UNPKG

@aws-cdk/core

Version:

AWS Cloud Development Kit Core Library

306 lines 49.3 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.DefaultStackSynthesizer = exports.BOOTSTRAP_QUALIFIER_CONTEXT = void 0; const jsiiDeprecationWarnings = require("../../.warnings.jsii.js"); const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const cxapi = require("@aws-cdk/cx-api"); const cfn_fn_1 = require("../cfn-fn"); const cfn_parameter_1 = require("../cfn-parameter"); const cfn_rule_1 = require("../cfn-rule"); const token_1 = require("../token"); const _asset_manifest_builder_1 = require("./_asset-manifest-builder"); const _shared_1 = require("./_shared"); const stack_synthesizer_1 = require("./stack-synthesizer"); exports.BOOTSTRAP_QUALIFIER_CONTEXT = '@aws-cdk/core:bootstrapQualifier'; /* eslint-disable max-len */ /** * The minimum bootstrap stack version required by this app. */ const MIN_BOOTSTRAP_STACK_VERSION = 6; /** * The minimum bootstrap stack version required * to use the lookup role. */ const MIN_LOOKUP_ROLE_BOOTSTRAP_STACK_VERSION = 8; /** * Uses conventionally named roles and asset storage locations * * This synthesizer: * * - Supports cross-account deployments (the CLI can have credentials to one * account, and you can still deploy to another account by assuming roles with * well-known names in the other account). * - Supports the **CDK Pipelines** library. * * Requires the environment to have been bootstrapped with Bootstrap Stack V2 * (also known as "modern bootstrap stack"). The synthesizer adds a version * check to the template, to make sure the bootstrap stack is recent enough * to support all features expected by this synthesizer. */ class DefaultStackSynthesizer extends stack_synthesizer_1.StackSynthesizer { constructor(props = {}) { super(); this.props = props; this.assetManifest = new _asset_manifest_builder_1.AssetManifestBuilder(); try { jsiiDeprecationWarnings._aws_cdk_core_DefaultStackSynthesizerProps(props); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, DefaultStackSynthesizer); } throw error; } this.useLookupRoleForStackOperations = props.useLookupRoleForStackOperations ?? true; for (const key in props) { if (props.hasOwnProperty(key)) { validateNoToken(key); } } function validateNoToken(key) { const prop = props[key]; if (typeof prop === 'string' && token_1.Token.isUnresolved(prop)) { throw new Error(`DefaultSynthesizer property '${key}' cannot contain tokens; only the following placeholder strings are allowed: ` + [ '${Qualifier}', cxapi.EnvironmentPlaceholders.CURRENT_REGION, cxapi.EnvironmentPlaceholders.CURRENT_ACCOUNT, cxapi.EnvironmentPlaceholders.CURRENT_PARTITION, ].join(', ')); } } } bind(stack) { try { jsiiDeprecationWarnings._aws_cdk_core_Stack(stack); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.bind); } throw error; } if (this._stack !== undefined) { throw new Error('A StackSynthesizer can only be used for one Stack: create a new instance to use with a different Stack'); } this._stack = stack; const qualifier = this.props.qualifier ?? stack.node.tryGetContext(exports.BOOTSTRAP_QUALIFIER_CONTEXT) ?? DefaultStackSynthesizer.DEFAULT_QUALIFIER; this.qualifier = qualifier; const spec = new _shared_1.StringSpecializer(stack, qualifier); /* eslint-disable max-len */ this.bucketName = spec.specialize(this.props.fileAssetsBucketName ?? DefaultStackSynthesizer.DEFAULT_FILE_ASSETS_BUCKET_NAME); this.repositoryName = spec.specialize(this.props.imageAssetsRepositoryName ?? DefaultStackSynthesizer.DEFAULT_IMAGE_ASSETS_REPOSITORY_NAME); this._deployRoleArn = spec.specialize(this.props.deployRoleArn ?? DefaultStackSynthesizer.DEFAULT_DEPLOY_ROLE_ARN); this._cloudFormationExecutionRoleArn = spec.specialize(this.props.cloudFormationExecutionRole ?? DefaultStackSynthesizer.DEFAULT_CLOUDFORMATION_ROLE_ARN); this.fileAssetPublishingRoleArn = spec.specialize(this.props.fileAssetPublishingRoleArn ?? DefaultStackSynthesizer.DEFAULT_FILE_ASSET_PUBLISHING_ROLE_ARN); this.imageAssetPublishingRoleArn = spec.specialize(this.props.imageAssetPublishingRoleArn ?? DefaultStackSynthesizer.DEFAULT_IMAGE_ASSET_PUBLISHING_ROLE_ARN); this.lookupRoleArn = spec.specialize(this.props.lookupRoleArn ?? DefaultStackSynthesizer.DEFAULT_LOOKUP_ROLE_ARN); this.bucketPrefix = spec.specialize(this.props.bucketPrefix ?? DefaultStackSynthesizer.DEFAULT_FILE_ASSET_PREFIX); this.dockerTagPrefix = spec.specialize(this.props.dockerTagPrefix ?? DefaultStackSynthesizer.DEFAULT_DOCKER_ASSET_PREFIX); this.bootstrapStackVersionSsmParameter = spec.qualifierOnly(this.props.bootstrapStackVersionSsmParameter ?? DefaultStackSynthesizer.DEFAULT_BOOTSTRAP_STACK_VERSION_SSM_PARAMETER); } addFileAsset(asset) { try { jsiiDeprecationWarnings._aws_cdk_core_FileAssetSource(asset); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.addFileAsset); } throw error; } _shared_1.assertBound(this.stack); _shared_1.assertBound(this.bucketName); _shared_1.assertBound(this.bucketPrefix); return this.assetManifest.addFileAssetDefault(asset, this.stack, this.bucketName, this.bucketPrefix, { assumeRoleArn: this.fileAssetPublishingRoleArn, assumeRoleExternalId: this.props.fileAssetPublishingExternalId, }); } addDockerImageAsset(asset) { try { jsiiDeprecationWarnings._aws_cdk_core_DockerImageAssetSource(asset); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.addDockerImageAsset); } throw error; } _shared_1.assertBound(this.stack); _shared_1.assertBound(this.repositoryName); _shared_1.assertBound(this.dockerTagPrefix); return this.assetManifest.addDockerImageAssetDefault(asset, this.stack, this.repositoryName, this.dockerTagPrefix, { assumeRoleArn: this.imageAssetPublishingRoleArn, assumeRoleExternalId: this.props.imageAssetPublishingExternalId, }); } synthesizeStackTemplate(stack, session) { try { jsiiDeprecationWarnings._aws_cdk_core_Stack(stack); jsiiDeprecationWarnings._aws_cdk_core_ISynthesisSession(session); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.synthesizeStackTemplate); } throw error; } stack._synthesizeTemplate(session, this.lookupRoleArn); } /** * Synthesize the associated stack to the session */ synthesize(session) { try { jsiiDeprecationWarnings._aws_cdk_core_ISynthesisSession(session); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.synthesize); } throw error; } _shared_1.assertBound(this.stack); _shared_1.assertBound(this.qualifier); // Must be done here -- if it's done in bind() (called in the Stack's constructor) // then it will become impossible to set context after that. // // If it's done AFTER _synthesizeTemplate(), then the template won't contain the // right constructs. if (this.props.generateBootstrapVersionRule ?? true) { addBootstrapVersionRule(this.stack, MIN_BOOTSTRAP_STACK_VERSION, this.bootstrapStackVersionSsmParameter); } this.synthesizeStackTemplate(this.stack, session); const templateAsset = this.addFileAsset(_shared_1.stackTemplateFileAsset(this.stack, session)); const assetManifestId = this.assetManifest.writeManifest(this.stack, session, { requiresBootstrapStackVersion: MIN_BOOTSTRAP_STACK_VERSION, bootstrapStackVersionSsmParameter: this.bootstrapStackVersionSsmParameter, }); this.emitStackArtifact(this.stack, session, { assumeRoleExternalId: this.props.deployRoleExternalId, assumeRoleArn: this._deployRoleArn, cloudFormationExecutionRoleArn: this._cloudFormationExecutionRoleArn, stackTemplateAssetObjectUrl: templateAsset.s3ObjectUrlWithPlaceholders, requiresBootstrapStackVersion: MIN_BOOTSTRAP_STACK_VERSION, bootstrapStackVersionSsmParameter: this.bootstrapStackVersionSsmParameter, additionalDependencies: [assetManifestId], lookupRole: this.useLookupRoleForStackOperations && this.lookupRoleArn ? { arn: this.lookupRoleArn, assumeRoleExternalId: this.props.lookupRoleExternalId, requiresBootstrapStackVersion: MIN_LOOKUP_ROLE_BOOTSTRAP_STACK_VERSION, bootstrapStackVersionSsmParameter: this.bootstrapStackVersionSsmParameter, } : undefined, }); } /** * Returns the ARN of the deploy Role. */ get deployRoleArn() { if (!this._deployRoleArn) { throw new Error('deployRoleArn getter can only be called after the synthesizer has been bound to a Stack'); } return this._deployRoleArn; } /** * Returns the ARN of the CFN execution Role. */ get cloudFormationExecutionRoleArn() { if (!this._cloudFormationExecutionRoleArn) { throw new Error('cloudFormationExecutionRoleArn getter can only be called after the synthesizer has been bound to a Stack'); } return this._cloudFormationExecutionRoleArn; } get stack() { return this._stack; } } exports.DefaultStackSynthesizer = DefaultStackSynthesizer; _a = JSII_RTTI_SYMBOL_1; DefaultStackSynthesizer[_a] = { fqn: "@aws-cdk/core.DefaultStackSynthesizer", version: "1.204.0" }; /** * Default ARN qualifier */ DefaultStackSynthesizer.DEFAULT_QUALIFIER = 'hnb659fds'; /** * Default CloudFormation role ARN. */ DefaultStackSynthesizer.DEFAULT_CLOUDFORMATION_ROLE_ARN = 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-${Qualifier}-cfn-exec-role-${AWS::AccountId}-${AWS::Region}'; /** * Default deploy role ARN. */ DefaultStackSynthesizer.DEFAULT_DEPLOY_ROLE_ARN = 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-${Qualifier}-deploy-role-${AWS::AccountId}-${AWS::Region}'; /** * Default asset publishing role ARN for file (S3) assets. */ DefaultStackSynthesizer.DEFAULT_FILE_ASSET_PUBLISHING_ROLE_ARN = 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-${Qualifier}-file-publishing-role-${AWS::AccountId}-${AWS::Region}'; /** * Default asset publishing role ARN for image (ECR) assets. */ DefaultStackSynthesizer.DEFAULT_IMAGE_ASSET_PUBLISHING_ROLE_ARN = 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-${Qualifier}-image-publishing-role-${AWS::AccountId}-${AWS::Region}'; /** * Default lookup role ARN for missing values. */ DefaultStackSynthesizer.DEFAULT_LOOKUP_ROLE_ARN = 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-${Qualifier}-lookup-role-${AWS::AccountId}-${AWS::Region}'; /** * Default image assets repository name */ DefaultStackSynthesizer.DEFAULT_IMAGE_ASSETS_REPOSITORY_NAME = 'cdk-${Qualifier}-container-assets-${AWS::AccountId}-${AWS::Region}'; /** * Default file assets bucket name */ DefaultStackSynthesizer.DEFAULT_FILE_ASSETS_BUCKET_NAME = 'cdk-${Qualifier}-assets-${AWS::AccountId}-${AWS::Region}'; /** * Name of the CloudFormation Export with the asset key name */ DefaultStackSynthesizer.DEFAULT_FILE_ASSET_KEY_ARN_EXPORT_NAME = 'CdkBootstrap-${Qualifier}-FileAssetKeyArn'; /** * Default file asset prefix */ DefaultStackSynthesizer.DEFAULT_FILE_ASSET_PREFIX = ''; /** * Default Docker asset prefix */ DefaultStackSynthesizer.DEFAULT_DOCKER_ASSET_PREFIX = ''; /** * Default bootstrap stack version SSM parameter. */ DefaultStackSynthesizer.DEFAULT_BOOTSTRAP_STACK_VERSION_SSM_PARAMETER = '/cdk-bootstrap/${Qualifier}/version'; /** * Add a CfnRule to the Stack which checks the current version of the bootstrap stack this template is targeting * * The CLI normally checks this, but in a pipeline the CLI is not involved * so we encode this rule into the template in a way that CloudFormation will check it. */ function addBootstrapVersionRule(stack, requiredVersion, bootstrapStackVersionSsmParameter) { // Because of https://github.com/aws/aws-cdk/blob/master/packages/assert-internal/lib/synth-utils.ts#L74 // synthesize() may be called more than once on a stack in unit tests, and the below would break // if we execute it a second time. Guard against the constructs already existing. if (stack.node.tryFindChild('BootstrapVersion')) { return; } const param = new cfn_parameter_1.CfnParameter(stack, 'BootstrapVersion', { type: 'AWS::SSM::Parameter::Value<String>', description: `Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. ${cxapi.SSMPARAM_NO_INVALIDATE}`, default: bootstrapStackVersionSsmParameter, }); // There is no >= check in CloudFormation, so we have to check the number // is NOT in [1, 2, 3, ... <required> - 1] const oldVersions = range(1, requiredVersion).map(n => `${n}`); new cfn_rule_1.CfnRule(stack, 'CheckBootstrapVersion', { assertions: [ { assert: cfn_fn_1.Fn.conditionNot(cfn_fn_1.Fn.conditionContains(oldVersions, param.valueAsString)), assertDescription: `CDK bootstrap stack version ${requiredVersion} required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.`, }, ], }); } function range(startIncl, endExcl) { const ret = new Array(); for (let i = startIncl; i < endExcl; i++) { ret.push(i); } return ret; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdC1zeW50aGVzaXplci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImRlZmF1bHQtc3ludGhlc2l6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEseUNBQXlDO0FBRXpDLHNDQUErQjtBQUMvQixvREFBZ0Q7QUFDaEQsMENBQXNDO0FBR3RDLG9DQUFpQztBQUNqQyx1RUFBaUU7QUFDakUsdUNBQW1GO0FBQ25GLDJEQUF1RDtBQUUxQyxRQUFBLDJCQUEyQixHQUFHLGtDQUFrQyxDQUFDO0FBRTlFLDRCQUE0QjtBQUU1Qjs7R0FFRztBQUNILE1BQU0sMkJBQTJCLEdBQUcsQ0FBQyxDQUFDO0FBRXRDOzs7R0FHRztBQUNILE1BQU0sdUNBQXVDLEdBQUcsQ0FBQyxDQUFDO0FBZ01sRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQWEsdUJBQXdCLFNBQVEsb0NBQWdCO0lBNEUzRCxZQUE2QixRQUFzQyxFQUFFO1FBQ25FLEtBQUssRUFBRSxDQUFDO1FBRG1CLFVBQUssR0FBTCxLQUFLLENBQW1DO1FBRjdELGtCQUFhLEdBQUcsSUFBSSw4Q0FBb0IsRUFBRSxDQUFDOzs7Ozs7K0NBMUV4Qyx1QkFBdUI7Ozs7UUE4RWhDLElBQUksQ0FBQywrQkFBK0IsR0FBRyxLQUFLLENBQUMsK0JBQStCLElBQUksSUFBSSxDQUFDO1FBRXJGLEtBQUssTUFBTSxHQUFHLElBQUksS0FBSyxFQUFFO1lBQ3ZCLElBQUksS0FBSyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRTtnQkFDN0IsZUFBZSxDQUFDLEdBQXlDLENBQUMsQ0FBQzthQUM1RDtTQUNGO1FBRUQsU0FBUyxlQUFlLENBQStDLEdBQU07WUFDM0UsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3hCLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxJQUFJLGFBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ3hELE1BQU0sSUFB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QUUsQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUN4QyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQ2I7SUFDRCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjeGFwaSBmcm9tICdAYXdzLWNkay9jeC1hcGknO1xuaW1wb3J0IHsgRG9ja2VySW1hZ2VBc3NldExvY2F0aW9uLCBEb2NrZXJJbWFnZUFzc2V0U291cmNlLCBGaWxlQXNzZXRMb2NhdGlvbiwgRmlsZUFzc2V0U291cmNlIH0gZnJvbSAnLi4vYXNzZXRzJztcbmltcG9ydCB7IEZuIH0gZnJvbSAnLi4vY2ZuLWZuJztcbmltcG9ydCB7IENmblBhcmFtZXRlciB9IGZyb20gJy4uL2Nmbi1wYXJhbWV0ZXInO1xuaW1wb3J0IHsgQ2ZuUnVsZSB9IGZyb20gJy4uL2Nmbi1ydWxlJztcbmltcG9ydCB7IElTeW50aGVzaXNTZXNzaW9uIH0gZnJvbSAnLi4vY29uc3RydWN0LWNvbXBhdCc7XG5pbXBvcnQgeyBTdGFjayB9IGZyb20gJy4uL3N0YWNrJztcbmltcG9ydCB7IFRva2VuIH0gZnJvbSAnLi4vdG9rZW4nO1xuaW1wb3J0IHsgQXNzZXRNYW5pZmVzdEJ1aWxkZXIgfSBmcm9tICcuL19hc3NldC1tYW5pZmVzdC1idWlsZGVyJztcbmltcG9ydCB7IGFzc2VydEJvdW5kLCBTdHJpbmdTcGVjaWFsaXplciwgc3RhY2tUZW1wbGF0ZUZpbGVBc3NldCB9IGZyb20gJy4vX3NoYXJlZCc7XG5pbXBvcnQgeyBTdGFja1N5bnRoZXNpemVyIH0gZnJvbSAnLi9zdGFjay1zeW50aGVzaXplcic7XG5cbmV4cG9ydCBjb25zdCBCT09UU1RSQVBfUVVBTElGSUVSX0NPTlRFWFQgPSAnQGF3cy1jZGsvY29yZTpib290c3RyYXBRdWFsaWZpZXInO1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5cbi8qKlxuICogVGhlIG1pbmltdW0gYm9vdHN0cmFwIHN0YWNrIHZlcnNpb24gcmVxdWlyZWQgYnkgdGhpcyBhcHAuXG4gKi9cbmNvbnN0IE1JTl9CT09UU1RSQVBfU1RBQ0tfVkVSU0lPTiA9IDY7XG5cbi8qKlxuICogVGhlIG1pbmltdW0gYm9vdHN0cmFwIHN0YWNrIHZlcnNpb24gcmVxdWlyZWRcbiAqIHRvIHVzZSB0aGUgbG9va3VwIHJvbGUuXG4gKi9cbmNvbnN0IE1JTl9MT09LVVBfUk9MRV9CT09UU1RSQVBfU1RBQ0tfVkVSU0lPTiA9IDg7XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBwcm9wZXJ0aWVzIGZvciBEZWZhdWx0U3RhY2tTeW50aGVzaXplclxuICovXG5leHBvcnQgaW50ZXJmYWNlIERlZmF1bHRTdGFja1N5bnRoZXNpemVyUHJvcHMge1xuICAvKipcbiAgICogTmFtZSBvZiB0aGUgUzMgYnVja2V0IHRvIGhvbGQgZmlsZSBhc3NldHNcbiAgICpcbiAgICogWW91IG11c3Qgc3VwcGx5IHRoaXMgaWYgeW91IGhhdmUgZ2l2ZW4gYSBub24tc3RhbmRhcmQgbmFtZSB0byB0aGUgc3RhZ2luZyBidWNrZXQuXG4gICAqXG4gICAqIFRoZSBwbGFjZWhvbGRlcnMgYCR7UXVhbGlmaWVyfWAsIGAke0FXUzo6QWNjb3VudElkfWAgYW5kIGAke0FXUzo6UmVnaW9ufWAgd2lsbFxuICAgKiBiZSByZXBsYWNlZCB3aXRoIHRoZSB2YWx1ZXMgb2YgcXVhbGlmaWVyIGFuZCB0aGUgc3RhY2sncyBhY2NvdW50IGFuZCByZWdpb24sXG4gICAqIHJlc3BlY3RpdmVseS5cbiAgICpcbiAgICogQGRlZmF1bHQgRGVmYXVsdFN0YWNrU3ludGhlc2l6ZXIuREVGQVVMVF9GSUxFX0FTU0VUU19CVUNLRVRfTkFNRVxuICAgKi9cbiAgcmVhZG9ubHkgZmlsZUFzc2V0c0J1Y2tldE5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE5hbWUgb2YgdGhlIEVDUiByZXBvc2l0b3J5IHRvIGhvbGQgRG9ja2VyIEltYWdlIGFzc2V0c1xuICAgKlxuICAgKiBZb3UgbXVzdCBzdXBwbHkgdGhpcyBpZiB5b3UgaGF2ZSBnaXZlbiBhIG5vbi1zdGFuZGFyZCBuYW1lIHRvIHRoZSBFQ1IgcmVwb3NpdG9yeS5cbiAgICpcbiAgICogVGhlIHBsYWNlaG9sZGVycyBgJHtRdWFsaWZpZXJ9YCwgYCR7QVdTOjpBY2NvdW50SWR9YCBhbmQgYCR7QVdTOjpSZWdpb259YCB3aWxsXG4gICAqIGJlIHJlcGxhY2VkIHdpdGggdGhlIHZhbHVlcyBvZiBxdWFsaWZpZXIgYW5kIHRoZSBzdGFjaydzIGFjY291bnQgYW5kIHJlZ2lvbixcbiAgICogcmVzcGVjdGl2ZWx5LlxuICAgKlxuICAgKiBAZGVmYXVsdCBEZWZhdWx0U3RhY2tTeW50aGVzaXplci5ERUZBVUxUX0lNQUdFX0FTU0VUU19SRVBPU0lUT1JZX05BTUVcbiAgICovXG4gIHJlYWRvbmx5IGltYWdlQXNzZXRzUmVwb3NpdG9yeU5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSByb2xlIHRvIHVzZSB0byBwdWJsaXNoIGZpbGUgYXNzZXRzIHRvIHRoZSBTMyBidWNrZXQgaW4gdGhpcyBlbnZpcm9ubWVudFxuICAgKlxuICAgKiBZb3UgbXVzdCBzdXBwbHkgdGhpcyBpZiB5b3UgaGF2ZSBnaXZlbiBhIG5vbi1zdGFuZGFyZCBuYW1lIHRvIHRoZSBwdWJsaXNoaW5nIHJvbGUuXG4gICAqXG4gICAqIFRoZSBwbGFjZWhvbGRlcnMgYCR7UXVhbGlmaWVyfWAsIGAke0FXUzo6QWNjb3VudElkfWAgYW5kIGAke0FXUzo6UmVnaW9ufWAgd2lsbFxuICAgKiBiZSByZXBsYWNlZCB3aXRoIHRoZSB2YWx1ZXMgb2YgcXVhbGlmaWVyIGFuZCB0aGUgc3RhY2sncyBhY2NvdW50IGFuZCByZWdpb24sXG4gICAqIHJlc3BlY3RpdmVseS5cbiAgICpcbiAgICogQGRlZmF1bHQgRGVmYXVsdFN0YWNrU3ludGhlc2l6ZXIuREVGQVVMVF9GSUxFX0FTU0VUX1BVQkxJU0hJTkdfUk9MRV9BUk5cbiAgICovXG4gIHJlYWRvbmx5IGZpbGVBc3NldFB1Ymxpc2hpbmdSb2xlQXJuPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBFeHRlcm5hbCBJRCB0byB1c2Ugd2hlbiBhc3N1bWluZyByb2xlIGZvciBmaWxlIGFzc2V0IHB1Ymxpc2hpbmdcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBleHRlcm5hbCBJRFxuICAgKi9cbiAgcmVhZG9ubHkgZmlsZUFzc2V0UHVibGlzaGluZ0V4dGVybmFsSWQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSByb2xlIHRvIHVzZSB0byBwdWJsaXNoIGltYWdlIGFzc2V0cyB0byB0aGUgRUNSIHJlcG9zaXRvcnkgaW4gdGhpcyBlbnZpcm9ubWVudFxuICAgKlxuICAgKiBZb3UgbXVzdCBzdXBwbHkgdGhpcyBpZiB5b3UgaGF2ZSBnaXZlbiBhIG5vbi1zdGFuZGFyZCBuYW1lIHRvIHRoZSBwdWJsaXNoaW5nIHJvbGUuXG4gICAqXG4gICAqIFRoZSBwbGFjZWhvbGRlcnMgYCR7UXVhbGlmaWVyfWAsIGAke0FXUzo6QWNjb3VudElkfWAgYW5kIGAke0FXUzo6UmVnaW9ufWAgd2lsbFxuICAgKiBiZSByZXBsYWNlZCB3aXRoIHRoZSB2YWx1ZXMgb2YgcXVhbGlmaWVyIGFuZCB0aGUgc3RhY2sncyBhY2NvdW50IGFuZCByZWdpb24sXG4gICAqIHJlc3BlY3RpdmVseS5cbiAgICpcbiAgICogQGRlZmF1bHQgRGVmYXVsdFN0YWNrU3ludGhlc2l6ZXIuREVGQVVMVF9JTUFHRV9BU1NFVF9QVUJMSVNISU5HX1JPTEVfQVJOXG4gICAqL1xuICByZWFkb25seSBpbWFnZUFzc2V0UHVibGlzaGluZ1JvbGVBcm4/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSByb2xlIHRvIHVzZSB0byBsb29rIHVwIHZhbHVlcyBmcm9tIHRoZSB0YXJnZXQgQVdTIGFjY291bnQgZHVyaW5nIHN5bnRoZXNpc1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vbmVcbiAgICovXG4gIHJlYWRvbmx5IGxvb2t1cFJvbGVBcm4/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEV4dGVybmFsIElEIHRvIHVzZSB3aGVuIGFzc3VtaW5nIGxvb2t1cCByb2xlXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gZXh0ZXJuYWwgSURcbiAgICovXG4gIHJlYWRvbmx5IGxvb2t1cFJvbGVFeHRlcm5hbElkPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBVc2UgdGhlIGJvb3RzdHJhcHBlZCBsb29rdXAgcm9sZSBmb3IgKHJlYWQtb25seSkgc3RhY2sgb3BlcmF0aW9uc1xuICAgKlxuICAgKiBVc2UgdGhlIGxvb2t1cCByb2xlIHdoZW4gcGVyZm9ybWluZyBhIGBjZGsgZGlmZmAuIElmIHNldCB0byBgZmFsc2VgLCB0aGVcbiAgICogYGRlcGxveSByb2xlYCBjcmVkZW50aWFscyB3aWxsIGJlIHVzZWQgdG8gcGVyZm9ybSBhIGBjZGsgZGlmZmAuXG4gICAqXG4gICAqIFJlcXVpcmVzIGJvb3RzdHJhcCBzdGFjayB2ZXJzaW9uIDguXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IHVzZUxvb2t1cFJvbGVGb3JTdGFja09wZXJhdGlvbnM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBFeHRlcm5hbCBJRCB0byB1c2Ugd2hlbiBhc3N1bWluZyByb2xlIGZvciBpbWFnZSBhc3NldCBwdWJsaXNoaW5nXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gZXh0ZXJuYWwgSURcbiAgICovXG4gIHJlYWRvbmx5IGltYWdlQXNzZXRQdWJsaXNoaW5nRXh0ZXJuYWxJZD86IHN0cmluZztcblxuICAvKipcbiAgICogRXh0ZXJuYWwgSUQgdG8gdXNlIHdoZW4gYXNzdW1pbmcgcm9sZSBmb3IgY2xvdWRmb3JtYXRpb24gZGVwbG95bWVudHNcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBleHRlcm5hbCBJRFxuICAgKi9cbiAgcmVhZG9ubHkgZGVwbG95Um9sZUV4dGVybmFsSWQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSByb2xlIHRvIGFzc3VtZSB0byBpbml0aWF0ZSBhIGRlcGxveW1lbnQgaW4gdGhpcyBlbnZpcm9ubWVudFxuICAgKlxuICAgKiBZb3UgbXVzdCBzdXBwbHkgdGhpcyBpZiB5b3UgaGF2ZSBnaXZlbiBhIG5vbi1zdGFuZGFyZCBuYW1lIHRvIHRoZSBwdWJsaXNoaW5nIHJvbGUuXG4gICAqXG4gICAqIFRoZSBwbGFjZWhvbGRlcnMgYCR7UXVhbGlmaWVyfWAsIGAke0FXUzo6QWNjb3VudElkfWAgYW5kIGAke0FXUzo6UmVnaW9ufWAgd2lsbFxuICAgKiBiZSByZXBsYWNlZCB3aXRoIHRoZSB2YWx1ZXMgb2YgcXVhbGlmaWVyIGFuZCB0aGUgc3RhY2sncyBhY2NvdW50IGFuZCByZWdpb24sXG4gICAqIHJlc3BlY3RpdmVseS5cbiAgICpcbiAgICogQGRlZmF1bHQgRGVmYXVsdFN0YWNrU3ludGhlc2l6ZXIuREVGQVVMVF9ERVBMT1lfUk9MRV9BUk5cbiAgICovXG4gIHJlYWRvbmx5IGRlcGxveVJvbGVBcm4/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSByb2xlIENsb3VkRm9ybWF0aW9uIHdpbGwgYXNzdW1lIHdoZW4gZGVwbG95aW5nIHRoZSBTdGFja1xuICAgKlxuICAgKiBZb3UgbXVzdCBzdXBwbHkgdGhpcyBpZiB5b3UgaGF2ZSBnaXZlbiBhIG5vbi1zdGFuZGFyZCBuYW1lIHRvIHRoZSBleGVjdXRpb24gcm9sZS5cbiAgICpcbiAgICogVGhlIHBsYWNlaG9sZGVycyBgJHtRdWFsaWZpZXJ9YCwgYCR7QVdTOjpBY2NvdW50SWR9YCBhbmQgYCR7QVdTOjpSZWdpb259YCB3aWxsXG4gICAqIGJlIHJlcGxhY2VkIHdpdGggdGhlIHZhbHVlcyBvZiBxdWFsaWZpZXIgYW5kIHRoZSBzdGFjaydzIGFjY291bnQgYW5kIHJlZ2lvbixcbiAgICogcmVzcGVjdGl2ZWx5LlxuICAgKlxuICAgKiBAZGVmYXVsdCBEZWZhdWx0U3RhY2tTeW50aGVzaXplci5ERUZBVUxUX0NMT1VERk9STUFUSU9OX1JPTEVfQVJOXG4gICAqL1xuICByZWFkb25seSBjbG91ZEZvcm1hdGlvbkV4ZWN1dGlvblJvbGU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE5hbWUgb2YgdGhlIENsb3VkRm9ybWF0aW9uIEV4cG9ydCB3aXRoIHRoZSBhc3NldCBrZXkgbmFtZVxuICAgKlxuICAgKiBZb3UgbXVzdCBzdXBwbHkgdGhpcyBpZiB5b3UgaGF2ZSBnaXZlbiBhIG5vbi1zdGFuZGFyZCBuYW1lIHRvIHRoZSBLTVMga2V5IGV4cG9ydFxuICAgKlxuICAgKiBUaGUgcGxhY2Vob2xkZXJzIGAke1F1YWxpZmllcn1gLCBgJHtBV1M6OkFjY291bnRJZH1gIGFuZCBgJHtBV1M6OlJlZ2lvbn1gIHdpbGxcbiAgICogYmUgcmVwbGFjZWQgd2l0aCB0aGUgdmFsdWVzIG9mIHF1YWxpZmllciBhbmQgdGhlIHN0YWNrJ3MgYWNjb3VudCBhbmQgcmVnaW9uLFxuICAgKiByZXNwZWN0aXZlbHkuXG4gICAqXG4gICAqIEBkZWZhdWx0IERlZmF1bHRTdGFja1N5bnRoZXNpemVyLkRFRkFVTFRfRklMRV9BU1NFVF9LRVlfQVJOX0VYUE9SVF9OQU1FXG4gICAqIEBkZXByZWNhdGVkIFRoaXMgcHJvcGVydHkgaXMgbm90IHVzZWQgYW55bW9yZVxuICAgKi9cbiAgcmVhZG9ubHkgZmlsZUFzc2V0S2V5QXJuRXhwb3J0TmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogUXVhbGlmaWVyIHRvIGRpc2FtYmlndWF0ZSBtdWx0aXBsZSBlbnZpcm9ubWVudHMgaW4gdGhlIHNhbWUgYWNjb3VudFxuICAgKlxuICAgKiBZb3UgY2FuIHVzZSB0aGlzIGFuZCBsZWF2ZSB0aGUgb3RoZXIgbmFtaW5nIHByb3BlcnRpZXMgZW1wdHkgaWYgeW91IGhhdmUgZGVwbG95ZWRcbiAgICogdGhlIGJvb3RzdHJhcCBlbnZpcm9ubWVudCB3aXRoIHN0YW5kYXJkIG5hbWVzIGJ1dCBvbmx5IGRpZmZlcm5ldCBxdWFsaWZpZXJzLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFZhbHVlIG9mIGNvbnRleHQga2V5ICdAYXdzLWNkay9jb3JlOmJvb3RzdHJhcFF1YWxpZmllcicgaWYgc2V0LCBvdGhlcndpc2UgYERlZmF1bHRTdGFja1N5bnRoZXNpemVyLkRFRkFVTFRfUVVBTElGSUVSYFxuICAgKi9cbiAgcmVhZG9ubHkgcXVhbGlmaWVyPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGFkZCBhIFJ1bGUgdG8gdGhlIHN0YWNrIHRlbXBsYXRlIHZlcmlmeWluZyB0aGUgYm9vdHN0cmFwIHN0YWNrIHZlcnNpb25cbiAgICpcbiAgICogVGhpcyBnZW5lcmFsbHkgc2hvdWxkIGJlIGxlZnQgc2V0IHRvIGB0cnVlYCwgdW5sZXNzIHlvdSBleHBsaWNpdGx5XG4gICAqIHdhbnQgdG8gYmUgYWJsZSB0byBkZXBsb3kgdG8gYW4gdW5ib290c3RyYXBwZWQgZW52aXJvbm1lbnQuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGdlbmVyYXRlQm9vdHN0cmFwVmVyc2lvblJ1bGU/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBidWNrZXRQcmVmaXggdG8gdXNlIHdoaWxlIHN0b3JpbmcgUzMgQXNzZXRzXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gRGVmYXVsdFN0YWNrU3ludGhlc2l6ZXIuREVGQVVMVF9GSUxFX0FTU0VUX1BSRUZJWFxuICAgKi9cbiAgcmVhZG9ubHkgYnVja2V0UHJlZml4Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIHByZWZpeCB0byB1c2Ugd2hpbGUgdGFnZ2luZyBhbmQgdXBsb2FkaW5nIERvY2tlciBpbWFnZXMgdG8gRUNSLlxuICAgKlxuICAgKiBUaGlzIGRvZXMgbm90IGFkZCBhbnkgc2VwYXJhdG9ycyAtIHRoZSBzb3VyY2UgaGFzaCB3aWxsIGJlIGFwcGVuZGVkIHRvXG4gICAqIHRoaXMgc3RyaW5nIGRpcmVjdGx5LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIERlZmF1bHRTdGFja1N5bnRoZXNpemVyLkRFRkFVTFRfRE9DS0VSX0FTU0VUX1BSRUZJWFxuICAgKi9cbiAgcmVhZG9ubHkgZG9ja2VyVGFnUHJlZml4Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBCb290c3RyYXAgc3RhY2sgdmVyc2lvbiBTU00gcGFyYW1ldGVyLlxuICAgKlxuICAgKiBUaGUgcGxhY2Vob2xkZXIgYCR7UXVhbGlmaWVyfWAgd2lsbCBiZSByZXBsYWNlZCB3aXRoIHRoZSB2YWx1ZSBvZiBxdWFsaWZpZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IERlZmF1bHRTdGFja1N5bnRoZXNpemVyLkRFRkFVTFRfQk9PVFNUUkFQX1NUQUNLX1ZFUlNJT05fU1NNX1BBUkFNRVRFUlxuICAgKi9cbiAgcmVhZG9ubHkgYm9vdHN0cmFwU3RhY2tWZXJzaW9uU3NtUGFyYW1ldGVyPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFVzZXMgY29udmVudGlvbmFsbHkgbmFtZWQgcm9sZXMgYW5kIGFzc2V0IHN0b3JhZ2UgbG9jYXRpb25zXG4gKlxuICogVGhpcyBzeW50aGVzaXplcjpcbiAqXG4gKiAtIFN1cHBvcnRzIGNyb3NzLWFjY291bnQgZGVwbG95bWVudHMgKHRoZSBDTEkgY2FuIGhhdmUgY3JlZGVudGlhbHMgdG8gb25lXG4gKiAgIGFjY291bnQsIGFuZCB5b3UgY2FuIHN0aWxsIGRlcGxveSB0byBhbm90aGVyIGFjY291bnQgYnkgYXNzdW1pbmcgcm9sZXMgd2l0aFxuICogICB3ZWxsLWtub3duIG5hbWVzIGluIHRoZSBvdGhlciBhY2NvdW50KS5cbiAqIC0gU3VwcG9ydHMgdGhlICoqQ0RLIFBpcGVsaW5lcyoqIGxpYnJhcnkuXG4gKlxuICogUmVxdWlyZXMgdGhlIGVudmlyb25tZW50IHRvIGhhdmUgYmVlbiBib290c3RyYXBwZWQgd2l0aCBCb290c3RyYXAgU3RhY2sgVjJcbiAqIChhbHNvIGtub3duIGFzIFwibW9kZXJuIGJvb3RzdHJhcCBzdGFja1wiKS4gVGhlIHN5bnRoZXNpemVyIGFkZHMgYSB2ZXJzaW9uXG4gKiBjaGVjayB0byB0aGUgdGVtcGxhdGUsIHRvIG1ha2Ugc3VyZSB0aGUgYm9vdHN0cmFwIHN0YWNrIGlzIHJlY2VudCBlbm91Z2hcbiAqIHRvIHN1cHBvcnQgYWxsIGZlYXR1cmVzIGV4cGVjdGVkIGJ5IHRoaXMgc3ludGhlc2l6ZXIuXG4gKi9cbmV4cG9ydCBjbGFzcyBEZWZhdWx0U3RhY2tTeW50aGVzaXplciBleHRlbmRzIFN0YWNrU3ludGhlc2l6ZXIge1xuICAvKipcbiAgICogRGVmYXVsdCBBUk4gcXVhbGlmaWVyXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfUVVBTElGSUVSID0gJ2huYjY1OWZkcyc7XG5cbiAgLyoqXG4gICAqIERlZmF1bHQgQ2xvdWRGb3JtYXRpb24gcm9sZSBBUk4uXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfQ0xPVURGT1JNQVRJT05fUk9MRV9BUk4gPSAnYXJuOiR7QVdTOjpQYXJ0aXRpb259OmlhbTo6JHtBV1M6OkFjY291bnRJZH06cm9sZS9jZGstJHtRdWFsaWZpZXJ9LWNmbi1leGVjLXJvbGUtJHtBV1M6OkFjY291bnRJZH0tJHtBV1M6OlJlZ2lvbn0nO1xuXG4gIC8qKlxuICAgKiBEZWZhdWx0IGRlcGxveSByb2xlIEFSTi5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9ERVBMT1lfUk9MRV9BUk4gPSAnYXJuOiR7QVdTOjpQYXJ0aXRpb259OmlhbTo6JHtBV1M6OkFjY291bnRJZH06cm9sZS9jZGstJHtRdWFsaWZpZXJ9LWRlcGxveS1yb2xlLSR7QVdTOjpBY2NvdW50SWR9LSR7QVdTOjpSZWdpb259JztcblxuICAvKipcbiAgICogRGVmYXVsdCBhc3NldCBwdWJsaXNoaW5nIHJvbGUgQVJOIGZvciBmaWxlIChTMykgYXNzZXRzLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBERUZBVUxUX0ZJTEVfQVNTRVRfUFVCTElTSElOR19ST0xFX0FSTiA9ICdhcm46JHtBV1M6OlBhcnRpdGlvbn06aWFtOjoke0FXUzo6QWNjb3VudElkfTpyb2xlL2Nkay0ke1F1YWxpZmllcn0tZmlsZS1wdWJsaXNoaW5nLXJvbGUtJHtBV1M6OkFjY291bnRJZH0tJHtBV1M6OlJlZ2lvbn0nO1xuXG4gIC8qKlxuICAgKiBEZWZhdWx0IGFzc2V0IHB1Ymxpc2hpbmcgcm9sZSBBUk4gZm9yIGltYWdlIChFQ1IpIGFzc2V0cy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9JTUFHRV9BU1NFVF9QVUJMSVNISU5HX1JPTEVfQVJOID0gJ2Fybjoke0FXUzo6UGFydGl0aW9ufTppYW06OiR7QVdTOjpBY2NvdW50SWR9OnJvbGUvY2RrLSR7UXVhbGlmaWVyfS1pbWFnZS1wdWJsaXNoaW5nLXJvbGUtJHtBV1M6OkFjY291bnRJZH0tJHtBV1M6OlJlZ2lvbn0nO1xuXG4gIC8qKlxuICAgKiBEZWZhdWx0IGxvb2t1cCByb2xlIEFSTiBmb3IgbWlzc2luZyB2YWx1ZXMuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfTE9PS1VQX1JPTEVfQVJOID0gJ2Fybjoke0FXUzo6UGFydGl0aW9ufTppYW06OiR7QVdTOjpBY2NvdW50SWR9OnJvbGUvY2RrLSR7UXVhbGlmaWVyfS1sb29rdXAtcm9sZS0ke0FXUzo6QWNjb3VudElkfS0ke0FXUzo6UmVnaW9ufSc7XG5cbiAgLyoqXG4gICAqIERlZmF1bHQgaW1hZ2UgYXNzZXRzIHJlcG9zaXRvcnkgbmFtZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBERUZBVUxUX0lNQUdFX0FTU0VUU19SRVBPU0lUT1JZX05BTUUgPSAnY2RrLSR7UXVhbGlmaWVyfS1jb250YWluZXItYXNzZXRzLSR7QVdTOjpBY2NvdW50SWR9LSR7QVdTOjpSZWdpb259JztcblxuICAvKipcbiAgICogRGVmYXVsdCBmaWxlIGFzc2V0cyBidWNrZXQgbmFtZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBERUZBVUxUX0ZJTEVfQVNTRVRTX0JVQ0tFVF9OQU1FID0gJ2Nkay0ke1F1YWxpZmllcn0tYXNzZXRzLSR7QVdTOjpBY2NvdW50SWR9LSR7QVdTOjpSZWdpb259JztcblxuICAvKipcbiAgICogTmFtZSBvZiB0aGUgQ2xvdWRGb3JtYXRpb24gRXhwb3J0IHdpdGggdGhlIGFzc2V0IGtleSBuYW1lXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfRklMRV9BU1NFVF9LRVlfQVJOX0VYUE9SVF9OQU1FID0gJ0Nka0Jvb3RzdHJhcC0ke1F1YWxpZmllcn0tRmlsZUFzc2V0S2V5QXJuJztcblxuICAvKipcbiAgICogRGVmYXVsdCBmaWxlIGFzc2V0IHByZWZpeFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBERUZBVUxUX0ZJTEVfQVNTRVRfUFJFRklYID0gJyc7XG4gIC8qKlxuICAgKiBEZWZhdWx0IERvY2tlciBhc3NldCBwcmVmaXhcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9ET0NLRVJfQVNTRVRfUFJFRklYID0gJyc7XG5cbiAgLyoqXG4gICAqIERlZmF1bHQgYm9vdHN0cmFwIHN0YWNrIHZlcnNpb24gU1NNIHBhcmFtZXRlci5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9CT09UU1RSQVBfU1RBQ0tfVkVSU0lPTl9TU01fUEFSQU1FVEVSID0gJy9jZGstYm9vdHN0cmFwLyR7UXVhbGlmaWVyfS92ZXJzaW9uJztcblxuICBwcml2YXRlIF9zdGFjaz86IFN0YWNrO1xuICBwcml2YXRlIGJ1Y2tldE5hbWU/OiBzdHJpbmc7XG4gIHByaXZhdGUgcmVwb3NpdG9yeU5hbWU/OiBzdHJpbmc7XG4gIHByaXZhdGUgX2RlcGxveVJvbGVBcm4/OiBzdHJpbmc7XG4gIHByaXZhdGUgX2Nsb3VkRm9ybWF0aW9uRXhlY3V0aW9uUm9sZUFybj86IHN0cmluZztcbiAgcHJpdmF0ZSBmaWxlQXNzZXRQdWJsaXNoaW5nUm9sZUFybj86IHN0cmluZztcbiAgcHJpdmF0ZSBpbWFnZUFzc2V0UHVibGlzaGluZ1JvbGVBcm4/OiBzdHJpbmc7XG4gIHByaXZhdGUgbG9va3VwUm9sZUFybj86IHN0cmluZztcbiAgcHJpdmF0ZSB1c2VMb29rdXBSb2xlRm9yU3RhY2tPcGVyYXRpb25zOiBib29sZWFuO1xuICBwcml2YXRlIHF1YWxpZmllcj86IHN0cmluZztcbiAgcHJpdmF0ZSBidWNrZXRQcmVmaXg/OiBzdHJpbmc7XG4gIHByaXZhdGUgZG9ja2VyVGFnUHJlZml4Pzogc3RyaW5nO1xuICBwcml2YXRlIGJvb3RzdHJhcFN0YWNrVmVyc2lvblNzbVBhcmFtZXRlcj86IHN0cmluZztcblxuICBwcml2YXRlIGFzc2V0TWFuaWZlc3QgPSBuZXcgQXNzZXRNYW5pZmVzdEJ1aWxkZXIoKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHByb3BzOiBEZWZhdWx0U3RhY2tTeW50aGVzaXplclByb3BzID0ge30pIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMudXNlTG9va3VwUm9sZUZvclN0YWNrT3BlcmF0aW9ucyA9IHByb3BzLnVzZUxvb2t1cFJvbGVGb3JTdGFja09wZXJhdGlvbnMgPz8gdHJ1ZTtcblxuICAgIGZvciAoY29uc3Qga2V5IGluIHByb3BzKSB7XG4gICAgICBpZiAocHJvcHMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICB2YWxpZGF0ZU5vVG9rZW4oa2V5IGFzIGtleW9mIERlZmF1bHRTdGFja1N5bnRoZXNpemVyUHJvcHMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHZhbGlkYXRlTm9Ub2tlbjxBIGV4dGVuZHMga2V5b2YgRGVmYXVsdFN0YWNrU3ludGhlc2l6ZXJQcm9wcz4oa2V5OiBBKSB7XG4gICAgICBjb25zdCBwcm9wID0gcHJvcHNba2V5XTtcbiAgICAgIGlmICh0eXBlb2YgcHJvcCA9PT0gJ3N0cmluZycgJiYgVG9rZW4uaXNVbnJlc29sdmVkKHByb3ApKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRGVmYXVsdFN5bnRoZXNpemVyIHByb3BlcnR5ICcke2tleX0nIGNhbm5vdCBjb250YWluIHRva2Vuczsgb25seSB0aGUgZm9sbG93aW5nIHBsYWNlaG9sZGVyIHN0cmluZ3MgYXJlIGFsbG93ZWQ6IGAgKyBbXG4gICAgICAgICAgJyR7UXVhbGlmaWVyfScsXG4gICAgICAgICAgY3hhcGkuRW52aXJvbm1lbnRQbGFjZWhvbGRlcnMuQ1VSUkVOVF9SRUdJT04sXG4gICAgICAgICAgY3hhcGkuRW52aXJvbm1lbnRQbGFjZWhvbGRlcnMuQ1VSUkVOVF9BQ0NPVU5ULFxuICAgICAgICAgIGN4YXBpLkVudmlyb25tZW50UGxhY2Vob2xkZXJzLkNVUlJFTlRfUEFSVElUSU9OLFxuICAgICAgICBdLmpvaW4oJywgJykpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBiaW5kKHN0YWNrOiBTdGFjayk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9zdGFjayAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgU3RhY2tTeW50aGVzaXplciBjYW4gb25seSBiZSB1c2VkIGZvciBvbmUgU3RhY2s6IGNyZWF0ZSBhIG5ldyBpbnN0YW5jZSB0byB1c2Ugd2l0aCBhIGRpZmZlcmVudCBTdGFjaycpO1xuICAgIH1cblxuICAgIHRoaXMuX3N0YWNrID0gc3RhY2s7XG5cbiAgICBjb25zdCBxdWFsaWZpZXIgPSB0aGlzLnByb3BzLnF1YWxpZmllciA/PyBzdGFjay5ub2RlLnRyeUdldENvbnRleHQoQk9PVFNUUkFQX1FVQUxJRklFUl9DT05URVhUKSA/PyBEZWZhdWx0U3RhY2tTeW50aGVzaXplci5ERUZBVUxUX1FVQUxJRklFUjtcbiAgICB0aGlzLnF1YWxpZmllciA9IHF1YWxpZmllcjtcblxuICAgIGNvbnN0IHNwZWMgPSBuZXcgU3RyaW5nU3BlY2lhbGl6ZXIoc3RhY2ssIHF1YWxpZmllcik7XG5cbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG4gICAgdGhpcy5idWNrZXROYW1lID0gc3BlYy5zcGVjaWFsaXplKHRoaXMucHJvcHMuZmlsZUFzc2V0c0J1Y2tldE5hbWUgPz8gRGVmYXVsdFN0YWNrU3ludGhlc2l6ZXIuREVGQVVMVF9GSUxFX0FTU0VUU19CVUNLRVRfTkFNRSk7XG4gICAgdGhpcy5yZXBvc2l0b3J5TmFtZSA9IHNwZWMuc3BlY2lhbGl6ZSh0aGlzLnByb3BzLmltYWdlQXNzZXRzUmVwb3NpdG9yeU5hbWUgPz8gRGVmYXVsdFN0YWNrU3ludGhlc2l6ZXIuREVGQVVMVF9JTUFHRV9BU1NFVFNfUkVQT1NJVE9SWV9OQU1FKTtcbiAgICB0aGlzLl9kZXBsb3lSb2xlQXJuID0gc3BlYy5zcGVjaWFsaXplKHRoaXMucHJvcHMuZGVwbG95Um9sZUFybiA/PyBEZWZhdWx0U3RhY2tTeW50aGVzaXplci5ERUZBVUxUX0RFUExPWV9ST0xFX0FSTik7XG4gICAgdGhpcy5fY2xvdWRGb3JtYXRpb25FeGVjdXRpb25Sb2xlQXJuID0gc3BlYy5zcGVjaWFsaXplKHRoaXMucHJvcHMuY2xvdWRGb3JtYXRpb25FeGVjdXRpb25Sb2xlID8/IERlZmF1bHRTdGFja1N5bnRoZXNpemVyLkRFRkFVTFRfQ0xPVURGT1JNQVRJT05fUk9MRV9BUk4pO1xuICAgIHRoaXMuZmlsZUFzc2V0UHVibGlzaGluZ1JvbGVBcm4gPSBzcGVjLnNwZWNpYWxpemUodGhpcy5wcm9wcy5maWxlQXNzZXRQdWJsaXNoaW5nUm9sZUFybiA/PyBEZWZhdWx0U3RhY2tTeW50aGVzaXplci5ERUZBVUxUX0ZJTEVfQVNTRVRfUFVCTElTSElOR19ST0xFX0FSTik7XG4gICAgdGhpcy5pbWFnZUFzc2V0UHVibGlzaGluZ1JvbGVBcm4gPSBzcGVjLnNwZWNpYWxpemUodGhpcy5wcm9wcy5pbWFnZUFzc2V0UHVibGlzaGluZ1JvbGVBcm4gPz8gRGVmYXVsdFN0YWNrU3ludGhlc2l6ZXIuREVGQVVMVF9JTUFHRV9BU1NFVF9QVUJMSVNISU5HX1JPTEVfQVJOKTtcbiAgICB0aGlzLmxvb2t1cFJvbGVBcm4gPSBzcGVjLnNwZWNpYWxpemUodGhpcy5wcm9wcy5sb29rdXBSb2xlQXJuID8/IERlZmF1bHRTdGFja1N5bnRoZXNpemVyLkRFRkFVTFRfTE9PS1VQX1JPTEVfQVJOKTtcbiAgICB0aGlzLmJ1Y2tldFByZWZpeCA9IHNwZWMuc3BlY2lhbGl6ZSh0aGlzLnByb3BzLmJ1Y2tldFByZWZpeCA/PyBEZWZhdWx0U3RhY2tTeW50aGVzaXplci5ERUZBVUxUX0ZJTEVfQVNTRVRfUFJFRklYKTtcbiAgICB0aGlzLmRvY2tlclRhZ1ByZWZpeCA9IHNwZWMuc3BlY2lhbGl6ZSh0aGlzLnByb3BzLmRvY2tlclRhZ1ByZWZpeCA/PyBEZWZhdWx0U3RhY2tTeW50aGVzaXplci5ERUZBVUxUX0RPQ0tFUl9BU1NFVF9QUkVGSVgpO1xuICAgIHRoaXMuYm9vdHN0cmFwU3RhY2tWZXJzaW9uU3NtUGFyYW1ldGVyID0gc3BlYy5xdWFsaWZpZXJPbmx5KHRoaXMucHJvcHMuYm9vdHN0cmFwU3RhY2tWZXJzaW9uU3NtUGFyYW1ldGVyID8/IERlZmF1bHRTdGFja1N5bnRoZXNpemVyLkRFRkFVTFRfQk9PVFNUUkFQX1NUQUNLX1ZFUlNJT05fU1NNX1BBUkFNRVRFUik7XG4gICAgLyogZXNsaW50LWVuYWJsZSBtYXgtbGVuICovXG4gIH1cblxuICBwdWJsaWMgYWRkRmlsZUFzc2V0KGFzc2V0OiBGaWxlQXNzZXRTb3VyY2UpOiBGaWxlQXNzZXRMb2NhdGlvbiB7XG4gICAgYXNzZXJ0Qm91bmQodGhpcy5zdGFjayk7XG4gICAgYXNzZXJ0Qm91bmQodGhpcy5idWNrZXROYW1lKTtcbiAgICBhc3NlcnRCb3VuZCh0aGlzLmJ1Y2tldFByZWZpeCk7XG5cbiAgICByZXR1cm4gdGhpcy5hc3NldE1hbmlmZXN0LmFkZEZpbGVBc3NldERlZmF1bHQoYXNzZXQsIHRoaXMuc3RhY2ssIHRoaXMuYnVja2V0TmFtZSwgdGhpcy5idWNrZXRQcmVmaXgsIHtcbiAgICAgIGFzc3VtZVJvbGVBcm46IHRoaXMuZmlsZUFzc2V0UHVibGlzaGluZ1JvbGVBcm4sXG4gICAgICBhc3N1bWVSb2xlRXh0ZXJuYWxJZDogdGhpcy5wcm9wcy5maWxlQXNzZXRQdWJsaXNoaW5nRXh0ZXJuYWxJZCxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhZGREb2NrZXJJbWFnZUFzc2V0KGFzc2V0OiBEb2NrZXJJbWFnZUFzc2V0U291cmNlKTogRG9ja2VySW1hZ2VBc3NldExvY2F0aW9uIHtcbiAgICBhc3NlcnRCb3VuZCh0aGlzLnN0YWNrKTtcbiAgICBhc3NlcnRCb3VuZCh0aGlzLnJlcG9zaXRvcnlOYW1lKTtcbiAgICBhc3NlcnRCb3VuZCh0aGlzLmRvY2tlclRhZ1ByZWZpeCk7XG5cbiAgICByZXR1cm4gdGhpcy5hc3NldE1hbmlmZXN0LmFkZERvY2tlckltYWdlQXNzZXREZWZhdWx0KGFzc2V0LCB0aGlzLnN0YWNrLCB0aGlzLnJlcG9zaXRvcnlOYW1lLCB0aGlzLmRvY2tlclRhZ1ByZWZpeCwge1xuICAgICAgYXNzdW1lUm9sZUFybjogdGhpcy5pbWFnZUFzc2V0UHVibGlzaGluZ1JvbGVBcm4sXG4gICAgICBhc3N1bWVSb2xlRXh0ZXJuYWxJZDogdGhpcy5wcm9wcy5pbWFnZUFzc2V0UHVibGlzaGluZ0V4dGVybmFsSWQsXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc3ludGhlc2l6ZVN0YWNrVGVtcGxhdGUoc3RhY2s6IFN0YWNrLCBzZXNzaW9uOiBJU3ludGhlc2lzU2Vzc2lvbikge1xuICAgIHN0YWNrLl9zeW50aGVzaXplVGVtcGxhdGUoc2Vzc2lvbiwgdGhpcy5sb29rdXBSb2xlQXJuKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTeW50aGVzaXplIHRoZSBhc3NvY2lhdGVkIHN0YWNrIHRvIHRoZSBzZXNzaW9uXG4gICAqL1xuICBwdWJsaWMgc3ludGhlc2l6ZShzZXNzaW9uOiBJU3ludGhlc2lzU2Vzc2lvbik6IHZvaWQge1xuICAgIGFzc2VydEJvdW5kKHRoaXMuc3RhY2spO1xuICAgIGFzc2VydEJvdW5kKHRoaXMucXVhbGlmaWVyKTtcblxuICAgIC8vIE11c3QgYmUgZG9uZSBoZXJlIC0tIGlmIGl0J3MgZG9uZSBpbiBiaW5kKCkgKGNhbGxlZCBpbiB0aGUgU3RhY2sncyBjb25zdHJ1Y3RvcilcbiAgICAvLyB0aGVuIGl0IHdpbGwgYmVjb21lIGltcG9zc2libGUgdG8gc2V0IGNvbnRleHQgYWZ0ZXIgdGhhdC5cbiAgICAvL1xuICAgIC8vIElmIGl0J3MgZG9uZSBBRlRFUiBfc3ludGhlc2l6ZVRlbXBsYXRlKCksIHRoZW4gdGhlIHRlbXBsYXRlIHdvbid0IGNvbnRhaW4gdGhlXG4gICAgLy8gcmlnaHQgY29uc3RydWN0cy5cbiAgICBpZiAodGhpcy5wcm9wcy5nZW5lcmF0ZUJvb3RzdHJhcFZlcnNpb25SdWxlID8/IHRydWUpIHtcbiAgICAgIGFkZEJvb3RzdHJhcFZlcnNpb25SdWxlKHRoaXMuc3RhY2ssIE1JTl9CT09UU1RSQVBfU1RBQ0tfVkVSU0lPTiwgPHN0cmluZz4gdGhpcy5ib290c3RyYXBTdGFja1ZlcnNpb25Tc21QYXJhbWV0ZXIpO1xuICAgIH1cblxuICAgIHRoaXMuc3ludGhlc2l6ZVN0YWNrVGVtcGxhdGUodGhpcy5zdGFjaywgc2Vzc2lvbik7XG5cbiAgICBjb25zdCB0ZW1wbGF0ZUFzc2V0ID0gdGhpcy5hZGRGaWxlQXNzZXQoc3RhY2tUZW1wbGF0ZUZpbGVBc3NldCh0aGlzLnN0YWNrLCBzZXNzaW9uKSk7XG5cbiAgICBjb25zdCBhc3NldE1hbmlmZXN0SWQgPSB0aGlzLmFzc2V0TWFuaWZlc3Qud3JpdGVNYW5pZmVzdCh0aGlzLnN0YWNrLCBzZXNzaW9uLCB7XG4gICAgICByZXF1aXJlc0Jvb3RzdHJhcFN0YWNrVmVyc2lvbjogTUlOX0JPT1RTVFJBUF9TVEFDS19WRVJTSU9OLFxuICAgICAgYm9vdHN0cmFwU3RhY2tWZXJzaW9uU3NtUGFyYW1ldGVyOiB0aGlzLmJvb3RzdHJhcFN0YWNrVmVyc2lvblNzbVBhcmFtZXRlcixcbiAgICB9KTtcblxuICAgIHRoaXMuZW1pdFN0YWNrQXJ0aWZhY3QodGhpcy5zdGFjaywgc2Vzc2lvbiwge1xuICAgICAgYXNzdW1lUm9sZUV4dGVybmFsSWQ6IHRoaXMucHJvcHMuZGVwbG95Um9sZUV4dGVybmFsSWQsXG4gICAgICBhc3N1bWVSb2xlQXJuOiB0aGlzLl9kZXBsb3lSb2xlQXJuLFxuICAgICAgY2xvdWRGb3JtYXRpb25FeGVjdXRpb25Sb2xlQXJuOiB0aGlzLl9jbG91ZEZvcm1hdGlvbkV4ZWN1dGlvblJvbGVBcm4sXG4gICAgICBzdGFja1RlbXBsYXRlQXNzZXRPYmplY3RVcmw6IHRlbXBsYXRlQXNzZXQuczNPYmplY3RVcmxXaXRoUGxhY2Vob2xkZXJzLFxuICAgICAgcmVxdWlyZXNCb290c3RyYXBTdGFja1ZlcnNpb246IE1JTl9CT09UU1RSQVBfU1RBQ0tfVkVSU0lPTixcbiAgICAgIGJvb3RzdHJhcFN0YWNrVmVyc2lvblNzbVBhcmFtZXRlcjogdGhpcy5ib290c3RyYXBTdGFja1ZlcnNpb25Tc21QYXJhbWV0ZXIsXG4gICAgICBhZGRpdGlvbmFsRGVwZW5kZW5jaWVzOiBbYXNzZXRNYW5pZmVzdElkXSxcbiAgICAgIGxvb2t1cFJvbGU6IHRoaXMudXNlTG9va3VwUm9sZUZvclN0YWNrT3BlcmF0aW9ucyAmJiB0aGlzLmxvb2t1cFJvbGVBcm4gPyB7XG4gICAgICAgIGFybjogdGhpcy5sb29rdXBSb2xlQXJuLFxuICAgICAgICBhc3N1bWVSb2xlRXh0ZXJuYWxJZDogdGhpcy5wcm9wcy5sb29rdXBSb2xlRXh0ZXJuYWxJZCxcbiAgICAgICAgcmVxdWlyZXNCb290c3RyYXBTdGFja1ZlcnNpb246IE1JTl9MT09LVVBfUk9MRV9CT09UU1RSQVBfU1RBQ0tfVkVSU0lPTixcbiAgICAgICAgYm9vdHN0cmFwU3RhY2tWZXJzaW9uU3NtUGFyYW1ldGVyOiB0aGlzLmJvb3RzdHJhcFN0YWNrVmVyc2lvblNzbVBhcmFtZXRlcixcbiAgICAgIH0gOiB1bmRlZmluZWQsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgQVJOIG9mIHRoZSBkZXBsb3kgUm9sZS5cbiAgICovXG4gIHB1YmxpYyBnZXQgZGVwbG95Um9sZUFybigpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5fZGVwbG95Um9sZUFybikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdkZXBsb3lSb2xlQXJuIGdldHRlciBjYW4gb25seSBiZSBjYWxsZWQgYWZ0ZXIgdGhlIHN5bnRoZXNpemVyIGhhcyBiZWVuIGJvdW5kIHRvIGEgU3RhY2snKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2RlcGxveVJvbGVBcm47XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgQVJOIG9mIHRoZSBDRk4gZXhlY3V0aW9uIFJvbGUuXG4gICAqL1xuICBwdWJsaWMgZ2V0IGNsb3VkRm9ybWF0aW9uRXhlY3V0aW9uUm9sZUFybigpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5fY2xvdWRGb3JtYXRpb25FeGVjdXRpb25Sb2xlQXJuKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nsb3VkRm9ybWF0aW9uRXhlY3V0aW9uUm9sZUFybiBnZXR0ZXIgY2FuIG9ubHkgYmUgY2FsbGVkIGFmdGVyIHRoZSBzeW50aGVzaXplciBoYXMgYmVlbiBib3VuZCB0byBhIFN0YWNrJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jbG91ZEZvcm1hdGlvbkV4ZWN1dGlvblJvbGVBcm47XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IHN0YWNrKCk6IFN0YWNrIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhY2s7XG4gIH1cbn1cblxuLyoqXG4gKiBBZGQgYSBDZm5SdWxlIHRvIHRoZSBTdGFjayB3aGljaCBjaGVja3MgdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGUgYm9vdHN0cmFwIHN0YWNrIHRoaXMgdGVtcGxhdGUgaXMgdGFyZ2V0aW5nXG4gKlxuICogVGhlIENMSSBub3JtYWxseSBjaGVja3MgdGhpcywgYnV0IGluIGEgcGlwZWxpbmUgdGhlIENMSSBpcyBub3QgaW52b2x2ZWRcbiAqIHNvIHdlIGVuY29kZSB0aGlzIHJ1bGUgaW50byB0aGUgdGVtcGxhdGUgaW4gYSB3YXkgdGhhdCBDbG91ZEZvcm1hdGlvbiB3aWxsIGNoZWNrIGl0LlxuICovXG5mdW5jdGlvbiBhZGRCb290c3RyYXBWZXJzaW9uUnVsZShzdGFjazogU3RhY2ssIHJlcXVpcmVkVmVyc2lvbjogbnVtYmVyLCBib290c3RyYXBTdGFja1ZlcnNpb25Tc21QYXJhbWV0ZXI6IHN0cmluZykge1xuICAvLyBCZWNhdXNlIG9mIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYXdzLWNkay9ibG9iL21hc3Rlci9wYWNrYWdlcy9hc3NlcnQtaW50ZXJuYWwvbGliL3N5bnRoLXV0aWxzLnRzI0w3NFxuICAvLyBzeW50aGVzaXplKCkgbWF5IGJlIGNhbGxlZCBtb3JlIHRoYW4gb25jZSBvbiBhIHN0YWNrIGluIHVuaXQgdGVzdHMsIGFuZCB0aGUgYmVsb3cgd291bGQgYnJlYWtcbiAgLy8gaWYgd2UgZXhlY3V0ZSBpdCBhIHNlY29uZCB0aW1lLiBHdWFyZCBhZ2FpbnN0IHRoZSBjb25zdHJ1Y3RzIGFscmVhZHkgZXhpc3RpbmcuXG4gIGlmIChzdGFjay5ub2RlLnRyeUZpbmRDaGlsZCgnQm9vdHN0cmFwVmVyc2lvbicpKSB7IHJldHVybjsgfVxuXG4gIGNvbnN0IHBhcmFtID0gbmV3IENmblBhcmFtZXRlcihzdGFjaywgJ0Jvb3RzdHJhcFZlcnNpb24nLCB7XG4gICAgdHlwZTogJ0FXUzo6U1NNOjpQYXJhbWV0ZXI6OlZhbHVlPFN0cmluZz4nLFxuICAgIGRlc2NyaXB0aW9uOiBgVmVyc2lvbiBvZiB0aGUgQ0RLIEJvb3RzdHJhcCByZXNvdXJjZXMgaW4gdGhpcyBlbnZpcm9ubWVudCwgYXV0b21hdGljYWxseSByZXRyaWV2ZWQgZnJvbSBTU00gUGFyYW1ldGVyIFN0b3JlLiAke2N4YXBpLlNTTVBBUkFNX05PX0lOVkFMSURBVEV9YCxcbiAgICBkZWZhdWx0OiBib290c3RyYXBTdGFja1ZlcnNpb25Tc21QYXJhbWV0ZXIsXG4gIH0pO1xuXG4gIC8vIFRoZXJlIGlzIG5vID49IGNoZWNrIGluIENsb3VkRm9ybWF0aW9uLCBzbyB3ZSBoYXZlIHRvIGNoZWNrIHRoZSBudW1iZXJcbiAgLy8gaXMgTk9UIGluIFsxLCAyLCAzLCAuLi4gPHJlcXVpcmVkPiAtIDFdXG4gIGNvbnN0IG9sZFZlcnNpb25zID0gcmFuZ2UoMSwgcmVxdWlyZWRWZXJzaW9uKS5tYXAobiA9PiBgJHtufWApO1xuXG4gIG5ldyBDZm5SdWxlKHN0YWNrLCAnQ2hlY2tCb290c3RyYXBWZXJzaW9uJywge1xuICAgIGFzc2VydGlvbnM6IFtcbiAgICAgIHtcbiAgICAgICAgYXNzZXJ0OiBGbi5jb25kaXRpb25Ob3QoRm4uY29uZGl0aW9uQ29udGFpbnMob2xkVmVyc2lvbnMsIHBhcmFtLnZhbHVlQXNTdHJpbmcpKSxcbiAgICAgICAgYXNzZXJ0RGVzY3JpcHRpb246IGBDREsgYm9vdHN0cmFwIHN0YWNrIHZlcnNpb24gJHtyZXF1aXJlZFZlcnNpb259IHJlcXVpcmVkLiBQbGVhc2UgcnVuICdjZGsgYm9vdHN0cmFwJyB3aXRoIGEgcmVjZW50IHZlcnNpb24gb2YgdGhlIENESyBDTEkuYCxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHJhbmdlKHN0YXJ0SW5jbDogbnVtYmVyLCBlbmRFeGNsOiBudW1iZXIpIHtcbiAgY29uc3QgcmV0ID0gbmV3IEFycmF5PG51bWJlcj4oKTtcbiAgZm9yIChsZXQgaSA9IHN0YXJ0SW5jbDsgaSA8IGVuZEV4Y2w7IGkrKykge1xuICAgIHJldC5wdXNoKGkpO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbiJdfQ==