UNPKG

aws-cdk

Version:

AWS CDK CLI, the command line tool for CDK apps

348 lines 44 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["VALIDATE"] = "validate"; })(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 const mergedSettings = this.defaultConfig .merge(userConfig) .merge(this.projectConfig) .merge(this.commandLineArguments); // Backwards compatibility: a `debug: true` in a config file (cdk.json / ~/.cdk.json) // implies both debug targets, mirroring the `--debug` CLI flag. if (mergedSettings.get(['debug'])) { mergedSettings.set(['debugApp'], true); mergedSettings.set(['debugCli'], true); } this.settings = mergedSettings.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, // The `--debug` implication (both debug targets) is resolved during argument // parsing, so here we only read the resolved per-target flags. debugApp: argv.debugApp, debugCli: argv.debugCli, verbose: argv.verbose, 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1jb25maWd1cmF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidXNlci1jb25maWd1cmF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQXFTQSx3RUE4REM7QUFuV0QseUJBQXlCO0FBQ3pCLGdDQUFnQztBQUNoQyxzREFBb0Q7QUFDcEQsK0JBQStCO0FBQy9CLDRDQUEwRDtBQUMxRCw4Q0FBMkM7QUFJOUIsUUFBQSxjQUFjLEdBQUcsVUFBVSxDQUFDO0FBQ3pDLDBDQUFpRDtBQUF4QywwR0FBQSxlQUFlLE9BQUE7QUFDWCxRQUFBLGFBQWEsR0FBRyxhQUFhLENBQUM7QUFDM0MsTUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDO0FBRTlCLElBQVksT0FnQ1g7QUFoQ0QsV0FBWSxPQUFPO0lBQ2pCLG9CQUFTLENBQUE7SUFDVCx3QkFBYSxDQUFBO0lBQ2Isd0JBQWEsQ0FBQTtJQUNiLGtDQUF1QixDQUFBO0lBQ3ZCLDRCQUFpQixDQUFBO0lBQ2pCLDhCQUFtQixDQUFBO0lBQ25CLG9DQUF5QixDQUFBO0lBQ3pCLDBCQUFlLENBQUE7SUFDZixnQ0FBcUIsQ0FBQTtJQUNyQix3QkFBYSxDQUFBO0lBQ2IsOEJBQW1CLENBQUE7SUFDbkIsMEJBQWUsQ0FBQTtJQUNmLG9CQUFTLENBQUE7SUFDVCwwQkFBZSxDQUFBO0lBQ2YsZ0NBQXFCLENBQUE7SUFDckIsNENBQWlDLENBQUE7SUFDakMsNEJBQWlCLENBQUE7SUFDakIsc0NBQTJCLENBQUE7SUFDM0Isc0JBQVcsQ0FBQTtJQUNYLDhCQUFtQixDQUFBO0lBQ25CLDhCQUFtQixDQUFBO0lBQ25CLDhCQUFtQixDQUFBO0lBQ25CLHdCQUFhLENBQUE7SUFDYixzQkFBVyxDQUFBO0lBQ1gsNEJBQWlCLENBQUE7SUFDakIsNEJBQWlCLENBQUE7SUFDakIsZ0NBQXFCLENBQUE7SUFDckIsMEJBQWUsQ0FBQTtJQUNmLDBDQUErQixDQUFBO0lBQy9CLGdDQUFxQixDQUFBO0lBQ3JCLGdDQUFx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QUUsVUFBVSxDQUFDLENBQUM7UUFDakcsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUM1QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnO1xuaW1wb3J0ICogYXMgZnNfcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IFRvb2xraXRFcnJvciB9IGZyb20gJ0Bhd3MtY2RrL3Rvb2xraXQtbGliJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCB7IENvbnRleHQsIFBST0pFQ1RfQ09OVEVYVCB9IGZyb20gJy4uL2FwaS9jb250ZXh0JztcbmltcG9ydCB7IFNldHRpbmdzIH0gZnJvbSAnLi4vYXBpL3NldHRpbmdzJztcbmltcG9ydCB0eXBlIHsgVGFnIH0gZnJvbSAnLi4vYXBpL3RhZ3MnO1xuaW1wb3J0IHR5cGUgeyBJb0hlbHBlciB9IGZyb20gJy4uL2FwaS1wcml2YXRlJztcblxuZXhwb3J0IGNvbnN0IFBST0pFQ1RfQ09ORklHID0gJ2Nkay5qc29uJztcbmV4cG9ydCB7IFBST0pFQ1RfQ09OVEVYVCB9IGZyb20gJy4uL2FwaS9jb250ZXh0JztcbmV4cG9ydCBjb25zdCBVU0VSX0RFRkFVTFRTID0gJ34vLmNkay5qc29uJztcbmNvbnN0IENPTlRFWFRfS0VZID0gJ2NvbnRleHQnO1xuXG5leHBvcnQgZW51bSBDb21tYW5kIHtcbiAgTFMgPSAnbHMnLFxuICBMSVNUID0gJ2xpc3QnLFxuICBESUZGID0gJ2RpZmYnLFxuICBCT09UU1RSQVAgPSAnYm9vdHN0cmFwJyxcbiAgREVQTE9ZID0gJ2RlcGxveScsXG4gIERFU1RST1kgPSAnZGVzdHJveScsXG4gIFNZTlRIRVNJWkUgPSAnc3ludGhlc2l6ZScsXG4gIFNZTlRIID0gJ3N5bnRoJyxcbiAgTUVUQURBVEEgPSAnbWV0YWRhdGEnLFxuICBJTklUID0gJ2luaXQnLFxuICBWRVJTSU9OID0gJ3ZlcnNpb24nLFxuICBXQVRDSCA9ICd3YXRjaCcsXG4gIEdDID0gJ2djJyxcbiAgRkxBR1MgPSAnZmxhZ3MnLFxuICBST0xMQkFDSyA9ICdyb2xsYmFjaycsXG4gIFBVQkxJU0hfQVNTRVRTID0gJ3B1Ymxpc2gtYXNzZXRzJyxcbiAgSU1QT1JUID0gJ2ltcG9ydCcsXG4gIEFDS05PV0xFREdFID0gJ2Fja25vd2xlZGdlJyxcbiAgQUNLID0gJ2FjaycsXG4gIE5PVElDRVMgPSAnbm90aWNlcycsXG4gIE1JR1JBVEUgPSAnbWlncmF0ZScsXG4gIENPTlRFWFQgPSAnY29udGV4dCcsXG4gIERPQ1MgPSAnZG9jcycsXG4gIERPQyA9ICdkb2MnLFxuICBET0NUT1IgPSAnZG9jdG9yJyxcbiAgT1JQSEFOID0gJ29ycGhhbicsXG4gIFJFRkFDVE9SID0gJ3JlZmFjdG9yJyxcbiAgRFJJRlQgPSAnZHJpZnQnLFxuICBDTElfVEVMRU1FVFJZID0gJ2NsaS10ZWxlbWV0cnknLFxuICBESUFHTk9TRSA9ICdkaWFnbm9zZScsXG4gIFZBTElEQVRFID0gJ3ZhbGlkYXRlJyxcbn1cblxuY29uc3QgQlVORExJTkdfQ09NTUFORFMgPSBbXG4gIENvbW1hbmQuREVQTE9ZLFxuICBDb21tYW5kLkRJRkYsXG4gIENvbW1hbmQuU1lOVEgsXG4gIENvbW1hbmQuU1lOVEhFU0laRSxcbiAgQ29tbWFuZC5XQVRDSCxcbiAgQ29tbWFuZC5JTVBPUlQsXG4gIENvbW1hbmQuUFVCTElTSF9BU1NFVFMsXG5dO1xuXG5leHBvcnQgdHlwZSBBcmd1bWVudHMgPSB7XG4gIHJlYWRvbmx5IF86IFtDb21tYW5kLCAuLi5zdHJpbmdbXV07XG4gIHJlYWRvbmx5IGV4Y2x1c2l2ZWx5PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgU1RBQ0tTPzogc3RyaW5nW107XG4gIHJlYWRvbmx5IGxvb2t1cHM/OiBib29sZWFuO1xuICByZWFkb25seSBbbmFtZTogc3RyaW5nXTogdW5rbm93bjtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29uZmlndXJhdGlvblByb3BzIHtcbiAgLyoqXG4gICAqIENvbmZpZ3VyYXRpb24gcGFzc2VkIHZpYSBjb21tYW5kIGxpbmUgYXJndW1lbnRzXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm90aGluZyBwYXNzZWRcbiAgICovXG4gIHJlYWRvbmx5IGNvbW1hbmRMaW5lQXJndW1lbnRzPzogQXJndW1lbnRzO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIG9yIG5vdCB0byB1c2UgY29udGV4dCBmcm9tIGAuY2RrLmpzb25gIGluIHVzZXIgaG9tZSBkaXJlY3RvcnlcbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgcmVhZFVzZXJDb250ZXh0PzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBBbGwgc291cmNlcyBvZiBzZXR0aW5ncyBjb21iaW5lZFxuICovXG5leHBvcnQgY2xhc3MgQ29uZmlndXJhdGlvbiB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIHVzZXIgY29uZmlndXJhdGlvbiBmcm9tIGNvbW1hbmRMaW5lQXJndW1lbnRzXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGFzeW5jIGZyb21BcmdzKGlvSGVscGVyOiBJb0hlbHBlciwgYXJncz86IEFyZ3VtZW50cykge1xuICAgIGNvbnN0IGNvbW1hbmRMaW5lQXJndW1lbnRzID0gYXJnc1xuICAgICAgPyBhd2FpdCBjb21tYW5kTGluZUFyZ3VtZW50c1RvU2V0dGluZ3MoaW9IZWxwZXIsIGFyZ3MpXG4gICAgICA6IG5ldyBTZXR0aW5ncygpO1xuXG4gICAgcmV0dXJuIG5ldyBDb25maWd1cmF0aW9uKGlvSGVscGVyLCBjb21tYW5kTGluZUFyZ3VtZW50cyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB1c2VyIGNvbmZpZ3VyYXRpb24gZnJvbSBjb21tYW5kTGluZUFyZ3VtZW50cyBhbmQgbG9hZHNcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgZnJvbUFyZ3NBbmRGaWxlcyhpb0hlbHBlcjogSW9IZWxwZXIsIHByb3BzOiBDb25maWd1cmF0aW9uUHJvcHMgPSB7fSkge1xuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPSBhd2FpdCBDb25maWd1cmF0aW9uLmZyb21BcmdzKGlvSGVscGVyLCBwcm9wcy5jb21tYW5kTGluZUFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIGNvbmZpZ3VyYXRpb24ubG9hZENvbmZpZ0ZpbGVzKHByb3BzLnJlYWRVc2VyQ29udGV4dCA/PyB0cnVlKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXR0aW5ncyA9IG5ldyBTZXR0aW5ncygpO1xuICBwdWJsaWMgY29udGV4dCA9IG5ldyBDb250ZXh0KCk7XG5cbiAgcHVibGljIHJlYWRvbmx5IGRlZmF1bHRDb25maWcgPSBuZXcgU2V0dGluZ3Moe1xuICAgIHZlcnNpb25SZXBvcnRpbmc6IHRydWUsXG4gICAgYXNzZXRNZXRhZGF0YTogdHJ1ZSxcbiAgICBwYXRoTWV0YWRhdGE6IHRydWUsXG4gICAgb3V0cHV0OiAnY2RrLm91dCcsXG4gIH0pO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY29tbWFuZExpbmVBcmd1bWVudHM6IFNldHRpbmdzO1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbW1hbmRMaW5lQ29udGV4dDogU2V0dGluZ3M7XG4gIHByaXZhdGUgX3Byb2plY3RDb25maWc/OiBTZXR0aW5ncztcbiAgcHJpdmF0ZSBfcHJvamVjdENvbnRleHQ/OiBTZXR0aW5ncztcbiAgcHJpdmF0ZSBsb2FkZWQgPSBmYWxzZTtcblxuICBwcml2YXRlIGlvSGVscGVyOiBJb0hlbHBlcjtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKGlvSGVscGVyOiBJb0hlbHBlciwgY29tbWFuZExpbmVBcmd1bWVudHM6IFNldHRpbmdzKSB7XG4gICAgdGhpcy5pb0hlbHBlciA9IGlvSGVscGVyO1xuICAgIHRoaXMuY29tbWFuZExpbmVBcmd1bWVudHMgPSBjb21tYW5kTGluZUFyZ3VtZW50cztcbiAgICB0aGlzLmNvbW1hbmRMaW5lQ29udGV4dCA9IHRoaXMuY29tbWFuZExpbmVBcmd1bWVudHNcbiAgICAgIC5zdWJTZXR0aW5ncyhbQ09OVEVYVF9LRVldKVxuICAgICAgLm1ha2VSZWFkT25seSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgcHJvamVjdENvbmZpZygpIHtcbiAgICBpZiAoIXRoaXMuX3Byb2plY3RDb25maWcpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ0NvbmZpZ05vdExvYWRlZCcsICcjbG9hZCBoYXMgbm90IGJlZW4gY2FsbGVkIHlldCEnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3Byb2plY3RDb25maWc7XG4gIH1cblxuICBwdWJsaWMgZ2V0IHByb2plY3RDb250ZXh0KCkge1xuICAgIGlmICghdGhpcy5fcHJvamVjdENvbnRleHQpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ0NvbmZpZ05vdExvYWRlZCcsICcjbG9hZCBoYXMgbm90IGJlZW4gY2FsbGVkIHlldCEnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3Byb2plY3RDb250ZXh0O1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgYWxsIGNvbmZpZ1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBsb2FkQ29uZmlnRmlsZXMocmVhZFVzZXJDb250ZXh0OiBib29sZWFuKTogUHJvbWlzZTx0aGlzPiB7XG4gICAgY29uc3QgdXNlckNvbmZpZyA9IGF3YWl0IGxvYWRBbmRMb2codGhpcy5pb0hlbHBlciwgVVNFUl9ERUZBVUxUUyk7XG4gICAgdGhpcy5fcHJvamVjdENvbmZpZyA9IGF3YWl0IGxvYWRBbmRMb2codGhpcy5pb0hlbHBlciwgUFJPSkVDVF9DT05GSUcpO1xuICAgIHRoaXMuX3Byb2plY3RDb250ZXh0ID0gYXdhaXQgbG9hZEFuZExvZyh0aGlzLmlvSGVscGVyLCBQUk9KRUNUX0NPTlRFWFQpO1xuXG4gICAgaWYgKHVzZXJDb25maWcuZ2V0KFsnYnVpbGQnXSkpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoXG4gICAgICAgICdCdWlsZEtleUluVXNlckNvbmZpZycsXG4gICAgICAgICdUaGUgYGJ1aWxkYCBrZXkgY2Fubm90IGJlIHNwZWNpZmllZCBpbiB0aGUgdXNlciBjb25maWcgKH4vLmNkay5qc29uKSwgc3BlY2lmeSBpdCBpbiB0aGUgcHJvamVjdCBjb25maWcgKGNkay5qc29uKSBpbnN0ZWFkJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgY29udGV4dFNvdXJjZXMgPSBbXG4gICAgICB7IGJhZzogdGhpcy5jb21tYW5kTGluZUNvbnRleHQgfSxcbiAgICAgIHtcbiAgICAgICAgZmlsZU5hbWU6IFBST0pFQ1RfQ09ORklHLFxuICAgICAgICBiYWc6IHRoaXMucHJvamVjdENvbmZpZy5zdWJTZXR0aW5ncyhbQ09OVEVYVF9LRVldKS5tYWtlUmVhZE9ubHkoKSxcbiAgICAgIH0sXG4gICAgICB7IGZpbGVOYW1lOiBQUk9KRUNUX0NPTlRFWFQsIGJhZzogdGhpcy5wcm9qZWN0Q29udGV4dCB9LFxuICAgIF07XG4gICAgaWYgKHJlYWRVc2VyQ29udGV4dCkge1xuICAgICAgY29udGV4dFNvdXJjZXMucHVzaCh7XG4gICAgICAgIGZpbGVOYW1lOiBVU0VSX0RFRkFVTFRTLFxuICAgICAgICBiYWc6IHVzZXJDb25maWcuc3ViU2V0dGluZ3MoW0NPTlRFWFRfS0VZXSkubWFrZVJlYWRPbmx5KCksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmNvbnRleHQgPSBuZXcgQ29udGV4dCguLi5jb250ZXh0U291cmNlcyk7XG5cbiAgICAvLyBCdWlsZCBzZXR0aW5ncyBmcm9tIHdoYXQncyBsZWZ0XG4gICAgY29uc3QgbWVyZ2VkU2V0dGluZ3MgPSB0aGlzLmRlZmF1bHRDb25maWdcbiAgICAgIC5tZXJnZSh1c2VyQ29uZmlnKVxuICAgICAgLm1lcmdlKHRoaXMucHJvamVjdENvbmZpZylcbiAgICAgIC5tZXJnZSh0aGlzLmNvbW1hbmRMaW5lQXJndW1lbnRzKTtcblxuICAgIC8vIEJhY2t3YXJkcyBjb21wYXRpYmlsaXR5OiBhIGBkZWJ1ZzogdHJ1ZWAgaW4gYSBjb25maWcgZmlsZSAoY2RrLmpzb24gLyB+Ly5jZGsuanNvbilcbiAgICAvLyBpbXBsaWVzIGJvdGggZGVidWcgdGFyZ2V0cywgbWlycm9yaW5nIHRoZSBgLS1kZWJ1Z2AgQ0xJIGZsYWcuXG4gICAgaWYgKG1lcmdlZFNldHRpbmdzLmdldChbJ2RlYnVnJ10pKSB7XG4gICAgICBtZXJnZWRTZXR0aW5ncy5zZXQoWydkZWJ1Z0FwcCddLCB0cnVlKTtcbiAgICAgIG1lcmdlZFNldHRpbmdzLnNldChbJ2RlYnVnQ2xpJ10sIHRydWUpO1xuICAgIH1cblxuICAgIHRoaXMuc2V0dGluZ3MgPSBtZXJnZWRTZXR0aW5ncy5tYWtlUmVhZE9ubHkoKTtcblxuICAgIGF3YWl0IHRoaXMuaW9IZWxwZXIuZGVmYXVsdHMuZGVidWcoJ21lcmdlZCBzZXR0aW5nczonLCB0aGlzLnNldHRpbmdzLmFsbCk7XG5cbiAgICB0aGlzLmxvYWRlZCA9IHRydWU7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTYXZlIHRoZSBwcm9qZWN0IGNvbnRleHRcbiAgICovXG4gIHB1YmxpYyBhc3luYyBzYXZlQ29udGV4dCgpOiBQcm9taXNlPHRoaXM+IHtcbiAgICBpZiAoIXRoaXMubG9hZGVkKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9IC8vIEF2b2lkIG92ZXJ3cml0aW5nIGZpbGVzIHdpdGggbm90aGluZ1xuXG4gICAgYXdhaXQgdGhpcy5wcm9qZWN0Q29udGV4dC5zYXZlKFBST0pFQ1RfQ09OVEVYVCk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBsb2FkQW5kTG9nKGlvSGVscGVyOiBJb0hlbHBlciwgZmlsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8U2V0dGluZ3M+IHtcbiAgY29uc3QgcmV0ID0gYXdhaXQgc2V0dGluZ3NGcm9tRmlsZShpb0hlbHBlciwgZmlsZU5hbWUpO1xuICBpZiAoIXJldC5lbXB0eSkge1xuICAgIGF3YWl0IGlvSGVscGVyLmRlZmF1bHRzLmRlYnVnKGZpbGVOYW1lICsgJzonLCBKU09OLnN0cmluZ2lmeShyZXQuYWxsLCB1bmRlZmluZWQsIDIpKTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzZXR0aW5nc0Zyb21GaWxlKGlvSGVscGVyOiBJb0hlbHBlciwgZmlsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8U2V0dGluZ3M+IHtcbiAgbGV0IHNldHRpbmdzO1xuICBjb25zdCBleHBhbmRlZCA9IGV4cGFuZEhvbWVEaXIoZmlsZU5hbWUpO1xuICBpZiAoYXdhaXQgZnMucGF0aEV4aXN0cyhleHBhbmRlZCkpIHtcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgZnMucmVhZEpzb24oZXhwYW5kZWQpO1xuICAgIHNldHRpbmdzID0gbmV3IFNldHRpbmdzKGRhdGEpO1xuICB9IGVsc2Uge1xuICAgIHNldHRpbmdzID0gbmV3IFNldHRpbmdzKCk7XG4gIH1cblxuICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2lzc3Vlcy81OVxuICBwcm9oaWJpdENvbnRleHRLZXlzKHNldHRpbmdzLCBbJ2RlZmF1bHQtYWNjb3VudCcsICdkZWZhdWx0LXJlZ2lvbiddLCBmaWxlTmFtZSk7XG4gIGF3YWl0IHdhcm5BYm91dENvbnRleHRLZXkoaW9IZWxwZXIsIHNldHRpbmdzLCAnYXdzOicsIGZpbGVOYW1lKTtcblxuICByZXR1cm4gc2V0dGluZ3M7XG59XG5cbmZ1bmN0aW9uIHByb2hpYml0Q29udGV4dEtleXMoc2V0dGluZ3M6IFNldHRpbmdzLCBrZXlzOiBzdHJpbmdbXSwgZmlsZU5hbWU6IHN0cmluZykge1xuICBjb25zdCBjb250ZXh0ID0gc2V0dGluZ3MuZ2V0KFsnY29udGV4dCddKTtcbiAgaWYgKCFjb250ZXh0IHx8IHR5cGVvZiBjb250ZXh0ICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcbiAgICBpZiAoa2V5IGluIGNvbnRleHQpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoXG4gICAgICAgICdVbnN1cHBvcnRlZENvbnRleHRLZXknLFxuICAgICAgICBgVGhlICdjb250ZXh0LiR7a2V5fScga2V5IHdhcyBmb3VuZCBpbiAke2ZzX3BhdGgucmVzb2x2ZShcbiAgICAgICAgICBmaWxlTmFtZSxcbiAgICAgICAgKX0sIGJ1dCBpdCBpcyBubyBsb25nZXIgc3VwcG9ydGVkLiBQbGVhc2UgcmVtb3ZlIGl0LmAsXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiB3YXJuQWJvdXRDb250ZXh0S2V5KGlvSGVscGVyOiBJb0hlbHBlciwgc2V0dGluZ3M6IFNldHRpbmdzLCBwcmVmaXg6IHN0cmluZywgZmlsZU5hbWU6IHN0cmluZykge1xuICBjb25zdCBjb250ZXh0ID0gc2V0dGluZ3MuZ2V0KFsnY29udGV4dCddKTtcbiAgaWYgKCFjb250ZXh0IHx8IHR5cGVvZiBjb250ZXh0ICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZvciAoY29uc3QgY29udGV4dEtleSBvZiBPYmplY3Qua2V5cyhjb250ZXh0KSkge1xuICAgIGlmIChjb250ZXh0S2V5LnN0YXJ0c1dpdGgocHJlZml4KSkge1xuICAgICAgYXdhaXQgaW9IZWxwZXIuZGVmYXVsdHMud2FybmluZyhcbiAgICAgICAgYEEgcmVzZXJ2ZWQgY29udGV4dCBrZXkgKCdjb250ZXh0LiR7cHJlZml4fScpIGtleSB3YXMgZm91bmQgaW4gJHtmc19wYXRoLnJlc29sdmUoXG4gICAgICAgICAgZmlsZU5hbWUsXG4gICAgICAgICl9LCBpdCBtaWdodCBjYXVzZSBzdXJwcmlzaW5nIGJlaGF2aW9yIGFuZCBzaG91bGQgYmUgcmVtb3ZlZC5gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZXhwYW5kSG9tZURpcih4OiBzdHJpbmcpIHtcbiAgaWYgKHguc3RhcnRzV2l0aCgnficpKSB7XG4gICAgcmV0dXJuIGZzX3BhdGguam9pbihvcy5ob21lZGlyKCksIHguc2xpY2UoMSkpO1xuICB9XG4gIHJldHVybiB4O1xufVxuXG4vKipcbiAqIFBhcnNlIENMSSBhcmd1bWVudHMgaW50byBTZXR0aW5nc1xuICpcbiAqIENMSSBhcmd1bWVudHMgaW4gbXVzdCBiZSBhY2Nlc3NlZCBpbiB0aGUgQ0xJIGNvZGUgdmlhXG4gKiBgY29uZmlndXJhdGlvbi5zZXR0aW5ncy5nZXQoWydhcmdOYW1lJ10pYCBpbnN0ZWFkIG9mIHZpYSBgYXJncy5hcmdOYW1lYC5cbiAqXG4gKiBUaGUgYWR2YW50YWdlIGlzIHRoYXQgdGhleSBjYW4gYmUgY29uZmlndXJlZCB2aWEgYGNkay5qc29uYCBhbmRcbiAqIGAkSE9NRS8uY2RrLmpzb25gLiBBcmd1bWVudHMgbm90IGxpc3RlZCBiZWxvdyBhbmQgYWNjZXNzZWQgdmlhIHRoaXMgb2JqZWN0XG4gKiBjYW4gb25seSBiZSBzcGVjaWZpZWQgb24gdGhlIGNvbW1hbmQgbGluZS5cbiAqXG4gKiBAcGFyYW0gYXJndiAtIHRoZSByZWNlaXZlZCBDTEkgYXJndW1lbnRzLlxuICogQHJldHVybnMgYSBuZXcgU2V0dGluZ3Mgb2JqZWN0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29tbWFuZExpbmVBcmd1bWVudHNUb1NldHRpbmdzKGlvSGVscGVyOiBJb0hlbHBlciwgYXJndjogQXJndW1lbnRzKTogUHJvbWlzZTxTZXR0aW5ncz4ge1xuICBjb25zdCBjb250ZXh0ID0gYXdhaXQgcGFyc2VTdHJpbmdDb250ZXh0TGlzdFRvT2JqZWN0KGlvSGVscGVyLCBhcmd2KTtcbiAgY29uc3QgdGFncyA9IGF3YWl0IHBhcnNlU3RyaW5nVGFnc0xpc3RUb09iamVjdChpb0hlbHBlciwgZXhwZWN0U3RyaW5nTGlzdChhcmd2LnRhZ3MpKTtcblxuICAvLyBEZXRlcm1pbmUgYnVuZGxpbmcgc3RhY2tzXG4gIGxldCBidW5kbGluZ1N0YWNrczogc3RyaW5nW107XG4gIGlmIChCVU5ETElOR19DT01NQU5EUy5pbmNsdWRlcyhhcmd2Ll9bMF0pKSB7XG4gICAgLy8gSWYgd2UgZGVwbG95LCBkaWZmLCBzeW50aCBvciB3YXRjaCBhIGxpc3Qgb2Ygc3RhY2tzIGV4Y2x1c2l2ZWx5IHdlIHNraXBcbiAgICAvLyBidW5kbGluZyBmb3IgYWxsIG90aGVyIHN0YWNrcy5cbiAgICBidW5kbGluZ1N0YWNrcyA9IGFyZ3YuZXhjbHVzaXZlbHkgPyBhcmd2LlNUQUNLUyA/PyBbJyoqJ10gOiBbJyoqJ107XG4gIH0gZWxzZSB7XG4gICAgLy8gU2tpcCBidW5kbGluZyBmb3IgYWxsIHN0YWNrc1xuICAgIGJ1bmRsaW5nU3RhY2tzID0gW107XG4gIH1cblxuICByZXR1cm4gbmV3IFNldHRpbmdzKHtcbiAgICBhcHA6IGFyZ3YuYXBwLFxuICAgIGJyb3dzZXI6IGFyZ3YuYnJvd3NlcixcbiAgICBidWlsZDogYXJndi5idWlsZCxcbiAgICBjYUJ1bmRsZVBhdGg6IGFyZ3YuY2FCdW5kbGVQYXRoLFxuICAgIGNvbnRleHQsXG4gICAgLy8gVGhlIGAtLWRlYnVnYCBpbXBsaWNhdGlvbiAoYm90aCBkZWJ1ZyB0YXJnZXRzKSBpcyByZXNvbHZlZCBkdXJpbmcgYXJndW1lbnRcbiAgICAvLyBwYXJzaW5nLCBzbyBoZXJlIHdlIG9ubHkgcmVhZCB0aGUgcmVzb2x2ZWQgcGVyLXRhcmdldCBmbGFncy5cbiAgICBkZWJ1Z0FwcDogYXJndi5kZWJ1Z0FwcCxcbiAgICBkZWJ1Z0NsaTogYXJndi5kZWJ1Z0NsaSxcbiAgICB2ZXJib3NlOiBhcmd2LnZlcmJvc2UsXG4gICAgdGFncyxcbiAgICBsYW5ndWFnZTogYXJndi5sYW5ndWFnZSxcbiAgICBwYXRoTWV0YWRhdGE6IGFyZ3YucGF0aE1ldGFkYXRhLFxuICAgIGFzc2V0TWV0YWRhdGE6IGFyZ3YuYXNzZXRNZXRhZGF0YSxcbiAgICBwcm9maWxlOiBhcmd2LnByb2ZpbGUsXG4gICAgcmVnaW9uOiBhcmd2LnJlZ2lvbixcbiAgICBwbHVnaW46IGFyZ3YucGx1Z2luLFxuICAgIHJlcXVpcmVBcHByb3ZhbDogYXJndi5yZXF1aXJlQXBwcm92YWwsXG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYXJndi50b29sa2l0U3RhY2tOYW1lLFxuICAgIHRvb2xraXRCdWNrZXQ6IHtcbiAgICAgIGJ1Y2tldE5hbWU6IGFyZ3YuYm9vdHN0cmFwQnVja2V0TmFtZSxcbiAgICAgIGttc0tleUlkOiBhcmd2LmJvb3RzdHJhcEttc0tleUlkLFxuICAgIH0sXG4gICAgdmVyc2lvblJlcG9ydGluZzogYXJndi52ZXJzaW9uUmVwb3J0aW5nLFxuICAgIHN0YWdpbmc6IGFyZ3Yuc3RhZ2luZyxcbiAgICBvdXRwdXQ6IGFyZ3Yub3V0cHV0LFxuICAgIG91dHB1dHNGaWxlOiBhcmd2Lm91dHB1dHNGaWxlLFxuICAgIHByb2dyZXNzOiBhcmd2LnByb2dyZXNzLFxuICAgIHByb3h5OiBhcmd2LnByb3h5LFxuICAgIGJ1bmRsaW5nU3RhY2tzLFxuICAgIGxvb2t1cHM6IGFyZ3YubG9va3VwcyxcbiAgICByb2xsYmFjazogYXJndi5yb2xsYmFjayxcbiAgICBub3RpY2VzOiBhcmd2Lm5vdGljZXMsXG4gICAgYXNzZXRQYXJhbGxlbGlzbTogYXJndlsnYXNzZXQtcGFyYWxsZWxpc20nXSxcbiAgICBhc3NldEJ1aWxkQ29uY3VycmVuY3k6IGFyZ3ZbJ2Fzc2V0LWJ1aWxkLWNvbmN1cnJlbmN5J10sXG4gICAgYXNzZXRQcmVidWlsZDogYXJndlsnYXNzZXQtcHJlYnVpbGQnXSxcbiAgICBpZ25vcmVOb1N0YWNrczogYXJndlsnaWdub3JlLW5vLXN0YWNrcyddLFxuICAgIGhvdHN3YXA6IHtcbiAgICAgIGVjczoge1xuICAgICAgICBtaW5pbXVtSGVhbHRoeVBlcmNlbnQ6IGFyZ3YuaG90c3dhcEVjc01pbmltdW1IZWFsdGh5UGVyY2VudCxcbiAgICAgICAgbWF4aW11bUhlYWx0aHlQZXJjZW50OiBhcmd2LmhvdHN3YXBFY3NNYXhpbXVtSGVhbHRoeVBlcmNlbnQsXG4gICAgICAgIHN0YWJpbGl6YXRpb25UaW1lb3V0U2Vjb25kczogYXJndi5ob3Rzd2FwRWNzU3RhYmlsaXphdGlvblRpbWVvdXRTZWNvbmRzLFxuICAgICAgfSxcbiAgICB9LFxuICAgIHVuc3RhYmxlOiBhcmd2LnVuc3RhYmxlLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gZXhwZWN0U3RyaW5nTGlzdCh4OiB1bmtub3duKTogc3RyaW5nW10gfCB1bmRlZmluZWQge1xuICBpZiAoeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAoIUFycmF5LmlzQXJyYXkoeCkpIHtcbiAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKCdFeHBlY3RlZEFycmF5JywgYEV4cGVjdGVkIGFycmF5LCBnb3QgJyR7eH0nYCk7XG4gIH1cbiAgY29uc3Qgbm9uU3RyaW5ncyA9IHguZmlsdGVyKChlKSA9PiB0eXBlb2YgZSAhPT0gJ3N0cmluZycpO1xuICBpZiAobm9uU3RyaW5ncy5sZW5ndGggPiAwKSB7XG4gICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignRXhwZWN0ZWRTdHJpbmdMaXN0JywgYEV4cGVjdGVkIGxpc3Qgb2Ygc3RyaW5ncywgZm91bmQgJHtub25TdHJpbmdzfWApO1xuICB9XG4gIHJldHVybiB4O1xufVxuXG5hc3luYyBmdW5jdGlvbiBwYXJzZVN0cmluZ0NvbnRleHRMaXN0VG9PYmplY3QoaW9IZWxwZXI6IElvSGVscGVyLCBhcmd2OiBBcmd1bWVudHMpOiBQcm9taXNlPGFueT4ge1xuICBjb25zdCBjb250ZXh0OiBhbnkgPSB7fTtcblxuICBmb3IgKGNvbnN0IGFzc2lnbm1lbnQgb2YgKGFyZ3YgYXMgYW55KS5jb250ZXh0IHx8IFtdKSB7XG4gICAgY29uc3QgcGFydHMgPSBhc3NpZ25tZW50LnNwbGl0KC89KC4qKS8sIDIpO1xuICAgIGlmIChwYXJ0cy5sZW5ndGggPT09IDIpIHtcbiAgICAgIGF3YWl0IGlvSGVscGVyLmRlZmF1bHRzLmRlYnVnKCdDTEkgYXJndW1lbnQgY29udGV4dDogJXM9JXMnLCBwYXJ0c1swXSwgcGFydHNbMV0pO1xuICAgICAgaWYgKHBhcnRzWzBdLm1hdGNoKC9eYXdzOi4rLykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihcbiAgICAgICAgICAnUmVzZXJ2ZWRDb250ZXh0UHJlZml4JyxcbiAgICAgICAgICBgVXNlci1wcm92aWRlZCBjb250ZXh0IGNhbm5vdCB1c2Uga2V5cyBwcmVmaXhlZCB3aXRoICdhd3M6JywgYnV0ICR7cGFydHNbMF19IHdhcyBwcm92aWRlZC5gLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgY29udGV4dFtwYXJ0c1swXV0gPSBwYXJ0c1sxXTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgaW9IZWxwZXIuZGVmYXVsdHMud2FybihcbiAgICAgICAgJ0NvbnRleHQgYXJndW1lbnQgaXMgbm90IGFuIGFzc2lnbm1lbnQgKGtleT12YWx1ZSk6ICVzJyxcbiAgICAgICAgYXNzaWdubWVudCxcbiAgICAgICk7XG4gICAgfVxuICB9XG4gIHJldHVybiBjb250ZXh0O1xufVxuXG4vKipcbiAqIFBhcnNlIHRhZ3Mgb3V0IG9mIGFyZ3VtZW50c1xuICpcbiAqIFJldHVybiB1bmRlZmluZWQgaWYgbm8gdGFncyB3ZXJlIHByb3ZpZGVkLCByZXR1cm4gYW4gZW1wdHkgYXJyYXkgaWYgb25seSBlbXB0eVxuICogc3RyaW5ncyB3ZXJlIHByb3ZpZGVkXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHBhcnNlU3RyaW5nVGFnc0xpc3RUb09iamVjdChcbiAgaW9IZWxwZXI6IElvSGVscGVyLFxuICBhcmdUYWdzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZCxcbik6IFByb21pc2U8VGFnW10gfCB1bmRlZmluZWQ+IHtcbiAgaWYgKGFyZ1RhZ3MgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKGFyZ1RhZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBub25FbXB0eVRhZ3MgPSBhcmdUYWdzLmZpbHRlcigodCkgPT4gdCAhPT0gJycpO1xuICBpZiAobm9uRW1wdHlUYWdzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHRhZ3M6IFRhZ1tdID0gW107XG5cbiAgZm9yIChjb25zdCBhc3NpZ25tZW50IG9mIG5vbkVtcHR5VGFncykge1xuICAgIGNvbnN0IHBhcnRzID0gYXNzaWdubWVudC5zcGxpdCgvPSguKikvLCAyKTtcbiAgICBpZiAocGFydHMubGVuZ3RoID09PSAyKSB7XG4gICAgICBhd2FpdCBpb0hlbHBlci5kZWZhdWx0cy5kZWJ1ZygnQ0xJIGFyZ3VtZW50IHRhZ3M6ICVzPSVzJywgcGFydHNbMF0sIHBhcnRzWzFdKTtcbiAgICAgIHRhZ3MucHVzaCh7XG4gICAgICAgIEtleTogcGFydHNbMF0sXG4gICAgICAgIFZhbHVlOiBwYXJ0c1sxXSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCBpb0hlbHBlci5kZWZhdWx0cy53YXJuKCdUYWdzIGFyZ3VtZW50IGlzIG5vdCBhbiBhc3NpZ25tZW50IChrZXk9dmFsdWUpOiAlcycsIGFzc2lnbm1lbnQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGFncy5sZW5ndGggPiAwID8gdGFncyA6IHVuZGVmaW5lZDtcbn1cbiJdfQ==