UNPKG

dkershner6-projen-sst-app

Version:

DKershner's preferred constructs for Projen SST Apps.

206 lines 37.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Node20SstApp = void 0; const path_1 = __importDefault(require("path")); const clone_deep_1 = __importDefault(require("clone-deep")); const dkershner6_projen_awscdk_core_1 = require("dkershner6-projen-awscdk-core"); const dkershner6_projen_typescript_1 = require("dkershner6-projen-typescript"); const projen_1 = require("projen"); const github_1 = require("projen/lib/github"); const util_1 = require("projen/lib/util"); const path_2 = require("projen/lib/util/path"); const projen_sst_1 = require("projen-sst"); class Node20SstApp extends projen_sst_1.SstTypescriptApp { jestTransformer; publishToAwsOptions; // eslint-disable-next-line sonarjs/cognitive-complexity constructor(options) { const combinedOptions = (0, util_1.deepMerge)([ (0, clone_deep_1.default)(dkershner6_projen_typescript_1.RECOMMENDED_NODE_20_PROJECT_OPTIONS), options, ]); super(combinedOptions); this.publishToAwsOptions = options.publishToAwsOptions; new dkershner6_projen_typescript_1.DKBugFixes(this); new dkershner6_projen_typescript_1.DKTasks(this); new dkershner6_projen_typescript_1.DKEslintConfig(this); this.jestTransformer = new dkershner6_projen_typescript_1.JestTransformer(this, options.jestOptions); this.eslint?.allowDevDeps(`${this.srcdir}/main.ts`); this.eslint?.allowDevDeps(`${this.srcdir}/*Stack.ts`); this.eslint?.allowDevDeps(`${this.srcdir}/*Stack/index.ts`); this.eslint?.allowDevDeps(`${this.srcdir}/stacks/**/*Stack.ts`); this.eslint?.allowDevDeps(`${this.srcdir}/stacks/**/*Stack/index.ts`); if (options.constructsVersionPinning) { this.addDeps(`constructs@${options.constructsVersion}`); } // No overriding package, since SST cant use an artifact if (this.release && options.publishToAws) { const defaultReleaseWorkflow = this.root?.github?.tryFindWorkflow(dkershner6_projen_awscdk_core_1.AwsAppPublisher.workflowNameForProject("release", this)); if ((defaultReleaseWorkflow && options.publishToAwsOptions?.autoAddJob) || options.publishToAwsOptions?.autoAddJob === undefined) { const synthSilentTask = this.tasks.tryFind("synth:silent"); const deployTask = this.tasks.tryFind("deploy"); if (synthSilentTask && deployTask) { defaultReleaseWorkflow?.addJob("release_aws", this.buildPublishToAwsJob({ deployTask, }, { ...(options.publishToAwsOptions ?? {}), configureAwsCredentialsJobSteps: [ ...(options?.publishToAwsOptions ?.configureAwsCredentialsJobSteps ?? []), { ...(options?.publishToAwsOptions ?.deployJobStepConfiguration ?? {}), name: "Synth", run: `npx projen ${synthSilentTask.name}`, }, ], deployJobStepBuilder: (builderParams) => this.buildDeployToAwsJobStep(builderParams), jobConfiguration: { runsOn: options.workflowRunsOn, runsOnGroup: options.workflowRunsOnGroup, ...(options.publishToAwsOptions ?.jobConfiguration ?? {}), }, })); if (this.release.branches) { const otherBranches = this.release.branches.filter((branch) => branch !== options?.defaultReleaseBranch); for (const branch of otherBranches) { const branchReleaseWorkflow = this.root?.github?.tryFindWorkflow(dkershner6_projen_awscdk_core_1.AwsAppPublisher.workflowNameForProject("release", this, branch)); const stageName = this.branchNameToSstStageMap?.[branch] ?? branch; const synthSilentTaskForBranch = this.tasks.tryFind(`synth:silent:${stageName}`); if (synthSilentTaskForBranch) { branchReleaseWorkflow?.addJob(`release_aws-${branch}`, this.buildPublishToAwsJob({ branchName: branch, deployTask: this.determineDeployTaskToUseForAwsJobStep({ deployTask, branchName: branch, }), }, { ...(options.publishToAwsOptions ?? {}), configureAwsCredentialsJobSteps: [ ...(options?.publishToAwsOptions ?.configureAwsCredentialsJobSteps ?? []), { ...(options ?.publishToAwsOptions ?.deployJobStepConfiguration ?? {}), name: "Synth", run: `npx projen ${synthSilentTaskForBranch.name}`, }, ], deployJobStepBuilder: (builderParams) => this.buildDeployToAwsJobStep(builderParams), jobConfiguration: { runsOn: options.workflowRunsOn, runsOnGroup: options.workflowRunsOnGroup, ...(options.publishToAwsOptions ?.jobConfiguration ?? {}), }, })); } } } } } } const cleanCompileTask = this.tasks.tryFind("clean-compile") ?? this.tasks.addTask("clean-compile", { description: "Clean up the compiled output", }); cleanCompileTask.exec(`rm -rf ${this.sstConfig.sstOut}`); } buildPublishToAwsJob({ deployTask, branchName }, options) { const projectPathRelativeToRoot = path_1.default.relative(this.root.outdir, this.outdir); const workingDirectory = (0, path_2.ensureRelativePathStartsWithDot)(projectPathRelativeToRoot); // We are basically ignoring the artifact since SST needs too many things to use it anyway, but we still download it return { ...(options?.jobConfiguration ?? {}), name: options?.jobConfiguration?.name ?? "Publish to AWS", if: options?.jobConfiguration?.if ?? this.release?.publisher.condition, needs: options?.jobConfiguration?.needs ?? ["release"], permissions: options?.jobConfiguration?.permissions ?? { contents: projen_1.github.workflows.JobPermission.WRITE, packages: projen_1.github.workflows.JobPermission.WRITE, }, defaults: (options?.jobConfiguration?.defaults ?? projectPathRelativeToRoot.length > 0) // is subproject ? { run: { workingDirectory, }, } : undefined, steps: [ ...(options.workflowBootstrapSteps ?? []), github_1.WorkflowSteps.checkout(), // For version.txt { name: "Download build artifacts", uses: "actions/download-artifact@v4", with: { name: "build-artifact", path: `${workingDirectory}/${this.artifactsDirectory}`, }, }, { name: "Restore build artifact permissions", continueOnError: true, run: [ `cd ${this.artifactsDirectory} && setfacl --restore=permissions-backup.acl`, ].join("\n"), }, ...this.renderWorkflowSetup({ installStepConfiguration: { workingDirectory: ".", }, }), ...(options.configureAwsCredentialsJobSteps ?? []), { ...options.deployJobStepBuilder({ deployTask, branchName, }), ...(options?.deployJobStepConfiguration ?? {}), }, ...(options?.postPublishJobSteps ?? []), ], }; } buildDeployToAwsJobStep({ deployTask, branchName, }) { const deployTaskToUse = this.determineDeployTaskToUseForAwsJobStep({ deployTask, branchName, }); // pj is installed const runCommand = `npx projen ${deployTaskToUse.name}`; return { ...(this.publishToAwsOptions?.deployJobStepConfiguration ?? {}), name: this.publishToAwsOptions?.deployJobStepConfiguration?.name ?? "Deploy to AWS", run: `${runCommand} || ${runCommand}`, // Trying twice. Sometimes the first time fails, but the second seems to pick up where the first left off. }; } determineDeployTaskToUseForAwsJobStep({ deployTask, branchName, }) { if (!branchName) { return deployTask; } const stageName = this.branchNameToSstStageMap?.[branchName] ?? branchName; const stageDeployTask = this.tasks.tryFind(`deploy:${stageName}`); if (stageDeployTask) { return stageDeployTask; } throw new Error(`AWSPublisher: Cannot find deploy task for stage ${stageName}`); } } exports.Node20SstApp = Node20SstApp; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsZ0RBQXdCO0FBRXhCLDREQUFtQztBQUNuQyxpRkFLdUM7QUFDdkMsK0VBT3NDO0FBQ3RDLG1DQUFzQztBQUN0Qyw4Q0FBaUU7QUFFakUsMENBQTRDO0FBQzVDLCtDQUF1RTtBQUN2RSwyQ0FBdUU7QUFzQnZFLE1BQWEsWUFBYSxTQUFRLDZCQUFnQjtJQUM5QixlQUFlLENBQWtCO0lBRWhDLG1CQUFtQixDQUF1QjtJQUUzRCx3REFBd0Q7SUFDeEQsWUFBWSxPQUE0QjtRQUNwQyxNQUFNLGVBQWUsR0FBd0IsSUFBQSxnQkFBUyxFQUFDO1lBQ25ELElBQUEsb0JBQVMsRUFBQyxrRUFBbUMsQ0FBQztZQUM5QyxPQUFPO1NBQ1YsQ0FBd0IsQ0FBQztRQUUxQixLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7UUFFdkIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQztRQUV2RCxJQUFJLHlDQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckIsSUFBSSxzQ0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xCLElBQUksNkNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksOENBQWUsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRXRFLElBQUksQ0FBQyxNQUFNLEVBQUUsWUFBWSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sVUFBVSxDQUFDLENBQUM7UUFDcEQsSUFBSSxDQUFDLE1BQU0sRUFBRSxZQUFZLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxZQUFZLENBQUMsQ0FBQztRQUN0RCxJQUFJLENBQUMsTUFBTSxFQUFFLFlBQVksQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLGtCQUFrQixDQUFDLENBQUM7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QUM7SUFFTSx1QkFBdUIsQ0FBQyxFQUMzQixVQUFVLEVBQ1YsVUFBVSxHQUNlO1FBQ3pCLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxxQ0FBcUMsQ0FBQztZQUMvRCxVQUFVO1lBQ1YsVUFBVTtTQUNiLENBQUMsQ0FBQztRQUVILGtCQUFrQjtRQUNsQixNQUFNLFVBQVUsR0FBRyxjQUFjLGVBQWUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUV4RCxPQUFPO1lBQ0gsR0FBRyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSwwQkFBMEIsSUFBSSxFQUFFLENBQUM7WUFDL0QsSUFBSSxFQUNBLElBQUksQ0FBQyxtQkFBbUIsRUFBRSwwQkFBMEIsRUFBRSxJQUFJO2dCQUMxRCxlQUFlO1lBQ25CLEdBQUcsRUFBRSxHQUFHLFVBQVUsT0FBTyxVQUFVLEVBQUUsRUFBRSwyR0FBMkc7U0FDckosQ0FBQztJQUNOLENBQUM7SUFFTyxxQ0FBcUMsQ0FBQyxFQUMxQyxVQUFVLEVBQ1YsVUFBVSxHQUNlO1FBQ3pCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNkLE9BQU8sVUFBVSxDQUFDO1FBQ3RCLENBQUM7UUFFRCxNQUFNLFNBQVMsR0FDWCxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxVQUFVLENBQUM7UUFFN0QsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQ2xFLElBQUksZUFBZSxFQUFFLENBQUM7WUFDbEIsT0FBTyxlQUFlLENBQUM7UUFDM0IsQ0FBQztRQUVELE1BQU0sSUFBSSxLQUFLLENBQ1gsbURBQW1ELFNBQVMsRUFBRSxDQUNqRSxDQUFDO0lBQ04sQ0FBQztDQUNKO0FBcFJELG9DQW9SQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbmltcG9ydCBkZWVwQ2xvbmUgZnJvbSBcImNsb25lLWRlZXBcIjtcbmltcG9ydCB7XG4gICAgQXdzQXBwUHVibGlzaGVyLFxuICAgIEF3c0FwcFB1Ymxpc2hlck9wdGlvbnMsXG4gICAgRGVwbG95Sm9iU3RlcEJ1aWxkZXJQYXJhbXMsXG4gICAgUHVibGlzaFRvQXdzT3B0aW9ucyxcbn0gZnJvbSBcImRrZXJzaG5lcjYtcHJvamVuLWF3c2Nkay1jb3JlXCI7XG5pbXBvcnQge1xuICAgIERLQnVnRml4ZXMsXG4gICAgSmVzdFRyYW5zZm9ybWVyLFxuICAgIERLVGFza3MsXG4gICAgREtFc2xpbnRDb25maWcsXG4gICAgTm9kZTIwVHlwZVNjcmlwdFByb2plY3RKZXN0T3B0aW9ucyxcbiAgICBSRUNPTU1FTkRFRF9OT0RFXzIwX1BST0pFQ1RfT1BUSU9OUyxcbn0gZnJvbSBcImRrZXJzaG5lcjYtcHJvamVuLXR5cGVzY3JpcHRcIjtcbmltcG9ydCB7IFRhc2ssIGdpdGh1YiB9IGZyb20gXCJwcm9qZW5cIjtcbmltcG9ydCB7IEdpdEh1YlByb2plY3QsIFdvcmtmbG93U3RlcHMgfSBmcm9tIFwicHJvamVuL2xpYi9naXRodWJcIjtcbmltcG9ydCB7IEpvYiwgSm9iU3RlcCB9IGZyb20gXCJwcm9qZW4vbGliL2dpdGh1Yi93b3JrZmxvd3MtbW9kZWxcIjtcbmltcG9ydCB7IGRlZXBNZXJnZSB9IGZyb20gXCJwcm9qZW4vbGliL3V0aWxcIjtcbmltcG9ydCB7IGVuc3VyZVJlbGF0aXZlUGF0aFN0YXJ0c1dpdGhEb3QgfSBmcm9tIFwicHJvamVuL2xpYi91dGlsL3BhdGhcIjtcbmltcG9ydCB7IFNzdFR5cGVzY3JpcHRBcHAsIFNzdFR5cGVzY3JpcHRBcHBPcHRpb25zIH0gZnJvbSBcInByb2plbi1zc3RcIjtcblxuZXhwb3J0IGludGVyZmFjZSBOb2RlMjBTc3RBcHBPcHRpb25zIGV4dGVuZHMgU3N0VHlwZXNjcmlwdEFwcE9wdGlvbnMge1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgb3Igbm90IHRvIHBpbiB0aGUgdmVyc2lvbiBvZiBjb25zdHJ1Y3RzIHRvIHRoZSB2ZXJzaW9uIHNwZWNpZmllZCBpbiB0aGVcbiAgICAgKiBgY29uc3RydWN0c1ZlcnNpb25gIHByb3BlcnR5LlxuICAgICAqL1xuICAgIHJlYWRvbmx5IGNvbnN0cnVjdHNWZXJzaW9uUGlubmluZz86IGJvb2xlYW47XG5cbiAgICByZWFkb25seSBqZXN0T3B0aW9ucz86IE5vZGUyMFR5cGVTY3JpcHRQcm9qZWN0SmVzdE9wdGlvbnM7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRvIHB1Ymxpc2ggdGhpcyBBcHAgdG8gQVdTLlxuICAgICAqL1xuICAgIHJlYWRvbmx5IHB1Ymxpc2hUb0F3cz86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBQb3B1bGF0ZSBpbiBvcmRlciB0byBhZGQgYSBkZXBsb3kgdG8gQVdTIGpvYiB0byB0aGUgcmVsZWFzZSB3b3JrZmxvdy5cbiAgICAgKi9cbiAgICByZWFkb25seSBwdWJsaXNoVG9Bd3NPcHRpb25zPzogUHVibGlzaFRvQXdzT3B0aW9ucztcbn1cblxuZXhwb3J0IGNsYXNzIE5vZGUyMFNzdEFwcCBleHRlbmRzIFNzdFR5cGVzY3JpcHRBcHAge1xuICAgIHB1YmxpYyByZWFkb25seSBqZXN0VHJhbnNmb3JtZXI6IEplc3RUcmFuc2Zvcm1lcjtcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgcHVibGlzaFRvQXdzT3B0aW9ucz86IFB1Ymxpc2hUb0F3c09wdGlvbnM7XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgc29uYXJqcy9jb2duaXRpdmUtY29tcGxleGl0eVxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE5vZGUyMFNzdEFwcE9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgY29tYmluZWRPcHRpb25zOiBOb2RlMjBTc3RBcHBPcHRpb25zID0gZGVlcE1lcmdlKFtcbiAgICAgICAgICAgIGRlZXBDbG9uZShSRUNPTU1FTkRFRF9OT0RFXzIwX1BST0pFQ1RfT1BUSU9OUyksXG4gICAgICAgICAgICBvcHRpb25zLFxuICAgICAgICBdKSBhcyBOb2RlMjBTc3RBcHBPcHRpb25zO1xuXG4gICAgICAgIHN1cGVyKGNvbWJpbmVkT3B0aW9ucyk7XG5cbiAgICAgICAgdGhpcy5wdWJsaXNoVG9Bd3NPcHRpb25zID0gb3B0aW9ucy5wdWJsaXNoVG9Bd3NPcHRpb25zO1xuXG4gICAgICAgIG5ldyBES0J1Z0ZpeGVzKHRoaXMpO1xuICAgICAgICBuZXcgREtUYXNrcyh0aGlzKTtcbiAgICAgICAgbmV3IERLRXNsaW50Q29uZmlnKHRoaXMpO1xuICAgICAgICB0aGlzLmplc3RUcmFuc2Zvcm1lciA9IG5ldyBKZXN0VHJhbnNmb3JtZXIodGhpcywgb3B0aW9ucy5qZXN0T3B0aW9ucyk7XG5cbiAgICAgICAgdGhpcy5lc2xpbnQ/LmFsbG93RGV2RGVwcyhgJHt0aGlzLnNyY2Rpcn0vbWFpbi50c2ApO1xuICAgICAgICB0aGlzLmVzbGludD8uYWxsb3dEZXZEZXBzKGAke3RoaXMuc3JjZGlyfS8qU3RhY2sudHNgKTtcbiAgICAgICAgdGhpcy5lc2xpbnQ/LmFsbG93RGV2RGVwcyhgJHt0aGlzLnNyY2Rpcn0vKlN0YWNrL2luZGV4LnRzYCk7XG4gICAgICAgIHRoaXMuZXNsaW50Py5hbGxvd0RldkRlcHMoYCR7dGhpcy5zcmNkaXJ9L3N0YWNrcy8qKi8qU3RhY2sudHNgKTtcbiAgICAgICAgdGhpcy5lc2xpbnQ/LmFsbG93RGV2RGVwcyhgJHt0aGlzLnNyY2Rpcn0vc3RhY2tzLyoqLypTdGFjay9pbmRleC50c2ApO1xuXG4gICAgICAgIGlmIChvcHRpb25zLmNvbnN0cnVjdHNWZXJzaW9uUGlubmluZykge1xuICAgICAgICAgICAgdGhpcy5hZGREZXBzKGBjb25zdHJ1Y3RzQCR7b3B0aW9ucy5jb25zdHJ1Y3RzVmVyc2lvbn1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE5vIG92ZXJyaWRpbmcgcGFja2FnZSwgc2luY2UgU1NUIGNhbnQgdXNlIGFuIGFydGlmYWN0XG5cbiAgICAgICAgaWYgKHRoaXMucmVsZWFzZSAmJiBvcHRpb25zLnB1Ymxpc2hUb0F3cykge1xuICAgICAgICAgICAgY29uc3QgZGVmYXVsdFJlbGVhc2VXb3JrZmxvdyA9IChcbiAgICAgICAgICAgICAgICB0aGlzLnJvb3QgYXMgR2l0SHViUHJvamVjdFxuICAgICAgICAgICAgKT8uZ2l0aHViPy50cnlGaW5kV29ya2Zsb3coXG4gICAgICAgICAgICAgICAgQXdzQXBwUHVibGlzaGVyLndvcmtmbG93TmFtZUZvclByb2plY3QoXCJyZWxlYXNlXCIsIHRoaXMpLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAoZGVmYXVsdFJlbGVhc2VXb3JrZmxvdyAmJlxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnB1Ymxpc2hUb0F3c09wdGlvbnM/LmF1dG9BZGRKb2IpIHx8XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5wdWJsaXNoVG9Bd3NPcHRpb25zPy5hdXRvQWRkSm9iID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN5bnRoU2lsZW50VGFzayA9IHRoaXMudGFza3MudHJ5RmluZChcInN5bnRoOnNpbGVudFwiKTtcbiAgICAgICAgICAgICAgICBjb25zdCBkZXBsb3lUYXNrID0gdGhpcy50YXNrcy50cnlGaW5kKFwiZGVwbG95XCIpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHN5bnRoU2lsZW50VGFzayAmJiBkZXBsb3lUYXNrKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRSZWxlYXNlV29ya2Zsb3c/LmFkZEpvYihcbiAgICAgICAgICAgICAgICAgICAgICAgIFwicmVsZWFzZV9hd3NcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYnVpbGRQdWJsaXNoVG9Bd3NKb2IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXBsb3lUYXNrLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi4ob3B0aW9ucy5wdWJsaXNoVG9Bd3NPcHRpb25zID8/IHt9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlndXJlQXdzQ3JlZGVudGlhbHNKb2JTdGVwczogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uKG9wdGlvbnM/LnB1Ymxpc2hUb0F3c09wdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/LmNvbmZpZ3VyZUF3c0NyZWRlbnRpYWxzSm9iU3RlcHMgPz9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbXSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uKG9wdGlvbnM/LnB1Ymxpc2hUb0F3c09wdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPy5kZXBsb3lKb2JTdGVwQ29uZmlndXJhdGlvbiA/PyB7fSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJTeW50aFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bjogYG5weCBwcm9qZW4gJHtzeW50aFNpbGVudFRhc2submFtZX1gLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwbG95Sm9iU3RlcEJ1aWxkZXI6IChidWlsZGVyUGFyYW1zKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5idWlsZERlcGxveVRvQXdzSm9iU3RlcChidWlsZGVyUGFyYW1zKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgam9iQ29uZmlndXJhdGlvbjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVuc09uOiBvcHRpb25zLndvcmtmbG93UnVuc09uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVuc09uR3JvdXA6IG9wdGlvbnMud29ya2Zsb3dSdW5zT25Hcm91cCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLihvcHRpb25zLnB1Ymxpc2hUb0F3c09wdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/LmpvYkNvbmZpZ3VyYXRpb24gPz8ge30pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbGVhc2UuYnJhbmNoZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG90aGVyQnJhbmNoZXMgPSB0aGlzLnJlbGVhc2UuYnJhbmNoZXMuZmlsdGVyKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChicmFuY2gpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyYW5jaCAhPT0gb3B0aW9ucz8uZGVmYXVsdFJlbGVhc2VCcmFuY2gsXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBicmFuY2ggb2Ygb3RoZXJCcmFuY2hlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJyYW5jaFJlbGVhc2VXb3JrZmxvdyA9IChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yb290IGFzIEdpdEh1YlByb2plY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApPy5naXRodWI/LnRyeUZpbmRXb3JrZmxvdyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXdzQXBwUHVibGlzaGVyLndvcmtmbG93TmFtZUZvclByb2plY3QoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcInJlbGVhc2VcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmFuY2gsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YWdlTmFtZSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYnJhbmNoTmFtZVRvU3N0U3RhZ2VNYXA/LlticmFuY2hdID8/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyYW5jaDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzeW50aFNpbGVudFRhc2tGb3JCcmFuY2ggPSB0aGlzLnRhc2tzLnRyeUZpbmQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBzeW50aDpzaWxlbnQ6JHtzdGFnZU5hbWV9YCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN5bnRoU2lsZW50VGFza0ZvckJyYW5jaCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmFuY2hSZWxlYXNlV29ya2Zsb3c/LmFkZEpvYihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGByZWxlYXNlX2F3cy0ke2JyYW5jaH1gLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5idWlsZFB1Ymxpc2hUb0F3c0pvYihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyYW5jaE5hbWU6IGJyYW5jaCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwbG95VGFzazpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGV0ZXJtaW5lRGVwbG95VGFza1RvVXNlRm9yQXdzSm9iU3RlcChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcGxveVRhc2ssXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyYW5jaE5hbWU6IGJyYW5jaCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uKG9wdGlvbnMucHVibGlzaFRvQXdzT3B0aW9ucyA/P1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge30pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWd1cmVBd3NDcmVkZW50aWFsc0pvYlN0ZXBzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi4ob3B0aW9ucz8ucHVibGlzaFRvQXdzT3B0aW9uc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8uY29uZmlndXJlQXdzQ3JlZGVudGlhbHNKb2JTdGVwcyA/P1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtdKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi4ob3B0aW9uc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/LnB1Ymxpc2hUb0F3c09wdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPy5kZXBsb3lKb2JTdGVwQ29uZmlndXJhdGlvbiA/P1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7fSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJTeW50aFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bjogYG5weCBwcm9qZW4gJHtzeW50aFNpbGVudFRhc2tGb3JCcmFuY2gubmFtZX1gLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwbG95Sm9iU3RlcEJ1aWxkZXI6IChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1aWxkZXJQYXJhbXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYnVpbGREZXBsb3lUb0F3c0pvYlN0ZXAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVpbGRlclBhcmFtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpvYkNvbmZpZ3VyYXRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bnNPbjogb3B0aW9ucy53b3JrZmxvd1J1bnNPbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bnNPbkdyb3VwOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMud29ya2Zsb3dSdW5zT25Hcm91cCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLihvcHRpb25zLnB1Ymxpc2hUb0F3c09wdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/LmpvYkNvbmZpZ3VyYXRpb24gPz8ge30pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNsZWFuQ29tcGlsZVRhc2sgPVxuICAgICAgICAgICAgdGhpcy50YXNrcy50cnlGaW5kKFwiY2xlYW4tY29tcGlsZVwiKSA/P1xuICAgICAgICAgICAgdGhpcy50YXNrcy5hZGRUYXNrKFwiY2xlYW4tY29tcGlsZVwiLCB7XG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiQ2xlYW4gdXAgdGhlIGNvbXBpbGVkIG91dHB1dFwiLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIGNsZWFuQ29tcGlsZVRhc2suZXhlYyhgcm0gLXJmICR7dGhpcy5zc3RDb25maWcuc3N0T3V0fWApO1xuICAgIH1cblxuICAgIHB1YmxpYyBidWlsZFB1Ymxpc2hUb0F3c0pvYihcbiAgICAgICAgeyBkZXBsb3lUYXNrLCBicmFuY2hOYW1lIH06IERlcGxveUpvYlN0ZXBCdWlsZGVyUGFyYW1zLFxuICAgICAgICBvcHRpb25zOiBBd3NBcHBQdWJsaXNoZXJPcHRpb25zLFxuICAgICk6IEpvYiB7XG4gICAgICAgIGNvbnN0IHByb2plY3RQYXRoUmVsYXRpdmVUb1Jvb3QgPSBwYXRoLnJlbGF0aXZlKFxuICAgICAgICAgICAgdGhpcy5yb290Lm91dGRpcixcbiAgICAgICAgICAgIHRoaXMub3V0ZGlyLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHdvcmtpbmdEaXJlY3RvcnkgPSBlbnN1cmVSZWxhdGl2ZVBhdGhTdGFydHNXaXRoRG90KFxuICAgICAgICAgICAgcHJvamVjdFBhdGhSZWxhdGl2ZVRvUm9vdCxcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBXZSBhcmUgYmFzaWNhbGx5IGlnbm9yaW5nIHRoZSBhcnRpZmFjdCBzaW5jZSBTU1QgbmVlZHMgdG9vIG1hbnkgdGhpbmdzIHRvIHVzZSBpdCBhbnl3YXksIGJ1dCB3ZSBzdGlsbCBkb3dubG9hZCBpdFxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uKG9wdGlvbnM/LmpvYkNvbmZpZ3VyYXRpb24gPz8ge30pLFxuICAgICAgICAgICAgbmFtZTogb3B0aW9ucz8uam9iQ29uZmlndXJhdGlvbj8ubmFtZSA/PyBcIlB1Ymxpc2ggdG8gQVdTXCIsXG4gICAgICAgICAgICBpZjpcbiAgICAgICAgICAgICAgICBvcHRpb25zPy5qb2JDb25maWd1cmF0aW9uPy5pZiA/P1xuICAgICAgICAgICAgICAgIHRoaXMucmVsZWFzZT8ucHVibGlzaGVyLmNvbmRpdGlvbixcbiAgICAgICAgICAgIG5lZWRzOiBvcHRpb25zPy5qb2JDb25maWd1cmF0aW9uPy5uZWVkcyA/PyBbXCJyZWxlYXNlXCJdLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IG9wdGlvbnM/LmpvYkNvbmZpZ3VyYXRpb24/LnBlcm1pc3Npb25zID8/IHtcbiAgICAgICAgICAgICAgICBjb250ZW50czogZ2l0aHViLndvcmtmbG93cy5Kb2JQZXJtaXNzaW9uLldSSVRFLFxuICAgICAgICAgICAgICAgIHBhY2thZ2VzOiBnaXRodWIud29ya2Zsb3dzLkpvYlBlcm1pc3Npb24uV1JJVEUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGVmYXVsdHM6XG4gICAgICAgICAgICAgICAgKG9wdGlvbnM/LmpvYkNvbmZpZ3VyYXRpb24/LmRlZmF1bHRzID8/XG4gICAgICAgICAgICAgICAgcHJvamVjdFBhdGhSZWxhdGl2ZVRvUm9vdC5sZW5ndGggPiAwKSAvLyBpcyBzdWJwcm9qZWN0XG4gICAgICAgICAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBydW46IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdvcmtpbmdEaXJlY3RvcnksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHN0ZXBzOiBbXG4gICAgICAgICAgICAgICAgLi4uKG9wdGlvbnMud29ya2Zsb3dCb290c3RyYXBTdGVwcyA/PyBbXSksXG4gICAgICAgICAgICAgICAgV29ya2Zsb3dTdGVwcy5jaGVja291dCgpLFxuICAgICAgICAgICAgICAgIC8vIEZvciB2ZXJzaW9uLnR4dFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJEb3dubG9hZCBidWlsZCBhcnRpZmFjdHNcIixcbiAgICAgICAgICAgICAgICAgICAgdXNlczogXCJhY3Rpb25zL2Rvd25sb2FkLWFydGlmYWN0QHY0XCIsXG4gICAgICAgICAgICAgICAgICAgIHdpdGg6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IFwiYnVpbGQtYXJ0aWZhY3RcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6IGAke3dvcmtpbmdEaXJlY3Rvcnl9LyR7dGhpcy5hcnRpZmFjdHNEaXJlY3Rvcnl9YCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJSZXN0b3JlIGJ1aWxkIGFydGlmYWN0IHBlcm1pc3Npb25zXCIsXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlT25FcnJvcjogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgcnVuOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICBgY2QgJHt0aGlzLmFydGlmYWN0c0RpcmVjdG9yeX0gJiYgc2V0ZmFjbCAtLXJlc3RvcmU9cGVybWlzc2lvbnMtYmFja3VwLmFjbGAsXG4gICAgICAgICAgICAgICAgICAgIF0uam9pbihcIlxcblwiKSxcbiAgICAgICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAgICAgLi4udGhpcy5yZW5kZXJXb3JrZmxvd1NldHVwKHtcbiAgICAgICAgICAgICAgICAgICAgaW5zdGFsbFN0ZXBDb25maWd1cmF0aW9uOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB3b3JraW5nRGlyZWN0b3J5OiBcIi5cIixcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAuLi4ob3B0aW9ucy5jb25maWd1cmVBd3NDcmVkZW50aWFsc0pvYlN0ZXBzID8/IFtdKSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIC4uLm9wdGlvbnMuZGVwbG95Sm9iU3RlcEJ1aWxkZXIoe1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVwbG95VGFzayxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyYW5jaE5hbWUsXG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAuLi4ob3B0aW9ucz8uZGVwbG95Sm9iU3RlcENvbmZpZ3VyYXRpb24gPz8ge30pLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgLi4uKG9wdGlvbnM/LnBvc3RQdWJsaXNoSm9iU3RlcHMgPz8gW10pLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYnVpbGREZXBsb3lUb0F3c0pvYlN0ZXAoe1xuICAgICAgICBkZXBsb3lUYXNrLFxuICAgICAgICBicmFuY2hOYW1lLFxuICAgIH06IERlcGxveUpvYlN0ZXBCdWlsZGVyUGFyYW1zKTogSm9iU3RlcCB7XG4gICAgICAgIGNvbnN0IGRlcGxveVRhc2tUb1VzZSA9IHRoaXMuZGV0ZXJtaW5lRGVwbG95VGFza1RvVXNlRm9yQXdzSm9iU3RlcCh7XG4gICAgICAgICAgICBkZXBsb3lUYXNrLFxuICAgICAgICAgICAgYnJhbmNoTmFtZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gcGogaXMgaW5zdGFsbGVkXG4gICAgICAgIGNvbnN0IHJ1bkNvbW1hbmQgPSBgbnB4IHByb2plbiAke2RlcGxveVRhc2tUb1VzZS5uYW1lfWA7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLih0aGlzLnB1Ymxpc2hUb0F3c09wdGlvbnM/LmRlcGxveUpvYlN0ZXBDb25maWd1cmF0aW9uID8/IHt9KSxcbiAgICAgICAgICAgIG5hbWU6XG4gICAgICAgICAgICAgICAgdGhpcy5wdWJsaXNoVG9Bd3NPcHRpb25zPy5kZXBsb3lKb2JTdGVwQ29uZmlndXJhdGlvbj8ubmFtZSA/P1xuICAgICAgICAgICAgICAgIFwiRGVwbG95IHRvIEFXU1wiLFxuICAgICAgICAgICAgcnVuOiBgJHtydW5Db21tYW5kfSB8fCAke3J1bkNvbW1hbmR9YCwgLy8gVHJ5aW5nIHR3aWNlLiAgU29tZXRpbWVzIHRoZSBmaXJzdCB0aW1lIGZhaWxzLCBidXQgdGhlIHNlY29uZCBzZWVtcyB0byBwaWNrIHVwIHdoZXJlIHRoZSBmaXJzdCBsZWZ0IG9mZi5cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGRldGVybWluZURlcGxveVRhc2tUb1VzZUZvckF3c0pvYlN0ZXAoe1xuICAgICAgICBkZXBsb3lUYXNrLFxuICAgICAgICBicmFuY2hOYW1lLFxuICAgIH06IERlcGxveUpvYlN0ZXBCdWlsZGVyUGFyYW1zKTogVGFzayB7XG4gICAgICAgIGlmICghYnJhbmNoTmFtZSkge1xuICAgICAgICAgICAgcmV0dXJuIGRlcGxveVRhc2s7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdGFnZU5hbWUgPVxuICAgICAgICAgICAgdGhpcy5icmFuY2hOYW1lVG9Tc3RTdGFnZU1hcD8uW2JyYW5jaE5hbWVdID8/IGJyYW5jaE5hbWU7XG5cbiAgICAgICAgY29uc3Qgc3RhZ2VEZXBsb3lUYXNrID0gdGhpcy50YXNrcy50cnlGaW5kKGBkZXBsb3k6JHtzdGFnZU5hbWV9YCk7XG4gICAgICAgIGlmIChzdGFnZURlcGxveVRhc2spIHtcbiAgICAgICAgICAgIHJldHVybiBzdGFnZURlcGxveVRhc2s7XG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgQVdTUHVibGlzaGVyOiBDYW5ub3QgZmluZCBkZXBsb3kgdGFzayBmb3Igc3RhZ2UgJHtzdGFnZU5hbWV9YCxcbiAgICAgICAgKTtcbiAgICB9XG59XG4iXX0=