UNPKG

projen

Version:

CDK for software projects

367 lines • 56.1 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.JsiiProject = exports.Stability = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const consts_1 = require("./consts"); const jsii_docgen_1 = require("./jsii-docgen"); const consts_2 = require("../build/private/consts"); const workflow_steps_1 = require("../github/workflow-steps"); const workflows_model_1 = require("../github/workflows-model"); const javascript_1 = require("../javascript"); const util_1 = require("../javascript/util"); const runner_options_1 = require("../runner-options"); const typescript_1 = require("../typescript"); const util_2 = require("../util"); const EMAIL_REGEX = /^[^\s@]+@[^\s@]+$/; const URL_REGEX = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/; const REPO_TEMP_DIRECTORY = ".repo"; const BUILD_ARTIFACT_OLD_DIR = "dist.old"; var Stability; (function (Stability) { Stability["EXPERIMENTAL"] = "experimental"; Stability["STABLE"] = "stable"; Stability["DEPRECATED"] = "deprecated"; })(Stability || (exports.Stability = Stability = {})); /** * Multi-language jsii library project * * @pjid jsii */ class JsiiProject extends typescript_1.TypeScriptProject { constructor(options) { const { authorEmail, authorUrl } = parseAuthorAddress(options); const jsiiVersion = options.jsiiVersion ?? "~5.9.0"; const defaultOptions = { repository: options.repositoryUrl, authorName: options.author, authorEmail, authorUrl, }; const forcedOptions = { releaseToNpm: false, // we have a jsii release workflow disableTsconfig: true, // jsii generates its own tsconfig.json docgen: false, // we use jsii-docgen here so disable typescript docgen }; const mergedOptions = (0, util_2.deepMerge)([ defaultOptions, options, forcedOptions, ]); super(mergedOptions); const srcdir = this.srcdir; const libdir = this.libdir; this.addFields({ types: `${libdir}/index.d.ts` }); const compressAssembly = options.compressAssembly ?? false; // this is an unhelpful warning const jsiiFlags = ["--silence-warnings=reserved-word"]; if (compressAssembly) { jsiiFlags.push("--compress-assembly"); } const compatIgnore = options.compatIgnore ?? ".compatignore"; this.addFields({ stability: options.stability ?? Stability.STABLE }); if (options.stability === Stability.DEPRECATED) { this.addFields({ deprecated: true }); } const compatTask = this.addTask("compat", { description: "Perform API compatibility check against latest version", exec: `jsii-diff npm:$(node -p "require(\'./package.json\').name") -k --ignore-file ${compatIgnore} || (echo "\nUNEXPECTED BREAKING CHANGES: add keys such as \'removed:constructs.Node.of\' to ${compatIgnore} to skip.\n" && exit 1)`, }); const compat = options.compat ?? false; if (compat) { this.compileTask.spawn(compatTask); } this.compileTask.reset(["jsii", ...jsiiFlags].join(" ")); this.watchTask.reset(["jsii", "-w", ...jsiiFlags].join(" ")); // Create a new package:all task, it will be filled with language targets later this.packageAllTask = this.addTask("package-all", { description: "Packages artifacts for all target languages", }); // in jsii we consider the entire repo (post build) as the build artifact // which is then used to create the language bindings in separate jobs. // we achieve this by doing a checkout and overwrite with the files from the js package. this.packageJsTask = this.addPackagingTask("js"); // When running inside CI we initially only package js. Other targets are packaged in separate jobs. // Outside of CI (i.e locally) we simply package all targets. this.packageTask.reset(); this.packageTask.spawn(this.packageJsTask, { // Only run in CI condition: `node -e "if (!process.env.CI) process.exit(1)"`, }); this.packageTask.spawn(this.packageAllTask, { // Don't run in CI condition: `node -e "if (process.env.CI) process.exit(1)"`, }); const targets = {}; const jsii = { outdir: this.artifactsDirectory, targets, tsc: { outDir: libdir, rootDir: srcdir, }, }; if (options.excludeTypescript) { jsii.excludeTypescript = options.excludeTypescript; } this.addFields({ jsii }); const extraJobOptions = { ...this.getJobRunsOnConfig(options), ...(options.workflowContainerImage ? { container: { image: options.workflowContainerImage } } : {}), }; if (options.releaseToNpm != false) { const npmjs = { registry: this.package.npmRegistry, npmTokenSecret: this.package.npmTokenSecret, npmProvenance: this.package.npmProvenance, codeArtifactOptions: options.codeArtifactOptions, trustedPublishing: options.npmTrustedPublishing ?? false, }; this.addTargetToBuild("js", this.packageJsTask, extraJobOptions); this.addTargetToRelease("js", this.packageJsTask, npmjs); } // we cannot call an option `java` because the java code generated by jsii // does not compile due to a conflict between this option name and the `java` // package (e.g. when `java.util.Objects` is referenced). if ("java" in options) { throw new Error('the "java" option is now called "publishToMaven"'); } const maven = options.publishToMaven; if (maven) { targets.java = { package: maven.javaPackage, maven: { groupId: maven.mavenGroupId, artifactId: maven.mavenArtifactId, }, }; const task = this.addPackagingTask("java"); this.addTargetToBuild("java", task, extraJobOptions); this.addTargetToRelease("java", task, maven); } const pypi = options.publishToPypi ?? options.python; if (pypi) { targets.python = { distName: pypi.distName, module: pypi.module, }; const task = this.addPackagingTask("python"); this.addTargetToBuild("python", task, extraJobOptions); this.addTargetToRelease("python", task, pypi); } const nuget = options.publishToNuget ?? options.dotnet; if (nuget) { targets.dotnet = { namespace: nuget.dotNetNamespace, packageId: nuget.packageId, iconUrl: nuget.iconUrl, }; const task = this.addPackagingTask("dotnet"); this.addTargetToBuild("dotnet", task, extraJobOptions); this.addTargetToRelease("dotnet", task, nuget); } const golang = options.publishToGo; if (golang) { targets.go = { moduleName: golang.moduleName, packageName: golang.packageName, versionSuffix: golang.versionSuffix, }; const task = this.addPackagingTask("go"); this.addTargetToBuild("go", task, extraJobOptions); this.addTargetToRelease("go", task, golang); } // If jsiiVersion is "*", don't specify anything so the user can manage. // Otherwise, use `jsiiVersion` const jsiiSuffix = jsiiVersion === "*" ? "" : `@${jsiiVersion}`; this.addDevDeps(`jsii${jsiiSuffix}`, `jsii-rosetta${jsiiSuffix}`, "jsii-diff", "jsii-pacmak"); this.gitignore.exclude(".jsii", "tsconfig.json"); this.npmignore?.include(".jsii"); if (options.docgen ?? true) { // If jsiiVersion is "*", don't specify anything so the user can manage. // Otherwise use a version that is compatible with all supported jsii releases. const docgenVersion = options.jsiiVersion === "*" ? "*" : "^10.5.0"; new jsii_docgen_1.JsiiDocgen(this, { version: docgenVersion, filePath: options.docgenFilePath, }); } // jsii updates .npmignore, so we make it writable if (this.npmignore) { this.npmignore.readonly = false; } } /** * Adds a target language to the release workflow. * @param language * @returns */ addTargetToRelease(language, packTask, target) { if (!this.release) { return; } const pacmak = this.pacmakForLanguage(language, packTask); const prePublishSteps = [ ...pacmak.bootstrapSteps, workflow_steps_1.WorkflowSteps.checkout({ with: { path: REPO_TEMP_DIRECTORY, ...(this.github?.downloadLfs ? { lfs: true } : {}), }, }), ...pacmak.packagingSteps, ]; const commonPublishOptions = { publishTools: pacmak.publishTools, prePublishSteps, }; const handler = publishTo[language]; this.release?.publisher[handler]({ ...commonPublishOptions, ...target, }); } /** * Adds a target language to the build workflow * @param language * @returns */ addTargetToBuild(language, packTask, extraJobOptions) { if (!this.buildWorkflow) { return; } const pacmak = this.pacmakForLanguage(language, packTask); this.buildWorkflow.addPostBuildJob(`package-${language}`, { ...(0, runner_options_1.filteredRunsOnOptions)(extraJobOptions.runsOn, extraJobOptions.runsOnGroup), permissions: { contents: workflows_model_1.JobPermission.READ, }, tools: { node: { version: this.nodeVersion ?? "lts/*" }, ...pacmak.publishTools, }, steps: [ ...pacmak.bootstrapSteps, workflow_steps_1.WorkflowSteps.checkout({ with: { path: REPO_TEMP_DIRECTORY, ref: consts_2.PULL_REQUEST_REF, repository: consts_2.PULL_REQUEST_REPOSITORY, ...(this.github?.downloadLfs ? { lfs: true } : {}), }, }), ...pacmak.packagingSteps, ], ...extraJobOptions, }); } addPackagingTask(language) { const packageTargetTask = this.tasks.addTask(`package:${language}`, { description: `Create ${language} language bindings`, }); const commandParts = ["jsii-pacmak", "-v"]; if (this.package.packageManager === javascript_1.NodePackageManager.PNPM) { commandParts.push('--pack-command "pnpm pack"'); } commandParts.push(`--target ${language}`); packageTargetTask.exec(commandParts.join(" ")); this.packageAllTask.spawn(packageTargetTask); return packageTargetTask; } pacmakForLanguage(target, packTask) { const bootstrapSteps = []; const packagingSteps = []; // Generic bootstrapping for all target languages bootstrapSteps.push(...this.workflowBootstrapSteps); if (this.package.packageManager === javascript_1.NodePackageManager.PNPM) { bootstrapSteps.push({ name: "Setup pnpm", uses: "pnpm/action-setup@v5", with: { version: this.package.pnpmVersion }, }); } else if (this.package.packageManager === javascript_1.NodePackageManager.BUN) { bootstrapSteps.push({ name: "Setup bun", uses: "oven-sh/setup-bun@v2", with: { "bun-version": this.package.bunVersion }, }); } else if ((0, util_1.isYarnBerry)(this.package.packageManager)) { bootstrapSteps.push({ name: "Enable corepack", run: "corepack enable", }); } // Installation steps before packaging, but after checkout packagingSteps.push({ name: "Install Dependencies", run: `cd ${REPO_TEMP_DIRECTORY} && ${this.package.installCommand}`, }, { name: "Extract build artifact", run: `tar --strip-components=1 -xzvf ${this.artifactsDirectory}/js/*.tgz -C ${REPO_TEMP_DIRECTORY}`, }, { name: `Move build artifact out of the way`, run: `mv ${this.artifactsDirectory} ${BUILD_ARTIFACT_OLD_DIR}`, }, { name: `Create ${target} artifact`, run: `cd ${REPO_TEMP_DIRECTORY} && ${this.runTaskCommand(packTask)}`, }, { name: `Collect ${target} artifact`, run: `mv ${REPO_TEMP_DIRECTORY}/${this.artifactsDirectory} ${this.artifactsDirectory}`, }); return { publishTools: consts_1.JSII_TOOLCHAIN[target], bootstrapSteps, packagingSteps, }; } /** * Generates the runs-on config for Jobs. * Throws error if 'runsOn' and 'runsOnGroup' are both set. * * @param options - 'runsOn' or 'runsOnGroup'. */ getJobRunsOnConfig(options) { return options.workflowRunsOnGroup ? { runsOnGroup: options.workflowRunsOnGroup } : options.workflowRunsOn ? { runsOn: options.workflowRunsOn } : {}; } } exports.JsiiProject = JsiiProject; _a = JSII_RTTI_SYMBOL_1; JsiiProject[_a] = { fqn: "projen.cdk.JsiiProject", version: "0.99.51" }; const publishTo = { js: "publishToNpm", java: "publishToMaven", python: "publishToPyPi", dotnet: "publishToNuget", go: "publishToGo", }; function parseAuthorAddress(options) { let authorEmail = options.authorEmail; let authorUrl = options.authorUrl; if (options.authorAddress) { if (options.authorEmail && options.authorEmail !== options.authorAddress) { throw new Error("authorEmail is deprecated and cannot be used in conjunction with authorAddress"); } if (options.authorUrl && options.authorUrl !== options.authorAddress) { throw new Error("authorUrl is deprecated and cannot be used in conjunction with authorAddress."); } if (EMAIL_REGEX.test(options.authorAddress)) { authorEmail = options.authorAddress; } else if (URL_REGEX.test(options.authorAddress)) { authorUrl = options.authorAddress; } else { throw new Error(`authorAddress must be either an email address or a URL: ${options.authorAddress}`); } } return { authorEmail, authorUrl }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNpaS1wcm9qZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Nkay9qc2lpLXByb2plY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFFQSxxQ0FBMEM7QUFDMUMsK0NBQTJDO0FBQzNDLG9EQUdpQztBQUNqQyw2REFBeUQ7QUFFekQsK0RBQTBEO0FBQzFELDhDQUFtRDtBQUNuRCw2Q0FBaUQ7QUFVakQsc0RBQTBEO0FBRTFELDhDQUFrRDtBQUNsRCxrQ0FBb0M7QUFFcEMsTUFBTSxXQUFXLEdBQUcsbUJBQW1CLENBQUM7QUFDeEMsTUFBTSxTQUFTLEdBQ2Isc0xBQXNMLENBQUM7QUFFekwsTUFBTSxtQkFBbUIsR0FBRyxPQUFPLENBQUM7QUFDcEMsTUFBTSxzQkFBc0IsR0FBRyxVQUFVLENBQUM7QUFrSDFDLElBQVksU0FJWDtBQUpELFdBQVksU0FBUztJQUNuQiwwQ0FBNkIsQ0FBQTtJQUM3Qiw4QkFBaUIsQ0FBQTtJQUNqQixzQ0FBeUIsQ0FBQTtBQUMzQixDQUFDLEVBSlcsU0FBUyx5QkFBVCxTQUFTLFFBSXBCO0FBbUREOzs7O0dBSUc7QUFDSCxNQUFhLFdBQVksU0FBUSw4QkFBaUI7SUFJaEQsWUFBWSxPQUEyQjtRQUNyQyxNQUFNLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxHQUFHLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRS9ELE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLElBQUksUUFBUSxDQUFDO1FBRXBELE1BQU0sY0FBYyxHQUFzQztZQUN4RCxVQUFVLEVBQUUsT0FBTyxDQUFDLGFBQWE7WUFDakMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1lBQzFCLFdBQVc7WUFDWCxTQUFTO1NBQ1YsQ0FBQztRQUVGLE1BQU0sYUFBYSxHQUFHO1lBQ3BCLFlBQVksRUFBRSxLQUFLLEVBQUUsa0NBQWtDO1lBQ3ZELGVBQWUsRUFBRSxJQUFJLEVBQUUsdUNBQXVDO1lBQzlELE1BQU0sRUFBRSxLQUFLLEVBQUUsdURBQXVEO1NBQ3ZFLENBQUM7UUFFRixNQUFNLGFBQWEsR0FBRyxJQUFBLGdCQUFTLEVBQUM7WUFDOUIsY0FBYztZQUNkLE9BQU87WUFDUCxhQUFhO1NBQ2QsQ0FBNkIsQ0FBQztRQUUvQixLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFckIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUMzQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBRTNCLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLGFBQWEsRUFBRSxDQUFDLENBQUM7UUFFbEQsTUFBTSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsZ0JBQWdCLElBQUksS0FBSyxDQUFDO1FBRTNELCtCQUErQjtRQUMvQixNQUFNLFNBQVMsR0FBRyxDQUFDLGtDQUFrQyxDQUFDLENBQUM7UUFDdkQsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3JCLFNBQVMsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUN4QyxDQUFDO1FBRUQsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVksSUFBSSxlQUFlLENBQUM7UUFFN0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUyxJQUFJLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBRXJFLElBQUksT0FBTyxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDL0MsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZDLENBQUM7UUFFRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRTtZQUN4QyxXQUFXLEVBQUUsd0RBQXdEO1lBQ3JFLElBQUksRUFBRSxnRkFBZ0YsWUFBWSxnR0FBZ0csWUFBWSx5QkFBeUI7U0FDeE8sQ0FBQyxDQUFDO1FBRUgsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUM7UUFDdkMsSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUNYLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3JDLENBQUM7UUFFRCxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sRUFBRSxHQUFHLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3pELElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBRTdELCtFQUErRTtRQUMvRSxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFO1lBQ2hELFdBQVcsRUFBRSw2Q0FBNkM7U0FDM0QsQ0FBQyxDQUFDO1FBRUgseUVBQXlFO1FBQ3pFLHVFQUF1RTtRQUN2RSx3RkFBd0Y7UUFDeEYsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFakQsb0dBQW9HO1FBQ3BHLDZEQUE2RDtRQUM3RCxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDekMsaUJBQWlCO1lBQ2pCLFNBQVMsRUFBRSxnREFBZ0Q7U0FDNUQsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUMxQyxrQkFBa0I7WUFDbEIsU0FBUyxFQUFFLCtDQUErQztTQUMzRCxDQUFDLENBQUM7UUFFSCxNQUFNLE9BQU8sR0FBd0IsRUFBRSxDQUFDO1FBRXhDLE1BQU0sSUFBSSxHQUFRO1lBQ2hCLE1BQU0sRUFBRSxJQUFJLENBQUMsa0JBQWtCO1lBQy9CLE9BQU87WUFDUCxHQUFHLEVBQUU7Z0JBQ0gsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsT0FBTyxFQUFFLE1BQU07YUFDaEI7U0FDRixDQUFDO1FBRUYsSUFBSSxPQUFPLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUM5QixJQUFJLENBQUMsaUJBQWlCLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDO1FBQ3JELENBQUM7UUFFRCxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUV6QixNQUFNLGVBQWUsR0FBaUI7WUFDcEMsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDO1lBQ25DLEdBQUcsQ0FBQyxPQUFPLENBQUMsc0JBQXNCO2dCQUNoQyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUUsRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLHNCQUFzQixFQUFFLEVBQUU7Z0JBQzFELENBQUMsQ0FBQyxFQUFFLENBQUM7U0FDUixDQUFDO1FBRUYsSUFBSSxPQUFPLENBQUMsWUFBWSxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ2xDLE1BQU0sS0FBSyxHQUFzQjtnQkFDL0IsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVztnQkFDbEMsY0FBYyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYztnQkFDM0MsYUFBYSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYTtnQkFDekMsbUJBQW1CLEVBQUUsT0FBTyxDQUFDLG1CQUFtQjtnQkFDaEQsaUJBQWlCLEVBQUUsT0FBTyxDQUFDLG9CQUFvQixJQUFJLEtBQUs7YUFDekQsQ0FBQztZQUNGLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxlQUFlLENBQUMsQ0FBQztZQUNqRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDM0QsQ0FBQztRQUVELDBFQUEwRTtRQUMxRSw2RUFBNkU7UUFDN0UseURBQXlEO1FBQ3pELElBQUksTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ3RCLE1BQU0sSUFBSSxLQUFLLENBQUMsa0RBQWtELENBQUMsQ0FBQztRQUN0RSxDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQztRQUNyQyxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1YsT0FBTyxDQUFDLElBQUksR0FBRztnQkFDYixPQUFPLEVBQUUsS0FBSyxDQUFDLFdBQVc7Z0JBQzFCLEtBQUssRUFBRTtvQkFDTCxPQUFPLEVBQUUsS0FBSyxDQUFDLFlBQVk7b0JBQzNCLFVBQVUsRUFBRSxLQUFLLENBQUMsZUFBZTtpQkFDbEM7YUFDRixDQUFDO1lBRUYsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzNDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1lBQ3JELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQy9DLENBQUM7UUFFRCxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsYUFBYSxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDckQsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNULE9BQU8sQ0FBQyxNQUFNLEdBQUc7Z0JBQ2YsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO2dCQUN2QixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07YUFDcEIsQ0FBQztZQUVGLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM3QyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxlQUFlLENBQUMsQ0FBQztZQUN2RCxJQUFJLENBQUMsa0JBQWtCLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNoRCxDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLGNBQWMsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDO1FBQ3ZELElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixPQUFPLENBQUMsTUFBTSxHQUFHO2dCQUNmLFNBQVMsRUFBRSxLQUFLLENBQUMsZUFBZTtnQkFDaEMsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO2dCQUMxQixPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87YUFDdkIsQ0FBQztZQUVGLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM3QyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxlQUFlLENBQUMsQ0FBQztZQUN2RCxJQUFJLENBQUMsa0JBQWtCLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBRUQsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQztRQUNuQyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEVBQUUsR0FBRztnQkFDWCxVQUFVLEVBQUUsTUFBTSxDQUFDLFVBQVU7Z0JBQzdCLFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVztnQkFDL0IsYUFBYSxFQUFFLE1BQU0sQ0FBQyxhQUFhO2FBQ3BDLENBQUM7WUFFRixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDekMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsZUFBZSxDQUFDLENBQUM7WUFDbkQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDOUMsQ0FBQztRQUVELHdFQUF3RTtRQUN4RSwrQkFBK0I7UUFDL0IsTUFBTSxVQUFVLEdBQUcsV0FBVyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLFdBQVcsRUFBRSxDQUFDO1FBQ2hFLElBQUksQ0FBQyxVQUFVLENBQ2IsT0FBTyxVQUFVLEVBQUUsRUFDbkIsZUFBZSxVQUFVLEVBQUUsRUFDM0IsV0FBVyxFQUNYLGFBQWEsQ0FDZCxDQUFDO1FBRUYsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLGVBQWUsQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRWpDLElBQUksT0FBTyxDQUFDLE1BQU0sSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUMzQix3RUFBd0U7WUFDeEUsK0VBQStFO1lBQy9FLE1BQU0sYUFBYSxHQUFHLE9BQU8sQ0FBQyxXQUFXLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUNwRSxJQUFJLHdCQUFVLENBQUMsSUFBSSxFQUFFO2dCQUNuQixPQUFPLEVBQUUsYUFBYTtnQkFDdEIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxjQUFjO2FBQ2pDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCxrREFBa0Q7UUFDbEQsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ2xDLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLGtCQUFrQixDQUN4QixRQUEwQixFQUMxQixRQUFjLEVBQ2QsTUFLcUI7UUFFckIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNsQixPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDMUQsTUFBTSxlQUFlLEdBQUc7WUFDdEIsR0FBRyxNQUFNLENBQUMsY0FBYztZQUN4Qiw4QkFBYSxDQUFDLFFBQVEsQ0FBQztnQkFDckIsSUFBSSxFQUFFO29CQUNKLElBQUksRUFBRSxtQkFBbUI7b0JBQ3pCLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztpQkFDbkQ7YUFDRixDQUFDO1lBQ0YsR0FBRyxNQUFNLENBQUMsY0FBYztTQUN6QixDQUFDO1FBQ0YsTUFBTSxvQkFBb0IsR0FBeUI7WUFDakQsWUFBWSxFQUFFLE1BQU0sQ0FBQyxZQUFZO1lBQ2pDLGVBQWU7U0FDaEIsQ0FBQztRQUVGLE1BQU0sT0FBTyxHQUFjLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMvQyxJQUFJLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMvQixHQUFHLG9CQUFvQjtZQUN2QixHQUFHLE1BQU07U0FDVixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLGdCQUFnQixDQUN0QixRQUEwQixFQUMxQixRQUFjLEVBQ2QsZUFBNkI7UUFFN0IsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN4QixPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFFMUQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsV0FBVyxRQUFRLEVBQUUsRUFBRTtZQUN4RCxHQUFHLElBQUEsc0NBQXFCLEVBQ3RCLGVBQWUsQ0FBQyxNQUFNLEVBQ3RCLGVBQWUsQ0FBQyxXQUFXLENBQzVCO1lBQ0QsV0FBVyxFQUFFO2dCQUNYLFFBQVEsRUFBRSwrQkFBYSxDQUFDLElBQUk7YUFDN0I7WUFDRCxLQUFLLEVBQUU7Z0JBQ0wsSUFBSSxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxXQUFXLElBQUksT0FBTyxFQUFFO2dCQUM5QyxHQUFHLE1BQU0sQ0FBQyxZQUFZO2FBQ3ZCO1lBQ0QsS0FBSyxFQUFFO2dCQUNMLEdBQUcsTUFBTSxDQUFDLGNBQWM7Z0JBQ3hCLDhCQUFhLENBQUMsUUFBUSxDQUFDO29CQUNyQixJQUFJLEVBQUU7d0JBQ0osSUFBSSxFQUFFLG1CQUFtQjt3QkFDekIsR0FBRyxFQUFFLHlCQUFnQjt3QkFDckIsVUFBVSxFQUFFLGdDQUF1Qjt3QkFDbkMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO3FCQUNuRDtpQkFDRixDQUFDO2dCQUNGLEdBQUcsTUFBTSxDQUFDLGNBQWM7YUFDekI7WUFDRCxHQUFHLGVBQWU7U0FDbkIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLGdCQUFnQixDQUFDLFFBQTBCO1FBQ2pELE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxRQUFRLEVBQUUsRUFBRTtZQUNsRSxXQUFXLEVBQUUsVUFBVSxRQUFRLG9CQUFvQjtTQUNwRCxDQUFDLENBQUM7UUFDSCxNQUFNLFlBQVksR0FBRyxDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUUzQyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxLQUFLLCtCQUFrQixDQUFDLElBQUksRUFBRSxDQUFDO1lBQzVELFlBQVksQ0FBQyxJQUFJLENBQUMsNEJBQTRCLENBQUMsQ0FBQztRQUNsRCxDQUFDO1FBRUQsWUFBWSxDQUFDLElBQUksQ0FBQyxZQUFZLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFFMUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUUvQyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQzdDLE9BQU8saUJBQWlCLENBQUM7SUFDM0IsQ0FBQztJQUVPLGlCQUFpQixDQUN2QixNQUF3QixFQUN4QixRQUFjO1FBTWQsTUFBTSxjQUFjLEdBQWdCLEVBQUUsQ0FBQztRQUN2QyxNQUFNLGNBQWMsR0FBZ0IsRUFBRSxDQUFDO1FBRXZDLGlEQUFpRDtRQUNqRCxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDcEQsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsS0FBSywrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUM1RCxjQUFjLENBQUMsSUFBSSxDQUFDO2dCQUNsQixJQUFJLEVBQUUsWUFBWTtnQkFDbEIsSUFBSSxFQUFFLHNCQUFzQjtnQkFDNUIsSUFBSSxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFO2FBQzVDLENBQUMsQ0FBQztRQUNMLENBQUM7YUFBTSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxLQUFLLCtCQUFrQixDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ2xFLGNBQWMsQ0FBQyxJQUFJLENBQUM7Z0JBQ2xCLElBQUksRUFBRSxXQUFXO2dCQUNqQixJQUFJLEVBQUUsc0JBQXNCO2dCQUM1QixJQUFJLEVBQUUsRUFBRSxhQUFhLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUU7YUFDakQsQ0FBQyxDQUFDO1FBQ0wsQ0FBQzthQUFNLElBQUksSUFBQSxrQkFBVyxFQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztZQUNwRCxjQUFjLENBQUMsSUFBSSxDQUFDO2dCQUNsQixJQUFJLEVBQUUsaUJBQWlCO2dCQUN2QixHQUFHLEVBQUUsaUJBQWlCO2FBQ3ZCLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCwwREFBMEQ7UUFDMUQsY0FBYyxDQUFDLElBQUksQ0FDakI7WUFDRSxJQUFJLEVBQUUsc0JBQXNCO1lBQzVCLEdBQUcsRUFBRSxNQUFNLG1CQUFtQixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFO1NBQ25FLEVBQ0Q7WUFDRSxJQUFJLEVBQUUsd0JBQXdCO1lBQzlCLEdBQUcsRUFBRSxrQ0FBa0MsSUFBSSxDQUFDLGtCQUFrQixnQkFBZ0IsbUJBQW1CLEVBQUU7U0FDcEcsRUFDRDtZQUNFLElBQUksRUFBRSxvQ0FBb0M7WUFDMUMsR0FBRyxFQUFFLE1BQU0sSUFBSSxDQUFDLGtCQUFrQixJQUFJLHNCQUFzQixFQUFFO1NBQy9ELEVBQ0Q7WUFDRSxJQUFJLEVBQUUsVUFBVSxNQUFNLFdBQVc7WUFDakMsR0FBRyxFQUFFLE1BQU0sbUJBQW1CLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsRUFBRTtTQUNyRSxFQUNEO1lBQ0UsSUFBSSxFQUFFLFdBQVcsTUFBTSxXQUFXO1lBQ2xDLEdBQUcsRUFBRSxNQUFNLG1CQUFtQixJQUFJLElBQUksQ0FBQyxrQkFBa0IsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUU7U0FDdkYsQ0FDRixDQUFDO1FBRUYsT0FBTztZQUNMLFlBQVksRUFBRSx1QkFBYyxDQUFDLE1BQU0sQ0FBQztZQUNwQyxjQUFjO1lBQ2QsY0FBYztTQUNmLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSyxrQkFBa0IsQ0FBQyxPQUEyQjtRQUNwRCxPQUFPLE9BQU8sQ0FBQyxtQkFBbUI7WUFDaEMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRTtZQUM5QyxDQUFDLENBQUMsT0FBTyxDQUFDLGNBQWM7Z0JBQ3RCLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsY0FBYyxFQUFFO2dCQUNwQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ1gsQ0FBQzs7QUFyWUgsa0NBc1lDOzs7QUFZRCxNQUFNLFNBQVMsR0FBb0I7SUFDakMsRUFBRSxFQUFFLGNBQWM7SUFDbEIsSUFBSSxFQUFFLGdCQUFnQjtJQUN0QixNQUFNLEVBQUUsZUFBZTtJQUN2QixNQUFNLEVBQUUsZ0JBQWdCO0lBQ3hCLEVBQUUsRUFBRSxhQUFhO0NBQ2xCLENBQUM7QUFFRixTQUFTLGtCQUFrQixDQUFDLE9BQTJCO0lBQ3JELElBQUksV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUM7SUFDdEMsSUFBSSxTQUFTLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQztJQUNsQyxJQUFJLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUMxQixJQUFJLE9BQU8sQ0FBQyxXQUFXLElBQUksT0FBTyxDQUFDLFdBQVcsS0FBSyxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDekUsTUFBTSxJQUFJLEtBQUssQ0FDYixnRkFBZ0YsQ0FDakYsQ0FBQztRQUNKLENBQUM7UUFFRCxJQUFJLE9BQU8sQ0FBQyxTQUFTLElBQUksT0FBTyxDQUFDLFNBQVMsS0FBSyxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDckUsTUFBTSxJQUFJLEtBQUssQ0FDYiwrRUFBK0UsQ0FDaEYsQ0FBQztRQUNKLENBQUM7UUFFRCxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7WUFDNUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUM7UUFDdEMsQ0FBQzthQUFNLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQztZQUNqRCxTQUFTLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQztRQUNwQyxDQUFDO2FBQU0sQ0FBQztZQUNOLE1BQU0sSUFBSSxLQUFLLENBQ2IsMkRBQTJELE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FDbkYsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsQ0FBQztBQUNwQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBUYXNrIH0gZnJvbSBcIi4uXCI7XG5pbXBvcnQgdHlwZSB7IEpzaWlQYWNtYWtUYXJnZXQgfSBmcm9tIFwiLi9jb25zdHNcIjtcbmltcG9ydCB7IEpTSUlfVE9PTENIQUlOIH0gZnJvbSBcIi4vY29uc3RzXCI7XG5pbXBvcnQgeyBKc2lpRG9jZ2VuIH0gZnJvbSBcIi4vanNpaS1kb2NnZW5cIjtcbmltcG9ydCB7XG4gIFBVTExfUkVRVUVTVF9SRUYsXG4gIFBVTExfUkVRVUVTVF9SRVBPU0lUT1JZLFxufSBmcm9tIFwiLi4vYnVpbGQvcHJpdmF0ZS9jb25zdHNcIjtcbmltcG9ydCB7IFdvcmtmbG93U3RlcHMgfSBmcm9tIFwiLi4vZ2l0aHViL3dvcmtmbG93LXN0ZXBzXCI7XG5pbXBvcnQgdHlwZSB7IEpvYiwgU3RlcCwgVG9vbHMgfSBmcm9tIFwiLi4vZ2l0aHViL3dvcmtmbG93cy1tb2RlbFwiO1xuaW1wb3J0IHsgSm9iUGVybWlzc2lvbiB9IGZyb20gXCIuLi9naXRodWIvd29ya2Zsb3dzLW1vZGVsXCI7XG5pbXBvcnQgeyBOb2RlUGFja2FnZU1hbmFnZXIgfSBmcm9tIFwiLi4vamF2YXNjcmlwdFwiO1xuaW1wb3J0IHsgaXNZYXJuQmVycnkgfSBmcm9tIFwiLi4vamF2YXNjcmlwdC91dGlsXCI7XG5pbXBvcnQgdHlwZSB7XG4gIENvbW1vblB1Ymxpc2hPcHRpb25zLFxuICBHb1B1Ymxpc2hPcHRpb25zLFxuICBNYXZlblB1Ymxpc2hPcHRpb25zLFxuICBOcG1QdWJsaXNoT3B0aW9ucyxcbiAgTnVnZXRQdWJsaXNoT3B0aW9ucyxcbiAgUHVibGlzaGVyLFxuICBQeVBpUHVibGlzaE9wdGlvbnMsXG59IGZyb20gXCIuLi9yZWxlYXNlXCI7XG5pbXBvcnQgeyBmaWx0ZXJlZFJ1bnNPbk9wdGlvbnMgfSBmcm9tIFwiLi4vcnVubmVyLW9wdGlvbnNcIjtcbmltcG9ydCB0eXBlIHsgVHlwZVNjcmlwdFByb2plY3RPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzY3JpcHRcIjtcbmltcG9ydCB7IFR5cGVTY3JpcHRQcm9qZWN0IH0gZnJvbSBcIi4uL3R5cGVzY3JpcHRcIjtcbmltcG9ydCB7IGRlZXBNZXJnZSB9IGZyb20gXCIuLi91dGlsXCI7XG5cbmNvbnN0IEVNQUlMX1JFR0VYID0gL15bXlxcc0BdK0BbXlxcc0BdKyQvO1xuY29uc3QgVVJMX1JFR0VYID1cbiAgLygoKFtBLVphLXpdezMsOX06KD86XFwvXFwvKT8pKD86W1xcLTs6Jj1cXCtcXCQsXFx3XStAKT9bQS1aYS16MC05XFwuXFwtXSt8KD86d3d3XFwufFtcXC07OiY9XFwrXFwkLFxcd10rQClbQS1aYS16MC05XFwuXFwtXSspKCg/OlxcL1tcXCt+JVxcL1xcLlxcd1xcLV9dKik/XFw/Pyg/OltcXC1cXCs9JjslQFxcLlxcd19dKikjPyg/OltcXC5cXCFcXC9cXFxcXFx3XSopKT8pLztcblxuY29uc3QgUkVQT19URU1QX0RJUkVDVE9SWSA9IFwiLnJlcG9cIjtcbmNvbnN0IEJVSUxEX0FSVElGQUNUX09MRF9ESVIgPSBcImRpc3Qub2xkXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSnNpaVByb2plY3RPcHRpb25zIGV4dGVuZHMgVHlwZVNjcmlwdFByb2plY3RPcHRpb25zIHtcbiAgLyoqXG4gICAqIEBkZWZhdWx0IFwiLlwiXG4gICAqL1xuICByZWFkb25seSByb290ZGlyPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBHaXQgcmVwb3NpdG9yeSBVUkwuXG4gICAqIEBkZWZhdWx0ICRHSVRfUkVNT1RFXG4gICAqL1xuICByZWFkb25seSByZXBvc2l0b3J5VXJsOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBsaWJyYXJ5IGF1dGhvci5cbiAgICogQGRlZmF1bHQgJEdJVF9VU0VSX05BTUVcbiAgICovXG4gIHJlYWRvbmx5IGF1dGhvcjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBFbWFpbCBvciBVUkwgb2YgdGhlIGxpYnJhcnkgYXV0aG9yLlxuICAgKiBAZGVmYXVsdCAkR0lUX1VTRVJfRU1BSUxcbiAgICovXG4gIHJlYWRvbmx5IGF1dGhvckFkZHJlc3M6IHN0cmluZztcblxuICAvKipcbiAgICogUHVibGlzaCB0byBtYXZlblxuICAgKiBAZGVmYXVsdCAtIG5vIHB1Ymxpc2hpbmdcbiAgICovXG4gIHJlYWRvbmx5IHB1Ymxpc2hUb01hdmVuPzogSnNpaUphdmFUYXJnZXQ7XG5cbiAgLyoqXG4gICAqIFB1Ymxpc2ggdG8gcHlwaVxuICAgKiBAZGVmYXVsdCAtIG5vIHB1Ymxpc2hpbmdcbiAgICovXG4gIHJlYWRvbmx5IHB1Ymxpc2hUb1B5cGk/OiBKc2lpUHl0aG9uVGFyZ2V0O1xuXG4gIC8qKlxuICAgKiBQdWJsaXNoIEdvIGJpbmRpbmdzIHRvIGEgZ2l0IHJlcG9zaXRvcnkuXG4gICAqIEBkZWZhdWx0IC0gbm8gcHVibGlzaGluZ1xuICAgKi9cbiAgcmVhZG9ubHkgcHVibGlzaFRvR28/OiBKc2lpR29UYXJnZXQ7XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIHVzZSBgcHVibGlzaFRvUHlQaWBcbiAgICovXG4gIHJlYWRvbmx5IHB5dGhvbj86IEpzaWlQeXRob25UYXJnZXQ7XG5cbiAgLyoqXG4gICAqIFB1Ymxpc2ggdG8gTnVHZXRcbiAgICogQGRlZmF1bHQgLSBubyBwdWJsaXNoaW5nXG4gICAqL1xuICByZWFkb25seSBwdWJsaXNoVG9OdWdldD86IEpzaWlEb3ROZXRUYXJnZXQ7XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIHVzZSBgcHVibGlzaFRvTnVnZXRgXG4gICAqL1xuICByZWFkb25seSBkb3RuZXQ/OiBKc2lpRG90TmV0VGFyZ2V0O1xuXG4gIC8qKlxuICAgKiBBdXRvbWF0aWNhbGx5IHJ1biBBUEkgY29tcGF0aWJpbGl0eSB0ZXN0IGFnYWluc3QgdGhlIGxhdGVzdCB2ZXJzaW9uIHB1Ymxpc2hlZCB0byBucG0gYWZ0ZXIgY29tcGlsYXRpb24uXG4gICAqXG4gICAqIC0gWW91IGNhbiBtYW51YWxseSBydW4gY29tcGF0aWJpbGl0eSB0ZXN0cyB1c2luZyBgeWFybiBjb21wYXRgIGlmIHRoaXMgZmVhdHVyZSBpcyBkaXNhYmxlZC5cbiAgICogLSBZb3UgY2FuIGlnbm9yZSBjb21wYXRpYmlsaXR5IGZhaWx1cmVzIGJ5IGFkZGluZyBsaW5lcyB0byBhIFwiLmNvbXBhdGlnbm9yZVwiIGZpbGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBjb21wYXQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBOYW1lIG9mIHRoZSBpZ25vcmUgZmlsZSBmb3IgQVBJIGNvbXBhdGliaWxpdHkgdGVzdHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IFwiLmNvbXBhdGlnbm9yZVwiXG4gICAqL1xuICByZWFkb25seSBjb21wYXRJZ25vcmU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEFjY2VwdHMgYSBsaXN0IG9mIGdsb2IgcGF0dGVybnMuIEZpbGVzIG1hdGNoaW5nIGFueSBvZiB0aG9zZSBwYXR0ZXJucyB3aWxsIGJlIGV4Y2x1ZGVkIGZyb20gdGhlIFR5cGVTY3JpcHQgY29tcGlsZXIgaW5wdXQuXG4gICAqXG4gICAqIEJ5IGRlZmF1bHQsIGpzaWkgd2lsbCBpbmNsdWRlIGFsbCAqLnRzIGZpbGVzIChleGNlcHQgLmQudHMgZmlsZXMpIGluIHRoZSBUeXBlU2NyaXB0IGNvbXBpbGVyIGlucHV0LlxuICAgKiBUaGlzIGNhbiBiZSBwcm9ibGVtYXRpYyBmb3IgZXhhbXBsZSB3aGVuIHRoZSBwYWNrYWdlJ3MgYnVpbGQgb3IgdGVzdCBwcm9jZWR1cmUgZ2VuZXJhdGVzIC50cyBmaWxlc1xuICAgKiB0aGF0IGNhbm5vdCBiZSBjb21waWxlZCB3aXRoIGpzaWkncyBjb21waWxlciBzZXR0aW5ncy5cbiAgICovXG4gIHJlYWRvbmx5IGV4Y2x1ZGVUeXBlc2NyaXB0Pzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEZpbGUgcGF0aCBmb3IgZ2VuZXJhdGVkIGRvY3MuXG4gICAqIEBkZWZhdWx0IFwiQVBJLm1kXCJcbiAgICovXG4gIHJlYWRvbmx5IGRvY2dlbkZpbGVQYXRoPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBFbWl0IGEgY29tcHJlc3NlZCB2ZXJzaW9uIG9mIHRoZSBhc3NlbWJseVxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgY29tcHJlc3NBc3NlbWJseT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFZlcnNpb24gb2YgdGhlIGpzaWkgY29tcGlsZXIgdG8gdXNlLlxuICAgKlxuICAgKiBTZXQgdG8gXCIqXCIgaWYgeW91IHdhbnQgdG8gbWFudWFsbHkgbWFuYWdlIHRoZSB2ZXJzaW9uIG9mIGpzaWkgaW4geW91clxuICAgKiBwcm9qZWN0IGJ5IG1hbmFnaW5nIHVwZGF0ZXMgdG8gYHBhY2thZ2UuanNvbmAgb24geW91ciBvd24uXG4gICAqXG4gICAqIE5PVEU6IFRoZSBqc2lpIGNvbXBpbGVyIHJlbGVhc2VzIHNpbmNlIDUuMC4wIGFyZSBub3Qgc2VtYW50aWNhbGx5IHZlcnNpb25lZFxuICAgKiBhbmQgc2hvdWxkIHJlbWFpbiBvbiB0aGUgc2FtZSBtaW5vciwgc28gd2UgcmVjb21tZW5kIHVzaW5nIGEgYH5gIGRlcGVuZGVuY3lcbiAgICogKGUuZy4gYH41LjAuMGApLlxuICAgKlxuICAgKiBAZGVmYXVsdCBcIn41LjkuMFwiXG4gICAqIEBwam5ldyBcIn41LjkuMFwiXG4gICAqL1xuICByZWFkb25seSBqc2lpVmVyc2lvbj86IHN0cmluZztcbn1cblxuZXhwb3J0IGVudW0gU3RhYmlsaXR5IHtcbiAgRVhQRVJJTUVOVEFMID0gXCJleHBlcmltZW50YWxcIixcbiAgU1RBQkxFID0gXCJzdGFibGVcIixcbiAgREVQUkVDQVRFRCA9IFwiZGVwcmVjYXRlZFwiLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEpzaWlKYXZhVGFyZ2V0IGV4dGVuZHMgTWF2ZW5QdWJsaXNoT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGphdmFQYWNrYWdlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IG1hdmVuR3JvdXBJZDogc3RyaW5nO1xuICByZWFkb25seSBtYXZlbkFydGlmYWN0SWQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBKc2lpUHl0aG9uVGFyZ2V0IGV4dGVuZHMgUHlQaVB1Ymxpc2hPcHRpb25zIHtcbiAgcmVhZG9ubHkgZGlzdE5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgbW9kdWxlOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSnNpaURvdE5ldFRhcmdldCBleHRlbmRzIE51Z2V0UHVibGlzaE9wdGlvbnMge1xuICByZWFkb25seSBkb3ROZXROYW1lc3BhY2U6IHN0cmluZztcbiAgcmVhZG9ubHkgcGFja2FnZUlkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGljb25Vcmw/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogR28gdGFyZ2V0IGNvbmZpZ3VyYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBKc2lpR29UYXJnZXQgZXh0ZW5kcyBHb1B1Ymxpc2hPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgcmVwb3NpdG9yeSBpbiB3aGljaCB0aGlzIG1vZHVsZSB3aWxsIGJlIHB1Ymxpc2hlZCAoZS5nLiBnaXRodWIuY29tL293bmVyL3JlcG8pLlxuICAgKlxuICAgKiBUaGUgbW9kdWxlIGl0c2VsZiB3aWxsIGFsd2F5cyBiZSBwdWJsaXNoZWQgdW5kZXIgYSBzdWJkaXJlY3RvcnkgbmFtZWQgYWNjb3JkaW5nXG4gICAqIHRvIHRoZSBgcGFja2FnZU5hbWVgIG9mIHRoZSBtb2R1bGUgKGUuZy4gZ2l0aHViLmNvbS9mb28vYmFyL3BrZykuXG4gICAqXG4gICAqIEBleGFtcGxlIGdpdGh1Yi5jb20vb3duZXIvcmVwb1xuICAgKi9cbiAgcmVhZG9ubHkgbW9kdWxlTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgR28gcGFja2FnZSBuYW1lLlxuICAgKlxuICAgKiBJZiBub3Qgc3BlY2lmaWVkLCBwYWNrYWdlIG5hbWUgd2lsbCBiZSBkZXJpdmVkIGZyb20gdGhlIEphdmFTY3JpcHQgbW9kdWxlIG5hbWVcbiAgICogYnkgcmVtb3Zpbmcgbm9uLWFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIChlLmcuIEBwcm9qZW4vZm9vLWJhciB3aWxsIGJlIHByb2plbmZvb2JhcikuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZGVyaXZlZCBmcm9tIHRoZSBKYXZhU2NyaXB0IG1vZHVsZSBuYW1lXG4gICAqL1xuICByZWFkb25seSBwYWNrYWdlTmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogQSBzdWZmaXggYXBwZW5kZWQgYXQgdGhlIGVuZCBvZiB0aGUgbW9kdWxlIHZlcnNpb24gKGUuZyBgXCItZGV2cHJlZml4XCJgKS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBub25lXG4gICAqL1xuICByZWFkb25seSB2ZXJzaW9uU3VmZml4Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIE11bHRpLWxhbmd1YWdlIGpzaWkgbGlicmFyeSBwcm9qZWN0XG4gKlxuICogQHBqaWQganNpaVxuICovXG5leHBvcnQgY2xhc3MgSnNpaVByb2plY3QgZXh0ZW5kcyBUeXBlU2NyaXB0UHJvamVjdCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgcGFja2FnZUFsbFRhc2s6IFRhc2s7XG4gIHByaXZhdGUgcmVhZG9ubHkgcGFja2FnZUpzVGFzazogVGFzaztcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBKc2lpUHJvamVjdE9wdGlvbnMpIHtcbiAgICBjb25zdCB7IGF1dGhvckVtYWlsLCBhdXRob3JVcmwgfSA9IHBhcnNlQXV0aG9yQWRkcmVzcyhvcHRpb25zKTtcblxuICAgIGNvbnN0IGpzaWlWZXJzaW9uID0gb3B0aW9ucy5qc2lpVmVyc2lvbiA/PyBcIn41LjkuMFwiO1xuXG4gICAgY29uc3QgZGVmYXVsdE9wdGlvbnM6IFBhcnRpYWw8VHlwZVNjcmlwdFByb2plY3RPcHRpb25zPiA9IHtcbiAgICAgIHJlcG9zaXRvcnk6IG9wdGlvbnMucmVwb3NpdG9yeVVybCxcbiAgICAgIGF1dGhvck5hbWU6IG9wdGlvbnMuYXV0aG9yLFxuICAgICAgYXV0aG9yRW1haWwsXG4gICAgICBhdXRob3JVcmwsXG4gICAgfTtcblxuICAgIGNvbnN0IGZvcmNlZE9wdGlvbnMgPSB7XG4gICAgICByZWxlYXNlVG9OcG06IGZhbHNlLCAvLyB3ZSBoYXZlIGEganNpaSByZWxlYXNlIHdvcmtmbG93XG4gICAgICBkaXNhYmxlVHNjb25maWc6IHRydWUsIC8vIGpzaWkgZ2VuZXJhdGVzIGl0cyBvd24gdHNjb25maWcuanNvblxuICAgICAgZG9jZ2VuOiBmYWxzZSwgLy8gd2UgdXNlIGpzaWktZG9jZ2VuIGhlcmUgc28gZGlzYWJsZSB0eXBlc2NyaXB0IGRvY2dlblxuICAgIH07XG5cbiAgICBjb25zdCBtZXJnZWRPcHRpb25zID0gZGVlcE1lcmdlKFtcbiAgICAgIGRlZmF1bHRPcHRpb25zLFxuICAgICAgb3B0aW9ucyxcbiAgICAgIGZvcmNlZE9wdGlvbnMsXG4gICAgXSkgYXMgVHlwZVNjcmlwdFByb2plY3RPcHRpb25zO1xuXG4gICAgc3VwZXIobWVyZ2VkT3B0aW9ucyk7XG5cbiAgICBjb25zdCBzcmNkaXIgPSB0aGlzLnNyY2RpcjtcbiAgICBjb25zdCBsaWJkaXIgPSB0aGlzLmxpYmRpcjtcblxuICAgIHRoaXMuYWRkRmllbGRzKHsgdHlwZXM6IGAke2xpYmRpcn0vaW5kZXguZC50c2AgfSk7XG5cbiAgICBjb25zdCBjb21wcmVzc0Fzc2VtYmx5ID0gb3B0aW9ucy5jb21wcmVzc0Fzc2VtYmx5ID8/IGZhbHNlO1xuXG4gICAgLy8gdGhpcyBpcyBhbiB1bmhlbHBmdWwgd2FybmluZ1xuICAgIGNvbnN0IGpzaWlGbGFncyA9IFtcIi0tc2lsZW5jZS13YXJuaW5ncz1yZXNlcnZlZC13b3JkXCJdO1xuICAgIGlmIChjb21wcmVzc0Fzc2VtYmx5KSB7XG4gICAgICBqc2lpRmxhZ3MucHVzaChcIi0tY29tcHJlc3MtYXNzZW1ibHlcIik7XG4gICAgfVxuXG4gICAgY29uc3QgY29tcGF0SWdub3JlID0gb3B0aW9ucy5jb21wYXRJZ25vcmUgPz8gXCIuY29tcGF0aWdub3JlXCI7XG5cbiAgICB0aGlzLmFkZEZpZWxkcyh7IHN0YWJpbGl0eTogb3B0aW9ucy5zdGFiaWxpdHkgPz8gU3RhYmlsaXR5LlNUQUJMRSB9KTtcblxuICAgIGlmIChvcHRpb25zLnN0YWJpbGl0eSA9PT0gU3RhYmlsaXR5LkRFUFJFQ0FURUQpIHtcbiAgICAgIHRoaXMuYWRkRmllbGRzKHsgZGVwcmVjYXRlZDogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBjb21wYXRUYXNrID0gdGhpcy5hZGRUYXNrKFwiY29tcGF0XCIsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlBlcmZvcm0gQVBJIGNvbXBhdGliaWxpdHkgY2hlY2sgYWdhaW5zdCBsYXRlc3QgdmVyc2lvblwiLFxuICAgICAgZXhlYzogYGpzaWktZGlmZiBucG06JChub2RlIC1wIFwicmVxdWlyZShcXCcuL3BhY2thZ2UuanNvblxcJykubmFtZVwiKSAtayAtLWlnbm9yZS1maWxlICR7Y29tcGF0SWdub3JlfSB8fCAoZWNobyBcIlxcblVORVhQRUNURUQgQlJFQUtJTkcgQ0hBTkdFUzogYWRkIGtleXMgc3VjaCBhcyBcXCdyZW1vdmVkOmNvbnN0cnVjdHMuTm9kZS5vZlxcJyB0byAke2NvbXBhdElnbm9yZX0gdG8gc2tpcC5cXG5cIiAmJiBleGl0IDEpYCxcbiAgICB9KTtcblxuICAgIGNvbnN0IGNvbXBhdCA9IG9wdGlvbnMuY29tcGF0ID8/IGZhbHNlO1xuICAgIGlmIChjb21wYXQpIHtcbiAgICAgIHRoaXMuY29tcGlsZVRhc2suc3Bhd24oY29tcGF0VGFzayk7XG4gICAgfVxuXG4gICAgdGhpcy5jb21waWxlVGFzay5yZXNldChbXCJqc2lpXCIsIC4uLmpzaWlGbGFnc10uam9pbihcIiBcIikpO1xuICAgIHRoaXMud2F0Y2hUYXNrLnJlc2V0KFtcImpzaWlcIiwgXCItd1wiLCAuLi5qc2lpRmxhZ3NdLmpvaW4oXCIgXCIpKTtcblxuICAgIC8vIENyZWF0ZSBhIG5ldyBwYWNrYWdlOmFsbCB0YXNrLCBpdCB3aWxsIGJlIGZpbGxlZCB3aXRoIGxhbmd1YWdlIHRhcmdldHMgbGF0ZXJcbiAgICB0aGlzLnBhY2thZ2VBbGxUYXNrID0gdGhpcy5hZGRUYXNrKFwicGFja2FnZS1hbGxcIiwge1xuICAgICAgZGVzY3JpcHRpb246IFwiUGFja2FnZXMgYXJ0aWZhY3RzIGZvciBhbGwgdGFyZ2V0IGxhbmd1YWdlc1wiLFxuICAgIH0pO1xuXG4gICAgLy8gaW4ganNpaSB3ZSBjb25zaWRlciB0aGUgZW50aXJlIHJlcG8gKHBvc3QgYnVpbGQpIGFzIHRoZSBidWlsZCBhcnRpZmFjdFxuICAgIC8vIHdoaWNoIGlzIHRoZW4gdXNlZCB0byBjcmVhdGUgdGhlIGxhbmd1YWdlIGJpbmRpbmdzIGluIHNlcGFyYXRlIGpvYnMuXG4gICAgLy8gd2UgYWNoaWV2ZSB0aGlzIGJ5IGRvaW5nIGEgY2hlY2tvdXQgYW5kIG92ZXJ3cml0ZSB3aXRoIHRoZSBmaWxlcyBmcm9tIHRoZSBqcyBwYWNrYWdlLlxuICAgIHRoaXMucGFja2FnZUpzVGFzayA9IHRoaXMuYWRkUGFja2FnaW5nVGFzayhcImpzXCIpO1xuXG4gICAgLy8gV2hlbiBydW5uaW5nIGluc2lkZSBDSSB3ZSBpbml0aWFsbHkgb25seSBwYWNrYWdlIGpzLiBPdGhlciB0YXJnZXRzIGFyZSBwYWNrYWdlZCBpbiBzZXBhcmF0ZSBqb2JzLlxuICAgIC8vIE91dHNpZGUgb2YgQ0kgKGkuZSBsb2NhbGx5KSB3ZSBzaW1wbHkgcGFja2FnZSBhbGwgdGFyZ2V0cy5cbiAgICB0aGlzLnBhY2thZ2VUYXNrLnJlc2V0KCk7XG4gICAgdGhpcy5wYWNrYWdlVGFzay5zcGF3bih0aGlzLnBhY2thZ2VKc1Rhc2ssIHtcbiAgICAgIC8vIE9ubHkgcnVuIGluIENJXG4gICAgICBjb25kaXRpb246IGBub2RlIC1lIFwiaWYgKCFwcm9jZXNzLmVudi5DSSkgcHJvY2Vzcy5leGl0KDEpXCJgLFxuICAgIH0pO1xuICAgIHRoaXMucGFja2FnZVRhc2suc3Bhd24odGhpcy5wYWNrYWdlQWxsVGFzaywge1xuICAgICAgLy8gRG9uJ3QgcnVuIGluIENJXG4gICAgICBjb25kaXRpb246IGBub2RlIC1lIFwiaWYgKHByb2Nlc3MuZW52LkNJKSBwcm9jZXNzLmV4aXQoMSlcImAsXG4gICAgfSk7XG5cbiAgICBjb25zdCB0YXJnZXRzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG5cbiAgICBjb25zdCBqc2lpOiBhbnkgPSB7XG4gICAgICBvdXRkaXI6IHRoaXMuYXJ0aWZhY3RzRGlyZWN0b3J5LFxuICAgICAgdGFyZ2V0cyxcbiAgICAgIHRzYzoge1xuICAgICAgICBvdXREaXI6IGxpYmRpcixcbiAgICAgICAgcm9vdERpcjogc3JjZGlyLFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgaWYgKG9wdGlvbnMuZXhjbHVkZVR5cGVzY3JpcHQpIHtcbiAgICAgIGpzaWkuZXhjbHVkZVR5cGVzY3JpcHQgPSBvcHRpb25zLmV4Y2x1ZGVUeXBlc2NyaXB0O1xuICAgIH1cblxuICAgIHRoaXMuYWRkRmllbGRzKHsganNpaSB9KTtcblxuICAgIGNvbnN0IGV4dHJhSm9iT3B0aW9uczogUGFydGlhbDxKb2I+ID0ge1xuICAgICAgLi4udGhpcy5nZXRKb2JSdW5zT25Db25maWcob3B0aW9ucyksXG4gICAgICAuLi4ob3B0aW9ucy53b3JrZmxvd0NvbnRhaW5lckltYWdlXG4gICAgICAgID8geyBjb250YWluZXI6IHsgaW1hZ2U6IG9wdGlvbnMud29ya2Zsb3dDb250YWluZXJJbWFnZSB9IH1cbiAgICAgICAgOiB7fSksXG4gICAgfTtcblxuICAgIGlmIChvcHRpb25zLnJlbGVhc2VUb05wbSAhPSBmYWxzZSkge1xuICAgICAgY29uc3QgbnBtanM6IE5wbVB1Ymxpc2hPcHRpb25zID0ge1xuICAgICAgICByZWdpc3RyeTogdGhpcy5wYWNrYWdlLm5wbVJlZ2lzdHJ5LFxuICAgICAgICBucG1Ub2tlblNlY3JldDogdGhpcy5wYWNrYWdlLm5wbVRva2VuU2VjcmV0LFxuICAgICAgICBucG1Qcm92ZW5hbmNlOiB0aGlzLnBhY2thZ2UubnBtUHJvdmVuYW5jZSxcbiAgICAgICAgY29kZUFydGlmYWN0T3B0aW9uczogb3B0aW9ucy5jb2RlQXJ0aWZhY3RPcHRpb25zLFxuICAgICAgICB0cnVzdGVkUHVibGlzaGluZzogb3B0aW9ucy5ucG1UcnVzdGVkUHVibGlzaGluZyA/PyBmYWxzZSxcbiAgICAgIH07XG4gICAgICB0aGlzLmFkZFRhcmdldFRvQnVpbGQoXCJqc1wiLCB0aGlzLnBhY2thZ2VKc1Rhc2ssIGV4dHJhSm9iT3B0aW9ucyk7XG4gICAgICB0aGlzLmFkZFRhcmdldFRvUmVsZWFzZShcImpzXCIsIHRoaXMucGFja2FnZUpzVGFzaywgbnBtanMpO1xuICAgIH1cblxuICAgIC8vIHdlIGNhbm5vdCBjYWxsIGFuIG9wdGlvbiBgamF2YWAgYmVjYXVzZSB0aGUgamF2YSBjb2RlIGdlbmVyYXRlZCBieSBqc2lpXG4gICAgLy8gZG9lcyBub3QgY29tcGlsZSBkdWUgdG8gYSBjb25mbGljdCBiZXR3ZWVuIHRoaXMgb3B0aW9uIG5hbWUgYW5kIHRoZSBgamF2YWBcbiAgICAvLyBwYWNrYWdlIChlLmcuIHdoZW4gYGphdmEudXRpbC5PYmplY3RzYCBpcyByZWZlcmVuY2VkKS5cbiAgICBpZiAoXCJqYXZhXCIgaW4gb3B0aW9ucykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgXCJqYXZhXCIgb3B0aW9uIGlzIG5vdyBjYWxsZWQgXCJwdWJsaXNoVG9NYXZlblwiJyk7XG4gICAgfVxuXG4gICAgY29uc3QgbWF2ZW4gPSBvcHRpb25zLnB1Ymxpc2hUb01hdmVuO1xuICAgIGlmIChtYXZlbikge1xuICAgICAgdGFyZ2V0cy5qYXZhID0ge1xuICAgICAgICBwYWNrYWdlOiBtYXZlbi5qYXZhUGFja2FnZSxcbiAgICAgICAgbWF2ZW46IHtcbiAgICAgICAgICBncm91cElkOiBtYXZlbi5tYXZlbkdyb3VwSWQsXG4gICAgICAgICAgYXJ0aWZhY3RJZDogbWF2ZW4ubWF2ZW5BcnRpZmFjdElkLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdGFzayA9IHRoaXMuYWRkUGFja2FnaW5nVGFzayhcImphdmFcIik7XG4gICAgICB0aGlzLmFkZFRhcmdldFRvQnVpbGQoXCJqYXZhXCIsIHRhc2ssIGV4dHJhSm9iT3B0aW9ucyk7XG4gICAgICB0aGlzLmFkZFRhcmdldFRvUmVsZWFzZShcImphdmFcIiwgdGFzaywgbWF2ZW4pO1xuICAgIH1cblxuICAgIGNvbnN0IHB5cGkgPSBvcHRpb25zLnB1Ymxpc2hUb1B5cGkgPz8gb3B0aW9ucy5weXRob247XG4gICAgaWYgKHB5cGkpIHtcbiAgICAgIHRhcmdldHMucHl0aG9uID0ge1xuICAgICAgICBkaXN0TmFtZTogcHlwaS5kaXN0TmFtZSxcbiAgICAgICAgbW9kdWxlOiBweXBpLm1vZHVsZSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHRhc2sgPSB0aGlzLmFkZFBhY2thZ2luZ1Rhc2soXCJweXRob25cIik7XG4gICAgICB0aGlzLmFkZFRhcmdldFRvQnVpbGQoXCJweXRob25cIiwgdGFzaywgZXh0cmFKb2JPcHRpb25zKTtcbiAgICAgIHRoaXMuYWRkVGFyZ2V0VG9SZWxlYXNlKFwicHl0aG9uXCIsIHRhc2ssIHB5cGkpO1xuICAgIH1cblxuICAgIGNvbnN0IG51Z2V0ID0gb3B0aW9ucy5wdWJsaXNoVG9OdWdldCA/PyBvcHRpb25zLmRvdG5ldDtcbiAgICBpZiAobnVnZXQpIHtcbiAgICAgIHRhcmdldHMuZG90bmV0ID0ge1xuICAgICAgICBuYW1lc3BhY2U6IG51Z2V0LmRvdE5ldE5hbWVzcGFjZSxcbiAgICAgICAgcGFja2FnZUlkOiBudWdldC5wYWNrYWdlSWQsXG4gICAgICAgIGljb25Vcmw6IG51Z2V0Lmljb25VcmwsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0YXNrID0gdGhpcy5hZGRQYWNrYWdpbmdUYXNrKFwiZG90bmV0XCIpO1xuICAgICAgdGhpcy5hZGRUYXJnZXRUb0J1aWxkKFwiZG90bmV0XCIsIHRhc2ssIGV4dHJhSm9iT3B0aW9ucyk7XG4gICAgICB0aGlzLmFkZFRhcmdldFRvUmVsZWFzZShcImRvdG5ldFwiLCB0YXNrLCBudWdldCk7XG4gICAgfVxuXG4gICAgY29uc3QgZ29sYW5nID0gb3B0aW9ucy5wdWJsaXNoVG9HbztcbiAgICBpZiAoZ29sYW5nKSB7XG4gICAgICB0YXJnZXRzLmdvID0ge1xuICAgICAgICBtb2R1bGVOYW1lOiBnb2xhbmcubW9kdWxlTmFtZSxcbiAgICAgICAgcGFja2FnZU5hbWU6IGdvbGFuZy5wYWNrYWdlTmFtZSxcbiAgICAgICAgdmVyc2lvblN1ZmZpeDogZ29sYW5nLnZlcnNpb25TdWZmaXgsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0YXNrID0gdGhpcy5hZGRQYWNrYWdpbmdUYXNrKFwiZ29cIik7XG4gICAgICB0aGlzLmFkZFRhcmdldFRvQnVpbGQoXCJnb1wiLCB0YXNrLCBleHRyYUpvYk9wdGlvbnMpO1xuICAgICAgdGhpcy5hZGRUYXJnZXRUb1JlbGVhc2UoXCJnb1wiLCB0YXNrLCBnb2xhbmcpO1xuICAgIH1cblxuICAgIC8vIElmIGpzaWlWZXJzaW9uIGlzIFwiKlwiLCBkb24ndCBzcGVjaWZ5IGFueXRoaW5nIHNvIHRoZSB1c2VyIGNhbiBtYW5hZ2UuXG4gICAgLy8gT3RoZXJ3aXNlLCB1c2UgYGpzaWlWZXJzaW9uYFxuICAgIGNvbnN0IGpzaWlTdWZmaXggPSBqc2lpVmVyc2lvbiA9PT0gXCIqXCIgPyBcIlwiIDogYEAke2pzaWlWZXJzaW9ufWA7XG4gICAgdGhpcy5hZGREZXZEZXBzKFxuICAgICAgYGpzaWkke2pzaWlTdWZmaXh9YCxcbiAgICAgIGBqc2lpLXJvc2V0dGEke2pzaWlTdWZmaXh9YCxcbiAgICAgIFwianNpaS1kaWZmXCIsXG4gICAgICBcImpzaWktcGFjbWFrXCIsXG4gICAgKTtcblxuICAgIHRoaXMuZ2l0aWdub3JlLmV4Y2x1ZGUoXCIuanNpaVwiLCBcInRzY29uZmlnLmpzb25cIik7XG4gICAgdGhpcy5ucG1pZ25vcmU/LmluY2x1ZGUoXCIuanNpaVwiKTtcblxuICAgIGlmIChvcHRpb25zLmRvY2dlbiA/PyB0cnVlKSB7XG4gICAgICAvLyBJZiBqc2lpVmVyc2lvbiBpcyBcIipcIiwgZG9uJ3Qgc3BlY2lmeSBhbnl0aGluZyBzbyB0aGUgdXNlciBjYW4gbWFuYWdlLlxuICAgICAgLy8gT3RoZXJ3aXNlIHVzZSBhIHZlcnNpb24gdGhhdCBpcyBjb21wYXRpYmxlIHdpdGggYWxsIHN1cHBvcnRlZCBqc2lpIHJlbGVhc2VzLlxuICAgICAgY29uc3QgZG9jZ2VuVmVyc2lvbiA9IG9wdGlvbnMuanNpaVZlcnNpb24gPT09IFwiKlwiID8gXCIqXCIgOiBcIl4xMC41LjBcIjtcbiAgICAgIG5ldyBKc2lpRG9jZ2VuKHRoaXMsIHtcbiAgICAgICAgdmVyc2lvbjogZG9jZ2VuVmVyc2lvbixcbiAgICAgICAgZmlsZVBhdGg6IG9wdGlvbnMuZG9jZ2VuRmlsZVBhdGgsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBqc2lpIHVwZGF0ZXMgLm5wbWlnbm9yZSwgc28gd2UgbWFrZSBpdCB3cml0YWJsZVxuICAgIGlmICh0aGlzLm5wbWlnbm9yZSkge1xuICAgICAgdGhpcy5ucG1pZ25vcmUucmVhZG9ubHkgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHRhcmdldCBsYW5ndWFnZSB0byB0aGUgcmVsZWFzZSB3b3JrZmxvdy5cbiAgICogQHBhcmFtIGxhbmd1YWdlXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBwcml2YXRlIGFkZFRhcmdldFRvUmVsZWFzZShcbiAgICBsYW5ndWFnZTogSnNpaVBhY21ha1RhcmdldCxcbiAgICBwYWNrVGFzazogVGFzayxcbiAgICB0YXJnZXQ6XG4gICAgICB8IEpzaWlQeXRob25UYXJnZXRcbiAgICAgIHwgSnNpaURvdE5ldFRhcmdldFxuICAgICAgfCBKc2lpR29UYXJnZXRcbiAgICAgIHwgSnNpaUphdmFUYXJnZXRcbiAgICAgIHwgTnBtUHVibGlzaE9wdGlvbnMsXG4gICkge1xuICAgIGlmICghdGhpcy5yZWxlYXNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcGFjbWFrID0gdGhpcy5wYWNtYWtGb3JMYW5ndWFnZShsYW5ndWFnZSwgcGFja1Rhc2spO1xuICAgIGNvbnN0IHByZVB1Ymxpc2hTdGVwcyA9IFtcbiAgICAgIC4uLnBhY21hay5ib290c3RyYXBTdGVwcyxcbiAgICAgIFdvcmtmbG93U3RlcHMuY2hlY2tvdXQoe1xuICAgICAgICB3aXRoOiB7XG4gICAgICAgICAgcGF0aDogUkVQT19URU1QX0RJUkVDVE9SWSxcbiAgICAgICAgICAuLi4odGhpcy5naXRodWI/LmRvd25sb2FkTGZzID8geyBsZnM6IHRydWUgfSA6IHt9KSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICAgLi4ucGFjbWFrLnBhY2thZ2luZ1N0ZXBzLFxuICAgIF07XG4gICAgY29uc3QgY29tbW9uUHVibGlzaE9wdGlvbnM6IENvbW1vblB1Ymxpc2hPcHRpb25zID0ge1xuICAgICAgcHVibGlzaFRvb2xzOiBwYWNtYWsucHVibGlzaFRvb2xzLFxuICAgICAgcHJlUHVibGlzaFN0ZXBzLFxuICAgIH07XG5cbiAgICBjb25zdCBoYW5kbGVyOiBQdWJsaXNoVG8gPSBwdWJsaXNoVG9bbGFuZ3VhZ2VdO1xuICAgIHRoaXMucmVsZWFzZT8ucHVibGlzaGVyW2hhbmRsZXJdKHtcbiAgICAgIC4uLmNvbW1vblB1Ymxpc2hPcHRpb25zLFxuICAgICAgLi4udGFyZ2V0LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSB0YXJnZXQgbGFuZ3VhZ2UgdG8gdGhlIGJ1aWxkIHdvcmtmbG93XG4gICAqIEBwYXJhbSBsYW5ndWFnZVxuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgcHJpdmF0ZSBhZGRUYXJnZXRUb0J1aWxkKFxuICAgIGxhbmd1YWdlOiBKc2lpUGFjbWFrVGFyZ2V0LFxuICAgIHBhY2tUYXNrOiBUYXNrLFxuICAgIGV4dHJhSm9iT3B0aW9uczogUGFydGlhbDxKb2I+LFxuICApIHtcbiAgICBpZiAoIXRoaXMuYnVpbGRXb3JrZmxvdykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwYWNtYWsgPSB0aGlzLnBhY21ha0Zvckxhbmd1YWdlKGxhbmd1YWdlLCBwYWNrVGFzayk7XG5cbiAgICB0aGlzLmJ1aWxkV29ya2Zsb3cuYWRkUG9zdEJ1aWxkSm9iKGBwYWNrYWdlLSR7bGFuZ3VhZ2V9YCwge1xuICAgICAgLi4uZmlsdGVyZWRSdW5zT25PcHRpb25zKFxuICAgICAgICBleHRyYUpvYk9wdGlvbnMucnVuc09uLFxuICAgICAgICBleHRyYUpvYk9wdGlvbnMucnVuc09uR3JvdXAsXG4gICAgICApLFxuICAgICAgcGVybWlzc2lvbnM6IHtcbiAgICAgICAgY29udGVudHM6IEpvYlBlcm1pc3Npb24uUkVBRCxcbiAgICAgIH0sXG4gICAgICB0b29sczoge1xuICAgICAgICBub2RlOiB7IHZlcnNpb246IHRoaXMubm9kZVZlcnNpb24gPz8gXCJsdHMvKlwiIH0sXG4gICAgICAgIC4uLnBhY21hay5wdWJsaXNoVG9vbHMsXG4gICAgICB9LFxuICAgICAgc3RlcHM6IFtcbiAgICAgICAgLi4ucGFjbWFrLmJvb3RzdHJhcFN0ZXBzLFxuICAgICAgICBXb3JrZmxvd1N0ZXBzLmNoZWNrb3V0KHtcbiAgICAgICAgICB3aXRoOiB7XG4gICAgICAgICAgICBwYXRoOiBSRVBPX1RFTVBfRElSRUNUT1JZLFxuICAgICAgICAgICAgcmVmOiBQVUxMX1JFUVVFU1RfUkVGLFxuICAgICAgICAgICAgcmVwb3NpdG9yeTogUFVMTF9SRVFVRVNUX1JFUE9TSVRPUlksXG4gICAgICAgICAgICAuLi4odGhpcy5naXRodWI/LmRvd25sb2FkTGZzID8geyBsZnM6IHRydWUgfSA6IHt9KSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbi