UNPKG

projen

Version:

CDK for software projects

283 lines (275 loc) • 38.8 kB
"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=