projen
Version:
CDK for software projects
377 lines • 56.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.JsiiBuild = exports.ValidateTsconfig = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const consts_1 = require("./consts");
const jsii_docgen_1 = require("./jsii-docgen");
const consts_2 = require("../build/private/consts");
const actions_const_1 = require("../github/actions.const");
const workflow_steps_1 = require("../github/workflow-steps");
const workflows_model_1 = require("../github/workflows-model");
const javascript_1 = require("../javascript");
const util_1 = require("../javascript/util");
const runner_options_1 = require("../runner-options");
const typescript_1 = require("../typescript");
const REPO_TEMP_DIRECTORY = ".repo";
const BUILD_ARTIFACT_OLD_DIR = "dist.old";
/**
* Level of tsconfig validation jsii should perform.
*/
var ValidateTsconfig;
(function (ValidateTsconfig) {
/**
* Validates against a strict rule set designed for widespread support and backwards-compatibility.
*/
ValidateTsconfig["STRICT"] = "strict";
/**
* Enforces a tsconfig as if it were generated by jsii.
*/
ValidateTsconfig["GENERATED"] = "generated";
/**
* Only reject options known to be incompatible with jsii.
*/
ValidateTsconfig["MINIMAL"] = "minimal";
/**
* Disables all config validation. Use at your own risk.
*/
ValidateTsconfig["OFF"] = "off";
})(ValidateTsconfig || (exports.ValidateTsconfig = ValidateTsconfig = {}));
/**
* A mixin that adds jsii compilation, multi-language packaging, and publishing
* capabilities to any TypeScript project.
*
* This implements the constructs `IMixin` interface and is applied using the
* `.with()` method on any construct.
*
* @example
* const project = new TypeScriptProject({ disableTsconfig: true, ... });
* project.with(new JsiiBuild({
* jsiiVersion: '~5.9.0',
* publishToMaven: { ... },
* }));
*/
class JsiiBuild {
static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.cdk.JsiiBuild", version: "0.103.12" };
options;
extraJobOptions;
constructor(options = {}, extraJobOptions) {
this.options = options;
this.extraJobOptions = (extraJobOptions ?? {});
}
/**
* Returns true if the construct is a TypeScriptProject.
*/
supports(construct) {
return construct instanceof typescript_1.TypeScriptProject;
}
/**
* Applies jsii configuration to the target TypeScriptProject.
*/
applyTo(project) {
if (!this.supports(project)) {
return;
}
const options = { ...this.options };
const srcdir = project.srcdir;
const libdir = project.libdir;
project.addFields({ types: `${libdir}/index.d.ts` });
const compressAssembly = options.compressAssembly ?? false;
// this is an unhelpful warning
const jsiiFlags = ["--silence-warnings=reserved-word"];
if (compressAssembly) {
jsiiFlags.push("--compress-assembly");
}
const compatIgnore = options.compatIgnore ?? ".compatignore";
project.addFields({
stability: options.stability ?? project.package.manifest.stability ?? "stable",
});
if (options.stability === "deprecated") {
project.addFields({ deprecated: true });
}
project.compileTask.reset(["jsii", ...jsiiFlags].join(" "));
project.watchTask.reset(["jsii", "-w", ...jsiiFlags].join(" "));
const compatTask = project.addTask("compat", {
description: `Perform API compatibility check against latest version`,
execArgs: [
"jsii-diff",
`npm:${project.package.packageName}`,
"-k",
"--ignore-file",
compatIgnore,
],
});
if (options.compat ?? false) {
project.compileTask.spawn(compatTask);
}
// Create a new package:all task, it will be filled with language targets later
const packageAllTask = project.addTask("package-all", {
description: "Packages artifacts for all target languages",
});
// in jsii we consider the entire repo (post build) as the build artifact
// which is then used to create the language bindings in separate jobs.
const packageJsTask = this.addPackagingTask(project, packageAllTask, "js");
// When running inside CI we initially only package js. Other targets are packaged in separate jobs.
// Outside of CI (i.e locally) we simply package all targets.
project.packageTask.reset();
project.packageTask.spawn(packageJsTask, {
// Only run in CI
condition: `node -e "if (!process.env.CI) process.exit(1)"`,
});
project.packageTask.spawn(packageAllTask, {
// Don't run in CI
condition: `node -e "if (process.env.CI) process.exit(1)"`,
});
const targets = {};
const jsii = {
outdir: project.artifactsDirectory,
targets,
};
// jsii compiles against an explicitly provided tsconfig, falling back to
// the project's own tsconfig when one is not injected. When neither is
// available (e.g. `disableTsconfig`), let jsii generate one from tsc settings.
const tsconfig = options.tsconfig ?? project.tsconfig;
if (tsconfig) {
// @ts-ignore jsii uses JSON.parse() and cannot handle comments
tsconfig.file.configureComments(false);
jsii.tsconfig = tsconfig.fileName;
jsii.validateTsconfig =
options.validateTsconfig ?? ValidateTsconfig.STRICT;
if (options.excludeTypescript) {
for (const pattern of options.excludeTypescript) {
tsconfig.addExclude(pattern);
}
}
}
else {
jsii.tsc = {
outDir: libdir,
rootDir: srcdir,
};
if (options.excludeTypescript) {
jsii.excludeTypescript = options.excludeTypescript;
}
}
project.addFields({ jsii });
const extraJobOptions = this.extraJobOptions;
if (options.releaseToNpm !== false) {
const npmjs = {
registry: project.package.npmRegistry,
npmTokenSecret: project.package.npmTokenSecret,
npmProvenance: project.package.npmProvenance,
codeArtifactOptions: options.codeArtifactOptions,
trustedPublishing: options.npmTrustedPublishing ??
//@ts-ignore
project.options.npmTrustedPublishing ??
false,
};
this.addTargetToBuild(project, packageJsTask, "js", extraJobOptions);
this.addTargetToRelease(project, packageJsTask, "js", npmjs);
}
const maven = options.publishToMaven;
if (maven) {
targets.java = {
package: maven.javaPackage,
maven: {
groupId: maven.mavenGroupId,
artifactId: maven.mavenArtifactId,
},
};
const task = this.addPackagingTask(project, packageAllTask, "java");
this.addTargetToBuild(project, task, "java", extraJobOptions);
this.addTargetToRelease(project, task, "java", maven);
}
const pypi = options.publishToPypi;
if (pypi) {
targets.python = {
distName: pypi.distName,
module: pypi.module,
};
const task = this.addPackagingTask(project, packageAllTask, "python");
this.addTargetToBuild(project, task, "python", extraJobOptions);
this.addTargetToRelease(project, task, "python", pypi);
}
const nuget = options.publishToNuget;
if (nuget) {
targets.dotnet = {
namespace: nuget.dotNetNamespace,
packageId: nuget.packageId,
iconUrl: nuget.iconUrl,
};
const task = this.addPackagingTask(project, packageAllTask, "dotnet");
this.addTargetToBuild(project, task, "dotnet", extraJobOptions);
this.addTargetToRelease(project, task, "dotnet", nuget);
}
const golang = options.publishToGo;
if (golang) {
targets.go = {
moduleName: golang.moduleName,
packageName: golang.packageName,
versionSuffix: golang.versionSuffix,
};
const task = this.addPackagingTask(project, packageAllTask, "go");
this.addTargetToBuild(project, task, "go", extraJobOptions);
this.addTargetToRelease(project, task, "go", golang);
}
// If jsiiVersion is "*", don't specify anything so the user can manage.
// Otherwise, use `jsiiVersion`
const jsiiVersion = options.jsiiVersion ?? "~5.9.0";
const jsiiSuffix = jsiiVersion === "*" ? "" : `@${jsiiVersion}`;
project.addDevDeps(`jsii${jsiiSuffix}`, `jsii-rosetta${jsiiSuffix}`, "jsii-diff", "jsii-pacmak");
project.gitignore.exclude(".jsii");
if (!tsconfig) {
project.gitignore.exclude("tsconfig.json");
}
project.npmignore?.include(".jsii");
if (options.docgen ?? true) {
// If jsiiVersion is "*", don't specify anything so the user can manage.
// Otherwise use a version that is compatible with all supported jsii releases.
const docgenVersion = options.jsiiVersion === "*" ? "*" : "^10.5.0";
new jsii_docgen_1.JsiiDocgen(project, {
version: docgenVersion,
filePath: options.docgenFilePath,
});
}
// jsii updates .npmignore, so we make it writable
if (project.npmignore) {
project.npmignore.readonly = false;
}
}
/**
* Adds a target language to the release workflow.
*/
addTargetToRelease(project, packTask, language, target) {
if (!project.release) {
return;
}
const pacmak = this.pacmakForLanguage(project, language, packTask);
const prePublishSteps = [
...pacmak.bootstrapSteps,
workflow_steps_1.WorkflowSteps.checkout({
with: {
path: REPO_TEMP_DIRECTORY,
...(project.github?.downloadLfs ? { lfs: true } : {}),
},
}),
...pacmak.packagingSteps,
];
const commonPublishOptions = {
publishTools: pacmak.publishTools,
prePublishSteps,
};
const handler = publishTo[language];
project.release?.publisher[handler]({
...commonPublishOptions,
...target,
});
}
/**
* Adds a target language to the build workflow.
*/
addTargetToBuild(project, packTask, language, extraJobOptions) {
if (!project.buildWorkflow) {
return;
}
const pacmak = this.pacmakForLanguage(project, language, packTask);
project.buildWorkflow.addPostBuildJob(`package-${language}`, {
...(0, runner_options_1.filteredRunsOnOptions)(extraJobOptions.runsOn, extraJobOptions.runsOnGroup),
permissions: {
contents: workflows_model_1.JobPermission.READ,
},
tools: {
node: {
version: this.options.workflowNodeVersion ??
// @ts-ignore
project.nodeVersion ??
"lts/*",
},
...pacmak.publishTools,
},
steps: [
...pacmak.bootstrapSteps,
workflow_steps_1.WorkflowSteps.checkout({
with: {
path: REPO_TEMP_DIRECTORY,
ref: consts_2.PULL_REQUEST_SHA,
repository: consts_2.PULL_REQUEST_REPOSITORY,
...(project.github?.downloadLfs ? { lfs: true } : {}),
},
}),
...pacmak.packagingSteps,
],
...extraJobOptions,
});
}
addPackagingTask(project, packageAllTask, language) {
const packageTargetTask = project.tasks.addTask(`package:${language}`, {
description: `Create ${language} language bindings`,
});
const commandParts = ["jsii-pacmak", "-v"];
if (project.package.packageManager === javascript_1.NodePackageManager.PNPM) {
commandParts.push("--pack-command", "pnpm pack");
}
commandParts.push("--target", language);
packageTargetTask.execArgs(commandParts);
packageAllTask.spawn(packageTargetTask);
return packageTargetTask;
}
pacmakForLanguage(project, target, packTask) {
const bootstrapSteps = [];
const packagingSteps = [];
// Generic bootstrapping for all target languages
bootstrapSteps.push(...(this.options.workflowBootstrapSteps ?? []));
if (project.package.packageManager === javascript_1.NodePackageManager.PNPM) {
bootstrapSteps.push({
name: "Setup pnpm",
uses: actions_const_1.GitHubActions.PNPM_ACTION_SETUP,
with: { version: project.package.pnpmVersion },
});
}
else if (project.package.packageManager === javascript_1.NodePackageManager.BUN) {
bootstrapSteps.push({
name: "Setup bun",
uses: actions_const_1.GitHubActions.OVEN_SH_SETUP_BUN,
with: { "bun-version": project.package.bunVersion },
});
}
else if ((0, util_1.isYarnBerry)(project.package.packageManager)) {
bootstrapSteps.push({
name: "Enable corepack",
run: "corepack enable",
});
}
const workDir = this.options.workspaceDirectory
? `${REPO_TEMP_DIRECTORY}/${this.options.workspaceDirectory}`
: REPO_TEMP_DIRECTORY;
// Installation steps before packaging, but after checkout
packagingSteps.push({
name: "Install Dependencies",
run: `cd ${REPO_TEMP_DIRECTORY} && ${project.package.installCommand}`,
}, {
name: "Extract build artifact",
run: `tar --strip-components=1 -xzvf ${project.artifactsDirectory}/js/*.tgz -C ${workDir}`,
}, {
name: `Move build artifact out of the way`,
run: `mv ${project.artifactsDirectory} ${BUILD_ARTIFACT_OLD_DIR}`,
}, {
name: `Create ${target} artifact`,
run: `cd ${workDir} && ${project.runTaskCommand(packTask)}`,
}, {
name: `Collect ${target} artifact`,
run: `mv ${workDir}/${project.artifactsDirectory} ${project.artifactsDirectory}`,
});
return {
publishTools: consts_1.JSII_TOOLCHAIN[target],
bootstrapSteps,
packagingSteps,
};
}
}
exports.JsiiBuild = JsiiBuild;
const publishTo = {
js: "publishToNpm",
java: "publishToMaven",
python: "publishToPyPi",
dotnet: "publishToNuget",
go: "publishToGo",
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNpaS1idWlsZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jZGsvanNpaS1idWlsZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBR0EscUNBQTBDO0FBQzFDLCtDQUEyQztBQU8zQyxvREFHaUM7QUFDakMsMkRBQXdEO0FBQ3hELDZEQUF5RDtBQUV6RCwrREFBMEQ7QUFDMUQsOENBQW1EO0FBRW5ELDZDQUFpRDtBQU1qRCxzREFBMEQ7QUFDMUQsOENBQWtEO0FBRWxELE1BQU0sbUJBQW1CLEdBQUcsT0FBTyxDQUFDO0FBQ3BDLE1BQU0sc0JBQXNCLEdBQUcsVUFBVSxDQUFDO0FBRTFDOztHQUVHO0FBQ0gsSUFBWSxnQkFvQlg7QUFwQkQsV0FBWSxnQkFBZ0I7SUFDMUI7O09BRUc7SUFDSCxxQ0FBaUIsQ0FBQTtJQUVqQjs7T0FFRztJQUNILDJDQUF1QixDQUFBO0lBRXZCOztPQUVHO0lBQ0gsdUNBQW1CLENBQUE7SUFFbkI7O09BRUc7SUFDSCwrQkFBVyxDQUFBO0FBQ2IsQ0FBQyxFQXBCVyxnQkFBZ0IsZ0NBQWhCLGdCQUFnQixRQW9CM0I7QUFxS0Q7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILE1BQWEsU0FBUzs7SUFDSCxPQUFPLENBQW1CO0lBQzFCLGVBQWUsQ0FBZTtJQUUvQyxZQUNFLFVBQTRCLEVBQUUsRUFDOUIsZUFBeUM7UUFFekMsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLGVBQWUsR0FBRyxDQUFDLGVBQWUsSUFBSSxFQUFFLENBQWlCLENBQUM7SUFDakUsQ0FBQztJQUVEOztPQUVHO0lBQ0ksUUFBUSxDQUFDLFNBQXFCO1FBQ25DLE9BQU8sU0FBUyxZQUFZLDhCQUFpQixDQUFDO0lBQ2hELENBQUM7SUFFRDs7T0FFRztJQUNJLE9BQU8sQ0FBQyxPQUFtQjtRQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQzVC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QU0sT0FBTyxDQUFDLGtCQUFrQixJQUFJLHNCQUFzQixFQUFFO1NBQ2xFLEVBQ0Q7WUFDRSxJQUFJLEVBQUUsVUFBVSxNQUFNLFdBQVc7WUFDakMsR0FBRyxFQUFFLE1BQU0sT0FBTyxPQUFPLE9BQU8sQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLEVBQUU7U0FDNUQsRUFDRDtZQUNFLElBQUksRUFBRSxXQUFXLE1BQU0sV0FBVztZQUNsQyxHQUFHLEVBQUUsTUFBTSxPQUFPLElBQUksT0FBTyxDQUFDLGtCQUFrQixJQUFJLE9BQU8sQ0FBQyxrQkFBa0IsRUFBRTtTQUNqRixDQUNGLENBQUM7UUFFRixPQUFPO1lBQ0wsWUFBWSxFQUFFLHVCQUFjLENBQUMsTUFBTSxDQUFDO1lBQ3BDLGNBQWM7WUFDZCxjQUFjO1NBQ2YsQ0FBQztJQUNKLENBQUM7O0FBdlpILDhCQXdaQztBQVlELE1BQU0sU0FBUyxHQUFvQjtJQUNqQyxFQUFFLEVBQUUsY0FBYztJQUNsQixJQUFJLEVBQUUsZ0JBQWdCO0lBQ3RCLE1BQU0sRUFBRSxlQUFlO0lBQ3ZCLE1BQU0sRUFBRSxnQkFBZ0I7SUFDeEIsRUFBRSxFQUFFLGFBQWE7Q0FDbEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgSUNvbnN0cnVjdCwgSU1peGluIH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB0eXBlIHsgVGFzayB9IGZyb20gXCIuLlwiO1xuaW1wb3J0IHR5cGUgeyBKc2lpUGFjbWFrVGFyZ2V0IH0gZnJvbSBcIi4vY29uc3RzXCI7XG5pbXBvcnQgeyBKU0lJX1RPT0xDSEFJTiB9IGZyb20gXCIuL2NvbnN0c1wiO1xuaW1wb3J0IHsgSnNpaURvY2dlbiB9IGZyb20gXCIuL2pzaWktZG9jZ2VuXCI7XG5pbXBvcnQgdHlwZSB7XG4gIEpzaWlEb3ROZXRUYXJnZXQsXG4gIEpzaWlHb1RhcmdldCxcbiAgSnNpaUphdmFUYXJnZXQsXG4gIEpzaWlQeXRob25UYXJnZXQsXG59IGZyb20gXCIuL2pzaWktcHJvamVjdFwiO1xuaW1wb3J0IHtcbiAgUFVMTF9SRVFVRVNUX1JFUE9TSVRPUlksXG4gIFBVTExfUkVRVUVTVF9TSEEsXG59IGZyb20gXCIuLi9idWlsZC9wcml2YXRlL2NvbnN0c1wiO1xuaW1wb3J0IHsgR2l0SHViQWN0aW9ucyB9IGZyb20gXCIuLi9naXRodWIvYWN0aW9ucy5jb25zdFwiO1xuaW1wb3J0IHsgV29ya2Zsb3dTdGVwcyB9IGZyb20gXCIuLi9naXRodWIvd29ya2Zsb3ctc3RlcHNcIjtcbmltcG9ydCB0eXBlIHsgSm9iLCBTdGVwLCBUb29scyB9IGZyb20gXCIuLi9naXRodWIvd29ya2Zsb3dzLW1vZGVsXCI7XG5pbXBvcnQgeyBKb2JQZXJtaXNzaW9uIH0gZnJvbSBcIi4uL2dpdGh1Yi93b3JrZmxvd3MtbW9kZWxcIjtcbmltcG9ydCB7IE5vZGVQYWNrYWdlTWFuYWdlciB9IGZyb20gXCIuLi9qYXZhc2NyaXB0XCI7XG5pbXBvcnQgdHlwZSB7IFR5cGVzY3JpcHRDb25maWcgfSBmcm9tIFwiLi4vamF2YXNjcmlwdFwiO1xuaW1wb3J0IHsgaXNZYXJuQmVycnkgfSBmcm9tIFwiLi4vamF2YXNjcmlwdC91dGlsXCI7XG5pbXBvcnQgdHlwZSB7XG4gIENvbW1vblB1Ymxpc2hPcHRpb25zLFxuICBOcG1QdWJsaXNoT3B0aW9ucyxcbiAgUHVibGlzaGVyLFxufSBmcm9tIFwiLi4vcmVsZWFzZVwiO1xuaW1wb3J0IHsgZmlsdGVyZWRSdW5zT25PcHRpb25zIH0gZnJvbSBcIi4uL3J1bm5lci1vcHRpb25zXCI7XG5pbXBvcnQgeyBUeXBlU2NyaXB0UHJvamVjdCB9IGZyb20gXCIuLi90eXBlc2NyaXB0XCI7XG5cbmNvbnN0IFJFUE9fVEVNUF9ESVJFQ1RPUlkgPSBcIi5yZXBvXCI7XG5jb25zdCBCVUlMRF9BUlRJRkFDVF9PTERfRElSID0gXCJkaXN0Lm9sZFwiO1xuXG4vKipcbiAqIExldmVsIG9mIHRzY29uZmlnIHZhbGlkYXRpb24ganNpaSBzaG91bGQgcGVyZm9ybS5cbiAqL1xuZXhwb3J0IGVudW0gVmFsaWRhdGVUc2NvbmZpZyB7XG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYWdhaW5zdCBhIHN0cmljdCBydWxlIHNldCBkZXNpZ25lZCBmb3Igd2lkZXNwcmVhZCBzdXBwb3J0IGFuZCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS5cbiAgICovXG4gIFNUUklDVCA9IFwic3RyaWN0XCIsXG5cbiAgLyoqXG4gICAqIEVuZm9yY2VzIGEgdHNjb25maWcgYXMgaWYgaXQgd2VyZSBnZW5lcmF0ZWQgYnkganNpaS5cbiAgICovXG4gIEdFTkVSQVRFRCA9IFwiZ2VuZXJhdGVkXCIsXG5cbiAgLyoqXG4gICAqIE9ubHkgcmVqZWN0IG9wdGlvbnMga25vd24gdG8gYmUgaW5jb21wYXRpYmxlIHdpdGgganNpaS5cbiAgICovXG4gIE1JTklNQUwgPSBcIm1pbmltYWxcIixcblxuICAvKipcbiAgICogRGlzYWJsZXMgYWxsIGNvbmZpZyB2YWxpZGF0aW9uLiBVc2UgYXQgeW91ciBvd24gcmlzay5cbiAgICovXG4gIE9GRiA9IFwib2ZmXCIsXG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgYEpzaWlCdWlsZGAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSnNpaUJ1aWxkT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBQdWJsaXNoIHRvIG1hdmVuXG4gICAqIEBkZWZhdWx0IC0gbm8gcHVibGlzaGluZ1xuICAgKi9cbiAgcmVhZG9ubHkgcHVibGlzaFRvTWF2ZW4/OiBKc2lpSmF2YVRhcmdldDtcblxuICAvKipcbiAgICogUHVibGlzaCB0byBweXBpXG4gICAqIEBkZWZhdWx0IC0gbm8gcHVibGlzaGluZ1xuICAgKi9cbiAgcmVhZG9ubHkgcHVibGlzaFRvUHlwaT86IEpzaWlQeXRob25UYXJnZXQ7XG5cbiAgLyoqXG4gICAqIFB1Ymxpc2ggR28gYmluZGluZ3MgdG8gYSBnaXQgcmVwb3NpdG9yeS5cbiAgICogQGRlZmF1bHQgLSBubyBwdWJsaXNoaW5nXG4gICAqL1xuICByZWFkb25seSBwdWJsaXNoVG9Hbz86IEpzaWlHb1RhcmdldDtcblxuICAvKipcbiAgICogUHVibGlzaCB0byBOdUdldFxuICAgKiBAZGVmYXVsdCAtIG5vIHB1Ymxpc2hpbmdcbiAgICovXG4gIHJlYWRvbmx5IHB1Ymxpc2hUb051Z2V0PzogSnNpaURvdE5ldFRhcmdldDtcblxuICAvKipcbiAgICogQXV0b21hdGljYWxseSBydW4gQVBJIGNvbXBhdGliaWxpdHkgdGVzdCBhZ2FpbnN0IHRoZSBsYXRlc3QgdmVyc2lvbiBwdWJsaXNoZWQgdG8gbnBtIGFmdGVyIGNvbXBpbGF0aW9uLlxuICAgKlxuICAgKiAtIFlvdSBjYW4gbWFudWFsbHkgcnVuIGNvbXBhdGliaWxpdHkgdGVzdHMgdXNpbmcgYHlhcm4gY29tcGF0YCBpZiB0aGlzIGZlYXR1cmUgaXMgZGlzYWJsZWQuXG4gICAqIC0gWW91IGNhbiBpZ25vcmUgY29tcGF0aWJpbGl0eSBmYWlsdXJlcyBieSBhZGRpbmcgbGluZXMgdG8gYSBcIi5jb21wYXRpZ25vcmVcIiBmaWxlLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgY29tcGF0PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogTmFtZSBvZiB0aGUgaWdub3JlIGZpbGUgZm9yIEFQSSBjb21wYXRpYmlsaXR5IHRlc3RzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBcIi5jb21wYXRpZ25vcmVcIlxuICAgKi9cbiAgcmVhZG9ubHkgY29tcGF0SWdub3JlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBY2NlcHRzIGEgbGlzdCBvZiBnbG9iIHBhdHRlcm5zLiBGaWxlcyBtYXRjaGluZyBhbnkgb2YgdGhvc2UgcGF0dGVybnMgd2lsbCBiZSBleGNsdWRlZCBmcm9tIHRoZSBUeXBlU2NyaXB0IGNvbXBpbGVyIGlucHV0LlxuICAgKlxuICAgKiBCeSBkZWZhdWx0LCBqc2lpIHdpbGwgaW5jbHVkZSBhbGwgKi50cyBmaWxlcyAoZXhjZXB0IC5kLnRzIGZpbGVzKSBpbiB0aGUgVHlwZVNjcmlwdCBjb21waWxlciBpbnB1dC5cbiAgICogVGhpcyBjYW4gYmUgcHJvYmxlbWF0aWMgZm9yIGV4YW1wbGUgd2hlbiB0aGUgcGFja2FnZSdzIGJ1aWxkIG9yIHRlc3QgcHJvY2VkdXJlIGdlbmVyYXRlcyAudHMgZmlsZXNcbiAgICogdGhhdCBjYW5ub3QgYmUgY29tcGlsZWQgd2l0aCBqc2lpJ3MgY29tcGlsZXIgc2V0dGluZ3MuXG4gICAqL1xuICByZWFkb25seSBleGNsdWRlVHlwZXNjcmlwdD86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBGaWxlIHBhdGggZm9yIGdlbmVyYXRlZCBkb2NzLlxuICAgKiBAZGVmYXVsdCBcIkFQSS5tZFwiXG4gICAqL1xuICByZWFkb25seSBkb2NnZW5GaWxlUGF0aD86IHN0cmluZztcblxuICAvKipcbiAgICogRW1pdCBhIGNvbXByZXNzZWQgdmVyc2lvbiBvZiB0aGUgYXNzZW1ibHlcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGNvbXByZXNzQXNzZW1ibHk/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBWZXJzaW9uIG9mIHRoZSBqc2lpIGNvbXBpbGVyIHRvIHVzZS5cbiAgICpcbiAgICogU2V0IHRvIFwiKlwiIGlmIHlvdSB3YW50IHRvIG1hbnVhbGx5IG1hbmFnZSB0aGUgdmVyc2lvbiBvZiBqc2lpIGluIHlvdXJcbiAgICogcHJvamVjdCBieSBtYW5hZ2luZyB1cGRhdGVzIHRvIGBwYWNrYWdlLmpzb25gIG9uIHlvdXIgb3duLlxuICAgKlxuICAgKiBOT1RFOiBUaGUganNpaSBjb21waWxlciByZWxlYXNlcyBzaW5jZSA1LjAuMCBhcmUgbm90IHNlbWFudGljYWxseSB2ZXJzaW9uZWRcbiAgICogYW5kIHNob3VsZCByZW1haW4gb24gdGhlIHNhbWUgbWlub3IsIHNvIHdlIHJlY29tbWVuZCB1c2luZyBhIGB+YCBkZXBlbmRlbmN5XG4gICAqIChlLmcuIGB+NS4wLjBgKS5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJ+NS45LjBcIlxuICAgKi9cbiAgcmVhZG9ubHkganNpaVZlcnNpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBzdGFiaWxpdHkgb2YgdGhlIHBhY2thZ2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IFwic3RhYmxlXCJcbiAgICovXG4gIHJlYWRvbmx5IHN0YWJpbGl0eT86IHN0cmluZztcblxuICAvKipcbiAgICogR2VuZXJhdGUgYSBNYXJrRG93biBmaWxlIGRlc2NyaWJpbmcgdGhlIGpzaWkgQVBJLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBkb2NnZW4/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHB1Ymxpc2ggdG8gbnBtLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSByZWxlYXNlVG9OcG0/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHVzZSB0cnVzdGVkIHB1Ymxpc2hpbmcgZm9yIG5wbS5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IG5wbVRydXN0ZWRQdWJsaXNoaW5nPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogT3B0aW9ucyBmb3IgcHVibGlzaGluZyBucG0gcGFja2FnZSB0byBBV1MgQ29kZUFydGlmYWN0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHVuZGVmaW5lZFxuICAgKi9cbiAgcmVhZG9ubHkgY29kZUFydGlmYWN0T3B0aW9ucz86IE5wbVB1Ymxpc2hPcHRpb25zW1wiY29kZUFydGlmYWN0T3B0aW9uc1wiXTtcblxuICAvKipcbiAgICogUmVsYXRpdmUgcGF0aCBvZiB0aGUgcGFja2FnZSB3aXRoaW4gdGhlIHJlcG9zaXRvcnkuXG4gICAqXG4gICAqIFRoaXMgaXMgdXNlZCBpbiBtb25vcmVwbyBzZXR1cHMgd2hlcmUgdGhlIHBhY2thZ2UgaXMgbm90IGF0IHRoZSByb290LlxuICAgKiBQYWNrYWdpbmcgc3RlcHMgd2lsbCBleHRyYWN0IGJ1aWxkIGFydGlmYWN0cyBpbnRvIHRoaXMgc3ViZGlyZWN0b3J5LlxuICAgKlxuICAgKiBAZGVmYXVsdCBcIi5cIiAtIHJvb3Qgb2YgdGhlIHJlcG9zaXRvcnlcbiAgICovXG4gIHJlYWRvbmx5IHdvcmtzcGFjZURpcmVjdG9yeT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG5vZGUgdmVyc2lvbiB0byB1c2UgaW4gcGFja2FnaW5nIHdvcmtmbG93cy5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJsdHMvKlwiXG4gICAqL1xuICByZWFkb25seSB3b3JrZmxvd05vZGVWZXJzaW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIHN0ZXBzIHRvIHJ1biBiZWZvcmUgcGFja2FnaW5nIGluIHdvcmtmbG93cy5cbiAgICpcbiAgICogQGRlZmF1bHQgW11cbiAgICovXG4gIHJlYWRvbmx5IHdvcmtmbG93Qm9vdHN0cmFwU3RlcHM/OiBBcnJheTxTdGVwPjtcblxuICAvKipcbiAgICogTGV2ZWwgb2YgdHNjb25maWcgdmFsaWRhdGlvbiBqc2lpIHNob3VsZCBwZXJmb3JtIG9uIHRoZSB1c2VyLXByb3ZpZGVkIHRzY29uZmlnLlxuICAgKlxuICAgKiBPbmx5IHJlbGV2YW50IHdoZW4gdGhlIHByb2plY3Qgc3ludGhlc2l6ZXMgaXRzIG93biB0c2NvbmZpZ1xuICAgKiAoaS5lLiBgZGlzYWJsZVRzY29uZmlnYCBpcyBub3Qgc2V0IG9uIHRoZSBUeXBlU2NyaXB0UHJvamVjdCkuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9hd3MuZ2l0aHViLmlvL2pzaWkvdXNlci1ndWlkZXMvbGliLWF1dGhvci9jb25maWd1cmF0aW9uLyN2YWxpZGF0ZXRzY29uZmlnXG4gICAqIEBkZWZhdWx0IFZhbGlkYXRlVHNjb25maWcuU1RSSUNUXG4gICAqL1xuICByZWFkb25seSB2YWxpZGF0ZVRzY29uZmlnPzogVmFsaWRhdGVUc2NvbmZpZztcblxuICAvKipcbiAgICogVGhlIFR5cGVzY3JpcHRDb25maWcgdGhhdCBqc2lpIGNvbXBpbGVzIGFnYWluc3QuXG4gICAqXG4gICAqIFByb3ZpZGUgYSBkZWRpY2F0ZWQgY29uZmlnIChlLmcuIG9uZSBuYW1lZCBgdHNjb25maWcuanNpaS5qc29uYCkgdG8ga2VlcFxuICAgKiBqc2lpIGNvbXBpbGF0aW9uIHNlcGFyYXRlIGZyb20gdGhlIHByb2plY3QncyBlZGl0b3ItZmFjaW5nIGB0c2NvbmZpZy5qc29uYC5cbiAgICoganNpaSByZXF1aXJlcyBhIGNvbW1lbnQtZnJlZSwgc3RyaWN0LXZhbGlkIGNvbmZpZywgc28gYEpzaWlCdWlsZGAgZGlzYWJsZXNcbiAgICogY29tbWVudHMgb24gd2hpY2hldmVyIGNvbmZpZyBpdCBpcyBnaXZlbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB0aGUgcHJvamVjdCdzIHRzY29uZmlnIChpLmUuIGBwcm9qZWN0LnRzY29uZmlnYClcbiAgICovXG4gIHJlYWRvbmx5IHRzY29uZmlnPzogVHlwZXNjcmlwdENvbmZpZztcbn1cblxuLyoqXG4gKiBBIG1peGluIHRoYXQgYWRkcyBqc2lpIGNvbXBpbGF0aW9uLCBtdWx0aS1sYW5ndWFnZSBwYWNrYWdpbmcsIGFuZCBwdWJsaXNoaW5nXG4gKiBjYXBhYmlsaXRpZXMgdG8gYW55IFR5cGVTY3JpcHQgcHJvamVjdC5cbiAqXG4gKiBUaGlzIGltcGxlbWVudHMgdGhlIGNvbnN0cnVjdHMgYElNaXhpbmAgaW50ZXJmYWNlIGFuZCBpcyBhcHBsaWVkIHVzaW5nIHRoZVxuICogYC53aXRoKClgIG1ldGhvZCBvbiBhbnkgY29uc3RydWN0LlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBwcm9qZWN0ID0gbmV3IFR5cGVTY3JpcHRQcm9qZWN0KHsgZGlzYWJsZVRzY29uZmlnOiB0cnVlLCAuLi4gfSk7XG4gKiBwcm9qZWN0LndpdGgobmV3IEpzaWlCdWlsZCh7XG4gKiAgIGpzaWlWZXJzaW9uOiAnfjUuOS4wJyxcbiAqICAgcHVibGlzaFRvTWF2ZW46IHsgLi4uIH0sXG4gKiB9KSk7XG4gKi9cbmV4cG9ydCBjbGFzcyBKc2lpQnVpbGQgaW1wbGVtZW50cyBJTWl4aW4ge1xuICBwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM6IEpzaWlCdWlsZE9wdGlvbnM7XG4gIHByaXZhdGUgcmVhZG9ubHkgZXh0cmFKb2JPcHRpb25zOiBQYXJ0aWFsPEpvYj47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgb3B0aW9uczogSnNpaUJ1aWxkT3B0aW9ucyA9IHt9LFxuICAgIGV4dHJhSm9iT3B0aW9ucz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICApIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIHRoaXMuZXh0cmFKb2JPcHRpb25zID0gKGV4dHJhSm9iT3B0aW9ucyA/PyB7fSkgYXMgUGFydGlhbDxKb2I+O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY29uc3RydWN0IGlzIGEgVHlwZVNjcmlwdFByb2plY3QuXG4gICAqL1xuICBwdWJsaWMgc3VwcG9ydHMoY29uc3RydWN0OiBJQ29uc3RydWN0KTogY29uc3RydWN0IGlzIFR5cGVTY3JpcHRQcm9qZWN0IHtcbiAgICByZXR1cm4gY29uc3RydWN0IGluc3RhbmNlb2YgVHlwZVNjcmlwdFByb2plY3Q7XG4gIH1cblxuICAvKipcbiAgICogQXBwbGllcyBqc2lpIGNvbmZpZ3VyYXRpb24gdG8gdGhlIHRhcmdldCBUeXBlU2NyaXB0UHJvamVjdC5cbiAgICovXG4gIHB1YmxpYyBhcHBseVRvKHByb2plY3Q6IElDb25zdHJ1Y3QpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc3VwcG9ydHMocHJvamVjdCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBvcHRpb25zID0geyAuLi50aGlzLm9wdGlvbnMgfTtcbiAgICBjb25zdCBzcmNkaXIgPSBwcm9qZWN0LnNyY2RpcjtcbiAgICBjb25zdCBsaWJkaXIgPSBwcm9qZWN0LmxpYmRpcjtcblxuICAgIHByb2plY3QuYWRkRmllbGRzKHsgdHlwZXM6IGAke2xpYmRpcn0vaW5kZXguZC50c2AgfSk7XG5cbiAgICBjb25zdCBjb21wcmVzc0Fzc2VtYmx5ID0gb3B0aW9ucy5jb21wcmVzc0Fzc2VtYmx5ID8/IGZhbHNlO1xuXG4gICAgLy8gdGhpcyBpcyBhbiB1bmhlbHBmdWwgd2FybmluZ1xuICAgIGNvbnN0IGpzaWlGbGFncyA9IFtcIi0tc2lsZW5jZS13YXJuaW5ncz1yZXNlcnZlZC13b3JkXCJdO1xuICAgIGlmIChjb21wcmVzc0Fzc2VtYmx5KSB7XG4gICAgICBqc2lpRmxhZ3MucHVzaChcIi0tY29tcHJlc3MtYXNzZW1ibHlcIik7XG4gICAgfVxuXG4gICAgY29uc3QgY29tcGF0SWdub3JlID0gb3B0aW9ucy5jb21wYXRJZ25vcmUgPz8gXCIuY29tcGF0aWdub3JlXCI7XG5cbiAgICBwcm9qZWN0LmFkZEZpZWxkcyh7XG4gICAgICBzdGFiaWxpdHk6XG4gICAgICAgIG9wdGlvbnMuc3RhYmlsaXR5ID8/IHByb2plY3QucGFja2FnZS5tYW5pZmVzdC5zdGFiaWxpdHkgPz8gXCJzdGFibGVcIixcbiAgICB9KTtcblxuICAgIGlmIChvcHRpb25zLnN0YWJpbGl0eSA9PT0gXCJkZXByZWNhdGVkXCIpIHtcbiAgICAgIHByb2plY3QuYWRkRmllbGRzKHsgZGVwcmVjYXRlZDogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBwcm9qZWN0LmNvbXBpbGVUYXNrLnJlc2V0KFtcImpzaWlcIiwgLi4uanNpaUZsYWdzXS5qb2luKFwiIFwiKSk7XG4gICAgcHJvamVjdC53YXRjaFRhc2sucmVzZXQoW1wianNpaVwiLCBcIi13XCIsIC4uLmpzaWlGbGFnc10uam9pbihcIiBcIikpO1xuXG4gICAgY29uc3QgY29tcGF0VGFzayA9IHByb2plY3QuYWRkVGFzayhcImNvbXBhdFwiLCB7XG4gICAgICBkZXNjcmlwdGlvbjogYFBlcmZvcm0gQVBJIGNvbXBhdGliaWxpdHkgY2hlY2sgYWdhaW5zdCBsYXRlc3QgdmVyc2lvbmAsXG4gICAgICBleGVjQXJnczogW1xuICAgICAgICBcImpzaWktZGlmZlwiLFxuICAgICAgICBgbnBtOiR7cHJvamVjdC5wYWNrYWdlLnBhY2thZ2VOYW1lfWAsXG4gICAgICAgIFwiLWtcIixcbiAgICAgICAgXCItLWlnbm9yZS1maWxlXCIsXG4gICAgICAgIGNvbXBhdElnbm9yZSxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICBpZiAob3B0aW9ucy5jb21wYXQgPz8gZmFsc2UpIHtcbiAgICAgIHByb2plY3QuY29tcGlsZVRhc2suc3Bhd24oY29tcGF0VGFzayk7XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlIGEgbmV3IHBhY2thZ2U6YWxsIHRhc2ssIGl0IHdpbGwgYmUgZmlsbGVkIHdpdGggbGFuZ3VhZ2UgdGFyZ2V0cyBsYXRlclxuICAgIGNvbnN0IHBhY2thZ2VBbGxUYXNrID0gcHJvamVjdC5hZGRUYXNrKFwicGFja2FnZS1hbGxcIiwge1xuICAgICAgZGVzY3JpcHRpb246IFwiUGFja2FnZXMgYXJ0aWZhY3RzIGZvciBhbGwgdGFyZ2V0IGxhbmd1YWdlc1wiLFxuICAgIH0pO1xuXG4gICAgLy8gaW4ganNpaSB3ZSBjb25zaWRlciB0aGUgZW50aXJlIHJlcG8gKHBvc3QgYnVpbGQpIGFzIHRoZSBidWlsZCBhcnRpZmFjdFxuICAgIC8vIHdoaWNoIGlzIHRoZW4gdXNlZCB0byBjcmVhdGUgdGhlIGxhbmd1YWdlIGJpbmRpbmdzIGluIHNlcGFyYXRlIGpvYnMuXG4gICAgY29uc3QgcGFja2FnZUpzVGFzayA9IHRoaXMuYWRkUGFja2FnaW5nVGFzayhwcm9qZWN0LCBwYWNrYWdlQWxsVGFzaywgXCJqc1wiKTtcblxuICAgIC8vIFdoZW4gcnVubmluZyBpbnNpZGUgQ0kgd2UgaW5pdGlhbGx5IG9ubHkgcGFja2FnZSBqcy4gT3RoZXIgdGFyZ2V0cyBhcmUgcGFja2FnZWQgaW4gc2VwYXJhdGUgam9icy5cbiAgICAvLyBPdXRzaWRlIG9mIENJIChpLmUgbG9jYWxseSkgd2Ugc2ltcGx5IHBhY2thZ2UgYWxsIHRhcmdldHMuXG4gICAgcHJvamVjdC5wYWNrYWdlVGFzay5yZXNldCgpO1xuICAgIHByb2plY3QucGFja2FnZVRhc2suc3Bhd24ocGFja2FnZUpzVGFzaywge1xuICAgICAgLy8gT25seSBydW4gaW4gQ0lcbiAgICAgIGNvbmRpdGlvbjogYG5vZGUgLWUgXCJpZiAoIXByb2Nlc3MuZW52LkNJKSBwcm9jZXNzLmV4aXQoMSlcImAsXG4gICAgfSk7XG4gICAgcHJvamVjdC5wYWNrYWdlVGFzay5zcGF3bihwYWNrYWdlQWxsVGFzaywge1xuICAgICAgLy8gRG9uJ3QgcnVuIGluIENJXG4gICAgICBjb25kaXRpb246IGBub2RlIC1lIFwiaWYgKHByb2Nlc3MuZW52LkNJKSBwcm9jZXNzLmV4aXQoMSlcImAsXG4gICAgfSk7XG5cbiAgICBjb25zdCB0YXJnZXRzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG5cbiAgICBjb25zdCBqc2lpOiBhbnkgPSB7XG4gICAgICBvdXRkaXI6IHByb2plY3QuYXJ0aWZhY3RzRGlyZWN0b3J5LFxuICAgICAgdGFyZ2V0cyxcbiAgICB9O1xuXG4gICAgLy8ganNpaSBjb21waWxlcyBhZ2FpbnN0IGFuIGV4cGxpY2l0bHkgcHJvdmlkZWQgdHNjb25maWcsIGZhbGxpbmcgYmFjayB0b1xuICAgIC8vIHRoZSBwcm9qZWN0J3Mgb3duIHRzY29uZmlnIHdoZW4gb25lIGlzIG5vdCBpbmplY3RlZC4gV2hlbiBuZWl0aGVyIGlzXG4gICAgLy8gYXZhaWxhYmxlIChlLmcuIGBkaXNhYmxlVHNjb25maWdgKSwgbGV0IGpzaWkgZ2VuZXJhdGUgb25lIGZyb20gdHNjIHNldHRpbmdzLlxuICAgIGNvbnN0IHRzY29uZmlnID0gb3B0aW9ucy50c2NvbmZpZyA/PyBwcm9qZWN0LnRzY29uZmlnO1xuICAgIGlmICh0c2NvbmZpZykge1xuICAgICAgLy8gQHRzLWlnbm9yZSBqc2lpIHVzZXMgSlNPTi5wYXJzZSgpIGFuZCBjYW5ub3QgaGFuZGxlIGNvbW1lbnRzXG4gICAgICB0c2NvbmZpZy5maWxlLmNvbmZpZ3VyZUNvbW1lbnRzKGZhbHNlKTtcbiAgICAgIGpzaWkudHNjb25maWcgPSB0c2NvbmZpZy5maWxlTmFtZTtcbiAgICAgIGpzaWkudmFsaWRhdGVUc2NvbmZpZyA9XG4gICAgICAgIG9wdGlvbnMudmFsaWRhdGVUc2NvbmZpZyA/PyBWYWxpZGF0ZVRzY29uZmlnLlNUUklDVDtcblxuICAgICAgaWYgKG9wdGlvbnMuZXhjbHVkZVR5cGVzY3JpcHQpIHtcbiAgICAgICAgZm9yIChjb25zdCBwYXR0ZXJuIG9mIG9wdGlvbnMuZXhjbHVkZVR5cGVzY3JpcHQpIHtcbiAgICAgICAgICB0c2NvbmZpZy5hZGRFeGNsdWRlKHBhdHRlcm4pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGpzaWkudHNjID0ge1xuICAgICAgICBvdXREaXI6IGxpYmRpcixcbiAgICAgICAgcm9vdERpcjogc3JjZGlyLFxuICAgICAgfTtcbiAgICAgIGlmIChvcHRpb25zLmV4Y2x1ZGVUeXBlc2NyaXB0KSB7XG4gICAgICAgIGpzaWkuZXhjbHVkZVR5cGVzY3JpcHQgPSBvcHRpb25zLmV4Y2x1ZGVUeXBlc2NyaXB0O1xuICAgICAgfVxuICAgIH1cblxuICAgIHByb2plY3QuYWRkRmllbGRzKHsganNpaSB9KTtcblxuICAgIGNvbnN0IGV4dHJhSm9iT3B0aW9uczogUGFydGlhbDxKb2I+ID0gdGhpcy5leHRyYUpvYk9wdGlvbnM7XG5cbiAgICBpZiAob3B0aW9ucy5yZWxlYXNlVG9OcG0gIT09IGZhbHNlKSB7XG4gICAgICBjb25zdCBucG1qczogTnBtUHVibGlzaE9wdGlvbnMgPSB7XG4gICAgICAgIHJlZ2lzdHJ5OiBwcm9qZWN0LnBhY2thZ2UubnBtUmVnaXN0cnksXG4gICAgICAgIG5wbVRva2VuU2VjcmV0OiBwcm9qZWN0LnBhY2thZ2UubnBtVG9rZW5TZWNyZXQsXG4gICAgICAgIG5wbVByb3ZlbmFuY2U6IHByb2plY3QucGFja2FnZS5ucG1Qcm92ZW5hbmNlLFxuICAgICAgICBjb2RlQXJ0aWZhY3RPcHRpb25zOiBvcHRpb25zLmNvZGVBcnRpZmFjdE9wdGlvbnMsXG4gICAgICAgIHRydXN0ZWRQdWJsaXNoaW5nOlxuICAgICAgICAgIG9wdGlvbnMubnBtVHJ1c3RlZFB1Ymxpc2hpbmcgPz9cbiAgICAgICAgICAvL0B0cy1pZ25vcmVcbiAgICAgICAgICBwcm9qZWN0Lm9wdGlvbnMubnBtVHJ1c3RlZFB1Ymxpc2hpbmcgPz9cbiAgICAgICAgICBmYWxzZSxcbiAgICAgIH07XG4gICAgICB0aGlzLmFkZFRhcmdldFRvQnVpbGQocHJvamVjdCwgcGFja2FnZUpzVGFzaywgXCJqc1wiLCBleHRyYUpvYk9wdGlvbnMpO1xuICAgICAgdGhpcy5hZGRUYXJnZXRUb1JlbGVhc2UocHJvamVjdCwgcGFja2FnZUpzVGFzaywgXCJqc1wiLCBucG1qcyk7XG4gICAgfVxuXG4gICAgY29uc3QgbWF2ZW4gPSBvcHRpb25zLnB1Ymxpc2hUb01hdmVuO1xuICAgIGlmIChtYXZlbikge1xuICAgICAgdGFyZ2V0cy5qYXZhID0ge1xuICAgICAgICBwYWNrYWdlOiBtYXZlbi5qYXZhUGFja2FnZSxcbiAgICAgICAgbWF2ZW46IHtcbiAgICAgICAgICBncm91cElkOiBtYXZlbi5tYXZlbkdyb3VwSWQsXG4gICAgICAgICAgYXJ0aWZhY3RJZDogbWF2ZW4ubWF2ZW5BcnRpZmFjdElkLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdGFzayA9IHRoaXMuYWRkUGFja2FnaW5nVGFzayhwcm9qZWN0LCBwYWNrYWdlQWxsVGFzaywgXCJqYXZhXCIpO1xuICAgICAgdGhpcy5hZGRUYXJnZXRUb0J1aWxkKHByb2plY3QsIHRhc2ssIFwiamF2YVwiLCBleHRyYUpvYk9wdGlvbnMpO1xuICAgICAgdGhpcy5hZGRUYXJnZXRUb1JlbGVhc2UocHJvamVjdCwgdGFzaywgXCJqYXZhXCIsIG1hdmVuKTtcbiAgICB9XG5cbiAgICBjb25zdCBweXBpID0gb3B0aW9ucy5wdWJsaXNoVG9QeXBpO1xuICAgIGlmIChweXBpKSB7XG4gICAgICB0YXJnZXRzLnB5dGhvbiA9IHtcbiAgICAgICAgZGlzdE5hbWU6IHB5cGkuZGlzdE5hbWUsXG4gICAgICAgIG1vZHVsZTogcHlwaS5tb2R1bGUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0YXNrID0gdGhpcy5hZGRQYWNrYWdpbmdUYXNrKHByb2plY3QsIHBhY2thZ2VBbGxUYXNrLCBcInB5dGhvblwiKTtcbiAgICAgIHRoaXMuYWRkVGFyZ2V0VG9CdWlsZChwcm9qZWN0LCB0YXNrLCBcInB5dGhvblwiLCBleHRyYUpvYk9wdGlvbnMpO1xuICAgICAgdGhpcy5hZGRUYXJnZXRUb1JlbGVhc2UocHJvamVjdCwgdGFzaywgXCJweXRob25cIiwgcHlwaSk7XG4gICAgfVxuXG4gICAgY29uc3QgbnVnZXQgPSBvcHRpb25zLnB1Ymxpc2hUb051Z2V0O1xuICAgIGlmIChudWdldCkge1xuICAgICAgdGFyZ2V0cy5kb3RuZXQgPSB7XG4gICAgICAgIG5hbWVzcGFjZTogbnVnZXQuZG90TmV0TmFtZXNwYWNlLFxuICAgICAgICBwYWNrYWdlSWQ6IG51Z2V0LnBhY2thZ2VJZCxcbiAgICAgICAgaWNvblVybDogbnVnZXQuaWNvblVybCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHRhc2sgPSB0aGlzLmFkZFBhY2thZ2luZ1Rhc2socHJvamVjdCwgcGFja2FnZUFsbFRhc2ssIFwiZG90bmV0XCIpO1xuICAgICAgdGhpcy5hZGRUYXJnZXRUb0J1aWxkKHByb2plY3QsIHRhc2ssIFwiZG90bmV0XCIsIGV4dHJhSm9iT3B0aW9ucyk7XG4gICAgICB0aGlzLmFkZFRhcmdldFRvUmVsZWFzZShwcm9qZWN0LCB0YXNrLCBcImRvdG5ldFwiLCBudWdldCk7XG4gICAgfVxuXG4gICAgY29uc3QgZ29sYW5nID0gb3B0aW9ucy5wdWJsaXNoVG9HbztcbiAgICBpZiAoZ29sYW5nKSB7XG4gICAgICB0YXJnZXRzLmdvID0ge1xuICAgICAgICBtb2R1bGVOYW1lOiBnb2xhbmcubW9kdWxlTmFtZSxcbiAgICAgICAgcGFja2FnZU5hbWU6IGdvbGFuZy5wYWNrYWdlTmFtZSxcbiAgICAgICAgdmVyc2lvblN1ZmZpeDogZ29sYW5nLnZlcnNpb25TdWZmaXgsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0YXNrID0gdGhpcy5hZGRQYWNrYWdpbmdUYXNrKHByb2plY3QsIHBhY2thZ2VBbGxUYXNrLCBcImdvXCIpO1xuICAgICAgdGhpcy5hZGRUYXJnZXRUb0J1aWxkKHByb2plY3QsIHRhc2ssIFwiZ29cIiwgZXh0cmFKb2JPcHRpb25zKTtcbiAgICAgIHRoaXMuYWRkVGFyZ2V0VG9SZWxlYXNlKHByb2plY3QsIHRhc2ssIFwiZ29cIiwgZ29sYW5nKTtcbiAgICB9XG5cbiAgICAvLyBJZiBqc2lpVmVyc2lvbiBpcyBcIipcIiwgZG9uJ3Qgc3BlY2lmeSBhbnl0aGluZyBzbyB0aGUgdXNlciBjYW4gbWFuYWdlLlxuICAgIC8vIE90aGVyd2lzZSwgdXNlIGBqc2lpVmVyc2lvbmBcbiAgICBjb25zdCBqc2lpVmVyc2lvbiA9IG9wdGlvbnMuanNpaVZlcnNpb24gPz8gXCJ+NS45LjBcIjtcbiAgICBjb25zdCBqc2lpU3VmZml4ID0ganNpaVZlcnNpb24gPT09IFwiKlwiID8gXCJcIiA6IGBAJHtqc2lpVmVyc2lvbn1gO1xuICAgIHByb2plY3QuYWRkRGV2RGVwcyhcbiAgICAgIGBqc2lpJHtqc2lpU3VmZml4fWAsXG4gICAgICBganNpaS1yb3NldHRhJHtqc2lpU3VmZml4fWAsXG4gICAgICBcImpzaWktZGlmZlwiLFxuICAgICAgXCJqc2lpLXBhY21ha1wiLFxuICAgICk7XG5cbiAgICBwcm9qZWN0LmdpdGlnbm9yZS5leGNsdWRlKFwiLmpzaWlcIik7XG4gICAgaWYgKCF0c2NvbmZpZykge1xuICAgICAgcHJvamVjdC5naXRpZ25vcmUuZXhjbHVkZShcInRzY29uZmlnLmpzb25cIik7XG4gICAgfVxuICAgIHByb2plY3QubnBtaWdub3JlPy5pbmNsdWRlKFwiLmpzaWlcIik7XG5cbiAgICBpZiAob3B0aW9ucy5kb2NnZW4gPz8gdHJ1ZSkge1xuICAgICAgLy8gSWYganNpaVZlcnNpb24gaXMgXCIqXCIsIGRvbid0IHNwZWNpZnkgYW55dGhpbmcgc28gdGhlIHVzZXIgY2FuIG1hbmFnZS5cbiAgICAgIC8vIE90aGVyd2lzZSB1c2UgYSB2ZXJzaW9uIHRoYXQgaXMgY29tcGF0aWJsZSB3aXRoIGFsbCBzdXBwb3J0ZWQganNpaSByZWxlYXNlcy5cbiAgICAgIGNvbnN0IGRvY2dlblZlcnNpb24gPSBvcHRpb25zLmpzaWlWZXJzaW9uID09PSBcIipcIiA/IFwiKlwiIDogXCJeMTAuNS4wXCI7XG4gICAgICBuZXcgSnNpaURvY2dlbihwcm9qZWN0LCB7XG4gICAgICAgIHZlcnNpb246IGRvY2dlblZlcnNpb24sXG4gICAgICAgIGZpbGVQYXRoOiBvcHRpb25zLmRvY2dlbkZpbGVQYXRoLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8ganNpaSB1cGRhdGVzIC5ucG1pZ25vcmUsIHNvIHdlIG1ha2UgaXQgd3JpdGFibGVcbiAgICBpZiAocHJvamVjdC5ucG1pZ25vcmUpIHtcbiAgICAgIHByb2plY3QubnBtaWdub3JlLnJlYWRvbmx5ID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSB0YXJnZXQgbGFuZ3VhZ2UgdG8gdGhlIHJlbGVhc2Ugd29ya2Zsb3cuXG4gICAqL1xuICBwcml2YXRlIGFkZFRhcmdldFRvUmVsZWFzZShcbiAgICBwcm9qZWN0OiBUeXBlU2NyaXB0UHJvamVjdCxcbiAgICBwYWNrVGFzazogVGFzayxcbiAgICBsYW5ndWFnZTogSnNpaVBhY21ha1RhcmdldCxcbiAgICB0YXJnZXQ6XG4gICAgICB8IEpzaWlQeXRob25UYXJnZXRcbiAgICAgIHwgSnNpaURvdE5ldFRhcmdldFxuICAgICAgfCBKc2lpR29UYXJnZXRcbiAgICAgIHwgSnNpaUphdmFUYXJnZXRcbiAgICAgIHwgTnBtUHVibGlzaE9wdGlvbnMsXG4gICkge1xuICAgIGlmICghcHJvamVjdC5yZWxlYXNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcGFjbWFrID0gdGhpcy5wYWNtYWtGb3JMYW5ndWFnZShwcm9qZWN0LCBsYW5ndWFnZSwgcGFja1Rhc2spO1xuICAgIGNvbnN0IHByZVB1Ymxpc2hTdGVwcyA9IFtcbiAgICAgIC4uLnBhY21hay5ib290c3RyYXBTdGVwcyxcbiAgICAgIFdvcmtmbG93U3RlcHMuY2hlY2tvdXQoe1xuICAgICAgICB3aXRoOiB7XG4gICAgICAgICAgcGF0aDogUkVQT19URU1QX0RJUkVDVE9SWSxcbiAgICAgICAgICAuLi4ocHJvamVjdC5naXRodWI/LmRvd25sb2FkTGZzID8geyBsZnM6IHRydWUgfSA6IHt9KSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICAgLi4ucGFjbWFrLnBhY2thZ2luZ1N0ZXBzLFxuICAgIF07XG4gICAgY29uc3QgY29tbW9uUHVibGlzaE9wdGlvbnM6IENvbW1vblB1Ymxpc2hPcHRpb25zID0ge1xuICAgICAgcHVibGlzaFRvb2xzOiBwYWNtYWsucHVibGlzaFRvb2xzLFxuICAgICAgcHJlUHVibGlzaFN0ZXBzLFxuICAgIH07XG5cbiAgICBjb25zdCBoYW5kbGVyOiBQdWJsaXNoVG8gPSBwdWJsaXNoVG9bbGFuZ3VhZ2VdO1xuICAgIHByb2plY3QucmVsZWFzZT8ucHVibGlzaGVyW2hhbmRsZXJdKHtcbiAgICAgIC4uLmNvbW1vblB1Ymxpc2hPcHRpb25zLFxuICAgICAgLi4udGFyZ2V0LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSB0YXJnZXQgbGFuZ3VhZ2UgdG8gdGhlIGJ1aWxkIHdvcmtmbG93LlxuICAgKi9cbiAgcHJpdmF0ZSBhZGRUYXJnZXRUb0J1aWxkKFxuICAgIHByb2plY3Q6IFR5cGVTY3JpcHRQcm9qZWN0LFxuICAgIHBhY2tUYXNrOiBUYXNrLFxuICAgIGxhbmd1YWdlOiBKc2lpUGFjbWFrVGFyZ2V0LFxuICAgIGV4dHJhSm9iT3B0aW9uczogUGFydGlhbDxKb2I+LFxuICApIHtcbiAgICBpZiAoIXByb2plY3QuYnVpbGRXb3JrZmxvdykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwYWNtYWsgPSB0aGlzLnBhY21ha0Zvckxhbmd1YWdlKHByb2plY3QsIGxhbmd1YWdlLCBwYWNrVGFzayk7XG5cbiAgICBwcm9qZWN0LmJ1aWxkV29ya2Zsb3cuYWRkUG9zdEJ1aWxkSm9iKGBwYWNrYWdlLSR7bGFuZ3VhZ2V9YCwge1xuICAgICAgLi4uZmlsdGVyZWRSdW5zT25PcHRpb25zKFxuICAgICAgICBleHRyYUpvYk9wdGlvbnMucnVuc09uLFxuICAgICAgICBleHRyYUpvYk9wdGlvbnMucnVuc09uR3JvdXAsXG4gICAgICApLFxuICAgICAgcGVybWlzc2lvbnM6IHtcbiAgICAgICAgY29udGVudHM6IEpvYlBlcm1pc3Npb24uUkVBRCxcbiAgICAgIH0sXG4gICAgICB0b29sczoge1xuICAgICAgICBub2RlOiB7XG4gICAgICAgICAgdmVyc2lvbjpcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy53b3JrZmxvd05vZGVWZXJzaW9uID8/XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICBwcm9qZWN0Lm5vZGVWZXJzaW9uID8/XG4gICAgICAgICAgICBcImx0cy8qXCIsXG4gICAgICAgIH0sXG4gICAgICAgIC4uLnBhY21hay5wdWJsaXNoVG9vbHMsXG4gICAgICB9LFxuICAgICAgc3RlcHM6IFtcbiAgICAgICAgLi4ucGFjbWFrLmJvb3RzdHJhcFN0ZXBzLFxuICAgICAgICBXb3JrZmxvd1N0ZXBzLmNoZWNrb3V0KHtcbiAgICAgICAgICB3aXRoOiB7XG4gICAgICAgICAgICBwYXRoOiBSRVBPX1RFTVBfRElSRUNUT1JZLFxuICAgICAgICAgICAgcmVmOiBQVUxMX1JFUVVFU1RfU0hBLFxuICAgICAgICAgICAgcmVwb3NpdG9yeTogUFVMTF9SRVFVRVNUX1JFUE9TSVRPUlksXG4gICAgICAgICAgICAuLi4ocHJvamVjdC5naXRodWI/LmRvd25sb2FkTGZzID8geyBsZnM6IHRydWUgfSA6IHt9KSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICAgLi4ucGFjbWFrLnBhY2thZ2luZ1N0ZXBzLFxuICAgICAgXSxcbiAgICAgIC4uLmV4dHJhSm9iT3B0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkUGFja2FnaW5nVGFzayhcbiAgICBwcm9qZWN0OiBUeXBlU2NyaXB0UHJvamVjdCxcbiAgICBwYWNrYWdlQWxsVGFzazogVGFzayxcbiAgICBsYW5ndWFnZTogSnNpaVBhY21ha1RhcmdldCxcbiAgKTogVGFzayB7XG4gICAgY29uc3QgcGFja2FnZVRhcmdldFRhc2sgPSBwcm9qZWN0LnRhc2tzLmFkZFRhc2soYHBhY2thZ2U6JHtsYW5ndWFnZX1gLCB7XG4gICAgICBkZXNjcmlwdGlvbjogYENyZWF0ZSAke2xhbmd1YWdlfSBsYW5ndWFnZSBiaW5kaW5nc2AsXG4gICAgfSk7XG4gICAgY29uc3QgY29tbWFuZFBhcnRzID0gW1wianNpaS1wYWNtYWtcIiwgXCItdlwiXTtcblxuICAgIGlmIChwcm9qZWN0LnBhY2thZ2UucGFja2FnZU1hbmFnZXIgPT09IE5vZGVQYWNrYWdlTWFuYWdlci5QTlBNKSB7XG4gICAgICBjb21tYW5kUGFydHMucHVzaChcIi0tcGFjay1jb21tYW5kXCIsIFwicG5wbSBwYWNrXCIpO1xuICAgIH1cblxuICAgIGNvbW1hbmRQYXJ0cy5wdXNoKFwiLS10YXJnZXRcIiwgbGFuZ3VhZ2UpO1xuXG4gICAgcGFja2FnZVRhcmdldFRhc2suZXhlY0FyZ3MoY29tbWFuZFBhcnRzKTtcblxuICAgIHBhY2thZ2VBbGxUYXNrLnNwYXduKHBhY2thZ2VUYXJnZXRUYXNrKTtcbiAgICByZXR1cm4gcGFja2FnZVRhcmdldFRhc2s7XG4gIH1cblxuICBwcml2YXRlIHBhY21ha0Zvckxhbmd1YWdlKFxuICAgIHByb2plY3Q6IFR5cGVTY3JpcHRQcm9qZWN0LFxuICAgIHRhcmdldDogSnNpaVBhY21ha1RhcmdldCxcbiAgICBwYWNrVGFzazogVGFzayxcbiAgKToge1xuICAgIHB1Ymxpc2hUb29sczogVG9vbHM7XG4gICAgYm9vdHN0cmFwU3RlcHM6IEFycmF5PFN0ZXA+O1xuICAgIHBhY2thZ2luZ1N0ZXBzOiBBcnJheTxTdGVwPjtcbiAgfSB7XG4gICAgY29uc3QgYm9vdHN0cmFwU3RlcHM6IEFycmF5PFN0ZXA+ID0gW107XG4gICAgY29uc3QgcGFja2FnaW5nU3RlcHM6IEFycmF5PFN0ZXA+ID0gW107XG5cbiAgICAvLyBHZW5lcmljIGJvb3RzdHJhcHBpbmcgZm9yIGFsbCB0YXJnZXQgbGFuZ3VhZ2VzXG4gICAgYm9vdHN0cmFwU3RlcHMucHVzaCguLi4odGhpcy5vcHRpb25zLndvcmtmbG93Qm9vdHN0cmFwU3RlcHMgPz8gW10pKTtcbiAgICBpZiAocHJvamVjdC5wYWNrYWdlLnBhY2thZ2VNYW5hZ2VyID09PSBOb2RlUGFja2FnZU1hbmFnZXIuUE5QTSkge1xuICAgICAgYm9vdHN0cmFwU3RlcHMucHVzaCh7XG4gICAgICAgIG5hbWU6IFwiU2V0dXAgcG5wbVwiLFxuICAgICAgICB1c2VzOiBHaXRIdWJBY3Rpb25zLlBOUE1fQUNUSU9OX1NFVFVQLFxuICAgICAgICB3aXRoOiB7IHZlcnNpb246IHByb2plY3QucGFja2FnZS5wbnBtVmVyc2lvbiB9LFxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChwcm9qZWN0LnBhY2thZ2UucGFja2FnZU1hbmFnZXIgPT09IE5vZGVQYWNrYWdlTWFuYWdlci5CVU4pIHtcbiAgICAgIGJvb3RzdHJhcFN0ZXBzLnB1c2goe1xuICAgICAgICBuYW1lOiBcIlNldHVwIGJ1blwiLFxuICAgICAgICB1c2VzOiBHaXRIdWJBY3Rpb25zLk9WRU5fU0hfU0VUVVBfQlVOLFxuICAgICAgICB3aXRoOiB7IFwiYnVuLXZlcnNpb25cIjogcHJvamVjdC5wYWNrYWdlLmJ1blZlcnNpb24gfSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoaXNZYXJuQmVycnkocHJvamVjdC5wYWNrYWdlLnBhY2thZ2VNYW5hZ2VyKSkge1xuICAgICAgYm9vdHN0cmFwU3RlcHMucHVzaCh7XG4gICAgICAgIG5hbWU6IFwiRW5hYmxlIGNvcmVwYWNrXCIsXG4gICAgICAgIHJ1bjogXCJjb3JlcGFjayBlbmFibGVcIixcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IHdvcmtEaXIgPSB0aGlzLm9wdGlvbnMud29ya3NwYWNlRGlyZWN0b3J5XG4gICAgICA/IGAke1JFUE9fVEVNUF9ESVJFQ1RPUll9LyR7dGhpcy5vcHRpb25zLndvcmtzcGFjZURpcmVjdG9yeX1gXG4gICAgICA6IFJFUE9fVEVNUF9ESVJFQ1RPUlk7XG5cbiAgICAvLyBJbnN0YWxsYXRpb24gc3RlcHMgYmVmb3JlIHBhY2thZ2luZywgYnV0IGFmdGVyIGNoZWNrb3V0XG4gICAgcGFja2FnaW5nU3RlcHMucHVzaChcbiAgICAgIHtcbiAgICAgICAgbmFtZTogXCJJbnN0YWxsIERlcGVuZGVuY2llc1wiLFxuICAgICAgICBydW46IGBjZCAke1JFUE9fVEVNUF9ESVJFQ1RPUll9ICYmICR7cHJvamVjdC5wYWNrYWdlLmluc3RhbGxDb21tYW5kfWAsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiBcIkV4dHJhY3QgYnVpbGQgYXJ0aWZhY3RcIixcbiAgICAgICAgcnVuOiBgdGFyIC0tc3RyaXAtY29tcG9uZW50cz0xIC14enZmICR7cHJvamVjdC5hcnRpZmFjdHNEaXJlY3Rvcnl9L2pzLyoudGd6IC1DICR7d29ya0Rpcn1gLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogYE1vdmUgYnVpbGQgYXJ0aWZhY3Qgb3V0IG9mIHRoZSB3YXlgLFxuICAgICAgICBydW46IGBtdiAke3Byb2plY3QuYXJ0aWZhY3RzRGlyZWN0b3J5fSAke0JVSUxEX0FSVElGQUNUX09MRF9ESVJ9YCxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6IGBDcmVhdGUgJHt0YXJnZXR9IGFydGlmYWN0YCxcbiAgICAgICAgcnVuOiBgY2QgJHt3b3JrRGlyfSAmJiAke3Byb2plY3QucnVuVGFza0NvbW1hbmQocGFja1Rhc2spfWAsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiBgQ29sbGVjdCAke3RhcmdldH0gYXJ0aWZhY3RgLFxuICAgICAgICBydW46IGBtdiAke3dvcmtEaXJ9LyR7cHJvamVjdC5hcnRpZmFjdHNEaXJlY3Rvcnl9ICR7cHJvamVjdC5hcnRpZmFjdHNEaXJlY3Rvcnl9YCxcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIHJldHVybiB7XG4gICAgICBwdWJsaXNoVG9vbHM6IEpTSUlfVE9PTENIQUlOW3RhcmdldF0sXG4gICAgICBib290c3RyYXBTdGVwcyxcbiAgICAgIHBhY2thZ2luZ1N0ZXBzLFxuICAgIH07XG4gIH1cbn1cblxudHlwZSBQdWJsaXNoVG8gPSBrZXlvZiBQdWJsaXNoZXIgJlxuICAoXG4gICAgfCBcInB1Ymxpc2hUb05wbVwiXG4gICAgfCBcInB1Ymxpc2hUb01hdmVuXCJcbiAgICB8IFwicHVibGlzaFRvUHlQaVwiXG4gICAgfCBcInB1Ymxpc2hUb051Z2V0XCJcbiAgICB8IFwicHVibGlzaFRvR29cIlxuICApO1xuXG50eXBlIFB1Ymxpc2hUb1RhcmdldCA9IHsgW0sgaW4gSnNpaVBhY21ha1RhcmdldF06IFB1Ymxpc2hUbyB9O1xuY29uc3QgcHVibGlzaFRvOiBQdWJsaXNoVG9UYXJnZXQgPSB7XG4gIGpzOiBcInB1Ymxpc2hUb05wbVwiLFxuICBqYXZhOiBcInB1Ymxpc2hUb01hdmVuXCIsXG4gIHB5dGhvbjogXCJwdWJsaXNoVG9QeVBpXCIsXG4gIGRvdG5ldDogXCJwdWJsaXNoVG9OdWdldFwiLFxuICBnbzogXCJwdWJsaXNoVG9Hb1wiLFxufTtcbiJdfQ==