1 | ;
|
2 | var _a, _b;
|
3 | Object.defineProperty(exports, "__esModule", { value: true });
|
4 | exports.BuiltInAttributes = exports.Ec2Service = void 0;
|
5 | const jsiiDeprecationWarnings = require("../../.warnings.jsii.js");
|
6 | const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
7 | const ec2 = require("@aws-cdk/aws-ec2");
|
8 | const core_1 = require("@aws-cdk/core");
|
9 | const base_service_1 = require("../base/base-service");
|
10 | const from_service_attributes_1 = require("../base/from-service-attributes");
|
11 | const task_definition_1 = require("../base/task-definition");
|
12 | /**
|
13 | * This creates a service using the EC2 launch type on an ECS cluster.
|
14 | *
|
15 | * @resource AWS::ECS::Service
|
16 | */
|
17 | class Ec2Service extends base_service_1.BaseService {
|
18 | /**
|
19 | * Constructs a new instance of the Ec2Service class.
|
20 | */
|
21 | constructor(scope, id, props) {
|
22 | var _c;
|
23 | try {
|
24 | jsiiDeprecationWarnings._aws_cdk_aws_ecs_Ec2ServiceProps(props);
|
25 | }
|
26 | catch (error) {
|
27 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
28 | Error.captureStackTrace(error, this.constructor);
|
29 | }
|
30 | throw error;
|
31 | }
|
32 | if (props.daemon && props.desiredCount !== undefined) {
|
33 | throw new Error('Daemon mode launches one task on every instance. Don\'t supply desiredCount.');
|
34 | }
|
35 | if (props.daemon && props.maxHealthyPercent !== undefined && props.maxHealthyPercent !== 100) {
|
36 | throw new Error('Maximum percent must be 100 for daemon mode.');
|
37 | }
|
38 | if (props.minHealthyPercent !== undefined && props.maxHealthyPercent !== undefined && props.minHealthyPercent >= props.maxHealthyPercent) {
|
39 | throw new Error('Minimum healthy percent must be less than maximum healthy percent.');
|
40 | }
|
41 | if (!props.taskDefinition.isEc2Compatible) {
|
42 | throw new Error('Supplied TaskDefinition is not configured for compatibility with EC2');
|
43 | }
|
44 | if (props.securityGroup !== undefined && props.securityGroups !== undefined) {
|
45 | throw new Error('Only one of SecurityGroup or SecurityGroups can be populated.');
|
46 | }
|
47 | super(scope, id, {
|
48 | ...props,
|
49 | desiredCount: props.desiredCount,
|
50 | maxHealthyPercent: props.daemon && props.maxHealthyPercent === undefined ? 100 : props.maxHealthyPercent,
|
51 | minHealthyPercent: props.daemon && props.minHealthyPercent === undefined ? 0 : props.minHealthyPercent,
|
52 | launchType: base_service_1.LaunchType.EC2,
|
53 | enableECSManagedTags: props.enableECSManagedTags,
|
54 | }, {
|
55 | cluster: props.cluster.clusterName,
|
56 | taskDefinition: ((_c = props.deploymentController) === null || _c === void 0 ? void 0 : _c.type) === base_service_1.DeploymentControllerType.EXTERNAL ? undefined : props.taskDefinition.taskDefinitionArn,
|
57 | placementConstraints: core_1.Lazy.any({ produce: () => this.constraints }, { omitEmptyArray: true }),
|
58 | placementStrategies: core_1.Lazy.any({ produce: () => this.strategies }, { omitEmptyArray: true }),
|
59 | schedulingStrategy: props.daemon ? 'DAEMON' : 'REPLICA',
|
60 | }, props.taskDefinition);
|
61 | this.constraints = [];
|
62 | this.strategies = [];
|
63 | this.daemon = props.daemon || false;
|
64 | let securityGroups;
|
65 | if (props.securityGroup !== undefined) {
|
66 | securityGroups = [props.securityGroup];
|
67 | }
|
68 | else if (props.securityGroups !== undefined) {
|
69 | securityGroups = props.securityGroups;
|
70 | }
|
71 | if (props.taskDefinition.networkMode === task_definition_1.NetworkMode.AWS_VPC) {
|
72 | this.configureAwsVpcNetworkingWithSecurityGroups(props.cluster.vpc, props.assignPublicIp, props.vpcSubnets, securityGroups);
|
73 | }
|
74 | else {
|
75 | // Either None, Bridge or Host networking. Copy SecurityGroups from ASG.
|
76 | // We have to be smart here -- by default future Security Group rules would be created
|
77 | // in the Cluster stack. However, if the Cluster is in a different stack than us,
|
78 | // that will lead to a cyclic reference (we point to that stack for the cluster name,
|
79 | // but that stack will point to the ALB probably created right next to us).
|
80 | //
|
81 | // In that case, reference the same security groups but make sure new rules are
|
82 | // created in the current scope (i.e., this stack)
|
83 | validateNoNetworkingProps(props);
|
84 | this.connections.addSecurityGroup(...securityGroupsInThisStack(this, props.cluster.connections.securityGroups));
|
85 | }
|
86 | this.addPlacementConstraints(...props.placementConstraints || []);
|
87 | this.addPlacementStrategies(...props.placementStrategies || []);
|
88 | this.node.addValidation({
|
89 | validate: () => !this.taskDefinition.defaultContainer ? ['A TaskDefinition must have at least one essential container'] : [],
|
90 | });
|
91 | }
|
92 | /**
|
93 | * Imports from the specified service ARN.
|
94 | */
|
95 | static fromEc2ServiceArn(scope, id, ec2ServiceArn) {
|
96 | class Import extends core_1.Resource {
|
97 | constructor() {
|
98 | super(...arguments);
|
99 | this.serviceArn = ec2ServiceArn;
|
100 | this.serviceName = core_1.Stack.of(scope).splitArn(ec2ServiceArn, core_1.ArnFormat.SLASH_RESOURCE_NAME).resourceName;
|
101 | }
|
102 | }
|
103 | return new Import(scope, id);
|
104 | }
|
105 | /**
|
106 | * Imports from the specified service attrributes.
|
107 | */
|
108 | static fromEc2ServiceAttributes(scope, id, attrs) {
|
109 | try {
|
110 | jsiiDeprecationWarnings._aws_cdk_aws_ecs_Ec2ServiceAttributes(attrs);
|
111 | }
|
112 | catch (error) {
|
113 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
114 | Error.captureStackTrace(error, this.fromEc2ServiceAttributes);
|
115 | }
|
116 | throw error;
|
117 | }
|
118 | return from_service_attributes_1.fromServiceAtrributes(scope, id, attrs);
|
119 | }
|
120 | /**
|
121 | * Adds one or more placement strategies to use for tasks in the service. For more information, see
|
122 | * [Amazon ECS Task Placement Strategies](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement-strategies.html).
|
123 | */
|
124 | addPlacementStrategies(...strategies) {
|
125 | try {
|
126 | jsiiDeprecationWarnings._aws_cdk_aws_ecs_PlacementStrategy(strategies);
|
127 | }
|
128 | catch (error) {
|
129 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
130 | Error.captureStackTrace(error, this.addPlacementStrategies);
|
131 | }
|
132 | throw error;
|
133 | }
|
134 | if (strategies.length > 0 && this.daemon) {
|
135 | throw new Error("Can't configure placement strategies when daemon=true");
|
136 | }
|
137 | for (const strategy of strategies) {
|
138 | this.strategies.push(...strategy.toJson());
|
139 | }
|
140 | }
|
141 | /**
|
142 | * Adds one or more placement constraints to use for tasks in the service. For more information, see
|
143 | * [Amazon ECS Task Placement Constraints](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement-constraints.html).
|
144 | */
|
145 | addPlacementConstraints(...constraints) {
|
146 | try {
|
147 | jsiiDeprecationWarnings._aws_cdk_aws_ecs_PlacementConstraint(constraints);
|
148 | }
|
149 | catch (error) {
|
150 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
151 | Error.captureStackTrace(error, this.addPlacementConstraints);
|
152 | }
|
153 | throw error;
|
154 | }
|
155 | for (const constraint of constraints) {
|
156 | this.constraints.push(...constraint.toJson());
|
157 | }
|
158 | }
|
159 | /**
|
160 | * Validates this Ec2Service.
|
161 | */
|
162 | validate() {
|
163 | const ret = super.validate();
|
164 | if (!this.cluster.hasEc2Capacity) {
|
165 | ret.push('Cluster for this service needs Ec2 capacity. Call addXxxCapacity() on the cluster.');
|
166 | }
|
167 | return ret;
|
168 | }
|
169 | }
|
170 | exports.Ec2Service = Ec2Service;
|
171 | _a = JSII_RTTI_SYMBOL_1;
|
172 | Ec2Service[_a] = { fqn: "@aws-cdk/aws-ecs.Ec2Service", version: "1.156.1" };
|
173 | /**
|
174 | * Validate combinations of networking arguments.
|
175 | */
|
176 | function validateNoNetworkingProps(props) {
|
177 | if (props.vpcSubnets !== undefined
|
178 | || props.securityGroup !== undefined
|
179 | || props.securityGroups !== undefined
|
180 | || props.assignPublicIp) {
|
181 | throw new Error('vpcSubnets, securityGroup(s) and assignPublicIp can only be used in AwsVpc networking mode');
|
182 | }
|
183 | }
|
184 | /**
|
185 | * Force security group rules to be created in this stack.
|
186 | *
|
187 | * For every security group, if the scope and the group are in different stacks, return
|
188 | * a fake "imported" security group instead. This will behave as the original security group,
|
189 | * but new Ingress and Egress rule resources will be added in the current stack instead of the
|
190 | * other one.
|
191 | */
|
192 | function securityGroupsInThisStack(scope, groups) {
|
193 | const thisStack = core_1.Stack.of(scope);
|
194 | let i = 1;
|
195 | return groups.map(group => {
|
196 | if (thisStack === core_1.Stack.of(group)) {
|
197 | return group;
|
198 | } // Simple case, just return the original one
|
199 | return ec2.SecurityGroup.fromSecurityGroupId(scope, `SecurityGroup${i++}`, group.securityGroupId, {
|
200 | allowAllOutbound: group.allowAllOutbound,
|
201 | mutable: true,
|
202 | });
|
203 | });
|
204 | }
|
205 | /**
|
206 | * The built-in container instance attributes
|
207 | */
|
208 | class BuiltInAttributes {
|
209 | }
|
210 | exports.BuiltInAttributes = BuiltInAttributes;
|
211 | _b = JSII_RTTI_SYMBOL_1;
|
212 | BuiltInAttributes[_b] = { fqn: "@aws-cdk/aws-ecs.BuiltInAttributes", version: "1.156.1" };
|
213 | /**
|
214 | * The id of the instance.
|
215 | */
|
216 | BuiltInAttributes.INSTANCE_ID = 'instanceId';
|
217 | /**
|
218 | * The AvailabilityZone where the instance is running in.
|
219 | */
|
220 | BuiltInAttributes.AVAILABILITY_ZONE = 'attribute:ecs.availability-zone';
|
221 | /**
|
222 | * The AMI id the instance is using.
|
223 | */
|
224 | BuiltInAttributes.AMI_ID = 'attribute:ecs.ami-id';
|
225 | /**
|
226 | * The EC2 instance type.
|
227 | */
|
228 | BuiltInAttributes.INSTANCE_TYPE = 'attribute:ecs.instance-type';
|
229 | /**
|
230 | * The operating system of the instance.
|
231 | *
|
232 | * Either 'linux' or 'windows'.
|
233 | */
|
234 | BuiltInAttributes.OS_TYPE = 'attribute:ecs.os-type';
|
235 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWMyLXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJlYzItc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSx3Q0FBd0M7QUFDeEMsd0NBQWlFO0FBRWpFLHVEQUFxSTtBQUNySSw2RUFBd0U7QUFDeEUsNkRBQXNFO0FBZ0h0RTs7OztHQUlHO0FBQ0gsTUFBYSxVQUFXLFNBQVEsMEJBQVc7SUF3QnpDOztPQUVHO0lBQ0gsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFzQjs7Ozs7Ozs7Ozs7UUFDOUQsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLEtBQUssQ0FBQyxZQUFZLEtBQUssU0FBUyxFQUFFO1lBQ3BELE1BQU0sSUFBSSxLQUFLLENBQUMsOEVBQThFLENBQUMsQ0FBQztTQUNqRztRQUVELElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsaUJBQWlCLEtBQUssU0FBUyxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsS0FBSyxHQUFHLEVBQUU7WUFDNUYsTUFBTSxJQUFJLEtBQUssQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO1NBQ2pFO1FBRUQsSUFBSSxLQUFLLENBQUMsaUJBQWlCLEtBQUssU0FBUyxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsS0FBSyxTQUFTLElBQUksS0FBSyxDQUFDLGlCQUFpQixJQUFJLEtBQUssQ0FBQyxpQkFBaUIsRUFBRTtZQUN4SSxNQUFNLElBQUksS0FBSyxDQUFDLG9FQUFvRSxDQUFDLENBQUM7U0FDdkY7UUFFRCxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxlQUFlLEVBQUU7WUFDekMsTUFBTSxJQUFJLEtBQUssQ0FBQyxzRUFBc0UsQ0FBQyxDQUFDO1NBQ3pGO1FBRUQsSUFBSSxLQUFLLENBQUMsYUFBYSxLQUFLLFNBQVMsSUFBSSxLQUFLLENBQUMsY0FBYyxLQUFLLFNBQVMsRUFBRTtZQUMzRSxNQUFNLElBQUksS0FBSyxDQUFDLCtEQUErRCxDQUFDLENB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UUFFakcsT0FBTyxHQUFHLENBQUMsYUFBYSxDQUFDLG1CQUFtQixDQUFDLEtBQUssRUFBRSxnQkFBZ0IsQ0FBQyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsZUFBZSxFQUFFO1lBQ2hHLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxnQkFBZ0I7WUFDeEMsT0FBTyxFQUFFLElBQUk7U0FDZCxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQWEsaUJBQWlCOztBQUE5Qiw4Q0EyQkM7OztBQTFCQzs7R0FFRztBQUNvQiw2QkFBVyxHQUFHLFlBQVksQ0FBQztBQUVsRDs7R0FFRztBQUNvQixtQ0FBaUIsR0FBRyxpQ0FBaUMsQ0FBQztBQUU3RTs7R0FFRztBQUNvQix3QkFBTSxHQUFHLHNCQUFzQixDQUFDO0FBRXZEOztHQUVHO0FBQ29CLCtCQUFhLEdBQUcsNkJBQTZCLENBQUM7QUFFckU7Ozs7R0FJRztBQUNvQix5QkFBTyxHQUFHLHVCQUF1QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZWMyIGZyb20gJ0Bhd3MtY2RrL2F3cy1lYzInO1xuaW1wb3J0IHsgQXJuRm9ybWF0LCBMYXp5LCBSZXNvdXJjZSwgU3RhY2sgfSBmcm9tICdAYXdzLWNkay9jb3JlJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgQmFzZVNlcnZpY2UsIEJhc2VTZXJ2aWNlT3B0aW9ucywgRGVwbG95bWVudENvbnRyb2xsZXJUeXBlLCBJQmFzZVNlcnZpY2UsIElTZXJ2aWNlLCBMYXVuY2hUeXBlIH0gZnJvbSAnLi4vYmFzZS9iYXNlLXNlcnZpY2UnO1xuaW1wb3J0IHsgZnJvbVNlcnZpY2VBdHJyaWJ1dGVzIH0gZnJvbSAnLi4vYmFzZS9mcm9tLXNlcnZpY2UtYXR0cmlidXRlcyc7XG5pbXBvcnQgeyBOZXR3b3JrTW9kZSwgVGFza0RlZmluaXRpb24gfSBmcm9tICcuLi9iYXNlL3Rhc2stZGVmaW5pdGlvbic7XG5pbXBvcnQgeyBJQ2x1c3RlciB9IGZyb20gJy4uL2NsdXN0ZXInO1xuaW1wb3J0IHsgQ2ZuU2VydmljZSB9IGZyb20gJy4uL2Vjcy5nZW5lcmF0ZWQnO1xuaW1wb3J0IHsgUGxhY2VtZW50Q29uc3RyYWludCwgUGxhY2VtZW50U3RyYXRlZ3kgfSBmcm9tICcuLi9wbGFjZW1lbnQnO1xuXG4vKipcbiAqIFRoZSBwcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIHNlcnZpY2UgdXNpbmcgdGhlIEVDMiBsYXVuY2ggdHlwZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFYzJTZXJ2aWNlUHJvcHMgZXh0ZW5kcyBCYXNlU2VydmljZU9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIHRhc2sgZGVmaW5pdGlvbiB0byB1c2UgZm9yIHRhc2tzIGluIHRoZSBzZXJ2aWNlLlxuICAgKlxuICAgKiBbZGlzYWJsZS1hd3NsaW50OnJlZi12aWEtaW50ZXJmYWNlXVxuICAgKi9cbiAgcmVhZG9ubHkgdGFza0RlZmluaXRpb246IFRhc2tEZWZpbml0aW9uO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgd2hldGhlciB0aGUgdGFzaydzIGVsYXN0aWMgbmV0d29yayBpbnRlcmZhY2UgcmVjZWl2ZXMgYSBwdWJsaWMgSVAgYWRkcmVzcy5cbiAgICogSWYgdHJ1ZSwgZWFjaCB0YXNrIHdpbGwgcmVjZWl2ZSBhIHB1YmxpYyBJUCBhZGRyZXNzLlxuICAgKlxuICAgKiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgdXNlZCBmb3IgdGFza3MgdGhhdCB1c2UgdGhlIGF3c3ZwYyBuZXR3b3JrIG1vZGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBhc3NpZ25QdWJsaWNJcD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBzdWJuZXRzIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBzZXJ2aWNlLlxuICAgKlxuICAgKiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgdXNlZCBmb3IgdGFza3MgdGhhdCB1c2UgdGhlIGF3c3ZwYyBuZXR3b3JrIG1vZGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gUHVibGljIHN1Ym5ldHMgaWYgYGFzc2lnblB1YmxpY0lwYCBpcyBzZXQsIG90aGVyd2lzZSB0aGUgZmlyc3QgYXZhaWxhYmxlIG9uZSBvZiBQcml2YXRlLCBJc29sYXRlZCwgUHVibGljLCBpbiB0aGF0IG9yZGVyLlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjU3VibmV0cz86IGVjMi5TdWJuZXRTZWxlY3Rpb247XG5cbiAgLyoqXG4gICAqIFRoZSBzZWN1cml0eSBncm91cHMgdG8gYXNzb2NpYXRlIHdpdGggdGhlIHNlcnZpY2UuIElmIHlvdSBkbyBub3Qgc3BlY2lmeSBhIHNlY3VyaXR5IGdyb3VwLCBhIG5ldyBzZWN1cml0eSBncm91cCBpcyBjcmVhdGVkLlxuICAgKlxuICAgKiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgdXNlZCBmb3IgdGFza3MgdGhhdCB1c2UgdGhlIGF3c3ZwYyBuZXR3b3JrIG1vZGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gQSBuZXcgc2VjdXJpdHkgZ3JvdXAgaXMgY3JlYXRlZC5cbiAgICogQGRlcHJlY2F0ZWQgdXNlIHNlY3VyaXR5R3JvdXBzIGluc3RlYWQuXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3VwPzogZWMyLklTZWN1cml0eUdyb3VwO1xuXG4gIC8qKlxuICAgKiBUaGUgc2VjdXJpdHkgZ3JvdXBzIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBzZXJ2aWNlLiBJZiB5b3UgZG8gbm90IHNwZWNpZnkgYSBzZWN1cml0eSBncm91cCwgYSBuZXcgc2VjdXJpdHkgZ3JvdXAgaXMgY3JlYXRlZC5cbiAgICpcbiAgICogVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IHVzZWQgZm9yIHRhc2tzIHRoYXQgdXNlIHRoZSBhd3N2cGMgbmV0d29yayBtb2RlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEEgbmV3IHNlY3VyaXR5IGdyb3VwIGlzIGNyZWF0ZWQuXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3Vwcz86IGVjMi5JU2VjdXJpdHlHcm91cFtdO1xuXG4gIC8qKlxuICAgKiBUaGUgcGxhY2VtZW50IGNvbnN0cmFpbnRzIHRvIHVzZSBmb3IgdGFza3MgaW4gdGhlIHNlcnZpY2UuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWVcbiAgICogW0FtYXpvbiBFQ1MgVGFzayBQbGFjZW1lbnQgQ29uc3RyYWludHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3Rhc2stcGxhY2VtZW50LWNvbnN0cmFpbnRzLmh0bWwpLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGNvbnN0cmFpbnRzLlxuICAgKi9cbiAgcmVhZG9ubHkgcGxhY2VtZW50Q29uc3RyYWludHM/OiBQbGFjZW1lbnRDb25zdHJhaW50W107XG5cbiAgLyoqXG4gICAqIFRoZSBwbGFjZW1lbnQgc3RyYXRlZ2llcyB0byB1c2UgZm9yIHRhc2tzIGluIHRoZSBzZXJ2aWNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlXG4gICAqIFtBbWF6b24gRUNTIFRhc2sgUGxhY2VtZW50IFN0cmF0ZWdpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3Rhc2stcGxhY2VtZW50LXN0cmF0ZWdpZXMuaHRtbCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gc3RyYXRlZ2llcy5cbiAgICovXG4gIHJlYWRvbmx5IHBsYWNlbWVudFN0cmF0ZWdpZXM/OiBQbGFjZW1lbnRTdHJhdGVneVtdO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgd2hldGhlciB0aGUgc2VydmljZSB3aWxsIHVzZSB0aGUgZGFlbW9uIHNjaGVkdWxpbmcgc3RyYXRlZ3kuXG4gICAqIElmIHRydWUsIHRoZSBzZXJ2aWNlIHNjaGVkdWxlciBkZXBsb3lzIGV4YWN0bHkgb25lIHRhc2sgb24gZWFjaCBjb250YWluZXIgaW5zdGFuY2UgaW4geW91ciBjbHVzdGVyLlxuICAgKlxuICAgKiBXaGVuIHlvdSBhcmUgdXNpbmcgdGhpcyBzdHJhdGVneSwgZG8gbm90IHNwZWNpZnkgYSBkZXNpcmVkIG51bWJlciBvZiB0YXNrcyBvcmFueSB0YXNrIHBsYWNlbWVudCBzdHJhdGVnaWVzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgZGFlbW9uPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBUaGUgaW50ZXJmYWNlIGZvciBhIHNlcnZpY2UgdXNpbmcgdGhlIEVDMiBsYXVuY2ggdHlwZSBvbiBhbiBFQ1MgY2x1c3Rlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJRWMyU2VydmljZSBleHRlbmRzIElTZXJ2aWNlIHtcblxufVxuXG4vKipcbiAqIFRoZSBwcm9wZXJ0aWVzIHRvIGltcG9ydCBmcm9tIHRoZSBzZXJ2aWNlIHVzaW5nIHRoZSBFQzIgbGF1bmNoIHR5cGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRWMyU2VydmljZUF0dHJpYnV0ZXMge1xuICAvKipcbiAgICogVGhlIGNsdXN0ZXIgdGhhdCBob3N0cyB0aGUgc2VydmljZS5cbiAgICovXG4gIHJlYWRvbmx5IGNsdXN0ZXI6IElDbHVzdGVyO1xuXG4gIC8qKlxuICAgKiBUaGUgc2VydmljZSBBUk4uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZWl0aGVyIHRoaXMsIG9yIHtAbGluayBzZXJ2aWNlTmFtZX0sIGlzIHJlcXVpcmVkXG4gICAqL1xuICByZWFkb25seSBzZXJ2aWNlQXJuPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgc2VydmljZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBlaXRoZXIgdGhpcywgb3Ige0BsaW5rIHNlcnZpY2VBcm59LCBpcyByZXF1aXJlZFxuICAgKi9cbiAgcmVhZG9ubHkgc2VydmljZU5hbWU/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhpcyBjcmVhdGVzIGEgc2VydmljZSB1c2luZyB0aGUgRUMyIGxhdW5jaCB0eXBlIG9uIGFuIEVDUyBjbHVzdGVyLlxuICpcbiAqIEByZXNvdXJjZSBBV1M6OkVDUzo6U2VydmljZVxuICovXG5leHBvcnQgY2xhc3MgRWMyU2VydmljZSBleHRlbmRzIEJhc2VTZXJ2aWNlIGltcGxlbWVudHMgSUVjMlNlcnZpY2Uge1xuXG4gIC8qKlxuICAgKiBJbXBvcnRzIGZyb20gdGhlIHNwZWNpZmllZCBzZXJ2aWNlIEFSTi5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbUVjMlNlcnZpY2VBcm4oc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgZWMyU2VydmljZUFybjogc3RyaW5nKTogSUVjMlNlcnZpY2Uge1xuICAgIGNsYXNzIEltcG9ydCBleHRlbmRzIFJlc291cmNlIGltcGxlbWVudHMgSUVjMlNlcnZpY2Uge1xuICAgICAgcHVibGljIHJlYWRvbmx5IHNlcnZpY2VBcm4gPSBlYzJTZXJ2aWNlQXJuO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHNlcnZpY2VOYW1lID0gU3RhY2sub2Yoc2NvcGUpLnNwbGl0QXJuKGVjMlNlcnZpY2VBcm4sIEFybkZvcm1hdC5TTEFTSF9SRVNPVVJDRV9OQU1FKS5yZXNvdXJjZU5hbWUgYXMgc3RyaW5nO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEltcG9ydChzY29wZSwgaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEltcG9ydHMgZnJvbSB0aGUgc3BlY2lmaWVkIHNlcnZpY2UgYXR0cnJpYnV0ZXMuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21FYzJTZXJ2aWNlQXR0cmlidXRlcyhzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBhdHRyczogRWMyU2VydmljZUF0dHJpYnV0ZXMpOiBJQmFzZVNlcnZpY2Uge1xuICAgIHJldHVybiBmcm9tU2VydmljZUF0cnJpYnV0ZXMoc2NvcGUsIGlkLCBhdHRycyk7XG4gIH1cblxuICBwcml2YXRlIHJlYWRvbmx5IGNvbnN0cmFpbnRzOiBDZm5TZXJ2aWNlLlBsYWNlbWVudENvbnN0cmFpbnRQcm9wZXJ0eVtdO1xuICBwcml2YXRlIHJlYWRvbmx5IHN0cmF0ZWdpZXM6IENmblNlcnZpY2UuUGxhY2VtZW50U3RyYXRlZ3lQcm9wZXJ0eVtdO1xuICBwcml2YXRlIHJlYWRvbmx5IGRhZW1vbjogYm9vbGVhbjtcblxuICAvKipcbiAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgRWMyU2VydmljZSBjbGFzcy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBFYzJTZXJ2aWNlUHJvcHMpIHtcbiAgICBpZiAocHJvcHMuZGFlbW9uICYmIHByb3BzLmRlc2lyZWRDb3VudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RhZW1vbiBtb2RlIGxhdW5jaGVzIG9uZSB0YXNrIG9uIGV2ZXJ5IGluc3RhbmNlLiBEb25cXCd0IHN1cHBseSBkZXNpcmVkQ291bnQuJyk7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmRhZW1vbiAmJiBwcm9wcy5tYXhIZWFsdGh5UGVyY2VudCAhPT0gdW5kZWZpbmVkICYmIHByb3BzLm1heEhlYWx0aHlQZXJjZW50ICE9PSAxMDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWF4aW11bSBwZXJjZW50IG11c3QgYmUgMTAwIGZvciBkYWVtb24gbW9kZS4nKTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMubWluSGVhbHRoeVBlcmNlbnQgIT09IHVuZGVmaW5lZCAmJiBwcm9wcy5tYXhIZWFsdGh5UGVyY2VudCAhPT0gdW5kZWZpbmVkICYmIHByb3BzLm1pbkhlYWx0aHlQZXJjZW50ID49IHByb3BzLm1heEhlYWx0aHlQZXJjZW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pbmltdW0gaGVhbHRoeSBwZXJjZW50IG11c3QgYmUgbGVzcyB0aGFuIG1heGltdW0gaGVhbHRoeSBwZXJjZW50LicpO1xuICAgIH1cblxuICAgIGlmICghcHJvcHMudGFza0RlZmluaXRpb24uaXNFYzJDb21wYXRpYmxlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1N1cHBsaWVkIFRhc2tEZWZpbml0aW9uIGlzIG5vdCBjb25maWd1cmVkIGZvciBjb21wYXRpYmlsaXR5IHdpdGggRUMyJyk7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLnNlY3VyaXR5R3JvdXAgIT09IHVuZGVmaW5lZCAmJiBwcm9wcy5zZWN1cml0eUdyb3VwcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ09ubHkgb25lIG9mIFNlY3VyaXR5R3JvdXAgb3IgU2VjdXJpdHlHcm91cHMgY2FuIGJlIHBvcHVsYXRlZC4nKTtcbiAgICB9XG5cbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIC4uLnByb3BzLFxuICAgICAgZGVzaXJlZENvdW50OiBwcm9wcy5kZXNpcmVkQ291bnQsXG4gICAgICBtYXhIZWFsdGh5UGVyY2VudDogcHJvcHMuZGFlbW9uICYmIHByb3BzLm1heEhlYWx0aHlQZXJjZW50ID09PSB1bmRlZmluZWQgPyAxMDAgOiBwcm9wcy5tYXhIZWFsdGh5UGVyY2VudCxcbiAgICAgIG1pbkhlYWx0aHlQZXJjZW50OiBwcm9wcy5kYWVtb24gJiYgcHJvcHMubWluSGVhbHRoeVBlcmNlbnQgPT09IHVuZGVmaW5lZCA/IDAgOiBwcm9wcy5taW5IZWFsdGh5UGVyY2VudCxcbiAgICAgIGxhdW5jaFR5cGU6IExhdW5jaFR5cGUuRUMyLFxuICAgICAgZW5hYmxlRUNTTWFuYWdlZFRhZ3M6IHByb3BzLmVuYWJsZUVDU01hbmFnZWRUYWdzLFxuICAgIH0sXG4gICAge1xuICAgICAgY2x1c3RlcjogcHJvcHMuY2x1c3Rlci5jbHVzdGVyTmFtZSxcbiAgICAgIHRhc2tEZWZpbml0aW9uOiBwcm9wcy5kZXBsb3ltZW50Q29udHJvbGxlcj8udHlwZSA9PT0gRGVwbG95bWVudENvbnRyb2xsZXJUeXBlLkVYVEVSTkFMID8gdW5kZWZpbmVkIDogcHJvcHMudGFza0RlZmluaXRpb24udGFza0RlZmluaXRpb25Bcm4sXG4gICAgICBwbGFjZW1lbnRDb25zdHJhaW50czogTGF6eS5hbnkoeyBwcm9kdWNlOiAoKSA9PiB0aGlzLmNvbnN0cmFpbnRzIH0sIHsgb21pdEVtcHR5QXJyYXk6IHRydWUgfSksXG4gICAgICBwbGFjZW1lbnRTdHJhdGVnaWVzOiBMYXp5LmFueSh7IHByb2R1Y2U6ICgpID0+IHRoaXMuc3RyYXRlZ2llcyB9LCB7IG9taXRFbXB0eUFycmF5OiB0cnVlIH0pLFxuICAgICAgc2NoZWR1bGluZ1N0cmF0ZWd5OiBwcm9wcy5kYWVtb24gPyAnREFFTU9OJyA6ICdSRVBMSUNBJyxcbiAgICB9LCBwcm9wcy50YXNrRGVmaW5pdGlvbik7XG5cbiAgICB0aGlzLmNvbnN0cmFpbnRzID0gW107XG4gICAgdGhpcy5zdHJhdGVnaWVzID0gW107XG4gICAgdGhpcy5kYWVtb24gPSBwcm9wcy5kYWVtb24gfHwgZmFsc2U7XG5cbiAgICBsZXQgc2VjdXJpdHlHcm91cHM7XG4gICAgaWYgKHByb3BzLnNlY3VyaXR5R3JvdXAgIT09IHVuZGVmaW5lZCkge1xuICAgICAgc2VjdXJpdHlHcm91cHMgPSBbcHJvcHMuc2VjdXJpdHlHcm91cF07XG4gICAgfSBlbHNlIGlmIChwcm9wcy5zZWN1cml0eUdyb3VwcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBzZWN1cml0eUdyb3VwcyA9IHByb3BzLnNlY3VyaXR5R3JvdXBzO1xuICAgIH1cblxuICAgIGlmIChwcm9wcy50YXNrRGVmaW5pdGlvbi5uZXR3b3JrTW9kZSA9PT0gTmV0d29ya01vZGUuQVdTX1ZQQykge1xuICAgICAgdGhpcy5jb25maWd1cmVBd3NWcGNOZXR3b3JraW5nV2l0aFNlY3VyaXR5R3JvdXBzKHByb3BzLmNsdXN0ZXIudnBjLCBwcm9wcy5hc3NpZ25QdWJsaWNJcCwgcHJvcHMudnBjU3VibmV0cywgc2VjdXJpdHlHcm91cHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBFaXRoZXIgTm9uZSwgQnJpZGdlIG9yIEhvc3QgbmV0d29ya2luZy4gQ29weSBTZWN1cml0eUdyb3VwcyBmcm9tIEFTRy5cbiAgICAgIC8vIFdlIGhhdmUgdG8gYmUgc21hcnQgaGVyZSAtLSBieSBkZWZhdWx0IGZ1dHVyZSBTZWN1cml0eSBHcm91cCBydWxlcyB3b3VsZCBiZSBjcmVhdGVkXG4gICAgICAvLyBpbiB0aGUgQ2x1c3RlciBzdGFjay4gSG93ZXZlciwgaWYgdGhlIENsdXN0ZXIgaXMgaW4gYSBkaWZmZXJlbnQgc3RhY2sgdGhhbiB1cyxcbiAgICAgIC8vIHRoYXQgd2lsbCBsZWFkIHRvIGEgY3ljbGljIHJlZmVyZW5jZSAod2UgcG9pbnQgdG8gdGhhdCBzdGFjayBmb3IgdGhlIGNsdXN0ZXIgbmFtZSxcbiAgICAgIC8vIGJ1dCB0aGF0IHN0YWNrIHdpbGwgcG9pbnQgdG8gdGhlIEFMQiBwcm9iYWJseSBjcmVhdGVkIHJpZ2h0IG5leHQgdG8gdXMpLlxuICAgICAgLy9cbiAgICAgIC8vIEluIHRoYXQgY2FzZSwgcmVmZXJlbmNlIHRoZSBzYW1lIHNlY3VyaXR5IGdyb3VwcyBidXQgbWFrZSBzdXJlIG5ldyBydWxlcyBhcmVcbiAgICAgIC8vIGNyZWF0ZWQgaW4gdGhlIGN1cnJlbnQgc2NvcGUgKGkuZS4sIHRoaXMgc3RhY2spXG4gICAgICB2YWxpZGF0ZU5vTmV0d29ya2luZ1Byb3BzKHByb3BzKTtcbiAgICAgIHRoaXMuY29ubmVjdGlvbnMuYWRkU2VjdXJpdHlHcm91cCguLi5zZWN1cml0eUdyb3Vwc0luVGhpc1N0YWNrKHRoaXMsIHByb3BzLmNsdXN0ZXIuY29ubmVjdGlvbnMuc2VjdXJpdHlHcm91cHMpKTtcbiAgICB9XG5cbiAgICB0aGlzLmFkZFBsYWNlbWVudENvbnN0cmFpbnRzKC4uLnByb3BzLnBsYWNlbWVudENvbnN0cmFpbnRzIHx8IFtdKTtcbiAgICB0aGlzLmFkZFBsYWNlbWVudFN0cmF0ZWdpZXMoLi4ucHJvcHMucGxhY2VtZW50U3RyYXRlZ2llcyB8fCBbXSk7XG5cbiAgICB0aGlzLm5vZGUuYWRkVmFsaWRhdGlvbih7XG4gICAgICB2YWxpZGF0ZTogKCkgPT4gIXRoaXMudGFza0RlZmluaXRpb24uZGVmYXVsdENvbnRhaW5lciA/IFsnQSBUYXNrRGVmaW5pdGlvbiBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIGVzc2VudGlhbCBjb250YWluZXInXSA6IFtdLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgb25lIG9yIG1vcmUgcGxhY2VtZW50IHN0cmF0ZWdpZXMgdG8gdXNlIGZvciB0YXNrcyBpbiB0aGUgc2VydmljZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZVxuICAgKiBbQW1hem9uIEVDUyBUYXNrIFBsYWNlbWVudCBTdHJhdGVnaWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS90YXNrLXBsYWNlbWVudC1zdHJhdGVnaWVzLmh0bWwpLlxuICAgKi9cbiAgcHVibGljIGFkZFBsYWNlbWVudFN0cmF0ZWdpZXMoLi4uc3RyYXRlZ2llczogUGxhY2VtZW50U3RyYXRlZ3lbXSkge1xuICAgIGlmIChzdHJhdGVnaWVzLmxlbmd0aCA+IDAgJiYgdGhpcy5kYWVtb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IGNvbmZpZ3VyZSBwbGFjZW1lbnQgc3RyYXRlZ2llcyB3aGVuIGRhZW1vbj10cnVlXCIpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3Qgc3RyYXRlZ3kgb2Ygc3RyYXRlZ2llcykge1xuICAgICAgdGhpcy5zdHJhdGVnaWVzLnB1c2goLi4uc3RyYXRlZ3kudG9Kc29uKCkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIG9uZSBvciBtb3JlIHBsYWNlbWVudCBjb25zdHJhaW50cyB0byB1c2UgZm9yIHRhc2tzIGluIHRoZSBzZXJ2aWNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlXG4gICAqIFtBbWF6b24gRUNTIFRhc2sgUGxhY2VtZW50IENvbnN0cmFpbnRzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS90YXNrLXBsYWNlbWVudC1jb25zdHJhaW50cy5odG1sKS5cbiAgICovXG4gIHB1YmxpYyBhZGRQbGFjZW1lbnRDb25zdHJhaW50cyguLi5jb25zdHJhaW50czogUGxhY2VtZW50Q29uc3RyYWludFtdKSB7XG4gICAgZm9yIChjb25zdCBjb25zdHJhaW50IG9mIGNvbnN0cmFpbnRzKSB7XG4gICAgICB0aGlzLmNvbnN0cmFpbnRzLnB1c2goLi4uY29uc3RyYWludC50b0pzb24oKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyB0aGlzIEVjMlNlcnZpY2UuXG4gICAqL1xuICBwcm90ZWN0ZWQgdmFsaWRhdGUoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHJldCA9IHN1cGVyLnZhbGlkYXRlKCk7XG4gICAgaWYgKCF0aGlzLmNsdXN0ZXIuaGFzRWMyQ2FwYWNpdHkpIHtcbiAgICAgIHJldC5wdXNoKCdDbHVzdGVyIGZvciB0aGlzIHNlcnZpY2UgbmVlZHMgRWMyIGNhcGFjaXR5LiBDYWxsIGFkZFh4eENhcGFjaXR5KCkgb24gdGhlIGNsdXN0ZXIuJyk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBjb21iaW5hdGlvbnMgb2YgbmV0d29ya2luZyBhcmd1bWVudHMuXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlTm9OZXR3b3JraW5nUHJvcHMocHJvcHM6IEVjMlNlcnZpY2VQcm9wcykge1xuICBpZiAocHJvcHMudnBjU3VibmV0cyAhPT0gdW5kZWZpbmVkXG4gICAgfHwgcHJvcHMuc2VjdXJpdHlHcm91cCAhPT0gdW5kZWZpbmVkXG4gICAgfHwgcHJvcHMuc2VjdXJpdHlHcm91cHMgIT09IHVuZGVmaW5lZFxuICAgIHx8IHByb3BzLmFzc2lnblB1YmxpY0lwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd2cGNTdWJuZXRzLCBzZWN1cml0eUdyb3VwKHMpIGFuZCBhc3NpZ25QdWJsaWNJcCBjYW4gb25seSBiZSB1c2VkIGluIEF3c1ZwYyBuZXR3b3JraW5nIG1vZGUnKTtcbiAgfVxufVxuXG4vKipcbiAqIEZvcmNlIHNlY3VyaXR5IGdyb3VwIHJ1bGVzIHRvIGJlIGNyZWF0ZWQgaW4gdGhpcyBzdGFjay5cbiAqXG4gKiBGb3IgZXZlcnkgc2VjdXJpdHkgZ3JvdXAsIGlmIHRoZSBzY29wZSBhbmQgdGhlIGdyb3VwIGFyZSBpbiBkaWZmZXJlbnQgc3RhY2tzLCByZXR1cm5cbiAqIGEgZmFrZSBcImltcG9ydGVkXCIgc2VjdXJpdHkgZ3JvdXAgaW5zdGVhZC4gVGhpcyB3aWxsIGJlaGF2ZSBhcyB0aGUgb3JpZ2luYWwgc2VjdXJpdHkgZ3JvdXAsXG4gKiBidXQgbmV3IEluZ3Jlc3MgYW5kIEVncmVzcyBydWxlIHJlc291cmNlcyB3aWxsIGJlIGFkZGVkIGluIHRoZSBjdXJyZW50IHN0YWNrIGluc3RlYWQgb2YgdGhlXG4gKiBvdGhlciBvbmUuXG4gKi9cbmZ1bmN0aW9uIHNlY3VyaXR5R3JvdXBzSW5UaGlzU3RhY2soc2NvcGU6IENvbnN0cnVjdCwgZ3JvdXBzOiBlYzIuSVNlY3VyaXR5R3JvdXBbXSk6IGVjMi5JU2VjdXJpdHlHcm91cFtdIHtcbiAgY29uc3QgdGhpc1N0YWNrID0gU3RhY2sub2Yoc2NvcGUpO1xuXG4gIGxldCBpID0gMTtcbiAgcmV0dXJuIGdyb3Vwcy5tYXAoZ3JvdXAgPT4ge1xuICAgIGlmICh0aGlzU3RhY2sgPT09IFN0YWNrLm9mKGdyb3VwKSkgeyByZXR1cm4gZ3JvdXA7IH0gLy8gU2ltcGxlIGNhc2UsIGp1c3QgcmV0dXJuIHRoZSBvcmlnaW5hbCBvbmVcblxuICAgIHJldHVybiBlYzIuU2VjdXJpdHlHcm91cC5mcm9tU2VjdXJpdHlHcm91cElkKHNjb3BlLCBgU2VjdXJpdHlHcm91cCR7aSsrfWAsIGdyb3VwLnNlY3VyaXR5R3JvdXBJZCwge1xuICAgICAgYWxsb3dBbGxPdXRib3VuZDogZ3JvdXAuYWxsb3dBbGxPdXRib3VuZCxcbiAgICAgIG11dGFibGU6IHRydWUsXG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIFRoZSBidWlsdC1pbiBjb250YWluZXIgaW5zdGFuY2UgYXR0cmlidXRlc1xuICovXG5leHBvcnQgY2xhc3MgQnVpbHRJbkF0dHJpYnV0ZXMge1xuICAvKipcbiAgICogVGhlIGlkIG9mIHRoZSBpbnN0YW5jZS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgSU5TVEFOQ0VfSUQgPSAnaW5zdGFuY2VJZCc7XG5cbiAgLyoqXG4gICAqIFRoZSBBdmFpbGFiaWxpdHlab25lIHdoZXJlIHRoZSBpbnN0YW5jZSBpcyBydW5uaW5nIGluLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBBVkFJTEFCSUxJVFlfWk9ORSA9ICdhdHRyaWJ1dGU6ZWNzLmF2YWlsYWJpbGl0eS16b25lJztcblxuICAvKipcbiAgICogVGhlIEFNSSBpZCB0aGUgaW5zdGFuY2UgaXMgdXNpbmcuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IEFNSV9JRCA9ICdhdHRyaWJ1dGU6ZWNzLmFtaS1pZCc7XG5cbiAgLyoqXG4gICAqIFRoZSBFQzIgaW5zdGFuY2UgdHlwZS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgSU5TVEFOQ0VfVFlQRSA9ICdhdHRyaWJ1dGU6ZWNzLmluc3RhbmNlLXR5cGUnO1xuXG4gIC8qKlxuICAgKiBUaGUgb3BlcmF0aW5nIHN5c3RlbSBvZiB0aGUgaW5zdGFuY2UuXG4gICAqXG4gICAqIEVpdGhlciAnbGludXgnIG9yICd3aW5kb3dzJy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgT1NfVFlQRSA9ICdhdHRyaWJ1dGU6ZWNzLm9zLXR5cGUnO1xufVxuIl19 |
\ | No newline at end of file |