@aws-cdk/aws-ecs
Version:
The CDK Construct Library for AWS::ECS
234 lines • 32.8 kB
JavaScript
;
var _a, _b;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BuiltInAttributes = exports.Ec2Service = void 0;
const jsiiDeprecationWarnings = require("../../.warnings.jsii.js");
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const ec2 = require("@aws-cdk/aws-ec2");
const core_1 = require("@aws-cdk/core");
const base_service_1 = require("../base/base-service");
const from_service_attributes_1 = require("../base/from-service-attributes");
const task_definition_1 = require("../base/task-definition");
/**
* This creates a service using the EC2 launch type on an ECS cluster.
*
* @resource AWS::ECS::Service
*/
class Ec2Service extends base_service_1.BaseService {
/**
* Constructs a new instance of the Ec2Service class.
*/
constructor(scope, id, props) {
try {
jsiiDeprecationWarnings._aws_cdk_aws_ecs_Ec2ServiceProps(props);
}
catch (error) {
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
Error.captureStackTrace(error, Ec2Service);
}
throw error;
}
if (props.daemon && props.desiredCount !== undefined) {
throw new Error('Daemon mode launches one task on every instance. Don\'t supply desiredCount.');
}
if (props.daemon && props.maxHealthyPercent !== undefined && props.maxHealthyPercent !== 100) {
throw new Error('Maximum percent must be 100 for daemon mode.');
}
if (props.minHealthyPercent !== undefined && props.maxHealthyPercent !== undefined && props.minHealthyPercent >= props.maxHealthyPercent) {
throw new Error('Minimum healthy percent must be less than maximum healthy percent.');
}
if (!props.taskDefinition.isEc2Compatible) {
throw new Error('Supplied TaskDefinition is not configured for compatibility with EC2');
}
if (props.securityGroup !== undefined && props.securityGroups !== undefined) {
throw new Error('Only one of SecurityGroup or SecurityGroups can be populated.');
}
super(scope, id, {
...props,
desiredCount: props.desiredCount,
maxHealthyPercent: props.daemon && props.maxHealthyPercent === undefined ? 100 : props.maxHealthyPercent,
minHealthyPercent: props.daemon && props.minHealthyPercent === undefined ? 0 : props.minHealthyPercent,
launchType: base_service_1.LaunchType.EC2,
enableECSManagedTags: props.enableECSManagedTags,
}, {
cluster: props.cluster.clusterName,
taskDefinition: props.deploymentController?.type === base_service_1.DeploymentControllerType.EXTERNAL ? undefined : props.taskDefinition.taskDefinitionArn,
placementConstraints: core_1.Lazy.any({ produce: () => this.constraints }, { omitEmptyArray: true }),
placementStrategies: core_1.Lazy.any({ produce: () => this.strategies }, { omitEmptyArray: true }),
schedulingStrategy: props.daemon ? 'DAEMON' : 'REPLICA',
}, props.taskDefinition);
this.constraints = [];
this.strategies = [];
this.daemon = props.daemon || false;
let securityGroups;
if (props.securityGroup !== undefined) {
securityGroups = [props.securityGroup];
}
else if (props.securityGroups !== undefined) {
securityGroups = props.securityGroups;
}
if (props.taskDefinition.networkMode === task_definition_1.NetworkMode.AWS_VPC) {
this.configureAwsVpcNetworkingWithSecurityGroups(props.cluster.vpc, props.assignPublicIp, props.vpcSubnets, securityGroups);
}
else {
// Either None, Bridge or Host networking. Copy SecurityGroups from ASG.
// We have to be smart here -- by default future Security Group rules would be created
// in the Cluster stack. However, if the Cluster is in a different stack than us,
// that will lead to a cyclic reference (we point to that stack for the cluster name,
// but that stack will point to the ALB probably created right next to us).
//
// In that case, reference the same security groups but make sure new rules are
// created in the current scope (i.e., this stack)
validateNoNetworkingProps(props);
this.connections.addSecurityGroup(...securityGroupsInThisStack(this, props.cluster.connections.securityGroups));
}
this.addPlacementConstraints(...props.placementConstraints || []);
this.addPlacementStrategies(...props.placementStrategies || []);
this.node.addValidation({
validate: () => !this.taskDefinition.defaultContainer ? ['A TaskDefinition must have at least one essential container'] : [],
});
}
/**
* Imports from the specified service ARN.
*/
static fromEc2ServiceArn(scope, id, ec2ServiceArn) {
class Import extends core_1.Resource {
constructor() {
super(...arguments);
this.serviceArn = ec2ServiceArn;
this.serviceName = core_1.Stack.of(scope).splitArn(ec2ServiceArn, core_1.ArnFormat.SLASH_RESOURCE_NAME).resourceName;
}
}
return new Import(scope, id);
}
/**
* Imports from the specified service attributes.
*/
static fromEc2ServiceAttributes(scope, id, attrs) {
try {
jsiiDeprecationWarnings._aws_cdk_aws_ecs_Ec2ServiceAttributes(attrs);
}
catch (error) {
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
Error.captureStackTrace(error, this.fromEc2ServiceAttributes);
}
throw error;
}
return from_service_attributes_1.fromServiceAttributes(scope, id, attrs);
}
/**
* Adds one or more placement strategies to use for tasks in the service. For more information, see
* [Amazon ECS Task Placement Strategies](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement-strategies.html).
*/
addPlacementStrategies(...strategies) {
try {
jsiiDeprecationWarnings._aws_cdk_aws_ecs_PlacementStrategy(strategies);
}
catch (error) {
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
Error.captureStackTrace(error, this.addPlacementStrategies);
}
throw error;
}
if (strategies.length > 0 && this.daemon) {
throw new Error("Can't configure placement strategies when daemon=true");
}
for (const strategy of strategies) {
this.strategies.push(...strategy.toJson());
}
}
/**
* Adds one or more placement constraints to use for tasks in the service. For more information, see
* [Amazon ECS Task Placement Constraints](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement-constraints.html).
*/
addPlacementConstraints(...constraints) {
try {
jsiiDeprecationWarnings._aws_cdk_aws_ecs_PlacementConstraint(constraints);
}
catch (error) {
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
Error.captureStackTrace(error, this.addPlacementConstraints);
}
throw error;
}
for (const constraint of constraints) {
this.constraints.push(...constraint.toJson());
}
}
/**
* Validates this Ec2Service.
*/
validate() {
const ret = super.validate();
if (!this.cluster.hasEc2Capacity) {
ret.push('Cluster for this service needs Ec2 capacity. Call addXxxCapacity() on the cluster.');
}
return ret;
}
}
exports.Ec2Service = Ec2Service;
_a = JSII_RTTI_SYMBOL_1;
Ec2Service[_a] = { fqn: "@aws-cdk/aws-ecs.Ec2Service", version: "1.197.0" };
/**
* Validate combinations of networking arguments.
*/
function validateNoNetworkingProps(props) {
if (props.vpcSubnets !== undefined
|| props.securityGroup !== undefined
|| props.securityGroups !== undefined
|| props.assignPublicIp) {
throw new Error('vpcSubnets, securityGroup(s) and assignPublicIp can only be used in AwsVpc networking mode');
}
}
/**
* Force security group rules to be created in this stack.
*
* For every security group, if the scope and the group are in different stacks, return
* a fake "imported" security group instead. This will behave as the original security group,
* but new Ingress and Egress rule resources will be added in the current stack instead of the
* other one.
*/
function securityGroupsInThisStack(scope, groups) {
const thisStack = core_1.Stack.of(scope);
let i = 1;
return groups.map(group => {
if (thisStack === core_1.Stack.of(group)) {
return group;
} // Simple case, just return the original one
return ec2.SecurityGroup.fromSecurityGroupId(scope, `SecurityGroup${i++}`, group.securityGroupId, {
allowAllOutbound: group.allowAllOutbound,
mutable: true,
});
});
}
/**
* The built-in container instance attributes
*/
class BuiltInAttributes {
}
exports.BuiltInAttributes = BuiltInAttributes;
_b = JSII_RTTI_SYMBOL_1;
BuiltInAttributes[_b] = { fqn: "@aws-cdk/aws-ecs.BuiltInAttributes", version: "1.197.0" };
/**
* The id of the instance.
*/
BuiltInAttributes.INSTANCE_ID = 'instanceId';
/**
* The AvailabilityZone where the instance is running in.
*/
BuiltInAttributes.AVAILABILITY_ZONE = 'attribute:ecs.availability-zone';
/**
* The AMI id the instance is using.
*/
BuiltInAttributes.AMI_ID = 'attribute:ecs.ami-id';
/**
* The EC2 instance type.
*/
BuiltInAttributes.INSTANCE_TYPE = 'attribute:ecs.instance-type';
/**
* The operating system of the instance.
*
* Either 'linux' or 'windows'.
*/
BuiltInAttributes.OS_TYPE = 'attribute:ecs.os-type';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWMyLXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJlYzItc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSx3Q0FBd0M7QUFDeEMsd0NBQWlFO0FBRWpFLHVEQUFxSTtBQUNySSw2RUFBd0U7QUFDeEUsNkRBQXNFO0FBZ0h0RTs7OztHQUlHO0FBQ0gsTUFBYSxVQUFXLFNBQVEsMEJBQVc7SUF3QnpDOztPQUVHO0lBQ0gsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFzQjs7Ozs7OytDQTNCckQsVUFBVTs7OztRQTRCbkIsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLEtBQUssQ0FBQyxZQUFZLEtBQUssU0FBUyxFQUFFO1lBQ3BELE1BQU0sSUFBSSxLQUFLLENBQUMsOEVBQThFLENBQUMsQ0FBQztTQUNqRztRQUVELElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsaUJBQWlCLEtBQUssU0FBUyxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsS0FBSyxHQUFHLEVBQUU7WUFDNUYsTUFBTSxJQUFJLEtBQUssQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO1NBQ2pFO1FBRUQsSUFBSSxLQUFLLENBQUMsaUJBQWlCLEtBQUssU0FBUyxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsS0FBSyxTQUFTLElBQUksS0FBSyxDQUFDLGlCQUFpQixJQUFJLEtBQUssQ0FBQyxpQkFBaUIsRUFBRTtZQUN4SSxNQUFNLElBQUksS0FBSyxDQUFDLG9FQUFvRSxDQUFDLENBQUM7U0FDdkY7UUFFRCxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxlQUFlLEVBQUU7WUFDekMsTUFBTSxJQUFJLEtBQUssQ0FBQyxzRUFBc0UsQ0FBQyxDQUFDO1NBQ3pGO1FBRUQsSUFBSSxLQUFLLENBQUMsYUFBYSxLQUFLLFNBQVMsSUFBSSxLQUFLLENBQUMsY0FBYyxLQUFLLFNBQVMsRUFBRTtZQUMzRSxNQUFNLElBQUksS0FBSyxDQUFDLCtE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Q0FBNEM7UUFFakcsT0FBTyxHQUFHLENBQUMsYUFBYSxDQUFDLG1CQUFtQixDQUFDLEtBQUssRUFBRSxnQkFBZ0IsQ0FBQyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsZUFBZSxFQUFFO1lBQ2hHLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxnQkFBZ0I7WUFDeEMsT0FBTyxFQUFFLElBQUk7U0FDZCxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQWEsaUJBQWlCOztBQUE5Qiw4Q0EyQkM7OztBQTFCQzs7R0FFRztBQUNvQiw2QkFBVyxHQUFHLFlBQVksQ0FBQztBQUVsRDs7R0FFRztBQUNvQixtQ0FBaUIsR0FBRyxpQ0FBaUMsQ0FBQztBQUU3RTs7R0FFRztBQUNvQix3QkFBTSxHQUFHLHNCQUFzQixDQUFDO0FBRXZEOztHQUVHO0FBQ29CLCtCQUFhLEdBQUcsNkJBQTZCLENBQUM7QUFFckU7Ozs7R0FJRztBQUNvQix5QkFBTyxHQUFHLHVCQUF1QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZWMyIGZyb20gJ0Bhd3MtY2RrL2F3cy1lYzInO1xuaW1wb3J0IHsgQXJuRm9ybWF0LCBMYXp5LCBSZXNvdXJjZSwgU3RhY2sgfSBmcm9tICdAYXdzLWNkay9jb3JlJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgQmFzZVNlcnZpY2UsIEJhc2VTZXJ2aWNlT3B0aW9ucywgRGVwbG95bWVudENvbnRyb2xsZXJUeXBlLCBJQmFzZVNlcnZpY2UsIElTZXJ2aWNlLCBMYXVuY2hUeXBlIH0gZnJvbSAnLi4vYmFzZS9iYXNlLXNlcnZpY2UnO1xuaW1wb3J0IHsgZnJvbVNlcnZpY2VBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vYmFzZS9mcm9tLXNlcnZpY2UtYXR0cmlidXRlcyc7XG5pbXBvcnQgeyBOZXR3b3JrTW9kZSwgVGFza0RlZmluaXRpb24gfSBmcm9tICcuLi9iYXNlL3Rhc2stZGVmaW5pdGlvbic7XG5pbXBvcnQgeyBJQ2x1c3RlciB9IGZyb20gJy4uL2NsdXN0ZXInO1xuaW1wb3J0IHsgQ2ZuU2VydmljZSB9IGZyb20gJy4uL2Vjcy5nZW5lcmF0ZWQnO1xuaW1wb3J0IHsgUGxhY2VtZW50Q29uc3RyYWludCwgUGxhY2VtZW50U3RyYXRlZ3kgfSBmcm9tICcuLi9wbGFjZW1lbnQnO1xuXG4vKipcbiAqIFRoZSBwcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIHNlcnZpY2UgdXNpbmcgdGhlIEVDMiBsYXVuY2ggdHlwZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFYzJTZXJ2aWNlUHJvcHMgZXh0ZW5kcyBCYXNlU2VydmljZU9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIHRhc2sgZGVmaW5pdGlvbiB0byB1c2UgZm9yIHRhc2tzIGluIHRoZSBzZXJ2aWNlLlxuICAgKlxuICAgKiBbZGlzYWJsZS1hd3NsaW50OnJlZi12aWEtaW50ZXJmYWNlXVxuICAgKi9cbiAgcmVhZG9ubHkgdGFza0RlZmluaXRpb246IFRhc2tEZWZpbml0aW9uO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgd2hldGhlciB0aGUgdGFzaydzIGVsYXN0aWMgbmV0d29yayBpbnRlcmZhY2UgcmVjZWl2ZXMgYSBwdWJsaWMgSVAgYWRkcmVzcy5cbiAgICogSWYgdHJ1ZSwgZWFjaCB0YXNrIHdpbGwgcmVjZWl2ZSBhIHB1YmxpYyBJUCBhZGRyZXNzLlxuICAgKlxuICAgKiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgdXNlZCBmb3IgdGFza3MgdGhhdCB1c2UgdGhlIGF3c3ZwYyBuZXR3b3JrIG1vZGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBhc3NpZ25QdWJsaWNJcD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBzdWJuZXRzIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBzZXJ2aWNlLlxuICAgKlxuICAgKiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgdXNlZCBmb3IgdGFza3MgdGhhdCB1c2UgdGhlIGF3c3ZwYyBuZXR3b3JrIG1vZGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gUHVibGljIHN1Ym5ldHMgaWYgYGFzc2lnblB1YmxpY0lwYCBpcyBzZXQsIG90aGVyd2lzZSB0aGUgZmlyc3QgYXZhaWxhYmxlIG9uZSBvZiBQcml2YXRlLCBJc29sYXRlZCwgUHVibGljLCBpbiB0aGF0IG9yZGVyLlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjU3VibmV0cz86IGVjMi5TdWJuZXRTZWxlY3Rpb247XG5cbiAgLyoqXG4gICAqIFRoZSBzZWN1cml0eSBncm91cHMgdG8gYXNzb2NpYXRlIHdpdGggdGhlIHNlcnZpY2UuIElmIHlvdSBkbyBub3Qgc3BlY2lmeSBhIHNlY3VyaXR5IGdyb3VwLCBhIG5ldyBzZWN1cml0eSBncm91cCBpcyBjcmVhdGVkLlxuICAgKlxuICAgKiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgdXNlZCBmb3IgdGFza3MgdGhhdCB1c2UgdGhlIGF3c3ZwYyBuZXR3b3JrIG1vZGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gQSBuZXcgc2VjdXJpdHkgZ3JvdXAgaXMgY3JlYXRlZC5cbiAgICogQGRlcHJlY2F0ZWQgdXNlIHNlY3VyaXR5R3JvdXBzIGluc3RlYWQuXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3VwPzogZWMyLklTZWN1cml0eUdyb3VwO1xuXG4gIC8qKlxuICAgKiBUaGUgc2VjdXJpdHkgZ3JvdXBzIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBzZXJ2aWNlLiBJZiB5b3UgZG8gbm90IHNwZWNpZnkgYSBzZWN1cml0eSBncm91cCwgYSBuZXcgc2VjdXJpdHkgZ3JvdXAgaXMgY3JlYXRlZC5cbiAgICpcbiAgICogVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IHVzZWQgZm9yIHRhc2tzIHRoYXQgdXNlIHRoZSBhd3N2cGMgbmV0d29yayBtb2RlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEEgbmV3IHNlY3VyaXR5IGdyb3VwIGlzIGNyZWF0ZWQuXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3Vwcz86IGVjMi5JU2VjdXJpdHlHcm91cFtdO1xuXG4gIC8qKlxuICAgKiBUaGUgcGxhY2VtZW50IGNvbnN0cmFpbnRzIHRvIHVzZSBmb3IgdGFza3MgaW4gdGhlIHNlcnZpY2UuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWVcbiAgICogW0FtYXpvbiBFQ1MgVGFzayBQbGFjZW1lbnQgQ29uc3RyYWludHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3Rhc2stcGxhY2VtZW50LWNvbnN0cmFpbnRzLmh0bWwpLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGNvbnN0cmFpbnRzLlxuICAgKi9cbiAgcmVhZG9ubHkgcGxhY2VtZW50Q29uc3RyYWludHM/OiBQbGFjZW1lbnRDb25zdHJhaW50W107XG5cbiAgLyoqXG4gICAqIFRoZSBwbGFjZW1lbnQgc3RyYXRlZ2llcyB0byB1c2UgZm9yIHRhc2tzIGluIHRoZSBzZXJ2aWNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlXG4gICAqIFtBbWF6b24gRUNTIFRhc2sgUGxhY2VtZW50IFN0cmF0ZWdpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3Rhc2stcGxhY2VtZW50LXN0cmF0ZWdpZXMuaHRtbCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gc3RyYXRlZ2llcy5cbiAgICovXG4gIHJlYWRvbmx5IHBsYWNlbWVudFN0cmF0ZWdpZXM/OiBQbGFjZW1lbnRTdHJhdGVneVtdO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgd2hldGhlciB0aGUgc2VydmljZSB3aWxsIHVzZSB0aGUgZGFlbW9uIHNjaGVkdWxpbmcgc3RyYXRlZ3kuXG4gICAqIElmIHRydWUsIHRoZSBzZXJ2aWNlIHNjaGVkdWxlciBkZXBsb3lzIGV4YWN0bHkgb25lIHRhc2sgb24gZWFjaCBjb250YWluZXIgaW5zdGFuY2UgaW4geW91ciBjbHVzdGVyLlxuICAgKlxuICAgKiBXaGVuIHlvdSBhcmUgdXNpbmcgdGhpcyBzdHJhdGVneSwgZG8gbm90IHNwZWNpZnkgYSBkZXNpcmVkIG51bWJlciBvZiB0YXNrcyBvcmFueSB0YXNrIHBsYWNlbWVudCBzdHJhdGVnaWVzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgZGFlbW9uPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBUaGUgaW50ZXJmYWNlIGZvciBhIHNlcnZpY2UgdXNpbmcgdGhlIEVDMiBsYXVuY2ggdHlwZSBvbiBhbiBFQ1MgY2x1c3Rlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJRWMyU2VydmljZSBleHRlbmRzIElTZXJ2aWNlIHtcblxufVxuXG4vKipcbiAqIFRoZSBwcm9wZXJ0aWVzIHRvIGltcG9ydCBmcm9tIHRoZSBzZXJ2aWNlIHVzaW5nIHRoZSBFQzIgbGF1bmNoIHR5cGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRWMyU2VydmljZUF0dHJpYnV0ZXMge1xuICAvKipcbiAgICogVGhlIGNsdXN0ZXIgdGhhdCBob3N0cyB0aGUgc2VydmljZS5cbiAgICovXG4gIHJlYWRvbmx5IGNsdXN0ZXI6IElDbHVzdGVyO1xuXG4gIC8qKlxuICAgKiBUaGUgc2VydmljZSBBUk4uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZWl0aGVyIHRoaXMsIG9yIHtAbGluayBzZXJ2aWNlTmFtZX0sIGlzIHJlcXVpcmVkXG4gICAqL1xuICByZWFkb25seSBzZXJ2aWNlQXJuPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgc2VydmljZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBlaXRoZXIgdGhpcywgb3Ige0BsaW5rIHNlcnZpY2VBcm59LCBpcyByZXF1aXJlZFxuICAgKi9cbiAgcmVhZG9ubHkgc2VydmljZU5hbWU/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhpcyBjcmVhdGVzIGEgc2VydmljZSB1c2luZyB0aGUgRUMyIGxhdW5jaCB0eXBlIG9uIGFuIEVDUyBjbHVzdGVyLlxuICpcbiAqIEByZXNvdXJjZSBBV1M6OkVDUzo6U2VydmljZVxuICovXG5leHBvcnQgY2xhc3MgRWMyU2VydmljZSBleHRlbmRzIEJhc2VTZXJ2aWNlIGltcGxlbWVudHMgSUVjMlNlcnZpY2Uge1xuXG4gIC8qKlxuICAgKiBJbXBvcnRzIGZyb20gdGhlIHNwZWNpZmllZCBzZXJ2aWNlIEFSTi5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbUVjMlNlcnZpY2VBcm4oc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgZWMyU2VydmljZUFybjogc3RyaW5nKTogSUVjMlNlcnZpY2Uge1xuICAgIGNsYXNzIEltcG9ydCBleHRlbmRzIFJlc291cmNlIGltcGxlbWVudHMgSUVjMlNlcnZpY2Uge1xuICAgICAgcHVibGljIHJlYWRvbmx5IHNlcnZpY2VBcm4gPSBlYzJTZXJ2aWNlQXJuO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHNlcnZpY2VOYW1lID0gU3RhY2sub2Yoc2NvcGUpLnNwbGl0QXJuKGVjMlNlcnZpY2VBcm4sIEFybkZvcm1hdC5TTEFTSF9SRVNPVVJDRV9OQU1FKS5yZXNvdXJjZU5hbWUgYXMgc3RyaW5nO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEltcG9ydChzY29wZSwgaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEltcG9ydHMgZnJvbSB0aGUgc3BlY2lmaWVkIHNlcnZpY2UgYXR0cmlidXRlcy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbUVjMlNlcnZpY2VBdHRyaWJ1dGVzKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIGF0dHJzOiBFYzJTZXJ2aWNlQXR0cmlidXRlcyk6IElCYXNlU2VydmljZSB7XG4gICAgcmV0dXJuIGZyb21TZXJ2aWNlQXR0cmlidXRlcyhzY29wZSwgaWQsIGF0dHJzKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZG9ubHkgY29uc3RyYWludHM6IENmblNlcnZpY2UuUGxhY2VtZW50Q29uc3RyYWludFByb3BlcnR5W107XG4gIHByaXZhdGUgcmVhZG9ubHkgc3RyYXRlZ2llczogQ2ZuU2VydmljZS5QbGFjZW1lbnRTdHJhdGVneVByb3BlcnR5W107XG4gIHByaXZhdGUgcmVhZG9ubHkgZGFlbW9uOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBFYzJTZXJ2aWNlIGNsYXNzLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IEVjMlNlcnZpY2VQcm9wcykge1xuICAgIGlmIChwcm9wcy5kYWVtb24gJiYgcHJvcHMuZGVzaXJlZENvdW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRGFlbW9uIG1vZGUgbGF1bmNoZXMgb25lIHRhc2sgb24gZXZlcnkgaW5zdGFuY2UuIERvblxcJ3Qgc3VwcGx5IGRlc2lyZWRDb3VudC4nKTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuZGFlbW9uICYmIHByb3BzLm1heEhlYWx0aHlQZXJjZW50ICE9PSB1bmRlZmluZWQgJiYgcHJvcHMubWF4SGVhbHRoeVBlcmNlbnQgIT09IDEwMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNYXhpbXVtIHBlcmNlbnQgbXVzdCBiZSAxMDAgZm9yIGRhZW1vbiBtb2RlLicpO1xuICAgIH1cblxuICAgIGlmIChwcm9wcy5taW5IZWFsdGh5UGVyY2VudCAhPT0gdW5kZWZpbmVkICYmIHByb3BzLm1heEhlYWx0aHlQZXJjZW50ICE9PSB1bmRlZmluZWQgJiYgcHJvcHMubWluSGVhbHRoeVBlcmNlbnQgPj0gcHJvcHMubWF4SGVhbHRoeVBlcmNlbnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWluaW11bSBoZWFsdGh5IHBlcmNlbnQgbXVzdCBiZSBsZXNzIHRoYW4gbWF4aW11bSBoZWFsdGh5IHBlcmNlbnQuJyk7XG4gICAgfVxuXG4gICAgaWYgKCFwcm9wcy50YXNrRGVmaW5pdGlvbi5pc0VjMkNvbXBhdGlibGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU3VwcGxpZWQgVGFza0RlZmluaXRpb24gaXMgbm90IGNvbmZpZ3VyZWQgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBFQzInKTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuc2VjdXJpdHlHcm91cCAhPT0gdW5kZWZpbmVkICYmIHByb3BzLnNlY3VyaXR5R3JvdXBzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT25seSBvbmUgb2YgU2VjdXJpdHlHcm91cCBvciBTZWN1cml0eUdyb3VwcyBjYW4gYmUgcG9wdWxhdGVkLicpO1xuICAgIH1cblxuICAgIHN1cGVyKHNjb3BlLCBpZCwge1xuICAgICAgLi4ucHJvcHMsXG4gICAgICBkZXNpcmVkQ291bnQ6IHByb3BzLmRlc2lyZWRDb3VudCxcbiAgICAgIG1heEhlYWx0aHlQZXJjZW50OiBwcm9wcy5kYWVtb24gJiYgcHJvcHMubWF4SGVhbHRoeVBlcmNlbnQgPT09IHVuZGVmaW5lZCA/IDEwMCA6IHByb3BzLm1heEhlYWx0aHlQZXJjZW50LFxuICAgICAgbWluSGVhbHRoeVBlcmNlbnQ6IHByb3BzLmRhZW1vbiAmJiBwcm9wcy5taW5IZWFsdGh5UGVyY2VudCA9PT0gdW5kZWZpbmVkID8gMCA6IHByb3BzLm1pbkhlYWx0aHlQZXJjZW50LFxuICAgICAgbGF1bmNoVHlwZTogTGF1bmNoVHlwZS5FQzIsXG4gICAgICBlbmFibGVFQ1NNYW5hZ2VkVGFnczogcHJvcHMuZW5hYmxlRUNTTWFuYWdlZFRhZ3MsXG4gICAgfSxcbiAgICB7XG4gICAgICBjbHVzdGVyOiBwcm9wcy5jbHVzdGVyLmNsdXN0ZXJOYW1lLFxuICAgICAgdGFza0RlZmluaXRpb246IHByb3BzLmRlcGxveW1lbnRDb250cm9sbGVyPy50eXBlID09PSBEZXBsb3ltZW50Q29udHJvbGxlclR5cGUuRVhURVJOQUwgPyB1bmRlZmluZWQgOiBwcm9wcy50YXNrRGVmaW5pdGlvbi50YXNrRGVmaW5pdGlvbkFybixcbiAgICAgIHBsYWNlbWVudENvbnN0cmFpbnRzOiBMYXp5LmFueSh7IHByb2R1Y2U6ICgpID0+IHRoaXMuY29uc3RyYWludHMgfSwgeyBvbWl0RW1wdHlBcnJheTogdHJ1ZSB9KSxcbiAgICAgIHBsYWNlbWVudFN0cmF0ZWdpZXM6IExhenkuYW55KHsgcHJvZHVjZTogKCkgPT4gdGhpcy5zdHJhdGVnaWVzIH0sIHsgb21pdEVtcHR5QXJyYXk6IHRydWUgfSksXG4gICAgICBzY2hlZHVsaW5nU3RyYXRlZ3k6IHByb3BzLmRhZW1vbiA/ICdEQUVNT04nIDogJ1JFUExJQ0EnLFxuICAgIH0sIHByb3BzLnRhc2tEZWZpbml0aW9uKTtcblxuICAgIHRoaXMuY29uc3RyYWludHMgPSBbXTtcbiAgICB0aGlzLnN0cmF0ZWdpZXMgPSBbXTtcbiAgICB0aGlzLmRhZW1vbiA9IHByb3BzLmRhZW1vbiB8fCBmYWxzZTtcblxuICAgIGxldCBzZWN1cml0eUdyb3VwcztcbiAgICBpZiAocHJvcHMuc2VjdXJpdHlHcm91cCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBzZWN1cml0eUdyb3VwcyA9IFtwcm9wcy5zZWN1cml0eUdyb3VwXTtcbiAgICB9IGVsc2UgaWYgKHByb3BzLnNlY3VyaXR5R3JvdXBzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHNlY3VyaXR5R3JvdXBzID0gcHJvcHMuc2VjdXJpdHlHcm91cHM7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLnRhc2tEZWZpbml0aW9uLm5ldHdvcmtNb2RlID09PSBOZXR3b3JrTW9kZS5BV1NfVlBDKSB7XG4gICAgICB0aGlzLmNvbmZpZ3VyZUF3c1ZwY05ldHdvcmtpbmdXaXRoU2VjdXJpdHlHcm91cHMocHJvcHMuY2x1c3Rlci52cGMsIHByb3BzLmFzc2lnblB1YmxpY0lwLCBwcm9wcy52cGNTdWJuZXRzLCBzZWN1cml0eUdyb3Vwcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEVpdGhlciBOb25lLCBCcmlkZ2Ugb3IgSG9zdCBuZXR3b3JraW5nLiBDb3B5IFNlY3VyaXR5R3JvdXBzIGZyb20gQVNHLlxuICAgICAgLy8gV2UgaGF2ZSB0byBiZSBzbWFydCBoZXJlIC0tIGJ5IGRlZmF1bHQgZnV0dXJlIFNlY3VyaXR5IEdyb3VwIHJ1bGVzIHdvdWxkIGJlIGNyZWF0ZWRcbiAgICAgIC8vIGluIHRoZSBDbHVzdGVyIHN0YWNrLiBIb3dldmVyLCBpZiB0aGUgQ2x1c3RlciBpcyBpbiBhIGRpZmZlcmVudCBzdGFjayB0aGFuIHVzLFxuICAgICAgLy8gdGhhdCB3aWxsIGxlYWQgdG8gYSBjeWNsaWMgcmVmZXJlbmNlICh3ZSBwb2ludCB0byB0aGF0IHN0YWNrIGZvciB0aGUgY2x1c3RlciBuYW1lLFxuICAgICAgLy8gYnV0IHRoYXQgc3RhY2sgd2lsbCBwb2ludCB0byB0aGUgQUxCIHByb2JhYmx5IGNyZWF0ZWQgcmlnaHQgbmV4dCB0byB1cykuXG4gICAgICAvL1xuICAgICAgLy8gSW4gdGhhdCBjYXNlLCByZWZlcmVuY2UgdGhlIHNhbWUgc2VjdXJpdHkgZ3JvdXBzIGJ1dCBtYWtlIHN1cmUgbmV3IHJ1bGVzIGFyZVxuICAgICAgLy8gY3JlYXRlZCBpbiB0aGUgY3VycmVudCBzY29wZSAoaS5lLiwgdGhpcyBzdGFjaylcbiAgICAgIHZhbGlkYXRlTm9OZXR3b3JraW5nUHJvcHMocHJvcHMpO1xuICAgICAgdGhpcy5jb25uZWN0aW9ucy5hZGRTZWN1cml0eUdyb3VwKC4uLnNlY3VyaXR5R3JvdXBzSW5UaGlzU3RhY2sodGhpcywgcHJvcHMuY2x1c3Rlci5jb25uZWN0aW9ucy5zZWN1cml0eUdyb3VwcykpO1xuICAgIH1cblxuICAgIHRoaXMuYWRkUGxhY2VtZW50Q29uc3RyYWludHMoLi4ucHJvcHMucGxhY2VtZW50Q29uc3RyYWludHMgfHwgW10pO1xuICAgIHRoaXMuYWRkUGxhY2VtZW50U3RyYXRlZ2llcyguLi5wcm9wcy5wbGFjZW1lbnRTdHJhdGVnaWVzIHx8IFtdKTtcblxuICAgIHRoaXMubm9kZS5hZGRWYWxpZGF0aW9uKHtcbiAgICAgIHZhbGlkYXRlOiAoKSA9PiAhdGhpcy50YXNrRGVmaW5pdGlvbi5kZWZhdWx0Q29udGFpbmVyID8gWydBIFRhc2tEZWZpbml0aW9uIG11c3QgaGF2ZSBhdCBsZWFzdCBvbmUgZXNzZW50aWFsIGNvbnRhaW5lciddIDogW10sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBvbmUgb3IgbW9yZSBwbGFjZW1lbnQgc3RyYXRlZ2llcyB0byB1c2UgZm9yIHRhc2tzIGluIHRoZSBzZXJ2aWNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlXG4gICAqIFtBbWF6b24gRUNTIFRhc2sgUGxhY2VtZW50IFN0cmF0ZWdpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3Rhc2stcGxhY2VtZW50LXN0cmF0ZWdpZXMuaHRtbCkuXG4gICAqL1xuICBwdWJsaWMgYWRkUGxhY2VtZW50U3RyYXRlZ2llcyguLi5zdHJhdGVnaWVzOiBQbGFjZW1lbnRTdHJhdGVneVtdKSB7XG4gICAgaWYgKHN0cmF0ZWdpZXMubGVuZ3RoID4gMCAmJiB0aGlzLmRhZW1vbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3QgY29uZmlndXJlIHBsYWNlbWVudCBzdHJhdGVnaWVzIHdoZW4gZGFlbW9uPXRydWVcIik7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBzdHJhdGVneSBvZiBzdHJhdGVnaWVzKSB7XG4gICAgICB0aGlzLnN0cmF0ZWdpZXMucHVzaCguLi5zdHJhdGVneS50b0pzb24oKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgb25lIG9yIG1vcmUgcGxhY2VtZW50IGNvbnN0cmFpbnRzIHRvIHVzZSBmb3IgdGFza3MgaW4gdGhlIHNlcnZpY2UuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWVcbiAgICogW0FtYXpvbiBFQ1MgVGFzayBQbGFjZW1lbnQgQ29uc3RyYWludHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3Rhc2stcGxhY2VtZW50LWNvbnN0cmFpbnRzLmh0bWwpLlxuICAgKi9cbiAgcHVibGljIGFkZFBsYWNlbWVudENvbnN0cmFpbnRzKC4uLmNvbnN0cmFpbnRzOiBQbGFjZW1lbnRDb25zdHJhaW50W10pIHtcbiAgICBmb3IgKGNvbnN0IGNvbnN0cmFpbnQgb2YgY29uc3RyYWludHMpIHtcbiAgICAgIHRoaXMuY29uc3RyYWludHMucHVzaCguLi5jb25zdHJhaW50LnRvSnNvbigpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoaXMgRWMyU2VydmljZS5cbiAgICovXG4gIHByb3RlY3RlZCB2YWxpZGF0ZSgpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgcmV0ID0gc3VwZXIudmFsaWRhdGUoKTtcbiAgICBpZiAoIXRoaXMuY2x1c3Rlci5oYXNFYzJDYXBhY2l0eSkge1xuICAgICAgcmV0LnB1c2goJ0NsdXN0ZXIgZm9yIHRoaXMgc2VydmljZSBuZWVkcyBFYzIgY2FwYWNpdHkuIENhbGwgYWRkWHh4Q2FwYWNpdHkoKSBvbiB0aGUgY2x1c3Rlci4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbiAgfVxufVxuXG4vKipcbiAqIFZhbGlkYXRlIGNvbWJpbmF0aW9ucyBvZiBuZXR3b3JraW5nIGFyZ3VtZW50cy5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVOb05ldHdvcmtpbmdQcm9wcyhwcm9wczogRWMyU2VydmljZVByb3BzKSB7XG4gIGlmIChwcm9wcy52cGNTdWJuZXRzICE9PSB1bmRlZmluZWRcbiAgICB8fCBwcm9wcy5zZWN1cml0eUdyb3VwICE9PSB1bmRlZmluZWRcbiAgICB8fCBwcm9wcy5zZWN1cml0eUdyb3VwcyAhPT0gdW5kZWZpbmVkXG4gICAgfHwgcHJvcHMuYXNzaWduUHVibGljSXApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3ZwY1N1Ym5ldHMsIHNlY3VyaXR5R3JvdXAocykgYW5kIGFzc2lnblB1YmxpY0lwIGNhbiBvbmx5IGJlIHVzZWQgaW4gQXdzVnBjIG5ldHdvcmtpbmcgbW9kZScpO1xuICB9XG59XG5cbi8qKlxuICogRm9yY2Ugc2VjdXJpdHkgZ3JvdXAgcnVsZXMgdG8gYmUgY3JlYXRlZCBpbiB0aGlzIHN0YWNrLlxuICpcbiAqIEZvciBldmVyeSBzZWN1cml0eSBncm91cCwgaWYgdGhlIHNjb3BlIGFuZCB0aGUgZ3JvdXAgYXJlIGluIGRpZmZlcmVudCBzdGFja3MsIHJldHVyblxuICogYSBmYWtlIFwiaW1wb3J0ZWRcIiBzZWN1cml0eSBncm91cCBpbnN0ZWFkLiBUaGlzIHdpbGwgYmVoYXZlIGFzIHRoZSBvcmlnaW5hbCBzZWN1cml0eSBncm91cCxcbiAqIGJ1dCBuZXcgSW5ncmVzcyBhbmQgRWdyZXNzIHJ1bGUgcmVzb3VyY2VzIHdpbGwgYmUgYWRkZWQgaW4gdGhlIGN1cnJlbnQgc3RhY2sgaW5zdGVhZCBvZiB0aGVcbiAqIG90aGVyIG9uZS5cbiAqL1xuZnVuY3Rpb24gc2VjdXJpdHlHcm91cHNJblRoaXNTdGFjayhzY29wZTogQ29uc3RydWN0LCBncm91cHM6IGVjMi5JU2VjdXJpdHlHcm91cFtdKTogZWMyLklTZWN1cml0eUdyb3VwW10ge1xuICBjb25zdCB0aGlzU3RhY2sgPSBTdGFjay5vZihzY29wZSk7XG5cbiAgbGV0IGkgPSAxO1xuICByZXR1cm4gZ3JvdXBzLm1hcChncm91cCA9PiB7XG4gICAgaWYgKHRoaXNTdGFjayA9PT0gU3RhY2sub2YoZ3JvdXApKSB7IHJldHVybiBncm91cDsgfSAvLyBTaW1wbGUgY2FzZSwganVzdCByZXR1cm4gdGhlIG9yaWdpbmFsIG9uZVxuXG4gICAgcmV0dXJuIGVjMi5TZWN1cml0eUdyb3VwLmZyb21TZWN1cml0eUdyb3VwSWQoc2NvcGUsIGBTZWN1cml0eUdyb3VwJHtpKyt9YCwgZ3JvdXAuc2VjdXJpdHlHcm91cElkLCB7XG4gICAgICBhbGxvd0FsbE91dGJvdW5kOiBncm91cC5hbGxvd0FsbE91dGJvdW5kLFxuICAgICAgbXV0YWJsZTogdHJ1ZSxcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogVGhlIGJ1aWx0LWluIGNvbnRhaW5lciBpbnN0YW5jZSBhdHRyaWJ1dGVzXG4gKi9cbmV4cG9ydCBjbGFzcyBCdWlsdEluQXR0cmlidXRlcyB7XG4gIC8qKlxuICAgKiBUaGUgaWQgb2YgdGhlIGluc3RhbmNlLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBJTlNUQU5DRV9JRCA9ICdpbnN0YW5jZUlkJztcblxuICAvKipcbiAgICogVGhlIEF2YWlsYWJpbGl0eVpvbmUgd2hlcmUgdGhlIGluc3RhbmNlIGlzIHJ1bm5pbmcgaW4uXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IEFWQUlMQUJJTElUWV9aT05FID0gJ2F0dHJpYnV0ZTplY3MuYXZhaWxhYmlsaXR5LXpvbmUnO1xuXG4gIC8qKlxuICAgKiBUaGUgQU1JIGlkIHRoZSBpbnN0YW5jZSBpcyB1c2luZy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQU1JX0lEID0gJ2F0dHJpYnV0ZTplY3MuYW1pLWlkJztcblxuICAvKipcbiAgICogVGhlIEVDMiBpbnN0YW5jZSB0eXBlLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBJTlNUQU5DRV9UWVBFID0gJ2F0dHJpYnV0ZTplY3MuaW5zdGFuY2UtdHlwZSc7XG5cbiAgLyoqXG4gICAqIFRoZSBvcGVyYXRpbmcgc3lzdGVtIG9mIHRoZSBpbnN0YW5jZS5cbiAgICpcbiAgICogRWl0aGVyICdsaW51eCcgb3IgJ3dpbmRvd3MnLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBPU19UWVBFID0gJ2F0dHJpYnV0ZTplY3Mub3MtdHlwZSc7XG59XG4iXX0=