@aws-cdk/aws-ssm
Version:
The CDK Construct Library for AWS::SSM
289 lines • 45.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StringListParameter = exports.StringParameter = exports.ParameterTier = exports.ParameterType = void 0;
const iam = require("@aws-cdk/aws-iam");
const cxschema = require("@aws-cdk/cloud-assembly-schema");
const core_1 = require("@aws-cdk/core");
const ssm = require("./ssm.generated");
const util_1 = require("./util");
/**
* Basic features shared across all types of SSM Parameters.
*/
class ParameterBase extends core_1.Resource {
/**
* Grants read (DescribeParameter, GetParameter, GetParameterHistory) permissions on the SSM Parameter.
*/
grantRead(grantee) {
if (this.encryptionKey) {
this.encryptionKey.grantDecrypt(grantee);
}
return iam.Grant.addToPrincipal({
grantee,
actions: [
'ssm:DescribeParameters',
'ssm:GetParameters',
'ssm:GetParameter',
'ssm:GetParameterHistory',
],
resourceArns: [this.parameterArn],
});
}
/**
* Grants write (PutParameter) permissions on the SSM Parameter.
*/
grantWrite(grantee) {
if (this.encryptionKey) {
this.encryptionKey.grantEncrypt(grantee);
}
return iam.Grant.addToPrincipal({
grantee,
actions: ['ssm:PutParameter'],
resourceArns: [this.parameterArn],
});
}
}
/**
* SSM parameter type.
*/
var ParameterType;
(function (ParameterType) {
ParameterType["STRING"] = "String";
ParameterType["SECURE_STRING"] = "SecureString";
ParameterType["STRING_LIST"] = "StringList";
ParameterType["AWS_EC2_IMAGE_ID"] = "AWS::EC2::Image::Id";
})(ParameterType = exports.ParameterType || (exports.ParameterType = {}));
/**
* SSM parameter tier.
*/
var ParameterTier;
(function (ParameterTier) {
ParameterTier["ADVANCED"] = "Advanced";
ParameterTier["INTELLIGENT_TIERING"] = "Intelligent-Tiering";
ParameterTier["STANDARD"] = "Standard";
})(ParameterTier = exports.ParameterTier || (exports.ParameterTier = {}));
/**
* Creates a new String SSM Parameter.
*
* @resource AWS::SSM::Parameter
*/
class StringParameter extends ParameterBase {
/**
*
*/
constructor(scope, id, props) {
var _a;
super(scope, id, {
physicalName: props.parameterName,
});
if (props.allowedPattern) {
_assertValidValue(props.stringValue, props.allowedPattern);
}
if (this.physicalName.length > 2048) {
throw new Error('Name cannot be longer than 2048 characters.');
}
if (props.description && ((_a = props.description) === null || _a === void 0 ? void 0 : _a.length) > 1024) {
throw new Error('Description cannot be longer than 1024 characters.');
}
const resource = new ssm.CfnParameter(this, 'Resource', {
allowedPattern: props.allowedPattern,
description: props.description,
name: this.physicalName,
tier: props.tier,
type: props.type || ParameterType.STRING,
value: props.stringValue,
});
this.parameterName = this.getResourceNameAttribute(resource.ref);
this.parameterArn = util_1.arnForParameterName(this, this.parameterName, {
physicalName: props.parameterName || util_1.AUTOGEN_MARKER,
simpleName: props.simpleName,
});
this.parameterType = resource.attrType;
this.stringValue = resource.attrValue;
}
/**
* Imports an external string parameter by name.
*/
static fromStringParameterName(scope, id, stringParameterName) {
return this.fromStringParameterAttributes(scope, id, { parameterName: stringParameterName });
}
/**
* Imports an external string parameter with name and optional version.
*/
static fromStringParameterAttributes(scope, id, attrs) {
if (!attrs.parameterName) {
throw new Error('parameterName cannot be an empty string');
}
const type = attrs.type || ParameterType.STRING;
const stringValue = attrs.version
? new core_1.CfnDynamicReference(core_1.CfnDynamicReferenceService.SSM, `${attrs.parameterName}:${attrs.version}`).toString()
: new core_1.CfnParameter(scope, `${id}.Parameter`, { type: `AWS::SSM::Parameter::Value<${type}>`, default: attrs.parameterName }).valueAsString;
class Import extends ParameterBase {
constructor() {
super(...arguments);
this.parameterName = attrs.parameterName;
this.parameterArn = util_1.arnForParameterName(this, attrs.parameterName, { simpleName: attrs.simpleName });
this.parameterType = type;
this.stringValue = stringValue;
}
}
return new Import(scope, id);
}
/**
* Imports a secure string parameter from the SSM parameter store.
*/
static fromSecureStringParameterAttributes(scope, id, attrs) {
const stringValue = new core_1.CfnDynamicReference(core_1.CfnDynamicReferenceService.SSM_SECURE, `${attrs.parameterName}:${attrs.version}`).toString();
class Import extends ParameterBase {
constructor() {
super(...arguments);
this.parameterName = attrs.parameterName;
this.parameterArn = util_1.arnForParameterName(this, attrs.parameterName, { simpleName: attrs.simpleName });
this.parameterType = ParameterType.SECURE_STRING;
this.stringValue = stringValue;
this.encryptionKey = attrs.encryptionKey;
}
}
return new Import(scope, id);
}
/**
* Reads the value of an SSM parameter during synthesis through an environmental context provider.
*
* Requires that the stack this scope is defined in will have explicit
* account/region information. Otherwise, it will fail during synthesis.
*/
static valueFromLookup(scope, parameterName) {
const value = core_1.ContextProvider.getValue(scope, {
provider: cxschema.ContextProvider.SSM_PARAMETER_PROVIDER,
props: { parameterName },
dummyValue: `dummy-value-for-${parameterName}`,
}).value;
return value;
}
/**
* Returns a token that will resolve (during deployment) to the string value of an SSM string parameter.
*
* @param scope Some scope within a stack.
* @param parameterName The name of the SSM parameter.
* @param version The parameter version (recommended in order to ensure that the value won't change during deployment).
*/
static valueForStringParameter(scope, parameterName, version) {
return StringParameter.valueForTypedStringParameter(scope, parameterName, ParameterType.STRING, version);
}
/**
* Returns a token that will resolve (during deployment) to the string value of an SSM string parameter.
*
* @param scope Some scope within a stack.
* @param parameterName The name of the SSM parameter.
* @param type The type of the SSM parameter.
* @param version The parameter version (recommended in order to ensure that the value won't change during deployment).
*/
static valueForTypedStringParameter(scope, parameterName, type = ParameterType.STRING, version) {
const stack = core_1.Stack.of(scope);
const id = makeIdentityForImportedValue(parameterName);
const exists = stack.node.tryFindChild(id);
if (exists) {
return exists.stringValue;
}
return this.fromStringParameterAttributes(stack, id, { parameterName, version, type }).stringValue;
}
/**
* Returns a token that will resolve (during deployment).
*
* @param scope Some scope within a stack.
* @param parameterName The name of the SSM parameter.
* @param version The parameter version (required for secure strings).
*/
static valueForSecureStringParameter(scope, parameterName, version) {
const stack = core_1.Stack.of(scope);
const id = makeIdentityForImportedValue(parameterName);
const exists = stack.node.tryFindChild(id);
if (exists) {
return exists.stringValue;
}
return this.fromSecureStringParameterAttributes(stack, id, { parameterName, version }).stringValue;
}
}
exports.StringParameter = StringParameter;
/**
* Creates a new StringList SSM Parameter.
*
* @resource AWS::SSM::Parameter
*/
class StringListParameter extends ParameterBase {
/**
*
*/
constructor(scope, id, props) {
var _a;
super(scope, id, {
physicalName: props.parameterName,
});
if (props.stringListValue.find(str => !core_1.Token.isUnresolved(str) && str.indexOf(',') !== -1)) {
throw new Error('Values of a StringList SSM Parameter cannot contain the \',\' character. Use a string parameter instead.');
}
if (props.allowedPattern && !core_1.Token.isUnresolved(props.stringListValue)) {
props.stringListValue.forEach(str => _assertValidValue(str, props.allowedPattern));
}
if (this.physicalName.length > 2048) {
throw new Error('Name cannot be longer than 2048 characters.');
}
if (props.description && ((_a = props.description) === null || _a === void 0 ? void 0 : _a.length) > 1024) {
throw new Error('Description cannot be longer than 1024 characters.');
}
const resource = new ssm.CfnParameter(this, 'Resource', {
allowedPattern: props.allowedPattern,
description: props.description,
name: this.physicalName,
tier: props.tier,
type: ParameterType.STRING_LIST,
value: props.stringListValue.join(','),
});
this.parameterName = this.getResourceNameAttribute(resource.ref);
this.parameterArn = util_1.arnForParameterName(this, this.parameterName, {
physicalName: props.parameterName || util_1.AUTOGEN_MARKER,
simpleName: props.simpleName,
});
this.parameterType = resource.attrType;
this.stringListValue = core_1.Fn.split(',', resource.attrValue);
}
/**
* Imports an external parameter of type string list.
*
* Returns a token and should not be parsed.
*/
static fromStringListParameterName(scope, id, stringListParameterName) {
class Import extends ParameterBase {
constructor() {
super(...arguments);
this.parameterName = stringListParameterName;
this.parameterArn = util_1.arnForParameterName(this, this.parameterName);
this.parameterType = ParameterType.STRING_LIST;
this.stringListValue = core_1.Fn.split(',', new core_1.CfnDynamicReference(core_1.CfnDynamicReferenceService.SSM, stringListParameterName).toString());
}
}
return new Import(scope, id);
}
}
exports.StringListParameter = StringListParameter;
/**
* Validates whether a supplied value conforms to the allowedPattern, granted neither is an unresolved token.
*
* @param value the value to be validated.
* @param allowedPattern the regular expression to use for validation.
*
* @throws if the ``value`` does not conform to the ``allowedPattern`` and neither is an unresolved token (per
* ``cdk.unresolved``).
*/
function _assertValidValue(value, allowedPattern) {
if (core_1.Token.isUnresolved(value) || core_1.Token.isUnresolved(allowedPattern)) {
// Unable to perform validations against unresolved tokens
return;
}
if (!new RegExp(allowedPattern).test(value)) {
throw new Error(`The supplied value (${value}) does not match the specified allowedPattern (${allowedPattern})`);
}
}
function makeIdentityForImportedValue(parameterName) {
return `SsmParameterValue:${parameterName}:C96584B6-F00A-464E-AD19-53AFF4B05118`;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyYW1ldGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicGFyYW1ldGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHdDQUF3QztBQUV4QywyREFBMkQ7QUFDM0Qsd0NBR3VCO0FBRXZCLHVDQUF1QztBQUN2QyxpQ0FBNkQ7QUE2STdEOztHQUVHO0FBQ0gsTUFBZSxhQUFjLFNBQVEsZUFBUTs7OztJQVlwQyxTQUFTLENBQUMsT0FBdUI7UUFDdEMsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQ3RCLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQzFDO1FBQ0QsT0FBTyxHQUFHLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQztZQUM5QixPQUFPO1lBQ1AsT0FBTyxFQUFFO2dCQUNQLHdCQUF3QjtnQkFDeEIsbUJBQW1CO2dCQUNuQixrQkFBa0I7Z0JBQ2xCLHlCQUF5QjthQUMxQjtZQUNELFlBQVksRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUM7U0FDbEMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7OztJQUVNLFVBQVUsQ0FBQyxPQUF1QjtRQUN2QyxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDdEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDMUM7UUFDRCxPQUFPLEdBQUcsQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDO1lBQzlCLE9BQU87WUFDUCxPQUFPLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQztZQUM3QixZQUFZLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO1NBQ2xDLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjs7OztBQUtELElBQVksYUFrQlg7QUFsQkQsV0FBWSxhQUFhO0lBSXZCLGtDQUFpQixDQUFBO0lBS2pCLCtDQUE4QixDQUFBO0lBSTlCLDJDQUEwQixDQUFBO0lBSTFCLHlEQUF3QyxDQUFBO0FBQzFDLENBQUMsRUFs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QUN6RCxPQUFPLHFCQUFxQixhQUFhLHVDQUF1QyxDQUFDO0FBQ25GLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBpYW0gZnJvbSAnQGF3cy1jZGsvYXdzLWlhbSc7XG5pbXBvcnQgKiBhcyBrbXMgZnJvbSAnQGF3cy1jZGsvYXdzLWttcyc7XG5pbXBvcnQgKiBhcyBjeHNjaGVtYSBmcm9tICdAYXdzLWNkay9jbG91ZC1hc3NlbWJseS1zY2hlbWEnO1xuaW1wb3J0IHtcbiAgQ2ZuRHluYW1pY1JlZmVyZW5jZSwgQ2ZuRHluYW1pY1JlZmVyZW5jZVNlcnZpY2UsIENmblBhcmFtZXRlcixcbiAgQ29uc3RydWN0IGFzIENvbXBhdENvbnN0cnVjdCwgQ29udGV4dFByb3ZpZGVyLCBGbiwgSVJlc291cmNlLCBSZXNvdXJjZSwgU3RhY2ssIFRva2VuLFxufSBmcm9tICdAYXdzLWNkay9jb3JlJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0ICogYXMgc3NtIGZyb20gJy4vc3NtLmdlbmVyYXRlZCc7XG5pbXBvcnQgeyBhcm5Gb3JQYXJhbWV0ZXJOYW1lLCBBVVRPR0VOX01BUktFUiB9IGZyb20gJy4vdXRpbCc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5leHBvcnQgaW50ZXJmYWNlIElQYXJhbWV0ZXIgZXh0ZW5kcyBJUmVzb3VyY2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgcGFyYW1ldGVyQXJuOiBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBwYXJhbWV0ZXJOYW1lOiBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBwYXJhbWV0ZXJUeXBlOiBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIGdyYW50UmVhZChncmFudGVlOiBpYW0uSUdyYW50YWJsZSk6IGlhbS5HcmFudDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBncmFudFdyaXRlKGdyYW50ZWU6IGlhbS5JR3JhbnRhYmxlKTogaWFtLkdyYW50O1xufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5leHBvcnQgaW50ZXJmYWNlIElTdHJpbmdQYXJhbWV0ZXIgZXh0ZW5kcyBJUGFyYW1ldGVyIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgc3RyaW5nVmFsdWU6IHN0cmluZztcbn1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBpbnRlcmZhY2UgSVN0cmluZ0xpc3RQYXJhbWV0ZXIgZXh0ZW5kcyBJUGFyYW1ldGVyIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBzdHJpbmdMaXN0VmFsdWU6IHN0cmluZ1tdO1xufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGludGVyZmFjZSBQYXJhbWV0ZXJPcHRpb25zIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgYWxsb3dlZFBhdHRlcm4/OiBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBkZXNjcmlwdGlvbj86IHN0cmluZztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgcGFyYW1ldGVyTmFtZT86IHN0cmluZztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHNpbXBsZU5hbWU/OiBib29sZWFuO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSB0aWVyPzogUGFyYW1ldGVyVGllcjtcbn1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBpbnRlcmZhY2UgU3RyaW5nUGFyYW1ldGVyUHJvcHMgZXh0ZW5kcyBQYXJhbWV0ZXJPcHRpb25zIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHN0cmluZ1ZhbHVlOiBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHR5cGU/OiBQYXJhbWV0ZXJUeXBlO1xufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGludGVyZmFjZSBTdHJpbmdMaXN0UGFyYW1ldGVyUHJvcHMgZXh0ZW5kcyBQYXJhbWV0ZXJPcHRpb25zIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBzdHJpbmdMaXN0VmFsdWU6IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIEJhc2ljIGZlYXR1cmVzIHNoYXJlZCBhY3Jvc3MgYWxsIHR5cGVzIG9mIFNTTSBQYXJhbWV0ZXJzLlxuICovXG5hYnN0cmFjdCBjbGFzcyBQYXJhbWV0ZXJCYXNlIGV4dGVuZHMgUmVzb3VyY2UgaW1wbGVtZW50cyBJUGFyYW1ldGVyIHtcbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IHBhcmFtZXRlckFybjogc3RyaW5nO1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgcGFyYW1ldGVyTmFtZTogc3RyaW5nO1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgcGFyYW1ldGVyVHlwZTogc3RyaW5nO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHJlYWRvbmx5IGVuY3J5cHRpb25LZXk/OiBrbXMuSUtleTtcblxuICBwdWJsaWMgZ3JhbnRSZWFkKGdyYW50ZWU6IGlhbS5JR3JhbnRhYmxlKTogaWFtLkdyYW50IHtcbiAgICBpZiAodGhpcy5lbmNyeXB0aW9uS2V5KSB7XG4gICAgICB0aGlzLmVuY3J5cHRpb25LZXkuZ3JhbnREZWNyeXB0KGdyYW50ZWUpO1xuICAgIH1cbiAgICByZXR1cm4gaWFtLkdyYW50LmFkZFRvUHJpbmNpcGFsKHtcbiAgICAgIGdyYW50ZWUsXG4gICAgICBhY3Rpb25zOiBbXG4gICAgICAgICdzc206RGVzY3JpYmVQYXJhbWV0ZXJzJyxcbiAgICAgICAgJ3NzbTpHZXRQYXJhbWV0ZXJzJyxcbiAgICAgICAgJ3NzbTpHZXRQYXJhbWV0ZXInLFxuICAgICAgICAnc3NtOkdldFBhcmFtZXRlckhpc3RvcnknLFxuICAgICAgXSxcbiAgICAgIHJlc291cmNlQXJuczogW3RoaXMucGFyYW1ldGVyQXJuXSxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBncmFudFdyaXRlKGdyYW50ZWU6IGlhbS5JR3JhbnRhYmxlKTogaWFtLkdyYW50IHtcbiAgICBpZiAodGhpcy5lbmNyeXB0aW9uS2V5KSB7XG4gICAgICB0aGlzLmVuY3J5cHRpb25LZXkuZ3JhbnRFbmNyeXB0KGdyYW50ZWUpO1xuICAgIH1cbiAgICByZXR1cm4gaWFtLkdyYW50LmFkZFRvUHJpbmNpcGFsKHtcbiAgICAgIGdyYW50ZWUsXG4gICAgICBhY3Rpb25zOiBbJ3NzbTpQdXRQYXJhbWV0ZXInXSxcbiAgICAgIHJlc291cmNlQXJuczogW3RoaXMucGFyYW1ldGVyQXJuXSxcbiAgICB9KTtcbiAgfVxufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGVudW0gUGFyYW1ldGVyVHlwZSB7XG4gICAgICAgICAgICAgICAgICAgICAgIFxuICBTVFJJTkcgPSAnU3RyaW5nJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBTRUNVUkVfU1RSSU5HID0gJ1NlY3VyZVN0cmluZycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIFNUUklOR19MSVNUID0gJ1N0cmluZ0xpc3QnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBBV1NfRUMyX0lNQUdFX0lEID0gJ0FXUzo6RUMyOjpJbWFnZTo6SWQnLFxufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGVudW0gUGFyYW1ldGVyVGllciB7XG4gICAgICAgICAgICAgICAgICAgICAgIFxuICBBRFZBTkNFRCA9ICdBZHZhbmNlZCcsXG4gICAgICAgICAgICAgICAgICAgICAgIFxuICBJTlRFTExJR0VOVF9USUVSSU5HID0gJ0ludGVsbGlnZW50LVRpZXJpbmcnLFxuICAgICAgICAgICAgICAgICAgICAgICBcbiAgU1RBTkRBUkQgPSAnU3RhbmRhcmQnLFxufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBpbnRlcmZhY2UgQ29tbW9uU3RyaW5nUGFyYW1ldGVyQXR0cmlidXRlcyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHBhcmFtZXRlck5hbWU6IHN0cmluZztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHNpbXBsZU5hbWU/OiBib29sZWFuO1xufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGludGVyZmFjZSBTdHJpbmdQYXJhbWV0ZXJBdHRyaWJ1dGVzIGV4dGVuZHMgQ29tbW9uU3RyaW5nUGFyYW1ldGVyQXR0cmlidXRlcyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHZlcnNpb24/OiBudW1iZXI7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHR5cGU/OiBQYXJhbWV0ZXJUeXBlO1xufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBpbnRlcmZhY2UgU2VjdXJlU3RyaW5nUGFyYW1ldGVyQXR0cmlidXRlcyBleHRlbmRzIENvbW1vblN0cmluZ1BhcmFtZXRlckF0dHJpYnV0ZXMge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgdmVyc2lvbjogbnVtYmVyO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgZW5jcnlwdGlvbktleT86IGttcy5JS2V5O1xuXG59XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBjbGFzcyBTdHJpbmdQYXJhbWV0ZXIgZXh0ZW5kcyBQYXJhbWV0ZXJCYXNlIGltcGxlbWVudHMgSVN0cmluZ1BhcmFtZXRlciB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBzdGF0aWMgZnJvbVN0cmluZ1BhcmFtZXRlck5hbWUoc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgc3RyaW5nUGFyYW1ldGVyTmFtZTogc3RyaW5nKTogSVN0cmluZ1BhcmFtZXRlciB7XG4gICAgcmV0dXJuIHRoaXMuZnJvbVN0cmluZ1BhcmFtZXRlckF0dHJpYnV0ZXMoc2NvcGUsIGlkLCB7IHBhcmFtZXRlck5hbWU6IHN0cmluZ1BhcmFtZXRlck5hbWUgfSk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIGZyb21TdHJpbmdQYXJhbWV0ZXJBdHRyaWJ1dGVzKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIGF0dHJzOiBTdHJpbmdQYXJhbWV0ZXJBdHRyaWJ1dGVzKTogSVN0cmluZ1BhcmFtZXRlciB7XG4gICAgaWYgKCFhdHRycy5wYXJhbWV0ZXJOYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3BhcmFtZXRlck5hbWUgY2Fubm90IGJlIGFuIGVtcHR5IHN0cmluZycpO1xuICAgIH1cblxuICAgIGNvbnN0IHR5cGUgPSBhdHRycy50eXBlIHx8IFBhcmFtZXRlclR5cGUuU1RSSU5HO1xuXG4gICAgY29uc3Qgc3RyaW5nVmFsdWUgPSBhdHRycy52ZXJzaW9uXG4gICAgICA/IG5ldyBDZm5EeW5hbWljUmVmZXJlbmNlKENmbkR5bmFtaWNSZWZlcmVuY2VTZXJ2aWNlLlNTTSwgYCR7YXR0cnMucGFyYW1ldGVyTmFtZX06JHthdHRycy52ZXJzaW9ufWApLnRvU3RyaW5nKClcbiAgICAgIDogbmV3IENmblBhcmFtZXRlcihzY29wZSBhcyBDb21wYXRDb25zdHJ1Y3QsIGAke2lkfS5QYXJhbWV0ZXJgLCB7IHR5cGU6IGBBV1M6OlNTTTo6UGFyYW1ldGVyOjpWYWx1ZTwke3R5cGV9PmAsIGRlZmF1bHQ6IGF0dHJzLnBhcmFtZXRlck5hbWUgfSkudmFsdWVBc1N0cmluZztcblxuICAgIGNsYXNzIEltcG9ydCBleHRlbmRzIFBhcmFtZXRlckJhc2Uge1xuICAgICAgcHVibGljIHJlYWRvbmx5IHBhcmFtZXRlck5hbWUgPSBhdHRycy5wYXJhbWV0ZXJOYW1lO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHBhcmFtZXRlckFybiA9IGFybkZvclBhcmFtZXRlck5hbWUodGhpcywgYXR0cnMucGFyYW1ldGVyTmFtZSwgeyBzaW1wbGVOYW1lOiBhdHRycy5zaW1wbGVOYW1lIH0pO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHBhcmFtZXRlclR5cGUgPSB0eXBlO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHN0cmluZ1ZhbHVlID0gc3RyaW5nVmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoc2NvcGUsIGlkKTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIGZyb21TZWN1cmVTdHJpbmdQYXJhbWV0ZXJBdHRyaWJ1dGVzKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIGF0dHJzOiBTZWN1cmVTdHJpbmdQYXJhbWV0ZXJBdHRyaWJ1dGVzKTogSVN0cmluZ1BhcmFtZXRlciB7XG4gICAgY29uc3Qgc3RyaW5nVmFsdWUgPSBuZXcgQ2ZuRHluYW1pY1JlZmVyZW5jZShDZm5EeW5hbWljUmVmZXJlbmNlU2VydmljZS5TU01fU0VDVVJFLCBgJHthdHRycy5wYXJhbWV0ZXJOYW1lfToke2F0dHJzLnZlcnNpb259YCkudG9TdHJpbmcoKTtcblxuICAgIGNsYXNzIEltcG9ydCBleHRlbmRzIFBhcmFtZXRlckJhc2Uge1xuICAgICAgcHVibGljIHJlYWRvbmx5IHBhcmFtZXRlck5hbWUgPSBhdHRycy5wYXJhbWV0ZXJOYW1lO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHBhcmFtZXRlckFybiA9IGFybkZvclBhcmFtZXRlck5hbWUodGhpcywgYXR0cnMucGFyYW1ldGVyTmFtZSwgeyBzaW1wbGVOYW1lOiBhdHRycy5zaW1wbGVOYW1lIH0pO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHBhcmFtZXRlclR5cGUgPSBQYXJhbWV0ZXJUeXBlLlNFQ1VSRV9TVFJJTkc7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgc3RyaW5nVmFsdWUgPSBzdHJpbmdWYWx1ZTtcbiAgICAgIHB1YmxpYyByZWFkb25seSBlbmNyeXB0aW9uS2V5ID0gYXR0cnMuZW5jcnlwdGlvbktleTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEltcG9ydChzY29wZSwgaWQpO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIHZhbHVlRnJvbUxvb2t1cChzY29wZTogQ29tcGF0Q29uc3RydWN0LCBwYXJhbWV0ZXJOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHZhbHVlID0gQ29udGV4dFByb3ZpZGVyLmdldFZhbHVlKHNjb3BlLCB7XG4gICAgICBwcm92aWRlcjogY3hzY2hlbWEuQ29udGV4dFByb3ZpZGVyLlNTTV9QQVJBTUVURVJfUFJPVklERVIsXG4gICAgICBwcm9wczogeyBwYXJhbWV0ZXJOYW1lIH0sXG4gICAgICBkdW1teVZhbHVlOiBgZHVtbXktdmFsdWUtZm9yLSR7cGFyYW1ldGVyTmFtZX1gLFxuICAgIH0pLnZhbHVlO1xuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyB2YWx1ZUZvclN0cmluZ1BhcmFtZXRlcihzY29wZTogQ29uc3RydWN0LCBwYXJhbWV0ZXJOYW1lOiBzdHJpbmcsIHZlcnNpb24/OiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiBTdHJpbmdQYXJhbWV0ZXIudmFsdWVGb3JUeXBlZFN0cmluZ1BhcmFtZXRlcihzY29wZSwgcGFyYW1ldGVyTmFtZSwgUGFyYW1ldGVyVHlwZS5TVFJJTkcsIHZlcnNpb24pO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyB2YWx1ZUZvclR5cGVkU3RyaW5nUGFyYW1ldGVyKHNjb3BlOiBDb25zdHJ1Y3QsIHBhcmFtZXRlck5hbWU6IHN0cmluZywgdHlwZSA9IFBhcmFtZXRlclR5cGUuU1RSSU5HLCB2ZXJzaW9uPzogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHNjb3BlKTtcbiAgICBjb25zdCBpZCA9IG1ha2VJZGVudGl0eUZvckltcG9ydGVkVmFsdWUocGFyYW1ldGVyTmFtZSk7XG4gICAgY29uc3QgZXhpc3RzID0gc3RhY2subm9kZS50cnlGaW5kQ2hpbGQoaWQpIGFzIElTdHJpbmdQYXJhbWV0ZXI7XG5cbiAgICBpZiAoZXhpc3RzKSB7IHJldHVybiBleGlzdHMuc3RyaW5nVmFsdWU7IH1cblxuICAgIHJldHVybiB0aGlzLmZyb21TdHJpbmdQYXJhbWV0ZXJBdHRyaWJ1dGVzKHN0YWNrLCBpZCwgeyBwYXJhbWV0ZXJOYW1lLCB2ZXJzaW9uLCB0eXBlIH0pLnN0cmluZ1ZhbHVlO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBzdGF0aWMgdmFsdWVGb3JTZWN1cmVTdHJpbmdQYXJhbWV0ZXIoc2NvcGU6IENvbnN0cnVjdCwgcGFyYW1ldGVyTmFtZTogc3RyaW5nLCB2ZXJzaW9uOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGNvbnN0IHN0YWNrID0gU3RhY2sub2Yoc2NvcGUpO1xuICAgIGNvbnN0IGlkID0gbWFrZUlkZW50aXR5Rm9ySW1wb3J0ZWRWYWx1ZShwYXJhbWV0ZXJOYW1lKTtcbiAgICBjb25zdCBleGlzdHMgPSBzdGFjay5ub2RlLnRyeUZpbmRDaGlsZChpZCkgYXMgSVN0cmluZ1BhcmFtZXRlcjtcbiAgICBpZiAoZXhpc3RzKSB7IHJldHVybiBleGlzdHMuc3RyaW5nVmFsdWU7IH1cblxuICAgIHJldHVybiB0aGlzLmZyb21TZWN1cmVTdHJpbmdQYXJhbWV0ZXJBdHRyaWJ1dGVzKHN0YWNrLCBpZCwgeyBwYXJhbWV0ZXJOYW1lLCB2ZXJzaW9uIH0pLnN0cmluZ1ZhbHVlO1xuICB9XG5cbiAgcHVibGljIHJlYWRvbmx5IHBhcmFtZXRlckFybjogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgcGFyYW1ldGVyTmFtZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgcGFyYW1ldGVyVHlwZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgc3RyaW5nVmFsdWU6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogU3RyaW5nUGFyYW1ldGVyUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIHBoeXNpY2FsTmFtZTogcHJvcHMucGFyYW1ldGVyTmFtZSxcbiAgICB9KTtcblxuICAgIGlmIChwcm9wcy5hbGxvd2VkUGF0dGVybikge1xuICAgICAgX2Fzc2VydFZhbGlkVmFsdWUocHJvcHMuc3RyaW5nVmFsdWUsIHByb3BzLmFsbG93ZWRQYXR0ZXJuKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5waHlzaWNhbE5hbWUubGVuZ3RoID4gMjA0OCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdOYW1lIGNhbm5vdCBiZSBsb25nZXIgdGhhbiAyMDQ4IGNoYXJhY3RlcnMuJyk7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmRlc2NyaXB0aW9uICYmIHByb3BzLmRlc2NyaXB0aW9uPy5sZW5ndGggPiAxMDI0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Rlc2NyaXB0aW9uIGNhbm5vdCBiZSBsb25nZXIgdGhhbiAxMDI0IGNoYXJhY3RlcnMuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzb3VyY2UgPSBuZXcgc3NtLkNmblBhcmFtZXRlcih0aGlzLCAnUmVzb3VyY2UnLCB7XG4gICAgICBhbGxvd2VkUGF0dGVybjogcHJvcHMuYWxsb3dlZFBhdHRlcm4sXG4gICAgICBkZXNjcmlwdGlvbjogcHJvcHMuZGVzY3JpcHRpb24sXG4gICAgICBuYW1lOiB0aGlzLnBoeXNpY2FsTmFtZSxcbiAgICAgIHRpZXI6IHByb3BzLnRpZXIsXG4gICAgICB0eXBlOiBwcm9wcy50eXBlIHx8IFBhcmFtZXRlclR5cGUuU1RSSU5HLFxuICAgICAgdmFsdWU6IHByb3BzLnN0cmluZ1ZhbHVlLFxuICAgIH0pO1xuXG4gICAgdGhpcy5wYXJhbWV0ZXJOYW1lID0gdGhpcy5nZXRSZXNvdXJjZU5hbWVBdHRyaWJ1dGUocmVzb3VyY2UucmVmKTtcbiAgICB0aGlzLnBhcmFtZXRlckFybiA9IGFybkZvclBhcmFtZXRlck5hbWUodGhpcywgdGhpcy5wYXJhbWV0ZXJOYW1lLCB7XG4gICAgICBwaHlzaWNhbE5hbWU6IHByb3BzLnBhcmFtZXRlck5hbWUgfHwgQVVUT0dFTl9NQVJLRVIsXG4gICAgICBzaW1wbGVOYW1lOiBwcm9wcy5zaW1wbGVOYW1lLFxuICAgIH0pO1xuXG4gICAgdGhpcy5wYXJhbWV0ZXJUeXBlID0gcmVzb3VyY2UuYXR0clR5cGU7XG4gICAgdGhpcy5zdHJpbmdWYWx1ZSA9IHJlc291cmNlLmF0dHJWYWx1ZTtcbiAgfVxufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGNsYXNzIFN0cmluZ0xpc3RQYXJhbWV0ZXIgZXh0ZW5kcyBQYXJhbWV0ZXJCYXNlIGltcGxlbWVudHMgSVN0cmluZ0xpc3RQYXJhbWV0ZXIge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBmcm9tU3RyaW5nTGlzdFBhcmFtZXRlck5hbWUoc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgc3RyaW5nTGlzdFBhcmFtZXRlck5hbWU6IHN0cmluZyk6IElTdHJpbmdMaXN0UGFyYW1ldGVyIHtcbiAgICBjbGFzcyBJbXBvcnQgZXh0ZW5kcyBQYXJhbWV0ZXJCYXNlIHtcbiAgICAgIHB1YmxpYyByZWFkb25seSBwYXJhbWV0ZXJOYW1lID0gc3RyaW5nTGlzdFBhcmFtZXRlck5hbWU7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgcGFyYW1ldGVyQXJuID0gYXJuRm9yUGFyYW1ldGVyTmFtZSh0aGlzLCB0aGlzLnBhcmFtZXRlck5hbWUpO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHBhcmFtZXRlclR5cGUgPSBQYXJhbWV0ZXJUeXBlLlNUUklOR19MSVNUO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHN0cmluZ0xpc3RWYWx1ZSA9IEZuLnNwbGl0KCcsJywgbmV3IENmbkR5bmFtaWNSZWZlcmVuY2UoQ2ZuRHluYW1pY1JlZmVyZW5jZVNlcnZpY2UuU1NNLCBzdHJpbmdMaXN0UGFyYW1ldGVyTmFtZSkudG9TdHJpbmcoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoc2NvcGUsIGlkKTtcbiAgfVxuXG4gIHB1YmxpYyByZWFkb25seSBwYXJhbWV0ZXJBcm46IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHBhcmFtZXRlck5hbWU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHBhcmFtZXRlclR5cGU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHN0cmluZ0xpc3RWYWx1ZTogc3RyaW5nW107XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFN0cmluZ0xpc3RQYXJhbWV0ZXJQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwge1xuICAgICAgcGh5c2ljYWxOYW1lOiBwcm9wcy5wYXJhbWV0ZXJOYW1lLFxuICAgIH0pO1xuXG4gICAgaWYgKHByb3BzLnN0cmluZ0xpc3RWYWx1ZS5maW5kKHN0ciA9PiAhVG9rZW4uaXNVbnJlc29sdmVkKHN0cikgJiYgc3RyLmluZGV4T2YoJywnKSAhPT0gLTEpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1ZhbHVlcyBvZiBhIFN0cmluZ0xpc3QgU1NNIFBhcmFtZXRlciBjYW5ub3QgY29udGFpbiB0aGUgXFwnLFxcJyBjaGFyYWN0ZXIuIFVzZSBhIHN0cmluZyBwYXJhbWV0ZXIgaW5zdGVhZC4nKTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuYWxsb3dlZFBhdHRlcm4gJiYgIVRva2VuLmlzVW5yZXNvbHZlZChwcm9wcy5zdHJpbmdMaXN0VmFsdWUpKSB7XG4gICAgICBwcm9wcy5zdHJpbmdMaXN0VmFsdWUuZm9yRWFjaChzdHIgPT4gX2Fzc2VydFZhbGlkVmFsdWUoc3RyLCBwcm9wcy5hbGxvd2VkUGF0dGVybiEpKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5waHlzaWNhbE5hbWUubGVuZ3RoID4gMjA0OCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdOYW1lIGNhbm5vdCBiZSBsb25nZXIgdGhhbiAyMDQ4IGNoYXJhY3RlcnMuJyk7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmRlc2NyaXB0aW9uICYmIHByb3BzLmRlc2NyaXB0aW9uPy5sZW5ndGggPiAxMDI0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Rlc2NyaXB0aW9uIGNhbm5vdCBiZSBsb25nZXIgdGhhbiAxMDI0IGNoYXJhY3RlcnMuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzb3VyY2UgPSBuZXcgc3NtLkNmblBhcmFtZXRlcih0aGlzLCAnUmVzb3VyY2UnLCB7XG4gICAgICBhbGxvd2VkUGF0dGVybjogcHJvcHMuYWxsb3dlZFBhdHRlcm4sXG4gICAgICBkZXNjcmlwdGlvbjogcHJvcHMuZGVzY3JpcHRpb24sXG4gICAgICBuYW1lOiB0aGlzLnBoeXNpY2FsTmFtZSxcbiAgICAgIHRpZXI6IHByb3BzLnRpZXIsXG4gICAgICB0eXBlOiBQYXJhbWV0ZXJUeXBlLlNUUklOR19MSVNULFxuICAgICAgdmFsdWU6IHByb3BzLnN0cmluZ0xpc3RWYWx1ZS5qb2luKCcsJyksXG4gICAgfSk7XG4gICAgdGhpcy5wYXJhbWV0ZXJOYW1lID0gdGhpcy5nZXRSZXNvdXJjZU5hbWVBdHRyaWJ1dGUocmVzb3VyY2UucmVmKTtcbiAgICB0aGlzLnBhcmFtZXRlckFybiA9IGFybkZvclBhcmFtZXRlck5hbWUodGhpcywgdGhpcy5wYXJhbWV0ZXJOYW1lLCB7XG4gICAgICBwaHlzaWNhbE5hbWU6IHByb3BzLnBhcmFtZXRlck5hbWUgfHwgQVVUT0dFTl9NQVJLRVIsXG4gICAgICBzaW1wbGVOYW1lOiBwcm9wcy5zaW1wbGVOYW1lLFxuICAgIH0pO1xuXG4gICAgdGhpcy5wYXJhbWV0ZXJUeXBlID0gcmVzb3VyY2UuYXR0clR5cGU7XG4gICAgdGhpcy5zdHJpbmdMaXN0VmFsdWUgPSBGbi5zcGxpdCgnLCcsIHJlc291cmNlLmF0dHJWYWx1ZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgd2hldGhlciBhIHN1cHBsaWVkIHZhbHVlIGNvbmZvcm1zIHRvIHRoZSBhbGxvd2VkUGF0dGVybiwgZ3JhbnRlZCBuZWl0aGVyIGlzIGFuIHVucmVzb2x2ZWQgdG9rZW4uXG4gKlxuICogQHBhcmFtIHZhbHVlICAgICAgICAgIHRoZSB2YWx1ZSB0byBiZSB2YWxpZGF0ZWQuXG4gKiBAcGFyYW0gYWxsb3dlZFBhdHRlcm4gdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byB1c2UgZm9yIHZhbGlkYXRpb24uXG4gKlxuICogQHRocm93cyBpZiB0aGUgYGB2YWx1ZWBgIGRvZXMgbm90IGNvbmZvcm0gdG8gdGhlIGBgYWxsb3dlZFBhdHRlcm5gYCBhbmQgbmVpdGhlciBpcyBhbiB1bnJlc29sdmVkIHRva2VuIChwZXJcbiAqICAgICAgICAgYGBjZGsudW5yZXNvbHZlZGBgKS5cbiAqL1xuZnVuY3Rpb24gX2Fzc2VydFZhbGlkVmFsdWUodmFsdWU6IHN0cmluZywgYWxsb3dlZFBhdHRlcm46IHN0cmluZyk6IHZvaWQge1xuICBpZiAoVG9rZW4uaXNVbnJlc29sdmVkKHZhbHVlKSB8fCBUb2tlbi5pc1VucmVzb2x2ZWQoYWxsb3dlZFBhdHRlcm4pKSB7XG4gICAgLy8gVW5hYmxlIHRvIHBlcmZvcm0gdmFsaWRhdGlvbnMgYWdhaW5zdCB1bnJlc29sdmVkIHRva2Vuc1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoIW5ldyBSZWdFeHAoYWxsb3dlZFBhdHRlcm4pLnRlc3QodmFsdWUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgc3VwcGxpZWQgdmFsdWUgKCR7dmFsdWV9KSBkb2VzIG5vdCBtYXRjaCB0aGUgc3BlY2lmaWVkIGFsbG93ZWRQYXR0ZXJuICgke2FsbG93ZWRQYXR0ZXJufSlgKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtYWtlSWRlbnRpdHlGb3JJbXBvcnRlZFZhbHVlKHBhcmFtZXRlck5hbWU6IHN0cmluZykge1xuICByZXR1cm4gYFNzbVBhcmFtZXRlclZhbHVlOiR7cGFyYW1ldGVyTmFtZX06Qzk2NTg0QjYtRjAwQS00NjRFLUFEMTktNTNBRkY0QjA1MTE4YDtcbn1cbiJdfQ==