aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
337 lines • 64.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CloudFormationDeployments = exports.Deployments = void 0;
const cdk_assets = require("cdk-assets");
const cdk_assets_1 = require("cdk-assets");
const credentials_1 = require("./aws-auth/credentials");
const deploy_stack_1 = require("./deploy-stack");
const environment_resources_1 = require("./environment-resources");
const nested_stack_helpers_1 = require("./nested-stack-helpers");
const cloudformation_1 = require("./util/cloudformation");
const placeholders_1 = require("./util/placeholders");
const logging_1 = require("../logging");
const asset_publishing_1 = require("../util/asset-publishing");
/**
* Scope for a single set of deployments from a set of Cloud Assembly Artifacts
*
* Manages lookup of SDKs, Bootstrap stacks, etc.
*/
class Deployments {
constructor(props) {
this.props = props;
this.sdkCache = new Map();
this.publisherCache = new Map();
this.sdkProvider = props.sdkProvider;
this.environmentResources = new environment_resources_1.EnvironmentResourcesRegistry(props.toolkitStackName);
}
async readCurrentTemplateWithNestedStacks(rootStackArtifact, retrieveProcessedTemplate = false) {
const sdk = (await this.prepareSdkWithLookupOrDeployRole(rootStackArtifact)).stackSdk;
const templateWithNestedStacks = await (0, nested_stack_helpers_1.loadCurrentTemplateWithNestedStacks)(rootStackArtifact, sdk, retrieveProcessedTemplate);
return {
deployedTemplate: templateWithNestedStacks.deployedTemplate,
nestedStackCount: (0, nested_stack_helpers_1.flattenNestedStackNames)(templateWithNestedStacks.nestedStackNames).length,
};
}
async readCurrentTemplate(stackArtifact) {
(0, logging_1.debug)(`Reading existing template for stack ${stackArtifact.displayName}.`);
const sdk = (await this.prepareSdkWithLookupOrDeployRole(stackArtifact)).stackSdk;
return (0, nested_stack_helpers_1.loadCurrentTemplate)(stackArtifact, sdk);
}
async resourceIdentifierSummaries(stackArtifact) {
(0, logging_1.debug)(`Retrieving template summary for stack ${stackArtifact.displayName}.`);
// Currently, needs to use `deploy-role` since it may need to read templates in the staging
// bucket which have been encrypted with a KMS key (and lookup-role may not read encrypted things)
const { stackSdk, resolvedEnvironment, envResources } = await this.prepareSdkFor(stackArtifact, undefined, credentials_1.Mode.ForReading);
const cfn = stackSdk.cloudFormation();
// Upload the template, if necessary, before passing it to CFN
const cfnParam = await (0, deploy_stack_1.makeBodyParameterAndUpload)(stackArtifact, resolvedEnvironment, envResources, this.sdkProvider, stackSdk);
const response = await cfn.getTemplateSummary(cfnParam).promise();
if (!response.ResourceIdentifierSummaries) {
(0, logging_1.debug)('GetTemplateSummary API call did not return "ResourceIdentifierSummaries"');
}
return response.ResourceIdentifierSummaries ?? [];
}
async deployStack(options) {
let deploymentMethod = options.deploymentMethod;
if (options.changeSetName || options.execute !== undefined) {
if (deploymentMethod) {
throw new Error('You cannot supply both \'deploymentMethod\' and \'changeSetName/execute\'. Supply one or the other.');
}
deploymentMethod = {
method: 'change-set',
changeSetName: options.changeSetName,
execute: options.execute,
};
}
const { stackSdk, resolvedEnvironment, cloudFormationRoleArn, envResources, } = await this.prepareSdkFor(options.stack, options.roleArn, credentials_1.Mode.ForWriting);
// Do a verification of the bootstrap stack version
await this.validateBootstrapStackVersion(options.stack.stackName, options.stack.requiresBootstrapStackVersion, options.stack.bootstrapStackVersionSsmParameter, envResources);
return (0, deploy_stack_1.deployStack)({
stack: options.stack,
resolvedEnvironment,
deployName: options.deployName,
notificationArns: options.notificationArns,
quiet: options.quiet,
sdk: stackSdk,
sdkProvider: this.sdkProvider,
roleArn: cloudFormationRoleArn,
reuseAssets: options.reuseAssets,
envResources,
tags: options.tags,
deploymentMethod,
force: options.force,
parameters: options.parameters,
usePreviousParameters: options.usePreviousParameters,
progress: options.progress,
ci: options.ci,
rollback: options.rollback,
hotswap: options.hotswap,
extraUserAgent: options.extraUserAgent,
resourcesToImport: options.resourcesToImport,
overrideTemplate: options.overrideTemplate,
assetParallelism: options.assetParallelism,
});
}
async destroyStack(options) {
const { stackSdk, cloudFormationRoleArn: roleArn } = await this.prepareSdkFor(options.stack, options.roleArn, credentials_1.Mode.ForWriting);
return (0, deploy_stack_1.destroyStack)({
sdk: stackSdk,
roleArn,
stack: options.stack,
deployName: options.deployName,
quiet: options.quiet,
ci: options.ci,
});
}
async stackExists(options) {
const { stackSdk } = await this.prepareSdkFor(options.stack, undefined, credentials_1.Mode.ForReading);
const stack = await cloudformation_1.CloudFormationStack.lookup(stackSdk.cloudFormation(), options.deployName ?? options.stack.stackName);
return stack.exists;
}
async prepareSdkWithLookupOrDeployRole(stackArtifact) {
// try to assume the lookup role
try {
const result = await this.prepareSdkWithLookupRoleFor(stackArtifact);
if (result.didAssumeRole) {
return {
resolvedEnvironment: result.resolvedEnvironment,
stackSdk: result.sdk,
envResources: result.envResources,
};
}
}
catch { }
// fall back to the deploy role
return this.prepareSdkFor(stackArtifact, undefined, credentials_1.Mode.ForReading);
}
/**
* Get the environment necessary for touching the given stack
*
* Returns the following:
*
* - The resolved environment for the stack (no more 'unknown-account/unknown-region')
* - SDK loaded with the right credentials for calling `CreateChangeSet`.
* - The Execution Role that should be passed to CloudFormation.
*/
async prepareSdkFor(stack, roleArn, mode) {
if (!stack.environment) {
throw new Error(`The stack ${stack.displayName} does not have an environment`);
}
const resolvedEnvironment = await this.sdkProvider.resolveEnvironment(stack.environment);
// Substitute any placeholders with information about the current environment
const arns = await (0, placeholders_1.replaceEnvPlaceholders)({
assumeRoleArn: stack.assumeRoleArn,
// Use the override if given, otherwise use the field from the stack
cloudFormationRoleArn: roleArn ?? stack.cloudFormationExecutionRoleArn,
}, resolvedEnvironment, this.sdkProvider);
const stackSdk = await this.cachedSdkForEnvironment(resolvedEnvironment, mode, {
assumeRoleArn: arns.assumeRoleArn,
assumeRoleExternalId: stack.assumeRoleExternalId,
});
return {
stackSdk: stackSdk.sdk,
resolvedEnvironment,
cloudFormationRoleArn: arns.cloudFormationRoleArn,
envResources: this.environmentResources.for(resolvedEnvironment, stackSdk.sdk),
};
}
/**
* Try to use the bootstrap lookupRole. There are two scenarios that are handled here
* 1. The lookup role may not exist (it was added in bootstrap stack version 7)
* 2. The lookup role may not have the correct permissions (ReadOnlyAccess was added in
* bootstrap stack version 8)
*
* In the case of 1 (lookup role doesn't exist) `forEnvironment` will either:
* 1. Return the default credentials if the default credentials are for the stack account
* 2. Throw an error if the default credentials are not for the stack account.
*
* If we successfully assume the lookup role we then proceed to 2 and check whether the bootstrap
* stack version is valid. If it is not we throw an error which should be handled in the calling
* function (and fallback to use a different role, etc)
*
* If we do not successfully assume the lookup role, but do get back the default credentials
* then return those and note that we are returning the default credentials. The calling
* function can then decide to use them or fallback to another role.
*/
async prepareSdkWithLookupRoleFor(stack) {
const resolvedEnvironment = await this.sdkProvider.resolveEnvironment(stack.environment);
// Substitute any placeholders with information about the current environment
const arns = await (0, placeholders_1.replaceEnvPlaceholders)({
lookupRoleArn: stack.lookupRole?.arn,
}, resolvedEnvironment, this.sdkProvider);
// try to assume the lookup role
const warningMessage = `Could not assume ${arns.lookupRoleArn}, proceeding anyway.`;
const upgradeMessage = `(To get rid of this warning, please upgrade to bootstrap version >= ${stack.lookupRole?.requiresBootstrapStackVersion})`;
try {
const stackSdk = await this.cachedSdkForEnvironment(resolvedEnvironment, credentials_1.Mode.ForReading, {
assumeRoleArn: arns.lookupRoleArn,
assumeRoleExternalId: stack.lookupRole?.assumeRoleExternalId,
});
const envResources = this.environmentResources.for(resolvedEnvironment, stackSdk.sdk);
// if we succeed in assuming the lookup role, make sure we have the correct bootstrap stack version
if (stackSdk.didAssumeRole && stack.lookupRole?.bootstrapStackVersionSsmParameter && stack.lookupRole.requiresBootstrapStackVersion) {
const version = await envResources.versionFromSsmParameter(stack.lookupRole.bootstrapStackVersionSsmParameter);
if (version < stack.lookupRole.requiresBootstrapStackVersion) {
throw new Error(`Bootstrap stack version '${stack.lookupRole.requiresBootstrapStackVersion}' is required, found version '${version}'.`);
}
// we may not have assumed the lookup role because one was not provided
// if that is the case then don't print the upgrade warning
}
else if (!stackSdk.didAssumeRole && stack.lookupRole?.requiresBootstrapStackVersion) {
(0, logging_1.warning)(upgradeMessage);
}
return { ...stackSdk, resolvedEnvironment, envResources };
}
catch (e) {
(0, logging_1.debug)(e);
// only print out the warnings if the lookupRole exists AND there is a required
// bootstrap version, otherwise the warnings will print `undefined`
if (stack.lookupRole && stack.lookupRole.requiresBootstrapStackVersion) {
(0, logging_1.warning)(warningMessage);
(0, logging_1.warning)(upgradeMessage);
}
throw (e);
}
}
async prepareAndValidateAssets(asset, options) {
const { envResources } = await this.prepareSdkFor(options.stack, options.roleArn, credentials_1.Mode.ForWriting);
await this.validateBootstrapStackVersion(options.stack.stackName, asset.requiresBootstrapStackVersion, asset.bootstrapStackVersionSsmParameter, envResources);
const manifest = cdk_assets_1.AssetManifest.fromFile(asset.file);
return { manifest, stackEnv: envResources.environment };
}
/**
* Build all assets in a manifest
*
* @deprecated Use `buildSingleAsset` instead
*/
async buildAssets(asset, options) {
const { manifest, stackEnv } = await this.prepareAndValidateAssets(asset, options);
await (0, asset_publishing_1.buildAssets)(manifest, this.sdkProvider, stackEnv, options.buildOptions);
}
/**
* Publish all assets in a manifest
*
* @deprecated Use `publishSingleAsset` instead
*/
async publishAssets(asset, options) {
const { manifest, stackEnv } = await this.prepareAndValidateAssets(asset, options);
await (0, asset_publishing_1.publishAssets)(manifest, this.sdkProvider, stackEnv, options.publishOptions);
}
/**
* Build a single asset from an asset manifest
*/
// eslint-disable-next-line max-len
async buildSingleAsset(assetArtifact, assetManifest, asset, options) {
const { resolvedEnvironment, envResources } = await this.prepareSdkFor(options.stack, options.roleArn, credentials_1.Mode.ForWriting);
await this.validateBootstrapStackVersion(options.stack.stackName, assetArtifact.requiresBootstrapStackVersion, assetArtifact.bootstrapStackVersionSsmParameter, envResources);
const publisher = this.cachedPublisher(assetManifest, resolvedEnvironment, options.stackName);
await publisher.buildEntry(asset);
if (publisher.hasFailures) {
throw new Error(`Failed to build asset ${asset.id}`);
}
}
/**
* Publish a single asset from an asset manifest
*/
// eslint-disable-next-line max-len
async publishSingleAsset(assetManifest, asset, options) {
const { resolvedEnvironment: stackEnv } = await this.prepareSdkFor(options.stack, options.roleArn, credentials_1.Mode.ForWriting);
// No need to validate anymore, we already did that during build
const publisher = this.cachedPublisher(assetManifest, stackEnv, options.stackName);
await publisher.publishEntry(asset);
if (publisher.hasFailures) {
throw new Error(`Failed to publish asset ${asset.id}`);
}
}
/**
* Return whether a single asset has been published already
*/
async isSingleAssetPublished(assetManifest, asset, options) {
const { resolvedEnvironment: stackEnv } = await this.prepareSdkFor(options.stack, options.roleArn, credentials_1.Mode.ForWriting);
const publisher = this.cachedPublisher(assetManifest, stackEnv, options.stackName);
return publisher.isEntryPublished(asset);
}
/**
* Validate that the bootstrap stack has the right version for this stack
*
* Call into envResources.validateVersion, but prepend the stack name in case of failure.
*/
async validateBootstrapStackVersion(stackName, requiresBootstrapStackVersion, bootstrapStackVersionSsmParameter, envResources) {
try {
await envResources.validateVersion(requiresBootstrapStackVersion, bootstrapStackVersionSsmParameter);
}
catch (e) {
throw new Error(`${stackName}: ${e.message}`);
}
}
async cachedSdkForEnvironment(environment, mode, options) {
const cacheKey = [
environment.account,
environment.region,
`${mode}`,
options?.assumeRoleArn ?? '',
options?.assumeRoleExternalId ?? '',
].join(':');
const existing = this.sdkCache.get(cacheKey);
if (existing) {
return existing;
}
const ret = await this.sdkProvider.forEnvironment(environment, mode, options);
this.sdkCache.set(cacheKey, ret);
return ret;
}
cachedPublisher(assetManifest, env, stackName) {
const existing = this.publisherCache.get(assetManifest);
if (existing) {
return existing;
}
const prefix = stackName ? `${stackName}: ` : '';
const publisher = new cdk_assets.AssetPublishing(assetManifest, {
aws: new asset_publishing_1.PublishingAws(this.sdkProvider, env),
progressListener: new ParallelSafeAssetProgress(prefix, this.props.quiet ?? false),
});
this.publisherCache.set(assetManifest, publisher);
return publisher;
}
}
exports.Deployments = Deployments;
/**
* Asset progress that doesn't do anything with percentages (currently)
*/
class ParallelSafeAssetProgress {
constructor(prefix, quiet) {
this.prefix = prefix;
this.quiet = quiet;
}
onPublishEvent(type, event) {
const handler = this.quiet && type !== 'fail' ? logging_1.debug : asset_publishing_1.EVENT_TO_LOGGER[type];
handler(`${this.prefix} ${type}: ${event.message}`);
}
}
/**
* @deprecated Use 'Deployments' instead
*/
class CloudFormationDeployments extends Deployments {
}
exports.CloudFormationDeployments = CloudFormationDeployments;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwbG95bWVudHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJkZXBsb3ltZW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSx5Q0FBeUM7QUFDekMsMkNBQTJEO0FBQzNELHdEQUE4QztBQUc5QyxpREFBNEg7QUFDNUgsbUVBQTZGO0FBRTdGLGlFQUF5SjtBQUN6SiwwREFBc0g7QUFFdEgsc0RBQTZEO0FBRTdELHdDQUE0QztBQUM1QywrREFBZ0o7QUF3UmhKOzs7O0dBSUc7QUFDSCxNQUFhLFdBQVc7SUFNdEIsWUFBNkIsS0FBdUI7UUFBdkIsVUFBSyxHQUFMLEtBQUssQ0FBa0I7UUFKbkMsYUFBUSxHQUFHLElBQUksR0FBRyxFQUE2QixDQUFDO1FBQ2hELG1CQUFjLEdBQUcsSUFBSSxHQUFHLEVBQTZDLENBQUM7UUFJckYsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLG9EQUE0QixDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ3ZGLENBQUM7SUFFTSxLQUFLLENBQUMsbUNBQW1DLENBQzlDLGlCQUFvRCxFQUNwRCw0QkFBcUMsS0FBSztRQUUxQyxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLGdDQUFnQyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7UUFDdEYsTUFBTSx3QkFBd0IsR0FBRyxNQUFNLElBQUEsMERBQW1DLEVBQUMsaUJBQWlCLEVBQUUsR0FBRyxFQUFFLHlCQUF5QixDQUFDLENBQUM7UUFDOUgsT0FBTztZQUNMLGdCQUFnQixFQUFFLHdCQUF3QixDQUFDLGdCQUFnQjtZQUMzRCxnQkFBZ0IsRUFBRSxJQUFBLDhDQUF1QixFQUFDLHdCQUF3QixDQUFDLGdCQUFnQixDQUFDLENBQUMsTUFBTTtTQUM1RixDQUFDO0lBQ0osQ0FBQztJQUVNLEtBQUssQ0FBQyxtQkFBbUIsQ0FB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QUFVLENBQUMsZUFBZSxDQUFDLGFBQWEsRUFBRTtZQUM5RCxHQUFHLEVBQUUsSUFBSSxnQ0FBYSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDO1lBQzdDLGdCQUFnQixFQUFFLElBQUkseUJBQXlCLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQztTQUNuRixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDbEQsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztDQUNGO0FBeFhELGtDQXdYQztBQUVEOztHQUVHO0FBQ0gsTUFBTSx5QkFBeUI7SUFDN0IsWUFBNkIsTUFBYyxFQUFtQixLQUFjO1FBQS9DLFdBQU0sR0FBTixNQUFNLENBQVE7UUFBbUIsVUFBSyxHQUFMLEtBQUssQ0FBUztJQUM1RSxDQUFDO0lBRU0sY0FBYyxDQUFDLElBQTBCLEVBQUUsS0FBa0M7UUFDbEYsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxlQUFLLENBQUMsQ0FBQyxDQUFDLGtDQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDOUUsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLEtBQUssS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDdEQsQ0FBQztDQUNGO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLHlCQUEwQixTQUFRLFdBQVc7Q0FDekQ7QUFERCw4REFDQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGN4YXBpIGZyb20gJ0Bhd3MtY2RrL2N4LWFwaSc7XG5pbXBvcnQgKiBhcyBjZGtfYXNzZXRzIGZyb20gJ2Nkay1hc3NldHMnO1xuaW1wb3J0IHsgQXNzZXRNYW5pZmVzdCwgSU1hbmlmZXN0RW50cnkgfSBmcm9tICdjZGstYXNzZXRzJztcbmltcG9ydCB7IE1vZGUgfSBmcm9tICcuL2F3cy1hdXRoL2NyZWRlbnRpYWxzJztcbmltcG9ydCB7IElTREsgfSBmcm9tICcuL2F3cy1hdXRoL3Nkayc7XG5pbXBvcnQgeyBDcmVkZW50aWFsc09wdGlvbnMsIFNka0ZvckVudmlyb25tZW50LCBTZGtQcm92aWRlciB9IGZyb20gJy4vYXdzLWF1dGgvc2RrLXByb3ZpZGVyJztcbmltcG9ydCB7IGRlcGxveVN0YWNrLCBEZXBsb3lTdGFja1Jlc3VsdCwgZGVzdHJveVN0YWNrLCBtYWtlQm9keVBhcmFtZXRlckFuZFVwbG9hZCwgRGVwbG95bWVudE1ldGhvZCB9IGZyb20gJy4vZGVwbG95LXN0YWNrJztcbmltcG9ydCB7IEVudmlyb25tZW50UmVzb3VyY2VzLCBFbnZpcm9ubWVudFJlc291cmNlc1JlZ2lzdHJ5IH0gZnJvbSAnLi9lbnZpcm9ubWVudC1yZXNvdXJjZXMnO1xuaW1wb3J0IHsgSG90c3dhcE1vZGUgfSBmcm9tICcuL2hvdHN3YXAvY29tbW9uJztcbmltcG9ydCB7IGxvYWRDdXJyZW50VGVtcGxhdGVXaXRoTmVzdGVkU3RhY2tzLCBsb2FkQ3VycmVudFRlbXBsYXRlLCBmbGF0dGVuTmVzdGVkU3RhY2tOYW1lcywgVGVtcGxhdGVXaXRoTmVzdGVkU3RhY2tDb3VudCB9IGZyb20gJy4vbmVzdGVkLXN0YWNrLWhlbHBlcnMnO1xuaW1wb3J0IHsgQ2xvdWRGb3JtYXRpb25TdGFjaywgVGVtcGxhdGUsIFJlc291cmNlc1RvSW1wb3J0LCBSZXNvdXJjZUlkZW50aWZpZXJTdW1tYXJpZXMgfSBmcm9tICcuL3V0aWwvY2xvdWRmb3JtYXRpb24nO1xuaW1wb3J0IHsgU3RhY2tBY3Rpdml0eVByb2dyZXNzIH0gZnJvbSAnLi91dGlsL2Nsb3VkZm9ybWF0aW9uL3N0YWNrLWFjdGl2aXR5LW1vbml0b3InO1xuaW1wb3J0IHsgcmVwbGFjZUVudlBsYWNlaG9sZGVycyB9IGZyb20gJy4vdXRpbC9wbGFjZWhvbGRlcnMnO1xuaW1wb3J0IHsgVGFnIH0gZnJvbSAnLi4vY2RrLXRvb2xraXQnO1xuaW1wb3J0IHsgZGVidWcsIHdhcm5pbmcgfSBmcm9tICcuLi9sb2dnaW5nJztcbmltcG9ydCB7IGJ1aWxkQXNzZXRzLCBwdWJsaXNoQXNzZXRzLCBCdWlsZEFzc2V0c09wdGlvbnMsIFB1Ymxpc2hBc3NldHNPcHRpb25zLCBQdWJsaXNoaW5nQXdzLCBFVkVOVF9UT19MT0dHRVIgfSBmcm9tICcuLi91dGlsL2Fzc2V0LXB1Ymxpc2hpbmcnO1xuXG4vKipcbiAqIFNESyBvYnRhaW5lZCBieSBhc3N1bWluZyB0aGUgbG9va3VwIHJvbGVcbiAqIGZvciBhIGdpdmVuIGVudmlyb25tZW50XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJlcGFyZWRTZGtXaXRoTG9va3VwUm9sZUZvckVudmlyb25tZW50IHtcbiAgLyoqXG4gICAqIFRoZSBTREsgZm9yIHRoZSBnaXZlbiBlbnZpcm9ubWVudFxuICAgKi9cbiAgcmVhZG9ubHkgc2RrOiBJU0RLO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVzb2x2ZWQgZW52aXJvbm1lbnQgZm9yIHRoZSBzdGFja1xuICAgKiAobm8gbW9yZSAndW5rbm93bi1hY2NvdW50L3Vua25vd24tcmVnaW9uJylcbiAgICovXG4gIHJlYWRvbmx5IHJlc29sdmVkRW52aXJvbm1lbnQ6IGN4YXBpLkVudmlyb25tZW50O1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgYXNzdW1lIHJvbGUgd2FzIHN1Y2Nlc3NmdWwuXG4gICAqIElmIHRoZSBhc3N1bWUgcm9sZSB3YXMgbm90IHN1Y2Nlc3NmdWwgKGZhbHNlKVxuICAgKiB0aGVuIHRoYXQgbWVhbnMgdGhhdCB0aGUgJ3NkaycgcmV0dXJuZWQgY29udGFpbnNcbiAgICogdGhlIGRlZmF1bHQgY3JlZGVudGlhbHMgKG5vdCB0aGUgYXNzdW1lIHJvbGUgY3JlZGVudGlhbHMpXG4gICAqL1xuICByZWFkb25seSBkaWRBc3N1bWVSb2xlOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBbiBvYmplY3QgZm9yIGFjY2Vzc2luZyB0aGUgYm9vdHN0cmFwIHJlc291cmNlcyBpbiB0aGlzIGVudmlyb25tZW50XG4gICAqL1xuICByZWFkb25seSBlbnZSZXNvdXJjZXM6IEVudmlyb25tZW50UmVzb3VyY2VzO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERlcGxveVN0YWNrT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBTdGFjayB0byBkZXBsb3lcbiAgICovXG4gIHJlYWRvbmx5IHN0YWNrOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3Q7XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGlvbiByb2xlIGZvciB0aGUgZGVwbG95bWVudCAocGFzcyB0aHJvdWdoIHRvIENsb3VkRm9ybWF0aW9uKVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEN1cnJlbnQgcm9sZVxuICAgKi9cbiAgcmVhZG9ubHkgcm9sZUFybj86IHN0cmluZztcblxuICAvKipcbiAgICogVG9waWMgQVJOcyB0byBzZW5kIGEgbWVzc2FnZSB3aGVuIGRlcGxveW1lbnQgZmluaXNoZXMgKHBhc3MgdGhyb3VnaCB0byBDbG91ZEZvcm1hdGlvbilcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBub3RpZmljYXRpb25zXG4gICAqL1xuICByZWFkb25seSBub3RpZmljYXRpb25Bcm5zPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIE92ZXJyaWRlIG5hbWUgdW5kZXIgd2hpY2ggc3RhY2sgd2lsbCBiZSBkZXBsb3llZFxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFVzZSBhcnRpZmFjdCBkZWZhdWx0XG4gICAqL1xuICByZWFkb25seSBkZXBsb3lOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBEb24ndCBzaG93IHN0YWNrIGRlcGxveW1lbnQgZXZlbnRzLCBqdXN0IHdhaXRcbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHF1aWV0PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogTmFtZSBvZiB0aGUgdG9vbGtpdCBzdGFjaywgaWYgbm90IHRoZSBkZWZhdWx0IG5hbWVcbiAgICpcbiAgICogQGRlZmF1bHQgJ0NES1Rvb2xraXQnXG4gICAqL1xuICByZWFkb25seSB0b29sa2l0U3RhY2tOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIGFzc2V0IElEcyB3aGljaCBzaG91bGQgTk9UIGJlIGJ1aWx0IG9yIHVwbG9hZGVkXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gQnVpbGQgYWxsIGFzc2V0c1xuICAgKi9cbiAgcmVhZG9ubHkgcmV1c2VBc3NldHM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogU3RhY2sgdGFncyAocGFzcyB0aHJvdWdoIHRvIENsb3VkRm9ybWF0aW9uKVxuICAgKi9cbiAgcmVhZG9ubHkgdGFncz86IFRhZ1tdO1xuXG4gIC8qKlxuICAgKiBTdGFnZSB0aGUgY2hhbmdlIHNldCBidXQgZG9uJ3QgZXhlY3V0ZSBpdFxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHRydWVcbiAgICogQGRlcHJlY2F0ZWQgVXNlICdkZXBsb3ltZW50TWV0aG9kJyBpbnN0ZWFkXG4gICAqL1xuICByZWFkb25seSBleGVjdXRlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogT3B0aW9uYWwgbmFtZSB0byB1c2UgZm9yIHRoZSBDbG91ZEZvcm1hdGlvbiBjaGFuZ2Ugc2V0LlxuICAgKiBJZiBub3QgcHJvdmlkZWQsIGEgbmFtZSB3aWxsIGJlIGdlbmVyYXRlZCBhdXRvbWF0aWNhbGx5LlxuICAgKlxuICAgKiBAZGVwcmVjYXRlZCBVc2UgJ2RlcGxveW1lbnRNZXRob2QnIGluc3RlYWRcbiAgICovXG4gIHJlYWRvbmx5IGNoYW5nZVNldE5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFNlbGVjdCB0aGUgZGVwbG95bWVudCBtZXRob2QgKGRpcmVjdCBvciB1c2luZyBhIGNoYW5nZSBzZXQpXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gQ2hhbmdlIHNldCB3aXRoIGRlZmF1bHQgb3B0aW9uc1xuICAgKi9cbiAgcmVhZG9ubHkgZGVwbG95bWVudE1ldGhvZD86IERlcGxveW1lbnRNZXRob2Q7XG5cbiAgLyoqXG4gICAqIEZvcmNlIGRlcGxveW1lbnQsIGV2ZW4gaWYgdGhlIGRlcGxveWVkIHRlbXBsYXRlIGlzIGlkZW50aWNhbCB0byB0aGUgb25lIHdlIGFyZSBhYm91dCB0byBkZXBsb3kuXG4gICAqIEBkZWZhdWx0IGZhbHNlIGRlcGxveW1lbnQgd2lsbCBiZSBza2lwcGVkIGlmIHRoZSB0ZW1wbGF0ZSBpcyBpZGVudGljYWxcbiAgICovXG4gIHJlYWRvbmx5IGZvcmNlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogRXh0cmEgcGFyYW1ldGVycyBmb3IgQ2xvdWRGb3JtYXRpb25cbiAgICogQGRlZmF1bHQgLSBubyBhZGRpdGlvbmFsIHBhcmFtZXRlcnMgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIHRlbXBsYXRlXG4gICAqL1xuICByZWFkb25seSBwYXJhbWV0ZXJzPzogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIHwgdW5kZWZpbmVkIH07XG5cbiAgLyoqXG4gICAqIFVzZSBwcmV2aW91cyB2YWx1ZXMgZm9yIHVuc3BlY2lmaWVkIHBhcmFtZXRlcnNcbiAgICpcbiAgICogSWYgbm90IHNldCwgYWxsIHBhcmFtZXRlcnMgbXVzdCBiZSBzcGVjaWZpZWQgZm9yIGV2ZXJ5IGRlcGxveW1lbnQuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IHVzZVByZXZpb3VzUGFyYW1ldGVycz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIERpc3BsYXkgbW9kZSBmb3Igc3RhY2sgZGVwbG95bWVudCBwcm9ncmVzcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBTdGFja0FjdGl2aXR5UHJvZ3Jlc3MuQmFyIC0gc3RhY2sgZXZlbnRzIHdpbGwgYmUgZGlzcGxheWVkIGZvclxuICAgKiAgIHRoZSByZXNvdXJjZSBjdXJyZW50bHkgYmVpbmcgZGVwbG95ZWQuXG4gICAqL1xuICByZWFkb25seSBwcm9ncmVzcz86IFN0YWNrQWN0aXZpdHlQcm9ncmVzcztcblxuICAvKipcbiAgICogV2hldGhlciB3ZSBhcmUgb24gYSBDSSBzeXN0ZW1cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGNpPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogUm9sbGJhY2sgZmFpbGVkIGRlcGxveW1lbnRzXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IHJvbGxiYWNrPzogYm9vbGVhbjtcblxuICAvKlxuICAgKiBXaGV0aGVyIHRvIHBlcmZvcm0gYSAnaG90c3dhcCcgZGVwbG95bWVudC5cbiAgICogQSAnaG90c3dhcCcgZGVwbG95bWVudCB3aWxsIGF0dGVtcHQgdG8gc2hvcnQtY2lyY3VpdCBDbG91ZEZvcm1hdGlvblxuICAgKiBhbmQgdXBkYXRlIHRoZSBhZmZlY3RlZCByZXNvdXJjZXMgbGlrZSBMYW1iZGEgZnVuY3Rpb25zIGRpcmVjdGx5LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGBIb3Rzd2FwTW9kZS5GVUxMX0RFUExPWU1FTlRgIGZvciByZWd1bGFyIGRlcGxveW1lbnRzLCBgSG90c3dhcE1vZGUuSE9UU1dBUF9PTkxZYCBmb3IgJ3dhdGNoJyBkZXBsb3ltZW50c1xuICAgKi9cbiAgcmVhZG9ubHkgaG90c3dhcD86IEhvdHN3YXBNb2RlO1xuXG4gIC8qKlxuICAgKiBUaGUgZXh0cmEgc3RyaW5nIHRvIGFwcGVuZCB0byB0aGUgVXNlci1BZ2VudCBoZWFkZXIgd2hlbiBwZXJmb3JtaW5nIEFXUyBTREsgY2FsbHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm90aGluZyBleHRyYSBpcyBhcHBlbmRlZCB0byB0aGUgVXNlci1BZ2VudCBoZWFkZXJcbiAgICovXG4gIHJlYWRvbmx5IGV4dHJhVXNlckFnZW50Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIGV4aXN0aW5nIHJlc291cmNlcyB0byBiZSBJTVBPUlRFRCBpbnRvIHRoZSBzdGFjaywgaW5zdGVhZCBvZiBiZWluZyBDUkVBVEVEXG4gICAqL1xuICByZWFkb25seSByZXNvdXJjZXNUb0ltcG9ydD86IFJlc291cmNlc1RvSW1wb3J0O1xuXG4gIC8qKlxuICAgKiBJZiBwcmVzZW50LCB1c2UgdGhpcyBnaXZlbiB0ZW1wbGF0ZSBpbnN0ZWFkIG9mIHRoZSBzdG9yZWQgb25lXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gVXNlIHRoZSBzdG9yZWQgdGVtcGxhdGVcbiAgICovXG4gIHJlYWRvbmx5IG92ZXJyaWRlVGVtcGxhdGU/OiBhbnk7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gYnVpbGQvcHVibGlzaCBhc3NldHMgaW4gcGFyYWxsZWxcbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZSBUbyByZW1haW4gYmFja3dhcmQgY29tcGF0aWJsZS5cbiAgICovXG4gIHJlYWRvbmx5IGFzc2V0UGFyYWxsZWxpc20/OiBib29sZWFuO1xufVxuXG5pbnRlcmZhY2UgQXNzZXRPcHRpb25zIHtcbiAgLyoqXG4gICAqIFN0YWNrIHdpdGggYXNzZXRzIHRvIGJ1aWxkLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhY2s6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdDtcblxuICAvKipcbiAgICogTmFtZSBvZiB0aGUgdG9vbGtpdCBzdGFjaywgaWYgbm90IHRoZSBkZWZhdWx0IG5hbWUuXG4gICAqXG4gICAqIEBkZWZhdWx0ICdDREtUb29sa2l0J1xuICAgKi9cbiAgcmVhZG9ubHkgdG9vbGtpdFN0YWNrTmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogRXhlY3V0aW9uIHJvbGUgZm9yIHRoZSBidWlsZGluZy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBDdXJyZW50IHJvbGVcbiAgICovXG4gIHJlYWRvbmx5IHJvbGVBcm4/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnVpbGRTdGFja0Fzc2V0c09wdGlvbnMgZXh0ZW5kcyBBc3NldE9wdGlvbnMge1xuICAvKipcbiAgICogT3B0aW9ucyB0byBwYXNzIG9uIHRvIGBidWlsZEFzc2V0cygpYCBmdW5jdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgYnVpbGRPcHRpb25zPzogQnVpbGRBc3NldHNPcHRpb25zO1xuXG4gIC8qKlxuICAgKiBTdGFjayBuYW1lIHRoaXMgYXNzZXQgaXMgZm9yXG4gICAqL1xuICByZWFkb25seSBzdGFja05hbWU/OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBQdWJsaXNoU3RhY2tBc3NldHNPcHRpb25zIGV4dGVuZHMgQXNzZXRPcHRpb25zIHtcbiAgLyoqXG4gICAqIE9wdGlvbnMgdG8gcGFzcyBvbiB0byBgcHVibGlzaEFzZXN0cygpYCBmdW5jdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgcHVibGlzaE9wdGlvbnM/OiBPbWl0PFB1Ymxpc2hBc3NldHNPcHRpb25zLCAnYnVpbGRBc3NldHMnPjtcblxuICAvKipcbiAgICogU3RhY2sgbmFtZSB0aGlzIGFzc2V0IGlzIGZvclxuICAgKi9cbiAgcmVhZG9ubHkgc3RhY2tOYW1lPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERlc3Ryb3lTdGFja09wdGlvbnMge1xuICBzdGFjazogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0O1xuICBkZXBsb3lOYW1lPzogc3RyaW5nO1xuICByb2xlQXJuPzogc3RyaW5nO1xuICBxdWlldD86IGJvb2xlYW47XG4gIGZvcmNlPzogYm9vbGVhbjtcbiAgY2k/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN0YWNrRXhpc3RzT3B0aW9ucyB7XG4gIHN0YWNrOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3Q7XG4gIGRlcGxveU5hbWU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVwbG95bWVudHNQcm9wcyB7XG4gIHNka1Byb3ZpZGVyOiBTZGtQcm92aWRlcjtcbiAgcmVhZG9ubHkgdG9vbGtpdFN0YWNrTmFtZT86IHN0cmluZztcbiAgcmVhZG9ubHkgcXVpZXQ/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFNESyBvYnRhaW5lZCBieSBhc3N1bWluZyB0aGUgZGVwbG95IHJvbGVcbiAqIGZvciBhIGdpdmVuIGVudmlyb25tZW50XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJlcGFyZWRTZGtGb3JFbnZpcm9ubWVudCB7XG4gIC8qKlxuICAgKiBUaGUgU0RLIGZvciB0aGUgZ2l2ZW4gZW52aXJvbm1lbnRcbiAgICovXG4gIHJlYWRvbmx5IHN0YWNrU2RrOiBJU0RLO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVzb2x2ZWQgZW52aXJvbm1lbnQgZm9yIHRoZSBzdGFja1xuICAgKiAobm8gbW9yZSAndW5rbm93bi1hY2NvdW50L3Vua25vd24tcmVnaW9uJylcbiAgICovXG4gIHJlYWRvbmx5IHJlc29sdmVkRW52aXJvbm1lbnQ6IGN4YXBpLkVudmlyb25tZW50O1xuICAvKipcbiAgICogVGhlIEV4ZWN1dGlvbiBSb2xlIHRoYXQgc2hvdWxkIGJlIHBhc3NlZCB0byBDbG91ZEZvcm1hdGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBleGVjdXRpb24gcm9sZSBpcyB1c2VkXG4gICAqL1xuICByZWFkb25seSBjbG91ZEZvcm1hdGlvblJvbGVBcm4/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEFjY2VzcyBjbGFzcyBmb3IgZW52aXJvbm1lbnRhbCByZXNvdXJjZXMgdG8gaGVscCB0aGUgZGVwbG95bWVudFxuICAgKi9cbiAgcmVhZG9ubHkgZW52UmVzb3VyY2VzOiBFbnZpcm9ubWVudFJlc291cmNlcztcbn1cblxuLyoqXG4gKiBTY29wZSBmb3IgYSBzaW5nbGUgc2V0IG9mIGRlcGxveW1lbnRzIGZyb20gYSBzZXQgb2YgQ2xvdWQgQXNzZW1ibHkgQXJ0aWZhY3RzXG4gKlxuICogTWFuYWdlcyBsb29rdXAgb2YgU0RLcywgQm9vdHN0cmFwIHN0YWNrcywgZXRjLlxuICovXG5leHBvcnQgY2xhc3MgRGVwbG95bWVudHMge1xuICBwcml2YXRlIHJlYWRvbmx5IHNka1Byb3ZpZGVyOiBTZGtQcm92aWRlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBzZGtDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBTZGtGb3JFbnZpcm9ubWVudD4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBwdWJsaXNoZXJDYWNoZSA9IG5ldyBNYXA8QXNzZXRNYW5pZmVzdCwgY2RrX2Fzc2V0cy5Bc3NldFB1Ymxpc2hpbmc+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZW52aXJvbm1lbnRSZXNvdXJjZXM6IEVudmlyb25tZW50UmVzb3VyY2VzUmVnaXN0cnk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBwcm9wczogRGVwbG95bWVudHNQcm9wcykge1xuICAgIHRoaXMuc2RrUHJvdmlkZXIgPSBwcm9wcy5zZGtQcm92aWRlcjtcbiAgICB0aGlzLmVudmlyb25tZW50UmVzb3VyY2VzID0gbmV3IEVudmlyb25tZW50UmVzb3VyY2VzUmVnaXN0cnkocHJvcHMudG9vbGtpdFN0YWNrTmFtZSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgcmVhZEN1cnJlbnRUZW1wbGF0ZVdpdGhOZXN0ZWRTdGFja3MoXG4gICAgcm9vdFN0YWNrQXJ0aWZhY3Q6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdCxcbiAgICByZXRyaWV2ZVByb2Nlc3NlZFRlbXBsYXRlOiBib29sZWFuID0gZmFsc2UsXG4gICk6IFByb21pc2U8VGVtcGxhdGVXaXRoTmVzdGVkU3RhY2tDb3VudD4ge1xuICAgIGNvbnN0IHNkayA9IChhd2FpdCB0aGlzLnByZXBhcmVTZGtXaXRoTG9va3VwT3JEZXBsb3lSb2xlKHJvb3RTdGFja0FydGlmYWN0KSkuc3RhY2tTZGs7XG4gICAgY29uc3QgdGVtcGxhdGVXaXRoTmVzdGVkU3RhY2tzID0gYXdhaXQgbG9hZEN1cnJlbnRUZW1wbGF0ZVdpdGhOZXN0ZWRTdGFja3Mocm9vdFN0YWNrQXJ0aWZhY3QsIHNkaywgcmV0cmlldmVQcm9jZXNzZWRUZW1wbGF0ZSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRlcGxveWVkVGVtcGxhdGU6IHRlbXBsYXRlV2l0aE5lc3RlZFN0YWNrcy5kZXBsb3llZFRlbXBsYXRlLFxuICAgICAgbmVzdGVkU3RhY2tDb3VudDogZmxhdHRlbk5lc3RlZFN0YWNrTmFtZXModGVtcGxhdGVXaXRoTmVzdGVkU3RhY2tzLm5lc3RlZFN0YWNrTmFtZXMpLmxlbmd0aCxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHJlYWRDdXJyZW50VGVtcGxhdGUoc3RhY2tBcnRpZmFjdDogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0KTogUHJvbWlzZTxUZW1wbGF0ZT4ge1xuICAgIGRlYnVnKGBSZWFkaW5nIGV4aXN0aW5nIHRlbXBsYXRlIGZvciBzdGFjayAke3N0YWNrQXJ0aWZhY3QuZGlzcGxheU5hbWV9LmApO1xuICAgIGNvbnN0IHNkayA9IChhd2FpdCB0aGlzLnByZXBhcmVTZGtXaXRoTG9va3VwT3JEZXBsb3lSb2xlKHN0YWNrQXJ0aWZhY3QpKS5zdGFja1NkaztcbiAgICByZXR1cm4gbG9hZEN1cnJlbnRUZW1wbGF0ZShzdGFja0FydGlmYWN0LCBzZGspO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHJlc291cmNlSWRlbnRpZmllclN1bW1hcmllcyhcbiAgICBzdGFja0FydGlmYWN0OiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QsXG4gICk6IFByb21pc2U8UmVzb3VyY2VJZGVudGlmaWVyU3VtbWFyaWVzPiB7XG4gICAgZGVidWcoYFJldHJpZXZpbmcgdGVtcGxhdGUgc3VtbWFyeSBmb3Igc3RhY2sgJHtzdGFja0FydGlmYWN0LmRpc3BsYXlOYW1lfS5gKTtcbiAgICAvLyBDdXJyZW50bHksIG5lZWRzIHRvIHVzZSBgZGVwbG95LXJvbGVgIHNpbmNlIGl0IG1heSBuZWVkIHRvIHJlYWQgdGVtcGxhdGVzIGluIHRoZSBzdGFnaW5nXG4gICAgLy8gYnVja2V0IHdoaWNoIGhhdmUgYmVlbiBlbmNyeXB0ZWQgd2l0aCBhIEtNUyBrZXkgKGFuZCBsb29rdXAtcm9sZSBtYXkgbm90IHJlYWQgZW5jcnlwdGVkIHRoaW5ncylcbiAgICBjb25zdCB7IHN0YWNrU2RrLCByZXNvbHZlZEVudmlyb25tZW50LCBlbnZSZXNvdXJjZXMgfSA9IGF3YWl0IHRoaXMucHJlcGFyZVNka0ZvcihzdGFja0FydGlmYWN0LCB1bmRlZmluZWQsIE1vZGUuRm9yUmVhZGluZyk7XG4gICAgY29uc3QgY2ZuID0gc3RhY2tTZGsuY2xvdWRGb3JtYXRpb24oKTtcblxuICAgIC8vIFVwbG9hZCB0aGUgdGVtcGxhdGUsIGlmIG5lY2Vzc2FyeSwgYmVmb3JlIHBhc3NpbmcgaXQgdG8gQ0ZOXG4gICAgY29uc3QgY2ZuUGFyYW0gPSBhd2FpdCBtYWtlQm9keVBhcmFtZXRlckFuZFVwbG9hZChcbiAgICAgIHN0YWNrQXJ0aWZhY3QsXG4gICAgICByZXNvbHZlZEVudmlyb25tZW50LFxuICAgICAgZW52UmVzb3VyY2VzLFxuICAgICAgdGhpcy5zZGtQcm92aWRlcixcbiAgICAgIHN0YWNrU2RrKTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2ZuLmdldFRlbXBsYXRlU3VtbWFyeShjZm5QYXJhbSkucHJvbWlzZSgpO1xuICAgIGlmICghcmVzcG9uc2UuUmVzb3VyY2VJZGVudGlmaWVyU3VtbWFyaWVzKSB7XG4gICAgICBkZWJ1ZygnR2V0VGVtcGxhdGVTdW1tYXJ5IEFQSSBjYWxsIGRpZCBub3QgcmV0dXJuIFwiUmVzb3VyY2VJZGVudGlmaWVyU3VtbWFyaWVzXCInKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3BvbnNlLlJlc291cmNlSWRlbnRpZmllclN1bW1hcmllcyA/PyBbXTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkZXBsb3lTdGFjayhvcHRpb25zOiBEZXBsb3lTdGFja09wdGlvbnMpOiBQcm9taXNlPERlcGxveVN0YWNrUmVzdWx0PiB7XG4gICAgbGV0IGRlcGxveW1lbnRNZXRob2QgPSBvcHRpb25zLmRlcGxveW1lbnRNZXRob2Q7XG4gICAgaWYgKG9wdGlvbnMuY2hhbmdlU2V0TmFtZSB8fCBvcHRpb25zLmV4ZWN1dGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGRlcGxveW1lbnRNZXRob2QpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgY2Fubm90IHN1cHBseSBib3RoIFxcJ2RlcGxveW1lbnRNZXRob2RcXCcgYW5kIFxcJ2NoYW5nZVNldE5hbWUvZXhlY3V0ZVxcJy4gU3VwcGx5IG9uZSBvciB0aGUgb3RoZXIuJyk7XG4gICAgICB9XG4gICAgICBkZXBsb3ltZW50TWV0aG9kID0ge1xuICAgICAgICBtZXRob2Q6ICdjaGFuZ2Utc2V0JyxcbiAgICAgICAgY2hhbmdlU2V0TmFtZTogb3B0aW9ucy5jaGFuZ2VTZXROYW1lLFxuICAgICAgICBleGVjdXRlOiBvcHRpb25zLmV4ZWN1dGUsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IHtcbiAgICAgIHN0YWNrU2RrLFxuICAgICAgcmVzb2x2ZWRFbnZpcm9ubWVudCxcbiAgICAgIGNsb3VkRm9ybWF0aW9uUm9sZUFybixcbiAgICAgIGVudlJlc291cmNlcyxcbiAgICB9ID0gYXdhaXQgdGhpcy5wcmVwYXJlU2RrRm9yKG9wdGlvbnMuc3RhY2ssIG9wdGlvbnMucm9sZUFybiwgTW9kZS5Gb3JXcml0aW5nKTtcblxuICAgIC8vIERvIGEgdmVyaWZpY2F0aW9uIG9mIHRoZSBib290c3RyYXAgc3RhY2sgdmVyc2lvblxuICAgIGF3YWl0IHRoaXMudmFsaWRhdGVCb290c3RyYXBTdGFja1ZlcnNpb24oXG4gICAgICBvcHRpb25zLnN0YWNrLnN0YWNrTmFtZSxcbiAgICAgIG9wdGlvbnMuc3RhY2sucmVxdWlyZXNCb290c3RyYXBTdGFja1ZlcnNpb24sXG4gICAgICBvcHRpb25zLnN0YWNrLmJvb3RzdHJhcFN0YWNrVmVyc2lvblNzbVBhcmFtZXRlcixcbiAgICAgIGVudlJlc291cmNlcyk7XG5cbiAgICByZXR1cm4gZGVwbG95U3RhY2soe1xuICAgICAgc3RhY2s6IG9wdGlvbnMuc3RhY2ssXG4gICAgICByZXNvbHZlZEVudmlyb25tZW50LFxuICAgICAgZGVwbG95TmFtZTogb3B0aW9ucy5kZXBsb3lOYW1lLFxuICAgICAgbm90aWZpY2F0aW9uQXJuczogb3B0aW9ucy5ub3RpZmljYXRpb25Bcm5zLFxuICAgICAgcXVpZXQ6IG9wdGlvbnMucXVpZXQsXG4gICAgICBzZGs6IHN0YWNrU2RrLFxuICAgICAgc2RrUHJvdmlkZXI6IHRoaXMuc2RrUHJvdmlkZXIsXG4gICAgICByb2xlQXJuOiBjbG91ZEZvcm1hdGlvblJvbGVBcm4sXG4gICAgICByZXVzZUFzc2V0czogb3B0aW9ucy5yZXVzZUFzc2V0cyxcbiAgICAgIGVudlJlc291cmNlcyxcbiAgICAgIHRhZ3M6IG9wdGlvbnMudGFncyxcbiAgICAgIGRlcGxveW1lbnRNZXRob2QsXG4gICAgICBmb3JjZTogb3B0aW9ucy5mb3JjZSxcbiAgICAgIHBhcmFtZXRlcnM6IG9wdGlvbnMucGFyYW1ldGVycyxcbiAgICAgIHVzZVByZXZpb3VzUGFyYW1ldGVyczogb3B0aW9ucy51c2VQcmV2aW91c1BhcmFtZXRlcnMsXG4gICAgICBwcm9ncmVzczogb3B0aW9ucy5wcm9ncmVzcyxcbiAgICAgIGNpOiBvcHRpb25zLmNpLFxuICAgICAgcm9sbGJhY2s6IG9wdGlvbnMucm9sbGJhY2ssXG4gICAgICBob3Rzd2FwOiBvcHRpb25zLmhvdHN3YXAsXG4gICAgICBleHRyYVVzZXJBZ2VudDogb3B0aW9ucy5leHRyYVVzZXJBZ2VudCxcbiAgICAgIHJlc291cmNlc1RvSW1wb3J0OiBvcHRpb25zLnJlc291cmNlc1RvSW1wb3J0LFxuICAgICAgb3ZlcnJpZGVUZW1wbGF0ZTogb3B0aW9ucy5vdmVycmlkZVRlbXBsYXRlLFxuICAgICAgYXNzZXRQYXJhbGxlbGlzbTogb3B0aW9ucy5hc3NldFBhcmFsbGVsaXNtLFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGRlc3Ryb3lTdGFjayhvcHRpb25zOiBEZXN0cm95U3RhY2tPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBzdGFja1NkaywgY2xvdWRGb3JtYXRpb25Sb2xlQXJuOiByb2xlQXJuIH0gPSBhd2FpdCB0aGlzLnByZXBhcmVTZGtGb3Iob3B0aW9ucy5zdGFjaywgb3B0aW9ucy5yb2xlQXJuLCBNb2RlLkZvcldyaXRpbmcpO1xuXG4gICAgcmV0dXJuIGRlc3Ryb3lTdGFjayh7XG4gICAgICBzZGs6IHN0YWNrU2RrLFxuICAgICAgcm9sZUFybixcbiAgICAgIHN0YWNrOiBvcHRpb25zLnN0YWNrLFxuICAgICAgZGVwbG95TmFtZTogb3B0aW9ucy5kZXBsb3lOYW1lLFxuICAgICAgcXVpZXQ6IG9wdGlvbnMucXVpZXQsXG4gICAgICBjaTogb3B0aW9ucy5jaSxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzdGFja0V4aXN0cyhvcHRpb25zOiBTdGFja0V4aXN0c09wdGlvbnMpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCB7IHN0YWNrU2RrIH0gPSBhd2FpdCB0aGlzLnByZXBhcmVTZGtGb3Iob3B0aW9ucy5zdGFjaywgdW5kZWZpbmVkLCBNb2RlLkZvclJlYWRpbmcpO1xuICAgIGNvbnN0IHN0YWNrID0gYXdhaXQgQ2xvdWRGb3JtYXRpb25TdGFjay5sb29rdXAoc3RhY2tTZGsuY2xvdWRGb3JtYXRpb24oKSwgb3B0aW9ucy5kZXBsb3lOYW1lID8/IG9wdGlvbnMuc3RhY2suc3RhY2tOYW1lKTtcbiAgICByZXR1cm4gc3RhY2suZXhpc3RzO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBwcmVwYXJlU2RrV2l0aExvb2t1cE9yRGVwbG95Um9sZShzdGFja0FydGlmYWN0OiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QpOiBQcm9taXNlPFByZXBhcmVkU2RrRm9yRW52aXJvbm1lbnQ+IHtcbiAgICAvLyB0cnkgdG8gYXNzdW1lIHRoZSBsb29rdXAgcm9sZVxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnByZXBhcmVTZGtXaXRoTG9va3VwUm9sZUZvcihzdGFja0FydGlmYWN0KTtcbiAgICAgIGlmIChyZXN1bHQuZGlkQXNzdW1lUm9sZSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHJlc29sdmVkRW52aXJvbm1lbnQ6IHJlc3VsdC5yZXNvbHZlZEVudmlyb25tZW50LFxuICAgICAgICAgIHN0YWNrU2RrOiByZXN1bHQuc2RrLFxuICAgICAgICAgIGVudlJlc291cmNlczo