projen
Version:
CDK for software projects
283 lines (275 loc) • 38.8 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AwsCdkTypeScriptApp = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const fs = require("fs");
const path = require("path");
const auto_discover_1 = require("./auto-discover");
const awscdk_deps_js_1 = require("./awscdk-deps-js");
const cdk_config_1 = require("./cdk-config");
const cdk_tasks_1 = require("./cdk-tasks");
const integ_runner_1 = require("./integ-runner");
const component_1 = require("../component");
const dependencies_1 = require("../dependencies");
const javascript_1 = require("../javascript");
const typescript_1 = require("../typescript");
const util_1 = require("../util");
/**
* AWS CDK app in TypeScript
*
* @pjid awscdk-app-ts
*/
class AwsCdkTypeScriptApp extends typescript_1.TypeScriptAppProject {
/**
* The CDK version this app is using.
*/
get cdkVersion() {
return this.cdkDeps.cdkVersion;
}
constructor(options) {
// CDK default compiler options
const cdkDefaultCompilerOptions = {
target: "ES2022",
module: "NodeNext",
moduleResolution: javascript_1.TypeScriptModuleResolution.NODE_NEXT,
lib: ["es2022"],
declaration: true,
strict: true,
noImplicitAny: true,
strictNullChecks: true,
noImplicitThis: true,
alwaysStrict: true,
noUnusedLocals: false,
noUnusedParameters: false,
noImplicitReturns: true,
noFallthroughCasesInSwitch: false,
inlineSourceMap: true,
inlineSources: true,
experimentalDecorators: true,
strictPropertyInitialization: false,
typeRoots: ["./node_modules/@types"],
};
let finalCompilerOptions = cdkDefaultCompilerOptions;
if (options.tsconfig?.compilerOptions) {
// Deep merge user's `compilerOptions` onto CDK-specific defaults.
finalCompilerOptions = (0, util_1.deepMerge)([cdkDefaultCompilerOptions, options.tsconfig.compilerOptions], { destructive: true });
}
// CDK default exclude
const cdkDefaultExclude = ["node_modules", "cdk.out"];
let finalExclude = cdkDefaultExclude;
if (options.tsconfig?.exclude) {
// Merge and deduplicate user's `exclude` with CDK-specific defaults.
finalExclude = [
...new Set([...cdkDefaultExclude, ...options.tsconfig.exclude]),
];
}
/**
* The final `tsconfig` object passed to the superclass.
* It incorporates AWS CDK defaults (derived from `cdkDefaultCompilerOptions` and `cdkDefaultExclude` above)
* and any user-provided overrides. The aim is to align with the standard CDK `tsconfig.json`:
* @see https://github.com/aws/aws-cdk-cli/blob/main/packages/aws-cdk/lib/init-templates/app/typescript/tsconfig.json
*/
const tsconfigToSuper = {
...options.tsconfig, // Pass through any other top-level tsconfig options from user
compilerOptions: finalCompilerOptions,
exclude: finalExclude,
};
super({
...options,
sampleCode: false,
bundlerOptions: {
...options.bundlerOptions,
// we invoke the "bundle" task as part of the build step in cdk.json so
// we don't want it to be added to the pre-compile phase.
runBundleTask: javascript_1.RunBundleTask.MANUAL,
},
tsconfig: tsconfigToSuper,
});
this.cdkDeps = new awscdk_deps_js_1.AwsCdkDepsJs(this, {
dependencyType: dependencies_1.DependencyType.RUNTIME,
...options,
});
this.appEntrypoint = options.appEntrypoint ?? "main.ts";
// CLI
this.addDevDeps(`aws-cdk@${this.cdkDeps.cdkCliVersion}`);
// no compile step because we do all of it in typescript directly
this.compileTask.reset();
this.cdkTasks = new cdk_tasks_1.CdkTasks(this);
// add synth to the build
this.postCompileTask.spawn(this.cdkTasks.synthSilent);
const tsConfigFile = this.tsconfig?.fileName;
if (!tsConfigFile) {
throw new Error("Expecting tsconfig.json");
}
this.cdkConfig = new cdk_config_1.CdkConfig(this, {
featureFlags: this.cdkDeps.cdkMajorVersion < 2,
buildCommand: this.runTaskCommand(this.bundler.bundleTask),
watchIncludes: [`${this.srcdir}/**/*.ts`, `${this.testdir}/**/*.ts`],
watchExcludes: [
"README.md",
"cdk*.json",
"**/*.d.ts",
"**/*.js",
"tsconfig.json",
"package*.json",
"yarn.lock",
"node_modules",
],
...options,
app: this.getCdkApp(options),
});
this.gitignore.exclude(".parcel-cache/");
this.npmignore?.exclude(`${this.cdkConfig.cdkout}/`);
this.npmignore?.exclude(".cdk.staging/");
if (this.tsconfig) {
this.tsconfig.exclude.push(this.cdkConfig.cdkout);
}
this.addDevDeps("ts-node");
if (options.sampleCode ?? true) {
new SampleCode(this, this.cdkDeps.cdkMajorVersion);
}
new auto_discover_1.AutoDiscover(this, {
srcdir: this.srcdir,
testdir: this.testdir,
lambdaOptions: options.lambdaOptions,
tsconfigPath: this.tsconfigDev.fileName,
cdkDeps: this.cdkDeps,
lambdaAutoDiscover: options.lambdaAutoDiscover ?? true,
edgeLambdaAutoDiscover: options.edgeLambdaAutoDiscover ?? true,
lambdaExtensionAutoDiscover: options.lambdaExtensionAutoDiscover ?? true,
integrationTestAutoDiscover: options.integrationTestAutoDiscover ?? true,
});
if (options.experimentalIntegRunner) {
new integ_runner_1.IntegRunner(this);
}
}
/**
* Adds an AWS CDK module dependencies
* @param modules The list of modules to depend on
*/
addCdkDependency(...modules) {
return this.cdkDeps.addV1Dependencies(...modules);
}
getCdkApp(options) {
if (options.app && options.appEntrypoint) {
throw new Error("Only one of 'app' or 'appEntrypoint' can be specified");
}
// prefer an explicitly provided app command
if (options.app) {
return options.app;
}
const appEntrypoint = path.posix.join(this.srcdir, this.appEntrypoint);
const tsNodeConfig = this.tsconfig?.fileName
? ` -P ${this.tsconfig?.fileName}`
: "";
const tsNodeApp = `ts-node${tsNodeConfig} --prefer-ts-exts ${appEntrypoint}`;
switch (this.package.packageManager) {
case javascript_1.NodePackageManager.BUN:
const bunTsConfig = this.tsconfig?.fileName
? ` --tsconfig-override=${this.tsconfig?.fileName}`
: "";
const bunEntrypoint = ensureRelativePathPrefix(appEntrypoint);
// https://bun.sh/docs/cli/run
// bun can run ts files directly
return `bun run${bunTsConfig} ${bunEntrypoint}`;
case javascript_1.NodePackageManager.PNPM:
case javascript_1.NodePackageManager.YARN_CLASSIC:
case javascript_1.NodePackageManager.YARN:
case javascript_1.NodePackageManager.YARN_BERRY:
case javascript_1.NodePackageManager.YARN2:
// use npx with also for yarn & pnpm due to reported issues
// @see https://github.com/projen/projen/issues/4180
return `npx ${tsNodeApp}`;
default:
return `npx ${tsNodeApp}`;
}
}
}
exports.AwsCdkTypeScriptApp = AwsCdkTypeScriptApp;
_a = JSII_RTTI_SYMBOL_1;
AwsCdkTypeScriptApp[_a] = { fqn: "projen.awscdk.AwsCdkTypeScriptApp", version: "0.95.2" };
/**
* Ensures a path is properly prefixed with './' if it's a relative path
* @param {string} filePath - The path to normalize
* @returns {string} - The normalized path
*/
function ensureRelativePathPrefix(filePath) {
// If it's already an absolute path, return as is
if (path.isAbsolute(filePath)) {
return filePath;
}
// If it already starts with ./ or ../, return as is
if (filePath.startsWith("./") || filePath.startsWith("../")) {
return filePath;
}
// Otherwise, add ./ prefix
return `./${filePath}`;
}
class SampleCode extends component_1.Component {
constructor(project, cdkMajorVersion) {
super(project);
this.cdkMajorVersion = cdkMajorVersion;
this.appProject = project;
}
synthesize() {
const outdir = this.project.outdir;
const srcdir = path.join(outdir, this.appProject.srcdir);
if (fs.existsSync(srcdir) &&
fs.readdirSync(srcdir).filter((x) => x.endsWith(".ts"))) {
return;
}
const srcImports = new Array();
if (this.cdkMajorVersion < 2) {
srcImports.push("import { App, Construct, Stack, StackProps } from '@aws-cdk/core';");
}
else {
srcImports.push("import { App, Stack, StackProps } from 'aws-cdk-lib';");
srcImports.push("import { Construct } from 'constructs';");
}
const srcCode = `${srcImports.join("\n")}
export class MyStack extends Stack {
constructor(scope: Construct, id: string, props: StackProps = {}) {
super(scope, id, props);
// define resources here...
}
}
// for development, use account/region from cdk cli
const devEnv = {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION,
};
const app = new App();
new MyStack(app, '${this.project.name}-dev', { env: devEnv });
// new MyStack(app, '${this.project.name}-prod', { env: prodEnv });
app.synth();`;
fs.mkdirSync(srcdir, { recursive: true });
fs.writeFileSync(path.join(srcdir, this.appProject.appEntrypoint), srcCode);
const testdir = path.join(outdir, this.appProject.testdir);
if (fs.existsSync(testdir) &&
fs.readdirSync(testdir).filter((x) => x.endsWith(".ts"))) {
return;
}
const testImports = new Array();
if (this.cdkMajorVersion < 2) {
testImports.push("import { App } from '@aws-cdk/core';");
testImports.push("import { Template } from '@aws-cdk/assertions';");
}
else {
testImports.push("import { App } from 'aws-cdk-lib';");
testImports.push("import { Template } from 'aws-cdk-lib/assertions';");
}
const appEntrypointName = path.basename(this.appProject.appEntrypoint, ".ts");
const testCode = `${testImports.join("\n")}
import { MyStack } from '../${this.appProject.srcdir}/${appEntrypointName}';
test('Snapshot', () => {
const app = new App();
const stack = new MyStack(app, 'test');
const template = Template.fromStack(stack);
expect(template.toJSON()).toMatchSnapshot();
});`;
fs.mkdirSync(testdir, { recursive: true });
fs.writeFileSync(path.join(testdir, `${appEntrypointName}.test.ts`), testCode);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzY2RrLWFwcC10cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hd3NjZGsvYXdzY2RrLWFwcC10cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUFDN0IsbURBQStDO0FBRS9DLHFEQUFnRDtBQUNoRCw2Q0FBaUU7QUFDakUsMkNBQXVDO0FBQ3ZDLGlEQUE2QztBQUU3Qyw0Q0FBeUM7QUFDekMsa0RBQWlEO0FBQ2pELDhDQUt1QjtBQUN2Qiw4Q0FBK0U7QUFDL0Usa0NBQW9DO0FBcUVwQzs7OztHQUlHO0FBQ0gsTUFBYSxtQkFBb0IsU0FBUSxpQ0FBb0I7SUFDM0Q7O09BRUc7SUFDSCxJQUFXLFVBQVU7UUFDbkIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQztJQUNqQyxDQUFDO0lBbUJELFlBQVksT0FBbUM7UUFDN0MsK0JBQStCO1FBQy9CLE1BQU0seUJBQXlCLEdBQzdCO1lBQ0UsTUFBTSxFQUFFLFFBQVE7WUFDaEIsTUFBTSxFQUFFLFVBQVU7WUFDbEIsZ0JBQWdCLEVBQUUsdUNBQTBCLENBQUMsU0FBUztZQUN0RCxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUM7WUFDZixXQUFXLEVBQUUsSUFBSTtZQUNqQixNQUFNLEVBQUUsSUFBSTtZQUNaLGFBQWEsRUFBRSxJQUFJO1lBQ25CLGdCQUFnQixFQUFFLElBQUk7WUFDdEIsY0FBYyxFQUFFLElBQUk7WUFDcEIsWUFBWSxFQUFFLElBQUk7WUFDbEIsY0FBYyxFQUFFLEtBQUs7WUFDckIsa0JBQWtCLEVBQUUsS0FBSztZQUN6QixpQkFBaUIsRUFBRSxJQUFJO1lBQ3ZCLDBCQUEwQixFQUFFLEtBQUs7WUFDakMsZUFBZSxFQUFFLElBQUk7WUFDckIsYUFBYSxFQUFFLElBQUk7WUFDbkIsc0JBQXNCLEVBQUUsSUFBSTtZQUM1Qiw0QkFBNEIsRUFBRSxLQUFLO1lBQ25DLFNBQVMsRUFBRSxDQUFDLHVCQUF1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QUFDLE9BQU8sRUFBRSxHQUFHLGlCQUFpQixVQUFVLENBQUMsRUFDbEQsUUFBUSxDQUNULENBQUM7SUFDSixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IEF1dG9EaXNjb3ZlciB9IGZyb20gXCIuL2F1dG8tZGlzY292ZXJcIjtcbmltcG9ydCB7IEF3c0Nka0RlcHMsIEF3c0Nka0RlcHNDb21tb25PcHRpb25zIH0gZnJvbSBcIi4vYXdzY2RrLWRlcHNcIjtcbmltcG9ydCB7IEF3c0Nka0RlcHNKcyB9IGZyb20gXCIuL2F3c2Nkay1kZXBzLWpzXCI7XG5pbXBvcnQgeyBDZGtDb25maWcsIENka0NvbmZpZ0NvbW1vbk9wdGlvbnMgfSBmcm9tIFwiLi9jZGstY29uZmlnXCI7XG5pbXBvcnQgeyBDZGtUYXNrcyB9IGZyb20gXCIuL2Nkay10YXNrc1wiO1xuaW1wb3J0IHsgSW50ZWdSdW5uZXIgfSBmcm9tIFwiLi9pbnRlZy1ydW5uZXJcIjtcbmltcG9ydCB7IExhbWJkYUZ1bmN0aW9uQ29tbW9uT3B0aW9ucyB9IGZyb20gXCIuL2xhbWJkYS1mdW5jdGlvblwiO1xuaW1wb3J0IHsgQ29tcG9uZW50IH0gZnJvbSBcIi4uL2NvbXBvbmVudFwiO1xuaW1wb3J0IHsgRGVwZW5kZW5jeVR5cGUgfSBmcm9tIFwiLi4vZGVwZW5kZW5jaWVzXCI7XG5pbXBvcnQge1xuICBOb2RlUGFja2FnZU1hbmFnZXIsXG4gIFJ1bkJ1bmRsZVRhc2ssXG4gIFR5cGVTY3JpcHRNb2R1bGVSZXNvbHV0aW9uLFxuICBUeXBlc2NyaXB0Q29uZmlnT3B0aW9ucyxcbn0gZnJvbSBcIi4uL2phdmFzY3JpcHRcIjtcbmltcG9ydCB7IFR5cGVTY3JpcHRBcHBQcm9qZWN0LCBUeXBlU2NyaXB0UHJvamVjdE9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNjcmlwdFwiO1xuaW1wb3J0IHsgZGVlcE1lcmdlIH0gZnJvbSBcIi4uL3V0aWxcIjtcblxuZXhwb3J0IGludGVyZmFjZSBBd3NDZGtUeXBlU2NyaXB0QXBwT3B0aW9uc1xuICBleHRlbmRzIFR5cGVTY3JpcHRQcm9qZWN0T3B0aW9ucyxcbiAgICBDZGtDb25maWdDb21tb25PcHRpb25zLFxuICAgIEF3c0Nka0RlcHNDb21tb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBDREsgYXBwJ3MgZW50cnlwb2ludCAocmVsYXRpdmUgdG8gdGhlIHNvdXJjZSBkaXJlY3RvcnksIHdoaWNoIGlzXG4gICAqIFwic3JjXCIgYnkgZGVmYXVsdCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IFwibWFpbi50c1wiXG4gICAqL1xuICByZWFkb25seSBhcHBFbnRyeXBvaW50Pzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGNvbW1hbmQgbGluZSB0byBleGVjdXRlIGluIG9yZGVyIHRvIHN5bnRoZXNpemUgdGhlIENESyBhcHBsaWNhdGlvblxuICAgKiAobGFuZ3VhZ2Ugc3BlY2lmaWMpLlxuICAgKi9cbiAgcmVhZG9ubHkgYXBwPzogc3RyaW5nO1xuICAvKipcbiAgICogQXV0b21hdGljYWxseSBhZGRzIGFuIGBhd3NjZGsuTGFtYmRhRnVuY3Rpb25gIGZvciBlYWNoIGAubGFtYmRhLnRzYCBoYW5kbGVyXG4gICAqIGluIHlvdXIgc291cmNlIHRyZWUuIElmIHRoaXMgaXMgZGlzYWJsZWQsIHlvdSBjYW4gbWFudWFsbHkgYWRkIGFuXG4gICAqIGBhd3NjZGsuQXV0b0Rpc2NvdmVyYCBjb21wb25lbnQgdG8geW91ciBwcm9qZWN0LlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBsYW1iZGFBdXRvRGlzY292ZXI/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBdXRvbWF0aWNhbGx5IGFkZHMgYW4gYGNsb3VkZnJvbnQuZXhwZXJpbWVudGFsLkVkZ2VGdW5jdGlvbmAgZm9yIGVhY2hcbiAgICogYC5lZGdlLWxhbWJkYS50c2AgaGFuZGxlciBpbiB5b3VyIHNvdXJjZSB0cmVlLiBJZiB0aGlzIGlzIGRpc2FibGVkLCB5b3UgY2FuXG4gICAqIG1hbnVhbGx5IGFkZCBhbiBgYXdzY2RrLkF1dG9EaXNjb3ZlcmAgY29tcG9uZW50IHRvIHlvdXIgcHJvamVjdC5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgZWRnZUxhbWJkYUF1dG9EaXNjb3Zlcj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEF1dG9tYXRpY2FsbHkgYWRkcyBhbiBgYXdzY2RrLkxhbWJkYUV4dGVuc2lvbmAgZm9yIGVhY2ggYC5sYW1iZGEtZXh0ZW5zaW9uLnRzYFxuICAgKiBlbnRyeXBvaW50IGluIHlvdXIgc291cmNlIHRyZWUuIElmIHRoaXMgaXMgZGlzYWJsZWQsIHlvdSBjYW4gbWFudWFsbHkgYWRkIGFuXG4gICAqIGBhd3NjZGsuQXV0b0Rpc2NvdmVyYCBjb21wb25lbnQgdG8geW91ciBwcm9qZWN0XG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGxhbWJkYUV4dGVuc2lvbkF1dG9EaXNjb3Zlcj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEF1dG9tYXRpY2FsbHkgZGlzY292ZXJzIGFuZCBjcmVhdGVzIGludGVncmF0aW9uIHRlc3RzIGZvciBlYWNoIGAuaW50ZWcudHNgXG4gICAqIGZpbGUgaW4gdW5kZXIgeW91ciB0ZXN0IGRpcmVjdG9yeS5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgaW50ZWdyYXRpb25UZXN0QXV0b0Rpc2NvdmVyPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogRW5hYmxlIGV4cGVyaW1lbnRhbCBzdXBwb3J0IGZvciB0aGUgQVdTIENESyBpbnRlZy1ydW5uZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqIEBleHBlcmltZW50YWxcbiAgICovXG4gIHJlYWRvbmx5IGV4cGVyaW1lbnRhbEludGVnUnVubmVyPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQ29tbW9uIG9wdGlvbnMgZm9yIGFsbCBBV1MgTGFtYmRhIGZ1bmN0aW9ucy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBkZWZhdWx0IG9wdGlvbnNcbiAgICovXG4gIHJlYWRvbmx5IGxhbWJkYU9wdGlvbnM/OiBMYW1iZGFGdW5jdGlvbkNvbW1vbk9wdGlvbnM7XG59XG5cbi8qKlxuICogQVdTIENESyBhcHAgaW4gVHlwZVNjcmlwdFxuICpcbiAqIEBwamlkIGF3c2Nkay1hcHAtdHNcbiAqL1xuZXhwb3J0IGNsYXNzIEF3c0Nka1R5cGVTY3JpcHRBcHAgZXh0ZW5kcyBUeXBlU2NyaXB0QXBwUHJvamVjdCB7XG4gIC8qKlxuICAgKiBUaGUgQ0RLIHZlcnNpb24gdGhpcyBhcHAgaXMgdXNpbmcuXG4gICAqL1xuICBwdWJsaWMgZ2V0IGNka1ZlcnNpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuY2RrRGVwcy5jZGtWZXJzaW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBDREsgYXBwIGVudHJ5cG9pbnRcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBhcHBFbnRyeXBvaW50OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIENvbW1vbiBDREsgdGFza3MuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY2RrVGFza3M6IENka1Rhc2tzO1xuXG4gIC8qKlxuICAgKiBjZGsuanNvbiBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGNka0NvbmZpZzogQ2RrQ29uZmlnO1xuXG4gIHB1YmxpYyByZWFkb25seSBjZGtEZXBzOiBBd3NDZGtEZXBzO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IEF3c0Nka1R5cGVTY3JpcHRBcHBPcHRpb25zKSB7XG4gICAgLy8gQ0RLIGRlZmF1bHQgY29tcGlsZXIgb3B0aW9uc1xuICAgIGNvbnN0IGNka0RlZmF1bHRDb21waWxlck9wdGlvbnM6IFR5cGVzY3JpcHRDb25maWdPcHRpb25zW1wiY29tcGlsZXJPcHRpb25zXCJdID1cbiAgICAgIHtcbiAgICAgICAgdGFyZ2V0OiBcIkVTMjAyMlwiLFxuICAgICAgICBtb2R1bGU6IFwiTm9kZU5leHRcIixcbiAgICAgICAgbW9kdWxlUmVzb2x1dGlvbjogVHlwZVNjcmlwdE1vZHVsZVJlc29sdXRpb24uTk9ERV9ORVhULFxuICAgICAgICBsaWI6IFtcImVzMjAyMlwiXSxcbiAgICAgICAgZGVjbGFyYXRpb246IHRydWUsXG4gICAgICAgIHN0cmljdDogdHJ1ZSxcbiAgICAgICAgbm9JbXBsaWNpdEFueTogdHJ1ZSxcbiAgICAgICAgc3RyaWN0TnVsbENoZWNrczogdHJ1ZSxcbiAgICAgICAgbm9JbXBsaWNpdFRoaXM6IHRydWUsXG4gICAgICAgIGFsd2F5c1N0cmljdDogdHJ1ZSxcbiAgICAgICAgbm9VbnVzZWRMb2NhbHM6IGZhbHNlLFxuICAgICAgICBub1VudXNlZFBhcmFtZXRlcnM6IGZhbHNlLFxuICAgICAgICBub0ltcGxpY2l0UmV0dXJuczogdHJ1ZSxcbiAgICAgICAgbm9GYWxsdGhyb3VnaENhc2VzSW5Td2l0Y2g6IGZhbHNlLFxuICAgICAgICBpbmxpbmVTb3VyY2VNYXA6IHRydWUsXG4gICAgICAgIGlubGluZVNvdXJjZXM6IHRydWUsXG4gICAgICAgIGV4cGVyaW1lbnRhbERlY29yYXRvcnM6IHRydWUsXG4gICAgICAgIHN0cmljdFByb3BlcnR5SW5pdGlhbGl6YXRpb246IGZhbHNlLFxuICAgICAgICB0eXBlUm9vdHM6IFtcIi4vbm9kZV9tb2R1bGVzL0B0eXBlc1wiXSxcbiAgICAgIH07XG5cbiAgICBsZXQgZmluYWxDb21waWxlck9wdGlvbnMgPSBjZGtEZWZhdWx0Q29tcGlsZXJPcHRpb25zO1xuICAgIGlmIChvcHRpb25zLnRzY29uZmlnPy5jb21waWxlck9wdGlvbnMpIHtcbiAgICAgIC8vIERlZXAgbWVyZ2UgdXNlcidzIGBjb21waWxlck9wdGlvbnNgIG9udG8gQ0RLLXNwZWNpZmljIGRlZmF1bHRzLlxuICAgICAgZmluYWxDb21waWxlck9wdGlvbnMgPSBkZWVwTWVyZ2UoXG4gICAgICAgIFtjZGtEZWZhdWx0Q29tcGlsZXJPcHRpb25zLCBvcHRpb25zLnRzY29uZmlnLmNvbXBpbGVyT3B0aW9uc10sXG4gICAgICAgIHsgZGVzdHJ1Y3RpdmU6IHRydWUgfVxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBDREsgZGVmYXVsdCBleGNsdWRlXG4gICAgY29uc3QgY2RrRGVmYXVsdEV4Y2x1ZGUgPSBbXCJub2RlX21vZHVsZXNcIiwgXCJjZGsub3V0XCJdO1xuICAgIGxldCBmaW5hbEV4Y2x1ZGUgPSBjZGtEZWZhdWx0RXhjbHVkZTtcbiAgICBpZiAob3B0aW9ucy50c2NvbmZpZz8uZXhjbHVkZSkge1xuICAgICAgLy8gTWVyZ2UgYW5kIGRlZHVwbGljYXRlIHVzZXIncyBgZXhjbHVkZWAgd2l0aCBDREstc3BlY2lmaWMgZGVmYXVsdHMuXG4gICAgICBmaW5hbEV4Y2x1ZGUgPSBbXG4gICAgICAgIC4uLm5ldyBTZXQoWy4uLmNka0RlZmF1bHRFeGNsdWRlLCAuLi5vcHRpb25zLnRzY29uZmlnLmV4Y2x1ZGVdKSxcbiAgICAgIF07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGZpbmFsIGB0c2NvbmZpZ2Agb2JqZWN0IHBhc3NlZCB0byB0aGUgc3VwZXJjbGFzcy5cbiAgICAgKiBJdCBpbmNvcnBvcmF0ZXMgQVdTIENESyBkZWZhdWx0cyAoZGVyaXZlZCBmcm9tIGBjZGtEZWZhdWx0Q29tcGlsZXJPcHRpb25zYCBhbmQgYGNka0RlZmF1bHRFeGNsdWRlYCBhYm92ZSlcbiAgICAgKiBhbmQgYW55IHVzZXItcHJvdmlkZWQgb3ZlcnJpZGVzLiBUaGUgYWltIGlzIHRvIGFsaWduIHdpdGggdGhlIHN0YW5kYXJkIENESyBgdHNjb25maWcuanNvbmA6XG4gICAgICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vYXdzL2F3cy1jZGstY2xpL2Jsb2IvbWFpbi9wYWNrYWdlcy9hd3MtY2RrL2xpYi9pbml0LXRlbXBsYXRlcy9hcHAvdHlwZXNjcmlwdC90c2NvbmZpZy5qc29uXG4gICAgICovXG4gICAgY29uc3QgdHNjb25maWdUb1N1cGVyOiBUeXBlc2NyaXB0Q29uZmlnT3B0aW9ucyA9IHtcbiAgICAgIC4uLm9wdGlvbnMudHNjb25maWcsIC8vIFBhc3MgdGhyb3VnaCBhbnkgb3RoZXIgdG9wLWxldmVsIHRzY29uZmlnIG9wdGlvbnMgZnJvbSB1c2VyXG4gICAgICBjb21waWxlck9wdGlvbnM6IGZpbmFsQ29tcGlsZXJPcHRpb25zLFxuICAgICAgZXhjbHVkZTogZmluYWxFeGNsdWRlLFxuICAgIH07XG5cbiAgICBzdXBlcih7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgc2FtcGxlQ29kZTogZmFsc2UsXG4gICAgICBidW5kbGVyT3B0aW9uczoge1xuICAgICAgICAuLi5vcHRpb25zLmJ1bmRsZXJPcHRpb25zLFxuICAgICAgICAvLyB3ZSBpbnZva2UgdGhlIFwiYnVuZGxlXCIgdGFzayBhcyBwYXJ0IG9mIHRoZSBidWlsZCBzdGVwIGluIGNkay5qc29uIHNvXG4gICAgICAgIC8vIHdlIGRvbid0IHdhbnQgaXQgdG8gYmUgYWRkZWQgdG8gdGhlIHByZS1jb21waWxlIHBoYXNlLlxuICAgICAgICBydW5CdW5kbGVUYXNrOiBSdW5CdW5kbGVUYXNrLk1BTlVBTCxcbiAgICAgIH0sXG4gICAgICB0c2NvbmZpZzogdHNjb25maWdUb1N1cGVyLFxuICAgIH0pO1xuICAgIHRoaXMuY2RrRGVwcyA9IG5ldyBBd3NDZGtEZXBzSnModGhpcywge1xuICAgICAgZGVwZW5kZW5jeVR5cGU6IERlcGVuZGVuY3lUeXBlLlJVTlRJTUUsXG4gICAgICAuLi5vcHRpb25zLFxuICAgIH0pO1xuICAgIHRoaXMuYXBwRW50cnlwb2ludCA9IG9wdGlvbnMuYXBwRW50cnlwb2ludCA/PyBcIm1haW4udHNcIjtcblxuICAgIC8vIENMSVxuICAgIHRoaXMuYWRkRGV2RGVwcyhgYXdzLWNka0Ake3RoaXMuY2RrRGVwcy5jZGtDbGlWZXJzaW9ufWApO1xuXG4gICAgLy8gbm8gY29tcGlsZSBzdGVwIGJlY2F1c2Ugd2UgZG8gYWxsIG9mIGl0IGluIHR5cGVzY3JpcHQgZGlyZWN0bHlcbiAgICB0aGlzLmNvbXBpbGVUYXNrLnJlc2V0KCk7XG5cbiAgICB0aGlzLmNka1Rhc2tzID0gbmV3IENka1Rhc2tzKHRoaXMpO1xuXG4gICAgLy8gYWRkIHN5bnRoIHRvIHRoZSBidWlsZFxuICAgIHRoaXMucG9zdENvbXBpbGVUYXNrLnNwYXduKHRoaXMuY2RrVGFza3Muc3ludGhTaWxlbnQpO1xuXG4gICAgY29uc3QgdHNDb25maWdGaWxlID0gdGhpcy50c2NvbmZpZz8uZmlsZU5hbWU7XG4gICAgaWYgKCF0c0NvbmZpZ0ZpbGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGluZyB0c2NvbmZpZy5qc29uXCIpO1xuICAgIH1cblxuICAgIHRoaXMuY2RrQ29uZmlnID0gbmV3IENka0NvbmZpZyh0aGlzLCB7XG4gICAgICBmZWF0dXJlRmxhZ3M6IHRoaXMuY2RrRGVwcy5jZGtNYWpvclZlcnNpb24gPCAyLFxuICAgICAgYnVpbGRDb21tYW5kOiB0aGlzLnJ1blRhc2tDb21tYW5kKHRoaXMuYnVuZGxlci5idW5kbGVUYXNrKSxcbiAgICAgIHdhdGNoSW5jbHVkZXM6IFtgJHt0aGlzLnNyY2Rpcn0vKiovKi50c2AsIGAke3RoaXMudGVzdGRpcn0vKiovKi50c2BdLFxuICAgICAgd2F0Y2hFeGNsdWRlczogW1xuICAgICAgICBcIlJFQURNRS5tZFwiLFxuICAgICAgICBcImNkayouanNvblwiLFxuICAgICAgICBcIioqLyouZC50c1wiLFxuICAgICAgICBcIioqLyouanNcIixcbiAgICAgICAgXCJ0c2NvbmZpZy5qc29uXCIsXG4gICAgICAgIFwicGFja2FnZSouanNvblwiLFxuICAgICAgICBcInlhcm4ubG9ja1wiLFxuICAgICAgICBcIm5vZGVfbW9kdWxlc1wiLFxuICAgICAgXSxcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBhcHA6IHRoaXMuZ2V0Q2RrQXBwKG9wdGlvbnMpLFxuICAgIH0pO1xuXG4gICAgdGhpcy5naXRpZ25vcmUuZXhjbHVkZShcIi5wYXJjZWwtY2FjaGUvXCIpO1xuXG4gICAgdGhpcy5ucG1pZ25vcmU/LmV4Y2x1ZGUoYCR7dGhpcy5jZGtDb25maWcuY2Rrb3V0fS9gKTtcbiAgICB0aGlzLm5wbWlnbm9yZT8uZXhjbHVkZShcIi5jZGsuc3RhZ2luZy9cIik7XG5cbiAgICBpZiAodGhpcy50c2NvbmZpZykge1xuICAgICAgdGhpcy50c2NvbmZpZy5leGNsdWRlLnB1c2godGhpcy5jZGtDb25maWcuY2Rrb3V0KTtcbiAgICB9XG5cbiAgICB0aGlzLmFkZERldkRlcHMoXCJ0cy1ub2RlXCIpO1xuICAgIGlmIChvcHRpb25zLnNhbXBsZUNvZGUgPz8gdHJ1ZSkge1xuICAgICAgbmV3IFNhbXBsZUNvZGUodGhpcywgdGhpcy5jZGtEZXBzLmNka01ham9yVmVyc2lvbik7XG4gICAgfVxuXG4gICAgbmV3IEF1dG9EaXNjb3Zlcih0aGlzLCB7XG4gICAgICBzcmNkaXI6IHRoaXMuc3JjZGlyLFxuICAgICAgdGVzdGRpcjogdGhpcy50ZXN0ZGlyLFxuICAgICAgbGFtYmRhT3B0aW9uczogb3B0aW9ucy5sYW1iZGFPcHRpb25zLFxuICAgICAgdHNjb25maWdQYXRoOiB0aGlzLnRzY29uZmlnRGV2LmZpbGVOYW1lLFxuICAgICAgY2RrRGVwczogdGhpcy5jZGtEZXBzLFxuICAgICAgbGFtYmRhQXV0b0Rpc2NvdmVyOiBvcHRpb25zLmxhbWJkYUF1dG9EaXNjb3ZlciA/PyB0cnVlLFxuICAgICAgZWRnZUxhbWJkYUF1dG9EaXNjb3Zlcjogb3B0aW9ucy5lZGdlTGFtYmRhQXV0b0Rpc2NvdmVyID8/IHRydWUsXG4gICAgICBsYW1iZGFFeHRlbnNpb25BdXRvRGlzY292ZXI6IG9wdGlvbnMubGFtYmRhRXh0ZW5zaW9uQXV0b0Rpc2NvdmVyID8/IHRydWUsXG4gICAgICBpbnRlZ3JhdGlvblRlc3RBdXRvRGlzY292ZXI6IG9wdGlvbnMuaW50ZWdyYXRpb25UZXN0QXV0b0Rpc2NvdmVyID8/IHRydWUsXG4gICAgfSk7XG5cbiAgICBpZiAob3B0aW9ucy5leHBlcmltZW50YWxJbnRlZ1J1bm5lcikge1xuICAgICAgbmV3IEludGVnUnVubmVyKHRoaXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGFuIEFXUyBDREsgbW9kdWxlIGRlcGVuZGVuY2llc1xuICAgKiBAcGFyYW0gbW9kdWxlcyBUaGUgbGlzdCBvZiBtb2R1bGVzIHRvIGRlcGVuZCBvblxuICAgKi9cbiAgcHVibGljIGFkZENka0RlcGVuZGVuY3koLi4ubW9kdWxlczogc3RyaW5nW10pIHtcbiAgICByZXR1cm4gdGhpcy5jZGtEZXBzLmFkZFYxRGVwZW5kZW5jaWVzKC4uLm1vZHVsZXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDZGtBcHAob3B0aW9uczogQXdzQ2RrVHlwZVNjcmlwdEFwcE9wdGlvbnMpOiBzdHJpbmcge1xuICAgIGlmIChvcHRpb25zLmFwcCAmJiBvcHRpb25zLmFwcEVudHJ5cG9pbnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk9ubHkgb25lIG9mICdhcHAnIG9yICdhcHBFbnRyeXBvaW50JyBjYW4gYmUgc3BlY2lmaWVkXCIpO1xuICAgIH1cblxuICAgIC8vIHByZWZlciBhbiBleHBsaWNpdGx5IHByb3ZpZGVkIGFwcCBjb21tYW5kXG4gICAgaWYgKG9wdGlvbnMuYXBwKSB7XG4gICAgICByZXR1cm4gb3B0aW9ucy5hcHA7XG4gICAgfVxuXG4gICAgY29uc3QgYXBwRW50cnlwb2ludCA9IHBhdGgucG9zaXguam9pbih0aGlzLnNyY2RpciwgdGhpcy5hcHBFbnRyeXBvaW50KTtcblxuICAgIGNvbnN0IHRzTm9kZUNvbmZpZyA9IHRoaXMudHNjb25maWc/LmZpbGVOYW1lXG4gICAgICA/IGAgLVAgJHt0aGlzLnRzY29uZmlnPy5maWxlTmFtZX1gXG4gICAgICA6IFwiXCI7XG4gICAgY29uc3QgdHNOb2RlQXBwID0gYHRzLW5vZGUke3RzTm9kZUNvbmZpZ30gLS1wcmVmZXItdHMtZXh0cyAke2FwcEVudHJ5cG9pbnR9YDtcblxuICAgIHN3aXRjaCAodGhpcy5wYWNrYWdlLnBhY2thZ2VNYW5hZ2VyKSB7XG4gICAgICBjYXNlIE5vZGVQYWNrYWdlTWFuYWdlci5CVU46XG4gICAgICAgIGNvbnN0IGJ1blRzQ29uZmlnID0gdGhpcy50c2NvbmZpZz8uZmlsZU5hbWVcbiAgICAgICAgICA/IGAgLS10c2NvbmZpZy1vdmVycmlkZT0ke3RoaXMudHNjb25maWc/LmZpbGVOYW1lfWBcbiAgICAgICAgICA6IFwiXCI7XG4gICAgICAgIGNvbnN0IGJ1bkVudHJ5cG9pbnQgPSBlbnN1cmVSZWxhdGl2ZVBhdGhQcmVmaXgoYXBwRW50cnlwb2ludCk7XG5cbiAgICAgICAgLy8gaHR0cHM6Ly9idW4uc2gvZG9jcy9jbGkvcnVuXG4gICAgICAgIC8vIGJ1biBjYW4gcnVuIHRzIGZpbGVzIGRpcmVjdGx5XG4gICAgICAgIHJldHVybiBgYnVuIHJ1biR7YnVuVHNDb25maWd9ICR7YnVuRW50cnlwb2ludH1gO1xuICAgICAgY2FzZSBOb2RlUGFja2FnZU1hbmFnZXIuUE5QTTpcbiAgICAgIGNhc2UgTm9kZVBhY2thZ2VNYW5hZ2VyLllBUk5fQ0xBU1NJQzpcbiAgICAgIGNhc2UgTm9kZVBhY2thZ2VNYW5hZ2VyLllBUk46XG4gICAgICBjYXNlIE5vZGVQYWNrYWdlTWFuYWdlci5ZQVJOX0JFUlJZOlxuICAgICAgY2FzZSBOb2RlUGFja2FnZU1hbmFnZXIuWUFSTjI6XG4gICAgICAgIC8vIHVzZSBucHggd2l0aCBhbHNvIGZvciB5YXJuICYgcG5wbSBkdWUgdG8gcmVwb3J0ZWQgaXNzdWVzXG4gICAgICAgIC8vIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL3Byb2plbi9wcm9qZW4vaXNzdWVzLzQxODBcbiAgICAgICAgcmV0dXJuIGBucHggJHt0c05vZGVBcHB9YDtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBgbnB4ICR7dHNOb2RlQXBwfWA7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRW5zdXJlcyBhIHBhdGggaXMgcHJvcGVybHkgcHJlZml4ZWQgd2l0aCAnLi8nIGlmIGl0J3MgYSByZWxhdGl2ZSBwYXRoXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZVBhdGggLSBUaGUgcGF0aCB0byBub3JtYWxpemVcbiAqIEByZXR1cm5zIHtzdHJpbmd9IC0gVGhlIG5vcm1hbGl6ZWQgcGF0aFxuICovXG5mdW5jdGlvbiBlbnN1cmVSZWxhdGl2ZVBhdGhQcmVmaXgoZmlsZVBhdGg6IHN0cmluZykge1xuICAvLyBJZiBpdCdzIGFscmVhZHkgYW4gYWJzb2x1dGUgcGF0aCwgcmV0dXJuIGFzIGlzXG4gIGlmIChwYXRoLmlzQWJzb2x1dGUoZmlsZVBhdGgpKSB7XG4gICAgcmV0dXJuIGZpbGVQYXRoO1xuICB9XG5cbiAgLy8gSWYgaXQgYWxyZWFkeSBzdGFydHMgd2l0aCAuLyBvciAuLi8sIHJldHVybiBhcyBpc1xuICBpZiAoZmlsZVBhdGguc3RhcnRzV2l0aChcIi4vXCIpIHx8IGZpbGVQYXRoLnN0YXJ0c1dpdGgoXCIuLi9cIikpIHtcbiAgICByZXR1cm4gZmlsZVBhdGg7XG4gIH1cblxuICAvLyBPdGhlcndpc2UsIGFkZCAuLyBwcmVmaXhcbiAgcmV0dXJuIGAuLyR7ZmlsZVBhdGh9YDtcbn1cblxuY2xhc3MgU2FtcGxlQ29kZSBleHRlbmRzIENvbXBvbmVudCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXBwUHJvamVjdDogQXdzQ2RrVHlwZVNjcmlwdEFwcDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm9qZWN0OiBBd3NDZGtUeXBlU2NyaXB0QXBwLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2RrTWFqb3JWZXJzaW9uOiBudW1iZXJcbiAgKSB7XG4gICAgc3VwZXIocHJvamVjdCk7XG4gICAgdGhpcy5hcHBQcm9qZWN0ID0gcHJvamVjdDtcbiAgfVxuXG4gIHB1YmxpYyBzeW50aGVzaXplKCkge1xuICAgIGNvbnN0IG91dGRpciA9IHRoaXMucHJvamVjdC5vdXRkaXI7XG4gICAgY29uc3Qgc3JjZGlyID0gcGF0aC5qb2luKG91dGRpciwgdGhpcy5hcHBQcm9qZWN0LnNyY2Rpcik7XG4gICAgaWYgKFxuICAgICAgZnMuZXhpc3RzU3luYyhzcmNkaXIpICYmXG4gICAgICBmcy5yZWFkZGlyU3luYyhzcmNkaXIpLmZpbHRlcigoeCkgPT4geC5lbmRzV2l0aChcIi50c1wiKSlcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzcmNJbXBvcnRzID0gbmV3IEFycmF5PHN0cmluZz4oKTtcbiAgICBpZiAodGhpcy5jZGtNYWpvclZlcnNpb24gPCAyKSB7XG4gICAgICBzcmNJbXBvcnRzLnB1c2goXG4gICAgICAgIFwiaW1wb3J0IHsgQXBwLCBDb25zdHJ1Y3QsIFN0YWNrLCBTdGFja1Byb3BzIH0gZnJvbSAnQGF3cy1jZGsvY29yZSc7XCJcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNyY0ltcG9ydHMucHVzaChcImltcG9ydCB7IEFwcCwgU3RhY2ssIFN0YWNrUHJvcHMgfSBmcm9tICdhd3MtY2RrLWxpYic7XCIpO1xuICAgICAgc3JjSW1wb3J0cy5wdXNoKFwiaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XCIpO1xuICAgIH1cblxuICAgIGNvbnN0IHNyY0NvZGUgPSBgJHtzcmNJbXBvcnRzLmpvaW4oXCJcXG5cIil9XG5cbmV4cG9ydCBjbGFzcyBNeVN0YWNrIGV4dGVuZHMgU3RhY2sge1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogU3RhY2tQcm9wcyA9IHt9KSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCBwcm9wcyk7XG5cbiAgICAvLyBkZWZpbmUgcmVzb3VyY2VzIGhlcmUuLi5cbiAgfVxufVxuXG4vLyBmb3IgZGV2ZWxvcG1lbnQsIHVzZSBhY2NvdW50L3JlZ2lvbiBmcm9tIGNkayBjbGlcbmNvbnN0IGRldkVudiA9IHtcbiAgYWNjb3VudDogcHJvY2Vzcy5lbnYuQ0RLX0RFRkFVTFRfQUNDT1VOVCxcbiAgcmVnaW9uOiBwcm9jZXNzLmVudi5DREtfREVGQVVMVF9SRUdJT04sXG59O1xuXG5jb25zdCBhcHAgPSBuZXcgQXBwKCk7XG5cbm5ldyBNeVN0YWNrKGFwcCwgJyR7dGhpcy5wcm9qZWN0Lm5hbWV9LWRldicsIHsgZW52OiBkZXZFbnYgfSk7XG4vLyBuZXcgTXlTdGFjayhhcHAsICcke3RoaXMucHJvamVjdC5uYW1lfS1wcm9kJywgeyBlbnY6IHByb2RFbnYgfSk7XG5cbmFwcC5zeW50aCgpO2A7XG5cbiAgICBmcy5ta2RpclN5bmMoc3JjZGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICBmcy53cml0ZUZpbGVTeW5jKHBhdGguam9pbihzcmNkaXIsIHRoaXMuYXBwUHJvamVjdC5hcHBFbnRyeXBvaW50KSwgc3JjQ29kZSk7XG5cbiAgICBjb25zdCB0ZXN0ZGlyID0gcGF0aC5qb2luKG91dGRpciwgdGhpcy5hcHBQcm9qZWN0LnRlc3RkaXIpO1xuICAgIGlmIChcbiAgICAgIGZzLmV4aXN0c1N5bmModGVzdGRpcikgJiZcbiAgICAgIGZzLnJlYWRkaXJTeW5jKHRlc3RkaXIpLmZpbHRlcigoeCkgPT4geC5lbmRzV2l0aChcIi50c1wiKSlcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXN0SW1wb3J0cyA9IG5ldyBBcnJheTxzdHJpbmc+KCk7XG4gICAgaWYgKHRoaXMuY2RrTWFqb3JWZXJzaW9uIDwgMikge1xuICAgICAgdGVzdEltcG9ydHMucHVzaChcImltcG9ydCB7IEFwcCB9IGZyb20gJ0Bhd3MtY2RrL2NvcmUnO1wiKTtcbiAgICAgIHRlc3RJbXBvcnRzLnB1c2goXCJpbXBvcnQgeyBUZW1wbGF0ZSB9IGZyb20gJ0Bhd3MtY2RrL2Fzc2VydGlvbnMnO1wiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGVzdEltcG9ydHMucHVzaChcImltcG9ydCB7IEFwcCB9IGZyb20gJ2F3cy1jZGstbGliJztcIik7XG4gICAgICB0ZXN0SW1wb3J0cy5wdXNoKFwiaW1wb3J0IHsgVGVtcGxhdGUgfSBmcm9tICdhd3MtY2RrLWxpYi9hc3NlcnRpb25zJztcIik7XG4gICAgfVxuXG4gICAgY29uc3QgYXBwRW50cnlwb2ludE5hbWUgPSBwYXRoLmJhc2VuYW1lKFxuICAgICAgdGhpcy5hcHBQcm9qZWN0LmFwcEVudHJ5cG9pbnQsXG4gICAgICBcIi50c1wiXG4gICAgKTtcbiAgICBjb25zdCB0ZXN0Q29kZSA9IGAke3Rlc3RJbXBvcnRzLmpvaW4oXCJcXG5cIil9XG5pbXBvcnQgeyBNeVN0YWNrIH0gZnJvbSAnLi4vJHt0aGlzLmFwcFByb2plY3Quc3JjZGlyfS8ke2FwcEVudHJ5cG9pbnROYW1lfSc7XG5cbnRlc3QoJ1NuYXBzaG90JywgKCkgPT4ge1xuICBjb25zdCBhcHAgPSBuZXcgQXBwKCk7XG4gIGNvbnN0IHN0YWNrID0gbmV3IE15U3RhY2soYXBwLCAndGVzdCcpO1xuXG4gIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgZXhwZWN0KHRlbXBsYXRlLnRvSlNPTigpKS50b01hdGNoU25hcHNob3QoKTtcbn0pO2A7XG5cbiAgICBmcy5ta2RpclN5bmModGVzdGRpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgZnMud3JpdGVGaWxlU3luYyhcbiAgICAgIHBhdGguam9pbih0ZXN0ZGlyLCBgJHthcHBFbnRyeXBvaW50TmFtZX0udGVzdC50c2ApLFxuICAgICAgdGVzdENvZGVcbiAgICApO1xuICB9XG59XG4iXX0=