UNPKG

@aws-cdk/aws-ec2

Version:

The CDK Construct Library for AWS::EC2

310 lines 54.2 kB
"use strict"; var _a, _b; Object.defineProperty(exports, "__esModule", { value: true }); exports.LaunchTemplate = exports.LaunchTemplateSpecialVersions = exports.SpotRequestType = exports.SpotInstanceInterruption = exports.InstanceInitiatedShutdownBehavior = exports.CpuCredits = void 0; const jsiiDeprecationWarnings = require("../.warnings.jsii.js"); const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const iam = require("@aws-cdk/aws-iam"); const core_1 = require("@aws-cdk/core"); const _1 = require("."); const connections_1 = require("./connections"); const ec2_generated_1 = require("./ec2.generated"); const ebs_util_1 = require("./private/ebs-util"); /** * Name tag constant */ const NAME_TAG = 'Name'; /** * Provides the options for specifying the CPU credit type for burstable EC2 instance types (T2, T3, T3a, etc). * * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/burstable-performance-instances-how-to.html */ // dev-note: This could be used in the Instance L2 var CpuCredits; (function (CpuCredits) { /** * Standard bursting mode. * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/burstable-performance-instances-standard-mode.html */ CpuCredits["STANDARD"] = "standard"; /** * Unlimited bursting mode. * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/burstable-performance-instances-unlimited-mode.html */ CpuCredits["UNLIMITED"] = "unlimited"; })(CpuCredits = exports.CpuCredits || (exports.CpuCredits = {})); ; /** * Provides the options for specifying the instance initiated shutdown behavior. * * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/terminating-instances.html#Using_ChangingInstanceInitiatedShutdownBehavior */ // dev-note: This could be used in the Instance L2 var InstanceInitiatedShutdownBehavior; (function (InstanceInitiatedShutdownBehavior) { /** * The instance will stop when it initiates a shutdown. */ InstanceInitiatedShutdownBehavior["STOP"] = "stop"; /** * The instance will be terminated when it initiates a shutdown. */ InstanceInitiatedShutdownBehavior["TERMINATE"] = "terminate"; })(InstanceInitiatedShutdownBehavior = exports.InstanceInitiatedShutdownBehavior || (exports.InstanceInitiatedShutdownBehavior = {})); ; /** * Provides the options for the types of interruption for spot instances. */ // dev-note: This could be used in a SpotFleet L2 if one gets developed. var SpotInstanceInterruption; (function (SpotInstanceInterruption) { /** * The instance will stop when interrupted. */ SpotInstanceInterruption["STOP"] = "stop"; /** * The instance will be terminated when interrupted. */ SpotInstanceInterruption["TERMINATE"] = "terminate"; /** * The instance will hibernate when interrupted. */ SpotInstanceInterruption["HIBERNATE"] = "hibernate"; })(SpotInstanceInterruption = exports.SpotInstanceInterruption || (exports.SpotInstanceInterruption = {})); /** * The Spot Instance request type. * * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html */ var SpotRequestType; (function (SpotRequestType) { /** * A one-time Spot Instance request remains active until Amazon EC2 launches the Spot Instance, * the request expires, or you cancel the request. If the Spot price exceeds your maximum price * or capacity is not available, your Spot Instance is terminated and the Spot Instance request * is closed. */ SpotRequestType["ONE_TIME"] = "one-time"; /** * A persistent Spot Instance request remains active until it expires or you cancel it, even if * the request is fulfilled. If the Spot price exceeds your maximum price or capacity is not available, * your Spot Instance is interrupted. After your instance is interrupted, when your maximum price exceeds * the Spot price or capacity becomes available again, the Spot Instance is started if stopped or resumed * if hibernated. */ SpotRequestType["PERSISTENT"] = "persistent"; })(SpotRequestType = exports.SpotRequestType || (exports.SpotRequestType = {})); ; /** * A class that provides convenient access to special version tokens for LaunchTemplate * versions. */ class LaunchTemplateSpecialVersions { } exports.LaunchTemplateSpecialVersions = LaunchTemplateSpecialVersions; _a = JSII_RTTI_SYMBOL_1; LaunchTemplateSpecialVersions[_a] = { fqn: "@aws-cdk/aws-ec2.LaunchTemplateSpecialVersions", version: "1.204.0" }; /** * The special value that denotes that users of a Launch Template should * reference the LATEST version of the template. */ LaunchTemplateSpecialVersions.LATEST_VERSION = '$Latest'; /** * The special value that denotes that users of a Launch Template should * reference the DEFAULT version of the template. */ LaunchTemplateSpecialVersions.DEFAULT_VERSION = '$Default'; /** * This represents an EC2 LaunchTemplate. * * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-launch-templates.html */ class LaunchTemplate extends core_1.Resource { // ============================================= constructor(scope, id, props = {}) { super(scope, id); try { jsiiDeprecationWarnings._aws_cdk_aws_ec2_LaunchTemplateProps(props); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, LaunchTemplate); } throw error; } // Basic validation of the provided spot block duration const spotDuration = props?.spotOptions?.blockDuration?.toHours({ integral: true }); if (spotDuration !== undefined && (spotDuration < 1 || spotDuration > 6)) { // See: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html#fixed-duration-spot-instances core_1.Annotations.of(this).addError('Spot block duration must be exactly 1, 2, 3, 4, 5, or 6 hours.'); } this.role = props.role; this._grantPrincipal = this.role; const iamProfile = this.role ? new iam.CfnInstanceProfile(this, 'Profile', { roles: [this.role.roleName], }) : undefined; if (props.securityGroup) { this._connections = new connections_1.Connections({ securityGroups: [props.securityGroup] }); } const securityGroupsToken = core_1.Lazy.list({ produce: () => { if (this._connections && this._connections.securityGroups.length > 0) { return this._connections.securityGroups.map(sg => sg.securityGroupId); } return undefined; }, }); if (props.userData) { this.userData = props.userData; } const userDataToken = core_1.Lazy.string({ produce: () => { if (this.userData) { return core_1.Fn.base64(this.userData.render()); } return undefined; }, }); const imageConfig = props.machineImage?.getImage(this); if (imageConfig) { this.osType = imageConfig.osType; this.imageId = imageConfig.imageId; } this.instanceType = props.instanceType; let marketOptions = undefined; if (props?.spotOptions) { marketOptions = { marketType: 'spot', spotOptions: { blockDurationMinutes: spotDuration !== undefined ? spotDuration * 60 : undefined, instanceInterruptionBehavior: props.spotOptions.interruptionBehavior, maxPrice: props.spotOptions.maxPrice?.toString(), spotInstanceType: props.spotOptions.requestType, validUntil: props.spotOptions.validUntil?.date.toUTCString(), }, }; // Remove SpotOptions if there are none. if (Object.keys(marketOptions.spotOptions).filter(k => marketOptions.spotOptions[k]).length == 0) { marketOptions.spotOptions = undefined; } } this.tags = new core_1.TagManager(core_1.TagType.KEY_VALUE, 'AWS::EC2::LaunchTemplate'); const tagsToken = core_1.Lazy.any({ produce: () => { if (this.tags.hasTags()) { const renderedTags = this.tags.renderTags(); const lowerCaseRenderedTags = renderedTags.map((tag) => { return { key: tag.Key, value: tag.Value, }; }); return [ { resourceType: 'instance', tags: lowerCaseRenderedTags, }, { resourceType: 'volume', tags: lowerCaseRenderedTags, }, ]; } return undefined; }, }); const resource = new ec2_generated_1.CfnLaunchTemplate(this, 'Resource', { launchTemplateName: props?.launchTemplateName, launchTemplateData: { blockDeviceMappings: props?.blockDevices !== undefined ? ebs_util_1.launchTemplateBlockDeviceMappings(this, props.blockDevices) : undefined, creditSpecification: props?.cpuCredits !== undefined ? { cpuCredits: props.cpuCredits, } : undefined, disableApiTermination: props?.disableApiTermination, ebsOptimized: props?.ebsOptimized, enclaveOptions: props?.nitroEnclaveEnabled !== undefined ? { enabled: props.nitroEnclaveEnabled, } : undefined, hibernationOptions: props?.hibernationConfigured !== undefined ? { configured: props.hibernationConfigured, } : undefined, iamInstanceProfile: iamProfile !== undefined ? { arn: iamProfile.getAtt('Arn').toString(), } : undefined, imageId: imageConfig?.imageId, instanceType: props?.instanceType?.toString(), instanceInitiatedShutdownBehavior: props?.instanceInitiatedShutdownBehavior, instanceMarketOptions: marketOptions, keyName: props?.keyName, monitoring: props?.detailedMonitoring !== undefined ? { enabled: props.detailedMonitoring, } : undefined, securityGroupIds: securityGroupsToken, tagSpecifications: tagsToken, userData: userDataToken, }, }); core_1.Tags.of(this).add(NAME_TAG, this.node.path); this.defaultVersionNumber = resource.attrDefaultVersionNumber; this.latestVersionNumber = resource.attrLatestVersionNumber; this.launchTemplateId = resource.ref; this.versionNumber = core_1.Token.asString(resource.getAtt('LatestVersionNumber')); if (props.requireImdsv2) { core_1.Aspects.of(this).add(new _1.LaunchTemplateRequireImdsv2Aspect()); } } /** * Import an existing LaunchTemplate. */ static fromLaunchTemplateAttributes(scope, id, attrs) { try { jsiiDeprecationWarnings._aws_cdk_aws_ec2_LaunchTemplateAttributes(attrs); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.fromLaunchTemplateAttributes); } throw error; } const haveId = Boolean(attrs.launchTemplateId); const haveName = Boolean(attrs.launchTemplateName); if (haveId == haveName) { throw new Error('LaunchTemplate.fromLaunchTemplateAttributes() requires exactly one of launchTemplateId or launchTemplateName be provided.'); } class Import extends core_1.Resource { constructor() { super(...arguments); this.versionNumber = attrs.versionNumber ?? LaunchTemplateSpecialVersions.DEFAULT_VERSION; this.launchTemplateId = attrs.launchTemplateId; this.launchTemplateName = attrs.launchTemplateName; } } return new Import(scope, id); } /** * Allows specifying security group connections for the instance. * * @note Only available if you provide a securityGroup when constructing the LaunchTemplate. */ get connections() { if (!this._connections) { throw new Error('LaunchTemplate can only be used as IConnectable if a securityGroup is provided when constructing it.'); } return this._connections; } /** * Principal to grant permissions to. * * @note Only available if you provide a role when constructing the LaunchTemplate. */ get grantPrincipal() { if (!this._grantPrincipal) { throw new Error('LaunchTemplate can only be used as IGrantable if a role is provided when constructing it.'); } return this._grantPrincipal; } } exports.LaunchTemplate = LaunchTemplate; _b = JSII_RTTI_SYMBOL_1; LaunchTemplate[_b] = { fqn: "@aws-cdk/aws-ec2.LaunchTemplate", version: "1.204.0" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF1bmNoLXRlbXBsYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibGF1bmNoLXRlbXBsYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLHdDQUF3QztBQUV4Qyx3Q0FhdUI7QUFFdkIsd0JBQXNEO0FBQ3RELCtDQUEwRDtBQUMxRCxtREFBb0Q7QUFHcEQsaURBQXVFO0FBS3ZFOztHQUVHO0FBQ0gsTUFBTSxRQUFRLEdBQVcsTUFBTSxDQUFDO0FBRWhDOzs7O0dBSUc7QUFDSCxrREFBa0Q7QUFDbEQsSUFBWSxVQVlYO0FBWkQsV0FBWSxVQUFVO0lBQ3BCOzs7T0FHRztJQUNILG1DQUFxQixDQUFBO0lBRXJCOzs7T0FHRztJQUNILHFDQUF1QixDQUFBO0FBQ3pCLENBQUMsRUFaVyxVQUFVLEdBQVYsa0JBQVUsS0FBVixrQkFBVSxRQVlyQjtBQUFBLENBQUM7QUFFRjs7OztHQUlHO0FBQ0gsa0RBQWtEO0FBQ2xELElBQVksaUNBVVg7QUFWRCxXQUFZLGlDQUFpQztJQUMzQzs7T0FFRztJQUNILGtEQUFhLENBQUE7SUFFYjs7T0FFRztJQUNILDREQUF1QixDQUFBO0FBQ3pCLENBQUMsRUFWVyxpQ0FBaUMsR0FBakMseUNBQWlDLEtBQWpDLHlDQUFpQyxRQVU1QztBQUFBLENBQUM7QUFnQ0Y7O0dBRUc7QUFDSCx3RUFBd0U7QUFDeEUsSUFBWSx3QkFlWDtBQWZELFdBQVksd0JBQXdCO0lBQ2xDOztPQUVHO0lBQ0gseUNBQWEsQ0FBQTtJQUViOztPQUVHO0lBQ0gsbURBQXVCLENBQUE7SUFFdkI7O09BRUc7SUFDSCxtREFBdUIsQ0FBQTtBQUN6QixDQUFDLEVBZlcsd0JBQXdCLEdBQXhCLGdDQUF3QixLQUF4QixnQ0FBd0IsUUFlbkM7QUFFRDs7OztHQUlHO0FBQ0gsSUFBWSxlQWlCWDtBQWpCRCxXQUFZLGVBQWU7SUFDekI7Ozs7O09BS0c7SUFDSCx3Q0FBcUIsQ0FBQTtJQUVyQjs7Ozs7O09BTUc7SUFDSCw0Q0FBeUIsQ0FB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Q0FBQztLQUMxQjtJQUVEOzs7O09BSUc7SUFDSCxJQUFXLGNBQWM7UUFDdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUU7WUFDekIsTUFBTSxJQUFJLEtBQUssQ0FBQywyRkFBMkYsQ0FBQyxDQUFDO1NBQzlHO1FBQ0QsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDO0tBQzdCOztBQXZTSCx3Q0F3U0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBpYW0gZnJvbSAnQGF3cy1jZGsvYXdzLWlhbSc7XG5cbmltcG9ydCB7XG4gIEFubm90YXRpb25zLFxuICBEdXJhdGlvbixcbiAgRXhwaXJhdGlvbixcbiAgRm4sXG4gIElSZXNvdXJjZSxcbiAgTGF6eSxcbiAgUmVzb3VyY2UsXG4gIFRhZ01hbmFnZXIsXG4gIFRhZ1R5cGUsXG4gIFRhZ3MsXG4gIFRva2VuLFxuICBBc3BlY3RzLFxufSBmcm9tICdAYXdzLWNkay9jb3JlJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgTGF1bmNoVGVtcGxhdGVSZXF1aXJlSW1kc3YyQXNwZWN0IH0gZnJvbSAnLic7XG5pbXBvcnQgeyBDb25uZWN0aW9ucywgSUNvbm5lY3RhYmxlIH0gZnJvbSAnLi9jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBDZm5MYXVuY2hUZW1wbGF0ZSB9IGZyb20gJy4vZWMyLmdlbmVyYXRlZCc7XG5pbXBvcnQgeyBJbnN0YW5jZVR5cGUgfSBmcm9tICcuL2luc3RhbmNlLXR5cGVzJztcbmltcG9ydCB7IElNYWNoaW5lSW1hZ2UsIE1hY2hpbmVJbWFnZUNvbmZpZywgT3BlcmF0aW5nU3lzdGVtVHlwZSB9IGZyb20gJy4vbWFjaGluZS1pbWFnZSc7XG5pbXBvcnQgeyBsYXVuY2hUZW1wbGF0ZUJsb2NrRGV2aWNlTWFwcGluZ3MgfSBmcm9tICcuL3ByaXZhdGUvZWJzLXV0aWwnO1xuaW1wb3J0IHsgSVNlY3VyaXR5R3JvdXAgfSBmcm9tICcuL3NlY3VyaXR5LWdyb3VwJztcbmltcG9ydCB7IFVzZXJEYXRhIH0gZnJvbSAnLi91c2VyLWRhdGEnO1xuaW1wb3J0IHsgQmxvY2tEZXZpY2UgfSBmcm9tICcuL3ZvbHVtZSc7XG5cbi8qKlxuICogTmFtZSB0YWcgY29uc3RhbnRcbiAqL1xuY29uc3QgTkFNRV9UQUc6IHN0cmluZyA9ICdOYW1lJztcblxuLyoqXG4gKiBQcm92aWRlcyB0aGUgb3B0aW9ucyBmb3Igc3BlY2lmeWluZyB0aGUgQ1BVIGNyZWRpdCB0eXBlIGZvciBidXJzdGFibGUgRUMyIGluc3RhbmNlIHR5cGVzIChUMiwgVDMsIFQzYSwgZXRjKS5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NFQzIvbGF0ZXN0L1VzZXJHdWlkZS9idXJzdGFibGUtcGVyZm9ybWFuY2UtaW5zdGFuY2VzLWhvdy10by5odG1sXG4gKi9cbi8vIGRldi1ub3RlOiBUaGlzIGNvdWxkIGJlIHVzZWQgaW4gdGhlIEluc3RhbmNlIEwyXG5leHBvcnQgZW51bSBDcHVDcmVkaXRzIHtcbiAgLyoqXG4gICAqIFN0YW5kYXJkIGJ1cnN0aW5nIG1vZGUuXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0VDMi9sYXRlc3QvVXNlckd1aWRlL2J1cnN0YWJsZS1wZXJmb3JtYW5jZS1pbnN0YW5jZXMtc3RhbmRhcmQtbW9kZS5odG1sXG4gICAqL1xuICBTVEFOREFSRCA9ICdzdGFuZGFyZCcsXG5cbiAgLyoqXG4gICAqIFVubGltaXRlZCBidXJzdGluZyBtb2RlLlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NFQzIvbGF0ZXN0L1VzZXJHdWlkZS9idXJzdGFibGUtcGVyZm9ybWFuY2UtaW5zdGFuY2VzLXVubGltaXRlZC1tb2RlLmh0bWxcbiAgICovXG4gIFVOTElNSVRFRCA9ICd1bmxpbWl0ZWQnLFxufTtcblxuLyoqXG4gKiBQcm92aWRlcyB0aGUgb3B0aW9ucyBmb3Igc3BlY2lmeWluZyB0aGUgaW5zdGFuY2UgaW5pdGlhdGVkIHNodXRkb3duIGJlaGF2aW9yLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0VDMi9sYXRlc3QvVXNlckd1aWRlL3Rlcm1pbmF0aW5nLWluc3RhbmNlcy5odG1sI1VzaW5nX0NoYW5naW5nSW5zdGFuY2VJbml0aWF0ZWRTaHV0ZG93bkJlaGF2aW9yXG4gKi9cbi8vIGRldi1ub3RlOiBUaGlzIGNvdWxkIGJlIHVzZWQgaW4gdGhlIEluc3RhbmNlIEwyXG5leHBvcnQgZW51bSBJbnN0YW5jZUluaXRpYXRlZFNodXRkb3duQmVoYXZpb3Ige1xuICAvKipcbiAgICogVGhlIGluc3RhbmNlIHdpbGwgc3RvcCB3aGVuIGl0IGluaXRpYXRlcyBhIHNodXRkb3duLlxuICAgKi9cbiAgU1RPUCA9ICdzdG9wJyxcblxuICAvKipcbiAgICogVGhlIGluc3RhbmNlIHdpbGwgYmUgdGVybWluYXRlZCB3aGVuIGl0IGluaXRpYXRlcyBhIHNodXRkb3duLlxuICAgKi9cbiAgVEVSTUlOQVRFID0gJ3Rlcm1pbmF0ZScsXG59O1xuXG4vKipcbiAqIEludGVyZmFjZSBmb3IgTGF1bmNoVGVtcGxhdGUtbGlrZSBvYmplY3RzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIElMYXVuY2hUZW1wbGF0ZSBleHRlbmRzIElSZXNvdXJjZSB7XG4gIC8qKlxuICAgKiBUaGUgdmVyc2lvbiBudW1iZXIgb2YgdGhpcyBsYXVuY2ggdGVtcGxhdGUgdG8gdXNlXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IHZlcnNpb25OdW1iZXI6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGlkZW50aWZpZXIgb2YgdGhlIExhdW5jaCBUZW1wbGF0ZVxuICAgKlxuICAgKiBFeGFjdGx5IG9uZSBvZiBgbGF1bmNoVGVtcGxhdGVJZGAgYW5kIGBsYXVuY2hUZW1wbGF0ZU5hbWVgIHdpbGwgYmUgc2V0LlxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSBsYXVuY2hUZW1wbGF0ZUlkPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgTGF1bmNoIFRlbXBsYXRlXG4gICAqXG4gICAqIEV4YWN0bHkgb25lIG9mIGBsYXVuY2hUZW1wbGF0ZUlkYCBhbmQgYGxhdW5jaFRlbXBsYXRlTmFtZWAgd2lsbCBiZSBzZXQuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IGxhdW5jaFRlbXBsYXRlTmFtZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBQcm92aWRlcyB0aGUgb3B0aW9ucyBmb3IgdGhlIHR5cGVzIG9mIGludGVycnVwdGlvbiBmb3Igc3BvdCBpbnN0YW5jZXMuXG4gKi9cbi8vIGRldi1ub3RlOiBUaGlzIGNvdWxkIGJlIHVzZWQgaW4gYSBTcG90RmxlZXQgTDIgaWYgb25lIGdldHMgZGV2ZWxvcGVkLlxuZXhwb3J0IGVudW0gU3BvdEluc3RhbmNlSW50ZXJydXB0aW9uIHtcbiAgLyoqXG4gICAqIFRoZSBpbnN0YW5jZSB3aWxsIHN0b3Agd2hlbiBpbnRlcnJ1cHRlZC5cbiAgICovXG4gIFNUT1AgPSAnc3RvcCcsXG5cbiAgLyoqXG4gICAqIFRoZSBpbnN0YW5jZSB3aWxsIGJlIHRlcm1pbmF0ZWQgd2hlbiBpbnRlcnJ1cHRlZC5cbiAgICovXG4gIFRFUk1JTkFURSA9ICd0ZXJtaW5hdGUnLFxuXG4gIC8qKlxuICAgKiBUaGUgaW5zdGFuY2Ugd2lsbCBoaWJlcm5hdGUgd2hlbiBpbnRlcnJ1cHRlZC5cbiAgICovXG4gIEhJQkVSTkFURSA9ICdoaWJlcm5hdGUnLFxufVxuXG4vKipcbiAqIFRoZSBTcG90IEluc3RhbmNlIHJlcXVlc3QgdHlwZS5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NFQzIvbGF0ZXN0L1VzZXJHdWlkZS9zcG90LXJlcXVlc3RzLmh0bWxcbiAqL1xuZXhwb3J0IGVudW0gU3BvdFJlcXVlc3RUeXBlIHtcbiAgLyoqXG4gICAqIEEgb25lLXRpbWUgU3BvdCBJbnN0YW5jZSByZXF1ZXN0IHJlbWFpbnMgYWN0aXZlIHVudGlsIEFtYXpvbiBFQzIgbGF1bmNoZXMgdGhlIFNwb3QgSW5zdGFuY2UsXG4gICAqIHRoZSByZXF1ZXN0IGV4cGlyZXMsIG9yIHlvdSBjYW5jZWwgdGhlIHJlcXVlc3QuIElmIHRoZSBTcG90IHByaWNlIGV4Y2VlZHMgeW91ciBtYXhpbXVtIHByaWNlXG4gICAqIG9yIGNhcGFjaXR5IGlzIG5vdCBhdmFpbGFibGUsIHlvdXIgU3BvdCBJbnN0YW5jZSBpcyB0ZXJtaW5hdGVkIGFuZCB0aGUgU3BvdCBJbnN0YW5jZSByZXF1ZXN0XG4gICAqIGlzIGNsb3NlZC5cbiAgICovXG4gIE9ORV9USU1FID0gJ29uZS10aW1lJyxcblxuICAvKipcbiAgICogQSBwZXJzaXN0ZW50IFNwb3QgSW5zdGFuY2UgcmVxdWVzdCByZW1haW5zIGFjdGl2ZSB1bnRpbCBpdCBleHBpcmVzIG9yIHlvdSBjYW5jZWwgaXQsIGV2ZW4gaWZcbiAgICogdGhlIHJlcXVlc3QgaXMgZnVsZmlsbGVkLiBJZiB0aGUgU3BvdCBwcmljZSBleGNlZWRzIHlvdXIgbWF4aW11bSBwcmljZSBvciBjYXBhY2l0eSBpcyBub3QgYXZhaWxhYmxlLFxuICAgKiB5b3VyIFNwb3QgSW5zdGFuY2UgaXMgaW50ZXJydXB0ZWQuIEFmdGVyIHlvdXIgaW5zdGFuY2UgaXMgaW50ZXJydXB0ZWQsIHdoZW4geW91ciBtYXhpbXVtIHByaWNlIGV4Y2VlZHNcbiAgICogdGhlIFNwb3QgcHJpY2Ugb3IgY2FwYWNpdHkgYmVjb21lcyBhdmFpbGFibGUgYWdhaW4sIHRoZSBTcG90IEluc3RhbmNlIGlzIHN0YXJ0ZWQgaWYgc3RvcHBlZCBvciByZXN1bWVkXG4gICAqIGlmIGhpYmVybmF0ZWQuXG4gICAqL1xuICBQRVJTSVNURU5UID0gJ3BlcnNpc3RlbnQnLFxufVxuXG4vKipcbiAqIEludGVyZmFjZSBmb3IgdGhlIFNwb3QgbWFya2V0IGluc3RhbmNlIG9wdGlvbnMgcHJvdmlkZWQgaW4gYSBMYXVuY2hUZW1wbGF0ZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMYXVuY2hUZW1wbGF0ZVNwb3RPcHRpb25zIHtcbiAgLyoqXG4gICAqIFNwb3QgSW5zdGFuY2VzIHdpdGggYSBkZWZpbmVkIGR1cmF0aW9uIChhbHNvIGtub3duIGFzIFNwb3QgYmxvY2tzKSBhcmUgZGVzaWduZWQgbm90IHRvIGJlIGludGVycnVwdGVkIGFuZCB3aWxsIHJ1biBjb250aW51b3VzbHkgZm9yIHRoZSBkdXJhdGlvbiB5b3Ugc2VsZWN0LlxuICAgKiBZb3UgY2FuIHVzZSBhIGR1cmF0aW9uIG9mIDEsIDIsIDMsIDQsIDUsIG9yIDYgaG91cnMuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0VDMi9sYXRlc3QvVXNlckd1aWRlL3Nwb3QtcmVxdWVzdHMuaHRtbCNmaXhlZC1kdXJhdGlvbi1zcG90LWluc3RhbmNlc1xuICAgKlxuICAgKiBAZGVmYXVsdCBSZXF1ZXN0ZWQgc3BvdCBpbnN0YW5jZXMgZG8gbm90IGhhdmUgYSBwcmUtZGVmaW5lZCBkdXJhdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IGJsb2NrRHVyYXRpb24/OiBEdXJhdGlvbjtcblxuICAvKipcbiAgICogVGhlIGJlaGF2aW9yIHdoZW4gYSBTcG90IEluc3RhbmNlIGlzIGludGVycnVwdGVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBTcG90IGluc3RhbmNlcyB3aWxsIHRlcm1pbmF0ZSB3aGVuIGludGVycnVwdGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgaW50ZXJydXB0aW9uQmVoYXZpb3I/OiBTcG90SW5zdGFuY2VJbnRlcnJ1cHRpb247XG5cbiAgLyoqXG4gICAqIE1heGltdW0gaG91cmx5IHByaWNlIHlvdSdyZSB3aWxsaW5nIHRvIHBheSBmb3IgZWFjaCBTcG90IGluc3RhbmNlLiBUaGUgdmFsdWUgaXMgZ2l2ZW5cbiAgICogaW4gZG9sbGFycy4gZXg6IDAuMDEgZm9yIDEgY2VudCBwZXIgaG91ciwgb3IgMC4wMDEgZm9yIG9uZS10ZW50aCBvZiBhIGNlbnQgcGVyIGhvdXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IE1heGltdW0gaG91cmx5IHByaWNlIHdpbGwgZGVmYXVsdCB0byB0aGUgb24tZGVtYW5kIHByaWNlIGZvciB0aGUgaW5zdGFuY2UgdHlwZS5cbiAgICovXG4gIHJlYWRvbmx5IG1heFByaWNlPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgU3BvdCBJbnN0YW5jZSByZXF1ZXN0IHR5cGUuXG4gICAqXG4gICAqIElmIHlvdSBhcmUgdXNpbmcgU3BvdCBJbnN0YW5jZXMgd2l0aCBhbiBBdXRvIFNjYWxpbmcgZ3JvdXAsIHVzZSBvbmUtdGltZSByZXF1ZXN0cywgYXMgdGhlXG4gICAqIEFtYXpvbiBFQzIgQXV0byBTY2FsaW5nIHNlcnZpY2UgaGFuZGxlcyByZXF1ZXN0aW5nIG5ldyBTcG90IEluc3RhbmNlcyB3aGVuZXZlciB0aGUgZ3JvdXAgaXNcbiAgICogYmVsb3cgaXRzIGRlc2lyZWQgY2FwYWNpdHkuXG4gICAqXG4gICAqIEBkZWZhdWx0IE9uZS10aW1lIHNwb3QgcmVxdWVzdC5cbiAgICovXG4gIHJlYWRvbmx5IHJlcXVlc3RUeXBlPzogU3BvdFJlcXVlc3RUeXBlO1xuXG4gIC8qKlxuICAgKiBUaGUgZW5kIGRhdGUgb2YgdGhlIHJlcXVlc3QuIEZvciBhIG9uZS10aW1lIHJlcXVlc3QsIHRoZSByZXF1ZXN0IHJlbWFpbnMgYWN0aXZlIHVudGlsIGFsbCBpbnN0YW5jZXNcbiAgICogbGF1bmNoLCB0aGUgcmVxdWVzdCBpcyBjYW5jZWxlZCwgb3IgdGhpcyBkYXRlIGlzIHJlYWNoZWQuIElmIHRoZSByZXF1ZXN0IGlzIHBlcnNpc3RlbnQsIGl0IHJlbWFpbnNcbiAgICogYWN0aXZlIHVudGlsIGl0IGlzIGNhbmNlbGVkIG9yIHRoaXMgZGF0ZSBhbmQgdGltZSBpcyByZWFjaGVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBUaGUgZGVmYXVsdCBlbmQgZGF0ZSBpcyA3IGRheXMgZnJvbSB0aGUgY3VycmVudCBkYXRlLlxuICAgKi9cbiAgcmVhZG9ubHkgdmFsaWRVbnRpbD86IEV4cGlyYXRpb247XG59O1xuXG4vKipcbiAqIFByb3BlcnRpZXMgb2YgYSBMYXVuY2hUZW1wbGF0ZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMYXVuY2hUZW1wbGF0ZVByb3BzIHtcbiAgLyoqXG4gICAqIE5hbWUgZm9yIHRoaXMgbGF1bmNoIHRlbXBsYXRlLlxuICAgKlxuICAgKiBAZGVmYXVsdCBBdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBuYW1lXG4gICAqL1xuICByZWFkb25seSBsYXVuY2hUZW1wbGF0ZU5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFR5cGUgb2YgaW5zdGFuY2UgdG8gbGF1bmNoLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFRoaXMgTGF1bmNoIFRlbXBsYXRlIGRvZXMgbm90IHNwZWNpZnkgYSBkZWZhdWx0IEluc3RhbmNlIFR5cGUuXG4gICAqL1xuICByZWFkb25seSBpbnN0YW5jZVR5cGU/OiBJbnN0YW5jZVR5cGU7XG5cbiAgLyoqXG4gICAqIFRoZSBBTUkgdGhhdCB3aWxsIGJlIHVzZWQgYnkgaW5zdGFuY2VzLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFRoaXMgTGF1bmNoIFRlbXBsYXRlIGRvZXMgbm90IHNwZWNpZnkgYSBkZWZhdWx0IEFNSS5cbiAgICovXG4gIHJlYWRvbmx5IG1hY2hpbmVJbWFnZT86IElNYWNoaW5lSW1hZ2U7XG5cbiAgLyoqXG4gICAqIFRoZSBBTUkgdGhhdCB3aWxsIGJlIHVzZWQgYnkgaW5zdGFuY2VzLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFRoaXMgTGF1bmNoIFRlbXBsYXRlIGNyZWF0ZXMgYSBVc2VyRGF0YSBiYXNlZCBvbiB0aGUgdHlwZSBvZiBwcm92aWRlZFxuICAgKiBtYWNoaW5lSW1hZ2U7IG5vIFVzZXJEYXRhIGlzIGNyZWF0ZWQgaWYgYSBtYWNoaW5lSW1hZ2UgaXMgbm90IHByb3ZpZGVkXG4gICAqL1xuICByZWFkb25seSB1c2VyRGF0YT86IFVzZXJEYXRhO1xuXG4gIC8qKlxuICAgKiBBbiBJQU0gcm9sZSB0byBhc3NvY2lhdGUgd2l0aCB0aGUgaW5zdGFuY2UgcHJvZmlsZSB0aGF0IGlzIHVzZWQgYnkgaW5zdGFuY2VzLlxuICAgKlxuICAgKiBUaGUgcm9sZSBtdXN0IGJlIGFzc3VtYWJsZSBieSB0aGUgc2VydmljZSBwcmluY2lwYWwgYGVjMi5hbWF6b25hd3MuY29tYDpcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY29uc3Qgcm9sZSA9IG5ldyBpYW0uUm9sZSh0aGlzLCAnTXlSb2xlJywge1xuICAgKiAgIGFzc3VtZWRCeTogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCdlYzIuYW1hem9uYXdzLmNvbScpXG4gICAqIH0pO1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIG5ldyByb2xlIGlzIGNyZWF0ZWQuXG4gICAqL1xuICByZWFkb25seSByb2xlPzogaWFtLklSb2xlO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgaG93IGJsb2NrIGRldmljZXMgYXJlIGV4cG9zZWQgdG8gdGhlIGluc3RhbmNlLiBZb3UgY2FuIHNwZWNpZnkgdmlydHVhbCBkZXZpY2VzIGFuZCBFQlMgdm9sdW1lcy5cbiAgICpcbiAgICogRWFjaCBpbnN0YW5jZSB0aGF0IGlzIGxhdW5jaGVkIGhhcyBhbiBhc3NvY2lhdGVkIHJvb3QgZGV2aWNlIHZvbHVtZSxcbiAgICogZWl0aGVyIGFuIEFtYXpvbiBFQlMgdm9sdW1lIG9yIGFuIGluc3RhbmNlIHN0b3JlIHZvbHVtZS5cbiAgICogWW91IGNhbiB1c2UgYmxvY2sgZGV2aWNlIG1hcHBpbmdzIHRvIHNwZWNpZnkgYWRkaXRpb25hbCBFQlMgdm9sdW1lcyBvclxuICAgKiBpbnN0YW5jZSBzdG9yZSB2b2x1bWVzIHRvIGF0dGFjaCB0byBhbiBpbnN0YW5jZSB3aGVuIGl0IGlzIGxhdW5jaGVkLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NFQzIvbGF0ZXN0L1VzZXJHdWlkZS9ibG9jay1kZXZpY2UtbWFwcGluZy1jb25jZXB0cy5odG1sXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gVXNlcyB0aGUgYmxvY2sgZGV2aWNlIG1hcHBpbmcgb2YgdGhlIEFNSVxuICAgKi9cbiAgcmVhZG9ubHkgYmxvY2tEZXZpY2VzPzogQmxvY2tEZXZpY2VbXTtcblxuICAvKipcbiAgICogQ1BVIGNyZWRpdCB0eXBlIGZvciBidXJzdGFibGUgRUMyIGluc3RhbmNlIHR5cGVzLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NFQzIvbGF0ZXN0L1VzZXJHdWlkZS9idXJzdGFibGUtcGVyZm9ybWFuY2UtaW5zdGFuY2VzLmh0bWxcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBjcmVkaXQgdHlwZSBpcyBzcGVjaWZpZWQgaW4gdGhlIExhdW5jaCBUZW1wbGF0ZS5cbiAgICovXG4gIHJlYWRvbmx5IGNwdUNyZWRpdHM/OiBDcHVDcmVkaXRzO1xuXG4gIC8qKlxuICAgKiBJZiB5b3Ugc2V0IHRoaXMgcGFyYW1ldGVyIHRvIHRydWUsIHlvdSBjYW5ub3QgdGVybWluYXRlIHRoZSBpbnN0YW5jZXMgbGF1bmNoZWQgd2l0aCB0aGlzIGxhdW5jaCB0ZW1wbGF0ZVxuICAgKiB1c2luZyB0aGUgQW1hem9uIEVDMiBjb25zb2xlLCBDTEksIG9yIEFQSTsgb3RoZXJ3aXNlLCB5b3UgY2FuLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFRoZSBBUEkgdGVybWluYXRpb24gc2V0dGluZyBpcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBMYXVuY2ggVGVtcGxhdGUuXG4gICAqL1xuICByZWFkb25seSBkaXNhYmxlQXBpVGVybWluYXRpb24/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgaW5zdGFuY2VzIGFyZSBvcHRpbWl6ZWQgZm9yIEFtYXpvbiBFQlMgSS9PLiBUaGlzIG9wdGltaXphdGlvbiBwcm92aWRlcyBkZWRpY2F0ZWQgdGhyb3VnaHB1dFxuICAgKiB0byBBbWF6b24gRUJTIGFuZCBhbiBvcHRpbWl6ZWQgY29uZmlndXJhdGlvbiBzdGFjayB0byBwcm92aWRlIG9wdGltYWwgQW1hem9uIEVCUyBJL08gcGVyZm9ybWFuY2UuIFRoaXMgb3B0aW1pemF0aW9uXG4gICAqIGlzbid0IGF2YWlsYWJsZSB3aXRoIGFsbCBpbnN0YW5jZSB0eXBlcy4gQWRkaXRpb25hbCB1c2FnZSBjaGFyZ2VzIGFwcGx5IHdoZW4gdXNpbmcgYW4gRUJTLW9wdGltaXplZCBpbnN0YW5jZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBFQlMgb3B0aW1pemF0aW9uIGlzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIGxhdW5jaCB0ZW1wbGF0ZS5cbiAgICovXG4gIHJlYWRvbmx5IGVic09wdGltaXplZD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIElmIHRoaXMgcGFyYW1ldGVyIGlzIHNldCB0byB0cnVlLCB0aGUgaW5zdGFuY2UgaXMgZW5hYmxlZCBmb3IgQVdTIE5pdHJvIEVuY2xhdmVzOyBvdGhlcndpc2UsIGl0IGlzIG5vdCBlbmFibGVkIGZvciBBV1MgTml0cm8gRW5jbGF2ZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gRW5hYmxlbWVudCBvZiBOaXRybyBlbmNsYXZlcyBpcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBsYXVuY2ggdGVtcGxhdGU7IGRlZmF1bHRpbmcgdG8gZmFsc2UuXG4gICAqL1xuICByZWFkb25seSBuaXRyb0VuY2xhdmVFbmFibGVkPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogSWYgeW91IHNldCB0aGlzIHBhcmFtZXRlciB0byB0cnVlLCB0aGUgaW5zdGFuY2UgaXMgZW5hYmxlZCBmb3IgaGliZXJuYXRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gSGliZXJuYXRpb24gY29uZmlndXJhdGlvbiBpcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBsYXVuY2ggdGVtcGxhdGU7IGRlZmF1bHRpbmcgdG8gZmFsc2UuXG4gICAqL1xuICByZWFkb25seSBoaWJlcm5hdGlvbkNvbmZpZ3VyZWQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgd2hldGhlciBhbiBpbnN0YW5jZSBzdG9wcyBvciB0ZXJtaW5hdGVzIHdoZW4geW91IGluaXRpYXRlIHNodXRkb3duIGZyb20gdGhlIGluc3RhbmNlICh1c2luZyB0aGUgb3BlcmF0aW5nIHN5c3RlbSBjb21tYW5kIGZvciBzeXN0ZW0gc2h1dGRvd24pLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NFQzIvbGF0ZXN0L1VzZXJHdWlkZS90ZXJtaW5hdGluZy1pbnN0YW5jZXMuaHRtbCNVc2luZ19DaGFuZ2luZ0luc3RhbmNlSW5pdGlhdGVkU2h1dGRvd25CZWhhdmlvclxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFNodXRkb3duIGJlaGF2aW9yIGlzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIGxhdW5jaCB0ZW1wbGF0ZTsgZGVmYXVsdHMgdG8gU1RPUC5cbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbmNlSW5pdGlhdGVkU2h1dGRvd25CZWhhdmlvcj86IEluc3RhbmNlSW5pdGlhdGVkU2h1dGRvd25CZWhhdmlvcjtcblxuICAvKipcbiAgICogSWYgdGhpcyBwcm9wZXJ0eSBpcyBkZWZpbmVkLCB0aGVuIHRoZSBMYXVuY2ggVGVtcGxhdGUncyBJbnN0YW5jZU1hcmtldE9wdGlvbnMgd2lsbCBiZVxuICAgKiBzZXQgdG8gdXNlIFNwb3QgaW5zdGFuY2VzLCBhbmQgdGhlIG9wdGlvbnMgZm9yIHRoZSBTcG90IGluc3RhbmNlcyB3aWxsIGJlIGFzIGRlZmluZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gSW5zdGFuY2UgbGF1bmNoZWQgd2l0aCB0aGlzIHRlbXBsYXRlIHdpbGwgbm90IGJlIHNwb3QgaW5zdGFuY2VzLlxuICAgKi9cbiAgcmVhZG9ubHkgc3BvdE9wdGlvbnM/OiBMYXVuY2hUZW1wbGF0ZVNwb3RPcHRpb25zO1xuXG4gIC8qKlxuICAgKiBOYW1lIG9mIFNTSCBrZXlwYWlyIHRvIGdyYW50IGFjY2VzcyB0byBpbnN0YW5jZVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIFNTSCBhY2Nlc3Mgd2lsbCBiZSBwb3NzaWJsZS5cbiAgICovXG4gIHJlYWRvbmx5IGtleU5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIElmIHNldCB0byB0cnVlLCB0aGVuIGRldGFpbGVkIG1vbml0b3Jpbmcgd2lsbCBiZSBlbmFibGVkIG9uIGluc3RhbmNlcyBjcmVhdGVkIHdpdGggdGhpc1xuICAgKiBsYXVuY2ggdGVtcGxhdGUuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0VDMi9sYXRlc3QvVXNlckd1aWRlL3VzaW5nLWNsb3Vkd2F0Y2gtbmV3Lmh0bWxcbiAgICpcbiAgICogQGRlZmF1bHQgRmFsc2UgLSBEZXRhaWxlZCBtb25pdG9yaW5nIGlzIGRpc2FibGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgZGV0YWlsZWRNb25pdG9yaW5nPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogU2VjdXJpdHkgZ3JvdXAgdG8gYXNzaWduIHRvIGluc3RhbmNlcyBjcmVhdGVkIHdpdGggdGhlIGxhdW5jaCB0ZW1wbGF0ZS5cbiAgICpcbiAgICogQGRlZmF1bHQgTm8gc2VjdXJpdHkgZ3JvdXAgaXMgYXNzaWduZWQuXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3VwPzogSVNlY3VyaXR5R3JvdXA7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgSU1EU3YyIHNob3VsZCBiZSByZXF1aXJlZCBvbiBsYXVuY2hlZCBpbnN0YW5jZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHJlcXVpcmVJbWRzdjI/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIEEgY2xhc3MgdGhhdCBwcm92aWRlcyBjb252ZW5pZW50IGFjY2VzcyB0byBzcGVjaWFsIHZlcnNpb24gdG9rZW5zIGZvciBMYXVuY2hUZW1wbGF0ZVxuICogdmVyc2lvbnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBMYXVuY2hUZW1wbGF0ZVNwZWNpYWxWZXJzaW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgc3BlY2lhbCB2YWx1ZSB0aGF0IGRlbm90ZXMgdGhhdCB1c2VycyBvZiBhIExhdW5jaCBUZW1wbGF0ZSBzaG91bGRcbiAgICogcmVmZXJlbmNlIHRoZSBMQVRFU1QgdmVyc2lvbiBvZiB0aGUgdGVtcGxhdGUuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IExBVEVTVF9WRVJTSU9OOiBzdHJpbmcgPSAnJExhdGVzdCc7XG5cbiAgLyoqXG4gICAqIFRoZSBzcGVjaWFsIHZhbHVlIHRoYXQgZGVub3RlcyB0aGF0IHVzZXJzIG9mIGEgTGF1bmNoIFRlbXBsYXRlIHNob3VsZFxuICAgKiByZWZlcmVuY2UgdGhlIERFRkFVTFQgdmVyc2lvbiBvZiB0aGUgdGVtcGxhdGUuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfVkVSU0lPTjogc3RyaW5nID0gJyREZWZhdWx0Jztcbn1cblxuLyoqXG4gKiBBdHRyaWJ1dGVzIGZvciBhbiBpbXBvcnRlZCBMYXVuY2hUZW1wbGF0ZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMYXVuY2hUZW1wbGF0ZUF0dHJpYnV0ZXMge1xuICAvKipcbiAgICogVGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoaXMgbGF1bmNoIHRlbXBsYXRlIHRvIHVzZVxuICAgKlxuICAgKiBAZGVmYXVsdCBWZXJzaW9uOiBcIiREZWZhdWx0XCJcbiAgICovXG4gIHJlYWRvbmx5IHZlcnNpb25OdW1iZXI/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBpZGVudGlmaWVyIG9mIHRoZSBMYXVuY2ggVGVtcGxhdGVcbiAgICpcbiAgICogRXhhY3RseSBvbmUgb2YgYGxhdW5jaFRlbXBsYXRlSWRgIGFuZCBgbGF1bmNoVGVtcGxhdGVOYW1lYCBtYXkgYmUgc2V0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBOb25lXG4gICAqL1xuICByZWFkb25seSBsYXVuY2hUZW1wbGF0ZUlkPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgTGF1bmNoIFRlbXBsYXRlXG4gICAqXG4gICAqIEV4YWN0bHkgb25lIG9mIGBsYXVuY2hUZW1wbGF0ZUlkYCBhbmQgYGxhdW5jaFRlbXBsYXRlTmFtZWAgbWF5IGJlIHNldC5cbiAgICpcbiAgICogQGRlZmF1bHQgTm9uZVxuICAgKi9cbiAgcmVhZG9ubHkgbGF1bmNoVGVtcGxhdGVOYW1lPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFRoaXMgcmVwcmVzZW50cyBhbiBFQzIgTGF1bmNoVGVtcGxhdGUuXG4gKlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTRUMyL2xhdGVzdC9Vc2VyR3VpZGUvZWMyLWxhdW5jaC10ZW1wbGF0ZXMuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgTGF1bmNoVGVtcGxhdGUgZXh0ZW5kcyBSZXNvdXJjZSBpbXBsZW1lbnRzIElMYXVuY2hUZW1wbGF0ZSwgaWFtLklHcmFudGFibGUsIElDb25uZWN0YWJsZSB7XG4gIC8qKlxuICAgKiBJbXBvcnQgYW4gZXhpc3RpbmcgTGF1bmNoVGVtcGxhdGUuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21MYXVuY2hUZW1wbGF0ZUF0dHJpYnV0ZXMoc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgYXR0cnM6IExhdW5jaFRlbXBsYXRlQXR0cmlidXRlcyk6IElMYXVuY2hUZW1wbGF0ZSB7XG4gICAgY29uc3QgaGF2ZUlkID0gQm9vbGVhbihhdHRycy5sYXVuY2hUZW1wbGF0ZUlkKTtcbiAgICBjb25zdCBoYXZlTmFtZSA9IEJvb2xlYW4oYXR0cnMubGF1bmNoVGVtcGxhdGVOYW1lKTtcbiAgICBpZiAoaGF2ZUlkID09IGhhdmVOYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0xhdW5jaFRlbXBsYXRlLmZyb21MYXVuY2hUZW1wbGF0ZUF0dHJpYnV0ZXMoKSByZXF1aXJlcyBleGFjdGx5IG9uZSBvZiBsYXVuY2hUZW1wbGF0ZUlkIG9yIGxhdW5jaFRlbXBsYXRlTmFtZSBiZSBwcm92aWRlZC4nKTtcbiAgICB9XG5cbiAgICBjbGFzcyBJbXBvcnQgZXh0ZW5kcyBSZXNvdXJjZSBpbXBsZW1lbnRzIElMYXVuY2hUZW1wbGF0ZSB7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgdmVyc2lvbk51bWJlciA9IGF0dHJzLnZlcnNpb25OdW1iZXIgPz8gTGF1bmNoVGVtcGxhdGVTcGVjaWFsVmVyc2lvbnMuREVGQVVMVF9WRVJTSU9OO1xuICAgICAgcHVibGljIHJlYWRvbmx5IGxhdW5jaFRlbXBsYXRlSWQ/ID0gYXR0cnMubGF1bmNoVGVtcGxhdGVJZDtcbiAgICAgIHB1YmxpYyByZWFkb25seSBsYXVuY2hUZW1wbGF0ZU5hbWU/ID0gYXR0cnMubGF1bmNoVGVtcGxhdGVOYW1lO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEltcG9ydChzY29wZSwgaWQpO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gICBNZW1iZXJzIGZvciBJTGF1bmNoVGVtcGxhdGUgaW50ZXJmYWNlXG5cbiAgcHVibGljIHJlYWRvbmx5IHZlcnNpb25OdW1iZXI6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGxhdW5jaFRlbXBsYXRlSWQ/OiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBsYXVuY2hUZW1wbGF0ZU5hbWU/OiBzdHJpbmc7XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vICAgRGF0YSBtZW1iZXJzXG5cbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IHZlcnNpb24gZm9yIHRoZSBsYXVuY2ggdGVtcGxhdGUuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBkZWZhdWx0VmVyc2lvbk51bWJlcjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbGF0ZXN0IHZlcnNpb24gb2YgdGhlIGxhdW5jaCB0ZW1wbGF0ZS5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGxhdGVzdFZlcnNpb25OdW1iZXI6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHR5cGUgb2YgT1MgdGhlIGluc3RhbmNlIGlzIHJ1bm5pbmcuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBvc1R5cGU/OiBPcGVyYXRpbmdTeXN0ZW1UeXBlO1xuXG4gIC8qKlxuICAgKiBUaGUgQU1JIElEIG9mIHRoZSBpbWFnZSB0byB1c2VcbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGltYWdlSWQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIElBTSBSb2xlIGFzc3VtZWQgYnkgaW5zdGFuY2VzIHRoYXQgYXJlIGxhdW5jaGVkIGZyb20gdGhpcyB0ZW1wbGF0ZS5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHJvbGU/OiBpYW0uSVJvbGU7XG5cbiAgLyoqXG4gICAqIFVzZXJEYXRhIGV4ZWN1dGVkIGJ5IGluc3RhbmNlcyB0aGF0IGFyZSBsYXVuY2hlZCBmcm9tIHRoaXMgdGVtcGxhdGUuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSB1c2VyRGF0YT86IFVzZXJEYXRhO1xuXG4gIC8qKlxuICAgKiBUeXBlIG9mIGluc3RhbmNlIHRvIGxhdW5jaC5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGluc3RhbmNlVHlwZT86IEluc3RhbmNlVHlwZTtcblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gICBQcml2YXRlL3Byb3RlY3RlZCBkYXRhIG1lbWJlcnNcblxuICAvKipcbiAgICogUHJpbmNpcGFsIHRvIGdyYW50IHBlcm1pc3Npb25zIHRvLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBfZ3JhbnRQcmluY2lwYWw/OiBpYW0uSVByaW5jaXBhbDtcblxuICAvKipcbiAgICogQWxsb3dzIHNwZWNpZnlpbmcgc2VjdXJpdHkgZ3JvdXAgY29ubmVjdGlvbnMgZm9yIHRoZSBpbnN0YW5jZS5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgX2Nvbm5lY3Rpb25zPzogQ29ubmVjdGlvbnM7XG5cbiAgLyoqXG4gICAqIFRhZ01hbmFnZXIgZm9yIHRhZ2dpbmcgc3VwcG9ydC5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSB0YWdzOiBUYWdNYW5hZ2VyO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBMYXVuY2hUZW1wbGF0ZVByb3BzID0ge30pIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgLy8gQmFzaWMgdmFsaWRhdGlvbiBvZiB0aGUgcHJvdmlkZWQgc3BvdCBibG9jayBkdXJhdGlvblxuICAgIGNvbnN0IHNwb3REdXJhdGlvbiA9IHByb3BzPy5zcG90T3B0aW9ucz8uYmxvY2tEdXJhdGlvbj8udG9Ib3Vycyh7IGludGVncmFsOiB0cnVlIH0pO1xuICAgIGlmIChzcG90RHVyYXRpb24gIT09IHVuZGVmaW5lZCAmJiAoc3BvdER1cmF0aW9uIDwgMSB8fCBzcG90RHVyYXRpb24gPiA2KSkge1xuICAgICAgLy8gU2VlOiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTRUMyL2xhdGVzdC9Vc2VyR3VpZGUvc3BvdC1yZXF1ZXN0cy5odG1sI2ZpeGVkLWR1cmF0aW9uLXNwb3QtaW5zdGFuY2VzXG4gICAgICBBbm5vdGF0aW9ucy5vZih0aGlzKS5hZGRFcnJvcignU3BvdCBibG9jayBkdXJhdGlvbiBtdXN0IGJlIGV4YWN0bHkgMSwgMiwgMywgNCwgNSwgb3IgNiBob3Vycy4nKTtcbiAgICB9XG5cbiAgICB0aGlzLnJvbGUgPSBwcm9wcy5yb2xlO1xuICAgIHRoaXMuX2dyYW50UHJpbmNpcGFsID0gdGhpcy5yb2xlO1xuICAgIGNvbnN0IGlhbVByb2ZpbGU6IGlhbS5DZm5JbnN0YW5jZVByb2ZpbGUgfCB1bmRlZmluZWQgPSB0aGlzLnJvbGUgPyBuZXcgaWFtLkNmbkluc3RhbmNlUHJvZmlsZSh0aGlzLCAnUHJvZmlsZScsIHtcbiAgICAgIHJvbGVzOiBbdGhpcy5yb2xlIS5yb2xlTmFtZV0sXG4gICAgfSkgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAocHJvcHMuc2VjdXJpdHlHcm91cCkge1xuICAgICAgdGhpcy5fY29ubmVjdGlvbnMgPSBuZXcgQ29ubmVjdGlvbnMoeyBzZWN1cml0eUdyb3VwczogW3Byb3BzLnNlY3VyaXR5R3JvdXBdIH0pO1xuICAgIH1cbiAgICBjb25zdCBzZWN1cml0eUdyb3Vwc1Rva2VuID0gTGF6eS5saXN0KHtcbiAgICAgIHByb2R1Y2U6ICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuX2Nvbm5lY3Rpb25zICYmIHRoaXMuX2Nvbm5lY3Rpb25zLnNlY3VyaXR5R3JvdXBzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5fY29ubmVjdGlvbnMuc2VjdXJpdHlHcm91cHMubWFwKHNnID0+IHNnLnNlY3VyaXR5R3JvdXBJZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAocHJvcHMudXNlckRhdGEpIHtcbiAgICAgIHRoaXMudXNlckRhdGEgPSBwcm9wcy51c2VyRGF0YTtcbiAgICB9XG4gICAgY29uc3QgdXNlckRhdGFUb2tlbiA9IExhenkuc3RyaW5nKHtcbiAgICAgIHByb2R1Y2U6ICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMudXNlckRhdGEpIHtcbiAgICAgICAgICByZXR1cm4gRm4uYmFzZTY0KHRoaXMudXNlckRhdGEucmVuZGVyKCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgaW1hZ2VDb25maWc6IE1hY2hpbmVJbWFnZUNvbmZpZyB8IHVuZGVmaW5lZCA9IHByb3BzLm1hY2hpbmVJbWFnZT8uZ2V0SW1hZ2UodGhpcyk7XG4gICAgaWYgKGltYWdlQ29uZmlnKSB7XG4gICAgICB0aGlzLm9zVHlwZSA9IGltYWdlQ29uZmlnLm9zVHlwZTtcbiAgICAgIHRoaXMuaW1hZ2VJZCA9IGltYWdlQ29uZmlnLmltYWdlSWQ7XG4gICAgfVxuXG4gICAgdGhpcy5pbnN0YW5jZVR5cGUgPSBwcm9wcy5pbnN0YW5jZVR5cGU7XG5cbiAgICBsZXQgbWFya2V0T3B0aW9uczogYW55ID0gdW5kZWZpbmVkO1xuICAgIGlmIChwcm9wcz8uc3BvdE9wdGlvbnMpIHtcbiAgICAgIG1hcmtldE9wdGlvbnMgPSB7XG4gICAgICAgIG1hcmtldFR5cGU6ICdzcG90JyxcbiAgICAgICAgc3BvdE9wdGlvbnM6IHtcbiAgICAgICAgICBibG9ja0R1cmF0aW9uTWludXRlczogc3BvdER1cmF0aW9uICE9PSB1bmRlZmluZWQgPyBzcG90RHVyYXRpb24gKiA2MCA6IHVuZGVmaW5lZCxcbiAgICAgICAgICBpbnN0YW5jZUludGVycnVwdGlvbkJlaGF2aW9yOiBwcm9wcy5zcG90T3B0aW9ucy5pbnRlcnJ1cHRpb25CZWhhdmlvcixcbiAgICAgICAgICBtYXhQcmljZTogcHJvcHMuc3BvdE9wdGlvbnMubWF4UHJpY2U/LnRvU3RyaW5nKCksXG4gICAgICAgICAgc3BvdEluc3RhbmNlVHlwZTogcHJvcHMuc3BvdE9wdGlvbnMucmVxdWVzdFR5cGUsXG4gICAgICAgICAgdmFsaWRVbnRpbDogcHJvcHMuc3BvdE9wdGlvbnMudmFsaWRVbnRpbD8uZGF0ZS50b1VUQ1N0cmluZygpLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIC8vIFJlbW92ZSBTcG90T3B0aW9ucyBpZiB0aGVyZSBhcmUgbm9uZS5cbiAgICAgIGlmIChPYmplY3Qua2V5cyhtYXJrZXRPcHRpb25zLnNwb3RPcHRpb25zKS5maWx0ZXIoayA9PiBtYXJrZXRPcHRpb25zLnNwb3RPcHRpb25zW2tdKS5sZW5ndGggPT0gMCkge1xuICAgICAgICBtYXJrZXRPcHRpb25zLnNwb3RPcHRpb25zID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMudGFncyA9IG5ldyBUYWdNYW5hZ2VyKFRhZ1R5cGUuS0VZX1ZBTFVFLCAnQVdTOjpFQzI6OkxhdW5jaFRlbXBsYXRlJyk7XG4gICAgY29uc3QgdGFnc1Rva2VuID0gTGF6eS5hbnkoe1xuICAgICAgcHJvZHVjZTogKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy50YWdzLmhhc1RhZ3MoKSkge1xuICAgICAgICAgIGNvbnN0IHJlbmRlcmVkVGFncyA9IHRoaXMudGFncy5yZW5kZXJUYWdzKCk7XG4gICAgICAgICAgY29uc3QgbG93ZXJDYXNlUmVuZGVyZWRUYWdzID0gcmVuZGVyZWRUYWdzLm1hcCggKHRhZzogeyBba2V5OiBzdHJpbmddOiBzdHJpbmd9KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBrZXk6IHRhZy5LZXksXG4gICAgICAgICAgICAgIHZhbHVlOiB0YWcuVmFsdWUsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHJlc291cmNlVHlwZTogJ2luc3RhbmNlJyxcbiAgICAgICAgICAgICAgdGFnczogbG93ZXJDYXNlUmVuZGVyZWRUYWdzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgcmVzb3VyY2VUeXBlOiAndm9sdW1lJyxcbiAgICAgICAgICAgICAgdGFnczogbG93ZXJDYXNlUmVuZGVyZWRUYWdzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzb3VyY2UgPSBuZXcgQ2ZuTGF1bmNoVGVtcGxhdGUodGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgbGF1bmNoVGVtcGxhdGVOYW1lOiBwcm9wcz8ubGF1bmNoVGVtcGxhdGVOYW1lLFxuICAgICAgbGF1bmNoVGVtcGxhdGVEYXRhOiB7XG4gICAgICAgIGJsb2NrRGV2aWNlTWFwcGluZ3M6IHByb3BzPy5ibG9ja0RldmljZXMgIT09IHVuZGVmaW5lZCA/IGxhdW5jaFRlbXBsYXRlQmxvY2tEZXZpY2VNYXBwaW5ncyh0aGlzLCBwcm9wcy5ibG9ja0RldmljZXMpIDogdW5kZWZpbmVkLFxuICAgICAgICBjcmVkaXRTcGVjaWZpY2F0aW9uOiBwcm9wcz8uY3B1Q3JlZGl0cyAhPT0gdW5kZWZpbmVkID8ge1xuICAgICAgICAgIGNwdUNyZWRpdHM6IHByb3BzLmNwdUNyZWRpdHMsXG4gICAgICAgIH0gOiB1bmRlZmluZWQsXG4gICAgICAgIGRpc2FibGVBcGlUZXJtaW5hdGlvbjogcHJvcHM/LmRpc2FibGVBcGlUZXJtaW5hdGlvbixcbiAgICAgICAgZWJzT3B0aW1pemVkOiBwcm9wcz8uZWJzT3B0aW1pemVkLFxuICAgICAgICBlbmNsYXZlT3B0aW9uczogcHJvcHM/Lm5pdHJvRW5jbGF2ZUVuYWJsZWQgIT09IHVuZGVmaW5lZCA/IHtcbiAgICAgICAgICBlbmFibGVkOiBwcm9wcy5uaXRyb0VuY2xhdmVFbmFibGVkLFxuICAgICAgICB9IDogdW5kZWZpbmVkLFxuICAgICAgICBoaWJlcm5hdGlvbk9wdGlvbnM6IHByb3BzPy5oaWJlcm5hdGlvbkNvbmZpZ3VyZWQgIT09IHVuZGVmaW5lZCA/IHtcbiAgICAgICAgICBjb25maWd1cmVkOiBwcm9wcy5oaWJlcm5hdGlvbkNvbmZpZ3VyZWQsXG4gICAgICAgIH0gOiB1bmRlZmluZWQsXG4gICAgICAgIGlhbUluc3RhbmNlUHJvZmlsZTogaWFtUHJvZmlsZSAhPT0gdW5kZWZpbmVkID8ge1xuICAgICAgICAgIGFybjogaWFtUHJvZmlsZS5nZXRBdHQoJ0FybicpLnRvU3RyaW5nKCksXG4gICAgICAgIH0gOiB1bmRlZmluZWQsXG4gICAgICAgIGltYWdlSWQ6IGltYWdlQ29uZmlnPy5pbWFnZUlkLFxuICAgICAgICBpbnN0YW5jZVR5cGU6IHByb3BzPy5pbnN0YW5jZVR5cGU/LnRvU3RyaW5nKCksXG4gICAgICAgIGluc3RhbmNlSW5pdGlhdGVkU2h1dGRvd25CZWhhdmlvcjogcHJvcHM/Lmluc3RhbmNlSW5pdGlhdGVkU2h1dGRvd25CZWhhdmlvcixcbiAgICAgICAgaW5zdGFuY2VNYXJrZXRPcHRpb25zOiBtYXJrZXRPcHRpb25zLFxuICAgICAgICBrZXlOYW1lOiBwcm9wcz8ua2V5TmFtZSxcbiAgICAgICAgbW9uaXRvcmluZzogcHJvcHM/LmRldGFpbGVkTW9uaXRvcmluZyAhPT0gdW5kZWZpbmVkID8ge1xuICAgICAgICAgIGVuYWJsZWQ6IHByb3BzLmRldGFpbGVkTW9uaXRvcmluZyxcbiAgICAgICAgfSA6IHVuZGVmaW5lZCxcbiAgICAgICAgc2VjdXJpdHlHcm91cElkczogc2VjdXJpdHlHcm91cHNUb2tlbixcbiAgICAgICAgdGFnU3BlY2lmaWNhdGlvbnM6IHRhZ3NUb2tlbixcbiAgICAgICAgdXNlckRhdGE6IHVzZXJEYXRhVG9rZW4sXG5cbiAgICAgICAgLy8gRmllbGRzIG5vdCB5ZXQgaW1wbGVtZW50ZWQ6XG4gICAgICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICAgIC8vIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjMi1sYXVuY2h0ZW1wbGF0ZS1sYXVuY2h0ZW1wbGF0ZWRhdGEtY2FwYWNpdHlyZXNlcnZhdGlvbnNwZWNpZmljYXRpb24uaHRtbFxuICAgICAgICAvLyBXaWxsIHJlcXVpcmUgY3JlYXRpbmcgYW4gTDIgZm9yIEFXUzo6RUMyOjpDYXBhY2l0eVJlc2VydmF0aW9uXG4gICAgICAgIC8vIGNhcGFjaXR5UmVzZXJ2YXRpb25TcGVjaWZpY2F0aW9uOiB1bmRlZmluZWQsXG5cbiAgICAgICAgLy8gaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWMyLWxhdW5jaHRlbXBsYXRlLWxhdW5jaHRlbXBsYXRlZGF0YS1jcHVvcHRpb25zLmh0bWxcbi