UNPKG

aws-cdk

Version:

AWS CDK CLI, the command line tool for CDK apps

334 lines 41.8 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["REFACTOR"] = "refactor"; Command["DRIFT"] = "drift"; Command["CLI_TELEMETRY"] = "cli-telemetry"; })(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, 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1jb25maWd1cmF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidXNlci1jb25maWd1cmF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQTBSQSx3RUF5REM7QUFuVkQseUJBQXlCO0FBQ3pCLGdDQUFnQztBQUNoQyxzREFBb0Q7QUFDcEQsK0JBQStCO0FBQy9CLDRDQUEwRDtBQUMxRCw4Q0FBMkM7QUFJOUIsUUFBQSxjQUFjLEdBQUcsVUFBVSxDQUFDO0FBQ3pDLDBDQUFpRDtBQUF4QywwR0FBQSxlQUFlLE9BQUE7QUFDWCxRQUFBLGFBQWEsR0FBRyxhQUFhLENBQUM7QUFDM0MsTUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDO0FBRTlCLElBQVksT0E2Qlg7QUE3QkQsV0FBWSxPQUFPO0lBQ2pCLG9CQUFTLENBQUE7SUFDVCx3QkFBYSxDQUFBO0lBQ2Isd0JBQWEsQ0FBQTtJQUNiLGtDQUF1QixDQUFBO0lBQ3ZCLDRCQUFpQixDQUFBO0lBQ2pCLDhCQUFtQixDQUFBO0lBQ25CLG9DQUF5QixDQUFBO0lBQ3pCLDBCQUFlLENBQUE7SUFDZixnQ0FBcUIsQ0FBQTtJQUNyQix3QkFBYSxDQUFBO0lBQ2IsOEJBQW1CLENBQUE7SUFDbkIsMEJBQWUsQ0FBQTtJQUNmLG9CQUFTLENBQUE7SUFDVCwwQkFBZSxDQUFBO0lBQ2YsZ0NBQXFCLENBQUE7SUFDckIsNENBQWlDLENBQUE7SUFDakMsNEJBQWlCLENBQUE7SUFDakIsc0NBQTJCLENBQUE7SUFDM0Isc0JBQVcsQ0FBQTtJQUNYLDhCQUFtQixDQUFBO0lBQ25CLDhCQUFtQixDQUFBO0lBQ25CLDhCQUFtQixDQUFBO0lBQ25CLHdCQUFhLENBQUE7SUFDYixzQkFBVyxDQUFBO0lBQ1gsNEJBQWlCLENBQUE7SUFDakIsZ0NBQXFCLENBQUE7SUFDckIsMEJBQWUsQ0FBQTtJQUNmLDBDQUErQixDQUFBO0FBQ2pDLENBQUMsRUE3QlcsT0FBTyx1QkFBUCxPQUFPLFFBNkJsQjtBQUVELE1B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QUFDO0lBRUQsTUFBTSxJQUFJLEdBQVUsRUFBRSxDQUFDO0lBRXZCLEtBQUssTUFBTSxVQUFVLElBQUksWUFBWSxFQUFFLENBQUM7UUFDdEMsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDM0MsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsMEJBQTBCLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlFLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ1IsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBQ2IsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7YUFDaEIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLG9EQUFvRCxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ2pHLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDNUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIG9zIGZyb20gJ29zJztcbmltcG9ydCAqIGFzIGZzX3BhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBUb29sa2l0RXJyb3IgfSBmcm9tICdAYXdzLWNkay90b29sa2l0LWxpYic7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcy1leHRyYSc7XG5pbXBvcnQgeyBDb250ZXh0LCBQUk9KRUNUX0NPTlRFWFQgfSBmcm9tICcuLi9hcGkvY29udGV4dCc7XG5pbXBvcnQgeyBTZXR0aW5ncyB9IGZyb20gJy4uL2FwaS9zZXR0aW5ncyc7XG5pbXBvcnQgdHlwZSB7IFRhZyB9IGZyb20gJy4uL2FwaS90YWdzJztcbmltcG9ydCB0eXBlIHsgSW9IZWxwZXIgfSBmcm9tICcuLi9hcGktcHJpdmF0ZSc7XG5cbmV4cG9ydCBjb25zdCBQUk9KRUNUX0NPTkZJRyA9ICdjZGsuanNvbic7XG5leHBvcnQgeyBQUk9KRUNUX0NPTlRFWFQgfSBmcm9tICcuLi9hcGkvY29udGV4dCc7XG5leHBvcnQgY29uc3QgVVNFUl9ERUZBVUxUUyA9ICd+Ly5jZGsuanNvbic7XG5jb25zdCBDT05URVhUX0tFWSA9ICdjb250ZXh0JztcblxuZXhwb3J0IGVudW0gQ29tbWFuZCB7XG4gIExTID0gJ2xzJyxcbiAgTElTVCA9ICdsaXN0JyxcbiAgRElGRiA9ICdkaWZmJyxcbiAgQk9PVFNUUkFQID0gJ2Jvb3RzdHJhcCcsXG4gIERFUExPWSA9ICdkZXBsb3knLFxuICBERVNUUk9ZID0gJ2Rlc3Ryb3knLFxuICBTWU5USEVTSVpFID0gJ3N5bnRoZXNpemUnLFxuICBTWU5USCA9ICdzeW50aCcsXG4gIE1FVEFEQVRBID0gJ21ldGFkYXRhJyxcbiAgSU5JVCA9ICdpbml0JyxcbiAgVkVSU0lPTiA9ICd2ZXJzaW9uJyxcbiAgV0FUQ0ggPSAnd2F0Y2gnLFxuICBHQyA9ICdnYycsXG4gIEZMQUdTID0gJ2ZsYWdzJyxcbiAgUk9MTEJBQ0sgPSAncm9sbGJhY2snLFxuICBQVUJMSVNIX0FTU0VUUyA9ICdwdWJsaXNoLWFzc2V0cycsXG4gIElNUE9SVCA9ICdpbXBvcnQnLFxuICBBQ0tOT1dMRURHRSA9ICdhY2tub3dsZWRnZScsXG4gIEFDSyA9ICdhY2snLFxuICBOT1RJQ0VTID0gJ25vdGljZXMnLFxuICBNSUdSQVRFID0gJ21pZ3JhdGUnLFxuICBDT05URVhUID0gJ2NvbnRleHQnLFxuICBET0NTID0gJ2RvY3MnLFxuICBET0MgPSAnZG9jJyxcbiAgRE9DVE9SID0gJ2RvY3RvcicsXG4gIFJFRkFDVE9SID0gJ3JlZmFjdG9yJyxcbiAgRFJJRlQgPSAnZHJpZnQnLFxuICBDTElfVEVMRU1FVFJZID0gJ2NsaS10ZWxlbWV0cnknLFxufVxuXG5jb25zdCBCVU5ETElOR19DT01NQU5EUyA9IFtcbiAgQ29tbWFuZC5ERVBMT1ksXG4gIENvbW1hbmQuRElGRixcbiAgQ29tbWFuZC5TWU5USCxcbiAgQ29tbWFuZC5TWU5USEVTSVpFLFxuICBDb21tYW5kLldBVENILFxuICBDb21tYW5kLklNUE9SVCxcbiAgQ29tbWFuZC5QVUJMSVNIX0FTU0VUUyxcbl07XG5cbmV4cG9ydCB0eXBlIEFyZ3VtZW50cyA9IHtcbiAgcmVhZG9ubHkgXzogW0NvbW1hbmQsIC4uLnN0cmluZ1tdXTtcbiAgcmVhZG9ubHkgZXhjbHVzaXZlbHk/OiBib29sZWFuO1xuICByZWFkb25seSBTVEFDS1M/OiBzdHJpbmdbXTtcbiAgcmVhZG9ubHkgbG9va3Vwcz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IFtuYW1lOiBzdHJpbmddOiB1bmtub3duO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBDb25maWd1cmF0aW9uUHJvcHMge1xuICAvKipcbiAgICogQ29uZmlndXJhdGlvbiBwYXNzZWQgdmlhIGNvbW1hbmQgbGluZSBhcmd1bWVudHNcbiAgICpcbiAgICogQGRlZmF1bHQgLSBOb3RoaW5nIHBhc3NlZFxuICAgKi9cbiAgcmVhZG9ubHkgY29tbWFuZExpbmVBcmd1bWVudHM/OiBBcmd1bWVudHM7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgb3Igbm90IHRvIHVzZSBjb250ZXh0IGZyb20gYC5jZGsuanNvbmAgaW4gdXNlciBob21lIGRpcmVjdG9yeVxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSByZWFkVXNlckNvbnRleHQ/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIEFsbCBzb3VyY2VzIG9mIHNldHRpbmdzIGNvbWJpbmVkXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25maWd1cmF0aW9uIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgdXNlciBjb25maWd1cmF0aW9uIGZyb20gY29tbWFuZExpbmVBcmd1bWVudHNcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgZnJvbUFyZ3MoaW9IZWxwZXI6IElvSGVscGVyLCBhcmdzPzogQXJndW1lbnRzKSB7XG4gICAgY29uc3QgY29tbWFuZExpbmVBcmd1bWVudHMgPSBhcmdzXG4gICAgICA/IGF3YWl0IGNvbW1hbmRMaW5lQXJndW1lbnRzVG9TZXR0aW5ncyhpb0hlbHBlciwgYXJncylcbiAgICAgIDogbmV3IFNldHRpbmdzKCk7XG5cbiAgICByZXR1cm4gbmV3IENvbmZpZ3VyYXRpb24oaW9IZWxwZXIsIGNvbW1hbmRMaW5lQXJndW1lbnRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIHVzZXIgY29uZmlndXJhdGlvbiBmcm9tIGNvbW1hbmRMaW5lQXJndW1lbnRzIGFuZCBsb2Fkc1xuICAgKi9cbiAgcHVibGljIHN0YXRpYyBhc3luYyBmcm9tQXJnc0FuZEZpbGVzKGlvSGVscGVyOiBJb0hlbHBlciwgcHJvcHM6IENvbmZpZ3VyYXRpb25Qcm9wcyA9IHt9KSB7XG4gICAgY29uc3QgY29uZmlndXJhdGlvbiA9IGF3YWl0IENvbmZpZ3VyYXRpb24uZnJvbUFyZ3MoaW9IZWxwZXIsIHByb3BzLmNvbW1hbmRMaW5lQXJndW1lbnRzKTtcbiAgICByZXR1cm4gY29uZmlndXJhdGlvbi5sb2FkQ29uZmlnRmlsZXMocHJvcHMucmVhZFVzZXJDb250ZXh0ID8/IHRydWUpO1xuICB9XG5cbiAgcHVibGljIHNldHRpbmdzID0gbmV3IFNldHRpbmdzKCk7XG4gIHB1YmxpYyBjb250ZXh0ID0gbmV3IENvbnRleHQoKTtcblxuICBwdWJsaWMgcmVhZG9ubHkgZGVmYXVsdENvbmZpZyA9IG5ldyBTZXR0aW5ncyh7XG4gICAgdmVyc2lvblJlcG9ydGluZzogdHJ1ZSxcbiAgICBhc3NldE1ldGFkYXRhOiB0cnVlLFxuICAgIHBhdGhNZXRhZGF0YTogdHJ1ZSxcbiAgICBvdXRwdXQ6ICdjZGsub3V0JyxcbiAgfSk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjb21tYW5kTGluZUFyZ3VtZW50czogU2V0dGluZ3M7XG4gIHByaXZhdGUgcmVhZG9ubHkgY29tbWFuZExpbmVDb250ZXh0OiBTZXR0aW5ncztcbiAgcHJpdmF0ZSBfcHJvamVjdENvbmZpZz86IFNldHRpbmdzO1xuICBwcml2YXRlIF9wcm9qZWN0Q29udGV4dD86IFNldHRpbmdzO1xuICBwcml2YXRlIGxvYWRlZCA9IGZhbHNlO1xuXG4gIHByaXZhdGUgaW9IZWxwZXI6IElvSGVscGVyO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoaW9IZWxwZXI6IElvSGVscGVyLCBjb21tYW5kTGluZUFyZ3VtZW50czogU2V0dGluZ3MpIHtcbiAgICB0aGlzLmlvSGVscGVyID0gaW9IZWxwZXI7XG4gICAgdGhpcy5jb21tYW5kTGluZUFyZ3VtZW50cyA9IGNvbW1hbmRMaW5lQXJndW1lbnRzO1xuICAgIHRoaXMuY29tbWFuZExpbmVDb250ZXh0ID0gdGhpcy5jb21tYW5kTGluZUFyZ3VtZW50c1xuICAgICAgLnN1YlNldHRpbmdzKFtDT05URVhUX0tFWV0pXG4gICAgICAubWFrZVJlYWRPbmx5KCk7XG4gIH1cblxuICBwcml2YXRlIGdldCBwcm9qZWN0Q29uZmlnKCkge1xuICAgIGlmICghdGhpcy5fcHJvamVjdENvbmZpZykge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignQ29uZmlnTm90TG9hZGVkJywgJyNsb2FkIGhhcyBub3QgYmVlbiBjYWxsZWQgeWV0IScpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fcHJvamVjdENvbmZpZztcbiAgfVxuXG4gIHB1YmxpYyBnZXQgcHJvamVjdENvbnRleHQoKSB7XG4gICAgaWYgKCF0aGlzLl9wcm9qZWN0Q29udGV4dCkge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignQ29uZmlnTm90TG9hZGVkJywgJyNsb2FkIGhhcyBub3QgYmVlbiBjYWxsZWQgeWV0IScpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fcHJvamVjdENvbnRleHQ7XG4gIH1cblxuICAvKipcbiAgICogTG9hZCBhbGwgY29uZmlnXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGxvYWRDb25maWdGaWxlcyhyZWFkVXNlckNvbnRleHQ6IGJvb2xlYW4pOiBQcm9taXNlPHRoaXM+IHtcbiAgICBjb25zdCB1c2VyQ29uZmlnID0gYXdhaXQgbG9hZEFuZExvZyh0aGlzLmlvSGVscGVyLCBVU0VSX0RFRkFVTFRTKTtcbiAgICB0aGlzLl9wcm9qZWN0Q29uZmlnID0gYXdhaXQgbG9hZEFuZExvZyh0aGlzLmlvSGVscGVyLCBQUk9KRUNUX0NPTkZJRyk7XG4gICAgdGhpcy5fcHJvamVjdENvbnRleHQgPSBhd2FpdCBsb2FkQW5kTG9nKHRoaXMuaW9IZWxwZXIsIFBST0pFQ1RfQ09OVEVYVCk7XG5cbiAgICBpZiAodXNlckNvbmZpZy5nZXQoWydidWlsZCddKSkge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihcbiAgICAgICAgJ0J1aWxkS2V5SW5Vc2VyQ29uZmlnJyxcbiAgICAgICAgJ1RoZSBgYnVpbGRgIGtleSBjYW5ub3QgYmUgc3BlY2lmaWVkIGluIHRoZSB1c2VyIGNvbmZpZyAofi8uY2RrLmpzb24pLCBzcGVjaWZ5IGl0IGluIHRoZSBwcm9qZWN0IGNvbmZpZyAoY2RrLmpzb24pIGluc3RlYWQnLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb250ZXh0U291cmNlcyA9IFtcbiAgICAgIHsgYmFnOiB0aGlzLmNvbW1hbmRMaW5lQ29udGV4dCB9LFxuICAgICAge1xuICAgICAgICBmaWxlTmFtZTogUFJPSkVDVF9DT05GSUcsXG4gICAgICAgIGJhZzogdGhpcy5wcm9qZWN0Q29uZmlnLnN1YlNldHRpbmdzKFtDT05URVhUX0tFWV0pLm1ha2VSZWFkT25seSgpLFxuICAgICAgfSxcbiAgICAgIHsgZmlsZU5hbWU6IFBST0pFQ1RfQ09OVEVYVCwgYmFnOiB0aGlzLnByb2plY3RDb250ZXh0IH0sXG4gICAgXTtcbiAgICBpZiAocmVhZFVzZXJDb250ZXh0KSB7XG4gICAgICBjb250ZXh0U291cmNlcy5wdXNoKHtcbiAgICAgICAgZmlsZU5hbWU6IFVTRVJfREVGQVVMVFMsXG4gICAgICAgIGJhZzogdXNlckNvbmZpZy5zdWJTZXR0aW5ncyhbQ09OVEVYVF9LRVldKS5tYWtlUmVhZE9ubHkoKSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuY29udGV4dCA9IG5ldyBDb250ZXh0KC4uLmNvbnRleHRTb3VyY2VzKTtcblxuICAgIC8vIEJ1aWxkIHNldHRpbmdzIGZyb20gd2hhdCdzIGxlZnRcbiAgICB0aGlzLnNldHRpbmdzID0gdGhpcy5kZWZhdWx0Q29uZmlnXG4gICAgICAubWVyZ2UodXNlckNvbmZpZylcbiAgICAgIC5tZXJnZSh0aGlzLnByb2plY3RDb25maWcpXG4gICAgICAubWVyZ2UodGhpcy5jb21tYW5kTGluZUFyZ3VtZW50cylcbiAgICAgIC5tYWtlUmVhZE9ubHkoKTtcblxuICAgIGF3YWl0IHRoaXMuaW9IZWxwZXIuZGVmYXVsdHMuZGVidWcoJ21lcmdlZCBzZXR0aW5nczonLCB0aGlzLnNldHRpbmdzLmFsbCk7XG5cbiAgICB0aGlzLmxvYWRlZCA9IHRydWU7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTYXZlIHRoZSBwcm9qZWN0IGNvbnRleHRcbiAgICovXG4gIHB1YmxpYyBhc3luYyBzYXZlQ29udGV4dCgpOiBQcm9taXNlPHRoaXM+IHtcbiAgICBpZiAoIXRoaXMubG9hZGVkKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9IC8vIEF2b2lkIG92ZXJ3cml0aW5nIGZpbGVzIHdpdGggbm90aGluZ1xuXG4gICAgYXdhaXQgdGhpcy5wcm9qZWN0Q29udGV4dC5zYXZlKFBST0pFQ1RfQ09OVEVYVCk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBsb2FkQW5kTG9nKGlvSGVscGVyOiBJb0hlbHBlciwgZmlsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8U2V0dGluZ3M+IHtcbiAgY29uc3QgcmV0ID0gYXdhaXQgc2V0dGluZ3NGcm9tRmlsZShpb0hlbHBlciwgZmlsZU5hbWUpO1xuICBpZiAoIXJldC5lbXB0eSkge1xuICAgIGF3YWl0IGlvSGVscGVyLmRlZmF1bHRzLmRlYnVnKGZpbGVOYW1lICsgJzonLCBKU09OLnN0cmluZ2lmeShyZXQuYWxsLCB1bmRlZmluZWQsIDIpKTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzZXR0aW5nc0Zyb21GaWxlKGlvSGVscGVyOiBJb0hlbHBlciwgZmlsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8U2V0dGluZ3M+IHtcbiAgbGV0IHNldHRpbmdzO1xuICBjb25zdCBleHBhbmRlZCA9IGV4cGFuZEhvbWVEaXIoZmlsZU5hbWUpO1xuICBpZiAoYXdhaXQgZnMucGF0aEV4aXN0cyhleHBhbmRlZCkpIHtcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgZnMucmVhZEpzb24oZXhwYW5kZWQpO1xuICAgIHNldHRpbmdzID0gbmV3IFNldHRpbmdzKGRhdGEpO1xuICB9IGVsc2Uge1xuICAgIHNldHRpbmdzID0gbmV3IFNldHRpbmdzKCk7XG4gIH1cblxuICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2lzc3Vlcy81OVxuICBwcm9oaWJpdENvbnRleHRLZXlzKHNldHRpbmdzLCBbJ2RlZmF1bHQtYWNjb3VudCcsICdkZWZhdWx0LXJlZ2lvbiddLCBmaWxlTmFtZSk7XG4gIGF3YWl0IHdhcm5BYm91dENvbnRleHRLZXkoaW9IZWxwZXIsIHNldHRpbmdzLCAnYXdzOicsIGZpbGVOYW1lKTtcblxuICByZXR1cm4gc2V0dGluZ3M7XG59XG5cbmZ1bmN0aW9uIHByb2hpYml0Q29udGV4dEtleXMoc2V0dGluZ3M6IFNldHRpbmdzLCBrZXlzOiBzdHJpbmdbXSwgZmlsZU5hbWU6IHN0cmluZykge1xuICBjb25zdCBjb250ZXh0ID0gc2V0dGluZ3MuZ2V0KFsnY29udGV4dCddKTtcbiAgaWYgKCFjb250ZXh0IHx8IHR5cGVvZiBjb250ZXh0ICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcbiAgICBpZiAoa2V5IGluIGNvbnRleHQpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoXG4gICAgICAgICdVbnN1cHBvcnRlZENvbnRleHRLZXknLFxuICAgICAgICBgVGhlICdjb250ZXh0LiR7a2V5fScga2V5IHdhcyBmb3VuZCBpbiAke2ZzX3BhdGgucmVzb2x2ZShcbiAgICAgICAgICBmaWxlTmFtZSxcbiAgICAgICAgKX0sIGJ1dCBpdCBpcyBubyBsb25nZXIgc3VwcG9ydGVkLiBQbGVhc2UgcmVtb3ZlIGl0LmAsXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiB3YXJuQWJvdXRDb250ZXh0S2V5KGlvSGVscGVyOiBJb0hlbHBlciwgc2V0dGluZ3M6IFNldHRpbmdzLCBwcmVmaXg6IHN0cmluZywgZmlsZU5hbWU6IHN0cmluZykge1xuICBjb25zdCBjb250ZXh0ID0gc2V0dGluZ3MuZ2V0KFsnY29udGV4dCddKTtcbiAgaWYgKCFjb250ZXh0IHx8IHR5cGVvZiBjb250ZXh0ICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZvciAoY29uc3QgY29udGV4dEtleSBvZiBPYmplY3Qua2V5cyhjb250ZXh0KSkge1xuICAgIGlmIChjb250ZXh0S2V5LnN0YXJ0c1dpdGgocHJlZml4KSkge1xuICAgICAgYXdhaXQgaW9IZWxwZXIuZGVmYXVsdHMud2FybmluZyhcbiAgICAgICAgYEEgcmVzZXJ2ZWQgY29udGV4dCBrZXkgKCdjb250ZXh0LiR7cHJlZml4fScpIGtleSB3YXMgZm91bmQgaW4gJHtmc19wYXRoLnJlc29sdmUoXG4gICAgICAgICAgZmlsZU5hbWUsXG4gICAgICAgICl9LCBpdCBtaWdodCBjYXVzZSBzdXJwcmlzaW5nIGJlaGF2aW9yIGFuZCBzaG91bGQgYmUgcmVtb3ZlZC5gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZXhwYW5kSG9tZURpcih4OiBzdHJpbmcpIHtcbiAgaWYgKHguc3RhcnRzV2l0aCgnficpKSB7XG4gICAgcmV0dXJuIGZzX3BhdGguam9pbihvcy5ob21lZGlyKCksIHguc2xpY2UoMSkpO1xuICB9XG4gIHJldHVybiB4O1xufVxuXG4vKipcbiAqIFBhcnNlIENMSSBhcmd1bWVudHMgaW50byBTZXR0aW5nc1xuICpcbiAqIENMSSBhcmd1bWVudHMgaW4gbXVzdCBiZSBhY2Nlc3NlZCBpbiB0aGUgQ0xJIGNvZGUgdmlhXG4gKiBgY29uZmlndXJhdGlvbi5zZXR0aW5ncy5nZXQoWydhcmdOYW1lJ10pYCBpbnN0ZWFkIG9mIHZpYSBgYXJncy5hcmdOYW1lYC5cbiAqXG4gKiBUaGUgYWR2YW50YWdlIGlzIHRoYXQgdGhleSBjYW4gYmUgY29uZmlndXJlZCB2aWEgYGNkay5qc29uYCBhbmRcbiAqIGAkSE9NRS8uY2RrLmpzb25gLiBBcmd1bWVudHMgbm90IGxpc3RlZCBiZWxvdyBhbmQgYWNjZXNzZWQgdmlhIHRoaXMgb2JqZWN0XG4gKiBjYW4gb25seSBiZSBzcGVjaWZpZWQgb24gdGhlIGNvbW1hbmQgbGluZS5cbiAqXG4gKiBAcGFyYW0gYXJndiAtIHRoZSByZWNlaXZlZCBDTEkgYXJndW1lbnRzLlxuICogQHJldHVybnMgYSBuZXcgU2V0dGluZ3Mgb2JqZWN0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29tbWFuZExpbmVBcmd1bWVudHNUb1NldHRpbmdzKGlvSGVscGVyOiBJb0hlbHBlciwgYXJndjogQXJndW1lbnRzKTogUHJvbWlzZTxTZXR0aW5ncz4ge1xuICBjb25zdCBjb250ZXh0ID0gYXdhaXQgcGFyc2VTdHJpbmdDb250ZXh0TGlzdFRvT2JqZWN0KGlvSGVscGVyLCBhcmd2KTtcbiAgY29uc3QgdGFncyA9IGF3YWl0IHBhcnNlU3RyaW5nVGFnc0xpc3RUb09iamVjdChpb0hlbHBlciwgZXhwZWN0U3RyaW5nTGlzdChhcmd2LnRhZ3MpKTtcblxuICAvLyBEZXRlcm1pbmUgYnVuZGxpbmcgc3RhY2tzXG4gIGxldCBidW5kbGluZ1N0YWNrczogc3RyaW5nW107XG4gIGlmIChCVU5ETElOR19DT01NQU5EUy5pbmNsdWRlcyhhcmd2Ll9bMF0pKSB7XG4gICAgLy8gSWYgd2UgZGVwbG95LCBkaWZmLCBzeW50aCBvciB3YXRjaCBhIGxpc3Qgb2Ygc3RhY2tzIGV4Y2x1c2l2ZWx5IHdlIHNraXBcbiAgICAvLyBidW5kbGluZyBmb3IgYWxsIG90aGVyIHN0YWNrcy5cbiAgICBidW5kbGluZ1N0YWNrcyA9IGFyZ3YuZXhjbHVzaXZlbHkgPyBhcmd2LlNUQUNLUyA/PyBbJyoqJ10gOiBbJyoqJ107XG4gIH0gZWxzZSB7XG4gICAgLy8gU2tpcCBidW5kbGluZyBmb3IgYWxsIHN0YWNrc1xuICAgIGJ1bmRsaW5nU3RhY2tzID0gW107XG4gIH1cblxuICByZXR1cm4gbmV3IFNldHRpbmdzKHtcbiAgICBhcHA6IGFyZ3YuYXBwLFxuICAgIGJyb3dzZXI6IGFyZ3YuYnJvd3NlcixcbiAgICBidWlsZDogYXJndi5idWlsZCxcbiAgICBjYUJ1bmRsZVBhdGg6IGFyZ3YuY2FCdW5kbGVQYXRoLFxuICAgIGNvbnRleHQsXG4gICAgZGVidWc6IGFyZ3YuZGVidWcsXG4gICAgdGFncyxcbiAgICBsYW5ndWFnZTogYXJndi5sYW5ndWFnZSxcbiAgICBwYXRoTWV0YWRhdGE6IGFyZ3YucGF0aE1ldGFkYXRhLFxuICAgIGFzc2V0TWV0YWRhdGE6IGFyZ3YuYXNzZXRNZXRhZGF0YSxcbiAgICBwcm9maWxlOiBhcmd2LnByb2ZpbGUsXG4gICAgcGx1Z2luOiBhcmd2LnBsdWdpbixcbiAgICByZXF1aXJlQXBwcm92YWw6IGFyZ3YucmVxdWlyZUFwcHJvdmFsLFxuICAgIHRvb2xraXRTdGFja05hbWU6IGFyZ3YudG9vbGtpdFN0YWNrTmFtZSxcbiAgICB0b29sa2l0QnVja2V0OiB7XG4gICAgICBidWNrZXROYW1lOiBhcmd2LmJvb3RzdHJhcEJ1Y2tldE5hbWUsXG4gICAgICBrbXNLZXlJZDogYXJndi5ib290c3RyYXBLbXNLZXlJZCxcbiAgICB9LFxuICAgIHZlcnNpb25SZXBvcnRpbmc6IGFyZ3YudmVyc2lvblJlcG9ydGluZyxcbiAgICBzdGFnaW5nOiBhcmd2LnN0YWdpbmcsXG4gICAgb3V0cHV0OiBhcmd2Lm91dHB1dCxcbiAgICBvdXRwdXRzRmlsZTogYXJndi5vdXRwdXRzRmlsZSxcbiAgICBwcm9ncmVzczogYXJndi5wcm9ncmVzcyxcbiAgICBwcm94eTogYXJndi5wcm94eSxcbiAgICBidW5kbGluZ1N0YWNrcyxcbiAgICBsb29rdXBzOiBhcmd2Lmxvb2t1cHMsXG4gICAgcm9sbGJhY2s6IGFyZ3Yucm9sbGJhY2ssXG4gICAgbm90aWNlczogYXJndi5ub3RpY2VzLFxuICAgIGFzc2V0UGFyYWxsZWxpc206IGFyZ3ZbJ2Fzc2V0LXBhcmFsbGVsaXNtJ10sXG4gICAgYXNzZXRCdWlsZENvbmN1cnJlbmN5OiBhcmd2Wydhc3NldC1idWlsZC1jb25jdXJyZW5jeSddLFxuICAgIGFzc2V0UHJlYnVpbGQ6IGFyZ3ZbJ2Fzc2V0LXByZWJ1aWxkJ10sXG4gICAgaWdub3JlTm9TdGFja3M6IGFyZ3ZbJ2lnbm9yZS1uby1zdGFja3MnXSxcbiAgICBob3Rzd2FwOiB7XG4gICAgICBlY3M6IHtcbiAgICAgICAgbWluaW11bUhlYWx0aHlQZXJjZW50OiBhcmd2LmhvdHN3YXBFY3NNaW5pbXVtSGVhbHRoeVBlcmNlbnQsXG4gICAgICAgIG1heGltdW1IZWFsdGh5UGVyY2VudDogYXJndi5ob3Rzd2FwRWNzTWF4aW11bUhlYWx0aHlQZXJjZW50LFxuICAgICAgICBzdGFiaWxpemF0aW9uVGltZW91dFNlY29uZHM6IGFyZ3YuaG90c3dhcEVjc1N0YWJpbGl6YXRpb25UaW1lb3V0U2Vjb25kcyxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB1bnN0YWJsZTogYXJndi51bnN0YWJsZSxcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGV4cGVjdFN0cmluZ0xpc3QoeDogdW5rbm93bik6IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHggPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKCFBcnJheS5pc0FycmF5KHgpKSB7XG4gICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignRXhwZWN0ZWRBcnJheScsIGBFeHBlY3RlZCBhcnJheSwgZ290ICcke3h9J2ApO1xuICB9XG4gIGNvbnN0IG5vblN0cmluZ3MgPSB4LmZpbHRlcigoZSkgPT4gdHlwZW9mIGUgIT09ICdzdHJpbmcnKTtcbiAgaWYgKG5vblN0cmluZ3MubGVuZ3RoID4gMCkge1xuICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ0V4cGVjdGVkU3RyaW5nTGlzdCcsIGBFeHBlY3RlZCBsaXN0IG9mIHN0cmluZ3MsIGZvdW5kICR7bm9uU3RyaW5nc31gKTtcbiAgfVxuICByZXR1cm4geDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcGFyc2VTdHJpbmdDb250ZXh0TGlzdFRvT2JqZWN0KGlvSGVscGVyOiBJb0hlbHBlciwgYXJndjogQXJndW1lbnRzKTogUHJvbWlzZTxhbnk+IHtcbiAgY29uc3QgY29udGV4dDogYW55ID0ge307XG5cbiAgZm9yIChjb25zdCBhc3NpZ25tZW50IG9mIChhcmd2IGFzIGFueSkuY29udGV4dCB8fCBbXSkge1xuICAgIGNvbnN0IHBhcnRzID0gYXNzaWdubWVudC5zcGxpdCgvPSguKikvLCAyKTtcbiAgICBpZiAocGFydHMubGVuZ3RoID09PSAyKSB7XG4gICAgICBhd2FpdCBpb0hlbHBlci5kZWZhdWx0cy5kZWJ1ZygnQ0xJIGFyZ3VtZW50IGNvbnRleHQ6ICVzPSVzJywgcGFydHNbMF0sIHBhcnRzWzFdKTtcbiAgICAgIGlmIChwYXJ0c1swXS5tYXRjaCgvXmF3czouKy8pKSB7XG4gICAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoXG4gICAgICAgICAgJ1Jlc2VydmVkQ29udGV4dFByZWZpeCcsXG4gICAgICAgICAgYFVzZXItcHJvdmlkZWQgY29udGV4dCBjYW5ub3QgdXNlIGtleXMgcHJlZml4ZWQgd2l0aCAnYXdzOicsIGJ1dCAke3BhcnRzWzBdfSB3YXMgcHJvdmlkZWQuYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnRleHRbcGFydHNbMF1dID0gcGFydHNbMV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IGlvSGVscGVyLmRlZmF1bHRzLndhcm4oXG4gICAgICAgICdDb250ZXh0IGFyZ3VtZW50IGlzIG5vdCBhbiBhc3NpZ25tZW50IChrZXk9dmFsdWUpOiAlcycsXG4gICAgICAgIGFzc2lnbm1lbnQsXG4gICAgICApO1xuICAgIH1cbiAgfVxuICByZXR1cm4gY29udGV4dDtcbn1cblxuLyoqXG4gKiBQYXJzZSB0YWdzIG91dCBvZiBhcmd1bWVudHNcbiAqXG4gKiBSZXR1cm4gdW5kZWZpbmVkIGlmIG5vIHRhZ3Mgd2VyZSBwcm92aWRlZCwgcmV0dXJuIGFuIGVtcHR5IGFycmF5IGlmIG9ubHkgZW1wdHlcbiAqIHN0cmluZ3Mgd2VyZSBwcm92aWRlZFxuICovXG5hc3luYyBmdW5jdGlvbiBwYXJzZVN0cmluZ1RhZ3NMaXN0VG9PYmplY3QoXG4gIGlvSGVscGVyOiBJb0hlbHBlcixcbiAgYXJnVGFnczogc3RyaW5nW10gfCB1bmRlZmluZWQsXG4pOiBQcm9taXNlPFRhZ1tdIHwgdW5kZWZpbmVkPiB7XG4gIGlmIChhcmdUYWdzID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGlmIChhcmdUYWdzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3Qgbm9uRW1wdHlUYWdzID0gYXJnVGFncy5maWx0ZXIoKHQpID0+IHQgIT09ICcnKTtcbiAgaWYgKG5vbkVtcHR5VGFncy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCB0YWdzOiBUYWdbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgYXNzaWdubWVudCBvZiBub25FbXB0eVRhZ3MpIHtcbiAgICBjb25zdCBwYXJ0cyA9IGFzc2lnbm1lbnQuc3BsaXQoLz0oLiopLywgMik7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgYXdhaXQgaW9IZWxwZXIuZGVmYXVsdHMuZGVidWcoJ0NMSSBhcmd1bWVudCB0YWdzOiAlcz0lcycsIHBhcnRzWzBdLCBwYXJ0c1sxXSk7XG4gICAgICB0YWdzLnB1c2goe1xuICAgICAgICBLZXk6IHBhcnRzWzBdLFxuICAgICAgICBWYWx1ZTogcGFydHNbMV0sXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgaW9IZWxwZXIuZGVmYXVsdHMud2FybignVGFncyBhcmd1bWVudCBpcyBub3QgYW4gYXNzaWdubWVudCAoa2V5PXZhbHVlKTogJXMnLCBhc3NpZ25tZW50KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRhZ3MubGVuZ3RoID4gMCA/IHRhZ3MgOiB1bmRlZmluZWQ7XG59XG4iXX0=