cdk8s-cli
Version:
This is the command line tool for Cloud Development Kit (CDK) for Kubernetes (cdk8s).
188 lines • 33.4 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (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 __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 __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const os = __importStar(require("os"));
const path_1 = __importDefault(require("path"));
const fs = __importStar(require("fs-extra"));
const semver = __importStar(require("semver"));
const sscaff_1 = require("sscaff");
const yaml = __importStar(require("yaml"));
const config_1 = require("../../config");
const dispatch_1 = require("../../import/dispatch");
const _manager_1 = require("../../plugins/_manager");
const util_1 = require("../../util");
const CHART_YAML_FILE = 'Chart.yaml';
const README = 'README.md';
const DEFAULT_OUTPUT_DIR = 'dist';
const DEFAULT_PLUGINS_DIR = path_1.default.join(os.homedir(), '.cdk8s', 'plugins');
const config = (0, config_1.readConfigSync)();
class Command {
constructor() {
this.command = 'synth';
this.describe = 'Synthesizes Kubernetes manifests for all charts in your app.';
this.aliases = ['synthesize'];
this.builder = (args) => args
.option('app', { required: true, default: config === null || config === void 0 ? void 0 : config.app, desc: 'Command to use in order to execute cdk8s app', alias: 'a' })
.option('output', { required: false, desc: 'Output directory', alias: 'o' })
.option('stdout', { type: 'boolean', required: false, desc: 'Write synthesized manifests to STDOUT instead of the output directory', alias: 'p' })
.option('plugins-dir', { required: false, desc: 'Directory to store cdk8s plugins.' })
.option('validate', { type: 'boolean', required: false, desc: 'Apply validation plugins on the resulting manifests (use --no-validate to disable)' })
.option('validation-reports-output-file', { required: false, desc: 'File to write a JSON representation of the validation reports to' })
.option('format', { required: false, desc: 'Synthesis format for Kubernetes manifests. The default synthesis format is plain kubernetes manifests.', type: 'string' })
.option('chart-api-version', { required: false, desc: 'Chart API version of helm chart. The default value would be \'v2\' api version when synthesis format is helm. There is no default set when synthesis format is plain.', type: 'string' })
.option('chart-version', { required: false, desc: 'Chart version of helm chart. This is required if synthesis format is helm.' });
}
async handler(argv) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
const command = argv.app;
const stdout = argv.stdout;
const outdir = (_b = (_a = argv.output) !== null && _a !== void 0 ? _a : config === null || config === void 0 ? void 0 : config.output) !== null && _b !== void 0 ? _b : (!stdout ? DEFAULT_OUTPUT_DIR : undefined);
const validate = (_c = argv.validate) !== null && _c !== void 0 ? _c : true;
const reportFile = argv.validationReportsOutputFile;
const pluginsDir = (_e = (_d = argv.pluginsDir) !== null && _d !== void 0 ? _d : config === null || config === void 0 ? void 0 : config.pluginsDirectory) !== null && _e !== void 0 ? _e : DEFAULT_PLUGINS_DIR;
const format = (_h = (_f = argv.format) !== null && _f !== void 0 ? _f : (_g = config === null || config === void 0 ? void 0 : config.synthConfig) === null || _g === void 0 ? void 0 : _g.format) !== null && _h !== void 0 ? _h : config_1.SynthesisFormat.PLAIN;
const chartVersion = (_j = argv.chartVersion) !== null && _j !== void 0 ? _j : (_k = config === null || config === void 0 ? void 0 : config.synthConfig) === null || _k === void 0 ? void 0 : _k.chartVersion;
const chartApiVersion = (_o = (_l = argv.chartApiVersion) !== null && _l !== void 0 ? _l : (_m = config === null || config === void 0 ? void 0 : config.synthConfig) === null || _m === void 0 ? void 0 : _m.chartApiVersion) !== null && _o !== void 0 ? _o : getDefaultChartApiVersion(format);
if (outdir && outdir !== (config === null || config === void 0 ? void 0 : config.output) && stdout) {
throw new Error('\'--output\' and \'--stdout\' are mutually exclusive. Please only use one.');
}
if (outdir) {
fs.rmSync(outdir, { recursive: true, force: true });
}
if (format != config_1.SynthesisFormat.PLAIN && format != config_1.SynthesisFormat.HELM) {
throw new Error(`You need to specify synthesis format either as ${config_1.SynthesisFormat.PLAIN} or ${config_1.SynthesisFormat.HELM} but received: ${format}`);
}
if (chartApiVersion && (chartApiVersion != config_1.HelmChartApiVersion.V1 && chartApiVersion != config_1.HelmChartApiVersion.V2)) {
throw new Error(`You need to specify helm chart api version either as ${config_1.HelmChartApiVersion.V1} or ${config_1.HelmChartApiVersion.V2} but received: ${chartApiVersion}`);
}
if (format === config_1.SynthesisFormat.HELM && !chartVersion) {
throw new Error('You need to specify \'--chart-version\' when \'--format\' is set as \'helm\'.');
}
if (chartVersion && !semver.valid(chartVersion)) {
throw new Error(`The value specified for '--chart-version': ${chartVersion} does not follow SemVer-2(https://semver.org/).`);
}
if (stdout && format === config_1.SynthesisFormat.HELM) {
throw new Error('Helm format synthesis does not support \'stdout\'. Please use \'outdir\' instead.');
}
if (format === config_1.SynthesisFormat.PLAIN && chartApiVersion) {
throw new Error('You need to specify \'--format\' as \'helm\' when \'--chart-api-version\' is set.');
}
if (format === config_1.SynthesisFormat.PLAIN && chartVersion) {
throw new Error('You need to specify \'--format\' as \'helm\' when \'--chart-version\' is set.');
}
if (chartApiVersion === config_1.HelmChartApiVersion.V1 && (0, util_1.crdsArePresent)(config === null || config === void 0 ? void 0 : config.imports)) {
throw new Error(`Your application uses CRDs, which are not supported when '--chart-api-version' is set to ${config_1.HelmChartApiVersion.V1}. Please either set '--chart-api-version' to ${config_1.HelmChartApiVersion.V2}, or remove the CRDs from your cdk8s.yaml configuration file`);
}
const validations = validate ? await fetchValidations() : undefined;
const recordConstructMetadata = !(validations == undefined || validations.length == 0);
if (stdout) {
await (0, util_1.mkdtemp)(async (tempDir) => {
const app = await (0, util_1.synthApp)(command, tempDir, stdout, recordConstructMetadata);
for (const f of app.manifests) {
fs.createReadStream(f).pipe(process.stdout);
}
if (validations) {
const pluginManager = new _manager_1.PluginManager(pluginsDir);
await (0, util_1.validateApp)(app, stdout, validations, pluginManager, reportFile);
}
});
}
else {
let manifests;
if (format === config_1.SynthesisFormat.HELM) {
await createHelmScaffolding(chartApiVersion, chartVersion, outdir);
const templateDir = path_1.default.join(outdir, 'templates');
manifests = await (0, util_1.synthApp)(command, templateDir, stdout, recordConstructMetadata);
}
else {
manifests = await (0, util_1.synthApp)(command, outdir, stdout, recordConstructMetadata);
}
if (validations) {
const pluginManager = new _manager_1.PluginManager(pluginsDir);
await (0, util_1.validateApp)(manifests, stdout, validations, pluginManager, reportFile);
}
}
}
}
async function fetchValidations() {
if (typeof (config === null || config === void 0 ? void 0 : config.validations) === 'string') {
const content = await (0, util_1.download)(config.validations);
return yaml.parse(content);
}
else {
return config === null || config === void 0 ? void 0 : config.validations;
}
}
async function createHelmScaffolding(apiVersion, chartVersion, outdir) {
const tempHelmStructure = createFolderStructure();
const substituteValues = {
apiVersion: apiVersion,
version: chartVersion,
app: path_1.default.basename(path_1.default.resolve()),
};
try {
await (0, sscaff_1.sscaff)(tempHelmStructure, outdir, substituteValues);
}
finally {
fs.rmSync(tempHelmStructure, { recursive: true });
}
if (apiVersion === config_1.HelmChartApiVersion.V2 && (0, util_1.crdsArePresent)(config === null || config === void 0 ? void 0 : config.imports)) {
await addCrdsToHelmChart(outdir);
}
function createFolderStructure() {
const root = fs.mkdtempSync(path_1.default.join(os.tmpdir(), 'helm-scaffolding-'));
fs.mkdirSync(path_1.default.join(root, 'templates'));
const chartYamlFile = {
apiVersion: '{{ apiVersion }}',
name: '{{ app }}',
version: '{{ version }}',
description: 'Generated chart for {{ app }}',
type: 'application',
};
fs.outputFileSync(path_1.default.join(root, CHART_YAML_FILE), yaml.stringify(chartYamlFile));
const readmeFile = 'This Helm chart is generated using cdk8s. Any manual changes to the chart would be discarded once cdk8s app is synthesized again with `--format helm`.';
fs.outputFileSync(path_1.default.join(root, README), readmeFile);
return root;
}
}
async function addCrdsToHelmChart(chartDir) {
var _a;
const crds = ((_a = config === null || config === void 0 ? void 0 : config.imports) !== null && _a !== void 0 ? _a : []).filter((imprt) => (!(0, util_1.isK8sImport)(imprt) && !(0, util_1.isHelmImport)(imprt)));
for (const crd of crds) {
const importSpec = (0, util_1.parseImports)(crd);
const importedCrdDef = await (0, dispatch_1.matchImporter)(importSpec, process.argv);
const manifest = importedCrdDef.rawManifest;
const filename = (0, util_1.deriveFileName)(importSpec.source);
fs.outputFileSync(path_1.default.join(chartDir, 'crds', `${filename}.yaml`), manifest);
}
}
function getDefaultChartApiVersion(synthFormat) {
return (synthFormat === config_1.SynthesisFormat.HELM) ? config_1.HelmChartApiVersion.V2 : undefined;
}
module.exports = new Command();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ludGguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2xpL2NtZHMvc3ludGgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHVDQUF5QjtBQUN6QixnREFBd0I7QUFDeEIsNkNBQStCO0FBQy9CLCtDQUFpQztBQUNqQyxtQ0FBZ0M7QUFDaEMsMkNBQTZCO0FBRTdCLHlDQUFzRztBQUV0RyxvREFBc0Q7QUFDdEQscURBQXVEO0FBQ3ZELHFDQUErSjtBQUUvSixNQUFNLGVBQWUsR0FBRyxZQUFZLENBQUM7QUFDckMsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDO0FBQzNCLE1BQU0sa0JBQWtCLEdBQUcsTUFBTSxDQUFDO0FBQ2xDLE1BQU0sbUJBQW1CLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBRXpFLE1BQU0sTUFBTSxHQUFHLElBQUEsdUJBQWMsR0FBRSxDQUFDO0FBRWhDLE1BQU0sT0FBTztJQUFiO1FBQ2tCLFlBQU8sR0FBRyxPQUFPLENBQUM7UUFDbEIsYUFBUSxHQUFHLDhEQUE4RCxDQUFDO1FBQzFFLFlBQU8sR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRXpCLFlBQU8sR0FBRyxDQUFDLElBQWdCLEVBQUUsRUFBRSxDQUFDLElBQUk7YUFDakQsTUFBTSxDQUFDLEtBQUssRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE1BQU0sYUFBTixNQUFNLHVCQUFOLE1BQU0sQ0FBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLDhDQUE4QyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQzthQUN6SCxNQUFNLENBQUMsUUFBUSxFQUFFLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsa0JBQWtCLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDO2FBQzNFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLHVFQUF1RSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQzthQUNqSixNQUFNLENBQUMsYUFBYSxFQUFFLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsbUNBQW1DLEVBQUUsQ0FBQzthQUNyRixNQUFNLENBQUMsVUFBVSxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxvRkFBb0YsRUFBRSxDQUFDO2FBQ3BKLE1BQU0sQ0FBQyxnQ0FBZ0MsRUFBRSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLGtFQUFrRSxFQUFFLENBQUM7YUFDdkksTUFBTSxDQUFDLFFBQVEsRUFBRSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLHdHQUF3RyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQzthQUNySyxNQUFNLENBQUMsbUJBQW1CLEVBQUUsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSx1S0FBdUssRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUM7YUFDL08sTUFBTSxDQUFDLGVBQWUsRUFBRSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLDRFQUE0RSxFQUFFLENBQUMsQ0FBQztJQXVGdEksQ0FBQztJQXJGUSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQVM7O1FBRTVCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7UUFDekIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUMzQixNQUFNLE1BQU0sR0FBRyxNQUFBLE1BQUEsSUFBSSxDQUFDLE1BQU0sbUNBQUksTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLE1BQU0sbUNBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzNGLE1BQU0sUUFBUSxHQUFHLE1BQUEsSUFBSSxDQUFDLFFBQVEsbUNBQUksSUFBSSxDQUFDO1FBQ3ZDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQywyQkFBMkIsQ0FBQztRQUNwRCxNQUFNLFVBQVUsR0FBRyxNQUFBLE1BQUEsSUFBSSxDQUFDLFVBQVUsbUNBQUksTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLGdCQUFnQixtQ0FBSSxtQkFBbUIsQ0FBQztRQUN0RixNQUFNLE1BQU0sR0FBRyxNQUFBLE1BQUEsSUFBSSxDQUFDLE1BQU0sbUNBQUksTUFBQSxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsV0FBVywwQ0FBRSxNQUFNLG1DQUFJLHdCQUFlLENBQUMsS0FBSyxDQUFDO1FBQ25GLE1BQU0sWUFBWSxHQUFHLE1BQUEsSUFBSSxDQUFDLFlBQVksbUNBQUksTUFBQSxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsV0FBVywwQ0FBRSxZQUFZLENBQUM7UUFDNUUsTUFBTSxlQUFlLEdBQUcsTUFBQSxNQUFBLElBQUksQ0FBQyxlQUFlLG1DQUFJLE1BQUEsTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLFdBQVcsMENBQUUsZUFBZSxtQ0FBSSx5QkFBeUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUUxSCxJQUFJLE1BQU0sSUFBSSxNQUFNLE1BQUssTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLE1BQU0sQ0FBQSxJQUFJLE1BQU0sRUFBRTtZQUNqRCxNQUFNLElBQUksS0FBSyxDQUFDLDRFQUE0RSxDQUFDLENBQUM7U0FDL0Y7UUFFRCxJQUFJLE1BQU0sRUFBRTtZQUNWLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztTQUNyRDtRQUVELElBQUksTUFBTSxJQUFJLHdCQUFlLENBQUMsS0FBSyxJQUFJLE1BQU0sSUFBSSx3QkFBZSxDQUFDLElBQUksRUFBRTtZQUNyRSxNQUFNLElBQUksS0FBSyxDQUFDLGtEQUFrRCx3QkFBZSxDQUFDLEtBQUssT0FBTyx3QkFBZSxDQUFDLElBQUksa0JBQWtCLE1BQU0sRUFBRSxDQUFDLENBQUM7U0FDL0k7UUFFRCxJQUFJLGVBQWUsSUFBSSxDQUFDLGVBQWUsSUFBSSw0QkFBbUIsQ0FBQyxFQUFFLElBQUksZUFBZSxJQUFJLDRCQUFtQixDQUFDLEVBQUUsQ0FBQyxFQUFFO1lBQy9HLE1BQU0sSUFBSSxLQUFLLENBQUMsd0RBQXdELDRCQUFtQixDQUFDLEVBQUUsT0FBTyw0QkFBbUIsQ0FBQyxFQUFFLGtCQUFrQixlQUFlLEVBQUUsQ0FBQyxDQUFDO1NBQ2pLO1FBRUQsSUFBSSxNQUFNLEtBQUssd0JBQWUsQ0FBQyxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDcEQsTUFBTSxJQUFJLEtBQUssQ0FBQywrRUFBK0UsQ0FBQyxDQUFDO1NBQ2xHO1FBRUQsSUFBSSxZQUFZLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxFQUFFO1lBQy9DLE1BQU0sSUFBSSxLQUFLLENBQUMsOENBQThDLFlBQVksaURBQWlELENBQUMsQ0FBQztTQUM5SDtRQUVELElBQUksTUFBTSxJQUFJLE1BQU0sS0FBSyx3QkFBZSxDQUFDLElBQUksRUFBRTtZQUM3QyxNQUFNLElBQUksS0FBSyxDQUFDLG1GQUFtRixDQUFDLENBQUM7U0FDdEc7UUFFRCxJQUFJLE1BQU0sS0FBSyx3QkFBZSxDQUFDLEtBQUssSUFBSSxlQUFlLEVBQUU7WUFDdkQsTUFBTSxJQUFJLEtBQUssQ0FBQyxtRkFBbUYsQ0FBQyxDQUFDO1NBQ3RHO1FBRUQsSUFBSSxNQUFNLEtBQUssd0JBQWUsQ0FBQyxLQUFLLElBQUksWUFBWSxFQUFFO1lBQ3BELE1BQU0sSUFBSSxLQUFLLENBQUMsK0VBQStFLENBQUMsQ0FBQztTQUNsRztRQUVELElBQUksZUFBZSxLQUFLLDRCQUFtQixDQUFDLEVBQUUsSUFBSSxJQUFBLHFCQUFjLEVBQUMsTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLE9BQU8sQ0FBQyxFQUFFO1lBQ2pGLE1BQU0sSUFBSSxLQUFLLENBQUMsNEZBQTRGLDRCQUFtQixDQUFDLEVBQUUsZ0RBQWdELDRCQUFtQixDQUFDLEVBQUUsOERBQThELENBQUMsQ0FBQztTQUN6UTtRQUVELE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxnQkFBZ0IsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDcEUsTUFBTSx1QkFBdUIsR0FBRyxDQUFDLENBQUMsV0FBVyxJQUFJLFNBQVMsSUFBSSxXQUFXLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBRXZGLElBQUksTUFBTSxFQUFFO1lBQ1YsTUFBTSxJQUFBLGNBQU8sRUFBQyxLQUFLLEVBQUMsT0FBTyxFQUFDLEVBQUU7Z0JBQzVCLE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBQSxlQUFRLEVBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsdUJBQXVCLENBQUMsQ0FBQztnQkFDOUUsS0FBSyxNQUFNLENBQUMsSUFBSSxHQUFHLENBQUMsU0FBUyxFQUFFO29CQUM3QixFQUFFLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztpQkFDN0M7Z0JBQ0QsSUFBSSxXQUFXLEVBQUU7b0JBQ2YsTUFBTSxhQUFhLEdBQUcsSUFBSSx3QkFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDO29CQUNwRCxNQUFNLElBQUEsa0JBQVcsRUFBQyxHQUFHLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsVUFBVSxDQUFDLENBQUM7aUJBQ3hFO1lBQ0gsQ0FBQyxDQUFDLENBQUM7U0FDSjthQUFNO1lBQ0wsSUFBSSxTQUF5QixDQUFDO1lBRTlCLElBQUksTUFBTSxLQUFLLHdCQUFlLENBQUMsSUFBSSxFQUFFO2dCQUNuQyxNQUFNLHFCQUFxQixDQUFDLGVBQWUsRUFBRSxZQUFZLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ25FLE1BQU0sV0FBVyxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDO2dCQUVuRCxTQUFTLEdBQUcsTUFBTSxJQUFBLGVBQVEsRUFBQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO2FBQ25GO2lCQUFNO2dCQUNMLFNBQVMsR0FBRyxNQUFNLElBQUEsZUFBUSxFQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLHVCQUF1QixDQUFDLENBQUM7YUFDOUU7WUFFRCxJQUFJLFdBQVcsRUFBRTtnQkFDZixNQUFNLGFBQWEsR0FBRyxJQUFJLHdCQUFhLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQ3BELE1BQU0sSUFBQSxrQkFBVyxFQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxVQUFVLENBQUMsQ0FBQzthQUM5RTtTQUNGO0lBQ0gsQ0FBQztDQUVGO0FBRUQsS0FBSyxVQUFVLGdCQUFnQjtJQUM3QixJQUFJLE9BQU0sQ0FBQyxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsV0FBVyxDQUFDLEtBQUssUUFBUSxFQUFFO1FBQzVDLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBQSxlQUFRLEVBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ25ELE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQXVCLENBQUM7S0FDbEQ7U0FBTTtRQUNMLE9BQU8sTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLFdBQVcsQ0FBQztLQUM1QjtBQUNILENBQUM7QUFFRCxLQUFLLFVBQVUscUJBQXFCLENBQUMsVUFBa0IsRUFBRSxZQUFvQixFQUFFLE1BQWM7SUFDM0YsTUFBTSxpQkFBaUIsR0FBRyxxQkFBcUIsRUFBRSxDQUFDO0lBRWxELE1BQU0sZ0JBQWdCLEdBQUc7UUFDdkIsVUFBVSxFQUFFLFVBQVU7UUFDdEIsT0FBTyxFQUFFLFlBQVk7UUFDckIsR0FBRyxFQUFFLGNBQUksQ0FBQyxRQUFRLENBQUMsY0FBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0tBQ25DLENBQUM7SUFFRixJQUFJO1FBQ0YsTUFBTSxJQUFBLGVBQU0sRUFBQyxpQkFBaUIsRUFBRSxNQUFNLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztLQUMzRDtZQUFTO1FBQ1IsRUFBRSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0tBQ25EO0lBR0QsSUFBSSxVQUFVLEtBQUssNEJBQW1CLENBQUMsRUFBRSxJQUFJLElBQUEscUJBQWMsRUFBQyxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsT0FBTyxDQUFDLEVBQUU7UUFDNUUsTUFBTSxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztLQUNsQztJQUVELFNBQVMscUJBQXFCO1FBQzVCLE1BQU0sSUFBSSxHQUFHLEVBQUUsQ0FBQyxXQUFXLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLEVBQUUsbUJBQW1CLENBQUMsQ0FBQyxDQUFDO1FBRXpFLEVBQUUsQ0FBQyxTQUFTLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUUzQyxNQUFNLGFBQWEsR0FBRztZQUNwQixVQUFVLEVBQUUsa0JBQWtCO1lBQzlCLElBQUksRUFBRSxXQUFXO1lBQ2pCLE9BQU8sRUFBRSxlQUFlO1lBQ3hCLFdBQVcsRUFBRSwrQkFBK0I7WUFDNUMsSUFBSSxFQUFFLGFBQWE7U0FDcEIsQ0FBQztRQUVGLEVBQUUsQ0FBQyxjQUFjLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsZUFBZSxDQUFDLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO1FBRW5GLE1BQU0sVUFBVSxHQUFHLHdKQUF3SixDQUFDO1FBRTVLLEVBQUUsQ0FBQyxjQUFjLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFFdkQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQztBQUVELEtBQUssVUFBVSxrQkFBa0IsQ0FBQyxRQUFnQjs7SUFDaEQsTUFBTSxJQUFJLEdBQUcsQ0FBQyxNQUFBLE1BQU0sYUFBTixNQUFNLHVCQUFOLE1BQU0sQ0FBRSxPQUFPLG1DQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUEsa0JBQVcsRUFBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUEsbUJBQVksRUFBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFdEcsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUU7UUFDdEIsTUFBTSxVQUFVLEdBQUcsSUFBQSxtQkFBWSxFQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sY0FBYyxHQUFHLE1BQU0sSUFBQSx3QkFBYSxFQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFtQyxDQUFDO1FBQ3ZHLE1BQU0sUUFBUSxHQUFHLGNBQWMsQ0FBQyxXQUFXLENBQUM7UUFFNUMsTUFBTSxRQUFRLEdBQUcsSUFBQSxxQkFBYyxFQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVuRCxFQUFFLENBQUMsY0FBYyxDQUFDLGNBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxHQUFHLFFBQVEsT0FBTyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUM7S0FDOUU7QUFDSCxDQUFDO0FBRUQsU0FBUyx5QkFBeUIsQ0FBQyxXQUFtQjtJQUNwRCxPQUFPLENBQUMsV0FBVyxLQUFLLHdCQUFlLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLDRCQUFtQixDQUFDLEVBQUUsQ0FBQSxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ3BGLENBQUM7QUFFRCxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksT0FBTyxFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBvcyBmcm9tICdvcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCAqIGFzIHNlbXZlciBmcm9tICdzZW12ZXInO1xuaW1wb3J0IHsgc3NjYWZmIH0gZnJvbSAnc3NjYWZmJztcbmltcG9ydCAqIGFzIHlhbWwgZnJvbSAneWFtbCc7XG5pbXBvcnQgKiBhcyB5YXJncyBmcm9tICd5YXJncyc7XG5pbXBvcnQgeyBIZWxtQ2hhcnRBcGlWZXJzaW9uLCBTeW50aGVzaXNGb3JtYXQsIFZhbGlkYXRpb25Db25maWcsIHJlYWRDb25maWdTeW5jIH0gZnJvbSAnLi4vLi4vY29uZmlnJztcbmltcG9ydCB7IEltcG9ydEN1c3RvbVJlc291cmNlRGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uL2ltcG9ydC9jcmQnO1xuaW1wb3J0IHsgbWF0Y2hJbXBvcnRlciB9IGZyb20gJy4uLy4uL2ltcG9ydC9kaXNwYXRjaCc7XG5pbXBvcnQgeyBQbHVnaW5NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vcGx1Z2lucy9fbWFuYWdlcic7XG5pbXBvcnQgeyBTeW50aGVzaXplZEFwcCwgY3Jkc0FyZVByZXNlbnQsIGRlcml2ZUZpbGVOYW1lLCBkb3dubG9hZCwgaXNIZWxtSW1wb3J0LCBpc0s4c0ltcG9ydCwgbWtkdGVtcCwgcGFyc2VJbXBvcnRzLCBzeW50aEFwcCwgdmFsaWRhdGVBcHAgfSBmcm9tICcuLi8uLi91dGlsJztcblxuY29uc3QgQ0hBUlRfWUFNTF9GSUxFID0gJ0NoYXJ0LnlhbWwnO1xuY29uc3QgUkVBRE1FID0gJ1JFQURNRS5tZCc7XG5jb25zdCBERUZBVUxUX09VVFBVVF9ESVIgPSAnZGlzdCc7XG5jb25zdCBERUZBVUxUX1BMVUdJTlNfRElSID0gcGF0aC5qb2luKG9zLmhvbWVkaXIoKSwgJy5jZGs4cycsICdwbHVnaW5zJyk7XG5cbmNvbnN0IGNvbmZpZyA9IHJlYWRDb25maWdTeW5jKCk7XG5cbmNsYXNzIENvbW1hbmQgaW1wbGVtZW50cyB5YXJncy5Db21tYW5kTW9kdWxlIHtcbiAgcHVibGljIHJlYWRvbmx5IGNvbW1hbmQgPSAnc3ludGgnO1xuICBwdWJsaWMgcmVhZG9ubHkgZGVzY3JpYmUgPSAnU3ludGhlc2l6ZXMgS3ViZXJuZXRlcyBtYW5pZmVzdHMgZm9yIGFsbCBjaGFydHMgaW4geW91ciBhcHAuJztcbiAgcHVibGljIHJlYWRvbmx5IGFsaWFzZXMgPSBbJ3N5bnRoZXNpemUnXTtcblxuICBwdWJsaWMgcmVhZG9ubHkgYnVpbGRlciA9IChhcmdzOiB5YXJncy5Bcmd2KSA9PiBhcmdzXG4gICAgLm9wdGlvbignYXBwJywgeyByZXF1aXJlZDogdHJ1ZSwgZGVmYXVsdDogY29uZmlnPy5hcHAsIGRlc2M6ICdDb21tYW5kIHRvIHVzZSBpbiBvcmRlciB0byBleGVjdXRlIGNkazhzIGFwcCcsIGFsaWFzOiAnYScgfSlcbiAgICAub3B0aW9uKCdvdXRwdXQnLCB7IHJlcXVpcmVkOiBmYWxzZSwgZGVzYzogJ091dHB1dCBkaXJlY3RvcnknLCBhbGlhczogJ28nIH0pXG4gICAgLm9wdGlvbignc3Rkb3V0JywgeyB0eXBlOiAnYm9vbGVhbicsIHJlcXVpcmVkOiBmYWxzZSwgZGVzYzogJ1dyaXRlIHN5bnRoZXNpemVkIG1hbmlmZXN0cyB0byBTVERPVVQgaW5zdGVhZCBvZiB0aGUgb3V0cHV0IGRpcmVjdG9yeScsIGFsaWFzOiAncCcgfSlcbiAgICAub3B0aW9uKCdwbHVnaW5zLWRpcicsIHsgcmVxdWlyZWQ6IGZhbHNlLCBkZXNjOiAnRGlyZWN0b3J5IHRvIHN0b3JlIGNkazhzIHBsdWdpbnMuJyB9KVxuICAgIC5vcHRpb24oJ3ZhbGlkYXRlJywgeyB0eXBlOiAnYm9vbGVhbicsIHJlcXVpcmVkOiBmYWxzZSwgZGVzYzogJ0FwcGx5IHZhbGlkYXRpb24gcGx1Z2lucyBvbiB0aGUgcmVzdWx0aW5nIG1hbmlmZXN0cyAodXNlIC0tbm8tdmFsaWRhdGUgdG8gZGlzYWJsZSknIH0pXG4gICAgLm9wdGlvbigndmFsaWRhdGlvbi1yZXBvcnRzLW91dHB1dC1maWxlJywgeyByZXF1aXJlZDogZmFsc2UsIGRlc2M6ICdGaWxlIHRvIHdyaXRlIGEgSlNPTiByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmFsaWRhdGlvbiByZXBvcnRzIHRvJyB9KVxuICAgIC5vcHRpb24oJ2Zvcm1hdCcsIHsgcmVxdWlyZWQ6IGZhbHNlLCBkZXNjOiAnU3ludGhlc2lzIGZvcm1hdCBmb3IgS3ViZXJuZXRlcyBtYW5pZmVzdHMuIFRoZSBkZWZhdWx0IHN5bnRoZXNpcyBmb3JtYXQgaXMgcGxhaW4ga3ViZXJuZXRlcyBtYW5pZmVzdHMuJywgdHlwZTogJ3N0cmluZycgfSlcbiAgICAub3B0aW9uKCdjaGFydC1hcGktdmVyc2lvbicsIHsgcmVxdWlyZWQ6IGZhbHNlLCBkZXNjOiAnQ2hhcnQgQVBJIHZlcnNpb24gb2YgaGVsbSBjaGFydC4gVGhlIGRlZmF1bHQgdmFsdWUgd291bGQgYmUgXFwndjJcXCcgYXBpIHZlcnNpb24gd2hlbiBzeW50aGVzaXMgZm9ybWF0IGlzIGhlbG0uIFRoZXJlIGlzIG5vIGRlZmF1bHQgc2V0IHdoZW4gc3ludGhlc2lzIGZvcm1hdCBpcyBwbGFpbi4nLCB0eXBlOiAnc3RyaW5nJyB9KVxuICAgIC5vcHRpb24oJ2NoYXJ0LXZlcnNpb24nLCB7IHJlcXVpcmVkOiBmYWxzZSwgZGVzYzogJ0NoYXJ0IHZlcnNpb24gb2YgaGVsbSBjaGFydC4gVGhpcyBpcyByZXF1aXJlZCBpZiBzeW50aGVzaXMgZm9ybWF0IGlzIGhlbG0uJyB9KTtcblxuICBwdWJsaWMgYXN5bmMgaGFuZGxlcihhcmd2OiBhbnkpIHtcblxuICAgIGNvbnN0IGNvbW1hbmQgPSBhcmd2LmFwcDtcbiAgICBjb25zdCBzdGRvdXQgPSBhcmd2LnN0ZG91dDtcbiAgICBjb25zdCBvdXRkaXIgPSBhcmd2Lm91dHB1dCA/PyBjb25maWc/Lm91dHB1dCA/PyAoIXN0ZG91dCA/IERFRkFVTFRfT1VUUFVUX0RJUiA6IHVuZGVmaW5lZCk7XG4gICAgY29uc3QgdmFsaWRhdGUgPSBhcmd2LnZhbGlkYXRlID8/IHRydWU7XG4gICAgY29uc3QgcmVwb3J0RmlsZSA9IGFyZ3YudmFsaWRhdGlvblJlcG9ydHNPdXRwdXRGaWxlO1xuICAgIGNvbnN0IHBsdWdpbnNEaXIgPSBhcmd2LnBsdWdpbnNEaXIgPz8gY29uZmlnPy5wbHVnaW5zRGlyZWN0b3J5ID8/IERFRkFVTFRfUExVR0lOU19ESVI7XG4gICAgY29uc3QgZm9ybWF0ID0gYXJndi5mb3JtYXQgPz8gY29uZmlnPy5zeW50aENvbmZpZz8uZm9ybWF0ID8/IFN5bnRoZXNpc0Zvcm1hdC5QTEFJTjtcbiAgICBjb25zdCBjaGFydFZlcnNpb24gPSBhcmd2LmNoYXJ0VmVyc2lvbiA/PyBjb25maWc/LnN5bnRoQ29uZmlnPy5jaGFydFZlcnNpb247XG4gICAgY29uc3QgY2hhcnRBcGlWZXJzaW9uID0gYXJndi5jaGFydEFwaVZlcnNpb24gPz8gY29uZmlnPy5zeW50aENvbmZpZz8uY2hhcnRBcGlWZXJzaW9uID8/IGdldERlZmF1bHRDaGFydEFwaVZlcnNpb24oZm9ybWF0KTtcblxuICAgIGlmIChvdXRkaXIgJiYgb3V0ZGlyICE9PSBjb25maWc/Lm91dHB1dCAmJiBzdGRvdXQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignXFwnLS1vdXRwdXRcXCcgYW5kIFxcJy0tc3Rkb3V0XFwnIGFyZSBtdXR1YWxseSBleGNsdXNpdmUuIFBsZWFzZSBvbmx5IHVzZSBvbmUuJyk7XG4gICAgfVxuXG4gICAgaWYgKG91dGRpcikge1xuICAgICAgZnMucm1TeW5jKG91dGRpciwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pO1xuICAgIH1cblxuICAgIGlmIChmb3JtYXQgIT0gU3ludGhlc2lzRm9ybWF0LlBMQUlOICYmIGZvcm1hdCAhPSBTeW50aGVzaXNGb3JtYXQuSEVMTSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBZb3UgbmVlZCB0byBzcGVjaWZ5IHN5bnRoZXNpcyBmb3JtYXQgZWl0aGVyIGFzICR7U3ludGhlc2lzRm9ybWF0LlBMQUlOfSBvciAke1N5bnRoZXNpc0Zvcm1hdC5IRUxNfSBidXQgcmVjZWl2ZWQ6ICR7Zm9ybWF0fWApO1xuICAgIH1cblxuICAgIGlmIChjaGFydEFwaVZlcnNpb24gJiYgKGNoYXJ0QXBpVmVyc2lvbiAhPSBIZWxtQ2hhcnRBcGlWZXJzaW9uLlYxICYmIGNoYXJ0QXBpVmVyc2lvbiAhPSBIZWxtQ2hhcnRBcGlWZXJzaW9uLlYyKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBZb3UgbmVlZCB0byBzcGVjaWZ5IGhlbG0gY2hhcnQgYXBpIHZlcnNpb24gZWl0aGVyIGFzICR7SGVsbUNoYXJ0QXBpVmVyc2lvbi5WMX0gb3IgJHtIZWxtQ2hhcnRBcGlWZXJzaW9uLlYyfSBidXQgcmVjZWl2ZWQ6ICR7Y2hhcnRBcGlWZXJzaW9ufWApO1xuICAgIH1cblxuICAgIGlmIChmb3JtYXQgPT09IFN5bnRoZXNpc0Zvcm1hdC5IRUxNICYmICFjaGFydFZlcnNpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignWW91IG5lZWQgdG8gc3BlY2lmeSBcXCctLWNoYXJ0LXZlcnNpb25cXCcgd2hlbiBcXCctLWZvcm1hdFxcJyBpcyBzZXQgYXMgXFwnaGVsbVxcJy4nKTtcbiAgICB9XG5cbiAgICBpZiAoY2hhcnRWZXJzaW9uICYmICFzZW12ZXIudmFsaWQoY2hhcnRWZXJzaW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgdmFsdWUgc3BlY2lmaWVkIGZvciAnLS1jaGFydC12ZXJzaW9uJzogJHtjaGFydFZlcnNpb259IGRvZXMgbm90IGZvbGxvdyBTZW1WZXItMihodHRwczovL3NlbXZlci5vcmcvKS5gKTtcbiAgICB9XG5cbiAgICBpZiAoc3Rkb3V0ICYmIGZvcm1hdCA9PT0gU3ludGhlc2lzRm9ybWF0LkhFTE0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSGVsbSBmb3JtYXQgc3ludGhlc2lzIGRvZXMgbm90IHN1cHBvcnQgXFwnc3Rkb3V0XFwnLiBQbGVhc2UgdXNlIFxcJ291dGRpclxcJyBpbnN0ZWFkLicpO1xuICAgIH1cblxuICAgIGlmIChmb3JtYXQgPT09IFN5bnRoZXNpc0Zvcm1hdC5QTEFJTiAmJiBjaGFydEFwaVZlcnNpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignWW91IG5lZWQgdG8gc3BlY2lmeSBcXCctLWZvcm1hdFxcJyBhcyBcXCdoZWxtXFwnIHdoZW4gXFwnLS1jaGFydC1hcGktdmVyc2lvblxcJyBpcyBzZXQuJyk7XG4gICAgfVxuXG4gICAgaWYgKGZvcm1hdCA9PT0gU3ludGhlc2lzRm9ybWF0LlBMQUlOICYmIGNoYXJ0VmVyc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgbmVlZCB0byBzcGVjaWZ5IFxcJy0tZm9ybWF0XFwnIGFzIFxcJ2hlbG1cXCcgd2hlbiBcXCctLWNoYXJ0LXZlcnNpb25cXCcgaXMgc2V0LicpO1xuICAgIH1cblxuICAgIGlmIChjaGFydEFwaVZlcnNpb24gPT09IEhlbG1DaGFydEFwaVZlcnNpb24uVjEgJiYgY3Jkc0FyZVByZXNlbnQoY29uZmlnPy5pbXBvcnRzKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBZb3VyIGFwcGxpY2F0aW9uIHVzZXMgQ1JEcywgd2hpY2ggYXJlIG5vdCBzdXBwb3J0ZWQgd2hlbiAnLS1jaGFydC1hcGktdmVyc2lvbicgaXMgc2V0IHRvICR7SGVsbUNoYXJ0QXBpVmVyc2lvbi5WMX0uIFBsZWFzZSBlaXRoZXIgc2V0ICctLWNoYXJ0LWFwaS12ZXJzaW9uJyB0byAke0hlbG1DaGFydEFwaVZlcnNpb24uVjJ9LCBvciByZW1vdmUgdGhlIENSRHMgZnJvbSB5b3VyIGNkazhzLnlhbWwgY29uZmlndXJhdGlvbiBmaWxlYCk7XG4gICAgfVxuXG4gICAgY29uc3QgdmFsaWRhdGlvbnMgPSB2YWxpZGF0ZSA/IGF3YWl0IGZldGNoVmFsaWRhdGlvbnMoKSA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCByZWNvcmRDb25zdHJ1Y3RNZXRhZGF0YSA9ICEodmFsaWRhdGlvbnMgPT0gdW5kZWZpbmVkIHx8IHZhbGlkYXRpb25zLmxlbmd0aCA9PSAwKTtcblxuICAgIGlmIChzdGRvdXQpIHtcbiAgICAgIGF3YWl0IG1rZHRlbXAoYXN5bmMgdGVtcERpciA9PiB7XG4gICAgICAgIGNvbnN0IGFwcCA9IGF3YWl0IHN5bnRoQXBwKGNvbW1hbmQsIHRlbXBEaXIsIHN0ZG91dCwgcmVjb3JkQ29uc3RydWN0TWV0YWRhdGEpO1xuICAgICAgICBmb3IgKGNvbnN0IGYgb2YgYXBwLm1hbmlmZXN0cykge1xuICAgICAgICAgIGZzLmNyZWF0ZVJlYWRTdHJlYW0oZikucGlwZShwcm9jZXNzLnN0ZG91dCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbGlkYXRpb25zKSB7XG4gICAgICAgICAgY29uc3QgcGx1Z2luTWFuYWdlciA9IG5ldyBQbHVnaW5NYW5hZ2VyKHBsdWdpbnNEaXIpO1xuICAgICAgICAgIGF3YWl0IHZhbGlkYXRlQXBwKGFwcCwgc3Rkb3V0LCB2YWxpZGF0aW9ucywgcGx1Z2luTWFuYWdlciwgcmVwb3J0RmlsZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgbWFuaWZlc3RzOiBTeW50aGVzaXplZEFwcDtcblxuICAgICAgaWYgKGZvcm1hdCA9PT0gU3ludGhlc2lzRm9ybWF0LkhFTE0pIHtcbiAgICAgICAgYXdhaXQgY3JlYXRlSGVsbVNjYWZmb2xkaW5nKGNoYXJ0QXBpVmVyc2lvbiwgY2hhcnRWZXJzaW9uLCBvdXRkaXIpO1xuICAgICAgICBjb25zdCB0ZW1wbGF0ZURpciA9IHBhdGguam9pbihvdXRkaXIsICd0ZW1wbGF0ZXMnKTtcblxuICAgICAgICBtYW5pZmVzdHMgPSBhd2FpdCBzeW50aEFwcChjb21tYW5kLCB0ZW1wbGF0ZURpciwgc3Rkb3V0LCByZWNvcmRDb25zdHJ1Y3RNZXRhZGF0YSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtYW5pZmVzdHMgPSBhd2FpdCBzeW50aEFwcChjb21tYW5kLCBvdXRkaXIsIHN0ZG91dCwgcmVjb3JkQ29uc3RydWN0TWV0YWRhdGEpO1xuICAgICAgfVxuXG4gICAgICBpZiAodmFsaWRhdGlvbnMpIHtcbiAgICAgICAgY29uc3QgcGx1Z2luTWFuYWdlciA9IG5ldyBQbHVnaW5NYW5hZ2VyKHBsdWdpbnNEaXIpO1xuICAgICAgICBhd2FpdCB2YWxpZGF0ZUFwcChtYW5pZmVzdHMsIHN0ZG91dCwgdmFsaWRhdGlvbnMsIHBsdWdpbk1hbmFnZXIsIHJlcG9ydEZpbGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG59XG5cbmFzeW5jIGZ1bmN0aW9uIGZldGNoVmFsaWRhdGlvbnMoKTogUHJvbWlzZTxWYWxpZGF0aW9uQ29uZmlnW10gfCB1bmRlZmluZWQ+IHtcbiAgaWYgKHR5cGVvZihjb25maWc/LnZhbGlkYXRpb25zKSA9PT0gJ3N0cmluZycpIHtcbiAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgZG93bmxvYWQoY29uZmlnLnZhbGlkYXRpb25zKTtcbiAgICByZXR1cm4geWFtbC5wYXJzZShjb250ZW50KSBhcyBWYWxpZGF0aW9uQ29uZmlnW107XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGNvbmZpZz8udmFsaWRhdGlvbnM7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gY3JlYXRlSGVsbVNjYWZmb2xkaW5nKGFwaVZlcnNpb246IHN0cmluZywgY2hhcnRWZXJzaW9uOiBzdHJpbmcsIG91dGRpcjogc3RyaW5nKSB7XG4gIGNvbnN0IHRlbXBIZWxtU3RydWN0dXJlID0gY3JlYXRlRm9sZGVyU3RydWN0dXJlKCk7XG5cbiAgY29uc3Qgc3Vic3RpdHV0ZVZhbHVlcyA9IHtcbiAgICBhcGlWZXJzaW9uOiBhcGlWZXJzaW9uLFxuICAgIHZlcnNpb246IGNoYXJ0VmVyc2lvbixcbiAgICBhcHA6IHBhdGguYmFzZW5hbWUocGF0aC5yZXNvbHZlKCkpLFxuICB9O1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgc3NjYWZmKHRlbXBIZWxtU3RydWN0dXJlLCBvdXRkaXIsIHN1YnN0aXR1dGVWYWx1ZXMpO1xuICB9IGZpbmFsbHkge1xuICAgIGZzLnJtU3luYyh0ZW1wSGVsbVN0cnVjdHVyZSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIH1cblxuXG4gIGlmIChhcGlWZXJzaW9uID09PSBIZWxtQ2hhcnRBcGlWZXJzaW9uLlYyICYmIGNyZHNBcmVQcmVzZW50KGNvbmZpZz8uaW1wb3J0cykpIHtcbiAgICBhd2FpdCBhZGRDcmRzVG9IZWxtQ2hhcnQob3V0ZGlyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZUZvbGRlclN0cnVjdHVyZSgpOiBzdHJpbmcge1xuICAgIGNvbnN0IHJvb3QgPSBmcy5ta2R0ZW1wU3luYyhwYXRoLmpvaW4ob3MudG1wZGlyKCksICdoZWxtLXNjYWZmb2xkaW5nLScpKTtcblxuICAgIGZzLm1rZGlyU3luYyhwYXRoLmpvaW4ocm9vdCwgJ3RlbXBsYXRlcycpKTtcblxuICAgIGNvbnN0IGNoYXJ0WWFtbEZpbGUgPSB7XG4gICAgICBhcGlWZXJzaW9uOiAne3sgYXBpVmVyc2lvbiB9fScsXG4gICAgICBuYW1lOiAne3sgYXBwIH19JyxcbiAgICAgIHZlcnNpb246ICd7eyB2ZXJzaW9uIH19JyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnR2VuZXJhdGVkIGNoYXJ0IGZvciB7eyBhcHAgfX0nLFxuICAgICAgdHlwZTogJ2FwcGxpY2F0aW9uJyxcbiAgICB9O1xuXG4gICAgZnMub3V0cHV0RmlsZVN5bmMocGF0aC5qb2luKHJvb3QsIENIQVJUX1lBTUxfRklMRSksIHlhbWwuc3RyaW5naWZ5KGNoYXJ0WWFtbEZpbGUpKTtcblxuICAgIGNvbnN0IHJlYWRtZUZpbGUgPSAnVGhpcyBIZWxtIGNoYXJ0IGlzIGdlbmVyYXRlZCB1c2luZyBjZGs4cy4gQW55IG1hbnVhbCBjaGFuZ2VzIHRvIHRoZSBjaGFydCB3b3VsZCBiZSBkaXNjYXJkZWQgb25jZSBjZGs4cyBhcHAgaXMgc3ludGhlc2l6ZWQgYWdhaW4gd2l0aCBgLS1mb3JtYXQgaGVsbWAuJztcblxuICAgIGZzLm91dHB1dEZpbGVTeW5jKHBhdGguam9pbihyb290LCBSRUFETUUpLCByZWFkbWVGaWxlKTtcblxuICAgIHJldHVybiByb290O1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGFkZENyZHNUb0hlbG1DaGFydChjaGFydERpcjogc3RyaW5nKSB7XG4gIGNvbnN0IGNyZHMgPSAoY29uZmlnPy5pbXBvcnRzID8/IFtdKS5maWx0ZXIoKGltcHJ0KSA9PiAoIWlzSzhzSW1wb3J0KGltcHJ0KSAmJiAhaXNIZWxtSW1wb3J0KGltcHJ0KSkpO1xuXG4gIGZvciAoY29uc3QgY3JkIG9mIGNyZHMpIHtcbiAgICBjb25zdCBpbXBvcnRTcGVjID0gcGFyc2VJbXBvcnRzKGNyZCk7XG4gICAgY29uc3QgaW1wb3J0ZWRDcmREZWYgPSBhd2FpdCBtYXRjaEltcG9ydGVyKGltcG9ydFNwZWMsIHByb2Nlc3MuYXJndikgYXMgSW1wb3J0Q3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uO1xuICAgIGNvbnN0IG1hbmlmZXN0ID0gaW1wb3J0ZWRDcmREZWYucmF3TWFuaWZlc3Q7XG5cbiAgICBjb25zdCBmaWxlbmFtZSA9IGRlcml2ZUZpbGVOYW1lKGltcG9ydFNwZWMuc291cmNlKTtcblxuICAgIGZzLm91dHB1dEZpbGVTeW5jKHBhdGguam9pbihjaGFydERpciwgJ2NyZHMnLCBgJHtmaWxlbmFtZX0ueWFtbGApLCBtYW5pZmVzdCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0RGVmYXVsdENoYXJ0QXBpVmVyc2lvbihzeW50aEZvcm1hdDogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIChzeW50aEZvcm1hdCA9PT0gU3ludGhlc2lzRm9ybWF0LkhFTE0pID8gSGVsbUNoYXJ0QXBpVmVyc2lvbi5WMjogdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBDb21tYW5kKCk7Il19