UNPKG

aws-cdk

Version:

AWS CDK CLI, the command line tool for CDK apps

337 lines 42.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Configuration = exports.Command = exports.USER_DEFAULTS = exports.PROJECT_CONTEXT = exports.PROJECT_CONFIG = void 0; exports.commandLineArgumentsToSettings = commandLineArgumentsToSettings; const os = require("os"); const fs_path = require("path"); const toolkit_lib_1 = require("@aws-cdk/toolkit-lib"); const fs = require("fs-extra"); const context_1 = require("../api/context"); const settings_1 = require("../api/settings"); exports.PROJECT_CONFIG = 'cdk.json'; var context_2 = require("../api/context"); Object.defineProperty(exports, "PROJECT_CONTEXT", { enumerable: true, get: function () { return context_2.PROJECT_CONTEXT; } }); exports.USER_DEFAULTS = '~/.cdk.json'; const CONTEXT_KEY = 'context'; var Command; (function (Command) { Command["LS"] = "ls"; Command["LIST"] = "list"; Command["DIFF"] = "diff"; Command["BOOTSTRAP"] = "bootstrap"; Command["DEPLOY"] = "deploy"; Command["DESTROY"] = "destroy"; Command["SYNTHESIZE"] = "synthesize"; Command["SYNTH"] = "synth"; Command["METADATA"] = "metadata"; Command["INIT"] = "init"; Command["VERSION"] = "version"; Command["WATCH"] = "watch"; Command["GC"] = "gc"; Command["FLAGS"] = "flags"; Command["ROLLBACK"] = "rollback"; Command["PUBLISH_ASSETS"] = "publish-assets"; Command["IMPORT"] = "import"; Command["ACKNOWLEDGE"] = "acknowledge"; Command["ACK"] = "ack"; Command["NOTICES"] = "notices"; Command["MIGRATE"] = "migrate"; Command["CONTEXT"] = "context"; Command["DOCS"] = "docs"; Command["DOC"] = "doc"; Command["DOCTOR"] = "doctor"; Command["ORPHAN"] = "orphan"; Command["REFACTOR"] = "refactor"; Command["DRIFT"] = "drift"; Command["CLI_TELEMETRY"] = "cli-telemetry"; Command["DIAGNOSE"] = "diagnose"; })(Command || (exports.Command = Command = {})); const BUNDLING_COMMANDS = [ Command.DEPLOY, Command.DIFF, Command.SYNTH, Command.SYNTHESIZE, Command.WATCH, Command.IMPORT, Command.PUBLISH_ASSETS, ]; /** * All sources of settings combined */ class Configuration { /** * Creates user configuration from commandLineArguments */ static async fromArgs(ioHelper, args) { const commandLineArguments = args ? await commandLineArgumentsToSettings(ioHelper, args) : new settings_1.Settings(); return new Configuration(ioHelper, commandLineArguments); } /** * Creates user configuration from commandLineArguments and loads */ static async fromArgsAndFiles(ioHelper, props = {}) { const configuration = await Configuration.fromArgs(ioHelper, props.commandLineArguments); return configuration.loadConfigFiles(props.readUserContext ?? true); } constructor(ioHelper, commandLineArguments) { this.settings = new settings_1.Settings(); this.context = new context_1.Context(); this.defaultConfig = new settings_1.Settings({ versionReporting: true, assetMetadata: true, pathMetadata: true, output: 'cdk.out', }); this.loaded = false; this.ioHelper = ioHelper; this.commandLineArguments = commandLineArguments; this.commandLineContext = this.commandLineArguments .subSettings([CONTEXT_KEY]) .makeReadOnly(); } get projectConfig() { if (!this._projectConfig) { throw new toolkit_lib_1.ToolkitError('ConfigNotLoaded', '#load has not been called yet!'); } return this._projectConfig; } get projectContext() { if (!this._projectContext) { throw new toolkit_lib_1.ToolkitError('ConfigNotLoaded', '#load has not been called yet!'); } return this._projectContext; } /** * Load all config */ async loadConfigFiles(readUserContext) { const userConfig = await loadAndLog(this.ioHelper, exports.USER_DEFAULTS); this._projectConfig = await loadAndLog(this.ioHelper, exports.PROJECT_CONFIG); this._projectContext = await loadAndLog(this.ioHelper, context_1.PROJECT_CONTEXT); if (userConfig.get(['build'])) { throw new toolkit_lib_1.ToolkitError('BuildKeyInUserConfig', 'The `build` key cannot be specified in the user config (~/.cdk.json), specify it in the project config (cdk.json) instead'); } const contextSources = [ { bag: this.commandLineContext }, { fileName: exports.PROJECT_CONFIG, bag: this.projectConfig.subSettings([CONTEXT_KEY]).makeReadOnly(), }, { fileName: context_1.PROJECT_CONTEXT, bag: this.projectContext }, ]; if (readUserContext) { contextSources.push({ fileName: exports.USER_DEFAULTS, bag: userConfig.subSettings([CONTEXT_KEY]).makeReadOnly(), }); } this.context = new context_1.Context(...contextSources); // Build settings from what's left this.settings = this.defaultConfig .merge(userConfig) .merge(this.projectConfig) .merge(this.commandLineArguments) .makeReadOnly(); await this.ioHelper.defaults.debug('merged settings:', this.settings.all); this.loaded = true; return this; } /** * Save the project context */ async saveContext() { if (!this.loaded) { return this; } // Avoid overwriting files with nothing await this.projectContext.save(context_1.PROJECT_CONTEXT); return this; } } exports.Configuration = Configuration; async function loadAndLog(ioHelper, fileName) { const ret = await settingsFromFile(ioHelper, fileName); if (!ret.empty) { await ioHelper.defaults.debug(fileName + ':', JSON.stringify(ret.all, undefined, 2)); } return ret; } async function settingsFromFile(ioHelper, fileName) { let settings; const expanded = expandHomeDir(fileName); if (await fs.pathExists(expanded)) { const data = await fs.readJson(expanded); settings = new settings_1.Settings(data); } else { settings = new settings_1.Settings(); } // See https://github.com/aws/aws-cdk/issues/59 prohibitContextKeys(settings, ['default-account', 'default-region'], fileName); await warnAboutContextKey(ioHelper, settings, 'aws:', fileName); return settings; } function prohibitContextKeys(settings, keys, fileName) { const context = settings.get(['context']); if (!context || typeof context !== 'object') { return; } for (const key of keys) { if (key in context) { throw new toolkit_lib_1.ToolkitError('UnsupportedContextKey', `The 'context.${key}' key was found in ${fs_path.resolve(fileName)}, but it is no longer supported. Please remove it.`); } } } async function warnAboutContextKey(ioHelper, settings, prefix, fileName) { const context = settings.get(['context']); if (!context || typeof context !== 'object') { return; } for (const contextKey of Object.keys(context)) { if (contextKey.startsWith(prefix)) { await ioHelper.defaults.warning(`A reserved context key ('context.${prefix}') key was found in ${fs_path.resolve(fileName)}, it might cause surprising behavior and should be removed.`); } } } function expandHomeDir(x) { if (x.startsWith('~')) { return fs_path.join(os.homedir(), x.slice(1)); } return x; } /** * Parse CLI arguments into Settings * * CLI arguments in must be accessed in the CLI code via * `configuration.settings.get(['argName'])` instead of via `args.argName`. * * The advantage is that they can be configured via `cdk.json` and * `$HOME/.cdk.json`. Arguments not listed below and accessed via this object * can only be specified on the command line. * * @param argv - the received CLI arguments. * @returns a new Settings object. */ async function commandLineArgumentsToSettings(ioHelper, argv) { const context = await parseStringContextListToObject(ioHelper, argv); const tags = await parseStringTagsListToObject(ioHelper, expectStringList(argv.tags)); // Determine bundling stacks let bundlingStacks; if (BUNDLING_COMMANDS.includes(argv._[0])) { // If we deploy, diff, synth or watch a list of stacks exclusively we skip // bundling for all other stacks. bundlingStacks = argv.exclusively ? argv.STACKS ?? ['**'] : ['**']; } else { // Skip bundling for all stacks bundlingStacks = []; } return new settings_1.Settings({ app: argv.app, browser: argv.browser, build: argv.build, caBundlePath: argv.caBundlePath, context, debug: argv.debug, tags, language: argv.language, pathMetadata: argv.pathMetadata, assetMetadata: argv.assetMetadata, profile: argv.profile, region: argv.region, plugin: argv.plugin, requireApproval: argv.requireApproval, toolkitStackName: argv.toolkitStackName, toolkitBucket: { bucketName: argv.bootstrapBucketName, kmsKeyId: argv.bootstrapKmsKeyId, }, versionReporting: argv.versionReporting, staging: argv.staging, output: argv.output, outputsFile: argv.outputsFile, progress: argv.progress, proxy: argv.proxy, bundlingStacks, lookups: argv.lookups, rollback: argv.rollback, notices: argv.notices, assetParallelism: argv['asset-parallelism'], assetBuildConcurrency: argv['asset-build-concurrency'], assetPrebuild: argv['asset-prebuild'], ignoreNoStacks: argv['ignore-no-stacks'], hotswap: { ecs: { minimumHealthyPercent: argv.hotswapEcsMinimumHealthyPercent, maximumHealthyPercent: argv.hotswapEcsMaximumHealthyPercent, stabilizationTimeoutSeconds: argv.hotswapEcsStabilizationTimeoutSeconds, }, }, unstable: argv.unstable, }); } function expectStringList(x) { if (x === undefined) { return undefined; } if (!Array.isArray(x)) { throw new toolkit_lib_1.ToolkitError('ExpectedArray', `Expected array, got '${x}'`); } const nonStrings = x.filter((e) => typeof e !== 'string'); if (nonStrings.length > 0) { throw new toolkit_lib_1.ToolkitError('ExpectedStringList', `Expected list of strings, found ${nonStrings}`); } return x; } async function parseStringContextListToObject(ioHelper, argv) { const context = {}; for (const assignment of argv.context || []) { const parts = assignment.split(/=(.*)/, 2); if (parts.length === 2) { await ioHelper.defaults.debug('CLI argument context: %s=%s', parts[0], parts[1]); if (parts[0].match(/^aws:.+/)) { throw new toolkit_lib_1.ToolkitError('ReservedContextPrefix', `User-provided context cannot use keys prefixed with 'aws:', but ${parts[0]} was provided.`); } context[parts[0]] = parts[1]; } else { await ioHelper.defaults.warn('Context argument is not an assignment (key=value): %s', assignment); } } return context; } /** * Parse tags out of arguments * * Return undefined if no tags were provided, return an empty array if only empty * strings were provided */ async function parseStringTagsListToObject(ioHelper, argTags) { if (argTags === undefined) { return undefined; } if (argTags.length === 0) { return undefined; } const nonEmptyTags = argTags.filter((t) => t !== ''); if (nonEmptyTags.length === 0) { return []; } const tags = []; for (const assignment of nonEmptyTags) { const parts = assignment.split(/=(.*)/, 2); if (parts.length === 2) { await ioHelper.defaults.debug('CLI argument tags: %s=%s', parts[0], parts[1]); tags.push({ Key: parts[0], Value: parts[1], }); } else { await ioHelper.defaults.warn('Tags argument is not an assignment (key=value): %s', assignment); } } return tags.length > 0 ? tags : undefined; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1jb25maWd1cmF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidXNlci1jb25maWd1cmF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQTRSQSx3RUEwREM7QUF0VkQseUJBQXlCO0FBQ3pCLGdDQUFnQztBQUNoQyxzREFBb0Q7QUFDcEQsK0JBQStCO0FBQy9CLDRDQUEwRDtBQUMxRCw4Q0FBMkM7QUFJOUIsUUFBQSxjQUFjLEdBQUcsVUFBVSxDQUFDO0FBQ3pDLDBDQUFpRDtBQUF4QywwR0FBQSxlQUFlLE9BQUE7QUFDWCxRQUFBLGFBQWEsR0FBRyxhQUFhLENBQUM7QUFDM0MsTUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDO0FBRTlCLElBQVksT0ErQlg7QUEvQkQsV0FBWSxPQUFPO0lBQ2pCLG9CQUFTLENBQUE7SUFDVCx3QkFBYSxDQUFBO0lBQ2Isd0JBQWEsQ0FBQTtJQUNiLGtDQUF1QixDQUFBO0lBQ3ZCLDRCQUFpQixDQUFBO0lBQ2pCLDhCQUFtQixDQUFBO0lBQ25CLG9DQUF5QixDQUFBO0lBQ3pCLDBCQUFlLENBQUE7SUFDZixnQ0FBcUIsQ0FBQTtJQUNyQix3QkFBYSxDQUFBO0lBQ2IsOEJBQW1CLENBQUE7SUFDbkIsMEJBQWUsQ0FBQTtJQUNmLG9CQUFTLENBQUE7SUFDVCwwQkFBZSxDQUFBO0lBQ2YsZ0NBQXFCLENBQUE7SUFDckIsNENBQWlDLENBQUE7SUFDakMsNEJBQWlCLENBQUE7SUFDakIsc0NBQTJCLENBQUE7SUFDM0Isc0JBQVcsQ0FBQTtJQUNYLDhCQUFtQixDQUFBO0lBQ25CLDhCQUFtQixDQUFBO0lBQ25CLDhCQUFtQixDQUFBO0lBQ25CLHdCQUFhLENBQUE7SUFDYixzQkFBVyxDQUFBO0lBQ1gsNEJBQWlCLENBQUE7SUFDakIsNEJBQWlCLENBQUE7SUFDakIsZ0NBQXFCLENBQUE7SUFDckIsMEJBQWUsQ0FBQTtJQUNmLDBDQUErQixDQUFBO0lBQy9CLGdDQUFxQixDQUFBO0FBQ3ZCLENBQUMs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SUFBSSxZQUFZLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzlCLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVELE1BQU0sSUFBSSxHQUFVLEVBQUUsQ0FBQztJQUV2QixLQUFLLE1BQU0sVUFBVSxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3RDLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzNDLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN2QixNQUFNLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLDBCQUEwQixFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5RSxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUNSLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUNiLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO2FBQ2hCLENBQUMsQ0FBQztRQUNMLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxvREFBb0QsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUNqRyxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQzVDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBvcyBmcm9tICdvcyc7XG5pbXBvcnQgKiBhcyBmc19wYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgVG9vbGtpdEVycm9yIH0gZnJvbSAnQGF3cy1jZGsvdG9vbGtpdC1saWInO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMtZXh0cmEnO1xuaW1wb3J0IHsgQ29udGV4dCwgUFJPSkVDVF9DT05URVhUIH0gZnJvbSAnLi4vYXBpL2NvbnRleHQnO1xuaW1wb3J0IHsgU2V0dGluZ3MgfSBmcm9tICcuLi9hcGkvc2V0dGluZ3MnO1xuaW1wb3J0IHR5cGUgeyBUYWcgfSBmcm9tICcuLi9hcGkvdGFncyc7XG5pbXBvcnQgdHlwZSB7IElvSGVscGVyIH0gZnJvbSAnLi4vYXBpLXByaXZhdGUnO1xuXG5leHBvcnQgY29uc3QgUFJPSkVDVF9DT05GSUcgPSAnY2RrLmpzb24nO1xuZXhwb3J0IHsgUFJPSkVDVF9DT05URVhUIH0gZnJvbSAnLi4vYXBpL2NvbnRleHQnO1xuZXhwb3J0IGNvbnN0IFVTRVJfREVGQVVMVFMgPSAnfi8uY2RrLmpzb24nO1xuY29uc3QgQ09OVEVYVF9LRVkgPSAnY29udGV4dCc7XG5cbmV4cG9ydCBlbnVtIENvbW1hbmQge1xuICBMUyA9ICdscycsXG4gIExJU1QgPSAnbGlzdCcsXG4gIERJRkYgPSAnZGlmZicsXG4gIEJPT1RTVFJBUCA9ICdib290c3RyYXAnLFxuICBERVBMT1kgPSAnZGVwbG95JyxcbiAgREVTVFJPWSA9ICdkZXN0cm95JyxcbiAgU1lOVEhFU0laRSA9ICdzeW50aGVzaXplJyxcbiAgU1lOVEggPSAnc3ludGgnLFxuICBNRVRBREFUQSA9ICdtZXRhZGF0YScsXG4gIElOSVQgPSAnaW5pdCcsXG4gIFZFUlNJT04gPSAndmVyc2lvbicsXG4gIFdBVENIID0gJ3dhdGNoJyxcbiAgR0MgPSAnZ2MnLFxuICBGTEFHUyA9ICdmbGFncycsXG4gIFJPTExCQUNLID0gJ3JvbGxiYWNrJyxcbiAgUFVCTElTSF9BU1NFVFMgPSAncHVibGlzaC1hc3NldHMnLFxuICBJTVBPUlQgPSAnaW1wb3J0JyxcbiAgQUNLTk9XTEVER0UgPSAnYWNrbm93bGVkZ2UnLFxuICBBQ0sgPSAnYWNrJyxcbiAgTk9USUNFUyA9ICdub3RpY2VzJyxcbiAgTUlHUkFURSA9ICdtaWdyYXRlJyxcbiAgQ09OVEVYVCA9ICdjb250ZXh0JyxcbiAgRE9DUyA9ICdkb2NzJyxcbiAgRE9DID0gJ2RvYycsXG4gIERPQ1RPUiA9ICdkb2N0b3InLFxuICBPUlBIQU4gPSAnb3JwaGFuJyxcbiAgUkVGQUNUT1IgPSAncmVmYWN0b3InLFxuICBEUklGVCA9ICdkcmlmdCcsXG4gIENMSV9URUxFTUVUUlkgPSAnY2xpLXRlbGVtZXRyeScsXG4gIERJQUdOT1NFID0gJ2RpYWdub3NlJyxcbn1cblxuY29uc3QgQlVORExJTkdfQ09NTUFORFMgPSBbXG4gIENvbW1hbmQuREVQTE9ZLFxuICBDb21tYW5kLkRJRkYsXG4gIENvbW1hbmQuU1lOVEgsXG4gIENvbW1hbmQuU1lOVEhFU0laRSxcbiAgQ29tbWFuZC5XQVRDSCxcbiAgQ29tbWFuZC5JTVBPUlQsXG4gIENvbW1hbmQuUFVCTElTSF9BU1NFVFMsXG5dO1xuXG5leHBvcnQgdHlwZSBBcmd1bWVudHMgPSB7XG4gIHJlYWRvbmx5IF86IFtDb21tYW5kLCAuLi5zdHJpbmdbXV07XG4gIHJlYWRvbmx5IGV4Y2x1c2l2ZWx5PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgU1RBQ0tTPzogc3RyaW5nW107XG4gIHJlYWRvbmx5IGxvb2t1cHM/OiBib29sZWFuO1xuICByZWFkb25seSBbbmFtZTogc3RyaW5nXTogdW5rbm93bjtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29uZmlndXJhdGlvblByb3BzIHtcbiAgLyoqXG4gICAqIENvbmZpZ3VyYXRpb24gcGFzc2VkIHZpYSBjb21tYW5kIGxpbmUgYXJndW1lbnRzXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm90aGluZyBwYXNzZWRcbiAgICovXG4gIHJlYWRvbmx5IGNvbW1hbmRMaW5lQXJndW1lbnRzPzogQXJndW1lbnRzO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIG9yIG5vdCB0byB1c2UgY29udGV4dCBmcm9tIGAuY2RrLmpzb25gIGluIHVzZXIgaG9tZSBkaXJlY3RvcnlcbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgcmVhZFVzZXJDb250ZXh0PzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBBbGwgc291cmNlcyBvZiBzZXR0aW5ncyBjb21iaW5lZFxuICovXG5leHBvcnQgY2xhc3MgQ29uZmlndXJhdGlvbiB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIHVzZXIgY29uZmlndXJhdGlvbiBmcm9tIGNvbW1hbmRMaW5lQXJndW1lbnRzXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGFzeW5jIGZyb21BcmdzKGlvSGVscGVyOiBJb0hlbHBlciwgYXJncz86IEFyZ3VtZW50cykge1xuICAgIGNvbnN0IGNvbW1hbmRMaW5lQXJndW1lbnRzID0gYXJnc1xuICAgICAgPyBhd2FpdCBjb21tYW5kTGluZUFyZ3VtZW50c1RvU2V0dGluZ3MoaW9IZWxwZXIsIGFyZ3MpXG4gICAgICA6IG5ldyBTZXR0aW5ncygpO1xuXG4gICAgcmV0dXJuIG5ldyBDb25maWd1cmF0aW9uKGlvSGVscGVyLCBjb21tYW5kTGluZUFyZ3VtZW50cyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB1c2VyIGNvbmZpZ3VyYXRpb24gZnJvbSBjb21tYW5kTGluZUFyZ3VtZW50cyBhbmQgbG9hZHNcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgZnJvbUFyZ3NBbmRGaWxlcyhpb0hlbHBlcjogSW9IZWxwZXIsIHByb3BzOiBDb25maWd1cmF0aW9uUHJvcHMgPSB7fSkge1xuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPSBhd2FpdCBDb25maWd1cmF0aW9uLmZyb21BcmdzKGlvSGVscGVyLCBwcm9wcy5jb21tYW5kTGluZUFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIGNvbmZpZ3VyYXRpb24ubG9hZENvbmZpZ0ZpbGVzKHByb3BzLnJlYWRVc2VyQ29udGV4dCA/PyB0cnVlKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXR0aW5ncyA9IG5ldyBTZXR0aW5ncygpO1xuICBwdWJsaWMgY29udGV4dCA9IG5ldyBDb250ZXh0KCk7XG5cbiAgcHVibGljIHJlYWRvbmx5IGRlZmF1bHRDb25maWcgPSBuZXcgU2V0dGluZ3Moe1xuICAgIHZlcnNpb25SZXBvcnRpbmc6IHRydWUsXG4gICAgYXNzZXRNZXRhZGF0YTogdHJ1ZSxcbiAgICBwYXRoTWV0YWRhdGE6IHRydWUsXG4gICAgb3V0cHV0OiAnY2RrLm91dCcsXG4gIH0pO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY29tbWFuZExpbmVBcmd1bWVudHM6IFNldHRpbmdzO1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbW1hbmRMaW5lQ29udGV4dDogU2V0dGluZ3M7XG4gIHByaXZhdGUgX3Byb2plY3RDb25maWc/OiBTZXR0aW5ncztcbiAgcHJpdmF0ZSBfcHJvamVjdENvbnRleHQ/OiBTZXR0aW5ncztcbiAgcHJpdmF0ZSBsb2FkZWQgPSBmYWxzZTtcblxuICBwcml2YXRlIGlvSGVscGVyOiBJb0hlbHBlcjtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKGlvSGVscGVyOiBJb0hlbHBlciwgY29tbWFuZExpbmVBcmd1bWVudHM6IFNldHRpbmdzKSB7XG4gICAgdGhpcy5pb0hlbHBlciA9IGlvSGVscGVyO1xuICAgIHRoaXMuY29tbWFuZExpbmVBcmd1bWVudHMgPSBjb21tYW5kTGluZUFyZ3VtZW50cztcbiAgICB0aGlzLmNvbW1hbmRMaW5lQ29udGV4dCA9IHRoaXMuY29tbWFuZExpbmVBcmd1bWVudHNcbiAgICAgIC5zdWJTZXR0aW5ncyhbQ09OVEVYVF9LRVldKVxuICAgICAgLm1ha2VSZWFkT25seSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgcHJvamVjdENvbmZpZygpIHtcbiAgICBpZiAoIXRoaXMuX3Byb2plY3RDb25maWcpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ0NvbmZpZ05vdExvYWRlZCcsICcjbG9hZCBoYXMgbm90IGJlZW4gY2FsbGVkIHlldCEnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3Byb2plY3RDb25maWc7XG4gIH1cblxuICBwdWJsaWMgZ2V0IHByb2plY3RDb250ZXh0KCkge1xuICAgIGlmICghdGhpcy5fcHJvamVjdENvbnRleHQpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ0NvbmZpZ05vdExvYWRlZCcsICcjbG9hZCBoYXMgbm90IGJlZW4gY2FsbGVkIHlldCEnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3Byb2plY3RDb250ZXh0O1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgYWxsIGNvbmZpZ1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBsb2FkQ29uZmlnRmlsZXMocmVhZFVzZXJDb250ZXh0OiBib29sZWFuKTogUHJvbWlzZTx0aGlzPiB7XG4gICAgY29uc3QgdXNlckNvbmZpZyA9IGF3YWl0IGxvYWRBbmRMb2codGhpcy5pb0hlbHBlciwgVVNFUl9ERUZBVUxUUyk7XG4gICAgdGhpcy5fcHJvamVjdENvbmZpZyA9IGF3YWl0IGxvYWRBbmRMb2codGhpcy5pb0hlbHBlciwgUFJPSkVDVF9DT05GSUcpO1xuICAgIHRoaXMuX3Byb2plY3RDb250ZXh0ID0gYXdhaXQgbG9hZEFuZExvZyh0aGlzLmlvSGVscGVyLCBQUk9KRUNUX0NPTlRFWFQpO1xuXG4gICAgaWYgKHVzZXJDb25maWcuZ2V0KFsnYnVpbGQnXSkpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoXG4gICAgICAgICdCdWlsZEtleUluVXNlckNvbmZpZycsXG4gICAgICAgICdUaGUgYGJ1aWxkYCBrZXkgY2Fubm90IGJlIHNwZWNpZmllZCBpbiB0aGUgdXNlciBjb25maWcgKH4vLmNkay5qc29uKSwgc3BlY2lmeSBpdCBpbiB0aGUgcHJvamVjdCBjb25maWcgKGNkay5qc29uKSBpbnN0ZWFkJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgY29udGV4dFNvdXJjZXMgPSBbXG4gICAgICB7IGJhZzogdGhpcy5jb21tYW5kTGluZUNvbnRleHQgfSxcbiAgICAgIHtcbiAgICAgICAgZmlsZU5hbWU6IFBST0pFQ1RfQ09ORklHLFxuICAgICAgICBiYWc6IHRoaXMucHJvamVjdENvbmZpZy5zdWJTZXR0aW5ncyhbQ09OVEVYVF9LRVldKS5tYWtlUmVhZE9ubHkoKSxcbiAgICAgIH0sXG4gICAgICB7IGZpbGVOYW1lOiBQUk9KRUNUX0NPTlRFWFQsIGJhZzogdGhpcy5wcm9qZWN0Q29udGV4dCB9LFxuICAgIF07XG4gICAgaWYgKHJlYWRVc2VyQ29udGV4dCkge1xuICAgICAgY29udGV4dFNvdXJjZXMucHVzaCh7XG4gICAgICAgIGZpbGVOYW1lOiBVU0VSX0RFRkFVTFRTLFxuICAgICAgICBiYWc6IHVzZXJDb25maWcuc3ViU2V0dGluZ3MoW0NPTlRFWFRfS0VZXSkubWFrZVJlYWRPbmx5KCksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmNvbnRleHQgPSBuZXcgQ29udGV4dCguLi5jb250ZXh0U291cmNlcyk7XG5cbiAgICAvLyBCdWlsZCBzZXR0aW5ncyBmcm9tIHdoYXQncyBsZWZ0XG4gICAgdGhpcy5zZXR0aW5ncyA9IHRoaXMuZGVmYXVsdENvbmZpZ1xuICAgICAgLm1lcmdlKHVzZXJDb25maWcpXG4gICAgICAubWVyZ2UodGhpcy5wcm9qZWN0Q29uZmlnKVxuICAgICAgLm1lcmdlKHRoaXMuY29tbWFuZExpbmVBcmd1bWVudHMpXG4gICAgICAubWFrZVJlYWRPbmx5KCk7XG5cbiAgICBhd2FpdCB0aGlzLmlvSGVscGVyLmRlZmF1bHRzLmRlYnVnKCdtZXJnZWQgc2V0dGluZ3M6JywgdGhpcy5zZXR0aW5ncy5hbGwpO1xuXG4gICAgdGhpcy5sb2FkZWQgPSB0cnVlO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogU2F2ZSB0aGUgcHJvamVjdCBjb250ZXh0XG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc2F2ZUNvbnRleHQoKTogUHJvbWlzZTx0aGlzPiB7XG4gICAgaWYgKCF0aGlzLmxvYWRlZCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSAvLyBBdm9pZCBvdmVyd3JpdGluZyBmaWxlcyB3aXRoIG5vdGhpbmdcblxuICAgIGF3YWl0IHRoaXMucHJvamVjdENvbnRleHQuc2F2ZShQUk9KRUNUX0NPTlRFWFQpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gbG9hZEFuZExvZyhpb0hlbHBlcjogSW9IZWxwZXIsIGZpbGVOYW1lOiBzdHJpbmcpOiBQcm9taXNlPFNldHRpbmdzPiB7XG4gIGNvbnN0IHJldCA9IGF3YWl0IHNldHRpbmdzRnJvbUZpbGUoaW9IZWxwZXIsIGZpbGVOYW1lKTtcbiAgaWYgKCFyZXQuZW1wdHkpIHtcbiAgICBhd2FpdCBpb0hlbHBlci5kZWZhdWx0cy5kZWJ1ZyhmaWxlTmFtZSArICc6JywgSlNPTi5zdHJpbmdpZnkocmV0LmFsbCwgdW5kZWZpbmVkLCAyKSk7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc2V0dGluZ3NGcm9tRmlsZShpb0hlbHBlcjogSW9IZWxwZXIsIGZpbGVOYW1lOiBzdHJpbmcpOiBQcm9taXNlPFNldHRpbmdzPiB7XG4gIGxldCBzZXR0aW5ncztcbiAgY29uc3QgZXhwYW5kZWQgPSBleHBhbmRIb21lRGlyKGZpbGVOYW1lKTtcbiAgaWYgKGF3YWl0IGZzLnBhdGhFeGlzdHMoZXhwYW5kZWQpKSB7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IGZzLnJlYWRKc29uKGV4cGFuZGVkKTtcbiAgICBzZXR0aW5ncyA9IG5ldyBTZXR0aW5ncyhkYXRhKTtcbiAgfSBlbHNlIHtcbiAgICBzZXR0aW5ncyA9IG5ldyBTZXR0aW5ncygpO1xuICB9XG5cbiAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYXdzLWNkay9pc3N1ZXMvNTlcbiAgcHJvaGliaXRDb250ZXh0S2V5cyhzZXR0aW5ncywgWydkZWZhdWx0LWFjY291bnQnLCAnZGVmYXVsdC1yZWdpb24nXSwgZmlsZU5hbWUpO1xuICBhd2FpdCB3YXJuQWJvdXRDb250ZXh0S2V5KGlvSGVscGVyLCBzZXR0aW5ncywgJ2F3czonLCBmaWxlTmFtZSk7XG5cbiAgcmV0dXJuIHNldHRpbmdzO1xufVxuXG5mdW5jdGlvbiBwcm9oaWJpdENvbnRleHRLZXlzKHNldHRpbmdzOiBTZXR0aW5ncywga2V5czogc3RyaW5nW10sIGZpbGVOYW1lOiBzdHJpbmcpIHtcbiAgY29uc3QgY29udGV4dCA9IHNldHRpbmdzLmdldChbJ2NvbnRleHQnXSk7XG4gIGlmICghY29udGV4dCB8fCB0eXBlb2YgY29udGV4dCAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgaWYgKGtleSBpbiBjb250ZXh0KSB7XG4gICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKFxuICAgICAgICAnVW5zdXBwb3J0ZWRDb250ZXh0S2V5JyxcbiAgICAgICAgYFRoZSAnY29udGV4dC4ke2tleX0nIGtleSB3YXMgZm91bmQgaW4gJHtmc19wYXRoLnJlc29sdmUoXG4gICAgICAgICAgZmlsZU5hbWUsXG4gICAgICAgICl9LCBidXQgaXQgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZC4gUGxlYXNlIHJlbW92ZSBpdC5gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gd2FybkFib3V0Q29udGV4dEtleShpb0hlbHBlcjogSW9IZWxwZXIsIHNldHRpbmdzOiBTZXR0aW5ncywgcHJlZml4OiBzdHJpbmcsIGZpbGVOYW1lOiBzdHJpbmcpIHtcbiAgY29uc3QgY29udGV4dCA9IHNldHRpbmdzLmdldChbJ2NvbnRleHQnXSk7XG4gIGlmICghY29udGV4dCB8fCB0eXBlb2YgY29udGV4dCAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBmb3IgKGNvbnN0IGNvbnRleHRLZXkgb2YgT2JqZWN0LmtleXMoY29udGV4dCkpIHtcbiAgICBpZiAoY29udGV4dEtleS5zdGFydHNXaXRoKHByZWZpeCkpIHtcbiAgICAgIGF3YWl0IGlvSGVscGVyLmRlZmF1bHRzLndhcm5pbmcoXG4gICAgICAgIGBBIHJlc2VydmVkIGNvbnRleHQga2V5ICgnY29udGV4dC4ke3ByZWZpeH0nKSBrZXkgd2FzIGZvdW5kIGluICR7ZnNfcGF0aC5yZXNvbHZlKFxuICAgICAgICAgIGZpbGVOYW1lLFxuICAgICAgICApfSwgaXQgbWlnaHQgY2F1c2Ugc3VycHJpc2luZyBiZWhhdmlvciBhbmQgc2hvdWxkIGJlIHJlbW92ZWQuYCxcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGV4cGFuZEhvbWVEaXIoeDogc3RyaW5nKSB7XG4gIGlmICh4LnN0YXJ0c1dpdGgoJ34nKSkge1xuICAgIHJldHVybiBmc19wYXRoLmpvaW4ob3MuaG9tZWRpcigpLCB4LnNsaWNlKDEpKTtcbiAgfVxuICByZXR1cm4geDtcbn1cblxuLyoqXG4gKiBQYXJzZSBDTEkgYXJndW1lbnRzIGludG8gU2V0dGluZ3NcbiAqXG4gKiBDTEkgYXJndW1lbnRzIGluIG11c3QgYmUgYWNjZXNzZWQgaW4gdGhlIENMSSBjb2RlIHZpYVxuICogYGNvbmZpZ3VyYXRpb24uc2V0dGluZ3MuZ2V0KFsnYXJnTmFtZSddKWAgaW5zdGVhZCBvZiB2aWEgYGFyZ3MuYXJnTmFtZWAuXG4gKlxuICogVGhlIGFkdmFudGFnZSBpcyB0aGF0IHRoZXkgY2FuIGJlIGNvbmZpZ3VyZWQgdmlhIGBjZGsuanNvbmAgYW5kXG4gKiBgJEhPTUUvLmNkay5qc29uYC4gQXJndW1lbnRzIG5vdCBsaXN0ZWQgYmVsb3cgYW5kIGFjY2Vzc2VkIHZpYSB0aGlzIG9iamVjdFxuICogY2FuIG9ubHkgYmUgc3BlY2lmaWVkIG9uIHRoZSBjb21tYW5kIGxpbmUuXG4gKlxuICogQHBhcmFtIGFyZ3YgLSB0aGUgcmVjZWl2ZWQgQ0xJIGFyZ3VtZW50cy5cbiAqIEByZXR1cm5zIGEgbmV3IFNldHRpbmdzIG9iamVjdC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvbW1hbmRMaW5lQXJndW1lbnRzVG9TZXR0aW5ncyhpb0hlbHBlcjogSW9IZWxwZXIsIGFyZ3Y6IEFyZ3VtZW50cyk6IFByb21pc2U8U2V0dGluZ3M+IHtcbiAgY29uc3QgY29udGV4dCA9IGF3YWl0IHBhcnNlU3RyaW5nQ29udGV4dExpc3RUb09iamVjdChpb0hlbHBlciwgYXJndik7XG4gIGNvbnN0IHRhZ3MgPSBhd2FpdCBwYXJzZVN0cmluZ1RhZ3NMaXN0VG9PYmplY3QoaW9IZWxwZXIsIGV4cGVjdFN0cmluZ0xpc3QoYXJndi50YWdzKSk7XG5cbiAgLy8gRGV0ZXJtaW5lIGJ1bmRsaW5nIHN0YWNrc1xuICBsZXQgYnVuZGxpbmdTdGFja3M6IHN0cmluZ1tdO1xuICBpZiAoQlVORExJTkdfQ09NTUFORFMuaW5jbHVkZXMoYXJndi5fWzBdKSkge1xuICAgIC8vIElmIHdlIGRlcGxveSwgZGlmZiwgc3ludGggb3Igd2F0Y2ggYSBsaXN0IG9mIHN0YWNrcyBleGNsdXNpdmVseSB3ZSBza2lwXG4gICAgLy8gYnVuZGxpbmcgZm9yIGFsbCBvdGhlciBzdGFja3MuXG4gICAgYnVuZGxpbmdTdGFja3MgPSBhcmd2LmV4Y2x1c2l2ZWx5ID8gYXJndi5TVEFDS1MgPz8gWycqKiddIDogWycqKiddO1xuICB9IGVsc2Uge1xuICAgIC8vIFNraXAgYnVuZGxpbmcgZm9yIGFsbCBzdGFja3NcbiAgICBidW5kbGluZ1N0YWNrcyA9IFtdO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBTZXR0aW5ncyh7XG4gICAgYXBwOiBhcmd2LmFwcCxcbiAgICBicm93c2VyOiBhcmd2LmJyb3dzZXIsXG4gICAgYnVpbGQ6IGFyZ3YuYnVpbGQsXG4gICAgY2FCdW5kbGVQYXRoOiBhcmd2LmNhQnVuZGxlUGF0aCxcbiAgICBjb250ZXh0LFxuICAgIGRlYnVnOiBhcmd2LmRlYnVnLFxuICAgIHRhZ3MsXG4gICAgbGFuZ3VhZ2U6IGFyZ3YubGFuZ3VhZ2UsXG4gICAgcGF0aE1ldGFkYXRhOiBhcmd2LnBhdGhNZXRhZGF0YSxcbiAgICBhc3NldE1ldGFkYXRhOiBhcmd2LmFzc2V0TWV0YWRhdGEsXG4gICAgcHJvZmlsZTogYXJndi5wcm9maWxlLFxuICAgIHJlZ2lvbjogYXJndi5yZWdpb24sXG4gICAgcGx1Z2luOiBhcmd2LnBsdWdpbixcbiAgICByZXF1aXJlQXBwcm92YWw6IGFyZ3YucmVxdWlyZUFwcHJvdmFsLFxuICAgIHRvb2xraXRTdGFja05hbWU6IGFyZ3YudG9vbGtpdFN0YWNrTmFtZSxcbiAgICB0b29sa2l0QnVja2V0OiB7XG4gICAgICBidWNrZXROYW1lOiBhcmd2LmJvb3RzdHJhcEJ1Y2tldE5hbWUsXG4gICAgICBrbXNLZXlJZDogYXJndi5ib290c3RyYXBLbXNLZXlJZCxcbiAgICB9LFxuICAgIHZlcnNpb25SZXBvcnRpbmc6IGFyZ3YudmVyc2lvblJlcG9ydGluZyxcbiAgICBzdGFnaW5nOiBhcmd2LnN0YWdpbmcsXG4gICAgb3V0cHV0OiBhcmd2Lm91dHB1dCxcbiAgICBvdXRwdXRzRmlsZTogYXJndi5vdXRwdXRzRmlsZSxcbiAgICBwcm9ncmVzczogYXJndi5wcm9ncmVzcyxcbiAgICBwcm94eTogYXJndi5wcm94eSxcbiAgICBidW5kbGluZ1N0YWNrcyxcbiAgICBsb29rdXBzOiBhcmd2Lmxvb2t1cHMsXG4gICAgcm9sbGJhY2s6IGFyZ3Yucm9sbGJhY2ssXG4gICAgbm90aWNlczogYXJndi5ub3RpY2VzLFxuICAgIGFzc2V0UGFyYWxsZWxpc206IGFyZ3ZbJ2Fzc2V0LXBhcmFsbGVsaXNtJ10sXG4gICAgYXNzZXRCdWlsZENvbmN1cnJlbmN5OiBhcmd2Wydhc3NldC1idWlsZC1jb25jdXJyZW5jeSddLFxuICAgIGFzc2V0UHJlYnVpbGQ6IGFyZ3ZbJ2Fzc2V0LXByZWJ1aWxkJ10sXG4gICAgaWdub3JlTm9TdGFja3M6IGFyZ3ZbJ2lnbm9yZS1uby1zdGFja3MnXSxcbiAgICBob3Rzd2FwOiB7XG4gICAgICBlY3M6IHtcbiAgICAgICAgbWluaW11bUhlYWx0aHlQZXJjZW50OiBhcmd2LmhvdHN3YXBFY3NNaW5pbXVtSGVhbHRoeVBlcmNlbnQsXG4gICAgICAgIG1heGltdW1IZWFsdGh5UGVyY2VudDogYXJndi5ob3Rzd2FwRWNzTWF4aW11bUhlYWx0aHlQZXJjZW50LFxuICAgICAgICBzdGFiaWxpemF0aW9uVGltZW91dFNlY29uZHM6IGFyZ3YuaG90c3dhcEVjc1N0YWJpbGl6YXRpb25UaW1lb3V0U2Vjb25kcyxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB1bnN0YWJsZTogYXJndi51bnN0YWJsZSxcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGV4cGVjdFN0cmluZ0xpc3QoeDogdW5rbm93bik6IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHggPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKCFBcnJheS5pc0FycmF5KHgpKSB7XG4gICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignRXhwZWN0ZWRBcnJheScsIGBFeHBlY3RlZCBhcnJheSwgZ290ICcke3h9J2ApO1xuICB9XG4gIGNvbnN0IG5vblN0cmluZ3MgPSB4LmZpbHRlcigoZSkgPT4gdHlwZW9mIGUgIT09ICdzdHJpbmcnKTtcbiAgaWYgKG5vblN0cmluZ3MubGVuZ3RoID4gMCkge1xuICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ0V4cGVjdGVkU3RyaW5nTGlzdCcsIGBFeHBlY3RlZCBsaXN0IG9mIHN0cmluZ3MsIGZvdW5kICR7bm9uU3RyaW5nc31gKTtcbiAgfVxuICByZXR1cm4geDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcGFyc2VTdHJpbmdDb250ZXh0TGlzdFRvT2JqZWN0KGlvSGVscGVyOiBJb0hlbHBlciwgYXJndjogQXJndW1lbnRzKTogUHJvbWlzZTxhbnk+IHtcbiAgY29uc3QgY29udGV4dDogYW55ID0ge307XG5cbiAgZm9yIChjb25zdCBhc3NpZ25tZW50IG9mIChhcmd2IGFzIGFueSkuY29udGV4dCB8fCBbXSkge1xuICAgIGNvbnN0IHBhcnRzID0gYXNzaWdubWVudC5zcGxpdCgvPSguKikvLCAyKTtcbiAgICBpZiAocGFydHMubGVuZ3RoID09PSAyKSB7XG4gICAgICBhd2FpdCBpb0hlbHBlci5kZWZhdWx0cy5kZWJ1ZygnQ0xJIGFyZ3VtZW50IGNvbnRleHQ6ICVzPSVzJywgcGFydHNbMF0sIHBhcnRzWzFdKTtcbiAgICAgIGlmIChwYXJ0c1swXS5tYXRjaCgvXmF3czouKy8pKSB7XG4gICAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoXG4gICAgICAgICAgJ1Jlc2VydmVkQ29udGV4dFByZWZpeCcsXG4gICAgICAgICAgYFVzZXItcHJvdmlkZWQgY29udGV4dCBjYW5ub3QgdXNlIGtleXMgcHJlZml4ZWQgd2l0aCAnYXdzOicsIGJ1dCAke3BhcnRzWzBdfSB3YXMgcHJvdmlkZWQuYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnRleHRbcGFydHNbMF1dID0gcGFydHNbMV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IGlvSGVscGVyLmRlZmF1bHRzLndhcm4oXG4gICAgICAgICdDb250ZXh0IGFyZ3VtZW50IGlzIG5vdCBhbiBhc3NpZ25tZW50IChrZXk9dmFsdWUpOiAlcycsXG4gICAgICAgIGFzc2lnbm1lbnQsXG4gICAgICApO1xuICAgIH1cbiAgfVxuICByZXR1cm4gY29udGV4dDtcbn1cblxuLyoqXG4gKiBQYXJzZSB0YWdzIG91dCBvZiBhcmd1bWVudHNcbiAqXG4gKiBSZXR1cm4gdW5kZWZpbmVkIGlmIG5vIHRhZ3Mgd2VyZSBwcm92aWRlZCwgcmV0dXJuIGFuIGVtcHR5IGFycmF5IGlmIG9ubHkgZW1wdHlcbiAqIHN0cmluZ3Mgd2VyZSBwcm92aWRlZFxuICovXG5hc3luYyBmdW5jdGlvbiBwYXJzZVN0cmluZ1RhZ3NMaXN0VG9PYmplY3QoXG4gIGlvSGVscGVyOiBJb0hlbHBlcixcbiAgYXJnVGFnczogc3RyaW5nW10gfCB1bmRlZmluZWQsXG4pOiBQcm9taXNlPFRhZ1tdIHwgdW5kZWZpbmVkPiB7XG4gIGlmIChhcmdUYWdzID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGlmIChhcmdUYWdzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3Qgbm9uRW1wdHlUYWdzID0gYXJnVGFncy5maWx0ZXIoKHQpID0+IHQgIT09ICcnKTtcbiAgaWYgKG5vbkVtcHR5VGFncy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCB0YWdzOiBUYWdbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgYXNzaWdubWVudCBvZiBub25FbXB0eVRhZ3MpIHtcbiAgICBjb25zdCBwYXJ0cyA9IGFzc2lnbm1lbnQuc3BsaXQoLz0oLiopLywgMik7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgYXdhaXQgaW9IZWxwZXIuZGVmYXVsdHMuZGVidWcoJ0NMSSBhcmd1bWVudCB0YWdzOiAlcz0lcycsIHBhcnRzWzBdLCBwYXJ0c1sxXSk7XG4gICAgICB0YWdzLnB1c2goe1xuICAgICAgICBLZXk6IHBhcnRzWzBdLFxuICAgICAgICBWYWx1ZTogcGFydHNbMV0sXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgaW9IZWxwZXIuZGVmYXVsdHMud2FybignVGFncyBhcmd1bWVudCBpcyBub3QgYW4gYXNzaWdubWVudCAoa2V5PXZhbHVlKTogJXMnLCBhc3NpZ25tZW50KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRhZ3MubGVuZ3RoID4gMCA/IHRhZ3MgOiB1bmRlZmluZWQ7XG59XG4iXX0=