UNPKG

@aws/pdk

Version:

All documentation is located at: https://aws.github.io/aws-pdk

368 lines 66.1 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.TypeSafeApiProject = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); /*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ const fs = require("fs"); const path = require("path"); const monorepo_1 = require("../../monorepo"); const projen_1 = require("projen"); const javascript_1 = require("projen/lib/javascript"); const generate_1 = require("./codegen/generate"); const languages_1 = require("./languages"); /** * Project for a type-safe API, defined using Smithy or OpenAPI. * * Generates a CDK construct to deploy your API, as well as client and server code to help build your API quickly. * * @pjid type-safe-api */ class TypeSafeApiProject extends projen_1.Project { constructor(options) { super(options); this.getNxWorkspace = (options) => { return options.parent ? monorepo_1.NxWorkspace.of(options.parent) : undefined; }; const nxWorkspace = this.getNxWorkspace(options); const isNxWorkspace = this.parent && (monorepo_1.ProjectUtils.isNamedInstanceOf(this.parent, monorepo_1.MonorepoTsProject) || monorepo_1.ProjectUtils.isNamedInstanceOf(this.parent, monorepo_1.MonorepoJavaProject) || monorepo_1.ProjectUtils.isNamedInstanceOf(this.parent, monorepo_1.MonorepoPythonProject)); const handlerLanguages = [...new Set(options.handlers?.languages ?? [])]; // Try to infer monorepo default release branch, otherwise default to mainline unless overridden const defaultReleaseBranch = nxWorkspace?.affected.defaultBase ?? "mainline"; const packageManager = this.parent && monorepo_1.ProjectUtils.isNamedInstanceOf(this.parent, javascript_1.NodeProject) ? this.parent.package.packageManager : javascript_1.NodePackageManager.PNPM; // API Definition project containing the model const modelDir = "model"; const parsedSpecFile = ".api.json"; this.model = (0, generate_1.generateModelProject)({ parent: nxWorkspace ? this.parent : this, outdir: nxWorkspace ? path.join(options.outdir, modelDir) : modelDir, name: `${options.name}-model`, modelLanguage: options.model.language, modelOptions: options.model.options, handlerLanguages, defaultReleaseBranch: nxWorkspace?.affected?.defaultBase ?? "mainline", packageManager, parsedSpecFile, }); const modelProject = [ this.model.openapi, this.model.smithy, this.model.typeSpec, ].filter((m) => m)[0]; // Ensure we always generate a runtime project for the infrastructure language, regardless of what was specified by // the user. Likewise we generate a runtime project for any handler languages specified const runtimeLanguages = [ ...new Set([ ...(options.runtime?.languages ?? []), options.infrastructure.language, ...(options.handlers?.languages ?? []), ]), ]; const generatedDir = "generated"; const runtimeDir = path.join(generatedDir, "runtime"); const runtimeDirRelativeToParent = nxWorkspace ? path.join(options.outdir, runtimeDir) : runtimeDir; // Path from a generated package directory (eg api/generated/runtime/typescript) to the model dir (ie api/model) const relativePathToModelDirFromGeneratedPackageDir = path.relative(path.join(this.outdir, runtimeDir, "language"), path.join(this.outdir, modelDir)); const parsedSpecRelativeToGeneratedPackageDir = path.join(relativePathToModelDirFromGeneratedPackageDir, this.model.parsedSpecFile); // Declare the generated runtime projects const generatedRuntimeProjects = (0, generate_1.generateRuntimeProjects)(runtimeLanguages, { parent: nxWorkspace ? this.parent : this, parentPackageName: this.name, generatedCodeDir: runtimeDirRelativeToParent, isWithinMonorepo: isNxWorkspace, // Spec path relative to each generated runtime dir parsedSpecPath: parsedSpecRelativeToGeneratedPackageDir, typescriptOptions: { defaultReleaseBranch, packageManager, commitGeneratedCode: options.runtime?.options?.typescript?.commitGeneratedCode ?? options.commitGeneratedCode ?? false, ...options.runtime?.options?.typescript, }, pythonOptions: { authorName: "APJ Cope", authorEmail: "apj-cope@amazon.com", version: "0.0.0", commitGeneratedCode: options.runtime?.options?.python?.commitGeneratedCode ?? options.commitGeneratedCode ?? false, ...options.runtime?.options?.python, }, javaOptions: { version: "0.0.0", commitGeneratedCode: options.runtime?.options?.java?.commitGeneratedCode ?? options.commitGeneratedCode ?? false, ...options.runtime?.options?.java, }, }); const documentationFormats = [ ...new Set(options.documentation?.formats ?? []), ]; const docsDir = path.join(generatedDir, "documentation"); const docsDirRelativeToParent = nxWorkspace ? path.join(options.outdir, docsDir) : docsDir; const generatedDocs = (0, generate_1.generateDocsProjects)(documentationFormats, { parent: nxWorkspace ? this.parent : this, parentPackageName: this.name, generatedDocsDir: docsDirRelativeToParent, // Spec path relative to each generated doc format dir parsedSpecPath: parsedSpecRelativeToGeneratedPackageDir, documentationOptions: options.documentation?.options, }); this.documentation = { htmlRedoc: generatedDocs[languages_1.DocumentationFormat.HTML_REDOC], markdown: generatedDocs[languages_1.DocumentationFormat.MARKDOWN], plantuml: generatedDocs[languages_1.DocumentationFormat.PLANTUML], }; const libraries = [...new Set(options.library?.libraries ?? [])]; const libraryDir = path.join(generatedDir, "libraries"); const libraryDirRelativeToParent = nxWorkspace ? path.join(options.outdir, libraryDir) : libraryDir; // Declare the generated runtime projects const generatedLibraryProjects = (0, generate_1.generateLibraryProjects)(libraries, { parent: nxWorkspace ? this.parent : this, parentPackageName: this.name, generatedCodeDir: libraryDirRelativeToParent, isWithinMonorepo: isNxWorkspace, // Spec path relative to each generated library dir parsedSpecPath: parsedSpecRelativeToGeneratedPackageDir, typescriptReactQueryHooksOptions: { defaultReleaseBranch, packageManager, commitGeneratedCode: options.library?.options?.typescriptReactQueryHooks ?.commitGeneratedCode ?? options.commitGeneratedCode ?? false, ...options.library?.options?.typescriptReactQueryHooks, }, }); // Ensure the generated runtime, libraries and docs projects have a dependency on the model project if (this.parent) { [ ...Object.values(generatedRuntimeProjects), ...Object.values(generatedDocs), ...Object.values(generatedLibraryProjects), ].forEach((project) => { monorepo_1.NxProject.ensure(project).addImplicitDependency(modelProject); }); } this.runtime = { typescript: generatedRuntimeProjects[languages_1.Language.TYPESCRIPT] ? generatedRuntimeProjects[languages_1.Language.TYPESCRIPT] : undefined, java: generatedRuntimeProjects[languages_1.Language.JAVA] ? generatedRuntimeProjects[languages_1.Language.JAVA] : undefined, python: generatedRuntimeProjects[languages_1.Language.PYTHON] ? generatedRuntimeProjects[languages_1.Language.PYTHON] : undefined, }; this.library = { typescriptReactQueryHooks: generatedLibraryProjects[languages_1.Library.TYPESCRIPT_REACT_QUERY_HOOKS] ? generatedLibraryProjects[languages_1.Library.TYPESCRIPT_REACT_QUERY_HOOKS] : undefined, }; const handlersDir = "handlers"; const handlersDirRelativeToParent = nxWorkspace ? path.join(options.outdir, handlersDir) : handlersDir; const relativePathToModelDirFromHandlersDir = path.relative(path.join(this.outdir, handlersDir, "language"), path.join(this.outdir, modelDir)); const parsedSpecRelativeToHandlersDir = path.join(relativePathToModelDirFromHandlersDir, this.model.parsedSpecFile); // Declare the generated handlers projects const generatedHandlersProjects = (0, generate_1.generateHandlersProjects)(handlerLanguages, { parent: nxWorkspace ? this.parent : this, parentPackageName: this.name, generatedCodeDir: handlersDirRelativeToParent, isWithinMonorepo: isNxWorkspace, // Spec path relative to each generated handlers package dir parsedSpecPath: parsedSpecRelativeToHandlersDir, typescriptOptions: { // Try to infer monorepo default release branch, otherwise default to mainline unless overridden defaultReleaseBranch: nxWorkspace?.affected.defaultBase ?? "mainline", packageManager: this.parent && monorepo_1.ProjectUtils.isNamedInstanceOf(this.parent, javascript_1.NodeProject) ? this.parent.package.packageManager : javascript_1.NodePackageManager.PNPM, commitGeneratedCode: options.handlers?.options?.typescript?.commitGeneratedCode ?? options.commitGeneratedCode ?? false, ...options.handlers?.options?.typescript, }, pythonOptions: { authorName: "APJ Cope", authorEmail: "apj-cope@amazon.com", version: "0.0.0", commitGeneratedCode: options.handlers?.options?.python?.commitGeneratedCode ?? options.commitGeneratedCode ?? false, ...options.handlers?.options?.python, }, javaOptions: { version: "0.0.0", commitGeneratedCode: options.handlers?.options?.java?.commitGeneratedCode ?? options.commitGeneratedCode ?? false, ...options.handlers?.options?.java, }, generatedRuntimes: { typescript: this.runtime.typescript, python: this.runtime.python, java: this.runtime.java, }, }); this.handlers = { typescript: generatedHandlersProjects[languages_1.Language.TYPESCRIPT] ? generatedHandlersProjects[languages_1.Language.TYPESCRIPT] : undefined, java: generatedHandlersProjects[languages_1.Language.JAVA] ? generatedHandlersProjects[languages_1.Language.JAVA] : undefined, python: generatedHandlersProjects[languages_1.Language.PYTHON] ? generatedHandlersProjects[languages_1.Language.PYTHON] : undefined, }; // Ensure the handlers project depends on the appropriate runtime projects if (this.handlers.typescript) { monorepo_1.NxProject.ensure(this.handlers.typescript).addImplicitDependency(this.runtime.typescript); } if (this.handlers.java) { monorepo_1.NxProject.ensure(this.handlers.java).addImplicitDependency(this.runtime.java); } if (this.handlers.python) { monorepo_1.NxProject.ensure(this.handlers.python).addImplicitDependency(this.runtime.python); } const infraDir = path.join(generatedDir, "infrastructure"); const infraDirRelativeToParent = nxWorkspace ? path.join(options.outdir, infraDir) : infraDir; // Infrastructure project const infraProject = (0, generate_1.generateInfraProject)(options.infrastructure.language, { parent: nxWorkspace ? this.parent : this, parentPackageName: this.name, generatedCodeDir: infraDirRelativeToParent, isWithinMonorepo: isNxWorkspace, // Spec path relative to each generated infra package dir parsedSpecPath: parsedSpecRelativeToGeneratedPackageDir, typescriptOptions: { defaultReleaseBranch, packageManager, commitGeneratedCode: options.infrastructure.options?.typescript?.commitGeneratedCode ?? options.commitGeneratedCode ?? false, ...options.infrastructure.options?.typescript, }, pythonOptions: { authorName: "APJ Cope", authorEmail: "apj-cope@amazon.com", version: "0.0.0", commitGeneratedCode: options.infrastructure.options?.python?.commitGeneratedCode ?? options.commitGeneratedCode ?? false, ...options.infrastructure.options?.python, }, javaOptions: { version: "0.0.0", commitGeneratedCode: options.infrastructure.options?.java?.commitGeneratedCode ?? options.commitGeneratedCode ?? false, ...options.infrastructure.options?.java, }, generatedRuntimes: { typescript: this.runtime.typescript, python: this.runtime.python, java: this.runtime.java, }, generatedHandlers: { typescript: this.handlers.typescript, python: this.handlers.python, java: this.handlers.java, }, }); const infraProjects = {}; // Add implicit dependencies and assign the appropriate infrastructure project member switch (options.infrastructure.language) { case languages_1.Language.JAVA: monorepo_1.NxProject.ensure(infraProject).addImplicitDependency(this.runtime.java); infraProjects.java = infraProject; break; case languages_1.Language.PYTHON: monorepo_1.NxProject.ensure(infraProject).addImplicitDependency(this.runtime.python); infraProjects.python = infraProject; break; case languages_1.Language.TYPESCRIPT: monorepo_1.NxProject.ensure(infraProject).addImplicitDependency(this.runtime.typescript); infraProjects.typescript = infraProject; break; default: throw new Error(`Unknown infrastructure language ${options.infrastructure.language}`); } this.infrastructure = infraProjects; monorepo_1.NxProject.ensure(infraProject).addImplicitDependency(modelProject); // Expose collections of projects const allRuntimes = Object.values(generatedRuntimeProjects); const allInfrastructure = [infraProject]; const allLibraries = Object.values(generatedLibraryProjects); const allDocumentation = Object.values(generatedDocs); const allHandlers = Object.values(generatedHandlersProjects); this.all = { model: [modelProject], runtimes: allRuntimes, infrastructure: allInfrastructure, libraries: allLibraries, documentation: allDocumentation, handlers: allHandlers, projects: [ modelProject, ...allRuntimes, ...allInfrastructure, ...allLibraries, ...allDocumentation, ...allHandlers, ], }; if (!nxWorkspace) { // Add a task for the non-monorepo case to build the projects in the right order [ modelProject, ...Object.values(generatedRuntimeProjects), infraProject, ...Object.values(generatedLibraryProjects), ...Object.values(generatedDocs), ].forEach((project) => { this.compileTask.exec("npx projen build", { cwd: path.relative(this.outdir, project.outdir), }); }); } // Add the README as a sample file which the user may edit new projen_1.SampleFile(this, "README.md", { sourcePath: path.resolve(__dirname, "..", "..", "samples", "type-safe-api", "readme", "TYPE_SAFE_API.md"), }); } /** * @inheritDoc */ postSynthesize() { // Migration code, since we've moved these generated directories under a parent "generated" // folder, we delete the generated projects which would otherwise be orphaned and still // checked into VCS ["runtime", "libraries", "infrastructure", "documentation"].forEach((dir) => fs.rmSync(path.join(this.outdir, dir), { force: true, recursive: true })); super.postSynthesize(); } } exports.TypeSafeApiProject = TypeSafeApiProject; _a = JSII_RTTI_SYMBOL_1; TypeSafeApiProject[_a] = { fqn: "@aws/pdk.type_safe_api.TypeSafeApiProject", version: "0.26.14" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS1zYWZlLWFwaS1wcm9qZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidHlwZS1zYWZlLWFwaS1wcm9qZWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUE7c0NBQ3NDO0FBQ3RDLHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUFDN0IsNENBT3VCO0FBQ3ZCLG1DQUE2RDtBQUU3RCxzREFBd0U7QUFHeEUsaURBTzRCO0FBTzVCLDJDQUFxRTtBQTBJckU7Ozs7OztHQU1HO0FBQ0gsTUFBYSxrQkFBbUIsU0FBUSxnQkFBTztJQStCN0MsWUFBWSxPQUFrQztRQUM1QyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUE2YlQsbUJBQWMsR0FBRyxDQUN2QixPQUFrQyxFQUNULEVBQUU7WUFDM0IsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxzQkFBVyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUNyRSxDQUFDLENBQUM7UUEvYkEsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUVqRCxNQUFNLGFBQWEsR0FDakIsSUFBSSxDQUFDLE1BQU07WUFDWCxDQUFDLHVCQUFZLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSw0QkFBaUIsQ0FBQztnQkFDN0QsdUJBQVksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLDhCQUFtQixDQUFDO2dCQUNoRSx1QkFBWSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsZ0NBQXFCLENBQUMsQ0FBQyxDQUFDO1FBRXhFLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsU0FBUyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFekUsZ0dBQWdHO1FBQ2hHLE1B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QUFTLEVBQ1QsSUFBSSxFQUNKLElBQUksRUFDSixTQUFTLEVBQ1QsZUFBZSxFQUNmLFFBQVEsRUFDUixrQkFBa0IsQ0FDbkI7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxjQUFjO1FBQ25CLDJGQUEyRjtRQUMzRix1RkFBdUY7UUFDdkYsbUJBQW1CO1FBQ25CLENBQUMsU0FBUyxFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBRSxlQUFlLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUMxRSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQ3pFLENBQUM7UUFFRixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDekIsQ0FBQzs7QUEzZEgsZ0RBa2VDIiwic291cmNlc0NvbnRlbnQiOlsiLyohIENvcHlyaWdodCBbQW1hem9uLmNvbV0oaHR0cDovL2FtYXpvbi5jb20vKSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wICovXG5pbXBvcnQgKiBhcyBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7XG4gIE1vbm9yZXBvVHNQcm9qZWN0LFxuICBNb25vcmVwb0phdmFQcm9qZWN0LFxuICBNb25vcmVwb1B5dGhvblByb2plY3QsXG4gIE54UHJvamVjdCxcbiAgTnhXb3Jrc3BhY2UsXG4gIFByb2plY3RVdGlscyxcbn0gZnJvbSBcIkBhd3MvbW9ub3JlcG9cIjtcbmltcG9ydCB7IFByb2plY3QsIFByb2plY3RPcHRpb25zLCBTYW1wbGVGaWxlIH0gZnJvbSBcInByb2plblwiO1xuaW1wb3J0IHsgSmF2YVByb2plY3QgfSBmcm9tIFwicHJvamVuL2xpYi9qYXZhXCI7XG5pbXBvcnQgeyBOb2RlUGFja2FnZU1hbmFnZXIsIE5vZGVQcm9qZWN0IH0gZnJvbSBcInByb2plbi9saWIvamF2YXNjcmlwdFwiO1xuaW1wb3J0IHsgUHl0aG9uUHJvamVjdCB9IGZyb20gXCJwcm9qZW4vbGliL3B5dGhvblwiO1xuaW1wb3J0IHsgVHlwZVNjcmlwdFByb2plY3QgfSBmcm9tIFwicHJvamVuL2xpYi90eXBlc2NyaXB0XCI7XG5pbXBvcnQge1xuICBnZW5lcmF0ZVJ1bnRpbWVQcm9qZWN0cyxcbiAgZ2VuZXJhdGVEb2NzUHJvamVjdHMsXG4gIGdlbmVyYXRlSW5mcmFQcm9qZWN0LFxuICBnZW5lcmF0ZUxpYnJhcnlQcm9qZWN0cyxcbiAgZ2VuZXJhdGVIYW5kbGVyc1Byb2plY3RzLFxuICBnZW5lcmF0ZU1vZGVsUHJvamVjdCxcbn0gZnJvbSBcIi4vY29kZWdlbi9nZW5lcmF0ZVwiO1xuaW1wb3J0IHsgR2VuZXJhdGVkSmF2YUhhbmRsZXJzUHJvamVjdCB9IGZyb20gXCIuL2NvZGVnZW4vaGFuZGxlcnMvZ2VuZXJhdGVkLWphdmEtaGFuZGxlcnMtcHJvamVjdFwiO1xuaW1wb3J0IHsgR2VuZXJhdGVkUHl0aG9uSGFuZGxlcnNQcm9qZWN0IH0gZnJvbSBcIi4vY29kZWdlbi9oYW5kbGVycy9nZW5lcmF0ZWQtcHl0aG9uLWhhbmRsZXJzLXByb2plY3RcIjtcbmltcG9ydCB7IEdlbmVyYXRlZFR5cGVzY3JpcHRIYW5kbGVyc1Byb2plY3QgfSBmcm9tIFwiLi9jb2RlZ2VuL2hhbmRsZXJzL2dlbmVyYXRlZC10eXBlc2NyaXB0LWhhbmRsZXJzLXByb2plY3RcIjtcbmltcG9ydCB7IEdlbmVyYXRlZEphdmFSdW50aW1lUHJvamVjdCB9IGZyb20gXCIuL2NvZGVnZW4vcnVudGltZS9nZW5lcmF0ZWQtamF2YS1ydW50aW1lLXByb2plY3RcIjtcbmltcG9ydCB7IEdlbmVyYXRlZFB5dGhvblJ1bnRpbWVQcm9qZWN0IH0gZnJvbSBcIi4vY29kZWdlbi9ydW50aW1lL2dlbmVyYXRlZC1weXRob24tcnVudGltZS1wcm9qZWN0XCI7XG5pbXBvcnQgeyBHZW5lcmF0ZWRUeXBlc2NyaXB0UnVudGltZVByb2plY3QgfSBmcm9tIFwiLi9jb2RlZ2VuL3J1bnRpbWUvZ2VuZXJhdGVkLXR5cGVzY3JpcHQtcnVudGltZS1wcm9qZWN0XCI7XG5pbXBvcnQgeyBEb2N1bWVudGF0aW9uRm9ybWF0LCBMYW5ndWFnZSwgTGlicmFyeSB9IGZyb20gXCIuL2xhbmd1YWdlc1wiO1xuaW1wb3J0IHtcbiAgR2VuZXJhdGVkUnVudGltZUNvZGVPcHRpb25zLFxuICBHZW5lcmF0ZWRDb2RlUHJvamVjdHMsXG4gIEdlbmVyYXRlZERvY3VtZW50YXRpb25PcHRpb25zLFxuICBHZW5lcmF0ZWREb2N1bWVudGF0aW9uUHJvamVjdHMsXG4gIEdlbmVyYXRlZExpYnJhcnlPcHRpb25zLFxuICBHZW5lcmF0ZWRMaWJyYXJ5UHJvamVjdHMsXG4gIE1vZGVsTGFuZ3VhZ2UsXG4gIE1vZGVsT3B0aW9ucyxcbiAgR2VuZXJhdGVkSW5mcmFzdHJ1Y3R1cmVDb2RlT3B0aW9ucyxcbiAgR2VuZXJhdGVkSGFuZGxlcnNDb2RlT3B0aW9ucyxcbiAgUHJvamVjdENvbGxlY3Rpb25zLFxuICBNb2RlbFByb2plY3QsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgbW9kZWxsaW5nIHRoZSBBUElcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNb2RlbENvbmZpZ3VyYXRpb24ge1xuICAvKipcbiAgICogVGhlIGxhbmd1YWdlIHRoZSBBUEkgbW9kZWwgaXMgZGVmaW5lZCBpbi5cbiAgICovXG4gIHJlYWRvbmx5IGxhbmd1YWdlOiBNb2RlbExhbmd1YWdlO1xuICAvKipcbiAgICogT3B0aW9ucyBmb3IgdGhlIEFQSSBtb2RlbC5cbiAgICovXG4gIHJlYWRvbmx5IG9wdGlvbnM6IE1vZGVsT3B0aW9ucztcbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciBnZW5lcmF0ZWQgcnVudGltZSBwcm9qZWN0c1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFJ1bnRpbWVDb25maWd1cmF0aW9uIHtcbiAgLyoqXG4gICAqIFRoZSBsYW5ndWFnZXMgdGhhdCBydW50aW1lIHByb2plY3RzIHdpbGwgYmUgZ2VuZXJhdGVkIGluLiBUaGVzZSBwcm9qZWN0cyBjYW4gYmUgdXNlZCB0byBwcm92aWRlIHR5cGUgc2FmZXR5IGZvclxuICAgKiBib3RoIGNsaWVudCBhbmQgc2VydmVyIHByb2plY3RzLlxuICAgKi9cbiAgcmVhZG9ubHkgbGFuZ3VhZ2VzOiBMYW5ndWFnZVtdO1xuICAvKipcbiAgICogT3B0aW9ucyBmb3IgdGhlIGdlbmVyYXRlZCBydW50aW1lcy4gTm90ZSB0aGF0IG9ubHkgb3B0aW9ucyBwcm92aWRlZCBmb3IgdGhlIHNwZWNpZmllZCBsYW5ndWFnZXMgd2lsbCBhcHBseS5cbiAgICovXG4gIHJlYWRvbmx5IG9wdGlvbnM/OiBHZW5lcmF0ZWRSdW50aW1lQ29kZU9wdGlvbnM7XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgZ2VuZXJhdGVkIGluZnJhc3RydWN0dXJlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW5mcmFzdHJ1Y3R1cmVDb25maWd1cmF0aW9uIHtcbiAgLyoqXG4gICAqIFRoZSBsYW5ndWFnZSB0byBnZW5lcmF0ZSB0aGUgdHlwZS1zYWZlIENESyBpbmZyYXN0cnVjdHVyZSBpblxuICAgKi9cbiAgcmVhZG9ubHkgbGFuZ3VhZ2U6IExhbmd1YWdlO1xuICAvKipcbiAgICogT3B0aW9ucyBmb3IgdGhlIGluZnJhc3RydWN0dXJlIHBhY2thZ2UuIE5vdGUgdGhhdCBvbmx5IHRob3NlIHByb3ZpZGVkIGZvciB0aGUgc3BlY2lmaWVkIGxhbmd1YWdlIHdpbGwgYXBwbHkuXG4gICAqL1xuICByZWFkb25seSBvcHRpb25zPzogR2VuZXJhdGVkSW5mcmFzdHJ1Y3R1cmVDb2RlT3B0aW9ucztcbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciBnZW5lcmF0ZWQgbGFtYmRhIGhhbmRsZXJzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSGFuZGxlcnNDb25maWd1cmF0aW9uIHtcbiAgLyoqXG4gICAqIFRoZSBsYW5ndWFnZXMgbGFtYmRhIGhhbmRsZXJzIGFyZSB3cml0dGVuIGluLiBTcGVjaWZ5IG11bHRpcGxlIGxhbmd1YWdlcyBpZiB5b3Ugd2lzaCB0byBpbXBsZW1lbnQgZGlmZmVyZW50IG9wZXJhdGlvbnNcbiAgICogYXMgQVdTIExhbWJkYSBmdW5jdGlvbnMgaW4gZGlmZmVyZW50IGxhbmd1YWdlcy5cbiAgICovXG4gIHJlYWRvbmx5IGxhbmd1YWdlczogTGFuZ3VhZ2VbXTtcbiAgLyoqXG4gICAqIE9wdGlvbnMgZm9yIHRoZSBpbmZyYXN0cnVjdHVyZSBwYWNrYWdlLiBOb3RlIHRoYXQgb25seSB0aG9zZSBwcm92aWRlZCBmb3IgdGhlIHNwZWNpZmllZCBsYW5ndWFnZSB3aWxsIGFwcGx5LlxuICAgKi9cbiAgcmVhZG9ubHkgb3B0aW9ucz86IEdlbmVyYXRlZEhhbmRsZXJzQ29kZU9wdGlvbnM7XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgZ2VuZXJhdGVkIGRvY3VtZW50YXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEb2N1bWVudGF0aW9uQ29uZmlndXJhdGlvbiB7XG4gIC8qKlxuICAgKiBGb3JtYXRzIGZvciBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgZm9ybWF0czogRG9jdW1lbnRhdGlvbkZvcm1hdFtdO1xuICAvKipcbiAgICogT3B0aW9ucyBmb3IgdGhlIGdlbmVyYXRlZCBkb2N1bWVudGF0aW9uIHByb2plY3RzLiBOb3RlIHRoYXQgb25seSB0aG9zZSBwcm92aWRlZCBmb3IgdGhlIHNwZWNpZmllZCBmb3JtYXRzIHdpbGwgYXBwbHlcbiAgICovXG4gIHJlYWRvbmx5IG9wdGlvbnM/OiBHZW5lcmF0ZWREb2N1bWVudGF0aW9uT3B0aW9ucztcbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciBnZW5lcmF0ZWQgbGlicmFyaWVzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTGlicmFyeUNvbmZpZ3VyYXRpb24ge1xuICAvKipcbiAgICogVGhlIGxpYnJhcnkgdG8gZ2VuZXJhdGVcbiAgICovXG4gIHJlYWRvbmx5IGxpYnJhcmllczogTGlicmFyeVtdO1xuICAvKipcbiAgICogT3B0aW9ucyBmb3IgdGhlIGdlbmVyYXRlZCBsaWJyYXJ5IHBhY2thZ2UuIE5vdGUgdGhhdCBvbmx5IG9wdGlvbnMgZm9yIHRoZSBzcGVjaWZpZWQgbGlicmFyaWVzIHdpbGwgYXBwbHlcbiAgICovXG4gIHJlYWRvbmx5IG9wdGlvbnM/OiBHZW5lcmF0ZWRMaWJyYXJ5T3B0aW9ucztcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciB0aGUgVHlwZVNhZmVBcGlQcm9qZWN0XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVHlwZVNhZmVBcGlQcm9qZWN0T3B0aW9ucyBleHRlbmRzIFByb2plY3RPcHRpb25zIHtcbiAgLyoqXG4gICAqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBBUEkgbW9kZWxcbiAgICovXG4gIHJlYWRvbmx5IG1vZGVsOiBNb2RlbENvbmZpZ3VyYXRpb247XG4gIC8qKlxuICAgKiBDb25maWd1cmF0aW9uIGZvciBnZW5lcmF0ZWQgcnVudGltZSBwcm9qZWN0cyAoY29udGFpbmluZyB0eXBlcywgY2xpZW50cyBhbmQgc2VydmVyIGNvZGUpXG4gICAqL1xuICByZWFkb25seSBydW50aW1lPzogUnVudGltZUNvbmZpZ3VyYXRpb247XG4gIC8qKlxuICAgKiBDb25maWd1cmF0aW9uIGZvciBnZW5lcmF0ZWQgaW5mcmFzdHJ1Y3R1cmVcbiAgICovXG4gIHJlYWRvbmx5IGluZnJhc3RydWN0dXJlOiBJbmZyYXN0cnVjdHVyZUNvbmZpZ3VyYXRpb247XG4gIC8qKlxuICAgKiBDb25maWd1cmF0aW9uIGZvciBsYW1iZGEgaGFuZGxlcnMgZm9yIGltcGxlbWVudGluZyB0aGUgQVBJXG4gICAqL1xuICByZWFkb25seSBoYW5kbGVycz86IEhhbmRsZXJzQ29uZmlndXJhdGlvbjtcbiAgLyoqXG4gICAqIENvbmZpZ3VyYXRpb24gZm9yIGdlbmVyYXRlZCBkb2N1bWVudGF0aW9uXG4gICAqL1xuICByZWFkb25seSBkb2N1bWVudGF0aW9uPzogRG9jdW1lbnRhdGlvbkNvbmZpZ3VyYXRpb247XG4gIC8qKlxuICAgKiBDb25maWd1cmF0aW9uIGZvciBnZW5lcmF0ZWQgbGlicmFyaWVzLiBMaWJyYXJpZXMgYXJlIHByb2plY3RzIHdoaWNoIGFyZSBnZW5lcmF0ZWQgZnJvbSB5b3VyIG1vZGVsLCBidXQgYXJlIG5vdFxuICAgKiBmdWxseS1mbGVkZ2VkIHJ1bnRpbWVzLCBmb3IgZXhhbXBsZSByZWFjdCBob29rcyBvciBjbGllbnRzIGluIGxhbmd1YWdlcyB0aGF0IGFyZW4ndCBzdXBwb3J0ZWQgYXMgcnVudGltZXMuXG4gICAqL1xuICByZWFkb25seSBsaWJyYXJ5PzogTGlicmFyeUNvbmZpZ3VyYXRpb247XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNvbW1pdCB0aGUgY29kZSBnZW5lcmF0ZWQgYnkgdGhlIE9wZW5BUEkgR2VuZXJhdG9yLlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgY29tbWl0R2VuZXJhdGVkQ29kZT86IGJvb2xlYW47XG59XG5cbi8qKlxuICogUHJvamVjdCBmb3IgYSB0eXBlLXNhZmUgQVBJLCBkZWZpbmVkIHVzaW5nIFNtaXRoeSBvciBPcGVuQVBJLlxuICpcbiAqIEdlbmVyYXRlcyBhIENESyBjb25zdHJ1Y3QgdG8gZGVwbG95IHlvdXIgQVBJLCBhcyB3ZWxsIGFzIGNsaWVudCBhbmQgc2VydmVyIGNvZGUgdG8gaGVscCBidWlsZCB5b3VyIEFQSSBxdWlja2x5LlxuICpcbiAqIEBwamlkIHR5cGUtc2FmZS1hcGlcbiAqL1xuZXhwb3J0IGNsYXNzIFR5cGVTYWZlQXBpUHJvamVjdCBleHRlbmRzIFByb2plY3Qge1xuICAvKipcbiAgICogUHJvamVjdCBmb3IgdGhlIGFwaSBtb2RlbFxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG1vZGVsOiBNb2RlbFByb2plY3Q7XG4gIC8qKlxuICAgKiBHZW5lcmF0ZWQgcnVudGltZSBwcm9qZWN0cy4gV2hlbiBgcnVudGltZS5sYW5ndWFnZXNgIGluY2x1ZGVzIHRoZSBjb3JyZXNwb25kaW5nIGxhbmd1YWdlLCB0aGUgcHJvamVjdCBjYW4gYmVcbiAgICogYXNzdW1lZCB0byBiZSBkZWZpbmVkLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHJ1bnRpbWU6IEdlbmVyYXRlZENvZGVQcm9qZWN0cztcbiAgLyoqXG4gICAqIEdlbmVyYXRlZCBpbmZyYXN0cnVjdHVyZSBwcm9qZWN0cy4gT25seSB0aGUgcHJvcGVydHkgY29ycmVzcG9uZGluZyB0byBgaW5mcmFzdHJ1Y3R1cmUubGFuZ3VhZ2VgIHdpbGwgYmUgZGVmaW5lZC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBpbmZyYXN0cnVjdHVyZTogR2VuZXJhdGVkQ29kZVByb2plY3RzO1xuICAvKipcbiAgICogTGFtYmRhIGhhbmRsZXJzIHByb2plY3RzLiBPbmx5IHRoZSBwcm9wZXJ0aWVzIGNvcnJlc3BvbmRpbmcgdG8gYGhhbmRsZXJzLmxhbmd1YWdlc2Agd2lsbCBiZSBkZWZpbmVkLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGhhbmRsZXJzOiBHZW5lcmF0ZWRDb2RlUHJvamVjdHM7XG4gIC8qKlxuICAgKiBHZW5lcmF0ZWQgbGlicmFyeSBwcm9qZWN0cy4gT25seSB0aGUgcHJvcGVydGllcyBjb3JyZXNwb25kaW5nIHRvIHNwZWNpZmllZCBgbGlicmFyeS5saWJyYXJpZXNgIHdpbGwgYmUgZGVmaW5lZC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBsaWJyYXJ5OiBHZW5lcmF0ZWRMaWJyYXJ5UHJvamVjdHM7XG4gIC8qKlxuICAgKiBHZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiBwcm9qZWN0cy4gT25seSB0aGUgcHJvcGVydGllcyBjb3JyZXNwb25kaW5nIHRvIHNwZWNpZmllZCBgZG9jdW1lbnRhdGlvbi5mb3JtYXRzYCB3aWxsIGJlIGRlZmluZWQuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZG9jdW1lbnRhdGlvbjogR2VuZXJhdGVkRG9jdW1lbnRhdGlvblByb2plY3RzO1xuICAvKipcbiAgICogQ29sbGVjdGlvbnMgb2YgYWxsIHN1Yi1wcm9qZWN0cyBtYW5hZ2VkIGJ5IHRoaXMgcHJvamVjdFxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFsbDogUHJvamVjdENvbGxlY3Rpb25zO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFR5cGVTYWZlQXBpUHJvamVjdE9wdGlvbnMpIHtcbiAgICBzdXBlcihvcHRpb25zKTtcblxuICAgIGNvbnN0IG54V29ya3NwYWNlID0gdGhpcy5nZXROeFdvcmtzcGFjZShvcHRpb25zKTtcblxuICAgIGNvbnN0IGlzTnhXb3Jrc3BhY2UgPVxuICAgICAgdGhpcy5wYXJlbnQgJiZcbiAgICAgIChQcm9qZWN0VXRpbHMuaXNOYW1lZEluc3RhbmNlT2YodGhpcy5wYXJlbnQsIE1vbm9yZXBvVHNQcm9qZWN0KSB8fFxuICAgICAgICBQcm9qZWN0VXRpbHMuaXNOYW1lZEluc3RhbmNlT2YodGhpcy5wYXJlbnQsIE1vbm9yZXBvSmF2YVByb2plY3QpIHx8XG4gICAgICAgIFByb2plY3RVdGlscy5pc05hbWVkSW5zdGFuY2VPZih0aGlzLnBhcmVudCwgTW9ub3JlcG9QeXRob25Qcm9qZWN0KSk7XG5cbiAgICBjb25zdCBoYW5kbGVyTGFuZ3VhZ2VzID0gWy4uLm5ldyBTZXQob3B0aW9ucy5oYW5kbGVycz8ubGFuZ3VhZ2VzID8/IFtdKV07XG5cbiAgICAvLyBUcnkgdG8gaW5mZXIgbW9ub3JlcG8gZGVmYXVsdCByZWxlYXNlIGJyYW5jaCwgb3RoZXJ3aXNlIGRlZmF1bHQgdG8gbWFpbmxpbmUgdW5sZXNzIG92ZXJyaWRkZW5cbiAgICBjb25zdCBkZWZhdWx0UmVsZWFzZUJyYW5jaCA9XG4gICAgICBueFdvcmtzcGFjZT8uYWZmZWN0ZWQuZGVmYXVsdEJhc2UgPz8gXCJtYWlubGluZVwiO1xuICAgIGNvbnN0IHBhY2thZ2VNYW5hZ2VyID1cbiAgICAgIHRoaXMucGFyZW50ICYmIFByb2plY3RVdGlscy5pc05hbWVkSW5zdGFuY2VPZih0aGlzLnBhcmVudCwgTm9kZVByb2plY3QpXG4gICAgICAgID8gdGhpcy5wYXJlbnQucGFja2FnZS5wYWNrYWdlTWFuYWdlclxuICAgICAgICA6IE5vZGVQYWNrYWdlTWFuYWdlci5QTlBNO1xuXG4gICAgLy8gQVBJIERlZmluaXRpb24gcHJvamVjdCBjb250YWluaW5nIHRoZSBtb2RlbFxuICAgIGNvbnN0IG1vZGVsRGlyID0gXCJtb2RlbFwiO1xuICAgIGNvbnN0IHBhcnNlZFNwZWNGaWxlID0gXCIuYXBpLmpzb25cIjtcblxuICAgIHRoaXMubW9kZWwgPSBnZW5lcmF0ZU1vZGVsUHJvamVjdCh7XG4gICAgICBwYXJlbnQ6IG54V29ya3NwYWNlID8gdGhpcy5wYXJlbnQgOiB0aGlzLFxuICAgICAgb3V0ZGlyOiBueFdvcmtzcGFjZSA/IHBhdGguam9pbihvcHRpb25zLm91dGRpciEsIG1vZGVsRGlyKSA6IG1vZGVsRGlyLFxuICAgICAgbmFtZTogYCR7b3B0aW9ucy5uYW1lfS1tb2RlbGAsXG4gICAgICBtb2RlbExhbmd1YWdlOiBvcHRpb25zLm1vZGVsLmxhbmd1YWdlLFxuICAgICAgbW9kZWxPcHRpb25zOiBvcHRpb25zLm1vZGVsLm9wdGlvbnMsXG4gICAgICBoYW5kbGVyTGFuZ3VhZ2VzLFxuICAgICAgZGVmYXVsdFJlbGVhc2VCcmFuY2g6IG54V29ya3NwYWNlPy5hZmZlY3RlZD8uZGVmYXVsdEJhc2UgPz8gXCJtYWlubGluZVwiLFxuICAgICAgcGFja2FnZU1hbmFnZXIsXG4gICAgICBwYXJzZWRTcGVjRmlsZSxcbiAgICB9KTtcbiAgICBjb25zdCBtb2RlbFByb2plY3QgPSBbXG4gICAgICB0aGlzLm1vZGVsLm9wZW5hcGksXG4gICAgICB0aGlzLm1vZGVsLnNtaXRoeSxcbiAgICAgIHRoaXMubW9kZWwudHlwZVNwZWMsXG4gICAgXS5maWx0ZXIoKG0pID0+IG0pWzBdIGFzIFByb2plY3Q7XG5cbiAgICAvLyBFbnN1cmUgd2UgYWx3YXlzIGdlbmVyYXRlIGEgcnVudGltZSBwcm9qZWN0IGZvciB0aGUgaW5mcmFzdHJ1Y3R1cmUgbGFuZ3VhZ2UsIHJlZ2FyZGxlc3Mgb2Ygd2hhdCB3YXMgc3BlY2lmaWVkIGJ5XG4gICAgLy8gdGhlIHVzZXIuIExpa2V3aXNlIHdlIGdlbmVyYXRlIGEgcnVudGltZSBwcm9qZWN0IGZvciBhbnkgaGFuZGxlciBsYW5ndWFnZXMgc3BlY2lmaWVkXG4gICAgY29uc3QgcnVudGltZUxhbmd1YWdlcyA9IFtcbiAgICAgIC4uLm5ldyBTZXQoW1xuICAgICAgICAuLi4ob3B0aW9ucy5ydW50aW1lPy5sYW5ndWFnZXMgPz8gW10pLFxuICAgICAgICBvcHRpb25zLmluZnJhc3RydWN0dXJlLmxhbmd1YWdlLFxuICAgICAgICAuLi4ob3B0aW9ucy5oYW5kbGVycz8ubGFuZ3VhZ2VzID8/IFtdKSxcbiAgICAgIF0pLFxuICAgIF07XG5cbiAgICBjb25zdCBnZW5lcmF0ZWREaXIgPSBcImdlbmVyYXRlZFwiO1xuICAgIGNvbnN0IHJ1bnRpbWVEaXIgPSBwYXRoLmpvaW4oZ2VuZXJhdGVkRGlyLCBcInJ1bnRpbWVcIik7XG4gICAgY29uc3QgcnVudGltZURpclJlbGF0aXZlVG9QYXJlbnQgPSBueFdvcmtzcGFjZVxuICAgICAgPyBwYXRoLmpvaW4ob3B0aW9ucy5vdXRkaXIhLCBydW50aW1lRGlyKVxuICAgICAgOiBydW50aW1lRGlyO1xuXG4gICAgLy8gUGF0aCBmcm9tIGEgZ2VuZXJhdGVkIHBhY2thZ2UgZGlyZWN0b3J5IChlZyBhcGkvZ2VuZXJhdGVkL3J1bnRpbWUvdHlwZXNjcmlwdCkgdG8gdGhlIG1vZGVsIGRpciAoaWUgYXBpL21vZGVsKVxuICAgIGNvbnN0IHJlbGF0aXZlUGF0aFRvTW9kZWxEaXJGcm9tR2VuZXJhdGVkUGFja2FnZURpciA9IHBhdGgucmVsYXRpdmUoXG4gICAgICBwYXRoLmpvaW4odGhpcy5vdXRkaXIsIHJ1bnRpbWVEaXIsIFwibGFuZ3VhZ2VcIiksXG4gICAgICBwYXRoLmpvaW4odGhpcy5vdXRkaXIsIG1vZGVsRGlyKVxuICAgICk7XG4gICAgY29uc3QgcGFyc2VkU3BlY1JlbGF0aXZlVG9HZW5lcmF0ZWRQYWNrYWdlRGlyID0gcGF0aC5qb2luKFxuICAgICAgcmVsYXRpdmVQYXRoVG9Nb2RlbERpckZyb21HZW5lcmF0ZWRQYWNrYWdlRGlyLFxuICAgICAgdGhpcy5tb2RlbC5wYXJzZWRTcGVjRmlsZVxuICAgICk7XG5cbiAgICAvLyBEZWNsYXJlIHRoZSBnZW5lcmF0ZWQgcnVudGltZSBwcm9qZWN0c1xuICAgIGNvbnN0IGdlbmVyYXRlZFJ1bnRpbWVQcm9qZWN0cyA9IGdlbmVyYXRlUnVudGltZVByb2plY3RzKHJ1bnRpbWVMYW5ndWFnZXMsIHtcbiAgICAgIHBhcmVudDogbnhXb3Jrc3BhY2UgPyB0aGlzLnBhcmVudCEgOiB0aGlzLFxuICAgICAgcGFyZW50UGFja2FnZU5hbWU6IHRoaXMubmFtZSxcbiAgICAgIGdlbmVyYXRlZENvZGVEaXI6IHJ1bnRpbWVEaXJSZWxhdGl2ZVRvUGFyZW50LFxuICAgICAgaXNXaXRoaW5Nb25vcmVwbzogaXNOeFdvcmtzcGFjZSxcbiAgICAgIC8vIFNwZWMgcGF0aCByZWxhdGl2ZSB0byBlYWNoIGdlbmVyYXRlZCBydW50aW1lIGRpclxuICAgICAgcGFyc2VkU3BlY1BhdGg6IHBhcnNlZFNwZWNSZWxhdGl2ZVRvR2VuZXJhdGVkUGFja2FnZURpcixcbiAgICAgIHR5cGVzY3JpcHRPcHRpb25zOiB7XG4gICAgICAgIGRlZmF1bHRSZWxlYXNlQnJhbmNoLFxuICAgICAgICBwYWNrYWdlTWFuYWdlcixcbiAgICAgICAgY29tbWl0R2VuZXJhdGVkQ29kZTpcbiAgICAgICAgICBvcHRpb25zLnJ1bnRpbWU/Lm9wdGlvbnM/LnR5cGVzY3JpcHQ/LmNvbW1pdEdlbmVyYXRlZENvZGUgPz9cbiAgICAgICAgICBvcHRpb25zLmNvbW1pdEdlbmVyYXRlZENvZGUgPz9cbiAgICAgICAgICBmYWxzZSxcbiAgICAgICAgLi4ub3B0aW9ucy5ydW50aW1lPy5vcHRpb25zPy50eXBlc2NyaXB0LFxuICAgICAgfSxcbiAgICAgIHB5dGhvbk9wdGlvbnM6IHtcbiAgICAgICAgYXV0aG9yTmFtZTogXCJBUEogQ29wZVwiLFxuICAgICAgICBhdXRob3JFbWFpbDogXCJhcGotY29wZUBhbWF6b24uY29tXCIsXG4gICAgICAgIHZlcnNpb246IFwiMC4wLjBcIixcbiAgICAgICAgY29tbWl0R2VuZXJhdGVkQ29kZTpcbiAgICAgICAgICBvcHRpb25zLnJ1bnRpbWU/Lm9wdGlvbnM/LnB5dGhvbj8uY29tbWl0R2VuZXJhdGVkQ29kZSA/P1xuICAgICAgICAgIG9wdGlvbnMuY29tbWl0R2VuZXJhdGVkQ29kZSA/P1xuICAgICAgICAgIGZhbHNlLFxuICAgICAgICAuLi5vcHRpb25zLnJ1bnRpbWU/Lm9wdGlvbnM/LnB5dGhvbixcbiAgICAgIH0sXG4gICAgICBqYXZhT3B0aW9uczoge1xuICAgICAgICB2ZXJzaW9uOiBcIjAuMC4wXCIsXG4gICAgICAgIGNvbW1pdEdlbmVyYXRlZENvZGU6XG4gICAgICAgICAgb3B0aW9ucy5ydW50aW1lPy5vcHRpb25zPy5qYXZhPy5jb21taXRHZW5lcmF0ZWRDb2RlID8/XG4gICAgICAgICAgb3B0aW9ucy5jb21taXRHZW5lcmF0ZWRDb2RlID8/XG4gICAgICAgICAgZmFsc2UsXG4gICAgICAgIC4uLm9wdGlvbnMucnVudGltZT8ub3B0aW9ucz8uamF2YSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjb25zdCBkb2N1bWVudGF0aW9uRm9ybWF0cyA9IFtcbiAgICAgIC4uLm5ldyBTZXQob3B0aW9ucy5kb2N1bWVudGF0aW9uPy5mb3JtYXRzID8/IFtdKSxcbiAgICBdO1xuXG4gICAgY29uc3QgZG9jc0RpciA9IHBhdGguam9pbihnZW5lcmF0ZWREaXIsIFwiZG9jdW1lbnRhdGlvblwiKTtcbiAgICBjb25zdCBkb2NzRGlyUmVsYXRpdmVUb1BhcmVudCA9IG54V29ya3NwYWNlXG4gICAgICA/IHBhdGguam9pbihvcHRpb25zLm91dGRpciEsIGRvY3NEaXIpXG4gICAgICA6IGRvY3NEaXI7XG5cbiAgICBjb25zdCBnZW5lcmF0ZWREb2NzID0gZ2VuZXJhdGVEb2NzUHJvamVjdHMoZG9jdW1lbnRhdGlvbkZvcm1hdHMsIHtcbiAgICAgIHBhcmVudDogbnhXb3Jrc3BhY2UgPyB0aGlzLnBhcmVudCEgOiB0aGlzLFxuICAgICAgcGFyZW50UGFja2FnZU5hbWU6IHRoaXMubmFtZSxcbiAgICAgIGdlbmVyYXRlZERvY3NEaXI6IGRvY3NEaXJSZWxhdGl2ZVRvUGFyZW50LFxuICAgICAgLy8gU3BlYyBwYX