18404 lines
1.6 MiB
18404 lines
1.6 MiB
module.exports =
|
||
/******/ (() => { // webpackBootstrap
|
||
/******/ var __webpack_modules__ = ({
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib/internal.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/internal.js ***!
|
||
\***********************************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
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')) {
|
||
this.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
|
||
if (process.env[envvar]) {
|
||
++loaded;
|
||
_debug('loading ' + envvar);
|
||
exports._vault.storeSecret(envvar, process.env[envvar]);
|
||
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 ***!
|
||
\*******************************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
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
|
||
*/
|
||
function cp(source, dest, options, continueOnError) {
|
||
if (options) {
|
||
shell.cp(options, source, dest);
|
||
}
|
||
else {
|
||
shell.cp(source, dest);
|
||
}
|
||
_checkShell('cp', continueOnError);
|
||
}
|
||
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'] = 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'] = 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')) {
|
||
this.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 }));
|
||
//
|
||
// 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, '%25')
|
||
.replace(/\r/g, '%0D')
|
||
.replace(/\n/g, '%0A');
|
||
}
|
||
function unescapedata(s) {
|
||
return s.replace(/%0D/g, '\r')
|
||
.replace(/%0A/g, '\n')
|
||
.replace(/%25/g, '%');
|
||
}
|
||
function escape(s) {
|
||
return s.replace(/%/g, '%25')
|
||
.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(/%25/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 (b.hasOwnProperty(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 }));
|
||
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 && c !== '"') {
|
||
arg += '\\';
|
||
}
|
||
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 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
|
||
cpFirst.stdout.on('data', function (data) {
|
||
try {
|
||
if (fileStream) {
|
||
fileStream.write(data);
|
||
}
|
||
cp.stdin.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.');
|
||
}
|
||
});
|
||
cpFirst.stderr.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) {
|
||
waitingEvents--; //first process is complete with errors
|
||
if (fileStream) {
|
||
fileStream.end();
|
||
}
|
||
cp.stdin.end();
|
||
error = new Error(toolPathFirst + ' failed. ' + err.message);
|
||
if (waitingEvents == 0) {
|
||
defer.reject(error);
|
||
}
|
||
});
|
||
cpFirst.on('close', function (code, signal) {
|
||
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();
|
||
}
|
||
cp.stdin.end();
|
||
if (waitingEvents == 0) {
|
||
if (error) {
|
||
defer.reject(error);
|
||
}
|
||
else {
|
||
defer.resolve(returnCode);
|
||
}
|
||
}
|
||
});
|
||
var stdbuffer = '';
|
||
cp.stdout.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 = '';
|
||
cp.stderr.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;
|
||
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.
|
||
cp.stdout.on('finish', function () {
|
||
if (!optionsNonNull.silent) {
|
||
optionsNonNull.outStream.write(os.EOL);
|
||
}
|
||
});
|
||
var stdbuffer = '';
|
||
cp.stdout.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 = '';
|
||
cp.stderr.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 }));
|
||
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) {
|
||
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 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/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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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 = false;
|
||
clone.implementationType = this.implementationType;
|
||
clone.dynamicValue = this.dynamicValue;
|
||
clone.scope = this.scope;
|
||
clone.type = this.type;
|
||
clone.factory = this.factory;
|
||
clone.provider = this.provider;
|
||
clone.constraint = this.constraint;
|
||
clone.onActivation = this.onActivation;
|
||
clone.cache = this.cache;
|
||
return clone;
|
||
};
|
||
return Binding;
|
||
}());
|
||
exports.Binding = Binding;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/bindings/binding_count.js":
|
||
/*!**************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/bindings/binding_count.js ***!
|
||
\**************************************************************/
|
||
/***/ ((__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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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:";
|
||
exports.UNDEFINED_INJECT_ANNOTATION = function (name) {
|
||
return "@inject called with undefined this could mean that the class " + name + " has " +
|
||
"a circular dependency problem. You can use a LazyServiceIdentifer to " +
|
||
"overcome this limitation.";
|
||
};
|
||
exports.CIRCULAR_DEPENDENCY = "Circular dependency found:";
|
||
exports.NOT_IMPLEMENTED = "Sorry, this feature is not fully implemented yet.";
|
||
exports.INVALID_BINDING_TYPE = "Invalid binding type:";
|
||
exports.NO_MORE_SNAPSHOTS_AVAILABLE = "No snapshot available to restore.";
|
||
exports.INVALID_MIDDLEWARE_RETURN = "Invalid return type in middleware. Middleware must return!";
|
||
exports.INVALID_FUNCTION_BINDING = "Value provided to function binding must be a function!";
|
||
exports.INVALID_TO_SELF_VALUE = "The toSelf function can only be applied when a constructor is " +
|
||
"used as service identifier";
|
||
exports.INVALID_DECORATOR_OPERATION = "The @inject @multiInject @tagged and @named decorators " +
|
||
"must be applied to the parameters of a class constructor or a class property.";
|
||
exports.ARGUMENTS_LENGTH_MISMATCH = function () {
|
||
var values = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
values[_i] = arguments[_i];
|
||
}
|
||
return "The number of constructor arguments in the derived class " +
|
||
(values[0] + " must be >= than the number of constructor arguments of its base class.");
|
||
};
|
||
exports.CONTAINER_OPTIONS_MUST_BE_AN_OBJECT = "Invalid Container constructor argument. Container options " +
|
||
"must be an object.";
|
||
exports.CONTAINER_OPTIONS_INVALID_DEFAULT_SCOPE = "Invalid Container option. Default scope must " +
|
||
"be a string ('singleton' or 'transient').";
|
||
exports.CONTAINER_OPTIONS_INVALID_AUTO_BIND_INJECTABLE = "Invalid Container option. Auto bind injectable must " +
|
||
"be a boolean";
|
||
exports.CONTAINER_OPTIONS_INVALID_SKIP_BASE_CHECK = "Invalid Container option. Skip base check must " +
|
||
"be a boolean";
|
||
exports.MULTIPLE_POST_CONSTRUCT_METHODS = "Cannot apply @postConstruct decorator multiple times in the same class";
|
||
exports.POST_CONSTRUCT_ERROR = function () {
|
||
var values = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
values[_i] = arguments[_i];
|
||
}
|
||
return "@postConstruct error in class " + values[0] + ": " + values[1];
|
||
};
|
||
exports.CIRCULAR_DEPENDENCY_IN_FACTORY = function () {
|
||
var values = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
values[_i] = arguments[_i];
|
||
}
|
||
return "It looks like there is a circular dependency " +
|
||
("in one of the '" + values[0] + "' bindings. Please investigate bindings with") +
|
||
("service identifier '" + values[1] + "'.");
|
||
};
|
||
exports.STACK_OVERFLOW = "Maximum call stack size exceeded";
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/constants/literal_types.js":
|
||
/*!***************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/constants/literal_types.js ***!
|
||
\***************************************************************/
|
||
/***/ ((__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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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.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";
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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 };
|
||
}
|
||
};
|
||
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) {
|
||
var options = containerOptions || {};
|
||
if (typeof options !== "object") {
|
||
throw new Error("" + ERROR_MSGS.CONTAINER_OPTIONS_MUST_BE_AN_OBJECT);
|
||
}
|
||
if (options.defaultScope === undefined) {
|
||
options.defaultScope = literal_types_1.BindingScopeEnum.Transient;
|
||
}
|
||
else if (options.defaultScope !== literal_types_1.BindingScopeEnum.Singleton &&
|
||
options.defaultScope !== literal_types_1.BindingScopeEnum.Transient &&
|
||
options.defaultScope !== literal_types_1.BindingScopeEnum.Request) {
|
||
throw new Error("" + ERROR_MSGS.CONTAINER_OPTIONS_INVALID_DEFAULT_SCOPE);
|
||
}
|
||
if (options.autoBindInjectable === undefined) {
|
||
options.autoBindInjectable = false;
|
||
}
|
||
else if (typeof options.autoBindInjectable !== "boolean") {
|
||
throw new Error("" + ERROR_MSGS.CONTAINER_OPTIONS_INVALID_AUTO_BIND_INJECTABLE);
|
||
}
|
||
if (options.skipBaseClassChecks === undefined) {
|
||
options.skipBaseClassChecks = false;
|
||
}
|
||
else if (typeof options.skipBaseClassChecks !== "boolean") {
|
||
throw new Error("" + ERROR_MSGS.CONTAINER_OPTIONS_INVALID_SKIP_BASE_CHECK);
|
||
}
|
||
this.options = {
|
||
autoBindInjectable: options.autoBindInjectable,
|
||
defaultScope: options.defaultScope,
|
||
skipBaseClassChecks: options.skipBaseClassChecks
|
||
};
|
||
this.id = id_1.id();
|
||
this._bindingDictionary = new lookup_1.Lookup();
|
||
this._snapshots = [];
|
||
this._middleware = null;
|
||
this.parent = null;
|
||
this._metadataReader = new metadata_reader_1.MetadataReader();
|
||
}
|
||
Container.merge = function (container1, container2) {
|
||
var container = new Container();
|
||
var bindingDictionary = planner_1.getBindingDictionary(container);
|
||
var bindingDictionary1 = planner_1.getBindingDictionary(container1);
|
||
var bindingDictionary2 = planner_1.getBindingDictionary(container2);
|
||
function copyDictionary(origin, destination) {
|
||
origin.traverse(function (key, value) {
|
||
value.forEach(function (binding) {
|
||
destination.add(binding.serviceIdentifier, binding.clone());
|
||
});
|
||
});
|
||
}
|
||
copyDictionary(bindingDictionary1, bindingDictionary);
|
||
copyDictionary(bindingDictionary2, bindingDictionary);
|
||
return container;
|
||
};
|
||
Container.prototype.load = function () {
|
||
var modules = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
modules[_i] = arguments[_i];
|
||
}
|
||
var getHelpers = this._getContainerModuleHelpersFactory();
|
||
for (var _a = 0, modules_1 = modules; _a < modules_1.length; _a++) {
|
||
var currentModule = modules_1[_a];
|
||
var containerModuleHelpers = getHelpers(currentModule.id);
|
||
currentModule.registry(containerModuleHelpers.bindFunction, containerModuleHelpers.unbindFunction, containerModuleHelpers.isboundFunction, containerModuleHelpers.rebindFunction);
|
||
}
|
||
};
|
||
Container.prototype.loadAsync = function () {
|
||
var modules = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
modules[_i] = arguments[_i];
|
||
}
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
var getHelpers, _a, modules_2, currentModule, containerModuleHelpers;
|
||
return __generator(this, function (_b) {
|
||
switch (_b.label) {
|
||
case 0:
|
||
getHelpers = this._getContainerModuleHelpersFactory();
|
||
_a = 0, modules_2 = modules;
|
||
_b.label = 1;
|
||
case 1:
|
||
if (!(_a < modules_2.length)) return [3, 4];
|
||
currentModule = modules_2[_a];
|
||
containerModuleHelpers = getHelpers(currentModule.id);
|
||
return [4, currentModule.registry(containerModuleHelpers.bindFunction, containerModuleHelpers.unbindFunction, containerModuleHelpers.isboundFunction, containerModuleHelpers.rebindFunction)];
|
||
case 2:
|
||
_b.sent();
|
||
_b.label = 3;
|
||
case 3:
|
||
_a++;
|
||
return [3, 1];
|
||
case 4: return [2];
|
||
}
|
||
});
|
||
});
|
||
};
|
||
Container.prototype.unload = function () {
|
||
var _this = this;
|
||
var modules = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
modules[_i] = arguments[_i];
|
||
}
|
||
var conditionFactory = function (expected) { return function (item) {
|
||
return item.moduleId === expected;
|
||
}; };
|
||
modules.forEach(function (module) {
|
||
var condition = conditionFactory(module.id);
|
||
_this._bindingDictionary.removeByCondition(condition);
|
||
});
|
||
};
|
||
Container.prototype.bind = function (serviceIdentifier) {
|
||
var scope = this.options.defaultScope || literal_types_1.BindingScopeEnum.Transient;
|
||
var binding = new binding_1.Binding(serviceIdentifier, scope);
|
||
this._bindingDictionary.add(serviceIdentifier, binding);
|
||
return new binding_to_syntax_1.BindingToSyntax(binding);
|
||
};
|
||
Container.prototype.rebind = function (serviceIdentifier) {
|
||
this.unbind(serviceIdentifier);
|
||
return this.bind(serviceIdentifier);
|
||
};
|
||
Container.prototype.unbind = function (serviceIdentifier) {
|
||
try {
|
||
this._bindingDictionary.remove(serviceIdentifier);
|
||
}
|
||
catch (e) {
|
||
throw new Error(ERROR_MSGS.CANNOT_UNBIND + " " + serialization_1.getServiceIdentifierAsString(serviceIdentifier));
|
||
}
|
||
};
|
||
Container.prototype.unbindAll = function () {
|
||
this._bindingDictionary = new lookup_1.Lookup();
|
||
};
|
||
Container.prototype.isBound = function (serviceIdentifier) {
|
||
var bound = this._bindingDictionary.hasKey(serviceIdentifier);
|
||
if (!bound && this.parent) {
|
||
bound = this.parent.isBound(serviceIdentifier);
|
||
}
|
||
return bound;
|
||
};
|
||
Container.prototype.isBoundNamed = function (serviceIdentifier, named) {
|
||
return this.isBoundTagged(serviceIdentifier, METADATA_KEY.NAMED_TAG, named);
|
||
};
|
||
Container.prototype.isBoundTagged = function (serviceIdentifier, key, value) {
|
||
var bound = false;
|
||
if (this._bindingDictionary.hasKey(serviceIdentifier)) {
|
||
var bindings = this._bindingDictionary.get(serviceIdentifier);
|
||
var request_1 = planner_1.createMockRequest(this, serviceIdentifier, key, value);
|
||
bound = bindings.some(function (b) { return b.constraint(request_1); });
|
||
}
|
||
if (!bound && this.parent) {
|
||
bound = this.parent.isBoundTagged(serviceIdentifier, key, value);
|
||
}
|
||
return bound;
|
||
};
|
||
Container.prototype.snapshot = function () {
|
||
this._snapshots.push(container_snapshot_1.ContainerSnapshot.of(this._bindingDictionary.clone(), this._middleware));
|
||
};
|
||
Container.prototype.restore = function () {
|
||
var snapshot = this._snapshots.pop();
|
||
if (snapshot === undefined) {
|
||
throw new Error(ERROR_MSGS.NO_MORE_SNAPSHOTS_AVAILABLE);
|
||
}
|
||
this._bindingDictionary = snapshot.bindings;
|
||
this._middleware = snapshot.middleware;
|
||
};
|
||
Container.prototype.createChild = function (containerOptions) {
|
||
var child = new Container(containerOptions || this.options);
|
||
child.parent = this;
|
||
return child;
|
||
};
|
||
Container.prototype.applyMiddleware = function () {
|
||
var middlewares = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
middlewares[_i] = arguments[_i];
|
||
}
|
||
var initial = (this._middleware) ? this._middleware : this._planAndResolve();
|
||
this._middleware = middlewares.reduce(function (prev, curr) { return curr(prev); }, initial);
|
||
};
|
||
Container.prototype.applyCustomMetadataReader = function (metadataReader) {
|
||
this._metadataReader = metadataReader;
|
||
};
|
||
Container.prototype.get = function (serviceIdentifier) {
|
||
return this._get(false, false, literal_types_1.TargetTypeEnum.Variable, serviceIdentifier);
|
||
};
|
||
Container.prototype.getTagged = function (serviceIdentifier, key, value) {
|
||
return this._get(false, false, literal_types_1.TargetTypeEnum.Variable, serviceIdentifier, key, value);
|
||
};
|
||
Container.prototype.getNamed = function (serviceIdentifier, named) {
|
||
return this.getTagged(serviceIdentifier, METADATA_KEY.NAMED_TAG, named);
|
||
};
|
||
Container.prototype.getAll = function (serviceIdentifier) {
|
||
return this._get(true, true, literal_types_1.TargetTypeEnum.Variable, serviceIdentifier);
|
||
};
|
||
Container.prototype.getAllTagged = function (serviceIdentifier, key, value) {
|
||
return this._get(false, true, literal_types_1.TargetTypeEnum.Variable, serviceIdentifier, key, value);
|
||
};
|
||
Container.prototype.getAllNamed = function (serviceIdentifier, named) {
|
||
return this.getAllTagged(serviceIdentifier, METADATA_KEY.NAMED_TAG, named);
|
||
};
|
||
Container.prototype.resolve = function (constructorFunction) {
|
||
var tempContainer = this.createChild();
|
||
tempContainer.bind(constructorFunction).toSelf();
|
||
return tempContainer.get(constructorFunction);
|
||
};
|
||
Container.prototype._getContainerModuleHelpersFactory = function () {
|
||
var _this = this;
|
||
var setModuleId = function (bindingToSyntax, moduleId) {
|
||
bindingToSyntax._binding.moduleId = moduleId;
|
||
};
|
||
var getBindFunction = function (moduleId) {
|
||
return function (serviceIdentifier) {
|
||
var _bind = _this.bind.bind(_this);
|
||
var bindingToSyntax = _bind(serviceIdentifier);
|
||
setModuleId(bindingToSyntax, moduleId);
|
||
return bindingToSyntax;
|
||
};
|
||
};
|
||
var getUnbindFunction = function (moduleId) {
|
||
return function (serviceIdentifier) {
|
||
var _unbind = _this.unbind.bind(_this);
|
||
_unbind(serviceIdentifier);
|
||
};
|
||
};
|
||
var getIsboundFunction = function (moduleId) {
|
||
return function (serviceIdentifier) {
|
||
var _isBound = _this.isBound.bind(_this);
|
||
return _isBound(serviceIdentifier);
|
||
};
|
||
};
|
||
var getRebindFunction = function (moduleId) {
|
||
return function (serviceIdentifier) {
|
||
var _rebind = _this.rebind.bind(_this);
|
||
var bindingToSyntax = _rebind(serviceIdentifier);
|
||
setModuleId(bindingToSyntax, moduleId);
|
||
return bindingToSyntax;
|
||
};
|
||
};
|
||
return function (mId) { return ({
|
||
bindFunction: getBindFunction(mId),
|
||
isboundFunction: getIsboundFunction(mId),
|
||
rebindFunction: getRebindFunction(mId),
|
||
unbindFunction: getUnbindFunction(mId)
|
||
}); };
|
||
};
|
||
Container.prototype._get = function (avoidConstraints, isMultiInject, targetType, serviceIdentifier, key, value) {
|
||
var result = null;
|
||
var defaultArgs = {
|
||
avoidConstraints: avoidConstraints,
|
||
contextInterceptor: function (context) { return context; },
|
||
isMultiInject: isMultiInject,
|
||
key: key,
|
||
serviceIdentifier: serviceIdentifier,
|
||
targetType: targetType,
|
||
value: value
|
||
};
|
||
if (this._middleware) {
|
||
result = this._middleware(defaultArgs);
|
||
if (result === undefined || result === null) {
|
||
throw new Error(ERROR_MSGS.INVALID_MIDDLEWARE_RETURN);
|
||
}
|
||
}
|
||
else {
|
||
result = this._planAndResolve()(defaultArgs);
|
||
}
|
||
return result;
|
||
};
|
||
Container.prototype._planAndResolve = function () {
|
||
var _this = this;
|
||
return function (args) {
|
||
var context = planner_1.plan(_this._metadataReader, _this, args.isMultiInject, args.targetType, args.serviceIdentifier, args.key, args.value, args.avoidConstraints);
|
||
context = args.contextInterceptor(context);
|
||
var result = resolver_1.resolve(context);
|
||
return result;
|
||
};
|
||
};
|
||
return Container;
|
||
}());
|
||
exports.Container = Container;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/container/container_module.js":
|
||
/*!******************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/container/container_module.js ***!
|
||
\******************************************************************/
|
||
/***/ ((__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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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.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; } }));
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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 __spreadArrays = (this && this.__spreadArrays) || function () {
|
||
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
||
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
||
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
||
r[k] = a[j];
|
||
return r;
|
||
};
|
||
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 iterations = (hasUserDeclaredUnknownInjections) ? keys.length : func.length;
|
||
var constructorTargets = getConstructorArgsAsTargets(isBaseClass, constructorName, serviceIdentifiers, constructorArgsMetadata, iterations);
|
||
var propertyTargets = getClassPropsAsTargets(metadataReader, func);
|
||
var targets = __spreadArrays(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 = __spreadArrays(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]
|
||
};
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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 (m) {
|
||
return (m.key !== METADATA_KEY.INJECT_TAG) &&
|
||
(m.key !== METADATA_KEY.MULTI_INJECT_TAG) &&
|
||
(m.key !== METADATA_KEY.NAME_TAG) &&
|
||
(m.key !== METADATA_KEY.UNMANAGED_TAG) &&
|
||
(m.key !== METADATA_KEY.NAMED_TAG);
|
||
});
|
||
};
|
||
Target.prototype.isOptional = function () {
|
||
return this.matchesTag(METADATA_KEY.OPTIONAL_TAG)(true);
|
||
};
|
||
Target.prototype.getNamedTag = function () {
|
||
if (this.isNamed()) {
|
||
return this.metadata.filter(function (m) { return m.key === METADATA_KEY.NAMED_TAG; })[0];
|
||
}
|
||
return null;
|
||
};
|
||
Target.prototype.getCustomTags = function () {
|
||
if (this.isTagged()) {
|
||
return this.metadata.filter(function (m) {
|
||
return (m.key !== METADATA_KEY.INJECT_TAG) &&
|
||
(m.key !== METADATA_KEY.MULTI_INJECT_TAG) &&
|
||
(m.key !== METADATA_KEY.NAME_TAG) &&
|
||
(m.key !== METADATA_KEY.UNMANAGED_TAG) &&
|
||
(m.key !== METADATA_KEY.NAMED_TAG);
|
||
});
|
||
}
|
||
return null;
|
||
};
|
||
Target.prototype.matchesNamedTag = function (name) {
|
||
return this.matchesTag(METADATA_KEY.NAMED_TAG)(name);
|
||
};
|
||
Target.prototype.matchesTag = function (key) {
|
||
var _this = this;
|
||
return function (value) {
|
||
for (var _i = 0, _a = _this.metadata; _i < _a.length; _i++) {
|
||
var m = _a[_i];
|
||
if (m.key === key && m.value === value) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
};
|
||
return Target;
|
||
}());
|
||
exports.Target = Target;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/resolution/instantiation.js":
|
||
/*!****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/resolution/instantiation.js ***!
|
||
\****************************************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __spreadArrays = (this && this.__spreadArrays) || function () {
|
||
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
||
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
||
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
||
r[k] = a[j];
|
||
return r;
|
||
};
|
||
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, __spreadArrays([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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
}
|
||
else if (binding_1.type === literal_types_1.BindingTypeEnum.Function) {
|
||
result = binding_1.cache;
|
||
}
|
||
else if (binding_1.type === literal_types_1.BindingTypeEnum.Constructor) {
|
||
result = binding_1.implementationType;
|
||
}
|
||
else if (binding_1.type === literal_types_1.BindingTypeEnum.DynamicValue && binding_1.dynamicValue !== null) {
|
||
result = invokeFactory("toDynamicValue", binding_1.serviceIdentifier, function () { return binding_1.dynamicValue(request.parentContext); });
|
||
}
|
||
else if (binding_1.type === literal_types_1.BindingTypeEnum.Factory && binding_1.factory !== null) {
|
||
result = invokeFactory("toFactory", binding_1.serviceIdentifier, function () { return binding_1.factory(request.parentContext); });
|
||
}
|
||
else if (binding_1.type === literal_types_1.BindingTypeEnum.Provider && binding_1.provider !== null) {
|
||
result = invokeFactory("toProvider", binding_1.serviceIdentifier, function () { return binding_1.provider(request.parentContext); });
|
||
}
|
||
else if (binding_1.type === literal_types_1.BindingTypeEnum.Instance && binding_1.implementationType !== null) {
|
||
result = instantiation_1.resolveInstance(binding_1.implementationType, childRequests, _resolveRequest(requestScope));
|
||
}
|
||
else {
|
||
var serviceIdentifier = serialization_1.getServiceIdentifierAsString(request.serviceIdentifier);
|
||
throw new Error(ERROR_MSGS.INVALID_BINDING_TYPE + " " + serviceIdentifier);
|
||
}
|
||
if (typeof binding_1.onActivation === "function") {
|
||
result = binding_1.onActivation(request.parentContext, result);
|
||
}
|
||
if (isSingleton) {
|
||
binding_1.cache = result;
|
||
binding_1.activated = true;
|
||
}
|
||
if (isRequestSingleton &&
|
||
requestScope !== null &&
|
||
!requestScope.has(binding_1.id)) {
|
||
requestScope.set(binding_1.id, result);
|
||
}
|
||
return result;
|
||
}
|
||
};
|
||
};
|
||
function resolve(context) {
|
||
var _f = _resolveRequest(context.plan.rootRequest.requestScope);
|
||
return _f(context.plan.rootRequest);
|
||
}
|
||
exports.resolve = resolve;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/syntax/binding_in_syntax.js":
|
||
/*!****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/syntax/binding_in_syntax.js ***!
|
||
\****************************************************************/
|
||
/***/ ((__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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding);
|
||
};
|
||
BindingToSyntax.prototype.toDynamicValue = function (func) {
|
||
this._binding.type = literal_types_1.BindingTypeEnum.DynamicValue;
|
||
this._binding.cache = null;
|
||
this._binding.dynamicValue = func;
|
||
this._binding.implementationType = null;
|
||
return new binding_in_when_on_syntax_1.BindingInWhenOnSyntax(this._binding);
|
||
};
|
||
BindingToSyntax.prototype.toConstructor = function (constructor) {
|
||
this._binding.type = literal_types_1.BindingTypeEnum.Constructor;
|
||
this._binding.implementationType = constructor;
|
||
return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding);
|
||
};
|
||
BindingToSyntax.prototype.toFactory = function (factory) {
|
||
this._binding.type = literal_types_1.BindingTypeEnum.Factory;
|
||
this._binding.factory = factory;
|
||
return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding);
|
||
};
|
||
BindingToSyntax.prototype.toFunction = function (func) {
|
||
if (typeof func !== "function") {
|
||
throw new Error(ERROR_MSGS.INVALID_FUNCTION_BINDING);
|
||
}
|
||
var bindingWhenOnSyntax = this.toConstantValue(func);
|
||
this._binding.type = literal_types_1.BindingTypeEnum.Function;
|
||
return bindingWhenOnSyntax;
|
||
};
|
||
BindingToSyntax.prototype.toAutoFactory = function (serviceIdentifier) {
|
||
this._binding.type = literal_types_1.BindingTypeEnum.Factory;
|
||
this._binding.factory = function (context) {
|
||
var autofactory = function () { return context.container.get(serviceIdentifier); };
|
||
return autofactory;
|
||
};
|
||
return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding);
|
||
};
|
||
BindingToSyntax.prototype.toProvider = function (provider) {
|
||
this._binding.type = literal_types_1.BindingTypeEnum.Provider;
|
||
this._binding.provider = provider;
|
||
return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding);
|
||
};
|
||
BindingToSyntax.prototype.toService = function (service) {
|
||
this.toDynamicValue(function (context) { return context.container.get(service); });
|
||
};
|
||
return BindingToSyntax;
|
||
}());
|
||
exports.BindingToSyntax = BindingToSyntax;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/syntax/binding_when_on_syntax.js":
|
||
/*!*********************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/syntax/binding_when_on_syntax.js ***!
|
||
\*********************************************************************/
|
||
/***/ ((__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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
exports.multiBindToService = function (container) {
|
||
return function (service) {
|
||
return function () {
|
||
var types = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
types[_i] = arguments[_i];
|
||
}
|
||
return types.forEach(function (t) { return container.bind(t).toService(service); });
|
||
};
|
||
};
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/utils/exceptions.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/utils/exceptions.js ***!
|
||
\********************************************************/
|
||
/***/ ((__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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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/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/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/arturadib/shelljs
|
||
//
|
||
|
||
var common = __webpack_require__(/*! ./src/common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
|
||
//@
|
||
//@ All commands run synchronously, unless otherwise stated.
|
||
//@
|
||
|
||
//@include ./src/cd
|
||
var _cd = __webpack_require__(/*! ./src/cd */ "./node_modules/shelljs/src/cd.js");
|
||
exports.cd = common.wrap('cd', _cd);
|
||
|
||
//@include ./src/pwd
|
||
var _pwd = __webpack_require__(/*! ./src/pwd */ "./node_modules/shelljs/src/pwd.js");
|
||
exports.pwd = common.wrap('pwd', _pwd);
|
||
|
||
//@include ./src/ls
|
||
var _ls = __webpack_require__(/*! ./src/ls */ "./node_modules/shelljs/src/ls.js");
|
||
exports.ls = common.wrap('ls', _ls);
|
||
|
||
//@include ./src/find
|
||
var _find = __webpack_require__(/*! ./src/find */ "./node_modules/shelljs/src/find.js");
|
||
exports.find = common.wrap('find', _find);
|
||
|
||
//@include ./src/cp
|
||
var _cp = __webpack_require__(/*! ./src/cp */ "./node_modules/shelljs/src/cp.js");
|
||
exports.cp = common.wrap('cp', _cp);
|
||
|
||
//@include ./src/rm
|
||
var _rm = __webpack_require__(/*! ./src/rm */ "./node_modules/shelljs/src/rm.js");
|
||
exports.rm = common.wrap('rm', _rm);
|
||
|
||
//@include ./src/mv
|
||
var _mv = __webpack_require__(/*! ./src/mv */ "./node_modules/shelljs/src/mv.js");
|
||
exports.mv = common.wrap('mv', _mv);
|
||
|
||
//@include ./src/mkdir
|
||
var _mkdir = __webpack_require__(/*! ./src/mkdir */ "./node_modules/shelljs/src/mkdir.js");
|
||
exports.mkdir = common.wrap('mkdir', _mkdir);
|
||
|
||
//@include ./src/test
|
||
var _test = __webpack_require__(/*! ./src/test */ "./node_modules/shelljs/src/test.js");
|
||
exports.test = common.wrap('test', _test);
|
||
|
||
//@include ./src/cat
|
||
var _cat = __webpack_require__(/*! ./src/cat */ "./node_modules/shelljs/src/cat.js");
|
||
exports.cat = common.wrap('cat', _cat);
|
||
|
||
//@include ./src/to
|
||
var _to = __webpack_require__(/*! ./src/to */ "./node_modules/shelljs/src/to.js");
|
||
String.prototype.to = common.wrap('to', _to);
|
||
|
||
//@include ./src/toEnd
|
||
var _toEnd = __webpack_require__(/*! ./src/toEnd */ "./node_modules/shelljs/src/toEnd.js");
|
||
String.prototype.toEnd = common.wrap('toEnd', _toEnd);
|
||
|
||
//@include ./src/sed
|
||
var _sed = __webpack_require__(/*! ./src/sed */ "./node_modules/shelljs/src/sed.js");
|
||
exports.sed = common.wrap('sed', _sed);
|
||
|
||
//@include ./src/grep
|
||
var _grep = __webpack_require__(/*! ./src/grep */ "./node_modules/shelljs/src/grep.js");
|
||
exports.grep = common.wrap('grep', _grep);
|
||
|
||
//@include ./src/which
|
||
var _which = __webpack_require__(/*! ./src/which */ "./node_modules/shelljs/src/which.js");
|
||
exports.which = common.wrap('which', _which);
|
||
|
||
//@include ./src/echo
|
||
var _echo = __webpack_require__(/*! ./src/echo */ "./node_modules/shelljs/src/echo.js");
|
||
exports.echo = _echo; // don't common.wrap() as it could parse '-options'
|
||
|
||
//@include ./src/dirs
|
||
var _dirs = __webpack_require__(/*! ./src/dirs */ "./node_modules/shelljs/src/dirs.js").dirs;
|
||
exports.dirs = common.wrap("dirs", _dirs);
|
||
var _pushd = __webpack_require__(/*! ./src/dirs */ "./node_modules/shelljs/src/dirs.js").pushd;
|
||
exports.pushd = common.wrap('pushd', _pushd);
|
||
var _popd = __webpack_require__(/*! ./src/dirs */ "./node_modules/shelljs/src/dirs.js").popd;
|
||
exports.popd = common.wrap("popd", _popd);
|
||
|
||
//@include ./src/ln
|
||
var _ln = __webpack_require__(/*! ./src/ln */ "./node_modules/shelljs/src/ln.js");
|
||
exports.ln = common.wrap('ln', _ln);
|
||
|
||
//@
|
||
//@ ### exit(code)
|
||
//@ Exits the current process with the given exit code.
|
||
exports.exit = process.exit;
|
||
|
||
//@
|
||
//@ ### env['VAR_NAME']
|
||
//@ Object containing environment variables (both getter and setter). Shortcut to process.env.
|
||
exports.env = process.env;
|
||
|
||
//@include ./src/exec
|
||
var _exec = __webpack_require__(/*! ./src/exec */ "./node_modules/shelljs/src/exec.js");
|
||
exports.exec = common.wrap('exec', _exec, {notUnix:true});
|
||
|
||
//@include ./src/chmod
|
||
var _chmod = __webpack_require__(/*! ./src/chmod */ "./node_modules/shelljs/src/chmod.js");
|
||
exports.chmod = common.wrap('chmod', _chmod);
|
||
|
||
|
||
|
||
//@
|
||
//@ ## Non-Unix commands
|
||
//@
|
||
|
||
//@include ./src/tempdir
|
||
var _tempDir = __webpack_require__(/*! ./src/tempdir */ "./node_modules/shelljs/src/tempdir.js");
|
||
exports.tempdir = common.wrap('tempdir', _tempDir);
|
||
|
||
|
||
//@include ./src/error
|
||
var _error = __webpack_require__(/*! ./src/error */ "./node_modules/shelljs/src/error.js");
|
||
exports.error = _error;
|
||
|
||
|
||
|
||
//@
|
||
//@ ## Configuration
|
||
//@
|
||
|
||
exports.config = common.config;
|
||
|
||
//@
|
||
//@ ### config.silent
|
||
//@ Example:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var silentState = config.silent; // save old silent state
|
||
//@ config.silent = true;
|
||
//@ /* ... */
|
||
//@ config.silent = silentState; // restore old silent state
|
||
//@ ```
|
||
//@
|
||
//@ Suppresses all command output if `true`, except for `echo()` calls.
|
||
//@ Default is `false`.
|
||
|
||
//@
|
||
//@ ### config.fatal
|
||
//@ Example:
|
||
//@
|
||
//@ ```javascript
|
||
//@ config.fatal = true;
|
||
//@ cp('this_file_does_not_exist', '/dev/null'); // dies here
|
||
//@ /* more commands... */
|
||
//@ ```
|
||
//@
|
||
//@ If `true` the script will die on errors. Default is `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");
|
||
|
||
//@
|
||
//@ ### cat(file [, file ...])
|
||
//@ ### cat(file_array)
|
||
//@
|
||
//@ 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). Wildcard `*` accepted.
|
||
function _cat(options, files) {
|
||
var cat = '';
|
||
|
||
if (!files)
|
||
common.error('no paths given');
|
||
|
||
if (typeof files === 'string')
|
||
files = [].slice.call(arguments, 1);
|
||
// if it's array leave it as it is
|
||
|
||
files = common.expand(files);
|
||
|
||
files.forEach(function(file) {
|
||
if (!fs.existsSync(file))
|
||
common.error('no such file or directory: ' + file);
|
||
|
||
cat += fs.readFileSync(file, 'utf8') + '\n';
|
||
});
|
||
|
||
if (cat[cat.length-1] === '\n')
|
||
cat = cat.substring(0, cat.length-1);
|
||
|
||
return common.ShellString(cat);
|
||
}
|
||
module.exports = _cat;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/cd.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/shelljs/src/cd.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
//@
|
||
//@ ### cd('dir')
|
||
//@ Changes to directory `dir` for the duration of the script
|
||
function _cd(options, dir) {
|
||
if (!dir)
|
||
common.error('directory not specified');
|
||
|
||
if (!fs.existsSync(dir))
|
||
common.error('no such file or directory: ' + dir);
|
||
|
||
if (!fs.statSync(dir).isDirectory())
|
||
common.error('not a directory: ' + dir);
|
||
|
||
process.chdir(dir);
|
||
}
|
||
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. Using parseInt is
|
||
// the preferred way, else a jshint warning is thrown.
|
||
STICKY : parseInt('01000', 8),
|
||
SETGID : parseInt('02000', 8),
|
||
SETUID : parseInt('04000', 8),
|
||
|
||
TYPE_MASK : parseInt('0770000', 8)
|
||
};
|
||
})({
|
||
EXEC : 1,
|
||
WRITE : 2,
|
||
READ : 4
|
||
});
|
||
|
||
//@
|
||
//@ ### chmod(octal_mode || octal_string, file)
|
||
//@ ### chmod(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');
|
||
//@ ```
|
||
//@
|
||
//@ 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.
|
||
filePattern = mode;
|
||
mode = options;
|
||
options = '';
|
||
}
|
||
else {
|
||
common.error('You must specify a file.');
|
||
}
|
||
}
|
||
|
||
options = common.parseOptions(options, {
|
||
'R': 'recursive',
|
||
'c': 'changes',
|
||
'v': 'verbose'
|
||
});
|
||
|
||
if (typeof filePattern === 'string') {
|
||
filePattern = [ filePattern ];
|
||
}
|
||
|
||
var files;
|
||
|
||
if (options.recursive) {
|
||
files = [];
|
||
common.expand(filePattern).forEach(function addFile(expandedFile) {
|
||
var stat = fs.lstatSync(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 = common.expand(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 && fs.lstatSync(file).isSymbolicLink()) {
|
||
return;
|
||
}
|
||
|
||
var perms = fs.statSync(file).mode;
|
||
var type = perms & PERMS.TYPE_MASK;
|
||
|
||
var newPerms = perms;
|
||
|
||
if (isNaN(parseInt(mode, 8))) {
|
||
// parse options
|
||
mode.split(',').forEach(function (symbolicMode) {
|
||
/*jshint regexdash:true */
|
||
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 changeSticky = change.indexOf('t') != -1;
|
||
var changeSetuid = change.indexOf('s') != -1;
|
||
|
||
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 (fs.statSync(file).isDirectory()) {
|
||
newPerms |= (PERMS.SETUID + PERMS.SETGID) & perms;
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (options.verbose) {
|
||
log(file + ' -> ' + newPerms.toString(8));
|
||
}
|
||
|
||
if (perms != newPerms) {
|
||
if (!options.verbose && options.changes) {
|
||
log(file + ' -> ' + newPerms.toString(8));
|
||
}
|
||
fs.chmodSync(file, newPerms);
|
||
}
|
||
}
|
||
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 (fs.statSync(file).isDirectory()) {
|
||
newPerms |= (PERMS.SETUID + PERMS.SETGID) & perms;
|
||
}
|
||
|
||
fs.chmodSync(file, newPerms);
|
||
}
|
||
});
|
||
}
|
||
module.exports = _chmod;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/common.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/shelljs/src/common.js ***!
|
||
\********************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
var os = __webpack_require__(/*! os */ "os");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var _ls = __webpack_require__(/*! ./ls */ "./node_modules/shelljs/src/ls.js");
|
||
|
||
// Module globals
|
||
var config = {
|
||
silent: false,
|
||
fatal: false
|
||
};
|
||
exports.config = config;
|
||
|
||
var state = {
|
||
error: null,
|
||
currentCmd: 'shell.js',
|
||
tempDir: null
|
||
};
|
||
exports.state = state;
|
||
|
||
var platform = os.type().match(/^Win/) ? 'win' : 'unix';
|
||
exports.platform = platform;
|
||
|
||
function log() {
|
||
if (!config.silent)
|
||
console.log.apply(this, arguments);
|
||
}
|
||
exports.log = log;
|
||
|
||
// Shows error message. Throws unless _continue or config.fatal are true
|
||
function error(msg, _continue) {
|
||
if (state.error === null)
|
||
state.error = '';
|
||
state.error += state.currentCmd + ': ' + msg + '\n';
|
||
|
||
if (msg.length > 0)
|
||
log(state.error);
|
||
|
||
if (config.fatal)
|
||
process.exit(1);
|
||
|
||
if (!_continue)
|
||
throw '';
|
||
}
|
||
exports.error = error;
|
||
|
||
// In the future, when Proxies are default, we can add methods like `.to()` to primitive strings.
|
||
// For now, this is a dummy function to bookmark places we need such strings
|
||
function ShellString(str) {
|
||
return str;
|
||
}
|
||
exports.ShellString = ShellString;
|
||
|
||
// Returns {'alice': true, 'bob': false} when passed a dictionary, e.g.:
|
||
// parseOptions('-a', {'a':'alice', 'b':'bob'});
|
||
function parseOptions(str, map) {
|
||
if (!map)
|
||
error('parseOptions() internal error: no map given');
|
||
|
||
// All options are false by default
|
||
var options = {};
|
||
for (var letter in map)
|
||
options[map[letter]] = false;
|
||
|
||
if (!str)
|
||
return options; // defaults
|
||
|
||
if (typeof str !== 'string')
|
||
error('parseOptions() internal error: wrong str');
|
||
|
||
// e.g. match[1] = 'Rf' for str = '-Rf'
|
||
var match = str.match(/^\-(.+)/);
|
||
if (!match)
|
||
return options;
|
||
|
||
// e.g. chars = ['R', 'f']
|
||
var chars = match[1].split('');
|
||
|
||
chars.forEach(function(c) {
|
||
if (c in map)
|
||
options[map[c]] = true;
|
||
else
|
||
error('option not recognized: '+c);
|
||
});
|
||
|
||
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) {
|
||
var expanded = [];
|
||
list.forEach(function(listEl) {
|
||
// Wildcard present on directory names ?
|
||
if(listEl.search(/\*[^\/]*\//) > -1 || listEl.search(/\*\*[^\/]*\//) > -1) {
|
||
var match = listEl.match(/^([^*]+\/|)(.*)/);
|
||
var root = match[1];
|
||
var rest = match[2];
|
||
var restRegex = rest.replace(/\*\*/g, ".*").replace(/\*/g, "[^\\/]*");
|
||
restRegex = new RegExp(restRegex);
|
||
|
||
_ls('-R', root).filter(function (e) {
|
||
return restRegex.test(e);
|
||
}).forEach(function(file) {
|
||
expanded.push(file);
|
||
});
|
||
}
|
||
// Wildcard present on file names ?
|
||
else if (listEl.search(/\*/) > -1) {
|
||
_ls('', listEl).forEach(function(file) {
|
||
expanded.push(file);
|
||
});
|
||
} else {
|
||
expanded.push(listEl);
|
||
}
|
||
});
|
||
return expanded;
|
||
}
|
||
exports.expand = expand;
|
||
|
||
// 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
|
||
if (e.code === 'EPERM') {
|
||
fs.chmodSync(file, '0666');
|
||
fs.unlinkSync(file);
|
||
} else {
|
||
throw e;
|
||
}
|
||
}
|
||
}
|
||
exports.unlinkSync = unlinkSync;
|
||
|
||
// e.g. 'shelljs_a5f185d0443ca...'
|
||
function randomFileName() {
|
||
function randomHash(count) {
|
||
if (count === 1)
|
||
return parseInt(16*Math.random(), 10).toString(16);
|
||
else {
|
||
var hash = '';
|
||
for (var i=0; i<count; i++)
|
||
hash += randomHash(1);
|
||
return hash;
|
||
}
|
||
}
|
||
|
||
return 'shelljs_'+randomHash(20);
|
||
}
|
||
exports.randomFileName = randomFileName;
|
||
|
||
// extend(target_obj, source_obj1 [, source_obj2 ...])
|
||
// Shallow extend, e.g.:
|
||
// extend({A:1}, {b:2}, {c:3}) returns {A:1, b:2, c:3}
|
||
function extend(target) {
|
||
var sources = [].slice.call(arguments, 1);
|
||
sources.forEach(function(source) {
|
||
for (var key in source)
|
||
target[key] = source[key];
|
||
});
|
||
|
||
return target;
|
||
}
|
||
exports.extend = extend;
|
||
|
||
// Common wrapper for all Unix-like commands
|
||
function wrap(cmd, fn, options) {
|
||
return function() {
|
||
var retValue = null;
|
||
|
||
state.currentCmd = cmd;
|
||
state.error = null;
|
||
|
||
try {
|
||
var args = [].slice.call(arguments, 0);
|
||
|
||
if (options && options.notUnix) {
|
||
retValue = fn.apply(this, args);
|
||
} else {
|
||
if (args.length === 0 || typeof args[0] !== 'string' || args[0][0] !== '-')
|
||
args.unshift(''); // only add dummy option if '-option' not already present
|
||
retValue = fn.apply(this, args);
|
||
}
|
||
} catch (e) {
|
||
if (!state.error) {
|
||
// If state.error hasn't been set it's an error thrown by Node, not us - probably a bug...
|
||
console.log('shell.js: internal error');
|
||
console.log(e.stack || e);
|
||
process.exit(1);
|
||
}
|
||
if (config.fatal)
|
||
throw e;
|
||
}
|
||
|
||
state.currentCmd = 'shell.js';
|
||
return retValue;
|
||
};
|
||
} // wrap
|
||
exports.wrap = wrap;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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");
|
||
var os = __webpack_require__(/*! os */ "os");
|
||
|
||
// Buffered file copy, synchronous
|
||
// (Using readFileSync() + writeFileSync() could easily cause a memory overflow
|
||
// with large files)
|
||
function copyFileSync(srcFile, destFile) {
|
||
if (!fs.existsSync(srcFile))
|
||
common.error('copyFileSync: no such file or directory: ' + srcFile);
|
||
|
||
var BUF_LENGTH = 64*1024,
|
||
buf = new Buffer(BUF_LENGTH),
|
||
bytesRead = BUF_LENGTH,
|
||
pos = 0,
|
||
fdr = null,
|
||
fdw = null;
|
||
|
||
try {
|
||
fdr = fs.openSync(srcFile, 'r');
|
||
} catch(e) {
|
||
common.error('copyFileSync: could not read src file ('+srcFile+')');
|
||
}
|
||
|
||
try {
|
||
fdw = fs.openSync(destFile, 'w');
|
||
} catch(e) {
|
||
common.error('copyFileSync: could not write to dest file (code='+e.code+'):'+destFile);
|
||
}
|
||
|
||
while (bytesRead === BUF_LENGTH) {
|
||
bytesRead = fs.readSync(fdr, buf, 0, BUF_LENGTH, pos);
|
||
fs.writeSync(fdw, buf, 0, bytesRead);
|
||
pos += bytesRead;
|
||
}
|
||
|
||
fs.closeSync(fdr);
|
||
fs.closeSync(fdw);
|
||
|
||
fs.chmodSync(destFile, fs.statSync(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, opts) {
|
||
if (!opts) opts = {};
|
||
|
||
/* Create the directory where all our junk is moving to; read the mode of the source directory and mirror it */
|
||
var checkDir = fs.statSync(sourceDir);
|
||
try {
|
||
fs.mkdirSync(destDir, checkDir.mode);
|
||
} 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 = fs.lstatSync(srcFile);
|
||
|
||
if (srcFileStat.isDirectory()) {
|
||
/* recursion this thing right on back. */
|
||
cpdirSyncRecursive(srcFile, destFile, opts);
|
||
} else if (srcFileStat.isSymbolicLink()) {
|
||
var symlinkFull = fs.readlinkSync(srcFile);
|
||
fs.symlinkSync(symlinkFull, destFile, os.platform() === "win32" ? "junction" : null);
|
||
} else {
|
||
/* At this point, we've hit a file actually worth copying... so copy it on over. */
|
||
if (fs.existsSync(destFile) && !opts.force) {
|
||
common.log('skipping existing file: ' + files[i]);
|
||
} else {
|
||
copyFileSync(srcFile, destFile);
|
||
}
|
||
}
|
||
|
||
} // for files
|
||
} // cpdirSyncRecursive
|
||
|
||
|
||
//@
|
||
//@ ### cp([options ,] source [,source ...], dest)
|
||
//@ ### cp([options ,] source_array, dest)
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-f`: force
|
||
//@ + `-r, -R`: recursive
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ cp('file1', 'dir1');
|
||
//@ cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp');
|
||
//@ cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Copies files. The wildcard `*` is accepted.
|
||
function _cp(options, sources, dest) {
|
||
options = common.parseOptions(options, {
|
||
'f': 'force',
|
||
'R': 'recursive',
|
||
'r': 'recursive'
|
||
});
|
||
|
||
// 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 if ('length' in sources) {
|
||
sources = sources; // no-op for array
|
||
} else {
|
||
common.error('invalid arguments');
|
||
}
|
||
|
||
var exists = fs.existsSync(dest),
|
||
stats = exists && fs.statSync(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.force)
|
||
common.error('dest file already exists: ' + dest);
|
||
|
||
if (options.recursive) {
|
||
// Recursive allows the shortcut syntax "sourcedir/" for "sourcedir/*"
|
||
// (see Github issue #15)
|
||
sources.forEach(function(src, i) {
|
||
if (src[src.length - 1] === '/')
|
||
sources[i] += '*';
|
||
});
|
||
|
||
// Create dest
|
||
try {
|
||
fs.mkdirSync(dest, parseInt('0777', 8));
|
||
} catch (e) {
|
||
// like Unix's cp, keep going even if we can't create dest dir
|
||
}
|
||
}
|
||
|
||
sources = common.expand(sources);
|
||
|
||
sources.forEach(function(src) {
|
||
if (!fs.existsSync(src)) {
|
||
common.error('no such file or directory: '+src, true);
|
||
return; // skip file
|
||
}
|
||
|
||
// If here, src exists
|
||
if (fs.statSync(src).isDirectory()) {
|
||
if (!options.recursive) {
|
||
// Non-Recursive
|
||
common.log(src + ' is a directory (not copied)');
|
||
} else {
|
||
// Recursive
|
||
// 'cp /a/source dest' should create 'source' in 'dest'
|
||
var newDest = path.join(dest, path.basename(src)),
|
||
checkDir = fs.statSync(src);
|
||
try {
|
||
fs.mkdirSync(newDest, checkDir.mode);
|
||
} catch (e) {
|
||
//if the directory already exists, that's okay
|
||
if (e.code !== 'EEXIST') throw e;
|
||
}
|
||
|
||
cpdirSyncRecursive(src, newDest, {force: options.force});
|
||
}
|
||
return; // done with dir
|
||
}
|
||
|
||
// If here, src is a file
|
||
|
||
// When copying to '/path/dir':
|
||
// thisDest = '/path/dir/file1'
|
||
var thisDest = dest;
|
||
if (fs.existsSync(dest) && fs.statSync(dest).isDirectory())
|
||
thisDest = path.normalize(dest + '/' + path.basename(src));
|
||
|
||
if (fs.existsSync(thisDest) && !options.force) {
|
||
common.error('dest file already exists: ' + thisDest, true);
|
||
return; // skip file
|
||
}
|
||
|
||
copyFileSync(src, thisDest);
|
||
}); // forEach(src)
|
||
}
|
||
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");
|
||
|
||
// 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);
|
||
} else {
|
||
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.
|
||
//@
|
||
//@ Arguments:
|
||
//@
|
||
//@ + `dir`: Makes the current working directory be the top of the stack, and 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'
|
||
});
|
||
|
||
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('');
|
||
}
|
||
exports.pushd = _pushd;
|
||
|
||
//@
|
||
//@ ### popd([options,] ['-N' | '+N'])
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-n`: Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated.
|
||
//@
|
||
//@ 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'
|
||
});
|
||
|
||
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('');
|
||
}
|
||
exports.popd = _popd;
|
||
|
||
//@
|
||
//@ ### dirs([options | '+N' | '-N'])
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-c`: Clears the directory stack by deleting all of the elements.
|
||
//@
|
||
//@ 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'
|
||
});
|
||
|
||
if (options['clear']) {
|
||
_dirStack = [];
|
||
return _dirStack;
|
||
}
|
||
|
||
var stack = _actualDirStack();
|
||
|
||
if (index) {
|
||
index = _parseStackIndex(index);
|
||
|
||
if (index < 0) {
|
||
index = stack.length + index;
|
||
}
|
||
|
||
common.log(stack[index]);
|
||
return stack[index];
|
||
}
|
||
|
||
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 common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
//@
|
||
//@ ### echo(string [,string ...])
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ echo('hello world');
|
||
//@ var str = echo('hello world');
|
||
//@ ```
|
||
//@
|
||
//@ Prints string to stdout, and returns string with additional utility methods
|
||
//@ like `.to()`.
|
||
function _echo() {
|
||
var messages = [].slice.call(arguments, 0);
|
||
console.log.apply(this, messages);
|
||
return common.ShellString(messages.join(' '));
|
||
}
|
||
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 `null` if no error occurred,
|
||
//@ otherwise returns string explaining the error
|
||
function error() {
|
||
return common.state.error;
|
||
};
|
||
module.exports = error;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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");
|
||
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");
|
||
|
||
// Hack to run child_process.exec() synchronously (sync avoids callback hell)
|
||
// Uses a custom wait loop that checks for a flag file, created when the child process is done.
|
||
// (Can't do a wait loop that checks for internal Node variables/messages as
|
||
// Node is single-threaded; callbacks and other internal state changes are done in the
|
||
// event loop).
|
||
function execSync(cmd, opts) {
|
||
var tempDir = _tempDir();
|
||
var stdoutFile = path.resolve(tempDir+'/'+common.randomFileName()),
|
||
codeFile = path.resolve(tempDir+'/'+common.randomFileName()),
|
||
scriptFile = path.resolve(tempDir+'/'+common.randomFileName()),
|
||
sleepFile = path.resolve(tempDir+'/'+common.randomFileName());
|
||
|
||
var options = common.extend({
|
||
silent: common.config.silent
|
||
}, opts);
|
||
|
||
var previousStdoutContent = '';
|
||
// Echoes stdout changes from running process, if not silent
|
||
function updateStdout() {
|
||
if (options.silent || !fs.existsSync(stdoutFile))
|
||
return;
|
||
|
||
var stdoutContent = fs.readFileSync(stdoutFile, 'utf8');
|
||
// No changes since last time?
|
||
if (stdoutContent.length <= previousStdoutContent.length)
|
||
return;
|
||
|
||
process.stdout.write(stdoutContent.substr(previousStdoutContent.length));
|
||
previousStdoutContent = stdoutContent;
|
||
}
|
||
|
||
function escape(str) {
|
||
return (str+'').replace(/([\\"'])/g, "\\$1").replace(/\0/g, "\\0");
|
||
}
|
||
|
||
cmd += ' > '+stdoutFile+' 2>&1'; // works on both win/unix
|
||
|
||
var script =
|
||
"var child = require('child_process')," +
|
||
" fs = require('fs');" +
|
||
"child.exec('"+escape(cmd)+"', {env: process.env, maxBuffer: 20*1024*1024}, function(err) {" +
|
||
" fs.writeFileSync('"+escape(codeFile)+"', err ? err.code.toString() : '0');" +
|
||
"});";
|
||
|
||
if (fs.existsSync(scriptFile)) common.unlinkSync(scriptFile);
|
||
if (fs.existsSync(stdoutFile)) common.unlinkSync(stdoutFile);
|
||
if (fs.existsSync(codeFile)) common.unlinkSync(codeFile);
|
||
|
||
fs.writeFileSync(scriptFile, script);
|
||
child.exec('"'+process.execPath+'" '+scriptFile, {
|
||
env: process.env,
|
||
cwd: _pwd(),
|
||
maxBuffer: 20*1024*1024
|
||
});
|
||
|
||
// The wait loop
|
||
// sleepFile is used as a dummy I/O op to mitigate unnecessary CPU usage
|
||
// (tried many I/O sync ops, writeFileSync() seems to be only one that is effective in reducing
|
||
// CPU usage, though apparently not so much on Windows)
|
||
while (!fs.existsSync(codeFile)) { updateStdout(); fs.writeFileSync(sleepFile, 'a'); }
|
||
while (!fs.existsSync(stdoutFile)) { updateStdout(); fs.writeFileSync(sleepFile, 'a'); }
|
||
|
||
// At this point codeFile exists, but it's not necessarily flushed yet.
|
||
// Keep reading it until it is.
|
||
var code = parseInt('', 10);
|
||
while (isNaN(code)) {
|
||
code = parseInt(fs.readFileSync(codeFile, 'utf8'), 10);
|
||
}
|
||
|
||
var stdout = fs.readFileSync(stdoutFile, 'utf8');
|
||
|
||
// No biggie if we can't erase the files now -- they're in a temp dir anyway
|
||
try { common.unlinkSync(scriptFile); } catch(e) {}
|
||
try { common.unlinkSync(stdoutFile); } catch(e) {}
|
||
try { common.unlinkSync(codeFile); } catch(e) {}
|
||
try { common.unlinkSync(sleepFile); } catch(e) {}
|
||
|
||
// some shell return codes are defined as errors, per http://tldp.org/LDP/abs/html/exitcodes.html
|
||
if (code === 1 || code === 2 || code >= 126) {
|
||
common.error('', true); // unix/shell doesn't really give an error message after non-zero exit codes
|
||
}
|
||
// True if successful, false if not
|
||
var obj = {
|
||
code: code,
|
||
output: stdout
|
||
};
|
||
return obj;
|
||
} // execSync()
|
||
|
||
// Wrapper around exec() to enable echoing output to console in real time
|
||
function execAsync(cmd, opts, callback) {
|
||
var output = '';
|
||
|
||
var options = common.extend({
|
||
silent: common.config.silent
|
||
}, opts);
|
||
|
||
var c = child.exec(cmd, {env: process.env, maxBuffer: 20*1024*1024}, function(err) {
|
||
if (callback)
|
||
callback(err ? err.code : 0, output);
|
||
});
|
||
|
||
c.stdout.on('data', function(data) {
|
||
output += data;
|
||
if (!options.silent)
|
||
process.stdout.write(data);
|
||
});
|
||
|
||
c.stderr.on('data', function(data) {
|
||
output += data;
|
||
if (!options.silent)
|
||
process.stdout.write(data);
|
||
});
|
||
|
||
return c;
|
||
}
|
||
|
||
//@
|
||
//@ ### exec(command [, options] [, callback])
|
||
//@ Available options (all `false` by default):
|
||
//@
|
||
//@ + `async`: Asynchronous execution. Defaults to true if a callback is provided.
|
||
//@ + `silent`: Do not echo program output to console.
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var version = exec('node --version', {silent:true}).output;
|
||
//@
|
||
//@ 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, output) {
|
||
//@ console.log('Exit code:', code);
|
||
//@ console.log('Program output:', output);
|
||
//@ });
|
||
//@ ```
|
||
//@
|
||
//@ Executes the given `command` _synchronously_, unless otherwise specified.
|
||
//@ When in synchronous mode returns the object `{ code:..., output:... }`, containing the program's
|
||
//@ `output` (stdout + stderr) and its exit `code`. Otherwise returns the child process object, and
|
||
//@ the `callback` gets the arguments `(code, output)`.
|
||
//@
|
||
//@ **Note:** For long-lived processes, it's best to run `exec()` asynchronously as
|
||
//@ the current synchronous implementation uses a lot of CPU. This should be getting
|
||
//@ fixed soon.
|
||
function _exec(command, options, callback) {
|
||
if (!command)
|
||
common.error('must specify command');
|
||
|
||
// 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, callback);
|
||
else
|
||
return execSync(command, options);
|
||
}
|
||
module.exports = _exec;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/find.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/find.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var _ls = __webpack_require__(/*! ./ls */ "./node_modules/shelljs/src/ls.js");
|
||
|
||
//@
|
||
//@ ### 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 === 'object')
|
||
paths = paths; // assume array
|
||
else if (typeof paths === 'string')
|
||
paths = [].slice.call(arguments, 1);
|
||
|
||
var list = [];
|
||
|
||
function pushFile(file) {
|
||
if (common.platform === 'win')
|
||
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) {
|
||
pushFile(file);
|
||
|
||
if (fs.statSync(file).isDirectory()) {
|
||
_ls('-RA', file+'/*').forEach(function(subfile) {
|
||
pushFile(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");
|
||
|
||
//@
|
||
//@ ### grep([options ,] regex_filter, file [, file ...])
|
||
//@ ### grep([options ,] regex_filter, file_array)
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-v`: Inverse the sense of the regex and print the lines not matching the criteria.
|
||
//@
|
||
//@ 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`. Wildcard `*` accepted.
|
||
function _grep(options, regex, files) {
|
||
options = common.parseOptions(options, {
|
||
'v': 'inverse'
|
||
});
|
||
|
||
if (!files)
|
||
common.error('no paths given');
|
||
|
||
if (typeof files === 'string')
|
||
files = [].slice.call(arguments, 2);
|
||
// if it's array leave it as it is
|
||
|
||
files = common.expand(files);
|
||
|
||
var grep = '';
|
||
files.forEach(function(file) {
|
||
if (!fs.existsSync(file)) {
|
||
common.error('no such file or directory: ' + file, true);
|
||
return;
|
||
}
|
||
|
||
var contents = fs.readFileSync(file, 'utf8'),
|
||
lines = contents.split(/\r*\n/);
|
||
lines.forEach(function(line) {
|
||
var matched = line.match(regex);
|
||
if ((options.inverse && !matched) || (!options.inverse && matched))
|
||
grep += line + '\n';
|
||
});
|
||
});
|
||
|
||
return common.ShellString(grep);
|
||
}
|
||
module.exports = _grep;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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");
|
||
var os = __webpack_require__(/*! os */ "os");
|
||
|
||
//@
|
||
//@ ### ln(options, source, dest)
|
||
//@ ### ln(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) {
|
||
options = common.parseOptions(options, {
|
||
's': 'symlink',
|
||
'f': 'force'
|
||
});
|
||
|
||
if (!source || !dest) {
|
||
common.error('Missing <source> and/or <dest>');
|
||
}
|
||
|
||
source = path.resolve(process.cwd(), String(source));
|
||
dest = path.resolve(process.cwd(), String(dest));
|
||
|
||
if (!fs.existsSync(source)) {
|
||
common.error('Source file does not exist', true);
|
||
}
|
||
|
||
if (fs.existsSync(dest)) {
|
||
if (!options.force) {
|
||
common.error('Destination file exists', true);
|
||
}
|
||
|
||
fs.unlinkSync(dest);
|
||
}
|
||
|
||
if (options.symlink) {
|
||
fs.symlinkSync(source, dest, os.platform() === "win32" ? "junction" : null);
|
||
} else {
|
||
fs.linkSync(source, dest, os.platform() === "win32" ? "junction" : null);
|
||
}
|
||
}
|
||
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 _cd = __webpack_require__(/*! ./cd */ "./node_modules/shelljs/src/cd.js");
|
||
var _pwd = __webpack_require__(/*! ./pwd */ "./node_modules/shelljs/src/pwd.js");
|
||
|
||
//@
|
||
//@ ### ls([options ,] path [,path ...])
|
||
//@ ### ls([options ,] path_array)
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-R`: recursive
|
||
//@ + `-A`: all files (include files beginning with `.`, except for `.` and `..`)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ ls('projs/*.js');
|
||
//@ ls('-R', '/users/me', '/tmp');
|
||
//@ ls('-R', ['/users/me', '/tmp']); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Returns array of files in the given path, or in current directory if no path provided.
|
||
function _ls(options, paths) {
|
||
options = common.parseOptions(options, {
|
||
'R': 'recursive',
|
||
'A': 'all',
|
||
'a': 'all_deprecated'
|
||
});
|
||
|
||
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 if (typeof paths === 'object')
|
||
paths = paths; // assume array
|
||
else if (typeof paths === 'string')
|
||
paths = [].slice.call(arguments, 1);
|
||
|
||
var list = [];
|
||
|
||
// Conditionally pushes file to list - returns true if pushed, false otherwise
|
||
// (e.g. prevents hidden files to be included unless explicitly told so)
|
||
function pushFile(file, query) {
|
||
// hidden file?
|
||
if (path.basename(file)[0] === '.') {
|
||
// not explicitly asking for hidden files?
|
||
if (!options.all && !(path.basename(query)[0] === '.' && path.basename(query).length > 1))
|
||
return false;
|
||
}
|
||
|
||
if (common.platform === 'win')
|
||
file = file.replace(/\\/g, '/');
|
||
|
||
list.push(file);
|
||
return true;
|
||
}
|
||
|
||
paths.forEach(function(p) {
|
||
if (fs.existsSync(p)) {
|
||
var stats = fs.statSync(p);
|
||
// Simple file?
|
||
if (stats.isFile()) {
|
||
pushFile(p, p);
|
||
return; // continue
|
||
}
|
||
|
||
// Simple dir?
|
||
if (stats.isDirectory()) {
|
||
// Iterate over p contents
|
||
fs.readdirSync(p).forEach(function(file) {
|
||
if (!pushFile(file, p))
|
||
return;
|
||
|
||
// Recursive?
|
||
if (options.recursive) {
|
||
var oldDir = _pwd();
|
||
_cd('', p);
|
||
if (fs.statSync(file).isDirectory())
|
||
list = list.concat(_ls('-R'+(options.all?'A':''), file+'/*'));
|
||
_cd('', oldDir);
|
||
}
|
||
});
|
||
return; // continue
|
||
}
|
||
}
|
||
|
||
// p does not exist - possible wildcard present
|
||
|
||
var basename = path.basename(p);
|
||
var dirname = path.dirname(p);
|
||
// Wildcard present on an existing dir? (e.g. '/tmp/*.js')
|
||
if (basename.search(/\*/) > -1 && fs.existsSync(dirname) && fs.statSync(dirname).isDirectory) {
|
||
// Escape special regular expression chars
|
||
var regexp = basename.replace(/(\^|\$|\(|\)|<|>|\[|\]|\{|\}|\.|\+|\?)/g, '\\$1');
|
||
// Translates wildcard into regex
|
||
regexp = '^' + regexp.replace(/\*/g, '.*') + '$';
|
||
// Iterate over directory contents
|
||
fs.readdirSync(dirname).forEach(function(file) {
|
||
if (file.match(new RegExp(regexp))) {
|
||
if (!pushFile(path.normalize(dirname+'/'+file), basename))
|
||
return;
|
||
|
||
// Recursive?
|
||
if (options.recursive) {
|
||
var pp = dirname + '/' + file;
|
||
if (fs.lstatSync(pp).isDirectory())
|
||
list = list.concat(_ls('-R'+(options.all?'A':''), pp+'/*'));
|
||
} // recursive
|
||
} // if file matches
|
||
}); // forEach
|
||
return;
|
||
}
|
||
|
||
common.error('no such file or directory: ' + p, true);
|
||
});
|
||
|
||
return list;
|
||
}
|
||
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");
|
||
|
||
// Recursively creates 'dir'
|
||
function mkdirSyncRecursive(dir) {
|
||
var baseDir = path.dirname(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 (will create intermediate dirs 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) {
|
||
options = common.parseOptions(options, {
|
||
'p': 'fullpath'
|
||
});
|
||
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) {
|
||
if (fs.existsSync(dir)) {
|
||
if (!options.fullpath)
|
||
common.error('path already exists: ' + dir, true);
|
||
return; // skip dir
|
||
}
|
||
|
||
// 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, true);
|
||
return; // skip dir
|
||
}
|
||
|
||
if (options.fullpath)
|
||
mkdirSyncRecursive(dir);
|
||
else
|
||
fs.mkdirSync(dir, parseInt('0777', 8));
|
||
});
|
||
} // 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");
|
||
|
||
//@
|
||
//@ ### mv(source [, source ...], dest')
|
||
//@ ### mv(source_array, dest')
|
||
//@ Available options:
|
||
//@
|
||
//@ + `f`: force
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ mv('-f', 'file', 'dir/');
|
||
//@ mv('file1', 'file2', 'dir/');
|
||
//@ mv(['file1', 'file2'], 'dir/'); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Moves files. The wildcard `*` is accepted.
|
||
function _mv(options, sources, dest) {
|
||
options = common.parseOptions(options, {
|
||
'f': 'force'
|
||
});
|
||
|
||
// 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 if ('length' in sources) {
|
||
sources = sources; // no-op for array
|
||
} else {
|
||
common.error('invalid arguments');
|
||
}
|
||
|
||
sources = common.expand(sources);
|
||
|
||
var exists = fs.existsSync(dest),
|
||
stats = exists && fs.statSync(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.force)
|
||
common.error('dest file already exists: ' + dest);
|
||
|
||
sources.forEach(function(src) {
|
||
if (!fs.existsSync(src)) {
|
||
common.error('no such file or directory: '+src, true);
|
||
return; // skip file
|
||
}
|
||
|
||
// If here, src exists
|
||
|
||
// When copying to '/path/dir':
|
||
// thisDest = '/path/dir/file1'
|
||
var thisDest = dest;
|
||
if (fs.existsSync(dest) && fs.statSync(dest).isDirectory())
|
||
thisDest = path.normalize(dest + '/' + path.basename(src));
|
||
|
||
if (fs.existsSync(thisDest) && !options.force) {
|
||
common.error('dest file already exists: ' + thisDest, true);
|
||
return; // skip file
|
||
}
|
||
|
||
if (path.resolve(src) === path.dirname(path.resolve(thisDest))) {
|
||
common.error('cannot move to self: '+src, true);
|
||
return; // skip file
|
||
}
|
||
|
||
fs.renameSync(src, thisDest);
|
||
}); // forEach(src)
|
||
} // mv
|
||
module.exports = _mv;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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");
|
||
|
||
//@
|
||
//@ ### pwd()
|
||
//@ Returns the current directory.
|
||
function _pwd(options) {
|
||
var pwd = path.resolve(process.cwd());
|
||
return common.ShellString(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");
|
||
|
||
// 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) {
|
||
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],
|
||
currFile = fs.lstatSync(file);
|
||
|
||
if(currFile.isDirectory()) { // Recursive function back to the beginning
|
||
rmdirSyncRecursive(file, force);
|
||
}
|
||
|
||
else if(currFile.isSymbolicLink()) { // Unlink symlinks
|
||
if (force || isWriteable(file)) {
|
||
try {
|
||
common.unlinkSync(file);
|
||
} catch (e) {
|
||
common.error('could not remove file (code '+e.code+'): ' + file, true);
|
||
}
|
||
}
|
||
}
|
||
|
||
else // Assume it's a file - perhaps a try/catch belongs here?
|
||
if (force || isWriteable(file)) {
|
||
try {
|
||
common.unlinkSync(file);
|
||
} catch (e) {
|
||
common.error('could not remove file (code '+e.code+'): ' + file, true);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 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 {
|
||
result = fs.rmdirSync(dir);
|
||
} catch(e) {
|
||
common.error('could not remove directory (code '+e.code+'): ' + dir, 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;
|
||
}
|
||
|
||
//@
|
||
//@ ### 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. The wildcard `*` is accepted.
|
||
function _rm(options, files) {
|
||
options = common.parseOptions(options, {
|
||
'f': 'force',
|
||
'r': 'recursive',
|
||
'R': 'recursive'
|
||
});
|
||
if (!files)
|
||
common.error('no paths given');
|
||
|
||
if (typeof files === 'string')
|
||
files = [].slice.call(arguments, 1);
|
||
// if it's array leave it as it is
|
||
|
||
files = common.expand(files);
|
||
|
||
files.forEach(function(file) {
|
||
if (!fs.existsSync(file)) {
|
||
// Path does not exist, no force flag given
|
||
if (!options.force)
|
||
common.error('no such file or directory: '+file, true);
|
||
|
||
return; // skip file
|
||
}
|
||
|
||
// If here, path exists
|
||
|
||
var stats = fs.lstatSync(file);
|
||
if (stats.isFile() || stats.isSymbolicLink()) {
|
||
|
||
// Do not check for file writing permissions
|
||
if (options.force) {
|
||
common.unlinkSync(file);
|
||
return;
|
||
}
|
||
|
||
if (isWriteable(file))
|
||
common.unlinkSync(file);
|
||
else
|
||
common.error('permission denied: '+file, true);
|
||
|
||
return;
|
||
} // simple file
|
||
|
||
// Path is an existing directory, but no -r flag given
|
||
if (stats.isDirectory() && !options.recursive) {
|
||
common.error('path is a directory', true);
|
||
return; // skip path
|
||
}
|
||
|
||
// Recursively remove existing directory
|
||
if (stats.isDirectory() && options.recursive) {
|
||
rmdirSyncRecursive(file, options.force);
|
||
}
|
||
}); // forEach(file)
|
||
} // 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");
|
||
|
||
//@
|
||
//@ ### sed([options ,] search_regex, replacement, file)
|
||
//@ 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` and performs a JavaScript `replace()` on the input
|
||
//@ using the given search regex and replacement string or function. Returns the new string after replacement.
|
||
function _sed(options, regex, replacement, file) {
|
||
options = common.parseOptions(options, {
|
||
'i': 'inplace'
|
||
});
|
||
|
||
if (typeof replacement === 'string' || typeof replacement === 'function')
|
||
replacement = replacement; // no-op
|
||
else if (typeof replacement === 'number')
|
||
replacement = replacement.toString(); // fallback
|
||
else
|
||
common.error('invalid replacement string');
|
||
|
||
if (!file)
|
||
common.error('no file given');
|
||
|
||
if (!fs.existsSync(file))
|
||
common.error('no such file or directory: ' + file);
|
||
|
||
var result = fs.readFileSync(file, 'utf8').replace(regex, replacement);
|
||
if (options.inplace)
|
||
fs.writeFileSync(file, result, 'utf8');
|
||
|
||
return common.ShellString(result);
|
||
}
|
||
module.exports = _sed;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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");
|
||
|
||
// Returns false if 'dir' is not a writeable directory, 'dir' otherwise
|
||
function writeableDir(dir) {
|
||
if (!dir || !fs.existsSync(dir))
|
||
return false;
|
||
|
||
if (!fs.statSync(dir).isDirectory())
|
||
return false;
|
||
|
||
var testFile = dir+'/'+common.randomFileName();
|
||
try {
|
||
fs.writeFileSync(testFile, ' ');
|
||
common.unlinkSync(testFile);
|
||
return dir;
|
||
} catch (e) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
//@
|
||
//@ ### 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() {
|
||
var state = common.state;
|
||
if (state.tempDir)
|
||
return state.tempDir; // from cache
|
||
|
||
state.tempDir = writeableDir(os.tempDir && os.tempDir()) || // node 0.8+
|
||
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 state.tempDir;
|
||
}
|
||
module.exports = _tempDir;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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");
|
||
|
||
//@
|
||
//@ ### 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 symboilc 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');
|
||
|
||
// hack - only works with unary primaries
|
||
options = common.parseOptions(options, {
|
||
'b': 'block',
|
||
'c': 'character',
|
||
'd': 'directory',
|
||
'e': 'exists',
|
||
'f': 'file',
|
||
'L': 'link',
|
||
'p': 'pipe',
|
||
'S': 'socket'
|
||
});
|
||
|
||
var canInterpret = false;
|
||
for (var key in options)
|
||
if (options[key] === true) {
|
||
canInterpret = true;
|
||
break;
|
||
}
|
||
|
||
if (!canInterpret)
|
||
common.error('could not interpret expression');
|
||
|
||
if (options.link) {
|
||
try {
|
||
return fs.lstatSync(path).isSymbolicLink();
|
||
} catch(e) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
if (!fs.existsSync(path))
|
||
return false;
|
||
|
||
if (options.exists)
|
||
return true;
|
||
|
||
var stats = fs.statSync(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();
|
||
|
||
if (options.pipe)
|
||
return stats.isFIFO();
|
||
|
||
if (options.socket)
|
||
return stats.isSocket();
|
||
} // 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");
|
||
|
||
//@
|
||
//@ ### 'string'.to(file)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ cat('input.txt').to('output.txt');
|
||
//@ ```
|
||
//@
|
||
//@ Analogous to the redirection operator `>` in Unix, but works with JavaScript strings (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.toString(), 'utf8');
|
||
} catch(e) {
|
||
common.error('could not write to file (code '+e.code+'): '+file, 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");
|
||
|
||
//@
|
||
//@ ### 'string'.toEnd(file)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ cat('input.txt').toEnd('output.txt');
|
||
//@ ```
|
||
//@
|
||
//@ Analogous to the redirect-and-append operator `>>` in Unix, but works with JavaScript strings (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.toString(), 'utf8');
|
||
} catch(e) {
|
||
common.error('could not append to file (code '+e.code+'): '+file, true);
|
||
}
|
||
}
|
||
module.exports = _toEnd;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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");
|
||
|
||
// Cross-platform method for splitting environment PATH variables
|
||
function splitPath(p) {
|
||
for (i=1;i<2;i++) {}
|
||
|
||
if (!p)
|
||
return [];
|
||
|
||
if (common.platform === 'win')
|
||
return p.split(';');
|
||
else
|
||
return p.split(':');
|
||
}
|
||
|
||
function checkPath(path) {
|
||
return fs.existsSync(path) && fs.statSync(path).isDirectory() == false;
|
||
}
|
||
|
||
//@
|
||
//@ ### which(command)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var nodeExec = which('node');
|
||
//@ ```
|
||
//@
|
||
//@ Searches for `command` in the system's PATH. On Windows looks for `.exe`, `.cmd`, and `.bat` extensions.
|
||
//@ Returns string containing the absolute path to the command.
|
||
function _which(options, cmd) {
|
||
if (!cmd)
|
||
common.error('must specify command');
|
||
|
||
var pathEnv = process.env.path || process.env.Path || process.env.PATH,
|
||
pathArray = splitPath(pathEnv),
|
||
where = null;
|
||
|
||
// No relative/absolute paths provided?
|
||
if (cmd.search(/\//) === -1) {
|
||
// Search for command in PATH
|
||
pathArray.forEach(function(dir) {
|
||
if (where)
|
||
return; // already found it
|
||
|
||
var attempt = path.resolve(dir + '/' + cmd);
|
||
if (checkPath(attempt)) {
|
||
where = attempt;
|
||
return;
|
||
}
|
||
|
||
if (common.platform === 'win') {
|
||
var baseAttempt = attempt;
|
||
attempt = baseAttempt + '.exe';
|
||
if (checkPath(attempt)) {
|
||
where = attempt;
|
||
return;
|
||
}
|
||
attempt = baseAttempt + '.cmd';
|
||
if (checkPath(attempt)) {
|
||
where = attempt;
|
||
return;
|
||
}
|
||
attempt = baseAttempt + '.bat';
|
||
if (checkPath(attempt)) {
|
||
where = attempt;
|
||
return;
|
||
}
|
||
} // if 'win'
|
||
});
|
||
}
|
||
|
||
// Command not found anywhere?
|
||
if (!checkPath(cmd) && !where)
|
||
return null;
|
||
|
||
where = where || path.resolve(cmd);
|
||
|
||
return common.ShellString(where);
|
||
}
|
||
module.exports = _which;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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/create.ts":
|
||
/*!***********************************************!*\
|
||
!*** ./src/tasks/gitreleasemanager/create.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.create();
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./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(new RegExp(bypass, 'i'));
|
||
});
|
||
}
|
||
this.requestOptions = requestOptions;
|
||
if (requestOptions) {
|
||
if (requestOptions.ignoreSslError != null) {
|
||
this._ignoreSslError = requestOptions.ignoreSslError;
|
||
}
|
||
this._socketTimeout = requestOptions.socketTimeout;
|
||
this._httpProxy = requestOptions.proxy;
|
||
if (requestOptions.proxy && requestOptions.proxy.proxyBypassHosts) {
|
||
this._httpProxyBypassHosts = [];
|
||
requestOptions.proxy.proxyBypassHosts.forEach(bypass => {
|
||
this._httpProxyBypassHosts.push(new RegExp(bypass, 'i'));
|
||
});
|
||
}
|
||
this._certConfig = requestOptions.cert;
|
||
if (this._certConfig) {
|
||
// If using cert, need fs
|
||
fs = __webpack_require__(/*! fs */ "fs");
|
||
// cache the cert content into memory, so we don't have to read it from disk every time
|
||
if (this._certConfig.caFile && fs.existsSync(this._certConfig.caFile)) {
|
||
this._ca = fs.readFileSync(this._certConfig.caFile, 'utf8');
|
||
}
|
||
if (this._certConfig.certFile && fs.existsSync(this._certConfig.certFile)) {
|
||
this._cert = fs.readFileSync(this._certConfig.certFile, 'utf8');
|
||
}
|
||
if (this._certConfig.keyFile && fs.existsSync(this._certConfig.keyFile)) {
|
||
this._key = fs.readFileSync(this._certConfig.keyFile, 'utf8');
|
||
}
|
||
}
|
||
if (requestOptions.allowRedirects != null) {
|
||
this._allowRedirects = requestOptions.allowRedirects;
|
||
}
|
||
if (requestOptions.allowRedirectDowngrade != null) {
|
||
this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade;
|
||
}
|
||
if (requestOptions.maxRedirects != null) {
|
||
this._maxRedirects = Math.max(requestOptions.maxRedirects, 0);
|
||
}
|
||
if (requestOptions.keepAlive != null) {
|
||
this._keepAlive = requestOptions.keepAlive;
|
||
}
|
||
if (requestOptions.allowRetries != null) {
|
||
this._allowRetries = requestOptions.allowRetries;
|
||
}
|
||
if (requestOptions.maxRetries != null) {
|
||
this._maxRetries = requestOptions.maxRetries;
|
||
}
|
||
}
|
||
}
|
||
options(requestUrl, additionalHeaders) {
|
||
return this.request('OPTIONS', requestUrl, null, additionalHeaders || {});
|
||
}
|
||
get(requestUrl, additionalHeaders) {
|
||
return this.request('GET', requestUrl, null, additionalHeaders || {});
|
||
}
|
||
del(requestUrl, additionalHeaders) {
|
||
return this.request('DELETE', requestUrl, null, additionalHeaders || {});
|
||
}
|
||
post(requestUrl, data, additionalHeaders) {
|
||
return this.request('POST', requestUrl, data, additionalHeaders || {});
|
||
}
|
||
patch(requestUrl, data, additionalHeaders) {
|
||
return this.request('PATCH', requestUrl, data, additionalHeaders || {});
|
||
}
|
||
put(requestUrl, data, additionalHeaders) {
|
||
return this.request('PUT', requestUrl, data, additionalHeaders || {});
|
||
}
|
||
head(requestUrl, additionalHeaders) {
|
||
return this.request('HEAD', requestUrl, null, additionalHeaders || {});
|
||
}
|
||
sendStream(verb, requestUrl, stream, additionalHeaders) {
|
||
return this.request(verb, requestUrl, stream, additionalHeaders);
|
||
}
|
||
/**
|
||
* Makes a raw http request.
|
||
* All other methods such as get, post, patch, and request ultimately call this.
|
||
* Prefer get, del, post and patch
|
||
*/
|
||
request(verb, requestUrl, data, headers) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
if (this._disposed) {
|
||
throw new Error("Client has already been disposed.");
|
||
}
|
||
let parsedUrl = url.parse(requestUrl);
|
||
let info = this._prepareRequest(verb, parsedUrl, headers);
|
||
// Only perform retries on reads since writes may not be idempotent.
|
||
let maxTries = (this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1) ? this._maxRetries + 1 : 1;
|
||
let numTries = 0;
|
||
let response;
|
||
while (numTries < maxTries) {
|
||
try {
|
||
response = yield this.requestRaw(info, data);
|
||
}
|
||
catch (err) {
|
||
if (err && err.code && NetworkRetryErrors.indexOf(err.code) > -1) {
|
||
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.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;
|
||
/**
|
||
* 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
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "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
|
||
/******/ if(__webpack_module_cache__[moduleId]) {
|
||
/******/ return __webpack_module_cache__[moduleId].exports;
|
||
/******/ }
|
||
/******/ // Create a new module (and put it into the cache)
|
||
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||
/******/ // no module.id needed
|
||
/******/ // no module.loaded needed
|
||
/******/ exports: {}
|
||
/******/ };
|
||
/******/
|
||
/******/ // Execute the module function
|
||
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||
/******/
|
||
/******/ // Return the exports of the module
|
||
/******/ return module.exports;
|
||
/******/ }
|
||
/******/
|
||
/************************************************************************/
|
||
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
||
/******/ (() => {
|
||
/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
|
||
/******/ })();
|
||
/******/
|
||
/************************************************************************/
|
||
/******/ // module exports must be returned from runtime so entry inlining is disabled
|
||
/******/ // startup
|
||
/******/ // Load entry module and return exports
|
||
/******/ return __webpack_require__("./src/tasks/gitreleasemanager/create.ts");
|
||
/******/ })()
|
||
;
|
||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10YXNrLWxpYi9pbnRlcm5hbC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10YXNrLWxpYi9ub2RlX21vZHVsZXMvdXVpZC9saWIvYnl0ZXNUb1V1aWQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9henVyZS1waXBlbGluZXMtdGFzay1saWIvbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10YXNrLWxpYi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10YXNrLWxpYi90YXNrLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvYXp1cmUtcGlwZWxpbmVzLXRhc2stbGliL3Rhc2tjb21tYW5kLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvYXp1cmUtcGlwZWxpbmVzLXRhc2stbGliL3Rvb2xydW5uZXIuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9henVyZS1waXBlbGluZXMtdGFzay1saWIvdmF1bHQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9henVyZS1waXBlbGluZXMtdGFzay1saWJ8c3luYyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10b29sLWxpYi9ub2RlX21vZHVsZXMvdXVpZC9saWIvYnl0ZXNUb1V1aWQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9henVyZS1waXBlbGluZXMtdG9vbC1saWIvbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10b29sLWxpYi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10b29sLWxpYi90b29sLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvYXp1cmUtcGlwZWxpbmVzLXRvb2wtbGlifHN5bmMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9iYWxhbmNlZC1tYXRjaC9pbmRleC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2JyYWNlLWV4cGFuc2lvbi9pbmRleC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2NvbmNhdC1tYXAvaW5kZXguanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2Fubm90YXRpb24vZGVjb3JhdG9yX3V0aWxzLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9hbm5vdGF0aW9uL2luamVjdC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYW5ub3RhdGlvbi9pbmplY3RhYmxlLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9hbm5vdGF0aW9uL211bHRpX2luamVjdC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYW5ub3RhdGlvbi9uYW1lZC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYW5ub3RhdGlvbi9vcHRpb25hbC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYW5ub3RhdGlvbi9wb3N0X2NvbnN0cnVjdC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYW5ub3RhdGlvbi90YWdnZWQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2Fubm90YXRpb24vdGFyZ2V0X25hbWUuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2Fubm90YXRpb24vdW5tYW5hZ2VkLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9iaW5kaW5ncy9iaW5kaW5nLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9iaW5kaW5ncy9iaW5kaW5nX2NvdW50LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9jb25zdGFudHMvZXJyb3JfbXNncy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvY29uc3RhbnRzL2xpdGVyYWxfdHlwZXMuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9jb250YWluZXIvY29udGFpbmVyLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9jb250YWluZXIvY29udGFpbmVyX21vZHVsZS5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvY29udGFpbmVyL2NvbnRhaW5lcl9zbmFwc2hvdC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvY29udGFpbmVyL2xvb2t1cC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvaW52ZXJzaWZ5LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9jb250ZXh0LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9tZXRhZGF0YS5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvcGxhbm5pbmcvbWV0YWRhdGFfcmVhZGVyLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9wbGFuLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9wbGFubmVyLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9xdWVyeWFibGVfc3RyaW5nLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9yZWZsZWN0aW9uX3V0aWxzLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9yZXF1ZXN0LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy90YXJnZXQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL3Jlc29sdXRpb24vaW5zdGFudGlhdGlvbi5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvcmVzb2x1dGlvbi9yZXNvbHZlci5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvc3ludGF4L2JpbmRpbmdfaW5fc3ludGF4LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9zeW50YXgvYmluZGluZ19pbl93aGVuX29uX3N5bnRheC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvc3ludGF4L2JpbmRpbmdfb25fc3ludGF4LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9zeW50YXgvYmluZGluZ190b19zeW50YXguanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL3N5bnRheC9iaW5kaW5nX3doZW5fb25fc3ludGF4LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9zeW50YXgvYmluZGluZ193aGVuX3N5bnRheC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvc3ludGF4L2NvbnN0cmFpbnRfaGVscGVycy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvdXRpbHMvYmluZGluZ191dGlscy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvdXRpbHMvZXhjZXB0aW9ucy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvdXRpbHMvaWQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL3V0aWxzL3NlcmlhbGl6YXRpb24uanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9taW5pbWF0Y2gvbWluaW1hdGNoLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvcS9xLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvcXMvbGliL2Zvcm1hdHMuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9xcy9saWIvaW5kZXguanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9xcy9saWIvcGFyc2UuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9xcy9saWIvc3RyaW5naWZ5LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvcXMvbGliL3V0aWxzLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvcmVmbGVjdC1tZXRhZGF0YS9SZWZsZWN0LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2VtdmVyLWNvbXBhcmUvaW5kZXguanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zZW12ZXIvc2VtdmVyLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zaGVsbC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2NhdC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2NkLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvY2htb2QuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9jb21tb24uanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9jcC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2RpcnMuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9lY2hvLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvZXJyb3IuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9leGVjLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvZmluZC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2dyZXAuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9sbi5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2xzLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvbWtkaXIuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9tdi5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3B3ZC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3JtLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvc2VkLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdGVtcGRpci5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3Rlc3QuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy90by5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3RvRW5kLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvd2hpY2guanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL3NyYy9hZ2VudC9henVyZS9idWlsZC1hZ2VudC50cyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vc3JjL2NvcmUvZG90bmV0LXRvb2wudHMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL3NyYy9jb3JlL2lvYy50cyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vc3JjL2NvcmUvbW9kZWxzLnRzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9zcmMvY29yZS9zZXR0aW5ncy50cyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vc3JjL2NvcmUvdmVyc2lvbk1hbmFnZXIudHMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL3NyYy90YXNrcy9naXRyZWxlYXNlbWFuYWdlci9jcmVhdGUudHMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL3NyYy90YXNrcy9naXRyZWxlYXNlbWFuYWdlci9tYWluLnRzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9zcmMvdG9vbHMvZ2l0cmVsZWFzZW1hbmFnZXIvbW9kZWxzLnRzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9zcmMvdG9vbHMvZ2l0cmVsZWFzZW1hbmFnZXIvc2V0dGluZ3MudHMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL3NyYy90b29scy9naXRyZWxlYXNlbWFuYWdlci90b29sLnRzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvdHlwZWQtcmVzdC1jbGllbnQvSHR0cENsaWVudC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3R5cGVkLXJlc3QtY2xpZW50L1V0aWwuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy90eXBlZC1yZXN0LWNsaWVudC9ub2RlX21vZHVsZXMvdHVubmVsL2luZGV4LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvdHlwZWQtcmVzdC1jbGllbnQvbm9kZV9tb2R1bGVzL3R1bm5lbC9saWIvdHVubmVsLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvZXh0ZXJuYWwgXCJhc3NlcnRcIiIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL2V4dGVybmFsIFwiY2hpbGRfcHJvY2Vzc1wiIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvZXh0ZXJuYWwgXCJjcnlwdG9cIiIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL2V4dGVybmFsIFwiZXZlbnRzXCIiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy9leHRlcm5hbCBcImZzXCIiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy9leHRlcm5hbCBcImh0dHBcIiIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL2V4dGVybmFsIFwiaHR0cHNcIiIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL2V4dGVybmFsIFwibmV0XCIiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy9leHRlcm5hbCBcIm9zXCIiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy9leHRlcm5hbCBcInBhdGhcIiIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL2V4dGVybmFsIFwicHJvY2Vzc1wiIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvZXh0ZXJuYWwgXCJ0bHNcIiIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL2V4dGVybmFsIFwidXJsXCIiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy9leHRlcm5hbCBcInV0aWxcIiIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL2V4dGVybmFsIFwiemxpYlwiIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy93ZWJwYWNrL3J1bnRpbWUvaGFzT3duUHJvcGVydHkgc2hvcnRoYW5kIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvd2VicGFjay9zdGFydHVwIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQWE7QUFDYiw4Q0FBNkMsQ0FB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Q0EsMkNBQTJDLGdFQUFnRTtBQUMzRztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQyw0QkFBNEI7QUFDbEUsc0NBQXNDO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQyxnQkFBZ0I7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRDtBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtDQUErQyx3QkFBd0I7QUFDdkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0RBQStELDRCQUE0QjtBQUMzRjtB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRGQUE0RjtBQUM1RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELGdCQUFnQjtBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxtQkFBbUI7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRCxtQkFBbUIsRUFBRTtBQUNyRSx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBLHFDQUFxQyxtQkFBbUI7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxPQUFPLE9BQU87QUFDOUM7QUFDQTtBQUNBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsT0FBTyxPQUFPO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixTQUFTO0FBQ1Q7QUFDQSw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFt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Q0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxLQUFLO0FBQ0wsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLElBQUk7QUFDdkM7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLEVBQUUsRUFBRSxLQUFLO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxRQUFRO0FBQ2hEOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLHNCQUFzQjtBQUNyQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSw2Q0FBNkM7QUFDN0M7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixRQUFRO0FBQ2hDO0FBQ0E7QUFDQTs7QUFFQSxhQUFhLGdCQUFnQjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLLDZDQUE2Qzs7QUFFbEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxTQUFTO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwyQkFBMkI7QUFDM0I7Ozs7Ozs7Ozs7O0FDMTVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLLFVBQVUsSUFBeUQ7QUFDeEU7O0FBRUE7QUFDQSxLQUFLLE1BQU0sMEJBK0JOOztBQUVMLENBQUM7QUFDRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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QWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtDQUFrQyxjQUFjLEVBQUU7QUFDbEQ7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0NBQWtDLGNBQWMsRUFBRTtBQUNsRDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMLGdCQUFnQjtBQUNoQixLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLGdCQUFnQjtBQUNoQixLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxXQUFXLFNBQVM7QUFDcEIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLHlDQUF5QyxnQ0FBZ0M7QUFDekU7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1QsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFlBQVk7QUFDdkI7QUFDQSxhQUFhLGFBQWE7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsS0FBSztBQUNoQixXQUFXLFNBQVM7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEtBQUs7QUFDaEIsV0FBVyxTQUFTO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsS0FBSztBQUNoQixXQUFXLFNBQVM7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxLQUFLO0FBQ2hCO0FBQ0E7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OztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsbUJBQW1CLGlCQUFpQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7QUMzUWE7O0FBRWIsWUFBWSxtQkFBTyxDQUFDLCtDQUFTO0FBQzdCLGNBQWMsbUJBQU8sQ0FBQyxtREFBVztBQUNqQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUEsbUJBQW1CLG9CQUFvQjtBQUN2Qzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsb0JBQW9CO0FBQ3ZDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDJDQUEyQztBQUMzQztBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFD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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQyw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEM7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkMsMkNBQTJDO0FBQzNDLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1R0FBdUc7QUFDdkc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkMsMkNBQTJDO0FBQzNDLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdGQUFnRjtBQUNoRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQywyQ0FBMkM7QUFDM0MsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUVBQXFFO0FBQ3JFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQyw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxRUFBcUU7QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkMsMkNBQTJDO0FBQzNDLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQyw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQywyQ0FBMkM7QUFDM0MsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUVBQXVFO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQyw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0NBQStDLFFBQVE7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtDQUErQyxRQUFRO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWlELHVCQUF1QjtBQUN4RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVEQUF1RCwwQkFBMEI7QUFDakY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTLFVBQVU7QUFDbkIsVUFBVSxXQUFXO0FBQ3JCOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixvQ0FBb0M7QUFDeEQsMEJBQTBCLG9DQUFvQztBQUM5RCwwQkFBMEIsb0NBQW9DO0FBQzlEOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUEsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxjQUFjOztBQUVkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUEsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQjs7QUFFMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDJCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7O0FBRUEsYUFBYTtBQUNiO0FBQ0E7QUFDQTs7QUFFQSxhQUFhO0FBQ2I7QUFDQTtBQUNBOztBQUVBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7O0FBRUEsZUFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQSxvQkFBb0I7QUFDcEI7QUFDQTtBQUNBOztBQUVBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7O0FBRUEsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7O0FBRUEsVUFBVTtBQUNWO0FBQ0E7QUFDQTs7QUFFQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBOztBQUVBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7O0FBRUEsV0FBVztBQUNYO0FBQ0E7QUFDQTs7QUFFQSxXQUFXO0FBQ1g7QUFDQTtBQUNBOztBQUVBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsT0FBTztBQUNQLEtBQUs7QUFDTCxHQUFHO0FBQ0g7O0FBRUE7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLGlCQUFpQixxQkFBcUI7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLGdCQUFnQjtBQUNqQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGdCQUFnQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUEscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBLGtCQUFrQjtBQUNsQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLHNCQUFzQjtBQUN2Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7O0FBRUEsZUFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGlCQUFpQixzQkFBc0I7QUFDdkM7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0I7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7QUMxOENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGFBQWEsbUJBQU8sQ0FBQywwREFBYzs7O0FBR25DO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFVBQVUsbUJBQU8sQ0FBQyxrREFBVTtBQUM1QixVQUFVOztBQUVWO0FBQ0EsV0FBVyxtQkFBTyxDQUFDLG9EQUFXO0FBQzlCLFdBQVc7O0FBRVg7QUFDQSxVQUFVLG1CQUFPLENBQUMsa0RBQVU7QUFDNUIsVUFBVTs7QUFFVjtBQUNBLFlBQVksbUJBQU8sQ0FBQyxzREFBWTtBQUNoQyxZQUFZOztBQUVaO0FBQ0EsVUFBVSxtQkFBTyxDQUFDLGtEQUFVO0FBQzVCLFVBQVU7O0FBRVY7QUFDQSxVQUFVLG1CQUFPLENBQUMsa0RBQVU7QUFDNUIsVUFBVTs7QUFFVjtBQUNBLFVBQVUsbUJBQU8sQ0FBQyxrREFBVTtBQUM1QixVQUFVOztBQUVWO0FBQ0EsYUFBYSxtQkFBTyxDQUFDLHdEQUFhO0FBQ2xDLGFBQWE7O0FBRWI7QUFDQSxZQUFZLG1CQUFPLENBQUMsc0RBQVk7QUFDaEMsWUFBWTs7QUFFWjtBQUNBLFdBQVcsbUJBQU8sQ0FBQyxvREFBVztBQUM5QixXQUFXOztBQUVYO0FBQ0EsVUFBVSxtQkFBTyxDQUFDLGtEQUFVO0FBQzVCOztBQUVBO0FBQ0EsYUFBYSxtQkFBTyxDQUFDLHdEQUFhO0FBQ2xDOztBQUVBO0FBQ0EsV0FBVyxtQkFBTyxDQUFDLG9EQUFXO0FBQzlCLFdBQVc7O0FBRVg7QUFDQSxZQUFZLG1CQUFPLENBQUMsc0RBQVk7QUFDaEMsWUFBWTs7QUFFWjtBQUNBLGFBQWEsbUJBQU8sQ0FBQyx3REFBYTtBQUNsQyxhQUFhOztBQUViO0FBQ0EsWUFBWSxtQkFBTyxDQUFDLHNEQUFZO0FBQ2hDLFlBQVksU0FBUzs7QUFFckI7QUFDQSxZQUFZLGdGQUEwQjtBQUN0QyxZQUFZO0FBQ1osYUFBYSxpRkFBMkI7QUFDeEMsYUFBYTtBQUNiLFlBQVksZ0ZBQTBCO0FBQ3RDLFlBQVk7O0FBRVo7QUFDQSxVQUFVLG1CQUFPLENBQUMsa0RBQVU7QUFDNUIsVUFBVTs7QUFFVjtBQUNBO0FBQ0E7QUFDQSxZQUFZOztBQUVaO0FBQ0E7QUFDQTtBQUNBLFdBQVc7O0FBRVg7QUFDQSxZQUFZLG1CQUFPLENBQUMsc0RBQVk7QUFDaEMsWUFBWSwrQkFBK0IsYUFBYTs7QUFFeEQ7QUFDQSxhQUFhLG1CQUFPLENBQUMsd0RBQWE7QUFDbEMsYUFBYTs7OztBQUliO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGVBQWUsbUJBQU8sQ0FBQyw0REFBZTtBQUN0QyxlQUFlOzs7QUFHZjtBQUNBLGFBQWEsbUJBQU8sQ0FBQyx3REFBYTtBQUNsQyxhQUFhOzs7O0FBSWI7QUFDQTtBQUNBOztBQUVBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQztBQUNwQztBQUNBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRDtBQUNoRDtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7QUM1SkEsYUFBYSxtQkFBTyxDQUFDLHNEQUFVO0FBQy9CLFNBQVMsbUJBQU8sQ0FBQyxjQUFJOztBQUVyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7QUMxQ0EsU0FBUyxtQkFBTyxDQUFDLGNBQUk7QUFDckIsYUFBYSxtQkFBTyxDQUFDLHNEQUFVOztBQUUvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7QUNsQkEsYUFBYSxtQkFBTyxDQUFDLHNEQUFVO0FBQy9CLFNBQVMsbUJBQU8sQ0FBQyxjQUFJO0FBQ3JCLFdBQVcsbUJBQU8sQ0FBQyxrQkFBTTs7QUFFekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGlDQUFpQztBQUNqQztBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7Ozs7Ozs7Ozs7QUMvTUEsU0FBUyxtQkFBTyxDQUFDLGNBQUk7QUFDckIsU0FBUyxtQkFBTyxDQUFDLGNBQUk7QUFDckIsVUFBVSxtQkFBTyxDQUFDLDhDQUFNOztBQUV4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYzs7QUFFZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTs7QUFFYjtBQUNBLGdCQUFnQjs7QUFFaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXOztBQUVYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQjs7QUFFbkIsWUFBWSw0QkFBNEI7QUFDeEMseUJBQXlCLHVCQUF1QjtBQUNoRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxtQkFBbUI7O0FBRW5CO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0Esb0JBQW9COztBQUVwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsY0FBYzs7QUFFZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCOztBQUVsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxzQkFBc0I7O0FBRXRCO0FBQ0E7QUFDQSxjQUFjLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxXQUFXO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQSxjQUFjOztBQUVkO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRCxZQUFZOzs7Ozs7Ozs7OztBQzFNWixTQUFTLG1CQUFPLENBQUMsY0FBSTtBQUNyQixXQUFXLG1CQUFPLENBQUMsa0JBQU07QUFDekIsYUFBYSxtQkFBTyxDQUFDLHNEQUFVO0FBQy9CLFNBQVMsbUJBQU8sQ0FBQyxjQUFJOztBQUVyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsMERBQTBEO0FBQzFEO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsaUJBQWlCLGtCQUFrQjtBQUNuQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQSxHQUFHO0FBQ0gsQ0FBQzs7O0FBR0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1REFBdUQ7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0gsc0JBQXNCO0FBQ3RCLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQSwwQ0FBMEMscUJBQXFCO0FBQy9EO0FBQ0EsYUFBYTtBQUNiOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWE7QUFDYjs7QUFFQTtBQUNBLEdBQUcsRUFBRTtBQUNMO0FBQ0E7Ozs7Ozs7Ozs7O0FDeE1BLGFBQWEsbUJBQU8sQ0FBQyxzREFBVTtBQUMvQixVQUFVLG1CQUFPLENBQUMsOENBQU07QUFDeEIsV0FBVyxtQkFBTyxDQUFDLGtCQUFNOztBQUV6QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaURBQWlEO0FBQ2pEO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHOztBQUVIOztBQUVBO0FBQ0EsZ0JBQWdCO0FBQ2hCLEdBQUc7QUFDSDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QjtBQUN4QixrQkFBa0I7QUFDbEIsd0JBQXdCO0FBQ3hCLFdBQVc7QUFDWCx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBLDZNQUE2TTtBQUM3TTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxZQUFZOztBQUVaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxZQUFZOzs7Ozs7Ozs7OztBQzlMWixhQUFhLG1CQUFPLENBQUMsc0RBQVU7O0FBRS9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7QUNuQkEsYUFBYSxtQkFBTyxDQUFDLHNEQUFVOztBQUUvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7OztBQ1RBLGFBQWEsbUJBQU8sQ0FBQyxzREFBVTtBQUMvQixlQUFlLG1CQUFPLENBQUMsd0RBQVc7QUFDbEMsV0FBVyxtQkFBTyxDQUFDLGdEQUFPO0FBQzFCLFdBQVcsbUJBQU8sQ0FBQyxrQkFBTTtBQUN6QixTQUFTLG1CQUFPLENBQUMsY0FBSTtBQUNyQixZQUFZLG1CQUFPLENBQUMsb0NBQWU7O0FBRW5DO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsa0NBQWtDOztBQUVsQztBQUNBO0FBQ0EsNEJBQTRCO0FBQzVCLG1DQUFtQywwQ0FBMEMsaUJBQWlCO0FBQzlGLGdGQUFnRjtBQUNoRixLQUFLLEVBQUU7O0FBRVA7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLGdCQUFnQixrQ0FBa0M7QUFDdEYsc0NBQXNDLGdCQUFnQixrQ0FBa0M7O0FBRXhGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLE9BQU8sK0JBQStCLEVBQUU7QUFDeEMsT0FBTywrQkFBK0IsRUFBRTtBQUN4QyxPQUFPLDZCQUE2QixFQUFFO0FBQ3RDLE9BQU8sOEJBQThCLEVBQUU7O0FBRXZDO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSCwyQkFBMkIsMENBQTBDO0FBQ3JFO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQyxZQUFZO0FBQ3REO0FBQ0EsbURBQW1ELFdBQVc7QUFDOUQ7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxrREFBa0QsdUJBQXVCO0FBQ3pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7O0FDcExBLFNBQVMsbUJBQU8sQ0FBQyxjQUFJO0FBQ3JCLGFBQWEsbUJBQU8sQ0FBQyxzREFBVTtBQUMvQixVQUFVLG1CQUFPLENBQUMsOENBQU07O0FBRXhCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCLHFDQUFxQyw0QkFBNEIsRUFBRTtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBOzs7Ozs7Ozs7OztBQ2xEQSxhQUFhLG1CQUFPLENBQUMsc0RBQVU7QUFDL0IsU0FBUyxtQkFBTyxDQUFDLGNBQUk7O0FBRXJCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7O0FBRUg7QUFDQTtBQUNBOzs7Ozs7Ozs7OztBQ25EQSxTQUFTLG1CQUFPLENBQUMsY0FBSTtBQUNyQixXQUFXLG1CQUFPLENBQUMsa0JBQU07QUFDekIsYUFBYSxtQkFBTyxDQUFDLHNEQUFVO0FBQy9CLFNBQVMsbUJBQU8sQ0FBQyxjQUFJOztBQUVyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7OztBQ3BEQSxXQUFXLG1CQUFPLENBQUMsa0JBQU07QUFDekIsU0FBUyxtQkFBTyxDQUFDLGNBQUk7QUFDckIsYUFBYSxtQkFBTyxDQUFDLHNEQUFVO0FBQy9CLFVBQVUsbUJBQU8sQ0FBQyw4Q0FBTTtBQUN4QixXQUFXLG1CQUFPLENBQUMsZ0RBQU87O0FBRTFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsZUFBZTtBQUNmO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhEQUE4RCxHQUFHO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsU0FBUztBQUNULE9BQU8sRUFBRTtBQUNUO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7QUM3SEEsYUFBYSxtQkFBTyxDQUFDLHNEQUFVO0FBQy9CLFNBQVMsbUJBQU8sQ0FBQyxjQUFJO0FBQ3JCLFdBQVcsbUJBQU8sQ0FBQyxrQkFBTTs7QUFFekI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRDtBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsQ0FBQztBQUNEOzs7Ozs7Ozs7OztBQ25FQSxTQUFTLG1CQUFPLENBQUMsY0FBSTtBQUNyQixXQUFXLG1CQUFPLENBQUMsa0JBQU07QUFDekIsYUFBYSxtQkFBTyxDQUFDLHNEQUFVOztBQUUvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSCxzQkFBc0I7QUFDdEIsR0FBRztBQUNIO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7O0FBRUE7QUFDQTtBQUNBLGFBQWE7QUFDYjs7QUFFQTtBQUNBLEdBQUcsRUFBRTtBQUNMLENBQUM7QUFDRDs7Ozs7Ozs7Ozs7QUMvRUEsV0FBVyxtQkFBTyxDQUFDLGtCQUFNO0FBQ3pCLGFBQWEsbUJBQU8sQ0FBQyxzREFBVTs7QUFFL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7QUNWQSxhQUFhLG1CQUFPLENBQUMsc0RBQVU7QUFDL0IsU0FBUyxtQkFBTyxDQUFDLGNBQUk7O0FBRXJCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsZ0JBQWdCLGtCQUFrQjtBQUNsQztBQUNBOztBQUVBLGdDQUFnQztBQUNoQztBQUNBOztBQUVBLHdDQUF3QztBQUN4QztBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOENBQThDO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxhQUFhO0FBQ2I7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHLEVBQUU7QUFDTCxDQUFDO0FBQ0Q7Ozs7Ozs7Ozs7O0FDaEpBLGFBQWEsbUJBQU8sQ0FBQyxzREFBVTtBQUMvQixTQUFTLG1CQUFPLENBQUMsY0FBSTs7QUFFckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBLDhCQUE4QjtBQUM5QjtBQUNBLHlDQUF5QztBQUN6QztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7Ozs7Ozs7OztBQzFDQSxhQUFhLG1CQUFPLENBQUMsc0RBQVU7QUFDL0IsU0FBUyxtQkFBTyxDQUFDLGNBQUk7QUFDckIsU0FBUyxtQkFBTyxDQUFDLGNBQUk7O0FBRXJCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QjtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5Qjs7QUFFekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DOztBQUVwQztBQUNBO0FBQ0E7Ozs7Ozs7Ozs7O0FDdkRBLGFBQWEsbUJBQU8sQ0FBQyxzREFBVTtBQUMvQixTQUFTLG1CQUFPLENBQUMsY0FBSTs7QUFFckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkI7QUFDM0Isb0NBQW9DO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7Ozs7Ozs7Ozs7O0FDcEZBLGFBQWEsbUJBQU8sQ0FBQyxzREFBVTtBQUMvQixTQUFTLG1CQUFPLENBQUMsY0FBSTtBQUNyQixXQUFXLG1CQUFPLENBQUMsa0JBQU07O0FBRXpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7OztBQzVCQSxhQUFhLG1CQUFPLENBQUMsc0RBQVU7QUFDL0IsU0FBUyxtQkFBTyxDQUFDLGNBQUk7QUFDckIsV0FBVyxtQkFBTyxDQUFDLGtCQUFNOztBQUV6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7QUM1QkEsYUFBYSxtQkFBTyxDQUFDLHNEQUFVO0FBQy9CLFNBQVMsbUJBQU8sQ0FBQyxjQUFJO0FBQ3JCLFdBQVcsbUJBQU8sQ0FBQyxrQkFBTTs7QUFFekI7QUFDQTtBQUNBLFdBQVcsSUFBSTs7QUFFZjtBQUNBOztBQUVBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7O0FBRWY7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDbEZBLHNHQUFzQztBQUV0QywwSUFBd0Q7QUFDeEQsMElBQXdEO0FBTXhELElBQU0sVUFBVSxHQUFoQixNQUFNLFVBQVU7SUFDWixJQUFXLFNBQVM7UUFDaEIsT0FBTyxpQkFBaUI7SUFDNUIsQ0FBQztJQUVNLGtCQUFrQixDQUFDLEdBQVc7UUFDakMsT0FBTztZQUNILEtBQUssRUFBRSxPQUFPLENBQUMseUJBQXlCLENBQUMsR0FBRyxDQUFDO1lBQzdDLElBQUksRUFBRSxPQUFPLENBQUMsd0JBQXdCLEVBQUU7WUFDeEMsY0FBYyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLDBCQUEwQixDQUFDO1NBQ3BFO0lBQ0wsQ0FBQztJQUVNLElBQUksQ0FBQyxRQUFnQixFQUFFLFdBQW1CLEVBQUUsSUFBYTtRQUM1RCxPQUFPLE9BQU8sQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUM7SUFDN0QsQ0FBQztJQUVNLFFBQVEsQ0FDWCxTQUFpQixFQUNqQixJQUFZLEVBQ1osT0FBZSxFQUNmLElBQWE7UUFFYixPQUFPLE9BQU8sQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDO0lBQzNELENBQUM7SUFFTSxhQUFhO1FBQ2hCLE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLHFCQUFxQixDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUVNLEtBQUssQ0FBQyxPQUFlO1FBQ3hCLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDO0lBQzFCLENBQUM7SUFFTSxTQUFTLENBQUMsT0FBZSxFQUFFLElBQWM7UUFDNUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDO0lBQy9ELENBQUM7SUFFTSxZQUFZLENBQUMsT0FBZSxFQUFFLElBQWM7UUFDL0MsT0FBTyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDO0lBQ2xFLENBQUM7SUFFTSxjQUFjLENBQUMsSUFBWSxFQUFFLEdBQVc7UUFDM0MsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDO0lBQ2xDLENBQUM7SUFFTSxXQUFXLENBQUMsSUFBWTtRQUMzQixPQUFPLE9BQU8sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDO0lBQ3BDLENBQUM7SUFFTSxPQUFPLENBQUMsU0FBaUI7UUFDNUIsT0FBTyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUM7SUFDbEMsQ0FBQztJQUVNLEtBQUssQ0FBQyxJQUFZLEVBQUUsS0FBZTtRQUN0QyxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVNLElBQUksQ0FBQyxJQUFZLEVBQUUsSUFBYztRQUNwQyxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztRQUM3QixFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQztRQUVaLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxRQUFRLEVBQUU7UUFDNUIsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDO1lBQ25CLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTtZQUNqQixLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUs7WUFDbkIsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNO1lBQ3JCLE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTTtTQUN4QixDQUFDO0lBQ04sQ0FBQztJQUVNLFlBQVk7UUFDZixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsd0JBQXdCLENBQUM7SUFDckQsQ0FBQztJQUVNLFNBQVMsQ0FBQyxJQUFZLEVBQUUsS0FBYTtRQUN4QyxPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUM7SUFDcEMsQ0FBQztJQUVNLFFBQVEsQ0FBQyxLQUFhLEVBQUUsUUFBa0I7O1FBQzdDLGFBQU8sT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLDBDQUFFLElBQUksR0FBRTtJQUNwRCxDQUFDO0lBRU0sWUFBWSxDQUFDLEtBQWEsRUFBRSxRQUFrQjtRQUNqRCxPQUFPLE9BQU87YUFDVCxRQUFRLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQzthQUN6QixLQUFLLENBQUMsSUFBSSxDQUFDO2FBQ1gsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBRU0sZUFBZSxDQUFDLEtBQWEsRUFBRSxRQUFrQjtRQUNwRCxPQUFPLE9BQU8sQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQztJQUNoRCxDQUFDO0lBRU0sZ0JBQWdCLENBQUMsS0FBYSxFQUFFLElBQVk7UUFDL0MsT0FBTyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7SUFDbkUsQ0FBQztJQUVNLFVBQVUsQ0FBQyxJQUFZO1FBQzFCLE9BQU8sT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRTtJQUM5RCxDQUFDO0lBRU0sZUFBZSxDQUFDLElBQVk7UUFDL0IsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsV0FBVyxFQUFFO0lBQ25FLENBQUM7Q0FDSjtBQXpHSyxVQUFVO0lBRGYsc0JBQVUsRUFBRTtHQUNQLFVBQVUsQ0F5R2Y7QUFFUSxnQ0FBVTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNwSG5CLDZEQUF3QjtBQUN4Qiw2REFBd0I7QUFDeEIsbUVBQTRCO0FBQzVCLHFJQUFvRDtBQUVwRCxzR0FBOEM7QUFDOUMsNkVBQTBEO0FBYzFELElBQWEsVUFBVSxrQkFBdkIsTUFBYSxVQUFVO0lBUW5CLFlBQytCLFVBQXVCLEVBQ25CLGNBQStCO1FBRTlELElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVTtRQUM1QixJQUFJLENBQUMsY0FBYyxHQUFHLGNBQWM7UUFDcEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQ2pDLFFBQVEsRUFDUixTQUFTLEVBQ1QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxZQUFVLENBQUMsU0FBUyxDQUFDLENBQzNEO0lBQ0wsQ0FBQztJQUVNLGdCQUFnQjtRQUNuQixJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyw2QkFBNkIsRUFBRSxNQUFNLENBQUM7UUFDckUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsZUFBZSxFQUFFLE1BQU0sQ0FBQztJQUMzRCxDQUFDO0lBRU0sT0FBTyxDQUFDLEdBQVcsRUFBRSxJQUFjO1FBQ3RDLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ2hELE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQztJQUMxQyxDQUFDO0lBRVksV0FBVyxDQUNwQixRQUFnQixFQUNoQixXQUFtQixFQUNuQixXQUFvQixFQUNwQixVQUFtQjs7WUFFbkIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDZixPQUFPLENBQUMsR0FBRyxDQUFDLDRCQUE0QixDQUFDO1lBQ3pDLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxRQUFRLFdBQVcsR0FBRyxXQUFXLENBQUM7WUFDNUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsQ0FBQztZQUV6QyxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLEVBQUU7Z0JBQ3BELFdBQVcsR0FBRyxLQUFLLEVBQUMsd0RBQXdEO2FBQy9FO1lBRUQsSUFBSSxRQUFnQjtZQUNwQixJQUFJLENBQUMsV0FBVyxFQUFFO2dCQUNkLEVBQUU7Z0JBQ0YsdURBQXVEO2dCQUN2RCxFQUFFO2dCQUNGLFFBQVEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDO2FBQ3pEO1lBRUQsSUFBSSxDQUFDLFFBQVEsRUFBRTtnQkFDWCxJQUFJLE9BQWU7Z0JBQ25CLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsRUFBRTtvQkFDcEQsRUFBRTtvQkFDRix5RUFBeUU7b0JBQ3pFLEVBQUU7b0JBQ0YsT0FBTyxHQUFHLFdBQVc7aUJBQ3hCO3FCQUFNO29CQUNILEVBQUU7b0JBQ0Ysa0VBQWtFO29CQUNsRSxpRkFBaUY7b0JBQ2pGLG1EQUFtRDtvQkFDbkQsaURBQWlEO29CQUNqRCxFQUFFO29CQUNGLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FDakMsUUFBUSxFQUNSLFdBQVcsRUFDWCxVQUFVLENBQ2I7b0JBQ0QsSUFBSSxDQUFDLE9BQU8sRUFBRTt3QkFDVixNQUFNLElBQUksS0FBSyxDQUNYLGtCQUFrQixRQUFRLGFBQWEsV0FBVyxJQUFJLENBQ3pEO3FCQUNKO29CQUVELEVBQUU7b0JBQ0YsNENBQTRDO29CQUM1QyxFQUFFO29CQUNGLFFBQVEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDO2lCQUNyRDtnQkFDRCxJQUFJLENBQUMsUUFBUSxFQUFFO29CQUNYLEVBQUU7b0JBQ0YsMkJBQTJCO29CQUMzQixFQUFFO29CQUNGLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQztpQkFDdkQ7YUFDSjtZQUVELEVBQUU7WUFDRiw2RUFBNkU7WUFDN0UsNkRBQTZEO1lBQzdELEVBQUU7WUFDRixJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxhQUFhLFFBQVEsRUFBRSxDQUFDO1lBRTlDLElBQ0ksRUFBRSxDQUFDLFFBQVEsRUFBRSxLQUFLLE9BQU87Z0JBQ3pCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLEVBQzdDO2dCQUNFLElBQUksVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDO2dCQUN0RCxVQUFVLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsSUFBSSxVQUFVO2dCQUN0RCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQztnQkFDM0MsSUFBSSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsYUFBYSxFQUFFLFVBQVUsQ0FBQzthQUM1RDtZQUNELElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQztZQUVqQyxPQUFPLFFBQVE7UUFDbkIsQ0FBQztLQUFBO0lBRWEsZ0JBQWdCLENBQzFCLFFBQWdCLEVBQ2hCLFdBQW1CLEVBQ25CLGlCQUEwQjs7WUFFMUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQ2pCLDhCQUE4QixRQUFRLEdBQ2xDLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFDdEMsSUFBSSxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUMxRDtZQUVELE1BQU0sWUFBWSxHQUFHLEdBQ2pCLFlBQVUsQ0FBQyxTQUNmLFdBQVcsa0JBQWtCLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDLGVBQ2pELGlCQUFpQixDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQ2pDLG9CQUFvQjtZQUVwQixNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQztZQUVuRCxJQUFJLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsVUFBVSxLQUFLLEdBQUcsRUFBRTtnQkFDeEMsT0FBTyxJQUFJO2FBQ2Q7WUFFRCxNQUFNLElBQUksR0FBVyxNQUFNLEdBQUcsQ0FBQyxRQUFRLEVBQUU7WUFDekMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJO1lBRWxDLE1BQU0sUUFBUSxHQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFrQyxDQUFDLEdBQUcsQ0FDNUQsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUNqQjtZQUNELElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFO2dCQUMvQixPQUFPLElBQUk7YUFDZDtZQUVELElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLGlCQUFpQixRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFFN0QsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxXQUFXLENBQUM7UUFDdEUsQ0FBQztLQUFBO0lBRWEsV0FBVyxDQUNyQixRQUFnQixFQUNoQixPQUFlOztZQUVmLE1BQU0sYUFBYSxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQUU7WUFDM0QsSUFBSSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxhQUFhLEVBQUUsYUFBYSxDQUFDO1lBRXRFLElBQUksT0FBTyxFQUFFO2dCQUNULE9BQU8sR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUM7Z0JBQ25ELElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDO2FBQzdDO1lBRUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUM7WUFDakQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUztZQUN4RCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU07WUFFakUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsd0JBQXdCLE1BQU0sSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUVsRSxJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQUU7Z0JBQ2IsTUFBTSxJQUFJLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQzthQUMzQztZQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQztRQUMzRSxDQUFDO0tBQUE7Q0FDSjtBQXpLMkIsb0JBQVMsR0FDN0IscUNBQXFDO0FBTmhDLFVBQVU7SUFEdEIsc0JBQVUsRUFBRTtJQVVKLDZCQUFNLENBQUMsY0FBSyxDQUFDLFdBQVcsQ0FBQztJQUN6Qiw2QkFBTSxDQUFDLGNBQUssQ0FBQyxlQUFlLENBQUM7O0dBVnpCLFVBQVUsQ0E4S3RCO0FBOUtZLGdDQUFVOzs7Ozs7Ozs7Ozs7OztBQ3BCdkIsc0dBQXFDO0FBQ3JDLHFHQUFrRTtBQUNsRSw2RUFBNkM7QUFDN0MsK0dBQXNEO0FBRXRELE1BQU0sU0FBUyxHQUFHLElBQUkscUJBQVMsRUFBRTtBQUVqQyxTQUFTLENBQUMsSUFBSSxDQUFrQixjQUFLLENBQUMsZUFBZSxDQUFDLENBQUMsRUFBRSxDQUFDLCtCQUFjLENBQUM7QUFDekUsU0FBUyxDQUFDLElBQUksQ0FBYyxjQUFLLENBQUMsV0FBVyxDQUFDLENBQUMsRUFBRSxDQUFDLHdCQUFVLENBQUM7QUFFN0Qsa0JBQWUsU0FBUzs7Ozs7Ozs7Ozs7Ozs7O0FDUlgsYUFBSyxHQUFHO0lBQ2pCLFdBQVcsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQztJQUNyQyxXQUFXLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUM7SUFDckMsZUFBZSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUM7SUFDN0Msc0JBQXNCLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyx1QkFBdUIsQ0FBQztJQUMzRCxlQUFlLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQztDQUNoRDtBQUVELElBQVksV0FHWDtBQUhELFdBQVksV0FBVztJQUNuQixzREFBdUM7SUFDdkMsMENBQTJCO0FBQy9CLENBQUMsRUFIVyxXQUFXLEdBQVgsbUJBQVcsS0FBWCxtQkFBVyxRQUd0Qjs7Ozs7Ozs7Ozs7Ozs7O0FDYkQsNkVBQW1FO0FBRW5FLE1BQWEsUUFBUTtJQUNWLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxVQUF1QjtRQUNsRCxNQUFNLFdBQVcsR0FBRyxVQUFVLENBQUMsUUFBUSxDQUFDLG9CQUFXLENBQUMsV0FBVyxDQUFDO1FBQ2hFLE1BQU0saUJBQWlCLEdBQUcsVUFBVSxDQUFDLGVBQWUsQ0FDaEQsb0JBQVcsQ0FBQyxpQkFBaUIsQ0FDaEM7UUFFRCxPQUFPO1lBQ0gsV0FBVztZQUNYLGlCQUFpQjtTQUNwQjtJQUNMLENBQUM7Q0FDSjtBQVpELDRCQVlDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDZEQsOEhBQWdDO0FBQ2hDLGtHQUFnQztBQUNoQyxzR0FBOEM7QUFFOUMsNkVBQTZDO0FBUzdDLElBQWEsY0FBYyxHQUEzQixNQUFhLGNBQWM7SUFFdkIsWUFBdUMsVUFBdUI7UUFDMUQsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVO0lBQ2hDLENBQUM7SUFFTSxpQkFBaUIsQ0FBQyxXQUFtQjtRQUN4QyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQztRQUNuQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxjQUFjLEdBQUcsQ0FBQyxDQUFDO1FBRXpDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSTtRQUNyQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1FBRTNDLE9BQU8sS0FBSztJQUNoQixDQUFDO0lBRU0sZ0JBQWdCLENBQUMsUUFBa0IsRUFBRSxXQUFtQjtRQUMzRCxJQUFJLE9BQWU7UUFDbkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsYUFBYSxHQUFHLFFBQVEsQ0FBQyxNQUFNLEdBQUcsV0FBVyxDQUFDO1FBQ3BFLFFBQVEsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLHdCQUFHLENBQUM7UUFDN0IsS0FBSyxJQUFJLENBQUMsR0FBRyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQzNDLE1BQU0sU0FBUyxHQUFXLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDckMsTUFBTSxTQUFTLEdBQVksTUFBTSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsV0FBVyxDQUFDO1lBQ25FLElBQUksU0FBUyxFQUFFO2dCQUNYLE9BQU8sR0FBRyxTQUFTO2dCQUNuQixNQUFLO2FBQ1I7U0FDSjtRQUVELElBQUksT0FBTyxFQUFFO1lBQ1QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQztTQUMvQzthQUFNO1lBQ0gsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUM7U0FDM0M7UUFFRCxPQUFPLE9BQU87SUFDbEIsQ0FBQztJQUVNLFlBQVksQ0FBQyxPQUFlO1FBQy9CLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLFlBQVksR0FBRyxPQUFPLENBQUM7UUFDN0MsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQztJQUNoQyxDQUFDO0NBQ0o7QUExQ1ksY0FBYztJQUQxQixzQkFBVSxFQUFFO0lBR0ksNkJBQU0sQ0FBQyxjQUFLLENBQUMsV0FBVyxDQUFDOztHQUY3QixjQUFjLENBMEMxQjtBQTFDWSx3Q0FBYzs7Ozs7Ozs7Ozs7Ozs7QUNiM0IsMEZBQXlCO0FBQ3pCLDBGQUErQjtBQUUvQixhQUFNLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ0hSLHNGQUFzRDtBQUN0RCxzSEFHMkM7QUFDM0MsNEZBQWdFO0FBQ2hFLGtJQUFpRTtBQUVqRSw4RkFBc0M7QUFFdEMsYUFBUztLQUNKLElBQUksQ0FBeUIsY0FBSyxDQUFDLHNCQUFzQixDQUFDO0tBQzFELEVBQUUsQ0FBQyw0QkFBcUIsQ0FBQztBQUU5QixNQUFNLHFCQUFxQixHQUFHLGFBQVMsQ0FBQyxHQUFHLENBQ3ZDLGNBQUssQ0FBQyxzQkFBc0IsQ0FDL0I7QUFDRCxNQUFNLFVBQVUsR0FBRyxhQUFTLENBQUMsR0FBRyxDQUFjLGNBQUssQ0FBQyxXQUFXLENBQUM7QUFFaEUsU0FBc0IsS0FBSzs7UUFDdkIsSUFBSTtZQUNBLHFCQUFxQixDQUFDLGdCQUFnQixFQUFFO1lBRXhDLE1BQU0sUUFBUSxHQUFHLG1CQUFjLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDO1lBRTVELE1BQU0scUJBQXFCLENBQUMsT0FBTyxDQUMvQixRQUFRLENBQUMsV0FBVyxFQUNwQixRQUFRLENBQUMsaUJBQWlCLENBQzdCO1lBRUQsVUFBVSxDQUFDLFlBQVksQ0FDbkIsMENBQTBDLEVBQzFDLElBQUksQ0FDUDtTQUNKO1FBQUMsT0FBTyxLQUFLLEVBQUU7WUFDWixVQUFVLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDO1NBQzVDO0lBQ0wsQ0FBQztDQUFBO0FBbEJELHNCQWtCQztBQUVELFNBQXNCLE1BQU07O1FBQ3hCLElBQUk7WUFDQSxxQkFBcUIsQ0FBQyxnQkFBZ0IsRUFBRTtZQUV4QyxNQUFNLFFBQVEsR0FBRyxtQkFBUSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQztZQUV2RCxNQUFNLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7WUFFNUMsVUFBVSxDQUFDLFlBQVksQ0FDbkIsZ0RBQWdELEVBQ2hELElBQUksQ0FDUDtTQUNKO1FBQUMsT0FBTyxLQUFLLEVBQUU7WUFDWixVQUFVLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDO1NBQzVDO0lBQ0wsQ0FBQztDQUFBO0FBZkQsd0JBZUM7QUFFRCxTQUFzQixPQUFPOztRQUN6QixJQUFJO1lBQ0EscUJBQXFCLENBQUMsZ0JBQWdCLEVBQUU7WUFFeEMsTUFBTSxRQUFRLEdBQUcsbUJBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUM7WUFFeEQsTUFBTSxxQkFBcUIsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO1lBRTdDLFVBQVUsQ0FBQyxZQUFZLENBQ25CLGtEQUFrRCxFQUNsRCxJQUFJLENBQ1A7U0FDSjtRQUFDLE9BQU8sS0FBSyxFQUFFO1lBQ1osVUFBVSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQztTQUM1QztJQUNMLENBQUM7Q0FBQTtBQWZELDBCQWVDO0FBRUQsU0FBc0IsS0FBSzs7UUFDdkIsSUFBSTtZQUNBLHFCQUFxQixDQUFDLGdCQUFnQixFQUFFO1lBRXhDLE1BQU0sUUFBUSxHQUFHLG1CQUFRLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDO1lBRXRELE1BQU0scUJBQXFCLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQztZQUUzQyxVQUFVLENBQUMsWUFBWSxDQUNuQiwrQ0FBK0MsRUFDL0MsSUFBSSxDQUNQO1NBQ0o7UUFBQyxPQUFPLEtBQUssRUFBRTtZQUNaLFVBQVUsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUM7U0FDNUM7SUFDTCxDQUFDO0NBQUE7QUFmRCxzQkFlQztBQUVELFNBQXNCLElBQUk7O1FBQ3RCLElBQUk7WUFDQSxxQkFBcUIsQ0FBQyxnQkFBZ0IsRUFBRTtZQUV4QyxNQUFNLFFBQVEsR0FBRyxtQkFBUSxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUM7WUFFckQsTUFBTSxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO1lBRTFDLFVBQVUsQ0FBQyxZQUFZLENBQ25CLCtDQUErQyxFQUMvQyxJQUFJLENBQ1A7U0FDSjtRQUFDLE9BQU8sS0FBSyxFQUFFO1lBQ1osVUFBVSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQztTQUM1QztJQUNMLENBQUM7Q0FBQTtBQWZELG9CQWVDO0FBRUQsU0FBc0IsT0FBTzs7UUFDekIsSUFBSTtZQUNBLHFCQUFxQixDQUFDLGdCQUFnQixFQUFFO1lBRXhDLE1BQU0sUUFBUSxHQUFHLG1CQUFRLENBQUMsa0JBQWtCLENBQUMsVUFBVSxDQUFDO1lBRXhELE1BQU0scUJBQXFCLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQztZQUU3QyxVQUFVLENBQUMsWUFBWSxDQUNuQixrREFBa0QsRUFDbEQsSUFBSSxDQUNQO1NBQ0o7UUFBQyxPQUFPLEtBQUssRUFBRTtZQUNaLFVBQVUsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUM7U0FDNUM7SUFDTCxDQUFDO0NBQUE7QUFmRCwwQkFlQztBQUVELFNBQXNCLFFBQVE7O1FBQzFCLElBQUk7WUFDQSxxQkFBcUIsQ0FBQyxnQkFBZ0IsRUFBRTtZQUV4QyxNQUFNLFFBQVEsR0FBRyxtQkFBUSxDQUFDLG1CQUFtQixDQUFDLFVBQVUsQ0FBQztZQUV6RCxNQUFNLHFCQUFxQixDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7WUFFOUMsVUFBVSxDQUFDLFlBQVksQ0FDbkIsd0RBQXdELEVBQ3hELElBQUksQ0FDUDtTQUNKO1FBQUMsT0FBTyxLQUFLLEVBQUU7WUFDWixVQUFVLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDO1NBQzVDO0lBQ0wsQ0FBQztDQUFBO0FBZkQsNEJBZUM7Ozs7Ozs7Ozs7Ozs7OztBQzNJRCxJQUFZLFlBS1g7QUFMRCxXQUFZLFlBQVk7SUFDcEIseUNBQXlCO0lBQ3pCLCtCQUFlO0lBQ2YsK0JBQWU7SUFDZixtREFBbUM7QUFDdkMsQ0FBQyxFQUxXLFlBQVksR0FBWixvQkFBWSxLQUFaLG9CQUFZLFFBS3ZCO0FBRUQsSUFBWSxZQU9YO0FBUEQsV0FBWSxZQUFZO0lBQ3BCLHVDQUF1QjtJQUN2Qiw2QkFBYTtJQUNiLCtDQUErQjtJQUMvQiw2Q0FBNkI7SUFDN0IsaUNBQWlCO0lBQ2pCLGlDQUFpQjtBQUNyQixDQUFDLEVBUFcsWUFBWSxHQUFaLG9CQUFZLEtBQVosb0JBQVksUUFPdkI7QUFFRCxJQUFZLGFBRVg7QUFGRCxXQUFZLGFBQWE7SUFDckIsd0NBQXVCO0FBQzNCLENBQUMsRUFGVyxhQUFhLEdBQWIscUJBQWEsS0FBYixxQkFBYSxRQUV4QjtBQUVELElBQVksV0FFWDtBQUZELFdBQVksV0FBVztJQUNuQixzQ0FBdUI7QUFDM0IsQ0FBQyxFQUZXLFdBQVcsR0FBWCxtQkFBVyxLQUFYLG1CQUFXLFFBRXRCO0FBRUQsSUFBWSxVQUVYO0FBRkQsV0FBWSxVQUFVO0lBQ2xCLHFDQUF1QjtBQUMzQixDQUFDLEVBRlcsVUFBVSxHQUFWLGtCQUFVLEtBQVYsa0JBQVUsUUFFckI7QUFFRCxJQUFZLGFBRVg7QUFGRCxXQUFZLGFBQWE7SUFDckIsb0NBQW1CO0FBQ3ZCLENBQUMsRUFGVyxhQUFhLEdBQWIscUJBQWEsS0FBYixxQkFBYSxRQUV4QjtBQUVELElBQVksY0FHWDtBQUhELFdBQVksY0FBYztJQUN0QixxQ0FBbUI7SUFDbkIsbUNBQWlCO0FBQ3JCLENBQUMsRUFIVyxjQUFjLEdBQWQsc0JBQWMsS0FBZCxzQkFBYyxRQUd6Qjs7Ozs7Ozs7Ozs7Ozs7O0FDbENELGdHQWVpQjtBQUVqQixNQUFhLFFBQVE7SUFDVixNQUFNLENBQUMsaUJBQWlCLENBQzNCLFVBQXVCO1FBRXZCLE1BQU0sU0FBUyxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUMscUJBQVksQ0FBQyxTQUFTLENBQUM7UUFDN0QsTUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyxxQkFBWSxDQUFDLElBQUksQ0FBQztRQUNuRCxNQUFNLGFBQWEsR0FBRyxVQUFVLENBQUMsUUFBUSxDQUFDLHFCQUFZLENBQUMsYUFBYSxDQUFDO1FBQ3JFLE1BQU0sWUFBWSxHQUFHLFVBQVUsQ0FBQyxlQUFlLENBQzNDLHFCQUFZLENBQUMsWUFBWSxDQUM1QjtRQUNELE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUMscUJBQVksQ0FBQyxNQUFNLENBQUM7UUFDdkQsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLFlBQVksQ0FBQyxxQkFBWSxDQUFDLE1BQU0sQ0FBQztRQUUzRCxNQUFNLGNBQWMsR0FBRyxRQUFRLENBQUMsaUJBQWlCLENBQUMsVUFBVSxDQUFDO1FBQzdELHVDQUNPLGNBQWMsS0FDakIsU0FBUztZQUNULElBQUk7WUFDSixhQUFhO1lBQ2IsWUFBWTtZQUNaLE1BQU07WUFDTixNQUFNLElBQ1Q7SUFDTCxDQUFDO0lBRU0sTUFBTSxDQUFDLGtCQUFrQixDQUM1QixVQUF1QjtRQUV2QixNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsUUFBUSxDQUFDLHNCQUFhLENBQUMsU0FBUyxDQUFDO1FBRTlELE1BQU0sY0FBYyxHQUFHLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLENBQUM7UUFDN0QsdUNBQ08sY0FBYyxLQUNqQixTQUFTLElBQ1o7SUFDTCxDQUFDO0lBRU0sTUFBTSxDQUFDLGdCQUFnQixDQUMxQixVQUF1QjtRQUV2QixNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsUUFBUSxDQUFDLG9CQUFXLENBQUMsU0FBUyxDQUFDO1FBRTVELE1BQU0sY0FBYyxHQUFHLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLENBQUM7UUFDN0QsdUNBQ08sY0FBYyxLQUNqQixTQUFTLElBQ1o7SUFDTCxDQUFDO0lBRU0sTUFBTSxDQUFDLGVBQWUsQ0FDekIsVUFBdUI7UUFFdkIsTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyxtQkFBVSxDQUFDLFNBQVMsQ0FBQztRQUUzRCxNQUFNLGNBQWMsR0FBRyxRQUFRLENBQUMsaUJBQWlCLENBQUMsVUFBVSxDQUFDO1FBQzdELHVDQUNPLGNBQWMsS0FDakIsU0FBUyxJQUNaO0lBQ0wsQ0FBQztJQUVNLE1BQU0sQ0FBQyxrQkFBa0IsQ0FDNUIsVUFBdUI7UUFFdkIsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyxzQkFBYSxDQUFDLE9BQU8sQ0FBQztRQUUxRCxNQUFNLGNBQWMsR0FBRyxRQUFRLENBQUMsaUJBQWlCLENBQUMsVUFBVSxDQUFDO1FBQzdELHVDQUNPLGNBQWMsS0FDakIsT0FBTyxJQUNWO0lBQ0wsQ0FBQztJQUVNLE1BQU0sQ0FBQyxtQkFBbUIsQ0FDN0IsVUFBdUI7UUFFdkIsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyx1QkFBYyxDQUFDLE9BQU8sQ0FBQztRQUMzRCxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsWUFBWSxDQUFDLHVCQUFjLENBQUMsTUFBTSxDQUFDO1FBRTdELE1BQU0sY0FBYyxHQUFHLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLENBQUM7UUFDN0QsdUNBQ08sY0FBYyxLQUNqQixPQUFPO1lBQ1AsTUFBTSxJQUNUO0lBQ0wsQ0FBQztJQUVPLE1BQU0sQ0FBQyxpQkFBaUIsQ0FDNUIsVUFBdUI7UUFFdkIsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyxxQkFBWSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUM7UUFDM0QsTUFBTSxVQUFVLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyxxQkFBWSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUM7UUFDckUsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyxxQkFBWSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUM7UUFDM0QsTUFBTSxlQUFlLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FDdkMscUJBQVksQ0FBQyxlQUFlLENBQy9CO1FBRUQsT0FBTztZQUNILEtBQUs7WUFDTCxVQUFVO1lBQ1YsS0FBSztZQUNMLGVBQWU7U0FDbEI7SUFDTCxDQUFDO0NBQ0o7QUF4R0QsNEJBd0dDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUMxSEQscURBQTZCO0FBRTdCLHNGQUFtRTtBQUNuRSxzR0FBOEM7QUFDOUMscUdBQWdFO0FBd0JoRSxJQUFhLHFCQUFxQixHQUFsQyxNQUFhLHFCQUNULFNBQVEsd0JBQVU7SUFFbEIsWUFDK0IsVUFBdUIsRUFDbkIsY0FBK0I7UUFFOUQsS0FBSyxDQUFDLFVBQVUsRUFBRSxjQUFjLENBQUM7SUFDckMsQ0FBQztJQUVZLE9BQU8sQ0FDaEIsV0FBbUIsRUFDbkIsaUJBQTBCOztZQUUxQixNQUFNLElBQUksQ0FBQyxXQUFXLENBQ2xCLHdCQUF3QixFQUN4QixXQUFXLEVBQ1gsS0FBSyxFQUNMLGlCQUFpQixDQUNwQjtRQUNMLENBQUM7S0FBQTtJQUVNLE1BQU0sQ0FDVCxRQUF5QztRQUV6QyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDO1FBRTlDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQywwQkFBMEIsRUFBRSxJQUFJLENBQUM7SUFDekQsQ0FBQztJQUVNLE9BQU8sQ0FDVixRQUEwQztRQUUxQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDO1FBRS9DLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQywwQkFBMEIsRUFBRSxJQUFJLENBQUM7SUFDekQsQ0FBQztJQUVNLEtBQUssQ0FDUixRQUF3QztRQUV4QyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDO1FBRTdDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQywwQkFBMEIsRUFBRSxJQUFJLENBQUM7SUFDekQsQ0FBQztJQUVNLElBQUksQ0FBQyxRQUF1QztRQUMvQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDO1FBRTVDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQywwQkFBMEIsRUFBRSxJQUFJLENBQUM7SUFDekQsQ0FBQztJQUVNLE9BQU8sQ0FDVixRQUEwQztRQUUxQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDO1FBRS9DLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQywwQkFBMEIsRUFBRSxJQUFJLENBQUM7SUFDekQsQ0FBQztJQUVNLFFBQVEsQ0FDWCxRQUEyQztRQUUzQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDO1FBRWhELE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQywwQkFBMEIsRUFBRSxJQUFJLENBQUM7SUFDekQsQ0FBQztJQUVPLGtCQUFrQixDQUFDLFFBQW1DO1FBQzFELE1BQU0sSUFBSSxHQUFhLEVBQUU7UUFFekIsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQztRQUNwQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxRQUFRLENBQUMsVUFBVSxDQUFDO1FBQzlDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFFcEMsUUFBUSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUM7UUFFcEUsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxRQUFRLENBQUMsZUFBZSxDQUFDO1FBRXhELE9BQU8sSUFBSTtJQUNmLENBQUM7SUFFTyxrQkFBa0IsQ0FDdEIsUUFBeUM7UUFFekMsTUFBTSxJQUFJLEdBQWEsQ0FBQyxRQUFRLEVBQUUsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFdkUsSUFBSSxRQUFRLENBQUMsU0FBUyxFQUFFO1lBQ3BCLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxTQUFTLENBQUM7U0FDL0M7UUFDRCxJQUFJLFFBQVEsQ0FBQyxJQUFJLEVBQUU7WUFDZixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDO1NBQ3JDO1FBQ0QsSUFBSSxRQUFRLENBQUMsTUFBTSxFQUFFO1lBQ2pCLElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsUUFBUSxDQUFDLE1BQU0sQ0FBQztTQUNsRDtRQUVELElBQUksUUFBUSxDQUFDLGFBQWEsRUFBRTtZQUN4QixJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsRUFBRTtnQkFDcEQsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxRQUFRLENBQUMsYUFBYSxDQUFDO2FBQ3ZEO2lCQUFNO2dCQUNILE1BQU0sSUFBSSxLQUFLLENBQ1gsK0NBQStDO29CQUMzQyxRQUFRLENBQUMsYUFBYSxDQUM3QjthQUNKO1NBQ0o7UUFDRCxJQUFJLFFBQVEsQ0FBQyxZQUFZLEVBQUU7WUFDdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7U0FDckI7UUFDRCxJQUFJLFFBQVEsQ0FBQyxNQUFNLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQy9DLFFBQVEsQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUU7Z0JBQzFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxFQUFFLEtBQUssQ0FBQztZQUNyRCxDQUFDLENBQUM7WUFFRixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUNuRDtRQUVELE9BQU8sSUFBSTtJQUNmLENBQUM7SUFFTyxtQkFBbUIsQ0FDdkIsUUFBMEM7UUFFMUMsTUFBTSxJQUFJLEdBQWEsQ0FBQyxTQUFTLEVBQUUsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFeEUsSUFBSSxRQUFRLENBQUMsU0FBUyxFQUFFO1lBQ3BCLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxTQUFTLENBQUM7U0FDL0M7UUFFRCxPQUFPLElBQUk7SUFDZixDQUFDO0lBRU8saUJBQWlCLENBQ3JCLFFBQXdDO1FBRXhDLE1BQU0sSUFBSSxHQUFhLENBQUMsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRXRFLElBQUksUUFBUSxDQUFDLFNBQVMsRUFBRTtZQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxRQUFRLENBQUMsU0FBUyxDQUFDO1NBQy9DO1FBRUQsT0FBTyxJQUFJO0lBQ2YsQ0FBQztJQUVPLGdCQUFnQixDQUNwQixRQUF1QztRQUV2QyxNQUFNLElBQUksR0FBYSxDQUFDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUVyRSxJQUFJLFFBQVEsQ0FBQyxTQUFTLEVBQUU7WUFDcEIsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsUUFBUSxDQUFDLFNBQVMsQ0FBQztTQUMvQztRQUVELE9BQU8sSUFBSTtJQUNmLENBQUM7SUFFTyxtQkFBbUIsQ0FDdkIsUUFBMEM7UUFFMUMsTUFBTSxJQUFJLEdBQWEsQ0FBQyxTQUFTLEVBQUUsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFeEUsSUFBSSxRQUFRLENBQUMsT0FBTyxFQUFFO1lBQ2xCLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUM7U0FDM0M7UUFFRCxPQUFPLElBQUk7SUFDZixDQUFDO0lBRU8sb0JBQW9CLENBQ3hCLFFBQTJDO1FBRTNDLE1BQU0sSUFBSSxHQUFhO1lBQ25CLFVBQVU7WUFDVixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUM7U0FDdkM7UUFFRCxJQUFJLFFBQVEsQ0FBQyxPQUFPLEVBQUU7WUFDbEIsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQztTQUMzQztRQUNELElBQUksUUFBUSxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDL0MsUUFBUSxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDMUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLEVBQUUsS0FBSyxDQUFDO1lBQ3JELENBQUMsQ0FBQztZQUVGLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ25EO1FBRUQsT0FBTyxJQUFJO0lBQ2YsQ0FBQztJQUVPLFVBQVUsQ0FBQyxVQUFrQjtRQUNqQyxJQUFJLE9BQWU7UUFDbkIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEVBQUU7UUFDN0MsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNiLE9BQU8sR0FBRyxNQUFNO1NBQ25CO2FBQU07WUFDSCxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxFQUFFO2dCQUM3QyxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDO2FBQzFDO2lCQUFNO2dCQUNILE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLEdBQUcsVUFBVSxDQUFDO2FBQzFEO1NBQ0o7UUFDRCxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQztJQUN0QyxDQUFDO0NBQ0o7QUE3TVkscUJBQXFCO0lBRGpDLHNCQUFVLEVBQUU7SUFLSiw2QkFBTSxDQUFDLGNBQUssQ0FBQyxXQUFXLENBQUM7SUFDekIsNkJBQU0sQ0FBQyxjQUFLLENBQUMsZUFBZSxDQUFDOztHQUx6QixxQkFBcUIsQ0E2TWpDO0FBN01ZLHNEQUFxQjs7Ozs7Ozs7Ozs7O0FDNUJyQjtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLE1BQU0sNkJBQTZCLEVBQUUsWUFBWSxXQUFXLEVBQUU7QUFDakcsa0NBQWtDLE1BQU0saUNBQWlDLEVBQUUsWUFBWSxXQUFXLEVBQUU7QUFDcEcsK0JBQStCLGlFQUFpRSx1QkFBdUIsRUFBRSw0QkFBNEI7QUFDcko7QUFDQSxLQUFLO0FBQ0w7QUFDQSw4Q0FBNkMsQ0FBQyxjQUFjLEVBQUM7QUFDN0QsWUFBWSxtQkFBTyxDQUFDLGdCQUFLO0FBQ3pCLGFBQWEsbUJBQU8sQ0FBQyxrQkFBTTtBQUMzQixjQUFjLG1CQUFPLENBQUMsb0JBQU87QUFDN0IsYUFBYSxtQkFBTyxDQUFDLHdEQUFRO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxvQ0FBb0MsaUJBQWlCLEtBQUs7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0EsMkNBQTJDO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQixhQUFhO0FBQ2I7QUFDQSxhQUFhO0FBQ2IsU0FBUztBQUNUO0FBQ0E7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsb0RBQW9EO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLG1CQUFPLENBQUMsY0FBSTtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0ZBQWdGO0FBQ2hGO0FBQ0E7QUFDQSw0RUFBNEU7QUFDNUU7QUFDQTtBQUNBLCtFQUErRTtBQUMvRTtBQUNBO0FBQ0EsNkVBQTZFO0FBQzdFO0FBQ0E7QUFDQSw4RUFBOEU7QUFDOUU7QUFDQTtBQUNBLDRFQUE0RTtBQUM1RTtBQUNBO0FBQ0EsNkVBQTZFO0FBQzdFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQywwQkFBMEI7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQixxQkFBcUI7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJHQUEyRztBQUMzRztBQUNBLG1DQUFtQztBQUNuQztBQUNBLDBDQUEwQztBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLG1CQUFPLENBQUMsNkVBQVE7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2REFBNkQsR0FBRyw0QkFBNEI7QUFDNUY7QUFDQTtBQUNBLDZEQUE2RCxHQUFHLDBGQUEwRjtBQUMxSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCOzs7Ozs7Ozs7Ozs7QUNoZkw7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxNQUFNLDZCQUE2QixFQUFFLFlBQVksV0FBVyxFQUFFO0FBQ2pHLGtDQUFrQyxNQUFNLGlDQUFpQyxFQUFFLFlBQVksV0FBVyxFQUFFO0FBQ3BHLCtCQUErQixpRUFBaUUsdUJBQXVCLEVBQUUsNEJBQTRCO0FBQ3JKO0FBQ0EsS0FBSztBQUNMO0FBQ0EsOENBQTZDLENBQUMsY0FBYyxFQUFDO0FBQzdELFdBQVcsbUJBQU8sQ0FBQywwQ0FBSTtBQUN2QixZQUFZLG1CQUFPLENBQUMsZ0JBQUs7QUFDekIsYUFBYSxtQkFBTyxDQUFDLGtCQUFNO0FBQzNCLGFBQWEsbUJBQU8sQ0FBQyxrQkFBTTtBQUMzQjtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQixXQUFXLGdCQUFnQjtBQUMzQixZQUFZLE9BQU87QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEIsV0FBVyxvQkFBb0I7QUFDL0IsWUFBWSxPQUFPO0FBQ25CO0FBQ0E7QUFDQSwrQ0FBK0M7QUFDL0M7QUFDQSxjQUFjLElBQUksRUFBRSxrQkFBa0I7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLG9CQUFvQjtBQUMvQixZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0MsNkNBQTZDO0FBQzdDLCtDQUErQztBQUMvQyxvREFBb0Q7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPLHFCQUFxQjtBQUN2QyxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsb0JBQW9CO0FBQy9CLFlBQVksT0FBTyw0QkFBNEI7QUFDL0M7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFO0FBQ2hFLGdEQUFnRDtBQUNoRCwyRkFBMkY7QUFDM0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtREFBbUQ7QUFDbkQ7QUFDQTtBQUNBLDRCQUE0Qjs7Ozs7Ozs7Ozs7QUN0SDVCLDhIQUF3Qzs7Ozs7Ozs7Ozs7O0FDQTNCOztBQUViLFVBQVUsbUJBQU8sQ0FBQyxnQkFBSztBQUN2QixVQUFVLG1CQUFPLENBQUMsZ0JBQUs7QUFDdkIsV0FBVyxtQkFBTyxDQUFDLGtCQUFNO0FBQ3pCLFlBQVksbUJBQU8sQ0FBQyxvQkFBTztBQUMzQixhQUFhLG1CQUFPLENBQUMsc0JBQVE7QUFDN0IsYUFBYSxtQkFBTyxDQUFDLHNCQUFRO0FBQzdCLFdBQVcsbUJBQU8sQ0FBQyxrQkFBTTs7O0FBR3pCLG9CQUFvQjtBQUNwQixxQkFBcUI7QUFDckIscUJBQXFCO0FBQ3JCLHNCQUFzQjs7O0FBR3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLCtDQUErQyxTQUFTO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsOEJBQThCLGFBQWE7O0FBRTNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsc0NBQXNDO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpREFBaUQ7QUFDakQsMENBQTBDO0FBQzFDLHdDQUF3QztBQUN4Qyx3Q0FBd0M7QUFDeEM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQztBQUNwQztBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7O0FBR0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkOztBQUVBO0FBQ0EseUNBQXlDLFNBQVM7QUFDbEQ7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDLFlBQVk7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLGFBQWEsU0FBUzs7Ozs7Ozs7Ozs7O0FDdlF0QixvQzs7Ozs7Ozs7Ozs7QUNBQSwyQzs7Ozs7Ozs7Ozs7QUNBQSxvQzs7Ozs7Ozs7Ozs7QUNBQSxvQzs7Ozs7Ozs7Ozs7QUNBQSxnQzs7Ozs7Ozs7Ozs7QUNBQSxrQzs7Ozs7Ozs7Ozs7QUNBQSxtQzs7Ozs7Ozs7Ozs7QUNBQSxpQzs7Ozs7Ozs7Ozs7QUNBQSxnQzs7Ozs7Ozs7Ozs7QUNBQSxrQzs7Ozs7Ozs7Ozs7QUNBQSxxQzs7Ozs7Ozs7Ozs7QUNBQSxpQzs7Ozs7Ozs7Ozs7QUNBQSxpQzs7Ozs7Ozs7Ozs7QUNBQSxrQzs7Ozs7Ozs7Ozs7QUNBQSxrQzs7Ozs7O1VDQUE7VUFDQTs7VUFFQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7O1VBRUE7VUFDQTs7VUFFQTtVQUNBO1VBQ0E7Ozs7O1dDckJBLHNGOzs7O1VDQUE7VUFDQTtVQUNBO1VBQ0EiLCJmaWxlIjoiZ2l0cmVsZWFzZW1hbmFnZXIvY3JlYXRlL2J1bmRsZS5qcyIsInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBmcyA9IHJlcXVpcmUoXCJmc1wiKTtcclxudmFyIHBhdGggPSByZXF1aXJlKFwicGF0aFwiKTtcclxudmFyIG9zID0gcmVxdWlyZShcIm9zXCIpO1xyXG52YXIgbWluaW1hdGNoID0gcmVxdWlyZShcIm1pbmltYXRjaFwiKTtcclxudmFyIHV0aWwgPSByZXF1aXJlKFwidXRpbFwiKTtcclxudmFyIHRjbSA9IHJlcXVpcmUoXCIuL3Rhc2tjb21tYW5kXCIpO1xyXG52YXIgdm0gPSByZXF1aXJlKFwiLi92YXVsdFwiKTtcclxudmFyIHNlbXZlciA9IHJlcXVpcmUoXCJzZW12ZXJcIik7XHJcbnZhciBjcnlwdG8gPSByZXF1aXJlKFwiY3J5cHRvXCIpO1xyXG4vKipcclxuICogSGFzaCB0YWJsZSBvZiBrbm93biB2YXJpYWJsZSBpbmZvLiBUaGUgZm9ybWF0dGVkIGVudiB2YXIgbmFtZSBpcyB0aGUgbG9va3VwIGtleS5cclxuICpcclxuICogVGhlIHB1cnBvc2Ugb2YgdGhpcyBoYXNoIHRhYmxlIGlzIHRvIGtlZXAgdHJhY2sgb2Yga25vd24gdmFyaWFibGVzLiBUaGUgaGFzaCB0YWJsZVxyXG4gKiBuZWVkcyB0byBiZSBtYWludGFpbmVkIGZvciBtdWx0aXBsZSByZWFzb25zOlxyXG4gKiAgMSkgdG8gZGlzdGluZ3Vpc2ggYmV0d2VlbiBlbnYgdmFycyBhbmQgam9iIHZhcnNcclxuICogIDIpIHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gc2VjcmV0IHZhcnMgYW5kIHB1YmxpY1xyXG4gKiAgMykgdG8ga25vdyB0aGUgcmVhbCB2YXJpYWJsZSBuYW1lIGFuZCBub3QganVzdCB0aGUgZm9ybWF0dGVkIGVudiB2YXIgbmFtZS5cclxuICovXHJcbmV4cG9ydHMuX2tub3duVmFyaWFibGVNYXAgPSB7fTtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBWYWxpZGF0aW9uIENoZWNrc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIGFzeW5jIGF3YWl0IG5lZWRzIGdlbmVyYXRvcnMgaW4gbm9kZSA0LngrXHJcbmlmIChzZW12ZXIubHQocHJvY2Vzcy52ZXJzaW9ucy5ub2RlLCAnNC4yLjAnKSkge1xyXG4gICAgdGhpcy53YXJuaW5nKCdUYXNrcyByZXF1aXJlIGEgbmV3IGFnZW50LiAgVXBncmFkZSB5b3VyIGFnZW50IG9yIG5vZGUgdG8gNC4yLjAgb3IgbGF0ZXInKTtcclxufVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIFN0cmluZyBjb252ZW5pZW5jZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmZ1bmN0aW9uIF9zdGFydHNXaXRoKHN0ciwgc3RhcnQpIHtcclxuICAgIHJldHVybiBzdHIuc2xpY2UoMCwgc3RhcnQubGVuZ3RoKSA9PSBzdGFydDtcclxufVxyXG5leHBvcnRzLl9zdGFydHNXaXRoID0gX3N0YXJ0c1dpdGg7XHJcbmZ1bmN0aW9uIF9lbmRzV2l0aChzdHIsIGVuZCkge1xyXG4gICAgcmV0dXJuIHN0ci5zbGljZSgtZW5kLmxlbmd0aCkgPT0gZW5kO1xyXG59XHJcbmV4cG9ydHMuX2VuZHNXaXRoID0gX2VuZHNXaXRoO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIEdlbmVyYWwgSGVscGVyc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbnZhciBfb3V0U3RyZWFtID0gcHJvY2Vzcy5zdGRvdXQ7XHJcbnZhciBfZXJyU3RyZWFtID0gcHJvY2Vzcy5zdGRlcnI7XHJcbmZ1bmN0aW9uIF93cml0ZUxpbmUoc3RyKSB7XHJcbiAgICBfb3V0U3RyZWFtLndyaXRlKHN0ciArIG9zLkVPTCk7XHJcbn1cclxuZXhwb3J0cy5fd3JpdGVMaW5lID0gX3dyaXRlTGluZTtcclxuZnVuY3Rpb24gX3NldFN0ZFN0cmVhbShzdGRTdHJlYW0pIHtcclxuICAgIF9vdXRTdHJlYW0gPSBzdGRTdHJlYW07XHJcbn1cclxuZXhwb3J0cy5fc2V0U3RkU3RyZWFtID0gX3NldFN0ZFN0cmVhbTtcclxuZnVuY3Rpb24gX3NldEVyclN0cmVhbShlcnJTdHJlYW0pIHtcclxuICAgIF9lcnJTdHJlYW0gPSBlcnJTdHJlYW07XHJcbn1cclxuZXhwb3J0cy5fc2V0RXJyU3RyZWFtID0gX3NldEVyclN0cmVhbTtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBMb2MgSGVscGVyc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbnZhciBfbG9jU3RyaW5nQ2FjaGUgPSB7fTtcclxudmFyIF9yZXNvdXJjZUZpbGVzID0ge307XHJcbnZhciBfbGliUmVzb3VyY2VGaWxlTG9hZGVkID0gZmFsc2U7XHJcbnZhciBfcmVzb3VyY2VDdWx0dXJlID0gJ2VuLVVTJztcclxuZnVuY3Rpb24gX2xvYWRSZXNKc29uKHJlc2pzb25GaWxlKSB7XHJcbiAgICB2YXIgcmVzSnNvbjtcclxuICAgIGlmIChfZXhpc3QocmVzanNvbkZpbGUpKSB7XHJcbiAgICAgICAgdmFyIHJlc2pzb25Db250ZW50ID0gZnMucmVhZEZpbGVTeW5jKHJlc2pzb25GaWxlLCAndXRmOCcpLnRvU3RyaW5nKCk7XHJcbiAgICAgICAgLy8gcmVtb3ZlIEJPTVxyXG4gICAgICAgIGlmIChyZXNqc29uQ29udGVudC5pbmRleE9mKCdcXHVGRUZGJykgPT0gMCkge1xyXG4gICAgICAgICAgICByZXNqc29uQ29udGVudCA9IHJlc2pzb25Db250ZW50LnNsaWNlKDEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICByZXNKc29uID0gSlNPTi5wYXJzZShyZXNqc29uQ29udGVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgX2RlYnVnKCd1bmFibGUgdG8gcGFyc2UgcmVzanNvbiB3aXRoIGVycjogJyArIGVyci5tZXNzYWdlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBfZGVidWcoJy5yZXNqc29uIGZpbGUgbm90IGZvdW5kOiAnICsgcmVzanNvbkZpbGUpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlc0pzb247XHJcbn1cclxuZnVuY3Rpb24gX2xvYWRMb2NTdHJpbmdzKHJlc291cmNlRmlsZSwgY3VsdHVyZSkge1xyXG4gICAgdmFyIGxvY1N0cmluZ3MgPSB7fTtcclxuICAgIGlmIChfZXhpc3QocmVzb3VyY2VGaWxlKSkge1xyXG4gICAgICAgIHZhciByZXNvdXJjZUpzb24gPSByZXF1aXJlKHJlc291cmNlRmlsZSk7XHJcbiAgICAgICAgaWYgKHJlc291cmNlSnNvbiAmJiByZXNvdXJjZUpzb24uaGFzT3duUHJvcGVydHkoJ21lc3NhZ2VzJykpIHtcclxuICAgICAgICAgICAgdmFyIGxvY1Jlc291cmNlSnNvbjtcclxuICAgICAgICAgICAgLy8gbG9hZCB1cCByZXNvdXJjZSByZXNqc29uIGZvciBkaWZmZXJlbnQgY3VsdHVyZVxyXG4gICAgICAgICAgICB2YXIgbG9jYWxpemVkUmVzb3VyY2VGaWxlID0gcGF0aC5qb2luKHBhdGguZGlybmFtZShyZXNvdXJjZUZpbGUpLCAnU3RyaW5ncycsICdyZXNvdXJjZXMucmVzanNvbicpO1xyXG4gICAgICAgICAgICB2YXIgdXBwZXJDdWx0dXJlID0gY3VsdHVyZS50b1VwcGVyQ2FzZSgpO1xyXG4gICAgICAgICAgICB2YXIgY3VsdHVyZXMgPSBbXTtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGN1bHR1cmVzID0gZnMucmVhZGRpclN5bmMobG9jYWxpemVkUmVzb3VyY2VGaWxlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXRjaCAoZXgpIHsgfVxyXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGN1bHR1cmVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY3VsdHVyZXNbaV0udG9VcHBlckNhc2UoKSA9PSB1cHBlckN1bHR1cmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBsb2NhbGl6ZWRSZXNvdXJjZUZpbGUgPSBwYXRoLmpvaW4obG9jYWxpemVkUmVzb3VyY2VGaWxlLCBjdWx0dXJlc1tpXSwgJ3Jlc291cmNlcy5yZXNqc29uJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9leGlzdChsb2NhbGl6ZWRSZXNvdXJjZUZpbGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvY1Jlc291cmNlSnNvbiA9IF9sb2FkUmVzSnNvbihsb2NhbGl6ZWRSZXNvdXJjZUZpbGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gcmVzb3VyY2VKc29uLm1lc3NhZ2VzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAobG9jUmVzb3VyY2VKc29uICYmIGxvY1Jlc291cmNlSnNvbi5oYXNPd25Qcm9wZXJ0eSgnbG9jLm1lc3NhZ2VzLicgKyBrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9jU3RyaW5nc1trZXldID0gbG9jUmVzb3VyY2VKc29uWydsb2MubWVzc2FnZXMuJyArIGtleV07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBsb2NTdHJpbmdzW2tleV0gPSByZXNvdXJjZUpzb24ubWVzc2FnZXNba2V5XTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIF93YXJuaW5nKCdMSUJfUmVzb3VyY2VGaWxlIGRvZXMgbm90IGV4aXN0Jyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbG9jU3RyaW5ncztcclxufVxyXG4vKipcclxuICogU2V0cyB0aGUgbG9jYXRpb24gb2YgdGhlIHJlc291cmNlcyBqc29uLiAgVGhpcyBpcyB0eXBpY2FsbHkgdGhlIHRhc2suanNvbiBmaWxlLlxyXG4gKiBDYWxsIG9uY2UgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgc2NyaXB0IGJlZm9yZSBhbnkgY2FsbHMgdG8gbG9jLlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHBhdGggICAgICBGdWxsIHBhdGggdG8gdGhlIGpzb24uXHJcbiAqIEBwYXJhbSAgICAgaWdub3JlV2FybmluZ3MgIFdvbid0IHRocm93IHdhcm5pbmdzIGlmIHBhdGggYWxyZWFkeSBzZXQuXHJcbiAqIEByZXR1cm5zICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gX3NldFJlc291cmNlUGF0aChwYXRoLCBpZ25vcmVXYXJuaW5ncykge1xyXG4gICAgaWYgKGlnbm9yZVdhcm5pbmdzID09PSB2b2lkIDApIHsgaWdub3JlV2FybmluZ3MgPSBmYWxzZTsgfVxyXG4gICAgaWYgKHByb2Nlc3MuZW52WydUQVNLTElCX0lOUFJPQ19VTklUUyddKSB7XHJcbiAgICAgICAgX3Jlc291cmNlRmlsZXMgPSB7fTtcclxuICAgICAgICBfbGliUmVzb3VyY2VGaWxlTG9hZGVkID0gZmFsc2U7XHJcbiAgICAgICAgX2xvY1N0cmluZ0NhY2hlID0ge307XHJcbiAgICAgICAgX3Jlc291cmNlQ3VsdHVyZSA9ICdlbi1VUyc7XHJcbiAgICB9XHJcbiAgICBpZiAoIV9yZXNvdXJjZUZpbGVzW3BhdGhdKSB7XHJcbiAgICAgICAgX2NoZWNrUGF0aChwYXRoLCAncmVzb3VyY2UgZmlsZSBwYXRoJyk7XHJcbiAgICAgICAgX3Jlc291cmNlRmlsZXNbcGF0aF0gPSBwYXRoO1xyXG4gICAgICAgIF9kZWJ1ZygnYWRkaW5nIHJlc291cmNlIGZpbGU6ICcgKyBwYXRoKTtcclxuICAgICAgICBfcmVzb3VyY2VDdWx0dXJlID0gX2dldFZhcmlhYmxlKCdzeXN0ZW0uY3VsdHVyZScpIHx8IF9yZXNvdXJjZUN1bHR1cmU7XHJcbiAgICAgICAgdmFyIGxvY1N0cnMgPSBfbG9hZExvY1N0cmluZ3MocGF0aCwgX3Jlc291cmNlQ3VsdHVyZSk7XHJcbiAgICAgICAgZm9yICh2YXIga2V5IGluIGxvY1N0cnMpIHtcclxuICAgICAgICAgICAgLy9jYWNoZSBsb2Mgc3RyaW5nXHJcbiAgICAgICAgICAgIF9sb2NTdHJpbmdDYWNoZVtrZXldID0gbG9jU3Ryc1trZXldO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGlmIChpZ25vcmVXYXJuaW5ncykge1xyXG4gICAgICAgICAgICBfZGVidWcoX2xvYygnTElCX1Jlc291cmNlRmlsZUFscmVhZHlTZXQnLCBwYXRoKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBfd2FybmluZyhfbG9jKCdMSUJfUmVzb3VyY2VGaWxlQWxyZWFkeVNldCcsIHBhdGgpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5fc2V0UmVzb3VyY2VQYXRoID0gX3NldFJlc291cmNlUGF0aDtcclxuLyoqXHJcbiAqIEdldHMgdGhlIGxvY2FsaXplZCBzdHJpbmcgZnJvbSB0aGUganNvbiByZXNvdXJjZSBmaWxlLiAgT3B0aW9uYWxseSBmb3JtYXRzIHdpdGggYWRkaXRpb25hbCBwYXJhbXMuXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAga2V5ICAgICAga2V5IG9mIHRoZSByZXNvdXJjZXMgc3RyaW5nIGluIHRoZSByZXNvdXJjZSBmaWxlXHJcbiAqIEBwYXJhbSAgICAgcGFyYW0gICAgYWRkaXRpb25hbCBwYXJhbXMgZm9yIGZvcm1hdHRpbmcgdGhlIHN0cmluZ1xyXG4gKiBAcmV0dXJucyAgIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gX2xvYyhrZXkpIHtcclxuICAgIHZhciBwYXJhbSA9IFtdO1xyXG4gICAgZm9yICh2YXIgX2kgPSAxOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICBwYXJhbVtfaSAtIDFdID0gYXJndW1lbnRzW19pXTtcclxuICAgIH1cclxuICAgIGlmICghX2xpYlJlc291cmNlRmlsZUxvYWRlZCkge1xyXG4gICAgICAgIC8vIG1lcmdlIGxvYyBzdHJpbmdzIGZyb20gYXp1cmUtcGlwZWxpbmVzLXRhc2stbGliLlxyXG4gICAgICAgIHZhciBsaWJSZXNvdXJjZUZpbGUgPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnbGliLmpzb24nKTtcclxuICAgICAgICB2YXIgbGliTG9jU3RycyA9IF9sb2FkTG9jU3RyaW5ncyhsaWJSZXNvdXJjZUZpbGUsIF9yZXNvdXJjZUN1bHR1cmUpO1xyXG4gICAgICAgIGZvciAodmFyIGxpYktleSBpbiBsaWJMb2NTdHJzKSB7XHJcbiAgICAgICAgICAgIC8vY2FjaGUgYXp1cmUtcGlwZWxpbmVzLXRhc2stbGliIGxvYyBzdHJpbmdcclxuICAgICAgICAgICAgX2xvY1N0cmluZ0NhY2hlW2xpYktleV0gPSBsaWJMb2NTdHJzW2xpYktleV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIF9saWJSZXNvdXJjZUZpbGVMb2FkZWQgPSB0cnVlO1xyXG4gICAgfVxyXG4gICAgdmFyIGxvY1N0cmluZztcclxuICAgIDtcclxuICAgIGlmIChfbG9jU3RyaW5nQ2FjaGUuaGFzT3duUHJvcGVydHkoa2V5KSkge1xyXG4gICAgICAgIGxvY1N0cmluZyA9IF9sb2NTdHJpbmdDYWNoZVtrZXldO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKF9yZXNvdXJjZUZpbGVzKS5sZW5ndGggPD0gMCkge1xyXG4gICAgICAgICAgICBfd2FybmluZyhfbG9jKCdMSUJfUmVzb3VyY2VGaWxlTm90U2V0Jywga2V5KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBfd2FybmluZyhfbG9jKCdMSUJfTG9jU3RyaW5nTm90Rm91bmQnLCBrZXkpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgbG9jU3RyaW5nID0ga2V5O1xyXG4gICAgfVxyXG4gICAgaWYgKHBhcmFtLmxlbmd0aCA+IDApIHtcclxuICAgICAgICByZXR1cm4gdXRpbC5mb3JtYXQuYXBwbHkodGhpcywgW2xvY1N0cmluZ10uY29uY2F0KHBhcmFtKSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICByZXR1cm4gbG9jU3RyaW5nO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMuX2xvYyA9IF9sb2M7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gSW5wdXQgSGVscGVyc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qKlxyXG4gKiBHZXRzIGEgdmFyaWFibGUgdmFsdWUgdGhhdCBpcyBkZWZpbmVkIG9uIHRoZSBidWlsZC9yZWxlYXNlIGRlZmluaXRpb24gb3Igc2V0IGF0IHJ1bnRpbWUuXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgbmFtZSAgICAgbmFtZSBvZiB0aGUgdmFyaWFibGUgdG8gZ2V0XHJcbiAqIEByZXR1cm5zICAgc3RyaW5nXHJcbiAqL1xyXG5mdW5jdGlvbiBfZ2V0VmFyaWFibGUobmFtZSkge1xyXG4gICAgdmFyIHZhcnZhbDtcclxuICAgIC8vIGdldCB0aGUgbWV0YWRhdGFcclxuICAgIHZhciBpbmZvO1xyXG4gICAgdmFyIGtleSA9IF9nZXRWYXJpYWJsZUtleShuYW1lKTtcclxuICAgIGlmIChleHBvcnRzLl9rbm93blZhcmlhYmxlTWFwLmhhc093blByb3BlcnR5KGtleSkpIHtcclxuICAgICAgICBpbmZvID0gZXhwb3J0cy5fa25vd25WYXJpYWJsZU1hcFtrZXldO1xyXG4gICAgfVxyXG4gICAgaWYgKGluZm8gJiYgaW5mby5zZWNyZXQpIHtcclxuICAgICAgICAvLyBnZXQgdGhlIHNlY3JldCB2YWx1ZVxyXG4gICAgICAgIHZhcnZhbCA9IGV4cG9ydHMuX3ZhdWx0LnJldHJpZXZlU2VjcmV0KCdTRUNSRVRfJyArIGtleSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICAvLyBnZXQgdGhlIHB1YmxpYyB2YWx1ZVxyXG4gICAgICAgIHZhcnZhbCA9IHByb2Nlc3MuZW52W2tleV07XHJcbiAgICAgICAgLy8gZmFsbGJhY2sgZm9yIHByZSAyLjEwNC4xIGFnZW50XHJcbiAgICAgICAgaWYgKCF2YXJ2YWwgJiYgbmFtZS50b1VwcGVyQ2FzZSgpID09ICdBR0VOVC5KT0JTVEFUVVMnKSB7XHJcbiAgICAgICAgICAgIHZhcnZhbCA9IHByb2Nlc3MuZW52WydhZ2VudC5qb2JzdGF0dXMnXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBfZGVidWcobmFtZSArICc9JyArIHZhcnZhbCk7XHJcbiAgICByZXR1cm4gdmFydmFsO1xyXG59XHJcbmV4cG9ydHMuX2dldFZhcmlhYmxlID0gX2dldFZhcmlhYmxlO1xyXG5mdW5jdGlvbiBfZ2V0VmFyaWFibGVLZXkobmFtZSkge1xyXG4gICAgaWYgKCFuYW1lKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKF9sb2MoJ0xJQl9QYXJhbWV0ZXJJc1JlcXVpcmVkJywgJ25hbWUnKSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbmFtZS5yZXBsYWNlKC9cXC4vZywgJ18nKS5yZXBsYWNlKC8gL2csICdfJykudG9VcHBlckNhc2UoKTtcclxufVxyXG5leHBvcnRzLl9nZXRWYXJpYWJsZUtleSA9IF9nZXRWYXJpYWJsZUtleTtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBDbWQgSGVscGVyc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmZ1bmN0aW9uIF9jb21tYW5kKGNvbW1hbmQsIHByb3BlcnRpZXMsIG1lc3NhZ2UpIHtcclxuICAgIHZhciB0YXNrQ21kID0gbmV3IHRjbS5UYXNrQ29tbWFuZChjb21tYW5kLCBwcm9wZXJ0aWVzLCBtZXNzYWdlKTtcclxuICAgIF93cml0ZUxpbmUodGFza0NtZC50b1N0cmluZygpKTtcclxufVxyXG5leHBvcnRzLl9jb21tYW5kID0gX2NvbW1hbmQ7XHJcbmZ1bmN0aW9uIF93YXJuaW5nKG1lc3NhZ2UpIHtcclxuICAgIF9jb21tYW5kKCd0YXNrLmlzc3VlJywgeyAndHlwZSc6ICd3YXJuaW5nJyB9LCBtZXNzYWdlKTtcclxufVxyXG5leHBvcnRzLl93YXJuaW5nID0gX3dhcm5pbmc7XHJcbmZ1bmN0aW9uIF9lcnJvcihtZXNzYWdlKSB7XHJcbiAgICBfY29tbWFuZCgndGFzay5pc3N1ZScsIHsgJ3R5cGUnOiAnZXJyb3InIH0sIG1lc3NhZ2UpO1xyXG59XHJcbmV4cG9ydHMuX2Vycm9yID0gX2Vycm9yO1xyXG5mdW5jdGlvbiBfZGVidWcobWVzc2FnZSkge1xyXG4gICAgX2NvbW1hbmQoJ3Rhc2suZGVidWcnLCBudWxsLCBtZXNzYWdlKTtcclxufVxyXG5leHBvcnRzLl9kZWJ1ZyA9IF9kZWJ1ZztcclxuLy8gLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyAvLyBEaXNrIEZ1bmN0aW9uc1xyXG4vLyAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHdoZXRoZXIgYSBwYXRoIGV4aXN0cy5cclxuICpcclxuICogQHBhcmFtICAgICBwYXRoICAgICAgcGF0aCB0byBjaGVja1xyXG4gKiBAcmV0dXJucyAgIGJvb2xlYW5cclxuICovXHJcbmZ1bmN0aW9uIF9leGlzdChwYXRoKSB7XHJcbiAgICB2YXIgZXhpc3QgPSBmYWxzZTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgZXhpc3QgPSAhIShwYXRoICYmIGZzLnN0YXRTeW5jKHBhdGgpICE9IG51bGwpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgIGlmIChlcnIgJiYgZXJyLmNvZGUgPT09ICdFTk9FTlQnKSB7XHJcbiAgICAgICAgICAgIGV4aXN0ID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aHJvdyBlcnI7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGV4aXN0O1xyXG59XHJcbmV4cG9ydHMuX2V4aXN0ID0gX2V4aXN0O1xyXG4vKipcclxuICogQ2hlY2tzIHdoZXRoZXIgYSBwYXRoIGV4aXN0cy5cclxuICogSWYgdGhlIHBhdGggZG9lcyBub3QgZXhpc3QsIGl0IHdpbGwgdGhyb3cuXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgcCAgICAgICAgIHBhdGggdG8gY2hlY2tcclxuICogQHBhcmFtICAgICBuYW1lICAgICAgbmFtZSBvbmx5IHVzZWQgaW4gZXJyb3IgbWVzc2FnZSB0byBpZGVudGlmeSB0aGUgcGF0aFxyXG4gKiBAcmV0dXJucyAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIF9jaGVja1BhdGgocCwgbmFtZSkge1xyXG4gICAgX2RlYnVnKCdjaGVjayBwYXRoIDogJyArIHApO1xyXG4gICAgaWYgKCFfZXhpc3QocCkpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoX2xvYygnTElCX1BhdGhOb3RGb3VuZCcsIG5hbWUsIHApKTtcclxuICAgIH1cclxufVxyXG5leHBvcnRzLl9jaGVja1BhdGggPSBfY2hlY2tQYXRoO1xyXG4vKipcclxuICogUmV0dXJucyBwYXRoIG9mIGEgdG9vbCBoYWQgdGhlIHRvb2wgYWN0dWFsbHkgYmVlbiBpbnZva2VkLiAgUmVzb2x2ZXMgdmlhIHBhdGhzLlxyXG4gKiBJZiB5b3UgY2hlY2sgYW5kIHRoZSB0b29sIGRvZXMgbm90IGV4aXN0LCBpdCB3aWxsIHRocm93LlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHRvb2wgICAgICAgbmFtZSBvZiB0aGUgdG9vbFxyXG4gKiBAcGFyYW0gICAgIGNoZWNrICAgICAgd2hldGhlciB0byBjaGVjayBpZiB0b29sIGV4aXN0c1xyXG4gKiBAcmV0dXJucyAgIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gX3doaWNoKHRvb2wsIGNoZWNrKSB7XHJcbiAgICBpZiAoIXRvb2wpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3BhcmFtZXRlciBcXCd0b29sXFwnIGlzIHJlcXVpcmVkJyk7XHJcbiAgICB9XHJcbiAgICAvLyByZWN1cnNpdmUgd2hlbiBjaGVjaz10cnVlXHJcbiAgICBpZiAoY2hlY2spIHtcclxuICAgICAgICB2YXIgcmVzdWx0ID0gX3doaWNoKHRvb2wsIGZhbHNlKTtcclxuICAgICAgICBpZiAocmVzdWx0KSB7XHJcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoX2xvYygnTElCX1doaWNoTm90Rm91bmRfV2luJywgdG9vbCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKF9sb2MoJ0xJQl9XaGljaE5vdEZvdW5kX0xpbnV4JywgdG9vbCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgX2RlYnVnKFwid2hpY2ggJ1wiICsgdG9vbCArIFwiJ1wiKTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgLy8gYnVpbGQgdGhlIGxpc3Qgb2YgZXh0ZW5zaW9ucyB0byB0cnlcclxuICAgICAgICB2YXIgZXh0ZW5zaW9ucyA9IFtdO1xyXG4gICAgICAgIGlmIChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgJiYgcHJvY2Vzcy5lbnZbJ1BBVEhFWFQnXSkge1xyXG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gcHJvY2Vzcy5lbnZbJ1BBVEhFWFQnXS5zcGxpdChwYXRoLmRlbGltaXRlcik7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZXh0ZW5zaW9uID0gX2FbX2ldO1xyXG4gICAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnMucHVzaChleHRlbnNpb24pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGlmIGl0J3Mgcm9vdGVkLCByZXR1cm4gaXQgaWYgZXhpc3RzLiBvdGhlcndpc2UgcmV0dXJuIGVtcHR5LlxyXG4gICAgICAgIGlmIChfaXNSb290ZWQodG9vbCkpIHtcclxuICAgICAgICAgICAgdmFyIGZpbGVQYXRoID0gX3RyeUdldEV4ZWN1dGFibGVQYXRoKHRvb2wsIGV4dGVuc2lvbnMpO1xyXG4gICAgICAgICAgICBpZiAoZmlsZVBhdGgpIHtcclxuICAgICAgICAgICAgICAgIF9kZWJ1ZyhcImZvdW5kOiAnXCIgKyBmaWxlUGF0aCArIFwiJ1wiKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmaWxlUGF0aDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBfZGVidWcoJ25vdCBmb3VuZCcpO1xyXG4gICAgICAgICAgICByZXR1cm4gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGlmIGFueSBwYXRoIHNlcGFyYXRvcnMsIHJldHVybiBlbXB0eVxyXG4gICAgICAgIGlmICh0b29sLmluZGV4T2YoJy8nKSA+PSAwIHx8IChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgJiYgdG9vbC5pbmRleE9mKCdcXFxcJykgPj0gMCkpIHtcclxuICAgICAgICAgICAgX2RlYnVnKCdub3QgZm91bmQnKTtcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBidWlsZCB0aGUgbGlzdCBvZiBkaXJlY3Rvcmllc1xyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gTm90ZSwgdGVjaG5pY2FsbHkgXCJ3aGVyZVwiIGNoZWNrcyB0aGUgY3VycmVudCBkaXJlY3Rvcnkgb24gV2luZG93cy4gRnJvbSBhIHRhc2sgbGliIHBlcnNwZWN0aXZlLFxyXG4gICAgICAgIC8vIGl0IGZlZWxzIGxpa2Ugd2Ugc2hvdWxkIG5vdCBkbyB0aGlzLiBDaGVja2luZyB0aGUgY3VycmVudCBkaXJlY3Rvcnkgc2VlbXMgbGlrZSBtb3JlIG9mIGEgdXNlXHJcbiAgICAgICAgLy8gY2FzZSBvZiBhIHNoZWxsLCBhbmQgdGhlIHdoaWNoKCkgZnVuY3Rpb24gZXhwb3NlZCBieSB0aGUgdGFzayBsaWIgc2hvdWxkIHN0cml2ZSBmb3IgY29uc2lzdGVuY3lcclxuICAgICAgICAvLyBhY3Jvc3MgcGxhdGZvcm1zLlxyXG4gICAgICAgIHZhciBkaXJlY3RvcmllcyA9IFtdO1xyXG4gICAgICAgIGlmIChwcm9jZXNzLmVudlsnUEFUSCddKSB7XHJcbiAgICAgICAgICAgIGZvciAodmFyIF9iID0gMCwgX2MgPSBwcm9jZXNzLmVudlsnUEFUSCddLnNwbGl0KHBhdGguZGVsaW1pdGVyKTsgX2IgPCBfYy5sZW5ndGg7IF9iKyspIHtcclxuICAgICAgICAgICAgICAgIHZhciBwID0gX2NbX2JdO1xyXG4gICAgICAgICAgICAgICAgaWYgKHApIHtcclxuICAgICAgICAgICAgICAgICAgICBkaXJlY3Rvcmllcy5wdXNoKHApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHJldHVybiB0aGUgZmlyc3QgbWF0Y2hcclxuICAgICAgICBmb3IgKHZhciBfZCA9IDAsIGRpcmVjdG9yaWVzXzEgPSBkaXJlY3RvcmllczsgX2QgPCBkaXJlY3Rvcmllc18xLmxlbmd0aDsgX2QrKykge1xyXG4gICAgICAgICAgICB2YXIgZGlyZWN0b3J5ID0gZGlyZWN0b3JpZXNfMVtfZF07XHJcbiAgICAgICAgICAgIHZhciBmaWxlUGF0aCA9IF90cnlHZXRFeGVjdXRhYmxlUGF0aChkaXJlY3RvcnkgKyBwYXRoLnNlcCArIHRvb2wsIGV4dGVuc2lvbnMpO1xyXG4gICAgICAgICAgICBpZiAoZmlsZVBhdGgpIHtcclxuICAgICAgICAgICAgICAgIF9kZWJ1ZyhcImZvdW5kOiAnXCIgKyBmaWxlUGF0aCArIFwiJ1wiKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmaWxlUGF0aDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBfZGVidWcoJ25vdCBmb3VuZCcpO1xyXG4gICAgICAgIHJldHVybiAnJztcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoX2xvYygnTElCX09wZXJhdGlvbkZhaWxlZCcsICd3aGljaCcsIGVyci5tZXNzYWdlKSk7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5fd2hpY2ggPSBfd2hpY2g7XHJcbi8qKlxyXG4gKiBCZXN0IGVmZm9ydCBhdHRlbXB0IHRvIGRldGVybWluZSB3aGV0aGVyIGEgZmlsZSBleGlzdHMgYW5kIGlzIGV4ZWN1dGFibGUuXHJcbiAqIEBwYXJhbSBmaWxlUGF0aCAgICBmaWxlIHBhdGggdG8gY2hlY2tcclxuICogQHBhcmFtIGV4dGVuc2lvbnMgIGFkZGl0aW9uYWwgZmlsZSBleHRlbnNpb25zIHRvIHRyeVxyXG4gKiBAcmV0dXJuIGlmIGZpbGUgZXhpc3RzIGFuZCBpcyBleGVjdXRhYmxlLCByZXR1cm5zIHRoZSBmaWxlIHBhdGguIG90aGVyd2lzZSBlbXB0eSBzdHJpbmcuXHJcbiAqL1xyXG5mdW5jdGlvbiBfdHJ5R2V0RXhlY3V0YWJsZVBhdGgoZmlsZVBhdGgsIGV4dGVuc2lvbnMpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgLy8gdGVzdCBmaWxlIGV4aXN0c1xyXG4gICAgICAgIHZhciBzdGF0cyA9IGZzLnN0YXRTeW5jKGZpbGVQYXRoKTtcclxuICAgICAgICBpZiAoc3RhdHMuaXNGaWxlKCkpIHtcclxuICAgICAgICAgICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJykge1xyXG4gICAgICAgICAgICAgICAgLy8gb24gV2luZG93cywgdGVzdCBmb3IgdmFsaWQgZXh0ZW5zaW9uXHJcbiAgICAgICAgICAgICAgICB2YXIgaXNFeGVjdXRhYmxlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB2YXIgZmlsZU5hbWUgPSBwYXRoLmJhc2VuYW1lKGZpbGVQYXRoKTtcclxuICAgICAgICAgICAgICAgIHZhciBkb3RJbmRleCA9IGZpbGVOYW1lLmxhc3RJbmRleE9mKCcuJyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoZG90SW5kZXggPj0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB1cHBlckV4dF8xID0gZmlsZU5hbWUuc3Vic3RyKGRvdEluZGV4KS50b1VwcGVyQ2FzZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChleHRlbnNpb25zLnNvbWUoZnVuY3Rpb24gKHZhbGlkRXh0KSB7IHJldHVybiB2YWxpZEV4dC50b1VwcGVyQ2FzZSgpID09IHVwcGVyRXh0XzE7IH0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWxlUGF0aDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaXNVbml4RXhlY3V0YWJsZShzdGF0cykpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsZVBhdGg7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgaWYgKGVyci5jb2RlICE9ICdFTk9FTlQnKSB7XHJcbiAgICAgICAgICAgIF9kZWJ1ZyhcIlVuZXhwZWN0ZWQgZXJyb3IgYXR0ZW1wdGluZyB0byBkZXRlcm1pbmUgaWYgZXhlY3V0YWJsZSBmaWxlIGV4aXN0cyAnXCIgKyBmaWxlUGF0aCArIFwiJzogXCIgKyBlcnIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIHRyeSBlYWNoIGV4dGVuc2lvblxyXG4gICAgdmFyIG9yaWdpbmFsRmlsZVBhdGggPSBmaWxlUGF0aDtcclxuICAgIGZvciAodmFyIF9pID0gMCwgZXh0ZW5zaW9uc18xID0gZXh0ZW5zaW9uczsgX2kgPCBleHRlbnNpb25zXzEubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgdmFyIGV4dGVuc2lvbiA9IGV4dGVuc2lvbnNfMVtfaV07XHJcbiAgICAgICAgdmFyIGZvdW5kID0gZmFsc2U7XHJcbiAgICAgICAgdmFyIGZpbGVQYXRoXzEgPSBvcmlnaW5hbEZpbGVQYXRoICsgZXh0ZW5zaW9uO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHZhciBzdGF0cyA9IGZzLnN0YXRTeW5jKGZpbGVQYXRoXzEpO1xyXG4gICAgICAgICAgICBpZiAoc3RhdHMuaXNGaWxlKCkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBwcmVzZXJ2ZSB0aGUgY2FzZSBvZiB0aGUgYWN0dWFsIGZpbGUgKHNpbmNlIGFuIGV4dGVuc2lvbiB3YXMgYXBwZW5kZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRpcmVjdG9yeSA9IHBhdGguZGlybmFtZShmaWxlUGF0aF8xKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHVwcGVyTmFtZSA9IHBhdGguYmFzZW5hbWUoZmlsZVBhdGhfMSkudG9VcHBlckNhc2UoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgX2EgPSAwLCBfYiA9IGZzLnJlYWRkaXJTeW5jKGRpcmVjdG9yeSk7IF9hIDwgX2IubGVuZ3RoOyBfYSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYWN0dWFsTmFtZSA9IF9iW19hXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1cHBlck5hbWUgPT0gYWN0dWFsTmFtZS50b1VwcGVyQ2FzZSgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVBhdGhfMSA9IHBhdGguam9pbihkaXJlY3RvcnksIGFjdHVhbE5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2RlYnVnKFwiVW5leHBlY3RlZCBlcnJvciBhdHRlbXB0aW5nIHRvIGRldGVybWluZSB0aGUgYWN0dWFsIGNhc2Ugb2YgdGhlIGZpbGUgJ1wiICsgZmlsZVBhdGhfMSArIFwiJzogXCIgKyBlcnIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsZVBhdGhfMTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpc1VuaXhFeGVjdXRhYmxlKHN0YXRzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsZVBhdGhfMTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICBpZiAoZXJyLmNvZGUgIT0gJ0VOT0VOVCcpIHtcclxuICAgICAgICAgICAgICAgIF9kZWJ1ZyhcIlVuZXhwZWN0ZWQgZXJyb3IgYXR0ZW1wdGluZyB0byBkZXRlcm1pbmUgaWYgZXhlY3V0YWJsZSBmaWxlIGV4aXN0cyAnXCIgKyBmaWxlUGF0aF8xICsgXCInOiBcIiArIGVycik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gJyc7XHJcbn1cclxuLy8gb24gTWFjL0xpbnV4LCB0ZXN0IHRoZSBleGVjdXRlIGJpdFxyXG4vLyAgICAgUiAgIFcgIFggIFIgIFcgWCBSIFcgWFxyXG4vLyAgIDI1NiAxMjggNjQgMzIgMTYgOCA0IDIgMVxyXG5mdW5jdGlvbiBpc1VuaXhFeGVjdXRhYmxlKHN0YXRzKSB7XHJcbiAgICByZXR1cm4gKHN0YXRzLm1vZGUgJiAxKSA+IDAgfHwgKChzdGF0cy5tb2RlICYgOCkgPiAwICYmIHN0YXRzLmdpZCA9PT0gcHJvY2Vzcy5nZXRnaWQoKSkgfHwgKChzdGF0cy5tb2RlICYgNjQpID4gMCAmJiBzdGF0cy51aWQgPT09IHByb2Nlc3MuZ2V0dWlkKCkpO1xyXG59XHJcbmZ1bmN0aW9uIF9sZWdhY3lGaW5kRmlsZXNfY29udmVydFBhdHRlcm5Ub1JlZ0V4cChwYXR0ZXJuKSB7XHJcbiAgICBwYXR0ZXJuID0gKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyA/IHBhdHRlcm4ucmVwbGFjZSgvXFxcXC9nLCAnLycpIDogcGF0dGVybikgLy8gbm9ybWFsaXplIHNlcGFyYXRvciBvbiBXaW5kb3dzXHJcbiAgICAgICAgLnJlcGxhY2UoL1stXFwvXFxcXF4kKis/LigpfFtcXF17fV0vZywgJ1xcXFwkJicpIC8vIHJlZ2V4IGVzY2FwZSAtIGZyb20gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zNTYxNDkzL2lzLXRoZXJlLWEtcmVnZXhwLWVzY2FwZS1mdW5jdGlvbi1pbi1qYXZhc2NyaXB0XHJcbiAgICAgICAgLnJlcGxhY2UoL1xcXFxcXC9cXFxcXFwqXFxcXFxcKlxcXFxcXC8vZywgJygoXFwvLisvKXwoXFwvKSknKSAvLyByZXBsYWNlIGRpcmVjdG9yeSBnbG9ic3RhciwgZS5nLiAvaGVsbG8vKiovd29ybGRcclxuICAgICAgICAucmVwbGFjZSgvXFxcXFxcKlxcXFxcXCovZywgJy4qJykgLy8gcmVwbGFjZSByZW1haW5pbmcgZ2xvYnN0YXJzIHdpdGggYSB3aWxkY2FyZCB0aGF0IGNhbiBzcGFuIGRpcmVjdG9yeSBzZXBhcmF0b3JzLCBlLmcuIC9oZWxsby8qKmRsbFxyXG4gICAgICAgIC5yZXBsYWNlKC9cXFxcXFwqL2csICdbXlxcL10qJykgLy8gcmVwbGFjZSBhc3Rlcmlza3Mgd2l0aCBhIHdpbGRjYXJkIHRoYXQgY2Fubm90IHNwYW4gZGlyZWN0b3J5IHNlcGFyYXRvcnMsIGUuZy4gL2hlbGxvLyouZGxsXHJcbiAgICAgICAgLnJlcGxhY2UoL1xcXFxcXD8vZywgJ1teXFwvXScpOyAvLyByZXBsYWNlIHNpbmdsZSBjaGFyYWN0ZXIgd2lsZGNhcmRzLCBlLmcuIC9oZWxsby9sb2c/LmRsbFxyXG4gICAgcGF0dGVybiA9IFwiXlwiICsgcGF0dGVybiArIFwiJFwiO1xyXG4gICAgdmFyIGZsYWdzID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gJ2knIDogJyc7XHJcbiAgICByZXR1cm4gbmV3IFJlZ0V4cChwYXR0ZXJuLCBmbGFncyk7XHJcbn1cclxuZXhwb3J0cy5fbGVnYWN5RmluZEZpbGVzX2NvbnZlcnRQYXR0ZXJuVG9SZWdFeHAgPSBfbGVnYWN5RmluZEZpbGVzX2NvbnZlcnRQYXR0ZXJuVG9SZWdFeHA7XHJcbmZ1bmN0aW9uIF9jbG9uZU1hdGNoT3B0aW9ucyhtYXRjaE9wdGlvbnMpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgZGVidWc6IG1hdGNoT3B0aW9ucy5kZWJ1ZyxcclxuICAgICAgICBub2JyYWNlOiBtYXRjaE9wdGlvbnMubm9icmFjZSxcclxuICAgICAgICBub2dsb2JzdGFyOiBtYXRjaE9wdGlvbnMubm9nbG9ic3RhcixcclxuICAgICAgICBkb3Q6IG1hdGNoT3B0aW9ucy5kb3QsXHJcbiAgICAgICAgbm9leHQ6IG1hdGNoT3B0aW9ucy5ub2V4dCxcclxuICAgICAgICBub2Nhc2U6IG1hdGNoT3B0aW9ucy5ub2Nhc2UsXHJcbiAgICAgICAgbm9udWxsOiBtYXRjaE9wdGlvbnMubm9udWxsLFxyXG4gICAgICAgIG1hdGNoQmFzZTogbWF0Y2hPcHRpb25zLm1hdGNoQmFzZSxcclxuICAgICAgICBub2NvbW1lbnQ6IG1hdGNoT3B0aW9ucy5ub2NvbW1lbnQsXHJcbiAgICAgICAgbm9uZWdhdGU6IG1hdGNoT3B0aW9ucy5ub25lZ2F0ZSxcclxuICAgICAgICBmbGlwTmVnYXRlOiBtYXRjaE9wdGlvbnMuZmxpcE5lZ2F0ZVxyXG4gICAgfTtcclxufVxyXG5leHBvcnRzLl9jbG9uZU1hdGNoT3B0aW9ucyA9IF9jbG9uZU1hdGNoT3B0aW9ucztcclxuZnVuY3Rpb24gX2dldEZpbmRJbmZvRnJvbVBhdHRlcm4oZGVmYXVsdFJvb3QsIHBhdHRlcm4sIG1hdGNoT3B0aW9ucykge1xyXG4gICAgLy8gcGFyYW1ldGVyIHZhbGlkYXRpb25cclxuICAgIGlmICghZGVmYXVsdFJvb3QpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dldEZpbmRSb290RnJvbVBhdHRlcm4oKSBwYXJhbWV0ZXIgZGVmYXVsdFJvb3QgY2Fubm90IGJlIGVtcHR5Jyk7XHJcbiAgICB9XHJcbiAgICBpZiAoIXBhdHRlcm4pIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dldEZpbmRSb290RnJvbVBhdHRlcm4oKSBwYXJhbWV0ZXIgcGF0dGVybiBjYW5ub3QgYmUgZW1wdHknKTtcclxuICAgIH1cclxuICAgIGlmICghbWF0Y2hPcHRpb25zLm5vYnJhY2UpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dldEZpbmRSb290RnJvbVBhdHRlcm4oKSBleHBlY3RlZCBtYXRjaE9wdGlvbnMubm9icmFjZSB0byBiZSB0cnVlJyk7XHJcbiAgICB9XHJcbiAgICAvLyBmb3IgdGhlIHNha2Ugb2YgZGV0ZXJtaW5pbmcgdGhlIGZpbmRQYXRoLCBwcmV0ZW5kIG5vY2FzZT1mYWxzZVxyXG4gICAgbWF0Y2hPcHRpb25zID0gX2Nsb25lTWF0Y2hPcHRpb25zKG1hdGNoT3B0aW9ucyk7XHJcbiAgICBtYXRjaE9wdGlvbnMubm9jYXNlID0gZmFsc2U7XHJcbiAgICAvLyBjaGVjayBpZiBiYXNlbmFtZSBvbmx5IGFuZCBtYXRjaEJhc2U9dHJ1ZVxyXG4gICAgaWYgKG1hdGNoT3B0aW9ucy5tYXRjaEJhc2UgJiZcclxuICAgICAgICAhX2lzUm9vdGVkKHBhdHRlcm4pICYmXHJcbiAgICAgICAgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyA/IHBhdHRlcm4ucmVwbGFjZSgvXFxcXC9nLCAnLycpIDogcGF0dGVybikuaW5kZXhPZignLycpIDwgMCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGFkanVzdGVkUGF0dGVybjogcGF0dGVybixcclxuICAgICAgICAgICAgZmluZFBhdGg6IGRlZmF1bHRSb290LFxyXG4gICAgICAgICAgICBzdGF0T25seTogZmFsc2UsXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIC8vIHRoZSB0ZWNobmlxdWUgYXBwbGllZCBieSB0aGlzIGZ1bmN0aW9uIGlzIHRvIHVzZSB0aGUgaW5mb3JtYXRpb24gb24gdGhlIE1pbmltYXRjaCBvYmplY3QgZGV0ZXJtaW5lXHJcbiAgICAvLyB0aGUgZmluZFBhdGguIE1pbmltYXRjaCBicmVha3MgdGhlIHBhdHRlcm4gaW50byBwYXRoIHNlZ21lbnRzLCBhbmQgZXhwb3NlcyBpbmZvcm1hdGlvbiBhYm91dCB3aGljaFxyXG4gICAgLy8gc2VnbWVudHMgYXJlIGxpdGVyYWwgdnMgcGF0dGVybnMuXHJcbiAgICAvL1xyXG4gICAgLy8gbm90ZSwgdGhlIHRlY2huaXF1ZSBjdXJyZW50bHkgaW1wb3NlcyBhIGxpbWl0YXRpb24gZm9yIGRyaXZlLXJlbGF0aXZlIHBhdGhzIHdpdGggYSBnbG9iIGluIHRoZVxyXG4gICAgLy8gZmlyc3Qgc2VnbWVudCwgZS5nLiBDOmhlbGxvKi93b3JsZC4gaXQncyBmZWFzaWJsZSB0byBvdmVyY29tZSB0aGlzIGxpbWl0YXRpb24sIGJ1dCBpcyBsZWZ0IHVuc29sdmVkXHJcbiAgICAvLyBmb3Igbm93LlxyXG4gICAgdmFyIG1pbmltYXRjaE9iaiA9IG5ldyBtaW5pbWF0Y2guTWluaW1hdGNoKHBhdHRlcm4sIG1hdGNoT3B0aW9ucyk7XHJcbiAgICAvLyB0aGUgXCJzZXRcIiBwcm9wZXJ0eSBpcyBhbiBhcnJheSBvZiBhcnJheXMgb2YgcGFyc2VkIHBhdGggc2VnbWVudCBpbmZvLiB0aGUgb3V0ZXIgYXJyYXkgc2hvdWxkIG9ubHlcclxuICAgIC8vIGNvbnRhaW4gb25lIGl0ZW0sIG90aGVyd2lzZSBzb21ldGhpbmcgd2VudCB3cm9uZy4gYnJhY2UgZXhwYW5zaW9uIGNhbiByZXN1bHQgaW4gbXVsdGlwbGUgYXJyYXlzLFxyXG4gICAgLy8gYnV0IHRoYXQgc2hvdWxkIGJlIHR1cm5lZCBvZmYgYnkgdGhlIHRpbWUgdGhpcyBmdW5jdGlvbiBpcyByZWFjaGVkLlxyXG4gICAgaWYgKG1pbmltYXRjaE9iai5zZXQubGVuZ3RoICE9IDEpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dldEZpbmRSb290RnJvbVBhdHRlcm4oKSBleHBlY3RlZCBNaW5pbWF0Y2goLi4uKS5zZXQubGVuZ3RoIHRvIGJlIDEuIEFjdHVhbDogJyArIG1pbmltYXRjaE9iai5zZXQubGVuZ3RoKTtcclxuICAgIH1cclxuICAgIHZhciBsaXRlcmFsU2VnbWVudHMgPSBbXTtcclxuICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSBtaW5pbWF0Y2hPYmouc2V0WzBdOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgIHZhciBwYXJzZWRTZWdtZW50ID0gX2FbX2ldO1xyXG4gICAgICAgIGlmICh0eXBlb2YgcGFyc2VkU2VnbWVudCA9PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICAvLyB0aGUgaXRlbSBpcyBhIHN0cmluZyB3aGVuIHRoZSBvcmlnaW5hbCBpbnB1dCBmb3IgdGhlIHBhdGggc2VnbWVudCBkb2VzIG5vdCBjb250YWluIGFueVxyXG4gICAgICAgICAgICAvLyB1bmVzY2FwZWQgZ2xvYiBjaGFyYWN0ZXJzLlxyXG4gICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAvLyBub3RlLCB0aGUgc3RyaW5nIGhlcmUgaXMgYWxyZWFkeSB1bmVzY2FwZWQgKGkuZS4gZ2xvYiBlc2NhcGluZyByZW1vdmVkKSwgc28gaXQgaXMgcmVhZHlcclxuICAgICAgICAgICAgLy8gdG8gcGFzcyB0byBmaW5kKCkgYXMtaXMuIGZvciBleGFtcGxlLCBhbiBpbnB1dCBzdHJpbmcgJ2hlbGxvXFxcXCp3b3JsZCcgPT4gJ2hlbGxvKndvcmxkJy5cclxuICAgICAgICAgICAgbGl0ZXJhbFNlZ21lbnRzLnB1c2gocGFyc2VkU2VnbWVudCk7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBicmVhaztcclxuICAgIH1cclxuICAgIC8vIGpvaW4gdGhlIGxpdGVyYWwgc2VnbWVudHMgYmFjayB0b2dldGhlci4gTWluaW1hdGNoIGNvbnZlcnRzICdcXCcgdG8gJy8nIG9uIFdpbmRvd3MsIHRoZW4gc3F1YXNoZXNcclxuICAgIC8vIGNvbnNlcXVldGl2ZSBzbGFzaGVzLCBhbmQgZmluYWxseSBzcGxpdHMgb24gc2xhc2guIHRoaXMgbWVhbnMgdGhhdCBVTkMgZm9ybWF0IGlzIGxvc3QsIGJ1dCBjYW5cclxuICAgIC8vIGJlIGRldGVjdGVkIGZyb20gdGhlIG9yaWdpbmFsIHBhdHRlcm4uXHJcbiAgICB2YXIgam9pbmVkU2VnbWVudHMgPSBsaXRlcmFsU2VnbWVudHMuam9pbignLycpO1xyXG4gICAgaWYgKGpvaW5lZFNlZ21lbnRzICYmIHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyAmJiBfc3RhcnRzV2l0aChwYXR0ZXJuLnJlcGxhY2UoL1xcXFwvZywgJy8nKSwgJy8vJykpIHtcclxuICAgICAgICBqb2luZWRTZWdtZW50cyA9ICcvJyArIGpvaW5lZFNlZ21lbnRzOyAvLyByZXN0b3JlIFVOQyBmb3JtYXRcclxuICAgIH1cclxuICAgIC8vIGRldGVybWluZSB0aGUgZmluZCBwYXRoXHJcbiAgICB2YXIgZmluZFBhdGg7XHJcbiAgICBpZiAoX2lzUm9vdGVkKHBhdHRlcm4pKSB7IC8vIHRoZSBwYXR0ZXJuIHdhcyByb290ZWRcclxuICAgICAgICBmaW5kUGF0aCA9IGpvaW5lZFNlZ21lbnRzO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoam9pbmVkU2VnbWVudHMpIHsgLy8gdGhlIHBhdHRlcm4gd2FzIG5vdCByb290ZWQsIGFuZCBsaXRlcmFsIHNlZ21lbnRzIHdlcmUgZm91bmRcclxuICAgICAgICBmaW5kUGF0aCA9IF9lbnN1cmVSb290ZWQoZGVmYXVsdFJvb3QsIGpvaW5lZFNlZ21lbnRzKTtcclxuICAgIH1cclxuICAgIGVsc2UgeyAvLyB0aGUgcGF0dGVybiB3YXMgbm90IHJvb3RlZCwgYW5kIG5vIGxpdGVyYWwgc2VnbWVudHMgd2VyZSBmb3VuZFxyXG4gICAgICAgIGZpbmRQYXRoID0gZGVmYXVsdFJvb3Q7XHJcbiAgICB9XHJcbiAgICAvLyBjbGVhbiB1cCB0aGUgcGF0aFxyXG4gICAgaWYgKGZpbmRQYXRoKSB7XHJcbiAgICAgICAgZmluZFBhdGggPSBfZ2V0RGlyZWN0b3J5TmFtZShfZW5zdXJlUm9vdGVkKGZpbmRQYXRoLCAnXycpKTsgLy8gaGFjayB0byByZW1vdmUgdW5uZWNlc3NhcnkgdHJhaWxpbmcgc2xhc2hcclxuICAgICAgICBmaW5kUGF0aCA9IF9ub3JtYWxpemVTZXBhcmF0b3JzKGZpbmRQYXRoKTsgLy8gbm9ybWFsaXplIHNsYXNoZXNcclxuICAgIH1cclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgYWRqdXN0ZWRQYXR0ZXJuOiBfZW5zdXJlUGF0dGVyblJvb3RlZChkZWZhdWx0Um9vdCwgcGF0dGVybiksXHJcbiAgICAgICAgZmluZFBhdGg6IGZpbmRQYXRoLFxyXG4gICAgICAgIHN0YXRPbmx5OiBsaXRlcmFsU2VnbWVudHMubGVuZ3RoID09IG1pbmltYXRjaE9iai5zZXRbMF0ubGVuZ3RoLFxyXG4gICAgfTtcclxufVxyXG5leHBvcnRzLl9nZXRGaW5kSW5mb0Zyb21QYXR0ZXJuID0gX2dldEZpbmRJbmZvRnJvbVBhdHRlcm47XHJcbmZ1bmN0aW9uIF9lbnN1cmVQYXR0ZXJuUm9vdGVkKHJvb3QsIHApIHtcclxuICAgIGlmICghcm9vdCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZW5zdXJlUGF0dGVyblJvb3RlZCgpIHBhcmFtZXRlciBcInJvb3RcIiBjYW5ub3QgYmUgZW1wdHknKTtcclxuICAgIH1cclxuICAgIGlmICghcCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZW5zdXJlUGF0dGVyblJvb3RlZCgpIHBhcmFtZXRlciBcInBcIiBjYW5ub3QgYmUgZW1wdHknKTtcclxuICAgIH1cclxuICAgIGlmIChfaXNSb290ZWQocCkpIHtcclxuICAgICAgICByZXR1cm4gcDtcclxuICAgIH1cclxuICAgIC8vIG5vcm1hbGl6ZSByb290XHJcbiAgICByb290ID0gX25vcm1hbGl6ZVNlcGFyYXRvcnMocm9vdCk7XHJcbiAgICAvLyBlc2NhcGUgc3BlY2lhbCBnbG9iIGNoYXJhY3RlcnNcclxuICAgIHJvb3QgPSAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gcm9vdCA6IHJvb3QucmVwbGFjZSgvXFxcXC9nLCAnXFxcXFxcXFwnKSkgLy8gZXNjYXBlICdcXCcgb24gT1NYL0xpbnV4XHJcbiAgICAgICAgLnJlcGxhY2UoLyhcXFspKD89W15cXC9dK1xcXSkvZywgJ1tbXScpIC8vIGVzY2FwZSAnWycgd2hlbiAnXScgZm9sbG93cyB3aXRoaW4gdGhlIHBhdGggc2VnbWVudFxyXG4gICAgICAgIC5yZXBsYWNlKC9cXD8vZywgJ1s/XScpIC8vIGVzY2FwZSAnPydcclxuICAgICAgICAucmVwbGFjZSgvXFwqL2csICdbKl0nKSAvLyBlc2NhcGUgJyonXHJcbiAgICAgICAgLnJlcGxhY2UoL1xcK1xcKC9nLCAnWytdKCcpIC8vIGVzY2FwZSAnKygnXHJcbiAgICAgICAgLnJlcGxhY2UoL0BcXCgvZywgJ1tAXSgnKSAvLyBlc2NhcGUgJ0AoJ1xyXG4gICAgICAgIC5yZXBsYWNlKC8hXFwoL2csICdbIV0oJyk7IC8vIGVzY2FwZSAnISgnXHJcbiAgICByZXR1cm4gX2Vuc3VyZVJvb3RlZChyb290LCBwKTtcclxufVxyXG5leHBvcnRzLl9lbnN1cmVQYXR0ZXJuUm9vdGVkID0gX2Vuc3VyZVBhdHRlcm5Sb290ZWQ7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBQb3B1bGF0ZSB0aGUgdmF1bHQgd2l0aCBzZW5zaXRpdmUgZGF0YS4gIElucHV0cyBhbmQgRW5kcG9pbnRzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5mdW5jdGlvbiBfbG9hZERhdGEoKSB7XHJcbiAgICAvLyBpbiBhZ2VudCwgcHJlZmVyIFRlbXBEaXJlY3RvcnkgdGhlbiB3b3JrRm9sZGVyLlxyXG4gICAgLy8gSW4gaW50ZXJhY3RpdmUgZGV2IG1vZGUsIGl0IHdvbid0IGJlXHJcbiAgICB2YXIga2V5UGF0aCA9IF9nZXRWYXJpYWJsZShcImFnZW50LlRlbXBEaXJlY3RvcnlcIikgfHwgX2dldFZhcmlhYmxlKFwiYWdlbnQud29ya0ZvbGRlclwiKSB8fCBwcm9jZXNzLmN3ZCgpO1xyXG4gICAgZXhwb3J0cy5fdmF1bHQgPSBuZXcgdm0uVmF1bHQoa2V5UGF0aCk7XHJcbiAgICBleHBvcnRzLl9rbm93blZhcmlhYmxlTWFwID0ge307XHJcbiAgICBfZGVidWcoJ2xvYWRpbmcgaW5wdXRzIGFuZCBlbmRwb2ludHMnKTtcclxuICAgIHZhciBsb2FkZWQgPSAwO1xyXG4gICAgZm9yICh2YXIgZW52dmFyIGluIHByb2Nlc3MuZW52KSB7XHJcbiAgICAgICAgaWYgKF9zdGFydHNXaXRoKGVudnZhciwgJ0lOUFVUXycpIHx8XHJcbiAgICAgICAgICAgIF9zdGFydHNXaXRoKGVudnZhciwgJ0VORFBPSU5UX0FVVEhfJykgfHxcclxuICAgICAgICAgICAgX3N0YXJ0c1dpdGgoZW52dmFyLCAnU0VDVVJFRklMRV9USUNLRVRfJykgfHxcclxuICAgICAgICAgICAgX3N0YXJ0c1dpdGgoZW52dmFyLCAnU0VDUkVUXycpIHx8XHJcbiAgICAgICAgICAgIF9zdGFydHNXaXRoKGVudnZhciwgJ1ZTVFNfVEFTS1ZBUklBQkxFXycpKSB7XHJcbiAgICAgICAgICAgIC8vIFJlY29yZCB0aGUgc2VjcmV0IHZhcmlhYmxlIG1ldGFkYXRhLiBUaGlzIGlzIHJlcXVpcmVkIGJ5IGdldFZhcmlhYmxlIHRvIGtub3cgd2hldGhlclxyXG4gICAgICAgICAgICAvLyB0byByZXRyaWV2ZSB0aGUgdmFsdWUgZnJvbSB0aGUgdmF1bHQuIEluIGEgMi4xMDQuMSBhZ2VudCBvciBoaWdoZXIsIHRoaXMgbWV0YWRhdGEgd2lsbFxyXG4gICAgICAgICAgICAvLyBiZSBvdmVyd3JpdHRlbiB3aGVuIHRoZSBWU1RTX1NFQ1JFVF9WQVJJQUJMRVMgZW52IHZhciBpcyBwcm9jZXNzZWQgYmVsb3cuXHJcbiAgICAgICAgICAgIGlmIChfc3RhcnRzV2l0aChlbnZ2YXIsICdTRUNSRVRfJykpIHtcclxuICAgICAgICAgICAgICAgIHZhciB2YXJpYWJsZU5hbWUgPSBlbnZ2YXIuc3Vic3RyaW5nKCdTRUNSRVRfJy5sZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHZhcmlhYmxlTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdGVjaG5pY2FsbHkgbm90IHRoZSB2YXJpYWJsZSBuYW1lIChoYXMgdW5kZXJzY29yZXMgaW5zdGVhZCBvZiBkb3RzKSxcclxuICAgICAgICAgICAgICAgICAgICAvLyBidXQgaXQncyBnb29kIGVub3VnaCB0byBtYWtlIGdldFZhcmlhYmxlIHdvcmsgaW4gYSBwcmUtMi4xMDQuMSBhZ2VudCB3aGVyZVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoZSBWU1RTX1NFQ1JFVF9WQVJJQUJMRVMgZW52IHZhciBpcyBub3QgZGVmaW5lZC5cclxuICAgICAgICAgICAgICAgICAgICBleHBvcnRzLl9rbm93blZhcmlhYmxlTWFwW19nZXRWYXJpYWJsZUtleSh2YXJpYWJsZU5hbWUpXSA9IHsgbmFtZTogdmFyaWFibGVOYW1lLCBzZWNyZXQ6IHRydWUgfTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBzdG9yZSB0aGUgc2VjcmV0XHJcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudltlbnZ2YXJdKSB7XHJcbiAgICAgICAgICAgICAgICArK2xvYWRlZDtcclxuICAgICAgICAgICAgICAgIF9kZWJ1ZygnbG9hZGluZyAnICsgZW52dmFyKTtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuX3ZhdWx0LnN0b3JlU2VjcmV0KGVudnZhciwgcHJvY2Vzcy5lbnZbZW52dmFyXSk7XHJcbiAgICAgICAgICAgICAgICBkZWxldGUgcHJvY2Vzcy5lbnZbZW52dmFyXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIF9kZWJ1ZygnbG9hZGVkICcgKyBsb2FkZWQpO1xyXG4gICAgLy8gc3RvcmUgcHVibGljIHZhcmlhYmxlIG1ldGFkYXRhXHJcbiAgICB2YXIgbmFtZXM7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIG5hbWVzID0gSlNPTi5wYXJzZShwcm9jZXNzLmVudlsnVlNUU19QVUJMSUNfVkFSSUFCTEVTJ10gfHwgJ1tdJyk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gcGFyc2UgVlNUU19QVUJMSUNfVkFSSUFCTEVTIGFzIEpTT04uICcgKyBlcnIpOyAvLyBtYXkgb2NjdXIgZHVyaW5nIGludGVyYWN0aXZlIHRlc3RpbmdcclxuICAgIH1cclxuICAgIG5hbWVzLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcclxuICAgICAgICBleHBvcnRzLl9rbm93blZhcmlhYmxlTWFwW19nZXRWYXJpYWJsZUtleShuYW1lKV0gPSB7IG5hbWU6IG5hbWUsIHNlY3JldDogZmFsc2UgfTtcclxuICAgIH0pO1xyXG4gICAgZGVsZXRlIHByb2Nlc3MuZW52WydWU1RTX1BVQkxJQ19WQVJJQUJMRVMnXTtcclxuICAgIC8vIHN0b3JlIHNlY3JldCB2YXJpYWJsZSBtZXRhZGF0YVxyXG4gICAgdHJ5IHtcclxuICAgICAgICBuYW1lcyA9IEpTT04ucGFyc2UocHJvY2Vzcy5lbnZbJ1ZTVFNfU0VDUkVUX1ZBUklBQkxFUyddIHx8ICdbXScpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIHBhcnNlIFZTVFNfU0VDUkVUX1ZBUklBQkxFUyBhcyBKU09OLiAnICsgZXJyKTsgLy8gbWF5IG9jY3VyIGR1cmluZyBpbnRlcmFjdGl2ZSB0ZXN0aW5nXHJcbiAgICB9XHJcbiAgICBuYW1lcy5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XHJcbiAgICAgICAgZXhwb3J0cy5fa25vd25WYXJpYWJsZU1hcFtfZ2V0VmFyaWFibGVLZXkobmFtZSldID0geyBuYW1lOiBuYW1lLCBzZWNyZXQ6IHRydWUgfTtcclxuICAgIH0pO1xyXG4gICAgZGVsZXRlIHByb2Nlc3MuZW52WydWU1RTX1NFQ1JFVF9WQVJJQUJMRVMnXTtcclxuICAgIC8vIGF2b2lkIGxvYWRpbmcgdHdpY2UgKG92ZXJ3cml0ZXMgLnRhc2trZXkpXHJcbiAgICBnbG9iYWxbJ192c3RzX3Rhc2tfbGliX2xvYWRlZCddID0gdHJ1ZTtcclxufVxyXG5leHBvcnRzLl9sb2FkRGF0YSA9IF9sb2FkRGF0YTtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBJbnRlcm5hbCBwYXRoIGhlbHBlcnMuXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZnVuY3Rpb24gX2Vuc3VyZVJvb3RlZChyb290LCBwKSB7XHJcbiAgICBpZiAoIXJvb3QpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Vuc3VyZVJvb3RlZCgpIHBhcmFtZXRlciBcInJvb3RcIiBjYW5ub3QgYmUgZW1wdHknKTtcclxuICAgIH1cclxuICAgIGlmICghcCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZW5zdXJlUm9vdGVkKCkgcGFyYW1ldGVyIFwicFwiIGNhbm5vdCBiZSBlbXB0eScpO1xyXG4gICAgfVxyXG4gICAgaWYgKF9pc1Jvb3RlZChwKSkge1xyXG4gICAgICAgIHJldHVybiBwO1xyXG4gICAgfVxyXG4gICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyAmJiByb290Lm1hdGNoKC9eW0EtWl06JC9pKSkgeyAvLyBlLmcuIEM6XHJcbiAgICAgICAgcmV0dXJuIHJvb3QgKyBwO1xyXG4gICAgfVxyXG4gICAgLy8gZW5zdXJlIHJvb3QgZW5kcyB3aXRoIGEgc2VwYXJhdG9yXHJcbiAgICBpZiAoX2VuZHNXaXRoKHJvb3QsICcvJykgfHwgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyAmJiBfZW5kc1dpdGgocm9vdCwgJ1xcXFwnKSkpIHtcclxuICAgICAgICAvLyByb290IGFscmVhZHkgZW5kcyB3aXRoIGEgc2VwYXJhdG9yXHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICByb290ICs9IHBhdGguc2VwOyAvLyBhcHBlbmQgc2VwYXJhdG9yXHJcbiAgICB9XHJcbiAgICByZXR1cm4gcm9vdCArIHA7XHJcbn1cclxuZXhwb3J0cy5fZW5zdXJlUm9vdGVkID0gX2Vuc3VyZVJvb3RlZDtcclxuLyoqXHJcbiAqIERldGVybWluZXMgdGhlIHBhcmVudCBwYXRoIGFuZCB0cmltcyB0cmFpbGluZyBzbGFzaGVzICh3aGVuIHNhZmUpLiBQYXRoIHNlcGFyYXRvcnMgYXJlIG5vcm1hbGl6ZWRcclxuICogaW4gdGhlIHJlc3VsdC4gVGhpcyBmdW5jdGlvbiB3b3JrcyBzaW1pbGFyIHRvIHRoZSAuTkVUIFN5c3RlbS5JTy5QYXRoLkdldERpcmVjdG9yeU5hbWUoKSBtZXRob2QuXHJcbiAqIEZvciBleGFtcGxlLCBDOlxcaGVsbG9cXHdvcmxkXFwgcmV0dXJucyBDOlxcaGVsbG9cXHdvcmxkICh0cmFpbGluZyBzbGFzaCByZW1vdmVkKS4gUmV0dXJucyBlbXB0eSB3aGVuXHJcbiAqIG5vIGhpZ2hlciBkaXJlY3RvcnkgY2FuIGJlIGRldGVybWluZWQuXHJcbiAqL1xyXG5mdW5jdGlvbiBfZ2V0RGlyZWN0b3J5TmFtZShwKSB7XHJcbiAgICAvLyBzaG9ydC1jaXJjdWl0IGlmIGVtcHR5XHJcbiAgICBpZiAoIXApIHtcclxuICAgICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcbiAgICAvLyBub3JtYWxpemUgc2VwYXJhdG9yc1xyXG4gICAgcCA9IF9ub3JtYWxpemVTZXBhcmF0b3JzKHApO1xyXG4gICAgLy8gb24gV2luZG93cywgdGhlIGdvYWwgb2YgdGhpcyBmdW5jdGlvbiBpcyB0byBtYXRjaCB0aGUgYmVoYXZpb3Igb2ZcclxuICAgIC8vIFtTeXN0ZW0uSU8uUGF0aF06OkdldERpcmVjdG9yeU5hbWUoKSwgZS5nLlxyXG4gICAgLy8gICAgICBDOi8gICAgICAgICAgICAgPT5cclxuICAgIC8vICAgICAgQzovaGVsbG8gICAgICAgID0+IEM6XFxcclxuICAgIC8vICAgICAgQzovaGVsbG8vICAgICAgID0+IEM6XFxoZWxsb1xyXG4gICAgLy8gICAgICBDOi9oZWxsby93b3JsZCAgPT4gQzpcXGhlbGxvXHJcbiAgICAvLyAgICAgIEM6L2hlbGxvL3dvcmxkLyA9PiBDOlxcaGVsbG9cXHdvcmxkXHJcbiAgICAvLyAgICAgIEM6ICAgICAgICAgICAgICA9PlxyXG4gICAgLy8gICAgICBDOmhlbGxvICAgICAgICAgPT4gQzpcclxuICAgIC8vICAgICAgQzpoZWxsby8gICAgICAgID0+IEM6aGVsbG9cclxuICAgIC8vICAgICAgLyAgICAgICAgICAgICAgID0+XHJcbiAgICAvLyAgICAgIC9oZWxsbyAgICAgICAgICA9PiBcXFxyXG4gICAgLy8gICAgICAvaGVsbG8vICAgICAgICAgPT4gXFxoZWxsb1xyXG4gICAgLy8gICAgICAvL2hlbGxvICAgICAgICAgPT5cclxuICAgIC8vICAgICAgLy9oZWxsby8gICAgICAgID0+XHJcbiAgICAvLyAgICAgIC8vaGVsbG8vd29ybGQgICA9PlxyXG4gICAgLy8gICAgICAvL2hlbGxvL3dvcmxkLyAgPT4gXFxcXGhlbGxvXFx3b3JsZFxyXG4gICAgLy9cclxuICAgIC8vIHVuZm9ydHVuYXRlbHksIHBhdGguZGlybmFtZSgpIGNhbid0IHNpbXBseSBiZSB1c2VkLiBmb3IgZXhhbXBsZSwgb24gV2luZG93c1xyXG4gICAgLy8gaXQgeWllbGRzIGRpZmZlcmVudCByZXN1bHRzIGZyb20gUGF0aC5HZXREaXJlY3RvcnlOYW1lOlxyXG4gICAgLy8gICAgICBDOi8gICAgICAgICAgICAgPT4gQzovXHJcbiAgICAvLyAgICAgIEM6L2hlbGxvICAgICAgICA9PiBDOi9cclxuICAgIC8vICAgICAgQzovaGVsbG8vICAgICAgID0+IEM6L1xyXG4gICAgLy8gICAgICBDOi9oZWxsby93b3JsZCAgPT4gQzovaGVsbG9cclxuICAgIC8vICAgICAgQzovaGVsbG8vd29ybGQvID0+IEM6L2hlbGxvXHJcbiAgICAvLyAgICAgIEM6ICAgICAgICAgICAgICA9PiBDOlxyXG4gICAgLy8gICAgICBDOmhlbGxvICAgICAgICAgPT4gQzpcclxuICAgIC8vICAgICAgQzpoZWxsby8gICAgICAgID0+IEM6XHJcbiAgICAvLyAgICAgIC8gICAgICAgICAgICAgICA9PiAvXHJcbiAgICAvLyAgICAgIC9oZWxsbyAgICAgICAgICA9PiAvXHJcbiAgICAvLyAgICAgIC9oZWxsby8gICAgICAgICA9PiAvXHJcbiAgICAvLyAgICAgIC8vaGVsbG8gICAgICAgICA9PiAvXHJcbiAgICAvLyAgICAgIC8vaGVsbG8vICAgICAgICA9PiAvXHJcbiAgICAvLyAgICAgIC8vaGVsbG8vd29ybGQgICA9PiAvL2hlbGxvL3dvcmxkXHJcbiAgICAvLyAgICAgIC8vaGVsbG8vd29ybGQvICA9PiAvL2hlbGxvL3dvcmxkL1xyXG4gICAgLy8gICAgICAvL2hlbGxvL3dvcmxkL2FnYWluID0+IC8vaGVsbG8vd29ybGQvXHJcbiAgICAvLyAgICAgIC8vaGVsbG8vd29ybGQvYWdhaW4vID0+IC8vaGVsbG8vd29ybGQvXHJcbiAgICAvLyAgICAgIC8vaGVsbG8vd29ybGQvYWdhaW4vYWdhaW4gPT4gLy9oZWxsby93b3JsZC9hZ2FpblxyXG4gICAgLy8gICAgICAvL2hlbGxvL3dvcmxkL2FnYWluL2FnYWluLyA9PiAvL2hlbGxvL3dvcmxkL2FnYWluXHJcbiAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInKSB7XHJcbiAgICAgICAgaWYgKC9eW0EtWl06XFxcXD9bXlxcXFxdKyQvaS50ZXN0KHApKSB7IC8vIGUuZy4gQzpcXGhlbGxvIG9yIEM6aGVsbG9cclxuICAgICAgICAgICAgcmV0dXJuIHAuY2hhckF0KDIpID09ICdcXFxcJyA/IHAuc3Vic3RyaW5nKDAsIDMpIDogcC5zdWJzdHJpbmcoMCwgMik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKC9eW0EtWl06XFxcXD8kL2kudGVzdChwKSkgeyAvLyBlLmcuIEM6XFwgb3IgQzpcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgbGFzdFNsYXNoSW5kZXggPSBwLmxhc3RJbmRleE9mKCdcXFxcJyk7XHJcbiAgICAgICAgaWYgKGxhc3RTbGFzaEluZGV4IDwgMCkgeyAvLyBmaWxlIG5hbWUgb25seVxyXG4gICAgICAgICAgICByZXR1cm4gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHAgPT0gJ1xcXFwnKSB7IC8vIHJlbGF0aXZlIHJvb3RcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChsYXN0U2xhc2hJbmRleCA9PSAwKSB7IC8vIGUuZy4gXFxcXGhlbGxvXHJcbiAgICAgICAgICAgIHJldHVybiAnXFxcXCc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKC9eXFxcXFxcXFxbXlxcXFxdKyhcXFxcW15cXFxcXSopPyQvLnRlc3QocCkpIHsgLy8gVU5DIHJvb3QsIGUuZy4gXFxcXGhlbGxvIG9yIFxcXFxoZWxsb1xcIG9yIFxcXFxoZWxsb1xcd29ybGRcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcC5zdWJzdHJpbmcoMCwgbGFzdFNsYXNoSW5kZXgpOyAvLyBlLmcuIGhlbGxvXFx3b3JsZCA9PiBoZWxsbyBvciBoZWxsb1xcd29ybGRcXCA9PiBoZWxsb1xcd29ybGRcclxuICAgICAgICAvLyBub3RlLCB0aGlzIG1lYW5zIHRyYWlsaW5nIHNsYXNoZXMgZm9yIG5vbi1yb290IGRpcmVjdG9yaWVzXHJcbiAgICAgICAgLy8gKGkuZS4gbm90IEM6XFwsIFxcLCBvciBcXFxcdW5jXFwpIHdpbGwgc2ltcGx5IGJlIHJlbW92ZWQuXHJcbiAgICB9XHJcbiAgICAvLyBPU1gvTGludXhcclxuICAgIGlmIChwLmluZGV4T2YoJy8nKSA8IDApIHsgLy8gZmlsZSBuYW1lIG9ubHlcclxuICAgICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChwID09ICcvJykge1xyXG4gICAgICAgIHJldHVybiAnJztcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKF9lbmRzV2l0aChwLCAnLycpKSB7XHJcbiAgICAgICAgcmV0dXJuIHAuc3Vic3RyaW5nKDAsIHAubGVuZ3RoIC0gMSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcGF0aC5kaXJuYW1lKHApO1xyXG59XHJcbmV4cG9ydHMuX2dldERpcmVjdG9yeU5hbWUgPSBfZ2V0RGlyZWN0b3J5TmFtZTtcclxuLyoqXHJcbiAqIE9uIE9TWC9MaW51eCwgdHJ1ZSBpZiBwYXRoIHN0YXJ0cyB3aXRoICcvJy4gT24gV2luZG93cywgdHJ1ZSBmb3IgcGF0aHMgbGlrZTpcclxuICogXFwsIFxcaGVsbG8sIFxcXFxoZWxsb1xcc2hhcmUsIEM6LCBhbmQgQzpcXGhlbGxvIChhbmQgY29ycmVzcG9uZGluZyBhbHRlcm5hdGUgc2VwYXJhdG9yIGNhc2VzKS5cclxuICovXHJcbmZ1bmN0aW9uIF9pc1Jvb3RlZChwKSB7XHJcbiAgICBwID0gX25vcm1hbGl6ZVNlcGFyYXRvcnMocCk7XHJcbiAgICBpZiAoIXApIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2lzUm9vdGVkKCkgcGFyYW1ldGVyIFwicFwiIGNhbm5vdCBiZSBlbXB0eScpO1xyXG4gICAgfVxyXG4gICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJykge1xyXG4gICAgICAgIHJldHVybiBfc3RhcnRzV2l0aChwLCAnXFxcXCcpIHx8IC8vIGUuZy4gXFwgb3IgXFxoZWxsbyBvciBcXFxcaGVsbG9cclxuICAgICAgICAgICAgL15bQS1aXTovaS50ZXN0KHApOyAvLyBlLmcuIEM6IG9yIEM6XFxoZWxsb1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIF9zdGFydHNXaXRoKHAsICcvJyk7IC8vIGUuZy4gL2hlbGxvXHJcbn1cclxuZXhwb3J0cy5faXNSb290ZWQgPSBfaXNSb290ZWQ7XHJcbmZ1bmN0aW9uIF9ub3JtYWxpemVTZXBhcmF0b3JzKHApIHtcclxuICAgIHAgPSBwIHx8ICcnO1xyXG4gICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJykge1xyXG4gICAgICAgIC8vIGNvbnZlcnQgc2xhc2hlcyBvbiBXaW5kb3dzXHJcbiAgICAgICAgcCA9IHAucmVwbGFjZSgvXFwvL2csICdcXFxcJyk7XHJcbiAgICAgICAgLy8gcmVtb3ZlIHJlZHVuZGFudCBzbGFzaGVzXHJcbiAgICAgICAgdmFyIGlzVW5jID0gL15cXFxcXFxcXCtbXlxcXFxdLy50ZXN0KHApOyAvLyBlLmcuIFxcXFxoZWxsb1xyXG4gICAgICAgIHJldHVybiAoaXNVbmMgPyAnXFxcXCcgOiAnJykgKyBwLnJlcGxhY2UoL1xcXFxcXFxcKy9nLCAnXFxcXCcpOyAvLyBwcmVzZXJ2ZSBsZWFkaW5nIC8vIGZvciBVTkNcclxuICAgIH1cclxuICAgIC8vIHJlbW92ZSByZWR1bmRhbnQgc2xhc2hlc1xyXG4gICAgcmV0dXJuIHAucmVwbGFjZSgvXFwvXFwvKy9nLCAnLycpO1xyXG59XHJcbmV4cG9ydHMuX25vcm1hbGl6ZVNlcGFyYXRvcnMgPSBfbm9ybWFsaXplU2VwYXJhdG9ycztcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBFeHBvc2UgcHJveHkgaW5mb3JtYXRpb24gdG8gdnN0cy1ub2RlLWFwaVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmZ1bmN0aW9uIF9leHBvc2VQcm94eVNldHRpbmdzKCkge1xyXG4gICAgdmFyIHByb3h5VXJsID0gX2dldFZhcmlhYmxlKCdBZ2VudC5Qcm94eVVybCcpO1xyXG4gICAgaWYgKHByb3h5VXJsICYmIHByb3h5VXJsLmxlbmd0aCA+IDApIHtcclxuICAgICAgICB2YXIgcHJveHlVc2VybmFtZSA9IF9nZXRWYXJpYWJsZSgnQWdlbnQuUHJveHlVc2VybmFtZScpO1xyXG4gICAgICAgIHZhciBwcm94eVBhc3N3b3JkID0gX2dldFZhcmlhYmxlKCdBZ2VudC5Qcm94eVBhc3N3b3JkJyk7XHJcbiAgICAgICAgdmFyIHByb3h5QnlwYXNzSG9zdHNKc29uID0gX2dldFZhcmlhYmxlKCdBZ2VudC5Qcm94eUJ5cGFzc0xpc3QnKTtcclxuICAgICAgICBnbG9iYWxbJ192c3RzX3Rhc2tfbGliX3Byb3h5X3VybCddID0gcHJveHlVcmw7XHJcbiAgICAgICAgZ2xvYmFsWydfdnN0c190YXNrX2xpYl9wcm94eV91c2VybmFtZSddID0gcHJveHlVc2VybmFtZTtcclxuICAgICAgICBnbG9iYWxbJ192c3RzX3Rhc2tfbGliX3Byb3h5X2J5cGFzcyddID0gcHJveHlCeXBhc3NIb3N0c0pzb247XHJcbiAgICAgICAgZ2xvYmFsWydfdnN0c190YXNrX2xpYl9wcm94eV9wYXNzd29yZCddID0gX2V4cG9zZVRhc2tMaWJTZWNyZXQoJ3Byb3h5JywgcHJveHlQYXNzd29yZCB8fCAnJyk7XHJcbiAgICAgICAgX2RlYnVnKCdleHBvc2UgYWdlbnQgcHJveHkgY29uZmlndXJhdGlvbi4nKTtcclxuICAgICAgICBnbG9iYWxbJ192c3RzX3Rhc2tfbGliX3Byb3h5J10gPSB0cnVlO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMuX2V4cG9zZVByb3h5U2V0dGluZ3MgPSBfZXhwb3NlUHJveHlTZXR0aW5ncztcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBFeHBvc2UgY2VydGlmaWNhdGUgaW5mb3JtYXRpb24gdG8gdnN0cy1ub2RlLWFwaVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmZ1bmN0aW9uIF9leHBvc2VDZXJ0U2V0dGluZ3MoKSB7XHJcbiAgICB2YXIgY2EgPSBfZ2V0VmFyaWFibGUoJ0FnZW50LkNBSW5mbycpO1xyXG4gICAgaWYgKGNhKSB7XHJcbiAgICAgICAgZ2xvYmFsWydfdnN0c190YXNrX2xpYl9jZXJ0X2NhJ10gPSBjYTtcclxuICAgIH1cclxuICAgIHZhciBjbGllbnRDZXJ0ID0gX2dldFZhcmlhYmxlKCdBZ2VudC5DbGllbnRDZXJ0Jyk7XHJcbiAgICBpZiAoY2xpZW50Q2VydCkge1xyXG4gICAgICAgIHZhciBjbGllbnRDZXJ0S2V5ID0gX2dldFZhcmlhYmxlKCdBZ2VudC5DbGllbnRDZXJ0S2V5Jyk7XHJcbiAgICAgICAgdmFyIGNsaWVudENlcnRBcmNoaXZlID0gX2dldFZhcmlhYmxlKCdBZ2VudC5DbGllbnRDZXJ0QXJjaGl2ZScpO1xyXG4gICAgICAgIHZhciBjbGllbnRDZXJ0UGFzc3dvcmQgPSBfZ2V0VmFyaWFibGUoJ0FnZW50LkNsaWVudENlcnRQYXNzd29yZCcpO1xyXG4gICAgICAgIGdsb2JhbFsnX3ZzdHNfdGFza19saWJfY2VydF9jbGllbnRjZXJ0J10gPSBjbGllbnRDZXJ0O1xyXG4gICAgICAgIGdsb2JhbFsnX3ZzdHNfdGFza19saWJfY2VydF9rZXknXSA9IGNsaWVudENlcnRLZXk7XHJcbiAgICAgICAgZ2xvYmFsWydfdnN0c190YXNrX2xpYl9jZXJ0X2FyY2hpdmUnXSA9IGNsaWVudENlcnRBcmNoaXZlO1xyXG4gICAgICAgIGdsb2JhbFsnX3ZzdHNfdGFza19saWJfY2VydF9wYXNzcGhyYXNlJ10gPSBfZXhwb3NlVGFza0xpYlNlY3JldCgnY2VydCcsIGNsaWVudENlcnRQYXNzd29yZCB8fCAnJyk7XHJcbiAgICB9XHJcbiAgICBpZiAoY2EgfHwgY2xpZW50Q2VydCkge1xyXG4gICAgICAgIF9kZWJ1ZygnZXhwb3NlIGFnZW50IGNlcnRpZmljYXRlIGNvbmZpZ3VyYXRpb24uJyk7XHJcbiAgICAgICAgZ2xvYmFsWydfdnN0c190YXNrX2xpYl9jZXJ0J10gPSB0cnVlO1xyXG4gICAgfVxyXG4gICAgdmFyIHNraXBDZXJ0VmFsaWRhdGlvbiA9IF9nZXRWYXJpYWJsZSgnQWdlbnQuU2tpcENlcnRWYWxpZGF0aW9uJykgfHwgJ2ZhbHNlJztcclxuICAgIGlmIChza2lwQ2VydFZhbGlkYXRpb24pIHtcclxuICAgICAgICBnbG9iYWxbJ192c3RzX3Rhc2tfbGliX3NraXBfY2VydF92YWxpZGF0aW9uJ10gPSBza2lwQ2VydFZhbGlkYXRpb24udG9VcHBlckNhc2UoKSA9PT0gJ1RSVUUnO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMuX2V4cG9zZUNlcnRTZXR0aW5ncyA9IF9leHBvc2VDZXJ0U2V0dGluZ3M7XHJcbi8vIFdlIHN0b3JlIHRoZSBlbmNyeXB0aW9uIGtleSBvbiBkaXNrIGFuZCBob2xkIHRoZSBlbmNyeXB0ZWQgY29udGVudCBhbmQga2V5IGZpbGUgaW4gbWVtb3J5XHJcbi8vIHJldHVybiBiYXNlNjRlbmNvZGVkPGtleUZpbGVQYXRoPjpiYXNlNjRlbmNvZGVkPGVuY3J5cHRlZENvbnRlbnQ+XHJcbi8vIGRvd25zdHJlYW0gdnN0cy1ub2RlLWFwaSB3aWxsIHJldHJpZXZlIHRoZSBzZWNyZXQgbGF0ZXJcclxuZnVuY3Rpb24gX2V4cG9zZVRhc2tMaWJTZWNyZXQoa2V5RmlsZSwgc2VjcmV0KSB7XHJcbiAgICBpZiAoc2VjcmV0KSB7XHJcbiAgICAgICAgdmFyIGVuY3J5cHRLZXkgPSBjcnlwdG8ucmFuZG9tQnl0ZXMoMjU2KTtcclxuICAgICAgICB2YXIgY2lwaGVyID0gY3J5cHRvLmNyZWF0ZUNpcGhlcihcImFlcy0yNTYtY3RyXCIsIGVuY3J5cHRLZXkpO1xyXG4gICAgICAgIHZhciBlbmNyeXB0ZWRDb250ZW50ID0gY2lwaGVyLnVwZGF0ZShzZWNyZXQsIFwidXRmOFwiLCBcImhleFwiKTtcclxuICAgICAgICBlbmNyeXB0ZWRDb250ZW50ICs9IGNpcGhlci5maW5hbChcImhleFwiKTtcclxuICAgICAgICB2YXIgc3RvcmFnZUZpbGUgPSBwYXRoLmpvaW4oX2dldFZhcmlhYmxlKCdBZ2VudC5UZW1wRGlyZWN0b3J5JykgfHwgX2dldFZhcmlhYmxlKFwiYWdlbnQud29ya0ZvbGRlclwiKSB8fCBwcm9jZXNzLmN3ZCgpLCBrZXlGaWxlKTtcclxuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKHN0b3JhZ2VGaWxlLCBlbmNyeXB0S2V5LnRvU3RyaW5nKCdiYXNlNjQnKSwgeyBlbmNvZGluZzogJ3V0ZjgnIH0pO1xyXG4gICAgICAgIHJldHVybiBuZXcgQnVmZmVyKHN0b3JhZ2VGaWxlKS50b1N0cmluZygnYmFzZTY0JykgKyAnOicgKyBuZXcgQnVmZmVyKGVuY3J5cHRlZENvbnRlbnQpLnRvU3RyaW5nKCdiYXNlNjQnKTtcclxuICAgIH1cclxufVxyXG4iLCIvKipcbiAqIENvbnZlcnQgYXJyYXkgb2YgMTYgYnl0ZSB2YWx1ZXMgdG8gVVVJRCBzdHJpbmcgZm9ybWF0IG9mIHRoZSBmb3JtOlxuICogWFhYWFhYWFgtWFhYWC1YWFhYLVhYWFgtWFhYWFhYWFhYWFhYXG4gKi9cbnZhciBieXRlVG9IZXggPSBbXTtcbmZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyArK2kpIHtcbiAgYnl0ZVRvSGV4W2ldID0gKGkgKyAweDEwMCkudG9TdHJpbmcoMTYpLnN1YnN0cigxKTtcbn1cblxuZnVuY3Rpb24gYnl0ZXNUb1V1aWQoYnVmLCBvZmZzZXQpIHtcbiAgdmFyIGkgPSBvZmZzZXQgfHwgMDtcbiAgdmFyIGJ0aCA9IGJ5dGVUb0hleDtcbiAgLy8gam9pbiB1c2VkIHRvIGZpeCBtZW1vcnkgaXNzdWUgY2F1c2VkIGJ5IGNvbmNhdGVuYXRpb246IGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTMxNzUjYzRcbiAgcmV0dXJuIChbXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSxcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSxcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV1cbiAgXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gbm9kZS5qc1xuLy8gdGhpcyBpcyBwcmV0dHkgc3RyYWlnaHQtZm9yd2FyZCAtIHdlIHVzZSB0aGUgY3J5cHRvIEFQSS5cblxudmFyIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIG5vZGVSTkcoKSB7XG4gIHJldHVybiBjcnlwdG8ucmFuZG9tQnl0ZXMoMTYpO1xufTtcbiIsInZhciBybmcgPSByZXF1aXJlKCcuL2xpYi9ybmcnKTtcbnZhciBieXRlc1RvVXVpZCA9IHJlcXVpcmUoJy4vbGliL2J5dGVzVG9VdWlkJyk7XG5cbmZ1bmN0aW9uIHY0KG9wdGlvbnMsIGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gYnVmICYmIG9mZnNldCB8fCAwO1xuXG4gIGlmICh0eXBlb2Yob3B0aW9ucykgPT0gJ3N0cmluZycpIHtcbiAgICBidWYgPSBvcHRpb25zID09PSAnYmluYXJ5JyA/IG5ldyBBcnJheSgxNikgOiBudWxsO1xuICAgIG9wdGlvbnMgPSBudWxsO1xuICB9XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIHZhciBybmRzID0gb3B0aW9ucy5yYW5kb20gfHwgKG9wdGlvbnMucm5nIHx8IHJuZykoKTtcblxuICAvLyBQZXIgNC40LCBzZXQgYml0cyBmb3IgdmVyc2lvbiBhbmQgYGNsb2NrX3NlcV9oaV9hbmRfcmVzZXJ2ZWRgXG4gIHJuZHNbNl0gPSAocm5kc1s2XSAmIDB4MGYpIHwgMHg0MDtcbiAgcm5kc1s4XSA9IChybmRzWzhdICYgMHgzZikgfCAweDgwO1xuXG4gIC8vIENvcHkgYnl0ZXMgdG8gYnVmZmVyLCBpZiBwcm92aWRlZFxuICBpZiAoYnVmKSB7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IDE2OyArK2lpKSB7XG4gICAgICBidWZbaSArIGlpXSA9IHJuZHNbaWldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBidWYgfHwgYnl0ZXNUb1V1aWQocm5kcyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjQ7XG4iLCJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgc2hlbGwgPSByZXF1aXJlKFwic2hlbGxqc1wiKTtcclxudmFyIGNoaWxkUHJvY2VzcyA9IHJlcXVpcmUoXCJjaGlsZF9wcm9jZXNzXCIpO1xyXG52YXIgZnMgPSByZXF1aXJlKFwiZnNcIik7XHJcbnZhciBwYXRoID0gcmVxdWlyZShcInBhdGhcIik7XHJcbnZhciBvcyA9IHJlcXVpcmUoXCJvc1wiKTtcclxudmFyIG1pbmltYXRjaCA9IHJlcXVpcmUoXCJtaW5pbWF0Y2hcIik7XHJcbnZhciBpbSA9IHJlcXVpcmUoXCIuL2ludGVybmFsXCIpO1xyXG52YXIgdGNtID0gcmVxdWlyZShcIi4vdGFza2NvbW1hbmRcIik7XHJcbnZhciB0cm0gPSByZXF1aXJlKFwiLi90b29scnVubmVyXCIpO1xyXG52YXIgc2VtdmVyID0gcmVxdWlyZShcInNlbXZlclwiKTtcclxudmFyIFRhc2tSZXN1bHQ7XHJcbihmdW5jdGlvbiAoVGFza1Jlc3VsdCkge1xyXG4gICAgVGFza1Jlc3VsdFtUYXNrUmVzdWx0W1wiU3VjY2VlZGVkXCJdID0gMF0gPSBcIlN1Y2NlZWRlZFwiO1xyXG4gICAgVGFza1Jlc3VsdFtUYXNrUmVzdWx0W1wiU3VjY2VlZGVkV2l0aElzc3Vlc1wiXSA9IDFdID0gXCJTdWNjZWVkZWRXaXRoSXNzdWVzXCI7XHJcbiAgICBUYXNrUmVzdWx0W1Rhc2tSZXN1bHRbXCJGYWlsZWRcIl0gPSAyXSA9IFwiRmFpbGVkXCI7XHJcbiAgICBUYXNrUmVzdWx0W1Rhc2tSZXN1bHRbXCJDYW5jZWxsZWRcIl0gPSAzXSA9IFwiQ2FuY2VsbGVkXCI7XHJcbiAgICBUYXNrUmVzdWx0W1Rhc2tSZXN1bHRbXCJTa2lwcGVkXCJdID0gNF0gPSBcIlNraXBwZWRcIjtcclxufSkoVGFza1Jlc3VsdCA9IGV4cG9ydHMuVGFza1Jlc3VsdCB8fCAoZXhwb3J0cy5UYXNrUmVzdWx0ID0ge30pKTtcclxudmFyIFRhc2tTdGF0ZTtcclxuKGZ1bmN0aW9uIChUYXNrU3RhdGUpIHtcclxuICAgIFRhc2tTdGF0ZVtUYXNrU3RhdGVbXCJVbmtub3duXCJdID0gMF0gPSBcIlVua25vd25cIjtcclxuICAgIFRhc2tTdGF0ZVtUYXNrU3RhdGVbXCJJbml0aWFsaXplZFwiXSA9IDFdID0gXCJJbml0aWFsaXplZFwiO1xyXG4gICAgVGFza1N0YXRlW1Rhc2tTdGF0ZVtcIkluUHJvZ3Jlc3NcIl0gPSAyXSA9IFwiSW5Qcm9ncmVzc1wiO1xyXG4gICAgVGFza1N0YXRlW1Rhc2tTdGF0ZVtcIkNvbXBsZXRlZFwiXSA9IDNdID0gXCJDb21wbGV0ZWRcIjtcclxufSkoVGFza1N0YXRlID0gZXhwb3J0cy5UYXNrU3RhdGUgfHwgKGV4cG9ydHMuVGFza1N0YXRlID0ge30pKTtcclxudmFyIElzc3VlVHlwZTtcclxuKGZ1bmN0aW9uIChJc3N1ZVR5cGUpIHtcclxuICAgIElzc3VlVHlwZVtJc3N1ZVR5cGVbXCJFcnJvclwiXSA9IDBdID0gXCJFcnJvclwiO1xyXG4gICAgSXNzdWVUeXBlW0lzc3VlVHlwZVtcIldhcm5pbmdcIl0gPSAxXSA9IFwiV2FybmluZ1wiO1xyXG59KShJc3N1ZVR5cGUgPSBleHBvcnRzLklzc3VlVHlwZSB8fCAoZXhwb3J0cy5Jc3N1ZVR5cGUgPSB7fSkpO1xyXG52YXIgQXJ0aWZhY3RUeXBlO1xyXG4oZnVuY3Rpb24gKEFydGlmYWN0VHlwZSkge1xyXG4gICAgQXJ0aWZhY3RUeXBlW0FydGlmYWN0VHlwZVtcIkNvbnRhaW5lclwiXSA9IDBdID0gXCJDb250YWluZXJcIjtcclxuICAgIEFydGlmYWN0VHlwZVtBcnRpZmFjdFR5cGVbXCJGaWxlUGF0aFwiXSA9IDFdID0gXCJGaWxlUGF0aFwiO1xyXG4gICAgQXJ0aWZhY3RUeXBlW0FydGlmYWN0VHlwZVtcIlZlcnNpb25Db250cm9sXCJdID0gMl0gPSBcIlZlcnNpb25Db250cm9sXCI7XHJcbiAgICBBcnRpZmFjdFR5cGVbQXJ0aWZhY3RUeXBlW1wiR2l0UmVmXCJdID0gM10gPSBcIkdpdFJlZlwiO1xyXG4gICAgQXJ0aWZhY3RUeXBlW0FydGlmYWN0VHlwZVtcIlRmdmNMYWJlbFwiXSA9IDRdID0gXCJUZnZjTGFiZWxcIjtcclxufSkoQXJ0aWZhY3RUeXBlID0gZXhwb3J0cy5BcnRpZmFjdFR5cGUgfHwgKGV4cG9ydHMuQXJ0aWZhY3RUeXBlID0ge30pKTtcclxudmFyIEZpZWxkVHlwZTtcclxuKGZ1bmN0aW9uIChGaWVsZFR5cGUpIHtcclxuICAgIEZpZWxkVHlwZVtGaWVsZFR5cGVbXCJBdXRoUGFyYW1ldGVyXCJdID0gMF0gPSBcIkF1dGhQYXJhbWV0ZXJcIjtcclxuICAgIEZpZWxkVHlwZVtGaWVsZFR5cGVbXCJEYXRhUGFyYW1ldGVyXCJdID0gMV0gPSBcIkRhdGFQYXJhbWV0ZXJcIjtcclxuICAgIEZpZWxkVHlwZVtGaWVsZFR5cGVbXCJVcmxcIl0gPSAyXSA9IFwiVXJsXCI7XHJcbn0pKEZpZWxkVHlwZSA9IGV4cG9ydHMuRmllbGRUeXBlIHx8IChleHBvcnRzLkZpZWxkVHlwZSA9IHt9KSk7XHJcbi8qKiBQbGF0Zm9ybXMgc3VwcG9ydGVkIGJ5IG91ciBidWlsZCBhZ2VudCAqL1xyXG52YXIgUGxhdGZvcm07XHJcbihmdW5jdGlvbiAoUGxhdGZvcm0pIHtcclxuICAgIFBsYXRmb3JtW1BsYXRmb3JtW1wiV2luZG93c1wiXSA9IDBdID0gXCJXaW5kb3dzXCI7XHJcbiAgICBQbGF0Zm9ybVtQbGF0Zm9ybVtcIk1hY09TXCJdID0gMV0gPSBcIk1hY09TXCI7XHJcbiAgICBQbGF0Zm9ybVtQbGF0Zm9ybVtcIkxpbnV4XCJdID0gMl0gPSBcIkxpbnV4XCI7XHJcbn0pKFBsYXRmb3JtID0gZXhwb3J0cy5QbGF0Zm9ybSB8fCAoZXhwb3J0cy5QbGF0Zm9ybSA9IHt9KSk7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gR2VuZXJhbCBIZWxwZXJzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZXhwb3J0cy5zZXRTdGRTdHJlYW0gPSBpbS5fc2V0U3RkU3RyZWFtO1xyXG5leHBvcnRzLnNldEVyclN0cmVhbSA9IGltLl9zZXRFcnJTdHJlYW07XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gUmVzdWx0c1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qKlxyXG4gKiBTZXRzIHRoZSByZXN1bHQgb2YgdGhlIHRhc2suXHJcbiAqIEV4ZWN1dGlvbiB3aWxsIGNvbnRpbnVlLlxyXG4gKiBJZiBub3Qgc2V0LCB0YXNrIHdpbGwgYmUgU3VjY2VlZGVkLlxyXG4gKiBJZiBtdWx0aXBsZSBjYWxscyBhcmUgbWFkZSB0byBzZXRSZXN1bHQgdGhlIG1vc3QgcGVzc2ltaXN0aWMgY2FsbCB3aW5zIChGYWlsZWQpIHJlZ2FyZGxlc3Mgb2YgdGhlIG9yZGVyIG9mIGNhbGxzLlxyXG4gKlxyXG4gKiBAcGFyYW0gcmVzdWx0ICAgIFRhc2tSZXN1bHQgZW51bSBvZiBTdWNjZWVkZWQsIFN1Y2NlZWRlZFdpdGhJc3N1ZXMsIEZhaWxlZCwgQ2FuY2VsbGVkIG9yIFNraXBwZWQuXHJcbiAqIEBwYXJhbSBtZXNzYWdlICAgQSBtZXNzYWdlIHdoaWNoIHdpbGwgYmUgbG9nZ2VkIGFzIGFuIGVycm9yIGlzc3VlIGlmIHRoZSByZXN1bHQgaXMgRmFpbGVkLlxyXG4gKiBAcGFyYW0gZG9uZSAgICAgIE9wdGlvbmFsLiBJbnN0cnVjdHMgdGhlIGFnZW50IHRoZSB0YXNrIGlzIGRvbmUuIFRoaXMgaXMgaGVscGZ1bCB3aGVuIGNoaWxkIHByb2Nlc3Nlc1xyXG4gKiAgICAgICAgICAgICAgICAgIG1heSBzdGlsbCBiZSBydW5uaW5nIGFuZCBwcmV2ZW50IG5vZGUgZnJvbSBmdWxseSBleGl0aW5nLiBUaGlzIGFyZ3VtZW50IGlzIHN1cHBvcnRlZFxyXG4gKiAgICAgICAgICAgICAgICAgIGZyb20gYWdlbnQgdmVyc2lvbiAyLjE0Mi4wIG9yIGhpZ2hlciAob3RoZXJ3aXNlIHdpbGwgbm8tb3ApLlxyXG4gKiBAcmV0dXJucyAgICAgICAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHNldFJlc3VsdChyZXN1bHQsIG1lc3NhZ2UsIGRvbmUpIHtcclxuICAgIGV4cG9ydHMuZGVidWcoJ3Rhc2sgcmVzdWx0OiAnICsgVGFza1Jlc3VsdFtyZXN1bHRdKTtcclxuICAgIC8vIGFkZCBhbiBlcnJvciBpc3N1ZVxyXG4gICAgaWYgKHJlc3VsdCA9PSBUYXNrUmVzdWx0LkZhaWxlZCAmJiBtZXNzYWdlKSB7XHJcbiAgICAgICAgZXhwb3J0cy5lcnJvcihtZXNzYWdlKTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHJlc3VsdCA9PSBUYXNrUmVzdWx0LlN1Y2NlZWRlZFdpdGhJc3N1ZXMgJiYgbWVzc2FnZSkge1xyXG4gICAgICAgIGV4cG9ydHMud2FybmluZyhtZXNzYWdlKTtcclxuICAgIH1cclxuICAgIC8vIHRhc2suY29tcGxldGVcclxuICAgIHZhciBwcm9wZXJ0aWVzID0geyAncmVzdWx0JzogVGFza1Jlc3VsdFtyZXN1bHRdIH07XHJcbiAgICBpZiAoZG9uZSkge1xyXG4gICAgICAgIHByb3BlcnRpZXNbJ2RvbmUnXSA9ICd0cnVlJztcclxuICAgIH1cclxuICAgIGV4cG9ydHMuY29tbWFuZCgndGFzay5jb21wbGV0ZScsIHByb3BlcnRpZXMsIG1lc3NhZ2UpO1xyXG59XHJcbmV4cG9ydHMuc2V0UmVzdWx0ID0gc2V0UmVzdWx0O1xyXG4vL1xyXG4vLyBDYXRjaGluZyBhbGwgZXhjZXB0aW9uc1xyXG4vL1xyXG5wcm9jZXNzLm9uKCd1bmNhdWdodEV4Y2VwdGlvbicsIGZ1bmN0aW9uIChlcnIpIHtcclxuICAgIHNldFJlc3VsdChUYXNrUmVzdWx0LkZhaWxlZCwgZXhwb3J0cy5sb2MoJ0xJQl9VbmhhbmRsZWRFeCcsIGVyci5tZXNzYWdlKSk7XHJcbn0pO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIExvYyBIZWxwZXJzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZXhwb3J0cy5zZXRSZXNvdXJjZVBhdGggPSBpbS5fc2V0UmVzb3VyY2VQYXRoO1xyXG5leHBvcnRzLmxvYyA9IGltLl9sb2M7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gSW5wdXQgSGVscGVyc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmV4cG9ydHMuZ2V0VmFyaWFibGUgPSBpbS5fZ2V0VmFyaWFibGU7XHJcbi8qKlxyXG4gKiBBc3NlcnRzIHRoZSBhZ2VudCB2ZXJzaW9uIGlzIGF0IGxlYXN0IHRoZSBzcGVjaWZpZWQgbWluaW11bS5cclxuICpcclxuICogQHBhcmFtICAgIG1pbmltdW0gICAgbWluaW11bSB2ZXJzaW9uIHZlcnNpb24gLSBtdXN0IGJlIDIuMTA0LjEgb3IgaGlnaGVyXHJcbiAqL1xyXG5mdW5jdGlvbiBhc3NlcnRBZ2VudChtaW5pbXVtKSB7XHJcbiAgICBpZiAoc2VtdmVyLmx0KG1pbmltdW0sICcyLjEwNC4xJykpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Fzc2VydEFnZW50KCkgcmVxdWlyZXMgdGhlIHBhcmFtZXRlciB0byBiZSAyLjEwNC4xIG9yIGhpZ2hlcicpO1xyXG4gICAgfVxyXG4gICAgdmFyIGFnZW50ID0gZXhwb3J0cy5nZXRWYXJpYWJsZSgnQWdlbnQuVmVyc2lvbicpO1xyXG4gICAgaWYgKGFnZW50ICYmIHNlbXZlci5sdChhZ2VudCwgbWluaW11bSkpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBZ2VudCB2ZXJzaW9uIFwiICsgbWluaW11bSArIFwiIG9yIGhpZ2hlciBpcyByZXF1aXJlZFwiKTtcclxuICAgIH1cclxufVxyXG5leHBvcnRzLmFzc2VydEFnZW50ID0gYXNzZXJ0QWdlbnQ7XHJcbi8qKlxyXG4gKiBHZXRzIGEgc25hcHNob3Qgb2YgdGhlIGN1cnJlbnQgc3RhdGUgb2YgYWxsIGpvYiB2YXJpYWJsZXMgYXZhaWxhYmxlIHRvIHRoZSB0YXNrLlxyXG4gKiBSZXF1aXJlcyBhIDIuMTA0LjEgYWdlbnQgb3IgaGlnaGVyIGZvciBmdWxsIGZ1bmN0aW9uYWxpdHkuXHJcbiAqXHJcbiAqIExpbWl0YXRpb25zIG9uIGFuIGFnZW50IHByaW9yIHRvIDIuMTA0LjE6XHJcbiAqICAxKSBUaGUgcmV0dXJuIHZhbHVlIGRvZXMgbm90IGluY2x1ZGUgYWxsIHB1YmxpYyB2YXJpYWJsZXMuIE9ubHkgcHVibGljIHZhcmlhYmxlc1xyXG4gKiAgICAgdGhhdCBoYXZlIGJlZW4gYWRkZWQgdXNpbmcgc2V0VmFyaWFibGUgYXJlIHJldHVybmVkLlxyXG4gKiAgMikgVGhlIG5hbWUgcmV0dXJuZWQgZm9yIGVhY2ggc2VjcmV0IHZhcmlhYmxlIGlzIHRoZSBmb3JtYXR0ZWQgZW52aXJvbm1lbnQgdmFyaWFibGVcclxuICogICAgIG5hbWUsIG5vdCB0aGUgYWN0dWFsIHZhcmlhYmxlIG5hbWUgKHVubGVzcyBpdCB3YXMgc2V0IGV4cGxpY2l0bHkgYXQgcnVudGltZSB1c2luZ1xyXG4gKiAgICAgc2V0VmFyaWFibGUpLlxyXG4gKlxyXG4gKiBAcmV0dXJucyBWYXJpYWJsZUluZm9bXVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0VmFyaWFibGVzKCkge1xyXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGltLl9rbm93blZhcmlhYmxlTWFwKVxyXG4gICAgICAgIC5tYXAoZnVuY3Rpb24gKGtleSkge1xyXG4gICAgICAgIHZhciBpbmZvID0gaW0uX2tub3duVmFyaWFibGVNYXBba2V5XTtcclxuICAgICAgICByZXR1cm4geyBuYW1lOiBpbmZvLm5hbWUsIHZhbHVlOiBleHBvcnRzLmdldFZhcmlhYmxlKGluZm8ubmFtZSksIHNlY3JldDogaW5mby5zZWNyZXQgfTtcclxuICAgIH0pO1xyXG59XHJcbmV4cG9ydHMuZ2V0VmFyaWFibGVzID0gZ2V0VmFyaWFibGVzO1xyXG4vKipcclxuICogU2V0cyBhIHZhcmlhYmxlIHdoaWNoIHdpbGwgYmUgYXZhaWxhYmxlIHRvIHN1YnNlcXVlbnQgdGFza3MgYXMgd2VsbC5cclxuICpcclxuICogQHBhcmFtICAgICBuYW1lICAgICBuYW1lIG9mIHRoZSB2YXJpYWJsZSB0byBzZXRcclxuICogQHBhcmFtICAgICB2YWwgICAgICB2YWx1ZSB0byBzZXRcclxuICogQHBhcmFtICAgICBzZWNyZXQgICB3aGV0aGVyIHZhcmlhYmxlIGlzIHNlY3JldC4gIE11bHRpLWxpbmUgc2VjcmV0cyBhcmUgbm90IGFsbG93ZWQuICBPcHRpb25hbCwgZGVmYXVsdHMgdG8gZmFsc2VcclxuICogQHBhcmFtICAgICBpc091dHB1dCB3aGV0aGVyIHZhcmlhYmxlIGlzIGFuIG91dHB1dCB2YXJpYWJsZS4gIE9wdGlvbmFsLCBkZWZhdWx0cyB0byBmYWxzZVxyXG4gKiBAcmV0dXJucyAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHNldFZhcmlhYmxlKG5hbWUsIHZhbCwgc2VjcmV0LCBpc091dHB1dCkge1xyXG4gICAgaWYgKHNlY3JldCA9PT0gdm9pZCAwKSB7IHNlY3JldCA9IGZhbHNlOyB9XHJcbiAgICBpZiAoaXNPdXRwdXQgPT09IHZvaWQgMCkgeyBpc091dHB1dCA9IGZhbHNlOyB9XHJcbiAgICAvLyBvbmNlIGEgc2VjcmV0IGFsd2F5cyBhIHNlY3JldFxyXG4gICAgdmFyIGtleSA9IGltLl9nZXRWYXJpYWJsZUtleShuYW1lKTtcclxuICAgIGlmIChpbS5fa25vd25WYXJpYWJsZU1hcC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XHJcbiAgICAgICAgc2VjcmV0ID0gc2VjcmV0IHx8IGltLl9rbm93blZhcmlhYmxlTWFwW2tleV0uc2VjcmV0O1xyXG4gICAgfVxyXG4gICAgLy8gc3RvcmUgdGhlIHZhbHVlXHJcbiAgICB2YXIgdmFyVmFsdWUgPSB2YWwgfHwgJyc7XHJcbiAgICBleHBvcnRzLmRlYnVnKCdzZXQgJyArIG5hbWUgKyAnPScgKyAoc2VjcmV0ICYmIHZhclZhbHVlID8gJyoqKioqKioqJyA6IHZhclZhbHVlKSk7XHJcbiAgICBpZiAoc2VjcmV0KSB7XHJcbiAgICAgICAgaWYgKHZhclZhbHVlICYmIHZhclZhbHVlLm1hdGNoKC9cXHJ8XFxuLykgJiYgKFwiXCIgKyBwcm9jZXNzLmVudlsnU1lTVEVNX1VOU0FGRUFMTE9XTVVMVElMSU5FU0VDUkVUJ10pLnRvVXBwZXJDYXNlKCkgIT0gJ1RSVUUnKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmxvYygnTElCX011bHRpbGluZVNlY3JldCcpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaW0uX3ZhdWx0LnN0b3JlU2VjcmV0KCdTRUNSRVRfJyArIGtleSwgdmFyVmFsdWUpO1xyXG4gICAgICAgIGRlbGV0ZSBwcm9jZXNzLmVudltrZXldO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgcHJvY2Vzcy5lbnZba2V5XSA9IHZhclZhbHVlO1xyXG4gICAgfVxyXG4gICAgLy8gc3RvcmUgdGhlIG1ldGFkYXRhXHJcbiAgICBpbS5fa25vd25WYXJpYWJsZU1hcFtrZXldID0geyBuYW1lOiBuYW1lLCBzZWNyZXQ6IHNlY3JldCB9O1xyXG4gICAgLy8gd3JpdGUgdGhlIHNldHZhcmlhYmxlIGNvbW1hbmRcclxuICAgIGV4cG9ydHMuY29tbWFuZCgndGFzay5zZXR2YXJpYWJsZScsIHsgJ3ZhcmlhYmxlJzogbmFtZSB8fCAnJywgaXNPdXRwdXQ6IChpc091dHB1dCB8fCBmYWxzZSkudG9TdHJpbmcoKSwgJ2lzc2VjcmV0JzogKHNlY3JldCB8fCBmYWxzZSkudG9TdHJpbmcoKSB9LCB2YXJWYWx1ZSk7XHJcbn1cclxuZXhwb3J0cy5zZXRWYXJpYWJsZSA9IHNldFZhcmlhYmxlO1xyXG4vKipcclxuICogUmVnaXN0ZXJzIGEgdmFsdWUgd2l0aCB0aGUgbG9nZ2VyLCBzbyB0aGUgdmFsdWUgd2lsbCBiZSBtYXNrZWQgZnJvbSB0aGUgbG9ncy4gIE11bHRpLWxpbmUgc2VjcmV0cyBhcmUgbm90IGFsbG93ZWQuXHJcbiAqXHJcbiAqIEBwYXJhbSB2YWwgdmFsdWUgdG8gcmVnaXN0ZXJcclxuICovXHJcbmZ1bmN0aW9uIHNldFNlY3JldCh2YWwpIHtcclxuICAgIGlmICh2YWwpIHtcclxuICAgICAgICBpZiAodmFsLm1hdGNoKC9cXHJ8XFxuLykgJiYgKFwiXCIgKyBwcm9jZXNzLmVudlsnU1lTVEVNX1VOU0FGRUFMTE9XTVVMVElMSU5FU0VDUkVUJ10pLnRvVXBwZXJDYXNlKCkgIT09ICdUUlVFJykge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9NdWx0aWxpbmVTZWNyZXQnKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGV4cG9ydHMuY29tbWFuZCgndGFzay5zZXRzZWNyZXQnLCB7fSwgdmFsKTtcclxuICAgIH1cclxufVxyXG5leHBvcnRzLnNldFNlY3JldCA9IHNldFNlY3JldDtcclxuLyoqXHJcbiAqIEdldHMgdGhlIHZhbHVlIG9mIGFuIGlucHV0LlxyXG4gKiBJZiByZXF1aXJlZCBpcyB0cnVlIGFuZCB0aGUgdmFsdWUgaXMgbm90IHNldCwgaXQgd2lsbCB0aHJvdy5cclxuICpcclxuICogQHBhcmFtICAgICBuYW1lICAgICBuYW1lIG9mIHRoZSBpbnB1dCB0byBnZXRcclxuICogQHBhcmFtICAgICByZXF1aXJlZCB3aGV0aGVyIGlucHV0IGlzIHJlcXVpcmVkLiAgb3B0aW9uYWwsIGRlZmF1bHRzIHRvIGZhbHNlXHJcbiAqIEByZXR1cm5zICAgc3RyaW5nXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRJbnB1dChuYW1lLCByZXF1aXJlZCkge1xyXG4gICAgdmFyIGludmFsID0gaW0uX3ZhdWx0LnJldHJpZXZlU2VjcmV0KCdJTlBVVF8nICsgaW0uX2dldFZhcmlhYmxlS2V5KG5hbWUpKTtcclxuICAgIGlmIChyZXF1aXJlZCAmJiAhaW52YWwpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9JbnB1dFJlcXVpcmVkJywgbmFtZSkpO1xyXG4gICAgfVxyXG4gICAgZXhwb3J0cy5kZWJ1ZyhuYW1lICsgJz0nICsgaW52YWwpO1xyXG4gICAgcmV0dXJuIGludmFsO1xyXG59XHJcbmV4cG9ydHMuZ2V0SW5wdXQgPSBnZXRJbnB1dDtcclxuLyoqXHJcbiAqIEdldHMgdGhlIHZhbHVlIG9mIGFuIGlucHV0IGFuZCBjb252ZXJ0cyB0byBhIGJvb2wuICBDb252ZW5pZW5jZS5cclxuICogSWYgcmVxdWlyZWQgaXMgdHJ1ZSBhbmQgdGhlIHZhbHVlIGlzIG5vdCBzZXQsIGl0IHdpbGwgdGhyb3cuXHJcbiAqIElmIHJlcXVpcmVkIGlzIGZhbHNlIGFuZCB0aGUgdmFsdWUgaXMgbm90IHNldCwgcmV0dXJucyBmYWxzZS5cclxuICpcclxuICogQHBhcmFtICAgICBuYW1lICAgICBuYW1lIG9mIHRoZSBib29sIGlucHV0IHRvIGdldFxyXG4gKiBAcGFyYW0gICAgIHJlcXVpcmVkIHdoZXRoZXIgaW5wdXQgaXMgcmVxdWlyZWQuICBvcHRpb25hbCwgZGVmYXVsdHMgdG8gZmFsc2VcclxuICogQHJldHVybnMgICBib29sZWFuXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRCb29sSW5wdXQobmFtZSwgcmVxdWlyZWQpIHtcclxuICAgIHJldHVybiAoZ2V0SW5wdXQobmFtZSwgcmVxdWlyZWQpIHx8ICcnKS50b1VwcGVyQ2FzZSgpID09IFwiVFJVRVwiO1xyXG59XHJcbmV4cG9ydHMuZ2V0Qm9vbElucHV0ID0gZ2V0Qm9vbElucHV0O1xyXG4vKipcclxuICogR2V0cyB0aGUgdmFsdWUgb2YgYW4gaW5wdXQgYW5kIHNwbGl0cyB0aGUgdmFsdWUgdXNpbmcgYSBkZWxpbWl0ZXIgKHNwYWNlLCBjb21tYSwgZXRjKS5cclxuICogRW1wdHkgdmFsdWVzIGFyZSByZW1vdmVkLiAgVGhpcyBmdW5jdGlvbiBpcyB1c2VmdWwgZm9yIHNwbGl0dGluZyBhbiBpbnB1dCBjb250YWluaW5nIGEgc2ltcGxlXHJcbiAqIGxpc3Qgb2YgaXRlbXMgLSBzdWNoIGFzIGJ1aWxkIHRhcmdldHMuXHJcbiAqIElNUE9SVEFOVDogRG8gbm90IHVzZSB0aGlzIGZ1bmN0aW9uIGZvciBzcGxpdHRpbmcgYWRkaXRpb25hbCBhcmdzISAgSW5zdGVhZCB1c2UgYXJnU3RyaW5nKCksIHdoaWNoXHJcbiAqIGZvbGxvd3Mgbm9ybWFsIGFyZ3VtZW50IHNwbGl0dGluZyBydWxlcyBhbmQgaGFuZGxlcyB2YWx1ZXMgZW5jYXBzdWxhdGVkIGJ5IHF1b3Rlcy5cclxuICogSWYgcmVxdWlyZWQgaXMgdHJ1ZSBhbmQgdGhlIHZhbHVlIGlzIG5vdCBzZXQsIGl0IHdpbGwgdGhyb3cuXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgbmFtZSAgICAgbmFtZSBvZiB0aGUgaW5wdXQgdG8gZ2V0XHJcbiAqIEBwYXJhbSAgICAgZGVsaW0gICAgZGVsaW1pdGVyIHRvIHNwbGl0IG9uXHJcbiAqIEBwYXJhbSAgICAgcmVxdWlyZWQgd2hldGhlciBpbnB1dCBpcyByZXF1aXJlZC4gIG9wdGlvbmFsLCBkZWZhdWx0cyB0byBmYWxzZVxyXG4gKiBAcmV0dXJucyAgIHN0cmluZ1tdXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXREZWxpbWl0ZWRJbnB1dChuYW1lLCBkZWxpbSwgcmVxdWlyZWQpIHtcclxuICAgIHZhciBpbnB1dFZhbCA9IGdldElucHV0KG5hbWUsIHJlcXVpcmVkKTtcclxuICAgIGlmICghaW5wdXRWYWwpIHtcclxuICAgICAgICByZXR1cm4gW107XHJcbiAgICB9XHJcbiAgICB2YXIgcmVzdWx0ID0gW107XHJcbiAgICBpbnB1dFZhbC5zcGxpdChkZWxpbSkuZm9yRWFjaChmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgIGlmICh4KSB7XHJcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHgpO1xyXG4gICAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5leHBvcnRzLmdldERlbGltaXRlZElucHV0ID0gZ2V0RGVsaW1pdGVkSW5wdXQ7XHJcbi8qKlxyXG4gKiBDaGVja3Mgd2hldGhlciBhIHBhdGggaW5wdXRzIHZhbHVlIHdhcyBzdXBwbGllZCBieSB0aGUgdXNlclxyXG4gKiBGaWxlIHBhdGhzIGFyZSByZWxhdGl2ZSB3aXRoIGEgcGlja2VyLCBzbyBhbiBlbXB0eSBwYXRoIGlzIHRoZSByb290IG9mIHRoZSByZXBvLlxyXG4gKiBVc2VmdWwgaWYgeW91IG5lZWQgdG8gY29uZGl0aW9uIHdvcmsgKGxpa2UgYXBwZW5kIGFuIGFyZykgaWYgYSB2YWx1ZSB3YXMgc3VwcGxpZWRcclxuICpcclxuICogQHBhcmFtICAgICBuYW1lICAgICAgbmFtZSBvZiB0aGUgcGF0aCBpbnB1dCB0byBjaGVja1xyXG4gKiBAcmV0dXJucyAgIGJvb2xlYW5cclxuICovXHJcbmZ1bmN0aW9uIGZpbGVQYXRoU3VwcGxpZWQobmFtZSkge1xyXG4gICAgLy8gbm9ybWFsaXplIHBhdGhzXHJcbiAgICB2YXIgcGF0aFZhbHVlID0gdGhpcy5yZXNvbHZlKHRoaXMuZ2V0UGF0aElucHV0KG5hbWUpIHx8ICcnKTtcclxuICAgIHZhciByZXBvUm9vdCA9IHRoaXMucmVzb2x2ZShleHBvcnRzLmdldFZhcmlhYmxlKCdidWlsZC5zb3VyY2VzRGlyZWN0b3J5JykgfHwgZXhwb3J0cy5nZXRWYXJpYWJsZSgnc3lzdGVtLmRlZmF1bHRXb3JraW5nRGlyZWN0b3J5JykgfHwgJycpO1xyXG4gICAgdmFyIHN1cHBsaWVkID0gcGF0aFZhbHVlICE9PSByZXBvUm9vdDtcclxuICAgIGV4cG9ydHMuZGVidWcobmFtZSArICdwYXRoIHN1cHBsaWVkIDonICsgc3VwcGxpZWQpO1xyXG4gICAgcmV0dXJuIHN1cHBsaWVkO1xyXG59XHJcbmV4cG9ydHMuZmlsZVBhdGhTdXBwbGllZCA9IGZpbGVQYXRoU3VwcGxpZWQ7XHJcbi8qKlxyXG4gKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHBhdGggaW5wdXRcclxuICogSXQgd2lsbCBiZSBxdW90ZWQgZm9yIHlvdSBpZiBpdCBpc24ndCBhbHJlYWR5IGFuZCBjb250YWlucyBzcGFjZXNcclxuICogSWYgcmVxdWlyZWQgaXMgdHJ1ZSBhbmQgdGhlIHZhbHVlIGlzIG5vdCBzZXQsIGl0IHdpbGwgdGhyb3cuXHJcbiAqIElmIGNoZWNrIGlzIHRydWUgYW5kIHRoZSBwYXRoIGRvZXMgbm90IGV4aXN0LCBpdCB3aWxsIHRocm93LlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIG5hbWUgICAgICBuYW1lIG9mIHRoZSBpbnB1dCB0byBnZXRcclxuICogQHBhcmFtICAgICByZXF1aXJlZCAgd2hldGhlciBpbnB1dCBpcyByZXF1aXJlZC4gIG9wdGlvbmFsLCBkZWZhdWx0cyB0byBmYWxzZVxyXG4gKiBAcGFyYW0gICAgIGNoZWNrICAgICB3aGV0aGVyIHBhdGggaXMgY2hlY2tlZC4gIG9wdGlvbmFsLCBkZWZhdWx0cyB0byBmYWxzZVxyXG4gKiBAcmV0dXJucyAgIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gZ2V0UGF0aElucHV0KG5hbWUsIHJlcXVpcmVkLCBjaGVjaykge1xyXG4gICAgdmFyIGludmFsID0gZ2V0SW5wdXQobmFtZSwgcmVxdWlyZWQpO1xyXG4gICAgaWYgKGludmFsKSB7XHJcbiAgICAgICAgaWYgKGNoZWNrKSB7XHJcbiAgICAgICAgICAgIGV4cG9ydHMuY2hlY2tQYXRoKGludmFsLCBuYW1lKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gaW52YWw7XHJcbn1cclxuZXhwb3J0cy5nZXRQYXRoSW5wdXQgPSBnZXRQYXRoSW5wdXQ7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gRW5kcG9pbnQgSGVscGVyc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSB1cmwgZm9yIGEgc2VydmljZSBlbmRwb2ludFxyXG4gKiBJZiB0aGUgdXJsIHdhcyBub3Qgc2V0IGFuZCBpcyBub3Qgb3B0aW9uYWwsIGl0IHdpbGwgdGhyb3cuXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgaWQgICAgICAgIG5hbWUgb2YgdGhlIHNlcnZpY2UgZW5kcG9pbnRcclxuICogQHBhcmFtICAgICBvcHRpb25hbCAgd2hldGhlciB0aGUgdXJsIGlzIG9wdGlvbmFsXHJcbiAqIEByZXR1cm5zICAgc3RyaW5nXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRFbmRwb2ludFVybChpZCwgb3B0aW9uYWwpIHtcclxuICAgIHZhciB1cmx2YWwgPSBwcm9jZXNzLmVudlsnRU5EUE9JTlRfVVJMXycgKyBpZF07XHJcbiAgICBpZiAoIW9wdGlvbmFsICYmICF1cmx2YWwpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9FbmRwb2ludE5vdEV4aXN0JywgaWQpKTtcclxuICAgIH1cclxuICAgIGV4cG9ydHMuZGVidWcoaWQgKyAnPScgKyB1cmx2YWwpO1xyXG4gICAgcmV0dXJuIHVybHZhbDtcclxufVxyXG5leHBvcnRzLmdldEVuZHBvaW50VXJsID0gZ2V0RW5kcG9pbnRVcmw7XHJcbi8qXHJcbiAqIEdldHMgdGhlIGVuZHBvaW50IGRhdGEgcGFyYW1ldGVyIHZhbHVlIHdpdGggc3BlY2lmaWVkIGtleSBmb3IgYSBzZXJ2aWNlIGVuZHBvaW50XHJcbiAqIElmIHRoZSBlbmRwb2ludCBkYXRhIHBhcmFtZXRlciB3YXMgbm90IHNldCBhbmQgaXMgbm90IG9wdGlvbmFsLCBpdCB3aWxsIHRocm93LlxyXG4gKlxyXG4gKiBAcGFyYW0gaWQgbmFtZSBvZiB0aGUgc2VydmljZSBlbmRwb2ludFxyXG4gKiBAcGFyYW0ga2V5IG9mIHRoZSBwYXJhbWV0ZXJcclxuICogQHBhcmFtIG9wdGlvbmFsIHdoZXRoZXIgdGhlIGVuZHBvaW50IGRhdGEgaXMgb3B0aW9uYWxcclxuICogQHJldHVybnMge3N0cmluZ30gdmFsdWUgb2YgdGhlIGVuZHBvaW50IGRhdGEgcGFyYW1ldGVyXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRFbmRwb2ludERhdGFQYXJhbWV0ZXIoaWQsIGtleSwgb3B0aW9uYWwpIHtcclxuICAgIHZhciBkYXRhUGFyYW1WYWwgPSBwcm9jZXNzLmVudlsnRU5EUE9JTlRfREFUQV8nICsgaWQgKyAnXycgKyBrZXkudG9VcHBlckNhc2UoKV07XHJcbiAgICBpZiAoIW9wdGlvbmFsICYmICFkYXRhUGFyYW1WYWwpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9FbmRwb2ludERhdGFOb3RFeGlzdCcsIGlkLCBrZXkpKTtcclxuICAgIH1cclxuICAgIGV4cG9ydHMuZGVidWcoaWQgKyAnIGRhdGEgJyArIGtleSArICcgPSAnICsgZGF0YVBhcmFtVmFsKTtcclxuICAgIHJldHVybiBkYXRhUGFyYW1WYWw7XHJcbn1cclxuZXhwb3J0cy5nZXRFbmRwb2ludERhdGFQYXJhbWV0ZXIgPSBnZXRFbmRwb2ludERhdGFQYXJhbWV0ZXI7XHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBlbmRwb2ludCBhdXRob3JpemF0aW9uIHNjaGVtZSBmb3IgYSBzZXJ2aWNlIGVuZHBvaW50XHJcbiAqIElmIHRoZSBlbmRwb2ludCBhdXRob3JpemF0aW9uIHNjaGVtZSBpcyBub3Qgc2V0IGFuZCBpcyBub3Qgb3B0aW9uYWwsIGl0IHdpbGwgdGhyb3cuXHJcbiAqXHJcbiAqIEBwYXJhbSBpZCBuYW1lIG9mIHRoZSBzZXJ2aWNlIGVuZHBvaW50XHJcbiAqIEBwYXJhbSBvcHRpb25hbCB3aGV0aGVyIHRoZSBlbmRwb2ludCBhdXRob3JpemF0aW9uIHNjaGVtZSBpcyBvcHRpb25hbFxyXG4gKiBAcmV0dXJucyB7c3RyaW5nfSB2YWx1ZSBvZiB0aGUgZW5kcG9pbnQgYXV0aG9yaXphdGlvbiBzY2hlbWVcclxuICovXHJcbmZ1bmN0aW9uIGdldEVuZHBvaW50QXV0aG9yaXphdGlvblNjaGVtZShpZCwgb3B0aW9uYWwpIHtcclxuICAgIHZhciBhdXRoU2NoZW1lID0gaW0uX3ZhdWx0LnJldHJpZXZlU2VjcmV0KCdFTkRQT0lOVF9BVVRIX1NDSEVNRV8nICsgaWQpO1xyXG4gICAgaWYgKCFvcHRpb25hbCAmJiAhYXV0aFNjaGVtZSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmxvYygnTElCX0VuZHBvaW50QXV0aE5vdEV4aXN0JywgaWQpKTtcclxuICAgIH1cclxuICAgIGV4cG9ydHMuZGVidWcoaWQgKyAnIGF1dGggc2NoZW1lID0gJyArIGF1dGhTY2hlbWUpO1xyXG4gICAgcmV0dXJuIGF1dGhTY2hlbWU7XHJcbn1cclxuZXhwb3J0cy5nZXRFbmRwb2ludEF1dGhvcml6YXRpb25TY2hlbWUgPSBnZXRFbmRwb2ludEF1dGhvcml6YXRpb25TY2hlbWU7XHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBlbmRwb2ludCBhdXRob3JpemF0aW9uIHBhcmFtZXRlciB2YWx1ZSBmb3IgYSBzZXJ2aWNlIGVuZHBvaW50IHdpdGggc3BlY2lmaWVkIGtleVxyXG4gKiBJZiB0aGUgZW5kcG9pbnQgYXV0aG9yaXphdGlvbiBwYXJhbWV0ZXIgaXMgbm90IHNldCBhbmQgaXMgbm90IG9wdGlvbmFsLCBpdCB3aWxsIHRocm93LlxyXG4gKlxyXG4gKiBAcGFyYW0gaWQgbmFtZSBvZiB0aGUgc2VydmljZSBlbmRwb2ludFxyXG4gKiBAcGFyYW0ga2V5IGtleSB0byBmaW5kIHRoZSBlbmRwb2ludCBhdXRob3JpemF0aW9uIHBhcmFtZXRlclxyXG4gKiBAcGFyYW0gb3B0aW9uYWwgb3B0aW9uYWwgd2hldGhlciB0aGUgZW5kcG9pbnQgYXV0aG9yaXphdGlvbiBzY2hlbWUgaXMgb3B0aW9uYWxcclxuICogQHJldHVybnMge3N0cmluZ30gdmFsdWUgb2YgdGhlIGVuZHBvaW50IGF1dGhvcml6YXRpb24gcGFyYW1ldGVyIHZhbHVlXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRFbmRwb2ludEF1dGhvcml6YXRpb25QYXJhbWV0ZXIoaWQsIGtleSwgb3B0aW9uYWwpIHtcclxuICAgIHZhciBhdXRoUGFyYW0gPSBpbS5fdmF1bHQucmV0cmlldmVTZWNyZXQoJ0VORFBPSU5UX0FVVEhfUEFSQU1FVEVSXycgKyBpZCArICdfJyArIGtleS50b1VwcGVyQ2FzZSgpKTtcclxuICAgIGlmICghb3B0aW9uYWwgJiYgIWF1dGhQYXJhbSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmxvYygnTElCX0VuZHBvaW50QXV0aE5vdEV4aXN0JywgaWQpKTtcclxuICAgIH1cclxuICAgIGV4cG9ydHMuZGVidWcoaWQgKyAnIGF1dGggcGFyYW0gJyArIGtleSArICcgPSAnICsgYXV0aFBhcmFtKTtcclxuICAgIHJldHVybiBhdXRoUGFyYW07XHJcbn1cclxuZXhwb3J0cy5nZXRFbmRwb2ludEF1dGhvcml6YXRpb25QYXJhbWV0ZXIgPSBnZXRFbmRwb2ludEF1dGhvcml6YXRpb25QYXJhbWV0ZXI7XHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBhdXRob3JpemF0aW9uIGRldGFpbHMgZm9yIGEgc2VydmljZSBlbmRwb2ludFxyXG4gKiBJZiB0aGUgYXV0aG9yaXphdGlvbiB3YXMgbm90IHNldCBhbmQgaXMgbm90IG9wdGlvbmFsLCBpdCB3aWxsIHRocm93LlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIGlkICAgICAgICBuYW1lIG9mIHRoZSBzZXJ2aWNlIGVuZHBvaW50XHJcbiAqIEBwYXJhbSAgICAgb3B0aW9uYWwgIHdoZXRoZXIgdGhlIHVybCBpcyBvcHRpb25hbFxyXG4gKiBAcmV0dXJucyAgIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gZ2V0RW5kcG9pbnRBdXRob3JpemF0aW9uKGlkLCBvcHRpb25hbCkge1xyXG4gICAgdmFyIGF2YWwgPSBpbS5fdmF1bHQucmV0cmlldmVTZWNyZXQoJ0VORFBPSU5UX0FVVEhfJyArIGlkKTtcclxuICAgIGlmICghb3B0aW9uYWwgJiYgIWF2YWwpIHtcclxuICAgICAgICBzZXRSZXN1bHQoVGFza1Jlc3VsdC5GYWlsZWQsIGV4cG9ydHMubG9jKCdMSUJfRW5kcG9pbnRBdXRoTm90RXhpc3QnLCBpZCkpO1xyXG4gICAgfVxyXG4gICAgZXhwb3J0cy5kZWJ1ZyhpZCArICcgZXhpc3RzICcgKyAoYXZhbCAhPT0gbnVsbCkpO1xyXG4gICAgdmFyIGF1dGg7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIGlmIChhdmFsKSB7XHJcbiAgICAgICAgICAgIGF1dGggPSBKU09OLnBhcnNlKGF2YWwpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9JbnZhbGlkRW5kcG9pbnRBdXRoJywgYXZhbCkpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGF1dGg7XHJcbn1cclxuZXhwb3J0cy5nZXRFbmRwb2ludEF1dGhvcml6YXRpb24gPSBnZXRFbmRwb2ludEF1dGhvcml6YXRpb247XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gU2VjdXJlRmlsZSBIZWxwZXJzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyoqXHJcbiAqIEdldHMgdGhlIG5hbWUgZm9yIGEgc2VjdXJlIGZpbGVcclxuICpcclxuICogQHBhcmFtICAgICBpZCAgICAgICAgc2VjdXJlIGZpbGUgaWRcclxuICogQHJldHVybnMgICBzdHJpbmdcclxuICovXHJcbmZ1bmN0aW9uIGdldFNlY3VyZUZpbGVOYW1lKGlkKSB7XHJcbiAgICB2YXIgbmFtZSA9IHByb2Nlc3MuZW52WydTRUNVUkVGSUxFX05BTUVfJyArIGlkXTtcclxuICAgIGV4cG9ydHMuZGVidWcoJ3NlY3VyZSBmaWxlIG5hbWUgZm9yIGlkICcgKyBpZCArICcgPSAnICsgbmFtZSk7XHJcbiAgICByZXR1cm4gbmFtZTtcclxufVxyXG5leHBvcnRzLmdldFNlY3VyZUZpbGVOYW1lID0gZ2V0U2VjdXJlRmlsZU5hbWU7XHJcbi8qKlxyXG4gICogR2V0cyB0aGUgc2VjdXJlIGZpbGUgdGlja2V0IHRoYXQgY2FuIGJlIHVzZWQgdG8gZG93bmxvYWQgdGhlIHNlY3VyZSBmaWxlIGNvbnRlbnRzXHJcbiAgKlxyXG4gICogQHBhcmFtIGlkIG5hbWUgb2YgdGhlIHNlY3VyZSBmaWxlXHJcbiAgKiBAcmV0dXJucyB7c3RyaW5nfSBzZWN1cmUgZmlsZSB0aWNrZXRcclxuICAqL1xyXG5mdW5jdGlvbiBnZXRTZWN1cmVGaWxlVGlja2V0KGlkKSB7XHJcbiAgICB2YXIgdGlja2V0ID0gaW0uX3ZhdWx0LnJldHJpZXZlU2VjcmV0KCdTRUNVUkVGSUxFX1RJQ0tFVF8nICsgaWQpO1xyXG4gICAgZXhwb3J0cy5kZWJ1Zygnc2VjdXJlIGZpbGUgdGlja2V0IGZvciBpZCAnICsgaWQgKyAnID0gJyArIHRpY2tldCk7XHJcbiAgICByZXR1cm4gdGlja2V0O1xyXG59XHJcbmV4cG9ydHMuZ2V0U2VjdXJlRmlsZVRpY2tldCA9IGdldFNlY3VyZUZpbGVUaWNrZXQ7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gVGFzayBWYXJpYWJsZSBIZWxwZXJzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyoqXHJcbiAqIEdldHMgYSB2YXJpYWJsZSB2YWx1ZSB0aGF0IGlzIHNldCBieSBwcmV2aW91cyBzdGVwIGZyb20gdGhlIHNhbWUgd3JhcHBlciB0YXNrLlxyXG4gKiBSZXF1aXJlcyBhIDIuMTE1LjAgYWdlbnQgb3IgaGlnaGVyLlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIG5hbWUgICAgIG5hbWUgb2YgdGhlIHZhcmlhYmxlIHRvIGdldFxyXG4gKiBAcmV0dXJucyAgIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gZ2V0VGFza1ZhcmlhYmxlKG5hbWUpIHtcclxuICAgIGFzc2VydEFnZW50KCcyLjExNS4wJyk7XHJcbiAgICB2YXIgaW52YWwgPSBpbS5fdmF1bHQucmV0cmlldmVTZWNyZXQoJ1ZTVFNfVEFTS1ZBUklBQkxFXycgKyBpbS5fZ2V0VmFyaWFibGVLZXkobmFtZSkpO1xyXG4gICAgaWYgKGludmFsKSB7XHJcbiAgICAgICAgaW52YWwgPSBpbnZhbC50cmltKCk7XHJcbiAgICB9XHJcbiAgICBleHBvcnRzLmRlYnVnKCd0YXNrIHZhcmlhYmxlOiAnICsgbmFtZSArICc9JyArIGludmFsKTtcclxuICAgIHJldHVybiBpbnZhbDtcclxufVxyXG5leHBvcnRzLmdldFRhc2tWYXJpYWJsZSA9IGdldFRhc2tWYXJpYWJsZTtcclxuLyoqXHJcbiAqIFNldHMgYSB0YXNrIHZhcmlhYmxlIHdoaWNoIHdpbGwgb25seSBiZSBhdmFpbGFibGUgdG8gc3Vic2VxdWVudCBzdGVwcyBiZWxvbmcgdG8gdGhlIHNhbWUgd3JhcHBlciB0YXNrLlxyXG4gKiBSZXF1aXJlcyBhIDIuMTE1LjAgYWdlbnQgb3IgaGlnaGVyLlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIG5hbWUgICAgbmFtZSBvZiB0aGUgdmFyaWFibGUgdG8gc2V0XHJcbiAqIEBwYXJhbSAgICAgdmFsICAgICB2YWx1ZSB0byBzZXRcclxuICogQHBhcmFtICAgICBzZWNyZXQgIHdoZXRoZXIgdmFyaWFibGUgaXMgc2VjcmV0LiAgb3B0aW9uYWwsIGRlZmF1bHRzIHRvIGZhbHNlXHJcbiAqIEByZXR1cm5zICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gc2V0VGFza1ZhcmlhYmxlKG5hbWUsIHZhbCwgc2VjcmV0KSB7XHJcbiAgICBpZiAoc2VjcmV0ID09PSB2b2lkIDApIHsgc2VjcmV0ID0gZmFsc2U7IH1cclxuICAgIGFzc2VydEFnZW50KCcyLjExNS4wJyk7XHJcbiAgICB2YXIga2V5ID0gaW0uX2dldFZhcmlhYmxlS2V5KG5hbWUpO1xyXG4gICAgLy8gc3RvcmUgdGhlIHZhbHVlXHJcbiAgICB2YXIgdmFyVmFsdWUgPSB2YWwgfHwgJyc7XHJcbiAgICBleHBvcnRzLmRlYnVnKCdzZXQgdGFzayB2YXJpYWJsZTogJyArIG5hbWUgKyAnPScgKyAoc2VjcmV0ICYmIHZhclZhbHVlID8gJyoqKioqKioqJyA6IHZhclZhbHVlKSk7XHJcbiAgICBpbS5fdmF1bHQuc3RvcmVTZWNyZXQoJ1ZTVFNfVEFTS1ZBUklBQkxFXycgKyBrZXksIHZhclZhbHVlKTtcclxuICAgIGRlbGV0ZSBwcm9jZXNzLmVudltrZXldO1xyXG4gICAgLy8gd3JpdGUgdGhlIGNvbW1hbmRcclxuICAgIGV4cG9ydHMuY29tbWFuZCgndGFzay5zZXR0YXNrdmFyaWFibGUnLCB7ICd2YXJpYWJsZSc6IG5hbWUgfHwgJycsICdpc3NlY3JldCc6IChzZWNyZXQgfHwgZmFsc2UpLnRvU3RyaW5nKCkgfSwgdmFyVmFsdWUpO1xyXG59XHJcbmV4cG9ydHMuc2V0VGFza1ZhcmlhYmxlID0gc2V0VGFza1ZhcmlhYmxlO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIENtZCBIZWxwZXJzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZXhwb3J0cy5jb21tYW5kID0gaW0uX2NvbW1hbmQ7XHJcbmV4cG9ydHMud2FybmluZyA9IGltLl93YXJuaW5nO1xyXG5leHBvcnRzLmVycm9yID0gaW0uX2Vycm9yO1xyXG5leHBvcnRzLmRlYnVnID0gaW0uX2RlYnVnO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIERpc2sgRnVuY3Rpb25zXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZnVuY3Rpb24gX2NoZWNrU2hlbGwoY21kLCBjb250aW51ZU9uRXJyb3IpIHtcclxuICAgIHZhciBzZSA9IHNoZWxsLmVycm9yKCk7XHJcbiAgICBpZiAoc2UpIHtcclxuICAgICAgICBleHBvcnRzLmRlYnVnKGNtZCArICcgZmFpbGVkJyk7XHJcbiAgICAgICAgdmFyIGVyck1zZyA9IGV4cG9ydHMubG9jKCdMSUJfT3BlcmF0aW9uRmFpbGVkJywgY21kLCBzZSk7XHJcbiAgICAgICAgZXhwb3J0cy5kZWJ1ZyhlcnJNc2cpO1xyXG4gICAgICAgIGlmICghY29udGludWVPbkVycm9yKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJNc2cpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4vKipcclxuICogR2V0J3Mgc3RhdCBvbiBhIHBhdGguXHJcbiAqIFVzZWZ1bCBmb3IgY2hlY2tpbmcgd2hldGhlciBhIGZpbGUgb3IgZGlyZWN0b3J5LiAgQWxzbyBnZXR0aW5nIGNyZWF0ZWQsIG1vZGlmaWVkIGFuZCBhY2Nlc3NlZCB0aW1lLlxyXG4gKiBzZWUgW2ZzLnN0YXRdKGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvZnMuaHRtbCNmc19jbGFzc19mc19zdGF0cylcclxuICpcclxuICogQHBhcmFtICAgICBwYXRoICAgICAgcGF0aCB0byBjaGVja1xyXG4gKiBAcmV0dXJucyAgIGZzU3RhdFxyXG4gKi9cclxuZnVuY3Rpb24gc3RhdHMocGF0aCkge1xyXG4gICAgcmV0dXJuIGZzLnN0YXRTeW5jKHBhdGgpO1xyXG59XHJcbmV4cG9ydHMuc3RhdHMgPSBzdGF0cztcclxuZXhwb3J0cy5leGlzdCA9IGltLl9leGlzdDtcclxuZnVuY3Rpb24gd3JpdGVGaWxlKGZpbGUsIGRhdGEsIG9wdGlvbnMpIHtcclxuICAgIGlmICh0eXBlb2YgKG9wdGlvbnMpID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMoZmlsZSwgZGF0YSwgeyBlbmNvZGluZzogb3B0aW9ucyB9KTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMoZmlsZSwgZGF0YSwgb3B0aW9ucyk7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy53cml0ZUZpbGUgPSB3cml0ZUZpbGU7XHJcbi8qKlxyXG4gKiBAZGVwcmVjYXRlZCBVc2UgYGdldFBsYXRmb3JtYFxyXG4gKiBVc2VmdWwgZm9yIGRldGVybWluaW5nIHRoZSBob3N0IG9wZXJhdGluZyBzeXN0ZW0uXHJcbiAqIHNlZSBbb3MudHlwZV0oaHR0cHM6Ly9ub2RlanMub3JnL2FwaS9vcy5odG1sI29zX29zX3R5cGUpXHJcbiAqXHJcbiAqIEByZXR1cm4gICAgICB0aGUgbmFtZSBvZiB0aGUgb3BlcmF0aW5nIHN5c3RlbVxyXG4gKi9cclxuZnVuY3Rpb24gb3NUeXBlKCkge1xyXG4gICAgcmV0dXJuIG9zLnR5cGUoKTtcclxufVxyXG5leHBvcnRzLm9zVHlwZSA9IG9zVHlwZTtcclxuLyoqXHJcbiAqIERldGVybWluZSB0aGUgb3BlcmF0aW5nIHN5c3RlbSB0aGUgYnVpbGQgYWdlbnQgaXMgcnVubmluZyBvbi5cclxuICogQHJldHVybnMge1BsYXRmb3JtfVxyXG4gKiBAdGhyb3dzIHtFcnJvcn0gUGxhdGZvcm0gaXMgbm90IHN1cHBvcnRlZCBieSBvdXIgYWdlbnRcclxuICovXHJcbmZ1bmN0aW9uIGdldFBsYXRmb3JtKCkge1xyXG4gICAgc3dpdGNoIChwcm9jZXNzLnBsYXRmb3JtKSB7XHJcbiAgICAgICAgY2FzZSAnd2luMzInOiByZXR1cm4gUGxhdGZvcm0uV2luZG93cztcclxuICAgICAgICBjYXNlICdkYXJ3aW4nOiByZXR1cm4gUGxhdGZvcm0uTWFjT1M7XHJcbiAgICAgICAgY2FzZSAnbGludXgnOiByZXR1cm4gUGxhdGZvcm0uTGludXg7XHJcbiAgICAgICAgZGVmYXVsdDogdGhyb3cgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9QbGF0Zm9ybU5vdFN1cHBvcnRlZCcsIHByb2Nlc3MucGxhdGZvcm0pKTtcclxuICAgIH1cclxufVxyXG5leHBvcnRzLmdldFBsYXRmb3JtID0gZ2V0UGxhdGZvcm07XHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBwcm9jZXNzJ3MgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS5cclxuICogc2VlIFtwcm9jZXNzLmN3ZF0oaHR0cHM6Ly9ub2RlanMub3JnL2FwaS9wcm9jZXNzLmh0bWwjcHJvY2Vzc19wcm9jZXNzX2N3ZClcclxuICpcclxuICogQHJldHVybiAgICAgIHRoZSBwYXRoIHRvIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5IG9mIHRoZSBwcm9jZXNzXHJcbiAqL1xyXG5mdW5jdGlvbiBjd2QoKSB7XHJcbiAgICByZXR1cm4gcHJvY2Vzcy5jd2QoKTtcclxufVxyXG5leHBvcnRzLmN3ZCA9IGN3ZDtcclxuZXhwb3J0cy5jaGVja1BhdGggPSBpbS5fY2hlY2tQYXRoO1xyXG4vKipcclxuICogQ2hhbmdlIHdvcmtpbmcgZGlyZWN0b3J5LlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHBhdGggICAgICBuZXcgd29ya2luZyBkaXJlY3RvcnkgcGF0aFxyXG4gKiBAcmV0dXJucyAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIGNkKHBhdGgpIHtcclxuICAgIGlmIChwYXRoKSB7XHJcbiAgICAgICAgc2hlbGwuY2QocGF0aCk7XHJcbiAgICAgICAgX2NoZWNrU2hlbGwoJ2NkJyk7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5jZCA9IGNkO1xyXG4vKipcclxuICogQ2hhbmdlIHdvcmtpbmcgZGlyZWN0b3J5IGFuZCBwdXNoIGl0IG9uIHRoZSBzdGFja1xyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHBhdGggICAgICBuZXcgd29ya2luZyBkaXJlY3RvcnkgcGF0aFxyXG4gKiBAcmV0dXJucyAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHB1c2hkKHBhdGgpIHtcclxuICAgIHNoZWxsLnB1c2hkKHBhdGgpO1xyXG4gICAgX2NoZWNrU2hlbGwoJ3B1c2hkJyk7XHJcbn1cclxuZXhwb3J0cy5wdXNoZCA9IHB1c2hkO1xyXG4vKipcclxuICogQ2hhbmdlIHdvcmtpbmcgZGlyZWN0b3J5IGJhY2sgdG8gcHJldmlvdXNseSBwdXNoZWQgZGlyZWN0b3J5XHJcbiAqXHJcbiAqIEByZXR1cm5zICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gcG9wZCgpIHtcclxuICAgIHNoZWxsLnBvcGQoKTtcclxuICAgIF9jaGVja1NoZWxsKCdwb3BkJyk7XHJcbn1cclxuZXhwb3J0cy5wb3BkID0gcG9wZDtcclxuLyoqXHJcbiAqIE1ha2UgYSBkaXJlY3RvcnkuICBDcmVhdGVzIHRoZSBmdWxsIHBhdGggd2l0aCBmb2xkZXJzIGluIGJldHdlZW5cclxuICogV2lsbCB0aHJvdyBpZiBpdCBmYWlsc1xyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHAgICAgICAgcGF0aCB0byBjcmVhdGVcclxuICogQHJldHVybnMgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBta2RpclAocCkge1xyXG4gICAgaWYgKCFwKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfUGFyYW1ldGVySXNSZXF1aXJlZCcsICdwJykpO1xyXG4gICAgfVxyXG4gICAgLy8gYnVpbGQgYSBzdGFjayBvZiBkaXJlY3RvcmllcyB0byBjcmVhdGVcclxuICAgIHZhciBzdGFjayA9IFtdO1xyXG4gICAgdmFyIHRlc3REaXIgPSBwO1xyXG4gICAgd2hpbGUgKHRydWUpIHtcclxuICAgICAgICAvLyB2YWxpZGF0ZSB0aGUgbG9vcCBpcyBub3Qgb3V0IG9mIGNvbnRyb2xcclxuICAgICAgICBpZiAoc3RhY2subGVuZ3RoID49IChwcm9jZXNzLmVudlsnVEFTS0xJQl9URVNUX01LRElSUF9GQUlMU0FGRSddIHx8IDEwMDApKSB7XHJcbiAgICAgICAgICAgIC8vIGxldCB0aGUgZnJhbWV3b3JrIHRocm93XHJcbiAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ2xvb3AgaXMgb3V0IG9mIGNvbnRyb2wnKTtcclxuICAgICAgICAgICAgZnMubWtkaXJTeW5jKHApO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGV4cG9ydHMuZGVidWcoXCJ0ZXN0aW5nIGRpcmVjdG9yeSAnXCIgKyB0ZXN0RGlyICsgXCInXCIpO1xyXG4gICAgICAgIHZhciBzdGF0c18xID0gdm9pZCAwO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHN0YXRzXzEgPSBmcy5zdGF0U3luYyh0ZXN0RGlyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT0gJ0VOT0VOVCcpIHtcclxuICAgICAgICAgICAgICAgIC8vIHZhbGlkYXRlIHRoZSBkaXJlY3RvcnkgaXMgbm90IHRoZSBkcml2ZSByb290XHJcbiAgICAgICAgICAgICAgICB2YXIgcGFyZW50RGlyID0gcGF0aC5kaXJuYW1lKHRlc3REaXIpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRlc3REaXIgPT0gcGFyZW50RGlyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfTWtkaXJGYWlsZWRJbnZhbGlkRHJpdmVSb290JywgcCwgdGVzdERpcikpOyAvLyBVbmFibGUgdG8gY3JlYXRlIGRpcmVjdG9yeSAne3B9Jy4gUm9vdCBkaXJlY3RvcnkgZG9lcyBub3QgZXhpc3Q6ICd7dGVzdERpcn0nXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBwdXNoIHRoZSBkaXIgYW5kIHRlc3QgdGhlIHBhcmVudFxyXG4gICAgICAgICAgICAgICAgc3RhY2sucHVzaCh0ZXN0RGlyKTtcclxuICAgICAgICAgICAgICAgIHRlc3REaXIgPSBwYXJlbnREaXI7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChlcnIuY29kZSA9PSAnVU5LTk9XTicpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmxvYygnTElCX01rZGlyRmFpbGVkSW52YWxpZFNoYXJlJywgcCwgdGVzdERpcikpOyAvLyBVbmFibGUgdG8gY3JlYXRlIGRpcmVjdG9yeSAne3B9Jy4gVW5hYmxlIHRvIHZlcmlmeSB0aGUgZGlyZWN0b3J5IGV4aXN0czogJ3t0ZXN0RGlyfScuIElmIGRpcmVjdG9yeSBpcyBhIGZpbGUgc2hhcmUsIHBsZWFzZSB2ZXJpZnkgdGhlIHNoYXJlIG5hbWUgaXMgY29ycmVjdCwgdGhlIHNoYXJlIGlzIG9ubGluZSwgYW5kIHRoZSBjdXJyZW50IHByb2Nlc3MgaGFzIHBlcm1pc3Npb24gdG8gYWNjZXNzIHRoZSBzaGFyZS5cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXN0YXRzXzEuaXNEaXJlY3RvcnkoKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9Na2RpckZhaWxlZEZpbGVFeGlzdHMnLCBwLCB0ZXN0RGlyKSk7IC8vIFVuYWJsZSB0byBjcmVhdGUgZGlyZWN0b3J5ICd7cH0nLiBDb25mbGljdGluZyBmaWxlIGV4aXN0czogJ3t0ZXN0RGlyfSdcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gdGVzdERpciBleGlzdHNcclxuICAgICAgICBicmVhaztcclxuICAgIH1cclxuICAgIC8vIGNyZWF0ZSBlYWNoIGRpcmVjdG9yeVxyXG4gICAgd2hpbGUgKHN0YWNrLmxlbmd0aCkge1xyXG4gICAgICAgIHZhciBkaXIgPSBzdGFjay5wb3AoKTsgLy8gbm9uLW51bGwgYmVjYXVzZSBgc3RhY2subGVuZ3RoYCB3YXMgdHJ1dGh5XHJcbiAgICAgICAgZXhwb3J0cy5kZWJ1ZyhcIm1rZGlyICdcIiArIGRpciArIFwiJ1wiKTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBmcy5ta2RpclN5bmMoZGlyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9Na2RpckZhaWxlZCcsIHAsIGVyci5tZXNzYWdlKSk7IC8vIFVuYWJsZSB0byBjcmVhdGUgZGlyZWN0b3J5ICd7cH0nLiB7ZXJyLm1lc3NhZ2V9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMubWtkaXJQID0gbWtkaXJQO1xyXG4vKipcclxuICogUmVzb2x2ZXMgYSBzZXF1ZW5jZSBvZiBwYXRocyBvciBwYXRoIHNlZ21lbnRzIGludG8gYW4gYWJzb2x1dGUgcGF0aC5cclxuICogQ2FsbHMgbm9kZS5qcyBwYXRoLnJlc29sdmUoKVxyXG4gKiBBbGxvd3MgTDAgdGVzdGluZyB3aXRoIGNvbnNpc3RlbnQgcGF0aCBmb3JtYXRzIG9uIE1hYy9MaW51eCBhbmQgV2luZG93cyBpbiB0aGUgbW9jayBpbXBsZW1lbnRhdGlvblxyXG4gKiBAcGFyYW0gcGF0aFNlZ21lbnRzXHJcbiAqIEByZXR1cm5zIHtzdHJpbmd9XHJcbiAqL1xyXG5mdW5jdGlvbiByZXNvbHZlKCkge1xyXG4gICAgdmFyIHBhdGhTZWdtZW50cyA9IFtdO1xyXG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICBwYXRoU2VnbWVudHNbX2ldID0gYXJndW1lbnRzW19pXTtcclxuICAgIH1cclxuICAgIHZhciBhYnNvbHV0ZVBhdGggPSBwYXRoLnJlc29sdmUuYXBwbHkodGhpcywgcGF0aFNlZ21lbnRzKTtcclxuICAgIGV4cG9ydHMuZGVidWcoJ0Fic29sdXRlIHBhdGggZm9yIHBhdGhTZWdtZW50czogJyArIHBhdGhTZWdtZW50cyArICcgPSAnICsgYWJzb2x1dGVQYXRoKTtcclxuICAgIHJldHVybiBhYnNvbHV0ZVBhdGg7XHJcbn1cclxuZXhwb3J0cy5yZXNvbHZlID0gcmVzb2x2ZTtcclxuZXhwb3J0cy53aGljaCA9IGltLl93aGljaDtcclxuLyoqXHJcbiAqIFJldHVybnMgYXJyYXkgb2YgZmlsZXMgaW4gdGhlIGdpdmVuIHBhdGgsIG9yIGluIGN1cnJlbnQgZGlyZWN0b3J5IGlmIG5vIHBhdGggcHJvdmlkZWQuICBTZWUgc2hlbGxqcy5sc1xyXG4gKiBAcGFyYW0gIHtzdHJpbmd9ICAgb3B0aW9ucyAgQXZhaWxhYmxlIG9wdGlvbnM6IC1SIChyZWN1cnNpdmUpLCAtQSAoYWxsIGZpbGVzLCBpbmNsdWRlIGZpbGVzIGJlZ2lubmluZyB3aXRoIC4sIGV4Y2VwdCBmb3IgLiBhbmQgLi4pXHJcbiAqIEBwYXJhbSAge3N0cmluZ1tdfSBwYXRocyAgICBQYXRocyB0byBzZWFyY2guXHJcbiAqIEByZXR1cm4ge3N0cmluZ1tdfSAgICAgICAgICBBbiBhcnJheSBvZiBmaWxlcyBpbiB0aGUgZ2l2ZW4gcGF0aChzKS5cclxuICovXHJcbmZ1bmN0aW9uIGxzKG9wdGlvbnMsIHBhdGhzKSB7XHJcbiAgICBpZiAob3B0aW9ucykge1xyXG4gICAgICAgIHJldHVybiBzaGVsbC5scyhvcHRpb25zLCBwYXRocyk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICByZXR1cm4gc2hlbGwubHMocGF0aHMpO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMubHMgPSBscztcclxuLyoqXHJcbiAqIENvcGllcyBhIGZpbGUgb3IgZm9sZGVyLlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHNvdXJjZSAgICAgc291cmNlIHBhdGhcclxuICogQHBhcmFtICAgICBkZXN0ICAgICAgIGRlc3RpbmF0aW9uIHBhdGhcclxuICogQHBhcmFtICAgICBvcHRpb25zICAgIHN0cmluZyAtciwgLWYgb3IgLXJmIGZvciByZWN1cnNpdmUgYW5kIGZvcmNlXHJcbiAqIEBwYXJhbSAgICAgY29udGludWVPbkVycm9yIG9wdGlvbmFsLiB3aGV0aGVyIHRvIGNvbnRpbnVlIG9uIGVycm9yXHJcbiAqL1xyXG5mdW5jdGlvbiBjcChzb3VyY2UsIGRlc3QsIG9wdGlvbnMsIGNvbnRpbnVlT25FcnJvcikge1xyXG4gICAgaWYgKG9wdGlvbnMpIHtcclxuICAgICAgICBzaGVsbC5jcChvcHRpb25zLCBzb3VyY2UsIGRlc3QpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgc2hlbGwuY3Aoc291cmNlLCBkZXN0KTtcclxuICAgIH1cclxuICAgIF9jaGVja1NoZWxsKCdjcCcsIGNvbnRpbnVlT25FcnJvcik7XHJcbn1cclxuZXhwb3J0cy5jcCA9IGNwO1xyXG4vKipcclxuICogTW92ZXMgYSBwYXRoLlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHNvdXJjZSAgICAgc291cmNlIHBhdGhcclxuICogQHBhcmFtICAgICBkZXN0ICAgICAgIGRlc3RpbmF0aW9uIHBhdGhcclxuICogQHBhcmFtICAgICBvcHRpb25zICAgIHN0cmluZyAtZiBvciAtbiBmb3IgZm9yY2UgYW5kIG5vIGNsb2JiZXJcclxuICogQHBhcmFtICAgICBjb250aW51ZU9uRXJyb3Igb3B0aW9uYWwuIHdoZXRoZXIgdG8gY29udGludWUgb24gZXJyb3JcclxuICovXHJcbmZ1bmN0aW9uIG12KHNvdXJjZSwgZGVzdCwgb3B0aW9ucywgY29udGludWVPbkVycm9yKSB7XHJcbiAgICBpZiAob3B0aW9ucykge1xyXG4gICAgICAgIHNoZWxsLm12KG9wdGlvbnMsIHNvdXJjZSwgZGVzdCk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBzaGVsbC5tdihzb3VyY2UsIGRlc3QpO1xyXG4gICAgfVxyXG4gICAgX2NoZWNrU2hlbGwoJ212JywgY29udGludWVPbkVycm9yKTtcclxufVxyXG5leHBvcnRzLm12ID0gbXY7XHJcbi8qKlxyXG4gKiBSZWN1cnNpdmVseSBmaW5kcyBhbGwgcGF0aHMgYSBnaXZlbiBwYXRoLiBSZXR1cm5zIGFuIGFycmF5IG9mIHBhdGhzLlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIGZpbmRQYXRoICBwYXRoIHRvIHNlYXJjaFxyXG4gKiBAcGFyYW0gICAgIG9wdGlvbnMgICBvcHRpb25hbC4gZGVmYXVsdHMgdG8geyBmb2xsb3dTeW1ib2xpY0xpbmtzOiB0cnVlIH0uIGZvbGxvd2luZyBzb2Z0IGxpbmtzIGlzIGdlbmVyYWxseSBhcHByb3ByaWF0ZSB1bmxlc3MgZGVsZXRpbmcgZmlsZXMuXHJcbiAqIEByZXR1cm5zICAgc3RyaW5nW11cclxuICovXHJcbmZ1bmN0aW9uIGZpbmQoZmluZFBhdGgsIG9wdGlvbnMpIHtcclxuICAgIGlmICghZmluZFBhdGgpIHtcclxuICAgICAgICBleHBvcnRzLmRlYnVnKCdubyBwYXRoIHNwZWNpZmllZCcpO1xyXG4gICAgICAgIHJldHVybiBbXTtcclxuICAgIH1cclxuICAgIC8vIG5vcm1hbGl6ZSB0aGUgcGF0aCwgb3RoZXJ3aXNlIHRoZSBmaXJzdCByZXN1bHQgaXMgaW5jb25zaXN0ZW50bHkgZm9ybWF0dGVkIGZyb20gdGhlIHJlc3Qgb2YgdGhlIHJlc3VsdHNcclxuICAgIC8vIGJlY2F1c2UgcGF0aC5qb2luKCkgcGVyZm9ybXMgbm9ybWFsaXphdGlvbi5cclxuICAgIGZpbmRQYXRoID0gcGF0aC5ub3JtYWxpemUoZmluZFBhdGgpO1xyXG4gICAgLy8gZGVidWcgdHJhY2UgdGhlIHBhcmFtZXRlcnNcclxuICAgIGV4cG9ydHMuZGVidWcoXCJmaW5kUGF0aDogJ1wiICsgZmluZFBhdGggKyBcIidcIik7XHJcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCBfZ2V0RGVmYXVsdEZpbmRPcHRpb25zKCk7XHJcbiAgICBfZGVidWdGaW5kT3B0aW9ucyhvcHRpb25zKTtcclxuICAgIC8vIHJldHVybiBlbXB0eSBpZiBub3QgZXhpc3RzXHJcbiAgICB0cnkge1xyXG4gICAgICAgIGZzLmxzdGF0U3luYyhmaW5kUGF0aCk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgaWYgKGVyci5jb2RlID09ICdFTk9FTlQnKSB7XHJcbiAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJzAgcmVzdWx0cycpO1xyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRocm93IGVycjtcclxuICAgIH1cclxuICAgIHRyeSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xyXG4gICAgICAgIC8vIHB1c2ggdGhlIGZpcnN0IGl0ZW1cclxuICAgICAgICB2YXIgc3RhY2sgPSBbbmV3IF9GaW5kSXRlbShmaW5kUGF0aCwgMSldO1xyXG4gICAgICAgIHZhciB0cmF2ZXJzYWxDaGFpbiA9IFtdOyAvLyB1c2VkIHRvIGRldGVjdCBjeWNsZXNcclxuICAgICAgICB2YXIgX2xvb3BfMSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgLy8gcG9wIHRoZSBuZXh0IGl0ZW0gYW5kIHB1c2ggdG8gdGhlIHJlc3VsdCBhcnJheVxyXG4gICAgICAgICAgICB2YXIgaXRlbSA9IHN0YWNrLnBvcCgpOyAvLyBub24tbnVsbCBiZWNhdXNlIGBzdGFjay5sZW5ndGhgIHdhcyB0cnV0aHlcclxuICAgICAgICAgICAgcmVzdWx0LnB1c2goaXRlbS5wYXRoKTtcclxuICAgICAgICAgICAgLy8gc3RhdCB0aGUgaXRlbS4gIHRoZSBzdGF0IGluZm8gaXMgdXNlZCBmdXJ0aGVyIGJlbG93IHRvIGRldGVybWluZSB3aGV0aGVyIHRvIHRyYXZlcnNlIGRlZXBlclxyXG4gICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAvLyBzdGF0IHJldHVybnMgaW5mbyBhYm91dCB0aGUgdGFyZ2V0IG9mIGEgc3ltbGluayAob3Igc3ltbGluayBjaGFpbiksXHJcbiAgICAgICAgICAgIC8vIGxzdGF0IHJldHVybnMgaW5mbyBhYm91dCBhIHN5bWxpbmsgaXRzZWxmXHJcbiAgICAgICAgICAgIHZhciBzdGF0c18yID0gdm9pZCAwO1xyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5mb2xsb3dTeW1ib2xpY0xpbmtzKSB7XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHVzZSBzdGF0IChmb2xsb3dpbmcgYWxsIHN5bWxpbmtzKVxyXG4gICAgICAgICAgICAgICAgICAgIHN0YXRzXzIgPSBmcy5zdGF0U3luYyhpdGVtLnBhdGgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PSAnRU5PRU5UJyAmJiBvcHRpb25zLmFsbG93QnJva2VuU3ltYm9saWNMaW5rcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBmYWxsYmFjayB0byBsc3RhdCAoYnJva2VuIHN5bWxpbmtzIGFsbG93ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRzXzIgPSBmcy5sc3RhdFN5bmMoaXRlbS5wYXRoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZyhcIiAgXCIgKyBpdGVtLnBhdGggKyBcIiAoYnJva2VuIHN5bWxpbmspXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChvcHRpb25zLmZvbGxvd1NwZWNpZmllZFN5bWJvbGljTGluayAmJiByZXN1bHQubGVuZ3RoID09IDEpIHtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdXNlIHN0YXQgKGZvbGxvd2luZyBzeW1saW5rcyBmb3IgdGhlIHNwZWNpZmllZCBwYXRoIGFuZCB0aGlzIGlzIHRoZSBzcGVjaWZpZWQgcGF0aClcclxuICAgICAgICAgICAgICAgICAgICBzdGF0c18yID0gZnMuc3RhdFN5bmMoaXRlbS5wYXRoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT0gJ0VOT0VOVCcgJiYgb3B0aW9ucy5hbGxvd0Jyb2tlblN5bWJvbGljTGlua3MpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmFsbGJhY2sgdG8gbHN0YXQgKGJyb2tlbiBzeW1saW5rcyBhbGxvd2VkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0c18yID0gZnMubHN0YXRTeW5jKGl0ZW0ucGF0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCIgIFwiICsgaXRlbS5wYXRoICsgXCIgKGJyb2tlbiBzeW1saW5rKVwiKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyB1c2UgbHN0YXQgKG5vdCBmb2xsb3dpbmcgc3ltbGlua3MpXHJcbiAgICAgICAgICAgICAgICBzdGF0c18yID0gZnMubHN0YXRTeW5jKGl0ZW0ucGF0aCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gbm90ZSwgaXNEaXJlY3RvcnkoKSByZXR1cm5zIGZhbHNlIGZvciB0aGUgbHN0YXQgb2YgYSBzeW1saW5rXHJcbiAgICAgICAgICAgIGlmIChzdGF0c18yLmlzRGlyZWN0b3J5KCkpIHtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCIgIFwiICsgaXRlbS5wYXRoICsgXCIgKGRpcmVjdG9yeSlcIik7XHJcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5mb2xsb3dTeW1ib2xpY0xpbmtzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSByZWFscGF0aFxyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWFsUGF0aF8xID0gZnMucmVhbHBhdGhTeW5jKGl0ZW0ucGF0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gZml4dXAgdGhlIHRyYXZlcnNhbCBjaGFpbiB0byBtYXRjaCB0aGUgaXRlbSBsZXZlbFxyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlICh0cmF2ZXJzYWxDaGFpbi5sZW5ndGggPj0gaXRlbS5sZXZlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmF2ZXJzYWxDaGFpbi5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdGVzdCBmb3IgYSBjeWNsZVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0cmF2ZXJzYWxDaGFpbi5zb21lKGZ1bmN0aW9uICh4KSB7IHJldHVybiB4ID09IHJlYWxQYXRoXzE7IH0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJyAgICBjeWNsZSBkZXRlY3RlZCcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJjb250aW51ZVwiO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyB1cGRhdGUgdGhlIHRyYXZlcnNhbCBjaGFpblxyXG4gICAgICAgICAgICAgICAgICAgIHRyYXZlcnNhbENoYWluLnB1c2gocmVhbFBhdGhfMSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBwdXNoIHRoZSBjaGlsZCBpdGVtcyBpbiByZXZlcnNlIG9udG8gdGhlIHN0YWNrXHJcbiAgICAgICAgICAgICAgICB2YXIgY2hpbGRMZXZlbF8xID0gaXRlbS5sZXZlbCArIDE7XHJcbiAgICAgICAgICAgICAgICB2YXIgY2hpbGRJdGVtcyA9IGZzLnJlYWRkaXJTeW5jKGl0ZW0ucGF0aClcclxuICAgICAgICAgICAgICAgICAgICAubWFwKGZ1bmN0aW9uIChjaGlsZE5hbWUpIHsgcmV0dXJuIG5ldyBfRmluZEl0ZW0ocGF0aC5qb2luKGl0ZW0ucGF0aCwgY2hpbGROYW1lKSwgY2hpbGRMZXZlbF8xKTsgfSk7XHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gY2hpbGRJdGVtcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrLnB1c2goY2hpbGRJdGVtc1tpXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKFwiICBcIiArIGl0ZW0ucGF0aCArIFwiIChmaWxlKVwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgd2hpbGUgKHN0YWNrLmxlbmd0aCkge1xyXG4gICAgICAgICAgICBfbG9vcF8xKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGV4cG9ydHMuZGVidWcocmVzdWx0Lmxlbmd0aCArIFwiIHJlc3VsdHNcIik7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9PcGVyYXRpb25GYWlsZWQnLCAnZmluZCcsIGVyci5tZXNzYWdlKSk7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5maW5kID0gZmluZDtcclxudmFyIF9GaW5kSXRlbSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIF9GaW5kSXRlbShwYXRoLCBsZXZlbCkge1xyXG4gICAgICAgIHRoaXMucGF0aCA9IHBhdGg7XHJcbiAgICAgICAgdGhpcy5sZXZlbCA9IGxldmVsO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIF9GaW5kSXRlbTtcclxufSgpKTtcclxuZnVuY3Rpb24gX2RlYnVnRmluZE9wdGlvbnMob3B0aW9ucykge1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcImZpbmRPcHRpb25zLmFsbG93QnJva2VuU3ltYm9saWNMaW5rczogJ1wiICsgb3B0aW9ucy5hbGxvd0Jyb2tlblN5bWJvbGljTGlua3MgKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwiZmluZE9wdGlvbnMuZm9sbG93U3BlY2lmaWVkU3ltYm9saWNMaW5rOiAnXCIgKyBvcHRpb25zLmZvbGxvd1NwZWNpZmllZFN5bWJvbGljTGluayArIFwiJ1wiKTtcclxuICAgIGV4cG9ydHMuZGVidWcoXCJmaW5kT3B0aW9ucy5mb2xsb3dTeW1ib2xpY0xpbmtzOiAnXCIgKyBvcHRpb25zLmZvbGxvd1N5bWJvbGljTGlua3MgKyBcIidcIik7XHJcbn1cclxuZnVuY3Rpb24gX2dldERlZmF1bHRGaW5kT3B0aW9ucygpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgYWxsb3dCcm9rZW5TeW1ib2xpY0xpbmtzOiBmYWxzZSxcclxuICAgICAgICBmb2xsb3dTcGVjaWZpZWRTeW1ib2xpY0xpbms6IHRydWUsXHJcbiAgICAgICAgZm9sbG93U3ltYm9saWNMaW5rczogdHJ1ZVxyXG4gICAgfTtcclxufVxyXG4vKipcclxuICogUHJlZmVyIHRsLmZpbmQoKSBhbmQgdGwubWF0Y2goKSBpbnN0ZWFkLiBUaGlzIGZ1bmN0aW9uIGlzIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XHJcbiAqIHdoZW4gcG9ydGluZyB0YXNrcyB0byBOb2RlIGZyb20gdGhlIFBvd2VyU2hlbGwgb3IgUG93ZXJTaGVsbDMgZXhlY3V0aW9uIGhhbmRsZXIuXHJcbiAqXHJcbiAqIEBwYXJhbSAgICByb290RGlyZWN0b3J5ICAgICAgcGF0aCB0byByb290IHVucm9vdGVkIHBhdHRlcm5zIHdpdGhcclxuICogQHBhcmFtICAgIHBhdHRlcm4gICAgICAgICAgICBpbmNsdWRlIGFuZCBleGNsdWRlIHBhdHRlcm5zXHJcbiAqIEBwYXJhbSAgICBpbmNsdWRlRmlsZXMgICAgICAgd2hldGhlciB0byBpbmNsdWRlIGZpbGVzIGluIHRoZSByZXN1bHQuIGRlZmF1bHRzIHRvIHRydWUgd2hlbiBpbmNsdWRlRmlsZXMgYW5kIGluY2x1ZGVEaXJlY3RvcmllcyBhcmUgYm90aCBmYWxzZVxyXG4gKiBAcGFyYW0gICAgaW5jbHVkZURpcmVjdG9yaWVzIHdoZXRoZXIgdG8gaW5jbHVkZSBkaXJlY3RvcmllcyBpbiB0aGUgcmVzdWx0XHJcbiAqIEByZXR1cm5zICBzdHJpbmdbXVxyXG4gKi9cclxuZnVuY3Rpb24gbGVnYWN5RmluZEZpbGVzKHJvb3REaXJlY3RvcnksIHBhdHRlcm4sIGluY2x1ZGVGaWxlcywgaW5jbHVkZURpcmVjdG9yaWVzKSB7XHJcbiAgICBpZiAoIXBhdHRlcm4pIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3BhdHRlcm4gcGFyYW1ldGVyIGNhbm5vdCBiZSBlbXB0eScpO1xyXG4gICAgfVxyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcImxlZ2FjeUZpbmRGaWxlcyByb290RGlyZWN0b3J5OiAnXCIgKyByb290RGlyZWN0b3J5ICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcInBhdHRlcm46ICdcIiArIHBhdHRlcm4gKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwiaW5jbHVkZUZpbGVzOiAnXCIgKyBpbmNsdWRlRmlsZXMgKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwiaW5jbHVkZURpcmVjdG9yaWVzOiAnXCIgKyBpbmNsdWRlRGlyZWN0b3JpZXMgKyBcIidcIik7XHJcbiAgICBpZiAoIWluY2x1ZGVGaWxlcyAmJiAhaW5jbHVkZURpcmVjdG9yaWVzKSB7XHJcbiAgICAgICAgaW5jbHVkZUZpbGVzID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIC8vIG9yZ2FuaXplIHRoZSBwYXR0ZXJucyBpbnRvIGluY2x1ZGUgcGF0dGVybnMgYW5kIGV4Y2x1ZGUgcGF0dGVybnNcclxuICAgIHZhciBpbmNsdWRlUGF0dGVybnMgPSBbXTtcclxuICAgIHZhciBleGNsdWRlUGF0dGVybnMgPSBbXTtcclxuICAgIHBhdHRlcm4gPSBwYXR0ZXJuLnJlcGxhY2UoLzs7L2csICdcXDAnKTtcclxuICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSBwYXR0ZXJuLnNwbGl0KCc7Jyk7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgdmFyIHBhdCA9IF9hW19pXTtcclxuICAgICAgICBpZiAoIXBhdCkge1xyXG4gICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcGF0ID0gcGF0LnJlcGxhY2UoL1xcMC9nLCAnOycpO1xyXG4gICAgICAgIC8vIGRldGVybWluZSB3aGV0aGVyIGluY2x1ZGUgcGF0dGVybiBhbmQgcmVtb3ZlIGFueSBpbmNsdWRlL2V4Y2x1ZGUgcHJlZml4LlxyXG4gICAgICAgIC8vIGluY2x1ZGUgcGF0dGVybnMgc3RhcnQgd2l0aCArOiBvciBhbnl0aGluZyBvdGhlciB0aGFuIC06XHJcbiAgICAgICAgLy8gZXhjbHVkZSBwYXR0ZXJucyBzdGFydCB3aXRoIC06XHJcbiAgICAgICAgdmFyIGlzSW5jbHVkZVBhdHRlcm4gPSB2b2lkIDA7XHJcbiAgICAgICAgaWYgKGltLl9zdGFydHNXaXRoKHBhdCwgJys6JykpIHtcclxuICAgICAgICAgICAgcGF0ID0gcGF0LnN1YnN0cmluZygyKTtcclxuICAgICAgICAgICAgaXNJbmNsdWRlUGF0dGVybiA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKGltLl9zdGFydHNXaXRoKHBhdCwgJy06JykpIHtcclxuICAgICAgICAgICAgcGF0ID0gcGF0LnN1YnN0cmluZygyKTtcclxuICAgICAgICAgICAgaXNJbmNsdWRlUGF0dGVybiA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgaXNJbmNsdWRlUGF0dGVybiA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHZhbGlkYXRlIHBhdHRlcm4gZG9lcyBub3QgZW5kIHdpdGggYSBzbGFzaFxyXG4gICAgICAgIGlmIChpbS5fZW5kc1dpdGgocGF0LCAnLycpIHx8IChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgJiYgaW0uX2VuZHNXaXRoKHBhdCwgJ1xcXFwnKSkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfSW52YWxpZFBhdHRlcm4nLCBwYXQpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gcm9vdCB0aGUgcGF0dGVyblxyXG4gICAgICAgIGlmIChyb290RGlyZWN0b3J5ICYmICFwYXRoLmlzQWJzb2x1dGUocGF0KSkge1xyXG4gICAgICAgICAgICBwYXQgPSBwYXRoLmpvaW4ocm9vdERpcmVjdG9yeSwgcGF0KTtcclxuICAgICAgICAgICAgLy8gcmVtb3ZlIHRyYWlsaW5nIHNsYXNoIHNvbWV0aW1lcyBhZGRlZCBieSBwYXRoLmpvaW4oKSBvbiBXaW5kb3dzLCBlLmcuXHJcbiAgICAgICAgICAgIC8vICAgICAgcGF0aC5qb2luKCdcXFxcXFxcXGhlbGxvJywgJ3dvcmxkJykgPT4gJ1xcXFxcXFxcaGVsbG9cXFxcd29ybGRcXFxcJ1xyXG4gICAgICAgICAgICAvLyAgICAgIHBhdGguam9pbignLy9oZWxsbycsICd3b3JsZCcpID0+ICdcXFxcXFxcXGhlbGxvXFxcXHdvcmxkXFxcXCdcclxuICAgICAgICAgICAgaWYgKGltLl9lbmRzV2l0aChwYXQsICdcXFxcJykpIHtcclxuICAgICAgICAgICAgICAgIHBhdCA9IHBhdC5zdWJzdHJpbmcoMCwgcGF0Lmxlbmd0aCAtIDEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChpc0luY2x1ZGVQYXR0ZXJuKSB7XHJcbiAgICAgICAgICAgIGluY2x1ZGVQYXR0ZXJucy5wdXNoKHBhdCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBleGNsdWRlUGF0dGVybnMucHVzaChpbS5fbGVnYWN5RmluZEZpbGVzX2NvbnZlcnRQYXR0ZXJuVG9SZWdFeHAocGF0KSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gZmluZCBhbmQgYXBwbHkgcGF0dGVybnNcclxuICAgIHZhciBjb3VudCA9IDA7XHJcbiAgICB2YXIgcmVzdWx0ID0gX2xlZ2FjeUZpbmRGaWxlc19nZXRNYXRjaGluZ0l0ZW1zKGluY2x1ZGVQYXR0ZXJucywgZXhjbHVkZVBhdHRlcm5zLCAhIWluY2x1ZGVGaWxlcywgISFpbmNsdWRlRGlyZWN0b3JpZXMpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZygnYWxsIG1hdGNoZXM6Jyk7XHJcbiAgICBmb3IgKHZhciBfYiA9IDAsIHJlc3VsdF8xID0gcmVzdWx0OyBfYiA8IHJlc3VsdF8xLmxlbmd0aDsgX2IrKykge1xyXG4gICAgICAgIHZhciByZXN1bHRJdGVtID0gcmVzdWx0XzFbX2JdO1xyXG4gICAgICAgIGV4cG9ydHMuZGVidWcoJyAnICsgcmVzdWx0SXRlbSk7XHJcbiAgICB9XHJcbiAgICBleHBvcnRzLmRlYnVnKCd0b3RhbCBtYXRjaGVkOiAnICsgcmVzdWx0Lmxlbmd0aCk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcbmV4cG9ydHMubGVnYWN5RmluZEZpbGVzID0gbGVnYWN5RmluZEZpbGVzO1xyXG5mdW5jdGlvbiBfbGVnYWN5RmluZEZpbGVzX2dldE1hdGNoaW5nSXRlbXMoaW5jbHVkZVBhdHRlcm5zLCBleGNsdWRlUGF0dGVybnMsIGluY2x1ZGVGaWxlcywgaW5jbHVkZURpcmVjdG9yaWVzKSB7XHJcbiAgICBleHBvcnRzLmRlYnVnKCdnZXRNYXRjaGluZ0l0ZW1zKCknKTtcclxuICAgIGZvciAodmFyIF9pID0gMCwgaW5jbHVkZVBhdHRlcm5zXzEgPSBpbmNsdWRlUGF0dGVybnM7IF9pIDwgaW5jbHVkZVBhdHRlcm5zXzEubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBpbmNsdWRlUGF0dGVybnNfMVtfaV07XHJcbiAgICAgICAgZXhwb3J0cy5kZWJ1ZyhcImluY2x1ZGVQYXR0ZXJuOiAnXCIgKyBwYXR0ZXJuICsgXCInXCIpO1xyXG4gICAgfVxyXG4gICAgZm9yICh2YXIgX2EgPSAwLCBleGNsdWRlUGF0dGVybnNfMSA9IGV4Y2x1ZGVQYXR0ZXJuczsgX2EgPCBleGNsdWRlUGF0dGVybnNfMS5sZW5ndGg7IF9hKyspIHtcclxuICAgICAgICB2YXIgcGF0dGVybiA9IGV4Y2x1ZGVQYXR0ZXJuc18xW19hXTtcclxuICAgICAgICBleHBvcnRzLmRlYnVnKFwiZXhjbHVkZVBhdHRlcm46IFwiICsgcGF0dGVybik7XHJcbiAgICB9XHJcbiAgICBleHBvcnRzLmRlYnVnKCdpbmNsdWRlRmlsZXM6ICcgKyBpbmNsdWRlRmlsZXMpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZygnaW5jbHVkZURpcmVjdG9yaWVzOiAnICsgaW5jbHVkZURpcmVjdG9yaWVzKTtcclxuICAgIHZhciBhbGxGaWxlcyA9IHt9O1xyXG4gICAgdmFyIF9sb29wXzIgPSBmdW5jdGlvbiAocGF0dGVybikge1xyXG4gICAgICAgIC8vIGRldGVybWluZSB0aGUgZGlyZWN0b3J5IHRvIHNlYXJjaFxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gbm90ZSwgZ2V0RGlyZWN0b3J5TmFtZSByZW1vdmVzIHJlZHVuZGFudCBwYXRoIHNlcGFyYXRvcnNcclxuICAgICAgICB2YXIgZmluZFBhdGggPSB2b2lkIDA7XHJcbiAgICAgICAgdmFyIHN0YXJJbmRleCA9IHBhdHRlcm4uaW5kZXhPZignKicpO1xyXG4gICAgICAgIHZhciBxdWVzdGlvbkluZGV4ID0gcGF0dGVybi5pbmRleE9mKCc/Jyk7XHJcbiAgICAgICAgaWYgKHN0YXJJbmRleCA8IDAgJiYgcXVlc3Rpb25JbmRleCA8IDApIHtcclxuICAgICAgICAgICAgLy8gaWYgbm8gd2lsZGNhcmRzIGFyZSBmb3VuZCwgdXNlIHRoZSBkaXJlY3RvcnkgbmFtZSBwb3J0aW9uIG9mIHRoZSBwYXRoLlxyXG4gICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBubyBkaXJlY3RvcnkgbmFtZSAoZmlsZSBuYW1lIG9ubHkgaW4gcGF0dGVybiBvciBkcml2ZSByb290KSxcclxuICAgICAgICAgICAgLy8gdGhpcyB3aWxsIHJldHVybiBlbXB0eSBzdHJpbmcuXHJcbiAgICAgICAgICAgIGZpbmRQYXRoID0gaW0uX2dldERpcmVjdG9yeU5hbWUocGF0dGVybik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBleHRyYWN0IHRoZSBkaXJlY3RvcnkgcHJpb3IgdG8gdGhlIGZpcnN0IHdpbGRjYXJkXHJcbiAgICAgICAgICAgIHZhciBpbmRleCA9IE1hdGgubWluKHN0YXJJbmRleCA+PSAwID8gc3RhckluZGV4IDogcXVlc3Rpb25JbmRleCwgcXVlc3Rpb25JbmRleCA+PSAwID8gcXVlc3Rpb25JbmRleCA6IHN0YXJJbmRleCk7XHJcbiAgICAgICAgICAgIGZpbmRQYXRoID0gaW0uX2dldERpcmVjdG9yeU5hbWUocGF0dGVybi5zdWJzdHJpbmcoMCwgaW5kZXgpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gbm90ZSwgZHVlIHRvIHRoaXMgc2hvcnQtY2lyY3VpdCBhbmQgdGhlIGFib3ZlIHVzYWdlIG9mIGdldERpcmVjdG9yeU5hbWUsIHRoaXNcclxuICAgICAgICAvLyBmdW5jdGlvbiBoYXMgdGhlIHNhbWUgbGltaXRhdGlvbnMgcmVnYXJkaW5nIGRyaXZlIHJvb3RzIGFzIHRoZSBwb3dlcnNoZWxsXHJcbiAgICAgICAgLy8gaW1wbGVtZW50YXRpb24uXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBhbHNvIG5vdGUsIHNpbmNlIGdldERpcmVjdG9yeU5hbWUgZWxpbWluYXRlcyBzbGFzaCByZWR1bmRhbmNpZXMsIHNvbWUgYWRkaXRpb25hbFxyXG4gICAgICAgIC8vIHdvcmsgbWF5IGJlIHJlcXVpcmVkIGlmIHJlbW92YWwgb2YgdGhpcyBsaW1pdGF0aW9uIGlzIGF0dGVtcHRlZC5cclxuICAgICAgICBpZiAoIWZpbmRQYXRoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBcImNvbnRpbnVlXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBwYXR0ZXJuUmVnZXggPSBpbS5fbGVnYWN5RmluZEZpbGVzX2NvbnZlcnRQYXR0ZXJuVG9SZWdFeHAocGF0dGVybik7XHJcbiAgICAgICAgLy8gZmluZCBmaWxlcy9kaXJlY3Rvcmllc1xyXG4gICAgICAgIHZhciBpdGVtcyA9IGZpbmQoZmluZFBhdGgsIHsgZm9sbG93U3ltYm9saWNMaW5rczogdHJ1ZSB9KVxyXG4gICAgICAgICAgICAuZmlsdGVyKGZ1bmN0aW9uIChpdGVtKSB7XHJcbiAgICAgICAgICAgIGlmIChpbmNsdWRlRmlsZXMgJiYgaW5jbHVkZURpcmVjdG9yaWVzKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgaXNEaXIgPSBmcy5zdGF0U3luYyhpdGVtKS5pc0RpcmVjdG9yeSgpO1xyXG4gICAgICAgICAgICByZXR1cm4gKGluY2x1ZGVGaWxlcyAmJiAhaXNEaXIpIHx8IChpbmNsdWRlRGlyZWN0b3JpZXMgJiYgaXNEaXIpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7XHJcbiAgICAgICAgICAgIHZhciBub3JtYWxpemVkUGF0aCA9IHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyA/IGl0ZW0ucmVwbGFjZSgvXFxcXC9nLCAnLycpIDogaXRlbTsgLy8gbm9ybWFsaXplIHNlcGFyYXRvcnNcclxuICAgICAgICAgICAgLy8gKiovdGltZXMvKiogd2lsbCBub3QgbWF0Y2ggQzovZnVuL3RpbWVzIGJlY2F1c2UgdGhlcmUgaXNuJ3QgYSB0cmFpbGluZyBzbGFzaFxyXG4gICAgICAgICAgICAvLyBzbyB0cnkgYm90aCBpZiBpbmNsdWRpbmcgZGlyZWN0b3JpZXNcclxuICAgICAgICAgICAgdmFyIGFsdGVybmF0ZVBhdGggPSBub3JtYWxpemVkUGF0aCArIFwiL1wiOyAvLyBwb3RlbnRpYWwgYnVnOiBpdCBsb29rcyBsaWtlIHRoaXMgd2lsbCByZXN1bHQgaW4gYSBmYWxzZVxyXG4gICAgICAgICAgICAvLyBwb3NpdGl2ZSBpZiB0aGUgaXRlbSBpcyBhIHJlZ3VsYXIgZmlsZSBhbmQgbm90IGEgZGlyZWN0b3J5XHJcbiAgICAgICAgICAgIHZhciBpc01hdGNoID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGlmIChwYXR0ZXJuUmVnZXgudGVzdChub3JtYWxpemVkUGF0aCkgfHwgKGluY2x1ZGVEaXJlY3RvcmllcyAmJiBwYXR0ZXJuUmVnZXgudGVzdChhbHRlcm5hdGVQYXRoKSkpIHtcclxuICAgICAgICAgICAgICAgIGlzTWF0Y2ggPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgLy8gdGVzdCB3aGV0aGVyIHRoZSBwYXRoIHNob3VsZCBiZSBleGNsdWRlZFxyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBleGNsdWRlUGF0dGVybnNfMiA9IGV4Y2x1ZGVQYXR0ZXJuczsgX2kgPCBleGNsdWRlUGF0dGVybnNfMi5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVnZXggPSBleGNsdWRlUGF0dGVybnNfMltfaV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlZ2V4LnRlc3Qobm9ybWFsaXplZFBhdGgpIHx8IChpbmNsdWRlRGlyZWN0b3JpZXMgJiYgcmVnZXgudGVzdChhbHRlcm5hdGVQYXRoKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaXNNYXRjaCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGlzTWF0Y2gpIHtcclxuICAgICAgICAgICAgICAgIGFsbEZpbGVzW2l0ZW1dID0gaXRlbTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIGZvciAodmFyIF9iID0gMCwgaW5jbHVkZVBhdHRlcm5zXzIgPSBpbmNsdWRlUGF0dGVybnM7IF9iIDwgaW5jbHVkZVBhdHRlcm5zXzIubGVuZ3RoOyBfYisrKSB7XHJcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBpbmNsdWRlUGF0dGVybnNfMltfYl07XHJcbiAgICAgICAgX2xvb3BfMihwYXR0ZXJuKTtcclxuICAgIH1cclxuICAgIHJldHVybiBPYmplY3Qua2V5cyhhbGxGaWxlcykuc29ydCgpO1xyXG59XHJcbi8qKlxyXG4gKiBSZW1vdmUgYSBwYXRoIHJlY3Vyc2l2ZWx5IHdpdGggZm9yY2VcclxuICpcclxuICogQHBhcmFtICAgICBpbnB1dFBhdGggcGF0aCB0byByZW1vdmVcclxuICogQHRocm93cyAgICB3aGVuIHRoZSBmaWxlIG9yIGRpcmVjdG9yeSBleGlzdHMgYnV0IGNvdWxkIG5vdCBiZSBkZWxldGVkLlxyXG4gKi9cclxuZnVuY3Rpb24gcm1SRihpbnB1dFBhdGgpIHtcclxuICAgIGV4cG9ydHMuZGVidWcoJ3JtIC1yZiAnICsgaW5wdXRQYXRoKTtcclxuICAgIGlmIChnZXRQbGF0Zm9ybSgpID09IFBsYXRmb3JtLldpbmRvd3MpIHtcclxuICAgICAgICAvLyBOb2RlIGRvZXNuJ3QgcHJvdmlkZSBhIGRlbGV0ZSBvcGVyYXRpb24sIG9ubHkgYW4gdW5saW5rIGZ1bmN0aW9uLiBUaGlzIG1lYW5zIHRoYXQgaWYgdGhlIGZpbGUgaXMgYmVpbmcgdXNlZCBieSBhbm90aGVyXHJcbiAgICAgICAgLy8gcHJvZ3JhbSAoZS5nLiBhbnRpdmlydXMpLCBpdCB3b24ndCBiZSBkZWxldGVkLiBUbyBhZGRyZXNzIHRoaXMsIHdlIHNoZWxsIG91dCB0aGUgd29yayB0byByZC9kZWwuXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGZzLnN0YXRTeW5jKGlucHV0UGF0aCkuaXNEaXJlY3RvcnkoKSkge1xyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZygncmVtb3ZpbmcgZGlyZWN0b3J5ICcgKyBpbnB1dFBhdGgpO1xyXG4gICAgICAgICAgICAgICAgY2hpbGRQcm9jZXNzLmV4ZWNTeW5jKFwicmQgL3MgL3EgXFxcIlwiICsgaW5wdXRQYXRoICsgXCJcXFwiXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZygncmVtb3ZpbmcgZmlsZSAnICsgaW5wdXRQYXRoKTtcclxuICAgICAgICAgICAgICAgIGNoaWxkUHJvY2Vzcy5leGVjU3luYyhcImRlbCAvZiAvYSBcXFwiXCIgKyBpbnB1dFBhdGggKyBcIlxcXCJcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAvLyBpZiB5b3UgdHJ5IHRvIGRlbGV0ZSBhIGZpbGUgdGhhdCBkb2Vzbid0IGV4aXN0LCBkZXNpcmVkIHJlc3VsdCBpcyBhY2hpZXZlZFxyXG4gICAgICAgICAgICAvLyBvdGhlciBlcnJvcnMgYXJlIHZhbGlkXHJcbiAgICAgICAgICAgIGlmIChlcnIuY29kZSAhPSAnRU5PRU5UJykge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfT3BlcmF0aW9uRmFpbGVkJywgJ3JtUkYnLCBlcnIubWVzc2FnZSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIFNoZWxsaW5nIG91dCBmYWlscyB0byByZW1vdmUgYSBzeW1saW5rIGZvbGRlciB3aXRoIG1pc3Npbmcgc291cmNlLCB0aGlzIHVubGluayBjYXRjaGVzIHRoYXRcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBmcy51bmxpbmtTeW5jKGlucHV0UGF0aCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgLy8gaWYgeW91IHRyeSB0byBkZWxldGUgYSBmaWxlIHRoYXQgZG9lc24ndCBleGlzdCwgZGVzaXJlZCByZXN1bHQgaXMgYWNoaWV2ZWRcclxuICAgICAgICAgICAgLy8gb3RoZXIgZXJyb3JzIGFyZSB2YWxpZFxyXG4gICAgICAgICAgICBpZiAoZXJyLmNvZGUgIT0gJ0VOT0VOVCcpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmxvYygnTElCX09wZXJhdGlvbkZhaWxlZCcsICdybVJGJywgZXJyLm1lc3NhZ2UpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIC8vIGdldCB0aGUgbHN0YXRzIGluIG9yZGVyIHRvIHdvcmthcm91bmQgYSBidWcgaW4gc2hlbGxqc0AwLjMuMCB3aGVyZSBzeW1saW5rc1xyXG4gICAgICAgIC8vIHdpdGggbWlzc2luZyB0YXJnZXRzIGFyZSBub3QgaGFuZGxlZCBjb3JyZWN0bHkgYnkgXCJybSgnLXJmJywgcGF0aClcIlxyXG4gICAgICAgIHZhciBsc3RhdHMgPSB2b2lkIDA7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgbHN0YXRzID0gZnMubHN0YXRTeW5jKGlucHV0UGF0aCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgLy8gaWYgeW91IHRyeSB0byBkZWxldGUgYSBmaWxlIHRoYXQgZG9lc24ndCBleGlzdCwgZGVzaXJlZCByZXN1bHQgaXMgYWNoaWV2ZWRcclxuICAgICAgICAgICAgLy8gb3RoZXIgZXJyb3JzIGFyZSB2YWxpZFxyXG4gICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT0gJ0VOT0VOVCcpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9PcGVyYXRpb25GYWlsZWQnLCAncm1SRicsIGVyci5tZXNzYWdlKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChsc3RhdHMuaXNEaXJlY3RvcnkoKSkge1xyXG4gICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdyZW1vdmluZyBkaXJlY3RvcnknKTtcclxuICAgICAgICAgICAgc2hlbGwucm0oJy1yZicsIGlucHV0UGF0aCk7XHJcbiAgICAgICAgICAgIHZhciBlcnJNc2cgPSBzaGVsbC5lcnJvcigpO1xyXG4gICAgICAgICAgICBpZiAoZXJyTXNnKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9PcGVyYXRpb25GYWlsZWQnLCAncm1SRicsIGVyck1zZykpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZXhwb3J0cy5kZWJ1ZygncmVtb3ZpbmcgZmlsZScpO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGZzLnVubGlua1N5bmMoaW5wdXRQYXRoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9PcGVyYXRpb25GYWlsZWQnLCAncm1SRicsIGVyci5tZXNzYWdlKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMucm1SRiA9IHJtUkY7XHJcbi8qKlxyXG4gKiBFeGVjIGEgdG9vbC4gIENvbnZlbmllbmNlIHdyYXBwZXIgb3ZlciBUb29sUnVubmVyIHRvIGV4ZWMgd2l0aCBhcmdzIGluIG9uZSBjYWxsLlxyXG4gKiBPdXRwdXQgd2lsbCBiZSBzdHJlYW1lZCB0byB0aGUgbGl2ZSBjb25zb2xlLlxyXG4gKiBSZXR1cm5zIHByb21pc2Ugd2l0aCByZXR1cm4gY29kZVxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHRvb2wgICAgIHBhdGggdG8gdG9vbCB0byBleGVjXHJcbiAqIEBwYXJhbSAgICAgYXJncyAgICAgYW4gYXJnIHN0cmluZyBvciBhcnJheSBvZiBhcmdzXHJcbiAqIEBwYXJhbSAgICAgb3B0aW9ucyAgb3B0aW9uYWwgZXhlYyBvcHRpb25zLiAgU2VlIElFeGVjT3B0aW9uc1xyXG4gKiBAcmV0dXJucyAgIG51bWJlclxyXG4gKi9cclxuZnVuY3Rpb24gZXhlYyh0b29sLCBhcmdzLCBvcHRpb25zKSB7XHJcbiAgICB2YXIgdHIgPSB0aGlzLnRvb2wodG9vbCk7XHJcbiAgICB0ci5vbignZGVidWcnLCBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgIGV4cG9ydHMuZGVidWcoZGF0YSk7XHJcbiAgICB9KTtcclxuICAgIGlmIChhcmdzKSB7XHJcbiAgICAgICAgaWYgKGFyZ3MgaW5zdGFuY2VvZiBBcnJheSkge1xyXG4gICAgICAgICAgICB0ci5hcmcoYXJncyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiAoYXJncykgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIHRyLmxpbmUoYXJncyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRyLmV4ZWMob3B0aW9ucyk7XHJcbn1cclxuZXhwb3J0cy5leGVjID0gZXhlYztcclxuLyoqXHJcbiAqIEV4ZWMgYSB0b29sIHN5bmNocm9ub3VzbHkuICBDb252ZW5pZW5jZSB3cmFwcGVyIG92ZXIgVG9vbFJ1bm5lciB0byBleGVjU3luYyB3aXRoIGFyZ3MgaW4gb25lIGNhbGwuXHJcbiAqIE91dHB1dCB3aWxsIGJlICpub3QqIGJlIHN0cmVhbWVkIHRvIHRoZSBsaXZlIGNvbnNvbGUuICBJdCB3aWxsIGJlIHJldHVybmVkIGFmdGVyIGV4ZWN1dGlvbiBpcyBjb21wbGV0ZS5cclxuICogQXBwcm9wcmlhdGUgZm9yIHNob3J0IHJ1bm5pbmcgdG9vbHNcclxuICogUmV0dXJucyBJRXhlY1Jlc3VsdCB3aXRoIG91dHB1dCBhbmQgcmV0dXJuIGNvZGVcclxuICpcclxuICogQHBhcmFtICAgICB0b29sICAgICBwYXRoIHRvIHRvb2wgdG8gZXhlY1xyXG4gKiBAcGFyYW0gICAgIGFyZ3MgICAgIGFuIGFyZyBzdHJpbmcgb3IgYXJyYXkgb2YgYXJnc1xyXG4gKiBAcGFyYW0gICAgIG9wdGlvbnMgIG9wdGlvbmFsIGV4ZWMgb3B0aW9ucy4gIFNlZSBJRXhlY1N5bmNPcHRpb25zXHJcbiAqIEByZXR1cm5zICAgSUV4ZWNTeW5jUmVzdWx0XHJcbiAqL1xyXG5mdW5jdGlvbiBleGVjU3luYyh0b29sLCBhcmdzLCBvcHRpb25zKSB7XHJcbiAgICB2YXIgdHIgPSB0aGlzLnRvb2wodG9vbCk7XHJcbiAgICB0ci5vbignZGVidWcnLCBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgIGV4cG9ydHMuZGVidWcoZGF0YSk7XHJcbiAgICB9KTtcclxuICAgIGlmIChhcmdzKSB7XHJcbiAgICAgICAgaWYgKGFyZ3MgaW5zdGFuY2VvZiBBcnJheSkge1xyXG4gICAgICAgICAgICB0ci5hcmcoYXJncyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiAoYXJncykgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIHRyLmxpbmUoYXJncyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRyLmV4ZWNTeW5jKG9wdGlvbnMpO1xyXG59XHJcbmV4cG9ydHMuZXhlY1N5bmMgPSBleGVjU3luYztcclxuLyoqXHJcbiAqIENvbnZlbmllbmNlIGZhY3RvcnkgdG8gY3JlYXRlIGEgVG9vbFJ1bm5lci5cclxuICpcclxuICogQHBhcmFtICAgICB0b29sICAgICBwYXRoIHRvIHRvb2wgdG8gZXhlY1xyXG4gKiBAcmV0dXJucyAgIFRvb2xSdW5uZXJcclxuICovXHJcbmZ1bmN0aW9uIHRvb2wodG9vbCkge1xyXG4gICAgdmFyIHRyID0gbmV3IHRybS5Ub29sUnVubmVyKHRvb2wpO1xyXG4gICAgdHIub24oJ2RlYnVnJywgZnVuY3Rpb24gKG1lc3NhZ2UpIHtcclxuICAgICAgICBleHBvcnRzLmRlYnVnKG1lc3NhZ2UpO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gdHI7XHJcbn1cclxuZXhwb3J0cy50b29sID0gdG9vbDtcclxuLyoqXHJcbiAqIEFwcGxpZXMgZ2xvYiBwYXR0ZXJucyB0byBhIGxpc3Qgb2YgcGF0aHMuIFN1cHBvcnRzIGludGVybGVhdmVkIGV4Y2x1ZGUgcGF0dGVybnMuXHJcbiAqXHJcbiAqIEBwYXJhbSAgbGlzdCAgICAgICAgIGFycmF5IG9mIHBhdGhzXHJcbiAqIEBwYXJhbSAgcGF0dGVybnMgICAgIHBhdHRlcm5zIHRvIGFwcGx5LiBzdXBwb3J0cyBpbnRlcmxlYXZlZCBleGNsdWRlIHBhdHRlcm5zLlxyXG4gKiBAcGFyYW0gIHBhdHRlcm5Sb290ICBvcHRpb25hbC4gZGVmYXVsdCByb290IHRvIGFwcGx5IHRvIHVucm9vdGVkIHBhdHRlcm5zLiBub3QgYXBwbGllZCB0byBiYXNlbmFtZS1vbmx5IHBhdHRlcm5zIHdoZW4gbWF0Y2hCYXNlOnRydWUuXHJcbiAqIEBwYXJhbSAgb3B0aW9ucyAgICAgIG9wdGlvbmFsLiBkZWZhdWx0cyB0byB7IGRvdDogdHJ1ZSwgbm9icmFjZTogdHJ1ZSwgbm9jYXNlOiBwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgfS5cclxuICovXHJcbmZ1bmN0aW9uIG1hdGNoKGxpc3QsIHBhdHRlcm5zLCBwYXR0ZXJuUm9vdCwgb3B0aW9ucykge1xyXG4gICAgLy8gdHJhY2UgcGFyYW1ldGVyc1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcInBhdHRlcm5Sb290OiAnXCIgKyBwYXR0ZXJuUm9vdCArIFwiJ1wiKTtcclxuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IF9nZXREZWZhdWx0TWF0Y2hPcHRpb25zKCk7IC8vIGRlZmF1bHQgbWF0Y2ggb3B0aW9uc1xyXG4gICAgX2RlYnVnTWF0Y2hPcHRpb25zKG9wdGlvbnMpO1xyXG4gICAgLy8gY29udmVydCBwYXR0ZXJuIHRvIGFuIGFycmF5XHJcbiAgICBpZiAodHlwZW9mIHBhdHRlcm5zID09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgcGF0dGVybnMgPSBbcGF0dGVybnNdO1xyXG4gICAgfVxyXG4gICAgLy8gaGFzaHRhYmxlIHRvIGtlZXAgdHJhY2sgb2YgbWF0Y2hlc1xyXG4gICAgdmFyIG1hcCA9IHt9O1xyXG4gICAgdmFyIG9yaWdpbmFsT3B0aW9ucyA9IG9wdGlvbnM7XHJcbiAgICBmb3IgKHZhciBfaSA9IDAsIHBhdHRlcm5zXzEgPSBwYXR0ZXJuczsgX2kgPCBwYXR0ZXJuc18xLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgIHZhciBwYXR0ZXJuID0gcGF0dGVybnNfMVtfaV07XHJcbiAgICAgICAgZXhwb3J0cy5kZWJ1ZyhcInBhdHRlcm46ICdcIiArIHBhdHRlcm4gKyBcIidcIik7XHJcbiAgICAgICAgLy8gdHJpbSBhbmQgc2tpcCBlbXB0eVxyXG4gICAgICAgIHBhdHRlcm4gPSAocGF0dGVybiB8fCAnJykudHJpbSgpO1xyXG4gICAgICAgIGlmICghcGF0dGVybikge1xyXG4gICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdza2lwcGluZyBlbXB0eSBwYXR0ZXJuJyk7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBjbG9uZSBtYXRjaCBvcHRpb25zXHJcbiAgICAgICAgdmFyIG9wdGlvbnNfMSA9IGltLl9jbG9uZU1hdGNoT3B0aW9ucyhvcmlnaW5hbE9wdGlvbnMpO1xyXG4gICAgICAgIC8vIHNraXAgY29tbWVudHNcclxuICAgICAgICBpZiAoIW9wdGlvbnNfMS5ub2NvbW1lbnQgJiYgaW0uX3N0YXJ0c1dpdGgocGF0dGVybiwgJyMnKSkge1xyXG4gICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdza2lwcGluZyBjb21tZW50Jyk7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBzZXQgbm9jb21tZW50IC0gYnJhY2UgZXhwYW5zaW9uIGNvdWxkIHJlc3VsdCBpbiBhIGxlYWRpbmcgJyMnXHJcbiAgICAgICAgb3B0aW9uc18xLm5vY29tbWVudCA9IHRydWU7XHJcbiAgICAgICAgLy8gZGV0ZXJtaW5lIHdoZXRoZXIgcGF0dGVybiBpcyBpbmNsdWRlIG9yIGV4Y2x1ZGVcclxuICAgICAgICB2YXIgbmVnYXRlQ291bnQgPSAwO1xyXG4gICAgICAgIGlmICghb3B0aW9uc18xLm5vbmVnYXRlKSB7XHJcbiAgICAgICAgICAgIHdoaWxlIChwYXR0ZXJuLmNoYXJBdChuZWdhdGVDb3VudCkgPT0gJyEnKSB7XHJcbiAgICAgICAgICAgICAgICBuZWdhdGVDb3VudCsrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHBhdHRlcm4gPSBwYXR0ZXJuLnN1YnN0cmluZyhuZWdhdGVDb3VudCk7IC8vIHRyaW0gbGVhZGluZyAnISdcclxuICAgICAgICAgICAgaWYgKG5lZ2F0ZUNvdW50KSB7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKFwidHJpbW1lZCBsZWFkaW5nICchJy4gcGF0dGVybjogJ1wiICsgcGF0dGVybiArIFwiJ1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgaXNJbmNsdWRlUGF0dGVybiA9IG5lZ2F0ZUNvdW50ID09IDAgfHxcclxuICAgICAgICAgICAgKG5lZ2F0ZUNvdW50ICUgMiA9PSAwICYmICFvcHRpb25zXzEuZmxpcE5lZ2F0ZSkgfHxcclxuICAgICAgICAgICAgKG5lZ2F0ZUNvdW50ICUgMiA9PSAxICYmIG9wdGlvbnNfMS5mbGlwTmVnYXRlKTtcclxuICAgICAgICAvLyBzZXQgbm9uZWdhdGUgLSBicmFjZSBleHBhbnNpb24gY291bGQgcmVzdWx0IGluIGEgbGVhZGluZyAnISdcclxuICAgICAgICBvcHRpb25zXzEubm9uZWdhdGUgPSB0cnVlO1xyXG4gICAgICAgIG9wdGlvbnNfMS5mbGlwTmVnYXRlID0gZmFsc2U7XHJcbiAgICAgICAgLy8gZXhwYW5kIGJyYWNlcyAtIHJlcXVpcmVkIHRvIGFjY3VyYXRlbHkgcm9vdCBwYXR0ZXJuc1xyXG4gICAgICAgIHZhciBleHBhbmRlZCA9IHZvaWQgMDtcclxuICAgICAgICB2YXIgcHJlRXhwYW5kZWQgPSBwYXR0ZXJuO1xyXG4gICAgICAgIGlmIChvcHRpb25zXzEubm9icmFjZSkge1xyXG4gICAgICAgICAgICBleHBhbmRlZCA9IFtwYXR0ZXJuXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIGNvbnZlcnQgc2xhc2hlcyBvbiBXaW5kb3dzIGJlZm9yZSBjYWxsaW5nIGJyYWNlRXhwYW5kKCkuIHVuZm9ydHVuYXRlbHkgdGhpcyBtZWFucyBicmFjZXMgY2Fubm90XHJcbiAgICAgICAgICAgIC8vIGJlIGVzY2FwZWQgb24gV2luZG93cywgdGhpcyBsaW1pdGF0aW9uIGlzIGNvbnNpc3RlbnQgd2l0aCBjdXJyZW50IGxpbWl0YXRpb25zIG9mIG1pbmltYXRjaCAoMy4wLjMpLlxyXG4gICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdleHBhbmRpbmcgYnJhY2VzJyk7XHJcbiAgICAgICAgICAgIHZhciBjb252ZXJ0ZWRQYXR0ZXJuID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gcGF0dGVybi5yZXBsYWNlKC9cXFxcL2csICcvJykgOiBwYXR0ZXJuO1xyXG4gICAgICAgICAgICBleHBhbmRlZCA9IG1pbmltYXRjaC5icmFjZUV4cGFuZChjb252ZXJ0ZWRQYXR0ZXJuKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gc2V0IG5vYnJhY2VcclxuICAgICAgICBvcHRpb25zXzEubm9icmFjZSA9IHRydWU7XHJcbiAgICAgICAgZm9yICh2YXIgX2EgPSAwLCBleHBhbmRlZF8xID0gZXhwYW5kZWQ7IF9hIDwgZXhwYW5kZWRfMS5sZW5ndGg7IF9hKyspIHtcclxuICAgICAgICAgICAgdmFyIHBhdHRlcm5fMSA9IGV4cGFuZGVkXzFbX2FdO1xyXG4gICAgICAgICAgICBpZiAoZXhwYW5kZWQubGVuZ3RoICE9IDEgfHwgcGF0dGVybl8xICE9IHByZUV4cGFuZGVkKSB7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKFwicGF0dGVybjogJ1wiICsgcGF0dGVybl8xICsgXCInXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIHRyaW0gYW5kIHNraXAgZW1wdHlcclxuICAgICAgICAgICAgcGF0dGVybl8xID0gKHBhdHRlcm5fMSB8fCAnJykudHJpbSgpO1xyXG4gICAgICAgICAgICBpZiAoIXBhdHRlcm5fMSkge1xyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1Zygnc2tpcHBpbmcgZW1wdHkgcGF0dGVybicpO1xyXG4gICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gcm9vdCB0aGUgcGF0dGVybiB3aGVuIGFsbCBvZiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIHRydWU6XHJcbiAgICAgICAgICAgIGlmIChwYXR0ZXJuUm9vdCAmJiAvLyBwYXR0ZXJuUm9vdCBzdXBwbGllZFxyXG4gICAgICAgICAgICAgICAgIWltLl9pc1Jvb3RlZChwYXR0ZXJuXzEpICYmIC8vIEFORCBwYXR0ZXJuIG5vdCByb290ZWRcclxuICAgICAgICAgICAgICAgIC8vIEFORCBtYXRjaEJhc2U6ZmFsc2Ugb3Igbm90IGJhc2VuYW1lIG9ubHlcclxuICAgICAgICAgICAgICAgICghb3B0aW9uc18xLm1hdGNoQmFzZSB8fCAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gcGF0dGVybl8xLnJlcGxhY2UoL1xcXFwvZywgJy8nKSA6IHBhdHRlcm5fMSkuaW5kZXhPZignLycpID49IDApKSB7XHJcbiAgICAgICAgICAgICAgICBwYXR0ZXJuXzEgPSBpbS5fZW5zdXJlUm9vdGVkKHBhdHRlcm5Sb290LCBwYXR0ZXJuXzEpO1xyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZyhcInJvb3RlZCBwYXR0ZXJuOiAnXCIgKyBwYXR0ZXJuXzEgKyBcIidcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGlzSW5jbHVkZVBhdHRlcm4pIHtcclxuICAgICAgICAgICAgICAgIC8vIGFwcGx5IHRoZSBwYXR0ZXJuXHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdhcHBseWluZyBpbmNsdWRlIHBhdHRlcm4gYWdhaW5zdCBvcmlnaW5hbCBsaXN0Jyk7XHJcbiAgICAgICAgICAgICAgICB2YXIgbWF0Y2hSZXN1bHRzID0gbWluaW1hdGNoLm1hdGNoKGxpc3QsIHBhdHRlcm5fMSwgb3B0aW9uc18xKTtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcobWF0Y2hSZXN1bHRzLmxlbmd0aCArICcgbWF0Y2hlcycpO1xyXG4gICAgICAgICAgICAgICAgLy8gdW5pb24gdGhlIHJlc3VsdHNcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIF9iID0gMCwgbWF0Y2hSZXN1bHRzXzEgPSBtYXRjaFJlc3VsdHM7IF9iIDwgbWF0Y2hSZXN1bHRzXzEubGVuZ3RoOyBfYisrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1hdGNoUmVzdWx0ID0gbWF0Y2hSZXN1bHRzXzFbX2JdO1xyXG4gICAgICAgICAgICAgICAgICAgIG1hcFttYXRjaFJlc3VsdF0gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gYXBwbHkgdGhlIHBhdHRlcm5cclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ2FwcGx5aW5nIGV4Y2x1ZGUgcGF0dGVybiBhZ2FpbnN0IG9yaWdpbmFsIGxpc3QnKTtcclxuICAgICAgICAgICAgICAgIHZhciBtYXRjaFJlc3VsdHMgPSBtaW5pbWF0Y2gubWF0Y2gobGlzdCwgcGF0dGVybl8xLCBvcHRpb25zXzEpO1xyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZyhtYXRjaFJlc3VsdHMubGVuZ3RoICsgJyBtYXRjaGVzJyk7XHJcbiAgICAgICAgICAgICAgICAvLyBzdWJzdHJhY3QgdGhlIHJlc3VsdHNcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIF9jID0gMCwgbWF0Y2hSZXN1bHRzXzIgPSBtYXRjaFJlc3VsdHM7IF9jIDwgbWF0Y2hSZXN1bHRzXzIubGVuZ3RoOyBfYysrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1hdGNoUmVzdWx0ID0gbWF0Y2hSZXN1bHRzXzJbX2NdO1xyXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBtYXBbbWF0Y2hSZXN1bHRdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gcmV0dXJuIGEgZmlsdGVyZWQgdmVyc2lvbiBvZiB0aGUgb3JpZ2luYWwgbGlzdCAocHJlc2VydmVzIG9yZGVyIGFuZCBwcmV2ZW50cyBkdXBsaWNhdGlvbilcclxuICAgIHZhciByZXN1bHQgPSBsaXN0LmZpbHRlcihmdW5jdGlvbiAoaXRlbSkgeyByZXR1cm4gbWFwLmhhc093blByb3BlcnR5KGl0ZW0pOyB9KTtcclxuICAgIGV4cG9ydHMuZGVidWcocmVzdWx0Lmxlbmd0aCArICcgZmluYWwgcmVzdWx0cycpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5leHBvcnRzLm1hdGNoID0gbWF0Y2g7XHJcbi8qKlxyXG4gKiBGaWx0ZXIgdG8gYXBwbHkgZ2xvYiBwYXR0ZXJuc1xyXG4gKlxyXG4gKiBAcGFyYW0gIHBhdHRlcm4gIHBhdHRlcm4gdG8gYXBwbHlcclxuICogQHBhcmFtICBvcHRpb25zICBvcHRpb25hbC4gZGVmYXVsdHMgdG8geyBkb3Q6IHRydWUsIG5vYnJhY2U6IHRydWUsIG5vY2FzZTogcHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInIH0uXHJcbiAqL1xyXG5mdW5jdGlvbiBmaWx0ZXIocGF0dGVybiwgb3B0aW9ucykge1xyXG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwgX2dldERlZmF1bHRNYXRjaE9wdGlvbnMoKTtcclxuICAgIHJldHVybiBtaW5pbWF0Y2guZmlsdGVyKHBhdHRlcm4sIG9wdGlvbnMpO1xyXG59XHJcbmV4cG9ydHMuZmlsdGVyID0gZmlsdGVyO1xyXG5mdW5jdGlvbiBfZGVidWdNYXRjaE9wdGlvbnMob3B0aW9ucykge1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcIm1hdGNoT3B0aW9ucy5kZWJ1ZzogJ1wiICsgb3B0aW9ucy5kZWJ1ZyArIFwiJ1wiKTtcclxuICAgIGV4cG9ydHMuZGVidWcoXCJtYXRjaE9wdGlvbnMubm9icmFjZTogJ1wiICsgb3B0aW9ucy5ub2JyYWNlICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcIm1hdGNoT3B0aW9ucy5ub2dsb2JzdGFyOiAnXCIgKyBvcHRpb25zLm5vZ2xvYnN0YXIgKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwibWF0Y2hPcHRpb25zLmRvdDogJ1wiICsgb3B0aW9ucy5kb3QgKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwibWF0Y2hPcHRpb25zLm5vZXh0OiAnXCIgKyBvcHRpb25zLm5vZXh0ICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcIm1hdGNoT3B0aW9ucy5ub2Nhc2U6ICdcIiArIG9wdGlvbnMubm9jYXNlICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcIm1hdGNoT3B0aW9ucy5ub251bGw6ICdcIiArIG9wdGlvbnMubm9udWxsICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcIm1hdGNoT3B0aW9ucy5tYXRjaEJhc2U6ICdcIiArIG9wdGlvbnMubWF0Y2hCYXNlICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcIm1hdGNoT3B0aW9ucy5ub2NvbW1lbnQ6ICdcIiArIG9wdGlvbnMubm9jb21tZW50ICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcIm1hdGNoT3B0aW9ucy5ub25lZ2F0ZTogJ1wiICsgb3B0aW9ucy5ub25lZ2F0ZSArIFwiJ1wiKTtcclxuICAgIGV4cG9ydHMuZGVidWcoXCJtYXRjaE9wdGlvbnMuZmxpcE5lZ2F0ZTogJ1wiICsgb3B0aW9ucy5mbGlwTmVnYXRlICsgXCInXCIpO1xyXG59XHJcbmZ1bmN0aW9uIF9nZXREZWZhdWx0TWF0Y2hPcHRpb25zKCkge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBkZWJ1ZzogZmFsc2UsXHJcbiAgICAgICAgbm9icmFjZTogdHJ1ZSxcclxuICAgICAgICBub2dsb2JzdGFyOiBmYWxzZSxcclxuICAgICAgICBkb3Q6IHRydWUsXHJcbiAgICAgICAgbm9leHQ6IGZhbHNlLFxyXG4gICAgICAgIG5vY2FzZTogcHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInLFxyXG4gICAgICAgIG5vbnVsbDogZmFsc2UsXHJcbiAgICAgICAgbWF0Y2hCYXNlOiBmYWxzZSxcclxuICAgICAgICBub2NvbW1lbnQ6IGZhbHNlLFxyXG4gICAgICAgIG5vbmVnYXRlOiBmYWxzZSxcclxuICAgICAgICBmbGlwTmVnYXRlOiBmYWxzZVxyXG4gICAgfTtcclxufVxyXG4vKipcclxuICogRGV0ZXJtaW5lcyB0aGUgZmluZCByb290IGZyb20gYSBsaXN0IG9mIHBhdHRlcm5zLiBQZXJmb3JtcyB0aGUgZmluZCBhbmQgdGhlbiBhcHBsaWVzIHRoZSBnbG9iIHBhdHRlcm5zLlxyXG4gKiBTdXBwb3J0cyBpbnRlcmxlYXZlZCBleGNsdWRlIHBhdHRlcm5zLiBVbnJvb3RlZCBwYXR0ZXJucyBhcmUgcm9vdGVkIHVzaW5nIGRlZmF1bHRSb290LCB1bmxlc3NcclxuICogbWF0Y2hPcHRpb25zLm1hdGNoQmFzZSBpcyBzcGVjaWZpZWQgYW5kIHRoZSBwYXR0ZXJuIGlzIGEgYmFzZW5hbWUgb25seS4gRm9yIG1hdGNoQmFzZSBjYXNlcywgdGhlXHJcbiAqIGRlZmF1bHRSb290IGlzIHVzZWQgYXMgdGhlIGZpbmQgcm9vdC5cclxuICpcclxuICogQHBhcmFtICBkZWZhdWx0Um9vdCAgIGRlZmF1bHQgcGF0aCB0byByb290IHVucm9vdGVkIHBhdHRlcm5zLiBmYWxscyBiYWNrIHRvIFN5c3RlbS5EZWZhdWx0V29ya2luZ0RpcmVjdG9yeSBvciBwcm9jZXNzLmN3ZCgpLlxyXG4gKiBAcGFyYW0gIHBhdHRlcm5zICAgICAgcGF0dGVybiBvciBhcnJheSBvZiBwYXR0ZXJucyB0byBhcHBseVxyXG4gKiBAcGFyYW0gIGZpbmRPcHRpb25zICAgZGVmYXVsdHMgdG8geyBmb2xsb3dTeW1ib2xpY0xpbmtzOiB0cnVlIH0uIGZvbGxvd2luZyBzb2Z0IGxpbmtzIGlzIGdlbmVyYWxseSBhcHByb3ByaWF0ZSB1bmxlc3MgZGVsZXRpbmcgZmlsZXMuXHJcbiAqIEBwYXJhbSAgbWF0Y2hPcHRpb25zICBkZWZhdWx0cyB0byB7IGRvdDogdHJ1ZSwgbm9icmFjZTogdHJ1ZSwgbm9jYXNlOiBwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgfVxyXG4gKi9cclxuZnVuY3Rpb24gZmluZE1hdGNoKGRlZmF1bHRSb290LCBwYXR0ZXJucywgZmluZE9wdGlvbnMsIG1hdGNoT3B0aW9ucykge1xyXG4gICAgLy8gYXBwbHkgZGVmYXVsdHMgZm9yIHBhcmFtZXRlcnMgYW5kIHRyYWNlXHJcbiAgICBkZWZhdWx0Um9vdCA9IGRlZmF1bHRSb290IHx8IHRoaXMuZ2V0VmFyaWFibGUoJ3N5c3RlbS5kZWZhdWx0V29ya2luZ0RpcmVjdG9yeScpIHx8IHByb2Nlc3MuY3dkKCk7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwiZGVmYXVsdFJvb3Q6ICdcIiArIGRlZmF1bHRSb290ICsgXCInXCIpO1xyXG4gICAgcGF0dGVybnMgPSBwYXR0ZXJucyB8fCBbXTtcclxuICAgIHBhdHRlcm5zID0gdHlwZW9mIHBhdHRlcm5zID09ICdzdHJpbmcnID8gW3BhdHRlcm5zXSA6IHBhdHRlcm5zO1xyXG4gICAgZmluZE9wdGlvbnMgPSBmaW5kT3B0aW9ucyB8fCBfZ2V0RGVmYXVsdEZpbmRPcHRpb25zKCk7XHJcbiAgICBfZGVidWdGaW5kT3B0aW9ucyhmaW5kT3B0aW9ucyk7XHJcbiAgICBtYXRjaE9wdGlvbnMgPSBtYXRjaE9wdGlvbnMgfHwgX2dldERlZmF1bHRNYXRjaE9wdGlvbnMoKTtcclxuICAgIF9kZWJ1Z01hdGNoT3B0aW9ucyhtYXRjaE9wdGlvbnMpO1xyXG4gICAgLy8gbm9ybWFsaXplIHNsYXNoZXMgZm9yIHJvb3QgZGlyXHJcbiAgICBkZWZhdWx0Um9vdCA9IGltLl9ub3JtYWxpemVTZXBhcmF0b3JzKGRlZmF1bHRSb290KTtcclxuICAgIHZhciByZXN1bHRzID0ge307XHJcbiAgICB2YXIgb3JpZ2luYWxNYXRjaE9wdGlvbnMgPSBtYXRjaE9wdGlvbnM7XHJcbiAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gKHBhdHRlcm5zIHx8IFtdKTsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICB2YXIgcGF0dGVybiA9IF9hW19pXTtcclxuICAgICAgICBleHBvcnRzLmRlYnVnKFwicGF0dGVybjogJ1wiICsgcGF0dGVybiArIFwiJ1wiKTtcclxuICAgICAgICAvLyB0cmltIGFuZCBza2lwIGVtcHR5XHJcbiAgICAgICAgcGF0dGVybiA9IChwYXR0ZXJuIHx8ICcnKS50cmltKCk7XHJcbiAgICAgICAgaWYgKCFwYXR0ZXJuKSB7XHJcbiAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ3NraXBwaW5nIGVtcHR5IHBhdHRlcm4nKTtcclxuICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGNsb25lIG1hdGNoIG9wdGlvbnNcclxuICAgICAgICB2YXIgbWF0Y2hPcHRpb25zXzEgPSBpbS5fY2xvbmVNYXRjaE9wdGlvbnMob3JpZ2luYWxNYXRjaE9wdGlvbnMpO1xyXG4gICAgICAgIC8vIHNraXAgY29tbWVudHNcclxuICAgICAgICBpZiAoIW1hdGNoT3B0aW9uc18xLm5vY29tbWVudCAmJiBpbS5fc3RhcnRzV2l0aChwYXR0ZXJuLCAnIycpKSB7XHJcbiAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ3NraXBwaW5nIGNvbW1lbnQnKTtcclxuICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHNldCBub2NvbW1lbnQgLSBicmFjZSBleHBhbnNpb24gY291bGQgcmVzdWx0IGluIGEgbGVhZGluZyAnIydcclxuICAgICAgICBtYXRjaE9wdGlvbnNfMS5ub2NvbW1lbnQgPSB0cnVlO1xyXG4gICAgICAgIC8vIGRldGVybWluZSB3aGV0aGVyIHBhdHRlcm4gaXMgaW5jbHVkZSBvciBleGNsdWRlXHJcbiAgICAgICAgdmFyIG5lZ2F0ZUNvdW50ID0gMDtcclxuICAgICAgICBpZiAoIW1hdGNoT3B0aW9uc18xLm5vbmVnYXRlKSB7XHJcbiAgICAgICAgICAgIHdoaWxlIChwYXR0ZXJuLmNoYXJBdChuZWdhdGVDb3VudCkgPT0gJyEnKSB7XHJcbiAgICAgICAgICAgICAgICBuZWdhdGVDb3VudCsrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHBhdHRlcm4gPSBwYXR0ZXJuLnN1YnN0cmluZyhuZWdhdGVDb3VudCk7IC8vIHRyaW0gbGVhZGluZyAnISdcclxuICAgICAgICAgICAgaWYgKG5lZ2F0ZUNvdW50KSB7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKFwidHJpbW1lZCBsZWFkaW5nICchJy4gcGF0dGVybjogJ1wiICsgcGF0dGVybiArIFwiJ1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgaXNJbmNsdWRlUGF0dGVybiA9IG5lZ2F0ZUNvdW50ID09IDAgfHxcclxuICAgICAgICAgICAgKG5lZ2F0ZUNvdW50ICUgMiA9PSAwICYmICFtYXRjaE9wdGlvbnNfMS5mbGlwTmVnYXRlKSB8fFxyXG4gICAgICAgICAgICAobmVnYXRlQ291bnQgJSAyID09IDEgJiYgbWF0Y2hPcHRpb25zXzEuZmxpcE5lZ2F0ZSk7XHJcbiAgICAgICAgLy8gc2V0IG5vbmVnYXRlIC0gYnJhY2UgZXhwYW5zaW9uIGNvdWxkIHJlc3VsdCBpbiBhIGxlYWRpbmcgJyEnXHJcbiAgICAgICAgbWF0Y2hPcHRpb25zXzEubm9uZWdhdGUgPSB0cnVlO1xyXG4gICAgICAgIG1hdGNoT3B0aW9uc18xLmZsaXBOZWdhdGUgPSBmYWxzZTtcclxuICAgICAgICAvLyBleHBhbmQgYnJhY2VzIC0gcmVxdWlyZWQgdG8gYWNjdXJhdGVseSBpbnRlcnByZXQgZmluZFBhdGhcclxuICAgICAgICB2YXIgZXhwYW5kZWQgPSB2b2lkIDA7XHJcbiAgICAgICAgdmFyIHByZUV4cGFuZGVkID0gcGF0dGVybjtcclxuICAgICAgICBpZiAobWF0Y2hPcHRpb25zXzEubm9icmFjZSkge1xyXG4gICAgICAgICAgICBleHBhbmRlZCA9IFtwYXR0ZXJuXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIGNvbnZlcnQgc2xhc2hlcyBvbiBXaW5kb3dzIGJlZm9yZSBjYWxsaW5nIGJyYWNlRXhwYW5kKCkuIHVuZm9ydHVuYXRlbHkgdGhpcyBtZWFucyBicmFjZXMgY2Fubm90XHJcbiAgICAgICAgICAgIC8vIGJlIGVzY2FwZWQgb24gV2luZG93cywgdGhpcyBsaW1pdGF0aW9uIGlzIGNvbnNpc3RlbnQgd2l0aCBjdXJyZW50IGxpbWl0YXRpb25zIG9mIG1pbmltYXRjaCAoMy4wLjMpLlxyXG4gICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdleHBhbmRpbmcgYnJhY2VzJyk7XHJcbiAgICAgICAgICAgIHZhciBjb252ZXJ0ZWRQYXR0ZXJuID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gcGF0dGVybi5yZXBsYWNlKC9cXFxcL2csICcvJykgOiBwYXR0ZXJuO1xyXG4gICAgICAgICAgICBleHBhbmRlZCA9IG1pbmltYXRjaC5icmFjZUV4cGFuZChjb252ZXJ0ZWRQYXR0ZXJuKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gc2V0IG5vYnJhY2VcclxuICAgICAgICBtYXRjaE9wdGlvbnNfMS5ub2JyYWNlID0gdHJ1ZTtcclxuICAgICAgICBmb3IgKHZhciBfYiA9IDAsIGV4cGFuZGVkXzIgPSBleHBhbmRlZDsgX2IgPCBleHBhbmRlZF8yLmxlbmd0aDsgX2IrKykge1xyXG4gICAgICAgICAgICB2YXIgcGF0dGVybl8yID0gZXhwYW5kZWRfMltfYl07XHJcbiAgICAgICAgICAgIGlmIChleHBhbmRlZC5sZW5ndGggIT0gMSB8fCBwYXR0ZXJuXzIgIT0gcHJlRXhwYW5kZWQpIHtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCJwYXR0ZXJuOiAnXCIgKyBwYXR0ZXJuXzIgKyBcIidcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gdHJpbSBhbmQgc2tpcCBlbXB0eVxyXG4gICAgICAgICAgICBwYXR0ZXJuXzIgPSAocGF0dGVybl8yIHx8ICcnKS50cmltKCk7XHJcbiAgICAgICAgICAgIGlmICghcGF0dGVybl8yKSB7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdza2lwcGluZyBlbXB0eSBwYXR0ZXJuJyk7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoaXNJbmNsdWRlUGF0dGVybikge1xyXG4gICAgICAgICAgICAgICAgLy8gZGV0ZXJtaW5lIHRoZSBmaW5kUGF0aFxyXG4gICAgICAgICAgICAgICAgdmFyIGZpbmRJbmZvID0gaW0uX2dldEZpbmRJbmZvRnJvbVBhdHRlcm4oZGVmYXVsdFJvb3QsIHBhdHRlcm5fMiwgbWF0Y2hPcHRpb25zXzEpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGZpbmRQYXRoID0gZmluZEluZm8uZmluZFBhdGg7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKFwiZmluZFBhdGg6ICdcIiArIGZpbmRQYXRoICsgXCInXCIpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFmaW5kUGF0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ3NraXBwaW5nIGVtcHR5IHBhdGgnKTtcclxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIHBlcmZvcm0gdGhlIGZpbmRcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCJzdGF0T25seTogJ1wiICsgZmluZEluZm8uc3RhdE9ubHkgKyBcIidcIik7XHJcbiAgICAgICAgICAgICAgICB2YXIgZmluZFJlc3VsdHMgPSBbXTtcclxuICAgICAgICAgICAgICAgIGlmIChmaW5kSW5mby5zdGF0T25seSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHNpbXBseSBzdGF0IHRoZSBwYXRoIC0gYWxsIHBhdGggc2VnbWVudHMgd2VyZSB1c2VkIHRvIGJ1aWxkIHRoZSBwYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZnMuc3RhdFN5bmMoZmluZFBhdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmaW5kUmVzdWx0cy5wdXNoKGZpbmRQYXRoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgIT0gJ0VOT0VOVCcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdFTk9FTlQnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBmaW5kUmVzdWx0cyA9IGZpbmQoZmluZFBhdGgsIGZpbmRPcHRpb25zKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCJmb3VuZCBcIiArIGZpbmRSZXN1bHRzLmxlbmd0aCArIFwiIHBhdGhzXCIpO1xyXG4gICAgICAgICAgICAgICAgLy8gYXBwbHkgdGhlIHBhdHRlcm5cclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ2FwcGx5aW5nIGluY2x1ZGUgcGF0dGVybicpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGZpbmRJbmZvLmFkanVzdGVkUGF0dGVybiAhPSBwYXR0ZXJuXzIpIHtcclxuICAgICAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKFwiYWRqdXN0ZWRQYXR0ZXJuOiAnXCIgKyBmaW5kSW5mby5hZGp1c3RlZFBhdHRlcm4gKyBcIidcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcGF0dGVybl8yID0gZmluZEluZm8uYWRqdXN0ZWRQYXR0ZXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdmFyIG1hdGNoUmVzdWx0cyA9IG1pbmltYXRjaC5tYXRjaChmaW5kUmVzdWx0cywgcGF0dGVybl8yLCBtYXRjaE9wdGlvbnNfMSk7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKG1hdGNoUmVzdWx0cy5sZW5ndGggKyAnIG1hdGNoZXMnKTtcclxuICAgICAgICAgICAgICAgIC8vIHVuaW9uIHRoZSByZXN1bHRzXHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBfYyA9IDAsIG1hdGNoUmVzdWx0c18zID0gbWF0Y2hSZXN1bHRzOyBfYyA8IG1hdGNoUmVzdWx0c18zLmxlbmd0aDsgX2MrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtYXRjaFJlc3VsdCA9IG1hdGNoUmVzdWx0c18zW19jXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIga2V5ID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gbWF0Y2hSZXN1bHQudG9VcHBlckNhc2UoKSA6IG1hdGNoUmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdHNba2V5XSA9IG1hdGNoUmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgYmFzZW5hbWUgb25seSBhbmQgbWF0Y2hCYXNlPXRydWVcclxuICAgICAgICAgICAgICAgIGlmIChtYXRjaE9wdGlvbnNfMS5tYXRjaEJhc2UgJiZcclxuICAgICAgICAgICAgICAgICAgICAhaW0uX2lzUm9vdGVkKHBhdHRlcm5fMikgJiZcclxuICAgICAgICAgICAgICAgICAgICAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gcGF0dGVybl8yLnJlcGxhY2UoL1xcXFwvZywgJy8nKSA6IHBhdHRlcm5fMikuaW5kZXhPZignLycpIDwgMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdCByb290IHRoZSBwYXR0ZXJuXHJcbiAgICAgICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZygnbWF0Y2hCYXNlIGFuZCBiYXNlbmFtZSBvbmx5Jyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyByb290IHRoZSBleGNsdWRlIHBhdHRlcm5cclxuICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuXzIgPSBpbS5fZW5zdXJlUGF0dGVyblJvb3RlZChkZWZhdWx0Um9vdCwgcGF0dGVybl8yKTtcclxuICAgICAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKFwiYWZ0ZXIgZW5zdXJlUGF0dGVyblJvb3RlZCwgcGF0dGVybjogJ1wiICsgcGF0dGVybl8yICsgXCInXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gYXBwbHkgdGhlIHBhdHRlcm5cclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ2FwcGx5aW5nIGV4Y2x1ZGUgcGF0dGVybicpO1xyXG4gICAgICAgICAgICAgICAgdmFyIG1hdGNoUmVzdWx0cyA9IG1pbmltYXRjaC5tYXRjaChPYmplY3Qua2V5cyhyZXN1bHRzKS5tYXAoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gcmVzdWx0c1trZXldOyB9KSwgcGF0dGVybl8yLCBtYXRjaE9wdGlvbnNfMSk7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKG1hdGNoUmVzdWx0cy5sZW5ndGggKyAnIG1hdGNoZXMnKTtcclxuICAgICAgICAgICAgICAgIC8vIHN1YnN0cmFjdCB0aGUgcmVzdWx0c1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgX2QgPSAwLCBtYXRjaFJlc3VsdHNfNCA9IG1hdGNoUmVzdWx0czsgX2QgPCBtYXRjaFJlc3VsdHNfNC5sZW5ndGg7IF9kKyspIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbWF0Y2hSZXN1bHQgPSBtYXRjaFJlc3VsdHNfNFtfZF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGtleSA9IHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyA/IG1hdGNoUmVzdWx0LnRvVXBwZXJDYXNlKCkgOiBtYXRjaFJlc3VsdDtcclxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgcmVzdWx0c1trZXldO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgdmFyIGZpbmFsUmVzdWx0ID0gT2JqZWN0LmtleXMocmVzdWx0cylcclxuICAgICAgICAubWFwKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIHJlc3VsdHNba2V5XTsgfSlcclxuICAgICAgICAuc29ydCgpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhmaW5hbFJlc3VsdC5sZW5ndGggKyAnIGZpbmFsIHJlc3VsdHMnKTtcclxuICAgIHJldHVybiBmaW5hbFJlc3VsdDtcclxufVxyXG5leHBvcnRzLmZpbmRNYXRjaCA9IGZpbmRNYXRjaDtcclxuLyoqXHJcbiAqIEdldHMgaHR0cCBwcm94eSBjb25maWd1cmF0aW9uIHVzZWQgYnkgQnVpbGQvUmVsZWFzZSBhZ2VudFxyXG4gKlxyXG4gKiBAcmV0dXJuICBQcm94eUNvbmZpZ3VyYXRpb25cclxuICovXHJcbmZ1bmN0aW9uIGdldEh0dHBQcm94eUNvbmZpZ3VyYXRpb24ocmVxdWVzdFVybCkge1xyXG4gICAgdmFyIHByb3h5VXJsID0gZXhwb3J0cy5nZXRWYXJpYWJsZSgnQWdlbnQuUHJveHlVcmwnKTtcclxuICAgIGlmIChwcm94eVVybCAmJiBwcm94eVVybC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgdmFyIHByb3h5VXNlcm5hbWUgPSBleHBvcnRzLmdldFZhcmlhYmxlKCdBZ2VudC5Qcm94eVVzZXJuYW1lJyk7XHJcbiAgICAgICAgdmFyIHByb3h5UGFzc3dvcmQgPSBleHBvcnRzLmdldFZhcmlhYmxlKCdBZ2VudC5Qcm94eVBhc3N3b3JkJyk7XHJcbiAgICAgICAgdmFyIHByb3h5QnlwYXNzSG9zdHMgPSBKU09OLnBhcnNlKGV4cG9ydHMuZ2V0VmFyaWFibGUoJ0FnZW50LlByb3h5QnlwYXNzTGlzdCcpIHx8ICdbXScpO1xyXG4gICAgICAgIHZhciBieXBhc3NfMSA9IGZhbHNlO1xyXG4gICAgICAgIGlmIChyZXF1ZXN0VXJsKSB7XHJcbiAgICAgICAgICAgIHByb3h5QnlwYXNzSG9zdHMuZm9yRWFjaChmdW5jdGlvbiAoYnlwYXNzSG9zdCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKG5ldyBSZWdFeHAoYnlwYXNzSG9zdCwgJ2knKS50ZXN0KHJlcXVlc3RVcmwpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYnlwYXNzXzEgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGJ5cGFzc18xKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIHByb3h5VXJsOiBwcm94eVVybCxcclxuICAgICAgICAgICAgICAgIHByb3h5VXNlcm5hbWU6IHByb3h5VXNlcm5hbWUsXHJcbiAgICAgICAgICAgICAgICBwcm94eVBhc3N3b3JkOiBwcm94eVBhc3N3b3JkLFxyXG4gICAgICAgICAgICAgICAgcHJveHlCeXBhc3NIb3N0czogcHJveHlCeXBhc3NIb3N0c1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMuZ2V0SHR0cFByb3h5Q29uZmlndXJhdGlvbiA9IGdldEh0dHBQcm94eUNvbmZpZ3VyYXRpb247XHJcbi8qKlxyXG4gKiBHZXRzIGh0dHAgY2VydGlmaWNhdGUgY29uZmlndXJhdGlvbiB1c2VkIGJ5IEJ1aWxkL1JlbGVhc2UgYWdlbnRcclxuICpcclxuICogQHJldHVybiAgQ2VydENvbmZpZ3VyYXRpb25cclxuICovXHJcbmZ1bmN0aW9uIGdldEh0dHBDZXJ0Q29uZmlndXJhdGlvbigpIHtcclxuICAgIHZhciBjYSA9IGV4cG9ydHMuZ2V0VmFyaWFibGUoJ0FnZW50LkNBSW5mbycpO1xyXG4gICAgdmFyIGNsaWVudENlcnQgPSBleHBvcnRzLmdldFZhcmlhYmxlKCdBZ2VudC5DbGllbnRDZXJ0Jyk7XHJcbiAgICBpZiAoY2EgfHwgY2xpZW50Q2VydCkge1xyXG4gICAgICAgIHZhciBjZXJ0Q29uZmlnID0ge307XHJcbiAgICAgICAgY2VydENvbmZpZy5jYUZpbGUgPSBjYTtcclxuICAgICAgICBjZXJ0Q29uZmlnLmNlcnRGaWxlID0gY2xpZW50Q2VydDtcclxuICAgICAgICBpZiAoY2xpZW50Q2VydCkge1xyXG4gICAgICAgICAgICB2YXIgY2xpZW50Q2VydEtleSA9IGV4cG9ydHMuZ2V0VmFyaWFibGUoJ0FnZW50LkNsaWVudENlcnRLZXknKTtcclxuICAgICAgICAgICAgdmFyIGNsaWVudENlcnRBcmNoaXZlID0gZXhwb3J0cy5nZXRWYXJpYWJsZSgnQWdlbnQuQ2xpZW50Q2VydEFyY2hpdmUnKTtcclxuICAgICAgICAgICAgdmFyIGNsaWVudENlcnRQYXNzd29yZCA9IGV4cG9ydHMuZ2V0VmFyaWFibGUoJ0FnZW50LkNsaWVudENlcnRQYXNzd29yZCcpO1xyXG4gICAgICAgICAgICBjZXJ0Q29uZmlnLmtleUZpbGUgPSBjbGllbnRDZXJ0S2V5O1xyXG4gICAgICAgICAgICBjZXJ0Q29uZmlnLmNlcnRBcmNoaXZlRmlsZSA9IGNsaWVudENlcnRBcmNoaXZlO1xyXG4gICAgICAgICAgICBjZXJ0Q29uZmlnLnBhc3NwaHJhc2UgPSBjbGllbnRDZXJ0UGFzc3dvcmQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBjZXJ0Q29uZmlnO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5nZXRIdHRwQ2VydENvbmZpZ3VyYXRpb24gPSBnZXRIdHRwQ2VydENvbmZpZ3VyYXRpb247XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gVGVzdCBQdWJsaXNoZXJcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG52YXIgVGVzdFB1Ymxpc2hlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIFRlc3RQdWJsaXNoZXIodGVzdFJ1bm5lcikge1xyXG4gICAgICAgIHRoaXMudGVzdFJ1bm5lciA9IHRlc3RSdW5uZXI7XHJcbiAgICB9XHJcbiAgICBUZXN0UHVibGlzaGVyLnByb3RvdHlwZS5wdWJsaXNoID0gZnVuY3Rpb24gKHJlc3VsdEZpbGVzLCBtZXJnZVJlc3VsdHMsIHBsYXRmb3JtLCBjb25maWcsIHJ1blRpdGxlLCBwdWJsaXNoUnVuQXR0YWNobWVudHMsIHRlc3RSdW5TeXN0ZW0pIHtcclxuICAgICAgICAvLyBDb3VsZCBoYXZlIHVzZWQgYW4gaW5pdGlhbGl6ZXIsIGJ1dCB3YW50ZWQgdG8gYXZvaWQgcmVvcmRlcmluZyBwYXJhbWV0ZXJzIHdoZW4gY29udmVydGluZyB0byBzdHJpY3QgbnVsbCBjaGVja3NcclxuICAgICAgICAvLyAoQSBwYXJhbWV0ZXIgY2Fubm90IGJvdGggYmUgb3B0aW9uYWwgYW5kIGhhdmUgYW4gaW5pdGlhbGl6ZXIpXHJcbiAgICAgICAgdGVzdFJ1blN5c3RlbSA9IHRlc3RSdW5TeXN0ZW0gfHwgXCJWU1RTVGFza1wiO1xyXG4gICAgICAgIHZhciBwcm9wZXJ0aWVzID0ge307XHJcbiAgICAgICAgcHJvcGVydGllc1sndHlwZSddID0gdGhpcy50ZXN0UnVubmVyO1xyXG4gICAgICAgIGlmIChtZXJnZVJlc3VsdHMpIHtcclxuICAgICAgICAgICAgcHJvcGVydGllc1snbWVyZ2VSZXN1bHRzJ10gPSBtZXJnZVJlc3VsdHM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChwbGF0Zm9ybSkge1xyXG4gICAgICAgICAgICBwcm9wZXJ0aWVzWydwbGF0Zm9ybSddID0gcGxhdGZvcm07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChjb25maWcpIHtcclxuICAgICAgICAgICAgcHJvcGVydGllc1snY29uZmlnJ10gPSBjb25maWc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChydW5UaXRsZSkge1xyXG4gICAgICAgICAgICBwcm9wZXJ0aWVzWydydW5UaXRsZSddID0gcnVuVGl0bGU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChwdWJsaXNoUnVuQXR0YWNobWVudHMpIHtcclxuICAgICAgICAgICAgcHJvcGVydGllc1sncHVibGlzaFJ1bkF0dGFjaG1lbnRzJ10gPSBwdWJsaXNoUnVuQXR0YWNobWVudHM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChyZXN1bHRGaWxlcykge1xyXG4gICAgICAgICAgICBwcm9wZXJ0aWVzWydyZXN1bHRGaWxlcyddID0gcmVzdWx0RmlsZXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHByb3BlcnRpZXNbJ3Rlc3RSdW5TeXN0ZW0nXSA9IHRlc3RSdW5TeXN0ZW07XHJcbiAgICAgICAgZXhwb3J0cy5jb21tYW5kKCdyZXN1bHRzLnB1Ymxpc2gnLCBwcm9wZXJ0aWVzLCAnJyk7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFRlc3RQdWJsaXNoZXI7XHJcbn0oKSk7XHJcbmV4cG9ydHMuVGVzdFB1Ymxpc2hlciA9IFRlc3RQdWJsaXNoZXI7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gQ29kZSBjb3ZlcmFnZSBQdWJsaXNoZXJcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG52YXIgQ29kZUNvdmVyYWdlUHVibGlzaGVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gQ29kZUNvdmVyYWdlUHVibGlzaGVyKCkge1xyXG4gICAgfVxyXG4gICAgQ29kZUNvdmVyYWdlUHVibGlzaGVyLnByb3RvdHlwZS5wdWJsaXNoID0gZnVuY3Rpb24gKGNvZGVDb3ZlcmFnZVRvb2wsIHN1bW1hcnlGaWxlTG9jYXRpb24sIHJlcG9ydERpcmVjdG9yeSwgYWRkaXRpb25hbENvZGVDb3ZlcmFnZUZpbGVzKSB7XHJcbiAgICAgICAgdmFyIHByb3BlcnRpZXMgPSB7fTtcclxuICAgICAgICBpZiAoY29kZUNvdmVyYWdlVG9vbCkge1xyXG4gICAgICAgICAgICBwcm9wZXJ0aWVzWydjb2RlY292ZXJhZ2V0b29sJ10gPSBjb2RlQ292ZXJhZ2VUb29sO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoc3VtbWFyeUZpbGVMb2NhdGlvbikge1xyXG4gICAgICAgICAgICBwcm9wZXJ0aWVzWydzdW1tYXJ5ZmlsZSddID0gc3VtbWFyeUZpbGVMb2NhdGlvbjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHJlcG9ydERpcmVjdG9yeSkge1xyXG4gICAgICAgICAgICBwcm9wZXJ0aWVzWydyZXBvcnRkaXJlY3RvcnknXSA9IHJlcG9ydERpcmVjdG9yeTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGFkZGl0aW9uYWxDb2RlQ292ZXJhZ2VGaWxlcykge1xyXG4gICAgICAgICAgICBwcm9wZXJ0aWVzWydhZGRpdGlvbmFsY29kZWNvdmVyYWdlZmlsZXMnXSA9IGFkZGl0aW9uYWxDb2RlQ292ZXJhZ2VGaWxlcztcclxuICAgICAgICB9XHJcbiAgICAgICAgZXhwb3J0cy5jb21tYW5kKCdjb2RlY292ZXJhZ2UucHVibGlzaCcsIHByb3BlcnRpZXMsIFwiXCIpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBDb2RlQ292ZXJhZ2VQdWJsaXNoZXI7XHJcbn0oKSk7XHJcbmV4cG9ydHMuQ29kZUNvdmVyYWdlUHVibGlzaGVyID0gQ29kZUNvdmVyYWdlUHVibGlzaGVyO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIENvZGUgY292ZXJhZ2UgUHVibGlzaGVyXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxudmFyIENvZGVDb3ZlcmFnZUVuYWJsZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBDb2RlQ292ZXJhZ2VFbmFibGVyKGJ1aWxkVG9vbCwgY2NUb29sKSB7XHJcbiAgICAgICAgdGhpcy5idWlsZFRvb2wgPSBidWlsZFRvb2w7XHJcbiAgICAgICAgdGhpcy5jY1Rvb2wgPSBjY1Rvb2w7XHJcbiAgICB9XHJcbiAgICBDb2RlQ292ZXJhZ2VFbmFibGVyLnByb3RvdHlwZS5lbmFibGVDb2RlQ292ZXJhZ2UgPSBmdW5jdGlvbiAoYnVpbGRQcm9wcykge1xyXG4gICAgICAgIGJ1aWxkUHJvcHNbJ2J1aWxkdG9vbCddID0gdGhpcy5idWlsZFRvb2w7XHJcbiAgICAgICAgYnVpbGRQcm9wc1snY29kZWNvdmVyYWdldG9vbCddID0gdGhpcy5jY1Rvb2w7XHJcbiAgICAgICAgZXhwb3J0cy5jb21tYW5kKCdjb2RlY292ZXJhZ2UuZW5hYmxlJywgYnVpbGRQcm9wcywgXCJcIik7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIENvZGVDb3ZlcmFnZUVuYWJsZXI7XHJcbn0oKSk7XHJcbmV4cG9ydHMuQ29kZUNvdmVyYWdlRW5hYmxlciA9IENvZGVDb3ZlcmFnZUVuYWJsZXI7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gVGFzayBMb2dnaW5nIENvbW1hbmRzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyoqXHJcbiAqIFVwbG9hZCB1c2VyIGludGVyZXN0ZWQgZmlsZSBhcyBhZGRpdGlvbmFsIGxvZyBpbmZvcm1hdGlvblxyXG4gKiB0byB0aGUgY3VycmVudCB0aW1lbGluZSByZWNvcmQuXHJcbiAqXHJcbiAqIFRoZSBmaWxlIHNoYWxsIGJlIGF2YWlsYWJsZSBmb3IgZG93bmxvYWQgYWxvbmcgd2l0aCB0YXNrIGxvZ3MuXHJcbiAqXHJcbiAqIEBwYXJhbSBwYXRoICAgICAgUGF0aCB0byB0aGUgZmlsZSB0aGF0IHNob3VsZCBiZSB1cGxvYWRlZC5cclxuICogQHJldHVybnMgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiB1cGxvYWRGaWxlKHBhdGgpIHtcclxuICAgIGV4cG9ydHMuY29tbWFuZChcInRhc2sudXBsb2FkZmlsZVwiLCBudWxsLCBwYXRoKTtcclxufVxyXG5leHBvcnRzLnVwbG9hZEZpbGUgPSB1cGxvYWRGaWxlO1xyXG4vKipcclxuICogSW5zdHJ1Y3Rpb24gZm9yIHRoZSBhZ2VudCB0byB1cGRhdGUgdGhlIFBBVEggZW52aXJvbm1lbnQgdmFyaWFibGUuXHJcbiAqIFRoZSBzcGVjaWZpZWQgZGlyZWN0b3J5IGlzIHByZXBlbmRlZCB0byB0aGUgUEFUSC5cclxuICogVGhlIHVwZGF0ZWQgZW52aXJvbm1lbnQgdmFyaWFibGUgd2lsbCBiZSByZWZsZWN0ZWQgaW4gc3Vic2VxdWVudCB0YXNrcy5cclxuICpcclxuICogQHBhcmFtIHBhdGggICAgICBMb2NhbCBkaXJlY3RvcnkgcGF0aC5cclxuICogQHJldHVybnMgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBwcmVwZW5kUGF0aChwYXRoKSB7XHJcbiAgICBhc3NlcnRBZ2VudChcIjIuMTE1LjBcIik7XHJcbiAgICBleHBvcnRzLmNvbW1hbmQoXCJ0YXNrLnByZXBlbmRwYXRoXCIsIG51bGwsIHBhdGgpO1xyXG59XHJcbmV4cG9ydHMucHJlcGVuZFBhdGggPSBwcmVwZW5kUGF0aDtcclxuLyoqXHJcbiAqIFVwbG9hZCBhbmQgYXR0YWNoIHN1bW1hcnkgbWFya2Rvd24gdG8gY3VycmVudCB0aW1lbGluZSByZWNvcmQuXHJcbiAqIFRoaXMgc3VtbWFyeSBzaGFsbCBiZSBhZGRlZCB0byB0aGUgYnVpbGQvcmVsZWFzZSBzdW1tYXJ5IGFuZFxyXG4gKiBub3QgYXZhaWxhYmxlIGZvciBkb3dubG9hZCB3aXRoIGxvZ3MuXHJcbiAqXHJcbiAqIEBwYXJhbSBwYXRoICAgICAgTG9jYWwgZGlyZWN0b3J5IHBhdGguXHJcbiAqIEByZXR1cm5zICAgICAgICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gdXBsb2FkU3VtbWFyeShwYXRoKSB7XHJcbiAgICBleHBvcnRzLmNvbW1hbmQoXCJ0YXNrLnVwbG9hZHN1bW1hcnlcIiwgbnVsbCwgcGF0aCk7XHJcbn1cclxuZXhwb3J0cy51cGxvYWRTdW1tYXJ5ID0gdXBsb2FkU3VtbWFyeTtcclxuLyoqXHJcbiAqIFVwbG9hZCBhbmQgYXR0YWNoIGF0dGFjaG1lbnQgdG8gY3VycmVudCB0aW1lbGluZSByZWNvcmQuXHJcbiAqIFRoZXNlIGZpbGVzIGFyZSBub3QgYXZhaWxhYmxlIGZvciBkb3dubG9hZCB3aXRoIGxvZ3MuXHJcbiAqIFRoZXNlIGNhbiBvbmx5IGJlIHJlZmVycmVkIHRvIGJ5IGV4dGVuc2lvbnMgdXNpbmcgdGhlIHR5cGUgb3IgbmFtZSB2YWx1ZXMuXHJcbiAqXHJcbiAqIEBwYXJhbSB0eXBlICAgICAgQXR0YWNobWVudCB0eXBlLlxyXG4gKiBAcGFyYW0gbmFtZSAgICAgIEF0dGFjaG1lbnQgbmFtZS5cclxuICogQHBhcmFtIHBhdGggICAgICBBdHRhY2htZW50IHBhdGguXHJcbiAqIEByZXR1cm5zICAgICAgICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gYWRkQXR0YWNobWVudCh0eXBlLCBuYW1lLCBwYXRoKSB7XHJcbiAgICBleHBvcnRzLmNvbW1hbmQoXCJ0YXNrLmFkZGF0dGFjaG1lbnRcIiwgeyBcInR5cGVcIjogdHlwZSwgXCJuYW1lXCI6IG5hbWUgfSwgcGF0aCk7XHJcbn1cclxuZXhwb3J0cy5hZGRBdHRhY2htZW50ID0gYWRkQXR0YWNobWVudDtcclxuLyoqXHJcbiAqIFNldCBhbiBlbmRwb2ludCBmaWVsZCB3aXRoIGdpdmVuIHZhbHVlLlxyXG4gKiBWYWx1ZSB1cGRhdGVkIHdpbGwgYmUgcmV0YWluZWQgaW4gdGhlIGVuZHBvaW50IGZvclxyXG4gKiB0aGUgc3Vic2VxdWVudCB0YXNrcyB0aGF0IGV4ZWN1dGUgd2l0aGluIHRoZSBzYW1lIGpvYi5cclxuICpcclxuICogQHBhcmFtIGlkICAgICAgRW5kcG9pbnQgaWQuXHJcbiAqIEBwYXJhbSBmaWVsZCAgIEZpZWxkVHlwZSBlbnVtIG9mIEF1dGhQYXJhbWV0ZXIsIERhdGFQYXJhbWV0ZXIgb3IgVXJsLlxyXG4gKiBAcGFyYW0ga2V5ICAgICBLZXkuXHJcbiAqIEBwYXJhbSB2YWx1ZSAgIFZhbHVlIGZvciBrZXkgb3IgdXJsLlxyXG4gKiBAcmV0dXJucyAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBzZXRFbmRwb2ludChpZCwgZmllbGQsIGtleSwgdmFsdWUpIHtcclxuICAgIGV4cG9ydHMuY29tbWFuZChcInRhc2suc2V0ZW5kcG9pbnRcIiwgeyBcImlkXCI6IGlkLCBcImZpZWxkXCI6IEZpZWxkVHlwZVtmaWVsZF0udG9Mb3dlckNhc2UoKSwgXCJrZXlcIjoga2V5IH0sIHZhbHVlKTtcclxufVxyXG5leHBvcnRzLnNldEVuZHBvaW50ID0gc2V0RW5kcG9pbnQ7XHJcbi8qKlxyXG4gKiBTZXQgcHJvZ3Jlc3MgYW5kIGN1cnJlbnQgb3BlcmF0aW9uIGZvciBjdXJyZW50IHRhc2suXHJcbiAqXHJcbiAqIEBwYXJhbSBwZXJjZW50ICAgICAgICAgICBQZXJjZW50YWdlIG9mIGNvbXBsZXRpb24uXHJcbiAqIEBwYXJhbSBjdXJyZW50T3BlcmF0aW9uICBDdXJyZW50IHBwZXJhdGlvbi5cclxuICogQHJldHVybnMgICAgICAgICAgICAgICAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHNldFByb2dyZXNzKHBlcmNlbnQsIGN1cnJlbnRPcGVyYXRpb24pIHtcclxuICAgIGV4cG9ydHMuY29tbWFuZChcInRhc2suc2V0cHJvZ3Jlc3NcIiwgeyBcInZhbHVlXCI6IFwiXCIgKyBwZXJjZW50IH0sIGN1cnJlbnRPcGVyYXRpb24pO1xyXG59XHJcbmV4cG9ydHMuc2V0UHJvZ3Jlc3MgPSBzZXRQcm9ncmVzcztcclxuLyoqXHJcbiAqIEluZGljYXRlcyB3aGV0aGVyIHRvIHdyaXRlIHRoZSBsb2dnaW5nIGNvbW1hbmQgZGlyZWN0bHkgdG8gdGhlIGhvc3Qgb3IgdG8gdGhlIG91dHB1dCBwaXBlbGluZS5cclxuICpcclxuICogQHBhcmFtIGlkICAgICAgICAgICAgVGltZWxpbmUgcmVjb3JkIEd1aWQuXHJcbiAqIEBwYXJhbSBwYXJlbnRJZCAgICAgIFBhcmVudCB0aW1lbGluZSByZWNvcmQgR3VpZC5cclxuICogQHBhcmFtIHJlY29yZFR5cGUgICAgUmVjb3JkIHR5cGUuXHJcbiAqIEBwYXJhbSByZWNvcmROYW1lICAgIFJlY29yZCBuYW1lLlxyXG4gKiBAcGFyYW0gb3JkZXIgICAgICAgICBPcmRlciBvZiB0aW1lbGluZSByZWNvcmQuXHJcbiAqIEBwYXJhbSBzdGFydFRpbWUgICAgIFN0YXJ0IHRpbWUuXHJcbiAqIEBwYXJhbSBmaW5pc2hUaW1lICAgIEVuZCB0aW1lLlxyXG4gKiBAcGFyYW0gcHJvZ3Jlc3MgICAgICBQZXJjZW50YWdlIG9mIGNvbXBsZXRpb24uXHJcbiAqIEBwYXJhbSBzdGF0ZSAgICAgICAgIFRhc2tTdGF0ZSBlbnVtIG9mIFVua25vd24sIEluaXRpYWxpemVkLCBJblByb2dyZXNzIG9yIENvbXBsZXRlZC5cclxuICogQHBhcmFtIHJlc3VsdCAgICAgICAgVGFza1Jlc3VsdCBlbnVtIG9mIFN1Y2NlZWRlZCwgU3VjY2VlZGVkV2l0aElzc3VlcywgRmFpbGVkLCBDYW5jZWxsZWQgb3IgU2tpcHBlZC5cclxuICogQHBhcmFtIG1lc3NhZ2UgICAgICAgY3VycmVudCBvcGVyYXRpb25cclxuICogQHJldHVybnMgICAgICAgICAgICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gbG9nRGV0YWlsKGlkLCBtZXNzYWdlLCBwYXJlbnRJZCwgcmVjb3JkVHlwZSwgcmVjb3JkTmFtZSwgb3JkZXIsIHN0YXJ0VGltZSwgZmluaXNoVGltZSwgcHJvZ3Jlc3MsIHN0YXRlLCByZXN1bHQpIHtcclxuICAgIHZhciBwcm9wZXJ0aWVzID0ge1xyXG4gICAgICAgIFwiaWRcIjogaWQsXHJcbiAgICAgICAgXCJwYXJlbnRpZFwiOiBwYXJlbnRJZCxcclxuICAgICAgICBcInR5cGVcIjogcmVjb3JkVHlwZSxcclxuICAgICAgICBcIm5hbWVcIjogcmVjb3JkTmFtZSxcclxuICAgICAgICBcIm9yZGVyXCI6IG9yZGVyID8gb3JkZXIudG9TdHJpbmcoKSA6IHVuZGVmaW5lZCxcclxuICAgICAgICBcInN0YXJ0dGltZVwiOiBzdGFydFRpbWUsXHJcbiAgICAgICAgXCJmaW5pc2h0aW1lXCI6IGZpbmlzaFRpbWUsXHJcbiAgICAgICAgXCJwcm9ncmVzc1wiOiBwcm9ncmVzcyA/IHByb2dyZXNzLnRvU3RyaW5nKCkgOiB1bmRlZmluZWQsXHJcbiAgICAgICAgXCJzdGF0ZVwiOiBzdGF0ZSA/IFRhc2tTdGF0ZVtzdGF0ZV0gOiB1bmRlZmluZWQsXHJcbiAgICAgICAgXCJyZXN1bHRcIjogcmVzdWx0ID8gVGFza1Jlc3VsdFtyZXN1bHRdIDogdW5kZWZpbmVkXHJcbiAgICB9O1xyXG4gICAgZXhwb3J0cy5jb21tYW5kKFwidGFzay5sb2dkZXRhaWxcIiwgcHJvcGVydGllcywgbWVzc2FnZSk7XHJcbn1cclxuZXhwb3J0cy5sb2dEZXRhaWwgPSBsb2dEZXRhaWw7XHJcbi8qKlxyXG4gKiBMb2cgZXJyb3Igb3Igd2FybmluZyBpc3N1ZSB0byB0aW1lbGluZSByZWNvcmQgb2YgY3VycmVudCB0YXNrLlxyXG4gKlxyXG4gKiBAcGFyYW0gdHlwZSAgICAgICAgICBJc3N1ZVR5cGUgZW51bSBvZiBFcnJvciBvciBXYXJuaW5nLlxyXG4gKiBAcGFyYW0gc291cmNlUGF0aCAgICBTb3VyY2UgZmlsZSBsb2NhdGlvbi5cclxuICogQHBhcmFtIGxpbmVOdW1iZXIgICAgTGluZSBudW1iZXIuXHJcbiAqIEBwYXJhbSBjb2x1bW5OdW1iZXIgIENvbHVtbiBudW1iZXIuXHJcbiAqIEBwYXJhbSBjb2RlICAgICAgICAgIEVycm9yIG9yIHdhcm5pbmcgY29kZS5cclxuICogQHBhcmFtIG1lc3NhZ2UgICAgICAgRXJyb3Igb3Igd2FybmluZyBtZXNzYWdlLlxyXG4gKiBAcmV0dXJucyAgICAgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBsb2dJc3N1ZSh0eXBlLCBtZXNzYWdlLCBzb3VyY2VQYXRoLCBsaW5lTnVtYmVyLCBjb2x1bW5OdW1iZXIsIGVycm9yQ29kZSkge1xyXG4gICAgdmFyIHByb3BlcnRpZXMgPSB7XHJcbiAgICAgICAgXCJ0eXBlXCI6IElzc3VlVHlwZVt0eXBlXS50b0xvd2VyQ2FzZSgpLFxyXG4gICAgICAgIFwiY29kZVwiOiBlcnJvckNvZGUsXHJcbiAgICAgICAgXCJzb3VyY2VwYXRoXCI6IHNvdXJjZVBhdGgsXHJcbiAgICAgICAgXCJsaW5lbnVtYmVyXCI6IGxpbmVOdW1iZXIgPyBsaW5lTnVtYmVyLnRvU3RyaW5nKCkgOiB1bmRlZmluZWQsXHJcbiAgICAgICAgXCJjb2x1bW5udW1iZXJcIjogY29sdW1uTnVtYmVyID8gY29sdW1uTnVtYmVyLnRvU3RyaW5nKCkgOiB1bmRlZmluZWQsXHJcbiAgICB9O1xyXG4gICAgZXhwb3J0cy5jb21tYW5kKFwidGFzay5sb2dpc3N1ZVwiLCBwcm9wZXJ0aWVzLCBtZXNzYWdlKTtcclxufVxyXG5leHBvcnRzLmxvZ0lzc3VlID0gbG9nSXNzdWU7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gQXJ0aWZhY3QgTG9nZ2luZyBDb21tYW5kc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qKlxyXG4gKiBVcGxvYWQgdXNlciBpbnRlcmVzdGVkIGZpbGUgYXMgYWRkaXRpb25hbCBsb2cgaW5mb3JtYXRpb25cclxuICogdG8gdGhlIGN1cnJlbnQgdGltZWxpbmUgcmVjb3JkLlxyXG4gKlxyXG4gKiBUaGUgZmlsZSBzaGFsbCBiZSBhdmFpbGFibGUgZm9yIGRvd25sb2FkIGFsb25nIHdpdGggdGFzayBsb2dzLlxyXG4gKlxyXG4gKiBAcGFyYW0gY29udGFpbmVyRm9sZGVyICAgRm9sZGVyIHRoYXQgdGhlIGZpbGUgd2lsbCB1cGxvYWQgdG8sIGZvbGRlciB3aWxsIGJlIGNyZWF0ZWQgaWYgbmVlZGVkLlxyXG4gKiBAcGFyYW0gcGF0aCAgICAgICAgICAgICAgUGF0aCB0byB0aGUgZmlsZSB0aGF0IHNob3VsZCBiZSB1cGxvYWRlZC5cclxuICogQHBhcmFtIG5hbWUgICAgICAgICAgICAgIEFydGlmYWN0IG5hbWUuXHJcbiAqIEByZXR1cm5zICAgICAgICAgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiB1cGxvYWRBcnRpZmFjdChjb250YWluZXJGb2xkZXIsIHBhdGgsIG5hbWUpIHtcclxuICAgIGV4cG9ydHMuY29tbWFuZChcImFydGlmYWN0LnVwbG9hZFwiLCB7IFwiY29udGFpbmVyZm9sZGVyXCI6IGNvbnRhaW5lckZvbGRlciwgXCJhcnRpZmFjdG5hbWVcIjogbmFtZSB9LCBwYXRoKTtcclxufVxyXG5leHBvcnRzLnVwbG9hZEFydGlmYWN0ID0gdXBsb2FkQXJ0aWZhY3Q7XHJcbi8qKlxyXG4gKiBDcmVhdGUgYW4gYXJ0aWZhY3QgbGluaywgYXJ0aWZhY3QgbG9jYXRpb24gaXMgcmVxdWlyZWQgdG8gYmVcclxuICogYSBmaWxlIGNvbnRhaW5lciBwYXRoLCBWQyBwYXRoIG9yIFVOQyBzaGFyZSBwYXRoLlxyXG4gKlxyXG4gKiBUaGUgZmlsZSBzaGFsbCBiZSBhdmFpbGFibGUgZm9yIGRvd25sb2FkIGFsb25nIHdpdGggdGFzayBsb2dzLlxyXG4gKlxyXG4gKiBAcGFyYW0gbmFtZSAgICAgICAgICAgICAgQXJ0aWZhY3QgbmFtZS5cclxuICogQHBhcmFtIHBhdGggICAgICAgICAgICAgIFBhdGggdG8gdGhlIGZpbGUgdGhhdCBzaG91bGQgYmUgYXNzb2NpYXRlZC5cclxuICogQHBhcmFtIGFydGlmYWN0VHlwZSAgICAgIEFydGlmYWN0VHlwZSBlbnVtIG9mIENvbnRhaW5lciwgRmlsZVBhdGgsIFZlcnNpb25Db250cm9sLCBHaXRSZWYgb3IgVGZ2Y0xhYmVsLlxyXG4gKiBAcmV0dXJucyAgICAgICAgICAgICAgICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gYXNzb2NpYXRlQXJ0aWZhY3QobmFtZSwgcGF0aCwgYXJ0aWZhY3RUeXBlKSB7XHJcbiAgICBleHBvcnRzLmNvbW1hbmQoXCJhcnRpZmFjdC5hc3NvY2lhdGVcIiwgeyBcInR5cGVcIjogQXJ0aWZhY3RUeXBlW2FydGlmYWN0VHlwZV0udG9Mb3dlckNhc2UoKSwgXCJhcnRpZmFjdG5hbWVcIjogbmFtZSB9LCBwYXRoKTtcclxufVxyXG5leHBvcnRzLmFzc29jaWF0ZUFydGlmYWN0ID0gYXNzb2NpYXRlQXJ0aWZhY3Q7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gQnVpbGQgTG9nZ2luZyBDb21tYW5kc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qKlxyXG4gKiBVcGxvYWQgdXNlciBpbnRlcmVzdGVkIGxvZyB0byBidWlsZOKAmXMgY29udGFpbmVyIOKAnGxvZ3NcXHRvb2zigJ0gZm9sZGVyLlxyXG4gKlxyXG4gKiBAcGFyYW0gcGF0aCAgICAgIFBhdGggdG8gdGhlIGZpbGUgdGhhdCBzaG91bGQgYmUgdXBsb2FkZWQuXHJcbiAqIEByZXR1cm5zICAgICAgICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gdXBsb2FkQnVpbGRMb2cocGF0aCkge1xyXG4gICAgZXhwb3J0cy5jb21tYW5kKFwiYnVpbGQudXBsb2FkbG9nXCIsIG51bGwsIHBhdGgpO1xyXG59XHJcbmV4cG9ydHMudXBsb2FkQnVpbGRMb2cgPSB1cGxvYWRCdWlsZExvZztcclxuLyoqXHJcbiAqIFVwZGF0ZSBidWlsZCBudW1iZXIgZm9yIGN1cnJlbnQgYnVpbGQuXHJcbiAqXHJcbiAqIEBwYXJhbSB2YWx1ZSAgICAgVmFsdWUgdG8gYmUgYXNzaWduZWQgYXMgdGhlIGJ1aWxkIG51bWJlci5cclxuICogQHJldHVybnMgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiB1cGRhdGVCdWlsZE51bWJlcih2YWx1ZSkge1xyXG4gICAgZXhwb3J0cy5jb21tYW5kKFwiYnVpbGQudXBkYXRlYnVpbGRudW1iZXJcIiwgbnVsbCwgdmFsdWUpO1xyXG59XHJcbmV4cG9ydHMudXBkYXRlQnVpbGROdW1iZXIgPSB1cGRhdGVCdWlsZE51bWJlcjtcclxuLyoqXHJcbiAqIEFkZCBhIHRhZyBmb3IgY3VycmVudCBidWlsZC5cclxuICpcclxuICogQHBhcmFtIHZhbHVlICAgICBUYWcgdmFsdWUuXHJcbiAqIEByZXR1cm5zICAgICAgICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gYWRkQnVpbGRUYWcodmFsdWUpIHtcclxuICAgIGV4cG9ydHMuY29tbWFuZChcImJ1aWxkLmFkZGJ1aWxkdGFnXCIsIG51bGwsIHZhbHVlKTtcclxufVxyXG5leHBvcnRzLmFkZEJ1aWxkVGFnID0gYWRkQnVpbGRUYWc7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gUmVsZWFzZSBMb2dnaW5nIENvbW1hbmRzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyoqXHJcbiAqIFVwZGF0ZSByZWxlYXNlIG5hbWUgZm9yIGN1cnJlbnQgcmVsZWFzZS5cclxuICpcclxuICogQHBhcmFtIHZhbHVlICAgICBWYWx1ZSB0byBiZSBhc3NpZ25lZCBhcyB0aGUgcmVsZWFzZSBuYW1lLlxyXG4gKiBAcmV0dXJucyAgICAgICAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHVwZGF0ZVJlbGVhc2VOYW1lKG5hbWUpIHtcclxuICAgIGFzc2VydEFnZW50KFwiMi4xMzJcIik7XHJcbiAgICBleHBvcnRzLmNvbW1hbmQoXCJyZWxlYXNlLnVwZGF0ZXJlbGVhc2VuYW1lXCIsIG51bGwsIG5hbWUpO1xyXG59XHJcbmV4cG9ydHMudXBkYXRlUmVsZWFzZU5hbWUgPSB1cGRhdGVSZWxlYXNlTmFtZTtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBUb29sc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmV4cG9ydHMuVGFza0NvbW1hbmQgPSB0Y20uVGFza0NvbW1hbmQ7XHJcbmV4cG9ydHMuY29tbWFuZEZyb21TdHJpbmcgPSB0Y20uY29tbWFuZEZyb21TdHJpbmc7XHJcbmV4cG9ydHMuVG9vbFJ1bm5lciA9IHRybS5Ub29sUnVubmVyO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIFZhbGlkYXRpb24gQ2hlY2tzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gYXN5bmMgYXdhaXQgbmVlZHMgZ2VuZXJhdG9ycyBpbiBub2RlIDQueCtcclxuaWYgKHNlbXZlci5sdChwcm9jZXNzLnZlcnNpb25zLm5vZGUsICc0LjIuMCcpKSB7XHJcbiAgICB0aGlzLndhcm5pbmcoJ1Rhc2tzIHJlcXVpcmUgYSBuZXcgYWdlbnQuICBVcGdyYWRlIHlvdXIgYWdlbnQgb3Igbm9kZSB0byA0LjIuMCBvciBsYXRlcicpO1xyXG59XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBQb3B1bGF0ZSB0aGUgdmF1bHQgd2l0aCBzZW5zaXRpdmUgZGF0YS4gIElucHV0cyBhbmQgRW5kcG9pbnRzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBhdm9pZCBsb2FkaW5nIHR3aWNlIChvdmVyd3JpdGVzIC50YXNra2V5KVxyXG5pZiAoIWdsb2JhbFsnX3ZzdHNfdGFza19saWJfbG9hZGVkJ10pIHtcclxuICAgIGltLl9sb2FkRGF0YSgpO1xyXG4gICAgaW0uX2V4cG9zZVByb3h5U2V0dGluZ3MoKTtcclxuICAgIGltLl9leHBvc2VDZXJ0U2V0dGluZ3MoKTtcclxufVxyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG4vL1xyXG4vLyBDb21tYW5kIEZvcm1hdDpcclxuLy8gICAgIyN2c29bYXJ0aWZhY3QuY29tbWFuZCBrZXk9dmFsdWU7a2V5PXZhbHVlXXVzZXIgbWVzc2FnZVxyXG4vLyAgICBcclxuLy8gRXhhbXBsZXM6XHJcbi8vICAgICMjdnNvW3Rhc2sucHJvZ3Jlc3MgdmFsdWU9NThdXHJcbi8vICAgICMjdnNvW3Rhc2suaXNzdWUgdHlwZT13YXJuaW5nO11UaGlzIGlzIHRoZSB1c2VyIHdhcm5pbmcgbWVzc2FnZVxyXG4vL1xyXG52YXIgQ01EX1BSRUZJWCA9ICcjI3Zzb1snO1xyXG52YXIgVGFza0NvbW1hbmQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBUYXNrQ29tbWFuZChjb21tYW5kLCBwcm9wZXJ0aWVzLCBtZXNzYWdlKSB7XHJcbiAgICAgICAgaWYgKCFjb21tYW5kKSB7XHJcbiAgICAgICAgICAgIGNvbW1hbmQgPSAnbWlzc2luZy5jb21tYW5kJztcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5jb21tYW5kID0gY29tbWFuZDtcclxuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xyXG4gICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XHJcbiAgICB9XHJcbiAgICBUYXNrQ29tbWFuZC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGNtZFN0ciA9IENNRF9QUkVGSVggKyB0aGlzLmNvbW1hbmQ7XHJcbiAgICAgICAgaWYgKHRoaXMucHJvcGVydGllcyAmJiBPYmplY3Qua2V5cyh0aGlzLnByb3BlcnRpZXMpLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgY21kU3RyICs9ICcgJztcclxuICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIHRoaXMucHJvcGVydGllcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHZhbCA9IHRoaXMucHJvcGVydGllc1trZXldO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2FmZWx5IGFwcGVuZCB0aGUgdmFsIC0gYXZvaWQgYmxvd2luZyB1cCB3aGVuIGF0dGVtcHRpbmcgdG9cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FsbCAucmVwbGFjZSgpIGlmIG1lc3NhZ2UgaXMgbm90IGEgc3RyaW5nIGZvciBzb21lIHJlYXNvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbWRTdHIgKz0ga2V5ICsgJz0nICsgZXNjYXBlKCcnICsgKHZhbCB8fCAnJykpICsgJzsnO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBjbWRTdHIgKz0gJ10nO1xyXG4gICAgICAgIC8vIHNhZmVseSBhcHBlbmQgdGhlIG1lc3NhZ2UgLSBhdm9pZCBibG93aW5nIHVwIHdoZW4gYXR0ZW1wdGluZyB0b1xyXG4gICAgICAgIC8vIGNhbGwgLnJlcGxhY2UoKSBpZiBtZXNzYWdlIGlzIG5vdCBhIHN0cmluZyBmb3Igc29tZSByZWFzb25cclxuICAgICAgICB2YXIgbWVzc2FnZSA9ICcnICsgKHRoaXMubWVzc2FnZSB8fCAnJyk7XHJcbiAgICAgICAgY21kU3RyICs9IGVzY2FwZWRhdGEobWVzc2FnZSk7XHJcbiAgICAgICAgcmV0dXJuIGNtZFN0cjtcclxuICAgIH07XHJcbiAgICByZXR1cm4gVGFza0NvbW1hbmQ7XHJcbn0oKSk7XHJcbmV4cG9ydHMuVGFza0NvbW1hbmQgPSBUYXNrQ29tbWFuZDtcclxuZnVuY3Rpb24gY29tbWFuZEZyb21TdHJpbmcoY29tbWFuZExpbmUpIHtcclxuICAgIHZhciBwcmVMZW4gPSBDTURfUFJFRklYLmxlbmd0aDtcclxuICAgIHZhciBsYlBvcyA9IGNvbW1hbmRMaW5lLmluZGV4T2YoJ1snKTtcclxuICAgIHZhciByYlBvcyA9IGNvbW1hbmRMaW5lLmluZGV4T2YoJ10nKTtcclxuICAgIGlmIChsYlBvcyA9PSAtMSB8fCByYlBvcyA9PSAtMSB8fCByYlBvcyAtIGxiUG9zIDwgMykge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb21tYW5kIGJyYWNrZXRzJyk7XHJcbiAgICB9XHJcbiAgICB2YXIgY21kSW5mbyA9IGNvbW1hbmRMaW5lLnN1YnN0cmluZyhsYlBvcyArIDEsIHJiUG9zKTtcclxuICAgIHZhciBzcGFjZUlkeCA9IGNtZEluZm8uaW5kZXhPZignICcpO1xyXG4gICAgdmFyIGNvbW1hbmQgPSBjbWRJbmZvO1xyXG4gICAgdmFyIHByb3BlcnRpZXMgPSB7fTtcclxuICAgIGlmIChzcGFjZUlkeCA+IDApIHtcclxuICAgICAgICBjb21tYW5kID0gY21kSW5mby50cmltKCkuc3Vic3RyaW5nKDAsIHNwYWNlSWR4KTtcclxuICAgICAgICB2YXIgcHJvcFNlY3Rpb24gPSBjbWRJbmZvLnRyaW0oKS5zdWJzdHJpbmcoc3BhY2VJZHggKyAxKTtcclxuICAgICAgICB2YXIgcHJvcExpbmVzID0gcHJvcFNlY3Rpb24uc3BsaXQoJzsnKTtcclxuICAgICAgICBwcm9wTGluZXMuZm9yRWFjaChmdW5jdGlvbiAocHJvcExpbmUpIHtcclxuICAgICAgICAgICAgcHJvcExpbmUgPSBwcm9wTGluZS50cmltKCk7XHJcbiAgICAgICAgICAgIGlmIChwcm9wTGluZS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZXFJbmRleCA9IHByb3BMaW5lLmluZGV4T2YoJz0nKTtcclxuICAgICAgICAgICAgICAgIGlmIChlcUluZGV4ID09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHByb3BlcnR5OiAnICsgcHJvcExpbmUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdmFyIGtleSA9IHByb3BMaW5lLnN1YnN0cmluZygwLCBlcUluZGV4KTtcclxuICAgICAgICAgICAgICAgIHZhciB2YWwgPSBwcm9wTGluZS5zdWJzdHJpbmcoZXFJbmRleCArIDEpO1xyXG4gICAgICAgICAgICAgICAgcHJvcGVydGllc1trZXldID0gdW5lc2NhcGUodmFsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgdmFyIG1zZyA9IHVuZXNjYXBlZGF0YShjb21tYW5kTGluZS5zdWJzdHJpbmcocmJQb3MgKyAxKSk7XHJcbiAgICB2YXIgY21kID0gbmV3IFRhc2tDb21tYW5kKGNvbW1hbmQsIHByb3BlcnRpZXMsIG1zZyk7XHJcbiAgICByZXR1cm4gY21kO1xyXG59XHJcbmV4cG9ydHMuY29tbWFuZEZyb21TdHJpbmcgPSBjb21tYW5kRnJvbVN0cmluZztcclxuZnVuY3Rpb24gZXNjYXBlZGF0YShzKSB7XHJcbiAgICByZXR1cm4gcy5yZXBsYWNlKC8lL2csICclMjUnKVxyXG4gICAgICAgIC5yZXBsYWNlKC9cXHIvZywgJyUwRCcpXHJcbiAgICAgICAgLnJlcGxhY2UoL1xcbi9nLCAnJTBBJyk7XHJcbn1cclxuZnVuY3Rpb24gdW5lc2NhcGVkYXRhKHMpIHtcclxuICAgIHJldHVybiBzLnJlcGxhY2UoLyUwRC9nLCAnXFxyJylcclxuICAgICAgICAucmVwbGFjZSgvJTBBL2csICdcXG4nKVxyXG4gICAgICAgIC5yZXBsYWNlKC8lMjUvZywgJyUnKTtcclxufVxyXG5mdW5jdGlvbiBlc2NhcGUocykge1xyXG4gICAgcmV0dXJuIHMucmVwbGFjZSgvJS9nLCAnJTI1JylcclxuICAgICAgICAucmVwbGFjZSgvXFxyL2csICclMEQnKVxyXG4gICAgICAgIC5yZXBsYWNlKC9cXG4vZywgJyUwQScpXHJcbiAgICAgICAgLnJlcGxhY2UoL10vZywgJyU1RCcpXHJcbiAgICAgICAgLnJlcGxhY2UoLzsvZywgJyUzQicpO1xyXG59XHJcbmZ1bmN0aW9uIHVuZXNjYXBlKHMpIHtcclxuICAgIHJldHVybiBzLnJlcGxhY2UoLyUwRC9nLCAnXFxyJylcclxuICAgICAgICAucmVwbGFjZSgvJTBBL2csICdcXG4nKVxyXG4gICAgICAgIC5yZXBsYWNlKC8lNUQvZywgJ10nKVxyXG4gICAgICAgIC5yZXBsYWNlKC8lM0IvZywgJzsnKVxyXG4gICAgICAgIC5yZXBsYWNlKC8lMjUvZywgJyUnKTtcclxufVxyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgICAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIH1cclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgUSA9IHJlcXVpcmUoXCJxXCIpO1xyXG52YXIgb3MgPSByZXF1aXJlKFwib3NcIik7XHJcbnZhciBldmVudHMgPSByZXF1aXJlKFwiZXZlbnRzXCIpO1xyXG52YXIgY2hpbGQgPSByZXF1aXJlKFwiY2hpbGRfcHJvY2Vzc1wiKTtcclxudmFyIGltID0gcmVxdWlyZShcIi4vaW50ZXJuYWxcIik7XHJcbnZhciBmcyA9IHJlcXVpcmUoXCJmc1wiKTtcclxudmFyIFRvb2xSdW5uZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoVG9vbFJ1bm5lciwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFRvb2xSdW5uZXIodG9vbFBhdGgpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLmNtZFNwZWNpYWxDaGFycyA9IFsnICcsICdcXHQnLCAnJicsICcoJywgJyknLCAnWycsICddJywgJ3snLCAnfScsICdeJywgJz0nLCAnOycsICchJywgJ1xcJycsICcrJywgJywnLCAnYCcsICd+JywgJ3wnLCAnPCcsICc+JywgJ1wiJ107XHJcbiAgICAgICAgaWYgKCF0b29sUGF0aCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhcmFtZXRlciBcXCd0b29sUGF0aFxcJyBjYW5ub3QgYmUgbnVsbCBvciBlbXB0eS4nKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgX3RoaXMudG9vbFBhdGggPSBpbS5fd2hpY2godG9vbFBhdGgsIHRydWUpO1xyXG4gICAgICAgIF90aGlzLmFyZ3MgPSBbXTtcclxuICAgICAgICBfdGhpcy5fZGVidWcoJ3Rvb2xSdW5uZXIgdG9vbFBhdGg6ICcgKyB0b29sUGF0aCk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX2RlYnVnID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcclxuICAgICAgICB0aGlzLmVtaXQoJ2RlYnVnJywgbWVzc2FnZSk7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX2FyZ1N0cmluZ1RvQXJyYXkgPSBmdW5jdGlvbiAoYXJnU3RyaW5nKSB7XHJcbiAgICAgICAgdmFyIGFyZ3MgPSBbXTtcclxuICAgICAgICB2YXIgaW5RdW90ZXMgPSBmYWxzZTtcclxuICAgICAgICB2YXIgZXNjYXBlZCA9IGZhbHNlO1xyXG4gICAgICAgIHZhciBsYXN0Q2hhcldhc1NwYWNlID0gdHJ1ZTtcclxuICAgICAgICB2YXIgYXJnID0gJyc7XHJcbiAgICAgICAgdmFyIGFwcGVuZCA9IGZ1bmN0aW9uIChjKSB7XHJcbiAgICAgICAgICAgIC8vIHdlIG9ubHkgZXNjYXBlIGRvdWJsZSBxdW90ZXMuXHJcbiAgICAgICAgICAgIGlmIChlc2NhcGVkICYmIGMgIT09ICdcIicpIHtcclxuICAgICAgICAgICAgICAgIGFyZyArPSAnXFxcXCc7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYXJnICs9IGM7XHJcbiAgICAgICAgICAgIGVzY2FwZWQgPSBmYWxzZTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJnU3RyaW5nLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHZhciBjID0gYXJnU3RyaW5nLmNoYXJBdChpKTtcclxuICAgICAgICAgICAgaWYgKGMgPT09ICcgJyAmJiAhaW5RdW90ZXMpIHtcclxuICAgICAgICAgICAgICAgIGlmICghbGFzdENoYXJXYXNTcGFjZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGFyZ3MucHVzaChhcmcpO1xyXG4gICAgICAgICAgICAgICAgICAgIGFyZyA9ICcnO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbGFzdENoYXJXYXNTcGFjZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGxhc3RDaGFyV2FzU3BhY2UgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoYyA9PT0gJ1wiJykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFlc2NhcGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaW5RdW90ZXMgPSAhaW5RdW90ZXM7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBhcHBlbmQoYyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoYyA9PT0gXCJcXFxcXCIgJiYgZXNjYXBlZCkge1xyXG4gICAgICAgICAgICAgICAgYXBwZW5kKGMpO1xyXG4gICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGMgPT09IFwiXFxcXFwiICYmIGluUXVvdGVzKSB7XHJcbiAgICAgICAgICAgICAgICBlc2NhcGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGFwcGVuZChjKTtcclxuICAgICAgICAgICAgbGFzdENoYXJXYXNTcGFjZSA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWxhc3RDaGFyV2FzU3BhY2UpIHtcclxuICAgICAgICAgICAgYXJncy5wdXNoKGFyZy50cmltKCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYXJncztcclxuICAgIH07XHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5fZ2V0Q29tbWFuZFN0cmluZyA9IGZ1bmN0aW9uIChvcHRpb25zLCBub1ByZWZpeCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHRvb2xQYXRoID0gdGhpcy5fZ2V0U3Bhd25GaWxlTmFtZSgpO1xyXG4gICAgICAgIHZhciBhcmdzID0gdGhpcy5fZ2V0U3Bhd25BcmdzKG9wdGlvbnMpO1xyXG4gICAgICAgIHZhciBjbWQgPSBub1ByZWZpeCA/ICcnIDogJ1tjb21tYW5kXSc7IC8vIG9taXQgcHJlZml4IHdoZW4gcGlwZWQgdG8gYSBzZWNvbmQgdG9vbFxyXG4gICAgICAgIHZhciBjb21tYW5kUGFydHMgPSBbXTtcclxuICAgICAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInKSB7XHJcbiAgICAgICAgICAgIC8vIFdpbmRvd3MgKyBjbWQgZmlsZVxyXG4gICAgICAgICAgICBpZiAodGhpcy5faXNDbWRGaWxlKCkpIHtcclxuICAgICAgICAgICAgICAgIGNvbW1hbmRQYXJ0cy5wdXNoKHRvb2xQYXRoKTtcclxuICAgICAgICAgICAgICAgIGNvbW1hbmRQYXJ0cyA9IGNvbW1hbmRQYXJ0cy5jb25jYXQoYXJncyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gV2luZG93cyArIHZlcmJhdGltXHJcbiAgICAgICAgICAgIGVsc2UgaWYgKG9wdGlvbnMud2luZG93c1ZlcmJhdGltQXJndW1lbnRzKSB7XHJcbiAgICAgICAgICAgICAgICBjb21tYW5kUGFydHMucHVzaChcIlxcXCJcIiArIHRvb2xQYXRoICsgXCJcXFwiXCIpO1xyXG4gICAgICAgICAgICAgICAgY29tbWFuZFBhcnRzID0gY29tbWFuZFBhcnRzLmNvbmNhdChhcmdzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChvcHRpb25zLnNoZWxsKSB7XHJcbiAgICAgICAgICAgICAgICBjb21tYW5kUGFydHMucHVzaCh0aGlzLl93aW5kb3dzUXVvdGVDbWRBcmcodG9vbFBhdGgpKTtcclxuICAgICAgICAgICAgICAgIGNvbW1hbmRQYXJ0cyA9IGNvbW1hbmRQYXJ0cy5jb25jYXQoYXJncyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gV2luZG93cyAocmVndWxhcilcclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb21tYW5kUGFydHMucHVzaCh0aGlzLl93aW5kb3dzUXVvdGVDbWRBcmcodG9vbFBhdGgpKTtcclxuICAgICAgICAgICAgICAgIGNvbW1hbmRQYXJ0cyA9IGNvbW1hbmRQYXJ0cy5jb25jYXQoYXJncy5tYXAoZnVuY3Rpb24gKGFyZykgeyByZXR1cm4gX3RoaXMuX3dpbmRvd3NRdW90ZUNtZEFyZyhhcmcpOyB9KSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIE9TWC9MaW51eCAtIHRoaXMgY2FuIGxpa2VseSBiZSBpbXByb3ZlZCB3aXRoIHNvbWUgZm9ybSBvZiBxdW90aW5nLlxyXG4gICAgICAgICAgICAvLyBjcmVhdGluZyBwcm9jZXNzZXMgb24gVW5peCBpcyBmdW5kYW1lbnRhbGx5IGRpZmZlcmVudCB0aGFuIFdpbmRvd3MuXHJcbiAgICAgICAgICAgIC8vIG9uIFVuaXgsIGV4ZWN2cCgpIHRha2VzIGFuIGFyZyBhcnJheS5cclxuICAgICAgICAgICAgY29tbWFuZFBhcnRzLnB1c2godG9vbFBhdGgpO1xyXG4gICAgICAgICAgICBjb21tYW5kUGFydHMgPSBjb21tYW5kUGFydHMuY29uY2F0KGFyZ3MpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjbWQgKz0gY29tbWFuZFBhcnRzLmpvaW4oJyAnKTtcclxuICAgICAgICAvLyBhcHBlbmQgc2Vjb25kIHRvb2xcclxuICAgICAgICBpZiAodGhpcy5waXBlT3V0cHV0VG9Ub29sKSB7XHJcbiAgICAgICAgICAgIGNtZCArPSAnIHwgJyArIHRoaXMucGlwZU91dHB1dFRvVG9vbC5fZ2V0Q29tbWFuZFN0cmluZyhvcHRpb25zLCAvKm5vUHJlZml4OiovIHRydWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gY21kO1xyXG4gICAgfTtcclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl9wcm9jZXNzTGluZUJ1ZmZlciA9IGZ1bmN0aW9uIChkYXRhLCBzdHJCdWZmZXIsIG9uTGluZSkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHZhciBzID0gc3RyQnVmZmVyICsgZGF0YS50b1N0cmluZygpO1xyXG4gICAgICAgICAgICB2YXIgbiA9IHMuaW5kZXhPZihvcy5FT0wpO1xyXG4gICAgICAgICAgICB3aGlsZSAobiA+IC0xKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbGluZSA9IHMuc3Vic3RyaW5nKDAsIG4pO1xyXG4gICAgICAgICAgICAgICAgb25MaW5lKGxpbmUpO1xyXG4gICAgICAgICAgICAgICAgLy8gdGhlIHJlc3Qgb2YgdGhlIHN0cmluZyAuLi5cclxuICAgICAgICAgICAgICAgIHMgPSBzLnN1YnN0cmluZyhuICsgb3MuRU9MLmxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICBuID0gcy5pbmRleE9mKG9zLkVPTCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc3RyQnVmZmVyID0gcztcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAvLyBzdHJlYW1pbmcgbGluZXMgdG8gY29uc29sZSBpcyBiZXN0IGVmZm9ydC4gIERvbid0IGZhaWwgYSBidWlsZC5cclxuICAgICAgICAgICAgdGhpcy5fZGVidWcoJ2Vycm9yIHByb2Nlc3NpbmcgbGluZScpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFdyYXBzIGFuIGFyZyBzdHJpbmcgd2l0aCBzcGVjaWZpZWQgY2hhciBpZiBpdCdzIG5vdCBhbHJlYWR5IHdyYXBwZWRcclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEFyZyB3cmFwcGVkIHdpdGggc3BlY2lmaWVkIGNoYXJcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhcmcgSW5wdXQgYXJndW1lbnQgc3RyaW5nXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gd3JhcENoYXIgQSBjaGFyIGlucHV0IHN0cmluZyBzaG91bGQgYmUgd3JhcHBlZCB3aXRoXHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl93cmFwQXJnID0gZnVuY3Rpb24gKGFyZywgd3JhcENoYXIpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2lzV3JhcHBlZChhcmcsIHdyYXBDaGFyKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gXCJcIiArIHdyYXBDaGFyICsgYXJnICsgd3JhcENoYXI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBhcmc7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBVbndyYXBzIGFuIGFyZyBzdHJpbmcgd3JhcHBlZCB3aXRoIHNwZWNpZmllZCBjaGFyXHJcbiAgICAgKiBAcGFyYW0gYXJnIEFyZyB3cmFwcGVkIHdpdGggc3BlY2lmaWVkIGNoYXJcclxuICAgICAqIEBwYXJhbSB3cmFwQ2hhciBBIGNoYXIgdG8gYmUgcmVtb3ZlZFxyXG4gICAgICovXHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5fdW53cmFwQXJnID0gZnVuY3Rpb24gKGFyZywgd3JhcENoYXIpIHtcclxuICAgICAgICBpZiAodGhpcy5faXNXcmFwcGVkKGFyZywgd3JhcENoYXIpKSB7XHJcbiAgICAgICAgICAgIHZhciBwYXR0ZXJuID0gbmV3IFJlZ0V4cChcIiheXFxcXFxcXFw/XCIgKyB3cmFwQ2hhciArIFwiKXwoXFxcXFxcXFw/XCIgKyB3cmFwQ2hhciArIFwiJClcIiwgJ2cnKTtcclxuICAgICAgICAgICAgcmV0dXJuIGFyZy50cmltKCkucmVwbGFjZShwYXR0ZXJuLCAnJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBhcmc7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBEZXRlcm1pbmUgaWYgYXJnIHN0cmluZyBpcyB3cmFwcGVkIHdpdGggc3BlY2lmaWVkIGNoYXJcclxuICAgICAqIEBwYXJhbSBhcmcgSW5wdXQgYXJnIHN0cmluZ1xyXG4gICAgICovXHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5faXNXcmFwcGVkID0gZnVuY3Rpb24gKGFyZywgd3JhcENoYXIpIHtcclxuICAgICAgICB2YXIgcGF0dGVybiA9IG5ldyBSZWdFeHAoXCJeXFxcXFxcXFw/XCIgKyB3cmFwQ2hhciArIFwiLitcXFxcXFxcXD9cIiArIHdyYXBDaGFyICsgXCIkXCIpO1xyXG4gICAgICAgIHJldHVybiBwYXR0ZXJuLnRlc3QoYXJnLnRyaW0oKSk7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX2dldFNwYXduRmlsZU5hbWUgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgIGlmIChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzQ21kRmlsZSgpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvY2Vzcy5lbnZbJ0NPTVNQRUMnXSB8fCAnY21kLmV4ZSc7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5zaGVsbCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fd3JhcEFyZyh0aGlzLnRvb2xQYXRoLCAnXCInKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudG9vbFBhdGg7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX2dldFNwYXduQXJncyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc0NtZEZpbGUoKSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGFyZ2xpbmUgPSBcIi9EIC9TIC9DIFxcXCJcIiArIHRoaXMuX3dpbmRvd3NRdW90ZUNtZEFyZyh0aGlzLnRvb2xQYXRoKTtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5hcmdzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXJnbGluZSArPSAnICc7XHJcbiAgICAgICAgICAgICAgICAgICAgYXJnbGluZSArPSBvcHRpb25zLndpbmRvd3NWZXJiYXRpbUFyZ3VtZW50cyA/IHRoaXMuYXJnc1tpXSA6IHRoaXMuX3dpbmRvd3NRdW90ZUNtZEFyZyh0aGlzLmFyZ3NbaV0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYXJnbGluZSArPSAnXCInO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFthcmdsaW5lXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy53aW5kb3dzVmVyYmF0aW1Bcmd1bWVudHMpIHtcclxuICAgICAgICAgICAgICAgIC8vIG5vdGUsIGluIE5vZGUgNi54IG9wdGlvbnMuYXJndjAgY2FuIGJlIHVzZWQgaW5zdGVhZCBvZiBvdmVycmlkaW5nIGFyZ3Muc2xpY2UgYW5kIGFyZ3MudW5zaGlmdC5cclxuICAgICAgICAgICAgICAgIC8vIGZvciBtb3JlIGRldGFpbHMsIHJlZmVyIHRvIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlanMvbm9kZS9ibG9iL3Y2LngvbGliL2NoaWxkX3Byb2Nlc3MuanNcclxuICAgICAgICAgICAgICAgIHZhciBhcmdzXzEgPSB0aGlzLmFyZ3Muc2xpY2UoMCk7IC8vIGNvcHkgdGhlIGFycmF5XHJcbiAgICAgICAgICAgICAgICAvLyBvdmVycmlkZSBzbGljZSB0byBwcmV2ZW50IE5vZGUgZnJvbSBjcmVhdGluZyBhIGNvcHkgb2YgdGhlIGFyZyBhcnJheS5cclxuICAgICAgICAgICAgICAgIC8vIHdlIG5lZWQgTm9kZSB0byB1c2UgdGhlIFwidW5zaGlmdFwiIG92ZXJyaWRlIGJlbG93LlxyXG4gICAgICAgICAgICAgICAgYXJnc18xLnNsaWNlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoICE9IDEgfHwgYXJndW1lbnRzWzBdICE9IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmV4cGVjdGVkIGFyZ3VtZW50cyBwYXNzZWQgdG8gYXJncy5zbGljZSB3aGVuIHdpbmRvd3NWZXJiYXRpbUFyZ3VtZW50cyBmbGFnIGlzIHNldC4nKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFyZ3NfMTtcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAvLyBvdmVycmlkZSB1bnNoaWZ0XHJcbiAgICAgICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAgICAgLy8gd2hlbiB1c2luZyB0aGUgd2luZG93c1ZlcmJhdGltQXJndW1lbnRzIG9wdGlvbiwgTm9kZSBkb2VzIG5vdCBxdW90ZSB0aGUgdG9vbCBwYXRoIHdoZW4gYnVpbGRpbmdcclxuICAgICAgICAgICAgICAgIC8vIHRoZSBjbWRsaW5lIHBhcmFtZXRlciBmb3IgdGhlIHdpbjMyIGZ1bmN0aW9uIENyZWF0ZVByb2Nlc3MoKS4gYW4gdW5xdW90ZWQgc3BhY2UgaW4gdGhlIHRvb2wgcGF0aFxyXG4gICAgICAgICAgICAgICAgLy8gY2F1c2VzIHByb2JsZW1zIGZvciB0b29scyB3aGVuIGF0dGVtcHRpbmcgdG8gcGFyc2UgdGhlaXIgb3duIGNvbW1hbmQgbGluZSBhcmdzLiB0b29scyB0eXBpY2FsbHlcclxuICAgICAgICAgICAgICAgIC8vIGFzc3VtZSB0aGVpciBhcmd1bWVudHMgYmVnaW4gYWZ0ZXIgYXJnIDAuXHJcbiAgICAgICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAgICAgLy8gYnkgaGlqYWNraW5nIHVuc2hpZnQsIHdlIGNhbiBxdW90ZSB0aGUgdG9vbCBwYXRoIHdoZW4gaXQgcHVzaGVkIG9udG8gdGhlIGFyZ3MgYXJyYXkuIE5vZGUgYnVpbGRzXHJcbiAgICAgICAgICAgICAgICAvLyB0aGUgY21kbGluZSBwYXJhbWV0ZXIgZnJvbSB0aGUgYXJncyBhcnJheS5cclxuICAgICAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgICAgICAvLyBub3RlLCB3ZSBjYW4ndCBzaW1wbHkgcGFzcyBhIHF1b3RlZCB0b29sIHBhdGggdG8gTm9kZSBmb3IgbXVsdGlwbGUgcmVhc29uczpcclxuICAgICAgICAgICAgICAgIC8vICAgMSkgTm9kZSB2ZXJpZmllcyB0aGUgZmlsZSBleGlzdHMgKGNhbGxzIHdpbjMyIGZ1bmN0aW9uIEdldEZpbGVBdHRyaWJ1dGVzVykgYW5kIHRoZSBjaGVjayByZXR1cm5zXHJcbiAgICAgICAgICAgICAgICAvLyAgICAgIGZhbHNlIGlmIHRoZSBwYXRoIGlzIHF1b3RlZC5cclxuICAgICAgICAgICAgICAgIC8vICAgMikgTm9kZSBwYXNzZXMgdGhlIHRvb2wgcGF0aCBhcyB0aGUgYXBwbGljYXRpb24gcGFyYW1ldGVyIHRvIENyZWF0ZVByb2Nlc3MsIHdoaWNoIGV4cGVjdHMgdGhlXHJcbiAgICAgICAgICAgICAgICAvLyAgICAgIHBhdGggdG8gYmUgdW5xdW90ZWQuXHJcbiAgICAgICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAgICAgLy8gYWxzbyBub3RlLCBpbiBhZGRpdGlvbiB0byB0aGUgdG9vbCBwYXRoIGJlaW5nIGVtYmVkZGVkIHdpdGhpbiB0aGUgY21kbGluZSBwYXJhbWV0ZXIsIE5vZGUgYWxzb1xyXG4gICAgICAgICAgICAgICAgLy8gcGFzc2VzIHRoZSB0b29sIHBhdGggdG8gQ3JlYXRlUHJvY2VzcyB2aWEgdGhlIGFwcGxpY2F0aW9uIHBhcmFtZXRlciAob3B0aW9uYWwgcGFyYW1ldGVyKS4gd2hlblxyXG4gICAgICAgICAgICAgICAgLy8gcHJlc2VudCwgV2luZG93cyB1c2VzIHRoZSBhcHBsaWNhdGlvbiBwYXJhbWV0ZXIgdG8gZGV0ZXJtaW5lIHdoaWNoIGZpbGUgdG8gcnVuLCBpbnN0ZWFkIG9mXHJcbiAgICAgICAgICAgICAgICAvLyBpbnRlcnByZXRpbmcgdGhlIGZpbGUgZnJvbSB0aGUgY21kbGluZSBwYXJhbWV0ZXIuXHJcbiAgICAgICAgICAgICAgICBhcmdzXzEudW5zaGlmdCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCAhPSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBhcmd1bWVudHMgcGFzc2VkIHRvIGFyZ3MudW5zaGlmdCB3aGVuIHdpbmRvd3NWZXJiYXRpbUFyZ3VtZW50cyBmbGFnIGlzIHNldC4nKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS51bnNoaWZ0LmNhbGwoYXJnc18xLCBcIlxcXCJcIiArIGFyZ3VtZW50c1swXSArIFwiXFxcIlwiKTsgLy8gcXVvdGUgdGhlIGZpbGUgbmFtZVxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBhcmdzXzE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAob3B0aW9ucy5zaGVsbCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGFyZ3MgPSBbXTtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSB0aGlzLmFyZ3M7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFyZyA9IF9hW19pXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fbmVlZFF1b3Rlc0ZvckNtZChhcmcsICclJykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXJncy5wdXNoKHRoaXMuX3dyYXBBcmcoYXJnLCAnXCInKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhcmdzLnB1c2goYXJnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYXJncztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChvcHRpb25zLnNoZWxsKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFyZ3MubWFwKGZ1bmN0aW9uIChhcmcpIHtcclxuICAgICAgICAgICAgICAgIGlmIChfdGhpcy5faXNXcmFwcGVkKGFyZywgXCInXCIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFyZztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIHJlbW92ZSB3cmFwcGluZyBkb3VibGUgcXVvdGVzIHRvIGF2b2lkIGVzY2FwaW5nXHJcbiAgICAgICAgICAgICAgICBhcmcgPSBfdGhpcy5fdW53cmFwQXJnKGFyZywgJ1wiJyk7XHJcbiAgICAgICAgICAgICAgICBhcmcgPSBfdGhpcy5fZXNjYXBlQ2hhcihhcmcsICdcIicpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzLl93cmFwQXJnKGFyZywgJ1wiJyk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy5hcmdzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogRXNjYXBlIHNwZWNpZmllZCBjaGFyYWN0ZXIuXHJcbiAgICAgKiBAcGFyYW0gYXJnIFN0cmluZyB0byBlc2NhcGUgY2hhciBpblxyXG4gICAgICogQHBhcmFtIGNoYXJUb0VzY2FwZSBDaGFyIHNob3VsZCBiZSBlc2NhcGVkXHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl9lc2NhcGVDaGFyID0gZnVuY3Rpb24gKGFyZywgY2hhclRvRXNjYXBlKSB7XHJcbiAgICAgICAgdmFyIGVzY0NoYXIgPSBcIlxcXFxcIjtcclxuICAgICAgICB2YXIgb3V0cHV0ID0gJyc7XHJcbiAgICAgICAgdmFyIGNoYXJJc0VzY2FwZWQgPSBmYWxzZTtcclxuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIGFyZ18xID0gYXJnOyBfaSA8IGFyZ18xLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICB2YXIgY2hhciA9IGFyZ18xW19pXTtcclxuICAgICAgICAgICAgaWYgKGNoYXIgPT09IGNoYXJUb0VzY2FwZSAmJiAhY2hhcklzRXNjYXBlZCkge1xyXG4gICAgICAgICAgICAgICAgb3V0cHV0ICs9IGVzY0NoYXIgKyBjaGFyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgb3V0cHV0ICs9IGNoYXI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2hhcklzRXNjYXBlZCA9IGNoYXIgPT09IGVzY0NoYXIgJiYgIWNoYXJJc0VzY2FwZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvdXRwdXQ7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX2lzQ21kRmlsZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgdXBwZXJUb29sUGF0aCA9IHRoaXMudG9vbFBhdGgudG9VcHBlckNhc2UoKTtcclxuICAgICAgICByZXR1cm4gaW0uX2VuZHNXaXRoKHVwcGVyVG9vbFBhdGgsICcuQ01EJykgfHwgaW0uX2VuZHNXaXRoKHVwcGVyVG9vbFBhdGgsICcuQkFUJyk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgY21kIGFyZyBuZWVkcyB0byBiZSBxdW90ZWQuIFJldHVybnMgdHJ1ZSBpZiBhcmcgY29udGFpbnMgYW55IG9mIHNwZWNpYWwgY2hhcnMgYXJyYXkuXHJcbiAgICAgKiBAcGFyYW0gYXJnIFRoZSBjbWQgY29tbWFuZCBhcmcuXHJcbiAgICAgKiBAcGFyYW0gYWRkaXRpb25hbENoYXJzIEFkZGl0aW9uYWwgY2hhcnMgd2hpY2ggc2hvdWxkIGJlIGFsc28gY2hlY2tlZC5cclxuICAgICAqL1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX25lZWRRdW90ZXNGb3JDbWQgPSBmdW5jdGlvbiAoYXJnLCBhZGRpdGlvbmFsQ2hhcnMpIHtcclxuICAgICAgICB2YXIgc3BlY2lhbENoYXJzID0gdGhpcy5jbWRTcGVjaWFsQ2hhcnM7XHJcbiAgICAgICAgaWYgKGFkZGl0aW9uYWxDaGFycykge1xyXG4gICAgICAgICAgICBzcGVjaWFsQ2hhcnMgPSB0aGlzLmNtZFNwZWNpYWxDaGFycy5jb25jYXQoYWRkaXRpb25hbENoYXJzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIF9sb29wXzEgPSBmdW5jdGlvbiAoY2hhcikge1xyXG4gICAgICAgICAgICBpZiAoc3BlY2lhbENoYXJzLnNvbWUoZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHggPT09IGNoYXI7IH0pKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogdHJ1ZSB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIGFyZ18yID0gYXJnOyBfaSA8IGFyZ18yLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICB2YXIgY2hhciA9IGFyZ18yW19pXTtcclxuICAgICAgICAgICAgdmFyIHN0YXRlXzEgPSBfbG9vcF8xKGNoYXIpO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHN0YXRlXzEgPT09IFwib2JqZWN0XCIpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RhdGVfMS52YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfTtcclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl93aW5kb3dzUXVvdGVDbWRBcmcgPSBmdW5jdGlvbiAoYXJnKSB7XHJcbiAgICAgICAgLy8gZm9yIC5leGUsIGFwcGx5IHRoZSBub3JtYWwgcXVvdGluZyBydWxlcyB0aGF0IGxpYnV2IGFwcGxpZXNcclxuICAgICAgICBpZiAoIXRoaXMuX2lzQ21kRmlsZSgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl91dl9xdW90ZV9jbWRfYXJnKGFyZyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIG90aGVyd2lzZSBhcHBseSBxdW90aW5nIHJ1bGVzIHNwZWNpZmljIHRvIHRoZSBjbWQuZXhlIGNvbW1hbmQgbGluZSBwYXJzZXIuXHJcbiAgICAgICAgLy8gdGhlIGxpYnV2IHJ1bGVzIGFyZSBnZW5lcmljIGFuZCBhcmUgbm90IGRlc2lnbmVkIHNwZWNpZmljYWxseSBmb3IgY21kLmV4ZVxyXG4gICAgICAgIC8vIGNvbW1hbmQgbGluZSBwYXJzZXIuXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBmb3IgYSBkZXRhaWxlZCBkZXNjcmlwdGlvbiBvZiB0aGUgY21kLmV4ZSBjb21tYW5kIGxpbmUgcGFyc2VyLCByZWZlciB0b1xyXG4gICAgICAgIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDA5NDY5OS9ob3ctZG9lcy10aGUtd2luZG93cy1jb21tYW5kLWludGVycHJldGVyLWNtZC1leGUtcGFyc2Utc2NyaXB0cy83OTcwOTEyIzc5NzA5MTJcclxuICAgICAgICAvLyBuZWVkIHF1b3RlcyBmb3IgZW1wdHkgYXJnXHJcbiAgICAgICAgaWYgKCFhcmcpIHtcclxuICAgICAgICAgICAgcmV0dXJuICdcIlwiJztcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGFyZyBuZWVkcyB0byBiZSBxdW90ZWRcclxuICAgICAgICB2YXIgbmVlZHNRdW90ZXMgPSB0aGlzLl9uZWVkUXVvdGVzRm9yQ21kKGFyZyk7XHJcbiAgICAgICAgLy8gc2hvcnQtY2lyY3VpdCBpZiBxdW90ZXMgbm90IG5lZWRlZFxyXG4gICAgICAgIGlmICghbmVlZHNRdW90ZXMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGFyZztcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gdGhlIGZvbGxvd2luZyBxdW90aW5nIHJ1bGVzIGFyZSB2ZXJ5IHNpbWlsYXIgdG8gdGhlIHJ1bGVzIHRoYXQgYnkgbGlidXYgYXBwbGllcy5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIDEpIHdyYXAgdGhlIHN0cmluZyBpbiBxdW90ZXNcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIDIpIGRvdWJsZS11cCBxdW90ZXMgLSBpLmUuIFwiID0+IFwiXCJcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vICAgIHRoaXMgaXMgZGlmZmVyZW50IGZyb20gdGhlIGxpYnV2IHF1b3RpbmcgcnVsZXMuIGxpYnV2IHJlcGxhY2VzIFwiIHdpdGggXFxcIiwgd2hpY2ggdW5mb3J0dW5hdGVseVxyXG4gICAgICAgIC8vICAgIGRvZXNuJ3Qgd29yayB3ZWxsIHdpdGggYSBjbWQuZXhlIGNvbW1hbmQgbGluZS5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vICAgIG5vdGUsIHJlcGxhY2luZyBcIiB3aXRoIFwiXCIgYWxzbyB3b3JrcyB3ZWxsIGlmIHRoZSBhcmcgaXMgcGFzc2VkIHRvIGEgZG93bnN0cmVhbSAuTkVUIGNvbnNvbGUgYXBwLlxyXG4gICAgICAgIC8vICAgIGZvciBleGFtcGxlLCB0aGUgY29tbWFuZCBsaW5lOlxyXG4gICAgICAgIC8vICAgICAgICAgIGZvby5leGUgXCJteWFyZzpcIlwibXkgdmFsXCJcIlwiXHJcbiAgICAgICAgLy8gICAgaXMgcGFyc2VkIGJ5IGEgLk5FVCBjb25zb2xlIGFwcCBpbnRvIGFuIGFyZyBhcnJheTpcclxuICAgICAgICAvLyAgICAgICAgICBbIFwibXlhcmc6XFxcIm15IHZhbFxcXCJcIiBdXHJcbiAgICAgICAgLy8gICAgd2hpY2ggaXMgdGhlIHNhbWUgZW5kIHJlc3VsdCB3aGVuIGFwcGx5aW5nIGxpYnV2IHF1b3RpbmcgcnVsZXMuIGFsdGhvdWdoIHRoZSBhY3R1YWxcclxuICAgICAgICAvLyAgICBjb21tYW5kIGxpbmUgZnJvbSBsaWJ1diBxdW90aW5nIHJ1bGVzIHdvdWxkIGxvb2sgbGlrZTpcclxuICAgICAgICAvLyAgICAgICAgICBmb28uZXhlIFwibXlhcmc6XFxcIm15IHZhbFxcXCJcIlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gMykgZG91YmxlLXVwIHNsYXNoZXMgdGhhdCBwcmVjZWVkIGEgcXVvdGUsXHJcbiAgICAgICAgLy8gICAgZS5nLiAgaGVsbG8gXFx3b3JsZCAgICA9PiBcImhlbGxvIFxcd29ybGRcIlxyXG4gICAgICAgIC8vICAgICAgICAgIGhlbGxvXFxcIndvcmxkICAgID0+IFwiaGVsbG9cXFxcXCJcIndvcmxkXCJcclxuICAgICAgICAvLyAgICAgICAgICBoZWxsb1xcXFxcIndvcmxkICAgPT4gXCJoZWxsb1xcXFxcXFxcXCJcIndvcmxkXCJcclxuICAgICAgICAvLyAgICAgICAgICBoZWxsbyB3b3JsZFxcICAgID0+IFwiaGVsbG8gd29ybGRcXFxcXCJcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vICAgIHRlY2huaWNhbGx5IHRoaXMgaXMgbm90IHJlcXVpcmVkIGZvciBhIGNtZC5leGUgY29tbWFuZCBsaW5lLCBvciB0aGUgYmF0Y2ggYXJndW1lbnQgcGFyc2VyLlxyXG4gICAgICAgIC8vICAgIHRoZSByZWFzb25zIGZvciBpbmNsdWRpbmcgdGhpcyBhcyBhIC5jbWQgcXVvdGluZyBydWxlIGFyZTpcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vICAgIGEpIHRoaXMgaXMgb3B0aW1pemVkIGZvciB0aGUgc2NlbmFyaW8gd2hlcmUgdGhlIGFyZ3VtZW50IGlzIHBhc3NlZCBmcm9tIHRoZSAuY21kIGZpbGUgdG8gYW5cclxuICAgICAgICAvLyAgICAgICBleHRlcm5hbCBwcm9ncmFtLiBtYW55IHByb2dyYW1zIChlLmcuIC5ORVQgY29uc29sZSBhcHBzKSByZWx5IG9uIHRoZSBzbGFzaC1kb3VibGluZyBydWxlLlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gICAgYikgaXQncyB3aGF0IHdlJ3ZlIGJlZW4gZG9pbmcgcHJldmlvdXNseSAoYnkgZGVmZXJyaW5nIHRvIG5vZGUgZGVmYXVsdCBiZWhhdmlvcikgYW5kIHdlXHJcbiAgICAgICAgLy8gICAgICAgaGF2ZW4ndCBoZWFyZCBhbnkgY29tcGxhaW50cyBhYm91dCB0aGF0IGFzcGVjdC5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIG5vdGUsIGEgd2Vha25lc3Mgb2YgdGhlIHF1b3RpbmcgcnVsZXMgY2hvc2VuIGhlcmUsIGlzIHRoYXQgJSBpcyBub3QgZXNjYXBlZC4gaW4gZmFjdCwgJSBjYW5ub3QgYmVcclxuICAgICAgICAvLyBlc2NhcGVkIHdoZW4gdXNlZCBvbiB0aGUgY29tbWFuZCBsaW5lIGRpcmVjdGx5IC0gZXZlbiB0aG91Z2ggd2l0aGluIGEgLmNtZCBmaWxlICUgY2FuIGJlIGVzY2FwZWRcclxuICAgICAgICAvLyBieSB1c2luZyAlJS5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIHRoZSBzYXZpbmcgZ3JhY2UgaXMsIG9uIHRoZSBjb21tYW5kIGxpbmUsICV2YXIlIGlzIGxlZnQgYXMtaXMgaWYgdmFyIGlzIG5vdCBkZWZpbmVkLiB0aGlzIGNvbnRyYXN0c1xyXG4gICAgICAgIC8vIHRoZSBsaW5lIHBhcnNpbmcgcnVsZXMgd2l0aGluIGEgLmNtZCBmaWxlLCB3aGVyZSBpZiB2YXIgaXMgbm90IGRlZmluZWQgaXQgaXMgcmVwbGFjZWQgd2l0aCBub3RoaW5nLlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gb25lIG9wdGlvbiB0aGF0IHdhcyBleHBsb3JlZCB3YXMgcmVwbGFjaW5nICUgd2l0aCBeJSAtIGkuZS4gJXZhciUgPT4gXiV2YXJeJS4gdGhpcyBoYWNrIHdvdWxkXHJcbiAgICAgICAgLy8gb2Z0ZW4gd29yaywgc2luY2UgaXQgaXMgdW5saWtlbHkgdGhhdCB2YXJeIHdvdWxkIGV4aXN0LCBhbmQgdGhlIF4gY2hhcmFjdGVyIGlzIHJlbW92ZWQgd2hlbiB0aGVcclxuICAgICAgICAvLyB2YXJpYWJsZSBpcyB1c2VkLiB0aGUgcHJvYmxlbSwgaG93ZXZlciwgaXMgdGhhdCBeIGlzIG5vdCByZW1vdmVkIHdoZW4gJSogaXMgdXNlZCB0byBwYXNzIHRoZSBhcmdzXHJcbiAgICAgICAgLy8gdG8gYW4gZXh0ZXJuYWwgcHJvZ3JhbS5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIGFuIHVuZXhwbG9yZWQgcG90ZW50aWFsIHNvbHV0aW9uIGZvciB0aGUgJSBlc2NhcGluZyBwcm9ibGVtLCBpcyB0byBjcmVhdGUgYSB3cmFwcGVyIC5jbWQgZmlsZS5cclxuICAgICAgICAvLyAlIGNhbiBiZSBlc2NhcGVkIHdpdGhpbiBhIC5jbWQgZmlsZS5cclxuICAgICAgICB2YXIgcmV2ZXJzZSA9ICdcIic7XHJcbiAgICAgICAgdmFyIHF1b3RlX2hpdCA9IHRydWU7XHJcbiAgICAgICAgZm9yICh2YXIgaSA9IGFyZy5sZW5ndGg7IGkgPiAwOyBpLS0pIHsgLy8gd2FsayB0aGUgc3RyaW5nIGluIHJldmVyc2VcclxuICAgICAgICAgICAgcmV2ZXJzZSArPSBhcmdbaSAtIDFdO1xyXG4gICAgICAgICAgICBpZiAocXVvdGVfaGl0ICYmIGFyZ1tpIC0gMV0gPT0gJ1xcXFwnKSB7XHJcbiAgICAgICAgICAgICAgICByZXZlcnNlICs9ICdcXFxcJzsgLy8gZG91YmxlIHRoZSBzbGFzaFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGFyZ1tpIC0gMV0gPT0gJ1wiJykge1xyXG4gICAgICAgICAgICAgICAgcXVvdGVfaGl0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHJldmVyc2UgKz0gJ1wiJzsgLy8gZG91YmxlIHRoZSBxdW90ZVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcXVvdGVfaGl0ID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV2ZXJzZSArPSAnXCInO1xyXG4gICAgICAgIHJldHVybiByZXZlcnNlLnNwbGl0KCcnKS5yZXZlcnNlKCkuam9pbignJyk7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX3V2X3F1b3RlX2NtZF9hcmcgPSBmdW5jdGlvbiAoYXJnKSB7XHJcbiAgICAgICAgLy8gVG9vbCBydW5uZXIgd3JhcHMgY2hpbGRfcHJvY2Vzcy5zcGF3bigpIGFuZCBuZWVkcyB0byBhcHBseSB0aGUgc2FtZSBxdW90aW5nIGFzXHJcbiAgICAgICAgLy8gTm9kZSBpbiBjZXJ0YWluIGNhc2VzIHdoZXJlIHRoZSB1bmRvY3VtZW50ZWQgc3Bhd24gb3B0aW9uIHdpbmRvd3NWZXJiYXRpbUFyZ3VtZW50c1xyXG4gICAgICAgIC8vIGlzIHVzZWQuXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBTaW5jZSB0aGlzIGZ1bmN0aW9uIGlzIGEgcG9ydCBvZiBxdW90ZV9jbWRfYXJnIGZyb20gTm9kZSA0LnggKHRlY2huaWNhbGx5LCBsaWIgVVYsXHJcbiAgICAgICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlanMvbm9kZS9ibG9iL3Y0LngvZGVwcy91di9zcmMvd2luL3Byb2Nlc3MuYyBmb3IgZGV0YWlscyksXHJcbiAgICAgICAgLy8gcGFzdGluZyBjb3B5cmlnaHQgbm90aWNlIGZyb20gTm9kZSB3aXRoaW4gdGhpcyBmdW5jdGlvbjpcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vICAgICAgQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyAgICAgIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcclxuICAgICAgICAvLyAgICAgIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXHJcbiAgICAgICAgLy8gICAgICBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxyXG4gICAgICAgIC8vICAgICAgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXHJcbiAgICAgICAgLy8gICAgICBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xyXG4gICAgICAgIC8vICAgICAgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vICAgICAgVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cclxuICAgICAgICAvLyAgICAgIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gICAgICBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXHJcbiAgICAgICAgLy8gICAgICBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcclxuICAgICAgICAvLyAgICAgIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxyXG4gICAgICAgIC8vICAgICAgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxyXG4gICAgICAgIC8vICAgICAgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcclxuICAgICAgICAvLyAgICAgIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1NcclxuICAgICAgICAvLyAgICAgIElOIFRIRSBTT0ZUV0FSRS5cclxuICAgICAgICBpZiAoIWFyZykge1xyXG4gICAgICAgICAgICAvLyBOZWVkIGRvdWJsZSBxdW90YXRpb24gZm9yIGVtcHR5IGFyZ3VtZW50XHJcbiAgICAgICAgICAgIHJldHVybiAnXCJcIic7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChhcmcuaW5kZXhPZignICcpIDwgMCAmJiBhcmcuaW5kZXhPZignXFx0JykgPCAwICYmIGFyZy5pbmRleE9mKCdcIicpIDwgMCkge1xyXG4gICAgICAgICAgICAvLyBObyBxdW90YXRpb24gbmVlZGVkXHJcbiAgICAgICAgICAgIHJldHVybiBhcmc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChhcmcuaW5kZXhPZignXCInKSA8IDAgJiYgYXJnLmluZGV4T2YoJ1xcXFwnKSA8IDApIHtcclxuICAgICAgICAgICAgLy8gTm8gZW1iZWRkZWQgZG91YmxlIHF1b3RlcyBvciBiYWNrc2xhc2hlcywgc28gSSBjYW4ganVzdCB3cmFwXHJcbiAgICAgICAgICAgIC8vIHF1b3RlIG1hcmtzIGFyb3VuZCB0aGUgd2hvbGUgdGhpbmcuXHJcbiAgICAgICAgICAgIHJldHVybiBcIlxcXCJcIiArIGFyZyArIFwiXFxcIlwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBFeHBlY3RlZCBpbnB1dC9vdXRwdXQ6XHJcbiAgICAgICAgLy8gICBpbnB1dCA6IGhlbGxvXCJ3b3JsZFxyXG4gICAgICAgIC8vICAgb3V0cHV0OiBcImhlbGxvXFxcIndvcmxkXCJcclxuICAgICAgICAvLyAgIGlucHV0IDogaGVsbG9cIlwid29ybGRcclxuICAgICAgICAvLyAgIG91dHB1dDogXCJoZWxsb1xcXCJcXFwid29ybGRcIlxyXG4gICAgICAgIC8vICAgaW5wdXQgOiBoZWxsb1xcd29ybGRcclxuICAgICAgICAvLyAgIG91dHB1dDogaGVsbG9cXHdvcmxkXHJcbiAgICAgICAgLy8gICBpbnB1dCA6IGhlbGxvXFxcXHdvcmxkXHJcbiAgICAgICAgLy8gICBvdXRwdXQ6IGhlbGxvXFxcXHdvcmxkXHJcbiAgICAgICAgLy8gICBpbnB1dCA6IGhlbGxvXFxcIndvcmxkXHJcbiAgICAgICAgLy8gICBvdXRwdXQ6IFwiaGVsbG9cXFxcXFxcIndvcmxkXCJcclxuICAgICAgICAvLyAgIGlucHV0IDogaGVsbG9cXFxcXCJ3b3JsZFxyXG4gICAgICAgIC8vICAgb3V0cHV0OiBcImhlbGxvXFxcXFxcXFxcXFwid29ybGRcIlxyXG4gICAgICAgIC8vICAgaW5wdXQgOiBoZWxsbyB3b3JsZFxcXHJcbiAgICAgICAgLy8gICBvdXRwdXQ6IFwiaGVsbG8gd29ybGRcXFxcXCIgLSBub3RlIHRoZSBjb21tZW50IGluIGxpYnV2IGFjdHVhbGx5IHJlYWRzIFwiaGVsbG8gd29ybGRcXFwiXHJcbiAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1dCBpdCBhcHBlYXJzIHRoZSBjb21tZW50IGlzIHdyb25nLCBpdCBzaG91bGQgYmUgXCJoZWxsbyB3b3JsZFxcXFxcIlxyXG4gICAgICAgIHZhciByZXZlcnNlID0gJ1wiJztcclxuICAgICAgICB2YXIgcXVvdGVfaGl0ID0gdHJ1ZTtcclxuICAgICAgICBmb3IgKHZhciBpID0gYXJnLmxlbmd0aDsgaSA+IDA7IGktLSkgeyAvLyB3YWxrIHRoZSBzdHJpbmcgaW4gcmV2ZXJzZVxyXG4gICAgICAgICAgICByZXZlcnNlICs9IGFyZ1tpIC0gMV07XHJcbiAgICAgICAgICAgIGlmIChxdW90ZV9oaXQgJiYgYXJnW2kgLSAxXSA9PSAnXFxcXCcpIHtcclxuICAgICAgICAgICAgICAgIHJldmVyc2UgKz0gJ1xcXFwnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGFyZ1tpIC0gMV0gPT0gJ1wiJykge1xyXG4gICAgICAgICAgICAgICAgcXVvdGVfaGl0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHJldmVyc2UgKz0gJ1xcXFwnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcXVvdGVfaGl0ID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV2ZXJzZSArPSAnXCInO1xyXG4gICAgICAgIHJldHVybiByZXZlcnNlLnNwbGl0KCcnKS5yZXZlcnNlKCkuam9pbignJyk7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX2Nsb25lRXhlY09wdGlvbnMgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xyXG4gICAgICAgIHZhciByZXN1bHQgPSB7XHJcbiAgICAgICAgICAgIGN3ZDogb3B0aW9ucy5jd2QgfHwgcHJvY2Vzcy5jd2QoKSxcclxuICAgICAgICAgICAgZW52OiBvcHRpb25zLmVudiB8fCBwcm9jZXNzLmVudixcclxuICAgICAgICAgICAgc2lsZW50OiBvcHRpb25zLnNpbGVudCB8fCBmYWxzZSxcclxuICAgICAgICAgICAgZmFpbE9uU3RkRXJyOiBvcHRpb25zLmZhaWxPblN0ZEVyciB8fCBmYWxzZSxcclxuICAgICAgICAgICAgaWdub3JlUmV0dXJuQ29kZTogb3B0aW9ucy5pZ25vcmVSZXR1cm5Db2RlIHx8IGZhbHNlLFxyXG4gICAgICAgICAgICB3aW5kb3dzVmVyYmF0aW1Bcmd1bWVudHM6IG9wdGlvbnMud2luZG93c1ZlcmJhdGltQXJndW1lbnRzIHx8IGZhbHNlLFxyXG4gICAgICAgICAgICBzaGVsbDogb3B0aW9ucy5zaGVsbCB8fCBmYWxzZVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgcmVzdWx0Lm91dFN0cmVhbSA9IG9wdGlvbnMub3V0U3RyZWFtIHx8IHByb2Nlc3Muc3Rkb3V0O1xyXG4gICAgICAgIHJlc3VsdC5lcnJTdHJlYW0gPSBvcHRpb25zLmVyclN0cmVhbSB8fCBwcm9jZXNzLnN0ZGVycjtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfTtcclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl9nZXRTcGF3bk9wdGlvbnMgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xyXG4gICAgICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgICAgICByZXN1bHQuY3dkID0gb3B0aW9ucy5jd2Q7XHJcbiAgICAgICAgcmVzdWx0LmVudiA9IG9wdGlvbnMuZW52O1xyXG4gICAgICAgIHJlc3VsdC5zaGVsbCA9IG9wdGlvbnMuc2hlbGw7XHJcbiAgICAgICAgcmVzdWx0Wyd3aW5kb3dzVmVyYmF0aW1Bcmd1bWVudHMnXSA9IG9wdGlvbnMud2luZG93c1ZlcmJhdGltQXJndW1lbnRzIHx8IHRoaXMuX2lzQ21kRmlsZSgpO1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX2dldFNwYXduU3luY09wdGlvbnMgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgICAgICByZXN1bHQuY3dkID0gb3B0aW9ucy5jd2Q7XHJcbiAgICAgICAgcmVzdWx0LmVudiA9IG9wdGlvbnMuZW52O1xyXG4gICAgICAgIHJlc3VsdC5zaGVsbCA9IG9wdGlvbnMuc2hlbGw7XHJcbiAgICAgICAgcmVzdWx0Wyd3aW5kb3dzVmVyYmF0aW1Bcmd1bWVudHMnXSA9IG9wdGlvbnMud2luZG93c1ZlcmJhdGltQXJndW1lbnRzIHx8IHRoaXMuX2lzQ21kRmlsZSgpO1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuZXhlY1dpdGhQaXBpbmcgPSBmdW5jdGlvbiAocGlwZU91dHB1dFRvVG9vbCwgb3B0aW9ucykge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIGRlZmVyID0gUS5kZWZlcigpO1xyXG4gICAgICAgIHRoaXMuX2RlYnVnKCdleGVjIHRvb2w6ICcgKyB0aGlzLnRvb2xQYXRoKTtcclxuICAgICAgICB0aGlzLl9kZWJ1ZygnYXJndW1lbnRzOicpO1xyXG4gICAgICAgIHRoaXMuYXJncy5mb3JFYWNoKGZ1bmN0aW9uIChhcmcpIHtcclxuICAgICAgICAgICAgX3RoaXMuX2RlYnVnKCcgICAnICsgYXJnKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB2YXIgc3VjY2VzcyA9IHRydWU7XHJcbiAgICAgICAgdmFyIG9wdGlvbnNOb25OdWxsID0gdGhpcy5fY2xvbmVFeGVjT3B0aW9ucyhvcHRpb25zKTtcclxuICAgICAgICBpZiAoIW9wdGlvbnNOb25OdWxsLnNpbGVudCkge1xyXG4gICAgICAgICAgICBvcHRpb25zTm9uTnVsbC5vdXRTdHJlYW0ud3JpdGUodGhpcy5fZ2V0Q29tbWFuZFN0cmluZyhvcHRpb25zTm9uTnVsbCkgKyBvcy5FT0wpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgY3A7XHJcbiAgICAgICAgdmFyIHRvb2xQYXRoID0gcGlwZU91dHB1dFRvVG9vbC50b29sUGF0aDtcclxuICAgICAgICB2YXIgdG9vbFBhdGhGaXJzdDtcclxuICAgICAgICB2YXIgc3VjY2Vzc0ZpcnN0ID0gdHJ1ZTtcclxuICAgICAgICB2YXIgcmV0dXJuQ29kZUZpcnN0O1xyXG4gICAgICAgIHZhciBmaWxlU3RyZWFtO1xyXG4gICAgICAgIHZhciB3YWl0aW5nRXZlbnRzID0gMDsgLy8gbnVtYmVyIG9mIHByb2Nlc3Mgb3Igc3RyZWFtIGV2ZW50cyB3ZSBhcmUgd2FpdGluZyBvbiB0byBjb21wbGV0ZVxyXG4gICAgICAgIHZhciByZXR1cm5Db2RlID0gMDtcclxuICAgICAgICB2YXIgZXJyb3I7XHJcbiAgICAgICAgdG9vbFBhdGhGaXJzdCA9IHRoaXMudG9vbFBhdGg7XHJcbiAgICAgICAgLy8gRm9sbG93aW5nIG5vZGUgZG9jdW1lbnRhdGlvbiBleGFtcGxlIGZyb20gdGhpcyBsaW5rIG9uIGhvdyB0byBwaXBlIG91dHB1dCBvZiBvbmUgcHJvY2VzcyB0byBhbm90aGVyXHJcbiAgICAgICAgLy8gaHR0cHM6Ly9ub2RlanMub3JnL2FwaS9jaGlsZF9wcm9jZXNzLmh0bWwjY2hpbGRfcHJvY2Vzc19jaGlsZF9wcm9jZXNzX3NwYXduX2NvbW1hbmRfYXJnc19vcHRpb25zXHJcbiAgICAgICAgLy9zdGFydCB0aGUgY2hpbGQgcHJvY2VzcyBmb3IgYm90aCB0b29sc1xyXG4gICAgICAgIHdhaXRpbmdFdmVudHMrKztcclxuICAgICAgICB2YXIgY3BGaXJzdCA9IGNoaWxkLnNwYXduKHRoaXMuX2dldFNwYXduRmlsZU5hbWUob3B0aW9uc05vbk51bGwpLCB0aGlzLl9nZXRTcGF3bkFyZ3Mob3B0aW9uc05vbk51bGwpLCB0aGlzLl9nZXRTcGF3bk9wdGlvbnMob3B0aW9uc05vbk51bGwpKTtcclxuICAgICAgICB3YWl0aW5nRXZlbnRzKys7XHJcbiAgICAgICAgY3AgPSBjaGlsZC5zcGF3bihwaXBlT3V0cHV0VG9Ub29sLl9nZXRTcGF3bkZpbGVOYW1lKG9wdGlvbnNOb25OdWxsKSwgcGlwZU91dHB1dFRvVG9vbC5fZ2V0U3Bhd25BcmdzKG9wdGlvbnNOb25OdWxsKSwgcGlwZU91dHB1dFRvVG9vbC5fZ2V0U3Bhd25PcHRpb25zKG9wdGlvbnNOb25OdWxsKSk7XHJcbiAgICAgICAgZmlsZVN0cmVhbSA9IHRoaXMucGlwZU91dHB1dFRvRmlsZSA/IGZzLmNyZWF0ZVdyaXRlU3RyZWFtKHRoaXMucGlwZU91dHB1dFRvRmlsZSkgOiBudWxsO1xyXG4gICAgICAgIGlmIChmaWxlU3RyZWFtKSB7XHJcbiAgICAgICAgICAgIHdhaXRpbmdFdmVudHMrKztcclxuICAgICAgICAgICAgZmlsZVN0cmVhbS5vbignZmluaXNoJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgd2FpdGluZ0V2ZW50cy0tOyAvL2ZpbGUgd3JpdGUgaXMgY29tcGxldGVcclxuICAgICAgICAgICAgICAgIGZpbGVTdHJlYW0gPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgaWYgKHdhaXRpbmdFdmVudHMgPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZlci5yZWplY3QoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXIucmVzb2x2ZShyZXR1cm5Db2RlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBmaWxlU3RyZWFtLm9uKCdlcnJvcicsIGZ1bmN0aW9uIChlcnIpIHtcclxuICAgICAgICAgICAgICAgIHdhaXRpbmdFdmVudHMtLTsgLy90aGVyZSB3ZXJlIGVycm9ycyB3cml0aW5nIHRvIHRoZSBmaWxlLCB3cml0ZSBpcyBkb25lXHJcbiAgICAgICAgICAgICAgICBfdGhpcy5fZGVidWcoXCJGYWlsZWQgdG8gcGlwZSBvdXRwdXQgb2YgXCIgKyB0b29sUGF0aEZpcnN0ICsgXCIgdG8gZmlsZSBcIiArIF90aGlzLnBpcGVPdXRwdXRUb0ZpbGUgKyBcIi4gRXJyb3IgPSBcIiArIGVycik7XHJcbiAgICAgICAgICAgICAgICBmaWxlU3RyZWFtID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIGlmICh3YWl0aW5nRXZlbnRzID09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXIucmVqZWN0KGVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVyLnJlc29sdmUocmV0dXJuQ29kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy9waXBlIHN0ZG91dCBvZiBmaXJzdCB0b29sIHRvIHN0ZGluIG9mIHNlY29uZCB0b29sXHJcbiAgICAgICAgY3BGaXJzdC5zdGRvdXQub24oJ2RhdGEnLCBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGZpbGVTdHJlYW0pIHtcclxuICAgICAgICAgICAgICAgICAgICBmaWxlU3RyZWFtLndyaXRlKGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY3Auc3RkaW4ud3JpdGUoZGF0YSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuX2RlYnVnKCdGYWlsZWQgdG8gcGlwZSBvdXRwdXQgb2YgJyArIHRvb2xQYXRoRmlyc3QgKyAnIHRvICcgKyB0b29sUGF0aCk7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5fZGVidWcodG9vbFBhdGggKyAnIG1pZ2h0IGhhdmUgZXhpdGVkIGR1ZSB0byBlcnJvcnMgcHJlbWF0dXJlbHkuIFZlcmlmeSB0aGUgYXJndW1lbnRzIHBhc3NlZCBhcmUgdmFsaWQuJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICBjcEZpcnN0LnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICAgICAgICAgIGlmIChmaWxlU3RyZWFtKSB7XHJcbiAgICAgICAgICAgICAgICBmaWxlU3RyZWFtLndyaXRlKGRhdGEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHN1Y2Nlc3NGaXJzdCA9ICFvcHRpb25zTm9uTnVsbC5mYWlsT25TdGRFcnI7XHJcbiAgICAgICAgICAgIGlmICghb3B0aW9uc05vbk51bGwuc2lsZW50KSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgcyA9IG9wdGlvbnNOb25OdWxsLmZhaWxPblN0ZEVyciA/IG9wdGlvbnNOb25OdWxsLmVyclN0cmVhbSA6IG9wdGlvbnNOb25OdWxsLm91dFN0cmVhbTtcclxuICAgICAgICAgICAgICAgIHMud3JpdGUoZGF0YSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICBjcEZpcnN0Lm9uKCdlcnJvcicsIGZ1bmN0aW9uIChlcnIpIHtcclxuICAgICAgICAgICAgd2FpdGluZ0V2ZW50cy0tOyAvL2ZpcnN0IHByb2Nlc3MgaXMgY29tcGxldGUgd2l0aCBlcnJvcnNcclxuICAgICAgICAgICAgaWYgKGZpbGVTdHJlYW0pIHtcclxuICAgICAgICAgICAgICAgIGZpbGVTdHJlYW0uZW5kKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY3Auc3RkaW4uZW5kKCk7XHJcbiAgICAgICAgICAgIGVycm9yID0gbmV3IEVycm9yKHRvb2xQYXRoRmlyc3QgKyAnIGZhaWxlZC4gJyArIGVyci5tZXNzYWdlKTtcclxuICAgICAgICAgICAgaWYgKHdhaXRpbmdFdmVudHMgPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgZGVmZXIucmVqZWN0KGVycm9yKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGNwRmlyc3Qub24oJ2Nsb3NlJywgZnVuY3Rpb24gKGNvZGUsIHNpZ25hbCkge1xyXG4gICAgICAgICAgICB3YWl0aW5nRXZlbnRzLS07IC8vZmlyc3QgcHJvY2VzcyBpcyBjb21wbGV0ZVxyXG4gICAgICAgICAgICBpZiAoY29kZSAhPSAwICYmICFvcHRpb25zTm9uTnVsbC5pZ25vcmVSZXR1cm5Db2RlKSB7XHJcbiAgICAgICAgICAgICAgICBzdWNjZXNzRmlyc3QgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHJldHVybkNvZGVGaXJzdCA9IGNvZGU7XHJcbiAgICAgICAgICAgICAgICByZXR1cm5Db2RlID0gcmV0dXJuQ29kZUZpcnN0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF90aGlzLl9kZWJ1Zygnc3VjY2VzcyBvZiBmaXJzdCB0b29sOicgKyBzdWNjZXNzRmlyc3QpO1xyXG4gICAgICAgICAgICBpZiAoZmlsZVN0cmVhbSkge1xyXG4gICAgICAgICAgICAgICAgZmlsZVN0cmVhbS5lbmQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjcC5zdGRpbi5lbmQoKTtcclxuICAgICAgICAgICAgaWYgKHdhaXRpbmdFdmVudHMgPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVmZXIucmVqZWN0KGVycm9yKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmVyLnJlc29sdmUocmV0dXJuQ29kZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICB2YXIgc3RkYnVmZmVyID0gJyc7XHJcbiAgICAgICAgY3Auc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGRhdGEpIHtcclxuICAgICAgICAgICAgX3RoaXMuZW1pdCgnc3Rkb3V0JywgZGF0YSk7XHJcbiAgICAgICAgICAgIGlmICghb3B0aW9uc05vbk51bGwuc2lsZW50KSB7XHJcbiAgICAgICAgICAgICAgICBvcHRpb25zTm9uTnVsbC5vdXRTdHJlYW0ud3JpdGUoZGF0YSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgX3RoaXMuX3Byb2Nlc3NMaW5lQnVmZmVyKGRhdGEsIHN0ZGJ1ZmZlciwgZnVuY3Rpb24gKGxpbmUpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmVtaXQoJ3N0ZGxpbmUnLCBsaW5lKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdmFyIGVycmJ1ZmZlciA9ICcnO1xyXG4gICAgICAgIGNwLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICAgICAgICAgIF90aGlzLmVtaXQoJ3N0ZGVycicsIGRhdGEpO1xyXG4gICAgICAgICAgICBzdWNjZXNzID0gIW9wdGlvbnNOb25OdWxsLmZhaWxPblN0ZEVycjtcclxuICAgICAgICAgICAgaWYgKCFvcHRpb25zTm9uTnVsbC5zaWxlbnQpIHtcclxuICAgICAgICAgICAgICAgIHZhciBzID0gb3B0aW9uc05vbk51bGwuZmFpbE9uU3RkRXJyID8gb3B0aW9uc05vbk51bGwuZXJyU3RyZWFtIDogb3B0aW9uc05vbk51bGwub3V0U3RyZWFtO1xyXG4gICAgICAgICAgICAgICAgcy53cml0ZShkYXRhKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBfdGhpcy5fcHJvY2Vzc0xpbmVCdWZmZXIoZGF0YSwgZXJyYnVmZmVyLCBmdW5jdGlvbiAobGluZSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZW1pdCgnZXJybGluZScsIGxpbmUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBjcC5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICAgIHdhaXRpbmdFdmVudHMtLTsgLy9wcm9jZXNzIGlzIGRvbmUgd2l0aCBlcnJvcnNcclxuICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IodG9vbFBhdGggKyAnIGZhaWxlZC4gJyArIGVyci5tZXNzYWdlKTtcclxuICAgICAgICAgICAgaWYgKHdhaXRpbmdFdmVudHMgPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgZGVmZXIucmVqZWN0KGVycm9yKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGNwLm9uKCdjbG9zZScsIGZ1bmN0aW9uIChjb2RlLCBzaWduYWwpIHtcclxuICAgICAgICAgICAgd2FpdGluZ0V2ZW50cy0tOyAvL3Byb2Nlc3MgaXMgY29tcGxldGVcclxuICAgICAgICAgICAgX3RoaXMuX2RlYnVnKCdyYzonICsgY29kZSk7XHJcbiAgICAgICAgICAgIHJldHVybkNvZGUgPSBjb2RlO1xyXG4gICAgICAgICAgICBpZiAoc3RkYnVmZmVyLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmVtaXQoJ3N0ZGxpbmUnLCBzdGRidWZmZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlcnJidWZmZXIubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZW1pdCgnZXJybGluZScsIGVycmJ1ZmZlcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGNvZGUgIT0gMCAmJiAhb3B0aW9uc05vbk51bGwuaWdub3JlUmV0dXJuQ29kZSkge1xyXG4gICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF90aGlzLl9kZWJ1Zygnc3VjY2VzczonICsgc3VjY2Vzcyk7XHJcbiAgICAgICAgICAgIGlmICghc3VjY2Vzc0ZpcnN0KSB7IC8vaW4gdGhlIGNhc2Ugb3V0cHV0IGlzIHBpcGVkIHRvIGFub3RoZXIgdG9vbCwgY2hlY2sgZXhpdCBjb2RlIG9mIGJvdGggdG9vbHNcclxuICAgICAgICAgICAgICAgIGVycm9yID0gbmV3IEVycm9yKHRvb2xQYXRoRmlyc3QgKyAnIGZhaWxlZCB3aXRoIHJldHVybiBjb2RlOiAnICsgcmV0dXJuQ29kZUZpcnN0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICghc3VjY2Vzcykge1xyXG4gICAgICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IodG9vbFBhdGggKyAnIGZhaWxlZCB3aXRoIHJldHVybiBjb2RlOiAnICsgY29kZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHdhaXRpbmdFdmVudHMgPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVmZXIucmVqZWN0KGVycm9yKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmVyLnJlc29sdmUocmV0dXJuQ29kZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gZGVmZXIucHJvbWlzZTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEFkZCBhcmd1bWVudFxyXG4gICAgICogQXBwZW5kIGFuIGFyZ3VtZW50IG9yIGFuIGFycmF5IG9mIGFyZ3VtZW50c1xyXG4gICAgICogcmV0dXJucyBUb29sUnVubmVyIGZvciBjaGFpbmluZ1xyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSAgICAgdmFsICAgICAgICBzdHJpbmcgY21kbGluZSBvciBhcnJheSBvZiBzdHJpbmdzXHJcbiAgICAgKiBAcmV0dXJucyAgIFRvb2xSdW5uZXJcclxuICAgICAqL1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuYXJnID0gZnVuY3Rpb24gKHZhbCkge1xyXG4gICAgICAgIGlmICghdmFsKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgQXJyYXkpIHtcclxuICAgICAgICAgICAgdGhpcy5fZGVidWcodGhpcy50b29sUGF0aCArICcgYXJnOiAnICsgSlNPTi5zdHJpbmdpZnkodmFsKSk7XHJcbiAgICAgICAgICAgIHRoaXMuYXJncyA9IHRoaXMuYXJncy5jb25jYXQodmFsKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mICh2YWwpID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICB0aGlzLl9kZWJ1Zyh0aGlzLnRvb2xQYXRoICsgJyBhcmc6ICcgKyB2YWwpO1xyXG4gICAgICAgICAgICB0aGlzLmFyZ3MgPSB0aGlzLmFyZ3MuY29uY2F0KHZhbC50cmltKCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFBhcnNlcyBhbiBhcmd1bWVudCBsaW5lIGludG8gb25lIG9yIG1vcmUgYXJndW1lbnRzXHJcbiAgICAgKiBlLmcuIC5saW5lKCdcImFyZyBvbmVcIiB0d28gLXonKSBpcyBlcXVpdmFsZW50IHRvIC5hcmcoWydhcmcgb25lJywgJ3R3bycsICcteiddKVxyXG4gICAgICogcmV0dXJucyBUb29sUnVubmVyIGZvciBjaGFpbmluZ1xyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSAgICAgdmFsICAgICAgICBzdHJpbmcgYXJndW1lbnQgbGluZVxyXG4gICAgICogQHJldHVybnMgICBUb29sUnVubmVyXHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLmxpbmUgPSBmdW5jdGlvbiAodmFsKSB7XHJcbiAgICAgICAgaWYgKCF2YWwpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuX2RlYnVnKHRoaXMudG9vbFBhdGggKyAnIGFyZzogJyArIHZhbCk7XHJcbiAgICAgICAgdGhpcy5hcmdzID0gdGhpcy5hcmdzLmNvbmNhdCh0aGlzLl9hcmdTdHJpbmdUb0FycmF5KHZhbCkpO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQWRkIGFyZ3VtZW50KHMpIGlmIGEgY29uZGl0aW9uIGlzIG1ldFxyXG4gICAgICogV3JhcHMgYXJnKCkuICBTZWUgYXJnIGZvciBkZXRhaWxzXHJcbiAgICAgKiByZXR1cm5zIFRvb2xSdW5uZXIgZm9yIGNoYWluaW5nXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtICAgICBjb25kaXRpb24gICAgIGJvb2xlYW4gY29uZGl0aW9uXHJcbiAgICAgKiBAcGFyYW0gICAgIHZhbCAgICAgc3RyaW5nIGNtZGxpbmUgb3IgYXJyYXkgb2Ygc3RyaW5nc1xyXG4gICAgICogQHJldHVybnMgICBUb29sUnVubmVyXHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLmFyZ0lmID0gZnVuY3Rpb24gKGNvbmRpdGlvbiwgdmFsKSB7XHJcbiAgICAgICAgaWYgKGNvbmRpdGlvbikge1xyXG4gICAgICAgICAgICB0aGlzLmFyZyh2YWwpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFBpcGUgb3V0cHV0IG9mIGV4ZWMoKSB0byBhbm90aGVyIHRvb2xcclxuICAgICAqIEBwYXJhbSB0b29sXHJcbiAgICAgKiBAcGFyYW0gZmlsZSAgb3B0aW9uYWwgZmlsZW5hbWUgdG8gYWRkaXRpb25hbGx5IHN0cmVhbSB0aGUgb3V0cHV0IHRvLlxyXG4gICAgICogQHJldHVybnMge1Rvb2xSdW5uZXJ9XHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLnBpcGVFeGVjT3V0cHV0VG9Ub29sID0gZnVuY3Rpb24gKHRvb2wsIGZpbGUpIHtcclxuICAgICAgICB0aGlzLnBpcGVPdXRwdXRUb1Rvb2wgPSB0b29sO1xyXG4gICAgICAgIHRoaXMucGlwZU91dHB1dFRvRmlsZSA9IGZpbGU7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBFeGVjIGEgdG9vbC5cclxuICAgICAqIE91dHB1dCB3aWxsIGJlIHN0cmVhbWVkIHRvIHRoZSBsaXZlIGNvbnNvbGUuXHJcbiAgICAgKiBSZXR1cm5zIHByb21pc2Ugd2l0aCByZXR1cm4gY29kZVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSAgICAgdG9vbCAgICAgcGF0aCB0byB0b29sIHRvIGV4ZWNcclxuICAgICAqIEBwYXJhbSAgICAgb3B0aW9ucyAgb3B0aW9uYWwgZXhlYyBvcHRpb25zLiAgU2VlIElFeGVjT3B0aW9uc1xyXG4gICAgICogQHJldHVybnMgICBudW1iZXJcclxuICAgICAqL1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuZXhlYyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICBpZiAodGhpcy5waXBlT3V0cHV0VG9Ub29sKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmV4ZWNXaXRoUGlwaW5nKHRoaXMucGlwZU91dHB1dFRvVG9vbCwgb3B0aW9ucyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBkZWZlciA9IFEuZGVmZXIoKTtcclxuICAgICAgICB0aGlzLl9kZWJ1ZygnZXhlYyB0b29sOiAnICsgdGhpcy50b29sUGF0aCk7XHJcbiAgICAgICAgdGhpcy5fZGVidWcoJ2FyZ3VtZW50czonKTtcclxuICAgICAgICB0aGlzLmFyZ3MuZm9yRWFjaChmdW5jdGlvbiAoYXJnKSB7XHJcbiAgICAgICAgICAgIF90aGlzLl9kZWJ1ZygnICAgJyArIGFyZyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdmFyIG9wdGlvbnNOb25OdWxsID0gdGhpcy5fY2xvbmVFeGVjT3B0aW9ucyhvcHRpb25zKTtcclxuICAgICAgICBpZiAoIW9wdGlvbnNOb25OdWxsLnNpbGVudCkge1xyXG4gICAgICAgICAgICBvcHRpb25zTm9uTnVsbC5vdXRTdHJlYW0ud3JpdGUodGhpcy5fZ2V0Q29tbWFuZFN0cmluZyhvcHRpb25zTm9uTnVsbCkgKyBvcy5FT0wpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgc3RhdGUgPSBuZXcgRXhlY1N0YXRlKG9wdGlvbnNOb25OdWxsLCB0aGlzLnRvb2xQYXRoKTtcclxuICAgICAgICBzdGF0ZS5vbignZGVidWcnLCBmdW5jdGlvbiAobWVzc2FnZSkge1xyXG4gICAgICAgICAgICBfdGhpcy5fZGVidWcobWVzc2FnZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdmFyIGNwID0gY2hpbGQuc3Bhd24odGhpcy5fZ2V0U3Bhd25GaWxlTmFtZShvcHRpb25zKSwgdGhpcy5fZ2V0U3Bhd25BcmdzKG9wdGlvbnNOb25OdWxsKSwgdGhpcy5fZ2V0U3Bhd25PcHRpb25zKG9wdGlvbnMpKTtcclxuICAgICAgICB0aGlzLmNoaWxkUHJvY2VzcyA9IGNwO1xyXG4gICAgICAgIC8vIGl0IGlzIHBvc3NpYmxlIGZvciB0aGUgY2hpbGQgcHJvY2VzcyB0byBlbmQgaXRzIGxhc3QgbGluZSB3aXRob3V0IGEgbmV3IGxpbmUuXHJcbiAgICAgICAgLy8gYmVjYXVzZSBzdGRvdXQgaXMgYnVmZmVyZWQsIHRoaXMgY2F1c2VzIHRoZSBsYXN0IGxpbmUgdG8gbm90IGdldCBzZW50IHRvIHRoZSBwYXJlbnRcclxuICAgICAgICAvLyBzdHJlYW0uIEFkZGluZyB0aGlzIGV2ZW50IGZvcmNlcyBhIGZsdXNoIGJlZm9yZSB0aGUgY2hpbGQgc3RyZWFtcyBhcmUgY2xvc2VkLlxyXG4gICAgICAgIGNwLnN0ZG91dC5vbignZmluaXNoJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoIW9wdGlvbnNOb25OdWxsLnNpbGVudCkge1xyXG4gICAgICAgICAgICAgICAgb3B0aW9uc05vbk51bGwub3V0U3RyZWFtLndyaXRlKG9zLkVPTCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICB2YXIgc3RkYnVmZmVyID0gJyc7XHJcbiAgICAgICAgY3Auc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGRhdGEpIHtcclxuICAgICAgICAgICAgX3RoaXMuZW1pdCgnc3Rkb3V0JywgZGF0YSk7XHJcbiAgICAgICAgICAgIGlmICghb3B0aW9uc05vbk51bGwuc2lsZW50KSB7XHJcbiAgICAgICAgICAgICAgICBvcHRpb25zTm9uTnVsbC5vdXRTdHJlYW0ud3JpdGUoZGF0YSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgX3RoaXMuX3Byb2Nlc3NMaW5lQnVmZmVyKGRhdGEsIHN0ZGJ1ZmZlciwgZnVuY3Rpb24gKGxpbmUpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmVtaXQoJ3N0ZGxpbmUnLCBsaW5lKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdmFyIGVycmJ1ZmZlciA9ICcnO1xyXG4gICAgICAgIGNwLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICAgICAgICAgIHN0YXRlLnByb2Nlc3NTdGRlcnIgPSB0cnVlO1xyXG4gICAgICAgICAgICBfdGhpcy5lbWl0KCdzdGRlcnInLCBkYXRhKTtcclxuICAgICAgICAgICAgaWYgKCFvcHRpb25zTm9uTnVsbC5zaWxlbnQpIHtcclxuICAgICAgICAgICAgICAgIHZhciBzID0gb3B0aW9uc05vbk51bGwuZmFpbE9uU3RkRXJyID8gb3B0aW9uc05vbk51bGwuZXJyU3RyZWFtIDogb3B0aW9uc05vbk51bGwub3V0U3RyZWFtO1xyXG4gICAgICAgICAgICAgICAgcy53cml0ZShkYXRhKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBfdGhpcy5fcHJvY2Vzc0xpbmVCdWZmZXIoZGF0YSwgZXJyYnVmZmVyLCBmdW5jdGlvbiAobGluZSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZW1pdCgnZXJybGluZScsIGxpbmUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBjcC5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICAgIHN0YXRlLnByb2Nlc3NFcnJvciA9IGVyci5tZXNzYWdlO1xyXG4gICAgICAgICAgICBzdGF0ZS5wcm9jZXNzRXhpdGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgc3RhdGUucHJvY2Vzc0Nsb3NlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHN0YXRlLkNoZWNrQ29tcGxldGUoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBjcC5vbignZXhpdCcsIGZ1bmN0aW9uIChjb2RlLCBzaWduYWwpIHtcclxuICAgICAgICAgICAgc3RhdGUucHJvY2Vzc0V4aXRDb2RlID0gY29kZTtcclxuICAgICAgICAgICAgc3RhdGUucHJvY2Vzc0V4aXRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIF90aGlzLl9kZWJ1ZyhcIkV4aXQgY29kZSBcIiArIGNvZGUgKyBcIiByZWNlaXZlZCBmcm9tIHRvb2wgJ1wiICsgX3RoaXMudG9vbFBhdGggKyBcIidcIik7XHJcbiAgICAgICAgICAgIHN0YXRlLkNoZWNrQ29tcGxldGUoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBjcC5vbignY2xvc2UnLCBmdW5jdGlvbiAoY29kZSwgc2lnbmFsKSB7XHJcbiAgICAgICAgICAgIHN0YXRlLnByb2Nlc3NFeGl0Q29kZSA9IGNvZGU7XHJcbiAgICAgICAgICAgIHN0YXRlLnByb2Nlc3NFeGl0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICBzdGF0ZS5wcm9jZXNzQ2xvc2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgX3RoaXMuX2RlYnVnKFwiU1RESU8gc3RyZWFtcyBoYXZlIGNsb3NlZCBmb3IgdG9vbCAnXCIgKyBfdGhpcy50b29sUGF0aCArIFwiJ1wiKTtcclxuICAgICAgICAgICAgc3RhdGUuQ2hlY2tDb21wbGV0ZSgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHN0YXRlLm9uKCdkb25lJywgZnVuY3Rpb24gKGVycm9yLCBleGl0Q29kZSkge1xyXG4gICAgICAgICAgICBpZiAoc3RkYnVmZmVyLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmVtaXQoJ3N0ZGxpbmUnLCBzdGRidWZmZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlcnJidWZmZXIubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZW1pdCgnZXJybGluZScsIGVycmJ1ZmZlcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY3AucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XHJcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xyXG4gICAgICAgICAgICAgICAgZGVmZXIucmVqZWN0KGVycm9yKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGRlZmVyLnJlc29sdmUoZXhpdENvZGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIGRlZmVyLnByb21pc2U7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBFeGVjIGEgdG9vbCBzeW5jaHJvbm91c2x5LlxyXG4gICAgICogT3V0cHV0IHdpbGwgYmUgKm5vdCogYmUgc3RyZWFtZWQgdG8gdGhlIGxpdmUgY29uc29sZS4gIEl0IHdpbGwgYmUgcmV0dXJuZWQgYWZ0ZXIgZXhlY3V0aW9uIGlzIGNvbXBsZXRlLlxyXG4gICAgICogQXBwcm9wcmlhdGUgZm9yIHNob3J0IHJ1bm5pbmcgdG9vbHNcclxuICAgICAqIFJldHVybnMgSUV4ZWNTeW5jUmVzdWx0IHdpdGggb3V0cHV0IGFuZCByZXR1cm4gY29kZVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSAgICAgdG9vbCAgICAgcGF0aCB0byB0b29sIHRvIGV4ZWNcclxuICAgICAqIEBwYXJhbSAgICAgb3B0aW9ucyAgb3B0aW9uYWwgZXhlYyBvcHRpb25zLiAgU2VlIElFeGVjU3luY09wdGlvbnNcclxuICAgICAqIEByZXR1cm5zICAgSUV4ZWNTeW5jUmVzdWx0XHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLmV4ZWNTeW5jID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHRoaXMuX2RlYnVnKCdleGVjIHRvb2w6ICcgKyB0aGlzLnRvb2xQYXRoKTtcclxuICAgICAgICB0aGlzLl9kZWJ1ZygnYXJndW1lbnRzOicpO1xyXG4gICAgICAgIHRoaXMuYXJncy5mb3JFYWNoKGZ1bmN0aW9uIChhcmcpIHtcclxuICAgICAgICAgICAgX3RoaXMuX2RlYnVnKCcgICAnICsgYXJnKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB2YXIgc3VjY2VzcyA9IHRydWU7XHJcbiAgICAgICAgb3B0aW9ucyA9IHRoaXMuX2Nsb25lRXhlY09wdGlvbnMob3B0aW9ucyk7XHJcbiAgICAgICAgaWYgKCFvcHRpb25zLnNpbGVudCkge1xyXG4gICAgICAgICAgICBvcHRpb25zLm91dFN0cmVhbS53cml0ZSh0aGlzLl9nZXRDb21tYW5kU3RyaW5nKG9wdGlvbnMpICsgb3MuRU9MKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHIgPSBjaGlsZC5zcGF3blN5bmModGhpcy5fZ2V0U3Bhd25GaWxlTmFtZShvcHRpb25zKSwgdGhpcy5fZ2V0U3Bhd25BcmdzKG9wdGlvbnMpLCB0aGlzLl9nZXRTcGF3blN5bmNPcHRpb25zKG9wdGlvbnMpKTtcclxuICAgICAgICBpZiAoIW9wdGlvbnMuc2lsZW50ICYmIHIuc3Rkb3V0ICYmIHIuc3Rkb3V0Lmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgb3B0aW9ucy5vdXRTdHJlYW0ud3JpdGUoci5zdGRvdXQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIW9wdGlvbnMuc2lsZW50ICYmIHIuc3RkZXJyICYmIHIuc3RkZXJyLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgb3B0aW9ucy5lcnJTdHJlYW0ud3JpdGUoci5zdGRlcnIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgcmVzID0geyBjb2RlOiByLnN0YXR1cywgZXJyb3I6IHIuZXJyb3IgfTtcclxuICAgICAgICByZXMuc3Rkb3V0ID0gKHIuc3Rkb3V0KSA/IHIuc3Rkb3V0LnRvU3RyaW5nKCkgOiAnJztcclxuICAgICAgICByZXMuc3RkZXJyID0gKHIuc3RkZXJyKSA/IHIuc3RkZXJyLnRvU3RyaW5nKCkgOiAnJztcclxuICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogVXNlZCB0byBjbG9zZSBjaGlsZCBwcm9jZXNzIGJ5IHNlbmRpbmcgU0lHTklOVCBzaWduYWwuXHJcbiAgICAgKiBJdCBhbGxvd3MgZXhlY3V0ZWQgc2NyaXB0IHRvIGhhdmUgc29tZSBhZGRpdGlvbmFsIGxvZ2ljIG9uIFNJR0lOVCwgYmVmb3JlIGV4aXRpbmcuXHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLmtpbGxDaGlsZFByb2Nlc3MgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuY2hpbGRQcm9jZXNzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2hpbGRQcm9jZXNzLmtpbGwoKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFRvb2xSdW5uZXI7XHJcbn0oZXZlbnRzLkV2ZW50RW1pdHRlcikpO1xyXG5leHBvcnRzLlRvb2xSdW5uZXIgPSBUb29sUnVubmVyO1xyXG52YXIgRXhlY1N0YXRlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKEV4ZWNTdGF0ZSwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIEV4ZWNTdGF0ZShvcHRpb25zLCB0b29sUGF0aCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuZGVsYXkgPSAxMDAwMDsgLy8gMTAgc2Vjb25kc1xyXG4gICAgICAgIF90aGlzLnRpbWVvdXQgPSBudWxsO1xyXG4gICAgICAgIGlmICghdG9vbFBhdGgpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0b29sUGF0aCBtdXN0IG5vdCBiZSBlbXB0eScpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBfdGhpcy5vcHRpb25zID0gb3B0aW9ucztcclxuICAgICAgICBfdGhpcy50b29sUGF0aCA9IHRvb2xQYXRoO1xyXG4gICAgICAgIHZhciBkZWxheSA9IHByb2Nlc3MuZW52WydUQVNLTElCX1RFU1RfVE9PTFJVTk5FUl9FWElUREVMQVknXTtcclxuICAgICAgICBpZiAoZGVsYXkpIHtcclxuICAgICAgICAgICAgX3RoaXMuZGVsYXkgPSBwYXJzZUludChkZWxheSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIEV4ZWNTdGF0ZS5wcm90b3R5cGUuQ2hlY2tDb21wbGV0ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAodGhpcy5kb25lKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMucHJvY2Vzc0Nsb3NlZCkge1xyXG4gICAgICAgICAgICB0aGlzLl9zZXRSZXN1bHQoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5wcm9jZXNzRXhpdGVkKSB7XHJcbiAgICAgICAgICAgIHRoaXMudGltZW91dCA9IHNldFRpbWVvdXQoRXhlY1N0YXRlLkhhbmRsZVRpbWVvdXQsIHRoaXMuZGVsYXksIHRoaXMpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBFeGVjU3RhdGUucHJvdG90eXBlLl9kZWJ1ZyA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XHJcbiAgICAgICAgdGhpcy5lbWl0KCdkZWJ1ZycsIG1lc3NhZ2UpO1xyXG4gICAgfTtcclxuICAgIEV4ZWNTdGF0ZS5wcm90b3R5cGUuX3NldFJlc3VsdCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBkZXRlcm1pbmUgd2hldGhlciB0aGVyZSBpcyBhbiBlcnJvclxyXG4gICAgICAgIHZhciBlcnJvcjtcclxuICAgICAgICBpZiAodGhpcy5wcm9jZXNzRXhpdGVkKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnByb2Nlc3NFcnJvcikge1xyXG4gICAgICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoaW0uX2xvYygnTElCX1Byb2Nlc3NFcnJvcicsIHRoaXMudG9vbFBhdGgsIHRoaXMucHJvY2Vzc0Vycm9yKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5wcm9jZXNzRXhpdENvZGUgIT0gMCAmJiAhdGhpcy5vcHRpb25zLmlnbm9yZVJldHVybkNvZGUpIHtcclxuICAgICAgICAgICAgICAgIGVycm9yID0gbmV3IEVycm9yKGltLl9sb2MoJ0xJQl9Qcm9jZXNzRXhpdENvZGUnLCB0aGlzLnRvb2xQYXRoLCB0aGlzLnByb2Nlc3NFeGl0Q29kZSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMucHJvY2Vzc1N0ZGVyciAmJiB0aGlzLm9wdGlvbnMuZmFpbE9uU3RkRXJyKSB7XHJcbiAgICAgICAgICAgICAgICBlcnJvciA9IG5ldyBFcnJvcihpbS5fbG9jKCdMSUJfUHJvY2Vzc1N0ZGVycicsIHRoaXMudG9vbFBhdGgpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBjbGVhciB0aGUgdGltZW91dFxyXG4gICAgICAgIGlmICh0aGlzLnRpbWVvdXQpIHtcclxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZW91dCk7XHJcbiAgICAgICAgICAgIHRoaXMudGltZW91dCA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZG9uZSA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5lbWl0KCdkb25lJywgZXJyb3IsIHRoaXMucHJvY2Vzc0V4aXRDb2RlKTtcclxuICAgIH07XHJcbiAgICBFeGVjU3RhdGUuSGFuZGxlVGltZW91dCA9IGZ1bmN0aW9uIChzdGF0ZSkge1xyXG4gICAgICAgIGlmIChzdGF0ZS5kb25lKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFzdGF0ZS5wcm9jZXNzQ2xvc2VkICYmIHN0YXRlLnByb2Nlc3NFeGl0ZWQpIHtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coaW0uX2xvYygnTElCX1N0ZGlvTm90Q2xvc2VkJywgc3RhdGUuZGVsYXkgLyAxMDAwLCBzdGF0ZS50b29sUGF0aCkpO1xyXG4gICAgICAgICAgICBzdGF0ZS5fZGVidWcoaW0uX2xvYygnTElCX1N0ZGlvTm90Q2xvc2VkJywgc3RhdGUuZGVsYXkgLyAxMDAwLCBzdGF0ZS50b29sUGF0aCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBzdGF0ZS5fc2V0UmVzdWx0KCk7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIEV4ZWNTdGF0ZTtcclxufShldmVudHMuRXZlbnRFbWl0dGVyKSk7XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBmcyA9IHJlcXVpcmUoXCJmc1wiKTtcclxudmFyIHBhdGggPSByZXF1aXJlKFwicGF0aFwiKTtcclxudmFyIGNyeXB0byA9IHJlcXVpcmUoXCJjcnlwdG9cIik7XHJcbnZhciB1dWlkVjQgPSByZXF1aXJlKCd1dWlkL3Y0Jyk7XHJcbnZhciBhbGdvcml0aG0gPSBcImFlcy0yNTYtY3RyXCI7XHJcbnZhciBlbmNyeXB0RW5jb2RpbmcgPSAnaGV4JztcclxudmFyIHVuZW5jcnlwdGVkRW5jb2RpbmcgPSAndXRmOCc7XHJcbi8vXHJcbi8vIFN0b3JlIHNlbnNpdGl2ZSBkYXRhIGluIHByb2MuXHJcbi8vIE1haW4gZ29hbDogUHJvdGVjdHMgdGFza3Mgd2hpY2ggd291bGQgZHVtcCBlbnZ2YXJzIGZyb20gbGVha2luZyBzZWNyZXRzIGluYWR2ZXJ0ZW50bHlcclxuLy8gICAgICAgICAgICB0aGUgdGFzayBsaWIgY2xlYXJzIGFmdGVyIHN0b3JpbmcuXHJcbi8vIEFsc28gcHJvdGVjdHMgYWdhaW5zdCBhIGR1bXAgb2YgYSBwcm9jZXNzIGdldHRpbmcgdGhlIHNlY3JldHNcclxuLy8gVGhlIHNlY3JldCBpcyBnZW5lcmF0ZWQgYW5kIHN0b3JlZCBleHRlcm5hbGx5IGZvciB0aGUgbGlmZXRpbWUgb2YgdGhlIHRhc2suXHJcbi8vXHJcbnZhciBWYXVsdCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIFZhdWx0KGtleVBhdGgpIHtcclxuICAgICAgICB0aGlzLl9rZXlGaWxlID0gcGF0aC5qb2luKGtleVBhdGgsICcudGFza2tleScpO1xyXG4gICAgICAgIHRoaXMuX3N0b3JlID0ge307XHJcbiAgICAgICAgdGhpcy5nZW5LZXkoKTtcclxuICAgIH1cclxuICAgIFZhdWx0LnByb3RvdHlwZS5pbml0aWFsaXplID0gZnVuY3Rpb24gKCkge1xyXG4gICAgfTtcclxuICAgIFZhdWx0LnByb3RvdHlwZS5zdG9yZVNlY3JldCA9IGZ1bmN0aW9uIChuYW1lLCBkYXRhKSB7XHJcbiAgICAgICAgaWYgKCFuYW1lIHx8IG5hbWUubGVuZ3RoID09IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBuYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICAgIGlmICghZGF0YSB8fCBkYXRhLmxlbmd0aCA9PSAwKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdG9yZS5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX3N0b3JlW25hbWVdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGtleSA9IHRoaXMuZ2V0S2V5KCk7XHJcbiAgICAgICAgdmFyIGl2ID0gY3J5cHRvLnJhbmRvbUJ5dGVzKDE2KTtcclxuICAgICAgICB2YXIgY2lwaGVyID0gY3J5cHRvLmNyZWF0ZUNpcGhlcml2KGFsZ29yaXRobSwga2V5LCBpdik7XHJcbiAgICAgICAgdmFyIGNyeXB0ZWQgPSBjaXBoZXIudXBkYXRlKGRhdGEsIHVuZW5jcnlwdGVkRW5jb2RpbmcsIGVuY3J5cHRFbmNvZGluZyk7XHJcbiAgICAgICAgdmFyIGNyeXB0ZWRGaW5hbCA9IGNpcGhlci5maW5hbChlbmNyeXB0RW5jb2RpbmcpO1xyXG4gICAgICAgIHRoaXMuX3N0b3JlW25hbWVdID0gaXYudG9TdHJpbmcoZW5jcnlwdEVuY29kaW5nKSArIGNyeXB0ZWQgKyBjcnlwdGVkRmluYWw7XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9O1xyXG4gICAgVmF1bHQucHJvdG90eXBlLnJldHJpZXZlU2VjcmV0ID0gZnVuY3Rpb24gKG5hbWUpIHtcclxuICAgICAgICB2YXIgc2VjcmV0O1xyXG4gICAgICAgIG5hbWUgPSAobmFtZSB8fCAnJykudG9Mb3dlckNhc2UoKTtcclxuICAgICAgICBpZiAodGhpcy5fc3RvcmUuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcclxuICAgICAgICAgICAgdmFyIGtleSA9IHRoaXMuZ2V0S2V5KCk7XHJcbiAgICAgICAgICAgIHZhciBkYXRhID0gdGhpcy5fc3RvcmVbbmFtZV07XHJcbiAgICAgICAgICAgIHZhciBpdkRhdGFCdWZmZXIgPSBCdWZmZXIuZnJvbShkYXRhLCBlbmNyeXB0RW5jb2RpbmcpO1xyXG4gICAgICAgICAgICB2YXIgaXYgPSBpdkRhdGFCdWZmZXIuc2xpY2UoMCwgMTYpO1xyXG4gICAgICAgICAgICB2YXIgZW5jcnlwdGVkVGV4dCA9IGl2RGF0YUJ1ZmZlci5zbGljZSgxNik7XHJcbiAgICAgICAgICAgIHZhciBkZWNpcGhlciA9IGNyeXB0by5jcmVhdGVEZWNpcGhlcml2KGFsZ29yaXRobSwga2V5LCBpdik7XHJcbiAgICAgICAgICAgIHZhciBkZWMgPSBkZWNpcGhlci51cGRhdGUoZW5jcnlwdGVkVGV4dCwgZW5jcnlwdEVuY29kaW5nLCB1bmVuY3J5cHRlZEVuY29kaW5nKTtcclxuICAgICAgICAgICAgdmFyIGRlY0ZpbmFsID0gZGVjaXBoZXIuZmluYWwodW5lbmNyeXB0ZWRFbmNvZGluZyk7XHJcbiAgICAgICAgICAgIHNlY3JldCA9IGRlYyArIGRlY0ZpbmFsO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gc2VjcmV0O1xyXG4gICAgfTtcclxuICAgIFZhdWx0LnByb3RvdHlwZS5nZXRLZXkgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGtleSA9IGZzLnJlYWRGaWxlU3luYyh0aGlzLl9rZXlGaWxlKS50b1N0cmluZygndXRmOCcpO1xyXG4gICAgICAgIC8vIEtleSBuZWVkcyB0byBiZSBoYXNoZWQgdG8gY29ycmVjdCBsZW5ndGggdG8gbWF0Y2ggYWxnb3JpdGhtIChhZXMtMjU2LWN0cilcclxuICAgICAgICByZXR1cm4gY3J5cHRvLmNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZShrZXkpLmRpZ2VzdCgpO1xyXG4gICAgfTtcclxuICAgIFZhdWx0LnByb3RvdHlwZS5nZW5LZXkgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyh0aGlzLl9rZXlGaWxlLCB1dWlkVjQoKSwgeyBlbmNvZGluZzogJ3V0ZjgnIH0pO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBWYXVsdDtcclxufSgpKTtcclxuZXhwb3J0cy5WYXVsdCA9IFZhdWx0O1xyXG4iLCJmdW5jdGlvbiB3ZWJwYWNrRW1wdHlDb250ZXh0KHJlcSkge1xuXHR2YXIgZSA9IG5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIgKyByZXEgKyBcIidcIik7XG5cdGUuY29kZSA9ICdNT0RVTEVfTk9UX0ZPVU5EJztcblx0dGhyb3cgZTtcbn1cbndlYnBhY2tFbXB0eUNvbnRleHQua2V5cyA9ICgpID0+IFtdO1xud2VicGFja0VtcHR5Q29udGV4dC5yZXNvbHZlID0gd2VicGFja0VtcHR5Q29udGV4dDtcbndlYnBhY2tFbXB0eUNvbnRleHQuaWQgPSBcIi4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10YXNrLWxpYiBzeW5jIHJlY3Vyc2l2ZVwiO1xubW9kdWxlLmV4cG9ydHMgPSB3ZWJwYWNrRW1wdHlDb250ZXh0OyIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXVxuICBdKS5qb2luKCcnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBieXRlc1RvVXVpZDtcbiIsIi8vIFVuaXF1ZSBJRCBjcmVhdGlvbiByZXF1aXJlcyBhIGhpZ2ggcXVhbGl0eSByYW5kb20gIyBnZW5lcmF0b3IuICBJbiBub2RlLmpzXG4vLyB0aGlzIGlzIHByZXR0eSBzdHJhaWdodC1mb3J3YXJkIC0gd2UgdXNlIHRoZSBjcnlwdG8gQVBJLlxuXG52YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gbm9kZVJORygpIHtcbiAgcmV0dXJuIGNyeXB0by5yYW5kb21CeXRlcygxNik7XG59O1xuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuZnVuY3Rpb24gdjQob3B0aW9ucywgYnVmLCBvZmZzZXQpIHtcbiAgdmFyIGkgPSBidWYgJiYgb2Zmc2V0IHx8IDA7XG5cbiAgaWYgKHR5cGVvZihvcHRpb25zKSA9PSAnc3RyaW5nJykge1xuICAgIGJ1ZiA9IG9wdGlvbnMgPT09ICdiaW5hcnknID8gbmV3IEFycmF5KDE2KSA6IG51bGw7XG4gICAgb3B0aW9ucyA9IG51bGw7XG4gIH1cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgdmFyIHJuZHMgPSBvcHRpb25zLnJhbmRvbSB8fCAob3B0aW9ucy5ybmcgfHwgcm5nKSgpO1xuXG4gIC8vIFBlciA0LjQsIHNldCBiaXRzIGZvciB2ZXJzaW9uIGFuZCBgY2xvY2tfc2VxX2hpX2FuZF9yZXNlcnZlZGBcbiAgcm5kc1s2XSA9IChybmRzWzZdICYgMHgwZikgfCAweDQwO1xuICBybmRzWzhdID0gKHJuZHNbOF0gJiAweDNmKSB8IDB4ODA7XG5cbiAgLy8gQ29weSBieXRlcyB0byBidWZmZXIsIGlmIHByb3ZpZGVkXG4gIGlmIChidWYpIHtcbiAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgMTY7ICsraWkpIHtcbiAgICAgIGJ1ZltpICsgaWldID0gcm5kc1tpaV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ1ZiB8fCBieXRlc1RvVXVpZChybmRzKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB2NDtcbiIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19hd2FpdGVyID0gKHRoaXMgJiYgdGhpcy5fX2F3YWl0ZXIpIHx8IGZ1bmN0aW9uICh0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUocmVzdWx0LnZhbHVlKTsgfSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59O1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbmNvbnN0IGh0dHBtID0gcmVxdWlyZShcInR5cGVkLXJlc3QtY2xpZW50L0h0dHBDbGllbnRcIik7XHJcbmNvbnN0IHBhdGggPSByZXF1aXJlKFwicGF0aFwiKTtcclxuY29uc3Qgb3MgPSByZXF1aXJlKFwib3NcIik7XHJcbmNvbnN0IHByb2Nlc3MgPSByZXF1aXJlKFwicHJvY2Vzc1wiKTtcclxuY29uc3QgZnMgPSByZXF1aXJlKFwiZnNcIik7XHJcbmNvbnN0IHNlbXZlciA9IHJlcXVpcmUoXCJzZW12ZXJcIik7XHJcbmNvbnN0IHRsID0gcmVxdWlyZShcImF6dXJlLXBpcGVsaW5lcy10YXNrLWxpYi90YXNrXCIpO1xyXG5jb25zdCBjbXAgPSByZXF1aXJlKCdzZW12ZXItY29tcGFyZScpO1xyXG5jb25zdCB1dWlkVjQgPSByZXF1aXJlKCd1dWlkL3Y0Jyk7XHJcbmxldCBwa2cgPSByZXF1aXJlKHBhdGguam9pbihfX2Rpcm5hbWUsICdwYWNrYWdlLmpzb24nKSk7XHJcbmxldCB1c2VyQWdlbnQgPSAndnN0cy10YXNrLWluc3RhbGxlci8nICsgcGtnLnZlcnNpb247XHJcbmxldCByZXF1ZXN0T3B0aW9ucyA9IHtcclxuICAgIC8vIGlnbm9yZVNzbEVycm9yOiB0cnVlLFxyXG4gICAgcHJveHk6IHRsLmdldEh0dHBQcm94eUNvbmZpZ3VyYXRpb24oKSxcclxuICAgIGNlcnQ6IHRsLmdldEh0dHBDZXJ0Q29uZmlndXJhdGlvbigpLFxyXG4gICAgYWxsb3dSZWRpcmVjdHM6IHRydWUsXHJcbiAgICBhbGxvd1JldHJpZXM6IHRydWUsXHJcbiAgICBtYXhSZXRyaWVzOiAyXHJcbn07XHJcbnRsLnNldFJlc291cmNlUGF0aChwYXRoLmpvaW4oX19kaXJuYW1lLCAnbGliLmpzb24nKSk7XHJcbmZ1bmN0aW9uIGRlYnVnKG1lc3NhZ2UpIHtcclxuICAgIHRsLmRlYnVnKG1lc3NhZ2UpO1xyXG59XHJcbmV4cG9ydHMuZGVidWcgPSBkZWJ1ZztcclxuZnVuY3Rpb24gcHJlcGVuZFBhdGgodG9vbFBhdGgpIHtcclxuICAgIHRsLmFzc2VydEFnZW50KCcyLjExNS4wJyk7XHJcbiAgICBpZiAoIXRvb2xQYXRoKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXJhbWV0ZXIgdG9vbFBhdGggbXVzdCBub3QgYmUgbnVsbCBvciBlbXB0eScpO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoIXRsLmV4aXN0KHRvb2xQYXRoKSB8fCAhdGwuc3RhdHModG9vbFBhdGgpLmlzRGlyZWN0b3J5KCkpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpcmVjdG9yeSBkb2VzIG5vdCBleGlzdDogJyArIHRvb2xQYXRoKTtcclxuICAgIH1cclxuICAgIC8vIHRvZG86IGFkZCBhIHRlc3QgZm9yIHBhdGhcclxuICAgIGNvbnNvbGUubG9nKHRsLmxvYygnVE9PTF9MSUJfUHJlcGVuZFBhdGgnLCB0b29sUGF0aCkpO1xyXG4gICAgbGV0IG5ld1BhdGggPSB0b29sUGF0aCArIHBhdGguZGVsaW1pdGVyICsgcHJvY2Vzcy5lbnZbJ1BBVEgnXTtcclxuICAgIHRsLmRlYnVnKCduZXcgUGF0aDogJyArIG5ld1BhdGgpO1xyXG4gICAgcHJvY2Vzcy5lbnZbJ1BBVEgnXSA9IG5ld1BhdGg7XHJcbiAgICAvLyBpbnN0cnVjdCB0aGUgYWdlbnQgdG8gc2V0IHRoaXMgcGF0aCBvbiBmdXR1cmUgdGFza3NcclxuICAgIGNvbnNvbGUubG9nKCcjI3Zzb1t0YXNrLnByZXBlbmRwYXRoXScgKyB0b29sUGF0aCk7XHJcbn1cclxuZXhwb3J0cy5wcmVwZW5kUGF0aCA9IHByZXBlbmRQYXRoO1xyXG5mdW5jdGlvbiBkZWxheShtcykge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCBtcykpO1xyXG59XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gVmVyc2lvbiBGdW5jdGlvbnNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vKipcclxuICogQ2hlY2tzIGlmIGEgdmVyc2lvbiBzcGVjIGlzIGFuIGV4cGxpY2l0IHZlcnNpb24gKGUuZy4gMS4wLjEgb3IgdjEuMC4xKVxyXG4gKiBBcyBvcHBvc2VkIHRvIGEgdmVyc2lvbiBzcGVjIGxpa2UgMS54XHJcbiAqXHJcbiAqIEBwYXJhbSB2ZXJzaW9uU3BlY1xyXG4gKi9cclxuZnVuY3Rpb24gaXNFeHBsaWNpdFZlcnNpb24odmVyc2lvblNwZWMpIHtcclxuICAgIGxldCBjID0gc2VtdmVyLmNsZWFuKHZlcnNpb25TcGVjKTtcclxuICAgIHRsLmRlYnVnKCdpc0V4cGxpY2l0OiAnICsgYyk7XHJcbiAgICBsZXQgdmFsaWQgPSBzZW12ZXIudmFsaWQoYykgIT0gbnVsbDtcclxuICAgIHRsLmRlYnVnKCdleHBsaWNpdD8gJyArIHZhbGlkKTtcclxuICAgIHJldHVybiB2YWxpZDtcclxufVxyXG5leHBvcnRzLmlzRXhwbGljaXRWZXJzaW9uID0gaXNFeHBsaWNpdFZlcnNpb247XHJcbi8qKlxyXG4gKiBSZXR1cm5zIGNsZWFuZWQgKHJlbW92ZWQgbGVhZGluZy90cmFpbGluZyB3aGl0ZXNwYWNlLCByZW1vdmUgJz12JyBwcmVmaXgpXHJcbiAqIGFuZCBwYXJzZWQgdmVyc2lvbiwgb3IgbnVsbCBpZiB2ZXJzaW9uIGlzIGludmFsaWQuXHJcbiAqL1xyXG5mdW5jdGlvbiBjbGVhblZlcnNpb24odmVyc2lvbikge1xyXG4gICAgdGwuZGVidWcoJ2NsZWFuaW5nOiAnICsgdmVyc2lvbik7XHJcbiAgICByZXR1cm4gc2VtdmVyLmNsZWFuKHZlcnNpb24pO1xyXG59XHJcbmV4cG9ydHMuY2xlYW5WZXJzaW9uID0gY2xlYW5WZXJzaW9uO1xyXG4vKipcclxuICogZXZhbHVhdGVzIGEgbGlzdCBvZiB2ZXJzaW9ucyBhbmQgcmV0dXJucyB0aGUgbGF0ZXN0IHZlcnNpb24gbWF0Y2hpbmcgdGhlIHZlcnNpb24gc3BlY1xyXG4gKlxyXG4gKiBAcGFyYW0gdmVyc2lvbnMgICAgICBhbiBhcnJheSBvZiB2ZXJzaW9ucyB0byBldmFsdWF0ZVxyXG4gKiBAcGFyYW0gdmVyc2lvblNwZWMgICBhIHZlcnNpb24gc3BlYyAoZS5nLiAxLngpXHJcbiAqL1xyXG5mdW5jdGlvbiBldmFsdWF0ZVZlcnNpb25zKHZlcnNpb25zLCB2ZXJzaW9uU3BlYykge1xyXG4gICAgbGV0IHZlcnNpb247XHJcbiAgICB0bC5kZWJ1ZygnZXZhbHVhdGluZyAnICsgdmVyc2lvbnMubGVuZ3RoICsgJyB2ZXJzaW9ucycpO1xyXG4gICAgdmVyc2lvbnMgPSB2ZXJzaW9ucy5zb3J0KGNtcCk7XHJcbiAgICBmb3IgKGxldCBpID0gdmVyc2lvbnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICBsZXQgcG90ZW50aWFsID0gdmVyc2lvbnNbaV07XHJcbiAgICAgICAgbGV0IHNhdGlzZmllZCA9IHNlbXZlci5zYXRpc2ZpZXMocG90ZW50aWFsLCB2ZXJzaW9uU3BlYyk7XHJcbiAgICAgICAgaWYgKHNhdGlzZmllZCkge1xyXG4gICAgICAgICAgICB2ZXJzaW9uID0gcG90ZW50aWFsO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAodmVyc2lvbikge1xyXG4gICAgICAgIHRsLmRlYnVnKCdtYXRjaGVkOiAnICsgdmVyc2lvbik7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICB0bC5kZWJ1ZygnbWF0Y2ggbm90IGZvdW5kJyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdmVyc2lvbjtcclxufVxyXG5leHBvcnRzLmV2YWx1YXRlVmVyc2lvbnMgPSBldmFsdWF0ZVZlcnNpb25zO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIExvY2FsIFRvb2wgQ2FjaGUgRnVuY3Rpb25zXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyoqXHJcbiAqIGZpbmRzIHRoZSBwYXRoIHRvIGEgdG9vbCBpbiB0aGUgbG9jYWwgaW5zdGFsbGVkIHRvb2wgY2FjaGVcclxuICpcclxuICogQHBhcmFtIHRvb2xOYW1lICAgICAgbmFtZSBvZiB0aGUgdG9vbFxyXG4gKiBAcGFyYW0gdmVyc2lvblNwZWMgICB2ZXJzaW9uIG9mIHRoZSB0b29sXHJcbiAqIEBwYXJhbSBhcmNoICAgICAgICAgIG9wdGlvbmFsIGFyY2guICBkZWZhdWx0cyB0byBhcmNoIG9mIGNvbXB1dGVyXHJcbiAqL1xyXG5mdW5jdGlvbiBmaW5kTG9jYWxUb29sKHRvb2xOYW1lLCB2ZXJzaW9uU3BlYywgYXJjaCkge1xyXG4gICAgaWYgKCF0b29sTmFtZSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcigndG9vbE5hbWUgcGFyYW1ldGVyIGlzIHJlcXVpcmVkJyk7XHJcbiAgICB9XHJcbiAgICBpZiAoIXZlcnNpb25TcGVjKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd2ZXJzaW9uU3BlYyBwYXJhbWV0ZXIgaXMgcmVxdWlyZWQnKTtcclxuICAgIH1cclxuICAgIGFyY2ggPSBhcmNoIHx8IG9zLmFyY2goKTtcclxuICAgIC8vIGF0dGVtcHQgdG8gcmVzb2x2ZSBhbiBleHBsaWNpdCB2ZXJzaW9uXHJcbiAgICBpZiAoIWlzRXhwbGljaXRWZXJzaW9uKHZlcnNpb25TcGVjKSkge1xyXG4gICAgICAgIGxldCBsb2NhbFZlcnNpb25zID0gZmluZExvY2FsVG9vbFZlcnNpb25zKHRvb2xOYW1lLCBhcmNoKTtcclxuICAgICAgICBsZXQgbWF0Y2ggPSBldmFsdWF0ZVZlcnNpb25zKGxvY2FsVmVyc2lvbnMsIHZlcnNpb25TcGVjKTtcclxuICAgICAgICB2ZXJzaW9uU3BlYyA9IG1hdGNoO1xyXG4gICAgfVxyXG4gICAgLy8gY2hlY2sgZm9yIHRoZSBleHBsaWNpdCB2ZXJzaW9uIGluIHRoZSBjYWNoZVxyXG4gICAgbGV0IHRvb2xQYXRoO1xyXG4gICAgaWYgKHZlcnNpb25TcGVjKSB7XHJcbiAgICAgICAgdmVyc2lvblNwZWMgPSBzZW12ZXIuY2xlYW4odmVyc2lvblNwZWMpO1xyXG4gICAgICAgIGxldCBjYWNoZVJvb3QgPSBfZ2V0Q2FjaGVSb290KCk7XHJcbiAgICAgICAgbGV0IGNhY2hlUGF0aCA9IHBhdGguam9pbihjYWNoZVJvb3QsIHRvb2xOYW1lLCB2ZXJzaW9uU3BlYywgYXJjaCk7XHJcbiAgICAgICAgdGwuZGVidWcoJ2NoZWNraW5nIGNhY2hlOiAnICsgY2FjaGVQYXRoKTtcclxuICAgICAgICBpZiAodGwuZXhpc3QoY2FjaGVQYXRoKSAmJiB0bC5leGlzdChgJHtjYWNoZVBhdGh9LmNvbXBsZXRlYCkpIHtcclxuICAgICAgICAgICAgY29uc29sZS5sb2codGwubG9jKCdUT09MX0xJQl9Gb3VuZEluQ2FjaGUnLCB0b29sTmFtZSwgdmVyc2lvblNwZWMsIGFyY2gpKTtcclxuICAgICAgICAgICAgdG9vbFBhdGggPSBjYWNoZVBhdGg7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0bC5kZWJ1Zygnbm90IGZvdW5kJyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRvb2xQYXRoO1xyXG59XHJcbmV4cG9ydHMuZmluZExvY2FsVG9vbCA9IGZpbmRMb2NhbFRvb2w7XHJcbi8qKlxyXG4gKiBSZXRyaWV2ZXMgdGhlIHZlcnNpb25zIG9mIGEgdG9vbCB0aGF0IGlzIGludGFsbGVkIGluIHRoZSBsb2NhbCB0b29sIGNhY2hlXHJcbiAqXHJcbiAqIEBwYXJhbSB0b29sTmFtZSAgbmFtZSBvZiB0aGUgdG9vbFxyXG4gKiBAcGFyYW0gYXJjaCAgICAgIG9wdGlvbmFsIGFyY2guICBkZWZhdWx0cyB0byBhcmNoIG9mIGNvbXB1dGVyXHJcbiAqL1xyXG5mdW5jdGlvbiBmaW5kTG9jYWxUb29sVmVyc2lvbnModG9vbE5hbWUsIGFyY2gpIHtcclxuICAgIGxldCB2ZXJzaW9ucyA9IFtdO1xyXG4gICAgYXJjaCA9IGFyY2ggfHwgb3MuYXJjaCgpO1xyXG4gICAgbGV0IHRvb2xQYXRoID0gcGF0aC5qb2luKF9nZXRDYWNoZVJvb3QoKSwgdG9vbE5hbWUpO1xyXG4gICAgaWYgKHRsLmV4aXN0KHRvb2xQYXRoKSkge1xyXG4gICAgICAgIGxldCBjaGlsZHJlbiA9IHRsLmxzKCcnLCBbdG9vbFBhdGhdKTtcclxuICAgICAgICBjaGlsZHJlbi5mb3JFYWNoKChjaGlsZCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoaXNFeHBsaWNpdFZlcnNpb24oY2hpbGQpKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgZnVsbFBhdGggPSBwYXRoLmpvaW4odG9vbFBhdGgsIGNoaWxkLCBhcmNoKTtcclxuICAgICAgICAgICAgICAgIGlmICh0bC5leGlzdChmdWxsUGF0aCkgJiYgdGwuZXhpc3QoYCR7ZnVsbFBhdGh9LmNvbXBsZXRlYCkpIHtcclxuICAgICAgICAgICAgICAgICAgICB2ZXJzaW9ucy5wdXNoKGNoaWxkKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHZlcnNpb25zO1xyXG59XHJcbmV4cG9ydHMuZmluZExvY2FsVG9vbFZlcnNpb25zID0gZmluZExvY2FsVG9vbFZlcnNpb25zO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBEb3dubG9hZCBGdW5jdGlvbnNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy9cclxuLy8gVE9ETzoga2VlcCBleHRlbnNpb24gaW50YWN0XHJcbi8vXHJcbi8qKlxyXG4gKiBEb3dubG9hZCBhIHRvb2wgZnJvbSBhbiB1cmwgYW5kIHN0cmVhbSBpdCBpbnRvIGEgZmlsZVxyXG4gKlxyXG4gKiBAcGFyYW0gdXJsICAgICAgIHVybCBvZiB0b29sIHRvIGRvd25sb2FkXHJcbiAqIEBwYXJhbSBmaWxlTmFtZSAgb3B0aW9uYWwgZmlsZU5hbWUuICBTaG91bGQgdHlwaWNhbGx5IG5vdCB1c2UgKHdpbGwgYmUgYSBndWlkIGZvciByZWxpYWJpbGl0eSkuIENhbiBwYXNzIGZpbGVOYW1lIHdpdGggYW4gYWJzb2x1dGUgcGF0aC5cclxuICogQHBhcmFtIGhhbmRsZXJzICBvcHRpb25hbCBoYW5kbGVycyBhcnJheS4gIEF1dGggaGFuZGxlcnMgdG8gcGFzcyB0byB0aGUgSHR0cENsaWVudCBmb3IgdGhlIHRvb2wgZG93bmxvYWQuXHJcbiAqL1xyXG5mdW5jdGlvbiBkb3dubG9hZFRvb2wodXJsLCBmaWxlTmFtZSwgaGFuZGxlcnMpIHtcclxuICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGhhbmRsZXJzID0gaGFuZGxlcnMgfHwgbnVsbDtcclxuICAgICAgICAgICAgICAgIGxldCBodHRwID0gbmV3IGh0dHBtLkh0dHBDbGllbnQodXNlckFnZW50LCBoYW5kbGVycywgcmVxdWVzdE9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgdGwuZGVidWcoZmlsZU5hbWUpO1xyXG4gICAgICAgICAgICAgICAgZmlsZU5hbWUgPSBmaWxlTmFtZSB8fCB1dWlkVjQoKTtcclxuICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIGl0J3MgYW4gYWJzb2x1dGUgcGF0aCBhbHJlYWR5XHJcbiAgICAgICAgICAgICAgICB2YXIgZGVzdFBhdGg7XHJcbiAgICAgICAgICAgICAgICBpZiAocGF0aC5pc0Fic29sdXRlKGZpbGVOYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlc3RQYXRoID0gZmlsZU5hbWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBkZXN0UGF0aCA9IHBhdGguam9pbihfZ2V0QWdlbnRUZW1wKCksIGZpbGVOYW1lKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGF0IHRoZSBmb2xkZXIgZXhpc3RzXHJcbiAgICAgICAgICAgICAgICB0bC5ta2RpclAocGF0aC5kaXJuYW1lKGRlc3RQYXRoKSk7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyh0bC5sb2MoJ1RPT0xfTElCX0Rvd25sb2FkaW5nJywgdXJsKSk7XHJcbiAgICAgICAgICAgICAgICB0bC5kZWJ1ZygnZGVzdGluYXRpb24gJyArIGRlc3RQYXRoKTtcclxuICAgICAgICAgICAgICAgIGlmIChmcy5leGlzdHNTeW5jKGRlc3RQYXRoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkRlc3RpbmF0aW9uIGZpbGUgcGF0aCBhbHJlYWR5IGV4aXN0c1wiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRsLmRlYnVnKCdkb3dubG9hZGluZycpO1xyXG4gICAgICAgICAgICAgICAgbGV0IHJlc3BvbnNlID0geWllbGQgaHR0cC5nZXQodXJsKTtcclxuICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5tZXNzYWdlLnN0YXR1c0NvZGUgIT0gMjAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGVyciA9IG5ldyBFcnJvcignVW5leHBlY3RlZCBIVFRQIHJlc3BvbnNlOiAnICsgcmVzcG9uc2UubWVzc2FnZS5zdGF0dXNDb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICBlcnJbJ2h0dHBTdGF0dXNDb2RlJ10gPSByZXNwb25zZS5tZXNzYWdlLnN0YXR1c0NvZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgdGwuZGVidWcoYEZhaWxlZCB0byBkb3dubG9hZCBcIiR7ZmlsZU5hbWV9XCIgZnJvbSBcIiR7dXJsfVwiLiBDb2RlKCR7cmVzcG9uc2UubWVzc2FnZS5zdGF0dXNDb2RlfSkgTWVzc2FnZSgke3Jlc3BvbnNlLm1lc3NhZ2Uuc3RhdHVzTWVzc2FnZX0pYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGwuZGVidWcoJ2NyZWF0aW5nIHN0cmVhbScpO1xyXG4gICAgICAgICAgICAgICAgbGV0IGZpbGUgPSBmcy5jcmVhdGVXcml0ZVN0cmVhbShkZXN0UGF0aCk7XHJcbiAgICAgICAgICAgICAgICBmaWxlLm9uKCdvcGVuJywgKGZkKSA9PiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHN0cmVhbSA9IHJlc3BvbnNlLm1lc3NhZ2UucGlwZShmaWxlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLm9uKCdjbG9zZScsICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRsLmRlYnVnKCdkb3dubG9hZCBjb21wbGV0ZScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShkZXN0UGF0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgICAgIGZpbGUub24oJ2Vycm9yJywgKGVycikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGZpbGUuZW5kKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KSk7XHJcbiAgICB9KTtcclxufVxyXG5leHBvcnRzLmRvd25sb2FkVG9vbCA9IGRvd25sb2FkVG9vbDtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gSW5zdGFsbCBGdW5jdGlvbnNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZnVuY3Rpb24gX2NyZWF0ZVRvb2xQYXRoKHRvb2wsIHZlcnNpb24sIGFyY2gpIHtcclxuICAgIC8vIHRvZG86IGFkZCB0ZXN0IGZvciBjbGVhblxyXG4gICAgbGV0IGZvbGRlclBhdGggPSBwYXRoLmpvaW4oX2dldENhY2hlUm9vdCgpLCB0b29sLCBzZW12ZXIuY2xlYW4odmVyc2lvbiksIGFyY2gpO1xyXG4gICAgdGwuZGVidWcoJ2Rlc3RpbmF0aW9uICcgKyBmb2xkZXJQYXRoKTtcclxuICAgIGxldCBtYXJrZXJQYXRoID0gYCR7Zm9sZGVyUGF0aH0uY29tcGxldGVgO1xyXG4gICAgdGwucm1SRihmb2xkZXJQYXRoKTtcclxuICAgIHRsLnJtUkYobWFya2VyUGF0aCk7XHJcbiAgICB0bC5ta2RpclAoZm9sZGVyUGF0aCk7XHJcbiAgICByZXR1cm4gZm9sZGVyUGF0aDtcclxufVxyXG5mdW5jdGlvbiBfY29tcGxldGVUb29sUGF0aCh0b29sLCB2ZXJzaW9uLCBhcmNoKSB7XHJcbiAgICBsZXQgZm9sZGVyUGF0aCA9IHBhdGguam9pbihfZ2V0Q2FjaGVSb290KCksIHRvb2wsIHNlbXZlci5jbGVhbih2ZXJzaW9uKSwgYXJjaCk7XHJcbiAgICBsZXQgbWFya2VyUGF0aCA9IGAke2ZvbGRlclBhdGh9LmNvbXBsZXRlYDtcclxuICAgIHRsLndyaXRlRmlsZShtYXJrZXJQYXRoLCAnJyk7XHJcbiAgICB0bC5kZWJ1ZygnZmluaXNoZWQgY2FjaGluZyB0b29sJyk7XHJcbn1cclxuLyoqXHJcbiAqIENhY2hlcyBhIGRpcmVjdG9yeSBhbmQgaW5zdGFsbHMgaXQgaW50byB0aGUgdG9vbCBjYWNoZURpclxyXG4gKlxyXG4gKiBAcGFyYW0gc291cmNlRGlyICAgIHRoZSBkaXJlY3RvcnkgdG8gY2FjaGUgaW50byB0b29sc1xyXG4gKiBAcGFyYW0gdG9vbCAgICAgICAgICB0b29sIG5hbWVcclxuICogQHBhcmFtIHZlcnNpb24gICAgICAgdmVyc2lvbiBvZiB0aGUgdG9vbC4gIHNlbXZlciBmb3JtYXRcclxuICogQHBhcmFtIGFyY2ggICAgICAgICAgYXJjaGl0ZWN0dXJlIG9mIHRoZSB0b29sLiAgT3B0aW9uYWwuICBEZWZhdWx0cyB0byBtYWNoaW5lIGFyY2hpdGVjdHVyZVxyXG4gKi9cclxuZnVuY3Rpb24gY2FjaGVEaXIoc291cmNlRGlyLCB0b29sLCB2ZXJzaW9uLCBhcmNoKSB7XHJcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgIHZlcnNpb24gPSBzZW12ZXIuY2xlYW4odmVyc2lvbik7XHJcbiAgICAgICAgYXJjaCA9IGFyY2ggfHwgb3MuYXJjaCgpO1xyXG4gICAgICAgIGNvbnNvbGUubG9nKHRsLmxvYygnVE9PTF9MSUJfQ2FjaGluZ1Rvb2wnLCB0b29sLCB2ZXJzaW9uLCBhcmNoKSk7XHJcbiAgICAgICAgdGwuZGVidWcoJ3NvdXJjZSBkaXI6ICcgKyBzb3VyY2VEaXIpO1xyXG4gICAgICAgIGlmICghdGwuc3RhdHMoc291cmNlRGlyKS5pc0RpcmVjdG9yeSgpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlRGlyIGlzIG5vdCBhIGRpcmVjdG9yeScpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBjcmVhdGUgdGhlIHRvb2wgZGlyXHJcbiAgICAgICAgbGV0IGRlc3RQYXRoID0gX2NyZWF0ZVRvb2xQYXRoKHRvb2wsIHZlcnNpb24sIGFyY2gpO1xyXG4gICAgICAgIC8vIGNvcHkgZWFjaCBjaGlsZCBpdGVtLiBkbyBub3QgbW92ZS4gbW92ZSBjYW4gZmFpbCBvbiBXaW5kb3dzXHJcbiAgICAgICAgLy8gZHVlIHRvIGFudGktdmlydXMgc29mdHdhcmUgaGF2aW5nIGFuIG9wZW4gaGFuZGxlIG9uIGEgZmlsZS5cclxuICAgICAgICBmb3IgKGxldCBpdGVtTmFtZSBvZiBmcy5yZWFkZGlyU3luYyhzb3VyY2VEaXIpKSB7XHJcbiAgICAgICAgICAgIGxldCBzID0gcGF0aC5qb2luKHNvdXJjZURpciwgaXRlbU5hbWUpO1xyXG4gICAgICAgICAgICB0bC5jcChzLCBkZXN0UGF0aCArICcvJywgJy1yJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHdyaXRlIC5jb21wbGV0ZVxyXG4gICAgICAgIF9jb21wbGV0ZVRvb2xQYXRoKHRvb2wsIHZlcnNpb24sIGFyY2gpO1xyXG4gICAgICAgIHJldHVybiBkZXN0UGF0aDtcclxuICAgIH0pO1xyXG59XHJcbmV4cG9ydHMuY2FjaGVEaXIgPSBjYWNoZURpcjtcclxuLyoqXHJcbiAqIENhY2hlcyBhIGRvd25sb2FkZWQgZmlsZSAoR1VJRCkgYW5kIGluc3RhbGxzIGl0XHJcbiAqIGludG8gdGhlIHRvb2wgY2FjaGUgd2l0aCBhIGdpdmVuIHRhcmdldE5hbWVcclxuICpcclxuICogQHBhcmFtIHNvdXJjZUZpbGUgICAgdGhlIGZpbGUgdG8gY2FjaGUgaW50byB0b29scy4gIFR5cGljYWxseSBhIHJlc3VsdCBvZiBkb3dubG9hZFRvb2wgd2hpY2ggaXMgYSBndWlkLlxyXG4gKiBAcGFyYW0gdGFyZ2V0RmlsZSAgICB0aGUgbmFtZSBvZiB0aGUgZmlsZSBuYW1lIGluIHRoZSB0b29scyBkaXJlY3RvcnlcclxuICogQHBhcmFtIHRvb2wgICAgICAgICAgdG9vbCBuYW1lXHJcbiAqIEBwYXJhbSB2ZXJzaW9uICAgICAgIHZlcnNpb24gb2YgdGhlIHRvb2wuICBzZW12ZXIgZm9ybWF0XHJcbiAqIEBwYXJhbSBhcmNoICAgICAgICAgIGFyY2hpdGVjdHVyZSBvZiB0aGUgdG9vbC4gIE9wdGlvbmFsLiAgRGVmYXVsdHMgdG8gbWFjaGluZSBhcmNoaXRlY3R1cmVcclxuICovXHJcbmZ1bmN0aW9uIGNhY2hlRmlsZShzb3VyY2VGaWxlLCB0YXJnZXRGaWxlLCB0b29sLCB2ZXJzaW9uLCBhcmNoKSB7XHJcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgIHZlcnNpb24gPSBzZW12ZXIuY2xlYW4odmVyc2lvbik7XHJcbiAgICAgICAgYXJjaCA9IGFyY2ggfHwgb3MuYXJjaCgpO1xyXG4gICAgICAgIGNvbnNvbGUubG9nKHRsLmxvYygnVE9PTF9MSUJfQ2FjaGluZ1Rvb2wnLCB0b29sLCB2ZXJzaW9uLCBhcmNoKSk7XHJcbiAgICAgICAgdGwuZGVidWcoJ3NvdXJjZSBmaWxlOicgKyBzb3VyY2VGaWxlKTtcclxuICAgICAgICBpZiAoIXRsLnN0YXRzKHNvdXJjZUZpbGUpLmlzRmlsZSgpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlRmlsZSBpcyBub3QgYSBmaWxlJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGNyZWF0ZSB0aGUgdG9vbCBkaXJcclxuICAgICAgICBsZXQgZGVzdEZvbGRlciA9IF9jcmVhdGVUb29sUGF0aCh0b29sLCB2ZXJzaW9uLCBhcmNoKTtcclxuICAgICAgICAvLyBjb3B5IGluc3RlYWQgb2YgbW92ZS4gbW92ZSBjYW4gZmFpbCBvbiBXaW5kb3dzIGR1ZSB0b1xyXG4gICAgICAgIC8vIGFudGktdmlydXMgc29mdHdhcmUgaGF2aW5nIGFuIG9wZW4gaGFuZGxlIG9uIGEgZmlsZS5cclxuICAgICAgICBsZXQgZGVzdFBhdGggPSBwYXRoLmpvaW4oZGVzdEZvbGRlciwgdGFyZ2V0RmlsZSk7XHJcbiAgICAgICAgdGwuZGVidWcoJ2Rlc3RpbmF0aW9uIGZpbGUnICsgZGVzdFBhdGgpO1xyXG4gICAgICAgIHRsLmNwKHNvdXJjZUZpbGUsIGRlc3RQYXRoKTtcclxuICAgICAgICAvLyB3cml0ZSAuY29tcGxldGVcclxuICAgICAgICBfY29tcGxldGVUb29sUGF0aCh0b29sLCB2ZXJzaW9uLCBhcmNoKTtcclxuICAgICAgICByZXR1cm4gZGVzdEZvbGRlcjtcclxuICAgIH0pO1xyXG59XHJcbmV4cG9ydHMuY2FjaGVGaWxlID0gY2FjaGVGaWxlO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBFeHRyYWN0IEZ1bmN0aW9uc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vKipcclxuICogRXh0cmFjdCBhIC43eiBmaWxlXHJcbiAqXHJcbiAqIEBwYXJhbSBmaWxlICAgICBwYXRoIHRvIHRoZSAuN3ogZmlsZVxyXG4gKiBAcGFyYW0gZGVzdCAgICAgZGVzdGluYXRpb24gZGlyZWN0b3J5LiBPcHRpb25hbC5cclxuICogQHBhcmFtIF83elBhdGggIHBhdGggdG8gN3pyLmV4ZS4gT3B0aW9uYWwsIGZvciBsb25nIHBhdGggc3VwcG9ydC4gTW9zdCAuN3ogYXJjaGl2ZXMgZG8gbm90IGhhdmUgdGhpc1xyXG4gKiBwcm9ibGVtLiBJZiB5b3VyIC43eiBhcmNoaXZlIGNvbnRhaW5zIHZlcnkgbG9uZyBwYXRocywgeW91IGNhbiBwYXNzIHRoZSBwYXRoIHRvIDd6ci5leGUgd2hpY2ggd2lsbFxyXG4gKiBncmFjZWZ1bGx5IGhhbmRsZSBsb25nIHBhdGhzLiBCeSBkZWZhdWx0IDd6ZGVjLmV4ZSBpcyB1c2VkIGJlY2F1c2UgaXQgaXMgYSB2ZXJ5IHNtYWxsIHByb2dyYW0gYW5kIGlzXHJcbiAqIGJ1bmRsZWQgd2l0aCB0aGUgdG9vbCBsaWIuIEhvd2V2ZXIgaXQgZG9lcyBub3Qgc3VwcG9ydCBsb25nIHBhdGhzLiA3enIuZXhlIGlzIHRoZSByZWR1Y2VkIGNvbW1hbmQgbGluZVxyXG4gKiBpbnRlcmZhY2UsIGl0IGlzIHNtYWxsZXIgdGhhbiB0aGUgZnVsbCBjb21tYW5kIGxpbmUgaW50ZXJmYWNlLCBhbmQgaXQgZG9lcyBzdXBwb3J0IGxvbmcgcGF0aHMuIEF0IHRoZVxyXG4gKiB0aW1lIG9mIHRoaXMgd3JpdGluZywgaXQgaXMgZnJlZWx5IGF2YWlsYWJsZSBmcm9tIHRoZSBMWk1BIFNESyB0aGF0IGlzIGF2YWlsYWJsZSBvbiB0aGUgN3ppcCB3ZWJzaXRlLlxyXG4gKiBCZSBzdXJlIHRvIGNoZWNrIHRoZSBjdXJyZW50IGxpY2Vuc2UgYWdyZWVtZW50LiBJZiA3enIuZXhlIGlzIGJ1bmRsZWQgd2l0aCB5b3VyIHRhc2ssIHRoZW4gdGhlIHBhdGhcclxuICogdG8gN3pyLmV4ZSBjYW4gYmUgcGFzcyB0byB0aGlzIGZ1bmN0aW9uLlxyXG4gKiBAcmV0dXJucyAgICAgICAgcGF0aCB0byB0aGUgZGVzdGluYXRpb24gZGlyZWN0b3J5XHJcbiAqL1xyXG5mdW5jdGlvbiBleHRyYWN0N3ooZmlsZSwgZGVzdCwgXzd6UGF0aCkge1xyXG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSAhPSAnd2luMzInKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZXh0cmFjdDd6KCkgbm90IHN1cHBvcnRlZCBvbiBjdXJyZW50IE9TJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghZmlsZSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJwYXJhbWV0ZXIgJ2ZpbGUnIGlzIHJlcXVpcmVkXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zb2xlLmxvZyh0bC5sb2MoJ1RPT0xfTElCX0V4dHJhY3RpbmdBcmNoaXZlJykpO1xyXG4gICAgICAgIGRlc3QgPSBfY3JlYXRlRXh0cmFjdEZvbGRlcihkZXN0KTtcclxuICAgICAgICBsZXQgb3JpZ2luYWxDd2QgPSBwcm9jZXNzLmN3ZCgpO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHByb2Nlc3MuY2hkaXIoZGVzdCk7XHJcbiAgICAgICAgICAgIGlmIChfN3pQYXRoKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBleHRyYWN0XHJcbiAgICAgICAgICAgICAgICBsZXQgXzd6ID0gdGwudG9vbChfN3pQYXRoKVxyXG4gICAgICAgICAgICAgICAgICAgIC5hcmcoJ3gnKSAvLyBlWHRyYWN0IGZpbGVzIHdpdGggZnVsbCBwYXRoc1xyXG4gICAgICAgICAgICAgICAgICAgIC5hcmcoJy1iYjEnKSAvLyAtYmJbMC0zXSA6IHNldCBvdXRwdXQgbG9nIGxldmVsXHJcbiAgICAgICAgICAgICAgICAgICAgLmFyZygnLWJkJykgLy8gZGlzYWJsZSBwcm9ncmVzcyBpbmRpY2F0b3JcclxuICAgICAgICAgICAgICAgICAgICAuYXJnKCctc2NjVVRGLTgnKSAvLyBzZXQgY2hhcnNldCBmb3IgZm9yIGNvbnNvbGUgaW5wdXQvb3V0cHV0XHJcbiAgICAgICAgICAgICAgICAgICAgLmFyZyhmaWxlKTtcclxuICAgICAgICAgICAgICAgIHlpZWxkIF83ei5leGVjKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBleHRyYWN0XHJcbiAgICAgICAgICAgICAgICBsZXQgZXNjYXBlZFNjcmlwdCA9IHBhdGguam9pbihfX2Rpcm5hbWUsICdJbnZva2UtN3pkZWMucHMxJykucmVwbGFjZSgvJy9nLCBcIicnXCIpLnJlcGxhY2UoL1wifFxcbnxcXHIvZywgJycpOyAvLyBkb3VibGUtdXAgc2luZ2xlIHF1b3RlcywgcmVtb3ZlIGRvdWJsZSBxdW90ZXMgYW5kIG5ld2xpbmVzXHJcbiAgICAgICAgICAgICAgICBsZXQgZXNjYXBlZEZpbGUgPSBmaWxlLnJlcGxhY2UoLycvZywgXCInJ1wiKS5yZXBsYWNlKC9cInxcXG58XFxyL2csICcnKTtcclxuICAgICAgICAgICAgICAgIGxldCBlc2NhcGVkVGFyZ2V0ID0gZGVzdC5yZXBsYWNlKC8nL2csIFwiJydcIikucmVwbGFjZSgvXCJ8XFxufFxcci9nLCAnJyk7XHJcbiAgICAgICAgICAgICAgICBsZXQgY29tbWFuZCA9IGAmICcke2VzY2FwZWRTY3JpcHR9JyAtU291cmNlICcke2VzY2FwZWRGaWxlfScgLVRhcmdldCAnJHtlc2NhcGVkVGFyZ2V0fSdgO1xyXG4gICAgICAgICAgICAgICAgbGV0IHBvd2Vyc2hlbGxQYXRoID0gdGwud2hpY2goJ3Bvd2Vyc2hlbGwnLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgIGxldCBwb3dlcnNoZWxsID0gdGwudG9vbChwb3dlcnNoZWxsUGF0aClcclxuICAgICAgICAgICAgICAgICAgICAubGluZSgnLU5vTG9nbyAtU3RhIC1Ob1Byb2ZpbGUgLU5vbkludGVyYWN0aXZlIC1FeGVjdXRpb25Qb2xpY3kgVW5yZXN0cmljdGVkIC1Db21tYW5kJylcclxuICAgICAgICAgICAgICAgICAgICAuYXJnKGNvbW1hbmQpO1xyXG4gICAgICAgICAgICAgICAgcG93ZXJzaGVsbC5vbignc3Rkb3V0JywgKGJ1ZmZlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKGJ1ZmZlcik7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHBvd2Vyc2hlbGwub24oJ3N0ZGVycicsIChidWZmZXIpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLnN0ZGVyci53cml0ZShidWZmZXIpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB5aWVsZCBwb3dlcnNoZWxsLmV4ZWMoeyBzaWxlbnQ6IHRydWUgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7XHJcbiAgICAgICAgICAgIHByb2Nlc3MuY2hkaXIob3JpZ2luYWxDd2QpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZGVzdDtcclxuICAgIH0pO1xyXG59XHJcbmV4cG9ydHMuZXh0cmFjdDd6ID0gZXh0cmFjdDd6O1xyXG4vKipcclxuICogaW5zdGFsbHMgYSB0b29sIGZyb20gYSB0YXIgYnkgZXh0cmFjdGluZyB0aGUgdGFyIGFuZCBpbnN0YWxsaW5nIGl0IGludG8gdGhlIHRvb2wgY2FjaGVcclxuICpcclxuICogQHBhcmFtIGZpbGUgICAgICBmaWxlIHBhdGggb2YgdGhlIHRhclxyXG4gKiBAcGFyYW0gdG9vbCAgICAgIG5hbWUgb2YgdG9vbCBpbiB0aGUgdG9vbCBjYWNoZVxyXG4gKiBAcGFyYW0gdmVyc2lvbiAgIHZlcnNpb24gb2YgdGhlIHRvb2xcclxuICogQHBhcmFtIGFyY2ggICAgICBhcmNoIG9mIHRoZSB0b29sLiAgb3B0aW9uYWwuICBkZWZhdWx0cyB0byB0aGUgYXJjaCBvZiB0aGUgbWFjaGluZVxyXG4gKiBAcGFyYW0gb3B0aW9ucyAgIElFeHRyYWN0T3B0aW9uc1xyXG4gKiBAcGFyYW0gZGVzdGluYXRpb24gICBkZXN0aW5hdGlvbiBkaXJlY3RvcnkuIG9wdGlvbmFsLlxyXG4gKi9cclxuZnVuY3Rpb24gZXh0cmFjdFRhcihmaWxlLCBkZXN0aW5hdGlvbikge1xyXG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICAvLyBta2RpciAtcCBub2RlLzQuNy4wL3g2NFxyXG4gICAgICAgIC8vIHRhciB4ekMgLi9ub2RlLzQuNy4wL3g2NCAtZiBub2RlLXY0LjcuMC1kYXJ3aW4teDY0LnRhci5neiAtLXN0cmlwLWNvbXBvbmVudHMgMVxyXG4gICAgICAgIGNvbnNvbGUubG9nKHRsLmxvYygnVE9PTF9MSUJfRXh0cmFjdGluZ0FyY2hpdmUnKSk7XHJcbiAgICAgICAgbGV0IGRlc3QgPSBfY3JlYXRlRXh0cmFjdEZvbGRlcihkZXN0aW5hdGlvbik7XHJcbiAgICAgICAgbGV0IHRyID0gdGwudG9vbCgndGFyJyk7XHJcbiAgICAgICAgdHIuYXJnKFsneEMnLCBkZXN0LCAnLWYnLCBmaWxlXSk7XHJcbiAgICAgICAgeWllbGQgdHIuZXhlYygpO1xyXG4gICAgICAgIHJldHVybiBkZXN0O1xyXG4gICAgfSk7XHJcbn1cclxuZXhwb3J0cy5leHRyYWN0VGFyID0gZXh0cmFjdFRhcjtcclxuZnVuY3Rpb24gZXh0cmFjdFppcChmaWxlLCBkZXN0aW5hdGlvbikge1xyXG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICBpZiAoIWZpbGUpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwicGFyYW1ldGVyICdmaWxlJyBpcyByZXF1aXJlZFwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc29sZS5sb2codGwubG9jKCdUT09MX0xJQl9FeHRyYWN0aW5nQXJjaGl2ZScpKTtcclxuICAgICAgICBsZXQgZGVzdCA9IF9jcmVhdGVFeHRyYWN0Rm9sZGVyKGRlc3RpbmF0aW9uKTtcclxuICAgICAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInKSB7XHJcbiAgICAgICAgICAgIC8vIGJ1aWxkIHRoZSBwb3dlcnNoZWxsIGNvbW1hbmRcclxuICAgICAgICAgICAgbGV0IGVzY2FwZWRGaWxlID0gZmlsZS5yZXBsYWNlKC8nL2csIFwiJydcIikucmVwbGFjZSgvXCJ8XFxufFxcci9nLCAnJyk7IC8vIGRvdWJsZS11cCBzaW5nbGUgcXVvdGVzLCByZW1vdmUgZG91YmxlIHF1b3RlcyBhbmQgbmV3bGluZXNcclxuICAgICAgICAgICAgbGV0IGVzY2FwZWREZXN0ID0gZGVzdC5yZXBsYWNlKC8nL2csIFwiJydcIikucmVwbGFjZSgvXCJ8XFxufFxcci9nLCAnJyk7XHJcbiAgICAgICAgICAgIGxldCBjb21tYW5kID0gYCRFcnJvckFjdGlvblByZWZlcmVuY2UgPSAnU3RvcCcgOyB0cnkgeyBBZGQtVHlwZSAtQXNzZW1ibHlOYW1lIFN5c3RlbS5JTy5Db21wcmVzc2lvbi5GaWxlU3lzdGVtIH0gY2F0Y2ggeyB9IDsgW1N5c3RlbS5JTy5Db21wcmVzc2lvbi5aaXBGaWxlXTo6RXh0cmFjdFRvRGlyZWN0b3J5KCcke2VzY2FwZWRGaWxlfScsICcke2VzY2FwZWREZXN0fScpYDtcclxuICAgICAgICAgICAgLy8gY2hhbmdlIHRoZSBjb25zb2xlIG91dHB1dCBjb2RlIHBhZ2UgdG8gVVRGLTguXHJcbiAgICAgICAgICAgIC8vIFRPRE86IEZJWCBXSElDSDogbGV0IGNoY3BQYXRoID0gdGwud2hpY2goJ2NoY3AuY29tJywgdHJ1ZSk7XHJcbiAgICAgICAgICAgIGxldCBjaGNwUGF0aCA9IHBhdGguam9pbihwcm9jZXNzLmVudi53aW5kaXIsIFwic3lzdGVtMzJcIiwgXCJjaGNwLmNvbVwiKTtcclxuICAgICAgICAgICAgeWllbGQgdGwuZXhlYyhjaGNwUGF0aCwgJzY1MDAxJyk7XHJcbiAgICAgICAgICAgIC8vIHJ1biBwb3dlcnNoZWxsXHJcbiAgICAgICAgICAgIGxldCBwb3dlcnNoZWxsID0gdGwudG9vbCgncG93ZXJzaGVsbCcpXHJcbiAgICAgICAgICAgICAgICAubGluZSgnLU5vTG9nbyAtU3RhIC1Ob1Byb2ZpbGUgLU5vbkludGVyYWN0aXZlIC1FeGVjdXRpb25Qb2xpY3kgVW5yZXN0cmljdGVkIC1Db21tYW5kJylcclxuICAgICAgICAgICAgICAgIC5hcmcoY29tbWFuZCk7XHJcbiAgICAgICAgICAgIHlpZWxkIHBvd2Vyc2hlbGwuZXhlYygpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgbGV0IHVuemlwID0gdGwudG9vbCgndW56aXAnKVxyXG4gICAgICAgICAgICAgICAgLmFyZyhmaWxlKTtcclxuICAgICAgICAgICAgeWllbGQgdW56aXAuZXhlYyh7IGN3ZDogZGVzdCB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGRlc3Q7XHJcbiAgICB9KTtcclxufVxyXG5leHBvcnRzLmV4dHJhY3RaaXAgPSBleHRyYWN0WmlwO1xyXG5mdW5jdGlvbiBfY3JlYXRlRXh0cmFjdEZvbGRlcihkZXN0KSB7XHJcbiAgICBpZiAoIWRlc3QpIHtcclxuICAgICAgICAvLyBjcmVhdGUgYSB0ZW1wIGRpclxyXG4gICAgICAgIGRlc3QgPSBwYXRoLmpvaW4oX2dldEFnZW50VGVtcCgpLCB1dWlkVjQoKSk7XHJcbiAgICB9XHJcbiAgICB0bC5ta2RpclAoZGVzdCk7XHJcbiAgICByZXR1cm4gZGVzdDtcclxufVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBRdWVyeSBGdW5jdGlvbnNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gICAgICAgZGVmYXVsdCBpbnB1dCB3aWxsIGJlID49IExUUyB2ZXJzaW9uLiAgZHJvcCBsYWJlbCBkaWZmZXJlbnQgdGhhbiB2YWx1ZS5cclxuLy8gICAgICAgdjQgKExUUykgd291bGQgaGF2ZSBhIHZhbHVlIG9mIDQueFxyXG4vLyAgICAgICBvcHRpb24gdG8gYWx3YXlzIGRvd25sb2FkPyAgKG5vdCBjYWNoZSksIFRUTD9cclxuLyoqXHJcbiAqIFNjcmFwZSBhIHdlYiBwYWdlIGZvciB2ZXJzaW9ucyBieSByZWdleFxyXG4gKlxyXG4gKiBAcGFyYW0gdXJsICAgICAgIHVybCB0byBzY3JhcGVcclxuICogQHBhcmFtIHJlZ2V4ICAgICByZWdleCB0byB1c2UgZm9yIHZlcnNpb24gbWF0Y2hlc1xyXG4gKiBAcGFyYW0gaGFuZGxlcnMgIG9wdGlvbmFsIGhhbmRsZXJzIGFycmF5LiAgQXV0aCBoYW5kbGVycyB0byBwYXNzIHRvIHRoZSBIdHRwQ2xpZW50IGZvciB0aGUgdG9vbCBkb3dubG9hZC5cclxuICovXHJcbmZ1bmN0aW9uIHNjcmFwZSh1cmwsIHJlZ2V4LCBoYW5kbGVycykge1xyXG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICBoYW5kbGVycyA9IGhhbmRsZXJzIHx8IG51bGw7XHJcbiAgICAgICAgbGV0IGh0dHAgPSBuZXcgaHR0cG0uSHR0cENsaWVudCh1c2VyQWdlbnQsIGhhbmRsZXJzLCByZXF1ZXN0T3B0aW9ucyk7XHJcbiAgICAgICAgbGV0IG91dHB1dCA9IHlpZWxkICh5aWVsZCBodHRwLmdldCh1cmwpKS5yZWFkQm9keSgpO1xyXG4gICAgICAgIGxldCBtYXRjaGVzID0gb3V0cHV0Lm1hdGNoKHJlZ2V4KTtcclxuICAgICAgICBsZXQgc2VlbiA9IHt9O1xyXG4gICAgICAgIGxldCB2ZXJzaW9ucyA9IFtdO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWF0Y2hlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgdmVyID0gc2VtdmVyLmNsZWFuKG1hdGNoZXNbaV0pO1xyXG4gICAgICAgICAgICBpZiAoIXNlZW4uaGFzT3duUHJvcGVydHkodmVyKSkge1xyXG4gICAgICAgICAgICAgICAgc2Vlblt2ZXJdID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHZlcnNpb25zLnB1c2godmVyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdmVyc2lvbnM7XHJcbiAgICB9KTtcclxufVxyXG5leHBvcnRzLnNjcmFwZSA9IHNjcmFwZTtcclxuZnVuY3Rpb24gX2dldENhY2hlUm9vdCgpIHtcclxuICAgIHRsLmFzc2VydEFnZW50KCcyLjExNS4wJyk7XHJcbiAgICBsZXQgY2FjaGVSb290ID0gdGwuZ2V0VmFyaWFibGUoJ0FnZW50LlRvb2xzRGlyZWN0b3J5Jyk7XHJcbiAgICBpZiAoIWNhY2hlUm9vdCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQWdlbnQuVG9vbHNEaXJlY3RvcnkgaXMgbm90IHNldCcpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGNhY2hlUm9vdDtcclxufVxyXG5mdW5jdGlvbiBfZ2V0QWdlbnRUZW1wKCkge1xyXG4gICAgdGwuYXNzZXJ0QWdlbnQoJzIuMTE1LjAnKTtcclxuICAgIGxldCB0ZW1wRGlyZWN0b3J5ID0gdGwuZ2V0VmFyaWFibGUoJ0FnZW50LlRlbXBEaXJlY3RvcnknKTtcclxuICAgIGlmICghdGVtcERpcmVjdG9yeSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQWdlbnQuVGVtcERpcmVjdG9yeSBpcyBub3Qgc2V0Jyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGVtcERpcmVjdG9yeTtcclxufVxyXG4iLCJmdW5jdGlvbiB3ZWJwYWNrRW1wdHlDb250ZXh0KHJlcSkge1xuXHR2YXIgZSA9IG5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIgKyByZXEgKyBcIidcIik7XG5cdGUuY29kZSA9ICdNT0RVTEVfTk9UX0ZPVU5EJztcblx0dGhyb3cgZTtcbn1cbndlYnBhY2tFbXB0eUNvbnRleHQua2V5cyA9ICgpID0+IFtdO1xud2VicGFja0VtcHR5Q29udGV4dC5yZXNvbHZlID0gd2VicGFja0VtcHR5Q29udGV4dDtcbndlYnBhY2tFbXB0eUNvbnRleHQuaWQgPSBcIi4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10b29sLWxpYiBzeW5jIHJlY3Vyc2l2ZVwiO1xubW9kdWxlLmV4cG9ydHMgPSB3ZWJwYWNrRW1wdHlDb250ZXh0OyIsIid1c2Ugc3RyaWN0Jztcbm1vZHVsZS5leHBvcnRzID0gYmFsYW5jZWQ7XG5mdW5jdGlvbiBiYWxhbmNlZChhLCBiLCBzdHIpIHtcbiAgaWYgKGEgaW5zdGFuY2VvZiBSZWdFeHApIGEgPSBtYXliZU1hdGNoKGEsIHN0cik7XG4gIGlmIChiIGluc3RhbmNlb2YgUmVnRXhwKSBiID0gbWF5YmVNYXRjaChiLCBzdHIpO1xuXG4gIHZhciByID0gcmFuZ2UoYSwgYiwgc3RyKTtcblxuICByZXR1cm4gciAmJiB7XG4gICAgc3RhcnQ6IHJbMF0sXG4gICAgZW5kOiByWzFdLFxuICAgIHByZTogc3RyLnNsaWNlKDAsIHJbMF0pLFxuICAgIGJvZHk6IHN0ci5zbGljZShyWzBdICsgYS5sZW5ndGgsIHJbMV0pLFxuICAgIHBvc3Q6IHN0ci5zbGljZShyWzFdICsgYi5sZW5ndGgpXG4gIH07XG59XG5cbmZ1bmN0aW9uIG1heWJlTWF0Y2gocmVnLCBzdHIpIHtcbiAgdmFyIG0gPSBzdHIubWF0Y2gocmVnKTtcbiAgcmV0dXJuIG0gPyBtWzBdIDogbnVsbDtcbn1cblxuYmFsYW5jZWQucmFuZ2UgPSByYW5nZTtcbmZ1bmN0aW9uIHJhbmdlKGEsIGIsIHN0cikge1xuICB2YXIgYmVncywgYmVnLCBsZWZ0LCByaWdodCwgcmVzdWx0O1xuICB2YXIgYWkgPSBzdHIuaW5kZXhPZihhKTtcbiAgdmFyIGJpID0gc3RyLmluZGV4T2YoYiwgYWkgKyAxKTtcbiAgdmFyIGkgPSBhaTtcblxuICBpZiAoYWkgPj0gMCAmJiBiaSA+IDApIHtcbiAgICBiZWdzID0gW107XG4gICAgbGVmdCA9IHN0ci5sZW5ndGg7XG5cbiAgICB3aGlsZSAoaSA+PSAwICYmICFyZXN1bHQpIHtcbiAgICAgIGlmIChpID09IGFpKSB7XG4gICAgICAgIGJlZ3MucHVzaChpKTtcbiAgICAgICAgYWkgPSBzdHIuaW5kZXhPZihhLCBpICsgMSk7XG4gICAgICB9IGVsc2UgaWYgKGJlZ3MubGVuZ3RoID09IDEpIHtcbiAgICAgICAgcmVzdWx0ID0gWyBiZWdzLnBvcCgpLCBiaSBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYmVnID0gYmVncy5wb3AoKTtcbiAgICAgICAgaWYgKGJlZyA8IGxlZnQpIHtcbiAgICAgICAgICBsZWZ0ID0gYmVnO1xuICAgICAgICAgIHJpZ2h0ID0gYmk7XG4gICAgICAgIH1cblxuICAgICAgICBiaSA9IHN0ci5pbmRleE9mKGIsIGkgKyAxKTtcbiAgICAgIH1cblxuICAgICAgaSA9IGFpIDwgYmkgJiYgYWkgPj0gMCA/IGFpIDogYmk7XG4gICAgfVxuXG4gICAgaWYgKGJlZ3MubGVuZ3RoKSB7XG4gICAgICByZXN1bHQgPSBbIGxlZnQsIHJpZ2h0IF07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiIsInZhciBjb25jYXRNYXAgPSByZXF1aXJlKCdjb25jYXQtbWFwJyk7XG52YXIgYmFsYW5jZWQgPSByZXF1aXJlKCdiYWxhbmNlZC1tYXRjaCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGV4cGFuZFRvcDtcblxudmFyIGVzY1NsYXNoID0gJ1xcMFNMQVNIJytNYXRoLnJhbmRvbSgpKydcXDAnO1xudmFyIGVzY09wZW4gPSAnXFwwT1BFTicrTWF0aC5yYW5kb20oKSsnXFwwJztcbnZhciBlc2NDbG9zZSA9ICdcXDBDTE9TRScrTWF0aC5yYW5kb20oKSsnXFwwJztcbnZhciBlc2NDb21tYSA9ICdcXDBDT01NQScrTWF0aC5yYW5kb20oKSsnXFwwJztcbnZhciBlc2NQZXJpb2QgPSAnXFwwUEVSSU9EJytNYXRoLnJhbmRvbSgpKydcXDAnO1xuXG5mdW5jdGlvbiBudW1lcmljKHN0cikge1xuICByZXR1cm4gcGFyc2VJbnQoc3RyLCAxMCkgPT0gc3RyXG4gICAgPyBwYXJzZUludChzdHIsIDEwKVxuICAgIDogc3RyLmNoYXJDb2RlQXQoMCk7XG59XG5cbmZ1bmN0aW9uIGVzY2FwZUJyYWNlcyhzdHIpIHtcbiAgcmV0dXJuIHN0ci5zcGxpdCgnXFxcXFxcXFwnKS5qb2luKGVzY1NsYXNoKVxuICAgICAgICAgICAgLnNwbGl0KCdcXFxceycpLmpvaW4oZXNjT3BlbilcbiAgICAgICAgICAgIC5zcGxpdCgnXFxcXH0nKS5qb2luKGVzY0Nsb3NlKVxuICAgICAgICAgICAgLnNwbGl0KCdcXFxcLCcpLmpvaW4oZXNjQ29tbWEpXG4gICAgICAgICAgICAuc3BsaXQoJ1xcXFwuJykuam9pbihlc2NQZXJpb2QpO1xufVxuXG5mdW5jdGlvbiB1bmVzY2FwZUJyYWNlcyhzdHIpIHtcbiAgcmV0dXJuIHN0ci5zcGxpdChlc2NTbGFzaCkuam9pbignXFxcXCcpXG4gICAgICAgICAgICAuc3BsaXQoZXNjT3Blbikuam9pbigneycpXG4gICAgICAgICAgICAuc3BsaXQoZXNjQ2xvc2UpLmpvaW4oJ30nKVxuICAgICAgICAgICAgLnNwbGl0KGVzY0NvbW1hKS5qb2luKCcsJylcbiAgICAgICAgICAgIC5zcGxpdChlc2NQZXJpb2QpLmpvaW4oJy4nKTtcbn1cblxuXG4vLyBCYXNpY2FsbHkganVzdCBzdHIuc3BsaXQoXCIsXCIpLCBidXQgaGFuZGxpbmcgY2FzZXNcbi8vIHdoZXJlIHdlIGhhdmUgbmVzdGVkIGJyYWNlZCBzZWN0aW9ucywgd2hpY2ggc2hvdWxkIGJlXG4vLyB0cmVhdGVkIGFzIGluZGl2aWR1YWwgbWVtYmVycywgbGlrZSB7YSx7YixjfSxkfVxuZnVuY3Rpb24gcGFyc2VDb21tYVBhcnRzKHN0cikge1xuICBpZiAoIXN0cilcbiAgICByZXR1cm4gWycnXTtcblxuICB2YXIgcGFydHMgPSBbXTtcbiAgdmFyIG0gPSBiYWxhbmNlZCgneycsICd9Jywgc3RyKTtcblxuICBpZiAoIW0pXG4gICAgcmV0dXJuIHN0ci5zcGxpdCgnLCcpO1xuXG4gIHZhciBwcmUgPSBtLnByZTtcbiAgdmFyIGJvZHkgPSBtLmJvZHk7XG4gIHZhciBwb3N0ID0gbS5wb3N0O1xuICB2YXIgcCA9IHByZS5zcGxpdCgnLCcpO1xuXG4gIHBbcC5sZW5ndGgtMV0gKz0gJ3snICsgYm9keSArICd9JztcbiAgdmFyIHBvc3RQYXJ0cyA9IHBhcnNlQ29tbWFQYXJ0cyhwb3N0KTtcbiAgaWYgKHBvc3QubGVuZ3RoKSB7XG4gICAgcFtwLmxlbmd0aC0xXSArPSBwb3N0UGFydHMuc2hpZnQoKTtcbiAgICBwLnB1c2guYXBwbHkocCwgcG9zdFBhcnRzKTtcbiAgfVxuXG4gIHBhcnRzLnB1c2guYXBwbHkocGFydHMsIHApO1xuXG4gIHJldHVybiBwYXJ0cztcbn1cblxuZnVuY3Rpb24gZXhwYW5kVG9wKHN0cikge1xuICBpZiAoIXN0cilcbiAgICByZXR1cm4gW107XG5cbiAgLy8gSSBkb24ndCBrbm93IHdoeSBCYXNoIDQuMyBkb2VzIHRoaXMsIGJ1dCBpdCBkb2VzLlxuICAvLyBBbnl0aGluZyBzdGFydGluZyB3aXRoIHt9IHdpbGwgaGF2ZSB0aGUgZmlyc3QgdHdvIGJ5dGVzIHByZXNlcnZlZFxuICAvLyBidXQgKm9ubHkqIGF0IHRoZSB0b3AgbGV2ZWwsIHNvIHt9LGF9YiB3aWxsIG5vdCBleHBhbmQgdG8gYW55dGhpbmcsXG4gIC8vIGJ1dCBhe30sYn1jIHdpbGwgYmUgZXhwYW5kZWQgdG8gW2F9YyxhYmNdLlxuICAvLyBPbmUgY291bGQgYXJndWUgdGhhdCB0aGlzIGlzIGEgYnVnIGluIEJhc2gsIGJ1dCBzaW5jZSB0aGUgZ29hbCBvZlxuICAvLyB0aGlzIG1vZHVsZSBpcyB0byBtYXRjaCBCYXNoJ3MgcnVsZXMsIHdlIGVzY2FwZSBhIGxlYWRpbmcge31cbiAgaWYgKHN0ci5zdWJzdHIoMCwgMikgPT09ICd7fScpIHtcbiAgICBzdHIgPSAnXFxcXHtcXFxcfScgKyBzdHIuc3Vic3RyKDIpO1xuICB9XG5cbiAgcmV0dXJuIGV4cGFuZChlc2NhcGVCcmFjZXMoc3RyKSwgdHJ1ZSkubWFwKHVuZXNjYXBlQnJhY2VzKTtcbn1cblxuZnVuY3Rpb24gaWRlbnRpdHkoZSkge1xuICByZXR1cm4gZTtcbn1cblxuZnVuY3Rpb24gZW1icmFjZShzdHIpIHtcbiAgcmV0dXJuICd7JyArIHN0ciArICd9Jztcbn1cbmZ1bmN0aW9uIGlzUGFkZGVkKGVsKSB7XG4gIHJldHVybiAvXi0/MFxcZC8udGVzdChlbCk7XG59XG5cbmZ1bmN0aW9uIGx0ZShpLCB5KSB7XG4gIHJldHVybiBpIDw9IHk7XG59XG5mdW5jdGlvbiBndGUoaSwgeSkge1xuICByZXR1cm4gaSA+PSB5O1xufVxuXG5mdW5jdGlvbiBleHBhbmQoc3RyLCBpc1RvcCkge1xuICB2YXIgZXhwYW5zaW9ucyA9IFtdO1xuXG4gIHZhciBtID0gYmFsYW5jZWQoJ3snLCAnfScsIHN0cik7XG4gIGlmICghbSB8fCAvXFwkJC8udGVzdChtLnByZSkpIHJldHVybiBbc3RyXTtcblxuICB2YXIgaXNOdW1lcmljU2VxdWVuY2UgPSAvXi0/XFxkK1xcLlxcLi0/XFxkKyg/OlxcLlxcLi0/XFxkKyk/JC8udGVzdChtLmJvZHkpO1xuICB2YXIgaXNBbHBoYVNlcXVlbmNlID0gL15bYS16QS1aXVxcLlxcLlthLXpBLVpdKD86XFwuXFwuLT9cXGQrKT8kLy50ZXN0KG0uYm9keSk7XG4gIHZhciBpc1NlcXVlbmNlID0gaXNOdW1lcmljU2VxdWVuY2UgfHwgaXNBbHBoYVNlcXVlbmNlO1xuICB2YXIgaXNPcHRpb25zID0gbS5ib2R5LmluZGV4T2YoJywnKSA+PSAwO1xuICBpZiAoIWlzU2VxdWVuY2UgJiYgIWlzT3B0aW9ucykge1xuICAgIC8vIHthfSxifVxuICAgIGlmIChtLnBvc3QubWF0Y2goLywuKlxcfS8pKSB7XG4gICAgICBzdHIgPSBtLnByZSArICd7JyArIG0uYm9keSArIGVzY0Nsb3NlICsgbS5wb3N0O1xuICAgICAgcmV0dXJuIGV4cGFuZChzdHIpO1xuICAgIH1cbiAgICByZXR1cm4gW3N0cl07XG4gIH1cblxuICB2YXIgbjtcbiAgaWYgKGlzU2VxdWVuY2UpIHtcbiAgICBuID0gbS5ib2R5LnNwbGl0KC9cXC5cXC4vKTtcbiAgfSBlbHNlIHtcbiAgICBuID0gcGFyc2VDb21tYVBhcnRzKG0uYm9keSk7XG4gICAgaWYgKG4ubGVuZ3RoID09PSAxKSB7XG4gICAgICAvLyB4e3thLGJ9fXkgPT0+IHh7YX15IHh7Yn15XG4gICAgICBuID0gZXhwYW5kKG5bMF0sIGZhbHNlKS5tYXAoZW1icmFjZSk7XG4gICAgICBpZiAobi5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgdmFyIHBvc3QgPSBtLnBvc3QubGVuZ3RoXG4gICAgICAgICAgPyBleHBhbmQobS5wb3N0LCBmYWxzZSlcbiAgICAgICAgICA6IFsnJ107XG4gICAgICAgIHJldHVybiBwb3N0Lm1hcChmdW5jdGlvbihwKSB7XG4gICAgICAgICAgcmV0dXJuIG0ucHJlICsgblswXSArIHA7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGF0IHRoaXMgcG9pbnQsIG4gaXMgdGhlIHBhcnRzLCBhbmQgd2Uga25vdyBpdCdzIG5vdCBhIGNvbW1hIHNldFxuICAvLyB3aXRoIGEgc2luZ2xlIGVudHJ5LlxuXG4gIC8vIG5vIG5lZWQgdG8gZXhwYW5kIHByZSwgc2luY2UgaXQgaXMgZ3VhcmFudGVlZCB0byBiZSBmcmVlIG9mIGJyYWNlLXNldHNcbiAgdmFyIHByZSA9IG0ucHJlO1xuICB2YXIgcG9zdCA9IG0ucG9zdC5sZW5ndGhcbiAgICA/IGV4cGFuZChtLnBvc3QsIGZhbHNlKVxuICAgIDogWycnXTtcblxuICB2YXIgTjtcblxuICBpZiAoaXNTZXF1ZW5jZSkge1xuICAgIHZhciB4ID0gbnVtZXJpYyhuWzBdKTtcbiAgICB2YXIgeSA9IG51bWVyaWMoblsxXSk7XG4gICAgdmFyIHdpZHRoID0gTWF0aC5tYXgoblswXS5sZW5ndGgsIG5bMV0ubGVuZ3RoKVxuICAgIHZhciBpbmNyID0gbi5sZW5ndGggPT0gM1xuICAgICAgPyBNYXRoLmFicyhudW1lcmljKG5bMl0pKVxuICAgICAgOiAxO1xuICAgIHZhciB0ZXN0ID0gbHRlO1xuICAgIHZhciByZXZlcnNlID0geSA8IHg7XG4gICAgaWYgKHJldmVyc2UpIHtcbiAgICAgIGluY3IgKj0gLTE7XG4gICAgICB0ZXN0ID0gZ3RlO1xuICAgIH1cbiAgICB2YXIgcGFkID0gbi5zb21lKGlzUGFkZGVkKTtcblxuICAgIE4gPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSB4OyB0ZXN0KGksIHkpOyBpICs9IGluY3IpIHtcbiAgICAgIHZhciBjO1xuICAgICAgaWYgKGlzQWxwaGFTZXF1ZW5jZSkge1xuICAgICAgICBjID0gU3RyaW5nLmZyb21DaGFyQ29kZShpKTtcbiAgICAgICAgaWYgKGMgPT09ICdcXFxcJylcbiAgICAgICAgICBjID0gJyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjID0gU3RyaW5nKGkpO1xuICAgICAgICBpZiAocGFkKSB7XG4gICAgICAgICAgdmFyIG5lZWQgPSB3aWR0aCAtIGMubGVuZ3RoO1xuICAgICAgICAgIGlmIChuZWVkID4gMCkge1xuICAgICAgICAgICAgdmFyIHogPSBuZXcgQXJyYXkobmVlZCArIDEpLmpvaW4oJzAnKTtcbiAgICAgICAgICAgIGlmIChpIDwgMClcbiAgICAgICAgICAgICAgYyA9ICctJyArIHogKyBjLnNsaWNlKDEpO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICBjID0geiArIGM7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBOLnB1c2goYyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIE4gPSBjb25jYXRNYXAobiwgZnVuY3Rpb24oZWwpIHsgcmV0dXJuIGV4cGFuZChlbCwgZmFsc2UpIH0pO1xuICB9XG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCBOLmxlbmd0aDsgaisrKSB7XG4gICAgZm9yICh2YXIgayA9IDA7IGsgPCBwb3N0Lmxlbmd0aDsgaysrKSB7XG4gICAgICB2YXIgZXhwYW5zaW9uID0gcHJlICsgTltqXSArIHBvc3Rba107XG4gICAgICBpZiAoIWlzVG9wIHx8IGlzU2VxdWVuY2UgfHwgZXhwYW5zaW9uKVxuICAgICAgICBleHBhbnNpb25zLnB1c2goZXhwYW5zaW9uKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZXhwYW5zaW9ucztcbn1cblxuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoeHMsIGZuKSB7XG4gICAgdmFyIHJlcyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHggPSBmbih4c1tpXSwgaSk7XG4gICAgICAgIGlmIChpc0FycmF5KHgpKSByZXMucHVzaC5hcHBseShyZXMsIHgpO1xuICAgICAgICBlbHNlIHJlcy5wdXNoKHgpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xufTtcblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uICh4cykge1xuICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoeHMpID09PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy50YWdQcm9wZXJ0eSA9IGV4cG9ydHMudGFnUGFyYW1ldGVyID0gZXhwb3J0cy5kZWNvcmF0ZSA9IHZvaWQgMDtcbnZhciBFUlJPUl9NU0dTID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbmZ1bmN0aW9uIHRhZ1BhcmFtZXRlcihhbm5vdGF0aW9uVGFyZ2V0LCBwcm9wZXJ0eU5hbWUsIHBhcmFtZXRlckluZGV4LCBtZXRhZGF0YSkge1xuICAgIHZhciBtZXRhZGF0YUtleSA9IE1FVEFEQVRBX0tFWS5UQUdHRUQ7XG4gICAgX3RhZ1BhcmFtZXRlck9yUHJvcGVydHkobWV0YWRhdGFLZXksIGFubm90YXRpb25UYXJnZXQsIHByb3BlcnR5TmFtZSwgbWV0YWRhdGEsIHBhcmFtZXRlckluZGV4KTtcbn1cbmV4cG9ydHMudGFnUGFyYW1ldGVyID0gdGFnUGFyYW1ldGVyO1xuZnVuY3Rpb24gdGFnUHJvcGVydHkoYW5ub3RhdGlvblRhcmdldCwgcHJvcGVydHlOYW1lLCBtZXRhZGF0YSkge1xuICAgIHZhciBtZXRhZGF0YUtleSA9IE1FVEFEQVRBX0tFWS5UQUdHRURfUFJPUDtcbiAgICBfdGFnUGFyYW1ldGVyT3JQcm9wZXJ0eShtZXRhZGF0YUtleSwgYW5ub3RhdGlvblRhcmdldC5jb25zdHJ1Y3RvciwgcHJvcGVydHlOYW1lLCBtZXRhZGF0YSk7XG59XG5leHBvcnRzLnRhZ1Byb3BlcnR5ID0gdGFnUHJvcGVydHk7XG5mdW5jdGlvbiBfdGFnUGFyYW1ldGVyT3JQcm9wZXJ0eShtZXRhZGF0YUtleSwgYW5ub3RhdGlvblRhcmdldCwgcHJvcGVydHlOYW1lLCBtZXRhZGF0YSwgcGFyYW1ldGVySW5kZXgpIHtcbiAgICB2YXIgcGFyYW1zT3JQcm9wZXJ0aWVzTWV0YWRhdGEgPSB7fTtcbiAgICB2YXIgaXNQYXJhbWV0ZXJEZWNvcmF0b3IgPSAodHlwZW9mIHBhcmFtZXRlckluZGV4ID09PSBcIm51bWJlclwiKTtcbiAgICB2YXIga2V5ID0gKHBhcmFtZXRlckluZGV4ICE9PSB1bmRlZmluZWQgJiYgaXNQYXJhbWV0ZXJEZWNvcmF0b3IpID8gcGFyYW1ldGVySW5kZXgudG9TdHJpbmcoKSA6IHByb3BlcnR5TmFtZTtcbiAgICBpZiAoaXNQYXJhbWV0ZXJEZWNvcmF0b3IgJiYgcHJvcGVydHlOYW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuSU5WQUxJRF9ERUNPUkFUT1JfT1BFUkFUSU9OKTtcbiAgICB9XG4gICAgaWYgKFJlZmxlY3QuaGFzT3duTWV0YWRhdGEobWV0YWRhdGFLZXksIGFubm90YXRpb25UYXJnZXQpKSB7XG4gICAgICAgIHBhcmFtc09yUHJvcGVydGllc01ldGFkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShtZXRhZGF0YUtleSwgYW5ub3RhdGlvblRhcmdldCk7XG4gICAgfVxuICAgIHZhciBwYXJhbU9yUHJvcGVydHlNZXRhZGF0YSA9IHBhcmFtc09yUHJvcGVydGllc01ldGFkYXRhW2tleV07XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHBhcmFtT3JQcm9wZXJ0eU1ldGFkYXRhKSkge1xuICAgICAgICBwYXJhbU9yUHJvcGVydHlNZXRhZGF0YSA9IFtdO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBwYXJhbU9yUHJvcGVydHlNZXRhZGF0YV8xID0gcGFyYW1PclByb3BlcnR5TWV0YWRhdGE7IF9pIDwgcGFyYW1PclByb3BlcnR5TWV0YWRhdGFfMS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIHZhciBtID0gcGFyYW1PclByb3BlcnR5TWV0YWRhdGFfMVtfaV07XG4gICAgICAgICAgICBpZiAobS5rZXkgPT09IG1ldGFkYXRhLmtleSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLkRVUExJQ0FURURfTUVUQURBVEEgKyBcIiBcIiArIG0ua2V5LnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHBhcmFtT3JQcm9wZXJ0eU1ldGFkYXRhLnB1c2gobWV0YWRhdGEpO1xuICAgIHBhcmFtc09yUHJvcGVydGllc01ldGFkYXRhW2tleV0gPSBwYXJhbU9yUHJvcGVydHlNZXRhZGF0YTtcbiAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKG1ldGFkYXRhS2V5LCBwYXJhbXNPclByb3BlcnRpZXNNZXRhZGF0YSwgYW5ub3RhdGlvblRhcmdldCk7XG59XG5mdW5jdGlvbiBfZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0KSB7XG4gICAgUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQpO1xufVxuZnVuY3Rpb24gX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsgZGVjb3JhdG9yKHRhcmdldCwga2V5LCBwYXJhbUluZGV4KTsgfTtcbn1cbmZ1bmN0aW9uIGRlY29yYXRlKGRlY29yYXRvciwgdGFyZ2V0LCBwYXJhbWV0ZXJJbmRleCkge1xuICAgIGlmICh0eXBlb2YgcGFyYW1ldGVySW5kZXggPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgX2RlY29yYXRlKFtfcGFyYW0ocGFyYW1ldGVySW5kZXgsIGRlY29yYXRvcildLCB0YXJnZXQpO1xuICAgIH1cbiAgICBlbHNlIGlmICh0eXBlb2YgcGFyYW1ldGVySW5kZXggPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgUmVmbGVjdC5kZWNvcmF0ZShbZGVjb3JhdG9yXSwgdGFyZ2V0LCBwYXJhbWV0ZXJJbmRleCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBfZGVjb3JhdGUoW2RlY29yYXRvcl0sIHRhcmdldCk7XG4gICAgfVxufVxuZXhwb3J0cy5kZWNvcmF0ZSA9IGRlY29yYXRlO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmluamVjdCA9IGV4cG9ydHMuTGF6eVNlcnZpY2VJZGVudGlmZXIgPSB2b2lkIDA7XG52YXIgZXJyb3JfbXNnc18xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbnZhciBtZXRhZGF0YV8xID0gcmVxdWlyZShcIi4uL3BsYW5uaW5nL21ldGFkYXRhXCIpO1xudmFyIGRlY29yYXRvcl91dGlsc18xID0gcmVxdWlyZShcIi4vZGVjb3JhdG9yX3V0aWxzXCIpO1xudmFyIExhenlTZXJ2aWNlSWRlbnRpZmVyID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBMYXp5U2VydmljZUlkZW50aWZlcihjYikge1xuICAgICAgICB0aGlzLl9jYiA9IGNiO1xuICAgIH1cbiAgICBMYXp5U2VydmljZUlkZW50aWZlci5wcm90b3R5cGUudW53cmFwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2IoKTtcbiAgICB9O1xuICAgIHJldHVybiBMYXp5U2VydmljZUlkZW50aWZlcjtcbn0oKSk7XG5leHBvcnRzLkxhenlTZXJ2aWNlSWRlbnRpZmVyID0gTGF6eVNlcnZpY2VJZGVudGlmZXI7XG5mdW5jdGlvbiBpbmplY3Qoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCkge1xuICAgICAgICBpZiAoc2VydmljZUlkZW50aWZpZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yX21zZ3NfMS5VTkRFRklORURfSU5KRUNUX0FOTk9UQVRJT04odGFyZ2V0Lm5hbWUpKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbWV0YWRhdGEgPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShNRVRBREFUQV9LRVkuSU5KRUNUX1RBRywgc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICBpZiAodHlwZW9mIGluZGV4ID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICBkZWNvcmF0b3JfdXRpbHNfMS50YWdQYXJhbWV0ZXIodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4LCBtZXRhZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZWNvcmF0b3JfdXRpbHNfMS50YWdQcm9wZXJ0eSh0YXJnZXQsIHRhcmdldEtleSwgbWV0YWRhdGEpO1xuICAgICAgICB9XG4gICAgfTtcbn1cbmV4cG9ydHMuaW5qZWN0ID0gaW5qZWN0O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmluamVjdGFibGUgPSB2b2lkIDA7XG52YXIgRVJST1JTX01TR1MgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2Vycm9yX21zZ3NcIik7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xuZnVuY3Rpb24gaW5qZWN0YWJsZSgpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCkge1xuICAgICAgICBpZiAoUmVmbGVjdC5oYXNPd25NZXRhZGF0YShNRVRBREFUQV9LRVkuUEFSQU1fVFlQRVMsIHRhcmdldCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUlNfTVNHUy5EVVBMSUNBVEVEX0lOSkVDVEFCTEVfREVDT1JBVE9SKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdHlwZXMgPSBSZWZsZWN0LmdldE1ldGFkYXRhKE1FVEFEQVRBX0tFWS5ERVNJR05fUEFSQU1fVFlQRVMsIHRhcmdldCkgfHwgW107XG4gICAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoTUVUQURBVEFfS0VZLlBBUkFNX1RZUEVTLCB0eXBlcywgdGFyZ2V0KTtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9O1xufVxuZXhwb3J0cy5pbmplY3RhYmxlID0gaW5qZWN0YWJsZTtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5tdWx0aUluamVjdCA9IHZvaWQgMDtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG52YXIgbWV0YWRhdGFfMSA9IHJlcXVpcmUoXCIuLi9wbGFubmluZy9tZXRhZGF0YVwiKTtcbnZhciBkZWNvcmF0b3JfdXRpbHNfMSA9IHJlcXVpcmUoXCIuL2RlY29yYXRvcl91dGlsc1wiKTtcbmZ1bmN0aW9uIG11bHRpSW5qZWN0KHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgpIHtcbiAgICAgICAgdmFyIG1ldGFkYXRhID0gbmV3IG1ldGFkYXRhXzEuTWV0YWRhdGEoTUVUQURBVEFfS0VZLk1VTFRJX0lOSkVDVF9UQUcsIHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgaWYgKHR5cGVvZiBpbmRleCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgZGVjb3JhdG9yX3V0aWxzXzEudGFnUGFyYW1ldGVyKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCwgbWV0YWRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVjb3JhdG9yX3V0aWxzXzEudGFnUHJvcGVydHkodGFyZ2V0LCB0YXJnZXRLZXksIG1ldGFkYXRhKTtcbiAgICAgICAgfVxuICAgIH07XG59XG5leHBvcnRzLm11bHRpSW5qZWN0ID0gbXVsdGlJbmplY3Q7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMubmFtZWQgPSB2b2lkIDA7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFcIik7XG52YXIgZGVjb3JhdG9yX3V0aWxzXzEgPSByZXF1aXJlKFwiLi9kZWNvcmF0b3JfdXRpbHNcIik7XG5mdW5jdGlvbiBuYW1lZChuYW1lKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgpIHtcbiAgICAgICAgdmFyIG1ldGFkYXRhID0gbmV3IG1ldGFkYXRhXzEuTWV0YWRhdGEoTUVUQURBVEFfS0VZLk5BTUVEX1RBRywgbmFtZSk7XG4gICAgICAgIGlmICh0eXBlb2YgaW5kZXggPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIGRlY29yYXRvcl91dGlsc18xLnRhZ1BhcmFtZXRlcih0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgsIG1ldGFkYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlY29yYXRvcl91dGlsc18xLnRhZ1Byb3BlcnR5KHRhcmdldCwgdGFyZ2V0S2V5LCBtZXRhZGF0YSk7XG4gICAgICAgIH1cbiAgICB9O1xufVxuZXhwb3J0cy5uYW1lZCA9IG5hbWVkO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLm9wdGlvbmFsID0gdm9pZCAwO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbnZhciBtZXRhZGF0YV8xID0gcmVxdWlyZShcIi4uL3BsYW5uaW5nL21ldGFkYXRhXCIpO1xudmFyIGRlY29yYXRvcl91dGlsc18xID0gcmVxdWlyZShcIi4vZGVjb3JhdG9yX3V0aWxzXCIpO1xuZnVuY3Rpb24gb3B0aW9uYWwoKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgpIHtcbiAgICAgICAgdmFyIG1ldGFkYXRhID0gbmV3IG1ldGFkYXRhXzEuTWV0YWRhdGEoTUVUQURBVEFfS0VZLk9QVElPTkFMX1RBRywgdHJ1ZSk7XG4gICAgICAgIGlmICh0eXBlb2YgaW5kZXggPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIGRlY29yYXRvcl91dGlsc18xLnRhZ1BhcmFtZXRlcih0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgsIG1ldGFkYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlY29yYXRvcl91dGlsc18xLnRhZ1Byb3BlcnR5KHRhcmdldCwgdGFyZ2V0S2V5LCBtZXRhZGF0YSk7XG4gICAgICAgIH1cbiAgICB9O1xufVxuZXhwb3J0cy5vcHRpb25hbCA9IG9wdGlvbmFsO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnBvc3RDb25zdHJ1Y3QgPSB2b2lkIDA7XG52YXIgRVJST1JTX01TR1MgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2Vycm9yX21zZ3NcIik7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFcIik7XG5mdW5jdGlvbiBwb3N0Q29uc3RydWN0KCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBwcm9wZXJ0eUtleSwgZGVzY3JpcHRvcikge1xuICAgICAgICB2YXIgbWV0YWRhdGEgPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShNRVRBREFUQV9LRVkuUE9TVF9DT05TVFJVQ1QsIHByb3BlcnR5S2V5KTtcbiAgICAgICAgaWYgKFJlZmxlY3QuaGFzT3duTWV0YWRhdGEoTUVUQURBVEFfS0VZLlBPU1RfQ09OU1RSVUNULCB0YXJnZXQuY29uc3RydWN0b3IpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JTX01TR1MuTVVMVElQTEVfUE9TVF9DT05TVFJVQ1RfTUVUSE9EUyk7XG4gICAgICAgIH1cbiAgICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShNRVRBREFUQV9LRVkuUE9TVF9DT05TVFJVQ1QsIG1ldGFkYXRhLCB0YXJnZXQuY29uc3RydWN0b3IpO1xuICAgIH07XG59XG5leHBvcnRzLnBvc3RDb25zdHJ1Y3QgPSBwb3N0Q29uc3RydWN0O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnRhZ2dlZCA9IHZvaWQgMDtcbnZhciBtZXRhZGF0YV8xID0gcmVxdWlyZShcIi4uL3BsYW5uaW5nL21ldGFkYXRhXCIpO1xudmFyIGRlY29yYXRvcl91dGlsc18xID0gcmVxdWlyZShcIi4vZGVjb3JhdG9yX3V0aWxzXCIpO1xuZnVuY3Rpb24gdGFnZ2VkKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgpIHtcbiAgICAgICAgdmFyIG1ldGFkYXRhID0gbmV3IG1ldGFkYXRhXzEuTWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xuICAgICAgICBpZiAodHlwZW9mIGluZGV4ID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICBkZWNvcmF0b3JfdXRpbHNfMS50YWdQYXJhbWV0ZXIodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4LCBtZXRhZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZWNvcmF0b3JfdXRpbHNfMS50YWdQcm9wZXJ0eSh0YXJnZXQsIHRhcmdldEtleSwgbWV0YWRhdGEpO1xuICAgICAgICB9XG4gICAgfTtcbn1cbmV4cG9ydHMudGFnZ2VkID0gdGFnZ2VkO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnRhcmdldE5hbWUgPSB2b2lkIDA7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFcIik7XG52YXIgZGVjb3JhdG9yX3V0aWxzXzEgPSByZXF1aXJlKFwiLi9kZWNvcmF0b3JfdXRpbHNcIik7XG5mdW5jdGlvbiB0YXJnZXROYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCkge1xuICAgICAgICB2YXIgbWV0YWRhdGEgPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShNRVRBREFUQV9LRVkuTkFNRV9UQUcsIG5hbWUpO1xuICAgICAgICBkZWNvcmF0b3JfdXRpbHNfMS50YWdQYXJhbWV0ZXIodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4LCBtZXRhZGF0YSk7XG4gICAgfTtcbn1cbmV4cG9ydHMudGFyZ2V0TmFtZSA9IHRhcmdldE5hbWU7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMudW5tYW5hZ2VkID0gdm9pZCAwO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbnZhciBtZXRhZGF0YV8xID0gcmVxdWlyZShcIi4uL3BsYW5uaW5nL21ldGFkYXRhXCIpO1xudmFyIGRlY29yYXRvcl91dGlsc18xID0gcmVxdWlyZShcIi4vZGVjb3JhdG9yX3V0aWxzXCIpO1xuZnVuY3Rpb24gdW5tYW5hZ2VkKCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4KSB7XG4gICAgICAgIHZhciBtZXRhZGF0YSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKE1FVEFEQVRBX0tFWS5VTk1BTkFHRURfVEFHLCB0cnVlKTtcbiAgICAgICAgZGVjb3JhdG9yX3V0aWxzXzEudGFnUGFyYW1ldGVyKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCwgbWV0YWRhdGEpO1xuICAgIH07XG59XG5leHBvcnRzLnVubWFuYWdlZCA9IHVubWFuYWdlZDtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5CaW5kaW5nID0gdm9pZCAwO1xudmFyIGxpdGVyYWxfdHlwZXNfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbGl0ZXJhbF90eXBlc1wiKTtcbnZhciBpZF8xID0gcmVxdWlyZShcIi4uL3V0aWxzL2lkXCIpO1xudmFyIEJpbmRpbmcgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEJpbmRpbmcoc2VydmljZUlkZW50aWZpZXIsIHNjb3BlKSB7XG4gICAgICAgIHRoaXMuaWQgPSBpZF8xLmlkKCk7XG4gICAgICAgIHRoaXMuYWN0aXZhdGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc2VydmljZUlkZW50aWZpZXIgPSBzZXJ2aWNlSWRlbnRpZmllcjtcbiAgICAgICAgdGhpcy5zY29wZSA9IHNjb3BlO1xuICAgICAgICB0aGlzLnR5cGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLkludmFsaWQ7XG4gICAgICAgIHRoaXMuY29uc3RyYWludCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7IHJldHVybiB0cnVlOyB9O1xuICAgICAgICB0aGlzLmltcGxlbWVudGF0aW9uVHlwZSA9IG51bGw7XG4gICAgICAgIHRoaXMuY2FjaGUgPSBudWxsO1xuICAgICAgICB0aGlzLmZhY3RvcnkgPSBudWxsO1xuICAgICAgICB0aGlzLnByb3ZpZGVyID0gbnVsbDtcbiAgICAgICAgdGhpcy5vbkFjdGl2YXRpb24gPSBudWxsO1xuICAgICAgICB0aGlzLmR5bmFtaWNWYWx1ZSA9IG51bGw7XG4gICAgfVxuICAgIEJpbmRpbmcucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2xvbmUgPSBuZXcgQmluZGluZyh0aGlzLnNlcnZpY2VJZGVudGlmaWVyLCB0aGlzLnNjb3BlKTtcbiAgICAgICAgY2xvbmUuYWN0aXZhdGVkID0gZmFsc2U7XG4gICAgICAgIGNsb25lLmltcGxlbWVudGF0aW9uVHlwZSA9IHRoaXMuaW1wbGVtZW50YXRpb25UeXBlO1xuICAgICAgICBjbG9uZS5keW5hbWljVmFsdWUgPSB0aGlzLmR5bmFtaWNWYWx1ZTtcbiAgICAgICAgY2xvbmUuc2NvcGUgPSB0aGlzLnNjb3BlO1xuICAgICAgICBjbG9uZS50eXBlID0gdGhpcy50eXBlO1xuICAgICAgICBjbG9uZS5mYWN0b3J5ID0gdGhpcy5mYWN0b3J5O1xuICAgICAgICBjbG9uZS5wcm92aWRlciA9IHRoaXMucHJvdmlkZXI7XG4gICAgICAgIGNsb25lLmNvbnN0cmFpbnQgPSB0aGlzLmNvbnN0cmFpbnQ7XG4gICAgICAgIGNsb25lLm9uQWN0aXZhdGlvbiA9IHRoaXMub25BY3RpdmF0aW9uO1xuICAgICAgICBjbG9uZS5jYWNoZSA9IHRoaXMuY2FjaGU7XG4gICAgICAgIHJldHVybiBjbG9uZTtcbiAgICB9O1xuICAgIHJldHVybiBCaW5kaW5nO1xufSgpKTtcbmV4cG9ydHMuQmluZGluZyA9IEJpbmRpbmc7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQmluZGluZ0NvdW50ID0gdm9pZCAwO1xudmFyIEJpbmRpbmdDb3VudCA9IHtcbiAgICBNdWx0aXBsZUJpbmRpbmdzQXZhaWxhYmxlOiAyLFxuICAgIE5vQmluZGluZ3NBdmFpbGFibGU6IDAsXG4gICAgT25seU9uZUJpbmRpbmdBdmFpbGFibGU6IDFcbn07XG5leHBvcnRzLkJpbmRpbmdDb3VudCA9IEJpbmRpbmdDb3VudDtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5TVEFDS19PVkVSRkxPVyA9IGV4cG9ydHMuQ0lSQ1VMQVJfREVQRU5ERU5DWV9JTl9GQUNUT1JZID0gZXhwb3J0cy5QT1NUX0NPTlNUUlVDVF9FUlJPUiA9IGV4cG9ydHMuTVVMVElQTEVfUE9TVF9DT05TVFJVQ1RfTUVUSE9EUyA9IGV4cG9ydHMuQ09OVEFJTkVSX09QVElPTlNfSU5WQUxJRF9TS0lQX0JBU0VfQ0hFQ0sgPSBleHBvcnRzLkNPTlRBSU5FUl9PUFRJT05TX0lOVkFMSURfQVVUT19CSU5EX0lOSkVDVEFCTEUgPSBleHBvcnRzLkNPTlRBSU5FUl9PUFRJT05TX0lOVkFMSURfREVGQVVMVF9TQ09QRSA9IGV4cG9ydHMuQ09OVEFJTkVSX09QVElPTlNfTVVTVF9CRV9BTl9PQkpFQ1QgPSBleHBvcnRzLkFSR1VNRU5UU19MRU5HVEhfTUlTTUFUQ0ggPSBleHBvcnRzLklOVkFMSURfREVDT1JBVE9SX09QRVJBVElPTiA9IGV4cG9ydHMuSU5WQUxJRF9UT19TRUxGX1ZBTFVFID0gZXhwb3J0cy5JTlZBTElEX0ZVTkNUSU9OX0JJTkRJTkcgPSBleHBvcnRzLklOVkFMSURfTUlERExFV0FSRV9SRVRVUk4gPSBleHBvcnRzLk5PX01PUkVfU05BUFNIT1RTX0FWQUlMQUJMRSA9IGV4cG9ydHMuSU5WQUxJRF9CSU5ESU5HX1RZUEUgPSBleHBvcnRzLk5PVF9JTVBMRU1FTlRFRCA9IGV4cG9ydHMuQ0lSQ1VMQVJfREVQRU5ERU5DWSA9IGV4cG9ydHMuVU5ERUZJTkVEX0lOSkVDVF9BTk5PVEFUSU9OID0gZXhwb3J0cy5NSVNTSU5HX0lOSkVDVF9BTk5PVEFUSU9OID0gZXhwb3J0cy5NSVNTSU5HX0lOSkVDVEFCTEVfQU5OT1RBVElPTiA9IGV4cG9ydHMuTk9UX1JFR0lTVEVSRUQgPSBleHBvcnRzLkNBTk5PVF9VTkJJTkQgPSBleHBvcnRzLkFNQklHVU9VU19NQVRDSCA9IGV4cG9ydHMuS0VZX05PVF9GT1VORCA9IGV4cG9ydHMuTlVMTF9BUkdVTUVOVCA9IGV4cG9ydHMuRFVQTElDQVRFRF9NRVRBREFUQSA9IGV4cG9ydHMuRFVQTElDQVRFRF9JTkpFQ1RBQkxFX0RFQ09SQVRPUiA9IHZvaWQgMDtcbmV4cG9ydHMuRFVQTElDQVRFRF9JTkpFQ1RBQkxFX0RFQ09SQVRPUiA9IFwiQ2Fubm90IGFwcGx5IEBpbmplY3RhYmxlIGRlY29yYXRvciBtdWx0aXBsZSB0aW1lcy5cIjtcbmV4cG9ydHMuRFVQTElDQVRFRF9NRVRBREFUQSA9IFwiTWV0YWRhdGEga2V5IHdhcyB1c2VkIG1vcmUgdGhhbiBvbmNlIGluIGEgcGFyYW1ldGVyOlwiO1xuZXhwb3J0cy5OVUxMX0FSR1VNRU5UID0gXCJOVUxMIGFyZ3VtZW50XCI7XG5leHBvcnRzLktFWV9OT1RfRk9VTkQgPSBcIktleSBOb3QgRm91bmRcIjtcbmV4cG9ydHMuQU1CSUdVT1VTX01BVENIID0gXCJBbWJpZ3VvdXMgbWF0Y2ggZm91bmQgZm9yIHNlcnZpY2VJZGVudGlmaWVyOlwiO1xuZXhwb3J0cy5DQU5OT1RfVU5CSU5EID0gXCJDb3VsZCBub3QgdW5iaW5kIHNlcnZpY2VJZGVudGlmaWVyOlwiO1xuZXhwb3J0cy5OT1RfUkVHSVNURVJFRCA9IFwiTm8gbWF0Y2hpbmcgYmluZGluZ3MgZm91bmQgZm9yIHNlcnZpY2VJZGVudGlmaWVyOlwiO1xuZXhwb3J0cy5NSVNTSU5HX0lOSkVDVEFCTEVfQU5OT1RBVElPTiA9IFwiTWlzc2luZyByZXF1aXJlZCBAaW5qZWN0YWJsZSBhbm5vdGF0aW9uIGluOlwiO1xuZXhwb3J0cy5NSVNTSU5HX0lOSkVDVF9BTk5PVEFUSU9OID0gXCJNaXNzaW5nIHJlcXVpcmVkIEBpbmplY3Qgb3IgQG11bHRpSW5qZWN0IGFubm90YXRpb24gaW46XCI7XG5leHBvcnRzLlVOREVGSU5FRF9JTkpFQ1RfQU5OT1RBVElPTiA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgcmV0dXJuIFwiQGluamVjdCBjYWxsZWQgd2l0aCB1bmRlZmluZWQgdGhpcyBjb3VsZCBtZWFuIHRoYXQgdGhlIGNsYXNzIFwiICsgbmFtZSArIFwiIGhhcyBcIiArXG4gICAgICAgIFwiYSBjaXJjdWxhciBkZXBlbmRlbmN5IHByb2JsZW0uIFlvdSBjYW4gdXNlIGEgTGF6eVNlcnZpY2VJZGVudGlmZXIgdG8gIFwiICtcbiAgICAgICAgXCJvdmVyY29tZSB0aGlzIGxpbWl0YXRpb24uXCI7XG59O1xuZXhwb3J0cy5DSVJDVUxBUl9ERVBFTkRFTkNZID0gXCJDaXJjdWxhciBkZXBlbmRlbmN5IGZvdW5kOlwiO1xuZXhwb3J0cy5OT1RfSU1QTEVNRU5URUQgPSBcIlNvcnJ5LCB0aGlzIGZlYXR1cmUgaXMgbm90IGZ1bGx5IGltcGxlbWVudGVkIHlldC5cIjtcbmV4cG9ydHMuSU5WQUxJRF9CSU5ESU5HX1RZUEUgPSBcIkludmFsaWQgYmluZGluZyB0eXBlOlwiO1xuZXhwb3J0cy5OT19NT1JFX1NOQVBTSE9UU19BVkFJTEFCTEUgPSBcIk5vIHNuYXBzaG90IGF2YWlsYWJsZSB0byByZXN0b3JlLlwiO1xuZXhwb3J0cy5JTlZBTElEX01JRERMRVdBUkVfUkVUVVJOID0gXCJJbnZhbGlkIHJldHVybiB0eXBlIGluIG1pZGRsZXdhcmUuIE1pZGRsZXdhcmUgbXVzdCByZXR1cm4hXCI7XG5leHBvcnRzLklOVkFMSURfRlVOQ1RJT05fQklORElORyA9IFwiVmFsdWUgcHJvdmlkZWQgdG8gZnVuY3Rpb24gYmluZGluZyBtdXN0IGJlIGEgZnVuY3Rpb24hXCI7XG5leHBvcnRzLklOVkFMSURfVE9fU0VMRl9WQUxVRSA9IFwiVGhlIHRvU2VsZiBmdW5jdGlvbiBjYW4gb25seSBiZSBhcHBsaWVkIHdoZW4gYSBjb25zdHJ1Y3RvciBpcyBcIiArXG4gICAgXCJ1c2VkIGFzIHNlcnZpY2UgaWRlbnRpZmllclwiO1xuZXhwb3J0cy5JTlZBTElEX0RFQ09SQVRPUl9PUEVSQVRJT04gPSBcIlRoZSBAaW5qZWN0IEBtdWx0aUluamVjdCBAdGFnZ2VkIGFuZCBAbmFtZWQgZGVjb3JhdG9ycyBcIiArXG4gICAgXCJtdXN0IGJlIGFwcGxpZWQgdG8gdGhlIHBhcmFtZXRlcnMgb2YgYSBjbGFzcyBjb25zdHJ1Y3RvciBvciBhIGNsYXNzIHByb3BlcnR5LlwiO1xuZXhwb3J0cy5BUkdVTUVOVFNfTEVOR1RIX01JU01BVENIID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZXMgPSBbXTtcbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICB2YWx1ZXNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICB9XG4gICAgcmV0dXJuIFwiVGhlIG51bWJlciBvZiBjb25zdHJ1Y3RvciBhcmd1bWVudHMgaW4gdGhlIGRlcml2ZWQgY2xhc3MgXCIgK1xuICAgICAgICAodmFsdWVzWzBdICsgXCIgbXVzdCBiZSA+PSB0aGFuIHRoZSBudW1iZXIgb2YgY29uc3RydWN0b3IgYXJndW1lbnRzIG9mIGl0cyBiYXNlIGNsYXNzLlwiKTtcbn07XG5leHBvcnRzLkNPTlRBSU5FUl9PUFRJT05TX01VU1RfQkVfQU5fT0JKRUNUID0gXCJJbnZhbGlkIENvbnRhaW5lciBjb25zdHJ1Y3RvciBhcmd1bWVudC4gQ29udGFpbmVyIG9wdGlvbnMgXCIgK1xuICAgIFwibXVzdCBiZSBhbiBvYmplY3QuXCI7XG5leHBvcnRzLkNPTlRBSU5FUl9PUFRJT05TX0lOVkFMSURfREVGQVVMVF9TQ09QRSA9IFwiSW52YWxpZCBDb250YWluZXIgb3B0aW9uLiBEZWZhdWx0IHNjb3BlIG11c3QgXCIgK1xuICAgIFwiYmUgYSBzdHJpbmcgKCdzaW5nbGV0b24nIG9yICd0cmFuc2llbnQnKS5cIjtcbmV4cG9ydHMuQ09OVEFJTkVSX09QVElPTlNfSU5WQUxJRF9BVVRPX0JJTkRfSU5KRUNUQUJMRSA9IFwiSW52YWxpZCBDb250YWluZXIgb3B0aW9uLiBBdXRvIGJpbmQgaW5qZWN0YWJsZSBtdXN0IFwiICtcbiAgICBcImJlIGEgYm9vbGVhblwiO1xuZXhwb3J0cy5DT05UQUlORVJfT1BUSU9OU19JTlZBTElEX1NLSVBfQkFTRV9DSEVDSyA9IFwiSW52YWxpZCBDb250YWluZXIgb3B0aW9uLiBTa2lwIGJhc2UgY2hlY2sgbXVzdCBcIiArXG4gICAgXCJiZSBhIGJvb2xlYW5cIjtcbmV4cG9ydHMuTVVMVElQTEVfUE9TVF9DT05TVFJVQ1RfTUVUSE9EUyA9IFwiQ2Fubm90IGFwcGx5IEBwb3N0Q29uc3RydWN0IGRlY29yYXRvciBtdWx0aXBsZSB0aW1lcyBpbiB0aGUgc2FtZSBjbGFzc1wiO1xuZXhwb3J0cy5QT1NUX0NPTlNUUlVDVF9FUlJPUiA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdmFsdWVzID0gW107XG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdmFsdWVzW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgfVxuICAgIHJldHVybiBcIkBwb3N0Q29uc3RydWN0IGVycm9yIGluIGNsYXNzIFwiICsgdmFsdWVzWzBdICsgXCI6IFwiICsgdmFsdWVzWzFdO1xufTtcbmV4cG9ydHMuQ0lSQ1VMQVJfREVQRU5ERU5DWV9JTl9GQUNUT1JZID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZXMgPSBbXTtcbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICB2YWx1ZXNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICB9XG4gICAgcmV0dXJuIFwiSXQgbG9va3MgbGlrZSB0aGVyZSBpcyBhIGNpcmN1bGFyIGRlcGVuZGVuY3kgXCIgK1xuICAgICAgICAoXCJpbiBvbmUgb2YgdGhlICdcIiArIHZhbHVlc1swXSArIFwiJyBiaW5kaW5ncy4gUGxlYXNlIGludmVzdGlnYXRlIGJpbmRpbmdzIHdpdGhcIikgK1xuICAgICAgICAoXCJzZXJ2aWNlIGlkZW50aWZpZXIgJ1wiICsgdmFsdWVzWzFdICsgXCInLlwiKTtcbn07XG5leHBvcnRzLlNUQUNLX09WRVJGTE9XID0gXCJNYXhpbXVtIGNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZFwiO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLlRhcmdldFR5cGVFbnVtID0gZXhwb3J0cy5CaW5kaW5nVHlwZUVudW0gPSBleHBvcnRzLkJpbmRpbmdTY29wZUVudW0gPSB2b2lkIDA7XG52YXIgQmluZGluZ1Njb3BlRW51bSA9IHtcbiAgICBSZXF1ZXN0OiBcIlJlcXVlc3RcIixcbiAgICBTaW5nbGV0b246IFwiU2luZ2xldG9uXCIsXG4gICAgVHJhbnNpZW50OiBcIlRyYW5zaWVudFwiXG59O1xuZXhwb3J0cy5CaW5kaW5nU2NvcGVFbnVtID0gQmluZGluZ1Njb3BlRW51bTtcbnZhciBCaW5kaW5nVHlwZUVudW0gPSB7XG4gICAgQ29uc3RhbnRWYWx1ZTogXCJDb25zdGFudFZhbHVlXCIsXG4gICAgQ29uc3RydWN0b3I6IFwiQ29uc3RydWN0b3JcIixcbiAgICBEeW5hbWljVmFsdWU6IFwiRHluYW1pY1ZhbHVlXCIsXG4gICAgRmFjdG9yeTogXCJGYWN0b3J5XCIsXG4gICAgRnVuY3Rpb246IFwiRnVuY3Rpb25cIixcbiAgICBJbnN0YW5jZTogXCJJbnN0YW5jZVwiLFxuICAgIEludmFsaWQ6IFwiSW52YWxpZFwiLFxuICAgIFByb3ZpZGVyOiBcIlByb3ZpZGVyXCJcbn07XG5leHBvcnRzLkJpbmRpbmdUeXBlRW51bSA9IEJpbmRpbmdUeXBlRW51bTtcbnZhciBUYXJnZXRUeXBlRW51bSA9IHtcbiAgICBDbGFzc1Byb3BlcnR5OiBcIkNsYXNzUHJvcGVydHlcIixcbiAgICBDb25zdHJ1Y3RvckFyZ3VtZW50OiBcIkNvbnN0cnVjdG9yQXJndW1lbnRcIixcbiAgICBWYXJpYWJsZTogXCJWYXJpYWJsZVwiXG59O1xuZXhwb3J0cy5UYXJnZXRUeXBlRW51bSA9IFRhcmdldFR5cGVFbnVtO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLlBPU1RfQ09OU1RSVUNUID0gZXhwb3J0cy5ERVNJR05fUEFSQU1fVFlQRVMgPSBleHBvcnRzLlBBUkFNX1RZUEVTID0gZXhwb3J0cy5UQUdHRURfUFJPUCA9IGV4cG9ydHMuVEFHR0VEID0gZXhwb3J0cy5NVUxUSV9JTkpFQ1RfVEFHID0gZXhwb3J0cy5JTkpFQ1RfVEFHID0gZXhwb3J0cy5PUFRJT05BTF9UQUcgPSBleHBvcnRzLlVOTUFOQUdFRF9UQUcgPSBleHBvcnRzLk5BTUVfVEFHID0gZXhwb3J0cy5OQU1FRF9UQUcgPSB2b2lkIDA7XG5leHBvcnRzLk5BTUVEX1RBRyA9IFwibmFtZWRcIjtcbmV4cG9ydHMuTkFNRV9UQUcgPSBcIm5hbWVcIjtcbmV4cG9ydHMuVU5NQU5BR0VEX1RBRyA9IFwidW5tYW5hZ2VkXCI7XG5leHBvcnRzLk9QVElPTkFMX1RBRyA9IFwib3B0aW9uYWxcIjtcbmV4cG9ydHMuSU5KRUNUX1RBRyA9IFwiaW5qZWN0XCI7XG5leHBvcnRzLk1VTFRJX0lOSkVDVF9UQUcgPSBcIm11bHRpX2luamVjdFwiO1xuZXhwb3J0cy5UQUdHRUQgPSBcImludmVyc2lmeTp0YWdnZWRcIjtcbmV4cG9ydHMuVEFHR0VEX1BST1AgPSBcImludmVyc2lmeTp0YWdnZWRfcHJvcHNcIjtcbmV4cG9ydHMuUEFSQU1fVFlQRVMgPSBcImludmVyc2lmeTpwYXJhbXR5cGVzXCI7XG5leHBvcnRzLkRFU0lHTl9QQVJBTV9UWVBFUyA9IFwiZGVzaWduOnBhcmFtdHlwZXNcIjtcbmV4cG9ydHMuUE9TVF9DT05TVFJVQ1QgPSBcInBvc3RfY29uc3RydWN0XCI7XG4iLCJcInVzZSBzdHJpY3RcIjtcbnZhciBfX2F3YWl0ZXIgPSAodGhpcyAmJiB0aGlzLl9fYXdhaXRlcikgfHwgZnVuY3Rpb24gKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XG4gICAgfSk7XG59O1xudmFyIF9fZ2VuZXJhdG9yID0gKHRoaXMgJiYgdGhpcy5fX2dlbmVyYXRvcikgfHwgZnVuY3Rpb24gKHRoaXNBcmcsIGJvZHkpIHtcbiAgICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnO1xuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xuICAgICAgICB3aGlsZSAoXykgdHJ5IHtcbiAgICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcbiAgICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xuICAgIH1cbn07XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkNvbnRhaW5lciA9IHZvaWQgMDtcbnZhciBiaW5kaW5nXzEgPSByZXF1aXJlKFwiLi4vYmluZGluZ3MvYmluZGluZ1wiKTtcbnZhciBFUlJPUl9NU0dTID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xudmFyIGxpdGVyYWxfdHlwZXNfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbGl0ZXJhbF90eXBlc1wiKTtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG52YXIgbWV0YWRhdGFfcmVhZGVyXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFfcmVhZGVyXCIpO1xudmFyIHBsYW5uZXJfMSA9IHJlcXVpcmUoXCIuLi9wbGFubmluZy9wbGFubmVyXCIpO1xudmFyIHJlc29sdmVyXzEgPSByZXF1aXJlKFwiLi4vcmVzb2x1dGlvbi9yZXNvbHZlclwiKTtcbnZhciBiaW5kaW5nX3RvX3N5bnRheF8xID0gcmVxdWlyZShcIi4uL3N5bnRheC9iaW5kaW5nX3RvX3N5bnRheFwiKTtcbnZhciBpZF8xID0gcmVxdWlyZShcIi4uL3V0aWxzL2lkXCIpO1xudmFyIHNlcmlhbGl6YXRpb25fMSA9IHJlcXVpcmUoXCIuLi91dGlscy9zZXJpYWxpemF0aW9uXCIpO1xudmFyIGNvbnRhaW5lcl9zbmFwc2hvdF8xID0gcmVxdWlyZShcIi4vY29udGFpbmVyX3NuYXBzaG90XCIpO1xudmFyIGxvb2t1cF8xID0gcmVxdWlyZShcIi4vbG9va3VwXCIpO1xudmFyIENvbnRhaW5lciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQ29udGFpbmVyKGNvbnRhaW5lck9wdGlvbnMpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSBjb250YWluZXJPcHRpb25zIHx8IHt9O1xuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlwiICsgRVJST1JfTVNHUy5DT05UQUlORVJfT1BUSU9OU19NVVNUX0JFX0FOX09CSkVDVCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdFNjb3BlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG9wdGlvbnMuZGVmYXVsdFNjb3BlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdTY29wZUVudW0uVHJhbnNpZW50O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG9wdGlvbnMuZGVmYXVsdFNjb3BlICE9PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5TaW5nbGV0b24gJiZcbiAgICAgICAgICAgIG9wdGlvbnMuZGVmYXVsdFNjb3BlICE9PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5UcmFuc2llbnQgJiZcbiAgICAgICAgICAgIG9wdGlvbnMuZGVmYXVsdFNjb3BlICE9PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5SZXF1ZXN0KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJcIiArIEVSUk9SX01TR1MuQ09OVEFJTkVSX09QVElPTlNfSU5WQUxJRF9ERUZBVUxUX1NDT1BFKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0aW9ucy5hdXRvQmluZEluamVjdGFibGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgb3B0aW9ucy5hdXRvQmluZEluamVjdGFibGUgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb3B0aW9ucy5hdXRvQmluZEluamVjdGFibGUgIT09IFwiYm9vbGVhblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJcIiArIEVSUk9SX01TR1MuQ09OVEFJTkVSX09QVElPTlNfSU5WQUxJRF9BVVRPX0JJTkRfSU5KRUNUQUJMRSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuc2tpcEJhc2VDbGFzc0NoZWNrcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBvcHRpb25zLnNraXBCYXNlQ2xhc3NDaGVja3MgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb3B0aW9ucy5za2lwQmFzZUNsYXNzQ2hlY2tzICE9PSBcImJvb2xlYW5cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiXCIgKyBFUlJPUl9NU0dTLkNPTlRBSU5FUl9PUFRJT05TX0lOVkFMSURfU0tJUF9CQVNFX0NIRUNLKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICAgICAgICBhdXRvQmluZEluamVjdGFibGU6IG9wdGlvbnMuYXV0b0JpbmRJbmplY3RhYmxlLFxuICAgICAgICAgICAgZGVmYXVsdFNjb3BlOiBvcHRpb25zLmRlZmF1bHRTY29wZSxcbiAgICAgICAgICAgIHNraXBCYXNlQ2xhc3NDaGVja3M6IG9wdGlvbnMuc2tpcEJhc2VDbGFzc0NoZWNrc1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmlkID0gaWRfMS5pZCgpO1xuICAgICAgICB0aGlzLl9iaW5kaW5nRGljdGlvbmFyeSA9IG5ldyBsb29rdXBfMS5Mb29rdXAoKTtcbiAgICAgICAgdGhpcy5fc25hcHNob3RzID0gW107XG4gICAgICAgIHRoaXMuX21pZGRsZXdhcmUgPSBudWxsO1xuICAgICAgICB0aGlzLnBhcmVudCA9IG51bGw7XG4gICAgICAgIHRoaXMuX21ldGFkYXRhUmVhZGVyID0gbmV3IG1ldGFkYXRhX3JlYWRlcl8xLk1ldGFkYXRhUmVhZGVyKCk7XG4gICAgfVxuICAgIENvbnRhaW5lci5tZXJnZSA9IGZ1bmN0aW9uIChjb250YWluZXIxLCBjb250YWluZXIyKSB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSBuZXcgQ29udGFpbmVyKCk7XG4gICAgICAgIHZhciBiaW5kaW5nRGljdGlvbmFyeSA9IHBsYW5uZXJfMS5nZXRCaW5kaW5nRGljdGlvbmFyeShjb250YWluZXIpO1xuICAgICAgICB2YXIgYmluZGluZ0RpY3Rpb25hcnkxID0gcGxhbm5lcl8xLmdldEJpbmRpbmdEaWN0aW9uYXJ5KGNvbnRhaW5lcjEpO1xuICAgICAgICB2YXIgYmluZGluZ0RpY3Rpb25hcnkyID0gcGxhbm5lcl8xLmdldEJpbmRpbmdEaWN0aW9uYXJ5KGNvbnRhaW5lcjIpO1xuICAgICAgICBmdW5jdGlvbiBjb3B5RGljdGlvbmFyeShvcmlnaW4sIGRlc3RpbmF0aW9uKSB7XG4gICAgICAgICAgICBvcmlnaW4udHJhdmVyc2UoZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uIChiaW5kaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uLmFkZChiaW5kaW5nLnNlcnZpY2VJZGVudGlmaWVyLCBiaW5kaW5nLmNsb25lKCkpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY29weURpY3Rpb25hcnkoYmluZGluZ0RpY3Rpb25hcnkxLCBiaW5kaW5nRGljdGlvbmFyeSk7XG4gICAgICAgIGNvcHlEaWN0aW9uYXJ5KGJpbmRpbmdEaWN0aW9uYXJ5MiwgYmluZGluZ0RpY3Rpb25hcnkpO1xuICAgICAgICByZXR1cm4gY29udGFpbmVyO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbW9kdWxlcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgbW9kdWxlc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICB9XG4gICAgICAgIHZhciBnZXRIZWxwZXJzID0gdGhpcy5fZ2V0Q29udGFpbmVyTW9kdWxlSGVscGVyc0ZhY3RvcnkoKTtcbiAgICAgICAgZm9yICh2YXIgX2EgPSAwLCBtb2R1bGVzXzEgPSBtb2R1bGVzOyBfYSA8IG1vZHVsZXNfMS5sZW5ndGg7IF9hKyspIHtcbiAgICAgICAgICAgIHZhciBjdXJyZW50TW9kdWxlID0gbW9kdWxlc18xW19hXTtcbiAgICAgICAgICAgIHZhciBjb250YWluZXJNb2R1bGVIZWxwZXJzID0gZ2V0SGVscGVycyhjdXJyZW50TW9kdWxlLmlkKTtcbiAgICAgICAgICAgIGN1cnJlbnRNb2R1bGUucmVnaXN0cnkoY29udGFpbmVyTW9kdWxlSGVscGVycy5iaW5kRnVuY3Rpb24sIGNvbnRhaW5lck1vZHVsZUhlbHBlcnMudW5iaW5kRnVuY3Rpb24sIGNvbnRhaW5lck1vZHVsZUhlbHBlcnMuaXNib3VuZEZ1bmN0aW9uLCBjb250YWluZXJNb2R1bGVIZWxwZXJzLnJlYmluZEZ1bmN0aW9uKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5sb2FkQXN5bmMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtb2R1bGVzID0gW107XG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICBtb2R1bGVzW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGdldEhlbHBlcnMsIF9hLCBtb2R1bGVzXzIsIGN1cnJlbnRNb2R1bGUsIGNvbnRhaW5lck1vZHVsZUhlbHBlcnM7XG4gICAgICAgICAgICByZXR1cm4gX19nZW5lcmF0b3IodGhpcywgZnVuY3Rpb24gKF9iKSB7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChfYi5sYWJlbCkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRIZWxwZXJzID0gdGhpcy5fZ2V0Q29udGFpbmVyTW9kdWxlSGVscGVyc0ZhY3RvcnkoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hID0gMCwgbW9kdWxlc18yID0gbW9kdWxlcztcbiAgICAgICAgICAgICAgICAgICAgICAgIF9iLmxhYmVsID0gMTtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoX2EgPCBtb2R1bGVzXzIubGVuZ3RoKSkgcmV0dXJuIFszLCA0XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNb2R1bGUgPSBtb2R1bGVzXzJbX2FdO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyTW9kdWxlSGVscGVycyA9IGdldEhlbHBlcnMoY3VycmVudE1vZHVsZS5pZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQsIGN1cnJlbnRNb2R1bGUucmVnaXN0cnkoY29udGFpbmVyTW9kdWxlSGVscGVycy5iaW5kRnVuY3Rpb24sIGNvbnRhaW5lck1vZHVsZUhlbHBlcnMudW5iaW5kRnVuY3Rpb24sIGNvbnRhaW5lck1vZHVsZUhlbHBlcnMuaXNib3VuZEZ1bmN0aW9uLCBjb250YWluZXJNb2R1bGVIZWxwZXJzLnJlYmluZEZ1bmN0aW9uKV07XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICAgICAgICAgIF9iLnNlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIF9iLmxhYmVsID0gMztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgICAgICAgICAgX2ErKztcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMywgMV07XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNDogcmV0dXJuIFsyXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLnVubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIG1vZHVsZXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIG1vZHVsZXNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgY29uZGl0aW9uRmFjdG9yeSA9IGZ1bmN0aW9uIChleHBlY3RlZCkgeyByZXR1cm4gZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgIHJldHVybiBpdGVtLm1vZHVsZUlkID09PSBleHBlY3RlZDtcbiAgICAgICAgfTsgfTtcbiAgICAgICAgbW9kdWxlcy5mb3JFYWNoKGZ1bmN0aW9uIChtb2R1bGUpIHtcbiAgICAgICAgICAgIHZhciBjb25kaXRpb24gPSBjb25kaXRpb25GYWN0b3J5KG1vZHVsZS5pZCk7XG4gICAgICAgICAgICBfdGhpcy5fYmluZGluZ0RpY3Rpb25hcnkucmVtb3ZlQnlDb25kaXRpb24oY29uZGl0aW9uKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgdmFyIHNjb3BlID0gdGhpcy5vcHRpb25zLmRlZmF1bHRTY29wZSB8fCBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5UcmFuc2llbnQ7XG4gICAgICAgIHZhciBiaW5kaW5nID0gbmV3IGJpbmRpbmdfMS5CaW5kaW5nKHNlcnZpY2VJZGVudGlmaWVyLCBzY29wZSk7XG4gICAgICAgIHRoaXMuX2JpbmRpbmdEaWN0aW9uYXJ5LmFkZChzZXJ2aWNlSWRlbnRpZmllciwgYmluZGluZyk7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ190b19zeW50YXhfMS5CaW5kaW5nVG9TeW50YXgoYmluZGluZyk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLnJlYmluZCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICB0aGlzLnVuYmluZChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIHJldHVybiB0aGlzLmJpbmQoc2VydmljZUlkZW50aWZpZXIpO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS51bmJpbmQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuX2JpbmRpbmdEaWN0aW9uYXJ5LnJlbW92ZShzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLkNBTk5PVF9VTkJJTkQgKyBcIiBcIiArIHNlcmlhbGl6YXRpb25fMS5nZXRTZXJ2aWNlSWRlbnRpZmllckFzU3RyaW5nKHNlcnZpY2VJZGVudGlmaWVyKSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUudW5iaW5kQWxsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nRGljdGlvbmFyeSA9IG5ldyBsb29rdXBfMS5Mb29rdXAoKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuaXNCb3VuZCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICB2YXIgYm91bmQgPSB0aGlzLl9iaW5kaW5nRGljdGlvbmFyeS5oYXNLZXkoc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICBpZiAoIWJvdW5kICYmIHRoaXMucGFyZW50KSB7XG4gICAgICAgICAgICBib3VuZCA9IHRoaXMucGFyZW50LmlzQm91bmQoc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBib3VuZDtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuaXNCb3VuZE5hbWVkID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyLCBuYW1lZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc0JvdW5kVGFnZ2VkKHNlcnZpY2VJZGVudGlmaWVyLCBNRVRBREFUQV9LRVkuTkFNRURfVEFHLCBuYW1lZCk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmlzQm91bmRUYWdnZWQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgdmFyIGJvdW5kID0gZmFsc2U7XG4gICAgICAgIGlmICh0aGlzLl9iaW5kaW5nRGljdGlvbmFyeS5oYXNLZXkoc2VydmljZUlkZW50aWZpZXIpKSB7XG4gICAgICAgICAgICB2YXIgYmluZGluZ3MgPSB0aGlzLl9iaW5kaW5nRGljdGlvbmFyeS5nZXQoc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICAgICAgdmFyIHJlcXVlc3RfMSA9IHBsYW5uZXJfMS5jcmVhdGVNb2NrUmVxdWVzdCh0aGlzLCBzZXJ2aWNlSWRlbnRpZmllciwga2V5LCB2YWx1ZSk7XG4gICAgICAgICAgICBib3VuZCA9IGJpbmRpbmdzLnNvbWUoZnVuY3Rpb24gKGIpIHsgcmV0dXJuIGIuY29uc3RyYWludChyZXF1ZXN0XzEpOyB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWJvdW5kICYmIHRoaXMucGFyZW50KSB7XG4gICAgICAgICAgICBib3VuZCA9IHRoaXMucGFyZW50LmlzQm91bmRUYWdnZWQoc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBib3VuZDtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuc25hcHNob3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX3NuYXBzaG90cy5wdXNoKGNvbnRhaW5lcl9zbmFwc2hvdF8xLkNvbnRhaW5lclNuYXBzaG90Lm9mKHRoaXMuX2JpbmRpbmdEaWN0aW9uYXJ5LmNsb25lKCksIHRoaXMuX21pZGRsZXdhcmUpKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUucmVzdG9yZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHNuYXBzaG90ID0gdGhpcy5fc25hcHNob3RzLnBvcCgpO1xuICAgICAgICBpZiAoc25hcHNob3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuTk9fTU9SRV9TTkFQU0hPVFNfQVZBSUxBQkxFKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9iaW5kaW5nRGljdGlvbmFyeSA9IHNuYXBzaG90LmJpbmRpbmdzO1xuICAgICAgICB0aGlzLl9taWRkbGV3YXJlID0gc25hcHNob3QubWlkZGxld2FyZTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuY3JlYXRlQ2hpbGQgPSBmdW5jdGlvbiAoY29udGFpbmVyT3B0aW9ucykge1xuICAgICAgICB2YXIgY2hpbGQgPSBuZXcgQ29udGFpbmVyKGNvbnRhaW5lck9wdGlvbnMgfHwgdGhpcy5vcHRpb25zKTtcbiAgICAgICAgY2hpbGQucGFyZW50ID0gdGhpcztcbiAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5hcHBseU1pZGRsZXdhcmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtaWRkbGV3YXJlcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgbWlkZGxld2FyZXNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaW5pdGlhbCA9ICh0aGlzLl9taWRkbGV3YXJlKSA/IHRoaXMuX21pZGRsZXdhcmUgOiB0aGlzLl9wbGFuQW5kUmVzb2x2ZSgpO1xuICAgICAgICB0aGlzLl9taWRkbGV3YXJlID0gbWlkZGxld2FyZXMucmVkdWNlKGZ1bmN0aW9uIChwcmV2LCBjdXJyKSB7IHJldHVybiBjdXJyKHByZXYpOyB9LCBpbml0aWFsKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuYXBwbHlDdXN0b21NZXRhZGF0YVJlYWRlciA9IGZ1bmN0aW9uIChtZXRhZGF0YVJlYWRlcikge1xuICAgICAgICB0aGlzLl9tZXRhZGF0YVJlYWRlciA9IG1ldGFkYXRhUmVhZGVyO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldChmYWxzZSwgZmFsc2UsIGxpdGVyYWxfdHlwZXNfMS5UYXJnZXRUeXBlRW51bS5WYXJpYWJsZSwgc2VydmljZUlkZW50aWZpZXIpO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5nZXRUYWdnZWQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldChmYWxzZSwgZmFsc2UsIGxpdGVyYWxfdHlwZXNfMS5UYXJnZXRUeXBlRW51bS5WYXJpYWJsZSwgc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5nZXROYW1lZCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllciwgbmFtZWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VGFnZ2VkKHNlcnZpY2VJZGVudGlmaWVyLCBNRVRBREFUQV9LRVkuTkFNRURfVEFHLCBuYW1lZCk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmdldEFsbCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0KHRydWUsIHRydWUsIGxpdGVyYWxfdHlwZXNfMS5UYXJnZXRUeXBlRW51bS5WYXJpYWJsZSwgc2VydmljZUlkZW50aWZpZXIpO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5nZXRBbGxUYWdnZWQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldChmYWxzZSwgdHJ1ZSwgbGl0ZXJhbF90eXBlc18xLlRhcmdldFR5cGVFbnVtLlZhcmlhYmxlLCBzZXJ2aWNlSWRlbnRpZmllciwga2V5LCB2YWx1ZSk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmdldEFsbE5hbWVkID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyLCBuYW1lZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRBbGxUYWdnZWQoc2VydmljZUlkZW50aWZpZXIsIE1FVEFEQVRBX0tFWS5OQU1FRF9UQUcsIG5hbWVkKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUucmVzb2x2ZSA9IGZ1bmN0aW9uIChjb25zdHJ1Y3RvckZ1bmN0aW9uKSB7XG4gICAgICAgIHZhciB0ZW1wQ29udGFpbmVyID0gdGhpcy5jcmVhdGVDaGlsZCgpO1xuICAgICAgICB0ZW1wQ29udGFpbmVyLmJpbmQoY29uc3RydWN0b3JGdW5jdGlvbikudG9TZWxmKCk7XG4gICAgICAgIHJldHVybiB0ZW1wQ29udGFpbmVyLmdldChjb25zdHJ1Y3RvckZ1bmN0aW9uKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuX2dldENvbnRhaW5lck1vZHVsZUhlbHBlcnNGYWN0b3J5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgc2V0TW9kdWxlSWQgPSBmdW5jdGlvbiAoYmluZGluZ1RvU3ludGF4LCBtb2R1bGVJZCkge1xuICAgICAgICAgICAgYmluZGluZ1RvU3ludGF4Ll9iaW5kaW5nLm1vZHVsZUlkID0gbW9kdWxlSWQ7XG4gICAgICAgIH07XG4gICAgICAgIHZhciBnZXRCaW5kRnVuY3Rpb24gPSBmdW5jdGlvbiAobW9kdWxlSWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2JpbmQgPSBfdGhpcy5iaW5kLmJpbmQoX3RoaXMpO1xuICAgICAgICAgICAgICAgIHZhciBiaW5kaW5nVG9TeW50YXggPSBfYmluZChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgICAgICAgICAgc2V0TW9kdWxlSWQoYmluZGluZ1RvU3ludGF4LCBtb2R1bGVJZCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJpbmRpbmdUb1N5bnRheDtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIHZhciBnZXRVbmJpbmRGdW5jdGlvbiA9IGZ1bmN0aW9uIChtb2R1bGVJZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICAgICAgICAgIHZhciBfdW5iaW5kID0gX3RoaXMudW5iaW5kLmJpbmQoX3RoaXMpO1xuICAgICAgICAgICAgICAgIF91bmJpbmQoc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIGdldElzYm91bmRGdW5jdGlvbiA9IGZ1bmN0aW9uIChtb2R1bGVJZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICAgICAgICAgIHZhciBfaXNCb3VuZCA9IF90aGlzLmlzQm91bmQuYmluZChfdGhpcyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9pc0JvdW5kKHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIHZhciBnZXRSZWJpbmRGdW5jdGlvbiA9IGZ1bmN0aW9uIChtb2R1bGVJZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICAgICAgICAgIHZhciBfcmViaW5kID0gX3RoaXMucmViaW5kLmJpbmQoX3RoaXMpO1xuICAgICAgICAgICAgICAgIHZhciBiaW5kaW5nVG9TeW50YXggPSBfcmViaW5kKHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgICAgICAgICBzZXRNb2R1bGVJZChiaW5kaW5nVG9TeW50YXgsIG1vZHVsZUlkKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYmluZGluZ1RvU3ludGF4O1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChtSWQpIHsgcmV0dXJuICh7XG4gICAgICAgICAgICBiaW5kRnVuY3Rpb246IGdldEJpbmRGdW5jdGlvbihtSWQpLFxuICAgICAgICAgICAgaXNib3VuZEZ1bmN0aW9uOiBnZXRJc2JvdW5kRnVuY3Rpb24obUlkKSxcbiAgICAgICAgICAgIHJlYmluZEZ1bmN0aW9uOiBnZXRSZWJpbmRGdW5jdGlvbihtSWQpLFxuICAgICAgICAgICAgdW5iaW5kRnVuY3Rpb246IGdldFVuYmluZEZ1bmN0aW9uKG1JZClcbiAgICAgICAgfSk7IH07XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLl9nZXQgPSBmdW5jdGlvbiAoYXZvaWRDb25zdHJhaW50cywgaXNNdWx0aUluamVjdCwgdGFyZ2V0VHlwZSwgc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IG51bGw7XG4gICAgICAgIHZhciBkZWZhdWx0QXJncyA9IHtcbiAgICAgICAgICAgIGF2b2lkQ29uc3RyYWludHM6IGF2b2lkQ29uc3RyYWludHMsXG4gICAgICAgICAgICBjb250ZXh0SW50ZXJjZXB0b3I6IGZ1bmN0aW9uIChjb250ZXh0KSB7IHJldHVybiBjb250ZXh0OyB9LFxuICAgICAgICAgICAgaXNNdWx0aUluamVjdDogaXNNdWx0aUluamVjdCxcbiAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgc2VydmljZUlkZW50aWZpZXI6IHNlcnZpY2VJZGVudGlmaWVyLFxuICAgICAgICAgICAgdGFyZ2V0VHlwZTogdGFyZ2V0VHlwZSxcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5fbWlkZGxld2FyZSkge1xuICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy5fbWlkZGxld2FyZShkZWZhdWx0QXJncyk7XG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSB1bmRlZmluZWQgfHwgcmVzdWx0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuSU5WQUxJRF9NSURETEVXQVJFX1JFVFVSTik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXN1bHQgPSB0aGlzLl9wbGFuQW5kUmVzb2x2ZSgpKGRlZmF1bHRBcmdzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5fcGxhbkFuZFJlc29sdmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoYXJncykge1xuICAgICAgICAgICAgdmFyIGNvbnRleHQgPSBwbGFubmVyXzEucGxhbihfdGhpcy5fbWV0YWRhdGFSZWFkZXIsIF90aGlzLCBhcmdzLmlzTXVsdGlJbmplY3QsIGFyZ3MudGFyZ2V0VHlwZSwgYXJncy5zZXJ2aWNlSWRlbnRpZmllciwgYXJncy5rZXksIGFyZ3MudmFsdWUsIGFyZ3MuYXZvaWRDb25zdHJhaW50cyk7XG4gICAgICAgICAgICBjb250ZXh0ID0gYXJncy5jb250ZXh0SW50ZXJjZXB0b3IoY29udGV4dCk7XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gcmVzb2x2ZXJfMS5yZXNvbHZlKGNvbnRleHQpO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHJldHVybiBDb250YWluZXI7XG59KCkpO1xuZXhwb3J0cy5Db250YWluZXIgPSBDb250YWluZXI7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQXN5bmNDb250YWluZXJNb2R1bGUgPSBleHBvcnRzLkNvbnRhaW5lck1vZHVsZSA9IHZvaWQgMDtcbnZhciBpZF8xID0gcmVxdWlyZShcIi4uL3V0aWxzL2lkXCIpO1xudmFyIENvbnRhaW5lck1vZHVsZSA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQ29udGFpbmVyTW9kdWxlKHJlZ2lzdHJ5KSB7XG4gICAgICAgIHRoaXMuaWQgPSBpZF8xLmlkKCk7XG4gICAgICAgIHRoaXMucmVnaXN0cnkgPSByZWdpc3RyeTtcbiAgICB9XG4gICAgcmV0dXJuIENvbnRhaW5lck1vZHVsZTtcbn0oKSk7XG5leHBvcnRzLkNvbnRhaW5lck1vZHVsZSA9IENvbnRhaW5lck1vZHVsZTtcbnZhciBBc3luY0NvbnRhaW5lck1vZHVsZSA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQXN5bmNDb250YWluZXJNb2R1bGUocmVnaXN0cnkpIHtcbiAgICAgICAgdGhpcy5pZCA9IGlkXzEuaWQoKTtcbiAgICAgICAgdGhpcy5yZWdpc3RyeSA9IHJlZ2lzdHJ5O1xuICAgIH1cbiAgICByZXR1cm4gQXN5bmNDb250YWluZXJNb2R1bGU7XG59KCkpO1xuZXhwb3J0cy5Bc3luY0NvbnRhaW5lck1vZHVsZSA9IEFzeW5jQ29udGFpbmVyTW9kdWxlO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkNvbnRhaW5lclNuYXBzaG90ID0gdm9pZCAwO1xudmFyIENvbnRhaW5lclNuYXBzaG90ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBDb250YWluZXJTbmFwc2hvdCgpIHtcbiAgICB9XG4gICAgQ29udGFpbmVyU25hcHNob3Qub2YgPSBmdW5jdGlvbiAoYmluZGluZ3MsIG1pZGRsZXdhcmUpIHtcbiAgICAgICAgdmFyIHNuYXBzaG90ID0gbmV3IENvbnRhaW5lclNuYXBzaG90KCk7XG4gICAgICAgIHNuYXBzaG90LmJpbmRpbmdzID0gYmluZGluZ3M7XG4gICAgICAgIHNuYXBzaG90Lm1pZGRsZXdhcmUgPSBtaWRkbGV3YXJlO1xuICAgICAgICByZXR1cm4gc25hcHNob3Q7XG4gICAgfTtcbiAgICByZXR1cm4gQ29udGFpbmVyU25hcHNob3Q7XG59KCkpO1xuZXhwb3J0cy5Db250YWluZXJTbmFwc2hvdCA9IENvbnRhaW5lclNuYXBzaG90O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkxvb2t1cCA9IHZvaWQgMDtcbnZhciBFUlJPUl9NU0dTID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xudmFyIExvb2t1cCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTG9va3VwKCkge1xuICAgICAgICB0aGlzLl9tYXAgPSBuZXcgTWFwKCk7XG4gICAgfVxuICAgIExvb2t1cC5wcm90b3R5cGUuZ2V0TWFwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwO1xuICAgIH07XG4gICAgTG9va3VwLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIsIHZhbHVlKSB7XG4gICAgICAgIGlmIChzZXJ2aWNlSWRlbnRpZmllciA9PT0gbnVsbCB8fCBzZXJ2aWNlSWRlbnRpZmllciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5OVUxMX0FSR1VNRU5UKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuTlVMTF9BUkdVTUVOVCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy5fbWFwLmdldChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIGlmIChlbnRyeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBlbnRyeS5wdXNoKHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuX21hcC5zZXQoc2VydmljZUlkZW50aWZpZXIsIGVudHJ5KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX21hcC5zZXQoc2VydmljZUlkZW50aWZpZXIsIFt2YWx1ZV0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBMb29rdXAucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICBpZiAoc2VydmljZUlkZW50aWZpZXIgPT09IG51bGwgfHwgc2VydmljZUlkZW50aWZpZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuTlVMTF9BUkdVTUVOVCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy5fbWFwLmdldChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIGlmIChlbnRyeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gZW50cnk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5LRVlfTk9UX0ZPVU5EKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgTG9va3VwLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgaWYgKHNlcnZpY2VJZGVudGlmaWVyID09PSBudWxsIHx8IHNlcnZpY2VJZGVudGlmaWVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLk5VTExfQVJHVU1FTlQpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5fbWFwLmRlbGV0ZShzZXJ2aWNlSWRlbnRpZmllcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLktFWV9OT1RfRk9VTkQpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBMb29rdXAucHJvdG90eXBlLnJlbW92ZUJ5Q29uZGl0aW9uID0gZnVuY3Rpb24gKGNvbmRpdGlvbikge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLl9tYXAuZm9yRWFjaChmdW5jdGlvbiAoZW50cmllcywga2V5KSB7XG4gICAgICAgICAgICB2YXIgdXBkYXRlZEVudHJpZXMgPSBlbnRyaWVzLmZpbHRlcihmdW5jdGlvbiAoZW50cnkpIHsgcmV0dXJuICFjb25kaXRpb24oZW50cnkpOyB9KTtcbiAgICAgICAgICAgIGlmICh1cGRhdGVkRW50cmllcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuX21hcC5zZXQoa2V5LCB1cGRhdGVkRW50cmllcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5fbWFwLmRlbGV0ZShrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIExvb2t1cC5wcm90b3R5cGUuaGFzS2V5ID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgICAgIGlmIChzZXJ2aWNlSWRlbnRpZmllciA9PT0gbnVsbCB8fCBzZXJ2aWNlSWRlbnRpZmllciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5OVUxMX0FSR1VNRU5UKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLmhhcyhzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgfTtcbiAgICBMb29rdXAucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29weSA9IG5ldyBMb29rdXAoKTtcbiAgICAgICAgdGhpcy5fbWFwLmZvckVhY2goZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcbiAgICAgICAgICAgIHZhbHVlLmZvckVhY2goZnVuY3Rpb24gKGIpIHsgcmV0dXJuIGNvcHkuYWRkKGtleSwgYi5jbG9uZSgpKTsgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY29weTtcbiAgICB9O1xuICAgIExvb2t1cC5wcm90b3R5cGUudHJhdmVyc2UgPSBmdW5jdGlvbiAoZnVuYykge1xuICAgICAgICB0aGlzLl9tYXAuZm9yRWFjaChmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgICAgICAgZnVuYyhrZXksIHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gTG9va3VwO1xufSgpKTtcbmV4cG9ydHMuTG9va3VwID0gTG9va3VwO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLk1FVEFEQVRBX0tFWSA9IHZvaWQgMDtcbnZhciBrZXlzID0gcmVxdWlyZShcIi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG5leHBvcnRzLk1FVEFEQVRBX0tFWSA9IGtleXM7XG52YXIgY29udGFpbmVyXzEgPSByZXF1aXJlKFwiLi9jb250YWluZXIvY29udGFpbmVyXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQ29udGFpbmVyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb250YWluZXJfMS5Db250YWluZXI7IH0gfSk7XG52YXIgbGl0ZXJhbF90eXBlc18xID0gcmVxdWlyZShcIi4vY29uc3RhbnRzL2xpdGVyYWxfdHlwZXNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJCaW5kaW5nU2NvcGVFbnVtXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkJpbmRpbmdUeXBlRW51bVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlRhcmdldFR5cGVFbnVtXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBsaXRlcmFsX3R5cGVzXzEuVGFyZ2V0VHlwZUVudW07IH0gfSk7XG52YXIgY29udGFpbmVyX21vZHVsZV8xID0gcmVxdWlyZShcIi4vY29udGFpbmVyL2NvbnRhaW5lcl9tb2R1bGVcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJBc3luY0NvbnRhaW5lck1vZHVsZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29udGFpbmVyX21vZHVsZV8xLkFzeW5jQ29udGFpbmVyTW9kdWxlOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQ29udGFpbmVyTW9kdWxlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb250YWluZXJfbW9kdWxlXzEuQ29udGFpbmVyTW9kdWxlOyB9IH0pO1xudmFyIGluamVjdGFibGVfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vaW5qZWN0YWJsZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImluamVjdGFibGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGluamVjdGFibGVfMS5pbmplY3RhYmxlOyB9IH0pO1xudmFyIHRhZ2dlZF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi90YWdnZWRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ0YWdnZWRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRhZ2dlZF8xLnRhZ2dlZDsgfSB9KTtcbnZhciBuYW1lZF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi9uYW1lZFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIm5hbWVkXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBuYW1lZF8xLm5hbWVkOyB9IH0pO1xudmFyIGluamVjdF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi9pbmplY3RcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJpbmplY3RcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGluamVjdF8xLmluamVjdDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkxhenlTZXJ2aWNlSWRlbnRpZmVyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBpbmplY3RfMS5MYXp5U2VydmljZUlkZW50aWZlcjsgfSB9KTtcbnZhciBvcHRpb25hbF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi9vcHRpb25hbFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIm9wdGlvbmFsXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBvcHRpb25hbF8xLm9wdGlvbmFsOyB9IH0pO1xudmFyIHVubWFuYWdlZF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi91bm1hbmFnZWRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ1bm1hbmFnZWRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHVubWFuYWdlZF8xLnVubWFuYWdlZDsgfSB9KTtcbnZhciBtdWx0aV9pbmplY3RfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vbXVsdGlfaW5qZWN0XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwibXVsdGlJbmplY3RcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG11bHRpX2luamVjdF8xLm11bHRpSW5qZWN0OyB9IH0pO1xudmFyIHRhcmdldF9uYW1lXzEgPSByZXF1aXJlKFwiLi9hbm5vdGF0aW9uL3RhcmdldF9uYW1lXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidGFyZ2V0TmFtZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGFyZ2V0X25hbWVfMS50YXJnZXROYW1lOyB9IH0pO1xudmFyIHBvc3RfY29uc3RydWN0XzEgPSByZXF1aXJlKFwiLi9hbm5vdGF0aW9uL3Bvc3RfY29uc3RydWN0XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicG9zdENvbnN0cnVjdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gcG9zdF9jb25zdHJ1Y3RfMS5wb3N0Q29uc3RydWN0OyB9IH0pO1xudmFyIG1ldGFkYXRhX3JlYWRlcl8xID0gcmVxdWlyZShcIi4vcGxhbm5pbmcvbWV0YWRhdGFfcmVhZGVyXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiTWV0YWRhdGFSZWFkZXJcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG1ldGFkYXRhX3JlYWRlcl8xLk1ldGFkYXRhUmVhZGVyOyB9IH0pO1xudmFyIGlkXzEgPSByZXF1aXJlKFwiLi91dGlscy9pZFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImlkXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBpZF8xLmlkOyB9IH0pO1xudmFyIGRlY29yYXRvcl91dGlsc18xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi9kZWNvcmF0b3JfdXRpbHNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJkZWNvcmF0ZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZGVjb3JhdG9yX3V0aWxzXzEuZGVjb3JhdGU7IH0gfSk7XG52YXIgY29uc3RyYWludF9oZWxwZXJzXzEgPSByZXF1aXJlKFwiLi9zeW50YXgvY29uc3RyYWludF9oZWxwZXJzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidHJhdmVyc2VBbmNlcnN0b3JzXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS50cmF2ZXJzZUFuY2Vyc3RvcnM7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ0YWdnZWRDb25zdHJhaW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS50YWdnZWRDb25zdHJhaW50OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwibmFtZWRDb25zdHJhaW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS5uYW1lZENvbnN0cmFpbnQ7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ0eXBlQ29uc3RyYWludFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29uc3RyYWludF9oZWxwZXJzXzEudHlwZUNvbnN0cmFpbnQ7IH0gfSk7XG52YXIgc2VyaWFsaXphdGlvbl8xID0gcmVxdWlyZShcIi4vdXRpbHMvc2VyaWFsaXphdGlvblwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldFNlcnZpY2VJZGVudGlmaWVyQXNTdHJpbmdcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlcmlhbGl6YXRpb25fMS5nZXRTZXJ2aWNlSWRlbnRpZmllckFzU3RyaW5nOyB9IH0pO1xudmFyIGJpbmRpbmdfdXRpbHNfMSA9IHJlcXVpcmUoXCIuL3V0aWxzL2JpbmRpbmdfdXRpbHNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJtdWx0aUJpbmRUb1NlcnZpY2VcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJpbmRpbmdfdXRpbHNfMS5tdWx0aUJpbmRUb1NlcnZpY2U7IH0gfSk7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQ29udGV4dCA9IHZvaWQgMDtcbnZhciBpZF8xID0gcmVxdWlyZShcIi4uL3V0aWxzL2lkXCIpO1xudmFyIENvbnRleHQgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIENvbnRleHQoY29udGFpbmVyKSB7XG4gICAgICAgIHRoaXMuaWQgPSBpZF8xLmlkKCk7XG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gY29udGFpbmVyO1xuICAgIH1cbiAgICBDb250ZXh0LnByb3RvdHlwZS5hZGRQbGFuID0gZnVuY3Rpb24gKHBsYW4pIHtcbiAgICAgICAgdGhpcy5wbGFuID0gcGxhbjtcbiAgICB9O1xuICAgIENvbnRleHQucHJvdG90eXBlLnNldEN1cnJlbnRSZXF1ZXN0ID0gZnVuY3Rpb24gKGN1cnJlbnRSZXF1ZXN0KSB7XG4gICAgICAgIHRoaXMuY3VycmVudFJlcXVlc3QgPSBjdXJyZW50UmVxdWVzdDtcbiAgICB9O1xuICAgIHJldHVybiBDb250ZXh0O1xufSgpKTtcbmV4cG9ydHMuQ29udGV4dCA9IENvbnRleHQ7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuTWV0YWRhdGEgPSB2b2lkIDA7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIE1ldGFkYXRhID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBNZXRhZGF0YShrZXksIHZhbHVlKSB7XG4gICAgICAgIHRoaXMua2V5ID0ga2V5O1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuICAgIE1ldGFkYXRhLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMua2V5ID09PSBNRVRBREFUQV9LRVkuTkFNRURfVEFHKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJuYW1lZDogXCIgKyB0aGlzLnZhbHVlLnRvU3RyaW5nKCkgKyBcIiBcIjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBcInRhZ2dlZDogeyBrZXk6XCIgKyB0aGlzLmtleS50b1N0cmluZygpICsgXCIsIHZhbHVlOiBcIiArIHRoaXMudmFsdWUgKyBcIiB9XCI7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBNZXRhZGF0YTtcbn0oKSk7XG5leHBvcnRzLk1ldGFkYXRhID0gTWV0YWRhdGE7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuTWV0YWRhdGFSZWFkZXIgPSB2b2lkIDA7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIE1ldGFkYXRhUmVhZGVyID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBNZXRhZGF0YVJlYWRlcigpIHtcbiAgICB9XG4gICAgTWV0YWRhdGFSZWFkZXIucHJvdG90eXBlLmdldENvbnN0cnVjdG9yTWV0YWRhdGEgPSBmdW5jdGlvbiAoY29uc3RydWN0b3JGdW5jKSB7XG4gICAgICAgIHZhciBjb21waWxlckdlbmVyYXRlZE1ldGFkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShNRVRBREFUQV9LRVkuUEFSQU1fVFlQRVMsIGNvbnN0cnVjdG9yRnVuYyk7XG4gICAgICAgIHZhciB1c2VyR2VuZXJhdGVkTWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKE1FVEFEQVRBX0tFWS5UQUdHRUQsIGNvbnN0cnVjdG9yRnVuYyk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb21waWxlckdlbmVyYXRlZE1ldGFkYXRhOiBjb21waWxlckdlbmVyYXRlZE1ldGFkYXRhLFxuICAgICAgICAgICAgdXNlckdlbmVyYXRlZE1ldGFkYXRhOiB1c2VyR2VuZXJhdGVkTWV0YWRhdGEgfHwge31cbiAgICAgICAgfTtcbiAgICB9O1xuICAgIE1ldGFkYXRhUmVhZGVyLnByb3RvdHlwZS5nZXRQcm9wZXJ0aWVzTWV0YWRhdGEgPSBmdW5jdGlvbiAoY29uc3RydWN0b3JGdW5jKSB7XG4gICAgICAgIHZhciB1c2VyR2VuZXJhdGVkTWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKE1FVEFEQVRBX0tFWS5UQUdHRURfUFJPUCwgY29uc3RydWN0b3JGdW5jKSB8fCBbXTtcbiAgICAgICAgcmV0dXJuIHVzZXJHZW5lcmF0ZWRNZXRhZGF0YTtcbiAgICB9O1xuICAgIHJldHVybiBNZXRhZGF0YVJlYWRlcjtcbn0oKSk7XG5leHBvcnRzLk1ldGFkYXRhUmVhZGVyID0gTWV0YWRhdGFSZWFkZXI7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuUGxhbiA9IHZvaWQgMDtcbnZhciBQbGFuID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBQbGFuKHBhcmVudENvbnRleHQsIHJvb3RSZXF1ZXN0KSB7XG4gICAgICAgIHRoaXMucGFyZW50Q29udGV4dCA9IHBhcmVudENvbnRleHQ7XG4gICAgICAgIHRoaXMucm9vdFJlcXVlc3QgPSByb290UmVxdWVzdDtcbiAgICB9XG4gICAgcmV0dXJuIFBsYW47XG59KCkpO1xuZXhwb3J0cy5QbGFuID0gUGxhbjtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRCaW5kaW5nRGljdGlvbmFyeSA9IGV4cG9ydHMuY3JlYXRlTW9ja1JlcXVlc3QgPSBleHBvcnRzLnBsYW4gPSB2b2lkIDA7XG52YXIgYmluZGluZ19jb3VudF8xID0gcmVxdWlyZShcIi4uL2JpbmRpbmdzL2JpbmRpbmdfY291bnRcIik7XG52YXIgRVJST1JfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbnZhciBsaXRlcmFsX3R5cGVzXzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2xpdGVyYWxfdHlwZXNcIik7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIGV4Y2VwdGlvbnNfMSA9IHJlcXVpcmUoXCIuLi91dGlscy9leGNlcHRpb25zXCIpO1xudmFyIHNlcmlhbGl6YXRpb25fMSA9IHJlcXVpcmUoXCIuLi91dGlscy9zZXJpYWxpemF0aW9uXCIpO1xudmFyIGNvbnRleHRfMSA9IHJlcXVpcmUoXCIuL2NvbnRleHRcIik7XG52YXIgbWV0YWRhdGFfMSA9IHJlcXVpcmUoXCIuL21ldGFkYXRhXCIpO1xudmFyIHBsYW5fMSA9IHJlcXVpcmUoXCIuL3BsYW5cIik7XG52YXIgcmVmbGVjdGlvbl91dGlsc18xID0gcmVxdWlyZShcIi4vcmVmbGVjdGlvbl91dGlsc1wiKTtcbnZhciByZXF1ZXN0XzEgPSByZXF1aXJlKFwiLi9yZXF1ZXN0XCIpO1xudmFyIHRhcmdldF8xID0gcmVxdWlyZShcIi4vdGFyZ2V0XCIpO1xuZnVuY3Rpb24gZ2V0QmluZGluZ0RpY3Rpb25hcnkoY250bnIpIHtcbiAgICByZXR1cm4gY250bnIuX2JpbmRpbmdEaWN0aW9uYXJ5O1xufVxuZXhwb3J0cy5nZXRCaW5kaW5nRGljdGlvbmFyeSA9IGdldEJpbmRpbmdEaWN0aW9uYXJ5O1xuZnVuY3Rpb24gX2NyZWF0ZVRhcmdldChpc011bHRpSW5qZWN0LCB0YXJnZXRUeXBlLCBzZXJ2aWNlSWRlbnRpZmllciwgbmFtZSwga2V5LCB2YWx1ZSkge1xuICAgIHZhciBtZXRhZGF0YUtleSA9IGlzTXVsdGlJbmplY3QgPyBNRVRBREFUQV9LRVkuTVVMVElfSU5KRUNUX1RBRyA6IE1FVEFEQVRBX0tFWS5JTkpFQ1RfVEFHO1xuICAgIHZhciBpbmplY3RNZXRhZGF0YSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKG1ldGFkYXRhS2V5LCBzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgdmFyIHRhcmdldCA9IG5ldyB0YXJnZXRfMS5UYXJnZXQodGFyZ2V0VHlwZSwgbmFtZSwgc2VydmljZUlkZW50aWZpZXIsIGluamVjdE1ldGFkYXRhKTtcbiAgICBpZiAoa2V5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFyIHRhZ01ldGFkYXRhID0gbmV3IG1ldGFkYXRhXzEuTWV0YWRhdGEoa2V5LCB2YWx1ZSk7XG4gICAgICAgIHRhcmdldC5tZXRhZGF0YS5wdXNoKHRhZ01ldGFkYXRhKTtcbiAgICB9XG4gICAgcmV0dXJuIHRhcmdldDtcbn1cbmZ1bmN0aW9uIF9nZXRBY3RpdmVCaW5kaW5ncyhtZXRhZGF0YVJlYWRlciwgYXZvaWRDb25zdHJhaW50cywgY29udGV4dCwgcGFyZW50UmVxdWVzdCwgdGFyZ2V0KSB7XG4gICAgdmFyIGJpbmRpbmdzID0gZ2V0QmluZGluZ3MoY29udGV4dC5jb250YWluZXIsIHRhcmdldC5zZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgdmFyIGFjdGl2ZUJpbmRpbmdzID0gW107XG4gICAgaWYgKGJpbmRpbmdzLmxlbmd0aCA9PT0gYmluZGluZ19jb3VudF8xLkJpbmRpbmdDb3VudC5Ob0JpbmRpbmdzQXZhaWxhYmxlICYmXG4gICAgICAgIGNvbnRleHQuY29udGFpbmVyLm9wdGlvbnMuYXV0b0JpbmRJbmplY3RhYmxlICYmXG4gICAgICAgIHR5cGVvZiB0YXJnZXQuc2VydmljZUlkZW50aWZpZXIgPT09IFwiZnVuY3Rpb25cIiAmJlxuICAgICAgICBtZXRhZGF0YVJlYWRlci5nZXRDb25zdHJ1Y3Rvck1ldGFkYXRhKHRhcmdldC5zZXJ2aWNlSWRlbnRpZmllcikuY29tcGlsZXJHZW5lcmF0ZWRNZXRhZGF0YSkge1xuICAgICAgICBjb250ZXh0LmNvbnRhaW5lci5iaW5kKHRhcmdldC5zZXJ2aWNlSWRlbnRpZmllcikudG9TZWxmKCk7XG4gICAgICAgIGJpbmRpbmdzID0gZ2V0QmluZGluZ3MoY29udGV4dC5jb250YWluZXIsIHRhcmdldC5zZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgfVxuICAgIGlmICghYXZvaWRDb25zdHJhaW50cykge1xuICAgICAgICBhY3RpdmVCaW5kaW5ncyA9IGJpbmRpbmdzLmZpbHRlcihmdW5jdGlvbiAoYmluZGluZykge1xuICAgICAgICAgICAgdmFyIHJlcXVlc3QgPSBuZXcgcmVxdWVzdF8xLlJlcXVlc3QoYmluZGluZy5zZXJ2aWNlSWRlbnRpZmllciwgY29udGV4dCwgcGFyZW50UmVxdWVzdCwgYmluZGluZywgdGFyZ2V0KTtcbiAgICAgICAgICAgIHJldHVybiBiaW5kaW5nLmNvbnN0cmFpbnQocmVxdWVzdCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgYWN0aXZlQmluZGluZ3MgPSBiaW5kaW5ncztcbiAgICB9XG4gICAgX3ZhbGlkYXRlQWN0aXZlQmluZGluZ0NvdW50KHRhcmdldC5zZXJ2aWNlSWRlbnRpZmllciwgYWN0aXZlQmluZGluZ3MsIHRhcmdldCwgY29udGV4dC5jb250YWluZXIpO1xuICAgIHJldHVybiBhY3RpdmVCaW5kaW5ncztcbn1cbmZ1bmN0aW9uIF92YWxpZGF0ZUFjdGl2ZUJpbmRpbmdDb3VudChzZXJ2aWNlSWRlbnRpZmllciwgYmluZGluZ3MsIHRhcmdldCwgY29udGFpbmVyKSB7XG4gICAgc3dpdGNoIChiaW5kaW5ncy5sZW5ndGgpIHtcbiAgICAgICAgY2FzZSBiaW5kaW5nX2NvdW50XzEuQmluZGluZ0NvdW50Lk5vQmluZGluZ3NBdmFpbGFibGU6XG4gICAgICAgICAgICBpZiAodGFyZ2V0LmlzT3B0aW9uYWwoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBiaW5kaW5ncztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBzZXJ2aWNlSWRlbnRpZmllclN0cmluZyA9IHNlcmlhbGl6YXRpb25fMS5nZXRTZXJ2aWNlSWRlbnRpZmllckFzU3RyaW5nKHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgICAgICAgICB2YXIgbXNnID0gRVJST1JfTVNHUy5OT1RfUkVHSVNURVJFRDtcbiAgICAgICAgICAgICAgICBtc2cgKz0gc2VyaWFsaXphdGlvbl8xLmxpc3RNZXRhZGF0YUZvclRhcmdldChzZXJ2aWNlSWRlbnRpZmllclN0cmluZywgdGFyZ2V0KTtcbiAgICAgICAgICAgICAgICBtc2cgKz0gc2VyaWFsaXphdGlvbl8xLmxpc3RSZWdpc3RlcmVkQmluZGluZ3NGb3JTZXJ2aWNlSWRlbnRpZmllcihjb250YWluZXIsIHNlcnZpY2VJZGVudGlmaWVyU3RyaW5nLCBnZXRCaW5kaW5ncyk7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgYmluZGluZ19jb3VudF8xLkJpbmRpbmdDb3VudC5Pbmx5T25lQmluZGluZ0F2YWlsYWJsZTpcbiAgICAgICAgICAgIGlmICghdGFyZ2V0LmlzQXJyYXkoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBiaW5kaW5ncztcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBiaW5kaW5nX2NvdW50XzEuQmluZGluZ0NvdW50Lk11bHRpcGxlQmluZGluZ3NBdmFpbGFibGU6XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBpZiAoIXRhcmdldC5pc0FycmF5KCkpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VydmljZUlkZW50aWZpZXJTdHJpbmcgPSBzZXJpYWxpemF0aW9uXzEuZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZyhzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgICAgICAgICAgdmFyIG1zZyA9IEVSUk9SX01TR1MuQU1CSUdVT1VTX01BVENIICsgXCIgXCIgKyBzZXJ2aWNlSWRlbnRpZmllclN0cmluZztcbiAgICAgICAgICAgICAgICBtc2cgKz0gc2VyaWFsaXphdGlvbl8xLmxpc3RSZWdpc3RlcmVkQmluZGluZ3NGb3JTZXJ2aWNlSWRlbnRpZmllcihjb250YWluZXIsIHNlcnZpY2VJZGVudGlmaWVyU3RyaW5nLCBnZXRCaW5kaW5ncyk7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYmluZGluZ3M7XG4gICAgICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gX2NyZWF0ZVN1YlJlcXVlc3RzKG1ldGFkYXRhUmVhZGVyLCBhdm9pZENvbnN0cmFpbnRzLCBzZXJ2aWNlSWRlbnRpZmllciwgY29udGV4dCwgcGFyZW50UmVxdWVzdCwgdGFyZ2V0KSB7XG4gICAgdmFyIGFjdGl2ZUJpbmRpbmdzO1xuICAgIHZhciBjaGlsZFJlcXVlc3Q7XG4gICAgaWYgKHBhcmVudFJlcXVlc3QgPT09IG51bGwpIHtcbiAgICAgICAgYWN0aXZlQmluZGluZ3MgPSBfZ2V0QWN0aXZlQmluZGluZ3MobWV0YWRhdGFSZWFkZXIsIGF2b2lkQ29uc3RyYWludHMsIGNvbnRleHQsIG51bGwsIHRhcmdldCk7XG4gICAgICAgIGNoaWxkUmVxdWVzdCA9IG5ldyByZXF1ZXN0XzEuUmVxdWVzdChzZXJ2aWNlSWRlbnRpZmllciwgY29udGV4dCwgbnVsbCwgYWN0aXZlQmluZGluZ3MsIHRhcmdldCk7XG4gICAgICAgIHZhciB0aGVQbGFuID0gbmV3IHBsYW5fMS5QbGFuKGNvbnRleHQsIGNoaWxkUmVxdWVzdCk7XG4gICAgICAgIGNvbnRleHQuYWRkUGxhbih0aGVQbGFuKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGFjdGl2ZUJpbmRpbmdzID0gX2dldEFjdGl2ZUJpbmRpbmdzKG1ldGFkYXRhUmVhZGVyLCBhdm9pZENvbnN0cmFpbnRzLCBjb250ZXh0LCBwYXJlbnRSZXF1ZXN0LCB0YXJnZXQpO1xuICAgICAgICBjaGlsZFJlcXVlc3QgPSBwYXJlbnRSZXF1ZXN0LmFkZENoaWxkUmVxdWVzdCh0YXJnZXQuc2VydmljZUlkZW50aWZpZXIsIGFjdGl2ZUJpbmRpbmdzLCB0YXJnZXQpO1xuICAgIH1cbiAgICBhY3RpdmVCaW5kaW5ncy5mb3JFYWNoKGZ1bmN0aW9uIChiaW5kaW5nKSB7XG4gICAgICAgIHZhciBzdWJDaGlsZFJlcXVlc3QgPSBudWxsO1xuICAgICAgICBpZiAodGFyZ2V0LmlzQXJyYXkoKSkge1xuICAgICAgICAgICAgc3ViQ2hpbGRSZXF1ZXN0ID0gY2hpbGRSZXF1ZXN0LmFkZENoaWxkUmVxdWVzdChiaW5kaW5nLnNlcnZpY2VJZGVudGlmaWVyLCBiaW5kaW5nLCB0YXJnZXQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKGJpbmRpbmcuY2FjaGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdWJDaGlsZFJlcXVlc3QgPSBjaGlsZFJlcXVlc3Q7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJpbmRpbmcudHlwZSA9PT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5JbnN0YW5jZSAmJiBiaW5kaW5nLmltcGxlbWVudGF0aW9uVHlwZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGRlcGVuZGVuY2llcyA9IHJlZmxlY3Rpb25fdXRpbHNfMS5nZXREZXBlbmRlbmNpZXMobWV0YWRhdGFSZWFkZXIsIGJpbmRpbmcuaW1wbGVtZW50YXRpb25UeXBlKTtcbiAgICAgICAgICAgIGlmICghY29udGV4dC5jb250YWluZXIub3B0aW9ucy5za2lwQmFzZUNsYXNzQ2hlY2tzKSB7XG4gICAgICAgICAgICAgICAgdmFyIGJhc2VDbGFzc0RlcGVuZGVuY3lDb3VudCA9IHJlZmxlY3Rpb25fdXRpbHNfMS5nZXRCYXNlQ2xhc3NEZXBlbmRlbmN5Q291bnQobWV0YWRhdGFSZWFkZXIsIGJpbmRpbmcuaW1wbGVtZW50YXRpb25UeXBlKTtcbiAgICAgICAgICAgICAgICBpZiAoZGVwZW5kZW5jaWVzLmxlbmd0aCA8IGJhc2VDbGFzc0RlcGVuZGVuY3lDb3VudCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSBFUlJPUl9NU0dTLkFSR1VNRU5UU19MRU5HVEhfTUlTTUFUQ0gocmVmbGVjdGlvbl91dGlsc18xLmdldEZ1bmN0aW9uTmFtZShiaW5kaW5nLmltcGxlbWVudGF0aW9uVHlwZSkpO1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlcGVuZGVuY2llcy5mb3JFYWNoKGZ1bmN0aW9uIChkZXBlbmRlbmN5KSB7XG4gICAgICAgICAgICAgICAgX2NyZWF0ZVN1YlJlcXVlc3RzKG1ldGFkYXRhUmVhZGVyLCBmYWxzZSwgZGVwZW5kZW5jeS5zZXJ2aWNlSWRlbnRpZmllciwgY29udGV4dCwgc3ViQ2hpbGRSZXF1ZXN0LCBkZXBlbmRlbmN5KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5mdW5jdGlvbiBnZXRCaW5kaW5ncyhjb250YWluZXIsIHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgdmFyIGJpbmRpbmdzID0gW107XG4gICAgdmFyIGJpbmRpbmdEaWN0aW9uYXJ5ID0gZ2V0QmluZGluZ0RpY3Rpb25hcnkoY29udGFpbmVyKTtcbiAgICBpZiAoYmluZGluZ0RpY3Rpb25hcnkuaGFzS2V5KHNlcnZpY2VJZGVudGlmaWVyKSkge1xuICAgICAgICBiaW5kaW5ncyA9IGJpbmRpbmdEaWN0aW9uYXJ5LmdldChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgfVxuICAgIGVsc2UgaWYgKGNvbnRhaW5lci5wYXJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgYmluZGluZ3MgPSBnZXRCaW5kaW5ncyhjb250YWluZXIucGFyZW50LCBzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgfVxuICAgIHJldHVybiBiaW5kaW5ncztcbn1cbmZ1bmN0aW9uIHBsYW4obWV0YWRhdGFSZWFkZXIsIGNvbnRhaW5lciwgaXNNdWx0aUluamVjdCwgdGFyZ2V0VHlwZSwgc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUsIGF2b2lkQ29uc3RyYWludHMpIHtcbiAgICBpZiAoYXZvaWRDb25zdHJhaW50cyA9PT0gdm9pZCAwKSB7IGF2b2lkQ29uc3RyYWludHMgPSBmYWxzZTsgfVxuICAgIHZhciBjb250ZXh0ID0gbmV3IGNvbnRleHRfMS5Db250ZXh0KGNvbnRhaW5lcik7XG4gICAgdmFyIHRhcmdldCA9IF9jcmVhdGVUYXJnZXQoaXNNdWx0aUluamVjdCwgdGFyZ2V0VHlwZSwgc2VydmljZUlkZW50aWZpZXIsIFwiXCIsIGtleSwgdmFsdWUpO1xuICAgIHRyeSB7XG4gICAgICAgIF9jcmVhdGVTdWJSZXF1ZXN0cyhtZXRhZGF0YVJlYWRlciwgYXZvaWRDb25zdHJhaW50cywgc2VydmljZUlkZW50aWZpZXIsIGNvbnRleHQsIG51bGwsIHRhcmdldCk7XG4gICAgICAgIHJldHVybiBjb250ZXh0O1xuICAgIH1cbiAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGV4Y2VwdGlvbnNfMS5pc1N0YWNrT3ZlcmZsb3dFeGVwdGlvbihlcnJvcikpIHtcbiAgICAgICAgICAgIGlmIChjb250ZXh0LnBsYW4pIHtcbiAgICAgICAgICAgICAgICBzZXJpYWxpemF0aW9uXzEuY2lyY3VsYXJEZXBlbmRlbmN5VG9FeGNlcHRpb24oY29udGV4dC5wbGFuLnJvb3RSZXF1ZXN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG59XG5leHBvcnRzLnBsYW4gPSBwbGFuO1xuZnVuY3Rpb24gY3JlYXRlTW9ja1JlcXVlc3QoY29udGFpbmVyLCBzZXJ2aWNlSWRlbnRpZmllciwga2V5LCB2YWx1ZSkge1xuICAgIHZhciB0YXJnZXQgPSBuZXcgdGFyZ2V0XzEuVGFyZ2V0KGxpdGVyYWxfdHlwZXNfMS5UYXJnZXRUeXBlRW51bS5WYXJpYWJsZSwgXCJcIiwgc2VydmljZUlkZW50aWZpZXIsIG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKGtleSwgdmFsdWUpKTtcbiAgICB2YXIgY29udGV4dCA9IG5ldyBjb250ZXh0XzEuQ29udGV4dChjb250YWluZXIpO1xuICAgIHZhciByZXF1ZXN0ID0gbmV3IHJlcXVlc3RfMS5SZXF1ZXN0KHNlcnZpY2VJZGVudGlmaWVyLCBjb250ZXh0LCBudWxsLCBbXSwgdGFyZ2V0KTtcbiAgICByZXR1cm4gcmVxdWVzdDtcbn1cbmV4cG9ydHMuY3JlYXRlTW9ja1JlcXVlc3QgPSBjcmVhdGVNb2NrUmVxdWVzdDtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5RdWVyeWFibGVTdHJpbmcgPSB2b2lkIDA7XG52YXIgUXVlcnlhYmxlU3RyaW5nID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBRdWVyeWFibGVTdHJpbmcoc3RyKSB7XG4gICAgICAgIHRoaXMuc3RyID0gc3RyO1xuICAgIH1cbiAgICBRdWVyeWFibGVTdHJpbmcucHJvdG90eXBlLnN0YXJ0c1dpdGggPSBmdW5jdGlvbiAoc2VhcmNoU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0ci5pbmRleE9mKHNlYXJjaFN0cmluZykgPT09IDA7XG4gICAgfTtcbiAgICBRdWVyeWFibGVTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoID0gZnVuY3Rpb24gKHNlYXJjaFN0cmluZykge1xuICAgICAgICB2YXIgcmV2ZXJzZVN0cmluZyA9IFwiXCI7XG4gICAgICAgIHZhciByZXZlcnNlU2VhcmNoU3RyaW5nID0gc2VhcmNoU3RyaW5nLnNwbGl0KFwiXCIpLnJldmVyc2UoKS5qb2luKFwiXCIpO1xuICAgICAgICByZXZlcnNlU3RyaW5nID0gdGhpcy5zdHIuc3BsaXQoXCJcIikucmV2ZXJzZSgpLmpvaW4oXCJcIik7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXJ0c1dpdGguY2FsbCh7IHN0cjogcmV2ZXJzZVN0cmluZyB9LCByZXZlcnNlU2VhcmNoU3RyaW5nKTtcbiAgICB9O1xuICAgIFF1ZXJ5YWJsZVN0cmluZy5wcm90b3R5cGUuY29udGFpbnMgPSBmdW5jdGlvbiAoc2VhcmNoU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiAodGhpcy5zdHIuaW5kZXhPZihzZWFyY2hTdHJpbmcpICE9PSAtMSk7XG4gICAgfTtcbiAgICBRdWVyeWFibGVTdHJpbmcucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChjb21wYXJlU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0ciA9PT0gY29tcGFyZVN0cmluZztcbiAgICB9O1xuICAgIFF1ZXJ5YWJsZVN0cmluZy5wcm90b3R5cGUudmFsdWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0cjtcbiAgICB9O1xuICAgIHJldHVybiBRdWVyeWFibGVTdHJpbmc7XG59KCkpO1xuZXhwb3J0cy5RdWVyeWFibGVTdHJpbmcgPSBRdWVyeWFibGVTdHJpbmc7XG4iLCJcInVzZSBzdHJpY3RcIjtcbnZhciBfX3NwcmVhZEFycmF5cyA9ICh0aGlzICYmIHRoaXMuX19zcHJlYWRBcnJheXMpIHx8IGZ1bmN0aW9uICgpIHtcbiAgICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcbiAgICBmb3IgKHZhciByID0gQXJyYXkocyksIGsgPSAwLCBpID0gMDsgaSA8IGlsOyBpKyspXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxuICAgICAgICAgICAgcltrXSA9IGFbal07XG4gICAgcmV0dXJuIHI7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRGdW5jdGlvbk5hbWUgPSBleHBvcnRzLmdldEJhc2VDbGFzc0RlcGVuZGVuY3lDb3VudCA9IGV4cG9ydHMuZ2V0RGVwZW5kZW5jaWVzID0gdm9pZCAwO1xudmFyIGluamVjdF8xID0gcmVxdWlyZShcIi4uL2Fubm90YXRpb24vaW5qZWN0XCIpO1xudmFyIEVSUk9SX01TR1MgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2Vycm9yX21zZ3NcIik7XG52YXIgbGl0ZXJhbF90eXBlc18xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9saXRlcmFsX3R5cGVzXCIpO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbnZhciBzZXJpYWxpemF0aW9uXzEgPSByZXF1aXJlKFwiLi4vdXRpbHMvc2VyaWFsaXphdGlvblwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldEZ1bmN0aW9uTmFtZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gc2VyaWFsaXphdGlvbl8xLmdldEZ1bmN0aW9uTmFtZTsgfSB9KTtcbnZhciB0YXJnZXRfMSA9IHJlcXVpcmUoXCIuL3RhcmdldFwiKTtcbmZ1bmN0aW9uIGdldERlcGVuZGVuY2llcyhtZXRhZGF0YVJlYWRlciwgZnVuYykge1xuICAgIHZhciBjb25zdHJ1Y3Rvck5hbWUgPSBzZXJpYWxpemF0aW9uXzEuZ2V0RnVuY3Rpb25OYW1lKGZ1bmMpO1xuICAgIHZhciB0YXJnZXRzID0gZ2V0VGFyZ2V0cyhtZXRhZGF0YVJlYWRlciwgY29uc3RydWN0b3JOYW1lLCBmdW5jLCBmYWxzZSk7XG4gICAgcmV0dXJuIHRhcmdldHM7XG59XG5leHBvcnRzLmdldERlcGVuZGVuY2llcyA9IGdldERlcGVuZGVuY2llcztcbmZ1bmN0aW9uIGdldFRhcmdldHMobWV0YWRhdGFSZWFkZXIsIGNvbnN0cnVjdG9yTmFtZSwgZnVuYywgaXNCYXNlQ2xhc3MpIHtcbiAgICB2YXIgbWV0YWRhdGEgPSBtZXRhZGF0YVJlYWRlci5nZXRDb25zdHJ1Y3Rvck1ldGFkYXRhKGZ1bmMpO1xuICAgIHZhciBzZXJ2aWNlSWRlbnRpZmllcnMgPSBtZXRhZGF0YS5jb21waWxlckdlbmVyYXRlZE1ldGFkYXRhO1xuICAgIGlmIChzZXJ2aWNlSWRlbnRpZmllcnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YXIgbXNnID0gRVJST1JfTVNHUy5NSVNTSU5HX0lOSkVDVEFCTEVfQU5OT1RBVElPTiArIFwiIFwiICsgY29uc3RydWN0b3JOYW1lICsgXCIuXCI7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgIH1cbiAgICB2YXIgY29uc3RydWN0b3JBcmdzTWV0YWRhdGEgPSBtZXRhZGF0YS51c2VyR2VuZXJhdGVkTWV0YWRhdGE7XG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhjb25zdHJ1Y3RvckFyZ3NNZXRhZGF0YSk7XG4gICAgdmFyIGhhc1VzZXJEZWNsYXJlZFVua25vd25JbmplY3Rpb25zID0gKGZ1bmMubGVuZ3RoID09PSAwICYmIGtleXMubGVuZ3RoID4gMCk7XG4gICAgdmFyIGl0ZXJhdGlvbnMgPSAoaGFzVXNlckRlY2xhcmVkVW5rbm93bkluamVjdGlvbnMpID8ga2V5cy5sZW5ndGggOiBmdW5jLmxlbmd0aDtcbiAgICB2YXIgY29uc3RydWN0b3JUYXJnZXRzID0gZ2V0Q29uc3RydWN0b3JBcmdzQXNUYXJnZXRzKGlzQmFzZUNsYXNzLCBjb25zdHJ1Y3Rvck5hbWUsIHNlcnZpY2VJZGVudGlmaWVycywgY29uc3RydWN0b3JBcmdzTWV0YWRhdGEsIGl0ZXJhdGlvbnMpO1xuICAgIHZhciBwcm9wZXJ0eVRhcmdldHMgPSBnZXRDbGFzc1Byb3BzQXNUYXJnZXRzKG1ldGFkYXRhUmVhZGVyLCBmdW5jKTtcbiAgICB2YXIgdGFyZ2V0cyA9IF9fc3ByZWFkQXJyYXlzKGNvbnN0cnVjdG9yVGFyZ2V0cywgcHJvcGVydHlUYXJnZXRzKTtcbiAgICByZXR1cm4gdGFyZ2V0cztcbn1cbmZ1bmN0aW9uIGdldENvbnN0cnVjdG9yQXJnc0FzVGFyZ2V0KGluZGV4LCBpc0Jhc2VDbGFzcywgY29uc3RydWN0b3JOYW1lLCBzZXJ2aWNlSWRlbnRpZmllcnMsIGNvbnN0cnVjdG9yQXJnc01ldGFkYXRhKSB7XG4gICAgdmFyIHRhcmdldE1ldGFkYXRhID0gY29uc3RydWN0b3JBcmdzTWV0YWRhdGFbaW5kZXgudG9TdHJpbmcoKV0gfHwgW107XG4gICAgdmFyIG1ldGFkYXRhID0gZm9ybWF0VGFyZ2V0TWV0YWRhdGEodGFyZ2V0TWV0YWRhdGEpO1xuICAgIHZhciBpc01hbmFnZWQgPSBtZXRhZGF0YS51bm1hbmFnZWQgIT09IHRydWU7XG4gICAgdmFyIHNlcnZpY2VJZGVudGlmaWVyID0gc2VydmljZUlkZW50aWZpZXJzW2luZGV4XTtcbiAgICB2YXIgaW5qZWN0SWRlbnRpZmllciA9IChtZXRhZGF0YS5pbmplY3QgfHwgbWV0YWRhdGEubXVsdGlJbmplY3QpO1xuICAgIHNlcnZpY2VJZGVudGlmaWVyID0gKGluamVjdElkZW50aWZpZXIpID8gKGluamVjdElkZW50aWZpZXIpIDogc2VydmljZUlkZW50aWZpZXI7XG4gICAgaWYgKHNlcnZpY2VJZGVudGlmaWVyIGluc3RhbmNlb2YgaW5qZWN0XzEuTGF6eVNlcnZpY2VJZGVudGlmZXIpIHtcbiAgICAgICAgc2VydmljZUlkZW50aWZpZXIgPSBzZXJ2aWNlSWRlbnRpZmllci51bndyYXAoKTtcbiAgICB9XG4gICAgaWYgKGlzTWFuYWdlZCkge1xuICAgICAgICB2YXIgaXNPYmplY3QgPSBzZXJ2aWNlSWRlbnRpZmllciA9PT0gT2JqZWN0O1xuICAgICAgICB2YXIgaXNGdW5jdGlvbiA9IHNlcnZpY2VJZGVudGlmaWVyID09PSBGdW5jdGlvbjtcbiAgICAgICAgdmFyIGlzVW5kZWZpbmVkID0gc2VydmljZUlkZW50aWZpZXIgPT09IHVuZGVmaW5lZDtcbiAgICAgICAgdmFyIGlzVW5rbm93blR5cGUgPSAoaXNPYmplY3QgfHwgaXNGdW5jdGlvbiB8fCBpc1VuZGVmaW5lZCk7XG4gICAgICAgIGlmICghaXNCYXNlQ2xhc3MgJiYgaXNVbmtub3duVHlwZSkge1xuICAgICAgICAgICAgdmFyIG1zZyA9IEVSUk9SX01TR1MuTUlTU0lOR19JTkpFQ1RfQU5OT1RBVElPTiArIFwiIGFyZ3VtZW50IFwiICsgaW5kZXggKyBcIiBpbiBjbGFzcyBcIiArIGNvbnN0cnVjdG9yTmFtZSArIFwiLlwiO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHRhcmdldCA9IG5ldyB0YXJnZXRfMS5UYXJnZXQobGl0ZXJhbF90eXBlc18xLlRhcmdldFR5cGVFbnVtLkNvbnN0cnVjdG9yQXJndW1lbnQsIG1ldGFkYXRhLnRhcmdldE5hbWUsIHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgdGFyZ2V0Lm1ldGFkYXRhID0gdGFyZ2V0TWV0YWRhdGE7XG4gICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuZnVuY3Rpb24gZ2V0Q29uc3RydWN0b3JBcmdzQXNUYXJnZXRzKGlzQmFzZUNsYXNzLCBjb25zdHJ1Y3Rvck5hbWUsIHNlcnZpY2VJZGVudGlmaWVycywgY29uc3RydWN0b3JBcmdzTWV0YWRhdGEsIGl0ZXJhdGlvbnMpIHtcbiAgICB2YXIgdGFyZ2V0cyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaXRlcmF0aW9uczsgaSsrKSB7XG4gICAgICAgIHZhciBpbmRleCA9IGk7XG4gICAgICAgIHZhciB0YXJnZXQgPSBnZXRDb25zdHJ1Y3RvckFyZ3NBc1RhcmdldChpbmRleCwgaXNCYXNlQ2xhc3MsIGNvbnN0cnVjdG9yTmFtZSwgc2VydmljZUlkZW50aWZpZXJzLCBjb25zdHJ1Y3RvckFyZ3NNZXRhZGF0YSk7XG4gICAgICAgIGlmICh0YXJnZXQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRhcmdldHMucHVzaCh0YXJnZXQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0YXJnZXRzO1xufVxuZnVuY3Rpb24gZ2V0Q2xhc3NQcm9wc0FzVGFyZ2V0cyhtZXRhZGF0YVJlYWRlciwgY29uc3RydWN0b3JGdW5jKSB7XG4gICAgdmFyIGNsYXNzUHJvcHNNZXRhZGF0YSA9IG1ldGFkYXRhUmVhZGVyLmdldFByb3BlcnRpZXNNZXRhZGF0YShjb25zdHJ1Y3RvckZ1bmMpO1xuICAgIHZhciB0YXJnZXRzID0gW107XG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhjbGFzc1Byb3BzTWV0YWRhdGEpO1xuICAgIGZvciAodmFyIF9pID0gMCwga2V5c18xID0ga2V5czsgX2kgPCBrZXlzXzEubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHZhciBrZXkgPSBrZXlzXzFbX2ldO1xuICAgICAgICB2YXIgdGFyZ2V0TWV0YWRhdGEgPSBjbGFzc1Byb3BzTWV0YWRhdGFba2V5XTtcbiAgICAgICAgdmFyIG1ldGFkYXRhID0gZm9ybWF0VGFyZ2V0TWV0YWRhdGEoY2xhc3NQcm9wc01ldGFkYXRhW2tleV0pO1xuICAgICAgICB2YXIgdGFyZ2V0TmFtZSA9IG1ldGFkYXRhLnRhcmdldE5hbWUgfHwga2V5O1xuICAgICAgICB2YXIgc2VydmljZUlkZW50aWZpZXIgPSAobWV0YWRhdGEuaW5qZWN0IHx8IG1ldGFkYXRhLm11bHRpSW5qZWN0KTtcbiAgICAgICAgdmFyIHRhcmdldCA9IG5ldyB0YXJnZXRfMS5UYXJnZXQobGl0ZXJhbF90eXBlc18xLlRhcmdldFR5cGVFbnVtLkNsYXNzUHJvcGVydHksIHRhcmdldE5hbWUsIHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgdGFyZ2V0Lm1ldGFkYXRhID0gdGFyZ2V0TWV0YWRhdGE7XG4gICAgICAgIHRhcmdldHMucHVzaCh0YXJnZXQpO1xuICAgIH1cbiAgICB2YXIgYmFzZUNvbnN0cnVjdG9yID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKGNvbnN0cnVjdG9yRnVuYy5wcm90b3R5cGUpLmNvbnN0cnVjdG9yO1xuICAgIGlmIChiYXNlQ29uc3RydWN0b3IgIT09IE9iamVjdCkge1xuICAgICAgICB2YXIgYmFzZVRhcmdldHMgPSBnZXRDbGFzc1Byb3BzQXNUYXJnZXRzKG1ldGFkYXRhUmVhZGVyLCBiYXNlQ29uc3RydWN0b3IpO1xuICAgICAgICB0YXJnZXRzID0gX19zcHJlYWRBcnJheXModGFyZ2V0cywgYmFzZVRhcmdldHMpO1xuICAgIH1cbiAgICByZXR1cm4gdGFyZ2V0cztcbn1cbmZ1bmN0aW9uIGdldEJhc2VDbGFzc0RlcGVuZGVuY3lDb3VudChtZXRhZGF0YVJlYWRlciwgZnVuYykge1xuICAgIHZhciBiYXNlQ29uc3RydWN0b3IgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoZnVuYy5wcm90b3R5cGUpLmNvbnN0cnVjdG9yO1xuICAgIGlmIChiYXNlQ29uc3RydWN0b3IgIT09IE9iamVjdCkge1xuICAgICAgICB2YXIgYmFzZUNvbnN0cnVjdG9yTmFtZSA9IHNlcmlhbGl6YXRpb25fMS5nZXRGdW5jdGlvbk5hbWUoYmFzZUNvbnN0cnVjdG9yKTtcbiAgICAgICAgdmFyIHRhcmdldHMgPSBnZXRUYXJnZXRzKG1ldGFkYXRhUmVhZGVyLCBiYXNlQ29uc3RydWN0b3JOYW1lLCBiYXNlQ29uc3RydWN0b3IsIHRydWUpO1xuICAgICAgICB2YXIgbWV0YWRhdGEgPSB0YXJnZXRzLm1hcChmdW5jdGlvbiAodCkge1xuICAgICAgICAgICAgcmV0dXJuIHQubWV0YWRhdGEuZmlsdGVyKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG0ua2V5ID09PSBNRVRBREFUQV9LRVkuVU5NQU5BR0VEX1RBRztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgdmFyIHVubWFuYWdlZENvdW50ID0gW10uY29uY2F0LmFwcGx5KFtdLCBtZXRhZGF0YSkubGVuZ3RoO1xuICAgICAgICB2YXIgZGVwZW5kZW5jeUNvdW50ID0gdGFyZ2V0cy5sZW5ndGggLSB1bm1hbmFnZWRDb3VudDtcbiAgICAgICAgaWYgKGRlcGVuZGVuY3lDb3VudCA+IDApIHtcbiAgICAgICAgICAgIHJldHVybiBkZXBlbmRlbmN5Q291bnQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0QmFzZUNsYXNzRGVwZW5kZW5jeUNvdW50KG1ldGFkYXRhUmVhZGVyLCBiYXNlQ29uc3RydWN0b3IpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG59XG5leHBvcnRzLmdldEJhc2VDbGFzc0RlcGVuZGVuY3lDb3VudCA9IGdldEJhc2VDbGFzc0RlcGVuZGVuY3lDb3VudDtcbmZ1bmN0aW9uIGZvcm1hdFRhcmdldE1ldGFkYXRhKHRhcmdldE1ldGFkYXRhKSB7XG4gICAgdmFyIHRhcmdldE1ldGFkYXRhTWFwID0ge307XG4gICAgdGFyZ2V0TWV0YWRhdGEuZm9yRWFjaChmdW5jdGlvbiAobSkge1xuICAgICAgICB0YXJnZXRNZXRhZGF0YU1hcFttLmtleS50b1N0cmluZygpXSA9IG0udmFsdWU7XG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgaW5qZWN0OiB0YXJnZXRNZXRhZGF0YU1hcFtNRVRBREFUQV9LRVkuSU5KRUNUX1RBR10sXG4gICAgICAgIG11bHRpSW5qZWN0OiB0YXJnZXRNZXRhZGF0YU1hcFtNRVRBREFUQV9LRVkuTVVMVElfSU5KRUNUX1RBR10sXG4gICAgICAgIHRhcmdldE5hbWU6IHRhcmdldE1ldGFkYXRhTWFwW01FVEFEQVRBX0tFWS5OQU1FX1RBR10sXG4gICAgICAgIHVubWFuYWdlZDogdGFyZ2V0TWV0YWRhdGFNYXBbTUVUQURBVEFfS0VZLlVOTUFOQUdFRF9UQUddXG4gICAgfTtcbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5SZXF1ZXN0ID0gdm9pZCAwO1xudmFyIGlkXzEgPSByZXF1aXJlKFwiLi4vdXRpbHMvaWRcIik7XG52YXIgUmVxdWVzdCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gUmVxdWVzdChzZXJ2aWNlSWRlbnRpZmllciwgcGFyZW50Q29udGV4dCwgcGFyZW50UmVxdWVzdCwgYmluZGluZ3MsIHRhcmdldCkge1xuICAgICAgICB0aGlzLmlkID0gaWRfMS5pZCgpO1xuICAgICAgICB0aGlzLnNlcnZpY2VJZGVudGlmaWVyID0gc2VydmljZUlkZW50aWZpZXI7XG4gICAgICAgIHRoaXMucGFyZW50Q29udGV4dCA9IHBhcmVudENvbnRleHQ7XG4gICAgICAgIHRoaXMucGFyZW50UmVxdWVzdCA9IHBhcmVudFJlcXVlc3Q7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgICAgICB0aGlzLmNoaWxkUmVxdWVzdHMgPSBbXTtcbiAgICAgICAgdGhpcy5iaW5kaW5ncyA9IChBcnJheS5pc0FycmF5KGJpbmRpbmdzKSA/IGJpbmRpbmdzIDogW2JpbmRpbmdzXSk7XG4gICAgICAgIHRoaXMucmVxdWVzdFNjb3BlID0gcGFyZW50UmVxdWVzdCA9PT0gbnVsbFxuICAgICAgICAgICAgPyBuZXcgTWFwKClcbiAgICAgICAgICAgIDogbnVsbDtcbiAgICB9XG4gICAgUmVxdWVzdC5wcm90b3R5cGUuYWRkQ2hpbGRSZXF1ZXN0ID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyLCBiaW5kaW5ncywgdGFyZ2V0KSB7XG4gICAgICAgIHZhciBjaGlsZCA9IG5ldyBSZXF1ZXN0KHNlcnZpY2VJZGVudGlmaWVyLCB0aGlzLnBhcmVudENvbnRleHQsIHRoaXMsIGJpbmRpbmdzLCB0YXJnZXQpO1xuICAgICAgICB0aGlzLmNoaWxkUmVxdWVzdHMucHVzaChjaGlsZCk7XG4gICAgICAgIHJldHVybiBjaGlsZDtcbiAgICB9O1xuICAgIHJldHVybiBSZXF1ZXN0O1xufSgpKTtcbmV4cG9ydHMuUmVxdWVzdCA9IFJlcXVlc3Q7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuVGFyZ2V0ID0gdm9pZCAwO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbnZhciBpZF8xID0gcmVxdWlyZShcIi4uL3V0aWxzL2lkXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi9tZXRhZGF0YVwiKTtcbnZhciBxdWVyeWFibGVfc3RyaW5nXzEgPSByZXF1aXJlKFwiLi9xdWVyeWFibGVfc3RyaW5nXCIpO1xudmFyIFRhcmdldCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gVGFyZ2V0KHR5cGUsIG5hbWUsIHNlcnZpY2VJZGVudGlmaWVyLCBuYW1lZE9yVGFnZ2VkKSB7XG4gICAgICAgIHRoaXMuaWQgPSBpZF8xLmlkKCk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuc2VydmljZUlkZW50aWZpZXIgPSBzZXJ2aWNlSWRlbnRpZmllcjtcbiAgICAgICAgdGhpcy5uYW1lID0gbmV3IHF1ZXJ5YWJsZV9zdHJpbmdfMS5RdWVyeWFibGVTdHJpbmcobmFtZSB8fCBcIlwiKTtcbiAgICAgICAgdGhpcy5tZXRhZGF0YSA9IG5ldyBBcnJheSgpO1xuICAgICAgICB2YXIgbWV0YWRhdGFJdGVtID0gbnVsbDtcbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lZE9yVGFnZ2VkID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBtZXRhZGF0YUl0ZW0gPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShNRVRBREFUQV9LRVkuTkFNRURfVEFHLCBuYW1lZE9yVGFnZ2VkKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChuYW1lZE9yVGFnZ2VkIGluc3RhbmNlb2YgbWV0YWRhdGFfMS5NZXRhZGF0YSkge1xuICAgICAgICAgICAgbWV0YWRhdGFJdGVtID0gbmFtZWRPclRhZ2dlZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWV0YWRhdGFJdGVtICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLm1ldGFkYXRhLnB1c2gobWV0YWRhdGFJdGVtKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBUYXJnZXQucHJvdG90eXBlLmhhc1RhZyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRoaXMubWV0YWRhdGE7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgbSA9IF9hW19pXTtcbiAgICAgICAgICAgIGlmIChtLmtleSA9PT0ga2V5KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5pc0FycmF5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5oYXNUYWcoTUVUQURBVEFfS0VZLk1VTFRJX0lOSkVDVF9UQUcpO1xuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5tYXRjaGVzQXJyYXkgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXRjaGVzVGFnKE1FVEFEQVRBX0tFWS5NVUxUSV9JTkpFQ1RfVEFHKShuYW1lKTtcbiAgICB9O1xuICAgIFRhcmdldC5wcm90b3R5cGUuaXNOYW1lZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzVGFnKE1FVEFEQVRBX0tFWS5OQU1FRF9UQUcpO1xuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5pc1RhZ2dlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGEuc29tZShmdW5jdGlvbiAobSkge1xuICAgICAgICAgICAgcmV0dXJuIChtLmtleSAhPT0gTUVUQURBVEFfS0VZLklOSkVDVF9UQUcpICYmXG4gICAgICAgICAgICAgICAgKG0ua2V5ICE9PSBNRVRBREFUQV9LRVkuTVVMVElfSU5KRUNUX1RBRykgJiZcbiAgICAgICAgICAgICAgICAobS5rZXkgIT09IE1FVEFEQVRBX0tFWS5OQU1FX1RBRykgJiZcbiAgICAgICAgICAgICAgICAobS5rZXkgIT09IE1FVEFEQVRBX0tFWS5VTk1BTkFHRURfVEFHKSAmJlxuICAgICAgICAgICAgICAgIChtLmtleSAhPT0gTUVUQURBVEFfS0VZLk5BTUVEX1RBRyk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5pc09wdGlvbmFsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXRjaGVzVGFnKE1FVEFEQVRBX0tFWS5PUFRJT05BTF9UQUcpKHRydWUpO1xuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5nZXROYW1lZFRhZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNOYW1lZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YS5maWx0ZXIoZnVuY3Rpb24gKG0pIHsgcmV0dXJuIG0ua2V5ID09PSBNRVRBREFUQV9LRVkuTkFNRURfVEFHOyB9KVswXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICAgIFRhcmdldC5wcm90b3R5cGUuZ2V0Q3VzdG9tVGFncyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNUYWdnZWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGEuZmlsdGVyKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChtLmtleSAhPT0gTUVUQURBVEFfS0VZLklOSkVDVF9UQUcpICYmXG4gICAgICAgICAgICAgICAgICAgIChtLmtleSAhPT0gTUVUQURBVEFfS0VZLk1VTFRJX0lOSkVDVF9UQUcpICYmXG4gICAgICAgICAgICAgICAgICAgIChtLmtleSAhPT0gTUVUQURBVEFfS0VZLk5BTUVfVEFHKSAmJlxuICAgICAgICAgICAgICAgICAgICAobS5rZXkgIT09IE1FVEFEQVRBX0tFWS5VTk1BTkFHRURfVEFHKSAmJlxuICAgICAgICAgICAgICAgICAgICAobS5rZXkgIT09IE1FVEFEQVRBX0tFWS5OQU1FRF9UQUcpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgICBUYXJnZXQucHJvdG90eXBlLm1hdGNoZXNOYW1lZFRhZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hdGNoZXNUYWcoTUVUQURBVEFfS0VZLk5BTUVEX1RBRykobmFtZSk7XG4gICAgfTtcbiAgICBUYXJnZXQucHJvdG90eXBlLm1hdGNoZXNUYWcgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSBfdGhpcy5tZXRhZGF0YTsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgbSA9IF9hW19pXTtcbiAgICAgICAgICAgICAgICBpZiAobS5rZXkgPT09IGtleSAmJiBtLnZhbHVlID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICByZXR1cm4gVGFyZ2V0O1xufSgpKTtcbmV4cG9ydHMuVGFyZ2V0ID0gVGFyZ2V0O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgX19zcHJlYWRBcnJheXMgPSAodGhpcyAmJiB0aGlzLl9fc3ByZWFkQXJyYXlzKSB8fCBmdW5jdGlvbiAoKSB7XG4gICAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XG4gICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxuICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcbiAgICAgICAgICAgIHJba10gPSBhW2pdO1xuICAgIHJldHVybiByO1xufTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMucmVzb2x2ZUluc3RhbmNlID0gdm9pZCAwO1xudmFyIGVycm9yX21zZ3NfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbnZhciBsaXRlcmFsX3R5cGVzXzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2xpdGVyYWxfdHlwZXNcIik7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xuZnVuY3Rpb24gX2luamVjdFByb3BlcnRpZXMoaW5zdGFuY2UsIGNoaWxkUmVxdWVzdHMsIHJlc29sdmVSZXF1ZXN0KSB7XG4gICAgdmFyIHByb3BlcnR5SW5qZWN0aW9uc1JlcXVlc3RzID0gY2hpbGRSZXF1ZXN0cy5maWx0ZXIoZnVuY3Rpb24gKGNoaWxkUmVxdWVzdCkge1xuICAgICAgICByZXR1cm4gKGNoaWxkUmVxdWVzdC50YXJnZXQgIT09IG51bGwgJiZcbiAgICAgICAgICAgIGNoaWxkUmVxdWVzdC50YXJnZXQudHlwZSA9PT0gbGl0ZXJhbF90eXBlc18xLlRhcmdldFR5cGVFbnVtLkNsYXNzUHJvcGVydHkpO1xuICAgIH0pO1xuICAgIHZhciBwcm9wZXJ0eUluamVjdGlvbnMgPSBwcm9wZXJ0eUluamVjdGlvbnNSZXF1ZXN0cy5tYXAocmVzb2x2ZVJlcXVlc3QpO1xuICAgIHByb3BlcnR5SW5qZWN0aW9uc1JlcXVlc3RzLmZvckVhY2goZnVuY3Rpb24gKHIsIGluZGV4KSB7XG4gICAgICAgIHZhciBwcm9wZXJ0eU5hbWUgPSBcIlwiO1xuICAgICAgICBwcm9wZXJ0eU5hbWUgPSByLnRhcmdldC5uYW1lLnZhbHVlKCk7XG4gICAgICAgIHZhciBpbmplY3Rpb24gPSBwcm9wZXJ0eUluamVjdGlvbnNbaW5kZXhdO1xuICAgICAgICBpbnN0YW5jZVtwcm9wZXJ0eU5hbWVdID0gaW5qZWN0aW9uO1xuICAgIH0pO1xuICAgIHJldHVybiBpbnN0YW5jZTtcbn1cbmZ1bmN0aW9uIF9jcmVhdGVJbnN0YW5jZShGdW5jLCBpbmplY3Rpb25zKSB7XG4gICAgcmV0dXJuIG5ldyAoRnVuYy5iaW5kLmFwcGx5KEZ1bmMsIF9fc3ByZWFkQXJyYXlzKFt2b2lkIDBdLCBpbmplY3Rpb25zKSkpKCk7XG59XG5mdW5jdGlvbiBfcG9zdENvbnN0cnVjdChjb25zdHIsIHJlc3VsdCkge1xuICAgIGlmIChSZWZsZWN0Lmhhc01ldGFkYXRhKE1FVEFEQVRBX0tFWS5QT1NUX0NPTlNUUlVDVCwgY29uc3RyKSkge1xuICAgICAgICB2YXIgZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoTUVUQURBVEFfS0VZLlBPU1RfQ09OU1RSVUNULCBjb25zdHIpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmVzdWx0W2RhdGEudmFsdWVdKCk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcl9tc2dzXzEuUE9TVF9DT05TVFJVQ1RfRVJST1IoY29uc3RyLm5hbWUsIGUubWVzc2FnZSkpO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gcmVzb2x2ZUluc3RhbmNlKGNvbnN0ciwgY2hpbGRSZXF1ZXN0cywgcmVzb2x2ZVJlcXVlc3QpIHtcbiAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICBpZiAoY2hpbGRSZXF1ZXN0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHZhciBjb25zdHJ1Y3RvckluamVjdGlvbnNSZXF1ZXN0cyA9IGNoaWxkUmVxdWVzdHMuZmlsdGVyKGZ1bmN0aW9uIChjaGlsZFJlcXVlc3QpIHtcbiAgICAgICAgICAgIHJldHVybiAoY2hpbGRSZXF1ZXN0LnRhcmdldCAhPT0gbnVsbCAmJiBjaGlsZFJlcXVlc3QudGFyZ2V0LnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5UYXJnZXRUeXBlRW51bS5Db25zdHJ1Y3RvckFyZ3VtZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBjb25zdHJ1Y3RvckluamVjdGlvbnMgPSBjb25zdHJ1Y3RvckluamVjdGlvbnNSZXF1ZXN0cy5tYXAocmVzb2x2ZVJlcXVlc3QpO1xuICAgICAgICByZXN1bHQgPSBfY3JlYXRlSW5zdGFuY2UoY29uc3RyLCBjb25zdHJ1Y3RvckluamVjdGlvbnMpO1xuICAgICAgICByZXN1bHQgPSBfaW5qZWN0UHJvcGVydGllcyhyZXN1bHQsIGNoaWxkUmVxdWVzdHMsIHJlc29sdmVSZXF1ZXN0KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBjb25zdHIoKTtcbiAgICB9XG4gICAgX3Bvc3RDb25zdHJ1Y3QoY29uc3RyLCByZXN1bHQpO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5leHBvcnRzLnJlc29sdmVJbnN0YW5jZSA9IHJlc29sdmVJbnN0YW5jZTtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5yZXNvbHZlID0gdm9pZCAwO1xudmFyIEVSUk9SX01TR1MgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2Vycm9yX21zZ3NcIik7XG52YXIgbGl0ZXJhbF90eXBlc18xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9saXRlcmFsX3R5cGVzXCIpO1xudmFyIGV4Y2VwdGlvbnNfMSA9IHJlcXVpcmUoXCIuLi91dGlscy9leGNlcHRpb25zXCIpO1xudmFyIHNlcmlhbGl6YXRpb25fMSA9IHJlcXVpcmUoXCIuLi91dGlscy9zZXJpYWxpemF0aW9uXCIpO1xudmFyIGluc3RhbnRpYXRpb25fMSA9IHJlcXVpcmUoXCIuL2luc3RhbnRpYXRpb25cIik7XG52YXIgaW52b2tlRmFjdG9yeSA9IGZ1bmN0aW9uIChmYWN0b3J5VHlwZSwgc2VydmljZUlkZW50aWZpZXIsIGZuKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGZuKCk7XG4gICAgfVxuICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoZXhjZXB0aW9uc18xLmlzU3RhY2tPdmVyZmxvd0V4ZXB0aW9uKGVycm9yKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuQ0lSQ1VMQVJfREVQRU5ERU5DWV9JTl9GQUNUT1JZKGZhY3RvcnlUeXBlLCBzZXJ2aWNlSWRlbnRpZmllci50b1N0cmluZygpKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgIH1cbn07XG52YXIgX3Jlc29sdmVSZXF1ZXN0ID0gZnVuY3Rpb24gKHJlcXVlc3RTY29wZSkge1xuICAgIHJldHVybiBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICByZXF1ZXN0LnBhcmVudENvbnRleHQuc2V0Q3VycmVudFJlcXVlc3QocmVxdWVzdCk7XG4gICAgICAgIHZhciBiaW5kaW5ncyA9IHJlcXVlc3QuYmluZGluZ3M7XG4gICAgICAgIHZhciBjaGlsZFJlcXVlc3RzID0gcmVxdWVzdC5jaGlsZFJlcXVlc3RzO1xuICAgICAgICB2YXIgdGFyZ2V0SXNBbkFycmF5ID0gcmVxdWVzdC50YXJnZXQgJiYgcmVxdWVzdC50YXJnZXQuaXNBcnJheSgpO1xuICAgICAgICB2YXIgdGFyZ2V0UGFyZW50SXNOb3RBbkFycmF5ID0gIXJlcXVlc3QucGFyZW50UmVxdWVzdCB8fFxuICAgICAgICAgICAgIXJlcXVlc3QucGFyZW50UmVxdWVzdC50YXJnZXQgfHxcbiAgICAgICAgICAgICFyZXF1ZXN0LnRhcmdldCB8fFxuICAgICAgICAgICAgIXJlcXVlc3QucGFyZW50UmVxdWVzdC50YXJnZXQubWF0Y2hlc0FycmF5KHJlcXVlc3QudGFyZ2V0LnNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgaWYgKHRhcmdldElzQW5BcnJheSAmJiB0YXJnZXRQYXJlbnRJc05vdEFuQXJyYXkpIHtcbiAgICAgICAgICAgIHJldHVybiBjaGlsZFJlcXVlc3RzLm1hcChmdW5jdGlvbiAoY2hpbGRSZXF1ZXN0KSB7XG4gICAgICAgICAgICAgICAgdmFyIF9mID0gX3Jlc29sdmVSZXF1ZXN0KHJlcXVlc3RTY29wZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9mKGNoaWxkUmVxdWVzdCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBudWxsO1xuICAgICAgICAgICAgaWYgKHJlcXVlc3QudGFyZ2V0LmlzT3B0aW9uYWwoKSAmJiBiaW5kaW5ncy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGJpbmRpbmdfMSA9IGJpbmRpbmdzWzBdO1xuICAgICAgICAgICAgdmFyIGlzU2luZ2xldG9uID0gYmluZGluZ18xLnNjb3BlID09PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5TaW5nbGV0b247XG4gICAgICAgICAgICB2YXIgaXNSZXF1ZXN0U2luZ2xldG9uID0gYmluZGluZ18xLnNjb3BlID09PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5SZXF1ZXN0O1xuICAgICAgICAgICAgaWYgKGlzU2luZ2xldG9uICYmIGJpbmRpbmdfMS5hY3RpdmF0ZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYmluZGluZ18xLmNhY2hlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzUmVxdWVzdFNpbmdsZXRvbiAmJlxuICAgICAgICAgICAgICAgIHJlcXVlc3RTY29wZSAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgIHJlcXVlc3RTY29wZS5oYXMoYmluZGluZ18xLmlkKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXF1ZXN0U2NvcGUuZ2V0KGJpbmRpbmdfMS5pZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYmluZGluZ18xLnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uQ29uc3RhbnRWYWx1ZSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGJpbmRpbmdfMS5jYWNoZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGJpbmRpbmdfMS50eXBlID09PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLkZ1bmN0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gYmluZGluZ18xLmNhY2hlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYmluZGluZ18xLnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uQ29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBiaW5kaW5nXzEuaW1wbGVtZW50YXRpb25UeXBlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYmluZGluZ18xLnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uRHluYW1pY1ZhbHVlICYmIGJpbmRpbmdfMS5keW5hbWljVmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBpbnZva2VGYWN0b3J5KFwidG9EeW5hbWljVmFsdWVcIiwgYmluZGluZ18xLnNlcnZpY2VJZGVudGlmaWVyLCBmdW5jdGlvbiAoKSB7IHJldHVybiBiaW5kaW5nXzEuZHluYW1pY1ZhbHVlKHJlcXVlc3QucGFyZW50Q29udGV4dCk7IH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYmluZGluZ18xLnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uRmFjdG9yeSAmJiBiaW5kaW5nXzEuZmFjdG9yeSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGludm9rZUZhY3RvcnkoXCJ0b0ZhY3RvcnlcIiwgYmluZGluZ18xLnNlcnZpY2VJZGVudGlmaWVyLCBmdW5jdGlvbiAoKSB7IHJldHVybiBiaW5kaW5nXzEuZmFjdG9yeShyZXF1ZXN0LnBhcmVudENvbnRleHQpOyB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGJpbmRpbmdfMS50eXBlID09PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLlByb3ZpZGVyICYmIGJpbmRpbmdfMS5wcm92aWRlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGludm9rZUZhY3RvcnkoXCJ0b1Byb3ZpZGVyXCIsIGJpbmRpbmdfMS5zZXJ2aWNlSWRlbnRpZmllciwgZnVuY3Rpb24gKCkgeyByZXR1cm4gYmluZGluZ18xLnByb3ZpZGVyKHJlcXVlc3QucGFyZW50Q29udGV4dCk7IH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYmluZGluZ18xLnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uSW5zdGFuY2UgJiYgYmluZGluZ18xLmltcGxlbWVudGF0aW9uVHlwZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGluc3RhbnRpYXRpb25fMS5yZXNvbHZlSW5zdGFuY2UoYmluZGluZ18xLmltcGxlbWVudGF0aW9uVHlwZSwgY2hpbGRSZXF1ZXN0cywgX3Jlc29sdmVSZXF1ZXN0KHJlcXVlc3RTY29wZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFyIHNlcnZpY2VJZGVudGlmaWVyID0gc2VyaWFsaXphdGlvbl8xLmdldFNlcnZpY2VJZGVudGlmaWVyQXNTdHJpbmcocmVxdWVzdC5zZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuSU5WQUxJRF9CSU5ESU5HX1RZUEUgKyBcIiBcIiArIHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlb2YgYmluZGluZ18xLm9uQWN0aXZhdGlvbiA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gYmluZGluZ18xLm9uQWN0aXZhdGlvbihyZXF1ZXN0LnBhcmVudENvbnRleHQsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNTaW5nbGV0b24pIHtcbiAgICAgICAgICAgICAgICBiaW5kaW5nXzEuY2FjaGUgPSByZXN1bHQ7XG4gICAgICAgICAgICAgICAgYmluZGluZ18xLmFjdGl2YXRlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNSZXF1ZXN0U2luZ2xldG9uICYmXG4gICAgICAgICAgICAgICAgcmVxdWVzdFNjb3BlICE9PSBudWxsICYmXG4gICAgICAgICAgICAgICAgIXJlcXVlc3RTY29wZS5oYXMoYmluZGluZ18xLmlkKSkge1xuICAgICAgICAgICAgICAgIHJlcXVlc3RTY29wZS5zZXQoYmluZGluZ18xLmlkLCByZXN1bHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZnVuY3Rpb24gcmVzb2x2ZShjb250ZXh0KSB7XG4gICAgdmFyIF9mID0gX3Jlc29sdmVSZXF1ZXN0KGNvbnRleHQucGxhbi5yb290UmVxdWVzdC5yZXF1ZXN0U2NvcGUpO1xuICAgIHJldHVybiBfZihjb250ZXh0LnBsYW4ucm9vdFJlcXVlc3QpO1xufVxuZXhwb3J0cy5yZXNvbHZlID0gcmVzb2x2ZTtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5CaW5kaW5nSW5TeW50YXggPSB2b2lkIDA7XG52YXIgbGl0ZXJhbF90eXBlc18xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9saXRlcmFsX3R5cGVzXCIpO1xudmFyIGJpbmRpbmdfd2hlbl9vbl9zeW50YXhfMSA9IHJlcXVpcmUoXCIuL2JpbmRpbmdfd2hlbl9vbl9zeW50YXhcIik7XG52YXIgQmluZGluZ0luU3ludGF4ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBCaW5kaW5nSW5TeW50YXgoYmluZGluZykge1xuICAgICAgICB0aGlzLl9iaW5kaW5nID0gYmluZGluZztcbiAgICB9XG4gICAgQmluZGluZ0luU3ludGF4LnByb3RvdHlwZS5pblJlcXVlc3RTY29wZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5zY29wZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nU2NvcGVFbnVtLlJlcXVlc3Q7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ193aGVuX29uX3N5bnRheF8xLkJpbmRpbmdXaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5TeW50YXgucHJvdG90eXBlLmluU2luZ2xldG9uU2NvcGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuc2NvcGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5TaW5nbGV0b247XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ193aGVuX29uX3N5bnRheF8xLkJpbmRpbmdXaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5TeW50YXgucHJvdG90eXBlLmluVHJhbnNpZW50U2NvcGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuc2NvcGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5UcmFuc2llbnQ7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ193aGVuX29uX3N5bnRheF8xLkJpbmRpbmdXaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICByZXR1cm4gQmluZGluZ0luU3ludGF4O1xufSgpKTtcbmV4cG9ydHMuQmluZGluZ0luU3ludGF4ID0gQmluZGluZ0luU3ludGF4O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkJpbmRpbmdJbldoZW5PblN5bnRheCA9IHZvaWQgMDtcbnZhciBiaW5kaW5nX2luX3N5bnRheF8xID0gcmVxdWlyZShcIi4vYmluZGluZ19pbl9zeW50YXhcIik7XG52YXIgYmluZGluZ19vbl9zeW50YXhfMSA9IHJlcXVpcmUoXCIuL2JpbmRpbmdfb25fc3ludGF4XCIpO1xudmFyIGJpbmRpbmdfd2hlbl9zeW50YXhfMSA9IHJlcXVpcmUoXCIuL2JpbmRpbmdfd2hlbl9zeW50YXhcIik7XG52YXIgQmluZGluZ0luV2hlbk9uU3ludGF4ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBCaW5kaW5nSW5XaGVuT25TeW50YXgoYmluZGluZykge1xuICAgICAgICB0aGlzLl9iaW5kaW5nID0gYmluZGluZztcbiAgICAgICAgdGhpcy5fYmluZGluZ1doZW5TeW50YXggPSBuZXcgYmluZGluZ193aGVuX3N5bnRheF8xLkJpbmRpbmdXaGVuU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgICAgICB0aGlzLl9iaW5kaW5nT25TeW50YXggPSBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgICAgIHRoaXMuX2JpbmRpbmdJblN5bnRheCA9IG5ldyBiaW5kaW5nX2luX3N5bnRheF8xLkJpbmRpbmdJblN5bnRheChiaW5kaW5nKTtcbiAgICB9XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS5pblJlcXVlc3RTY29wZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdJblN5bnRheC5pblJlcXVlc3RTY29wZSgpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS5pblNpbmdsZXRvblNjb3BlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ0luU3ludGF4LmluU2luZ2xldG9uU2NvcGUoKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUuaW5UcmFuc2llbnRTY29wZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdJblN5bnRheC5pblRyYW5zaWVudFNjb3BlKCk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW4gPSBmdW5jdGlvbiAoY29uc3RyYWludCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbihjb25zdHJhaW50KTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlblRhcmdldE5hbWVkID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5UYXJnZXROYW1lZChuYW1lKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlblRhcmdldElzRGVmYXVsdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5UYXJnZXRJc0RlZmF1bHQoKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlblRhcmdldFRhZ2dlZCA9IGZ1bmN0aW9uICh0YWcsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuVGFyZ2V0VGFnZ2VkKHRhZywgdmFsdWUpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuSW5qZWN0ZWRJbnRvID0gZnVuY3Rpb24gKHBhcmVudCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbkluamVjdGVkSW50byhwYXJlbnQpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuUGFyZW50TmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlblBhcmVudE5hbWVkKG5hbWUpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuUGFyZW50VGFnZ2VkID0gZnVuY3Rpb24gKHRhZywgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5QYXJlbnRUYWdnZWQodGFnLCB2YWx1ZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5BbnlBbmNlc3RvcklzID0gZnVuY3Rpb24gKGFuY2VzdG9yKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuQW55QW5jZXN0b3JJcyhhbmNlc3Rvcik7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5Ob0FuY2VzdG9ySXMgPSBmdW5jdGlvbiAoYW5jZXN0b3IpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5Ob0FuY2VzdG9ySXMoYW5jZXN0b3IpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JOYW1lZCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuQW55QW5jZXN0b3JOYW1lZChuYW1lKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9yVGFnZ2VkID0gZnVuY3Rpb24gKHRhZywgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5BbnlBbmNlc3RvclRhZ2dlZCh0YWcsIHZhbHVlKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlbk5vQW5jZXN0b3JOYW1lZCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuTm9BbmNlc3Rvck5hbWVkKG5hbWUpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuTm9BbmNlc3RvclRhZ2dlZCA9IGZ1bmN0aW9uICh0YWcsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuTm9BbmNlc3RvclRhZ2dlZCh0YWcsIHZhbHVlKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9yTWF0Y2hlcyA9IGZ1bmN0aW9uIChjb25zdHJhaW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuQW55QW5jZXN0b3JNYXRjaGVzKGNvbnN0cmFpbnQpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuTm9BbmNlc3Rvck1hdGNoZXMgPSBmdW5jdGlvbiAoY29uc3RyYWludCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbk5vQW5jZXN0b3JNYXRjaGVzKGNvbnN0cmFpbnQpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS5vbkFjdGl2YXRpb24gPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ09uU3ludGF4Lm9uQWN0aXZhdGlvbihoYW5kbGVyKTtcbiAgICB9O1xuICAgIHJldHVybiBCaW5kaW5nSW5XaGVuT25TeW50YXg7XG59KCkpO1xuZXhwb3J0cy5CaW5kaW5nSW5XaGVuT25TeW50YXggPSBCaW5kaW5nSW5XaGVuT25TeW50YXg7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQmluZGluZ09uU3ludGF4ID0gdm9pZCAwO1xudmFyIGJpbmRpbmdfd2hlbl9zeW50YXhfMSA9IHJlcXVpcmUoXCIuL2JpbmRpbmdfd2hlbl9zeW50YXhcIik7XG52YXIgQmluZGluZ09uU3ludGF4ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBCaW5kaW5nT25TeW50YXgoYmluZGluZykge1xuICAgICAgICB0aGlzLl9iaW5kaW5nID0gYmluZGluZztcbiAgICB9XG4gICAgQmluZGluZ09uU3ludGF4LnByb3RvdHlwZS5vbkFjdGl2YXRpb24gPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLm9uQWN0aXZhdGlvbiA9IGhhbmRsZXI7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ193aGVuX3N5bnRheF8xLkJpbmRpbmdXaGVuU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgcmV0dXJuIEJpbmRpbmdPblN5bnRheDtcbn0oKSk7XG5leHBvcnRzLkJpbmRpbmdPblN5bnRheCA9IEJpbmRpbmdPblN5bnRheDtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5CaW5kaW5nVG9TeW50YXggPSB2b2lkIDA7XG52YXIgRVJST1JfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbnZhciBsaXRlcmFsX3R5cGVzXzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2xpdGVyYWxfdHlwZXNcIik7XG52YXIgYmluZGluZ19pbl93aGVuX29uX3N5bnRheF8xID0gcmVxdWlyZShcIi4vYmluZGluZ19pbl93aGVuX29uX3N5bnRheFwiKTtcbnZhciBiaW5kaW5nX3doZW5fb25fc3ludGF4XzEgPSByZXF1aXJlKFwiLi9iaW5kaW5nX3doZW5fb25fc3ludGF4XCIpO1xudmFyIEJpbmRpbmdUb1N5bnRheCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQmluZGluZ1RvU3ludGF4KGJpbmRpbmcpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZyA9IGJpbmRpbmc7XG4gICAgfVxuICAgIEJpbmRpbmdUb1N5bnRheC5wcm90b3R5cGUudG8gPSBmdW5jdGlvbiAoY29uc3RydWN0b3IpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy50eXBlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5JbnN0YW5jZTtcbiAgICAgICAgdGhpcy5fYmluZGluZy5pbXBsZW1lbnRhdGlvblR5cGUgPSBjb25zdHJ1Y3RvcjtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX2luX3doZW5fb25fc3ludGF4XzEuQmluZGluZ0luV2hlbk9uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1RvU3ludGF4LnByb3RvdHlwZS50b1NlbGYgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fYmluZGluZy5zZXJ2aWNlSWRlbnRpZmllciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJcIiArIEVSUk9SX01TR1MuSU5WQUxJRF9UT19TRUxGX1ZBTFVFKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc2VsZiA9IHRoaXMuX2JpbmRpbmcuc2VydmljZUlkZW50aWZpZXI7XG4gICAgICAgIHJldHVybiB0aGlzLnRvKHNlbGYpO1xuICAgIH07XG4gICAgQmluZGluZ1RvU3ludGF4LnByb3RvdHlwZS50b0NvbnN0YW50VmFsdWUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy50eXBlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5Db25zdGFudFZhbHVlO1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNhY2hlID0gdmFsdWU7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuZHluYW1pY1ZhbHVlID0gbnVsbDtcbiAgICAgICAgdGhpcy5fYmluZGluZy5pbXBsZW1lbnRhdGlvblR5cGUgPSBudWxsO1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfd2hlbl9vbl9zeW50YXhfMS5CaW5kaW5nV2hlbk9uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1RvU3ludGF4LnByb3RvdHlwZS50b0R5bmFtaWNWYWx1ZSA9IGZ1bmN0aW9uIChmdW5jKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcudHlwZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uRHluYW1pY1ZhbHVlO1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNhY2hlID0gbnVsbDtcbiAgICAgICAgdGhpcy5fYmluZGluZy5keW5hbWljVmFsdWUgPSBmdW5jO1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmltcGxlbWVudGF0aW9uVHlwZSA9IG51bGw7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19pbl93aGVuX29uX3N5bnRheF8xLkJpbmRpbmdJbldoZW5PblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdUb1N5bnRheC5wcm90b3R5cGUudG9Db25zdHJ1Y3RvciA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLnR5cGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLkNvbnN0cnVjdG9yO1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmltcGxlbWVudGF0aW9uVHlwZSA9IGNvbnN0cnVjdG9yO1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfd2hlbl9vbl9zeW50YXhfMS5CaW5kaW5nV2hlbk9uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1RvU3ludGF4LnByb3RvdHlwZS50b0ZhY3RvcnkgPSBmdW5jdGlvbiAoZmFjdG9yeSkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLnR5cGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLkZhY3Rvcnk7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuZmFjdG9yeSA9IGZhY3Rvcnk7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ193aGVuX29uX3N5bnRheF8xLkJpbmRpbmdXaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nVG9TeW50YXgucHJvdG90eXBlLnRvRnVuY3Rpb24gPSBmdW5jdGlvbiAoZnVuYykge1xuICAgICAgICBpZiAodHlwZW9mIGZ1bmMgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuSU5WQUxJRF9GVU5DVElPTl9CSU5ESU5HKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgYmluZGluZ1doZW5PblN5bnRheCA9IHRoaXMudG9Db25zdGFudFZhbHVlKGZ1bmMpO1xuICAgICAgICB0aGlzLl9iaW5kaW5nLnR5cGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLkZ1bmN0aW9uO1xuICAgICAgICByZXR1cm4gYmluZGluZ1doZW5PblN5bnRheDtcbiAgICB9O1xuICAgIEJpbmRpbmdUb1N5bnRheC5wcm90b3R5cGUudG9BdXRvRmFjdG9yeSA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLnR5cGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLkZhY3Rvcnk7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuZmFjdG9yeSA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICAgICAgICB2YXIgYXV0b2ZhY3RvcnkgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBjb250ZXh0LmNvbnRhaW5lci5nZXQoc2VydmljZUlkZW50aWZpZXIpOyB9O1xuICAgICAgICAgICAgcmV0dXJuIGF1dG9mYWN0b3J5O1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfd2hlbl9vbl9zeW50YXhfMS5CaW5kaW5nV2hlbk9uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1RvU3ludGF4LnByb3RvdHlwZS50b1Byb3ZpZGVyID0gZnVuY3Rpb24gKHByb3ZpZGVyKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcudHlwZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uUHJvdmlkZXI7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcucHJvdmlkZXIgPSBwcm92aWRlcjtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX3doZW5fb25fc3ludGF4XzEuQmluZGluZ1doZW5PblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdUb1N5bnRheC5wcm90b3R5cGUudG9TZXJ2aWNlID0gZnVuY3Rpb24gKHNlcnZpY2UpIHtcbiAgICAgICAgdGhpcy50b0R5bmFtaWNWYWx1ZShmdW5jdGlvbiAoY29udGV4dCkgeyByZXR1cm4gY29udGV4dC5jb250YWluZXIuZ2V0KHNlcnZpY2UpOyB9KTtcbiAgICB9O1xuICAgIHJldHVybiBCaW5kaW5nVG9TeW50YXg7XG59KCkpO1xuZXhwb3J0cy5CaW5kaW5nVG9TeW50YXggPSBCaW5kaW5nVG9TeW50YXg7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQmluZGluZ1doZW5PblN5bnRheCA9IHZvaWQgMDtcbnZhciBiaW5kaW5nX29uX3N5bnRheF8xID0gcmVxdWlyZShcIi4vYmluZGluZ19vbl9zeW50YXhcIik7XG52YXIgYmluZGluZ193aGVuX3N5bnRheF8xID0gcmVxdWlyZShcIi4vYmluZGluZ193aGVuX3N5bnRheFwiKTtcbnZhciBCaW5kaW5nV2hlbk9uU3ludGF4ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBCaW5kaW5nV2hlbk9uU3ludGF4KGJpbmRpbmcpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZyA9IGJpbmRpbmc7XG4gICAgICAgIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4ID0gbmV3IGJpbmRpbmdfd2hlbl9zeW50YXhfMS5CaW5kaW5nV2hlblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICAgICAgdGhpcy5fYmluZGluZ09uU3ludGF4ID0gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH1cbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuID0gZnVuY3Rpb24gKGNvbnN0cmFpbnQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW4oY29uc3RyYWludCk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuVGFyZ2V0TmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlblRhcmdldE5hbWVkKG5hbWUpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlblRhcmdldElzRGVmYXVsdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5UYXJnZXRJc0RlZmF1bHQoKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5UYXJnZXRUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlblRhcmdldFRhZ2dlZCh0YWcsIHZhbHVlKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5JbmplY3RlZEludG8gPSBmdW5jdGlvbiAocGFyZW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuSW5qZWN0ZWRJbnRvKHBhcmVudCk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuUGFyZW50TmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlblBhcmVudE5hbWVkKG5hbWUpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlblBhcmVudFRhZ2dlZCA9IGZ1bmN0aW9uICh0YWcsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuUGFyZW50VGFnZ2VkKHRhZywgdmFsdWUpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9ySXMgPSBmdW5jdGlvbiAoYW5jZXN0b3IpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5BbnlBbmNlc3RvcklzKGFuY2VzdG9yKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5Ob0FuY2VzdG9ySXMgPSBmdW5jdGlvbiAoYW5jZXN0b3IpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5Ob0FuY2VzdG9ySXMoYW5jZXN0b3IpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9yTmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbkFueUFuY2VzdG9yTmFtZWQobmFtZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbkFueUFuY2VzdG9yVGFnZ2VkKHRhZywgdmFsdWUpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlbk5vQW5jZXN0b3JOYW1lZCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuTm9BbmNlc3Rvck5hbWVkKG5hbWUpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlbk5vQW5jZXN0b3JUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbk5vQW5jZXN0b3JUYWdnZWQodGFnLCB2YWx1ZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JNYXRjaGVzID0gZnVuY3Rpb24gKGNvbnN0cmFpbnQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5BbnlBbmNlc3Rvck1hdGNoZXMoY29uc3RyYWludCk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuTm9BbmNlc3Rvck1hdGNoZXMgPSBmdW5jdGlvbiAoY29uc3RyYWludCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbk5vQW5jZXN0b3JNYXRjaGVzKGNvbnN0cmFpbnQpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUub25BY3RpdmF0aW9uID0gZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdPblN5bnRheC5vbkFjdGl2YXRpb24oaGFuZGxlcik7XG4gICAgfTtcbiAgICByZXR1cm4gQmluZGluZ1doZW5PblN5bnRheDtcbn0oKSk7XG5leHBvcnRzLkJpbmRpbmdXaGVuT25TeW50YXggPSBCaW5kaW5nV2hlbk9uU3ludGF4O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkJpbmRpbmdXaGVuU3ludGF4ID0gdm9pZCAwO1xudmFyIGJpbmRpbmdfb25fc3ludGF4XzEgPSByZXF1aXJlKFwiLi9iaW5kaW5nX29uX3N5bnRheFwiKTtcbnZhciBjb25zdHJhaW50X2hlbHBlcnNfMSA9IHJlcXVpcmUoXCIuL2NvbnN0cmFpbnRfaGVscGVyc1wiKTtcbnZhciBCaW5kaW5nV2hlblN5bnRheCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQmluZGluZ1doZW5TeW50YXgoYmluZGluZykge1xuICAgICAgICB0aGlzLl9iaW5kaW5nID0gYmluZGluZztcbiAgICB9XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW4gPSBmdW5jdGlvbiAoY29uc3RyYWludCkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBjb25zdHJhaW50O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5UYXJnZXROYW1lZCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGNvbnN0cmFpbnRfaGVscGVyc18xLm5hbWVkQ29uc3RyYWludChuYW1lKTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuVGFyZ2V0SXNEZWZhdWx0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgdmFyIHRhcmdldElzRGVmYXVsdCA9IChyZXF1ZXN0LnRhcmdldCAhPT0gbnVsbCkgJiZcbiAgICAgICAgICAgICAgICAoIXJlcXVlc3QudGFyZ2V0LmlzTmFtZWQoKSkgJiZcbiAgICAgICAgICAgICAgICAoIXJlcXVlc3QudGFyZ2V0LmlzVGFnZ2VkKCkpO1xuICAgICAgICAgICAgcmV0dXJuIHRhcmdldElzRGVmYXVsdDtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuVGFyZ2V0VGFnZ2VkID0gZnVuY3Rpb24gKHRhZywgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gY29uc3RyYWludF9oZWxwZXJzXzEudGFnZ2VkQ29uc3RyYWludCh0YWcpKHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuSW5qZWN0ZWRJbnRvID0gZnVuY3Rpb24gKHBhcmVudCkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRfaGVscGVyc18xLnR5cGVDb25zdHJhaW50KHBhcmVudCkocmVxdWVzdC5wYXJlbnRSZXF1ZXN0KTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuUGFyZW50TmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRfaGVscGVyc18xLm5hbWVkQ29uc3RyYWludChuYW1lKShyZXF1ZXN0LnBhcmVudFJlcXVlc3QpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5QYXJlbnRUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRfaGVscGVyc18xLnRhZ2dlZENvbnN0cmFpbnQodGFnKSh2YWx1ZSkocmVxdWVzdC5wYXJlbnRSZXF1ZXN0KTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JJcyA9IGZ1bmN0aW9uIChhbmNlc3Rvcikge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRfaGVscGVyc18xLnRyYXZlcnNlQW5jZXJzdG9ycyhyZXF1ZXN0LCBjb25zdHJhaW50X2hlbHBlcnNfMS50eXBlQ29uc3RyYWludChhbmNlc3RvcikpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5Ob0FuY2VzdG9ySXMgPSBmdW5jdGlvbiAoYW5jZXN0b3IpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgICAgIHJldHVybiAhY29uc3RyYWludF9oZWxwZXJzXzEudHJhdmVyc2VBbmNlcnN0b3JzKHJlcXVlc3QsIGNvbnN0cmFpbnRfaGVscGVyc18xLnR5cGVDb25zdHJhaW50KGFuY2VzdG9yKSk7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9yTmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRfaGVscGVyc18xLnRyYXZlcnNlQW5jZXJzdG9ycyhyZXF1ZXN0LCBjb25zdHJhaW50X2hlbHBlcnNfMS5uYW1lZENvbnN0cmFpbnQobmFtZSkpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5Ob0FuY2VzdG9yTmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuICFjb25zdHJhaW50X2hlbHBlcnNfMS50cmF2ZXJzZUFuY2Vyc3RvcnMocmVxdWVzdCwgY29uc3RyYWludF9oZWxwZXJzXzEubmFtZWRDb25zdHJhaW50KG5hbWUpKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRfaGVscGVyc18xLnRyYXZlcnNlQW5jZXJzdG9ycyhyZXF1ZXN0LCBjb25zdHJhaW50X2hlbHBlcnNfMS50YWdnZWRDb25zdHJhaW50KHRhZykodmFsdWUpKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuTm9BbmNlc3RvclRhZ2dlZCA9IGZ1bmN0aW9uICh0YWcsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gIWNvbnN0cmFpbnRfaGVscGVyc18xLnRyYXZlcnNlQW5jZXJzdG9ycyhyZXF1ZXN0LCBjb25zdHJhaW50X2hlbHBlcnNfMS50YWdnZWRDb25zdHJhaW50KHRhZykodmFsdWUpKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JNYXRjaGVzID0gZnVuY3Rpb24gKGNvbnN0cmFpbnQpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgICAgIHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS50cmF2ZXJzZUFuY2Vyc3RvcnMocmVxdWVzdCwgY29uc3RyYWludCk7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlbk5vQW5jZXN0b3JNYXRjaGVzID0gZnVuY3Rpb24gKGNvbnN0cmFpbnQpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgICAgIHJldHVybiAhY29uc3RyYWludF9oZWxwZXJzXzEudHJhdmVyc2VBbmNlcnN0b3JzKHJlcXVlc3QsIGNvbnN0cmFpbnQpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgcmV0dXJuIEJpbmRpbmdXaGVuU3ludGF4O1xufSgpKTtcbmV4cG9ydHMuQmluZGluZ1doZW5TeW50YXggPSBCaW5kaW5nV2hlblN5bnRheDtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy50eXBlQ29uc3RyYWludCA9IGV4cG9ydHMubmFtZWRDb25zdHJhaW50ID0gZXhwb3J0cy50YWdnZWRDb25zdHJhaW50ID0gZXhwb3J0cy50cmF2ZXJzZUFuY2Vyc3RvcnMgPSB2b2lkIDA7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFcIik7XG52YXIgdHJhdmVyc2VBbmNlcnN0b3JzID0gZnVuY3Rpb24gKHJlcXVlc3QsIGNvbnN0cmFpbnQpIHtcbiAgICB2YXIgcGFyZW50ID0gcmVxdWVzdC5wYXJlbnRSZXF1ZXN0O1xuICAgIGlmIChwYXJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnQocGFyZW50KSA/IHRydWUgOiB0cmF2ZXJzZUFuY2Vyc3RvcnMocGFyZW50LCBjb25zdHJhaW50KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59O1xuZXhwb3J0cy50cmF2ZXJzZUFuY2Vyc3RvcnMgPSB0cmF2ZXJzZUFuY2Vyc3RvcnM7XG52YXIgdGFnZ2VkQ29uc3RyYWludCA9IGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHZhciBjb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgcmV0dXJuIHJlcXVlc3QgIT09IG51bGwgJiYgcmVxdWVzdC50YXJnZXQgIT09IG51bGwgJiYgcmVxdWVzdC50YXJnZXQubWF0Y2hlc1RhZyhrZXkpKHZhbHVlKTtcbiAgICB9O1xuICAgIGNvbnN0cmFpbnQubWV0YURhdGEgPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShrZXksIHZhbHVlKTtcbiAgICByZXR1cm4gY29uc3RyYWludDtcbn07IH07XG5leHBvcnRzLnRhZ2dlZENvbnN0cmFpbnQgPSB0YWdnZWRDb25zdHJhaW50O1xudmFyIG5hbWVkQ29uc3RyYWludCA9IHRhZ2dlZENvbnN0cmFpbnQoTUVUQURBVEFfS0VZLk5BTUVEX1RBRyk7XG5leHBvcnRzLm5hbWVkQ29uc3RyYWludCA9IG5hbWVkQ29uc3RyYWludDtcbnZhciB0eXBlQ29uc3RyYWludCA9IGZ1bmN0aW9uICh0eXBlKSB7IHJldHVybiBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgIHZhciBiaW5kaW5nID0gbnVsbDtcbiAgICBpZiAocmVxdWVzdCAhPT0gbnVsbCkge1xuICAgICAgICBiaW5kaW5nID0gcmVxdWVzdC5iaW5kaW5nc1swXTtcbiAgICAgICAgaWYgKHR5cGVvZiB0eXBlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB2YXIgc2VydmljZUlkZW50aWZpZXIgPSBiaW5kaW5nLnNlcnZpY2VJZGVudGlmaWVyO1xuICAgICAgICAgICAgcmV0dXJuIHNlcnZpY2VJZGVudGlmaWVyID09PSB0eXBlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIGNvbnN0cnVjdG9yID0gcmVxdWVzdC5iaW5kaW5nc1swXS5pbXBsZW1lbnRhdGlvblR5cGU7XG4gICAgICAgICAgICByZXR1cm4gdHlwZSA9PT0gY29uc3RydWN0b3I7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTsgfTtcbmV4cG9ydHMudHlwZUNvbnN0cmFpbnQgPSB0eXBlQ29uc3RyYWludDtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5tdWx0aUJpbmRUb1NlcnZpY2UgPSB2b2lkIDA7XG5leHBvcnRzLm11bHRpQmluZFRvU2VydmljZSA9IGZ1bmN0aW9uIChjb250YWluZXIpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHNlcnZpY2UpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciB0eXBlcyA9IFtdO1xuICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgICAgICB0eXBlc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHR5cGVzLmZvckVhY2goZnVuY3Rpb24gKHQpIHsgcmV0dXJuIGNvbnRhaW5lci5iaW5kKHQpLnRvU2VydmljZShzZXJ2aWNlKTsgfSk7XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuaXNTdGFja092ZXJmbG93RXhlcHRpb24gPSB2b2lkIDA7XG52YXIgRVJST1JfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbmZ1bmN0aW9uIGlzU3RhY2tPdmVyZmxvd0V4ZXB0aW9uKGVycm9yKSB7XG4gICAgcmV0dXJuIChlcnJvciBpbnN0YW5jZW9mIFJhbmdlRXJyb3IgfHxcbiAgICAgICAgZXJyb3IubWVzc2FnZSA9PT0gRVJST1JfTVNHUy5TVEFDS19PVkVSRkxPVyk7XG59XG5leHBvcnRzLmlzU3RhY2tPdmVyZmxvd0V4ZXB0aW9uID0gaXNTdGFja092ZXJmbG93RXhlcHRpb247XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuaWQgPSB2b2lkIDA7XG52YXIgaWRDb3VudGVyID0gMDtcbmZ1bmN0aW9uIGlkKCkge1xuICAgIHJldHVybiBpZENvdW50ZXIrKztcbn1cbmV4cG9ydHMuaWQgPSBpZDtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5jaXJjdWxhckRlcGVuZGVuY3lUb0V4Y2VwdGlvbiA9IGV4cG9ydHMubGlzdE1ldGFkYXRhRm9yVGFyZ2V0ID0gZXhwb3J0cy5saXN0UmVnaXN0ZXJlZEJpbmRpbmdzRm9yU2VydmljZUlkZW50aWZpZXIgPSBleHBvcnRzLmdldFNlcnZpY2VJZGVudGlmaWVyQXNTdHJpbmcgPSBleHBvcnRzLmdldEZ1bmN0aW9uTmFtZSA9IHZvaWQgMDtcbnZhciBFUlJPUl9NU0dTID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xuZnVuY3Rpb24gZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZyhzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgIGlmICh0eXBlb2Ygc2VydmljZUlkZW50aWZpZXIgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB2YXIgX3NlcnZpY2VJZGVudGlmaWVyID0gc2VydmljZUlkZW50aWZpZXI7XG4gICAgICAgIHJldHVybiBfc2VydmljZUlkZW50aWZpZXIubmFtZTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIHNlcnZpY2VJZGVudGlmaWVyID09PSBcInN5bWJvbFwiKSB7XG4gICAgICAgIHJldHVybiBzZXJ2aWNlSWRlbnRpZmllci50b1N0cmluZygpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIF9zZXJ2aWNlSWRlbnRpZmllciA9IHNlcnZpY2VJZGVudGlmaWVyO1xuICAgICAgICByZXR1cm4gX3NlcnZpY2VJZGVudGlmaWVyO1xuICAgIH1cbn1cbmV4cG9ydHMuZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZyA9IGdldFNlcnZpY2VJZGVudGlmaWVyQXNTdHJpbmc7XG5mdW5jdGlvbiBsaXN0UmVnaXN0ZXJlZEJpbmRpbmdzRm9yU2VydmljZUlkZW50aWZpZXIoY29udGFpbmVyLCBzZXJ2aWNlSWRlbnRpZmllciwgZ2V0QmluZGluZ3MpIHtcbiAgICB2YXIgcmVnaXN0ZXJlZEJpbmRpbmdzTGlzdCA9IFwiXCI7XG4gICAgdmFyIHJlZ2lzdGVyZWRCaW5kaW5ncyA9IGdldEJpbmRpbmdzKGNvbnRhaW5lciwgc2VydmljZUlkZW50aWZpZXIpO1xuICAgIGlmIChyZWdpc3RlcmVkQmluZGluZ3MubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgIHJlZ2lzdGVyZWRCaW5kaW5nc0xpc3QgPSBcIlxcblJlZ2lzdGVyZWQgYmluZGluZ3M6XCI7XG4gICAgICAgIHJlZ2lzdGVyZWRCaW5kaW5ncy5mb3JFYWNoKGZ1bmN0aW9uIChiaW5kaW5nKSB7XG4gICAgICAgICAgICB2YXIgbmFtZSA9IFwiT2JqZWN0XCI7XG4gICAgICAgICAgICBpZiAoYmluZGluZy5pbXBsZW1lbnRhdGlvblR5cGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBuYW1lID0gZ2V0RnVuY3Rpb25OYW1lKGJpbmRpbmcuaW1wbGVtZW50YXRpb25UeXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlZ2lzdGVyZWRCaW5kaW5nc0xpc3QgPSByZWdpc3RlcmVkQmluZGluZ3NMaXN0ICsgXCJcXG4gXCIgKyBuYW1lO1xuICAgICAgICAgICAgaWYgKGJpbmRpbmcuY29uc3RyYWludC5tZXRhRGF0YSkge1xuICAgICAgICAgICAgICAgIHJlZ2lzdGVyZWRCaW5kaW5nc0xpc3QgPSByZWdpc3RlcmVkQmluZGluZ3NMaXN0ICsgXCIgLSBcIiArIGJpbmRpbmcuY29uc3RyYWludC5tZXRhRGF0YTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByZWdpc3RlcmVkQmluZGluZ3NMaXN0O1xufVxuZXhwb3J0cy5saXN0UmVnaXN0ZXJlZEJpbmRpbmdzRm9yU2VydmljZUlkZW50aWZpZXIgPSBsaXN0UmVnaXN0ZXJlZEJpbmRpbmdzRm9yU2VydmljZUlkZW50aWZpZXI7XG5mdW5jdGlvbiBhbHJlYWR5RGVwZW5kZW5jeUNoYWluKHJlcXVlc3QsIHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgaWYgKHJlcXVlc3QucGFyZW50UmVxdWVzdCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGVsc2UgaWYgKHJlcXVlc3QucGFyZW50UmVxdWVzdC5zZXJ2aWNlSWRlbnRpZmllciA9PT0gc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gYWxyZWFkeURlcGVuZGVuY3lDaGFpbihyZXF1ZXN0LnBhcmVudFJlcXVlc3QsIHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICB9XG59XG5mdW5jdGlvbiBkZXBlbmRlbmN5Q2hhaW5Ub1N0cmluZyhyZXF1ZXN0KSB7XG4gICAgZnVuY3Rpb24gX2NyZWF0ZVN0cmluZ0FycihyZXEsIHJlc3VsdCkge1xuICAgICAgICBpZiAocmVzdWx0ID09PSB2b2lkIDApIHsgcmVzdWx0ID0gW107IH1cbiAgICAgICAgdmFyIHNlcnZpY2VJZGVudGlmaWVyID0gZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZyhyZXEuc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICByZXN1bHQucHVzaChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIGlmIChyZXEucGFyZW50UmVxdWVzdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIF9jcmVhdGVTdHJpbmdBcnIocmVxLnBhcmVudFJlcXVlc3QsIHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgdmFyIHN0cmluZ0FyciA9IF9jcmVhdGVTdHJpbmdBcnIocmVxdWVzdCk7XG4gICAgcmV0dXJuIHN0cmluZ0Fyci5yZXZlcnNlKCkuam9pbihcIiAtLT4gXCIpO1xufVxuZnVuY3Rpb24gY2lyY3VsYXJEZXBlbmRlbmN5VG9FeGNlcHRpb24ocmVxdWVzdCkge1xuICAgIHJlcXVlc3QuY2hpbGRSZXF1ZXN0cy5mb3JFYWNoKGZ1bmN0aW9uIChjaGlsZFJlcXVlc3QpIHtcbiAgICAgICAgaWYgKGFscmVhZHlEZXBlbmRlbmN5Q2hhaW4oY2hpbGRSZXF1ZXN0LCBjaGlsZFJlcXVlc3Quc2VydmljZUlkZW50aWZpZXIpKSB7XG4gICAgICAgICAgICB2YXIgc2VydmljZXMgPSBkZXBlbmRlbmN5Q2hhaW5Ub1N0cmluZyhjaGlsZFJlcXVlc3QpO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuQ0lSQ1VMQVJfREVQRU5ERU5DWSArIFwiIFwiICsgc2VydmljZXMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY2lyY3VsYXJEZXBlbmRlbmN5VG9FeGNlcHRpb24oY2hpbGRSZXF1ZXN0KTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZXhwb3J0cy5jaXJjdWxhckRlcGVuZGVuY3lUb0V4Y2VwdGlvbiA9IGNpcmN1bGFyRGVwZW5kZW5jeVRvRXhjZXB0aW9uO1xuZnVuY3Rpb24gbGlzdE1ldGFkYXRhRm9yVGFyZ2V0KHNlcnZpY2VJZGVudGlmaWVyU3RyaW5nLCB0YXJnZXQpIHtcbiAgICBpZiAodGFyZ2V0LmlzVGFnZ2VkKCkgfHwgdGFyZ2V0LmlzTmFtZWQoKSkge1xuICAgICAgICB2YXIgbV8xID0gXCJcIjtcbiAgICAgICAgdmFyIG5hbWVkVGFnID0gdGFyZ2V0LmdldE5hbWVkVGFnKCk7XG4gICAgICAgIHZhciBvdGhlclRhZ3MgPSB0YXJnZXQuZ2V0Q3VzdG9tVGFncygpO1xuICAgICAgICBpZiAobmFtZWRUYWcgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG1fMSArPSBuYW1lZFRhZy50b1N0cmluZygpICsgXCJcXG5cIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3RoZXJUYWdzICE9PSBudWxsKSB7XG4gICAgICAgICAgICBvdGhlclRhZ3MuZm9yRWFjaChmdW5jdGlvbiAodGFnKSB7XG4gICAgICAgICAgICAgICAgbV8xICs9IHRhZy50b1N0cmluZygpICsgXCJcXG5cIjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBcIiBcIiArIHNlcnZpY2VJZGVudGlmaWVyU3RyaW5nICsgXCJcXG4gXCIgKyBzZXJ2aWNlSWRlbnRpZmllclN0cmluZyArIFwiIC0gXCIgKyBtXzE7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gXCIgXCIgKyBzZXJ2aWNlSWRlbnRpZmllclN0cmluZztcbiAgICB9XG59XG5leHBvcnRzLmxpc3RNZXRhZGF0YUZvclRhcmdldCA9IGxpc3RNZXRhZGF0YUZvclRhcmdldDtcbmZ1bmN0aW9uIGdldEZ1bmN0aW9uTmFtZSh2KSB7XG4gICAgaWYgKHYubmFtZSkge1xuICAgICAgICByZXR1cm4gdi5uYW1lO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIG5hbWVfMSA9IHYudG9TdHJpbmcoKTtcbiAgICAgICAgdmFyIG1hdGNoID0gbmFtZV8xLm1hdGNoKC9eZnVuY3Rpb25cXHMqKFteXFxzKF0rKS8pO1xuICAgICAgICByZXR1cm4gbWF0Y2ggPyBtYXRjaFsxXSA6IFwiQW5vbnltb3VzIGZ1bmN0aW9uOiBcIiArIG5hbWVfMTtcbiAgICB9XG59XG5leHBvcnRzLmdldEZ1bmN0aW9uTmFtZSA9IGdldEZ1bmN0aW9uTmFtZTtcbiIsIm1vZHVsZS5leHBvcnRzID0gbWluaW1hdGNoXG5taW5pbWF0Y2guTWluaW1hdGNoID0gTWluaW1hdGNoXG5cbnZhciBwYXRoID0geyBzZXA6ICcvJyB9XG50cnkge1xuICBwYXRoID0gcmVxdWlyZSgncGF0aCcpXG59IGNhdGNoIChlcikge31cblxudmFyIEdMT0JTVEFSID0gbWluaW1hdGNoLkdMT0JTVEFSID0gTWluaW1hdGNoLkdMT0JTVEFSID0ge31cbnZhciBleHBhbmQgPSByZXF1aXJlKCdicmFjZS1leHBhbnNpb24nKVxuXG52YXIgcGxUeXBlcyA9IHtcbiAgJyEnOiB7IG9wZW46ICcoPzooPyEoPzonLCBjbG9zZTogJykpW14vXSo/KSd9LFxuICAnPyc6IHsgb3BlbjogJyg/OicsIGNsb3NlOiAnKT8nIH0sXG4gICcrJzogeyBvcGVuOiAnKD86JywgY2xvc2U6ICcpKycgfSxcbiAgJyonOiB7IG9wZW46ICcoPzonLCBjbG9zZTogJykqJyB9LFxuICAnQCc6IHsgb3BlbjogJyg/OicsIGNsb3NlOiAnKScgfVxufVxuXG4vLyBhbnkgc2luZ2xlIHRoaW5nIG90aGVyIHRoYW4gL1xuLy8gZG9uJ3QgbmVlZCB0byBlc2NhcGUgLyB3aGVuIHVzaW5nIG5ldyBSZWdFeHAoKVxudmFyIHFtYXJrID0gJ1teL10nXG5cbi8vICogPT4gYW55IG51bWJlciBvZiBjaGFyYWN0ZXJzXG52YXIgc3RhciA9IHFtYXJrICsgJyo/J1xuXG4vLyAqKiB3aGVuIGRvdHMgYXJlIGFsbG93ZWQuICBBbnl0aGluZyBnb2VzLCBleGNlcHQgLi4gYW5kIC5cbi8vIG5vdCAoXiBvciAvIGZvbGxvd2VkIGJ5IG9uZSBvciB0d28gZG90cyBmb2xsb3dlZCBieSAkIG9yIC8pLFxuLy8gZm9sbG93ZWQgYnkgYW55dGhpbmcsIGFueSBudW1iZXIgb2YgdGltZXMuXG52YXIgdHdvU3RhckRvdCA9ICcoPzooPyEoPzpcXFxcXFwvfF4pKD86XFxcXC57MSwyfSkoJHxcXFxcXFwvKSkuKSo/J1xuXG4vLyBub3QgYSBeIG9yIC8gZm9sbG93ZWQgYnkgYSBkb3QsXG4vLyBmb2xsb3dlZCBieSBhbnl0aGluZywgYW55IG51bWJlciBvZiB0aW1lcy5cbnZhciB0d29TdGFyTm9Eb3QgPSAnKD86KD8hKD86XFxcXFxcL3xeKVxcXFwuKS4pKj8nXG5cbi8vIGNoYXJhY3RlcnMgdGhhdCBuZWVkIHRvIGJlIGVzY2FwZWQgaW4gUmVnRXhwLlxudmFyIHJlU3BlY2lhbHMgPSBjaGFyU2V0KCcoKS4qe30rP1tdXiRcXFxcIScpXG5cbi8vIFwiYWJjXCIgLT4geyBhOnRydWUsIGI6dHJ1ZSwgYzp0cnVlIH1cbmZ1bmN0aW9uIGNoYXJTZXQgKHMpIHtcbiAgcmV0dXJuIHMuc3BsaXQoJycpLnJlZHVjZShmdW5jdGlvbiAoc2V0LCBjKSB7XG4gICAgc2V0W2NdID0gdHJ1ZVxuICAgIHJldHVybiBzZXRcbiAgfSwge30pXG59XG5cbi8vIG5vcm1hbGl6ZXMgc2xhc2hlcy5cbnZhciBzbGFzaFNwbGl0ID0gL1xcLysvXG5cbm1pbmltYXRjaC5maWx0ZXIgPSBmaWx0ZXJcbmZ1bmN0aW9uIGZpbHRlciAocGF0dGVybiwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICByZXR1cm4gZnVuY3Rpb24gKHAsIGksIGxpc3QpIHtcbiAgICByZXR1cm4gbWluaW1hdGNoKHAsIHBhdHRlcm4sIG9wdGlvbnMpXG4gIH1cbn1cblxuZnVuY3Rpb24gZXh0IChhLCBiKSB7XG4gIGEgPSBhIHx8IHt9XG4gIGIgPSBiIHx8IHt9XG4gIHZhciB0ID0ge31cbiAgT2JqZWN0LmtleXMoYikuZm9yRWFjaChmdW5jdGlvbiAoaykge1xuICAgIHRba10gPSBiW2tdXG4gIH0pXG4gIE9iamVjdC5rZXlzKGEpLmZvckVhY2goZnVuY3Rpb24gKGspIHtcbiAgICB0W2tdID0gYVtrXVxuICB9KVxuICByZXR1cm4gdFxufVxuXG5taW5pbWF0Y2guZGVmYXVsdHMgPSBmdW5jdGlvbiAoZGVmKSB7XG4gIGlmICghZGVmIHx8ICFPYmplY3Qua2V5cyhkZWYpLmxlbmd0aCkgcmV0dXJuIG1pbmltYXRjaFxuXG4gIHZhciBvcmlnID0gbWluaW1hdGNoXG5cbiAgdmFyIG0gPSBmdW5jdGlvbiBtaW5pbWF0Y2ggKHAsIHBhdHRlcm4sIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gb3JpZy5taW5pbWF0Y2gocCwgcGF0dGVybiwgZXh0KGRlZiwgb3B0aW9ucykpXG4gIH1cblxuICBtLk1pbmltYXRjaCA9IGZ1bmN0aW9uIE1pbmltYXRjaCAocGF0dGVybiwgb3B0aW9ucykge1xuICAgIHJldHVybiBuZXcgb3JpZy5NaW5pbWF0Y2gocGF0dGVybiwgZXh0KGRlZiwgb3B0aW9ucykpXG4gIH1cblxuICByZXR1cm4gbVxufVxuXG5NaW5pbWF0Y2guZGVmYXVsdHMgPSBmdW5jdGlvbiAoZGVmKSB7XG4gIGlmICghZGVmIHx8ICFPYmplY3Qua2V5cyhkZWYpLmxlbmd0aCkgcmV0dXJuIE1pbmltYXRjaFxuICByZXR1cm4gbWluaW1hdGNoLmRlZmF1bHRzKGRlZikuTWluaW1hdGNoXG59XG5cbmZ1bmN0aW9uIG1pbmltYXRjaCAocCwgcGF0dGVybiwgb3B0aW9ucykge1xuICBpZiAodHlwZW9mIHBhdHRlcm4gIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZ2xvYiBwYXR0ZXJuIHN0cmluZyByZXF1aXJlZCcpXG4gIH1cblxuICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fVxuXG4gIC8vIHNob3J0Y3V0OiBjb21tZW50cyBtYXRjaCBub3RoaW5nLlxuICBpZiAoIW9wdGlvbnMubm9jb21tZW50ICYmIHBhdHRlcm4uY2hhckF0KDApID09PSAnIycpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8vIFwiXCIgb25seSBtYXRjaGVzIFwiXCJcbiAgaWYgKHBhdHRlcm4udHJpbSgpID09PSAnJykgcmV0dXJuIHAgPT09ICcnXG5cbiAgcmV0dXJuIG5ldyBNaW5pbWF0Y2gocGF0dGVybiwgb3B0aW9ucykubWF0Y2gocClcbn1cblxuZnVuY3Rpb24gTWluaW1hdGNoIChwYXR0ZXJuLCBvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBNaW5pbWF0Y2gpKSB7XG4gICAgcmV0dXJuIG5ldyBNaW5pbWF0Y2gocGF0dGVybiwgb3B0aW9ucylcbiAgfVxuXG4gIGlmICh0eXBlb2YgcGF0dGVybiAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdnbG9iIHBhdHRlcm4gc3RyaW5nIHJlcXVpcmVkJylcbiAgfVxuXG4gIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9XG4gIHBhdHRlcm4gPSBwYXR0ZXJuLnRyaW0oKVxuXG4gIC8vIHdpbmRvd3Mgc3VwcG9ydDogbmVlZCB0byB1c2UgLywgbm90IFxcXG4gIGlmIChwYXRoLnNlcCAhPT0gJy8nKSB7XG4gICAgcGF0dGVybiA9IHBhdHRlcm4uc3BsaXQocGF0aC5zZXApLmpvaW4oJy8nKVxuICB9XG5cbiAgdGhpcy5vcHRpb25zID0gb3B0aW9uc1xuICB0aGlzLnNldCA9IFtdXG4gIHRoaXMucGF0dGVybiA9IHBhdHRlcm5cbiAgdGhpcy5yZWdleHAgPSBudWxsXG4gIHRoaXMubmVnYXRlID0gZmFsc2VcbiAgdGhpcy5jb21tZW50ID0gZmFsc2VcbiAgdGhpcy5lbXB0eSA9IGZhbHNlXG5cbiAgLy8gbWFrZSB0aGUgc2V0IG9mIHJlZ2V4cHMgZXRjLlxuICB0aGlzLm1ha2UoKVxufVxuXG5NaW5pbWF0Y2gucHJvdG90eXBlLmRlYnVnID0gZnVuY3Rpb24gKCkge31cblxuTWluaW1hdGNoLnByb3RvdHlwZS5tYWtlID0gbWFrZVxuZnVuY3Rpb24gbWFrZSAoKSB7XG4gIC8vIGRvbid0IGRvIGl0IG1vcmUgdGhhbiBvbmNlLlxuICBpZiAodGhpcy5fbWFkZSkgcmV0dXJuXG5cbiAgdmFyIHBhdHRlcm4gPSB0aGlzLnBhdHRlcm5cbiAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnNcblxuICAvLyBlbXB0eSBwYXR0ZXJucyBhbmQgY29tbWVudHMgbWF0Y2ggbm90aGluZy5cbiAgaWYgKCFvcHRpb25zLm5vY29tbWVudCAmJiBwYXR0ZXJuLmNoYXJBdCgwKSA9PT0gJyMnKSB7XG4gICAgdGhpcy5jb21tZW50ID0gdHJ1ZVxuICAgIHJldHVyblxuICB9XG4gIGlmICghcGF0dGVybikge1xuICAgIHRoaXMuZW1wdHkgPSB0cnVlXG4gICAgcmV0dXJuXG4gIH1cblxuICAvLyBzdGVwIDE6IGZpZ3VyZSBvdXQgbmVnYXRpb24sIGV0Yy5cbiAgdGhpcy5wYXJzZU5lZ2F0ZSgpXG5cbiAgLy8gc3RlcCAyOiBleHBhbmQgYnJhY2VzXG4gIHZhciBzZXQgPSB0aGlzLmdsb2JTZXQgPSB0aGlzLmJyYWNlRXhwYW5kKClcblxuICBpZiAob3B0aW9ucy5kZWJ1ZykgdGhpcy5kZWJ1ZyA9IGNvbnNvbGUuZXJyb3JcblxuICB0aGlzLmRlYnVnKHRoaXMucGF0dGVybiwgc2V0KVxuXG4gIC8vIHN0ZXAgMzogbm93IHdlIGhhdmUgYSBzZXQsIHNvIHR1cm4gZWFjaCBvbmUgaW50byBhIHNlcmllcyBvZiBwYXRoLXBvcnRpb25cbiAgLy8gbWF0Y2hpbmcgcGF0dGVybnMuXG4gIC8vIFRoZXNlIHdpbGwgYmUgcmVnZXhwcywgZXhjZXB0IGluIHRoZSBjYXNlIG9mIFwiKipcIiwgd2hpY2ggaXNcbiAgLy8gc2V0IHRvIHRoZSBHTE9CU1RBUiBvYmplY3QgZm9yIGdsb2JzdGFyIGJlaGF2aW9yLFxuICAvLyBhbmQgd2lsbCBub3QgY29udGFpbiBhbnkgLyBjaGFyYWN0ZXJzXG4gIHNldCA9IHRoaXMuZ2xvYlBhcnRzID0gc2V0Lm1hcChmdW5jdGlvbiAocykge1xuICAgIHJldHVybiBzLnNwbGl0KHNsYXNoU3BsaXQpXG4gIH0pXG5cbiAgdGhpcy5kZWJ1Zyh0aGlzLnBhdHRlcm4sIHNldClcblxuICAvLyBnbG9iIC0tPiByZWdleHBzXG4gIHNldCA9IHNldC5tYXAoZnVuY3Rpb24gKHMsIHNpLCBzZXQpIHtcbiAgICByZXR1cm4gcy5tYXAodGhpcy5wYXJzZSwgdGhpcylcbiAgfSwgdGhpcylcblxuICB0aGlzLmRlYnVnKHRoaXMucGF0dGVybiwgc2V0KVxuXG4gIC8vIGZpbHRlciBvdXQgZXZlcnl0aGluZyB0aGF0IGRpZG4ndCBjb21waWxlIHByb3Blcmx5LlxuICBzZXQgPSBzZXQuZmlsdGVyKGZ1bmN0aW9uIChzKSB7XG4gICAgcmV0dXJuIHMuaW5kZXhPZihmYWxzZSkgPT09IC0xXG4gIH0pXG5cbiAgdGhpcy5kZWJ1Zyh0aGlzLnBhdHRlcm4sIHNldClcblxuICB0aGlzLnNldCA9IHNldFxufVxuXG5NaW5pbWF0Y2gucHJvdG90eXBlLnBhcnNlTmVnYXRlID0gcGFyc2VOZWdhdGVcbmZ1bmN0aW9uIHBhcnNlTmVnYXRlICgpIHtcbiAgdmFyIHBhdHRlcm4gPSB0aGlzLnBhdHRlcm5cbiAgdmFyIG5lZ2F0ZSA9IGZhbHNlXG4gIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zXG4gIHZhciBuZWdhdGVPZmZzZXQgPSAwXG5cbiAgaWYgKG9wdGlvbnMubm9uZWdhdGUpIHJldHVyblxuXG4gIGZvciAodmFyIGkgPSAwLCBsID0gcGF0dGVybi5sZW5ndGhcbiAgICA7IGkgPCBsICYmIHBhdHRlcm4uY2hhckF0KGkpID09PSAnISdcbiAgICA7IGkrKykge1xuICAgIG5lZ2F0ZSA9ICFuZWdhdGVcbiAgICBuZWdhdGVPZmZzZXQrK1xuICB9XG5cbiAgaWYgKG5lZ2F0ZU9mZnNldCkgdGhpcy5wYXR0ZXJuID0gcGF0dGVybi5zdWJzdHIobmVnYXRlT2Zmc2V0KVxuICB0aGlzLm5lZ2F0ZSA9IG5lZ2F0ZVxufVxuXG4vLyBCcmFjZSBleHBhbnNpb246XG4vLyBhe2IsY31kIC0+IGFiZCBhY2Rcbi8vIGF7Yix9YyAtPiBhYmMgYWNcbi8vIGF7MC4uM31kIC0+IGEwZCBhMWQgYTJkIGEzZFxuLy8gYXtiLGN7ZCxlfWZ9ZyAtPiBhYmcgYWNkZmcgYWNlZmdcbi8vIGF7YixjfWR7ZSxmfWcgLT4gYWJkZWcgYWNkZWcgYWJkZWcgYWJkZmdcbi8vXG4vLyBJbnZhbGlkIHNldHMgYXJlIG5vdCBleHBhbmRlZC5cbi8vIGF7Mi4ufWIgLT4gYXsyLi59YlxuLy8gYXtifWMgLT4gYXtifWNcbm1pbmltYXRjaC5icmFjZUV4cGFuZCA9IGZ1bmN0aW9uIChwYXR0ZXJuLCBvcHRpb25zKSB7XG4gIHJldHVybiBicmFjZUV4cGFuZChwYXR0ZXJuLCBvcHRpb25zKVxufVxuXG5NaW5pbWF0Y2gucHJvdG90eXBlLmJyYWNlRXhwYW5kID0gYnJhY2VFeHBhbmRcblxuZnVuY3Rpb24gYnJhY2VFeHBhbmQgKHBhdHRlcm4sIG9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zKSB7XG4gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBNaW5pbWF0Y2gpIHtcbiAgICAgIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnNcbiAgICB9IGVsc2Uge1xuICAgICAgb3B0aW9ucyA9IHt9XG4gICAgfVxuICB9XG5cbiAgcGF0dGVybiA9IHR5cGVvZiBwYXR0ZXJuID09PSAndW5kZWZpbmVkJ1xuICAgID8gdGhpcy5wYXR0ZXJuIDogcGF0dGVyblxuXG4gIGlmICh0eXBlb2YgcGF0dGVybiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd1bmRlZmluZWQgcGF0dGVybicpXG4gIH1cblxuICBpZiAob3B0aW9ucy5ub2JyYWNlIHx8XG4gICAgIXBhdHRlcm4ubWF0Y2goL1xcey4qXFx9LykpIHtcbiAgICAvLyBzaG9ydGN1dC4gbm8gbmVlZCB0byBleHBhbmQuXG4gICAgcmV0dXJuIFtwYXR0ZXJuXVxuICB9XG5cbiAgcmV0dXJuIGV4cGFuZChwYXR0ZXJuKVxufVxuXG4vLyBwYXJzZSBhIGNvbXBvbmVudCBvZiB0aGUgZXhwYW5kZWQgc2V0LlxuLy8gQXQgdGhpcyBwb2ludCwgbm8gcGF0dGVybiBtYXkgY29udGFpbiBcIi9cIiBpbiBpdFxuLy8gc28gd2UncmUgZ29pbmcgdG8gcmV0dXJuIGEgMmQgYXJyYXksIHdoZXJlIGVhY2ggZW50cnkgaXMgdGhlIGZ1bGxcbi8vIHBhdHRlcm4sIHNwbGl0IG9uICcvJywgYW5kIHRoZW4gdHVybmVkIGludG8gYSByZWd1bGFyIGV4cHJlc3Npb24uXG4vLyBBIHJlZ2V4cCBpcyBtYWRlIGF0IHRoZSBlbmQgd2hpY2ggam9pbnMgZWFjaCBhcnJheSB3aXRoIGFuXG4vLyBlc2NhcGVkIC8sIGFuZCBhbm90aGVyIGZ1bGwgb25lIHdoaWNoIGpvaW5zIGVhY2ggcmVnZXhwIHdpdGggfC5cbi8vXG4vLyBGb2xsb3dpbmcgdGhlIGxlYWQgb2YgQmFzaCA0LjEsIG5vdGUgdGhhdCBcIioqXCIgb25seSBoYXMgc3BlY2lhbCBtZWFuaW5nXG4vLyB3aGVuIGl0IGlzIHRoZSAqb25seSogdGhpbmcgaW4gYSBwYXRoIHBvcnRpb24uICBPdGhlcndpc2UsIGFueSBzZXJpZXNcbi8vIG9mICogaXMgZXF1aXZhbGVudCB0byBhIHNpbmdsZSAqLiAgR2xvYnN0YXIgYmVoYXZpb3IgaXMgZW5hYmxlZCBieVxuLy8gZGVmYXVsdCwgYW5kIGNhbiBiZSBkaXNhYmxlZCBieSBzZXR0aW5nIG9wdGlvbnMubm9nbG9ic3Rhci5cbk1pbmltYXRjaC5wcm90b3R5cGUucGFyc2UgPSBwYXJzZVxudmFyIFNVQlBBUlNFID0ge31cbmZ1bmN0aW9uIHBhcnNlIChwYXR0ZXJuLCBpc1N1Yikge1xuICBpZiAocGF0dGVybi5sZW5ndGggPiAxMDI0ICogNjQpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdwYXR0ZXJuIGlzIHRvbyBsb25nJylcbiAgfVxuXG4gIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zXG5cbiAgLy8gc2hvcnRjdXRzXG4gIGlmICghb3B0aW9ucy5ub2dsb2JzdGFyICYmIHBhdHRlcm4gPT09ICcqKicpIHJldHVybiBHTE9CU1RBUlxuICBpZiAocGF0dGVybiA9PT0gJycpIHJldHVybiAnJ1xuXG4gIHZhciByZSA9ICcnXG4gIHZhciBoYXNNYWdpYyA9ICEhb3B0aW9ucy5ub2Nhc2VcbiAgdmFyIGVzY2FwaW5nID0gZmFsc2VcbiAgLy8gPyA9PiBvbmUgc2luZ2xlIGNoYXJhY3RlclxuICB2YXIgcGF0dGVybkxpc3RTdGFjayA9IFtdXG4gIHZhciBuZWdhdGl2ZUxpc3RzID0gW11cbiAgdmFyIHN0YXRlQ2hhclxuICB2YXIgaW5DbGFzcyA9IGZhbHNlXG4gIHZhciByZUNsYXNzU3RhcnQgPSAtMVxuICB2YXIgY2xhc3NTdGFydCA9IC0xXG4gIC8vIC4gYW5kIC4uIG5ldmVyIG1hdGNoIGFueXRoaW5nIHRoYXQgZG9lc24ndCBzdGFydCB3aXRoIC4sXG4gIC8vIGV2ZW4gd2hlbiBvcHRpb25zLmRvdCBpcyBzZXQuXG4gIHZhciBwYXR0ZXJuU3RhcnQgPSBwYXR0ZXJuLmNoYXJBdCgwKSA9PT0gJy4nID8gJycgLy8gYW55dGhpbmdcbiAgLy8gbm90IChzdGFydCBvciAvIGZvbGxvd2VkIGJ5IC4gb3IgLi4gZm9sbG93ZWQgYnkgLyBvciBlbmQpXG4gIDogb3B0aW9ucy5kb3QgPyAnKD8hKD86XnxcXFxcXFwvKVxcXFwuezEsMn0oPzokfFxcXFxcXC8pKSdcbiAgOiAnKD8hXFxcXC4pJ1xuICB2YXIgc2VsZiA9IHRoaXNcblxuICBmdW5jdGlvbiBjbGVhclN0YXRlQ2hhciAoKSB7XG4gICAgaWYgKHN0YXRlQ2hhcikge1xuICAgICAgLy8gd2UgaGFkIHNvbWUgc3RhdGUtdHJhY2tpbmcgY2hhcmFjdGVyXG4gICAgICAvLyB0aGF0IHdhc24ndCBjb25zdW1lZCBieSB0aGlzIHBhc3MuXG4gICAgICBzd2l0Y2ggKHN0YXRlQ2hhcikge1xuICAgICAgICBjYXNlICcqJzpcbiAgICAgICAgICByZSArPSBzdGFyXG4gICAgICAgICAgaGFzTWFnaWMgPSB0cnVlXG4gICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgJz8nOlxuICAgICAgICAgIHJlICs9IHFtYXJrXG4gICAgICAgICAgaGFzTWFnaWMgPSB0cnVlXG4gICAgICAgIGJyZWFrXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmUgKz0gJ1xcXFwnICsgc3RhdGVDaGFyXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgICBzZWxmLmRlYnVnKCdjbGVhclN0YXRlQ2hhciAlaiAlaicsIHN0YXRlQ2hhciwgcmUpXG4gICAgICBzdGF0ZUNoYXIgPSBmYWxzZVxuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBwYXR0ZXJuLmxlbmd0aCwgY1xuICAgIDsgKGkgPCBsZW4pICYmIChjID0gcGF0dGVybi5jaGFyQXQoaSkpXG4gICAgOyBpKyspIHtcbiAgICB0aGlzLmRlYnVnKCclc1xcdCVzICVzICVqJywgcGF0dGVybiwgaSwgcmUsIGMpXG5cbiAgICAvLyBza2lwIG92ZXIgYW55IHRoYXQgYXJlIGVzY2FwZWQuXG4gICAgaWYgKGVzY2FwaW5nICYmIHJlU3BlY2lhbHNbY10pIHtcbiAgICAgIHJlICs9ICdcXFxcJyArIGNcbiAgICAgIGVzY2FwaW5nID0gZmFsc2VcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgc3dpdGNoIChjKSB7XG4gICAgICBjYXNlICcvJzpcbiAgICAgICAgLy8gY29tcGxldGVseSBub3QgYWxsb3dlZCwgZXZlbiBlc2NhcGVkLlxuICAgICAgICAvLyBTaG91bGQgYWxyZWFkeSBiZSBwYXRoLXNwbGl0IGJ5IG5vdy5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG5cbiAgICAgIGNhc2UgJ1xcXFwnOlxuICAgICAgICBjbGVhclN0YXRlQ2hhcigpXG4gICAgICAgIGVzY2FwaW5nID0gdHJ1ZVxuICAgICAgY29udGludWVcblxuICAgICAgLy8gdGhlIHZhcmlvdXMgc3RhdGVDaGFyIHZhbHVlc1xuICAgICAgLy8gZm9yIHRoZSBcImV4dGdsb2JcIiBzdHVmZi5cbiAgICAgIGNhc2UgJz8nOlxuICAgICAgY2FzZSAnKic6XG4gICAgICBjYXNlICcrJzpcbiAgICAgIGNhc2UgJ0AnOlxuICAgICAgY2FzZSAnISc6XG4gICAgICAgIHRoaXMuZGVidWcoJyVzXFx0JXMgJXMgJWogPC0tIHN0YXRlQ2hhcicsIHBhdHRlcm4sIGksIHJlLCBjKVxuXG4gICAgICAgIC8vIGFsbCBvZiB0aG9zZSBhcmUgbGl0ZXJhbHMgaW5zaWRlIGEgY2xhc3MsIGV4Y2VwdCB0aGF0XG4gICAgICAgIC8vIHRoZSBnbG9iIFshYV0gbWVhbnMgW15hXSBpbiByZWdleHBcbiAgICAgICAgaWYgKGluQ2xhc3MpIHtcbiAgICAgICAgICB0aGlzLmRlYnVnKCcgIGluIGNsYXNzJylcbiAgICAgICAgICBpZiAoYyA9PT0gJyEnICYmIGkgPT09IGNsYXNzU3RhcnQgKyAxKSBjID0gJ14nXG4gICAgICAgICAgcmUgKz0gY1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiB3ZSBhbHJlYWR5IGhhdmUgYSBzdGF0ZUNoYXIsIHRoZW4gaXQgbWVhbnNcbiAgICAgICAgLy8gdGhhdCB0aGVyZSB3YXMgc29tZXRoaW5nIGxpa2UgKiogb3IgKz8gaW4gdGhlcmUuXG4gICAgICAgIC8vIEhhbmRsZSB0aGUgc3RhdGVDaGFyLCB0aGVuIHByb2NlZWQgd2l0aCB0aGlzIG9uZS5cbiAgICAgICAgc2VsZi5kZWJ1ZygnY2FsbCBjbGVhclN0YXRlQ2hhciAlaicsIHN0YXRlQ2hhcilcbiAgICAgICAgY2xlYXJTdGF0ZUNoYXIoKVxuICAgICAgICBzdGF0ZUNoYXIgPSBjXG4gICAgICAgIC8vIGlmIGV4dGdsb2IgaXMgZGlzYWJsZWQsIHRoZW4gKyhhc2RmfGZvbykgaXNuJ3QgYSB0aGluZy5cbiAgICAgICAgLy8ganVzdCBjbGVhciB0aGUgc3RhdGVjaGFyICpub3cqLCByYXRoZXIgdGhhbiBldmVuIGRpdmluZyBpbnRvXG4gICAgICAgIC8vIHRoZSBwYXR0ZXJuTGlzdCBzdHVmZi5cbiAgICAgICAgaWYgKG9wdGlvbnMubm9leHQpIGNsZWFyU3RhdGVDaGFyKClcbiAgICAgIGNvbnRpbnVlXG5cbiAgICAgIGNhc2UgJygnOlxuICAgICAgICBpZiAoaW5DbGFzcykge1xuICAgICAgICAgIHJlICs9ICcoJ1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXN0YXRlQ2hhcikge1xuICAgICAgICAgIHJlICs9ICdcXFxcKCdcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgcGF0dGVybkxpc3RTdGFjay5wdXNoKHtcbiAgICAgICAgICB0eXBlOiBzdGF0ZUNoYXIsXG4gICAgICAgICAgc3RhcnQ6IGkgLSAxLFxuICAgICAgICAgIHJlU3RhcnQ6IHJlLmxlbmd0aCxcbiAgICAgICAgICBvcGVuOiBwbFR5cGVzW3N0YXRlQ2hhcl0ub3BlbixcbiAgICAgICAgICBjbG9zZTogcGxUeXBlc1tzdGF0ZUNoYXJdLmNsb3NlXG4gICAgICAgIH0pXG4gICAgICAgIC8vIG5lZ2F0aW9uIGlzICg/Oig/IWpzKVteL10qKVxuICAgICAgICByZSArPSBzdGF0ZUNoYXIgPT09ICchJyA/ICcoPzooPyEoPzonIDogJyg/OidcbiAgICAgICAgdGhpcy5kZWJ1ZygncGxUeXBlICVqICVqJywgc3RhdGVDaGFyLCByZSlcbiAgICAgICAgc3RhdGVDaGFyID0gZmFsc2VcbiAgICAgIGNvbnRpbnVlXG5cbiAgICAgIGNhc2UgJyknOlxuICAgICAgICBpZiAoaW5DbGFzcyB8fCAhcGF0dGVybkxpc3RTdGFjay5sZW5ndGgpIHtcbiAgICAgICAgICByZSArPSAnXFxcXCknXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIGNsZWFyU3RhdGVDaGFyKClcbiAgICAgICAgaGFzTWFnaWMgPSB0cnVlXG4gICAgICAgIHZhciBwbCA9IHBhdHRlcm5MaXN0U3RhY2sucG9wKClcbiAgICAgICAgLy8gbmVnYXRpb24gaXMgKD86KD8hanMpW14vXSopXG4gICAgICAgIC8vIFRoZSBvdGhlcnMgYXJlICg/OjxwYXR0ZXJuPik8dHlwZT5cbiAgICAgICAgcmUgKz0gcGwuY2xvc2VcbiAgICAgICAgaWYgKHBsLnR5cGUgPT09ICchJykge1xuICAgICAgICAgIG5lZ2F0aXZlTGlzdHMucHVzaChwbClcbiAgICAgICAgfVxuICAgICAgICBwbC5yZUVuZCA9IHJlLmxlbmd0aFxuICAgICAgY29udGludWVcblxuICAgICAgY2FzZSAnfCc6XG4gICAgICAgIGlmIChpbkNsYXNzIHx8ICFwYXR0ZXJuTGlzdFN0YWNrLmxlbmd0aCB8fCBlc2NhcGluZykge1xuICAgICAgICAgIHJlICs9ICdcXFxcfCdcbiAgICAgICAgICBlc2NhcGluZyA9IGZhbHNlXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIGNsZWFyU3RhdGVDaGFyKClcbiAgICAgICAgcmUgKz0gJ3wnXG4gICAgICBjb250aW51ZVxuXG4gICAgICAvLyB0aGVzZSBhcmUgbW9zdGx5IHRoZSBzYW1lIGluIHJlZ2V4cCBhbmQgZ2xvYlxuICAgICAgY2FzZSAnWyc6XG4gICAgICAgIC8vIHN3YWxsb3cgYW55IHN0YXRlLXRyYWNraW5nIGNoYXIgYmVmb3JlIHRoZSBbXG4gICAgICAgIGNsZWFyU3RhdGVDaGFyKClcblxuICAgICAgICBpZiAoaW5DbGFzcykge1xuICAgICAgICAgIHJlICs9ICdcXFxcJyArIGNcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgaW5DbGFzcyA9IHRydWVcbiAgICAgICAgY2xhc3NTdGFydCA9IGlcbiAgICAgICAgcmVDbGFzc1N0YXJ0ID0gcmUubGVuZ3RoXG4gICAgICAgIHJlICs9IGNcbiAgICAgIGNvbnRpbnVlXG5cbiAgICAgIGNhc2UgJ10nOlxuICAgICAgICAvLyAgYSByaWdodCBicmFja2V0IHNoYWxsIGxvc2UgaXRzIHNwZWNpYWxcbiAgICAgICAgLy8gIG1lYW5pbmcgYW5kIHJlcHJlc2VudCBpdHNlbGYgaW5cbiAgICAgICAgLy8gIGEgYnJhY2tldCBleHByZXNzaW9uIGlmIGl0IG9jY3Vyc1xuICAgICAgICAvLyAgZmlyc3QgaW4gdGhlIGxpc3QuICAtLSBQT1NJWC4yIDIuOC4zLjJcbiAgICAgICAgaWYgKGkgPT09IGNsYXNzU3RhcnQgKyAxIHx8ICFpbkNsYXNzKSB7XG4gICAgICAgICAgcmUgKz0gJ1xcXFwnICsgY1xuICAgICAgICAgIGVzY2FwaW5nID0gZmFsc2VcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gaGFuZGxlIHRoZSBjYXNlIHdoZXJlIHdlIGxlZnQgYSBjbGFzcyBvcGVuLlxuICAgICAgICAvLyBcIlt6LWFdXCIgaXMgdmFsaWQsIGVxdWl2YWxlbnQgdG8gXCJcXFt6LWFcXF1cIlxuICAgICAgICBpZiAoaW5DbGFzcykge1xuICAgICAgICAgIC8vIHNwbGl0IHdoZXJlIHRoZSBsYXN0IFsgd2FzLCBtYWtlIHN1cmUgd2UgZG9uJ3QgaGF2ZVxuICAgICAgICAgIC8vIGFuIGludmFsaWQgcmUuIGlmIHNvLCByZS13YWxrIHRoZSBjb250ZW50cyBvZiB0aGVcbiAgICAgICAgICAvLyB3b3VsZC1iZSBjbGFzcyB0byByZS10cmFuc2xhdGUgYW55IGNoYXJhY3RlcnMgdGhhdFxuICAgICAgICAgIC8vIHdlcmUgcGFzc2VkIHRocm91Z2ggYXMtaXNcbiAgICAgICAgICAvLyBUT0RPOiBJdCB3b3VsZCBwcm9iYWJseSBiZSBmYXN0ZXIgdG8gZGV0ZXJtaW5lIHRoaXNcbiAgICAgICAgICAvLyB3aXRob3V0IGEgdHJ5L2NhdGNoIGFuZCBhIG5ldyBSZWdFeHAsIGJ1dCBpdCdzIHRyaWNreVxuICAgICAgICAgIC8vIHRvIGRvIHNhZmVseS4gIEZvciBub3csIHRoaXMgaXMgc2FmZSBhbmQgd29ya3MuXG4gICAgICAgICAgdmFyIGNzID0gcGF0dGVybi5zdWJzdHJpbmcoY2xhc3NTdGFydCArIDEsIGkpXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIFJlZ0V4cCgnWycgKyBjcyArICddJylcbiAgICAgICAgICB9IGNhdGNoIChlcikge1xuICAgICAgICAgICAgLy8gbm90IGEgdmFsaWQgY2xhc3MhXG4gICAgICAgICAgICB2YXIgc3AgPSB0aGlzLnBhcnNlKGNzLCBTVUJQQVJTRSlcbiAgICAgICAgICAgIHJlID0gcmUuc3Vic3RyKDAsIHJlQ2xhc3NTdGFydCkgKyAnXFxcXFsnICsgc3BbMF0gKyAnXFxcXF0nXG4gICAgICAgICAgICBoYXNNYWdpYyA9IGhhc01hZ2ljIHx8IHNwWzFdXG4gICAgICAgICAgICBpbkNsYXNzID0gZmFsc2VcbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gZmluaXNoIHVwIHRoZSBjbGFzcy5cbiAgICAgICAgaGFzTWFnaWMgPSB0cnVlXG4gICAgICAgIGluQ2xhc3MgPSBmYWxzZVxuICAgICAgICByZSArPSBjXG4gICAgICBjb250aW51ZVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICAvLyBzd2FsbG93IGFueSBzdGF0ZSBjaGFyIHRoYXQgd2Fzbid0IGNvbnN1bWVkXG4gICAgICAgIGNsZWFyU3RhdGVDaGFyKClcblxuICAgICAgICBpZiAoZXNjYXBpbmcpIHtcbiAgICAgICAgICAvLyBubyBuZWVkXG4gICAgICAgICAgZXNjYXBpbmcgPSBmYWxzZVxuICAgICAgICB9IGVsc2UgaWYgKHJlU3BlY2lhbHNbY11cbiAgICAgICAgICAmJiAhKGMgPT09ICdeJyAmJiBpbkNsYXNzKSkge1xuICAgICAgICAgIHJlICs9ICdcXFxcJ1xuICAgICAgICB9XG5cbiAgICAgICAgcmUgKz0gY1xuXG4gICAgfSAvLyBzd2l0Y2hcbiAgfSAvLyBmb3JcblxuICAvLyBoYW5kbGUgdGhlIGNhc2Ugd2hlcmUgd2UgbGVmdCBhIGNsYXNzIG9wZW4uXG4gIC8vIFwiW2FiY1wiIGlzIHZhbGlkLCBlcXVpdmFsZW50IHRvIFwiXFxbYWJjXCJcbiAgaWYgKGluQ2xhc3MpIHtcbiAgICAvLyBzcGxpdCB3aGVyZSB0aGUgbGFzdCBbIHdhcywgYW5kIGVzY2FwZSBpdFxuICAgIC8vIHRoaXMgaXMgYSBodWdlIHBpdGEuICBXZSBub3cgaGF2ZSB0byByZS13YWxrXG4gICAgLy8gdGhlIGNvbnRlbnRzIG9mIHRoZSB3b3VsZC1iZSBjbGFzcyB0byByZS10cmFuc2xhdGVcbiAgICAvLyBhbnkgY2hhcmFjdGVycyB0aGF0IHdlcmUgcGFzc2VkIHRocm91Z2ggYXMtaXNcbiAgICBjcyA9IHBhdHRlcm4uc3Vic3RyKGNsYXNzU3RhcnQgKyAxKVxuICAgIHNwID0gdGhpcy5wYXJzZShjcywgU1VCUEFSU0UpXG4gICAgcmUgPSByZS5zdWJzdHIoMCwgcmVDbGFzc1N0YXJ0KSArICdcXFxcWycgKyBzcFswXVxuICAgIGhhc01hZ2ljID0gaGFzTWFnaWMgfHwgc3BbMV1cbiAgfVxuXG4gIC8vIGhhbmRsZSB0aGUgY2FzZSB3aGVyZSB3ZSBoYWQgYSArKCB0aGluZyBhdCB0aGUgKmVuZCpcbiAgLy8gb2YgdGhlIHBhdHRlcm4uXG4gIC8vIGVhY2ggcGF0dGVybiBsaXN0IHN0YWNrIGFkZHMgMyBjaGFycywgYW5kIHdlIG5lZWQgdG8gZ28gdGhyb3VnaFxuICAvLyBhbmQgZXNjYXBlIGFueSB8IGNoYXJzIHRoYXQgd2VyZSBwYXNzZWQgdGhyb3VnaCBhcy1pcyBmb3IgdGhlIHJlZ2V4cC5cbiAgLy8gR28gdGhyb3VnaCBhbmQgZXNjYXBlIHRoZW0sIHRha2luZyBjYXJlIG5vdCB0byBkb3VibGUtZXNjYXBlIGFueVxuICAvLyB8IGNoYXJzIHRoYXQgd2VyZSBhbHJlYWR5IGVzY2FwZWQuXG4gIGZvciAocGwgPSBwYXR0ZXJuTGlzdFN0YWNrLnBvcCgpOyBwbDsgcGwgPSBwYXR0ZXJuTGlzdFN0YWNrLnBvcCgpKSB7XG4gICAgdmFyIHRhaWwgPSByZS5zbGljZShwbC5yZVN0YXJ0ICsgcGwub3Blbi5sZW5ndGgpXG4gICAgdGhpcy5kZWJ1Zygnc2V0dGluZyB0YWlsJywgcmUsIHBsKVxuICAgIC8vIG1heWJlIHNvbWUgZXZlbiBudW1iZXIgb2YgXFwsIHRoZW4gbWF5YmUgMSBcXCwgZm9sbG93ZWQgYnkgYSB8XG4gICAgdGFpbCA9IHRhaWwucmVwbGFjZSgvKCg/OlxcXFx7Mn0pezAsNjR9KShcXFxcPylcXHwvZywgZnVuY3Rpb24gKF8sICQxLCAkMikge1xuICAgICAgaWYgKCEkMikge1xuICAgICAgICAvLyB0aGUgfCBpc24ndCBhbHJlYWR5IGVzY2FwZWQsIHNvIGVzY2FwZSBpdC5cbiAgICAgICAgJDIgPSAnXFxcXCdcbiAgICAgIH1cblxuICAgICAgLy8gbmVlZCB0byBlc2NhcGUgYWxsIHRob3NlIHNsYXNoZXMgKmFnYWluKiwgd2l0aG91dCBlc2NhcGluZyB0aGVcbiAgICAgIC8vIG9uZSB0aGF0IHdlIG5lZWQgZm9yIGVzY2FwaW5nIHRoZSB8IGNoYXJhY3Rlci4gIEFzIGl0IHdvcmtzIG91dCxcbiAgICAgIC8vIGVzY2FwaW5nIGFuIGV2ZW4gbnVtYmVyIG9mIHNsYXNoZXMgY2FuIGJlIGRvbmUgYnkgc2ltcGx5IHJlcGVhdGluZ1xuICAgICAgLy8gaXQgZXhhY3RseSBhZnRlciBpdHNlbGYuICBUaGF0J3Mgd2h5IHRoaXMgdHJpY2sgd29ya3MuXG4gICAgICAvL1xuICAgICAgLy8gSSBhbSBzb3JyeSB0aGF0IHlvdSBoYXZlIHRvIHNlZSB0aGlzLlxuICAgICAgcmV0dXJuICQxICsgJDEgKyAkMiArICd8J1xuICAgIH0pXG5cbiAgICB0aGlzLmRlYnVnKCd0YWlsPSVqXFxuICAgJXMnLCB0YWlsLCB0YWlsLCBwbCwgcmUpXG4gICAgdmFyIHQgPSBwbC50eXBlID09PSAnKicgPyBzdGFyXG4gICAgICA6IHBsLnR5cGUgPT09ICc/JyA/IHFtYXJrXG4gICAgICA6ICdcXFxcJyArIHBsLnR5cGVcblxuICAgIGhhc01hZ2ljID0gdHJ1ZVxuICAgIHJlID0gcmUuc2xpY2UoMCwgcGwucmVTdGFydCkgKyB0ICsgJ1xcXFwoJyArIHRhaWxcbiAgfVxuXG4gIC8vIGhhbmRsZSB0cmFpbGluZyB0aGluZ3MgdGhhdCBvbmx5IG1hdHRlciBhdCB0aGUgdmVyeSBlbmQuXG4gIGNsZWFyU3RhdGVDaGFyKClcbiAgaWYgKGVzY2FwaW5nKSB7XG4gICAgLy8gdHJhaWxpbmcgXFxcXFxuICAgIHJlICs9ICdcXFxcXFxcXCdcbiAgfVxuXG4gIC8vIG9ubHkgbmVlZCB0byBhcHBseSB0aGUgbm9kb3Qgc3RhcnQgaWYgdGhlIHJlIHN0YXJ0cyB3aXRoXG4gIC8vIHNvbWV0aGluZyB0aGF0IGNvdWxkIGNvbmNlaXZhYmx5IGNhcHR1cmUgYSBkb3RcbiAgdmFyIGFkZFBhdHRlcm5TdGFydCA9IGZhbHNlXG4gIHN3aXRjaCAocmUuY2hhckF0KDApKSB7XG4gICAgY2FzZSAnLic6XG4gICAgY2FzZSAnWyc6XG4gICAgY2FzZSAnKCc6IGFkZFBhdHRlcm5TdGFydCA9IHRydWVcbiAgfVxuXG4gIC8vIEhhY2sgdG8gd29yayBhcm91bmQgbGFjayBvZiBuZWdhdGl2ZSBsb29rYmVoaW5kIGluIEpTXG4gIC8vIEEgcGF0dGVybiBsaWtlOiAqLiEoeCkuISh5fHopIG5lZWRzIHRvIGVuc3VyZSB0aGF0IGEgbmFtZVxuICAvLyBsaWtlICdhLnh5ei55eicgZG9lc24ndCBtYXRjaC4gIFNvLCB0aGUgZmlyc3QgbmVnYXRpdmVcbiAgLy8gbG9va2FoZWFkLCBoYXMgdG8gbG9vayBBTEwgdGhlIHdheSBhaGVhZCwgdG8gdGhlIGVuZCBvZlxuICAvLyB0aGUgcGF0dGVybi5cbiAgZm9yICh2YXIgbiA9IG5lZ2F0aXZlTGlzdHMubGVuZ3RoIC0gMTsgbiA+IC0xOyBuLS0pIHtcbiAgICB2YXIgbmwgPSBuZWdhdGl2ZUxpc3RzW25dXG5cbiAgICB2YXIgbmxCZWZvcmUgPSByZS5zbGljZSgwLCBubC5yZVN0YXJ0KVxuICAgIHZhciBubEZpcnN0ID0gcmUuc2xpY2UobmwucmVTdGFydCwgbmwucmVFbmQgLSA4KVxuICAgIHZhciBubExhc3QgPSByZS5zbGljZShubC5yZUVuZCAtIDgsIG5sLnJlRW5kKVxuICAgIHZhciBubEFmdGVyID0gcmUuc2xpY2UobmwucmVFbmQpXG5cbiAgICBubExhc3QgKz0gbmxBZnRlclxuXG4gICAgLy8gSGFuZGxlIG5lc3RlZCBzdHVmZiBsaWtlICooKi5qc3whKCouanNvbikpLCB3aGVyZSBvcGVuIHBhcmVuc1xuICAgIC8vIG1lYW4gdGhhdCB3ZSBzaG91bGQgKm5vdCogaW5jbHVkZSB0aGUgKSBpbiB0aGUgYml0IHRoYXQgaXMgY29uc2lkZXJlZFxuICAgIC8vIFwiYWZ0ZXJcIiB0aGUgbmVnYXRlZCBzZWN0aW9uLlxuICAgIHZhciBvcGVuUGFyZW5zQmVmb3JlID0gbmxCZWZvcmUuc3BsaXQoJygnKS5sZW5ndGggLSAxXG4gICAgdmFyIGNsZWFuQWZ0ZXIgPSBubEFmdGVyXG4gICAgZm9yIChpID0gMDsgaSA8IG9wZW5QYXJlbnNCZWZvcmU7IGkrKykge1xuICAgICAgY2xlYW5BZnRlciA9IGNsZWFuQWZ0ZXIucmVwbGFjZSgvXFwpWysqP10/LywgJycpXG4gICAgfVxuICAgIG5sQWZ0ZXIgPSBjbGVhbkFmdGVyXG5cbiAgICB2YXIgZG9sbGFyID0gJydcbiAgICBpZiAobmxBZnRlciA9PT0gJycgJiYgaXNTdWIgIT09IFNVQlBBUlNFKSB7XG4gICAgICBkb2xsYXIgPSAnJCdcbiAgICB9XG4gICAgdmFyIG5ld1JlID0gbmxCZWZvcmUgKyBubEZpcnN0ICsgbmxBZnRlciArIGRvbGxhciArIG5sTGFzdFxuICAgIHJlID0gbmV3UmVcbiAgfVxuXG4gIC8vIGlmIHRoZSByZSBpcyBub3QgXCJcIiBhdCB0aGlzIHBvaW50LCB0aGVuIHdlIG5lZWQgdG8gbWFrZSBzdXJlXG4gIC8vIGl0IGRvZXNuJ3QgbWF0Y2ggYWdhaW5zdCBhbiBlbXB0eSBwYXRoIHBhcnQuXG4gIC8vIE90aGVyd2lzZSBhLyogd2lsbCBtYXRjaCBhLywgd2hpY2ggaXQgc2hvdWxkIG5vdC5cbiAgaWYgKHJlICE9PSAnJyAmJiBoYXNNYWdpYykge1xuICAgIHJlID0gJyg/PS4pJyArIHJlXG4gIH1cblxuICBpZiAoYWRkUGF0dGVyblN0YXJ0KSB7XG4gICAgcmUgPSBwYXR0ZXJuU3RhcnQgKyByZVxuICB9XG5cbiAgLy8gcGFyc2luZyBqdXN0IGEgcGllY2Ugb2YgYSBsYXJnZXIgcGF0dGVybi5cbiAgaWYgKGlzU3ViID09PSBTVUJQQVJTRSkge1xuICAgIHJldHVybiBbcmUsIGhhc01hZ2ljXVxuICB9XG5cbiAgLy8gc2tpcCB0aGUgcmVnZXhwIGZvciBub24tbWFnaWNhbCBwYXR0ZXJuc1xuICAvLyB1bmVzY2FwZSBhbnl0aGluZyBpbiBpdCwgdGhvdWdoLCBzbyB0aGF0IGl0J2xsIGJlXG4gIC8vIGFuIGV4YWN0IG1hdGNoIGFnYWluc3QgYSBmaWxlIGV0Yy5cbiAgaWYgKCFoYXNNYWdpYykge1xuICAgIHJldHVybiBnbG9iVW5lc2NhcGUocGF0dGVybilcbiAgfVxuXG4gIHZhciBmbGFncyA9IG9wdGlvbnMubm9jYXNlID8gJ2knIDogJydcbiAgdHJ5IHtcbiAgICB2YXIgcmVnRXhwID0gbmV3IFJlZ0V4cCgnXicgKyByZSArICckJywgZmxhZ3MpXG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgLy8gSWYgaXQgd2FzIGFuIGludmFsaWQgcmVndWxhciBleHByZXNzaW9uLCB0aGVuIGl0IGNhbid0IG1hdGNoXG4gICAgLy8gYW55dGhpbmcuICBUaGlzIHRyaWNrIGxvb2tzIGZvciBhIGNoYXJhY3RlciBhZnRlciB0aGUgZW5kIG9mXG4gICAgLy8gdGhlIHN0cmluZywgd2hpY2ggaXMgb2YgY291cnNlIGltcG9zc2libGUsIGV4Y2VwdCBpbiBtdWx0aS1saW5lXG4gICAgLy8gbW9kZSwgYnV0IGl0J3Mgbm90IGEgL20gcmVnZXguXG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoJyQuJylcbiAgfVxuXG4gIHJlZ0V4cC5fZ2xvYiA9IHBhdHRlcm5cbiAgcmVnRXhwLl9zcmMgPSByZVxuXG4gIHJldHVybiByZWdFeHBcbn1cblxubWluaW1hdGNoLm1ha2VSZSA9IGZ1bmN0aW9uIChwYXR0ZXJuLCBvcHRpb25zKSB7XG4gIHJldHVybiBuZXcgTWluaW1hdGNoKHBhdHRlcm4sIG9wdGlvbnMgfHwge30pLm1ha2VSZSgpXG59XG5cbk1pbmltYXRjaC5wcm90b3R5cGUubWFrZVJlID0gbWFrZVJlXG5mdW5jdGlvbiBtYWtlUmUgKCkge1xuICBpZiAodGhpcy5yZWdleHAgfHwgdGhpcy5yZWdleHAgPT09IGZhbHNlKSByZXR1cm4gdGhpcy5yZWdleHBcblxuICAvLyBhdCB0aGlzIHBvaW50LCB0aGlzLnNldCBpcyBhIDJkIGFycmF5IG9mIHBhcnRpYWxcbiAgLy8gcGF0dGVybiBzdHJpbmdzLCBvciBcIioqXCIuXG4gIC8vXG4gIC8vIEl0J3MgYmV0dGVyIHRvIHVzZSAubWF0Y2goKS4gIFRoaXMgZnVuY3Rpb24gc2hvdWxkbid0XG4gIC8vIGJlIHVzZWQsIHJlYWxseSwgYnV0IGl0J3MgcHJldHR5IGNvbnZlbmllbnQgc29tZXRpbWVzLFxuICAvLyB3aGVuIHlvdSBqdXN0IHdhbnQgdG8gd29yayB3aXRoIGEgcmVnZXguXG4gIHZhciBzZXQgPSB0aGlzLnNldFxuXG4gIGlmICghc2V0Lmxlbmd0aCkge1xuICAgIHRoaXMucmVnZXhwID0gZmFsc2VcbiAgICByZXR1cm4gdGhpcy5yZWdleHBcbiAgfVxuICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9uc1xuXG4gIHZhciB0d29TdGFyID0gb3B0aW9ucy5ub2dsb2JzdGFyID8gc3RhclxuICAgIDogb3B0aW9ucy5kb3QgPyB0d29TdGFyRG90XG4gICAgOiB0d29TdGFyTm9Eb3RcbiAgdmFyIGZsYWdzID0gb3B0aW9ucy5ub2Nhc2UgPyAnaScgOiAnJ1xuXG4gIHZhciByZSA9IHNldC5tYXAoZnVuY3Rpb24gKHBhdHRlcm4pIHtcbiAgICByZXR1cm4gcGF0dGVybi5tYXAoZnVuY3Rpb24gKHApIHtcbiAgICAgIHJldHVybiAocCA9PT0gR0xPQlNUQVIpID8gdHdvU3RhclxuICAgICAgOiAodHlwZW9mIHAgPT09ICdzdHJpbmcnKSA/IHJlZ0V4cEVzY2FwZShwKVxuICAgICAgOiBwLl9zcmNcbiAgICB9KS5qb2luKCdcXFxcXFwvJylcbiAgfSkuam9pbignfCcpXG5cbiAgLy8gbXVzdCBtYXRjaCBlbnRpcmUgcGF0dGVyblxuICAvLyBlbmRpbmcgaW4gYSAqIG9yICoqIHdpbGwgbWFrZSBpdCBsZXNzIHN0cmljdC5cbiAgcmUgPSAnXig/OicgKyByZSArICcpJCdcblxuICAvLyBjYW4gbWF0Y2ggYW55dGhpbmcsIGFzIGxvbmcgYXMgaXQncyBub3QgdGhpcy5cbiAgaWYgKHRoaXMubmVnYXRlKSByZSA9ICdeKD8hJyArIHJlICsgJykuKiQnXG5cbiAgdHJ5IHtcbiAgICB0aGlzLnJlZ2V4cCA9IG5ldyBSZWdFeHAocmUsIGZsYWdzKVxuICB9IGNhdGNoIChleCkge1xuICAgIHRoaXMucmVnZXhwID0gZmFsc2VcbiAgfVxuICByZXR1cm4gdGhpcy5yZWdleHBcbn1cblxubWluaW1hdGNoLm1hdGNoID0gZnVuY3Rpb24gKGxpc3QsIHBhdHRlcm4sIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge31cbiAgdmFyIG1tID0gbmV3IE1pbmltYXRjaChwYXR0ZXJuLCBvcHRpb25zKVxuICBsaXN0ID0gbGlzdC5maWx0ZXIoZnVuY3Rpb24gKGYpIHtcbiAgICByZXR1cm4gbW0ubWF0Y2goZilcbiAgfSlcbiAgaWYgKG1tLm9wdGlvbnMubm9udWxsICYmICFsaXN0Lmxlbmd0aCkge1xuICAgIGxpc3QucHVzaChwYXR0ZXJuKVxuICB9XG4gIHJldHVybiBsaXN0XG59XG5cbk1pbmltYXRjaC5wcm90b3R5cGUubWF0Y2ggPSBtYXRjaFxuZnVuY3Rpb24gbWF0Y2ggKGYsIHBhcnRpYWwpIHtcbiAgdGhpcy5kZWJ1ZygnbWF0Y2gnLCBmLCB0aGlzLnBhdHRlcm4pXG4gIC8vIHNob3J0LWNpcmN1aXQgaW4gdGhlIGNhc2Ugb2YgYnVzdGVkIHRoaW5ncy5cbiAgLy8gY29tbWVudHMsIGV0Yy5cbiAgaWYgKHRoaXMuY29tbWVudCkgcmV0dXJuIGZhbHNlXG4gIGlmICh0aGlzLmVtcHR5KSByZXR1cm4gZiA9PT0gJydcblxuICBpZiAoZiA9PT0gJy8nICYmIHBhcnRpYWwpIHJldHVybiB0cnVlXG5cbiAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnNcblxuICAvLyB3aW5kb3dzOiBuZWVkIHRvIHVzZSAvLCBub3QgXFxcbiAgaWYgKHBhdGguc2VwICE9PSAnLycpIHtcbiAgICBmID0gZi5zcGxpdChwYXRoLnNlcCkuam9pbignLycpXG4gIH1cblxuICAvLyB0cmVhdCB0aGUgdGVzdCBwYXRoIGFzIGEgc2V0IG9mIHBhdGhwYXJ0cy5cbiAgZiA9IGYuc3BsaXQoc2xhc2hTcGxpdClcbiAgdGhpcy5kZWJ1Zyh0aGlzLnBhdHRlcm4sICdzcGxpdCcsIGYpXG5cbiAgLy8ganVzdCBPTkUgb2YgdGhlIHBhdHRlcm4gc2V0cyBpbiB0aGlzLnNldCBuZWVkcyB0byBtYXRjaFxuICAvLyBpbiBvcmRlciBmb3IgaXQgdG8gYmUgdmFsaWQuICBJZiBuZWdhdGluZywgdGhlbiBqdXN0IG9uZVxuICAvLyBtYXRjaCBtZWFucyB0aGF0IHdlIGhhdmUgZmFpbGVkLlxuICAvLyBFaXRoZXIgd2F5LCByZXR1cm4gb24gdGhlIGZpcnN0IGhpdC5cblxuICB2YXIgc2V0ID0gdGhpcy5zZXRcbiAgdGhpcy5kZWJ1Zyh0aGlzLnBhdHRlcm4sICdzZXQnLCBzZXQpXG5cbiAgLy8gRmluZCB0aGUgYmFzZW5hbWUgb2YgdGhlIHBhdGggYnkgbG9va2luZyBmb3IgdGhlIGxhc3Qgbm9uLWVtcHR5IHNlZ21lbnRcbiAgdmFyIGZpbGVuYW1lXG4gIHZhciBpXG4gIGZvciAoaSA9IGYubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBmaWxlbmFtZSA9IGZbaV1cbiAgICBpZiAoZmlsZW5hbWUpIGJyZWFrXG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDwgc2V0Lmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhdHRlcm4gPSBzZXRbaV1cbiAgICB2YXIgZmlsZSA9IGZcbiAgICBpZiAob3B0aW9ucy5tYXRjaEJhc2UgJiYgcGF0dGVybi5sZW5ndGggPT09IDEpIHtcbiAgICAgIGZpbGUgPSBbZmlsZW5hbWVdXG4gICAgfVxuICAgIHZhciBoaXQgPSB0aGlzLm1hdGNoT25lKGZpbGUsIHBhdHRlcm4sIHBhcnRpYWwpXG4gICAgaWYgKGhpdCkge1xuICAgICAgaWYgKG9wdGlvbnMuZmxpcE5lZ2F0ZSkgcmV0dXJuIHRydWVcbiAgICAgIHJldHVybiAhdGhpcy5uZWdhdGVcbiAgICB9XG4gIH1cblxuICAvLyBkaWRuJ3QgZ2V0IGFueSBoaXRzLiAgdGhpcyBpcyBzdWNjZXNzIGlmIGl0J3MgYSBuZWdhdGl2ZVxuICAvLyBwYXR0ZXJuLCBmYWlsdXJlIG90aGVyd2lzZS5cbiAgaWYgKG9wdGlvbnMuZmxpcE5lZ2F0ZSkgcmV0dXJuIGZhbHNlXG4gIHJldHVybiB0aGlzLm5lZ2F0ZVxufVxuXG4vLyBzZXQgcGFydGlhbCB0byB0cnVlIHRvIHRlc3QgaWYsIGZvciBleGFtcGxlLFxuLy8gXCIvYS9iXCIgbWF0Y2hlcyB0aGUgc3RhcnQgb2YgXCIvKi9iLyovZFwiXG4vLyBQYXJ0aWFsIG1lYW5zLCBpZiB5b3UgcnVuIG91dCBvZiBmaWxlIGJlZm9yZSB5b3UgcnVuXG4vLyBvdXQgb2YgcGF0dGVybiwgdGhlbiB0aGF0J3MgZmluZSwgYXMgbG9uZyBhcyBhbGxcbi8vIHRoZSBwYXJ0cyBtYXRjaC5cbk1pbmltYXRjaC5wcm90b3R5cGUubWF0Y2hPbmUgPSBmdW5jdGlvbiAoZmlsZSwgcGF0dGVybiwgcGFydGlhbCkge1xuICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9uc1xuXG4gIHRoaXMuZGVidWcoJ21hdGNoT25lJyxcbiAgICB7ICd0aGlzJzogdGhpcywgZmlsZTogZmlsZSwgcGF0dGVybjogcGF0dGVybiB9KVxuXG4gIHRoaXMuZGVidWcoJ21hdGNoT25lJywgZmlsZS5sZW5ndGgsIHBhdHRlcm4ubGVuZ3RoKVxuXG4gIGZvciAodmFyIGZpID0gMCxcbiAgICAgIHBpID0gMCxcbiAgICAgIGZsID0gZmlsZS5sZW5ndGgsXG4gICAgICBwbCA9IHBhdHRlcm4ubGVuZ3RoXG4gICAgICA7IChmaSA8IGZsKSAmJiAocGkgPCBwbClcbiAgICAgIDsgZmkrKywgcGkrKykge1xuICAgIHRoaXMuZGVidWcoJ21hdGNoT25lIGxvb3AnKVxuICAgIHZhciBwID0gcGF0dGVybltwaV1cbiAgICB2YXIgZiA9IGZpbGVbZmldXG5cbiAgICB0aGlzLmRlYnVnKHBhdHRlcm4sIHAsIGYpXG5cbiAgICAvLyBzaG91bGQgYmUgaW1wb3NzaWJsZS5cbiAgICAvLyBzb21lIGludmFsaWQgcmVnZXhwIHN0dWZmIGluIHRoZSBzZXQuXG4gICAgaWYgKHAgPT09IGZhbHNlKSByZXR1cm4gZmFsc2VcblxuICAgIGlmIChwID09PSBHTE9CU1RBUikge1xuICAgICAgdGhpcy5kZWJ1ZygnR0xPQlNUQVInLCBbcGF0dGVybiwgcCwgZl0pXG5cbiAgICAgIC8vIFwiKipcIlxuICAgICAgLy8gYS8qKi9iLyoqL2Mgd291bGQgbWF0Y2ggdGhlIGZvbGxvd2luZzpcbiAgICAgIC8vIGEvYi94L3kvei9jXG4gICAgICAvLyBhL3gveS96L2IvY1xuICAgICAgLy8gYS9iL3gvYi94L2NcbiAgICAgIC8vIGEvYi9jXG4gICAgICAvLyBUbyBkbyB0aGlzLCB0YWtlIHRoZSByZXN0IG9mIHRoZSBwYXR0ZXJuIGFmdGVyXG4gICAgICAvLyB0aGUgKiosIGFuZCBzZWUgaWYgaXQgd291bGQgbWF0Y2ggdGhlIGZpbGUgcmVtYWluZGVyLlxuICAgICAgLy8gSWYgc28sIHJldHVybiBzdWNjZXNzLlxuICAgICAgLy8gSWYgbm90LCB0aGUgKiogXCJzd2FsbG93c1wiIGEgc2VnbWVudCwgYW5kIHRyeSBhZ2Fpbi5cbiAgICAgIC8vIFRoaXMgaXMgcmVjdXJzaXZlbHkgYXdmdWwuXG4gICAgICAvL1xuICAgICAgLy8gYS8qKi9iLyoqL2MgbWF0Y2hpbmcgYS9iL3gveS96L2NcbiAgICAgIC8vIC0gYSBtYXRjaGVzIGFcbiAgICAgIC8vIC0gZG91Ymxlc3RhclxuICAgICAgLy8gICAtIG1hdGNoT25lKGIveC95L3ovYywgYi8qKi9jKVxuICAgICAgLy8gICAgIC0gYiBtYXRjaGVzIGJcbiAgICAgIC8vICAgICAtIGRvdWJsZXN0YXJcbiAgICAgIC8vICAgICAgIC0gbWF0Y2hPbmUoeC95L3ovYywgYykgLT4gbm9cbiAgICAgIC8vICAgICAgIC0gbWF0Y2hPbmUoeS96L2MsIGMpIC0+IG5vXG4gICAgICAvLyAgICAgICAtIG1hdGNoT25lKHovYywgYykgLT4gbm9cbiAgICAgIC8vICAgICAgIC0gbWF0Y2hPbmUoYywgYykgeWVzLCBoaXRcbiAgICAgIHZhciBmciA9IGZpXG4gICAgICB2YXIgcHIgPSBwaSArIDFcbiAgICAgIGlmIChwciA9PT0gcGwpIHtcbiAgICAgICAgdGhpcy5kZWJ1ZygnKiogYXQgdGhlIGVuZCcpXG4gICAgICAgIC8vIGEgKiogYXQgdGhlIGVuZCB3aWxsIGp1c3Qgc3dhbGxvdyB0aGUgcmVzdC5cbiAgICAgICAgLy8gV2UgaGF2ZSBmb3VuZCBhIG1hdGNoLlxuICAgICAgICAvLyBob3dldmVyLCBpdCB3aWxsIG5vdCBzd2FsbG93IC8ueCwgdW5sZXNzXG4gICAgICAgIC8vIG9wdGlvbnMuZG90IGlzIHNldC5cbiAgICAgICAgLy8gLiBhbmQgLi4gYXJlICpuZXZlciogbWF0Y2hlZCBieSAqKiwgZm9yIGV4cGxvc2l2ZWx5XG4gICAgICAgIC8vIGV4cG9uZW50aWFsIHJlYXNvbnMuXG4gICAgICAgIGZvciAoOyBmaSA8IGZsOyBmaSsrKSB7XG4gICAgICAgICAgaWYgKGZpbGVbZmldID09PSAnLicgfHwgZmlsZVtmaV0gPT09ICcuLicgfHxcbiAgICAgICAgICAgICghb3B0aW9ucy5kb3QgJiYgZmlsZVtmaV0uY2hhckF0KDApID09PSAnLicpKSByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuXG4gICAgICAvLyBvaywgbGV0J3Mgc2VlIGlmIHdlIGNhbiBzd2FsbG93IHdoYXRldmVyIHdlIGNhbi5cbiAgICAgIHdoaWxlIChmciA8IGZsKSB7XG4gICAgICAgIHZhciBzd2FsbG93ZWUgPSBmaWxlW2ZyXVxuXG4gICAgICAgIHRoaXMuZGVidWcoJ1xcbmdsb2JzdGFyIHdoaWxlJywgZmlsZSwgZnIsIHBhdHRlcm4sIHByLCBzd2FsbG93ZWUpXG5cbiAgICAgICAgLy8gWFhYIHJlbW92ZSB0aGlzIHNsaWNlLiAgSnVzdCBwYXNzIHRoZSBzdGFydCBpbmRleC5cbiAgICAgICAgaWYgKHRoaXMubWF0Y2hPbmUoZmlsZS5zbGljZShmciksIHBhdHRlcm4uc2xpY2UocHIpLCBwYXJ0aWFsKSkge1xuICAgICAgICAgIHRoaXMuZGVidWcoJ2dsb2JzdGFyIGZvdW5kIG1hdGNoIScsIGZyLCBmbCwgc3dhbGxvd2VlKVxuICAgICAgICAgIC8vIGZvdW5kIGEgbWF0Y2guXG4gICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBjYW4ndCBzd2FsbG93IFwiLlwiIG9yIFwiLi5cIiBldmVyLlxuICAgICAgICAgIC8vIGNhbiBvbmx5IHN3YWxsb3cgXCIuZm9vXCIgd2hlbiBleHBsaWNpdGx5IGFza2VkLlxuICAgICAgICAgIGlmIChzd2FsbG93ZWUgPT09ICcuJyB8fCBzd2FsbG93ZWUgPT09ICcuLicgfHxcbiAgICAgICAgICAgICghb3B0aW9ucy5kb3QgJiYgc3dhbGxvd2VlLmNoYXJBdCgwKSA9PT0gJy4nKSkge1xuICAgICAgICAgICAgdGhpcy5kZWJ1ZygnZG90IGRldGVjdGVkIScsIGZpbGUsIGZyLCBwYXR0ZXJuLCBwcilcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gKiogc3dhbGxvd3MgYSBzZWdtZW50LCBhbmQgY29udGludWUuXG4gICAgICAgICAgdGhpcy5kZWJ1ZygnZ2xvYnN0YXIgc3dhbGxvdyBhIHNlZ21lbnQsIGFuZCBjb250aW51ZScpXG4gICAgICAgICAgZnIrK1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIG5vIG1hdGNoIHdhcyBmb3VuZC5cbiAgICAgIC8vIEhvd2V2ZXIsIGluIHBhcnRpYWwgbW9kZSwgd2UgY2FuJ3Qgc2F5IHRoaXMgaXMgbmVjZXNzYXJpbHkgb3Zlci5cbiAgICAgIC8vIElmIHRoZXJlJ3MgbW9yZSAqcGF0dGVybiogbGVmdCwgdGhlblxuICAgICAgaWYgKHBhcnRpYWwpIHtcbiAgICAgICAgLy8gcmFuIG91dCBvZiBmaWxlXG4gICAgICAgIHRoaXMuZGVidWcoJ1xcbj4+PiBubyBtYXRjaCwgcGFydGlhbD8nLCBmaWxlLCBmciwgcGF0dGVybiwgcHIpXG4gICAgICAgIGlmIChmciA9PT0gZmwpIHJldHVybiB0cnVlXG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBzb21ldGhpbmcgb3RoZXIgdGhhbiAqKlxuICAgIC8vIG5vbi1tYWdpYyBwYXR0ZXJucyBqdXN0IGhhdmUgdG8gbWF0Y2ggZXhhY3RseVxuICAgIC8vIHBhdHRlcm5zIHdpdGggbWFnaWMgaGF2ZSBiZWVuIHR1cm5lZCBpbnRvIHJlZ2V4cHMuXG4gICAgdmFyIGhpdFxuICAgIGlmICh0eXBlb2YgcCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmIChvcHRpb25zLm5vY2FzZSkge1xuICAgICAgICBoaXQgPSBmLnRvTG93ZXJDYXNlKCkgPT09IHAudG9Mb3dlckNhc2UoKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaGl0ID0gZiA9PT0gcFxuICAgICAgfVxuICAgICAgdGhpcy5kZWJ1Zygnc3RyaW5nIG1hdGNoJywgcCwgZiwgaGl0KVxuICAgIH0gZWxzZSB7XG4gICAgICBoaXQgPSBmLm1hdGNoKHApXG4gICAgICB0aGlzLmRlYnVnKCdwYXR0ZXJuIG1hdGNoJywgcCwgZiwgaGl0KVxuICAgIH1cblxuICAgIGlmICghaGl0KSByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8vIE5vdGU6IGVuZGluZyBpbiAvIG1lYW5zIHRoYXQgd2UnbGwgZ2V0IGEgZmluYWwgXCJcIlxuICAvLyBhdCB0aGUgZW5kIG9mIHRoZSBwYXR0ZXJuLiAgVGhpcyBjYW4gb25seSBtYXRjaCBhXG4gIC8vIGNvcnJlc3BvbmRpbmcgXCJcIiBhdCB0aGUgZW5kIG9mIHRoZSBmaWxlLlxuICAvLyBJZiB0aGUgZmlsZSBlbmRzIGluIC8sIHRoZW4gaXQgY2FuIG9ubHkgbWF0Y2ggYVxuICAvLyBhIHBhdHRlcm4gdGhhdCBlbmRzIGluIC8sIHVubGVzcyB0aGUgcGF0dGVybiBqdXN0XG4gIC8vIGRvZXNuJ3QgaGF2ZSBhbnkgbW9yZSBmb3IgaXQuIEJ1dCwgYS9iLyBzaG91bGQgKm5vdCpcbiAgLy8gbWF0Y2ggXCJhL2IvKlwiLCBldmVuIHRob3VnaCBcIlwiIG1hdGNoZXMgYWdhaW5zdCB0aGVcbiAgLy8gW14vXSo/IHBhdHRlcm4sIGV4Y2VwdCBpbiBwYXJ0aWFsIG1vZGUsIHdoZXJlIGl0IG1pZ2h0XG4gIC8vIHNpbXBseSBub3QgYmUgcmVhY2hlZCB5ZXQuXG4gIC8vIEhvd2V2ZXIsIGEvYi8gc2hvdWxkIHN0aWxsIHNhdGlzZnkgYS8qXG5cbiAgLy8gbm93IGVpdGhlciB3ZSBmZWxsIG9mZiB0aGUgZW5kIG9mIHRoZSBwYXR0ZXJuLCBvciB3ZSdyZSBkb25lLlxuICBpZiAoZmkgPT09IGZsICYmIHBpID09PSBwbCkge1xuICAgIC8vIHJhbiBvdXQgb2YgcGF0dGVybiBhbmQgZmlsZW5hbWUgYXQgdGhlIHNhbWUgdGltZS5cbiAgICAvLyBhbiBleGFjdCBoaXQhXG4gICAgcmV0dXJuIHRydWVcbiAgfSBlbHNlIGlmIChmaSA9PT0gZmwpIHtcbiAgICAvLyByYW4gb3V0IG9mIGZpbGUsIGJ1dCBzdGlsbCBoYWQgcGF0dGVybiBsZWZ0LlxuICAgIC8vIHRoaXMgaXMgb2sgaWYgd2UncmUgZG9pbmcgdGhlIG1hdGNoIGFzIHBhcnQgb2ZcbiAgICAvLyBhIGdsb2IgZnMgdHJhdmVyc2FsLlxuICAgIHJldHVybiBwYXJ0aWFsXG4gIH0gZWxzZSBpZiAocGkgPT09IHBsKSB7XG4gICAgLy8gcmFuIG91dCBvZiBwYXR0ZXJuLCBzdGlsbCBoYXZlIGZpbGUgbGVmdC5cbiAgICAvLyB0aGlzIGlzIG9ubHkgYWNjZXB0YWJsZSBpZiB3ZSdyZSBvbiB0aGUgdmVyeSBsYXN0XG4gICAgLy8gZW1wdHkgc2VnbWVudCBvZiBhIGZpbGUgd2l0aCBhIHRyYWlsaW5nIHNsYXNoLlxuICAgIC8vIGEvKiBzaG91bGQgbWF0Y2ggYS9iL1xuICAgIHZhciBlbXB0eUZpbGVFbmQgPSAoZmkgPT09IGZsIC0gMSkgJiYgKGZpbGVbZmldID09PSAnJylcbiAgICByZXR1cm4gZW1wdHlGaWxlRW5kXG4gIH1cblxuICAvLyBzaG91bGQgYmUgdW5yZWFjaGFibGUuXG4gIHRocm93IG5ldyBFcnJvcignd3RmPycpXG59XG5cbi8vIHJlcGxhY2Ugc3R1ZmYgbGlrZSBcXCogd2l0aCAqXG5mdW5jdGlvbiBnbG9iVW5lc2NhcGUgKHMpIHtcbiAgcmV0dXJuIHMucmVwbGFjZSgvXFxcXCguKS9nLCAnJDEnKVxufVxuXG5mdW5jdGlvbiByZWdFeHBFc2NhcGUgKHMpIHtcbiAgcmV0dXJuIHMucmVwbGFjZSgvWy1bXFxde30oKSorPy4sXFxcXF4kfCNcXHNdL2csICdcXFxcJCYnKVxufVxuIiwiLy8gdmltOnRzPTQ6c3RzPTQ6c3c9NDpcbi8qIVxuICpcbiAqIENvcHlyaWdodCAyMDA5LTIwMTcgS3JpcyBLb3dhbCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIE1JVFxuICogbGljZW5zZSBmb3VuZCBhdCBodHRwczovL2dpdGh1Yi5jb20va3Jpc2tvd2FsL3EvYmxvYi92MS9MSUNFTlNFXG4gKlxuICogV2l0aCBwYXJ0cyBieSBUeWxlciBDbG9zZVxuICogQ29weXJpZ2h0IDIwMDctMjAwOSBUeWxlciBDbG9zZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIE1JVCBYIGxpY2Vuc2UgZm91bmRcbiAqIGF0IGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UuaHRtbFxuICogRm9ya2VkIGF0IHJlZl9zZW5kLmpzIHZlcnNpb246IDIwMDktMDUtMTFcbiAqXG4gKiBXaXRoIHBhcnRzIGJ5IE1hcmsgTWlsbGVyXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTEgR29vZ2xlIEluYy5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuKGZ1bmN0aW9uIChkZWZpbml0aW9uKSB7XG4gICAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgICAvLyBUaGlzIGZpbGUgd2lsbCBmdW5jdGlvbiBwcm9wZXJseSBhcyBhIDxzY3JpcHQ+IHRhZywgb3IgYSBtb2R1bGVcbiAgICAvLyB1c2luZyBDb21tb25KUyBhbmQgTm9kZUpTIG9yIFJlcXVpcmVKUyBtb2R1bGUgZm9ybWF0cy4gIEluXG4gICAgLy8gQ29tbW9uL05vZGUvUmVxdWlyZUpTLCB0aGUgbW9kdWxlIGV4cG9ydHMgdGhlIFEgQVBJIGFuZCB3aGVuXG4gICAgLy8gZXhlY3V0ZWQgYXMgYSBzaW1wbGUgPHNjcmlwdD4sIGl0IGNyZWF0ZXMgYSBRIGdsb2JhbCBpbnN0ZWFkLlxuXG4gICAgLy8gTW9udGFnZSBSZXF1aXJlXG4gICAgaWYgKHR5cGVvZiBib290c3RyYXAgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBib290c3RyYXAoXCJwcm9taXNlXCIsIGRlZmluaXRpb24pO1xuXG4gICAgLy8gQ29tbW9uSlNcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBkZWZpbml0aW9uKCk7XG5cbiAgICAvLyBSZXF1aXJlSlNcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShkZWZpbml0aW9uKTtcblxuICAgIC8vIFNFUyAoU2VjdXJlIEVjbWFTY3JpcHQpXG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygc2VzICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIGlmICghc2VzLm9rKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNlcy5tYWtlUSA9IGRlZmluaXRpb247XG4gICAgICAgIH1cblxuICAgIC8vIDxzY3JpcHQ+XG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiIHx8IHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIC8vIFByZWZlciB3aW5kb3cgb3ZlciBzZWxmIGZvciBhZGQtb24gc2NyaXB0cy4gVXNlIHNlbGYgZm9yXG4gICAgICAgIC8vIG5vbi13aW5kb3dlZCBjb250ZXh0cy5cbiAgICAgICAgdmFyIGdsb2JhbCA9IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiBzZWxmO1xuXG4gICAgICAgIC8vIEdldCB0aGUgYHdpbmRvd2Agb2JqZWN0LCBzYXZlIHRoZSBwcmV2aW91cyBRIGdsb2JhbFxuICAgICAgICAvLyBhbmQgaW5pdGlhbGl6ZSBRIGFzIGEgZ2xvYmFsLlxuICAgICAgICB2YXIgcHJldmlvdXNRID0gZ2xvYmFsLlE7XG4gICAgICAgIGdsb2JhbC5RID0gZGVmaW5pdGlvbigpO1xuXG4gICAgICAgIC8vIEFkZCBhIG5vQ29uZmxpY3QgZnVuY3Rpb24gc28gUSBjYW4gYmUgcmVtb3ZlZCBmcm9tIHRoZVxuICAgICAgICAvLyBnbG9iYWwgbmFtZXNwYWNlLlxuICAgICAgICBnbG9iYWwuUS5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZ2xvYmFsLlEgPSBwcmV2aW91c1E7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgZW52aXJvbm1lbnQgd2FzIG5vdCBhbnRpY2lwYXRlZCBieSBRLiBQbGVhc2UgZmlsZSBhIGJ1Zy5cIik7XG4gICAgfVxuXG59KShmdW5jdGlvbiAoKSB7XG5cInVzZSBzdHJpY3RcIjtcblxudmFyIGhhc1N0YWNrcyA9IGZhbHNlO1xudHJ5IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbn0gY2F0Y2ggKGUpIHtcbiAgICBoYXNTdGFja3MgPSAhIWUuc3RhY2s7XG59XG5cbi8vIEFsbCBjb2RlIGFmdGVyIHRoaXMgcG9pbnQgd2lsbCBiZSBmaWx0ZXJlZCBmcm9tIHN0YWNrIHRyYWNlcyByZXBvcnRlZFxuLy8gYnkgUS5cbnZhciBxU3RhcnRpbmdMaW5lID0gY2FwdHVyZUxpbmUoKTtcbnZhciBxRmlsZU5hbWU7XG5cbi8vIHNoaW1zXG5cbi8vIHVzZWQgZm9yIGZhbGxiYWNrIGluIFwiYWxsUmVzb2x2ZWRcIlxudmFyIG5vb3AgPSBmdW5jdGlvbiAoKSB7fTtcblxuLy8gVXNlIHRoZSBmYXN0ZXN0IHBvc3NpYmxlIG1lYW5zIHRvIGV4ZWN1dGUgYSB0YXNrIGluIGEgZnV0dXJlIHR1cm5cbi8vIG9mIHRoZSBldmVudCBsb29wLlxudmFyIG5leHRUaWNrID0oZnVuY3Rpb24gKCkge1xuICAgIC8vIGxpbmtlZCBsaXN0IG9mIHRhc2tzIChzaW5nbGUsIHdpdGggaGVhZCBub2RlKVxuICAgIHZhciBoZWFkID0ge3Rhc2s6IHZvaWQgMCwgbmV4dDogbnVsbH07XG4gICAgdmFyIHRhaWwgPSBoZWFkO1xuICAgIHZhciBmbHVzaGluZyA9IGZhbHNlO1xuICAgIHZhciByZXF1ZXN0VGljayA9IHZvaWQgMDtcbiAgICB2YXIgaXNOb2RlSlMgPSBmYWxzZTtcbiAgICAvLyBxdWV1ZSBmb3IgbGF0ZSB0YXNrcywgdXNlZCBieSB1bmhhbmRsZWQgcmVqZWN0aW9uIHRyYWNraW5nXG4gICAgdmFyIGxhdGVyUXVldWUgPSBbXTtcblxuICAgIGZ1bmN0aW9uIGZsdXNoKCkge1xuICAgICAgICAvKiBqc2hpbnQgbG9vcGZ1bmM6IHRydWUgKi9cbiAgICAgICAgdmFyIHRhc2ssIGRvbWFpbjtcblxuICAgICAgICB3aGlsZSAoaGVhZC5uZXh0KSB7XG4gICAgICAgICAgICBoZWFkID0gaGVhZC5uZXh0O1xuICAgICAgICAgICAgdGFzayA9IGhlYWQudGFzaztcbiAgICAgICAgICAgIGhlYWQudGFzayA9IHZvaWQgMDtcbiAgICAgICAgICAgIGRvbWFpbiA9IGhlYWQuZG9tYWluO1xuXG4gICAgICAgICAgICBpZiAoZG9tYWluKSB7XG4gICAgICAgICAgICAgICAgaGVhZC5kb21haW4gPSB2b2lkIDA7XG4gICAgICAgICAgICAgICAgZG9tYWluLmVudGVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBydW5TaW5nbGUodGFzaywgZG9tYWluKTtcblxuICAgICAgICB9XG4gICAgICAgIHdoaWxlIChsYXRlclF1ZXVlLmxlbmd0aCkge1xuICAgICAgICAgICAgdGFzayA9IGxhdGVyUXVldWUucG9wKCk7XG4gICAgICAgICAgICBydW5TaW5nbGUodGFzayk7XG4gICAgICAgIH1cbiAgICAgICAgZmx1c2hpbmcgPSBmYWxzZTtcbiAgICB9XG4gICAgLy8gcnVucyBhIHNpbmdsZSBmdW5jdGlvbiBpbiB0aGUgYXN5bmMgcXVldWVcbiAgICBmdW5jdGlvbiBydW5TaW5nbGUodGFzaywgZG9tYWluKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0YXNrKCk7XG5cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgaWYgKGlzTm9kZUpTKSB7XG4gICAgICAgICAgICAgICAgLy8gSW4gbm9kZSwgdW5jYXVnaHQgZXhjZXB0aW9ucyBhcmUgY29uc2lkZXJlZCBmYXRhbCBlcnJvcnMuXG4gICAgICAgICAgICAgICAgLy8gUmUtdGhyb3cgdGhlbSBzeW5jaHJvbm91c2x5IHRvIGludGVycnVwdCBmbHVzaGluZyFcblxuICAgICAgICAgICAgICAgIC8vIEVuc3VyZSBjb250aW51YXRpb24gaWYgdGhlIHVuY2F1Z2h0IGV4Y2VwdGlvbiBpcyBzdXBwcmVzc2VkXG4gICAgICAgICAgICAgICAgLy8gbGlzdGVuaW5nIFwidW5jYXVnaHRFeGNlcHRpb25cIiBldmVudHMgKGFzIGRvbWFpbnMgZG9lcykuXG4gICAgICAgICAgICAgICAgLy8gQ29udGludWUgaW4gbmV4dCBldmVudCB0byBhdm9pZCB0aWNrIHJlY3Vyc2lvbi5cbiAgICAgICAgICAgICAgICBpZiAoZG9tYWluKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbWFpbi5leGl0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZmx1c2gsIDApO1xuICAgICAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICAgICAgZG9tYWluLmVudGVyKCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBJbiBicm93c2VycywgdW5jYXVnaHQgZXhjZXB0aW9ucyBhcmUgbm90IGZhdGFsLlxuICAgICAgICAgICAgICAgIC8vIFJlLXRocm93IHRoZW0gYXN5bmNocm9ub3VzbHkgdG8gYXZvaWQgc2xvdy1kb3ducy5cbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgIGRvbWFpbi5leGl0KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBuZXh0VGljayA9IGZ1bmN0aW9uICh0YXNrKSB7XG4gICAgICAgIHRhaWwgPSB0YWlsLm5leHQgPSB7XG4gICAgICAgICAgICB0YXNrOiB0YXNrLFxuICAgICAgICAgICAgZG9tYWluOiBpc05vZGVKUyAmJiBwcm9jZXNzLmRvbWFpbixcbiAgICAgICAgICAgIG5leHQ6IG51bGxcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoIWZsdXNoaW5nKSB7XG4gICAgICAgICAgICBmbHVzaGluZyA9IHRydWU7XG4gICAgICAgICAgICByZXF1ZXN0VGljaygpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGlmICh0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgICBwcm9jZXNzLnRvU3RyaW5nKCkgPT09IFwiW29iamVjdCBwcm9jZXNzXVwiICYmIHByb2Nlc3MubmV4dFRpY2spIHtcbiAgICAgICAgLy8gRW5zdXJlIFEgaXMgaW4gYSByZWFsIE5vZGUgZW52aXJvbm1lbnQsIHdpdGggYSBgcHJvY2Vzcy5uZXh0VGlja2AuXG4gICAgICAgIC8vIFRvIHNlZSB0aHJvdWdoIGZha2UgTm9kZSBlbnZpcm9ubWVudHM6XG4gICAgICAgIC8vICogTW9jaGEgdGVzdCBydW5uZXIgLSBleHBvc2VzIGEgYHByb2Nlc3NgIGdsb2JhbCB3aXRob3V0IGEgYG5leHRUaWNrYFxuICAgICAgICAvLyAqIEJyb3dzZXJpZnkgLSBleHBvc2VzIGEgYHByb2Nlc3MubmV4VGlja2AgZnVuY3Rpb24gdGhhdCB1c2VzXG4gICAgICAgIC8vICAgYHNldFRpbWVvdXRgLiBJbiB0aGlzIGNhc2UgYHNldEltbWVkaWF0ZWAgaXMgcHJlZmVycmVkIGJlY2F1c2VcbiAgICAgICAgLy8gICAgaXQgaXMgZmFzdGVyLiBCcm93c2VyaWZ5J3MgYHByb2Nlc3MudG9TdHJpbmcoKWAgeWllbGRzXG4gICAgICAgIC8vICAgXCJbb2JqZWN0IE9iamVjdF1cIiwgd2hpbGUgaW4gYSByZWFsIE5vZGUgZW52aXJvbm1lbnRcbiAgICAgICAgLy8gICBgcHJvY2Vzcy50b1N0cmluZygpYCB5aWVsZHMgXCJbb2JqZWN0IHByb2Nlc3NdXCIuXG4gICAgICAgIGlzTm9kZUpTID0gdHJ1ZTtcblxuICAgICAgICByZXF1ZXN0VGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHByb2Nlc3MubmV4dFRpY2soZmx1c2gpO1xuICAgICAgICB9O1xuXG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygc2V0SW1tZWRpYXRlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgLy8gSW4gSUUxMCwgTm9kZS5qcyAwLjkrLCBvciBodHRwczovL2dpdGh1Yi5jb20vTm9ibGVKUy9zZXRJbW1lZGlhdGVcbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gc2V0SW1tZWRpYXRlLmJpbmQod2luZG93LCBmbHVzaCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXF1ZXN0VGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBzZXRJbW1lZGlhdGUoZmx1c2gpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgTWVzc2FnZUNoYW5uZWwgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgLy8gbW9kZXJuIGJyb3dzZXJzXG4gICAgICAgIC8vIGh0dHA6Ly93d3cubm9uYmxvY2tpbmcuaW8vMjAxMS8wNi93aW5kb3duZXh0dGljay5odG1sXG4gICAgICAgIHZhciBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgICAgIC8vIEF0IGxlYXN0IFNhZmFyaSBWZXJzaW9uIDYuMC41ICg4NTM2LjMwLjEpIGludGVybWl0dGVudGx5IGNhbm5vdCBjcmVhdGVcbiAgICAgICAgLy8gd29ya2luZyBtZXNzYWdlIHBvcnRzIHRoZSBmaXJzdCB0aW1lIGEgcGFnZSBsb2Fkcy5cbiAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXF1ZXN0VGljayA9IHJlcXVlc3RQb3J0VGljaztcbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gZmx1c2g7XG4gICAgICAgICAgICBmbHVzaCgpO1xuICAgICAgICB9O1xuICAgICAgICB2YXIgcmVxdWVzdFBvcnRUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy8gT3BlcmEgcmVxdWlyZXMgdXMgdG8gcHJvdmlkZSBhIG1lc3NhZ2UgcGF5bG9hZCwgcmVnYXJkbGVzcyBvZlxuICAgICAgICAgICAgLy8gd2hldGhlciB3ZSB1c2UgaXQuXG4gICAgICAgICAgICBjaGFubmVsLnBvcnQyLnBvc3RNZXNzYWdlKDApO1xuICAgICAgICB9O1xuICAgICAgICByZXF1ZXN0VGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZmx1c2gsIDApO1xuICAgICAgICAgICAgcmVxdWVzdFBvcnRUaWNrKCk7XG4gICAgICAgIH07XG5cbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBvbGQgYnJvd3NlcnNcbiAgICAgICAgcmVxdWVzdFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZsdXNoLCAwKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLy8gcnVucyBhIHRhc2sgYWZ0ZXIgYWxsIG90aGVyIHRhc2tzIGhhdmUgYmVlbiBydW5cbiAgICAvLyB0aGlzIGlzIHVzZWZ1bCBmb3IgdW5oYW5kbGVkIHJlamVjdGlvbiB0cmFja2luZyB0aGF0IG5lZWRzIHRvIGhhcHBlblxuICAgIC8vIGFmdGVyIGFsbCBgdGhlbmBkIHRhc2tzIGhhdmUgYmVlbiBydW4uXG4gICAgbmV4dFRpY2sucnVuQWZ0ZXIgPSBmdW5jdGlvbiAodGFzaykge1xuICAgICAgICBsYXRlclF1ZXVlLnB1c2godGFzayk7XG4gICAgICAgIGlmICghZmx1c2hpbmcpIHtcbiAgICAgICAgICAgIGZsdXNoaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBuZXh0VGljaztcbn0pKCk7XG5cbi8vIEF0dGVtcHQgdG8gbWFrZSBnZW5lcmljcyBzYWZlIGluIHRoZSBmYWNlIG9mIGRvd25zdHJlYW1cbi8vIG1vZGlmaWNhdGlvbnMuXG4vLyBUaGVyZSBpcyBubyBzaXR1YXRpb24gd2hlcmUgdGhpcyBpcyBuZWNlc3NhcnkuXG4vLyBJZiB5b3UgbmVlZCBhIHNlY3VyaXR5IGd1YXJhbnRlZSwgdGhlc2UgcHJpbW9yZGlhbHMgbmVlZCB0byBiZVxuLy8gZGVlcGx5IGZyb3plbiBhbnl3YXksIGFuZCBpZiB5b3UgZG9u4oCZdCBuZWVkIGEgc2VjdXJpdHkgZ3VhcmFudGVlLFxuLy8gdGhpcyBpcyBqdXN0IHBsYWluIHBhcmFub2lkLlxuLy8gSG93ZXZlciwgdGhpcyAqKm1pZ2h0KiogaGF2ZSB0aGUgbmljZSBzaWRlLWVmZmVjdCBvZiByZWR1Y2luZyB0aGUgc2l6ZSBvZlxuLy8gdGhlIG1pbmlmaWVkIGNvZGUgYnkgcmVkdWNpbmcgeC5jYWxsKCkgdG8gbWVyZWx5IHgoKVxuLy8gU2VlIE1hcmsgTWlsbGVy4oCZcyBleHBsYW5hdGlvbiBvZiB3aGF0IHRoaXMgZG9lcy5cbi8vIGh0dHA6Ly93aWtpLmVjbWFzY3JpcHQub3JnL2Rva3UucGhwP2lkPWNvbnZlbnRpb25zOnNhZmVfbWV0YV9wcm9ncmFtbWluZ1xudmFyIGNhbGwgPSBGdW5jdGlvbi5jYWxsO1xuZnVuY3Rpb24gdW5jdXJyeVRoaXMoZikge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBjYWxsLmFwcGx5KGYsIGFyZ3VtZW50cyk7XG4gICAgfTtcbn1cbi8vIFRoaXMgaXMgZXF1aXZhbGVudCwgYnV0IHNsb3dlcjpcbi8vIHVuY3VycnlUaGlzID0gRnVuY3Rpb25fYmluZC5iaW5kKEZ1bmN0aW9uX2JpbmQuY2FsbCk7XG4vLyBodHRwOi8vanNwZXJmLmNvbS91bmN1cnJ5dGhpc1xuXG52YXIgYXJyYXlfc2xpY2UgPSB1bmN1cnJ5VGhpcyhBcnJheS5wcm90b3R5cGUuc2xpY2UpO1xuXG52YXIgYXJyYXlfcmVkdWNlID0gdW5jdXJyeVRoaXMoXG4gICAgQXJyYXkucHJvdG90eXBlLnJlZHVjZSB8fCBmdW5jdGlvbiAoY2FsbGJhY2ssIGJhc2lzKSB7XG4gICAgICAgIHZhciBpbmRleCA9IDAsXG4gICAgICAgICAgICBsZW5ndGggPSB0aGlzLmxlbmd0aDtcbiAgICAgICAgLy8gY29uY2VybmluZyB0aGUgaW5pdGlhbCB2YWx1ZSwgaWYgb25lIGlzIG5vdCBwcm92aWRlZFxuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgLy8gc2VlayB0byB0aGUgZmlyc3QgdmFsdWUgaW4gdGhlIGFycmF5LCBhY2NvdW50aW5nXG4gICAgICAgICAgICAvLyBmb3IgdGhlIHBvc3NpYmlsaXR5IHRoYXQgaXMgaXMgYSBzcGFyc2UgYXJyYXlcbiAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggaW4gdGhpcykge1xuICAgICAgICAgICAgICAgICAgICBiYXNpcyA9IHRoaXNbaW5kZXgrK107XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoKytpbmRleCA+PSBsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gd2hpbGUgKDEpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHJlZHVjZVxuICAgICAgICBmb3IgKDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgICAgIC8vIGFjY291bnQgZm9yIHRoZSBwb3NzaWJpbGl0eSB0aGF0IHRoZSBhcnJheSBpcyBzcGFyc2VcbiAgICAgICAgICAgIGlmIChpbmRleCBpbiB0aGlzKSB7XG4gICAgICAgICAgICAgICAgYmFzaXMgPSBjYWxsYmFjayhiYXNpcywgdGhpc1tpbmRleF0sIGluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYmFzaXM7XG4gICAgfVxuKTtcblxudmFyIGFycmF5X2luZGV4T2YgPSB1bmN1cnJ5VGhpcyhcbiAgICBBcnJheS5wcm90b3R5cGUuaW5kZXhPZiB8fCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgLy8gbm90IGEgdmVyeSBnb29kIHNoaW0sIGJ1dCBnb29kIGVub3VnaCBmb3Igb3VyIG9uZSB1c2Ugb2YgaXRcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpc1tpXSA9PT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuKTtcblxudmFyIGFycmF5X21hcCA9IHVuY3VycnlUaGlzKFxuICAgIEFycmF5LnByb3RvdHlwZS5tYXAgfHwgZnVuY3Rpb24gKGNhbGxiYWNrLCB0aGlzcCkge1xuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgIHZhciBjb2xsZWN0ID0gW107XG4gICAgICAgIGFycmF5X3JlZHVjZShzZWxmLCBmdW5jdGlvbiAodW5kZWZpbmVkLCB2YWx1ZSwgaW5kZXgpIHtcbiAgICAgICAgICAgIGNvbGxlY3QucHVzaChjYWxsYmFjay5jYWxsKHRoaXNwLCB2YWx1ZSwgaW5kZXgsIHNlbGYpKTtcbiAgICAgICAgfSwgdm9pZCAwKTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Q7XG4gICAgfVxuKTtcblxudmFyIG9iamVjdF9jcmVhdGUgPSBPYmplY3QuY3JlYXRlIHx8IGZ1bmN0aW9uIChwcm90b3R5cGUpIHtcbiAgICBmdW5jdGlvbiBUeXBlKCkgeyB9XG4gICAgVHlwZS5wcm90b3R5cGUgPSBwcm90b3R5cGU7XG4gICAgcmV0dXJuIG5ldyBUeXBlKCk7XG59O1xuXG52YXIgb2JqZWN0X2RlZmluZVByb3BlcnR5ID0gT2JqZWN0LmRlZmluZVByb3BlcnR5IHx8IGZ1bmN0aW9uIChvYmosIHByb3AsIGRlc2NyaXB0b3IpIHtcbiAgICBvYmpbcHJvcF0gPSBkZXNjcmlwdG9yLnZhbHVlO1xuICAgIHJldHVybiBvYmo7XG59O1xuXG52YXIgb2JqZWN0X2hhc093blByb3BlcnR5ID0gdW5jdXJyeVRoaXMoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSk7XG5cbnZhciBvYmplY3Rfa2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICB2YXIga2V5cyA9IFtdO1xuICAgIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICAgICAgaWYgKG9iamVjdF9oYXNPd25Qcm9wZXJ0eShvYmplY3QsIGtleSkpIHtcbiAgICAgICAgICAgIGtleXMucHVzaChrZXkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBrZXlzO1xufTtcblxudmFyIG9iamVjdF90b1N0cmluZyA9IHVuY3VycnlUaGlzKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcpO1xuXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSA9PT0gT2JqZWN0KHZhbHVlKTtcbn1cblxuLy8gZ2VuZXJhdG9yIHJlbGF0ZWQgc2hpbXNcblxuLy8gRklYTUU6IFJlbW92ZSB0aGlzIGZ1bmN0aW9uIG9uY2UgRVM2IGdlbmVyYXRvcnMgYXJlIGluIFNwaWRlck1vbmtleS5cbmZ1bmN0aW9uIGlzU3RvcEl0ZXJhdGlvbihleGNlcHRpb24pIHtcbiAgICByZXR1cm4gKFxuICAgICAgICBvYmplY3RfdG9TdHJpbmcoZXhjZXB0aW9uKSA9PT0gXCJbb2JqZWN0IFN0b3BJdGVyYXRpb25dXCIgfHxcbiAgICAgICAgZXhjZXB0aW9uIGluc3RhbmNlb2YgUVJldHVyblZhbHVlXG4gICAgKTtcbn1cblxuLy8gRklYTUU6IFJlbW92ZSB0aGlzIGhlbHBlciBhbmQgUS5yZXR1cm4gb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW5cbi8vIFNwaWRlck1vbmtleS5cbnZhciBRUmV0dXJuVmFsdWU7XG5pZiAodHlwZW9mIFJldHVyblZhbHVlICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgUVJldHVyblZhbHVlID0gUmV0dXJuVmFsdWU7XG59IGVsc2Uge1xuICAgIFFSZXR1cm5WYWx1ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgfTtcbn1cblxuLy8gbG9uZyBzdGFjayB0cmFjZXNcblxudmFyIFNUQUNLX0pVTVBfU0VQQVJBVE9SID0gXCJGcm9tIHByZXZpb3VzIGV2ZW50OlwiO1xuXG5mdW5jdGlvbiBtYWtlU3RhY2tUcmFjZUxvbmcoZXJyb3IsIHByb21pc2UpIHtcbiAgICAvLyBJZiBwb3NzaWJsZSwgdHJhbnNmb3JtIHRoZSBlcnJvciBzdGFjayB0cmFjZSBieSByZW1vdmluZyBOb2RlIGFuZCBRXG4gICAgLy8gY3J1ZnQsIHRoZW4gY29uY2F0ZW5hdGluZyB3aXRoIHRoZSBzdGFjayB0cmFjZSBvZiBgcHJvbWlzZWAuIFNlZSAjNTcuXG4gICAgaWYgKGhhc1N0YWNrcyAmJlxuICAgICAgICBwcm9taXNlLnN0YWNrICYmXG4gICAgICAgIHR5cGVvZiBlcnJvciA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgICBlcnJvciAhPT0gbnVsbCAmJlxuICAgICAgICBlcnJvci5zdGFja1xuICAgICkge1xuICAgICAgICB2YXIgc3RhY2tzID0gW107XG4gICAgICAgIGZvciAodmFyIHAgPSBwcm9taXNlOyAhIXA7IHAgPSBwLnNvdXJjZSkge1xuICAgICAgICAgICAgaWYgKHAuc3RhY2sgJiYgKCFlcnJvci5fX21pbmltdW1TdGFja0NvdW50ZXJfXyB8fCBlcnJvci5fX21pbmltdW1TdGFja0NvdW50ZXJfXyA+IHAuc3RhY2tDb3VudGVyKSkge1xuICAgICAgICAgICAgICAgIG9iamVjdF9kZWZpbmVQcm9wZXJ0eShlcnJvciwgXCJfX21pbmltdW1TdGFja0NvdW50ZXJfX1wiLCB7dmFsdWU6IHAuc3RhY2tDb3VudGVyLCBjb25maWd1cmFibGU6IHRydWV9KTtcbiAgICAgICAgICAgICAgICBzdGFja3MudW5zaGlmdChwLnN0YWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdGFja3MudW5zaGlmdChlcnJvci5zdGFjayk7XG5cbiAgICAgICAgdmFyIGNvbmNhdGVkU3RhY2tzID0gc3RhY2tzLmpvaW4oXCJcXG5cIiArIFNUQUNLX0pVTVBfU0VQQVJBVE9SICsgXCJcXG5cIik7XG4gICAgICAgIHZhciBzdGFjayA9IGZpbHRlclN0YWNrU3RyaW5nKGNvbmNhdGVkU3RhY2tzKTtcbiAgICAgICAgb2JqZWN0X2RlZmluZVByb3BlcnR5KGVycm9yLCBcInN0YWNrXCIsIHt2YWx1ZTogc3RhY2ssIGNvbmZpZ3VyYWJsZTogdHJ1ZX0pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZmlsdGVyU3RhY2tTdHJpbmcoc3RhY2tTdHJpbmcpIHtcbiAgICB2YXIgbGluZXMgPSBzdGFja1N0cmluZy5zcGxpdChcIlxcblwiKTtcbiAgICB2YXIgZGVzaXJlZExpbmVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgbGluZSA9IGxpbmVzW2ldO1xuXG4gICAgICAgIGlmICghaXNJbnRlcm5hbEZyYW1lKGxpbmUpICYmICFpc05vZGVGcmFtZShsaW5lKSAmJiBsaW5lKSB7XG4gICAgICAgICAgICBkZXNpcmVkTGluZXMucHVzaChsaW5lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVzaXJlZExpbmVzLmpvaW4oXCJcXG5cIik7XG59XG5cbmZ1bmN0aW9uIGlzTm9kZUZyYW1lKHN0YWNrTGluZSkge1xuICAgIHJldHVybiBzdGFja0xpbmUuaW5kZXhPZihcIihtb2R1bGUuanM6XCIpICE9PSAtMSB8fFxuICAgICAgICAgICBzdGFja0xpbmUuaW5kZXhPZihcIihub2RlLmpzOlwiKSAhPT0gLTE7XG59XG5cbmZ1bmN0aW9uIGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpIHtcbiAgICAvLyBOYW1lZCBmdW5jdGlvbnM6IFwiYXQgZnVuY3Rpb25OYW1lIChmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlcilcIlxuICAgIC8vIEluIElFMTAgZnVuY3Rpb24gbmFtZSBjYW4gaGF2ZSBzcGFjZXMgKFwiQW5vbnltb3VzIGZ1bmN0aW9uXCIpIE9fb1xuICAgIHZhciBhdHRlbXB0MSA9IC9hdCAuKyBcXCgoLispOihcXGQrKTooPzpcXGQrKVxcKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDEpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0MVsxXSwgTnVtYmVyKGF0dGVtcHQxWzJdKV07XG4gICAgfVxuXG4gICAgLy8gQW5vbnltb3VzIGZ1bmN0aW9uczogXCJhdCBmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlclwiXG4gICAgdmFyIGF0dGVtcHQyID0gL2F0IChbXiBdKyk6KFxcZCspOig/OlxcZCspJC8uZXhlYyhzdGFja0xpbmUpO1xuICAgIGlmIChhdHRlbXB0Mikge1xuICAgICAgICByZXR1cm4gW2F0dGVtcHQyWzFdLCBOdW1iZXIoYXR0ZW1wdDJbMl0pXTtcbiAgICB9XG5cbiAgICAvLyBGaXJlZm94IHN0eWxlOiBcImZ1bmN0aW9uQGZpbGVuYW1lOmxpbmVOdW1iZXIgb3IgQGZpbGVuYW1lOmxpbmVOdW1iZXJcIlxuICAgIHZhciBhdHRlbXB0MyA9IC8uKkAoLispOihcXGQrKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDMpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0M1sxXSwgTnVtYmVyKGF0dGVtcHQzWzJdKV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc0ludGVybmFsRnJhbWUoc3RhY2tMaW5lKSB7XG4gICAgdmFyIGZpbGVOYW1lQW5kTGluZU51bWJlciA9IGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpO1xuXG4gICAgaWYgKCFmaWxlTmFtZUFuZExpbmVOdW1iZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBmaWxlTmFtZSA9IGZpbGVOYW1lQW5kTGluZU51bWJlclswXTtcbiAgICB2YXIgbGluZU51bWJlciA9IGZpbGVOYW1lQW5kTGluZU51bWJlclsxXTtcblxuICAgIHJldHVybiBmaWxlTmFtZSA9PT0gcUZpbGVOYW1lICYmXG4gICAgICAgIGxpbmVOdW1iZXIgPj0gcVN0YXJ0aW5nTGluZSAmJlxuICAgICAgICBsaW5lTnVtYmVyIDw9IHFFbmRpbmdMaW5lO1xufVxuXG4vLyBkaXNjb3ZlciBvd24gZmlsZSBuYW1lIGFuZCBsaW5lIG51bWJlciByYW5nZSBmb3IgZmlsdGVyaW5nIHN0YWNrXG4vLyB0cmFjZXNcbmZ1bmN0aW9uIGNhcHR1cmVMaW5lKCkge1xuICAgIGlmICghaGFzU3RhY2tzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHZhciBsaW5lcyA9IGUuc3RhY2suc3BsaXQoXCJcXG5cIik7XG4gICAgICAgIHZhciBmaXJzdExpbmUgPSBsaW5lc1swXS5pbmRleE9mKFwiQFwiKSA+IDAgPyBsaW5lc1sxXSA6IGxpbmVzWzJdO1xuICAgICAgICB2YXIgZmlsZU5hbWVBbmRMaW5lTnVtYmVyID0gZ2V0RmlsZU5hbWVBbmRMaW5lTnVtYmVyKGZpcnN0TGluZSk7XG4gICAgICAgIGlmICghZmlsZU5hbWVBbmRMaW5lTnVtYmVyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBxRmlsZU5hbWUgPSBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMF07XG4gICAgICAgIHJldHVybiBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkZXByZWNhdGUoY2FsbGJhY2ssIG5hbWUsIGFsdGVybmF0aXZlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICB0eXBlb2YgY29uc29sZS53YXJuID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihuYW1lICsgXCIgaXMgZGVwcmVjYXRlZCwgdXNlIFwiICsgYWx0ZXJuYXRpdmUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgIFwiIGluc3RlYWQuXCIsIG5ldyBFcnJvcihcIlwiKS5zdGFjayk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KGNhbGxiYWNrLCBhcmd1bWVudHMpO1xuICAgIH07XG59XG5cbi8vIGVuZCBvZiBzaGltc1xuLy8gYmVnaW5uaW5nIG9mIHJlYWwgd29ya1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLCBwYXNzZXMgcHJvbWlzZXMgdGhyb3VnaCwgb3JcbiAqIGNvZXJjZXMgcHJvbWlzZXMgZnJvbSBkaWZmZXJlbnQgc3lzdGVtcy5cbiAqIEBwYXJhbSB2YWx1ZSBpbW1lZGlhdGUgcmVmZXJlbmNlIG9yIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gUSh2YWx1ZSkge1xuICAgIC8vIElmIHRoZSBvYmplY3QgaXMgYWxyZWFkeSBhIFByb21pc2UsIHJldHVybiBpdCBkaXJlY3RseS4gIFRoaXMgZW5hYmxlc1xuICAgIC8vIHRoZSByZXNvbHZlIGZ1bmN0aW9uIHRvIGJvdGggYmUgdXNlZCB0byBjcmVhdGVkIHJlZmVyZW5jZXMgZnJvbSBvYmplY3RzLFxuICAgIC8vIGJ1dCB0byB0b2xlcmFibHkgY29lcmNlIG5vbi1wcm9taXNlcyB0byBwcm9taXNlcy5cbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBhc3NpbWlsYXRlIHRoZW5hYmxlc1xuICAgIGlmIChpc1Byb21pc2VBbGlrZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGNvZXJjZSh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGwodmFsdWUpO1xuICAgIH1cbn1cblEucmVzb2x2ZSA9IFE7XG5cbi8qKlxuICogUGVyZm9ybXMgYSB0YXNrIGluIGEgZnV0dXJlIHR1cm4gb2YgdGhlIGV2ZW50IGxvb3AuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0YXNrXG4gKi9cblEubmV4dFRpY2sgPSBuZXh0VGljaztcblxuLyoqXG4gKiBDb250cm9scyB3aGV0aGVyIG9yIG5vdCBsb25nIHN0YWNrIHRyYWNlcyB3aWxsIGJlIG9uXG4gKi9cblEubG9uZ1N0YWNrU3VwcG9ydCA9IGZhbHNlO1xuXG4vKipcbiAqIFRoZSBjb3VudGVyIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBzdG9wcGluZyBwb2ludCBmb3IgYnVpbGRpbmdcbiAqIGxvbmcgc3RhY2sgdHJhY2VzLiBJbiBtYWtlU3RhY2tUcmFjZUxvbmcgd2Ugd2FsayBiYWNrd2FyZHMgdGhyb3VnaFxuICogdGhlIGxpbmtlZCBsaXN0IG9mIHByb21pc2VzLCBvbmx5IHN0YWNrcyB3aGljaCB3ZXJlIGNyZWF0ZWQgYmVmb3JlXG4gKiB0aGUgcmVqZWN0aW9uIGFyZSBjb25jYXRlbmF0ZWQuXG4gKi9cbnZhciBsb25nU3RhY2tDb3VudGVyID0gMTtcblxuLy8gZW5hYmxlIGxvbmcgc3RhY2tzIGlmIFFfREVCVUcgaXMgc2V0XG5pZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgcHJvY2VzcyAmJiBwcm9jZXNzLmVudiAmJiBwcm9jZXNzLmVudi5RX0RFQlVHKSB7XG4gICAgUS5sb25nU3RhY2tTdXBwb3J0ID0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEge3Byb21pc2UsIHJlc29sdmUsIHJlamVjdH0gb2JqZWN0LlxuICpcbiAqIGByZXNvbHZlYCBpcyBhIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGEgbW9yZSByZXNvbHZlZCB2YWx1ZSBmb3IgdGhlXG4gKiBwcm9taXNlLiBUbyBmdWxmaWxsIHRoZSBwcm9taXNlLCBpbnZva2UgYHJlc29sdmVgIHdpdGggYW55IHZhbHVlIHRoYXQgaXNcbiAqIG5vdCBhIHRoZW5hYmxlLiBUbyByZWplY3QgdGhlIHByb21pc2UsIGludm9rZSBgcmVzb2x2ZWAgd2l0aCBhIHJlamVjdGVkXG4gKiB0aGVuYWJsZSwgb3IgaW52b2tlIGByZWplY3RgIHdpdGggdGhlIHJlYXNvbiBkaXJlY3RseS4gVG8gcmVzb2x2ZSB0aGVcbiAqIHByb21pc2UgdG8gYW5vdGhlciB0aGVuYWJsZSwgdGh1cyBwdXR0aW5nIGl0IGluIHRoZSBzYW1lIHN0YXRlLCBpbnZva2VcbiAqIGByZXNvbHZlYCB3aXRoIHRoYXQgb3RoZXIgdGhlbmFibGUuXG4gKi9cblEuZGVmZXIgPSBkZWZlcjtcbmZ1bmN0aW9uIGRlZmVyKCkge1xuICAgIC8vIGlmIFwibWVzc2FnZXNcIiBpcyBhbiBcIkFycmF5XCIsIHRoYXQgaW5kaWNhdGVzIHRoYXQgdGhlIHByb21pc2UgaGFzIG5vdCB5ZXRcbiAgICAvLyBiZWVuIHJlc29sdmVkLiAgSWYgaXQgaXMgXCJ1bmRlZmluZWRcIiwgaXQgaGFzIGJlZW4gcmVzb2x2ZWQuICBFYWNoXG4gICAgLy8gZWxlbWVudCBvZiB0aGUgbWVzc2FnZXMgYXJyYXkgaXMgaXRzZWxmIGFuIGFycmF5IG9mIGNvbXBsZXRlIGFyZ3VtZW50cyB0b1xuICAgIC8vIGZvcndhcmQgdG8gdGhlIHJlc29sdmVkIHByb21pc2UuICBXZSBjb2VyY2UgdGhlIHJlc29sdXRpb24gdmFsdWUgdG8gYVxuICAgIC8vIHByb21pc2UgdXNpbmcgdGhlIGByZXNvbHZlYCBmdW5jdGlvbiBiZWNhdXNlIGl0IGhhbmRsZXMgYm90aCBmdWxseVxuICAgIC8vIG5vbi10aGVuYWJsZSB2YWx1ZXMgYW5kIG90aGVyIHRoZW5hYmxlcyBncmFjZWZ1bGx5LlxuICAgIHZhciBtZXNzYWdlcyA9IFtdLCBwcm9ncmVzc0xpc3RlbmVycyA9IFtdLCByZXNvbHZlZFByb21pc2U7XG5cbiAgICB2YXIgZGVmZXJyZWQgPSBvYmplY3RfY3JlYXRlKGRlZmVyLnByb3RvdHlwZSk7XG4gICAgdmFyIHByb21pc2UgPSBvYmplY3RfY3JlYXRlKFByb21pc2UucHJvdG90eXBlKTtcblxuICAgIHByb21pc2UucHJvbWlzZURpc3BhdGNoID0gZnVuY3Rpb24gKHJlc29sdmUsIG9wLCBvcGVyYW5kcykge1xuICAgICAgICB2YXIgYXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cyk7XG4gICAgICAgIGlmIChtZXNzYWdlcykge1xuICAgICAgICAgICAgbWVzc2FnZXMucHVzaChhcmdzKTtcbiAgICAgICAgICAgIGlmIChvcCA9PT0gXCJ3aGVuXCIgJiYgb3BlcmFuZHNbMV0pIHsgLy8gcHJvZ3Jlc3Mgb3BlcmFuZFxuICAgICAgICAgICAgICAgIHByb2dyZXNzTGlzdGVuZXJzLnB1c2gob3BlcmFuZHNbMV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZWRQcm9taXNlLnByb21pc2VEaXNwYXRjaC5hcHBseShyZXNvbHZlZFByb21pc2UsIGFyZ3MpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLy8gWFhYIGRlcHJlY2F0ZWRcbiAgICBwcm9taXNlLnZhbHVlT2YgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChtZXNzYWdlcykge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG5lYXJlclZhbHVlID0gbmVhcmVyKHJlc29sdmVkUHJvbWlzZSk7XG4gICAgICAgIGlmIChpc1Byb21pc2UobmVhcmVyVmFsdWUpKSB7XG4gICAgICAgICAgICByZXNvbHZlZFByb21pc2UgPSBuZWFyZXJWYWx1ZTsgLy8gc2hvcnRlbiBjaGFpblxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZWFyZXJWYWx1ZTtcbiAgICB9O1xuXG4gICAgcHJvbWlzZS5pbnNwZWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIXJlc29sdmVkUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwicGVuZGluZ1wiIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc29sdmVkUHJvbWlzZS5pbnNwZWN0KCk7XG4gICAgfTtcblxuICAgIGlmIChRLmxvbmdTdGFja1N1cHBvcnQgJiYgaGFzU3RhY2tzKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgLy8gTk9URTogZG9uJ3QgdHJ5IHRvIHVzZSBgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2VgIG9yIHRyYW5zZmVyIHRoZVxuICAgICAgICAgICAgLy8gYWNjZXNzb3IgYXJvdW5kOyB0aGF0IGNhdXNlcyBtZW1vcnkgbGVha3MgYXMgcGVyIEdILTExMS4gSnVzdFxuICAgICAgICAgICAgLy8gcmVpZnkgdGhlIHN0YWNrIHRyYWNlIGFzIGEgc3RyaW5nIEFTQVAuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gQXQgdGhlIHNhbWUgdGltZSwgY3V0IG9mZiB0aGUgZmlyc3QgbGluZTsgaXQncyBhbHdheXMganVzdFxuICAgICAgICAgICAgLy8gXCJbb2JqZWN0IFByb21pc2VdXFxuXCIsIGFzIHBlciB0aGUgYHRvU3RyaW5nYC5cbiAgICAgICAgICAgIHByb21pc2Uuc3RhY2sgPSBlLnN0YWNrLnN1YnN0cmluZyhlLnN0YWNrLmluZGV4T2YoXCJcXG5cIikgKyAxKTtcbiAgICAgICAgICAgIHByb21pc2Uuc3RhY2tDb3VudGVyID0gbG9uZ1N0YWNrQ291bnRlcisrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTk9URTogd2UgZG8gdGhlIGNoZWNrcyBmb3IgYHJlc29sdmVkUHJvbWlzZWAgaW4gZWFjaCBtZXRob2QsIGluc3RlYWQgb2ZcbiAgICAvLyBjb25zb2xpZGF0aW5nIHRoZW0gaW50byBgYmVjb21lYCwgc2luY2Ugb3RoZXJ3aXNlIHdlJ2QgY3JlYXRlIG5ld1xuICAgIC8vIHByb21pc2VzIHdpdGggdGhlIGxpbmVzIGBiZWNvbWUod2hhdGV2ZXIodmFsdWUpKWAuIFNlZSBlLmcuIEdILTI1Mi5cblxuICAgIGZ1bmN0aW9uIGJlY29tZShuZXdQcm9taXNlKSB7XG4gICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5ld1Byb21pc2U7XG5cbiAgICAgICAgaWYgKFEubG9uZ1N0YWNrU3VwcG9ydCAmJiBoYXNTdGFja3MpIHtcbiAgICAgICAgICAgIC8vIE9ubHkgaG9sZCBhIHJlZmVyZW5jZSB0byB0aGUgbmV3IHByb21pc2UgaWYgbG9uZyBzdGFja3NcbiAgICAgICAgICAgIC8vIGFyZSBlbmFibGVkIHRvIHJlZHVjZSBtZW1vcnkgdXNhZ2VcbiAgICAgICAgICAgIHByb21pc2Uuc291cmNlID0gbmV3UHJvbWlzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGFycmF5X3JlZHVjZShtZXNzYWdlcywgZnVuY3Rpb24gKHVuZGVmaW5lZCwgbWVzc2FnZSkge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbmV3UHJvbWlzZS5wcm9taXNlRGlzcGF0Y2guYXBwbHkobmV3UHJvbWlzZSwgbWVzc2FnZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgdm9pZCAwKTtcblxuICAgICAgICBtZXNzYWdlcyA9IHZvaWQgMDtcbiAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcnMgPSB2b2lkIDA7XG4gICAgfVxuXG4gICAgZGVmZXJyZWQucHJvbWlzZSA9IHByb21pc2U7XG4gICAgZGVmZXJyZWQucmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUoUSh2YWx1ZSkpO1xuICAgIH07XG5cbiAgICBkZWZlcnJlZC5mdWxmaWxsID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIGlmIChyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGJlY29tZShmdWxmaWxsKHZhbHVlKSk7XG4gICAgfTtcbiAgICBkZWZlcnJlZC5yZWplY3QgPSBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgICAgIGlmIChyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGJlY29tZShyZWplY3QocmVhc29uKSk7XG4gICAgfTtcbiAgICBkZWZlcnJlZC5ub3RpZnkgPSBmdW5jdGlvbiAocHJvZ3Jlc3MpIHtcbiAgICAgICAgaWYgKHJlc29sdmVkUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYXJyYXlfcmVkdWNlKHByb2dyZXNzTGlzdGVuZXJzLCBmdW5jdGlvbiAodW5kZWZpbmVkLCBwcm9ncmVzc0xpc3RlbmVyKSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBwcm9ncmVzc0xpc3RlbmVyKHByb2dyZXNzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCB2b2lkIDApO1xuICAgIH07XG5cbiAgICByZXR1cm4gZGVmZXJyZWQ7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIE5vZGUtc3R5bGUgY2FsbGJhY2sgdGhhdCB3aWxsIHJlc29sdmUgb3IgcmVqZWN0IHRoZSBkZWZlcnJlZFxuICogcHJvbWlzZS5cbiAqIEByZXR1cm5zIGEgbm9kZWJhY2tcbiAqL1xuZGVmZXIucHJvdG90eXBlLm1ha2VOb2RlUmVzb2x2ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHJldHVybiBmdW5jdGlvbiAoZXJyb3IsIHZhbHVlKSB7XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgc2VsZi5yZWplY3QoZXJyb3IpO1xuICAgICAgICB9IGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAyKSB7XG4gICAgICAgICAgICBzZWxmLnJlc29sdmUoYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZWxmLnJlc29sdmUodmFsdWUpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHJlc29sdmVyIHtGdW5jdGlvbn0gYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgbm90aGluZyBhbmQgYWNjZXB0c1xuICogdGhlIHJlc29sdmUsIHJlamVjdCwgYW5kIG5vdGlmeSBmdW5jdGlvbnMgZm9yIGEgZGVmZXJyZWQuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgdGhhdCBtYXkgYmUgcmVzb2x2ZWQgd2l0aCB0aGUgZ2l2ZW4gcmVzb2x2ZSBhbmQgcmVqZWN0XG4gKiBmdW5jdGlvbnMsIG9yIHJlamVjdGVkIGJ5IGEgdGhyb3duIGV4Y2VwdGlvbiBpbiByZXNvbHZlclxuICovXG5RLlByb21pc2UgPSBwcm9taXNlOyAvLyBFUzZcblEucHJvbWlzZSA9IHByb21pc2U7XG5mdW5jdGlvbiBwcm9taXNlKHJlc29sdmVyKSB7XG4gICAgaWYgKHR5cGVvZiByZXNvbHZlciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJyZXNvbHZlciBtdXN0IGJlIGEgZnVuY3Rpb24uXCIpO1xuICAgIH1cbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIHRyeSB7XG4gICAgICAgIHJlc29sdmVyKGRlZmVycmVkLnJlc29sdmUsIGRlZmVycmVkLnJlamVjdCwgZGVmZXJyZWQubm90aWZ5KTtcbiAgICB9IGNhdGNoIChyZWFzb24pIHtcbiAgICAgICAgZGVmZXJyZWQucmVqZWN0KHJlYXNvbik7XG4gICAgfVxuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufVxuXG5wcm9taXNlLnJhY2UgPSByYWNlOyAvLyBFUzZcbnByb21pc2UuYWxsID0gYWxsOyAvLyBFUzZcbnByb21pc2UucmVqZWN0ID0gcmVqZWN0OyAvLyBFUzZcbnByb21pc2UucmVzb2x2ZSA9IFE7IC8vIEVTNlxuXG4vLyBYWFggZXhwZXJpbWVudGFsLiAgVGhpcyBtZXRob2QgaXMgYSB3YXkgdG8gZGVub3RlIHRoYXQgYSBsb2NhbCB2YWx1ZSBpc1xuLy8gc2VyaWFsaXphYmxlIGFuZCBzaG91bGQgYmUgaW1tZWRpYXRlbHkgZGlzcGF0Y2hlZCB0byBhIHJlbW90ZSB1cG9uIHJlcXVlc3QsXG4vLyBpbnN0ZWFkIG9mIHBhc3NpbmcgYSByZWZlcmVuY2UuXG5RLnBhc3NCeUNvcHkgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgLy9mcmVlemUob2JqZWN0KTtcbiAgICAvL3Bhc3NCeUNvcGllcy5zZXQob2JqZWN0LCB0cnVlKTtcbiAgICByZXR1cm4gb2JqZWN0O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUucGFzc0J5Q29weSA9IGZ1bmN0aW9uICgpIHtcbiAgICAvL2ZyZWV6ZShvYmplY3QpO1xuICAgIC8vcGFzc0J5Q29waWVzLnNldChvYmplY3QsIHRydWUpO1xuICAgIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBJZiB0d28gcHJvbWlzZXMgZXZlbnR1YWxseSBmdWxmaWxsIHRvIHRoZSBzYW1lIHZhbHVlLCBwcm9taXNlcyB0aGF0IHZhbHVlLFxuICogYnV0IG90aGVyd2lzZSByZWplY3RzLlxuICogQHBhcmFtIHgge0FueSp9XG4gKiBAcGFyYW0geSB7QW55Kn1cbiAqIEByZXR1cm5zIHtBbnkqfSBhIHByb21pc2UgZm9yIHggYW5kIHkgaWYgdGhleSBhcmUgdGhlIHNhbWUsIGJ1dCBhIHJlamVjdGlvblxuICogb3RoZXJ3aXNlLlxuICpcbiAqL1xuUS5qb2luID0gZnVuY3Rpb24gKHgsIHkpIHtcbiAgICByZXR1cm4gUSh4KS5qb2luKHkpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuam9pbiA9IGZ1bmN0aW9uICh0aGF0KSB7XG4gICAgcmV0dXJuIFEoW3RoaXMsIHRoYXRdKS5zcHJlYWQoZnVuY3Rpb24gKHgsIHkpIHtcbiAgICAgICAgaWYgKHggPT09IHkpIHtcbiAgICAgICAgICAgIC8vIFRPRE86IFwiPT09XCIgc2hvdWxkIGJlIE9iamVjdC5pcyBvciBlcXVpdlxuICAgICAgICAgICAgcmV0dXJuIHg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJRIGNhbid0IGpvaW46IG5vdCB0aGUgc2FtZTogXCIgKyB4ICsgXCIgXCIgKyB5KTtcbiAgICAgICAgfVxuICAgIH0pO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIGZpcnN0IG9mIGFuIGFycmF5IG9mIHByb21pc2VzIHRvIGJlY29tZSBzZXR0bGVkLlxuICogQHBhcmFtIGFuc3dlcnMge0FycmF5W0FueSpdfSBwcm9taXNlcyB0byByYWNlXG4gKiBAcmV0dXJucyB7QW55Kn0gdGhlIGZpcnN0IHByb21pc2UgdG8gYmUgc2V0dGxlZFxuICovXG5RLnJhY2UgPSByYWNlO1xuZnVuY3Rpb24gcmFjZShhbnN3ZXJQcykge1xuICAgIHJldHVybiBwcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgLy8gU3dpdGNoIHRvIHRoaXMgb25jZSB3ZSBjYW4gYXNzdW1lIGF0IGxlYXN0IEVTNVxuICAgICAgICAvLyBhbnN3ZXJQcy5mb3JFYWNoKGZ1bmN0aW9uIChhbnN3ZXJQKSB7XG4gICAgICAgIC8vICAgICBRKGFuc3dlclApLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgLy8gfSk7XG4gICAgICAgIC8vIFVzZSB0aGlzIGluIHRoZSBtZWFudGltZVxuICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gYW5zd2VyUHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIFEoYW5zd2VyUHNbaV0pLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5yYWNlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnRoZW4oUS5yYWNlKTtcbn07XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIFByb21pc2Ugd2l0aCBhIHByb21pc2UgZGVzY3JpcHRvciBvYmplY3QgYW5kIG9wdGlvbmFsIGZhbGxiYWNrXG4gKiBmdW5jdGlvbi4gIFRoZSBkZXNjcmlwdG9yIGNvbnRhaW5zIG1ldGhvZHMgbGlrZSB3aGVuKHJlamVjdGVkKSwgZ2V0KG5hbWUpLFxuICogc2V0KG5hbWUsIHZhbHVlKSwgcG9zdChuYW1lLCBhcmdzKSwgYW5kIGRlbGV0ZShuYW1lKSwgd2hpY2ggYWxsXG4gKiByZXR1cm4gZWl0aGVyIGEgdmFsdWUsIGEgcHJvbWlzZSBmb3IgYSB2YWx1ZSwgb3IgYSByZWplY3Rpb24uICBUaGUgZmFsbGJhY2tcbiAqIGFjY2VwdHMgdGhlIG9wZXJhdGlvbiBuYW1lLCBhIHJlc29sdmVyLCBhbmQgYW55IGZ1cnRoZXIgYXJndW1lbnRzIHRoYXQgd291bGRcbiAqIGhhdmUgYmVlbiBmb3J3YXJkZWQgdG8gdGhlIGFwcHJvcHJpYXRlIG1ldGhvZCBhYm92ZSBoYWQgYSBtZXRob2QgYmVlblxuICogcHJvdmlkZWQgd2l0aCB0aGUgcHJvcGVyIG5hbWUuICBUaGUgQVBJIG1ha2VzIG5vIGd1YXJhbnRlZXMgYWJvdXQgdGhlIG5hdHVyZVxuICogb2YgdGhlIHJldHVybmVkIG9iamVjdCwgYXBhcnQgZnJvbSB0aGF0IGl0IGlzIHVzYWJsZSB3aGVyZWV2ZXIgcHJvbWlzZXMgYXJlXG4gKiBib3VnaHQgYW5kIHNvbGQuXG4gKi9cblEubWFrZVByb21pc2UgPSBQcm9taXNlO1xuZnVuY3Rpb24gUHJvbWlzZShkZXNjcmlwdG9yLCBmYWxsYmFjaywgaW5zcGVjdCkge1xuICAgIGlmIChmYWxsYmFjayA9PT0gdm9pZCAwKSB7XG4gICAgICAgIGZhbGxiYWNrID0gZnVuY3Rpb24gKG9wKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBcIlByb21pc2UgZG9lcyBub3Qgc3VwcG9ydCBvcGVyYXRpb246IFwiICsgb3BcbiAgICAgICAgICAgICkpO1xuICAgICAgICB9O1xuICAgIH1cbiAgICBpZiAoaW5zcGVjdCA9PT0gdm9pZCAwKSB7XG4gICAgICAgIGluc3BlY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4ge3N0YXRlOiBcInVua25vd25cIn07XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIHByb21pc2UgPSBvYmplY3RfY3JlYXRlKFByb21pc2UucHJvdG90eXBlKTtcblxuICAgIHByb21pc2UucHJvbWlzZURpc3BhdGNoID0gZnVuY3Rpb24gKHJlc29sdmUsIG9wLCBhcmdzKSB7XG4gICAgICAgIHZhciByZXN1bHQ7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoZGVzY3JpcHRvcltvcF0pIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBkZXNjcmlwdG9yW29wXS5hcHBseShwcm9taXNlLCBhcmdzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gZmFsbGJhY2suY2FsbChwcm9taXNlLCBvcCwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgcmVzdWx0ID0gcmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlc29sdmUpIHtcbiAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBwcm9taXNlLmluc3BlY3QgPSBpbnNwZWN0O1xuXG4gICAgLy8gWFhYIGRlcHJlY2F0ZWQgYHZhbHVlT2ZgIGFuZCBgZXhjZXB0aW9uYCBzdXBwb3J0XG4gICAgaWYgKGluc3BlY3QpIHtcbiAgICAgICAgdmFyIGluc3BlY3RlZCA9IGluc3BlY3QoKTtcbiAgICAgICAgaWYgKGluc3BlY3RlZC5zdGF0ZSA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgICAgICBwcm9taXNlLmV4Y2VwdGlvbiA9IGluc3BlY3RlZC5yZWFzb247XG4gICAgICAgIH1cblxuICAgICAgICBwcm9taXNlLnZhbHVlT2YgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgaW5zcGVjdGVkID0gaW5zcGVjdCgpO1xuICAgICAgICAgICAgaWYgKGluc3BlY3RlZC5zdGF0ZSA9PT0gXCJwZW5kaW5nXCIgfHxcbiAgICAgICAgICAgICAgICBpbnNwZWN0ZWQuc3RhdGUgPT09IFwicmVqZWN0ZWRcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGluc3BlY3RlZC52YWx1ZTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIFwiW29iamVjdCBQcm9taXNlXVwiO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUudGhlbiA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzc2VkKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgdmFyIGRvbmUgPSBmYWxzZTsgICAvLyBlbnN1cmUgdGhlIHVudHJ1c3RlZCBwcm9taXNlIG1ha2VzIGF0IG1vc3QgYVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2luZ2xlIGNhbGwgdG8gb25lIG9mIHRoZSBjYWxsYmFja3NcblxuICAgIGZ1bmN0aW9uIF9mdWxmaWxsZWQodmFsdWUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgZnVsZmlsbGVkID09PSBcImZ1bmN0aW9uXCIgPyBmdWxmaWxsZWQodmFsdWUpIDogdmFsdWU7XG4gICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgcmV0dXJuIHJlamVjdChleGNlcHRpb24pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX3JlamVjdGVkKGV4Y2VwdGlvbikge1xuICAgICAgICBpZiAodHlwZW9mIHJlamVjdGVkID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIG1ha2VTdGFja1RyYWNlTG9uZyhleGNlcHRpb24sIHNlbGYpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0ZWQoZXhjZXB0aW9uKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKG5ld0V4Y2VwdGlvbikge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3RXhjZXB0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX3Byb2dyZXNzZWQodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBwcm9ncmVzc2VkID09PSBcImZ1bmN0aW9uXCIgPyBwcm9ncmVzc2VkKHZhbHVlKSA6IHZhbHVlO1xuICAgIH1cblxuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLnByb21pc2VEaXNwYXRjaChmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIGlmIChkb25lKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZG9uZSA9IHRydWU7XG5cbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUoX2Z1bGZpbGxlZCh2YWx1ZSkpO1xuICAgICAgICB9LCBcIndoZW5cIiwgW2Z1bmN0aW9uIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgIGlmIChkb25lKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZG9uZSA9IHRydWU7XG5cbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUoX3JlamVjdGVkKGV4Y2VwdGlvbikpO1xuICAgICAgICB9XSk7XG4gICAgfSk7XG5cbiAgICAvLyBQcm9ncmVzcyBwcm9wYWdhdG9yIG5lZWQgdG8gYmUgYXR0YWNoZWQgaW4gdGhlIGN1cnJlbnQgdGljay5cbiAgICBzZWxmLnByb21pc2VEaXNwYXRjaCh2b2lkIDAsIFwid2hlblwiLCBbdm9pZCAwLCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIG5ld1ZhbHVlO1xuICAgICAgICB2YXIgdGhyZXcgPSBmYWxzZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gX3Byb2dyZXNzZWQodmFsdWUpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICB0aHJldyA9IHRydWU7XG4gICAgICAgICAgICBpZiAoUS5vbmVycm9yKSB7XG4gICAgICAgICAgICAgICAgUS5vbmVycm9yKGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aHJldykge1xuICAgICAgICAgICAgZGVmZXJyZWQubm90aWZ5KG5ld1ZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1dKTtcblxuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuUS50YXAgPSBmdW5jdGlvbiAocHJvbWlzZSwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gUShwcm9taXNlKS50YXAoY2FsbGJhY2spO1xufTtcblxuLyoqXG4gKiBXb3JrcyBhbG1vc3QgbGlrZSBcImZpbmFsbHlcIiwgYnV0IG5vdCBjYWxsZWQgZm9yIHJlamVjdGlvbnMuXG4gKiBPcmlnaW5hbCByZXNvbHV0aW9uIHZhbHVlIGlzIHBhc3NlZCB0aHJvdWdoIGNhbGxiYWNrIHVuYWZmZWN0ZWQuXG4gKiBDYWxsYmFjayBtYXkgcmV0dXJuIGEgcHJvbWlzZSB0aGF0IHdpbGwgYmUgYXdhaXRlZCBmb3IuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICogQHJldHVybnMge1EuUHJvbWlzZX1cbiAqIEBleGFtcGxlXG4gKiBkb1NvbWV0aGluZygpXG4gKiAgIC50aGVuKC4uLilcbiAqICAgLnRhcChjb25zb2xlLmxvZylcbiAqICAgLnRoZW4oLi4uKTtcbiAqL1xuUHJvbWlzZS5wcm90b3R5cGUudGFwID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBRKGNhbGxiYWNrKTtcblxuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjay5mY2FsbCh2YWx1ZSkudGhlblJlc29sdmUodmFsdWUpO1xuICAgIH0pO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYW4gb2JzZXJ2ZXIgb24gYSBwcm9taXNlLlxuICpcbiAqIEd1YXJhbnRlZXM6XG4gKlxuICogMS4gdGhhdCBmdWxmaWxsZWQgYW5kIHJlamVjdGVkIHdpbGwgYmUgY2FsbGVkIG9ubHkgb25jZS5cbiAqIDIuIHRoYXQgZWl0aGVyIHRoZSBmdWxmaWxsZWQgY2FsbGJhY2sgb3IgdGhlIHJlamVjdGVkIGNhbGxiYWNrIHdpbGwgYmVcbiAqICAgIGNhbGxlZCwgYnV0IG5vdCBib3RoLlxuICogMy4gdGhhdCBmdWxmaWxsZWQgYW5kIHJlamVjdGVkIHdpbGwgbm90IGJlIGNhbGxlZCBpbiB0aGlzIHR1cm4uXG4gKlxuICogQHBhcmFtIHZhbHVlICAgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIHRvIG9ic2VydmVcbiAqIEBwYXJhbSBmdWxmaWxsZWQgIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCB3aXRoIHRoZSBmdWxmaWxsZWQgdmFsdWVcbiAqIEBwYXJhbSByZWplY3RlZCAgIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCB3aXRoIHRoZSByZWplY3Rpb24gZXhjZXB0aW9uXG4gKiBAcGFyYW0gcHJvZ3Jlc3NlZCBmdW5jdGlvbiB0byBiZSBjYWxsZWQgb24gYW55IHByb2dyZXNzIG5vdGlmaWNhdGlvbnNcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZSBmcm9tIHRoZSBpbnZva2VkIGNhbGxiYWNrXG4gKi9cblEud2hlbiA9IHdoZW47XG5mdW5jdGlvbiB3aGVuKHZhbHVlLCBmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzc2VkKSB7XG4gICAgcmV0dXJuIFEodmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3NlZCk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnRoZW5SZXNvbHZlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiB2YWx1ZTsgfSk7XG59O1xuXG5RLnRoZW5SZXNvbHZlID0gZnVuY3Rpb24gKHByb21pc2UsIHZhbHVlKSB7XG4gICAgcmV0dXJuIFEocHJvbWlzZSkudGhlblJlc29sdmUodmFsdWUpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUudGhlblJlamVjdCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICgpIHsgdGhyb3cgcmVhc29uOyB9KTtcbn07XG5cblEudGhlblJlamVjdCA9IGZ1bmN0aW9uIChwcm9taXNlLCByZWFzb24pIHtcbiAgICByZXR1cm4gUShwcm9taXNlKS50aGVuUmVqZWN0KHJlYXNvbik7XG59O1xuXG4vKipcbiAqIElmIGFuIG9iamVjdCBpcyBub3QgYSBwcm9taXNlLCBpdCBpcyBhcyBcIm5lYXJcIiBhcyBwb3NzaWJsZS5cbiAqIElmIGEgcHJvbWlzZSBpcyByZWplY3RlZCwgaXQgaXMgYXMgXCJuZWFyXCIgYXMgcG9zc2libGUgdG9vLlxuICogSWYgaXTigJlzIGEgZnVsZmlsbGVkIHByb21pc2UsIHRoZSBmdWxmaWxsbWVudCB2YWx1ZSBpcyBuZWFyZXIuXG4gKiBJZiBpdOKAmXMgYSBkZWZlcnJlZCBwcm9taXNlIGFuZCB0aGUgZGVmZXJyZWQgaGFzIGJlZW4gcmVzb2x2ZWQsIHRoZVxuICogcmVzb2x1dGlvbiBpcyBcIm5lYXJlclwiLlxuICogQHBhcmFtIG9iamVjdFxuICogQHJldHVybnMgbW9zdCByZXNvbHZlZCAobmVhcmVzdCkgZm9ybSBvZiB0aGUgb2JqZWN0XG4gKi9cblxuLy8gWFhYIHNob3VsZCB3ZSByZS1kbyB0aGlzP1xuUS5uZWFyZXIgPSBuZWFyZXI7XG5mdW5jdGlvbiBuZWFyZXIodmFsdWUpIHtcbiAgICBpZiAoaXNQcm9taXNlKHZhbHVlKSkge1xuICAgICAgICB2YXIgaW5zcGVjdGVkID0gdmFsdWUuaW5zcGVjdCgpO1xuICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5zcGVjdGVkLnZhbHVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBwcm9taXNlLlxuICogT3RoZXJ3aXNlIGl0IGlzIGEgZnVsZmlsbGVkIHZhbHVlLlxuICovXG5RLmlzUHJvbWlzZSA9IGlzUHJvbWlzZTtcbmZ1bmN0aW9uIGlzUHJvbWlzZShvYmplY3QpIHtcbiAgICByZXR1cm4gb2JqZWN0IGluc3RhbmNlb2YgUHJvbWlzZTtcbn1cblxuUS5pc1Byb21pc2VBbGlrZSA9IGlzUHJvbWlzZUFsaWtlO1xuZnVuY3Rpb24gaXNQcm9taXNlQWxpa2Uob2JqZWN0KSB7XG4gICAgcmV0dXJuIGlzT2JqZWN0KG9iamVjdCkgJiYgdHlwZW9mIG9iamVjdC50aGVuID09PSBcImZ1bmN0aW9uXCI7XG59XG5cbi8qKlxuICogQHJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGEgcGVuZGluZyBwcm9taXNlLCBtZWFuaW5nIG5vdFxuICogZnVsZmlsbGVkIG9yIHJlamVjdGVkLlxuICovXG5RLmlzUGVuZGluZyA9IGlzUGVuZGluZztcbmZ1bmN0aW9uIGlzUGVuZGluZyhvYmplY3QpIHtcbiAgICByZXR1cm4gaXNQcm9taXNlKG9iamVjdCkgJiYgb2JqZWN0Lmluc3BlY3QoKS5zdGF0ZSA9PT0gXCJwZW5kaW5nXCI7XG59XG5cblByb21pc2UucHJvdG90eXBlLmlzUGVuZGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnNwZWN0KCkuc3RhdGUgPT09IFwicGVuZGluZ1wiO1xufTtcblxuLyoqXG4gKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSB2YWx1ZSBvciBmdWxmaWxsZWRcbiAqIHByb21pc2UuXG4gKi9cblEuaXNGdWxmaWxsZWQgPSBpc0Z1bGZpbGxlZDtcbmZ1bmN0aW9uIGlzRnVsZmlsbGVkKG9iamVjdCkge1xuICAgIHJldHVybiAhaXNQcm9taXNlKG9iamVjdCkgfHwgb2JqZWN0Lmluc3BlY3QoKS5zdGF0ZSA9PT0gXCJmdWxmaWxsZWRcIjtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuaXNGdWxmaWxsZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5zcGVjdCgpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiO1xufTtcblxuLyoqXG4gKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSByZWplY3RlZCBwcm9taXNlLlxuICovXG5RLmlzUmVqZWN0ZWQgPSBpc1JlamVjdGVkO1xuZnVuY3Rpb24gaXNSZWplY3RlZChvYmplY3QpIHtcbiAgICByZXR1cm4gaXNQcm9taXNlKG9iamVjdCkgJiYgb2JqZWN0Lmluc3BlY3QoKS5zdGF0ZSA9PT0gXCJyZWplY3RlZFwiO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5pc1JlamVjdGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmluc3BlY3QoKS5zdGF0ZSA9PT0gXCJyZWplY3RlZFwiO1xufTtcblxuLy8vLyBCRUdJTiBVTkhBTkRMRUQgUkVKRUNUSU9OIFRSQUNLSU5HXG5cbi8vIFRoaXMgcHJvbWlzZSBsaWJyYXJ5IGNvbnN1bWVzIGV4Y2VwdGlvbnMgdGhyb3duIGluIGhhbmRsZXJzIHNvIHRoZXkgY2FuIGJlXG4vLyBoYW5kbGVkIGJ5IGEgc3Vic2VxdWVudCBwcm9taXNlLiAgVGhlIGV4Y2VwdGlvbnMgZ2V0IGFkZGVkIHRvIHRoaXMgYXJyYXkgd2hlblxuLy8gdGhleSBhcmUgY3JlYXRlZCwgYW5kIHJlbW92ZWQgd2hlbiB0aGV5IGFyZSBoYW5kbGVkLiAgTm90ZSB0aGF0IGluIEVTNiBvclxuLy8gc2hpbW1lZCBlbnZpcm9ubWVudHMsIHRoaXMgd291bGQgbmF0dXJhbGx5IGJlIGEgYFNldGAuXG52YXIgdW5oYW5kbGVkUmVhc29ucyA9IFtdO1xudmFyIHVuaGFuZGxlZFJlamVjdGlvbnMgPSBbXTtcbnZhciByZXBvcnRlZFVuaGFuZGxlZFJlamVjdGlvbnMgPSBbXTtcbnZhciB0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMgPSB0cnVlO1xuXG5mdW5jdGlvbiByZXNldFVuaGFuZGxlZFJlamVjdGlvbnMoKSB7XG4gICAgdW5oYW5kbGVkUmVhc29ucy5sZW5ndGggPSAwO1xuICAgIHVuaGFuZGxlZFJlamVjdGlvbnMubGVuZ3RoID0gMDtcblxuICAgIGlmICghdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zKSB7XG4gICAgICAgIHRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucyA9IHRydWU7XG4gICAgfVxufVxuXG5mdW5jdGlvbiB0cmFja1JlamVjdGlvbihwcm9taXNlLCByZWFzb24pIHtcbiAgICBpZiAoIXRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcHJvY2Vzcy5lbWl0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgUS5uZXh0VGljay5ydW5BZnRlcihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoYXJyYXlfaW5kZXhPZih1bmhhbmRsZWRSZWplY3Rpb25zLCBwcm9taXNlKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICBwcm9jZXNzLmVtaXQoXCJ1bmhhbmRsZWRSZWplY3Rpb25cIiwgcmVhc29uLCBwcm9taXNlKTtcbiAgICAgICAgICAgICAgICByZXBvcnRlZFVuaGFuZGxlZFJlamVjdGlvbnMucHVzaChwcm9taXNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5wdXNoKHByb21pc2UpO1xuICAgIGlmIChyZWFzb24gJiYgdHlwZW9mIHJlYXNvbi5zdGFjayAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICB1bmhhbmRsZWRSZWFzb25zLnB1c2gocmVhc29uLnN0YWNrKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB1bmhhbmRsZWRSZWFzb25zLnB1c2goXCIobm8gc3RhY2spIFwiICsgcmVhc29uKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHVudHJhY2tSZWplY3Rpb24ocHJvbWlzZSkge1xuICAgIGlmICghdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgYXQgPSBhcnJheV9pbmRleE9mKHVuaGFuZGxlZFJlamVjdGlvbnMsIHByb21pc2UpO1xuICAgIGlmIChhdCAhPT0gLTEpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBwcm9jZXNzLmVtaXQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgUS5uZXh0VGljay5ydW5BZnRlcihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGF0UmVwb3J0ID0gYXJyYXlfaW5kZXhPZihyZXBvcnRlZFVuaGFuZGxlZFJlamVjdGlvbnMsIHByb21pc2UpO1xuICAgICAgICAgICAgICAgIGlmIChhdFJlcG9ydCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzcy5lbWl0KFwicmVqZWN0aW9uSGFuZGxlZFwiLCB1bmhhbmRsZWRSZWFzb25zW2F0XSwgcHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgICAgIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucy5zcGxpY2UoYXRSZXBvcnQsIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHVuaGFuZGxlZFJlamVjdGlvbnMuc3BsaWNlKGF0LCAxKTtcbiAgICAgICAgdW5oYW5kbGVkUmVhc29ucy5zcGxpY2UoYXQsIDEpO1xuICAgIH1cbn1cblxuUS5yZXNldFVuaGFuZGxlZFJlamVjdGlvbnMgPSByZXNldFVuaGFuZGxlZFJlamVjdGlvbnM7XG5cblEuZ2V0VW5oYW5kbGVkUmVhc29ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAvLyBNYWtlIGEgY29weSBzbyB0aGF0IGNvbnN1bWVycyBjYW4ndCBpbnRlcmZlcmUgd2l0aCBvdXIgaW50ZXJuYWwgc3RhdGUuXG4gICAgcmV0dXJuIHVuaGFuZGxlZFJlYXNvbnMuc2xpY2UoKTtcbn07XG5cblEuc3RvcFVuaGFuZGxlZFJlamVjdGlvblRyYWNraW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucygpO1xuICAgIHRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucyA9IGZhbHNlO1xufTtcblxucmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zKCk7XG5cbi8vLy8gRU5EIFVOSEFORExFRCBSRUpFQ1RJT04gVFJBQ0tJTkdcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgcmVqZWN0ZWQgcHJvbWlzZS5cbiAqIEBwYXJhbSByZWFzb24gdmFsdWUgZGVzY3JpYmluZyB0aGUgZmFpbHVyZVxuICovXG5RLnJlamVjdCA9IHJlamVjdDtcbmZ1bmN0aW9uIHJlamVjdChyZWFzb24pIHtcbiAgICB2YXIgcmVqZWN0aW9uID0gUHJvbWlzZSh7XG4gICAgICAgIFwid2hlblwiOiBmdW5jdGlvbiAocmVqZWN0ZWQpIHtcbiAgICAgICAgICAgIC8vIG5vdGUgdGhhdCB0aGUgZXJyb3IgaGFzIGJlZW4gaGFuZGxlZFxuICAgICAgICAgICAgaWYgKHJlamVjdGVkKSB7XG4gICAgICAgICAgICAgICAgdW50cmFja1JlamVjdGlvbih0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZWplY3RlZCA/IHJlamVjdGVkKHJlYXNvbikgOiB0aGlzO1xuICAgICAgICB9XG4gICAgfSwgZnVuY3Rpb24gZmFsbGJhY2soKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sIGZ1bmN0aW9uIGluc3BlY3QoKSB7XG4gICAgICAgIHJldHVybiB7IHN0YXRlOiBcInJlamVjdGVkXCIsIHJlYXNvbjogcmVhc29uIH07XG4gICAgfSk7XG5cbiAgICAvLyBOb3RlIHRoYXQgdGhlIHJlYXNvbiBoYXMgbm90IGJlZW4gaGFuZGxlZC5cbiAgICB0cmFja1JlamVjdGlvbihyZWplY3Rpb24sIHJlYXNvbik7XG5cbiAgICByZXR1cm4gcmVqZWN0aW9uO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBmdWxmaWxsZWQgcHJvbWlzZSBmb3IgYW4gaW1tZWRpYXRlIHJlZmVyZW5jZS5cbiAqIEBwYXJhbSB2YWx1ZSBpbW1lZGlhdGUgcmVmZXJlbmNlXG4gKi9cblEuZnVsZmlsbCA9IGZ1bGZpbGw7XG5mdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7XG4gICAgcmV0dXJuIFByb21pc2Uoe1xuICAgICAgICBcIndoZW5cIjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9LFxuICAgICAgICBcImdldFwiOiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlW25hbWVdO1xuICAgICAgICB9LFxuICAgICAgICBcInNldFwiOiBmdW5jdGlvbiAobmFtZSwgcmhzKSB7XG4gICAgICAgICAgICB2YWx1ZVtuYW1lXSA9IHJocztcbiAgICAgICAgfSxcbiAgICAgICAgXCJkZWxldGVcIjogZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgICAgIGRlbGV0ZSB2YWx1ZVtuYW1lXTtcbiAgICAgICAgfSxcbiAgICAgICAgXCJwb3N0XCI6IGZ1bmN0aW9uIChuYW1lLCBhcmdzKSB7XG4gICAgICAgICAgICAvLyBNYXJrIE1pbGxlciBwcm9wb3NlcyB0aGF0IHBvc3Qgd2l0aCBubyBuYW1lIHNob3VsZCBhcHBseSBhXG4gICAgICAgICAgICAvLyBwcm9taXNlZCBmdW5jdGlvbi5cbiAgICAgICAgICAgIGlmIChuYW1lID09PSBudWxsIHx8IG5hbWUgPT09IHZvaWQgMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5hcHBseSh2b2lkIDAsIGFyZ3MpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVbbmFtZV0uYXBwbHkodmFsdWUsIGFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBcImFwcGx5XCI6IGZ1bmN0aW9uICh0aGlzcCwgYXJncykge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmFwcGx5KHRoaXNwLCBhcmdzKTtcbiAgICAgICAgfSxcbiAgICAgICAgXCJrZXlzXCI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmplY3Rfa2V5cyh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9LCB2b2lkIDAsIGZ1bmN0aW9uIGluc3BlY3QoKSB7XG4gICAgICAgIHJldHVybiB7IHN0YXRlOiBcImZ1bGZpbGxlZFwiLCB2YWx1ZTogdmFsdWUgfTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGVuYWJsZXMgdG8gUSBwcm9taXNlcy5cbiAqIEBwYXJhbSBwcm9taXNlIHRoZW5hYmxlIHByb21pc2VcbiAqIEByZXR1cm5zIGEgUSBwcm9taXNlXG4gKi9cbmZ1bmN0aW9uIGNvZXJjZShwcm9taXNlKSB7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHByb21pc2UudGhlbihkZWZlcnJlZC5yZXNvbHZlLCBkZWZlcnJlZC5yZWplY3QsIGRlZmVycmVkLm5vdGlmeSk7XG4gICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgZGVmZXJyZWQucmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn1cblxuLyoqXG4gKiBBbm5vdGF0ZXMgYW4gb2JqZWN0IHN1Y2ggdGhhdCBpdCB3aWxsIG5ldmVyIGJlXG4gKiB0cmFuc2ZlcnJlZCBhd2F5IGZyb20gdGhpcyBwcm9jZXNzIG92ZXIgYW55IHByb21pc2VcbiAqIGNvbW11bmljYXRpb24gY2hhbm5lbC5cbiAqIEBwYXJhbSBvYmplY3RcbiAqIEByZXR1cm5zIHByb21pc2UgYSB3cmFwcGluZyBvZiB0aGF0IG9iamVjdCB0aGF0XG4gKiBhZGRpdGlvbmFsbHkgcmVzcG9uZHMgdG8gdGhlIFwiaXNEZWZcIiBtZXNzYWdlXG4gKiB3aXRob3V0IGEgcmVqZWN0aW9uLlxuICovXG5RLm1hc3RlciA9IG1hc3RlcjtcbmZ1bmN0aW9uIG1hc3RlcihvYmplY3QpIHtcbiAgICByZXR1cm4gUHJvbWlzZSh7XG4gICAgICAgIFwiaXNEZWZcIjogZnVuY3Rpb24gKCkge31cbiAgICB9LCBmdW5jdGlvbiBmYWxsYmFjayhvcCwgYXJncykge1xuICAgICAgICByZXR1cm4gZGlzcGF0Y2gob2JqZWN0LCBvcCwgYXJncyk7XG4gICAgfSwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gUShvYmplY3QpLmluc3BlY3QoKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBTcHJlYWRzIHRoZSB2YWx1ZXMgb2YgYSBwcm9taXNlZCBhcnJheSBvZiBhcmd1bWVudHMgaW50byB0aGVcbiAqIGZ1bGZpbGxtZW50IGNhbGxiYWNrLlxuICogQHBhcmFtIGZ1bGZpbGxlZCBjYWxsYmFjayB0aGF0IHJlY2VpdmVzIHZhcmlhZGljIGFyZ3VtZW50cyBmcm9tIHRoZVxuICogcHJvbWlzZWQgYXJyYXlcbiAqIEBwYXJhbSByZWplY3RlZCBjYWxsYmFjayB0aGF0IHJlY2VpdmVzIHRoZSBleGNlcHRpb24gaWYgdGhlIHByb21pc2VcbiAqIGlzIHJlamVjdGVkLlxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIG9yIHRocm93biBleGNlcHRpb24gb2ZcbiAqIGVpdGhlciBjYWxsYmFjay5cbiAqL1xuUS5zcHJlYWQgPSBzcHJlYWQ7XG5mdW5jdGlvbiBzcHJlYWQodmFsdWUsIGZ1bGZpbGxlZCwgcmVqZWN0ZWQpIHtcbiAgICByZXR1cm4gUSh2YWx1ZSkuc3ByZWFkKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5zcHJlYWQgPSBmdW5jdGlvbiAoZnVsZmlsbGVkLCByZWplY3RlZCkge1xuICAgIHJldHVybiB0aGlzLmFsbCgpLnRoZW4oZnVuY3Rpb24gKGFycmF5KSB7XG4gICAgICAgIHJldHVybiBmdWxmaWxsZWQuYXBwbHkodm9pZCAwLCBhcnJheSk7XG4gICAgfSwgcmVqZWN0ZWQpO1xufTtcblxuLyoqXG4gKiBUaGUgYXN5bmMgZnVuY3Rpb24gaXMgYSBkZWNvcmF0b3IgZm9yIGdlbmVyYXRvciBmdW5jdGlvbnMsIHR1cm5pbmdcbiAqIHRoZW0gaW50byBhc3luY2hyb25vdXMgZ2VuZXJhdG9ycy4gIEFsdGhvdWdoIGdlbmVyYXRvcnMgYXJlIG9ubHkgcGFydFxuICogb2YgdGhlIG5ld2VzdCBFQ01BU2NyaXB0IDYgZHJhZnRzLCB0aGlzIGNvZGUgZG9lcyBub3QgY2F1c2Ugc3ludGF4XG4gKiBlcnJvcnMgaW4gb2xkZXIgZW5naW5lcy4gIFRoaXMgY29kZSBzaG91bGQgY29udGludWUgdG8gd29yayBhbmQgd2lsbFxuICogaW4gZmFjdCBpbXByb3ZlIG92ZXIgdGltZSBhcyB0aGUgbGFuZ3VhZ2UgaW1wcm92ZXMuXG4gKlxuICogRVM2IGdlbmVyYXRvcnMgYXJlIGN1cnJlbnRseSBwYXJ0IG9mIFY4IHZlcnNpb24gMy4xOSB3aXRoIHRoZVxuICogLS1oYXJtb255LWdlbmVyYXRvcnMgcnVudGltZSBmbGFnIGVuYWJsZWQuICBTcGlkZXJNb25rZXkgaGFzIGhhZCB0aGVtXG4gKiBmb3IgbG9uZ2VyLCBidXQgdW5kZXIgYW4gb2xkZXIgUHl0aG9uLWluc3BpcmVkIGZvcm0uICBUaGlzIGZ1bmN0aW9uXG4gKiB3b3JrcyBvbiBib3RoIGtpbmRzIG9mIGdlbmVyYXRvcnMuXG4gKlxuICogRGVjb3JhdGVzIGEgZ2VuZXJhdG9yIGZ1bmN0aW9uIHN1Y2ggdGhhdDpcbiAqICAtIGl0IG1heSB5aWVsZCBwcm9taXNlc1xuICogIC0gZXhlY3V0aW9uIHdpbGwgY29udGludWUgd2hlbiB0aGF0IHByb21pc2UgaXMgZnVsZmlsbGVkXG4gKiAgLSB0aGUgdmFsdWUgb2YgdGhlIHlpZWxkIGV4cHJlc3Npb24gd2lsbCBiZSB0aGUgZnVsZmlsbGVkIHZhbHVlXG4gKiAgLSBpdCByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZSAod2hlbiB0aGUgZ2VuZXJhdG9yXG4gKiAgICBzdG9wcyBpdGVyYXRpbmcpXG4gKiAgLSB0aGUgZGVjb3JhdGVkIGZ1bmN0aW9uIHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlXG4gKiAgICBvZiB0aGUgZ2VuZXJhdG9yIG9yIHRoZSBmaXJzdCByZWplY3RlZCBwcm9taXNlIGFtb25nIHRob3NlXG4gKiAgICB5aWVsZGVkLlxuICogIC0gaWYgYW4gZXJyb3IgaXMgdGhyb3duIGluIHRoZSBnZW5lcmF0b3IsIGl0IHByb3BhZ2F0ZXMgdGhyb3VnaFxuICogICAgZXZlcnkgZm9sbG93aW5nIHlpZWxkIHVudGlsIGl0IGlzIGNhdWdodCwgb3IgdW50aWwgaXQgZXNjYXBlc1xuICogICAgdGhlIGdlbmVyYXRvciBmdW5jdGlvbiBhbHRvZ2V0aGVyLCBhbmQgaXMgdHJhbnNsYXRlZCBpbnRvIGFcbiAqICAgIHJlamVjdGlvbiBmb3IgdGhlIHByb21pc2UgcmV0dXJuZWQgYnkgdGhlIGRlY29yYXRlZCBnZW5lcmF0b3IuXG4gKi9cblEuYXN5bmMgPSBhc3luYztcbmZ1bmN0aW9uIGFzeW5jKG1ha2VHZW5lcmF0b3IpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyB3aGVuIHZlcmIgaXMgXCJzZW5kXCIsIGFyZyBpcyBhIHZhbHVlXG4gICAgICAgIC8vIHdoZW4gdmVyYiBpcyBcInRocm93XCIsIGFyZyBpcyBhbiBleGNlcHRpb25cbiAgICAgICAgZnVuY3Rpb24gY29udGludWVyKHZlcmIsIGFyZykge1xuICAgICAgICAgICAgdmFyIHJlc3VsdDtcblxuICAgICAgICAgICAgLy8gVW50aWwgVjggMy4xOSAvIENocm9taXVtIDI5IGlzIHJlbGVhc2VkLCBTcGlkZXJNb25rZXkgaXMgdGhlIG9ubHlcbiAgICAgICAgICAgIC8vIGVuZ2luZSB0aGF0IGhhcyBhIGRlcGxveWVkIGJhc2Ugb2YgYnJvd3NlcnMgdGhhdCBzdXBwb3J0IGdlbmVyYXRvcnMuXG4gICAgICAgICAgICAvLyBIb3dldmVyLCBTTSdzIGdlbmVyYXRvcnMgdXNlIHRoZSBQeXRob24taW5zcGlyZWQgc2VtYW50aWNzIG9mXG4gICAgICAgICAgICAvLyBvdXRkYXRlZCBFUzYgZHJhZnRzLiAgV2Ugd291bGQgbGlrZSB0byBzdXBwb3J0IEVTNiwgYnV0IHdlJ2QgYWxzb1xuICAgICAgICAgICAgLy8gbGlrZSB0byBtYWtlIGl0IHBvc3NpYmxlIHRvIHVzZSBnZW5lcmF0b3JzIGluIGRlcGxveWVkIGJyb3dzZXJzLCBzb1xuICAgICAgICAgICAgLy8gd2UgYWxzbyBzdXBwb3J0IFB5dGhvbi1zdHlsZSBnZW5lcmF0b3JzLiAgQXQgc29tZSBwb2ludCB3ZSBjYW4gcmVtb3ZlXG4gICAgICAgICAgICAvLyB0aGlzIGJsb2NrLlxuXG4gICAgICAgICAgICBpZiAodHlwZW9mIFN0b3BJdGVyYXRpb24gPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgICAgICAvLyBFUzYgR2VuZXJhdG9yc1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGdlbmVyYXRvclt2ZXJiXShhcmcpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuZG9uZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUShyZXN1bHQudmFsdWUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB3aGVuKHJlc3VsdC52YWx1ZSwgY2FsbGJhY2ssIGVycmJhY2spO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gU3BpZGVyTW9ua2V5IEdlbmVyYXRvcnNcbiAgICAgICAgICAgICAgICAvLyBGSVhNRTogUmVtb3ZlIHRoaXMgY2FzZSB3aGVuIFNNIGRvZXMgRVM2IGdlbmVyYXRvcnMuXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZ2VuZXJhdG9yW3ZlcmJdKGFyZyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc1N0b3BJdGVyYXRpb24oZXhjZXB0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFEoZXhjZXB0aW9uLnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gd2hlbihyZXN1bHQsIGNhbGxiYWNrLCBlcnJiYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgZ2VuZXJhdG9yID0gbWFrZUdlbmVyYXRvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB2YXIgY2FsbGJhY2sgPSBjb250aW51ZXIuYmluZChjb250aW51ZXIsIFwibmV4dFwiKTtcbiAgICAgICAgdmFyIGVycmJhY2sgPSBjb250aW51ZXIuYmluZChjb250aW51ZXIsIFwidGhyb3dcIik7XG4gICAgICAgIHJldHVybiBjYWxsYmFjaygpO1xuICAgIH07XG59XG5cbi8qKlxuICogVGhlIHNwYXduIGZ1bmN0aW9uIGlzIGEgc21hbGwgd3JhcHBlciBhcm91bmQgYXN5bmMgdGhhdCBpbW1lZGlhdGVseVxuICogY2FsbHMgdGhlIGdlbmVyYXRvciBhbmQgYWxzbyBlbmRzIHRoZSBwcm9taXNlIGNoYWluLCBzbyB0aGF0IGFueVxuICogdW5oYW5kbGVkIGVycm9ycyBhcmUgdGhyb3duIGluc3RlYWQgb2YgZm9yd2FyZGVkIHRvIHRoZSBlcnJvclxuICogaGFuZGxlci4gVGhpcyBpcyB1c2VmdWwgYmVjYXVzZSBpdCdzIGV4dHJlbWVseSBjb21tb24gdG8gcnVuXG4gKiBnZW5lcmF0b3JzIGF0IHRoZSB0b3AtbGV2ZWwgdG8gd29yayB3aXRoIGxpYnJhcmllcy5cbiAqL1xuUS5zcGF3biA9IHNwYXduO1xuZnVuY3Rpb24gc3Bhd24obWFrZUdlbmVyYXRvcikge1xuICAgIFEuZG9uZShRLmFzeW5jKG1ha2VHZW5lcmF0b3IpKCkpO1xufVxuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgaW50ZXJmYWNlIG9uY2UgRVM2IGdlbmVyYXRvcnMgYXJlIGluIFNwaWRlck1vbmtleS5cbi8qKlxuICogVGhyb3dzIGEgUmV0dXJuVmFsdWUgZXhjZXB0aW9uIHRvIHN0b3AgYW4gYXN5bmNocm9ub3VzIGdlbmVyYXRvci5cbiAqXG4gKiBUaGlzIGludGVyZmFjZSBpcyBhIHN0b3AtZ2FwIG1lYXN1cmUgdG8gc3VwcG9ydCBnZW5lcmF0b3IgcmV0dXJuXG4gKiB2YWx1ZXMgaW4gb2xkZXIgRmlyZWZveC9TcGlkZXJNb25rZXkuICBJbiBicm93c2VycyB0aGF0IHN1cHBvcnQgRVM2XG4gKiBnZW5lcmF0b3JzIGxpa2UgQ2hyb21pdW0gMjksIGp1c3QgdXNlIFwicmV0dXJuXCIgaW4geW91ciBnZW5lcmF0b3JcbiAqIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgdGhlIHJldHVybiB2YWx1ZSBmb3IgdGhlIHN1cnJvdW5kaW5nIGdlbmVyYXRvclxuICogQHRocm93cyBSZXR1cm5WYWx1ZSBleGNlcHRpb24gd2l0aCB0aGUgdmFsdWUuXG4gKiBAZXhhbXBsZVxuICogLy8gRVM2IHN0eWxlXG4gKiBRLmFzeW5jKGZ1bmN0aW9uKiAoKSB7XG4gKiAgICAgIHZhciBmb28gPSB5aWVsZCBnZXRGb29Qcm9taXNlKCk7XG4gKiAgICAgIHZhciBiYXIgPSB5aWVsZCBnZXRCYXJQcm9taXNlKCk7XG4gKiAgICAgIHJldHVybiBmb28gKyBiYXI7XG4gKiB9KVxuICogLy8gT2xkZXIgU3BpZGVyTW9ua2V5IHN0eWxlXG4gKiBRLmFzeW5jKGZ1bmN0aW9uICgpIHtcbiAqICAgICAgdmFyIGZvbyA9IHlpZWxkIGdldEZvb1Byb21pc2UoKTtcbiAqICAgICAgdmFyIGJhciA9IHlpZWxkIGdldEJhclByb21pc2UoKTtcbiAqICAgICAgUS5yZXR1cm4oZm9vICsgYmFyKTtcbiAqIH0pXG4gKi9cblFbXCJyZXR1cm5cIl0gPSBfcmV0dXJuO1xuZnVuY3Rpb24gX3JldHVybih2YWx1ZSkge1xuICAgIHRocm93IG5ldyBRUmV0dXJuVmFsdWUodmFsdWUpO1xufVxuXG4vKipcbiAqIFRoZSBwcm9taXNlZCBmdW5jdGlvbiBkZWNvcmF0b3IgZW5zdXJlcyB0aGF0IGFueSBwcm9taXNlIGFyZ3VtZW50c1xuICogYXJlIHNldHRsZWQgYW5kIHBhc3NlZCBhcyB2YWx1ZXMgKGB0aGlzYCBpcyBhbHNvIHNldHRsZWQgYW5kIHBhc3NlZFxuICogYXMgYSB2YWx1ZSkuICBJdCB3aWxsIGFsc28gZW5zdXJlIHRoYXQgdGhlIHJlc3VsdCBvZiBhIGZ1bmN0aW9uIGlzXG4gKiBhbHdheXMgYSBwcm9taXNlLlxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgYWRkID0gUS5wcm9taXNlZChmdW5jdGlvbiAoYSwgYikge1xuICogICAgIHJldHVybiBhICsgYjtcbiAqIH0pO1xuICogYWRkKFEoYSksIFEoQikpO1xuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrIFRoZSBmdW5jdGlvbiB0byBkZWNvcmF0ZVxuICogQHJldHVybnMge2Z1bmN0aW9ufSBhIGZ1bmN0aW9uIHRoYXQgaGFzIGJlZW4gZGVjb3JhdGVkLlxuICovXG5RLnByb21pc2VkID0gcHJvbWlzZWQ7XG5mdW5jdGlvbiBwcm9taXNlZChjYWxsYmFjaykge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBzcHJlYWQoW3RoaXMsIGFsbChhcmd1bWVudHMpXSwgZnVuY3Rpb24gKHNlbGYsIGFyZ3MpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjay5hcHBseShzZWxmLCBhcmdzKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbn1cblxuLyoqXG4gKiBzZW5kcyBhIG1lc3NhZ2UgdG8gYSB2YWx1ZSBpbiBhIGZ1dHVyZSB0dXJuXG4gKiBAcGFyYW0gb2JqZWN0KiB0aGUgcmVjaXBpZW50XG4gKiBAcGFyYW0gb3AgdGhlIG5hbWUgb2YgdGhlIG1lc3NhZ2Ugb3BlcmF0aW9uLCBlLmcuLCBcIndoZW5cIixcbiAqIEBwYXJhbSBhcmdzIGZ1cnRoZXIgYXJndW1lbnRzIHRvIGJlIGZvcndhcmRlZCB0byB0aGUgb3BlcmF0aW9uXG4gKiBAcmV0dXJucyByZXN1bHQge1Byb21pc2V9IGEgcHJvbWlzZSBmb3IgdGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uXG4gKi9cblEuZGlzcGF0Y2ggPSBkaXNwYXRjaDtcbmZ1bmN0aW9uIGRpc3BhdGNoKG9iamVjdCwgb3AsIGFyZ3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKG9wLCBhcmdzKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuZGlzcGF0Y2ggPSBmdW5jdGlvbiAob3AsIGFyZ3MpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2VsZi5wcm9taXNlRGlzcGF0Y2goZGVmZXJyZWQucmVzb2x2ZSwgb3AsIGFyZ3MpO1xuICAgIH0pO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5IGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHBhcmFtIG5hbWUgICAgICBuYW1lIG9mIHByb3BlcnR5IHRvIGdldFxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcHJvcGVydHkgdmFsdWVcbiAqL1xuUS5nZXQgPSBmdW5jdGlvbiAob2JqZWN0LCBrZXkpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwiZ2V0XCIsIFtrZXldKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImdldFwiLCBba2V5XSk7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciBvYmplY3Qgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gc2V0XG4gKiBAcGFyYW0gdmFsdWUgICAgIG5ldyB2YWx1ZSBvZiBwcm9wZXJ0eVxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlXG4gKi9cblEuc2V0ID0gZnVuY3Rpb24gKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJzZXRcIiwgW2tleSwgdmFsdWVdKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJzZXRcIiwgW2tleSwgdmFsdWVdKTtcbn07XG5cbi8qKlxuICogRGVsZXRlcyBhIHByb3BlcnR5IGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHBhcmFtIG5hbWUgICAgICBuYW1lIG9mIHByb3BlcnR5IHRvIGRlbGV0ZVxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlXG4gKi9cblEuZGVsID0gLy8gWFhYIGxlZ2FjeVxuUVtcImRlbGV0ZVwiXSA9IGZ1bmN0aW9uIChvYmplY3QsIGtleSkge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJkZWxldGVcIiwgW2tleV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZGVsID0gLy8gWFhYIGxlZ2FjeVxuUHJvbWlzZS5wcm90b3R5cGVbXCJkZWxldGVcIl0gPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJkZWxldGVcIiwgW2tleV0pO1xufTtcblxuLyoqXG4gKiBJbnZva2VzIGEgbWV0aG9kIGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHBhcmFtIG5hbWUgICAgICBuYW1lIG9mIG1ldGhvZCB0byBpbnZva2VcbiAqIEBwYXJhbSB2YWx1ZSAgICAgYSB2YWx1ZSB0byBwb3N0LCB0eXBpY2FsbHkgYW4gYXJyYXkgb2ZcbiAqICAgICAgICAgICAgICAgICAgaW52b2NhdGlvbiBhcmd1bWVudHMgZm9yIHByb21pc2VzIHRoYXRcbiAqICAgICAgICAgICAgICAgICAgYXJlIHVsdGltYXRlbHkgYmFja2VkIHdpdGggYHJlc29sdmVgIHZhbHVlcyxcbiAqICAgICAgICAgICAgICAgICAgYXMgb3Bwb3NlZCB0byB0aG9zZSBiYWNrZWQgd2l0aCBVUkxzXG4gKiAgICAgICAgICAgICAgICAgIHdoZXJlaW4gdGhlIHBvc3RlZCB2YWx1ZSBjYW4gYmUgYW55XG4gKiAgICAgICAgICAgICAgICAgIEpTT04gc2VyaWFsaXphYmxlIG9iamVjdC5cbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICovXG4vLyBib3VuZCBsb2NhbGx5IGJlY2F1c2UgaXQgaXMgdXNlZCBieSBvdGhlciBtZXRob2RzXG5RLm1hcHBseSA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLnBvc3QgPSBmdW5jdGlvbiAob2JqZWN0LCBuYW1lLCBhcmdzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcInBvc3RcIiwgW25hbWUsIGFyZ3NdKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLm1hcHBseSA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5Qcm9taXNlLnByb3RvdHlwZS5wb3N0ID0gZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcInBvc3RcIiwgW25hbWUsIGFyZ3NdKTtcbn07XG5cbi8qKlxuICogSW52b2tlcyBhIG1ldGhvZCBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBtZXRob2QgdG8gaW52b2tlXG4gKiBAcGFyYW0gLi4uYXJncyAgIGFycmF5IG9mIGludm9jYXRpb24gYXJndW1lbnRzXG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5zZW5kID0gLy8gWFhYIE1hcmsgTWlsbGVyJ3MgcHJvcG9zZWQgcGFybGFuY2VcblEubWNhbGwgPSAvLyBYWFggQXMgcHJvcG9zZWQgYnkgXCJSZWRzYW5kcm9cIlxuUS5pbnZva2UgPSBmdW5jdGlvbiAob2JqZWN0LCBuYW1lIC8qLi4uYXJncyovKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcInBvc3RcIiwgW25hbWUsIGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMildKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnNlbmQgPSAvLyBYWFggTWFyayBNaWxsZXIncyBwcm9wb3NlZCBwYXJsYW5jZVxuUHJvbWlzZS5wcm90b3R5cGUubWNhbGwgPSAvLyBYWFggQXMgcHJvcG9zZWQgYnkgXCJSZWRzYW5kcm9cIlxuUHJvbWlzZS5wcm90b3R5cGUuaW52b2tlID0gZnVuY3Rpb24gKG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcInBvc3RcIiwgW25hbWUsIGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSldKTtcbn07XG5cbi8qKlxuICogQXBwbGllcyB0aGUgcHJvbWlzZWQgZnVuY3Rpb24gaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgZnVuY3Rpb25cbiAqIEBwYXJhbSBhcmdzICAgICAgYXJyYXkgb2YgYXBwbGljYXRpb24gYXJndW1lbnRzXG4gKi9cblEuZmFwcGx5ID0gZnVuY3Rpb24gKG9iamVjdCwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJhcHBseVwiLCBbdm9pZCAwLCBhcmdzXSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5mYXBwbHkgPSBmdW5jdGlvbiAoYXJncykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwiYXBwbHlcIiwgW3ZvaWQgMCwgYXJnc10pO1xufTtcblxuLyoqXG4gKiBDYWxscyB0aGUgcHJvbWlzZWQgZnVuY3Rpb24gaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgZnVuY3Rpb25cbiAqIEBwYXJhbSAuLi5hcmdzICAgYXJyYXkgb2YgYXBwbGljYXRpb24gYXJndW1lbnRzXG4gKi9cblFbXCJ0cnlcIl0gPVxuUS5mY2FsbCA9IGZ1bmN0aW9uIChvYmplY3QgLyogLi4uYXJncyovKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSldKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZjYWxsID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJhcHBseVwiLCBbdm9pZCAwLCBhcnJheV9zbGljZShhcmd1bWVudHMpXSk7XG59O1xuXG4vKipcbiAqIEJpbmRzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiwgdHJhbnNmb3JtaW5nIHJldHVybiB2YWx1ZXMgaW50byBhIGZ1bGZpbGxlZFxuICogcHJvbWlzZSBhbmQgdGhyb3duIGVycm9ycyBpbnRvIGEgcmVqZWN0ZWQgb25lLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIC4uLmFyZ3MgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUS5mYmluZCA9IGZ1bmN0aW9uIChvYmplY3QgLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgcHJvbWlzZSA9IFEob2JqZWN0KTtcbiAgICB2YXIgYXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIGZib3VuZCgpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2UuZGlzcGF0Y2goXCJhcHBseVwiLCBbXG4gICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgYXJncy5jb25jYXQoYXJyYXlfc2xpY2UoYXJndW1lbnRzKSlcbiAgICAgICAgXSk7XG4gICAgfTtcbn07XG5Qcm9taXNlLnByb3RvdHlwZS5mYmluZCA9IGZ1bmN0aW9uICgvKi4uLmFyZ3MqLykge1xuICAgIHZhciBwcm9taXNlID0gdGhpcztcbiAgICB2YXIgYXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIGZib3VuZCgpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2UuZGlzcGF0Y2goXCJhcHBseVwiLCBbXG4gICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgYXJncy5jb25jYXQoYXJyYXlfc2xpY2UoYXJndW1lbnRzKSlcbiAgICAgICAgXSk7XG4gICAgfTtcbn07XG5cbi8qKlxuICogUmVxdWVzdHMgdGhlIG5hbWVzIG9mIHRoZSBvd25lZCBwcm9wZXJ0aWVzIG9mIGEgcHJvbWlzZWRcbiAqIG9iamVjdCBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBvYmplY3RcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIGtleXMgb2YgdGhlIGV2ZW50dWFsbHkgc2V0dGxlZCBvYmplY3RcbiAqL1xuUS5rZXlzID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJrZXlzXCIsIFtdKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmtleXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJrZXlzXCIsIFtdKTtcbn07XG5cbi8qKlxuICogVHVybnMgYW4gYXJyYXkgb2YgcHJvbWlzZXMgaW50byBhIHByb21pc2UgZm9yIGFuIGFycmF5LiAgSWYgYW55IG9mXG4gKiB0aGUgcHJvbWlzZXMgZ2V0cyByZWplY3RlZCwgdGhlIHdob2xlIGFycmF5IGlzIHJlamVjdGVkIGltbWVkaWF0ZWx5LlxuICogQHBhcmFtIHtBcnJheSp9IGFuIGFycmF5IChvciBwcm9taXNlIGZvciBhbiBhcnJheSkgb2YgdmFsdWVzIChvclxuICogcHJvbWlzZXMgZm9yIHZhbHVlcylcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkgb2YgdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWVzXG4gKi9cbi8vIEJ5IE1hcmsgTWlsbGVyXG4vLyBodHRwOi8vd2lraS5lY21hc2NyaXB0Lm9yZy9kb2t1LnBocD9pZD1zdHJhd21hbjpjb25jdXJyZW5jeSZyZXY9MTMwODc3NjUyMSNhbGxmdWxmaWxsZWRcblEuYWxsID0gYWxsO1xuZnVuY3Rpb24gYWxsKHByb21pc2VzKSB7XG4gICAgcmV0dXJuIHdoZW4ocHJvbWlzZXMsIGZ1bmN0aW9uIChwcm9taXNlcykge1xuICAgICAgICB2YXIgcGVuZGluZ0NvdW50ID0gMDtcbiAgICAgICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICAgICAgYXJyYXlfcmVkdWNlKHByb21pc2VzLCBmdW5jdGlvbiAodW5kZWZpbmVkLCBwcm9taXNlLCBpbmRleCkge1xuICAgICAgICAgICAgdmFyIHNuYXBzaG90O1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIGlzUHJvbWlzZShwcm9taXNlKSAmJlxuICAgICAgICAgICAgICAgIChzbmFwc2hvdCA9IHByb21pc2UuaW5zcGVjdCgpKS5zdGF0ZSA9PT0gXCJmdWxmaWxsZWRcIlxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgcHJvbWlzZXNbaW5kZXhdID0gc25hcHNob3QudmFsdWU7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICsrcGVuZGluZ0NvdW50O1xuICAgICAgICAgICAgICAgIHdoZW4oXG4gICAgICAgICAgICAgICAgICAgIHByb21pc2UsXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXNbaW5kZXhdID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoLS1wZW5kaW5nQ291bnQgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHByb21pc2VzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQucmVqZWN0LFxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAocHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLm5vdGlmeSh7IGluZGV4OiBpbmRleCwgdmFsdWU6IHByb2dyZXNzIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdm9pZCAwKTtcbiAgICAgICAgaWYgKHBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShwcm9taXNlcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgfSk7XG59XG5cblByb21pc2UucHJvdG90eXBlLmFsbCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYWxsKHRoaXMpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBmaXJzdCByZXNvbHZlZCBwcm9taXNlIG9mIGFuIGFycmF5LiBQcmlvciByZWplY3RlZCBwcm9taXNlcyBhcmVcbiAqIGlnbm9yZWQuICBSZWplY3RzIG9ubHkgaWYgYWxsIHByb21pc2VzIGFyZSByZWplY3RlZC5cbiAqIEBwYXJhbSB7QXJyYXkqfSBhbiBhcnJheSBjb250YWluaW5nIHZhbHVlcyBvciBwcm9taXNlcyBmb3IgdmFsdWVzXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZnVsZmlsbGVkIHdpdGggdGhlIHZhbHVlIG9mIHRoZSBmaXJzdCByZXNvbHZlZCBwcm9taXNlLFxuICogb3IgYSByZWplY3RlZCBwcm9taXNlIGlmIGFsbCBwcm9taXNlcyBhcmUgcmVqZWN0ZWQuXG4gKi9cblEuYW55ID0gYW55O1xuXG5mdW5jdGlvbiBhbnkocHJvbWlzZXMpIHtcbiAgICBpZiAocHJvbWlzZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBRLnJlc29sdmUoKTtcbiAgICB9XG5cbiAgICB2YXIgZGVmZXJyZWQgPSBRLmRlZmVyKCk7XG4gICAgdmFyIHBlbmRpbmdDb3VudCA9IDA7XG4gICAgYXJyYXlfcmVkdWNlKHByb21pc2VzLCBmdW5jdGlvbiAocHJldiwgY3VycmVudCwgaW5kZXgpIHtcbiAgICAgICAgdmFyIHByb21pc2UgPSBwcm9taXNlc1tpbmRleF07XG5cbiAgICAgICAgcGVuZGluZ0NvdW50Kys7XG5cbiAgICAgICAgd2hlbihwcm9taXNlLCBvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCwgb25Qcm9ncmVzcyk7XG4gICAgICAgIGZ1bmN0aW9uIG9uRnVsZmlsbGVkKHJlc3VsdCkge1xuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG9uUmVqZWN0ZWQoZXJyKSB7XG4gICAgICAgICAgICBwZW5kaW5nQ291bnQtLTtcbiAgICAgICAgICAgIGlmIChwZW5kaW5nQ291bnQgPT09IDApIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVqZWN0aW9uID0gZXJyIHx8IG5ldyBFcnJvcihcIlwiICsgZXJyKTtcblxuICAgICAgICAgICAgICAgIHJlamVjdGlvbi5tZXNzYWdlID0gKFwiUSBjYW4ndCBnZXQgZnVsZmlsbG1lbnQgdmFsdWUgZnJvbSBhbnkgcHJvbWlzZSwgYWxsIFwiICtcbiAgICAgICAgICAgICAgICAgICAgXCJwcm9taXNlcyB3ZXJlIHJlamVjdGVkLiBMYXN0IGVycm9yIG1lc3NhZ2U6IFwiICsgcmVqZWN0aW9uLm1lc3NhZ2UpO1xuXG4gICAgICAgICAgICAgICAgZGVmZXJyZWQucmVqZWN0KHJlamVjdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gb25Qcm9ncmVzcyhwcm9ncmVzcykge1xuICAgICAgICAgICAgZGVmZXJyZWQubm90aWZ5KHtcbiAgICAgICAgICAgICAgICBpbmRleDogaW5kZXgsXG4gICAgICAgICAgICAgICAgdmFsdWU6IHByb2dyZXNzXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0sIHVuZGVmaW5lZCk7XG5cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYW55ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhbnkodGhpcyk7XG59O1xuXG4vKipcbiAqIFdhaXRzIGZvciBhbGwgcHJvbWlzZXMgdG8gYmUgc2V0dGxlZCwgZWl0aGVyIGZ1bGZpbGxlZCBvclxuICogcmVqZWN0ZWQuICBUaGlzIGlzIGRpc3RpbmN0IGZyb20gYGFsbGAgc2luY2UgdGhhdCB3b3VsZCBzdG9wXG4gKiB3YWl0aW5nIGF0IHRoZSBmaXJzdCByZWplY3Rpb24uICBUaGUgcHJvbWlzZSByZXR1cm5lZCBieVxuICogYGFsbFJlc29sdmVkYCB3aWxsIG5ldmVyIGJlIHJlamVjdGVkLlxuICogQHBhcmFtIHByb21pc2VzIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkgKG9yIGFuIGFycmF5KSBvZiBwcm9taXNlc1xuICogKG9yIHZhbHVlcylcbiAqIEByZXR1cm4gYSBwcm9taXNlIGZvciBhbiBhcnJheSBvZiBwcm9taXNlc1xuICovXG5RLmFsbFJlc29sdmVkID0gZGVwcmVjYXRlKGFsbFJlc29sdmVkLCBcImFsbFJlc29sdmVkXCIsIFwiYWxsU2V0dGxlZFwiKTtcbmZ1bmN0aW9uIGFsbFJlc29sdmVkKHByb21pc2VzKSB7XG4gICAgcmV0dXJuIHdoZW4ocHJvbWlzZXMsIGZ1bmN0aW9uIChwcm9taXNlcykge1xuICAgICAgICBwcm9taXNlcyA9IGFycmF5X21hcChwcm9taXNlcywgUSk7XG4gICAgICAgIHJldHVybiB3aGVuKGFsbChhcnJheV9tYXAocHJvbWlzZXMsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4gd2hlbihwcm9taXNlLCBub29wLCBub29wKTtcbiAgICAgICAgfSkpLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZXM7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5hbGxSZXNvbHZlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYWxsUmVzb2x2ZWQodGhpcyk7XG59O1xuXG4vKipcbiAqIEBzZWUgUHJvbWlzZSNhbGxTZXR0bGVkXG4gKi9cblEuYWxsU2V0dGxlZCA9IGFsbFNldHRsZWQ7XG5mdW5jdGlvbiBhbGxTZXR0bGVkKHByb21pc2VzKSB7XG4gICAgcmV0dXJuIFEocHJvbWlzZXMpLmFsbFNldHRsZWQoKTtcbn1cblxuLyoqXG4gKiBUdXJucyBhbiBhcnJheSBvZiBwcm9taXNlcyBpbnRvIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkgb2YgdGhlaXIgc3RhdGVzIChhc1xuICogcmV0dXJuZWQgYnkgYGluc3BlY3RgKSB3aGVuIHRoZXkgaGF2ZSBhbGwgc2V0dGxlZC5cbiAqIEBwYXJhbSB7QXJyYXlbQW55Kl19IHZhbHVlcyBhbiBhcnJheSAob3IgcHJvbWlzZSBmb3IgYW4gYXJyYXkpIG9mIHZhbHVlcyAob3JcbiAqIHByb21pc2VzIGZvciB2YWx1ZXMpXG4gKiBAcmV0dXJucyB7QXJyYXlbU3RhdGVdfSBhbiBhcnJheSBvZiBzdGF0ZXMgZm9yIHRoZSByZXNwZWN0aXZlIHZhbHVlcy5cbiAqL1xuUHJvbWlzZS5wcm90b3R5cGUuYWxsU2V0dGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uIChwcm9taXNlcykge1xuICAgICAgICByZXR1cm4gYWxsKGFycmF5X21hcChwcm9taXNlcywgZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgICAgICAgICAgIHByb21pc2UgPSBRKHByb21pc2UpO1xuICAgICAgICAgICAgZnVuY3Rpb24gcmVnYXJkbGVzcygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZS5pbnNwZWN0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZS50aGVuKHJlZ2FyZGxlc3MsIHJlZ2FyZGxlc3MpO1xuICAgICAgICB9KSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIENhcHR1cmVzIHRoZSBmYWlsdXJlIG9mIGEgcHJvbWlzZSwgZ2l2aW5nIGFuIG9wb3J0dW5pdHkgdG8gcmVjb3ZlclxuICogd2l0aCBhIGNhbGxiYWNrLiAgSWYgdGhlIGdpdmVuIHByb21pc2UgaXMgZnVsZmlsbGVkLCB0aGUgcmV0dXJuZWRcbiAqIHByb21pc2UgaXMgZnVsZmlsbGVkLlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlIGZvciBzb21ldGhpbmdcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHRvIGZ1bGZpbGwgdGhlIHJldHVybmVkIHByb21pc2UgaWYgdGhlXG4gKiBnaXZlbiBwcm9taXNlIGlzIHJlamVjdGVkXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGNhbGxiYWNrXG4gKi9cblEuZmFpbCA9IC8vIFhYWCBsZWdhY3lcblFbXCJjYXRjaFwiXSA9IGZ1bmN0aW9uIChvYmplY3QsIHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS50aGVuKHZvaWQgMCwgcmVqZWN0ZWQpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmFpbCA9IC8vIFhYWCBsZWdhY3lcblByb21pc2UucHJvdG90eXBlW1wiY2F0Y2hcIl0gPSBmdW5jdGlvbiAocmVqZWN0ZWQpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKHZvaWQgMCwgcmVqZWN0ZWQpO1xufTtcblxuLyoqXG4gKiBBdHRhY2hlcyBhIGxpc3RlbmVyIHRoYXQgY2FuIHJlc3BvbmQgdG8gcHJvZ3Jlc3Mgbm90aWZpY2F0aW9ucyBmcm9tIGFcbiAqIHByb21pc2UncyBvcmlnaW5hdGluZyBkZWZlcnJlZC4gVGhpcyBsaXN0ZW5lciByZWNlaXZlcyB0aGUgZXhhY3QgYXJndW1lbnRzXG4gKiBwYXNzZWQgdG8gYGBkZWZlcnJlZC5ub3RpZnlgYC5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBmb3Igc29tZXRoaW5nXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byByZWNlaXZlIGFueSBwcm9ncmVzcyBub3RpZmljYXRpb25zXG4gKiBAcmV0dXJucyB0aGUgZ2l2ZW4gcHJvbWlzZSwgdW5jaGFuZ2VkXG4gKi9cblEucHJvZ3Jlc3MgPSBwcm9ncmVzcztcbmZ1bmN0aW9uIHByb2dyZXNzKG9iamVjdCwgcHJvZ3Jlc3NlZCkge1xuICAgIHJldHVybiBRKG9iamVjdCkudGhlbih2b2lkIDAsIHZvaWQgMCwgcHJvZ3Jlc3NlZCk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnByb2dyZXNzID0gZnVuY3Rpb24gKHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKHZvaWQgMCwgdm9pZCAwLCBwcm9ncmVzc2VkKTtcbn07XG5cbi8qKlxuICogUHJvdmlkZXMgYW4gb3Bwb3J0dW5pdHkgdG8gb2JzZXJ2ZSB0aGUgc2V0dGxpbmcgb2YgYSBwcm9taXNlLFxuICogcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZSBwcm9taXNlIGlzIGZ1bGZpbGxlZCBvciByZWplY3RlZC4gIEZvcndhcmRzXG4gKiB0aGUgcmVzb2x1dGlvbiB0byB0aGUgcmV0dXJuZWQgcHJvbWlzZSB3aGVuIHRoZSBjYWxsYmFjayBpcyBkb25lLlxuICogVGhlIGNhbGxiYWNrIGNhbiByZXR1cm4gYSBwcm9taXNlIHRvIGRlZmVyIGNvbXBsZXRpb24uXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2VcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHRvIG9ic2VydmUgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuXG4gKiBwcm9taXNlLCB0YWtlcyBubyBhcmd1bWVudHMuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlbiBwcm9taXNlIHdoZW5cbiAqIGBgZmluYGAgaXMgZG9uZS5cbiAqL1xuUS5maW4gPSAvLyBYWFggbGVnYWN5XG5RW1wiZmluYWxseVwiXSA9IGZ1bmN0aW9uIChvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KVtcImZpbmFsbHlcIl0oY2FsbGJhY2spO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmluID0gLy8gWFhYIGxlZ2FjeVxuUHJvbWlzZS5wcm90b3R5cGVbXCJmaW5hbGx5XCJdID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgaWYgKCFjYWxsYmFjayB8fCB0eXBlb2YgY2FsbGJhY2suYXBwbHkgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJRIGNhbid0IGFwcGx5IGZpbmFsbHkgY2FsbGJhY2tcIik7XG4gICAgfVxuICAgIGNhbGxiYWNrID0gUShjYWxsYmFjayk7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgLy8gVE9ETyBhdHRlbXB0IHRvIHJlY3ljbGUgdGhlIHJlamVjdGlvbiB3aXRoIFwidGhpc1wiLlxuICAgICAgICByZXR1cm4gY2FsbGJhY2suZmNhbGwoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRocm93IHJlYXNvbjtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFRlcm1pbmF0ZXMgYSBjaGFpbiBvZiBwcm9taXNlcywgZm9yY2luZyByZWplY3Rpb25zIHRvIGJlXG4gKiB0aHJvd24gYXMgZXhjZXB0aW9ucy5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBhdCB0aGUgZW5kIG9mIGEgY2hhaW4gb2YgcHJvbWlzZXNcbiAqIEByZXR1cm5zIG5vdGhpbmdcbiAqL1xuUS5kb25lID0gZnVuY3Rpb24gKG9iamVjdCwgZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRvbmUoZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZG9uZSA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykge1xuICAgIHZhciBvblVuaGFuZGxlZEVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIC8vIGZvcndhcmQgdG8gYSBmdXR1cmUgdHVybiBzbyB0aGF0IGBgd2hlbmBgXG4gICAgICAgIC8vIGRvZXMgbm90IGNhdGNoIGl0IGFuZCB0dXJuIGl0IGludG8gYSByZWplY3Rpb24uXG4gICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGVycm9yLCBwcm9taXNlKTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8vIEF2b2lkIHVubmVjZXNzYXJ5IGBuZXh0VGlja2BpbmcgdmlhIGFuIHVubmVjZXNzYXJ5IGB3aGVuYC5cbiAgICB2YXIgcHJvbWlzZSA9IGZ1bGZpbGxlZCB8fCByZWplY3RlZCB8fCBwcm9ncmVzcyA/XG4gICAgICAgIHRoaXMudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykgOlxuICAgICAgICB0aGlzO1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHByb2Nlc3MgJiYgcHJvY2Vzcy5kb21haW4pIHtcbiAgICAgICAgb25VbmhhbmRsZWRFcnJvciA9IHByb2Nlc3MuZG9tYWluLmJpbmQob25VbmhhbmRsZWRFcnJvcik7XG4gICAgfVxuXG4gICAgcHJvbWlzZS50aGVuKHZvaWQgMCwgb25VbmhhbmRsZWRFcnJvcik7XG59O1xuXG4vKipcbiAqIENhdXNlcyBhIHByb21pc2UgdG8gYmUgcmVqZWN0ZWQgaWYgaXQgZG9lcyBub3QgZ2V0IGZ1bGZpbGxlZCBiZWZvcmVcbiAqIHNvbWUgbWlsbGlzZWNvbmRzIHRpbWUgb3V0LlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge051bWJlcn0gbWlsbGlzZWNvbmRzIHRpbWVvdXRcbiAqIEBwYXJhbSB7QW55Kn0gY3VzdG9tIGVycm9yIG1lc3NhZ2Ugb3IgRXJyb3Igb2JqZWN0IChvcHRpb25hbClcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UgaWYgaXQgaXNcbiAqIGZ1bGZpbGxlZCBiZWZvcmUgdGhlIHRpbWVvdXQsIG90aGVyd2lzZSByZWplY3RlZC5cbiAqL1xuUS50aW1lb3V0ID0gZnVuY3Rpb24gKG9iamVjdCwgbXMsIGVycm9yKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS50aW1lb3V0KG1zLCBlcnJvcik7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aW1lb3V0ID0gZnVuY3Rpb24gKG1zLCBlcnJvcikge1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgdmFyIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIWVycm9yIHx8IFwic3RyaW5nXCIgPT09IHR5cGVvZiBlcnJvcikge1xuICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoZXJyb3IgfHwgXCJUaW1lZCBvdXQgYWZ0ZXIgXCIgKyBtcyArIFwiIG1zXCIpO1xuICAgICAgICAgICAgZXJyb3IuY29kZSA9IFwiRVRJTUVET1VUXCI7XG4gICAgICAgIH1cbiAgICAgICAgZGVmZXJyZWQucmVqZWN0KGVycm9yKTtcbiAgICB9LCBtcyk7XG5cbiAgICB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHZhbHVlKTtcbiAgICB9LCBmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9LCBkZWZlcnJlZC5ub3RpZnkpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZ2l2ZW4gdmFsdWUgKG9yIHByb21pc2VkIHZhbHVlKSwgc29tZVxuICogbWlsbGlzZWNvbmRzIGFmdGVyIGl0IHJlc29sdmVkLiBQYXNzZXMgcmVqZWN0aW9ucyBpbW1lZGlhdGVseS5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZVxuICogQHBhcmFtIHtOdW1iZXJ9IG1pbGxpc2Vjb25kc1xuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSBhZnRlciBtaWxsaXNlY29uZHNcbiAqIHRpbWUgaGFzIGVsYXBzZWQgc2luY2UgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UuXG4gKiBJZiB0aGUgZ2l2ZW4gcHJvbWlzZSByZWplY3RzLCB0aGF0IGlzIHBhc3NlZCBpbW1lZGlhdGVseS5cbiAqL1xuUS5kZWxheSA9IGZ1bmN0aW9uIChvYmplY3QsIHRpbWVvdXQpIHtcbiAgICBpZiAodGltZW91dCA9PT0gdm9pZCAwKSB7XG4gICAgICAgIHRpbWVvdXQgPSBvYmplY3Q7XG4gICAgICAgIG9iamVjdCA9IHZvaWQgMDtcbiAgICB9XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kZWxheSh0aW1lb3V0KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmRlbGF5ID0gZnVuY3Rpb24gKHRpbWVvdXQpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUodmFsdWUpO1xuICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFBhc3NlcyBhIGNvbnRpbnVhdGlvbiB0byBhIE5vZGUgZnVuY3Rpb24sIHdoaWNoIGlzIGNhbGxlZCB3aXRoIHRoZSBnaXZlblxuICogYXJndW1lbnRzIHByb3ZpZGVkIGFzIGFuIGFycmF5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKlxuICogICAgICBRLm5mYXBwbHkoRlMucmVhZEZpbGUsIFtfX2ZpbGVuYW1lXSlcbiAqICAgICAgLnRoZW4oZnVuY3Rpb24gKGNvbnRlbnQpIHtcbiAqICAgICAgfSlcbiAqXG4gKi9cblEubmZhcHBseSA9IGZ1bmN0aW9uIChjYWxsYmFjaywgYXJncykge1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgdGhpcy5mYXBwbHkobm9kZUFyZ3MpLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogUGFzc2VzIGEgY29udGludWF0aW9uIHRvIGEgTm9kZSBmdW5jdGlvbiwgd2hpY2ggaXMgY2FsbGVkIHdpdGggdGhlIGdpdmVuXG4gKiBhcmd1bWVudHMgcHJvdmlkZWQgaW5kaXZpZHVhbGx5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmNhbGwoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpXG4gKiAudGhlbihmdW5jdGlvbiAoY29udGVudCkge1xuICogfSlcbiAqXG4gKi9cblEubmZjYWxsID0gZnVuY3Rpb24gKGNhbGxiYWNrIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZjYWxsID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIG5vZGVBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBXcmFwcyBhIE5vZGVKUyBjb250aW51YXRpb24gcGFzc2luZyBmdW5jdGlvbiBhbmQgcmV0dXJucyBhbiBlcXVpdmFsZW50XG4gKiB2ZXJzaW9uIHRoYXQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmJpbmQoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpKFwidXRmLThcIilcbiAqIC50aGVuKGNvbnNvbGUubG9nKVxuICogLmRvbmUoKVxuICovXG5RLm5mYmluZCA9XG5RLmRlbm9kZWlmeSA9IGZ1bmN0aW9uIChjYWxsYmFjayAvKi4uLmFyZ3MqLykge1xuICAgIGlmIChjYWxsYmFjayA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlEgY2FuJ3Qgd3JhcCBhbiB1bmRlZmluZWQgZnVuY3Rpb25cIik7XG4gICAgfVxuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIFEoY2FsbGJhY2spLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZiaW5kID1cblByb21pc2UucHJvdG90eXBlLmRlbm9kZWlmeSA9IGZ1bmN0aW9uICgvKi4uLmFyZ3MqLykge1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICBhcmdzLnVuc2hpZnQodGhpcyk7XG4gICAgcmV0dXJuIFEuZGVub2RlaWZ5LmFwcGx5KHZvaWQgMCwgYXJncyk7XG59O1xuXG5RLm5iaW5kID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0aGlzcCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIGZ1bmN0aW9uIGJvdW5kKCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHRoaXNwLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICAgIFEoYm91bmQpLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmJpbmQgPSBmdW5jdGlvbiAoLyp0aGlzcCwgLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDApO1xuICAgIGFyZ3MudW5zaGlmdCh0aGlzKTtcbiAgICByZXR1cm4gUS5uYmluZC5hcHBseSh2b2lkIDAsIGFyZ3MpO1xufTtcblxuLyoqXG4gKiBDYWxscyBhIG1ldGhvZCBvZiBhIE5vZGUtc3R5bGUgb2JqZWN0IHRoYXQgYWNjZXB0cyBhIE5vZGUtc3R5bGVcbiAqIGNhbGxiYWNrIHdpdGggYSBnaXZlbiBhcnJheSBvZiBhcmd1bWVudHMsIHBsdXMgYSBwcm92aWRlZCBjYWxsYmFjay5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG1ldGhvZDsgdGhlIGNhbGxiYWNrXG4gKiB3aWxsIGJlIHByb3ZpZGVkIGJ5IFEgYW5kIGFwcGVuZGVkIHRvIHRoZXNlIGFyZ3VtZW50cy5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHZhbHVlIG9yIGVycm9yXG4gKi9cblEubm1hcHBseSA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLm5wb3N0ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkubnBvc3QobmFtZSwgYXJncyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5ubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLm5wb3N0ID0gZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzIHx8IFtdKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIENhbGxzIGEgbWV0aG9kIG9mIGEgTm9kZS1zdHlsZSBvYmplY3QgdGhhdCBhY2NlcHRzIGEgTm9kZS1zdHlsZVxuICogY2FsbGJhY2ssIGZvcndhcmRpbmcgdGhlIGdpdmVuIHZhcmlhZGljIGFyZ3VtZW50cywgcGx1cyBhIHByb3ZpZGVkXG4gKiBjYWxsYmFjayBhcmd1bWVudC5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSAuLi5hcmdzIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXRob2Q7IHRoZSBjYWxsYmFjayB3aWxsXG4gKiBiZSBwcm92aWRlZCBieSBRIGFuZCBhcHBlbmRlZCB0byB0aGVzZSBhcmd1bWVudHMuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSB2YWx1ZSBvciBlcnJvclxuICovXG5RLm5zZW5kID0gLy8gWFhYIEJhc2VkIG9uIE1hcmsgTWlsbGVyJ3MgcHJvcG9zZWQgXCJzZW5kXCJcblEubm1jYWxsID0gLy8gWFhYIEJhc2VkIG9uIFwiUmVkc2FuZHJvJ3NcIiBwcm9wb3NhbFxuUS5uaW52b2tlID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uc2VuZCA9IC8vIFhYWCBCYXNlZCBvbiBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIFwic2VuZFwiXG5Qcm9taXNlLnByb3RvdHlwZS5ubWNhbGwgPSAvLyBYWFggQmFzZWQgb24gXCJSZWRzYW5kcm8nc1wiIHByb3Bvc2FsXG5Qcm9taXNlLnByb3RvdHlwZS5uaW52b2tlID0gZnVuY3Rpb24gKG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBub2RlQXJnc10pLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogSWYgYSBmdW5jdGlvbiB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgYm90aCBOb2RlIGNvbnRpbnVhdGlvbi1wYXNzaW5nLXN0eWxlIGFuZFxuICogcHJvbWlzZS1yZXR1cm5pbmctc3R5bGUsIGl0IGNhbiBlbmQgaXRzIGludGVybmFsIHByb21pc2UgY2hhaW4gd2l0aFxuICogYG5vZGVpZnkobm9kZWJhY2spYCwgZm9yd2FyZGluZyB0aGUgb3B0aW9uYWwgbm9kZWJhY2sgYXJndW1lbnQuICBJZiB0aGUgdXNlclxuICogZWxlY3RzIHRvIHVzZSBhIG5vZGViYWNrLCB0aGUgcmVzdWx0IHdpbGwgYmUgc2VudCB0aGVyZS4gIElmIHRoZXkgZG8gbm90XG4gKiBwYXNzIGEgbm9kZWJhY2ssIHRoZXkgd2lsbCByZWNlaXZlIHRoZSByZXN1bHQgcHJvbWlzZS5cbiAqIEBwYXJhbSBvYmplY3QgYSByZXN1bHQgKG9yIGEgcHJvbWlzZSBmb3IgYSByZXN1bHQpXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBub2RlYmFjayBhIE5vZGUuanMtc3R5bGUgY2FsbGJhY2tcbiAqIEByZXR1cm5zIGVpdGhlciB0aGUgcHJvbWlzZSBvciBub3RoaW5nXG4gKi9cblEubm9kZWlmeSA9IG5vZGVpZnk7XG5mdW5jdGlvbiBub2RlaWZ5KG9iamVjdCwgbm9kZWJhY2spIHtcbiAgICByZXR1cm4gUShvYmplY3QpLm5vZGVpZnkobm9kZWJhY2spO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5ub2RlaWZ5ID0gZnVuY3Rpb24gKG5vZGViYWNrKSB7XG4gICAgaWYgKG5vZGViYWNrKSB7XG4gICAgICAgIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKG51bGwsIHZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59O1xuXG5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJRLm5vQ29uZmxpY3Qgb25seSB3b3JrcyB3aGVuIFEgaXMgdXNlZCBhcyBhIGdsb2JhbFwiKTtcbn07XG5cbi8vIEFsbCBjb2RlIGJlZm9yZSB0aGlzIHBvaW50IHdpbGwgYmUgZmlsdGVyZWQgZnJvbSBzdGFjayB0cmFjZXMuXG52YXIgcUVuZGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xuXG5yZXR1cm4gUTtcblxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciByZXBsYWNlID0gU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlO1xudmFyIHBlcmNlbnRUd2VudGllcyA9IC8lMjAvZztcblxudmFyIHV0aWwgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5cbnZhciBGb3JtYXQgPSB7XG4gICAgUkZDMTczODogJ1JGQzE3MzgnLFxuICAgIFJGQzM5ODY6ICdSRkMzOTg2J1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB1dGlsLmFzc2lnbihcbiAgICB7XG4gICAgICAgICdkZWZhdWx0JzogRm9ybWF0LlJGQzM5ODYsXG4gICAgICAgIGZvcm1hdHRlcnM6IHtcbiAgICAgICAgICAgIFJGQzE3Mzg6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXBsYWNlLmNhbGwodmFsdWUsIHBlcmNlbnRUd2VudGllcywgJysnKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBSRkMzOTg2OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG4gICAgRm9ybWF0XG4pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgc3RyaW5naWZ5ID0gcmVxdWlyZSgnLi9zdHJpbmdpZnknKTtcbnZhciBwYXJzZSA9IHJlcXVpcmUoJy4vcGFyc2UnKTtcbnZhciBmb3JtYXRzID0gcmVxdWlyZSgnLi9mb3JtYXRzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIGZvcm1hdHM6IGZvcm1hdHMsXG4gICAgcGFyc2U6IHBhcnNlLFxuICAgIHN0cmluZ2lmeTogc3RyaW5naWZ5XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5cbnZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuXG52YXIgZGVmYXVsdHMgPSB7XG4gICAgYWxsb3dEb3RzOiBmYWxzZSxcbiAgICBhbGxvd1Byb3RvdHlwZXM6IGZhbHNlLFxuICAgIGFycmF5TGltaXQ6IDIwLFxuICAgIGNoYXJzZXQ6ICd1dGYtOCcsXG4gICAgY2hhcnNldFNlbnRpbmVsOiBmYWxzZSxcbiAgICBjb21tYTogZmFsc2UsXG4gICAgZGVjb2RlcjogdXRpbHMuZGVjb2RlLFxuICAgIGRlbGltaXRlcjogJyYnLFxuICAgIGRlcHRoOiA1LFxuICAgIGlnbm9yZVF1ZXJ5UHJlZml4OiBmYWxzZSxcbiAgICBpbnRlcnByZXROdW1lcmljRW50aXRpZXM6IGZhbHNlLFxuICAgIHBhcmFtZXRlckxpbWl0OiAxMDAwLFxuICAgIHBhcnNlQXJyYXlzOiB0cnVlLFxuICAgIHBsYWluT2JqZWN0czogZmFsc2UsXG4gICAgc3RyaWN0TnVsbEhhbmRsaW5nOiBmYWxzZVxufTtcblxudmFyIGludGVycHJldE51bWVyaWNFbnRpdGllcyA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgICByZXR1cm4gc3RyLnJlcGxhY2UoLyYjKFxcZCspOy9nLCBmdW5jdGlvbiAoJDAsIG51bWJlclN0cikge1xuICAgICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShwYXJzZUludChudW1iZXJTdHIsIDEwKSk7XG4gICAgfSk7XG59O1xuXG52YXIgcGFyc2VBcnJheVZhbHVlID0gZnVuY3Rpb24gKHZhbCwgb3B0aW9ucykge1xuICAgIGlmICh2YWwgJiYgdHlwZW9mIHZhbCA9PT0gJ3N0cmluZycgJiYgb3B0aW9ucy5jb21tYSAmJiB2YWwuaW5kZXhPZignLCcpID4gLTEpIHtcbiAgICAgICAgcmV0dXJuIHZhbC5zcGxpdCgnLCcpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWw7XG59O1xuXG52YXIgbWF5YmVNYXAgPSBmdW5jdGlvbiBtYXliZU1hcCh2YWwsIGZuKSB7XG4gICAgaWYgKGlzQXJyYXkodmFsKSkge1xuICAgICAgICB2YXIgbWFwcGVkID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBtYXBwZWQucHVzaChmbih2YWxbaV0pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWFwcGVkO1xuICAgIH1cbiAgICByZXR1cm4gZm4odmFsKTtcbn07XG5cbi8vIFRoaXMgaXMgd2hhdCBicm93c2VycyB3aWxsIHN1Ym1pdCB3aGVuIHRoZSDinJMgY2hhcmFjdGVyIG9jY3VycyBpbiBhblxuLy8gYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkIGJvZHkgYW5kIHRoZSBlbmNvZGluZyBvZiB0aGUgcGFnZSBjb250YWluaW5nXG4vLyB0aGUgZm9ybSBpcyBpc28tODg1OS0xLCBvciB3aGVuIHRoZSBzdWJtaXR0ZWQgZm9ybSBoYXMgYW4gYWNjZXB0LWNoYXJzZXRcbi8vIGF0dHJpYnV0ZSBvZiBpc28tODg1OS0xLiBQcmVzdW1hYmx5IGFsc28gd2l0aCBvdGhlciBjaGFyc2V0cyB0aGF0IGRvIG5vdCBjb250YWluXG4vLyB0aGUg4pyTIGNoYXJhY3Rlciwgc3VjaCBhcyB1cy1hc2NpaS5cbnZhciBpc29TZW50aW5lbCA9ICd1dGY4PSUyNiUyMzEwMDAzJTNCJzsgLy8gZW5jb2RlVVJJQ29tcG9uZW50KCcmIzEwMDAzOycpXG5cbi8vIFRoZXNlIGFyZSB0aGUgcGVyY2VudC1lbmNvZGVkIHV0Zi04IG9jdGV0cyByZXByZXNlbnRpbmcgYSBjaGVja21hcmssIGluZGljYXRpbmcgdGhhdCB0aGUgcmVxdWVzdCBhY3R1YWxseSBpcyB1dGYtOCBlbmNvZGVkLlxudmFyIGNoYXJzZXRTZW50aW5lbCA9ICd1dGY4PSVFMiU5QyU5Myc7IC8vIGVuY29kZVVSSUNvbXBvbmVudCgn4pyTJylcblxudmFyIHBhcnNlVmFsdWVzID0gZnVuY3Rpb24gcGFyc2VRdWVyeVN0cmluZ1ZhbHVlcyhzdHIsIG9wdGlvbnMpIHtcbiAgICB2YXIgb2JqID0ge307XG4gICAgdmFyIGNsZWFuU3RyID0gb3B0aW9ucy5pZ25vcmVRdWVyeVByZWZpeCA/IHN0ci5yZXBsYWNlKC9eXFw/LywgJycpIDogc3RyO1xuICAgIHZhciBsaW1pdCA9IG9wdGlvbnMucGFyYW1ldGVyTGltaXQgPT09IEluZmluaXR5ID8gdW5kZWZpbmVkIDogb3B0aW9ucy5wYXJhbWV0ZXJMaW1pdDtcbiAgICB2YXIgcGFydHMgPSBjbGVhblN0ci5zcGxpdChvcHRpb25zLmRlbGltaXRlciwgbGltaXQpO1xuICAgIHZhciBza2lwSW5kZXggPSAtMTsgLy8gS2VlcCB0cmFjayBvZiB3aGVyZSB0aGUgdXRmOCBzZW50aW5lbCB3YXMgZm91bmRcbiAgICB2YXIgaTtcblxuICAgIHZhciBjaGFyc2V0ID0gb3B0aW9ucy5jaGFyc2V0O1xuICAgIGlmIChvcHRpb25zLmNoYXJzZXRTZW50aW5lbCkge1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmIChwYXJ0c1tpXS5pbmRleE9mKCd1dGY4PScpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKHBhcnRzW2ldID09PSBjaGFyc2V0U2VudGluZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhcnNldCA9ICd1dGYtOCc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJ0c1tpXSA9PT0gaXNvU2VudGluZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhcnNldCA9ICdpc28tODg1OS0xJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2tpcEluZGV4ID0gaTtcbiAgICAgICAgICAgICAgICBpID0gcGFydHMubGVuZ3RoOyAvLyBUaGUgZXNsaW50IHNldHRpbmdzIGRvIG5vdCBhbGxvdyBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGg7ICsraSkge1xuICAgICAgICBpZiAoaSA9PT0gc2tpcEluZGV4KSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcGFydCA9IHBhcnRzW2ldO1xuXG4gICAgICAgIHZhciBicmFja2V0RXF1YWxzUG9zID0gcGFydC5pbmRleE9mKCddPScpO1xuICAgICAgICB2YXIgcG9zID0gYnJhY2tldEVxdWFsc1BvcyA9PT0gLTEgPyBwYXJ0LmluZGV4T2YoJz0nKSA6IGJyYWNrZXRFcXVhbHNQb3MgKyAxO1xuXG4gICAgICAgIHZhciBrZXksIHZhbDtcbiAgICAgICAgaWYgKHBvcyA9PT0gLTEpIHtcbiAgICAgICAgICAgIGtleSA9IG9wdGlvbnMuZGVjb2RlcihwYXJ0LCBkZWZhdWx0cy5kZWNvZGVyLCBjaGFyc2V0LCAna2V5Jyk7XG4gICAgICAgICAgICB2YWwgPSBvcHRpb25zLnN0cmljdE51bGxIYW5kbGluZyA/IG51bGwgOiAnJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGtleSA9IG9wdGlvbnMuZGVjb2RlcihwYXJ0LnNsaWNlKDAsIHBvcyksIGRlZmF1bHRzLmRlY29kZXIsIGNoYXJzZXQsICdrZXknKTtcbiAgICAgICAgICAgIHZhbCA9IG1heWJlTWFwKFxuICAgICAgICAgICAgICAgIHBhcnNlQXJyYXlWYWx1ZShwYXJ0LnNsaWNlKHBvcyArIDEpLCBvcHRpb25zKSxcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoZW5jb2RlZFZhbCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5kZWNvZGVyKGVuY29kZWRWYWwsIGRlZmF1bHRzLmRlY29kZXIsIGNoYXJzZXQsICd2YWx1ZScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmFsICYmIG9wdGlvbnMuaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzICYmIGNoYXJzZXQgPT09ICdpc28tODg1OS0xJykge1xuICAgICAgICAgICAgdmFsID0gaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzKHZhbCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFydC5pbmRleE9mKCdbXT0nKSA+IC0xKSB7XG4gICAgICAgICAgICB2YWwgPSBpc0FycmF5KHZhbCkgPyBbdmFsXSA6IHZhbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChoYXMuY2FsbChvYmosIGtleSkpIHtcbiAgICAgICAgICAgIG9ialtrZXldID0gdXRpbHMuY29tYmluZShvYmpba2V5XSwgdmFsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9ialtrZXldID0gdmFsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG9iajtcbn07XG5cbnZhciBwYXJzZU9iamVjdCA9IGZ1bmN0aW9uIChjaGFpbiwgdmFsLCBvcHRpb25zLCB2YWx1ZXNQYXJzZWQpIHtcbiAgICB2YXIgbGVhZiA9IHZhbHVlc1BhcnNlZCA/IHZhbCA6IHBhcnNlQXJyYXlWYWx1ZSh2YWwsIG9wdGlvbnMpO1xuXG4gICAgZm9yICh2YXIgaSA9IGNoYWluLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIHZhciBvYmo7XG4gICAgICAgIHZhciByb290ID0gY2hhaW5baV07XG5cbiAgICAgICAgaWYgKHJvb3QgPT09ICdbXScgJiYgb3B0aW9ucy5wYXJzZUFycmF5cykge1xuICAgICAgICAgICAgb2JqID0gW10uY29uY2F0KGxlYWYpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb2JqID0gb3B0aW9ucy5wbGFpbk9iamVjdHMgPyBPYmplY3QuY3JlYXRlKG51bGwpIDoge307XG4gICAgICAgICAgICB2YXIgY2xlYW5Sb290ID0gcm9vdC5jaGFyQXQoMCkgPT09ICdbJyAmJiByb290LmNoYXJBdChyb290Lmxlbmd0aCAtIDEpID09PSAnXScgPyByb290LnNsaWNlKDEsIC0xKSA6IHJvb3Q7XG4gICAgICAgICAgICB2YXIgaW5kZXggPSBwYXJzZUludChjbGVhblJvb3QsIDEwKTtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucy5wYXJzZUFycmF5cyAmJiBjbGVhblJvb3QgPT09ICcnKSB7XG4gICAgICAgICAgICAgICAgb2JqID0geyAwOiBsZWFmIH07XG4gICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgICFpc05hTihpbmRleClcbiAgICAgICAgICAgICAgICAmJiByb290ICE9PSBjbGVhblJvb3RcbiAgICAgICAgICAgICAgICAmJiBTdHJpbmcoaW5kZXgpID09PSBjbGVhblJvb3RcbiAgICAgICAgICAgICAgICAmJiBpbmRleCA+PSAwXG4gICAgICAgICAgICAgICAgJiYgKG9wdGlvbnMucGFyc2VBcnJheXMgJiYgaW5kZXggPD0gb3B0aW9ucy5hcnJheUxpbWl0KVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgb2JqID0gW107XG4gICAgICAgICAgICAgICAgb2JqW2luZGV4XSA9IGxlYWY7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG9ialtjbGVhblJvb3RdID0gbGVhZjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxlYWYgPSBvYmo7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cbiAgICB9XG5cbiAgICByZXR1cm4gbGVhZjtcbn07XG5cbnZhciBwYXJzZUtleXMgPSBmdW5jdGlvbiBwYXJzZVF1ZXJ5U3RyaW5nS2V5cyhnaXZlbktleSwgdmFsLCBvcHRpb25zLCB2YWx1ZXNQYXJzZWQpIHtcbiAgICBpZiAoIWdpdmVuS2V5KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBUcmFuc2Zvcm0gZG90IG5vdGF0aW9uIHRvIGJyYWNrZXQgbm90YXRpb25cbiAgICB2YXIga2V5ID0gb3B0aW9ucy5hbGxvd0RvdHMgPyBnaXZlbktleS5yZXBsYWNlKC9cXC4oW14uW10rKS9nLCAnWyQxXScpIDogZ2l2ZW5LZXk7XG5cbiAgICAvLyBUaGUgcmVnZXggY2h1bmtzXG5cbiAgICB2YXIgYnJhY2tldHMgPSAvKFxcW1teW1xcXV0qXSkvO1xuICAgIHZhciBjaGlsZCA9IC8oXFxbW15bXFxdXSpdKS9nO1xuXG4gICAgLy8gR2V0IHRoZSBwYXJlbnRcblxuICAgIHZhciBzZWdtZW50ID0gb3B0aW9ucy5kZXB0aCA+IDAgJiYgYnJhY2tldHMuZXhlYyhrZXkpO1xuICAgIHZhciBwYXJlbnQgPSBzZWdtZW50ID8ga2V5LnNsaWNlKDAsIHNlZ21lbnQuaW5kZXgpIDoga2V5O1xuXG4gICAgLy8gU3Rhc2ggdGhlIHBhcmVudCBpZiBpdCBleGlzdHNcblxuICAgIHZhciBrZXlzID0gW107XG4gICAgaWYgKHBhcmVudCkge1xuICAgICAgICAvLyBJZiB3ZSBhcmVuJ3QgdXNpbmcgcGxhaW4gb2JqZWN0cywgb3B0aW9uYWxseSBwcmVmaXgga2V5cyB0aGF0IHdvdWxkIG92ZXJ3cml0ZSBvYmplY3QgcHJvdG90eXBlIHByb3BlcnRpZXNcbiAgICAgICAgaWYgKCFvcHRpb25zLnBsYWluT2JqZWN0cyAmJiBoYXMuY2FsbChPYmplY3QucHJvdG90eXBlLCBwYXJlbnQpKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMuYWxsb3dQcm90b3R5cGVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAga2V5cy5wdXNoKHBhcmVudCk7XG4gICAgfVxuXG4gICAgLy8gTG9vcCB0aHJvdWdoIGNoaWxkcmVuIGFwcGVuZGluZyB0byB0aGUgYXJyYXkgdW50aWwgd2UgaGl0IGRlcHRoXG5cbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKG9wdGlvbnMuZGVwdGggPiAwICYmIChzZWdtZW50ID0gY2hpbGQuZXhlYyhrZXkpKSAhPT0gbnVsbCAmJiBpIDwgb3B0aW9ucy5kZXB0aCkge1xuICAgICAgICBpICs9IDE7XG4gICAgICAgIGlmICghb3B0aW9ucy5wbGFpbk9iamVjdHMgJiYgaGFzLmNhbGwoT2JqZWN0LnByb3RvdHlwZSwgc2VnbWVudFsxXS5zbGljZSgxLCAtMSkpKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMuYWxsb3dQcm90b3R5cGVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGtleXMucHVzaChzZWdtZW50WzFdKTtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGVyZSdzIGEgcmVtYWluZGVyLCBqdXN0IGFkZCB3aGF0ZXZlciBpcyBsZWZ0XG5cbiAgICBpZiAoc2VnbWVudCkge1xuICAgICAgICBrZXlzLnB1c2goJ1snICsga2V5LnNsaWNlKHNlZ21lbnQuaW5kZXgpICsgJ10nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFyc2VPYmplY3Qoa2V5cywgdmFsLCBvcHRpb25zLCB2YWx1ZXNQYXJzZWQpO1xufTtcblxudmFyIG5vcm1hbGl6ZVBhcnNlT3B0aW9ucyA9IGZ1bmN0aW9uIG5vcm1hbGl6ZVBhcnNlT3B0aW9ucyhvcHRzKSB7XG4gICAgaWYgKCFvcHRzKSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0cztcbiAgICB9XG5cbiAgICBpZiAob3B0cy5kZWNvZGVyICE9PSBudWxsICYmIG9wdHMuZGVjb2RlciAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvcHRzLmRlY29kZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRGVjb2RlciBoYXMgdG8gYmUgYSBmdW5jdGlvbi4nKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9wdHMuY2hhcnNldCAhPT0gJ3VuZGVmaW5lZCcgJiYgb3B0cy5jaGFyc2V0ICE9PSAndXRmLTgnICYmIG9wdHMuY2hhcnNldCAhPT0gJ2lzby04ODU5LTEnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBjaGFyc2V0IG9wdGlvbiBtdXN0IGJlIGVpdGhlciB1dGYtOCwgaXNvLTg4NTktMSwgb3IgdW5kZWZpbmVkJyk7XG4gICAgfVxuICAgIHZhciBjaGFyc2V0ID0gdHlwZW9mIG9wdHMuY2hhcnNldCA9PT0gJ3VuZGVmaW5lZCcgPyBkZWZhdWx0cy5jaGFyc2V0IDogb3B0cy5jaGFyc2V0O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgYWxsb3dEb3RzOiB0eXBlb2Ygb3B0cy5hbGxvd0RvdHMgPT09ICd1bmRlZmluZWQnID8gZGVmYXVsdHMuYWxsb3dEb3RzIDogISFvcHRzLmFsbG93RG90cyxcbiAgICAgICAgYWxsb3dQcm90b3R5cGVzOiB0eXBlb2Ygb3B0cy5hbGxvd1Byb3RvdHlwZXMgPT09ICdib29sZWFuJyA/IG9wdHMuYWxsb3dQcm90b3R5cGVzIDogZGVmYXVsdHMuYWxsb3dQcm90b3R5cGVzLFxuICAgICAgICBhcnJheUxpbWl0OiB0eXBlb2Ygb3B0cy5hcnJheUxpbWl0ID09PSAnbnVtYmVyJyA/IG9wdHMuYXJyYXlMaW1pdCA6IGRlZmF1bHRzLmFycmF5TGltaXQsXG4gICAgICAgIGNoYXJzZXQ6IGNoYXJzZXQsXG4gICAgICAgIGNoYXJzZXRTZW50aW5lbDogdHlwZW9mIG9wdHMuY2hhcnNldFNlbnRpbmVsID09PSAnYm9vbGVhbicgPyBvcHRzLmNoYXJzZXRTZW50aW5lbCA6IGRlZmF1bHRzLmNoYXJzZXRTZW50aW5lbCxcbiAgICAgICAgY29tbWE6IHR5cGVvZiBvcHRzLmNvbW1hID09PSAnYm9vbGVhbicgPyBvcHRzLmNvbW1hIDogZGVmYXVsdHMuY29tbWEsXG4gICAgICAgIGRlY29kZXI6IHR5cGVvZiBvcHRzLmRlY29kZXIgPT09ICdmdW5jdGlvbicgPyBvcHRzLmRlY29kZXIgOiBkZWZhdWx0cy5kZWNvZGVyLFxuICAgICAgICBkZWxpbWl0ZXI6IHR5cGVvZiBvcHRzLmRlbGltaXRlciA9PT0gJ3N0cmluZycgfHwgdXRpbHMuaXNSZWdFeHAob3B0cy5kZWxpbWl0ZXIpID8gb3B0cy5kZWxpbWl0ZXIgOiBkZWZhdWx0cy5kZWxpbWl0ZXIsXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1pbXBsaWNpdC1jb2VyY2lvbiwgbm8tZXh0cmEtcGFyZW5zXG4gICAgICAgIGRlcHRoOiAodHlwZW9mIG9wdHMuZGVwdGggPT09ICdudW1iZXInIHx8IG9wdHMuZGVwdGggPT09IGZhbHNlKSA/ICtvcHRzLmRlcHRoIDogZGVmYXVsdHMuZGVwdGgsXG4gICAgICAgIGlnbm9yZVF1ZXJ5UHJlZml4OiBvcHRzLmlnbm9yZVF1ZXJ5UHJlZml4ID09PSB0cnVlLFxuICAgICAgICBpbnRlcnByZXROdW1lcmljRW50aXRpZXM6IHR5cGVvZiBvcHRzLmludGVycHJldE51bWVyaWNFbnRpdGllcyA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5pbnRlcnByZXROdW1lcmljRW50aXRpZXMgOiBkZWZhdWx0cy5pbnRlcnByZXROdW1lcmljRW50aXRpZXMsXG4gICAgICAgIHBhcmFtZXRlckxpbWl0OiB0eXBlb2Ygb3B0cy5wYXJhbWV0ZXJMaW1pdCA9PT0gJ251bWJlcicgPyBvcHRzLnBhcmFtZXRlckxpbWl0IDogZGVmYXVsdHMucGFyYW1ldGVyTGltaXQsXG4gICAgICAgIHBhcnNlQXJyYXlzOiBvcHRzLnBhcnNlQXJyYXlzICE9PSBmYWxzZSxcbiAgICAgICAgcGxhaW5PYmplY3RzOiB0eXBlb2Ygb3B0cy5wbGFpbk9iamVjdHMgPT09ICdib29sZWFuJyA/IG9wdHMucGxhaW5PYmplY3RzIDogZGVmYXVsdHMucGxhaW5PYmplY3RzLFxuICAgICAgICBzdHJpY3ROdWxsSGFuZGxpbmc6IHR5cGVvZiBvcHRzLnN0cmljdE51bGxIYW5kbGluZyA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5zdHJpY3ROdWxsSGFuZGxpbmcgOiBkZWZhdWx0cy5zdHJpY3ROdWxsSGFuZGxpbmdcbiAgICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoc3RyLCBvcHRzKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBub3JtYWxpemVQYXJzZU9wdGlvbnMob3B0cyk7XG5cbiAgICBpZiAoc3RyID09PSAnJyB8fCBzdHIgPT09IG51bGwgfHwgdHlwZW9mIHN0ciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMucGxhaW5PYmplY3RzID8gT2JqZWN0LmNyZWF0ZShudWxsKSA6IHt9O1xuICAgIH1cblxuICAgIHZhciB0ZW1wT2JqID0gdHlwZW9mIHN0ciA9PT0gJ3N0cmluZycgPyBwYXJzZVZhbHVlcyhzdHIsIG9wdGlvbnMpIDogc3RyO1xuICAgIHZhciBvYmogPSBvcHRpb25zLnBsYWluT2JqZWN0cyA/IE9iamVjdC5jcmVhdGUobnVsbCkgOiB7fTtcblxuICAgIC8vIEl0ZXJhdGUgb3ZlciB0aGUga2V5cyBhbmQgc2V0dXAgdGhlIG5ldyBvYmplY3RcblxuICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXModGVtcE9iaik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgICAgICB2YXIgbmV3T2JqID0gcGFyc2VLZXlzKGtleSwgdGVtcE9ialtrZXldLCBvcHRpb25zLCB0eXBlb2Ygc3RyID09PSAnc3RyaW5nJyk7XG4gICAgICAgIG9iaiA9IHV0aWxzLm1lcmdlKG9iaiwgbmV3T2JqLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdXRpbHMuY29tcGFjdChvYmopO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGZvcm1hdHMgPSByZXF1aXJlKCcuL2Zvcm1hdHMnKTtcbnZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG52YXIgYXJyYXlQcmVmaXhHZW5lcmF0b3JzID0ge1xuICAgIGJyYWNrZXRzOiBmdW5jdGlvbiBicmFja2V0cyhwcmVmaXgpIHtcbiAgICAgICAgcmV0dXJuIHByZWZpeCArICdbXSc7XG4gICAgfSxcbiAgICBjb21tYTogJ2NvbW1hJyxcbiAgICBpbmRpY2VzOiBmdW5jdGlvbiBpbmRpY2VzKHByZWZpeCwga2V5KSB7XG4gICAgICAgIHJldHVybiBwcmVmaXggKyAnWycgKyBrZXkgKyAnXSc7XG4gICAgfSxcbiAgICByZXBlYXQ6IGZ1bmN0aW9uIHJlcGVhdChwcmVmaXgpIHtcbiAgICAgICAgcmV0dXJuIHByZWZpeDtcbiAgICB9XG59O1xuXG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG52YXIgcHVzaCA9IEFycmF5LnByb3RvdHlwZS5wdXNoO1xudmFyIHB1c2hUb0FycmF5ID0gZnVuY3Rpb24gKGFyciwgdmFsdWVPckFycmF5KSB7XG4gICAgcHVzaC5hcHBseShhcnIsIGlzQXJyYXkodmFsdWVPckFycmF5KSA/IHZhbHVlT3JBcnJheSA6IFt2YWx1ZU9yQXJyYXldKTtcbn07XG5cbnZhciB0b0lTTyA9IERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nO1xuXG52YXIgZGVmYXVsdEZvcm1hdCA9IGZvcm1hdHNbJ2RlZmF1bHQnXTtcbnZhciBkZWZhdWx0cyA9IHtcbiAgICBhZGRRdWVyeVByZWZpeDogZmFsc2UsXG4gICAgYWxsb3dEb3RzOiBmYWxzZSxcbiAgICBjaGFyc2V0OiAndXRmLTgnLFxuICAgIGNoYXJzZXRTZW50aW5lbDogZmFsc2UsXG4gICAgZGVsaW1pdGVyOiAnJicsXG4gICAgZW5jb2RlOiB0cnVlLFxuICAgIGVuY29kZXI6IHV0aWxzLmVuY29kZSxcbiAgICBlbmNvZGVWYWx1ZXNPbmx5OiBmYWxzZSxcbiAgICBmb3JtYXQ6IGRlZmF1bHRGb3JtYXQsXG4gICAgZm9ybWF0dGVyOiBmb3JtYXRzLmZvcm1hdHRlcnNbZGVmYXVsdEZvcm1hdF0sXG4gICAgLy8gZGVwcmVjYXRlZFxuICAgIGluZGljZXM6IGZhbHNlLFxuICAgIHNlcmlhbGl6ZURhdGU6IGZ1bmN0aW9uIHNlcmlhbGl6ZURhdGUoZGF0ZSkge1xuICAgICAgICByZXR1cm4gdG9JU08uY2FsbChkYXRlKTtcbiAgICB9LFxuICAgIHNraXBOdWxsczogZmFsc2UsXG4gICAgc3RyaWN0TnVsbEhhbmRsaW5nOiBmYWxzZVxufTtcblxudmFyIGlzTm9uTnVsbGlzaFByaW1pdGl2ZSA9IGZ1bmN0aW9uIGlzTm9uTnVsbGlzaFByaW1pdGl2ZSh2KSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2ID09PSAnc3RyaW5nJ1xuICAgICAgICB8fCB0eXBlb2YgdiA9PT0gJ251bWJlcidcbiAgICAgICAgfHwgdHlwZW9mIHYgPT09ICdib29sZWFuJ1xuICAgICAgICB8fCB0eXBlb2YgdiA9PT0gJ3N5bWJvbCdcbiAgICAgICAgfHwgdHlwZW9mIHYgPT09ICdiaWdpbnQnO1xufTtcblxudmFyIHN0cmluZ2lmeSA9IGZ1bmN0aW9uIHN0cmluZ2lmeShcbiAgICBvYmplY3QsXG4gICAgcHJlZml4LFxuICAgIGdlbmVyYXRlQXJyYXlQcmVmaXgsXG4gICAgc3RyaWN0TnVsbEhhbmRsaW5nLFxuICAgIHNraXBOdWxscyxcbiAgICBlbmNvZGVyLFxuICAgIGZpbHRlcixcbiAgICBzb3J0LFxuICAgIGFsbG93RG90cyxcbiAgICBzZXJpYWxpemVEYXRlLFxuICAgIGZvcm1hdHRlcixcbiAgICBlbmNvZGVWYWx1ZXNPbmx5LFxuICAgIGNoYXJzZXRcbikge1xuICAgIHZhciBvYmogPSBvYmplY3Q7XG4gICAgaWYgKHR5cGVvZiBmaWx0ZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgb2JqID0gZmlsdGVyKHByZWZpeCwgb2JqKTtcbiAgICB9IGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgb2JqID0gc2VyaWFsaXplRGF0ZShvYmopO1xuICAgIH0gZWxzZSBpZiAoZ2VuZXJhdGVBcnJheVByZWZpeCA9PT0gJ2NvbW1hJyAmJiBpc0FycmF5KG9iaikpIHtcbiAgICAgICAgb2JqID0gb2JqLmpvaW4oJywnKTtcbiAgICB9XG5cbiAgICBpZiAob2JqID09PSBudWxsKSB7XG4gICAgICAgIGlmIChzdHJpY3ROdWxsSGFuZGxpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiBlbmNvZGVyICYmICFlbmNvZGVWYWx1ZXNPbmx5ID8gZW5jb2RlcihwcmVmaXgsIGRlZmF1bHRzLmVuY29kZXIsIGNoYXJzZXQsICdrZXknKSA6IHByZWZpeDtcbiAgICAgICAgfVxuXG4gICAgICAgIG9iaiA9ICcnO1xuICAgIH1cblxuICAgIGlmIChpc05vbk51bGxpc2hQcmltaXRpdmUob2JqKSB8fCB1dGlscy5pc0J1ZmZlcihvYmopKSB7XG4gICAgICAgIGlmIChlbmNvZGVyKSB7XG4gICAgICAgICAgICB2YXIga2V5VmFsdWUgPSBlbmNvZGVWYWx1ZXNPbmx5ID8gcHJlZml4IDogZW5jb2RlcihwcmVmaXgsIGRlZmF1bHRzLmVuY29kZXIsIGNoYXJzZXQsICdrZXknKTtcbiAgICAgICAgICAgIHJldHVybiBbZm9ybWF0dGVyKGtleVZhbHVlKSArICc9JyArIGZvcm1hdHRlcihlbmNvZGVyKG9iaiwgZGVmYXVsdHMuZW5jb2RlciwgY2hhcnNldCwgJ3ZhbHVlJykpXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW2Zvcm1hdHRlcihwcmVmaXgpICsgJz0nICsgZm9ybWF0dGVyKFN0cmluZyhvYmopKV07XG4gICAgfVxuXG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfVxuXG4gICAgdmFyIG9iaktleXM7XG4gICAgaWYgKGlzQXJyYXkoZmlsdGVyKSkge1xuICAgICAgICBvYmpLZXlzID0gZmlsdGVyO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqKTtcbiAgICAgICAgb2JqS2V5cyA9IHNvcnQgPyBrZXlzLnNvcnQoc29ydCkgOiBrZXlzO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqS2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIga2V5ID0gb2JqS2V5c1tpXTtcblxuICAgICAgICBpZiAoc2tpcE51bGxzICYmIG9ialtrZXldID09PSBudWxsKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgICAgICAgIHB1c2hUb0FycmF5KHZhbHVlcywgc3RyaW5naWZ5KFxuICAgICAgICAgICAgICAgIG9ialtrZXldLFxuICAgICAgICAgICAgICAgIHR5cGVvZiBnZW5lcmF0ZUFycmF5UHJlZml4ID09PSAnZnVuY3Rpb24nID8gZ2VuZXJhdGVBcnJheVByZWZpeChwcmVmaXgsIGtleSkgOiBwcmVmaXgsXG4gICAgICAgICAgICAgICAgZ2VuZXJhdGVBcnJheVByZWZpeCxcbiAgICAgICAgICAgICAgICBzdHJpY3ROdWxsSGFuZGxpbmcsXG4gICAgICAgICAgICAgICAgc2tpcE51bGxzLFxuICAgICAgICAgICAgICAgIGVuY29kZXIsXG4gICAgICAgICAgICAgICAgZmlsdGVyLFxuICAgICAgICAgICAgICAgIHNvcnQsXG4gICAgICAgICAgICAgICAgYWxsb3dEb3RzLFxuICAgICAgICAgICAgICAgIHNlcmlhbGl6ZURhdGUsXG4gICAgICAgICAgICAgICAgZm9ybWF0dGVyLFxuICAgICAgICAgICAgICAgIGVuY29kZVZhbHVlc09ubHksXG4gICAgICAgICAgICAgICAgY2hhcnNldFxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwdXNoVG9BcnJheSh2YWx1ZXMsIHN0cmluZ2lmeShcbiAgICAgICAgICAgICAgICBvYmpba2V5XSxcbiAgICAgICAgICAgICAgICBwcmVmaXggKyAoYWxsb3dEb3RzID8gJy4nICsga2V5IDogJ1snICsga2V5ICsgJ10nKSxcbiAgICAgICAgICAgICAgICBnZW5lcmF0ZUFycmF5UHJlZml4LFxuICAgICAgICAgICAgICAgIHN0cmljdE51bGxIYW5kbGluZyxcbiAgICAgICAgICAgICAgICBza2lwTnVsbHMsXG4gICAgICAgICAgICAgICAgZW5jb2RlcixcbiAgICAgICAgICAgICAgICBmaWx0ZXIsXG4gICAgICAgICAgICAgICAgc29ydCxcbiAgICAgICAgICAgICAgICBhbGxvd0RvdHMsXG4gICAgICAgICAgICAgICAgc2VyaWFsaXplRGF0ZSxcbiAgICAgICAgICAgICAgICBmb3JtYXR0ZXIsXG4gICAgICAgICAgICAgICAgZW5jb2RlVmFsdWVzT25seSxcbiAgICAgICAgICAgICAgICBjaGFyc2V0XG4gICAgICAgICAgICApKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZXM7XG59O1xuXG52YXIgbm9ybWFsaXplU3RyaW5naWZ5T3B0aW9ucyA9IGZ1bmN0aW9uIG5vcm1hbGl6ZVN0cmluZ2lmeU9wdGlvbnMob3B0cykge1xuICAgIGlmICghb3B0cykge1xuICAgICAgICByZXR1cm4gZGVmYXVsdHM7XG4gICAgfVxuXG4gICAgaWYgKG9wdHMuZW5jb2RlciAhPT0gbnVsbCAmJiBvcHRzLmVuY29kZXIgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb3B0cy5lbmNvZGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0VuY29kZXIgaGFzIHRvIGJlIGEgZnVuY3Rpb24uJyk7XG4gICAgfVxuXG4gICAgdmFyIGNoYXJzZXQgPSBvcHRzLmNoYXJzZXQgfHwgZGVmYXVsdHMuY2hhcnNldDtcbiAgICBpZiAodHlwZW9mIG9wdHMuY2hhcnNldCAhPT0gJ3VuZGVmaW5lZCcgJiYgb3B0cy5jaGFyc2V0ICE9PSAndXRmLTgnICYmIG9wdHMuY2hhcnNldCAhPT0gJ2lzby04ODU5LTEnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBjaGFyc2V0IG9wdGlvbiBtdXN0IGJlIGVpdGhlciB1dGYtOCwgaXNvLTg4NTktMSwgb3IgdW5kZWZpbmVkJyk7XG4gICAgfVxuXG4gICAgdmFyIGZvcm1hdCA9IGZvcm1hdHNbJ2RlZmF1bHQnXTtcbiAgICBpZiAodHlwZW9mIG9wdHMuZm9ybWF0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBpZiAoIWhhcy5jYWxsKGZvcm1hdHMuZm9ybWF0dGVycywgb3B0cy5mb3JtYXQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGZvcm1hdCBvcHRpb24gcHJvdmlkZWQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgZm9ybWF0ID0gb3B0cy5mb3JtYXQ7XG4gICAgfVxuICAgIHZhciBmb3JtYXR0ZXIgPSBmb3JtYXRzLmZvcm1hdHRlcnNbZm9ybWF0XTtcblxuICAgIHZhciBmaWx0ZXIgPSBkZWZhdWx0cy5maWx0ZXI7XG4gICAgaWYgKHR5cGVvZiBvcHRzLmZpbHRlciA9PT0gJ2Z1bmN0aW9uJyB8fCBpc0FycmF5KG9wdHMuZmlsdGVyKSkge1xuICAgICAgICBmaWx0ZXIgPSBvcHRzLmZpbHRlcjtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBhZGRRdWVyeVByZWZpeDogdHlwZW9mIG9wdHMuYWRkUXVlcnlQcmVmaXggPT09ICdib29sZWFuJyA/IG9wdHMuYWRkUXVlcnlQcmVmaXggOiBkZWZhdWx0cy5hZGRRdWVyeVByZWZpeCxcbiAgICAgICAgYWxsb3dEb3RzOiB0eXBlb2Ygb3B0cy5hbGxvd0RvdHMgPT09ICd1bmRlZmluZWQnID8gZGVmYXVsdHMuYWxsb3dEb3RzIDogISFvcHRzLmFsbG93RG90cyxcbiAgICAgICAgY2hhcnNldDogY2hhcnNldCxcbiAgICAgICAgY2hhcnNldFNlbnRpbmVsOiB0eXBlb2Ygb3B0cy5jaGFyc2V0U2VudGluZWwgPT09ICdib29sZWFuJyA/IG9wdHMuY2hhcnNldFNlbnRpbmVsIDogZGVmYXVsdHMuY2hhcnNldFNlbnRpbmVsLFxuICAgICAgICBkZWxpbWl0ZXI6IHR5cGVvZiBvcHRzLmRlbGltaXRlciA9PT0gJ3VuZGVmaW5lZCcgPyBkZWZhdWx0cy5kZWxpbWl0ZXIgOiBvcHRzLmRlbGltaXRlcixcbiAgICAgICAgZW5jb2RlOiB0eXBlb2Ygb3B0cy5lbmNvZGUgPT09ICdib29sZWFuJyA/IG9wdHMuZW5jb2RlIDogZGVmYXVsdHMuZW5jb2RlLFxuICAgICAgICBlbmNvZGVyOiB0eXBlb2Ygb3B0cy5lbmNvZGVyID09PSAnZnVuY3Rpb24nID8gb3B0cy5lbmNvZGVyIDogZGVmYXVsdHMuZW5jb2RlcixcbiAgICAgICAgZW5jb2RlVmFsdWVzT25seTogdHlwZW9mIG9wdHMuZW5jb2RlVmFsdWVzT25seSA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5lbmNvZGVWYWx1ZXNPbmx5IDogZGVmYXVsdHMuZW5jb2RlVmFsdWVzT25seSxcbiAgICAgICAgZmlsdGVyOiBmaWx0ZXIsXG4gICAgICAgIGZvcm1hdHRlcjogZm9ybWF0dGVyLFxuICAgICAgICBzZXJpYWxpemVEYXRlOiB0eXBlb2Ygb3B0cy5zZXJpYWxpemVEYXRlID09PSAnZnVuY3Rpb24nID8gb3B0cy5zZXJpYWxpemVEYXRlIDogZGVmYXVsdHMuc2VyaWFsaXplRGF0ZSxcbiAgICAgICAgc2tpcE51bGxzOiB0eXBlb2Ygb3B0cy5za2lwTnVsbHMgPT09ICdib29sZWFuJyA/IG9wdHMuc2tpcE51bGxzIDogZGVmYXVsdHMuc2tpcE51bGxzLFxuICAgICAgICBzb3J0OiB0eXBlb2Ygb3B0cy5zb3J0ID09PSAnZnVuY3Rpb24nID8gb3B0cy5zb3J0IDogbnVsbCxcbiAgICAgICAgc3RyaWN0TnVsbEhhbmRsaW5nOiB0eXBlb2Ygb3B0cy5zdHJpY3ROdWxsSGFuZGxpbmcgPT09ICdib29sZWFuJyA/IG9wdHMuc3RyaWN0TnVsbEhhbmRsaW5nIDogZGVmYXVsdHMuc3RyaWN0TnVsbEhhbmRsaW5nXG4gICAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9iamVjdCwgb3B0cykge1xuICAgIHZhciBvYmogPSBvYmplY3Q7XG4gICAgdmFyIG9wdGlvbnMgPSBub3JtYWxpemVTdHJpbmdpZnlPcHRpb25zKG9wdHMpO1xuXG4gICAgdmFyIG9iaktleXM7XG4gICAgdmFyIGZpbHRlcjtcblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5maWx0ZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgZmlsdGVyID0gb3B0aW9ucy5maWx0ZXI7XG4gICAgICAgIG9iaiA9IGZpbHRlcignJywgb2JqKTtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkob3B0aW9ucy5maWx0ZXIpKSB7XG4gICAgICAgIGZpbHRlciA9IG9wdGlvbnMuZmlsdGVyO1xuICAgICAgICBvYmpLZXlzID0gZmlsdGVyO1xuICAgIH1cblxuICAgIHZhciBrZXlzID0gW107XG5cbiAgICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgb2JqID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICB2YXIgYXJyYXlGb3JtYXQ7XG4gICAgaWYgKG9wdHMgJiYgb3B0cy5hcnJheUZvcm1hdCBpbiBhcnJheVByZWZpeEdlbmVyYXRvcnMpIHtcbiAgICAgICAgYXJyYXlGb3JtYXQgPSBvcHRzLmFycmF5Rm9ybWF0O1xuICAgIH0gZWxzZSBpZiAob3B0cyAmJiAnaW5kaWNlcycgaW4gb3B0cykge1xuICAgICAgICBhcnJheUZvcm1hdCA9IG9wdHMuaW5kaWNlcyA/ICdpbmRpY2VzJyA6ICdyZXBlYXQnO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGFycmF5Rm9ybWF0ID0gJ2luZGljZXMnO1xuICAgIH1cblxuICAgIHZhciBnZW5lcmF0ZUFycmF5UHJlZml4ID0gYXJyYXlQcmVmaXhHZW5lcmF0b3JzW2FycmF5Rm9ybWF0XTtcblxuICAgIGlmICghb2JqS2V5cykge1xuICAgICAgICBvYmpLZXlzID0gT2JqZWN0LmtleXMob2JqKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5zb3J0KSB7XG4gICAgICAgIG9iaktleXMuc29ydChvcHRpb25zLnNvcnQpO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqS2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIga2V5ID0gb2JqS2V5c1tpXTtcblxuICAgICAgICBpZiAob3B0aW9ucy5za2lwTnVsbHMgJiYgb2JqW2tleV0gPT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHB1c2hUb0FycmF5KGtleXMsIHN0cmluZ2lmeShcbiAgICAgICAgICAgIG9ialtrZXldLFxuICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgZ2VuZXJhdGVBcnJheVByZWZpeCxcbiAgICAgICAgICAgIG9wdGlvbnMuc3RyaWN0TnVsbEhhbmRsaW5nLFxuICAgICAgICAgICAgb3B0aW9ucy5za2lwTnVsbHMsXG4gICAgICAgICAgICBvcHRpb25zLmVuY29kZSA/IG9wdGlvbnMuZW5jb2RlciA6IG51bGwsXG4gICAgICAgICAgICBvcHRpb25zLmZpbHRlcixcbiAgICAgICAgICAgIG9wdGlvbnMuc29ydCxcbiAgICAgICAgICAgIG9wdGlvbnMuYWxsb3dEb3RzLFxuICAgICAgICAgICAgb3B0aW9ucy5zZXJpYWxpemVEYXRlLFxuICAgICAgICAgICAgb3B0aW9ucy5mb3JtYXR0ZXIsXG4gICAgICAgICAgICBvcHRpb25zLmVuY29kZVZhbHVlc09ubHksXG4gICAgICAgICAgICBvcHRpb25zLmNoYXJzZXRcbiAgICAgICAgKSk7XG4gICAgfVxuXG4gICAgdmFyIGpvaW5lZCA9IGtleXMuam9pbihvcHRpb25zLmRlbGltaXRlcik7XG4gICAgdmFyIHByZWZpeCA9IG9wdGlvbnMuYWRkUXVlcnlQcmVmaXggPT09IHRydWUgPyAnPycgOiAnJztcblxuICAgIGlmIChvcHRpb25zLmNoYXJzZXRTZW50aW5lbCkge1xuICAgICAgICBpZiAob3B0aW9ucy5jaGFyc2V0ID09PSAnaXNvLTg4NTktMScpIHtcbiAgICAgICAgICAgIC8vIGVuY29kZVVSSUNvbXBvbmVudCgnJiMxMDAwMzsnKSwgdGhlIFwibnVtZXJpYyBlbnRpdHlcIiByZXByZXNlbnRhdGlvbiBvZiBhIGNoZWNrbWFya1xuICAgICAgICAgICAgcHJlZml4ICs9ICd1dGY4PSUyNiUyMzEwMDAzJTNCJic7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBlbmNvZGVVUklDb21wb25lbnQoJ+KckycpXG4gICAgICAgICAgICBwcmVmaXggKz0gJ3V0Zjg9JUUyJTlDJTkzJic7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gam9pbmVkLmxlbmd0aCA+IDAgPyBwcmVmaXggKyBqb2luZWQgOiAnJztcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuXG52YXIgaGV4VGFibGUgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcnJheSA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyArK2kpIHtcbiAgICAgICAgYXJyYXkucHVzaCgnJScgKyAoKGkgPCAxNiA/ICcwJyA6ICcnKSArIGkudG9TdHJpbmcoMTYpKS50b1VwcGVyQ2FzZSgpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXJyYXk7XG59KCkpO1xuXG52YXIgY29tcGFjdFF1ZXVlID0gZnVuY3Rpb24gY29tcGFjdFF1ZXVlKHF1ZXVlKSB7XG4gICAgd2hpbGUgKHF1ZXVlLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgdmFyIGl0ZW0gPSBxdWV1ZS5wb3AoKTtcbiAgICAgICAgdmFyIG9iaiA9IGl0ZW0ub2JqW2l0ZW0ucHJvcF07XG5cbiAgICAgICAgaWYgKGlzQXJyYXkob2JqKSkge1xuICAgICAgICAgICAgdmFyIGNvbXBhY3RlZCA9IFtdO1xuXG4gICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG9iai5sZW5ndGg7ICsraikge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqW2pdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICBjb21wYWN0ZWQucHVzaChvYmpbal0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaXRlbS5vYmpbaXRlbS5wcm9wXSA9IGNvbXBhY3RlZDtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbnZhciBhcnJheVRvT2JqZWN0ID0gZnVuY3Rpb24gYXJyYXlUb09iamVjdChzb3VyY2UsIG9wdGlvbnMpIHtcbiAgICB2YXIgb2JqID0gb3B0aW9ucyAmJiBvcHRpb25zLnBsYWluT2JqZWN0cyA/IE9iamVjdC5jcmVhdGUobnVsbCkgOiB7fTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNvdXJjZS5sZW5ndGg7ICsraSkge1xuICAgICAgICBpZiAodHlwZW9mIHNvdXJjZVtpXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIG9ialtpXSA9IHNvdXJjZVtpXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvYmo7XG59O1xuXG52YXIgbWVyZ2UgPSBmdW5jdGlvbiBtZXJnZSh0YXJnZXQsIHNvdXJjZSwgb3B0aW9ucykge1xuICAgIC8qIGVzbGludCBuby1wYXJhbS1yZWFzc2lnbjogMCAqL1xuICAgIGlmICghc291cmNlKSB7XG4gICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBzb3VyY2UgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmIChpc0FycmF5KHRhcmdldCkpIHtcbiAgICAgICAgICAgIHRhcmdldC5wdXNoKHNvdXJjZSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0ICYmIHR5cGVvZiB0YXJnZXQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBpZiAoKG9wdGlvbnMgJiYgKG9wdGlvbnMucGxhaW5PYmplY3RzIHx8IG9wdGlvbnMuYWxsb3dQcm90b3R5cGVzKSkgfHwgIWhhcy5jYWxsKE9iamVjdC5wcm90b3R5cGUsIHNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICB0YXJnZXRbc291cmNlXSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gW3RhcmdldCwgc291cmNlXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuXG4gICAgaWYgKCF0YXJnZXQgfHwgdHlwZW9mIHRhcmdldCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIFt0YXJnZXRdLmNvbmNhdChzb3VyY2UpO1xuICAgIH1cblxuICAgIHZhciBtZXJnZVRhcmdldCA9IHRhcmdldDtcbiAgICBpZiAoaXNBcnJheSh0YXJnZXQpICYmICFpc0FycmF5KHNvdXJjZSkpIHtcbiAgICAgICAgbWVyZ2VUYXJnZXQgPSBhcnJheVRvT2JqZWN0KHRhcmdldCwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgaWYgKGlzQXJyYXkodGFyZ2V0KSAmJiBpc0FycmF5KHNvdXJjZSkpIHtcbiAgICAgICAgc291cmNlLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0sIGkpIHtcbiAgICAgICAgICAgIGlmIChoYXMuY2FsbCh0YXJnZXQsIGkpKSB7XG4gICAgICAgICAgICAgICAgdmFyIHRhcmdldEl0ZW0gPSB0YXJnZXRbaV07XG4gICAgICAgICAgICAgICAgaWYgKHRhcmdldEl0ZW0gJiYgdHlwZW9mIHRhcmdldEl0ZW0gPT09ICdvYmplY3QnICYmIGl0ZW0gJiYgdHlwZW9mIGl0ZW0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldFtpXSA9IG1lcmdlKHRhcmdldEl0ZW0sIGl0ZW0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldC5wdXNoKGl0ZW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0W2ldID0gaXRlbTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHNvdXJjZSkucmVkdWNlKGZ1bmN0aW9uIChhY2MsIGtleSkge1xuICAgICAgICB2YXIgdmFsdWUgPSBzb3VyY2Vba2V5XTtcblxuICAgICAgICBpZiAoaGFzLmNhbGwoYWNjLCBrZXkpKSB7XG4gICAgICAgICAgICBhY2Nba2V5XSA9IG1lcmdlKGFjY1trZXldLCB2YWx1ZSwgb3B0aW9ucyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhY2Nba2V5XSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgbWVyZ2VUYXJnZXQpO1xufTtcblxudmFyIGFzc2lnbiA9IGZ1bmN0aW9uIGFzc2lnblNpbmdsZVNvdXJjZSh0YXJnZXQsIHNvdXJjZSkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhzb3VyY2UpLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBrZXkpIHtcbiAgICAgICAgYWNjW2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB0YXJnZXQpO1xufTtcblxudmFyIGRlY29kZSA9IGZ1bmN0aW9uIChzdHIsIGRlY29kZXIsIGNoYXJzZXQpIHtcbiAgICB2YXIgc3RyV2l0aG91dFBsdXMgPSBzdHIucmVwbGFjZSgvXFwrL2csICcgJyk7XG4gICAgaWYgKGNoYXJzZXQgPT09ICdpc28tODg1OS0xJykge1xuICAgICAgICAvLyB1bmVzY2FwZSBuZXZlciB0aHJvd3MsIG5vIHRyeS4uLmNhdGNoIG5lZWRlZDpcbiAgICAgICAgcmV0dXJuIHN0cldpdGhvdXRQbHVzLnJlcGxhY2UoLyVbMC05YS1mXXsyfS9naSwgdW5lc2NhcGUpO1xuICAgIH1cbiAgICAvLyB1dGYtOFxuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoc3RyV2l0aG91dFBsdXMpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIHN0cldpdGhvdXRQbHVzO1xuICAgIH1cbn07XG5cbnZhciBlbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUoc3RyLCBkZWZhdWx0RW5jb2RlciwgY2hhcnNldCkge1xuICAgIC8vIFRoaXMgY29kZSB3YXMgb3JpZ2luYWxseSB3cml0dGVuIGJ5IEJyaWFuIFdoaXRlIChtc2NkZXgpIGZvciB0aGUgaW8uanMgY29yZSBxdWVyeXN0cmluZyBsaWJyYXJ5LlxuICAgIC8vIEl0IGhhcyBiZWVuIGFkYXB0ZWQgaGVyZSBmb3Igc3RyaWN0ZXIgYWRoZXJlbmNlIHRvIFJGQyAzOTg2XG4gICAgaWYgKHN0ci5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG5cbiAgICB2YXIgc3RyaW5nID0gc3RyO1xuICAgIGlmICh0eXBlb2Ygc3RyID09PSAnc3ltYm9sJykge1xuICAgICAgICBzdHJpbmcgPSBTeW1ib2wucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3RyKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzdHIgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHN0cmluZyA9IFN0cmluZyhzdHIpO1xuICAgIH1cblxuICAgIGlmIChjaGFyc2V0ID09PSAnaXNvLTg4NTktMScpIHtcbiAgICAgICAgcmV0dXJuIGVzY2FwZShzdHJpbmcpLnJlcGxhY2UoLyV1WzAtOWEtZl17NH0vZ2ksIGZ1bmN0aW9uICgkMCkge1xuICAgICAgICAgICAgcmV0dXJuICclMjYlMjMnICsgcGFyc2VJbnQoJDAuc2xpY2UoMiksIDE2KSArICclM0InO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB2YXIgb3V0ID0gJyc7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHJpbmcubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGMgPSBzdHJpbmcuY2hhckNvZGVBdChpKTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICBjID09PSAweDJEIC8vIC1cbiAgICAgICAgICAgIHx8IGMgPT09IDB4MkUgLy8gLlxuICAgICAgICAgICAgfHwgYyA9PT0gMHg1RiAvLyBfXG4gICAgICAgICAgICB8fCBjID09PSAweDdFIC8vIH5cbiAgICAgICAgICAgIHx8IChjID49IDB4MzAgJiYgYyA8PSAweDM5KSAvLyAwLTlcbiAgICAgICAgICAgIHx8IChjID49IDB4NDEgJiYgYyA8PSAweDVBKSAvLyBhLXpcbiAgICAgICAgICAgIHx8IChjID49IDB4NjEgJiYgYyA8PSAweDdBKSAvLyBBLVpcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBvdXQgKz0gc3RyaW5nLmNoYXJBdChpKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGMgPCAweDgwKSB7XG4gICAgICAgICAgICBvdXQgPSBvdXQgKyBoZXhUYWJsZVtjXTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGMgPCAweDgwMCkge1xuICAgICAgICAgICAgb3V0ID0gb3V0ICsgKGhleFRhYmxlWzB4QzAgfCAoYyA+PiA2KV0gKyBoZXhUYWJsZVsweDgwIHwgKGMgJiAweDNGKV0pO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYyA8IDB4RDgwMCB8fCBjID49IDB4RTAwMCkge1xuICAgICAgICAgICAgb3V0ID0gb3V0ICsgKGhleFRhYmxlWzB4RTAgfCAoYyA+PiAxMildICsgaGV4VGFibGVbMHg4MCB8ICgoYyA+PiA2KSAmIDB4M0YpXSArIGhleFRhYmxlWzB4ODAgfCAoYyAmIDB4M0YpXSk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGkgKz0gMTtcbiAgICAgICAgYyA9IDB4MTAwMDAgKyAoKChjICYgMHgzRkYpIDw8IDEwKSB8IChzdHJpbmcuY2hhckNvZGVBdChpKSAmIDB4M0ZGKSk7XG4gICAgICAgIG91dCArPSBoZXhUYWJsZVsweEYwIHwgKGMgPj4gMTgpXVxuICAgICAgICAgICAgKyBoZXhUYWJsZVsweDgwIHwgKChjID4+IDEyKSAmIDB4M0YpXVxuICAgICAgICAgICAgKyBoZXhUYWJsZVsweDgwIHwgKChjID4+IDYpICYgMHgzRildXG4gICAgICAgICAgICArIGhleFRhYmxlWzB4ODAgfCAoYyAmIDB4M0YpXTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0O1xufTtcblxudmFyIGNvbXBhY3QgPSBmdW5jdGlvbiBjb21wYWN0KHZhbHVlKSB7XG4gICAgdmFyIHF1ZXVlID0gW3sgb2JqOiB7IG86IHZhbHVlIH0sIHByb3A6ICdvJyB9XTtcbiAgICB2YXIgcmVmcyA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBxdWV1ZS5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgaXRlbSA9IHF1ZXVlW2ldO1xuICAgICAgICB2YXIgb2JqID0gaXRlbS5vYmpbaXRlbS5wcm9wXTtcblxuICAgICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iaik7XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwga2V5cy5sZW5ndGg7ICsraikge1xuICAgICAgICAgICAgdmFyIGtleSA9IGtleXNbal07XG4gICAgICAgICAgICB2YXIgdmFsID0gb2JqW2tleV07XG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ29iamVjdCcgJiYgdmFsICE9PSBudWxsICYmIHJlZnMuaW5kZXhPZih2YWwpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIHF1ZXVlLnB1c2goeyBvYmo6IG9iaiwgcHJvcDoga2V5IH0pO1xuICAgICAgICAgICAgICAgIHJlZnMucHVzaCh2YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29tcGFjdFF1ZXVlKHF1ZXVlKTtcblxuICAgIHJldHVybiB2YWx1ZTtcbn07XG5cbnZhciBpc1JlZ0V4cCA9IGZ1bmN0aW9uIGlzUmVnRXhwKG9iaikge1xuICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59O1xuXG52YXIgaXNCdWZmZXIgPSBmdW5jdGlvbiBpc0J1ZmZlcihvYmopIHtcbiAgICBpZiAoIW9iaiB8fCB0eXBlb2Ygb2JqICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuICEhKG9iai5jb25zdHJ1Y3RvciAmJiBvYmouY29uc3RydWN0b3IuaXNCdWZmZXIgJiYgb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyKG9iaikpO1xufTtcblxudmFyIGNvbWJpbmUgPSBmdW5jdGlvbiBjb21iaW5lKGEsIGIpIHtcbiAgICByZXR1cm4gW10uY29uY2F0KGEsIGIpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgYXJyYXlUb09iamVjdDogYXJyYXlUb09iamVjdCxcbiAgICBhc3NpZ246IGFzc2lnbixcbiAgICBjb21iaW5lOiBjb21iaW5lLFxuICAgIGNvbXBhY3Q6IGNvbXBhY3QsXG4gICAgZGVjb2RlOiBkZWNvZGUsXG4gICAgZW5jb2RlOiBlbmNvZGUsXG4gICAgaXNCdWZmZXI6IGlzQnVmZmVyLFxuICAgIGlzUmVnRXhwOiBpc1JlZ0V4cCxcbiAgICBtZXJnZTogbWVyZ2Vcbn07XG4iLCIvKiEgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbkNvcHlyaWdodCAoQykgTWljcm9zb2Z0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlXG50aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZVxuTGljZW5zZSBhdCBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVEhJUyBDT0RFIElTIFBST1ZJREVEIE9OIEFOICpBUyBJUyogQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxuS0lORCwgRUlUSEVSIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIFdJVEhPVVQgTElNSVRBVElPTiBBTlkgSU1QTElFRFxuV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIFRJVExFLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSxcbk1FUkNIQU5UQUJMSVRZIE9SIE5PTi1JTkZSSU5HRU1FTlQuXG5cblNlZSB0aGUgQXBhY2hlIFZlcnNpb24gMi4wIExpY2Vuc2UgZm9yIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9uc1xuYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cbnZhciBSZWZsZWN0O1xuKGZ1bmN0aW9uIChSZWZsZWN0KSB7XG4gICAgLy8gTWV0YWRhdGEgUHJvcG9zYWxcbiAgICAvLyBodHRwczovL3JidWNrdG9uLmdpdGh1Yi5pby9yZWZsZWN0LW1ldGFkYXRhL1xuICAgIChmdW5jdGlvbiAoZmFjdG9yeSkge1xuICAgICAgICB2YXIgcm9vdCA9IHR5cGVvZiBnbG9iYWwgPT09IFwib2JqZWN0XCIgPyBnbG9iYWwgOlxuICAgICAgICAgICAgdHlwZW9mIHNlbGYgPT09IFwib2JqZWN0XCIgPyBzZWxmIDpcbiAgICAgICAgICAgICAgICB0eXBlb2YgdGhpcyA9PT0gXCJvYmplY3RcIiA/IHRoaXMgOlxuICAgICAgICAgICAgICAgICAgICBGdW5jdGlvbihcInJldHVybiB0aGlzO1wiKSgpO1xuICAgICAgICB2YXIgZXhwb3J0ZXIgPSBtYWtlRXhwb3J0ZXIoUmVmbGVjdCk7XG4gICAgICAgIGlmICh0eXBlb2Ygcm9vdC5SZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICByb290LlJlZmxlY3QgPSBSZWZsZWN0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZXhwb3J0ZXIgPSBtYWtlRXhwb3J0ZXIocm9vdC5SZWZsZWN0LCBleHBvcnRlcik7XG4gICAgICAgIH1cbiAgICAgICAgZmFjdG9yeShleHBvcnRlcik7XG4gICAgICAgIGZ1bmN0aW9uIG1ha2VFeHBvcnRlcih0YXJnZXQsIHByZXZpb3VzKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHRhcmdldFtrZXldICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCB7IGNvbmZpZ3VyYWJsZTogdHJ1ZSwgd3JpdGFibGU6IHRydWUsIHZhbHVlOiB2YWx1ZSB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHByZXZpb3VzKVxuICAgICAgICAgICAgICAgICAgICBwcmV2aW91cyhrZXksIHZhbHVlKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9KShmdW5jdGlvbiAoZXhwb3J0ZXIpIHtcbiAgICAgICAgdmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG4gICAgICAgIC8vIGZlYXR1cmUgdGVzdCBmb3IgU3ltYm9sIHN1cHBvcnRcbiAgICAgICAgdmFyIHN1cHBvcnRzU3ltYm9sID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiO1xuICAgICAgICB2YXIgdG9QcmltaXRpdmVTeW1ib2wgPSBzdXBwb3J0c1N5bWJvbCAmJiB0eXBlb2YgU3ltYm9sLnRvUHJpbWl0aXZlICE9PSBcInVuZGVmaW5lZFwiID8gU3ltYm9sLnRvUHJpbWl0aXZlIDogXCJAQHRvUHJpbWl0aXZlXCI7XG4gICAgICAgIHZhciBpdGVyYXRvclN5bWJvbCA9IHN1cHBvcnRzU3ltYm9sICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgIT09IFwidW5kZWZpbmVkXCIgPyBTeW1ib2wuaXRlcmF0b3IgOiBcIkBAaXRlcmF0b3JcIjtcbiAgICAgICAgdmFyIHN1cHBvcnRzQ3JlYXRlID0gdHlwZW9mIE9iamVjdC5jcmVhdGUgPT09IFwiZnVuY3Rpb25cIjsgLy8gZmVhdHVyZSB0ZXN0IGZvciBPYmplY3QuY3JlYXRlIHN1cHBvcnRcbiAgICAgICAgdmFyIHN1cHBvcnRzUHJvdG8gPSB7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5OyAvLyBmZWF0dXJlIHRlc3QgZm9yIF9fcHJvdG9fXyBzdXBwb3J0XG4gICAgICAgIHZhciBkb3duTGV2ZWwgPSAhc3VwcG9ydHNDcmVhdGUgJiYgIXN1cHBvcnRzUHJvdG87XG4gICAgICAgIHZhciBIYXNoTWFwID0ge1xuICAgICAgICAgICAgLy8gY3JlYXRlIGFuIG9iamVjdCBpbiBkaWN0aW9uYXJ5IG1vZGUgKGEuay5hLiBcInNsb3dcIiBtb2RlIGluIHY4KVxuICAgICAgICAgICAgY3JlYXRlOiBzdXBwb3J0c0NyZWF0ZVxuICAgICAgICAgICAgICAgID8gZnVuY3Rpb24gKCkgeyByZXR1cm4gTWFrZURpY3Rpb25hcnkoT2JqZWN0LmNyZWF0ZShudWxsKSk7IH1cbiAgICAgICAgICAgICAgICA6IHN1cHBvcnRzUHJvdG9cbiAgICAgICAgICAgICAgICAgICAgPyBmdW5jdGlvbiAoKSB7IHJldHVybiBNYWtlRGljdGlvbmFyeSh7IF9fcHJvdG9fXzogbnVsbCB9KTsgfVxuICAgICAgICAgICAgICAgICAgICA6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIE1ha2VEaWN0aW9uYXJ5KHt9KTsgfSxcbiAgICAgICAgICAgIGhhczogZG93bkxldmVsXG4gICAgICAgICAgICAgICAgPyBmdW5jdGlvbiAobWFwLCBrZXkpIHsgcmV0dXJuIGhhc093bi5jYWxsKG1hcCwga2V5KTsgfVxuICAgICAgICAgICAgICAgIDogZnVuY3Rpb24gKG1hcCwga2V5KSB7IHJldHVybiBrZXkgaW4gbWFwOyB9LFxuICAgICAgICAgICAgZ2V0OiBkb3duTGV2ZWxcbiAgICAgICAgICAgICAgICA/IGZ1bmN0aW9uIChtYXAsIGtleSkgeyByZXR1cm4gaGFzT3duLmNhbGwobWFwLCBrZXkpID8gbWFwW2tleV0gOiB1bmRlZmluZWQ7IH1cbiAgICAgICAgICAgICAgICA6IGZ1bmN0aW9uIChtYXAsIGtleSkgeyByZXR1cm4gbWFwW2tleV07IH0sXG4gICAgICAgIH07XG4gICAgICAgIC8vIExvYWQgZ2xvYmFsIG9yIHNoaW0gdmVyc2lvbnMgb2YgTWFwLCBTZXQsIGFuZCBXZWFrTWFwXG4gICAgICAgIHZhciBmdW5jdGlvblByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihGdW5jdGlvbik7XG4gICAgICAgIHZhciB1c2VQb2x5ZmlsbCA9IHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHByb2Nlc3MuZW52ICYmIHByb2Nlc3MuZW52W1wiUkVGTEVDVF9NRVRBREFUQV9VU0VfTUFQX1BPTFlGSUxMXCJdID09PSBcInRydWVcIjtcbiAgICAgICAgdmFyIF9NYXAgPSAhdXNlUG9seWZpbGwgJiYgdHlwZW9mIE1hcCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBNYXAucHJvdG90eXBlLmVudHJpZXMgPT09IFwiZnVuY3Rpb25cIiA/IE1hcCA6IENyZWF0ZU1hcFBvbHlmaWxsKCk7XG4gICAgICAgIHZhciBfU2V0ID0gIXVzZVBvbHlmaWxsICYmIHR5cGVvZiBTZXQgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU2V0LnByb3RvdHlwZS5lbnRyaWVzID09PSBcImZ1bmN0aW9uXCIgPyBTZXQgOiBDcmVhdGVTZXRQb2x5ZmlsbCgpO1xuICAgICAgICB2YXIgX1dlYWtNYXAgPSAhdXNlUG9seWZpbGwgJiYgdHlwZW9mIFdlYWtNYXAgPT09IFwiZnVuY3Rpb25cIiA/IFdlYWtNYXAgOiBDcmVhdGVXZWFrTWFwUG9seWZpbGwoKTtcbiAgICAgICAgLy8gW1tNZXRhZGF0YV1dIGludGVybmFsIHNsb3RcbiAgICAgICAgLy8gaHR0cHM6Ly9yYnVja3Rvbi5naXRodWIuaW8vcmVmbGVjdC1tZXRhZGF0YS8jb3JkaW5hcnktb2JqZWN0LWludGVybmFsLW1ldGhvZHMtYW5kLWludGVybmFsLXNsb3RzXG4gICAgICAgIHZhciBNZXRhZGF0YSA9IG5ldyBfV2Vha01hcCgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogQXBwbGllcyBhIHNldCBvZiBkZWNvcmF0b3JzIHRvIGEgcHJvcGVydHkgb2YgYSB0YXJnZXQgb2JqZWN0LlxuICAgICAgICAgKiBAcGFyYW0gZGVjb3JhdG9ycyBBbiBhcnJheSBvZiBkZWNvcmF0b3JzLlxuICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQgb2JqZWN0LlxuICAgICAgICAgKiBAcGFyYW0gcHJvcGVydHlLZXkgKE9wdGlvbmFsKSBUaGUgcHJvcGVydHkga2V5IHRvIGRlY29yYXRlLlxuICAgICAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyAoT3B0aW9uYWwpIFRoZSBwcm9wZXJ0eSBkZXNjcmlwdG9yIGZvciB0aGUgdGFyZ2V0IGtleS5cbiAgICAgICAgICogQHJlbWFya3MgRGVjb3JhdG9ycyBhcmUgYXBwbGllZCBpbiByZXZlcnNlIG9yZGVyLlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHkgZGVjbGFyYXRpb25zIGFyZSBub3QgcGFydCBvZiBFUzYsIHRob3VnaCB0aGV5IGFyZSB2YWxpZCBpbiBUeXBlU2NyaXB0OlxuICAgICAgICAgKiAgICAgICAgIC8vIHN0YXRpYyBzdGF0aWNQcm9wZXJ0eTtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgICAgICBjb25zdHJ1Y3RvcihwKSB7IH1cbiAgICAgICAgICogICAgICAgICBzdGF0aWMgc3RhdGljTWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIG1ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIGNvbnN0cnVjdG9yXG4gICAgICAgICAqICAgICBFeGFtcGxlID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzQXJyYXksIEV4YW1wbGUpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzQXJyYXksIEV4YW1wbGUsIFwic3RhdGljUHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzQXJyYXksIEV4YW1wbGUucHJvdG90eXBlLCBcInByb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShFeGFtcGxlLCBcInN0YXRpY01ldGhvZFwiLFxuICAgICAgICAgKiAgICAgICAgIFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9yc0FycmF5LCBFeGFtcGxlLCBcInN0YXRpY01ldGhvZFwiLFxuICAgICAgICAgKiAgICAgICAgICAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKEV4YW1wbGUsIFwic3RhdGljTWV0aG9kXCIpKSk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShFeGFtcGxlLnByb3RvdHlwZSwgXCJtZXRob2RcIixcbiAgICAgICAgICogICAgICAgICBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnNBcnJheSwgRXhhbXBsZS5wcm90b3R5cGUsIFwibWV0aG9kXCIsXG4gICAgICAgICAqICAgICAgICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoRXhhbXBsZS5wcm90b3R5cGUsIFwibWV0aG9kXCIpKSk7XG4gICAgICAgICAqXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBkZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIHByb3BlcnR5S2V5LCBhdHRyaWJ1dGVzKSB7XG4gICAgICAgICAgICBpZiAoIUlzVW5kZWZpbmVkKHByb3BlcnR5S2V5KSkge1xuICAgICAgICAgICAgICAgIGlmICghSXNBcnJheShkZWNvcmF0b3JzKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIGlmICghSXNPYmplY3QodGFyZ2V0KSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIGlmICghSXNPYmplY3QoYXR0cmlidXRlcykgJiYgIUlzVW5kZWZpbmVkKGF0dHJpYnV0ZXMpICYmICFJc051bGwoYXR0cmlidXRlcykpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICBpZiAoSXNOdWxsKGF0dHJpYnV0ZXMpKVxuICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIHByb3BlcnR5S2V5ID0gVG9Qcm9wZXJ0eUtleShwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIERlY29yYXRlUHJvcGVydHkoZGVjb3JhdG9ycywgdGFyZ2V0LCBwcm9wZXJ0eUtleSwgYXR0cmlidXRlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoIUlzQXJyYXkoZGVjb3JhdG9ycykpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICBpZiAoIUlzQ29uc3RydWN0b3IodGFyZ2V0KSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIHJldHVybiBEZWNvcmF0ZUNvbnN0cnVjdG9yKGRlY29yYXRvcnMsIHRhcmdldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZXhwb3J0ZXIoXCJkZWNvcmF0ZVwiLCBkZWNvcmF0ZSk7XG4gICAgICAgIC8vIDQuMS4yIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpXG4gICAgICAgIC8vIGh0dHBzOi8vcmJ1Y2t0b24uZ2l0aHViLmlvL3JlZmxlY3QtbWV0YWRhdGEvI3JlZmxlY3QubWV0YWRhdGFcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgZGVmYXVsdCBtZXRhZGF0YSBkZWNvcmF0b3IgZmFjdG9yeSB0aGF0IGNhbiBiZSB1c2VkIG9uIGEgY2xhc3MsIGNsYXNzIG1lbWJlciwgb3IgcGFyYW1ldGVyLlxuICAgICAgICAgKiBAcGFyYW0gbWV0YWRhdGFLZXkgVGhlIGtleSBmb3IgdGhlIG1ldGFkYXRhIGVudHJ5LlxuICAgICAgICAgKiBAcGFyYW0gbWV0YWRhdGFWYWx1ZSBUaGUgdmFsdWUgZm9yIHRoZSBtZXRhZGF0YSBlbnRyeS5cbiAgICAgICAgICogQHJldHVybnMgQSBkZWNvcmF0b3IgZnVuY3Rpb24uXG4gICAgICAgICAqIEByZW1hcmtzXG4gICAgICAgICAqIElmIGBtZXRhZGF0YUtleWAgaXMgYWxyZWFkeSBkZWZpbmVkIGZvciB0aGUgdGFyZ2V0IGFuZCB0YXJnZXQga2V5LCB0aGVcbiAgICAgICAgICogbWV0YWRhdGFWYWx1ZSBmb3IgdGhhdCBrZXkgd2lsbCBiZSBvdmVyd3JpdHRlbi5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIGNvbnN0cnVjdG9yXG4gICAgICAgICAqICAgICBAUmVmbGVjdC5tZXRhZGF0YShrZXksIHZhbHVlKVxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gY29uc3RydWN0b3IsIFR5cGVTY3JpcHQgb25seSlcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIEBSZWZsZWN0Lm1ldGFkYXRhKGtleSwgdmFsdWUpXG4gICAgICAgICAqICAgICAgICAgc3RhdGljIHN0YXRpY1Byb3BlcnR5O1xuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIHByb3RvdHlwZSwgVHlwZVNjcmlwdCBvbmx5KVxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICAgICAgQFJlZmxlY3QubWV0YWRhdGEoa2V5LCB2YWx1ZSlcbiAgICAgICAgICogICAgICAgICBwcm9wZXJ0eTtcbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICBAUmVmbGVjdC5tZXRhZGF0YShrZXksIHZhbHVlKVxuICAgICAgICAgKiAgICAgICAgIHN0YXRpYyBzdGF0aWNNZXRob2QoKSB7IH1cbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICAgICAgQFJlZmxlY3QubWV0YWRhdGEoa2V5LCB2YWx1ZSlcbiAgICAgICAgICogICAgICAgICBtZXRob2QoKSB7IH1cbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIG1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XG4gICAgICAgICAgICBmdW5jdGlvbiBkZWNvcmF0b3IodGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICAgICAgICAgIGlmICghSXNPYmplY3QodGFyZ2V0KSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQocHJvcGVydHlLZXkpICYmICFJc1Byb3BlcnR5S2V5KHByb3BlcnR5S2V5KSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIE9yZGluYXJ5RGVmaW5lT3duTWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUsIHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRlY29yYXRvcjtcbiAgICAgICAgfVxuICAgICAgICBleHBvcnRlcihcIm1ldGFkYXRhXCIsIG1ldGFkYXRhKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlZmluZSBhIHVuaXF1ZSBtZXRhZGF0YSBlbnRyeSBvbiB0aGUgdGFyZ2V0LlxuICAgICAgICAgKiBAcGFyYW0gbWV0YWRhdGFLZXkgQSBrZXkgdXNlZCB0byBzdG9yZSBhbmQgcmV0cmlldmUgbWV0YWRhdGEuXG4gICAgICAgICAqIEBwYXJhbSBtZXRhZGF0YVZhbHVlIEEgdmFsdWUgdGhhdCBjb250YWlucyBhdHRhY2hlZCBtZXRhZGF0YS5cbiAgICAgICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0IG9iamVjdCBvbiB3aGljaCB0byBkZWZpbmUgbWV0YWRhdGEuXG4gICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eUtleSAoT3B0aW9uYWwpIFRoZSBwcm9wZXJ0eSBrZXkgZm9yIHRoZSB0YXJnZXQuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eSBkZWNsYXJhdGlvbnMgYXJlIG5vdCBwYXJ0IG9mIEVTNiwgdGhvdWdoIHRoZXkgYXJlIHZhbGlkIGluIFR5cGVTY3JpcHQ6XG4gICAgICAgICAqICAgICAgICAgLy8gc3RhdGljIHN0YXRpY1Byb3BlcnR5O1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5O1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgICAgIGNvbnN0cnVjdG9yKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIHN0YXRpYyBzdGF0aWNNZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgbWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gY29uc3RydWN0b3JcbiAgICAgICAgICogICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBvcHRpb25zLCBFeGFtcGxlKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBvcHRpb25zLCBFeGFtcGxlLCBcInN0YXRpY1Byb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBvcHRpb25zLCBFeGFtcGxlLnByb3RvdHlwZSwgXCJwcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgb3B0aW9ucywgRXhhbXBsZSwgXCJzdGF0aWNNZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBvcHRpb25zLCBFeGFtcGxlLnByb3RvdHlwZSwgXCJtZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBkZWNvcmF0b3IgZmFjdG9yeSBhcyBtZXRhZGF0YS1wcm9kdWNpbmcgYW5ub3RhdGlvbi5cbiAgICAgICAgICogICAgIGZ1bmN0aW9uIE15QW5ub3RhdGlvbihvcHRpb25zKTogRGVjb3JhdG9yIHtcbiAgICAgICAgICogICAgICAgICByZXR1cm4gKHRhcmdldCwga2V5PykgPT4gUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIG9wdGlvbnMsIHRhcmdldCwga2V5KTtcbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGRlZmluZU1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlLCB0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHRhcmdldCkpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgaWYgKCFJc1VuZGVmaW5lZChwcm9wZXJ0eUtleSkpXG4gICAgICAgICAgICAgICAgcHJvcGVydHlLZXkgPSBUb1Byb3BlcnR5S2V5KHByb3BlcnR5S2V5KTtcbiAgICAgICAgICAgIHJldHVybiBPcmRpbmFyeURlZmluZU93bk1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlLCB0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgICAgICAgfVxuICAgICAgICBleHBvcnRlcihcImRlZmluZU1ldGFkYXRhXCIsIGRlZmluZU1ldGFkYXRhKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHRhcmdldCBvYmplY3Qgb3IgaXRzIHByb3RvdHlwZSBjaGFpbiBoYXMgdGhlIHByb3ZpZGVkIG1ldGFkYXRhIGtleSBkZWZpbmVkLlxuICAgICAgICAgKiBAcGFyYW0gbWV0YWRhdGFLZXkgQSBrZXkgdXNlZCB0byBzdG9yZSBhbmQgcmV0cmlldmUgbWV0YWRhdGEuXG4gICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCBvYmplY3Qgb24gd2hpY2ggdGhlIG1ldGFkYXRhIGlzIGRlZmluZWQuXG4gICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eUtleSAoT3B0aW9uYWwpIFRoZSBwcm9wZXJ0eSBrZXkgZm9yIHRoZSB0YXJnZXQuXG4gICAgICAgICAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbWV0YWRhdGEga2V5IHdhcyBkZWZpbmVkIG9uIHRoZSB0YXJnZXQgb2JqZWN0IG9yIGl0cyBwcm90b3R5cGUgY2hhaW47IG90aGVyd2lzZSwgYGZhbHNlYC5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5IGRlY2xhcmF0aW9ucyBhcmUgbm90IHBhcnQgb2YgRVM2LCB0aG91Z2ggdGhleSBhcmUgdmFsaWQgaW4gVHlwZVNjcmlwdDpcbiAgICAgICAgICogICAgICAgICAvLyBzdGF0aWMgc3RhdGljUHJvcGVydHk7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAgICAgY29uc3RydWN0b3IocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgc3RhdGljIHN0YXRpY01ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgICAgICBtZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBjb25zdHJ1Y3RvclxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5oYXNNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5oYXNNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUsIFwic3RhdGljUHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5oYXNNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUucHJvdG90eXBlLCBcInByb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuaGFzTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLCBcInN0YXRpY01ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5oYXNNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUucHJvdG90eXBlLCBcIm1ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGhhc01ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHRhcmdldCkpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgaWYgKCFJc1VuZGVmaW5lZChwcm9wZXJ0eUtleSkpXG4gICAgICAgICAgICAgICAgcHJvcGVydHlLZXkgPSBUb1Byb3BlcnR5S2V5KHByb3BlcnR5S2V5KTtcbiAgICAgICAgICAgIHJldHVybiBPcmRpbmFyeUhhc01ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgICAgICAgfVxuICAgICAgICBleHBvcnRlcihcImhhc01ldGFkYXRhXCIsIGhhc01ldGFkYXRhKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHRhcmdldCBvYmplY3QgaGFzIHRoZSBwcm92aWRlZCBtZXRhZGF0YSBrZXkgZGVmaW5lZC5cbiAgICAgICAgICogQHBhcmFtIG1ldGFkYXRhS2V5IEEga2V5IHVzZWQgdG8gc3RvcmUgYW5kIHJldHJpZXZlIG1ldGFkYXRhLlxuICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQgb2JqZWN0IG9uIHdoaWNoIHRoZSBtZXRhZGF0YSBpcyBkZWZpbmVkLlxuICAgICAgICAgKiBAcGFyYW0gcHJvcGVydHlLZXkgKE9wdGlvbmFsKSBUaGUgcHJvcGVydHkga2V5IGZvciB0aGUgdGFyZ2V0LlxuICAgICAgICAgKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG1ldGFkYXRhIGtleSB3YXMgZGVmaW5lZCBvbiB0aGUgdGFyZ2V0IG9iamVjdDsgb3RoZXJ3aXNlLCBgZmFsc2VgLlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHkgZGVjbGFyYXRpb25zIGFyZSBub3QgcGFydCBvZiBFUzYsIHRob3VnaCB0aGV5IGFyZSB2YWxpZCBpbiBUeXBlU2NyaXB0OlxuICAgICAgICAgKiAgICAgICAgIC8vIHN0YXRpYyBzdGF0aWNQcm9wZXJ0eTtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgICAgICBjb25zdHJ1Y3RvcihwKSB7IH1cbiAgICAgICAgICogICAgICAgICBzdGF0aWMgc3RhdGljTWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIG1ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIGNvbnN0cnVjdG9yXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0Lmhhc093bk1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0Lmhhc093bk1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSwgXCJzdGF0aWNQcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0Lmhhc093bk1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZS5wcm90b3R5cGUsIFwicHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5oYXNPd25NZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUsIFwic3RhdGljTWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0Lmhhc093bk1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZS5wcm90b3R5cGUsIFwibWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gaGFzT3duTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICAgICAgICAgIGlmICghSXNPYmplY3QodGFyZ2V0KSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICBpZiAoIUlzVW5kZWZpbmVkKHByb3BlcnR5S2V5KSlcbiAgICAgICAgICAgICAgICBwcm9wZXJ0eUtleSA9IFRvUHJvcGVydHlLZXkocHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgcmV0dXJuIE9yZGluYXJ5SGFzT3duTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICAgICAgICB9XG4gICAgICAgIGV4cG9ydGVyKFwiaGFzT3duTWV0YWRhdGFcIiwgaGFzT3duTWV0YWRhdGEpO1xuICAgICAgICAvKipcbiAgICAgICAgICogR2V0cyB0aGUgbWV0YWRhdGEgdmFsdWUgZm9yIHRoZSBwcm92aWRlZCBtZXRhZGF0YSBrZXkgb24gdGhlIHRhcmdldCBvYmplY3Qgb3IgaXRzIHByb3RvdHlwZSBjaGFpbi5cbiAgICAgICAgICogQHBhcmFtIG1ldGFkYXRhS2V5IEEga2V5IHVzZWQgdG8gc3RvcmUgYW5kIHJldHJpZXZlIG1ldGFkYXRhLlxuICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQgb2JqZWN0IG9uIHdoaWNoIHRoZSBtZXRhZGF0YSBpcyBkZWZpbmVkLlxuICAgICAgICAgKiBAcGFyYW0gcHJvcGVydHlLZXkgKE9wdGlvbmFsKSBUaGUgcHJvcGVydHkga2V5IGZvciB0aGUgdGFyZ2V0LlxuICAgICAgICAgKiBAcmV0dXJucyBUaGUgbWV0YWRhdGEgdmFsdWUgZm9yIHRoZSBtZXRhZGF0YSBrZXkgaWYgZm91bmQ7IG90aGVyd2lzZSwgYHVuZGVmaW5lZGAuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eSBkZWNsYXJhdGlvbnMgYXJlIG5vdCBwYXJ0IG9mIEVTNiwgdGhvdWdoIHRoZXkgYXJlIHZhbGlkIGluIFR5cGVTY3JpcHQ6XG4gICAgICAgICAqICAgICAgICAgLy8gc3RhdGljIHN0YXRpY1Byb3BlcnR5O1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5O1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgICAgIGNvbnN0cnVjdG9yKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIHN0YXRpYyBzdGF0aWNNZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgbWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gY29uc3RydWN0b3JcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLCBcInN0YXRpY1Byb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLnByb3RvdHlwZSwgXCJwcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSwgXCJzdGF0aWNNZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLnByb3RvdHlwZSwgXCJtZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBnZXRNZXRhZGF0YShtZXRhZGF0YUtleSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICAgICAgaWYgKCFJc09iamVjdCh0YXJnZXQpKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQocHJvcGVydHlLZXkpKVxuICAgICAgICAgICAgICAgIHByb3BlcnR5S2V5ID0gVG9Qcm9wZXJ0eUtleShwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICByZXR1cm4gT3JkaW5hcnlHZXRNZXRhZGF0YShtZXRhZGF0YUtleSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gICAgICAgIH1cbiAgICAgICAgZXhwb3J0ZXIoXCJnZXRNZXRhZGF0YVwiLCBnZXRNZXRhZGF0YSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXRzIHRoZSBtZXRhZGF0YSB2YWx1ZSBmb3IgdGhlIHByb3ZpZGVkIG1ldGFkYXRhIGtleSBvbiB0aGUgdGFyZ2V0IG9iamVjdC5cbiAgICAgICAgICogQHBhcmFtIG1ldGFkYXRhS2V5IEEga2V5IHVzZWQgdG8gc3RvcmUgYW5kIHJldHJpZXZlIG1ldGFkYXRhLlxuICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQgb2JqZWN0IG9uIHdoaWNoIHRoZSBtZXRhZGF0YSBpcyBkZWZpbmVkLlxuICAgICAgICAgKiBAcGFyYW0gcHJvcGVydHlLZXkgKE9wdGlvbmFsKSBUaGUgcHJvcGVydHkga2V5IGZvciB0aGUgdGFyZ2V0LlxuICAgICAgICAgKiBAcmV0dXJucyBUaGUgbWV0YWRhdGEgdmFsdWUgZm9yIHRoZSBtZXRhZGF0YSBrZXkgaWYgZm91bmQ7IG90aGVyd2lzZSwgYHVuZGVmaW5lZGAuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eSBkZWNsYXJhdGlvbnMgYXJlIG5vdCBwYXJ0IG9mIEVTNiwgdGhvdWdoIHRoZXkgYXJlIHZhbGlkIGluIFR5cGVTY3JpcHQ6XG4gICAgICAgICAqICAgICAgICAgLy8gc3RhdGljIHN0YXRpY1Byb3BlcnR5O1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5O1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgICAgIGNvbnN0cnVjdG9yKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIHN0YXRpYyBzdGF0aWNNZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgbWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gY29uc3RydWN0b3JcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLCBcInN0YXRpY1Byb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLnByb3RvdHlwZSwgXCJwcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE93bk1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSwgXCJzdGF0aWNNZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLnByb3RvdHlwZSwgXCJtZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBnZXRPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICAgICAgaWYgKCFJc09iamVjdCh0YXJnZXQpKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQocHJvcGVydHlLZXkpKVxuICAgICAgICAgICAgICAgIHByb3BlcnR5S2V5ID0gVG9Qcm9wZXJ0eUtleShwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICByZXR1cm4gT3JkaW5hcnlHZXRPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gICAgICAgIH1cbiAgICAgICAgZXhwb3J0ZXIoXCJnZXRPd25NZXRhZGF0YVwiLCBnZXRPd25NZXRhZGF0YSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXRzIHRoZSBtZXRhZGF0YSBrZXlzIGRlZmluZWQgb24gdGhlIHRhcmdldCBvYmplY3Qgb3IgaXRzIHByb3RvdHlwZSBjaGFpbi5cbiAgICAgICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0IG9iamVjdCBvbiB3aGljaCB0aGUgbWV0YWRhdGEgaXMgZGVmaW5lZC5cbiAgICAgICAgICogQHBhcmFtIHByb3BlcnR5S2V5IChPcHRpb25hbCkgVGhlIHByb3BlcnR5IGtleSBmb3IgdGhlIHRhcmdldC5cbiAgICAgICAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgdW5pcXVlIG1ldGFkYXRhIGtleXMuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eSBkZWNsYXJhdGlvbnMgYXJlIG5vdCBwYXJ0IG9mIEVTNiwgdGhvdWdoIHRoZXkgYXJlIHZhbGlkIGluIFR5cGVTY3JpcHQ6XG4gICAgICAgICAqICAgICAgICAgLy8gc3RhdGljIHN0YXRpY1Byb3BlcnR5O1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5O1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgICAgIGNvbnN0cnVjdG9yKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIHN0YXRpYyBzdGF0aWNNZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgbWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gY29uc3RydWN0b3JcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0TWV0YWRhdGFLZXlzKEV4YW1wbGUpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRNZXRhZGF0YUtleXMoRXhhbXBsZSwgXCJzdGF0aWNQcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE1ldGFkYXRhS2V5cyhFeGFtcGxlLnByb3RvdHlwZSwgXCJwcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE1ldGFkYXRhS2V5cyhFeGFtcGxlLCBcInN0YXRpY01ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRNZXRhZGF0YUtleXMoRXhhbXBsZS5wcm90b3R5cGUsIFwibWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gZ2V0TWV0YWRhdGFLZXlzKHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICAgICAgICAgIGlmICghSXNPYmplY3QodGFyZ2V0KSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICBpZiAoIUlzVW5kZWZpbmVkKHByb3BlcnR5S2V5KSlcbiAgICAgICAgICAgICAgICBwcm9wZXJ0eUtleSA9IFRvUHJvcGVydHlLZXkocHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgcmV0dXJuIE9yZGluYXJ5TWV0YWRhdGFLZXlzKHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICAgICAgICB9XG4gICAgICAgIGV4cG9ydGVyKFwiZ2V0TWV0YWRhdGFLZXlzXCIsIGdldE1ldGFkYXRhS2V5cyk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXRzIHRoZSB1bmlxdWUgbWV0YWRhdGEga2V5cyBkZWZpbmVkIG9uIHRoZSB0YXJnZXQgb2JqZWN0LlxuICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQgb2JqZWN0IG9uIHdoaWNoIHRoZSBtZXRhZGF0YSBpcyBkZWZpbmVkLlxuICAgICAgICAgKiBAcGFyYW0gcHJvcGVydHlLZXkgKE9wdGlvbmFsKSBUaGUgcHJvcGVydHkga2V5IGZvciB0aGUgdGFyZ2V0LlxuICAgICAgICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiB1bmlxdWUgbWV0YWRhdGEga2V5cy5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5IGRlY2xhcmF0aW9ucyBhcmUgbm90IHBhcnQgb2YgRVM2LCB0aG91Z2ggdGhleSBhcmUgdmFsaWQgaW4gVHlwZVNjcmlwdDpcbiAgICAgICAgICogICAgICAgICAvLyBzdGF0aWMgc3RhdGljUHJvcGVydHk7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAgICAgY29uc3RydWN0b3IocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgc3RhdGljIHN0YXRpY01ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgICAgICBtZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBjb25zdHJ1Y3RvclxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YUtleXMoRXhhbXBsZSk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE93bk1ldGFkYXRhS2V5cyhFeGFtcGxlLCBcInN0YXRpY1Byb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGFLZXlzKEV4YW1wbGUucHJvdG90eXBlLCBcInByb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGFLZXlzKEV4YW1wbGUsIFwic3RhdGljTWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE93bk1ldGFkYXRhS2V5cyhFeGFtcGxlLnByb3RvdHlwZSwgXCJtZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBnZXRPd25NZXRhZGF0YUtleXModGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICAgICAgaWYgKCFJc09iamVjdCh0YXJnZXQpKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQocHJvcGVydHlLZXkpKVxuICAgICAgICAgICAgICAgIHByb3BlcnR5S2V5ID0gVG9Qcm9wZXJ0eUtleShwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICByZXR1cm4gT3JkaW5hcnlPd25NZXRhZGF0YUtleXModGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gICAgICAgIH1cbiAgICAgICAgZXhwb3J0ZXIoXCJnZXRPd25NZXRhZGF0YUtleXNcIiwgZ2V0T3duTWV0YWRhdGFLZXlzKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlbGV0ZXMgdGhlIG1ldGFkYXRhIGVudHJ5IGZyb20gdGhlIHRhcmdldCBvYmplY3Qgd2l0aCB0aGUgcHJvdmlkZWQga2V5LlxuICAgICAgICAgKiBAcGFyYW0gbWV0YWRhdGFLZXkgQSBrZXkgdXNlZCB0byBzdG9yZSBhbmQgcmV0cmlldmUgbWV0YWRhdGEuXG4gICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCBvYmplY3Qgb24gd2hpY2ggdGhlIG1ldGFkYXRhIGlzIGRlZmluZWQuXG4gICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eUtleSAoT3B0aW9uYWwpIFRoZSBwcm9wZXJ0eSBrZXkgZm9yIHRoZSB0YXJnZXQuXG4gICAgICAgICAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbWV0YWRhdGEgZW50cnkgd2FzIGZvdW5kIGFuZCBkZWxldGVkOyBvdGhlcndpc2UsIGZhbHNlLlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHkgZGVjbGFyYXRpb25zIGFyZSBub3QgcGFydCBvZiBFUzYsIHRob3VnaCB0aGV5IGFyZSB2YWxpZCBpbiBUeXBlU2NyaXB0OlxuICAgICAgICAgKiAgICAgICAgIC8vIHN0YXRpYyBzdGF0aWNQcm9wZXJ0eTtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgICAgICBjb25zdHJ1Y3RvcihwKSB7IH1cbiAgICAgICAgICogICAgICAgICBzdGF0aWMgc3RhdGljTWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIG1ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIGNvbnN0cnVjdG9yXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmRlbGV0ZU1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmRlbGV0ZU1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSwgXCJzdGF0aWNQcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmRlbGV0ZU1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZS5wcm90b3R5cGUsIFwicHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5kZWxldGVNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUsIFwic3RhdGljTWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmRlbGV0ZU1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZS5wcm90b3R5cGUsIFwibWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gZGVsZXRlTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICAgICAgICAgIGlmICghSXNPYmplY3QodGFyZ2V0KSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICBpZiAoIUlzVW5kZWZpbmVkKHByb3BlcnR5S2V5KSlcbiAgICAgICAgICAgICAgICBwcm9wZXJ0eUtleSA9IFRvUHJvcGVydHlLZXkocHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgdmFyIG1ldGFkYXRhTWFwID0gR2V0T3JDcmVhdGVNZXRhZGF0YU1hcCh0YXJnZXQsIHByb3BlcnR5S2V5LCAvKkNyZWF0ZSovIGZhbHNlKTtcbiAgICAgICAgICAgIGlmIChJc1VuZGVmaW5lZChtZXRhZGF0YU1hcCkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgaWYgKCFtZXRhZGF0YU1hcC5kZWxldGUobWV0YWRhdGFLZXkpKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIGlmIChtZXRhZGF0YU1hcC5zaXplID4gMClcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIHZhciB0YXJnZXRNZXRhZGF0YSA9IE1ldGFkYXRhLmdldCh0YXJnZXQpO1xuICAgICAgICAgICAgdGFyZ2V0TWV0YWRhdGEuZGVsZXRlKHByb3BlcnR5S2V5KTtcbiAgICAgICAgICAgIGlmICh0YXJnZXRNZXRhZGF0YS5zaXplID4gMClcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIE1ldGFkYXRhLmRlbGV0ZSh0YXJnZXQpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZXhwb3J0ZXIoXCJkZWxldGVNZXRhZGF0YVwiLCBkZWxldGVNZXRhZGF0YSk7XG4gICAgICAgIGZ1bmN0aW9uIERlY29yYXRlQ29uc3RydWN0b3IoZGVjb3JhdG9ycywgdGFyZ2V0KSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICAgICAgICAgIHZhciBkZWNvcmF0b3IgPSBkZWNvcmF0b3JzW2ldO1xuICAgICAgICAgICAgICAgIHZhciBkZWNvcmF0ZWQgPSBkZWNvcmF0b3IodGFyZ2V0KTtcbiAgICAgICAgICAgICAgICBpZiAoIUlzVW5kZWZpbmVkKGRlY29yYXRlZCkgJiYgIUlzTnVsbChkZWNvcmF0ZWQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghSXNDb25zdHJ1Y3RvcihkZWNvcmF0ZWQpKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXQgPSBkZWNvcmF0ZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBEZWNvcmF0ZVByb3BlcnR5KGRlY29yYXRvcnMsIHRhcmdldCwgcHJvcGVydHlLZXksIGRlc2NyaXB0b3IpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICAgICAgdmFyIGRlY29yYXRvciA9IGRlY29yYXRvcnNbaV07XG4gICAgICAgICAgICAgICAgdmFyIGRlY29yYXRlZCA9IGRlY29yYXRvcih0YXJnZXQsIHByb3BlcnR5S2V5LCBkZXNjcmlwdG9yKTtcbiAgICAgICAgICAgICAgICBpZiAoIUlzVW5kZWZpbmVkKGRlY29yYXRlZCkgJiYgIUlzTnVsbChkZWNvcmF0ZWQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghSXNPYmplY3QoZGVjb3JhdGVkKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvciA9IGRlY29yYXRlZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBHZXRPckNyZWF0ZU1ldGFkYXRhTWFwKE8sIFAsIENyZWF0ZSkge1xuICAgICAgICAgICAgdmFyIHRhcmdldE1ldGFkYXRhID0gTWV0YWRhdGEuZ2V0KE8pO1xuICAgICAgICAgICAgaWYgKElzVW5kZWZpbmVkKHRhcmdldE1ldGFkYXRhKSkge1xuICAgICAgICAgICAgICAgIGlmICghQ3JlYXRlKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIHRhcmdldE1ldGFkYXRhID0gbmV3IF9NYXAoKTtcbiAgICAgICAgICAgICAgICBNZXRhZGF0YS5zZXQoTywgdGFyZ2V0TWV0YWRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIG1ldGFkYXRhTWFwID0gdGFyZ2V0TWV0YWRhdGEuZ2V0KFApO1xuICAgICAgICAgICAgaWYgKElzVW5kZWZpbmVkKG1ldGFkYXRhTWFwKSkge1xuICAgICAgICAgICAgICAgIGlmICghQ3JlYXRlKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIG1ldGFkYXRhTWFwID0gbmV3IF9NYXAoKTtcbiAgICAgICAgICAgICAgICB0YXJnZXRNZXRhZGF0YS5zZXQoUCwgbWV0YWRhdGFNYXApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1ldGFkYXRhTWFwO1xuICAgICAgICB9XG4gICAgICAgIC8vIDMuMS4xLjEgT3JkaW5hcnlIYXNNZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUClcbiAgICAgICAgLy8gaHR0cHM6Ly9yYnVja3Rvbi5naXRodWIuaW8vcmVmbGVjdC1tZXRhZGF0YS8jb3JkaW5hcnloYXNtZXRhZGF0YVxuICAgICAgICBmdW5jdGlvbiBPcmRpbmFyeUhhc01ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKSB7XG4gICAgICAgICAgICB2YXIgaGFzT3duID0gT3JkaW5hcnlIYXNPd25NZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUCk7XG4gICAgICAgICAgICBpZiAoaGFzT3duKVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgdmFyIHBhcmVudCA9IE9yZGluYXJ5R2V0UHJvdG90eXBlT2YoTyk7XG4gICAgICAgICAgICBpZiAoIUlzTnVsbChwYXJlbnQpKVxuICAgICAgICAgICAgICAgIHJldHVybiBPcmRpbmFyeUhhc01ldGFkYXRhKE1ldGFkYXRhS2V5LCBwYXJlbnQsIFApO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIC8vIDMuMS4yLjEgT3JkaW5hcnlIYXNPd25NZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUClcbiAgICAgICAgLy8gaHR0cHM6Ly9yYnVja3Rvbi5naXRodWIuaW8vcmVmbGVjdC1tZXRhZGF0YS8jb3JkaW5hcnloYXNvd25tZXRhZGF0YVxuICAgICAgICBmdW5jdGlvbiBPcmRpbmFyeUhhc093bk1ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKSB7XG4gICAgICAgICAgICB2YXIgbWV0YWRhdGFNYXAgPSBHZXRPckNyZWF0ZU1ldGFkYXRhTWFwKE8sIFAsIC8qQ3JlYXRlKi8gZmFsc2UpO1xuICAgICAgICAgICAgaWYgKElzVW5kZWZpbmVkKG1ldGFkYXRhTWFwKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm4gVG9Cb29sZWFuKG1ldGFkYXRhTWFwLmhhcyhNZXRhZGF0YUtleSkpO1xuICAgICAgICB9XG4gICAgICAgIC8vIDMuMS4zLjEgT3JkaW5hcnlHZXRNZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUClcbiAgICAgICAgLy8gaHR0cHM6Ly9yYnVja3Rvbi5naXRodWIuaW8vcmVmbGVjdC1tZXRhZGF0YS8jb3JkaW5hcnlnZXRtZXRhZGF0YVxuICAgICAgICBmdW5jdGlvbiBPcmRpbmFyeUdldE1ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKSB7XG4gICAgICAgICAgICB2YXIgaGFzT3duID0gT3JkaW5hcnlIYXNPd25NZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUCk7XG4gICAgICAgICAgICBpZiAoaGFzT3duKVxuICAgICAgICAgICAgICAgIHJldHVybiBPcmRpbmFyeUdldE93bk1ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKTtcbiAgICAgICAgICAgIHZhciBwYXJlbnQgPSBPcmRpbmFyeUdldFByb3RvdHlwZU9mKE8pO1xuICAgICAgICAgICAgaWYgKCFJc051bGwocGFyZW50KSlcbiAgICAgICAgICAgICAgICByZXR1cm4gT3JkaW5hcnlHZXRNZXRhZGF0YShNZXRhZGF0YUtleSwgcGFyZW50LCBQKTtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gMy4xLjQuMSBPcmRpbmFyeUdldE93bk1ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKVxuICAgICAgICAvLyBodHRwczovL3JidWNrdG9uLmdpdGh1Yi5pby9yZWZsZWN0LW1ldGFkYXRhLyNvcmRpbmFyeWdldG93bm1ldGFkYXRhXG4gICAgICAgIGZ1bmN0aW9uIE9yZGluYXJ5R2V0T3duTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApIHtcbiAgICAgICAgICAgIHZhciBtZXRhZGF0YU1hcCA9IEdldE9yQ3JlYXRlTWV0YWRhdGFNYXAoTywgUCwgLypDcmVhdGUqLyBmYWxzZSk7XG4gICAgICAgICAgICBpZiAoSXNVbmRlZmluZWQobWV0YWRhdGFNYXApKVxuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGFNYXAuZ2V0KE1ldGFkYXRhS2V5KTtcbiAgICAgICAgfVxuICAgICAgICAvLyAzLjEuNS4xIE9yZGluYXJ5RGVmaW5lT3duTWV0YWRhdGEoTWV0YWRhdGFLZXksIE1ldGFkYXRhVmFsdWUsIE8sIFApXG4gICAgICAgIC8vIGh0dHBzOi8vcmJ1Y2t0b24uZ2l0aHViLmlvL3JlZmxlY3QtbWV0YWRhdGEvI29yZGluYXJ5ZGVmaW5lb3dubWV0YWRhdGFcbiAgICAgICAgZnVuY3Rpb24gT3JkaW5hcnlEZWZpbmVPd25NZXRhZGF0YShNZXRhZGF0YUtleSwgTWV0YWRhdGFWYWx1ZSwgTywgUCkge1xuICAgICAgICAgICAgdmFyIG1ldGFkYXRhTWFwID0gR2V0T3JDcmVhdGVNZXRhZGF0YU1hcChPLCBQLCAvKkNyZWF0ZSovIHRydWUpO1xuICAgICAgICAgICAgbWV0YWRhdGFNYXAuc2V0KE1ldGFkYXRhS2V5LCBNZXRhZGF0YVZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyAzLjEuNi4xIE9yZGluYXJ5TWV0YWRhdGFLZXlzKE8sIFApXG4gICAgICAgIC8vIGh0dHBzOi8vcmJ1Y2t0b24uZ2l0aHViLmlvL3JlZmxlY3QtbWV0YWRhdGEvI29yZGluYXJ5bWV0YWRhdGFrZXlzXG4gICAgICAgIGZ1bmN0aW9uIE9yZGluYXJ5TWV0YWRhdGFLZXlzKE8sIFApIHtcbiAgICAgICAgICAgIHZhciBvd25LZXlzID0gT3JkaW5hcnlPd25NZXRhZGF0YUtleXMoTywgUCk7XG4gICAgICAgICAgICB2YXIgcGFyZW50ID0gT3JkaW5hcnlHZXRQcm90b3R5cGVPZihPKTtcbiAgICAgICAgICAgIGlmIChwYXJlbnQgPT09IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIG93bktleXM7XG4gICAgICAgICAgICB2YXIgcGFyZW50S2V5cyA9IE9yZGluYXJ5TWV0YWRhdGFLZXlzKHBhcmVudCwgUCk7XG4gICAgICAgICAgICBpZiAocGFyZW50S2V5cy5sZW5ndGggPD0gMClcbiAgICAgICAgICAgICAgICByZXR1cm4gb3duS2V5cztcbiAgICAgICAgICAgIGlmIChvd25LZXlzLmxlbmd0aCA8PSAwKVxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJlbnRLZXlzO1xuICAgICAgICAgICAgdmFyIHNldCA9IG5ldyBfU2V0KCk7XG4gICAgICAgICAgICB2YXIga2V5cyA9IFtdO1xuICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBvd25LZXlzXzEgPSBvd25LZXlzOyBfaSA8IG93bktleXNfMS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgICAgICB2YXIga2V5ID0gb3duS2V5c18xW19pXTtcbiAgICAgICAgICAgICAgICB2YXIgaGFzS2V5ID0gc2V0LmhhcyhrZXkpO1xuICAgICAgICAgICAgICAgIGlmICghaGFzS2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIHNldC5hZGQoa2V5KTtcbiAgICAgICAgICAgICAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yICh2YXIgX2EgPSAwLCBwYXJlbnRLZXlzXzEgPSBwYXJlbnRLZXlzOyBfYSA8IHBhcmVudEtleXNfMS5sZW5ndGg7IF9hKyspIHtcbiAgICAgICAgICAgICAgICB2YXIga2V5ID0gcGFyZW50S2V5c18xW19hXTtcbiAgICAgICAgICAgICAgICB2YXIgaGFzS2V5ID0gc2V0LmhhcyhrZXkpO1xuICAgICAgICAgICAgICAgIGlmICghaGFzS2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIHNldC5hZGQoa2V5KTtcbiAgICAgICAgICAgICAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGtleXM7XG4gICAgICAgIH1cbiAgICAgICAgLy8gMy4xLjcuMSBPcmRpbmFyeU93bk1ldGFkYXRhS2V5cyhPLCBQKVxuICAgICAgICAvLyBodHRwczovL3JidWNrdG9uLmdpdGh1Yi5pby9yZWZsZWN0LW1ldGFkYXRhLyNvcmRpbmFyeW93bm1ldGFkYXRha2V5c1xuICAgICAgICBmdW5jdGlvbiBPcmRpbmFyeU93bk1ldGFkYXRhS2V5cyhPLCBQKSB7XG4gICAgICAgICAgICB2YXIga2V5cyA9IFtdO1xuICAgICAgICAgICAgdmFyIG1ldGFkYXRhTWFwID0gR2V0T3JDcmVhdGVNZXRhZGF0YU1hcChPLCBQLCAvKkNyZWF0ZSovIGZhbHNlKTtcbiAgICAgICAgICAgIGlmIChJc1VuZGVmaW5lZChtZXRhZGF0YU1hcCkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGtleXM7XG4gICAgICAgICAgICB2YXIga2V5c09iaiA9IG1ldGFkYXRhTWFwLmtleXMoKTtcbiAgICAgICAgICAgIHZhciBpdGVyYXRvciA9IEdldEl0ZXJhdG9yKGtleXNPYmopO1xuICAgICAgICAgICAgdmFyIGsgPSAwO1xuICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgICAgICB2YXIgbmV4dCA9IEl0ZXJhdG9yU3RlcChpdGVyYXRvcik7XG4gICAgICAgICAgICAgICAgaWYgKCFuZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIGtleXMubGVuZ3RoID0gaztcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGtleXM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBuZXh0VmFsdWUgPSBJdGVyYXRvclZhbHVlKG5leHQpO1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGtleXNba10gPSBuZXh0VmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBJdGVyYXRvckNsb3NlKGl0ZXJhdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaysrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIDYgRUNNQVNjcmlwdCBEYXRhIFR5cDBlcyBhbmQgVmFsdWVzXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWVjbWFzY3JpcHQtZGF0YS10eXBlcy1hbmQtdmFsdWVzXG4gICAgICAgIGZ1bmN0aW9uIFR5cGUoeCkge1xuICAgICAgICAgICAgaWYgKHggPT09IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIDEgLyogTnVsbCAqLztcbiAgICAgICAgICAgIHN3aXRjaCAodHlwZW9mIHgpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFwidW5kZWZpbmVkXCI6IHJldHVybiAwIC8qIFVuZGVmaW5lZCAqLztcbiAgICAgICAgICAgICAgICBjYXNlIFwiYm9vbGVhblwiOiByZXR1cm4gMiAvKiBCb29sZWFuICovO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJzdHJpbmdcIjogcmV0dXJuIDMgLyogU3RyaW5nICovO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJzeW1ib2xcIjogcmV0dXJuIDQgLyogU3ltYm9sICovO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjogcmV0dXJuIDUgLyogTnVtYmVyICovO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjogcmV0dXJuIHggPT09IG51bGwgPyAxIC8qIE51bGwgKi8gOiA2IC8qIE9iamVjdCAqLztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gNiAvKiBPYmplY3QgKi87XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gNi4xLjEgVGhlIFVuZGVmaW5lZCBUeXBlXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWVjbWFzY3JpcHQtbGFuZ3VhZ2UtdHlwZXMtdW5kZWZpbmVkLXR5cGVcbiAgICAgICAgZnVuY3Rpb24gSXNVbmRlZmluZWQoeCkge1xuICAgICAgICAgICAgcmV0dXJuIHggPT09IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICAvLyA2LjEuMiBUaGUgTnVsbCBUeXBlXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWVjbWFzY3JpcHQtbGFuZ3VhZ2UtdHlwZXMtbnVsbC10eXBlXG4gICAgICAgIGZ1bmN0aW9uIElzTnVsbCh4KSB7XG4gICAgICAgICAgICByZXR1cm4geCA9PT0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICAvLyA2LjEuNSBUaGUgU3ltYm9sIFR5cGVcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtZWNtYXNjcmlwdC1sYW5ndWFnZS10eXBlcy1zeW1ib2wtdHlwZVxuICAgICAgICBmdW5jdGlvbiBJc1N5bWJvbCh4KSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIHggPT09IFwic3ltYm9sXCI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNi4xLjcgVGhlIE9iamVjdCBUeXBlXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLW9iamVjdC10eXBlXG4gICAgICAgIGZ1bmN0aW9uIElzT2JqZWN0KHgpIHtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgeCA9PT0gXCJvYmplY3RcIiA/IHggIT09IG51bGwgOiB0eXBlb2YgeCA9PT0gXCJmdW5jdGlvblwiO1xuICAgICAgICB9XG4gICAgICAgIC8vIDcuMSBUeXBlIENvbnZlcnNpb25cbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtdHlwZS1jb252ZXJzaW9uXG4gICAgICAgIC8vIDcuMS4xIFRvUHJpbWl0aXZlKGlucHV0IFssIFByZWZlcnJlZFR5cGVdKVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy10b3ByaW1pdGl2ZVxuICAgICAgICBmdW5jdGlvbiBUb1ByaW1pdGl2ZShpbnB1dCwgUHJlZmVycmVkVHlwZSkge1xuICAgICAgICAgICAgc3dpdGNoIChUeXBlKGlucHV0KSkge1xuICAgICAgICAgICAgICAgIGNhc2UgMCAvKiBVbmRlZmluZWQgKi86IHJldHVybiBpbnB1dDtcbiAgICAgICAgICAgICAgICBjYXNlIDEgLyogTnVsbCAqLzogcmV0dXJuIGlucHV0O1xuICAgICAgICAgICAgICAgIGNhc2UgMiAvKiBCb29sZWFuICovOiByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICAgICAgY2FzZSAzIC8qIFN0cmluZyAqLzogcmV0dXJuIGlucHV0O1xuICAgICAgICAgICAgICAgIGNhc2UgNCAvKiBTeW1ib2wgKi86IHJldHVybiBpbnB1dDtcbiAgICAgICAgICAgICAgICBjYXNlIDUgLyogTnVtYmVyICovOiByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgaGludCA9IFByZWZlcnJlZFR5cGUgPT09IDMgLyogU3RyaW5nICovID8gXCJzdHJpbmdcIiA6IFByZWZlcnJlZFR5cGUgPT09IDUgLyogTnVtYmVyICovID8gXCJudW1iZXJcIiA6IFwiZGVmYXVsdFwiO1xuICAgICAgICAgICAgdmFyIGV4b3RpY1RvUHJpbSA9IEdldE1ldGhvZChpbnB1dCwgdG9QcmltaXRpdmVTeW1ib2wpO1xuICAgICAgICAgICAgaWYgKGV4b3RpY1RvUHJpbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGV4b3RpY1RvUHJpbS5jYWxsKGlucHV0LCBoaW50KTtcbiAgICAgICAgICAgICAgICBpZiAoSXNPYmplY3QocmVzdWx0KSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gT3JkaW5hcnlUb1ByaW1pdGl2ZShpbnB1dCwgaGludCA9PT0gXCJkZWZhdWx0XCIgPyBcIm51bWJlclwiIDogaGludCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy4xLjEuMSBPcmRpbmFyeVRvUHJpbWl0aXZlKE8sIGhpbnQpXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLW9yZGluYXJ5dG9wcmltaXRpdmVcbiAgICAgICAgZnVuY3Rpb24gT3JkaW5hcnlUb1ByaW1pdGl2ZShPLCBoaW50KSB7XG4gICAgICAgICAgICBpZiAoaGludCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgIHZhciB0b1N0cmluZ18xID0gTy50b1N0cmluZztcbiAgICAgICAgICAgICAgICBpZiAoSXNDYWxsYWJsZSh0b1N0cmluZ18xKSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gdG9TdHJpbmdfMS5jYWxsKE8pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHJlc3VsdCkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgdmFsdWVPZiA9IE8udmFsdWVPZjtcbiAgICAgICAgICAgICAgICBpZiAoSXNDYWxsYWJsZSh2YWx1ZU9mKSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gdmFsdWVPZi5jYWxsKE8pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHJlc3VsdCkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciB2YWx1ZU9mID0gTy52YWx1ZU9mO1xuICAgICAgICAgICAgICAgIGlmIChJc0NhbGxhYmxlKHZhbHVlT2YpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSB2YWx1ZU9mLmNhbGwoTyk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghSXNPYmplY3QocmVzdWx0KSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciB0b1N0cmluZ18yID0gTy50b1N0cmluZztcbiAgICAgICAgICAgICAgICBpZiAoSXNDYWxsYWJsZSh0b1N0cmluZ18yKSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gdG9TdHJpbmdfMi5jYWxsKE8pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHJlc3VsdCkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjEuMiBUb0Jvb2xlYW4oYXJndW1lbnQpXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8yMDE2LyNzZWMtdG9ib29sZWFuXG4gICAgICAgIGZ1bmN0aW9uIFRvQm9vbGVhbihhcmd1bWVudCkge1xuICAgICAgICAgICAgcmV0dXJuICEhYXJndW1lbnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy4xLjEyIFRvU3RyaW5nKGFyZ3VtZW50KVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy10b3N0cmluZ1xuICAgICAgICBmdW5jdGlvbiBUb1N0cmluZyhhcmd1bWVudCkge1xuICAgICAgICAgICAgcmV0dXJuIFwiXCIgKyBhcmd1bWVudDtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjEuMTQgVG9Qcm9wZXJ0eUtleShhcmd1bWVudClcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtdG9wcm9wZXJ0eWtleVxuICAgICAgICBmdW5jdGlvbiBUb1Byb3BlcnR5S2V5KGFyZ3VtZW50KSB7XG4gICAgICAgICAgICB2YXIga2V5ID0gVG9QcmltaXRpdmUoYXJndW1lbnQsIDMgLyogU3RyaW5nICovKTtcbiAgICAgICAgICAgIGlmIChJc1N5bWJvbChrZXkpKVxuICAgICAgICAgICAgICAgIHJldHVybiBrZXk7XG4gICAgICAgICAgICByZXR1cm4gVG9TdHJpbmcoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjIgVGVzdGluZyBhbmQgQ29tcGFyaXNvbiBPcGVyYXRpb25zXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXRlc3RpbmctYW5kLWNvbXBhcmlzb24tb3BlcmF0aW9uc1xuICAgICAgICAvLyA3LjIuMiBJc0FycmF5KGFyZ3VtZW50KVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1pc2FycmF5XG4gICAgICAgIGZ1bmN0aW9uIElzQXJyYXkoYXJndW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBBcnJheS5pc0FycmF5XG4gICAgICAgICAgICAgICAgPyBBcnJheS5pc0FycmF5KGFyZ3VtZW50KVxuICAgICAgICAgICAgICAgIDogYXJndW1lbnQgaW5zdGFuY2VvZiBPYmplY3RcbiAgICAgICAgICAgICAgICAgICAgPyBhcmd1bWVudCBpbnN0YW5jZW9mIEFycmF5XG4gICAgICAgICAgICAgICAgICAgIDogT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFyZ3VtZW50KSA9PT0gXCJbb2JqZWN0IEFycmF5XVwiO1xuICAgICAgICB9XG4gICAgICAgIC8vIDcuMi4zIElzQ2FsbGFibGUoYXJndW1lbnQpXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWlzY2FsbGFibGVcbiAgICAgICAgZnVuY3Rpb24gSXNDYWxsYWJsZShhcmd1bWVudCkge1xuICAgICAgICAgICAgLy8gTk9URTogVGhpcyBpcyBhbiBhcHByb3hpbWF0aW9uIGFzIHdlIGNhbm5vdCBjaGVjayBmb3IgW1tDYWxsXV0gaW50ZXJuYWwgbWV0aG9kLlxuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBhcmd1bWVudCA9PT0gXCJmdW5jdGlvblwiO1xuICAgICAgICB9XG4gICAgICAgIC8vIDcuMi40IElzQ29uc3RydWN0b3IoYXJndW1lbnQpXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWlzY29uc3RydWN0b3JcbiAgICAgICAgZnVuY3Rpb24gSXNDb25zdHJ1Y3Rvcihhcmd1bWVudCkge1xuICAgICAgICAgICAgLy8gTk9URTogVGhpcyBpcyBhbiBhcHByb3hpbWF0aW9uIGFzIHdlIGNhbm5vdCBjaGVjayBmb3IgW1tDb25zdHJ1Y3RdXSBpbnRlcm5hbCBtZXRob2QuXG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIGFyZ3VtZW50ID09PSBcImZ1bmN0aW9uXCI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy4yLjcgSXNQcm9wZXJ0eUtleShhcmd1bWVudClcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtaXNwcm9wZXJ0eWtleVxuICAgICAgICBmdW5jdGlvbiBJc1Byb3BlcnR5S2V5KGFyZ3VtZW50KSB7XG4gICAgICAgICAgICBzd2l0Y2ggKFR5cGUoYXJndW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAzIC8qIFN0cmluZyAqLzogcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgY2FzZSA0IC8qIFN5bWJvbCAqLzogcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDogcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIDcuMyBPcGVyYXRpb25zIG9uIE9iamVjdHNcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtb3BlcmF0aW9ucy1vbi1vYmplY3RzXG4gICAgICAgIC8vIDcuMy45IEdldE1ldGhvZChWLCBQKVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1nZXRtZXRob2RcbiAgICAgICAgZnVuY3Rpb24gR2V0TWV0aG9kKFYsIFApIHtcbiAgICAgICAgICAgIHZhciBmdW5jID0gVltQXTtcbiAgICAgICAgICAgIGlmIChmdW5jID09PSB1bmRlZmluZWQgfHwgZnVuYyA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKCFJc0NhbGxhYmxlKGZ1bmMpKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIHJldHVybiBmdW5jO1xuICAgICAgICB9XG4gICAgICAgIC8vIDcuNCBPcGVyYXRpb25zIG9uIEl0ZXJhdG9yIE9iamVjdHNcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtb3BlcmF0aW9ucy1vbi1pdGVyYXRvci1vYmplY3RzXG4gICAgICAgIGZ1bmN0aW9uIEdldEl0ZXJhdG9yKG9iaikge1xuICAgICAgICAgICAgdmFyIG1ldGhvZCA9IEdldE1ldGhvZChvYmosIGl0ZXJhdG9yU3ltYm9sKTtcbiAgICAgICAgICAgIGlmICghSXNDYWxsYWJsZShtZXRob2QpKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsgLy8gZnJvbSBDYWxsXG4gICAgICAgICAgICB2YXIgaXRlcmF0b3IgPSBtZXRob2QuY2FsbChvYmopO1xuICAgICAgICAgICAgaWYgKCFJc09iamVjdChpdGVyYXRvcikpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yO1xuICAgICAgICB9XG4gICAgICAgIC8vIDcuNC40IEl0ZXJhdG9yVmFsdWUoaXRlclJlc3VsdClcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLzIwMTYvI3NlYy1pdGVyYXRvcnZhbHVlXG4gICAgICAgIGZ1bmN0aW9uIEl0ZXJhdG9yVmFsdWUoaXRlclJlc3VsdCkge1xuICAgICAgICAgICAgcmV0dXJuIGl0ZXJSZXN1bHQudmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy40LjUgSXRlcmF0b3JTdGVwKGl0ZXJhdG9yKVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1pdGVyYXRvcnN0ZXBcbiAgICAgICAgZnVuY3Rpb24gSXRlcmF0b3JTdGVwKGl0ZXJhdG9yKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5kb25lID8gZmFsc2UgOiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy40LjYgSXRlcmF0b3JDbG9zZShpdGVyYXRvciwgY29tcGxldGlvbilcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtaXRlcmF0b3JjbG9zZVxuICAgICAgICBmdW5jdGlvbiBJdGVyYXRvckNsb3NlKGl0ZXJhdG9yKSB7XG4gICAgICAgICAgICB2YXIgZiA9IGl0ZXJhdG9yW1wicmV0dXJuXCJdO1xuICAgICAgICAgICAgaWYgKGYpXG4gICAgICAgICAgICAgICAgZi5jYWxsKGl0ZXJhdG9yKTtcbiAgICAgICAgfVxuICAgICAgICAvLyA5LjEgT3JkaW5hcnkgT2JqZWN0IEludGVybmFsIE1ldGhvZHMgYW5kIEludGVybmFsIFNsb3RzXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLW9yZGluYXJ5LW9iamVjdC1pbnRlcm5hbC1tZXRob2RzLWFuZC1pbnRlcm5hbC1zbG90c1xuICAgICAgICAvLyA5LjEuMS4xIE9yZGluYXJ5R2V0UHJvdG90eXBlT2YoTylcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtb3JkaW5hcnlnZXRwcm90b3R5cGVvZlxuICAgICAgICBmdW5jdGlvbiBPcmRpbmFyeUdldFByb3RvdHlwZU9mKE8pIHtcbiAgICAgICAgICAgIHZhciBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihPKTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgTyAhPT0gXCJmdW5jdGlvblwiIHx8IE8gPT09IGZ1bmN0aW9uUHJvdG90eXBlKVxuICAgICAgICAgICAgICAgIHJldHVybiBwcm90bztcbiAgICAgICAgICAgIC8vIFR5cGVTY3JpcHQgZG9lc24ndCBzZXQgX19wcm90b19fIGluIEVTNSwgYXMgaXQncyBub24tc3RhbmRhcmQuXG4gICAgICAgICAgICAvLyBUcnkgdG8gZGV0ZXJtaW5lIHRoZSBzdXBlcmNsYXNzIGNvbnN0cnVjdG9yLiBDb21wYXRpYmxlIGltcGxlbWVudGF0aW9uc1xuICAgICAgICAgICAgLy8gbXVzdCBlaXRoZXIgc2V0IF9fcHJvdG9fXyBvbiBhIHN1YmNsYXNzIGNvbnN0cnVjdG9yIHRvIHRoZSBzdXBlcmNsYXNzIGNvbnN0cnVjdG9yLFxuICAgICAgICAgICAgLy8gb3IgZW5zdXJlIGVhY2ggY2xhc3MgaGFzIGEgdmFsaWQgYGNvbnN0cnVjdG9yYCBwcm9wZXJ0eSBvbiBpdHMgcHJvdG90eXBlIHRoYXRcbiAgICAgICAgICAgIC8vIHBvaW50cyBiYWNrIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgbm90IHRoZSBzYW1lIGFzIEZ1bmN0aW9uLltbUHJvdG90eXBlXV0sIHRoZW4gdGhpcyBpcyBkZWZpbmF0ZWx5IGluaGVyaXRlZC5cbiAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIGNhc2Ugd2hlbiBpbiBFUzYgb3Igd2hlbiB1c2luZyBfX3Byb3RvX18gaW4gYSBjb21wYXRpYmxlIGJyb3dzZXIuXG4gICAgICAgICAgICBpZiAocHJvdG8gIT09IGZ1bmN0aW9uUHJvdG90eXBlKVxuICAgICAgICAgICAgICAgIHJldHVybiBwcm90bztcbiAgICAgICAgICAgIC8vIElmIHRoZSBzdXBlciBwcm90b3R5cGUgaXMgT2JqZWN0LnByb3RvdHlwZSwgbnVsbCwgb3IgdW5kZWZpbmVkLCB0aGVuIHdlIGNhbm5vdCBkZXRlcm1pbmUgdGhlIGhlcml0YWdlLlxuICAgICAgICAgICAgdmFyIHByb3RvdHlwZSA9IE8ucHJvdG90eXBlO1xuICAgICAgICAgICAgdmFyIHByb3RvdHlwZVByb3RvID0gcHJvdG90eXBlICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90b3R5cGUpO1xuICAgICAgICAgICAgaWYgKHByb3RvdHlwZVByb3RvID09IG51bGwgfHwgcHJvdG90eXBlUHJvdG8gPT09IE9iamVjdC5wcm90b3R5cGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb3RvO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGNvbnN0cnVjdG9yIHdhcyBub3QgYSBmdW5jdGlvbiwgdGhlbiB3ZSBjYW5ub3QgZGV0ZXJtaW5lIHRoZSBoZXJpdGFnZS5cbiAgICAgICAgICAgIHZhciBjb25zdHJ1Y3RvciA9IHByb3RvdHlwZVByb3RvLmNvbnN0cnVjdG9yO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjb25zdHJ1Y3RvciAhPT0gXCJmdW5jdGlvblwiKVxuICAgICAgICAgICAgICAgIHJldHVybiBwcm90bztcbiAgICAgICAgICAgIC8vIElmIHdlIGhhdmUgc29tZSBraW5kIG9mIHNlbGYtcmVmZXJlbmNlLCB0aGVuIHdlIGNhbm5vdCBkZXRlcm1pbmUgdGhlIGhlcml0YWdlLlxuICAgICAgICAgICAgaWYgKGNvbnN0cnVjdG9yID09PSBPKVxuICAgICAgICAgICAgICAgIHJldHVybiBwcm90bztcbiAgICAgICAgICAgIC8vIHdlIGhhdmUgYSBwcmV0dHkgZ29vZCBndWVzcyBhdCB0aGUgaGVyaXRhZ2UuXG4gICAgICAgICAgICByZXR1cm4gY29uc3RydWN0b3I7XG4gICAgICAgIH1cbiAgICAgICAgLy8gbmFpdmUgTWFwIHNoaW1cbiAgICAgICAgZnVuY3Rpb24gQ3JlYXRlTWFwUG9seWZpbGwoKSB7XG4gICAgICAgICAgICB2YXIgY2FjaGVTZW50aW5lbCA9IHt9O1xuICAgICAgICAgICAgdmFyIGFycmF5U2VudGluZWwgPSBbXTtcbiAgICAgICAgICAgIHZhciBNYXBJdGVyYXRvciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBNYXBJdGVyYXRvcihrZXlzLCB2YWx1ZXMsIHNlbGVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2luZGV4ID0gMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5cyA9IGtleXM7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlcyA9IHZhbHVlcztcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgTWFwSXRlcmF0b3IucHJvdG90eXBlW1wiQEBpdGVyYXRvclwiXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH07XG4gICAgICAgICAgICAgICAgTWFwSXRlcmF0b3IucHJvdG90eXBlW2l0ZXJhdG9yU3ltYm9sXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH07XG4gICAgICAgICAgICAgICAgTWFwSXRlcmF0b3IucHJvdG90eXBlLm5leHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IHRoaXMuX2luZGV4O1xuICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IHRoaXMuX2tleXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gdGhpcy5fc2VsZWN0b3IodGhpcy5fa2V5c1tpbmRleF0sIHRoaXMuX3ZhbHVlc1tpbmRleF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ICsgMSA+PSB0aGlzLl9rZXlzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2luZGV4ID0gLTE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5cyA9IGFycmF5U2VudGluZWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWVzID0gYXJyYXlTZW50aW5lbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2luZGV4Kys7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogcmVzdWx0LCBkb25lOiBmYWxzZSB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWUgfTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIE1hcEl0ZXJhdG9yLnByb3RvdHlwZS50aHJvdyA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5faW5kZXggPj0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faW5kZXggPSAtMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleXMgPSBhcnJheVNlbnRpbmVsO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWVzID0gYXJyYXlTZW50aW5lbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIE1hcEl0ZXJhdG9yLnByb3RvdHlwZS5yZXR1cm4gPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2luZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2luZGV4ID0gLTE7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlzID0gYXJyYXlTZW50aW5lbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlcyA9IGFycmF5U2VudGluZWw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IHZhbHVlLCBkb25lOiB0cnVlIH07XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gTWFwSXRlcmF0b3I7XG4gICAgICAgICAgICB9KCkpO1xuICAgICAgICAgICAgcmV0dXJuIC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBNYXAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWVzID0gW107XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NhY2hlS2V5ID0gY2FjaGVTZW50aW5lbDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2FjaGVJbmRleCA9IC0yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoTWFwLnByb3RvdHlwZSwgXCJzaXplXCIsIHtcbiAgICAgICAgICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLl9rZXlzLmxlbmd0aDsgfSxcbiAgICAgICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgTWFwLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAoa2V5KSB7IHJldHVybiB0aGlzLl9maW5kKGtleSwgLyppbnNlcnQqLyBmYWxzZSkgPj0gMDsgfTtcbiAgICAgICAgICAgICAgICBNYXAucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5fZmluZChrZXksIC8qaW5zZXJ0Ki8gZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5kZXggPj0gMCA/IHRoaXMuX3ZhbHVlc1tpbmRleF0gOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBNYXAucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IHRoaXMuX2ZpbmQoa2V5LCAvKmluc2VydCovIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXNbaW5kZXhdID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgTWFwLnByb3RvdHlwZS5kZWxldGUgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IHRoaXMuX2ZpbmQoa2V5LCAvKmluc2VydCovIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzaXplID0gdGhpcy5fa2V5cy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gaW5kZXggKyAxOyBpIDwgc2l6ZTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5c1tpIC0gMV0gPSB0aGlzLl9rZXlzW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlc1tpIC0gMV0gPSB0aGlzLl92YWx1ZXNbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlzLmxlbmd0aC0tO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWVzLmxlbmd0aC0tO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGtleSA9PT0gdGhpcy5fY2FjaGVLZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZUtleSA9IGNhY2hlU2VudGluZWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2FjaGVJbmRleCA9IC0yO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgTWFwLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5cy5sZW5ndGggPSAwO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXMubGVuZ3RoID0gMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2FjaGVLZXkgPSBjYWNoZVNlbnRpbmVsO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZUluZGV4ID0gLTI7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBNYXAucHJvdG90eXBlLmtleXMgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBuZXcgTWFwSXRlcmF0b3IodGhpcy5fa2V5cywgdGhpcy5fdmFsdWVzLCBnZXRLZXkpOyB9O1xuICAgICAgICAgICAgICAgIE1hcC5wcm90b3R5cGUudmFsdWVzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gbmV3IE1hcEl0ZXJhdG9yKHRoaXMuX2tleXMsIHRoaXMuX3ZhbHVlcywgZ2V0VmFsdWUpOyB9O1xuICAgICAgICAgICAgICAgIE1hcC5wcm90b3R5cGUuZW50cmllcyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ldyBNYXBJdGVyYXRvcih0aGlzLl9rZXlzLCB0aGlzLl92YWx1ZXMsIGdldEVudHJ5KTsgfTtcbiAgICAgICAgICAgICAgICBNYXAucHJvdG90eXBlW1wiQEBpdGVyYXRvclwiXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuZW50cmllcygpOyB9O1xuICAgICAgICAgICAgICAgIE1hcC5wcm90b3R5cGVbaXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5lbnRyaWVzKCk7IH07XG4gICAgICAgICAgICAgICAgTWFwLnByb3RvdHlwZS5fZmluZCA9IGZ1bmN0aW9uIChrZXksIGluc2VydCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fY2FjaGVLZXkgIT09IGtleSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2FjaGVJbmRleCA9IHRoaXMuX2tleXMuaW5kZXhPZih0aGlzLl9jYWNoZUtleSA9IGtleSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2NhY2hlSW5kZXggPCAwICYmIGluc2VydCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2FjaGVJbmRleCA9IHRoaXMuX2tleXMubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5cy5wdXNoKGtleSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXMucHVzaCh1bmRlZmluZWQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9jYWNoZUluZGV4O1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIE1hcDtcbiAgICAgICAgICAgIH0oKSk7XG4gICAgICAgICAgICBmdW5jdGlvbiBnZXRLZXkoa2V5LCBfKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGtleTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZ1bmN0aW9uIGdldFZhbHVlKF8sIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZnVuY3Rpb24gZ2V0RW50cnkoa2V5LCB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBba2V5LCB2YWx1ZV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gbmFpdmUgU2V0IHNoaW1cbiAgICAgICAgZnVuY3Rpb24gQ3JlYXRlU2V0UG9seWZpbGwoKSB7XG4gICAgICAgICAgICByZXR1cm4gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIFNldCgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWFwID0gbmV3IF9NYXAoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFNldC5wcm90b3R5cGUsIFwic2l6ZVwiLCB7XG4gICAgICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5fbWFwLnNpemU7IH0sXG4gICAgICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIFNldC5wcm90b3R5cGUuaGFzID0gZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiB0aGlzLl9tYXAuaGFzKHZhbHVlKTsgfTtcbiAgICAgICAgICAgICAgICBTZXQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gdGhpcy5fbWFwLnNldCh2YWx1ZSwgdmFsdWUpLCB0aGlzOyB9O1xuICAgICAgICAgICAgICAgIFNldC5wcm90b3R5cGUuZGVsZXRlID0gZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiB0aGlzLl9tYXAuZGVsZXRlKHZhbHVlKTsgfTtcbiAgICAgICAgICAgICAgICBTZXQucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkgeyB0aGlzLl9tYXAuY2xlYXIoKTsgfTtcbiAgICAgICAgICAgICAgICBTZXQucHJvdG90eXBlLmtleXMgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLl9tYXAua2V5cygpOyB9O1xuICAgICAgICAgICAgICAgIFNldC5wcm90b3R5cGUudmFsdWVzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5fbWFwLnZhbHVlcygpOyB9O1xuICAgICAgICAgICAgICAgIFNldC5wcm90b3R5cGUuZW50cmllcyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuX21hcC5lbnRyaWVzKCk7IH07XG4gICAgICAgICAgICAgICAgU2V0LnByb3RvdHlwZVtcIkBAaXRlcmF0b3JcIl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLmtleXMoKTsgfTtcbiAgICAgICAgICAgICAgICBTZXQucHJvdG90eXBlW2l0ZXJhdG9yU3ltYm9sXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMua2V5cygpOyB9O1xuICAgICAgICAgICAgICAgIHJldHVybiBTZXQ7XG4gICAgICAgICAgICB9KCkpO1xuICAgICAgICB9XG4gICAgICAgIC8vIG5haXZlIFdlYWtNYXAgc2hpbVxuICAgICAgICBmdW5jdGlvbiBDcmVhdGVXZWFrTWFwUG9seWZpbGwoKSB7XG4gICAgICAgICAgICB2YXIgVVVJRF9TSVpFID0gMTY7XG4gICAgICAgICAgICB2YXIga2V5cyA9IEhhc2hNYXAuY3JlYXRlKCk7XG4gICAgICAgICAgICB2YXIgcm9vdEtleSA9IENyZWF0ZVVuaXF1ZUtleSgpO1xuICAgICAgICAgICAgcmV0dXJuIC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBXZWFrTWFwKCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXkgPSBDcmVhdGVVbmlxdWVLZXkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgV2Vha01hcC5wcm90b3R5cGUuaGFzID0gZnVuY3Rpb24gKHRhcmdldCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdGFibGUgPSBHZXRPckNyZWF0ZVdlYWtNYXBUYWJsZSh0YXJnZXQsIC8qY3JlYXRlKi8gZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGFibGUgIT09IHVuZGVmaW5lZCA/IEhhc2hNYXAuaGFzKHRhYmxlLCB0aGlzLl9rZXkpIDogZmFsc2U7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBXZWFrTWFwLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAodGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0YWJsZSA9IEdldE9yQ3JlYXRlV2Vha01hcFRhYmxlKHRhcmdldCwgLypjcmVhdGUqLyBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0YWJsZSAhPT0gdW5kZWZpbmVkID8gSGFzaE1hcC5nZXQodGFibGUsIHRoaXMuX2tleSkgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBXZWFrTWFwLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAodGFyZ2V0LCB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdGFibGUgPSBHZXRPckNyZWF0ZVdlYWtNYXBUYWJsZSh0YXJnZXQsIC8qY3JlYXRlKi8gdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHRhYmxlW3RoaXMuX2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBXZWFrTWFwLnByb3RvdHlwZS5kZWxldGUgPSBmdW5jdGlvbiAodGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0YWJsZSA9IEdldE9yQ3JlYXRlV2Vha01hcFRhYmxlKHRhcmdldCwgLypjcmVhdGUqLyBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0YWJsZSAhPT0gdW5kZWZpbmVkID8gZGVsZXRlIHRhYmxlW3RoaXMuX2tleV0gOiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIFdlYWtNYXAucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBOT1RFOiBub3QgYSByZWFsIGNsZWFyLCBqdXN0IG1ha2VzIHRoZSBwcmV2aW91cyBkYXRhIHVucmVhY2hhYmxlXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleSA9IENyZWF0ZVVuaXF1ZUtleSgpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIFdlYWtNYXA7XG4gICAgICAgICAgICB9KCkpO1xuICAgICAgICAgICAgZnVuY3Rpb24gQ3JlYXRlVW5pcXVlS2V5KCkge1xuICAgICAgICAgICAgICAgIHZhciBrZXk7XG4gICAgICAgICAgICAgICAgZG9cbiAgICAgICAgICAgICAgICAgICAga2V5ID0gXCJAQFdlYWtNYXBAQFwiICsgQ3JlYXRlVVVJRCgpO1xuICAgICAgICAgICAgICAgIHdoaWxlIChIYXNoTWFwLmhhcyhrZXlzLCBrZXkpKTtcbiAgICAgICAgICAgICAgICBrZXlzW2tleV0gPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJldHVybiBrZXk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmdW5jdGlvbiBHZXRPckNyZWF0ZVdlYWtNYXBUYWJsZSh0YXJnZXQsIGNyZWF0ZSkge1xuICAgICAgICAgICAgICAgIGlmICghaGFzT3duLmNhbGwodGFyZ2V0LCByb290S2V5KSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWNyZWF0ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHJvb3RLZXksIHsgdmFsdWU6IEhhc2hNYXAuY3JlYXRlKCkgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0YXJnZXRbcm9vdEtleV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmdW5jdGlvbiBGaWxsUmFuZG9tQnl0ZXMoYnVmZmVyLCBzaXplKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlcltpXSA9IE1hdGgucmFuZG9tKCkgKiAweGZmIHwgMDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYnVmZmVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZnVuY3Rpb24gR2VuUmFuZG9tQnl0ZXMoc2l6ZSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgVWludDhBcnJheSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY3J5cHRvICE9PSBcInVuZGVmaW5lZFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQ4QXJyYXkoc2l6ZSkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1zQ3J5cHRvICE9PSBcInVuZGVmaW5lZFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyhuZXcgVWludDhBcnJheShzaXplKSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGaWxsUmFuZG9tQnl0ZXMobmV3IFVpbnQ4QXJyYXkoc2l6ZSksIHNpemUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gRmlsbFJhbmRvbUJ5dGVzKG5ldyBBcnJheShzaXplKSwgc2l6ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmdW5jdGlvbiBDcmVhdGVVVUlEKCkge1xuICAgICAgICAgICAgICAgIHZhciBkYXRhID0gR2VuUmFuZG9tQnl0ZXMoVVVJRF9TSVpFKTtcbiAgICAgICAgICAgICAgICAvLyBtYXJrIGFzIHJhbmRvbSAtIFJGQyA0MTIyIMKnIDQuNFxuICAgICAgICAgICAgICAgIGRhdGFbNl0gPSBkYXRhWzZdICYgMHg0ZiB8IDB4NDA7XG4gICAgICAgICAgICAgICAgZGF0YVs4XSA9IGRhdGFbOF0gJiAweGJmIHwgMHg4MDtcbiAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBvZmZzZXQgPSAwOyBvZmZzZXQgPCBVVUlEX1NJWkU7ICsrb2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBieXRlID0gZGF0YVtvZmZzZXRdO1xuICAgICAgICAgICAgICAgICAgICBpZiAob2Zmc2V0ID09PSA0IHx8IG9mZnNldCA9PT0gNiB8fCBvZmZzZXQgPT09IDgpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gXCItXCI7XG4gICAgICAgICAgICAgICAgICAgIGlmIChieXRlIDwgMTYpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gXCIwXCI7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCArPSBieXRlLnRvU3RyaW5nKDE2KS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIHVzZXMgYSBoZXVyaXN0aWMgdXNlZCBieSB2OCBhbmQgY2hha3JhIHRvIGZvcmNlIGFuIG9iamVjdCBpbnRvIGRpY3Rpb25hcnkgbW9kZS5cbiAgICAgICAgZnVuY3Rpb24gTWFrZURpY3Rpb25hcnkob2JqKSB7XG4gICAgICAgICAgICBvYmouX18gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBkZWxldGUgb2JqLl9fO1xuICAgICAgICAgICAgcmV0dXJuIG9iajtcbiAgICAgICAgfVxuICAgIH0pO1xufSkoUmVmbGVjdCB8fCAoUmVmbGVjdCA9IHt9KSk7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNtcCAoYSwgYikge1xuICAgIHZhciBwYSA9IGEuc3BsaXQoJy4nKTtcbiAgICB2YXIgcGIgPSBiLnNwbGl0KCcuJyk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAzOyBpKyspIHtcbiAgICAgICAgdmFyIG5hID0gTnVtYmVyKHBhW2ldKTtcbiAgICAgICAgdmFyIG5iID0gTnVtYmVyKHBiW2ldKTtcbiAgICAgICAgaWYgKG5hID4gbmIpIHJldHVybiAxO1xuICAgICAgICBpZiAobmIgPiBuYSkgcmV0dXJuIC0xO1xuICAgICAgICBpZiAoIWlzTmFOKG5hKSAmJiBpc05hTihuYikpIHJldHVybiAxO1xuICAgICAgICBpZiAoaXNOYU4obmEpICYmICFpc05hTihuYikpIHJldHVybiAtMTtcbiAgICB9XG4gICAgcmV0dXJuIDA7XG59O1xuIiwiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gU2VtVmVyXG5cbnZhciBkZWJ1Z1xuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmlmICh0eXBlb2YgcHJvY2VzcyA9PT0gJ29iamVjdCcgJiZcbiAgICBwcm9jZXNzLmVudiAmJlxuICAgIHByb2Nlc3MuZW52Lk5PREVfREVCVUcgJiZcbiAgICAvXFxic2VtdmVyXFxiL2kudGVzdChwcm9jZXNzLmVudi5OT0RFX0RFQlVHKSkge1xuICBkZWJ1ZyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMClcbiAgICBhcmdzLnVuc2hpZnQoJ1NFTVZFUicpXG4gICAgY29uc29sZS5sb2cuYXBwbHkoY29uc29sZSwgYXJncylcbiAgfVxufSBlbHNlIHtcbiAgZGVidWcgPSBmdW5jdGlvbiAoKSB7fVxufVxuXG4vLyBOb3RlOiB0aGlzIGlzIHRoZSBzZW12ZXIub3JnIHZlcnNpb24gb2YgdGhlIHNwZWMgdGhhdCBpdCBpbXBsZW1lbnRzXG4vLyBOb3QgbmVjZXNzYXJpbHkgdGhlIHBhY2thZ2UgdmVyc2lvbiBvZiB0aGlzIGNvZGUuXG5leHBvcnRzLlNFTVZFUl9TUEVDX1ZFUlNJT04gPSAnMi4wLjAnXG5cbnZhciBNQVhfTEVOR1RIID0gMjU2XG52YXIgTUFYX1NBRkVfSU5URUdFUiA9IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSIHx8XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIDkwMDcxOTkyNTQ3NDA5OTFcblxuLy8gTWF4IHNhZmUgc2VnbWVudCBsZW5ndGggZm9yIGNvZXJjaW9uLlxudmFyIE1BWF9TQUZFX0NPTVBPTkVOVF9MRU5HVEggPSAxNlxuXG4vLyBUaGUgYWN0dWFsIHJlZ2V4cHMgZ28gb24gZXhwb3J0cy5yZVxudmFyIHJlID0gZXhwb3J0cy5yZSA9IFtdXG52YXIgc3JjID0gZXhwb3J0cy5zcmMgPSBbXVxudmFyIFIgPSAwXG5cbi8vIFRoZSBmb2xsb3dpbmcgUmVndWxhciBFeHByZXNzaW9ucyBjYW4gYmUgdXNlZCBmb3IgdG9rZW5pemluZyxcbi8vIHZhbGlkYXRpbmcsIGFuZCBwYXJzaW5nIFNlbVZlciB2ZXJzaW9uIHN0cmluZ3MuXG5cbi8vICMjIE51bWVyaWMgSWRlbnRpZmllclxuLy8gQSBzaW5nbGUgYDBgLCBvciBhIG5vbi16ZXJvIGRpZ2l0IGZvbGxvd2VkIGJ5IHplcm8gb3IgbW9yZSBkaWdpdHMuXG5cbnZhciBOVU1FUklDSURFTlRJRklFUiA9IFIrK1xuc3JjW05VTUVSSUNJREVOVElGSUVSXSA9ICcwfFsxLTldXFxcXGQqJ1xudmFyIE5VTUVSSUNJREVOVElGSUVSTE9PU0UgPSBSKytcbnNyY1tOVU1FUklDSURFTlRJRklFUkxPT1NFXSA9ICdbMC05XSsnXG5cbi8vICMjIE5vbi1udW1lcmljIElkZW50aWZpZXJcbi8vIFplcm8gb3IgbW9yZSBkaWdpdHMsIGZvbGxvd2VkIGJ5IGEgbGV0dGVyIG9yIGh5cGhlbiwgYW5kIHRoZW4gemVybyBvclxuLy8gbW9yZSBsZXR0ZXJzLCBkaWdpdHMsIG9yIGh5cGhlbnMuXG5cbnZhciBOT05OVU1FUklDSURFTlRJRklFUiA9IFIrK1xuc3JjW05PTk5VTUVSSUNJREVOVElGSUVSXSA9ICdcXFxcZCpbYS16QS1aLV1bYS16QS1aMC05LV0qJ1xuXG4vLyAjIyBNYWluIFZlcnNpb25cbi8vIFRocmVlIGRvdC1zZXBhcmF0ZWQgbnVtZXJpYyBpZGVudGlmaWVycy5cblxudmFyIE1BSU5WRVJTSU9OID0gUisrXG5zcmNbTUFJTlZFUlNJT05dID0gJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSXSArICcpXFxcXC4nICtcbiAgICAgICAgICAgICAgICAgICAnKCcgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJdICsgJylcXFxcLicgK1xuICAgICAgICAgICAgICAgICAgICcoJyArIHNyY1tOVU1FUklDSURFTlRJRklFUl0gKyAnKSdcblxudmFyIE1BSU5WRVJTSU9OTE9PU0UgPSBSKytcbnNyY1tNQUlOVkVSU0lPTkxPT1NFXSA9ICcoJyArIHNyY1tOVU1FUklDSURFTlRJRklFUkxPT1NFXSArICcpXFxcXC4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcoJyArIHNyY1tOVU1FUklDSURFTlRJRklFUkxPT1NFXSArICcpXFxcXC4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcoJyArIHNyY1tOVU1FUklDSURFTlRJRklFUkxPT1NFXSArICcpJ1xuXG4vLyAjIyBQcmUtcmVsZWFzZSBWZXJzaW9uIElkZW50aWZpZXJcbi8vIEEgbnVtZXJpYyBpZGVudGlmaWVyLCBvciBhIG5vbi1udW1lcmljIGlkZW50aWZpZXIuXG5cbnZhciBQUkVSRUxFQVNFSURFTlRJRklFUiA9IFIrK1xuc3JjW1BSRVJFTEVBU0VJREVOVElGSUVSXSA9ICcoPzonICsgc3JjW05VTUVSSUNJREVOVElGSUVSXSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3wnICsgc3JjW05PTk5VTUVSSUNJREVOVElGSUVSXSArICcpJ1xuXG52YXIgUFJFUkVMRUFTRUlERU5USUZJRVJMT09TRSA9IFIrK1xuc3JjW1BSRVJFTEVBU0VJREVOVElGSUVSTE9PU0VdID0gJyg/OicgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3wnICsgc3JjW05PTk5VTUVSSUNJREVOVElGSUVSXSArICcpJ1xuXG4vLyAjIyBQcmUtcmVsZWFzZSBWZXJzaW9uXG4vLyBIeXBoZW4sIGZvbGxvd2VkIGJ5IG9uZSBvciBtb3JlIGRvdC1zZXBhcmF0ZWQgcHJlLXJlbGVhc2UgdmVyc2lvblxuLy8gaWRlbnRpZmllcnMuXG5cbnZhciBQUkVSRUxFQVNFID0gUisrXG5zcmNbUFJFUkVMRUFTRV0gPSAnKD86LSgnICsgc3JjW1BSRVJFTEVBU0VJREVOVElGSUVSXSArXG4gICAgICAgICAgICAgICAgICAnKD86XFxcXC4nICsgc3JjW1BSRVJFTEVBU0VJREVOVElGSUVSXSArICcpKikpJ1xuXG52YXIgUFJFUkVMRUFTRUxPT1NFID0gUisrXG5zcmNbUFJFUkVMRUFTRUxPT1NFXSA9ICcoPzotPygnICsgc3JjW1BSRVJFTEVBU0VJREVOVElGSUVSTE9PU0VdICtcbiAgICAgICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuJyArIHNyY1tQUkVSRUxFQVNFSURFTlRJRklFUkxPT1NFXSArICcpKikpJ1xuXG4vLyAjIyBCdWlsZCBNZXRhZGF0YSBJZGVudGlmaWVyXG4vLyBBbnkgY29tYmluYXRpb24gb2YgZGlnaXRzLCBsZXR0ZXJzLCBvciBoeXBoZW5zLlxuXG52YXIgQlVJTERJREVOVElGSUVSID0gUisrXG5zcmNbQlVJTERJREVOVElGSUVSXSA9ICdbMC05QS1aYS16LV0rJ1xuXG4vLyAjIyBCdWlsZCBNZXRhZGF0YVxuLy8gUGx1cyBzaWduLCBmb2xsb3dlZCBieSBvbmUgb3IgbW9yZSBwZXJpb2Qtc2VwYXJhdGVkIGJ1aWxkIG1ldGFkYXRhXG4vLyBpZGVudGlmaWVycy5cblxudmFyIEJVSUxEID0gUisrXG5zcmNbQlVJTERdID0gJyg/OlxcXFwrKCcgKyBzcmNbQlVJTERJREVOVElGSUVSXSArXG4gICAgICAgICAgICAgJyg/OlxcXFwuJyArIHNyY1tCVUlMRElERU5USUZJRVJdICsgJykqKSknXG5cbi8vICMjIEZ1bGwgVmVyc2lvbiBTdHJpbmdcbi8vIEEgbWFpbiB2ZXJzaW9uLCBmb2xsb3dlZCBvcHRpb25hbGx5IGJ5IGEgcHJlLXJlbGVhc2UgdmVyc2lvbiBhbmRcbi8vIGJ1aWxkIG1ldGFkYXRhLlxuXG4vLyBOb3RlIHRoYXQgdGhlIG9ubHkgbWFqb3IsIG1pbm9yLCBwYXRjaCwgYW5kIHByZS1yZWxlYXNlIHNlY3Rpb25zIG9mXG4vLyB0aGUgdmVyc2lvbiBzdHJpbmcgYXJlIGNhcHR1cmluZyBncm91cHMuICBUaGUgYnVpbGQgbWV0YWRhdGEgaXMgbm90IGFcbi8vIGNhcHR1cmluZyBncm91cCwgYmVjYXVzZSBpdCBzaG91bGQgbm90IGV2ZXIgYmUgdXNlZCBpbiB2ZXJzaW9uXG4vLyBjb21wYXJpc29uLlxuXG52YXIgRlVMTCA9IFIrK1xudmFyIEZVTExQTEFJTiA9ICd2PycgKyBzcmNbTUFJTlZFUlNJT05dICtcbiAgICAgICAgICAgICAgICBzcmNbUFJFUkVMRUFTRV0gKyAnPycgK1xuICAgICAgICAgICAgICAgIHNyY1tCVUlMRF0gKyAnPydcblxuc3JjW0ZVTExdID0gJ14nICsgRlVMTFBMQUlOICsgJyQnXG5cbi8vIGxpa2UgZnVsbCwgYnV0IGFsbG93cyB2MS4yLjMgYW5kID0xLjIuMywgd2hpY2ggcGVvcGxlIGRvIHNvbWV0aW1lcy5cbi8vIGFsc28sIDEuMC4wYWxwaGExIChwcmVyZWxlYXNlIHdpdGhvdXQgdGhlIGh5cGhlbikgd2hpY2ggaXMgcHJldHR5XG4vLyBjb21tb24gaW4gdGhlIG5wbSByZWdpc3RyeS5cbnZhciBMT09TRVBMQUlOID0gJ1t2PVxcXFxzXSonICsgc3JjW01BSU5WRVJTSU9OTE9PU0VdICtcbiAgICAgICAgICAgICAgICAgc3JjW1BSRVJFTEVBU0VMT09TRV0gKyAnPycgK1xuICAgICAgICAgICAgICAgICBzcmNbQlVJTERdICsgJz8nXG5cbnZhciBMT09TRSA9IFIrK1xuc3JjW0xPT1NFXSA9ICdeJyArIExPT1NFUExBSU4gKyAnJCdcblxudmFyIEdUTFQgPSBSKytcbnNyY1tHVExUXSA9ICcoKD86PHw+KT89PyknXG5cbi8vIFNvbWV0aGluZyBsaWtlIFwiMi4qXCIgb3IgXCIxLjIueFwiLlxuLy8gTm90ZSB0aGF0IFwieC54XCIgaXMgYSB2YWxpZCB4UmFuZ2UgaWRlbnRpZmVyLCBtZWFuaW5nIFwiYW55IHZlcnNpb25cIlxuLy8gT25seSB0aGUgZmlyc3QgaXRlbSBpcyBzdHJpY3RseSByZXF1aXJlZC5cbnZhciBYUkFOR0VJREVOVElGSUVSTE9PU0UgPSBSKytcbnNyY1tYUkFOR0VJREVOVElGSUVSTE9PU0VdID0gc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdICsgJ3x4fFh8XFxcXConXG52YXIgWFJBTkdFSURFTlRJRklFUiA9IFIrK1xuc3JjW1hSQU5HRUlERU5USUZJRVJdID0gc3JjW05VTUVSSUNJREVOVElGSUVSXSArICd8eHxYfFxcXFwqJ1xuXG52YXIgWFJBTkdFUExBSU4gPSBSKytcbnNyY1tYUkFOR0VQTEFJTl0gPSAnW3Y9XFxcXHNdKignICsgc3JjW1hSQU5HRUlERU5USUZJRVJdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAnKD86XFxcXC4oJyArIHNyY1tYUkFOR0VJREVOVElGSUVSXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuKCcgKyBzcmNbWFJBTkdFSURFTlRJRklFUl0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICcoPzonICsgc3JjW1BSRVJFTEVBU0VdICsgJyk/JyArXG4gICAgICAgICAgICAgICAgICAgc3JjW0JVSUxEXSArICc/JyArXG4gICAgICAgICAgICAgICAgICAgJyk/KT8nXG5cbnZhciBYUkFOR0VQTEFJTkxPT1NFID0gUisrXG5zcmNbWFJBTkdFUExBSU5MT09TRV0gPSAnW3Y9XFxcXHNdKignICsgc3JjW1hSQU5HRUlERU5USUZJRVJMT09TRV0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuKCcgKyBzcmNbWFJBTkdFSURFTlRJRklFUkxPT1NFXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKD86XFxcXC4oJyArIHNyY1tYUkFOR0VJREVOVElGSUVSTE9PU0VdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcoPzonICsgc3JjW1BSRVJFTEVBU0VMT09TRV0gKyAnKT8nICtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNyY1tCVUlMRF0gKyAnPycgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJyk/KT8nXG5cbnZhciBYUkFOR0UgPSBSKytcbnNyY1tYUkFOR0VdID0gJ14nICsgc3JjW0dUTFRdICsgJ1xcXFxzKicgKyBzcmNbWFJBTkdFUExBSU5dICsgJyQnXG52YXIgWFJBTkdFTE9PU0UgPSBSKytcbnNyY1tYUkFOR0VMT09TRV0gPSAnXicgKyBzcmNbR1RMVF0gKyAnXFxcXHMqJyArIHNyY1tYUkFOR0VQTEFJTkxPT1NFXSArICckJ1xuXG4vLyBDb2VyY2lvbi5cbi8vIEV4dHJhY3QgYW55dGhpbmcgdGhhdCBjb3VsZCBjb25jZWl2YWJseSBiZSBhIHBhcnQgb2YgYSB2YWxpZCBzZW12ZXJcbnZhciBDT0VSQ0UgPSBSKytcbnNyY1tDT0VSQ0VdID0gJyg/Ol58W15cXFxcZF0pJyArXG4gICAgICAgICAgICAgICcoXFxcXGR7MSwnICsgTUFYX1NBRkVfQ09NUE9ORU5UX0xFTkdUSCArICd9KScgK1xuICAgICAgICAgICAgICAnKD86XFxcXC4oXFxcXGR7MSwnICsgTUFYX1NBRkVfQ09NUE9ORU5UX0xFTkdUSCArICd9KSk/JyArXG4gICAgICAgICAgICAgICcoPzpcXFxcLihcXFxcZHsxLCcgKyBNQVhfU0FGRV9DT01QT05FTlRfTEVOR1RIICsgJ30pKT8nICtcbiAgICAgICAgICAgICAgJyg/OiR8W15cXFxcZF0pJ1xuXG4vLyBUaWxkZSByYW5nZXMuXG4vLyBNZWFuaW5nIGlzIFwicmVhc29uYWJseSBhdCBvciBncmVhdGVyIHRoYW5cIlxudmFyIExPTkVUSUxERSA9IFIrK1xuc3JjW0xPTkVUSUxERV0gPSAnKD86fj4/KSdcblxudmFyIFRJTERFVFJJTSA9IFIrK1xuc3JjW1RJTERFVFJJTV0gPSAnKFxcXFxzKiknICsgc3JjW0xPTkVUSUxERV0gKyAnXFxcXHMrJ1xucmVbVElMREVUUklNXSA9IG5ldyBSZWdFeHAoc3JjW1RJTERFVFJJTV0sICdnJylcbnZhciB0aWxkZVRyaW1SZXBsYWNlID0gJyQxfidcblxudmFyIFRJTERFID0gUisrXG5zcmNbVElMREVdID0gJ14nICsgc3JjW0xPTkVUSUxERV0gKyBzcmNbWFJBTkdFUExBSU5dICsgJyQnXG52YXIgVElMREVMT09TRSA9IFIrK1xuc3JjW1RJTERFTE9PU0VdID0gJ14nICsgc3JjW0xPTkVUSUxERV0gKyBzcmNbWFJBTkdFUExBSU5MT09TRV0gKyAnJCdcblxuLy8gQ2FyZXQgcmFuZ2VzLlxuLy8gTWVhbmluZyBpcyBcImF0IGxlYXN0IGFuZCBiYWNrd2FyZHMgY29tcGF0aWJsZSB3aXRoXCJcbnZhciBMT05FQ0FSRVQgPSBSKytcbnNyY1tMT05FQ0FSRVRdID0gJyg/OlxcXFxeKSdcblxudmFyIENBUkVUVFJJTSA9IFIrK1xuc3JjW0NBUkVUVFJJTV0gPSAnKFxcXFxzKiknICsgc3JjW0xPTkVDQVJFVF0gKyAnXFxcXHMrJ1xucmVbQ0FSRVRUUklNXSA9IG5ldyBSZWdFeHAoc3JjW0NBUkVUVFJJTV0sICdnJylcbnZhciBjYXJldFRyaW1SZXBsYWNlID0gJyQxXidcblxudmFyIENBUkVUID0gUisrXG5zcmNbQ0FSRVRdID0gJ14nICsgc3JjW0xPTkVDQVJFVF0gKyBzcmNbWFJBTkdFUExBSU5dICsgJyQnXG52YXIgQ0FSRVRMT09TRSA9IFIrK1xuc3JjW0NBUkVUTE9PU0VdID0gJ14nICsgc3JjW0xPTkVDQVJFVF0gKyBzcmNbWFJBTkdFUExBSU5MT09TRV0gKyAnJCdcblxuLy8gQSBzaW1wbGUgZ3QvbHQvZXEgdGhpbmcsIG9yIGp1c3QgXCJcIiB0byBpbmRpY2F0ZSBcImFueSB2ZXJzaW9uXCJcbnZhciBDT01QQVJBVE9STE9PU0UgPSBSKytcbnNyY1tDT01QQVJBVE9STE9PU0VdID0gJ14nICsgc3JjW0dUTFRdICsgJ1xcXFxzKignICsgTE9PU0VQTEFJTiArICcpJHxeJCdcbnZhciBDT01QQVJBVE9SID0gUisrXG5zcmNbQ09NUEFSQVRPUl0gPSAnXicgKyBzcmNbR1RMVF0gKyAnXFxcXHMqKCcgKyBGVUxMUExBSU4gKyAnKSR8XiQnXG5cbi8vIEFuIGV4cHJlc3Npb24gdG8gc3RyaXAgYW55IHdoaXRlc3BhY2UgYmV0d2VlbiB0aGUgZ3RsdCBhbmQgdGhlIHRoaW5nXG4vLyBpdCBtb2RpZmllcywgc28gdGhhdCBgPiAxLjIuM2AgPT0+IGA+MS4yLjNgXG52YXIgQ09NUEFSQVRPUlRSSU0gPSBSKytcbnNyY1tDT01QQVJBVE9SVFJJTV0gPSAnKFxcXFxzKiknICsgc3JjW0dUTFRdICtcbiAgICAgICAgICAgICAgICAgICAgICAnXFxcXHMqKCcgKyBMT09TRVBMQUlOICsgJ3wnICsgc3JjW1hSQU5HRVBMQUlOXSArICcpJ1xuXG4vLyB0aGlzIG9uZSBoYXMgdG8gdXNlIHRoZSAvZyBmbGFnXG5yZVtDT01QQVJBVE9SVFJJTV0gPSBuZXcgUmVnRXhwKHNyY1tDT01QQVJBVE9SVFJJTV0sICdnJylcbnZhciBjb21wYXJhdG9yVHJpbVJlcGxhY2UgPSAnJDEkMiQzJ1xuXG4vLyBTb21ldGhpbmcgbGlrZSBgMS4yLjMgLSAxLjIuNGBcbi8vIE5vdGUgdGhhdCB0aGVzZSBhbGwgdXNlIHRoZSBsb29zZSBmb3JtLCBiZWNhdXNlIHRoZXknbGwgYmVcbi8vIGNoZWNrZWQgYWdhaW5zdCBlaXRoZXIgdGhlIHN0cmljdCBvciBsb29zZSBjb21wYXJhdG9yIGZvcm1cbi8vIGxhdGVyLlxudmFyIEhZUEhFTlJBTkdFID0gUisrXG5zcmNbSFlQSEVOUkFOR0VdID0gJ15cXFxccyooJyArIHNyY1tYUkFOR0VQTEFJTl0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICdcXFxccystXFxcXHMrJyArXG4gICAgICAgICAgICAgICAgICAgJygnICsgc3JjW1hSQU5HRVBMQUlOXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJ1xcXFxzKiQnXG5cbnZhciBIWVBIRU5SQU5HRUxPT1NFID0gUisrXG5zcmNbSFlQSEVOUkFOR0VMT09TRV0gPSAnXlxcXFxzKignICsgc3JjW1hSQU5HRVBMQUlOTE9PU0VdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAgICAgICdcXFxccystXFxcXHMrJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKCcgKyBzcmNbWFJBTkdFUExBSU5MT09TRV0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJ1xcXFxzKiQnXG5cbi8vIFN0YXIgcmFuZ2VzIGJhc2ljYWxseSBqdXN0IGFsbG93IGFueXRoaW5nIGF0IGFsbC5cbnZhciBTVEFSID0gUisrXG5zcmNbU1RBUl0gPSAnKDx8Pik/PT9cXFxccypcXFxcKidcblxuLy8gQ29tcGlsZSB0byBhY3R1YWwgcmVnZXhwIG9iamVjdHMuXG4vLyBBbGwgYXJlIGZsYWctZnJlZSwgdW5sZXNzIHRoZXkgd2VyZSBjcmVhdGVkIGFib3ZlIHdpdGggYSBmbGFnLlxuZm9yICh2YXIgaSA9IDA7IGkgPCBSOyBpKyspIHtcbiAgZGVidWcoaSwgc3JjW2ldKVxuICBpZiAoIXJlW2ldKSB7XG4gICAgcmVbaV0gPSBuZXcgUmVnRXhwKHNyY1tpXSlcbiAgfVxufVxuXG5leHBvcnRzLnBhcnNlID0gcGFyc2VcbmZ1bmN0aW9uIHBhcnNlICh2ZXJzaW9uLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucyB8fCB0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgbG9vc2U6ICEhb3B0aW9ucyxcbiAgICAgIGluY2x1ZGVQcmVyZWxlYXNlOiBmYWxzZVxuICAgIH1cbiAgfVxuXG4gIGlmICh2ZXJzaW9uIGluc3RhbmNlb2YgU2VtVmVyKSB7XG4gICAgcmV0dXJuIHZlcnNpb25cbiAgfVxuXG4gIGlmICh0eXBlb2YgdmVyc2lvbiAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgaWYgKHZlcnNpb24ubGVuZ3RoID4gTUFYX0xFTkdUSCkge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICB2YXIgciA9IG9wdGlvbnMubG9vc2UgPyByZVtMT09TRV0gOiByZVtGVUxMXVxuICBpZiAoIXIudGVzdCh2ZXJzaW9uKSkge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICB0cnkge1xuICAgIHJldHVybiBuZXcgU2VtVmVyKHZlcnNpb24sIG9wdGlvbnMpXG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxufVxuXG5leHBvcnRzLnZhbGlkID0gdmFsaWRcbmZ1bmN0aW9uIHZhbGlkICh2ZXJzaW9uLCBvcHRpb25zKSB7XG4gIHZhciB2ID0gcGFyc2UodmVyc2lvbiwgb3B0aW9ucylcbiAgcmV0dXJuIHYgPyB2LnZlcnNpb24gOiBudWxsXG59XG5cbmV4cG9ydHMuY2xlYW4gPSBjbGVhblxuZnVuY3Rpb24gY2xlYW4gKHZlcnNpb24sIG9wdGlvbnMpIHtcbiAgdmFyIHMgPSBwYXJzZSh2ZXJzaW9uLnRyaW0oKS5yZXBsYWNlKC9eWz12XSsvLCAnJyksIG9wdGlvbnMpXG4gIHJldHVybiBzID8gcy52ZXJzaW9uIDogbnVsbFxufVxuXG5leHBvcnRzLlNlbVZlciA9IFNlbVZlclxuXG5mdW5jdGlvbiBTZW1WZXIgKHZlcnNpb24sIG9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zIHx8IHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0Jykge1xuICAgIG9wdGlvbnMgPSB7XG4gICAgICBsb29zZTogISFvcHRpb25zLFxuICAgICAgaW5jbHVkZVByZXJlbGVhc2U6IGZhbHNlXG4gICAgfVxuICB9XG4gIGlmICh2ZXJzaW9uIGluc3RhbmNlb2YgU2VtVmVyKSB7XG4gICAgaWYgKHZlcnNpb24ubG9vc2UgPT09IG9wdGlvbnMubG9vc2UpIHtcbiAgICAgIHJldHVybiB2ZXJzaW9uXG4gICAgfSBlbHNlIHtcbiAgICAgIHZlcnNpb24gPSB2ZXJzaW9uLnZlcnNpb25cbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZlcnNpb24gIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBWZXJzaW9uOiAnICsgdmVyc2lvbilcbiAgfVxuXG4gIGlmICh2ZXJzaW9uLmxlbmd0aCA+IE1BWF9MRU5HVEgpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd2ZXJzaW9uIGlzIGxvbmdlciB0aGFuICcgKyBNQVhfTEVOR1RIICsgJyBjaGFyYWN0ZXJzJylcbiAgfVxuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTZW1WZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBTZW1WZXIodmVyc2lvbiwgb3B0aW9ucylcbiAgfVxuXG4gIGRlYnVnKCdTZW1WZXInLCB2ZXJzaW9uLCBvcHRpb25zKVxuICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zXG4gIHRoaXMubG9vc2UgPSAhIW9wdGlvbnMubG9vc2VcblxuICB2YXIgbSA9IHZlcnNpb24udHJpbSgpLm1hdGNoKG9wdGlvbnMubG9vc2UgPyByZVtMT09TRV0gOiByZVtGVUxMXSlcblxuICBpZiAoIW0pIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIFZlcnNpb246ICcgKyB2ZXJzaW9uKVxuICB9XG5cbiAgdGhpcy5yYXcgPSB2ZXJzaW9uXG5cbiAgLy8gdGhlc2UgYXJlIGFjdHVhbGx5IG51bWJlcnNcbiAgdGhpcy5tYWpvciA9ICttWzFdXG4gIHRoaXMubWlub3IgPSArbVsyXVxuICB0aGlzLnBhdGNoID0gK21bM11cblxuICBpZiAodGhpcy5tYWpvciA+IE1BWF9TQUZFX0lOVEVHRVIgfHwgdGhpcy5tYWpvciA8IDApIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG1ham9yIHZlcnNpb24nKVxuICB9XG5cbiAgaWYgKHRoaXMubWlub3IgPiBNQVhfU0FGRV9JTlRFR0VSIHx8IHRoaXMubWlub3IgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBtaW5vciB2ZXJzaW9uJylcbiAgfVxuXG4gIGlmICh0aGlzLnBhdGNoID4gTUFYX1NBRkVfSU5URUdFUiB8fCB0aGlzLnBhdGNoIDwgMCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgcGF0Y2ggdmVyc2lvbicpXG4gIH1cblxuICAvLyBudW1iZXJpZnkgYW55IHByZXJlbGVhc2UgbnVtZXJpYyBpZHNcbiAgaWYgKCFtWzRdKSB7XG4gICAgdGhpcy5wcmVyZWxlYXNlID0gW11cbiAgfSBlbHNlIHtcbiAgICB0aGlzLnByZXJlbGVhc2UgPSBtWzRdLnNwbGl0KCcuJykubWFwKGZ1bmN0aW9uIChpZCkge1xuICAgICAgaWYgKC9eWzAtOV0rJC8udGVzdChpZCkpIHtcbiAgICAgICAgdmFyIG51bSA9ICtpZFxuICAgICAgICBpZiAobnVtID49IDAgJiYgbnVtIDwgTUFYX1NBRkVfSU5URUdFUikge1xuICAgICAgICAgIHJldHVybiBudW1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGlkXG4gICAgfSlcbiAgfVxuXG4gIHRoaXMuYnVpbGQgPSBtWzVdID8gbVs1XS5zcGxpdCgnLicpIDogW11cbiAgdGhpcy5mb3JtYXQoKVxufVxuXG5TZW1WZXIucHJvdG90eXBlLmZvcm1hdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy52ZXJzaW9uID0gdGhpcy5tYWpvciArICcuJyArIHRoaXMubWlub3IgKyAnLicgKyB0aGlzLnBhdGNoXG4gIGlmICh0aGlzLnByZXJlbGVhc2UubGVuZ3RoKSB7XG4gICAgdGhpcy52ZXJzaW9uICs9ICctJyArIHRoaXMucHJlcmVsZWFzZS5qb2luKCcuJylcbiAgfVxuICByZXR1cm4gdGhpcy52ZXJzaW9uXG59XG5cblNlbVZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLnZlcnNpb25cbn1cblxuU2VtVmVyLnByb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gKG90aGVyKSB7XG4gIGRlYnVnKCdTZW1WZXIuY29tcGFyZScsIHRoaXMudmVyc2lvbiwgdGhpcy5vcHRpb25zLCBvdGhlcilcbiAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZW1WZXIpKSB7XG4gICAgb3RoZXIgPSBuZXcgU2VtVmVyKG90aGVyLCB0aGlzLm9wdGlvbnMpXG4gIH1cblxuICByZXR1cm4gdGhpcy5jb21wYXJlTWFpbihvdGhlcikgfHwgdGhpcy5jb21wYXJlUHJlKG90aGVyKVxufVxuXG5TZW1WZXIucHJvdG90eXBlLmNvbXBhcmVNYWluID0gZnVuY3Rpb24gKG90aGVyKSB7XG4gIGlmICghKG90aGVyIGluc3RhbmNlb2YgU2VtVmVyKSkge1xuICAgIG90aGVyID0gbmV3IFNlbVZlcihvdGhlciwgdGhpcy5vcHRpb25zKVxuICB9XG5cbiAgcmV0dXJuIGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLm1ham9yLCBvdGhlci5tYWpvcikgfHxcbiAgICAgICAgIGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLm1pbm9yLCBvdGhlci5taW5vcikgfHxcbiAgICAgICAgIGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLnBhdGNoLCBvdGhlci5wYXRjaClcbn1cblxuU2VtVmVyLnByb3RvdHlwZS5jb21wYXJlUHJlID0gZnVuY3Rpb24gKG90aGVyKSB7XG4gIGlmICghKG90aGVyIGluc3RhbmNlb2YgU2VtVmVyKSkge1xuICAgIG90aGVyID0gbmV3IFNlbVZlcihvdGhlciwgdGhpcy5vcHRpb25zKVxuICB9XG5cbiAgLy8gTk9UIGhhdmluZyBhIHByZXJlbGVhc2UgaXMgPiBoYXZpbmcgb25lXG4gIGlmICh0aGlzLnByZXJlbGVhc2UubGVuZ3RoICYmICFvdGhlci5wcmVyZWxlYXNlLmxlbmd0aCkge1xuICAgIHJldHVybiAtMVxuICB9IGVsc2UgaWYgKCF0aGlzLnByZXJlbGVhc2UubGVuZ3RoICYmIG90aGVyLnByZXJlbGVhc2UubGVuZ3RoKSB7XG4gICAgcmV0dXJuIDFcbiAgfSBlbHNlIGlmICghdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCAmJiAhb3RoZXIucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICByZXR1cm4gMFxuICB9XG5cbiAgdmFyIGkgPSAwXG4gIGRvIHtcbiAgICB2YXIgYSA9IHRoaXMucHJlcmVsZWFzZVtpXVxuICAgIHZhciBiID0gb3RoZXIucHJlcmVsZWFzZVtpXVxuICAgIGRlYnVnKCdwcmVyZWxlYXNlIGNvbXBhcmUnLCBpLCBhLCBiKVxuICAgIGlmIChhID09PSB1bmRlZmluZWQgJiYgYiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gMFxuICAgIH0gZWxzZSBpZiAoYiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gMVxuICAgIH0gZWxzZSBpZiAoYSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gLTFcbiAgICB9IGVsc2UgaWYgKGEgPT09IGIpIHtcbiAgICAgIGNvbnRpbnVlXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjb21wYXJlSWRlbnRpZmllcnMoYSwgYilcbiAgICB9XG4gIH0gd2hpbGUgKCsraSlcbn1cblxuLy8gcHJlbWlub3Igd2lsbCBidW1wIHRoZSB2ZXJzaW9uIHVwIHRvIHRoZSBuZXh0IG1pbm9yIHJlbGVhc2UsIGFuZCBpbW1lZGlhdGVseVxuLy8gZG93biB0byBwcmUtcmVsZWFzZS4gcHJlbWFqb3IgYW5kIHByZXBhdGNoIHdvcmsgdGhlIHNhbWUgd2F5LlxuU2VtVmVyLnByb3RvdHlwZS5pbmMgPSBmdW5jdGlvbiAocmVsZWFzZSwgaWRlbnRpZmllcikge1xuICBzd2l0Y2ggKHJlbGVhc2UpIHtcbiAgICBjYXNlICdwcmVtYWpvcic6XG4gICAgICB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID0gMFxuICAgICAgdGhpcy5wYXRjaCA9IDBcbiAgICAgIHRoaXMubWlub3IgPSAwXG4gICAgICB0aGlzLm1ham9yKytcbiAgICAgIHRoaXMuaW5jKCdwcmUnLCBpZGVudGlmaWVyKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdwcmVtaW5vcic6XG4gICAgICB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID0gMFxuICAgICAgdGhpcy5wYXRjaCA9IDBcbiAgICAgIHRoaXMubWlub3IrK1xuICAgICAgdGhpcy5pbmMoJ3ByZScsIGlkZW50aWZpZXIpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3ByZXBhdGNoJzpcbiAgICAgIC8vIElmIHRoaXMgaXMgYWxyZWFkeSBhIHByZXJlbGVhc2UsIGl0IHdpbGwgYnVtcCB0byB0aGUgbmV4dCB2ZXJzaW9uXG4gICAgICAvLyBkcm9wIGFueSBwcmVyZWxlYXNlcyB0aGF0IG1pZ2h0IGFscmVhZHkgZXhpc3QsIHNpbmNlIHRoZXkgYXJlIG5vdFxuICAgICAgLy8gcmVsZXZhbnQgYXQgdGhpcyBwb2ludC5cbiAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPSAwXG4gICAgICB0aGlzLmluYygncGF0Y2gnLCBpZGVudGlmaWVyKVxuICAgICAgdGhpcy5pbmMoJ3ByZScsIGlkZW50aWZpZXIpXG4gICAgICBicmVha1xuICAgIC8vIElmIHRoZSBpbnB1dCBpcyBhIG5vbi1wcmVyZWxlYXNlIHZlcnNpb24sIHRoaXMgYWN0cyB0aGUgc2FtZSBhc1xuICAgIC8vIHByZXBhdGNoLlxuICAgIGNhc2UgJ3ByZXJlbGVhc2UnOlxuICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5pbmMoJ3BhdGNoJywgaWRlbnRpZmllcilcbiAgICAgIH1cbiAgICAgIHRoaXMuaW5jKCdwcmUnLCBpZGVudGlmaWVyKVxuICAgICAgYnJlYWtcblxuICAgIGNhc2UgJ21ham9yJzpcbiAgICAgIC8vIElmIHRoaXMgaXMgYSBwcmUtbWFqb3IgdmVyc2lvbiwgYnVtcCB1cCB0byB0aGUgc2FtZSBtYWpvciB2ZXJzaW9uLlxuICAgICAgLy8gT3RoZXJ3aXNlIGluY3JlbWVudCBtYWpvci5cbiAgICAgIC8vIDEuMC4wLTUgYnVtcHMgdG8gMS4wLjBcbiAgICAgIC8vIDEuMS4wIGJ1bXBzIHRvIDIuMC4wXG4gICAgICBpZiAodGhpcy5taW5vciAhPT0gMCB8fFxuICAgICAgICAgIHRoaXMucGF0Y2ggIT09IDAgfHxcbiAgICAgICAgICB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMubWFqb3IrK1xuICAgICAgfVxuICAgICAgdGhpcy5taW5vciA9IDBcbiAgICAgIHRoaXMucGF0Y2ggPSAwXG4gICAgICB0aGlzLnByZXJlbGVhc2UgPSBbXVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdtaW5vcic6XG4gICAgICAvLyBJZiB0aGlzIGlzIGEgcHJlLW1pbm9yIHZlcnNpb24sIGJ1bXAgdXAgdG8gdGhlIHNhbWUgbWlub3IgdmVyc2lvbi5cbiAgICAgIC8vIE90aGVyd2lzZSBpbmNyZW1lbnQgbWlub3IuXG4gICAgICAvLyAxLjIuMC01IGJ1bXBzIHRvIDEuMi4wXG4gICAgICAvLyAxLjIuMSBidW1wcyB0byAxLjMuMFxuICAgICAgaWYgKHRoaXMucGF0Y2ggIT09IDAgfHwgdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLm1pbm9yKytcbiAgICAgIH1cbiAgICAgIHRoaXMucGF0Y2ggPSAwXG4gICAgICB0aGlzLnByZXJlbGVhc2UgPSBbXVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdwYXRjaCc6XG4gICAgICAvLyBJZiB0aGlzIGlzIG5vdCBhIHByZS1yZWxlYXNlIHZlcnNpb24sIGl0IHdpbGwgaW5jcmVtZW50IHRoZSBwYXRjaC5cbiAgICAgIC8vIElmIGl0IGlzIGEgcHJlLXJlbGVhc2UgaXQgd2lsbCBidW1wIHVwIHRvIHRoZSBzYW1lIHBhdGNoIHZlcnNpb24uXG4gICAgICAvLyAxLjIuMC01IHBhdGNoZXMgdG8gMS4yLjBcbiAgICAgIC8vIDEuMi4wIHBhdGNoZXMgdG8gMS4yLjFcbiAgICAgIGlmICh0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMucGF0Y2grK1xuICAgICAgfVxuICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW11cbiAgICAgIGJyZWFrXG4gICAgLy8gVGhpcyBwcm9iYWJseSBzaG91bGRuJ3QgYmUgdXNlZCBwdWJsaWNseS5cbiAgICAvLyAxLjAuMCBcInByZVwiIHdvdWxkIGJlY29tZSAxLjAuMC0wIHdoaWNoIGlzIHRoZSB3cm9uZyBkaXJlY3Rpb24uXG4gICAgY2FzZSAncHJlJzpcbiAgICAgIGlmICh0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFswXVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGkgPSB0aGlzLnByZXJlbGVhc2UubGVuZ3RoXG4gICAgICAgIHdoaWxlICgtLWkgPj0gMCkge1xuICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcmVyZWxlYXNlW2ldID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgdGhpcy5wcmVyZWxlYXNlW2ldKytcbiAgICAgICAgICAgIGkgPSAtMlxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaSA9PT0gLTEpIHtcbiAgICAgICAgICAvLyBkaWRuJ3QgaW5jcmVtZW50IGFueXRoaW5nXG4gICAgICAgICAgdGhpcy5wcmVyZWxlYXNlLnB1c2goMClcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGlkZW50aWZpZXIpIHtcbiAgICAgICAgLy8gMS4yLjAtYmV0YS4xIGJ1bXBzIHRvIDEuMi4wLWJldGEuMixcbiAgICAgICAgLy8gMS4yLjAtYmV0YS5mb29ibHogb3IgMS4yLjAtYmV0YSBidW1wcyB0byAxLjIuMC1iZXRhLjBcbiAgICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZVswXSA9PT0gaWRlbnRpZmllcikge1xuICAgICAgICAgIGlmIChpc05hTih0aGlzLnByZXJlbGVhc2VbMV0pKSB7XG4gICAgICAgICAgICB0aGlzLnByZXJlbGVhc2UgPSBbaWRlbnRpZmllciwgMF1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW2lkZW50aWZpZXIsIDBdXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrXG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGluY3JlbWVudCBhcmd1bWVudDogJyArIHJlbGVhc2UpXG4gIH1cbiAgdGhpcy5mb3JtYXQoKVxuICB0aGlzLnJhdyA9IHRoaXMudmVyc2lvblxuICByZXR1cm4gdGhpc1xufVxuXG5leHBvcnRzLmluYyA9IGluY1xuZnVuY3Rpb24gaW5jICh2ZXJzaW9uLCByZWxlYXNlLCBsb29zZSwgaWRlbnRpZmllcikge1xuICBpZiAodHlwZW9mIChsb29zZSkgPT09ICdzdHJpbmcnKSB7XG4gICAgaWRlbnRpZmllciA9IGxvb3NlXG4gICAgbG9vc2UgPSB1bmRlZmluZWRcbiAgfVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIG5ldyBTZW1WZXIodmVyc2lvbiwgbG9vc2UpLmluYyhyZWxlYXNlLCBpZGVudGlmaWVyKS52ZXJzaW9uXG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxufVxuXG5leHBvcnRzLmRpZmYgPSBkaWZmXG5mdW5jdGlvbiBkaWZmICh2ZXJzaW9uMSwgdmVyc2lvbjIpIHtcbiAgaWYgKGVxKHZlcnNpb24xLCB2ZXJzaW9uMikpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9IGVsc2Uge1xuICAgIHZhciB2MSA9IHBhcnNlKHZlcnNpb24xKVxuICAgIHZhciB2MiA9IHBhcnNlKHZlcnNpb24yKVxuICAgIHZhciBwcmVmaXggPSAnJ1xuICAgIGlmICh2MS5wcmVyZWxlYXNlLmxlbmd0aCB8fCB2Mi5wcmVyZWxlYXNlLmxlbmd0aCkge1xuICAgICAgcHJlZml4ID0gJ3ByZSdcbiAgICAgIHZhciBkZWZhdWx0UmVzdWx0ID0gJ3ByZXJlbGVhc2UnXG4gICAgfVxuICAgIGZvciAodmFyIGtleSBpbiB2MSkge1xuICAgICAgaWYgKGtleSA9PT0gJ21ham9yJyB8fCBrZXkgPT09ICdtaW5vcicgfHwga2V5ID09PSAncGF0Y2gnKSB7XG4gICAgICAgIGlmICh2MVtrZXldICE9PSB2MltrZXldKSB7XG4gICAgICAgICAgcmV0dXJuIHByZWZpeCArIGtleVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkZWZhdWx0UmVzdWx0IC8vIG1heSBiZSB1bmRlZmluZWRcbiAgfVxufVxuXG5leHBvcnRzLmNvbXBhcmVJZGVudGlmaWVycyA9IGNvbXBhcmVJZGVudGlmaWVyc1xuXG52YXIgbnVtZXJpYyA9IC9eWzAtOV0rJC9cbmZ1bmN0aW9uIGNvbXBhcmVJZGVudGlmaWVycyAoYSwgYikge1xuICB2YXIgYW51bSA9IG51bWVyaWMudGVzdChhKVxuICB2YXIgYm51bSA9IG51bWVyaWMudGVzdChiKVxuXG4gIGlmIChhbnVtICYmIGJudW0pIHtcbiAgICBhID0gK2FcbiAgICBiID0gK2JcbiAgfVxuXG4gIHJldHVybiBhID09PSBiID8gMFxuICAgIDogKGFudW0gJiYgIWJudW0pID8gLTFcbiAgICA6IChibnVtICYmICFhbnVtKSA/IDFcbiAgICA6IGEgPCBiID8gLTFcbiAgICA6IDFcbn1cblxuZXhwb3J0cy5yY29tcGFyZUlkZW50aWZpZXJzID0gcmNvbXBhcmVJZGVudGlmaWVyc1xuZnVuY3Rpb24gcmNvbXBhcmVJZGVudGlmaWVycyAoYSwgYikge1xuICByZXR1cm4gY29tcGFyZUlkZW50aWZpZXJzKGIsIGEpXG59XG5cbmV4cG9ydHMubWFqb3IgPSBtYWpvclxuZnVuY3Rpb24gbWFqb3IgKGEsIGxvb3NlKSB7XG4gIHJldHVybiBuZXcgU2VtVmVyKGEsIGxvb3NlKS5tYWpvclxufVxuXG5leHBvcnRzLm1pbm9yID0gbWlub3JcbmZ1bmN0aW9uIG1pbm9yIChhLCBsb29zZSkge1xuICByZXR1cm4gbmV3IFNlbVZlcihhLCBsb29zZSkubWlub3Jcbn1cblxuZXhwb3J0cy5wYXRjaCA9IHBhdGNoXG5mdW5jdGlvbiBwYXRjaCAoYSwgbG9vc2UpIHtcbiAgcmV0dXJuIG5ldyBTZW1WZXIoYSwgbG9vc2UpLnBhdGNoXG59XG5cbmV4cG9ydHMuY29tcGFyZSA9IGNvbXBhcmVcbmZ1bmN0aW9uIGNvbXBhcmUgKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBuZXcgU2VtVmVyKGEsIGxvb3NlKS5jb21wYXJlKG5ldyBTZW1WZXIoYiwgbG9vc2UpKVxufVxuXG5leHBvcnRzLmNvbXBhcmVMb29zZSA9IGNvbXBhcmVMb29zZVxuZnVuY3Rpb24gY29tcGFyZUxvb3NlIChhLCBiKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIHRydWUpXG59XG5cbmV4cG9ydHMucmNvbXBhcmUgPSByY29tcGFyZVxuZnVuY3Rpb24gcmNvbXBhcmUgKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGIsIGEsIGxvb3NlKVxufVxuXG5leHBvcnRzLnNvcnQgPSBzb3J0XG5mdW5jdGlvbiBzb3J0IChsaXN0LCBsb29zZSkge1xuICByZXR1cm4gbGlzdC5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIGV4cG9ydHMuY29tcGFyZShhLCBiLCBsb29zZSlcbiAgfSlcbn1cblxuZXhwb3J0cy5yc29ydCA9IHJzb3J0XG5mdW5jdGlvbiByc29ydCAobGlzdCwgbG9vc2UpIHtcbiAgcmV0dXJuIGxpc3Quc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgIHJldHVybiBleHBvcnRzLnJjb21wYXJlKGEsIGIsIGxvb3NlKVxuICB9KVxufVxuXG5leHBvcnRzLmd0ID0gZ3RcbmZ1bmN0aW9uIGd0IChhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgPiAwXG59XG5cbmV4cG9ydHMubHQgPSBsdFxuZnVuY3Rpb24gbHQgKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSA8IDBcbn1cblxuZXhwb3J0cy5lcSA9IGVxXG5mdW5jdGlvbiBlcSAoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgbG9vc2UpID09PSAwXG59XG5cbmV4cG9ydHMubmVxID0gbmVxXG5mdW5jdGlvbiBuZXEgKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSAhPT0gMFxufVxuXG5leHBvcnRzLmd0ZSA9IGd0ZVxuZnVuY3Rpb24gZ3RlIChhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgPj0gMFxufVxuXG5leHBvcnRzLmx0ZSA9IGx0ZVxuZnVuY3Rpb24gbHRlIChhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgPD0gMFxufVxuXG5leHBvcnRzLmNtcCA9IGNtcFxuZnVuY3Rpb24gY21wIChhLCBvcCwgYiwgbG9vc2UpIHtcbiAgc3dpdGNoIChvcCkge1xuICAgIGNhc2UgJz09PSc6XG4gICAgICBpZiAodHlwZW9mIGEgPT09ICdvYmplY3QnKVxuICAgICAgICBhID0gYS52ZXJzaW9uXG4gICAgICBpZiAodHlwZW9mIGIgPT09ICdvYmplY3QnKVxuICAgICAgICBiID0gYi52ZXJzaW9uXG4gICAgICByZXR1cm4gYSA9PT0gYlxuXG4gICAgY2FzZSAnIT09JzpcbiAgICAgIGlmICh0eXBlb2YgYSA9PT0gJ29iamVjdCcpXG4gICAgICAgIGEgPSBhLnZlcnNpb25cbiAgICAgIGlmICh0eXBlb2YgYiA9PT0gJ29iamVjdCcpXG4gICAgICAgIGIgPSBiLnZlcnNpb25cbiAgICAgIHJldHVybiBhICE9PSBiXG5cbiAgICBjYXNlICcnOlxuICAgIGNhc2UgJz0nOlxuICAgIGNhc2UgJz09JzpcbiAgICAgIHJldHVybiBlcShhLCBiLCBsb29zZSlcblxuICAgIGNhc2UgJyE9JzpcbiAgICAgIHJldHVybiBuZXEoYSwgYiwgbG9vc2UpXG5cbiAgICBjYXNlICc+JzpcbiAgICAgIHJldHVybiBndChhLCBiLCBsb29zZSlcblxuICAgIGNhc2UgJz49JzpcbiAgICAgIHJldHVybiBndGUoYSwgYiwgbG9vc2UpXG5cbiAgICBjYXNlICc8JzpcbiAgICAgIHJldHVybiBsdChhLCBiLCBsb29zZSlcblxuICAgIGNhc2UgJzw9JzpcbiAgICAgIHJldHVybiBsdGUoYSwgYiwgbG9vc2UpXG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBvcGVyYXRvcjogJyArIG9wKVxuICB9XG59XG5cbmV4cG9ydHMuQ29tcGFyYXRvciA9IENvbXBhcmF0b3JcbmZ1bmN0aW9uIENvbXBhcmF0b3IgKGNvbXAsIG9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zIHx8IHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0Jykge1xuICAgIG9wdGlvbnMgPSB7XG4gICAgICBsb29zZTogISFvcHRpb25zLFxuICAgICAgaW5jbHVkZVByZXJlbGVhc2U6IGZhbHNlXG4gICAgfVxuICB9XG5cbiAgaWYgKGNvbXAgaW5zdGFuY2VvZiBDb21wYXJhdG9yKSB7XG4gICAgaWYgKGNvbXAubG9vc2UgPT09ICEhb3B0aW9ucy5sb29zZSkge1xuICAgICAgcmV0dXJuIGNvbXBcbiAgICB9IGVsc2Uge1xuICAgICAgY29tcCA9IGNvbXAudmFsdWVcbiAgICB9XG4gIH1cblxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQ29tcGFyYXRvcikpIHtcbiAgICByZXR1cm4gbmV3IENvbXBhcmF0b3IoY29tcCwgb3B0aW9ucylcbiAgfVxuXG4gIGRlYnVnKCdjb21wYXJhdG9yJywgY29tcCwgb3B0aW9ucylcbiAgdGhpcy5vcHRpb25zID0gb3B0aW9uc1xuICB0aGlzLmxvb3NlID0gISFvcHRpb25zLmxvb3NlXG4gIHRoaXMucGFyc2UoY29tcClcblxuICBpZiAodGhpcy5zZW12ZXIgPT09IEFOWSkge1xuICAgIHRoaXMudmFsdWUgPSAnJ1xuICB9IGVsc2Uge1xuICAgIHRoaXMudmFsdWUgPSB0aGlzLm9wZXJhdG9yICsgdGhpcy5zZW12ZXIudmVyc2lvblxuICB9XG5cbiAgZGVidWcoJ2NvbXAnLCB0aGlzKVxufVxuXG52YXIgQU5ZID0ge31cbkNvbXBhcmF0b3IucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24gKGNvbXApIHtcbiAgdmFyIHIgPSB0aGlzLm9wdGlvbnMubG9vc2UgPyByZVtDT01QQVJBVE9STE9PU0VdIDogcmVbQ09NUEFSQVRPUl1cbiAgdmFyIG0gPSBjb21wLm1hdGNoKHIpXG5cbiAgaWYgKCFtKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBjb21wYXJhdG9yOiAnICsgY29tcClcbiAgfVxuXG4gIHRoaXMub3BlcmF0b3IgPSBtWzFdXG4gIGlmICh0aGlzLm9wZXJhdG9yID09PSAnPScpIHtcbiAgICB0aGlzLm9wZXJhdG9yID0gJydcbiAgfVxuXG4gIC8vIGlmIGl0IGxpdGVyYWxseSBpcyBqdXN0ICc+JyBvciAnJyB0aGVuIGFsbG93IGFueXRoaW5nLlxuICBpZiAoIW1bMl0pIHtcbiAgICB0aGlzLnNlbXZlciA9IEFOWVxuICB9IGVsc2Uge1xuICAgIHRoaXMuc2VtdmVyID0gbmV3IFNlbVZlcihtWzJdLCB0aGlzLm9wdGlvbnMubG9vc2UpXG4gIH1cbn1cblxuQ29tcGFyYXRvci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLnZhbHVlXG59XG5cbkNvbXBhcmF0b3IucHJvdG90eXBlLnRlc3QgPSBmdW5jdGlvbiAodmVyc2lvbikge1xuICBkZWJ1ZygnQ29tcGFyYXRvci50ZXN0JywgdmVyc2lvbiwgdGhpcy5vcHRpb25zLmxvb3NlKVxuXG4gIGlmICh0aGlzLnNlbXZlciA9PT0gQU5ZKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIGlmICh0eXBlb2YgdmVyc2lvbiA9PT0gJ3N0cmluZycpIHtcbiAgICB2ZXJzaW9uID0gbmV3IFNlbVZlcih2ZXJzaW9uLCB0aGlzLm9wdGlvbnMpXG4gIH1cblxuICByZXR1cm4gY21wKHZlcnNpb24sIHRoaXMub3BlcmF0b3IsIHRoaXMuc2VtdmVyLCB0aGlzLm9wdGlvbnMpXG59XG5cbkNvbXBhcmF0b3IucHJvdG90eXBlLmludGVyc2VjdHMgPSBmdW5jdGlvbiAoY29tcCwgb3B0aW9ucykge1xuICBpZiAoIShjb21wIGluc3RhbmNlb2YgQ29tcGFyYXRvcikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhIENvbXBhcmF0b3IgaXMgcmVxdWlyZWQnKVxuICB9XG5cbiAgaWYgKCFvcHRpb25zIHx8IHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0Jykge1xuICAgIG9wdGlvbnMgPSB7XG4gICAgICBsb29zZTogISFvcHRpb25zLFxuICAgICAgaW5jbHVkZVByZXJlbGVhc2U6IGZhbHNlXG4gICAgfVxuICB9XG5cbiAgdmFyIHJhbmdlVG1wXG5cbiAgaWYgKHRoaXMub3BlcmF0b3IgPT09ICcnKSB7XG4gICAgcmFuZ2VUbXAgPSBuZXcgUmFuZ2UoY29tcC52YWx1ZSwgb3B0aW9ucylcbiAgICByZXR1cm4gc2F0aXNmaWVzKHRoaXMudmFsdWUsIHJhbmdlVG1wLCBvcHRpb25zKVxuICB9IGVsc2UgaWYgKGNvbXAub3BlcmF0b3IgPT09ICcnKSB7XG4gICAgcmFuZ2VUbXAgPSBuZXcgUmFuZ2UodGhpcy52YWx1ZSwgb3B0aW9ucylcbiAgICByZXR1cm4gc2F0aXNmaWVzKGNvbXAuc2VtdmVyLCByYW5nZVRtcCwgb3B0aW9ucylcbiAgfVxuXG4gIHZhciBzYW1lRGlyZWN0aW9uSW5jcmVhc2luZyA9XG4gICAgKHRoaXMub3BlcmF0b3IgPT09ICc+PScgfHwgdGhpcy5vcGVyYXRvciA9PT0gJz4nKSAmJlxuICAgIChjb21wLm9wZXJhdG9yID09PSAnPj0nIHx8IGNvbXAub3BlcmF0b3IgPT09ICc+JylcbiAgdmFyIHNhbWVEaXJlY3Rpb25EZWNyZWFzaW5nID1cbiAgICAodGhpcy5vcGVyYXRvciA9PT0gJzw9JyB8fCB0aGlzLm9wZXJhdG9yID09PSAnPCcpICYmXG4gICAgKGNvbXAub3BlcmF0b3IgPT09ICc8PScgfHwgY29tcC5vcGVyYXRvciA9PT0gJzwnKVxuICB2YXIgc2FtZVNlbVZlciA9IHRoaXMuc2VtdmVyLnZlcnNpb24gPT09IGNvbXAuc2VtdmVyLnZlcnNpb25cbiAgdmFyIGRpZmZlcmVudERpcmVjdGlvbnNJbmNsdXNpdmUgPVxuICAgICh0aGlzLm9wZXJhdG9yID09PSAnPj0nIHx8IHRoaXMub3BlcmF0b3IgPT09ICc8PScpICYmXG4gICAgKGNvbXAub3BlcmF0b3IgPT09ICc+PScgfHwgY29tcC5vcGVyYXRvciA9PT0gJzw9JylcbiAgdmFyIG9wcG9zaXRlRGlyZWN0aW9uc0xlc3NUaGFuID1cbiAgICBjbXAodGhpcy5zZW12ZXIsICc8JywgY29tcC5zZW12ZXIsIG9wdGlvbnMpICYmXG4gICAgKCh0aGlzLm9wZXJhdG9yID09PSAnPj0nIHx8IHRoaXMub3BlcmF0b3IgPT09ICc+JykgJiZcbiAgICAoY29tcC5vcGVyYXRvciA9PT0gJzw9JyB8fCBjb21wLm9wZXJhdG9yID09PSAnPCcpKVxuICB2YXIgb3Bwb3NpdGVEaXJlY3Rpb25zR3JlYXRlclRoYW4gPVxuICAgIGNtcCh0aGlzLnNlbXZlciwgJz4nLCBjb21wLnNlbXZlciwgb3B0aW9ucykgJiZcbiAgICAoKHRoaXMub3BlcmF0b3IgPT09ICc8PScgfHwgdGhpcy5vcGVyYXRvciA9PT0gJzwnKSAmJlxuICAgIChjb21wLm9wZXJhdG9yID09PSAnPj0nIHx8IGNvbXAub3BlcmF0b3IgPT09ICc+JykpXG5cbiAgcmV0dXJuIHNhbWVEaXJlY3Rpb25JbmNyZWFzaW5nIHx8IHNhbWVEaXJlY3Rpb25EZWNyZWFzaW5nIHx8XG4gICAgKHNhbWVTZW1WZXIgJiYgZGlmZmVyZW50RGlyZWN0aW9uc0luY2x1c2l2ZSkgfHxcbiAgICBvcHBvc2l0ZURpcmVjdGlvbnNMZXNzVGhhbiB8fCBvcHBvc2l0ZURpcmVjdGlvbnNHcmVhdGVyVGhhblxufVxuXG5leHBvcnRzLlJhbmdlID0gUmFuZ2VcbmZ1bmN0aW9uIFJhbmdlIChyYW5nZSwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMgfHwgdHlwZW9mIG9wdGlvbnMgIT09ICdvYmplY3QnKSB7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIGxvb3NlOiAhIW9wdGlvbnMsXG4gICAgICBpbmNsdWRlUHJlcmVsZWFzZTogZmFsc2VcbiAgICB9XG4gIH1cblxuICBpZiAocmFuZ2UgaW5zdGFuY2VvZiBSYW5nZSkge1xuICAgIGlmIChyYW5nZS5sb29zZSA9PT0gISFvcHRpb25zLmxvb3NlICYmXG4gICAgICAgIHJhbmdlLmluY2x1ZGVQcmVyZWxlYXNlID09PSAhIW9wdGlvbnMuaW5jbHVkZVByZXJlbGVhc2UpIHtcbiAgICAgIHJldHVybiByYW5nZVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbmV3IFJhbmdlKHJhbmdlLnJhdywgb3B0aW9ucylcbiAgICB9XG4gIH1cblxuICBpZiAocmFuZ2UgaW5zdGFuY2VvZiBDb21wYXJhdG9yKSB7XG4gICAgcmV0dXJuIG5ldyBSYW5nZShyYW5nZS52YWx1ZSwgb3B0aW9ucylcbiAgfVxuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBSYW5nZSkpIHtcbiAgICByZXR1cm4gbmV3IFJhbmdlKHJhbmdlLCBvcHRpb25zKVxuICB9XG5cbiAgdGhpcy5vcHRpb25zID0gb3B0aW9uc1xuICB0aGlzLmxvb3NlID0gISFvcHRpb25zLmxvb3NlXG4gIHRoaXMuaW5jbHVkZVByZXJlbGVhc2UgPSAhIW9wdGlvbnMuaW5jbHVkZVByZXJlbGVhc2VcblxuICAvLyBGaXJzdCwgc3BsaXQgYmFzZWQgb24gYm9vbGVhbiBvciB8fFxuICB0aGlzLnJhdyA9IHJhbmdlXG4gIHRoaXMuc2V0ID0gcmFuZ2Uuc3BsaXQoL1xccypcXHxcXHxcXHMqLykubWFwKGZ1bmN0aW9uIChyYW5nZSkge1xuICAgIHJldHVybiB0aGlzLnBhcnNlUmFuZ2UocmFuZ2UudHJpbSgpKVxuICB9LCB0aGlzKS5maWx0ZXIoZnVuY3Rpb24gKGMpIHtcbiAgICAvLyB0aHJvdyBvdXQgYW55IHRoYXQgYXJlIG5vdCByZWxldmFudCBmb3Igd2hhdGV2ZXIgcmVhc29uXG4gICAgcmV0dXJuIGMubGVuZ3RoXG4gIH0pXG5cbiAgaWYgKCF0aGlzLnNldC5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIFNlbVZlciBSYW5nZTogJyArIHJhbmdlKVxuICB9XG5cbiAgdGhpcy5mb3JtYXQoKVxufVxuXG5SYW5nZS5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnJhbmdlID0gdGhpcy5zZXQubWFwKGZ1bmN0aW9uIChjb21wcykge1xuICAgIHJldHVybiBjb21wcy5qb2luKCcgJykudHJpbSgpXG4gIH0pLmpvaW4oJ3x8JykudHJpbSgpXG4gIHJldHVybiB0aGlzLnJhbmdlXG59XG5cblJhbmdlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMucmFuZ2Vcbn1cblxuUmFuZ2UucHJvdG90eXBlLnBhcnNlUmFuZ2UgPSBmdW5jdGlvbiAocmFuZ2UpIHtcbiAgdmFyIGxvb3NlID0gdGhpcy5vcHRpb25zLmxvb3NlXG4gIHJhbmdlID0gcmFuZ2UudHJpbSgpXG4gIC8vIGAxLjIuMyAtIDEuMi40YCA9PiBgPj0xLjIuMyA8PTEuMi40YFxuICB2YXIgaHIgPSBsb29zZSA/IHJlW0hZUEhFTlJBTkdFTE9PU0VdIDogcmVbSFlQSEVOUkFOR0VdXG4gIHJhbmdlID0gcmFuZ2UucmVwbGFjZShociwgaHlwaGVuUmVwbGFjZSlcbiAgZGVidWcoJ2h5cGhlbiByZXBsYWNlJywgcmFuZ2UpXG4gIC8vIGA+IDEuMi4zIDwgMS4yLjVgID0+IGA+MS4yLjMgPDEuMi41YFxuICByYW5nZSA9IHJhbmdlLnJlcGxhY2UocmVbQ09NUEFSQVRPUlRSSU1dLCBjb21wYXJhdG9yVHJpbVJlcGxhY2UpXG4gIGRlYnVnKCdjb21wYXJhdG9yIHRyaW0nLCByYW5nZSwgcmVbQ09NUEFSQVRPUlRSSU1dKVxuXG4gIC8vIGB+IDEuMi4zYCA9PiBgfjEuMi4zYFxuICByYW5nZSA9IHJhbmdlLnJlcGxhY2UocmVbVElMREVUUklNXSwgdGlsZGVUcmltUmVwbGFjZSlcblxuICAvLyBgXiAxLjIuM2AgPT4gYF4xLjIuM2BcbiAgcmFuZ2UgPSByYW5nZS5yZXBsYWNlKHJlW0NBUkVUVFJJTV0sIGNhcmV0VHJpbVJlcGxhY2UpXG5cbiAgLy8gbm9ybWFsaXplIHNwYWNlc1xuICByYW5nZSA9IHJhbmdlLnNwbGl0KC9cXHMrLykuam9pbignICcpXG5cbiAgLy8gQXQgdGhpcyBwb2ludCwgdGhlIHJhbmdlIGlzIGNvbXBsZXRlbHkgdHJpbW1lZCBhbmRcbiAgLy8gcmVhZHkgdG8gYmUgc3BsaXQgaW50byBjb21wYXJhdG9ycy5cblxuICB2YXIgY29tcFJlID0gbG9vc2UgPyByZVtDT01QQVJBVE9STE9PU0VdIDogcmVbQ09NUEFSQVRPUl1cbiAgdmFyIHNldCA9IHJhbmdlLnNwbGl0KCcgJykubWFwKGZ1bmN0aW9uIChjb21wKSB7XG4gICAgcmV0dXJuIHBhcnNlQ29tcGFyYXRvcihjb21wLCB0aGlzLm9wdGlvbnMpXG4gIH0sIHRoaXMpLmpvaW4oJyAnKS5zcGxpdCgvXFxzKy8pXG4gIGlmICh0aGlzLm9wdGlvbnMubG9vc2UpIHtcbiAgICAvLyBpbiBsb29zZSBtb2RlLCB0aHJvdyBvdXQgYW55IHRoYXQgYXJlIG5vdCB2YWxpZCBjb21wYXJhdG9yc1xuICAgIHNldCA9IHNldC5maWx0ZXIoZnVuY3Rpb24gKGNvbXApIHtcbiAgICAgIHJldHVybiAhIWNvbXAubWF0Y2goY29tcFJlKVxuICAgIH0pXG4gIH1cbiAgc2V0ID0gc2V0Lm1hcChmdW5jdGlvbiAoY29tcCkge1xuICAgIHJldHVybiBuZXcgQ29tcGFyYXRvcihjb21wLCB0aGlzLm9wdGlvbnMpXG4gIH0sIHRoaXMpXG5cbiAgcmV0dXJuIHNldFxufVxuXG5SYW5nZS5wcm90b3R5cGUuaW50ZXJzZWN0cyA9IGZ1bmN0aW9uIChyYW5nZSwgb3B0aW9ucykge1xuICBpZiAoIShyYW5nZSBpbnN0YW5jZW9mIFJhbmdlKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2EgUmFuZ2UgaXMgcmVxdWlyZWQnKVxuICB9XG5cbiAgcmV0dXJuIHRoaXMuc2V0LnNvbWUoZnVuY3Rpb24gKHRoaXNDb21wYXJhdG9ycykge1xuICAgIHJldHVybiB0aGlzQ29tcGFyYXRvcnMuZXZlcnkoZnVuY3Rpb24gKHRoaXNDb21wYXJhdG9yKSB7XG4gICAgICByZXR1cm4gcmFuZ2Uuc2V0LnNvbWUoZnVuY3Rpb24gKHJhbmdlQ29tcGFyYXRvcnMpIHtcbiAgICAgICAgcmV0dXJuIHJhbmdlQ29tcGFyYXRvcnMuZXZlcnkoZnVuY3Rpb24gKHJhbmdlQ29tcGFyYXRvcikge1xuICAgICAgICAgIHJldHVybiB0aGlzQ29tcGFyYXRvci5pbnRlcnNlY3RzKHJhbmdlQ29tcGFyYXRvciwgb3B0aW9ucylcbiAgICAgICAgfSlcbiAgICAgIH0pXG4gICAgfSlcbiAgfSlcbn1cblxuLy8gTW9zdGx5IGp1c3QgZm9yIHRlc3RpbmcgYW5kIGxlZ2FjeSBBUEkgcmVhc29uc1xuZXhwb3J0cy50b0NvbXBhcmF0b3JzID0gdG9Db21wYXJhdG9yc1xuZnVuY3Rpb24gdG9Db21wYXJhdG9ycyAocmFuZ2UsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIG5ldyBSYW5nZShyYW5nZSwgb3B0aW9ucykuc2V0Lm1hcChmdW5jdGlvbiAoY29tcCkge1xuICAgIHJldHVybiBjb21wLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgcmV0dXJuIGMudmFsdWVcbiAgICB9KS5qb2luKCcgJykudHJpbSgpLnNwbGl0KCcgJylcbiAgfSlcbn1cblxuLy8gY29tcHJpc2VkIG9mIHhyYW5nZXMsIHRpbGRlcywgc3RhcnMsIGFuZCBndGx0J3MgYXQgdGhpcyBwb2ludC5cbi8vIGFscmVhZHkgcmVwbGFjZWQgdGhlIGh5cGhlbiByYW5nZXNcbi8vIHR1cm4gaW50byBhIHNldCBvZiBKVVNUIGNvbXBhcmF0b3JzLlxuZnVuY3Rpb24gcGFyc2VDb21wYXJhdG9yIChjb21wLCBvcHRpb25zKSB7XG4gIGRlYnVnKCdjb21wJywgY29tcCwgb3B0aW9ucylcbiAgY29tcCA9IHJlcGxhY2VDYXJldHMoY29tcCwgb3B0aW9ucylcbiAgZGVidWcoJ2NhcmV0JywgY29tcClcbiAgY29tcCA9IHJlcGxhY2VUaWxkZXMoY29tcCwgb3B0aW9ucylcbiAgZGVidWcoJ3RpbGRlcycsIGNvbXApXG4gIGNvbXAgPSByZXBsYWNlWFJhbmdlcyhjb21wLCBvcHRpb25zKVxuICBkZWJ1ZygneHJhbmdlJywgY29tcClcbiAgY29tcCA9IHJlcGxhY2VTdGFycyhjb21wLCBvcHRpb25zKVxuICBkZWJ1Zygnc3RhcnMnLCBjb21wKVxuICByZXR1cm4gY29tcFxufVxuXG5mdW5jdGlvbiBpc1ggKGlkKSB7XG4gIHJldHVybiAhaWQgfHwgaWQudG9Mb3dlckNhc2UoKSA9PT0gJ3gnIHx8IGlkID09PSAnKidcbn1cblxuLy8gfiwgfj4gLS0+ICogKGFueSwga2luZGEgc2lsbHkpXG4vLyB+MiwgfjIueCwgfjIueC54LCB+PjIsIH4+Mi54IH4+Mi54LnggLS0+ID49Mi4wLjAgPDMuMC4wXG4vLyB+Mi4wLCB+Mi4wLngsIH4+Mi4wLCB+PjIuMC54IC0tPiA+PTIuMC4wIDwyLjEuMFxuLy8gfjEuMiwgfjEuMi54LCB+PjEuMiwgfj4xLjIueCAtLT4gPj0xLjIuMCA8MS4zLjBcbi8vIH4xLjIuMywgfj4xLjIuMyAtLT4gPj0xLjIuMyA8MS4zLjBcbi8vIH4xLjIuMCwgfj4xLjIuMCAtLT4gPj0xLjIuMCA8MS4zLjBcbmZ1bmN0aW9uIHJlcGxhY2VUaWxkZXMgKGNvbXAsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGNvbXAudHJpbSgpLnNwbGl0KC9cXHMrLykubWFwKGZ1bmN0aW9uIChjb21wKSB7XG4gICAgcmV0dXJuIHJlcGxhY2VUaWxkZShjb21wLCBvcHRpb25zKVxuICB9KS5qb2luKCcgJylcbn1cblxuZnVuY3Rpb24gcmVwbGFjZVRpbGRlIChjb21wLCBvcHRpb25zKSB7XG4gIHZhciByID0gb3B0aW9ucy5sb29zZSA/IHJlW1RJTERFTE9PU0VdIDogcmVbVElMREVdXG4gIHJldHVybiBjb21wLnJlcGxhY2UociwgZnVuY3Rpb24gKF8sIE0sIG0sIHAsIHByKSB7XG4gICAgZGVidWcoJ3RpbGRlJywgY29tcCwgXywgTSwgbSwgcCwgcHIpXG4gICAgdmFyIHJldFxuXG4gICAgaWYgKGlzWChNKSkge1xuICAgICAgcmV0ID0gJydcbiAgICB9IGVsc2UgaWYgKGlzWChtKSkge1xuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLjAuMCA8JyArICgrTSArIDEpICsgJy4wLjAnXG4gICAgfSBlbHNlIGlmIChpc1gocCkpIHtcbiAgICAgIC8vIH4xLjIgPT0gPj0xLjIuMCA8MS4zLjBcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuMCA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCdcbiAgICB9IGVsc2UgaWYgKHByKSB7XG4gICAgICBkZWJ1ZygncmVwbGFjZVRpbGRlIHByJywgcHIpXG4gICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICsgJy0nICsgcHIgK1xuICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCdcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gfjEuMi4zID09ID49MS4yLjMgPDEuMy4wXG4gICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICtcbiAgICAgICAgICAgICcgPCcgKyBNICsgJy4nICsgKCttICsgMSkgKyAnLjAnXG4gICAgfVxuXG4gICAgZGVidWcoJ3RpbGRlIHJldHVybicsIHJldClcbiAgICByZXR1cm4gcmV0XG4gIH0pXG59XG5cbi8vIF4gLS0+ICogKGFueSwga2luZGEgc2lsbHkpXG4vLyBeMiwgXjIueCwgXjIueC54IC0tPiA+PTIuMC4wIDwzLjAuMFxuLy8gXjIuMCwgXjIuMC54IC0tPiA+PTIuMC4wIDwzLjAuMFxuLy8gXjEuMiwgXjEuMi54IC0tPiA+PTEuMi4wIDwyLjAuMFxuLy8gXjEuMi4zIC0tPiA+PTEuMi4zIDwyLjAuMFxuLy8gXjEuMi4wIC0tPiA+PTEuMi4wIDwyLjAuMFxuZnVuY3Rpb24gcmVwbGFjZUNhcmV0cyAoY29tcCwgb3B0aW9ucykge1xuICByZXR1cm4gY29tcC50cmltKCkuc3BsaXQoL1xccysvKS5tYXAoZnVuY3Rpb24gKGNvbXApIHtcbiAgICByZXR1cm4gcmVwbGFjZUNhcmV0KGNvbXAsIG9wdGlvbnMpXG4gIH0pLmpvaW4oJyAnKVxufVxuXG5mdW5jdGlvbiByZXBsYWNlQ2FyZXQgKGNvbXAsIG9wdGlvbnMpIHtcbiAgZGVidWcoJ2NhcmV0JywgY29tcCwgb3B0aW9ucylcbiAgdmFyIHIgPSBvcHRpb25zLmxvb3NlID8gcmVbQ0FSRVRMT09TRV0gOiByZVtDQVJFVF1cbiAgcmV0dXJuIGNvbXAucmVwbGFjZShyLCBmdW5jdGlvbiAoXywgTSwgbSwgcCwgcHIpIHtcbiAgICBkZWJ1ZygnY2FyZXQnLCBjb21wLCBfLCBNLCBtLCBwLCBwcilcbiAgICB2YXIgcmV0XG5cbiAgICBpZiAoaXNYKE0pKSB7XG4gICAgICByZXQgPSAnJ1xuICAgIH0gZWxzZSBpZiAoaXNYKG0pKSB7XG4gICAgICByZXQgPSAnPj0nICsgTSArICcuMC4wIDwnICsgKCtNICsgMSkgKyAnLjAuMCdcbiAgICB9IGVsc2UgaWYgKGlzWChwKSkge1xuICAgICAgaWYgKE0gPT09ICcwJykge1xuICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLjAgPCcgKyBNICsgJy4nICsgKCttICsgMSkgKyAnLjAnXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLjAgPCcgKyAoK00gKyAxKSArICcuMC4wJ1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocHIpIHtcbiAgICAgIGRlYnVnKCdyZXBsYWNlQ2FyZXQgcHInLCBwcilcbiAgICAgIGlmIChNID09PSAnMCcpIHtcbiAgICAgICAgaWYgKG0gPT09ICcwJykge1xuICAgICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgKyAnLScgKyBwciArXG4gICAgICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyBtICsgJy4nICsgKCtwICsgMSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICsgJy0nICsgcHIgK1xuICAgICAgICAgICAgICAgICcgPCcgKyBNICsgJy4nICsgKCttICsgMSkgKyAnLjAnXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgKyAnLScgKyBwciArXG4gICAgICAgICAgICAgICcgPCcgKyAoK00gKyAxKSArICcuMC4wJ1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1Zygnbm8gcHInKVxuICAgICAgaWYgKE0gPT09ICcwJykge1xuICAgICAgICBpZiAobSA9PT0gJzAnKSB7XG4gICAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArXG4gICAgICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyBtICsgJy4nICsgKCtwICsgMSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICtcbiAgICAgICAgICAgICAgICAnIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJ1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICtcbiAgICAgICAgICAgICAgJyA8JyArICgrTSArIDEpICsgJy4wLjAnXG4gICAgICB9XG4gICAgfVxuXG4gICAgZGVidWcoJ2NhcmV0IHJldHVybicsIHJldClcbiAgICByZXR1cm4gcmV0XG4gIH0pXG59XG5cbmZ1bmN0aW9uIHJlcGxhY2VYUmFuZ2VzIChjb21wLCBvcHRpb25zKSB7XG4gIGRlYnVnKCdyZXBsYWNlWFJhbmdlcycsIGNvbXAsIG9wdGlvbnMpXG4gIHJldHVybiBjb21wLnNwbGl0KC9cXHMrLykubWFwKGZ1bmN0aW9uIChjb21wKSB7XG4gICAgcmV0dXJuIHJlcGxhY2VYUmFuZ2UoY29tcCwgb3B0aW9ucylcbiAgfSkuam9pbignICcpXG59XG5cbmZ1bmN0aW9uIHJlcGxhY2VYUmFuZ2UgKGNvbXAsIG9wdGlvbnMpIHtcbiAgY29tcCA9IGNvbXAudHJpbSgpXG4gIHZhciByID0gb3B0aW9ucy5sb29zZSA/IHJlW1hSQU5HRUxPT1NFXSA6IHJlW1hSQU5HRV1cbiAgcmV0dXJuIGNvbXAucmVwbGFjZShyLCBmdW5jdGlvbiAocmV0LCBndGx0LCBNLCBtLCBwLCBwcikge1xuICAgIGRlYnVnKCd4UmFuZ2UnLCBjb21wLCByZXQsIGd0bHQsIE0sIG0sIHAsIHByKVxuICAgIHZhciB4TSA9IGlzWChNKVxuICAgIHZhciB4bSA9IHhNIHx8IGlzWChtKVxuICAgIHZhciB4cCA9IHhtIHx8IGlzWChwKVxuICAgIHZhciBhbnlYID0geHBcblxuICAgIGlmIChndGx0ID09PSAnPScgJiYgYW55WCkge1xuICAgICAgZ3RsdCA9ICcnXG4gICAgfVxuXG4gICAgaWYgKHhNKSB7XG4gICAgICBpZiAoZ3RsdCA9PT0gJz4nIHx8IGd0bHQgPT09ICc8Jykge1xuICAgICAgICAvLyBub3RoaW5nIGlzIGFsbG93ZWRcbiAgICAgICAgcmV0ID0gJzwwLjAuMCdcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG5vdGhpbmcgaXMgZm9yYmlkZGVuXG4gICAgICAgIHJldCA9ICcqJ1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZ3RsdCAmJiBhbnlYKSB7XG4gICAgICAvLyB3ZSBrbm93IHBhdGNoIGlzIGFuIHgsIGJlY2F1c2Ugd2UgaGF2ZSBhbnkgeCBhdCBhbGwuXG4gICAgICAvLyByZXBsYWNlIFggd2l0aCAwXG4gICAgICBpZiAoeG0pIHtcbiAgICAgICAgbSA9IDBcbiAgICAgIH1cbiAgICAgIHAgPSAwXG5cbiAgICAgIGlmIChndGx0ID09PSAnPicpIHtcbiAgICAgICAgLy8gPjEgPT4gPj0yLjAuMFxuICAgICAgICAvLyA+MS4yID0+ID49MS4zLjBcbiAgICAgICAgLy8gPjEuMi4zID0+ID49IDEuMi40XG4gICAgICAgIGd0bHQgPSAnPj0nXG4gICAgICAgIGlmICh4bSkge1xuICAgICAgICAgIE0gPSArTSArIDFcbiAgICAgICAgICBtID0gMFxuICAgICAgICAgIHAgPSAwXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbSA9ICttICsgMVxuICAgICAgICAgIHAgPSAwXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZ3RsdCA9PT0gJzw9Jykge1xuICAgICAgICAvLyA8PTAuNy54IGlzIGFjdHVhbGx5IDwwLjguMCwgc2luY2UgYW55IDAuNy54IHNob3VsZFxuICAgICAgICAvLyBwYXNzLiAgU2ltaWxhcmx5LCA8PTcueCBpcyBhY3R1YWxseSA8OC4wLjAsIGV0Yy5cbiAgICAgICAgZ3RsdCA9ICc8J1xuICAgICAgICBpZiAoeG0pIHtcbiAgICAgICAgICBNID0gK00gKyAxXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbSA9ICttICsgMVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldCA9IGd0bHQgKyBNICsgJy4nICsgbSArICcuJyArIHBcbiAgICB9IGVsc2UgaWYgKHhtKSB7XG4gICAgICByZXQgPSAnPj0nICsgTSArICcuMC4wIDwnICsgKCtNICsgMSkgKyAnLjAuMCdcbiAgICB9IGVsc2UgaWYgKHhwKSB7XG4gICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLjAgPCcgKyBNICsgJy4nICsgKCttICsgMSkgKyAnLjAnXG4gICAgfVxuXG4gICAgZGVidWcoJ3hSYW5nZSByZXR1cm4nLCByZXQpXG5cbiAgICByZXR1cm4gcmV0XG4gIH0pXG59XG5cbi8vIEJlY2F1c2UgKiBpcyBBTkQtZWQgd2l0aCBldmVyeXRoaW5nIGVsc2UgaW4gdGhlIGNvbXBhcmF0b3IsXG4vLyBhbmQgJycgbWVhbnMgXCJhbnkgdmVyc2lvblwiLCBqdXN0IHJlbW92ZSB0aGUgKnMgZW50aXJlbHkuXG5mdW5jdGlvbiByZXBsYWNlU3RhcnMgKGNvbXAsIG9wdGlvbnMpIHtcbiAgZGVidWcoJ3JlcGxhY2VTdGFycycsIGNvbXAsIG9wdGlvbnMpXG4gIC8vIExvb3NlbmVzcyBpcyBpZ25vcmVkIGhlcmUuICBzdGFyIGlzIGFsd2F5cyBhcyBsb29zZSBhcyBpdCBnZXRzIVxuICByZXR1cm4gY29tcC50cmltKCkucmVwbGFjZShyZVtTVEFSXSwgJycpXG59XG5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgcGFzc2VkIHRvIHN0cmluZy5yZXBsYWNlKHJlW0hZUEhFTlJBTkdFXSlcbi8vIE0sIG0sIHBhdGNoLCBwcmVyZWxlYXNlLCBidWlsZFxuLy8gMS4yIC0gMy40LjUgPT4gPj0xLjIuMCA8PTMuNC41XG4vLyAxLjIuMyAtIDMuNCA9PiA+PTEuMi4wIDwzLjUuMCBBbnkgMy40Lnggd2lsbCBkb1xuLy8gMS4yIC0gMy40ID0+ID49MS4yLjAgPDMuNS4wXG5mdW5jdGlvbiBoeXBoZW5SZXBsYWNlICgkMCxcbiAgZnJvbSwgZk0sIGZtLCBmcCwgZnByLCBmYixcbiAgdG8sIHRNLCB0bSwgdHAsIHRwciwgdGIpIHtcbiAgaWYgKGlzWChmTSkpIHtcbiAgICBmcm9tID0gJydcbiAgfSBlbHNlIGlmIChpc1goZm0pKSB7XG4gICAgZnJvbSA9ICc+PScgKyBmTSArICcuMC4wJ1xuICB9IGVsc2UgaWYgKGlzWChmcCkpIHtcbiAgICBmcm9tID0gJz49JyArIGZNICsgJy4nICsgZm0gKyAnLjAnXG4gIH0gZWxzZSB7XG4gICAgZnJvbSA9ICc+PScgKyBmcm9tXG4gIH1cblxuICBpZiAoaXNYKHRNKSkge1xuICAgIHRvID0gJydcbiAgfSBlbHNlIGlmIChpc1godG0pKSB7XG4gICAgdG8gPSAnPCcgKyAoK3RNICsgMSkgKyAnLjAuMCdcbiAgfSBlbHNlIGlmIChpc1godHApKSB7XG4gICAgdG8gPSAnPCcgKyB0TSArICcuJyArICgrdG0gKyAxKSArICcuMCdcbiAgfSBlbHNlIGlmICh0cHIpIHtcbiAgICB0byA9ICc8PScgKyB0TSArICcuJyArIHRtICsgJy4nICsgdHAgKyAnLScgKyB0cHJcbiAgfSBlbHNlIHtcbiAgICB0byA9ICc8PScgKyB0b1xuICB9XG5cbiAgcmV0dXJuIChmcm9tICsgJyAnICsgdG8pLnRyaW0oKVxufVxuXG4vLyBpZiBBTlkgb2YgdGhlIHNldHMgbWF0Y2ggQUxMIG9mIGl0cyBjb21wYXJhdG9ycywgdGhlbiBwYXNzXG5SYW5nZS5wcm90b3R5cGUudGVzdCA9IGZ1bmN0aW9uICh2ZXJzaW9uKSB7XG4gIGlmICghdmVyc2lvbikge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgaWYgKHR5cGVvZiB2ZXJzaW9uID09PSAnc3RyaW5nJykge1xuICAgIHZlcnNpb24gPSBuZXcgU2VtVmVyKHZlcnNpb24sIHRoaXMub3B0aW9ucylcbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zZXQubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAodGVzdFNldCh0aGlzLnNldFtpXSwgdmVyc2lvbiwgdGhpcy5vcHRpb25zKSkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlXG59XG5cbmZ1bmN0aW9uIHRlc3RTZXQgKHNldCwgdmVyc2lvbiwgb3B0aW9ucykge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHNldC5sZW5ndGg7IGkrKykge1xuICAgIGlmICghc2V0W2ldLnRlc3QodmVyc2lvbikpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgfVxuXG4gIGlmICh2ZXJzaW9uLnByZXJlbGVhc2UubGVuZ3RoICYmICFvcHRpb25zLmluY2x1ZGVQcmVyZWxlYXNlKSB7XG4gICAgLy8gRmluZCB0aGUgc2V0IG9mIHZlcnNpb25zIHRoYXQgYXJlIGFsbG93ZWQgdG8gaGF2ZSBwcmVyZWxlYXNlc1xuICAgIC8vIEZvciBleGFtcGxlLCBeMS4yLjMtcHIuMSBkZXN1Z2FycyB0byA+PTEuMi4zLXByLjEgPDIuMC4wXG4gICAgLy8gVGhhdCBzaG91bGQgYWxsb3cgYDEuMi4zLXByLjJgIHRvIHBhc3MuXG4gICAgLy8gSG93ZXZlciwgYDEuMi40LWFscGhhLm5vdHJlYWR5YCBzaG91bGQgTk9UIGJlIGFsbG93ZWQsXG4gICAgLy8gZXZlbiB0aG91Z2ggaXQncyB3aXRoaW4gdGhlIHJhbmdlIHNldCBieSB0aGUgY29tcGFyYXRvcnMuXG4gICAgZm9yIChpID0gMDsgaSA8IHNldC5sZW5ndGg7IGkrKykge1xuICAgICAgZGVidWcoc2V0W2ldLnNlbXZlcilcbiAgICAgIGlmIChzZXRbaV0uc2VtdmVyID09PSBBTlkpIHtcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKHNldFtpXS5zZW12ZXIucHJlcmVsZWFzZS5sZW5ndGggPiAwKSB7XG4gICAgICAgIHZhciBhbGxvd2VkID0gc2V0W2ldLnNlbXZlclxuICAgICAgICBpZiAoYWxsb3dlZC5tYWpvciA9PT0gdmVyc2lvbi5tYWpvciAmJlxuICAgICAgICAgICAgYWxsb3dlZC5taW5vciA9PT0gdmVyc2lvbi5taW5vciAmJlxuICAgICAgICAgICAgYWxsb3dlZC5wYXRjaCA9PT0gdmVyc2lvbi5wYXRjaCkge1xuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBWZXJzaW9uIGhhcyBhIC1wcmUsIGJ1dCBpdCdzIG5vdCBvbmUgb2YgdGhlIG9uZXMgd2UgbGlrZS5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHJldHVybiB0cnVlXG59XG5cbmV4cG9ydHMuc2F0aXNmaWVzID0gc2F0aXNmaWVzXG5mdW5jdGlvbiBzYXRpc2ZpZXMgKHZlcnNpb24sIHJhbmdlLCBvcHRpb25zKSB7XG4gIHRyeSB7XG4gICAgcmFuZ2UgPSBuZXcgUmFuZ2UocmFuZ2UsIG9wdGlvbnMpXG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbiAgcmV0dXJuIHJhbmdlLnRlc3QodmVyc2lvbilcbn1cblxuZXhwb3J0cy5tYXhTYXRpc2Z5aW5nID0gbWF4U2F0aXNmeWluZ1xuZnVuY3Rpb24gbWF4U2F0aXNmeWluZyAodmVyc2lvbnMsIHJhbmdlLCBvcHRpb25zKSB7XG4gIHZhciBtYXggPSBudWxsXG4gIHZhciBtYXhTViA9IG51bGxcbiAgdHJ5IHtcbiAgICB2YXIgcmFuZ2VPYmogPSBuZXcgUmFuZ2UocmFuZ2UsIG9wdGlvbnMpXG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuICB2ZXJzaW9ucy5mb3JFYWNoKGZ1bmN0aW9uICh2KSB7XG4gICAgaWYgKHJhbmdlT2JqLnRlc3QodikpIHtcbiAgICAgIC8vIHNhdGlzZmllcyh2LCByYW5nZSwgb3B0aW9ucylcbiAgICAgIGlmICghbWF4IHx8IG1heFNWLmNvbXBhcmUodikgPT09IC0xKSB7XG4gICAgICAgIC8vIGNvbXBhcmUobWF4LCB2LCB0cnVlKVxuICAgICAgICBtYXggPSB2XG4gICAgICAgIG1heFNWID0gbmV3IFNlbVZlcihtYXgsIG9wdGlvbnMpXG4gICAgICB9XG4gICAgfVxuICB9KVxuICByZXR1cm4gbWF4XG59XG5cbmV4cG9ydHMubWluU2F0aXNmeWluZyA9IG1pblNhdGlzZnlpbmdcbmZ1bmN0aW9uIG1pblNhdGlzZnlpbmcgKHZlcnNpb25zLCByYW5nZSwgb3B0aW9ucykge1xuICB2YXIgbWluID0gbnVsbFxuICB2YXIgbWluU1YgPSBudWxsXG4gIHRyeSB7XG4gICAgdmFyIHJhbmdlT2JqID0gbmV3IFJhbmdlKHJhbmdlLCBvcHRpb25zKVxuICB9IGNhdGNoIChlcikge1xuICAgIHJldHVybiBudWxsXG4gIH1cbiAgdmVyc2lvbnMuZm9yRWFjaChmdW5jdGlvbiAodikge1xuICAgIGlmIChyYW5nZU9iai50ZXN0KHYpKSB7XG4gICAgICAvLyBzYXRpc2ZpZXModiwgcmFuZ2UsIG9wdGlvbnMpXG4gICAgICBpZiAoIW1pbiB8fCBtaW5TVi5jb21wYXJlKHYpID09PSAxKSB7XG4gICAgICAgIC8vIGNvbXBhcmUobWluLCB2LCB0cnVlKVxuICAgICAgICBtaW4gPSB2XG4gICAgICAgIG1pblNWID0gbmV3IFNlbVZlcihtaW4sIG9wdGlvbnMpXG4gICAgICB9XG4gICAgfVxuICB9KVxuICByZXR1cm4gbWluXG59XG5cbmV4cG9ydHMubWluVmVyc2lvbiA9IG1pblZlcnNpb25cbmZ1bmN0aW9uIG1pblZlcnNpb24gKHJhbmdlLCBsb29zZSkge1xuICByYW5nZSA9IG5ldyBSYW5nZShyYW5nZSwgbG9vc2UpXG5cbiAgdmFyIG1pbnZlciA9IG5ldyBTZW1WZXIoJzAuMC4wJylcbiAgaWYgKHJhbmdlLnRlc3QobWludmVyKSkge1xuICAgIHJldHVybiBtaW52ZXJcbiAgfVxuXG4gIG1pbnZlciA9IG5ldyBTZW1WZXIoJzAuMC4wLTAnKVxuICBpZiAocmFuZ2UudGVzdChtaW52ZXIpKSB7XG4gICAgcmV0dXJuIG1pbnZlclxuICB9XG5cbiAgbWludmVyID0gbnVsbFxuICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlLnNldC5sZW5ndGg7ICsraSkge1xuICAgIHZhciBjb21wYXJhdG9ycyA9IHJhbmdlLnNldFtpXVxuXG4gICAgY29tcGFyYXRvcnMuZm9yRWFjaChmdW5jdGlvbiAoY29tcGFyYXRvcikge1xuICAgICAgLy8gQ2xvbmUgdG8gYXZvaWQgbWFuaXB1bGF0aW5nIHRoZSBjb21wYXJhdG9yJ3Mgc2VtdmVyIG9iamVjdC5cbiAgICAgIHZhciBjb21wdmVyID0gbmV3IFNlbVZlcihjb21wYXJhdG9yLnNlbXZlci52ZXJzaW9uKVxuICAgICAgc3dpdGNoIChjb21wYXJhdG9yLm9wZXJhdG9yKSB7XG4gICAgICAgIGNhc2UgJz4nOlxuICAgICAgICAgIGlmIChjb21wdmVyLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBjb21wdmVyLnBhdGNoKytcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29tcHZlci5wcmVyZWxlYXNlLnB1c2goMClcbiAgICAgICAgICB9XG4gICAgICAgICAgY29tcHZlci5yYXcgPSBjb21wdmVyLmZvcm1hdCgpXG4gICAgICAgICAgLyogZmFsbHRocm91Z2ggKi9cbiAgICAgICAgY2FzZSAnJzpcbiAgICAgICAgY2FzZSAnPj0nOlxuICAgICAgICAgIGlmICghbWludmVyIHx8IGd0KG1pbnZlciwgY29tcHZlcikpIHtcbiAgICAgICAgICAgIG1pbnZlciA9IGNvbXB2ZXJcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAnPCc6XG4gICAgICAgIGNhc2UgJzw9JzpcbiAgICAgICAgICAvKiBJZ25vcmUgbWF4aW11bSB2ZXJzaW9ucyAqL1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmV4cGVjdGVkIG9wZXJhdGlvbjogJyArIGNvbXBhcmF0b3Iub3BlcmF0b3IpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIGlmIChtaW52ZXIgJiYgcmFuZ2UudGVzdChtaW52ZXIpKSB7XG4gICAgcmV0dXJuIG1pbnZlclxuICB9XG5cbiAgcmV0dXJuIG51bGxcbn1cblxuZXhwb3J0cy52YWxpZFJhbmdlID0gdmFsaWRSYW5nZVxuZnVuY3Rpb24gdmFsaWRSYW5nZSAocmFuZ2UsIG9wdGlvbnMpIHtcbiAgdHJ5IHtcbiAgICAvLyBSZXR1cm4gJyonIGluc3RlYWQgb2YgJycgc28gdGhhdCB0cnV0aGluZXNzIHdvcmtzLlxuICAgIC8vIFRoaXMgd2lsbCB0aHJvdyBpZiBpdCdzIGludmFsaWQgYW55d2F5XG4gICAgcmV0dXJuIG5ldyBSYW5nZShyYW5nZSwgb3B0aW9ucykucmFuZ2UgfHwgJyonXG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxufVxuXG4vLyBEZXRlcm1pbmUgaWYgdmVyc2lvbiBpcyBsZXNzIHRoYW4gYWxsIHRoZSB2ZXJzaW9ucyBwb3NzaWJsZSBpbiB0aGUgcmFuZ2VcbmV4cG9ydHMubHRyID0gbHRyXG5mdW5jdGlvbiBsdHIgKHZlcnNpb24sIHJhbmdlLCBvcHRpb25zKSB7XG4gIHJldHVybiBvdXRzaWRlKHZlcnNpb24sIHJhbmdlLCAnPCcsIG9wdGlvbnMpXG59XG5cbi8vIERldGVybWluZSBpZiB2ZXJzaW9uIGlzIGdyZWF0ZXIgdGhhbiBhbGwgdGhlIHZlcnNpb25zIHBvc3NpYmxlIGluIHRoZSByYW5nZS5cbmV4cG9ydHMuZ3RyID0gZ3RyXG5mdW5jdGlvbiBndHIgKHZlcnNpb24sIHJhbmdlLCBvcHRpb25zKSB7XG4gIHJldHVybiBvdXRzaWRlKHZlcnNpb24sIHJhbmdlLCAnPicsIG9wdGlvbnMpXG59XG5cbmV4cG9ydHMub3V0c2lkZSA9IG91dHNpZGVcbmZ1bmN0aW9uIG91dHNpZGUgKHZlcnNpb24sIHJhbmdlLCBoaWxvLCBvcHRpb25zKSB7XG4gIHZlcnNpb24gPSBuZXcgU2VtVmVyKHZlcnNpb24sIG9wdGlvbnMpXG4gIHJhbmdlID0gbmV3IFJhbmdlKHJhbmdlLCBvcHRpb25zKVxuXG4gIHZhciBndGZuLCBsdGVmbiwgbHRmbiwgY29tcCwgZWNvbXBcbiAgc3dpdGNoIChoaWxvKSB7XG4gICAgY2FzZSAnPic6XG4gICAgICBndGZuID0gZ3RcbiAgICAgIGx0ZWZuID0gbHRlXG4gICAgICBsdGZuID0gbHRcbiAgICAgIGNvbXAgPSAnPidcbiAgICAgIGVjb21wID0gJz49J1xuICAgICAgYnJlYWtcbiAgICBjYXNlICc8JzpcbiAgICAgIGd0Zm4gPSBsdFxuICAgICAgbHRlZm4gPSBndGVcbiAgICAgIGx0Zm4gPSBndFxuICAgICAgY29tcCA9ICc8J1xuICAgICAgZWNvbXAgPSAnPD0nXG4gICAgICBicmVha1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdNdXN0IHByb3ZpZGUgYSBoaWxvIHZhbCBvZiBcIjxcIiBvciBcIj5cIicpXG4gIH1cblxuICAvLyBJZiBpdCBzYXRpc2lmZXMgdGhlIHJhbmdlIGl0IGlzIG5vdCBvdXRzaWRlXG4gIGlmIChzYXRpc2ZpZXModmVyc2lvbiwgcmFuZ2UsIG9wdGlvbnMpKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvLyBGcm9tIG5vdyBvbiwgdmFyaWFibGUgdGVybXMgYXJlIGFzIGlmIHdlJ3JlIGluIFwiZ3RyXCIgbW9kZS5cbiAgLy8gYnV0IG5vdGUgdGhhdCBldmVyeXRoaW5nIGlzIGZsaXBwZWQgZm9yIHRoZSBcImx0clwiIGZ1bmN0aW9uLlxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2Uuc2V0Lmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGNvbXBhcmF0b3JzID0gcmFuZ2Uuc2V0W2ldXG5cbiAgICB2YXIgaGlnaCA9IG51bGxcbiAgICB2YXIgbG93ID0gbnVsbFxuXG4gICAgY29tcGFyYXRvcnMuZm9yRWFjaChmdW5jdGlvbiAoY29tcGFyYXRvcikge1xuICAgICAgaWYgKGNvbXBhcmF0b3Iuc2VtdmVyID09PSBBTlkpIHtcbiAgICAgICAgY29tcGFyYXRvciA9IG5ldyBDb21wYXJhdG9yKCc+PTAuMC4wJylcbiAgICAgIH1cbiAgICAgIGhpZ2ggPSBoaWdoIHx8IGNvbXBhcmF0b3JcbiAgICAgIGxvdyA9IGxvdyB8fCBjb21wYXJhdG9yXG4gICAgICBpZiAoZ3Rmbihjb21wYXJhdG9yLnNlbXZlciwgaGlnaC5zZW12ZXIsIG9wdGlvbnMpKSB7XG4gICAgICAgIGhpZ2ggPSBjb21wYXJhdG9yXG4gICAgICB9IGVsc2UgaWYgKGx0Zm4oY29tcGFyYXRvci5zZW12ZXIsIGxvdy5zZW12ZXIsIG9wdGlvbnMpKSB7XG4gICAgICAgIGxvdyA9IGNvbXBhcmF0b3JcbiAgICAgIH1cbiAgICB9KVxuXG4gICAgLy8gSWYgdGhlIGVkZ2UgdmVyc2lvbiBjb21wYXJhdG9yIGhhcyBhIG9wZXJhdG9yIHRoZW4gb3VyIHZlcnNpb25cbiAgICAvLyBpc24ndCBvdXRzaWRlIGl0XG4gICAgaWYgKGhpZ2gub3BlcmF0b3IgPT09IGNvbXAgfHwgaGlnaC5vcGVyYXRvciA9PT0gZWNvbXApIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIElmIHRoZSBsb3dlc3QgdmVyc2lvbiBjb21wYXJhdG9yIGhhcyBhbiBvcGVyYXRvciBhbmQgb3VyIHZlcnNpb25cbiAgICAvLyBpcyBsZXNzIHRoYW4gaXQgdGhlbiBpdCBpc24ndCBoaWdoZXIgdGhhbiB0aGUgcmFuZ2VcbiAgICBpZiAoKCFsb3cub3BlcmF0b3IgfHwgbG93Lm9wZXJhdG9yID09PSBjb21wKSAmJlxuICAgICAgICBsdGVmbih2ZXJzaW9uLCBsb3cuc2VtdmVyKSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfSBlbHNlIGlmIChsb3cub3BlcmF0b3IgPT09IGVjb21wICYmIGx0Zm4odmVyc2lvbiwgbG93LnNlbXZlcikpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG5leHBvcnRzLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlXG5mdW5jdGlvbiBwcmVyZWxlYXNlICh2ZXJzaW9uLCBvcHRpb25zKSB7XG4gIHZhciBwYXJzZWQgPSBwYXJzZSh2ZXJzaW9uLCBvcHRpb25zKVxuICByZXR1cm4gKHBhcnNlZCAmJiBwYXJzZWQucHJlcmVsZWFzZS5sZW5ndGgpID8gcGFyc2VkLnByZXJlbGVhc2UgOiBudWxsXG59XG5cbmV4cG9ydHMuaW50ZXJzZWN0cyA9IGludGVyc2VjdHNcbmZ1bmN0aW9uIGludGVyc2VjdHMgKHIxLCByMiwgb3B0aW9ucykge1xuICByMSA9IG5ldyBSYW5nZShyMSwgb3B0aW9ucylcbiAgcjIgPSBuZXcgUmFuZ2UocjIsIG9wdGlvbnMpXG4gIHJldHVybiByMS5pbnRlcnNlY3RzKHIyKVxufVxuXG5leHBvcnRzLmNvZXJjZSA9IGNvZXJjZVxuZnVuY3Rpb24gY29lcmNlICh2ZXJzaW9uKSB7XG4gIGlmICh2ZXJzaW9uIGluc3RhbmNlb2YgU2VtVmVyKSB7XG4gICAgcmV0dXJuIHZlcnNpb25cbiAgfVxuXG4gIGlmICh0eXBlb2YgdmVyc2lvbiAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgdmFyIG1hdGNoID0gdmVyc2lvbi5tYXRjaChyZVtDT0VSQ0VdKVxuXG4gIGlmIChtYXRjaCA9PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIHJldHVybiBwYXJzZShtYXRjaFsxXSArXG4gICAgJy4nICsgKG1hdGNoWzJdIHx8ICcwJykgK1xuICAgICcuJyArIChtYXRjaFszXSB8fCAnMCcpKVxufVxuIiwiLy9cbi8vIFNoZWxsSlNcbi8vIFVuaXggc2hlbGwgY29tbWFuZHMgb24gdG9wIG9mIE5vZGUncyBBUElcbi8vXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTIgQXJ0dXIgQWRpYlxuLy8gaHR0cDovL2dpdGh1Yi5jb20vYXJ0dXJhZGliL3NoZWxsanNcbi8vXG5cbnZhciBjb21tb24gPSByZXF1aXJlKCcuL3NyYy9jb21tb24nKTtcblxuXG4vL0Bcbi8vQCBBbGwgY29tbWFuZHMgcnVuIHN5bmNocm9ub3VzbHksIHVubGVzcyBvdGhlcndpc2Ugc3RhdGVkLlxuLy9AXG5cbi8vQGluY2x1ZGUgLi9zcmMvY2RcbnZhciBfY2QgPSByZXF1aXJlKCcuL3NyYy9jZCcpO1xuZXhwb3J0cy5jZCA9IGNvbW1vbi53cmFwKCdjZCcsIF9jZCk7XG5cbi8vQGluY2x1ZGUgLi9zcmMvcHdkXG52YXIgX3B3ZCA9IHJlcXVpcmUoJy4vc3JjL3B3ZCcpO1xuZXhwb3J0cy5wd2QgPSBjb21tb24ud3JhcCgncHdkJywgX3B3ZCk7XG5cbi8vQGluY2x1ZGUgLi9zcmMvbHNcbnZhciBfbHMgPSByZXF1aXJlKCcuL3NyYy9scycpO1xuZXhwb3J0cy5scyA9IGNvbW1vbi53cmFwKCdscycsIF9scyk7XG5cbi8vQGluY2x1ZGUgLi9zcmMvZmluZFxudmFyIF9maW5kID0gcmVxdWlyZSgnLi9zcmMvZmluZCcpO1xuZXhwb3J0cy5maW5kID0gY29tbW9uLndyYXAoJ2ZpbmQnLCBfZmluZCk7XG5cbi8vQGluY2x1ZGUgLi9zcmMvY3BcbnZhciBfY3AgPSByZXF1aXJlKCcuL3NyYy9jcCcpO1xuZXhwb3J0cy5jcCA9IGNvbW1vbi53cmFwKCdjcCcsIF9jcCk7XG5cbi8vQGluY2x1ZGUgLi9zcmMvcm1cbnZhciBfcm0gPSByZXF1aXJlKCcuL3NyYy9ybScpO1xuZXhwb3J0cy5ybSA9IGNvbW1vbi53cmFwKCdybScsIF9ybSk7XG5cbi8vQGluY2x1ZGUgLi9zcmMvbXZcbnZhciBfbXYgPSByZXF1aXJlKCcuL3NyYy9tdicpO1xuZXhwb3J0cy5tdiA9IGNvbW1vbi53cmFwKCdtdicsIF9tdik7XG5cbi8vQGluY2x1ZGUgLi9zcmMvbWtkaXJcbnZhciBfbWtkaXIgPSByZXF1aXJlKCcuL3NyYy9ta2RpcicpO1xuZXhwb3J0cy5ta2RpciA9IGNvbW1vbi53cmFwKCdta2RpcicsIF9ta2Rpcik7XG5cbi8vQGluY2x1ZGUgLi9zcmMvdGVzdFxudmFyIF90ZXN0ID0gcmVxdWlyZSgnLi9zcmMvdGVzdCcpO1xuZXhwb3J0cy50ZXN0ID0gY29tbW9uLndyYXAoJ3Rlc3QnLCBfdGVzdCk7XG5cbi8vQGluY2x1ZGUgLi9zcmMvY2F0XG52YXIgX2NhdCA9IHJlcXVpcmUoJy4vc3JjL2NhdCcpO1xuZXhwb3J0cy5jYXQgPSBjb21tb24ud3JhcCgnY2F0JywgX2NhdCk7XG5cbi8vQGluY2x1ZGUgLi9zcmMvdG9cbnZhciBfdG8gPSByZXF1aXJlKCcuL3NyYy90bycpO1xuU3RyaW5nLnByb3RvdHlwZS50byA9IGNvbW1vbi53cmFwKCd0bycsIF90byk7XG5cbi8vQGluY2x1ZGUgLi9zcmMvdG9FbmRcbnZhciBfdG9FbmQgPSByZXF1aXJlKCcuL3NyYy90b0VuZCcpO1xuU3RyaW5nLnByb3RvdHlwZS50b0VuZCA9IGNvbW1vbi53cmFwKCd0b0VuZCcsIF90b0VuZCk7XG5cbi8vQGluY2x1ZGUgLi9zcmMvc2VkXG52YXIgX3NlZCA9IHJlcXVpcmUoJy4vc3JjL3NlZCcpO1xuZXhwb3J0cy5zZWQgPSBjb21tb24ud3JhcCgnc2VkJywgX3NlZCk7XG5cbi8vQGluY2x1ZGUgLi9zcmMvZ3JlcFxudmFyIF9ncmVwID0gcmVxdWlyZSgnLi9zcmMvZ3JlcCcpO1xuZXhwb3J0cy5ncmVwID0gY29tbW9uLndyYXAoJ2dyZXAnLCBfZ3JlcCk7XG5cbi8vQGluY2x1ZGUgLi9zcmMvd2hpY2hcbnZhciBfd2hpY2ggPSByZXF1aXJlKCcuL3NyYy93aGljaCcpO1xuZXhwb3J0cy53aGljaCA9IGNvbW1vbi53cmFwKCd3aGljaCcsIF93aGljaCk7XG5cbi8vQGluY2x1ZGUgLi9zcmMvZWNob1xudmFyIF9lY2hvID0gcmVxdWlyZSgnLi9zcmMvZWNobycpO1xuZXhwb3J0cy5lY2hvID0gX2VjaG87IC8vIGRvbid0IGNvbW1vbi53cmFwKCkgYXMgaXQgY291bGQgcGFyc2UgJy1vcHRpb25zJ1xuXG4vL0BpbmNsdWRlIC4vc3JjL2RpcnNcbnZhciBfZGlycyA9IHJlcXVpcmUoJy4vc3JjL2RpcnMnKS5kaXJzO1xuZXhwb3J0cy5kaXJzID0gY29tbW9uLndyYXAoXCJkaXJzXCIsIF9kaXJzKTtcbnZhciBfcHVzaGQgPSByZXF1aXJlKCcuL3NyYy9kaXJzJykucHVzaGQ7XG5leHBvcnRzLnB1c2hkID0gY29tbW9uLndyYXAoJ3B1c2hkJywgX3B1c2hkKTtcbnZhciBfcG9wZCA9IHJlcXVpcmUoJy4vc3JjL2RpcnMnKS5wb3BkO1xuZXhwb3J0cy5wb3BkID0gY29tbW9uLndyYXAoXCJwb3BkXCIsIF9wb3BkKTtcblxuLy9AaW5jbHVkZSAuL3NyYy9sblxudmFyIF9sbiA9IHJlcXVpcmUoJy4vc3JjL2xuJyk7XG5leHBvcnRzLmxuID0gY29tbW9uLndyYXAoJ2xuJywgX2xuKTtcblxuLy9AXG4vL0AgIyMjIGV4aXQoY29kZSlcbi8vQCBFeGl0cyB0aGUgY3VycmVudCBwcm9jZXNzIHdpdGggdGhlIGdpdmVuIGV4aXQgY29kZS5cbmV4cG9ydHMuZXhpdCA9IHByb2Nlc3MuZXhpdDtcblxuLy9AXG4vL0AgIyMjIGVudlsnVkFSX05BTUUnXVxuLy9AIE9iamVjdCBjb250YWluaW5nIGVudmlyb25tZW50IHZhcmlhYmxlcyAoYm90aCBnZXR0ZXIgYW5kIHNldHRlcikuIFNob3J0Y3V0IHRvIHByb2Nlc3MuZW52LlxuZXhwb3J0cy5lbnYgPSBwcm9jZXNzLmVudjtcblxuLy9AaW5jbHVkZSAuL3NyYy9leGVjXG52YXIgX2V4ZWMgPSByZXF1aXJlKCcuL3NyYy9leGVjJyk7XG5leHBvcnRzLmV4ZWMgPSBjb21tb24ud3JhcCgnZXhlYycsIF9leGVjLCB7bm90VW5peDp0cnVlfSk7XG5cbi8vQGluY2x1ZGUgLi9zcmMvY2htb2RcbnZhciBfY2htb2QgPSByZXF1aXJlKCcuL3NyYy9jaG1vZCcpO1xuZXhwb3J0cy5jaG1vZCA9IGNvbW1vbi53cmFwKCdjaG1vZCcsIF9jaG1vZCk7XG5cblxuXG4vL0Bcbi8vQCAjIyBOb24tVW5peCBjb21tYW5kc1xuLy9AXG5cbi8vQGluY2x1ZGUgLi9zcmMvdGVtcGRpclxudmFyIF90ZW1wRGlyID0gcmVxdWlyZSgnLi9zcmMvdGVtcGRpcicpO1xuZXhwb3J0cy50ZW1wZGlyID0gY29tbW9uLndyYXAoJ3RlbXBkaXInLCBfdGVtcERpcik7XG5cblxuLy9AaW5jbHVkZSAuL3NyYy9lcnJvclxudmFyIF9lcnJvciA9IHJlcXVpcmUoJy4vc3JjL2Vycm9yJyk7XG5leHBvcnRzLmVycm9yID0gX2Vycm9yO1xuXG5cblxuLy9AXG4vL0AgIyMgQ29uZmlndXJhdGlvblxuLy9AXG5cbmV4cG9ydHMuY29uZmlnID0gY29tbW9uLmNvbmZpZztcblxuLy9AXG4vL0AgIyMjIGNvbmZpZy5zaWxlbnRcbi8vQCBFeGFtcGxlOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIHZhciBzaWxlbnRTdGF0ZSA9IGNvbmZpZy5zaWxlbnQ7IC8vIHNhdmUgb2xkIHNpbGVudCBzdGF0ZVxuLy9AIGNvbmZpZy5zaWxlbnQgPSB0cnVlO1xuLy9AIC8qIC4uLiAqL1xuLy9AIGNvbmZpZy5zaWxlbnQgPSBzaWxlbnRTdGF0ZTsgLy8gcmVzdG9yZSBvbGQgc2lsZW50IHN0YXRlXG4vL0AgYGBgXG4vL0Bcbi8vQCBTdXBwcmVzc2VzIGFsbCBjb21tYW5kIG91dHB1dCBpZiBgdHJ1ZWAsIGV4Y2VwdCBmb3IgYGVjaG8oKWAgY2FsbHMuXG4vL0AgRGVmYXVsdCBpcyBgZmFsc2VgLlxuXG4vL0Bcbi8vQCAjIyMgY29uZmlnLmZhdGFsXG4vL0AgRXhhbXBsZTpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBjb25maWcuZmF0YWwgPSB0cnVlO1xuLy9AIGNwKCd0aGlzX2ZpbGVfZG9lc19ub3RfZXhpc3QnLCAnL2Rldi9udWxsJyk7IC8vIGRpZXMgaGVyZVxuLy9AIC8qIG1vcmUgY29tbWFuZHMuLi4gKi9cbi8vQCBgYGBcbi8vQFxuLy9AIElmIGB0cnVlYCB0aGUgc2NyaXB0IHdpbGwgZGllIG9uIGVycm9ycy4gRGVmYXVsdCBpcyBgZmFsc2VgLlxuIiwidmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xuXG4vL0Bcbi8vQCAjIyMgY2F0KGZpbGUgWywgZmlsZSAuLi5dKVxuLy9AICMjIyBjYXQoZmlsZV9hcnJheSlcbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIHZhciBzdHIgPSBjYXQoJ2ZpbGUqLnR4dCcpO1xuLy9AIHZhciBzdHIgPSBjYXQoJ2ZpbGUxJywgJ2ZpbGUyJyk7XG4vL0AgdmFyIHN0ciA9IGNhdChbJ2ZpbGUxJywgJ2ZpbGUyJ10pOyAvLyBzYW1lIGFzIGFib3ZlXG4vL0AgYGBgXG4vL0Bcbi8vQCBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGdpdmVuIGZpbGUsIG9yIGEgY29uY2F0ZW5hdGVkIHN0cmluZ1xuLy9AIGNvbnRhaW5pbmcgdGhlIGZpbGVzIGlmIG1vcmUgdGhhbiBvbmUgZmlsZSBpcyBnaXZlbiAoYSBuZXcgbGluZSBjaGFyYWN0ZXIgaXNcbi8vQCBpbnRyb2R1Y2VkIGJldHdlZW4gZWFjaCBmaWxlKS4gV2lsZGNhcmQgYCpgIGFjY2VwdGVkLlxuZnVuY3Rpb24gX2NhdChvcHRpb25zLCBmaWxlcykge1xuICB2YXIgY2F0ID0gJyc7XG5cbiAgaWYgKCFmaWxlcylcbiAgICBjb21tb24uZXJyb3IoJ25vIHBhdGhzIGdpdmVuJyk7XG5cbiAgaWYgKHR5cGVvZiBmaWxlcyA9PT0gJ3N0cmluZycpXG4gICAgZmlsZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gIC8vIGlmIGl0J3MgYXJyYXkgbGVhdmUgaXQgYXMgaXQgaXNcblxuICBmaWxlcyA9IGNvbW1vbi5leHBhbmQoZmlsZXMpO1xuXG4gIGZpbGVzLmZvckVhY2goZnVuY3Rpb24oZmlsZSkge1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhmaWxlKSlcbiAgICAgIGNvbW1vbi5lcnJvcignbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeTogJyArIGZpbGUpO1xuXG4gICAgY2F0ICs9IGZzLnJlYWRGaWxlU3luYyhmaWxlLCAndXRmOCcpICsgJ1xcbic7XG4gIH0pO1xuXG4gIGlmIChjYXRbY2F0Lmxlbmd0aC0xXSA9PT0gJ1xcbicpXG4gICAgY2F0ID0gY2F0LnN1YnN0cmluZygwLCBjYXQubGVuZ3RoLTEpO1xuXG4gIHJldHVybiBjb21tb24uU2hlbGxTdHJpbmcoY2F0KTtcbn1cbm1vZHVsZS5leHBvcnRzID0gX2NhdDtcbiIsInZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxuLy9AXG4vL0AgIyMjIGNkKCdkaXInKVxuLy9AIENoYW5nZXMgdG8gZGlyZWN0b3J5IGBkaXJgIGZvciB0aGUgZHVyYXRpb24gb2YgdGhlIHNjcmlwdFxuZnVuY3Rpb24gX2NkKG9wdGlvbnMsIGRpcikge1xuICBpZiAoIWRpcilcbiAgICBjb21tb24uZXJyb3IoJ2RpcmVjdG9yeSBub3Qgc3BlY2lmaWVkJyk7XG5cbiAgaWYgKCFmcy5leGlzdHNTeW5jKGRpcikpXG4gICAgY29tbW9uLmVycm9yKCdubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgZGlyKTtcblxuICBpZiAoIWZzLnN0YXRTeW5jKGRpcikuaXNEaXJlY3RvcnkoKSlcbiAgICBjb21tb24uZXJyb3IoJ25vdCBhIGRpcmVjdG9yeTogJyArIGRpcik7XG5cbiAgcHJvY2Vzcy5jaGRpcihkaXIpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBfY2Q7XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcblxudmFyIFBFUk1TID0gKGZ1bmN0aW9uIChiYXNlKSB7XG4gIHJldHVybiB7XG4gICAgT1RIRVJfRVhFQyAgOiBiYXNlLkVYRUMsXG4gICAgT1RIRVJfV1JJVEUgOiBiYXNlLldSSVRFLFxuICAgIE9USEVSX1JFQUQgIDogYmFzZS5SRUFELFxuXG4gICAgR1JPVVBfRVhFQyAgOiBiYXNlLkVYRUMgIDw8IDMsXG4gICAgR1JPVVBfV1JJVEUgOiBiYXNlLldSSVRFIDw8IDMsXG4gICAgR1JPVVBfUkVBRCAgOiBiYXNlLlJFQUQgPDwgMyxcblxuICAgIE9XTkVSX0VYRUMgIDogYmFzZS5FWEVDIDw8IDYsXG4gICAgT1dORVJfV1JJVEUgOiBiYXNlLldSSVRFIDw8IDYsXG4gICAgT1dORVJfUkVBRCAgOiBiYXNlLlJFQUQgPDwgNixcblxuICAgIC8vIExpdGVyYWwgb2N0YWwgbnVtYmVycyBhcmUgYXBwYXJlbnRseSBub3QgYWxsb3dlZCBpbiBcInN0cmljdFwiIGphdmFzY3JpcHQuICBVc2luZyBwYXJzZUludCBpc1xuICAgIC8vIHRoZSBwcmVmZXJyZWQgd2F5LCBlbHNlIGEganNoaW50IHdhcm5pbmcgaXMgdGhyb3duLlxuICAgIFNUSUNLWSAgICAgIDogcGFyc2VJbnQoJzAxMDAwJywgOCksXG4gICAgU0VUR0lEICAgICAgOiBwYXJzZUludCgnMDIwMDAnLCA4KSxcbiAgICBTRVRVSUQgICAgICA6IHBhcnNlSW50KCcwNDAwMCcsIDgpLFxuXG4gICAgVFlQRV9NQVNLICAgOiBwYXJzZUludCgnMDc3MDAwMCcsIDgpXG4gIH07XG59KSh7XG4gIEVYRUMgIDogMSxcbiAgV1JJVEUgOiAyLFxuICBSRUFEICA6IDRcbn0pO1xuXG4vL0Bcbi8vQCAjIyMgY2htb2Qob2N0YWxfbW9kZSB8fCBvY3RhbF9zdHJpbmcsIGZpbGUpXG4vL0AgIyMjIGNobW9kKHN5bWJvbGljX21vZGUsIGZpbGUpXG4vL0Bcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYC12YDogb3V0cHV0IGEgZGlhZ25vc3RpYyBmb3IgZXZlcnkgZmlsZSBwcm9jZXNzZWQvL0Bcbi8vQCArIGAtY2A6IGxpa2UgdmVyYm9zZSBidXQgcmVwb3J0IG9ubHkgd2hlbiBhIGNoYW5nZSBpcyBtYWRlLy9AXG4vL0AgKyBgLVJgOiBjaGFuZ2UgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIHJlY3Vyc2l2ZWx5Ly9AXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBjaG1vZCg3NTUsICcvVXNlcnMvYnJhbmRvbicpO1xuLy9AIGNobW9kKCc3NTUnLCAnL1VzZXJzL2JyYW5kb24nKTsgLy8gc2FtZSBhcyBhYm92ZVxuLy9AIGNobW9kKCd1K3gnLCAnL1VzZXJzL2JyYW5kb24nKTtcbi8vQCBgYGBcbi8vQFxuLy9AIEFsdGVycyB0aGUgcGVybWlzc2lvbnMgb2YgYSBmaWxlIG9yIGRpcmVjdG9yeSBieSBlaXRoZXIgc3BlY2lmeWluZyB0aGVcbi8vQCBhYnNvbHV0ZSBwZXJtaXNzaW9ucyBpbiBvY3RhbCBmb3JtIG9yIGV4cHJlc3NpbmcgdGhlIGNoYW5nZXMgaW4gc3ltYm9scy5cbi8vQCBUaGlzIGNvbW1hbmQgdHJpZXMgdG8gbWltaWMgdGhlIFBPU0lYIGJlaGF2aW9yIGFzIG11Y2ggYXMgcG9zc2libGUuXG4vL0AgTm90YWJsZSBleGNlcHRpb25zOlxuLy9AXG4vL0AgKyBJbiBzeW1ib2xpYyBtb2RlcywgJ2EtcicgYW5kICctcicgYXJlIGlkZW50aWNhbC4gIE5vIGNvbnNpZGVyYXRpb24gaXNcbi8vQCAgIGdpdmVuIHRvIHRoZSB1bWFzay5cbi8vQCArIFRoZXJlIGlzIG5vIFwicXVpZXRcIiBvcHRpb24gc2luY2UgZGVmYXVsdCBiZWhhdmlvciBpcyB0byBydW4gc2lsZW50LlxuZnVuY3Rpb24gX2NobW9kKG9wdGlvbnMsIG1vZGUsIGZpbGVQYXR0ZXJuKSB7XG4gIGlmICghZmlsZVBhdHRlcm4pIHtcbiAgICBpZiAob3B0aW9ucy5sZW5ndGggPiAwICYmIG9wdGlvbnMuY2hhckF0KDApID09PSAnLScpIHtcbiAgICAgIC8vIFNwZWNpYWwgY2FzZSB3aGVyZSB0aGUgc3BlY2lmaWVkIGZpbGUgcGVybWlzc2lvbnMgc3RhcnRlZCB3aXRoIC0gdG8gc3VidHJhY3QgcGVybXMsIHdoaWNoXG4gICAgICAvLyBnZXQgcGlja2VkIHVwIGJ5IHRoZSBvcHRpb24gcGFyc2VyIGFzIGNvbW1hbmQgZmxhZ3MuXG4gICAgICAvLyBJZiB3ZSBhcmUgZG93biBieSBvbmUgYXJndW1lbnQgYW5kIG9wdGlvbnMgc3RhcnRzIHdpdGggLSwgc2hpZnQgZXZlcnl0aGluZyBvdmVyLlxuICAgICAgZmlsZVBhdHRlcm4gPSBtb2RlO1xuICAgICAgbW9kZSA9IG9wdGlvbnM7XG4gICAgICBvcHRpb25zID0gJyc7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgY29tbW9uLmVycm9yKCdZb3UgbXVzdCBzcGVjaWZ5IGEgZmlsZS4nKTtcbiAgICB9XG4gIH1cblxuICBvcHRpb25zID0gY29tbW9uLnBhcnNlT3B0aW9ucyhvcHRpb25zLCB7XG4gICAgJ1InOiAncmVjdXJzaXZlJyxcbiAgICAnYyc6ICdjaGFuZ2VzJyxcbiAgICAndic6ICd2ZXJib3NlJ1xuICB9KTtcblxuICBpZiAodHlwZW9mIGZpbGVQYXR0ZXJuID09PSAnc3RyaW5nJykge1xuICAgIGZpbGVQYXR0ZXJuID0gWyBmaWxlUGF0dGVybiBdO1xuICB9XG5cbiAgdmFyIGZpbGVzO1xuXG4gIGlmIChvcHRpb25zLnJlY3Vyc2l2ZSkge1xuICAgIGZpbGVzID0gW107XG4gICAgY29tbW9uLmV4cGFuZChmaWxlUGF0dGVybikuZm9yRWFjaChmdW5jdGlvbiBhZGRGaWxlKGV4cGFuZGVkRmlsZSkge1xuICAgICAgdmFyIHN0YXQgPSBmcy5sc3RhdFN5bmMoZXhwYW5kZWRGaWxlKTtcblxuICAgICAgaWYgKCFzdGF0LmlzU3ltYm9saWNMaW5rKCkpIHtcbiAgICAgICAgZmlsZXMucHVzaChleHBhbmRlZEZpbGUpO1xuXG4gICAgICAgIGlmIChzdGF0LmlzRGlyZWN0b3J5KCkpIHsgIC8vIGludGVudGlvbmFsbHkgZG9lcyBub3QgZm9sbG93IHN5bWxpbmtzLlxuICAgICAgICAgIGZzLnJlYWRkaXJTeW5jKGV4cGFuZGVkRmlsZSkuZm9yRWFjaChmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgICAgICAgIGFkZEZpbGUoZXhwYW5kZWRGaWxlICsgJy8nICsgY2hpbGQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgZWxzZSB7XG4gICAgZmlsZXMgPSBjb21tb24uZXhwYW5kKGZpbGVQYXR0ZXJuKTtcbiAgfVxuXG4gIGZpbGVzLmZvckVhY2goZnVuY3Rpb24gaW5uZXJDaG1vZChmaWxlKSB7XG4gICAgZmlsZSA9IHBhdGgucmVzb2x2ZShmaWxlKTtcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZmlsZSkpIHtcbiAgICAgIGNvbW1vbi5lcnJvcignRmlsZSBub3QgZm91bmQ6ICcgKyBmaWxlKTtcbiAgICB9XG5cbiAgICAvLyBXaGVuIHJlY3Vyc2luZywgZG9uJ3QgZm9sbG93IHN5bWxpbmtzLlxuICAgIGlmIChvcHRpb25zLnJlY3Vyc2l2ZSAmJiBmcy5sc3RhdFN5bmMoZmlsZSkuaXNTeW1ib2xpY0xpbmsoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBwZXJtcyA9IGZzLnN0YXRTeW5jKGZpbGUpLm1vZGU7XG4gICAgdmFyIHR5cGUgPSBwZXJtcyAmIFBFUk1TLlRZUEVfTUFTSztcblxuICAgIHZhciBuZXdQZXJtcyA9IHBlcm1zO1xuXG4gICAgaWYgKGlzTmFOKHBhcnNlSW50KG1vZGUsIDgpKSkge1xuICAgICAgLy8gcGFyc2Ugb3B0aW9uc1xuICAgICAgbW9kZS5zcGxpdCgnLCcpLmZvckVhY2goZnVuY3Rpb24gKHN5bWJvbGljTW9kZSkge1xuICAgICAgICAvKmpzaGludCByZWdleGRhc2g6dHJ1ZSAqL1xuICAgICAgICB2YXIgcGF0dGVybiA9IC8oW3Vnb2FdKikoWz1cXCstXSkoW3J3eFhzdF0qKS9pO1xuICAgICAgICB2YXIgbWF0Y2hlcyA9IHBhdHRlcm4uZXhlYyhzeW1ib2xpY01vZGUpO1xuXG4gICAgICAgIGlmIChtYXRjaGVzKSB7XG4gICAgICAgICAgdmFyIGFwcGx5VG8gPSBtYXRjaGVzWzFdO1xuICAgICAgICAgIHZhciBvcGVyYXRvciA9IG1hdGNoZXNbMl07XG4gICAgICAgICAgdmFyIGNoYW5nZSA9IG1hdGNoZXNbM107XG5cbiAgICAgICAgICB2YXIgY2hhbmdlT3duZXIgPSBhcHBseVRvLmluZGV4T2YoJ3UnKSAhPSAtMSB8fCBhcHBseVRvID09PSAnYScgfHwgYXBwbHlUbyA9PT0gJyc7XG4gICAgICAgICAgdmFyIGNoYW5nZUdyb3VwID0gYXBwbHlUby5pbmRleE9mKCdnJykgIT0gLTEgfHwgYXBwbHlUbyA9PT0gJ2EnIHx8IGFwcGx5VG8gPT09ICcnO1xuICAgICAgICAgIHZhciBjaGFuZ2VPdGhlciA9IGFwcGx5VG8uaW5kZXhPZignbycpICE9IC0xIHx8IGFwcGx5VG8gPT09ICdhJyB8fCBhcHBseVRvID09PSAnJztcblxuICAgICAgICAgIHZhciBjaGFuZ2VSZWFkICAgPSBjaGFuZ2UuaW5kZXhPZigncicpICE9IC0xO1xuICAgICAgICAgIHZhciBjaGFuZ2VXcml0ZSAgPSBjaGFuZ2UuaW5kZXhPZigndycpICE9IC0xO1xuICAgICAgICAgIHZhciBjaGFuZ2VFeGVjICAgPSBjaGFuZ2UuaW5kZXhPZigneCcpICE9IC0xO1xuICAgICAgICAgIHZhciBjaGFuZ2VTdGlja3kgPSBjaGFuZ2UuaW5kZXhPZigndCcpICE9IC0xO1xuICAgICAgICAgIHZhciBjaGFuZ2VTZXR1aWQgPSBjaGFuZ2UuaW5kZXhPZigncycpICE9IC0xO1xuXG4gICAgICAgICAgdmFyIG1hc2sgPSAwO1xuICAgICAgICAgIGlmIChjaGFuZ2VPd25lcikge1xuICAgICAgICAgICAgbWFzayB8PSAoY2hhbmdlUmVhZCA/IFBFUk1TLk9XTkVSX1JFQUQgOiAwKSArIChjaGFuZ2VXcml0ZSA/IFBFUk1TLk9XTkVSX1dSSVRFIDogMCkgKyAoY2hhbmdlRXhlYyA/IFBFUk1TLk9XTkVSX0VYRUMgOiAwKSArIChjaGFuZ2VTZXR1aWQgPyBQRVJNUy5TRVRVSUQgOiAwKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGNoYW5nZUdyb3VwKSB7XG4gICAgICAgICAgICBtYXNrIHw9IChjaGFuZ2VSZWFkID8gUEVSTVMuR1JPVVBfUkVBRCA6IDApICsgKGNoYW5nZVdyaXRlID8gUEVSTVMuR1JPVVBfV1JJVEUgOiAwKSArIChjaGFuZ2VFeGVjID8gUEVSTVMuR1JPVVBfRVhFQyA6IDApICsgKGNoYW5nZVNldHVpZCA/IFBFUk1TLlNFVEdJRCA6IDApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY2hhbmdlT3RoZXIpIHtcbiAgICAgICAgICAgIG1hc2sgfD0gKGNoYW5nZVJlYWQgPyBQRVJNUy5PVEhFUl9SRUFEIDogMCkgKyAoY2hhbmdlV3JpdGUgPyBQRVJNUy5PVEhFUl9XUklURSA6IDApICsgKGNoYW5nZUV4ZWMgPyBQRVJNUy5PVEhFUl9FWEVDIDogMCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gU3RpY2t5IGJpdCBpcyBzcGVjaWFsIC0gaXQncyBub3QgdGllZCB0byB1c2VyLCBncm91cCBvciBvdGhlci5cbiAgICAgICAgICBpZiAoY2hhbmdlU3RpY2t5KSB7XG4gICAgICAgICAgICBtYXNrIHw9IFBFUk1TLlNUSUNLWTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzd2l0Y2ggKG9wZXJhdG9yKSB7XG4gICAgICAgICAgICBjYXNlICcrJzpcbiAgICAgICAgICAgICAgbmV3UGVybXMgfD0gbWFzaztcbiAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgJy0nOlxuICAgICAgICAgICAgICBuZXdQZXJtcyAmPSB+bWFzaztcbiAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgJz0nOlxuICAgICAgICAgICAgICBuZXdQZXJtcyA9IHR5cGUgKyBtYXNrO1xuXG4gICAgICAgICAgICAgIC8vIEFjY29yZGluZyB0byBQT1NJWCwgd2hlbiB1c2luZyA9IHRvIGV4cGxpY2l0bHkgc2V0IHRoZSBwZXJtaXNzaW9ucywgc2V0dWlkIGFuZCBzZXRnaWQgY2FuIG5ldmVyIGJlIGNsZWFyZWQuXG4gICAgICAgICAgICAgIGlmIChmcy5zdGF0U3luYyhmaWxlKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgICAgICAgICAgbmV3UGVybXMgfD0gKFBFUk1TLlNFVFVJRCArIFBFUk1TLlNFVEdJRCkgJiBwZXJtcztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAob3B0aW9ucy52ZXJib3NlKSB7XG4gICAgICAgICAgICBsb2coZmlsZSArICcgLT4gJyArIG5ld1Blcm1zLnRvU3RyaW5nKDgpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocGVybXMgIT0gbmV3UGVybXMpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucy52ZXJib3NlICYmIG9wdGlvbnMuY2hhbmdlcykge1xuICAgICAgICAgICAgICBsb2coZmlsZSArICcgLT4gJyArIG5ld1Blcm1zLnRvU3RyaW5nKDgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZzLmNobW9kU3luYyhmaWxlLCBuZXdQZXJtcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGNvbW1vbi5lcnJvcignSW52YWxpZCBzeW1ib2xpYyBtb2RlIGNoYW5nZTogJyArIHN5bWJvbGljTW9kZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIC8vIHRoZXkgZ2F2ZSB1cyBhIGZ1bGwgbnVtYmVyXG4gICAgICBuZXdQZXJtcyA9IHR5cGUgKyBwYXJzZUludChtb2RlLCA4KTtcblxuICAgICAgLy8gUE9TSVggcnVsZXMgYXJlIHRoYXQgc2V0dWlkIGFuZCBzZXRnaWQgY2FuIG9ubHkgYmUgYWRkZWQgdXNpbmcgbnVtZXJpYyBmb3JtLCBidXQgbm90IGNsZWFyZWQuXG4gICAgICBpZiAoZnMuc3RhdFN5bmMoZmlsZSkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICBuZXdQZXJtcyB8PSAoUEVSTVMuU0VUVUlEICsgUEVSTVMuU0VUR0lEKSAmIHBlcm1zO1xuICAgICAgfVxuXG4gICAgICBmcy5jaG1vZFN5bmMoZmlsZSwgbmV3UGVybXMpO1xuICAgIH1cbiAgfSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF9jaG1vZDtcbiIsInZhciBvcyA9IHJlcXVpcmUoJ29zJyk7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xudmFyIF9scyA9IHJlcXVpcmUoJy4vbHMnKTtcblxuLy8gTW9kdWxlIGdsb2JhbHNcbnZhciBjb25maWcgPSB7XG4gIHNpbGVudDogZmFsc2UsXG4gIGZhdGFsOiBmYWxzZVxufTtcbmV4cG9ydHMuY29uZmlnID0gY29uZmlnO1xuXG52YXIgc3RhdGUgPSB7XG4gIGVycm9yOiBudWxsLFxuICBjdXJyZW50Q21kOiAnc2hlbGwuanMnLFxuICB0ZW1wRGlyOiBudWxsXG59O1xuZXhwb3J0cy5zdGF0ZSA9IHN0YXRlO1xuXG52YXIgcGxhdGZvcm0gPSBvcy50eXBlKCkubWF0Y2goL15XaW4vKSA/ICd3aW4nIDogJ3VuaXgnO1xuZXhwb3J0cy5wbGF0Zm9ybSA9IHBsYXRmb3JtO1xuXG5mdW5jdGlvbiBsb2coKSB7XG4gIGlmICghY29uZmlnLnNpbGVudClcbiAgICBjb25zb2xlLmxvZy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuZXhwb3J0cy5sb2cgPSBsb2c7XG5cbi8vIFNob3dzIGVycm9yIG1lc3NhZ2UuIFRocm93cyB1bmxlc3MgX2NvbnRpbnVlIG9yIGNvbmZpZy5mYXRhbCBhcmUgdHJ1ZVxuZnVuY3Rpb24gZXJyb3IobXNnLCBfY29udGludWUpIHtcbiAgaWYgKHN0YXRlLmVycm9yID09PSBudWxsKVxuICAgIHN0YXRlLmVycm9yID0gJyc7XG4gIHN0YXRlLmVycm9yICs9IHN0YXRlLmN1cnJlbnRDbWQgKyAnOiAnICsgbXNnICsgJ1xcbic7XG5cbiAgaWYgKG1zZy5sZW5ndGggPiAwKVxuICAgIGxvZyhzdGF0ZS5lcnJvcik7XG5cbiAgaWYgKGNvbmZpZy5mYXRhbClcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG5cbiAgaWYgKCFfY29udGludWUpXG4gICAgdGhyb3cgJyc7XG59XG5leHBvcnRzLmVycm9yID0gZXJyb3I7XG5cbi8vIEluIHRoZSBmdXR1cmUsIHdoZW4gUHJveGllcyBhcmUgZGVmYXVsdCwgd2UgY2FuIGFkZCBtZXRob2RzIGxpa2UgYC50bygpYCB0byBwcmltaXRpdmUgc3RyaW5ncy5cbi8vIEZvciBub3csIHRoaXMgaXMgYSBkdW1teSBmdW5jdGlvbiB0byBib29rbWFyayBwbGFjZXMgd2UgbmVlZCBzdWNoIHN0cmluZ3NcbmZ1bmN0aW9uIFNoZWxsU3RyaW5nKHN0cikge1xuICByZXR1cm4gc3RyO1xufVxuZXhwb3J0cy5TaGVsbFN0cmluZyA9IFNoZWxsU3RyaW5nO1xuXG4vLyBSZXR1cm5zIHsnYWxpY2UnOiB0cnVlLCAnYm9iJzogZmFsc2V9IHdoZW4gcGFzc2VkIGEgZGljdGlvbmFyeSwgZS5nLjpcbi8vICAgcGFyc2VPcHRpb25zKCctYScsIHsnYSc6J2FsaWNlJywgJ2InOidib2InfSk7XG5mdW5jdGlvbiBwYXJzZU9wdGlvbnMoc3RyLCBtYXApIHtcbiAgaWYgKCFtYXApXG4gICAgZXJyb3IoJ3BhcnNlT3B0aW9ucygpIGludGVybmFsIGVycm9yOiBubyBtYXAgZ2l2ZW4nKTtcblxuICAvLyBBbGwgb3B0aW9ucyBhcmUgZmFsc2UgYnkgZGVmYXVsdFxuICB2YXIgb3B0aW9ucyA9IHt9O1xuICBmb3IgKHZhciBsZXR0ZXIgaW4gbWFwKVxuICAgIG9wdGlvbnNbbWFwW2xldHRlcl1dID0gZmFsc2U7XG5cbiAgaWYgKCFzdHIpXG4gICAgcmV0dXJuIG9wdGlvbnM7IC8vIGRlZmF1bHRzXG5cbiAgaWYgKHR5cGVvZiBzdHIgIT09ICdzdHJpbmcnKVxuICAgIGVycm9yKCdwYXJzZU9wdGlvbnMoKSBpbnRlcm5hbCBlcnJvcjogd3Jvbmcgc3RyJyk7XG5cbiAgLy8gZS5nLiBtYXRjaFsxXSA9ICdSZicgZm9yIHN0ciA9ICctUmYnXG4gIHZhciBtYXRjaCA9IHN0ci5tYXRjaCgvXlxcLSguKykvKTtcbiAgaWYgKCFtYXRjaClcbiAgICByZXR1cm4gb3B0aW9ucztcblxuICAvLyBlLmcuIGNoYXJzID0gWydSJywgJ2YnXVxuICB2YXIgY2hhcnMgPSBtYXRjaFsxXS5zcGxpdCgnJyk7XG5cbiAgY2hhcnMuZm9yRWFjaChmdW5jdGlvbihjKSB7XG4gICAgaWYgKGMgaW4gbWFwKVxuICAgICAgb3B0aW9uc1ttYXBbY11dID0gdHJ1ZTtcbiAgICBlbHNlXG4gICAgICBlcnJvcignb3B0aW9uIG5vdCByZWNvZ25pemVkOiAnK2MpO1xuICB9KTtcblxuICByZXR1cm4gb3B0aW9ucztcbn1cbmV4cG9ydHMucGFyc2VPcHRpb25zID0gcGFyc2VPcHRpb25zO1xuXG4vLyBFeHBhbmRzIHdpbGRjYXJkcyB3aXRoIG1hdGNoaW5nIChpZS4gZXhpc3RpbmcpIGZpbGUgbmFtZXMuXG4vLyBGb3IgZXhhbXBsZTpcbi8vICAgZXhwYW5kKFsnZmlsZSouanMnXSkgPSBbJ2ZpbGUxLmpzJywgJ2ZpbGUyLmpzJywgLi4uXVxuLy8gICAoaWYgdGhlIGZpbGVzICdmaWxlMS5qcycsICdmaWxlMi5qcycsIGV0YywgZXhpc3QgaW4gdGhlIGN1cnJlbnQgZGlyKVxuZnVuY3Rpb24gZXhwYW5kKGxpc3QpIHtcbiAgdmFyIGV4cGFuZGVkID0gW107XG4gIGxpc3QuZm9yRWFjaChmdW5jdGlvbihsaXN0RWwpIHtcbiAgICAvLyBXaWxkY2FyZCBwcmVzZW50IG9uIGRpcmVjdG9yeSBuYW1lcyA/XG4gICAgaWYobGlzdEVsLnNlYXJjaCgvXFwqW15cXC9dKlxcLy8pID4gLTEgfHwgbGlzdEVsLnNlYXJjaCgvXFwqXFwqW15cXC9dKlxcLy8pID4gLTEpIHtcbiAgICAgIHZhciBtYXRjaCA9IGxpc3RFbC5tYXRjaCgvXihbXipdK1xcL3wpKC4qKS8pO1xuICAgICAgdmFyIHJvb3QgPSBtYXRjaFsxXTtcbiAgICAgIHZhciByZXN0ID0gbWF0Y2hbMl07XG4gICAgICB2YXIgcmVzdFJlZ2V4ID0gcmVzdC5yZXBsYWNlKC9cXCpcXCovZywgXCIuKlwiKS5yZXBsYWNlKC9cXCovZywgXCJbXlxcXFwvXSpcIik7XG4gICAgICByZXN0UmVnZXggPSBuZXcgUmVnRXhwKHJlc3RSZWdleCk7XG4gICAgICBcbiAgICAgIF9scygnLVInLCByb290KS5maWx0ZXIoZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgcmV0dXJuIHJlc3RSZWdleC50ZXN0KGUpO1xuICAgICAgfSkuZm9yRWFjaChmdW5jdGlvbihmaWxlKSB7XG4gICAgICAgIGV4cGFuZGVkLnB1c2goZmlsZSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgLy8gV2lsZGNhcmQgcHJlc2VudCBvbiBmaWxlIG5hbWVzID9cbiAgICBlbHNlIGlmIChsaXN0RWwuc2VhcmNoKC9cXCovKSA+IC0xKSB7XG4gICAgICBfbHMoJycsIGxpc3RFbCkuZm9yRWFjaChmdW5jdGlvbihmaWxlKSB7XG4gICAgICAgIGV4cGFuZGVkLnB1c2goZmlsZSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXhwYW5kZWQucHVzaChsaXN0RWwpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBleHBhbmRlZDtcbn1cbmV4cG9ydHMuZXhwYW5kID0gZXhwYW5kO1xuXG4vLyBOb3JtYWxpemVzIF91bmxpbmtTeW5jKCkgYWNyb3NzIHBsYXRmb3JtcyB0byBtYXRjaCBVbml4IGJlaGF2aW9yLCBpLmUuXG4vLyBmaWxlIGNhbiBiZSB1bmxpbmtlZCBldmVuIGlmIGl0J3MgcmVhZC1vbmx5LCBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2pveWVudC9ub2RlL2lzc3Vlcy8zMDA2XG5mdW5jdGlvbiB1bmxpbmtTeW5jKGZpbGUpIHtcbiAgdHJ5IHtcbiAgICBmcy51bmxpbmtTeW5jKGZpbGUpO1xuICB9IGNhdGNoKGUpIHtcbiAgICAvLyBUcnkgdG8gb3ZlcnJpZGUgZmlsZSBwZXJtaXNzaW9uXG4gICAgaWYgKGUuY29kZSA9PT0gJ0VQRVJNJykge1xuICAgICAgZnMuY2htb2RTeW5jKGZpbGUsICcwNjY2Jyk7XG4gICAgICBmcy51bmxpbmtTeW5jKGZpbGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgfVxufVxuZXhwb3J0cy51bmxpbmtTeW5jID0gdW5saW5rU3luYztcblxuLy8gZS5nLiAnc2hlbGxqc19hNWYxODVkMDQ0M2NhLi4uJ1xuZnVuY3Rpb24gcmFuZG9tRmlsZU5hbWUoKSB7XG4gIGZ1bmN0aW9uIHJhbmRvbUhhc2goY291bnQpIHtcbiAgICBpZiAoY291bnQgPT09IDEpXG4gICAgICByZXR1cm4gcGFyc2VJbnQoMTYqTWF0aC5yYW5kb20oKSwgMTApLnRvU3RyaW5nKDE2KTtcbiAgICBlbHNlIHtcbiAgICAgIHZhciBoYXNoID0gJyc7XG4gICAgICBmb3IgKHZhciBpPTA7IGk8Y291bnQ7IGkrKylcbiAgICAgICAgaGFzaCArPSByYW5kb21IYXNoKDEpO1xuICAgICAgcmV0dXJuIGhhc2g7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuICdzaGVsbGpzXycrcmFuZG9tSGFzaCgyMCk7XG59XG5leHBvcnRzLnJhbmRvbUZpbGVOYW1lID0gcmFuZG9tRmlsZU5hbWU7XG5cbi8vIGV4dGVuZCh0YXJnZXRfb2JqLCBzb3VyY2Vfb2JqMSBbLCBzb3VyY2Vfb2JqMiAuLi5dKVxuLy8gU2hhbGxvdyBleHRlbmQsIGUuZy46XG4vLyAgICBleHRlbmQoe0E6MX0sIHtiOjJ9LCB7YzozfSkgcmV0dXJucyB7QToxLCBiOjIsIGM6M31cbmZ1bmN0aW9uIGV4dGVuZCh0YXJnZXQpIHtcbiAgdmFyIHNvdXJjZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gIHNvdXJjZXMuZm9yRWFjaChmdW5jdGlvbihzb3VyY2UpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gc291cmNlKVxuICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgfSk7XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cbmV4cG9ydHMuZXh0ZW5kID0gZXh0ZW5kO1xuXG4vLyBDb21tb24gd3JhcHBlciBmb3IgYWxsIFVuaXgtbGlrZSBjb21tYW5kc1xuZnVuY3Rpb24gd3JhcChjbWQsIGZuLCBvcHRpb25zKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgcmV0VmFsdWUgPSBudWxsO1xuXG4gICAgc3RhdGUuY3VycmVudENtZCA9IGNtZDtcbiAgICBzdGF0ZS5lcnJvciA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCk7XG5cbiAgICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMubm90VW5peCkge1xuICAgICAgICByZXRWYWx1ZSA9IGZuLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID09PSAwIHx8IHR5cGVvZiBhcmdzWzBdICE9PSAnc3RyaW5nJyB8fCBhcmdzWzBdWzBdICE9PSAnLScpXG4gICAgICAgICAgYXJncy51bnNoaWZ0KCcnKTsgLy8gb25seSBhZGQgZHVtbXkgb3B0aW9uIGlmICctb3B0aW9uJyBub3QgYWxyZWFkeSBwcmVzZW50XG4gICAgICAgIHJldFZhbHVlID0gZm4uYXBwbHkodGhpcywgYXJncyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKCFzdGF0ZS5lcnJvcikge1xuICAgICAgICAvLyBJZiBzdGF0ZS5lcnJvciBoYXNuJ3QgYmVlbiBzZXQgaXQncyBhbiBlcnJvciB0aHJvd24gYnkgTm9kZSwgbm90IHVzIC0gcHJvYmFibHkgYSBidWcuLi5cbiAgICAgICAgY29uc29sZS5sb2coJ3NoZWxsLmpzOiBpbnRlcm5hbCBlcnJvcicpO1xuICAgICAgICBjb25zb2xlLmxvZyhlLnN0YWNrIHx8IGUpO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICB9XG4gICAgICBpZiAoY29uZmlnLmZhdGFsKVxuICAgICAgICB0aHJvdyBlO1xuICAgIH1cblxuICAgIHN0YXRlLmN1cnJlbnRDbWQgPSAnc2hlbGwuanMnO1xuICAgIHJldHVybiByZXRWYWx1ZTtcbiAgfTtcbn0gLy8gd3JhcFxuZXhwb3J0cy53cmFwID0gd3JhcDtcbiIsInZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcbnZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIG9zID0gcmVxdWlyZSgnb3MnKTtcblxuLy8gQnVmZmVyZWQgZmlsZSBjb3B5LCBzeW5jaHJvbm91c1xuLy8gKFVzaW5nIHJlYWRGaWxlU3luYygpICsgd3JpdGVGaWxlU3luYygpIGNvdWxkIGVhc2lseSBjYXVzZSBhIG1lbW9yeSBvdmVyZmxvd1xuLy8gIHdpdGggbGFyZ2UgZmlsZXMpXG5mdW5jdGlvbiBjb3B5RmlsZVN5bmMoc3JjRmlsZSwgZGVzdEZpbGUpIHtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKHNyY0ZpbGUpKVxuICAgIGNvbW1vbi5lcnJvcignY29weUZpbGVTeW5jOiBubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgc3JjRmlsZSk7XG5cbiAgdmFyIEJVRl9MRU5HVEggPSA2NCoxMDI0LFxuICAgICAgYnVmID0gbmV3IEJ1ZmZlcihCVUZfTEVOR1RIKSxcbiAgICAgIGJ5dGVzUmVhZCA9IEJVRl9MRU5HVEgsXG4gICAgICBwb3MgPSAwLFxuICAgICAgZmRyID0gbnVsbCxcbiAgICAgIGZkdyA9IG51bGw7XG5cbiAgdHJ5IHtcbiAgICBmZHIgPSBmcy5vcGVuU3luYyhzcmNGaWxlLCAncicpO1xuICB9IGNhdGNoKGUpIHtcbiAgICBjb21tb24uZXJyb3IoJ2NvcHlGaWxlU3luYzogY291bGQgbm90IHJlYWQgc3JjIGZpbGUgKCcrc3JjRmlsZSsnKScpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBmZHcgPSBmcy5vcGVuU3luYyhkZXN0RmlsZSwgJ3cnKTtcbiAgfSBjYXRjaChlKSB7XG4gICAgY29tbW9uLmVycm9yKCdjb3B5RmlsZVN5bmM6IGNvdWxkIG5vdCB3cml0ZSB0byBkZXN0IGZpbGUgKGNvZGU9JytlLmNvZGUrJyk6JytkZXN0RmlsZSk7XG4gIH1cblxuICB3aGlsZSAoYnl0ZXNSZWFkID09PSBCVUZfTEVOR1RIKSB7XG4gICAgYnl0ZXNSZWFkID0gZnMucmVhZFN5bmMoZmRyLCBidWYsIDAsIEJVRl9MRU5HVEgsIHBvcyk7XG4gICAgZnMud3JpdGVTeW5jKGZkdywgYnVmLCAwLCBieXRlc1JlYWQpO1xuICAgIHBvcyArPSBieXRlc1JlYWQ7XG4gIH1cblxuICBmcy5jbG9zZVN5bmMoZmRyKTtcbiAgZnMuY2xvc2VTeW5jKGZkdyk7XG5cbiAgZnMuY2htb2RTeW5jKGRlc3RGaWxlLCBmcy5zdGF0U3luYyhzcmNGaWxlKS5tb2RlKTtcbn1cblxuLy8gUmVjdXJzaXZlbHkgY29waWVzICdzb3VyY2VEaXInIGludG8gJ2Rlc3REaXInXG4vLyBBZGFwdGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL3J5YW5tY2dyYXRoL3dyZW5jaC1qc1xuLy9cbi8vIENvcHlyaWdodCAoYykgMjAxMCBSeWFuIE1jR3JhdGhcbi8vIENvcHlyaWdodCAoYykgMjAxMiBBcnR1ciBBZGliXG4vL1xuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlXG4vLyBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocFxuZnVuY3Rpb24gY3BkaXJTeW5jUmVjdXJzaXZlKHNvdXJjZURpciwgZGVzdERpciwgb3B0cykge1xuICBpZiAoIW9wdHMpIG9wdHMgPSB7fTtcblxuICAvKiBDcmVhdGUgdGhlIGRpcmVjdG9yeSB3aGVyZSBhbGwgb3VyIGp1bmsgaXMgbW92aW5nIHRvOyByZWFkIHRoZSBtb2RlIG9mIHRoZSBzb3VyY2UgZGlyZWN0b3J5IGFuZCBtaXJyb3IgaXQgKi9cbiAgdmFyIGNoZWNrRGlyID0gZnMuc3RhdFN5bmMoc291cmNlRGlyKTtcbiAgdHJ5IHtcbiAgICBmcy5ta2RpclN5bmMoZGVzdERpciwgY2hlY2tEaXIubW9kZSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvL2lmIHRoZSBkaXJlY3RvcnkgYWxyZWFkeSBleGlzdHMsIHRoYXQncyBva2F5XG4gICAgaWYgKGUuY29kZSAhPT0gJ0VFWElTVCcpIHRocm93IGU7XG4gIH1cblxuICB2YXIgZmlsZXMgPSBmcy5yZWFkZGlyU3luYyhzb3VyY2VEaXIpO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZmlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgc3JjRmlsZSA9IHNvdXJjZURpciArIFwiL1wiICsgZmlsZXNbaV07XG4gICAgdmFyIGRlc3RGaWxlID0gZGVzdERpciArIFwiL1wiICsgZmlsZXNbaV07XG4gICAgdmFyIHNyY0ZpbGVTdGF0ID0gZnMubHN0YXRTeW5jKHNyY0ZpbGUpO1xuXG4gICAgaWYgKHNyY0ZpbGVTdGF0LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIC8qIHJlY3Vyc2lvbiB0aGlzIHRoaW5nIHJpZ2h0IG9uIGJhY2suICovXG4gICAgICBjcGRpclN5bmNSZWN1cnNpdmUoc3JjRmlsZSwgZGVzdEZpbGUsIG9wdHMpO1xuICAgIH0gZWxzZSBpZiAoc3JjRmlsZVN0YXQuaXNTeW1ib2xpY0xpbmsoKSkge1xuICAgICAgdmFyIHN5bWxpbmtGdWxsID0gZnMucmVhZGxpbmtTeW5jKHNyY0ZpbGUpO1xuICAgICAgZnMuc3ltbGlua1N5bmMoc3ltbGlua0Z1bGwsIGRlc3RGaWxlLCBvcy5wbGF0Zm9ybSgpID09PSBcIndpbjMyXCIgPyBcImp1bmN0aW9uXCIgOiBudWxsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLyogQXQgdGhpcyBwb2ludCwgd2UndmUgaGl0IGEgZmlsZSBhY3R1YWxseSB3b3J0aCBjb3B5aW5nLi4uIHNvIGNvcHkgaXQgb24gb3Zlci4gKi9cbiAgICAgIGlmIChmcy5leGlzdHNTeW5jKGRlc3RGaWxlKSAmJiAhb3B0cy5mb3JjZSkge1xuICAgICAgICBjb21tb24ubG9nKCdza2lwcGluZyBleGlzdGluZyBmaWxlOiAnICsgZmlsZXNbaV0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29weUZpbGVTeW5jKHNyY0ZpbGUsIGRlc3RGaWxlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgfSAvLyBmb3IgZmlsZXNcbn0gLy8gY3BkaXJTeW5jUmVjdXJzaXZlXG5cblxuLy9AXG4vL0AgIyMjIGNwKFtvcHRpb25zICxdIHNvdXJjZSBbLHNvdXJjZSAuLi5dLCBkZXN0KVxuLy9AICMjIyBjcChbb3B0aW9ucyAsXSBzb3VyY2VfYXJyYXksIGRlc3QpXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGAtZmA6IGZvcmNlXG4vL0AgKyBgLXIsIC1SYDogcmVjdXJzaXZlXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBjcCgnZmlsZTEnLCAnZGlyMScpO1xuLy9AIGNwKCctUmYnLCAnL3RtcC8qJywgJy91c3IvbG9jYWwvKicsICcvaG9tZS90bXAnKTtcbi8vQCBjcCgnLVJmJywgWycvdG1wLyonLCAnL3Vzci9sb2NhbC8qJ10sICcvaG9tZS90bXAnKTsgLy8gc2FtZSBhcyBhYm92ZVxuLy9AIGBgYFxuLy9AXG4vL0AgQ29waWVzIGZpbGVzLiBUaGUgd2lsZGNhcmQgYCpgIGlzIGFjY2VwdGVkLlxuZnVuY3Rpb24gX2NwKG9wdGlvbnMsIHNvdXJjZXMsIGRlc3QpIHtcbiAgb3B0aW9ucyA9IGNvbW1vbi5wYXJzZU9wdGlvbnMob3B0aW9ucywge1xuICAgICdmJzogJ2ZvcmNlJyxcbiAgICAnUic6ICdyZWN1cnNpdmUnLFxuICAgICdyJzogJ3JlY3Vyc2l2ZSdcbiAgfSk7XG5cbiAgLy8gR2V0IHNvdXJjZXMsIGRlc3RcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzKSB7XG4gICAgY29tbW9uLmVycm9yKCdtaXNzaW5nIDxzb3VyY2U+IGFuZC9vciA8ZGVzdD4nKTtcbiAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMykge1xuICAgIHNvdXJjZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSwgYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGRlc3QgPSBhcmd1bWVudHNbYXJndW1lbnRzLmxlbmd0aCAtIDFdO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBzb3VyY2VzID09PSAnc3RyaW5nJykge1xuICAgIHNvdXJjZXMgPSBbc291cmNlc107XG4gIH0gZWxzZSBpZiAoJ2xlbmd0aCcgaW4gc291cmNlcykge1xuICAgIHNvdXJjZXMgPSBzb3VyY2VzOyAvLyBuby1vcCBmb3IgYXJyYXlcbiAgfSBlbHNlIHtcbiAgICBjb21tb24uZXJyb3IoJ2ludmFsaWQgYXJndW1lbnRzJyk7XG4gIH1cblxuICB2YXIgZXhpc3RzID0gZnMuZXhpc3RzU3luYyhkZXN0KSxcbiAgICAgIHN0YXRzID0gZXhpc3RzICYmIGZzLnN0YXRTeW5jKGRlc3QpO1xuXG4gIC8vIERlc3QgaXMgbm90IGV4aXN0aW5nIGRpciwgYnV0IG11bHRpcGxlIHNvdXJjZXMgZ2l2ZW5cbiAgaWYgKCghZXhpc3RzIHx8ICFzdGF0cy5pc0RpcmVjdG9yeSgpKSAmJiBzb3VyY2VzLmxlbmd0aCA+IDEpXG4gICAgY29tbW9uLmVycm9yKCdkZXN0IGlzIG5vdCBhIGRpcmVjdG9yeSAodG9vIG1hbnkgc291cmNlcyknKTtcblxuICAvLyBEZXN0IGlzIGFuIGV4aXN0aW5nIGZpbGUsIGJ1dCBubyAtZiBnaXZlblxuICBpZiAoZXhpc3RzICYmIHN0YXRzLmlzRmlsZSgpICYmICFvcHRpb25zLmZvcmNlKVxuICAgIGNvbW1vbi5lcnJvcignZGVzdCBmaWxlIGFscmVhZHkgZXhpc3RzOiAnICsgZGVzdCk7XG5cbiAgaWYgKG9wdGlvbnMucmVjdXJzaXZlKSB7XG4gICAgLy8gUmVjdXJzaXZlIGFsbG93cyB0aGUgc2hvcnRjdXQgc3ludGF4IFwic291cmNlZGlyL1wiIGZvciBcInNvdXJjZWRpci8qXCJcbiAgICAvLyAoc2VlIEdpdGh1YiBpc3N1ZSAjMTUpXG4gICAgc291cmNlcy5mb3JFYWNoKGZ1bmN0aW9uKHNyYywgaSkge1xuICAgICAgaWYgKHNyY1tzcmMubGVuZ3RoIC0gMV0gPT09ICcvJylcbiAgICAgICAgc291cmNlc1tpXSArPSAnKic7XG4gICAgfSk7XG5cbiAgICAvLyBDcmVhdGUgZGVzdFxuICAgIHRyeSB7XG4gICAgICBmcy5ta2RpclN5bmMoZGVzdCwgcGFyc2VJbnQoJzA3NzcnLCA4KSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gbGlrZSBVbml4J3MgY3AsIGtlZXAgZ29pbmcgZXZlbiBpZiB3ZSBjYW4ndCBjcmVhdGUgZGVzdCBkaXJcbiAgICB9XG4gIH1cblxuICBzb3VyY2VzID0gY29tbW9uLmV4cGFuZChzb3VyY2VzKTtcblxuICBzb3VyY2VzLmZvckVhY2goZnVuY3Rpb24oc3JjKSB7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHNyYykpIHtcbiAgICAgIGNvbW1vbi5lcnJvcignbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeTogJytzcmMsIHRydWUpO1xuICAgICAgcmV0dXJuOyAvLyBza2lwIGZpbGVcbiAgICB9XG5cbiAgICAvLyBJZiBoZXJlLCBzcmMgZXhpc3RzXG4gICAgaWYgKGZzLnN0YXRTeW5jKHNyYykuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgaWYgKCFvcHRpb25zLnJlY3Vyc2l2ZSkge1xuICAgICAgICAvLyBOb24tUmVjdXJzaXZlXG4gICAgICAgIGNvbW1vbi5sb2coc3JjICsgJyBpcyBhIGRpcmVjdG9yeSAobm90IGNvcGllZCknKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFJlY3Vyc2l2ZVxuICAgICAgICAvLyAnY3AgL2Evc291cmNlIGRlc3QnIHNob3VsZCBjcmVhdGUgJ3NvdXJjZScgaW4gJ2Rlc3QnXG4gICAgICAgIHZhciBuZXdEZXN0ID0gcGF0aC5qb2luKGRlc3QsIHBhdGguYmFzZW5hbWUoc3JjKSksXG4gICAgICAgICAgICBjaGVja0RpciA9IGZzLnN0YXRTeW5jKHNyYyk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZnMubWtkaXJTeW5jKG5ld0Rlc3QsIGNoZWNrRGlyLm1vZGUpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgLy9pZiB0aGUgZGlyZWN0b3J5IGFscmVhZHkgZXhpc3RzLCB0aGF0J3Mgb2theVxuICAgICAgICAgIGlmIChlLmNvZGUgIT09ICdFRVhJU1QnKSB0aHJvdyBlO1xuICAgICAgICB9XG5cbiAgICAgICAgY3BkaXJTeW5jUmVjdXJzaXZlKHNyYywgbmV3RGVzdCwge2ZvcmNlOiBvcHRpb25zLmZvcmNlfSk7XG4gICAgICB9XG4gICAgICByZXR1cm47IC8vIGRvbmUgd2l0aCBkaXJcbiAgICB9XG5cbiAgICAvLyBJZiBoZXJlLCBzcmMgaXMgYSBmaWxlXG5cbiAgICAvLyBXaGVuIGNvcHlpbmcgdG8gJy9wYXRoL2Rpcic6XG4gICAgLy8gICAgdGhpc0Rlc3QgPSAnL3BhdGgvZGlyL2ZpbGUxJ1xuICAgIHZhciB0aGlzRGVzdCA9IGRlc3Q7XG4gICAgaWYgKGZzLmV4aXN0c1N5bmMoZGVzdCkgJiYgZnMuc3RhdFN5bmMoZGVzdCkuaXNEaXJlY3RvcnkoKSlcbiAgICAgIHRoaXNEZXN0ID0gcGF0aC5ub3JtYWxpemUoZGVzdCArICcvJyArIHBhdGguYmFzZW5hbWUoc3JjKSk7XG5cbiAgICBpZiAoZnMuZXhpc3RzU3luYyh0aGlzRGVzdCkgJiYgIW9wdGlvbnMuZm9yY2UpIHtcbiAgICAgIGNvbW1vbi5lcnJvcignZGVzdCBmaWxlIGFscmVhZHkgZXhpc3RzOiAnICsgdGhpc0Rlc3QsIHRydWUpO1xuICAgICAgcmV0dXJuOyAvLyBza2lwIGZpbGVcbiAgICB9XG5cbiAgICBjb3B5RmlsZVN5bmMoc3JjLCB0aGlzRGVzdCk7XG4gIH0pOyAvLyBmb3JFYWNoKHNyYylcbn1cbm1vZHVsZS5leHBvcnRzID0gX2NwO1xuIiwidmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgX2NkID0gcmVxdWlyZSgnLi9jZCcpO1xudmFyIHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG5cbi8vIFB1c2hkL3BvcGQvZGlycyBpbnRlcm5hbHNcbnZhciBfZGlyU3RhY2sgPSBbXTtcblxuZnVuY3Rpb24gX2lzU3RhY2tJbmRleChpbmRleCkge1xuICByZXR1cm4gKC9eW1xcLStdXFxkKyQvKS50ZXN0KGluZGV4KTtcbn1cblxuZnVuY3Rpb24gX3BhcnNlU3RhY2tJbmRleChpbmRleCkge1xuICBpZiAoX2lzU3RhY2tJbmRleChpbmRleCkpIHtcbiAgICBpZiAoTWF0aC5hYnMoaW5kZXgpIDwgX2RpclN0YWNrLmxlbmd0aCArIDEpIHsgLy8gKzEgZm9yIHB3ZFxuICAgICAgcmV0dXJuICgvXi0vKS50ZXN0KGluZGV4KSA/IE51bWJlcihpbmRleCkgLSAxIDogTnVtYmVyKGluZGV4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29tbW9uLmVycm9yKGluZGV4ICsgJzogZGlyZWN0b3J5IHN0YWNrIGluZGV4IG91dCBvZiByYW5nZScpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBjb21tb24uZXJyb3IoaW5kZXggKyAnOiBpbnZhbGlkIG51bWJlcicpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9hY3R1YWxEaXJTdGFjaygpIHtcbiAgcmV0dXJuIFtwcm9jZXNzLmN3ZCgpXS5jb25jYXQoX2RpclN0YWNrKTtcbn1cblxuLy9AXG4vL0AgIyMjIHB1c2hkKFtvcHRpb25zLF0gW2RpciB8ICctTicgfCAnK04nXSlcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLW5gOiBTdXBwcmVzc2VzIHRoZSBub3JtYWwgY2hhbmdlIG9mIGRpcmVjdG9yeSB3aGVuIGFkZGluZyBkaXJlY3RvcmllcyB0byB0aGUgc3RhY2ssIHNvIHRoYXQgb25seSB0aGUgc3RhY2sgaXMgbWFuaXB1bGF0ZWQuXG4vL0Bcbi8vQCBBcmd1bWVudHM6XG4vL0Bcbi8vQCArIGBkaXJgOiBNYWtlcyB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSBiZSB0aGUgdG9wIG9mIHRoZSBzdGFjaywgYW5kIHRoZW4gZXhlY3V0ZXMgdGhlIGVxdWl2YWxlbnQgb2YgYGNkIGRpcmAuXG4vL0AgKyBgK05gOiBCcmluZ3MgdGhlIE50aCBkaXJlY3RvcnkgKGNvdW50aW5nIGZyb20gdGhlIGxlZnQgb2YgdGhlIGxpc3QgcHJpbnRlZCBieSBkaXJzLCBzdGFydGluZyB3aXRoIHplcm8pIHRvIHRoZSB0b3Agb2YgdGhlIGxpc3QgYnkgcm90YXRpbmcgdGhlIHN0YWNrLlxuLy9AICsgYC1OYDogQnJpbmdzIHRoZSBOdGggZGlyZWN0b3J5IChjb3VudGluZyBmcm9tIHRoZSByaWdodCBvZiB0aGUgbGlzdCBwcmludGVkIGJ5IGRpcnMsIHN0YXJ0aW5nIHdpdGggemVybykgdG8gdGhlIHRvcCBvZiB0aGUgbGlzdCBieSByb3RhdGluZyB0aGUgc3RhY2suXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCAvLyBwcm9jZXNzLmN3ZCgpID09PSAnL3Vzcidcbi8vQCBwdXNoZCgnL2V0YycpOyAvLyBSZXR1cm5zIC9ldGMgL3VzclxuLy9AIHB1c2hkKCcrMScpOyAgIC8vIFJldHVybnMgL3VzciAvZXRjXG4vL0AgYGBgXG4vL0Bcbi8vQCBTYXZlIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBvbiB0aGUgdG9wIG9mIHRoZSBkaXJlY3Rvcnkgc3RhY2sgYW5kIHRoZW4gY2QgdG8gYGRpcmAuIFdpdGggbm8gYXJndW1lbnRzLCBwdXNoZCBleGNoYW5nZXMgdGhlIHRvcCB0d28gZGlyZWN0b3JpZXMuIFJldHVybnMgYW4gYXJyYXkgb2YgcGF0aHMgaW4gdGhlIHN0YWNrLlxuZnVuY3Rpb24gX3B1c2hkKG9wdGlvbnMsIGRpcikge1xuICBpZiAoX2lzU3RhY2tJbmRleChvcHRpb25zKSkge1xuICAgIGRpciA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyA9ICcnO1xuICB9XG5cbiAgb3B0aW9ucyA9IGNvbW1vbi5wYXJzZU9wdGlvbnMob3B0aW9ucywge1xuICAgICduJyA6ICduby1jZCdcbiAgfSk7XG5cbiAgdmFyIGRpcnMgPSBfYWN0dWFsRGlyU3RhY2soKTtcblxuICBpZiAoZGlyID09PSAnKzAnKSB7XG4gICAgcmV0dXJuIGRpcnM7IC8vICswIGlzIGEgbm9vcFxuICB9IGVsc2UgaWYgKCFkaXIpIHtcbiAgICBpZiAoZGlycy5sZW5ndGggPiAxKSB7XG4gICAgICBkaXJzID0gZGlycy5zcGxpY2UoMSwgMSkuY29uY2F0KGRpcnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY29tbW9uLmVycm9yKCdubyBvdGhlciBkaXJlY3RvcnknKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoX2lzU3RhY2tJbmRleChkaXIpKSB7XG4gICAgdmFyIG4gPSBfcGFyc2VTdGFja0luZGV4KGRpcik7XG4gICAgZGlycyA9IGRpcnMuc2xpY2UobikuY29uY2F0KGRpcnMuc2xpY2UoMCwgbikpO1xuICB9IGVsc2Uge1xuICAgIGlmIChvcHRpb25zWyduby1jZCddKSB7XG4gICAgICBkaXJzLnNwbGljZSgxLCAwLCBkaXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkaXJzLnVuc2hpZnQoZGlyKTtcbiAgICB9XG4gIH1cblxuICBpZiAob3B0aW9uc1snbm8tY2QnXSkge1xuICAgIGRpcnMgPSBkaXJzLnNsaWNlKDEpO1xuICB9IGVsc2Uge1xuICAgIGRpciA9IHBhdGgucmVzb2x2ZShkaXJzLnNoaWZ0KCkpO1xuICAgIF9jZCgnJywgZGlyKTtcbiAgfVxuXG4gIF9kaXJTdGFjayA9IGRpcnM7XG4gIHJldHVybiBfZGlycygnJyk7XG59XG5leHBvcnRzLnB1c2hkID0gX3B1c2hkO1xuXG4vL0Bcbi8vQCAjIyMgcG9wZChbb3B0aW9ucyxdIFsnLU4nIHwgJytOJ10pXG4vL0Bcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYC1uYDogU3VwcHJlc3NlcyB0aGUgbm9ybWFsIGNoYW5nZSBvZiBkaXJlY3Rvcnkgd2hlbiByZW1vdmluZyBkaXJlY3RvcmllcyBmcm9tIHRoZSBzdGFjaywgc28gdGhhdCBvbmx5IHRoZSBzdGFjayBpcyBtYW5pcHVsYXRlZC5cbi8vQFxuLy9AIEFyZ3VtZW50czpcbi8vQFxuLy9AICsgYCtOYDogUmVtb3ZlcyB0aGUgTnRoIGRpcmVjdG9yeSAoY291bnRpbmcgZnJvbSB0aGUgbGVmdCBvZiB0aGUgbGlzdCBwcmludGVkIGJ5IGRpcnMpLCBzdGFydGluZyB3aXRoIHplcm8uXG4vL0AgKyBgLU5gOiBSZW1vdmVzIHRoZSBOdGggZGlyZWN0b3J5IChjb3VudGluZyBmcm9tIHRoZSByaWdodCBvZiB0aGUgbGlzdCBwcmludGVkIGJ5IGRpcnMpLCBzdGFydGluZyB3aXRoIHplcm8uXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBlY2hvKHByb2Nlc3MuY3dkKCkpOyAvLyAnL3Vzcidcbi8vQCBwdXNoZCgnL2V0YycpOyAgICAgICAvLyAnL2V0YyAvdXNyJ1xuLy9AIGVjaG8ocHJvY2Vzcy5jd2QoKSk7IC8vICcvZXRjJ1xuLy9AIHBvcGQoKTsgICAgICAgICAgICAgIC8vICcvdXNyJ1xuLy9AIGVjaG8ocHJvY2Vzcy5jd2QoKSk7IC8vICcvdXNyJ1xuLy9AIGBgYFxuLy9AXG4vL0AgV2hlbiBubyBhcmd1bWVudHMgYXJlIGdpdmVuLCBwb3BkIHJlbW92ZXMgdGhlIHRvcCBkaXJlY3RvcnkgZnJvbSB0aGUgc3RhY2sgYW5kIHBlcmZvcm1zIGEgY2QgdG8gdGhlIG5ldyB0b3AgZGlyZWN0b3J5LiBUaGUgZWxlbWVudHMgYXJlIG51bWJlcmVkIGZyb20gMCBzdGFydGluZyBhdCB0aGUgZmlyc3QgZGlyZWN0b3J5IGxpc3RlZCB3aXRoIGRpcnM7IGkuZS4sIHBvcGQgaXMgZXF1aXZhbGVudCB0byBwb3BkICswLiBSZXR1cm5zIGFuIGFycmF5IG9mIHBhdGhzIGluIHRoZSBzdGFjay5cbmZ1bmN0aW9uIF9wb3BkKG9wdGlvbnMsIGluZGV4KSB7XG4gIGlmIChfaXNTdGFja0luZGV4KG9wdGlvbnMpKSB7XG4gICAgaW5kZXggPSBvcHRpb25zO1xuICAgIG9wdGlvbnMgPSAnJztcbiAgfVxuXG4gIG9wdGlvbnMgPSBjb21tb24ucGFyc2VPcHRpb25zKG9wdGlvbnMsIHtcbiAgICAnbicgOiAnbm8tY2QnXG4gIH0pO1xuXG4gIGlmICghX2RpclN0YWNrLmxlbmd0aCkge1xuICAgIHJldHVybiBjb21tb24uZXJyb3IoJ2RpcmVjdG9yeSBzdGFjayBlbXB0eScpO1xuICB9XG5cbiAgaW5kZXggPSBfcGFyc2VTdGFja0luZGV4KGluZGV4IHx8ICcrMCcpO1xuXG4gIGlmIChvcHRpb25zWyduby1jZCddIHx8IGluZGV4ID4gMCB8fCBfZGlyU3RhY2subGVuZ3RoICsgaW5kZXggPT09IDApIHtcbiAgICBpbmRleCA9IGluZGV4ID4gMCA/IGluZGV4IC0gMSA6IGluZGV4O1xuICAgIF9kaXJTdGFjay5zcGxpY2UoaW5kZXgsIDEpO1xuICB9IGVsc2Uge1xuICAgIHZhciBkaXIgPSBwYXRoLnJlc29sdmUoX2RpclN0YWNrLnNoaWZ0KCkpO1xuICAgIF9jZCgnJywgZGlyKTtcbiAgfVxuXG4gIHJldHVybiBfZGlycygnJyk7XG59XG5leHBvcnRzLnBvcGQgPSBfcG9wZDtcblxuLy9AXG4vL0AgIyMjIGRpcnMoW29wdGlvbnMgfCAnK04nIHwgJy1OJ10pXG4vL0Bcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYC1jYDogQ2xlYXJzIHRoZSBkaXJlY3Rvcnkgc3RhY2sgYnkgZGVsZXRpbmcgYWxsIG9mIHRoZSBlbGVtZW50cy5cbi8vQFxuLy9AIEFyZ3VtZW50czpcbi8vQFxuLy9AICsgYCtOYDogRGlzcGxheXMgdGhlIE50aCBkaXJlY3RvcnkgKGNvdW50aW5nIGZyb20gdGhlIGxlZnQgb2YgdGhlIGxpc3QgcHJpbnRlZCBieSBkaXJzIHdoZW4gaW52b2tlZCB3aXRob3V0IG9wdGlvbnMpLCBzdGFydGluZyB3aXRoIHplcm8uXG4vL0AgKyBgLU5gOiBEaXNwbGF5cyB0aGUgTnRoIGRpcmVjdG9yeSAoY291bnRpbmcgZnJvbSB0aGUgcmlnaHQgb2YgdGhlIGxpc3QgcHJpbnRlZCBieSBkaXJzIHdoZW4gaW52b2tlZCB3aXRob3V0IG9wdGlvbnMpLCBzdGFydGluZyB3aXRoIHplcm8uXG4vL0Bcbi8vQCBEaXNwbGF5IHRoZSBsaXN0IG9mIGN1cnJlbnRseSByZW1lbWJlcmVkIGRpcmVjdG9yaWVzLiBSZXR1cm5zIGFuIGFycmF5IG9mIHBhdGhzIGluIHRoZSBzdGFjaywgb3IgYSBzaW5nbGUgcGF0aCBpZiArTiBvciAtTiB3YXMgc3BlY2lmaWVkLlxuLy9AXG4vL0AgU2VlIGFsc286IHB1c2hkLCBwb3BkXG5mdW5jdGlvbiBfZGlycyhvcHRpb25zLCBpbmRleCkge1xuICBpZiAoX2lzU3RhY2tJbmRleChvcHRpb25zKSkge1xuICAgIGluZGV4ID0gb3B0aW9ucztcbiAgICBvcHRpb25zID0gJyc7XG4gIH1cblxuICBvcHRpb25zID0gY29tbW9uLnBhcnNlT3B0aW9ucyhvcHRpb25zLCB7XG4gICAgJ2MnIDogJ2NsZWFyJ1xuICB9KTtcblxuICBpZiAob3B0aW9uc1snY2xlYXInXSkge1xuICAgIF9kaXJTdGFjayA9IFtdO1xuICAgIHJldHVybiBfZGlyU3RhY2s7XG4gIH1cblxuICB2YXIgc3RhY2sgPSBfYWN0dWFsRGlyU3RhY2soKTtcblxuICBpZiAoaW5kZXgpIHtcbiAgICBpbmRleCA9IF9wYXJzZVN0YWNrSW5kZXgoaW5kZXgpO1xuXG4gICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgaW5kZXggPSBzdGFjay5sZW5ndGggKyBpbmRleDtcbiAgICB9XG5cbiAgICBjb21tb24ubG9nKHN0YWNrW2luZGV4XSk7XG4gICAgcmV0dXJuIHN0YWNrW2luZGV4XTtcbiAgfVxuXG4gIGNvbW1vbi5sb2coc3RhY2suam9pbignICcpKTtcblxuICByZXR1cm4gc3RhY2s7XG59XG5leHBvcnRzLmRpcnMgPSBfZGlycztcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xuXG4vL0Bcbi8vQCAjIyMgZWNobyhzdHJpbmcgWyxzdHJpbmcgLi4uXSlcbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIGVjaG8oJ2hlbGxvIHdvcmxkJyk7XG4vL0AgdmFyIHN0ciA9IGVjaG8oJ2hlbGxvIHdvcmxkJyk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBQcmludHMgc3RyaW5nIHRvIHN0ZG91dCwgYW5kIHJldHVybnMgc3RyaW5nIHdpdGggYWRkaXRpb25hbCB1dGlsaXR5IG1ldGhvZHNcbi8vQCBsaWtlIGAudG8oKWAuXG5mdW5jdGlvbiBfZWNobygpIHtcbiAgdmFyIG1lc3NhZ2VzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuICBjb25zb2xlLmxvZy5hcHBseSh0aGlzLCBtZXNzYWdlcyk7XG4gIHJldHVybiBjb21tb24uU2hlbGxTdHJpbmcobWVzc2FnZXMuam9pbignICcpKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gX2VjaG87XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxuLy9AXG4vL0AgIyMjIGVycm9yKClcbi8vQCBUZXN0cyBpZiBlcnJvciBvY2N1cnJlZCBpbiB0aGUgbGFzdCBjb21tYW5kLiBSZXR1cm5zIGBudWxsYCBpZiBubyBlcnJvciBvY2N1cnJlZCxcbi8vQCBvdGhlcndpc2UgcmV0dXJucyBzdHJpbmcgZXhwbGFpbmluZyB0aGUgZXJyb3JcbmZ1bmN0aW9uIGVycm9yKCkge1xuICByZXR1cm4gY29tbW9uLnN0YXRlLmVycm9yO1xufTtcbm1vZHVsZS5leHBvcnRzID0gZXJyb3I7XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBfdGVtcERpciA9IHJlcXVpcmUoJy4vdGVtcGRpcicpO1xudmFyIF9wd2QgPSByZXF1aXJlKCcuL3B3ZCcpO1xudmFyIHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xudmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpO1xuXG4vLyBIYWNrIHRvIHJ1biBjaGlsZF9wcm9jZXNzLmV4ZWMoKSBzeW5jaHJvbm91c2x5IChzeW5jIGF2b2lkcyBjYWxsYmFjayBoZWxsKVxuLy8gVXNlcyBhIGN1c3RvbSB3YWl0IGxvb3AgdGhhdCBjaGVja3MgZm9yIGEgZmxhZyBmaWxlLCBjcmVhdGVkIHdoZW4gdGhlIGNoaWxkIHByb2Nlc3MgaXMgZG9uZS5cbi8vIChDYW4ndCBkbyBhIHdhaXQgbG9vcCB0aGF0IGNoZWNrcyBmb3IgaW50ZXJuYWwgTm9kZSB2YXJpYWJsZXMvbWVzc2FnZXMgYXNcbi8vIE5vZGUgaXMgc2luZ2xlLXRocmVhZGVkOyBjYWxsYmFja3MgYW5kIG90aGVyIGludGVybmFsIHN0YXRlIGNoYW5nZXMgYXJlIGRvbmUgaW4gdGhlXG4vLyBldmVudCBsb29wKS5cbmZ1bmN0aW9uIGV4ZWNTeW5jKGNtZCwgb3B0cykge1xuICB2YXIgdGVtcERpciA9IF90ZW1wRGlyKCk7XG4gIHZhciBzdGRvdXRGaWxlID0gcGF0aC5yZXNvbHZlKHRlbXBEaXIrJy8nK2NvbW1vbi5yYW5kb21GaWxlTmFtZSgpKSxcbiAgICAgIGNvZGVGaWxlID0gcGF0aC5yZXNvbHZlKHRlbXBEaXIrJy8nK2NvbW1vbi5yYW5kb21GaWxlTmFtZSgpKSxcbiAgICAgIHNjcmlwdEZpbGUgPSBwYXRoLnJlc29sdmUodGVtcERpcisnLycrY29tbW9uLnJhbmRvbUZpbGVOYW1lKCkpLFxuICAgICAgc2xlZXBGaWxlID0gcGF0aC5yZXNvbHZlKHRlbXBEaXIrJy8nK2NvbW1vbi5yYW5kb21GaWxlTmFtZSgpKTtcblxuICB2YXIgb3B0aW9ucyA9IGNvbW1vbi5leHRlbmQoe1xuICAgIHNpbGVudDogY29tbW9uLmNvbmZpZy5zaWxlbnRcbiAgfSwgb3B0cyk7XG5cbiAgdmFyIHByZXZpb3VzU3Rkb3V0Q29udGVudCA9ICcnO1xuICAvLyBFY2hvZXMgc3Rkb3V0IGNoYW5nZXMgZnJvbSBydW5uaW5nIHByb2Nlc3MsIGlmIG5vdCBzaWxlbnRcbiAgZnVuY3Rpb24gdXBkYXRlU3Rkb3V0KCkge1xuICAgIGlmIChvcHRpb25zLnNpbGVudCB8fCAhZnMuZXhpc3RzU3luYyhzdGRvdXRGaWxlKSlcbiAgICAgIHJldHVybjtcblxuICAgIHZhciBzdGRvdXRDb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKHN0ZG91dEZpbGUsICd1dGY4Jyk7XG4gICAgLy8gTm8gY2hhbmdlcyBzaW5jZSBsYXN0IHRpbWU/XG4gICAgaWYgKHN0ZG91dENvbnRlbnQubGVuZ3RoIDw9IHByZXZpb3VzU3Rkb3V0Q29udGVudC5sZW5ndGgpXG4gICAgICByZXR1cm47XG5cbiAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShzdGRvdXRDb250ZW50LnN1YnN0cihwcmV2aW91c1N0ZG91dENvbnRlbnQubGVuZ3RoKSk7XG4gICAgcHJldmlvdXNTdGRvdXRDb250ZW50ID0gc3Rkb3V0Q29udGVudDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGVzY2FwZShzdHIpIHtcbiAgICByZXR1cm4gKHN0cisnJykucmVwbGFjZSgvKFtcXFxcXCInXSkvZywgXCJcXFxcJDFcIikucmVwbGFjZSgvXFwwL2csIFwiXFxcXDBcIik7XG4gIH1cblxuICBjbWQgKz0gJyA+ICcrc3Rkb3V0RmlsZSsnIDI+JjEnOyAvLyB3b3JrcyBvbiBib3RoIHdpbi91bml4XG5cbiAgdmFyIHNjcmlwdCA9XG4gICBcInZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKSxcIiArXG4gICBcIiAgICAgZnMgPSByZXF1aXJlKCdmcycpO1wiICtcbiAgIFwiY2hpbGQuZXhlYygnXCIrZXNjYXBlKGNtZCkrXCInLCB7ZW52OiBwcm9jZXNzLmVudiwgbWF4QnVmZmVyOiAyMCoxMDI0KjEwMjR9LCBmdW5jdGlvbihlcnIpIHtcIiArXG4gICBcIiAgZnMud3JpdGVGaWxlU3luYygnXCIrZXNjYXBlKGNvZGVGaWxlKStcIicsIGVyciA/IGVyci5jb2RlLnRvU3RyaW5nKCkgOiAnMCcpO1wiICtcbiAgIFwifSk7XCI7XG5cbiAgaWYgKGZzLmV4aXN0c1N5bmMoc2NyaXB0RmlsZSkpIGNvbW1vbi51bmxpbmtTeW5jKHNjcmlwdEZpbGUpO1xuICBpZiAoZnMuZXhpc3RzU3luYyhzdGRvdXRGaWxlKSkgY29tbW9uLnVubGlua1N5bmMoc3Rkb3V0RmlsZSk7XG4gIGlmIChmcy5leGlzdHNTeW5jKGNvZGVGaWxlKSkgY29tbW9uLnVubGlua1N5bmMoY29kZUZpbGUpO1xuXG4gIGZzLndyaXRlRmlsZVN5bmMoc2NyaXB0RmlsZSwgc2NyaXB0KTtcbiAgY2hpbGQuZXhlYygnXCInK3Byb2Nlc3MuZXhlY1BhdGgrJ1wiICcrc2NyaXB0RmlsZSwge1xuICAgIGVudjogcHJvY2Vzcy5lbnYsXG4gICAgY3dkOiBfcHdkKCksXG4gICAgbWF4QnVmZmVyOiAyMCoxMDI0KjEwMjRcbiAgfSk7XG5cbiAgLy8gVGhlIHdhaXQgbG9vcFxuICAvLyBzbGVlcEZpbGUgaXMgdXNlZCBhcyBhIGR1bW15IEkvTyBvcCB0byBtaXRpZ2F0ZSB1bm5lY2Vzc2FyeSBDUFUgdXNhZ2VcbiAgLy8gKHRyaWVkIG1hbnkgSS9PIHN5bmMgb3BzLCB3cml0ZUZpbGVTeW5jKCkgc2VlbXMgdG8gYmUgb25seSBvbmUgdGhhdCBpcyBlZmZlY3RpdmUgaW4gcmVkdWNpbmdcbiAgLy8gQ1BVIHVzYWdlLCB0aG91Z2ggYXBwYXJlbnRseSBub3Qgc28gbXVjaCBvbiBXaW5kb3dzKVxuICB3aGlsZSAoIWZzLmV4aXN0c1N5bmMoY29kZUZpbGUpKSB7IHVwZGF0ZVN0ZG91dCgpOyBmcy53cml0ZUZpbGVTeW5jKHNsZWVwRmlsZSwgJ2EnKTsgfVxuICB3aGlsZSAoIWZzLmV4aXN0c1N5bmMoc3Rkb3V0RmlsZSkpIHsgdXBkYXRlU3Rkb3V0KCk7IGZzLndyaXRlRmlsZVN5bmMoc2xlZXBGaWxlLCAnYScpOyB9XG5cbiAgLy8gQXQgdGhpcyBwb2ludCBjb2RlRmlsZSBleGlzdHMsIGJ1dCBpdCdzIG5vdCBuZWNlc3NhcmlseSBmbHVzaGVkIHlldC5cbiAgLy8gS2VlcCByZWFkaW5nIGl0IHVudGlsIGl0IGlzLlxuICB2YXIgY29kZSA9IHBhcnNlSW50KCcnLCAxMCk7XG4gIHdoaWxlIChpc05hTihjb2RlKSkge1xuICAgIGNvZGUgPSBwYXJzZUludChmcy5yZWFkRmlsZVN5bmMoY29kZUZpbGUsICd1dGY4JyksIDEwKTtcbiAgfVxuXG4gIHZhciBzdGRvdXQgPSBmcy5yZWFkRmlsZVN5bmMoc3Rkb3V0RmlsZSwgJ3V0ZjgnKTtcblxuICAvLyBObyBiaWdnaWUgaWYgd2UgY2FuJ3QgZXJhc2UgdGhlIGZpbGVzIG5vdyAtLSB0aGV5J3JlIGluIGEgdGVtcCBkaXIgYW55d2F5XG4gIHRyeSB7IGNvbW1vbi51bmxpbmtTeW5jKHNjcmlwdEZpbGUpOyB9IGNhdGNoKGUpIHt9XG4gIHRyeSB7IGNvbW1vbi51bmxpbmtTeW5jKHN0ZG91dEZpbGUpOyB9IGNhdGNoKGUpIHt9XG4gIHRyeSB7IGNvbW1vbi51bmxpbmtTeW5jKGNvZGVGaWxlKTsgfSBjYXRjaChlKSB7fVxuICB0cnkgeyBjb21tb24udW5saW5rU3luYyhzbGVlcEZpbGUpOyB9IGNhdGNoKGUpIHt9XG5cbiAgLy8gc29tZSBzaGVsbCByZXR1cm4gY29kZXMgYXJlIGRlZmluZWQgYXMgZXJyb3JzLCBwZXIgaHR0cDovL3RsZHAub3JnL0xEUC9hYnMvaHRtbC9leGl0Y29kZXMuaHRtbFxuICBpZiAoY29kZSA9PT0gMSB8fCBjb2RlID09PSAyIHx8IGNvZGUgPj0gMTI2KSAge1xuICAgICAgY29tbW9uLmVycm9yKCcnLCB0cnVlKTsgLy8gdW5peC9zaGVsbCBkb2Vzbid0IHJlYWxseSBnaXZlIGFuIGVycm9yIG1lc3NhZ2UgYWZ0ZXIgbm9uLXplcm8gZXhpdCBjb2Rlc1xuICB9XG4gIC8vIFRydWUgaWYgc3VjY2Vzc2Z1bCwgZmFsc2UgaWYgbm90XG4gIHZhciBvYmogPSB7XG4gICAgY29kZTogY29kZSxcbiAgICBvdXRwdXQ6IHN0ZG91dFxuICB9O1xuICByZXR1cm4gb2JqO1xufSAvLyBleGVjU3luYygpXG5cbi8vIFdyYXBwZXIgYXJvdW5kIGV4ZWMoKSB0byBlbmFibGUgZWNob2luZyBvdXRwdXQgdG8gY29uc29sZSBpbiByZWFsIHRpbWVcbmZ1bmN0aW9uIGV4ZWNBc3luYyhjbWQsIG9wdHMsIGNhbGxiYWNrKSB7XG4gIHZhciBvdXRwdXQgPSAnJztcblxuICB2YXIgb3B0aW9ucyA9IGNvbW1vbi5leHRlbmQoe1xuICAgIHNpbGVudDogY29tbW9uLmNvbmZpZy5zaWxlbnRcbiAgfSwgb3B0cyk7XG5cbiAgdmFyIGMgPSBjaGlsZC5leGVjKGNtZCwge2VudjogcHJvY2Vzcy5lbnYsIG1heEJ1ZmZlcjogMjAqMTAyNCoxMDI0fSwgZnVuY3Rpb24oZXJyKSB7XG4gICAgaWYgKGNhbGxiYWNrKVxuICAgICAgY2FsbGJhY2soZXJyID8gZXJyLmNvZGUgOiAwLCBvdXRwdXQpO1xuICB9KTtcblxuICBjLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uKGRhdGEpIHtcbiAgICBvdXRwdXQgKz0gZGF0YTtcbiAgICBpZiAoIW9wdGlvbnMuc2lsZW50KVxuICAgICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoZGF0YSk7XG4gIH0pO1xuXG4gIGMuc3RkZXJyLm9uKCdkYXRhJywgZnVuY3Rpb24oZGF0YSkge1xuICAgIG91dHB1dCArPSBkYXRhO1xuICAgIGlmICghb3B0aW9ucy5zaWxlbnQpXG4gICAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShkYXRhKTtcbiAgfSk7XG5cbiAgcmV0dXJuIGM7XG59XG5cbi8vQFxuLy9AICMjIyBleGVjKGNvbW1hbmQgWywgb3B0aW9uc10gWywgY2FsbGJhY2tdKVxuLy9AIEF2YWlsYWJsZSBvcHRpb25zIChhbGwgYGZhbHNlYCBieSBkZWZhdWx0KTpcbi8vQFxuLy9AICsgYGFzeW5jYDogQXN5bmNocm9ub3VzIGV4ZWN1dGlvbi4gRGVmYXVsdHMgdG8gdHJ1ZSBpZiBhIGNhbGxiYWNrIGlzIHByb3ZpZGVkLlxuLy9AICsgYHNpbGVudGA6IERvIG5vdCBlY2hvIHByb2dyYW0gb3V0cHV0IHRvIGNvbnNvbGUuXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCB2YXIgdmVyc2lvbiA9IGV4ZWMoJ25vZGUgLS12ZXJzaW9uJywge3NpbGVudDp0cnVlfSkub3V0cHV0O1xuLy9AXG4vL0AgdmFyIGNoaWxkID0gZXhlYygnc29tZV9sb25nX3J1bm5pbmdfcHJvY2VzcycsIHthc3luYzp0cnVlfSk7XG4vL0AgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24oZGF0YSkge1xuLy9AICAgLyogLi4uIGRvIHNvbWV0aGluZyB3aXRoIGRhdGEgLi4uICovXG4vL0AgfSk7XG4vL0Bcbi8vQCBleGVjKCdzb21lX2xvbmdfcnVubmluZ19wcm9jZXNzJywgZnVuY3Rpb24oY29kZSwgb3V0cHV0KSB7XG4vL0AgICBjb25zb2xlLmxvZygnRXhpdCBjb2RlOicsIGNvZGUpO1xuLy9AICAgY29uc29sZS5sb2coJ1Byb2dyYW0gb3V0cHV0OicsIG91dHB1dCk7XG4vL0AgfSk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBFeGVjdXRlcyB0aGUgZ2l2ZW4gYGNvbW1hbmRgIF9zeW5jaHJvbm91c2x5XywgdW5sZXNzIG90aGVyd2lzZSBzcGVjaWZpZWQuXG4vL0AgV2hlbiBpbiBzeW5jaHJvbm91cyBtb2RlIHJldHVybnMgdGhlIG9iamVjdCBgeyBjb2RlOi4uLiwgb3V0cHV0Oi4uLiB9YCwgY29udGFpbmluZyB0aGUgcHJvZ3JhbSdzXG4vL0AgYG91dHB1dGAgKHN0ZG91dCArIHN0ZGVycikgIGFuZCBpdHMgZXhpdCBgY29kZWAuIE90aGVyd2lzZSByZXR1cm5zIHRoZSBjaGlsZCBwcm9jZXNzIG9iamVjdCwgYW5kXG4vL0AgdGhlIGBjYWxsYmFja2AgZ2V0cyB0aGUgYXJndW1lbnRzIGAoY29kZSwgb3V0cHV0KWAuXG4vL0Bcbi8vQCAqKk5vdGU6KiogRm9yIGxvbmctbGl2ZWQgcHJvY2Vzc2VzLCBpdCdzIGJlc3QgdG8gcnVuIGBleGVjKClgIGFzeW5jaHJvbm91c2x5IGFzXG4vL0AgdGhlIGN1cnJlbnQgc3luY2hyb25vdXMgaW1wbGVtZW50YXRpb24gdXNlcyBhIGxvdCBvZiBDUFUuIFRoaXMgc2hvdWxkIGJlIGdldHRpbmdcbi8vQCBmaXhlZCBzb29uLlxuZnVuY3Rpb24gX2V4ZWMoY29tbWFuZCwgb3B0aW9ucywgY2FsbGJhY2spIHtcbiAgaWYgKCFjb21tYW5kKVxuICAgIGNvbW1vbi5lcnJvcignbXVzdCBzcGVjaWZ5IGNvbW1hbmQnKTtcblxuICAvLyBDYWxsYmFjayBpcyBkZWZpbmVkIGluc3RlYWQgb2Ygb3B0aW9ucy5cbiAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBvcHRpb25zO1xuICAgIG9wdGlvbnMgPSB7IGFzeW5jOiB0cnVlIH07XG4gIH1cblxuICAvLyBDYWxsYmFjayBpcyBkZWZpbmVkIHdpdGggb3B0aW9ucy5cbiAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICBvcHRpb25zLmFzeW5jID0gdHJ1ZTtcbiAgfVxuXG4gIG9wdGlvbnMgPSBjb21tb24uZXh0ZW5kKHtcbiAgICBzaWxlbnQ6IGNvbW1vbi5jb25maWcuc2lsZW50LFxuICAgIGFzeW5jOiBmYWxzZVxuICB9LCBvcHRpb25zKTtcblxuICBpZiAob3B0aW9ucy5hc3luYylcbiAgICByZXR1cm4gZXhlY0FzeW5jKGNvbW1hbmQsIG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgZWxzZVxuICAgIHJldHVybiBleGVjU3luYyhjb21tYW5kLCBvcHRpb25zKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gX2V4ZWM7XG4iLCJ2YXIgZnMgPSByZXF1aXJlKCdmcycpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgX2xzID0gcmVxdWlyZSgnLi9scycpO1xuXG4vL0Bcbi8vQCAjIyMgZmluZChwYXRoIFsscGF0aCAuLi5dKVxuLy9AICMjIyBmaW5kKHBhdGhfYXJyYXkpXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgZmluZCgnc3JjJywgJ2xpYicpO1xuLy9AIGZpbmQoWydzcmMnLCAnbGliJ10pOyAvLyBzYW1lIGFzIGFib3ZlXG4vL0AgZmluZCgnLicpLmZpbHRlcihmdW5jdGlvbihmaWxlKSB7IHJldHVybiBmaWxlLm1hdGNoKC9cXC5qcyQvKTsgfSk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBSZXR1cm5zIGFycmF5IG9mIGFsbCBmaWxlcyAoaG93ZXZlciBkZWVwKSBpbiB0aGUgZ2l2ZW4gcGF0aHMuXG4vL0Bcbi8vQCBUaGUgbWFpbiBkaWZmZXJlbmNlIGZyb20gYGxzKCctUicsIHBhdGgpYCBpcyB0aGF0IHRoZSByZXN1bHRpbmcgZmlsZSBuYW1lc1xuLy9AIGluY2x1ZGUgdGhlIGJhc2UgZGlyZWN0b3JpZXMsIGUuZy4gYGxpYi9yZXNvdXJjZXMvZmlsZTFgIGluc3RlYWQgb2YganVzdCBgZmlsZTFgLlxuZnVuY3Rpb24gX2ZpbmQob3B0aW9ucywgcGF0aHMpIHtcbiAgaWYgKCFwYXRocylcbiAgICBjb21tb24uZXJyb3IoJ25vIHBhdGggc3BlY2lmaWVkJyk7XG4gIGVsc2UgaWYgKHR5cGVvZiBwYXRocyA9PT0gJ29iamVjdCcpXG4gICAgcGF0aHMgPSBwYXRoczsgLy8gYXNzdW1lIGFycmF5XG4gIGVsc2UgaWYgKHR5cGVvZiBwYXRocyA9PT0gJ3N0cmluZycpXG4gICAgcGF0aHMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG5cbiAgdmFyIGxpc3QgPSBbXTtcblxuICBmdW5jdGlvbiBwdXNoRmlsZShmaWxlKSB7XG4gICAgaWYgKGNvbW1vbi5wbGF0Zm9ybSA9PT0gJ3dpbicpXG4gICAgICBmaWxlID0gZmlsZS5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG4gICAgbGlzdC5wdXNoKGZpbGUpO1xuICB9XG5cbiAgLy8gd2h5IG5vdCBzaW1wbHkgZG8gbHMoJy1SJywgcGF0aHMpPyBiZWNhdXNlIHRoZSBvdXRwdXQgd291bGRuJ3QgZ2l2ZSB0aGUgYmFzZSBkaXJzXG4gIC8vIHRvIGdldCB0aGUgYmFzZSBkaXIgaW4gdGhlIG91dHB1dCwgd2UgbmVlZCBpbnN0ZWFkIGxzKCctUicsICdkaXIvKicpIGZvciBldmVyeSBkaXJlY3RvcnlcblxuICBwYXRocy5mb3JFYWNoKGZ1bmN0aW9uKGZpbGUpIHtcbiAgICBwdXNoRmlsZShmaWxlKTtcblxuICAgIGlmIChmcy5zdGF0U3luYyhmaWxlKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICBfbHMoJy1SQScsIGZpbGUrJy8qJykuZm9yRWFjaChmdW5jdGlvbihzdWJmaWxlKSB7XG4gICAgICAgIHB1c2hGaWxlKHN1YmZpbGUpO1xuICAgICAgfSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gbGlzdDtcbn1cbm1vZHVsZS5leHBvcnRzID0gX2ZpbmQ7XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5cbi8vQFxuLy9AICMjIyBncmVwKFtvcHRpb25zICxdIHJlZ2V4X2ZpbHRlciwgZmlsZSBbLCBmaWxlIC4uLl0pXG4vL0AgIyMjIGdyZXAoW29wdGlvbnMgLF0gcmVnZXhfZmlsdGVyLCBmaWxlX2FycmF5KVxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLXZgOiBJbnZlcnNlIHRoZSBzZW5zZSBvZiB0aGUgcmVnZXggYW5kIHByaW50IHRoZSBsaW5lcyBub3QgbWF0Y2hpbmcgdGhlIGNyaXRlcmlhLlxuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgZ3JlcCgnLXYnLCAnR0xPQkFMX1ZBUklBQkxFJywgJyouanMnKTtcbi8vQCBncmVwKCdHTE9CQUxfVkFSSUFCTEUnLCAnKi5qcycpO1xuLy9AIGBgYFxuLy9AXG4vL0AgUmVhZHMgaW5wdXQgc3RyaW5nIGZyb20gZ2l2ZW4gZmlsZXMgYW5kIHJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhbGwgbGluZXMgb2YgdGhlXG4vL0AgZmlsZSB0aGF0IG1hdGNoIHRoZSBnaXZlbiBgcmVnZXhfZmlsdGVyYC4gV2lsZGNhcmQgYCpgIGFjY2VwdGVkLlxuZnVuY3Rpb24gX2dyZXAob3B0aW9ucywgcmVnZXgsIGZpbGVzKSB7XG4gIG9wdGlvbnMgPSBjb21tb24ucGFyc2VPcHRpb25zKG9wdGlvbnMsIHtcbiAgICAndic6ICdpbnZlcnNlJ1xuICB9KTtcblxuICBpZiAoIWZpbGVzKVxuICAgIGNvbW1vbi5lcnJvcignbm8gcGF0aHMgZ2l2ZW4nKTtcblxuICBpZiAodHlwZW9mIGZpbGVzID09PSAnc3RyaW5nJylcbiAgICBmaWxlcyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKTtcbiAgLy8gaWYgaXQncyBhcnJheSBsZWF2ZSBpdCBhcyBpdCBpc1xuXG4gIGZpbGVzID0gY29tbW9uLmV4cGFuZChmaWxlcyk7XG5cbiAgdmFyIGdyZXAgPSAnJztcbiAgZmlsZXMuZm9yRWFjaChmdW5jdGlvbihmaWxlKSB7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKGZpbGUpKSB7XG4gICAgICBjb21tb24uZXJyb3IoJ25vIHN1Y2ggZmlsZSBvciBkaXJlY3Rvcnk6ICcgKyBmaWxlLCB0cnVlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY29udGVudHMgPSBmcy5yZWFkRmlsZVN5bmMoZmlsZSwgJ3V0ZjgnKSxcbiAgICAgICAgbGluZXMgPSBjb250ZW50cy5zcGxpdCgvXFxyKlxcbi8pO1xuICAgIGxpbmVzLmZvckVhY2goZnVuY3Rpb24obGluZSkge1xuICAgICAgdmFyIG1hdGNoZWQgPSBsaW5lLm1hdGNoKHJlZ2V4KTtcbiAgICAgIGlmICgob3B0aW9ucy5pbnZlcnNlICYmICFtYXRjaGVkKSB8fCAoIW9wdGlvbnMuaW52ZXJzZSAmJiBtYXRjaGVkKSlcbiAgICAgICAgZ3JlcCArPSBsaW5lICsgJ1xcbic7XG4gICAgfSk7XG4gIH0pO1xuXG4gIHJldHVybiBjb21tb24uU2hlbGxTdHJpbmcoZ3JlcCk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF9ncmVwO1xuIiwidmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcbnZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgb3MgPSByZXF1aXJlKCdvcycpO1xuXG4vL0Bcbi8vQCAjIyMgbG4ob3B0aW9ucywgc291cmNlLCBkZXN0KVxuLy9AICMjIyBsbihzb3VyY2UsIGRlc3QpXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGBzYDogc3ltbGlua1xuLy9AICsgYGZgOiBmb3JjZVxuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgbG4oJ2ZpbGUnLCAnbmV3bGluaycpO1xuLy9AIGxuKCctc2YnLCAnZmlsZScsICdleGlzdGluZycpO1xuLy9AIGBgYFxuLy9AXG4vL0AgTGlua3Mgc291cmNlIHRvIGRlc3QuIFVzZSAtZiB0byBmb3JjZSB0aGUgbGluaywgc2hvdWxkIGRlc3QgYWxyZWFkeSBleGlzdC5cbmZ1bmN0aW9uIF9sbihvcHRpb25zLCBzb3VyY2UsIGRlc3QpIHtcbiAgb3B0aW9ucyA9IGNvbW1vbi5wYXJzZU9wdGlvbnMob3B0aW9ucywge1xuICAgICdzJzogJ3N5bWxpbmsnLFxuICAgICdmJzogJ2ZvcmNlJ1xuICB9KTtcblxuICBpZiAoIXNvdXJjZSB8fCAhZGVzdCkge1xuICAgIGNvbW1vbi5lcnJvcignTWlzc2luZyA8c291cmNlPiBhbmQvb3IgPGRlc3Q+Jyk7XG4gIH1cblxuICBzb3VyY2UgPSBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgU3RyaW5nKHNvdXJjZSkpO1xuICBkZXN0ID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIFN0cmluZyhkZXN0KSk7XG5cbiAgaWYgKCFmcy5leGlzdHNTeW5jKHNvdXJjZSkpIHtcbiAgICBjb21tb24uZXJyb3IoJ1NvdXJjZSBmaWxlIGRvZXMgbm90IGV4aXN0JywgdHJ1ZSk7XG4gIH1cblxuICBpZiAoZnMuZXhpc3RzU3luYyhkZXN0KSkge1xuICAgIGlmICghb3B0aW9ucy5mb3JjZSkge1xuICAgICAgY29tbW9uLmVycm9yKCdEZXN0aW5hdGlvbiBmaWxlIGV4aXN0cycsIHRydWUpO1xuICAgIH1cblxuICAgIGZzLnVubGlua1N5bmMoZGVzdCk7XG4gIH1cblxuICBpZiAob3B0aW9ucy5zeW1saW5rKSB7XG4gICAgZnMuc3ltbGlua1N5bmMoc291cmNlLCBkZXN0LCBvcy5wbGF0Zm9ybSgpID09PSBcIndpbjMyXCIgPyBcImp1bmN0aW9uXCIgOiBudWxsKTtcbiAgfSBlbHNlIHtcbiAgICBmcy5saW5rU3luYyhzb3VyY2UsIGRlc3QsIG9zLnBsYXRmb3JtKCkgPT09IFwid2luMzJcIiA/IFwianVuY3Rpb25cIiA6IG51bGwpO1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IF9sbjtcbiIsInZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcbnZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIF9jZCA9IHJlcXVpcmUoJy4vY2QnKTtcbnZhciBfcHdkID0gcmVxdWlyZSgnLi9wd2QnKTtcblxuLy9AXG4vL0AgIyMjIGxzKFtvcHRpb25zICxdIHBhdGggWyxwYXRoIC4uLl0pXG4vL0AgIyMjIGxzKFtvcHRpb25zICxdIHBhdGhfYXJyYXkpXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGAtUmA6IHJlY3Vyc2l2ZVxuLy9AICsgYC1BYDogYWxsIGZpbGVzIChpbmNsdWRlIGZpbGVzIGJlZ2lubmluZyB3aXRoIGAuYCwgZXhjZXB0IGZvciBgLmAgYW5kIGAuLmApXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBscygncHJvanMvKi5qcycpO1xuLy9AIGxzKCctUicsICcvdXNlcnMvbWUnLCAnL3RtcCcpO1xuLy9AIGxzKCctUicsIFsnL3VzZXJzL21lJywgJy90bXAnXSk7IC8vIHNhbWUgYXMgYWJvdmVcbi8vQCBgYGBcbi8vQFxuLy9AIFJldHVybnMgYXJyYXkgb2YgZmlsZXMgaW4gdGhlIGdpdmVuIHBhdGgsIG9yIGluIGN1cnJlbnQgZGlyZWN0b3J5IGlmIG5vIHBhdGggcHJvdmlkZWQuXG5mdW5jdGlvbiBfbHMob3B0aW9ucywgcGF0aHMpIHtcbiAgb3B0aW9ucyA9IGNvbW1vbi5wYXJzZU9wdGlvbnMob3B0aW9ucywge1xuICAgICdSJzogJ3JlY3Vyc2l2ZScsXG4gICAgJ0EnOiAnYWxsJyxcbiAgICAnYSc6ICdhbGxfZGVwcmVjYXRlZCdcbiAgfSk7XG5cbiAgaWYgKG9wdGlvbnMuYWxsX2RlcHJlY2F0ZWQpIHtcbiAgICAvLyBXZSB3b24ndCBzdXBwb3J0IHRoZSAtYSBvcHRpb24gYXMgaXQncyBoYXJkIHRvIGltYWdlIHdoeSBpdCdzIHVzZWZ1bFxuICAgIC8vIChpdCBpbmNsdWRlcyAnLicgYW5kICcuLicgaW4gYWRkaXRpb24gdG8gJy4qJyBmaWxlcylcbiAgICAvLyBGb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgd2UnbGwgZHVtcCBhIGRlcHJlY2F0ZWQgbWVzc2FnZSBhbmQgcHJvY2VlZCBhcyBiZWZvcmVcbiAgICBjb21tb24ubG9nKCdsczogT3B0aW9uIC1hIGlzIGRlcHJlY2F0ZWQuIFVzZSAtQSBpbnN0ZWFkJyk7XG4gICAgb3B0aW9ucy5hbGwgPSB0cnVlO1xuICB9XG5cbiAgaWYgKCFwYXRocylcbiAgICBwYXRocyA9IFsnLiddO1xuICBlbHNlIGlmICh0eXBlb2YgcGF0aHMgPT09ICdvYmplY3QnKVxuICAgIHBhdGhzID0gcGF0aHM7IC8vIGFzc3VtZSBhcnJheVxuICBlbHNlIGlmICh0eXBlb2YgcGF0aHMgPT09ICdzdHJpbmcnKVxuICAgIHBhdGhzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gIHZhciBsaXN0ID0gW107XG5cbiAgLy8gQ29uZGl0aW9uYWxseSBwdXNoZXMgZmlsZSB0byBsaXN0IC0gcmV0dXJucyB0cnVlIGlmIHB1c2hlZCwgZmFsc2Ugb3RoZXJ3aXNlXG4gIC8vIChlLmcuIHByZXZlbnRzIGhpZGRlbiBmaWxlcyB0byBiZSBpbmNsdWRlZCB1bmxlc3MgZXhwbGljaXRseSB0b2xkIHNvKVxuICBmdW5jdGlvbiBwdXNoRmlsZShmaWxlLCBxdWVyeSkge1xuICAgIC8vIGhpZGRlbiBmaWxlP1xuICAgIGlmIChwYXRoLmJhc2VuYW1lKGZpbGUpWzBdID09PSAnLicpIHtcbiAgICAgIC8vIG5vdCBleHBsaWNpdGx5IGFza2luZyBmb3IgaGlkZGVuIGZpbGVzP1xuICAgICAgaWYgKCFvcHRpb25zLmFsbCAmJiAhKHBhdGguYmFzZW5hbWUocXVlcnkpWzBdID09PSAnLicgJiYgcGF0aC5iYXNlbmFtZShxdWVyeSkubGVuZ3RoID4gMSkpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoY29tbW9uLnBsYXRmb3JtID09PSAnd2luJylcbiAgICAgIGZpbGUgPSBmaWxlLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcblxuICAgIGxpc3QucHVzaChmaWxlKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHBhdGhzLmZvckVhY2goZnVuY3Rpb24ocCkge1xuICAgIGlmIChmcy5leGlzdHNTeW5jKHApKSB7XG4gICAgICB2YXIgc3RhdHMgPSBmcy5zdGF0U3luYyhwKTtcbiAgICAgIC8vIFNpbXBsZSBmaWxlP1xuICAgICAgaWYgKHN0YXRzLmlzRmlsZSgpKSB7XG4gICAgICAgIHB1c2hGaWxlKHAsIHApO1xuICAgICAgICByZXR1cm47IC8vIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIFNpbXBsZSBkaXI/XG4gICAgICBpZiAoc3RhdHMuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICAvLyBJdGVyYXRlIG92ZXIgcCBjb250ZW50c1xuICAgICAgICBmcy5yZWFkZGlyU3luYyhwKS5mb3JFYWNoKGZ1bmN0aW9uKGZpbGUpIHtcbiAgICAgICAgICBpZiAoIXB1c2hGaWxlKGZpbGUsIHApKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgICAgLy8gUmVjdXJzaXZlP1xuICAgICAgICAgIGlmIChvcHRpb25zLnJlY3Vyc2l2ZSkge1xuICAgICAgICAgICAgdmFyIG9sZERpciA9IF9wd2QoKTtcbiAgICAgICAgICAgIF9jZCgnJywgcCk7XG4gICAgICAgICAgICBpZiAoZnMuc3RhdFN5bmMoZmlsZSkuaXNEaXJlY3RvcnkoKSlcbiAgICAgICAgICAgICAgbGlzdCA9IGxpc3QuY29uY2F0KF9scygnLVInKyhvcHRpb25zLmFsbD8nQSc6JycpLCBmaWxlKycvKicpKTtcbiAgICAgICAgICAgIF9jZCgnJywgb2xkRGlyKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47IC8vIGNvbnRpbnVlXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gcCBkb2VzIG5vdCBleGlzdCAtIHBvc3NpYmxlIHdpbGRjYXJkIHByZXNlbnRcblxuICAgIHZhciBiYXNlbmFtZSA9IHBhdGguYmFzZW5hbWUocCk7XG4gICAgdmFyIGRpcm5hbWUgPSBwYXRoLmRpcm5hbWUocCk7XG4gICAgLy8gV2lsZGNhcmQgcHJlc2VudCBvbiBhbiBleGlzdGluZyBkaXI/IChlLmcuICcvdG1wLyouanMnKVxuICAgIGlmIChiYXNlbmFtZS5zZWFyY2goL1xcKi8pID4gLTEgJiYgZnMuZXhpc3RzU3luYyhkaXJuYW1lKSAmJiBmcy5zdGF0U3luYyhkaXJuYW1lKS5pc0RpcmVjdG9yeSkge1xuICAgICAgLy8gRXNjYXBlIHNwZWNpYWwgcmVndWxhciBleHByZXNzaW9uIGNoYXJzXG4gICAgICB2YXIgcmVnZXhwID0gYmFzZW5hbWUucmVwbGFjZSgvKFxcXnxcXCR8XFwofFxcKXw8fD58XFxbfFxcXXxcXHt8XFx9fFxcLnxcXCt8XFw/KS9nLCAnXFxcXCQxJyk7XG4gICAgICAvLyBUcmFuc2xhdGVzIHdpbGRjYXJkIGludG8gcmVnZXhcbiAgICAgIHJlZ2V4cCA9ICdeJyArIHJlZ2V4cC5yZXBsYWNlKC9cXCovZywgJy4qJykgKyAnJCc7XG4gICAgICAvLyBJdGVyYXRlIG92ZXIgZGlyZWN0b3J5IGNvbnRlbnRzXG4gICAgICBmcy5yZWFkZGlyU3luYyhkaXJuYW1lKS5mb3JFYWNoKGZ1bmN0aW9uKGZpbGUpIHtcbiAgICAgICAgaWYgKGZpbGUubWF0Y2gobmV3IFJlZ0V4cChyZWdleHApKSkge1xuICAgICAgICAgIGlmICghcHVzaEZpbGUocGF0aC5ub3JtYWxpemUoZGlybmFtZSsnLycrZmlsZSksIGJhc2VuYW1lKSlcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICAgIC8vIFJlY3Vyc2l2ZT9cbiAgICAgICAgICBpZiAob3B0aW9ucy5yZWN1cnNpdmUpIHtcbiAgICAgICAgICAgIHZhciBwcCA9IGRpcm5hbWUgKyAnLycgKyBmaWxlO1xuICAgICAgICAgICAgaWYgKGZzLmxzdGF0U3luYyhwcCkuaXNEaXJlY3RvcnkoKSlcbiAgICAgICAgICAgICAgbGlzdCA9IGxpc3QuY29uY2F0KF9scygnLVInKyhvcHRpb25zLmFsbD8nQSc6JycpLCBwcCsnLyonKSk7XG4gICAgICAgICAgfSAvLyByZWN1cnNpdmVcbiAgICAgICAgfSAvLyBpZiBmaWxlIG1hdGNoZXNcbiAgICAgIH0pOyAvLyBmb3JFYWNoXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29tbW9uLmVycm9yKCdubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgcCwgdHJ1ZSk7XG4gIH0pO1xuXG4gIHJldHVybiBsaXN0O1xufVxubW9kdWxlLmV4cG9ydHMgPSBfbHM7XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcblxuLy8gUmVjdXJzaXZlbHkgY3JlYXRlcyAnZGlyJ1xuZnVuY3Rpb24gbWtkaXJTeW5jUmVjdXJzaXZlKGRpcikge1xuICB2YXIgYmFzZURpciA9IHBhdGguZGlybmFtZShkaXIpO1xuXG4gIC8vIEJhc2UgZGlyIGV4aXN0cywgbm8gcmVjdXJzaW9uIG5lY2Vzc2FyeVxuICBpZiAoZnMuZXhpc3RzU3luYyhiYXNlRGlyKSkge1xuICAgIGZzLm1rZGlyU3luYyhkaXIsIHBhcnNlSW50KCcwNzc3JywgOCkpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEJhc2UgZGlyIGRvZXMgbm90IGV4aXN0LCBnbyByZWN1cnNpdmVcbiAgbWtkaXJTeW5jUmVjdXJzaXZlKGJhc2VEaXIpO1xuXG4gIC8vIEJhc2UgZGlyIGNyZWF0ZWQsIGNhbiBjcmVhdGUgZGlyXG4gIGZzLm1rZGlyU3luYyhkaXIsIHBhcnNlSW50KCcwNzc3JywgOCkpO1xufVxuXG4vL0Bcbi8vQCAjIyMgbWtkaXIoW29wdGlvbnMgLF0gZGlyIFssIGRpciAuLi5dKVxuLy9AICMjIyBta2Rpcihbb3B0aW9ucyAsXSBkaXJfYXJyYXkpXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGBwYDogZnVsbCBwYXRoICh3aWxsIGNyZWF0ZSBpbnRlcm1lZGlhdGUgZGlycyBpZiBuZWNlc3NhcnkpXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBta2RpcignLXAnLCAnL3RtcC9hL2IvYy9kJywgJy90bXAvZS9mL2cnKTtcbi8vQCBta2RpcignLXAnLCBbJy90bXAvYS9iL2MvZCcsICcvdG1wL2UvZi9nJ10pOyAvLyBzYW1lIGFzIGFib3ZlXG4vL0AgYGBgXG4vL0Bcbi8vQCBDcmVhdGVzIGRpcmVjdG9yaWVzLlxuZnVuY3Rpb24gX21rZGlyKG9wdGlvbnMsIGRpcnMpIHtcbiAgb3B0aW9ucyA9IGNvbW1vbi5wYXJzZU9wdGlvbnMob3B0aW9ucywge1xuICAgICdwJzogJ2Z1bGxwYXRoJ1xuICB9KTtcbiAgaWYgKCFkaXJzKVxuICAgIGNvbW1vbi5lcnJvcignbm8gcGF0aHMgZ2l2ZW4nKTtcblxuICBpZiAodHlwZW9mIGRpcnMgPT09ICdzdHJpbmcnKVxuICAgIGRpcnMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gIC8vIGlmIGl0J3MgYXJyYXkgbGVhdmUgaXQgYXMgaXQgaXNcblxuICBkaXJzLmZvckVhY2goZnVuY3Rpb24oZGlyKSB7XG4gICAgaWYgKGZzLmV4aXN0c1N5bmMoZGlyKSkge1xuICAgICAgaWYgKCFvcHRpb25zLmZ1bGxwYXRoKVxuICAgICAgICAgIGNvbW1vbi5lcnJvcigncGF0aCBhbHJlYWR5IGV4aXN0czogJyArIGRpciwgdHJ1ZSk7XG4gICAgICByZXR1cm47IC8vIHNraXAgZGlyXG4gICAgfVxuXG4gICAgLy8gQmFzZSBkaXIgZG9lcyBub3QgZXhpc3QsIGFuZCBubyAtcCBvcHRpb24gZ2l2ZW5cbiAgICB2YXIgYmFzZURpciA9IHBhdGguZGlybmFtZShkaXIpO1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhiYXNlRGlyKSAmJiAhb3B0aW9ucy5mdWxscGF0aCkge1xuICAgICAgY29tbW9uLmVycm9yKCdubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgYmFzZURpciwgdHJ1ZSk7XG4gICAgICByZXR1cm47IC8vIHNraXAgZGlyXG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuZnVsbHBhdGgpXG4gICAgICBta2RpclN5bmNSZWN1cnNpdmUoZGlyKTtcbiAgICBlbHNlXG4gICAgICBmcy5ta2RpclN5bmMoZGlyLCBwYXJzZUludCgnMDc3NycsIDgpKTtcbiAgfSk7XG59IC8vIG1rZGlyXG5tb2R1bGUuZXhwb3J0cyA9IF9ta2RpcjtcbiIsInZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcbnZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xuXG4vL0Bcbi8vQCAjIyMgbXYoc291cmNlIFssIHNvdXJjZSAuLi5dLCBkZXN0Jylcbi8vQCAjIyMgbXYoc291cmNlX2FycmF5LCBkZXN0Jylcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYGZgOiBmb3JjZVxuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgbXYoJy1mJywgJ2ZpbGUnLCAnZGlyLycpO1xuLy9AIG12KCdmaWxlMScsICdmaWxlMicsICdkaXIvJyk7XG4vL0AgbXYoWydmaWxlMScsICdmaWxlMiddLCAnZGlyLycpOyAvLyBzYW1lIGFzIGFib3ZlXG4vL0AgYGBgXG4vL0Bcbi8vQCBNb3ZlcyBmaWxlcy4gVGhlIHdpbGRjYXJkIGAqYCBpcyBhY2NlcHRlZC5cbmZ1bmN0aW9uIF9tdihvcHRpb25zLCBzb3VyY2VzLCBkZXN0KSB7XG4gIG9wdGlvbnMgPSBjb21tb24ucGFyc2VPcHRpb25zKG9wdGlvbnMsIHtcbiAgICAnZic6ICdmb3JjZSdcbiAgfSk7XG5cbiAgLy8gR2V0IHNvdXJjZXMsIGRlc3RcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzKSB7XG4gICAgY29tbW9uLmVycm9yKCdtaXNzaW5nIDxzb3VyY2U+IGFuZC9vciA8ZGVzdD4nKTtcbiAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMykge1xuICAgIHNvdXJjZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSwgYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGRlc3QgPSBhcmd1bWVudHNbYXJndW1lbnRzLmxlbmd0aCAtIDFdO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBzb3VyY2VzID09PSAnc3RyaW5nJykge1xuICAgIHNvdXJjZXMgPSBbc291cmNlc107XG4gIH0gZWxzZSBpZiAoJ2xlbmd0aCcgaW4gc291cmNlcykge1xuICAgIHNvdXJjZXMgPSBzb3VyY2VzOyAvLyBuby1vcCBmb3IgYXJyYXlcbiAgfSBlbHNlIHtcbiAgICBjb21tb24uZXJyb3IoJ2ludmFsaWQgYXJndW1lbnRzJyk7XG4gIH1cblxuICBzb3VyY2VzID0gY29tbW9uLmV4cGFuZChzb3VyY2VzKTtcblxuICB2YXIgZXhpc3RzID0gZnMuZXhpc3RzU3luYyhkZXN0KSxcbiAgICAgIHN0YXRzID0gZXhpc3RzICYmIGZzLnN0YXRTeW5jKGRlc3QpO1xuXG4gIC8vIERlc3QgaXMgbm90IGV4aXN0aW5nIGRpciwgYnV0IG11bHRpcGxlIHNvdXJjZXMgZ2l2ZW5cbiAgaWYgKCghZXhpc3RzIHx8ICFzdGF0cy5pc0RpcmVjdG9yeSgpKSAmJiBzb3VyY2VzLmxlbmd0aCA+IDEpXG4gICAgY29tbW9uLmVycm9yKCdkZXN0IGlzIG5vdCBhIGRpcmVjdG9yeSAodG9vIG1hbnkgc291cmNlcyknKTtcblxuICAvLyBEZXN0IGlzIGFuIGV4aXN0aW5nIGZpbGUsIGJ1dCBubyAtZiBnaXZlblxuICBpZiAoZXhpc3RzICYmIHN0YXRzLmlzRmlsZSgpICYmICFvcHRpb25zLmZvcmNlKVxuICAgIGNvbW1vbi5lcnJvcignZGVzdCBmaWxlIGFscmVhZHkgZXhpc3RzOiAnICsgZGVzdCk7XG5cbiAgc291cmNlcy5mb3JFYWNoKGZ1bmN0aW9uKHNyYykge1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhzcmMpKSB7XG4gICAgICBjb21tb24uZXJyb3IoJ25vIHN1Y2ggZmlsZSBvciBkaXJlY3Rvcnk6ICcrc3JjLCB0cnVlKTtcbiAgICAgIHJldHVybjsgLy8gc2tpcCBmaWxlXG4gICAgfVxuXG4gICAgLy8gSWYgaGVyZSwgc3JjIGV4aXN0c1xuXG4gICAgLy8gV2hlbiBjb3B5aW5nIHRvICcvcGF0aC9kaXInOlxuICAgIC8vICAgIHRoaXNEZXN0ID0gJy9wYXRoL2Rpci9maWxlMSdcbiAgICB2YXIgdGhpc0Rlc3QgPSBkZXN0O1xuICAgIGlmIChmcy5leGlzdHNTeW5jKGRlc3QpICYmIGZzLnN0YXRTeW5jKGRlc3QpLmlzRGlyZWN0b3J5KCkpXG4gICAgICB0aGlzRGVzdCA9IHBhdGgubm9ybWFsaXplKGRlc3QgKyAnLycgKyBwYXRoLmJhc2VuYW1lKHNyYykpO1xuXG4gICAgaWYgKGZzLmV4aXN0c1N5bmModGhpc0Rlc3QpICYmICFvcHRpb25zLmZvcmNlKSB7XG4gICAgICBjb21tb24uZXJyb3IoJ2Rlc3QgZmlsZSBhbHJlYWR5IGV4aXN0czogJyArIHRoaXNEZXN0LCB0cnVlKTtcbiAgICAgIHJldHVybjsgLy8gc2tpcCBmaWxlXG4gICAgfVxuXG4gICAgaWYgKHBhdGgucmVzb2x2ZShzcmMpID09PSBwYXRoLmRpcm5hbWUocGF0aC5yZXNvbHZlKHRoaXNEZXN0KSkpIHtcbiAgICAgIGNvbW1vbi5lcnJvcignY2Fubm90IG1vdmUgdG8gc2VsZjogJytzcmMsIHRydWUpO1xuICAgICAgcmV0dXJuOyAvLyBza2lwIGZpbGVcbiAgICB9XG5cbiAgICBmcy5yZW5hbWVTeW5jKHNyYywgdGhpc0Rlc3QpO1xuICB9KTsgLy8gZm9yRWFjaChzcmMpXG59IC8vIG12XG5tb2R1bGUuZXhwb3J0cyA9IF9tdjtcbiIsInZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG5cbi8vQFxuLy9AICMjIyBwd2QoKVxuLy9AIFJldHVybnMgdGhlIGN1cnJlbnQgZGlyZWN0b3J5LlxuZnVuY3Rpb24gX3B3ZChvcHRpb25zKSB7XG4gIHZhciBwd2QgPSBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSk7XG4gIHJldHVybiBjb21tb24uU2hlbGxTdHJpbmcocHdkKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gX3B3ZDtcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcblxuLy8gUmVjdXJzaXZlbHkgcmVtb3ZlcyAnZGlyJ1xuLy8gQWRhcHRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9yeWFubWNncmF0aC93cmVuY2gtanNcbi8vXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTAgUnlhbiBNY0dyYXRoXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTIgQXJ0dXIgQWRpYlxuLy9cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZVxuLy8gaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHBcbmZ1bmN0aW9uIHJtZGlyU3luY1JlY3Vyc2l2ZShkaXIsIGZvcmNlKSB7XG4gIHZhciBmaWxlcztcblxuICBmaWxlcyA9IGZzLnJlYWRkaXJTeW5jKGRpcik7XG5cbiAgLy8gTG9vcCB0aHJvdWdoIGFuZCBkZWxldGUgZXZlcnl0aGluZyBpbiB0aGUgc3ViLXRyZWUgYWZ0ZXIgY2hlY2tpbmcgaXRcbiAgZm9yKHZhciBpID0gMDsgaSA8IGZpbGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGZpbGUgPSBkaXIgKyBcIi9cIiArIGZpbGVzW2ldLFxuICAgICAgICBjdXJyRmlsZSA9IGZzLmxzdGF0U3luYyhmaWxlKTtcblxuICAgIGlmKGN1cnJGaWxlLmlzRGlyZWN0b3J5KCkpIHsgLy8gUmVjdXJzaXZlIGZ1bmN0aW9uIGJhY2sgdG8gdGhlIGJlZ2lubmluZ1xuICAgICAgcm1kaXJTeW5jUmVjdXJzaXZlKGZpbGUsIGZvcmNlKTtcbiAgICB9XG5cbiAgICBlbHNlIGlmKGN1cnJGaWxlLmlzU3ltYm9saWNMaW5rKCkpIHsgLy8gVW5saW5rIHN5bWxpbmtzXG4gICAgICBpZiAoZm9yY2UgfHwgaXNXcml0ZWFibGUoZmlsZSkpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb21tb24udW5saW5rU3luYyhmaWxlKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGNvbW1vbi5lcnJvcignY291bGQgbm90IHJlbW92ZSBmaWxlIChjb2RlICcrZS5jb2RlKycpOiAnICsgZmlsZSwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBlbHNlIC8vIEFzc3VtZSBpdCdzIGEgZmlsZSAtIHBlcmhhcHMgYSB0cnkvY2F0Y2ggYmVsb25ncyBoZXJlP1xuICAgICAgaWYgKGZvcmNlIHx8IGlzV3JpdGVhYmxlKGZpbGUpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29tbW9uLnVubGlua1N5bmMoZmlsZSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBjb21tb24uZXJyb3IoJ2NvdWxkIG5vdCByZW1vdmUgZmlsZSAoY29kZSAnK2UuY29kZSsnKTogJyArIGZpbGUsIHRydWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gIH1cblxuICAvLyBOb3cgdGhhdCB3ZSBrbm93IGV2ZXJ5dGhpbmcgaW4gdGhlIHN1Yi10cmVlIGhhcyBiZWVuIGRlbGV0ZWQsIHdlIGNhbiBkZWxldGUgdGhlIG1haW4gZGlyZWN0b3J5LlxuICAvLyBIdXp6YWggZm9yIHRoZSBzaG9wa2VlcC5cblxuICB2YXIgcmVzdWx0O1xuICB0cnkge1xuICAgIHJlc3VsdCA9IGZzLnJtZGlyU3luYyhkaXIpO1xuICB9IGNhdGNoKGUpIHtcbiAgICBjb21tb24uZXJyb3IoJ2NvdWxkIG5vdCByZW1vdmUgZGlyZWN0b3J5IChjb2RlICcrZS5jb2RlKycpOiAnICsgZGlyLCB0cnVlKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59IC8vIHJtZGlyU3luY1JlY3Vyc2l2ZVxuXG4vLyBIYWNrIHRvIGRldGVybWluZSBpZiBmaWxlIGhhcyB3cml0ZSBwZXJtaXNzaW9ucyBmb3IgY3VycmVudCB1c2VyXG4vLyBBdm9pZHMgaGF2aW5nIHRvIGNoZWNrIHVzZXIsIGdyb3VwLCBldGMsIGJ1dCBpdCdzIHByb2JhYmx5IHNsb3dcbmZ1bmN0aW9uIGlzV3JpdGVhYmxlKGZpbGUpIHtcbiAgdmFyIHdyaXRlUGVybWlzc2lvbiA9IHRydWU7XG4gIHRyeSB7XG4gICAgdmFyIF9fZmQgPSBmcy5vcGVuU3luYyhmaWxlLCAnYScpO1xuICAgIGZzLmNsb3NlU3luYyhfX2ZkKTtcbiAgfSBjYXRjaChlKSB7XG4gICAgd3JpdGVQZXJtaXNzaW9uID0gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gd3JpdGVQZXJtaXNzaW9uO1xufVxuXG4vL0Bcbi8vQCAjIyMgcm0oW29wdGlvbnMgLF0gZmlsZSBbLCBmaWxlIC4uLl0pXG4vL0AgIyMjIHJtKFtvcHRpb25zICxdIGZpbGVfYXJyYXkpXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGAtZmA6IGZvcmNlXG4vL0AgKyBgLXIsIC1SYDogcmVjdXJzaXZlXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBybSgnLXJmJywgJy90bXAvKicpO1xuLy9AIHJtKCdzb21lX2ZpbGUudHh0JywgJ2Fub3RoZXJfZmlsZS50eHQnKTtcbi8vQCBybShbJ3NvbWVfZmlsZS50eHQnLCAnYW5vdGhlcl9maWxlLnR4dCddKTsgLy8gc2FtZSBhcyBhYm92ZVxuLy9AIGBgYFxuLy9AXG4vL0AgUmVtb3ZlcyBmaWxlcy4gVGhlIHdpbGRjYXJkIGAqYCBpcyBhY2NlcHRlZC5cbmZ1bmN0aW9uIF9ybShvcHRpb25zLCBmaWxlcykge1xuICBvcHRpb25zID0gY29tbW9uLnBhcnNlT3B0aW9ucyhvcHRpb25zLCB7XG4gICAgJ2YnOiAnZm9yY2UnLFxuICAgICdyJzogJ3JlY3Vyc2l2ZScsXG4gICAgJ1InOiAncmVjdXJzaXZlJ1xuICB9KTtcbiAgaWYgKCFmaWxlcylcbiAgICBjb21tb24uZXJyb3IoJ25vIHBhdGhzIGdpdmVuJyk7XG5cbiAgaWYgKHR5cGVvZiBmaWxlcyA9PT0gJ3N0cmluZycpXG4gICAgZmlsZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gIC8vIGlmIGl0J3MgYXJyYXkgbGVhdmUgaXQgYXMgaXQgaXNcblxuICBmaWxlcyA9IGNvbW1vbi5leHBhbmQoZmlsZXMpO1xuXG4gIGZpbGVzLmZvckVhY2goZnVuY3Rpb24oZmlsZSkge1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhmaWxlKSkge1xuICAgICAgLy8gUGF0aCBkb2VzIG5vdCBleGlzdCwgbm8gZm9yY2UgZmxhZyBnaXZlblxuICAgICAgaWYgKCFvcHRpb25zLmZvcmNlKVxuICAgICAgICBjb21tb24uZXJyb3IoJ25vIHN1Y2ggZmlsZSBvciBkaXJlY3Rvcnk6ICcrZmlsZSwgdHJ1ZSk7XG5cbiAgICAgIHJldHVybjsgLy8gc2tpcCBmaWxlXG4gICAgfVxuXG4gICAgLy8gSWYgaGVyZSwgcGF0aCBleGlzdHNcblxuICAgIHZhciBzdGF0cyA9IGZzLmxzdGF0U3luYyhmaWxlKTtcbiAgICBpZiAoc3RhdHMuaXNGaWxlKCkgfHwgc3RhdHMuaXNTeW1ib2xpY0xpbmsoKSkge1xuXG4gICAgICAvLyBEbyBub3QgY2hlY2sgZm9yIGZpbGUgd3JpdGluZyBwZXJtaXNzaW9uc1xuICAgICAgaWYgKG9wdGlvbnMuZm9yY2UpIHtcbiAgICAgICAgY29tbW9uLnVubGlua1N5bmMoZmlsZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzV3JpdGVhYmxlKGZpbGUpKVxuICAgICAgICBjb21tb24udW5saW5rU3luYyhmaWxlKTtcbiAgICAgIGVsc2VcbiAgICAgICAgY29tbW9uLmVycm9yKCdwZXJtaXNzaW9uIGRlbmllZDogJytmaWxlLCB0cnVlKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH0gLy8gc2ltcGxlIGZpbGVcblxuICAgIC8vIFBhdGggaXMgYW4gZXhpc3RpbmcgZGlyZWN0b3J5LCBidXQgbm8gLXIgZmxhZyBnaXZlblxuICAgIGlmIChzdGF0cy5pc0RpcmVjdG9yeSgpICYmICFvcHRpb25zLnJlY3Vyc2l2ZSkge1xuICAgICAgY29tbW9uLmVycm9yKCdwYXRoIGlzIGEgZGlyZWN0b3J5JywgdHJ1ZSk7XG4gICAgICByZXR1cm47IC8vIHNraXAgcGF0aFxuICAgIH1cblxuICAgIC8vIFJlY3Vyc2l2ZWx5IHJlbW92ZSBleGlzdGluZyBkaXJlY3RvcnlcbiAgICBpZiAoc3RhdHMuaXNEaXJlY3RvcnkoKSAmJiBvcHRpb25zLnJlY3Vyc2l2ZSkge1xuICAgICAgcm1kaXJTeW5jUmVjdXJzaXZlKGZpbGUsIG9wdGlvbnMuZm9yY2UpO1xuICAgIH1cbiAgfSk7IC8vIGZvckVhY2goZmlsZSlcbn0gLy8gcm1cbm1vZHVsZS5leHBvcnRzID0gX3JtO1xuIiwidmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xuXG4vL0Bcbi8vQCAjIyMgc2VkKFtvcHRpb25zICxdIHNlYXJjaF9yZWdleCwgcmVwbGFjZW1lbnQsIGZpbGUpXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGAtaWA6IFJlcGxhY2UgY29udGVudHMgb2YgJ2ZpbGUnIGluLXBsYWNlLiBfTm90ZSB0aGF0IG5vIGJhY2t1cHMgd2lsbCBiZSBjcmVhdGVkIV9cbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIHNlZCgnLWknLCAnUFJPR1JBTV9WRVJTSU9OJywgJ3YwLjEuMycsICdzb3VyY2UuanMnKTtcbi8vQCBzZWQoLy4qREVMRVRFX1RISVNfTElORS4qXFxuLywgJycsICdzb3VyY2UuanMnKTtcbi8vQCBgYGBcbi8vQFxuLy9AIFJlYWRzIGFuIGlucHV0IHN0cmluZyBmcm9tIGBmaWxlYCBhbmQgcGVyZm9ybXMgYSBKYXZhU2NyaXB0IGByZXBsYWNlKClgIG9uIHRoZSBpbnB1dFxuLy9AIHVzaW5nIHRoZSBnaXZlbiBzZWFyY2ggcmVnZXggYW5kIHJlcGxhY2VtZW50IHN0cmluZyBvciBmdW5jdGlvbi4gUmV0dXJucyB0aGUgbmV3IHN0cmluZyBhZnRlciByZXBsYWNlbWVudC5cbmZ1bmN0aW9uIF9zZWQob3B0aW9ucywgcmVnZXgsIHJlcGxhY2VtZW50LCBmaWxlKSB7XG4gIG9wdGlvbnMgPSBjb21tb24ucGFyc2VPcHRpb25zKG9wdGlvbnMsIHtcbiAgICAnaSc6ICdpbnBsYWNlJ1xuICB9KTtcblxuICBpZiAodHlwZW9mIHJlcGxhY2VtZW50ID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgcmVwbGFjZW1lbnQgPT09ICdmdW5jdGlvbicpXG4gICAgcmVwbGFjZW1lbnQgPSByZXBsYWNlbWVudDsgLy8gbm8tb3BcbiAgZWxzZSBpZiAodHlwZW9mIHJlcGxhY2VtZW50ID09PSAnbnVtYmVyJylcbiAgICByZXBsYWNlbWVudCA9IHJlcGxhY2VtZW50LnRvU3RyaW5nKCk7IC8vIGZhbGxiYWNrXG4gIGVsc2VcbiAgICBjb21tb24uZXJyb3IoJ2ludmFsaWQgcmVwbGFjZW1lbnQgc3RyaW5nJyk7XG5cbiAgaWYgKCFmaWxlKVxuICAgIGNvbW1vbi5lcnJvcignbm8gZmlsZSBnaXZlbicpO1xuXG4gIGlmICghZnMuZXhpc3RzU3luYyhmaWxlKSlcbiAgICBjb21tb24uZXJyb3IoJ25vIHN1Y2ggZmlsZSBvciBkaXJlY3Rvcnk6ICcgKyBmaWxlKTtcblxuICB2YXIgcmVzdWx0ID0gZnMucmVhZEZpbGVTeW5jKGZpbGUsICd1dGY4JykucmVwbGFjZShyZWdleCwgcmVwbGFjZW1lbnQpO1xuICBpZiAob3B0aW9ucy5pbnBsYWNlKVxuICAgIGZzLndyaXRlRmlsZVN5bmMoZmlsZSwgcmVzdWx0LCAndXRmOCcpO1xuXG4gIHJldHVybiBjb21tb24uU2hlbGxTdHJpbmcocmVzdWx0KTtcbn1cbm1vZHVsZS5leHBvcnRzID0gX3NlZDtcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIG9zID0gcmVxdWlyZSgnb3MnKTtcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5cbi8vIFJldHVybnMgZmFsc2UgaWYgJ2RpcicgaXMgbm90IGEgd3JpdGVhYmxlIGRpcmVjdG9yeSwgJ2Rpcicgb3RoZXJ3aXNlXG5mdW5jdGlvbiB3cml0ZWFibGVEaXIoZGlyKSB7XG4gIGlmICghZGlyIHx8ICFmcy5leGlzdHNTeW5jKGRpcikpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGlmICghZnMuc3RhdFN5bmMoZGlyKS5pc0RpcmVjdG9yeSgpKVxuICAgIHJldHVybiBmYWxzZTtcblxuICB2YXIgdGVzdEZpbGUgPSBkaXIrJy8nK2NvbW1vbi5yYW5kb21GaWxlTmFtZSgpO1xuICB0cnkge1xuICAgIGZzLndyaXRlRmlsZVN5bmModGVzdEZpbGUsICcgJyk7XG4gICAgY29tbW9uLnVubGlua1N5bmModGVzdEZpbGUpO1xuICAgIHJldHVybiBkaXI7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuXG4vL0Bcbi8vQCAjIyMgdGVtcGRpcigpXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCB2YXIgdG1wID0gdGVtcGRpcigpOyAvLyBcIi90bXBcIiBmb3IgbW9zdCAqbml4IHBsYXRmb3Jtc1xuLy9AIGBgYFxuLy9AXG4vL0AgU2VhcmNoZXMgYW5kIHJldHVybnMgc3RyaW5nIGNvbnRhaW5pbmcgYSB3cml0ZWFibGUsIHBsYXRmb3JtLWRlcGVuZGVudCB0ZW1wb3JhcnkgZGlyZWN0b3J5LlxuLy9AIEZvbGxvd3MgUHl0aG9uJ3MgW3RlbXBmaWxlIGFsZ29yaXRobV0oaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3RlbXBmaWxlLmh0bWwjdGVtcGZpbGUudGVtcGRpcikuXG5mdW5jdGlvbiBfdGVtcERpcigpIHtcbiAgdmFyIHN0YXRlID0gY29tbW9uLnN0YXRlO1xuICBpZiAoc3RhdGUudGVtcERpcilcbiAgICByZXR1cm4gc3RhdGUudGVtcERpcjsgLy8gZnJvbSBjYWNoZVxuXG4gIHN0YXRlLnRlbXBEaXIgPSB3cml0ZWFibGVEaXIob3MudGVtcERpciAmJiBvcy50ZW1wRGlyKCkpIHx8IC8vIG5vZGUgMC44K1xuICAgICAgICAgICAgICAgICAgd3JpdGVhYmxlRGlyKHByb2Nlc3MuZW52WydUTVBESVInXSkgfHxcbiAgICAgICAgICAgICAgICAgIHdyaXRlYWJsZURpcihwcm9jZXNzLmVudlsnVEVNUCddKSB8fFxuICAgICAgICAgICAgICAgICAgd3JpdGVhYmxlRGlyKHByb2Nlc3MuZW52WydUTVAnXSkgfHxcbiAgICAgICAgICAgICAgICAgIHdyaXRlYWJsZURpcihwcm9jZXNzLmVudlsnV2ltcCRTY3JhcERpciddKSB8fCAvLyBSaXNjT1NcbiAgICAgICAgICAgICAgICAgIHdyaXRlYWJsZURpcignQzpcXFxcVEVNUCcpIHx8IC8vIFdpbmRvd3NcbiAgICAgICAgICAgICAgICAgIHdyaXRlYWJsZURpcignQzpcXFxcVE1QJykgfHwgLy8gV2luZG93c1xuICAgICAgICAgICAgICAgICAgd3JpdGVhYmxlRGlyKCdcXFxcVEVNUCcpIHx8IC8vIFdpbmRvd3NcbiAgICAgICAgICAgICAgICAgIHdyaXRlYWJsZURpcignXFxcXFRNUCcpIHx8IC8vIFdpbmRvd3NcbiAgICAgICAgICAgICAgICAgIHdyaXRlYWJsZURpcignL3RtcCcpIHx8XG4gICAgICAgICAgICAgICAgICB3cml0ZWFibGVEaXIoJy92YXIvdG1wJykgfHxcbiAgICAgICAgICAgICAgICAgIHdyaXRlYWJsZURpcignL3Vzci90bXAnKSB8fFxuICAgICAgICAgICAgICAgICAgd3JpdGVhYmxlRGlyKCcuJyk7IC8vIGxhc3QgcmVzb3J0XG5cbiAgcmV0dXJuIHN0YXRlLnRlbXBEaXI7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF90ZW1wRGlyO1xuIiwidmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xuXG4vL0Bcbi8vQCAjIyMgdGVzdChleHByZXNzaW9uKVxuLy9AIEF2YWlsYWJsZSBleHByZXNzaW9uIHByaW1hcmllczpcbi8vQFxuLy9AICsgYCctYicsICdwYXRoJ2A6IHRydWUgaWYgcGF0aCBpcyBhIGJsb2NrIGRldmljZVxuLy9AICsgYCctYycsICdwYXRoJ2A6IHRydWUgaWYgcGF0aCBpcyBhIGNoYXJhY3RlciBkZXZpY2Vcbi8vQCArIGAnLWQnLCAncGF0aCdgOiB0cnVlIGlmIHBhdGggaXMgYSBkaXJlY3Rvcnlcbi8vQCArIGAnLWUnLCAncGF0aCdgOiB0cnVlIGlmIHBhdGggZXhpc3RzXG4vL0AgKyBgJy1mJywgJ3BhdGgnYDogdHJ1ZSBpZiBwYXRoIGlzIGEgcmVndWxhciBmaWxlXG4vL0AgKyBgJy1MJywgJ3BhdGgnYDogdHJ1ZSBpZiBwYXRoIGlzIGEgc3ltYm9pbGMgbGlua1xuLy9AICsgYCctcCcsICdwYXRoJ2A6IHRydWUgaWYgcGF0aCBpcyBhIHBpcGUgKEZJRk8pXG4vL0AgKyBgJy1TJywgJ3BhdGgnYDogdHJ1ZSBpZiBwYXRoIGlzIGEgc29ja2V0XG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBpZiAodGVzdCgnLWQnLCBwYXRoKSkgeyAvKiBkbyBzb21ldGhpbmcgd2l0aCBkaXIgKi8gfTtcbi8vQCBpZiAoIXRlc3QoJy1mJywgcGF0aCkpIGNvbnRpbnVlOyAvLyBza2lwIGlmIGl0J3MgYSByZWd1bGFyIGZpbGVcbi8vQCBgYGBcbi8vQFxuLy9AIEV2YWx1YXRlcyBleHByZXNzaW9uIHVzaW5nIHRoZSBhdmFpbGFibGUgcHJpbWFyaWVzIGFuZCByZXR1cm5zIGNvcnJlc3BvbmRpbmcgdmFsdWUuXG5mdW5jdGlvbiBfdGVzdChvcHRpb25zLCBwYXRoKSB7XG4gIGlmICghcGF0aClcbiAgICBjb21tb24uZXJyb3IoJ25vIHBhdGggZ2l2ZW4nKTtcblxuICAvLyBoYWNrIC0gb25seSB3b3JrcyB3aXRoIHVuYXJ5IHByaW1hcmllc1xuICBvcHRpb25zID0gY29tbW9uLnBhcnNlT3B0aW9ucyhvcHRpb25zLCB7XG4gICAgJ2InOiAnYmxvY2snLFxuICAgICdjJzogJ2NoYXJhY3RlcicsXG4gICAgJ2QnOiAnZGlyZWN0b3J5JyxcbiAgICAnZSc6ICdleGlzdHMnLFxuICAgICdmJzogJ2ZpbGUnLFxuICAgICdMJzogJ2xpbmsnLFxuICAgICdwJzogJ3BpcGUnLFxuICAgICdTJzogJ3NvY2tldCdcbiAgfSk7XG5cbiAgdmFyIGNhbkludGVycHJldCA9IGZhbHNlO1xuICBmb3IgKHZhciBrZXkgaW4gb3B0aW9ucylcbiAgICBpZiAob3B0aW9uc1trZXldID09PSB0cnVlKSB7XG4gICAgICBjYW5JbnRlcnByZXQgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gIGlmICghY2FuSW50ZXJwcmV0KVxuICAgIGNvbW1vbi5lcnJvcignY291bGQgbm90IGludGVycHJldCBleHByZXNzaW9uJyk7XG5cbiAgaWYgKG9wdGlvbnMubGluaykge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gZnMubHN0YXRTeW5jKHBhdGgpLmlzU3ltYm9saWNMaW5rKCk7XG4gICAgfSBjYXRjaChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFmcy5leGlzdHNTeW5jKHBhdGgpKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAob3B0aW9ucy5leGlzdHMpXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgdmFyIHN0YXRzID0gZnMuc3RhdFN5bmMocGF0aCk7XG5cbiAgaWYgKG9wdGlvbnMuYmxvY2spXG4gICAgcmV0dXJuIHN0YXRzLmlzQmxvY2tEZXZpY2UoKTtcblxuICBpZiAob3B0aW9ucy5jaGFyYWN0ZXIpXG4gICAgcmV0dXJuIHN0YXRzLmlzQ2hhcmFjdGVyRGV2aWNlKCk7XG5cbiAgaWYgKG9wdGlvbnMuZGlyZWN0b3J5KVxuICAgIHJldHVybiBzdGF0cy5pc0RpcmVjdG9yeSgpO1xuXG4gIGlmIChvcHRpb25zLmZpbGUpXG4gICAgcmV0dXJuIHN0YXRzLmlzRmlsZSgpO1xuXG4gIGlmIChvcHRpb25zLnBpcGUpXG4gICAgcmV0dXJuIHN0YXRzLmlzRklGTygpO1xuXG4gIGlmIChvcHRpb25zLnNvY2tldClcbiAgICByZXR1cm4gc3RhdHMuaXNTb2NrZXQoKTtcbn0gLy8gdGVzdFxubW9kdWxlLmV4cG9ydHMgPSBfdGVzdDtcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcbnZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xuXG4vL0Bcbi8vQCAjIyMgJ3N0cmluZycudG8oZmlsZSlcbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIGNhdCgnaW5wdXQudHh0JykudG8oJ291dHB1dC50eHQnKTtcbi8vQCBgYGBcbi8vQFxuLy9AIEFuYWxvZ291cyB0byB0aGUgcmVkaXJlY3Rpb24gb3BlcmF0b3IgYD5gIGluIFVuaXgsIGJ1dCB3b3JrcyB3aXRoIEphdmFTY3JpcHQgc3RyaW5ncyAoc3VjaCBhc1xuLy9AIHRob3NlIHJldHVybmVkIGJ5IGBjYXRgLCBgZ3JlcGAsIGV0YykuIF9MaWtlIFVuaXggcmVkaXJlY3Rpb25zLCBgdG8oKWAgd2lsbCBvdmVyd3JpdGUgYW55IGV4aXN0aW5nIGZpbGUhX1xuZnVuY3Rpb24gX3RvKG9wdGlvbnMsIGZpbGUpIHtcbiAgaWYgKCFmaWxlKVxuICAgIGNvbW1vbi5lcnJvcignd3JvbmcgYXJndW1lbnRzJyk7XG5cbiAgaWYgKCFmcy5leGlzdHNTeW5jKCBwYXRoLmRpcm5hbWUoZmlsZSkgKSlcbiAgICAgIGNvbW1vbi5lcnJvcignbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeTogJyArIHBhdGguZGlybmFtZShmaWxlKSk7XG5cbiAgdHJ5IHtcbiAgICBmcy53cml0ZUZpbGVTeW5jKGZpbGUsIHRoaXMudG9TdHJpbmcoKSwgJ3V0ZjgnKTtcbiAgfSBjYXRjaChlKSB7XG4gICAgY29tbW9uLmVycm9yKCdjb3VsZCBub3Qgd3JpdGUgdG8gZmlsZSAoY29kZSAnK2UuY29kZSsnKTogJytmaWxlLCB0cnVlKTtcbiAgfVxufVxubW9kdWxlLmV4cG9ydHMgPSBfdG87XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcblxuLy9AXG4vL0AgIyMjICdzdHJpbmcnLnRvRW5kKGZpbGUpXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBjYXQoJ2lucHV0LnR4dCcpLnRvRW5kKCdvdXRwdXQudHh0Jyk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBBbmFsb2dvdXMgdG8gdGhlIHJlZGlyZWN0LWFuZC1hcHBlbmQgb3BlcmF0b3IgYD4+YCBpbiBVbml4LCBidXQgd29ya3Mgd2l0aCBKYXZhU2NyaXB0IHN0cmluZ3MgKHN1Y2ggYXNcbi8vQCB0aG9zZSByZXR1cm5lZCBieSBgY2F0YCwgYGdyZXBgLCBldGMpLlxuZnVuY3Rpb24gX3RvRW5kKG9wdGlvbnMsIGZpbGUpIHtcbiAgaWYgKCFmaWxlKVxuICAgIGNvbW1vbi5lcnJvcignd3JvbmcgYXJndW1lbnRzJyk7XG5cbiAgaWYgKCFmcy5leGlzdHNTeW5jKCBwYXRoLmRpcm5hbWUoZmlsZSkgKSlcbiAgICAgIGNvbW1vbi5lcnJvcignbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeTogJyArIHBhdGguZGlybmFtZShmaWxlKSk7XG5cbiAgdHJ5IHtcbiAgICBmcy5hcHBlbmRGaWxlU3luYyhmaWxlLCB0aGlzLnRvU3RyaW5nKCksICd1dGY4Jyk7XG4gIH0gY2F0Y2goZSkge1xuICAgIGNvbW1vbi5lcnJvcignY291bGQgbm90IGFwcGVuZCB0byBmaWxlIChjb2RlICcrZS5jb2RlKycpOiAnK2ZpbGUsIHRydWUpO1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IF90b0VuZDtcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcbnZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xuXG4vLyBDcm9zcy1wbGF0Zm9ybSBtZXRob2QgZm9yIHNwbGl0dGluZyBlbnZpcm9ubWVudCBQQVRIIHZhcmlhYmxlc1xuZnVuY3Rpb24gc3BsaXRQYXRoKHApIHtcbiAgZm9yIChpPTE7aTwyO2krKykge31cblxuICBpZiAoIXApXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmIChjb21tb24ucGxhdGZvcm0gPT09ICd3aW4nKVxuICAgIHJldHVybiBwLnNwbGl0KCc7Jyk7XG4gIGVsc2VcbiAgICByZXR1cm4gcC5zcGxpdCgnOicpO1xufVxuXG5mdW5jdGlvbiBjaGVja1BhdGgocGF0aCkge1xuICByZXR1cm4gZnMuZXhpc3RzU3luYyhwYXRoKSAmJiBmcy5zdGF0U3luYyhwYXRoKS5pc0RpcmVjdG9yeSgpID09IGZhbHNlO1xufVxuXG4vL0Bcbi8vQCAjIyMgd2hpY2goY29tbWFuZClcbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIHZhciBub2RlRXhlYyA9IHdoaWNoKCdub2RlJyk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBTZWFyY2hlcyBmb3IgYGNvbW1hbmRgIGluIHRoZSBzeXN0ZW0ncyBQQVRILiBPbiBXaW5kb3dzIGxvb2tzIGZvciBgLmV4ZWAsIGAuY21kYCwgYW5kIGAuYmF0YCBleHRlbnNpb25zLlxuLy9AIFJldHVybnMgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGFic29sdXRlIHBhdGggdG8gdGhlIGNvbW1hbmQuXG5mdW5jdGlvbiBfd2hpY2gob3B0aW9ucywgY21kKSB7XG4gIGlmICghY21kKVxuICAgIGNvbW1vbi5lcnJvcignbXVzdCBzcGVjaWZ5IGNvbW1hbmQnKTtcblxuICB2YXIgcGF0aEVudiA9IHByb2Nlc3MuZW52LnBhdGggfHwgcHJvY2Vzcy5lbnYuUGF0aCB8fCBwcm9jZXNzLmVudi5QQVRILFxuICAgICAgcGF0aEFycmF5ID0gc3BsaXRQYXRoKHBhdGhFbnYpLFxuICAgICAgd2hlcmUgPSBudWxsO1xuXG4gIC8vIE5vIHJlbGF0aXZlL2Fic29sdXRlIHBhdGhzIHByb3ZpZGVkP1xuICBpZiAoY21kLnNlYXJjaCgvXFwvLykgPT09IC0xKSB7XG4gICAgLy8gU2VhcmNoIGZvciBjb21tYW5kIGluIFBBVEhcbiAgICBwYXRoQXJyYXkuZm9yRWFjaChmdW5jdGlvbihkaXIpIHtcbiAgICAgIGlmICh3aGVyZSlcbiAgICAgICAgcmV0dXJuOyAvLyBhbHJlYWR5IGZvdW5kIGl0XG5cbiAgICAgIHZhciBhdHRlbXB0ID0gcGF0aC5yZXNvbHZlKGRpciArICcvJyArIGNtZCk7XG4gICAgICBpZiAoY2hlY2tQYXRoKGF0dGVtcHQpKSB7XG4gICAgICAgIHdoZXJlID0gYXR0ZW1wdDtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29tbW9uLnBsYXRmb3JtID09PSAnd2luJykge1xuICAgICAgICB2YXIgYmFzZUF0dGVtcHQgPSBhdHRlbXB0O1xuICAgICAgICBhdHRlbXB0ID0gYmFzZUF0dGVtcHQgKyAnLmV4ZSc7XG4gICAgICAgIGlmIChjaGVja1BhdGgoYXR0ZW1wdCkpIHtcbiAgICAgICAgICB3aGVyZSA9IGF0dGVtcHQ7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGF0dGVtcHQgPSBiYXNlQXR0ZW1wdCArICcuY21kJztcbiAgICAgICAgaWYgKGNoZWNrUGF0aChhdHRlbXB0KSkge1xuICAgICAgICAgIHdoZXJlID0gYXR0ZW1wdDtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgYXR0ZW1wdCA9IGJhc2VBdHRlbXB0ICsgJy5iYXQnO1xuICAgICAgICBpZiAoY2hlY2tQYXRoKGF0dGVtcHQpKSB7XG4gICAgICAgICAgd2hlcmUgPSBhdHRlbXB0O1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfSAvLyBpZiAnd2luJ1xuICAgIH0pO1xuICB9XG5cbiAgLy8gQ29tbWFuZCBub3QgZm91bmQgYW55d2hlcmU/XG4gIGlmICghY2hlY2tQYXRoKGNtZCkgJiYgIXdoZXJlKVxuICAgIHJldHVybiBudWxsO1xuXG4gIHdoZXJlID0gd2hlcmUgfHwgcGF0aC5yZXNvbHZlKGNtZCk7XG5cbiAgcmV0dXJuIGNvbW1vbi5TaGVsbFN0cmluZyh3aGVyZSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF93aGljaDtcbiIsImltcG9ydCB7IGluamVjdGFibGUgfSBmcm9tICdpbnZlcnNpZnknXG5cbmltcG9ydCAqIGFzIHRhc2tMaWIgZnJvbSAnYXp1cmUtcGlwZWxpbmVzLXRhc2stbGliL3Rhc2snXG5pbXBvcnQgKiBhcyB0b29sTGliIGZyb20gJ2F6dXJlLXBpcGVsaW5lcy10b29sLWxpYi90b29sJ1xuXG5pbXBvcnQgeyBJQnVpbGRBZ2VudCwgSUV4ZWNSZXN1bHQgfSBmcm9tICcuLi8uLi9jb3JlL21vZGVscydcbmltcG9ydCB7IElSZXF1ZXN0T3B0aW9ucyB9IGZyb20gJ3R5cGVkLXJlc3QtY2xpZW50L0ludGVyZmFjZXMnXG5cbkBpbmplY3RhYmxlKClcbmNsYXNzIEJ1aWxkQWdlbnQgaW1wbGVtZW50cyBJQnVpbGRBZ2VudCB7XG4gICAgcHVibGljIGdldCBhZ2VudE5hbWUoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuICdBenVyZSBQaXBlbGluZXMnXG4gICAgfVxuXG4gICAgcHVibGljIHByb3h5Q29uZmlndXJhdGlvbih1cmw6IHN0cmluZyk6IElSZXF1ZXN0T3B0aW9ucyB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBwcm94eTogdGFza0xpYi5nZXRIdHRwUHJveHlDb25maWd1cmF0aW9uKHVybCksXG4gICAgICAgICAgICBjZXJ0OiB0YXNrTGliLmdldEh0dHBDZXJ0Q29uZmlndXJhdGlvbigpLFxuICAgICAgICAgICAgaWdub3JlU3NsRXJyb3I6ICEhdGFza0xpYi5nZXRWYXJpYWJsZSgnQWdlbnQuU2tpcENlcnRWYWxpZGF0aW9uJylcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBmaW5kKHRvb2xOYW1lOiBzdHJpbmcsIHZlcnNpb25TcGVjOiBzdHJpbmcsIGFyY2g/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdG9vbExpYi5maW5kTG9jYWxUb29sKHRvb2xOYW1lLCB2ZXJzaW9uU3BlYywgYXJjaClcbiAgICB9XG5cbiAgICBwdWJsaWMgY2FjaGVEaXIoXG4gICAgICAgIHNvdXJjZURpcjogc3RyaW5nLFxuICAgICAgICB0b29sOiBzdHJpbmcsXG4gICAgICAgIHZlcnNpb246IHN0cmluZyxcbiAgICAgICAgYXJjaD86IHN0cmluZ1xuICAgICk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiB0b29sTGliLmNhY2hlRGlyKHNvdXJjZURpciwgdG9vbCwgdmVyc2lvbiwgYXJjaClcbiAgICB9XG5cbiAgICBwdWJsaWMgY3JlYXRlVGVtcERpcigpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRhc2tMaWIuZ2V0VmFyaWFibGUoJ0FnZW50LlRlbXBEaXJlY3RvcnknKSlcbiAgICB9XG5cbiAgICBwdWJsaWMgZGVidWcobWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIHRhc2tMaWIuZGVidWcobWVzc2FnZSlcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0RmFpbGVkKG1lc3NhZ2U6IHN0cmluZywgZG9uZT86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgdGFza0xpYi5zZXRSZXN1bHQodGFza0xpYi5UYXNrUmVzdWx0LkZhaWxlZCwgbWVzc2FnZSwgZG9uZSlcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0U3VjY2VlZGVkKG1lc3NhZ2U6IHN0cmluZywgZG9uZT86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgdGFza0xpYi5zZXRSZXN1bHQodGFza0xpYi5UYXNrUmVzdWx0LlN1Y2NlZWRlZCwgbWVzc2FnZSwgZG9uZSlcbiAgICB9XG5cbiAgICBwdWJsaWMgZXhwb3J0VmFyaWFibGUobmFtZTogc3RyaW5nLCB2YWw6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0YXNrTGliLnNldFZhcmlhYmxlKG5hbWUsIHZhbClcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0VmFyaWFibGUobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRhc2tMaWIuZ2V0VmFyaWFibGUobmFtZSlcbiAgICB9XG5cbiAgICBwdWJsaWMgYWRkUGF0aChpbnB1dFBhdGg6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0b29sTGliLnByZXBlbmRQYXRoKGlucHV0UGF0aClcbiAgICB9XG5cbiAgICBwdWJsaWMgd2hpY2godG9vbDogc3RyaW5nLCBjaGVjaz86IGJvb2xlYW4pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRhc2tMaWIud2hpY2godG9vbCwgY2hlY2spKVxuICAgIH1cblxuICAgIHB1YmxpYyBleGVjKGV4ZWM6IHN0cmluZywgYXJnczogc3RyaW5nW10pOiBQcm9taXNlPElFeGVjUmVzdWx0PiB7XG4gICAgICAgIGNvbnN0IHRyID0gdGFza0xpYi50b29sKGV4ZWMpXG4gICAgICAgIHRyLmFyZyhhcmdzKVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRyLmV4ZWNTeW5jKClcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgICBjb2RlOiByZXN1bHQuY29kZSxcbiAgICAgICAgICAgIGVycm9yOiByZXN1bHQuZXJyb3IsXG4gICAgICAgICAgICBzdGRlcnI6IHJlc3VsdC5zdGRlcnIsXG4gICAgICAgICAgICBzdGRvdXQ6IHJlc3VsdC5zdGRvdXRcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0U291cmNlRGlyKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFZhcmlhYmxlKCdCdWlsZC5Tb3VyY2VzRGlyZWN0b3J5JylcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0T3V0cHV0KG5hbWU6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0YXNrTGliLnNldFZhcmlhYmxlKG5hbWUsIHZhbHVlKVxuICAgIH1cblxuICAgIHB1YmxpYyBnZXRJbnB1dChpbnB1dDogc3RyaW5nLCByZXF1aXJlZD86IGJvb2xlYW4pOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGFza0xpYi5nZXRJbnB1dChpbnB1dCwgcmVxdWlyZWQpPy50cmltKClcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0TGlzdElucHV0KGlucHV0OiBzdHJpbmcsIHJlcXVpcmVkPzogYm9vbGVhbik6IHN0cmluZ1tdIHtcbiAgICAgICAgcmV0dXJuIHRhc2tMaWJcbiAgICAgICAgICAgIC5nZXRJbnB1dChpbnB1dCwgcmVxdWlyZWQpXG4gICAgICAgICAgICAuc3BsaXQoJ1xcbicpXG4gICAgICAgICAgICAuZmlsdGVyKHggPT4geCAhPT0gJycpXG4gICAgfVxuXG4gICAgcHVibGljIGdldEJvb2xlYW5JbnB1dChpbnB1dDogc3RyaW5nLCByZXF1aXJlZD86IGJvb2xlYW4pOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRhc2tMaWIuZ2V0Qm9vbElucHV0KGlucHV0LCByZXF1aXJlZClcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNWYWxpZElucHV0RmlsZShpbnB1dDogc3RyaW5nLCBmaWxlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRhc2tMaWIuZmlsZVBhdGhTdXBwbGllZChpbnB1dCkgJiYgdGhpcy5maWxlRXhpc3RzKGZpbGUpXG4gICAgfVxuXG4gICAgcHVibGljIGZpbGVFeGlzdHMoZmlsZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0YXNrTGliLmV4aXN0KGZpbGUpICYmIHRhc2tMaWIuc3RhdHMoZmlsZSkuaXNGaWxlKClcbiAgICB9XG5cbiAgICBwdWJsaWMgZGlyZWN0b3J5RXhpc3RzKGZpbGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGFza0xpYi5leGlzdChmaWxlKSAmJiB0YXNrTGliLnN0YXRzKGZpbGUpLmlzRGlyZWN0b3J5KClcbiAgICB9XG59XG5cbmV4cG9ydCB7IEJ1aWxkQWdlbnQgfVxuIiwiaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnXG5pbXBvcnQgKiBhcyBvcyBmcm9tICdvcydcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCdcbmltcG9ydCAqIGFzIGh0dHAgZnJvbSAndHlwZWQtcmVzdC1jbGllbnQvSHR0cENsaWVudCdcblxuaW1wb3J0IHsgaW5qZWN0LCBpbmplY3RhYmxlIH0gZnJvbSAnaW52ZXJzaWZ5J1xuaW1wb3J0IHsgVFlQRVMsIElFeGVjUmVzdWx0LCBJQnVpbGRBZ2VudCB9IGZyb20gJy4vbW9kZWxzJ1xuaW1wb3J0IHsgSVZlcnNpb25NYW5hZ2VyIH0gZnJvbSAnLi92ZXJzaW9uTWFuYWdlcidcblxuZXhwb3J0IGludGVyZmFjZSBJRG90bmV0VG9vbCB7XG4gICAgZGlzYWJsZVRlbGVtZXRyeSgpOiB2b2lkXG4gICAgdG9vbEluc3RhbGwoXG4gICAgICAgIHRvb2xOYW1lOiBzdHJpbmcsXG4gICAgICAgIHZlcnNpb25TcGVjOiBzdHJpbmcsXG4gICAgICAgIGNoZWNrTGF0ZXN0OiBib29sZWFuLFxuICAgICAgICBpbmNsdWRlUHJlOiBib29sZWFuXG4gICAgKTogUHJvbWlzZTxzdHJpbmc+XG59XG5cbkBpbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBEb3RuZXRUb29sIGltcGxlbWVudHMgSURvdG5ldFRvb2wge1xuICAgIHByb3RlY3RlZCBidWlsZEFnZW50OiBJQnVpbGRBZ2VudFxuICAgIHByb3RlY3RlZCB2ZXJzaW9uTWFuYWdlcjogSVZlcnNpb25NYW5hZ2VyXG4gICAgcHJpdmF0ZSBodHRwQ2xpZW50OiBodHRwLkh0dHBDbGllbnRcblxuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IG51Z2V0Um9vdDogc3RyaW5nID1cbiAgICAgICAgJ2h0dHBzOi8vYXBpLXYydjNzZWFyY2gtMC5udWdldC5vcmcvJ1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIEBpbmplY3QoVFlQRVMuSUJ1aWxkQWdlbnQpIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50LFxuICAgICAgICBAaW5qZWN0KFRZUEVTLklWZXJzaW9uTWFuYWdlcikgdmVyc2lvbk1hbmFnZXI6IElWZXJzaW9uTWFuYWdlclxuICAgICkge1xuICAgICAgICB0aGlzLmJ1aWxkQWdlbnQgPSBidWlsZEFnZW50XG4gICAgICAgIHRoaXMudmVyc2lvbk1hbmFnZXIgPSB2ZXJzaW9uTWFuYWdlclxuICAgICAgICB0aGlzLmh0dHBDbGllbnQgPSBuZXcgaHR0cC5IdHRwQ2xpZW50KFxuICAgICAgICAgICAgJ2RvdG5ldCcsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICB0aGlzLmJ1aWxkQWdlbnQucHJveHlDb25maWd1cmF0aW9uKERvdG5ldFRvb2wubnVnZXRSb290KVxuICAgICAgICApXG4gICAgfVxuXG4gICAgcHVibGljIGRpc2FibGVUZWxlbWV0cnkoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5leHBvcnRWYXJpYWJsZSgnRE9UTkVUX0NMSV9URUxFTUVUUllfT1BUT1VUJywgJ3RydWUnKVxuICAgICAgICB0aGlzLmJ1aWxkQWdlbnQuZXhwb3J0VmFyaWFibGUoJ0RPVE5FVF9OT0xPR08nLCAndHJ1ZScpXG4gICAgfVxuXG4gICAgcHVibGljIGV4ZWN1dGUoY21kOiBzdHJpbmcsIGFyZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD4ge1xuICAgICAgICBjb25zb2xlLmxvZyhgQ29tbWFuZDogJHtjbWR9ICR7YXJncy5qb2luKCcgJyl9YClcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRBZ2VudC5leGVjKGNtZCwgYXJncylcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgdG9vbEluc3RhbGwoXG4gICAgICAgIHRvb2xOYW1lOiBzdHJpbmcsXG4gICAgICAgIHZlcnNpb25TcGVjOiBzdHJpbmcsXG4gICAgICAgIGNoZWNrTGF0ZXN0OiBib29sZWFuLFxuICAgICAgICBpbmNsdWRlUHJlOiBib29sZWFuXG4gICAgKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICAgIGNvbnNvbGUubG9nKCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpXG4gICAgICAgIGNvbnNvbGUubG9nKGBJbnN0YWxsaW5nICR7dG9vbE5hbWV9IHZlcnNpb24gYCArIHZlcnNpb25TcGVjKVxuICAgICAgICBjb25zb2xlLmxvZygnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKVxuXG4gICAgICAgIGlmICh0aGlzLnZlcnNpb25NYW5hZ2VyLmlzRXhwbGljaXRWZXJzaW9uKHZlcnNpb25TcGVjKSkge1xuICAgICAgICAgICAgY2hlY2tMYXRlc3QgPSBmYWxzZSAvLyBjaGVjayBsYXRlc3QgZG9lc24ndCBtYWtlIHNlbnNlIHdoZW4gZXhwbGljaXQgdmVyc2lvblxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHRvb2xQYXRoOiBzdHJpbmdcbiAgICAgICAgaWYgKCFjaGVja0xhdGVzdCkge1xuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIExldCdzIHRyeSBhbmQgcmVzb2x2ZSB0aGUgdmVyc2lvbiBzcGVjIGxvY2FsbHkgZmlyc3RcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICB0b29sUGF0aCA9IHRoaXMuYnVpbGRBZ2VudC5maW5kKHRvb2xOYW1lLCB2ZXJzaW9uU3BlYylcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdG9vbFBhdGgpIHtcbiAgICAgICAgICAgIGxldCB2ZXJzaW9uOiBzdHJpbmdcbiAgICAgICAgICAgIGlmICh0aGlzLnZlcnNpb25NYW5hZ2VyLmlzRXhwbGljaXRWZXJzaW9uKHZlcnNpb25TcGVjKSkge1xuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gRXhwbGljaXQgdmVyc2lvbiB3YXMgc3BlY2lmaWVkLiBObyBuZWVkIHRvIHF1ZXJ5IGZvciBsaXN0IG9mIHZlcnNpb25zLlxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgdmVyc2lvbiA9IHZlcnNpb25TcGVjXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gTGV0J3MgcXVlcnkgYW5kIHJlc29sdmUgdGhlIGxhdGVzdCB2ZXJzaW9uIGZvciB0aGUgdmVyc2lvblNwZWMuXG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIHZlcnNpb24gaXMgYW4gZXhwbGljaXQgdmVyc2lvbiAoMS4xLjEgb3IgdjEuMS4xKSB0aGVuIG5vIG5lZWQgdG8gcXVlcnkuXG4gICAgICAgICAgICAgICAgLy8gSWYgeW91ciB0b29sIGRvZXNuJ3Qgb2ZmZXIgYSBtZWNoYW5pc20gdG8gcXVlcnksXG4gICAgICAgICAgICAgICAgLy8gdGhlbiBpdCBjYW4gb25seSBzdXBwb3J0IGV4YWN0IHZlcnNpb24gaW5wdXRzLlxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgdmVyc2lvbiA9IGF3YWl0IHRoaXMucXVlcnlMYXRlc3RNYXRjaChcbiAgICAgICAgICAgICAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgICAgICAgICAgICAgIHZlcnNpb25TcGVjLFxuICAgICAgICAgICAgICAgICAgICBpbmNsdWRlUHJlXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIGlmICghdmVyc2lvbikge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBgVW5hYmxlIHRvIGZpbmQgJHt0b29sTmFtZX0gdmVyc2lvbiAnJHt2ZXJzaW9uU3BlY30nLmBcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgdGhlIGNhY2hlIGZvciB0aGUgcmVzb2x2ZWQgdmVyc2lvbi5cbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIHRvb2xQYXRoID0gdGhpcy5idWlsZEFnZW50LmZpbmQodG9vbE5hbWUsIHZlcnNpb24pXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRvb2xQYXRoKSB7XG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyBEb3dubG9hZCwgZXh0cmFjdCwgY2FjaGVcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIHRvb2xQYXRoID0gYXdhaXQgdGhpcy5hY3F1aXJlVG9vbCh0b29sTmFtZSwgdmVyc2lvbilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFByZXBlbmQgdGhlIHRvb2xzIHBhdGguIFRoaXMgcHJlcGVuZHMgdGhlIFBBVEggZm9yIHRoZSBjdXJyZW50IHByb2Nlc3MgYW5kXG4gICAgICAgIC8vIGluc3RydWN0cyB0aGUgYWdlbnQgdG8gcHJlcGVuZCBmb3IgZWFjaCB0YXNrIHRoYXQgZm9sbG93cy5cbiAgICAgICAgLy9cbiAgICAgICAgdGhpcy5idWlsZEFnZW50LmRlYnVnKGB0b29sUGF0aDogJHt0b29sUGF0aH1gKVxuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIG9zLnBsYXRmb3JtKCkgIT09ICd3aW4zMicgJiZcbiAgICAgICAgICAgICF0aGlzLmJ1aWxkQWdlbnQuZ2V0VmFyaWFibGUoJ0RPVE5FVF9ST09UJylcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBsZXQgZG90bmV0UGF0aCA9IGF3YWl0IHRoaXMuYnVpbGRBZ2VudC53aGljaCgnZG90bmV0JylcbiAgICAgICAgICAgIGRvdG5ldFBhdGggPSBmcy5yZWFkbGlua1N5bmMoZG90bmV0UGF0aCkgfHwgZG90bmV0UGF0aFxuICAgICAgICAgICAgY29uc3QgZG90bmV0Um9vdCA9IHBhdGguZGlybmFtZShkb3RuZXRQYXRoKVxuICAgICAgICAgICAgdGhpcy5idWlsZEFnZW50LmV4cG9ydFZhcmlhYmxlKCdET1RORVRfUk9PVCcsIGRvdG5ldFJvb3QpXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5idWlsZEFnZW50LmFkZFBhdGgodG9vbFBhdGgpXG5cbiAgICAgICAgcmV0dXJuIHRvb2xQYXRoXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBxdWVyeUxhdGVzdE1hdGNoKFxuICAgICAgICB0b29sTmFtZTogc3RyaW5nLFxuICAgICAgICB2ZXJzaW9uU3BlYzogc3RyaW5nLFxuICAgICAgICBpbmNsdWRlUHJlcmVsZWFzZTogYm9vbGVhblxuICAgICk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZyhcbiAgICAgICAgICAgIGBxdWVyeWluZyB0b29sIHZlcnNpb25zIGZvciAke3Rvb2xOYW1lfSR7XG4gICAgICAgICAgICAgICAgdmVyc2lvblNwZWMgPyBgQCR7dmVyc2lvblNwZWN9YCA6ICcnXG4gICAgICAgICAgICB9ICR7aW5jbHVkZVByZXJlbGVhc2UgPyAnaW5jbHVkaW5nIHByZS1yZWxlYXNlcycgOiAnJ31gXG4gICAgICAgIClcblxuICAgICAgICBjb25zdCBkb3dubG9hZFBhdGggPSBgJHtcbiAgICAgICAgICAgIERvdG5ldFRvb2wubnVnZXRSb290XG4gICAgICAgIH1xdWVyeT9xPSR7ZW5jb2RlVVJJQ29tcG9uZW50KHRvb2xOYW1lLnRvTG93ZXJDYXNlKCkpfSZwcmVyZWxlYXNlPSR7XG4gICAgICAgICAgICBpbmNsdWRlUHJlcmVsZWFzZSA/ICd0cnVlJyA6ICdmYWxzZSdcbiAgICAgICAgfSZzZW1WZXJMZXZlbD0yLjAuMGBcblxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmh0dHBDbGllbnQuZ2V0KGRvd25sb2FkUGF0aClcblxuICAgICAgICBpZiAoIXJlcyB8fCByZXMubWVzc2FnZS5zdGF0dXNDb2RlICE9PSAyMDApIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBib2R5OiBzdHJpbmcgPSBhd2FpdCByZXMucmVhZEJvZHkoKVxuICAgICAgICBjb25zdCBkYXRhID0gSlNPTi5wYXJzZShib2R5KS5kYXRhXG5cbiAgICAgICAgY29uc3QgdmVyc2lvbnMgPSAoZGF0YVswXS52ZXJzaW9ucyBhcyB7IHZlcnNpb246IHN0cmluZyB9W10pLm1hcChcbiAgICAgICAgICAgIHggPT4geC52ZXJzaW9uXG4gICAgICAgIClcbiAgICAgICAgaWYgKCF2ZXJzaW9ucyB8fCAhdmVyc2lvbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5idWlsZEFnZW50LmRlYnVnKGBnb3QgdmVyc2lvbnM6ICR7dmVyc2lvbnMuam9pbignLCAnKX1gKVxuXG4gICAgICAgIHJldHVybiB0aGlzLnZlcnNpb25NYW5hZ2VyLmV2YWx1YXRlVmVyc2lvbnModmVyc2lvbnMsIHZlcnNpb25TcGVjKVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgYWNxdWlyZVRvb2woXG4gICAgICAgIHRvb2xOYW1lOiBzdHJpbmcsXG4gICAgICAgIHZlcnNpb246IHN0cmluZ1xuICAgICk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIGNvbnN0IHRlbXBEaXJlY3RvcnkgPSBhd2FpdCB0aGlzLmJ1aWxkQWdlbnQuY3JlYXRlVGVtcERpcigpXG4gICAgICAgIGxldCBhcmdzID0gWyd0b29sJywgJ2luc3RhbGwnLCB0b29sTmFtZSwgJy0tdG9vbC1wYXRoJywgdGVtcERpcmVjdG9yeV1cblxuICAgICAgICBpZiAodmVyc2lvbikge1xuICAgICAgICAgICAgdmVyc2lvbiA9IHRoaXMudmVyc2lvbk1hbmFnZXIuY2xlYW5WZXJzaW9uKHZlcnNpb24pXG4gICAgICAgICAgICBhcmdzID0gYXJncy5jb25jYXQoWyctLXZlcnNpb24nLCB2ZXJzaW9uXSlcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZXhlY3V0ZSgnZG90bmV0JywgYXJncylcbiAgICAgICAgY29uc3Qgc3RhdHVzID0gcmVzdWx0LmNvZGUgPT09IDAgPyAnc3VjY2VzcycgOiAnZmFpbHVyZSdcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IHJlc3VsdC5jb2RlID09PSAwID8gcmVzdWx0LnN0ZG91dCA6IHJlc3VsdC5zdGRlcnJcblxuICAgICAgICB0aGlzLmJ1aWxkQWdlbnQuZGVidWcoYHRvb2wgaW5zdGFsbCByZXN1bHQ6ICR7c3RhdHVzfSAke21lc3NhZ2V9YClcblxuICAgICAgICBpZiAocmVzdWx0LmNvZGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRXJyb3IgaW5zdGFsbGluZyB0b29sJylcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmJ1aWxkQWdlbnQuY2FjaGVEaXIodGVtcERpcmVjdG9yeSwgdG9vbE5hbWUsIHZlcnNpb24pXG4gICAgfVxufVxuIiwiaW1wb3J0IHsgQ29udGFpbmVyIH0gZnJvbSAnaW52ZXJzaWZ5J1xuaW1wb3J0IHsgSVZlcnNpb25NYW5hZ2VyLCBWZXJzaW9uTWFuYWdlciB9IGZyb20gJy4vdmVyc2lvbk1hbmFnZXInXG5pbXBvcnQgeyBUWVBFUywgSUJ1aWxkQWdlbnQgfSBmcm9tICcuL21vZGVscydcbmltcG9ydCB7IEJ1aWxkQWdlbnQgfSBmcm9tICcuLi9hZ2VudC9tb2NrL2J1aWxkLWFnZW50J1xuXG5jb25zdCBjb250YWluZXIgPSBuZXcgQ29udGFpbmVyKClcblxuY29udGFpbmVyLmJpbmQ8SVZlcnNpb25NYW5hZ2VyPihUWVBFUy5JVmVyc2lvbk1hbmFnZXIpLnRvKFZlcnNpb25NYW5hZ2VyKVxuY29udGFpbmVyLmJpbmQ8SUJ1aWxkQWdlbnQ+KFRZUEVTLklCdWlsZEFnZW50KS50byhCdWlsZEFnZW50KVxuXG5leHBvcnQgZGVmYXVsdCBjb250YWluZXJcbiIsImltcG9ydCB7IElSZXF1ZXN0T3B0aW9ucyB9IGZyb20gJ3R5cGVkLXJlc3QtY2xpZW50L0ludGVyZmFjZXMnXG5cbmV4cG9ydCBjb25zdCBUWVBFUyA9IHtcbiAgICBJQnVpbGRBZ2VudDogU3ltYm9sLmZvcignQnVpbGRBZ2VudCcpLFxuICAgIElEb3RuZXRUb29sOiBTeW1ib2wuZm9yKCdEb3RuZXRUb29sJyksXG4gICAgSUdpdFZlcnNpb25Ub29sOiBTeW1ib2wuZm9yKCdHaXRWZXJzaW9uVG9vbCcpLFxuICAgIElHaXRSZWxlYXNlTWFuYWdlclRvb2w6IFN5bWJvbC5mb3IoJ0dpdFJlbGVhc2VNYW5hZ2VyVG9vbCcpLFxuICAgIElWZXJzaW9uTWFuYWdlcjogU3ltYm9sLmZvcignVmVyc2lvbk1hbmFnZXInKVxufVxuXG5leHBvcnQgZW51bSBTZXR1cEZpZWxkcyB7XG4gICAgaW5jbHVkZVByZXJlbGVhc2UgPSAnaW5jbHVkZVByZXJlbGVhc2UnLFxuICAgIHZlcnNpb25TcGVjID0gJ3ZlcnNpb25TcGVjJ1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElTZXR1cFNldHRpbmdzIHtcbiAgICBbU2V0dXBGaWVsZHMudmVyc2lvblNwZWNdOiBzdHJpbmdcbiAgICBbU2V0dXBGaWVsZHMuaW5jbHVkZVByZXJlbGVhc2VdOiBib29sZWFuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUV4ZWNSZXN1bHQge1xuICAgIHN0ZG91dDogc3RyaW5nXG4gICAgc3RkZXJyOiBzdHJpbmdcbiAgICBjb2RlOiBudW1iZXJcbiAgICBlcnJvcjogRXJyb3Jcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJQnVpbGRBZ2VudCB7XG4gICAgYWdlbnROYW1lOiBzdHJpbmdcbiAgICBwcm94eUNvbmZpZ3VyYXRpb24odXJsOiBzdHJpbmcpOiBJUmVxdWVzdE9wdGlvbnNcbiAgICBmaW5kKHRvb2xOYW1lOiBzdHJpbmcsIHZlcnNpb25TcGVjOiBzdHJpbmcsIGFyY2g/OiBzdHJpbmcpOiBzdHJpbmdcbiAgICBjYWNoZURpcihcbiAgICAgICAgc291cmNlRGlyOiBzdHJpbmcsXG4gICAgICAgIHRvb2w6IHN0cmluZyxcbiAgICAgICAgdmVyc2lvbjogc3RyaW5nLFxuICAgICAgICBhcmNoPzogc3RyaW5nXG4gICAgKTogUHJvbWlzZTxzdHJpbmc+XG4gICAgY3JlYXRlVGVtcERpcigpOiBQcm9taXNlPHN0cmluZz5cbiAgICBkZWJ1ZyhtZXNzYWdlOiBzdHJpbmcpOiB2b2lkXG4gICAgc2V0RmFpbGVkKG1lc3NhZ2U6IHN0cmluZywgZG9uZT86IGJvb2xlYW4pOiB2b2lkXG4gICAgc2V0U3VjY2VlZGVkKG1lc3NhZ2U6IHN0cmluZywgZG9uZT86IGJvb2xlYW4pOiB2b2lkXG4gICAgZXhwb3J0VmFyaWFibGUobmFtZTogc3RyaW5nLCB2YWw6IHN0cmluZyk6IHZvaWRcbiAgICBnZXRWYXJpYWJsZShuYW1lOiBzdHJpbmcpOiBzdHJpbmdcbiAgICBhZGRQYXRoKGlucHV0UGF0aDogc3RyaW5nKTogdm9pZFxuICAgIHdoaWNoKHRvb2w6IHN0cmluZywgY2hlY2s/OiBib29sZWFuKTogUHJvbWlzZTxzdHJpbmc+XG4gICAgZXhlYyhleGVjOiBzdHJpbmcsIGFyZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD5cblxuICAgIGdldFNvdXJjZURpcigpOiBzdHJpbmdcbiAgICBpc1ZhbGlkSW5wdXRGaWxlKGlucHV0OiBzdHJpbmcsIGZpbGU6IHN0cmluZyk6IGJvb2xlYW5cbiAgICBmaWxlRXhpc3RzKGZpbGU6IHN0cmluZyk6IGJvb2xlYW5cbiAgICBkaXJlY3RvcnlFeGlzdHMoZmlsZTogc3RyaW5nKTogYm9vbGVhblxuXG4gICAgc2V0T3V0cHV0KG5hbWU6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHZvaWRcbiAgICBnZXRJbnB1dChpbnB1dDogc3RyaW5nLCByZXF1aXJlZD86IGJvb2xlYW4pOiBzdHJpbmdcbiAgICBnZXRMaXN0SW5wdXQoaW5wdXQ6IHN0cmluZywgcmVxdWlyZWQ/OiBib29sZWFuKTogc3RyaW5nW11cbiAgICBnZXRCb29sZWFuSW5wdXQoaW5wdXQ6IHN0cmluZywgcmVxdWlyZWQ/OiBib29sZWFuKTogYm9vbGVhblxufVxuIiwiaW1wb3J0IHsgSUJ1aWxkQWdlbnQsIFNldHVwRmllbGRzLCBJU2V0dXBTZXR0aW5ncyB9IGZyb20gJy4vbW9kZWxzJ1xuXG5leHBvcnQgY2xhc3MgU2V0dGluZ3Mge1xuICAgIHB1YmxpYyBzdGF0aWMgZ2V0U2V0dXBTZXR0aW5ncyhidWlsZEFnZW50OiBJQnVpbGRBZ2VudCk6IElTZXR1cFNldHRpbmdzIHtcbiAgICAgICAgY29uc3QgdmVyc2lvblNwZWMgPSBidWlsZEFnZW50LmdldElucHV0KFNldHVwRmllbGRzLnZlcnNpb25TcGVjKVxuICAgICAgICBjb25zdCBpbmNsdWRlUHJlcmVsZWFzZSA9IGJ1aWxkQWdlbnQuZ2V0Qm9vbGVhbklucHV0KFxuICAgICAgICAgICAgU2V0dXBGaWVsZHMuaW5jbHVkZVByZXJlbGVhc2VcbiAgICAgICAgKVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2ZXJzaW9uU3BlYyxcbiAgICAgICAgICAgIGluY2x1ZGVQcmVyZWxlYXNlXG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJpbXBvcnQgY21wIGZyb20gJ3NlbXZlci1jb21wYXJlJ1xuaW1wb3J0ICogYXMgc2VtdmVyIGZyb20gJ3NlbXZlcidcbmltcG9ydCB7IGluamVjdGFibGUsIGluamVjdCB9IGZyb20gJ2ludmVyc2lmeSdcblxuaW1wb3J0IHsgSUJ1aWxkQWdlbnQsIFRZUEVTIH0gZnJvbSAnLi9tb2RlbHMnXG5cbmV4cG9ydCBpbnRlcmZhY2UgSVZlcnNpb25NYW5hZ2VyIHtcbiAgICBpc0V4cGxpY2l0VmVyc2lvbih2ZXJzaW9uU3BlYzogc3RyaW5nKTogYm9vbGVhblxuICAgIGV2YWx1YXRlVmVyc2lvbnModmVyc2lvbnM6IHN0cmluZ1tdLCB2ZXJzaW9uU3BlYzogc3RyaW5nKTogc3RyaW5nXG4gICAgY2xlYW5WZXJzaW9uKHZlcnNpb246IHN0cmluZyk6IHN0cmluZ1xufVxuXG5AaW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgVmVyc2lvbk1hbmFnZXIgaW1wbGVtZW50cyBJVmVyc2lvbk1hbmFnZXIge1xuICAgIHByaXZhdGUgYnVpbGRBZ2VudDogSUJ1aWxkQWdlbnRcbiAgICBjb25zdHJ1Y3RvcihAaW5qZWN0KFRZUEVTLklCdWlsZEFnZW50KSBidWlsZEFnZW50OiBJQnVpbGRBZ2VudCkge1xuICAgICAgICB0aGlzLmJ1aWxkQWdlbnQgPSBidWlsZEFnZW50XG4gICAgfVxuXG4gICAgcHVibGljIGlzRXhwbGljaXRWZXJzaW9uKHZlcnNpb25TcGVjOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgYyA9IHNlbXZlci5jbGVhbih2ZXJzaW9uU3BlYylcbiAgICAgICAgdGhpcy5idWlsZEFnZW50LmRlYnVnKCdpc0V4cGxpY2l0OiAnICsgYylcblxuICAgICAgICBjb25zdCB2YWxpZCA9IHNlbXZlci52YWxpZChjKSAhPSBudWxsXG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZygnZXhwbGljaXQ/ICcgKyB2YWxpZClcblxuICAgICAgICByZXR1cm4gdmFsaWRcbiAgICB9XG5cbiAgICBwdWJsaWMgZXZhbHVhdGVWZXJzaW9ucyh2ZXJzaW9uczogc3RyaW5nW10sIHZlcnNpb25TcGVjOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBsZXQgdmVyc2lvbjogc3RyaW5nXG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZygnZXZhbHVhdGluZyAnICsgdmVyc2lvbnMubGVuZ3RoICsgJyB2ZXJzaW9ucycpXG4gICAgICAgIHZlcnNpb25zID0gdmVyc2lvbnMuc29ydChjbXApXG4gICAgICAgIGZvciAobGV0IGkgPSB2ZXJzaW9ucy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgY29uc3QgcG90ZW50aWFsOiBzdHJpbmcgPSB2ZXJzaW9uc1tpXVxuICAgICAgICAgICAgY29uc3Qgc2F0aXNmaWVkOiBib29sZWFuID0gc2VtdmVyLnNhdGlzZmllcyhwb3RlbnRpYWwsIHZlcnNpb25TcGVjKVxuICAgICAgICAgICAgaWYgKHNhdGlzZmllZCkge1xuICAgICAgICAgICAgICAgIHZlcnNpb24gPSBwb3RlbnRpYWxcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZlcnNpb24pIHtcbiAgICAgICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZygnbWF0Y2hlZDogJyArIHZlcnNpb24pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmJ1aWxkQWdlbnQuZGVidWcoJ21hdGNoIG5vdCBmb3VuZCcpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdmVyc2lvblxuICAgIH1cblxuICAgIHB1YmxpYyBjbGVhblZlcnNpb24odmVyc2lvbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgdGhpcy5idWlsZEFnZW50LmRlYnVnKCdjbGVhbmluZzogJyArIHZlcnNpb24pXG4gICAgICAgIHJldHVybiBzZW12ZXIuY2xlYW4odmVyc2lvbilcbiAgICB9XG59XG4iLCJpbXBvcnQgJ3JlZmxlY3QtbWV0YWRhdGEnXG5pbXBvcnQgeyBjcmVhdGUgfSBmcm9tICcuL21haW4nXG5cbmNyZWF0ZSgpXG4iLCJpbXBvcnQgeyBJQnVpbGRBZ2VudCwgVFlQRVMgfSBmcm9tICcuLi8uLi9jb3JlL21vZGVscydcbmltcG9ydCB7XG4gICAgSUdpdFJlbGVhc2VNYW5hZ2VyVG9vbCxcbiAgICBHaXRSZWxlYXNlTWFuYWdlclRvb2xcbn0gZnJvbSAnLi4vLi4vdG9vbHMvZ2l0cmVsZWFzZW1hbmFnZXIvdG9vbCdcbmltcG9ydCB7IFNldHRpbmdzIGFzIENvbW1vblNldHRpbmdzIH0gZnJvbSAnLi4vLi4vY29yZS9zZXR0aW5ncydcbmltcG9ydCB7IFNldHRpbmdzIH0gZnJvbSAnLi4vLi4vdG9vbHMvZ2l0cmVsZWFzZW1hbmFnZXIvc2V0dGluZ3MnXG5cbmltcG9ydCBjb250YWluZXIgZnJvbSAnLi4vLi4vY29yZS9pb2MnXG5cbmNvbnRhaW5lclxuICAgIC5iaW5kPElHaXRSZWxlYXNlTWFuYWdlclRvb2w+KFRZUEVTLklHaXRSZWxlYXNlTWFuYWdlclRvb2wpXG4gICAgLnRvKEdpdFJlbGVhc2VNYW5hZ2VyVG9vbClcblxuY29uc3QgZ2l0UmVsZWFzZU1hbmFnZXJUb29sID0gY29udGFpbmVyLmdldDxJR2l0UmVsZWFzZU1hbmFnZXJUb29sPihcbiAgICBUWVBFUy5JR2l0UmVsZWFzZU1hbmFnZXJUb29sXG4pXG5jb25zdCBidWlsZEFnZW50ID0gY29udGFpbmVyLmdldDxJQnVpbGRBZ2VudD4oVFlQRVMuSUJ1aWxkQWdlbnQpXG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzZXR1cCgpIHtcbiAgICB0cnkge1xuICAgICAgICBnaXRSZWxlYXNlTWFuYWdlclRvb2wuZGlzYWJsZVRlbGVtZXRyeSgpXG5cbiAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSBDb21tb25TZXR0aW5ncy5nZXRTZXR1cFNldHRpbmdzKGJ1aWxkQWdlbnQpXG5cbiAgICAgICAgYXdhaXQgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmluc3RhbGwoXG4gICAgICAgICAgICBzZXR0aW5ncy52ZXJzaW9uU3BlYyxcbiAgICAgICAgICAgIHNldHRpbmdzLmluY2x1ZGVQcmVyZWxlYXNlXG4gICAgICAgIClcblxuICAgICAgICBidWlsZEFnZW50LnNldFN1Y2NlZWRlZChcbiAgICAgICAgICAgICdHaXRWZXJzaW9uTWFuYWdlciBpbnN0YWxsZWQgc3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICAgIHRydWVcbiAgICAgICAgKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGJ1aWxkQWdlbnQuc2V0RmFpbGVkKGVycm9yLm1lc3NhZ2UsIHRydWUpXG4gICAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGdpdFJlbGVhc2VNYW5hZ2VyVG9vbC5kaXNhYmxlVGVsZW1ldHJ5KClcblxuICAgICAgICBjb25zdCBzZXR0aW5ncyA9IFNldHRpbmdzLmdldENyZWF0ZVNldHRpbmdzKGJ1aWxkQWdlbnQpXG5cbiAgICAgICAgYXdhaXQgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmNyZWF0ZShzZXR0aW5ncylcblxuICAgICAgICBidWlsZEFnZW50LnNldFN1Y2NlZWRlZChcbiAgICAgICAgICAgICdHaXRWZXJzaW9uTWFuYWdlciBjcmVhdGVkIHJlbGVhc2Ugc3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICAgIHRydWVcbiAgICAgICAgKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGJ1aWxkQWdlbnQuc2V0RmFpbGVkKGVycm9yLm1lc3NhZ2UsIHRydWUpXG4gICAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGlzY2FyZCgpIHtcbiAgICB0cnkge1xuICAgICAgICBnaXRSZWxlYXNlTWFuYWdlclRvb2wuZGlzYWJsZVRlbGVtZXRyeSgpXG5cbiAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSBTZXR0aW5ncy5nZXREaXNjYXJkU2V0dGluZ3MoYnVpbGRBZ2VudClcblxuICAgICAgICBhd2FpdCBnaXRSZWxlYXNlTWFuYWdlclRvb2wuZGlzY2FyZChzZXR0aW5ncylcblxuICAgICAgICBidWlsZEFnZW50LnNldFN1Y2NlZWRlZChcbiAgICAgICAgICAgICdHaXRWZXJzaW9uTWFuYWdlciBkaXNjYXJkZWQgcmVsZWFzZSBzdWNjZXNzZnVsbHknLFxuICAgICAgICAgICAgdHJ1ZVxuICAgICAgICApXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYnVpbGRBZ2VudC5zZXRGYWlsZWQoZXJyb3IubWVzc2FnZSwgdHJ1ZSlcbiAgICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbG9zZSgpIHtcbiAgICB0cnkge1xuICAgICAgICBnaXRSZWxlYXNlTWFuYWdlclRvb2wuZGlzYWJsZVRlbGVtZXRyeSgpXG5cbiAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSBTZXR0aW5ncy5nZXRDbG9zZVNldHRpbmdzKGJ1aWxkQWdlbnQpXG5cbiAgICAgICAgYXdhaXQgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmNsb3NlKHNldHRpbmdzKVxuXG4gICAgICAgIGJ1aWxkQWdlbnQuc2V0U3VjY2VlZGVkKFxuICAgICAgICAgICAgJ0dpdFZlcnNpb25NYW5hZ2VyIGNsb3NlZCByZWxlYXNlIHN1Y2Nlc3NmdWxseScsXG4gICAgICAgICAgICB0cnVlXG4gICAgICAgIClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBidWlsZEFnZW50LnNldEZhaWxlZChlcnJvci5tZXNzYWdlLCB0cnVlKVxuICAgIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9wZW4oKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmRpc2FibGVUZWxlbWV0cnkoKVxuXG4gICAgICAgIGNvbnN0IHNldHRpbmdzID0gU2V0dGluZ3MuZ2V0T3BlblNldHRpbmdzKGJ1aWxkQWdlbnQpXG5cbiAgICAgICAgYXdhaXQgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLm9wZW4oc2V0dGluZ3MpXG5cbiAgICAgICAgYnVpbGRBZ2VudC5zZXRTdWNjZWVkZWQoXG4gICAgICAgICAgICAnR2l0VmVyc2lvbk1hbmFnZXIgb3BlbmVkIHJlbGVhc2Ugc3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICAgIHRydWVcbiAgICAgICAgKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGJ1aWxkQWdlbnQuc2V0RmFpbGVkKGVycm9yLm1lc3NhZ2UsIHRydWUpXG4gICAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHVibGlzaCgpIHtcbiAgICB0cnkge1xuICAgICAgICBnaXRSZWxlYXNlTWFuYWdlclRvb2wuZGlzYWJsZVRlbGVtZXRyeSgpXG5cbiAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSBTZXR0aW5ncy5nZXRQdWJsaXNoU2V0dGluZ3MoYnVpbGRBZ2VudClcblxuICAgICAgICBhd2FpdCBnaXRSZWxlYXNlTWFuYWdlclRvb2wucHVibGlzaChzZXR0aW5ncylcblxuICAgICAgICBidWlsZEFnZW50LnNldFN1Y2NlZWRlZChcbiAgICAgICAgICAgICdHaXRWZXJzaW9uTWFuYWdlciBwdWJsaXNoZWQgcmVsZWFzZSBzdWNjZXNzZnVsbHknLFxuICAgICAgICAgICAgdHJ1ZVxuICAgICAgICApXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYnVpbGRBZ2VudC5zZXRGYWlsZWQoZXJyb3IubWVzc2FnZSwgdHJ1ZSlcbiAgICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhZGRBc3NldCgpIHtcbiAgICB0cnkge1xuICAgICAgICBnaXRSZWxlYXNlTWFuYWdlclRvb2wuZGlzYWJsZVRlbGVtZXRyeSgpXG5cbiAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSBTZXR0aW5ncy5nZXRBZGRBc3NldFNldHRpbmdzKGJ1aWxkQWdlbnQpXG5cbiAgICAgICAgYXdhaXQgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmFkZEFzc2V0KHNldHRpbmdzKVxuXG4gICAgICAgIGJ1aWxkQWdlbnQuc2V0U3VjY2VlZGVkKFxuICAgICAgICAgICAgJ0dpdFZlcnNpb25NYW5hZ2VyIGFkZGVkIGFzc2V0cyB0byByZWxlYXNlIHN1Y2Nlc3NmdWxseScsXG4gICAgICAgICAgICB0cnVlXG4gICAgICAgIClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBidWlsZEFnZW50LnNldEZhaWxlZChlcnJvci5tZXNzYWdlLCB0cnVlKVxuICAgIH1cbn1cbiIsImV4cG9ydCBlbnVtIENvbW1vbkZpZWxkcyB7XG4gICAgcmVwb3NpdG9yeSA9ICdyZXBvc2l0b3J5JyxcbiAgICBvd25lciA9ICdvd25lcicsXG4gICAgdG9rZW4gPSAndG9rZW4nLFxuICAgIHRhcmdldERpcmVjdG9yeSA9ICd0YXJnZXREaXJlY3RvcnknXG59XG5cbmV4cG9ydCBlbnVtIENyZWF0ZUZpZWxkcyB7XG4gICAgbWlsZXN0b25lID0gJ21pbGVzdG9uZScsXG4gICAgbmFtZSA9ICduYW1lJyxcbiAgICBpbnB1dEZpbGVOYW1lID0gJ2lucHV0RmlsZU5hbWUnLFxuICAgIGlzUHJlUmVsZWFzZSA9ICdpc1ByZVJlbGVhc2UnLFxuICAgIGNvbW1pdCA9ICdjb21taXQnLFxuICAgIGFzc2V0cyA9ICdhc3NldHMnXG59XG5cbmV4cG9ydCBlbnVtIERpc2NhcmRGaWVsZHMge1xuICAgIG1pbGVzdG9uZSA9ICdtaWxlc3RvbmUnXG59XG5cbmV4cG9ydCBlbnVtIENsb3NlRmllbGRzIHtcbiAgICBtaWxlc3RvbmUgPSAnbWlsZXN0b25lJ1xufVxuXG5leHBvcnQgZW51bSBPcGVuRmllbGRzIHtcbiAgICBtaWxlc3RvbmUgPSAnbWlsZXN0b25lJ1xufVxuXG5leHBvcnQgZW51bSBQdWJsaXNoRmllbGRzIHtcbiAgICB0YWdOYW1lID0gJ3RhZ05hbWUnXG59XG5cbmV4cG9ydCBlbnVtIEFkZEFzc2V0RmllbGRzIHtcbiAgICB0YWdOYW1lID0gJ3RhZ05hbWUnLFxuICAgIGFzc2V0cyA9ICdhc3NldHMnXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2l0UmVsZWFzZU1hbmFnZXJTZXR0aW5ncyB7XG4gICAgW0NvbW1vbkZpZWxkcy5yZXBvc2l0b3J5XTogc3RyaW5nXG4gICAgW0NvbW1vbkZpZWxkcy5vd25lcl06IHN0cmluZ1xuICAgIFtDb21tb25GaWVsZHMudG9rZW5dOiBzdHJpbmdcbiAgICBbQ29tbW9uRmllbGRzLnRhcmdldERpcmVjdG9yeV06IHN0cmluZ1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdpdFJlbGVhc2VNYW5hZ2VyQ3JlYXRlU2V0dGluZ3NcbiAgICBleHRlbmRzIEdpdFJlbGVhc2VNYW5hZ2VyU2V0dGluZ3Mge1xuICAgIFtDcmVhdGVGaWVsZHMubWlsZXN0b25lXTogc3RyaW5nXG4gICAgW0NyZWF0ZUZpZWxkcy5uYW1lXTogc3RyaW5nXG4gICAgW0NyZWF0ZUZpZWxkcy5pbnB1dEZpbGVOYW1lXTogc3RyaW5nXG4gICAgW0NyZWF0ZUZpZWxkcy5pc1ByZVJlbGVhc2VdOiBib29sZWFuXG4gICAgW0NyZWF0ZUZpZWxkcy5jb21taXRdOiBzdHJpbmdcbiAgICBbQ3JlYXRlRmllbGRzLmFzc2V0c10/OiBzdHJpbmdbXVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdpdFJlbGVhc2VNYW5hZ2VyRGlzY2FyZFNldHRpbmdzXG4gICAgZXh0ZW5kcyBHaXRSZWxlYXNlTWFuYWdlclNldHRpbmdzIHtcbiAgICBbRGlzY2FyZEZpZWxkcy5taWxlc3RvbmVdOiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHaXRSZWxlYXNlTWFuYWdlckNsb3NlU2V0dGluZ3NcbiAgICBleHRlbmRzIEdpdFJlbGVhc2VNYW5hZ2VyU2V0dGluZ3Mge1xuICAgIFtDbG9zZUZpZWxkcy5taWxlc3RvbmVdOiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHaXRSZWxlYXNlTWFuYWdlck9wZW5TZXR0aW5nc1xuICAgIGV4dGVuZHMgR2l0UmVsZWFzZU1hbmFnZXJTZXR0aW5ncyB7XG4gICAgW09wZW5GaWVsZHMubWlsZXN0b25lXTogc3RyaW5nXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2l0UmVsZWFzZU1hbmFnZXJQdWJsaXNoU2V0dGluZ3NcbiAgICBleHRlbmRzIEdpdFJlbGVhc2VNYW5hZ2VyU2V0dGluZ3Mge1xuICAgIFtQdWJsaXNoRmllbGRzLnRhZ05hbWVdOiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHaXRSZWxlYXNlTWFuYWdlckFkZEFzc2V0U2V0dGluZ3NcbiAgICBleHRlbmRzIEdpdFJlbGVhc2VNYW5hZ2VyU2V0dGluZ3Mge1xuICAgIFtBZGRBc3NldEZpZWxkcy50YWdOYW1lXTogc3RyaW5nXG4gICAgW0FkZEFzc2V0RmllbGRzLmFzc2V0c106IHN0cmluZ1tdXG59XG4iLCJpbXBvcnQgeyBJQnVpbGRBZ2VudCB9IGZyb20gJy4uLy4uL2NvcmUvbW9kZWxzJ1xuaW1wb3J0IHtcbiAgICBHaXRSZWxlYXNlTWFuYWdlclNldHRpbmdzLFxuICAgIENvbW1vbkZpZWxkcyxcbiAgICBDcmVhdGVGaWVsZHMsXG4gICAgRGlzY2FyZEZpZWxkcyxcbiAgICBDbG9zZUZpZWxkcyxcbiAgICBPcGVuRmllbGRzLFxuICAgIFB1Ymxpc2hGaWVsZHMsXG4gICAgQWRkQXNzZXRGaWVsZHMsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJDcmVhdGVTZXR0aW5ncyxcbiAgICBHaXRSZWxlYXNlTWFuYWdlckRpc2NhcmRTZXR0aW5ncyxcbiAgICBHaXRSZWxlYXNlTWFuYWdlckNsb3NlU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJPcGVuU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJQdWJsaXNoU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJBZGRBc3NldFNldHRpbmdzXG59IGZyb20gJy4vbW9kZWxzJ1xuXG5leHBvcnQgY2xhc3MgU2V0dGluZ3Mge1xuICAgIHB1YmxpYyBzdGF0aWMgZ2V0Q3JlYXRlU2V0dGluZ3MoXG4gICAgICAgIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50XG4gICAgKTogR2l0UmVsZWFzZU1hbmFnZXJDcmVhdGVTZXR0aW5ncyB7XG4gICAgICAgIGNvbnN0IG1pbGVzdG9uZSA9IGJ1aWxkQWdlbnQuZ2V0SW5wdXQoQ3JlYXRlRmllbGRzLm1pbGVzdG9uZSlcbiAgICAgICAgY29uc3QgbmFtZSA9IGJ1aWxkQWdlbnQuZ2V0SW5wdXQoQ3JlYXRlRmllbGRzLm5hbWUpXG4gICAgICAgIGNvbnN0IGlucHV0RmlsZU5hbWUgPSBidWlsZEFnZW50LmdldElucHV0KENyZWF0ZUZpZWxkcy5pbnB1dEZpbGVOYW1lKVxuICAgICAgICBjb25zdCBpc1ByZVJlbGVhc2UgPSBidWlsZEFnZW50LmdldEJvb2xlYW5JbnB1dChcbiAgICAgICAgICAgIENyZWF0ZUZpZWxkcy5pc1ByZVJlbGVhc2VcbiAgICAgICAgKVxuICAgICAgICBjb25zdCBjb21taXQgPSBidWlsZEFnZW50LmdldElucHV0KENyZWF0ZUZpZWxkcy5jb21taXQpXG4gICAgICAgIGNvbnN0IGFzc2V0cyA9IGJ1aWxkQWdlbnQuZ2V0TGlzdElucHV0KENyZWF0ZUZpZWxkcy5hc3NldHMpXG5cbiAgICAgICAgY29uc3QgY29tbW9uU2V0dGluZ3MgPSBTZXR0aW5ncy5nZXRDb21tb25TZXR0aW5ncyhidWlsZEFnZW50KVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uY29tbW9uU2V0dGluZ3MsXG4gICAgICAgICAgICBtaWxlc3RvbmUsXG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgaW5wdXRGaWxlTmFtZSxcbiAgICAgICAgICAgIGlzUHJlUmVsZWFzZSxcbiAgICAgICAgICAgIGNvbW1pdCxcbiAgICAgICAgICAgIGFzc2V0c1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBnZXREaXNjYXJkU2V0dGluZ3MoXG4gICAgICAgIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50XG4gICAgKTogR2l0UmVsZWFzZU1hbmFnZXJEaXNjYXJkU2V0dGluZ3Mge1xuICAgICAgICBjb25zdCBtaWxlc3RvbmUgPSBidWlsZEFnZW50LmdldElucHV0KERpc2NhcmRGaWVsZHMubWlsZXN0b25lKVxuXG4gICAgICAgIGNvbnN0IGNvbW1vblNldHRpbmdzID0gU2V0dGluZ3MuZ2V0Q29tbW9uU2V0dGluZ3MoYnVpbGRBZ2VudClcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmNvbW1vblNldHRpbmdzLFxuICAgICAgICAgICAgbWlsZXN0b25lXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIGdldENsb3NlU2V0dGluZ3MoXG4gICAgICAgIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50XG4gICAgKTogR2l0UmVsZWFzZU1hbmFnZXJDbG9zZVNldHRpbmdzIHtcbiAgICAgICAgY29uc3QgbWlsZXN0b25lID0gYnVpbGRBZ2VudC5nZXRJbnB1dChDbG9zZUZpZWxkcy5taWxlc3RvbmUpXG5cbiAgICAgICAgY29uc3QgY29tbW9uU2V0dGluZ3MgPSBTZXR0aW5ncy5nZXRDb21tb25TZXR0aW5ncyhidWlsZEFnZW50KVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uY29tbW9uU2V0dGluZ3MsXG4gICAgICAgICAgICBtaWxlc3RvbmVcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgZ2V0T3BlblNldHRpbmdzKFxuICAgICAgICBidWlsZEFnZW50OiBJQnVpbGRBZ2VudFxuICAgICk6IEdpdFJlbGVhc2VNYW5hZ2VyT3BlblNldHRpbmdzIHtcbiAgICAgICAgY29uc3QgbWlsZXN0b25lID0gYnVpbGRBZ2VudC5nZXRJbnB1dChPcGVuRmllbGRzLm1pbGVzdG9uZSlcblxuICAgICAgICBjb25zdCBjb21tb25TZXR0aW5ncyA9IFNldHRpbmdzLmdldENvbW1vblNldHRpbmdzKGJ1aWxkQWdlbnQpXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5jb21tb25TZXR0aW5ncyxcbiAgICAgICAgICAgIG1pbGVzdG9uZVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBnZXRQdWJsaXNoU2V0dGluZ3MoXG4gICAgICAgIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50XG4gICAgKTogR2l0UmVsZWFzZU1hbmFnZXJQdWJsaXNoU2V0dGluZ3Mge1xuICAgICAgICBjb25zdCB0YWdOYW1lID0gYnVpbGRBZ2VudC5nZXRJbnB1dChQdWJsaXNoRmllbGRzLnRhZ05hbWUpXG5cbiAgICAgICAgY29uc3QgY29tbW9uU2V0dGluZ3MgPSBTZXR0aW5ncy5nZXRDb21tb25TZXR0aW5ncyhidWlsZEFnZW50KVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uY29tbW9uU2V0dGluZ3MsXG4gICAgICAgICAgICB0YWdOYW1lXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIGdldEFkZEFzc2V0U2V0dGluZ3MoXG4gICAgICAgIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50XG4gICAgKTogR2l0UmVsZWFzZU1hbmFnZXJBZGRBc3NldFNldHRpbmdzIHtcbiAgICAgICAgY29uc3QgdGFnTmFtZSA9IGJ1aWxkQWdlbnQuZ2V0SW5wdXQoQWRkQXNzZXRGaWVsZHMudGFnTmFtZSlcbiAgICAgICAgY29uc3QgYXNzZXRzID0gYnVpbGRBZ2VudC5nZXRMaXN0SW5wdXQoQWRkQXNzZXRGaWVsZHMuYXNzZXRzKVxuXG4gICAgICAgIGNvbnN0IGNvbW1vblNldHRpbmdzID0gU2V0dGluZ3MuZ2V0Q29tbW9uU2V0dGluZ3MoYnVpbGRBZ2VudClcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmNvbW1vblNldHRpbmdzLFxuICAgICAgICAgICAgdGFnTmFtZSxcbiAgICAgICAgICAgIGFzc2V0c1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgZ2V0Q29tbW9uU2V0dGluZ3MoXG4gICAgICAgIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50XG4gICAgKTogR2l0UmVsZWFzZU1hbmFnZXJTZXR0aW5ncyB7XG4gICAgICAgIGNvbnN0IG93bmVyID0gYnVpbGRBZ2VudC5nZXRJbnB1dChDb21tb25GaWVsZHMub3duZXIsIHRydWUpXG4gICAgICAgIGNvbnN0IHJlcG9zaXRvcnkgPSBidWlsZEFnZW50LmdldElucHV0KENvbW1vbkZpZWxkcy5yZXBvc2l0b3J5LCB0cnVlKVxuICAgICAgICBjb25zdCB0b2tlbiA9IGJ1aWxkQWdlbnQuZ2V0SW5wdXQoQ29tbW9uRmllbGRzLnRva2VuLCB0cnVlKVxuICAgICAgICBjb25zdCB0YXJnZXREaXJlY3RvcnkgPSBidWlsZEFnZW50LmdldElucHV0KFxuICAgICAgICAgICAgQ29tbW9uRmllbGRzLnRhcmdldERpcmVjdG9yeVxuICAgICAgICApXG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG93bmVyLFxuICAgICAgICAgICAgcmVwb3NpdG9yeSxcbiAgICAgICAgICAgIHRva2VuLFxuICAgICAgICAgICAgdGFyZ2V0RGlyZWN0b3J5XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJpbXBvcnQgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKVxuXG5pbXBvcnQgeyBUWVBFUywgSUJ1aWxkQWdlbnQsIElFeGVjUmVzdWx0IH0gZnJvbSAnLi4vLi4vY29yZS9tb2RlbHMnXG5pbXBvcnQgeyBpbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tICdpbnZlcnNpZnknXG5pbXBvcnQgeyBEb3RuZXRUb29sLCBJRG90bmV0VG9vbCB9IGZyb20gJy4uLy4uL2NvcmUvZG90bmV0LXRvb2wnXG5pbXBvcnQgeyBJVmVyc2lvbk1hbmFnZXIgfSBmcm9tICcuLi8uLi9jb3JlL3ZlcnNpb25NYW5hZ2VyJ1xuXG5pbXBvcnQge1xuICAgIEdpdFJlbGVhc2VNYW5hZ2VyU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJDcmVhdGVTZXR0aW5ncyxcbiAgICBHaXRSZWxlYXNlTWFuYWdlckRpc2NhcmRTZXR0aW5ncyxcbiAgICBHaXRSZWxlYXNlTWFuYWdlckNsb3NlU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJPcGVuU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJQdWJsaXNoU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJBZGRBc3NldFNldHRpbmdzXG59IGZyb20gJy4vbW9kZWxzJ1xuXG5leHBvcnQgaW50ZXJmYWNlIElHaXRSZWxlYXNlTWFuYWdlclRvb2wgZXh0ZW5kcyBJRG90bmV0VG9vbCB7XG4gICAgaW5zdGFsbCh2ZXJzaW9uU3BlYzogc3RyaW5nLCBpbmNsdWRlUHJlcmVsZWFzZTogYm9vbGVhbik6IFByb21pc2U8dm9pZD5cbiAgICBjcmVhdGUoc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyQ3JlYXRlU2V0dGluZ3MpOiBQcm9taXNlPElFeGVjUmVzdWx0PlxuICAgIGRpc2NhcmQoc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyRGlzY2FyZFNldHRpbmdzKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD5cbiAgICBjbG9zZShzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJDbG9zZVNldHRpbmdzKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD5cbiAgICBvcGVuKHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlck9wZW5TZXR0aW5ncyk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+XG4gICAgcHVibGlzaChzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJQdWJsaXNoU2V0dGluZ3MpOiBQcm9taXNlPElFeGVjUmVzdWx0PlxuICAgIGFkZEFzc2V0KHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlckFkZEFzc2V0U2V0dGluZ3MpOiBQcm9taXNlPElFeGVjUmVzdWx0PlxufVxuXG5AaW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgR2l0UmVsZWFzZU1hbmFnZXJUb29sXG4gICAgZXh0ZW5kcyBEb3RuZXRUb29sXG4gICAgaW1wbGVtZW50cyBJR2l0UmVsZWFzZU1hbmFnZXJUb29sIHtcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgQGluamVjdChUWVBFUy5JQnVpbGRBZ2VudCkgYnVpbGRBZ2VudDogSUJ1aWxkQWdlbnQsXG4gICAgICAgIEBpbmplY3QoVFlQRVMuSVZlcnNpb25NYW5hZ2VyKSB2ZXJzaW9uTWFuYWdlcjogSVZlcnNpb25NYW5hZ2VyXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKGJ1aWxkQWdlbnQsIHZlcnNpb25NYW5hZ2VyKVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBpbnN0YWxsKFxuICAgICAgICB2ZXJzaW9uU3BlYzogc3RyaW5nLFxuICAgICAgICBpbmNsdWRlUHJlcmVsZWFzZTogYm9vbGVhblxuICAgICk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLnRvb2xJbnN0YWxsKFxuICAgICAgICAgICAgJ0dpdFJlbGVhc2VNYW5hZ2VyLlRvb2wnLFxuICAgICAgICAgICAgdmVyc2lvblNwZWMsXG4gICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgIGluY2x1ZGVQcmVyZWxlYXNlXG4gICAgICAgIClcbiAgICB9XG5cbiAgICBwdWJsaWMgY3JlYXRlKFxuICAgICAgICBzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJDcmVhdGVTZXR0aW5nc1xuICAgICk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+IHtcbiAgICAgICAgY29uc3QgYXJncyA9IHRoaXMuZ2V0Q3JlYXRlQXJndW1lbnRzKHNldHRpbmdzKVxuXG4gICAgICAgIHJldHVybiB0aGlzLmV4ZWN1dGUoJ2RvdG5ldC1naXRyZWxlYXNlbWFuYWdlcicsIGFyZ3MpXG4gICAgfVxuXG4gICAgcHVibGljIGRpc2NhcmQoXG4gICAgICAgIHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlckRpc2NhcmRTZXR0aW5nc1xuICAgICk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+IHtcbiAgICAgICAgY29uc3QgYXJncyA9IHRoaXMuZ2V0RGlzY2FyZEFyZ3VtZW50cyhzZXR0aW5ncylcblxuICAgICAgICByZXR1cm4gdGhpcy5leGVjdXRlKCdkb3RuZXQtZ2l0cmVsZWFzZW1hbmFnZXInLCBhcmdzKVxuICAgIH1cblxuICAgIHB1YmxpYyBjbG9zZShcbiAgICAgICAgc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyQ2xvc2VTZXR0aW5nc1xuICAgICk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+IHtcbiAgICAgICAgY29uc3QgYXJncyA9IHRoaXMuZ2V0Q2xvc2VBcmd1bWVudHMoc2V0dGluZ3MpXG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSgnZG90bmV0LWdpdHJlbGVhc2VtYW5hZ2VyJywgYXJncylcbiAgICB9XG5cbiAgICBwdWJsaWMgb3BlbihzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJPcGVuU2V0dGluZ3MpOiBQcm9taXNlPElFeGVjUmVzdWx0PiB7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSB0aGlzLmdldE9wZW5Bcmd1bWVudHMoc2V0dGluZ3MpXG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSgnZG90bmV0LWdpdHJlbGVhc2VtYW5hZ2VyJywgYXJncylcbiAgICB9XG5cbiAgICBwdWJsaWMgcHVibGlzaChcbiAgICAgICAgc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyUHVibGlzaFNldHRpbmdzXG4gICAgKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD4ge1xuICAgICAgICBjb25zdCBhcmdzID0gdGhpcy5nZXRQdWJsaXNoQXJndW1lbnRzKHNldHRpbmdzKVxuXG4gICAgICAgIHJldHVybiB0aGlzLmV4ZWN1dGUoJ2RvdG5ldC1naXRyZWxlYXNlbWFuYWdlcicsIGFyZ3MpXG4gICAgfVxuXG4gICAgcHVibGljIGFkZEFzc2V0KFxuICAgICAgICBzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJBZGRBc3NldFNldHRpbmdzXG4gICAgKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD4ge1xuICAgICAgICBjb25zdCBhcmdzID0gdGhpcy5nZXRBZGRBc3NldEFyZ3VtZW50cyhzZXR0aW5ncylcblxuICAgICAgICByZXR1cm4gdGhpcy5leGVjdXRlKCdkb3RuZXQtZ2l0cmVsZWFzZW1hbmFnZXInLCBhcmdzKVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Q29tbW9uQXJndW1lbnRzKHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlclNldHRpbmdzKTogc3RyaW5nW10ge1xuICAgICAgICBjb25zdCBhcmdzOiBzdHJpbmdbXSA9IFtdXG5cbiAgICAgICAgYXJncy5wdXNoKCctLW93bmVyJywgc2V0dGluZ3Mub3duZXIpXG4gICAgICAgIGFyZ3MucHVzaCgnLS1yZXBvc2l0b3J5Jywgc2V0dGluZ3MucmVwb3NpdG9yeSlcbiAgICAgICAgYXJncy5wdXNoKCctLXRva2VuJywgc2V0dGluZ3MudG9rZW4pXG5cbiAgICAgICAgc2V0dGluZ3MudGFyZ2V0RGlyZWN0b3J5ID0gdGhpcy5nZXRSZXBvRGlyKHNldHRpbmdzLnRhcmdldERpcmVjdG9yeSlcblxuICAgICAgICBhcmdzLnB1c2goJy0tdGFyZ2V0RGlyZWN0b3J5Jywgc2V0dGluZ3MudGFyZ2V0RGlyZWN0b3J5KVxuXG4gICAgICAgIHJldHVybiBhcmdzXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRDcmVhdGVBcmd1bWVudHMoXG4gICAgICAgIHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlckNyZWF0ZVNldHRpbmdzXG4gICAgKTogc3RyaW5nW10ge1xuICAgICAgICBjb25zdCBhcmdzOiBzdHJpbmdbXSA9IFsnY3JlYXRlJywgLi4udGhpcy5nZXRDb21tb25Bcmd1bWVudHMoc2V0dGluZ3MpXVxuXG4gICAgICAgIGlmIChzZXR0aW5ncy5taWxlc3RvbmUpIHtcbiAgICAgICAgICAgIGFyZ3MucHVzaCgnLS1taWxlc3RvbmUnLCBzZXR0aW5ncy5taWxlc3RvbmUpXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNldHRpbmdzLm5hbWUpIHtcbiAgICAgICAgICAgIGFyZ3MucHVzaCgnLS1uYW1lJywgc2V0dGluZ3MubmFtZSlcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2V0dGluZ3MuY29tbWl0KSB7XG4gICAgICAgICAgICBhcmdzLnB1c2goJy0tdGFyZ2V0Y29tbWl0aXNoJywgc2V0dGluZ3MuY29tbWl0KVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNldHRpbmdzLmlucHV0RmlsZU5hbWUpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmJ1aWxkQWdlbnQuZmlsZUV4aXN0cyhzZXR0aW5ncy5pbnB1dEZpbGVOYW1lKSkge1xuICAgICAgICAgICAgICAgIGFyZ3MucHVzaCgnLS1pbnB1dEZpbGVQYXRoJywgc2V0dGluZ3MuaW5wdXRGaWxlTmFtZSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAnR2l0UmVsZWFzZU1hbmFnZXIgaW5wdXRGaWxlUGF0aCBub3QgZm91bmQgYXQgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXR0aW5ncy5pbnB1dEZpbGVOYW1lXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChzZXR0aW5ncy5pc1ByZVJlbGVhc2UpIHtcbiAgICAgICAgICAgIGFyZ3MucHVzaCgnLS1wcmUnKVxuICAgICAgICB9XG4gICAgICAgIGlmIChzZXR0aW5ncy5hc3NldHMgJiYgc2V0dGluZ3MuYXNzZXRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHNldHRpbmdzLmFzc2V0cyA9IHNldHRpbmdzLmFzc2V0cy5tYXAoYXNzZXQgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXRoLmpvaW4oc2V0dGluZ3MudGFyZ2V0RGlyZWN0b3J5LCBhc3NldClcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGFyZ3MucHVzaCgnLS1hc3NldHMnLCBzZXR0aW5ncy5hc3NldHMuam9pbignLCcpKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFyZ3NcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldERpc2NhcmRBcmd1bWVudHMoXG4gICAgICAgIHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlckRpc2NhcmRTZXR0aW5nc1xuICAgICk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgYXJnczogc3RyaW5nW10gPSBbJ2Rpc2NhcmQnLCAuLi50aGlzLmdldENvbW1vbkFyZ3VtZW50cyhzZXR0aW5ncyldXG5cbiAgICAgICAgaWYgKHNldHRpbmdzLm1pbGVzdG9uZSkge1xuICAgICAgICAgICAgYXJncy5wdXNoKCctLW1pbGVzdG9uZScsIHNldHRpbmdzLm1pbGVzdG9uZSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhcmdzXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRDbG9zZUFyZ3VtZW50cyhcbiAgICAgICAgc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyQ2xvc2VTZXR0aW5nc1xuICAgICk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgYXJnczogc3RyaW5nW10gPSBbJ2Nsb3NlJywgLi4udGhpcy5nZXRDb21tb25Bcmd1bWVudHMoc2V0dGluZ3MpXVxuXG4gICAgICAgIGlmIChzZXR0aW5ncy5taWxlc3RvbmUpIHtcbiAgICAgICAgICAgIGFyZ3MucHVzaCgnLS1taWxlc3RvbmUnLCBzZXR0aW5ncy5taWxlc3RvbmUpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXJnc1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0T3BlbkFyZ3VtZW50cyhcbiAgICAgICAgc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyT3BlblNldHRpbmdzXG4gICAgKTogc3RyaW5nW10ge1xuICAgICAgICBjb25zdCBhcmdzOiBzdHJpbmdbXSA9IFsnb3BlbicsIC4uLnRoaXMuZ2V0Q29tbW9uQXJndW1lbnRzKHNldHRpbmdzKV1cblxuICAgICAgICBpZiAoc2V0dGluZ3MubWlsZXN0b25lKSB7XG4gICAgICAgICAgICBhcmdzLnB1c2goJy0tbWlsZXN0b25lJywgc2V0dGluZ3MubWlsZXN0b25lKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFyZ3NcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFB1Ymxpc2hBcmd1bWVudHMoXG4gICAgICAgIHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlclB1Ymxpc2hTZXR0aW5nc1xuICAgICk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgYXJnczogc3RyaW5nW10gPSBbJ3B1Ymxpc2gnLCAuLi50aGlzLmdldENvbW1vbkFyZ3VtZW50cyhzZXR0aW5ncyldXG5cbiAgICAgICAgaWYgKHNldHRpbmdzLnRhZ05hbWUpIHtcbiAgICAgICAgICAgIGFyZ3MucHVzaCgnLS10YWdOYW1lJywgc2V0dGluZ3MudGFnTmFtZSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhcmdzXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRBZGRBc3NldEFyZ3VtZW50cyhcbiAgICAgICAgc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyQWRkQXNzZXRTZXR0aW5nc1xuICAgICk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgYXJnczogc3RyaW5nW10gPSBbXG4gICAgICAgICAgICAnYWRkYXNzZXQnLFxuICAgICAgICAgICAgLi4udGhpcy5nZXRDb21tb25Bcmd1bWVudHMoc2V0dGluZ3MpXG4gICAgICAgIF1cblxuICAgICAgICBpZiAoc2V0dGluZ3MudGFnTmFtZSkge1xuICAgICAgICAgICAgYXJncy5wdXNoKCctLXRhZ05hbWUnLCBzZXR0aW5ncy50YWdOYW1lKVxuICAgICAgICB9XG4gICAgICAgIGlmIChzZXR0aW5ncy5hc3NldHMgJiYgc2V0dGluZ3MuYXNzZXRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHNldHRpbmdzLmFzc2V0cyA9IHNldHRpbmdzLmFzc2V0cy5tYXAoYXNzZXQgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXRoLmpvaW4oc2V0dGluZ3MudGFyZ2V0RGlyZWN0b3J5LCBhc3NldClcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGFyZ3MucHVzaCgnLS1hc3NldHMnLCBzZXR0aW5ncy5hc3NldHMuam9pbignLCcpKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFyZ3NcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFJlcG9EaXIodGFyZ2V0UGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgbGV0IHdvcmtEaXI6IHN0cmluZ1xuICAgICAgICBjb25zdCBzcmNEaXIgPSB0aGlzLmJ1aWxkQWdlbnQuZ2V0U291cmNlRGlyKClcbiAgICAgICAgaWYgKCF0YXJnZXRQYXRoKSB7XG4gICAgICAgICAgICB3b3JrRGlyID0gc3JjRGlyXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAodGhpcy5idWlsZEFnZW50LmRpcmVjdG9yeUV4aXN0cyh0YXJnZXRQYXRoKSkge1xuICAgICAgICAgICAgICAgIHdvcmtEaXIgPSBwYXRoLmpvaW4oc3JjRGlyLCB0YXJnZXRQYXRoKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpcmVjdG9yeSBub3QgZm91bmQgYXQgJyArIHRhcmdldFBhdGgpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHdvcmtEaXIucmVwbGFjZSgvXFxcXC9nLCAnLycpXG4gICAgfVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuIFNlZSBMSUNFTlNFIGZpbGUgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgZnVsbCBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG52YXIgX19hd2FpdGVyID0gKHRoaXMgJiYgdGhpcy5fX2F3YWl0ZXIpIHx8IGZ1bmN0aW9uICh0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUocmVzdWx0LnZhbHVlKTsgfSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59O1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbmNvbnN0IHVybCA9IHJlcXVpcmUoXCJ1cmxcIik7XHJcbmNvbnN0IGh0dHAgPSByZXF1aXJlKFwiaHR0cFwiKTtcclxuY29uc3QgaHR0cHMgPSByZXF1aXJlKFwiaHR0cHNcIik7XHJcbmNvbnN0IHV0aWwgPSByZXF1aXJlKFwiLi9VdGlsXCIpO1xyXG5sZXQgZnM7XHJcbmxldCB0dW5uZWw7XHJcbnZhciBIdHRwQ29kZXM7XHJcbihmdW5jdGlvbiAoSHR0cENvZGVzKSB7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiT0tcIl0gPSAyMDBdID0gXCJPS1wiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk11bHRpcGxlQ2hvaWNlc1wiXSA9IDMwMF0gPSBcIk11bHRpcGxlQ2hvaWNlc1wiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk1vdmVkUGVybWFuZW50bHlcIl0gPSAzMDFdID0gXCJNb3ZlZFBlcm1hbmVudGx5XCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiUmVzb3VyY2VNb3ZlZFwiXSA9IDMwMl0gPSBcIlJlc291cmNlTW92ZWRcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJTZWVPdGhlclwiXSA9IDMwM10gPSBcIlNlZU90aGVyXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiTm90TW9kaWZpZWRcIl0gPSAzMDRdID0gXCJOb3RNb2RpZmllZFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlVzZVByb3h5XCJdID0gMzA1XSA9IFwiVXNlUHJveHlcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJTd2l0Y2hQcm94eVwiXSA9IDMwNl0gPSBcIlN3aXRjaFByb3h5XCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiVGVtcG9yYXJ5UmVkaXJlY3RcIl0gPSAzMDddID0gXCJUZW1wb3JhcnlSZWRpcmVjdFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlBlcm1hbmVudFJlZGlyZWN0XCJdID0gMzA4XSA9IFwiUGVybWFuZW50UmVkaXJlY3RcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJCYWRSZXF1ZXN0XCJdID0gNDAwXSA9IFwiQmFkUmVxdWVzdFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlVuYXV0aG9yaXplZFwiXSA9IDQwMV0gPSBcIlVuYXV0aG9yaXplZFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlBheW1lbnRSZXF1aXJlZFwiXSA9IDQwMl0gPSBcIlBheW1lbnRSZXF1aXJlZFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIkZvcmJpZGRlblwiXSA9IDQwM10gPSBcIkZvcmJpZGRlblwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk5vdEZvdW5kXCJdID0gNDA0XSA9IFwiTm90Rm91bmRcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJNZXRob2ROb3RBbGxvd2VkXCJdID0gNDA1XSA9IFwiTWV0aG9kTm90QWxsb3dlZFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk5vdEFjY2VwdGFibGVcIl0gPSA0MDZdID0gXCJOb3RBY2NlcHRhYmxlXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiUHJveHlBdXRoZW50aWNhdGlvblJlcXVpcmVkXCJdID0gNDA3XSA9IFwiUHJveHlBdXRoZW50aWNhdGlvblJlcXVpcmVkXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiUmVxdWVzdFRpbWVvdXRcIl0gPSA0MDhdID0gXCJSZXF1ZXN0VGltZW91dFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIkNvbmZsaWN0XCJdID0gNDA5XSA9IFwiQ29uZmxpY3RcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJHb25lXCJdID0gNDEwXSA9IFwiR29uZVwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlRvb01hbnlSZXF1ZXN0c1wiXSA9IDQyOV0gPSBcIlRvb01hbnlSZXF1ZXN0c1wiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIkludGVybmFsU2VydmVyRXJyb3JcIl0gPSA1MDBdID0gXCJJbnRlcm5hbFNlcnZlckVycm9yXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiTm90SW1wbGVtZW50ZWRcIl0gPSA1MDFdID0gXCJOb3RJbXBsZW1lbnRlZFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIkJhZEdhdGV3YXlcIl0gPSA1MDJdID0gXCJCYWRHYXRld2F5XCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiU2VydmljZVVuYXZhaWxhYmxlXCJdID0gNTAzXSA9IFwiU2VydmljZVVuYXZhaWxhYmxlXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiR2F0ZXdheVRpbWVvdXRcIl0gPSA1MDRdID0gXCJHYXRld2F5VGltZW91dFwiO1xyXG59KShIdHRwQ29kZXMgPSBleHBvcnRzLkh0dHBDb2RlcyB8fCAoZXhwb3J0cy5IdHRwQ29kZXMgPSB7fSkpO1xyXG5jb25zdCBIdHRwUmVkaXJlY3RDb2RlcyA9IFtIdHRwQ29kZXMuTW92ZWRQZXJtYW5lbnRseSwgSHR0cENvZGVzLlJlc291cmNlTW92ZWQsIEh0dHBDb2Rlcy5TZWVPdGhlciwgSHR0cENvZGVzLlRlbXBvcmFyeVJlZGlyZWN0LCBIdHRwQ29kZXMuUGVybWFuZW50UmVkaXJlY3RdO1xyXG5jb25zdCBIdHRwUmVzcG9uc2VSZXRyeUNvZGVzID0gW0h0dHBDb2Rlcy5CYWRHYXRld2F5LCBIdHRwQ29kZXMuU2VydmljZVVuYXZhaWxhYmxlLCBIdHRwQ29kZXMuR2F0ZXdheVRpbWVvdXRdO1xyXG5jb25zdCBOZXR3b3JrUmV0cnlFcnJvcnMgPSBbJ0VDT05OUkVTRVQnLCAnRU5PVEZPVU5EJywgJ0VTT0NLRVRUSU1FRE9VVCcsICdFVElNRURPVVQnLCAnRUNPTk5SRUZVU0VEJ107XHJcbmNvbnN0IFJldHJ5YWJsZUh0dHBWZXJicyA9IFsnT1BUSU9OUycsICdHRVQnLCAnREVMRVRFJywgJ0hFQUQnXTtcclxuY29uc3QgRXhwb25lbnRpYWxCYWNrb2ZmQ2VpbGluZyA9IDEwO1xyXG5jb25zdCBFeHBvbmVudGlhbEJhY2tvZmZUaW1lU2xpY2UgPSA1O1xyXG5jbGFzcyBIdHRwQ2xpZW50UmVzcG9uc2Uge1xyXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSkge1xyXG4gICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XHJcbiAgICB9XHJcbiAgICByZWFkQm9keSgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgICAgICBsZXQgYnVmZmVyID0gQnVmZmVyLmFsbG9jKDApO1xyXG4gICAgICAgICAgICBjb25zdCBlbmNvZGluZ0NoYXJzZXQgPSB1dGlsLm9idGFpbkNvbnRlbnRDaGFyc2V0KHRoaXMpO1xyXG4gICAgICAgICAgICAvLyBFeHRyYWN0IEVuY29kaW5nIGZyb20gaGVhZGVyOiAnY29udGVudC1lbmNvZGluZydcclxuICAgICAgICAgICAgLy8gTWF0Y2ggYGd6aXBgLCBgZ3ppcCwgZGVmbGF0ZWAgdmFyaWF0aW9ucyBvZiBHWklQIGVuY29kaW5nXHJcbiAgICAgICAgICAgIGNvbnN0IGNvbnRlbnRFbmNvZGluZyA9IHRoaXMubWVzc2FnZS5oZWFkZXJzWydjb250ZW50LWVuY29kaW5nJ10gfHwgJyc7XHJcbiAgICAgICAgICAgIGNvbnN0IGlzR3ppcHBlZEVuY29kZWQgPSBuZXcgUmVnRXhwKCcoZ3ppcCQpfChnemlwLCAqZGVmbGF0ZSknKS50ZXN0KGNvbnRlbnRFbmNvZGluZyk7XHJcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZS5vbignZGF0YScsIGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjaHVuayA9ICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpID8gQnVmZmVyLmZyb20oZGF0YSwgZW5jb2RpbmdDaGFyc2V0KSA6IGRhdGE7XHJcbiAgICAgICAgICAgICAgICBidWZmZXIgPSBCdWZmZXIuY29uY2F0KFtidWZmZXIsIGNodW5rXSk7XHJcbiAgICAgICAgICAgIH0pLm9uKCdlbmQnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0d6aXBwZWRFbmNvZGVkKSB7IC8vIFByb2Nlc3MgR1ppcHBlZCBSZXNwb25zZSBCb2R5IEhFUkVcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ3VuemlwcGVkQm9keSA9IHlpZWxkIHV0aWwuZGVjb21wcmVzc0d6aXBwZWRDb250ZW50KGJ1ZmZlciwgZW5jb2RpbmdDaGFyc2V0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShndW56aXBwZWRCb2R5KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoYnVmZmVyLnRvU3RyaW5nKGVuY29kaW5nQ2hhcnNldCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KS5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSkpO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMuSHR0cENsaWVudFJlc3BvbnNlID0gSHR0cENsaWVudFJlc3BvbnNlO1xyXG5mdW5jdGlvbiBpc0h0dHBzKHJlcXVlc3RVcmwpIHtcclxuICAgIGxldCBwYXJzZWRVcmwgPSB1cmwucGFyc2UocmVxdWVzdFVybCk7XHJcbiAgICByZXR1cm4gcGFyc2VkVXJsLnByb3RvY29sID09PSAnaHR0cHM6JztcclxufVxyXG5leHBvcnRzLmlzSHR0cHMgPSBpc0h0dHBzO1xyXG52YXIgRW52aXJvbm1lbnRWYXJpYWJsZXM7XHJcbihmdW5jdGlvbiAoRW52aXJvbm1lbnRWYXJpYWJsZXMpIHtcclxuICAgIEVudmlyb25tZW50VmFyaWFibGVzW1wiSFRUUF9QUk9YWVwiXSA9IFwiSFRUUF9QUk9YWVwiO1xyXG4gICAgRW52aXJvbm1lbnRWYXJpYWJsZXNbXCJIVFRQU19QUk9YWVwiXSA9IFwiSFRUUFNfUFJPWFlcIjtcclxuICAgIEVudmlyb25tZW50VmFyaWFibGVzW1wiTk9fUFJPWFlcIl0gPSBcIk5PX1BST1hZXCI7XHJcbn0pKEVudmlyb25tZW50VmFyaWFibGVzIHx8IChFbnZpcm9ubWVudFZhcmlhYmxlcyA9IHt9KSk7XHJcbmNsYXNzIEh0dHBDbGllbnQge1xyXG4gICAgY29uc3RydWN0b3IodXNlckFnZW50LCBoYW5kbGVycywgcmVxdWVzdE9wdGlvbnMpIHtcclxuICAgICAgICB0aGlzLl9pZ25vcmVTc2xFcnJvciA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuX2FsbG93UmVkaXJlY3RzID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLl9hbGxvd1JlZGlyZWN0RG93bmdyYWRlID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5fbWF4UmVkaXJlY3RzID0gNTA7XHJcbiAgICAgICAgdGhpcy5fYWxsb3dSZXRyaWVzID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5fbWF4UmV0cmllcyA9IDE7XHJcbiAgICAgICAgdGhpcy5fa2VlcEFsaXZlID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5fZGlzcG9zZWQgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLnVzZXJBZ2VudCA9IHVzZXJBZ2VudDtcclxuICAgICAgICB0aGlzLmhhbmRsZXJzID0gaGFuZGxlcnMgfHwgW107XHJcbiAgICAgICAgbGV0IG5vX3Byb3h5ID0gcHJvY2Vzcy5lbnZbRW52aXJvbm1lbnRWYXJpYWJsZXMuTk9fUFJPWFldO1xyXG4gICAgICAgIGlmIChub19wcm94eSkge1xyXG4gICAgICAgICAgICB0aGlzLl9odHRwUHJveHlCeXBhc3NIb3N0cyA9IFtdO1xyXG4gICAgICAgICAgICBub19wcm94eS5zcGxpdCgnLCcpLmZvckVhY2goYnlwYXNzID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2h0dHBQcm94eUJ5cGFzc0hvc3RzLnB1c2gobmV3IFJlZ0V4cChieXBhc3MsICdpJykpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5yZXF1ZXN0T3B0aW9ucyA9IHJlcXVlc3RPcHRpb25zO1xyXG4gICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucykge1xyXG4gICAgICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMuaWdub3JlU3NsRXJyb3IgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5faWdub3JlU3NsRXJyb3IgPSByZXF1ZXN0T3B0aW9ucy5pZ25vcmVTc2xFcnJvcjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLl9zb2NrZXRUaW1lb3V0ID0gcmVxdWVzdE9wdGlvbnMuc29ja2V0VGltZW91dDtcclxuICAgICAgICAgICAgdGhpcy5faHR0cFByb3h5ID0gcmVxdWVzdE9wdGlvbnMucHJveHk7XHJcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5wcm94eSAmJiByZXF1ZXN0T3B0aW9ucy5wcm94eS5wcm94eUJ5cGFzc0hvc3RzKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9odHRwUHJveHlCeXBhc3NIb3N0cyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgcmVxdWVzdE9wdGlvbnMucHJveHkucHJveHlCeXBhc3NIb3N0cy5mb3JFYWNoKGJ5cGFzcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5faHR0cFByb3h5QnlwYXNzSG9zdHMucHVzaChuZXcgUmVnRXhwKGJ5cGFzcywgJ2knKSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLl9jZXJ0Q29uZmlnID0gcmVxdWVzdE9wdGlvbnMuY2VydDtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2NlcnRDb25maWcpIHtcclxuICAgICAgICAgICAgICAgIC8vIElmIHVzaW5nIGNlcnQsIG5lZWQgZnNcclxuICAgICAgICAgICAgICAgIGZzID0gcmVxdWlyZSgnZnMnKTtcclxuICAgICAgICAgICAgICAgIC8vIGNhY2hlIHRoZSBjZXJ0IGNvbnRlbnQgaW50byBtZW1vcnksIHNvIHdlIGRvbid0IGhhdmUgdG8gcmVhZCBpdCBmcm9tIGRpc2sgZXZlcnkgdGltZVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2NlcnRDb25maWcuY2FGaWxlICYmIGZzLmV4aXN0c1N5bmModGhpcy5fY2VydENvbmZpZy5jYUZpbGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2EgPSBmcy5yZWFkRmlsZVN5bmModGhpcy5fY2VydENvbmZpZy5jYUZpbGUsICd1dGY4Jyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fY2VydENvbmZpZy5jZXJ0RmlsZSAmJiBmcy5leGlzdHNTeW5jKHRoaXMuX2NlcnRDb25maWcuY2VydEZpbGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2VydCA9IGZzLnJlYWRGaWxlU3luYyh0aGlzLl9jZXJ0Q29uZmlnLmNlcnRGaWxlLCAndXRmOCcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2NlcnRDb25maWcua2V5RmlsZSAmJiBmcy5leGlzdHNTeW5jKHRoaXMuX2NlcnRDb25maWcua2V5RmlsZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXkgPSBmcy5yZWFkRmlsZVN5bmModGhpcy5fY2VydENvbmZpZy5rZXlGaWxlLCAndXRmOCcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5hbGxvd1JlZGlyZWN0cyAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hbGxvd1JlZGlyZWN0cyA9IHJlcXVlc3RPcHRpb25zLmFsbG93UmVkaXJlY3RzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5hbGxvd1JlZGlyZWN0RG93bmdyYWRlICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2FsbG93UmVkaXJlY3REb3duZ3JhZGUgPSByZXF1ZXN0T3B0aW9ucy5hbGxvd1JlZGlyZWN0RG93bmdyYWRlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5tYXhSZWRpcmVjdHMgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbWF4UmVkaXJlY3RzID0gTWF0aC5tYXgocmVxdWVzdE9wdGlvbnMubWF4UmVkaXJlY3RzLCAwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMua2VlcEFsaXZlICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2tlZXBBbGl2ZSA9IHJlcXVlc3RPcHRpb25zLmtlZXBBbGl2ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMuYWxsb3dSZXRyaWVzICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2FsbG93UmV0cmllcyA9IHJlcXVlc3RPcHRpb25zLmFsbG93UmV0cmllcztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMubWF4UmV0cmllcyAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9tYXhSZXRyaWVzID0gcmVxdWVzdE9wdGlvbnMubWF4UmV0cmllcztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIG9wdGlvbnMocmVxdWVzdFVybCwgYWRkaXRpb25hbEhlYWRlcnMpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCdPUFRJT05TJywgcmVxdWVzdFVybCwgbnVsbCwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xyXG4gICAgfVxyXG4gICAgZ2V0KHJlcXVlc3RVcmwsIGFkZGl0aW9uYWxIZWFkZXJzKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnR0VUJywgcmVxdWVzdFVybCwgbnVsbCwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xyXG4gICAgfVxyXG4gICAgZGVsKHJlcXVlc3RVcmwsIGFkZGl0aW9uYWxIZWFkZXJzKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnREVMRVRFJywgcmVxdWVzdFVybCwgbnVsbCwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xyXG4gICAgfVxyXG4gICAgcG9zdChyZXF1ZXN0VXJsLCBkYXRhLCBhZGRpdGlvbmFsSGVhZGVycykge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QoJ1BPU1QnLCByZXF1ZXN0VXJsLCBkYXRhLCBhZGRpdGlvbmFsSGVhZGVycyB8fCB7fSk7XHJcbiAgICB9XHJcbiAgICBwYXRjaChyZXF1ZXN0VXJsLCBkYXRhLCBhZGRpdGlvbmFsSGVhZGVycykge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QoJ1BBVENIJywgcmVxdWVzdFVybCwgZGF0YSwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xyXG4gICAgfVxyXG4gICAgcHV0KHJlcXVlc3RVcmwsIGRhdGEsIGFkZGl0aW9uYWxIZWFkZXJzKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnUFVUJywgcmVxdWVzdFVybCwgZGF0YSwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xyXG4gICAgfVxyXG4gICAgaGVhZChyZXF1ZXN0VXJsLCBhZGRpdGlvbmFsSGVhZGVycykge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QoJ0hFQUQnLCByZXF1ZXN0VXJsLCBudWxsLCBhZGRpdGlvbmFsSGVhZGVycyB8fCB7fSk7XHJcbiAgICB9XHJcbiAgICBzZW5kU3RyZWFtKHZlcmIsIHJlcXVlc3RVcmwsIHN0cmVhbSwgYWRkaXRpb25hbEhlYWRlcnMpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KHZlcmIsIHJlcXVlc3RVcmwsIHN0cmVhbSwgYWRkaXRpb25hbEhlYWRlcnMpO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBNYWtlcyBhIHJhdyBodHRwIHJlcXVlc3QuXHJcbiAgICAgKiBBbGwgb3RoZXIgbWV0aG9kcyBzdWNoIGFzIGdldCwgcG9zdCwgcGF0Y2gsIGFuZCByZXF1ZXN0IHVsdGltYXRlbHkgY2FsbCB0aGlzLlxyXG4gICAgICogUHJlZmVyIGdldCwgZGVsLCBwb3N0IGFuZCBwYXRjaFxyXG4gICAgICovXHJcbiAgICByZXF1ZXN0KHZlcmIsIHJlcXVlc3RVcmwsIGRhdGEsIGhlYWRlcnMpIHtcclxuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fZGlzcG9zZWQpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNsaWVudCBoYXMgYWxyZWFkeSBiZWVuIGRpc3Bvc2VkLlwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBsZXQgcGFyc2VkVXJsID0gdXJsLnBhcnNlKHJlcXVlc3RVcmwpO1xyXG4gICAgICAgICAgICBsZXQgaW5mbyA9IHRoaXMuX3ByZXBhcmVSZXF1ZXN0KHZlcmIsIHBhcnNlZFVybCwgaGVhZGVycyk7XHJcbiAgICAgICAgICAgIC8vIE9ubHkgcGVyZm9ybSByZXRyaWVzIG9uIHJlYWRzIHNpbmNlIHdyaXRlcyBtYXkgbm90IGJlIGlkZW1wb3RlbnQuXHJcbiAgICAgICAgICAgIGxldCBtYXhUcmllcyA9ICh0aGlzLl9hbGxvd1JldHJpZXMgJiYgUmV0cnlhYmxlSHR0cFZlcmJzLmluZGV4T2YodmVyYikgIT0gLTEpID8gdGhpcy5fbWF4UmV0cmllcyArIDEgOiAxO1xyXG4gICAgICAgICAgICBsZXQgbnVtVHJpZXMgPSAwO1xyXG4gICAgICAgICAgICBsZXQgcmVzcG9uc2U7XHJcbiAgICAgICAgICAgIHdoaWxlIChudW1UcmllcyA8IG1heFRyaWVzKSB7XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0geWllbGQgdGhpcy5yZXF1ZXN0UmF3KGluZm8sIGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIgJiYgZXJyLmNvZGUgJiYgTmV0d29ya1JldHJ5RXJyb3JzLmluZGV4T2YoZXJyLmNvZGUpID4gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGl0J3MgYW4gYXV0aGVudGljYXRpb24gY2hhbGxlbmdlXHJcbiAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2UubWVzc2FnZSAmJiByZXNwb25zZS5tZXNzYWdlLnN0YXR1c0NvZGUgPT09IEh0dHBDb2Rlcy5VbmF1dGhvcml6ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgYXV0aGVudGljYXRpb25IYW5kbGVyO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5oYW5kbGVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5oYW5kbGVyc1tpXS5jYW5IYW5kbGVBdXRoZW50aWNhdGlvbihyZXNwb25zZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dGhlbnRpY2F0aW9uSGFuZGxlciA9IHRoaXMuaGFuZGxlcnNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXV0aGVudGljYXRpb25IYW5kbGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhdXRoZW50aWNhdGlvbkhhbmRsZXIuaGFuZGxlQXV0aGVudGljYXRpb24odGhpcywgaW5mbywgZGF0YSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBoYXZlIHJlY2VpdmVkIGFuIHVuYXV0aG9yaXplZCByZXNwb25zZSBidXQgaGF2ZSBubyBoYW5kbGVycyB0byBoYW5kbGUgaXQuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIExldCB0aGUgcmVzcG9uc2UgcmV0dXJuIHRvIHRoZSBjYWxsZXIuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBsZXQgcmVkaXJlY3RzUmVtYWluaW5nID0gdGhpcy5fbWF4UmVkaXJlY3RzO1xyXG4gICAgICAgICAgICAgICAgd2hpbGUgKEh0dHBSZWRpcmVjdENvZGVzLmluZGV4T2YocmVzcG9uc2UubWVzc2FnZS5zdGF0dXNDb2RlKSAhPSAtMVxyXG4gICAgICAgICAgICAgICAgICAgICYmIHRoaXMuX2FsbG93UmVkaXJlY3RzXHJcbiAgICAgICAgICAgICAgICAgICAgJiYgcmVkaXJlY3RzUmVtYWluaW5nID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlZGlyZWN0VXJsID0gcmVzcG9uc2UubWVzc2FnZS5oZWFkZXJzW1wibG9jYXRpb25cIl07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFyZWRpcmVjdFVybCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiB0aGVyZSdzIG5vIGxvY2F0aW9uIHRvIHJlZGlyZWN0IHRvLCB3ZSB3b24ndFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHBhcnNlZFJlZGlyZWN0VXJsID0gdXJsLnBhcnNlKHJlZGlyZWN0VXJsKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocGFyc2VkVXJsLnByb3RvY29sID09ICdodHRwczonICYmIHBhcnNlZFVybC5wcm90b2NvbCAhPSBwYXJzZWRSZWRpcmVjdFVybC5wcm90b2NvbCAmJiAhdGhpcy5fYWxsb3dSZWRpcmVjdERvd25ncmFkZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJSZWRpcmVjdCBmcm9tIEhUVFBTIHRvIEhUVFAgcHJvdG9jb2wuIFRoaXMgZG93bmdyYWRlIGlzIG5vdCBhbGxvd2VkIGZvciBzZWN1cml0eSByZWFzb25zLiBJZiB5b3Ugd2FudCB0byBhbGxvdyB0aGlzIGJlaGF2aW9yLCBzZXQgdGhlIGFsbG93UmVkaXJlY3REb3duZ3JhZGUgb3B0aW9uIHRvIHRydWUuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGZpbmlzaCByZWFkaW5nIHRoZSByZXNwb25zZSBiZWZvcmUgcmVhc3NpZ25pbmcgcmVzcG9uc2VcclxuICAgICAgICAgICAgICAgICAgICAvLyB3aGljaCB3aWxsIGxlYWsgdGhlIG9wZW4gc29ja2V0LlxyXG4gICAgICAgICAgICAgICAgICAgIHlpZWxkIHJlc3BvbnNlLnJlYWRCb2R5KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gbGV0J3MgbWFrZSB0aGUgcmVxdWVzdCB3aXRoIHRoZSBuZXcgcmVkaXJlY3RVcmxcclxuICAgICAgICAgICAgICAgICAgICBpbmZvID0gdGhpcy5fcHJlcGFyZVJlcXVlc3QodmVyYiwgcGFyc2VkUmVkaXJlY3RVcmwsIGhlYWRlcnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0geWllbGQgdGhpcy5yZXF1ZXN0UmF3KGluZm8sIGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0c1JlbWFpbmluZy0tO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKEh0dHBSZXNwb25zZVJldHJ5Q29kZXMuaW5kZXhPZihyZXNwb25zZS5tZXNzYWdlLnN0YXR1c0NvZGUpID09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgbm90IGEgcmV0cnkgY29kZSwgcmV0dXJuIGltbWVkaWF0ZWx5IGluc3RlYWQgb2YgcmV0cnlpbmdcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBudW1UcmllcyArPSAxO1xyXG4gICAgICAgICAgICAgICAgaWYgKG51bVRyaWVzIDwgbWF4VHJpZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICB5aWVsZCByZXNwb25zZS5yZWFkQm9keSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHlpZWxkIHRoaXMuX3BlcmZvcm1FeHBvbmVudGlhbEJhY2tvZmYobnVtVHJpZXMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogTmVlZHMgdG8gYmUgY2FsbGVkIGlmIGtlZXBBbGl2ZSBpcyBzZXQgdG8gdHJ1ZSBpbiByZXF1ZXN0IG9wdGlvbnMuXHJcbiAgICAgKi9cclxuICAgIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2FnZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2FnZW50LmRlc3Ryb3koKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fZGlzcG9zZWQgPSB0cnVlO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBSYXcgcmVxdWVzdC5cclxuICAgICAqIEBwYXJhbSBpbmZvXHJcbiAgICAgKiBAcGFyYW0gZGF0YVxyXG4gICAgICovXHJcbiAgICByZXF1ZXN0UmF3KGluZm8sIGRhdGEpIHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICBsZXQgY2FsbGJhY2tGb3JSZXN1bHQgPSBmdW5jdGlvbiAoZXJyLCByZXMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJlc29sdmUocmVzKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgdGhpcy5yZXF1ZXN0UmF3V2l0aENhbGxiYWNrKGluZm8sIGRhdGEsIGNhbGxiYWNrRm9yUmVzdWx0KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogUmF3IHJlcXVlc3Qgd2l0aCBjYWxsYmFjay5cclxuICAgICAqIEBwYXJhbSBpbmZvXHJcbiAgICAgKiBAcGFyYW0gZGF0YVxyXG4gICAgICogQHBhcmFtIG9uUmVzdWx0XHJcbiAgICAgKi9cclxuICAgIHJlcXVlc3RSYXdXaXRoQ2FsbGJhY2soaW5mbywgZGF0YSwgb25SZXN1bHQpIHtcclxuICAgICAgICBsZXQgc29ja2V0O1xyXG4gICAgICAgIGlmICh0eXBlb2YgKGRhdGEpID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICBpbmZvLm9wdGlvbnMuaGVhZGVyc1tcIkNvbnRlbnQtTGVuZ3RoXCJdID0gQnVmZmVyLmJ5dGVMZW5ndGgoZGF0YSwgJ3V0ZjgnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgbGV0IGNhbGxiYWNrQ2FsbGVkID0gZmFsc2U7XHJcbiAgICAgICAgbGV0IGhhbmRsZVJlc3VsdCA9IChlcnIsIHJlcykgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIWNhbGxiYWNrQ2FsbGVkKSB7XHJcbiAgICAgICAgICAgICAgICBjYWxsYmFja0NhbGxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBvblJlc3VsdChlcnIsIHJlcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIGxldCByZXEgPSBpbmZvLmh0dHBNb2R1bGUucmVxdWVzdChpbmZvLm9wdGlvbnMsIChtc2cpID0+IHtcclxuICAgICAgICAgICAgbGV0IHJlcyA9IG5ldyBIdHRwQ2xpZW50UmVzcG9uc2UobXNnKTtcclxuICAgICAgICAgICAgaGFuZGxlUmVzdWx0KG51bGwsIHJlcyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmVxLm9uKCdzb2NrZXQnLCAoc29jaykgPT4ge1xyXG4gICAgICAgICAgICBzb2NrZXQgPSBzb2NrO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIElmIHdlIGV2ZXIgZ2V0IGRpc2Nvbm5lY3RlZCwgd2Ugd2FudCB0aGUgc29ja2V0IHRvIHRpbWVvdXQgZXZlbnR1YWxseVxyXG4gICAgICAgIHJlcS5zZXRUaW1lb3V0KHRoaXMuX3NvY2tldFRpbWVvdXQgfHwgMyAqIDYwMDAwLCAoKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChzb2NrZXQpIHtcclxuICAgICAgICAgICAgICAgIHNvY2tldC5kZXN0cm95KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaGFuZGxlUmVzdWx0KG5ldyBFcnJvcignUmVxdWVzdCB0aW1lb3V0OiAnICsgaW5mby5vcHRpb25zLnBhdGgpLCBudWxsKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXEub24oJ2Vycm9yJywgZnVuY3Rpb24gKGVycikge1xyXG4gICAgICAgICAgICAvLyBlcnIgaGFzIHN0YXR1c0NvZGUgcHJvcGVydHlcclxuICAgICAgICAgICAgLy8gcmVzIHNob3VsZCBoYXZlIGhlYWRlcnNcclxuICAgICAgICAgICAgaGFuZGxlUmVzdWx0KGVyciwgbnVsbCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgaWYgKGRhdGEgJiYgdHlwZW9mIChkYXRhKSA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgcmVxLndyaXRlKGRhdGEsICd1dGY4Jyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChkYXRhICYmIHR5cGVvZiAoZGF0YSkgIT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIGRhdGEub24oJ2Nsb3NlJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmVxLmVuZCgpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgZGF0YS5waXBlKHJlcSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXEuZW5kKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgX3ByZXBhcmVSZXF1ZXN0KG1ldGhvZCwgcmVxdWVzdFVybCwgaGVhZGVycykge1xyXG4gICAgICAgIGNvbnN0IGluZm8gPSB7fTtcclxuICAgICAgICBpbmZvLnBhcnNlZFVybCA9IHJlcXVlc3RVcmw7XHJcbiAgICAgICAgY29uc3QgdXNpbmdTc2wgPSBpbmZvLnBhcnNlZFVybC5wcm90b2NvbCA9PT0gJ2h0dHBzOic7XHJcbiAgICAgICAgaW5mby5odHRwTW9kdWxlID0gdXNpbmdTc2wgPyBodHRwcyA6IGh0dHA7XHJcbiAgICAgICAgY29uc3QgZGVmYXVsdFBvcnQgPSB1c2luZ1NzbCA/IDQ0MyA6IDgwO1xyXG4gICAgICAgIGluZm8ub3B0aW9ucyA9IHt9O1xyXG4gICAgICAgIGluZm8ub3B0aW9ucy5ob3N0ID0gaW5mby5wYXJzZWRVcmwuaG9zdG5hbWU7XHJcbiAgICAgICAgaW5mby5vcHRpb25zLnBvcnQgPSBpbmZvLnBhcnNlZFVybC5wb3J0ID8gcGFyc2VJbnQoaW5mby5wYXJzZWRVcmwucG9ydCkgOiBkZWZhdWx0UG9ydDtcclxuICAgICAgICBpbmZvLm9wdGlvbnMucGF0aCA9IChpbmZvLnBhcnNlZFVybC5wYXRobmFtZSB8fCAnJykgKyAoaW5mby5wYXJzZWRVcmwuc2VhcmNoIHx8ICcnKTtcclxuICAgICAgICBpbmZvLm9wdGlvbnMubWV0aG9kID0gbWV0aG9kO1xyXG4gICAgICAgIGluZm8ub3B0aW9ucy5oZWFkZXJzID0gdGhpcy5fbWVyZ2VIZWFkZXJzKGhlYWRlcnMpO1xyXG4gICAgICAgIGlmICh0aGlzLnVzZXJBZ2VudCAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgIGluZm8ub3B0aW9ucy5oZWFkZXJzW1widXNlci1hZ2VudFwiXSA9IHRoaXMudXNlckFnZW50O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpbmZvLm9wdGlvbnMuYWdlbnQgPSB0aGlzLl9nZXRBZ2VudChpbmZvLnBhcnNlZFVybCk7XHJcbiAgICAgICAgLy8gZ2l2ZXMgaGFuZGxlcnMgYW4gb3Bwb3J0dW5pdHkgdG8gcGFydGljaXBhdGVcclxuICAgICAgICBpZiAodGhpcy5oYW5kbGVycyAmJiAhdGhpcy5faXNQcmVzaWduZWQodXJsLmZvcm1hdChyZXF1ZXN0VXJsKSkpIHtcclxuICAgICAgICAgICAgdGhpcy5oYW5kbGVycy5mb3JFYWNoKChoYW5kbGVyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBoYW5kbGVyLnByZXBhcmVSZXF1ZXN0KGluZm8ub3B0aW9ucyk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gaW5mbztcclxuICAgIH1cclxuICAgIF9pc1ByZXNpZ25lZChyZXF1ZXN0VXJsKSB7XHJcbiAgICAgICAgaWYgKHRoaXMucmVxdWVzdE9wdGlvbnMgJiYgdGhpcy5yZXF1ZXN0T3B0aW9ucy5wcmVzaWduZWRVcmxQYXR0ZXJucykge1xyXG4gICAgICAgICAgICBjb25zdCBwYXR0ZXJucyA9IHRoaXMucmVxdWVzdE9wdGlvbnMucHJlc2lnbmVkVXJsUGF0dGVybnM7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGF0dGVybnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0VXJsLm1hdGNoKHBhdHRlcm5zW2ldKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIF9tZXJnZUhlYWRlcnMoaGVhZGVycykge1xyXG4gICAgICAgIGNvbnN0IGxvd2VyY2FzZUtleXMgPSBvYmogPT4gT2JqZWN0LmtleXMob2JqKS5yZWR1Y2UoKGMsIGspID0+IChjW2sudG9Mb3dlckNhc2UoKV0gPSBvYmpba10sIGMpLCB7fSk7XHJcbiAgICAgICAgaWYgKHRoaXMucmVxdWVzdE9wdGlvbnMgJiYgdGhpcy5yZXF1ZXN0T3B0aW9ucy5oZWFkZXJzKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBsb3dlcmNhc2VLZXlzKHRoaXMucmVxdWVzdE9wdGlvbnMuaGVhZGVycyksIGxvd2VyY2FzZUtleXMoaGVhZGVycykpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbG93ZXJjYXNlS2V5cyhoZWFkZXJzIHx8IHt9KTtcclxuICAgIH1cclxuICAgIF9nZXRBZ2VudChwYXJzZWRVcmwpIHtcclxuICAgICAgICBsZXQgYWdlbnQ7XHJcbiAgICAgICAgbGV0IHByb3h5ID0gdGhpcy5fZ2V0UHJveHkocGFyc2VkVXJsKTtcclxuICAgICAgICBsZXQgdXNlUHJveHkgPSBwcm94eS5wcm94eVVybCAmJiBwcm94eS5wcm94eVVybC5ob3N0bmFtZSAmJiAhdGhpcy5faXNNYXRjaEluQnlwYXNzUHJveHlMaXN0KHBhcnNlZFVybCk7XHJcbiAgICAgICAgaWYgKHRoaXMuX2tlZXBBbGl2ZSAmJiB1c2VQcm94eSkge1xyXG4gICAgICAgICAgICBhZ2VudCA9IHRoaXMuX3Byb3h5QWdlbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLl9rZWVwQWxpdmUgJiYgIXVzZVByb3h5KSB7XHJcbiAgICAgICAgICAgIGFnZW50ID0gdGhpcy5fYWdlbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGlmIGFnZW50IGlzIGFscmVhZHkgYXNzaWduZWQgdXNlIHRoYXQgYWdlbnQuXHJcbiAgICAgICAgaWYgKCEhYWdlbnQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGFnZW50O1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCB1c2luZ1NzbCA9IHBhcnNlZFVybC5wcm90b2NvbCA9PT0gJ2h0dHBzOic7XHJcbiAgICAgICAgbGV0IG1heFNvY2tldHMgPSAxMDA7XHJcbiAgICAgICAgaWYgKCEhdGhpcy5yZXF1ZXN0T3B0aW9ucykge1xyXG4gICAgICAgICAgICBtYXhTb2NrZXRzID0gdGhpcy5yZXF1ZXN0T3B0aW9ucy5tYXhTb2NrZXRzIHx8IGh0dHAuZ2xvYmFsQWdlbnQubWF4U29ja2V0cztcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHVzZVByb3h5KSB7XHJcbiAgICAgICAgICAgIC8vIElmIHVzaW5nIHByb3h5LCBuZWVkIHR1bm5lbFxyXG4gICAgICAgICAgICBpZiAoIXR1bm5lbCkge1xyXG4gICAgICAgICAgICAgICAgdHVubmVsID0gcmVxdWlyZSgndHVubmVsJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgYWdlbnRPcHRpb25zID0ge1xyXG4gICAgICAgICAgICAgICAgbWF4U29ja2V0czogbWF4U29ja2V0cyxcclxuICAgICAgICAgICAgICAgIGtlZXBBbGl2ZTogdGhpcy5fa2VlcEFsaXZlLFxyXG4gICAgICAgICAgICAgICAgcHJveHk6IHtcclxuICAgICAgICAgICAgICAgICAgICBwcm94eUF1dGg6IHByb3h5LnByb3h5QXV0aCxcclxuICAgICAgICAgICAgICAgICAgICBob3N0OiBwcm94eS5wcm94eVVybC5ob3N0bmFtZSxcclxuICAgICAgICAgICAgICAgICAgICBwb3J0OiBwcm94eS5wcm94eVVybC5wb3J0XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBsZXQgdHVubmVsQWdlbnQ7XHJcbiAgICAgICAgICAgIGNvbnN0IG92ZXJIdHRwcyA9IHByb3h5LnByb3h5VXJsLnByb3RvY29sID09PSAnaHR0cHM6JztcclxuICAgICAgICAgICAgaWYgKHVzaW5nU3NsKSB7XHJcbiAgICAgICAgICAgICAgICB0dW5uZWxBZ2VudCA9IG92ZXJIdHRwcyA/IHR1bm5lbC5odHRwc092ZXJIdHRwcyA6IHR1bm5lbC5odHRwc092ZXJIdHRwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdHVubmVsQWdlbnQgPSBvdmVySHR0cHMgPyB0dW5uZWwuaHR0cE92ZXJIdHRwcyA6IHR1bm5lbC5odHRwT3Zlckh0dHA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYWdlbnQgPSB0dW5uZWxBZ2VudChhZ2VudE9wdGlvbnMpO1xyXG4gICAgICAgICAgICB0aGlzLl9wcm94eUFnZW50ID0gYWdlbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGlmIHJldXNpbmcgYWdlbnQgYWNyb3NzIHJlcXVlc3QgYW5kIHR1bm5lbGluZyBhZ2VudCBpc24ndCBhc3NpZ25lZCBjcmVhdGUgYSBuZXcgYWdlbnRcclxuICAgICAgICBpZiAodGhpcy5fa2VlcEFsaXZlICYmICFhZ2VudCkge1xyXG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0geyBrZWVwQWxpdmU6IHRoaXMuX2tlZXBBbGl2ZSwgbWF4U29ja2V0czogbWF4U29ja2V0cyB9O1xyXG4gICAgICAgICAgICBhZ2VudCA9IHVzaW5nU3NsID8gbmV3IGh0dHBzLkFnZW50KG9wdGlvbnMpIDogbmV3IGh0dHAuQWdlbnQob3B0aW9ucyk7XHJcbiAgICAgICAgICAgIHRoaXMuX2FnZW50ID0gYWdlbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGlmIG5vdCB1c2luZyBwcml2YXRlIGFnZW50IGFuZCB0dW5uZWwgYWdlbnQgaXNuJ3Qgc2V0dXAgdGhlbiB1c2UgZ2xvYmFsIGFnZW50XHJcbiAgICAgICAgaWYgKCFhZ2VudCkge1xyXG4gICAgICAgICAgICBhZ2VudCA9IHVzaW5nU3NsID8gaHR0cHMuZ2xvYmFsQWdlbnQgOiBodHRwLmdsb2JhbEFnZW50O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodXNpbmdTc2wgJiYgdGhpcy5faWdub3JlU3NsRXJyb3IpIHtcclxuICAgICAgICAgICAgLy8gd2UgZG9uJ3Qgd2FudCB0byBzZXQgTk9ERV9UTFNfUkVKRUNUX1VOQVVUSE9SSVpFRD0wIHNpbmNlIHRoYXQgd2lsbCBhZmZlY3QgcmVxdWVzdCBmb3IgZW50aXJlIHByb2Nlc3NcclxuICAgICAgICAgICAgLy8gaHR0cC5SZXF1ZXN0T3B0aW9ucyBkb2Vzbid0IGV4cG9zZSBhIHdheSB0byBtb2RpZnkgUmVxdWVzdE9wdGlvbnMuYWdlbnQub3B0aW9uc1xyXG4gICAgICAgICAgICAvLyB3ZSBoYXZlIHRvIGNhc3QgaXQgdG8gYW55IGFuZCBjaGFuZ2UgaXQgZGlyZWN0bHlcclxuICAgICAgICAgICAgYWdlbnQub3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oYWdlbnQub3B0aW9ucyB8fCB7fSwgeyByZWplY3RVbmF1dGhvcml6ZWQ6IGZhbHNlIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodXNpbmdTc2wgJiYgdGhpcy5fY2VydENvbmZpZykge1xyXG4gICAgICAgICAgICBhZ2VudC5vcHRpb25zID0gT2JqZWN0LmFzc2lnbihhZ2VudC5vcHRpb25zIHx8IHt9LCB7IGNhOiB0aGlzLl9jYSwgY2VydDogdGhpcy5fY2VydCwga2V5OiB0aGlzLl9rZXksIHBhc3NwaHJhc2U6IHRoaXMuX2NlcnRDb25maWcucGFzc3BocmFzZSB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGFnZW50O1xyXG4gICAgfVxyXG4gICAgX2dldFByb3h5KHBhcnNlZFVybCkge1xyXG4gICAgICAgIGxldCB1c2luZ1NzbCA9IHBhcnNlZFVybC5wcm90b2NvbCA9PT0gJ2h0dHBzOic7XHJcbiAgICAgICAgbGV0IHByb3h5Q29uZmlnID0gdGhpcy5faHR0cFByb3h5O1xyXG4gICAgICAgIC8vIGZhbGxiYWNrIHRvIGh0dHBfcHJveHkgYW5kIGh0dHBzX3Byb3h5IGVudlxyXG4gICAgICAgIGxldCBodHRwc19wcm94eSA9IHByb2Nlc3MuZW52W0Vudmlyb25tZW50VmFyaWFibGVzLkhUVFBTX1BST1hZXTtcclxuICAgICAgICBsZXQgaHR0cF9wcm94eSA9IHByb2Nlc3MuZW52W0Vudmlyb25tZW50VmFyaWFibGVzLkhUVFBfUFJPWFldO1xyXG4gICAgICAgIGlmICghcHJveHlDb25maWcpIHtcclxuICAgICAgICAgICAgaWYgKGh0dHBzX3Byb3h5ICYmIHVzaW5nU3NsKSB7XHJcbiAgICAgICAgICAgICAgICBwcm94eUNvbmZpZyA9IHtcclxuICAgICAgICAgICAgICAgICAgICBwcm94eVVybDogaHR0cHNfcHJveHlcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoaHR0cF9wcm94eSkge1xyXG4gICAgICAgICAgICAgICAgcHJveHlDb25maWcgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJveHlVcmw6IGh0dHBfcHJveHlcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgbGV0IHByb3h5VXJsO1xyXG4gICAgICAgIGxldCBwcm94eUF1dGg7XHJcbiAgICAgICAgaWYgKHByb3h5Q29uZmlnKSB7XHJcbiAgICAgICAgICAgIGlmIChwcm94eUNvbmZpZy5wcm94eVVybC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBwcm94eVVybCA9IHVybC5wYXJzZShwcm94eUNvbmZpZy5wcm94eVVybCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHByb3h5Q29uZmlnLnByb3h5VXNlcm5hbWUgfHwgcHJveHlDb25maWcucHJveHlQYXNzd29yZCkge1xyXG4gICAgICAgICAgICAgICAgcHJveHlBdXRoID0gcHJveHlDb25maWcucHJveHlVc2VybmFtZSArIFwiOlwiICsgcHJveHlDb25maWcucHJveHlQYXNzd29yZDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4geyBwcm94eVVybDogcHJveHlVcmwsIHByb3h5QXV0aDogcHJveHlBdXRoIH07XHJcbiAgICB9XHJcbiAgICBfaXNNYXRjaEluQnlwYXNzUHJveHlMaXN0KHBhcnNlZFVybCkge1xyXG4gICAgICAgIGlmICghdGhpcy5faHR0cFByb3h5QnlwYXNzSG9zdHMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgYnlwYXNzID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5faHR0cFByb3h5QnlwYXNzSG9zdHMuZm9yRWFjaChieXBhc3NIb3N0ID0+IHtcclxuICAgICAgICAgICAgaWYgKGJ5cGFzc0hvc3QudGVzdChwYXJzZWRVcmwuaHJlZikpIHtcclxuICAgICAgICAgICAgICAgIGJ5cGFzcyA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gYnlwYXNzO1xyXG4gICAgfVxyXG4gICAgX3BlcmZvcm1FeHBvbmVudGlhbEJhY2tvZmYocmV0cnlOdW1iZXIpIHtcclxuICAgICAgICByZXRyeU51bWJlciA9IE1hdGgubWluKEV4cG9uZW50aWFsQmFja29mZkNlaWxpbmcsIHJldHJ5TnVtYmVyKTtcclxuICAgICAgICBjb25zdCBtcyA9IEV4cG9uZW50aWFsQmFja29mZlRpbWVTbGljZSAqIE1hdGgucG93KDIsIHJldHJ5TnVtYmVyKTtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KCgpID0+IHJlc29sdmUoKSwgbXMpKTtcclxuICAgIH1cclxufVxyXG5leHBvcnRzLkh0dHBDbGllbnQgPSBIdHRwQ2xpZW50O1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS4gU2VlIExJQ0VOU0UgZmlsZSBpbiB0aGUgcHJvamVjdCByb290IGZvciBmdWxsIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcbnZhciBfX2F3YWl0ZXIgPSAodGhpcyAmJiB0aGlzLl9fYXdhaXRlcikgfHwgZnVuY3Rpb24gKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZShyZXN1bHQudmFsdWUpOyB9KS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn07XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxuY29uc3QgcXMgPSByZXF1aXJlKFwicXNcIik7XHJcbmNvbnN0IHVybCA9IHJlcXVpcmUoXCJ1cmxcIik7XHJcbmNvbnN0IHBhdGggPSByZXF1aXJlKFwicGF0aFwiKTtcclxuY29uc3QgemxpYiA9IHJlcXVpcmUoXCJ6bGliXCIpO1xyXG4vKipcclxuICogY3JlYXRlcyBhbiB1cmwgZnJvbSBhIHJlcXVlc3QgdXJsIGFuZCBvcHRpb25hbCBiYXNlIHVybCAoaHR0cDovL3NlcnZlcjo4MDgwKVxyXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVzb3VyY2UgLSBhIGZ1bGx5IHF1YWxpZmllZCB1cmwgb3IgcmVsYXRpdmUgcGF0aFxyXG4gKiBAcGFyYW0ge3N0cmluZ30gYmFzZVVybCAtIGFuIG9wdGlvbmFsIGJhc2VVcmwgKGh0dHA6Ly9zZXJ2ZXI6ODA4MClcclxuICogQHBhcmFtIHtJUmVxdWVzdE9wdGlvbnN9IG9wdGlvbnMgLSBhbiBvcHRpb25hbCBvcHRpb25zIG9iamVjdCwgY291bGQgaW5jbHVkZSBRdWVyeVBhcmFtZXRlcnMgZS5nLlxyXG4gKiBAcmV0dXJuIHtzdHJpbmd9IC0gcmVzdWx0YW50IHVybFxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0VXJsKHJlc291cmNlLCBiYXNlVXJsLCBxdWVyeVBhcmFtcykge1xyXG4gICAgY29uc3QgcGF0aEFwaSA9IHBhdGgucG9zaXggfHwgcGF0aDtcclxuICAgIGxldCByZXF1ZXN0VXJsID0gJyc7XHJcbiAgICBpZiAoIWJhc2VVcmwpIHtcclxuICAgICAgICByZXF1ZXN0VXJsID0gcmVzb3VyY2U7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmICghcmVzb3VyY2UpIHtcclxuICAgICAgICByZXF1ZXN0VXJsID0gYmFzZVVybDtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGNvbnN0IGJhc2UgPSB1cmwucGFyc2UoYmFzZVVybCk7XHJcbiAgICAgICAgY29uc3QgcmVzdWx0YW50VXJsID0gdXJsLnBhcnNlKHJlc291cmNlKTtcclxuICAgICAgICAvLyByZXNvdXJjZSAoc3BlY2lmaWMgcGVyIHJlcXVlc3QpIGVsZW1lbnRzIHRha2UgcHJpb3JpdHlcclxuICAgICAgICByZXN1bHRhbnRVcmwucHJvdG9jb2wgPSByZXN1bHRhbnRVcmwucHJvdG9jb2wgfHwgYmFzZS5wcm90b2NvbDtcclxuICAgICAgICByZXN1bHRhbnRVcmwuYXV0aCA9IHJlc3VsdGFudFVybC5hdXRoIHx8IGJhc2UuYXV0aDtcclxuICAgICAgICByZXN1bHRhbnRVcmwuaG9zdCA9IHJlc3VsdGFudFVybC5ob3N0IHx8IGJhc2UuaG9zdDtcclxuICAgICAgICByZXN1bHRhbnRVcmwucGF0aG5hbWUgPSBwYXRoQXBpLnJlc29sdmUoYmFzZS5wYXRobmFtZSwgcmVzdWx0YW50VXJsLnBhdGhuYW1lKTtcclxuICAgICAgICBpZiAoIXJlc3VsdGFudFVybC5wYXRobmFtZS5lbmRzV2l0aCgnLycpICYmIHJlc291cmNlLmVuZHNXaXRoKCcvJykpIHtcclxuICAgICAgICAgICAgcmVzdWx0YW50VXJsLnBhdGhuYW1lICs9ICcvJztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmVxdWVzdFVybCA9IHVybC5mb3JtYXQocmVzdWx0YW50VXJsKTtcclxuICAgIH1cclxuICAgIHJldHVybiBxdWVyeVBhcmFtcyA/XHJcbiAgICAgICAgZ2V0VXJsV2l0aFBhcnNlZFF1ZXJ5UGFyYW1zKHJlcXVlc3RVcmwsIHF1ZXJ5UGFyYW1zKSA6XHJcbiAgICAgICAgcmVxdWVzdFVybDtcclxufVxyXG5leHBvcnRzLmdldFVybCA9IGdldFVybDtcclxuLyoqXHJcbiAqXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSByZXF1ZXN0VXJsXHJcbiAqIEBwYXJhbSB7SVJlcXVlc3RRdWVyeVBhcmFtc30gcXVlcnlQYXJhbXNcclxuICogQHJldHVybiB7c3RyaW5nfSAtIFJlcXVlc3QncyBVUkwgd2l0aCBRdWVyeSBQYXJhbWV0ZXJzIGFwcGVuZGVkL3BhcnNlZC5cclxuICovXHJcbmZ1bmN0aW9uIGdldFVybFdpdGhQYXJzZWRRdWVyeVBhcmFtcyhyZXF1ZXN0VXJsLCBxdWVyeVBhcmFtcykge1xyXG4gICAgY29uc3QgdXJsID0gcmVxdWVzdFVybC5yZXBsYWNlKC9cXD8kL2csICcnKTsgLy8gQ2xlYW4gYW55IGV4dHJhIGVuZC1vZi1zdHJpbmcgXCI/XCIgY2hhcmFjdGVyXHJcbiAgICBjb25zdCBwYXJzZWRRdWVyeVBhcmFtcyA9IHFzLnN0cmluZ2lmeShxdWVyeVBhcmFtcy5wYXJhbXMsIGJ1aWxkUGFyYW1zU3RyaW5naWZ5T3B0aW9ucyhxdWVyeVBhcmFtcykpO1xyXG4gICAgcmV0dXJuIGAke3VybH0ke3BhcnNlZFF1ZXJ5UGFyYW1zfWA7XHJcbn1cclxuLyoqXHJcbiAqIEJ1aWxkIG9wdGlvbnMgZm9yIFF1ZXJ5UGFyYW1zIFN0cmluZ2lmeWluZy5cclxuICpcclxuICogQHBhcmFtIHtJUmVxdWVzdFF1ZXJ5UGFyYW1zfSBxdWVyeVBhcmFtc1xyXG4gKiBAcmV0dXJuIHtvYmplY3R9XHJcbiAqL1xyXG5mdW5jdGlvbiBidWlsZFBhcmFtc1N0cmluZ2lmeU9wdGlvbnMocXVlcnlQYXJhbXMpIHtcclxuICAgIGxldCBvcHRpb25zID0ge1xyXG4gICAgICAgIGFkZFF1ZXJ5UHJlZml4OiB0cnVlLFxyXG4gICAgICAgIGRlbGltaXRlcjogKHF1ZXJ5UGFyYW1zLm9wdGlvbnMgfHwge30pLnNlcGFyYXRvciB8fCAnJicsXHJcbiAgICAgICAgYWxsb3dEb3RzOiAocXVlcnlQYXJhbXMub3B0aW9ucyB8fCB7fSkuc2hvdWxkQWxsb3dEb3RzIHx8IGZhbHNlLFxyXG4gICAgICAgIGFycmF5Rm9ybWF0OiAocXVlcnlQYXJhbXMub3B0aW9ucyB8fCB7fSkuYXJyYXlGb3JtYXQgfHwgJ3JlcGVhdCcsXHJcbiAgICAgICAgZW5jb2RlVmFsdWVzT25seTogKHF1ZXJ5UGFyYW1zLm9wdGlvbnMgfHwge30pLnNob3VsZE9ubHlFbmNvZGVWYWx1ZXMgfHwgdHJ1ZVxyXG4gICAgfTtcclxuICAgIHJldHVybiBvcHRpb25zO1xyXG59XHJcbi8qKlxyXG4gKiBEZWNvbXByZXNzL0RlY29kZSBnemlwIGVuY29kZWQgSlNPTlxyXG4gKiBVc2luZyBOb2RlLmpzIGJ1aWx0LWluIHpsaWIgbW9kdWxlXHJcbiAqXHJcbiAqIEBwYXJhbSB7QnVmZmVyfSBidWZmZXJcclxuICogQHBhcmFtIHtzdHJpbmd9IGNoYXJzZXQ/IC0gb3B0aW9uYWw7IGRlZmF1bHRzIHRvICd1dGYtOCdcclxuICogQHJldHVybiB7UHJvbWlzZTxzdHJpbmc+fVxyXG4gKi9cclxuZnVuY3Rpb24gZGVjb21wcmVzc0d6aXBwZWRDb250ZW50KGJ1ZmZlciwgY2hhcnNldCkge1xyXG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgICAgICB6bGliLmd1bnppcChidWZmZXIsIGZ1bmN0aW9uIChlcnJvciwgYnVmZmVyKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShidWZmZXIudG9TdHJpbmcoY2hhcnNldCB8fCAndXRmLTgnKSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pKTtcclxuICAgIH0pO1xyXG59XHJcbmV4cG9ydHMuZGVjb21wcmVzc0d6aXBwZWRDb250ZW50ID0gZGVjb21wcmVzc0d6aXBwZWRDb250ZW50O1xyXG4vKipcclxuICogT2J0YWluIFJlc3BvbnNlJ3MgQ29udGVudCBDaGFyc2V0LlxyXG4gKiBUaHJvdWdoIGluc3BlY3RpbmcgYGNvbnRlbnQtdHlwZWAgcmVzcG9uc2UgaGVhZGVyLlxyXG4gKiBJdCBSZXR1cm5zICd1dGYtOCcgaWYgTk8gY2hhcnNldCBzcGVjaWZpZWQvbWF0Y2hlZC5cclxuICpcclxuICogQHBhcmFtIHtJSHR0cENsaWVudFJlc3BvbnNlfSByZXNwb25zZVxyXG4gKiBAcmV0dXJuIHtzdHJpbmd9IC0gQ29udGVudCBFbmNvZGluZyBDaGFyc2V0OyBEZWZhdWx0PXV0Zi04XHJcbiAqL1xyXG5mdW5jdGlvbiBvYnRhaW5Db250ZW50Q2hhcnNldChyZXNwb25zZSkge1xyXG4gICAgLy8gRmluZCB0aGUgY2hhcnNldCwgaWYgc3BlY2lmaWVkLlxyXG4gICAgLy8gU2VhcmNoIGZvciB0aGUgYGNoYXJzZXQ9Q0hBUlNFVGAgc3RyaW5nLCBub3QgaW5jbHVkaW5nIGA7LFxcclxcbmBcclxuICAgIC8vIEV4YW1wbGU6IGNvbnRlbnQtdHlwZTogJ2FwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtOCdcclxuICAgIC8vIHxfXyBtYXRjaGVzIHdvdWxkIGJlIFsnY2hhcnNldD11dGYtOCcsICd1dGYtOCcsIGluZGV4OiAxOCwgaW5wdXQ6ICdhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04J11cclxuICAgIC8vIHxfX19fXyBtYXRjaGVzWzFdIHdvdWxkIGhhdmUgdGhlIGNoYXJzZXQgOnRhZGE6ICwgaW4gb3VyIGV4YW1wbGUgaXQncyB1dGYtOFxyXG4gICAgLy8gSG93ZXZlciwgaWYgdGhlIG1hdGNoZXMgQXJyYXkgd2FzIGVtcHR5IG9yIG5vIGNoYXJzZXQgZm91bmQsICd1dGYtOCcgd291bGQgYmUgcmV0dXJuZWQgYnkgZGVmYXVsdC5cclxuICAgIGNvbnN0IG5vZGVTdXBwb3J0ZWRFbmNvZGluZ3MgPSBbJ2FzY2lpJywgJ3V0ZjgnLCAndXRmMTZsZScsICd1Y3MyJywgJ2Jhc2U2NCcsICdiaW5hcnknLCAnaGV4J107XHJcbiAgICBjb25zdCBjb250ZW50VHlwZSA9IHJlc3BvbnNlLm1lc3NhZ2UuaGVhZGVyc1snY29udGVudC10eXBlJ10gfHwgJyc7XHJcbiAgICBjb25zdCBtYXRjaGVzID0gY29udGVudFR5cGUubWF0Y2goL2NoYXJzZXQ9KFteOyxcXHJcXG5dKykvaSk7XHJcbiAgICByZXR1cm4gKG1hdGNoZXMgJiYgbWF0Y2hlc1sxXSAmJiBub2RlU3VwcG9ydGVkRW5jb2RpbmdzLmluZGV4T2YobWF0Y2hlc1sxXSkgIT0gLTEpID8gbWF0Y2hlc1sxXSA6ICd1dGYtOCc7XHJcbn1cclxuZXhwb3J0cy5vYnRhaW5Db250ZW50Q2hhcnNldCA9IG9idGFpbkNvbnRlbnRDaGFyc2V0O1xyXG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL3R1bm5lbCcpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgbmV0ID0gcmVxdWlyZSgnbmV0Jyk7XG52YXIgdGxzID0gcmVxdWlyZSgndGxzJyk7XG52YXIgaHR0cCA9IHJlcXVpcmUoJ2h0dHAnKTtcbnZhciBodHRwcyA9IHJlcXVpcmUoJ2h0dHBzJyk7XG52YXIgZXZlbnRzID0gcmVxdWlyZSgnZXZlbnRzJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcblxuXG5leHBvcnRzLmh0dHBPdmVySHR0cCA9IGh0dHBPdmVySHR0cDtcbmV4cG9ydHMuaHR0cHNPdmVySHR0cCA9IGh0dHBzT3Zlckh0dHA7XG5leHBvcnRzLmh0dHBPdmVySHR0cHMgPSBodHRwT3Zlckh0dHBzO1xuZXhwb3J0cy5odHRwc092ZXJIdHRwcyA9IGh0dHBzT3Zlckh0dHBzO1xuXG5cbmZ1bmN0aW9uIGh0dHBPdmVySHR0cChvcHRpb25zKSB7XG4gIHZhciBhZ2VudCA9IG5ldyBUdW5uZWxpbmdBZ2VudChvcHRpb25zKTtcbiAgYWdlbnQucmVxdWVzdCA9IGh0dHAucmVxdWVzdDtcbiAgcmV0dXJuIGFnZW50O1xufVxuXG5mdW5jdGlvbiBodHRwc092ZXJIdHRwKG9wdGlvbnMpIHtcbiAgdmFyIGFnZW50ID0gbmV3IFR1bm5lbGluZ0FnZW50KG9wdGlvbnMpO1xuICBhZ2VudC5yZXF1ZXN0ID0gaHR0cC5yZXF1ZXN0O1xuICBhZ2VudC5jcmVhdGVTb2NrZXQgPSBjcmVhdGVTZWN1cmVTb2NrZXQ7XG4gIGFnZW50LmRlZmF1bHRQb3J0ID0gNDQzO1xuICByZXR1cm4gYWdlbnQ7XG59XG5cbmZ1bmN0aW9uIGh0dHBPdmVySHR0cHMob3B0aW9ucykge1xuICB2YXIgYWdlbnQgPSBuZXcgVHVubmVsaW5nQWdlbnQob3B0aW9ucyk7XG4gIGFnZW50LnJlcXVlc3QgPSBodHRwcy5yZXF1ZXN0O1xuICByZXR1cm4gYWdlbnQ7XG59XG5cbmZ1bmN0aW9uIGh0dHBzT3Zlckh0dHBzKG9wdGlvbnMpIHtcbiAgdmFyIGFnZW50ID0gbmV3IFR1bm5lbGluZ0FnZW50KG9wdGlvbnMpO1xuICBhZ2VudC5yZXF1ZXN0ID0gaHR0cHMucmVxdWVzdDtcbiAgYWdlbnQuY3JlYXRlU29ja2V0ID0gY3JlYXRlU2VjdXJlU29ja2V0O1xuICBhZ2VudC5kZWZhdWx0UG9ydCA9IDQ0MztcbiAgcmV0dXJuIGFnZW50O1xufVxuXG5cbmZ1bmN0aW9uIFR1bm5lbGluZ0FnZW50KG9wdGlvbnMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBzZWxmLm9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBzZWxmLnByb3h5T3B0aW9ucyA9IHNlbGYub3B0aW9ucy5wcm94eSB8fCB7fTtcbiAgc2VsZi5tYXhTb2NrZXRzID0gc2VsZi5vcHRpb25zLm1heFNvY2tldHMgfHwgaHR0cC5BZ2VudC5kZWZhdWx0TWF4U29ja2V0cztcbiAgc2VsZi5yZXF1ZXN0cyA9IFtdO1xuICBzZWxmLnNvY2tldHMgPSBbXTtcblxuICBzZWxmLm9uKCdmcmVlJywgZnVuY3Rpb24gb25GcmVlKHNvY2tldCwgaG9zdCwgcG9ydCwgbG9jYWxBZGRyZXNzKSB7XG4gICAgdmFyIG9wdGlvbnMgPSB0b09wdGlvbnMoaG9zdCwgcG9ydCwgbG9jYWxBZGRyZXNzKTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gc2VsZi5yZXF1ZXN0cy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgdmFyIHBlbmRpbmcgPSBzZWxmLnJlcXVlc3RzW2ldO1xuICAgICAgaWYgKHBlbmRpbmcuaG9zdCA9PT0gb3B0aW9ucy5ob3N0ICYmIHBlbmRpbmcucG9ydCA9PT0gb3B0aW9ucy5wb3J0KSB7XG4gICAgICAgIC8vIERldGVjdCB0aGUgcmVxdWVzdCB0byBjb25uZWN0IHNhbWUgb3JpZ2luIHNlcnZlcixcbiAgICAgICAgLy8gcmV1c2UgdGhlIGNvbm5lY3Rpb24uXG4gICAgICAgIHNlbGYucmVxdWVzdHMuc3BsaWNlKGksIDEpO1xuICAgICAgICBwZW5kaW5nLnJlcXVlc3Qub25Tb2NrZXQoc29ja2V0KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICBzb2NrZXQuZGVzdHJveSgpO1xuICAgIHNlbGYucmVtb3ZlU29ja2V0KHNvY2tldCk7XG4gIH0pO1xufVxudXRpbC5pbmhlcml0cyhUdW5uZWxpbmdBZ2VudCwgZXZlbnRzLkV2ZW50RW1pdHRlcik7XG5cblR1bm5lbGluZ0FnZW50LnByb3RvdHlwZS5hZGRSZXF1ZXN0ID0gZnVuY3Rpb24gYWRkUmVxdWVzdChyZXEsIGhvc3QsIHBvcnQsIGxvY2FsQWRkcmVzcykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBvcHRpb25zID0gbWVyZ2VPcHRpb25zKHtyZXF1ZXN0OiByZXF9LCBzZWxmLm9wdGlvbnMsIHRvT3B0aW9ucyhob3N0LCBwb3J0LCBsb2NhbEFkZHJlc3MpKTtcblxuICBpZiAoc2VsZi5zb2NrZXRzLmxlbmd0aCA+PSB0aGlzLm1heFNvY2tldHMpIHtcbiAgICAvLyBXZSBhcmUgb3ZlciBsaW1pdCBzbyB3ZSdsbCBhZGQgaXQgdG8gdGhlIHF1ZXVlLlxuICAgIHNlbGYucmVxdWVzdHMucHVzaChvcHRpb25zKTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBJZiB3ZSBhcmUgdW5kZXIgbWF4U29ja2V0cyBjcmVhdGUgYSBuZXcgb25lLlxuICBzZWxmLmNyZWF0ZVNvY2tldChvcHRpb25zLCBmdW5jdGlvbihzb2NrZXQpIHtcbiAgICBzb2NrZXQub24oJ2ZyZWUnLCBvbkZyZWUpO1xuICAgIHNvY2tldC5vbignY2xvc2UnLCBvbkNsb3NlT3JSZW1vdmUpO1xuICAgIHNvY2tldC5vbignYWdlbnRSZW1vdmUnLCBvbkNsb3NlT3JSZW1vdmUpO1xuICAgIHJlcS5vblNvY2tldChzb2NrZXQpO1xuXG4gICAgZnVuY3Rpb24gb25GcmVlKCkge1xuICAgICAgc2VsZi5lbWl0KCdmcmVlJywgc29ja2V0LCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBvbkNsb3NlT3JSZW1vdmUoZXJyKSB7XG4gICAgICBzZWxmLnJlbW92ZVNvY2tldChzb2NrZXQpO1xuICAgICAgc29ja2V0LnJlbW92ZUxpc3RlbmVyKCdmcmVlJywgb25GcmVlKTtcbiAgICAgIHNvY2tldC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbkNsb3NlT3JSZW1vdmUpO1xuICAgICAgc29ja2V0LnJlbW92ZUxpc3RlbmVyKCdhZ2VudFJlbW92ZScsIG9uQ2xvc2VPclJlbW92ZSk7XG4gICAgfVxuICB9KTtcbn07XG5cblR1bm5lbGluZ0FnZW50LnByb3RvdHlwZS5jcmVhdGVTb2NrZXQgPSBmdW5jdGlvbiBjcmVhdGVTb2NrZXQob3B0aW9ucywgY2IpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgcGxhY2Vob2xkZXIgPSB7fTtcbiAgc2VsZi5zb2NrZXRzLnB1c2gocGxhY2Vob2xkZXIpO1xuXG4gIHZhciBjb25uZWN0T3B0aW9ucyA9IG1lcmdlT3B0aW9ucyh7fSwgc2VsZi5wcm94eU9wdGlvbnMsIHtcbiAgICBtZXRob2Q6ICdDT05ORUNUJyxcbiAgICBwYXRoOiBvcHRpb25zLmhvc3QgKyAnOicgKyBvcHRpb25zLnBvcnQsXG4gICAgYWdlbnQ6IGZhbHNlLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIGhvc3Q6IG9wdGlvbnMuaG9zdCArICc6JyArIG9wdGlvbnMucG9ydFxuICAgIH1cbiAgfSk7XG4gIGlmIChvcHRpb25zLmxvY2FsQWRkcmVzcykge1xuICAgIGNvbm5lY3RPcHRpb25zLmxvY2FsQWRkcmVzcyA9IG9wdGlvbnMubG9jYWxBZGRyZXNzO1xuICB9XG4gIGlmIChjb25uZWN0T3B0aW9ucy5wcm94eUF1dGgpIHtcbiAgICBjb25uZWN0T3B0aW9ucy5oZWFkZXJzID0gY29ubmVjdE9wdGlvbnMuaGVhZGVycyB8fCB7fTtcbiAgICBjb25uZWN0T3B0aW9ucy5oZWFkZXJzWydQcm94eS1BdXRob3JpemF0aW9uJ10gPSAnQmFzaWMgJyArXG4gICAgICAgIG5ldyBCdWZmZXIoY29ubmVjdE9wdGlvbnMucHJveHlBdXRoKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gIH1cblxuICBkZWJ1ZygnbWFraW5nIENPTk5FQ1QgcmVxdWVzdCcpO1xuICB2YXIgY29ubmVjdFJlcSA9IHNlbGYucmVxdWVzdChjb25uZWN0T3B0aW9ucyk7XG4gIGNvbm5lY3RSZXEudXNlQ2h1bmtlZEVuY29kaW5nQnlEZWZhdWx0ID0gZmFsc2U7IC8vIGZvciB2MC42XG4gIGNvbm5lY3RSZXEub25jZSgncmVzcG9uc2UnLCBvblJlc3BvbnNlKTsgLy8gZm9yIHYwLjZcbiAgY29ubmVjdFJlcS5vbmNlKCd1cGdyYWRlJywgb25VcGdyYWRlKTsgICAvLyBmb3IgdjAuNlxuICBjb25uZWN0UmVxLm9uY2UoJ2Nvbm5lY3QnLCBvbkNvbm5lY3QpOyAgIC8vIGZvciB2MC43IG9yIGxhdGVyXG4gIGNvbm5lY3RSZXEub25jZSgnZXJyb3InLCBvbkVycm9yKTtcbiAgY29ubmVjdFJlcS5lbmQoKTtcblxuICBmdW5jdGlvbiBvblJlc3BvbnNlKHJlcykge1xuICAgIC8vIFZlcnkgaGFja3kuIFRoaXMgaXMgbmVjZXNzYXJ5IHRvIGF2b2lkIGh0dHAtcGFyc2VyIGxlYWtzLlxuICAgIHJlcy51cGdyYWRlID0gdHJ1ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uVXBncmFkZShyZXMsIHNvY2tldCwgaGVhZCkge1xuICAgIC8vIEhhY2t5LlxuICAgIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24oKSB7XG4gICAgICBvbkNvbm5lY3QocmVzLCBzb2NrZXQsIGhlYWQpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gb25Db25uZWN0KHJlcywgc29ja2V0LCBoZWFkKSB7XG4gICAgY29ubmVjdFJlcS5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcbiAgICBzb2NrZXQucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG5cbiAgICBpZiAocmVzLnN0YXR1c0NvZGUgIT09IDIwMCkge1xuICAgICAgZGVidWcoJ3R1bm5lbGluZyBzb2NrZXQgY291bGQgbm90IGJlIGVzdGFibGlzaGVkLCBzdGF0dXNDb2RlPSVkJyxcbiAgICAgICAgcmVzLnN0YXR1c0NvZGUpO1xuICAgICAgc29ja2V0LmRlc3Ryb3koKTtcbiAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcigndHVubmVsaW5nIHNvY2tldCBjb3VsZCBub3QgYmUgZXN0YWJsaXNoZWQsICcgK1xuICAgICAgICAnc3RhdHVzQ29kZT0nICsgcmVzLnN0YXR1c0NvZGUpO1xuICAgICAgZXJyb3IuY29kZSA9ICdFQ09OTlJFU0VUJztcbiAgICAgIG9wdGlvbnMucmVxdWVzdC5lbWl0KCdlcnJvcicsIGVycm9yKTtcbiAgICAgIHNlbGYucmVtb3ZlU29ja2V0KHBsYWNlaG9sZGVyKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGhlYWQubGVuZ3RoID4gMCkge1xuICAgICAgZGVidWcoJ2dvdCBpbGxlZ2FsIHJlc3BvbnNlIGJvZHkgZnJvbSBwcm94eScpO1xuICAgICAgc29ja2V0LmRlc3Ryb3koKTtcbiAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignZ290IGlsbGVnYWwgcmVzcG9uc2UgYm9keSBmcm9tIHByb3h5Jyk7XG4gICAgICBlcnJvci5jb2RlID0gJ0VDT05OUkVTRVQnO1xuICAgICAgb3B0aW9ucy5yZXF1ZXN0LmVtaXQoJ2Vycm9yJywgZXJyb3IpO1xuICAgICAgc2VsZi5yZW1vdmVTb2NrZXQocGxhY2Vob2xkZXIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkZWJ1ZygndHVubmVsaW5nIGNvbm5lY3Rpb24gaGFzIGVzdGFibGlzaGVkJyk7XG4gICAgc2VsZi5zb2NrZXRzW3NlbGYuc29ja2V0cy5pbmRleE9mKHBsYWNlaG9sZGVyKV0gPSBzb2NrZXQ7XG4gICAgcmV0dXJuIGNiKHNvY2tldCk7XG4gIH1cblxuICBmdW5jdGlvbiBvbkVycm9yKGNhdXNlKSB7XG4gICAgY29ubmVjdFJlcS5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcblxuICAgIGRlYnVnKCd0dW5uZWxpbmcgc29ja2V0IGNvdWxkIG5vdCBiZSBlc3RhYmxpc2hlZCwgY2F1c2U9JXNcXG4nLFxuICAgICAgICAgIGNhdXNlLm1lc3NhZ2UsIGNhdXNlLnN0YWNrKTtcbiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ3R1bm5lbGluZyBzb2NrZXQgY291bGQgbm90IGJlIGVzdGFibGlzaGVkLCAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NhdXNlPScgKyBjYXVzZS5tZXNzYWdlKTtcbiAgICBlcnJvci5jb2RlID0gJ0VDT05OUkVTRVQnO1xuICAgIG9wdGlvbnMucmVxdWVzdC5lbWl0KCdlcnJvcicsIGVycm9yKTtcbiAgICBzZWxmLnJlbW92ZVNvY2tldChwbGFjZWhvbGRlcik7XG4gIH1cbn07XG5cblR1bm5lbGluZ0FnZW50LnByb3RvdHlwZS5yZW1vdmVTb2NrZXQgPSBmdW5jdGlvbiByZW1vdmVTb2NrZXQoc29ja2V0KSB7XG4gIHZhciBwb3MgPSB0aGlzLnNvY2tldHMuaW5kZXhPZihzb2NrZXQpXG4gIGlmIChwb3MgPT09IC0xKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHRoaXMuc29ja2V0cy5zcGxpY2UocG9zLCAxKTtcblxuICB2YXIgcGVuZGluZyA9IHRoaXMucmVxdWVzdHMuc2hpZnQoKTtcbiAgaWYgKHBlbmRpbmcpIHtcbiAgICAvLyBJZiB3ZSBoYXZlIHBlbmRpbmcgcmVxdWVzdHMgYW5kIGEgc29ja2V0IGdldHMgY2xvc2VkIGEgbmV3IG9uZVxuICAgIC8vIG5lZWRzIHRvIGJlIGNyZWF0ZWQgdG8gdGFrZSBvdmVyIGluIHRoZSBwb29sIGZvciB0aGUgb25lIHRoYXQgY2xvc2VkLlxuICAgIHRoaXMuY3JlYXRlU29ja2V0KHBlbmRpbmcsIGZ1bmN0aW9uKHNvY2tldCkge1xuICAgICAgcGVuZGluZy5yZXF1ZXN0Lm9uU29ja2V0KHNvY2tldCk7XG4gICAgfSk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGNyZWF0ZVNlY3VyZVNvY2tldChvcHRpb25zLCBjYikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIFR1bm5lbGluZ0FnZW50LnByb3RvdHlwZS5jcmVhdGVTb2NrZXQuY2FsbChzZWxmLCBvcHRpb25zLCBmdW5jdGlvbihzb2NrZXQpIHtcbiAgICB2YXIgaG9zdEhlYWRlciA9IG9wdGlvbnMucmVxdWVzdC5nZXRIZWFkZXIoJ2hvc3QnKTtcbiAgICB2YXIgdGxzT3B0aW9ucyA9IG1lcmdlT3B0aW9ucyh7fSwgc2VsZi5vcHRpb25zLCB7XG4gICAgICBzb2NrZXQ6IHNvY2tldCxcbiAgICAgIHNlcnZlcm5hbWU6IGhvc3RIZWFkZXIgPyBob3N0SGVhZGVyLnJlcGxhY2UoLzouKiQvLCAnJykgOiBvcHRpb25zLmhvc3RcbiAgICB9KTtcblxuICAgIC8vIDAgaXMgZHVtbXkgcG9ydCBmb3IgdjAuNlxuICAgIHZhciBzZWN1cmVTb2NrZXQgPSB0bHMuY29ubmVjdCgwLCB0bHNPcHRpb25zKTtcbiAgICBzZWxmLnNvY2tldHNbc2VsZi5zb2NrZXRzLmluZGV4T2Yoc29ja2V0KV0gPSBzZWN1cmVTb2NrZXQ7XG4gICAgY2Ioc2VjdXJlU29ja2V0KTtcbiAgfSk7XG59XG5cblxuZnVuY3Rpb24gdG9PcHRpb25zKGhvc3QsIHBvcnQsIGxvY2FsQWRkcmVzcykge1xuICBpZiAodHlwZW9mIGhvc3QgPT09ICdzdHJpbmcnKSB7IC8vIHNpbmNlIHYwLjEwXG4gICAgcmV0dXJuIHtcbiAgICAgIGhvc3Q6IGhvc3QsXG4gICAgICBwb3J0OiBwb3J0LFxuICAgICAgbG9jYWxBZGRyZXNzOiBsb2NhbEFkZHJlc3NcbiAgICB9O1xuICB9XG4gIHJldHVybiBob3N0OyAvLyBmb3IgdjAuMTEgb3IgbGF0ZXJcbn1cblxuZnVuY3Rpb24gbWVyZ2VPcHRpb25zKHRhcmdldCkge1xuICBmb3IgKHZhciBpID0gMSwgbGVuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgdmFyIG92ZXJyaWRlcyA9IGFyZ3VtZW50c1tpXTtcbiAgICBpZiAodHlwZW9mIG92ZXJyaWRlcyA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMob3ZlcnJpZGVzKTtcbiAgICAgIGZvciAodmFyIGogPSAwLCBrZXlMZW4gPSBrZXlzLmxlbmd0aDsgaiA8IGtleUxlbjsgKytqKSB7XG4gICAgICAgIHZhciBrID0ga2V5c1tqXTtcbiAgICAgICAgaWYgKG92ZXJyaWRlc1trXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGFyZ2V0W2tdID0gb3ZlcnJpZGVzW2tdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiB0YXJnZXQ7XG59XG5cblxudmFyIGRlYnVnO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfREVCVUcgJiYgL1xcYnR1bm5lbFxcYi8udGVzdChwcm9jZXNzLmVudi5OT0RFX0RFQlVHKSkge1xuICBkZWJ1ZyA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICBpZiAodHlwZW9mIGFyZ3NbMF0gPT09ICdzdHJpbmcnKSB7XG4gICAgICBhcmdzWzBdID0gJ1RVTk5FTDogJyArIGFyZ3NbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGFyZ3MudW5zaGlmdCgnVFVOTkVMOicpO1xuICAgIH1cbiAgICBjb25zb2xlLmVycm9yLmFwcGx5KGNvbnNvbGUsIGFyZ3MpO1xuICB9XG59IGVsc2Uge1xuICBkZWJ1ZyA9IGZ1bmN0aW9uKCkge307XG59XG5leHBvcnRzLmRlYnVnID0gZGVidWc7IC8vIGZvciB0ZXN0XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJhc3NlcnRcIik7OyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImNoaWxkX3Byb2Nlc3NcIik7OyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImNyeXB0b1wiKTs7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiZXZlbnRzXCIpOzsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJmc1wiKTs7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiaHR0cFwiKTs7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiaHR0cHNcIik7OyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIm5ldFwiKTs7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwib3NcIik7OyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInBhdGhcIik7OyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInByb2Nlc3NcIik7OyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInRsc1wiKTs7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwidXJsXCIpOzsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ1dGlsXCIpOzsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ6bGliXCIpOzsiLCIvLyBUaGUgbW9kdWxlIGNhY2hlXG52YXIgX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fID0ge307XG5cbi8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG5mdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuXHRpZihfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdKSB7XG5cdFx0cmV0dXJuIF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0uZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHQvLyBubyBtb2R1bGUuaWQgbmVlZGVkXG5cdFx0Ly8gbm8gbW9kdWxlLmxvYWRlZCBuZWVkZWRcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbiIsIl9fd2VicGFja19yZXF1aXJlX18ubyA9IChvYmosIHByb3ApID0+IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApIiwiLy8gbW9kdWxlIGV4cG9ydHMgbXVzdCBiZSByZXR1cm5lZCBmcm9tIHJ1bnRpbWUgc28gZW50cnkgaW5saW5pbmcgaXMgZGlzYWJsZWRcbi8vIHN0YXJ0dXBcbi8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xucmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oXCIuL3NyYy90YXNrcy9naXRyZWxlYXNlbWFuYWdlci9jcmVhdGUudHNcIik7XG4iXSwic291cmNlUm9vdCI6IiJ9 |