UNPKG

1.27 MBJavaScriptView Raw
1"use strict";
2var _a, _b, _c, _d, _e, _f, _g;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.CfnTaskSet = exports.CfnTaskDefinition = exports.CfnService = exports.CfnPrimaryTaskSet = exports.CfnClusterCapacityProviderAssociations = exports.CfnCluster = exports.CfnCapacityProvider = void 0;
5const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
6const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
7// Copyright 2012-2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
8// Generated from the AWS CloudFormation Resource Specification
9// See: docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html
10// @cfn2ts:meta@ {"generated":"2023-06-19T15:21:32.416Z","fingerprint":"xTJPmCaq2v7nK3mRM5KxvnfckBQA0TXjUqjQy38bw/4="}
11/* eslint-disable max-len */ // This is generated code - line lengths are difficult to control
12const cdk = require("@aws-cdk/core");
13const cfn_parse = require("@aws-cdk/core/lib/helpers-internal");
14/**
15 * Determine whether the given properties match those of a `CfnCapacityProviderProps`
16 *
17 * @param properties - the TypeScript properties of a `CfnCapacityProviderProps`
18 *
19 * @returns the result of the validation.
20 */
21function CfnCapacityProviderPropsValidator(properties) {
22 if (!cdk.canInspect(properties)) {
23 return cdk.VALIDATION_SUCCESS;
24 }
25 const errors = new cdk.ValidationResults();
26 if (typeof properties !== 'object') {
27 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
28 }
29 errors.collect(cdk.propertyValidator('autoScalingGroupProvider', cdk.requiredValidator)(properties.autoScalingGroupProvider));
30 errors.collect(cdk.propertyValidator('autoScalingGroupProvider', CfnCapacityProvider_AutoScalingGroupProviderPropertyValidator)(properties.autoScalingGroupProvider));
31 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
32 errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
33 return errors.wrap('supplied properties not correct for "CfnCapacityProviderProps"');
34}
35/**
36 * Renders the AWS CloudFormation properties of an `AWS::ECS::CapacityProvider` resource
37 *
38 * @param properties - the TypeScript properties of a `CfnCapacityProviderProps`
39 *
40 * @returns the AWS CloudFormation properties of an `AWS::ECS::CapacityProvider` resource.
41 */
42// @ts-ignore TS6133
43function cfnCapacityProviderPropsToCloudFormation(properties) {
44 if (!cdk.canInspect(properties)) {
45 return properties;
46 }
47 CfnCapacityProviderPropsValidator(properties).assertSuccess();
48 return {
49 AutoScalingGroupProvider: cfnCapacityProviderAutoScalingGroupProviderPropertyToCloudFormation(properties.autoScalingGroupProvider),
50 Name: cdk.stringToCloudFormation(properties.name),
51 Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
52 };
53}
54// @ts-ignore TS6133
55function CfnCapacityProviderPropsFromCloudFormation(properties) {
56 properties = properties == null ? {} : properties;
57 if (typeof properties !== 'object') {
58 return new cfn_parse.FromCloudFormationResult(properties);
59 }
60 const ret = new cfn_parse.FromCloudFormationPropertyObject();
61 ret.addPropertyResult('autoScalingGroupProvider', 'AutoScalingGroupProvider', CfnCapacityProviderAutoScalingGroupProviderPropertyFromCloudFormation(properties.AutoScalingGroupProvider));
62 ret.addPropertyResult('name', 'Name', properties.Name != null ? cfn_parse.FromCloudFormation.getString(properties.Name) : undefined);
63 ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
64 ret.addUnrecognizedPropertiesAsExtra(properties);
65 return ret;
66}
67/**
68 * A CloudFormation `AWS::ECS::CapacityProvider`
69 *
70 * Creates a new capacity provider. Capacity providers are associated with an Amazon ECS cluster and are used in capacity provider strategies to facilitate cluster auto scaling.
71 *
72 * Only capacity providers that use an Auto Scaling group can be created. Amazon ECS tasks on AWS Fargate use the `FARGATE` and `FARGATE_SPOT` capacity providers. These providers are available to all accounts in the AWS Regions that AWS Fargate supports.
73 *
74 * @cloudformationResource AWS::ECS::CapacityProvider
75 * @stability external
76 *
77 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-capacityprovider.html
78 */
79class CfnCapacityProvider extends cdk.CfnResource {
80 /**
81 * Create a new `AWS::ECS::CapacityProvider`.
82 *
83 * @param scope - scope in which this resource is defined
84 * @param id - scoped id of the resource
85 * @param props - resource properties
86 */
87 constructor(scope, id, props) {
88 super(scope, id, { type: CfnCapacityProvider.CFN_RESOURCE_TYPE_NAME, properties: props });
89 try {
90 jsiiDeprecationWarnings._aws_cdk_aws_ecs_CfnCapacityProviderProps(props);
91 }
92 catch (error) {
93 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
94 Error.captureStackTrace(error, CfnCapacityProvider);
95 }
96 throw error;
97 }
98 cdk.requireProperty(props, 'autoScalingGroupProvider', this);
99 this.autoScalingGroupProvider = props.autoScalingGroupProvider;
100 this.name = props.name;
101 this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::ECS::CapacityProvider", props.tags, { tagPropertyName: 'tags' });
102 }
103 /**
104 * A factory method that creates a new instance of this class from an object
105 * containing the CloudFormation properties of this resource.
106 * Used in the @aws-cdk/cloudformation-include module.
107 *
108 * @internal
109 */
110 static _fromCloudFormation(scope, id, resourceAttributes, options) {
111 resourceAttributes = resourceAttributes || {};
112 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
113 const propsResult = CfnCapacityProviderPropsFromCloudFormation(resourceProperties);
114 const ret = new CfnCapacityProvider(scope, id, propsResult.value);
115 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
116 ret.addPropertyOverride(propKey, propVal);
117 }
118 options.parser.handleAttributes(ret, resourceAttributes, id);
119 return ret;
120 }
121 /**
122 * Examines the CloudFormation resource and discloses attributes.
123 *
124 * @param inspector - tree inspector to collect and process attributes
125 *
126 */
127 inspect(inspector) {
128 inspector.addAttribute("aws:cdk:cloudformation:type", CfnCapacityProvider.CFN_RESOURCE_TYPE_NAME);
129 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
130 }
131 get cfnProperties() {
132 return {
133 autoScalingGroupProvider: this.autoScalingGroupProvider,
134 name: this.name,
135 tags: this.tags.renderTags(),
136 };
137 }
138 renderProperties(props) {
139 return cfnCapacityProviderPropsToCloudFormation(props);
140 }
141}
142exports.CfnCapacityProvider = CfnCapacityProvider;
143_a = JSII_RTTI_SYMBOL_1;
144CfnCapacityProvider[_a] = { fqn: "@aws-cdk/aws-ecs.CfnCapacityProvider", version: "1.204.0" };
145/**
146 * The CloudFormation resource type name for this resource class.
147 */
148CfnCapacityProvider.CFN_RESOURCE_TYPE_NAME = "AWS::ECS::CapacityProvider";
149/**
150 * Determine whether the given properties match those of a `AutoScalingGroupProviderProperty`
151 *
152 * @param properties - the TypeScript properties of a `AutoScalingGroupProviderProperty`
153 *
154 * @returns the result of the validation.
155 */
156function CfnCapacityProvider_AutoScalingGroupProviderPropertyValidator(properties) {
157 if (!cdk.canInspect(properties)) {
158 return cdk.VALIDATION_SUCCESS;
159 }
160 const errors = new cdk.ValidationResults();
161 if (typeof properties !== 'object') {
162 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
163 }
164 errors.collect(cdk.propertyValidator('autoScalingGroupArn', cdk.requiredValidator)(properties.autoScalingGroupArn));
165 errors.collect(cdk.propertyValidator('autoScalingGroupArn', cdk.validateString)(properties.autoScalingGroupArn));
166 errors.collect(cdk.propertyValidator('managedScaling', CfnCapacityProvider_ManagedScalingPropertyValidator)(properties.managedScaling));
167 errors.collect(cdk.propertyValidator('managedTerminationProtection', cdk.validateString)(properties.managedTerminationProtection));
168 return errors.wrap('supplied properties not correct for "AutoScalingGroupProviderProperty"');
169}
170/**
171 * Renders the AWS CloudFormation properties of an `AWS::ECS::CapacityProvider.AutoScalingGroupProvider` resource
172 *
173 * @param properties - the TypeScript properties of a `AutoScalingGroupProviderProperty`
174 *
175 * @returns the AWS CloudFormation properties of an `AWS::ECS::CapacityProvider.AutoScalingGroupProvider` resource.
176 */
177// @ts-ignore TS6133
178function cfnCapacityProviderAutoScalingGroupProviderPropertyToCloudFormation(properties) {
179 if (!cdk.canInspect(properties)) {
180 return properties;
181 }
182 CfnCapacityProvider_AutoScalingGroupProviderPropertyValidator(properties).assertSuccess();
183 return {
184 AutoScalingGroupArn: cdk.stringToCloudFormation(properties.autoScalingGroupArn),
185 ManagedScaling: cfnCapacityProviderManagedScalingPropertyToCloudFormation(properties.managedScaling),
186 ManagedTerminationProtection: cdk.stringToCloudFormation(properties.managedTerminationProtection),
187 };
188}
189// @ts-ignore TS6133
190function CfnCapacityProviderAutoScalingGroupProviderPropertyFromCloudFormation(properties) {
191 if (cdk.isResolvableObject(properties)) {
192 return new cfn_parse.FromCloudFormationResult(properties);
193 }
194 properties = properties == null ? {} : properties;
195 if (typeof properties !== 'object') {
196 return new cfn_parse.FromCloudFormationResult(properties);
197 }
198 const ret = new cfn_parse.FromCloudFormationPropertyObject();
199 ret.addPropertyResult('autoScalingGroupArn', 'AutoScalingGroupArn', cfn_parse.FromCloudFormation.getString(properties.AutoScalingGroupArn));
200 ret.addPropertyResult('managedScaling', 'ManagedScaling', properties.ManagedScaling != null ? CfnCapacityProviderManagedScalingPropertyFromCloudFormation(properties.ManagedScaling) : undefined);
201 ret.addPropertyResult('managedTerminationProtection', 'ManagedTerminationProtection', properties.ManagedTerminationProtection != null ? cfn_parse.FromCloudFormation.getString(properties.ManagedTerminationProtection) : undefined);
202 ret.addUnrecognizedPropertiesAsExtra(properties);
203 return ret;
204}
205/**
206 * Determine whether the given properties match those of a `ManagedScalingProperty`
207 *
208 * @param properties - the TypeScript properties of a `ManagedScalingProperty`
209 *
210 * @returns the result of the validation.
211 */
212function CfnCapacityProvider_ManagedScalingPropertyValidator(properties) {
213 if (!cdk.canInspect(properties)) {
214 return cdk.VALIDATION_SUCCESS;
215 }
216 const errors = new cdk.ValidationResults();
217 if (typeof properties !== 'object') {
218 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
219 }
220 errors.collect(cdk.propertyValidator('instanceWarmupPeriod', cdk.validateNumber)(properties.instanceWarmupPeriod));
221 errors.collect(cdk.propertyValidator('maximumScalingStepSize', cdk.validateNumber)(properties.maximumScalingStepSize));
222 errors.collect(cdk.propertyValidator('minimumScalingStepSize', cdk.validateNumber)(properties.minimumScalingStepSize));
223 errors.collect(cdk.propertyValidator('status', cdk.validateString)(properties.status));
224 errors.collect(cdk.propertyValidator('targetCapacity', cdk.validateNumber)(properties.targetCapacity));
225 return errors.wrap('supplied properties not correct for "ManagedScalingProperty"');
226}
227/**
228 * Renders the AWS CloudFormation properties of an `AWS::ECS::CapacityProvider.ManagedScaling` resource
229 *
230 * @param properties - the TypeScript properties of a `ManagedScalingProperty`
231 *
232 * @returns the AWS CloudFormation properties of an `AWS::ECS::CapacityProvider.ManagedScaling` resource.
233 */
234// @ts-ignore TS6133
235function cfnCapacityProviderManagedScalingPropertyToCloudFormation(properties) {
236 if (!cdk.canInspect(properties)) {
237 return properties;
238 }
239 CfnCapacityProvider_ManagedScalingPropertyValidator(properties).assertSuccess();
240 return {
241 InstanceWarmupPeriod: cdk.numberToCloudFormation(properties.instanceWarmupPeriod),
242 MaximumScalingStepSize: cdk.numberToCloudFormation(properties.maximumScalingStepSize),
243 MinimumScalingStepSize: cdk.numberToCloudFormation(properties.minimumScalingStepSize),
244 Status: cdk.stringToCloudFormation(properties.status),
245 TargetCapacity: cdk.numberToCloudFormation(properties.targetCapacity),
246 };
247}
248// @ts-ignore TS6133
249function CfnCapacityProviderManagedScalingPropertyFromCloudFormation(properties) {
250 if (cdk.isResolvableObject(properties)) {
251 return new cfn_parse.FromCloudFormationResult(properties);
252 }
253 properties = properties == null ? {} : properties;
254 if (typeof properties !== 'object') {
255 return new cfn_parse.FromCloudFormationResult(properties);
256 }
257 const ret = new cfn_parse.FromCloudFormationPropertyObject();
258 ret.addPropertyResult('instanceWarmupPeriod', 'InstanceWarmupPeriod', properties.InstanceWarmupPeriod != null ? cfn_parse.FromCloudFormation.getNumber(properties.InstanceWarmupPeriod) : undefined);
259 ret.addPropertyResult('maximumScalingStepSize', 'MaximumScalingStepSize', properties.MaximumScalingStepSize != null ? cfn_parse.FromCloudFormation.getNumber(properties.MaximumScalingStepSize) : undefined);
260 ret.addPropertyResult('minimumScalingStepSize', 'MinimumScalingStepSize', properties.MinimumScalingStepSize != null ? cfn_parse.FromCloudFormation.getNumber(properties.MinimumScalingStepSize) : undefined);
261 ret.addPropertyResult('status', 'Status', properties.Status != null ? cfn_parse.FromCloudFormation.getString(properties.Status) : undefined);
262 ret.addPropertyResult('targetCapacity', 'TargetCapacity', properties.TargetCapacity != null ? cfn_parse.FromCloudFormation.getNumber(properties.TargetCapacity) : undefined);
263 ret.addUnrecognizedPropertiesAsExtra(properties);
264 return ret;
265}
266/**
267 * Determine whether the given properties match those of a `CfnClusterProps`
268 *
269 * @param properties - the TypeScript properties of a `CfnClusterProps`
270 *
271 * @returns the result of the validation.
272 */
273function CfnClusterPropsValidator(properties) {
274 if (!cdk.canInspect(properties)) {
275 return cdk.VALIDATION_SUCCESS;
276 }
277 const errors = new cdk.ValidationResults();
278 if (typeof properties !== 'object') {
279 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
280 }
281 errors.collect(cdk.propertyValidator('capacityProviders', cdk.listValidator(cdk.validateString))(properties.capacityProviders));
282 errors.collect(cdk.propertyValidator('clusterName', cdk.validateString)(properties.clusterName));
283 errors.collect(cdk.propertyValidator('clusterSettings', cdk.listValidator(CfnCluster_ClusterSettingsPropertyValidator))(properties.clusterSettings));
284 errors.collect(cdk.propertyValidator('configuration', CfnCluster_ClusterConfigurationPropertyValidator)(properties.configuration));
285 errors.collect(cdk.propertyValidator('defaultCapacityProviderStrategy', cdk.listValidator(CfnCluster_CapacityProviderStrategyItemPropertyValidator))(properties.defaultCapacityProviderStrategy));
286 errors.collect(cdk.propertyValidator('serviceConnectDefaults', CfnCluster_ServiceConnectDefaultsPropertyValidator)(properties.serviceConnectDefaults));
287 errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
288 return errors.wrap('supplied properties not correct for "CfnClusterProps"');
289}
290/**
291 * Renders the AWS CloudFormation properties of an `AWS::ECS::Cluster` resource
292 *
293 * @param properties - the TypeScript properties of a `CfnClusterProps`
294 *
295 * @returns the AWS CloudFormation properties of an `AWS::ECS::Cluster` resource.
296 */
297// @ts-ignore TS6133
298function cfnClusterPropsToCloudFormation(properties) {
299 if (!cdk.canInspect(properties)) {
300 return properties;
301 }
302 CfnClusterPropsValidator(properties).assertSuccess();
303 return {
304 CapacityProviders: cdk.listMapper(cdk.stringToCloudFormation)(properties.capacityProviders),
305 ClusterName: cdk.stringToCloudFormation(properties.clusterName),
306 ClusterSettings: cdk.listMapper(cfnClusterClusterSettingsPropertyToCloudFormation)(properties.clusterSettings),
307 Configuration: cfnClusterClusterConfigurationPropertyToCloudFormation(properties.configuration),
308 DefaultCapacityProviderStrategy: cdk.listMapper(cfnClusterCapacityProviderStrategyItemPropertyToCloudFormation)(properties.defaultCapacityProviderStrategy),
309 ServiceConnectDefaults: cfnClusterServiceConnectDefaultsPropertyToCloudFormation(properties.serviceConnectDefaults),
310 Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
311 };
312}
313// @ts-ignore TS6133
314function CfnClusterPropsFromCloudFormation(properties) {
315 properties = properties == null ? {} : properties;
316 if (typeof properties !== 'object') {
317 return new cfn_parse.FromCloudFormationResult(properties);
318 }
319 const ret = new cfn_parse.FromCloudFormationPropertyObject();
320 ret.addPropertyResult('capacityProviders', 'CapacityProviders', properties.CapacityProviders != null ? cfn_parse.FromCloudFormation.getStringArray(properties.CapacityProviders) : undefined);
321 ret.addPropertyResult('clusterName', 'ClusterName', properties.ClusterName != null ? cfn_parse.FromCloudFormation.getString(properties.ClusterName) : undefined);
322 ret.addPropertyResult('clusterSettings', 'ClusterSettings', properties.ClusterSettings != null ? cfn_parse.FromCloudFormation.getArray(CfnClusterClusterSettingsPropertyFromCloudFormation)(properties.ClusterSettings) : undefined);
323 ret.addPropertyResult('configuration', 'Configuration', properties.Configuration != null ? CfnClusterClusterConfigurationPropertyFromCloudFormation(properties.Configuration) : undefined);
324 ret.addPropertyResult('defaultCapacityProviderStrategy', 'DefaultCapacityProviderStrategy', properties.DefaultCapacityProviderStrategy != null ? cfn_parse.FromCloudFormation.getArray(CfnClusterCapacityProviderStrategyItemPropertyFromCloudFormation)(properties.DefaultCapacityProviderStrategy) : undefined);
325 ret.addPropertyResult('serviceConnectDefaults', 'ServiceConnectDefaults', properties.ServiceConnectDefaults != null ? CfnClusterServiceConnectDefaultsPropertyFromCloudFormation(properties.ServiceConnectDefaults) : undefined);
326 ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
327 ret.addUnrecognizedPropertiesAsExtra(properties);
328 return ret;
329}
330/**
331 * A CloudFormation `AWS::ECS::Cluster`
332 *
333 * The `AWS::ECS::Cluster` resource creates an Amazon Elastic Container Service (Amazon ECS) cluster.
334 *
335 * @cloudformationResource AWS::ECS::Cluster
336 * @stability external
337 *
338 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-cluster.html
339 */
340class CfnCluster extends cdk.CfnResource {
341 /**
342 * Create a new `AWS::ECS::Cluster`.
343 *
344 * @param scope - scope in which this resource is defined
345 * @param id - scoped id of the resource
346 * @param props - resource properties
347 */
348 constructor(scope, id, props = {}) {
349 super(scope, id, { type: CfnCluster.CFN_RESOURCE_TYPE_NAME, properties: props });
350 try {
351 jsiiDeprecationWarnings._aws_cdk_aws_ecs_CfnClusterProps(props);
352 }
353 catch (error) {
354 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
355 Error.captureStackTrace(error, CfnCluster);
356 }
357 throw error;
358 }
359 this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
360 this.capacityProviders = props.capacityProviders;
361 this.clusterName = props.clusterName;
362 this.clusterSettings = props.clusterSettings;
363 this.configuration = props.configuration;
364 this.defaultCapacityProviderStrategy = props.defaultCapacityProviderStrategy;
365 this.serviceConnectDefaults = props.serviceConnectDefaults;
366 this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::ECS::Cluster", props.tags, { tagPropertyName: 'tags' });
367 }
368 /**
369 * A factory method that creates a new instance of this class from an object
370 * containing the CloudFormation properties of this resource.
371 * Used in the @aws-cdk/cloudformation-include module.
372 *
373 * @internal
374 */
375 static _fromCloudFormation(scope, id, resourceAttributes, options) {
376 resourceAttributes = resourceAttributes || {};
377 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
378 const propsResult = CfnClusterPropsFromCloudFormation(resourceProperties);
379 const ret = new CfnCluster(scope, id, propsResult.value);
380 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
381 ret.addPropertyOverride(propKey, propVal);
382 }
383 options.parser.handleAttributes(ret, resourceAttributes, id);
384 return ret;
385 }
386 /**
387 * Examines the CloudFormation resource and discloses attributes.
388 *
389 * @param inspector - tree inspector to collect and process attributes
390 *
391 */
392 inspect(inspector) {
393 inspector.addAttribute("aws:cdk:cloudformation:type", CfnCluster.CFN_RESOURCE_TYPE_NAME);
394 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
395 }
396 get cfnProperties() {
397 return {
398 capacityProviders: this.capacityProviders,
399 clusterName: this.clusterName,
400 clusterSettings: this.clusterSettings,
401 configuration: this.configuration,
402 defaultCapacityProviderStrategy: this.defaultCapacityProviderStrategy,
403 serviceConnectDefaults: this.serviceConnectDefaults,
404 tags: this.tags.renderTags(),
405 };
406 }
407 renderProperties(props) {
408 return cfnClusterPropsToCloudFormation(props);
409 }
410}
411exports.CfnCluster = CfnCluster;
412_b = JSII_RTTI_SYMBOL_1;
413CfnCluster[_b] = { fqn: "@aws-cdk/aws-ecs.CfnCluster", version: "1.204.0" };
414/**
415 * The CloudFormation resource type name for this resource class.
416 */
417CfnCluster.CFN_RESOURCE_TYPE_NAME = "AWS::ECS::Cluster";
418/**
419 * Determine whether the given properties match those of a `CapacityProviderStrategyItemProperty`
420 *
421 * @param properties - the TypeScript properties of a `CapacityProviderStrategyItemProperty`
422 *
423 * @returns the result of the validation.
424 */
425function CfnCluster_CapacityProviderStrategyItemPropertyValidator(properties) {
426 if (!cdk.canInspect(properties)) {
427 return cdk.VALIDATION_SUCCESS;
428 }
429 const errors = new cdk.ValidationResults();
430 if (typeof properties !== 'object') {
431 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
432 }
433 errors.collect(cdk.propertyValidator('base', cdk.validateNumber)(properties.base));
434 errors.collect(cdk.propertyValidator('capacityProvider', cdk.validateString)(properties.capacityProvider));
435 errors.collect(cdk.propertyValidator('weight', cdk.validateNumber)(properties.weight));
436 return errors.wrap('supplied properties not correct for "CapacityProviderStrategyItemProperty"');
437}
438/**
439 * Renders the AWS CloudFormation properties of an `AWS::ECS::Cluster.CapacityProviderStrategyItem` resource
440 *
441 * @param properties - the TypeScript properties of a `CapacityProviderStrategyItemProperty`
442 *
443 * @returns the AWS CloudFormation properties of an `AWS::ECS::Cluster.CapacityProviderStrategyItem` resource.
444 */
445// @ts-ignore TS6133
446function cfnClusterCapacityProviderStrategyItemPropertyToCloudFormation(properties) {
447 if (!cdk.canInspect(properties)) {
448 return properties;
449 }
450 CfnCluster_CapacityProviderStrategyItemPropertyValidator(properties).assertSuccess();
451 return {
452 Base: cdk.numberToCloudFormation(properties.base),
453 CapacityProvider: cdk.stringToCloudFormation(properties.capacityProvider),
454 Weight: cdk.numberToCloudFormation(properties.weight),
455 };
456}
457// @ts-ignore TS6133
458function CfnClusterCapacityProviderStrategyItemPropertyFromCloudFormation(properties) {
459 if (cdk.isResolvableObject(properties)) {
460 return new cfn_parse.FromCloudFormationResult(properties);
461 }
462 properties = properties == null ? {} : properties;
463 if (typeof properties !== 'object') {
464 return new cfn_parse.FromCloudFormationResult(properties);
465 }
466 const ret = new cfn_parse.FromCloudFormationPropertyObject();
467 ret.addPropertyResult('base', 'Base', properties.Base != null ? cfn_parse.FromCloudFormation.getNumber(properties.Base) : undefined);
468 ret.addPropertyResult('capacityProvider', 'CapacityProvider', properties.CapacityProvider != null ? cfn_parse.FromCloudFormation.getString(properties.CapacityProvider) : undefined);
469 ret.addPropertyResult('weight', 'Weight', properties.Weight != null ? cfn_parse.FromCloudFormation.getNumber(properties.Weight) : undefined);
470 ret.addUnrecognizedPropertiesAsExtra(properties);
471 return ret;
472}
473/**
474 * Determine whether the given properties match those of a `ClusterConfigurationProperty`
475 *
476 * @param properties - the TypeScript properties of a `ClusterConfigurationProperty`
477 *
478 * @returns the result of the validation.
479 */
480function CfnCluster_ClusterConfigurationPropertyValidator(properties) {
481 if (!cdk.canInspect(properties)) {
482 return cdk.VALIDATION_SUCCESS;
483 }
484 const errors = new cdk.ValidationResults();
485 if (typeof properties !== 'object') {
486 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
487 }
488 errors.collect(cdk.propertyValidator('executeCommandConfiguration', CfnCluster_ExecuteCommandConfigurationPropertyValidator)(properties.executeCommandConfiguration));
489 return errors.wrap('supplied properties not correct for "ClusterConfigurationProperty"');
490}
491/**
492 * Renders the AWS CloudFormation properties of an `AWS::ECS::Cluster.ClusterConfiguration` resource
493 *
494 * @param properties - the TypeScript properties of a `ClusterConfigurationProperty`
495 *
496 * @returns the AWS CloudFormation properties of an `AWS::ECS::Cluster.ClusterConfiguration` resource.
497 */
498// @ts-ignore TS6133
499function cfnClusterClusterConfigurationPropertyToCloudFormation(properties) {
500 if (!cdk.canInspect(properties)) {
501 return properties;
502 }
503 CfnCluster_ClusterConfigurationPropertyValidator(properties).assertSuccess();
504 return {
505 ExecuteCommandConfiguration: cfnClusterExecuteCommandConfigurationPropertyToCloudFormation(properties.executeCommandConfiguration),
506 };
507}
508// @ts-ignore TS6133
509function CfnClusterClusterConfigurationPropertyFromCloudFormation(properties) {
510 if (cdk.isResolvableObject(properties)) {
511 return new cfn_parse.FromCloudFormationResult(properties);
512 }
513 properties = properties == null ? {} : properties;
514 if (typeof properties !== 'object') {
515 return new cfn_parse.FromCloudFormationResult(properties);
516 }
517 const ret = new cfn_parse.FromCloudFormationPropertyObject();
518 ret.addPropertyResult('executeCommandConfiguration', 'ExecuteCommandConfiguration', properties.ExecuteCommandConfiguration != null ? CfnClusterExecuteCommandConfigurationPropertyFromCloudFormation(properties.ExecuteCommandConfiguration) : undefined);
519 ret.addUnrecognizedPropertiesAsExtra(properties);
520 return ret;
521}
522/**
523 * Determine whether the given properties match those of a `ClusterSettingsProperty`
524 *
525 * @param properties - the TypeScript properties of a `ClusterSettingsProperty`
526 *
527 * @returns the result of the validation.
528 */
529function CfnCluster_ClusterSettingsPropertyValidator(properties) {
530 if (!cdk.canInspect(properties)) {
531 return cdk.VALIDATION_SUCCESS;
532 }
533 const errors = new cdk.ValidationResults();
534 if (typeof properties !== 'object') {
535 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
536 }
537 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
538 errors.collect(cdk.propertyValidator('value', cdk.validateString)(properties.value));
539 return errors.wrap('supplied properties not correct for "ClusterSettingsProperty"');
540}
541/**
542 * Renders the AWS CloudFormation properties of an `AWS::ECS::Cluster.ClusterSettings` resource
543 *
544 * @param properties - the TypeScript properties of a `ClusterSettingsProperty`
545 *
546 * @returns the AWS CloudFormation properties of an `AWS::ECS::Cluster.ClusterSettings` resource.
547 */
548// @ts-ignore TS6133
549function cfnClusterClusterSettingsPropertyToCloudFormation(properties) {
550 if (!cdk.canInspect(properties)) {
551 return properties;
552 }
553 CfnCluster_ClusterSettingsPropertyValidator(properties).assertSuccess();
554 return {
555 Name: cdk.stringToCloudFormation(properties.name),
556 Value: cdk.stringToCloudFormation(properties.value),
557 };
558}
559// @ts-ignore TS6133
560function CfnClusterClusterSettingsPropertyFromCloudFormation(properties) {
561 if (cdk.isResolvableObject(properties)) {
562 return new cfn_parse.FromCloudFormationResult(properties);
563 }
564 properties = properties == null ? {} : properties;
565 if (typeof properties !== 'object') {
566 return new cfn_parse.FromCloudFormationResult(properties);
567 }
568 const ret = new cfn_parse.FromCloudFormationPropertyObject();
569 ret.addPropertyResult('name', 'Name', properties.Name != null ? cfn_parse.FromCloudFormation.getString(properties.Name) : undefined);
570 ret.addPropertyResult('value', 'Value', properties.Value != null ? cfn_parse.FromCloudFormation.getString(properties.Value) : undefined);
571 ret.addUnrecognizedPropertiesAsExtra(properties);
572 return ret;
573}
574/**
575 * Determine whether the given properties match those of a `ExecuteCommandConfigurationProperty`
576 *
577 * @param properties - the TypeScript properties of a `ExecuteCommandConfigurationProperty`
578 *
579 * @returns the result of the validation.
580 */
581function CfnCluster_ExecuteCommandConfigurationPropertyValidator(properties) {
582 if (!cdk.canInspect(properties)) {
583 return cdk.VALIDATION_SUCCESS;
584 }
585 const errors = new cdk.ValidationResults();
586 if (typeof properties !== 'object') {
587 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
588 }
589 errors.collect(cdk.propertyValidator('kmsKeyId', cdk.validateString)(properties.kmsKeyId));
590 errors.collect(cdk.propertyValidator('logConfiguration', CfnCluster_ExecuteCommandLogConfigurationPropertyValidator)(properties.logConfiguration));
591 errors.collect(cdk.propertyValidator('logging', cdk.validateString)(properties.logging));
592 return errors.wrap('supplied properties not correct for "ExecuteCommandConfigurationProperty"');
593}
594/**
595 * Renders the AWS CloudFormation properties of an `AWS::ECS::Cluster.ExecuteCommandConfiguration` resource
596 *
597 * @param properties - the TypeScript properties of a `ExecuteCommandConfigurationProperty`
598 *
599 * @returns the AWS CloudFormation properties of an `AWS::ECS::Cluster.ExecuteCommandConfiguration` resource.
600 */
601// @ts-ignore TS6133
602function cfnClusterExecuteCommandConfigurationPropertyToCloudFormation(properties) {
603 if (!cdk.canInspect(properties)) {
604 return properties;
605 }
606 CfnCluster_ExecuteCommandConfigurationPropertyValidator(properties).assertSuccess();
607 return {
608 KmsKeyId: cdk.stringToCloudFormation(properties.kmsKeyId),
609 LogConfiguration: cfnClusterExecuteCommandLogConfigurationPropertyToCloudFormation(properties.logConfiguration),
610 Logging: cdk.stringToCloudFormation(properties.logging),
611 };
612}
613// @ts-ignore TS6133
614function CfnClusterExecuteCommandConfigurationPropertyFromCloudFormation(properties) {
615 if (cdk.isResolvableObject(properties)) {
616 return new cfn_parse.FromCloudFormationResult(properties);
617 }
618 properties = properties == null ? {} : properties;
619 if (typeof properties !== 'object') {
620 return new cfn_parse.FromCloudFormationResult(properties);
621 }
622 const ret = new cfn_parse.FromCloudFormationPropertyObject();
623 ret.addPropertyResult('kmsKeyId', 'KmsKeyId', properties.KmsKeyId != null ? cfn_parse.FromCloudFormation.getString(properties.KmsKeyId) : undefined);
624 ret.addPropertyResult('logConfiguration', 'LogConfiguration', properties.LogConfiguration != null ? CfnClusterExecuteCommandLogConfigurationPropertyFromCloudFormation(properties.LogConfiguration) : undefined);
625 ret.addPropertyResult('logging', 'Logging', properties.Logging != null ? cfn_parse.FromCloudFormation.getString(properties.Logging) : undefined);
626 ret.addUnrecognizedPropertiesAsExtra(properties);
627 return ret;
628}
629/**
630 * Determine whether the given properties match those of a `ExecuteCommandLogConfigurationProperty`
631 *
632 * @param properties - the TypeScript properties of a `ExecuteCommandLogConfigurationProperty`
633 *
634 * @returns the result of the validation.
635 */
636function CfnCluster_ExecuteCommandLogConfigurationPropertyValidator(properties) {
637 if (!cdk.canInspect(properties)) {
638 return cdk.VALIDATION_SUCCESS;
639 }
640 const errors = new cdk.ValidationResults();
641 if (typeof properties !== 'object') {
642 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
643 }
644 errors.collect(cdk.propertyValidator('cloudWatchEncryptionEnabled', cdk.validateBoolean)(properties.cloudWatchEncryptionEnabled));
645 errors.collect(cdk.propertyValidator('cloudWatchLogGroupName', cdk.validateString)(properties.cloudWatchLogGroupName));
646 errors.collect(cdk.propertyValidator('s3BucketName', cdk.validateString)(properties.s3BucketName));
647 errors.collect(cdk.propertyValidator('s3EncryptionEnabled', cdk.validateBoolean)(properties.s3EncryptionEnabled));
648 errors.collect(cdk.propertyValidator('s3KeyPrefix', cdk.validateString)(properties.s3KeyPrefix));
649 return errors.wrap('supplied properties not correct for "ExecuteCommandLogConfigurationProperty"');
650}
651/**
652 * Renders the AWS CloudFormation properties of an `AWS::ECS::Cluster.ExecuteCommandLogConfiguration` resource
653 *
654 * @param properties - the TypeScript properties of a `ExecuteCommandLogConfigurationProperty`
655 *
656 * @returns the AWS CloudFormation properties of an `AWS::ECS::Cluster.ExecuteCommandLogConfiguration` resource.
657 */
658// @ts-ignore TS6133
659function cfnClusterExecuteCommandLogConfigurationPropertyToCloudFormation(properties) {
660 if (!cdk.canInspect(properties)) {
661 return properties;
662 }
663 CfnCluster_ExecuteCommandLogConfigurationPropertyValidator(properties).assertSuccess();
664 return {
665 CloudWatchEncryptionEnabled: cdk.booleanToCloudFormation(properties.cloudWatchEncryptionEnabled),
666 CloudWatchLogGroupName: cdk.stringToCloudFormation(properties.cloudWatchLogGroupName),
667 S3BucketName: cdk.stringToCloudFormation(properties.s3BucketName),
668 S3EncryptionEnabled: cdk.booleanToCloudFormation(properties.s3EncryptionEnabled),
669 S3KeyPrefix: cdk.stringToCloudFormation(properties.s3KeyPrefix),
670 };
671}
672// @ts-ignore TS6133
673function CfnClusterExecuteCommandLogConfigurationPropertyFromCloudFormation(properties) {
674 if (cdk.isResolvableObject(properties)) {
675 return new cfn_parse.FromCloudFormationResult(properties);
676 }
677 properties = properties == null ? {} : properties;
678 if (typeof properties !== 'object') {
679 return new cfn_parse.FromCloudFormationResult(properties);
680 }
681 const ret = new cfn_parse.FromCloudFormationPropertyObject();
682 ret.addPropertyResult('cloudWatchEncryptionEnabled', 'CloudWatchEncryptionEnabled', properties.CloudWatchEncryptionEnabled != null ? cfn_parse.FromCloudFormation.getBoolean(properties.CloudWatchEncryptionEnabled) : undefined);
683 ret.addPropertyResult('cloudWatchLogGroupName', 'CloudWatchLogGroupName', properties.CloudWatchLogGroupName != null ? cfn_parse.FromCloudFormation.getString(properties.CloudWatchLogGroupName) : undefined);
684 ret.addPropertyResult('s3BucketName', 'S3BucketName', properties.S3BucketName != null ? cfn_parse.FromCloudFormation.getString(properties.S3BucketName) : undefined);
685 ret.addPropertyResult('s3EncryptionEnabled', 'S3EncryptionEnabled', properties.S3EncryptionEnabled != null ? cfn_parse.FromCloudFormation.getBoolean(properties.S3EncryptionEnabled) : undefined);
686 ret.addPropertyResult('s3KeyPrefix', 'S3KeyPrefix', properties.S3KeyPrefix != null ? cfn_parse.FromCloudFormation.getString(properties.S3KeyPrefix) : undefined);
687 ret.addUnrecognizedPropertiesAsExtra(properties);
688 return ret;
689}
690/**
691 * Determine whether the given properties match those of a `ServiceConnectDefaultsProperty`
692 *
693 * @param properties - the TypeScript properties of a `ServiceConnectDefaultsProperty`
694 *
695 * @returns the result of the validation.
696 */
697function CfnCluster_ServiceConnectDefaultsPropertyValidator(properties) {
698 if (!cdk.canInspect(properties)) {
699 return cdk.VALIDATION_SUCCESS;
700 }
701 const errors = new cdk.ValidationResults();
702 if (typeof properties !== 'object') {
703 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
704 }
705 errors.collect(cdk.propertyValidator('namespace', cdk.validateString)(properties.namespace));
706 return errors.wrap('supplied properties not correct for "ServiceConnectDefaultsProperty"');
707}
708/**
709 * Renders the AWS CloudFormation properties of an `AWS::ECS::Cluster.ServiceConnectDefaults` resource
710 *
711 * @param properties - the TypeScript properties of a `ServiceConnectDefaultsProperty`
712 *
713 * @returns the AWS CloudFormation properties of an `AWS::ECS::Cluster.ServiceConnectDefaults` resource.
714 */
715// @ts-ignore TS6133
716function cfnClusterServiceConnectDefaultsPropertyToCloudFormation(properties) {
717 if (!cdk.canInspect(properties)) {
718 return properties;
719 }
720 CfnCluster_ServiceConnectDefaultsPropertyValidator(properties).assertSuccess();
721 return {
722 Namespace: cdk.stringToCloudFormation(properties.namespace),
723 };
724}
725// @ts-ignore TS6133
726function CfnClusterServiceConnectDefaultsPropertyFromCloudFormation(properties) {
727 if (cdk.isResolvableObject(properties)) {
728 return new cfn_parse.FromCloudFormationResult(properties);
729 }
730 properties = properties == null ? {} : properties;
731 if (typeof properties !== 'object') {
732 return new cfn_parse.FromCloudFormationResult(properties);
733 }
734 const ret = new cfn_parse.FromCloudFormationPropertyObject();
735 ret.addPropertyResult('namespace', 'Namespace', properties.Namespace != null ? cfn_parse.FromCloudFormation.getString(properties.Namespace) : undefined);
736 ret.addUnrecognizedPropertiesAsExtra(properties);
737 return ret;
738}
739/**
740 * Determine whether the given properties match those of a `CfnClusterCapacityProviderAssociationsProps`
741 *
742 * @param properties - the TypeScript properties of a `CfnClusterCapacityProviderAssociationsProps`
743 *
744 * @returns the result of the validation.
745 */
746function CfnClusterCapacityProviderAssociationsPropsValidator(properties) {
747 if (!cdk.canInspect(properties)) {
748 return cdk.VALIDATION_SUCCESS;
749 }
750 const errors = new cdk.ValidationResults();
751 if (typeof properties !== 'object') {
752 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
753 }
754 errors.collect(cdk.propertyValidator('capacityProviders', cdk.requiredValidator)(properties.capacityProviders));
755 errors.collect(cdk.propertyValidator('capacityProviders', cdk.listValidator(cdk.validateString))(properties.capacityProviders));
756 errors.collect(cdk.propertyValidator('cluster', cdk.requiredValidator)(properties.cluster));
757 errors.collect(cdk.propertyValidator('cluster', cdk.validateString)(properties.cluster));
758 errors.collect(cdk.propertyValidator('defaultCapacityProviderStrategy', cdk.requiredValidator)(properties.defaultCapacityProviderStrategy));
759 errors.collect(cdk.propertyValidator('defaultCapacityProviderStrategy', cdk.listValidator(CfnClusterCapacityProviderAssociations_CapacityProviderStrategyPropertyValidator))(properties.defaultCapacityProviderStrategy));
760 return errors.wrap('supplied properties not correct for "CfnClusterCapacityProviderAssociationsProps"');
761}
762/**
763 * Renders the AWS CloudFormation properties of an `AWS::ECS::ClusterCapacityProviderAssociations` resource
764 *
765 * @param properties - the TypeScript properties of a `CfnClusterCapacityProviderAssociationsProps`
766 *
767 * @returns the AWS CloudFormation properties of an `AWS::ECS::ClusterCapacityProviderAssociations` resource.
768 */
769// @ts-ignore TS6133
770function cfnClusterCapacityProviderAssociationsPropsToCloudFormation(properties) {
771 if (!cdk.canInspect(properties)) {
772 return properties;
773 }
774 CfnClusterCapacityProviderAssociationsPropsValidator(properties).assertSuccess();
775 return {
776 CapacityProviders: cdk.listMapper(cdk.stringToCloudFormation)(properties.capacityProviders),
777 Cluster: cdk.stringToCloudFormation(properties.cluster),
778 DefaultCapacityProviderStrategy: cdk.listMapper(cfnClusterCapacityProviderAssociationsCapacityProviderStrategyPropertyToCloudFormation)(properties.defaultCapacityProviderStrategy),
779 };
780}
781// @ts-ignore TS6133
782function CfnClusterCapacityProviderAssociationsPropsFromCloudFormation(properties) {
783 properties = properties == null ? {} : properties;
784 if (typeof properties !== 'object') {
785 return new cfn_parse.FromCloudFormationResult(properties);
786 }
787 const ret = new cfn_parse.FromCloudFormationPropertyObject();
788 ret.addPropertyResult('capacityProviders', 'CapacityProviders', cfn_parse.FromCloudFormation.getStringArray(properties.CapacityProviders));
789 ret.addPropertyResult('cluster', 'Cluster', cfn_parse.FromCloudFormation.getString(properties.Cluster));
790 ret.addPropertyResult('defaultCapacityProviderStrategy', 'DefaultCapacityProviderStrategy', cfn_parse.FromCloudFormation.getArray(CfnClusterCapacityProviderAssociationsCapacityProviderStrategyPropertyFromCloudFormation)(properties.DefaultCapacityProviderStrategy));
791 ret.addUnrecognizedPropertiesAsExtra(properties);
792 return ret;
793}
794/**
795 * A CloudFormation `AWS::ECS::ClusterCapacityProviderAssociations`
796 *
797 * The `AWS::ECS::ClusterCapacityProviderAssociations` resource associates one or more capacity providers and a default capacity provider strategy with a cluster.
798 *
799 * @cloudformationResource AWS::ECS::ClusterCapacityProviderAssociations
800 * @stability external
801 *
802 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-clustercapacityproviderassociations.html
803 */
804class CfnClusterCapacityProviderAssociations extends cdk.CfnResource {
805 /**
806 * Create a new `AWS::ECS::ClusterCapacityProviderAssociations`.
807 *
808 * @param scope - scope in which this resource is defined
809 * @param id - scoped id of the resource
810 * @param props - resource properties
811 */
812 constructor(scope, id, props) {
813 super(scope, id, { type: CfnClusterCapacityProviderAssociations.CFN_RESOURCE_TYPE_NAME, properties: props });
814 try {
815 jsiiDeprecationWarnings._aws_cdk_aws_ecs_CfnClusterCapacityProviderAssociationsProps(props);
816 }
817 catch (error) {
818 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
819 Error.captureStackTrace(error, CfnClusterCapacityProviderAssociations);
820 }
821 throw error;
822 }
823 cdk.requireProperty(props, 'capacityProviders', this);
824 cdk.requireProperty(props, 'cluster', this);
825 cdk.requireProperty(props, 'defaultCapacityProviderStrategy', this);
826 this.capacityProviders = props.capacityProviders;
827 this.cluster = props.cluster;
828 this.defaultCapacityProviderStrategy = props.defaultCapacityProviderStrategy;
829 }
830 /**
831 * A factory method that creates a new instance of this class from an object
832 * containing the CloudFormation properties of this resource.
833 * Used in the @aws-cdk/cloudformation-include module.
834 *
835 * @internal
836 */
837 static _fromCloudFormation(scope, id, resourceAttributes, options) {
838 resourceAttributes = resourceAttributes || {};
839 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
840 const propsResult = CfnClusterCapacityProviderAssociationsPropsFromCloudFormation(resourceProperties);
841 const ret = new CfnClusterCapacityProviderAssociations(scope, id, propsResult.value);
842 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
843 ret.addPropertyOverride(propKey, propVal);
844 }
845 options.parser.handleAttributes(ret, resourceAttributes, id);
846 return ret;
847 }
848 /**
849 * Examines the CloudFormation resource and discloses attributes.
850 *
851 * @param inspector - tree inspector to collect and process attributes
852 *
853 */
854 inspect(inspector) {
855 inspector.addAttribute("aws:cdk:cloudformation:type", CfnClusterCapacityProviderAssociations.CFN_RESOURCE_TYPE_NAME);
856 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
857 }
858 get cfnProperties() {
859 return {
860 capacityProviders: this.capacityProviders,
861 cluster: this.cluster,
862 defaultCapacityProviderStrategy: this.defaultCapacityProviderStrategy,
863 };
864 }
865 renderProperties(props) {
866 return cfnClusterCapacityProviderAssociationsPropsToCloudFormation(props);
867 }
868}
869exports.CfnClusterCapacityProviderAssociations = CfnClusterCapacityProviderAssociations;
870_c = JSII_RTTI_SYMBOL_1;
871CfnClusterCapacityProviderAssociations[_c] = { fqn: "@aws-cdk/aws-ecs.CfnClusterCapacityProviderAssociations", version: "1.204.0" };
872/**
873 * The CloudFormation resource type name for this resource class.
874 */
875CfnClusterCapacityProviderAssociations.CFN_RESOURCE_TYPE_NAME = "AWS::ECS::ClusterCapacityProviderAssociations";
876/**
877 * Determine whether the given properties match those of a `CapacityProviderStrategyProperty`
878 *
879 * @param properties - the TypeScript properties of a `CapacityProviderStrategyProperty`
880 *
881 * @returns the result of the validation.
882 */
883function CfnClusterCapacityProviderAssociations_CapacityProviderStrategyPropertyValidator(properties) {
884 if (!cdk.canInspect(properties)) {
885 return cdk.VALIDATION_SUCCESS;
886 }
887 const errors = new cdk.ValidationResults();
888 if (typeof properties !== 'object') {
889 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
890 }
891 errors.collect(cdk.propertyValidator('base', cdk.validateNumber)(properties.base));
892 errors.collect(cdk.propertyValidator('capacityProvider', cdk.requiredValidator)(properties.capacityProvider));
893 errors.collect(cdk.propertyValidator('capacityProvider', cdk.validateString)(properties.capacityProvider));
894 errors.collect(cdk.propertyValidator('weight', cdk.validateNumber)(properties.weight));
895 return errors.wrap('supplied properties not correct for "CapacityProviderStrategyProperty"');
896}
897/**
898 * Renders the AWS CloudFormation properties of an `AWS::ECS::ClusterCapacityProviderAssociations.CapacityProviderStrategy` resource
899 *
900 * @param properties - the TypeScript properties of a `CapacityProviderStrategyProperty`
901 *
902 * @returns the AWS CloudFormation properties of an `AWS::ECS::ClusterCapacityProviderAssociations.CapacityProviderStrategy` resource.
903 */
904// @ts-ignore TS6133
905function cfnClusterCapacityProviderAssociationsCapacityProviderStrategyPropertyToCloudFormation(properties) {
906 if (!cdk.canInspect(properties)) {
907 return properties;
908 }
909 CfnClusterCapacityProviderAssociations_CapacityProviderStrategyPropertyValidator(properties).assertSuccess();
910 return {
911 Base: cdk.numberToCloudFormation(properties.base),
912 CapacityProvider: cdk.stringToCloudFormation(properties.capacityProvider),
913 Weight: cdk.numberToCloudFormation(properties.weight),
914 };
915}
916// @ts-ignore TS6133
917function CfnClusterCapacityProviderAssociationsCapacityProviderStrategyPropertyFromCloudFormation(properties) {
918 if (cdk.isResolvableObject(properties)) {
919 return new cfn_parse.FromCloudFormationResult(properties);
920 }
921 properties = properties == null ? {} : properties;
922 if (typeof properties !== 'object') {
923 return new cfn_parse.FromCloudFormationResult(properties);
924 }
925 const ret = new cfn_parse.FromCloudFormationPropertyObject();
926 ret.addPropertyResult('base', 'Base', properties.Base != null ? cfn_parse.FromCloudFormation.getNumber(properties.Base) : undefined);
927 ret.addPropertyResult('capacityProvider', 'CapacityProvider', cfn_parse.FromCloudFormation.getString(properties.CapacityProvider));
928 ret.addPropertyResult('weight', 'Weight', properties.Weight != null ? cfn_parse.FromCloudFormation.getNumber(properties.Weight) : undefined);
929 ret.addUnrecognizedPropertiesAsExtra(properties);
930 return ret;
931}
932/**
933 * Determine whether the given properties match those of a `CfnPrimaryTaskSetProps`
934 *
935 * @param properties - the TypeScript properties of a `CfnPrimaryTaskSetProps`
936 *
937 * @returns the result of the validation.
938 */
939function CfnPrimaryTaskSetPropsValidator(properties) {
940 if (!cdk.canInspect(properties)) {
941 return cdk.VALIDATION_SUCCESS;
942 }
943 const errors = new cdk.ValidationResults();
944 if (typeof properties !== 'object') {
945 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
946 }
947 errors.collect(cdk.propertyValidator('cluster', cdk.requiredValidator)(properties.cluster));
948 errors.collect(cdk.propertyValidator('cluster', cdk.validateString)(properties.cluster));
949 errors.collect(cdk.propertyValidator('service', cdk.requiredValidator)(properties.service));
950 errors.collect(cdk.propertyValidator('service', cdk.validateString)(properties.service));
951 errors.collect(cdk.propertyValidator('taskSetId', cdk.requiredValidator)(properties.taskSetId));
952 errors.collect(cdk.propertyValidator('taskSetId', cdk.validateString)(properties.taskSetId));
953 return errors.wrap('supplied properties not correct for "CfnPrimaryTaskSetProps"');
954}
955/**
956 * Renders the AWS CloudFormation properties of an `AWS::ECS::PrimaryTaskSet` resource
957 *
958 * @param properties - the TypeScript properties of a `CfnPrimaryTaskSetProps`
959 *
960 * @returns the AWS CloudFormation properties of an `AWS::ECS::PrimaryTaskSet` resource.
961 */
962// @ts-ignore TS6133
963function cfnPrimaryTaskSetPropsToCloudFormation(properties) {
964 if (!cdk.canInspect(properties)) {
965 return properties;
966 }
967 CfnPrimaryTaskSetPropsValidator(properties).assertSuccess();
968 return {
969 Cluster: cdk.stringToCloudFormation(properties.cluster),
970 Service: cdk.stringToCloudFormation(properties.service),
971 TaskSetId: cdk.stringToCloudFormation(properties.taskSetId),
972 };
973}
974// @ts-ignore TS6133
975function CfnPrimaryTaskSetPropsFromCloudFormation(properties) {
976 properties = properties == null ? {} : properties;
977 if (typeof properties !== 'object') {
978 return new cfn_parse.FromCloudFormationResult(properties);
979 }
980 const ret = new cfn_parse.FromCloudFormationPropertyObject();
981 ret.addPropertyResult('cluster', 'Cluster', cfn_parse.FromCloudFormation.getString(properties.Cluster));
982 ret.addPropertyResult('service', 'Service', cfn_parse.FromCloudFormation.getString(properties.Service));
983 ret.addPropertyResult('taskSetId', 'TaskSetId', cfn_parse.FromCloudFormation.getString(properties.TaskSetId));
984 ret.addUnrecognizedPropertiesAsExtra(properties);
985 return ret;
986}
987/**
988 * A CloudFormation `AWS::ECS::PrimaryTaskSet`
989 *
990 * Modifies which task set in a service is the primary task set. Any parameters that are updated on the primary task set in a service will transition to the service. This is used when a service uses the `EXTERNAL` deployment controller type. For more information, see [Amazon ECS Deployment Types](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/deployment-types.html) in the *Amazon Elastic Container Service Developer Guide* .
991 *
992 * @cloudformationResource AWS::ECS::PrimaryTaskSet
993 * @stability external
994 *
995 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-primarytaskset.html
996 */
997class CfnPrimaryTaskSet extends cdk.CfnResource {
998 /**
999 * Create a new `AWS::ECS::PrimaryTaskSet`.
1000 *
1001 * @param scope - scope in which this resource is defined
1002 * @param id - scoped id of the resource
1003 * @param props - resource properties
1004 */
1005 constructor(scope, id, props) {
1006 super(scope, id, { type: CfnPrimaryTaskSet.CFN_RESOURCE_TYPE_NAME, properties: props });
1007 try {
1008 jsiiDeprecationWarnings._aws_cdk_aws_ecs_CfnPrimaryTaskSetProps(props);
1009 }
1010 catch (error) {
1011 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
1012 Error.captureStackTrace(error, CfnPrimaryTaskSet);
1013 }
1014 throw error;
1015 }
1016 cdk.requireProperty(props, 'cluster', this);
1017 cdk.requireProperty(props, 'service', this);
1018 cdk.requireProperty(props, 'taskSetId', this);
1019 this.cluster = props.cluster;
1020 this.service = props.service;
1021 this.taskSetId = props.taskSetId;
1022 }
1023 /**
1024 * A factory method that creates a new instance of this class from an object
1025 * containing the CloudFormation properties of this resource.
1026 * Used in the @aws-cdk/cloudformation-include module.
1027 *
1028 * @internal
1029 */
1030 static _fromCloudFormation(scope, id, resourceAttributes, options) {
1031 resourceAttributes = resourceAttributes || {};
1032 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
1033 const propsResult = CfnPrimaryTaskSetPropsFromCloudFormation(resourceProperties);
1034 const ret = new CfnPrimaryTaskSet(scope, id, propsResult.value);
1035 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
1036 ret.addPropertyOverride(propKey, propVal);
1037 }
1038 options.parser.handleAttributes(ret, resourceAttributes, id);
1039 return ret;
1040 }
1041 /**
1042 * Examines the CloudFormation resource and discloses attributes.
1043 *
1044 * @param inspector - tree inspector to collect and process attributes
1045 *
1046 */
1047 inspect(inspector) {
1048 inspector.addAttribute("aws:cdk:cloudformation:type", CfnPrimaryTaskSet.CFN_RESOURCE_TYPE_NAME);
1049 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
1050 }
1051 get cfnProperties() {
1052 return {
1053 cluster: this.cluster,
1054 service: this.service,
1055 taskSetId: this.taskSetId,
1056 };
1057 }
1058 renderProperties(props) {
1059 return cfnPrimaryTaskSetPropsToCloudFormation(props);
1060 }
1061}
1062exports.CfnPrimaryTaskSet = CfnPrimaryTaskSet;
1063_d = JSII_RTTI_SYMBOL_1;
1064CfnPrimaryTaskSet[_d] = { fqn: "@aws-cdk/aws-ecs.CfnPrimaryTaskSet", version: "1.204.0" };
1065/**
1066 * The CloudFormation resource type name for this resource class.
1067 */
1068CfnPrimaryTaskSet.CFN_RESOURCE_TYPE_NAME = "AWS::ECS::PrimaryTaskSet";
1069/**
1070 * Determine whether the given properties match those of a `CfnServiceProps`
1071 *
1072 * @param properties - the TypeScript properties of a `CfnServiceProps`
1073 *
1074 * @returns the result of the validation.
1075 */
1076function CfnServicePropsValidator(properties) {
1077 if (!cdk.canInspect(properties)) {
1078 return cdk.VALIDATION_SUCCESS;
1079 }
1080 const errors = new cdk.ValidationResults();
1081 if (typeof properties !== 'object') {
1082 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1083 }
1084 errors.collect(cdk.propertyValidator('capacityProviderStrategy', cdk.listValidator(CfnService_CapacityProviderStrategyItemPropertyValidator))(properties.capacityProviderStrategy));
1085 errors.collect(cdk.propertyValidator('cluster', cdk.validateString)(properties.cluster));
1086 errors.collect(cdk.propertyValidator('deploymentConfiguration', CfnService_DeploymentConfigurationPropertyValidator)(properties.deploymentConfiguration));
1087 errors.collect(cdk.propertyValidator('deploymentController', CfnService_DeploymentControllerPropertyValidator)(properties.deploymentController));
1088 errors.collect(cdk.propertyValidator('desiredCount', cdk.validateNumber)(properties.desiredCount));
1089 errors.collect(cdk.propertyValidator('enableEcsManagedTags', cdk.validateBoolean)(properties.enableEcsManagedTags));
1090 errors.collect(cdk.propertyValidator('enableExecuteCommand', cdk.validateBoolean)(properties.enableExecuteCommand));
1091 errors.collect(cdk.propertyValidator('healthCheckGracePeriodSeconds', cdk.validateNumber)(properties.healthCheckGracePeriodSeconds));
1092 errors.collect(cdk.propertyValidator('launchType', cdk.validateString)(properties.launchType));
1093 errors.collect(cdk.propertyValidator('loadBalancers', cdk.listValidator(CfnService_LoadBalancerPropertyValidator))(properties.loadBalancers));
1094 errors.collect(cdk.propertyValidator('networkConfiguration', CfnService_NetworkConfigurationPropertyValidator)(properties.networkConfiguration));
1095 errors.collect(cdk.propertyValidator('placementConstraints', cdk.listValidator(CfnService_PlacementConstraintPropertyValidator))(properties.placementConstraints));
1096 errors.collect(cdk.propertyValidator('placementStrategies', cdk.listValidator(CfnService_PlacementStrategyPropertyValidator))(properties.placementStrategies));
1097 errors.collect(cdk.propertyValidator('platformVersion', cdk.validateString)(properties.platformVersion));
1098 errors.collect(cdk.propertyValidator('propagateTags', cdk.validateString)(properties.propagateTags));
1099 errors.collect(cdk.propertyValidator('role', cdk.validateString)(properties.role));
1100 errors.collect(cdk.propertyValidator('schedulingStrategy', cdk.validateString)(properties.schedulingStrategy));
1101 errors.collect(cdk.propertyValidator('serviceConnectConfiguration', CfnService_ServiceConnectConfigurationPropertyValidator)(properties.serviceConnectConfiguration));
1102 errors.collect(cdk.propertyValidator('serviceName', cdk.validateString)(properties.serviceName));
1103 errors.collect(cdk.propertyValidator('serviceRegistries', cdk.listValidator(CfnService_ServiceRegistryPropertyValidator))(properties.serviceRegistries));
1104 errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
1105 errors.collect(cdk.propertyValidator('taskDefinition', cdk.validateString)(properties.taskDefinition));
1106 return errors.wrap('supplied properties not correct for "CfnServiceProps"');
1107}
1108/**
1109 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service` resource
1110 *
1111 * @param properties - the TypeScript properties of a `CfnServiceProps`
1112 *
1113 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service` resource.
1114 */
1115// @ts-ignore TS6133
1116function cfnServicePropsToCloudFormation(properties) {
1117 if (!cdk.canInspect(properties)) {
1118 return properties;
1119 }
1120 CfnServicePropsValidator(properties).assertSuccess();
1121 return {
1122 CapacityProviderStrategy: cdk.listMapper(cfnServiceCapacityProviderStrategyItemPropertyToCloudFormation)(properties.capacityProviderStrategy),
1123 Cluster: cdk.stringToCloudFormation(properties.cluster),
1124 DeploymentConfiguration: cfnServiceDeploymentConfigurationPropertyToCloudFormation(properties.deploymentConfiguration),
1125 DeploymentController: cfnServiceDeploymentControllerPropertyToCloudFormation(properties.deploymentController),
1126 DesiredCount: cdk.numberToCloudFormation(properties.desiredCount),
1127 EnableECSManagedTags: cdk.booleanToCloudFormation(properties.enableEcsManagedTags),
1128 EnableExecuteCommand: cdk.booleanToCloudFormation(properties.enableExecuteCommand),
1129 HealthCheckGracePeriodSeconds: cdk.numberToCloudFormation(properties.healthCheckGracePeriodSeconds),
1130 LaunchType: cdk.stringToCloudFormation(properties.launchType),
1131 LoadBalancers: cdk.listMapper(cfnServiceLoadBalancerPropertyToCloudFormation)(properties.loadBalancers),
1132 NetworkConfiguration: cfnServiceNetworkConfigurationPropertyToCloudFormation(properties.networkConfiguration),
1133 PlacementConstraints: cdk.listMapper(cfnServicePlacementConstraintPropertyToCloudFormation)(properties.placementConstraints),
1134 PlacementStrategies: cdk.listMapper(cfnServicePlacementStrategyPropertyToCloudFormation)(properties.placementStrategies),
1135 PlatformVersion: cdk.stringToCloudFormation(properties.platformVersion),
1136 PropagateTags: cdk.stringToCloudFormation(properties.propagateTags),
1137 Role: cdk.stringToCloudFormation(properties.role),
1138 SchedulingStrategy: cdk.stringToCloudFormation(properties.schedulingStrategy),
1139 ServiceConnectConfiguration: cfnServiceServiceConnectConfigurationPropertyToCloudFormation(properties.serviceConnectConfiguration),
1140 ServiceName: cdk.stringToCloudFormation(properties.serviceName),
1141 ServiceRegistries: cdk.listMapper(cfnServiceServiceRegistryPropertyToCloudFormation)(properties.serviceRegistries),
1142 Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
1143 TaskDefinition: cdk.stringToCloudFormation(properties.taskDefinition),
1144 };
1145}
1146// @ts-ignore TS6133
1147function CfnServicePropsFromCloudFormation(properties) {
1148 properties = properties == null ? {} : properties;
1149 if (typeof properties !== 'object') {
1150 return new cfn_parse.FromCloudFormationResult(properties);
1151 }
1152 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1153 ret.addPropertyResult('capacityProviderStrategy', 'CapacityProviderStrategy', properties.CapacityProviderStrategy != null ? cfn_parse.FromCloudFormation.getArray(CfnServiceCapacityProviderStrategyItemPropertyFromCloudFormation)(properties.CapacityProviderStrategy) : undefined);
1154 ret.addPropertyResult('cluster', 'Cluster', properties.Cluster != null ? cfn_parse.FromCloudFormation.getString(properties.Cluster) : undefined);
1155 ret.addPropertyResult('deploymentConfiguration', 'DeploymentConfiguration', properties.DeploymentConfiguration != null ? CfnServiceDeploymentConfigurationPropertyFromCloudFormation(properties.DeploymentConfiguration) : undefined);
1156 ret.addPropertyResult('deploymentController', 'DeploymentController', properties.DeploymentController != null ? CfnServiceDeploymentControllerPropertyFromCloudFormation(properties.DeploymentController) : undefined);
1157 ret.addPropertyResult('desiredCount', 'DesiredCount', properties.DesiredCount != null ? cfn_parse.FromCloudFormation.getNumber(properties.DesiredCount) : undefined);
1158 ret.addPropertyResult('enableEcsManagedTags', 'EnableECSManagedTags', properties.EnableECSManagedTags != null ? cfn_parse.FromCloudFormation.getBoolean(properties.EnableECSManagedTags) : undefined);
1159 ret.addPropertyResult('enableExecuteCommand', 'EnableExecuteCommand', properties.EnableExecuteCommand != null ? cfn_parse.FromCloudFormation.getBoolean(properties.EnableExecuteCommand) : undefined);
1160 ret.addPropertyResult('healthCheckGracePeriodSeconds', 'HealthCheckGracePeriodSeconds', properties.HealthCheckGracePeriodSeconds != null ? cfn_parse.FromCloudFormation.getNumber(properties.HealthCheckGracePeriodSeconds) : undefined);
1161 ret.addPropertyResult('launchType', 'LaunchType', properties.LaunchType != null ? cfn_parse.FromCloudFormation.getString(properties.LaunchType) : undefined);
1162 ret.addPropertyResult('loadBalancers', 'LoadBalancers', properties.LoadBalancers != null ? cfn_parse.FromCloudFormation.getArray(CfnServiceLoadBalancerPropertyFromCloudFormation)(properties.LoadBalancers) : undefined);
1163 ret.addPropertyResult('networkConfiguration', 'NetworkConfiguration', properties.NetworkConfiguration != null ? CfnServiceNetworkConfigurationPropertyFromCloudFormation(properties.NetworkConfiguration) : undefined);
1164 ret.addPropertyResult('placementConstraints', 'PlacementConstraints', properties.PlacementConstraints != null ? cfn_parse.FromCloudFormation.getArray(CfnServicePlacementConstraintPropertyFromCloudFormation)(properties.PlacementConstraints) : undefined);
1165 ret.addPropertyResult('placementStrategies', 'PlacementStrategies', properties.PlacementStrategies != null ? cfn_parse.FromCloudFormation.getArray(CfnServicePlacementStrategyPropertyFromCloudFormation)(properties.PlacementStrategies) : undefined);
1166 ret.addPropertyResult('platformVersion', 'PlatformVersion', properties.PlatformVersion != null ? cfn_parse.FromCloudFormation.getString(properties.PlatformVersion) : undefined);
1167 ret.addPropertyResult('propagateTags', 'PropagateTags', properties.PropagateTags != null ? cfn_parse.FromCloudFormation.getString(properties.PropagateTags) : undefined);
1168 ret.addPropertyResult('role', 'Role', properties.Role != null ? cfn_parse.FromCloudFormation.getString(properties.Role) : undefined);
1169 ret.addPropertyResult('schedulingStrategy', 'SchedulingStrategy', properties.SchedulingStrategy != null ? cfn_parse.FromCloudFormation.getString(properties.SchedulingStrategy) : undefined);
1170 ret.addPropertyResult('serviceConnectConfiguration', 'ServiceConnectConfiguration', properties.ServiceConnectConfiguration != null ? CfnServiceServiceConnectConfigurationPropertyFromCloudFormation(properties.ServiceConnectConfiguration) : undefined);
1171 ret.addPropertyResult('serviceName', 'ServiceName', properties.ServiceName != null ? cfn_parse.FromCloudFormation.getString(properties.ServiceName) : undefined);
1172 ret.addPropertyResult('serviceRegistries', 'ServiceRegistries', properties.ServiceRegistries != null ? cfn_parse.FromCloudFormation.getArray(CfnServiceServiceRegistryPropertyFromCloudFormation)(properties.ServiceRegistries) : undefined);
1173 ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
1174 ret.addPropertyResult('taskDefinition', 'TaskDefinition', properties.TaskDefinition != null ? cfn_parse.FromCloudFormation.getString(properties.TaskDefinition) : undefined);
1175 ret.addUnrecognizedPropertiesAsExtra(properties);
1176 return ret;
1177}
1178/**
1179 * A CloudFormation `AWS::ECS::Service`
1180 *
1181 * The `AWS::ECS::Service` resource creates an Amazon Elastic Container Service (Amazon ECS) service that runs and maintains the requested number of tasks and associated load balancers.
1182 *
1183 * > The stack update fails if you change any properties that require replacement and at least one Amazon ECS Service Connect `ServiceConnectService` is configured. This is because AWS CloudFormation creates the replacement service first, but each `ServiceConnectService` must have a name that is unique in the namespace. > Starting April 15, 2023, AWS ; will not onboard new customers to Amazon Elastic Inference (EI), and will help current customers migrate their workloads to options that offer better price and performance. After April 15, 2023, new customers will not be able to launch instances with Amazon EI accelerators in Amazon SageMaker, Amazon ECS , or Amazon EC2 . However, customers who have used Amazon EI at least once during the past 30-day period are considered current customers and will be able to continue using the service.
1184 *
1185 * @cloudformationResource AWS::ECS::Service
1186 * @stability external
1187 *
1188 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-service.html
1189 */
1190class CfnService extends cdk.CfnResource {
1191 /**
1192 * Create a new `AWS::ECS::Service`.
1193 *
1194 * @param scope - scope in which this resource is defined
1195 * @param id - scoped id of the resource
1196 * @param props - resource properties
1197 */
1198 constructor(scope, id, props = {}) {
1199 super(scope, id, { type: CfnService.CFN_RESOURCE_TYPE_NAME, properties: props });
1200 try {
1201 jsiiDeprecationWarnings._aws_cdk_aws_ecs_CfnServiceProps(props);
1202 }
1203 catch (error) {
1204 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
1205 Error.captureStackTrace(error, CfnService);
1206 }
1207 throw error;
1208 }
1209 this.attrName = cdk.Token.asString(this.getAtt('Name'));
1210 this.attrServiceArn = cdk.Token.asString(this.getAtt('ServiceArn'));
1211 this.capacityProviderStrategy = props.capacityProviderStrategy;
1212 this.cluster = props.cluster;
1213 this.deploymentConfiguration = props.deploymentConfiguration;
1214 this.deploymentController = props.deploymentController;
1215 this.desiredCount = props.desiredCount;
1216 this.enableEcsManagedTags = props.enableEcsManagedTags;
1217 this.enableExecuteCommand = props.enableExecuteCommand;
1218 this.healthCheckGracePeriodSeconds = props.healthCheckGracePeriodSeconds;
1219 this.launchType = props.launchType;
1220 this.loadBalancers = props.loadBalancers;
1221 this.networkConfiguration = props.networkConfiguration;
1222 this.placementConstraints = props.placementConstraints;
1223 this.placementStrategies = props.placementStrategies;
1224 this.platformVersion = props.platformVersion;
1225 this.propagateTags = props.propagateTags;
1226 this.role = props.role;
1227 this.schedulingStrategy = props.schedulingStrategy;
1228 this.serviceConnectConfiguration = props.serviceConnectConfiguration;
1229 this.serviceName = props.serviceName;
1230 this.serviceRegistries = props.serviceRegistries;
1231 this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::ECS::Service", props.tags, { tagPropertyName: 'tags' });
1232 this.taskDefinition = props.taskDefinition;
1233 }
1234 /**
1235 * A factory method that creates a new instance of this class from an object
1236 * containing the CloudFormation properties of this resource.
1237 * Used in the @aws-cdk/cloudformation-include module.
1238 *
1239 * @internal
1240 */
1241 static _fromCloudFormation(scope, id, resourceAttributes, options) {
1242 resourceAttributes = resourceAttributes || {};
1243 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
1244 const propsResult = CfnServicePropsFromCloudFormation(resourceProperties);
1245 const ret = new CfnService(scope, id, propsResult.value);
1246 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
1247 ret.addPropertyOverride(propKey, propVal);
1248 }
1249 options.parser.handleAttributes(ret, resourceAttributes, id);
1250 return ret;
1251 }
1252 /**
1253 * Examines the CloudFormation resource and discloses attributes.
1254 *
1255 * @param inspector - tree inspector to collect and process attributes
1256 *
1257 */
1258 inspect(inspector) {
1259 inspector.addAttribute("aws:cdk:cloudformation:type", CfnService.CFN_RESOURCE_TYPE_NAME);
1260 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
1261 }
1262 get cfnProperties() {
1263 return {
1264 capacityProviderStrategy: this.capacityProviderStrategy,
1265 cluster: this.cluster,
1266 deploymentConfiguration: this.deploymentConfiguration,
1267 deploymentController: this.deploymentController,
1268 desiredCount: this.desiredCount,
1269 enableEcsManagedTags: this.enableEcsManagedTags,
1270 enableExecuteCommand: this.enableExecuteCommand,
1271 healthCheckGracePeriodSeconds: this.healthCheckGracePeriodSeconds,
1272 launchType: this.launchType,
1273 loadBalancers: this.loadBalancers,
1274 networkConfiguration: this.networkConfiguration,
1275 placementConstraints: this.placementConstraints,
1276 placementStrategies: this.placementStrategies,
1277 platformVersion: this.platformVersion,
1278 propagateTags: this.propagateTags,
1279 role: this.role,
1280 schedulingStrategy: this.schedulingStrategy,
1281 serviceConnectConfiguration: this.serviceConnectConfiguration,
1282 serviceName: this.serviceName,
1283 serviceRegistries: this.serviceRegistries,
1284 tags: this.tags.renderTags(),
1285 taskDefinition: this.taskDefinition,
1286 };
1287 }
1288 renderProperties(props) {
1289 return cfnServicePropsToCloudFormation(props);
1290 }
1291}
1292exports.CfnService = CfnService;
1293_e = JSII_RTTI_SYMBOL_1;
1294CfnService[_e] = { fqn: "@aws-cdk/aws-ecs.CfnService", version: "1.204.0" };
1295/**
1296 * The CloudFormation resource type name for this resource class.
1297 */
1298CfnService.CFN_RESOURCE_TYPE_NAME = "AWS::ECS::Service";
1299/**
1300 * Determine whether the given properties match those of a `AwsVpcConfigurationProperty`
1301 *
1302 * @param properties - the TypeScript properties of a `AwsVpcConfigurationProperty`
1303 *
1304 * @returns the result of the validation.
1305 */
1306function CfnService_AwsVpcConfigurationPropertyValidator(properties) {
1307 if (!cdk.canInspect(properties)) {
1308 return cdk.VALIDATION_SUCCESS;
1309 }
1310 const errors = new cdk.ValidationResults();
1311 if (typeof properties !== 'object') {
1312 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1313 }
1314 errors.collect(cdk.propertyValidator('assignPublicIp', cdk.validateString)(properties.assignPublicIp));
1315 errors.collect(cdk.propertyValidator('securityGroups', cdk.listValidator(cdk.validateString))(properties.securityGroups));
1316 errors.collect(cdk.propertyValidator('subnets', cdk.requiredValidator)(properties.subnets));
1317 errors.collect(cdk.propertyValidator('subnets', cdk.listValidator(cdk.validateString))(properties.subnets));
1318 return errors.wrap('supplied properties not correct for "AwsVpcConfigurationProperty"');
1319}
1320/**
1321 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service.AwsVpcConfiguration` resource
1322 *
1323 * @param properties - the TypeScript properties of a `AwsVpcConfigurationProperty`
1324 *
1325 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service.AwsVpcConfiguration` resource.
1326 */
1327// @ts-ignore TS6133
1328function cfnServiceAwsVpcConfigurationPropertyToCloudFormation(properties) {
1329 if (!cdk.canInspect(properties)) {
1330 return properties;
1331 }
1332 CfnService_AwsVpcConfigurationPropertyValidator(properties).assertSuccess();
1333 return {
1334 AssignPublicIp: cdk.stringToCloudFormation(properties.assignPublicIp),
1335 SecurityGroups: cdk.listMapper(cdk.stringToCloudFormation)(properties.securityGroups),
1336 Subnets: cdk.listMapper(cdk.stringToCloudFormation)(properties.subnets),
1337 };
1338}
1339// @ts-ignore TS6133
1340function CfnServiceAwsVpcConfigurationPropertyFromCloudFormation(properties) {
1341 if (cdk.isResolvableObject(properties)) {
1342 return new cfn_parse.FromCloudFormationResult(properties);
1343 }
1344 properties = properties == null ? {} : properties;
1345 if (typeof properties !== 'object') {
1346 return new cfn_parse.FromCloudFormationResult(properties);
1347 }
1348 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1349 ret.addPropertyResult('assignPublicIp', 'AssignPublicIp', properties.AssignPublicIp != null ? cfn_parse.FromCloudFormation.getString(properties.AssignPublicIp) : undefined);
1350 ret.addPropertyResult('securityGroups', 'SecurityGroups', properties.SecurityGroups != null ? cfn_parse.FromCloudFormation.getStringArray(properties.SecurityGroups) : undefined);
1351 ret.addPropertyResult('subnets', 'Subnets', cfn_parse.FromCloudFormation.getStringArray(properties.Subnets));
1352 ret.addUnrecognizedPropertiesAsExtra(properties);
1353 return ret;
1354}
1355/**
1356 * Determine whether the given properties match those of a `CapacityProviderStrategyItemProperty`
1357 *
1358 * @param properties - the TypeScript properties of a `CapacityProviderStrategyItemProperty`
1359 *
1360 * @returns the result of the validation.
1361 */
1362function CfnService_CapacityProviderStrategyItemPropertyValidator(properties) {
1363 if (!cdk.canInspect(properties)) {
1364 return cdk.VALIDATION_SUCCESS;
1365 }
1366 const errors = new cdk.ValidationResults();
1367 if (typeof properties !== 'object') {
1368 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1369 }
1370 errors.collect(cdk.propertyValidator('base', cdk.validateNumber)(properties.base));
1371 errors.collect(cdk.propertyValidator('capacityProvider', cdk.validateString)(properties.capacityProvider));
1372 errors.collect(cdk.propertyValidator('weight', cdk.validateNumber)(properties.weight));
1373 return errors.wrap('supplied properties not correct for "CapacityProviderStrategyItemProperty"');
1374}
1375/**
1376 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service.CapacityProviderStrategyItem` resource
1377 *
1378 * @param properties - the TypeScript properties of a `CapacityProviderStrategyItemProperty`
1379 *
1380 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service.CapacityProviderStrategyItem` resource.
1381 */
1382// @ts-ignore TS6133
1383function cfnServiceCapacityProviderStrategyItemPropertyToCloudFormation(properties) {
1384 if (!cdk.canInspect(properties)) {
1385 return properties;
1386 }
1387 CfnService_CapacityProviderStrategyItemPropertyValidator(properties).assertSuccess();
1388 return {
1389 Base: cdk.numberToCloudFormation(properties.base),
1390 CapacityProvider: cdk.stringToCloudFormation(properties.capacityProvider),
1391 Weight: cdk.numberToCloudFormation(properties.weight),
1392 };
1393}
1394// @ts-ignore TS6133
1395function CfnServiceCapacityProviderStrategyItemPropertyFromCloudFormation(properties) {
1396 if (cdk.isResolvableObject(properties)) {
1397 return new cfn_parse.FromCloudFormationResult(properties);
1398 }
1399 properties = properties == null ? {} : properties;
1400 if (typeof properties !== 'object') {
1401 return new cfn_parse.FromCloudFormationResult(properties);
1402 }
1403 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1404 ret.addPropertyResult('base', 'Base', properties.Base != null ? cfn_parse.FromCloudFormation.getNumber(properties.Base) : undefined);
1405 ret.addPropertyResult('capacityProvider', 'CapacityProvider', properties.CapacityProvider != null ? cfn_parse.FromCloudFormation.getString(properties.CapacityProvider) : undefined);
1406 ret.addPropertyResult('weight', 'Weight', properties.Weight != null ? cfn_parse.FromCloudFormation.getNumber(properties.Weight) : undefined);
1407 ret.addUnrecognizedPropertiesAsExtra(properties);
1408 return ret;
1409}
1410/**
1411 * Determine whether the given properties match those of a `DeploymentAlarmsProperty`
1412 *
1413 * @param properties - the TypeScript properties of a `DeploymentAlarmsProperty`
1414 *
1415 * @returns the result of the validation.
1416 */
1417function CfnService_DeploymentAlarmsPropertyValidator(properties) {
1418 if (!cdk.canInspect(properties)) {
1419 return cdk.VALIDATION_SUCCESS;
1420 }
1421 const errors = new cdk.ValidationResults();
1422 if (typeof properties !== 'object') {
1423 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1424 }
1425 errors.collect(cdk.propertyValidator('alarmNames', cdk.requiredValidator)(properties.alarmNames));
1426 errors.collect(cdk.propertyValidator('alarmNames', cdk.listValidator(cdk.validateString))(properties.alarmNames));
1427 errors.collect(cdk.propertyValidator('enable', cdk.requiredValidator)(properties.enable));
1428 errors.collect(cdk.propertyValidator('enable', cdk.validateBoolean)(properties.enable));
1429 errors.collect(cdk.propertyValidator('rollback', cdk.requiredValidator)(properties.rollback));
1430 errors.collect(cdk.propertyValidator('rollback', cdk.validateBoolean)(properties.rollback));
1431 return errors.wrap('supplied properties not correct for "DeploymentAlarmsProperty"');
1432}
1433/**
1434 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service.DeploymentAlarms` resource
1435 *
1436 * @param properties - the TypeScript properties of a `DeploymentAlarmsProperty`
1437 *
1438 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service.DeploymentAlarms` resource.
1439 */
1440// @ts-ignore TS6133
1441function cfnServiceDeploymentAlarmsPropertyToCloudFormation(properties) {
1442 if (!cdk.canInspect(properties)) {
1443 return properties;
1444 }
1445 CfnService_DeploymentAlarmsPropertyValidator(properties).assertSuccess();
1446 return {
1447 AlarmNames: cdk.listMapper(cdk.stringToCloudFormation)(properties.alarmNames),
1448 Enable: cdk.booleanToCloudFormation(properties.enable),
1449 Rollback: cdk.booleanToCloudFormation(properties.rollback),
1450 };
1451}
1452// @ts-ignore TS6133
1453function CfnServiceDeploymentAlarmsPropertyFromCloudFormation(properties) {
1454 if (cdk.isResolvableObject(properties)) {
1455 return new cfn_parse.FromCloudFormationResult(properties);
1456 }
1457 properties = properties == null ? {} : properties;
1458 if (typeof properties !== 'object') {
1459 return new cfn_parse.FromCloudFormationResult(properties);
1460 }
1461 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1462 ret.addPropertyResult('alarmNames', 'AlarmNames', cfn_parse.FromCloudFormation.getStringArray(properties.AlarmNames));
1463 ret.addPropertyResult('enable', 'Enable', cfn_parse.FromCloudFormation.getBoolean(properties.Enable));
1464 ret.addPropertyResult('rollback', 'Rollback', cfn_parse.FromCloudFormation.getBoolean(properties.Rollback));
1465 ret.addUnrecognizedPropertiesAsExtra(properties);
1466 return ret;
1467}
1468/**
1469 * Determine whether the given properties match those of a `DeploymentCircuitBreakerProperty`
1470 *
1471 * @param properties - the TypeScript properties of a `DeploymentCircuitBreakerProperty`
1472 *
1473 * @returns the result of the validation.
1474 */
1475function CfnService_DeploymentCircuitBreakerPropertyValidator(properties) {
1476 if (!cdk.canInspect(properties)) {
1477 return cdk.VALIDATION_SUCCESS;
1478 }
1479 const errors = new cdk.ValidationResults();
1480 if (typeof properties !== 'object') {
1481 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1482 }
1483 errors.collect(cdk.propertyValidator('enable', cdk.requiredValidator)(properties.enable));
1484 errors.collect(cdk.propertyValidator('enable', cdk.validateBoolean)(properties.enable));
1485 errors.collect(cdk.propertyValidator('rollback', cdk.requiredValidator)(properties.rollback));
1486 errors.collect(cdk.propertyValidator('rollback', cdk.validateBoolean)(properties.rollback));
1487 return errors.wrap('supplied properties not correct for "DeploymentCircuitBreakerProperty"');
1488}
1489/**
1490 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service.DeploymentCircuitBreaker` resource
1491 *
1492 * @param properties - the TypeScript properties of a `DeploymentCircuitBreakerProperty`
1493 *
1494 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service.DeploymentCircuitBreaker` resource.
1495 */
1496// @ts-ignore TS6133
1497function cfnServiceDeploymentCircuitBreakerPropertyToCloudFormation(properties) {
1498 if (!cdk.canInspect(properties)) {
1499 return properties;
1500 }
1501 CfnService_DeploymentCircuitBreakerPropertyValidator(properties).assertSuccess();
1502 return {
1503 Enable: cdk.booleanToCloudFormation(properties.enable),
1504 Rollback: cdk.booleanToCloudFormation(properties.rollback),
1505 };
1506}
1507// @ts-ignore TS6133
1508function CfnServiceDeploymentCircuitBreakerPropertyFromCloudFormation(properties) {
1509 if (cdk.isResolvableObject(properties)) {
1510 return new cfn_parse.FromCloudFormationResult(properties);
1511 }
1512 properties = properties == null ? {} : properties;
1513 if (typeof properties !== 'object') {
1514 return new cfn_parse.FromCloudFormationResult(properties);
1515 }
1516 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1517 ret.addPropertyResult('enable', 'Enable', cfn_parse.FromCloudFormation.getBoolean(properties.Enable));
1518 ret.addPropertyResult('rollback', 'Rollback', cfn_parse.FromCloudFormation.getBoolean(properties.Rollback));
1519 ret.addUnrecognizedPropertiesAsExtra(properties);
1520 return ret;
1521}
1522/**
1523 * Determine whether the given properties match those of a `DeploymentConfigurationProperty`
1524 *
1525 * @param properties - the TypeScript properties of a `DeploymentConfigurationProperty`
1526 *
1527 * @returns the result of the validation.
1528 */
1529function CfnService_DeploymentConfigurationPropertyValidator(properties) {
1530 if (!cdk.canInspect(properties)) {
1531 return cdk.VALIDATION_SUCCESS;
1532 }
1533 const errors = new cdk.ValidationResults();
1534 if (typeof properties !== 'object') {
1535 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1536 }
1537 errors.collect(cdk.propertyValidator('alarms', CfnService_DeploymentAlarmsPropertyValidator)(properties.alarms));
1538 errors.collect(cdk.propertyValidator('deploymentCircuitBreaker', CfnService_DeploymentCircuitBreakerPropertyValidator)(properties.deploymentCircuitBreaker));
1539 errors.collect(cdk.propertyValidator('maximumPercent', cdk.validateNumber)(properties.maximumPercent));
1540 errors.collect(cdk.propertyValidator('minimumHealthyPercent', cdk.validateNumber)(properties.minimumHealthyPercent));
1541 return errors.wrap('supplied properties not correct for "DeploymentConfigurationProperty"');
1542}
1543/**
1544 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service.DeploymentConfiguration` resource
1545 *
1546 * @param properties - the TypeScript properties of a `DeploymentConfigurationProperty`
1547 *
1548 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service.DeploymentConfiguration` resource.
1549 */
1550// @ts-ignore TS6133
1551function cfnServiceDeploymentConfigurationPropertyToCloudFormation(properties) {
1552 if (!cdk.canInspect(properties)) {
1553 return properties;
1554 }
1555 CfnService_DeploymentConfigurationPropertyValidator(properties).assertSuccess();
1556 return {
1557 Alarms: cfnServiceDeploymentAlarmsPropertyToCloudFormation(properties.alarms),
1558 DeploymentCircuitBreaker: cfnServiceDeploymentCircuitBreakerPropertyToCloudFormation(properties.deploymentCircuitBreaker),
1559 MaximumPercent: cdk.numberToCloudFormation(properties.maximumPercent),
1560 MinimumHealthyPercent: cdk.numberToCloudFormation(properties.minimumHealthyPercent),
1561 };
1562}
1563// @ts-ignore TS6133
1564function CfnServiceDeploymentConfigurationPropertyFromCloudFormation(properties) {
1565 if (cdk.isResolvableObject(properties)) {
1566 return new cfn_parse.FromCloudFormationResult(properties);
1567 }
1568 properties = properties == null ? {} : properties;
1569 if (typeof properties !== 'object') {
1570 return new cfn_parse.FromCloudFormationResult(properties);
1571 }
1572 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1573 ret.addPropertyResult('alarms', 'Alarms', properties.Alarms != null ? CfnServiceDeploymentAlarmsPropertyFromCloudFormation(properties.Alarms) : undefined);
1574 ret.addPropertyResult('deploymentCircuitBreaker', 'DeploymentCircuitBreaker', properties.DeploymentCircuitBreaker != null ? CfnServiceDeploymentCircuitBreakerPropertyFromCloudFormation(properties.DeploymentCircuitBreaker) : undefined);
1575 ret.addPropertyResult('maximumPercent', 'MaximumPercent', properties.MaximumPercent != null ? cfn_parse.FromCloudFormation.getNumber(properties.MaximumPercent) : undefined);
1576 ret.addPropertyResult('minimumHealthyPercent', 'MinimumHealthyPercent', properties.MinimumHealthyPercent != null ? cfn_parse.FromCloudFormation.getNumber(properties.MinimumHealthyPercent) : undefined);
1577 ret.addUnrecognizedPropertiesAsExtra(properties);
1578 return ret;
1579}
1580/**
1581 * Determine whether the given properties match those of a `DeploymentControllerProperty`
1582 *
1583 * @param properties - the TypeScript properties of a `DeploymentControllerProperty`
1584 *
1585 * @returns the result of the validation.
1586 */
1587function CfnService_DeploymentControllerPropertyValidator(properties) {
1588 if (!cdk.canInspect(properties)) {
1589 return cdk.VALIDATION_SUCCESS;
1590 }
1591 const errors = new cdk.ValidationResults();
1592 if (typeof properties !== 'object') {
1593 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1594 }
1595 errors.collect(cdk.propertyValidator('type', cdk.validateString)(properties.type));
1596 return errors.wrap('supplied properties not correct for "DeploymentControllerProperty"');
1597}
1598/**
1599 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service.DeploymentController` resource
1600 *
1601 * @param properties - the TypeScript properties of a `DeploymentControllerProperty`
1602 *
1603 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service.DeploymentController` resource.
1604 */
1605// @ts-ignore TS6133
1606function cfnServiceDeploymentControllerPropertyToCloudFormation(properties) {
1607 if (!cdk.canInspect(properties)) {
1608 return properties;
1609 }
1610 CfnService_DeploymentControllerPropertyValidator(properties).assertSuccess();
1611 return {
1612 Type: cdk.stringToCloudFormation(properties.type),
1613 };
1614}
1615// @ts-ignore TS6133
1616function CfnServiceDeploymentControllerPropertyFromCloudFormation(properties) {
1617 if (cdk.isResolvableObject(properties)) {
1618 return new cfn_parse.FromCloudFormationResult(properties);
1619 }
1620 properties = properties == null ? {} : properties;
1621 if (typeof properties !== 'object') {
1622 return new cfn_parse.FromCloudFormationResult(properties);
1623 }
1624 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1625 ret.addPropertyResult('type', 'Type', properties.Type != null ? cfn_parse.FromCloudFormation.getString(properties.Type) : undefined);
1626 ret.addUnrecognizedPropertiesAsExtra(properties);
1627 return ret;
1628}
1629/**
1630 * Determine whether the given properties match those of a `LoadBalancerProperty`
1631 *
1632 * @param properties - the TypeScript properties of a `LoadBalancerProperty`
1633 *
1634 * @returns the result of the validation.
1635 */
1636function CfnService_LoadBalancerPropertyValidator(properties) {
1637 if (!cdk.canInspect(properties)) {
1638 return cdk.VALIDATION_SUCCESS;
1639 }
1640 const errors = new cdk.ValidationResults();
1641 if (typeof properties !== 'object') {
1642 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1643 }
1644 errors.collect(cdk.propertyValidator('containerName', cdk.validateString)(properties.containerName));
1645 errors.collect(cdk.propertyValidator('containerPort', cdk.requiredValidator)(properties.containerPort));
1646 errors.collect(cdk.propertyValidator('containerPort', cdk.validateNumber)(properties.containerPort));
1647 errors.collect(cdk.propertyValidator('loadBalancerName', cdk.validateString)(properties.loadBalancerName));
1648 errors.collect(cdk.propertyValidator('targetGroupArn', cdk.validateString)(properties.targetGroupArn));
1649 return errors.wrap('supplied properties not correct for "LoadBalancerProperty"');
1650}
1651/**
1652 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service.LoadBalancer` resource
1653 *
1654 * @param properties - the TypeScript properties of a `LoadBalancerProperty`
1655 *
1656 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service.LoadBalancer` resource.
1657 */
1658// @ts-ignore TS6133
1659function cfnServiceLoadBalancerPropertyToCloudFormation(properties) {
1660 if (!cdk.canInspect(properties)) {
1661 return properties;
1662 }
1663 CfnService_LoadBalancerPropertyValidator(properties).assertSuccess();
1664 return {
1665 ContainerName: cdk.stringToCloudFormation(properties.containerName),
1666 ContainerPort: cdk.numberToCloudFormation(properties.containerPort),
1667 LoadBalancerName: cdk.stringToCloudFormation(properties.loadBalancerName),
1668 TargetGroupArn: cdk.stringToCloudFormation(properties.targetGroupArn),
1669 };
1670}
1671// @ts-ignore TS6133
1672function CfnServiceLoadBalancerPropertyFromCloudFormation(properties) {
1673 if (cdk.isResolvableObject(properties)) {
1674 return new cfn_parse.FromCloudFormationResult(properties);
1675 }
1676 properties = properties == null ? {} : properties;
1677 if (typeof properties !== 'object') {
1678 return new cfn_parse.FromCloudFormationResult(properties);
1679 }
1680 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1681 ret.addPropertyResult('containerName', 'ContainerName', properties.ContainerName != null ? cfn_parse.FromCloudFormation.getString(properties.ContainerName) : undefined);
1682 ret.addPropertyResult('containerPort', 'ContainerPort', cfn_parse.FromCloudFormation.getNumber(properties.ContainerPort));
1683 ret.addPropertyResult('loadBalancerName', 'LoadBalancerName', properties.LoadBalancerName != null ? cfn_parse.FromCloudFormation.getString(properties.LoadBalancerName) : undefined);
1684 ret.addPropertyResult('targetGroupArn', 'TargetGroupArn', properties.TargetGroupArn != null ? cfn_parse.FromCloudFormation.getString(properties.TargetGroupArn) : undefined);
1685 ret.addUnrecognizedPropertiesAsExtra(properties);
1686 return ret;
1687}
1688/**
1689 * Determine whether the given properties match those of a `LogConfigurationProperty`
1690 *
1691 * @param properties - the TypeScript properties of a `LogConfigurationProperty`
1692 *
1693 * @returns the result of the validation.
1694 */
1695function CfnService_LogConfigurationPropertyValidator(properties) {
1696 if (!cdk.canInspect(properties)) {
1697 return cdk.VALIDATION_SUCCESS;
1698 }
1699 const errors = new cdk.ValidationResults();
1700 if (typeof properties !== 'object') {
1701 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1702 }
1703 errors.collect(cdk.propertyValidator('logDriver', cdk.validateString)(properties.logDriver));
1704 errors.collect(cdk.propertyValidator('options', cdk.hashValidator(cdk.validateString))(properties.options));
1705 errors.collect(cdk.propertyValidator('secretOptions', cdk.listValidator(CfnService_SecretPropertyValidator))(properties.secretOptions));
1706 return errors.wrap('supplied properties not correct for "LogConfigurationProperty"');
1707}
1708/**
1709 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service.LogConfiguration` resource
1710 *
1711 * @param properties - the TypeScript properties of a `LogConfigurationProperty`
1712 *
1713 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service.LogConfiguration` resource.
1714 */
1715// @ts-ignore TS6133
1716function cfnServiceLogConfigurationPropertyToCloudFormation(properties) {
1717 if (!cdk.canInspect(properties)) {
1718 return properties;
1719 }
1720 CfnService_LogConfigurationPropertyValidator(properties).assertSuccess();
1721 return {
1722 LogDriver: cdk.stringToCloudFormation(properties.logDriver),
1723 Options: cdk.hashMapper(cdk.stringToCloudFormation)(properties.options),
1724 SecretOptions: cdk.listMapper(cfnServiceSecretPropertyToCloudFormation)(properties.secretOptions),
1725 };
1726}
1727// @ts-ignore TS6133
1728function CfnServiceLogConfigurationPropertyFromCloudFormation(properties) {
1729 if (cdk.isResolvableObject(properties)) {
1730 return new cfn_parse.FromCloudFormationResult(properties);
1731 }
1732 properties = properties == null ? {} : properties;
1733 if (typeof properties !== 'object') {
1734 return new cfn_parse.FromCloudFormationResult(properties);
1735 }
1736 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1737 ret.addPropertyResult('logDriver', 'LogDriver', properties.LogDriver != null ? cfn_parse.FromCloudFormation.getString(properties.LogDriver) : undefined);
1738 ret.addPropertyResult('options', 'Options', properties.Options != null ? cfn_parse.FromCloudFormation.getMap(cfn_parse.FromCloudFormation.getString)(properties.Options) : undefined);
1739 ret.addPropertyResult('secretOptions', 'SecretOptions', properties.SecretOptions != null ? cfn_parse.FromCloudFormation.getArray(CfnServiceSecretPropertyFromCloudFormation)(properties.SecretOptions) : undefined);
1740 ret.addUnrecognizedPropertiesAsExtra(properties);
1741 return ret;
1742}
1743/**
1744 * Determine whether the given properties match those of a `NetworkConfigurationProperty`
1745 *
1746 * @param properties - the TypeScript properties of a `NetworkConfigurationProperty`
1747 *
1748 * @returns the result of the validation.
1749 */
1750function CfnService_NetworkConfigurationPropertyValidator(properties) {
1751 if (!cdk.canInspect(properties)) {
1752 return cdk.VALIDATION_SUCCESS;
1753 }
1754 const errors = new cdk.ValidationResults();
1755 if (typeof properties !== 'object') {
1756 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1757 }
1758 errors.collect(cdk.propertyValidator('awsvpcConfiguration', CfnService_AwsVpcConfigurationPropertyValidator)(properties.awsvpcConfiguration));
1759 return errors.wrap('supplied properties not correct for "NetworkConfigurationProperty"');
1760}
1761/**
1762 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service.NetworkConfiguration` resource
1763 *
1764 * @param properties - the TypeScript properties of a `NetworkConfigurationProperty`
1765 *
1766 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service.NetworkConfiguration` resource.
1767 */
1768// @ts-ignore TS6133
1769function cfnServiceNetworkConfigurationPropertyToCloudFormation(properties) {
1770 if (!cdk.canInspect(properties)) {
1771 return properties;
1772 }
1773 CfnService_NetworkConfigurationPropertyValidator(properties).assertSuccess();
1774 return {
1775 AwsvpcConfiguration: cfnServiceAwsVpcConfigurationPropertyToCloudFormation(properties.awsvpcConfiguration),
1776 };
1777}
1778// @ts-ignore TS6133
1779function CfnServiceNetworkConfigurationPropertyFromCloudFormation(properties) {
1780 if (cdk.isResolvableObject(properties)) {
1781 return new cfn_parse.FromCloudFormationResult(properties);
1782 }
1783 properties = properties == null ? {} : properties;
1784 if (typeof properties !== 'object') {
1785 return new cfn_parse.FromCloudFormationResult(properties);
1786 }
1787 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1788 ret.addPropertyResult('awsvpcConfiguration', 'AwsvpcConfiguration', properties.AwsvpcConfiguration != null ? CfnServiceAwsVpcConfigurationPropertyFromCloudFormation(properties.AwsvpcConfiguration) : undefined);
1789 ret.addUnrecognizedPropertiesAsExtra(properties);
1790 return ret;
1791}
1792/**
1793 * Determine whether the given properties match those of a `PlacementConstraintProperty`
1794 *
1795 * @param properties - the TypeScript properties of a `PlacementConstraintProperty`
1796 *
1797 * @returns the result of the validation.
1798 */
1799function CfnService_PlacementConstraintPropertyValidator(properties) {
1800 if (!cdk.canInspect(properties)) {
1801 return cdk.VALIDATION_SUCCESS;
1802 }
1803 const errors = new cdk.ValidationResults();
1804 if (typeof properties !== 'object') {
1805 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1806 }
1807 errors.collect(cdk.propertyValidator('expression', cdk.validateString)(properties.expression));
1808 errors.collect(cdk.propertyValidator('type', cdk.requiredValidator)(properties.type));
1809 errors.collect(cdk.propertyValidator('type', cdk.validateString)(properties.type));
1810 return errors.wrap('supplied properties not correct for "PlacementConstraintProperty"');
1811}
1812/**
1813 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service.PlacementConstraint` resource
1814 *
1815 * @param properties - the TypeScript properties of a `PlacementConstraintProperty`
1816 *
1817 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service.PlacementConstraint` resource.
1818 */
1819// @ts-ignore TS6133
1820function cfnServicePlacementConstraintPropertyToCloudFormation(properties) {
1821 if (!cdk.canInspect(properties)) {
1822 return properties;
1823 }
1824 CfnService_PlacementConstraintPropertyValidator(properties).assertSuccess();
1825 return {
1826 Expression: cdk.stringToCloudFormation(properties.expression),
1827 Type: cdk.stringToCloudFormation(properties.type),
1828 };
1829}
1830// @ts-ignore TS6133
1831function CfnServicePlacementConstraintPropertyFromCloudFormation(properties) {
1832 if (cdk.isResolvableObject(properties)) {
1833 return new cfn_parse.FromCloudFormationResult(properties);
1834 }
1835 properties = properties == null ? {} : properties;
1836 if (typeof properties !== 'object') {
1837 return new cfn_parse.FromCloudFormationResult(properties);
1838 }
1839 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1840 ret.addPropertyResult('expression', 'Expression', properties.Expression != null ? cfn_parse.FromCloudFormation.getString(properties.Expression) : undefined);
1841 ret.addPropertyResult('type', 'Type', cfn_parse.FromCloudFormation.getString(properties.Type));
1842 ret.addUnrecognizedPropertiesAsExtra(properties);
1843 return ret;
1844}
1845/**
1846 * Determine whether the given properties match those of a `PlacementStrategyProperty`
1847 *
1848 * @param properties - the TypeScript properties of a `PlacementStrategyProperty`
1849 *
1850 * @returns the result of the validation.
1851 */
1852function CfnService_PlacementStrategyPropertyValidator(properties) {
1853 if (!cdk.canInspect(properties)) {
1854 return cdk.VALIDATION_SUCCESS;
1855 }
1856 const errors = new cdk.ValidationResults();
1857 if (typeof properties !== 'object') {
1858 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1859 }
1860 errors.collect(cdk.propertyValidator('field', cdk.validateString)(properties.field));
1861 errors.collect(cdk.propertyValidator('type', cdk.requiredValidator)(properties.type));
1862 errors.collect(cdk.propertyValidator('type', cdk.validateString)(properties.type));
1863 return errors.wrap('supplied properties not correct for "PlacementStrategyProperty"');
1864}
1865/**
1866 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service.PlacementStrategy` resource
1867 *
1868 * @param properties - the TypeScript properties of a `PlacementStrategyProperty`
1869 *
1870 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service.PlacementStrategy` resource.
1871 */
1872// @ts-ignore TS6133
1873function cfnServicePlacementStrategyPropertyToCloudFormation(properties) {
1874 if (!cdk.canInspect(properties)) {
1875 return properties;
1876 }
1877 CfnService_PlacementStrategyPropertyValidator(properties).assertSuccess();
1878 return {
1879 Field: cdk.stringToCloudFormation(properties.field),
1880 Type: cdk.stringToCloudFormation(properties.type),
1881 };
1882}
1883// @ts-ignore TS6133
1884function CfnServicePlacementStrategyPropertyFromCloudFormation(properties) {
1885 if (cdk.isResolvableObject(properties)) {
1886 return new cfn_parse.FromCloudFormationResult(properties);
1887 }
1888 properties = properties == null ? {} : properties;
1889 if (typeof properties !== 'object') {
1890 return new cfn_parse.FromCloudFormationResult(properties);
1891 }
1892 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1893 ret.addPropertyResult('field', 'Field', properties.Field != null ? cfn_parse.FromCloudFormation.getString(properties.Field) : undefined);
1894 ret.addPropertyResult('type', 'Type', cfn_parse.FromCloudFormation.getString(properties.Type));
1895 ret.addUnrecognizedPropertiesAsExtra(properties);
1896 return ret;
1897}
1898/**
1899 * Determine whether the given properties match those of a `SecretProperty`
1900 *
1901 * @param properties - the TypeScript properties of a `SecretProperty`
1902 *
1903 * @returns the result of the validation.
1904 */
1905function CfnService_SecretPropertyValidator(properties) {
1906 if (!cdk.canInspect(properties)) {
1907 return cdk.VALIDATION_SUCCESS;
1908 }
1909 const errors = new cdk.ValidationResults();
1910 if (typeof properties !== 'object') {
1911 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1912 }
1913 errors.collect(cdk.propertyValidator('name', cdk.requiredValidator)(properties.name));
1914 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
1915 errors.collect(cdk.propertyValidator('valueFrom', cdk.requiredValidator)(properties.valueFrom));
1916 errors.collect(cdk.propertyValidator('valueFrom', cdk.validateString)(properties.valueFrom));
1917 return errors.wrap('supplied properties not correct for "SecretProperty"');
1918}
1919/**
1920 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service.Secret` resource
1921 *
1922 * @param properties - the TypeScript properties of a `SecretProperty`
1923 *
1924 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service.Secret` resource.
1925 */
1926// @ts-ignore TS6133
1927function cfnServiceSecretPropertyToCloudFormation(properties) {
1928 if (!cdk.canInspect(properties)) {
1929 return properties;
1930 }
1931 CfnService_SecretPropertyValidator(properties).assertSuccess();
1932 return {
1933 Name: cdk.stringToCloudFormation(properties.name),
1934 ValueFrom: cdk.stringToCloudFormation(properties.valueFrom),
1935 };
1936}
1937// @ts-ignore TS6133
1938function CfnServiceSecretPropertyFromCloudFormation(properties) {
1939 if (cdk.isResolvableObject(properties)) {
1940 return new cfn_parse.FromCloudFormationResult(properties);
1941 }
1942 properties = properties == null ? {} : properties;
1943 if (typeof properties !== 'object') {
1944 return new cfn_parse.FromCloudFormationResult(properties);
1945 }
1946 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1947 ret.addPropertyResult('name', 'Name', cfn_parse.FromCloudFormation.getString(properties.Name));
1948 ret.addPropertyResult('valueFrom', 'ValueFrom', cfn_parse.FromCloudFormation.getString(properties.ValueFrom));
1949 ret.addUnrecognizedPropertiesAsExtra(properties);
1950 return ret;
1951}
1952/**
1953 * Determine whether the given properties match those of a `ServiceConnectClientAliasProperty`
1954 *
1955 * @param properties - the TypeScript properties of a `ServiceConnectClientAliasProperty`
1956 *
1957 * @returns the result of the validation.
1958 */
1959function CfnService_ServiceConnectClientAliasPropertyValidator(properties) {
1960 if (!cdk.canInspect(properties)) {
1961 return cdk.VALIDATION_SUCCESS;
1962 }
1963 const errors = new cdk.ValidationResults();
1964 if (typeof properties !== 'object') {
1965 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1966 }
1967 errors.collect(cdk.propertyValidator('dnsName', cdk.validateString)(properties.dnsName));
1968 errors.collect(cdk.propertyValidator('port', cdk.requiredValidator)(properties.port));
1969 errors.collect(cdk.propertyValidator('port', cdk.validateNumber)(properties.port));
1970 return errors.wrap('supplied properties not correct for "ServiceConnectClientAliasProperty"');
1971}
1972/**
1973 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service.ServiceConnectClientAlias` resource
1974 *
1975 * @param properties - the TypeScript properties of a `ServiceConnectClientAliasProperty`
1976 *
1977 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service.ServiceConnectClientAlias` resource.
1978 */
1979// @ts-ignore TS6133
1980function cfnServiceServiceConnectClientAliasPropertyToCloudFormation(properties) {
1981 if (!cdk.canInspect(properties)) {
1982 return properties;
1983 }
1984 CfnService_ServiceConnectClientAliasPropertyValidator(properties).assertSuccess();
1985 return {
1986 DnsName: cdk.stringToCloudFormation(properties.dnsName),
1987 Port: cdk.numberToCloudFormation(properties.port),
1988 };
1989}
1990// @ts-ignore TS6133
1991function CfnServiceServiceConnectClientAliasPropertyFromCloudFormation(properties) {
1992 if (cdk.isResolvableObject(properties)) {
1993 return new cfn_parse.FromCloudFormationResult(properties);
1994 }
1995 properties = properties == null ? {} : properties;
1996 if (typeof properties !== 'object') {
1997 return new cfn_parse.FromCloudFormationResult(properties);
1998 }
1999 const ret = new cfn_parse.FromCloudFormationPropertyObject();
2000 ret.addPropertyResult('dnsName', 'DnsName', properties.DnsName != null ? cfn_parse.FromCloudFormation.getString(properties.DnsName) : undefined);
2001 ret.addPropertyResult('port', 'Port', cfn_parse.FromCloudFormation.getNumber(properties.Port));
2002 ret.addUnrecognizedPropertiesAsExtra(properties);
2003 return ret;
2004}
2005/**
2006 * Determine whether the given properties match those of a `ServiceConnectConfigurationProperty`
2007 *
2008 * @param properties - the TypeScript properties of a `ServiceConnectConfigurationProperty`
2009 *
2010 * @returns the result of the validation.
2011 */
2012function CfnService_ServiceConnectConfigurationPropertyValidator(properties) {
2013 if (!cdk.canInspect(properties)) {
2014 return cdk.VALIDATION_SUCCESS;
2015 }
2016 const errors = new cdk.ValidationResults();
2017 if (typeof properties !== 'object') {
2018 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
2019 }
2020 errors.collect(cdk.propertyValidator('enabled', cdk.requiredValidator)(properties.enabled));
2021 errors.collect(cdk.propertyValidator('enabled', cdk.validateBoolean)(properties.enabled));
2022 errors.collect(cdk.propertyValidator('logConfiguration', CfnService_LogConfigurationPropertyValidator)(properties.logConfiguration));
2023 errors.collect(cdk.propertyValidator('namespace', cdk.validateString)(properties.namespace));
2024 errors.collect(cdk.propertyValidator('services', cdk.listValidator(CfnService_ServiceConnectServicePropertyValidator))(properties.services));
2025 return errors.wrap('supplied properties not correct for "ServiceConnectConfigurationProperty"');
2026}
2027/**
2028 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service.ServiceConnectConfiguration` resource
2029 *
2030 * @param properties - the TypeScript properties of a `ServiceConnectConfigurationProperty`
2031 *
2032 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service.ServiceConnectConfiguration` resource.
2033 */
2034// @ts-ignore TS6133
2035function cfnServiceServiceConnectConfigurationPropertyToCloudFormation(properties) {
2036 if (!cdk.canInspect(properties)) {
2037 return properties;
2038 }
2039 CfnService_ServiceConnectConfigurationPropertyValidator(properties).assertSuccess();
2040 return {
2041 Enabled: cdk.booleanToCloudFormation(properties.enabled),
2042 LogConfiguration: cfnServiceLogConfigurationPropertyToCloudFormation(properties.logConfiguration),
2043 Namespace: cdk.stringToCloudFormation(properties.namespace),
2044 Services: cdk.listMapper(cfnServiceServiceConnectServicePropertyToCloudFormation)(properties.services),
2045 };
2046}
2047// @ts-ignore TS6133
2048function CfnServiceServiceConnectConfigurationPropertyFromCloudFormation(properties) {
2049 if (cdk.isResolvableObject(properties)) {
2050 return new cfn_parse.FromCloudFormationResult(properties);
2051 }
2052 properties = properties == null ? {} : properties;
2053 if (typeof properties !== 'object') {
2054 return new cfn_parse.FromCloudFormationResult(properties);
2055 }
2056 const ret = new cfn_parse.FromCloudFormationPropertyObject();
2057 ret.addPropertyResult('enabled', 'Enabled', cfn_parse.FromCloudFormation.getBoolean(properties.Enabled));
2058 ret.addPropertyResult('logConfiguration', 'LogConfiguration', properties.LogConfiguration != null ? CfnServiceLogConfigurationPropertyFromCloudFormation(properties.LogConfiguration) : undefined);
2059 ret.addPropertyResult('namespace', 'Namespace', properties.Namespace != null ? cfn_parse.FromCloudFormation.getString(properties.Namespace) : undefined);
2060 ret.addPropertyResult('services', 'Services', properties.Services != null ? cfn_parse.FromCloudFormation.getArray(CfnServiceServiceConnectServicePropertyFromCloudFormation)(properties.Services) : undefined);
2061 ret.addUnrecognizedPropertiesAsExtra(properties);
2062 return ret;
2063}
2064/**
2065 * Determine whether the given properties match those of a `ServiceConnectServiceProperty`
2066 *
2067 * @param properties - the TypeScript properties of a `ServiceConnectServiceProperty`
2068 *
2069 * @returns the result of the validation.
2070 */
2071function CfnService_ServiceConnectServicePropertyValidator(properties) {
2072 if (!cdk.canInspect(properties)) {
2073 return cdk.VALIDATION_SUCCESS;
2074 }
2075 const errors = new cdk.ValidationResults();
2076 if (typeof properties !== 'object') {
2077 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
2078 }
2079 errors.collect(cdk.propertyValidator('clientAliases', cdk.listValidator(CfnService_ServiceConnectClientAliasPropertyValidator))(properties.clientAliases));
2080 errors.collect(cdk.propertyValidator('discoveryName', cdk.validateString)(properties.discoveryName));
2081 errors.collect(cdk.propertyValidator('ingressPortOverride', cdk.validateNumber)(properties.ingressPortOverride));
2082 errors.collect(cdk.propertyValidator('portName', cdk.requiredValidator)(properties.portName));
2083 errors.collect(cdk.propertyValidator('portName', cdk.validateString)(properties.portName));
2084 return errors.wrap('supplied properties not correct for "ServiceConnectServiceProperty"');
2085}
2086/**
2087 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service.ServiceConnectService` resource
2088 *
2089 * @param properties - the TypeScript properties of a `ServiceConnectServiceProperty`
2090 *
2091 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service.ServiceConnectService` resource.
2092 */
2093// @ts-ignore TS6133
2094function cfnServiceServiceConnectServicePropertyToCloudFormation(properties) {
2095 if (!cdk.canInspect(properties)) {
2096 return properties;
2097 }
2098 CfnService_ServiceConnectServicePropertyValidator(properties).assertSuccess();
2099 return {
2100 ClientAliases: cdk.listMapper(cfnServiceServiceConnectClientAliasPropertyToCloudFormation)(properties.clientAliases),
2101 DiscoveryName: cdk.stringToCloudFormation(properties.discoveryName),
2102 IngressPortOverride: cdk.numberToCloudFormation(properties.ingressPortOverride),
2103 PortName: cdk.stringToCloudFormation(properties.portName),
2104 };
2105}
2106// @ts-ignore TS6133
2107function CfnServiceServiceConnectServicePropertyFromCloudFormation(properties) {
2108 if (cdk.isResolvableObject(properties)) {
2109 return new cfn_parse.FromCloudFormationResult(properties);
2110 }
2111 properties = properties == null ? {} : properties;
2112 if (typeof properties !== 'object') {
2113 return new cfn_parse.FromCloudFormationResult(properties);
2114 }
2115 const ret = new cfn_parse.FromCloudFormationPropertyObject();
2116 ret.addPropertyResult('clientAliases', 'ClientAliases', properties.ClientAliases != null ? cfn_parse.FromCloudFormation.getArray(CfnServiceServiceConnectClientAliasPropertyFromCloudFormation)(properties.ClientAliases) : undefined);
2117 ret.addPropertyResult('discoveryName', 'DiscoveryName', properties.DiscoveryName != null ? cfn_parse.FromCloudFormation.getString(properties.DiscoveryName) : undefined);
2118 ret.addPropertyResult('ingressPortOverride', 'IngressPortOverride', properties.IngressPortOverride != null ? cfn_parse.FromCloudFormation.getNumber(properties.IngressPortOverride) : undefined);
2119 ret.addPropertyResult('portName', 'PortName', cfn_parse.FromCloudFormation.getString(properties.PortName));
2120 ret.addUnrecognizedPropertiesAsExtra(properties);
2121 return ret;
2122}
2123/**
2124 * Determine whether the given properties match those of a `ServiceRegistryProperty`
2125 *
2126 * @param properties - the TypeScript properties of a `ServiceRegistryProperty`
2127 *
2128 * @returns the result of the validation.
2129 */
2130function CfnService_ServiceRegistryPropertyValidator(properties) {
2131 if (!cdk.canInspect(properties)) {
2132 return cdk.VALIDATION_SUCCESS;
2133 }
2134 const errors = new cdk.ValidationResults();
2135 if (typeof properties !== 'object') {
2136 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
2137 }
2138 errors.collect(cdk.propertyValidator('containerName', cdk.validateString)(properties.containerName));
2139 errors.collect(cdk.propertyValidator('containerPort', cdk.validateNumber)(properties.containerPort));
2140 errors.collect(cdk.propertyValidator('port', cdk.validateNumber)(properties.port));
2141 errors.collect(cdk.propertyValidator('registryArn', cdk.validateString)(properties.registryArn));
2142 return errors.wrap('supplied properties not correct for "ServiceRegistryProperty"');
2143}
2144/**
2145 * Renders the AWS CloudFormation properties of an `AWS::ECS::Service.ServiceRegistry` resource
2146 *
2147 * @param properties - the TypeScript properties of a `ServiceRegistryProperty`
2148 *
2149 * @returns the AWS CloudFormation properties of an `AWS::ECS::Service.ServiceRegistry` resource.
2150 */
2151// @ts-ignore TS6133
2152function cfnServiceServiceRegistryPropertyToCloudFormation(properties) {
2153 if (!cdk.canInspect(properties)) {
2154 return properties;
2155 }
2156 CfnService_ServiceRegistryPropertyValidator(properties).assertSuccess();
2157 return {
2158 ContainerName: cdk.stringToCloudFormation(properties.containerName),
2159 ContainerPort: cdk.numberToCloudFormation(properties.containerPort),
2160 Port: cdk.numberToCloudFormation(properties.port),
2161 RegistryArn: cdk.stringToCloudFormation(properties.registryArn),
2162 };
2163}
2164// @ts-ignore TS6133
2165function CfnServiceServiceRegistryPropertyFromCloudFormation(properties) {
2166 if (cdk.isResolvableObject(properties)) {
2167 return new cfn_parse.FromCloudFormationResult(properties);
2168 }
2169 properties = properties == null ? {} : properties;
2170 if (typeof properties !== 'object') {
2171 return new cfn_parse.FromCloudFormationResult(properties);
2172 }
2173 const ret = new cfn_parse.FromCloudFormationPropertyObject();
2174 ret.addPropertyResult('containerName', 'ContainerName', properties.ContainerName != null ? cfn_parse.FromCloudFormation.getString(properties.ContainerName) : undefined);
2175 ret.addPropertyResult('containerPort', 'ContainerPort', properties.ContainerPort != null ? cfn_parse.FromCloudFormation.getNumber(properties.ContainerPort) : undefined);
2176 ret.addPropertyResult('port', 'Port', properties.Port != null ? cfn_parse.FromCloudFormation.getNumber(properties.Port) : undefined);
2177 ret.addPropertyResult('registryArn', 'RegistryArn', properties.RegistryArn != null ? cfn_parse.FromCloudFormation.getString(properties.RegistryArn) : undefined);
2178 ret.addUnrecognizedPropertiesAsExtra(properties);
2179 return ret;
2180}
2181/**
2182 * Determine whether the given properties match those of a `CfnTaskDefinitionProps`
2183 *
2184 * @param properties - the TypeScript properties of a `CfnTaskDefinitionProps`
2185 *
2186 * @returns the result of the validation.
2187 */
2188function CfnTaskDefinitionPropsValidator(properties) {
2189 if (!cdk.canInspect(properties)) {
2190 return cdk.VALIDATION_SUCCESS;
2191 }
2192 const errors = new cdk.ValidationResults();
2193 if (typeof properties !== 'object') {
2194 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
2195 }
2196 errors.collect(cdk.propertyValidator('containerDefinitions', cdk.listValidator(CfnTaskDefinition_ContainerDefinitionPropertyValidator))(properties.containerDefinitions));
2197 errors.collect(cdk.propertyValidator('cpu', cdk.validateString)(properties.cpu));
2198 errors.collect(cdk.propertyValidator('ephemeralStorage', CfnTaskDefinition_EphemeralStoragePropertyValidator)(properties.ephemeralStorage));
2199 errors.collect(cdk.propertyValidator('executionRoleArn', cdk.validateString)(properties.executionRoleArn));
2200 errors.collect(cdk.propertyValidator('family', cdk.validateString)(properties.family));
2201 errors.collect(cdk.propertyValidator('inferenceAccelerators', cdk.listValidator(CfnTaskDefinition_InferenceAcceleratorPropertyValidator))(properties.inferenceAccelerators));
2202 errors.collect(cdk.propertyValidator('ipcMode', cdk.validateString)(properties.ipcMode));
2203 errors.collect(cdk.propertyValidator('memory', cdk.validateString)(properties.memory));
2204 errors.collect(cdk.propertyValidator('networkMode', cdk.validateString)(properties.networkMode));
2205 errors.collect(cdk.propertyValidator('pidMode', cdk.validateString)(properties.pidMode));
2206 errors.collect(cdk.propertyValidator('placementConstraints', cdk.listValidator(CfnTaskDefinition_TaskDefinitionPlacementConstraintPropertyValidator))(properties.placementConstraints));
2207 errors.collect(cdk.propertyValidator('proxyConfiguration', CfnTaskDefinition_ProxyConfigurationPropertyValidator)(properties.proxyConfiguration));
2208 errors.collect(cdk.propertyValidator('requiresCompatibilities', cdk.listValidator(cdk.validateString))(properties.requiresCompatibilities));
2209 errors.collect(cdk.propertyValidator('runtimePlatform', CfnTaskDefinition_RuntimePlatformPropertyValidator)(properties.runtimePlatform));
2210 errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
2211 errors.collect(cdk.propertyValidator('taskRoleArn', cdk.validateString)(properties.taskRoleArn));
2212 errors.collect(cdk.propertyValidator('volumes', cdk.listValidator(CfnTaskDefinition_VolumePropertyValidator))(properties.volumes));
2213 return errors.wrap('supplied properties not correct for "CfnTaskDefinitionProps"');
2214}
2215/**
2216 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition` resource
2217 *
2218 * @param properties - the TypeScript properties of a `CfnTaskDefinitionProps`
2219 *
2220 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition` resource.
2221 */
2222// @ts-ignore TS6133
2223function cfnTaskDefinitionPropsToCloudFormation(properties) {
2224 if (!cdk.canInspect(properties)) {
2225 return properties;
2226 }
2227 CfnTaskDefinitionPropsValidator(properties).assertSuccess();
2228 return {
2229 ContainerDefinitions: cdk.listMapper(cfnTaskDefinitionContainerDefinitionPropertyToCloudFormation)(properties.containerDefinitions),
2230 Cpu: cdk.stringToCloudFormation(properties.cpu),
2231 EphemeralStorage: cfnTaskDefinitionEphemeralStoragePropertyToCloudFormation(properties.ephemeralStorage),
2232 ExecutionRoleArn: cdk.stringToCloudFormation(properties.executionRoleArn),
2233 Family: cdk.stringToCloudFormation(properties.family),
2234 InferenceAccelerators: cdk.listMapper(cfnTaskDefinitionInferenceAcceleratorPropertyToCloudFormation)(properties.inferenceAccelerators),
2235 IpcMode: cdk.stringToCloudFormation(properties.ipcMode),
2236 Memory: cdk.stringToCloudFormation(properties.memory),
2237 NetworkMode: cdk.stringToCloudFormation(properties.networkMode),
2238 PidMode: cdk.stringToCloudFormation(properties.pidMode),
2239 PlacementConstraints: cdk.listMapper(cfnTaskDefinitionTaskDefinitionPlacementConstraintPropertyToCloudFormation)(properties.placementConstraints),
2240 ProxyConfiguration: cfnTaskDefinitionProxyConfigurationPropertyToCloudFormation(properties.proxyConfiguration),
2241 RequiresCompatibilities: cdk.listMapper(cdk.stringToCloudFormation)(properties.requiresCompatibilities),
2242 RuntimePlatform: cfnTaskDefinitionRuntimePlatformPropertyToCloudFormation(properties.runtimePlatform),
2243 Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
2244 TaskRoleArn: cdk.stringToCloudFormation(properties.taskRoleArn),
2245 Volumes: cdk.listMapper(cfnTaskDefinitionVolumePropertyToCloudFormation)(properties.volumes),
2246 };
2247}
2248// @ts-ignore TS6133
2249function CfnTaskDefinitionPropsFromCloudFormation(properties) {
2250 properties = properties == null ? {} : properties;
2251 if (typeof properties !== 'object') {
2252 return new cfn_parse.FromCloudFormationResult(properties);
2253 }
2254 const ret = new cfn_parse.FromCloudFormationPropertyObject();
2255 ret.addPropertyResult('containerDefinitions', 'ContainerDefinitions', properties.ContainerDefinitions != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionContainerDefinitionPropertyFromCloudFormation)(properties.ContainerDefinitions) : undefined);
2256 ret.addPropertyResult('cpu', 'Cpu', properties.Cpu != null ? cfn_parse.FromCloudFormation.getString(properties.Cpu) : undefined);
2257 ret.addPropertyResult('ephemeralStorage', 'EphemeralStorage', properties.EphemeralStorage != null ? CfnTaskDefinitionEphemeralStoragePropertyFromCloudFormation(properties.EphemeralStorage) : undefined);
2258 ret.addPropertyResult('executionRoleArn', 'ExecutionRoleArn', properties.ExecutionRoleArn != null ? cfn_parse.FromCloudFormation.getString(properties.ExecutionRoleArn) : undefined);
2259 ret.addPropertyResult('family', 'Family', properties.Family != null ? cfn_parse.FromCloudFormation.getString(properties.Family) : undefined);
2260 ret.addPropertyResult('inferenceAccelerators', 'InferenceAccelerators', properties.InferenceAccelerators != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionInferenceAcceleratorPropertyFromCloudFormation)(properties.InferenceAccelerators) : undefined);
2261 ret.addPropertyResult('ipcMode', 'IpcMode', properties.IpcMode != null ? cfn_parse.FromCloudFormation.getString(properties.IpcMode) : undefined);
2262 ret.addPropertyResult('memory', 'Memory', properties.Memory != null ? cfn_parse.FromCloudFormation.getString(properties.Memory) : undefined);
2263 ret.addPropertyResult('networkMode', 'NetworkMode', properties.NetworkMode != null ? cfn_parse.FromCloudFormation.getString(properties.NetworkMode) : undefined);
2264 ret.addPropertyResult('pidMode', 'PidMode', properties.PidMode != null ? cfn_parse.FromCloudFormation.getString(properties.PidMode) : undefined);
2265 ret.addPropertyResult('placementConstraints', 'PlacementConstraints', properties.PlacementConstraints != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionTaskDefinitionPlacementConstraintPropertyFromCloudFormation)(properties.PlacementConstraints) : undefined);
2266 ret.addPropertyResult('proxyConfiguration', 'ProxyConfiguration', properties.ProxyConfiguration != null ? CfnTaskDefinitionProxyConfigurationPropertyFromCloudFormation(properties.ProxyConfiguration) : undefined);
2267 ret.addPropertyResult('requiresCompatibilities', 'RequiresCompatibilities', properties.RequiresCompatibilities != null ? cfn_parse.FromCloudFormation.getStringArray(properties.RequiresCompatibilities) : undefined);
2268 ret.addPropertyResult('runtimePlatform', 'RuntimePlatform', properties.RuntimePlatform != null ? CfnTaskDefinitionRuntimePlatformPropertyFromCloudFormation(properties.RuntimePlatform) : undefined);
2269 ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
2270 ret.addPropertyResult('taskRoleArn', 'TaskRoleArn', properties.TaskRoleArn != null ? cfn_parse.FromCloudFormation.getString(properties.TaskRoleArn) : undefined);
2271 ret.addPropertyResult('volumes', 'Volumes', properties.Volumes != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionVolumePropertyFromCloudFormation)(properties.Volumes) : undefined);
2272 ret.addUnrecognizedPropertiesAsExtra(properties);
2273 return ret;
2274}
2275/**
2276 * A CloudFormation `AWS::ECS::TaskDefinition`
2277 *
2278 * The details of a task definition which describes the container and volume definitions of an Amazon Elastic Container Service task. You can specify which Docker images to use, the required resources, and other configurations related to launching the task definition through an Amazon ECS service or task.
2279 *
2280 * @cloudformationResource AWS::ECS::TaskDefinition
2281 * @stability external
2282 *
2283 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html
2284 */
2285class CfnTaskDefinition extends cdk.CfnResource {
2286 /**
2287 * Create a new `AWS::ECS::TaskDefinition`.
2288 *
2289 * @param scope - scope in which this resource is defined
2290 * @param id - scoped id of the resource
2291 * @param props - resource properties
2292 */
2293 constructor(scope, id, props = {}) {
2294 super(scope, id, { type: CfnTaskDefinition.CFN_RESOURCE_TYPE_NAME, properties: props });
2295 try {
2296 jsiiDeprecationWarnings._aws_cdk_aws_ecs_CfnTaskDefinitionProps(props);
2297 }
2298 catch (error) {
2299 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
2300 Error.captureStackTrace(error, CfnTaskDefinition);
2301 }
2302 throw error;
2303 }
2304 this.attrTaskDefinitionArn = cdk.Token.asString(this.getAtt('TaskDefinitionArn'));
2305 this.containerDefinitions = props.containerDefinitions;
2306 this.cpu = props.cpu;
2307 this.ephemeralStorage = props.ephemeralStorage;
2308 this.executionRoleArn = props.executionRoleArn;
2309 this.family = props.family;
2310 this.inferenceAccelerators = props.inferenceAccelerators;
2311 this.ipcMode = props.ipcMode;
2312 this.memory = props.memory;
2313 this.networkMode = props.networkMode;
2314 this.pidMode = props.pidMode;
2315 this.placementConstraints = props.placementConstraints;
2316 this.proxyConfiguration = props.proxyConfiguration;
2317 this.requiresCompatibilities = props.requiresCompatibilities;
2318 this.runtimePlatform = props.runtimePlatform;
2319 this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::ECS::TaskDefinition", props.tags, { tagPropertyName: 'tags' });
2320 this.taskRoleArn = props.taskRoleArn;
2321 this.volumes = props.volumes;
2322 }
2323 /**
2324 * A factory method that creates a new instance of this class from an object
2325 * containing the CloudFormation properties of this resource.
2326 * Used in the @aws-cdk/cloudformation-include module.
2327 *
2328 * @internal
2329 */
2330 static _fromCloudFormation(scope, id, resourceAttributes, options) {
2331 resourceAttributes = resourceAttributes || {};
2332 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
2333 const propsResult = CfnTaskDefinitionPropsFromCloudFormation(resourceProperties);
2334 const ret = new CfnTaskDefinition(scope, id, propsResult.value);
2335 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
2336 ret.addPropertyOverride(propKey, propVal);
2337 }
2338 options.parser.handleAttributes(ret, resourceAttributes, id);
2339 return ret;
2340 }
2341 /**
2342 * Examines the CloudFormation resource and discloses attributes.
2343 *
2344 * @param inspector - tree inspector to collect and process attributes
2345 *
2346 */
2347 inspect(inspector) {
2348 inspector.addAttribute("aws:cdk:cloudformation:type", CfnTaskDefinition.CFN_RESOURCE_TYPE_NAME);
2349 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
2350 }
2351 get cfnProperties() {
2352 return {
2353 containerDefinitions: this.containerDefinitions,
2354 cpu: this.cpu,
2355 ephemeralStorage: this.ephemeralStorage,
2356 executionRoleArn: this.executionRoleArn,
2357 family: this.family,
2358 inferenceAccelerators: this.inferenceAccelerators,
2359 ipcMode: this.ipcMode,
2360 memory: this.memory,
2361 networkMode: this.networkMode,
2362 pidMode: this.pidMode,
2363 placementConstraints: this.placementConstraints,
2364 proxyConfiguration: this.proxyConfiguration,
2365 requiresCompatibilities: this.requiresCompatibilities,
2366 runtimePlatform: this.runtimePlatform,
2367 tags: this.tags.renderTags(),
2368 taskRoleArn: this.taskRoleArn,
2369 volumes: this.volumes,
2370 };
2371 }
2372 renderProperties(props) {
2373 return cfnTaskDefinitionPropsToCloudFormation(props);
2374 }
2375}
2376exports.CfnTaskDefinition = CfnTaskDefinition;
2377_f = JSII_RTTI_SYMBOL_1;
2378CfnTaskDefinition[_f] = { fqn: "@aws-cdk/aws-ecs.CfnTaskDefinition", version: "1.204.0" };
2379/**
2380 * The CloudFormation resource type name for this resource class.
2381 */
2382CfnTaskDefinition.CFN_RESOURCE_TYPE_NAME = "AWS::ECS::TaskDefinition";
2383/**
2384 * Determine whether the given properties match those of a `AuthorizationConfigProperty`
2385 *
2386 * @param properties - the TypeScript properties of a `AuthorizationConfigProperty`
2387 *
2388 * @returns the result of the validation.
2389 */
2390function CfnTaskDefinition_AuthorizationConfigPropertyValidator(properties) {
2391 if (!cdk.canInspect(properties)) {
2392 return cdk.VALIDATION_SUCCESS;
2393 }
2394 const errors = new cdk.ValidationResults();
2395 if (typeof properties !== 'object') {
2396 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
2397 }
2398 errors.collect(cdk.propertyValidator('accessPointId', cdk.validateString)(properties.accessPointId));
2399 errors.collect(cdk.propertyValidator('iam', cdk.validateString)(properties.iam));
2400 return errors.wrap('supplied properties not correct for "AuthorizationConfigProperty"');
2401}
2402/**
2403 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.AuthorizationConfig` resource
2404 *
2405 * @param properties - the TypeScript properties of a `AuthorizationConfigProperty`
2406 *
2407 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.AuthorizationConfig` resource.
2408 */
2409// @ts-ignore TS6133
2410function cfnTaskDefinitionAuthorizationConfigPropertyToCloudFormation(properties) {
2411 if (!cdk.canInspect(properties)) {
2412 return properties;
2413 }
2414 CfnTaskDefinition_AuthorizationConfigPropertyValidator(properties).assertSuccess();
2415 return {
2416 AccessPointId: cdk.stringToCloudFormation(properties.accessPointId),
2417 IAM: cdk.stringToCloudFormation(properties.iam),
2418 };
2419}
2420// @ts-ignore TS6133
2421function CfnTaskDefinitionAuthorizationConfigPropertyFromCloudFormation(properties) {
2422 if (cdk.isResolvableObject(properties)) {
2423 return new cfn_parse.FromCloudFormationResult(properties);
2424 }
2425 properties = properties == null ? {} : properties;
2426 if (typeof properties !== 'object') {
2427 return new cfn_parse.FromCloudFormationResult(properties);
2428 }
2429 const ret = new cfn_parse.FromCloudFormationPropertyObject();
2430 ret.addPropertyResult('accessPointId', 'AccessPointId', properties.AccessPointId != null ? cfn_parse.FromCloudFormation.getString(properties.AccessPointId) : undefined);
2431 ret.addPropertyResult('iam', 'IAM', properties.IAM != null ? cfn_parse.FromCloudFormation.getString(properties.IAM) : undefined);
2432 ret.addUnrecognizedPropertiesAsExtra(properties);
2433 return ret;
2434}
2435/**
2436 * Determine whether the given properties match those of a `ContainerDefinitionProperty`
2437 *
2438 * @param properties - the TypeScript properties of a `ContainerDefinitionProperty`
2439 *
2440 * @returns the result of the validation.
2441 */
2442function CfnTaskDefinition_ContainerDefinitionPropertyValidator(properties) {
2443 if (!cdk.canInspect(properties)) {
2444 return cdk.VALIDATION_SUCCESS;
2445 }
2446 const errors = new cdk.ValidationResults();
2447 if (typeof properties !== 'object') {
2448 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
2449 }
2450 errors.collect(cdk.propertyValidator('command', cdk.listValidator(cdk.validateString))(properties.command));
2451 errors.collect(cdk.propertyValidator('cpu', cdk.validateNumber)(properties.cpu));
2452 errors.collect(cdk.propertyValidator('dependsOn', cdk.listValidator(CfnTaskDefinition_ContainerDependencyPropertyValidator))(properties.dependsOn));
2453 errors.collect(cdk.propertyValidator('disableNetworking', cdk.validateBoolean)(properties.disableNetworking));
2454 errors.collect(cdk.propertyValidator('dnsSearchDomains', cdk.listValidator(cdk.validateString))(properties.dnsSearchDomains));
2455 errors.collect(cdk.propertyValidator('dnsServers', cdk.listValidator(cdk.validateString))(properties.dnsServers));
2456 errors.collect(cdk.propertyValidator('dockerLabels', cdk.hashValidator(cdk.validateString))(properties.dockerLabels));
2457 errors.collect(cdk.propertyValidator('dockerSecurityOptions', cdk.listValidator(cdk.validateString))(properties.dockerSecurityOptions));
2458 errors.collect(cdk.propertyValidator('entryPoint', cdk.listValidator(cdk.validateString))(properties.entryPoint));
2459 errors.collect(cdk.propertyValidator('environment', cdk.listValidator(CfnTaskDefinition_KeyValuePairPropertyValidator))(properties.environment));
2460 errors.collect(cdk.propertyValidator('environmentFiles', cdk.listValidator(CfnTaskDefinition_EnvironmentFilePropertyValidator))(properties.environmentFiles));
2461 errors.collect(cdk.propertyValidator('essential', cdk.validateBoolean)(properties.essential));
2462 errors.collect(cdk.propertyValidator('extraHosts', cdk.listValidator(CfnTaskDefinition_HostEntryPropertyValidator))(properties.extraHosts));
2463 errors.collect(cdk.propertyValidator('firelensConfiguration', CfnTaskDefinition_FirelensConfigurationPropertyValidator)(properties.firelensConfiguration));
2464 errors.collect(cdk.propertyValidator('healthCheck', CfnTaskDefinition_HealthCheckPropertyValidator)(properties.healthCheck));
2465 errors.collect(cdk.propertyValidator('hostname', cdk.validateString)(properties.hostname));
2466 errors.collect(cdk.propertyValidator('image', cdk.requiredValidator)(properties.image));
2467 errors.collect(cdk.propertyValidator('image', cdk.validateString)(properties.image));
2468 errors.collect(cdk.propertyValidator('interactive', cdk.validateBoolean)(properties.interactive));
2469 errors.collect(cdk.propertyValidator('links', cdk.listValidator(cdk.validateString))(properties.links));
2470 errors.collect(cdk.propertyValidator('linuxParameters', CfnTaskDefinition_LinuxParametersPropertyValidator)(properties.linuxParameters));
2471 errors.collect(cdk.propertyValidator('logConfiguration', CfnTaskDefinition_LogConfigurationPropertyValidator)(properties.logConfiguration));
2472 errors.collect(cdk.propertyValidator('memory', cdk.validateNumber)(properties.memory));
2473 errors.collect(cdk.propertyValidator('memoryReservation', cdk.validateNumber)(properties.memoryReservation));
2474 errors.collect(cdk.propertyValidator('mountPoints', cdk.listValidator(CfnTaskDefinition_MountPointPropertyValidator))(properties.mountPoints));
2475 errors.collect(cdk.propertyValidator('name', cdk.requiredValidator)(properties.name));
2476 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
2477 errors.collect(cdk.propertyValidator('portMappings', cdk.listValidator(CfnTaskDefinition_PortMappingPropertyValidator))(properties.portMappings));
2478 errors.collect(cdk.propertyValidator('privileged', cdk.validateBoolean)(properties.privileged));
2479 errors.collect(cdk.propertyValidator('pseudoTerminal', cdk.validateBoolean)(properties.pseudoTerminal));
2480 errors.collect(cdk.propertyValidator('readonlyRootFilesystem', cdk.validateBoolean)(properties.readonlyRootFilesystem));
2481 errors.collect(cdk.propertyValidator('repositoryCredentials', CfnTaskDefinition_RepositoryCredentialsPropertyValidator)(properties.repositoryCredentials));
2482 errors.collect(cdk.propertyValidator('resourceRequirements', cdk.listValidator(CfnTaskDefinition_ResourceRequirementPropertyValidator))(properties.resourceRequirements));
2483 errors.collect(cdk.propertyValidator('secrets', cdk.listValidator(CfnTaskDefinition_SecretPropertyValidator))(properties.secrets));
2484 errors.collect(cdk.propertyValidator('startTimeout', cdk.validateNumber)(properties.startTimeout));
2485 errors.collect(cdk.propertyValidator('stopTimeout', cdk.validateNumber)(properties.stopTimeout));
2486 errors.collect(cdk.propertyValidator('systemControls', cdk.listValidator(CfnTaskDefinition_SystemControlPropertyValidator))(properties.systemControls));
2487 errors.collect(cdk.propertyValidator('ulimits', cdk.listValidator(CfnTaskDefinition_UlimitPropertyValidator))(properties.ulimits));
2488 errors.collect(cdk.propertyValidator('user', cdk.validateString)(properties.user));
2489 errors.collect(cdk.propertyValidator('volumesFrom', cdk.listValidator(CfnTaskDefinition_VolumeFromPropertyValidator))(properties.volumesFrom));
2490 errors.collect(cdk.propertyValidator('workingDirectory', cdk.validateString)(properties.workingDirectory));
2491 return errors.wrap('supplied properties not correct for "ContainerDefinitionProperty"');
2492}
2493/**
2494 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.ContainerDefinition` resource
2495 *
2496 * @param properties - the TypeScript properties of a `ContainerDefinitionProperty`
2497 *
2498 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.ContainerDefinition` resource.
2499 */
2500// @ts-ignore TS6133
2501function cfnTaskDefinitionContainerDefinitionPropertyToCloudFormation(properties) {
2502 if (!cdk.canInspect(properties)) {
2503 return properties;
2504 }
2505 CfnTaskDefinition_ContainerDefinitionPropertyValidator(properties).assertSuccess();
2506 return {
2507 Command: cdk.listMapper(cdk.stringToCloudFormation)(properties.command),
2508 Cpu: cdk.numberToCloudFormation(properties.cpu),
2509 DependsOn: cdk.listMapper(cfnTaskDefinitionContainerDependencyPropertyToCloudFormation)(properties.dependsOn),
2510 DisableNetworking: cdk.booleanToCloudFormation(properties.disableNetworking),
2511 DnsSearchDomains: cdk.listMapper(cdk.stringToCloudFormation)(properties.dnsSearchDomains),
2512 DnsServers: cdk.listMapper(cdk.stringToCloudFormation)(properties.dnsServers),
2513 DockerLabels: cdk.hashMapper(cdk.stringToCloudFormation)(properties.dockerLabels),
2514 DockerSecurityOptions: cdk.listMapper(cdk.stringToCloudFormation)(properties.dockerSecurityOptions),
2515 EntryPoint: cdk.listMapper(cdk.stringToCloudFormation)(properties.entryPoint),
2516 Environment: cdk.listMapper(cfnTaskDefinitionKeyValuePairPropertyToCloudFormation)(properties.environment),
2517 EnvironmentFiles: cdk.listMapper(cfnTaskDefinitionEnvironmentFilePropertyToCloudFormation)(properties.environmentFiles),
2518 Essential: cdk.booleanToCloudFormation(properties.essential),
2519 ExtraHosts: cdk.listMapper(cfnTaskDefinitionHostEntryPropertyToCloudFormation)(properties.extraHosts),
2520 FirelensConfiguration: cfnTaskDefinitionFirelensConfigurationPropertyToCloudFormation(properties.firelensConfiguration),
2521 HealthCheck: cfnTaskDefinitionHealthCheckPropertyToCloudFormation(properties.healthCheck),
2522 Hostname: cdk.stringToCloudFormation(properties.hostname),
2523 Image: cdk.stringToCloudFormation(properties.image),
2524 Interactive: cdk.booleanToCloudFormation(properties.interactive),
2525 Links: cdk.listMapper(cdk.stringToCloudFormation)(properties.links),
2526 LinuxParameters: cfnTaskDefinitionLinuxParametersPropertyToCloudFormation(properties.linuxParameters),
2527 LogConfiguration: cfnTaskDefinitionLogConfigurationPropertyToCloudFormation(properties.logConfiguration),
2528 Memory: cdk.numberToCloudFormation(properties.memory),
2529 MemoryReservation: cdk.numberToCloudFormation(properties.memoryReservation),
2530 MountPoints: cdk.listMapper(cfnTaskDefinitionMountPointPropertyToCloudFormation)(properties.mountPoints),
2531 Name: cdk.stringToCloudFormation(properties.name),
2532 PortMappings: cdk.listMapper(cfnTaskDefinitionPortMappingPropertyToCloudFormation)(properties.portMappings),
2533 Privileged: cdk.booleanToCloudFormation(properties.privileged),
2534 PseudoTerminal: cdk.booleanToCloudFormation(properties.pseudoTerminal),
2535 ReadonlyRootFilesystem: cdk.booleanToCloudFormation(properties.readonlyRootFilesystem),
2536 RepositoryCredentials: cfnTaskDefinitionRepositoryCredentialsPropertyToCloudFormation(properties.repositoryCredentials),
2537 ResourceRequirements: cdk.listMapper(cfnTaskDefinitionResourceRequirementPropertyToCloudFormation)(properties.resourceRequirements),
2538 Secrets: cdk.listMapper(cfnTaskDefinitionSecretPropertyToCloudFormation)(properties.secrets),
2539 StartTimeout: cdk.numberToCloudFormation(properties.startTimeout),
2540 StopTimeout: cdk.numberToCloudFormation(properties.stopTimeout),
2541 SystemControls: cdk.listMapper(cfnTaskDefinitionSystemControlPropertyToCloudFormation)(properties.systemControls),
2542 Ulimits: cdk.listMapper(cfnTaskDefinitionUlimitPropertyToCloudFormation)(properties.ulimits),
2543 User: cdk.stringToCloudFormation(properties.user),
2544 VolumesFrom: cdk.listMapper(cfnTaskDefinitionVolumeFromPropertyToCloudFormation)(properties.volumesFrom),
2545 WorkingDirectory: cdk.stringToCloudFormation(properties.workingDirectory),
2546 };
2547}
2548// @ts-ignore TS6133
2549function CfnTaskDefinitionContainerDefinitionPropertyFromCloudFormation(properties) {
2550 if (cdk.isResolvableObject(properties)) {
2551 return new cfn_parse.FromCloudFormationResult(properties);
2552 }
2553 properties = properties == null ? {} : properties;
2554 if (typeof properties !== 'object') {
2555 return new cfn_parse.FromCloudFormationResult(properties);
2556 }
2557 const ret = new cfn_parse.FromCloudFormationPropertyObject();
2558 ret.addPropertyResult('command', 'Command', properties.Command != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Command) : undefined);
2559 ret.addPropertyResult('cpu', 'Cpu', properties.Cpu != null ? cfn_parse.FromCloudFormation.getNumber(properties.Cpu) : undefined);
2560 ret.addPropertyResult('dependsOn', 'DependsOn', properties.DependsOn != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionContainerDependencyPropertyFromCloudFormation)(properties.DependsOn) : undefined);
2561 ret.addPropertyResult('disableNetworking', 'DisableNetworking', properties.DisableNetworking != null ? cfn_parse.FromCloudFormation.getBoolean(properties.DisableNetworking) : undefined);
2562 ret.addPropertyResult('dnsSearchDomains', 'DnsSearchDomains', properties.DnsSearchDomains != null ? cfn_parse.FromCloudFormation.getStringArray(properties.DnsSearchDomains) : undefined);
2563 ret.addPropertyResult('dnsServers', 'DnsServers', properties.DnsServers != null ? cfn_parse.FromCloudFormation.getStringArray(properties.DnsServers) : undefined);
2564 ret.addPropertyResult('dockerLabels', 'DockerLabels', properties.DockerLabels != null ? cfn_parse.FromCloudFormation.getMap(cfn_parse.FromCloudFormation.getString)(properties.DockerLabels) : undefined);
2565 ret.addPropertyResult('dockerSecurityOptions', 'DockerSecurityOptions', properties.DockerSecurityOptions != null ? cfn_parse.FromCloudFormation.getStringArray(properties.DockerSecurityOptions) : undefined);
2566 ret.addPropertyResult('entryPoint', 'EntryPoint', properties.EntryPoint != null ? cfn_parse.FromCloudFormation.getStringArray(properties.EntryPoint) : undefined);
2567 ret.addPropertyResult('environment', 'Environment', properties.Environment != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionKeyValuePairPropertyFromCloudFormation)(properties.Environment) : undefined);
2568 ret.addPropertyResult('environmentFiles', 'EnvironmentFiles', properties.EnvironmentFiles != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionEnvironmentFilePropertyFromCloudFormation)(properties.EnvironmentFiles) : undefined);
2569 ret.addPropertyResult('essential', 'Essential', properties.Essential != null ? cfn_parse.FromCloudFormation.getBoolean(properties.Essential) : undefined);
2570 ret.addPropertyResult('extraHosts', 'ExtraHosts', properties.ExtraHosts != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionHostEntryPropertyFromCloudFormation)(properties.ExtraHosts) : undefined);
2571 ret.addPropertyResult('firelensConfiguration', 'FirelensConfiguration', properties.FirelensConfiguration != null ? CfnTaskDefinitionFirelensConfigurationPropertyFromCloudFormation(properties.FirelensConfiguration) : undefined);
2572 ret.addPropertyResult('healthCheck', 'HealthCheck', properties.HealthCheck != null ? CfnTaskDefinitionHealthCheckPropertyFromCloudFormation(properties.HealthCheck) : undefined);
2573 ret.addPropertyResult('hostname', 'Hostname', properties.Hostname != null ? cfn_parse.FromCloudFormation.getString(properties.Hostname) : undefined);
2574 ret.addPropertyResult('image', 'Image', cfn_parse.FromCloudFormation.getString(properties.Image));
2575 ret.addPropertyResult('interactive', 'Interactive', properties.Interactive != null ? cfn_parse.FromCloudFormation.getBoolean(properties.Interactive) : undefined);
2576 ret.addPropertyResult('links', 'Links', properties.Links != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Links) : undefined);
2577 ret.addPropertyResult('linuxParameters', 'LinuxParameters', properties.LinuxParameters != null ? CfnTaskDefinitionLinuxParametersPropertyFromCloudFormation(properties.LinuxParameters) : undefined);
2578 ret.addPropertyResult('logConfiguration', 'LogConfiguration', properties.LogConfiguration != null ? CfnTaskDefinitionLogConfigurationPropertyFromCloudFormation(properties.LogConfiguration) : undefined);
2579 ret.addPropertyResult('memory', 'Memory', properties.Memory != null ? cfn_parse.FromCloudFormation.getNumber(properties.Memory) : undefined);
2580 ret.addPropertyResult('memoryReservation', 'MemoryReservation', properties.MemoryReservation != null ? cfn_parse.FromCloudFormation.getNumber(properties.MemoryReservation) : undefined);
2581 ret.addPropertyResult('mountPoints', 'MountPoints', properties.MountPoints != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionMountPointPropertyFromCloudFormation)(properties.MountPoints) : undefined);
2582 ret.addPropertyResult('name', 'Name', cfn_parse.FromCloudFormation.getString(properties.Name));
2583 ret.addPropertyResult('portMappings', 'PortMappings', properties.PortMappings != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionPortMappingPropertyFromCloudFormation)(properties.PortMappings) : undefined);
2584 ret.addPropertyResult('privileged', 'Privileged', properties.Privileged != null ? cfn_parse.FromCloudFormation.getBoolean(properties.Privileged) : undefined);
2585 ret.addPropertyResult('pseudoTerminal', 'PseudoTerminal', properties.PseudoTerminal != null ? cfn_parse.FromCloudFormation.getBoolean(properties.PseudoTerminal) : undefined);
2586 ret.addPropertyResult('readonlyRootFilesystem', 'ReadonlyRootFilesystem', properties.ReadonlyRootFilesystem != null ? cfn_parse.FromCloudFormation.getBoolean(properties.ReadonlyRootFilesystem) : undefined);
2587 ret.addPropertyResult('repositoryCredentials', 'RepositoryCredentials', properties.RepositoryCredentials != null ? CfnTaskDefinitionRepositoryCredentialsPropertyFromCloudFormation(properties.RepositoryCredentials) : undefined);
2588 ret.addPropertyResult('resourceRequirements', 'ResourceRequirements', properties.ResourceRequirements != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionResourceRequirementPropertyFromCloudFormation)(properties.ResourceRequirements) : undefined);
2589 ret.addPropertyResult('secrets', 'Secrets', properties.Secrets != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionSecretPropertyFromCloudFormation)(properties.Secrets) : undefined);
2590 ret.addPropertyResult('startTimeout', 'StartTimeout', properties.StartTimeout != null ? cfn_parse.FromCloudFormation.getNumber(properties.StartTimeout) : undefined);
2591 ret.addPropertyResult('stopTimeout', 'StopTimeout', properties.StopTimeout != null ? cfn_parse.FromCloudFormation.getNumber(properties.StopTimeout) : undefined);
2592 ret.addPropertyResult('systemControls', 'SystemControls', properties.SystemControls != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionSystemControlPropertyFromCloudFormation)(properties.SystemControls) : undefined);
2593 ret.addPropertyResult('ulimits', 'Ulimits', properties.Ulimits != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionUlimitPropertyFromCloudFormation)(properties.Ulimits) : undefined);
2594 ret.addPropertyResult('user', 'User', properties.User != null ? cfn_parse.FromCloudFormation.getString(properties.User) : undefined);
2595 ret.addPropertyResult('volumesFrom', 'VolumesFrom', properties.VolumesFrom != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionVolumeFromPropertyFromCloudFormation)(properties.VolumesFrom) : undefined);
2596 ret.addPropertyResult('workingDirectory', 'WorkingDirectory', properties.WorkingDirectory != null ? cfn_parse.FromCloudFormation.getString(properties.WorkingDirectory) : undefined);
2597 ret.addUnrecognizedPropertiesAsExtra(properties);
2598 return ret;
2599}
2600/**
2601 * Determine whether the given properties match those of a `ContainerDependencyProperty`
2602 *
2603 * @param properties - the TypeScript properties of a `ContainerDependencyProperty`
2604 *
2605 * @returns the result of the validation.
2606 */
2607function CfnTaskDefinition_ContainerDependencyPropertyValidator(properties) {
2608 if (!cdk.canInspect(properties)) {
2609 return cdk.VALIDATION_SUCCESS;
2610 }
2611 const errors = new cdk.ValidationResults();
2612 if (typeof properties !== 'object') {
2613 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
2614 }
2615 errors.collect(cdk.propertyValidator('condition', cdk.validateString)(properties.condition));
2616 errors.collect(cdk.propertyValidator('containerName', cdk.validateString)(properties.containerName));
2617 return errors.wrap('supplied properties not correct for "ContainerDependencyProperty"');
2618}
2619/**
2620 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.ContainerDependency` resource
2621 *
2622 * @param properties - the TypeScript properties of a `ContainerDependencyProperty`
2623 *
2624 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.ContainerDependency` resource.
2625 */
2626// @ts-ignore TS6133
2627function cfnTaskDefinitionContainerDependencyPropertyToCloudFormation(properties) {
2628 if (!cdk.canInspect(properties)) {
2629 return properties;
2630 }
2631 CfnTaskDefinition_ContainerDependencyPropertyValidator(properties).assertSuccess();
2632 return {
2633 Condition: cdk.stringToCloudFormation(properties.condition),
2634 ContainerName: cdk.stringToCloudFormation(properties.containerName),
2635 };
2636}
2637// @ts-ignore TS6133
2638function CfnTaskDefinitionContainerDependencyPropertyFromCloudFormation(properties) {
2639 if (cdk.isResolvableObject(properties)) {
2640 return new cfn_parse.FromCloudFormationResult(properties);
2641 }
2642 properties = properties == null ? {} : properties;
2643 if (typeof properties !== 'object') {
2644 return new cfn_parse.FromCloudFormationResult(properties);
2645 }
2646 const ret = new cfn_parse.FromCloudFormationPropertyObject();
2647 ret.addPropertyResult('condition', 'Condition', properties.Condition != null ? cfn_parse.FromCloudFormation.getString(properties.Condition) : undefined);
2648 ret.addPropertyResult('containerName', 'ContainerName', properties.ContainerName != null ? cfn_parse.FromCloudFormation.getString(properties.ContainerName) : undefined);
2649 ret.addUnrecognizedPropertiesAsExtra(properties);
2650 return ret;
2651}
2652/**
2653 * Determine whether the given properties match those of a `DeviceProperty`
2654 *
2655 * @param properties - the TypeScript properties of a `DeviceProperty`
2656 *
2657 * @returns the result of the validation.
2658 */
2659function CfnTaskDefinition_DevicePropertyValidator(properties) {
2660 if (!cdk.canInspect(properties)) {
2661 return cdk.VALIDATION_SUCCESS;
2662 }
2663 const errors = new cdk.ValidationResults();
2664 if (typeof properties !== 'object') {
2665 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
2666 }
2667 errors.collect(cdk.propertyValidator('containerPath', cdk.validateString)(properties.containerPath));
2668 errors.collect(cdk.propertyValidator('hostPath', cdk.validateString)(properties.hostPath));
2669 errors.collect(cdk.propertyValidator('permissions', cdk.listValidator(cdk.validateString))(properties.permissions));
2670 return errors.wrap('supplied properties not correct for "DeviceProperty"');
2671}
2672/**
2673 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.Device` resource
2674 *
2675 * @param properties - the TypeScript properties of a `DeviceProperty`
2676 *
2677 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.Device` resource.
2678 */
2679// @ts-ignore TS6133
2680function cfnTaskDefinitionDevicePropertyToCloudFormation(properties) {
2681 if (!cdk.canInspect(properties)) {
2682 return properties;
2683 }
2684 CfnTaskDefinition_DevicePropertyValidator(properties).assertSuccess();
2685 return {
2686 ContainerPath: cdk.stringToCloudFormation(properties.containerPath),
2687 HostPath: cdk.stringToCloudFormation(properties.hostPath),
2688 Permissions: cdk.listMapper(cdk.stringToCloudFormation)(properties.permissions),
2689 };
2690}
2691// @ts-ignore TS6133
2692function CfnTaskDefinitionDevicePropertyFromCloudFormation(properties) {
2693 if (cdk.isResolvableObject(properties)) {
2694 return new cfn_parse.FromCloudFormationResult(properties);
2695 }
2696 properties = properties == null ? {} : properties;
2697 if (typeof properties !== 'object') {
2698 return new cfn_parse.FromCloudFormationResult(properties);
2699 }
2700 const ret = new cfn_parse.FromCloudFormationPropertyObject();
2701 ret.addPropertyResult('containerPath', 'ContainerPath', properties.ContainerPath != null ? cfn_parse.FromCloudFormation.getString(properties.ContainerPath) : undefined);
2702 ret.addPropertyResult('hostPath', 'HostPath', properties.HostPath != null ? cfn_parse.FromCloudFormation.getString(properties.HostPath) : undefined);
2703 ret.addPropertyResult('permissions', 'Permissions', properties.Permissions != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Permissions) : undefined);
2704 ret.addUnrecognizedPropertiesAsExtra(properties);
2705 return ret;
2706}
2707/**
2708 * Determine whether the given properties match those of a `DockerVolumeConfigurationProperty`
2709 *
2710 * @param properties - the TypeScript properties of a `DockerVolumeConfigurationProperty`
2711 *
2712 * @returns the result of the validation.
2713 */
2714function CfnTaskDefinition_DockerVolumeConfigurationPropertyValidator(properties) {
2715 if (!cdk.canInspect(properties)) {
2716 return cdk.VALIDATION_SUCCESS;
2717 }
2718 const errors = new cdk.ValidationResults();
2719 if (typeof properties !== 'object') {
2720 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
2721 }
2722 errors.collect(cdk.propertyValidator('autoprovision', cdk.validateBoolean)(properties.autoprovision));
2723 errors.collect(cdk.propertyValidator('driver', cdk.validateString)(properties.driver));
2724 errors.collect(cdk.propertyValidator('driverOpts', cdk.hashValidator(cdk.validateString))(properties.driverOpts));
2725 errors.collect(cdk.propertyValidator('labels', cdk.hashValidator(cdk.validateString))(properties.labels));
2726 errors.collect(cdk.propertyValidator('scope', cdk.validateString)(properties.scope));
2727 return errors.wrap('supplied properties not correct for "DockerVolumeConfigurationProperty"');
2728}
2729/**
2730 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.DockerVolumeConfiguration` resource
2731 *
2732 * @param properties - the TypeScript properties of a `DockerVolumeConfigurationProperty`
2733 *
2734 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.DockerVolumeConfiguration` resource.
2735 */
2736// @ts-ignore TS6133
2737function cfnTaskDefinitionDockerVolumeConfigurationPropertyToCloudFormation(properties) {
2738 if (!cdk.canInspect(properties)) {
2739 return properties;
2740 }
2741 CfnTaskDefinition_DockerVolumeConfigurationPropertyValidator(properties).assertSuccess();
2742 return {
2743 Autoprovision: cdk.booleanToCloudFormation(properties.autoprovision),
2744 Driver: cdk.stringToCloudFormation(properties.driver),
2745 DriverOpts: cdk.hashMapper(cdk.stringToCloudFormation)(properties.driverOpts),
2746 Labels: cdk.hashMapper(cdk.stringToCloudFormation)(properties.labels),
2747 Scope: cdk.stringToCloudFormation(properties.scope),
2748 };
2749}
2750// @ts-ignore TS6133
2751function CfnTaskDefinitionDockerVolumeConfigurationPropertyFromCloudFormation(properties) {
2752 if (cdk.isResolvableObject(properties)) {
2753 return new cfn_parse.FromCloudFormationResult(properties);
2754 }
2755 properties = properties == null ? {} : properties;
2756 if (typeof properties !== 'object') {
2757 return new cfn_parse.FromCloudFormationResult(properties);
2758 }
2759 const ret = new cfn_parse.FromCloudFormationPropertyObject();
2760 ret.addPropertyResult('autoprovision', 'Autoprovision', properties.Autoprovision != null ? cfn_parse.FromCloudFormation.getBoolean(properties.Autoprovision) : undefined);
2761 ret.addPropertyResult('driver', 'Driver', properties.Driver != null ? cfn_parse.FromCloudFormation.getString(properties.Driver) : undefined);
2762 ret.addPropertyResult('driverOpts', 'DriverOpts', properties.DriverOpts != null ? cfn_parse.FromCloudFormation.getMap(cfn_parse.FromCloudFormation.getString)(properties.DriverOpts) : undefined);
2763 ret.addPropertyResult('labels', 'Labels', properties.Labels != null ? cfn_parse.FromCloudFormation.getMap(cfn_parse.FromCloudFormation.getString)(properties.Labels) : undefined);
2764 ret.addPropertyResult('scope', 'Scope', properties.Scope != null ? cfn_parse.FromCloudFormation.getString(properties.Scope) : undefined);
2765 ret.addUnrecognizedPropertiesAsExtra(properties);
2766 return ret;
2767}
2768/**
2769 * Determine whether the given properties match those of a `EFSVolumeConfigurationProperty`
2770 *
2771 * @param properties - the TypeScript properties of a `EFSVolumeConfigurationProperty`
2772 *
2773 * @returns the result of the validation.
2774 */
2775function CfnTaskDefinition_EFSVolumeConfigurationPropertyValidator(properties) {
2776 if (!cdk.canInspect(properties)) {
2777 return cdk.VALIDATION_SUCCESS;
2778 }
2779 const errors = new cdk.ValidationResults();
2780 if (typeof properties !== 'object') {
2781 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
2782 }
2783 errors.collect(cdk.propertyValidator('authorizationConfig', CfnTaskDefinition_AuthorizationConfigPropertyValidator)(properties.authorizationConfig));
2784 errors.collect(cdk.propertyValidator('filesystemId', cdk.requiredValidator)(properties.filesystemId));
2785 errors.collect(cdk.propertyValidator('filesystemId', cdk.validateString)(properties.filesystemId));
2786 errors.collect(cdk.propertyValidator('rootDirectory', cdk.validateString)(properties.rootDirectory));
2787 errors.collect(cdk.propertyValidator('transitEncryption', cdk.validateString)(properties.transitEncryption));
2788 errors.collect(cdk.propertyValidator('transitEncryptionPort', cdk.validateNumber)(properties.transitEncryptionPort));
2789 return errors.wrap('supplied properties not correct for "EFSVolumeConfigurationProperty"');
2790}
2791/**
2792 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.EFSVolumeConfiguration` resource
2793 *
2794 * @param properties - the TypeScript properties of a `EFSVolumeConfigurationProperty`
2795 *
2796 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.EFSVolumeConfiguration` resource.
2797 */
2798// @ts-ignore TS6133
2799function cfnTaskDefinitionEFSVolumeConfigurationPropertyToCloudFormation(properties) {
2800 if (!cdk.canInspect(properties)) {
2801 return properties;
2802 }
2803 CfnTaskDefinition_EFSVolumeConfigurationPropertyValidator(properties).assertSuccess();
2804 return {
2805 AuthorizationConfig: cfnTaskDefinitionAuthorizationConfigPropertyToCloudFormation(properties.authorizationConfig),
2806 FilesystemId: cdk.stringToCloudFormation(properties.filesystemId),
2807 RootDirectory: cdk.stringToCloudFormation(properties.rootDirectory),
2808 TransitEncryption: cdk.stringToCloudFormation(properties.transitEncryption),
2809 TransitEncryptionPort: cdk.numberToCloudFormation(properties.transitEncryptionPort),
2810 };
2811}
2812// @ts-ignore TS6133
2813function CfnTaskDefinitionEFSVolumeConfigurationPropertyFromCloudFormation(properties) {
2814 if (cdk.isResolvableObject(properties)) {
2815 return new cfn_parse.FromCloudFormationResult(properties);
2816 }
2817 properties = properties == null ? {} : properties;
2818 if (typeof properties !== 'object') {
2819 return new cfn_parse.FromCloudFormationResult(properties);
2820 }
2821 const ret = new cfn_parse.FromCloudFormationPropertyObject();
2822 ret.addPropertyResult('authorizationConfig', 'AuthorizationConfig', properties.AuthorizationConfig != null ? CfnTaskDefinitionAuthorizationConfigPropertyFromCloudFormation(properties.AuthorizationConfig) : undefined);
2823 ret.addPropertyResult('filesystemId', 'FilesystemId', cfn_parse.FromCloudFormation.getString(properties.FilesystemId));
2824 ret.addPropertyResult('rootDirectory', 'RootDirectory', properties.RootDirectory != null ? cfn_parse.FromCloudFormation.getString(properties.RootDirectory) : undefined);
2825 ret.addPropertyResult('transitEncryption', 'TransitEncryption', properties.TransitEncryption != null ? cfn_parse.FromCloudFormation.getString(properties.TransitEncryption) : undefined);
2826 ret.addPropertyResult('transitEncryptionPort', 'TransitEncryptionPort', properties.TransitEncryptionPort != null ? cfn_parse.FromCloudFormation.getNumber(properties.TransitEncryptionPort) : undefined);
2827 ret.addUnrecognizedPropertiesAsExtra(properties);
2828 return ret;
2829}
2830/**
2831 * Determine whether the given properties match those of a `EnvironmentFileProperty`
2832 *
2833 * @param properties - the TypeScript properties of a `EnvironmentFileProperty`
2834 *
2835 * @returns the result of the validation.
2836 */
2837function CfnTaskDefinition_EnvironmentFilePropertyValidator(properties) {
2838 if (!cdk.canInspect(properties)) {
2839 return cdk.VALIDATION_SUCCESS;
2840 }
2841 const errors = new cdk.ValidationResults();
2842 if (typeof properties !== 'object') {
2843 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
2844 }
2845 errors.collect(cdk.propertyValidator('type', cdk.validateString)(properties.type));
2846 errors.collect(cdk.propertyValidator('value', cdk.validateString)(properties.value));
2847 return errors.wrap('supplied properties not correct for "EnvironmentFileProperty"');
2848}
2849/**
2850 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.EnvironmentFile` resource
2851 *
2852 * @param properties - the TypeScript properties of a `EnvironmentFileProperty`
2853 *
2854 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.EnvironmentFile` resource.
2855 */
2856// @ts-ignore TS6133
2857function cfnTaskDefinitionEnvironmentFilePropertyToCloudFormation(properties) {
2858 if (!cdk.canInspect(properties)) {
2859 return properties;
2860 }
2861 CfnTaskDefinition_EnvironmentFilePropertyValidator(properties).assertSuccess();
2862 return {
2863 Type: cdk.stringToCloudFormation(properties.type),
2864 Value: cdk.stringToCloudFormation(properties.value),
2865 };
2866}
2867// @ts-ignore TS6133
2868function CfnTaskDefinitionEnvironmentFilePropertyFromCloudFormation(properties) {
2869 if (cdk.isResolvableObject(properties)) {
2870 return new cfn_parse.FromCloudFormationResult(properties);
2871 }
2872 properties = properties == null ? {} : properties;
2873 if (typeof properties !== 'object') {
2874 return new cfn_parse.FromCloudFormationResult(properties);
2875 }
2876 const ret = new cfn_parse.FromCloudFormationPropertyObject();
2877 ret.addPropertyResult('type', 'Type', properties.Type != null ? cfn_parse.FromCloudFormation.getString(properties.Type) : undefined);
2878 ret.addPropertyResult('value', 'Value', properties.Value != null ? cfn_parse.FromCloudFormation.getString(properties.Value) : undefined);
2879 ret.addUnrecognizedPropertiesAsExtra(properties);
2880 return ret;
2881}
2882/**
2883 * Determine whether the given properties match those of a `EphemeralStorageProperty`
2884 *
2885 * @param properties - the TypeScript properties of a `EphemeralStorageProperty`
2886 *
2887 * @returns the result of the validation.
2888 */
2889function CfnTaskDefinition_EphemeralStoragePropertyValidator(properties) {
2890 if (!cdk.canInspect(properties)) {
2891 return cdk.VALIDATION_SUCCESS;
2892 }
2893 const errors = new cdk.ValidationResults();
2894 if (typeof properties !== 'object') {
2895 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
2896 }
2897 errors.collect(cdk.propertyValidator('sizeInGiB', cdk.validateNumber)(properties.sizeInGiB));
2898 return errors.wrap('supplied properties not correct for "EphemeralStorageProperty"');
2899}
2900/**
2901 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.EphemeralStorage` resource
2902 *
2903 * @param properties - the TypeScript properties of a `EphemeralStorageProperty`
2904 *
2905 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.EphemeralStorage` resource.
2906 */
2907// @ts-ignore TS6133
2908function cfnTaskDefinitionEphemeralStoragePropertyToCloudFormation(properties) {
2909 if (!cdk.canInspect(properties)) {
2910 return properties;
2911 }
2912 CfnTaskDefinition_EphemeralStoragePropertyValidator(properties).assertSuccess();
2913 return {
2914 SizeInGiB: cdk.numberToCloudFormation(properties.sizeInGiB),
2915 };
2916}
2917// @ts-ignore TS6133
2918function CfnTaskDefinitionEphemeralStoragePropertyFromCloudFormation(properties) {
2919 if (cdk.isResolvableObject(properties)) {
2920 return new cfn_parse.FromCloudFormationResult(properties);
2921 }
2922 properties = properties == null ? {} : properties;
2923 if (typeof properties !== 'object') {
2924 return new cfn_parse.FromCloudFormationResult(properties);
2925 }
2926 const ret = new cfn_parse.FromCloudFormationPropertyObject();
2927 ret.addPropertyResult('sizeInGiB', 'SizeInGiB', properties.SizeInGiB != null ? cfn_parse.FromCloudFormation.getNumber(properties.SizeInGiB) : undefined);
2928 ret.addUnrecognizedPropertiesAsExtra(properties);
2929 return ret;
2930}
2931/**
2932 * Determine whether the given properties match those of a `FirelensConfigurationProperty`
2933 *
2934 * @param properties - the TypeScript properties of a `FirelensConfigurationProperty`
2935 *
2936 * @returns the result of the validation.
2937 */
2938function CfnTaskDefinition_FirelensConfigurationPropertyValidator(properties) {
2939 if (!cdk.canInspect(properties)) {
2940 return cdk.VALIDATION_SUCCESS;
2941 }
2942 const errors = new cdk.ValidationResults();
2943 if (typeof properties !== 'object') {
2944 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
2945 }
2946 errors.collect(cdk.propertyValidator('options', cdk.hashValidator(cdk.validateString))(properties.options));
2947 errors.collect(cdk.propertyValidator('type', cdk.validateString)(properties.type));
2948 return errors.wrap('supplied properties not correct for "FirelensConfigurationProperty"');
2949}
2950/**
2951 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.FirelensConfiguration` resource
2952 *
2953 * @param properties - the TypeScript properties of a `FirelensConfigurationProperty`
2954 *
2955 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.FirelensConfiguration` resource.
2956 */
2957// @ts-ignore TS6133
2958function cfnTaskDefinitionFirelensConfigurationPropertyToCloudFormation(properties) {
2959 if (!cdk.canInspect(properties)) {
2960 return properties;
2961 }
2962 CfnTaskDefinition_FirelensConfigurationPropertyValidator(properties).assertSuccess();
2963 return {
2964 Options: cdk.hashMapper(cdk.stringToCloudFormation)(properties.options),
2965 Type: cdk.stringToCloudFormation(properties.type),
2966 };
2967}
2968// @ts-ignore TS6133
2969function CfnTaskDefinitionFirelensConfigurationPropertyFromCloudFormation(properties) {
2970 if (cdk.isResolvableObject(properties)) {
2971 return new cfn_parse.FromCloudFormationResult(properties);
2972 }
2973 properties = properties == null ? {} : properties;
2974 if (typeof properties !== 'object') {
2975 return new cfn_parse.FromCloudFormationResult(properties);
2976 }
2977 const ret = new cfn_parse.FromCloudFormationPropertyObject();
2978 ret.addPropertyResult('options', 'Options', properties.Options != null ? cfn_parse.FromCloudFormation.getMap(cfn_parse.FromCloudFormation.getString)(properties.Options) : undefined);
2979 ret.addPropertyResult('type', 'Type', properties.Type != null ? cfn_parse.FromCloudFormation.getString(properties.Type) : undefined);
2980 ret.addUnrecognizedPropertiesAsExtra(properties);
2981 return ret;
2982}
2983/**
2984 * Determine whether the given properties match those of a `HealthCheckProperty`
2985 *
2986 * @param properties - the TypeScript properties of a `HealthCheckProperty`
2987 *
2988 * @returns the result of the validation.
2989 */
2990function CfnTaskDefinition_HealthCheckPropertyValidator(properties) {
2991 if (!cdk.canInspect(properties)) {
2992 return cdk.VALIDATION_SUCCESS;
2993 }
2994 const errors = new cdk.ValidationResults();
2995 if (typeof properties !== 'object') {
2996 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
2997 }
2998 errors.collect(cdk.propertyValidator('command', cdk.listValidator(cdk.validateString))(properties.command));
2999 errors.collect(cdk.propertyValidator('interval', cdk.validateNumber)(properties.interval));
3000 errors.collect(cdk.propertyValidator('retries', cdk.validateNumber)(properties.retries));
3001 errors.collect(cdk.propertyValidator('startPeriod', cdk.validateNumber)(properties.startPeriod));
3002 errors.collect(cdk.propertyValidator('timeout', cdk.validateNumber)(properties.timeout));
3003 return errors.wrap('supplied properties not correct for "HealthCheckProperty"');
3004}
3005/**
3006 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.HealthCheck` resource
3007 *
3008 * @param properties - the TypeScript properties of a `HealthCheckProperty`
3009 *
3010 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.HealthCheck` resource.
3011 */
3012// @ts-ignore TS6133
3013function cfnTaskDefinitionHealthCheckPropertyToCloudFormation(properties) {
3014 if (!cdk.canInspect(properties)) {
3015 return properties;
3016 }
3017 CfnTaskDefinition_HealthCheckPropertyValidator(properties).assertSuccess();
3018 return {
3019 Command: cdk.listMapper(cdk.stringToCloudFormation)(properties.command),
3020 Interval: cdk.numberToCloudFormation(properties.interval),
3021 Retries: cdk.numberToCloudFormation(properties.retries),
3022 StartPeriod: cdk.numberToCloudFormation(properties.startPeriod),
3023 Timeout: cdk.numberToCloudFormation(properties.timeout),
3024 };
3025}
3026// @ts-ignore TS6133
3027function CfnTaskDefinitionHealthCheckPropertyFromCloudFormation(properties) {
3028 if (cdk.isResolvableObject(properties)) {
3029 return new cfn_parse.FromCloudFormationResult(properties);
3030 }
3031 properties = properties == null ? {} : properties;
3032 if (typeof properties !== 'object') {
3033 return new cfn_parse.FromCloudFormationResult(properties);
3034 }
3035 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3036 ret.addPropertyResult('command', 'Command', properties.Command != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Command) : undefined);
3037 ret.addPropertyResult('interval', 'Interval', properties.Interval != null ? cfn_parse.FromCloudFormation.getNumber(properties.Interval) : undefined);
3038 ret.addPropertyResult('retries', 'Retries', properties.Retries != null ? cfn_parse.FromCloudFormation.getNumber(properties.Retries) : undefined);
3039 ret.addPropertyResult('startPeriod', 'StartPeriod', properties.StartPeriod != null ? cfn_parse.FromCloudFormation.getNumber(properties.StartPeriod) : undefined);
3040 ret.addPropertyResult('timeout', 'Timeout', properties.Timeout != null ? cfn_parse.FromCloudFormation.getNumber(properties.Timeout) : undefined);
3041 ret.addUnrecognizedPropertiesAsExtra(properties);
3042 return ret;
3043}
3044/**
3045 * Determine whether the given properties match those of a `HostEntryProperty`
3046 *
3047 * @param properties - the TypeScript properties of a `HostEntryProperty`
3048 *
3049 * @returns the result of the validation.
3050 */
3051function CfnTaskDefinition_HostEntryPropertyValidator(properties) {
3052 if (!cdk.canInspect(properties)) {
3053 return cdk.VALIDATION_SUCCESS;
3054 }
3055 const errors = new cdk.ValidationResults();
3056 if (typeof properties !== 'object') {
3057 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3058 }
3059 errors.collect(cdk.propertyValidator('hostname', cdk.validateString)(properties.hostname));
3060 errors.collect(cdk.propertyValidator('ipAddress', cdk.validateString)(properties.ipAddress));
3061 return errors.wrap('supplied properties not correct for "HostEntryProperty"');
3062}
3063/**
3064 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.HostEntry` resource
3065 *
3066 * @param properties - the TypeScript properties of a `HostEntryProperty`
3067 *
3068 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.HostEntry` resource.
3069 */
3070// @ts-ignore TS6133
3071function cfnTaskDefinitionHostEntryPropertyToCloudFormation(properties) {
3072 if (!cdk.canInspect(properties)) {
3073 return properties;
3074 }
3075 CfnTaskDefinition_HostEntryPropertyValidator(properties).assertSuccess();
3076 return {
3077 Hostname: cdk.stringToCloudFormation(properties.hostname),
3078 IpAddress: cdk.stringToCloudFormation(properties.ipAddress),
3079 };
3080}
3081// @ts-ignore TS6133
3082function CfnTaskDefinitionHostEntryPropertyFromCloudFormation(properties) {
3083 if (cdk.isResolvableObject(properties)) {
3084 return new cfn_parse.FromCloudFormationResult(properties);
3085 }
3086 properties = properties == null ? {} : properties;
3087 if (typeof properties !== 'object') {
3088 return new cfn_parse.FromCloudFormationResult(properties);
3089 }
3090 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3091 ret.addPropertyResult('hostname', 'Hostname', properties.Hostname != null ? cfn_parse.FromCloudFormation.getString(properties.Hostname) : undefined);
3092 ret.addPropertyResult('ipAddress', 'IpAddress', properties.IpAddress != null ? cfn_parse.FromCloudFormation.getString(properties.IpAddress) : undefined);
3093 ret.addUnrecognizedPropertiesAsExtra(properties);
3094 return ret;
3095}
3096/**
3097 * Determine whether the given properties match those of a `HostVolumePropertiesProperty`
3098 *
3099 * @param properties - the TypeScript properties of a `HostVolumePropertiesProperty`
3100 *
3101 * @returns the result of the validation.
3102 */
3103function CfnTaskDefinition_HostVolumePropertiesPropertyValidator(properties) {
3104 if (!cdk.canInspect(properties)) {
3105 return cdk.VALIDATION_SUCCESS;
3106 }
3107 const errors = new cdk.ValidationResults();
3108 if (typeof properties !== 'object') {
3109 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3110 }
3111 errors.collect(cdk.propertyValidator('sourcePath', cdk.validateString)(properties.sourcePath));
3112 return errors.wrap('supplied properties not correct for "HostVolumePropertiesProperty"');
3113}
3114/**
3115 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.HostVolumeProperties` resource
3116 *
3117 * @param properties - the TypeScript properties of a `HostVolumePropertiesProperty`
3118 *
3119 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.HostVolumeProperties` resource.
3120 */
3121// @ts-ignore TS6133
3122function cfnTaskDefinitionHostVolumePropertiesPropertyToCloudFormation(properties) {
3123 if (!cdk.canInspect(properties)) {
3124 return properties;
3125 }
3126 CfnTaskDefinition_HostVolumePropertiesPropertyValidator(properties).assertSuccess();
3127 return {
3128 SourcePath: cdk.stringToCloudFormation(properties.sourcePath),
3129 };
3130}
3131// @ts-ignore TS6133
3132function CfnTaskDefinitionHostVolumePropertiesPropertyFromCloudFormation(properties) {
3133 if (cdk.isResolvableObject(properties)) {
3134 return new cfn_parse.FromCloudFormationResult(properties);
3135 }
3136 properties = properties == null ? {} : properties;
3137 if (typeof properties !== 'object') {
3138 return new cfn_parse.FromCloudFormationResult(properties);
3139 }
3140 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3141 ret.addPropertyResult('sourcePath', 'SourcePath', properties.SourcePath != null ? cfn_parse.FromCloudFormation.getString(properties.SourcePath) : undefined);
3142 ret.addUnrecognizedPropertiesAsExtra(properties);
3143 return ret;
3144}
3145/**
3146 * Determine whether the given properties match those of a `InferenceAcceleratorProperty`
3147 *
3148 * @param properties - the TypeScript properties of a `InferenceAcceleratorProperty`
3149 *
3150 * @returns the result of the validation.
3151 */
3152function CfnTaskDefinition_InferenceAcceleratorPropertyValidator(properties) {
3153 if (!cdk.canInspect(properties)) {
3154 return cdk.VALIDATION_SUCCESS;
3155 }
3156 const errors = new cdk.ValidationResults();
3157 if (typeof properties !== 'object') {
3158 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3159 }
3160 errors.collect(cdk.propertyValidator('deviceName', cdk.validateString)(properties.deviceName));
3161 errors.collect(cdk.propertyValidator('deviceType', cdk.validateString)(properties.deviceType));
3162 return errors.wrap('supplied properties not correct for "InferenceAcceleratorProperty"');
3163}
3164/**
3165 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.InferenceAccelerator` resource
3166 *
3167 * @param properties - the TypeScript properties of a `InferenceAcceleratorProperty`
3168 *
3169 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.InferenceAccelerator` resource.
3170 */
3171// @ts-ignore TS6133
3172function cfnTaskDefinitionInferenceAcceleratorPropertyToCloudFormation(properties) {
3173 if (!cdk.canInspect(properties)) {
3174 return properties;
3175 }
3176 CfnTaskDefinition_InferenceAcceleratorPropertyValidator(properties).assertSuccess();
3177 return {
3178 DeviceName: cdk.stringToCloudFormation(properties.deviceName),
3179 DeviceType: cdk.stringToCloudFormation(properties.deviceType),
3180 };
3181}
3182// @ts-ignore TS6133
3183function CfnTaskDefinitionInferenceAcceleratorPropertyFromCloudFormation(properties) {
3184 if (cdk.isResolvableObject(properties)) {
3185 return new cfn_parse.FromCloudFormationResult(properties);
3186 }
3187 properties = properties == null ? {} : properties;
3188 if (typeof properties !== 'object') {
3189 return new cfn_parse.FromCloudFormationResult(properties);
3190 }
3191 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3192 ret.addPropertyResult('deviceName', 'DeviceName', properties.DeviceName != null ? cfn_parse.FromCloudFormation.getString(properties.DeviceName) : undefined);
3193 ret.addPropertyResult('deviceType', 'DeviceType', properties.DeviceType != null ? cfn_parse.FromCloudFormation.getString(properties.DeviceType) : undefined);
3194 ret.addUnrecognizedPropertiesAsExtra(properties);
3195 return ret;
3196}
3197/**
3198 * Determine whether the given properties match those of a `KernelCapabilitiesProperty`
3199 *
3200 * @param properties - the TypeScript properties of a `KernelCapabilitiesProperty`
3201 *
3202 * @returns the result of the validation.
3203 */
3204function CfnTaskDefinition_KernelCapabilitiesPropertyValidator(properties) {
3205 if (!cdk.canInspect(properties)) {
3206 return cdk.VALIDATION_SUCCESS;
3207 }
3208 const errors = new cdk.ValidationResults();
3209 if (typeof properties !== 'object') {
3210 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3211 }
3212 errors.collect(cdk.propertyValidator('add', cdk.listValidator(cdk.validateString))(properties.add));
3213 errors.collect(cdk.propertyValidator('drop', cdk.listValidator(cdk.validateString))(properties.drop));
3214 return errors.wrap('supplied properties not correct for "KernelCapabilitiesProperty"');
3215}
3216/**
3217 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.KernelCapabilities` resource
3218 *
3219 * @param properties - the TypeScript properties of a `KernelCapabilitiesProperty`
3220 *
3221 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.KernelCapabilities` resource.
3222 */
3223// @ts-ignore TS6133
3224function cfnTaskDefinitionKernelCapabilitiesPropertyToCloudFormation(properties) {
3225 if (!cdk.canInspect(properties)) {
3226 return properties;
3227 }
3228 CfnTaskDefinition_KernelCapabilitiesPropertyValidator(properties).assertSuccess();
3229 return {
3230 Add: cdk.listMapper(cdk.stringToCloudFormation)(properties.add),
3231 Drop: cdk.listMapper(cdk.stringToCloudFormation)(properties.drop),
3232 };
3233}
3234// @ts-ignore TS6133
3235function CfnTaskDefinitionKernelCapabilitiesPropertyFromCloudFormation(properties) {
3236 if (cdk.isResolvableObject(properties)) {
3237 return new cfn_parse.FromCloudFormationResult(properties);
3238 }
3239 properties = properties == null ? {} : properties;
3240 if (typeof properties !== 'object') {
3241 return new cfn_parse.FromCloudFormationResult(properties);
3242 }
3243 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3244 ret.addPropertyResult('add', 'Add', properties.Add != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Add) : undefined);
3245 ret.addPropertyResult('drop', 'Drop', properties.Drop != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Drop) : undefined);
3246 ret.addUnrecognizedPropertiesAsExtra(properties);
3247 return ret;
3248}
3249/**
3250 * Determine whether the given properties match those of a `KeyValuePairProperty`
3251 *
3252 * @param properties - the TypeScript properties of a `KeyValuePairProperty`
3253 *
3254 * @returns the result of the validation.
3255 */
3256function CfnTaskDefinition_KeyValuePairPropertyValidator(properties) {
3257 if (!cdk.canInspect(properties)) {
3258 return cdk.VALIDATION_SUCCESS;
3259 }
3260 const errors = new cdk.ValidationResults();
3261 if (typeof properties !== 'object') {
3262 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3263 }
3264 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
3265 errors.collect(cdk.propertyValidator('value', cdk.validateString)(properties.value));
3266 return errors.wrap('supplied properties not correct for "KeyValuePairProperty"');
3267}
3268/**
3269 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.KeyValuePair` resource
3270 *
3271 * @param properties - the TypeScript properties of a `KeyValuePairProperty`
3272 *
3273 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.KeyValuePair` resource.
3274 */
3275// @ts-ignore TS6133
3276function cfnTaskDefinitionKeyValuePairPropertyToCloudFormation(properties) {
3277 if (!cdk.canInspect(properties)) {
3278 return properties;
3279 }
3280 CfnTaskDefinition_KeyValuePairPropertyValidator(properties).assertSuccess();
3281 return {
3282 Name: cdk.stringToCloudFormation(properties.name),
3283 Value: cdk.stringToCloudFormation(properties.value),
3284 };
3285}
3286// @ts-ignore TS6133
3287function CfnTaskDefinitionKeyValuePairPropertyFromCloudFormation(properties) {
3288 if (cdk.isResolvableObject(properties)) {
3289 return new cfn_parse.FromCloudFormationResult(properties);
3290 }
3291 properties = properties == null ? {} : properties;
3292 if (typeof properties !== 'object') {
3293 return new cfn_parse.FromCloudFormationResult(properties);
3294 }
3295 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3296 ret.addPropertyResult('name', 'Name', properties.Name != null ? cfn_parse.FromCloudFormation.getString(properties.Name) : undefined);
3297 ret.addPropertyResult('value', 'Value', properties.Value != null ? cfn_parse.FromCloudFormation.getString(properties.Value) : undefined);
3298 ret.addUnrecognizedPropertiesAsExtra(properties);
3299 return ret;
3300}
3301/**
3302 * Determine whether the given properties match those of a `LinuxParametersProperty`
3303 *
3304 * @param properties - the TypeScript properties of a `LinuxParametersProperty`
3305 *
3306 * @returns the result of the validation.
3307 */
3308function CfnTaskDefinition_LinuxParametersPropertyValidator(properties) {
3309 if (!cdk.canInspect(properties)) {
3310 return cdk.VALIDATION_SUCCESS;
3311 }
3312 const errors = new cdk.ValidationResults();
3313 if (typeof properties !== 'object') {
3314 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3315 }
3316 errors.collect(cdk.propertyValidator('capabilities', CfnTaskDefinition_KernelCapabilitiesPropertyValidator)(properties.capabilities));
3317 errors.collect(cdk.propertyValidator('devices', cdk.listValidator(CfnTaskDefinition_DevicePropertyValidator))(properties.devices));
3318 errors.collect(cdk.propertyValidator('initProcessEnabled', cdk.validateBoolean)(properties.initProcessEnabled));
3319 errors.collect(cdk.propertyValidator('maxSwap', cdk.validateNumber)(properties.maxSwap));
3320 errors.collect(cdk.propertyValidator('sharedMemorySize', cdk.validateNumber)(properties.sharedMemorySize));
3321 errors.collect(cdk.propertyValidator('swappiness', cdk.validateNumber)(properties.swappiness));
3322 errors.collect(cdk.propertyValidator('tmpfs', cdk.listValidator(CfnTaskDefinition_TmpfsPropertyValidator))(properties.tmpfs));
3323 return errors.wrap('supplied properties not correct for "LinuxParametersProperty"');
3324}
3325/**
3326 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.LinuxParameters` resource
3327 *
3328 * @param properties - the TypeScript properties of a `LinuxParametersProperty`
3329 *
3330 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.LinuxParameters` resource.
3331 */
3332// @ts-ignore TS6133
3333function cfnTaskDefinitionLinuxParametersPropertyToCloudFormation(properties) {
3334 if (!cdk.canInspect(properties)) {
3335 return properties;
3336 }
3337 CfnTaskDefinition_LinuxParametersPropertyValidator(properties).assertSuccess();
3338 return {
3339 Capabilities: cfnTaskDefinitionKernelCapabilitiesPropertyToCloudFormation(properties.capabilities),
3340 Devices: cdk.listMapper(cfnTaskDefinitionDevicePropertyToCloudFormation)(properties.devices),
3341 InitProcessEnabled: cdk.booleanToCloudFormation(properties.initProcessEnabled),
3342 MaxSwap: cdk.numberToCloudFormation(properties.maxSwap),
3343 SharedMemorySize: cdk.numberToCloudFormation(properties.sharedMemorySize),
3344 Swappiness: cdk.numberToCloudFormation(properties.swappiness),
3345 Tmpfs: cdk.listMapper(cfnTaskDefinitionTmpfsPropertyToCloudFormation)(properties.tmpfs),
3346 };
3347}
3348// @ts-ignore TS6133
3349function CfnTaskDefinitionLinuxParametersPropertyFromCloudFormation(properties) {
3350 if (cdk.isResolvableObject(properties)) {
3351 return new cfn_parse.FromCloudFormationResult(properties);
3352 }
3353 properties = properties == null ? {} : properties;
3354 if (typeof properties !== 'object') {
3355 return new cfn_parse.FromCloudFormationResult(properties);
3356 }
3357 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3358 ret.addPropertyResult('capabilities', 'Capabilities', properties.Capabilities != null ? CfnTaskDefinitionKernelCapabilitiesPropertyFromCloudFormation(properties.Capabilities) : undefined);
3359 ret.addPropertyResult('devices', 'Devices', properties.Devices != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionDevicePropertyFromCloudFormation)(properties.Devices) : undefined);
3360 ret.addPropertyResult('initProcessEnabled', 'InitProcessEnabled', properties.InitProcessEnabled != null ? cfn_parse.FromCloudFormation.getBoolean(properties.InitProcessEnabled) : undefined);
3361 ret.addPropertyResult('maxSwap', 'MaxSwap', properties.MaxSwap != null ? cfn_parse.FromCloudFormation.getNumber(properties.MaxSwap) : undefined);
3362 ret.addPropertyResult('sharedMemorySize', 'SharedMemorySize', properties.SharedMemorySize != null ? cfn_parse.FromCloudFormation.getNumber(properties.SharedMemorySize) : undefined);
3363 ret.addPropertyResult('swappiness', 'Swappiness', properties.Swappiness != null ? cfn_parse.FromCloudFormation.getNumber(properties.Swappiness) : undefined);
3364 ret.addPropertyResult('tmpfs', 'Tmpfs', properties.Tmpfs != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionTmpfsPropertyFromCloudFormation)(properties.Tmpfs) : undefined);
3365 ret.addUnrecognizedPropertiesAsExtra(properties);
3366 return ret;
3367}
3368/**
3369 * Determine whether the given properties match those of a `LogConfigurationProperty`
3370 *
3371 * @param properties - the TypeScript properties of a `LogConfigurationProperty`
3372 *
3373 * @returns the result of the validation.
3374 */
3375function CfnTaskDefinition_LogConfigurationPropertyValidator(properties) {
3376 if (!cdk.canInspect(properties)) {
3377 return cdk.VALIDATION_SUCCESS;
3378 }
3379 const errors = new cdk.ValidationResults();
3380 if (typeof properties !== 'object') {
3381 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3382 }
3383 errors.collect(cdk.propertyValidator('logDriver', cdk.requiredValidator)(properties.logDriver));
3384 errors.collect(cdk.propertyValidator('logDriver', cdk.validateString)(properties.logDriver));
3385 errors.collect(cdk.propertyValidator('options', cdk.hashValidator(cdk.validateString))(properties.options));
3386 errors.collect(cdk.propertyValidator('secretOptions', cdk.listValidator(CfnTaskDefinition_SecretPropertyValidator))(properties.secretOptions));
3387 return errors.wrap('supplied properties not correct for "LogConfigurationProperty"');
3388}
3389/**
3390 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.LogConfiguration` resource
3391 *
3392 * @param properties - the TypeScript properties of a `LogConfigurationProperty`
3393 *
3394 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.LogConfiguration` resource.
3395 */
3396// @ts-ignore TS6133
3397function cfnTaskDefinitionLogConfigurationPropertyToCloudFormation(properties) {
3398 if (!cdk.canInspect(properties)) {
3399 return properties;
3400 }
3401 CfnTaskDefinition_LogConfigurationPropertyValidator(properties).assertSuccess();
3402 return {
3403 LogDriver: cdk.stringToCloudFormation(properties.logDriver),
3404 Options: cdk.hashMapper(cdk.stringToCloudFormation)(properties.options),
3405 SecretOptions: cdk.listMapper(cfnTaskDefinitionSecretPropertyToCloudFormation)(properties.secretOptions),
3406 };
3407}
3408// @ts-ignore TS6133
3409function CfnTaskDefinitionLogConfigurationPropertyFromCloudFormation(properties) {
3410 if (cdk.isResolvableObject(properties)) {
3411 return new cfn_parse.FromCloudFormationResult(properties);
3412 }
3413 properties = properties == null ? {} : properties;
3414 if (typeof properties !== 'object') {
3415 return new cfn_parse.FromCloudFormationResult(properties);
3416 }
3417 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3418 ret.addPropertyResult('logDriver', 'LogDriver', cfn_parse.FromCloudFormation.getString(properties.LogDriver));
3419 ret.addPropertyResult('options', 'Options', properties.Options != null ? cfn_parse.FromCloudFormation.getMap(cfn_parse.FromCloudFormation.getString)(properties.Options) : undefined);
3420 ret.addPropertyResult('secretOptions', 'SecretOptions', properties.SecretOptions != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionSecretPropertyFromCloudFormation)(properties.SecretOptions) : undefined);
3421 ret.addUnrecognizedPropertiesAsExtra(properties);
3422 return ret;
3423}
3424/**
3425 * Determine whether the given properties match those of a `MountPointProperty`
3426 *
3427 * @param properties - the TypeScript properties of a `MountPointProperty`
3428 *
3429 * @returns the result of the validation.
3430 */
3431function CfnTaskDefinition_MountPointPropertyValidator(properties) {
3432 if (!cdk.canInspect(properties)) {
3433 return cdk.VALIDATION_SUCCESS;
3434 }
3435 const errors = new cdk.ValidationResults();
3436 if (typeof properties !== 'object') {
3437 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3438 }
3439 errors.collect(cdk.propertyValidator('containerPath', cdk.validateString)(properties.containerPath));
3440 errors.collect(cdk.propertyValidator('readOnly', cdk.validateBoolean)(properties.readOnly));
3441 errors.collect(cdk.propertyValidator('sourceVolume', cdk.validateString)(properties.sourceVolume));
3442 return errors.wrap('supplied properties not correct for "MountPointProperty"');
3443}
3444/**
3445 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.MountPoint` resource
3446 *
3447 * @param properties - the TypeScript properties of a `MountPointProperty`
3448 *
3449 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.MountPoint` resource.
3450 */
3451// @ts-ignore TS6133
3452function cfnTaskDefinitionMountPointPropertyToCloudFormation(properties) {
3453 if (!cdk.canInspect(properties)) {
3454 return properties;
3455 }
3456 CfnTaskDefinition_MountPointPropertyValidator(properties).assertSuccess();
3457 return {
3458 ContainerPath: cdk.stringToCloudFormation(properties.containerPath),
3459 ReadOnly: cdk.booleanToCloudFormation(properties.readOnly),
3460 SourceVolume: cdk.stringToCloudFormation(properties.sourceVolume),
3461 };
3462}
3463// @ts-ignore TS6133
3464function CfnTaskDefinitionMountPointPropertyFromCloudFormation(properties) {
3465 if (cdk.isResolvableObject(properties)) {
3466 return new cfn_parse.FromCloudFormationResult(properties);
3467 }
3468 properties = properties == null ? {} : properties;
3469 if (typeof properties !== 'object') {
3470 return new cfn_parse.FromCloudFormationResult(properties);
3471 }
3472 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3473 ret.addPropertyResult('containerPath', 'ContainerPath', properties.ContainerPath != null ? cfn_parse.FromCloudFormation.getString(properties.ContainerPath) : undefined);
3474 ret.addPropertyResult('readOnly', 'ReadOnly', properties.ReadOnly != null ? cfn_parse.FromCloudFormation.getBoolean(properties.ReadOnly) : undefined);
3475 ret.addPropertyResult('sourceVolume', 'SourceVolume', properties.SourceVolume != null ? cfn_parse.FromCloudFormation.getString(properties.SourceVolume) : undefined);
3476 ret.addUnrecognizedPropertiesAsExtra(properties);
3477 return ret;
3478}
3479/**
3480 * Determine whether the given properties match those of a `PortMappingProperty`
3481 *
3482 * @param properties - the TypeScript properties of a `PortMappingProperty`
3483 *
3484 * @returns the result of the validation.
3485 */
3486function CfnTaskDefinition_PortMappingPropertyValidator(properties) {
3487 if (!cdk.canInspect(properties)) {
3488 return cdk.VALIDATION_SUCCESS;
3489 }
3490 const errors = new cdk.ValidationResults();
3491 if (typeof properties !== 'object') {
3492 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3493 }
3494 errors.collect(cdk.propertyValidator('appProtocol', cdk.validateString)(properties.appProtocol));
3495 errors.collect(cdk.propertyValidator('containerPort', cdk.validateNumber)(properties.containerPort));
3496 errors.collect(cdk.propertyValidator('containerPortRange', cdk.validateString)(properties.containerPortRange));
3497 errors.collect(cdk.propertyValidator('hostPort', cdk.validateNumber)(properties.hostPort));
3498 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
3499 errors.collect(cdk.propertyValidator('protocol', cdk.validateString)(properties.protocol));
3500 return errors.wrap('supplied properties not correct for "PortMappingProperty"');
3501}
3502/**
3503 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.PortMapping` resource
3504 *
3505 * @param properties - the TypeScript properties of a `PortMappingProperty`
3506 *
3507 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.PortMapping` resource.
3508 */
3509// @ts-ignore TS6133
3510function cfnTaskDefinitionPortMappingPropertyToCloudFormation(properties) {
3511 if (!cdk.canInspect(properties)) {
3512 return properties;
3513 }
3514 CfnTaskDefinition_PortMappingPropertyValidator(properties).assertSuccess();
3515 return {
3516 AppProtocol: cdk.stringToCloudFormation(properties.appProtocol),
3517 ContainerPort: cdk.numberToCloudFormation(properties.containerPort),
3518 ContainerPortRange: cdk.stringToCloudFormation(properties.containerPortRange),
3519 HostPort: cdk.numberToCloudFormation(properties.hostPort),
3520 Name: cdk.stringToCloudFormation(properties.name),
3521 Protocol: cdk.stringToCloudFormation(properties.protocol),
3522 };
3523}
3524// @ts-ignore TS6133
3525function CfnTaskDefinitionPortMappingPropertyFromCloudFormation(properties) {
3526 if (cdk.isResolvableObject(properties)) {
3527 return new cfn_parse.FromCloudFormationResult(properties);
3528 }
3529 properties = properties == null ? {} : properties;
3530 if (typeof properties !== 'object') {
3531 return new cfn_parse.FromCloudFormationResult(properties);
3532 }
3533 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3534 ret.addPropertyResult('appProtocol', 'AppProtocol', properties.AppProtocol != null ? cfn_parse.FromCloudFormation.getString(properties.AppProtocol) : undefined);
3535 ret.addPropertyResult('containerPort', 'ContainerPort', properties.ContainerPort != null ? cfn_parse.FromCloudFormation.getNumber(properties.ContainerPort) : undefined);
3536 ret.addPropertyResult('containerPortRange', 'ContainerPortRange', properties.ContainerPortRange != null ? cfn_parse.FromCloudFormation.getString(properties.ContainerPortRange) : undefined);
3537 ret.addPropertyResult('hostPort', 'HostPort', properties.HostPort != null ? cfn_parse.FromCloudFormation.getNumber(properties.HostPort) : undefined);
3538 ret.addPropertyResult('name', 'Name', properties.Name != null ? cfn_parse.FromCloudFormation.getString(properties.Name) : undefined);
3539 ret.addPropertyResult('protocol', 'Protocol', properties.Protocol != null ? cfn_parse.FromCloudFormation.getString(properties.Protocol) : undefined);
3540 ret.addUnrecognizedPropertiesAsExtra(properties);
3541 return ret;
3542}
3543/**
3544 * Determine whether the given properties match those of a `ProxyConfigurationProperty`
3545 *
3546 * @param properties - the TypeScript properties of a `ProxyConfigurationProperty`
3547 *
3548 * @returns the result of the validation.
3549 */
3550function CfnTaskDefinition_ProxyConfigurationPropertyValidator(properties) {
3551 if (!cdk.canInspect(properties)) {
3552 return cdk.VALIDATION_SUCCESS;
3553 }
3554 const errors = new cdk.ValidationResults();
3555 if (typeof properties !== 'object') {
3556 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3557 }
3558 errors.collect(cdk.propertyValidator('containerName', cdk.requiredValidator)(properties.containerName));
3559 errors.collect(cdk.propertyValidator('containerName', cdk.validateString)(properties.containerName));
3560 errors.collect(cdk.propertyValidator('proxyConfigurationProperties', cdk.listValidator(CfnTaskDefinition_KeyValuePairPropertyValidator))(properties.proxyConfigurationProperties));
3561 errors.collect(cdk.propertyValidator('type', cdk.validateString)(properties.type));
3562 return errors.wrap('supplied properties not correct for "ProxyConfigurationProperty"');
3563}
3564/**
3565 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.ProxyConfiguration` resource
3566 *
3567 * @param properties - the TypeScript properties of a `ProxyConfigurationProperty`
3568 *
3569 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.ProxyConfiguration` resource.
3570 */
3571// @ts-ignore TS6133
3572function cfnTaskDefinitionProxyConfigurationPropertyToCloudFormation(properties) {
3573 if (!cdk.canInspect(properties)) {
3574 return properties;
3575 }
3576 CfnTaskDefinition_ProxyConfigurationPropertyValidator(properties).assertSuccess();
3577 return {
3578 ContainerName: cdk.stringToCloudFormation(properties.containerName),
3579 ProxyConfigurationProperties: cdk.listMapper(cfnTaskDefinitionKeyValuePairPropertyToCloudFormation)(properties.proxyConfigurationProperties),
3580 Type: cdk.stringToCloudFormation(properties.type),
3581 };
3582}
3583// @ts-ignore TS6133
3584function CfnTaskDefinitionProxyConfigurationPropertyFromCloudFormation(properties) {
3585 if (cdk.isResolvableObject(properties)) {
3586 return new cfn_parse.FromCloudFormationResult(properties);
3587 }
3588 properties = properties == null ? {} : properties;
3589 if (typeof properties !== 'object') {
3590 return new cfn_parse.FromCloudFormationResult(properties);
3591 }
3592 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3593 ret.addPropertyResult('containerName', 'ContainerName', cfn_parse.FromCloudFormation.getString(properties.ContainerName));
3594 ret.addPropertyResult('proxyConfigurationProperties', 'ProxyConfigurationProperties', properties.ProxyConfigurationProperties != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskDefinitionKeyValuePairPropertyFromCloudFormation)(properties.ProxyConfigurationProperties) : undefined);
3595 ret.addPropertyResult('type', 'Type', properties.Type != null ? cfn_parse.FromCloudFormation.getString(properties.Type) : undefined);
3596 ret.addUnrecognizedPropertiesAsExtra(properties);
3597 return ret;
3598}
3599/**
3600 * Determine whether the given properties match those of a `RepositoryCredentialsProperty`
3601 *
3602 * @param properties - the TypeScript properties of a `RepositoryCredentialsProperty`
3603 *
3604 * @returns the result of the validation.
3605 */
3606function CfnTaskDefinition_RepositoryCredentialsPropertyValidator(properties) {
3607 if (!cdk.canInspect(properties)) {
3608 return cdk.VALIDATION_SUCCESS;
3609 }
3610 const errors = new cdk.ValidationResults();
3611 if (typeof properties !== 'object') {
3612 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3613 }
3614 errors.collect(cdk.propertyValidator('credentialsParameter', cdk.validateString)(properties.credentialsParameter));
3615 return errors.wrap('supplied properties not correct for "RepositoryCredentialsProperty"');
3616}
3617/**
3618 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.RepositoryCredentials` resource
3619 *
3620 * @param properties - the TypeScript properties of a `RepositoryCredentialsProperty`
3621 *
3622 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.RepositoryCredentials` resource.
3623 */
3624// @ts-ignore TS6133
3625function cfnTaskDefinitionRepositoryCredentialsPropertyToCloudFormation(properties) {
3626 if (!cdk.canInspect(properties)) {
3627 return properties;
3628 }
3629 CfnTaskDefinition_RepositoryCredentialsPropertyValidator(properties).assertSuccess();
3630 return {
3631 CredentialsParameter: cdk.stringToCloudFormation(properties.credentialsParameter),
3632 };
3633}
3634// @ts-ignore TS6133
3635function CfnTaskDefinitionRepositoryCredentialsPropertyFromCloudFormation(properties) {
3636 if (cdk.isResolvableObject(properties)) {
3637 return new cfn_parse.FromCloudFormationResult(properties);
3638 }
3639 properties = properties == null ? {} : properties;
3640 if (typeof properties !== 'object') {
3641 return new cfn_parse.FromCloudFormationResult(properties);
3642 }
3643 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3644 ret.addPropertyResult('credentialsParameter', 'CredentialsParameter', properties.CredentialsParameter != null ? cfn_parse.FromCloudFormation.getString(properties.CredentialsParameter) : undefined);
3645 ret.addUnrecognizedPropertiesAsExtra(properties);
3646 return ret;
3647}
3648/**
3649 * Determine whether the given properties match those of a `ResourceRequirementProperty`
3650 *
3651 * @param properties - the TypeScript properties of a `ResourceRequirementProperty`
3652 *
3653 * @returns the result of the validation.
3654 */
3655function CfnTaskDefinition_ResourceRequirementPropertyValidator(properties) {
3656 if (!cdk.canInspect(properties)) {
3657 return cdk.VALIDATION_SUCCESS;
3658 }
3659 const errors = new cdk.ValidationResults();
3660 if (typeof properties !== 'object') {
3661 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3662 }
3663 errors.collect(cdk.propertyValidator('type', cdk.requiredValidator)(properties.type));
3664 errors.collect(cdk.propertyValidator('type', cdk.validateString)(properties.type));
3665 errors.collect(cdk.propertyValidator('value', cdk.requiredValidator)(properties.value));
3666 errors.collect(cdk.propertyValidator('value', cdk.validateString)(properties.value));
3667 return errors.wrap('supplied properties not correct for "ResourceRequirementProperty"');
3668}
3669/**
3670 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.ResourceRequirement` resource
3671 *
3672 * @param properties - the TypeScript properties of a `ResourceRequirementProperty`
3673 *
3674 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.ResourceRequirement` resource.
3675 */
3676// @ts-ignore TS6133
3677function cfnTaskDefinitionResourceRequirementPropertyToCloudFormation(properties) {
3678 if (!cdk.canInspect(properties)) {
3679 return properties;
3680 }
3681 CfnTaskDefinition_ResourceRequirementPropertyValidator(properties).assertSuccess();
3682 return {
3683 Type: cdk.stringToCloudFormation(properties.type),
3684 Value: cdk.stringToCloudFormation(properties.value),
3685 };
3686}
3687// @ts-ignore TS6133
3688function CfnTaskDefinitionResourceRequirementPropertyFromCloudFormation(properties) {
3689 if (cdk.isResolvableObject(properties)) {
3690 return new cfn_parse.FromCloudFormationResult(properties);
3691 }
3692 properties = properties == null ? {} : properties;
3693 if (typeof properties !== 'object') {
3694 return new cfn_parse.FromCloudFormationResult(properties);
3695 }
3696 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3697 ret.addPropertyResult('type', 'Type', cfn_parse.FromCloudFormation.getString(properties.Type));
3698 ret.addPropertyResult('value', 'Value', cfn_parse.FromCloudFormation.getString(properties.Value));
3699 ret.addUnrecognizedPropertiesAsExtra(properties);
3700 return ret;
3701}
3702/**
3703 * Determine whether the given properties match those of a `RuntimePlatformProperty`
3704 *
3705 * @param properties - the TypeScript properties of a `RuntimePlatformProperty`
3706 *
3707 * @returns the result of the validation.
3708 */
3709function CfnTaskDefinition_RuntimePlatformPropertyValidator(properties) {
3710 if (!cdk.canInspect(properties)) {
3711 return cdk.VALIDATION_SUCCESS;
3712 }
3713 const errors = new cdk.ValidationResults();
3714 if (typeof properties !== 'object') {
3715 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3716 }
3717 errors.collect(cdk.propertyValidator('cpuArchitecture', cdk.validateString)(properties.cpuArchitecture));
3718 errors.collect(cdk.propertyValidator('operatingSystemFamily', cdk.validateString)(properties.operatingSystemFamily));
3719 return errors.wrap('supplied properties not correct for "RuntimePlatformProperty"');
3720}
3721/**
3722 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.RuntimePlatform` resource
3723 *
3724 * @param properties - the TypeScript properties of a `RuntimePlatformProperty`
3725 *
3726 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.RuntimePlatform` resource.
3727 */
3728// @ts-ignore TS6133
3729function cfnTaskDefinitionRuntimePlatformPropertyToCloudFormation(properties) {
3730 if (!cdk.canInspect(properties)) {
3731 return properties;
3732 }
3733 CfnTaskDefinition_RuntimePlatformPropertyValidator(properties).assertSuccess();
3734 return {
3735 CpuArchitecture: cdk.stringToCloudFormation(properties.cpuArchitecture),
3736 OperatingSystemFamily: cdk.stringToCloudFormation(properties.operatingSystemFamily),
3737 };
3738}
3739// @ts-ignore TS6133
3740function CfnTaskDefinitionRuntimePlatformPropertyFromCloudFormation(properties) {
3741 if (cdk.isResolvableObject(properties)) {
3742 return new cfn_parse.FromCloudFormationResult(properties);
3743 }
3744 properties = properties == null ? {} : properties;
3745 if (typeof properties !== 'object') {
3746 return new cfn_parse.FromCloudFormationResult(properties);
3747 }
3748 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3749 ret.addPropertyResult('cpuArchitecture', 'CpuArchitecture', properties.CpuArchitecture != null ? cfn_parse.FromCloudFormation.getString(properties.CpuArchitecture) : undefined);
3750 ret.addPropertyResult('operatingSystemFamily', 'OperatingSystemFamily', properties.OperatingSystemFamily != null ? cfn_parse.FromCloudFormation.getString(properties.OperatingSystemFamily) : undefined);
3751 ret.addUnrecognizedPropertiesAsExtra(properties);
3752 return ret;
3753}
3754/**
3755 * Determine whether the given properties match those of a `SecretProperty`
3756 *
3757 * @param properties - the TypeScript properties of a `SecretProperty`
3758 *
3759 * @returns the result of the validation.
3760 */
3761function CfnTaskDefinition_SecretPropertyValidator(properties) {
3762 if (!cdk.canInspect(properties)) {
3763 return cdk.VALIDATION_SUCCESS;
3764 }
3765 const errors = new cdk.ValidationResults();
3766 if (typeof properties !== 'object') {
3767 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3768 }
3769 errors.collect(cdk.propertyValidator('name', cdk.requiredValidator)(properties.name));
3770 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
3771 errors.collect(cdk.propertyValidator('valueFrom', cdk.requiredValidator)(properties.valueFrom));
3772 errors.collect(cdk.propertyValidator('valueFrom', cdk.validateString)(properties.valueFrom));
3773 return errors.wrap('supplied properties not correct for "SecretProperty"');
3774}
3775/**
3776 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.Secret` resource
3777 *
3778 * @param properties - the TypeScript properties of a `SecretProperty`
3779 *
3780 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.Secret` resource.
3781 */
3782// @ts-ignore TS6133
3783function cfnTaskDefinitionSecretPropertyToCloudFormation(properties) {
3784 if (!cdk.canInspect(properties)) {
3785 return properties;
3786 }
3787 CfnTaskDefinition_SecretPropertyValidator(properties).assertSuccess();
3788 return {
3789 Name: cdk.stringToCloudFormation(properties.name),
3790 ValueFrom: cdk.stringToCloudFormation(properties.valueFrom),
3791 };
3792}
3793// @ts-ignore TS6133
3794function CfnTaskDefinitionSecretPropertyFromCloudFormation(properties) {
3795 if (cdk.isResolvableObject(properties)) {
3796 return new cfn_parse.FromCloudFormationResult(properties);
3797 }
3798 properties = properties == null ? {} : properties;
3799 if (typeof properties !== 'object') {
3800 return new cfn_parse.FromCloudFormationResult(properties);
3801 }
3802 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3803 ret.addPropertyResult('name', 'Name', cfn_parse.FromCloudFormation.getString(properties.Name));
3804 ret.addPropertyResult('valueFrom', 'ValueFrom', cfn_parse.FromCloudFormation.getString(properties.ValueFrom));
3805 ret.addUnrecognizedPropertiesAsExtra(properties);
3806 return ret;
3807}
3808/**
3809 * Determine whether the given properties match those of a `SystemControlProperty`
3810 *
3811 * @param properties - the TypeScript properties of a `SystemControlProperty`
3812 *
3813 * @returns the result of the validation.
3814 */
3815function CfnTaskDefinition_SystemControlPropertyValidator(properties) {
3816 if (!cdk.canInspect(properties)) {
3817 return cdk.VALIDATION_SUCCESS;
3818 }
3819 const errors = new cdk.ValidationResults();
3820 if (typeof properties !== 'object') {
3821 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3822 }
3823 errors.collect(cdk.propertyValidator('namespace', cdk.validateString)(properties.namespace));
3824 errors.collect(cdk.propertyValidator('value', cdk.validateString)(properties.value));
3825 return errors.wrap('supplied properties not correct for "SystemControlProperty"');
3826}
3827/**
3828 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.SystemControl` resource
3829 *
3830 * @param properties - the TypeScript properties of a `SystemControlProperty`
3831 *
3832 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.SystemControl` resource.
3833 */
3834// @ts-ignore TS6133
3835function cfnTaskDefinitionSystemControlPropertyToCloudFormation(properties) {
3836 if (!cdk.canInspect(properties)) {
3837 return properties;
3838 }
3839 CfnTaskDefinition_SystemControlPropertyValidator(properties).assertSuccess();
3840 return {
3841 Namespace: cdk.stringToCloudFormation(properties.namespace),
3842 Value: cdk.stringToCloudFormation(properties.value),
3843 };
3844}
3845// @ts-ignore TS6133
3846function CfnTaskDefinitionSystemControlPropertyFromCloudFormation(properties) {
3847 if (cdk.isResolvableObject(properties)) {
3848 return new cfn_parse.FromCloudFormationResult(properties);
3849 }
3850 properties = properties == null ? {} : properties;
3851 if (typeof properties !== 'object') {
3852 return new cfn_parse.FromCloudFormationResult(properties);
3853 }
3854 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3855 ret.addPropertyResult('namespace', 'Namespace', properties.Namespace != null ? cfn_parse.FromCloudFormation.getString(properties.Namespace) : undefined);
3856 ret.addPropertyResult('value', 'Value', properties.Value != null ? cfn_parse.FromCloudFormation.getString(properties.Value) : undefined);
3857 ret.addUnrecognizedPropertiesAsExtra(properties);
3858 return ret;
3859}
3860/**
3861 * Determine whether the given properties match those of a `TaskDefinitionPlacementConstraintProperty`
3862 *
3863 * @param properties - the TypeScript properties of a `TaskDefinitionPlacementConstraintProperty`
3864 *
3865 * @returns the result of the validation.
3866 */
3867function CfnTaskDefinition_TaskDefinitionPlacementConstraintPropertyValidator(properties) {
3868 if (!cdk.canInspect(properties)) {
3869 return cdk.VALIDATION_SUCCESS;
3870 }
3871 const errors = new cdk.ValidationResults();
3872 if (typeof properties !== 'object') {
3873 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3874 }
3875 errors.collect(cdk.propertyValidator('expression', cdk.validateString)(properties.expression));
3876 errors.collect(cdk.propertyValidator('type', cdk.requiredValidator)(properties.type));
3877 errors.collect(cdk.propertyValidator('type', cdk.validateString)(properties.type));
3878 return errors.wrap('supplied properties not correct for "TaskDefinitionPlacementConstraintProperty"');
3879}
3880/**
3881 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.TaskDefinitionPlacementConstraint` resource
3882 *
3883 * @param properties - the TypeScript properties of a `TaskDefinitionPlacementConstraintProperty`
3884 *
3885 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.TaskDefinitionPlacementConstraint` resource.
3886 */
3887// @ts-ignore TS6133
3888function cfnTaskDefinitionTaskDefinitionPlacementConstraintPropertyToCloudFormation(properties) {
3889 if (!cdk.canInspect(properties)) {
3890 return properties;
3891 }
3892 CfnTaskDefinition_TaskDefinitionPlacementConstraintPropertyValidator(properties).assertSuccess();
3893 return {
3894 Expression: cdk.stringToCloudFormation(properties.expression),
3895 Type: cdk.stringToCloudFormation(properties.type),
3896 };
3897}
3898// @ts-ignore TS6133
3899function CfnTaskDefinitionTaskDefinitionPlacementConstraintPropertyFromCloudFormation(properties) {
3900 if (cdk.isResolvableObject(properties)) {
3901 return new cfn_parse.FromCloudFormationResult(properties);
3902 }
3903 properties = properties == null ? {} : properties;
3904 if (typeof properties !== 'object') {
3905 return new cfn_parse.FromCloudFormationResult(properties);
3906 }
3907 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3908 ret.addPropertyResult('expression', 'Expression', properties.Expression != null ? cfn_parse.FromCloudFormation.getString(properties.Expression) : undefined);
3909 ret.addPropertyResult('type', 'Type', cfn_parse.FromCloudFormation.getString(properties.Type));
3910 ret.addUnrecognizedPropertiesAsExtra(properties);
3911 return ret;
3912}
3913/**
3914 * Determine whether the given properties match those of a `TmpfsProperty`
3915 *
3916 * @param properties - the TypeScript properties of a `TmpfsProperty`
3917 *
3918 * @returns the result of the validation.
3919 */
3920function CfnTaskDefinition_TmpfsPropertyValidator(properties) {
3921 if (!cdk.canInspect(properties)) {
3922 return cdk.VALIDATION_SUCCESS;
3923 }
3924 const errors = new cdk.ValidationResults();
3925 if (typeof properties !== 'object') {
3926 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3927 }
3928 errors.collect(cdk.propertyValidator('containerPath', cdk.validateString)(properties.containerPath));
3929 errors.collect(cdk.propertyValidator('mountOptions', cdk.listValidator(cdk.validateString))(properties.mountOptions));
3930 errors.collect(cdk.propertyValidator('size', cdk.requiredValidator)(properties.size));
3931 errors.collect(cdk.propertyValidator('size', cdk.validateNumber)(properties.size));
3932 return errors.wrap('supplied properties not correct for "TmpfsProperty"');
3933}
3934/**
3935 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.Tmpfs` resource
3936 *
3937 * @param properties - the TypeScript properties of a `TmpfsProperty`
3938 *
3939 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.Tmpfs` resource.
3940 */
3941// @ts-ignore TS6133
3942function cfnTaskDefinitionTmpfsPropertyToCloudFormation(properties) {
3943 if (!cdk.canInspect(properties)) {
3944 return properties;
3945 }
3946 CfnTaskDefinition_TmpfsPropertyValidator(properties).assertSuccess();
3947 return {
3948 ContainerPath: cdk.stringToCloudFormation(properties.containerPath),
3949 MountOptions: cdk.listMapper(cdk.stringToCloudFormation)(properties.mountOptions),
3950 Size: cdk.numberToCloudFormation(properties.size),
3951 };
3952}
3953// @ts-ignore TS6133
3954function CfnTaskDefinitionTmpfsPropertyFromCloudFormation(properties) {
3955 if (cdk.isResolvableObject(properties)) {
3956 return new cfn_parse.FromCloudFormationResult(properties);
3957 }
3958 properties = properties == null ? {} : properties;
3959 if (typeof properties !== 'object') {
3960 return new cfn_parse.FromCloudFormationResult(properties);
3961 }
3962 const ret = new cfn_parse.FromCloudFormationPropertyObject();
3963 ret.addPropertyResult('containerPath', 'ContainerPath', properties.ContainerPath != null ? cfn_parse.FromCloudFormation.getString(properties.ContainerPath) : undefined);
3964 ret.addPropertyResult('mountOptions', 'MountOptions', properties.MountOptions != null ? cfn_parse.FromCloudFormation.getStringArray(properties.MountOptions) : undefined);
3965 ret.addPropertyResult('size', 'Size', cfn_parse.FromCloudFormation.getNumber(properties.Size));
3966 ret.addUnrecognizedPropertiesAsExtra(properties);
3967 return ret;
3968}
3969/**
3970 * Determine whether the given properties match those of a `UlimitProperty`
3971 *
3972 * @param properties - the TypeScript properties of a `UlimitProperty`
3973 *
3974 * @returns the result of the validation.
3975 */
3976function CfnTaskDefinition_UlimitPropertyValidator(properties) {
3977 if (!cdk.canInspect(properties)) {
3978 return cdk.VALIDATION_SUCCESS;
3979 }
3980 const errors = new cdk.ValidationResults();
3981 if (typeof properties !== 'object') {
3982 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
3983 }
3984 errors.collect(cdk.propertyValidator('hardLimit', cdk.requiredValidator)(properties.hardLimit));
3985 errors.collect(cdk.propertyValidator('hardLimit', cdk.validateNumber)(properties.hardLimit));
3986 errors.collect(cdk.propertyValidator('name', cdk.requiredValidator)(properties.name));
3987 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
3988 errors.collect(cdk.propertyValidator('softLimit', cdk.requiredValidator)(properties.softLimit));
3989 errors.collect(cdk.propertyValidator('softLimit', cdk.validateNumber)(properties.softLimit));
3990 return errors.wrap('supplied properties not correct for "UlimitProperty"');
3991}
3992/**
3993 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.Ulimit` resource
3994 *
3995 * @param properties - the TypeScript properties of a `UlimitProperty`
3996 *
3997 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.Ulimit` resource.
3998 */
3999// @ts-ignore TS6133
4000function cfnTaskDefinitionUlimitPropertyToCloudFormation(properties) {
4001 if (!cdk.canInspect(properties)) {
4002 return properties;
4003 }
4004 CfnTaskDefinition_UlimitPropertyValidator(properties).assertSuccess();
4005 return {
4006 HardLimit: cdk.numberToCloudFormation(properties.hardLimit),
4007 Name: cdk.stringToCloudFormation(properties.name),
4008 SoftLimit: cdk.numberToCloudFormation(properties.softLimit),
4009 };
4010}
4011// @ts-ignore TS6133
4012function CfnTaskDefinitionUlimitPropertyFromCloudFormation(properties) {
4013 if (cdk.isResolvableObject(properties)) {
4014 return new cfn_parse.FromCloudFormationResult(properties);
4015 }
4016 properties = properties == null ? {} : properties;
4017 if (typeof properties !== 'object') {
4018 return new cfn_parse.FromCloudFormationResult(properties);
4019 }
4020 const ret = new cfn_parse.FromCloudFormationPropertyObject();
4021 ret.addPropertyResult('hardLimit', 'HardLimit', cfn_parse.FromCloudFormation.getNumber(properties.HardLimit));
4022 ret.addPropertyResult('name', 'Name', cfn_parse.FromCloudFormation.getString(properties.Name));
4023 ret.addPropertyResult('softLimit', 'SoftLimit', cfn_parse.FromCloudFormation.getNumber(properties.SoftLimit));
4024 ret.addUnrecognizedPropertiesAsExtra(properties);
4025 return ret;
4026}
4027/**
4028 * Determine whether the given properties match those of a `VolumeProperty`
4029 *
4030 * @param properties - the TypeScript properties of a `VolumeProperty`
4031 *
4032 * @returns the result of the validation.
4033 */
4034function CfnTaskDefinition_VolumePropertyValidator(properties) {
4035 if (!cdk.canInspect(properties)) {
4036 return cdk.VALIDATION_SUCCESS;
4037 }
4038 const errors = new cdk.ValidationResults();
4039 if (typeof properties !== 'object') {
4040 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
4041 }
4042 errors.collect(cdk.propertyValidator('dockerVolumeConfiguration', CfnTaskDefinition_DockerVolumeConfigurationPropertyValidator)(properties.dockerVolumeConfiguration));
4043 errors.collect(cdk.propertyValidator('efsVolumeConfiguration', CfnTaskDefinition_EFSVolumeConfigurationPropertyValidator)(properties.efsVolumeConfiguration));
4044 errors.collect(cdk.propertyValidator('host', CfnTaskDefinition_HostVolumePropertiesPropertyValidator)(properties.host));
4045 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
4046 return errors.wrap('supplied properties not correct for "VolumeProperty"');
4047}
4048/**
4049 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.Volume` resource
4050 *
4051 * @param properties - the TypeScript properties of a `VolumeProperty`
4052 *
4053 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.Volume` resource.
4054 */
4055// @ts-ignore TS6133
4056function cfnTaskDefinitionVolumePropertyToCloudFormation(properties) {
4057 if (!cdk.canInspect(properties)) {
4058 return properties;
4059 }
4060 CfnTaskDefinition_VolumePropertyValidator(properties).assertSuccess();
4061 return {
4062 DockerVolumeConfiguration: cfnTaskDefinitionDockerVolumeConfigurationPropertyToCloudFormation(properties.dockerVolumeConfiguration),
4063 EFSVolumeConfiguration: cfnTaskDefinitionEFSVolumeConfigurationPropertyToCloudFormation(properties.efsVolumeConfiguration),
4064 Host: cfnTaskDefinitionHostVolumePropertiesPropertyToCloudFormation(properties.host),
4065 Name: cdk.stringToCloudFormation(properties.name),
4066 };
4067}
4068// @ts-ignore TS6133
4069function CfnTaskDefinitionVolumePropertyFromCloudFormation(properties) {
4070 if (cdk.isResolvableObject(properties)) {
4071 return new cfn_parse.FromCloudFormationResult(properties);
4072 }
4073 properties = properties == null ? {} : properties;
4074 if (typeof properties !== 'object') {
4075 return new cfn_parse.FromCloudFormationResult(properties);
4076 }
4077 const ret = new cfn_parse.FromCloudFormationPropertyObject();
4078 ret.addPropertyResult('dockerVolumeConfiguration', 'DockerVolumeConfiguration', properties.DockerVolumeConfiguration != null ? CfnTaskDefinitionDockerVolumeConfigurationPropertyFromCloudFormation(properties.DockerVolumeConfiguration) : undefined);
4079 ret.addPropertyResult('efsVolumeConfiguration', 'EFSVolumeConfiguration', properties.EFSVolumeConfiguration != null ? CfnTaskDefinitionEFSVolumeConfigurationPropertyFromCloudFormation(properties.EFSVolumeConfiguration) : undefined);
4080 ret.addPropertyResult('host', 'Host', properties.Host != null ? CfnTaskDefinitionHostVolumePropertiesPropertyFromCloudFormation(properties.Host) : undefined);
4081 ret.addPropertyResult('name', 'Name', properties.Name != null ? cfn_parse.FromCloudFormation.getString(properties.Name) : undefined);
4082 ret.addUnrecognizedPropertiesAsExtra(properties);
4083 return ret;
4084}
4085/**
4086 * Determine whether the given properties match those of a `VolumeFromProperty`
4087 *
4088 * @param properties - the TypeScript properties of a `VolumeFromProperty`
4089 *
4090 * @returns the result of the validation.
4091 */
4092function CfnTaskDefinition_VolumeFromPropertyValidator(properties) {
4093 if (!cdk.canInspect(properties)) {
4094 return cdk.VALIDATION_SUCCESS;
4095 }
4096 const errors = new cdk.ValidationResults();
4097 if (typeof properties !== 'object') {
4098 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
4099 }
4100 errors.collect(cdk.propertyValidator('readOnly', cdk.validateBoolean)(properties.readOnly));
4101 errors.collect(cdk.propertyValidator('sourceContainer', cdk.validateString)(properties.sourceContainer));
4102 return errors.wrap('supplied properties not correct for "VolumeFromProperty"');
4103}
4104/**
4105 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.VolumeFrom` resource
4106 *
4107 * @param properties - the TypeScript properties of a `VolumeFromProperty`
4108 *
4109 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskDefinition.VolumeFrom` resource.
4110 */
4111// @ts-ignore TS6133
4112function cfnTaskDefinitionVolumeFromPropertyToCloudFormation(properties) {
4113 if (!cdk.canInspect(properties)) {
4114 return properties;
4115 }
4116 CfnTaskDefinition_VolumeFromPropertyValidator(properties).assertSuccess();
4117 return {
4118 ReadOnly: cdk.booleanToCloudFormation(properties.readOnly),
4119 SourceContainer: cdk.stringToCloudFormation(properties.sourceContainer),
4120 };
4121}
4122// @ts-ignore TS6133
4123function CfnTaskDefinitionVolumeFromPropertyFromCloudFormation(properties) {
4124 if (cdk.isResolvableObject(properties)) {
4125 return new cfn_parse.FromCloudFormationResult(properties);
4126 }
4127 properties = properties == null ? {} : properties;
4128 if (typeof properties !== 'object') {
4129 return new cfn_parse.FromCloudFormationResult(properties);
4130 }
4131 const ret = new cfn_parse.FromCloudFormationPropertyObject();
4132 ret.addPropertyResult('readOnly', 'ReadOnly', properties.ReadOnly != null ? cfn_parse.FromCloudFormation.getBoolean(properties.ReadOnly) : undefined);
4133 ret.addPropertyResult('sourceContainer', 'SourceContainer', properties.SourceContainer != null ? cfn_parse.FromCloudFormation.getString(properties.SourceContainer) : undefined);
4134 ret.addUnrecognizedPropertiesAsExtra(properties);
4135 return ret;
4136}
4137/**
4138 * Determine whether the given properties match those of a `CfnTaskSetProps`
4139 *
4140 * @param properties - the TypeScript properties of a `CfnTaskSetProps`
4141 *
4142 * @returns the result of the validation.
4143 */
4144function CfnTaskSetPropsValidator(properties) {
4145 if (!cdk.canInspect(properties)) {
4146 return cdk.VALIDATION_SUCCESS;
4147 }
4148 const errors = new cdk.ValidationResults();
4149 if (typeof properties !== 'object') {
4150 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
4151 }
4152 errors.collect(cdk.propertyValidator('cluster', cdk.requiredValidator)(properties.cluster));
4153 errors.collect(cdk.propertyValidator('cluster', cdk.validateString)(properties.cluster));
4154 errors.collect(cdk.propertyValidator('externalId', cdk.validateString)(properties.externalId));
4155 errors.collect(cdk.propertyValidator('launchType', cdk.validateString)(properties.launchType));
4156 errors.collect(cdk.propertyValidator('loadBalancers', cdk.listValidator(CfnTaskSet_LoadBalancerPropertyValidator))(properties.loadBalancers));
4157 errors.collect(cdk.propertyValidator('networkConfiguration', CfnTaskSet_NetworkConfigurationPropertyValidator)(properties.networkConfiguration));
4158 errors.collect(cdk.propertyValidator('platformVersion', cdk.validateString)(properties.platformVersion));
4159 errors.collect(cdk.propertyValidator('scale', CfnTaskSet_ScalePropertyValidator)(properties.scale));
4160 errors.collect(cdk.propertyValidator('service', cdk.requiredValidator)(properties.service));
4161 errors.collect(cdk.propertyValidator('service', cdk.validateString)(properties.service));
4162 errors.collect(cdk.propertyValidator('serviceRegistries', cdk.listValidator(CfnTaskSet_ServiceRegistryPropertyValidator))(properties.serviceRegistries));
4163 errors.collect(cdk.propertyValidator('taskDefinition', cdk.requiredValidator)(properties.taskDefinition));
4164 errors.collect(cdk.propertyValidator('taskDefinition', cdk.validateString)(properties.taskDefinition));
4165 return errors.wrap('supplied properties not correct for "CfnTaskSetProps"');
4166}
4167/**
4168 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskSet` resource
4169 *
4170 * @param properties - the TypeScript properties of a `CfnTaskSetProps`
4171 *
4172 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskSet` resource.
4173 */
4174// @ts-ignore TS6133
4175function cfnTaskSetPropsToCloudFormation(properties) {
4176 if (!cdk.canInspect(properties)) {
4177 return properties;
4178 }
4179 CfnTaskSetPropsValidator(properties).assertSuccess();
4180 return {
4181 Cluster: cdk.stringToCloudFormation(properties.cluster),
4182 Service: cdk.stringToCloudFormation(properties.service),
4183 TaskDefinition: cdk.stringToCloudFormation(properties.taskDefinition),
4184 ExternalId: cdk.stringToCloudFormation(properties.externalId),
4185 LaunchType: cdk.stringToCloudFormation(properties.launchType),
4186 LoadBalancers: cdk.listMapper(cfnTaskSetLoadBalancerPropertyToCloudFormation)(properties.loadBalancers),
4187 NetworkConfiguration: cfnTaskSetNetworkConfigurationPropertyToCloudFormation(properties.networkConfiguration),
4188 PlatformVersion: cdk.stringToCloudFormation(properties.platformVersion),
4189 Scale: cfnTaskSetScalePropertyToCloudFormation(properties.scale),
4190 ServiceRegistries: cdk.listMapper(cfnTaskSetServiceRegistryPropertyToCloudFormation)(properties.serviceRegistries),
4191 };
4192}
4193// @ts-ignore TS6133
4194function CfnTaskSetPropsFromCloudFormation(properties) {
4195 properties = properties == null ? {} : properties;
4196 if (typeof properties !== 'object') {
4197 return new cfn_parse.FromCloudFormationResult(properties);
4198 }
4199 const ret = new cfn_parse.FromCloudFormationPropertyObject();
4200 ret.addPropertyResult('cluster', 'Cluster', cfn_parse.FromCloudFormation.getString(properties.Cluster));
4201 ret.addPropertyResult('service', 'Service', cfn_parse.FromCloudFormation.getString(properties.Service));
4202 ret.addPropertyResult('taskDefinition', 'TaskDefinition', cfn_parse.FromCloudFormation.getString(properties.TaskDefinition));
4203 ret.addPropertyResult('externalId', 'ExternalId', properties.ExternalId != null ? cfn_parse.FromCloudFormation.getString(properties.ExternalId) : undefined);
4204 ret.addPropertyResult('launchType', 'LaunchType', properties.LaunchType != null ? cfn_parse.FromCloudFormation.getString(properties.LaunchType) : undefined);
4205 ret.addPropertyResult('loadBalancers', 'LoadBalancers', properties.LoadBalancers != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskSetLoadBalancerPropertyFromCloudFormation)(properties.LoadBalancers) : undefined);
4206 ret.addPropertyResult('networkConfiguration', 'NetworkConfiguration', properties.NetworkConfiguration != null ? CfnTaskSetNetworkConfigurationPropertyFromCloudFormation(properties.NetworkConfiguration) : undefined);
4207 ret.addPropertyResult('platformVersion', 'PlatformVersion', properties.PlatformVersion != null ? cfn_parse.FromCloudFormation.getString(properties.PlatformVersion) : undefined);
4208 ret.addPropertyResult('scale', 'Scale', properties.Scale != null ? CfnTaskSetScalePropertyFromCloudFormation(properties.Scale) : undefined);
4209 ret.addPropertyResult('serviceRegistries', 'ServiceRegistries', properties.ServiceRegistries != null ? cfn_parse.FromCloudFormation.getArray(CfnTaskSetServiceRegistryPropertyFromCloudFormation)(properties.ServiceRegistries) : undefined);
4210 ret.addUnrecognizedPropertiesAsExtra(properties);
4211 return ret;
4212}
4213/**
4214 * A CloudFormation `AWS::ECS::TaskSet`
4215 *
4216 * Create a task set in the specified cluster and service. This is used when a service uses the `EXTERNAL` deployment controller type. For more information, see [Amazon ECS deployment types](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/deployment-types.html) in the *Amazon Elastic Container Service Developer Guide* .
4217 *
4218 * @cloudformationResource AWS::ECS::TaskSet
4219 * @stability external
4220 *
4221 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskset.html
4222 */
4223class CfnTaskSet extends cdk.CfnResource {
4224 /**
4225 * Create a new `AWS::ECS::TaskSet`.
4226 *
4227 * @param scope - scope in which this resource is defined
4228 * @param id - scoped id of the resource
4229 * @param props - resource properties
4230 */
4231 constructor(scope, id, props) {
4232 super(scope, id, { type: CfnTaskSet.CFN_RESOURCE_TYPE_NAME, properties: props });
4233 try {
4234 jsiiDeprecationWarnings._aws_cdk_aws_ecs_CfnTaskSetProps(props);
4235 }
4236 catch (error) {
4237 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
4238 Error.captureStackTrace(error, CfnTaskSet);
4239 }
4240 throw error;
4241 }
4242 cdk.requireProperty(props, 'cluster', this);
4243 cdk.requireProperty(props, 'service', this);
4244 cdk.requireProperty(props, 'taskDefinition', this);
4245 this.attrId = cdk.Token.asString(this.getAtt('Id'));
4246 this.cluster = props.cluster;
4247 this.service = props.service;
4248 this.taskDefinition = props.taskDefinition;
4249 this.externalId = props.externalId;
4250 this.launchType = props.launchType;
4251 this.loadBalancers = props.loadBalancers;
4252 this.networkConfiguration = props.networkConfiguration;
4253 this.platformVersion = props.platformVersion;
4254 this.scale = props.scale;
4255 this.serviceRegistries = props.serviceRegistries;
4256 }
4257 /**
4258 * A factory method that creates a new instance of this class from an object
4259 * containing the CloudFormation properties of this resource.
4260 * Used in the @aws-cdk/cloudformation-include module.
4261 *
4262 * @internal
4263 */
4264 static _fromCloudFormation(scope, id, resourceAttributes, options) {
4265 resourceAttributes = resourceAttributes || {};
4266 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
4267 const propsResult = CfnTaskSetPropsFromCloudFormation(resourceProperties);
4268 const ret = new CfnTaskSet(scope, id, propsResult.value);
4269 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
4270 ret.addPropertyOverride(propKey, propVal);
4271 }
4272 options.parser.handleAttributes(ret, resourceAttributes, id);
4273 return ret;
4274 }
4275 /**
4276 * Examines the CloudFormation resource and discloses attributes.
4277 *
4278 * @param inspector - tree inspector to collect and process attributes
4279 *
4280 */
4281 inspect(inspector) {
4282 inspector.addAttribute("aws:cdk:cloudformation:type", CfnTaskSet.CFN_RESOURCE_TYPE_NAME);
4283 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
4284 }
4285 get cfnProperties() {
4286 return {
4287 cluster: this.cluster,
4288 service: this.service,
4289 taskDefinition: this.taskDefinition,
4290 externalId: this.externalId,
4291 launchType: this.launchType,
4292 loadBalancers: this.loadBalancers,
4293 networkConfiguration: this.networkConfiguration,
4294 platformVersion: this.platformVersion,
4295 scale: this.scale,
4296 serviceRegistries: this.serviceRegistries,
4297 };
4298 }
4299 renderProperties(props) {
4300 return cfnTaskSetPropsToCloudFormation(props);
4301 }
4302}
4303exports.CfnTaskSet = CfnTaskSet;
4304_g = JSII_RTTI_SYMBOL_1;
4305CfnTaskSet[_g] = { fqn: "@aws-cdk/aws-ecs.CfnTaskSet", version: "1.204.0" };
4306/**
4307 * The CloudFormation resource type name for this resource class.
4308 */
4309CfnTaskSet.CFN_RESOURCE_TYPE_NAME = "AWS::ECS::TaskSet";
4310/**
4311 * Determine whether the given properties match those of a `AwsVpcConfigurationProperty`
4312 *
4313 * @param properties - the TypeScript properties of a `AwsVpcConfigurationProperty`
4314 *
4315 * @returns the result of the validation.
4316 */
4317function CfnTaskSet_AwsVpcConfigurationPropertyValidator(properties) {
4318 if (!cdk.canInspect(properties)) {
4319 return cdk.VALIDATION_SUCCESS;
4320 }
4321 const errors = new cdk.ValidationResults();
4322 if (typeof properties !== 'object') {
4323 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
4324 }
4325 errors.collect(cdk.propertyValidator('assignPublicIp', cdk.validateString)(properties.assignPublicIp));
4326 errors.collect(cdk.propertyValidator('securityGroups', cdk.listValidator(cdk.validateString))(properties.securityGroups));
4327 errors.collect(cdk.propertyValidator('subnets', cdk.requiredValidator)(properties.subnets));
4328 errors.collect(cdk.propertyValidator('subnets', cdk.listValidator(cdk.validateString))(properties.subnets));
4329 return errors.wrap('supplied properties not correct for "AwsVpcConfigurationProperty"');
4330}
4331/**
4332 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskSet.AwsVpcConfiguration` resource
4333 *
4334 * @param properties - the TypeScript properties of a `AwsVpcConfigurationProperty`
4335 *
4336 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskSet.AwsVpcConfiguration` resource.
4337 */
4338// @ts-ignore TS6133
4339function cfnTaskSetAwsVpcConfigurationPropertyToCloudFormation(properties) {
4340 if (!cdk.canInspect(properties)) {
4341 return properties;
4342 }
4343 CfnTaskSet_AwsVpcConfigurationPropertyValidator(properties).assertSuccess();
4344 return {
4345 AssignPublicIp: cdk.stringToCloudFormation(properties.assignPublicIp),
4346 SecurityGroups: cdk.listMapper(cdk.stringToCloudFormation)(properties.securityGroups),
4347 Subnets: cdk.listMapper(cdk.stringToCloudFormation)(properties.subnets),
4348 };
4349}
4350// @ts-ignore TS6133
4351function CfnTaskSetAwsVpcConfigurationPropertyFromCloudFormation(properties) {
4352 if (cdk.isResolvableObject(properties)) {
4353 return new cfn_parse.FromCloudFormationResult(properties);
4354 }
4355 properties = properties == null ? {} : properties;
4356 if (typeof properties !== 'object') {
4357 return new cfn_parse.FromCloudFormationResult(properties);
4358 }
4359 const ret = new cfn_parse.FromCloudFormationPropertyObject();
4360 ret.addPropertyResult('assignPublicIp', 'AssignPublicIp', properties.AssignPublicIp != null ? cfn_parse.FromCloudFormation.getString(properties.AssignPublicIp) : undefined);
4361 ret.addPropertyResult('securityGroups', 'SecurityGroups', properties.SecurityGroups != null ? cfn_parse.FromCloudFormation.getStringArray(properties.SecurityGroups) : undefined);
4362 ret.addPropertyResult('subnets', 'Subnets', cfn_parse.FromCloudFormation.getStringArray(properties.Subnets));
4363 ret.addUnrecognizedPropertiesAsExtra(properties);
4364 return ret;
4365}
4366/**
4367 * Determine whether the given properties match those of a `LoadBalancerProperty`
4368 *
4369 * @param properties - the TypeScript properties of a `LoadBalancerProperty`
4370 *
4371 * @returns the result of the validation.
4372 */
4373function CfnTaskSet_LoadBalancerPropertyValidator(properties) {
4374 if (!cdk.canInspect(properties)) {
4375 return cdk.VALIDATION_SUCCESS;
4376 }
4377 const errors = new cdk.ValidationResults();
4378 if (typeof properties !== 'object') {
4379 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
4380 }
4381 errors.collect(cdk.propertyValidator('containerName', cdk.validateString)(properties.containerName));
4382 errors.collect(cdk.propertyValidator('containerPort', cdk.validateNumber)(properties.containerPort));
4383 errors.collect(cdk.propertyValidator('loadBalancerName', cdk.validateString)(properties.loadBalancerName));
4384 errors.collect(cdk.propertyValidator('targetGroupArn', cdk.validateString)(properties.targetGroupArn));
4385 return errors.wrap('supplied properties not correct for "LoadBalancerProperty"');
4386}
4387/**
4388 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskSet.LoadBalancer` resource
4389 *
4390 * @param properties - the TypeScript properties of a `LoadBalancerProperty`
4391 *
4392 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskSet.LoadBalancer` resource.
4393 */
4394// @ts-ignore TS6133
4395function cfnTaskSetLoadBalancerPropertyToCloudFormation(properties) {
4396 if (!cdk.canInspect(properties)) {
4397 return properties;
4398 }
4399 CfnTaskSet_LoadBalancerPropertyValidator(properties).assertSuccess();
4400 return {
4401 ContainerName: cdk.stringToCloudFormation(properties.containerName),
4402 ContainerPort: cdk.numberToCloudFormation(properties.containerPort),
4403 LoadBalancerName: cdk.stringToCloudFormation(properties.loadBalancerName),
4404 TargetGroupArn: cdk.stringToCloudFormation(properties.targetGroupArn),
4405 };
4406}
4407// @ts-ignore TS6133
4408function CfnTaskSetLoadBalancerPropertyFromCloudFormation(properties) {
4409 if (cdk.isResolvableObject(properties)) {
4410 return new cfn_parse.FromCloudFormationResult(properties);
4411 }
4412 properties = properties == null ? {} : properties;
4413 if (typeof properties !== 'object') {
4414 return new cfn_parse.FromCloudFormationResult(properties);
4415 }
4416 const ret = new cfn_parse.FromCloudFormationPropertyObject();
4417 ret.addPropertyResult('containerName', 'ContainerName', properties.ContainerName != null ? cfn_parse.FromCloudFormation.getString(properties.ContainerName) : undefined);
4418 ret.addPropertyResult('containerPort', 'ContainerPort', properties.ContainerPort != null ? cfn_parse.FromCloudFormation.getNumber(properties.ContainerPort) : undefined);
4419 ret.addPropertyResult('loadBalancerName', 'LoadBalancerName', properties.LoadBalancerName != null ? cfn_parse.FromCloudFormation.getString(properties.LoadBalancerName) : undefined);
4420 ret.addPropertyResult('targetGroupArn', 'TargetGroupArn', properties.TargetGroupArn != null ? cfn_parse.FromCloudFormation.getString(properties.TargetGroupArn) : undefined);
4421 ret.addUnrecognizedPropertiesAsExtra(properties);
4422 return ret;
4423}
4424/**
4425 * Determine whether the given properties match those of a `NetworkConfigurationProperty`
4426 *
4427 * @param properties - the TypeScript properties of a `NetworkConfigurationProperty`
4428 *
4429 * @returns the result of the validation.
4430 */
4431function CfnTaskSet_NetworkConfigurationPropertyValidator(properties) {
4432 if (!cdk.canInspect(properties)) {
4433 return cdk.VALIDATION_SUCCESS;
4434 }
4435 const errors = new cdk.ValidationResults();
4436 if (typeof properties !== 'object') {
4437 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
4438 }
4439 errors.collect(cdk.propertyValidator('awsVpcConfiguration', CfnTaskSet_AwsVpcConfigurationPropertyValidator)(properties.awsVpcConfiguration));
4440 return errors.wrap('supplied properties not correct for "NetworkConfigurationProperty"');
4441}
4442/**
4443 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskSet.NetworkConfiguration` resource
4444 *
4445 * @param properties - the TypeScript properties of a `NetworkConfigurationProperty`
4446 *
4447 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskSet.NetworkConfiguration` resource.
4448 */
4449// @ts-ignore TS6133
4450function cfnTaskSetNetworkConfigurationPropertyToCloudFormation(properties) {
4451 if (!cdk.canInspect(properties)) {
4452 return properties;
4453 }
4454 CfnTaskSet_NetworkConfigurationPropertyValidator(properties).assertSuccess();
4455 return {
4456 AwsVpcConfiguration: cfnTaskSetAwsVpcConfigurationPropertyToCloudFormation(properties.awsVpcConfiguration),
4457 };
4458}
4459// @ts-ignore TS6133
4460function CfnTaskSetNetworkConfigurationPropertyFromCloudFormation(properties) {
4461 if (cdk.isResolvableObject(properties)) {
4462 return new cfn_parse.FromCloudFormationResult(properties);
4463 }
4464 properties = properties == null ? {} : properties;
4465 if (typeof properties !== 'object') {
4466 return new cfn_parse.FromCloudFormationResult(properties);
4467 }
4468 const ret = new cfn_parse.FromCloudFormationPropertyObject();
4469 ret.addPropertyResult('awsVpcConfiguration', 'AwsVpcConfiguration', properties.AwsVpcConfiguration != null ? CfnTaskSetAwsVpcConfigurationPropertyFromCloudFormation(properties.AwsVpcConfiguration) : undefined);
4470 ret.addUnrecognizedPropertiesAsExtra(properties);
4471 return ret;
4472}
4473/**
4474 * Determine whether the given properties match those of a `ScaleProperty`
4475 *
4476 * @param properties - the TypeScript properties of a `ScaleProperty`
4477 *
4478 * @returns the result of the validation.
4479 */
4480function CfnTaskSet_ScalePropertyValidator(properties) {
4481 if (!cdk.canInspect(properties)) {
4482 return cdk.VALIDATION_SUCCESS;
4483 }
4484 const errors = new cdk.ValidationResults();
4485 if (typeof properties !== 'object') {
4486 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
4487 }
4488 errors.collect(cdk.propertyValidator('unit', cdk.validateString)(properties.unit));
4489 errors.collect(cdk.propertyValidator('value', cdk.validateNumber)(properties.value));
4490 return errors.wrap('supplied properties not correct for "ScaleProperty"');
4491}
4492/**
4493 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskSet.Scale` resource
4494 *
4495 * @param properties - the TypeScript properties of a `ScaleProperty`
4496 *
4497 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskSet.Scale` resource.
4498 */
4499// @ts-ignore TS6133
4500function cfnTaskSetScalePropertyToCloudFormation(properties) {
4501 if (!cdk.canInspect(properties)) {
4502 return properties;
4503 }
4504 CfnTaskSet_ScalePropertyValidator(properties).assertSuccess();
4505 return {
4506 Unit: cdk.stringToCloudFormation(properties.unit),
4507 Value: cdk.numberToCloudFormation(properties.value),
4508 };
4509}
4510// @ts-ignore TS6133
4511function CfnTaskSetScalePropertyFromCloudFormation(properties) {
4512 if (cdk.isResolvableObject(properties)) {
4513 return new cfn_parse.FromCloudFormationResult(properties);
4514 }
4515 properties = properties == null ? {} : properties;
4516 if (typeof properties !== 'object') {
4517 return new cfn_parse.FromCloudFormationResult(properties);
4518 }
4519 const ret = new cfn_parse.FromCloudFormationPropertyObject();
4520 ret.addPropertyResult('unit', 'Unit', properties.Unit != null ? cfn_parse.FromCloudFormation.getString(properties.Unit) : undefined);
4521 ret.addPropertyResult('value', 'Value', properties.Value != null ? cfn_parse.FromCloudFormation.getNumber(properties.Value) : undefined);
4522 ret.addUnrecognizedPropertiesAsExtra(properties);
4523 return ret;
4524}
4525/**
4526 * Determine whether the given properties match those of a `ServiceRegistryProperty`
4527 *
4528 * @param properties - the TypeScript properties of a `ServiceRegistryProperty`
4529 *
4530 * @returns the result of the validation.
4531 */
4532function CfnTaskSet_ServiceRegistryPropertyValidator(properties) {
4533 if (!cdk.canInspect(properties)) {
4534 return cdk.VALIDATION_SUCCESS;
4535 }
4536 const errors = new cdk.ValidationResults();
4537 if (typeof properties !== 'object') {
4538 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
4539 }
4540 errors.collect(cdk.propertyValidator('containerName', cdk.validateString)(properties.containerName));
4541 errors.collect(cdk.propertyValidator('containerPort', cdk.validateNumber)(properties.containerPort));
4542 errors.collect(cdk.propertyValidator('port', cdk.validateNumber)(properties.port));
4543 errors.collect(cdk.propertyValidator('registryArn', cdk.validateString)(properties.registryArn));
4544 return errors.wrap('supplied properties not correct for "ServiceRegistryProperty"');
4545}
4546/**
4547 * Renders the AWS CloudFormation properties of an `AWS::ECS::TaskSet.ServiceRegistry` resource
4548 *
4549 * @param properties - the TypeScript properties of a `ServiceRegistryProperty`
4550 *
4551 * @returns the AWS CloudFormation properties of an `AWS::ECS::TaskSet.ServiceRegistry` resource.
4552 */
4553// @ts-ignore TS6133
4554function cfnTaskSetServiceRegistryPropertyToCloudFormation(properties) {
4555 if (!cdk.canInspect(properties)) {
4556 return properties;
4557 }
4558 CfnTaskSet_ServiceRegistryPropertyValidator(properties).assertSuccess();
4559 return {
4560 ContainerName: cdk.stringToCloudFormation(properties.containerName),
4561 ContainerPort: cdk.numberToCloudFormation(properties.containerPort),
4562 Port: cdk.numberToCloudFormation(properties.port),
4563 RegistryArn: cdk.stringToCloudFormation(properties.registryArn),
4564 };
4565}
4566// @ts-ignore TS6133
4567function CfnTaskSetServiceRegistryPropertyFromCloudFormation(properties) {
4568 if (cdk.isResolvableObject(properties)) {
4569 return new cfn_parse.FromCloudFormationResult(properties);
4570 }
4571 properties = properties == null ? {} : properties;
4572 if (typeof properties !== 'object') {
4573 return new cfn_parse.FromCloudFormationResult(properties);
4574 }
4575 const ret = new cfn_parse.FromCloudFormationPropertyObject();
4576 ret.addPropertyResult('containerName', 'ContainerName', properties.ContainerName != null ? cfn_parse.FromCloudFormation.getString(properties.ContainerName) : undefined);
4577 ret.addPropertyResult('containerPort', 'ContainerPort', properties.ContainerPort != null ? cfn_parse.FromCloudFormation.getNumber(properties.ContainerPort) : undefined);
4578 ret.addPropertyResult('port', 'Port', properties.Port != null ? cfn_parse.FromCloudFormation.getNumber(properties.Port) : undefined);
4579 ret.addPropertyResult('registryArn', 'RegistryArn', properties.RegistryArn != null ? cfn_parse.FromCloudFormation.getString(properties.RegistryArn) : undefined);
4580 ret.addUnrecognizedPropertiesAsExtra(properties);
4581 return ret;
4582}
4583//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNzLmdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImVjcy5nZW5lcmF0ZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsK0VBQStFO0FBQy9FLCtEQUErRDtBQUMvRCw4RkFBOEY7QUFDOUYsc0hBQXNIO0FBRXRILDRCQUE0QixDQUFDLGlFQUFpRTtBQUU5RixxQ0FBcUM7QUFDckMsZ0VBQWdFO0FBNENoRTs7Ozs7O0dBTUc7QUFDSCxTQUFTLGlDQUFpQyxDQUFDLFVBQWU7SUFDdEQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLEVBQUU7UUFBRSxPQUFPLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQztLQUFFO0lBQ25FLE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDM0MsSUFBSSxPQUFPLFVBQVUsS0FBSyxRQUFRLEVBQUU7UUFDaEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxvQ0FBb0MsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUMvRztJQUNELE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLDBCQUEwQixFQUFFLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLFVBQVUsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLENBQUM7SUFDOUgsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsMEJBQTBCLEVBQUUsNkRBQTZELENBQUMsQ0FBQyxVQUFVLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxDQUFDO0lBQ3RLLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDbkYs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QUFDLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNySSxHQUFHLENBQUMsaUJBQWlCLENBQUMsYUFBYSxFQUFFLGFBQWEsRUFBRSxVQUFVLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2pLLEdBQUcsQ0FBQyxnQ0FBZ0MsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNqRCxPQUFPLEdBQUcsQ0FBQztBQUNmLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxMi0yMDIzIEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4vLyBHZW5lcmF0ZWQgZnJvbSB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIFJlc291cmNlIFNwZWNpZmljYXRpb25cbi8vIFNlZTogZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2Nmbi1yZXNvdXJjZS1zcGVjaWZpY2F0aW9uLmh0bWxcbi8vIEBjZm4ydHM6bWV0YUAge1wiZ2VuZXJhdGVkXCI6XCIyMDIzLTA2LTE5VDE1OjIxOjMyLjQxNlpcIixcImZpbmdlcnByaW50XCI6XCJ4VEpQbUNhcTJ2N25LM21STTVLeHZuZmNrQlFBMFRYalVxalF5Mzhidy80PVwifVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovIC8vIFRoaXMgaXMgZ2VuZXJhdGVkIGNvZGUgLSBsaW5lIGxlbmd0aHMgYXJlIGRpZmZpY3VsdCB0byBjb250cm9sXG5cbmltcG9ydCAqIGFzIGNkayBmcm9tICdAYXdzLWNkay9jb3JlJztcbmltcG9ydCAqIGFzIGNmbl9wYXJzZSBmcm9tICdAYXdzLWNkay9jb3JlL2xpYi9oZWxwZXJzLWludGVybmFsJztcblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIGBDZm5DYXBhY2l0eVByb3ZpZGVyYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtY2FwYWNpdHlwcm92aWRlci5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2ZuQ2FwYWNpdHlQcm92aWRlclByb3BzIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBBdXRvIFNjYWxpbmcgZ3JvdXAgc2V0dGluZ3MgZm9yIHRoZSBjYXBhY2l0eSBwcm92aWRlci5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1jYXBhY2l0eXByb3ZpZGVyLmh0bWwjY2ZuLWVjcy1jYXBhY2l0eXByb3ZpZGVyLWF1dG9zY2FsaW5nZ3JvdXBwcm92aWRlclxuICAgICAqL1xuICAgIHJlYWRvbmx5IGF1dG9TY2FsaW5nR3JvdXBQcm92aWRlcjogQ2ZuQ2FwYWNpdHlQcm92aWRlci5BdXRvU2NhbGluZ0dyb3VwUHJvdmlkZXJQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBjYXBhY2l0eSBwcm92aWRlci4gSWYgYSBuYW1lIGlzIHNwZWNpZmllZCwgaXQgY2Fubm90IHN0YXJ0IHdpdGggYGF3c2AgLCBgZWNzYCAsIG9yIGBmYXJnYXRlYCAuIElmIG5vIG5hbWUgaXMgc3BlY2lmaWVkLCBhIGRlZmF1bHQgbmFtZSBpbiB0aGUgYENGTlN0YWNrTmFtZS1DRk5SZXNvdXJjZU5hbWUtUmFuZG9tU3RyaW5nYCBmb3JtYXQgaXMgdXNlZC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1jYXBhY2l0eXByb3ZpZGVyLmh0bWwjY2ZuLWVjcy1jYXBhY2l0eXByb3ZpZGVyLW5hbWVcbiAgICAgKi9cbiAgICByZWFkb25seSBuYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG1ldGFkYXRhIHRoYXQgeW91IGFwcGx5IHRvIHRoZSBjYXBhY2l0eSBwcm92aWRlciB0byBoZWxwIHlvdSBjYXRlZ29yaXplIGFuZCBvcmdhbml6ZSBpdC4gRWFjaCB0YWcgY29uc2lzdHMgb2YgYSBrZXkgYW5kIGFuIG9wdGlvbmFsIHZhbHVlLiBZb3UgZGVmaW5lIGJvdGguXG4gICAgICpcbiAgICAgKiBUaGUgZm9sbG93aW5nIGJhc2ljIHJlc3RyaWN0aW9ucyBhcHBseSB0byB0YWdzOlxuICAgICAqXG4gICAgICogLSBNYXhpbXVtIG51bWJlciBvZiB0YWdzIHBlciByZXNvdXJjZSAtIDUwXG4gICAgICogLSBGb3IgZWFjaCByZXNvdXJjZSwgZWFjaCB0YWcga2V5IG11c3QgYmUgdW5pcXVlLCBhbmQgZWFjaCB0YWcga2V5IGNhbiBoYXZlIG9ubHkgb25lIHZhbHVlLlxuICAgICAqIC0gTWF4aW11bSBrZXkgbGVuZ3RoIC0gMTI4IFVuaWNvZGUgY2hhcmFjdGVycyBpbiBVVEYtOFxuICAgICAqIC0gTWF4aW11bSB2YWx1ZSBsZW5ndGggLSAyNTYgVW5pY29kZSBjaGFyYWN0ZXJzIGluIFVURi04XG4gICAgICogLSBJZiB5b3VyIHRhZ2dpbmcgc2NoZW1hIGlzIHVzZWQgYWNyb3NzIG11bHRpcGxlIHNlcnZpY2VzIGFuZCByZXNvdXJjZXMsIHJlbWVtYmVyIHRoYXQgb3RoZXIgc2VydmljZXMgbWF5IGhhdmUgcmVzdHJpY3Rpb25zIG9uIGFsbG93ZWQgY2hhcmFjdGVycy4gR2VuZXJhbGx5IGFsbG93ZWQgY2hhcmFjdGVycyBhcmU6IGxldHRlcnMsIG51bWJlcnMsIGFuZCBzcGFjZXMgcmVwcmVzZW50YWJsZSBpbiBVVEYtOCwgYW5kIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogKyAtID0gLiBfIDogLyBALlxuICAgICAqIC0gVGFnIGtleXMgYW5kIHZhbHVlcyBhcmUgY2FzZS1zZW5zaXRpdmUuXG4gICAgICogLSBEbyBub3QgdXNlIGBhd3M6YCAsIGBBV1M6YCAsIG9yIGFueSB1cHBlciBvciBsb3dlcmNhc2UgY29tYmluYXRpb24gb2Ygc3VjaCBhcyBhIHByZWZpeCBmb3IgZWl0aGVyIGtleXMgb3IgdmFsdWVzIGFzIGl0IGlzIHJlc2VydmVkIGZvciBBV1MgdXNlLiBZb3UgY2Fubm90IGVkaXQgb3IgZGVsZXRlIHRhZyBrZXlzIG9yIHZhbHVlcyB3aXRoIHRoaXMgcHJlZml4LiBUYWdzIHdpdGggdGhpcyBwcmVmaXggZG8gbm90IGNvdW50IGFnYWluc3QgeW91ciB0YWdzIHBlciByZXNvdXJjZSBsaW1pdC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1jYXBhY2l0eXByb3ZpZGVyLmh0bWwjY2ZuLWVjcy1jYXBhY2l0eXByb3ZpZGVyLXRhZ3NcbiAgICAgKi9cbiAgICByZWFkb25seSB0YWdzPzogY2RrLkNmblRhZ1tdO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmbkNhcGFjaXR5UHJvdmlkZXJQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuQ2FwYWNpdHlQcm92aWRlclByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmbkNhcGFjaXR5UHJvdmlkZXJQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2F1dG9TY2FsaW5nR3JvdXBQcm92aWRlcicsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5hdXRvU2NhbGluZ0dyb3VwUHJvdmlkZXIpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2F1dG9TY2FsaW5nR3JvdXBQcm92aWRlcicsIENmbkNhcGFjaXR5UHJvdmlkZXJfQXV0b1NjYWxpbmdHcm91cFByb3ZpZGVyUHJvcGVydHlWYWxpZGF0b3IpKHByb3BlcnRpZXMuYXV0b1NjYWxpbmdHcm91cFByb3ZpZGVyKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCduYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLm5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3RhZ3MnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVDZm5UYWcpKShwcm9wZXJ0aWVzLnRhZ3MpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuQ2FwYWNpdHlQcm92aWRlclByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OkNhcGFjaXR5UHJvdmlkZXJgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbkNhcGFjaXR5UHJvdmlkZXJQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpDYXBhY2l0eVByb3ZpZGVyYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmbkNhcGFjaXR5UHJvdmlkZXJQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuQ2FwYWNpdHlQcm92aWRlclByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBBdXRvU2NhbGluZ0dyb3VwUHJvdmlkZXI6IGNmbkNhcGFjaXR5UHJvdmlkZXJBdXRvU2NhbGluZ0dyb3VwUHJvdmlkZXJQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5hdXRvU2NhbGluZ0dyb3VwUHJvdmlkZXIpLFxuICAgICAgICBOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm5hbWUpLFxuICAgICAgICBUYWdzOiBjZGsubGlzdE1hcHBlcihjZGsuY2ZuVGFnVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy50YWdzKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuQ2FwYWNpdHlQcm92aWRlclByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuQ2FwYWNpdHlQcm92aWRlclByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5DYXBhY2l0eVByb3ZpZGVyUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdhdXRvU2NhbGluZ0dyb3VwUHJvdmlkZXInLCAnQXV0b1NjYWxpbmdHcm91cFByb3ZpZGVyJywgQ2ZuQ2FwYWNpdHlQcm92aWRlckF1dG9TY2FsaW5nR3JvdXBQcm92aWRlclByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuQXV0b1NjYWxpbmdHcm91cFByb3ZpZGVyKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCduYW1lJywgJ05hbWUnLCBwcm9wZXJ0aWVzLk5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuTmFtZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndGFncycsICdUYWdzJywgcHJvcGVydGllcy5UYWdzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Q2ZuVGFnKShwcm9wZXJ0aWVzLlRhZ3MpIDogdW5kZWZpbmVkIGFzIGFueSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpFQ1M6OkNhcGFjaXR5UHJvdmlkZXJgXG4gKlxuICogQ3JlYXRlcyBhIG5ldyBjYXBhY2l0eSBwcm92aWRlci4gQ2FwYWNpdHkgcHJvdmlkZXJzIGFyZSBhc3NvY2lhdGVkIHdpdGggYW4gQW1hem9uIEVDUyBjbHVzdGVyIGFuZCBhcmUgdXNlZCBpbiBjYXBhY2l0eSBwcm92aWRlciBzdHJhdGVnaWVzIHRvIGZhY2lsaXRhdGUgY2x1c3RlciBhdXRvIHNjYWxpbmcuXG4gKlxuICogT25seSBjYXBhY2l0eSBwcm92aWRlcnMgdGhhdCB1c2UgYW4gQXV0byBTY2FsaW5nIGdyb3VwIGNhbiBiZSBjcmVhdGVkLiBBbWF6b24gRUNTIHRhc2tzIG9uIEFXUyBGYXJnYXRlIHVzZSB0aGUgYEZBUkdBVEVgIGFuZCBgRkFSR0FURV9TUE9UYCBjYXBhY2l0eSBwcm92aWRlcnMuIFRoZXNlIHByb3ZpZGVycyBhcmUgYXZhaWxhYmxlIHRvIGFsbCBhY2NvdW50cyBpbiB0aGUgQVdTIFJlZ2lvbnMgdGhhdCBBV1MgRmFyZ2F0ZSBzdXBwb3J0cy5cbiAqXG4gKiBAY2xvdWRmb3JtYXRpb25SZXNvdXJjZSBBV1M6OkVDUzo6Q2FwYWNpdHlQcm92aWRlclxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1jYXBhY2l0eXByb3ZpZGVyLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIENmbkNhcGFjaXR5UHJvdmlkZXIgZXh0ZW5kcyBjZGsuQ2ZuUmVzb3VyY2UgaW1wbGVtZW50cyBjZGsuSUluc3BlY3RhYmxlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgdHlwZSBuYW1lIGZvciB0aGlzIHJlc291cmNlIGNsYXNzLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSA9IFwiQVdTOjpFQ1M6OkNhcGFjaXR5UHJvdmlkZXJcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmbkNhcGFjaXR5UHJvdmlkZXIge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmbkNhcGFjaXR5UHJvdmlkZXJQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihyZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgQ2ZuQ2FwYWNpdHlQcm92aWRlcihzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgQXV0byBTY2FsaW5nIGdyb3VwIHNldHRpbmdzIGZvciB0aGUgY2FwYWNpdHkgcHJvdmlkZXIuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtY2FwYWNpdHlwcm92aWRlci5odG1sI2Nmbi1lY3MtY2FwYWNpdHlwcm92aWRlci1hdXRvc2NhbGluZ2dyb3VwcHJvdmlkZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgYXV0b1NjYWxpbmdHcm91cFByb3ZpZGVyOiBDZm5DYXBhY2l0eVByb3ZpZGVyLkF1dG9TY2FsaW5nR3JvdXBQcm92aWRlclByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGNhcGFjaXR5IHByb3ZpZGVyLiBJZiBhIG5hbWUgaXMgc3BlY2lmaWVkLCBpdCBjYW5ub3Qgc3RhcnQgd2l0aCBgYXdzYCAsIGBlY3NgICwgb3IgYGZhcmdhdGVgIC4gSWYgbm8gbmFtZSBpcyBzcGVjaWZpZWQsIGEgZGVmYXVsdCBuYW1lIGluIHRoZSBgQ0ZOU3RhY2tOYW1lLUNGTlJlc291cmNlTmFtZS1SYW5kb21TdHJpbmdgIGZvcm1hdCBpcyB1c2VkLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLWNhcGFjaXR5cHJvdmlkZXIuaHRtbCNjZm4tZWNzLWNhcGFjaXR5cHJvdmlkZXItbmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyBuYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWV0YWRhdGEgdGhhdCB5b3UgYXBwbHkgdG8gdGhlIGNhcGFjaXR5IHByb3ZpZGVyIHRvIGhlbHAgeW91IGNhdGVnb3JpemUgYW5kIG9yZ2FuaXplIGl0LiBFYWNoIHRhZyBjb25zaXN0cyBvZiBhIGtleSBhbmQgYW4gb3B0aW9uYWwgdmFsdWUuIFlvdSBkZWZpbmUgYm90aC5cbiAgICAgKlxuICAgICAqIFRoZSBmb2xsb3dpbmcgYmFzaWMgcmVzdHJpY3Rpb25zIGFwcGx5IHRvIHRhZ3M6XG4gICAgICpcbiAgICAgKiAtIE1heGltdW0gbnVtYmVyIG9mIHRhZ3MgcGVyIHJlc291cmNlIC0gNTBcbiAgICAgKiAtIEZvciBlYWNoIHJlc291cmNlLCBlYWNoIHRhZyBrZXkgbXVzdCBiZSB1bmlxdWUsIGFuZCBlYWNoIHRhZyBrZXkgY2FuIGhhdmUgb25seSBvbmUgdmFsdWUuXG4gICAgICogLSBNYXhpbXVtIGtleSBsZW5ndGggLSAxMjggVW5pY29kZSBjaGFyYWN0ZXJzIGluIFVURi04XG4gICAgICogLSBNYXhpbXVtIHZhbHVlIGxlbmd0aCAtIDI1NiBVbmljb2RlIGNoYXJhY3RlcnMgaW4gVVRGLThcbiAgICAgKiAtIElmIHlvdXIgdGFnZ2luZyBzY2hlbWEgaXMgdXNlZCBhY3Jvc3MgbXVsdGlwbGUgc2VydmljZXMgYW5kIHJlc291cmNlcywgcmVtZW1iZXIgdGhhdCBvdGhlciBzZXJ2aWNlcyBtYXkgaGF2ZSByZXN0cmljdGlvbnMgb24gYWxsb3dlZCBjaGFyYWN0ZXJzLiBHZW5lcmFsbHkgYWxsb3dlZCBjaGFyYWN0ZXJzIGFyZTogbGV0dGVycywgbnVtYmVycywgYW5kIHNwYWNlcyByZXByZXNlbnRhYmxlIGluIFVURi04LCBhbmQgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiArIC0gPSAuIF8gOiAvIEAuXG4gICAgICogLSBUYWcga2V5cyBhbmQgdmFsdWVzIGFyZSBjYXNlLXNlbnNpdGl2ZS5cbiAgICAgKiAtIERvIG5vdCB1c2UgYGF3czpgICwgYEFXUzpgICwgb3IgYW55IHVwcGVyIG9yIGxvd2VyY2FzZSBjb21iaW5hdGlvbiBvZiBzdWNoIGFzIGEgcHJlZml4IGZvciBlaXRoZXIga2V5cyBvciB2YWx1ZXMgYXMgaXQgaXMgcmVzZXJ2ZWQgZm9yIEFXUyB1c2UuIFlvdSBjYW5ub3QgZWRpdCBvciBkZWxldGUgdGFnIGtleXMgb3IgdmFsdWVzIHdpdGggdGhpcyBwcmVmaXguIFRhZ3Mgd2l0aCB0aGlzIHByZWZpeCBkbyBub3QgY291bnQgYWdhaW5zdCB5b3VyIHRhZ3MgcGVyIHJlc291cmNlIGxpbWl0LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLWNhcGFjaXR5cHJvdmlkZXIuaHRtbCNjZm4tZWNzLWNhcGFjaXR5cHJvdmlkZXItdGFnc1xuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSB0YWdzOiBjZGsuVGFnTWFuYWdlcjtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpFQ1M6OkNhcGFjaXR5UHJvdmlkZXJgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNjb3BlIC0gc2NvcGUgaW4gd2hpY2ggdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkXG4gICAgICogQHBhcmFtIGlkICAgIC0gc2NvcGVkIGlkIG9mIHRoZSByZXNvdXJjZVxuICAgICAqIEBwYXJhbSBwcm9wcyAtIHJlc291cmNlIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENmbkNhcGFjaXR5UHJvdmlkZXJQcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuQ2FwYWNpdHlQcm92aWRlci5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ2F1dG9TY2FsaW5nR3JvdXBQcm92aWRlcicsIHRoaXMpO1xuXG4gICAgICAgIHRoaXMuYXV0b1NjYWxpbmdHcm91cFByb3ZpZGVyID0gcHJvcHMuYXV0b1NjYWxpbmdHcm91cFByb3ZpZGVyO1xuICAgICAgICB0aGlzLm5hbWUgPSBwcm9wcy5uYW1lO1xuICAgICAgICB0aGlzLnRhZ3MgPSBuZXcgY2RrLlRhZ01hbmFnZXIoY2RrLlRhZ1R5cGUuU1RBTkRBUkQsIFwiQVdTOjpFQ1M6OkNhcGFjaXR5UHJvdmlkZXJcIiwgcHJvcHMudGFncywgeyB0YWdQcm9wZXJ0eU5hbWU6ICd0YWdzJyB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmbkNhcGFjaXR5UHJvdmlkZXIuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGF1dG9TY2FsaW5nR3JvdXBQcm92aWRlcjogdGhpcy5hdXRvU2NhbGluZ0dyb3VwUHJvdmlkZXIsXG4gICAgICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgICAgICB0YWdzOiB0aGlzLnRhZ3MucmVuZGVyVGFncygpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmbkNhcGFjaXR5UHJvdmlkZXJQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcHMpO1xuICAgIH1cbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5DYXBhY2l0eVByb3ZpZGVyIHtcbiAgICAvKipcbiAgICAgKiBUaGUgZGV0YWlscyBvZiB0aGUgQXV0byBTY2FsaW5nIGdyb3VwIGZvciB0aGUgY2FwYWNpdHkgcHJvdmlkZXIuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtY2FwYWNpdHlwcm92aWRlci1hdXRvc2NhbGluZ2dyb3VwcHJvdmlkZXIuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgQXV0b1NjYWxpbmdHcm91cFByb3ZpZGVyUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIHRoYXQgaWRlbnRpZmllcyB0aGUgQXV0byBTY2FsaW5nIGdyb3VwLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1jYXBhY2l0eXByb3ZpZGVyLWF1dG9zY2FsaW5nZ3JvdXBwcm92aWRlci5odG1sI2Nmbi1lY3MtY2FwYWNpdHlwcm92aWRlci1hdXRvc2NhbGluZ2dyb3VwcHJvdmlkZXItYXV0b3NjYWxpbmdncm91cGFyblxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgYXV0b1NjYWxpbmdHcm91cEFybjogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG1hbmFnZWQgc2NhbGluZyBzZXR0aW5ncyBmb3IgdGhlIEF1dG8gU2NhbGluZyBncm91cCBjYXBhY2l0eSBwcm92aWRlci5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtY2FwYWNpdHlwcm92aWRlci1hdXRvc2NhbGluZ2dyb3VwcHJvdmlkZXIuaHRtbCNjZm4tZWNzLWNhcGFjaXR5cHJvdmlkZXItYXV0b3NjYWxpbmdncm91cHByb3ZpZGVyLW1hbmFnZWRzY2FsaW5nXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBtYW5hZ2VkU2NhbGluZz86IENmbkNhcGFjaXR5UHJvdmlkZXIuTWFuYWdlZFNjYWxpbmdQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBtYW5hZ2VkIHRlcm1pbmF0aW9uIHByb3RlY3Rpb24gc2V0dGluZyB0byB1c2UgZm9yIHRoZSBBdXRvIFNjYWxpbmcgZ3JvdXAgY2FwYWNpdHkgcHJvdmlkZXIuIFRoaXMgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBBdXRvIFNjYWxpbmcgZ3JvdXAgaGFzIG1hbmFnZWQgdGVybWluYXRpb24gcHJvdGVjdGlvbi4gVGhlIGRlZmF1bHQgaXMgb2ZmLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFdoZW4gdXNpbmcgbWFuYWdlZCB0ZXJtaW5hdGlvbiBwcm90ZWN0aW9uLCBtYW5hZ2VkIHNjYWxpbmcgbXVzdCBhbHNvIGJlIHVzZWQgb3RoZXJ3aXNlIG1hbmFnZWQgdGVybWluYXRpb24gcHJvdGVjdGlvbiBkb2Vzbid0IHdvcmsuXG4gICAgICAgICAqXG4gICAgICAgICAqIFdoZW4gbWFuYWdlZCB0ZXJtaW5hdGlvbiBwcm90ZWN0aW9uIGlzIG9uLCBBbWF6b24gRUNTIHByZXZlbnRzIHRoZSBBbWF6b24gRUMyIGluc3RhbmNlcyBpbiBhbiBBdXRvIFNjYWxpbmcgZ3JvdXAgdGhhdCBjb250YWluIHRhc2tzIGZyb20gYmVpbmcgdGVybWluYXRlZCBkdXJpbmcgYSBzY2FsZS1pbiBhY3Rpb24uIFRoZSBBdXRvIFNjYWxpbmcgZ3JvdXAgYW5kIGVhY2ggaW5zdGFuY2UgaW4gdGhlIEF1dG8gU2NhbGluZyBncm91cCBtdXN0IGhhdmUgaW5zdGFuY2UgcHJvdGVjdGlvbiBmcm9tIHNjYWxlLWluIGFjdGlvbnMgb24gYXMgd2VsbC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbSW5zdGFuY2UgUHJvdGVjdGlvbl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2F1dG9zY2FsaW5nL2VjMi91c2VyZ3VpZGUvYXMtaW5zdGFuY2UtdGVybWluYXRpb24uaHRtbCNpbnN0YW5jZS1wcm90ZWN0aW9uKSBpbiB0aGUgKkFXUyBBdXRvIFNjYWxpbmcgVXNlciBHdWlkZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiBXaGVuIG1hbmFnZWQgdGVybWluYXRpb24gcHJvdGVjdGlvbiBpcyBvZmYsIHlvdXIgQW1hem9uIEVDMiBpbnN0YW5jZXMgYXJlbid0IHByb3RlY3RlZCBmcm9tIHRlcm1pbmF0aW9uIHdoZW4gdGhlIEF1dG8gU2NhbGluZyBncm91cCBzY2FsZXMgaW4uXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLWNhcGFjaXR5cHJvdmlkZXItYXV0b3NjYWxpbmdncm91cHByb3ZpZGVyLmh0bWwjY2ZuLWVjcy1jYXBhY2l0eXByb3ZpZGVyLWF1dG9zY2FsaW5nZ3JvdXBwcm92aWRlci1tYW5hZ2VkdGVybWluYXRpb25wcm90ZWN0aW9uXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBtYW5hZ2VkVGVybWluYXRpb25Qcm90ZWN0aW9uPzogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBBdXRvU2NhbGluZ0dyb3VwUHJvdmlkZXJQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQXV0b1NjYWxpbmdHcm91cFByb3ZpZGVyUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuQ2FwYWNpdHlQcm92aWRlcl9BdXRvU2NhbGluZ0dyb3VwUHJvdmlkZXJQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2F1dG9TY2FsaW5nR3JvdXBBcm4nLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMuYXV0b1NjYWxpbmdHcm91cEFybikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignYXV0b1NjYWxpbmdHcm91cEFybicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5hdXRvU2NhbGluZ0dyb3VwQXJuKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdtYW5hZ2VkU2NhbGluZycsIENmbkNhcGFjaXR5UHJvdmlkZXJfTWFuYWdlZFNjYWxpbmdQcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5tYW5hZ2VkU2NhbGluZykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbWFuYWdlZFRlcm1pbmF0aW9uUHJvdGVjdGlvbicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5tYW5hZ2VkVGVybWluYXRpb25Qcm90ZWN0aW9uKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkF1dG9TY2FsaW5nR3JvdXBQcm92aWRlclByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OkNhcGFjaXR5UHJvdmlkZXIuQXV0b1NjYWxpbmdHcm91cFByb3ZpZGVyYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBBdXRvU2NhbGluZ0dyb3VwUHJvdmlkZXJQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpDYXBhY2l0eVByb3ZpZGVyLkF1dG9TY2FsaW5nR3JvdXBQcm92aWRlcmAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5DYXBhY2l0eVByb3ZpZGVyQXV0b1NjYWxpbmdHcm91cFByb3ZpZGVyUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbkNhcGFjaXR5UHJvdmlkZXJfQXV0b1NjYWxpbmdHcm91cFByb3ZpZGVyUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEF1dG9TY2FsaW5nR3JvdXBBcm46IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuYXV0b1NjYWxpbmdHcm91cEFybiksXG4gICAgICAgIE1hbmFnZWRTY2FsaW5nOiBjZm5DYXBhY2l0eVByb3ZpZGVyTWFuYWdlZFNjYWxpbmdQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5tYW5hZ2VkU2NhbGluZyksXG4gICAgICAgIE1hbmFnZWRUZXJtaW5hdGlvblByb3RlY3Rpb246IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubWFuYWdlZFRlcm1pbmF0aW9uUHJvdGVjdGlvbiksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkNhcGFjaXR5UHJvdmlkZXJBdXRvU2NhbGluZ0dyb3VwUHJvdmlkZXJQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbkNhcGFjaXR5UHJvdmlkZXIuQXV0b1NjYWxpbmdHcm91cFByb3ZpZGVyUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuQ2FwYWNpdHlQcm92aWRlci5BdXRvU2NhbGluZ0dyb3VwUHJvdmlkZXJQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2F1dG9TY2FsaW5nR3JvdXBBcm4nLCAnQXV0b1NjYWxpbmdHcm91cEFybicsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQXV0b1NjYWxpbmdHcm91cEFybikpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbWFuYWdlZFNjYWxpbmcnLCAnTWFuYWdlZFNjYWxpbmcnLCBwcm9wZXJ0aWVzLk1hbmFnZWRTY2FsaW5nICE9IG51bGwgPyBDZm5DYXBhY2l0eVByb3ZpZGVyTWFuYWdlZFNjYWxpbmdQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLk1hbmFnZWRTY2FsaW5nKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdtYW5hZ2VkVGVybWluYXRpb25Qcm90ZWN0aW9uJywgJ01hbmFnZWRUZXJtaW5hdGlvblByb3RlY3Rpb24nLCBwcm9wZXJ0aWVzLk1hbmFnZWRUZXJtaW5hdGlvblByb3RlY3Rpb24gIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuTWFuYWdlZFRlcm1pbmF0aW9uUHJvdGVjdGlvbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmbkNhcGFjaXR5UHJvdmlkZXIge1xuICAgIC8qKlxuICAgICAqIFRoZSBtYW5hZ2VkIHNjYWxpbmcgc2V0dGluZ3MgZm9yIHRoZSBBdXRvIFNjYWxpbmcgZ3JvdXAgY2FwYWNpdHkgcHJvdmlkZXIuXG4gICAgICpcbiAgICAgKiBXaGVuIG1hbmFnZWQgc2NhbGluZyBpcyB0dXJuZWQgb24sIEFtYXpvbiBFQ1MgbWFuYWdlcyB0aGUgc2NhbGUtaW4gYW5kIHNjYWxlLW91dCBhY3Rpb25zIG9mIHRoZSBBdXRvIFNjYWxpbmcgZ3JvdXAuIEFtYXpvbiBFQ1MgbWFuYWdlcyBhIHRhcmdldCB0cmFja2luZyBzY2FsaW5nIHBvbGljeSB1c2luZyBhbiBBbWF6b24gRUNTIG1hbmFnZWQgQ2xvdWRXYXRjaCBtZXRyaWMgd2l0aCB0aGUgc3BlY2lmaWVkIGB0YXJnZXRDYXBhY2l0eWAgdmFsdWUgYXMgdGhlIHRhcmdldCB2YWx1ZSBmb3IgdGhlIG1ldHJpYy4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbVXNpbmcgbWFuYWdlZCBzY2FsaW5nXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9hc2ctY2FwYWNpdHktcHJvdmlkZXJzLmh0bWwjYXNnLWNhcGFjaXR5LXByb3ZpZGVycy1tYW5hZ2VkLXNjYWxpbmcpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBJZiBtYW5hZ2VkIHNjYWxpbmcgaXMgb2ZmLCB0aGUgdXNlciBtdXN0IG1hbmFnZSB0aGUgc2NhbGluZyBvZiB0aGUgQXV0byBTY2FsaW5nIGdyb3VwLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLWNhcGFjaXR5cHJvdmlkZXItbWFuYWdlZHNjYWxpbmcuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgTWFuYWdlZFNjYWxpbmdQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcGVyaW9kIG9mIHRpbWUsIGluIHNlY29uZHMsIGFmdGVyIGEgbmV3bHkgbGF1bmNoZWQgQW1hem9uIEVDMiBpbnN0YW5jZSBjYW4gY29udHJpYnV0ZSB0byBDbG91ZFdhdGNoIG1ldHJpY3MgZm9yIEF1dG8gU2NhbGluZyBncm91cC4gSWYgdGhpcyBwYXJhbWV0ZXIgaXMgb21pdHRlZCwgdGhlIGRlZmF1bHQgdmFsdWUgb2YgYDMwMGAgc2Vjb25kcyBpcyB1c2VkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1jYXBhY2l0eXByb3ZpZGVyLW1hbmFnZWRzY2FsaW5nLmh0bWwjY2ZuLWVjcy1jYXBhY2l0eXByb3ZpZGVyLW1hbmFnZWRzY2FsaW5nLWluc3RhbmNld2FybXVwcGVyaW9kXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBpbnN0YW5jZVdhcm11cFBlcmlvZD86IG51bWJlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBtYXhpbXVtIG51bWJlciBvZiBBbWF6b24gRUMyIGluc3RhbmNlcyB0aGF0IEFtYXpvbiBFQ1Mgd2lsbCBzY2FsZSBvdXQgYXQgb25lIHRpbWUuIFRoZSBzY2FsZSBpbiBwcm9jZXNzIGlzIG5vdCBhZmZlY3RlZCBieSB0aGlzIHBhcmFtZXRlci4gSWYgdGhpcyBwYXJhbWV0ZXIgaXMgb21pdHRlZCwgdGhlIGRlZmF1bHQgdmFsdWUgb2YgYDFgIGlzIHVzZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLWNhcGFjaXR5cHJvdmlkZXItbWFuYWdlZHNjYWxpbmcuaHRtbCNjZm4tZWNzLWNhcGFjaXR5cHJvdmlkZXItbWFuYWdlZHNjYWxpbmctbWF4aW11bXNjYWxpbmdzdGVwc2l6ZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbWF4aW11bVNjYWxpbmdTdGVwU2l6ZT86IG51bWJlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBtaW5pbXVtIG51bWJlciBvZiBBbWF6b24gRUMyIGluc3RhbmNlcyB0aGF0IEFtYXpvbiBFQ1Mgd2lsbCBzY2FsZSBvdXQgYXQgb25lIHRpbWUuIFRoZSBzY2FsZSBpbiBwcm9jZXNzIGlzIG5vdCBhZmZlY3RlZCBieSB0aGlzIHBhcmFtZXRlciBJZiB0aGlzIHBhcmFtZXRlciBpcyBvbWl0dGVkLCB0aGUgZGVmYXVsdCB2YWx1ZSBvZiBgMWAgaXMgdXNlZC5cbiAgICAgICAgICpcbiAgICAgICAgICogV2hlbiBhZGRpdGlvbmFsIGNhcGFjaXR5IGlzIHJlcXVpcmVkLCBBbWF6b24gRUNTIHdpbGwgc2NhbGUgdXAgdGhlIG1pbmltdW0gc2NhbGluZyBzdGVwIHNpemUgZXZlbiBpZiB0aGUgYWN0dWFsIGRlbWFuZCBpcyBsZXNzIHRoYW4gdGhlIG1pbmltdW0gc2NhbGluZyBzdGVwIHNpemUuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSB1c2UgYSBjYXBhY2l0eSBwcm92aWRlciB3aXRoIGFuIEF1dG8gU2NhbGluZyBncm91cCBjb25maWd1cmVkIHdpdGggbW9yZSB0aGFuIG9uZSBBbWF6b24gRUMyIGluc3RhbmNlIHR5cGUgb3IgQXZhaWxhYmlsaXR5IFpvbmUsIEFtYXpvbiBFQ1Mgd2lsbCBzY2FsZSB1cCBieSB0aGUgZXhhY3QgbWluaW11bSBzY2FsaW5nIHN0ZXAgc2l6ZSB2YWx1ZSBhbmQgd2lsbCBpZ25vcmUgYm90aCB0aGUgbWF4aW11bSBzY2FsaW5nIHN0ZXAgc2l6ZSBhcyB3ZWxsIGFzIHRoZSBjYXBhY2l0eSBkZW1hbmQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLWNhcGFjaXR5cHJvdmlkZXItbWFuYWdlZHNjYWxpbmcuaHRtbCNjZm4tZWNzLWNhcGFjaXR5cHJvdmlkZXItbWFuYWdlZHNjYWxpbmctbWluaW11bXNjYWxpbmdzdGVwc2l6ZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbWluaW11bVNjYWxpbmdTdGVwU2l6ZT86IG51bWJlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERldGVybWluZXMgd2hldGhlciB0byB1c2UgbWFuYWdlZCBzY2FsaW5nIGZvciB0aGUgY2FwYWNpdHkgcHJvdmlkZXIuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLWNhcGFjaXR5cHJvdmlkZXItbWFuYWdlZHNjYWxpbmcuaHRtbCNjZm4tZWNzLWNhcGFjaXR5cHJvdmlkZXItbWFuYWdlZHNjYWxpbmctc3RhdHVzXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBzdGF0dXM/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdGFyZ2V0IGNhcGFjaXR5IHV0aWxpemF0aW9uIGFzIGEgcGVyY2VudGFnZSBmb3IgdGhlIGNhcGFjaXR5IHByb3ZpZGVyLiBUaGUgc3BlY2lmaWVkIHZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIGAwYCBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGAxMDBgIC4gRm9yIGV4YW1wbGUsIGlmIHlvdSB3YW50IHRoZSBjYXBhY2l0eSBwcm92aWRlciB0byBtYWludGFpbiAxMCUgc3BhcmUgY2FwYWNpdHksIHRoZW4gdGhhdCBtZWFucyB0aGUgdXRpbGl6YXRpb24gaXMgOTAlLCBzbyB1c2UgYSBgdGFyZ2V0Q2FwYWNpdHlgIG9mIGA5MGAgLiBUaGUgZGVmYXVsdCB2YWx1ZSBvZiBgMTAwYCBwZXJjZW50IHJlc3VsdHMgaW4gdGhlIEFtYXpvbiBFQzIgaW5zdGFuY2VzIGluIHlvdXIgQXV0byBTY2FsaW5nIGdyb3VwIGJlaW5nIGNvbXBsZXRlbHkgdXNlZC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtY2FwYWNpdHlwcm92aWRlci1tYW5hZ2Vkc2NhbGluZy5odG1sI2Nmbi1lY3MtY2FwYWNpdHlwcm92aWRlci1tYW5hZ2Vkc2NhbGluZy10YXJnZXRjYXBhY2l0eVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgdGFyZ2V0Q2FwYWNpdHk/OiBudW1iZXI7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYE1hbmFnZWRTY2FsaW5nUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYE1hbmFnZWRTY2FsaW5nUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuQ2FwYWNpdHlQcm92aWRlcl9NYW5hZ2VkU2NhbGluZ1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaW5zdGFuY2VXYXJtdXBQZXJpb2QnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMuaW5zdGFuY2VXYXJtdXBQZXJpb2QpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ21heGltdW1TY2FsaW5nU3RlcFNpemUnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMubWF4aW11bVNjYWxpbmdTdGVwU2l6ZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbWluaW11bVNjYWxpbmdTdGVwU2l6ZScsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5taW5pbXVtU2NhbGluZ1N0ZXBTaXplKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzdGF0dXMnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuc3RhdHVzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0YXJnZXRDYXBhY2l0eScsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy50YXJnZXRDYXBhY2l0eSkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJNYW5hZ2VkU2NhbGluZ1Byb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OkNhcGFjaXR5UHJvdmlkZXIuTWFuYWdlZFNjYWxpbmdgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYE1hbmFnZWRTY2FsaW5nUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6Q2FwYWNpdHlQcm92aWRlci5NYW5hZ2VkU2NhbGluZ2AgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5DYXBhY2l0eVByb3ZpZGVyTWFuYWdlZFNjYWxpbmdQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuQ2FwYWNpdHlQcm92aWRlcl9NYW5hZ2VkU2NhbGluZ1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBJbnN0YW5jZVdhcm11cFBlcmlvZDogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5pbnN0YW5jZVdhcm11cFBlcmlvZCksXG4gICAgICAgIE1heGltdW1TY2FsaW5nU3RlcFNpemU6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubWF4aW11bVNjYWxpbmdTdGVwU2l6ZSksXG4gICAgICAgIE1pbmltdW1TY2FsaW5nU3RlcFNpemU6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubWluaW11bVNjYWxpbmdTdGVwU2l6ZSksXG4gICAgICAgIFN0YXR1czogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zdGF0dXMpLFxuICAgICAgICBUYXJnZXRDYXBhY2l0eTogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy50YXJnZXRDYXBhY2l0eSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkNhcGFjaXR5UHJvdmlkZXJNYW5hZ2VkU2NhbGluZ1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuQ2FwYWNpdHlQcm92aWRlci5NYW5hZ2VkU2NhbGluZ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbkNhcGFjaXR5UHJvdmlkZXIuTWFuYWdlZFNjYWxpbmdQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2luc3RhbmNlV2FybXVwUGVyaW9kJywgJ0luc3RhbmNlV2FybXVwUGVyaW9kJywgcHJvcGVydGllcy5JbnN0YW5jZVdhcm11cFBlcmlvZCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5JbnN0YW5jZVdhcm11cFBlcmlvZCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbWF4aW11bVNjYWxpbmdTdGVwU2l6ZScsICdNYXhpbXVtU2NhbGluZ1N0ZXBTaXplJywgcHJvcGVydGllcy5NYXhpbXVtU2NhbGluZ1N0ZXBTaXplICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLk1heGltdW1TY2FsaW5nU3RlcFNpemUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ21pbmltdW1TY2FsaW5nU3RlcFNpemUnLCAnTWluaW11bVNjYWxpbmdTdGVwU2l6ZScsIHByb3BlcnRpZXMuTWluaW11bVNjYWxpbmdTdGVwU2l6ZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5NaW5pbXVtU2NhbGluZ1N0ZXBTaXplKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzdGF0dXMnLCAnU3RhdHVzJywgcHJvcGVydGllcy5TdGF0dXMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuU3RhdHVzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0YXJnZXRDYXBhY2l0eScsICdUYXJnZXRDYXBhY2l0eScsIHByb3BlcnRpZXMuVGFyZ2V0Q2FwYWNpdHkgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuVGFyZ2V0Q2FwYWNpdHkpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIGBDZm5DbHVzdGVyYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtY2x1c3Rlci5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2ZuQ2x1c3RlclByb3BzIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBzaG9ydCBuYW1lIG9mIG9uZSBvciBtb3JlIGNhcGFjaXR5IHByb3ZpZGVycyB0byBhc3NvY2lhdGUgd2l0aCB0aGUgY2x1c3Rlci4gQSBjYXBhY2l0eSBwcm92aWRlciBtdXN0IGJlIGFzc29jaWF0ZWQgd2l0aCBhIGNsdXN0ZXIgYmVmb3JlIGl0IGNhbiBiZSBpbmNsdWRlZCBhcyBwYXJ0IG9mIHRoZSBkZWZhdWx0IGNhcGFjaXR5IHByb3ZpZGVyIHN0cmF0ZWd5IG9mIHRoZSBjbHVzdGVyIG9yIHVzZWQgaW4gYSBjYXBhY2l0eSBwcm92aWRlciBzdHJhdGVneSB3aGVuIGNhbGxpbmcgdGhlIFtDcmVhdGVTZXJ2aWNlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVNlcnZpY2UuaHRtbCkgb3IgW1J1blRhc2tdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUnVuVGFzay5odG1sKSBhY3Rpb25zLlxuICAgICAqXG4gICAgICogSWYgc3BlY2lmeWluZyBhIGNhcGFjaXR5IHByb3ZpZGVyIHRoYXQgdXNlcyBhbiBBdXRvIFNjYWxpbmcgZ3JvdXAsIHRoZSBjYXBhY2l0eSBwcm92aWRlciBtdXN0IGJlIGNyZWF0ZWQgYnV0IG5vdCBhc3NvY2lhdGVkIHdpdGggYW5vdGhlciBjbHVzdGVyLiBOZXcgQXV0byBTY2FsaW5nIGdyb3VwIGNhcGFjaXR5IHByb3ZpZGVycyBjYW4gYmUgY3JlYXRlZCB3aXRoIHRoZSBbQ3JlYXRlQ2FwYWNpdHlQcm92aWRlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVDYXBhY2l0eVByb3ZpZGVyLmh0bWwpIEFQSSBvcGVyYXRpb24uXG4gICAgICpcbiAgICAgKiBUbyB1c2UgYSBBV1MgRmFyZ2F0ZSBjYXBhY2l0eSBwcm92aWRlciwgc3BlY2lmeSBlaXRoZXIgdGhlIGBGQVJHQVRFYCBvciBgRkFSR0FURV9TUE9UYCBjYXBhY2l0eSBwcm92aWRlcnMuIFRoZSBBV1MgRmFyZ2F0ZSBjYXBhY2l0eSBwcm92aWRlcnMgYXJlIGF2YWlsYWJsZSB0byBhbGwgYWNjb3VudHMgYW5kIG9ubHkgbmVlZCB0byBiZSBhc3NvY2lhdGVkIHdpdGggYSBjbHVzdGVyIHRvIGJlIHVzZWQuXG4gICAgICpcbiAgICAgKiBUaGUgW1B1dENhcGFjaXR5UHJvdmlkZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUHV0Q2FwYWNpdHlQcm92aWRlci5odG1sKSBBUEkgb3BlcmF0aW9uIGlzIHVzZWQgdG8gdXBkYXRlIHRoZSBsaXN0IG9mIGF2YWlsYWJsZSBjYXBhY2l0eSBwcm92aWRlcnMgZm9yIGEgY2x1c3RlciBhZnRlciB0aGUgY2x1c3RlciBpcyBjcmVhdGVkLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLWNsdXN0ZXIuaHRtbCNjZm4tZWNzLWNsdXN0ZXItY2FwYWNpdHlwcm92aWRlcnNcbiAgICAgKi9cbiAgICByZWFkb25seSBjYXBhY2l0eVByb3ZpZGVycz86IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogQSB1c2VyLWdlbmVyYXRlZCBzdHJpbmcgdGhhdCB5b3UgdXNlIHRvIGlkZW50aWZ5IHlvdXIgY2x1c3Rlci4gSWYgeW91IGRvbid0IHNwZWNpZnkgYSBuYW1lLCBBV1MgQ2xvdWRGb3JtYXRpb24gZ2VuZXJhdGVzIGEgdW5pcXVlIHBoeXNpY2FsIElEIGZvciB0aGUgbmFtZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1jbHVzdGVyLmh0bWwjY2ZuLWVjcy1jbHVzdGVyLWNsdXN0ZXJuYW1lXG4gICAgICovXG4gICAgcmVhZG9ubHkgY2x1c3Rlck5hbWU/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc2V0dGluZ3MgdG8gdXNlIHdoZW4gY3JlYXRpbmcgYSBjbHVzdGVyLiBUaGlzIHBhcmFtZXRlciBpcyB1c2VkIHRvIHR1cm4gb24gQ2xvdWRXYXRjaCBDb250YWluZXIgSW5zaWdodHMgZm9yIGEgY2x1c3Rlci5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1jbHVzdGVyLmh0bWwjY2ZuLWVjcy1jbHVzdGVyLWNsdXN0ZXJzZXR0aW5nc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IGNsdXN0ZXJTZXR0aW5ncz86IEFycmF5PENmbkNsdXN0ZXIuQ2x1c3RlclNldHRpbmdzUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGV4ZWN1dGUgY29tbWFuZCBjb25maWd1cmF0aW9uIGZvciB0aGUgY2x1c3Rlci5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1jbHVzdGVyLmh0bWwjY2ZuLWVjcy1jbHVzdGVyLWNvbmZpZ3VyYXRpb25cbiAgICAgKi9cbiAgICByZWFkb25seSBjb25maWd1cmF0aW9uPzogQ2ZuQ2x1c3Rlci5DbHVzdGVyQ29uZmlndXJhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGRlZmF1bHQgY2FwYWNpdHkgcHJvdmlkZXIgc3RyYXRlZ3kgZm9yIHRoZSBjbHVzdGVyLiBXaGVuIHNlcnZpY2VzIG9yIHRhc2tzIGFyZSBydW4gaW4gdGhlIGNsdXN0ZXIgd2l0aCBubyBsYXVuY2ggdHlwZSBvciBjYXBhY2l0eSBwcm92aWRlciBzdHJhdGVneSBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IGNhcGFjaXR5IHByb3ZpZGVyIHN0cmF0ZWd5IGlzIHVzZWQuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtY2x1c3Rlci5odG1sI2Nmbi1lY3MtY2x1c3Rlci1kZWZhdWx0Y2FwYWNpdHlwcm92aWRlcnN0cmF0ZWd5XG4gICAgICovXG4gICAgcmVhZG9ubHkgZGVmYXVsdENhcGFjaXR5UHJvdmlkZXJTdHJhdGVneT86IEFycmF5PENmbkNsdXN0ZXIuQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5SXRlbVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIFVzZSB0aGlzIHBhcmFtZXRlciB0byBzZXQgYSBkZWZhdWx0IFNlcnZpY2UgQ29ubmVjdCBuYW1lc3BhY2UuIEFmdGVyIHlvdSBzZXQgYSBkZWZhdWx0IFNlcnZpY2UgQ29ubmVjdCBuYW1lc3BhY2UsIGFueSBuZXcgc2VydmljZXMgd2l0aCBTZXJ2aWNlIENvbm5lY3QgdHVybmVkIG9uIHRoYXQgYXJlIGNyZWF0ZWQgaW4gdGhlIGNsdXN0ZXIgYXJlIGFkZGVkIGFzIGNsaWVudCBzZXJ2aWNlcyBpbiB0aGUgbmFtZXNwYWNlLiBUaGlzIHNldHRpbmcgb25seSBhcHBsaWVzIHRvIG5ldyBzZXJ2aWNlcyB0aGF0IHNldCB0aGUgYGVuYWJsZWRgIHBhcmFtZXRlciB0byBgdHJ1ZWAgaW4gdGhlIGBTZXJ2aWNlQ29ubmVjdENvbmZpZ3VyYXRpb25gIC4gWW91IGNhbiBzZXQgdGhlIG5hbWVzcGFjZSBvZiBlYWNoIHNlcnZpY2UgaW5kaXZpZHVhbGx5IGluIHRoZSBgU2VydmljZUNvbm5lY3RDb25maWd1cmF0aW9uYCB0byBvdmVycmlkZSB0aGlzIGRlZmF1bHQgcGFyYW1ldGVyLlxuICAgICAqXG4gICAgICogVGFza3MgdGhhdCBydW4gaW4gYSBuYW1lc3BhY2UgY2FuIHVzZSBzaG9ydCBuYW1lcyB0byBjb25uZWN0IHRvIHNlcnZpY2VzIGluIHRoZSBuYW1lc3BhY2UuIFRhc2tzIGNhbiBjb25uZWN0IHRvIHNlcnZpY2VzIGFjcm9zcyBhbGwgb2YgdGhlIGNsdXN0ZXJzIGluIHRoZSBuYW1lc3BhY2UuIFRhc2tzIGNvbm5lY3QgdGhyb3VnaCBhIG1hbmFnZWQgcHJveHkgY29udGFpbmVyIHRoYXQgY29sbGVjdHMgbG9ncyBhbmQgbWV0cmljcyBmb3IgaW5jcmVhc2VkIHZpc2liaWxpdHkuIE9ubHkgdGhlIHRhc2tzIHRoYXQgQW1hem9uIEVDUyBzZXJ2aWNlcyBjcmVhdGUgYXJlIHN1cHBvcnRlZCB3aXRoIFNlcnZpY2UgQ29ubmVjdC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbU2VydmljZSBDb25uZWN0XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zZXJ2aWNlLWNvbm5lY3QuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1jbHVzdGVyLmh0bWwjY2ZuLWVjcy1jbHVzdGVyLXNlcnZpY2Vjb25uZWN0ZGVmYXVsdHNcbiAgICAgKi9cbiAgICByZWFkb25seSBzZXJ2aWNlQ29ubmVjdERlZmF1bHRzPzogQ2ZuQ2x1c3Rlci5TZXJ2aWNlQ29ubmVjdERlZmF1bHRzUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWV0YWRhdGEgdGhhdCB5b3UgYXBwbHkgdG8gdGhlIGNsdXN0ZXIgdG8gaGVscCB5b3UgY2F0ZWdvcml6ZSBhbmQgb3JnYW5pemUgdGhlbS4gRWFjaCB0YWcgY29uc2lzdHMgb2YgYSBrZXkgYW5kIGFuIG9wdGlvbmFsIHZhbHVlLiBZb3UgZGVmaW5lIGJvdGguXG4gICAgICpcbiAgICAgKiBUaGUgZm9sbG93aW5nIGJhc2ljIHJlc3RyaWN0aW9ucyBhcHBseSB0byB0YWdzOlxuICAgICAqXG4gICAgICogLSBNYXhpbXVtIG51bWJlciBvZiB0YWdzIHBlciByZXNvdXJjZSAtIDUwXG4gICAgICogLSBGb3IgZWFjaCByZXNvdXJjZSwgZWFjaCB0YWcga2V5IG11c3QgYmUgdW5pcXVlLCBhbmQgZWFjaCB0YWcga2V5IGNhbiBoYXZlIG9ubHkgb25lIHZhbHVlLlxuICAgICAqIC0gTWF4aW11bSBrZXkgbGVuZ3RoIC0gMTI4IFVuaWNvZGUgY2hhcmFjdGVycyBpbiBVVEYtOFxuICAgICAqIC0gTWF4aW11bSB2YWx1ZSBsZW5ndGggLSAyNTYgVW5pY29kZSBjaGFyYWN0ZXJzIGluIFVURi04XG4gICAgICogLSBJZiB5b3VyIHRhZ2dpbmcgc2NoZW1hIGlzIHVzZWQgYWNyb3NzIG11bHRpcGxlIHNlcnZpY2VzIGFuZCByZXNvdXJjZXMsIHJlbWVtYmVyIHRoYXQgb3RoZXIgc2VydmljZXMgbWF5IGhhdmUgcmVzdHJpY3Rpb25zIG9uIGFsbG93ZWQgY2hhcmFjdGVycy4gR2VuZXJhbGx5IGFsbG93ZWQgY2hhcmFjdGVycyBhcmU6IGxldHRlcnMsIG51bWJlcnMsIGFuZCBzcGFjZXMgcmVwcmVzZW50YWJsZSBpbiBVVEYtOCwgYW5kIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogKyAtID0gLiBfIDogLyBALlxuICAgICAqIC0gVGFnIGtleXMgYW5kIHZhbHVlcyBhcmUgY2FzZS1zZW5zaXRpdmUuXG4gICAgICogLSBEbyBub3QgdXNlIGBhd3M6YCAsIGBBV1M6YCAsIG9yIGFueSB1cHBlciBvciBsb3dlcmNhc2UgY29tYmluYXRpb24gb2Ygc3VjaCBhcyBhIHByZWZpeCBmb3IgZWl0aGVyIGtleXMgb3IgdmFsdWVzIGFzIGl0IGlzIHJlc2VydmVkIGZvciBBV1MgdXNlLiBZb3UgY2Fubm90IGVkaXQgb3IgZGVsZXRlIHRhZyBrZXlzIG9yIHZhbHVlcyB3aXRoIHRoaXMgcHJlZml4LiBUYWdzIHdpdGggdGhpcyBwcmVmaXggZG8gbm90IGNvdW50IGFnYWluc3QgeW91ciB0YWdzIHBlciByZXNvdXJjZSBsaW1pdC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1jbHVzdGVyLmh0bWwjY2ZuLWVjcy1jbHVzdGVyLXRhZ3NcbiAgICAgKi9cbiAgICByZWFkb25seSB0YWdzPzogY2RrLkNmblRhZ1tdO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmbkNsdXN0ZXJQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuQ2x1c3RlclByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmbkNsdXN0ZXJQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NhcGFjaXR5UHJvdmlkZXJzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5jYXBhY2l0eVByb3ZpZGVycykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY2x1c3Rlck5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY2x1c3Rlck5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NsdXN0ZXJTZXR0aW5ncycsIGNkay5saXN0VmFsaWRhdG9yKENmbkNsdXN0ZXJfQ2x1c3RlclNldHRpbmdzUHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLmNsdXN0ZXJTZXR0aW5ncykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY29uZmlndXJhdGlvbicsIENmbkNsdXN0ZXJfQ2x1c3RlckNvbmZpZ3VyYXRpb25Qcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5jb25maWd1cmF0aW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdkZWZhdWx0Q2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5JywgY2RrLmxpc3RWYWxpZGF0b3IoQ2ZuQ2x1c3Rlcl9DYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3lJdGVtUHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLmRlZmF1bHRDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3kpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3NlcnZpY2VDb25uZWN0RGVmYXVsdHMnLCBDZm5DbHVzdGVyX1NlcnZpY2VDb25uZWN0RGVmYXVsdHNQcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5zZXJ2aWNlQ29ubmVjdERlZmF1bHRzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0YWdzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlQ2ZuVGFnKSkocHJvcGVydGllcy50YWdzKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNmbkNsdXN0ZXJQcm9wc1wiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpDbHVzdGVyYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5DbHVzdGVyUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6Q2x1c3RlcmAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5DbHVzdGVyUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbkNsdXN0ZXJQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQ2FwYWNpdHlQcm92aWRlcnM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLmNhcGFjaXR5UHJvdmlkZXJzKSxcbiAgICAgICAgQ2x1c3Rlck5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY2x1c3Rlck5hbWUpLFxuICAgICAgICBDbHVzdGVyU2V0dGluZ3M6IGNkay5saXN0TWFwcGVyKGNmbkNsdXN0ZXJDbHVzdGVyU2V0dGluZ3NQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuY2x1c3RlclNldHRpbmdzKSxcbiAgICAgICAgQ29uZmlndXJhdGlvbjogY2ZuQ2x1c3RlckNsdXN0ZXJDb25maWd1cmF0aW9uUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY29uZmlndXJhdGlvbiksXG4gICAgICAgIERlZmF1bHRDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3k6IGNkay5saXN0TWFwcGVyKGNmbkNsdXN0ZXJDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3lJdGVtUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLmRlZmF1bHRDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3kpLFxuICAgICAgICBTZXJ2aWNlQ29ubmVjdERlZmF1bHRzOiBjZm5DbHVzdGVyU2VydmljZUNvbm5lY3REZWZhdWx0c1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnNlcnZpY2VDb25uZWN0RGVmYXVsdHMpLFxuICAgICAgICBUYWdzOiBjZGsubGlzdE1hcHBlcihjZGsuY2ZuVGFnVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy50YWdzKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuQ2x1c3RlclByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuQ2x1c3RlclByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5DbHVzdGVyUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjYXBhY2l0eVByb3ZpZGVycycsICdDYXBhY2l0eVByb3ZpZGVycycsIHByb3BlcnRpZXMuQ2FwYWNpdHlQcm92aWRlcnMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5DYXBhY2l0eVByb3ZpZGVycykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY2x1c3Rlck5hbWUnLCAnQ2x1c3Rlck5hbWUnLCBwcm9wZXJ0aWVzLkNsdXN0ZXJOYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNsdXN0ZXJOYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjbHVzdGVyU2V0dGluZ3MnLCAnQ2x1c3RlclNldHRpbmdzJywgcHJvcGVydGllcy5DbHVzdGVyU2V0dGluZ3MgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoQ2ZuQ2x1c3RlckNsdXN0ZXJTZXR0aW5nc1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLkNsdXN0ZXJTZXR0aW5ncykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY29uZmlndXJhdGlvbicsICdDb25maWd1cmF0aW9uJywgcHJvcGVydGllcy5Db25maWd1cmF0aW9uICE9IG51bGwgPyBDZm5DbHVzdGVyQ2x1c3RlckNvbmZpZ3VyYXRpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLkNvbmZpZ3VyYXRpb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2RlZmF1bHRDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3knLCAnRGVmYXVsdENhcGFjaXR5UHJvdmlkZXJTdHJhdGVneScsIHByb3BlcnRpZXMuRGVmYXVsdENhcGFjaXR5UHJvdmlkZXJTdHJhdGVneSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5DbHVzdGVyQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5SXRlbVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLkRlZmF1bHRDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3kpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3NlcnZpY2VDb25uZWN0RGVmYXVsdHMnLCAnU2VydmljZUNvbm5lY3REZWZhdWx0cycsIHByb3BlcnRpZXMuU2VydmljZUNvbm5lY3REZWZhdWx0cyAhPSBudWxsID8gQ2ZuQ2x1c3RlclNlcnZpY2VDb25uZWN0RGVmYXVsdHNQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLlNlcnZpY2VDb25uZWN0RGVmYXVsdHMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3RhZ3MnLCAnVGFncycsIHByb3BlcnRpZXMuVGFncyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldENmblRhZykocHJvcGVydGllcy5UYWdzKSA6IHVuZGVmaW5lZCBhcyBhbnkpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6RUNTOjpDbHVzdGVyYFxuICpcbiAqIFRoZSBgQVdTOjpFQ1M6OkNsdXN0ZXJgIHJlc291cmNlIGNyZWF0ZXMgYW4gQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgKEFtYXpvbiBFQ1MpIGNsdXN0ZXIuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpFQ1M6OkNsdXN0ZXJcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtY2x1c3Rlci5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5DbHVzdGVyIGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6RUNTOjpDbHVzdGVyXCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5DbHVzdGVyIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5DbHVzdGVyUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmbkNsdXN0ZXIoc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIG9mIHRoZSBBbWF6b24gRUNTIGNsdXN0ZXIsIHN1Y2ggYXMgYGFybjphd3M6ZWNzOnVzLWVhc3QtMjoxMjM0NTY3ODkwMTI6Y2x1c3Rlci9NeUVDU0NsdXN0ZXJgIC5cbiAgICAgKiBAY2xvdWRmb3JtYXRpb25BdHRyaWJ1dGUgQXJuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGF0dHJBcm46IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBzaG9ydCBuYW1lIG9mIG9uZSBvciBtb3JlIGNhcGFjaXR5IHByb3ZpZGVycyB0byBhc3NvY2lhdGUgd2l0aCB0aGUgY2x1c3Rlci4gQSBjYXBhY2l0eSBwcm92aWRlciBtdXN0IGJlIGFzc29jaWF0ZWQgd2l0aCBhIGNsdXN0ZXIgYmVmb3JlIGl0IGNhbiBiZSBpbmNsdWRlZCBhcyBwYXJ0IG9mIHRoZSBkZWZhdWx0IGNhcGFjaXR5IHByb3ZpZGVyIHN0cmF0ZWd5IG9mIHRoZSBjbHVzdGVyIG9yIHVzZWQgaW4gYSBjYXBhY2l0eSBwcm92aWRlciBzdHJhdGVneSB3aGVuIGNhbGxpbmcgdGhlIFtDcmVhdGVTZXJ2aWNlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVNlcnZpY2UuaHRtbCkgb3IgW1J1blRhc2tdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUnVuVGFzay5odG1sKSBhY3Rpb25zLlxuICAgICAqXG4gICAgICogSWYgc3BlY2lmeWluZyBhIGNhcGFjaXR5IHByb3ZpZGVyIHRoYXQgdXNlcyBhbiBBdXRvIFNjYWxpbmcgZ3JvdXAsIHRoZSBjYXBhY2l0eSBwcm92aWRlciBtdXN0IGJlIGNyZWF0ZWQgYnV0IG5vdCBhc3NvY2lhdGVkIHdpdGggYW5vdGhlciBjbHVzdGVyLiBOZXcgQXV0byBTY2FsaW5nIGdyb3VwIGNhcGFjaXR5IHByb3ZpZGVycyBjYW4gYmUgY3JlYXRlZCB3aXRoIHRoZSBbQ3JlYXRlQ2FwYWNpdHlQcm92aWRlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVDYXBhY2l0eVByb3ZpZGVyLmh0bWwpIEFQSSBvcGVyYXRpb24uXG4gICAgICpcbiAgICAgKiBUbyB1c2UgYSBBV1MgRmFyZ2F0ZSBjYXBhY2l0eSBwcm92aWRlciwgc3BlY2lmeSBlaXRoZXIgdGhlIGBGQVJHQVRFYCBvciBgRkFSR0FURV9TUE9UYCBjYXBhY2l0eSBwcm92aWRlcnMuIFRoZSBBV1MgRmFyZ2F0ZSBjYXBhY2l0eSBwcm92aWRlcnMgYXJlIGF2YWlsYWJsZSB0byBhbGwgYWNjb3VudHMgYW5kIG9ubHkgbmVlZCB0byBiZSBhc3NvY2lhdGVkIHdpdGggYSBjbHVzdGVyIHRvIGJlIHVzZWQuXG4gICAgICpcbiAgICAgKiBUaGUgW1B1dENhcGFjaXR5UHJvdmlkZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUHV0Q2FwYWNpdHlQcm92aWRlci5odG1sKSBBUEkgb3BlcmF0aW9uIGlzIHVzZWQgdG8gdXBkYXRlIHRoZSBsaXN0IG9mIGF2YWlsYWJsZSBjYXBhY2l0eSBwcm92aWRlcnMgZm9yIGEgY2x1c3RlciBhZnRlciB0aGUgY2x1c3RlciBpcyBjcmVhdGVkLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLWNsdXN0ZXIuaHRtbCNjZm4tZWNzLWNsdXN0ZXItY2FwYWNpdHlwcm92aWRlcnNcbiAgICAgKi9cbiAgICBwdWJsaWMgY2FwYWNpdHlQcm92aWRlcnM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQSB1c2VyLWdlbmVyYXRlZCBzdHJpbmcgdGhhdCB5b3UgdXNlIHRvIGlkZW50aWZ5IHlvdXIgY2x1c3Rlci4gSWYgeW91IGRvbid0IHNwZWNpZnkgYSBuYW1lLCBBV1MgQ2xvdWRGb3JtYXRpb24gZ2VuZXJhdGVzIGEgdW5pcXVlIHBoeXNpY2FsIElEIGZvciB0aGUgbmFtZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1jbHVzdGVyLmh0bWwjY2ZuLWVjcy1jbHVzdGVyLWNsdXN0ZXJuYW1lXG4gICAgICovXG4gICAgcHVibGljIGNsdXN0ZXJOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc2V0dGluZ3MgdG8gdXNlIHdoZW4gY3JlYXRpbmcgYSBjbHVzdGVyLiBUaGlzIHBhcmFtZXRlciBpcyB1c2VkIHRvIHR1cm4gb24gQ2xvdWRXYXRjaCBDb250YWluZXIgSW5zaWdodHMgZm9yIGEgY2x1c3Rlci5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1jbHVzdGVyLmh0bWwjY2ZuLWVjcy1jbHVzdGVyLWNsdXN0ZXJzZXR0aW5nc1xuICAgICAqL1xuICAgIHB1YmxpYyBjbHVzdGVyU2V0dGluZ3M6IEFycmF5PENmbkNsdXN0ZXIuQ2x1c3RlclNldHRpbmdzUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGV4ZWN1dGUgY29tbWFuZCBjb25maWd1cmF0aW9uIGZvciB0aGUgY2x1c3Rlci5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1jbHVzdGVyLmh0bWwjY2ZuLWVjcy1jbHVzdGVyLWNvbmZpZ3VyYXRpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgY29uZmlndXJhdGlvbjogQ2ZuQ2x1c3Rlci5DbHVzdGVyQ29uZmlndXJhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGRlZmF1bHQgY2FwYWNpdHkgcHJvdmlkZXIgc3RyYXRlZ3kgZm9yIHRoZSBjbHVzdGVyLiBXaGVuIHNlcnZpY2VzIG9yIHRhc2tzIGFyZSBydW4gaW4gdGhlIGNsdXN0ZXIgd2l0aCBubyBsYXVuY2ggdHlwZSBvciBjYXBhY2l0eSBwcm92aWRlciBzdHJhdGVneSBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IGNhcGFjaXR5IHByb3ZpZGVyIHN0cmF0ZWd5IGlzIHVzZWQuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtY2x1c3Rlci5odG1sI2Nmbi1lY3MtY2x1c3Rlci1kZWZhdWx0Y2FwYWNpdHlwcm92aWRlcnN0cmF0ZWd5XG4gICAgICovXG4gICAgcHVibGljIGRlZmF1bHRDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3k6IEFycmF5PENmbkNsdXN0ZXIuQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5SXRlbVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFVzZSB0aGlzIHBhcmFtZXRlciB0byBzZXQgYSBkZWZhdWx0IFNlcnZpY2UgQ29ubmVjdCBuYW1lc3BhY2UuIEFmdGVyIHlvdSBzZXQgYSBkZWZhdWx0IFNlcnZpY2UgQ29ubmVjdCBuYW1lc3BhY2UsIGFueSBuZXcgc2VydmljZXMgd2l0aCBTZXJ2aWNlIENvbm5lY3QgdHVybmVkIG9uIHRoYXQgYXJlIGNyZWF0ZWQgaW4gdGhlIGNsdXN0ZXIgYXJlIGFkZGVkIGFzIGNsaWVudCBzZXJ2aWNlcyBpbiB0aGUgbmFtZXNwYWNlLiBUaGlzIHNldHRpbmcgb25seSBhcHBsaWVzIHRvIG5ldyBzZXJ2aWNlcyB0aGF0IHNldCB0aGUgYGVuYWJsZWRgIHBhcmFtZXRlciB0byBgdHJ1ZWAgaW4gdGhlIGBTZXJ2aWNlQ29ubmVjdENvbmZpZ3VyYXRpb25gIC4gWW91IGNhbiBzZXQgdGhlIG5hbWVzcGFjZSBvZiBlYWNoIHNlcnZpY2UgaW5kaXZpZHVhbGx5IGluIHRoZSBgU2VydmljZUNvbm5lY3RDb25maWd1cmF0aW9uYCB0byBvdmVycmlkZSB0aGlzIGRlZmF1bHQgcGFyYW1ldGVyLlxuICAgICAqXG4gICAgICogVGFza3MgdGhhdCBydW4gaW4gYSBuYW1lc3BhY2UgY2FuIHVzZSBzaG9ydCBuYW1lcyB0byBjb25uZWN0IHRvIHNlcnZpY2VzIGluIHRoZSBuYW1lc3BhY2UuIFRhc2tzIGNhbiBjb25uZWN0IHRvIHNlcnZpY2VzIGFjcm9zcyBhbGwgb2YgdGhlIGNsdXN0ZXJzIGluIHRoZSBuYW1lc3BhY2UuIFRhc2tzIGNvbm5lY3QgdGhyb3VnaCBhIG1hbmFnZWQgcHJveHkgY29udGFpbmVyIHRoYXQgY29sbGVjdHMgbG9ncyBhbmQgbWV0cmljcyBmb3IgaW5jcmVhc2VkIHZpc2liaWxpdHkuIE9ubHkgdGhlIHRhc2tzIHRoYXQgQW1hem9uIEVDUyBzZXJ2aWNlcyBjcmVhdGUgYXJlIHN1cHBvcnRlZCB3aXRoIFNlcnZpY2UgQ29ubmVjdC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbU2VydmljZSBDb25uZWN0XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zZXJ2aWNlLWNvbm5lY3QuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1jbHVzdGVyLmh0bWwjY2ZuLWVjcy1jbHVzdGVyLXNlcnZpY2Vjb25uZWN0ZGVmYXVsdHNcbiAgICAgKi9cbiAgICBwdWJsaWMgc2VydmljZUNvbm5lY3REZWZhdWx0czogQ2ZuQ2x1c3Rlci5TZXJ2aWNlQ29ubmVjdERlZmF1bHRzUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWV0YWRhdGEgdGhhdCB5b3UgYXBwbHkgdG8gdGhlIGNsdXN0ZXIgdG8gaGVscCB5b3UgY2F0ZWdvcml6ZSBhbmQgb3JnYW5pemUgdGhlbS4gRWFjaCB0YWcgY29uc2lzdHMgb2YgYSBrZXkgYW5kIGFuIG9wdGlvbmFsIHZhbHVlLiBZb3UgZGVmaW5lIGJvdGguXG4gICAgICpcbiAgICAgKiBUaGUgZm9sbG93aW5nIGJhc2ljIHJlc3RyaWN0aW9ucyBhcHBseSB0byB0YWdzOlxuICAgICAqXG4gICAgICogLSBNYXhpbXVtIG51bWJlciBvZiB0YWdzIHBlciByZXNvdXJjZSAtIDUwXG4gICAgICogLSBGb3IgZWFjaCByZXNvdXJjZSwgZWFjaCB0YWcga2V5IG11c3QgYmUgdW5pcXVlLCBhbmQgZWFjaCB0YWcga2V5IGNhbiBoYXZlIG9ubHkgb25lIHZhbHVlLlxuICAgICAqIC0gTWF4aW11bSBrZXkgbGVuZ3RoIC0gMTI4IFVuaWNvZGUgY2hhcmFjdGVycyBpbiBVVEYtOFxuICAgICAqIC0gTWF4aW11bSB2YWx1ZSBsZW5ndGggLSAyNTYgVW5pY29kZSBjaGFyYWN0ZXJzIGluIFVURi04XG4gICAgICogLSBJZiB5b3VyIHRhZ2dpbmcgc2NoZW1hIGlzIHVzZWQgYWNyb3NzIG11bHRpcGxlIHNlcnZpY2VzIGFuZCByZXNvdXJjZXMsIHJlbWVtYmVyIHRoYXQgb3RoZXIgc2VydmljZXMgbWF5IGhhdmUgcmVzdHJpY3Rpb25zIG9uIGFsbG93ZWQgY2hhcmFjdGVycy4gR2VuZXJhbGx5IGFsbG93ZWQgY2hhcmFjdGVycyBhcmU6IGxldHRlcnMsIG51bWJlcnMsIGFuZCBzcGFjZXMgcmVwcmVzZW50YWJsZSBpbiBVVEYtOCwgYW5kIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogKyAtID0gLiBfIDogLyBALlxuICAgICAqIC0gVGFnIGtleXMgYW5kIHZhbHVlcyBhcmUgY2FzZS1zZW5zaXRpdmUuXG4gICAgICogLSBEbyBub3QgdXNlIGBhd3M6YCAsIGBBV1M6YCAsIG9yIGFueSB1cHBlciBvciBsb3dlcmNhc2UgY29tYmluYXRpb24gb2Ygc3VjaCBhcyBhIHByZWZpeCBmb3IgZWl0aGVyIGtleXMgb3IgdmFsdWVzIGFzIGl0IGlzIHJlc2VydmVkIGZvciBBV1MgdXNlLiBZb3UgY2Fubm90IGVkaXQgb3IgZGVsZXRlIHRhZyBrZXlzIG9yIHZhbHVlcyB3aXRoIHRoaXMgcHJlZml4LiBUYWdzIHdpdGggdGhpcyBwcmVmaXggZG8gbm90IGNvdW50IGFnYWluc3QgeW91ciB0YWdzIHBlciByZXNvdXJjZSBsaW1pdC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1jbHVzdGVyLmh0bWwjY2ZuLWVjcy1jbHVzdGVyLXRhZ3NcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgdGFnczogY2RrLlRhZ01hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6RUNTOjpDbHVzdGVyYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5DbHVzdGVyUHJvcHMgPSB7fSkge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuQ2x1c3Rlci5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgdGhpcy5hdHRyQXJuID0gY2RrLlRva2VuLmFzU3RyaW5nKHRoaXMuZ2V0QXR0KCdBcm4nKSk7XG5cbiAgICAgICAgdGhpcy5jYXBhY2l0eVByb3ZpZGVycyA9IHByb3BzLmNhcGFjaXR5UHJvdmlkZXJzO1xuICAgICAgICB0aGlzLmNsdXN0ZXJOYW1lID0gcHJvcHMuY2x1c3Rlck5hbWU7XG4gICAgICAgIHRoaXMuY2x1c3RlclNldHRpbmdzID0gcHJvcHMuY2x1c3RlclNldHRpbmdzO1xuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24gPSBwcm9wcy5jb25maWd1cmF0aW9uO1xuICAgICAgICB0aGlzLmRlZmF1bHRDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3kgPSBwcm9wcy5kZWZhdWx0Q2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5O1xuICAgICAgICB0aGlzLnNlcnZpY2VDb25uZWN0RGVmYXVsdHMgPSBwcm9wcy5zZXJ2aWNlQ29ubmVjdERlZmF1bHRzO1xuICAgICAgICB0aGlzLnRhZ3MgPSBuZXcgY2RrLlRhZ01hbmFnZXIoY2RrLlRhZ1R5cGUuU1RBTkRBUkQsIFwiQVdTOjpFQ1M6OkNsdXN0ZXJcIiwgcHJvcHMudGFncywgeyB0YWdQcm9wZXJ0eU5hbWU6ICd0YWdzJyB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmbkNsdXN0ZXIuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNhcGFjaXR5UHJvdmlkZXJzOiB0aGlzLmNhcGFjaXR5UHJvdmlkZXJzLFxuICAgICAgICAgICAgY2x1c3Rlck5hbWU6IHRoaXMuY2x1c3Rlck5hbWUsXG4gICAgICAgICAgICBjbHVzdGVyU2V0dGluZ3M6IHRoaXMuY2x1c3RlclNldHRpbmdzLFxuICAgICAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLFxuICAgICAgICAgICAgZGVmYXVsdENhcGFjaXR5UHJvdmlkZXJTdHJhdGVneTogdGhpcy5kZWZhdWx0Q2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5LFxuICAgICAgICAgICAgc2VydmljZUNvbm5lY3REZWZhdWx0czogdGhpcy5zZXJ2aWNlQ29ubmVjdERlZmF1bHRzLFxuICAgICAgICAgICAgdGFnczogdGhpcy50YWdzLnJlbmRlclRhZ3MoKSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5DbHVzdGVyUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuQ2x1c3RlciB7XG4gICAgLyoqXG4gICAgICogVGhlIGBDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3lJdGVtYCBwcm9wZXJ0eSBzcGVjaWZpZXMgdGhlIGRldGFpbHMgb2YgdGhlIGRlZmF1bHQgY2FwYWNpdHkgcHJvdmlkZXIgc3RyYXRlZ3kgZm9yIHRoZSBjbHVzdGVyLiBXaGVuIHNlcnZpY2VzIG9yIHRhc2tzIGFyZSBydW4gaW4gdGhlIGNsdXN0ZXIgd2l0aCBubyBsYXVuY2ggdHlwZSBvciBjYXBhY2l0eSBwcm92aWRlciBzdHJhdGVneSBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IGNhcGFjaXR5IHByb3ZpZGVyIHN0cmF0ZWd5IGlzIHVzZWQuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtY2x1c3Rlci1jYXBhY2l0eXByb3ZpZGVyc3RyYXRlZ3lpdGVtLmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIENhcGFjaXR5UHJvdmlkZXJTdHJhdGVneUl0ZW1Qcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgKmJhc2UqIHZhbHVlIGRlc2lnbmF0ZXMgaG93IG1hbnkgdGFza3MsIGF0IGEgbWluaW11bSwgdG8gcnVuIG9uIHRoZSBzcGVjaWZpZWQgY2FwYWNpdHkgcHJvdmlkZXIuIE9ubHkgb25lIGNhcGFjaXR5IHByb3ZpZGVyIGluIGEgY2FwYWNpdHkgcHJvdmlkZXIgc3RyYXRlZ3kgY2FuIGhhdmUgYSAqYmFzZSogZGVmaW5lZC4gSWYgbm8gdmFsdWUgaXMgc3BlY2lmaWVkLCB0aGUgZGVmYXVsdCB2YWx1ZSBvZiBgMGAgaXMgdXNlZC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtY2x1c3Rlci1jYXBhY2l0eXByb3ZpZGVyc3RyYXRlZ3lpdGVtLmh0bWwjY2ZuLWVjcy1jbHVzdGVyLWNhcGFjaXR5cHJvdmlkZXJzdHJhdGVneWl0ZW0tYmFzZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgYmFzZT86IG51bWJlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzaG9ydCBuYW1lIG9mIHRoZSBjYXBhY2l0eSBwcm92aWRlci5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtY2x1c3Rlci1jYXBhY2l0eXByb3ZpZGVyc3RyYXRlZ3lpdGVtLmh0bWwjY2ZuLWVjcy1jbHVzdGVyLWNhcGFjaXR5cHJvdmlkZXJzdHJhdGVneWl0ZW0tY2FwYWNpdHlwcm92aWRlclxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY2FwYWNpdHlQcm92aWRlcj86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSAqd2VpZ2h0KiB2YWx1ZSBkZXNpZ25hdGVzIHRoZSByZWxhdGl2ZSBwZXJjZW50YWdlIG9mIHRoZSB0b3RhbCBudW1iZXIgb2YgdGFza3MgbGF1bmNoZWQgdGhhdCBzaG91bGQgdXNlIHRoZSBzcGVjaWZpZWQgY2FwYWNpdHkgcHJvdmlkZXIuIFRoZSBgd2VpZ2h0YCB2YWx1ZSBpcyB0YWtlbiBpbnRvIGNvbnNpZGVyYXRpb24gYWZ0ZXIgdGhlIGBiYXNlYCB2YWx1ZSwgaWYgZGVmaW5lZCwgaXMgc2F0aXNmaWVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiBubyBgd2VpZ2h0YCB2YWx1ZSBpcyBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IHZhbHVlIG9mIGAwYCBpcyB1c2VkLiBXaGVuIG11bHRpcGxlIGNhcGFjaXR5IHByb3ZpZGVycyBhcmUgc3BlY2lmaWVkIHdpdGhpbiBhIGNhcGFjaXR5IHByb3ZpZGVyIHN0cmF0ZWd5LCBhdCBsZWFzdCBvbmUgb2YgdGhlIGNhcGFjaXR5IHByb3ZpZGVycyBtdXN0IGhhdmUgYSB3ZWlnaHQgdmFsdWUgZ3JlYXRlciB0aGFuIHplcm8gYW5kIGFueSBjYXBhY2l0eSBwcm92aWRlcnMgd2l0aCBhIHdlaWdodCBvZiBgMGAgY2FuJ3QgYmUgdXNlZCB0byBwbGFjZSB0YXNrcy4gSWYgeW91IHNwZWNpZnkgbXVsdGlwbGUgY2FwYWNpdHkgcHJvdmlkZXJzIGluIGEgc3RyYXRlZ3kgdGhhdCBhbGwgaGF2ZSBhIHdlaWdodCBvZiBgMGAgLCBhbnkgYFJ1blRhc2tgIG9yIGBDcmVhdGVTZXJ2aWNlYCBhY3Rpb25zIHVzaW5nIHRoZSBjYXBhY2l0eSBwcm92aWRlciBzdHJhdGVneSB3aWxsIGZhaWwuXG4gICAgICAgICAqXG4gICAgICAgICAqIEFuIGV4YW1wbGUgc2NlbmFyaW8gZm9yIHVzaW5nIHdlaWdodHMgaXMgZGVmaW5pbmcgYSBzdHJhdGVneSB0aGF0IGNvbnRhaW5zIHR3byBjYXBhY2l0eSBwcm92aWRlcnMgYW5kIGJvdGggaGF2ZSBhIHdlaWdodCBvZiBgMWAgLCB0aGVuIHdoZW4gdGhlIGBiYXNlYCBpcyBzYXRpc2ZpZWQsIHRoZSB0YXNrcyB3aWxsIGJlIHNwbGl0IGV2ZW5seSBhY3Jvc3MgdGhlIHR3byBjYXBhY2l0eSBwcm92aWRlcnMuIFVzaW5nIHRoYXQgc2FtZSBsb2dpYywgaWYgeW91IHNwZWNpZnkgYSB3ZWlnaHQgb2YgYDFgIGZvciAqY2FwYWNpdHlQcm92aWRlckEqIGFuZCBhIHdlaWdodCBvZiBgNGAgZm9yICpjYXBhY2l0eVByb3ZpZGVyQiogLCB0aGVuIGZvciBldmVyeSBvbmUgdGFzayB0aGF0J3MgcnVuIHVzaW5nICpjYXBhY2l0eVByb3ZpZGVyQSogLCBmb3VyIHRhc2tzIHdvdWxkIHVzZSAqY2FwYWNpdHlQcm92aWRlckIqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtY2x1c3Rlci1jYXBhY2l0eXByb3ZpZGVyc3RyYXRlZ3lpdGVtLmh0bWwjY2ZuLWVjcy1jbHVzdGVyLWNhcGFjaXR5cHJvdmlkZXJzdHJhdGVneWl0ZW0td2VpZ2h0XG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB3ZWlnaHQ/OiBudW1iZXI7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENhcGFjaXR5UHJvdmlkZXJTdHJhdGVneUl0ZW1Qcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5SXRlbVByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmbkNsdXN0ZXJfQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5SXRlbVByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignYmFzZScsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5iYXNlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjYXBhY2l0eVByb3ZpZGVyJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmNhcGFjaXR5UHJvdmlkZXIpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3dlaWdodCcsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy53ZWlnaHQpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5SXRlbVByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OkNsdXN0ZXIuQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5SXRlbWAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5SXRlbVByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OkNsdXN0ZXIuQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5SXRlbWAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5DbHVzdGVyQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5SXRlbVByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5DbHVzdGVyX0NhcGFjaXR5UHJvdmlkZXJTdHJhdGVneUl0ZW1Qcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQmFzZTogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5iYXNlKSxcbiAgICAgICAgQ2FwYWNpdHlQcm92aWRlcjogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5jYXBhY2l0eVByb3ZpZGVyKSxcbiAgICAgICAgV2VpZ2h0OiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLndlaWdodCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkNsdXN0ZXJDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3lJdGVtUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5DbHVzdGVyLkNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneUl0ZW1Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5DbHVzdGVyLkNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneUl0ZW1Qcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2Jhc2UnLCAnQmFzZScsIHByb3BlcnRpZXMuQmFzZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5CYXNlKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjYXBhY2l0eVByb3ZpZGVyJywgJ0NhcGFjaXR5UHJvdmlkZXInLCBwcm9wZXJ0aWVzLkNhcGFjaXR5UHJvdmlkZXIgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQ2FwYWNpdHlQcm92aWRlcikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnd2VpZ2h0JywgJ1dlaWdodCcsIHByb3BlcnRpZXMuV2VpZ2h0ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLldlaWdodCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmbkNsdXN0ZXIge1xuICAgIC8qKlxuICAgICAqIFRoZSBleGVjdXRlIGNvbW1hbmQgY29uZmlndXJhdGlvbiBmb3IgdGhlIGNsdXN0ZXIuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtY2x1c3Rlci1jbHVzdGVyY29uZmlndXJhdGlvbi5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBDbHVzdGVyQ29uZmlndXJhdGlvblByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBkZXRhaWxzIG9mIHRoZSBleGVjdXRlIGNvbW1hbmQgY29uZmlndXJhdGlvbi5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtY2x1c3Rlci1jbHVzdGVyY29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3MtY2x1c3Rlci1jbHVzdGVyY29uZmlndXJhdGlvbi1leGVjdXRlY29tbWFuZGNvbmZpZ3VyYXRpb25cbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGV4ZWN1dGVDb21tYW5kQ29uZmlndXJhdGlvbj86IENmbkNsdXN0ZXIuRXhlY3V0ZUNvbW1hbmRDb25maWd1cmF0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENsdXN0ZXJDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENsdXN0ZXJDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuQ2x1c3Rlcl9DbHVzdGVyQ29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZXhlY3V0ZUNvbW1hbmRDb25maWd1cmF0aW9uJywgQ2ZuQ2x1c3Rlcl9FeGVjdXRlQ29tbWFuZENvbmZpZ3VyYXRpb25Qcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5leGVjdXRlQ29tbWFuZENvbmZpZ3VyYXRpb24pKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2x1c3RlckNvbmZpZ3VyYXRpb25Qcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpDbHVzdGVyLkNsdXN0ZXJDb25maWd1cmF0aW9uYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDbHVzdGVyQ29uZmlndXJhdGlvblByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OkNsdXN0ZXIuQ2x1c3RlckNvbmZpZ3VyYXRpb25gIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuQ2x1c3RlckNsdXN0ZXJDb25maWd1cmF0aW9uUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbkNsdXN0ZXJfQ2x1c3RlckNvbmZpZ3VyYXRpb25Qcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgRXhlY3V0ZUNvbW1hbmRDb25maWd1cmF0aW9uOiBjZm5DbHVzdGVyRXhlY3V0ZUNvbW1hbmRDb25maWd1cmF0aW9uUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZXhlY3V0ZUNvbW1hbmRDb25maWd1cmF0aW9uKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuQ2x1c3RlckNsdXN0ZXJDb25maWd1cmF0aW9uUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5DbHVzdGVyLkNsdXN0ZXJDb25maWd1cmF0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuQ2x1c3Rlci5DbHVzdGVyQ29uZmlndXJhdGlvblByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZXhlY3V0ZUNvbW1hbmRDb25maWd1cmF0aW9uJywgJ0V4ZWN1dGVDb21tYW5kQ29uZmlndXJhdGlvbicsIHByb3BlcnRpZXMuRXhlY3V0ZUNvbW1hbmRDb25maWd1cmF0aW9uICE9IG51bGwgPyBDZm5DbHVzdGVyRXhlY3V0ZUNvbW1hbmRDb25maWd1cmF0aW9uUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5FeGVjdXRlQ29tbWFuZENvbmZpZ3VyYXRpb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5DbHVzdGVyIHtcbiAgICAvKipcbiAgICAgKiBUaGUgc2V0dGluZ3MgdG8gdXNlIHdoZW4gY3JlYXRpbmcgYSBjbHVzdGVyLiBUaGlzIHBhcmFtZXRlciBpcyB1c2VkIHRvIHR1cm4gb24gQ2xvdWRXYXRjaCBDb250YWluZXIgSW5zaWdodHMgZm9yIGEgY2x1c3Rlci5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1jbHVzdGVyLWNsdXN0ZXJzZXR0aW5ncy5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBDbHVzdGVyU2V0dGluZ3NQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbmFtZSBvZiB0aGUgY2x1c3RlciBzZXR0aW5nLiBUaGUgdmFsdWUgaXMgYGNvbnRhaW5lckluc2lnaHRzYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLWNsdXN0ZXItY2x1c3RlcnNldHRpbmdzLmh0bWwjY2ZuLWVjcy1jbHVzdGVyLWNsdXN0ZXJzZXR0aW5ncy1uYW1lXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBuYW1lPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHZhbHVlIHRvIHNldCBmb3IgdGhlIGNsdXN0ZXIgc2V0dGluZy4gVGhlIHN1cHBvcnRlZCB2YWx1ZXMgYXJlIGBlbmFibGVkYCBhbmQgYGRpc2FibGVkYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSBzZXQgYG5hbWVgIHRvIGBjb250YWluZXJJbnNpZ2h0c2AgYW5kIGB2YWx1ZWAgdG8gYGVuYWJsZWRgICwgQ2xvdWRXYXRjaCBDb250YWluZXIgSW5zaWdodHMgd2lsbCBiZSBvbiBmb3IgdGhlIGNsdXN0ZXIsIG90aGVyd2lzZSBpdCB3aWxsIGJlIG9mZiB1bmxlc3MgdGhlIGBjb250YWluZXJJbnNpZ2h0c2AgYWNjb3VudCBzZXR0aW5nIGlzIHR1cm5lZCBvbi4gSWYgYSBjbHVzdGVyIHZhbHVlIGlzIHNwZWNpZmllZCwgaXQgd2lsbCBvdmVycmlkZSB0aGUgYGNvbnRhaW5lckluc2lnaHRzYCB2YWx1ZSBzZXQgd2l0aCBbUHV0QWNjb3VudFNldHRpbmddKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUHV0QWNjb3VudFNldHRpbmcuaHRtbCkgb3IgW1B1dEFjY291bnRTZXR0aW5nRGVmYXVsdF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9QdXRBY2NvdW50U2V0dGluZ0RlZmF1bHQuaHRtbCkgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1jbHVzdGVyLWNsdXN0ZXJzZXR0aW5ncy5odG1sI2Nmbi1lY3MtY2x1c3Rlci1jbHVzdGVyc2V0dGluZ3MtdmFsdWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHZhbHVlPzogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDbHVzdGVyU2V0dGluZ3NQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2x1c3RlclNldHRpbmdzUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuQ2x1c3Rlcl9DbHVzdGVyU2V0dGluZ3NQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ25hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMubmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndmFsdWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMudmFsdWUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2x1c3RlclNldHRpbmdzUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6Q2x1c3Rlci5DbHVzdGVyU2V0dGluZ3NgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENsdXN0ZXJTZXR0aW5nc1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OkNsdXN0ZXIuQ2x1c3RlclNldHRpbmdzYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmbkNsdXN0ZXJDbHVzdGVyU2V0dGluZ3NQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuQ2x1c3Rlcl9DbHVzdGVyU2V0dGluZ3NQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5uYW1lKSxcbiAgICAgICAgVmFsdWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMudmFsdWUpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5DbHVzdGVyQ2x1c3RlclNldHRpbmdzUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5DbHVzdGVyLkNsdXN0ZXJTZXR0aW5nc1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbkNsdXN0ZXIuQ2x1c3RlclNldHRpbmdzUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCduYW1lJywgJ05hbWUnLCBwcm9wZXJ0aWVzLk5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuTmFtZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndmFsdWUnLCAnVmFsdWUnLCBwcm9wZXJ0aWVzLlZhbHVlICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlZhbHVlKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuQ2x1c3RlciB7XG4gICAgLyoqXG4gICAgICogVGhlIGRldGFpbHMgb2YgdGhlIGV4ZWN1dGUgY29tbWFuZCBjb25maWd1cmF0aW9uLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLWNsdXN0ZXItZXhlY3V0ZWNvbW1hbmRjb25maWd1cmF0aW9uLmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIEV4ZWN1dGVDb21tYW5kQ29uZmlndXJhdGlvblByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNwZWNpZnkgYW4gQVdTIEtleSBNYW5hZ2VtZW50IFNlcnZpY2Uga2V5IElEIHRvIGVuY3J5cHQgdGhlIGRhdGEgYmV0d2VlbiB0aGUgbG9jYWwgY2xpZW50IGFuZCB0aGUgY29udGFpbmVyLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1jbHVzdGVyLWV4ZWN1dGVjb21tYW5kY29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3MtY2x1c3Rlci1leGVjdXRlY29tbWFuZGNvbmZpZ3VyYXRpb24ta21za2V5aWRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGttc0tleUlkPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGxvZyBjb25maWd1cmF0aW9uIGZvciB0aGUgcmVzdWx0cyBvZiB0aGUgZXhlY3V0ZSBjb21tYW5kIGFjdGlvbnMuIFRoZSBsb2dzIGNhbiBiZSBzZW50IHRvIENsb3VkV2F0Y2ggTG9ncyBvciBhbiBBbWF6b24gUzMgYnVja2V0LiBXaGVuIGBsb2dnaW5nPU9WRVJSSURFYCBpcyBzcGVjaWZpZWQsIGEgYGxvZ0NvbmZpZ3VyYXRpb25gIG11c3QgYmUgcHJvdmlkZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLWNsdXN0ZXItZXhlY3V0ZWNvbW1hbmRjb25maWd1cmF0aW9uLmh0bWwjY2ZuLWVjcy1jbHVzdGVyLWV4ZWN1dGVjb21tYW5kY29uZmlndXJhdGlvbi1sb2djb25maWd1cmF0aW9uXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBsb2dDb25maWd1cmF0aW9uPzogQ2ZuQ2x1c3Rlci5FeGVjdXRlQ29tbWFuZExvZ0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBsb2cgc2V0dGluZyB0byB1c2UgZm9yIHJlZGlyZWN0aW5nIGxvZ3MgZm9yIHlvdXIgZXhlY3V0ZSBjb21tYW5kIHJlc3VsdHMuIFRoZSBmb2xsb3dpbmcgbG9nIHNldHRpbmdzIGFyZSBhdmFpbGFibGUuXG4gICAgICAgICAqXG4gICAgICAgICAqIC0gYE5PTkVgIDogVGhlIGV4ZWN1dGUgY29tbWFuZCBzZXNzaW9uIGlzIG5vdCBsb2dnZWQuXG4gICAgICAgICAqIC0gYERFRkFVTFRgIDogVGhlIGBhd3Nsb2dzYCBjb25maWd1cmF0aW9uIGluIHRoZSB0YXNrIGRlZmluaXRpb24gaXMgdXNlZC4gSWYgbm8gbG9nZ2luZyBwYXJhbWV0ZXIgaXMgc3BlY2lmaWVkLCBpdCBkZWZhdWx0cyB0byB0aGlzIHZhbHVlLiBJZiBubyBgYXdzbG9nc2AgbG9nIGRyaXZlciBpcyBjb25maWd1cmVkIGluIHRoZSB0YXNrIGRlZmluaXRpb24sIHRoZSBvdXRwdXQgd29uJ3QgYmUgbG9nZ2VkLlxuICAgICAgICAgKiAtIGBPVkVSUklERWAgOiBTcGVjaWZ5IHRoZSBsb2dnaW5nIGRldGFpbHMgYXMgYSBwYXJ0IG9mIGBsb2dDb25maWd1cmF0aW9uYCAuIElmIHRoZSBgT1ZFUlJJREVgIGxvZ2dpbmcgb3B0aW9uIGlzIHNwZWNpZmllZCwgdGhlIGBsb2dDb25maWd1cmF0aW9uYCBpcyByZXF1aXJlZC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtY2x1c3Rlci1leGVjdXRlY29tbWFuZGNvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLWNsdXN0ZXItZXhlY3V0ZWNvbW1hbmRjb25maWd1cmF0aW9uLWxvZ2dpbmdcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGxvZ2dpbmc/OiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYEV4ZWN1dGVDb21tYW5kQ29uZmlndXJhdGlvblByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBFeGVjdXRlQ29tbWFuZENvbmZpZ3VyYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5DbHVzdGVyX0V4ZWN1dGVDb21tYW5kQ29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigna21zS2V5SWQnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMua21zS2V5SWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2xvZ0NvbmZpZ3VyYXRpb24nLCBDZm5DbHVzdGVyX0V4ZWN1dGVDb21tYW5kTG9nQ29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKShwcm9wZXJ0aWVzLmxvZ0NvbmZpZ3VyYXRpb24pKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2xvZ2dpbmcnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMubG9nZ2luZykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJFeGVjdXRlQ29tbWFuZENvbmZpZ3VyYXRpb25Qcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpDbHVzdGVyLkV4ZWN1dGVDb21tYW5kQ29uZmlndXJhdGlvbmAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgRXhlY3V0ZUNvbW1hbmRDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6Q2x1c3Rlci5FeGVjdXRlQ29tbWFuZENvbmZpZ3VyYXRpb25gIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuQ2x1c3RlckV4ZWN1dGVDb21tYW5kQ29uZmlndXJhdGlvblByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5DbHVzdGVyX0V4ZWN1dGVDb21tYW5kQ29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBLbXNLZXlJZDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5rbXNLZXlJZCksXG4gICAgICAgIExvZ0NvbmZpZ3VyYXRpb246IGNmbkNsdXN0ZXJFeGVjdXRlQ29tbWFuZExvZ0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5sb2dDb25maWd1cmF0aW9uKSxcbiAgICAgICAgTG9nZ2luZzogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5sb2dnaW5nKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuQ2x1c3RlckV4ZWN1dGVDb21tYW5kQ29uZmlndXJhdGlvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuQ2x1c3Rlci5FeGVjdXRlQ29tbWFuZENvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5DbHVzdGVyLkV4ZWN1dGVDb21tYW5kQ29uZmlndXJhdGlvblByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgna21zS2V5SWQnLCAnS21zS2V5SWQnLCBwcm9wZXJ0aWVzLkttc0tleUlkICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkttc0tleUlkKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdsb2dDb25maWd1cmF0aW9uJywgJ0xvZ0NvbmZpZ3VyYXRpb24nLCBwcm9wZXJ0aWVzLkxvZ0NvbmZpZ3VyYXRpb24gIT0gbnVsbCA/IENmbkNsdXN0ZXJFeGVjdXRlQ29tbWFuZExvZ0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLkxvZ0NvbmZpZ3VyYXRpb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2xvZ2dpbmcnLCAnTG9nZ2luZycsIHByb3BlcnRpZXMuTG9nZ2luZyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Mb2dnaW5nKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuQ2x1c3RlciB7XG4gICAgLyoqXG4gICAgICogVGhlIGxvZyBjb25maWd1cmF0aW9uIGZvciB0aGUgcmVzdWx0cyBvZiB0aGUgZXhlY3V0ZSBjb21tYW5kIGFjdGlvbnMuIFRoZSBsb2dzIGNhbiBiZSBzZW50IHRvIENsb3VkV2F0Y2ggTG9ncyBvciBhbiBBbWF6b24gUzMgYnVja2V0LlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLWNsdXN0ZXItZXhlY3V0ZWNvbW1hbmRsb2djb25maWd1cmF0aW9uLmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIEV4ZWN1dGVDb21tYW5kTG9nQ29uZmlndXJhdGlvblByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERldGVybWluZXMgd2hldGhlciB0byB1c2UgZW5jcnlwdGlvbiBvbiB0aGUgQ2xvdWRXYXRjaCBsb2dzLiBJZiBub3Qgc3BlY2lmaWVkLCBlbmNyeXB0aW9uIHdpbGwgYmUgb2ZmLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1jbHVzdGVyLWV4ZWN1dGVjb21tYW5kbG9nY29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3MtY2x1c3Rlci1leGVjdXRlY29tbWFuZGxvZ2NvbmZpZ3VyYXRpb24tY2xvdWR3YXRjaGVuY3J5cHRpb25lbmFibGVkXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBjbG91ZFdhdGNoRW5jcnlwdGlvbkVuYWJsZWQ/OiBib29sZWFuIHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5hbWUgb2YgdGhlIENsb3VkV2F0Y2ggbG9nIGdyb3VwIHRvIHNlbmQgbG9ncyB0by5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBUaGUgQ2xvdWRXYXRjaCBsb2cgZ3JvdXAgbXVzdCBhbHJlYWR5IGJlIGNyZWF0ZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLWNsdXN0ZXItZXhlY3V0ZWNvbW1hbmRsb2djb25maWd1cmF0aW9uLmh0bWwjY2ZuLWVjcy1jbHVzdGVyLWV4ZWN1dGVjb21tYW5kbG9nY29uZmlndXJhdGlvbi1jbG91ZHdhdGNobG9nZ3JvdXBuYW1lXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBjbG91ZFdhdGNoTG9nR3JvdXBOYW1lPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5hbWUgb2YgdGhlIFMzIGJ1Y2tldCB0byBzZW5kIGxvZ3MgdG8uXG4gICAgICAgICAqXG4gICAgICAgICAqID4gVGhlIFMzIGJ1Y2tldCBtdXN0IGFscmVhZHkgYmUgY3JlYXRlZC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtY2x1c3Rlci1leGVjdXRlY29tbWFuZGxvZ2NvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLWNsdXN0ZXItZXhlY3V0ZWNvbW1hbmRsb2djb25maWd1cmF0aW9uLXMzYnVja2V0bmFtZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgczNCdWNrZXROYW1lPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRvIHVzZSBlbmNyeXB0aW9uIG9uIHRoZSBTMyBsb2dzLiBJZiBub3Qgc3BlY2lmaWVkLCBlbmNyeXB0aW9uIGlzIG5vdCB1c2VkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1jbHVzdGVyLWV4ZWN1dGVjb21tYW5kbG9nY29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3MtY2x1c3Rlci1leGVjdXRlY29tbWFuZGxvZ2NvbmZpZ3VyYXRpb24tczNlbmNyeXB0aW9uZW5hYmxlZFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgczNFbmNyeXB0aW9uRW5hYmxlZD86IGJvb2xlYW4gfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbiBvcHRpb25hbCBmb2xkZXIgaW4gdGhlIFMzIGJ1Y2tldCB0byBwbGFjZSBsb2dzIGluLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1jbHVzdGVyLWV4ZWN1dGVjb21tYW5kbG9nY29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3MtY2x1c3Rlci1leGVjdXRlY29tbWFuZGxvZ2NvbmZpZ3VyYXRpb24tczNrZXlwcmVmaXhcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHMzS2V5UHJlZml4Pzogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBFeGVjdXRlQ29tbWFuZExvZ0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgRXhlY3V0ZUNvbW1hbmRMb2dDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuQ2x1c3Rlcl9FeGVjdXRlQ29tbWFuZExvZ0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2Nsb3VkV2F0Y2hFbmNyeXB0aW9uRW5hYmxlZCcsIGNkay52YWxpZGF0ZUJvb2xlYW4pKHByb3BlcnRpZXMuY2xvdWRXYXRjaEVuY3J5cHRpb25FbmFibGVkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjbG91ZFdhdGNoTG9nR3JvdXBOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmNsb3VkV2F0Y2hMb2dHcm91cE5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3MzQnVja2V0TmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5zM0J1Y2tldE5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3MzRW5jcnlwdGlvbkVuYWJsZWQnLCBjZGsudmFsaWRhdGVCb29sZWFuKShwcm9wZXJ0aWVzLnMzRW5jcnlwdGlvbkVuYWJsZWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3MzS2V5UHJlZml4JywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnMzS2V5UHJlZml4KSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkV4ZWN1dGVDb21tYW5kTG9nQ29uZmlndXJhdGlvblByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OkNsdXN0ZXIuRXhlY3V0ZUNvbW1hbmRMb2dDb25maWd1cmF0aW9uYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBFeGVjdXRlQ29tbWFuZExvZ0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpDbHVzdGVyLkV4ZWN1dGVDb21tYW5kTG9nQ29uZmlndXJhdGlvbmAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5DbHVzdGVyRXhlY3V0ZUNvbW1hbmRMb2dDb25maWd1cmF0aW9uUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbkNsdXN0ZXJfRXhlY3V0ZUNvbW1hbmRMb2dDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIENsb3VkV2F0Y2hFbmNyeXB0aW9uRW5hYmxlZDogY2RrLmJvb2xlYW5Ub0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY2xvdWRXYXRjaEVuY3J5cHRpb25FbmFibGVkKSxcbiAgICAgICAgQ2xvdWRXYXRjaExvZ0dyb3VwTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5jbG91ZFdhdGNoTG9nR3JvdXBOYW1lKSxcbiAgICAgICAgUzNCdWNrZXROYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnMzQnVja2V0TmFtZSksXG4gICAgICAgIFMzRW5jcnlwdGlvbkVuYWJsZWQ6IGNkay5ib29sZWFuVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnMzRW5jcnlwdGlvbkVuYWJsZWQpLFxuICAgICAgICBTM0tleVByZWZpeDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zM0tleVByZWZpeCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkNsdXN0ZXJFeGVjdXRlQ29tbWFuZExvZ0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbkNsdXN0ZXIuRXhlY3V0ZUNvbW1hbmRMb2dDb25maWd1cmF0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuQ2x1c3Rlci5FeGVjdXRlQ29tbWFuZExvZ0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2Nsb3VkV2F0Y2hFbmNyeXB0aW9uRW5hYmxlZCcsICdDbG91ZFdhdGNoRW5jcnlwdGlvbkVuYWJsZWQnLCBwcm9wZXJ0aWVzLkNsb3VkV2F0Y2hFbmNyeXB0aW9uRW5hYmxlZCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRCb29sZWFuKHByb3BlcnRpZXMuQ2xvdWRXYXRjaEVuY3J5cHRpb25FbmFibGVkKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjbG91ZFdhdGNoTG9nR3JvdXBOYW1lJywgJ0Nsb3VkV2F0Y2hMb2dHcm91cE5hbWUnLCBwcm9wZXJ0aWVzLkNsb3VkV2F0Y2hMb2dHcm91cE5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQ2xvdWRXYXRjaExvZ0dyb3VwTmFtZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnczNCdWNrZXROYW1lJywgJ1MzQnVja2V0TmFtZScsIHByb3BlcnRpZXMuUzNCdWNrZXROYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlMzQnVja2V0TmFtZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnczNFbmNyeXB0aW9uRW5hYmxlZCcsICdTM0VuY3J5cHRpb25FbmFibGVkJywgcHJvcGVydGllcy5TM0VuY3J5cHRpb25FbmFibGVkICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5TM0VuY3J5cHRpb25FbmFibGVkKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzM0tleVByZWZpeCcsICdTM0tleVByZWZpeCcsIHByb3BlcnRpZXMuUzNLZXlQcmVmaXggIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuUzNLZXlQcmVmaXgpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5DbHVzdGVyIHtcbiAgICAvKipcbiAgICAgKiBVc2UgdGhpcyBwYXJhbWV0ZXIgdG8gc2V0IGEgZGVmYXVsdCBTZXJ2aWNlIENvbm5lY3QgbmFtZXNwYWNlLiBBZnRlciB5b3Ugc2V0IGEgZGVmYXVsdCBTZXJ2aWNlIENvbm5lY3QgbmFtZXNwYWNlLCBhbnkgbmV3IHNlcnZpY2VzIHdpdGggU2VydmljZSBDb25uZWN0IHR1cm5lZCBvbiB0aGF0IGFyZSBjcmVhdGVkIGluIHRoZSBjbHVzdGVyIGFyZSBhZGRlZCBhcyBjbGllbnQgc2VydmljZXMgaW4gdGhlIG5hbWVzcGFjZS4gVGhpcyBzZXR0aW5nIG9ubHkgYXBwbGllcyB0byBuZXcgc2VydmljZXMgdGhhdCBzZXQgdGhlIGBlbmFibGVkYCBwYXJhbWV0ZXIgdG8gYHRydWVgIGluIHRoZSBgU2VydmljZUNvbm5lY3RDb25maWd1cmF0aW9uYCAuIFlvdSBjYW4gc2V0IHRoZSBuYW1lc3BhY2Ugb2YgZWFjaCBzZXJ2aWNlIGluZGl2aWR1YWxseSBpbiB0aGUgYFNlcnZpY2VDb25uZWN0Q29uZmlndXJhdGlvbmAgdG8gb3ZlcnJpZGUgdGhpcyBkZWZhdWx0IHBhcmFtZXRlci5cbiAgICAgKlxuICAgICAqIFRhc2tzIHRoYXQgcnVuIGluIGEgbmFtZXNwYWNlIGNhbiB1c2Ugc2hvcnQgbmFtZXMgdG8gY29ubmVjdCB0byBzZXJ2aWNlcyBpbiB0aGUgbmFtZXNwYWNlLiBUYXNrcyBjYW4gY29ubmVjdCB0byBzZXJ2aWNlcyBhY3Jvc3MgYWxsIG9mIHRoZSBjbHVzdGVycyBpbiB0aGUgbmFtZXNwYWNlLiBUYXNrcyBjb25uZWN0IHRocm91Z2ggYSBtYW5hZ2VkIHByb3h5IGNvbnRhaW5lciB0aGF0IGNvbGxlY3RzIGxvZ3MgYW5kIG1ldHJpY3MgZm9yIGluY3JlYXNlZCB2aXNpYmlsaXR5LiBPbmx5IHRoZSB0YXNrcyB0aGF0IEFtYXpvbiBFQ1Mgc2VydmljZXMgY3JlYXRlIGFyZSBzdXBwb3J0ZWQgd2l0aCBTZXJ2aWNlIENvbm5lY3QuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1NlcnZpY2UgQ29ubmVjdF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvc2VydmljZS1jb25uZWN0Lmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtY2x1c3Rlci1zZXJ2aWNlY29ubmVjdGRlZmF1bHRzLmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIFNlcnZpY2VDb25uZWN0RGVmYXVsdHNQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbmFtZXNwYWNlIG5hbWUgb3IgZnVsbCBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgQVdTIENsb3VkIE1hcCBuYW1lc3BhY2UgdGhhdCdzIHVzZWQgd2hlbiB5b3UgY3JlYXRlIGEgc2VydmljZSBhbmQgZG9uJ3Qgc3BlY2lmeSBhIFNlcnZpY2UgQ29ubmVjdCBjb25maWd1cmF0aW9uLiBUaGUgbmFtZXNwYWNlIG5hbWUgY2FuIGluY2x1ZGUgdXAgdG8gMTAyNCBjaGFyYWN0ZXJzLiBUaGUgbmFtZSBpcyBjYXNlLXNlbnNpdGl2ZS4gVGhlIG5hbWUgY2FuJ3QgaW5jbHVkZSBoeXBoZW5zICgtKSwgdGlsZGUgKH4pLCBncmVhdGVyIHRoYW4gKD4pLCBsZXNzIHRoYW4gKDwpLCBvciBzbGFzaCAoLykuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSBlbnRlciBhbiBleGlzdGluZyBuYW1lc3BhY2UgbmFtZSBvciBBUk4sIHRoZW4gdGhhdCBuYW1lc3BhY2Ugd2lsbCBiZSB1c2VkLiBBbnkgbmFtZXNwYWNlIHR5cGUgaXMgc3VwcG9ydGVkLiBUaGUgbmFtZXNwYWNlIG11c3QgYmUgaW4gdGhpcyBhY2NvdW50IGFuZCB0aGlzIEFXUyBSZWdpb24uXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSBlbnRlciBhIG5ldyBuYW1lLCBhIEFXUyBDbG91ZCBNYXAgbmFtZXNwYWNlIHdpbGwgYmUgY3JlYXRlZC4gQW1hem9uIEVDUyBjcmVhdGVzIGEgQVdTIENsb3VkIE1hcCBuYW1lc3BhY2Ugd2l0aCB0aGUgXCJBUEkgY2FsbHNcIiBtZXRob2Qgb2YgaW5zdGFuY2UgZGlzY292ZXJ5IG9ubHkuIFRoaXMgaW5zdGFuY2UgZGlzY292ZXJ5IG1ldGhvZCBpcyB0aGUgXCJIVFRQXCIgbmFtZXNwYWNlIHR5cGUgaW4gdGhlIEFXUyBDb21tYW5kIExpbmUgSW50ZXJmYWNlIC4gT3RoZXIgdHlwZXMgb2YgaW5zdGFuY2UgZGlzY292ZXJ5IGFyZW4ndCB1c2VkIGJ5IFNlcnZpY2UgQ29ubmVjdC5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgeW91IHVwZGF0ZSB0aGUgc2VydmljZSB3aXRoIGFuIGVtcHR5IHN0cmluZyBgXCJcImAgZm9yIHRoZSBuYW1lc3BhY2UgbmFtZSwgdGhlIGNsdXN0ZXIgY29uZmlndXJhdGlvbiBmb3IgU2VydmljZSBDb25uZWN0IGlzIHJlbW92ZWQuIE5vdGUgdGhhdCB0aGUgbmFtZXNwYWNlIHdpbGwgcmVtYWluIGluIEFXUyBDbG91ZCBNYXAgYW5kIG11c3QgYmUgZGVsZXRlZCBzZXBhcmF0ZWx5LlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBBV1MgQ2xvdWQgTWFwICwgc2VlIFtXb3JraW5nIHdpdGggU2VydmljZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbG91ZC1tYXAvbGF0ZXN0L2RnL3dvcmtpbmctd2l0aC1zZXJ2aWNlcy5odG1sKSBpbiB0aGUgKkFXUyBDbG91ZCBNYXAgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLWNsdXN0ZXItc2VydmljZWNvbm5lY3RkZWZhdWx0cy5odG1sI2Nmbi1lY3MtY2x1c3Rlci1zZXJ2aWNlY29ubmVjdGRlZmF1bHRzLW5hbWVzcGFjZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbmFtZXNwYWNlPzogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBTZXJ2aWNlQ29ubmVjdERlZmF1bHRzUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYFNlcnZpY2VDb25uZWN0RGVmYXVsdHNQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5DbHVzdGVyX1NlcnZpY2VDb25uZWN0RGVmYXVsdHNQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ25hbWVzcGFjZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5uYW1lc3BhY2UpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiU2VydmljZUNvbm5lY3REZWZhdWx0c1Byb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OkNsdXN0ZXIuU2VydmljZUNvbm5lY3REZWZhdWx0c2AgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgU2VydmljZUNvbm5lY3REZWZhdWx0c1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OkNsdXN0ZXIuU2VydmljZUNvbm5lY3REZWZhdWx0c2AgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5DbHVzdGVyU2VydmljZUNvbm5lY3REZWZhdWx0c1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5DbHVzdGVyX1NlcnZpY2VDb25uZWN0RGVmYXVsdHNQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgTmFtZXNwYWNlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm5hbWVzcGFjZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkNsdXN0ZXJTZXJ2aWNlQ29ubmVjdERlZmF1bHRzUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5DbHVzdGVyLlNlcnZpY2VDb25uZWN0RGVmYXVsdHNQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5DbHVzdGVyLlNlcnZpY2VDb25uZWN0RGVmYXVsdHNQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ25hbWVzcGFjZScsICdOYW1lc3BhY2UnLCBwcm9wZXJ0aWVzLk5hbWVzcGFjZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5OYW1lc3BhY2UpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIGBDZm5DbHVzdGVyQ2FwYWNpdHlQcm92aWRlckFzc29jaWF0aW9uc2BcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLWNsdXN0ZXJjYXBhY2l0eXByb3ZpZGVyYXNzb2NpYXRpb25zLmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5DbHVzdGVyQ2FwYWNpdHlQcm92aWRlckFzc29jaWF0aW9uc1Byb3BzIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjYXBhY2l0eSBwcm92aWRlcnMgdG8gYXNzb2NpYXRlIHdpdGggdGhlIGNsdXN0ZXIuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtY2x1c3RlcmNhcGFjaXR5cHJvdmlkZXJhc3NvY2lhdGlvbnMuaHRtbCNjZm4tZWNzLWNsdXN0ZXJjYXBhY2l0eXByb3ZpZGVyYXNzb2NpYXRpb25zLWNhcGFjaXR5cHJvdmlkZXJzXG4gICAgICovXG4gICAgcmVhZG9ubHkgY2FwYWNpdHlQcm92aWRlcnM6IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNsdXN0ZXIgdGhlIGNhcGFjaXR5IHByb3ZpZGVyIGFzc29jaWF0aW9uIGlzIHRoZSB0YXJnZXQgb2YuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtY2x1c3RlcmNhcGFjaXR5cHJvdmlkZXJhc3NvY2lhdGlvbnMuaHRtbCNjZm4tZWNzLWNsdXN0ZXJjYXBhY2l0eXByb3ZpZGVyYXNzb2NpYXRpb25zLWNsdXN0ZXJcbiAgICAgKi9cbiAgICByZWFkb25seSBjbHVzdGVyOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZGVmYXVsdCBjYXBhY2l0eSBwcm92aWRlciBzdHJhdGVneSB0byBhc3NvY2lhdGUgd2l0aCB0aGUgY2x1c3Rlci5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1jbHVzdGVyY2FwYWNpdHlwcm92aWRlcmFzc29jaWF0aW9ucy5odG1sI2Nmbi1lY3MtY2x1c3RlcmNhcGFjaXR5cHJvdmlkZXJhc3NvY2lhdGlvbnMtZGVmYXVsdGNhcGFjaXR5cHJvdmlkZXJzdHJhdGVneVxuICAgICAqL1xuICAgIHJlYWRvbmx5IGRlZmF1bHRDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3k6IEFycmF5PENmbkNsdXN0ZXJDYXBhY2l0eVByb3ZpZGVyQXNzb2NpYXRpb25zLkNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDZm5DbHVzdGVyQ2FwYWNpdHlQcm92aWRlckFzc29jaWF0aW9uc1Byb3BzYFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5DbHVzdGVyQ2FwYWNpdHlQcm92aWRlckFzc29jaWF0aW9uc1Byb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmbkNsdXN0ZXJDYXBhY2l0eVByb3ZpZGVyQXNzb2NpYXRpb25zUHJvcHNWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjYXBhY2l0eVByb3ZpZGVycycsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5jYXBhY2l0eVByb3ZpZGVycykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY2FwYWNpdHlQcm92aWRlcnMnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLmNhcGFjaXR5UHJvdmlkZXJzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjbHVzdGVyJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmNsdXN0ZXIpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NsdXN0ZXInLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY2x1c3RlcikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZGVmYXVsdENhcGFjaXR5UHJvdmlkZXJTdHJhdGVneScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5kZWZhdWx0Q2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdkZWZhdWx0Q2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5JywgY2RrLmxpc3RWYWxpZGF0b3IoQ2ZuQ2x1c3RlckNhcGFjaXR5UHJvdmlkZXJBc3NvY2lhdGlvbnNfQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5UHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLmRlZmF1bHRDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3kpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuQ2x1c3RlckNhcGFjaXR5UHJvdmlkZXJBc3NvY2lhdGlvbnNQcm9wc1wiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpDbHVzdGVyQ2FwYWNpdHlQcm92aWRlckFzc29jaWF0aW9uc2AgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuQ2x1c3RlckNhcGFjaXR5UHJvdmlkZXJBc3NvY2lhdGlvbnNQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpDbHVzdGVyQ2FwYWNpdHlQcm92aWRlckFzc29jaWF0aW9uc2AgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5DbHVzdGVyQ2FwYWNpdHlQcm92aWRlckFzc29jaWF0aW9uc1Byb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5DbHVzdGVyQ2FwYWNpdHlQcm92aWRlckFzc29jaWF0aW9uc1Byb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBDYXBhY2l0eVByb3ZpZGVyczogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuY2FwYWNpdHlQcm92aWRlcnMpLFxuICAgICAgICBDbHVzdGVyOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNsdXN0ZXIpLFxuICAgICAgICBEZWZhdWx0Q2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5OiBjZGsubGlzdE1hcHBlcihjZm5DbHVzdGVyQ2FwYWNpdHlQcm92aWRlckFzc29jaWF0aW9uc0NhcGFjaXR5UHJvdmlkZXJTdHJhdGVneVByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5kZWZhdWx0Q2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5KSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuQ2x1c3RlckNhcGFjaXR5UHJvdmlkZXJBc3NvY2lhdGlvbnNQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbkNsdXN0ZXJDYXBhY2l0eVByb3ZpZGVyQXNzb2NpYXRpb25zUHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbkNsdXN0ZXJDYXBhY2l0eVByb3ZpZGVyQXNzb2NpYXRpb25zUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjYXBhY2l0eVByb3ZpZGVycycsICdDYXBhY2l0eVByb3ZpZGVycycsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5DYXBhY2l0eVByb3ZpZGVycykpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY2x1c3RlcicsICdDbHVzdGVyJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5DbHVzdGVyKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdkZWZhdWx0Q2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5JywgJ0RlZmF1bHRDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3knLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KENmbkNsdXN0ZXJDYXBhY2l0eVByb3ZpZGVyQXNzb2NpYXRpb25zQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuRGVmYXVsdENhcGFjaXR5UHJvdmlkZXJTdHJhdGVneSkpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6RUNTOjpDbHVzdGVyQ2FwYWNpdHlQcm92aWRlckFzc29jaWF0aW9uc2BcbiAqXG4gKiBUaGUgYEFXUzo6RUNTOjpDbHVzdGVyQ2FwYWNpdHlQcm92aWRlckFzc29jaWF0aW9uc2AgcmVzb3VyY2UgYXNzb2NpYXRlcyBvbmUgb3IgbW9yZSBjYXBhY2l0eSBwcm92aWRlcnMgYW5kIGEgZGVmYXVsdCBjYXBhY2l0eSBwcm92aWRlciBzdHJhdGVneSB3aXRoIGEgY2x1c3Rlci5cbiAqXG4gKiBAY2xvdWRmb3JtYXRpb25SZXNvdXJjZSBBV1M6OkVDUzo6Q2x1c3RlckNhcGFjaXR5UHJvdmlkZXJBc3NvY2lhdGlvbnNcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtY2x1c3RlcmNhcGFjaXR5cHJvdmlkZXJhc3NvY2lhdGlvbnMuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuQ2x1c3RlckNhcGFjaXR5UHJvdmlkZXJBc3NvY2lhdGlvbnMgZXh0ZW5kcyBjZGsuQ2ZuUmVzb3VyY2UgaW1wbGVtZW50cyBjZGsuSUluc3BlY3RhYmxlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgdHlwZSBuYW1lIGZvciB0aGlzIHJlc291cmNlIGNsYXNzLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSA9IFwiQVdTOjpFQ1M6OkNsdXN0ZXJDYXBhY2l0eVByb3ZpZGVyQXNzb2NpYXRpb25zXCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5DbHVzdGVyQ2FwYWNpdHlQcm92aWRlckFzc29jaWF0aW9ucyB7XG4gICAgICAgIHJlc291cmNlQXR0cmlidXRlcyA9IHJlc291cmNlQXR0cmlidXRlcyB8fCB7fTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VQcm9wZXJ0aWVzID0gb3B0aW9ucy5wYXJzZXIucGFyc2VWYWx1ZShyZXNvdXJjZUF0dHJpYnV0ZXMuUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHByb3BzUmVzdWx0ID0gQ2ZuQ2x1c3RlckNhcGFjaXR5UHJvdmlkZXJBc3NvY2lhdGlvbnNQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihyZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgQ2ZuQ2x1c3RlckNhcGFjaXR5UHJvdmlkZXJBc3NvY2lhdGlvbnMoc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGNhcGFjaXR5IHByb3ZpZGVycyB0byBhc3NvY2lhdGUgd2l0aCB0aGUgY2x1c3Rlci5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1jbHVzdGVyY2FwYWNpdHlwcm92aWRlcmFzc29jaWF0aW9ucy5odG1sI2Nmbi1lY3MtY2x1c3RlcmNhcGFjaXR5cHJvdmlkZXJhc3NvY2lhdGlvbnMtY2FwYWNpdHlwcm92aWRlcnNcbiAgICAgKi9cbiAgICBwdWJsaWMgY2FwYWNpdHlQcm92aWRlcnM6IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNsdXN0ZXIgdGhlIGNhcGFjaXR5IHByb3ZpZGVyIGFzc29jaWF0aW9uIGlzIHRoZSB0YXJnZXQgb2YuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtY2x1c3RlcmNhcGFjaXR5cHJvdmlkZXJhc3NvY2lhdGlvbnMuaHRtbCNjZm4tZWNzLWNsdXN0ZXJjYXBhY2l0eXByb3ZpZGVyYXNzb2NpYXRpb25zLWNsdXN0ZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgY2x1c3Rlcjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGRlZmF1bHQgY2FwYWNpdHkgcHJvdmlkZXIgc3RyYXRlZ3kgdG8gYXNzb2NpYXRlIHdpdGggdGhlIGNsdXN0ZXIuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtY2x1c3RlcmNhcGFjaXR5cHJvdmlkZXJhc3NvY2lhdGlvbnMuaHRtbCNjZm4tZWNzLWNsdXN0ZXJjYXBhY2l0eXByb3ZpZGVyYXNzb2NpYXRpb25zLWRlZmF1bHRjYXBhY2l0eXByb3ZpZGVyc3RyYXRlZ3lcbiAgICAgKi9cbiAgICBwdWJsaWMgZGVmYXVsdENhcGFjaXR5UHJvdmlkZXJTdHJhdGVneTogQXJyYXk8Q2ZuQ2x1c3RlckNhcGFjaXR5UHJvdmlkZXJBc3NvY2lhdGlvbnMuQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGBBV1M6OkVDUzo6Q2x1c3RlckNhcGFjaXR5UHJvdmlkZXJBc3NvY2lhdGlvbnNgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNjb3BlIC0gc2NvcGUgaW4gd2hpY2ggdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkXG4gICAgICogQHBhcmFtIGlkICAgIC0gc2NvcGVkIGlkIG9mIHRoZSByZXNvdXJjZVxuICAgICAqIEBwYXJhbSBwcm9wcyAtIHJlc291cmNlIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENmbkNsdXN0ZXJDYXBhY2l0eVByb3ZpZGVyQXNzb2NpYXRpb25zUHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmbkNsdXN0ZXJDYXBhY2l0eVByb3ZpZGVyQXNzb2NpYXRpb25zLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUsIHByb3BlcnRpZXM6IHByb3BzIH0pO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAnY2FwYWNpdHlQcm92aWRlcnMnLCB0aGlzKTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ2NsdXN0ZXInLCB0aGlzKTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ2RlZmF1bHRDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3knLCB0aGlzKTtcblxuICAgICAgICB0aGlzLmNhcGFjaXR5UHJvdmlkZXJzID0gcHJvcHMuY2FwYWNpdHlQcm92aWRlcnM7XG4gICAgICAgIHRoaXMuY2x1c3RlciA9IHByb3BzLmNsdXN0ZXI7XG4gICAgICAgIHRoaXMuZGVmYXVsdENhcGFjaXR5UHJvdmlkZXJTdHJhdGVneSA9IHByb3BzLmRlZmF1bHRDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3k7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5DbHVzdGVyQ2FwYWNpdHlQcm92aWRlckFzc29jaWF0aW9ucy5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FKTtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246cHJvcHNcIiwgdGhpcy5jZm5Qcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGNmblByb3BlcnRpZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY2FwYWNpdHlQcm92aWRlcnM6IHRoaXMuY2FwYWNpdHlQcm92aWRlcnMsXG4gICAgICAgICAgICBjbHVzdGVyOiB0aGlzLmNsdXN0ZXIsXG4gICAgICAgICAgICBkZWZhdWx0Q2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5OiB0aGlzLmRlZmF1bHRDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3ksXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlbmRlclByb3BlcnRpZXMocHJvcHM6IHtba2V5OiBzdHJpbmddOiBhbnl9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4gY2ZuQ2x1c3RlckNhcGFjaXR5UHJvdmlkZXJBc3NvY2lhdGlvbnNQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcHMpO1xuICAgIH1cbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5DbHVzdGVyQ2FwYWNpdHlQcm92aWRlckFzc29jaWF0aW9ucyB7XG4gICAgLyoqXG4gICAgICogVGhlIGBDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3lgIHByb3BlcnR5IHNwZWNpZmllcyB0aGUgZGV0YWlscyBvZiB0aGUgZGVmYXVsdCBjYXBhY2l0eSBwcm92aWRlciBzdHJhdGVneSBmb3IgdGhlIGNsdXN0ZXIuIFdoZW4gc2VydmljZXMgb3IgdGFza3MgYXJlIHJ1biBpbiB0aGUgY2x1c3RlciB3aXRoIG5vIGxhdW5jaCB0eXBlIG9yIGNhcGFjaXR5IHByb3ZpZGVyIHN0cmF0ZWd5IHNwZWNpZmllZCwgdGhlIGRlZmF1bHQgY2FwYWNpdHkgcHJvdmlkZXIgc3RyYXRlZ3kgaXMgdXNlZC5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1jbHVzdGVyY2FwYWNpdHlwcm92aWRlcmFzc29jaWF0aW9ucy1jYXBhY2l0eXByb3ZpZGVyc3RyYXRlZ3kuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5UHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlICpiYXNlKiB2YWx1ZSBkZXNpZ25hdGVzIGhvdyBtYW55IHRhc2tzLCBhdCBhIG1pbmltdW0sIHRvIHJ1biBvbiB0aGUgc3BlY2lmaWVkIGNhcGFjaXR5IHByb3ZpZGVyLiBPbmx5IG9uZSBjYXBhY2l0eSBwcm92aWRlciBpbiBhIGNhcGFjaXR5IHByb3ZpZGVyIHN0cmF0ZWd5IGNhbiBoYXZlIGEgKmJhc2UqIGRlZmluZWQuIElmIG5vIHZhbHVlIGlzIHNwZWNpZmllZCwgdGhlIGRlZmF1bHQgdmFsdWUgb2YgYDBgIGlzIHVzZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLWNsdXN0ZXJjYXBhY2l0eXByb3ZpZGVyYXNzb2NpYXRpb25zLWNhcGFjaXR5cHJvdmlkZXJzdHJhdGVneS5odG1sI2Nmbi1lY3MtY2x1c3RlcmNhcGFjaXR5cHJvdmlkZXJhc3NvY2lhdGlvbnMtY2FwYWNpdHlwcm92aWRlcnN0cmF0ZWd5LWJhc2VcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGJhc2U/OiBudW1iZXI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgc2hvcnQgbmFtZSBvZiB0aGUgY2FwYWNpdHkgcHJvdmlkZXIuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLWNsdXN0ZXJjYXBhY2l0eXByb3ZpZGVyYXNzb2NpYXRpb25zLWNhcGFjaXR5cHJvdmlkZXJzdHJhdGVneS5odG1sI2Nmbi1lY3MtY2x1c3RlcmNhcGFjaXR5cHJvdmlkZXJhc3NvY2lhdGlvbnMtY2FwYWNpdHlwcm92aWRlcnN0cmF0ZWd5LWNhcGFjaXR5cHJvdmlkZXJcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNhcGFjaXR5UHJvdmlkZXI6IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSAqd2VpZ2h0KiB2YWx1ZSBkZXNpZ25hdGVzIHRoZSByZWxhdGl2ZSBwZXJjZW50YWdlIG9mIHRoZSB0b3RhbCBudW1iZXIgb2YgdGFza3MgbGF1bmNoZWQgdGhhdCBzaG91bGQgdXNlIHRoZSBzcGVjaWZpZWQgY2FwYWNpdHkgcHJvdmlkZXIuIFRoZSBgd2VpZ2h0YCB2YWx1ZSBpcyB0YWtlbiBpbnRvIGNvbnNpZGVyYXRpb24gYWZ0ZXIgdGhlIGBiYXNlYCB2YWx1ZSwgaWYgZGVmaW5lZCwgaXMgc2F0aXNmaWVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiBubyBgd2VpZ2h0YCB2YWx1ZSBpcyBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IHZhbHVlIG9mIGAwYCBpcyB1c2VkLiBXaGVuIG11bHRpcGxlIGNhcGFjaXR5IHByb3ZpZGVycyBhcmUgc3BlY2lmaWVkIHdpdGhpbiBhIGNhcGFjaXR5IHByb3ZpZGVyIHN0cmF0ZWd5LCBhdCBsZWFzdCBvbmUgb2YgdGhlIGNhcGFjaXR5IHByb3ZpZGVycyBtdXN0IGhhdmUgYSB3ZWlnaHQgdmFsdWUgZ3JlYXRlciB0aGFuIHplcm8gYW5kIGFueSBjYXBhY2l0eSBwcm92aWRlcnMgd2l0aCBhIHdlaWdodCBvZiBgMGAgd2lsbCBub3QgYmUgdXNlZCB0byBwbGFjZSB0YXNrcy4gSWYgeW91IHNwZWNpZnkgbXVsdGlwbGUgY2FwYWNpdHkgcHJvdmlkZXJzIGluIGEgc3RyYXRlZ3kgdGhhdCBhbGwgaGF2ZSBhIHdlaWdodCBvZiBgMGAgLCBhbnkgYFJ1blRhc2tgIG9yIGBDcmVhdGVTZXJ2aWNlYCBhY3Rpb25zIHVzaW5nIHRoZSBjYXBhY2l0eSBwcm92aWRlciBzdHJhdGVneSB3aWxsIGZhaWwuXG4gICAgICAgICAqXG4gICAgICAgICAqIEFuIGV4YW1wbGUgc2NlbmFyaW8gZm9yIHVzaW5nIHdlaWdodHMgaXMgZGVmaW5pbmcgYSBzdHJhdGVneSB0aGF0IGNvbnRhaW5zIHR3byBjYXBhY2l0eSBwcm92aWRlcnMgYW5kIGJvdGggaGF2ZSBhIHdlaWdodCBvZiBgMWAgLCB0aGVuIHdoZW4gdGhlIGBiYXNlYCBpcyBzYXRpc2ZpZWQsIHRoZSB0YXNrcyB3aWxsIGJlIHNwbGl0IGV2ZW5seSBhY3Jvc3MgdGhlIHR3byBjYXBhY2l0eSBwcm92aWRlcnMuIFVzaW5nIHRoYXQgc2FtZSBsb2dpYywgaWYgeW91IHNwZWNpZnkgYSB3ZWlnaHQgb2YgYDFgIGZvciAqY2FwYWNpdHlQcm92aWRlckEqIGFuZCBhIHdlaWdodCBvZiBgNGAgZm9yICpjYXBhY2l0eVByb3ZpZGVyQiogLCB0aGVuIGZvciBldmVyeSBvbmUgdGFzayB0aGF0IGlzIHJ1biB1c2luZyAqY2FwYWNpdHlQcm92aWRlckEqICwgZm91ciB0YXNrcyB3b3VsZCB1c2UgKmNhcGFjaXR5UHJvdmlkZXJCKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLWNsdXN0ZXJjYXBhY2l0eXByb3ZpZGVyYXNzb2NpYXRpb25zLWNhcGFjaXR5cHJvdmlkZXJzdHJhdGVneS5odG1sI2Nmbi1lY3MtY2x1c3RlcmNhcGFjaXR5cHJvdmlkZXJhc3NvY2lhdGlvbnMtY2FwYWNpdHlwcm92aWRlcnN0cmF0ZWd5LXdlaWdodFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgd2VpZ2h0PzogbnVtYmVyO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3lQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuQ2x1c3RlckNhcGFjaXR5UHJvdmlkZXJBc3NvY2lhdGlvbnNfQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5UHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdiYXNlJywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLmJhc2UpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NhcGFjaXR5UHJvdmlkZXInLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMuY2FwYWNpdHlQcm92aWRlcikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY2FwYWNpdHlQcm92aWRlcicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jYXBhY2l0eVByb3ZpZGVyKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd3ZWlnaHQnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMud2VpZ2h0KSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneVByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OkNsdXN0ZXJDYXBhY2l0eVByb3ZpZGVyQXNzb2NpYXRpb25zLkNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneWAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6Q2x1c3RlckNhcGFjaXR5UHJvdmlkZXJBc3NvY2lhdGlvbnMuQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5YCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmbkNsdXN0ZXJDYXBhY2l0eVByb3ZpZGVyQXNzb2NpYXRpb25zQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbkNsdXN0ZXJDYXBhY2l0eVByb3ZpZGVyQXNzb2NpYXRpb25zX0NhcGFjaXR5UHJvdmlkZXJTdHJhdGVneVByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBCYXNlOiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmJhc2UpLFxuICAgICAgICBDYXBhY2l0eVByb3ZpZGVyOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNhcGFjaXR5UHJvdmlkZXIpLFxuICAgICAgICBXZWlnaHQ6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMud2VpZ2h0KSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuQ2x1c3RlckNhcGFjaXR5UHJvdmlkZXJBc3NvY2lhdGlvbnNDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3lQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbkNsdXN0ZXJDYXBhY2l0eVByb3ZpZGVyQXNzb2NpYXRpb25zLkNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbkNsdXN0ZXJDYXBhY2l0eVByb3ZpZGVyQXNzb2NpYXRpb25zLkNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneVByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnYmFzZScsICdCYXNlJywgcHJvcGVydGllcy5CYXNlICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLkJhc2UpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2NhcGFjaXR5UHJvdmlkZXInLCAnQ2FwYWNpdHlQcm92aWRlcicsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQ2FwYWNpdHlQcm92aWRlcikpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnd2VpZ2h0JywgJ1dlaWdodCcsIHByb3BlcnRpZXMuV2VpZ2h0ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLldlaWdodCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmblByaW1hcnlUYXNrU2V0YFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtcHJpbWFyeXRhc2tzZXQuaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENmblByaW1hcnlUYXNrU2V0UHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogVGhlIHNob3J0IG5hbWUgb3IgZnVsbCBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgY2x1c3RlciB0aGF0IGhvc3RzIHRoZSBzZXJ2aWNlIHRoYXQgdGhlIHRhc2sgc2V0IGV4aXN0cyBpbi5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1wcmltYXJ5dGFza3NldC5odG1sI2Nmbi1lY3MtcHJpbWFyeXRhc2tzZXQtY2x1c3RlclxuICAgICAqL1xuICAgIHJlYWRvbmx5IGNsdXN0ZXI6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBzaG9ydCBuYW1lIG9yIGZ1bGwgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIHNlcnZpY2UgdGhhdCB0aGUgdGFzayBzZXQgZXhpc3RzIGluLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXByaW1hcnl0YXNrc2V0Lmh0bWwjY2ZuLWVjcy1wcmltYXJ5dGFza3NldC1zZXJ2aWNlXG4gICAgICovXG4gICAgcmVhZG9ubHkgc2VydmljZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHNob3J0IG5hbWUgb3IgZnVsbCBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgdGFzayBzZXQgdG8gc2V0IGFzIHRoZSBwcmltYXJ5IHRhc2sgc2V0IGluIHRoZSBkZXBsb3ltZW50LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXByaW1hcnl0YXNrc2V0Lmh0bWwjY2ZuLWVjcy1wcmltYXJ5dGFza3NldC10YXNrc2V0aWRcbiAgICAgKi9cbiAgICByZWFkb25seSB0YXNrU2V0SWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDZm5QcmltYXJ5VGFza1NldFByb3BzYFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5QcmltYXJ5VGFza1NldFByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblByaW1hcnlUYXNrU2V0UHJvcHNWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjbHVzdGVyJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmNsdXN0ZXIpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NsdXN0ZXInLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY2x1c3RlcikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc2VydmljZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5zZXJ2aWNlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzZXJ2aWNlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnNlcnZpY2UpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3Rhc2tTZXRJZCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy50YXNrU2V0SWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3Rhc2tTZXRJZCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy50YXNrU2V0SWQpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuUHJpbWFyeVRhc2tTZXRQcm9wc1wiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpQcmltYXJ5VGFza1NldGAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuUHJpbWFyeVRhc2tTZXRQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpQcmltYXJ5VGFza1NldGAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5QcmltYXJ5VGFza1NldFByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5QcmltYXJ5VGFza1NldFByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBDbHVzdGVyOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNsdXN0ZXIpLFxuICAgICAgICBTZXJ2aWNlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnNlcnZpY2UpLFxuICAgICAgICBUYXNrU2V0SWQ6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMudGFza1NldElkKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuUHJpbWFyeVRhc2tTZXRQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblByaW1hcnlUYXNrU2V0UHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblByaW1hcnlUYXNrU2V0UHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjbHVzdGVyJywgJ0NsdXN0ZXInLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNsdXN0ZXIpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3NlcnZpY2UnLCAnU2VydmljZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuU2VydmljZSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndGFza1NldElkJywgJ1Rhc2tTZXRJZCcsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuVGFza1NldElkKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpFQ1M6OlByaW1hcnlUYXNrU2V0YFxuICpcbiAqIE1vZGlmaWVzIHdoaWNoIHRhc2sgc2V0IGluIGEgc2VydmljZSBpcyB0aGUgcHJpbWFyeSB0YXNrIHNldC4gQW55IHBhcmFtZXRlcnMgdGhhdCBhcmUgdXBkYXRlZCBvbiB0aGUgcHJpbWFyeSB0YXNrIHNldCBpbiBhIHNlcnZpY2Ugd2lsbCB0cmFuc2l0aW9uIHRvIHRoZSBzZXJ2aWNlLiBUaGlzIGlzIHVzZWQgd2hlbiBhIHNlcnZpY2UgdXNlcyB0aGUgYEVYVEVSTkFMYCBkZXBsb3ltZW50IGNvbnRyb2xsZXIgdHlwZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQW1hem9uIEVDUyBEZXBsb3ltZW50IFR5cGVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9kZXBsb3ltZW50LXR5cGVzLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpFQ1M6OlByaW1hcnlUYXNrU2V0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXByaW1hcnl0YXNrc2V0Lmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIENmblByaW1hcnlUYXNrU2V0IGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6RUNTOjpQcmltYXJ5VGFza1NldFwiO1xuXG4gICAgLyoqXG4gICAgICogQSBmYWN0b3J5IG1ldGhvZCB0aGF0IGNyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBmcm9tIGFuIG9iamVjdFxuICAgICAqIGNvbnRhaW5pbmcgdGhlIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgdGhpcyByZXNvdXJjZS5cbiAgICAgKiBVc2VkIGluIHRoZSBAYXdzLWNkay9jbG91ZGZvcm1hdGlvbi1pbmNsdWRlIG1vZHVsZS5cbiAgICAgKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgX2Zyb21DbG91ZEZvcm1hdGlvbihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcmVzb3VyY2VBdHRyaWJ1dGVzOiBhbnksIG9wdGlvbnM6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25PcHRpb25zKTogQ2ZuUHJpbWFyeVRhc2tTZXQge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmblByaW1hcnlUYXNrU2V0UHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmblByaW1hcnlUYXNrU2V0KHNjb3BlLCBpZCwgcHJvcHNSZXN1bHQudmFsdWUpO1xuICAgICAgICBmb3IgKGNvbnN0IFtwcm9wS2V5LCBwcm9wVmFsXSBvZiBPYmplY3QuZW50cmllcyhwcm9wc1Jlc3VsdC5leHRyYVByb3BlcnRpZXMpKSAge1xuICAgICAgICAgICAgcmV0LmFkZFByb3BlcnR5T3ZlcnJpZGUocHJvcEtleSwgcHJvcFZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5wYXJzZXIuaGFuZGxlQXR0cmlidXRlcyhyZXQsIHJlc291cmNlQXR0cmlidXRlcywgaWQpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzaG9ydCBuYW1lIG9yIGZ1bGwgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIGNsdXN0ZXIgdGhhdCBob3N0cyB0aGUgc2VydmljZSB0aGF0IHRoZSB0YXNrIHNldCBleGlzdHMgaW4uXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtcHJpbWFyeXRhc2tzZXQuaHRtbCNjZm4tZWNzLXByaW1hcnl0YXNrc2V0LWNsdXN0ZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgY2x1c3Rlcjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHNob3J0IG5hbWUgb3IgZnVsbCBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgc2VydmljZSB0aGF0IHRoZSB0YXNrIHNldCBleGlzdHMgaW4uXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtcHJpbWFyeXRhc2tzZXQuaHRtbCNjZm4tZWNzLXByaW1hcnl0YXNrc2V0LXNlcnZpY2VcbiAgICAgKi9cbiAgICBwdWJsaWMgc2VydmljZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHNob3J0IG5hbWUgb3IgZnVsbCBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgdGFzayBzZXQgdG8gc2V0IGFzIHRoZSBwcmltYXJ5IHRhc2sgc2V0IGluIHRoZSBkZXBsb3ltZW50LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXByaW1hcnl0YXNrc2V0Lmh0bWwjY2ZuLWVjcy1wcmltYXJ5dGFza3NldC10YXNrc2V0aWRcbiAgICAgKi9cbiAgICBwdWJsaWMgdGFza1NldElkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6RUNTOjpQcmltYXJ5VGFza1NldGAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuUHJpbWFyeVRhc2tTZXRQcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuUHJpbWFyeVRhc2tTZXQuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICdjbHVzdGVyJywgdGhpcyk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICdzZXJ2aWNlJywgdGhpcyk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICd0YXNrU2V0SWQnLCB0aGlzKTtcblxuICAgICAgICB0aGlzLmNsdXN0ZXIgPSBwcm9wcy5jbHVzdGVyO1xuICAgICAgICB0aGlzLnNlcnZpY2UgPSBwcm9wcy5zZXJ2aWNlO1xuICAgICAgICB0aGlzLnRhc2tTZXRJZCA9IHByb3BzLnRhc2tTZXRJZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmblByaW1hcnlUYXNrU2V0LkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjbHVzdGVyOiB0aGlzLmNsdXN0ZXIsXG4gICAgICAgICAgICBzZXJ2aWNlOiB0aGlzLnNlcnZpY2UsXG4gICAgICAgICAgICB0YXNrU2V0SWQ6IHRoaXMudGFza1NldElkLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmblByaW1hcnlUYXNrU2V0UHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuU2VydmljZWBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENmblNlcnZpY2VQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2FwYWNpdHkgcHJvdmlkZXIgc3RyYXRlZ3kgdG8gdXNlIGZvciB0aGUgc2VydmljZS5cbiAgICAgKlxuICAgICAqIElmIGEgYGNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneWAgaXMgc3BlY2lmaWVkLCB0aGUgYGxhdW5jaFR5cGVgIHBhcmFtZXRlciBtdXN0IGJlIG9taXR0ZWQuIElmIG5vIGBjYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3lgIG9yIGBsYXVuY2hUeXBlYCBpcyBzcGVjaWZpZWQsIHRoZSBgZGVmYXVsdENhcGFjaXR5UHJvdmlkZXJTdHJhdGVneWAgZm9yIHRoZSBjbHVzdGVyIGlzIHVzZWQuXG4gICAgICpcbiAgICAgKiBBIGNhcGFjaXR5IHByb3ZpZGVyIHN0cmF0ZWd5IG1heSBjb250YWluIGEgbWF4aW11bSBvZiA2IGNhcGFjaXR5IHByb3ZpZGVycy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1zZXJ2aWNlLmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLWNhcGFjaXR5cHJvdmlkZXJzdHJhdGVneVxuICAgICAqL1xuICAgIHJlYWRvbmx5IGNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneT86IEFycmF5PENmblNlcnZpY2UuQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5SXRlbVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBzaG9ydCBuYW1lIG9yIGZ1bGwgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIGNsdXN0ZXIgdGhhdCB5b3UgcnVuIHlvdXIgc2VydmljZSBvbi4gSWYgeW91IGRvIG5vdCBzcGVjaWZ5IGEgY2x1c3RlciwgdGhlIGRlZmF1bHQgY2x1c3RlciBpcyBhc3N1bWVkLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbCNjZm4tZWNzLXNlcnZpY2UtY2x1c3RlclxuICAgICAqL1xuICAgIHJlYWRvbmx5IGNsdXN0ZXI/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBPcHRpb25hbCBkZXBsb3ltZW50IHBhcmFtZXRlcnMgdGhhdCBjb250cm9sIGhvdyBtYW55IHRhc2tzIHJ1biBkdXJpbmcgdGhlIGRlcGxveW1lbnQgYW5kIHRoZSBvcmRlcmluZyBvZiBzdG9wcGluZyBhbmQgc3RhcnRpbmcgdGFza3MuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1kZXBsb3ltZW50Y29uZmlndXJhdGlvblxuICAgICAqL1xuICAgIHJlYWRvbmx5IGRlcGxveW1lbnRDb25maWd1cmF0aW9uPzogQ2ZuU2VydmljZS5EZXBsb3ltZW50Q29uZmlndXJhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGRlcGxveW1lbnQgY29udHJvbGxlciB0byB1c2UgZm9yIHRoZSBzZXJ2aWNlLiBJZiBubyBkZXBsb3ltZW50IGNvbnRyb2xsZXIgaXMgc3BlY2lmaWVkLCB0aGUgZGVmYXVsdCB2YWx1ZSBvZiBgRUNTYCBpcyB1c2VkLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbCNjZm4tZWNzLXNlcnZpY2UtZGVwbG95bWVudGNvbnRyb2xsZXJcbiAgICAgKi9cbiAgICByZWFkb25seSBkZXBsb3ltZW50Q29udHJvbGxlcj86IENmblNlcnZpY2UuRGVwbG95bWVudENvbnRyb2xsZXJQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgaW5zdGFudGlhdGlvbnMgb2YgdGhlIHNwZWNpZmllZCB0YXNrIGRlZmluaXRpb24gdG8gcGxhY2UgYW5kIGtlZXAgcnVubmluZyBpbiB5b3VyIHNlcnZpY2UuXG4gICAgICpcbiAgICAgKiBGb3IgbmV3IHNlcnZpY2VzLCBpZiBhIGRlc2lyZWQgY291bnQgaXMgbm90IHNwZWNpZmllZCwgYSBkZWZhdWx0IHZhbHVlIG9mIGAxYCBpcyB1c2VkLiBXaGVuIHVzaW5nIHRoZSBgREFFTU9OYCBzY2hlZHVsaW5nIHN0cmF0ZWd5LCB0aGUgZGVzaXJlZCBjb3VudCBpcyBub3QgcmVxdWlyZWQuXG4gICAgICpcbiAgICAgKiBGb3IgZXhpc3Rpbmcgc2VydmljZXMsIGlmIGEgZGVzaXJlZCBjb3VudCBpcyBub3Qgc3BlY2lmaWVkLCBpdCBpcyBvbWl0dGVkIGZyb20gdGhlIG9wZXJhdGlvbi5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1zZXJ2aWNlLmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLWRlc2lyZWRjb3VudFxuICAgICAqL1xuICAgIHJlYWRvbmx5IGRlc2lyZWRDb3VudD86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIFNwZWNpZmllcyB3aGV0aGVyIHRvIHR1cm4gb24gQW1hem9uIEVDUyBtYW5hZ2VkIHRhZ3MgZm9yIHRoZSB0YXNrcyB3aXRoaW4gdGhlIHNlcnZpY2UuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1RhZ2dpbmcgeW91ciBBbWF6b24gRUNTIHJlc291cmNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvZWNzLXVzaW5nLXRhZ3MuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIFdoZW4geW91IHVzZSBBbWF6b24gRUNTIG1hbmFnZWQgdGFncywgeW91IG5lZWQgdG8gc2V0IHRoZSBgcHJvcGFnYXRlVGFnc2AgcmVxdWVzdCBwYXJhbWV0ZXIuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1lbmFibGVlY3NtYW5hZ2VkdGFnc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IGVuYWJsZUVjc01hbmFnZWRUYWdzPzogYm9vbGVhbiB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGUgZXhlY3V0ZSBjb21tYW5kIGZ1bmN0aW9uYWxpdHkgaXMgdHVybmVkIG9uIGZvciB0aGUgc2VydmljZS4gSWYgYHRydWVgICwgdGhlIGV4ZWN1dGUgY29tbWFuZCBmdW5jdGlvbmFsaXR5IGlzIHR1cm5lZCBvbiBmb3IgYWxsIGNvbnRhaW5lcnMgaW4gdGFza3MgYXMgcGFydCBvZiB0aGUgc2VydmljZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1zZXJ2aWNlLmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLWVuYWJsZWV4ZWN1dGVjb21tYW5kXG4gICAgICovXG4gICAgcmVhZG9ubHkgZW5hYmxlRXhlY3V0ZUNvbW1hbmQ/OiBib29sZWFuIHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBlcmlvZCBvZiB0aW1lLCBpbiBzZWNvbmRzLCB0aGF0IHRoZSBBbWF6b24gRUNTIHNlcnZpY2Ugc2NoZWR1bGVyIGlnbm9yZXMgdW5oZWFsdGh5IEVsYXN0aWMgTG9hZCBCYWxhbmNpbmcgdGFyZ2V0IGhlYWx0aCBjaGVja3MgYWZ0ZXIgYSB0YXNrIGhhcyBmaXJzdCBzdGFydGVkLiBUaGlzIGlzIG9ubHkgdXNlZCB3aGVuIHlvdXIgc2VydmljZSBpcyBjb25maWd1cmVkIHRvIHVzZSBhIGxvYWQgYmFsYW5jZXIuIElmIHlvdXIgc2VydmljZSBoYXMgYSBsb2FkIGJhbGFuY2VyIGRlZmluZWQgYW5kIHlvdSBkb24ndCBzcGVjaWZ5IGEgaGVhbHRoIGNoZWNrIGdyYWNlIHBlcmlvZCB2YWx1ZSwgdGhlIGRlZmF1bHQgdmFsdWUgb2YgYDBgIGlzIHVzZWQuXG4gICAgICpcbiAgICAgKiBJZiB5b3UgZG8gbm90IHVzZSBhbiBFbGFzdGljIExvYWQgQmFsYW5jaW5nLCB3ZSByZWNvbW1lbmQgdGhhdCB5b3UgdXNlIHRoZSBgc3RhcnRQZXJpb2RgIGluIHRoZSB0YXNrIGRlZmluaXRpb24gaGVhbHRoIGNoZWNrIHBhcmFtZXRlcnMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0hlYWx0aCBjaGVja10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9IZWFsdGhDaGVjay5odG1sKSAuXG4gICAgICpcbiAgICAgKiBJZiB5b3VyIHNlcnZpY2UncyB0YXNrcyB0YWtlIGEgd2hpbGUgdG8gc3RhcnQgYW5kIHJlc3BvbmQgdG8gRWxhc3RpYyBMb2FkIEJhbGFuY2luZyBoZWFsdGggY2hlY2tzLCB5b3UgY2FuIHNwZWNpZnkgYSBoZWFsdGggY2hlY2sgZ3JhY2UgcGVyaW9kIG9mIHVwIHRvIDIsMTQ3LDQ4Myw2NDcgc2Vjb25kcyAoYWJvdXQgNjkgeWVhcnMpLiBEdXJpbmcgdGhhdCB0aW1lLCB0aGUgQW1hem9uIEVDUyBzZXJ2aWNlIHNjaGVkdWxlciBpZ25vcmVzIGhlYWx0aCBjaGVjayBzdGF0dXMuIFRoaXMgZ3JhY2UgcGVyaW9kIGNhbiBwcmV2ZW50IHRoZSBzZXJ2aWNlIHNjaGVkdWxlciBmcm9tIG1hcmtpbmcgdGFza3MgYXMgdW5oZWFsdGh5IGFuZCBzdG9wcGluZyB0aGVtIGJlZm9yZSB0aGV5IGhhdmUgdGltZSB0byBjb21lIHVwLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbCNjZm4tZWNzLXNlcnZpY2UtaGVhbHRoY2hlY2tncmFjZXBlcmlvZHNlY29uZHNcbiAgICAgKi9cbiAgICByZWFkb25seSBoZWFsdGhDaGVja0dyYWNlUGVyaW9kU2Vjb25kcz86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBsYXVuY2ggdHlwZSBvbiB3aGljaCB0byBydW4geW91ciBzZXJ2aWNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBbWF6b24gRUNTIExhdW5jaCBUeXBlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvbGF1bmNoX3R5cGVzLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1sYXVuY2h0eXBlXG4gICAgICovXG4gICAgcmVhZG9ubHkgbGF1bmNoVHlwZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiBsb2FkIGJhbGFuY2VyIG9iamVjdHMgdG8gYXNzb2NpYXRlIHdpdGggdGhlIHNlcnZpY2UuIElmIHlvdSBzcGVjaWZ5IHRoZSBgUm9sZWAgcHJvcGVydHksIGBMb2FkQmFsYW5jZXJzYCBtdXN0IGJlIHNwZWNpZmllZCBhcyB3ZWxsLiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG51bWJlciBvZiBsb2FkIGJhbGFuY2VycyB0aGF0IHlvdSBjYW4gc3BlY2lmeSBwZXIgc2VydmljZSwgc2VlIFtTZXJ2aWNlIExvYWQgQmFsYW5jaW5nXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zZXJ2aWNlLWxvYWQtYmFsYW5jaW5nLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1sb2FkYmFsYW5jZXJzXG4gICAgICovXG4gICAgcmVhZG9ubHkgbG9hZEJhbGFuY2Vycz86IEFycmF5PENmblNlcnZpY2UuTG9hZEJhbGFuY2VyUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5ldHdvcmsgY29uZmlndXJhdGlvbiBmb3IgdGhlIHNlcnZpY2UuIFRoaXMgcGFyYW1ldGVyIGlzIHJlcXVpcmVkIGZvciB0YXNrIGRlZmluaXRpb25zIHRoYXQgdXNlIHRoZSBgYXdzdnBjYCBuZXR3b3JrIG1vZGUgdG8gcmVjZWl2ZSB0aGVpciBvd24gZWxhc3RpYyBuZXR3b3JrIGludGVyZmFjZSwgYW5kIGl0IGlzIG5vdCBzdXBwb3J0ZWQgZm9yIG90aGVyIG5ldHdvcmsgbW9kZXMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1Rhc2sgTmV0d29ya2luZ10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvdGFzay1uZXR3b3JraW5nLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1uZXR3b3JrY29uZmlndXJhdGlvblxuICAgICAqL1xuICAgIHJlYWRvbmx5IG5ldHdvcmtDb25maWd1cmF0aW9uPzogQ2ZuU2VydmljZS5OZXR3b3JrQ29uZmlndXJhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogQW4gYXJyYXkgb2YgcGxhY2VtZW50IGNvbnN0cmFpbnQgb2JqZWN0cyB0byB1c2UgZm9yIHRhc2tzIGluIHlvdXIgc2VydmljZS4gWW91IGNhbiBzcGVjaWZ5IGEgbWF4aW11bSBvZiAxMCBjb25zdHJhaW50cyBmb3IgZWFjaCB0YXNrLiBUaGlzIGxpbWl0IGluY2x1ZGVzIGNvbnN0cmFpbnRzIGluIHRoZSB0YXNrIGRlZmluaXRpb24gYW5kIHRob3NlIHNwZWNpZmllZCBhdCBydW50aW1lLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbCNjZm4tZWNzLXNlcnZpY2UtcGxhY2VtZW50Y29uc3RyYWludHNcbiAgICAgKi9cbiAgICByZWFkb25seSBwbGFjZW1lbnRDb25zdHJhaW50cz86IEFycmF5PENmblNlcnZpY2UuUGxhY2VtZW50Q29uc3RyYWludFByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBwbGFjZW1lbnQgc3RyYXRlZ3kgb2JqZWN0cyB0byB1c2UgZm9yIHRhc2tzIGluIHlvdXIgc2VydmljZS4gWW91IGNhbiBzcGVjaWZ5IGEgbWF4aW11bSBvZiA1IHN0cmF0ZWd5IHJ1bGVzIGZvciBlYWNoIHNlcnZpY2UuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1wbGFjZW1lbnRzdHJhdGVnaWVzXG4gICAgICovXG4gICAgcmVhZG9ubHkgcGxhY2VtZW50U3RyYXRlZ2llcz86IEFycmF5PENmblNlcnZpY2UuUGxhY2VtZW50U3RyYXRlZ3lQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gdmVyc2lvbiB0aGF0IHlvdXIgdGFza3MgaW4gdGhlIHNlcnZpY2UgYXJlIHJ1bm5pbmcgb24uIEEgcGxhdGZvcm0gdmVyc2lvbiBpcyBzcGVjaWZpZWQgb25seSBmb3IgdGFza3MgdXNpbmcgdGhlIEZhcmdhdGUgbGF1bmNoIHR5cGUuIElmIG9uZSBpc24ndCBzcGVjaWZpZWQsIHRoZSBgTEFURVNUYCBwbGF0Zm9ybSB2ZXJzaW9uIGlzIHVzZWQuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0FXUyBGYXJnYXRlIHBsYXRmb3JtIHZlcnNpb25zXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9wbGF0Zm9ybV92ZXJzaW9ucy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbCNjZm4tZWNzLXNlcnZpY2UtcGxhdGZvcm12ZXJzaW9uXG4gICAgICovXG4gICAgcmVhZG9ubHkgcGxhdGZvcm1WZXJzaW9uPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogU3BlY2lmaWVzIHdoZXRoZXIgdG8gcHJvcGFnYXRlIHRoZSB0YWdzIGZyb20gdGhlIHRhc2sgZGVmaW5pdGlvbiB0byB0aGUgdGFzay4gSWYgbm8gdmFsdWUgaXMgc3BlY2lmaWVkLCB0aGUgdGFncyBhcmVuJ3QgcHJvcGFnYXRlZC4gVGFncyBjYW4gb25seSBiZSBwcm9wYWdhdGVkIHRvIHRoZSB0YXNrIGR1cmluZyB0YXNrIGNyZWF0aW9uLiBUbyBhZGQgdGFncyB0byBhIHRhc2sgYWZ0ZXIgdGFzayBjcmVhdGlvbiwgdXNlIHRoZSBbVGFnUmVzb3VyY2VdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVGFnUmVzb3VyY2UuaHRtbCkgQVBJIGFjdGlvbi5cbiAgICAgKlxuICAgICAqIFRoZSBkZWZhdWx0IGlzIGBOT05FYCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1wcm9wYWdhdGV0YWdzXG4gICAgICovXG4gICAgcmVhZG9ubHkgcHJvcGFnYXRlVGFncz86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9yIGZ1bGwgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIElBTSByb2xlIHRoYXQgYWxsb3dzIEFtYXpvbiBFQ1MgdG8gbWFrZSBjYWxscyB0byB5b3VyIGxvYWQgYmFsYW5jZXIgb24geW91ciBiZWhhbGYuIFRoaXMgcGFyYW1ldGVyIGlzIG9ubHkgcGVybWl0dGVkIGlmIHlvdSBhcmUgdXNpbmcgYSBsb2FkIGJhbGFuY2VyIHdpdGggeW91ciBzZXJ2aWNlIGFuZCB5b3VyIHRhc2sgZGVmaW5pdGlvbiBkb2Vzbid0IHVzZSB0aGUgYGF3c3ZwY2AgbmV0d29yayBtb2RlLiBJZiB5b3Ugc3BlY2lmeSB0aGUgYHJvbGVgIHBhcmFtZXRlciwgeW91IG11c3QgYWxzbyBzcGVjaWZ5IGEgbG9hZCBiYWxhbmNlciBvYmplY3Qgd2l0aCB0aGUgYGxvYWRCYWxhbmNlcnNgIHBhcmFtZXRlci5cbiAgICAgKlxuICAgICAqID4gSWYgeW91ciBhY2NvdW50IGhhcyBhbHJlYWR5IGNyZWF0ZWQgdGhlIEFtYXpvbiBFQ1Mgc2VydmljZS1saW5rZWQgcm9sZSwgdGhhdCByb2xlIGlzIHVzZWQgZm9yIHlvdXIgc2VydmljZSB1bmxlc3MgeW91IHNwZWNpZnkgYSByb2xlIGhlcmUuIFRoZSBzZXJ2aWNlLWxpbmtlZCByb2xlIGlzIHJlcXVpcmVkIGlmIHlvdXIgdGFzayBkZWZpbml0aW9uIHVzZXMgdGhlIGBhd3N2cGNgIG5ldHdvcmsgbW9kZSBvciBpZiB0aGUgc2VydmljZSBpcyBjb25maWd1cmVkIHRvIHVzZSBzZXJ2aWNlIGRpc2NvdmVyeSwgYW4gZXh0ZXJuYWwgZGVwbG95bWVudCBjb250cm9sbGVyLCBtdWx0aXBsZSB0YXJnZXQgZ3JvdXBzLCBvciBFbGFzdGljIEluZmVyZW5jZSBhY2NlbGVyYXRvcnMgaW4gd2hpY2ggY2FzZSB5b3UgZG9uJ3Qgc3BlY2lmeSBhIHJvbGUgaGVyZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbVXNpbmcgc2VydmljZS1saW5rZWQgcm9sZXMgZm9yIEFtYXpvbiBFQ1NdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3VzaW5nLXNlcnZpY2UtbGlua2VkLXJvbGVzLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBJZiB5b3VyIHNwZWNpZmllZCByb2xlIGhhcyBhIHBhdGggb3RoZXIgdGhhbiBgL2AgLCB0aGVuIHlvdSBtdXN0IGVpdGhlciBzcGVjaWZ5IHRoZSBmdWxsIHJvbGUgQVJOICh0aGlzIGlzIHJlY29tbWVuZGVkKSBvciBwcmVmaXggdGhlIHJvbGUgbmFtZSB3aXRoIHRoZSBwYXRoLiBGb3IgZXhhbXBsZSwgaWYgYSByb2xlIHdpdGggdGhlIG5hbWUgYGJhcmAgaGFzIGEgcGF0aCBvZiBgL2Zvby9gIHRoZW4geW91IHdvdWxkIHNwZWNpZnkgYC9mb28vYmFyYCBhcyB0aGUgcm9sZSBuYW1lLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtGcmllbmRseSBuYW1lcyBhbmQgcGF0aHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfaWRlbnRpZmllcnMuaHRtbCNpZGVudGlmaWVycy1mcmllbmRseS1uYW1lcykgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbCNjZm4tZWNzLXNlcnZpY2Utcm9sZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IHJvbGU/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc2NoZWR1bGluZyBzdHJhdGVneSB0byB1c2UgZm9yIHRoZSBzZXJ2aWNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtTZXJ2aWNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvZWNzX3NlcnZpY2VzLmh0bWwpIC5cbiAgICAgKlxuICAgICAqIFRoZXJlIGFyZSB0d28gc2VydmljZSBzY2hlZHVsZXIgc3RyYXRlZ2llcyBhdmFpbGFibGU6XG4gICAgICpcbiAgICAgKiAtIGBSRVBMSUNBYCAtVGhlIHJlcGxpY2Egc2NoZWR1bGluZyBzdHJhdGVneSBwbGFjZXMgYW5kIG1haW50YWlucyB0aGUgZGVzaXJlZCBudW1iZXIgb2YgdGFza3MgYWNyb3NzIHlvdXIgY2x1c3Rlci4gQnkgZGVmYXVsdCwgdGhlIHNlcnZpY2Ugc2NoZWR1bGVyIHNwcmVhZHMgdGFza3MgYWNyb3NzIEF2YWlsYWJpbGl0eSBab25lcy4gWW91IGNhbiB1c2UgdGFzayBwbGFjZW1lbnQgc3RyYXRlZ2llcyBhbmQgY29uc3RyYWludHMgdG8gY3VzdG9taXplIHRhc2sgcGxhY2VtZW50IGRlY2lzaW9ucy4gVGhpcyBzY2hlZHVsZXIgc3RyYXRlZ3kgaXMgcmVxdWlyZWQgaWYgdGhlIHNlcnZpY2UgdXNlcyB0aGUgYENPREVfREVQTE9ZYCBvciBgRVhURVJOQUxgIGRlcGxveW1lbnQgY29udHJvbGxlciB0eXBlcy5cbiAgICAgKiAtIGBEQUVNT05gIC1UaGUgZGFlbW9uIHNjaGVkdWxpbmcgc3RyYXRlZ3kgZGVwbG95cyBleGFjdGx5IG9uZSB0YXNrIG9uIGVhY2ggYWN0aXZlIGNvbnRhaW5lciBpbnN0YW5jZSB0aGF0IG1lZXRzIGFsbCBvZiB0aGUgdGFzayBwbGFjZW1lbnQgY29uc3RyYWludHMgdGhhdCB5b3Ugc3BlY2lmeSBpbiB5b3VyIGNsdXN0ZXIuIFRoZSBzZXJ2aWNlIHNjaGVkdWxlciBhbHNvIGV2YWx1YXRlcyB0aGUgdGFzayBwbGFjZW1lbnQgY29uc3RyYWludHMgZm9yIHJ1bm5pbmcgdGFza3MgYW5kIHdpbGwgc3RvcCB0YXNrcyB0aGF0IGRvbid0IG1lZXQgdGhlIHBsYWNlbWVudCBjb25zdHJhaW50cy4gV2hlbiB5b3UncmUgdXNpbmcgdGhpcyBzdHJhdGVneSwgeW91IGRvbid0IG5lZWQgdG8gc3BlY2lmeSBhIGRlc2lyZWQgbnVtYmVyIG9mIHRhc2tzLCBhIHRhc2sgcGxhY2VtZW50IHN0cmF0ZWd5LCBvciB1c2UgU2VydmljZSBBdXRvIFNjYWxpbmcgcG9saWNpZXMuXG4gICAgICpcbiAgICAgKiA+IFRhc2tzIHVzaW5nIHRoZSBGYXJnYXRlIGxhdW5jaCB0eXBlIG9yIHRoZSBgQ09ERV9ERVBMT1lgIG9yIGBFWFRFUk5BTGAgZGVwbG95bWVudCBjb250cm9sbGVyIHR5cGVzIGRvbid0IHN1cHBvcnQgdGhlIGBEQUVNT05gIHNjaGVkdWxpbmcgc3RyYXRlZ3kuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1zY2hlZHVsaW5nc3RyYXRlZ3lcbiAgICAgKi9cbiAgICByZWFkb25seSBzY2hlZHVsaW5nU3RyYXRlZ3k/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY29uZmlndXJhdGlvbiBmb3IgdGhpcyBzZXJ2aWNlIHRvIGRpc2NvdmVyIGFuZCBjb25uZWN0IHRvIHNlcnZpY2VzLCBhbmQgYmUgZGlzY292ZXJlZCBieSwgYW5kIGNvbm5lY3RlZCBmcm9tLCBvdGhlciBzZXJ2aWNlcyB3aXRoaW4gYSBuYW1lc3BhY2UuXG4gICAgICpcbiAgICAgKiBUYXNrcyB0aGF0IHJ1biBpbiBhIG5hbWVzcGFjZSBjYW4gdXNlIHNob3J0IG5hbWVzIHRvIGNvbm5lY3QgdG8gc2VydmljZXMgaW4gdGhlIG5hbWVzcGFjZS4gVGFza3MgY2FuIGNvbm5lY3QgdG8gc2VydmljZXMgYWNyb3NzIGFsbCBvZiB0aGUgY2x1c3RlcnMgaW4gdGhlIG5hbWVzcGFjZS4gVGFza3MgY29ubmVjdCB0aHJvdWdoIGEgbWFuYWdlZCBwcm94eSBjb250YWluZXIgdGhhdCBjb2xsZWN0cyBsb2dzIGFuZCBtZXRyaWNzIGZvciBpbmNyZWFzZWQgdmlzaWJpbGl0eS4gT25seSB0aGUgdGFza3MgdGhhdCBBbWF6b24gRUNTIHNlcnZpY2VzIGNyZWF0ZSBhcmUgc3VwcG9ydGVkIHdpdGggU2VydmljZSBDb25uZWN0LiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtTZXJ2aWNlIENvbm5lY3RdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3NlcnZpY2UtY29ubmVjdC5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbCNjZm4tZWNzLXNlcnZpY2Utc2VydmljZWNvbm5lY3Rjb25maWd1cmF0aW9uXG4gICAgICovXG4gICAgcmVhZG9ubHkgc2VydmljZUNvbm5lY3RDb25maWd1cmF0aW9uPzogQ2ZuU2VydmljZS5TZXJ2aWNlQ29ubmVjdENvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHlvdXIgc2VydmljZS4gVXAgdG8gMjU1IGxldHRlcnMgKHVwcGVyY2FzZSBhbmQgbG93ZXJjYXNlKSwgbnVtYmVycywgdW5kZXJzY29yZXMsIGFuZCBoeXBoZW5zIGFyZSBhbGxvd2VkLiBTZXJ2aWNlIG5hbWVzIG11c3QgYmUgdW5pcXVlIHdpdGhpbiBhIGNsdXN0ZXIsIGJ1dCB5b3UgY2FuIGhhdmUgc2ltaWxhcmx5IG5hbWVkIHNlcnZpY2VzIGluIG11bHRpcGxlIGNsdXN0ZXJzIHdpdGhpbiBhIFJlZ2lvbiBvciBhY3Jvc3MgbXVsdGlwbGUgUmVnaW9ucy5cbiAgICAgKlxuICAgICAqID4gVGhlIHN0YWNrIHVwZGF0ZSBmYWlscyBpZiB5b3UgY2hhbmdlIGFueSBwcm9wZXJ0aWVzIHRoYXQgcmVxdWlyZSByZXBsYWNlbWVudCBhbmQgdGhlIGBTZXJ2aWNlTmFtZWAgaXMgY29uZmlndXJlZC4gVGhpcyBpcyBiZWNhdXNlIEFXUyBDbG91ZEZvcm1hdGlvbiBjcmVhdGVzIHRoZSByZXBsYWNlbWVudCBzZXJ2aWNlIGZpcnN0LCBidXQgZWFjaCBgU2VydmljZU5hbWVgIG11c3QgYmUgdW5pcXVlIGluIHRoZSBjbHVzdGVyLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbCNjZm4tZWNzLXNlcnZpY2Utc2VydmljZW5hbWVcbiAgICAgKi9cbiAgICByZWFkb25seSBzZXJ2aWNlTmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBkZXRhaWxzIG9mIHRoZSBzZXJ2aWNlIGRpc2NvdmVyeSByZWdpc3RyeSB0byBhc3NvY2lhdGUgd2l0aCB0aGlzIHNlcnZpY2UuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1NlcnZpY2UgZGlzY292ZXJ5XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zZXJ2aWNlLWRpc2NvdmVyeS5odG1sKSAuXG4gICAgICpcbiAgICAgKiA+IEVhY2ggc2VydmljZSBtYXkgYmUgYXNzb2NpYXRlZCB3aXRoIG9uZSBzZXJ2aWNlIHJlZ2lzdHJ5LiBNdWx0aXBsZSBzZXJ2aWNlIHJlZ2lzdHJpZXMgZm9yIGVhY2ggc2VydmljZSBpc24ndCBzdXBwb3J0ZWQuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1zZXJ2aWNlcmVnaXN0cmllc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IHNlcnZpY2VSZWdpc3RyaWVzPzogQXJyYXk8Q2ZuU2VydmljZS5TZXJ2aWNlUmVnaXN0cnlQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWV0YWRhdGEgdGhhdCB5b3UgYXBwbHkgdG8gdGhlIHNlcnZpY2UgdG8gaGVscCB5b3UgY2F0ZWdvcml6ZSBhbmQgb3JnYW5pemUgdGhlbS4gRWFjaCB0YWcgY29uc2lzdHMgb2YgYSBrZXkgYW5kIGFuIG9wdGlvbmFsIHZhbHVlLCBib3RoIG9mIHdoaWNoIHlvdSBkZWZpbmUuIFdoZW4gYSBzZXJ2aWNlIGlzIGRlbGV0ZWQsIHRoZSB0YWdzIGFyZSBkZWxldGVkIGFzIHdlbGwuXG4gICAgICpcbiAgICAgKiBUaGUgZm9sbG93aW5nIGJhc2ljIHJlc3RyaWN0aW9ucyBhcHBseSB0byB0YWdzOlxuICAgICAqXG4gICAgICogLSBNYXhpbXVtIG51bWJlciBvZiB0YWdzIHBlciByZXNvdXJjZSAtIDUwXG4gICAgICogLSBGb3IgZWFjaCByZXNvdXJjZSwgZWFjaCB0YWcga2V5IG11c3QgYmUgdW5pcXVlLCBhbmQgZWFjaCB0YWcga2V5IGNhbiBoYXZlIG9ubHkgb25lIHZhbHVlLlxuICAgICAqIC0gTWF4aW11bSBrZXkgbGVuZ3RoIC0gMTI4IFVuaWNvZGUgY2hhcmFjdGVycyBpbiBVVEYtOFxuICAgICAqIC0gTWF4aW11bSB2YWx1ZSBsZW5ndGggLSAyNTYgVW5pY29kZSBjaGFyYWN0ZXJzIGluIFVURi04XG4gICAgICogLSBJZiB5b3VyIHRhZ2dpbmcgc2NoZW1hIGlzIHVzZWQgYWNyb3NzIG11bHRpcGxlIHNlcnZpY2VzIGFuZCByZXNvdXJjZXMsIHJlbWVtYmVyIHRoYXQgb3RoZXIgc2VydmljZXMgbWF5IGhhdmUgcmVzdHJpY3Rpb25zIG9uIGFsbG93ZWQgY2hhcmFjdGVycy4gR2VuZXJhbGx5IGFsbG93ZWQgY2hhcmFjdGVycyBhcmU6IGxldHRlcnMsIG51bWJlcnMsIGFuZCBzcGFjZXMgcmVwcmVzZW50YWJsZSBpbiBVVEYtOCwgYW5kIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogKyAtID0gLiBfIDogLyBALlxuICAgICAqIC0gVGFnIGtleXMgYW5kIHZhbHVlcyBhcmUgY2FzZS1zZW5zaXRpdmUuXG4gICAgICogLSBEbyBub3QgdXNlIGBhd3M6YCAsIGBBV1M6YCAsIG9yIGFueSB1cHBlciBvciBsb3dlcmNhc2UgY29tYmluYXRpb24gb2Ygc3VjaCBhcyBhIHByZWZpeCBmb3IgZWl0aGVyIGtleXMgb3IgdmFsdWVzIGFzIGl0IGlzIHJlc2VydmVkIGZvciBBV1MgdXNlLiBZb3UgY2Fubm90IGVkaXQgb3IgZGVsZXRlIHRhZyBrZXlzIG9yIHZhbHVlcyB3aXRoIHRoaXMgcHJlZml4LiBUYWdzIHdpdGggdGhpcyBwcmVmaXggZG8gbm90IGNvdW50IGFnYWluc3QgeW91ciB0YWdzIHBlciByZXNvdXJjZSBsaW1pdC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1zZXJ2aWNlLmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLXRhZ3NcbiAgICAgKi9cbiAgICByZWFkb25seSB0YWdzPzogY2RrLkNmblRhZ1tdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGBmYW1pbHlgIGFuZCBgcmV2aXNpb25gICggYGZhbWlseTpyZXZpc2lvbmAgKSBvciBmdWxsIEFSTiBvZiB0aGUgdGFzayBkZWZpbml0aW9uIHRvIHJ1biBpbiB5b3VyIHNlcnZpY2UuIElmIGEgYHJldmlzaW9uYCBpc24ndCBzcGVjaWZpZWQsIHRoZSBsYXRlc3QgYEFDVElWRWAgcmV2aXNpb24gaXMgdXNlZC5cbiAgICAgKlxuICAgICAqIEEgdGFzayBkZWZpbml0aW9uIG11c3QgYmUgc3BlY2lmaWVkIGlmIHRoZSBzZXJ2aWNlIHVzZXMgZWl0aGVyIHRoZSBgRUNTYCBvciBgQ09ERV9ERVBMT1lgIGRlcGxveW1lbnQgY29udHJvbGxlcnMuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBkZXBsb3ltZW50IHR5cGVzLCBzZWUgW0FtYXpvbiBFQ1MgZGVwbG95bWVudCB0eXBlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvZGVwbG95bWVudC10eXBlcy5odG1sKSAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS10YXNrZGVmaW5pdGlvblxuICAgICAqL1xuICAgIHJlYWRvbmx5IHRhc2tEZWZpbml0aW9uPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmblNlcnZpY2VQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuU2VydmljZVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblNlcnZpY2VQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NhcGFjaXR5UHJvdmlkZXJTdHJhdGVneScsIGNkay5saXN0VmFsaWRhdG9yKENmblNlcnZpY2VfQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5SXRlbVByb3BlcnR5VmFsaWRhdG9yKSkocHJvcGVydGllcy5jYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3kpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NsdXN0ZXInLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY2x1c3RlcikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZGVwbG95bWVudENvbmZpZ3VyYXRpb24nLCBDZm5TZXJ2aWNlX0RlcGxveW1lbnRDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IpKHByb3BlcnRpZXMuZGVwbG95bWVudENvbmZpZ3VyYXRpb24pKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2RlcGxveW1lbnRDb250cm9sbGVyJywgQ2ZuU2VydmljZV9EZXBsb3ltZW50Q29udHJvbGxlclByb3BlcnR5VmFsaWRhdG9yKShwcm9wZXJ0aWVzLmRlcGxveW1lbnRDb250cm9sbGVyKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdkZXNpcmVkQ291bnQnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMuZGVzaXJlZENvdW50KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdlbmFibGVFY3NNYW5hZ2VkVGFncycsIGNkay52YWxpZGF0ZUJvb2xlYW4pKHByb3BlcnRpZXMuZW5hYmxlRWNzTWFuYWdlZFRhZ3MpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2VuYWJsZUV4ZWN1dGVDb21tYW5kJywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5lbmFibGVFeGVjdXRlQ29tbWFuZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaGVhbHRoQ2hlY2tHcmFjZVBlcmlvZFNlY29uZHMnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMuaGVhbHRoQ2hlY2tHcmFjZVBlcmlvZFNlY29uZHMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2xhdW5jaFR5cGUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMubGF1bmNoVHlwZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbG9hZEJhbGFuY2VycycsIGNkay5saXN0VmFsaWRhdG9yKENmblNlcnZpY2VfTG9hZEJhbGFuY2VyUHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLmxvYWRCYWxhbmNlcnMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ25ldHdvcmtDb25maWd1cmF0aW9uJywgQ2ZuU2VydmljZV9OZXR3b3JrQ29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKShwcm9wZXJ0aWVzLm5ldHdvcmtDb25maWd1cmF0aW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwbGFjZW1lbnRDb25zdHJhaW50cycsIGNkay5saXN0VmFsaWRhdG9yKENmblNlcnZpY2VfUGxhY2VtZW50Q29uc3RyYWludFByb3BlcnR5VmFsaWRhdG9yKSkocHJvcGVydGllcy5wbGFjZW1lbnRDb25zdHJhaW50cykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncGxhY2VtZW50U3RyYXRlZ2llcycsIGNkay5saXN0VmFsaWRhdG9yKENmblNlcnZpY2VfUGxhY2VtZW50U3RyYXRlZ3lQcm9wZXJ0eVZhbGlkYXRvcikpKHByb3BlcnRpZXMucGxhY2VtZW50U3RyYXRlZ2llcykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncGxhdGZvcm1WZXJzaW9uJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnBsYXRmb3JtVmVyc2lvbikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncHJvcGFnYXRlVGFncycsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5wcm9wYWdhdGVUYWdzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyb2xlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnJvbGUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3NjaGVkdWxpbmdTdHJhdGVneScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5zY2hlZHVsaW5nU3RyYXRlZ3kpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3NlcnZpY2VDb25uZWN0Q29uZmlndXJhdGlvbicsIENmblNlcnZpY2VfU2VydmljZUNvbm5lY3RDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IpKHByb3BlcnRpZXMuc2VydmljZUNvbm5lY3RDb25maWd1cmF0aW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzZXJ2aWNlTmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5zZXJ2aWNlTmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc2VydmljZVJlZ2lzdHJpZXMnLCBjZGsubGlzdFZhbGlkYXRvcihDZm5TZXJ2aWNlX1NlcnZpY2VSZWdpc3RyeVByb3BlcnR5VmFsaWRhdG9yKSkocHJvcGVydGllcy5zZXJ2aWNlUmVnaXN0cmllcykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndGFncycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZUNmblRhZykpKHByb3BlcnRpZXMudGFncykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndGFza0RlZmluaXRpb24nLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMudGFza0RlZmluaXRpb24pKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuU2VydmljZVByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlNlcnZpY2VgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblNlcnZpY2VQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpTZXJ2aWNlYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblNlcnZpY2VQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuU2VydmljZVByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3k6IGNkay5saXN0TWFwcGVyKGNmblNlcnZpY2VDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3lJdGVtUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLmNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneSksXG4gICAgICAgIENsdXN0ZXI6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY2x1c3RlciksXG4gICAgICAgIERlcGxveW1lbnRDb25maWd1cmF0aW9uOiBjZm5TZXJ2aWNlRGVwbG95bWVudENvbmZpZ3VyYXRpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5kZXBsb3ltZW50Q29uZmlndXJhdGlvbiksXG4gICAgICAgIERlcGxveW1lbnRDb250cm9sbGVyOiBjZm5TZXJ2aWNlRGVwbG95bWVudENvbnRyb2xsZXJQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5kZXBsb3ltZW50Q29udHJvbGxlciksXG4gICAgICAgIERlc2lyZWRDb3VudDogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5kZXNpcmVkQ291bnQpLFxuICAgICAgICBFbmFibGVFQ1NNYW5hZ2VkVGFnczogY2RrLmJvb2xlYW5Ub0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZW5hYmxlRWNzTWFuYWdlZFRhZ3MpLFxuICAgICAgICBFbmFibGVFeGVjdXRlQ29tbWFuZDogY2RrLmJvb2xlYW5Ub0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZW5hYmxlRXhlY3V0ZUNvbW1hbmQpLFxuICAgICAgICBIZWFsdGhDaGVja0dyYWNlUGVyaW9kU2Vjb25kczogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5oZWFsdGhDaGVja0dyYWNlUGVyaW9kU2Vjb25kcyksXG4gICAgICAgIExhdW5jaFR5cGU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubGF1bmNoVHlwZSksXG4gICAgICAgIExvYWRCYWxhbmNlcnM6IGNkay5saXN0TWFwcGVyKGNmblNlcnZpY2VMb2FkQmFsYW5jZXJQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMubG9hZEJhbGFuY2VycyksXG4gICAgICAgIE5ldHdvcmtDb25maWd1cmF0aW9uOiBjZm5TZXJ2aWNlTmV0d29ya0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5uZXR3b3JrQ29uZmlndXJhdGlvbiksXG4gICAgICAgIFBsYWNlbWVudENvbnN0cmFpbnRzOiBjZGsubGlzdE1hcHBlcihjZm5TZXJ2aWNlUGxhY2VtZW50Q29uc3RyYWludFByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5wbGFjZW1lbnRDb25zdHJhaW50cyksXG4gICAgICAgIFBsYWNlbWVudFN0cmF0ZWdpZXM6IGNkay5saXN0TWFwcGVyKGNmblNlcnZpY2VQbGFjZW1lbnRTdHJhdGVneVByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5wbGFjZW1lbnRTdHJhdGVnaWVzKSxcbiAgICAgICAgUGxhdGZvcm1WZXJzaW9uOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBsYXRmb3JtVmVyc2lvbiksXG4gICAgICAgIFByb3BhZ2F0ZVRhZ3M6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucHJvcGFnYXRlVGFncyksXG4gICAgICAgIFJvbGU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucm9sZSksXG4gICAgICAgIFNjaGVkdWxpbmdTdHJhdGVneTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zY2hlZHVsaW5nU3RyYXRlZ3kpLFxuICAgICAgICBTZXJ2aWNlQ29ubmVjdENvbmZpZ3VyYXRpb246IGNmblNlcnZpY2VTZXJ2aWNlQ29ubmVjdENvbmZpZ3VyYXRpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zZXJ2aWNlQ29ubmVjdENvbmZpZ3VyYXRpb24pLFxuICAgICAgICBTZXJ2aWNlTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zZXJ2aWNlTmFtZSksXG4gICAgICAgIFNlcnZpY2VSZWdpc3RyaWVzOiBjZGsubGlzdE1hcHBlcihjZm5TZXJ2aWNlU2VydmljZVJlZ2lzdHJ5UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnNlcnZpY2VSZWdpc3RyaWVzKSxcbiAgICAgICAgVGFnczogY2RrLmxpc3RNYXBwZXIoY2RrLmNmblRhZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMudGFncyksXG4gICAgICAgIFRhc2tEZWZpbml0aW9uOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnRhc2tEZWZpbml0aW9uKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuU2VydmljZVByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuU2VydmljZVByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5TZXJ2aWNlUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3knLCAnQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5JywgcHJvcGVydGllcy5DYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3kgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoQ2ZuU2VydmljZUNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneUl0ZW1Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5DYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3kpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2NsdXN0ZXInLCAnQ2x1c3RlcicsIHByb3BlcnRpZXMuQ2x1c3RlciAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5DbHVzdGVyKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdkZXBsb3ltZW50Q29uZmlndXJhdGlvbicsICdEZXBsb3ltZW50Q29uZmlndXJhdGlvbicsIHByb3BlcnRpZXMuRGVwbG95bWVudENvbmZpZ3VyYXRpb24gIT0gbnVsbCA/IENmblNlcnZpY2VEZXBsb3ltZW50Q29uZmlndXJhdGlvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuRGVwbG95bWVudENvbmZpZ3VyYXRpb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2RlcGxveW1lbnRDb250cm9sbGVyJywgJ0RlcGxveW1lbnRDb250cm9sbGVyJywgcHJvcGVydGllcy5EZXBsb3ltZW50Q29udHJvbGxlciAhPSBudWxsID8gQ2ZuU2VydmljZURlcGxveW1lbnRDb250cm9sbGVyUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5EZXBsb3ltZW50Q29udHJvbGxlcikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZGVzaXJlZENvdW50JywgJ0Rlc2lyZWRDb3VudCcsIHByb3BlcnRpZXMuRGVzaXJlZENvdW50ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLkRlc2lyZWRDb3VudCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZW5hYmxlRWNzTWFuYWdlZFRhZ3MnLCAnRW5hYmxlRUNTTWFuYWdlZFRhZ3MnLCBwcm9wZXJ0aWVzLkVuYWJsZUVDU01hbmFnZWRUYWdzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5FbmFibGVFQ1NNYW5hZ2VkVGFncykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZW5hYmxlRXhlY3V0ZUNvbW1hbmQnLCAnRW5hYmxlRXhlY3V0ZUNvbW1hbmQnLCBwcm9wZXJ0aWVzLkVuYWJsZUV4ZWN1dGVDb21tYW5kICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5FbmFibGVFeGVjdXRlQ29tbWFuZCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaGVhbHRoQ2hlY2tHcmFjZVBlcmlvZFNlY29uZHMnLCAnSGVhbHRoQ2hlY2tHcmFjZVBlcmlvZFNlY29uZHMnLCBwcm9wZXJ0aWVzLkhlYWx0aENoZWNrR3JhY2VQZXJpb2RTZWNvbmRzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLkhlYWx0aENoZWNrR3JhY2VQZXJpb2RTZWNvbmRzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdsYXVuY2hUeXBlJywgJ0xhdW5jaFR5cGUnLCBwcm9wZXJ0aWVzLkxhdW5jaFR5cGUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuTGF1bmNoVHlwZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbG9hZEJhbGFuY2VycycsICdMb2FkQmFsYW5jZXJzJywgcHJvcGVydGllcy5Mb2FkQmFsYW5jZXJzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KENmblNlcnZpY2VMb2FkQmFsYW5jZXJQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5Mb2FkQmFsYW5jZXJzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCduZXR3b3JrQ29uZmlndXJhdGlvbicsICdOZXR3b3JrQ29uZmlndXJhdGlvbicsIHByb3BlcnRpZXMuTmV0d29ya0NvbmZpZ3VyYXRpb24gIT0gbnVsbCA/IENmblNlcnZpY2VOZXR3b3JrQ29uZmlndXJhdGlvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuTmV0d29ya0NvbmZpZ3VyYXRpb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BsYWNlbWVudENvbnN0cmFpbnRzJywgJ1BsYWNlbWVudENvbnN0cmFpbnRzJywgcHJvcGVydGllcy5QbGFjZW1lbnRDb25zdHJhaW50cyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5TZXJ2aWNlUGxhY2VtZW50Q29uc3RyYWludFByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLlBsYWNlbWVudENvbnN0cmFpbnRzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwbGFjZW1lbnRTdHJhdGVnaWVzJywgJ1BsYWNlbWVudFN0cmF0ZWdpZXMnLCBwcm9wZXJ0aWVzLlBsYWNlbWVudFN0cmF0ZWdpZXMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoQ2ZuU2VydmljZVBsYWNlbWVudFN0cmF0ZWd5UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuUGxhY2VtZW50U3RyYXRlZ2llcykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncGxhdGZvcm1WZXJzaW9uJywgJ1BsYXRmb3JtVmVyc2lvbicsIHByb3BlcnRpZXMuUGxhdGZvcm1WZXJzaW9uICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlBsYXRmb3JtVmVyc2lvbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncHJvcGFnYXRlVGFncycsICdQcm9wYWdhdGVUYWdzJywgcHJvcGVydGllcy5Qcm9wYWdhdGVUYWdzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlByb3BhZ2F0ZVRhZ3MpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3JvbGUnLCAnUm9sZScsIHByb3BlcnRpZXMuUm9sZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Sb2xlKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzY2hlZHVsaW5nU3RyYXRlZ3knLCAnU2NoZWR1bGluZ1N0cmF0ZWd5JywgcHJvcGVydGllcy5TY2hlZHVsaW5nU3RyYXRlZ3kgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuU2NoZWR1bGluZ1N0cmF0ZWd5KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzZXJ2aWNlQ29ubmVjdENvbmZpZ3VyYXRpb24nLCAnU2VydmljZUNvbm5lY3RDb25maWd1cmF0aW9uJywgcHJvcGVydGllcy5TZXJ2aWNlQ29ubmVjdENvbmZpZ3VyYXRpb24gIT0gbnVsbCA/IENmblNlcnZpY2VTZXJ2aWNlQ29ubmVjdENvbmZpZ3VyYXRpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLlNlcnZpY2VDb25uZWN0Q29uZmlndXJhdGlvbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnc2VydmljZU5hbWUnLCAnU2VydmljZU5hbWUnLCBwcm9wZXJ0aWVzLlNlcnZpY2VOYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlNlcnZpY2VOYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzZXJ2aWNlUmVnaXN0cmllcycsICdTZXJ2aWNlUmVnaXN0cmllcycsIHByb3BlcnRpZXMuU2VydmljZVJlZ2lzdHJpZXMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoQ2ZuU2VydmljZVNlcnZpY2VSZWdpc3RyeVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLlNlcnZpY2VSZWdpc3RyaWVzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0YWdzJywgJ1RhZ3MnLCBwcm9wZXJ0aWVzLlRhZ3MgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRDZm5UYWcpKHByb3BlcnRpZXMuVGFncykgOiB1bmRlZmluZWQgYXMgYW55KTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3Rhc2tEZWZpbml0aW9uJywgJ1Rhc2tEZWZpbml0aW9uJywgcHJvcGVydGllcy5UYXNrRGVmaW5pdGlvbiAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5UYXNrRGVmaW5pdGlvbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6RUNTOjpTZXJ2aWNlYFxuICpcbiAqIFRoZSBgQVdTOjpFQ1M6OlNlcnZpY2VgIHJlc291cmNlIGNyZWF0ZXMgYW4gQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgKEFtYXpvbiBFQ1MpIHNlcnZpY2UgdGhhdCBydW5zIGFuZCBtYWludGFpbnMgdGhlIHJlcXVlc3RlZCBudW1iZXIgb2YgdGFza3MgYW5kIGFzc29jaWF0ZWQgbG9hZCBiYWxhbmNlcnMuXG4gKlxuICogPiBUaGUgc3RhY2sgdXBkYXRlIGZhaWxzIGlmIHlvdSBjaGFuZ2UgYW55IHByb3BlcnRpZXMgdGhhdCByZXF1aXJlIHJlcGxhY2VtZW50IGFuZCBhdCBsZWFzdCBvbmUgQW1hem9uIEVDUyBTZXJ2aWNlIENvbm5lY3QgYFNlcnZpY2VDb25uZWN0U2VydmljZWAgaXMgY29uZmlndXJlZC4gVGhpcyBpcyBiZWNhdXNlIEFXUyBDbG91ZEZvcm1hdGlvbiBjcmVhdGVzIHRoZSByZXBsYWNlbWVudCBzZXJ2aWNlIGZpcnN0LCBidXQgZWFjaCBgU2VydmljZUNvbm5lY3RTZXJ2aWNlYCBtdXN0IGhhdmUgYSBuYW1lIHRoYXQgaXMgdW5pcXVlIGluIHRoZSBuYW1lc3BhY2UuID4gU3RhcnRpbmcgQXByaWwgMTUsIDIwMjMsIEFXUyA7IHdpbGwgbm90IG9uYm9hcmQgbmV3IGN1c3RvbWVycyB0byBBbWF6b24gRWxhc3RpYyBJbmZlcmVuY2UgKEVJKSwgYW5kIHdpbGwgaGVscCBjdXJyZW50IGN1c3RvbWVycyBtaWdyYXRlIHRoZWlyIHdvcmtsb2FkcyB0byBvcHRpb25zIHRoYXQgb2ZmZXIgYmV0dGVyIHByaWNlIGFuZCBwZXJmb3JtYW5jZS4gQWZ0ZXIgQXByaWwgMTUsIDIwMjMsIG5ldyBjdXN0b21lcnMgd2lsbCBub3QgYmUgYWJsZSB0byBsYXVuY2ggaW5zdGFuY2VzIHdpdGggQW1hem9uIEVJIGFjY2VsZXJhdG9ycyBpbiBBbWF6b24gU2FnZU1ha2VyLCBBbWF6b24gRUNTICwgb3IgQW1hem9uIEVDMiAuIEhvd2V2ZXIsIGN1c3RvbWVycyB3aG8gaGF2ZSB1c2VkIEFtYXpvbiBFSSBhdCBsZWFzdCBvbmNlIGR1cmluZyB0aGUgcGFzdCAzMC1kYXkgcGVyaW9kIGFyZSBjb25zaWRlcmVkIGN1cnJlbnQgY3VzdG9tZXJzIGFuZCB3aWxsIGJlIGFibGUgdG8gY29udGludWUgdXNpbmcgdGhlIHNlcnZpY2UuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpFQ1M6OlNlcnZpY2VcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5TZXJ2aWNlIGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6RUNTOjpTZXJ2aWNlXCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5TZXJ2aWNlIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5TZXJ2aWNlUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmblNlcnZpY2Uoc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIEFtYXpvbiBFQ1Mgc2VydmljZSwgc3VjaCBhcyBgc2FtcGxlLXdlYmFwcGAgLlxuICAgICAqIEBjbG91ZGZvcm1hdGlvbkF0dHJpYnV0ZSBOYW1lXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGF0dHJOYW1lOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBOb3QgY3VycmVudGx5IHN1cHBvcnRlZCBpbiBBV1MgQ2xvdWRGb3JtYXRpb24gLlxuICAgICAqIEBjbG91ZGZvcm1hdGlvbkF0dHJpYnV0ZSBTZXJ2aWNlQXJuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGF0dHJTZXJ2aWNlQXJuOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2FwYWNpdHkgcHJvdmlkZXIgc3RyYXRlZ3kgdG8gdXNlIGZvciB0aGUgc2VydmljZS5cbiAgICAgKlxuICAgICAqIElmIGEgYGNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneWAgaXMgc3BlY2lmaWVkLCB0aGUgYGxhdW5jaFR5cGVgIHBhcmFtZXRlciBtdXN0IGJlIG9taXR0ZWQuIElmIG5vIGBjYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3lgIG9yIGBsYXVuY2hUeXBlYCBpcyBzcGVjaWZpZWQsIHRoZSBgZGVmYXVsdENhcGFjaXR5UHJvdmlkZXJTdHJhdGVneWAgZm9yIHRoZSBjbHVzdGVyIGlzIHVzZWQuXG4gICAgICpcbiAgICAgKiBBIGNhcGFjaXR5IHByb3ZpZGVyIHN0cmF0ZWd5IG1heSBjb250YWluIGEgbWF4aW11bSBvZiA2IGNhcGFjaXR5IHByb3ZpZGVycy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1zZXJ2aWNlLmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLWNhcGFjaXR5cHJvdmlkZXJzdHJhdGVneVxuICAgICAqL1xuICAgIHB1YmxpYyBjYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3k6IEFycmF5PENmblNlcnZpY2UuQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5SXRlbVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBzaG9ydCBuYW1lIG9yIGZ1bGwgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIGNsdXN0ZXIgdGhhdCB5b3UgcnVuIHlvdXIgc2VydmljZSBvbi4gSWYgeW91IGRvIG5vdCBzcGVjaWZ5IGEgY2x1c3RlciwgdGhlIGRlZmF1bHQgY2x1c3RlciBpcyBhc3N1bWVkLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbCNjZm4tZWNzLXNlcnZpY2UtY2x1c3RlclxuICAgICAqL1xuICAgIHB1YmxpYyBjbHVzdGVyOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBPcHRpb25hbCBkZXBsb3ltZW50IHBhcmFtZXRlcnMgdGhhdCBjb250cm9sIGhvdyBtYW55IHRhc2tzIHJ1biBkdXJpbmcgdGhlIGRlcGxveW1lbnQgYW5kIHRoZSBvcmRlcmluZyBvZiBzdG9wcGluZyBhbmQgc3RhcnRpbmcgdGFza3MuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1kZXBsb3ltZW50Y29uZmlndXJhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBkZXBsb3ltZW50Q29uZmlndXJhdGlvbjogQ2ZuU2VydmljZS5EZXBsb3ltZW50Q29uZmlndXJhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGRlcGxveW1lbnQgY29udHJvbGxlciB0byB1c2UgZm9yIHRoZSBzZXJ2aWNlLiBJZiBubyBkZXBsb3ltZW50IGNvbnRyb2xsZXIgaXMgc3BlY2lmaWVkLCB0aGUgZGVmYXVsdCB2YWx1ZSBvZiBgRUNTYCBpcyB1c2VkLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbCNjZm4tZWNzLXNlcnZpY2UtZGVwbG95bWVudGNvbnRyb2xsZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgZGVwbG95bWVudENvbnRyb2xsZXI6IENmblNlcnZpY2UuRGVwbG95bWVudENvbnRyb2xsZXJQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgaW5zdGFudGlhdGlvbnMgb2YgdGhlIHNwZWNpZmllZCB0YXNrIGRlZmluaXRpb24gdG8gcGxhY2UgYW5kIGtlZXAgcnVubmluZyBpbiB5b3VyIHNlcnZpY2UuXG4gICAgICpcbiAgICAgKiBGb3IgbmV3IHNlcnZpY2VzLCBpZiBhIGRlc2lyZWQgY291bnQgaXMgbm90IHNwZWNpZmllZCwgYSBkZWZhdWx0IHZhbHVlIG9mIGAxYCBpcyB1c2VkLiBXaGVuIHVzaW5nIHRoZSBgREFFTU9OYCBzY2hlZHVsaW5nIHN0cmF0ZWd5LCB0aGUgZGVzaXJlZCBjb3VudCBpcyBub3QgcmVxdWlyZWQuXG4gICAgICpcbiAgICAgKiBGb3IgZXhpc3Rpbmcgc2VydmljZXMsIGlmIGEgZGVzaXJlZCBjb3VudCBpcyBub3Qgc3BlY2lmaWVkLCBpdCBpcyBvbWl0dGVkIGZyb20gdGhlIG9wZXJhdGlvbi5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1zZXJ2aWNlLmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLWRlc2lyZWRjb3VudFxuICAgICAqL1xuICAgIHB1YmxpYyBkZXNpcmVkQ291bnQ6IG51bWJlciB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFNwZWNpZmllcyB3aGV0aGVyIHRvIHR1cm4gb24gQW1hem9uIEVDUyBtYW5hZ2VkIHRhZ3MgZm9yIHRoZSB0YXNrcyB3aXRoaW4gdGhlIHNlcnZpY2UuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1RhZ2dpbmcgeW91ciBBbWF6b24gRUNTIHJlc291cmNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvZWNzLXVzaW5nLXRhZ3MuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIFdoZW4geW91IHVzZSBBbWF6b24gRUNTIG1hbmFnZWQgdGFncywgeW91IG5lZWQgdG8gc2V0IHRoZSBgcHJvcGFnYXRlVGFnc2AgcmVxdWVzdCBwYXJhbWV0ZXIuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1lbmFibGVlY3NtYW5hZ2VkdGFnc1xuICAgICAqL1xuICAgIHB1YmxpYyBlbmFibGVFY3NNYW5hZ2VkVGFnczogYm9vbGVhbiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGUgZXhlY3V0ZSBjb21tYW5kIGZ1bmN0aW9uYWxpdHkgaXMgdHVybmVkIG9uIGZvciB0aGUgc2VydmljZS4gSWYgYHRydWVgICwgdGhlIGV4ZWN1dGUgY29tbWFuZCBmdW5jdGlvbmFsaXR5IGlzIHR1cm5lZCBvbiBmb3IgYWxsIGNvbnRhaW5lcnMgaW4gdGFza3MgYXMgcGFydCBvZiB0aGUgc2VydmljZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1zZXJ2aWNlLmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLWVuYWJsZWV4ZWN1dGVjb21tYW5kXG4gICAgICovXG4gICAgcHVibGljIGVuYWJsZUV4ZWN1dGVDb21tYW5kOiBib29sZWFuIHwgY2RrLklSZXNvbHZhYmxlIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBlcmlvZCBvZiB0aW1lLCBpbiBzZWNvbmRzLCB0aGF0IHRoZSBBbWF6b24gRUNTIHNlcnZpY2Ugc2NoZWR1bGVyIGlnbm9yZXMgdW5oZWFsdGh5IEVsYXN0aWMgTG9hZCBCYWxhbmNpbmcgdGFyZ2V0IGhlYWx0aCBjaGVja3MgYWZ0ZXIgYSB0YXNrIGhhcyBmaXJzdCBzdGFydGVkLiBUaGlzIGlzIG9ubHkgdXNlZCB3aGVuIHlvdXIgc2VydmljZSBpcyBjb25maWd1cmVkIHRvIHVzZSBhIGxvYWQgYmFsYW5jZXIuIElmIHlvdXIgc2VydmljZSBoYXMgYSBsb2FkIGJhbGFuY2VyIGRlZmluZWQgYW5kIHlvdSBkb24ndCBzcGVjaWZ5IGEgaGVhbHRoIGNoZWNrIGdyYWNlIHBlcmlvZCB2YWx1ZSwgdGhlIGRlZmF1bHQgdmFsdWUgb2YgYDBgIGlzIHVzZWQuXG4gICAgICpcbiAgICAgKiBJZiB5b3UgZG8gbm90IHVzZSBhbiBFbGFzdGljIExvYWQgQmFsYW5jaW5nLCB3ZSByZWNvbW1lbmQgdGhhdCB5b3UgdXNlIHRoZSBgc3RhcnRQZXJpb2RgIGluIHRoZSB0YXNrIGRlZmluaXRpb24gaGVhbHRoIGNoZWNrIHBhcmFtZXRlcnMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0hlYWx0aCBjaGVja10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9IZWFsdGhDaGVjay5odG1sKSAuXG4gICAgICpcbiAgICAgKiBJZiB5b3VyIHNlcnZpY2UncyB0YXNrcyB0YWtlIGEgd2hpbGUgdG8gc3RhcnQgYW5kIHJlc3BvbmQgdG8gRWxhc3RpYyBMb2FkIEJhbGFuY2luZyBoZWFsdGggY2hlY2tzLCB5b3UgY2FuIHNwZWNpZnkgYSBoZWFsdGggY2hlY2sgZ3JhY2UgcGVyaW9kIG9mIHVwIHRvIDIsMTQ3LDQ4Myw2NDcgc2Vjb25kcyAoYWJvdXQgNjkgeWVhcnMpLiBEdXJpbmcgdGhhdCB0aW1lLCB0aGUgQW1hem9uIEVDUyBzZXJ2aWNlIHNjaGVkdWxlciBpZ25vcmVzIGhlYWx0aCBjaGVjayBzdGF0dXMuIFRoaXMgZ3JhY2UgcGVyaW9kIGNhbiBwcmV2ZW50IHRoZSBzZXJ2aWNlIHNjaGVkdWxlciBmcm9tIG1hcmtpbmcgdGFza3MgYXMgdW5oZWFsdGh5IGFuZCBzdG9wcGluZyB0aGVtIGJlZm9yZSB0aGV5IGhhdmUgdGltZSB0byBjb21lIHVwLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbCNjZm4tZWNzLXNlcnZpY2UtaGVhbHRoY2hlY2tncmFjZXBlcmlvZHNlY29uZHNcbiAgICAgKi9cbiAgICBwdWJsaWMgaGVhbHRoQ2hlY2tHcmFjZVBlcmlvZFNlY29uZHM6IG51bWJlciB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBsYXVuY2ggdHlwZSBvbiB3aGljaCB0byBydW4geW91ciBzZXJ2aWNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBbWF6b24gRUNTIExhdW5jaCBUeXBlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvbGF1bmNoX3R5cGVzLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1sYXVuY2h0eXBlXG4gICAgICovXG4gICAgcHVibGljIGxhdW5jaFR5cGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiBsb2FkIGJhbGFuY2VyIG9iamVjdHMgdG8gYXNzb2NpYXRlIHdpdGggdGhlIHNlcnZpY2UuIElmIHlvdSBzcGVjaWZ5IHRoZSBgUm9sZWAgcHJvcGVydHksIGBMb2FkQmFsYW5jZXJzYCBtdXN0IGJlIHNwZWNpZmllZCBhcyB3ZWxsLiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG51bWJlciBvZiBsb2FkIGJhbGFuY2VycyB0aGF0IHlvdSBjYW4gc3BlY2lmeSBwZXIgc2VydmljZSwgc2VlIFtTZXJ2aWNlIExvYWQgQmFsYW5jaW5nXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zZXJ2aWNlLWxvYWQtYmFsYW5jaW5nLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1sb2FkYmFsYW5jZXJzXG4gICAgICovXG4gICAgcHVibGljIGxvYWRCYWxhbmNlcnM6IEFycmF5PENmblNlcnZpY2UuTG9hZEJhbGFuY2VyUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5ldHdvcmsgY29uZmlndXJhdGlvbiBmb3IgdGhlIHNlcnZpY2UuIFRoaXMgcGFyYW1ldGVyIGlzIHJlcXVpcmVkIGZvciB0YXNrIGRlZmluaXRpb25zIHRoYXQgdXNlIHRoZSBgYXdzdnBjYCBuZXR3b3JrIG1vZGUgdG8gcmVjZWl2ZSB0aGVpciBvd24gZWxhc3RpYyBuZXR3b3JrIGludGVyZmFjZSwgYW5kIGl0IGlzIG5vdCBzdXBwb3J0ZWQgZm9yIG90aGVyIG5ldHdvcmsgbW9kZXMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1Rhc2sgTmV0d29ya2luZ10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvdGFzay1uZXR3b3JraW5nLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1uZXR3b3JrY29uZmlndXJhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBuZXR3b3JrQ29uZmlndXJhdGlvbjogQ2ZuU2VydmljZS5OZXR3b3JrQ29uZmlndXJhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQW4gYXJyYXkgb2YgcGxhY2VtZW50IGNvbnN0cmFpbnQgb2JqZWN0cyB0byB1c2UgZm9yIHRhc2tzIGluIHlvdXIgc2VydmljZS4gWW91IGNhbiBzcGVjaWZ5IGEgbWF4aW11bSBvZiAxMCBjb25zdHJhaW50cyBmb3IgZWFjaCB0YXNrLiBUaGlzIGxpbWl0IGluY2x1ZGVzIGNvbnN0cmFpbnRzIGluIHRoZSB0YXNrIGRlZmluaXRpb24gYW5kIHRob3NlIHNwZWNpZmllZCBhdCBydW50aW1lLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbCNjZm4tZWNzLXNlcnZpY2UtcGxhY2VtZW50Y29uc3RyYWludHNcbiAgICAgKi9cbiAgICBwdWJsaWMgcGxhY2VtZW50Q29uc3RyYWludHM6IEFycmF5PENmblNlcnZpY2UuUGxhY2VtZW50Q29uc3RyYWludFByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBwbGFjZW1lbnQgc3RyYXRlZ3kgb2JqZWN0cyB0byB1c2UgZm9yIHRhc2tzIGluIHlvdXIgc2VydmljZS4gWW91IGNhbiBzcGVjaWZ5IGEgbWF4aW11bSBvZiA1IHN0cmF0ZWd5IHJ1bGVzIGZvciBlYWNoIHNlcnZpY2UuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1wbGFjZW1lbnRzdHJhdGVnaWVzXG4gICAgICovXG4gICAgcHVibGljIHBsYWNlbWVudFN0cmF0ZWdpZXM6IEFycmF5PENmblNlcnZpY2UuUGxhY2VtZW50U3RyYXRlZ3lQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gdmVyc2lvbiB0aGF0IHlvdXIgdGFza3MgaW4gdGhlIHNlcnZpY2UgYXJlIHJ1bm5pbmcgb24uIEEgcGxhdGZvcm0gdmVyc2lvbiBpcyBzcGVjaWZpZWQgb25seSBmb3IgdGFza3MgdXNpbmcgdGhlIEZhcmdhdGUgbGF1bmNoIHR5cGUuIElmIG9uZSBpc24ndCBzcGVjaWZpZWQsIHRoZSBgTEFURVNUYCBwbGF0Zm9ybSB2ZXJzaW9uIGlzIHVzZWQuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0FXUyBGYXJnYXRlIHBsYXRmb3JtIHZlcnNpb25zXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9wbGF0Zm9ybV92ZXJzaW9ucy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbCNjZm4tZWNzLXNlcnZpY2UtcGxhdGZvcm12ZXJzaW9uXG4gICAgICovXG4gICAgcHVibGljIHBsYXRmb3JtVmVyc2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogU3BlY2lmaWVzIHdoZXRoZXIgdG8gcHJvcGFnYXRlIHRoZSB0YWdzIGZyb20gdGhlIHRhc2sgZGVmaW5pdGlvbiB0byB0aGUgdGFzay4gSWYgbm8gdmFsdWUgaXMgc3BlY2lmaWVkLCB0aGUgdGFncyBhcmVuJ3QgcHJvcGFnYXRlZC4gVGFncyBjYW4gb25seSBiZSBwcm9wYWdhdGVkIHRvIHRoZSB0YXNrIGR1cmluZyB0YXNrIGNyZWF0aW9uLiBUbyBhZGQgdGFncyB0byBhIHRhc2sgYWZ0ZXIgdGFzayBjcmVhdGlvbiwgdXNlIHRoZSBbVGFnUmVzb3VyY2VdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVGFnUmVzb3VyY2UuaHRtbCkgQVBJIGFjdGlvbi5cbiAgICAgKlxuICAgICAqIFRoZSBkZWZhdWx0IGlzIGBOT05FYCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1wcm9wYWdhdGV0YWdzXG4gICAgICovXG4gICAgcHVibGljIHByb3BhZ2F0ZVRhZ3M6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9yIGZ1bGwgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIElBTSByb2xlIHRoYXQgYWxsb3dzIEFtYXpvbiBFQ1MgdG8gbWFrZSBjYWxscyB0byB5b3VyIGxvYWQgYmFsYW5jZXIgb24geW91ciBiZWhhbGYuIFRoaXMgcGFyYW1ldGVyIGlzIG9ubHkgcGVybWl0dGVkIGlmIHlvdSBhcmUgdXNpbmcgYSBsb2FkIGJhbGFuY2VyIHdpdGggeW91ciBzZXJ2aWNlIGFuZCB5b3VyIHRhc2sgZGVmaW5pdGlvbiBkb2Vzbid0IHVzZSB0aGUgYGF3c3ZwY2AgbmV0d29yayBtb2RlLiBJZiB5b3Ugc3BlY2lmeSB0aGUgYHJvbGVgIHBhcmFtZXRlciwgeW91IG11c3QgYWxzbyBzcGVjaWZ5IGEgbG9hZCBiYWxhbmNlciBvYmplY3Qgd2l0aCB0aGUgYGxvYWRCYWxhbmNlcnNgIHBhcmFtZXRlci5cbiAgICAgKlxuICAgICAqID4gSWYgeW91ciBhY2NvdW50IGhhcyBhbHJlYWR5IGNyZWF0ZWQgdGhlIEFtYXpvbiBFQ1Mgc2VydmljZS1saW5rZWQgcm9sZSwgdGhhdCByb2xlIGlzIHVzZWQgZm9yIHlvdXIgc2VydmljZSB1bmxlc3MgeW91IHNwZWNpZnkgYSByb2xlIGhlcmUuIFRoZSBzZXJ2aWNlLWxpbmtlZCByb2xlIGlzIHJlcXVpcmVkIGlmIHlvdXIgdGFzayBkZWZpbml0aW9uIHVzZXMgdGhlIGBhd3N2cGNgIG5ldHdvcmsgbW9kZSBvciBpZiB0aGUgc2VydmljZSBpcyBjb25maWd1cmVkIHRvIHVzZSBzZXJ2aWNlIGRpc2NvdmVyeSwgYW4gZXh0ZXJuYWwgZGVwbG95bWVudCBjb250cm9sbGVyLCBtdWx0aXBsZSB0YXJnZXQgZ3JvdXBzLCBvciBFbGFzdGljIEluZmVyZW5jZSBhY2NlbGVyYXRvcnMgaW4gd2hpY2ggY2FzZSB5b3UgZG9uJ3Qgc3BlY2lmeSBhIHJvbGUgaGVyZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbVXNpbmcgc2VydmljZS1saW5rZWQgcm9sZXMgZm9yIEFtYXpvbiBFQ1NdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3VzaW5nLXNlcnZpY2UtbGlua2VkLXJvbGVzLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBJZiB5b3VyIHNwZWNpZmllZCByb2xlIGhhcyBhIHBhdGggb3RoZXIgdGhhbiBgL2AgLCB0aGVuIHlvdSBtdXN0IGVpdGhlciBzcGVjaWZ5IHRoZSBmdWxsIHJvbGUgQVJOICh0aGlzIGlzIHJlY29tbWVuZGVkKSBvciBwcmVmaXggdGhlIHJvbGUgbmFtZSB3aXRoIHRoZSBwYXRoLiBGb3IgZXhhbXBsZSwgaWYgYSByb2xlIHdpdGggdGhlIG5hbWUgYGJhcmAgaGFzIGEgcGF0aCBvZiBgL2Zvby9gIHRoZW4geW91IHdvdWxkIHNwZWNpZnkgYC9mb28vYmFyYCBhcyB0aGUgcm9sZSBuYW1lLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtGcmllbmRseSBuYW1lcyBhbmQgcGF0aHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfaWRlbnRpZmllcnMuaHRtbCNpZGVudGlmaWVycy1mcmllbmRseS1uYW1lcykgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbCNjZm4tZWNzLXNlcnZpY2Utcm9sZVxuICAgICAqL1xuICAgIHB1YmxpYyByb2xlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc2NoZWR1bGluZyBzdHJhdGVneSB0byB1c2UgZm9yIHRoZSBzZXJ2aWNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtTZXJ2aWNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvZWNzX3NlcnZpY2VzLmh0bWwpIC5cbiAgICAgKlxuICAgICAqIFRoZXJlIGFyZSB0d28gc2VydmljZSBzY2hlZHVsZXIgc3RyYXRlZ2llcyBhdmFpbGFibGU6XG4gICAgICpcbiAgICAgKiAtIGBSRVBMSUNBYCAtVGhlIHJlcGxpY2Egc2NoZWR1bGluZyBzdHJhdGVneSBwbGFjZXMgYW5kIG1haW50YWlucyB0aGUgZGVzaXJlZCBudW1iZXIgb2YgdGFza3MgYWNyb3NzIHlvdXIgY2x1c3Rlci4gQnkgZGVmYXVsdCwgdGhlIHNlcnZpY2Ugc2NoZWR1bGVyIHNwcmVhZHMgdGFza3MgYWNyb3NzIEF2YWlsYWJpbGl0eSBab25lcy4gWW91IGNhbiB1c2UgdGFzayBwbGFjZW1lbnQgc3RyYXRlZ2llcyBhbmQgY29uc3RyYWludHMgdG8gY3VzdG9taXplIHRhc2sgcGxhY2VtZW50IGRlY2lzaW9ucy4gVGhpcyBzY2hlZHVsZXIgc3RyYXRlZ3kgaXMgcmVxdWlyZWQgaWYgdGhlIHNlcnZpY2UgdXNlcyB0aGUgYENPREVfREVQTE9ZYCBvciBgRVhURVJOQUxgIGRlcGxveW1lbnQgY29udHJvbGxlciB0eXBlcy5cbiAgICAgKiAtIGBEQUVNT05gIC1UaGUgZGFlbW9uIHNjaGVkdWxpbmcgc3RyYXRlZ3kgZGVwbG95cyBleGFjdGx5IG9uZSB0YXNrIG9uIGVhY2ggYWN0aXZlIGNvbnRhaW5lciBpbnN0YW5jZSB0aGF0IG1lZXRzIGFsbCBvZiB0aGUgdGFzayBwbGFjZW1lbnQgY29uc3RyYWludHMgdGhhdCB5b3Ugc3BlY2lmeSBpbiB5b3VyIGNsdXN0ZXIuIFRoZSBzZXJ2aWNlIHNjaGVkdWxlciBhbHNvIGV2YWx1YXRlcyB0aGUgdGFzayBwbGFjZW1lbnQgY29uc3RyYWludHMgZm9yIHJ1bm5pbmcgdGFza3MgYW5kIHdpbGwgc3RvcCB0YXNrcyB0aGF0IGRvbid0IG1lZXQgdGhlIHBsYWNlbWVudCBjb25zdHJhaW50cy4gV2hlbiB5b3UncmUgdXNpbmcgdGhpcyBzdHJhdGVneSwgeW91IGRvbid0IG5lZWQgdG8gc3BlY2lmeSBhIGRlc2lyZWQgbnVtYmVyIG9mIHRhc2tzLCBhIHRhc2sgcGxhY2VtZW50IHN0cmF0ZWd5LCBvciB1c2UgU2VydmljZSBBdXRvIFNjYWxpbmcgcG9saWNpZXMuXG4gICAgICpcbiAgICAgKiA+IFRhc2tzIHVzaW5nIHRoZSBGYXJnYXRlIGxhdW5jaCB0eXBlIG9yIHRoZSBgQ09ERV9ERVBMT1lgIG9yIGBFWFRFUk5BTGAgZGVwbG95bWVudCBjb250cm9sbGVyIHR5cGVzIGRvbid0IHN1cHBvcnQgdGhlIGBEQUVNT05gIHNjaGVkdWxpbmcgc3RyYXRlZ3kuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1zY2hlZHVsaW5nc3RyYXRlZ3lcbiAgICAgKi9cbiAgICBwdWJsaWMgc2NoZWR1bGluZ1N0cmF0ZWd5OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY29uZmlndXJhdGlvbiBmb3IgdGhpcyBzZXJ2aWNlIHRvIGRpc2NvdmVyIGFuZCBjb25uZWN0IHRvIHNlcnZpY2VzLCBhbmQgYmUgZGlzY292ZXJlZCBieSwgYW5kIGNvbm5lY3RlZCBmcm9tLCBvdGhlciBzZXJ2aWNlcyB3aXRoaW4gYSBuYW1lc3BhY2UuXG4gICAgICpcbiAgICAgKiBUYXNrcyB0aGF0IHJ1biBpbiBhIG5hbWVzcGFjZSBjYW4gdXNlIHNob3J0IG5hbWVzIHRvIGNvbm5lY3QgdG8gc2VydmljZXMgaW4gdGhlIG5hbWVzcGFjZS4gVGFza3MgY2FuIGNvbm5lY3QgdG8gc2VydmljZXMgYWNyb3NzIGFsbCBvZiB0aGUgY2x1c3RlcnMgaW4gdGhlIG5hbWVzcGFjZS4gVGFza3MgY29ubmVjdCB0aHJvdWdoIGEgbWFuYWdlZCBwcm94eSBjb250YWluZXIgdGhhdCBjb2xsZWN0cyBsb2dzIGFuZCBtZXRyaWNzIGZvciBpbmNyZWFzZWQgdmlzaWJpbGl0eS4gT25seSB0aGUgdGFza3MgdGhhdCBBbWF6b24gRUNTIHNlcnZpY2VzIGNyZWF0ZSBhcmUgc3VwcG9ydGVkIHdpdGggU2VydmljZSBDb25uZWN0LiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtTZXJ2aWNlIENvbm5lY3RdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3NlcnZpY2UtY29ubmVjdC5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbCNjZm4tZWNzLXNlcnZpY2Utc2VydmljZWNvbm5lY3Rjb25maWd1cmF0aW9uXG4gICAgICovXG4gICAgcHVibGljIHNlcnZpY2VDb25uZWN0Q29uZmlndXJhdGlvbjogQ2ZuU2VydmljZS5TZXJ2aWNlQ29ubmVjdENvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHlvdXIgc2VydmljZS4gVXAgdG8gMjU1IGxldHRlcnMgKHVwcGVyY2FzZSBhbmQgbG93ZXJjYXNlKSwgbnVtYmVycywgdW5kZXJzY29yZXMsIGFuZCBoeXBoZW5zIGFyZSBhbGxvd2VkLiBTZXJ2aWNlIG5hbWVzIG11c3QgYmUgdW5pcXVlIHdpdGhpbiBhIGNsdXN0ZXIsIGJ1dCB5b3UgY2FuIGhhdmUgc2ltaWxhcmx5IG5hbWVkIHNlcnZpY2VzIGluIG11bHRpcGxlIGNsdXN0ZXJzIHdpdGhpbiBhIFJlZ2lvbiBvciBhY3Jvc3MgbXVsdGlwbGUgUmVnaW9ucy5cbiAgICAgKlxuICAgICAqID4gVGhlIHN0YWNrIHVwZGF0ZSBmYWlscyBpZiB5b3UgY2hhbmdlIGFueSBwcm9wZXJ0aWVzIHRoYXQgcmVxdWlyZSByZXBsYWNlbWVudCBhbmQgdGhlIGBTZXJ2aWNlTmFtZWAgaXMgY29uZmlndXJlZC4gVGhpcyBpcyBiZWNhdXNlIEFXUyBDbG91ZEZvcm1hdGlvbiBjcmVhdGVzIHRoZSByZXBsYWNlbWVudCBzZXJ2aWNlIGZpcnN0LCBidXQgZWFjaCBgU2VydmljZU5hbWVgIG11c3QgYmUgdW5pcXVlIGluIHRoZSBjbHVzdGVyLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXNlcnZpY2UuaHRtbCNjZm4tZWNzLXNlcnZpY2Utc2VydmljZW5hbWVcbiAgICAgKi9cbiAgICBwdWJsaWMgc2VydmljZU5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBkZXRhaWxzIG9mIHRoZSBzZXJ2aWNlIGRpc2NvdmVyeSByZWdpc3RyeSB0byBhc3NvY2lhdGUgd2l0aCB0aGlzIHNlcnZpY2UuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1NlcnZpY2UgZGlzY292ZXJ5XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zZXJ2aWNlLWRpc2NvdmVyeS5odG1sKSAuXG4gICAgICpcbiAgICAgKiA+IEVhY2ggc2VydmljZSBtYXkgYmUgYXNzb2NpYXRlZCB3aXRoIG9uZSBzZXJ2aWNlIHJlZ2lzdHJ5LiBNdWx0aXBsZSBzZXJ2aWNlIHJlZ2lzdHJpZXMgZm9yIGVhY2ggc2VydmljZSBpc24ndCBzdXBwb3J0ZWQuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3Mtc2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1zZXJ2aWNlcmVnaXN0cmllc1xuICAgICAqL1xuICAgIHB1YmxpYyBzZXJ2aWNlUmVnaXN0cmllczogQXJyYXk8Q2ZuU2VydmljZS5TZXJ2aWNlUmVnaXN0cnlQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWV0YWRhdGEgdGhhdCB5b3UgYXBwbHkgdG8gdGhlIHNlcnZpY2UgdG8gaGVscCB5b3UgY2F0ZWdvcml6ZSBhbmQgb3JnYW5pemUgdGhlbS4gRWFjaCB0YWcgY29uc2lzdHMgb2YgYSBrZXkgYW5kIGFuIG9wdGlvbmFsIHZhbHVlLCBib3RoIG9mIHdoaWNoIHlvdSBkZWZpbmUuIFdoZW4gYSBzZXJ2aWNlIGlzIGRlbGV0ZWQsIHRoZSB0YWdzIGFyZSBkZWxldGVkIGFzIHdlbGwuXG4gICAgICpcbiAgICAgKiBUaGUgZm9sbG93aW5nIGJhc2ljIHJlc3RyaWN0aW9ucyBhcHBseSB0byB0YWdzOlxuICAgICAqXG4gICAgICogLSBNYXhpbXVtIG51bWJlciBvZiB0YWdzIHBlciByZXNvdXJjZSAtIDUwXG4gICAgICogLSBGb3IgZWFjaCByZXNvdXJjZSwgZWFjaCB0YWcga2V5IG11c3QgYmUgdW5pcXVlLCBhbmQgZWFjaCB0YWcga2V5IGNhbiBoYXZlIG9ubHkgb25lIHZhbHVlLlxuICAgICAqIC0gTWF4aW11bSBrZXkgbGVuZ3RoIC0gMTI4IFVuaWNvZGUgY2hhcmFjdGVycyBpbiBVVEYtOFxuICAgICAqIC0gTWF4aW11bSB2YWx1ZSBsZW5ndGggLSAyNTYgVW5pY29kZSBjaGFyYWN0ZXJzIGluIFVURi04XG4gICAgICogLSBJZiB5b3VyIHRhZ2dpbmcgc2NoZW1hIGlzIHVzZWQgYWNyb3NzIG11bHRpcGxlIHNlcnZpY2VzIGFuZCByZXNvdXJjZXMsIHJlbWVtYmVyIHRoYXQgb3RoZXIgc2VydmljZXMgbWF5IGhhdmUgcmVzdHJpY3Rpb25zIG9uIGFsbG93ZWQgY2hhcmFjdGVycy4gR2VuZXJhbGx5IGFsbG93ZWQgY2hhcmFjdGVycyBhcmU6IGxldHRlcnMsIG51bWJlcnMsIGFuZCBzcGFjZXMgcmVwcmVzZW50YWJsZSBpbiBVVEYtOCwgYW5kIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogKyAtID0gLiBfIDogLyBALlxuICAgICAqIC0gVGFnIGtleXMgYW5kIHZhbHVlcyBhcmUgY2FzZS1zZW5zaXRpdmUuXG4gICAgICogLSBEbyBub3QgdXNlIGBhd3M6YCAsIGBBV1M6YCAsIG9yIGFueSB1cHBlciBvciBsb3dlcmNhc2UgY29tYmluYXRpb24gb2Ygc3VjaCBhcyBhIHByZWZpeCBmb3IgZWl0aGVyIGtleXMgb3IgdmFsdWVzIGFzIGl0IGlzIHJlc2VydmVkIGZvciBBV1MgdXNlLiBZb3UgY2Fubm90IGVkaXQgb3IgZGVsZXRlIHRhZyBrZXlzIG9yIHZhbHVlcyB3aXRoIHRoaXMgcHJlZml4LiBUYWdzIHdpdGggdGhpcyBwcmVmaXggZG8gbm90IGNvdW50IGFnYWluc3QgeW91ciB0YWdzIHBlciByZXNvdXJjZSBsaW1pdC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1zZXJ2aWNlLmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLXRhZ3NcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgdGFnczogY2RrLlRhZ01hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYGZhbWlseWAgYW5kIGByZXZpc2lvbmAgKCBgZmFtaWx5OnJldmlzaW9uYCApIG9yIGZ1bGwgQVJOIG9mIHRoZSB0YXNrIGRlZmluaXRpb24gdG8gcnVuIGluIHlvdXIgc2VydmljZS4gSWYgYSBgcmV2aXNpb25gIGlzbid0IHNwZWNpZmllZCwgdGhlIGxhdGVzdCBgQUNUSVZFYCByZXZpc2lvbiBpcyB1c2VkLlxuICAgICAqXG4gICAgICogQSB0YXNrIGRlZmluaXRpb24gbXVzdCBiZSBzcGVjaWZpZWQgaWYgdGhlIHNlcnZpY2UgdXNlcyBlaXRoZXIgdGhlIGBFQ1NgIG9yIGBDT0RFX0RFUExPWWAgZGVwbG95bWVudCBjb250cm9sbGVycy5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGRlcGxveW1lbnQgdHlwZXMsIHNlZSBbQW1hem9uIEVDUyBkZXBsb3ltZW50IHR5cGVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9kZXBsb3ltZW50LXR5cGVzLmh0bWwpIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy1zZXJ2aWNlLmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLXRhc2tkZWZpbml0aW9uXG4gICAgICovXG4gICAgcHVibGljIHRhc2tEZWZpbml0aW9uOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6RUNTOjpTZXJ2aWNlYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5TZXJ2aWNlUHJvcHMgPSB7fSkge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuU2VydmljZS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgdGhpcy5hdHRyTmFtZSA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnTmFtZScpKTtcbiAgICAgICAgdGhpcy5hdHRyU2VydmljZUFybiA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnU2VydmljZUFybicpKTtcblxuICAgICAgICB0aGlzLmNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneSA9IHByb3BzLmNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneTtcbiAgICAgICAgdGhpcy5jbHVzdGVyID0gcHJvcHMuY2x1c3RlcjtcbiAgICAgICAgdGhpcy5kZXBsb3ltZW50Q29uZmlndXJhdGlvbiA9IHByb3BzLmRlcGxveW1lbnRDb25maWd1cmF0aW9uO1xuICAgICAgICB0aGlzLmRlcGxveW1lbnRDb250cm9sbGVyID0gcHJvcHMuZGVwbG95bWVudENvbnRyb2xsZXI7XG4gICAgICAgIHRoaXMuZGVzaXJlZENvdW50ID0gcHJvcHMuZGVzaXJlZENvdW50O1xuICAgICAgICB0aGlzLmVuYWJsZUVjc01hbmFnZWRUYWdzID0gcHJvcHMuZW5hYmxlRWNzTWFuYWdlZFRhZ3M7XG4gICAgICAgIHRoaXMuZW5hYmxlRXhlY3V0ZUNvbW1hbmQgPSBwcm9wcy5lbmFibGVFeGVjdXRlQ29tbWFuZDtcbiAgICAgICAgdGhpcy5oZWFsdGhDaGVja0dyYWNlUGVyaW9kU2Vjb25kcyA9IHByb3BzLmhlYWx0aENoZWNrR3JhY2VQZXJpb2RTZWNvbmRzO1xuICAgICAgICB0aGlzLmxhdW5jaFR5cGUgPSBwcm9wcy5sYXVuY2hUeXBlO1xuICAgICAgICB0aGlzLmxvYWRCYWxhbmNlcnMgPSBwcm9wcy5sb2FkQmFsYW5jZXJzO1xuICAgICAgICB0aGlzLm5ldHdvcmtDb25maWd1cmF0aW9uID0gcHJvcHMubmV0d29ya0NvbmZpZ3VyYXRpb247XG4gICAgICAgIHRoaXMucGxhY2VtZW50Q29uc3RyYWludHMgPSBwcm9wcy5wbGFjZW1lbnRDb25zdHJhaW50cztcbiAgICAgICAgdGhpcy5wbGFjZW1lbnRTdHJhdGVnaWVzID0gcHJvcHMucGxhY2VtZW50U3RyYXRlZ2llcztcbiAgICAgICAgdGhpcy5wbGF0Zm9ybVZlcnNpb24gPSBwcm9wcy5wbGF0Zm9ybVZlcnNpb247XG4gICAgICAgIHRoaXMucHJvcGFnYXRlVGFncyA9IHByb3BzLnByb3BhZ2F0ZVRhZ3M7XG4gICAgICAgIHRoaXMucm9sZSA9IHByb3BzLnJvbGU7XG4gICAgICAgIHRoaXMuc2NoZWR1bGluZ1N0cmF0ZWd5ID0gcHJvcHMuc2NoZWR1bGluZ1N0cmF0ZWd5O1xuICAgICAgICB0aGlzLnNlcnZpY2VDb25uZWN0Q29uZmlndXJhdGlvbiA9IHByb3BzLnNlcnZpY2VDb25uZWN0Q29uZmlndXJhdGlvbjtcbiAgICAgICAgdGhpcy5zZXJ2aWNlTmFtZSA9IHByb3BzLnNlcnZpY2VOYW1lO1xuICAgICAgICB0aGlzLnNlcnZpY2VSZWdpc3RyaWVzID0gcHJvcHMuc2VydmljZVJlZ2lzdHJpZXM7XG4gICAgICAgIHRoaXMudGFncyA9IG5ldyBjZGsuVGFnTWFuYWdlcihjZGsuVGFnVHlwZS5TVEFOREFSRCwgXCJBV1M6OkVDUzo6U2VydmljZVwiLCBwcm9wcy50YWdzLCB7IHRhZ1Byb3BlcnR5TmFtZTogJ3RhZ3MnIH0pO1xuICAgICAgICB0aGlzLnRhc2tEZWZpbml0aW9uID0gcHJvcHMudGFza0RlZmluaXRpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5TZXJ2aWNlLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3k6IHRoaXMuY2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5LFxuICAgICAgICAgICAgY2x1c3RlcjogdGhpcy5jbHVzdGVyLFxuICAgICAgICAgICAgZGVwbG95bWVudENvbmZpZ3VyYXRpb246IHRoaXMuZGVwbG95bWVudENvbmZpZ3VyYXRpb24sXG4gICAgICAgICAgICBkZXBsb3ltZW50Q29udHJvbGxlcjogdGhpcy5kZXBsb3ltZW50Q29udHJvbGxlcixcbiAgICAgICAgICAgIGRlc2lyZWRDb3VudDogdGhpcy5kZXNpcmVkQ291bnQsXG4gICAgICAgICAgICBlbmFibGVFY3NNYW5hZ2VkVGFnczogdGhpcy5lbmFibGVFY3NNYW5hZ2VkVGFncyxcbiAgICAgICAgICAgIGVuYWJsZUV4ZWN1dGVDb21tYW5kOiB0aGlzLmVuYWJsZUV4ZWN1dGVDb21tYW5kLFxuICAgICAgICAgICAgaGVhbHRoQ2hlY2tHcmFjZVBlcmlvZFNlY29uZHM6IHRoaXMuaGVhbHRoQ2hlY2tHcmFjZVBlcmlvZFNlY29uZHMsXG4gICAgICAgICAgICBsYXVuY2hUeXBlOiB0aGlzLmxhdW5jaFR5cGUsXG4gICAgICAgICAgICBsb2FkQmFsYW5jZXJzOiB0aGlzLmxvYWRCYWxhbmNlcnMsXG4gICAgICAgICAgICBuZXR3b3JrQ29uZmlndXJhdGlvbjogdGhpcy5uZXR3b3JrQ29uZmlndXJhdGlvbixcbiAgICAgICAgICAgIHBsYWNlbWVudENvbnN0cmFpbnRzOiB0aGlzLnBsYWNlbWVudENvbnN0cmFpbnRzLFxuICAgICAgICAgICAgcGxhY2VtZW50U3RyYXRlZ2llczogdGhpcy5wbGFjZW1lbnRTdHJhdGVnaWVzLFxuICAgICAgICAgICAgcGxhdGZvcm1WZXJzaW9uOiB0aGlzLnBsYXRmb3JtVmVyc2lvbixcbiAgICAgICAgICAgIHByb3BhZ2F0ZVRhZ3M6IHRoaXMucHJvcGFnYXRlVGFncyxcbiAgICAgICAgICAgIHJvbGU6IHRoaXMucm9sZSxcbiAgICAgICAgICAgIHNjaGVkdWxpbmdTdHJhdGVneTogdGhpcy5zY2hlZHVsaW5nU3RyYXRlZ3ksXG4gICAgICAgICAgICBzZXJ2aWNlQ29ubmVjdENvbmZpZ3VyYXRpb246IHRoaXMuc2VydmljZUNvbm5lY3RDb25maWd1cmF0aW9uLFxuICAgICAgICAgICAgc2VydmljZU5hbWU6IHRoaXMuc2VydmljZU5hbWUsXG4gICAgICAgICAgICBzZXJ2aWNlUmVnaXN0cmllczogdGhpcy5zZXJ2aWNlUmVnaXN0cmllcyxcbiAgICAgICAgICAgIHRhZ3M6IHRoaXMudGFncy5yZW5kZXJUYWdzKCksXG4gICAgICAgICAgICB0YXNrRGVmaW5pdGlvbjogdGhpcy50YXNrRGVmaW5pdGlvbixcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5TZXJ2aWNlUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuU2VydmljZSB7XG4gICAgLyoqXG4gICAgICogQW4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgbmV0d29ya2luZyBkZXRhaWxzIGZvciBhIHRhc2sgb3Igc2VydmljZS5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLWF3c3ZwY2NvbmZpZ3VyYXRpb24uaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgQXdzVnBjQ29uZmlndXJhdGlvblByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZXRoZXIgdGhlIHRhc2sncyBlbGFzdGljIG5ldHdvcmsgaW50ZXJmYWNlIHJlY2VpdmVzIGEgcHVibGljIElQIGFkZHJlc3MuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGBESVNBQkxFRGAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLWF3c3ZwY2NvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLXNlcnZpY2UtYXdzdnBjY29uZmlndXJhdGlvbi1hc3NpZ25wdWJsaWNpcFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgYXNzaWduUHVibGljSXA/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgSURzIG9mIHRoZSBzZWN1cml0eSBncm91cHMgYXNzb2NpYXRlZCB3aXRoIHRoZSB0YXNrIG9yIHNlcnZpY2UuIElmIHlvdSBkb24ndCBzcGVjaWZ5IGEgc2VjdXJpdHkgZ3JvdXAsIHRoZSBkZWZhdWx0IHNlY3VyaXR5IGdyb3VwIGZvciB0aGUgVlBDIGlzIHVzZWQuIFRoZXJlJ3MgYSBsaW1pdCBvZiA1IHNlY3VyaXR5IGdyb3VwcyB0aGF0IGNhbiBiZSBzcGVjaWZpZWQgcGVyIGBBd3NWcGNDb25maWd1cmF0aW9uYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gQWxsIHNwZWNpZmllZCBzZWN1cml0eSBncm91cHMgbXVzdCBiZSBmcm9tIHRoZSBzYW1lIFZQQy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1hd3N2cGNjb25maWd1cmF0aW9uLmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLWF3c3ZwY2NvbmZpZ3VyYXRpb24tc2VjdXJpdHlncm91cHNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHNlY3VyaXR5R3JvdXBzPzogc3RyaW5nW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgSURzIG9mIHRoZSBzdWJuZXRzIGFzc29jaWF0ZWQgd2l0aCB0aGUgdGFzayBvciBzZXJ2aWNlLiBUaGVyZSdzIGEgbGltaXQgb2YgMTYgc3VibmV0cyB0aGF0IGNhbiBiZSBzcGVjaWZpZWQgcGVyIGBBd3NWcGNDb25maWd1cmF0aW9uYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gQWxsIHNwZWNpZmllZCBzdWJuZXRzIG11c3QgYmUgZnJvbSB0aGUgc2FtZSBWUEMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXNlcnZpY2UtYXdzdnBjY29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3Mtc2VydmljZS1hd3N2cGNjb25maWd1cmF0aW9uLXN1Ym5ldHNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHN1Ym5ldHM6IHN0cmluZ1tdO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBBd3NWcGNDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEF3c1ZwY0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5TZXJ2aWNlX0F3c1ZwY0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2Fzc2lnblB1YmxpY0lwJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmFzc2lnblB1YmxpY0lwKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzZWN1cml0eUdyb3VwcycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMuc2VjdXJpdHlHcm91cHMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3N1Ym5ldHMnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMuc3VibmV0cykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc3VibmV0cycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMuc3VibmV0cykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJBd3NWcGNDb25maWd1cmF0aW9uUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6U2VydmljZS5Bd3NWcGNDb25maWd1cmF0aW9uYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBBd3NWcGNDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6U2VydmljZS5Bd3NWcGNDb25maWd1cmF0aW9uYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblNlcnZpY2VBd3NWcGNDb25maWd1cmF0aW9uUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblNlcnZpY2VfQXdzVnBjQ29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBBc3NpZ25QdWJsaWNJcDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5hc3NpZ25QdWJsaWNJcCksXG4gICAgICAgIFNlY3VyaXR5R3JvdXBzOiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5zZWN1cml0eUdyb3VwcyksXG4gICAgICAgIFN1Ym5ldHM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnN1Ym5ldHMpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5TZXJ2aWNlQXdzVnBjQ29uZmlndXJhdGlvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuU2VydmljZS5Bd3NWcGNDb25maWd1cmF0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuU2VydmljZS5Bd3NWcGNDb25maWd1cmF0aW9uUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdhc3NpZ25QdWJsaWNJcCcsICdBc3NpZ25QdWJsaWNJcCcsIHByb3BlcnRpZXMuQXNzaWduUHVibGljSXAgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQXNzaWduUHVibGljSXApIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3NlY3VyaXR5R3JvdXBzJywgJ1NlY3VyaXR5R3JvdXBzJywgcHJvcGVydGllcy5TZWN1cml0eUdyb3VwcyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmdBcnJheShwcm9wZXJ0aWVzLlNlY3VyaXR5R3JvdXBzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzdWJuZXRzJywgJ1N1Ym5ldHMnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuU3VibmV0cykpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblNlcnZpY2Uge1xuICAgIC8qKlxuICAgICAqIFRoZSBkZXRhaWxzIG9mIGEgY2FwYWNpdHkgcHJvdmlkZXIgc3RyYXRlZ3kuIEEgY2FwYWNpdHkgcHJvdmlkZXIgc3RyYXRlZ3kgY2FuIGJlIHNldCB3aGVuIHVzaW5nIHRoZSBgUnVuVGFza2Agb3IgYENyZWF0ZVNlcnZpY2VgIEFQSXMgb3IgYXMgdGhlIGRlZmF1bHQgY2FwYWNpdHkgcHJvdmlkZXIgc3RyYXRlZ3kgZm9yIGEgY2x1c3RlciB3aXRoIHRoZSBgQ3JlYXRlQ2x1c3RlcmAgQVBJLlxuICAgICAqXG4gICAgICogT25seSBjYXBhY2l0eSBwcm92aWRlcnMgdGhhdCBhcmUgYWxyZWFkeSBhc3NvY2lhdGVkIHdpdGggYSBjbHVzdGVyIGFuZCBoYXZlIGFuIGBBQ1RJVkVgIG9yIGBVUERBVElOR2Agc3RhdHVzIGNhbiBiZSB1c2VkIGluIGEgY2FwYWNpdHkgcHJvdmlkZXIgc3RyYXRlZ3kuIFRoZSBgUHV0Q2x1c3RlckNhcGFjaXR5UHJvdmlkZXJzYCBBUEkgaXMgdXNlZCB0byBhc3NvY2lhdGUgYSBjYXBhY2l0eSBwcm92aWRlciB3aXRoIGEgY2x1c3Rlci5cbiAgICAgKlxuICAgICAqIElmIHNwZWNpZnlpbmcgYSBjYXBhY2l0eSBwcm92aWRlciB0aGF0IHVzZXMgYW4gQXV0byBTY2FsaW5nIGdyb3VwLCB0aGUgY2FwYWNpdHkgcHJvdmlkZXIgbXVzdCBhbHJlYWR5IGJlIGNyZWF0ZWQuIE5ldyBBdXRvIFNjYWxpbmcgZ3JvdXAgY2FwYWNpdHkgcHJvdmlkZXJzIGNhbiBiZSBjcmVhdGVkIHdpdGggdGhlIGBDcmVhdGVDYXBhY2l0eVByb3ZpZGVyYCBBUEkgb3BlcmF0aW9uLlxuICAgICAqXG4gICAgICogVG8gdXNlIGFuIEFXUyBGYXJnYXRlIGNhcGFjaXR5IHByb3ZpZGVyLCBzcGVjaWZ5IGVpdGhlciB0aGUgYEZBUkdBVEVgIG9yIGBGQVJHQVRFX1NQT1RgIGNhcGFjaXR5IHByb3ZpZGVycy4gVGhlIEFXUyBGYXJnYXRlIGNhcGFjaXR5IHByb3ZpZGVycyBhcmUgYXZhaWxhYmxlIHRvIGFsbCBhY2NvdW50cyBhbmQgb25seSBuZWVkIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCBhIGNsdXN0ZXIgdG8gYmUgdXNlZCBpbiBhIGNhcGFjaXR5IHByb3ZpZGVyIHN0cmF0ZWd5LlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXNlcnZpY2UtY2FwYWNpdHlwcm92aWRlcnN0cmF0ZWd5aXRlbS5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3lJdGVtUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlICpiYXNlKiB2YWx1ZSBkZXNpZ25hdGVzIGhvdyBtYW55IHRhc2tzLCBhdCBhIG1pbmltdW0sIHRvIHJ1biBvbiB0aGUgc3BlY2lmaWVkIGNhcGFjaXR5IHByb3ZpZGVyLiBPbmx5IG9uZSBjYXBhY2l0eSBwcm92aWRlciBpbiBhIGNhcGFjaXR5IHByb3ZpZGVyIHN0cmF0ZWd5IGNhbiBoYXZlIGEgKmJhc2UqIGRlZmluZWQuIElmIG5vIHZhbHVlIGlzIHNwZWNpZmllZCwgdGhlIGRlZmF1bHQgdmFsdWUgb2YgYDBgIGlzIHVzZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXNlcnZpY2UtY2FwYWNpdHlwcm92aWRlcnN0cmF0ZWd5aXRlbS5odG1sI2Nmbi1lY3Mtc2VydmljZS1jYXBhY2l0eXByb3ZpZGVyc3RyYXRlZ3lpdGVtLWJhc2VcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGJhc2U/OiBudW1iZXI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgc2hvcnQgbmFtZSBvZiB0aGUgY2FwYWNpdHkgcHJvdmlkZXIuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXNlcnZpY2UtY2FwYWNpdHlwcm92aWRlcnN0cmF0ZWd5aXRlbS5odG1sI2Nmbi1lY3Mtc2VydmljZS1jYXBhY2l0eXByb3ZpZGVyc3RyYXRlZ3lpdGVtLWNhcGFjaXR5cHJvdmlkZXJcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNhcGFjaXR5UHJvdmlkZXI/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgKndlaWdodCogdmFsdWUgZGVzaWduYXRlcyB0aGUgcmVsYXRpdmUgcGVyY2VudGFnZSBvZiB0aGUgdG90YWwgbnVtYmVyIG9mIHRhc2tzIGxhdW5jaGVkIHRoYXQgc2hvdWxkIHVzZSB0aGUgc3BlY2lmaWVkIGNhcGFjaXR5IHByb3ZpZGVyLiBUaGUgYHdlaWdodGAgdmFsdWUgaXMgdGFrZW4gaW50byBjb25zaWRlcmF0aW9uIGFmdGVyIHRoZSBgYmFzZWAgdmFsdWUsIGlmIGRlZmluZWQsIGlzIHNhdGlzZmllZC5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgbm8gYHdlaWdodGAgdmFsdWUgaXMgc3BlY2lmaWVkLCB0aGUgZGVmYXVsdCB2YWx1ZSBvZiBgMGAgaXMgdXNlZC4gV2hlbiBtdWx0aXBsZSBjYXBhY2l0eSBwcm92aWRlcnMgYXJlIHNwZWNpZmllZCB3aXRoaW4gYSBjYXBhY2l0eSBwcm92aWRlciBzdHJhdGVneSwgYXQgbGVhc3Qgb25lIG9mIHRoZSBjYXBhY2l0eSBwcm92aWRlcnMgbXVzdCBoYXZlIGEgd2VpZ2h0IHZhbHVlIGdyZWF0ZXIgdGhhbiB6ZXJvIGFuZCBhbnkgY2FwYWNpdHkgcHJvdmlkZXJzIHdpdGggYSB3ZWlnaHQgb2YgYDBgIGNhbid0IGJlIHVzZWQgdG8gcGxhY2UgdGFza3MuIElmIHlvdSBzcGVjaWZ5IG11bHRpcGxlIGNhcGFjaXR5IHByb3ZpZGVycyBpbiBhIHN0cmF0ZWd5IHRoYXQgYWxsIGhhdmUgYSB3ZWlnaHQgb2YgYDBgICwgYW55IGBSdW5UYXNrYCBvciBgQ3JlYXRlU2VydmljZWAgYWN0aW9ucyB1c2luZyB0aGUgY2FwYWNpdHkgcHJvdmlkZXIgc3RyYXRlZ3kgd2lsbCBmYWlsLlxuICAgICAgICAgKlxuICAgICAgICAgKiBBbiBleGFtcGxlIHNjZW5hcmlvIGZvciB1c2luZyB3ZWlnaHRzIGlzIGRlZmluaW5nIGEgc3RyYXRlZ3kgdGhhdCBjb250YWlucyB0d28gY2FwYWNpdHkgcHJvdmlkZXJzIGFuZCBib3RoIGhhdmUgYSB3ZWlnaHQgb2YgYDFgICwgdGhlbiB3aGVuIHRoZSBgYmFzZWAgaXMgc2F0aXNmaWVkLCB0aGUgdGFza3Mgd2lsbCBiZSBzcGxpdCBldmVubHkgYWNyb3NzIHRoZSB0d28gY2FwYWNpdHkgcHJvdmlkZXJzLiBVc2luZyB0aGF0IHNhbWUgbG9naWMsIGlmIHlvdSBzcGVjaWZ5IGEgd2VpZ2h0IG9mIGAxYCBmb3IgKmNhcGFjaXR5UHJvdmlkZXJBKiBhbmQgYSB3ZWlnaHQgb2YgYDRgIGZvciAqY2FwYWNpdHlQcm92aWRlckIqICwgdGhlbiBmb3IgZXZlcnkgb25lIHRhc2sgdGhhdCdzIHJ1biB1c2luZyAqY2FwYWNpdHlQcm92aWRlckEqICwgZm91ciB0YXNrcyB3b3VsZCB1c2UgKmNhcGFjaXR5UHJvdmlkZXJCKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXNlcnZpY2UtY2FwYWNpdHlwcm92aWRlcnN0cmF0ZWd5aXRlbS5odG1sI2Nmbi1lY3Mtc2VydmljZS1jYXBhY2l0eXByb3ZpZGVyc3RyYXRlZ3lpdGVtLXdlaWdodFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgd2VpZ2h0PzogbnVtYmVyO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3lJdGVtUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENhcGFjaXR5UHJvdmlkZXJTdHJhdGVneUl0ZW1Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5TZXJ2aWNlX0NhcGFjaXR5UHJvdmlkZXJTdHJhdGVneUl0ZW1Qcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2Jhc2UnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMuYmFzZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY2FwYWNpdHlQcm92aWRlcicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jYXBhY2l0eVByb3ZpZGVyKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd3ZWlnaHQnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMud2VpZ2h0KSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneUl0ZW1Qcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpTZXJ2aWNlLkNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneUl0ZW1gIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENhcGFjaXR5UHJvdmlkZXJTdHJhdGVneUl0ZW1Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpTZXJ2aWNlLkNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneUl0ZW1gIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuU2VydmljZUNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneUl0ZW1Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuU2VydmljZV9DYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3lJdGVtUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEJhc2U6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuYmFzZSksXG4gICAgICAgIENhcGFjaXR5UHJvdmlkZXI6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY2FwYWNpdHlQcm92aWRlciksXG4gICAgICAgIFdlaWdodDogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy53ZWlnaHQpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5TZXJ2aWNlQ2FwYWNpdHlQcm92aWRlclN0cmF0ZWd5SXRlbVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuU2VydmljZS5DYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3lJdGVtUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuU2VydmljZS5DYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3lJdGVtUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdiYXNlJywgJ0Jhc2UnLCBwcm9wZXJ0aWVzLkJhc2UgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuQmFzZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY2FwYWNpdHlQcm92aWRlcicsICdDYXBhY2l0eVByb3ZpZGVyJywgcHJvcGVydGllcy5DYXBhY2l0eVByb3ZpZGVyICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNhcGFjaXR5UHJvdmlkZXIpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3dlaWdodCcsICdXZWlnaHQnLCBwcm9wZXJ0aWVzLldlaWdodCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5XZWlnaHQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5TZXJ2aWNlIHtcbiAgICAvKipcbiAgICAgKiBPbmUgb2YgdGhlIG1ldGhvZHMgd2hpY2ggcHJvdmlkZSBhIHdheSBmb3IgeW91IHRvIHF1aWNrbHkgaWRlbnRpZnkgd2hlbiBhIGRlcGxveW1lbnQgaGFzIGZhaWxlZCwgYW5kIHRoZW4gdG8gb3B0aW9uYWxseSByb2xsIGJhY2sgdGhlIGZhaWx1cmUgdG8gdGhlIGxhc3Qgd29ya2luZyBkZXBsb3ltZW50LlxuICAgICAqXG4gICAgICogV2hlbiB0aGUgYWxhcm1zIGFyZSBnZW5lcmF0ZWQsIEFtYXpvbiBFQ1Mgc2V0cyB0aGUgc2VydmljZSBkZXBsb3ltZW50IHRvIGZhaWxlZC4gU2V0IHRoZSByb2xsYmFjayBwYXJhbWV0ZXIgdG8gaGF2ZSBBbWF6b24gRUNTIHRvIHJvbGwgYmFjayB5b3VyIHNlcnZpY2UgdG8gdGhlIGxhc3QgY29tcGxldGVkIGRlcGxveW1lbnQgYWZ0ZXIgYSBmYWlsdXJlLlxuICAgICAqXG4gICAgICogWW91IGNhbiBvbmx5IHVzZSB0aGUgYERlcGxveW1lbnRBbGFybXNgIG1ldGhvZCB0byBkZXRlY3QgZmFpbHVyZXMgd2hlbiB0aGUgYERlcGxveW1lbnRDb250cm9sbGVyYCBpcyBzZXQgdG8gYEVDU2AgKHJvbGxpbmcgdXBkYXRlKS5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1JvbGxpbmcgdXBkYXRlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9kZXBsb3ltZW50LXR5cGUtZWNzLmh0bWwpIGluIHRoZSAqKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSoqIC5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLWRlcGxveW1lbnRhbGFybXMuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgRGVwbG95bWVudEFsYXJtc1Byb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIE9uZSBvciBtb3JlIENsb3VkV2F0Y2ggYWxhcm0gbmFtZXMuIFVzZSBhIFwiLFwiIHRvIHNlcGFyYXRlIHRoZSBhbGFybXMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXNlcnZpY2UtZGVwbG95bWVudGFsYXJtcy5odG1sI2Nmbi1lY3Mtc2VydmljZS1kZXBsb3ltZW50YWxhcm1zLWFsYXJtbmFtZXNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGFsYXJtTmFtZXM6IHN0cmluZ1tdO1xuICAgICAgICAvKipcbiAgICAgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRvIHVzZSB0aGUgQ2xvdWRXYXRjaCBhbGFybSBvcHRpb24gaW4gdGhlIHNlcnZpY2UgZGVwbG95bWVudCBwcm9jZXNzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLWRlcGxveW1lbnRhbGFybXMuaHRtbCNjZm4tZWNzLXNlcnZpY2UtZGVwbG95bWVudGFsYXJtcy1lbmFibGVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGVuYWJsZTogYm9vbGVhbiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERldGVybWluZXMgd2hldGhlciB0byBjb25maWd1cmUgQW1hem9uIEVDUyB0byByb2xsIGJhY2sgdGhlIHNlcnZpY2UgaWYgYSBzZXJ2aWNlIGRlcGxveW1lbnQgZmFpbHMuIElmIHJvbGxiYWNrIGlzIHVzZWQsIHdoZW4gYSBzZXJ2aWNlIGRlcGxveW1lbnQgZmFpbHMsIHRoZSBzZXJ2aWNlIGlzIHJvbGxlZCBiYWNrIHRvIHRoZSBsYXN0IGRlcGxveW1lbnQgdGhhdCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLWRlcGxveW1lbnRhbGFybXMuaHRtbCNjZm4tZWNzLXNlcnZpY2UtZGVwbG95bWVudGFsYXJtcy1yb2xsYmFja1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcm9sbGJhY2s6IGJvb2xlYW4gfCBjZGsuSVJlc29sdmFibGU7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYERlcGxveW1lbnRBbGFybXNQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgRGVwbG95bWVudEFsYXJtc1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblNlcnZpY2VfRGVwbG95bWVudEFsYXJtc1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignYWxhcm1OYW1lcycsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5hbGFybU5hbWVzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdhbGFybU5hbWVzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5hbGFybU5hbWVzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdlbmFibGUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMuZW5hYmxlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdlbmFibGUnLCBjZGsudmFsaWRhdGVCb29sZWFuKShwcm9wZXJ0aWVzLmVuYWJsZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncm9sbGJhY2snLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMucm9sbGJhY2spKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3JvbGxiYWNrJywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5yb2xsYmFjaykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJEZXBsb3ltZW50QWxhcm1zUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6U2VydmljZS5EZXBsb3ltZW50QWxhcm1zYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBEZXBsb3ltZW50QWxhcm1zUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6U2VydmljZS5EZXBsb3ltZW50QWxhcm1zYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblNlcnZpY2VEZXBsb3ltZW50QWxhcm1zUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblNlcnZpY2VfRGVwbG95bWVudEFsYXJtc1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBBbGFybU5hbWVzOiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5hbGFybU5hbWVzKSxcbiAgICAgICAgRW5hYmxlOiBjZGsuYm9vbGVhblRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5lbmFibGUpLFxuICAgICAgICBSb2xsYmFjazogY2RrLmJvb2xlYW5Ub0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucm9sbGJhY2spLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5TZXJ2aWNlRGVwbG95bWVudEFsYXJtc1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuU2VydmljZS5EZXBsb3ltZW50QWxhcm1zUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuU2VydmljZS5EZXBsb3ltZW50QWxhcm1zUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdhbGFybU5hbWVzJywgJ0FsYXJtTmFtZXMnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuQWxhcm1OYW1lcykpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZW5hYmxlJywgJ0VuYWJsZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Qm9vbGVhbihwcm9wZXJ0aWVzLkVuYWJsZSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncm9sbGJhY2snLCAnUm9sbGJhY2snLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5Sb2xsYmFjaykpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblNlcnZpY2Uge1xuICAgIC8qKlxuICAgICAqID4gVGhlIGRlcGxveW1lbnQgY2lyY3VpdCBicmVha2VyIGNhbiBvbmx5IGJlIHVzZWQgZm9yIHNlcnZpY2VzIHVzaW5nIHRoZSByb2xsaW5nIHVwZGF0ZSAoIGBFQ1NgICkgZGVwbG95bWVudCB0eXBlLlxuICAgICAqXG4gICAgICogVGhlICpkZXBsb3ltZW50IGNpcmN1aXQgYnJlYWtlciogZGV0ZXJtaW5lcyB3aGV0aGVyIGEgc2VydmljZSBkZXBsb3ltZW50IHdpbGwgZmFpbCBpZiB0aGUgc2VydmljZSBjYW4ndCByZWFjaCBhIHN0ZWFkeSBzdGF0ZS4gSWYgaXQgaXMgdHVybmVkIG9uLCBhIHNlcnZpY2UgZGVwbG95bWVudCB3aWxsIHRyYW5zaXRpb24gdG8gYSBmYWlsZWQgc3RhdGUgYW5kIHN0b3AgbGF1bmNoaW5nIG5ldyB0YXNrcy4gWW91IGNhbiBhbHNvIGNvbmZpZ3VyZSBBbWF6b24gRUNTIHRvIHJvbGwgYmFjayB5b3VyIHNlcnZpY2UgdG8gdGhlIGxhc3QgY29tcGxldGVkIGRlcGxveW1lbnQgYWZ0ZXIgYSBmYWlsdXJlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtSb2xsaW5nIHVwZGF0ZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvZGVwbG95bWVudC10eXBlLWVjcy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXNlcnZpY2UtZGVwbG95bWVudGNpcmN1aXRicmVha2VyLmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIERlcGxveW1lbnRDaXJjdWl0QnJlYWtlclByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERldGVybWluZXMgd2hldGhlciB0byB1c2UgdGhlIGRlcGxveW1lbnQgY2lyY3VpdCBicmVha2VyIGxvZ2ljIGZvciB0aGUgc2VydmljZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1kZXBsb3ltZW50Y2lyY3VpdGJyZWFrZXIuaHRtbCNjZm4tZWNzLXNlcnZpY2UtZGVwbG95bWVudGNpcmN1aXRicmVha2VyLWVuYWJsZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgZW5hYmxlOiBib29sZWFuIHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRvIGNvbmZpZ3VyZSBBbWF6b24gRUNTIHRvIHJvbGwgYmFjayB0aGUgc2VydmljZSBpZiBhIHNlcnZpY2UgZGVwbG95bWVudCBmYWlscy4gSWYgcm9sbGJhY2sgaXMgb24sIHdoZW4gYSBzZXJ2aWNlIGRlcGxveW1lbnQgZmFpbHMsIHRoZSBzZXJ2aWNlIGlzIHJvbGxlZCBiYWNrIHRvIHRoZSBsYXN0IGRlcGxveW1lbnQgdGhhdCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLWRlcGxveW1lbnRjaXJjdWl0YnJlYWtlci5odG1sI2Nmbi1lY3Mtc2VydmljZS1kZXBsb3ltZW50Y2lyY3VpdGJyZWFrZXItcm9sbGJhY2tcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHJvbGxiYWNrOiBib29sZWFuIHwgY2RrLklSZXNvbHZhYmxlO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBEZXBsb3ltZW50Q2lyY3VpdEJyZWFrZXJQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgRGVwbG95bWVudENpcmN1aXRCcmVha2VyUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuU2VydmljZV9EZXBsb3ltZW50Q2lyY3VpdEJyZWFrZXJQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2VuYWJsZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5lbmFibGUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2VuYWJsZScsIGNkay52YWxpZGF0ZUJvb2xlYW4pKHByb3BlcnRpZXMuZW5hYmxlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyb2xsYmFjaycsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5yb2xsYmFjaykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncm9sbGJhY2snLCBjZGsudmFsaWRhdGVCb29sZWFuKShwcm9wZXJ0aWVzLnJvbGxiYWNrKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkRlcGxveW1lbnRDaXJjdWl0QnJlYWtlclByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlNlcnZpY2UuRGVwbG95bWVudENpcmN1aXRCcmVha2VyYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBEZXBsb3ltZW50Q2lyY3VpdEJyZWFrZXJQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpTZXJ2aWNlLkRlcGxveW1lbnRDaXJjdWl0QnJlYWtlcmAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5TZXJ2aWNlRGVwbG95bWVudENpcmN1aXRCcmVha2VyUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblNlcnZpY2VfRGVwbG95bWVudENpcmN1aXRCcmVha2VyUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEVuYWJsZTogY2RrLmJvb2xlYW5Ub0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZW5hYmxlKSxcbiAgICAgICAgUm9sbGJhY2s6IGNkay5ib29sZWFuVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnJvbGxiYWNrKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuU2VydmljZURlcGxveW1lbnRDaXJjdWl0QnJlYWtlclByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuU2VydmljZS5EZXBsb3ltZW50Q2lyY3VpdEJyZWFrZXJQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5TZXJ2aWNlLkRlcGxveW1lbnRDaXJjdWl0QnJlYWtlclByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZW5hYmxlJywgJ0VuYWJsZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Qm9vbGVhbihwcm9wZXJ0aWVzLkVuYWJsZSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncm9sbGJhY2snLCAnUm9sbGJhY2snLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5Sb2xsYmFjaykpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblNlcnZpY2Uge1xuICAgIC8qKlxuICAgICAqIFRoZSBgRGVwbG95bWVudENvbmZpZ3VyYXRpb25gIHByb3BlcnR5IHNwZWNpZmllcyBvcHRpb25hbCBkZXBsb3ltZW50IHBhcmFtZXRlcnMgdGhhdCBjb250cm9sIGhvdyBtYW55IHRhc2tzIHJ1biBkdXJpbmcgdGhlIGRlcGxveW1lbnQgYW5kIHRoZSBvcmRlcmluZyBvZiBzdG9wcGluZyBhbmQgc3RhcnRpbmcgdGFza3MuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1kZXBsb3ltZW50Y29uZmlndXJhdGlvbi5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBEZXBsb3ltZW50Q29uZmlndXJhdGlvblByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluZm9ybWF0aW9uIGFib3V0IHRoZSBDbG91ZFdhdGNoIGFsYXJtcy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1kZXBsb3ltZW50Y29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3Mtc2VydmljZS1kZXBsb3ltZW50Y29uZmlndXJhdGlvbi1hbGFybXNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGFsYXJtcz86IENmblNlcnZpY2UuRGVwbG95bWVudEFsYXJtc1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogPiBUaGUgZGVwbG95bWVudCBjaXJjdWl0IGJyZWFrZXIgY2FuIG9ubHkgYmUgdXNlZCBmb3Igc2VydmljZXMgdXNpbmcgdGhlIHJvbGxpbmcgdXBkYXRlICggYEVDU2AgKSBkZXBsb3ltZW50IHR5cGUuXG4gICAgICAgICAqXG4gICAgICAgICAqIFRoZSAqZGVwbG95bWVudCBjaXJjdWl0IGJyZWFrZXIqIGRldGVybWluZXMgd2hldGhlciBhIHNlcnZpY2UgZGVwbG95bWVudCB3aWxsIGZhaWwgaWYgdGhlIHNlcnZpY2UgY2FuJ3QgcmVhY2ggYSBzdGVhZHkgc3RhdGUuIElmIHlvdSB1c2UgdGhlIGRlcGxveW1lbnQgY2lyY3VpdCBicmVha2VyLCBhIHNlcnZpY2UgZGVwbG95bWVudCB3aWxsIHRyYW5zaXRpb24gdG8gYSBmYWlsZWQgc3RhdGUgYW5kIHN0b3AgbGF1bmNoaW5nIG5ldyB0YXNrcy4gSWYgeW91IHVzZSB0aGUgcm9sbGJhY2sgb3B0aW9uLCB3aGVuIGEgc2VydmljZSBkZXBsb3ltZW50IGZhaWxzLCB0aGUgc2VydmljZSBpcyByb2xsZWQgYmFjayB0byB0aGUgbGFzdCBkZXBsb3ltZW50IHRoYXQgY29tcGxldGVkIHN1Y2Nlc3NmdWxseS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbUm9sbGluZyB1cGRhdGVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2RlcGxveW1lbnQtdHlwZS1lY3MuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXNlcnZpY2UtZGVwbG95bWVudGNvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLXNlcnZpY2UtZGVwbG95bWVudGNvbmZpZ3VyYXRpb24tZGVwbG95bWVudGNpcmN1aXRicmVha2VyXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBkZXBsb3ltZW50Q2lyY3VpdEJyZWFrZXI/OiBDZm5TZXJ2aWNlLkRlcGxveW1lbnRDaXJjdWl0QnJlYWtlclByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogSWYgYSBzZXJ2aWNlIGlzIHVzaW5nIHRoZSByb2xsaW5nIHVwZGF0ZSAoIGBFQ1NgICkgZGVwbG95bWVudCB0eXBlLCB0aGUgYG1heGltdW1QZXJjZW50YCBwYXJhbWV0ZXIgcmVwcmVzZW50cyBhbiB1cHBlciBsaW1pdCBvbiB0aGUgbnVtYmVyIG9mIHlvdXIgc2VydmljZSdzIHRhc2tzIHRoYXQgYXJlIGFsbG93ZWQgaW4gdGhlIGBSVU5OSU5HYCBvciBgUEVORElOR2Agc3RhdGUgZHVyaW5nIGEgZGVwbG95bWVudCwgYXMgYSBwZXJjZW50YWdlIG9mIHRoZSBgZGVzaXJlZENvdW50YCAocm91bmRlZCBkb3duIHRvIHRoZSBuZWFyZXN0IGludGVnZXIpLiBUaGlzIHBhcmFtZXRlciBlbmFibGVzIHlvdSB0byBkZWZpbmUgdGhlIGRlcGxveW1lbnQgYmF0Y2ggc2l6ZS4gRm9yIGV4YW1wbGUsIGlmIHlvdXIgc2VydmljZSBpcyB1c2luZyB0aGUgYFJFUExJQ0FgIHNlcnZpY2Ugc2NoZWR1bGVyIGFuZCBoYXMgYSBgZGVzaXJlZENvdW50YCBvZiBmb3VyIHRhc2tzIGFuZCBhIGBtYXhpbXVtUGVyY2VudGAgdmFsdWUgb2YgMjAwJSwgdGhlIHNjaGVkdWxlciBtYXkgc3RhcnQgZm91ciBuZXcgdGFza3MgYmVmb3JlIHN0b3BwaW5nIHRoZSBmb3VyIG9sZGVyIHRhc2tzIChwcm92aWRlZCB0aGF0IHRoZSBjbHVzdGVyIHJlc291cmNlcyByZXF1aXJlZCB0byBkbyB0aGlzIGFyZSBhdmFpbGFibGUpLiBUaGUgZGVmYXVsdCBgbWF4aW11bVBlcmNlbnRgIHZhbHVlIGZvciBhIHNlcnZpY2UgdXNpbmcgdGhlIGBSRVBMSUNBYCBzZXJ2aWNlIHNjaGVkdWxlciBpcyAyMDAlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiBhIHNlcnZpY2UgaXMgdXNpbmcgZWl0aGVyIHRoZSBibHVlL2dyZWVuICggYENPREVfREVQTE9ZYCApIG9yIGBFWFRFUk5BTGAgZGVwbG95bWVudCB0eXBlcyBhbmQgdGFza3MgdGhhdCB1c2UgdGhlIEVDMiBsYXVuY2ggdHlwZSwgdGhlICptYXhpbXVtIHBlcmNlbnQqIHZhbHVlIGlzIHNldCB0byB0aGUgZGVmYXVsdCB2YWx1ZSBhbmQgaXMgdXNlZCB0byBkZWZpbmUgdGhlIHVwcGVyIGxpbWl0IG9uIHRoZSBudW1iZXIgb2YgdGhlIHRhc2tzIGluIHRoZSBzZXJ2aWNlIHRoYXQgcmVtYWluIGluIHRoZSBgUlVOTklOR2Agc3RhdGUgd2hpbGUgdGhlIGNvbnRhaW5lciBpbnN0YW5jZXMgYXJlIGluIHRoZSBgRFJBSU5JTkdgIHN0YXRlLiBJZiB0aGUgdGFza3MgaW4gdGhlIHNlcnZpY2UgdXNlIHRoZSBGYXJnYXRlIGxhdW5jaCB0eXBlLCB0aGUgbWF4aW11bSBwZXJjZW50IHZhbHVlIGlzIG5vdCB1c2VkLCBhbHRob3VnaCBpdCBpcyByZXR1cm5lZCB3aGVuIGRlc2NyaWJpbmcgeW91ciBzZXJ2aWNlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLWRlcGxveW1lbnRjb25maWd1cmF0aW9uLmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLWRlcGxveW1lbnRjb25maWd1cmF0aW9uLW1heGltdW1wZXJjZW50XG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBtYXhpbXVtUGVyY2VudD86IG51bWJlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIElmIGEgc2VydmljZSBpcyB1c2luZyB0aGUgcm9sbGluZyB1cGRhdGUgKCBgRUNTYCApIGRlcGxveW1lbnQgdHlwZSwgdGhlIGBtaW5pbXVtSGVhbHRoeVBlcmNlbnRgIHJlcHJlc2VudHMgYSBsb3dlciBsaW1pdCBvbiB0aGUgbnVtYmVyIG9mIHlvdXIgc2VydmljZSdzIHRhc2tzIHRoYXQgbXVzdCByZW1haW4gaW4gdGhlIGBSVU5OSU5HYCBzdGF0ZSBkdXJpbmcgYSBkZXBsb3ltZW50LCBhcyBhIHBlcmNlbnRhZ2Ugb2YgdGhlIGBkZXNpcmVkQ291bnRgIChyb3VuZGVkIHVwIHRvIHRoZSBuZWFyZXN0IGludGVnZXIpLiBUaGlzIHBhcmFtZXRlciBlbmFibGVzIHlvdSB0byBkZXBsb3kgd2l0aG91dCB1c2luZyBhZGRpdGlvbmFsIGNsdXN0ZXIgY2FwYWNpdHkuIEZvciBleGFtcGxlLCBpZiB5b3VyIHNlcnZpY2UgaGFzIGEgYGRlc2lyZWRDb3VudGAgb2YgZm91ciB0YXNrcyBhbmQgYSBgbWluaW11bUhlYWx0aHlQZXJjZW50YCBvZiA1MCUsIHRoZSBzZXJ2aWNlIHNjaGVkdWxlciBtYXkgc3RvcCB0d28gZXhpc3RpbmcgdGFza3MgdG8gZnJlZSB1cCBjbHVzdGVyIGNhcGFjaXR5IGJlZm9yZSBzdGFydGluZyB0d28gbmV3IHRhc2tzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3Igc2VydmljZXMgdGhhdCAqZG8gbm90KiB1c2UgYSBsb2FkIGJhbGFuY2VyLCB0aGUgZm9sbG93aW5nIHNob3VsZCBiZSBub3RlZDpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBBIHNlcnZpY2UgaXMgY29uc2lkZXJlZCBoZWFsdGh5IGlmIGFsbCBlc3NlbnRpYWwgY29udGFpbmVycyB3aXRoaW4gdGhlIHRhc2tzIGluIHRoZSBzZXJ2aWNlIHBhc3MgdGhlaXIgaGVhbHRoIGNoZWNrcy5cbiAgICAgICAgICogLSBJZiBhIHRhc2sgaGFzIG5vIGVzc2VudGlhbCBjb250YWluZXJzIHdpdGggYSBoZWFsdGggY2hlY2sgZGVmaW5lZCwgdGhlIHNlcnZpY2Ugc2NoZWR1bGVyIHdpbGwgd2FpdCBmb3IgNDAgc2Vjb25kcyBhZnRlciBhIHRhc2sgcmVhY2hlcyBhIGBSVU5OSU5HYCBzdGF0ZSBiZWZvcmUgdGhlIHRhc2sgaXMgY291bnRlZCB0b3dhcmRzIHRoZSBtaW5pbXVtIGhlYWx0aHkgcGVyY2VudCB0b3RhbC5cbiAgICAgICAgICogLSBJZiBhIHRhc2sgaGFzIG9uZSBvciBtb3JlIGVzc2VudGlhbCBjb250YWluZXJzIHdpdGggYSBoZWFsdGggY2hlY2sgZGVmaW5lZCwgdGhlIHNlcnZpY2Ugc2NoZWR1bGVyIHdpbGwgd2FpdCBmb3IgdGhlIHRhc2sgdG8gcmVhY2ggYSBoZWFsdGh5IHN0YXR1cyBiZWZvcmUgY291bnRpbmcgaXQgdG93YXJkcyB0aGUgbWluaW11bSBoZWFsdGh5IHBlcmNlbnQgdG90YWwuIEEgdGFzayBpcyBjb25zaWRlcmVkIGhlYWx0aHkgd2hlbiBhbGwgZXNzZW50aWFsIGNvbnRhaW5lcnMgd2l0aGluIHRoZSB0YXNrIGhhdmUgcGFzc2VkIHRoZWlyIGhlYWx0aCBjaGVja3MuIFRoZSBhbW91bnQgb2YgdGltZSB0aGUgc2VydmljZSBzY2hlZHVsZXIgY2FuIHdhaXQgZm9yIGlzIGRldGVybWluZWQgYnkgdGhlIGNvbnRhaW5lciBoZWFsdGggY2hlY2sgc2V0dGluZ3MuXG4gICAgICAgICAqXG4gICAgICAgICAqIEZvciBzZXJ2aWNlcyBhcmUgdGhhdCAqZG8qIHVzZSBhIGxvYWQgYmFsYW5jZXIsIHRoZSBmb2xsb3dpbmcgc2hvdWxkIGJlIG5vdGVkOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIElmIGEgdGFzayBoYXMgbm8gZXNzZW50aWFsIGNvbnRhaW5lcnMgd2l0aCBhIGhlYWx0aCBjaGVjayBkZWZpbmVkLCB0aGUgc2VydmljZSBzY2hlZHVsZXIgd2lsbCB3YWl0IGZvciB0aGUgbG9hZCBiYWxhbmNlciB0YXJnZXQgZ3JvdXAgaGVhbHRoIGNoZWNrIHRvIHJldHVybiBhIGhlYWx0aHkgc3RhdHVzIGJlZm9yZSBjb3VudGluZyB0aGUgdGFzayB0b3dhcmRzIHRoZSBtaW5pbXVtIGhlYWx0aHkgcGVyY2VudCB0b3RhbC5cbiAgICAgICAgICogLSBJZiBhIHRhc2sgaGFzIGFuIGVzc2VudGlhbCBjb250YWluZXIgd2l0aCBhIGhlYWx0aCBjaGVjayBkZWZpbmVkLCB0aGUgc2VydmljZSBzY2hlZHVsZXIgd2lsbCB3YWl0IGZvciBib3RoIHRoZSB0YXNrIHRvIHJlYWNoIGEgaGVhbHRoeSBzdGF0dXMgYW5kIHRoZSBsb2FkIGJhbGFuY2VyIHRhcmdldCBncm91cCBoZWFsdGggY2hlY2sgdG8gcmV0dXJuIGEgaGVhbHRoeSBzdGF0dXMgYmVmb3JlIGNvdW50aW5nIHRoZSB0YXNrIHRvd2FyZHMgdGhlIG1pbmltdW0gaGVhbHRoeSBwZXJjZW50IHRvdGFsLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiBhIHNlcnZpY2UgaXMgdXNpbmcgZWl0aGVyIHRoZSBibHVlL2dyZWVuICggYENPREVfREVQTE9ZYCApIG9yIGBFWFRFUk5BTGAgZGVwbG95bWVudCB0eXBlcyBhbmQgaXMgcnVubmluZyB0YXNrcyB0aGF0IHVzZSB0aGUgRUMyIGxhdW5jaCB0eXBlLCB0aGUgKm1pbmltdW0gaGVhbHRoeSBwZXJjZW50KiB2YWx1ZSBpcyBzZXQgdG8gdGhlIGRlZmF1bHQgdmFsdWUgYW5kIGlzIHVzZWQgdG8gZGVmaW5lIHRoZSBsb3dlciBsaW1pdCBvbiB0aGUgbnVtYmVyIG9mIHRoZSB0YXNrcyBpbiB0aGUgc2VydmljZSB0aGF0IHJlbWFpbiBpbiB0aGUgYFJVTk5JTkdgIHN0YXRlIHdoaWxlIHRoZSBjb250YWluZXIgaW5zdGFuY2VzIGFyZSBpbiB0aGUgYERSQUlOSU5HYCBzdGF0ZS4gSWYgYSBzZXJ2aWNlIGlzIHVzaW5nIGVpdGhlciB0aGUgYmx1ZS9ncmVlbiAoIGBDT0RFX0RFUExPWWAgKSBvciBgRVhURVJOQUxgIGRlcGxveW1lbnQgdHlwZXMgYW5kIGlzIHJ1bm5pbmcgdGFza3MgdGhhdCB1c2UgdGhlIEZhcmdhdGUgbGF1bmNoIHR5cGUsIHRoZSBtaW5pbXVtIGhlYWx0aHkgcGVyY2VudCB2YWx1ZSBpcyBub3QgdXNlZCwgYWx0aG91Z2ggaXQgaXMgcmV0dXJuZWQgd2hlbiBkZXNjcmliaW5nIHlvdXIgc2VydmljZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1kZXBsb3ltZW50Y29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3Mtc2VydmljZS1kZXBsb3ltZW50Y29uZmlndXJhdGlvbi1taW5pbXVtaGVhbHRoeXBlcmNlbnRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IG1pbmltdW1IZWFsdGh5UGVyY2VudD86IG51bWJlcjtcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgRGVwbG95bWVudENvbmZpZ3VyYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgRGVwbG95bWVudENvbmZpZ3VyYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5TZXJ2aWNlX0RlcGxveW1lbnRDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdhbGFybXMnLCBDZm5TZXJ2aWNlX0RlcGxveW1lbnRBbGFybXNQcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5hbGFybXMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2RlcGxveW1lbnRDaXJjdWl0QnJlYWtlcicsIENmblNlcnZpY2VfRGVwbG95bWVudENpcmN1aXRCcmVha2VyUHJvcGVydHlWYWxpZGF0b3IpKHByb3BlcnRpZXMuZGVwbG95bWVudENpcmN1aXRCcmVha2VyKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdtYXhpbXVtUGVyY2VudCcsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5tYXhpbXVtUGVyY2VudCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbWluaW11bUhlYWx0aHlQZXJjZW50JywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLm1pbmltdW1IZWFsdGh5UGVyY2VudCkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJEZXBsb3ltZW50Q29uZmlndXJhdGlvblByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlNlcnZpY2UuRGVwbG95bWVudENvbmZpZ3VyYXRpb25gIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYERlcGxveW1lbnRDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6U2VydmljZS5EZXBsb3ltZW50Q29uZmlndXJhdGlvbmAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5TZXJ2aWNlRGVwbG95bWVudENvbmZpZ3VyYXRpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuU2VydmljZV9EZXBsb3ltZW50Q29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBBbGFybXM6IGNmblNlcnZpY2VEZXBsb3ltZW50QWxhcm1zUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuYWxhcm1zKSxcbiAgICAgICAgRGVwbG95bWVudENpcmN1aXRCcmVha2VyOiBjZm5TZXJ2aWNlRGVwbG95bWVudENpcmN1aXRCcmVha2VyUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZGVwbG95bWVudENpcmN1aXRCcmVha2VyKSxcbiAgICAgICAgTWF4aW11bVBlcmNlbnQ6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubWF4aW11bVBlcmNlbnQpLFxuICAgICAgICBNaW5pbXVtSGVhbHRoeVBlcmNlbnQ6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubWluaW11bUhlYWx0aHlQZXJjZW50KSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuU2VydmljZURlcGxveW1lbnRDb25maWd1cmF0aW9uUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5TZXJ2aWNlLkRlcGxveW1lbnRDb25maWd1cmF0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuU2VydmljZS5EZXBsb3ltZW50Q29uZmlndXJhdGlvblByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnYWxhcm1zJywgJ0FsYXJtcycsIHByb3BlcnRpZXMuQWxhcm1zICE9IG51bGwgPyBDZm5TZXJ2aWNlRGVwbG95bWVudEFsYXJtc1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuQWxhcm1zKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdkZXBsb3ltZW50Q2lyY3VpdEJyZWFrZXInLCAnRGVwbG95bWVudENpcmN1aXRCcmVha2VyJywgcHJvcGVydGllcy5EZXBsb3ltZW50Q2lyY3VpdEJyZWFrZXIgIT0gbnVsbCA/IENmblNlcnZpY2VEZXBsb3ltZW50Q2lyY3VpdEJyZWFrZXJQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLkRlcGxveW1lbnRDaXJjdWl0QnJlYWtlcikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbWF4aW11bVBlcmNlbnQnLCAnTWF4aW11bVBlcmNlbnQnLCBwcm9wZXJ0aWVzLk1heGltdW1QZXJjZW50ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLk1heGltdW1QZXJjZW50KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdtaW5pbXVtSGVhbHRoeVBlcmNlbnQnLCAnTWluaW11bUhlYWx0aHlQZXJjZW50JywgcHJvcGVydGllcy5NaW5pbXVtSGVhbHRoeVBlcmNlbnQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuTWluaW11bUhlYWx0aHlQZXJjZW50KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuU2VydmljZSB7XG4gICAgLyoqXG4gICAgICogVGhlIGRlcGxveW1lbnQgY29udHJvbGxlciB0byB1c2UgZm9yIHRoZSBzZXJ2aWNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBbWF6b24gRUNTIGRlcGxveW1lbnQgdHlwZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2RlcGxveW1lbnQtdHlwZXMuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLWRlcGxveW1lbnRjb250cm9sbGVyLmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIERlcGxveW1lbnRDb250cm9sbGVyUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGRlcGxveW1lbnQgY29udHJvbGxlciB0eXBlIHRvIHVzZS4gVGhlcmUgYXJlIHRocmVlIGRlcGxveW1lbnQgY29udHJvbGxlciB0eXBlcyBhdmFpbGFibGU6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKipFQ1MqKiAtIFRoZSByb2xsaW5nIHVwZGF0ZSAoIGBFQ1NgICkgZGVwbG95bWVudCB0eXBlIGludm9sdmVzIHJlcGxhY2luZyB0aGUgY3VycmVudCBydW5uaW5nIHZlcnNpb24gb2YgdGhlIGNvbnRhaW5lciB3aXRoIHRoZSBsYXRlc3QgdmVyc2lvbi4gVGhlIG51bWJlciBvZiBjb250YWluZXJzIEFtYXpvbiBFQ1MgYWRkcyBvciByZW1vdmVzIGZyb20gdGhlIHNlcnZpY2UgZHVyaW5nIGEgcm9sbGluZyB1cGRhdGUgaXMgY29udHJvbGxlZCBieSBhZGp1c3RpbmcgdGhlIG1pbmltdW0gYW5kIG1heGltdW0gbnVtYmVyIG9mIGhlYWx0aHkgdGFza3MgYWxsb3dlZCBkdXJpbmcgYSBzZXJ2aWNlIGRlcGxveW1lbnQsIGFzIHNwZWNpZmllZCBpbiB0aGUgW0RlcGxveW1lbnRDb25maWd1cmF0aW9uXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlcGxveW1lbnRDb25maWd1cmF0aW9uLmh0bWwpIC5cbiAgICAgICAgICogLSAqKkNPREVfREVQTE9ZKiogLSBUaGUgYmx1ZS9ncmVlbiAoIGBDT0RFX0RFUExPWWAgKSBkZXBsb3ltZW50IHR5cGUgdXNlcyB0aGUgYmx1ZS9ncmVlbiBkZXBsb3ltZW50IG1vZGVsIHBvd2VyZWQgYnkgQVdTIENvZGVEZXBsb3kgLCB3aGljaCBhbGxvd3MgeW91IHRvIHZlcmlmeSBhIG5ldyBkZXBsb3ltZW50IG9mIGEgc2VydmljZSBiZWZvcmUgc2VuZGluZyBwcm9kdWN0aW9uIHRyYWZmaWMgdG8gaXQuXG4gICAgICAgICAqIC0gKipFWFRFUk5BTCoqIC0gVGhlIGV4dGVybmFsICggYEVYVEVSTkFMYCApIGRlcGxveW1lbnQgdHlwZSBlbmFibGVzIHlvdSB0byB1c2UgYW55IHRoaXJkLXBhcnR5IGRlcGxveW1lbnQgY29udHJvbGxlciBmb3IgZnVsbCBjb250cm9sIG92ZXIgdGhlIGRlcGxveW1lbnQgcHJvY2VzcyBmb3IgYW4gQW1hem9uIEVDUyBzZXJ2aWNlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLWRlcGxveW1lbnRjb250cm9sbGVyLmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLWRlcGxveW1lbnRjb250cm9sbGVyLXR5cGVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHR5cGU/OiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYERlcGxveW1lbnRDb250cm9sbGVyUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYERlcGxveW1lbnRDb250cm9sbGVyUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuU2VydmljZV9EZXBsb3ltZW50Q29udHJvbGxlclByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndHlwZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy50eXBlKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkRlcGxveW1lbnRDb250cm9sbGVyUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6U2VydmljZS5EZXBsb3ltZW50Q29udHJvbGxlcmAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgRGVwbG95bWVudENvbnRyb2xsZXJQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpTZXJ2aWNlLkRlcGxveW1lbnRDb250cm9sbGVyYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblNlcnZpY2VEZXBsb3ltZW50Q29udHJvbGxlclByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5TZXJ2aWNlX0RlcGxveW1lbnRDb250cm9sbGVyUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIFR5cGU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMudHlwZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblNlcnZpY2VEZXBsb3ltZW50Q29udHJvbGxlclByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuU2VydmljZS5EZXBsb3ltZW50Q29udHJvbGxlclByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblNlcnZpY2UuRGVwbG95bWVudENvbnRyb2xsZXJQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3R5cGUnLCAnVHlwZScsIHByb3BlcnRpZXMuVHlwZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5UeXBlKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuU2VydmljZSB7XG4gICAgLyoqXG4gICAgICogVGhlIGBMb2FkQmFsYW5jZXJgIHByb3BlcnR5IHNwZWNpZmllcyBkZXRhaWxzIG9uIGEgbG9hZCBiYWxhbmNlciB0aGF0IGlzIHVzZWQgd2l0aCBhIHNlcnZpY2UuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgc2VydmljZSBpcyB1c2luZyB0aGUgYENPREVfREVQTE9ZYCBkZXBsb3ltZW50IGNvbnRyb2xsZXIsIHRoZSBzZXJ2aWNlIGlzIHJlcXVpcmVkIHRvIHVzZSBlaXRoZXIgYW4gQXBwbGljYXRpb24gTG9hZCBCYWxhbmNlciBvciBOZXR3b3JrIExvYWQgQmFsYW5jZXIuIFdoZW4geW91IGFyZSBjcmVhdGluZyBhbiBBV1MgQ29kZURlcGxveSBkZXBsb3ltZW50IGdyb3VwLCB5b3Ugc3BlY2lmeSB0d28gdGFyZ2V0IGdyb3VwcyAocmVmZXJyZWQgdG8gYXMgYSBgdGFyZ2V0R3JvdXBQYWlyYCApLiBFYWNoIHRhcmdldCBncm91cCBiaW5kcyB0byBhIHNlcGFyYXRlIHRhc2sgc2V0IGluIHRoZSBkZXBsb3ltZW50LiBUaGUgbG9hZCBiYWxhbmNlciBjYW4gYWxzbyBoYXZlIHVwIHRvIHR3byBsaXN0ZW5lcnMsIGEgcmVxdWlyZWQgbGlzdGVuZXIgZm9yIHByb2R1Y3Rpb24gdHJhZmZpYyBhbmQgYW4gb3B0aW9uYWwgbGlzdGVuZXIgdGhhdCBhbGxvd3MgeW91IHRvIHRlc3QgbmV3IHJldmlzaW9ucyBvZiB0aGUgc2VydmljZSBiZWZvcmUgcm91dGluZyBwcm9kdWN0aW9uIHRyYWZmaWMgdG8gaXQuXG4gICAgICpcbiAgICAgKiBTZXJ2aWNlcyB3aXRoIHRhc2tzIHRoYXQgdXNlIHRoZSBgYXdzdnBjYCBuZXR3b3JrIG1vZGUgKGZvciBleGFtcGxlLCB0aG9zZSB3aXRoIHRoZSBGYXJnYXRlIGxhdW5jaCB0eXBlKSBvbmx5IHN1cHBvcnQgQXBwbGljYXRpb24gTG9hZCBCYWxhbmNlcnMgYW5kIE5ldHdvcmsgTG9hZCBCYWxhbmNlcnMuIENsYXNzaWMgTG9hZCBCYWxhbmNlcnMgYXJlIG5vdCBzdXBwb3J0ZWQuIEFsc28sIHdoZW4geW91IGNyZWF0ZSBhbnkgdGFyZ2V0IGdyb3VwcyBmb3IgdGhlc2Ugc2VydmljZXMsIHlvdSBtdXN0IGNob29zZSBgaXBgIGFzIHRoZSB0YXJnZXQgdHlwZSwgbm90IGBpbnN0YW5jZWAgLiBUYXNrcyB0aGF0IHVzZSB0aGUgYGF3c3ZwY2AgbmV0d29yayBtb2RlIGFyZSBhc3NvY2lhdGVkIHdpdGggYW4gZWxhc3RpYyBuZXR3b3JrIGludGVyZmFjZSwgbm90IGFuIEFtYXpvbiBFQzIgaW5zdGFuY2UuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1sb2FkYmFsYW5jZXIuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgTG9hZEJhbGFuY2VyUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5hbWUgb2YgdGhlIGNvbnRhaW5lciAoYXMgaXQgYXBwZWFycyBpbiBhIGNvbnRhaW5lciBkZWZpbml0aW9uKSB0byBhc3NvY2lhdGUgd2l0aCB0aGUgbG9hZCBiYWxhbmNlci5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1sb2FkYmFsYW5jZXIuaHRtbCNjZm4tZWNzLXNlcnZpY2UtbG9hZGJhbGFuY2VyLWNvbnRhaW5lcm5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNvbnRhaW5lck5hbWU/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcG9ydCBvbiB0aGUgY29udGFpbmVyIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBsb2FkIGJhbGFuY2VyLiBUaGlzIHBvcnQgbXVzdCBjb3JyZXNwb25kIHRvIGEgYGNvbnRhaW5lclBvcnRgIGluIHRoZSB0YXNrIGRlZmluaXRpb24gdGhlIHRhc2tzIGluIHRoZSBzZXJ2aWNlIGFyZSB1c2luZy4gRm9yIHRhc2tzIHRoYXQgdXNlIHRoZSBFQzIgbGF1bmNoIHR5cGUsIHRoZSBjb250YWluZXIgaW5zdGFuY2UgdGhleSdyZSBsYXVuY2hlZCBvbiBtdXN0IGFsbG93IGluZ3Jlc3MgdHJhZmZpYyBvbiB0aGUgYGhvc3RQb3J0YCBvZiB0aGUgcG9ydCBtYXBwaW5nLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLWxvYWRiYWxhbmNlci5odG1sI2Nmbi1lY3Mtc2VydmljZS1sb2FkYmFsYW5jZXItY29udGFpbmVycG9ydFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY29udGFpbmVyUG9ydDogbnVtYmVyO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5hbWUgb2YgdGhlIGxvYWQgYmFsYW5jZXIgdG8gYXNzb2NpYXRlIHdpdGggdGhlIEFtYXpvbiBFQ1Mgc2VydmljZSBvciB0YXNrIHNldC5cbiAgICAgICAgICpcbiAgICAgICAgICogQSBsb2FkIGJhbGFuY2VyIG5hbWUgaXMgb25seSBzcGVjaWZpZWQgd2hlbiB1c2luZyBhIENsYXNzaWMgTG9hZCBCYWxhbmNlci4gSWYgeW91IGFyZSB1c2luZyBhbiBBcHBsaWNhdGlvbiBMb2FkIEJhbGFuY2VyIG9yIGEgTmV0d29yayBMb2FkIEJhbGFuY2VyIHRoZSBsb2FkIGJhbGFuY2VyIG5hbWUgcGFyYW1ldGVyIHNob3VsZCBiZSBvbWl0dGVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLWxvYWRiYWxhbmNlci5odG1sI2Nmbi1lY3Mtc2VydmljZS1sb2FkYmFsYW5jZXItbG9hZGJhbGFuY2VybmFtZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbG9hZEJhbGFuY2VyTmFtZT86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBmdWxsIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIG9mIHRoZSBFbGFzdGljIExvYWQgQmFsYW5jaW5nIHRhcmdldCBncm91cCBvciBncm91cHMgYXNzb2NpYXRlZCB3aXRoIGEgc2VydmljZSBvciB0YXNrIHNldC5cbiAgICAgICAgICpcbiAgICAgICAgICogQSB0YXJnZXQgZ3JvdXAgQVJOIGlzIG9ubHkgc3BlY2lmaWVkIHdoZW4gdXNpbmcgYW4gQXBwbGljYXRpb24gTG9hZCBCYWxhbmNlciBvciBOZXR3b3JrIExvYWQgQmFsYW5jZXIuIElmIHlvdSdyZSB1c2luZyBhIENsYXNzaWMgTG9hZCBCYWxhbmNlciwgb21pdCB0aGUgdGFyZ2V0IGdyb3VwIEFSTi5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIHNlcnZpY2VzIHVzaW5nIHRoZSBgRUNTYCBkZXBsb3ltZW50IGNvbnRyb2xsZXIsIHlvdSBjYW4gc3BlY2lmeSBvbmUgb3IgbXVsdGlwbGUgdGFyZ2V0IGdyb3Vwcy4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbUmVnaXN0ZXJpbmcgbXVsdGlwbGUgdGFyZ2V0IGdyb3VwcyB3aXRoIGEgc2VydmljZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvcmVnaXN0ZXItbXVsdGlwbGUtdGFyZ2V0Z3JvdXBzLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEZvciBzZXJ2aWNlcyB1c2luZyB0aGUgYENPREVfREVQTE9ZYCBkZXBsb3ltZW50IGNvbnRyb2xsZXIsIHlvdSdyZSByZXF1aXJlZCB0byBkZWZpbmUgdHdvIHRhcmdldCBncm91cHMgZm9yIHRoZSBsb2FkIGJhbGFuY2VyLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtCbHVlL2dyZWVuIGRlcGxveW1lbnQgd2l0aCBDb2RlRGVwbG95XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9kZXBsb3ltZW50LXR5cGUtYmx1ZWdyZWVuLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gSWYgeW91ciBzZXJ2aWNlJ3MgdGFzayBkZWZpbml0aW9uIHVzZXMgdGhlIGBhd3N2cGNgIG5ldHdvcmsgbW9kZSwgeW91IG11c3QgY2hvb3NlIGBpcGAgYXMgdGhlIHRhcmdldCB0eXBlLCBub3QgYGluc3RhbmNlYCAuIERvIHRoaXMgd2hlbiBjcmVhdGluZyB5b3VyIHRhcmdldCBncm91cHMgYmVjYXVzZSB0YXNrcyB0aGF0IHVzZSB0aGUgYGF3c3ZwY2AgbmV0d29yayBtb2RlIGFyZSBhc3NvY2lhdGVkIHdpdGggYW4gZWxhc3RpYyBuZXR3b3JrIGludGVyZmFjZSwgbm90IGFuIEFtYXpvbiBFQzIgaW5zdGFuY2UuIFRoaXMgbmV0d29yayBtb2RlIGlzIHJlcXVpcmVkIGZvciB0aGUgRmFyZ2F0ZSBsYXVuY2ggdHlwZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1sb2FkYmFsYW5jZXIuaHRtbCNjZm4tZWNzLXNlcnZpY2UtbG9hZGJhbGFuY2VyLXRhcmdldGdyb3VwYXJuXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB0YXJnZXRHcm91cEFybj86IHN0cmluZztcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgTG9hZEJhbGFuY2VyUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYExvYWRCYWxhbmNlclByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblNlcnZpY2VfTG9hZEJhbGFuY2VyUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjb250YWluZXJOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmNvbnRhaW5lck5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvbnRhaW5lclBvcnQnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMuY29udGFpbmVyUG9ydCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY29udGFpbmVyUG9ydCcsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5jb250YWluZXJQb3J0KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdsb2FkQmFsYW5jZXJOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmxvYWRCYWxhbmNlck5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3RhcmdldEdyb3VwQXJuJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnRhcmdldEdyb3VwQXJuKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkxvYWRCYWxhbmNlclByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlNlcnZpY2UuTG9hZEJhbGFuY2VyYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBMb2FkQmFsYW5jZXJQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpTZXJ2aWNlLkxvYWRCYWxhbmNlcmAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5TZXJ2aWNlTG9hZEJhbGFuY2VyUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblNlcnZpY2VfTG9hZEJhbGFuY2VyUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIENvbnRhaW5lck5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY29udGFpbmVyTmFtZSksXG4gICAgICAgIENvbnRhaW5lclBvcnQ6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY29udGFpbmVyUG9ydCksXG4gICAgICAgIExvYWRCYWxhbmNlck5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubG9hZEJhbGFuY2VyTmFtZSksXG4gICAgICAgIFRhcmdldEdyb3VwQXJuOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnRhcmdldEdyb3VwQXJuKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuU2VydmljZUxvYWRCYWxhbmNlclByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuU2VydmljZS5Mb2FkQmFsYW5jZXJQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5TZXJ2aWNlLkxvYWRCYWxhbmNlclByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY29udGFpbmVyTmFtZScsICdDb250YWluZXJOYW1lJywgcHJvcGVydGllcy5Db250YWluZXJOYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNvbnRhaW5lck5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2NvbnRhaW5lclBvcnQnLCAnQ29udGFpbmVyUG9ydCcsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuQ29udGFpbmVyUG9ydCkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbG9hZEJhbGFuY2VyTmFtZScsICdMb2FkQmFsYW5jZXJOYW1lJywgcHJvcGVydGllcy5Mb2FkQmFsYW5jZXJOYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkxvYWRCYWxhbmNlck5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3RhcmdldEdyb3VwQXJuJywgJ1RhcmdldEdyb3VwQXJuJywgcHJvcGVydGllcy5UYXJnZXRHcm91cEFybiAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5UYXJnZXRHcm91cEFybikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblNlcnZpY2Uge1xuICAgIC8qKlxuICAgICAqIFRoZSBsb2cgY29uZmlndXJhdGlvbiBmb3IgdGhlIGNvbnRhaW5lci4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgTG9nQ29uZmlnYCBpbiB0aGUgW0NyZWF0ZSBhIGNvbnRhaW5lcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvI29wZXJhdGlvbi9Db250YWluZXJDcmVhdGUpIHNlY3Rpb24gb2YgdGhlIFtEb2NrZXIgUmVtb3RlIEFQSV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvKSBhbmQgdGhlIGAtLWxvZy1kcml2ZXJgIG9wdGlvbiB0byBbYGRvY2tlciBydW5gXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9jb21tYW5kbGluZS9ydW4vKSAuXG4gICAgICpcbiAgICAgKiBCeSBkZWZhdWx0LCBjb250YWluZXJzIHVzZSB0aGUgc2FtZSBsb2dnaW5nIGRyaXZlciB0aGF0IHRoZSBEb2NrZXIgZGFlbW9uIHVzZXMuIEhvd2V2ZXIsIHRoZSBjb250YWluZXIgbWlnaHQgdXNlIGEgZGlmZmVyZW50IGxvZ2dpbmcgZHJpdmVyIHRoYW4gdGhlIERvY2tlciBkYWVtb24gYnkgc3BlY2lmeWluZyBhIGxvZyBkcml2ZXIgY29uZmlndXJhdGlvbiBpbiB0aGUgY29udGFpbmVyIGRlZmluaXRpb24uIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBvcHRpb25zIGZvciBkaWZmZXJlbnQgc3VwcG9ydGVkIGxvZyBkcml2ZXJzLCBzZWUgW0NvbmZpZ3VyZSBsb2dnaW5nIGRyaXZlcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYWRtaW4vbG9nZ2luZy9vdmVydmlldy8pIGluIHRoZSBEb2NrZXIgZG9jdW1lbnRhdGlvbi5cbiAgICAgKlxuICAgICAqIFVuZGVyc3RhbmQgdGhlIGZvbGxvd2luZyB3aGVuIHNwZWNpZnlpbmcgYSBsb2cgY29uZmlndXJhdGlvbiBmb3IgeW91ciBjb250YWluZXJzLlxuICAgICAqXG4gICAgICogLSBBbWF6b24gRUNTIGN1cnJlbnRseSBzdXBwb3J0cyBhIHN1YnNldCBvZiB0aGUgbG9nZ2luZyBkcml2ZXJzIGF2YWlsYWJsZSB0byB0aGUgRG9ja2VyIGRhZW1vbiAoc2hvd24gaW4gdGhlIHZhbGlkIHZhbHVlcyBiZWxvdykuIEFkZGl0aW9uYWwgbG9nIGRyaXZlcnMgbWF5IGJlIGF2YWlsYWJsZSBpbiBmdXR1cmUgcmVsZWFzZXMgb2YgdGhlIEFtYXpvbiBFQ1MgY29udGFpbmVyIGFnZW50LlxuICAgICAqIC0gVGhpcyBwYXJhbWV0ZXIgcmVxdWlyZXMgdmVyc2lvbiAxLjE4IG9mIHRoZSBEb2NrZXIgUmVtb3RlIEFQSSBvciBncmVhdGVyIG9uIHlvdXIgY29udGFpbmVyIGluc3RhbmNlLlxuICAgICAqIC0gRm9yIHRhc2tzIHRoYXQgYXJlIGhvc3RlZCBvbiBBbWF6b24gRUMyIGluc3RhbmNlcywgdGhlIEFtYXpvbiBFQ1MgY29udGFpbmVyIGFnZW50IG11c3QgcmVnaXN0ZXIgdGhlIGF2YWlsYWJsZSBsb2dnaW5nIGRyaXZlcnMgd2l0aCB0aGUgYEVDU19BVkFJTEFCTEVfTE9HR0lOR19EUklWRVJTYCBlbnZpcm9ubWVudCB2YXJpYWJsZSBiZWZvcmUgY29udGFpbmVycyBwbGFjZWQgb24gdGhhdCBpbnN0YW5jZSBjYW4gdXNlIHRoZXNlIGxvZyBjb25maWd1cmF0aW9uIG9wdGlvbnMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0FtYXpvbiBFQ1MgY29udGFpbmVyIGFnZW50IGNvbmZpZ3VyYXRpb25dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2Vjcy1hZ2VudC1jb25maWcuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKiAtIEZvciB0YXNrcyB0aGF0IGFyZSBvbiBBV1MgRmFyZ2F0ZSAsIGJlY2F1c2UgeW91IGRvbid0IGhhdmUgYWNjZXNzIHRvIHRoZSB1bmRlcmx5aW5nIGluZnJhc3RydWN0dXJlIHlvdXIgdGFza3MgYXJlIGhvc3RlZCBvbiwgYW55IGFkZGl0aW9uYWwgc29mdHdhcmUgbmVlZGVkIG11c3QgYmUgaW5zdGFsbGVkIG91dHNpZGUgb2YgdGhlIHRhc2suIEZvciBleGFtcGxlLCB0aGUgRmx1ZW50ZCBvdXRwdXQgYWdncmVnYXRvcnMgb3IgYSByZW1vdGUgaG9zdCBydW5uaW5nIExvZ3N0YXNoIHRvIHNlbmQgR2VsZiBsb2dzIHRvLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXNlcnZpY2UtbG9nY29uZmlndXJhdGlvbi5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBMb2dDb25maWd1cmF0aW9uUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGxvZyBkcml2ZXIgdG8gdXNlIGZvciB0aGUgY29udGFpbmVyLlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgdGFza3Mgb24gQVdTIEZhcmdhdGUgLCB0aGUgc3VwcG9ydGVkIGxvZyBkcml2ZXJzIGFyZSBgYXdzbG9nc2AgLCBgc3BsdW5rYCAsIGFuZCBgYXdzZmlyZWxlbnNgIC5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIHRhc2tzIGhvc3RlZCBvbiBBbWF6b24gRUMyIGluc3RhbmNlcywgdGhlIHN1cHBvcnRlZCBsb2cgZHJpdmVycyBhcmUgYGF3c2xvZ3NgICwgYGZsdWVudGRgICwgYGdlbGZgICwgYGpzb24tZmlsZWAgLCBgam91cm5hbGRgICwgYGxvZ2VudHJpZXNgICwgYHN5c2xvZ2AgLCBgc3BsdW5rYCAsIGFuZCBgYXdzZmlyZWxlbnNgIC5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdXNpbmcgdGhlIGBhd3Nsb2dzYCBsb2cgZHJpdmVyLCBzZWUgW1VzaW5nIHRoZSBhd3Nsb2dzIGxvZyBkcml2ZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3VzaW5nX2F3c2xvZ3MuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdXNpbmcgdGhlIGBhd3NmaXJlbGVuc2AgbG9nIGRyaXZlciwgc2VlIFtDdXN0b20gbG9nIHJvdXRpbmddKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3VzaW5nX2ZpcmVsZW5zLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gSWYgeW91IGhhdmUgYSBjdXN0b20gZHJpdmVyIHRoYXQgaXNuJ3QgbGlzdGVkLCB5b3UgY2FuIGZvcmsgdGhlIEFtYXpvbiBFQ1MgY29udGFpbmVyIGFnZW50IHByb2plY3QgdGhhdCdzIFthdmFpbGFibGUgb24gR2l0SHViXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hbWF6b24tZWNzLWFnZW50KSBhbmQgY3VzdG9taXplIGl0IHRvIHdvcmsgd2l0aCB0aGF0IGRyaXZlci4gV2UgZW5jb3VyYWdlIHlvdSB0byBzdWJtaXQgcHVsbCByZXF1ZXN0cyBmb3IgY2hhbmdlcyB0aGF0IHlvdSB3b3VsZCBsaWtlIHRvIGhhdmUgaW5jbHVkZWQuIEhvd2V2ZXIsIHdlIGRvbid0IGN1cnJlbnRseSBwcm92aWRlIHN1cHBvcnQgZm9yIHJ1bm5pbmcgbW9kaWZpZWQgY29waWVzIG9mIHRoaXMgc29mdHdhcmUuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXNlcnZpY2UtbG9nY29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3Mtc2VydmljZS1sb2djb25maWd1cmF0aW9uLWxvZ2RyaXZlclxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbG9nRHJpdmVyPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byBzZW5kIHRvIHRoZSBsb2cgZHJpdmVyLiBUaGlzIHBhcmFtZXRlciByZXF1aXJlcyB2ZXJzaW9uIDEuMTkgb2YgdGhlIERvY2tlciBSZW1vdGUgQVBJIG9yIGdyZWF0ZXIgb24geW91ciBjb250YWluZXIgaW5zdGFuY2UuIFRvIGNoZWNrIHRoZSBEb2NrZXIgUmVtb3RlIEFQSSB2ZXJzaW9uIG9uIHlvdXIgY29udGFpbmVyIGluc3RhbmNlLCBsb2cgaW4gdG8geW91ciBjb250YWluZXIgaW5zdGFuY2UgYW5kIHJ1biB0aGUgZm9sbG93aW5nIGNvbW1hbmQ6IGBzdWRvIGRvY2tlciB2ZXJzaW9uIC0tZm9ybWF0ICd7ey5TZXJ2ZXIuQVBJVmVyc2lvbn19J2BcbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1sb2djb25maWd1cmF0aW9uLmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLWxvZ2NvbmZpZ3VyYXRpb24tb3B0aW9uc1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgb3B0aW9ucz86IHsgW2tleTogc3RyaW5nXTogKHN0cmluZykgfSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzZWNyZXRzIHRvIHBhc3MgdG8gdGhlIGxvZyBjb25maWd1cmF0aW9uLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtTcGVjaWZ5aW5nIHNlbnNpdGl2ZSBkYXRhXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zcGVjaWZ5aW5nLXNlbnNpdGl2ZS1kYXRhLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXNlcnZpY2UtbG9nY29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3Mtc2VydmljZS1sb2djb25maWd1cmF0aW9uLXNlY3JldG9wdGlvbnNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHNlY3JldE9wdGlvbnM/OiBBcnJheTxDZm5TZXJ2aWNlLlNlY3JldFByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgTG9nQ29uZmlndXJhdGlvblByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBMb2dDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuU2VydmljZV9Mb2dDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdsb2dEcml2ZXInLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMubG9nRHJpdmVyKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdvcHRpb25zJywgY2RrLmhhc2hWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5vcHRpb25zKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzZWNyZXRPcHRpb25zJywgY2RrLmxpc3RWYWxpZGF0b3IoQ2ZuU2VydmljZV9TZWNyZXRQcm9wZXJ0eVZhbGlkYXRvcikpKHByb3BlcnRpZXMuc2VjcmV0T3B0aW9ucykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJMb2dDb25maWd1cmF0aW9uUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6U2VydmljZS5Mb2dDb25maWd1cmF0aW9uYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBMb2dDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6U2VydmljZS5Mb2dDb25maWd1cmF0aW9uYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblNlcnZpY2VMb2dDb25maWd1cmF0aW9uUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblNlcnZpY2VfTG9nQ29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBMb2dEcml2ZXI6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubG9nRHJpdmVyKSxcbiAgICAgICAgT3B0aW9uczogY2RrLmhhc2hNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMub3B0aW9ucyksXG4gICAgICAgIFNlY3JldE9wdGlvbnM6IGNkay5saXN0TWFwcGVyKGNmblNlcnZpY2VTZWNyZXRQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuc2VjcmV0T3B0aW9ucyksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblNlcnZpY2VMb2dDb25maWd1cmF0aW9uUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5TZXJ2aWNlLkxvZ0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5TZXJ2aWNlLkxvZ0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2xvZ0RyaXZlcicsICdMb2dEcml2ZXInLCBwcm9wZXJ0aWVzLkxvZ0RyaXZlciAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Mb2dEcml2ZXIpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ29wdGlvbnMnLCAnT3B0aW9ucycsIHByb3BlcnRpZXMuT3B0aW9ucyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRNYXAoY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcpKHByb3BlcnRpZXMuT3B0aW9ucykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnc2VjcmV0T3B0aW9ucycsICdTZWNyZXRPcHRpb25zJywgcHJvcGVydGllcy5TZWNyZXRPcHRpb25zICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KENmblNlcnZpY2VTZWNyZXRQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5TZWNyZXRPcHRpb25zKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuU2VydmljZSB7XG4gICAgLyoqXG4gICAgICogVGhlIGBOZXR3b3JrQ29uZmlndXJhdGlvbmAgcHJvcGVydHkgc3BlY2lmaWVzIGFuIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIG5ldHdvcmsgY29uZmlndXJhdGlvbiBmb3IgYSB0YXNrIG9yIHNlcnZpY2UuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1uZXR3b3JrY29uZmlndXJhdGlvbi5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBOZXR3b3JrQ29uZmlndXJhdGlvblByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBWUEMgc3VibmV0cyBhbmQgc2VjdXJpdHkgZ3JvdXBzIHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCBhIHRhc2suXG4gICAgICAgICAqXG4gICAgICAgICAqID4gQWxsIHNwZWNpZmllZCBzdWJuZXRzIGFuZCBzZWN1cml0eSBncm91cHMgbXVzdCBiZSBmcm9tIHRoZSBzYW1lIFZQQy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1uZXR3b3JrY29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3Mtc2VydmljZS1uZXR3b3JrY29uZmlndXJhdGlvbi1hd3N2cGNjb25maWd1cmF0aW9uXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBhd3N2cGNDb25maWd1cmF0aW9uPzogQ2ZuU2VydmljZS5Bd3NWcGNDb25maWd1cmF0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYE5ldHdvcmtDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYE5ldHdvcmtDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuU2VydmljZV9OZXR3b3JrQ29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignYXdzdnBjQ29uZmlndXJhdGlvbicsIENmblNlcnZpY2VfQXdzVnBjQ29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKShwcm9wZXJ0aWVzLmF3c3ZwY0NvbmZpZ3VyYXRpb24pKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiTmV0d29ya0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpTZXJ2aWNlLk5ldHdvcmtDb25maWd1cmF0aW9uYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBOZXR3b3JrQ29uZmlndXJhdGlvblByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlNlcnZpY2UuTmV0d29ya0NvbmZpZ3VyYXRpb25gIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuU2VydmljZU5ldHdvcmtDb25maWd1cmF0aW9uUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblNlcnZpY2VfTmV0d29ya0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQXdzdnBjQ29uZmlndXJhdGlvbjogY2ZuU2VydmljZUF3c1ZwY0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5hd3N2cGNDb25maWd1cmF0aW9uKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuU2VydmljZU5ldHdvcmtDb25maWd1cmF0aW9uUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5TZXJ2aWNlLk5ldHdvcmtDb25maWd1cmF0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuU2VydmljZS5OZXR3b3JrQ29uZmlndXJhdGlvblByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnYXdzdnBjQ29uZmlndXJhdGlvbicsICdBd3N2cGNDb25maWd1cmF0aW9uJywgcHJvcGVydGllcy5Bd3N2cGNDb25maWd1cmF0aW9uICE9IG51bGwgPyBDZm5TZXJ2aWNlQXdzVnBjQ29uZmlndXJhdGlvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuQXdzdnBjQ29uZmlndXJhdGlvbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblNlcnZpY2Uge1xuICAgIC8qKlxuICAgICAqIFRoZSBgUGxhY2VtZW50Q29uc3RyYWludGAgcHJvcGVydHkgc3BlY2lmaWVzIGFuIG9iamVjdCByZXByZXNlbnRpbmcgYSBjb25zdHJhaW50IG9uIHRhc2sgcGxhY2VtZW50IGluIHRoZSB0YXNrIGRlZmluaXRpb24uIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1Rhc2sgUGxhY2VtZW50IENvbnN0cmFpbnRzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS90YXNrLXBsYWNlbWVudC1jb25zdHJhaW50cy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXNlcnZpY2UtcGxhY2VtZW50Y29uc3RyYWludC5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBQbGFjZW1lbnRDb25zdHJhaW50UHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogQSBjbHVzdGVyIHF1ZXJ5IGxhbmd1YWdlIGV4cHJlc3Npb24gdG8gYXBwbHkgdG8gdGhlIGNvbnN0cmFpbnQuIFRoZSBleHByZXNzaW9uIGNhbiBoYXZlIGEgbWF4aW11bSBsZW5ndGggb2YgMjAwMCBjaGFyYWN0ZXJzLiBZb3UgY2FuJ3Qgc3BlY2lmeSBhbiBleHByZXNzaW9uIGlmIHRoZSBjb25zdHJhaW50IHR5cGUgaXMgYGRpc3RpbmN0SW5zdGFuY2VgIC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQ2x1c3RlciBxdWVyeSBsYW5ndWFnZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvY2x1c3Rlci1xdWVyeS1sYW5ndWFnZS5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLXBsYWNlbWVudGNvbnN0cmFpbnQuaHRtbCNjZm4tZWNzLXNlcnZpY2UtcGxhY2VtZW50Y29uc3RyYWludC1leHByZXNzaW9uXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBleHByZXNzaW9uPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHR5cGUgb2YgY29uc3RyYWludC4gVXNlIGBkaXN0aW5jdEluc3RhbmNlYCB0byBlbnN1cmUgdGhhdCBlYWNoIHRhc2sgaW4gYSBwYXJ0aWN1bGFyIGdyb3VwIGlzIHJ1bm5pbmcgb24gYSBkaWZmZXJlbnQgY29udGFpbmVyIGluc3RhbmNlLiBVc2UgYG1lbWJlck9mYCB0byByZXN0cmljdCB0aGUgc2VsZWN0aW9uIHRvIGEgZ3JvdXAgb2YgdmFsaWQgY2FuZGlkYXRlcy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1wbGFjZW1lbnRjb25zdHJhaW50Lmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLXBsYWNlbWVudGNvbnN0cmFpbnQtdHlwZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgdHlwZTogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBQbGFjZW1lbnRDb25zdHJhaW50UHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYFBsYWNlbWVudENvbnN0cmFpbnRQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5TZXJ2aWNlX1BsYWNlbWVudENvbnN0cmFpbnRQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2V4cHJlc3Npb24nLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuZXhwcmVzc2lvbikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndHlwZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy50eXBlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0eXBlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnR5cGUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiUGxhY2VtZW50Q29uc3RyYWludFByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlNlcnZpY2UuUGxhY2VtZW50Q29uc3RyYWludGAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgUGxhY2VtZW50Q29uc3RyYWludFByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlNlcnZpY2UuUGxhY2VtZW50Q29uc3RyYWludGAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5TZXJ2aWNlUGxhY2VtZW50Q29uc3RyYWludFByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5TZXJ2aWNlX1BsYWNlbWVudENvbnN0cmFpbnRQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgRXhwcmVzc2lvbjogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5leHByZXNzaW9uKSxcbiAgICAgICAgVHlwZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy50eXBlKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuU2VydmljZVBsYWNlbWVudENvbnN0cmFpbnRQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblNlcnZpY2UuUGxhY2VtZW50Q29uc3RyYWludFByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblNlcnZpY2UuUGxhY2VtZW50Q29uc3RyYWludFByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZXhwcmVzc2lvbicsICdFeHByZXNzaW9uJywgcHJvcGVydGllcy5FeHByZXNzaW9uICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkV4cHJlc3Npb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3R5cGUnLCAnVHlwZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuVHlwZSkpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblNlcnZpY2Uge1xuICAgIC8qKlxuICAgICAqIFRoZSBgUGxhY2VtZW50U3RyYXRlZ3lgIHByb3BlcnR5IHNwZWNpZmllcyB0aGUgdGFzayBwbGFjZW1lbnQgc3RyYXRlZ3kgZm9yIGEgdGFzayBvciBzZXJ2aWNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtUYXNrIFBsYWNlbWVudCBTdHJhdGVnaWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS90YXNrLXBsYWNlbWVudC1zdHJhdGVnaWVzLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1wbGFjZW1lbnRzdHJhdGVneS5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBQbGFjZW1lbnRTdHJhdGVneVByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBmaWVsZCB0byBhcHBseSB0aGUgcGxhY2VtZW50IHN0cmF0ZWd5IGFnYWluc3QuIEZvciB0aGUgYHNwcmVhZGAgcGxhY2VtZW50IHN0cmF0ZWd5LCB2YWxpZCB2YWx1ZXMgYXJlIGBpbnN0YW5jZUlkYCAob3IgYGhvc3RgICwgd2hpY2ggaGFzIHRoZSBzYW1lIGVmZmVjdCksIG9yIGFueSBwbGF0Zm9ybSBvciBjdXN0b20gYXR0cmlidXRlIHRoYXQgaXMgYXBwbGllZCB0byBhIGNvbnRhaW5lciBpbnN0YW5jZSwgc3VjaCBhcyBgYXR0cmlidXRlOmVjcy5hdmFpbGFiaWxpdHktem9uZWAgLiBGb3IgdGhlIGBiaW5wYWNrYCBwbGFjZW1lbnQgc3RyYXRlZ3ksIHZhbGlkIHZhbHVlcyBhcmUgYENQVWAgYW5kIGBNRU1PUllgIC4gRm9yIHRoZSBgcmFuZG9tYCBwbGFjZW1lbnQgc3RyYXRlZ3ksIHRoaXMgZmllbGQgaXMgbm90IHVzZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXNlcnZpY2UtcGxhY2VtZW50c3RyYXRlZ3kuaHRtbCNjZm4tZWNzLXNlcnZpY2UtcGxhY2VtZW50c3RyYXRlZ3ktZmllbGRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGZpZWxkPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHR5cGUgb2YgcGxhY2VtZW50IHN0cmF0ZWd5LiBUaGUgYHJhbmRvbWAgcGxhY2VtZW50IHN0cmF0ZWd5IHJhbmRvbWx5IHBsYWNlcyB0YXNrcyBvbiBhdmFpbGFibGUgY2FuZGlkYXRlcy4gVGhlIGBzcHJlYWRgIHBsYWNlbWVudCBzdHJhdGVneSBzcHJlYWRzIHBsYWNlbWVudCBhY3Jvc3MgYXZhaWxhYmxlIGNhbmRpZGF0ZXMgZXZlbmx5IGJhc2VkIG9uIHRoZSBgZmllbGRgIHBhcmFtZXRlci4gVGhlIGBiaW5wYWNrYCBzdHJhdGVneSBwbGFjZXMgdGFza3Mgb24gYXZhaWxhYmxlIGNhbmRpZGF0ZXMgdGhhdCBoYXZlIHRoZSBsZWFzdCBhdmFpbGFibGUgYW1vdW50IG9mIHRoZSByZXNvdXJjZSB0aGF0J3Mgc3BlY2lmaWVkIHdpdGggdGhlIGBmaWVsZGAgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZSwgaWYgeW91IGJpbnBhY2sgb24gbWVtb3J5LCBhIHRhc2sgaXMgcGxhY2VkIG9uIHRoZSBpbnN0YW5jZSB3aXRoIHRoZSBsZWFzdCBhbW91bnQgb2YgcmVtYWluaW5nIG1lbW9yeSBidXQgc3RpbGwgZW5vdWdoIHRvIHJ1biB0aGUgdGFzay5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1wbGFjZW1lbnRzdHJhdGVneS5odG1sI2Nmbi1lY3Mtc2VydmljZS1wbGFjZW1lbnRzdHJhdGVneS10eXBlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB0eXBlOiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYFBsYWNlbWVudFN0cmF0ZWd5UHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYFBsYWNlbWVudFN0cmF0ZWd5UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuU2VydmljZV9QbGFjZW1lbnRTdHJhdGVneVByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZmllbGQnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuZmllbGQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3R5cGUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMudHlwZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndHlwZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy50eXBlKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIlBsYWNlbWVudFN0cmF0ZWd5UHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6U2VydmljZS5QbGFjZW1lbnRTdHJhdGVneWAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgUGxhY2VtZW50U3RyYXRlZ3lQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpTZXJ2aWNlLlBsYWNlbWVudFN0cmF0ZWd5YCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblNlcnZpY2VQbGFjZW1lbnRTdHJhdGVneVByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5TZXJ2aWNlX1BsYWNlbWVudFN0cmF0ZWd5UHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEZpZWxkOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmZpZWxkKSxcbiAgICAgICAgVHlwZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy50eXBlKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuU2VydmljZVBsYWNlbWVudFN0cmF0ZWd5UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5TZXJ2aWNlLlBsYWNlbWVudFN0cmF0ZWd5UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuU2VydmljZS5QbGFjZW1lbnRTdHJhdGVneVByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZmllbGQnLCAnRmllbGQnLCBwcm9wZXJ0aWVzLkZpZWxkICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkZpZWxkKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0eXBlJywgJ1R5cGUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlR5cGUpKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5TZXJ2aWNlIHtcbiAgICAvKipcbiAgICAgKiBBbiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBzZWNyZXQgdG8gZXhwb3NlIHRvIHlvdXIgY29udGFpbmVyLiBTZWNyZXRzIGNhbiBiZSBleHBvc2VkIHRvIGEgY29udGFpbmVyIGluIHRoZSBmb2xsb3dpbmcgd2F5czpcbiAgICAgKlxuICAgICAqIC0gVG8gaW5qZWN0IHNlbnNpdGl2ZSBkYXRhIGludG8geW91ciBjb250YWluZXJzIGFzIGVudmlyb25tZW50IHZhcmlhYmxlcywgdXNlIHRoZSBgc2VjcmV0c2AgY29udGFpbmVyIGRlZmluaXRpb24gcGFyYW1ldGVyLlxuICAgICAqIC0gVG8gcmVmZXJlbmNlIHNlbnNpdGl2ZSBpbmZvcm1hdGlvbiBpbiB0aGUgbG9nIGNvbmZpZ3VyYXRpb24gb2YgYSBjb250YWluZXIsIHVzZSB0aGUgYHNlY3JldE9wdGlvbnNgIGNvbnRhaW5lciBkZWZpbml0aW9uIHBhcmFtZXRlci5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1NwZWNpZnlpbmcgc2Vuc2l0aXZlIGRhdGFdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3NwZWNpZnlpbmctc2Vuc2l0aXZlLWRhdGEuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLXNlY3JldC5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBTZWNyZXRQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbmFtZSBvZiB0aGUgc2VjcmV0LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLXNlY3JldC5odG1sI2Nmbi1lY3Mtc2VydmljZS1zZWNyZXQtbmFtZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHNlY3JldCB0byBleHBvc2UgdG8gdGhlIGNvbnRhaW5lci4gVGhlIHN1cHBvcnRlZCB2YWx1ZXMgYXJlIGVpdGhlciB0aGUgZnVsbCBBUk4gb2YgdGhlIEFXUyBTZWNyZXRzIE1hbmFnZXIgc2VjcmV0IG9yIHRoZSBmdWxsIEFSTiBvZiB0aGUgcGFyYW1ldGVyIGluIHRoZSBTU00gUGFyYW1ldGVyIFN0b3JlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHJlcXVpcmUgQVdTIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCBwZXJtaXNzaW9ucywgc2VlIFtSZXF1aXJlZCBJQU0gcGVybWlzc2lvbnMgZm9yIEFtYXpvbiBFQ1Mgc2VjcmV0c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvc3BlY2lmeWluZy1zZW5zaXRpdmUtZGF0YS1zZWNyZXRzLmh0bWwjc2VjcmV0cy1pYW0pIChmb3IgU2VjcmV0cyBNYW5hZ2VyKSBvciBbUmVxdWlyZWQgSUFNIHBlcm1pc3Npb25zIGZvciBBbWF6b24gRUNTIHNlY3JldHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3NwZWNpZnlpbmctc2Vuc2l0aXZlLWRhdGEtcGFyYW1ldGVycy5odG1sKSAoZm9yIFN5c3RlbXMgTWFuYWdlciBQYXJhbWV0ZXIgc3RvcmUpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gSWYgdGhlIFNTTSBQYXJhbWV0ZXIgU3RvcmUgcGFyYW1ldGVyIGV4aXN0cyBpbiB0aGUgc2FtZSBSZWdpb24gYXMgdGhlIHRhc2sgeW91J3JlIGxhdW5jaGluZywgdGhlbiB5b3UgY2FuIHVzZSBlaXRoZXIgdGhlIGZ1bGwgQVJOIG9yIG5hbWUgb2YgdGhlIHBhcmFtZXRlci4gSWYgdGhlIHBhcmFtZXRlciBleGlzdHMgaW4gYSBkaWZmZXJlbnQgUmVnaW9uLCB0aGVuIHRoZSBmdWxsIEFSTiBtdXN0IGJlIHNwZWNpZmllZC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1zZWNyZXQuaHRtbCNjZm4tZWNzLXNlcnZpY2Utc2VjcmV0LXZhbHVlZnJvbVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgdmFsdWVGcm9tOiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYFNlY3JldFByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBTZWNyZXRQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5TZXJ2aWNlX1NlY3JldFByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5uYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCduYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLm5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3ZhbHVlRnJvbScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy52YWx1ZUZyb20pKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3ZhbHVlRnJvbScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy52YWx1ZUZyb20pKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiU2VjcmV0UHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6U2VydmljZS5TZWNyZXRgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYFNlY3JldFByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlNlcnZpY2UuU2VjcmV0YCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblNlcnZpY2VTZWNyZXRQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuU2VydmljZV9TZWNyZXRQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5uYW1lKSxcbiAgICAgICAgVmFsdWVGcm9tOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnZhbHVlRnJvbSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblNlcnZpY2VTZWNyZXRQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblNlcnZpY2UuU2VjcmV0UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuU2VydmljZS5TZWNyZXRQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ25hbWUnLCAnTmFtZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuTmFtZSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndmFsdWVGcm9tJywgJ1ZhbHVlRnJvbScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuVmFsdWVGcm9tKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuU2VydmljZSB7XG4gICAgLyoqXG4gICAgICogRWFjaCBhbGlhcyAoXCJlbmRwb2ludFwiKSBpcyBhIGZ1bGx5LXF1YWxpZmllZCBuYW1lIGFuZCBwb3J0IG51bWJlciB0aGF0IG90aGVyIHRhc2tzIChcImNsaWVudHNcIikgY2FuIHVzZSB0byBjb25uZWN0IHRvIHRoaXMgc2VydmljZS5cbiAgICAgKlxuICAgICAqIEVhY2ggbmFtZSBhbmQgcG9ydCBtYXBwaW5nIG11c3QgYmUgdW5pcXVlIHdpdGhpbiB0aGUgbmFtZXNwYWNlLlxuICAgICAqXG4gICAgICogVGFza3MgdGhhdCBydW4gaW4gYSBuYW1lc3BhY2UgY2FuIHVzZSBzaG9ydCBuYW1lcyB0byBjb25uZWN0IHRvIHNlcnZpY2VzIGluIHRoZSBuYW1lc3BhY2UuIFRhc2tzIGNhbiBjb25uZWN0IHRvIHNlcnZpY2VzIGFjcm9zcyBhbGwgb2YgdGhlIGNsdXN0ZXJzIGluIHRoZSBuYW1lc3BhY2UuIFRhc2tzIGNvbm5lY3QgdGhyb3VnaCBhIG1hbmFnZWQgcHJveHkgY29udGFpbmVyIHRoYXQgY29sbGVjdHMgbG9ncyBhbmQgbWV0cmljcyBmb3IgaW5jcmVhc2VkIHZpc2liaWxpdHkuIE9ubHkgdGhlIHRhc2tzIHRoYXQgQW1hem9uIEVDUyBzZXJ2aWNlcyBjcmVhdGUgYXJlIHN1cHBvcnRlZCB3aXRoIFNlcnZpY2UgQ29ubmVjdC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbU2VydmljZSBDb25uZWN0XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zZXJ2aWNlLWNvbm5lY3QuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLXNlcnZpY2Vjb25uZWN0Y2xpZW50YWxpYXMuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgU2VydmljZUNvbm5lY3RDbGllbnRBbGlhc1Byb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBgZG5zTmFtZWAgaXMgdGhlIG5hbWUgdGhhdCB5b3UgdXNlIGluIHRoZSBhcHBsaWNhdGlvbnMgb2YgY2xpZW50IHRhc2tzIHRvIGNvbm5lY3QgdG8gdGhpcyBzZXJ2aWNlLiBUaGUgbmFtZSBtdXN0IGJlIGEgdmFsaWQgRE5TIG5hbWUgYnV0IGRvZXNuJ3QgbmVlZCB0byBiZSBmdWxseS1xdWFsaWZpZWQuIFRoZSBuYW1lIGNhbiBpbmNsdWRlIHVwIHRvIDEyNyBjaGFyYWN0ZXJzLiBUaGUgbmFtZSBjYW4gaW5jbHVkZSBsb3dlcmNhc2UgbGV0dGVycywgbnVtYmVycywgdW5kZXJzY29yZXMgKF8pLCBoeXBoZW5zICgtKSwgYW5kIHBlcmlvZHMgKC4pLiBUaGUgbmFtZSBjYW4ndCBzdGFydCB3aXRoIGEgaHlwaGVuLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB0aGlzIHBhcmFtZXRlciBpc24ndCBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IHZhbHVlIG9mIGBkaXNjb3ZlcnlOYW1lLm5hbWVzcGFjZWAgaXMgdXNlZC4gSWYgdGhlIGBkaXNjb3ZlcnlOYW1lYCBpc24ndCBzcGVjaWZpZWQsIHRoZSBwb3J0IG1hcHBpbmcgbmFtZSBmcm9tIHRoZSB0YXNrIGRlZmluaXRpb24gaXMgdXNlZCBpbiBgcG9ydE5hbWUubmFtZXNwYWNlYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIFRvIGF2b2lkIGNoYW5naW5nIHlvdXIgYXBwbGljYXRpb25zIGluIGNsaWVudCBBbWF6b24gRUNTIHNlcnZpY2VzLCBzZXQgdGhpcyB0byB0aGUgc2FtZSBuYW1lIHRoYXQgdGhlIGNsaWVudCBhcHBsaWNhdGlvbiB1c2VzIGJ5IGRlZmF1bHQuIEZvciBleGFtcGxlLCBhIGZldyBjb21tb24gbmFtZXMgYXJlIGBkYXRhYmFzZWAgLCBgZGJgICwgb3IgdGhlIGxvd2VyY2FzZSBuYW1lIG9mIGEgZGF0YWJhc2UsIHN1Y2ggYXMgYG15c3FsYCBvciBgcmVkaXNgIC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbU2VydmljZSBDb25uZWN0XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zZXJ2aWNlLWNvbm5lY3QuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1zZXJ2aWNlY29ubmVjdGNsaWVudGFsaWFzLmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLXNlcnZpY2Vjb25uZWN0Y2xpZW50YWxpYXMtZG5zbmFtZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgZG5zTmFtZT86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBsaXN0ZW5pbmcgcG9ydCBudW1iZXIgZm9yIHRoZSBTZXJ2aWNlIENvbm5lY3QgcHJveHkuIFRoaXMgcG9ydCBpcyBhdmFpbGFibGUgaW5zaWRlIG9mIGFsbCBvZiB0aGUgdGFza3Mgd2l0aGluIHRoZSBzYW1lIG5hbWVzcGFjZS5cbiAgICAgICAgICpcbiAgICAgICAgICogVG8gYXZvaWQgY2hhbmdpbmcgeW91ciBhcHBsaWNhdGlvbnMgaW4gY2xpZW50IEFtYXpvbiBFQ1Mgc2VydmljZXMsIHNldCB0aGlzIHRvIHRoZSBzYW1lIHBvcnQgdGhhdCB0aGUgY2xpZW50IGFwcGxpY2F0aW9uIHVzZXMgYnkgZGVmYXVsdC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbU2VydmljZSBDb25uZWN0XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zZXJ2aWNlLWNvbm5lY3QuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1zZXJ2aWNlY29ubmVjdGNsaWVudGFsaWFzLmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLXNlcnZpY2Vjb25uZWN0Y2xpZW50YWxpYXMtcG9ydFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcG9ydDogbnVtYmVyO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBTZXJ2aWNlQ29ubmVjdENsaWVudEFsaWFzUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYFNlcnZpY2VDb25uZWN0Q2xpZW50QWxpYXNQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5TZXJ2aWNlX1NlcnZpY2VDb25uZWN0Q2xpZW50QWxpYXNQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2Ruc05hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuZG5zTmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9ydCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5wb3J0KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwb3J0JywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLnBvcnQpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiU2VydmljZUNvbm5lY3RDbGllbnRBbGlhc1Byb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlNlcnZpY2UuU2VydmljZUNvbm5lY3RDbGllbnRBbGlhc2AgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgU2VydmljZUNvbm5lY3RDbGllbnRBbGlhc1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlNlcnZpY2UuU2VydmljZUNvbm5lY3RDbGllbnRBbGlhc2AgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5TZXJ2aWNlU2VydmljZUNvbm5lY3RDbGllbnRBbGlhc1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5TZXJ2aWNlX1NlcnZpY2VDb25uZWN0Q2xpZW50QWxpYXNQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgRG5zTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5kbnNOYW1lKSxcbiAgICAgICAgUG9ydDogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wb3J0KSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuU2VydmljZVNlcnZpY2VDb25uZWN0Q2xpZW50QWxpYXNQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblNlcnZpY2UuU2VydmljZUNvbm5lY3RDbGllbnRBbGlhc1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblNlcnZpY2UuU2VydmljZUNvbm5lY3RDbGllbnRBbGlhc1Byb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZG5zTmFtZScsICdEbnNOYW1lJywgcHJvcGVydGllcy5EbnNOYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkRuc05hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BvcnQnLCAnUG9ydCcsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuUG9ydCkpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblNlcnZpY2Uge1xuICAgIC8qKlxuICAgICAqIFRoZSBTZXJ2aWNlIENvbm5lY3QgY29uZmlndXJhdGlvbiBvZiB5b3VyIEFtYXpvbiBFQ1Mgc2VydmljZS4gVGhlIGNvbmZpZ3VyYXRpb24gZm9yIHRoaXMgc2VydmljZSB0byBkaXNjb3ZlciBhbmQgY29ubmVjdCB0byBzZXJ2aWNlcywgYW5kIGJlIGRpc2NvdmVyZWQgYnksIGFuZCBjb25uZWN0ZWQgZnJvbSwgb3RoZXIgc2VydmljZXMgd2l0aGluIGEgbmFtZXNwYWNlLlxuICAgICAqXG4gICAgICogVGFza3MgdGhhdCBydW4gaW4gYSBuYW1lc3BhY2UgY2FuIHVzZSBzaG9ydCBuYW1lcyB0byBjb25uZWN0IHRvIHNlcnZpY2VzIGluIHRoZSBuYW1lc3BhY2UuIFRhc2tzIGNhbiBjb25uZWN0IHRvIHNlcnZpY2VzIGFjcm9zcyBhbGwgb2YgdGhlIGNsdXN0ZXJzIGluIHRoZSBuYW1lc3BhY2UuIFRhc2tzIGNvbm5lY3QgdGhyb3VnaCBhIG1hbmFnZWQgcHJveHkgY29udGFpbmVyIHRoYXQgY29sbGVjdHMgbG9ncyBhbmQgbWV0cmljcyBmb3IgaW5jcmVhc2VkIHZpc2liaWxpdHkuIE9ubHkgdGhlIHRhc2tzIHRoYXQgQW1hem9uIEVDUyBzZXJ2aWNlcyBjcmVhdGUgYXJlIHN1cHBvcnRlZCB3aXRoIFNlcnZpY2UgQ29ubmVjdC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbU2VydmljZSBDb25uZWN0XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zZXJ2aWNlLWNvbm5lY3QuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLXNlcnZpY2Vjb25uZWN0Y29uZmlndXJhdGlvbi5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBTZXJ2aWNlQ29ubmVjdENvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTcGVjaWZpZXMgd2hldGhlciB0byB1c2UgU2VydmljZSBDb25uZWN0IHdpdGggdGhpcyBzZXJ2aWNlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLXNlcnZpY2Vjb25uZWN0Y29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3Mtc2VydmljZS1zZXJ2aWNlY29ubmVjdGNvbmZpZ3VyYXRpb24tZW5hYmxlZFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgZW5hYmxlZDogYm9vbGVhbiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBsb2cgY29uZmlndXJhdGlvbiBmb3IgdGhlIGNvbnRhaW5lci4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgTG9nQ29uZmlnYCBpbiB0aGUgW0NyZWF0ZSBhIGNvbnRhaW5lcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvI29wZXJhdGlvbi9Db250YWluZXJDcmVhdGUpIHNlY3Rpb24gb2YgdGhlIFtEb2NrZXIgUmVtb3RlIEFQSV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvKSBhbmQgdGhlIGAtLWxvZy1kcml2ZXJgIG9wdGlvbiB0byBbYGRvY2tlciBydW5gXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9jb21tYW5kbGluZS9ydW4vKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEJ5IGRlZmF1bHQsIGNvbnRhaW5lcnMgdXNlIHRoZSBzYW1lIGxvZ2dpbmcgZHJpdmVyIHRoYXQgdGhlIERvY2tlciBkYWVtb24gdXNlcy4gSG93ZXZlciwgdGhlIGNvbnRhaW5lciBtaWdodCB1c2UgYSBkaWZmZXJlbnQgbG9nZ2luZyBkcml2ZXIgdGhhbiB0aGUgRG9ja2VyIGRhZW1vbiBieSBzcGVjaWZ5aW5nIGEgbG9nIGRyaXZlciBjb25maWd1cmF0aW9uIGluIHRoZSBjb250YWluZXIgZGVmaW5pdGlvbi4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG9wdGlvbnMgZm9yIGRpZmZlcmVudCBzdXBwb3J0ZWQgbG9nIGRyaXZlcnMsIHNlZSBbQ29uZmlndXJlIGxvZ2dpbmcgZHJpdmVyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hZG1pbi9sb2dnaW5nL292ZXJ2aWV3LykgaW4gdGhlIERvY2tlciBkb2N1bWVudGF0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBVbmRlcnN0YW5kIHRoZSBmb2xsb3dpbmcgd2hlbiBzcGVjaWZ5aW5nIGEgbG9nIGNvbmZpZ3VyYXRpb24gZm9yIHlvdXIgY29udGFpbmVycy5cbiAgICAgICAgICpcbiAgICAgICAgICogLSBBbWF6b24gRUNTIGN1cnJlbnRseSBzdXBwb3J0cyBhIHN1YnNldCBvZiB0aGUgbG9nZ2luZyBkcml2ZXJzIGF2YWlsYWJsZSB0byB0aGUgRG9ja2VyIGRhZW1vbiAoc2hvd24gaW4gdGhlIHZhbGlkIHZhbHVlcyBiZWxvdykuIEFkZGl0aW9uYWwgbG9nIGRyaXZlcnMgbWF5IGJlIGF2YWlsYWJsZSBpbiBmdXR1cmUgcmVsZWFzZXMgb2YgdGhlIEFtYXpvbiBFQ1MgY29udGFpbmVyIGFnZW50LlxuICAgICAgICAgKiAtIFRoaXMgcGFyYW1ldGVyIHJlcXVpcmVzIHZlcnNpb24gMS4xOCBvZiB0aGUgRG9ja2VyIFJlbW90ZSBBUEkgb3IgZ3JlYXRlciBvbiB5b3VyIGNvbnRhaW5lciBpbnN0YW5jZS5cbiAgICAgICAgICogLSBGb3IgdGFza3MgdGhhdCBhcmUgaG9zdGVkIG9uIEFtYXpvbiBFQzIgaW5zdGFuY2VzLCB0aGUgQW1hem9uIEVDUyBjb250YWluZXIgYWdlbnQgbXVzdCByZWdpc3RlciB0aGUgYXZhaWxhYmxlIGxvZ2dpbmcgZHJpdmVycyB3aXRoIHRoZSBgRUNTX0FWQUlMQUJMRV9MT0dHSU5HX0RSSVZFUlNgIGVudmlyb25tZW50IHZhcmlhYmxlIGJlZm9yZSBjb250YWluZXJzIHBsYWNlZCBvbiB0aGF0IGluc3RhbmNlIGNhbiB1c2UgdGhlc2UgbG9nIGNvbmZpZ3VyYXRpb24gb3B0aW9ucy4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQW1hem9uIEVDUyBjb250YWluZXIgYWdlbnQgY29uZmlndXJhdGlvbl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvZWNzLWFnZW50LWNvbmZpZy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKiAtIEZvciB0YXNrcyB0aGF0IGFyZSBvbiBBV1MgRmFyZ2F0ZSAsIGJlY2F1c2UgeW91IGRvbid0IGhhdmUgYWNjZXNzIHRvIHRoZSB1bmRlcmx5aW5nIGluZnJhc3RydWN0dXJlIHlvdXIgdGFza3MgYXJlIGhvc3RlZCBvbiwgYW55IGFkZGl0aW9uYWwgc29mdHdhcmUgbmVlZGVkIG11c3QgYmUgaW5zdGFsbGVkIG91dHNpZGUgb2YgdGhlIHRhc2suIEZvciBleGFtcGxlLCB0aGUgRmx1ZW50ZCBvdXRwdXQgYWdncmVnYXRvcnMgb3IgYSByZW1vdGUgaG9zdCBydW5uaW5nIExvZ3N0YXNoIHRvIHNlbmQgR2VsZiBsb2dzIHRvLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLXNlcnZpY2Vjb25uZWN0Y29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3Mtc2VydmljZS1zZXJ2aWNlY29ubmVjdGNvbmZpZ3VyYXRpb24tbG9nY29uZmlndXJhdGlvblxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbG9nQ29uZmlndXJhdGlvbj86IENmblNlcnZpY2UuTG9nQ29uZmlndXJhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5hbWVzcGFjZSBuYW1lIG9yIGZ1bGwgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIEFXUyBDbG91ZCBNYXAgbmFtZXNwYWNlIGZvciB1c2Ugd2l0aCBTZXJ2aWNlIENvbm5lY3QuIFRoZSBuYW1lc3BhY2UgbXVzdCBiZSBpbiB0aGUgc2FtZSBBV1MgUmVnaW9uIGFzIHRoZSBBbWF6b24gRUNTIHNlcnZpY2UgYW5kIGNsdXN0ZXIuIFRoZSB0eXBlIG9mIG5hbWVzcGFjZSBkb2Vzbid0IGFmZmVjdCBTZXJ2aWNlIENvbm5lY3QuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IEFXUyBDbG91ZCBNYXAgLCBzZWUgW1dvcmtpbmcgd2l0aCBTZXJ2aWNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nsb3VkLW1hcC9sYXRlc3QvZGcvd29ya2luZy13aXRoLXNlcnZpY2VzLmh0bWwpIGluIHRoZSAqQVdTIENsb3VkIE1hcCBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1zZXJ2aWNlY29ubmVjdGNvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLXNlcnZpY2Utc2VydmljZWNvbm5lY3Rjb25maWd1cmF0aW9uLW5hbWVzcGFjZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbmFtZXNwYWNlPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGxpc3Qgb2YgU2VydmljZSBDb25uZWN0IHNlcnZpY2Ugb2JqZWN0cy4gVGhlc2UgYXJlIG5hbWVzIGFuZCBhbGlhc2VzIChhbHNvIGtub3duIGFzIGVuZHBvaW50cykgdGhhdCBhcmUgdXNlZCBieSBvdGhlciBBbWF6b24gRUNTIHNlcnZpY2VzIHRvIGNvbm5lY3QgdG8gdGhpcyBzZXJ2aWNlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBUaGlzIGZpZWxkIGlzIG5vdCByZXF1aXJlZCBmb3IgYSBcImNsaWVudFwiIEFtYXpvbiBFQ1Mgc2VydmljZSB0aGF0J3MgYSBtZW1iZXIgb2YgYSBuYW1lc3BhY2Ugb25seSB0byBjb25uZWN0IHRvIG90aGVyIHNlcnZpY2VzIHdpdGhpbiB0aGUgbmFtZXNwYWNlLiBBbiBleGFtcGxlIG9mIHRoaXMgd291bGQgYmUgYSBmcm9udGVuZCBhcHBsaWNhdGlvbiB0aGF0IGFjY2VwdHMgaW5jb21pbmcgcmVxdWVzdHMgZnJvbSBlaXRoZXIgYSBsb2FkIGJhbGFuY2VyIHRoYXQncyBhdHRhY2hlZCB0byB0aGUgc2VydmljZSBvciBieSBvdGhlciBtZWFucy5cbiAgICAgICAgICpcbiAgICAgICAgICogQW4gb2JqZWN0IHNlbGVjdHMgYSBwb3J0IGZyb20gdGhlIHRhc2sgZGVmaW5pdGlvbiwgYXNzaWducyBhIG5hbWUgZm9yIHRoZSBBV1MgQ2xvdWQgTWFwIHNlcnZpY2UsIGFuZCBhIGxpc3Qgb2YgYWxpYXNlcyAoZW5kcG9pbnRzKSBhbmQgcG9ydHMgZm9yIGNsaWVudCBhcHBsaWNhdGlvbnMgdG8gcmVmZXIgdG8gdGhpcyBzZXJ2aWNlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLXNlcnZpY2Vjb25uZWN0Y29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3Mtc2VydmljZS1zZXJ2aWNlY29ubmVjdGNvbmZpZ3VyYXRpb24tc2VydmljZXNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHNlcnZpY2VzPzogQXJyYXk8Q2ZuU2VydmljZS5TZXJ2aWNlQ29ubmVjdFNlcnZpY2VQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGU7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYFNlcnZpY2VDb25uZWN0Q29uZmlndXJhdGlvblByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBTZXJ2aWNlQ29ubmVjdENvbmZpZ3VyYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5TZXJ2aWNlX1NlcnZpY2VDb25uZWN0Q29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZW5hYmxlZCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5lbmFibGVkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdlbmFibGVkJywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5lbmFibGVkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdsb2dDb25maWd1cmF0aW9uJywgQ2ZuU2VydmljZV9Mb2dDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IpKHByb3BlcnRpZXMubG9nQ29uZmlndXJhdGlvbikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbmFtZXNwYWNlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLm5hbWVzcGFjZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc2VydmljZXMnLCBjZGsubGlzdFZhbGlkYXRvcihDZm5TZXJ2aWNlX1NlcnZpY2VDb25uZWN0U2VydmljZVByb3BlcnR5VmFsaWRhdG9yKSkocHJvcGVydGllcy5zZXJ2aWNlcykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJTZXJ2aWNlQ29ubmVjdENvbmZpZ3VyYXRpb25Qcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpTZXJ2aWNlLlNlcnZpY2VDb25uZWN0Q29uZmlndXJhdGlvbmAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgU2VydmljZUNvbm5lY3RDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6U2VydmljZS5TZXJ2aWNlQ29ubmVjdENvbmZpZ3VyYXRpb25gIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuU2VydmljZVNlcnZpY2VDb25uZWN0Q29uZmlndXJhdGlvblByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5TZXJ2aWNlX1NlcnZpY2VDb25uZWN0Q29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBFbmFibGVkOiBjZGsuYm9vbGVhblRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5lbmFibGVkKSxcbiAgICAgICAgTG9nQ29uZmlndXJhdGlvbjogY2ZuU2VydmljZUxvZ0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5sb2dDb25maWd1cmF0aW9uKSxcbiAgICAgICAgTmFtZXNwYWNlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm5hbWVzcGFjZSksXG4gICAgICAgIFNlcnZpY2VzOiBjZGsubGlzdE1hcHBlcihjZm5TZXJ2aWNlU2VydmljZUNvbm5lY3RTZXJ2aWNlUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnNlcnZpY2VzKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuU2VydmljZVNlcnZpY2VDb25uZWN0Q29uZmlndXJhdGlvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuU2VydmljZS5TZXJ2aWNlQ29ubmVjdENvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5TZXJ2aWNlLlNlcnZpY2VDb25uZWN0Q29uZmlndXJhdGlvblByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZW5hYmxlZCcsICdFbmFibGVkJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRCb29sZWFuKHByb3BlcnRpZXMuRW5hYmxlZCkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbG9nQ29uZmlndXJhdGlvbicsICdMb2dDb25maWd1cmF0aW9uJywgcHJvcGVydGllcy5Mb2dDb25maWd1cmF0aW9uICE9IG51bGwgPyBDZm5TZXJ2aWNlTG9nQ29uZmlndXJhdGlvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuTG9nQ29uZmlndXJhdGlvbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbmFtZXNwYWNlJywgJ05hbWVzcGFjZScsIHByb3BlcnRpZXMuTmFtZXNwYWNlICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLk5hbWVzcGFjZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnc2VydmljZXMnLCAnU2VydmljZXMnLCBwcm9wZXJ0aWVzLlNlcnZpY2VzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KENmblNlcnZpY2VTZXJ2aWNlQ29ubmVjdFNlcnZpY2VQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5TZXJ2aWNlcykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblNlcnZpY2Uge1xuICAgIC8qKlxuICAgICAqIFRoZSBTZXJ2aWNlIENvbm5lY3Qgc2VydmljZSBvYmplY3QgY29uZmlndXJhdGlvbi4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbU2VydmljZSBDb25uZWN0XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zZXJ2aWNlLWNvbm5lY3QuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLXNlcnZpY2Vjb25uZWN0c2VydmljZS5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBTZXJ2aWNlQ29ubmVjdFNlcnZpY2VQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbGlzdCBvZiBjbGllbnQgYWxpYXNlcyBmb3IgdGhpcyBTZXJ2aWNlIENvbm5lY3Qgc2VydmljZS4gWW91IHVzZSB0aGVzZSB0byBhc3NpZ24gbmFtZXMgdGhhdCBjYW4gYmUgdXNlZCBieSBjbGllbnQgYXBwbGljYXRpb25zLiBUaGUgbWF4aW11bSBudW1iZXIgb2YgY2xpZW50IGFsaWFzZXMgdGhhdCB5b3UgY2FuIGhhdmUgaW4gdGhpcyBsaXN0IGlzIDEuXG4gICAgICAgICAqXG4gICAgICAgICAqIEVhY2ggYWxpYXMgKFwiZW5kcG9pbnRcIikgaXMgYSBmdWxseS1xdWFsaWZpZWQgbmFtZSBhbmQgcG9ydCBudW1iZXIgdGhhdCBvdGhlciBBbWF6b24gRUNTIHRhc2tzIChcImNsaWVudHNcIikgY2FuIHVzZSB0byBjb25uZWN0IHRvIHRoaXMgc2VydmljZS5cbiAgICAgICAgICpcbiAgICAgICAgICogRWFjaCBuYW1lIGFuZCBwb3J0IG1hcHBpbmcgbXVzdCBiZSB1bmlxdWUgd2l0aGluIHRoZSBuYW1lc3BhY2UuXG4gICAgICAgICAqXG4gICAgICAgICAqIEZvciBlYWNoIGBTZXJ2aWNlQ29ubmVjdFNlcnZpY2VgICwgeW91IG11c3QgcHJvdmlkZSBhdCBsZWFzdCBvbmUgYGNsaWVudEFsaWFzYCB3aXRoIG9uZSBgcG9ydGAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLXNlcnZpY2Vjb25uZWN0c2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1zZXJ2aWNlY29ubmVjdHNlcnZpY2UtY2xpZW50YWxpYXNlc1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY2xpZW50QWxpYXNlcz86IEFycmF5PENmblNlcnZpY2UuU2VydmljZUNvbm5lY3RDbGllbnRBbGlhc1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBgZGlzY292ZXJ5TmFtZWAgaXMgdGhlIG5hbWUgb2YgdGhlIG5ldyBBV1MgQ2xvdWQgTWFwIHNlcnZpY2UgdGhhdCBBbWF6b24gRUNTIGNyZWF0ZXMgZm9yIHRoaXMgQW1hem9uIEVDUyBzZXJ2aWNlLiBUaGlzIG11c3QgYmUgdW5pcXVlIHdpdGhpbiB0aGUgQVdTIENsb3VkIE1hcCBuYW1lc3BhY2UuIFRoZSBuYW1lIGNhbiBjb250YWluIHVwIHRvIDY0IGNoYXJhY3RlcnMuIFRoZSBuYW1lIGNhbiBpbmNsdWRlIGxvd2VyY2FzZSBsZXR0ZXJzLCBudW1iZXJzLCB1bmRlcnNjb3JlcyAoXyksIGFuZCBoeXBoZW5zICgtKS4gVGhlIG5hbWUgY2FuJ3Qgc3RhcnQgd2l0aCBhIGh5cGhlbi5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgdGhlIGBkaXNjb3ZlcnlOYW1lYCBpc24ndCBzcGVjaWZpZWQsIHRoZSBwb3J0IG1hcHBpbmcgbmFtZSBmcm9tIHRoZSB0YXNrIGRlZmluaXRpb24gaXMgdXNlZCBpbiBgcG9ydE5hbWUubmFtZXNwYWNlYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXNlcnZpY2Utc2VydmljZWNvbm5lY3RzZXJ2aWNlLmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLXNlcnZpY2Vjb25uZWN0c2VydmljZS1kaXNjb3ZlcnluYW1lXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBkaXNjb3ZlcnlOYW1lPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHBvcnQgbnVtYmVyIGZvciB0aGUgU2VydmljZSBDb25uZWN0IHByb3h5IHRvIGxpc3RlbiBvbi5cbiAgICAgICAgICpcbiAgICAgICAgICogVXNlIHRoZSB2YWx1ZSBvZiB0aGlzIGZpZWxkIHRvIGJ5cGFzcyB0aGUgcHJveHkgZm9yIHRyYWZmaWMgb24gdGhlIHBvcnQgbnVtYmVyIHNwZWNpZmllZCBpbiB0aGUgbmFtZWQgYHBvcnRNYXBwaW5nYCBpbiB0aGUgdGFzayBkZWZpbml0aW9uIG9mIHRoaXMgYXBwbGljYXRpb24sIGFuZCB0aGVuIHVzZSBpdCBpbiB5b3VyIFZQQyBzZWN1cml0eSBncm91cHMgdG8gYWxsb3cgdHJhZmZpYyBpbnRvIHRoZSBwcm94eSBmb3IgdGhpcyBBbWF6b24gRUNTIHNlcnZpY2UuXG4gICAgICAgICAqXG4gICAgICAgICAqIEluIGBhd3N2cGNgIG1vZGUgYW5kIEZhcmdhdGUsIHRoZSBkZWZhdWx0IHZhbHVlIGlzIHRoZSBjb250YWluZXIgcG9ydCBudW1iZXIuIFRoZSBjb250YWluZXIgcG9ydCBudW1iZXIgaXMgaW4gdGhlIGBwb3J0TWFwcGluZ2AgaW4gdGhlIHRhc2sgZGVmaW5pdGlvbi4gSW4gYnJpZGdlIG1vZGUsIHRoZSBkZWZhdWx0IHZhbHVlIGlzIHRoZSBlcGhlbWVyYWwgcG9ydCBvZiB0aGUgU2VydmljZSBDb25uZWN0IHByb3h5LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLXNlcnZpY2Vjb25uZWN0c2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1zZXJ2aWNlY29ubmVjdHNlcnZpY2UtaW5ncmVzc3BvcnRvdmVycmlkZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgaW5ncmVzc1BvcnRPdmVycmlkZT86IG51bWJlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBgcG9ydE5hbWVgIG11c3QgbWF0Y2ggdGhlIG5hbWUgb2Ygb25lIG9mIHRoZSBgcG9ydE1hcHBpbmdzYCBmcm9tIGFsbCB0aGUgY29udGFpbmVycyBpbiB0aGUgdGFzayBkZWZpbml0aW9uIG9mIHRoaXMgQW1hem9uIEVDUyBzZXJ2aWNlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLXNlcnZpY2Vjb25uZWN0c2VydmljZS5odG1sI2Nmbi1lY3Mtc2VydmljZS1zZXJ2aWNlY29ubmVjdHNlcnZpY2UtcG9ydG5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHBvcnROYW1lOiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYFNlcnZpY2VDb25uZWN0U2VydmljZVByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBTZXJ2aWNlQ29ubmVjdFNlcnZpY2VQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5TZXJ2aWNlX1NlcnZpY2VDb25uZWN0U2VydmljZVByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY2xpZW50QWxpYXNlcycsIGNkay5saXN0VmFsaWRhdG9yKENmblNlcnZpY2VfU2VydmljZUNvbm5lY3RDbGllbnRBbGlhc1Byb3BlcnR5VmFsaWRhdG9yKSkocHJvcGVydGllcy5jbGllbnRBbGlhc2VzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdkaXNjb3ZlcnlOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmRpc2NvdmVyeU5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2luZ3Jlc3NQb3J0T3ZlcnJpZGUnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMuaW5ncmVzc1BvcnRPdmVycmlkZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9ydE5hbWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMucG9ydE5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvcnROYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnBvcnROYW1lKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIlNlcnZpY2VDb25uZWN0U2VydmljZVByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlNlcnZpY2UuU2VydmljZUNvbm5lY3RTZXJ2aWNlYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBTZXJ2aWNlQ29ubmVjdFNlcnZpY2VQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpTZXJ2aWNlLlNlcnZpY2VDb25uZWN0U2VydmljZWAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5TZXJ2aWNlU2VydmljZUNvbm5lY3RTZXJ2aWNlUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblNlcnZpY2VfU2VydmljZUNvbm5lY3RTZXJ2aWNlUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIENsaWVudEFsaWFzZXM6IGNkay5saXN0TWFwcGVyKGNmblNlcnZpY2VTZXJ2aWNlQ29ubmVjdENsaWVudEFsaWFzUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLmNsaWVudEFsaWFzZXMpLFxuICAgICAgICBEaXNjb3ZlcnlOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmRpc2NvdmVyeU5hbWUpLFxuICAgICAgICBJbmdyZXNzUG9ydE92ZXJyaWRlOiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmluZ3Jlc3NQb3J0T3ZlcnJpZGUpLFxuICAgICAgICBQb3J0TmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wb3J0TmFtZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblNlcnZpY2VTZXJ2aWNlQ29ubmVjdFNlcnZpY2VQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblNlcnZpY2UuU2VydmljZUNvbm5lY3RTZXJ2aWNlUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuU2VydmljZS5TZXJ2aWNlQ29ubmVjdFNlcnZpY2VQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2NsaWVudEFsaWFzZXMnLCAnQ2xpZW50QWxpYXNlcycsIHByb3BlcnRpZXMuQ2xpZW50QWxpYXNlcyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5TZXJ2aWNlU2VydmljZUNvbm5lY3RDbGllbnRBbGlhc1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLkNsaWVudEFsaWFzZXMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2Rpc2NvdmVyeU5hbWUnLCAnRGlzY292ZXJ5TmFtZScsIHByb3BlcnRpZXMuRGlzY292ZXJ5TmFtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5EaXNjb3ZlcnlOYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdpbmdyZXNzUG9ydE92ZXJyaWRlJywgJ0luZ3Jlc3NQb3J0T3ZlcnJpZGUnLCBwcm9wZXJ0aWVzLkluZ3Jlc3NQb3J0T3ZlcnJpZGUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuSW5ncmVzc1BvcnRPdmVycmlkZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncG9ydE5hbWUnLCAnUG9ydE5hbWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlBvcnROYW1lKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuU2VydmljZSB7XG4gICAgLyoqXG4gICAgICogVGhlIGBTZXJ2aWNlUmVnaXN0cnlgIHByb3BlcnR5IHNwZWNpZmllcyBkZXRhaWxzIG9mIHRoZSBzZXJ2aWNlIHJlZ2lzdHJ5LiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtTZXJ2aWNlIERpc2NvdmVyeV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvc2VydmljZS1kaXNjb3ZlcnkuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLXNlcnZpY2VyZWdpc3RyeS5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBTZXJ2aWNlUmVnaXN0cnlQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY29udGFpbmVyIG5hbWUgdmFsdWUgdG8gYmUgdXNlZCBmb3IgeW91ciBzZXJ2aWNlIGRpc2NvdmVyeSBzZXJ2aWNlLiBJdCdzIGFscmVhZHkgc3BlY2lmaWVkIGluIHRoZSB0YXNrIGRlZmluaXRpb24uIElmIHRoZSB0YXNrIGRlZmluaXRpb24gdGhhdCB5b3VyIHNlcnZpY2UgdGFzayBzcGVjaWZpZXMgdXNlcyB0aGUgYGJyaWRnZWAgb3IgYGhvc3RgIG5ldHdvcmsgbW9kZSwgeW91IG11c3Qgc3BlY2lmeSBhIGBjb250YWluZXJOYW1lYCBhbmQgYGNvbnRhaW5lclBvcnRgIGNvbWJpbmF0aW9uIGZyb20gdGhlIHRhc2sgZGVmaW5pdGlvbi4gSWYgdGhlIHRhc2sgZGVmaW5pdGlvbiB0aGF0IHlvdXIgc2VydmljZSB0YXNrIHNwZWNpZmllcyB1c2VzIHRoZSBgYXdzdnBjYCBuZXR3b3JrIG1vZGUgYW5kIGEgdHlwZSBTUlYgRE5TIHJlY29yZCBpcyB1c2VkLCB5b3UgbXVzdCBzcGVjaWZ5IGVpdGhlciBhIGBjb250YWluZXJOYW1lYCBhbmQgYGNvbnRhaW5lclBvcnRgIGNvbWJpbmF0aW9uIG9yIGEgYHBvcnRgIHZhbHVlLiBIb3dldmVyLCB5b3UgY2FuJ3Qgc3BlY2lmeSBib3RoLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLXNlcnZpY2VyZWdpc3RyeS5odG1sI2Nmbi1lY3Mtc2VydmljZS1zZXJ2aWNlcmVnaXN0cnktY29udGFpbmVybmFtZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY29udGFpbmVyTmFtZT86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwb3J0IHZhbHVlIHRvIGJlIHVzZWQgZm9yIHlvdXIgc2VydmljZSBkaXNjb3Zlcnkgc2VydmljZS4gSXQncyBhbHJlYWR5IHNwZWNpZmllZCBpbiB0aGUgdGFzayBkZWZpbml0aW9uLiBJZiB0aGUgdGFzayBkZWZpbml0aW9uIHlvdXIgc2VydmljZSB0YXNrIHNwZWNpZmllcyB1c2VzIHRoZSBgYnJpZGdlYCBvciBgaG9zdGAgbmV0d29yayBtb2RlLCB5b3UgbXVzdCBzcGVjaWZ5IGEgYGNvbnRhaW5lck5hbWVgIGFuZCBgY29udGFpbmVyUG9ydGAgY29tYmluYXRpb24gZnJvbSB0aGUgdGFzayBkZWZpbml0aW9uLiBJZiB0aGUgdGFzayBkZWZpbml0aW9uIHlvdXIgc2VydmljZSB0YXNrIHNwZWNpZmllcyB1c2VzIHRoZSBgYXdzdnBjYCBuZXR3b3JrIG1vZGUgYW5kIGEgdHlwZSBTUlYgRE5TIHJlY29yZCBpcyB1c2VkLCB5b3UgbXVzdCBzcGVjaWZ5IGVpdGhlciBhIGBjb250YWluZXJOYW1lYCBhbmQgYGNvbnRhaW5lclBvcnRgIGNvbWJpbmF0aW9uIG9yIGEgYHBvcnRgIHZhbHVlLiBIb3dldmVyLCB5b3UgY2FuJ3Qgc3BlY2lmeSBib3RoLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy1zZXJ2aWNlLXNlcnZpY2VyZWdpc3RyeS5odG1sI2Nmbi1lY3Mtc2VydmljZS1zZXJ2aWNlcmVnaXN0cnktY29udGFpbmVycG9ydFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY29udGFpbmVyUG9ydD86IG51bWJlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwb3J0IHZhbHVlIHVzZWQgaWYgeW91ciBzZXJ2aWNlIGRpc2NvdmVyeSBzZXJ2aWNlIHNwZWNpZmllZCBhbiBTUlYgcmVjb3JkLiBUaGlzIGZpZWxkIG1pZ2h0IGJlIHVzZWQgaWYgYm90aCB0aGUgYGF3c3ZwY2AgbmV0d29yayBtb2RlIGFuZCBTUlYgcmVjb3JkcyBhcmUgdXNlZC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3Mtc2VydmljZS1zZXJ2aWNlcmVnaXN0cnkuaHRtbCNjZm4tZWNzLXNlcnZpY2Utc2VydmljZXJlZ2lzdHJ5LXBvcnRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHBvcnQ/OiBudW1iZXI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIHNlcnZpY2UgcmVnaXN0cnkuIFRoZSBjdXJyZW50bHkgc3VwcG9ydGVkIHNlcnZpY2UgcmVnaXN0cnkgaXMgQVdTIENsb3VkIE1hcCAuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0NyZWF0ZVNlcnZpY2VdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbG91ZC1tYXAvbGF0ZXN0L2FwaS9BUElfQ3JlYXRlU2VydmljZS5odG1sKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXNlcnZpY2Utc2VydmljZXJlZ2lzdHJ5Lmh0bWwjY2ZuLWVjcy1zZXJ2aWNlLXNlcnZpY2VyZWdpc3RyeS1yZWdpc3RyeWFyblxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcmVnaXN0cnlBcm4/OiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYFNlcnZpY2VSZWdpc3RyeVByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBTZXJ2aWNlUmVnaXN0cnlQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5TZXJ2aWNlX1NlcnZpY2VSZWdpc3RyeVByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY29udGFpbmVyTmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jb250YWluZXJOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjb250YWluZXJQb3J0JywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLmNvbnRhaW5lclBvcnQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvcnQnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMucG9ydCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncmVnaXN0cnlBcm4nLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucmVnaXN0cnlBcm4pKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiU2VydmljZVJlZ2lzdHJ5UHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6U2VydmljZS5TZXJ2aWNlUmVnaXN0cnlgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYFNlcnZpY2VSZWdpc3RyeVByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlNlcnZpY2UuU2VydmljZVJlZ2lzdHJ5YCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblNlcnZpY2VTZXJ2aWNlUmVnaXN0cnlQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuU2VydmljZV9TZXJ2aWNlUmVnaXN0cnlQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQ29udGFpbmVyTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5jb250YWluZXJOYW1lKSxcbiAgICAgICAgQ29udGFpbmVyUG9ydDogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5jb250YWluZXJQb3J0KSxcbiAgICAgICAgUG9ydDogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wb3J0KSxcbiAgICAgICAgUmVnaXN0cnlBcm46IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucmVnaXN0cnlBcm4pLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5TZXJ2aWNlU2VydmljZVJlZ2lzdHJ5UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5TZXJ2aWNlLlNlcnZpY2VSZWdpc3RyeVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblNlcnZpY2UuU2VydmljZVJlZ2lzdHJ5UHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjb250YWluZXJOYW1lJywgJ0NvbnRhaW5lck5hbWUnLCBwcm9wZXJ0aWVzLkNvbnRhaW5lck5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQ29udGFpbmVyTmFtZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY29udGFpbmVyUG9ydCcsICdDb250YWluZXJQb3J0JywgcHJvcGVydGllcy5Db250YWluZXJQb3J0ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLkNvbnRhaW5lclBvcnQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BvcnQnLCAnUG9ydCcsIHByb3BlcnRpZXMuUG9ydCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5Qb3J0KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdyZWdpc3RyeUFybicsICdSZWdpc3RyeUFybicsIHByb3BlcnRpZXMuUmVnaXN0cnlBcm4gIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuUmVnaXN0cnlBcm4pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIGBDZm5UYXNrRGVmaW5pdGlvbmBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tkZWZpbml0aW9uLmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5UYXNrRGVmaW5pdGlvblByb3BzIHtcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiBjb250YWluZXIgZGVmaW5pdGlvbnMgaW4gSlNPTiBmb3JtYXQgdGhhdCBkZXNjcmliZSB0aGUgZGlmZmVyZW50IGNvbnRhaW5lcnMgdGhhdCBtYWtlIHVwIHlvdXIgdGFzay4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgY29udGFpbmVyIGRlZmluaXRpb24gcGFyYW1ldGVycyBhbmQgZGVmYXVsdHMsIHNlZSBbQW1hem9uIEVDUyBUYXNrIERlZmluaXRpb25zXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS90YXNrX2RlZmludGlvbnMuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbnNcbiAgICAgKi9cbiAgICByZWFkb25seSBjb250YWluZXJEZWZpbml0aW9ucz86IEFycmF5PENmblRhc2tEZWZpbml0aW9uLkNvbnRhaW5lckRlZmluaXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGBjcHVgIHVuaXRzIHVzZWQgYnkgdGhlIHRhc2suIElmIHlvdSB1c2UgdGhlIEVDMiBsYXVuY2ggdHlwZSwgdGhpcyBmaWVsZCBpcyBvcHRpb25hbC4gQW55IHZhbHVlIGNhbiBiZSB1c2VkLiBJZiB5b3UgdXNlIHRoZSBGYXJnYXRlIGxhdW5jaCB0eXBlLCB0aGlzIGZpZWxkIGlzIHJlcXVpcmVkLiBZb3UgbXVzdCB1c2Ugb25lIG9mIHRoZSBmb2xsb3dpbmcgdmFsdWVzLiBUaGUgdmFsdWUgdGhhdCB5b3UgY2hvb3NlIGRldGVybWluZXMgeW91ciByYW5nZSBvZiB2YWxpZCB2YWx1ZXMgZm9yIHRoZSBgbWVtb3J5YCBwYXJhbWV0ZXIuXG4gICAgICpcbiAgICAgKiBUaGUgQ1BVIHVuaXRzIGNhbm5vdCBiZSBsZXNzIHRoYW4gMSB2Q1BVIHdoZW4geW91IHVzZSBXaW5kb3dzIGNvbnRhaW5lcnMgb24gRmFyZ2F0ZS5cbiAgICAgKlxuICAgICAqIC0gMjU2ICguMjUgdkNQVSkgLSBBdmFpbGFibGUgYG1lbW9yeWAgdmFsdWVzOiA1MTIgKDAuNSBHQiksIDEwMjQgKDEgR0IpLCAyMDQ4ICgyIEdCKVxuICAgICAqIC0gNTEyICguNSB2Q1BVKSAtIEF2YWlsYWJsZSBgbWVtb3J5YCB2YWx1ZXM6IDEwMjQgKDEgR0IpLCAyMDQ4ICgyIEdCKSwgMzA3MiAoMyBHQiksIDQwOTYgKDQgR0IpXG4gICAgICogLSAxMDI0ICgxIHZDUFUpIC0gQXZhaWxhYmxlIGBtZW1vcnlgIHZhbHVlczogMjA0OCAoMiBHQiksIDMwNzIgKDMgR0IpLCA0MDk2ICg0IEdCKSwgNTEyMCAoNSBHQiksIDYxNDQgKDYgR0IpLCA3MTY4ICg3IEdCKSwgODE5MiAoOCBHQilcbiAgICAgKiAtIDIwNDggKDIgdkNQVSkgLSBBdmFpbGFibGUgYG1lbW9yeWAgdmFsdWVzOiA0MDk2ICg0IEdCKSBhbmQgMTYzODQgKDE2IEdCKSBpbiBpbmNyZW1lbnRzIG9mIDEwMjQgKDEgR0IpXG4gICAgICogLSA0MDk2ICg0IHZDUFUpIC0gQXZhaWxhYmxlIGBtZW1vcnlgIHZhbHVlczogODE5MiAoOCBHQikgYW5kIDMwNzIwICgzMCBHQikgaW4gaW5jcmVtZW50cyBvZiAxMDI0ICgxIEdCKVxuICAgICAqIC0gODE5MiAoOCB2Q1BVKSAtIEF2YWlsYWJsZSBgbWVtb3J5YCB2YWx1ZXM6IDE2IEdCIGFuZCA2MCBHQiBpbiA0IEdCIGluY3JlbWVudHNcbiAgICAgKlxuICAgICAqIFRoaXMgb3B0aW9uIHJlcXVpcmVzIExpbnV4IHBsYXRmb3JtIGAxLjQuMGAgb3IgbGF0ZXIuXG4gICAgICogLSAxNjM4NCAoMTZ2Q1BVKSAtIEF2YWlsYWJsZSBgbWVtb3J5YCB2YWx1ZXM6IDMyR0IgYW5kIDEyMCBHQiBpbiA4IEdCIGluY3JlbWVudHNcbiAgICAgKlxuICAgICAqIFRoaXMgb3B0aW9uIHJlcXVpcmVzIExpbnV4IHBsYXRmb3JtIGAxLjQuMGAgb3IgbGF0ZXIuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtdGFza2RlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWNwdVxuICAgICAqL1xuICAgIHJlYWRvbmx5IGNwdT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBlcGhlbWVyYWwgc3RvcmFnZSBzZXR0aW5ncyB0byB1c2UgZm9yIHRhc2tzIHJ1biB3aXRoIHRoZSB0YXNrIGRlZmluaXRpb24uXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtdGFza2RlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWVwaGVtZXJhbHN0b3JhZ2VcbiAgICAgKi9cbiAgICByZWFkb25seSBlcGhlbWVyYWxTdG9yYWdlPzogQ2ZuVGFza0RlZmluaXRpb24uRXBoZW1lcmFsU3RvcmFnZVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIG9mIHRoZSB0YXNrIGV4ZWN1dGlvbiByb2xlIHRoYXQgZ3JhbnRzIHRoZSBBbWF6b24gRUNTIGNvbnRhaW5lciBhZ2VudCBwZXJtaXNzaW9uIHRvIG1ha2UgQVdTIEFQSSBjYWxscyBvbiB5b3VyIGJlaGFsZi4gVGhlIHRhc2sgZXhlY3V0aW9uIElBTSByb2xlIGlzIHJlcXVpcmVkIGRlcGVuZGluZyBvbiB0aGUgcmVxdWlyZW1lbnRzIG9mIHlvdXIgdGFzay4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQW1hem9uIEVDUyB0YXNrIGV4ZWN1dGlvbiBJQU0gcm9sZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvdGFza19leGVjdXRpb25fSUFNX3JvbGUuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tZXhlY3V0aW9ucm9sZWFyblxuICAgICAqL1xuICAgIHJlYWRvbmx5IGV4ZWN1dGlvblJvbGVBcm4/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiBhIGZhbWlseSB0aGF0IHRoaXMgdGFzayBkZWZpbml0aW9uIGlzIHJlZ2lzdGVyZWQgdG8uIFVwIHRvIDI1NSBsZXR0ZXJzICh1cHBlcmNhc2UgYW5kIGxvd2VyY2FzZSksIG51bWJlcnMsIGh5cGhlbnMsIGFuZCB1bmRlcnNjb3JlcyBhcmUgYWxsb3dlZC5cbiAgICAgKlxuICAgICAqIEEgZmFtaWx5IGdyb3VwcyBtdWx0aXBsZSB2ZXJzaW9ucyBvZiBhIHRhc2sgZGVmaW5pdGlvbi4gQW1hem9uIEVDUyBnaXZlcyB0aGUgZmlyc3QgdGFzayBkZWZpbml0aW9uIHRoYXQgeW91IHJlZ2lzdGVyZWQgdG8gYSBmYW1pbHkgYSByZXZpc2lvbiBudW1iZXIgb2YgMS4gQW1hem9uIEVDUyBnaXZlcyBzZXF1ZW50aWFsIHJldmlzaW9uIG51bWJlcnMgdG8gZWFjaCB0YXNrIGRlZmluaXRpb24gdGhhdCB5b3UgYWRkLlxuICAgICAqXG4gICAgICogPiBUbyB1c2UgcmV2aXNpb24gbnVtYmVycyB3aGVuIHlvdSB1cGRhdGUgYSB0YXNrIGRlZmluaXRpb24sIHNwZWNpZnkgdGhpcyBwcm9wZXJ0eS4gSWYgeW91IGRvbid0IHNwZWNpZnkgYSB2YWx1ZSwgQVdTIENsb3VkRm9ybWF0aW9uIGdlbmVyYXRlcyBhIG5ldyB0YXNrIGRlZmluaXRpb24gZWFjaCB0aW1lIHRoYXQgeW91IHVwZGF0ZSBpdC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tZmFtaWx5XG4gICAgICovXG4gICAgcmVhZG9ubHkgZmFtaWx5Pzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIEVsYXN0aWMgSW5mZXJlbmNlIGFjY2VsZXJhdG9ycyB0byB1c2UgZm9yIHRoZSBjb250YWluZXJzIGluIHRoZSB0YXNrLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1pbmZlcmVuY2VhY2NlbGVyYXRvcnNcbiAgICAgKi9cbiAgICByZWFkb25seSBpbmZlcmVuY2VBY2NlbGVyYXRvcnM/OiBBcnJheTxDZm5UYXNrRGVmaW5pdGlvbi5JbmZlcmVuY2VBY2NlbGVyYXRvclByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBJUEMgcmVzb3VyY2UgbmFtZXNwYWNlIHRvIHVzZSBmb3IgdGhlIGNvbnRhaW5lcnMgaW4gdGhlIHRhc2suIFRoZSB2YWxpZCB2YWx1ZXMgYXJlIGBob3N0YCAsIGB0YXNrYCAsIG9yIGBub25lYCAuIElmIGBob3N0YCBpcyBzcGVjaWZpZWQsIHRoZW4gYWxsIGNvbnRhaW5lcnMgd2l0aGluIHRoZSB0YXNrcyB0aGF0IHNwZWNpZmllZCB0aGUgYGhvc3RgIElQQyBtb2RlIG9uIHRoZSBzYW1lIGNvbnRhaW5lciBpbnN0YW5jZSBzaGFyZSB0aGUgc2FtZSBJUEMgcmVzb3VyY2VzIHdpdGggdGhlIGhvc3QgQW1hem9uIEVDMiBpbnN0YW5jZS4gSWYgYHRhc2tgIGlzIHNwZWNpZmllZCwgYWxsIGNvbnRhaW5lcnMgd2l0aGluIHRoZSBzcGVjaWZpZWQgdGFzayBzaGFyZSB0aGUgc2FtZSBJUEMgcmVzb3VyY2VzLiBJZiBgbm9uZWAgaXMgc3BlY2lmaWVkLCB0aGVuIElQQyByZXNvdXJjZXMgd2l0aGluIHRoZSBjb250YWluZXJzIG9mIGEgdGFzayBhcmUgcHJpdmF0ZSBhbmQgbm90IHNoYXJlZCB3aXRoIG90aGVyIGNvbnRhaW5lcnMgaW4gYSB0YXNrIG9yIG9uIHRoZSBjb250YWluZXIgaW5zdGFuY2UuIElmIG5vIHZhbHVlIGlzIHNwZWNpZmllZCwgdGhlbiB0aGUgSVBDIHJlc291cmNlIG5hbWVzcGFjZSBzaGFyaW5nIGRlcGVuZHMgb24gdGhlIERvY2tlciBkYWVtb24gc2V0dGluZyBvbiB0aGUgY29udGFpbmVyIGluc3RhbmNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtJUEMgc2V0dGluZ3NdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jaXBjLXNldHRpbmdzLS0taXBjKSBpbiB0aGUgKkRvY2tlciBydW4gcmVmZXJlbmNlKiAuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgYGhvc3RgIElQQyBtb2RlIGlzIHVzZWQsIGJlIGF3YXJlIHRoYXQgdGhlcmUgaXMgYSBoZWlnaHRlbmVkIHJpc2sgb2YgdW5kZXNpcmVkIElQQyBuYW1lc3BhY2UgZXhwb3NlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtEb2NrZXIgc2VjdXJpdHldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvc2VjdXJpdHkvc2VjdXJpdHkvKSAuXG4gICAgICpcbiAgICAgKiBJZiB5b3UgYXJlIHNldHRpbmcgbmFtZXNwYWNlZCBrZXJuZWwgcGFyYW1ldGVycyB1c2luZyBgc3lzdGVtQ29udHJvbHNgIGZvciB0aGUgY29udGFpbmVycyBpbiB0aGUgdGFzaywgdGhlIGZvbGxvd2luZyB3aWxsIGFwcGx5IHRvIHlvdXIgSVBDIHJlc291cmNlIG5hbWVzcGFjZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbU3lzdGVtIENvbnRyb2xzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS90YXNrX2RlZmluaXRpb25fcGFyYW1ldGVycy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogLSBGb3IgdGFza3MgdGhhdCB1c2UgdGhlIGBob3N0YCBJUEMgbW9kZSwgSVBDIG5hbWVzcGFjZSByZWxhdGVkIGBzeXN0ZW1Db250cm9sc2AgYXJlIG5vdCBzdXBwb3J0ZWQuXG4gICAgICogLSBGb3IgdGFza3MgdGhhdCB1c2UgdGhlIGB0YXNrYCBJUEMgbW9kZSwgSVBDIG5hbWVzcGFjZSByZWxhdGVkIGBzeXN0ZW1Db250cm9sc2Agd2lsbCBhcHBseSB0byBhbGwgY29udGFpbmVycyB3aXRoaW4gYSB0YXNrLlxuICAgICAqXG4gICAgICogPiBUaGlzIHBhcmFtZXRlciBpcyBub3Qgc3VwcG9ydGVkIGZvciBXaW5kb3dzIGNvbnRhaW5lcnMgb3IgdGFza3MgcnVuIG9uIEFXUyBGYXJnYXRlIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24taXBjbW9kZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IGlwY01vZGU/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYW1vdW50IChpbiBNaUIpIG9mIG1lbW9yeSB1c2VkIGJ5IHRoZSB0YXNrLlxuICAgICAqXG4gICAgICogSWYgeW91ciB0YXNrcyBydW5zIG9uIEFtYXpvbiBFQzIgaW5zdGFuY2VzLCB5b3UgbXVzdCBzcGVjaWZ5IGVpdGhlciBhIHRhc2stbGV2ZWwgbWVtb3J5IHZhbHVlIG9yIGEgY29udGFpbmVyLWxldmVsIG1lbW9yeSB2YWx1ZS4gVGhpcyBmaWVsZCBpcyBvcHRpb25hbCBhbmQgYW55IHZhbHVlIGNhbiBiZSB1c2VkLiBJZiBhIHRhc2stbGV2ZWwgbWVtb3J5IHZhbHVlIGlzIHNwZWNpZmllZCwgdGhlIGNvbnRhaW5lci1sZXZlbCBtZW1vcnkgdmFsdWUgaXMgb3B0aW9uYWwuIEZvciBtb3JlIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb250YWluZXItbGV2ZWwgbWVtb3J5IGFuZCBtZW1vcnkgcmVzZXJ2YXRpb24sIHNlZSBbQ29udGFpbmVyRGVmaW5pdGlvbl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9Db250YWluZXJEZWZpbml0aW9uLmh0bWwpIC5cbiAgICAgKlxuICAgICAqIElmIHlvdXIgdGFza3MgcnVucyBvbiBBV1MgRmFyZ2F0ZSAsIHRoaXMgZmllbGQgaXMgcmVxdWlyZWQuIFlvdSBtdXN0IHVzZSBvbmUgb2YgdGhlIGZvbGxvd2luZyB2YWx1ZXMuIFRoZSB2YWx1ZSB5b3UgY2hvb3NlIGRldGVybWluZXMgeW91ciByYW5nZSBvZiB2YWxpZCB2YWx1ZXMgZm9yIHRoZSBgY3B1YCBwYXJhbWV0ZXIuXG4gICAgICpcbiAgICAgKiAtIDUxMiAoMC41IEdCKSwgMTAyNCAoMSBHQiksIDIwNDggKDIgR0IpIC0gQXZhaWxhYmxlIGBjcHVgIHZhbHVlczogMjU2ICguMjUgdkNQVSlcbiAgICAgKiAtIDEwMjQgKDEgR0IpLCAyMDQ4ICgyIEdCKSwgMzA3MiAoMyBHQiksIDQwOTYgKDQgR0IpIC0gQXZhaWxhYmxlIGBjcHVgIHZhbHVlczogNTEyICguNSB2Q1BVKVxuICAgICAqIC0gMjA0OCAoMiBHQiksIDMwNzIgKDMgR0IpLCA0MDk2ICg0IEdCKSwgNTEyMCAoNSBHQiksIDYxNDQgKDYgR0IpLCA3MTY4ICg3IEdCKSwgODE5MiAoOCBHQikgLSBBdmFpbGFibGUgYGNwdWAgdmFsdWVzOiAxMDI0ICgxIHZDUFUpXG4gICAgICogLSBCZXR3ZWVuIDQwOTYgKDQgR0IpIGFuZCAxNjM4NCAoMTYgR0IpIGluIGluY3JlbWVudHMgb2YgMTAyNCAoMSBHQikgLSBBdmFpbGFibGUgYGNwdWAgdmFsdWVzOiAyMDQ4ICgyIHZDUFUpXG4gICAgICogLSBCZXR3ZWVuIDgxOTIgKDggR0IpIGFuZCAzMDcyMCAoMzAgR0IpIGluIGluY3JlbWVudHMgb2YgMTAyNCAoMSBHQikgLSBBdmFpbGFibGUgYGNwdWAgdmFsdWVzOiA0MDk2ICg0IHZDUFUpXG4gICAgICogLSBCZXR3ZWVuIDE2IEdCIGFuZCA2MCBHQiBpbiA0IEdCIGluY3JlbWVudHMgLSBBdmFpbGFibGUgYGNwdWAgdmFsdWVzOiA4MTkyICg4IHZDUFUpXG4gICAgICpcbiAgICAgKiBUaGlzIG9wdGlvbiByZXF1aXJlcyBMaW51eCBwbGF0Zm9ybSBgMS40LjBgIG9yIGxhdGVyLlxuICAgICAqIC0gQmV0d2VlbiAzMkdCIGFuZCAxMjAgR0IgaW4gOCBHQiBpbmNyZW1lbnRzIC0gQXZhaWxhYmxlIGBjcHVgIHZhbHVlczogMTYzODQgKDE2IHZDUFUpXG4gICAgICpcbiAgICAgKiBUaGlzIG9wdGlvbiByZXF1aXJlcyBMaW51eCBwbGF0Zm9ybSBgMS40LjBgIG9yIGxhdGVyLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1tZW1vcnlcbiAgICAgKi9cbiAgICByZWFkb25seSBtZW1vcnk/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgRG9ja2VyIG5ldHdvcmtpbmcgbW9kZSB0byB1c2UgZm9yIHRoZSBjb250YWluZXJzIGluIHRoZSB0YXNrLiBUaGUgdmFsaWQgdmFsdWVzIGFyZSBgbm9uZWAgLCBgYnJpZGdlYCAsIGBhd3N2cGNgICwgYW5kIGBob3N0YCAuIElmIG5vIG5ldHdvcmsgbW9kZSBpcyBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IGlzIGBicmlkZ2VgIC5cbiAgICAgKlxuICAgICAqIEZvciBBbWF6b24gRUNTIHRhc2tzIG9uIEZhcmdhdGUsIHRoZSBgYXdzdnBjYCBuZXR3b3JrIG1vZGUgaXMgcmVxdWlyZWQuIEZvciBBbWF6b24gRUNTIHRhc2tzIG9uIEFtYXpvbiBFQzIgTGludXggaW5zdGFuY2VzLCBhbnkgbmV0d29yayBtb2RlIGNhbiBiZSB1c2VkLiBGb3IgQW1hem9uIEVDUyB0YXNrcyBvbiBBbWF6b24gRUMyIFdpbmRvd3MgaW5zdGFuY2VzLCBgPGRlZmF1bHQ+YCBvciBgYXdzdnBjYCBjYW4gYmUgdXNlZC4gSWYgdGhlIG5ldHdvcmsgbW9kZSBpcyBzZXQgdG8gYG5vbmVgICwgeW91IGNhbm5vdCBzcGVjaWZ5IHBvcnQgbWFwcGluZ3MgaW4geW91ciBjb250YWluZXIgZGVmaW5pdGlvbnMsIGFuZCB0aGUgdGFza3MgY29udGFpbmVycyBkbyBub3QgaGF2ZSBleHRlcm5hbCBjb25uZWN0aXZpdHkuIFRoZSBgaG9zdGAgYW5kIGBhd3N2cGNgIG5ldHdvcmsgbW9kZXMgb2ZmZXIgdGhlIGhpZ2hlc3QgbmV0d29ya2luZyBwZXJmb3JtYW5jZSBmb3IgY29udGFpbmVycyBiZWNhdXNlIHRoZXkgdXNlIHRoZSBFQzIgbmV0d29yayBzdGFjayBpbnN0ZWFkIG9mIHRoZSB2aXJ0dWFsaXplZCBuZXR3b3JrIHN0YWNrIHByb3ZpZGVkIGJ5IHRoZSBgYnJpZGdlYCBtb2RlLlxuICAgICAqXG4gICAgICogV2l0aCB0aGUgYGhvc3RgIGFuZCBgYXdzdnBjYCBuZXR3b3JrIG1vZGVzLCBleHBvc2VkIGNvbnRhaW5lciBwb3J0cyBhcmUgbWFwcGVkIGRpcmVjdGx5IHRvIHRoZSBjb3JyZXNwb25kaW5nIGhvc3QgcG9ydCAoZm9yIHRoZSBgaG9zdGAgbmV0d29yayBtb2RlKSBvciB0aGUgYXR0YWNoZWQgZWxhc3RpYyBuZXR3b3JrIGludGVyZmFjZSBwb3J0IChmb3IgdGhlIGBhd3N2cGNgIG5ldHdvcmsgbW9kZSksIHNvIHlvdSBjYW5ub3QgdGFrZSBhZHZhbnRhZ2Ugb2YgZHluYW1pYyBob3N0IHBvcnQgbWFwcGluZ3MuXG4gICAgICpcbiAgICAgKiA+IFdoZW4gdXNpbmcgdGhlIGBob3N0YCBuZXR3b3JrIG1vZGUsIHlvdSBzaG91bGQgbm90IHJ1biBjb250YWluZXJzIHVzaW5nIHRoZSByb290IHVzZXIgKFVJRCAwKS4gSXQgaXMgY29uc2lkZXJlZCBiZXN0IHByYWN0aWNlIHRvIHVzZSBhIG5vbi1yb290IHVzZXIuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgbmV0d29yayBtb2RlIGlzIGBhd3N2cGNgICwgdGhlIHRhc2sgaXMgYWxsb2NhdGVkIGFuIGVsYXN0aWMgbmV0d29yayBpbnRlcmZhY2UsIGFuZCB5b3UgbXVzdCBzcGVjaWZ5IGEgYE5ldHdvcmtDb25maWd1cmF0aW9uYCB2YWx1ZSB3aGVuIHlvdSBjcmVhdGUgYSBzZXJ2aWNlIG9yIHJ1biBhIHRhc2sgd2l0aCB0aGUgdGFzayBkZWZpbml0aW9uLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtUYXNrIE5ldHdvcmtpbmddKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3Rhc2stbmV0d29ya2luZy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogSWYgdGhlIG5ldHdvcmsgbW9kZSBpcyBgaG9zdGAgLCB5b3UgY2Fubm90IHJ1biBtdWx0aXBsZSBpbnN0YW50aWF0aW9ucyBvZiB0aGUgc2FtZSB0YXNrIG9uIGEgc2luZ2xlIGNvbnRhaW5lciBpbnN0YW5jZSB3aGVuIHBvcnQgbWFwcGluZ3MgYXJlIHVzZWQuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtOZXR3b3JrIHNldHRpbmdzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vI25ldHdvcmstc2V0dGluZ3MpIGluIHRoZSAqRG9ja2VyIHJ1biByZWZlcmVuY2UqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tbmV0d29ya21vZGVcbiAgICAgKi9cbiAgICByZWFkb25seSBuZXR3b3JrTW9kZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBwcm9jZXNzIG5hbWVzcGFjZSB0byB1c2UgZm9yIHRoZSBjb250YWluZXJzIGluIHRoZSB0YXNrLiBUaGUgdmFsaWQgdmFsdWVzIGFyZSBgaG9zdGAgb3IgYHRhc2tgIC4gSWYgYGhvc3RgIGlzIHNwZWNpZmllZCwgdGhlbiBhbGwgY29udGFpbmVycyB3aXRoaW4gdGhlIHRhc2tzIHRoYXQgc3BlY2lmaWVkIHRoZSBgaG9zdGAgUElEIG1vZGUgb24gdGhlIHNhbWUgY29udGFpbmVyIGluc3RhbmNlIHNoYXJlIHRoZSBzYW1lIHByb2Nlc3MgbmFtZXNwYWNlIHdpdGggdGhlIGhvc3QgQW1hem9uIEVDMiBpbnN0YW5jZS4gSWYgYHRhc2tgIGlzIHNwZWNpZmllZCwgYWxsIGNvbnRhaW5lcnMgd2l0aGluIHRoZSBzcGVjaWZpZWQgdGFzayBzaGFyZSB0aGUgc2FtZSBwcm9jZXNzIG5hbWVzcGFjZS4gSWYgbm8gdmFsdWUgaXMgc3BlY2lmaWVkLCB0aGUgZGVmYXVsdCBpcyBhIHByaXZhdGUgbmFtZXNwYWNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtQSUQgc2V0dGluZ3NdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jcGlkLXNldHRpbmdzLS0tcGlkKSBpbiB0aGUgKkRvY2tlciBydW4gcmVmZXJlbmNlKiAuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgYGhvc3RgIFBJRCBtb2RlIGlzIHVzZWQsIGJlIGF3YXJlIHRoYXQgdGhlcmUgaXMgYSBoZWlnaHRlbmVkIHJpc2sgb2YgdW5kZXNpcmVkIHByb2Nlc3MgbmFtZXNwYWNlIGV4cG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbRG9ja2VyIHNlY3VyaXR5XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3NlY3VyaXR5L3NlY3VyaXR5LykgLlxuICAgICAqXG4gICAgICogPiBUaGlzIHBhcmFtZXRlciBpcyBub3Qgc3VwcG9ydGVkIGZvciBXaW5kb3dzIGNvbnRhaW5lcnMgb3IgdGFza3MgcnVuIG9uIEFXUyBGYXJnYXRlIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tcGlkbW9kZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IHBpZE1vZGU/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBbiBhcnJheSBvZiBwbGFjZW1lbnQgY29uc3RyYWludCBvYmplY3RzIHRvIHVzZSBmb3IgdGFza3MuXG4gICAgICpcbiAgICAgKiA+IFRoaXMgcGFyYW1ldGVyIGlzbid0IHN1cHBvcnRlZCBmb3IgdGFza3MgcnVuIG9uIEFXUyBGYXJnYXRlIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tcGxhY2VtZW50Y29uc3RyYWludHNcbiAgICAgKi9cbiAgICByZWFkb25seSBwbGFjZW1lbnRDb25zdHJhaW50cz86IEFycmF5PENmblRhc2tEZWZpbml0aW9uLlRhc2tEZWZpbml0aW9uUGxhY2VtZW50Q29uc3RyYWludFByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjb25maWd1cmF0aW9uIGRldGFpbHMgZm9yIHRoZSBBcHAgTWVzaCBwcm94eS5cbiAgICAgKlxuICAgICAqIFlvdXIgQW1hem9uIEVDUyBjb250YWluZXIgaW5zdGFuY2VzIHJlcXVpcmUgYXQgbGVhc3QgdmVyc2lvbiAxLjI2LjAgb2YgdGhlIGNvbnRhaW5lciBhZ2VudCBhbmQgYXQgbGVhc3QgdmVyc2lvbiAxLjI2LjAtMSBvZiB0aGUgYGVjcy1pbml0YCBwYWNrYWdlIHRvIHVzZSBhIHByb3h5IGNvbmZpZ3VyYXRpb24uIElmIHlvdXIgY29udGFpbmVyIGluc3RhbmNlcyBhcmUgbGF1bmNoZWQgZnJvbSB0aGUgQW1hem9uIEVDUyBvcHRpbWl6ZWQgQU1JIHZlcnNpb24gYDIwMTkwMzAxYCBvciBsYXRlciwgdGhleSBjb250YWluIHRoZSByZXF1aXJlZCB2ZXJzaW9ucyBvZiB0aGUgY29udGFpbmVyIGFnZW50IGFuZCBgZWNzLWluaXRgIC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQW1hem9uIEVDUy1vcHRpbWl6ZWQgTGludXggQU1JXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9lY3Mtb3B0aW1pemVkX0FNSS5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1wcm94eWNvbmZpZ3VyYXRpb25cbiAgICAgKi9cbiAgICByZWFkb25seSBwcm94eUNvbmZpZ3VyYXRpb24/OiBDZm5UYXNrRGVmaW5pdGlvbi5Qcm94eUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0YXNrIGxhdW5jaCB0eXBlcyB0aGUgdGFzayBkZWZpbml0aW9uIHdhcyB2YWxpZGF0ZWQgYWdhaW5zdC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQW1hem9uIEVDUyBsYXVuY2ggdHlwZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2xhdW5jaF90eXBlcy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1yZXF1aXJlc2NvbXBhdGliaWxpdGllc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IHJlcXVpcmVzQ29tcGF0aWJpbGl0aWVzPzogc3RyaW5nW107XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3BlcmF0aW5nIHN5c3RlbSB0aGF0IHlvdXIgdGFza3MgZGVmaW5pdGlvbnMgcnVuIG9uLiBBIHBsYXRmb3JtIGZhbWlseSBpcyBzcGVjaWZpZWQgb25seSBmb3IgdGFza3MgdXNpbmcgdGhlIEZhcmdhdGUgbGF1bmNoIHR5cGUuXG4gICAgICpcbiAgICAgKiBXaGVuIHlvdSBzcGVjaWZ5IGEgdGFzayBkZWZpbml0aW9uIGluIGEgc2VydmljZSwgdGhpcyB2YWx1ZSBtdXN0IG1hdGNoIHRoZSBgcnVudGltZVBsYXRmb3JtYCB2YWx1ZSBvZiB0aGUgc2VydmljZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tcnVudGltZXBsYXRmb3JtXG4gICAgICovXG4gICAgcmVhZG9ubHkgcnVudGltZVBsYXRmb3JtPzogQ2ZuVGFza0RlZmluaXRpb24uUnVudGltZVBsYXRmb3JtUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWV0YWRhdGEgdGhhdCB5b3UgYXBwbHkgdG8gdGhlIHRhc2sgZGVmaW5pdGlvbiB0byBoZWxwIHlvdSBjYXRlZ29yaXplIGFuZCBvcmdhbml6ZSB0aGVtLiBFYWNoIHRhZyBjb25zaXN0cyBvZiBhIGtleSBhbmQgYW4gb3B0aW9uYWwgdmFsdWUuIFlvdSBkZWZpbmUgYm90aCBvZiB0aGVtLlxuICAgICAqXG4gICAgICogVGhlIGZvbGxvd2luZyBiYXNpYyByZXN0cmljdGlvbnMgYXBwbHkgdG8gdGFnczpcbiAgICAgKlxuICAgICAqIC0gTWF4aW11bSBudW1iZXIgb2YgdGFncyBwZXIgcmVzb3VyY2UgLSA1MFxuICAgICAqIC0gRm9yIGVhY2ggcmVzb3VyY2UsIGVhY2ggdGFnIGtleSBtdXN0IGJlIHVuaXF1ZSwgYW5kIGVhY2ggdGFnIGtleSBjYW4gaGF2ZSBvbmx5IG9uZSB2YWx1ZS5cbiAgICAgKiAtIE1heGltdW0ga2V5IGxlbmd0aCAtIDEyOCBVbmljb2RlIGNoYXJhY3RlcnMgaW4gVVRGLThcbiAgICAgKiAtIE1heGltdW0gdmFsdWUgbGVuZ3RoIC0gMjU2IFVuaWNvZGUgY2hhcmFjdGVycyBpbiBVVEYtOFxuICAgICAqIC0gSWYgeW91ciB0YWdnaW5nIHNjaGVtYSBpcyB1c2VkIGFjcm9zcyBtdWx0aXBsZSBzZXJ2aWNlcyBhbmQgcmVzb3VyY2VzLCByZW1lbWJlciB0aGF0IG90aGVyIHNlcnZpY2VzIG1heSBoYXZlIHJlc3RyaWN0aW9ucyBvbiBhbGxvd2VkIGNoYXJhY3RlcnMuIEdlbmVyYWxseSBhbGxvd2VkIGNoYXJhY3RlcnMgYXJlOiBsZXR0ZXJzLCBudW1iZXJzLCBhbmQgc3BhY2VzIHJlcHJlc2VudGFibGUgaW4gVVRGLTgsIGFuZCB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6ICsgLSA9IC4gXyA6IC8gQC5cbiAgICAgKiAtIFRhZyBrZXlzIGFuZCB2YWx1ZXMgYXJlIGNhc2Utc2Vuc2l0aXZlLlxuICAgICAqIC0gRG8gbm90IHVzZSBgYXdzOmAgLCBgQVdTOmAgLCBvciBhbnkgdXBwZXIgb3IgbG93ZXJjYXNlIGNvbWJpbmF0aW9uIG9mIHN1Y2ggYXMgYSBwcmVmaXggZm9yIGVpdGhlciBrZXlzIG9yIHZhbHVlcyBhcyBpdCBpcyByZXNlcnZlZCBmb3IgQVdTIHVzZS4gWW91IGNhbm5vdCBlZGl0IG9yIGRlbGV0ZSB0YWcga2V5cyBvciB2YWx1ZXMgd2l0aCB0aGlzIHByZWZpeC4gVGFncyB3aXRoIHRoaXMgcHJlZml4IGRvIG5vdCBjb3VudCBhZ2FpbnN0IHlvdXIgdGFncyBwZXIgcmVzb3VyY2UgbGltaXQuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtdGFza2RlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLXRhZ3NcbiAgICAgKi9cbiAgICByZWFkb25seSB0YWdzPzogY2RrLkNmblRhZ1tdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHNob3J0IG5hbWUgb3IgZnVsbCBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgQVdTIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCByb2xlIHRoYXQgZ3JhbnRzIGNvbnRhaW5lcnMgaW4gdGhlIHRhc2sgcGVybWlzc2lvbiB0byBjYWxsIEFXUyBBUElzIG9uIHlvdXIgYmVoYWxmLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBbWF6b24gRUNTIFRhc2sgUm9sZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvdGFzay1pYW0tcm9sZXMuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIElBTSByb2xlcyBmb3IgdGFza3Mgb24gV2luZG93cyByZXF1aXJlIHRoYXQgdGhlIGAtRW5hYmxlVGFza0lBTVJvbGVgIG9wdGlvbiBpcyBzZXQgd2hlbiB5b3UgbGF1bmNoIHRoZSBBbWF6b24gRUNTLW9wdGltaXplZCBXaW5kb3dzIEFNSS4gWW91ciBjb250YWluZXJzIG11c3QgYWxzbyBydW4gc29tZSBjb25maWd1cmF0aW9uIGNvZGUgdG8gdXNlIHRoZSBmZWF0dXJlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtXaW5kb3dzIElBTSByb2xlcyBmb3IgdGFza3NdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3dpbmRvd3NfdGFza19JQU1fcm9sZXMuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tdGFza3JvbGVhcm5cbiAgICAgKi9cbiAgICByZWFkb25seSB0YXNrUm9sZUFybj86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBsaXN0IG9mIGRhdGEgdm9sdW1lIGRlZmluaXRpb25zIGZvciB0aGUgdGFzay4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbVXNpbmcgZGF0YSB2b2x1bWVzIGluIHRhc2tzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS91c2luZ19kYXRhX3ZvbHVtZXMuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqID4gVGhlIGBob3N0YCBhbmQgYHNvdXJjZVBhdGhgIHBhcmFtZXRlcnMgYXJlbid0IHN1cHBvcnRlZCBmb3IgdGFza3MgcnVuIG9uIEFXUyBGYXJnYXRlIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tdm9sdW1lc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IHZvbHVtZXM/OiBBcnJheTxDZm5UYXNrRGVmaW5pdGlvbi5Wb2x1bWVQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGU7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgQ2ZuVGFza0RlZmluaXRpb25Qcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuVGFza0RlZmluaXRpb25Qcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvblByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY29udGFpbmVyRGVmaW5pdGlvbnMnLCBjZGsubGlzdFZhbGlkYXRvcihDZm5UYXNrRGVmaW5pdGlvbl9Db250YWluZXJEZWZpbml0aW9uUHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLmNvbnRhaW5lckRlZmluaXRpb25zKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjcHUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY3B1KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdlcGhlbWVyYWxTdG9yYWdlJywgQ2ZuVGFza0RlZmluaXRpb25fRXBoZW1lcmFsU3RvcmFnZVByb3BlcnR5VmFsaWRhdG9yKShwcm9wZXJ0aWVzLmVwaGVtZXJhbFN0b3JhZ2UpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2V4ZWN1dGlvblJvbGVBcm4nLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuZXhlY3V0aW9uUm9sZUFybikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZmFtaWx5JywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmZhbWlseSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaW5mZXJlbmNlQWNjZWxlcmF0b3JzJywgY2RrLmxpc3RWYWxpZGF0b3IoQ2ZuVGFza0RlZmluaXRpb25fSW5mZXJlbmNlQWNjZWxlcmF0b3JQcm9wZXJ0eVZhbGlkYXRvcikpKHByb3BlcnRpZXMuaW5mZXJlbmNlQWNjZWxlcmF0b3JzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdpcGNNb2RlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmlwY01vZGUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ21lbW9yeScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5tZW1vcnkpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ25ldHdvcmtNb2RlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLm5ldHdvcmtNb2RlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwaWRNb2RlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnBpZE1vZGUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BsYWNlbWVudENvbnN0cmFpbnRzJywgY2RrLmxpc3RWYWxpZGF0b3IoQ2ZuVGFza0RlZmluaXRpb25fVGFza0RlZmluaXRpb25QbGFjZW1lbnRDb25zdHJhaW50UHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLnBsYWNlbWVudENvbnN0cmFpbnRzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwcm94eUNvbmZpZ3VyYXRpb24nLCBDZm5UYXNrRGVmaW5pdGlvbl9Qcm94eUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5wcm94eUNvbmZpZ3VyYXRpb24pKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3JlcXVpcmVzQ29tcGF0aWJpbGl0aWVzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5yZXF1aXJlc0NvbXBhdGliaWxpdGllcykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncnVudGltZVBsYXRmb3JtJywgQ2ZuVGFza0RlZmluaXRpb25fUnVudGltZVBsYXRmb3JtUHJvcGVydHlWYWxpZGF0b3IpKHByb3BlcnRpZXMucnVudGltZVBsYXRmb3JtKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0YWdzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlQ2ZuVGFnKSkocHJvcGVydGllcy50YWdzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0YXNrUm9sZUFybicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy50YXNrUm9sZUFybikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndm9sdW1lcycsIGNkay5saXN0VmFsaWRhdG9yKENmblRhc2tEZWZpbml0aW9uX1ZvbHVtZVByb3BlcnR5VmFsaWRhdG9yKSkocHJvcGVydGllcy52b2x1bWVzKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNmblRhc2tEZWZpbml0aW9uUHJvcHNcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb25gIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblRhc2tEZWZpbml0aW9uUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb25gIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuVGFza0RlZmluaXRpb25Qcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVGFza0RlZmluaXRpb25Qcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQ29udGFpbmVyRGVmaW5pdGlvbnM6IGNkay5saXN0TWFwcGVyKGNmblRhc2tEZWZpbml0aW9uQ29udGFpbmVyRGVmaW5pdGlvblByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5jb250YWluZXJEZWZpbml0aW9ucyksXG4gICAgICAgIENwdTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5jcHUpLFxuICAgICAgICBFcGhlbWVyYWxTdG9yYWdlOiBjZm5UYXNrRGVmaW5pdGlvbkVwaGVtZXJhbFN0b3JhZ2VQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5lcGhlbWVyYWxTdG9yYWdlKSxcbiAgICAgICAgRXhlY3V0aW9uUm9sZUFybjogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5leGVjdXRpb25Sb2xlQXJuKSxcbiAgICAgICAgRmFtaWx5OiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmZhbWlseSksXG4gICAgICAgIEluZmVyZW5jZUFjY2VsZXJhdG9yczogY2RrLmxpc3RNYXBwZXIoY2ZuVGFza0RlZmluaXRpb25JbmZlcmVuY2VBY2NlbGVyYXRvclByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5pbmZlcmVuY2VBY2NlbGVyYXRvcnMpLFxuICAgICAgICBJcGNNb2RlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmlwY01vZGUpLFxuICAgICAgICBNZW1vcnk6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubWVtb3J5KSxcbiAgICAgICAgTmV0d29ya01vZGU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubmV0d29ya01vZGUpLFxuICAgICAgICBQaWRNb2RlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBpZE1vZGUpLFxuICAgICAgICBQbGFjZW1lbnRDb25zdHJhaW50czogY2RrLmxpc3RNYXBwZXIoY2ZuVGFza0RlZmluaXRpb25UYXNrRGVmaW5pdGlvblBsYWNlbWVudENvbnN0cmFpbnRQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMucGxhY2VtZW50Q29uc3RyYWludHMpLFxuICAgICAgICBQcm94eUNvbmZpZ3VyYXRpb246IGNmblRhc2tEZWZpbml0aW9uUHJveHlDb25maWd1cmF0aW9uUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucHJveHlDb25maWd1cmF0aW9uKSxcbiAgICAgICAgUmVxdWlyZXNDb21wYXRpYmlsaXRpZXM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnJlcXVpcmVzQ29tcGF0aWJpbGl0aWVzKSxcbiAgICAgICAgUnVudGltZVBsYXRmb3JtOiBjZm5UYXNrRGVmaW5pdGlvblJ1bnRpbWVQbGF0Zm9ybVByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnJ1bnRpbWVQbGF0Zm9ybSksXG4gICAgICAgIFRhZ3M6IGNkay5saXN0TWFwcGVyKGNkay5jZm5UYWdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnRhZ3MpLFxuICAgICAgICBUYXNrUm9sZUFybjogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy50YXNrUm9sZUFybiksXG4gICAgICAgIFZvbHVtZXM6IGNkay5saXN0TWFwcGVyKGNmblRhc2tEZWZpbml0aW9uVm9sdW1lUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnZvbHVtZXMpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvblByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb25Qcm9wcz4ge1xuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVGFza0RlZmluaXRpb25Qcm9wcz4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2NvbnRhaW5lckRlZmluaXRpb25zJywgJ0NvbnRhaW5lckRlZmluaXRpb25zJywgcHJvcGVydGllcy5Db250YWluZXJEZWZpbml0aW9ucyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5UYXNrRGVmaW5pdGlvbkNvbnRhaW5lckRlZmluaXRpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5Db250YWluZXJEZWZpbml0aW9ucykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY3B1JywgJ0NwdScsIHByb3BlcnRpZXMuQ3B1ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNwdSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZXBoZW1lcmFsU3RvcmFnZScsICdFcGhlbWVyYWxTdG9yYWdlJywgcHJvcGVydGllcy5FcGhlbWVyYWxTdG9yYWdlICE9IG51bGwgPyBDZm5UYXNrRGVmaW5pdGlvbkVwaGVtZXJhbFN0b3JhZ2VQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLkVwaGVtZXJhbFN0b3JhZ2UpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2V4ZWN1dGlvblJvbGVBcm4nLCAnRXhlY3V0aW9uUm9sZUFybicsIHByb3BlcnRpZXMuRXhlY3V0aW9uUm9sZUFybiAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5FeGVjdXRpb25Sb2xlQXJuKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdmYW1pbHknLCAnRmFtaWx5JywgcHJvcGVydGllcy5GYW1pbHkgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuRmFtaWx5KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdpbmZlcmVuY2VBY2NlbGVyYXRvcnMnLCAnSW5mZXJlbmNlQWNjZWxlcmF0b3JzJywgcHJvcGVydGllcy5JbmZlcmVuY2VBY2NlbGVyYXRvcnMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoQ2ZuVGFza0RlZmluaXRpb25JbmZlcmVuY2VBY2NlbGVyYXRvclByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLkluZmVyZW5jZUFjY2VsZXJhdG9ycykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaXBjTW9kZScsICdJcGNNb2RlJywgcHJvcGVydGllcy5JcGNNb2RlICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLklwY01vZGUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ21lbW9yeScsICdNZW1vcnknLCBwcm9wZXJ0aWVzLk1lbW9yeSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5NZW1vcnkpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ25ldHdvcmtNb2RlJywgJ05ldHdvcmtNb2RlJywgcHJvcGVydGllcy5OZXR3b3JrTW9kZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5OZXR3b3JrTW9kZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncGlkTW9kZScsICdQaWRNb2RlJywgcHJvcGVydGllcy5QaWRNb2RlICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlBpZE1vZGUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BsYWNlbWVudENvbnN0cmFpbnRzJywgJ1BsYWNlbWVudENvbnN0cmFpbnRzJywgcHJvcGVydGllcy5QbGFjZW1lbnRDb25zdHJhaW50cyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5UYXNrRGVmaW5pdGlvblRhc2tEZWZpbml0aW9uUGxhY2VtZW50Q29uc3RyYWludFByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLlBsYWNlbWVudENvbnN0cmFpbnRzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwcm94eUNvbmZpZ3VyYXRpb24nLCAnUHJveHlDb25maWd1cmF0aW9uJywgcHJvcGVydGllcy5Qcm94eUNvbmZpZ3VyYXRpb24gIT0gbnVsbCA/IENmblRhc2tEZWZpbml0aW9uUHJveHlDb25maWd1cmF0aW9uUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5Qcm94eUNvbmZpZ3VyYXRpb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3JlcXVpcmVzQ29tcGF0aWJpbGl0aWVzJywgJ1JlcXVpcmVzQ29tcGF0aWJpbGl0aWVzJywgcHJvcGVydGllcy5SZXF1aXJlc0NvbXBhdGliaWxpdGllcyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmdBcnJheShwcm9wZXJ0aWVzLlJlcXVpcmVzQ29tcGF0aWJpbGl0aWVzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdydW50aW1lUGxhdGZvcm0nLCAnUnVudGltZVBsYXRmb3JtJywgcHJvcGVydGllcy5SdW50aW1lUGxhdGZvcm0gIT0gbnVsbCA/IENmblRhc2tEZWZpbml0aW9uUnVudGltZVBsYXRmb3JtUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5SdW50aW1lUGxhdGZvcm0pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3RhZ3MnLCAnVGFncycsIHByb3BlcnRpZXMuVGFncyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldENmblRhZykocHJvcGVydGllcy5UYWdzKSA6IHVuZGVmaW5lZCBhcyBhbnkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndGFza1JvbGVBcm4nLCAnVGFza1JvbGVBcm4nLCBwcm9wZXJ0aWVzLlRhc2tSb2xlQXJuICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlRhc2tSb2xlQXJuKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd2b2x1bWVzJywgJ1ZvbHVtZXMnLCBwcm9wZXJ0aWVzLlZvbHVtZXMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoQ2ZuVGFza0RlZmluaXRpb25Wb2x1bWVQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5Wb2x1bWVzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uYFxuICpcbiAqIFRoZSBkZXRhaWxzIG9mIGEgdGFzayBkZWZpbml0aW9uIHdoaWNoIGRlc2NyaWJlcyB0aGUgY29udGFpbmVyIGFuZCB2b2x1bWUgZGVmaW5pdGlvbnMgb2YgYW4gQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgdGFzay4gWW91IGNhbiBzcGVjaWZ5IHdoaWNoIERvY2tlciBpbWFnZXMgdG8gdXNlLCB0aGUgcmVxdWlyZWQgcmVzb3VyY2VzLCBhbmQgb3RoZXIgY29uZmlndXJhdGlvbnMgcmVsYXRlZCB0byBsYXVuY2hpbmcgdGhlIHRhc2sgZGVmaW5pdGlvbiB0aHJvdWdoIGFuIEFtYXpvbiBFQ1Mgc2VydmljZSBvciB0YXNrLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvblxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5UYXNrRGVmaW5pdGlvbiBleHRlbmRzIGNkay5DZm5SZXNvdXJjZSBpbXBsZW1lbnRzIGNkay5JSW5zcGVjdGFibGUge1xuICAgIC8qKlxuICAgICAqIFRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSB0eXBlIG5hbWUgZm9yIHRoaXMgcmVzb3VyY2UgY2xhc3MuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBDRk5fUkVTT1VSQ0VfVFlQRV9OQU1FID0gXCJBV1M6OkVDUzo6VGFza0RlZmluaXRpb25cIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmblRhc2tEZWZpbml0aW9uIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5UYXNrRGVmaW5pdGlvblByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5UYXNrRGVmaW5pdGlvbihzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBjbG91ZGZvcm1hdGlvbkF0dHJpYnV0ZSBUYXNrRGVmaW5pdGlvbkFyblxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBhdHRyVGFza0RlZmluaXRpb25Bcm46IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiBjb250YWluZXIgZGVmaW5pdGlvbnMgaW4gSlNPTiBmb3JtYXQgdGhhdCBkZXNjcmliZSB0aGUgZGlmZmVyZW50IGNvbnRhaW5lcnMgdGhhdCBtYWtlIHVwIHlvdXIgdGFzay4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgY29udGFpbmVyIGRlZmluaXRpb24gcGFyYW1ldGVycyBhbmQgZGVmYXVsdHMsIHNlZSBbQW1hem9uIEVDUyBUYXNrIERlZmluaXRpb25zXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS90YXNrX2RlZmludGlvbnMuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbnNcbiAgICAgKi9cbiAgICBwdWJsaWMgY29udGFpbmVyRGVmaW5pdGlvbnM6IEFycmF5PENmblRhc2tEZWZpbml0aW9uLkNvbnRhaW5lckRlZmluaXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGBjcHVgIHVuaXRzIHVzZWQgYnkgdGhlIHRhc2suIElmIHlvdSB1c2UgdGhlIEVDMiBsYXVuY2ggdHlwZSwgdGhpcyBmaWVsZCBpcyBvcHRpb25hbC4gQW55IHZhbHVlIGNhbiBiZSB1c2VkLiBJZiB5b3UgdXNlIHRoZSBGYXJnYXRlIGxhdW5jaCB0eXBlLCB0aGlzIGZpZWxkIGlzIHJlcXVpcmVkLiBZb3UgbXVzdCB1c2Ugb25lIG9mIHRoZSBmb2xsb3dpbmcgdmFsdWVzLiBUaGUgdmFsdWUgdGhhdCB5b3UgY2hvb3NlIGRldGVybWluZXMgeW91ciByYW5nZSBvZiB2YWxpZCB2YWx1ZXMgZm9yIHRoZSBgbWVtb3J5YCBwYXJhbWV0ZXIuXG4gICAgICpcbiAgICAgKiBUaGUgQ1BVIHVuaXRzIGNhbm5vdCBiZSBsZXNzIHRoYW4gMSB2Q1BVIHdoZW4geW91IHVzZSBXaW5kb3dzIGNvbnRhaW5lcnMgb24gRmFyZ2F0ZS5cbiAgICAgKlxuICAgICAqIC0gMjU2ICguMjUgdkNQVSkgLSBBdmFpbGFibGUgYG1lbW9yeWAgdmFsdWVzOiA1MTIgKDAuNSBHQiksIDEwMjQgKDEgR0IpLCAyMDQ4ICgyIEdCKVxuICAgICAqIC0gNTEyICguNSB2Q1BVKSAtIEF2YWlsYWJsZSBgbWVtb3J5YCB2YWx1ZXM6IDEwMjQgKDEgR0IpLCAyMDQ4ICgyIEdCKSwgMzA3MiAoMyBHQiksIDQwOTYgKDQgR0IpXG4gICAgICogLSAxMDI0ICgxIHZDUFUpIC0gQXZhaWxhYmxlIGBtZW1vcnlgIHZhbHVlczogMjA0OCAoMiBHQiksIDMwNzIgKDMgR0IpLCA0MDk2ICg0IEdCKSwgNTEyMCAoNSBHQiksIDYxNDQgKDYgR0IpLCA3MTY4ICg3IEdCKSwgODE5MiAoOCBHQilcbiAgICAgKiAtIDIwNDggKDIgdkNQVSkgLSBBdmFpbGFibGUgYG1lbW9yeWAgdmFsdWVzOiA0MDk2ICg0IEdCKSBhbmQgMTYzODQgKDE2IEdCKSBpbiBpbmNyZW1lbnRzIG9mIDEwMjQgKDEgR0IpXG4gICAgICogLSA0MDk2ICg0IHZDUFUpIC0gQXZhaWxhYmxlIGBtZW1vcnlgIHZhbHVlczogODE5MiAoOCBHQikgYW5kIDMwNzIwICgzMCBHQikgaW4gaW5jcmVtZW50cyBvZiAxMDI0ICgxIEdCKVxuICAgICAqIC0gODE5MiAoOCB2Q1BVKSAtIEF2YWlsYWJsZSBgbWVtb3J5YCB2YWx1ZXM6IDE2IEdCIGFuZCA2MCBHQiBpbiA0IEdCIGluY3JlbWVudHNcbiAgICAgKlxuICAgICAqIFRoaXMgb3B0aW9uIHJlcXVpcmVzIExpbnV4IHBsYXRmb3JtIGAxLjQuMGAgb3IgbGF0ZXIuXG4gICAgICogLSAxNjM4NCAoMTZ2Q1BVKSAtIEF2YWlsYWJsZSBgbWVtb3J5YCB2YWx1ZXM6IDMyR0IgYW5kIDEyMCBHQiBpbiA4IEdCIGluY3JlbWVudHNcbiAgICAgKlxuICAgICAqIFRoaXMgb3B0aW9uIHJlcXVpcmVzIExpbnV4IHBsYXRmb3JtIGAxLjQuMGAgb3IgbGF0ZXIuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtdGFza2RlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWNwdVxuICAgICAqL1xuICAgIHB1YmxpYyBjcHU6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBlcGhlbWVyYWwgc3RvcmFnZSBzZXR0aW5ncyB0byB1c2UgZm9yIHRhc2tzIHJ1biB3aXRoIHRoZSB0YXNrIGRlZmluaXRpb24uXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtdGFza2RlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWVwaGVtZXJhbHN0b3JhZ2VcbiAgICAgKi9cbiAgICBwdWJsaWMgZXBoZW1lcmFsU3RvcmFnZTogQ2ZuVGFza0RlZmluaXRpb24uRXBoZW1lcmFsU3RvcmFnZVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIG9mIHRoZSB0YXNrIGV4ZWN1dGlvbiByb2xlIHRoYXQgZ3JhbnRzIHRoZSBBbWF6b24gRUNTIGNvbnRhaW5lciBhZ2VudCBwZXJtaXNzaW9uIHRvIG1ha2UgQVdTIEFQSSBjYWxscyBvbiB5b3VyIGJlaGFsZi4gVGhlIHRhc2sgZXhlY3V0aW9uIElBTSByb2xlIGlzIHJlcXVpcmVkIGRlcGVuZGluZyBvbiB0aGUgcmVxdWlyZW1lbnRzIG9mIHlvdXIgdGFzay4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQW1hem9uIEVDUyB0YXNrIGV4ZWN1dGlvbiBJQU0gcm9sZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvdGFza19leGVjdXRpb25fSUFNX3JvbGUuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tZXhlY3V0aW9ucm9sZWFyblxuICAgICAqL1xuICAgIHB1YmxpYyBleGVjdXRpb25Sb2xlQXJuOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiBhIGZhbWlseSB0aGF0IHRoaXMgdGFzayBkZWZpbml0aW9uIGlzIHJlZ2lzdGVyZWQgdG8uIFVwIHRvIDI1NSBsZXR0ZXJzICh1cHBlcmNhc2UgYW5kIGxvd2VyY2FzZSksIG51bWJlcnMsIGh5cGhlbnMsIGFuZCB1bmRlcnNjb3JlcyBhcmUgYWxsb3dlZC5cbiAgICAgKlxuICAgICAqIEEgZmFtaWx5IGdyb3VwcyBtdWx0aXBsZSB2ZXJzaW9ucyBvZiBhIHRhc2sgZGVmaW5pdGlvbi4gQW1hem9uIEVDUyBnaXZlcyB0aGUgZmlyc3QgdGFzayBkZWZpbml0aW9uIHRoYXQgeW91IHJlZ2lzdGVyZWQgdG8gYSBmYW1pbHkgYSByZXZpc2lvbiBudW1iZXIgb2YgMS4gQW1hem9uIEVDUyBnaXZlcyBzZXF1ZW50aWFsIHJldmlzaW9uIG51bWJlcnMgdG8gZWFjaCB0YXNrIGRlZmluaXRpb24gdGhhdCB5b3UgYWRkLlxuICAgICAqXG4gICAgICogPiBUbyB1c2UgcmV2aXNpb24gbnVtYmVycyB3aGVuIHlvdSB1cGRhdGUgYSB0YXNrIGRlZmluaXRpb24sIHNwZWNpZnkgdGhpcyBwcm9wZXJ0eS4gSWYgeW91IGRvbid0IHNwZWNpZnkgYSB2YWx1ZSwgQVdTIENsb3VkRm9ybWF0aW9uIGdlbmVyYXRlcyBhIG5ldyB0YXNrIGRlZmluaXRpb24gZWFjaCB0aW1lIHRoYXQgeW91IHVwZGF0ZSBpdC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tZmFtaWx5XG4gICAgICovXG4gICAgcHVibGljIGZhbWlseTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIEVsYXN0aWMgSW5mZXJlbmNlIGFjY2VsZXJhdG9ycyB0byB1c2UgZm9yIHRoZSBjb250YWluZXJzIGluIHRoZSB0YXNrLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1pbmZlcmVuY2VhY2NlbGVyYXRvcnNcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5mZXJlbmNlQWNjZWxlcmF0b3JzOiBBcnJheTxDZm5UYXNrRGVmaW5pdGlvbi5JbmZlcmVuY2VBY2NlbGVyYXRvclByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBJUEMgcmVzb3VyY2UgbmFtZXNwYWNlIHRvIHVzZSBmb3IgdGhlIGNvbnRhaW5lcnMgaW4gdGhlIHRhc2suIFRoZSB2YWxpZCB2YWx1ZXMgYXJlIGBob3N0YCAsIGB0YXNrYCAsIG9yIGBub25lYCAuIElmIGBob3N0YCBpcyBzcGVjaWZpZWQsIHRoZW4gYWxsIGNvbnRhaW5lcnMgd2l0aGluIHRoZSB0YXNrcyB0aGF0IHNwZWNpZmllZCB0aGUgYGhvc3RgIElQQyBtb2RlIG9uIHRoZSBzYW1lIGNvbnRhaW5lciBpbnN0YW5jZSBzaGFyZSB0aGUgc2FtZSBJUEMgcmVzb3VyY2VzIHdpdGggdGhlIGhvc3QgQW1hem9uIEVDMiBpbnN0YW5jZS4gSWYgYHRhc2tgIGlzIHNwZWNpZmllZCwgYWxsIGNvbnRhaW5lcnMgd2l0aGluIHRoZSBzcGVjaWZpZWQgdGFzayBzaGFyZSB0aGUgc2FtZSBJUEMgcmVzb3VyY2VzLiBJZiBgbm9uZWAgaXMgc3BlY2lmaWVkLCB0aGVuIElQQyByZXNvdXJjZXMgd2l0aGluIHRoZSBjb250YWluZXJzIG9mIGEgdGFzayBhcmUgcHJpdmF0ZSBhbmQgbm90IHNoYXJlZCB3aXRoIG90aGVyIGNvbnRhaW5lcnMgaW4gYSB0YXNrIG9yIG9uIHRoZSBjb250YWluZXIgaW5zdGFuY2UuIElmIG5vIHZhbHVlIGlzIHNwZWNpZmllZCwgdGhlbiB0aGUgSVBDIHJlc291cmNlIG5hbWVzcGFjZSBzaGFyaW5nIGRlcGVuZHMgb24gdGhlIERvY2tlciBkYWVtb24gc2V0dGluZyBvbiB0aGUgY29udGFpbmVyIGluc3RhbmNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtJUEMgc2V0dGluZ3NdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jaXBjLXNldHRpbmdzLS0taXBjKSBpbiB0aGUgKkRvY2tlciBydW4gcmVmZXJlbmNlKiAuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgYGhvc3RgIElQQyBtb2RlIGlzIHVzZWQsIGJlIGF3YXJlIHRoYXQgdGhlcmUgaXMgYSBoZWlnaHRlbmVkIHJpc2sgb2YgdW5kZXNpcmVkIElQQyBuYW1lc3BhY2UgZXhwb3NlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtEb2NrZXIgc2VjdXJpdHldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvc2VjdXJpdHkvc2VjdXJpdHkvKSAuXG4gICAgICpcbiAgICAgKiBJZiB5b3UgYXJlIHNldHRpbmcgbmFtZXNwYWNlZCBrZXJuZWwgcGFyYW1ldGVycyB1c2luZyBgc3lzdGVtQ29udHJvbHNgIGZvciB0aGUgY29udGFpbmVycyBpbiB0aGUgdGFzaywgdGhlIGZvbGxvd2luZyB3aWxsIGFwcGx5IHRvIHlvdXIgSVBDIHJlc291cmNlIG5hbWVzcGFjZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbU3lzdGVtIENvbnRyb2xzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS90YXNrX2RlZmluaXRpb25fcGFyYW1ldGVycy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogLSBGb3IgdGFza3MgdGhhdCB1c2UgdGhlIGBob3N0YCBJUEMgbW9kZSwgSVBDIG5hbWVzcGFjZSByZWxhdGVkIGBzeXN0ZW1Db250cm9sc2AgYXJlIG5vdCBzdXBwb3J0ZWQuXG4gICAgICogLSBGb3IgdGFza3MgdGhhdCB1c2UgdGhlIGB0YXNrYCBJUEMgbW9kZSwgSVBDIG5hbWVzcGFjZSByZWxhdGVkIGBzeXN0ZW1Db250cm9sc2Agd2lsbCBhcHBseSB0byBhbGwgY29udGFpbmVycyB3aXRoaW4gYSB0YXNrLlxuICAgICAqXG4gICAgICogPiBUaGlzIHBhcmFtZXRlciBpcyBub3Qgc3VwcG9ydGVkIGZvciBXaW5kb3dzIGNvbnRhaW5lcnMgb3IgdGFza3MgcnVuIG9uIEFXUyBGYXJnYXRlIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24taXBjbW9kZVxuICAgICAqL1xuICAgIHB1YmxpYyBpcGNNb2RlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYW1vdW50IChpbiBNaUIpIG9mIG1lbW9yeSB1c2VkIGJ5IHRoZSB0YXNrLlxuICAgICAqXG4gICAgICogSWYgeW91ciB0YXNrcyBydW5zIG9uIEFtYXpvbiBFQzIgaW5zdGFuY2VzLCB5b3UgbXVzdCBzcGVjaWZ5IGVpdGhlciBhIHRhc2stbGV2ZWwgbWVtb3J5IHZhbHVlIG9yIGEgY29udGFpbmVyLWxldmVsIG1lbW9yeSB2YWx1ZS4gVGhpcyBmaWVsZCBpcyBvcHRpb25hbCBhbmQgYW55IHZhbHVlIGNhbiBiZSB1c2VkLiBJZiBhIHRhc2stbGV2ZWwgbWVtb3J5IHZhbHVlIGlzIHNwZWNpZmllZCwgdGhlIGNvbnRhaW5lci1sZXZlbCBtZW1vcnkgdmFsdWUgaXMgb3B0aW9uYWwuIEZvciBtb3JlIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb250YWluZXItbGV2ZWwgbWVtb3J5IGFuZCBtZW1vcnkgcmVzZXJ2YXRpb24sIHNlZSBbQ29udGFpbmVyRGVmaW5pdGlvbl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9Db250YWluZXJEZWZpbml0aW9uLmh0bWwpIC5cbiAgICAgKlxuICAgICAqIElmIHlvdXIgdGFza3MgcnVucyBvbiBBV1MgRmFyZ2F0ZSAsIHRoaXMgZmllbGQgaXMgcmVxdWlyZWQuIFlvdSBtdXN0IHVzZSBvbmUgb2YgdGhlIGZvbGxvd2luZyB2YWx1ZXMuIFRoZSB2YWx1ZSB5b3UgY2hvb3NlIGRldGVybWluZXMgeW91ciByYW5nZSBvZiB2YWxpZCB2YWx1ZXMgZm9yIHRoZSBgY3B1YCBwYXJhbWV0ZXIuXG4gICAgICpcbiAgICAgKiAtIDUxMiAoMC41IEdCKSwgMTAyNCAoMSBHQiksIDIwNDggKDIgR0IpIC0gQXZhaWxhYmxlIGBjcHVgIHZhbHVlczogMjU2ICguMjUgdkNQVSlcbiAgICAgKiAtIDEwMjQgKDEgR0IpLCAyMDQ4ICgyIEdCKSwgMzA3MiAoMyBHQiksIDQwOTYgKDQgR0IpIC0gQXZhaWxhYmxlIGBjcHVgIHZhbHVlczogNTEyICguNSB2Q1BVKVxuICAgICAqIC0gMjA0OCAoMiBHQiksIDMwNzIgKDMgR0IpLCA0MDk2ICg0IEdCKSwgNTEyMCAoNSBHQiksIDYxNDQgKDYgR0IpLCA3MTY4ICg3IEdCKSwgODE5MiAoOCBHQikgLSBBdmFpbGFibGUgYGNwdWAgdmFsdWVzOiAxMDI0ICgxIHZDUFUpXG4gICAgICogLSBCZXR3ZWVuIDQwOTYgKDQgR0IpIGFuZCAxNjM4NCAoMTYgR0IpIGluIGluY3JlbWVudHMgb2YgMTAyNCAoMSBHQikgLSBBdmFpbGFibGUgYGNwdWAgdmFsdWVzOiAyMDQ4ICgyIHZDUFUpXG4gICAgICogLSBCZXR3ZWVuIDgxOTIgKDggR0IpIGFuZCAzMDcyMCAoMzAgR0IpIGluIGluY3JlbWVudHMgb2YgMTAyNCAoMSBHQikgLSBBdmFpbGFibGUgYGNwdWAgdmFsdWVzOiA0MDk2ICg0IHZDUFUpXG4gICAgICogLSBCZXR3ZWVuIDE2IEdCIGFuZCA2MCBHQiBpbiA0IEdCIGluY3JlbWVudHMgLSBBdmFpbGFibGUgYGNwdWAgdmFsdWVzOiA4MTkyICg4IHZDUFUpXG4gICAgICpcbiAgICAgKiBUaGlzIG9wdGlvbiByZXF1aXJlcyBMaW51eCBwbGF0Zm9ybSBgMS40LjBgIG9yIGxhdGVyLlxuICAgICAqIC0gQmV0d2VlbiAzMkdCIGFuZCAxMjAgR0IgaW4gOCBHQiBpbmNyZW1lbnRzIC0gQXZhaWxhYmxlIGBjcHVgIHZhbHVlczogMTYzODQgKDE2IHZDUFUpXG4gICAgICpcbiAgICAgKiBUaGlzIG9wdGlvbiByZXF1aXJlcyBMaW51eCBwbGF0Zm9ybSBgMS40LjBgIG9yIGxhdGVyLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1tZW1vcnlcbiAgICAgKi9cbiAgICBwdWJsaWMgbWVtb3J5OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgRG9ja2VyIG5ldHdvcmtpbmcgbW9kZSB0byB1c2UgZm9yIHRoZSBjb250YWluZXJzIGluIHRoZSB0YXNrLiBUaGUgdmFsaWQgdmFsdWVzIGFyZSBgbm9uZWAgLCBgYnJpZGdlYCAsIGBhd3N2cGNgICwgYW5kIGBob3N0YCAuIElmIG5vIG5ldHdvcmsgbW9kZSBpcyBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IGlzIGBicmlkZ2VgIC5cbiAgICAgKlxuICAgICAqIEZvciBBbWF6b24gRUNTIHRhc2tzIG9uIEZhcmdhdGUsIHRoZSBgYXdzdnBjYCBuZXR3b3JrIG1vZGUgaXMgcmVxdWlyZWQuIEZvciBBbWF6b24gRUNTIHRhc2tzIG9uIEFtYXpvbiBFQzIgTGludXggaW5zdGFuY2VzLCBhbnkgbmV0d29yayBtb2RlIGNhbiBiZSB1c2VkLiBGb3IgQW1hem9uIEVDUyB0YXNrcyBvbiBBbWF6b24gRUMyIFdpbmRvd3MgaW5zdGFuY2VzLCBgPGRlZmF1bHQ+YCBvciBgYXdzdnBjYCBjYW4gYmUgdXNlZC4gSWYgdGhlIG5ldHdvcmsgbW9kZSBpcyBzZXQgdG8gYG5vbmVgICwgeW91IGNhbm5vdCBzcGVjaWZ5IHBvcnQgbWFwcGluZ3MgaW4geW91ciBjb250YWluZXIgZGVmaW5pdGlvbnMsIGFuZCB0aGUgdGFza3MgY29udGFpbmVycyBkbyBub3QgaGF2ZSBleHRlcm5hbCBjb25uZWN0aXZpdHkuIFRoZSBgaG9zdGAgYW5kIGBhd3N2cGNgIG5ldHdvcmsgbW9kZXMgb2ZmZXIgdGhlIGhpZ2hlc3QgbmV0d29ya2luZyBwZXJmb3JtYW5jZSBmb3IgY29udGFpbmVycyBiZWNhdXNlIHRoZXkgdXNlIHRoZSBFQzIgbmV0d29yayBzdGFjayBpbnN0ZWFkIG9mIHRoZSB2aXJ0dWFsaXplZCBuZXR3b3JrIHN0YWNrIHByb3ZpZGVkIGJ5IHRoZSBgYnJpZGdlYCBtb2RlLlxuICAgICAqXG4gICAgICogV2l0aCB0aGUgYGhvc3RgIGFuZCBgYXdzdnBjYCBuZXR3b3JrIG1vZGVzLCBleHBvc2VkIGNvbnRhaW5lciBwb3J0cyBhcmUgbWFwcGVkIGRpcmVjdGx5IHRvIHRoZSBjb3JyZXNwb25kaW5nIGhvc3QgcG9ydCAoZm9yIHRoZSBgaG9zdGAgbmV0d29yayBtb2RlKSBvciB0aGUgYXR0YWNoZWQgZWxhc3RpYyBuZXR3b3JrIGludGVyZmFjZSBwb3J0IChmb3IgdGhlIGBhd3N2cGNgIG5ldHdvcmsgbW9kZSksIHNvIHlvdSBjYW5ub3QgdGFrZSBhZHZhbnRhZ2Ugb2YgZHluYW1pYyBob3N0IHBvcnQgbWFwcGluZ3MuXG4gICAgICpcbiAgICAgKiA+IFdoZW4gdXNpbmcgdGhlIGBob3N0YCBuZXR3b3JrIG1vZGUsIHlvdSBzaG91bGQgbm90IHJ1biBjb250YWluZXJzIHVzaW5nIHRoZSByb290IHVzZXIgKFVJRCAwKS4gSXQgaXMgY29uc2lkZXJlZCBiZXN0IHByYWN0aWNlIHRvIHVzZSBhIG5vbi1yb290IHVzZXIuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgbmV0d29yayBtb2RlIGlzIGBhd3N2cGNgICwgdGhlIHRhc2sgaXMgYWxsb2NhdGVkIGFuIGVsYXN0aWMgbmV0d29yayBpbnRlcmZhY2UsIGFuZCB5b3UgbXVzdCBzcGVjaWZ5IGEgYE5ldHdvcmtDb25maWd1cmF0aW9uYCB2YWx1ZSB3aGVuIHlvdSBjcmVhdGUgYSBzZXJ2aWNlIG9yIHJ1biBhIHRhc2sgd2l0aCB0aGUgdGFzayBkZWZpbml0aW9uLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtUYXNrIE5ldHdvcmtpbmddKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3Rhc2stbmV0d29ya2luZy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogSWYgdGhlIG5ldHdvcmsgbW9kZSBpcyBgaG9zdGAgLCB5b3UgY2Fubm90IHJ1biBtdWx0aXBsZSBpbnN0YW50aWF0aW9ucyBvZiB0aGUgc2FtZSB0YXNrIG9uIGEgc2luZ2xlIGNvbnRhaW5lciBpbnN0YW5jZSB3aGVuIHBvcnQgbWFwcGluZ3MgYXJlIHVzZWQuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtOZXR3b3JrIHNldHRpbmdzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vI25ldHdvcmstc2V0dGluZ3MpIGluIHRoZSAqRG9ja2VyIHJ1biByZWZlcmVuY2UqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tbmV0d29ya21vZGVcbiAgICAgKi9cbiAgICBwdWJsaWMgbmV0d29ya01vZGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBwcm9jZXNzIG5hbWVzcGFjZSB0byB1c2UgZm9yIHRoZSBjb250YWluZXJzIGluIHRoZSB0YXNrLiBUaGUgdmFsaWQgdmFsdWVzIGFyZSBgaG9zdGAgb3IgYHRhc2tgIC4gSWYgYGhvc3RgIGlzIHNwZWNpZmllZCwgdGhlbiBhbGwgY29udGFpbmVycyB3aXRoaW4gdGhlIHRhc2tzIHRoYXQgc3BlY2lmaWVkIHRoZSBgaG9zdGAgUElEIG1vZGUgb24gdGhlIHNhbWUgY29udGFpbmVyIGluc3RhbmNlIHNoYXJlIHRoZSBzYW1lIHByb2Nlc3MgbmFtZXNwYWNlIHdpdGggdGhlIGhvc3QgQW1hem9uIEVDMiBpbnN0YW5jZS4gSWYgYHRhc2tgIGlzIHNwZWNpZmllZCwgYWxsIGNvbnRhaW5lcnMgd2l0aGluIHRoZSBzcGVjaWZpZWQgdGFzayBzaGFyZSB0aGUgc2FtZSBwcm9jZXNzIG5hbWVzcGFjZS4gSWYgbm8gdmFsdWUgaXMgc3BlY2lmaWVkLCB0aGUgZGVmYXVsdCBpcyBhIHByaXZhdGUgbmFtZXNwYWNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtQSUQgc2V0dGluZ3NdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jcGlkLXNldHRpbmdzLS0tcGlkKSBpbiB0aGUgKkRvY2tlciBydW4gcmVmZXJlbmNlKiAuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgYGhvc3RgIFBJRCBtb2RlIGlzIHVzZWQsIGJlIGF3YXJlIHRoYXQgdGhlcmUgaXMgYSBoZWlnaHRlbmVkIHJpc2sgb2YgdW5kZXNpcmVkIHByb2Nlc3MgbmFtZXNwYWNlIGV4cG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbRG9ja2VyIHNlY3VyaXR5XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3NlY3VyaXR5L3NlY3VyaXR5LykgLlxuICAgICAqXG4gICAgICogPiBUaGlzIHBhcmFtZXRlciBpcyBub3Qgc3VwcG9ydGVkIGZvciBXaW5kb3dzIGNvbnRhaW5lcnMgb3IgdGFza3MgcnVuIG9uIEFXUyBGYXJnYXRlIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tcGlkbW9kZVxuICAgICAqL1xuICAgIHB1YmxpYyBwaWRNb2RlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBBbiBhcnJheSBvZiBwbGFjZW1lbnQgY29uc3RyYWludCBvYmplY3RzIHRvIHVzZSBmb3IgdGFza3MuXG4gICAgICpcbiAgICAgKiA+IFRoaXMgcGFyYW1ldGVyIGlzbid0IHN1cHBvcnRlZCBmb3IgdGFza3MgcnVuIG9uIEFXUyBGYXJnYXRlIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tcGxhY2VtZW50Y29uc3RyYWludHNcbiAgICAgKi9cbiAgICBwdWJsaWMgcGxhY2VtZW50Q29uc3RyYWludHM6IEFycmF5PENmblRhc2tEZWZpbml0aW9uLlRhc2tEZWZpbml0aW9uUGxhY2VtZW50Q29uc3RyYWludFByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjb25maWd1cmF0aW9uIGRldGFpbHMgZm9yIHRoZSBBcHAgTWVzaCBwcm94eS5cbiAgICAgKlxuICAgICAqIFlvdXIgQW1hem9uIEVDUyBjb250YWluZXIgaW5zdGFuY2VzIHJlcXVpcmUgYXQgbGVhc3QgdmVyc2lvbiAxLjI2LjAgb2YgdGhlIGNvbnRhaW5lciBhZ2VudCBhbmQgYXQgbGVhc3QgdmVyc2lvbiAxLjI2LjAtMSBvZiB0aGUgYGVjcy1pbml0YCBwYWNrYWdlIHRvIHVzZSBhIHByb3h5IGNvbmZpZ3VyYXRpb24uIElmIHlvdXIgY29udGFpbmVyIGluc3RhbmNlcyBhcmUgbGF1bmNoZWQgZnJvbSB0aGUgQW1hem9uIEVDUyBvcHRpbWl6ZWQgQU1JIHZlcnNpb24gYDIwMTkwMzAxYCBvciBsYXRlciwgdGhleSBjb250YWluIHRoZSByZXF1aXJlZCB2ZXJzaW9ucyBvZiB0aGUgY29udGFpbmVyIGFnZW50IGFuZCBgZWNzLWluaXRgIC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQW1hem9uIEVDUy1vcHRpbWl6ZWQgTGludXggQU1JXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9lY3Mtb3B0aW1pemVkX0FNSS5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1wcm94eWNvbmZpZ3VyYXRpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgcHJveHlDb25maWd1cmF0aW9uOiBDZm5UYXNrRGVmaW5pdGlvbi5Qcm94eUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0YXNrIGxhdW5jaCB0eXBlcyB0aGUgdGFzayBkZWZpbml0aW9uIHdhcyB2YWxpZGF0ZWQgYWdhaW5zdC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQW1hem9uIEVDUyBsYXVuY2ggdHlwZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2xhdW5jaF90eXBlcy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1yZXF1aXJlc2NvbXBhdGliaWxpdGllc1xuICAgICAqL1xuICAgIHB1YmxpYyByZXF1aXJlc0NvbXBhdGliaWxpdGllczogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3BlcmF0aW5nIHN5c3RlbSB0aGF0IHlvdXIgdGFza3MgZGVmaW5pdGlvbnMgcnVuIG9uLiBBIHBsYXRmb3JtIGZhbWlseSBpcyBzcGVjaWZpZWQgb25seSBmb3IgdGFza3MgdXNpbmcgdGhlIEZhcmdhdGUgbGF1bmNoIHR5cGUuXG4gICAgICpcbiAgICAgKiBXaGVuIHlvdSBzcGVjaWZ5IGEgdGFzayBkZWZpbml0aW9uIGluIGEgc2VydmljZSwgdGhpcyB2YWx1ZSBtdXN0IG1hdGNoIHRoZSBgcnVudGltZVBsYXRmb3JtYCB2YWx1ZSBvZiB0aGUgc2VydmljZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tcnVudGltZXBsYXRmb3JtXG4gICAgICovXG4gICAgcHVibGljIHJ1bnRpbWVQbGF0Zm9ybTogQ2ZuVGFza0RlZmluaXRpb24uUnVudGltZVBsYXRmb3JtUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWV0YWRhdGEgdGhhdCB5b3UgYXBwbHkgdG8gdGhlIHRhc2sgZGVmaW5pdGlvbiB0byBoZWxwIHlvdSBjYXRlZ29yaXplIGFuZCBvcmdhbml6ZSB0aGVtLiBFYWNoIHRhZyBjb25zaXN0cyBvZiBhIGtleSBhbmQgYW4gb3B0aW9uYWwgdmFsdWUuIFlvdSBkZWZpbmUgYm90aCBvZiB0aGVtLlxuICAgICAqXG4gICAgICogVGhlIGZvbGxvd2luZyBiYXNpYyByZXN0cmljdGlvbnMgYXBwbHkgdG8gdGFnczpcbiAgICAgKlxuICAgICAqIC0gTWF4aW11bSBudW1iZXIgb2YgdGFncyBwZXIgcmVzb3VyY2UgLSA1MFxuICAgICAqIC0gRm9yIGVhY2ggcmVzb3VyY2UsIGVhY2ggdGFnIGtleSBtdXN0IGJlIHVuaXF1ZSwgYW5kIGVhY2ggdGFnIGtleSBjYW4gaGF2ZSBvbmx5IG9uZSB2YWx1ZS5cbiAgICAgKiAtIE1heGltdW0ga2V5IGxlbmd0aCAtIDEyOCBVbmljb2RlIGNoYXJhY3RlcnMgaW4gVVRGLThcbiAgICAgKiAtIE1heGltdW0gdmFsdWUgbGVuZ3RoIC0gMjU2IFVuaWNvZGUgY2hhcmFjdGVycyBpbiBVVEYtOFxuICAgICAqIC0gSWYgeW91ciB0YWdnaW5nIHNjaGVtYSBpcyB1c2VkIGFjcm9zcyBtdWx0aXBsZSBzZXJ2aWNlcyBhbmQgcmVzb3VyY2VzLCByZW1lbWJlciB0aGF0IG90aGVyIHNlcnZpY2VzIG1heSBoYXZlIHJlc3RyaWN0aW9ucyBvbiBhbGxvd2VkIGNoYXJhY3RlcnMuIEdlbmVyYWxseSBhbGxvd2VkIGNoYXJhY3RlcnMgYXJlOiBsZXR0ZXJzLCBudW1iZXJzLCBhbmQgc3BhY2VzIHJlcHJlc2VudGFibGUgaW4gVVRGLTgsIGFuZCB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6ICsgLSA9IC4gXyA6IC8gQC5cbiAgICAgKiAtIFRhZyBrZXlzIGFuZCB2YWx1ZXMgYXJlIGNhc2Utc2Vuc2l0aXZlLlxuICAgICAqIC0gRG8gbm90IHVzZSBgYXdzOmAgLCBgQVdTOmAgLCBvciBhbnkgdXBwZXIgb3IgbG93ZXJjYXNlIGNvbWJpbmF0aW9uIG9mIHN1Y2ggYXMgYSBwcmVmaXggZm9yIGVpdGhlciBrZXlzIG9yIHZhbHVlcyBhcyBpdCBpcyByZXNlcnZlZCBmb3IgQVdTIHVzZS4gWW91IGNhbm5vdCBlZGl0IG9yIGRlbGV0ZSB0YWcga2V5cyBvciB2YWx1ZXMgd2l0aCB0aGlzIHByZWZpeC4gVGFncyB3aXRoIHRoaXMgcHJlZml4IGRvIG5vdCBjb3VudCBhZ2FpbnN0IHlvdXIgdGFncyBwZXIgcmVzb3VyY2UgbGltaXQuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtdGFza2RlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLXRhZ3NcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgdGFnczogY2RrLlRhZ01hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc2hvcnQgbmFtZSBvciBmdWxsIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIG9mIHRoZSBBV1MgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IHJvbGUgdGhhdCBncmFudHMgY29udGFpbmVycyBpbiB0aGUgdGFzayBwZXJtaXNzaW9uIHRvIGNhbGwgQVdTIEFQSXMgb24geW91ciBiZWhhbGYuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0FtYXpvbiBFQ1MgVGFzayBSb2xlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS90YXNrLWlhbS1yb2xlcy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogSUFNIHJvbGVzIGZvciB0YXNrcyBvbiBXaW5kb3dzIHJlcXVpcmUgdGhhdCB0aGUgYC1FbmFibGVUYXNrSUFNUm9sZWAgb3B0aW9uIGlzIHNldCB3aGVuIHlvdSBsYXVuY2ggdGhlIEFtYXpvbiBFQ1Mtb3B0aW1pemVkIFdpbmRvd3MgQU1JLiBZb3VyIGNvbnRhaW5lcnMgbXVzdCBhbHNvIHJ1biBzb21lIGNvbmZpZ3VyYXRpb24gY29kZSB0byB1c2UgdGhlIGZlYXR1cmUuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1dpbmRvd3MgSUFNIHJvbGVzIGZvciB0YXNrc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvd2luZG93c190YXNrX0lBTV9yb2xlcy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi10YXNrcm9sZWFyblxuICAgICAqL1xuICAgIHB1YmxpYyB0YXNrUm9sZUFybjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGxpc3Qgb2YgZGF0YSB2b2x1bWUgZGVmaW5pdGlvbnMgZm9yIHRoZSB0YXNrLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtVc2luZyBkYXRhIHZvbHVtZXMgaW4gdGFza3NdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3VzaW5nX2RhdGFfdm9sdW1lcy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogPiBUaGUgYGhvc3RgIGFuZCBgc291cmNlUGF0aGAgcGFyYW1ldGVycyBhcmVuJ3Qgc3VwcG9ydGVkIGZvciB0YXNrcyBydW4gb24gQVdTIEZhcmdhdGUgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi12b2x1bWVzXG4gICAgICovXG4gICAgcHVibGljIHZvbHVtZXM6IEFycmF5PENmblRhc2tEZWZpbml0aW9uLlZvbHVtZVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5UYXNrRGVmaW5pdGlvblByb3BzID0ge30pIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmblRhc2tEZWZpbml0aW9uLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUsIHByb3BlcnRpZXM6IHByb3BzIH0pO1xuICAgICAgICB0aGlzLmF0dHJUYXNrRGVmaW5pdGlvbkFybiA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnVGFza0RlZmluaXRpb25Bcm4nKSk7XG5cbiAgICAgICAgdGhpcy5jb250YWluZXJEZWZpbml0aW9ucyA9IHByb3BzLmNvbnRhaW5lckRlZmluaXRpb25zO1xuICAgICAgICB0aGlzLmNwdSA9IHByb3BzLmNwdTtcbiAgICAgICAgdGhpcy5lcGhlbWVyYWxTdG9yYWdlID0gcHJvcHMuZXBoZW1lcmFsU3RvcmFnZTtcbiAgICAgICAgdGhpcy5leGVjdXRpb25Sb2xlQXJuID0gcHJvcHMuZXhlY3V0aW9uUm9sZUFybjtcbiAgICAgICAgdGhpcy5mYW1pbHkgPSBwcm9wcy5mYW1pbHk7XG4gICAgICAgIHRoaXMuaW5mZXJlbmNlQWNjZWxlcmF0b3JzID0gcHJvcHMuaW5mZXJlbmNlQWNjZWxlcmF0b3JzO1xuICAgICAgICB0aGlzLmlwY01vZGUgPSBwcm9wcy5pcGNNb2RlO1xuICAgICAgICB0aGlzLm1lbW9yeSA9IHByb3BzLm1lbW9yeTtcbiAgICAgICAgdGhpcy5uZXR3b3JrTW9kZSA9IHByb3BzLm5ldHdvcmtNb2RlO1xuICAgICAgICB0aGlzLnBpZE1vZGUgPSBwcm9wcy5waWRNb2RlO1xuICAgICAgICB0aGlzLnBsYWNlbWVudENvbnN0cmFpbnRzID0gcHJvcHMucGxhY2VtZW50Q29uc3RyYWludHM7XG4gICAgICAgIHRoaXMucHJveHlDb25maWd1cmF0aW9uID0gcHJvcHMucHJveHlDb25maWd1cmF0aW9uO1xuICAgICAgICB0aGlzLnJlcXVpcmVzQ29tcGF0aWJpbGl0aWVzID0gcHJvcHMucmVxdWlyZXNDb21wYXRpYmlsaXRpZXM7XG4gICAgICAgIHRoaXMucnVudGltZVBsYXRmb3JtID0gcHJvcHMucnVudGltZVBsYXRmb3JtO1xuICAgICAgICB0aGlzLnRhZ3MgPSBuZXcgY2RrLlRhZ01hbmFnZXIoY2RrLlRhZ1R5cGUuU1RBTkRBUkQsIFwiQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uXCIsIHByb3BzLnRhZ3MsIHsgdGFnUHJvcGVydHlOYW1lOiAndGFncycgfSk7XG4gICAgICAgIHRoaXMudGFza1JvbGVBcm4gPSBwcm9wcy50YXNrUm9sZUFybjtcbiAgICAgICAgdGhpcy52b2x1bWVzID0gcHJvcHMudm9sdW1lcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmblRhc2tEZWZpbml0aW9uLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb250YWluZXJEZWZpbml0aW9uczogdGhpcy5jb250YWluZXJEZWZpbml0aW9ucyxcbiAgICAgICAgICAgIGNwdTogdGhpcy5jcHUsXG4gICAgICAgICAgICBlcGhlbWVyYWxTdG9yYWdlOiB0aGlzLmVwaGVtZXJhbFN0b3JhZ2UsXG4gICAgICAgICAgICBleGVjdXRpb25Sb2xlQXJuOiB0aGlzLmV4ZWN1dGlvblJvbGVBcm4sXG4gICAgICAgICAgICBmYW1pbHk6IHRoaXMuZmFtaWx5LFxuICAgICAgICAgICAgaW5mZXJlbmNlQWNjZWxlcmF0b3JzOiB0aGlzLmluZmVyZW5jZUFjY2VsZXJhdG9ycyxcbiAgICAgICAgICAgIGlwY01vZGU6IHRoaXMuaXBjTW9kZSxcbiAgICAgICAgICAgIG1lbW9yeTogdGhpcy5tZW1vcnksXG4gICAgICAgICAgICBuZXR3b3JrTW9kZTogdGhpcy5uZXR3b3JrTW9kZSxcbiAgICAgICAgICAgIHBpZE1vZGU6IHRoaXMucGlkTW9kZSxcbiAgICAgICAgICAgIHBsYWNlbWVudENvbnN0cmFpbnRzOiB0aGlzLnBsYWNlbWVudENvbnN0cmFpbnRzLFxuICAgICAgICAgICAgcHJveHlDb25maWd1cmF0aW9uOiB0aGlzLnByb3h5Q29uZmlndXJhdGlvbixcbiAgICAgICAgICAgIHJlcXVpcmVzQ29tcGF0aWJpbGl0aWVzOiB0aGlzLnJlcXVpcmVzQ29tcGF0aWJpbGl0aWVzLFxuICAgICAgICAgICAgcnVudGltZVBsYXRmb3JtOiB0aGlzLnJ1bnRpbWVQbGF0Zm9ybSxcbiAgICAgICAgICAgIHRhZ3M6IHRoaXMudGFncy5yZW5kZXJUYWdzKCksXG4gICAgICAgICAgICB0YXNrUm9sZUFybjogdGhpcy50YXNrUm9sZUFybixcbiAgICAgICAgICAgIHZvbHVtZXM6IHRoaXMudm9sdW1lcyxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5UYXNrRGVmaW5pdGlvblByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wcyk7XG4gICAgfVxufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblRhc2tEZWZpbml0aW9uIHtcbiAgICAvKipcbiAgICAgKiBUaGUgYXV0aG9yaXphdGlvbiBjb25maWd1cmF0aW9uIGRldGFpbHMgZm9yIHRoZSBBbWF6b24gRUZTIGZpbGUgc3lzdGVtLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWF1dGhvcml6YXRpb25jb25maWcuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgQXV0aG9yaXphdGlvbkNvbmZpZ1Byb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBBbWF6b24gRUZTIGFjY2VzcyBwb2ludCBJRCB0byB1c2UuIElmIGFuIGFjY2VzcyBwb2ludCBpcyBzcGVjaWZpZWQsIHRoZSByb290IGRpcmVjdG9yeSB2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIGBFRlNWb2x1bWVDb25maWd1cmF0aW9uYCBtdXN0IGVpdGhlciBiZSBvbWl0dGVkIG9yIHNldCB0byBgL2Agd2hpY2ggd2lsbCBlbmZvcmNlIHRoZSBwYXRoIHNldCBvbiB0aGUgRUZTIGFjY2VzcyBwb2ludC4gSWYgYW4gYWNjZXNzIHBvaW50IGlzIHVzZWQsIHRyYW5zaXQgZW5jcnlwdGlvbiBtdXN0IGJlIG9uIGluIHRoZSBgRUZTVm9sdW1lQ29uZmlndXJhdGlvbmAgLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtXb3JraW5nIHdpdGggQW1hem9uIEVGUyBhY2Nlc3MgcG9pbnRzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWZzL2xhdGVzdC91Zy9lZnMtYWNjZXNzLXBvaW50cy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIEZpbGUgU3lzdGVtIFVzZXIgR3VpZGUqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tYXV0aG9yaXphdGlvbmNvbmZpZy5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tYXV0aG9yaXphdGlvbmNvbmZpZy1hY2Nlc3Nwb2ludGlkXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBhY2Nlc3NQb2ludElkPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRvIHVzZSB0aGUgQW1hem9uIEVDUyB0YXNrIHJvbGUgZGVmaW5lZCBpbiBhIHRhc2sgZGVmaW5pdGlvbiB3aGVuIG1vdW50aW5nIHRoZSBBbWF6b24gRUZTIGZpbGUgc3lzdGVtLiBJZiBpdCBpcyB0dXJuZWQgb24sIHRyYW5zaXQgZW5jcnlwdGlvbiBtdXN0IGJlIHR1cm5lZCBvbiBpbiB0aGUgYEVGU1ZvbHVtZUNvbmZpZ3VyYXRpb25gIC4gSWYgdGhpcyBwYXJhbWV0ZXIgaXMgb21pdHRlZCwgdGhlIGRlZmF1bHQgdmFsdWUgb2YgYERJU0FCTEVEYCBpcyB1c2VkLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtVc2luZyBBbWF6b24gRUZTIGFjY2VzcyBwb2ludHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2Vmcy12b2x1bWVzLmh0bWwjZWZzLXZvbHVtZS1hY2Nlc3Nwb2ludHMpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWF1dGhvcml6YXRpb25jb25maWcuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWF1dGhvcml6YXRpb25jb25maWctaWFtXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBpYW0/OiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYEF1dGhvcml6YXRpb25Db25maWdQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQXV0aG9yaXphdGlvbkNvbmZpZ1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uX0F1dGhvcml6YXRpb25Db25maWdQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2FjY2Vzc1BvaW50SWQnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuYWNjZXNzUG9pbnRJZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaWFtJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmlhbSkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJBdXRob3JpemF0aW9uQ29uZmlnUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uQXV0aG9yaXphdGlvbkNvbmZpZ2AgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQXV0aG9yaXphdGlvbkNvbmZpZ1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLkF1dGhvcml6YXRpb25Db25maWdgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuVGFza0RlZmluaXRpb25BdXRob3JpemF0aW9uQ29uZmlnUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblRhc2tEZWZpbml0aW9uX0F1dGhvcml6YXRpb25Db25maWdQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQWNjZXNzUG9pbnRJZDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5hY2Nlc3NQb2ludElkKSxcbiAgICAgICAgSUFNOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmlhbSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uQXV0aG9yaXphdGlvbkNvbmZpZ1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb24uQXV0aG9yaXphdGlvbkNvbmZpZ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblRhc2tEZWZpbml0aW9uLkF1dGhvcml6YXRpb25Db25maWdQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2FjY2Vzc1BvaW50SWQnLCAnQWNjZXNzUG9pbnRJZCcsIHByb3BlcnRpZXMuQWNjZXNzUG9pbnRJZCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5BY2Nlc3NQb2ludElkKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdpYW0nLCAnSUFNJywgcHJvcGVydGllcy5JQU0gIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuSUFNKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuVGFza0RlZmluaXRpb24ge1xuICAgIC8qKlxuICAgICAqIFRoZSBgQ29udGFpbmVyRGVmaW5pdGlvbmAgcHJvcGVydHkgc3BlY2lmaWVzIGEgY29udGFpbmVyIGRlZmluaXRpb24uIENvbnRhaW5lciBkZWZpbml0aW9ucyBhcmUgdXNlZCBpbiB0YXNrIGRlZmluaXRpb25zIHRvIGRlc2NyaWJlIHRoZSBkaWZmZXJlbnQgY29udGFpbmVycyB0aGF0IGFyZSBsYXVuY2hlZCBhcyBwYXJ0IG9mIGEgdGFzay5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIENvbnRhaW5lckRlZmluaXRpb25Qcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY29tbWFuZCB0aGF0J3MgcGFzc2VkIHRvIHRoZSBjb250YWluZXIuIFRoaXMgcGFyYW1ldGVyIG1hcHMgdG8gYENtZGAgaW4gdGhlIFtDcmVhdGUgYSBjb250YWluZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LyNvcGVyYXRpb24vQ29udGFpbmVyQ3JlYXRlKSBzZWN0aW9uIG9mIHRoZSBbRG9ja2VyIFJlbW90ZSBBUEldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LykgYW5kIHRoZSBgQ09NTUFORGAgcGFyYW1ldGVyIHRvIFtkb2NrZXIgcnVuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vI3NlY3VyaXR5LWNvbmZpZ3VyYXRpb24pIC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9idWlsZGVyLyNjbWRdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL2J1aWxkZXIvI2NtZCkgLiBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgYXJndW1lbnRzLCBlYWNoIGFyZ3VtZW50IGlzIGEgc2VwYXJhdGVkIHN0cmluZyBpbiB0aGUgYXJyYXkuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24tY29tbWFuZFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY29tbWFuZD86IHN0cmluZ1tdO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG51bWJlciBvZiBgY3B1YCB1bml0cyByZXNlcnZlZCBmb3IgdGhlIGNvbnRhaW5lci4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgQ3B1U2hhcmVzYCBpbiB0aGUgW0NyZWF0ZSBhIGNvbnRhaW5lcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvI29wZXJhdGlvbi9Db250YWluZXJDcmVhdGUpIHNlY3Rpb24gb2YgdGhlIFtEb2NrZXIgUmVtb3RlIEFQSV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvKSBhbmQgdGhlIGAtLWNwdS1zaGFyZXNgIG9wdGlvbiB0byBbZG9ja2VyIHJ1bl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9yZWZlcmVuY2UvcnVuLyNzZWN1cml0eS1jb25maWd1cmF0aW9uKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqIFRoaXMgZmllbGQgaXMgb3B0aW9uYWwgZm9yIHRhc2tzIHVzaW5nIHRoZSBGYXJnYXRlIGxhdW5jaCB0eXBlLCBhbmQgdGhlIG9ubHkgcmVxdWlyZW1lbnQgaXMgdGhhdCB0aGUgdG90YWwgYW1vdW50IG9mIENQVSByZXNlcnZlZCBmb3IgYWxsIGNvbnRhaW5lcnMgd2l0aGluIGEgdGFzayBiZSBsb3dlciB0aGFuIHRoZSB0YXNrLWxldmVsIGBjcHVgIHZhbHVlLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFlvdSBjYW4gZGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgQ1BVIHVuaXRzIHRoYXQgYXJlIGF2YWlsYWJsZSBwZXIgRUMyIGluc3RhbmNlIHR5cGUgYnkgbXVsdGlwbHlpbmcgdGhlIHZDUFVzIGxpc3RlZCBmb3IgdGhhdCBpbnN0YW5jZSB0eXBlIG9uIHRoZSBbQW1hem9uIEVDMiBJbnN0YW5jZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lYzIvaW5zdGFuY2UtdHlwZXMvKSBkZXRhaWwgcGFnZSBieSAxLDAyNC5cbiAgICAgICAgICpcbiAgICAgICAgICogTGludXggY29udGFpbmVycyBzaGFyZSB1bmFsbG9jYXRlZCBDUFUgdW5pdHMgd2l0aCBvdGhlciBjb250YWluZXJzIG9uIHRoZSBjb250YWluZXIgaW5zdGFuY2Ugd2l0aCB0aGUgc2FtZSByYXRpbyBhcyB0aGVpciBhbGxvY2F0ZWQgYW1vdW50LiBGb3IgZXhhbXBsZSwgaWYgeW91IHJ1biBhIHNpbmdsZS1jb250YWluZXIgdGFzayBvbiBhIHNpbmdsZS1jb3JlIGluc3RhbmNlIHR5cGUgd2l0aCA1MTIgQ1BVIHVuaXRzIHNwZWNpZmllZCBmb3IgdGhhdCBjb250YWluZXIsIGFuZCB0aGF0J3MgdGhlIG9ubHkgdGFzayBydW5uaW5nIG9uIHRoZSBjb250YWluZXIgaW5zdGFuY2UsIHRoYXQgY29udGFpbmVyIGNvdWxkIHVzZSB0aGUgZnVsbCAxLDAyNCBDUFUgdW5pdCBzaGFyZSBhdCBhbnkgZ2l2ZW4gdGltZS4gSG93ZXZlciwgaWYgeW91IGxhdW5jaGVkIGFub3RoZXIgY29weSBvZiB0aGUgc2FtZSB0YXNrIG9uIHRoYXQgY29udGFpbmVyIGluc3RhbmNlLCBlYWNoIHRhc2sgaXMgZ3VhcmFudGVlZCBhIG1pbmltdW0gb2YgNTEyIENQVSB1bml0cyB3aGVuIG5lZWRlZC4gTW9yZW92ZXIsIGVhY2ggY29udGFpbmVyIGNvdWxkIGZsb2F0IHRvIGhpZ2hlciBDUFUgdXNhZ2UgaWYgdGhlIG90aGVyIGNvbnRhaW5lciB3YXMgbm90IHVzaW5nIGl0LiBJZiBib3RoIHRhc2tzIHdlcmUgMTAwJSBhY3RpdmUgYWxsIG9mIHRoZSB0aW1lLCB0aGV5IHdvdWxkIGJlIGxpbWl0ZWQgdG8gNTEyIENQVSB1bml0cy5cbiAgICAgICAgICpcbiAgICAgICAgICogT24gTGludXggY29udGFpbmVyIGluc3RhbmNlcywgdGhlIERvY2tlciBkYWVtb24gb24gdGhlIGNvbnRhaW5lciBpbnN0YW5jZSB1c2VzIHRoZSBDUFUgdmFsdWUgdG8gY2FsY3VsYXRlIHRoZSByZWxhdGl2ZSBDUFUgc2hhcmUgcmF0aW9zIGZvciBydW5uaW5nIGNvbnRhaW5lcnMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0NQVSBzaGFyZSBjb25zdHJhaW50XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vI2NwdS1zaGFyZS1jb25zdHJhaW50KSBpbiB0aGUgRG9ja2VyIGRvY3VtZW50YXRpb24uIFRoZSBtaW5pbXVtIHZhbGlkIENQVSBzaGFyZSB2YWx1ZSB0aGF0IHRoZSBMaW51eCBrZXJuZWwgYWxsb3dzIGlzIDIuIEhvd2V2ZXIsIHRoZSBDUFUgcGFyYW1ldGVyIGlzbid0IHJlcXVpcmVkLCBhbmQgeW91IGNhbiB1c2UgQ1BVIHZhbHVlcyBiZWxvdyAyIGluIHlvdXIgY29udGFpbmVyIGRlZmluaXRpb25zLiBGb3IgQ1BVIHZhbHVlcyBiZWxvdyAyIChpbmNsdWRpbmcgbnVsbCksIHRoZSBiZWhhdmlvciB2YXJpZXMgYmFzZWQgb24geW91ciBBbWF6b24gRUNTIGNvbnRhaW5lciBhZ2VudCB2ZXJzaW9uOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICpBZ2VudCB2ZXJzaW9ucyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gMS4xLjA6KiBOdWxsIGFuZCB6ZXJvIENQVSB2YWx1ZXMgYXJlIHBhc3NlZCB0byBEb2NrZXIgYXMgMCwgd2hpY2ggRG9ja2VyIHRoZW4gY29udmVydHMgdG8gMSwwMjQgQ1BVIHNoYXJlcy4gQ1BVIHZhbHVlcyBvZiAxIGFyZSBwYXNzZWQgdG8gRG9ja2VyIGFzIDEsIHdoaWNoIHRoZSBMaW51eCBrZXJuZWwgY29udmVydHMgdG8gdHdvIENQVSBzaGFyZXMuXG4gICAgICAgICAqIC0gKkFnZW50IHZlcnNpb25zIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxLjIuMDoqIE51bGwsIHplcm8sIGFuZCBDUFUgdmFsdWVzIG9mIDEgYXJlIHBhc3NlZCB0byBEb2NrZXIgYXMgMi5cbiAgICAgICAgICpcbiAgICAgICAgICogT24gV2luZG93cyBjb250YWluZXIgaW5zdGFuY2VzLCB0aGUgQ1BVIGxpbWl0IGlzIGVuZm9yY2VkIGFzIGFuIGFic29sdXRlIGxpbWl0LCBvciBhIHF1b3RhLiBXaW5kb3dzIGNvbnRhaW5lcnMgb25seSBoYXZlIGFjY2VzcyB0byB0aGUgc3BlY2lmaWVkIGFtb3VudCBvZiBDUFUgdGhhdCdzIGRlc2NyaWJlZCBpbiB0aGUgdGFzayBkZWZpbml0aW9uLiBBIG51bGwgb3IgemVybyBDUFUgdmFsdWUgaXMgcGFzc2VkIHRvIERvY2tlciBhcyBgMGAgLCB3aGljaCBXaW5kb3dzIGludGVycHJldHMgYXMgMSUgb2Ygb25lIENQVS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi1jcHVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNwdT86IG51bWJlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBkZXBlbmRlbmNpZXMgZGVmaW5lZCBmb3IgY29udGFpbmVyIHN0YXJ0dXAgYW5kIHNodXRkb3duLiBBIGNvbnRhaW5lciBjYW4gY29udGFpbiBtdWx0aXBsZSBkZXBlbmRlbmNpZXMuIFdoZW4gYSBkZXBlbmRlbmN5IGlzIGRlZmluZWQgZm9yIGNvbnRhaW5lciBzdGFydHVwLCBmb3IgY29udGFpbmVyIHNodXRkb3duIGl0IGlzIHJldmVyc2VkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgdGFza3MgdXNpbmcgdGhlIEVDMiBsYXVuY2ggdHlwZSwgdGhlIGNvbnRhaW5lciBpbnN0YW5jZXMgcmVxdWlyZSBhdCBsZWFzdCB2ZXJzaW9uIDEuMjYuMCBvZiB0aGUgY29udGFpbmVyIGFnZW50IHRvIHR1cm4gb24gY29udGFpbmVyIGRlcGVuZGVuY2llcy4gSG93ZXZlciwgd2UgcmVjb21tZW5kIHVzaW5nIHRoZSBsYXRlc3QgY29udGFpbmVyIGFnZW50IHZlcnNpb24uIEZvciBpbmZvcm1hdGlvbiBhYm91dCBjaGVja2luZyB5b3VyIGFnZW50IHZlcnNpb24gYW5kIHVwZGF0aW5nIHRvIHRoZSBsYXRlc3QgdmVyc2lvbiwgc2VlIFtVcGRhdGluZyB0aGUgQW1hem9uIEVDUyBDb250YWluZXIgQWdlbnRdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2Vjcy1hZ2VudC11cGRhdGUuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC4gSWYgeW91J3JlIHVzaW5nIGFuIEFtYXpvbiBFQ1Mtb3B0aW1pemVkIExpbnV4IEFNSSwgeW91ciBpbnN0YW5jZSBuZWVkcyBhdCBsZWFzdCB2ZXJzaW9uIDEuMjYuMC0xIG9mIHRoZSBgZWNzLWluaXRgIHBhY2thZ2UuIElmIHlvdXIgY29udGFpbmVyIGluc3RhbmNlcyBhcmUgbGF1bmNoZWQgZnJvbSB2ZXJzaW9uIGAyMDE5MDMwMWAgb3IgbGF0ZXIsIHRoZW4gdGhleSBjb250YWluIHRoZSByZXF1aXJlZCB2ZXJzaW9ucyBvZiB0aGUgY29udGFpbmVyIGFnZW50IGFuZCBgZWNzLWluaXRgIC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQW1hem9uIEVDUy1vcHRpbWl6ZWQgTGludXggQU1JXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9lY3Mtb3B0aW1pemVkX0FNSS5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgdGFza3MgdXNpbmcgdGhlIEZhcmdhdGUgbGF1bmNoIHR5cGUsIHRoZSB0YXNrIG9yIHNlcnZpY2UgcmVxdWlyZXMgdGhlIGZvbGxvd2luZyBwbGF0Zm9ybXM6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gTGludXggcGxhdGZvcm0gdmVyc2lvbiBgMS4zLjBgIG9yIGxhdGVyLlxuICAgICAgICAgKiAtIFdpbmRvd3MgcGxhdGZvcm0gdmVyc2lvbiBgMS4wLjBgIG9yIGxhdGVyLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB0aGUgdGFzayBkZWZpbml0aW9uIGlzIHVzZWQgaW4gYSBibHVlL2dyZWVuIGRlcGxveW1lbnQgdGhhdCB1c2VzIFtBV1M6OkNvZGVEZXBsb3k6OkRlcGxveW1lbnRHcm91cCBCbHVlR3JlZW5EZXBsb3ltZW50Q29uZmlndXJhdGlvbl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtY29kZWRlcGxveS1kZXBsb3ltZW50Z3JvdXAtYmx1ZWdyZWVuZGVwbG95bWVudGNvbmZpZ3VyYXRpb24uaHRtbCkgLCB0aGUgYGRlcGVuZHNPbmAgcGFyYW1ldGVyIGlzIG5vdCBzdXBwb3J0ZWQuIEZvciBtb3JlIGluZm9ybWF0aW9uIHNlZSBbSXNzdWUgIzY4MF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZ2l0aHViLmNvbS9hd3MtY2xvdWRmb3JtYXRpb24vY2xvdWRmb3JtYXRpb24tY292ZXJhZ2Utcm9hZG1hcC9pc3N1ZXMvNjgwKSBvbiB0aGUgb24gdGhlIEdpdEh1YiB3ZWJzaXRlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLWRlcGVuZHNvblxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgZGVwZW5kc09uPzogQXJyYXk8Q2ZuVGFza0RlZmluaXRpb24uQ29udGFpbmVyRGVwZW5kZW5jeVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZW4gdGhpcyBwYXJhbWV0ZXIgaXMgdHJ1ZSwgbmV0d29ya2luZyBpcyBvZmYgd2l0aGluIHRoZSBjb250YWluZXIuIFRoaXMgcGFyYW1ldGVyIG1hcHMgdG8gYE5ldHdvcmtEaXNhYmxlZGAgaW4gdGhlIFtDcmVhdGUgYSBjb250YWluZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LyNvcGVyYXRpb24vQ29udGFpbmVyQ3JlYXRlKSBzZWN0aW9uIG9mIHRoZSBbRG9ja2VyIFJlbW90ZSBBUEldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LykgLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFRoaXMgcGFyYW1ldGVyIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIFdpbmRvd3MgY29udGFpbmVycy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi1kaXNhYmxlbmV0d29ya2luZ1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgZGlzYWJsZU5ldHdvcmtpbmc/OiBib29sZWFuIHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogQSBsaXN0IG9mIEROUyBzZWFyY2ggZG9tYWlucyB0aGF0IGFyZSBwcmVzZW50ZWQgdG8gdGhlIGNvbnRhaW5lci4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgRG5zU2VhcmNoYCBpbiB0aGUgW0NyZWF0ZSBhIGNvbnRhaW5lcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvI29wZXJhdGlvbi9Db250YWluZXJDcmVhdGUpIHNlY3Rpb24gb2YgdGhlIFtEb2NrZXIgUmVtb3RlIEFQSV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvKSBhbmQgdGhlIGAtLWRucy1zZWFyY2hgIG9wdGlvbiB0byBbZG9ja2VyIHJ1bl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9yZWZlcmVuY2UvcnVuLyNzZWN1cml0eS1jb25maWd1cmF0aW9uKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gVGhpcyBwYXJhbWV0ZXIgaXMgbm90IHN1cHBvcnRlZCBmb3IgV2luZG93cyBjb250YWluZXJzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLWRuc3NlYXJjaGRvbWFpbnNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGRuc1NlYXJjaERvbWFpbnM/OiBzdHJpbmdbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgbGlzdCBvZiBETlMgc2VydmVycyB0aGF0IGFyZSBwcmVzZW50ZWQgdG8gdGhlIGNvbnRhaW5lci4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgRG5zYCBpbiB0aGUgW0NyZWF0ZSBhIGNvbnRhaW5lcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvI29wZXJhdGlvbi9Db250YWluZXJDcmVhdGUpIHNlY3Rpb24gb2YgdGhlIFtEb2NrZXIgUmVtb3RlIEFQSV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvKSBhbmQgdGhlIGAtLWRuc2Agb3B0aW9uIHRvIFtkb2NrZXIgcnVuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vI3NlY3VyaXR5LWNvbmZpZ3VyYXRpb24pIC5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBUaGlzIHBhcmFtZXRlciBpcyBub3Qgc3VwcG9ydGVkIGZvciBXaW5kb3dzIGNvbnRhaW5lcnMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24tZG5zc2VydmVyc1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgZG5zU2VydmVycz86IHN0cmluZ1tdO1xuICAgICAgICAvKipcbiAgICAgICAgICogQSBrZXkvdmFsdWUgbWFwIG9mIGxhYmVscyB0byBhZGQgdG8gdGhlIGNvbnRhaW5lci4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgTGFiZWxzYCBpbiB0aGUgW0NyZWF0ZSBhIGNvbnRhaW5lcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvI29wZXJhdGlvbi9Db250YWluZXJDcmVhdGUpIHNlY3Rpb24gb2YgdGhlIFtEb2NrZXIgUmVtb3RlIEFQSV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvKSBhbmQgdGhlIGAtLWxhYmVsYCBvcHRpb24gdG8gW2RvY2tlciBydW5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jc2VjdXJpdHktY29uZmlndXJhdGlvbikgLiBUaGlzIHBhcmFtZXRlciByZXF1aXJlcyB2ZXJzaW9uIDEuMTggb2YgdGhlIERvY2tlciBSZW1vdGUgQVBJIG9yIGdyZWF0ZXIgb24geW91ciBjb250YWluZXIgaW5zdGFuY2UuIFRvIGNoZWNrIHRoZSBEb2NrZXIgUmVtb3RlIEFQSSB2ZXJzaW9uIG9uIHlvdXIgY29udGFpbmVyIGluc3RhbmNlLCBsb2cgaW4gdG8geW91ciBjb250YWluZXIgaW5zdGFuY2UgYW5kIHJ1biB0aGUgZm9sbG93aW5nIGNvbW1hbmQ6IGBzdWRvIGRvY2tlciB2ZXJzaW9uIC0tZm9ybWF0ICd7ey5TZXJ2ZXIuQVBJVmVyc2lvbn19J2BcbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi1kb2NrZXJsYWJlbHNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGRvY2tlckxhYmVscz86IHsgW2tleTogc3RyaW5nXTogKHN0cmluZykgfSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgbGlzdCBvZiBzdHJpbmdzIHRvIHByb3ZpZGUgY3VzdG9tIGNvbmZpZ3VyYXRpb24gZm9yIG11bHRpcGxlIHNlY3VyaXR5IHN5c3RlbXMuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHZhbGlkIHZhbHVlcywgc2VlIFtEb2NrZXIgUnVuIFNlY3VyaXR5IENvbmZpZ3VyYXRpb25dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jc2VjdXJpdHktY29uZmlndXJhdGlvbikgLiBUaGlzIGZpZWxkIGlzbid0IHZhbGlkIGZvciBjb250YWluZXJzIGluIHRhc2tzIHVzaW5nIHRoZSBGYXJnYXRlIGxhdW5jaCB0eXBlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgTGludXggdGFza3Mgb24gRUMyLCB0aGlzIHBhcmFtZXRlciBjYW4gYmUgdXNlZCB0byByZWZlcmVuY2UgY3VzdG9tIGxhYmVscyBmb3IgU0VMaW51eCBhbmQgQXBwQXJtb3IgbXVsdGktbGV2ZWwgc2VjdXJpdHkgc3lzdGVtcy5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIGFueSB0YXNrcyBvbiBFQzIsIHRoaXMgcGFyYW1ldGVyIGNhbiBiZSB1c2VkIHRvIHJlZmVyZW5jZSBhIGNyZWRlbnRpYWwgc3BlYyBmaWxlIHRoYXQgY29uZmlndXJlcyBhIGNvbnRhaW5lciBmb3IgQWN0aXZlIERpcmVjdG9yeSBhdXRoZW50aWNhdGlvbi4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbVXNpbmcgZ01TQXMgZm9yIFdpbmRvd3MgQ29udGFpbmVyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvd2luZG93cy1nbXNhLmh0bWwpIGFuZCBbVXNpbmcgZ01TQXMgZm9yIExpbnV4IENvbnRhaW5lcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2xpbnV4LWdtc2EuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgU2VjdXJpdHlPcHRgIGluIHRoZSBbQ3JlYXRlIGEgY29udGFpbmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8jb3BlcmF0aW9uL0NvbnRhaW5lckNyZWF0ZSkgc2VjdGlvbiBvZiB0aGUgW0RvY2tlciBSZW1vdGUgQVBJXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8pIGFuZCB0aGUgYC0tc2VjdXJpdHktb3B0YCBvcHRpb24gdG8gW2RvY2tlciBydW5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jc2VjdXJpdHktY29uZmlndXJhdGlvbikgLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFRoZSBBbWF6b24gRUNTIGNvbnRhaW5lciBhZ2VudCBydW5uaW5nIG9uIGEgY29udGFpbmVyIGluc3RhbmNlIG11c3QgcmVnaXN0ZXIgd2l0aCB0aGUgYEVDU19TRUxJTlVYX0NBUEFCTEU9dHJ1ZWAgb3IgYEVDU19BUFBBUk1PUl9DQVBBQkxFPXRydWVgIGVudmlyb25tZW50IHZhcmlhYmxlcyBiZWZvcmUgY29udGFpbmVycyBwbGFjZWQgb24gdGhhdCBpbnN0YW5jZSBjYW4gdXNlIHRoZXNlIHNlY3VyaXR5IG9wdGlvbnMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0FtYXpvbiBFQ1MgQ29udGFpbmVyIEFnZW50IENvbmZpZ3VyYXRpb25dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2Vjcy1hZ2VudC1jb25maWcuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdmFsaWQgdmFsdWVzLCBzZWUgW0RvY2tlciBSdW4gU2VjdXJpdHkgQ29uZmlndXJhdGlvbl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9yZWZlcmVuY2UvcnVuLyNzZWN1cml0eS1jb25maWd1cmF0aW9uKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqIFZhbGlkIHZhbHVlczogXCJuby1uZXctcHJpdmlsZWdlc1wiIHwgXCJhcHBhcm1vcjpQUk9GSUxFXCIgfCBcImxhYmVsOnZhbHVlXCIgfCBcImNyZWRlbnRpYWxzcGVjOkNyZWRlbnRpYWxTcGVjRmlsZVBhdGhcIlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLWRvY2tlcnNlY3VyaXR5b3B0aW9uc1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgZG9ja2VyU2VjdXJpdHlPcHRpb25zPzogc3RyaW5nW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiA+IEVhcmx5IHZlcnNpb25zIG9mIHRoZSBBbWF6b24gRUNTIGNvbnRhaW5lciBhZ2VudCBkb24ndCBwcm9wZXJseSBoYW5kbGUgYGVudHJ5UG9pbnRgIHBhcmFtZXRlcnMuIElmIHlvdSBoYXZlIHByb2JsZW1zIHVzaW5nIGBlbnRyeVBvaW50YCAsIHVwZGF0ZSB5b3VyIGNvbnRhaW5lciBhZ2VudCBvciBlbnRlciB5b3VyIGNvbW1hbmRzIGFuZCBhcmd1bWVudHMgYXMgYGNvbW1hbmRgIGFycmF5IGl0ZW1zIGluc3RlYWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIFRoZSBlbnRyeSBwb2ludCB0aGF0J3MgcGFzc2VkIHRvIHRoZSBjb250YWluZXIuIFRoaXMgcGFyYW1ldGVyIG1hcHMgdG8gYEVudHJ5cG9pbnRgIGluIHRoZSBbQ3JlYXRlIGEgY29udGFpbmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8jb3BlcmF0aW9uL0NvbnRhaW5lckNyZWF0ZSkgc2VjdGlvbiBvZiB0aGUgW0RvY2tlciBSZW1vdGUgQVBJXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8pIGFuZCB0aGUgYC0tZW50cnlwb2ludGAgb3B0aW9uIHRvIFtkb2NrZXIgcnVuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vI3NlY3VyaXR5LWNvbmZpZ3VyYXRpb24pIC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9idWlsZGVyLyNlbnRyeXBvaW50XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9idWlsZGVyLyNlbnRyeXBvaW50KSAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24tZW50cnlwb2ludFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgZW50cnlQb2ludD86IHN0cmluZ1tdO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGVudmlyb25tZW50IHZhcmlhYmxlcyB0byBwYXNzIHRvIGEgY29udGFpbmVyLiBUaGlzIHBhcmFtZXRlciBtYXBzIHRvIGBFbnZgIGluIHRoZSBbQ3JlYXRlIGEgY29udGFpbmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8jb3BlcmF0aW9uL0NvbnRhaW5lckNyZWF0ZSkgc2VjdGlvbiBvZiB0aGUgW0RvY2tlciBSZW1vdGUgQVBJXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8pIGFuZCB0aGUgYC0tZW52YCBvcHRpb24gdG8gW2RvY2tlciBydW5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jc2VjdXJpdHktY29uZmlndXJhdGlvbikgLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFdlIGRvbid0IHJlY29tbWVuZCB0aGF0IHlvdSB1c2UgcGxhaW50ZXh0IGVudmlyb25tZW50IHZhcmlhYmxlcyBmb3Igc2Vuc2l0aXZlIGluZm9ybWF0aW9uLCBzdWNoIGFzIGNyZWRlbnRpYWwgZGF0YS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi1lbnZpcm9ubWVudFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgZW52aXJvbm1lbnQ/OiBBcnJheTxDZm5UYXNrRGVmaW5pdGlvbi5LZXlWYWx1ZVBhaXJQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBIGxpc3Qgb2YgZmlsZXMgY29udGFpbmluZyB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGVzIHRvIHBhc3MgdG8gYSBjb250YWluZXIuIFRoaXMgcGFyYW1ldGVyIG1hcHMgdG8gdGhlIGAtLWVudi1maWxlYCBvcHRpb24gdG8gW2RvY2tlciBydW5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jc2VjdXJpdHktY29uZmlndXJhdGlvbikgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBZb3UgY2FuIHNwZWNpZnkgdXAgdG8gdGVuIGVudmlyb25tZW50IGZpbGVzLiBUaGUgZmlsZSBtdXN0IGhhdmUgYSBgLmVudmAgZmlsZSBleHRlbnNpb24uIEVhY2ggbGluZSBpbiBhbiBlbnZpcm9ubWVudCBmaWxlIGNvbnRhaW5zIGFuIGVudmlyb25tZW50IHZhcmlhYmxlIGluIGBWQVJJQUJMRT1WQUxVRWAgZm9ybWF0LiBMaW5lcyBiZWdpbm5pbmcgd2l0aCBgI2AgYXJlIHRyZWF0ZWQgYXMgY29tbWVudHMgYW5kIGFyZSBpZ25vcmVkLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGUgZmlsZSBzeW50YXgsIHNlZSBbRGVjbGFyZSBkZWZhdWx0IGVudmlyb25tZW50IHZhcmlhYmxlcyBpbiBmaWxlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vY29tcG9zZS9lbnYtZmlsZS8pIC5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgdGhlcmUgYXJlIGVudmlyb25tZW50IHZhcmlhYmxlcyBzcGVjaWZpZWQgdXNpbmcgdGhlIGBlbnZpcm9ubWVudGAgcGFyYW1ldGVyIGluIGEgY29udGFpbmVyIGRlZmluaXRpb24sIHRoZXkgdGFrZSBwcmVjZWRlbmNlIG92ZXIgdGhlIHZhcmlhYmxlcyBjb250YWluZWQgd2l0aGluIGFuIGVudmlyb25tZW50IGZpbGUuIElmIG11bHRpcGxlIGVudmlyb25tZW50IGZpbGVzIGFyZSBzcGVjaWZpZWQgdGhhdCBjb250YWluIHRoZSBzYW1lIHZhcmlhYmxlLCB0aGV5J3JlIHByb2Nlc3NlZCBmcm9tIHRoZSB0b3AgZG93bi4gV2UgcmVjb21tZW5kIHRoYXQgeW91IHVzZSB1bmlxdWUgdmFyaWFibGUgbmFtZXMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1NwZWNpZnlpbmcgRW52aXJvbm1lbnQgVmFyaWFibGVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS90YXNrZGVmLWVudmZpbGVzLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24tZW52aXJvbm1lbnRmaWxlc1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgZW52aXJvbm1lbnRGaWxlcz86IEFycmF5PENmblRhc2tEZWZpbml0aW9uLkVudmlyb25tZW50RmlsZVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIElmIHRoZSBgZXNzZW50aWFsYCBwYXJhbWV0ZXIgb2YgYSBjb250YWluZXIgaXMgbWFya2VkIGFzIGB0cnVlYCAsIGFuZCB0aGF0IGNvbnRhaW5lciBmYWlscyBvciBzdG9wcyBmb3IgYW55IHJlYXNvbiwgYWxsIG90aGVyIGNvbnRhaW5lcnMgdGhhdCBhcmUgcGFydCBvZiB0aGUgdGFzayBhcmUgc3RvcHBlZC4gSWYgdGhlIGBlc3NlbnRpYWxgIHBhcmFtZXRlciBvZiBhIGNvbnRhaW5lciBpcyBtYXJrZWQgYXMgYGZhbHNlYCAsIGl0cyBmYWlsdXJlIGRvZXNuJ3QgYWZmZWN0IHRoZSByZXN0IG9mIHRoZSBjb250YWluZXJzIGluIGEgdGFzay4gSWYgdGhpcyBwYXJhbWV0ZXIgaXMgb21pdHRlZCwgYSBjb250YWluZXIgaXMgYXNzdW1lZCB0byBiZSBlc3NlbnRpYWwuXG4gICAgICAgICAqXG4gICAgICAgICAqIEFsbCB0YXNrcyBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIGVzc2VudGlhbCBjb250YWluZXIuIElmIHlvdSBoYXZlIGFuIGFwcGxpY2F0aW9uIHRoYXQncyBjb21wb3NlZCBvZiBtdWx0aXBsZSBjb250YWluZXJzLCBncm91cCBjb250YWluZXJzIHRoYXQgYXJlIHVzZWQgZm9yIGEgY29tbW9uIHB1cnBvc2UgaW50byBjb21wb25lbnRzLCBhbmQgc2VwYXJhdGUgdGhlIGRpZmZlcmVudCBjb21wb25lbnRzIGludG8gbXVsdGlwbGUgdGFzayBkZWZpbml0aW9ucy4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQXBwbGljYXRpb24gQXJjaGl0ZWN0dXJlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9hcHBsaWNhdGlvbl9hcmNoaXRlY3R1cmUuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi1lc3NlbnRpYWxcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGVzc2VudGlhbD86IGJvb2xlYW4gfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBIGxpc3Qgb2YgaG9zdG5hbWVzIGFuZCBJUCBhZGRyZXNzIG1hcHBpbmdzIHRvIGFwcGVuZCB0byB0aGUgYC9ldGMvaG9zdHNgIGZpbGUgb24gdGhlIGNvbnRhaW5lci4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgRXh0cmFIb3N0c2AgaW4gdGhlIFtDcmVhdGUgYSBjb250YWluZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LyNvcGVyYXRpb24vQ29udGFpbmVyQ3JlYXRlKSBzZWN0aW9uIG9mIHRoZSBbRG9ja2VyIFJlbW90ZSBBUEldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LykgYW5kIHRoZSBgLS1hZGQtaG9zdGAgb3B0aW9uIHRvIFtkb2NrZXIgcnVuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vI3NlY3VyaXR5LWNvbmZpZ3VyYXRpb24pIC5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBUaGlzIHBhcmFtZXRlciBpc24ndCBzdXBwb3J0ZWQgZm9yIFdpbmRvd3MgY29udGFpbmVycyBvciB0YXNrcyB0aGF0IHVzZSB0aGUgYGF3c3ZwY2AgbmV0d29yayBtb2RlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLWV4dHJhaG9zdHNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGV4dHJhSG9zdHM/OiBBcnJheTxDZm5UYXNrRGVmaW5pdGlvbi5Ib3N0RW50cnlQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgRmlyZUxlbnMgY29uZmlndXJhdGlvbiBmb3IgdGhlIGNvbnRhaW5lci4gVGhpcyBpcyB1c2VkIHRvIHNwZWNpZnkgYW5kIGNvbmZpZ3VyZSBhIGxvZyByb3V0ZXIgZm9yIGNvbnRhaW5lciBsb2dzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtDdXN0b20gTG9nIFJvdXRpbmddKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3VzaW5nX2ZpcmVsZW5zLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24tZmlyZWxlbnNjb25maWd1cmF0aW9uXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBmaXJlbGVuc0NvbmZpZ3VyYXRpb24/OiBDZm5UYXNrRGVmaW5pdGlvbi5GaXJlbGVuc0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjb250YWluZXIgaGVhbHRoIGNoZWNrIGNvbW1hbmQgYW5kIGFzc29jaWF0ZWQgY29uZmlndXJhdGlvbiBwYXJhbWV0ZXJzIGZvciB0aGUgY29udGFpbmVyLiBUaGlzIHBhcmFtZXRlciBtYXBzIHRvIGBIZWFsdGhDaGVja2AgaW4gdGhlIFtDcmVhdGUgYSBjb250YWluZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LyNvcGVyYXRpb24vQ29udGFpbmVyQ3JlYXRlKSBzZWN0aW9uIG9mIHRoZSBbRG9ja2VyIFJlbW90ZSBBUEldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LykgYW5kIHRoZSBgSEVBTFRIQ0hFQ0tgIHBhcmFtZXRlciBvZiBbZG9ja2VyIHJ1bl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9yZWZlcmVuY2UvcnVuLyNzZWN1cml0eS1jb25maWd1cmF0aW9uKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24taGVhbHRoY2hlY2tcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGhlYWx0aENoZWNrPzogQ2ZuVGFza0RlZmluaXRpb24uSGVhbHRoQ2hlY2tQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBob3N0bmFtZSB0byB1c2UgZm9yIHlvdXIgY29udGFpbmVyLiBUaGlzIHBhcmFtZXRlciBtYXBzIHRvIGBIb3N0bmFtZWAgaW4gdGhlIFtDcmVhdGUgYSBjb250YWluZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LyNvcGVyYXRpb24vQ29udGFpbmVyQ3JlYXRlKSBzZWN0aW9uIG9mIHRoZSBbRG9ja2VyIFJlbW90ZSBBUEldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LykgYW5kIHRoZSBgLS1ob3N0bmFtZWAgb3B0aW9uIHRvIFtkb2NrZXIgcnVuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vI3NlY3VyaXR5LWNvbmZpZ3VyYXRpb24pIC5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBUaGUgYGhvc3RuYW1lYCBwYXJhbWV0ZXIgaXMgbm90IHN1cHBvcnRlZCBpZiB5b3UncmUgdXNpbmcgdGhlIGBhd3N2cGNgIG5ldHdvcmsgbW9kZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi1ob3N0bmFtZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgaG9zdG5hbWU/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaW1hZ2UgdXNlZCB0byBzdGFydCBhIGNvbnRhaW5lci4gVGhpcyBzdHJpbmcgaXMgcGFzc2VkIGRpcmVjdGx5IHRvIHRoZSBEb2NrZXIgZGFlbW9uLiBCeSBkZWZhdWx0LCBpbWFnZXMgaW4gdGhlIERvY2tlciBIdWIgcmVnaXN0cnkgYXJlIGF2YWlsYWJsZS4gT3RoZXIgcmVwb3NpdG9yaWVzIGFyZSBzcGVjaWZpZWQgd2l0aCBlaXRoZXIgYCpyZXBvc2l0b3J5LXVybCogLyAqaW1hZ2UqIDogKnRhZypgIG9yIGAqcmVwb3NpdG9yeS11cmwqIC8gKmltYWdlKiBAICpkaWdlc3QqYCAuIFVwIHRvIDI1NSBsZXR0ZXJzICh1cHBlcmNhc2UgYW5kIGxvd2VyY2FzZSksIG51bWJlcnMsIGh5cGhlbnMsIHVuZGVyc2NvcmVzLCBjb2xvbnMsIHBlcmlvZHMsIGZvcndhcmQgc2xhc2hlcywgYW5kIG51bWJlciBzaWducyBhcmUgYWxsb3dlZC4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgSW1hZ2VgIGluIHRoZSBbQ3JlYXRlIGEgY29udGFpbmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8jb3BlcmF0aW9uL0NvbnRhaW5lckNyZWF0ZSkgc2VjdGlvbiBvZiB0aGUgW0RvY2tlciBSZW1vdGUgQVBJXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8pIGFuZCB0aGUgYElNQUdFYCBwYXJhbWV0ZXIgb2YgW2RvY2tlciBydW5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jc2VjdXJpdHktY29uZmlndXJhdGlvbikgLlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIFdoZW4gYSBuZXcgdGFzayBzdGFydHMsIHRoZSBBbWF6b24gRUNTIGNvbnRhaW5lciBhZ2VudCBwdWxscyB0aGUgbGF0ZXN0IHZlcnNpb24gb2YgdGhlIHNwZWNpZmllZCBpbWFnZSBhbmQgdGFnIGZvciB0aGUgY29udGFpbmVyIHRvIHVzZS4gSG93ZXZlciwgc3Vic2VxdWVudCB1cGRhdGVzIHRvIGEgcmVwb3NpdG9yeSBpbWFnZSBhcmVuJ3QgcHJvcGFnYXRlZCB0byBhbHJlYWR5IHJ1bm5pbmcgdGFza3MuXG4gICAgICAgICAqIC0gSW1hZ2VzIGluIEFtYXpvbiBFQ1IgcmVwb3NpdG9yaWVzIGNhbiBiZSBzcGVjaWZpZWQgYnkgZWl0aGVyIHVzaW5nIHRoZSBmdWxsIGByZWdpc3RyeS9yZXBvc2l0b3J5OnRhZ2Agb3IgYHJlZ2lzdHJ5L3JlcG9zaXRvcnlAZGlnZXN0YCAuIEZvciBleGFtcGxlLCBgMDEyMzQ1Njc4OTEwLmRrci5lY3IuPHJlZ2lvbi1uYW1lPi5hbWF6b25hd3MuY29tLzxyZXBvc2l0b3J5LW5hbWU+OmxhdGVzdGAgb3IgYDAxMjM0NTY3ODkxMC5ka3IuZWNyLjxyZWdpb24tbmFtZT4uYW1hem9uYXdzLmNvbS88cmVwb3NpdG9yeS1uYW1lPkBzaGEyNTY6OTRhZmQxZjJlNjRkOTA4YmM5MGRiY2EwMDM1YTViNTY3RVhBTVBMRWAgLlxuICAgICAgICAgKiAtIEltYWdlcyBpbiBvZmZpY2lhbCByZXBvc2l0b3JpZXMgb24gRG9ja2VyIEh1YiB1c2UgYSBzaW5nbGUgbmFtZSAoZm9yIGV4YW1wbGUsIGB1YnVudHVgIG9yIGBtb25nb2AgKS5cbiAgICAgICAgICogLSBJbWFnZXMgaW4gb3RoZXIgcmVwb3NpdG9yaWVzIG9uIERvY2tlciBIdWIgYXJlIHF1YWxpZmllZCB3aXRoIGFuIG9yZ2FuaXphdGlvbiBuYW1lIChmb3IgZXhhbXBsZSwgYGFtYXpvbi9hbWF6b24tZWNzLWFnZW50YCApLlxuICAgICAgICAgKiAtIEltYWdlcyBpbiBvdGhlciBvbmxpbmUgcmVwb3NpdG9yaWVzIGFyZSBxdWFsaWZpZWQgZnVydGhlciBieSBhIGRvbWFpbiBuYW1lIChmb3IgZXhhbXBsZSwgYHF1YXkuaW8vYXNzZW1ibHlsaW5lL3VidW50dWAgKS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi1pbWFnZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgaW1hZ2U6IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZW4gdGhpcyBwYXJhbWV0ZXIgaXMgYHRydWVgICwgeW91IGNhbiBkZXBsb3kgY29udGFpbmVyaXplZCBhcHBsaWNhdGlvbnMgdGhhdCByZXF1aXJlIGBzdGRpbmAgb3IgYSBgdHR5YCB0byBiZSBhbGxvY2F0ZWQuIFRoaXMgcGFyYW1ldGVyIG1hcHMgdG8gYE9wZW5TdGRpbmAgaW4gdGhlIFtDcmVhdGUgYSBjb250YWluZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LyNvcGVyYXRpb24vQ29udGFpbmVyQ3JlYXRlKSBzZWN0aW9uIG9mIHRoZSBbRG9ja2VyIFJlbW90ZSBBUEldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LykgYW5kIHRoZSBgLS1pbnRlcmFjdGl2ZWAgb3B0aW9uIHRvIFtkb2NrZXIgcnVuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vI3NlY3VyaXR5LWNvbmZpZ3VyYXRpb24pIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi1pbnRlcmFjdGl2ZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgaW50ZXJhY3RpdmU/OiBib29sZWFuIHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGBsaW5rc2AgcGFyYW1ldGVyIGFsbG93cyBjb250YWluZXJzIHRvIGNvbW11bmljYXRlIHdpdGggZWFjaCBvdGhlciB3aXRob3V0IHRoZSBuZWVkIGZvciBwb3J0IG1hcHBpbmdzLiBUaGlzIHBhcmFtZXRlciBpcyBvbmx5IHN1cHBvcnRlZCBpZiB0aGUgbmV0d29yayBtb2RlIG9mIGEgdGFzayBkZWZpbml0aW9uIGlzIGBicmlkZ2VgIC4gVGhlIGBuYW1lOmludGVybmFsTmFtZWAgY29uc3RydWN0IGlzIGFuYWxvZ291cyB0byBgbmFtZTphbGlhc2AgaW4gRG9ja2VyIGxpbmtzLiBVcCB0byAyNTUgbGV0dGVycyAodXBwZXJjYXNlIGFuZCBsb3dlcmNhc2UpLCBudW1iZXJzLCB1bmRlcnNjb3JlcywgYW5kIGh5cGhlbnMgYXJlIGFsbG93ZWQuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGxpbmtpbmcgRG9ja2VyIGNvbnRhaW5lcnMsIGdvIHRvIFtMZWdhY3kgY29udGFpbmVyIGxpbmtzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vbmV0d29yay9saW5rcy8pIGluIHRoZSBEb2NrZXIgZG9jdW1lbnRhdGlvbi4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgTGlua3NgIGluIHRoZSBbQ3JlYXRlIGEgY29udGFpbmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8jb3BlcmF0aW9uL0NvbnRhaW5lckNyZWF0ZSkgc2VjdGlvbiBvZiB0aGUgW0RvY2tlciBSZW1vdGUgQVBJXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8pIGFuZCB0aGUgYC0tbGlua2Agb3B0aW9uIHRvIFtkb2NrZXIgcnVuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vI3NlY3VyaXR5LWNvbmZpZ3VyYXRpb24pIC5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBUaGlzIHBhcmFtZXRlciBpcyBub3Qgc3VwcG9ydGVkIGZvciBXaW5kb3dzIGNvbnRhaW5lcnMuID4gQ29udGFpbmVycyB0aGF0IGFyZSBjb2xsb2NhdGVkIG9uIGEgc2luZ2xlIGNvbnRhaW5lciBpbnN0YW5jZSBtYXkgYmUgYWJsZSB0byBjb21tdW5pY2F0ZSB3aXRoIGVhY2ggb3RoZXIgd2l0aG91dCByZXF1aXJpbmcgbGlua3Mgb3IgaG9zdCBwb3J0IG1hcHBpbmdzLiBOZXR3b3JrIGlzb2xhdGlvbiBpcyBhY2hpZXZlZCBvbiB0aGUgY29udGFpbmVyIGluc3RhbmNlIHVzaW5nIHNlY3VyaXR5IGdyb3VwcyBhbmQgVlBDIHNldHRpbmdzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLWxpbmtzXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBsaW5rcz86IHN0cmluZ1tdO1xuICAgICAgICAvKipcbiAgICAgICAgICogTGludXgtc3BlY2lmaWMgbW9kaWZpY2F0aW9ucyB0aGF0IGFyZSBhcHBsaWVkIHRvIHRoZSBjb250YWluZXIsIHN1Y2ggYXMgTGludXgga2VybmVsIGNhcGFiaWxpdGllcy4gRm9yIG1vcmUgaW5mb3JtYXRpb24gc2VlIFtLZXJuZWxDYXBhYmlsaXRpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfS2VybmVsQ2FwYWJpbGl0aWVzLmh0bWwpIC5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBUaGlzIHBhcmFtZXRlciBpcyBub3Qgc3VwcG9ydGVkIGZvciBXaW5kb3dzIGNvbnRhaW5lcnMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24tbGludXhwYXJhbWV0ZXJzXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBsaW51eFBhcmFtZXRlcnM/OiBDZm5UYXNrRGVmaW5pdGlvbi5MaW51eFBhcmFtZXRlcnNQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBsb2cgY29uZmlndXJhdGlvbiBzcGVjaWZpY2F0aW9uIGZvciB0aGUgY29udGFpbmVyLlxuICAgICAgICAgKlxuICAgICAgICAgKiBUaGlzIHBhcmFtZXRlciBtYXBzIHRvIGBMb2dDb25maWdgIGluIHRoZSBbQ3JlYXRlIGEgY29udGFpbmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8jb3BlcmF0aW9uL0NvbnRhaW5lckNyZWF0ZSkgc2VjdGlvbiBvZiB0aGUgW0RvY2tlciBSZW1vdGUgQVBJXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8pIGFuZCB0aGUgYC0tbG9nLWRyaXZlcmAgb3B0aW9uIHRvIFtkb2NrZXIgcnVuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vKSAuIEJ5IGRlZmF1bHQsIGNvbnRhaW5lcnMgdXNlIHRoZSBzYW1lIGxvZ2dpbmcgZHJpdmVyIHRoYXQgdGhlIERvY2tlciBkYWVtb24gdXNlcy4gSG93ZXZlciwgdGhlIGNvbnRhaW5lciBtYXkgdXNlIGEgZGlmZmVyZW50IGxvZ2dpbmcgZHJpdmVyIHRoYW4gdGhlIERvY2tlciBkYWVtb24gYnkgc3BlY2lmeWluZyBhIGxvZyBkcml2ZXIgd2l0aCB0aGlzIHBhcmFtZXRlciBpbiB0aGUgY29udGFpbmVyIGRlZmluaXRpb24uIFRvIHVzZSBhIGRpZmZlcmVudCBsb2dnaW5nIGRyaXZlciBmb3IgYSBjb250YWluZXIsIHRoZSBsb2cgc3lzdGVtIG11c3QgYmUgY29uZmlndXJlZCBwcm9wZXJseSBvbiB0aGUgY29udGFpbmVyIGluc3RhbmNlIChvciBvbiBhIGRpZmZlcmVudCBsb2cgc2VydmVyIGZvciByZW1vdGUgbG9nZ2luZyBvcHRpb25zKS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhlIG9wdGlvbnMgZm9yIGRpZmZlcmVudCBzdXBwb3J0ZWQgbG9nIGRyaXZlcnMsIHNlZSBbQ29uZmlndXJlIGxvZ2dpbmcgZHJpdmVyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hZG1pbi9sb2dnaW5nL292ZXJ2aWV3LykgaW4gdGhlIERvY2tlciBkb2N1bWVudGF0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IEFtYXpvbiBFQ1MgY3VycmVudGx5IHN1cHBvcnRzIGEgc3Vic2V0IG9mIHRoZSBsb2dnaW5nIGRyaXZlcnMgYXZhaWxhYmxlIHRvIHRoZSBEb2NrZXIgZGFlbW9uIChzaG93biBpbiB0aGUgW0xvZ0NvbmZpZ3VyYXRpb25dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTG9nQ29uZmlndXJhdGlvbi5odG1sKSBkYXRhIHR5cGUpLiBBZGRpdGlvbmFsIGxvZyBkcml2ZXJzIG1heSBiZSBhdmFpbGFibGUgaW4gZnV0dXJlIHJlbGVhc2VzIG9mIHRoZSBBbWF6b24gRUNTIGNvbnRhaW5lciBhZ2VudC5cbiAgICAgICAgICpcbiAgICAgICAgICogVGhpcyBwYXJhbWV0ZXIgcmVxdWlyZXMgdmVyc2lvbiAxLjE4IG9mIHRoZSBEb2NrZXIgUmVtb3RlIEFQSSBvciBncmVhdGVyIG9uIHlvdXIgY29udGFpbmVyIGluc3RhbmNlLiBUbyBjaGVjayB0aGUgRG9ja2VyIFJlbW90ZSBBUEkgdmVyc2lvbiBvbiB5b3VyIGNvbnRhaW5lciBpbnN0YW5jZSwgbG9nIGluIHRvIHlvdXIgY29udGFpbmVyIGluc3RhbmNlIGFuZCBydW4gdGhlIGZvbGxvd2luZyBjb21tYW5kOiBgc3VkbyBkb2NrZXIgdmVyc2lvbiAtLWZvcm1hdCAne3suU2VydmVyLkFQSVZlcnNpb259fSdgXG4gICAgICAgICAqXG4gICAgICAgICAqID4gVGhlIEFtYXpvbiBFQ1MgY29udGFpbmVyIGFnZW50IHJ1bm5pbmcgb24gYSBjb250YWluZXIgaW5zdGFuY2UgbXVzdCByZWdpc3RlciB0aGUgbG9nZ2luZyBkcml2ZXJzIGF2YWlsYWJsZSBvbiB0aGF0IGluc3RhbmNlIHdpdGggdGhlIGBFQ1NfQVZBSUxBQkxFX0xPR0dJTkdfRFJJVkVSU2AgZW52aXJvbm1lbnQgdmFyaWFibGUgYmVmb3JlIGNvbnRhaW5lcnMgcGxhY2VkIG9uIHRoYXQgaW5zdGFuY2UgY2FuIHVzZSB0aGVzZSBsb2cgY29uZmlndXJhdGlvbiBvcHRpb25zLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBbWF6b24gRUNTIENvbnRhaW5lciBBZ2VudCBDb25maWd1cmF0aW9uXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9lY3MtYWdlbnQtY29uZmlnLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24tbG9nY29uZmlndXJhdGlvblxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbG9nQ29uZmlndXJhdGlvbj86IENmblRhc2tEZWZpbml0aW9uLkxvZ0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhbW91bnQgKGluIE1pQikgb2YgbWVtb3J5IHRvIHByZXNlbnQgdG8gdGhlIGNvbnRhaW5lci4gSWYgeW91ciBjb250YWluZXIgYXR0ZW1wdHMgdG8gZXhjZWVkIHRoZSBtZW1vcnkgc3BlY2lmaWVkIGhlcmUsIHRoZSBjb250YWluZXIgaXMga2lsbGVkLiBUaGUgdG90YWwgYW1vdW50IG9mIG1lbW9yeSByZXNlcnZlZCBmb3IgYWxsIGNvbnRhaW5lcnMgd2l0aGluIGEgdGFzayBtdXN0IGJlIGxvd2VyIHRoYW4gdGhlIHRhc2sgYG1lbW9yeWAgdmFsdWUsIGlmIG9uZSBpcyBzcGVjaWZpZWQuIFRoaXMgcGFyYW1ldGVyIG1hcHMgdG8gYE1lbW9yeWAgaW4gdGhlIFtDcmVhdGUgYSBjb250YWluZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LyNvcGVyYXRpb24vQ29udGFpbmVyQ3JlYXRlKSBzZWN0aW9uIG9mIHRoZSBbRG9ja2VyIFJlbW90ZSBBUEldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LykgYW5kIHRoZSBgLS1tZW1vcnlgIG9wdGlvbiB0byBbZG9ja2VyIHJ1bl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9yZWZlcmVuY2UvcnVuLyNzZWN1cml0eS1jb25maWd1cmF0aW9uKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHVzaW5nIHRoZSBGYXJnYXRlIGxhdW5jaCB0eXBlLCB0aGlzIHBhcmFtZXRlciBpcyBvcHRpb25hbC5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgdXNpbmcgdGhlIEVDMiBsYXVuY2ggdHlwZSwgeW91IG11c3Qgc3BlY2lmeSBlaXRoZXIgYSB0YXNrLWxldmVsIG1lbW9yeSB2YWx1ZSBvciBhIGNvbnRhaW5lci1sZXZlbCBtZW1vcnkgdmFsdWUuIElmIHlvdSBzcGVjaWZ5IGJvdGggYSBjb250YWluZXItbGV2ZWwgYG1lbW9yeWAgYW5kIGBtZW1vcnlSZXNlcnZhdGlvbmAgdmFsdWUsIGBtZW1vcnlgIG11c3QgYmUgZ3JlYXRlciB0aGFuIGBtZW1vcnlSZXNlcnZhdGlvbmAgLiBJZiB5b3Ugc3BlY2lmeSBgbWVtb3J5UmVzZXJ2YXRpb25gICwgdGhlbiB0aGF0IHZhbHVlIGlzIHN1YnRyYWN0ZWQgZnJvbSB0aGUgYXZhaWxhYmxlIG1lbW9yeSByZXNvdXJjZXMgZm9yIHRoZSBjb250YWluZXIgaW5zdGFuY2Ugd2hlcmUgdGhlIGNvbnRhaW5lciBpcyBwbGFjZWQuIE90aGVyd2lzZSwgdGhlIHZhbHVlIG9mIGBtZW1vcnlgIGlzIHVzZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIFRoZSBEb2NrZXIgMjAuMTAuMCBvciBsYXRlciBkYWVtb24gcmVzZXJ2ZXMgYSBtaW5pbXVtIG9mIDYgTWlCIG9mIG1lbW9yeSBmb3IgYSBjb250YWluZXIsIHNvIHlvdSBzaG91bGQgbm90IHNwZWNpZnkgZmV3ZXIgdGhhbiA2IE1pQiBvZiBtZW1vcnkgZm9yIHlvdXIgY29udGFpbmVycy5cbiAgICAgICAgICpcbiAgICAgICAgICogVGhlIERvY2tlciAxOS4wMy4xMy1jZSBvciBlYXJsaWVyIGRhZW1vbiByZXNlcnZlcyBhIG1pbmltdW0gb2YgNCBNaUIgb2YgbWVtb3J5IGZvciBhIGNvbnRhaW5lciwgc28geW91IHNob3VsZCBub3Qgc3BlY2lmeSBmZXdlciB0aGFuIDQgTWlCIG9mIG1lbW9yeSBmb3IgeW91ciBjb250YWluZXJzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLW1lbW9yeVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbWVtb3J5PzogbnVtYmVyO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHNvZnQgbGltaXQgKGluIE1pQikgb2YgbWVtb3J5IHRvIHJlc2VydmUgZm9yIHRoZSBjb250YWluZXIuIFdoZW4gc3lzdGVtIG1lbW9yeSBpcyB1bmRlciBoZWF2eSBjb250ZW50aW9uLCBEb2NrZXIgYXR0ZW1wdHMgdG8ga2VlcCB0aGUgY29udGFpbmVyIG1lbW9yeSB0byB0aGlzIHNvZnQgbGltaXQuIEhvd2V2ZXIsIHlvdXIgY29udGFpbmVyIGNhbiBjb25zdW1lIG1vcmUgbWVtb3J5IHdoZW4gaXQgbmVlZHMgdG8sIHVwIHRvIGVpdGhlciB0aGUgaGFyZCBsaW1pdCBzcGVjaWZpZWQgd2l0aCB0aGUgYG1lbW9yeWAgcGFyYW1ldGVyIChpZiBhcHBsaWNhYmxlKSwgb3IgYWxsIG9mIHRoZSBhdmFpbGFibGUgbWVtb3J5IG9uIHRoZSBjb250YWluZXIgaW5zdGFuY2UsIHdoaWNoZXZlciBjb21lcyBmaXJzdC4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgTWVtb3J5UmVzZXJ2YXRpb25gIGluIHRoZSBbQ3JlYXRlIGEgY29udGFpbmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8jb3BlcmF0aW9uL0NvbnRhaW5lckNyZWF0ZSkgc2VjdGlvbiBvZiB0aGUgW0RvY2tlciBSZW1vdGUgQVBJXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8pIGFuZCB0aGUgYC0tbWVtb3J5LXJlc2VydmF0aW9uYCBvcHRpb24gdG8gW2RvY2tlciBydW5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jc2VjdXJpdHktY29uZmlndXJhdGlvbikgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiBhIHRhc2stbGV2ZWwgbWVtb3J5IHZhbHVlIGlzIG5vdCBzcGVjaWZpZWQsIHlvdSBtdXN0IHNwZWNpZnkgYSBub24temVybyBpbnRlZ2VyIGZvciBvbmUgb3IgYm90aCBvZiBgbWVtb3J5YCBvciBgbWVtb3J5UmVzZXJ2YXRpb25gIGluIGEgY29udGFpbmVyIGRlZmluaXRpb24uIElmIHlvdSBzcGVjaWZ5IGJvdGgsIGBtZW1vcnlgIG11c3QgYmUgZ3JlYXRlciB0aGFuIGBtZW1vcnlSZXNlcnZhdGlvbmAgLiBJZiB5b3Ugc3BlY2lmeSBgbWVtb3J5UmVzZXJ2YXRpb25gICwgdGhlbiB0aGF0IHZhbHVlIGlzIHN1YnRyYWN0ZWQgZnJvbSB0aGUgYXZhaWxhYmxlIG1lbW9yeSByZXNvdXJjZXMgZm9yIHRoZSBjb250YWluZXIgaW5zdGFuY2Ugd2hlcmUgdGhlIGNvbnRhaW5lciBpcyBwbGFjZWQuIE90aGVyd2lzZSwgdGhlIHZhbHVlIG9mIGBtZW1vcnlgIGlzIHVzZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEZvciBleGFtcGxlLCBpZiB5b3VyIGNvbnRhaW5lciBub3JtYWxseSB1c2VzIDEyOCBNaUIgb2YgbWVtb3J5LCBidXQgb2NjYXNpb25hbGx5IGJ1cnN0cyB0byAyNTYgTWlCIG9mIG1lbW9yeSBmb3Igc2hvcnQgcGVyaW9kcyBvZiB0aW1lLCB5b3UgY2FuIHNldCBhIGBtZW1vcnlSZXNlcnZhdGlvbmAgb2YgMTI4IE1pQiwgYW5kIGEgYG1lbW9yeWAgaGFyZCBsaW1pdCBvZiAzMDAgTWlCLiBUaGlzIGNvbmZpZ3VyYXRpb24gd291bGQgYWxsb3cgdGhlIGNvbnRhaW5lciB0byBvbmx5IHJlc2VydmUgMTI4IE1pQiBvZiBtZW1vcnkgZnJvbSB0aGUgcmVtYWluaW5nIHJlc291cmNlcyBvbiB0aGUgY29udGFpbmVyIGluc3RhbmNlLCBidXQgYWxzbyBhbGxvdyB0aGUgY29udGFpbmVyIHRvIGNvbnN1bWUgbW9yZSBtZW1vcnkgcmVzb3VyY2VzIHdoZW4gbmVlZGVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBUaGUgRG9ja2VyIDIwLjEwLjAgb3IgbGF0ZXIgZGFlbW9uIHJlc2VydmVzIGEgbWluaW11bSBvZiA2IE1pQiBvZiBtZW1vcnkgZm9yIGEgY29udGFpbmVyLiBTbywgZG9uJ3Qgc3BlY2lmeSBsZXNzIHRoYW4gNiBNaUIgb2YgbWVtb3J5IGZvciB5b3VyIGNvbnRhaW5lcnMuXG4gICAgICAgICAqXG4gICAgICAgICAqIFRoZSBEb2NrZXIgMTkuMDMuMTMtY2Ugb3IgZWFybGllciBkYWVtb24gcmVzZXJ2ZXMgYSBtaW5pbXVtIG9mIDQgTWlCIG9mIG1lbW9yeSBmb3IgYSBjb250YWluZXIuIFNvLCBkb24ndCBzcGVjaWZ5IGxlc3MgdGhhbiA0IE1pQiBvZiBtZW1vcnkgZm9yIHlvdXIgY29udGFpbmVycy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi1tZW1vcnlyZXNlcnZhdGlvblxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbWVtb3J5UmVzZXJ2YXRpb24/OiBudW1iZXI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbW91bnQgcG9pbnRzIGZvciBkYXRhIHZvbHVtZXMgaW4geW91ciBjb250YWluZXIuXG4gICAgICAgICAqXG4gICAgICAgICAqIFRoaXMgcGFyYW1ldGVyIG1hcHMgdG8gYFZvbHVtZXNgIGluIHRoZSBbQ3JlYXRlIGEgY29udGFpbmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8jb3BlcmF0aW9uL0NvbnRhaW5lckNyZWF0ZSkgc2VjdGlvbiBvZiB0aGUgW0RvY2tlciBSZW1vdGUgQVBJXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8pIGFuZCB0aGUgYC0tdm9sdW1lYCBvcHRpb24gdG8gW2RvY2tlciBydW5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jc2VjdXJpdHktY29uZmlndXJhdGlvbikgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBXaW5kb3dzIGNvbnRhaW5lcnMgY2FuIG1vdW50IHdob2xlIGRpcmVjdG9yaWVzIG9uIHRoZSBzYW1lIGRyaXZlIGFzIGAkZW52OlByb2dyYW1EYXRhYCAuIFdpbmRvd3MgY29udGFpbmVycyBjYW4ndCBtb3VudCBkaXJlY3RvcmllcyBvbiBhIGRpZmZlcmVudCBkcml2ZSwgYW5kIG1vdW50IHBvaW50IGNhbid0IGJlIGFjcm9zcyBkcml2ZXMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24tbW91bnRwb2ludHNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IG1vdW50UG9pbnRzPzogQXJyYXk8Q2ZuVGFza0RlZmluaXRpb24uTW91bnRQb2ludFByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBuYW1lIG9mIGEgY29udGFpbmVyLiBJZiB5b3UncmUgbGlua2luZyBtdWx0aXBsZSBjb250YWluZXJzIHRvZ2V0aGVyIGluIGEgdGFzayBkZWZpbml0aW9uLCB0aGUgYG5hbWVgIG9mIG9uZSBjb250YWluZXIgY2FuIGJlIGVudGVyZWQgaW4gdGhlIGBsaW5rc2Agb2YgYW5vdGhlciBjb250YWluZXIgdG8gY29ubmVjdCB0aGUgY29udGFpbmVycy4gVXAgdG8gMjU1IGxldHRlcnMgKHVwcGVyY2FzZSBhbmQgbG93ZXJjYXNlKSwgbnVtYmVycywgdW5kZXJzY29yZXMsIGFuZCBoeXBoZW5zIGFyZSBhbGxvd2VkLiBUaGlzIHBhcmFtZXRlciBtYXBzIHRvIGBuYW1lYCBpbiB0aGUgW0NyZWF0ZSBhIGNvbnRhaW5lcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvI29wZXJhdGlvbi9Db250YWluZXJDcmVhdGUpIHNlY3Rpb24gb2YgdGhlIFtEb2NrZXIgUmVtb3RlIEFQSV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvKSBhbmQgdGhlIGAtLW5hbWVgIG9wdGlvbiB0byBbZG9ja2VyIHJ1bl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9yZWZlcmVuY2UvcnVuLyNzZWN1cml0eS1jb25maWd1cmF0aW9uKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24tbmFtZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGxpc3Qgb2YgcG9ydCBtYXBwaW5ncyBmb3IgdGhlIGNvbnRhaW5lci4gUG9ydCBtYXBwaW5ncyBhbGxvdyBjb250YWluZXJzIHRvIGFjY2VzcyBwb3J0cyBvbiB0aGUgaG9zdCBjb250YWluZXIgaW5zdGFuY2UgdG8gc2VuZCBvciByZWNlaXZlIHRyYWZmaWMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEZvciB0YXNrIGRlZmluaXRpb25zIHRoYXQgdXNlIHRoZSBgYXdzdnBjYCBuZXR3b3JrIG1vZGUsIHlvdSBzaG91bGQgb25seSBzcGVjaWZ5IHRoZSBgY29udGFpbmVyUG9ydGAgLiBUaGUgYGhvc3RQb3J0YCBjYW4gYmUgbGVmdCBibGFuayBvciBpdCBtdXN0IGJlIHRoZSBzYW1lIHZhbHVlIGFzIHRoZSBgY29udGFpbmVyUG9ydGAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBQb3J0IG1hcHBpbmdzIG9uIFdpbmRvd3MgdXNlIHRoZSBgTmV0TkFUYCBnYXRld2F5IGFkZHJlc3MgcmF0aGVyIHRoYW4gYGxvY2FsaG9zdGAgLiBUaGVyZSBpcyBubyBsb29wYmFjayBmb3IgcG9ydCBtYXBwaW5ncyBvbiBXaW5kb3dzLCBzbyB5b3UgY2Fubm90IGFjY2VzcyBhIGNvbnRhaW5lcidzIG1hcHBlZCBwb3J0IGZyb20gdGhlIGhvc3QgaXRzZWxmLlxuICAgICAgICAgKlxuICAgICAgICAgKiBUaGlzIHBhcmFtZXRlciBtYXBzIHRvIGBQb3J0QmluZGluZ3NgIGluIHRoZSBbQ3JlYXRlIGEgY29udGFpbmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8jb3BlcmF0aW9uL0NvbnRhaW5lckNyZWF0ZSkgc2VjdGlvbiBvZiB0aGUgW0RvY2tlciBSZW1vdGUgQVBJXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8pIGFuZCB0aGUgYC0tcHVibGlzaGAgb3B0aW9uIHRvIFtkb2NrZXIgcnVuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vKSAuIElmIHRoZSBuZXR3b3JrIG1vZGUgb2YgYSB0YXNrIGRlZmluaXRpb24gaXMgc2V0IHRvIGBub25lYCAsIHRoZW4geW91IGNhbid0IHNwZWNpZnkgcG9ydCBtYXBwaW5ncy4gSWYgdGhlIG5ldHdvcmsgbW9kZSBvZiBhIHRhc2sgZGVmaW5pdGlvbiBpcyBzZXQgdG8gYGhvc3RgICwgdGhlbiBob3N0IHBvcnRzIG11c3QgZWl0aGVyIGJlIHVuZGVmaW5lZCBvciB0aGV5IG11c3QgbWF0Y2ggdGhlIGNvbnRhaW5lciBwb3J0IGluIHRoZSBwb3J0IG1hcHBpbmcuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gQWZ0ZXIgYSB0YXNrIHJlYWNoZXMgdGhlIGBSVU5OSU5HYCBzdGF0dXMsIG1hbnVhbCBhbmQgYXV0b21hdGljIGhvc3QgYW5kIGNvbnRhaW5lciBwb3J0IGFzc2lnbm1lbnRzIGFyZSB2aXNpYmxlIGluIHRoZSAqTmV0d29yayBCaW5kaW5ncyogc2VjdGlvbiBvZiBhIGNvbnRhaW5lciBkZXNjcmlwdGlvbiBmb3IgYSBzZWxlY3RlZCB0YXNrIGluIHRoZSBBbWF6b24gRUNTIGNvbnNvbGUuIFRoZSBhc3NpZ25tZW50cyBhcmUgYWxzbyB2aXNpYmxlIGluIHRoZSBgbmV0d29ya0JpbmRpbmdzYCBzZWN0aW9uIFtEZXNjcmliZVRhc2tzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlVGFza3MuaHRtbCkgcmVzcG9uc2VzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLXBvcnRtYXBwaW5nc1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcG9ydE1hcHBpbmdzPzogQXJyYXk8Q2ZuVGFza0RlZmluaXRpb24uUG9ydE1hcHBpbmdQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXaGVuIHRoaXMgcGFyYW1ldGVyIGlzIHRydWUsIHRoZSBjb250YWluZXIgaXMgZ2l2ZW4gZWxldmF0ZWQgcHJpdmlsZWdlcyBvbiB0aGUgaG9zdCBjb250YWluZXIgaW5zdGFuY2UgKHNpbWlsYXIgdG8gdGhlIGByb290YCB1c2VyKS4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgUHJpdmlsZWdlZGAgaW4gdGhlIFtDcmVhdGUgYSBjb250YWluZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LyNvcGVyYXRpb24vQ29udGFpbmVyQ3JlYXRlKSBzZWN0aW9uIG9mIHRoZSBbRG9ja2VyIFJlbW90ZSBBUEldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LykgYW5kIHRoZSBgLS1wcml2aWxlZ2VkYCBvcHRpb24gdG8gW2RvY2tlciBydW5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jc2VjdXJpdHktY29uZmlndXJhdGlvbikgLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFRoaXMgcGFyYW1ldGVyIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIFdpbmRvd3MgY29udGFpbmVycyBvciB0YXNrcyBydW4gb24gQVdTIEZhcmdhdGUgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLXByaXZpbGVnZWRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHByaXZpbGVnZWQ/OiBib29sZWFuIHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogV2hlbiB0aGlzIHBhcmFtZXRlciBpcyBgdHJ1ZWAgLCBhIFRUWSBpcyBhbGxvY2F0ZWQuIFRoaXMgcGFyYW1ldGVyIG1hcHMgdG8gYFR0eWAgaW4gdGhlIFtDcmVhdGUgYSBjb250YWluZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LyNvcGVyYXRpb24vQ29udGFpbmVyQ3JlYXRlKSBzZWN0aW9uIG9mIHRoZSBbRG9ja2VyIFJlbW90ZSBBUEldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LykgYW5kIHRoZSBgLS10dHlgIG9wdGlvbiB0byBbZG9ja2VyIHJ1bl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9yZWZlcmVuY2UvcnVuLyNzZWN1cml0eS1jb25maWd1cmF0aW9uKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24tcHNldWRvdGVybWluYWxcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHBzZXVkb1Rlcm1pbmFsPzogYm9vbGVhbiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZW4gdGhpcyBwYXJhbWV0ZXIgaXMgdHJ1ZSwgdGhlIGNvbnRhaW5lciBpcyBnaXZlbiByZWFkLW9ubHkgYWNjZXNzIHRvIGl0cyByb290IGZpbGUgc3lzdGVtLiBUaGlzIHBhcmFtZXRlciBtYXBzIHRvIGBSZWFkb25seVJvb3Rmc2AgaW4gdGhlIFtDcmVhdGUgYSBjb250YWluZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LyNvcGVyYXRpb24vQ29udGFpbmVyQ3JlYXRlKSBzZWN0aW9uIG9mIHRoZSBbRG9ja2VyIFJlbW90ZSBBUEldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LykgYW5kIHRoZSBgLS1yZWFkLW9ubHlgIG9wdGlvbiB0byBbZG9ja2VyIHJ1bl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9yZWZlcmVuY2UvcnVuLyNzZWN1cml0eS1jb25maWd1cmF0aW9uKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gVGhpcyBwYXJhbWV0ZXIgaXMgbm90IHN1cHBvcnRlZCBmb3IgV2luZG93cyBjb250YWluZXJzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLXJlYWRvbmx5cm9vdGZpbGVzeXN0ZW1cbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHJlYWRvbmx5Um9vdEZpbGVzeXN0ZW0/OiBib29sZWFuIHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHByaXZhdGUgcmVwb3NpdG9yeSBhdXRoZW50aWNhdGlvbiBjcmVkZW50aWFscyB0byB1c2UuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24tcmVwb3NpdG9yeWNyZWRlbnRpYWxzXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSByZXBvc2l0b3J5Q3JlZGVudGlhbHM/OiBDZm5UYXNrRGVmaW5pdGlvbi5SZXBvc2l0b3J5Q3JlZGVudGlhbHNQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB0eXBlIGFuZCBhbW91bnQgb2YgYSByZXNvdXJjZSB0byBhc3NpZ24gdG8gYSBjb250YWluZXIuIFRoZSBvbmx5IHN1cHBvcnRlZCByZXNvdXJjZSBpcyBhIEdQVS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi1yZXNvdXJjZXJlcXVpcmVtZW50c1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcmVzb3VyY2VSZXF1aXJlbWVudHM/OiBBcnJheTxDZm5UYXNrRGVmaW5pdGlvbi5SZXNvdXJjZVJlcXVpcmVtZW50UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHNlY3JldHMgdG8gcGFzcyB0byB0aGUgY29udGFpbmVyLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtTcGVjaWZ5aW5nIFNlbnNpdGl2ZSBEYXRhXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zcGVjaWZ5aW5nLXNlbnNpdGl2ZS1kYXRhLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24tc2VjcmV0c1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgc2VjcmV0cz86IEFycmF5PENmblRhc2tEZWZpbml0aW9uLlNlY3JldFByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRpbWUgZHVyYXRpb24gKGluIHNlY29uZHMpIHRvIHdhaXQgYmVmb3JlIGdpdmluZyB1cCBvbiByZXNvbHZpbmcgZGVwZW5kZW5jaWVzIGZvciBhIGNvbnRhaW5lci4gRm9yIGV4YW1wbGUsIHlvdSBzcGVjaWZ5IHR3byBjb250YWluZXJzIGluIGEgdGFzayBkZWZpbml0aW9uIHdpdGggY29udGFpbmVyQSBoYXZpbmcgYSBkZXBlbmRlbmN5IG9uIGNvbnRhaW5lckIgcmVhY2hpbmcgYSBgQ09NUExFVEVgICwgYFNVQ0NFU1NgICwgb3IgYEhFQUxUSFlgIHN0YXR1cy4gSWYgYSBgc3RhcnRUaW1lb3V0YCB2YWx1ZSBpcyBzcGVjaWZpZWQgZm9yIGNvbnRhaW5lckIgYW5kIGl0IGRvZXNuJ3QgcmVhY2ggdGhlIGRlc2lyZWQgc3RhdHVzIHdpdGhpbiB0aGF0IHRpbWUgdGhlbiBjb250YWluZXJBIGdpdmVzIHVwIGFuZCBub3Qgc3RhcnQuIFRoaXMgcmVzdWx0cyBpbiB0aGUgdGFzayB0cmFuc2l0aW9uaW5nIHRvIGEgYFNUT1BQRURgIHN0YXRlLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFdoZW4gdGhlIGBFQ1NfQ09OVEFJTkVSX1NUQVJUX1RJTUVPVVRgIGNvbnRhaW5lciBhZ2VudCBjb25maWd1cmF0aW9uIHZhcmlhYmxlIGlzIHVzZWQsIGl0J3MgZW5mb3JjZWQgaW5kZXBlbmRlbnRseSBmcm9tIHRoaXMgc3RhcnQgdGltZW91dCB2YWx1ZS5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIHRhc2tzIHVzaW5nIHRoZSBGYXJnYXRlIGxhdW5jaCB0eXBlLCB0aGUgdGFzayBvciBzZXJ2aWNlIHJlcXVpcmVzIHRoZSBmb2xsb3dpbmcgcGxhdGZvcm1zOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIExpbnV4IHBsYXRmb3JtIHZlcnNpb24gYDEuMy4wYCBvciBsYXRlci5cbiAgICAgICAgICogLSBXaW5kb3dzIHBsYXRmb3JtIHZlcnNpb24gYDEuMC4wYCBvciBsYXRlci5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIHRhc2tzIHVzaW5nIHRoZSBFQzIgbGF1bmNoIHR5cGUsIHlvdXIgY29udGFpbmVyIGluc3RhbmNlcyByZXF1aXJlIGF0IGxlYXN0IHZlcnNpb24gYDEuMjYuMGAgb2YgdGhlIGNvbnRhaW5lciBhZ2VudCB0byB1c2UgYSBjb250YWluZXIgc3RhcnQgdGltZW91dCB2YWx1ZS4gSG93ZXZlciwgd2UgcmVjb21tZW5kIHVzaW5nIHRoZSBsYXRlc3QgY29udGFpbmVyIGFnZW50IHZlcnNpb24uIEZvciBpbmZvcm1hdGlvbiBhYm91dCBjaGVja2luZyB5b3VyIGFnZW50IHZlcnNpb24gYW5kIHVwZGF0aW5nIHRvIHRoZSBsYXRlc3QgdmVyc2lvbiwgc2VlIFtVcGRhdGluZyB0aGUgQW1hem9uIEVDUyBDb250YWluZXIgQWdlbnRdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2Vjcy1hZ2VudC11cGRhdGUuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC4gSWYgeW91J3JlIHVzaW5nIGFuIEFtYXpvbiBFQ1Mtb3B0aW1pemVkIExpbnV4IEFNSSwgeW91ciBpbnN0YW5jZSBuZWVkcyBhdCBsZWFzdCB2ZXJzaW9uIGAxLjI2LjAtMWAgb2YgdGhlIGBlY3MtaW5pdGAgcGFja2FnZS4gSWYgeW91ciBjb250YWluZXIgaW5zdGFuY2VzIGFyZSBsYXVuY2hlZCBmcm9tIHZlcnNpb24gYDIwMTkwMzAxYCBvciBsYXRlciwgdGhlbiB0aGV5IGNvbnRhaW4gdGhlIHJlcXVpcmVkIHZlcnNpb25zIG9mIHRoZSBjb250YWluZXIgYWdlbnQgYW5kIGBlY3MtaW5pdGAgLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBbWF6b24gRUNTLW9wdGltaXplZCBMaW51eCBBTUldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2Vjcy1vcHRpbWl6ZWRfQU1JLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWNvbnRhaW5lcmRlZmluaXRpb24tc3RhcnR0aW1lb3V0XG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBzdGFydFRpbWVvdXQ/OiBudW1iZXI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaW1lIGR1cmF0aW9uIChpbiBzZWNvbmRzKSB0byB3YWl0IGJlZm9yZSB0aGUgY29udGFpbmVyIGlzIGZvcmNlZnVsbHkga2lsbGVkIGlmIGl0IGRvZXNuJ3QgZXhpdCBub3JtYWxseSBvbiBpdHMgb3duLlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgdGFza3MgdXNpbmcgdGhlIEZhcmdhdGUgbGF1bmNoIHR5cGUsIHRoZSB0YXNrIG9yIHNlcnZpY2UgcmVxdWlyZXMgdGhlIGZvbGxvd2luZyBwbGF0Zm9ybXM6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gTGludXggcGxhdGZvcm0gdmVyc2lvbiBgMS4zLjBgIG9yIGxhdGVyLlxuICAgICAgICAgKiAtIFdpbmRvd3MgcGxhdGZvcm0gdmVyc2lvbiBgMS4wLjBgIG9yIGxhdGVyLlxuICAgICAgICAgKlxuICAgICAgICAgKiBUaGUgbWF4IHN0b3AgdGltZW91dCB2YWx1ZSBpcyAxMjAgc2Vjb25kcyBhbmQgaWYgdGhlIHBhcmFtZXRlciBpcyBub3Qgc3BlY2lmaWVkLCB0aGUgZGVmYXVsdCB2YWx1ZSBvZiAzMCBzZWNvbmRzIGlzIHVzZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEZvciB0YXNrcyB0aGF0IHVzZSB0aGUgRUMyIGxhdW5jaCB0eXBlLCBpZiB0aGUgYHN0b3BUaW1lb3V0YCBwYXJhbWV0ZXIgaXNuJ3Qgc3BlY2lmaWVkLCB0aGUgdmFsdWUgc2V0IGZvciB0aGUgQW1hem9uIEVDUyBjb250YWluZXIgYWdlbnQgY29uZmlndXJhdGlvbiB2YXJpYWJsZSBgRUNTX0NPTlRBSU5FUl9TVE9QX1RJTUVPVVRgIGlzIHVzZWQuIElmIG5laXRoZXIgdGhlIGBzdG9wVGltZW91dGAgcGFyYW1ldGVyIG9yIHRoZSBgRUNTX0NPTlRBSU5FUl9TVE9QX1RJTUVPVVRgIGFnZW50IGNvbmZpZ3VyYXRpb24gdmFyaWFibGUgYXJlIHNldCwgdGhlbiB0aGUgZGVmYXVsdCB2YWx1ZXMgb2YgMzAgc2Vjb25kcyBmb3IgTGludXggY29udGFpbmVycyBhbmQgMzAgc2Vjb25kcyBvbiBXaW5kb3dzIGNvbnRhaW5lcnMgYXJlIHVzZWQuIFlvdXIgY29udGFpbmVyIGluc3RhbmNlcyByZXF1aXJlIGF0IGxlYXN0IHZlcnNpb24gMS4yNi4wIG9mIHRoZSBjb250YWluZXIgYWdlbnQgdG8gdXNlIGEgY29udGFpbmVyIHN0b3AgdGltZW91dCB2YWx1ZS4gSG93ZXZlciwgd2UgcmVjb21tZW5kIHVzaW5nIHRoZSBsYXRlc3QgY29udGFpbmVyIGFnZW50IHZlcnNpb24uIEZvciBpbmZvcm1hdGlvbiBhYm91dCBjaGVja2luZyB5b3VyIGFnZW50IHZlcnNpb24gYW5kIHVwZGF0aW5nIHRvIHRoZSBsYXRlc3QgdmVyc2lvbiwgc2VlIFtVcGRhdGluZyB0aGUgQW1hem9uIEVDUyBDb250YWluZXIgQWdlbnRdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2Vjcy1hZ2VudC11cGRhdGUuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC4gSWYgeW91J3JlIHVzaW5nIGFuIEFtYXpvbiBFQ1Mtb3B0aW1pemVkIExpbnV4IEFNSSwgeW91ciBpbnN0YW5jZSBuZWVkcyBhdCBsZWFzdCB2ZXJzaW9uIDEuMjYuMC0xIG9mIHRoZSBgZWNzLWluaXRgIHBhY2thZ2UuIElmIHlvdXIgY29udGFpbmVyIGluc3RhbmNlcyBhcmUgbGF1bmNoZWQgZnJvbSB2ZXJzaW9uIGAyMDE5MDMwMWAgb3IgbGF0ZXIsIHRoZW4gdGhleSBjb250YWluIHRoZSByZXF1aXJlZCB2ZXJzaW9ucyBvZiB0aGUgY29udGFpbmVyIGFnZW50IGFuZCBgZWNzLWluaXRgIC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQW1hem9uIEVDUy1vcHRpbWl6ZWQgTGludXggQU1JXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9lY3Mtb3B0aW1pemVkX0FNSS5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLXN0b3B0aW1lb3V0XG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBzdG9wVGltZW91dD86IG51bWJlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgbGlzdCBvZiBuYW1lc3BhY2VkIGtlcm5lbCBwYXJhbWV0ZXJzIHRvIHNldCBpbiB0aGUgY29udGFpbmVyLiBUaGlzIHBhcmFtZXRlciBtYXBzIHRvIGBTeXNjdGxzYCBpbiB0aGUgW0NyZWF0ZSBhIGNvbnRhaW5lcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvI29wZXJhdGlvbi9Db250YWluZXJDcmVhdGUpIHNlY3Rpb24gb2YgdGhlIFtEb2NrZXIgUmVtb3RlIEFQSV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvKSBhbmQgdGhlIGAtLXN5c2N0bGAgb3B0aW9uIHRvIFtkb2NrZXIgcnVuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vI3NlY3VyaXR5LWNvbmZpZ3VyYXRpb24pIC5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBXZSBkb24ndCByZWNvbW1lbmRlZCB0aGF0IHlvdSBzcGVjaWZ5IG5ldHdvcmstcmVsYXRlZCBgc3lzdGVtQ29udHJvbHNgIHBhcmFtZXRlcnMgZm9yIG11bHRpcGxlIGNvbnRhaW5lcnMgaW4gYSBzaW5nbGUgdGFzayB0aGF0IGFsc28gdXNlcyBlaXRoZXIgdGhlIGBhd3N2cGNgIG9yIGBob3N0YCBuZXR3b3JrIG1vZGVzLiBGb3IgdGFza3MgdGhhdCB1c2UgdGhlIGBhd3N2cGNgIG5ldHdvcmsgbW9kZSwgdGhlIGNvbnRhaW5lciB0aGF0J3Mgc3RhcnRlZCBsYXN0IGRldGVybWluZXMgd2hpY2ggYHN5c3RlbUNvbnRyb2xzYCBwYXJhbWV0ZXJzIHRha2UgZWZmZWN0LiBGb3IgdGFza3MgdGhhdCB1c2UgdGhlIGBob3N0YCBuZXR3b3JrIG1vZGUsIGl0IGNoYW5nZXMgdGhlIGNvbnRhaW5lciBpbnN0YW5jZSdzIG5hbWVzcGFjZWQga2VybmVsIHBhcmFtZXRlcnMgYXMgd2VsbCBhcyB0aGUgY29udGFpbmVycy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi1zeXN0ZW1jb250cm9sc1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgc3lzdGVtQ29udHJvbHM/OiBBcnJheTxDZm5UYXNrRGVmaW5pdGlvbi5TeXN0ZW1Db250cm9sUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogQSBsaXN0IG9mIGB1bGltaXRzYCB0byBzZXQgaW4gdGhlIGNvbnRhaW5lci4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgVWxpbWl0c2AgaW4gdGhlIFtDcmVhdGUgYSBjb250YWluZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LyNvcGVyYXRpb24vQ29udGFpbmVyQ3JlYXRlKSBzZWN0aW9uIG9mIHRoZSBbRG9ja2VyIFJlbW90ZSBBUEldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LykgYW5kIHRoZSBgLS11bGltaXRgIG9wdGlvbiB0byBbZG9ja2VyIHJ1bl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9yZWZlcmVuY2UvcnVuLykgLiBWYWxpZCBuYW1pbmcgdmFsdWVzIGFyZSBkaXNwbGF5ZWQgaW4gdGhlIFtVbGltaXRdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVWxpbWl0Lmh0bWwpIGRhdGEgdHlwZS4gVGhpcyBwYXJhbWV0ZXIgcmVxdWlyZXMgdmVyc2lvbiAxLjE4IG9mIHRoZSBEb2NrZXIgUmVtb3RlIEFQSSBvciBncmVhdGVyIG9uIHlvdXIgY29udGFpbmVyIGluc3RhbmNlLiBUbyBjaGVjayB0aGUgRG9ja2VyIFJlbW90ZSBBUEkgdmVyc2lvbiBvbiB5b3VyIGNvbnRhaW5lciBpbnN0YW5jZSwgbG9nIGluIHRvIHlvdXIgY29udGFpbmVyIGluc3RhbmNlIGFuZCBydW4gdGhlIGZvbGxvd2luZyBjb21tYW5kOiBgc3VkbyBkb2NrZXIgdmVyc2lvbiAtLWZvcm1hdCAne3suU2VydmVyLkFQSVZlcnNpb259fSdgXG4gICAgICAgICAqXG4gICAgICAgICAqID4gVGhpcyBwYXJhbWV0ZXIgaXMgbm90IHN1cHBvcnRlZCBmb3IgV2luZG93cyBjb250YWluZXJzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLXVsaW1pdHNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHVsaW1pdHM/OiBBcnJheTxDZm5UYXNrRGVmaW5pdGlvbi5VbGltaXRQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdXNlciB0byB1c2UgaW5zaWRlIHRoZSBjb250YWluZXIuIFRoaXMgcGFyYW1ldGVyIG1hcHMgdG8gYFVzZXJgIGluIHRoZSBbQ3JlYXRlIGEgY29udGFpbmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8jb3BlcmF0aW9uL0NvbnRhaW5lckNyZWF0ZSkgc2VjdGlvbiBvZiB0aGUgW0RvY2tlciBSZW1vdGUgQVBJXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8pIGFuZCB0aGUgYC0tdXNlcmAgb3B0aW9uIHRvIFtkb2NrZXIgcnVuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vI3NlY3VyaXR5LWNvbmZpZ3VyYXRpb24pIC5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBXaGVuIHJ1bm5pbmcgdGFza3MgdXNpbmcgdGhlIGBob3N0YCBuZXR3b3JrIG1vZGUsIGRvbid0IHJ1biBjb250YWluZXJzIHVzaW5nIHRoZSByb290IHVzZXIgKFVJRCAwKS4gV2UgcmVjb21tZW5kIHVzaW5nIGEgbm9uLXJvb3QgdXNlciBmb3IgYmV0dGVyIHNlY3VyaXR5LlxuICAgICAgICAgKlxuICAgICAgICAgKiBZb3UgY2FuIHNwZWNpZnkgdGhlIGB1c2VyYCB1c2luZyB0aGUgZm9sbG93aW5nIGZvcm1hdHMuIElmIHNwZWNpZnlpbmcgYSBVSUQgb3IgR0lELCB5b3UgbXVzdCBzcGVjaWZ5IGl0IGFzIGEgcG9zaXRpdmUgaW50ZWdlci5cbiAgICAgICAgICpcbiAgICAgICAgICogLSBgdXNlcmBcbiAgICAgICAgICogLSBgdXNlcjpncm91cGBcbiAgICAgICAgICogLSBgdWlkYFxuICAgICAgICAgKiAtIGB1aWQ6Z2lkYFxuICAgICAgICAgKiAtIGB1c2VyOmdpZGBcbiAgICAgICAgICogLSBgdWlkOmdyb3VwYFxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFRoaXMgcGFyYW1ldGVyIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIFdpbmRvd3MgY29udGFpbmVycy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi11c2VyXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB1c2VyPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogRGF0YSB2b2x1bWVzIHRvIG1vdW50IGZyb20gYW5vdGhlciBjb250YWluZXIuIFRoaXMgcGFyYW1ldGVyIG1hcHMgdG8gYFZvbHVtZXNGcm9tYCBpbiB0aGUgW0NyZWF0ZSBhIGNvbnRhaW5lcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvI29wZXJhdGlvbi9Db250YWluZXJDcmVhdGUpIHNlY3Rpb24gb2YgdGhlIFtEb2NrZXIgUmVtb3RlIEFQSV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvKSBhbmQgdGhlIGAtLXZvbHVtZXMtZnJvbWAgb3B0aW9uIHRvIFtkb2NrZXIgcnVuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vI3NlY3VyaXR5LWNvbmZpZ3VyYXRpb24pIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVmaW5pdGlvbi12b2x1bWVzZnJvbVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgdm9sdW1lc0Zyb20/OiBBcnJheTxDZm5UYXNrRGVmaW5pdGlvbi5Wb2x1bWVGcm9tUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHdvcmtpbmcgZGlyZWN0b3J5IHRvIHJ1biBjb21tYW5kcyBpbnNpZGUgdGhlIGNvbnRhaW5lciBpbi4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgV29ya2luZ0RpcmAgaW4gdGhlIFtDcmVhdGUgYSBjb250YWluZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LyNvcGVyYXRpb24vQ29udGFpbmVyQ3JlYXRlKSBzZWN0aW9uIG9mIHRoZSBbRG9ja2VyIFJlbW90ZSBBUEldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LykgYW5kIHRoZSBgLS13b3JrZGlyYCBvcHRpb24gdG8gW2RvY2tlciBydW5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jc2VjdXJpdHktY29uZmlndXJhdGlvbikgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLXdvcmtpbmdkaXJlY3RvcnlcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHdvcmtpbmdEaXJlY3Rvcnk/OiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENvbnRhaW5lckRlZmluaXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ29udGFpbmVyRGVmaW5pdGlvblByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uX0NvbnRhaW5lckRlZmluaXRpb25Qcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvbW1hbmQnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLmNvbW1hbmQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NwdScsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5jcHUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2RlcGVuZHNPbicsIGNkay5saXN0VmFsaWRhdG9yKENmblRhc2tEZWZpbml0aW9uX0NvbnRhaW5lckRlcGVuZGVuY3lQcm9wZXJ0eVZhbGlkYXRvcikpKHByb3BlcnRpZXMuZGVwZW5kc09uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdkaXNhYmxlTmV0d29ya2luZycsIGNkay52YWxpZGF0ZUJvb2xlYW4pKHByb3BlcnRpZXMuZGlzYWJsZU5ldHdvcmtpbmcpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2Ruc1NlYXJjaERvbWFpbnMnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLmRuc1NlYXJjaERvbWFpbnMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2Ruc1NlcnZlcnMnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLmRuc1NlcnZlcnMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2RvY2tlckxhYmVscycsIGNkay5oYXNoVmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMuZG9ja2VyTGFiZWxzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdkb2NrZXJTZWN1cml0eU9wdGlvbnMnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLmRvY2tlclNlY3VyaXR5T3B0aW9ucykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZW50cnlQb2ludCcsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMuZW50cnlQb2ludCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZW52aXJvbm1lbnQnLCBjZGsubGlzdFZhbGlkYXRvcihDZm5UYXNrRGVmaW5pdGlvbl9LZXlWYWx1ZVBhaXJQcm9wZXJ0eVZhbGlkYXRvcikpKHByb3BlcnRpZXMuZW52aXJvbm1lbnQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2Vudmlyb25tZW50RmlsZXMnLCBjZGsubGlzdFZhbGlkYXRvcihDZm5UYXNrRGVmaW5pdGlvbl9FbnZpcm9ubWVudEZpbGVQcm9wZXJ0eVZhbGlkYXRvcikpKHByb3BlcnRpZXMuZW52aXJvbm1lbnRGaWxlcykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZXNzZW50aWFsJywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5lc3NlbnRpYWwpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2V4dHJhSG9zdHMnLCBjZGsubGlzdFZhbGlkYXRvcihDZm5UYXNrRGVmaW5pdGlvbl9Ib3N0RW50cnlQcm9wZXJ0eVZhbGlkYXRvcikpKHByb3BlcnRpZXMuZXh0cmFIb3N0cykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZmlyZWxlbnNDb25maWd1cmF0aW9uJywgQ2ZuVGFza0RlZmluaXRpb25fRmlyZWxlbnNDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IpKHByb3BlcnRpZXMuZmlyZWxlbnNDb25maWd1cmF0aW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdoZWFsdGhDaGVjaycsIENmblRhc2tEZWZpbml0aW9uX0hlYWx0aENoZWNrUHJvcGVydHlWYWxpZGF0b3IpKHByb3BlcnRpZXMuaGVhbHRoQ2hlY2spKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hvc3RuYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmhvc3RuYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdpbWFnZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5pbWFnZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaW1hZ2UnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuaW1hZ2UpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2ludGVyYWN0aXZlJywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5pbnRlcmFjdGl2ZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbGlua3MnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLmxpbmtzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdsaW51eFBhcmFtZXRlcnMnLCBDZm5UYXNrRGVmaW5pdGlvbl9MaW51eFBhcmFtZXRlcnNQcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5saW51eFBhcmFtZXRlcnMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2xvZ0NvbmZpZ3VyYXRpb24nLCBDZm5UYXNrRGVmaW5pdGlvbl9Mb2dDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IpKHByb3BlcnRpZXMubG9nQ29uZmlndXJhdGlvbikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbWVtb3J5JywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLm1lbW9yeSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbWVtb3J5UmVzZXJ2YXRpb24nLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMubWVtb3J5UmVzZXJ2YXRpb24pKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ21vdW50UG9pbnRzJywgY2RrLmxpc3RWYWxpZGF0b3IoQ2ZuVGFza0RlZmluaXRpb25fTW91bnRQb2ludFByb3BlcnR5VmFsaWRhdG9yKSkocHJvcGVydGllcy5tb3VudFBvaW50cykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5uYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCduYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLm5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvcnRNYXBwaW5ncycsIGNkay5saXN0VmFsaWRhdG9yKENmblRhc2tEZWZpbml0aW9uX1BvcnRNYXBwaW5nUHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLnBvcnRNYXBwaW5ncykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncHJpdmlsZWdlZCcsIGNkay52YWxpZGF0ZUJvb2xlYW4pKHByb3BlcnRpZXMucHJpdmlsZWdlZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncHNldWRvVGVybWluYWwnLCBjZGsudmFsaWRhdGVCb29sZWFuKShwcm9wZXJ0aWVzLnBzZXVkb1Rlcm1pbmFsKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyZWFkb25seVJvb3RGaWxlc3lzdGVtJywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5yZWFkb25seVJvb3RGaWxlc3lzdGVtKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyZXBvc2l0b3J5Q3JlZGVudGlhbHMnLCBDZm5UYXNrRGVmaW5pdGlvbl9SZXBvc2l0b3J5Q3JlZGVudGlhbHNQcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5yZXBvc2l0b3J5Q3JlZGVudGlhbHMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3Jlc291cmNlUmVxdWlyZW1lbnRzJywgY2RrLmxpc3RWYWxpZGF0b3IoQ2ZuVGFza0RlZmluaXRpb25fUmVzb3VyY2VSZXF1aXJlbWVudFByb3BlcnR5VmFsaWRhdG9yKSkocHJvcGVydGllcy5yZXNvdXJjZVJlcXVpcmVtZW50cykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc2VjcmV0cycsIGNkay5saXN0VmFsaWRhdG9yKENmblRhc2tEZWZpbml0aW9uX1NlY3JldFByb3BlcnR5VmFsaWRhdG9yKSkocHJvcGVydGllcy5zZWNyZXRzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzdGFydFRpbWVvdXQnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMuc3RhcnRUaW1lb3V0KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzdG9wVGltZW91dCcsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5zdG9wVGltZW91dCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc3lzdGVtQ29udHJvbHMnLCBjZGsubGlzdFZhbGlkYXRvcihDZm5UYXNrRGVmaW5pdGlvbl9TeXN0ZW1Db250cm9sUHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLnN5c3RlbUNvbnRyb2xzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd1bGltaXRzJywgY2RrLmxpc3RWYWxpZGF0b3IoQ2ZuVGFza0RlZmluaXRpb25fVWxpbWl0UHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLnVsaW1pdHMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3VzZXInLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMudXNlcikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndm9sdW1lc0Zyb20nLCBjZGsubGlzdFZhbGlkYXRvcihDZm5UYXNrRGVmaW5pdGlvbl9Wb2x1bWVGcm9tUHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLnZvbHVtZXNGcm9tKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd3b3JraW5nRGlyZWN0b3J5JywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLndvcmtpbmdEaXJlY3RvcnkpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ29udGFpbmVyRGVmaW5pdGlvblByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLkNvbnRhaW5lckRlZmluaXRpb25gIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENvbnRhaW5lckRlZmluaXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5Db250YWluZXJEZWZpbml0aW9uYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblRhc2tEZWZpbml0aW9uQ29udGFpbmVyRGVmaW5pdGlvblByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5UYXNrRGVmaW5pdGlvbl9Db250YWluZXJEZWZpbml0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIENvbW1hbmQ6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLmNvbW1hbmQpLFxuICAgICAgICBDcHU6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY3B1KSxcbiAgICAgICAgRGVwZW5kc09uOiBjZGsubGlzdE1hcHBlcihjZm5UYXNrRGVmaW5pdGlvbkNvbnRhaW5lckRlcGVuZGVuY3lQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuZGVwZW5kc09uKSxcbiAgICAgICAgRGlzYWJsZU5ldHdvcmtpbmc6IGNkay5ib29sZWFuVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmRpc2FibGVOZXR3b3JraW5nKSxcbiAgICAgICAgRG5zU2VhcmNoRG9tYWluczogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuZG5zU2VhcmNoRG9tYWlucyksXG4gICAgICAgIERuc1NlcnZlcnM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLmRuc1NlcnZlcnMpLFxuICAgICAgICBEb2NrZXJMYWJlbHM6IGNkay5oYXNoTWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLmRvY2tlckxhYmVscyksXG4gICAgICAgIERvY2tlclNlY3VyaXR5T3B0aW9uczogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuZG9ja2VyU2VjdXJpdHlPcHRpb25zKSxcbiAgICAgICAgRW50cnlQb2ludDogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuZW50cnlQb2ludCksXG4gICAgICAgIEVudmlyb25tZW50OiBjZGsubGlzdE1hcHBlcihjZm5UYXNrRGVmaW5pdGlvbktleVZhbHVlUGFpclByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5lbnZpcm9ubWVudCksXG4gICAgICAgIEVudmlyb25tZW50RmlsZXM6IGNkay5saXN0TWFwcGVyKGNmblRhc2tEZWZpbml0aW9uRW52aXJvbm1lbnRGaWxlUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLmVudmlyb25tZW50RmlsZXMpLFxuICAgICAgICBFc3NlbnRpYWw6IGNkay5ib29sZWFuVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmVzc2VudGlhbCksXG4gICAgICAgIEV4dHJhSG9zdHM6IGNkay5saXN0TWFwcGVyKGNmblRhc2tEZWZpbml0aW9uSG9zdEVudHJ5UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLmV4dHJhSG9zdHMpLFxuICAgICAgICBGaXJlbGVuc0NvbmZpZ3VyYXRpb246IGNmblRhc2tEZWZpbml0aW9uRmlyZWxlbnNDb25maWd1cmF0aW9uUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZmlyZWxlbnNDb25maWd1cmF0aW9uKSxcbiAgICAgICAgSGVhbHRoQ2hlY2s6IGNmblRhc2tEZWZpbml0aW9uSGVhbHRoQ2hlY2tQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5oZWFsdGhDaGVjayksXG4gICAgICAgIEhvc3RuYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmhvc3RuYW1lKSxcbiAgICAgICAgSW1hZ2U6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaW1hZ2UpLFxuICAgICAgICBJbnRlcmFjdGl2ZTogY2RrLmJvb2xlYW5Ub0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaW50ZXJhY3RpdmUpLFxuICAgICAgICBMaW5rczogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMubGlua3MpLFxuICAgICAgICBMaW51eFBhcmFtZXRlcnM6IGNmblRhc2tEZWZpbml0aW9uTGludXhQYXJhbWV0ZXJzUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubGludXhQYXJhbWV0ZXJzKSxcbiAgICAgICAgTG9nQ29uZmlndXJhdGlvbjogY2ZuVGFza0RlZmluaXRpb25Mb2dDb25maWd1cmF0aW9uUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubG9nQ29uZmlndXJhdGlvbiksXG4gICAgICAgIE1lbW9yeTogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5tZW1vcnkpLFxuICAgICAgICBNZW1vcnlSZXNlcnZhdGlvbjogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5tZW1vcnlSZXNlcnZhdGlvbiksXG4gICAgICAgIE1vdW50UG9pbnRzOiBjZGsubGlzdE1hcHBlcihjZm5UYXNrRGVmaW5pdGlvbk1vdW50UG9pbnRQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMubW91bnRQb2ludHMpLFxuICAgICAgICBOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm5hbWUpLFxuICAgICAgICBQb3J0TWFwcGluZ3M6IGNkay5saXN0TWFwcGVyKGNmblRhc2tEZWZpbml0aW9uUG9ydE1hcHBpbmdQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMucG9ydE1hcHBpbmdzKSxcbiAgICAgICAgUHJpdmlsZWdlZDogY2RrLmJvb2xlYW5Ub0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucHJpdmlsZWdlZCksXG4gICAgICAgIFBzZXVkb1Rlcm1pbmFsOiBjZGsuYm9vbGVhblRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wc2V1ZG9UZXJtaW5hbCksXG4gICAgICAgIFJlYWRvbmx5Um9vdEZpbGVzeXN0ZW06IGNkay5ib29sZWFuVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnJlYWRvbmx5Um9vdEZpbGVzeXN0ZW0pLFxuICAgICAgICBSZXBvc2l0b3J5Q3JlZGVudGlhbHM6IGNmblRhc2tEZWZpbml0aW9uUmVwb3NpdG9yeUNyZWRlbnRpYWxzUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucmVwb3NpdG9yeUNyZWRlbnRpYWxzKSxcbiAgICAgICAgUmVzb3VyY2VSZXF1aXJlbWVudHM6IGNkay5saXN0TWFwcGVyKGNmblRhc2tEZWZpbml0aW9uUmVzb3VyY2VSZXF1aXJlbWVudFByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5yZXNvdXJjZVJlcXVpcmVtZW50cyksXG4gICAgICAgIFNlY3JldHM6IGNkay5saXN0TWFwcGVyKGNmblRhc2tEZWZpbml0aW9uU2VjcmV0UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnNlY3JldHMpLFxuICAgICAgICBTdGFydFRpbWVvdXQ6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuc3RhcnRUaW1lb3V0KSxcbiAgICAgICAgU3RvcFRpbWVvdXQ6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuc3RvcFRpbWVvdXQpLFxuICAgICAgICBTeXN0ZW1Db250cm9sczogY2RrLmxpc3RNYXBwZXIoY2ZuVGFza0RlZmluaXRpb25TeXN0ZW1Db250cm9sUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnN5c3RlbUNvbnRyb2xzKSxcbiAgICAgICAgVWxpbWl0czogY2RrLmxpc3RNYXBwZXIoY2ZuVGFza0RlZmluaXRpb25VbGltaXRQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMudWxpbWl0cyksXG4gICAgICAgIFVzZXI6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMudXNlciksXG4gICAgICAgIFZvbHVtZXNGcm9tOiBjZGsubGlzdE1hcHBlcihjZm5UYXNrRGVmaW5pdGlvblZvbHVtZUZyb21Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMudm9sdW1lc0Zyb20pLFxuICAgICAgICBXb3JraW5nRGlyZWN0b3J5OiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLndvcmtpbmdEaXJlY3RvcnkpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbkNvbnRhaW5lckRlZmluaXRpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblRhc2tEZWZpbml0aW9uLkNvbnRhaW5lckRlZmluaXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5UYXNrRGVmaW5pdGlvbi5Db250YWluZXJEZWZpbml0aW9uUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjb21tYW5kJywgJ0NvbW1hbmQnLCBwcm9wZXJ0aWVzLkNvbW1hbmQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5Db21tYW5kKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjcHUnLCAnQ3B1JywgcHJvcGVydGllcy5DcHUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuQ3B1KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdkZXBlbmRzT24nLCAnRGVwZW5kc09uJywgcHJvcGVydGllcy5EZXBlbmRzT24gIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoQ2ZuVGFza0RlZmluaXRpb25Db250YWluZXJEZXBlbmRlbmN5UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuRGVwZW5kc09uKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdkaXNhYmxlTmV0d29ya2luZycsICdEaXNhYmxlTmV0d29ya2luZycsIHByb3BlcnRpZXMuRGlzYWJsZU5ldHdvcmtpbmcgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Qm9vbGVhbihwcm9wZXJ0aWVzLkRpc2FibGVOZXR3b3JraW5nKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdkbnNTZWFyY2hEb21haW5zJywgJ0Ruc1NlYXJjaERvbWFpbnMnLCBwcm9wZXJ0aWVzLkRuc1NlYXJjaERvbWFpbnMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5EbnNTZWFyY2hEb21haW5zKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdkbnNTZXJ2ZXJzJywgJ0Ruc1NlcnZlcnMnLCBwcm9wZXJ0aWVzLkRuc1NlcnZlcnMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5EbnNTZXJ2ZXJzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdkb2NrZXJMYWJlbHMnLCAnRG9ja2VyTGFiZWxzJywgcHJvcGVydGllcy5Eb2NrZXJMYWJlbHMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TWFwKGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKShwcm9wZXJ0aWVzLkRvY2tlckxhYmVscykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZG9ja2VyU2VjdXJpdHlPcHRpb25zJywgJ0RvY2tlclNlY3VyaXR5T3B0aW9ucycsIHByb3BlcnRpZXMuRG9ja2VyU2VjdXJpdHlPcHRpb25zICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuRG9ja2VyU2VjdXJpdHlPcHRpb25zKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdlbnRyeVBvaW50JywgJ0VudHJ5UG9pbnQnLCBwcm9wZXJ0aWVzLkVudHJ5UG9pbnQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5FbnRyeVBvaW50KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdlbnZpcm9ubWVudCcsICdFbnZpcm9ubWVudCcsIHByb3BlcnRpZXMuRW52aXJvbm1lbnQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoQ2ZuVGFza0RlZmluaXRpb25LZXlWYWx1ZVBhaXJQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5FbnZpcm9ubWVudCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZW52aXJvbm1lbnRGaWxlcycsICdFbnZpcm9ubWVudEZpbGVzJywgcHJvcGVydGllcy5FbnZpcm9ubWVudEZpbGVzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KENmblRhc2tEZWZpbml0aW9uRW52aXJvbm1lbnRGaWxlUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuRW52aXJvbm1lbnRGaWxlcykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZXNzZW50aWFsJywgJ0Vzc2VudGlhbCcsIHByb3BlcnRpZXMuRXNzZW50aWFsICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5Fc3NlbnRpYWwpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2V4dHJhSG9zdHMnLCAnRXh0cmFIb3N0cycsIHByb3BlcnRpZXMuRXh0cmFIb3N0cyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5UYXNrRGVmaW5pdGlvbkhvc3RFbnRyeVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLkV4dHJhSG9zdHMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2ZpcmVsZW5zQ29uZmlndXJhdGlvbicsICdGaXJlbGVuc0NvbmZpZ3VyYXRpb24nLCBwcm9wZXJ0aWVzLkZpcmVsZW5zQ29uZmlndXJhdGlvbiAhPSBudWxsID8gQ2ZuVGFza0RlZmluaXRpb25GaXJlbGVuc0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLkZpcmVsZW5zQ29uZmlndXJhdGlvbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaGVhbHRoQ2hlY2snLCAnSGVhbHRoQ2hlY2snLCBwcm9wZXJ0aWVzLkhlYWx0aENoZWNrICE9IG51bGwgPyBDZm5UYXNrRGVmaW5pdGlvbkhlYWx0aENoZWNrUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5IZWFsdGhDaGVjaykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaG9zdG5hbWUnLCAnSG9zdG5hbWUnLCBwcm9wZXJ0aWVzLkhvc3RuYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkhvc3RuYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdpbWFnZScsICdJbWFnZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuSW1hZ2UpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2ludGVyYWN0aXZlJywgJ0ludGVyYWN0aXZlJywgcHJvcGVydGllcy5JbnRlcmFjdGl2ZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRCb29sZWFuKHByb3BlcnRpZXMuSW50ZXJhY3RpdmUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2xpbmtzJywgJ0xpbmtzJywgcHJvcGVydGllcy5MaW5rcyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmdBcnJheShwcm9wZXJ0aWVzLkxpbmtzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdsaW51eFBhcmFtZXRlcnMnLCAnTGludXhQYXJhbWV0ZXJzJywgcHJvcGVydGllcy5MaW51eFBhcmFtZXRlcnMgIT0gbnVsbCA/IENmblRhc2tEZWZpbml0aW9uTGludXhQYXJhbWV0ZXJzUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5MaW51eFBhcmFtZXRlcnMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2xvZ0NvbmZpZ3VyYXRpb24nLCAnTG9nQ29uZmlndXJhdGlvbicsIHByb3BlcnRpZXMuTG9nQ29uZmlndXJhdGlvbiAhPSBudWxsID8gQ2ZuVGFza0RlZmluaXRpb25Mb2dDb25maWd1cmF0aW9uUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5Mb2dDb25maWd1cmF0aW9uKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdtZW1vcnknLCAnTWVtb3J5JywgcHJvcGVydGllcy5NZW1vcnkgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuTWVtb3J5KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdtZW1vcnlSZXNlcnZhdGlvbicsICdNZW1vcnlSZXNlcnZhdGlvbicsIHByb3BlcnRpZXMuTWVtb3J5UmVzZXJ2YXRpb24gIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuTWVtb3J5UmVzZXJ2YXRpb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ21vdW50UG9pbnRzJywgJ01vdW50UG9pbnRzJywgcHJvcGVydGllcy5Nb3VudFBvaW50cyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5UYXNrRGVmaW5pdGlvbk1vdW50UG9pbnRQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5Nb3VudFBvaW50cykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbmFtZScsICdOYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5OYW1lKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwb3J0TWFwcGluZ3MnLCAnUG9ydE1hcHBpbmdzJywgcHJvcGVydGllcy5Qb3J0TWFwcGluZ3MgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoQ2ZuVGFza0RlZmluaXRpb25Qb3J0TWFwcGluZ1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLlBvcnRNYXBwaW5ncykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncHJpdmlsZWdlZCcsICdQcml2aWxlZ2VkJywgcHJvcGVydGllcy5Qcml2aWxlZ2VkICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5Qcml2aWxlZ2VkKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwc2V1ZG9UZXJtaW5hbCcsICdQc2V1ZG9UZXJtaW5hbCcsIHByb3BlcnRpZXMuUHNldWRvVGVybWluYWwgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Qm9vbGVhbihwcm9wZXJ0aWVzLlBzZXVkb1Rlcm1pbmFsKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdyZWFkb25seVJvb3RGaWxlc3lzdGVtJywgJ1JlYWRvbmx5Um9vdEZpbGVzeXN0ZW0nLCBwcm9wZXJ0aWVzLlJlYWRvbmx5Um9vdEZpbGVzeXN0ZW0gIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Qm9vbGVhbihwcm9wZXJ0aWVzLlJlYWRvbmx5Um9vdEZpbGVzeXN0ZW0pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3JlcG9zaXRvcnlDcmVkZW50aWFscycsICdSZXBvc2l0b3J5Q3JlZGVudGlhbHMnLCBwcm9wZXJ0aWVzLlJlcG9zaXRvcnlDcmVkZW50aWFscyAhPSBudWxsID8gQ2ZuVGFza0RlZmluaXRpb25SZXBvc2l0b3J5Q3JlZGVudGlhbHNQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLlJlcG9zaXRvcnlDcmVkZW50aWFscykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncmVzb3VyY2VSZXF1aXJlbWVudHMnLCAnUmVzb3VyY2VSZXF1aXJlbWVudHMnLCBwcm9wZXJ0aWVzLlJlc291cmNlUmVxdWlyZW1lbnRzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KENmblRhc2tEZWZpbml0aW9uUmVzb3VyY2VSZXF1aXJlbWVudFByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLlJlc291cmNlUmVxdWlyZW1lbnRzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzZWNyZXRzJywgJ1NlY3JldHMnLCBwcm9wZXJ0aWVzLlNlY3JldHMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoQ2ZuVGFza0RlZmluaXRpb25TZWNyZXRQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5TZWNyZXRzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzdGFydFRpbWVvdXQnLCAnU3RhcnRUaW1lb3V0JywgcHJvcGVydGllcy5TdGFydFRpbWVvdXQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuU3RhcnRUaW1lb3V0KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzdG9wVGltZW91dCcsICdTdG9wVGltZW91dCcsIHByb3BlcnRpZXMuU3RvcFRpbWVvdXQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuU3RvcFRpbWVvdXQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3N5c3RlbUNvbnRyb2xzJywgJ1N5c3RlbUNvbnRyb2xzJywgcHJvcGVydGllcy5TeXN0ZW1Db250cm9scyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5UYXNrRGVmaW5pdGlvblN5c3RlbUNvbnRyb2xQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5TeXN0ZW1Db250cm9scykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndWxpbWl0cycsICdVbGltaXRzJywgcHJvcGVydGllcy5VbGltaXRzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KENmblRhc2tEZWZpbml0aW9uVWxpbWl0UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuVWxpbWl0cykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndXNlcicsICdVc2VyJywgcHJvcGVydGllcy5Vc2VyICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlVzZXIpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3ZvbHVtZXNGcm9tJywgJ1ZvbHVtZXNGcm9tJywgcHJvcGVydGllcy5Wb2x1bWVzRnJvbSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5UYXNrRGVmaW5pdGlvblZvbHVtZUZyb21Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5Wb2x1bWVzRnJvbSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnd29ya2luZ0RpcmVjdG9yeScsICdXb3JraW5nRGlyZWN0b3J5JywgcHJvcGVydGllcy5Xb3JraW5nRGlyZWN0b3J5ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLldvcmtpbmdEaXJlY3RvcnkpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5UYXNrRGVmaW5pdGlvbiB7XG4gICAgLyoqXG4gICAgICogVGhlIGBDb250YWluZXJEZXBlbmRlbmN5YCBwcm9wZXJ0eSBzcGVjaWZpZXMgdGhlIGRlcGVuZGVuY2llcyBkZWZpbmVkIGZvciBjb250YWluZXIgc3RhcnR1cCBhbmQgc2h1dGRvd24uIEEgY29udGFpbmVyIGNhbiBjb250YWluIG11bHRpcGxlIGRlcGVuZGVuY2llcy4gV2hlbiBhIGRlcGVuZGVuY3kgaXMgZGVmaW5lZCBmb3IgY29udGFpbmVyIHN0YXJ0dXAsIGZvciBjb250YWluZXIgc2h1dGRvd24gaXQgaXMgcmV2ZXJzZWQuXG4gICAgICpcbiAgICAgKiBZb3VyIEFtYXpvbiBFQ1MgY29udGFpbmVyIGluc3RhbmNlcyByZXF1aXJlIGF0IGxlYXN0IHZlcnNpb24gMS4yNi4wIG9mIHRoZSBjb250YWluZXIgYWdlbnQgdG8gZW5hYmxlIGNvbnRhaW5lciBkZXBlbmRlbmNpZXMuIEhvd2V2ZXIsIHdlIHJlY29tbWVuZCB1c2luZyB0aGUgbGF0ZXN0IGNvbnRhaW5lciBhZ2VudCB2ZXJzaW9uLiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgY2hlY2tpbmcgeW91ciBhZ2VudCB2ZXJzaW9uIGFuZCB1cGRhdGluZyB0byB0aGUgbGF0ZXN0IHZlcnNpb24sIHNlZSBbVXBkYXRpbmcgdGhlIEFtYXpvbiBFQ1MgQ29udGFpbmVyIEFnZW50XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9lY3MtYWdlbnQtdXBkYXRlLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuIElmIHlvdSBhcmUgdXNpbmcgYW4gQW1hem9uIEVDUy1vcHRpbWl6ZWQgTGludXggQU1JLCB5b3VyIGluc3RhbmNlIG5lZWRzIGF0IGxlYXN0IHZlcnNpb24gMS4yNi4wLTEgb2YgdGhlIGBlY3MtaW5pdGAgcGFja2FnZS4gSWYgeW91ciBjb250YWluZXIgaW5zdGFuY2VzIGFyZSBsYXVuY2hlZCBmcm9tIHZlcnNpb24gYDIwMTkwMzAxYCBvciBsYXRlciwgdGhlbiB0aGV5IGNvbnRhaW4gdGhlIHJlcXVpcmVkIHZlcnNpb25zIG9mIHRoZSBjb250YWluZXIgYWdlbnQgYW5kIGBlY3MtaW5pdGAgLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBbWF6b24gRUNTLW9wdGltaXplZCBMaW51eCBBTUldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2Vjcy1vcHRpbWl6ZWRfQU1JLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiA+IEZvciB0YXNrcyB1c2luZyB0aGUgRmFyZ2F0ZSBsYXVuY2ggdHlwZSwgdGhpcyBwYXJhbWV0ZXIgcmVxdWlyZXMgdGhhdCB0aGUgdGFzayBvciBzZXJ2aWNlIHVzZXMgcGxhdGZvcm0gdmVyc2lvbiAxLjMuMCBvciBsYXRlci5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZXBlbmRlbmN5Lmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIENvbnRhaW5lckRlcGVuZGVuY3lQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZGVwZW5kZW5jeSBjb25kaXRpb24gb2YgdGhlIGNvbnRhaW5lci4gVGhlIGZvbGxvd2luZyBhcmUgdGhlIGF2YWlsYWJsZSBjb25kaXRpb25zIGFuZCB0aGVpciBiZWhhdmlvcjpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBgU1RBUlRgIC0gVGhpcyBjb25kaXRpb24gZW11bGF0ZXMgdGhlIGJlaGF2aW9yIG9mIGxpbmtzIGFuZCB2b2x1bWVzIHRvZGF5LiBJdCB2YWxpZGF0ZXMgdGhhdCBhIGRlcGVuZGVudCBjb250YWluZXIgaXMgc3RhcnRlZCBiZWZvcmUgcGVybWl0dGluZyBvdGhlciBjb250YWluZXJzIHRvIHN0YXJ0LlxuICAgICAgICAgKiAtIGBDT01QTEVURWAgLSBUaGlzIGNvbmRpdGlvbiB2YWxpZGF0ZXMgdGhhdCBhIGRlcGVuZGVudCBjb250YWluZXIgcnVucyB0byBjb21wbGV0aW9uIChleGl0cykgYmVmb3JlIHBlcm1pdHRpbmcgb3RoZXIgY29udGFpbmVycyB0byBzdGFydC4gVGhpcyBjYW4gYmUgdXNlZnVsIGZvciBub25lc3NlbnRpYWwgY29udGFpbmVycyB0aGF0IHJ1biBhIHNjcmlwdCBhbmQgdGhlbiBleGl0LiBUaGlzIGNvbmRpdGlvbiBjYW4ndCBiZSBzZXQgb24gYW4gZXNzZW50aWFsIGNvbnRhaW5lci5cbiAgICAgICAgICogLSBgU1VDQ0VTU2AgLSBUaGlzIGNvbmRpdGlvbiBpcyB0aGUgc2FtZSBhcyBgQ09NUExFVEVgICwgYnV0IGl0IGFsc28gcmVxdWlyZXMgdGhhdCB0aGUgY29udGFpbmVyIGV4aXRzIHdpdGggYSBgemVyb2Agc3RhdHVzLiBUaGlzIGNvbmRpdGlvbiBjYW4ndCBiZSBzZXQgb24gYW4gZXNzZW50aWFsIGNvbnRhaW5lci5cbiAgICAgICAgICogLSBgSEVBTFRIWWAgLSBUaGlzIGNvbmRpdGlvbiB2YWxpZGF0ZXMgdGhhdCB0aGUgZGVwZW5kZW50IGNvbnRhaW5lciBwYXNzZXMgaXRzIERvY2tlciBoZWFsdGggY2hlY2sgYmVmb3JlIHBlcm1pdHRpbmcgb3RoZXIgY29udGFpbmVycyB0byBzdGFydC4gVGhpcyByZXF1aXJlcyB0aGF0IHRoZSBkZXBlbmRlbnQgY29udGFpbmVyIGhhcyBoZWFsdGggY2hlY2tzIGNvbmZpZ3VyZWQuIFRoaXMgY29uZGl0aW9uIGlzIGNvbmZpcm1lZCBvbmx5IGF0IHRhc2sgc3RhcnR1cC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVwZW5kZW5jeS5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tY29udGFpbmVyZGVwZW5kZW5jeS1jb25kaXRpb25cbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNvbmRpdGlvbj86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBuYW1lIG9mIGEgY29udGFpbmVyLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZXBlbmRlbmN5Lmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZXBlbmRlbmN5LWNvbnRhaW5lcm5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNvbnRhaW5lck5hbWU/OiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENvbnRhaW5lckRlcGVuZGVuY3lQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ29udGFpbmVyRGVwZW5kZW5jeVByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uX0NvbnRhaW5lckRlcGVuZGVuY3lQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvbmRpdGlvbicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jb25kaXRpb24pKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvbnRhaW5lck5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY29udGFpbmVyTmFtZSkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDb250YWluZXJEZXBlbmRlbmN5UHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uQ29udGFpbmVyRGVwZW5kZW5jeWAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ29udGFpbmVyRGVwZW5kZW5jeVByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLkNvbnRhaW5lckRlcGVuZGVuY3lgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuVGFza0RlZmluaXRpb25Db250YWluZXJEZXBlbmRlbmN5UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblRhc2tEZWZpbml0aW9uX0NvbnRhaW5lckRlcGVuZGVuY3lQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQ29uZGl0aW9uOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNvbmRpdGlvbiksXG4gICAgICAgIENvbnRhaW5lck5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY29udGFpbmVyTmFtZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uQ29udGFpbmVyRGVwZW5kZW5jeVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb24uQ29udGFpbmVyRGVwZW5kZW5jeVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblRhc2tEZWZpbml0aW9uLkNvbnRhaW5lckRlcGVuZGVuY3lQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2NvbmRpdGlvbicsICdDb25kaXRpb24nLCBwcm9wZXJ0aWVzLkNvbmRpdGlvbiAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Db25kaXRpb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2NvbnRhaW5lck5hbWUnLCAnQ29udGFpbmVyTmFtZScsIHByb3BlcnRpZXMuQ29udGFpbmVyTmFtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Db250YWluZXJOYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuVGFza0RlZmluaXRpb24ge1xuICAgIC8qKlxuICAgICAqIFRoZSBgRGV2aWNlYCBwcm9wZXJ0eSBzcGVjaWZpZXMgYW4gb2JqZWN0IHJlcHJlc2VudGluZyBhIGNvbnRhaW5lciBpbnN0YW5jZSBob3N0IGRldmljZS5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1kZXZpY2UuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgRGV2aWNlUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHBhdGggaW5zaWRlIHRoZSBjb250YWluZXIgYXQgd2hpY2ggdG8gZXhwb3NlIHRoZSBob3N0IGRldmljZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tZGV2aWNlLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1kZXZpY2UtY29udGFpbmVycGF0aFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY29udGFpbmVyUGF0aD86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwYXRoIGZvciB0aGUgZGV2aWNlIG9uIHRoZSBob3N0IGNvbnRhaW5lciBpbnN0YW5jZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tZGV2aWNlLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1kZXZpY2UtaG9zdHBhdGhcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGhvc3RQYXRoPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGV4cGxpY2l0IHBlcm1pc3Npb25zIHRvIHByb3ZpZGUgdG8gdGhlIGNvbnRhaW5lciBmb3IgdGhlIGRldmljZS4gQnkgZGVmYXVsdCwgdGhlIGNvbnRhaW5lciBoYXMgcGVybWlzc2lvbnMgZm9yIGByZWFkYCAsIGB3cml0ZWAgLCBhbmQgYG1rbm9kYCBmb3IgdGhlIGRldmljZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tZGV2aWNlLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1kZXZpY2UtcGVybWlzc2lvbnNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHBlcm1pc3Npb25zPzogc3RyaW5nW107XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYERldmljZVByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBEZXZpY2VQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbl9EZXZpY2VQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvbnRhaW5lclBhdGgnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY29udGFpbmVyUGF0aCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaG9zdFBhdGgnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuaG9zdFBhdGgpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3Blcm1pc3Npb25zJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5wZXJtaXNzaW9ucykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJEZXZpY2VQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5EZXZpY2VgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYERldmljZVByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLkRldmljZWAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5UYXNrRGVmaW5pdGlvbkRldmljZVByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5UYXNrRGVmaW5pdGlvbl9EZXZpY2VQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQ29udGFpbmVyUGF0aDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5jb250YWluZXJQYXRoKSxcbiAgICAgICAgSG9zdFBhdGg6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaG9zdFBhdGgpLFxuICAgICAgICBQZXJtaXNzaW9uczogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMucGVybWlzc2lvbnMpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbkRldmljZVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb24uRGV2aWNlUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVGFza0RlZmluaXRpb24uRGV2aWNlUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjb250YWluZXJQYXRoJywgJ0NvbnRhaW5lclBhdGgnLCBwcm9wZXJ0aWVzLkNvbnRhaW5lclBhdGggIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQ29udGFpbmVyUGF0aCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaG9zdFBhdGgnLCAnSG9zdFBhdGgnLCBwcm9wZXJ0aWVzLkhvc3RQYXRoICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkhvc3RQYXRoKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwZXJtaXNzaW9ucycsICdQZXJtaXNzaW9ucycsIHByb3BlcnRpZXMuUGVybWlzc2lvbnMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5QZXJtaXNzaW9ucykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblRhc2tEZWZpbml0aW9uIHtcbiAgICAvKipcbiAgICAgKiBUaGUgYERvY2tlclZvbHVtZUNvbmZpZ3VyYXRpb25gIHByb3BlcnR5IHNwZWNpZmllcyBhIERvY2tlciB2b2x1bWUgY29uZmlndXJhdGlvbiBhbmQgaXMgdXNlZCB3aGVuIHlvdSB1c2UgRG9ja2VyIHZvbHVtZXMuIERvY2tlciB2b2x1bWVzIGFyZSBvbmx5IHN1cHBvcnRlZCB3aGVuIHlvdSBhcmUgdXNpbmcgdGhlIEVDMiBsYXVuY2ggdHlwZS4gV2luZG93cyBjb250YWluZXJzIG9ubHkgc3VwcG9ydCB0aGUgdXNlIG9mIHRoZSBgbG9jYWxgIGRyaXZlci4gVG8gdXNlIGJpbmQgbW91bnRzLCBzcGVjaWZ5IGEgYGhvc3RgIGluc3RlYWQuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tZG9ja2Vydm9sdW1lY29uZmlndXJhdGlvbi5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBEb2NrZXJWb2x1bWVDb25maWd1cmF0aW9uUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogSWYgdGhpcyB2YWx1ZSBpcyBgdHJ1ZWAgLCB0aGUgRG9ja2VyIHZvbHVtZSBpcyBjcmVhdGVkIGlmIGl0IGRvZXNuJ3QgYWxyZWFkeSBleGlzdC5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBUaGlzIGZpZWxkIGlzIG9ubHkgdXNlZCBpZiB0aGUgYHNjb3BlYCBpcyBgc2hhcmVkYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWRvY2tlcnZvbHVtZWNvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWRvY2tlcnZvbHVtZWNvbmZpZ3VyYXRpb24tYXV0b3Byb3Zpc2lvblxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgYXV0b3Byb3Zpc2lvbj86IGJvb2xlYW4gfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgRG9ja2VyIHZvbHVtZSBkcml2ZXIgdG8gdXNlLiBUaGUgZHJpdmVyIHZhbHVlIG11c3QgbWF0Y2ggdGhlIGRyaXZlciBuYW1lIHByb3ZpZGVkIGJ5IERvY2tlciBiZWNhdXNlIGl0IGlzIHVzZWQgZm9yIHRhc2sgcGxhY2VtZW50LiBJZiB0aGUgZHJpdmVyIHdhcyBpbnN0YWxsZWQgdXNpbmcgdGhlIERvY2tlciBwbHVnaW4gQ0xJLCB1c2UgYGRvY2tlciBwbHVnaW4gbHNgIHRvIHJldHJpZXZlIHRoZSBkcml2ZXIgbmFtZSBmcm9tIHlvdXIgY29udGFpbmVyIGluc3RhbmNlLiBJZiB0aGUgZHJpdmVyIHdhcyBpbnN0YWxsZWQgdXNpbmcgYW5vdGhlciBtZXRob2QsIHVzZSBEb2NrZXIgcGx1Z2luIGRpc2NvdmVyeSB0byByZXRyaWV2ZSB0aGUgZHJpdmVyIG5hbWUuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0RvY2tlciBwbHVnaW4gZGlzY292ZXJ5XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2V4dGVuZC9wbHVnaW5fYXBpLyNwbHVnaW4tZGlzY292ZXJ5KSAuIFRoaXMgcGFyYW1ldGVyIG1hcHMgdG8gYERyaXZlcmAgaW4gdGhlIFtDcmVhdGUgYSB2b2x1bWVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LyNvcGVyYXRpb24vVm9sdW1lQ3JlYXRlKSBzZWN0aW9uIG9mIHRoZSBbRG9ja2VyIFJlbW90ZSBBUEldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LykgYW5kIHRoZSBgeHhkcml2ZXJgIG9wdGlvbiB0byBbZG9ja2VyIHZvbHVtZSBjcmVhdGVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL2NvbW1hbmRsaW5lL3ZvbHVtZV9jcmVhdGUvKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWRvY2tlcnZvbHVtZWNvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWRvY2tlcnZvbHVtZWNvbmZpZ3VyYXRpb24tZHJpdmVyXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBkcml2ZXI/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBIG1hcCBvZiBEb2NrZXIgZHJpdmVyLXNwZWNpZmljIG9wdGlvbnMgcGFzc2VkIHRocm91Z2guIFRoaXMgcGFyYW1ldGVyIG1hcHMgdG8gYERyaXZlck9wdHNgIGluIHRoZSBbQ3JlYXRlIGEgdm9sdW1lXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8jb3BlcmF0aW9uL1ZvbHVtZUNyZWF0ZSkgc2VjdGlvbiBvZiB0aGUgW0RvY2tlciBSZW1vdGUgQVBJXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8pIGFuZCB0aGUgYHh4b3B0YCBvcHRpb24gdG8gW2RvY2tlciB2b2x1bWUgY3JlYXRlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9jb21tYW5kbGluZS92b2x1bWVfY3JlYXRlLykgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1kb2NrZXJ2b2x1bWVjb25maWd1cmF0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1kb2NrZXJ2b2x1bWVjb25maWd1cmF0aW9uLWRyaXZlcm9wdHNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGRyaXZlck9wdHM/OiB7IFtrZXk6IHN0cmluZ106IChzdHJpbmcpIH0gfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDdXN0b20gbWV0YWRhdGEgdG8gYWRkIHRvIHlvdXIgRG9ja2VyIHZvbHVtZS4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgTGFiZWxzYCBpbiB0aGUgW0NyZWF0ZSBhIHZvbHVtZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvI29wZXJhdGlvbi9Wb2x1bWVDcmVhdGUpIHNlY3Rpb24gb2YgdGhlIFtEb2NrZXIgUmVtb3RlIEFQSV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvKSBhbmQgdGhlIGB4eGxhYmVsYCBvcHRpb24gdG8gW2RvY2tlciB2b2x1bWUgY3JlYXRlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9jb21tYW5kbGluZS92b2x1bWVfY3JlYXRlLykgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1kb2NrZXJ2b2x1bWVjb25maWd1cmF0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1kb2NrZXJ2b2x1bWVjb25maWd1cmF0aW9uLWxhYmVsc1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbGFiZWxzPzogeyBba2V5OiBzdHJpbmddOiAoc3RyaW5nKSB9IHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHNjb3BlIGZvciB0aGUgRG9ja2VyIHZvbHVtZSB0aGF0IGRldGVybWluZXMgaXRzIGxpZmVjeWNsZS4gRG9ja2VyIHZvbHVtZXMgdGhhdCBhcmUgc2NvcGVkIHRvIGEgYHRhc2tgIGFyZSBhdXRvbWF0aWNhbGx5IHByb3Zpc2lvbmVkIHdoZW4gdGhlIHRhc2sgc3RhcnRzIGFuZCBkZXN0cm95ZWQgd2hlbiB0aGUgdGFzayBzdG9wcy4gRG9ja2VyIHZvbHVtZXMgdGhhdCBhcmUgc2NvcGVkIGFzIGBzaGFyZWRgIHBlcnNpc3QgYWZ0ZXIgdGhlIHRhc2sgc3RvcHMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWRvY2tlcnZvbHVtZWNvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWRvY2tlcnZvbHVtZWNvbmZpZ3VyYXRpb24tc2NvcGVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHNjb3BlPzogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBEb2NrZXJWb2x1bWVDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYERvY2tlclZvbHVtZUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbl9Eb2NrZXJWb2x1bWVDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdhdXRvcHJvdmlzaW9uJywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5hdXRvcHJvdmlzaW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdkcml2ZXInLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuZHJpdmVyKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdkcml2ZXJPcHRzJywgY2RrLmhhc2hWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5kcml2ZXJPcHRzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdsYWJlbHMnLCBjZGsuaGFzaFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLmxhYmVscykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc2NvcGUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuc2NvcGUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiRG9ja2VyVm9sdW1lQ29uZmlndXJhdGlvblByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLkRvY2tlclZvbHVtZUNvbmZpZ3VyYXRpb25gIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYERvY2tlclZvbHVtZUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5Eb2NrZXJWb2x1bWVDb25maWd1cmF0aW9uYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblRhc2tEZWZpbml0aW9uRG9ja2VyVm9sdW1lQ29uZmlndXJhdGlvblByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5UYXNrRGVmaW5pdGlvbl9Eb2NrZXJWb2x1bWVDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEF1dG9wcm92aXNpb246IGNkay5ib29sZWFuVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmF1dG9wcm92aXNpb24pLFxuICAgICAgICBEcml2ZXI6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZHJpdmVyKSxcbiAgICAgICAgRHJpdmVyT3B0czogY2RrLmhhc2hNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuZHJpdmVyT3B0cyksXG4gICAgICAgIExhYmVsczogY2RrLmhhc2hNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMubGFiZWxzKSxcbiAgICAgICAgU2NvcGU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuc2NvcGUpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbkRvY2tlclZvbHVtZUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblRhc2tEZWZpbml0aW9uLkRvY2tlclZvbHVtZUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5UYXNrRGVmaW5pdGlvbi5Eb2NrZXJWb2x1bWVDb25maWd1cmF0aW9uUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdhdXRvcHJvdmlzaW9uJywgJ0F1dG9wcm92aXNpb24nLCBwcm9wZXJ0aWVzLkF1dG9wcm92aXNpb24gIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Qm9vbGVhbihwcm9wZXJ0aWVzLkF1dG9wcm92aXNpb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2RyaXZlcicsICdEcml2ZXInLCBwcm9wZXJ0aWVzLkRyaXZlciAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Ecml2ZXIpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2RyaXZlck9wdHMnLCAnRHJpdmVyT3B0cycsIHByb3BlcnRpZXMuRHJpdmVyT3B0cyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRNYXAoY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcpKHByb3BlcnRpZXMuRHJpdmVyT3B0cykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbGFiZWxzJywgJ0xhYmVscycsIHByb3BlcnRpZXMuTGFiZWxzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE1hcChjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZykocHJvcGVydGllcy5MYWJlbHMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3Njb3BlJywgJ1Njb3BlJywgcHJvcGVydGllcy5TY29wZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5TY29wZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblRhc2tEZWZpbml0aW9uIHtcbiAgICAvKipcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBzcGVjaWZpZWQgd2hlbiB5b3UncmUgdXNpbmcgYW4gQW1hem9uIEVsYXN0aWMgRmlsZSBTeXN0ZW0gZmlsZSBzeXN0ZW0gZm9yIHRhc2sgc3RvcmFnZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQW1hem9uIEVGUyB2b2x1bWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9lZnMtdm9sdW1lcy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWVmc3ZvbHVtZWNvbmZpZ3VyYXRpb24uaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgRUZTVm9sdW1lQ29uZmlndXJhdGlvblByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhdXRob3JpemF0aW9uIGNvbmZpZ3VyYXRpb24gZGV0YWlscyBmb3IgdGhlIEFtYXpvbiBFRlMgZmlsZSBzeXN0ZW0uXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWVmc3ZvbHVtZWNvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWVmc3ZvbHVtZWNvbmZpZ3VyYXRpb24tYXV0aG9yaXphdGlvbmNvbmZpZ1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgYXV0aG9yaXphdGlvbkNvbmZpZz86IENmblRhc2tEZWZpbml0aW9uLkF1dGhvcml6YXRpb25Db25maWdQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBBbWF6b24gRUZTIGZpbGUgc3lzdGVtIElEIHRvIHVzZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tZWZzdm9sdW1lY29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tZWZzdm9sdW1lY29uZmlndXJhdGlvbi1maWxlc3lzdGVtaWRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGZpbGVzeXN0ZW1JZDogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGRpcmVjdG9yeSB3aXRoaW4gdGhlIEFtYXpvbiBFRlMgZmlsZSBzeXN0ZW0gdG8gbW91bnQgYXMgdGhlIHJvb3QgZGlyZWN0b3J5IGluc2lkZSB0aGUgaG9zdC4gSWYgdGhpcyBwYXJhbWV0ZXIgaXMgb21pdHRlZCwgdGhlIHJvb3Qgb2YgdGhlIEFtYXpvbiBFRlMgdm9sdW1lIHdpbGwgYmUgdXNlZC4gU3BlY2lmeWluZyBgL2Agd2lsbCBoYXZlIHRoZSBzYW1lIGVmZmVjdCBhcyBvbWl0dGluZyB0aGlzIHBhcmFtZXRlci5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBJZiBhbiBFRlMgYWNjZXNzIHBvaW50IGlzIHNwZWNpZmllZCBpbiB0aGUgYGF1dGhvcml6YXRpb25Db25maWdgICwgdGhlIHJvb3QgZGlyZWN0b3J5IHBhcmFtZXRlciBtdXN0IGVpdGhlciBiZSBvbWl0dGVkIG9yIHNldCB0byBgL2Agd2hpY2ggd2lsbCBlbmZvcmNlIHRoZSBwYXRoIHNldCBvbiB0aGUgRUZTIGFjY2VzcyBwb2ludC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tZWZzdm9sdW1lY29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tZWZzdm9sdW1lY29uZmlndXJhdGlvbi1yb290ZGlyZWN0b3J5XG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSByb290RGlyZWN0b3J5Pzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRvIHVzZSBlbmNyeXB0aW9uIGZvciBBbWF6b24gRUZTIGRhdGEgaW4gdHJhbnNpdCBiZXR3ZWVuIHRoZSBBbWF6b24gRUNTIGhvc3QgYW5kIHRoZSBBbWF6b24gRUZTIHNlcnZlci4gVHJhbnNpdCBlbmNyeXB0aW9uIG11c3QgYmUgdHVybmVkIG9uIGlmIEFtYXpvbiBFRlMgSUFNIGF1dGhvcml6YXRpb24gaXMgdXNlZC4gSWYgdGhpcyBwYXJhbWV0ZXIgaXMgb21pdHRlZCwgdGhlIGRlZmF1bHQgdmFsdWUgb2YgYERJU0FCTEVEYCBpcyB1c2VkLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtFbmNyeXB0aW5nIGRhdGEgaW4gdHJhbnNpdF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvZW5jcnlwdGlvbi1pbi10cmFuc2l0Lmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgRmlsZSBTeXN0ZW0gVXNlciBHdWlkZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1lZnN2b2x1bWVjb25maWd1cmF0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1lZnN2b2x1bWVjb25maWd1cmF0aW9uLXRyYW5zaXRlbmNyeXB0aW9uXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB0cmFuc2l0RW5jcnlwdGlvbj86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwb3J0IHRvIHVzZSB3aGVuIHNlbmRpbmcgZW5jcnlwdGVkIGRhdGEgYmV0d2VlbiB0aGUgQW1hem9uIEVDUyBob3N0IGFuZCB0aGUgQW1hem9uIEVGUyBzZXJ2ZXIuIElmIHlvdSBkbyBub3Qgc3BlY2lmeSBhIHRyYW5zaXQgZW5jcnlwdGlvbiBwb3J0LCBpdCB3aWxsIHVzZSB0aGUgcG9ydCBzZWxlY3Rpb24gc3RyYXRlZ3kgdGhhdCB0aGUgQW1hem9uIEVGUyBtb3VudCBoZWxwZXIgdXNlcy4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbRUZTIG1vdW50IGhlbHBlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvZWZzLW1vdW50LWhlbHBlci5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIEZpbGUgU3lzdGVtIFVzZXIgR3VpZGUqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tZWZzdm9sdW1lY29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tZWZzdm9sdW1lY29uZmlndXJhdGlvbi10cmFuc2l0ZW5jcnlwdGlvbnBvcnRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHRyYW5zaXRFbmNyeXB0aW9uUG9ydD86IG51bWJlcjtcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgRUZTVm9sdW1lQ29uZmlndXJhdGlvblByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBFRlNWb2x1bWVDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25fRUZTVm9sdW1lQ29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignYXV0aG9yaXphdGlvbkNvbmZpZycsIENmblRhc2tEZWZpbml0aW9uX0F1dGhvcml6YXRpb25Db25maWdQcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5hdXRob3JpemF0aW9uQ29uZmlnKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdmaWxlc3lzdGVtSWQnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMuZmlsZXN5c3RlbUlkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdmaWxlc3lzdGVtSWQnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuZmlsZXN5c3RlbUlkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyb290RGlyZWN0b3J5JywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnJvb3REaXJlY3RvcnkpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3RyYW5zaXRFbmNyeXB0aW9uJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnRyYW5zaXRFbmNyeXB0aW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0cmFuc2l0RW5jcnlwdGlvblBvcnQnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMudHJhbnNpdEVuY3J5cHRpb25Qb3J0KSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkVGU1ZvbHVtZUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5FRlNWb2x1bWVDb25maWd1cmF0aW9uYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBFRlNWb2x1bWVDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uRUZTVm9sdW1lQ29uZmlndXJhdGlvbmAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5UYXNrRGVmaW5pdGlvbkVGU1ZvbHVtZUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVGFza0RlZmluaXRpb25fRUZTVm9sdW1lQ29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBBdXRob3JpemF0aW9uQ29uZmlnOiBjZm5UYXNrRGVmaW5pdGlvbkF1dGhvcml6YXRpb25Db25maWdQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5hdXRob3JpemF0aW9uQ29uZmlnKSxcbiAgICAgICAgRmlsZXN5c3RlbUlkOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmZpbGVzeXN0ZW1JZCksXG4gICAgICAgIFJvb3REaXJlY3Rvcnk6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucm9vdERpcmVjdG9yeSksXG4gICAgICAgIFRyYW5zaXRFbmNyeXB0aW9uOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnRyYW5zaXRFbmNyeXB0aW9uKSxcbiAgICAgICAgVHJhbnNpdEVuY3J5cHRpb25Qb3J0OiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnRyYW5zaXRFbmNyeXB0aW9uUG9ydCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uRUZTVm9sdW1lQ29uZmlndXJhdGlvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb24uRUZTVm9sdW1lQ29uZmlndXJhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblRhc2tEZWZpbml0aW9uLkVGU1ZvbHVtZUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2F1dGhvcml6YXRpb25Db25maWcnLCAnQXV0aG9yaXphdGlvbkNvbmZpZycsIHByb3BlcnRpZXMuQXV0aG9yaXphdGlvbkNvbmZpZyAhPSBudWxsID8gQ2ZuVGFza0RlZmluaXRpb25BdXRob3JpemF0aW9uQ29uZmlnUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5BdXRob3JpemF0aW9uQ29uZmlnKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdmaWxlc3lzdGVtSWQnLCAnRmlsZXN5c3RlbUlkJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5GaWxlc3lzdGVtSWQpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3Jvb3REaXJlY3RvcnknLCAnUm9vdERpcmVjdG9yeScsIHByb3BlcnRpZXMuUm9vdERpcmVjdG9yeSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Sb290RGlyZWN0b3J5KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0cmFuc2l0RW5jcnlwdGlvbicsICdUcmFuc2l0RW5jcnlwdGlvbicsIHByb3BlcnRpZXMuVHJhbnNpdEVuY3J5cHRpb24gIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuVHJhbnNpdEVuY3J5cHRpb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3RyYW5zaXRFbmNyeXB0aW9uUG9ydCcsICdUcmFuc2l0RW5jcnlwdGlvblBvcnQnLCBwcm9wZXJ0aWVzLlRyYW5zaXRFbmNyeXB0aW9uUG9ydCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5UcmFuc2l0RW5jcnlwdGlvblBvcnQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5UYXNrRGVmaW5pdGlvbiB7XG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIGZpbGVzIGNvbnRhaW5pbmcgdGhlIGVudmlyb25tZW50IHZhcmlhYmxlcyB0byBwYXNzIHRvIGEgY29udGFpbmVyLiBZb3UgY2FuIHNwZWNpZnkgdXAgdG8gdGVuIGVudmlyb25tZW50IGZpbGVzLiBUaGUgZmlsZSBtdXN0IGhhdmUgYSBgLmVudmAgZmlsZSBleHRlbnNpb24uIEVhY2ggbGluZSBpbiBhbiBlbnZpcm9ubWVudCBmaWxlIHNob3VsZCBjb250YWluIGFuIGVudmlyb25tZW50IHZhcmlhYmxlIGluIGBWQVJJQUJMRT1WQUxVRWAgZm9ybWF0LiBMaW5lcyBiZWdpbm5pbmcgd2l0aCBgI2AgYXJlIHRyZWF0ZWQgYXMgY29tbWVudHMgYW5kIGFyZSBpZ25vcmVkLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGUgZmlsZSBzeW50YXgsIHNlZSBbRGVjbGFyZSBkZWZhdWx0IGVudmlyb25tZW50IHZhcmlhYmxlcyBpbiBmaWxlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vY29tcG9zZS9lbnYtZmlsZS8pIC5cbiAgICAgKlxuICAgICAqIElmIHRoZXJlIGFyZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMgc3BlY2lmaWVkIHVzaW5nIHRoZSBgZW52aXJvbm1lbnRgIHBhcmFtZXRlciBpbiBhIGNvbnRhaW5lciBkZWZpbml0aW9uLCB0aGV5IHRha2UgcHJlY2VkZW5jZSBvdmVyIHRoZSB2YXJpYWJsZXMgY29udGFpbmVkIHdpdGhpbiBhbiBlbnZpcm9ubWVudCBmaWxlLiBJZiBtdWx0aXBsZSBlbnZpcm9ubWVudCBmaWxlcyBhcmUgc3BlY2lmaWVkIHRoYXQgY29udGFpbiB0aGUgc2FtZSB2YXJpYWJsZSwgdGhleSdyZSBwcm9jZXNzZWQgZnJvbSB0aGUgdG9wIGRvd24uIFdlIHJlY29tbWVuZCB0aGF0IHlvdSB1c2UgdW5pcXVlIHZhcmlhYmxlIG5hbWVzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtTcGVjaWZ5aW5nIGVudmlyb25tZW50IHZhcmlhYmxlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvdGFza2RlZi1lbnZmaWxlcy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgaXMgb25seSBzdXBwb3J0ZWQgZm9yIHRhc2tzIGhvc3RlZCBvbiBGYXJnYXRlIHVzaW5nIHRoZSBmb2xsb3dpbmcgcGxhdGZvcm0gdmVyc2lvbnM6XG4gICAgICpcbiAgICAgKiAtIExpbnV4IHBsYXRmb3JtIHZlcnNpb24gYDEuNC4wYCBvciBsYXRlci5cbiAgICAgKiAtIFdpbmRvd3MgcGxhdGZvcm0gdmVyc2lvbiBgMS4wLjBgIG9yIGxhdGVyLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWVudmlyb25tZW50ZmlsZS5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBFbnZpcm9ubWVudEZpbGVQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZmlsZSB0eXBlIHRvIHVzZS4gVGhlIG9ubHkgc3VwcG9ydGVkIHZhbHVlIGlzIGBzM2AgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1lbnZpcm9ubWVudGZpbGUuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWVudmlyb25tZW50ZmlsZS10eXBlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB0eXBlPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIG9mIHRoZSBBbWF6b24gUzMgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGVudmlyb25tZW50IHZhcmlhYmxlIGZpbGUuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWVudmlyb25tZW50ZmlsZS5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tZW52aXJvbm1lbnRmaWxlLXZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB2YWx1ZT86IHN0cmluZztcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgRW52aXJvbm1lbnRGaWxlUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEVudmlyb25tZW50RmlsZVByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uX0Vudmlyb25tZW50RmlsZVByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndHlwZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy50eXBlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd2YWx1ZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy52YWx1ZSkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJFbnZpcm9ubWVudEZpbGVQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5FbnZpcm9ubWVudEZpbGVgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEVudmlyb25tZW50RmlsZVByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLkVudmlyb25tZW50RmlsZWAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5UYXNrRGVmaW5pdGlvbkVudmlyb25tZW50RmlsZVByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5UYXNrRGVmaW5pdGlvbl9FbnZpcm9ubWVudEZpbGVQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgVHlwZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy50eXBlKSxcbiAgICAgICAgVmFsdWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMudmFsdWUpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbkVudmlyb25tZW50RmlsZVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb24uRW52aXJvbm1lbnRGaWxlUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVGFza0RlZmluaXRpb24uRW52aXJvbm1lbnRGaWxlUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0eXBlJywgJ1R5cGUnLCBwcm9wZXJ0aWVzLlR5cGUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuVHlwZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndmFsdWUnLCAnVmFsdWUnLCBwcm9wZXJ0aWVzLlZhbHVlICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlZhbHVlKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuVGFza0RlZmluaXRpb24ge1xuICAgIC8qKlxuICAgICAqIFRoZSBhbW91bnQgb2YgZXBoZW1lcmFsIHN0b3JhZ2UgdG8gYWxsb2NhdGUgZm9yIHRoZSB0YXNrLiBUaGlzIHBhcmFtZXRlciBpcyB1c2VkIHRvIGV4cGFuZCB0aGUgdG90YWwgYW1vdW50IG9mIGVwaGVtZXJhbCBzdG9yYWdlIGF2YWlsYWJsZSwgYmV5b25kIHRoZSBkZWZhdWx0IGFtb3VudCwgZm9yIHRhc2tzIGhvc3RlZCBvbiBBV1MgRmFyZ2F0ZSAuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0ZhcmdhdGUgdGFzayBzdG9yYWdlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC91c2VyZ3VpZGUvdXNpbmdfZGF0YV92b2x1bWVzLmh0bWwpIGluIHRoZSAqQW1hem9uIEVDUyBVc2VyIEd1aWRlIGZvciBBV1MgRmFyZ2F0ZSogLlxuICAgICAqXG4gICAgICogPiBGb3IgdGFza3MgdXNpbmcgdGhlIEZhcmdhdGUgbGF1bmNoIHR5cGUsIHRoZSB0YXNrIHJlcXVpcmVzIHRoZSBmb2xsb3dpbmcgcGxhdGZvcm1zOlxuICAgICAqID5cbiAgICAgKiA+IC0gTGludXggcGxhdGZvcm0gdmVyc2lvbiBgMS40LjBgIG9yIGxhdGVyLlxuICAgICAqID4gLSBXaW5kb3dzIHBsYXRmb3JtIHZlcnNpb24gYDEuMC4wYCBvciBsYXRlci5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1lcGhlbWVyYWxzdG9yYWdlLmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIEVwaGVtZXJhbFN0b3JhZ2VQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdG90YWwgYW1vdW50LCBpbiBHaUIsIG9mIGVwaGVtZXJhbCBzdG9yYWdlIHRvIHNldCBmb3IgdGhlIHRhc2suIFRoZSBtaW5pbXVtIHN1cHBvcnRlZCB2YWx1ZSBpcyBgMjFgIEdpQiBhbmQgdGhlIG1heGltdW0gc3VwcG9ydGVkIHZhbHVlIGlzIGAyMDBgIEdpQi5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tZXBoZW1lcmFsc3RvcmFnZS5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tZXBoZW1lcmFsc3RvcmFnZS1zaXplaW5naWJcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHNpemVJbkdpQj86IG51bWJlcjtcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgRXBoZW1lcmFsU3RvcmFnZVByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBFcGhlbWVyYWxTdG9yYWdlUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25fRXBoZW1lcmFsU3RvcmFnZVByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc2l6ZUluR2lCJywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLnNpemVJbkdpQikpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJFcGhlbWVyYWxTdG9yYWdlUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uRXBoZW1lcmFsU3RvcmFnZWAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgRXBoZW1lcmFsU3RvcmFnZVByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLkVwaGVtZXJhbFN0b3JhZ2VgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuVGFza0RlZmluaXRpb25FcGhlbWVyYWxTdG9yYWdlUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblRhc2tEZWZpbml0aW9uX0VwaGVtZXJhbFN0b3JhZ2VQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgU2l6ZUluR2lCOiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnNpemVJbkdpQiksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uRXBoZW1lcmFsU3RvcmFnZVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb24uRXBoZW1lcmFsU3RvcmFnZVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblRhc2tEZWZpbml0aW9uLkVwaGVtZXJhbFN0b3JhZ2VQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3NpemVJbkdpQicsICdTaXplSW5HaUInLCBwcm9wZXJ0aWVzLlNpemVJbkdpQiAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5TaXplSW5HaUIpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5UYXNrRGVmaW5pdGlvbiB7XG4gICAgLyoqXG4gICAgICogVGhlIEZpcmVMZW5zIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBjb250YWluZXIuIFRoaXMgaXMgdXNlZCB0byBzcGVjaWZ5IGFuZCBjb25maWd1cmUgYSBsb2cgcm91dGVyIGZvciBjb250YWluZXIgbG9ncy4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQ3VzdG9tIGxvZyByb3V0aW5nXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS91c2luZ19maXJlbGVucy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWZpcmVsZW5zY29uZmlndXJhdGlvbi5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBGaXJlbGVuc0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb3B0aW9ucyB0byB1c2Ugd2hlbiBjb25maWd1cmluZyB0aGUgbG9nIHJvdXRlci4gVGhpcyBmaWVsZCBpcyBvcHRpb25hbCBhbmQgY2FuIGJlIHVzZWQgdG8gYWRkIGFkZGl0aW9uYWwgbWV0YWRhdGEsIHN1Y2ggYXMgdGhlIHRhc2ssIHRhc2sgZGVmaW5pdGlvbiwgY2x1c3RlciwgYW5kIGNvbnRhaW5lciBpbnN0YW5jZSBkZXRhaWxzIHRvIHRoZSBsb2cgZXZlbnQuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHNwZWNpZmllZCwgdmFsaWQgb3B0aW9uIGtleXMgYXJlOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIGBlbmFibGUtZWNzLWxvZy1tZXRhZGF0YWAgLCB3aGljaCBjYW4gYmUgYHRydWVgIG9yIGBmYWxzZWBcbiAgICAgICAgICogLSBgY29uZmlnLWZpbGUtdHlwZWAgLCB3aGljaCBjYW4gYmUgYHMzYCBvciBgZmlsZWBcbiAgICAgICAgICogLSBgY29uZmlnLWZpbGUtdmFsdWVgICwgd2hpY2ggaXMgZWl0aGVyIGFuIFMzIEFSTiBvciBhIGZpbGUgcGF0aFxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1maXJlbGVuc2NvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWZpcmVsZW5zY29uZmlndXJhdGlvbi1vcHRpb25zXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBvcHRpb25zPzogeyBba2V5OiBzdHJpbmddOiAoc3RyaW5nKSB9IHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGxvZyByb3V0ZXIgdG8gdXNlLiBUaGUgdmFsaWQgdmFsdWVzIGFyZSBgZmx1ZW50ZGAgb3IgYGZsdWVudGJpdGAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1maXJlbGVuc2NvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWZpcmVsZW5zY29uZmlndXJhdGlvbi10eXBlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB0eXBlPzogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBGaXJlbGVuc0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgRmlyZWxlbnNDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25fRmlyZWxlbnNDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdvcHRpb25zJywgY2RrLmhhc2hWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5vcHRpb25zKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0eXBlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnR5cGUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiRmlyZWxlbnNDb25maWd1cmF0aW9uUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uRmlyZWxlbnNDb25maWd1cmF0aW9uYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBGaXJlbGVuc0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5GaXJlbGVuc0NvbmZpZ3VyYXRpb25gIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuVGFza0RlZmluaXRpb25GaXJlbGVuc0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVGFza0RlZmluaXRpb25fRmlyZWxlbnNDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIE9wdGlvbnM6IGNkay5oYXNoTWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLm9wdGlvbnMpLFxuICAgICAgICBUeXBlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnR5cGUpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbkZpcmVsZW5zQ29uZmlndXJhdGlvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb24uRmlyZWxlbnNDb25maWd1cmF0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVGFza0RlZmluaXRpb24uRmlyZWxlbnNDb25maWd1cmF0aW9uUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdvcHRpb25zJywgJ09wdGlvbnMnLCBwcm9wZXJ0aWVzLk9wdGlvbnMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TWFwKGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKShwcm9wZXJ0aWVzLk9wdGlvbnMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3R5cGUnLCAnVHlwZScsIHByb3BlcnRpZXMuVHlwZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5UeXBlKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuVGFza0RlZmluaXRpb24ge1xuICAgIC8qKlxuICAgICAqIFRoZSBgSGVhbHRoQ2hlY2tgIHByb3BlcnR5IHNwZWNpZmllcyBhbiBvYmplY3QgcmVwcmVzZW50aW5nIGEgY29udGFpbmVyIGhlYWx0aCBjaGVjay4gSGVhbHRoIGNoZWNrIHBhcmFtZXRlcnMgdGhhdCBhcmUgc3BlY2lmaWVkIGluIGEgY29udGFpbmVyIGRlZmluaXRpb24gb3ZlcnJpZGUgYW55IERvY2tlciBoZWFsdGggY2hlY2tzIHRoYXQgZXhpc3QgaW4gdGhlIGNvbnRhaW5lciBpbWFnZSAoc3VjaCBhcyB0aG9zZSBzcGVjaWZpZWQgaW4gYSBwYXJlbnQgaW1hZ2Ugb3IgZnJvbSB0aGUgaW1hZ2UncyBEb2NrZXJmaWxlKS4gVGhpcyBjb25maWd1cmF0aW9uIG1hcHMgdG8gdGhlIGBIRUFMVEhDSEVDS2AgcGFyYW1ldGVyIG9mIFtkb2NrZXIgcnVuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vKSAuXG4gICAgICpcbiAgICAgKiA+IFRoZSBBbWF6b24gRUNTIGNvbnRhaW5lciBhZ2VudCBvbmx5IG1vbml0b3JzIGFuZCByZXBvcnRzIG9uIHRoZSBoZWFsdGggY2hlY2tzIHNwZWNpZmllZCBpbiB0aGUgdGFzayBkZWZpbml0aW9uLiBBbWF6b24gRUNTIGRvZXMgbm90IG1vbml0b3IgRG9ja2VyIGhlYWx0aCBjaGVja3MgdGhhdCBhcmUgZW1iZWRkZWQgaW4gYSBjb250YWluZXIgaW1hZ2UgYW5kIG5vdCBzcGVjaWZpZWQgaW4gdGhlIGNvbnRhaW5lciBkZWZpbml0aW9uLiBIZWFsdGggY2hlY2sgcGFyYW1ldGVycyB0aGF0IGFyZSBzcGVjaWZpZWQgaW4gYSBjb250YWluZXIgZGVmaW5pdGlvbiBvdmVycmlkZSBhbnkgRG9ja2VyIGhlYWx0aCBjaGVja3MgdGhhdCBleGlzdCBpbiB0aGUgY29udGFpbmVyIGltYWdlLlxuICAgICAqXG4gICAgICogSWYgYSB0YXNrIGlzIHJ1biBtYW51YWxseSwgYW5kIG5vdCBhcyBwYXJ0IG9mIGEgc2VydmljZSwgdGhlIHRhc2sgd2lsbCBjb250aW51ZSBpdHMgbGlmZWN5Y2xlIHJlZ2FyZGxlc3Mgb2YgaXRzIGhlYWx0aCBzdGF0dXMuIEZvciB0YXNrcyB0aGF0IGFyZSBwYXJ0IG9mIGEgc2VydmljZSwgaWYgdGhlIHRhc2sgcmVwb3J0cyBhcyB1bmhlYWx0aHkgdGhlbiB0aGUgdGFzayB3aWxsIGJlIHN0b3BwZWQgYW5kIHRoZSBzZXJ2aWNlIHNjaGVkdWxlciB3aWxsIHJlcGxhY2UgaXQuXG4gICAgICpcbiAgICAgKiBUaGUgZm9sbG93aW5nIGFyZSBub3RlcyBhYm91dCBjb250YWluZXIgaGVhbHRoIGNoZWNrIHN1cHBvcnQ6XG4gICAgICpcbiAgICAgKiAtIENvbnRhaW5lciBoZWFsdGggY2hlY2tzIHJlcXVpcmUgdmVyc2lvbiAxLjE3LjAgb3IgZ3JlYXRlciBvZiB0aGUgQW1hem9uIEVDUyBjb250YWluZXIgYWdlbnQuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1VwZGF0aW5nIHRoZSBBbWF6b24gRUNTIENvbnRhaW5lciBBZ2VudF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvZWNzLWFnZW50LXVwZGF0ZS5odG1sKSAuXG4gICAgICogLSBDb250YWluZXIgaGVhbHRoIGNoZWNrcyBhcmUgc3VwcG9ydGVkIGZvciBGYXJnYXRlIHRhc2tzIGlmIHlvdSBhcmUgdXNpbmcgcGxhdGZvcm0gdmVyc2lvbiAxLjEuMCBvciBncmVhdGVyLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBV1MgRmFyZ2F0ZSBQbGF0Zm9ybSBWZXJzaW9uc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvcGxhdGZvcm1fdmVyc2lvbnMuaHRtbCkgLlxuICAgICAqIC0gQ29udGFpbmVyIGhlYWx0aCBjaGVja3MgYXJlIG5vdCBzdXBwb3J0ZWQgZm9yIHRhc2tzIHRoYXQgYXJlIHBhcnQgb2YgYSBzZXJ2aWNlIHRoYXQgaXMgY29uZmlndXJlZCB0byB1c2UgYSBDbGFzc2ljIExvYWQgQmFsYW5jZXIuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24taGVhbHRoY2hlY2suaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgSGVhbHRoQ2hlY2tQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBIHN0cmluZyBhcnJheSByZXByZXNlbnRpbmcgdGhlIGNvbW1hbmQgdGhhdCB0aGUgY29udGFpbmVyIHJ1bnMgdG8gZGV0ZXJtaW5lIGlmIGl0IGlzIGhlYWx0aHkuIFRoZSBzdHJpbmcgYXJyYXkgbXVzdCBzdGFydCB3aXRoIGBDTURgIHRvIHJ1biB0aGUgY29tbWFuZCBhcmd1bWVudHMgZGlyZWN0bHksIG9yIGBDTUQtU0hFTExgIHRvIHJ1biB0aGUgY29tbWFuZCB3aXRoIHRoZSBjb250YWluZXIncyBkZWZhdWx0IHNoZWxsLlxuICAgICAgICAgKlxuICAgICAgICAgKiBXaGVuIHlvdSB1c2UgdGhlIEFXUyBNYW5hZ2VtZW50IENvbnNvbGUgSlNPTiBwYW5lbCwgdGhlIEFXUyBDb21tYW5kIExpbmUgSW50ZXJmYWNlICwgb3IgdGhlIEFQSXMsIGVuY2xvc2UgdGhlIGxpc3Qgb2YgY29tbWFuZHMgaW4gZG91YmxlIHF1b3RlcyBhbmQgYnJhY2tldHMuXG4gICAgICAgICAqXG4gICAgICAgICAqIGBbIFwiQ01ELVNIRUxMXCIsIFwiY3VybCAtZiBodHRwOi8vbG9jYWxob3N0LyB8fCBleGl0IDFcIiBdYFxuICAgICAgICAgKlxuICAgICAgICAgKiBZb3UgZG9uJ3QgaW5jbHVkZSB0aGUgZG91YmxlIHF1b3RlcyBhbmQgYnJhY2tldHMgd2hlbiB5b3UgdXNlIHRoZSBBV1MgTWFuYWdlbWVudCBDb25zb2xlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBgQ01ELVNIRUxMLCBjdXJsIC1mIGh0dHA6Ly9sb2NhbGhvc3QvIHx8IGV4aXQgMWBcbiAgICAgICAgICpcbiAgICAgICAgICogQW4gZXhpdCBjb2RlIG9mIDAgaW5kaWNhdGVzIHN1Y2Nlc3MsIGFuZCBub24temVybyBleGl0IGNvZGUgaW5kaWNhdGVzIGZhaWx1cmUuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgYEhlYWx0aENoZWNrYCBpbiB0aGUgW0NyZWF0ZSBhIGNvbnRhaW5lcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvI29wZXJhdGlvbi9Db250YWluZXJDcmVhdGUpIHNlY3Rpb24gb2YgdGhlIFtEb2NrZXIgUmVtb3RlIEFQSV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9hcGkvdjEuMzUvKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWhlYWx0aGNoZWNrLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1oZWFsdGhjaGVjay1jb21tYW5kXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBjb21tYW5kPzogc3RyaW5nW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdGltZSBwZXJpb2QgaW4gc2Vjb25kcyBiZXR3ZWVuIGVhY2ggaGVhbHRoIGNoZWNrIGV4ZWN1dGlvbi4gWW91IG1heSBzcGVjaWZ5IGJldHdlZW4gNSBhbmQgMzAwIHNlY29uZHMuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIDMwIHNlY29uZHMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWhlYWx0aGNoZWNrLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1oZWFsdGhjaGVjay1pbnRlcnZhbFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgaW50ZXJ2YWw/OiBudW1iZXI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIHJldHJ5IGEgZmFpbGVkIGhlYWx0aCBjaGVjayBiZWZvcmUgdGhlIGNvbnRhaW5lciBpcyBjb25zaWRlcmVkIHVuaGVhbHRoeS4gWW91IG1heSBzcGVjaWZ5IGJldHdlZW4gMSBhbmQgMTAgcmV0cmllcy4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgMy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24taGVhbHRoY2hlY2suaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWhlYWx0aGNoZWNrLXJldHJpZXNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHJldHJpZXM/OiBudW1iZXI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb3B0aW9uYWwgZ3JhY2UgcGVyaW9kIHRvIHByb3ZpZGUgY29udGFpbmVycyB0aW1lIHRvIGJvb3RzdHJhcCBiZWZvcmUgZmFpbGVkIGhlYWx0aCBjaGVja3MgY291bnQgdG93YXJkcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgcmV0cmllcy4gWW91IGNhbiBzcGVjaWZ5IGJldHdlZW4gMCBhbmQgMzAwIHNlY29uZHMuIEJ5IGRlZmF1bHQsIHRoZSBgc3RhcnRQZXJpb2RgIGlzIG9mZi5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBJZiBhIGhlYWx0aCBjaGVjayBzdWNjZWVkcyB3aXRoaW4gdGhlIGBzdGFydFBlcmlvZGAgLCB0aGVuIHRoZSBjb250YWluZXIgaXMgY29uc2lkZXJlZCBoZWFsdGh5IGFuZCBhbnkgc3Vic2VxdWVudCBmYWlsdXJlcyBjb3VudCB0b3dhcmQgdGhlIG1heGltdW0gbnVtYmVyIG9mIHJldHJpZXMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWhlYWx0aGNoZWNrLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1oZWFsdGhjaGVjay1zdGFydHBlcmlvZFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgc3RhcnRQZXJpb2Q/OiBudW1iZXI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdGltZSBwZXJpb2QgaW4gc2Vjb25kcyB0byB3YWl0IGZvciBhIGhlYWx0aCBjaGVjayB0byBzdWNjZWVkIGJlZm9yZSBpdCBpcyBjb25zaWRlcmVkIGEgZmFpbHVyZS4gWW91IG1heSBzcGVjaWZ5IGJldHdlZW4gMiBhbmQgNjAgc2Vjb25kcy4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgNS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24taGVhbHRoY2hlY2suaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWhlYWx0aGNoZWNrLXRpbWVvdXRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHRpbWVvdXQ/OiBudW1iZXI7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYEhlYWx0aENoZWNrUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEhlYWx0aENoZWNrUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25fSGVhbHRoQ2hlY2tQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvbW1hbmQnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLmNvbW1hbmQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2ludGVydmFsJywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLmludGVydmFsKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyZXRyaWVzJywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLnJldHJpZXMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3N0YXJ0UGVyaW9kJywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLnN0YXJ0UGVyaW9kKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0aW1lb3V0JywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLnRpbWVvdXQpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiSGVhbHRoQ2hlY2tQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5IZWFsdGhDaGVja2AgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgSGVhbHRoQ2hlY2tQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5IZWFsdGhDaGVja2AgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5UYXNrRGVmaW5pdGlvbkhlYWx0aENoZWNrUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblRhc2tEZWZpbml0aW9uX0hlYWx0aENoZWNrUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIENvbW1hbmQ6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLmNvbW1hbmQpLFxuICAgICAgICBJbnRlcnZhbDogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5pbnRlcnZhbCksXG4gICAgICAgIFJldHJpZXM6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucmV0cmllcyksXG4gICAgICAgIFN0YXJ0UGVyaW9kOiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnN0YXJ0UGVyaW9kKSxcbiAgICAgICAgVGltZW91dDogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy50aW1lb3V0KSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25IZWFsdGhDaGVja1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb24uSGVhbHRoQ2hlY2tQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5UYXNrRGVmaW5pdGlvbi5IZWFsdGhDaGVja1Byb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY29tbWFuZCcsICdDb21tYW5kJywgcHJvcGVydGllcy5Db21tYW5kICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuQ29tbWFuZCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaW50ZXJ2YWwnLCAnSW50ZXJ2YWwnLCBwcm9wZXJ0aWVzLkludGVydmFsICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLkludGVydmFsKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdyZXRyaWVzJywgJ1JldHJpZXMnLCBwcm9wZXJ0aWVzLlJldHJpZXMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuUmV0cmllcykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnc3RhcnRQZXJpb2QnLCAnU3RhcnRQZXJpb2QnLCBwcm9wZXJ0aWVzLlN0YXJ0UGVyaW9kICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLlN0YXJ0UGVyaW9kKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0aW1lb3V0JywgJ1RpbWVvdXQnLCBwcm9wZXJ0aWVzLlRpbWVvdXQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuVGltZW91dCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblRhc2tEZWZpbml0aW9uIHtcbiAgICAvKipcbiAgICAgKiBUaGUgYEhvc3RFbnRyeWAgcHJvcGVydHkgc3BlY2lmaWVzIGEgaG9zdG5hbWUgYW5kIGFuIElQIGFkZHJlc3MgdGhhdCBhcmUgYWRkZWQgdG8gdGhlIGAvZXRjL2hvc3RzYCBmaWxlIG9mIGEgY29udGFpbmVyIHRocm91Z2ggdGhlIGBleHRyYUhvc3RzYCBwYXJhbWV0ZXIgb2YgaXRzIGBDb250YWluZXJEZWZpbml0aW9uYCByZXNvdXJjZS5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1ob3N0ZW50cnkuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgSG9zdEVudHJ5UHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGhvc3RuYW1lIHRvIHVzZSBpbiB0aGUgYC9ldGMvaG9zdHNgIGVudHJ5LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1ob3N0ZW50cnkuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWhvc3RlbnRyeS1ob3N0bmFtZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgaG9zdG5hbWU/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgSVAgYWRkcmVzcyB0byB1c2UgaW4gdGhlIGAvZXRjL2hvc3RzYCBlbnRyeS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24taG9zdGVudHJ5Lmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1ob3N0ZW50cnktaXBhZGRyZXNzXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBpcEFkZHJlc3M/OiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYEhvc3RFbnRyeVByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBIb3N0RW50cnlQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbl9Ib3N0RW50cnlQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hvc3RuYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmhvc3RuYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdpcEFkZHJlc3MnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuaXBBZGRyZXNzKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkhvc3RFbnRyeVByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLkhvc3RFbnRyeWAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgSG9zdEVudHJ5UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uSG9zdEVudHJ5YCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblRhc2tEZWZpbml0aW9uSG9zdEVudHJ5UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblRhc2tEZWZpbml0aW9uX0hvc3RFbnRyeVByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBIb3N0bmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5ob3N0bmFtZSksXG4gICAgICAgIElwQWRkcmVzczogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5pcEFkZHJlc3MpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbkhvc3RFbnRyeVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb24uSG9zdEVudHJ5UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVGFza0RlZmluaXRpb24uSG9zdEVudHJ5UHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdob3N0bmFtZScsICdIb3N0bmFtZScsIHByb3BlcnRpZXMuSG9zdG5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuSG9zdG5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2lwQWRkcmVzcycsICdJcEFkZHJlc3MnLCBwcm9wZXJ0aWVzLklwQWRkcmVzcyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5JcEFkZHJlc3MpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5UYXNrRGVmaW5pdGlvbiB7XG4gICAgLyoqXG4gICAgICogVGhlIGBIb3N0Vm9sdW1lUHJvcGVydGllc2AgcHJvcGVydHkgc3BlY2lmaWVzIGRldGFpbHMgb24gYSBjb250YWluZXIgaW5zdGFuY2UgYmluZCBtb3VudCBob3N0IHZvbHVtZS5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1ob3N0dm9sdW1lcHJvcGVydGllcy5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBIb3N0Vm9sdW1lUHJvcGVydGllc1Byb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZW4gdGhlIGBob3N0YCBwYXJhbWV0ZXIgaXMgdXNlZCwgc3BlY2lmeSBhIGBzb3VyY2VQYXRoYCB0byBkZWNsYXJlIHRoZSBwYXRoIG9uIHRoZSBob3N0IGNvbnRhaW5lciBpbnN0YW5jZSB0aGF0J3MgcHJlc2VudGVkIHRvIHRoZSBjb250YWluZXIuIElmIHRoaXMgcGFyYW1ldGVyIGlzIGVtcHR5LCB0aGVuIHRoZSBEb2NrZXIgZGFlbW9uIGhhcyBhc3NpZ25lZCBhIGhvc3QgcGF0aCBmb3IgeW91LiBJZiB0aGUgYGhvc3RgIHBhcmFtZXRlciBjb250YWlucyBhIGBzb3VyY2VQYXRoYCBmaWxlIGxvY2F0aW9uLCB0aGVuIHRoZSBkYXRhIHZvbHVtZSBwZXJzaXN0cyBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uIG9uIHRoZSBob3N0IGNvbnRhaW5lciBpbnN0YW5jZSB1bnRpbCB5b3UgZGVsZXRlIGl0IG1hbnVhbGx5LiBJZiB0aGUgYHNvdXJjZVBhdGhgIHZhbHVlIGRvZXNuJ3QgZXhpc3Qgb24gdGhlIGhvc3QgY29udGFpbmVyIGluc3RhbmNlLCB0aGUgRG9ja2VyIGRhZW1vbiBjcmVhdGVzIGl0LiBJZiB0aGUgbG9jYXRpb24gZG9lcyBleGlzdCwgdGhlIGNvbnRlbnRzIG9mIHRoZSBzb3VyY2UgcGF0aCBmb2xkZXIgYXJlIGV4cG9ydGVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB5b3UncmUgdXNpbmcgdGhlIEZhcmdhdGUgbGF1bmNoIHR5cGUsIHRoZSBgc291cmNlUGF0aGAgcGFyYW1ldGVyIGlzIG5vdCBzdXBwb3J0ZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWhvc3R2b2x1bWVwcm9wZXJ0aWVzLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1ob3N0dm9sdW1lcHJvcGVydGllcy1zb3VyY2VwYXRoXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBzb3VyY2VQYXRoPzogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBIb3N0Vm9sdW1lUHJvcGVydGllc1Byb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBIb3N0Vm9sdW1lUHJvcGVydGllc1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uX0hvc3RWb2x1bWVQcm9wZXJ0aWVzUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzb3VyY2VQYXRoJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnNvdXJjZVBhdGgpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiSG9zdFZvbHVtZVByb3BlcnRpZXNQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5Ib3N0Vm9sdW1lUHJvcGVydGllc2AgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgSG9zdFZvbHVtZVByb3BlcnRpZXNQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5Ib3N0Vm9sdW1lUHJvcGVydGllc2AgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5UYXNrRGVmaW5pdGlvbkhvc3RWb2x1bWVQcm9wZXJ0aWVzUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblRhc2tEZWZpbml0aW9uX0hvc3RWb2x1bWVQcm9wZXJ0aWVzUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIFNvdXJjZVBhdGg6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuc291cmNlUGF0aCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uSG9zdFZvbHVtZVByb3BlcnRpZXNQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblRhc2tEZWZpbml0aW9uLkhvc3RWb2x1bWVQcm9wZXJ0aWVzUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVGFza0RlZmluaXRpb24uSG9zdFZvbHVtZVByb3BlcnRpZXNQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3NvdXJjZVBhdGgnLCAnU291cmNlUGF0aCcsIHByb3BlcnRpZXMuU291cmNlUGF0aCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Tb3VyY2VQYXRoKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuVGFza0RlZmluaXRpb24ge1xuICAgIC8qKlxuICAgICAqIERldGFpbHMgb24gYW4gRWxhc3RpYyBJbmZlcmVuY2UgYWNjZWxlcmF0b3IuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1dvcmtpbmcgd2l0aCBBbWF6b24gRWxhc3RpYyBJbmZlcmVuY2Ugb24gQW1hem9uIEVDU10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvZWNzLWluZmVyZW5jZS5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWluZmVyZW5jZWFjY2VsZXJhdG9yLmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIEluZmVyZW5jZUFjY2VsZXJhdG9yUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIEVsYXN0aWMgSW5mZXJlbmNlIGFjY2VsZXJhdG9yIGRldmljZSBuYW1lLiBUaGUgYGRldmljZU5hbWVgIG11c3QgYWxzbyBiZSByZWZlcmVuY2VkIGluIGEgY29udGFpbmVyIGRlZmluaXRpb24gYXMgYSBbUmVzb3VyY2VSZXF1aXJlbWVudF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9SZXNvdXJjZVJlcXVpcmVtZW50Lmh0bWwpIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24taW5mZXJlbmNlYWNjZWxlcmF0b3IuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWluZmVyZW5jZWFjY2VsZXJhdG9yLWRldmljZW5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGRldmljZU5hbWU/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgRWxhc3RpYyBJbmZlcmVuY2UgYWNjZWxlcmF0b3IgdHlwZSB0byB1c2UuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWluZmVyZW5jZWFjY2VsZXJhdG9yLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1pbmZlcmVuY2VhY2NlbGVyYXRvci1kZXZpY2V0eXBlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBkZXZpY2VUeXBlPzogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBJbmZlcmVuY2VBY2NlbGVyYXRvclByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBJbmZlcmVuY2VBY2NlbGVyYXRvclByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uX0luZmVyZW5jZUFjY2VsZXJhdG9yUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdkZXZpY2VOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmRldmljZU5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2RldmljZVR5cGUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuZGV2aWNlVHlwZSkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJJbmZlcmVuY2VBY2NlbGVyYXRvclByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLkluZmVyZW5jZUFjY2VsZXJhdG9yYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBJbmZlcmVuY2VBY2NlbGVyYXRvclByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLkluZmVyZW5jZUFjY2VsZXJhdG9yYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblRhc2tEZWZpbml0aW9uSW5mZXJlbmNlQWNjZWxlcmF0b3JQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVGFza0RlZmluaXRpb25fSW5mZXJlbmNlQWNjZWxlcmF0b3JQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgRGV2aWNlTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5kZXZpY2VOYW1lKSxcbiAgICAgICAgRGV2aWNlVHlwZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5kZXZpY2VUeXBlKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25JbmZlcmVuY2VBY2NlbGVyYXRvclByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb24uSW5mZXJlbmNlQWNjZWxlcmF0b3JQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5UYXNrRGVmaW5pdGlvbi5JbmZlcmVuY2VBY2NlbGVyYXRvclByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZGV2aWNlTmFtZScsICdEZXZpY2VOYW1lJywgcHJvcGVydGllcy5EZXZpY2VOYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkRldmljZU5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2RldmljZVR5cGUnLCAnRGV2aWNlVHlwZScsIHByb3BlcnRpZXMuRGV2aWNlVHlwZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5EZXZpY2VUeXBlKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuVGFza0RlZmluaXRpb24ge1xuICAgIC8qKlxuICAgICAqIFRoZSBgS2VybmVsQ2FwYWJpbGl0aWVzYCBwcm9wZXJ0eSBzcGVjaWZpZXMgdGhlIExpbnV4IGNhcGFiaWxpdGllcyBmb3IgdGhlIGNvbnRhaW5lciB0aGF0IGFyZSBhZGRlZCB0byBvciBkcm9wcGVkIGZyb20gdGhlIGRlZmF1bHQgY29uZmlndXJhdGlvbiB0aGF0IGlzIHByb3ZpZGVkIGJ5IERvY2tlci4gRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhlIGRlZmF1bHQgY2FwYWJpbGl0aWVzIGFuZCB0aGUgbm9uLWRlZmF1bHQgYXZhaWxhYmxlIGNhcGFiaWxpdGllcywgc2VlIFtSdW50aW1lIHByaXZpbGVnZSBhbmQgTGludXggY2FwYWJpbGl0aWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vI3J1bnRpbWUtcHJpdmlsZWdlLWFuZC1saW51eC1jYXBhYmlsaXRpZXMpIGluIHRoZSAqRG9ja2VyIHJ1biByZWZlcmVuY2UqIC4gRm9yIG1vcmUgZGV0YWlsZWQgaW5mb3JtYXRpb24gb24gdGhlc2UgTGludXggY2FwYWJpbGl0aWVzLCBzZWUgdGhlIFtjYXBhYmlsaXRpZXMoNyldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vbWFuNy5vcmcvbGludXgvbWFuLXBhZ2VzL21hbjcvY2FwYWJpbGl0aWVzLjcuaHRtbCkgTGludXggbWFudWFsIHBhZ2UuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24ta2VybmVsY2FwYWJpbGl0aWVzLmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIEtlcm5lbENhcGFiaWxpdGllc1Byb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBMaW51eCBjYXBhYmlsaXRpZXMgZm9yIHRoZSBjb250YWluZXIgdGhhdCBoYXZlIGJlZW4gYWRkZWQgdG8gdGhlIGRlZmF1bHQgY29uZmlndXJhdGlvbiBwcm92aWRlZCBieSBEb2NrZXIuIFRoaXMgcGFyYW1ldGVyIG1hcHMgdG8gYENhcEFkZGAgaW4gdGhlIFtDcmVhdGUgYSBjb250YWluZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LyNvcGVyYXRpb24vQ29udGFpbmVyQ3JlYXRlKSBzZWN0aW9uIG9mIHRoZSBbRG9ja2VyIFJlbW90ZSBBUEldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LykgYW5kIHRoZSBgLS1jYXAtYWRkYCBvcHRpb24gdG8gW2RvY2tlciBydW5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jc2VjdXJpdHktY29uZmlndXJhdGlvbikgLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFRhc2tzIGxhdW5jaGVkIG9uIEFXUyBGYXJnYXRlIG9ubHkgc3VwcG9ydCBhZGRpbmcgdGhlIGBTWVNfUFRSQUNFYCBrZXJuZWwgY2FwYWJpbGl0eS5cbiAgICAgICAgICpcbiAgICAgICAgICogVmFsaWQgdmFsdWVzOiBgXCJBTExcIiB8IFwiQVVESVRfQ09OVFJPTFwiIHwgXCJBVURJVF9XUklURVwiIHwgXCJCTE9DS19TVVNQRU5EXCIgfCBcIkNIT1dOXCIgfCBcIkRBQ19PVkVSUklERVwiIHwgXCJEQUNfUkVBRF9TRUFSQ0hcIiB8IFwiRk9XTkVSXCIgfCBcIkZTRVRJRFwiIHwgXCJJUENfTE9DS1wiIHwgXCJJUENfT1dORVJcIiB8IFwiS0lMTFwiIHwgXCJMRUFTRVwiIHwgXCJMSU5VWF9JTU1VVEFCTEVcIiB8IFwiTUFDX0FETUlOXCIgfCBcIk1BQ19PVkVSUklERVwiIHwgXCJNS05PRFwiIHwgXCJORVRfQURNSU5cIiB8IFwiTkVUX0JJTkRfU0VSVklDRVwiIHwgXCJORVRfQlJPQURDQVNUXCIgfCBcIk5FVF9SQVdcIiB8IFwiU0VURkNBUFwiIHwgXCJTRVRHSURcIiB8IFwiU0VUUENBUFwiIHwgXCJTRVRVSURcIiB8IFwiU1lTX0FETUlOXCIgfCBcIlNZU19CT09UXCIgfCBcIlNZU19DSFJPT1RcIiB8IFwiU1lTX01PRFVMRVwiIHwgXCJTWVNfTklDRVwiIHwgXCJTWVNfUEFDQ1RcIiB8IFwiU1lTX1BUUkFDRVwiIHwgXCJTWVNfUkFXSU9cIiB8IFwiU1lTX1JFU09VUkNFXCIgfCBcIlNZU19USU1FXCIgfCBcIlNZU19UVFlfQ09ORklHXCIgfCBcIlNZU0xPR1wiIHwgXCJXQUtFX0FMQVJNXCJgXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWtlcm5lbGNhcGFiaWxpdGllcy5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24ta2VybmVsY2FwYWJpbGl0aWVzLWFkZFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgYWRkPzogc3RyaW5nW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgTGludXggY2FwYWJpbGl0aWVzIGZvciB0aGUgY29udGFpbmVyIHRoYXQgaGF2ZSBiZWVuIHJlbW92ZWQgZnJvbSB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9uIHByb3ZpZGVkIGJ5IERvY2tlci4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgQ2FwRHJvcGAgaW4gdGhlIFtDcmVhdGUgYSBjb250YWluZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LyNvcGVyYXRpb24vQ29udGFpbmVyQ3JlYXRlKSBzZWN0aW9uIG9mIHRoZSBbRG9ja2VyIFJlbW90ZSBBUEldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LykgYW5kIHRoZSBgLS1jYXAtZHJvcGAgb3B0aW9uIHRvIFtkb2NrZXIgcnVuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vI3NlY3VyaXR5LWNvbmZpZ3VyYXRpb24pIC5cbiAgICAgICAgICpcbiAgICAgICAgICogVmFsaWQgdmFsdWVzOiBgXCJBTExcIiB8IFwiQVVESVRfQ09OVFJPTFwiIHwgXCJBVURJVF9XUklURVwiIHwgXCJCTE9DS19TVVNQRU5EXCIgfCBcIkNIT1dOXCIgfCBcIkRBQ19PVkVSUklERVwiIHwgXCJEQUNfUkVBRF9TRUFSQ0hcIiB8IFwiRk9XTkVSXCIgfCBcIkZTRVRJRFwiIHwgXCJJUENfTE9DS1wiIHwgXCJJUENfT1dORVJcIiB8IFwiS0lMTFwiIHwgXCJMRUFTRVwiIHwgXCJMSU5VWF9JTU1VVEFCTEVcIiB8IFwiTUFDX0FETUlOXCIgfCBcIk1BQ19PVkVSUklERVwiIHwgXCJNS05PRFwiIHwgXCJORVRfQURNSU5cIiB8IFwiTkVUX0JJTkRfU0VSVklDRVwiIHwgXCJORVRfQlJPQURDQVNUXCIgfCBcIk5FVF9SQVdcIiB8IFwiU0VURkNBUFwiIHwgXCJTRVRHSURcIiB8IFwiU0VUUENBUFwiIHwgXCJTRVRVSURcIiB8IFwiU1lTX0FETUlOXCIgfCBcIlNZU19CT09UXCIgfCBcIlNZU19DSFJPT1RcIiB8IFwiU1lTX01PRFVMRVwiIHwgXCJTWVNfTklDRVwiIHwgXCJTWVNfUEFDQ1RcIiB8IFwiU1lTX1BUUkFDRVwiIHwgXCJTWVNfUkFXSU9cIiB8IFwiU1lTX1JFU09VUkNFXCIgfCBcIlNZU19USU1FXCIgfCBcIlNZU19UVFlfQ09ORklHXCIgfCBcIlNZU0xPR1wiIHwgXCJXQUtFX0FMQVJNXCJgXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWtlcm5lbGNhcGFiaWxpdGllcy5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24ta2VybmVsY2FwYWJpbGl0aWVzLWRyb3BcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGRyb3A/OiBzdHJpbmdbXTtcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgS2VybmVsQ2FwYWJpbGl0aWVzUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEtlcm5lbENhcGFiaWxpdGllc1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uX0tlcm5lbENhcGFiaWxpdGllc1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignYWRkJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5hZGQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2Ryb3AnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLmRyb3ApKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiS2VybmVsQ2FwYWJpbGl0aWVzUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uS2VybmVsQ2FwYWJpbGl0aWVzYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBLZXJuZWxDYXBhYmlsaXRpZXNQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5LZXJuZWxDYXBhYmlsaXRpZXNgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuVGFza0RlZmluaXRpb25LZXJuZWxDYXBhYmlsaXRpZXNQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVGFza0RlZmluaXRpb25fS2VybmVsQ2FwYWJpbGl0aWVzUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEFkZDogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuYWRkKSxcbiAgICAgICAgRHJvcDogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuZHJvcCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uS2VybmVsQ2FwYWJpbGl0aWVzUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5UYXNrRGVmaW5pdGlvbi5LZXJuZWxDYXBhYmlsaXRpZXNQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5UYXNrRGVmaW5pdGlvbi5LZXJuZWxDYXBhYmlsaXRpZXNQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2FkZCcsICdBZGQnLCBwcm9wZXJ0aWVzLkFkZCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmdBcnJheShwcm9wZXJ0aWVzLkFkZCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZHJvcCcsICdEcm9wJywgcHJvcGVydGllcy5Ecm9wICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuRHJvcCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblRhc2tEZWZpbml0aW9uIHtcbiAgICAvKipcbiAgICAgKiBBIGtleS12YWx1ZSBwYWlyIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1rZXl2YWx1ZXBhaXIuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgS2V5VmFsdWVQYWlyUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5hbWUgb2YgdGhlIGtleS12YWx1ZSBwYWlyLiBGb3IgZW52aXJvbm1lbnQgdmFyaWFibGVzLCB0aGlzIGlzIHRoZSBuYW1lIG9mIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24ta2V5dmFsdWVwYWlyLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1rZXl2YWx1ZXBhaXItbmFtZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbmFtZT86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2YWx1ZSBvZiB0aGUga2V5LXZhbHVlIHBhaXIuIEZvciBlbnZpcm9ubWVudCB2YXJpYWJsZXMsIHRoaXMgaXMgdGhlIHZhbHVlIG9mIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24ta2V5dmFsdWVwYWlyLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1rZXl2YWx1ZXBhaXItdmFsdWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHZhbHVlPzogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBLZXlWYWx1ZVBhaXJQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgS2V5VmFsdWVQYWlyUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25fS2V5VmFsdWVQYWlyUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCduYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLm5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3ZhbHVlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnZhbHVlKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIktleVZhbHVlUGFpclByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLktleVZhbHVlUGFpcmAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgS2V5VmFsdWVQYWlyUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uS2V5VmFsdWVQYWlyYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblRhc2tEZWZpbml0aW9uS2V5VmFsdWVQYWlyUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblRhc2tEZWZpbml0aW9uX0tleVZhbHVlUGFpclByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm5hbWUpLFxuICAgICAgICBWYWx1ZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy52YWx1ZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uS2V5VmFsdWVQYWlyUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5UYXNrRGVmaW5pdGlvbi5LZXlWYWx1ZVBhaXJQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5UYXNrRGVmaW5pdGlvbi5LZXlWYWx1ZVBhaXJQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ25hbWUnLCAnTmFtZScsIHByb3BlcnRpZXMuTmFtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5OYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd2YWx1ZScsICdWYWx1ZScsIHByb3BlcnRpZXMuVmFsdWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuVmFsdWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5UYXNrRGVmaW5pdGlvbiB7XG4gICAgLyoqXG4gICAgICogVGhlIExpbnV4LXNwZWNpZmljIG9wdGlvbnMgdGhhdCBhcmUgYXBwbGllZCB0byB0aGUgY29udGFpbmVyLCBzdWNoIGFzIExpbnV4IFtLZXJuZWxDYXBhYmlsaXRpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfS2VybmVsQ2FwYWJpbGl0aWVzLmh0bWwpIC5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1saW51eHBhcmFtZXRlcnMuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgTGludXhQYXJhbWV0ZXJzUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIExpbnV4IGNhcGFiaWxpdGllcyBmb3IgdGhlIGNvbnRhaW5lciB0aGF0IGFyZSBhZGRlZCB0byBvciBkcm9wcGVkIGZyb20gdGhlIGRlZmF1bHQgY29uZmlndXJhdGlvbiBwcm92aWRlZCBieSBEb2NrZXIuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gRm9yIHRhc2tzIHRoYXQgdXNlIHRoZSBGYXJnYXRlIGxhdW5jaCB0eXBlLCBgY2FwYWJpbGl0aWVzYCBpcyBzdXBwb3J0ZWQgZm9yIGFsbCBwbGF0Zm9ybSB2ZXJzaW9ucyBidXQgdGhlIGBhZGRgIHBhcmFtZXRlciBpcyBvbmx5IHN1cHBvcnRlZCBpZiB1c2luZyBwbGF0Zm9ybSB2ZXJzaW9uIDEuNC4wIG9yIGxhdGVyLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1saW51eHBhcmFtZXRlcnMuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWxpbnV4cGFyYW1ldGVycy1jYXBhYmlsaXRpZXNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNhcGFiaWxpdGllcz86IENmblRhc2tEZWZpbml0aW9uLktlcm5lbENhcGFiaWxpdGllc1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogQW55IGhvc3QgZGV2aWNlcyB0byBleHBvc2UgdG8gdGhlIGNvbnRhaW5lci4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byBgRGV2aWNlc2AgaW4gdGhlIFtDcmVhdGUgYSBjb250YWluZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LyNvcGVyYXRpb24vQ29udGFpbmVyQ3JlYXRlKSBzZWN0aW9uIG9mIHRoZSBbRG9ja2VyIFJlbW90ZSBBUEldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvYXBpL3YxLjM1LykgYW5kIHRoZSBgLS1kZXZpY2VgIG9wdGlvbiB0byBbZG9ja2VyIHJ1bl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9yZWZlcmVuY2UvcnVuLyNzZWN1cml0eS1jb25maWd1cmF0aW9uKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gSWYgeW91J3JlIHVzaW5nIHRhc2tzIHRoYXQgdXNlIHRoZSBGYXJnYXRlIGxhdW5jaCB0eXBlLCB0aGUgYGRldmljZXNgIHBhcmFtZXRlciBpc24ndCBzdXBwb3J0ZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWxpbnV4cGFyYW1ldGVycy5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tbGludXhwYXJhbWV0ZXJzLWRldmljZXNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGRldmljZXM/OiBBcnJheTxDZm5UYXNrRGVmaW5pdGlvbi5EZXZpY2VQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSdW4gYW4gYGluaXRgIHByb2Nlc3MgaW5zaWRlIHRoZSBjb250YWluZXIgdGhhdCBmb3J3YXJkcyBzaWduYWxzIGFuZCByZWFwcyBwcm9jZXNzZXMuIFRoaXMgcGFyYW1ldGVyIG1hcHMgdG8gdGhlIGAtLWluaXRgIG9wdGlvbiB0byBbZG9ja2VyIHJ1bl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9yZWZlcmVuY2UvcnVuLyNzZWN1cml0eS1jb25maWd1cmF0aW9uKSAuIFRoaXMgcGFyYW1ldGVyIHJlcXVpcmVzIHZlcnNpb24gMS4yNSBvZiB0aGUgRG9ja2VyIFJlbW90ZSBBUEkgb3IgZ3JlYXRlciBvbiB5b3VyIGNvbnRhaW5lciBpbnN0YW5jZS4gVG8gY2hlY2sgdGhlIERvY2tlciBSZW1vdGUgQVBJIHZlcnNpb24gb24geW91ciBjb250YWluZXIgaW5zdGFuY2UsIGxvZyBpbiB0byB5b3VyIGNvbnRhaW5lciBpbnN0YW5jZSBhbmQgcnVuIHRoZSBmb2xsb3dpbmcgY29tbWFuZDogYHN1ZG8gZG9ja2VyIHZlcnNpb24gLS1mb3JtYXQgJ3t7LlNlcnZlci5BUElWZXJzaW9ufX0nYFxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1saW51eHBhcmFtZXRlcnMuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWxpbnV4cGFyYW1ldGVycy1pbml0cHJvY2Vzc2VuYWJsZWRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGluaXRQcm9jZXNzRW5hYmxlZD86IGJvb2xlYW4gfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdG90YWwgYW1vdW50IG9mIHN3YXAgbWVtb3J5IChpbiBNaUIpIGEgY29udGFpbmVyIGNhbiB1c2UuIFRoaXMgcGFyYW1ldGVyIHdpbGwgYmUgdHJhbnNsYXRlZCB0byB0aGUgYC0tbWVtb3J5LXN3YXBgIG9wdGlvbiB0byBbZG9ja2VyIHJ1bl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9yZWZlcmVuY2UvcnVuLyNzZWN1cml0eS1jb25maWd1cmF0aW9uKSB3aGVyZSB0aGUgdmFsdWUgd291bGQgYmUgdGhlIHN1bSBvZiB0aGUgY29udGFpbmVyIG1lbW9yeSBwbHVzIHRoZSBgbWF4U3dhcGAgdmFsdWUuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIGEgYG1heFN3YXBgIHZhbHVlIG9mIGAwYCBpcyBzcGVjaWZpZWQsIHRoZSBjb250YWluZXIgd2lsbCBub3QgdXNlIHN3YXAuIEFjY2VwdGVkIHZhbHVlcyBhcmUgYDBgIG9yIGFueSBwb3NpdGl2ZSBpbnRlZ2VyLiBJZiB0aGUgYG1heFN3YXBgIHBhcmFtZXRlciBpcyBvbWl0dGVkLCB0aGUgY29udGFpbmVyIHdpbGwgdXNlIHRoZSBzd2FwIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBjb250YWluZXIgaW5zdGFuY2UgaXQgaXMgcnVubmluZyBvbi4gQSBgbWF4U3dhcGAgdmFsdWUgbXVzdCBiZSBzZXQgZm9yIHRoZSBgc3dhcHBpbmVzc2AgcGFyYW1ldGVyIHRvIGJlIHVzZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gSWYgeW91J3JlIHVzaW5nIHRhc2tzIHRoYXQgdXNlIHRoZSBGYXJnYXRlIGxhdW5jaCB0eXBlLCB0aGUgYG1heFN3YXBgIHBhcmFtZXRlciBpc24ndCBzdXBwb3J0ZWQuXG4gICAgICAgICAqID5cbiAgICAgICAgICogPiBJZiB5b3UncmUgdXNpbmcgdGFza3Mgb24gQW1hem9uIExpbnV4IDIwMjMgdGhlIGBzd2FwcGluZXNzYCBwYXJhbWV0ZXIgaXNuJ3Qgc3VwcG9ydGVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1saW51eHBhcmFtZXRlcnMuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWxpbnV4cGFyYW1ldGVycy1tYXhzd2FwXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBtYXhTd2FwPzogbnVtYmVyO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHZhbHVlIGZvciB0aGUgc2l6ZSAoaW4gTWlCKSBvZiB0aGUgYC9kZXYvc2htYCB2b2x1bWUuIFRoaXMgcGFyYW1ldGVyIG1hcHMgdG8gdGhlIGAtLXNobS1zaXplYCBvcHRpb24gdG8gW2RvY2tlciBydW5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jc2VjdXJpdHktY29uZmlndXJhdGlvbikgLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IElmIHlvdSBhcmUgdXNpbmcgdGFza3MgdGhhdCB1c2UgdGhlIEZhcmdhdGUgbGF1bmNoIHR5cGUsIHRoZSBgc2hhcmVkTWVtb3J5U2l6ZWAgcGFyYW1ldGVyIGlzIG5vdCBzdXBwb3J0ZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWxpbnV4cGFyYW1ldGVycy5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tbGludXhwYXJhbWV0ZXJzLXNoYXJlZG1lbW9yeXNpemVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHNoYXJlZE1lbW9yeVNpemU/OiBudW1iZXI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGlzIGFsbG93cyB5b3UgdG8gdHVuZSBhIGNvbnRhaW5lcidzIG1lbW9yeSBzd2FwcGluZXNzIGJlaGF2aW9yLiBBIGBzd2FwcGluZXNzYCB2YWx1ZSBvZiBgMGAgd2lsbCBjYXVzZSBzd2FwcGluZyB0byBub3QgaGFwcGVuIHVubGVzcyBhYnNvbHV0ZWx5IG5lY2Vzc2FyeS4gQSBgc3dhcHBpbmVzc2AgdmFsdWUgb2YgYDEwMGAgd2lsbCBjYXVzZSBwYWdlcyB0byBiZSBzd2FwcGVkIHZlcnkgYWdncmVzc2l2ZWx5LiBBY2NlcHRlZCB2YWx1ZXMgYXJlIHdob2xlIG51bWJlcnMgYmV0d2VlbiBgMGAgYW5kIGAxMDBgIC4gSWYgdGhlIGBzd2FwcGluZXNzYCBwYXJhbWV0ZXIgaXMgbm90IHNwZWNpZmllZCwgYSBkZWZhdWx0IHZhbHVlIG9mIGA2MGAgaXMgdXNlZC4gSWYgYSB2YWx1ZSBpcyBub3Qgc3BlY2lmaWVkIGZvciBgbWF4U3dhcGAgdGhlbiB0aGlzIHBhcmFtZXRlciBpcyBpZ25vcmVkLiBUaGlzIHBhcmFtZXRlciBtYXBzIHRvIHRoZSBgLS1tZW1vcnktc3dhcHBpbmVzc2Agb3B0aW9uIHRvIFtkb2NrZXIgcnVuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL3JlZmVyZW5jZS9ydW4vI3NlY3VyaXR5LWNvbmZpZ3VyYXRpb24pIC5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBJZiB5b3UncmUgdXNpbmcgdGFza3MgdGhhdCB1c2UgdGhlIEZhcmdhdGUgbGF1bmNoIHR5cGUsIHRoZSBgc3dhcHBpbmVzc2AgcGFyYW1ldGVyIGlzbid0IHN1cHBvcnRlZC5cbiAgICAgICAgICogPlxuICAgICAgICAgKiA+IElmIHlvdSdyZSB1c2luZyB0YXNrcyBvbiBBbWF6b24gTGludXggMjAyMyB0aGUgYHN3YXBwaW5lc3NgIHBhcmFtZXRlciBpc24ndCBzdXBwb3J0ZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWxpbnV4cGFyYW1ldGVycy5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tbGludXhwYXJhbWV0ZXJzLXN3YXBwaW5lc3NcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHN3YXBwaW5lc3M/OiBudW1iZXI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY29udGFpbmVyIHBhdGgsIG1vdW50IG9wdGlvbnMsIGFuZCBzaXplIChpbiBNaUIpIG9mIHRoZSB0bXBmcyBtb3VudC4gVGhpcyBwYXJhbWV0ZXIgbWFwcyB0byB0aGUgYC0tdG1wZnNgIG9wdGlvbiB0byBbZG9ja2VyIHJ1bl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9yZWZlcmVuY2UvcnVuLyNzZWN1cml0eS1jb25maWd1cmF0aW9uKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gSWYgeW91J3JlIHVzaW5nIHRhc2tzIHRoYXQgdXNlIHRoZSBGYXJnYXRlIGxhdW5jaCB0eXBlLCB0aGUgYHRtcGZzYCBwYXJhbWV0ZXIgaXNuJ3Qgc3VwcG9ydGVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1saW51eHBhcmFtZXRlcnMuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWxpbnV4cGFyYW1ldGVycy10bXBmc1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgdG1wZnM/OiBBcnJheTxDZm5UYXNrRGVmaW5pdGlvbi5UbXBmc1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgTGludXhQYXJhbWV0ZXJzUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYExpbnV4UGFyYW1ldGVyc1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uX0xpbnV4UGFyYW1ldGVyc1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY2FwYWJpbGl0aWVzJywgQ2ZuVGFza0RlZmluaXRpb25fS2VybmVsQ2FwYWJpbGl0aWVzUHJvcGVydHlWYWxpZGF0b3IpKHByb3BlcnRpZXMuY2FwYWJpbGl0aWVzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdkZXZpY2VzJywgY2RrLmxpc3RWYWxpZGF0b3IoQ2ZuVGFza0RlZmluaXRpb25fRGV2aWNlUHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLmRldmljZXMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2luaXRQcm9jZXNzRW5hYmxlZCcsIGNkay52YWxpZGF0ZUJvb2xlYW4pKHByb3BlcnRpZXMuaW5pdFByb2Nlc3NFbmFibGVkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdtYXhTd2FwJywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLm1heFN3YXApKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3NoYXJlZE1lbW9yeVNpemUnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMuc2hhcmVkTWVtb3J5U2l6ZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc3dhcHBpbmVzcycsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5zd2FwcGluZXNzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0bXBmcycsIGNkay5saXN0VmFsaWRhdG9yKENmblRhc2tEZWZpbml0aW9uX1RtcGZzUHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLnRtcGZzKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkxpbnV4UGFyYW1ldGVyc1Byb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLkxpbnV4UGFyYW1ldGVyc2AgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgTGludXhQYXJhbWV0ZXJzUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uTGludXhQYXJhbWV0ZXJzYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblRhc2tEZWZpbml0aW9uTGludXhQYXJhbWV0ZXJzUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblRhc2tEZWZpbml0aW9uX0xpbnV4UGFyYW1ldGVyc1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBDYXBhYmlsaXRpZXM6IGNmblRhc2tEZWZpbml0aW9uS2VybmVsQ2FwYWJpbGl0aWVzUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY2FwYWJpbGl0aWVzKSxcbiAgICAgICAgRGV2aWNlczogY2RrLmxpc3RNYXBwZXIoY2ZuVGFza0RlZmluaXRpb25EZXZpY2VQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuZGV2aWNlcyksXG4gICAgICAgIEluaXRQcm9jZXNzRW5hYmxlZDogY2RrLmJvb2xlYW5Ub0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaW5pdFByb2Nlc3NFbmFibGVkKSxcbiAgICAgICAgTWF4U3dhcDogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5tYXhTd2FwKSxcbiAgICAgICAgU2hhcmVkTWVtb3J5U2l6ZTogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zaGFyZWRNZW1vcnlTaXplKSxcbiAgICAgICAgU3dhcHBpbmVzczogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zd2FwcGluZXNzKSxcbiAgICAgICAgVG1wZnM6IGNkay5saXN0TWFwcGVyKGNmblRhc2tEZWZpbml0aW9uVG1wZnNQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMudG1wZnMpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbkxpbnV4UGFyYW1ldGVyc1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb24uTGludXhQYXJhbWV0ZXJzUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVGFza0RlZmluaXRpb24uTGludXhQYXJhbWV0ZXJzUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjYXBhYmlsaXRpZXMnLCAnQ2FwYWJpbGl0aWVzJywgcHJvcGVydGllcy5DYXBhYmlsaXRpZXMgIT0gbnVsbCA/IENmblRhc2tEZWZpbml0aW9uS2VybmVsQ2FwYWJpbGl0aWVzUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5DYXBhYmlsaXRpZXMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2RldmljZXMnLCAnRGV2aWNlcycsIHByb3BlcnRpZXMuRGV2aWNlcyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5UYXNrRGVmaW5pdGlvbkRldmljZVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLkRldmljZXMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2luaXRQcm9jZXNzRW5hYmxlZCcsICdJbml0UHJvY2Vzc0VuYWJsZWQnLCBwcm9wZXJ0aWVzLkluaXRQcm9jZXNzRW5hYmxlZCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRCb29sZWFuKHByb3BlcnRpZXMuSW5pdFByb2Nlc3NFbmFibGVkKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdtYXhTd2FwJywgJ01heFN3YXAnLCBwcm9wZXJ0aWVzLk1heFN3YXAgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuTWF4U3dhcCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnc2hhcmVkTWVtb3J5U2l6ZScsICdTaGFyZWRNZW1vcnlTaXplJywgcHJvcGVydGllcy5TaGFyZWRNZW1vcnlTaXplICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLlNoYXJlZE1lbW9yeVNpemUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3N3YXBwaW5lc3MnLCAnU3dhcHBpbmVzcycsIHByb3BlcnRpZXMuU3dhcHBpbmVzcyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5Td2FwcGluZXNzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0bXBmcycsICdUbXBmcycsIHByb3BlcnRpZXMuVG1wZnMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoQ2ZuVGFza0RlZmluaXRpb25UbXBmc1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLlRtcGZzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuVGFza0RlZmluaXRpb24ge1xuICAgIC8qKlxuICAgICAqIFRoZSBgTG9nQ29uZmlndXJhdGlvbmAgcHJvcGVydHkgc3BlY2lmaWVzIGxvZyBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gc2VuZCB0byBhIGN1c3RvbSBsb2cgZHJpdmVyIGZvciB0aGUgY29udGFpbmVyLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWxvZ2NvbmZpZ3VyYXRpb24uaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgTG9nQ29uZmlndXJhdGlvblByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBsb2cgZHJpdmVyIHRvIHVzZSBmb3IgdGhlIGNvbnRhaW5lci5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIHRhc2tzIG9uIEFXUyBGYXJnYXRlICwgdGhlIHN1cHBvcnRlZCBsb2cgZHJpdmVycyBhcmUgYGF3c2xvZ3NgICwgYHNwbHVua2AgLCBhbmQgYGF3c2ZpcmVsZW5zYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEZvciB0YXNrcyBob3N0ZWQgb24gQW1hem9uIEVDMiBpbnN0YW5jZXMsIHRoZSBzdXBwb3J0ZWQgbG9nIGRyaXZlcnMgYXJlIGBhd3Nsb2dzYCAsIGBmbHVlbnRkYCAsIGBnZWxmYCAsIGBqc29uLWZpbGVgICwgYGpvdXJuYWxkYCAsIGBsb2dlbnRyaWVzYCAsIGBzeXNsb2dgICwgYHNwbHVua2AgLCBhbmQgYGF3c2ZpcmVsZW5zYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHVzaW5nIHRoZSBgYXdzbG9nc2AgbG9nIGRyaXZlciwgc2VlIFtVc2luZyB0aGUgYXdzbG9ncyBsb2cgZHJpdmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS91c2luZ19hd3Nsb2dzLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHVzaW5nIHRoZSBgYXdzZmlyZWxlbnNgIGxvZyBkcml2ZXIsIHNlZSBbQ3VzdG9tIGxvZyByb3V0aW5nXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS91c2luZ19maXJlbGVucy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IElmIHlvdSBoYXZlIGEgY3VzdG9tIGRyaXZlciB0aGF0IGlzbid0IGxpc3RlZCwgeW91IGNhbiBmb3JrIHRoZSBBbWF6b24gRUNTIGNvbnRhaW5lciBhZ2VudCBwcm9qZWN0IHRoYXQncyBbYXZhaWxhYmxlIG9uIEdpdEh1Yl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYW1hem9uLWVjcy1hZ2VudCkgYW5kIGN1c3RvbWl6ZSBpdCB0byB3b3JrIHdpdGggdGhhdCBkcml2ZXIuIFdlIGVuY291cmFnZSB5b3UgdG8gc3VibWl0IHB1bGwgcmVxdWVzdHMgZm9yIGNoYW5nZXMgdGhhdCB5b3Ugd291bGQgbGlrZSB0byBoYXZlIGluY2x1ZGVkLiBIb3dldmVyLCB3ZSBkb24ndCBjdXJyZW50bHkgcHJvdmlkZSBzdXBwb3J0IGZvciBydW5uaW5nIG1vZGlmaWVkIGNvcGllcyBvZiB0aGlzIHNvZnR3YXJlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1sb2djb25maWd1cmF0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1sb2djb25maWd1cmF0aW9uLWxvZ2RyaXZlclxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbG9nRHJpdmVyOiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHNlbmQgdG8gdGhlIGxvZyBkcml2ZXIuIFRoaXMgcGFyYW1ldGVyIHJlcXVpcmVzIHZlcnNpb24gMS4xOSBvZiB0aGUgRG9ja2VyIFJlbW90ZSBBUEkgb3IgZ3JlYXRlciBvbiB5b3VyIGNvbnRhaW5lciBpbnN0YW5jZS4gVG8gY2hlY2sgdGhlIERvY2tlciBSZW1vdGUgQVBJIHZlcnNpb24gb24geW91ciBjb250YWluZXIgaW5zdGFuY2UsIGxvZyBpbiB0byB5b3VyIGNvbnRhaW5lciBpbnN0YW5jZSBhbmQgcnVuIHRoZSBmb2xsb3dpbmcgY29tbWFuZDogYHN1ZG8gZG9ja2VyIHZlcnNpb24gLS1mb3JtYXQgJ3t7LlNlcnZlci5BUElWZXJzaW9ufX0nYFxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9ucy1sb2djb25maWd1cmF0aW9uLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1jb250YWluZXJkZWZpbml0aW9uLWxvZ2NvbmZpZ3VyYXRpb24tb3B0aW9uc1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgb3B0aW9ucz86IHsgW2tleTogc3RyaW5nXTogKHN0cmluZykgfSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzZWNyZXRzIHRvIHBhc3MgdG8gdGhlIGxvZyBjb25maWd1cmF0aW9uLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtTcGVjaWZ5aW5nIHNlbnNpdGl2ZSBkYXRhXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zcGVjaWZ5aW5nLXNlbnNpdGl2ZS1kYXRhLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLWxvZ2NvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLWxvZ2NvbmZpZ3VyYXRpb24tc2VjcmV0b3B0aW9uc1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgc2VjcmV0T3B0aW9ucz86IEFycmF5PENmblRhc2tEZWZpbml0aW9uLlNlY3JldFByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgTG9nQ29uZmlndXJhdGlvblByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBMb2dDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25fTG9nQ29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbG9nRHJpdmVyJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmxvZ0RyaXZlcikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbG9nRHJpdmVyJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmxvZ0RyaXZlcikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignb3B0aW9ucycsIGNkay5oYXNoVmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMub3B0aW9ucykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc2VjcmV0T3B0aW9ucycsIGNkay5saXN0VmFsaWRhdG9yKENmblRhc2tEZWZpbml0aW9uX1NlY3JldFByb3BlcnR5VmFsaWRhdG9yKSkocHJvcGVydGllcy5zZWNyZXRPcHRpb25zKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkxvZ0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5Mb2dDb25maWd1cmF0aW9uYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBMb2dDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uTG9nQ29uZmlndXJhdGlvbmAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5UYXNrRGVmaW5pdGlvbkxvZ0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVGFza0RlZmluaXRpb25fTG9nQ29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBMb2dEcml2ZXI6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubG9nRHJpdmVyKSxcbiAgICAgICAgT3B0aW9uczogY2RrLmhhc2hNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMub3B0aW9ucyksXG4gICAgICAgIFNlY3JldE9wdGlvbnM6IGNkay5saXN0TWFwcGVyKGNmblRhc2tEZWZpbml0aW9uU2VjcmV0UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnNlY3JldE9wdGlvbnMpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbkxvZ0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblRhc2tEZWZpbml0aW9uLkxvZ0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5UYXNrRGVmaW5pdGlvbi5Mb2dDb25maWd1cmF0aW9uUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdsb2dEcml2ZXInLCAnTG9nRHJpdmVyJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Mb2dEcml2ZXIpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ29wdGlvbnMnLCAnT3B0aW9ucycsIHByb3BlcnRpZXMuT3B0aW9ucyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRNYXAoY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcpKHByb3BlcnRpZXMuT3B0aW9ucykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnc2VjcmV0T3B0aW9ucycsICdTZWNyZXRPcHRpb25zJywgcHJvcGVydGllcy5TZWNyZXRPcHRpb25zICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KENmblRhc2tEZWZpbml0aW9uU2VjcmV0UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuU2VjcmV0T3B0aW9ucykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblRhc2tEZWZpbml0aW9uIHtcbiAgICAvKipcbiAgICAgKiBUaGUgZGV0YWlscyBmb3IgYSB2b2x1bWUgbW91bnQgcG9pbnQgdGhhdCdzIHVzZWQgaW4gYSBjb250YWluZXIgZGVmaW5pdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1tb3VudHBvaW50Lmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIE1vdW50UG9pbnRQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcGF0aCBvbiB0aGUgY29udGFpbmVyIHRvIG1vdW50IHRoZSBob3N0IHZvbHVtZSBhdC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tbW91bnRwb2ludC5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tbW91bnRwb2ludC1jb250YWluZXJwYXRoXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBjb250YWluZXJQYXRoPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogSWYgdGhpcyB2YWx1ZSBpcyBgdHJ1ZWAgLCB0aGUgY29udGFpbmVyIGhhcyByZWFkLW9ubHkgYWNjZXNzIHRvIHRoZSB2b2x1bWUuIElmIHRoaXMgdmFsdWUgaXMgYGZhbHNlYCAsIHRoZW4gdGhlIGNvbnRhaW5lciBjYW4gd3JpdGUgdG8gdGhlIHZvbHVtZS4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgYGZhbHNlYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLW1vdW50cG9pbnQuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLW1vdW50cG9pbnQtcmVhZG9ubHlcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHJlYWRPbmx5PzogYm9vbGVhbiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBuYW1lIG9mIHRoZSB2b2x1bWUgdG8gbW91bnQuIE11c3QgYmUgYSB2b2x1bWUgbmFtZSByZWZlcmVuY2VkIGluIHRoZSBgbmFtZWAgcGFyYW1ldGVyIG9mIHRhc2sgZGVmaW5pdGlvbiBgdm9sdW1lYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLW1vdW50cG9pbnQuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLW1vdW50cG9pbnQtc291cmNldm9sdW1lXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBzb3VyY2VWb2x1bWU/OiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYE1vdW50UG9pbnRQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgTW91bnRQb2ludFByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uX01vdW50UG9pbnRQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvbnRhaW5lclBhdGgnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY29udGFpbmVyUGF0aCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncmVhZE9ubHknLCBjZGsudmFsaWRhdGVCb29sZWFuKShwcm9wZXJ0aWVzLnJlYWRPbmx5KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzb3VyY2VWb2x1bWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuc291cmNlVm9sdW1lKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIk1vdW50UG9pbnRQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5Nb3VudFBvaW50YCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBNb3VudFBvaW50UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uTW91bnRQb2ludGAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5UYXNrRGVmaW5pdGlvbk1vdW50UG9pbnRQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVGFza0RlZmluaXRpb25fTW91bnRQb2ludFByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBDb250YWluZXJQYXRoOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNvbnRhaW5lclBhdGgpLFxuICAgICAgICBSZWFkT25seTogY2RrLmJvb2xlYW5Ub0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucmVhZE9ubHkpLFxuICAgICAgICBTb3VyY2VWb2x1bWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuc291cmNlVm9sdW1lKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25Nb3VudFBvaW50UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5UYXNrRGVmaW5pdGlvbi5Nb3VudFBvaW50UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVGFza0RlZmluaXRpb24uTW91bnRQb2ludFByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY29udGFpbmVyUGF0aCcsICdDb250YWluZXJQYXRoJywgcHJvcGVydGllcy5Db250YWluZXJQYXRoICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNvbnRhaW5lclBhdGgpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3JlYWRPbmx5JywgJ1JlYWRPbmx5JywgcHJvcGVydGllcy5SZWFkT25seSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRCb29sZWFuKHByb3BlcnRpZXMuUmVhZE9ubHkpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3NvdXJjZVZvbHVtZScsICdTb3VyY2VWb2x1bWUnLCBwcm9wZXJ0aWVzLlNvdXJjZVZvbHVtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Tb3VyY2VWb2x1bWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5UYXNrRGVmaW5pdGlvbiB7XG4gICAgLyoqXG4gICAgICogVGhlIGBQb3J0TWFwcGluZ2AgcHJvcGVydHkgc3BlY2lmaWVzIGEgcG9ydCBtYXBwaW5nLiBQb3J0IG1hcHBpbmdzIGFsbG93IGNvbnRhaW5lcnMgdG8gYWNjZXNzIHBvcnRzIG9uIHRoZSBob3N0IGNvbnRhaW5lciBpbnN0YW5jZSB0byBzZW5kIG9yIHJlY2VpdmUgdHJhZmZpYy4gUG9ydCBtYXBwaW5ncyBhcmUgc3BlY2lmaWVkIGFzIHBhcnQgb2YgdGhlIGNvbnRhaW5lciBkZWZpbml0aW9uLlxuICAgICAqXG4gICAgICogSWYgeW91IGFyZSB1c2luZyBjb250YWluZXJzIGluIGEgdGFzayB3aXRoIHRoZSBgYXdzdnBjYCBvciBgaG9zdGAgbmV0d29yayBtb2RlLCBleHBvc2VkIHBvcnRzIHNob3VsZCBiZSBzcGVjaWZpZWQgdXNpbmcgYGNvbnRhaW5lclBvcnRgIC4gVGhlIGBob3N0UG9ydGAgY2FuIGJlIGxlZnQgYmxhbmsgb3IgaXQgbXVzdCBiZSB0aGUgc2FtZSB2YWx1ZSBhcyB0aGUgYGNvbnRhaW5lclBvcnRgIC5cbiAgICAgKlxuICAgICAqIEFmdGVyIGEgdGFzayByZWFjaGVzIHRoZSBgUlVOTklOR2Agc3RhdHVzLCBtYW51YWwgYW5kIGF1dG9tYXRpYyBob3N0IGFuZCBjb250YWluZXIgcG9ydCBhc3NpZ25tZW50cyBhcmUgdmlzaWJsZSBpbiB0aGUgYG5ldHdvcmtCaW5kaW5nc2Agc2VjdGlvbiBvZiBbRGVzY3JpYmVUYXNrc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVRhc2tzLmh0bWwpIEFQSSByZXNwb25zZXMuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tcG9ydG1hcHBpbmcuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgUG9ydE1hcHBpbmdQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYXBwbGljYXRpb24gcHJvdG9jb2wgdGhhdCdzIHVzZWQgZm9yIHRoZSBwb3J0IG1hcHBpbmcuIFRoaXMgcGFyYW1ldGVyIG9ubHkgYXBwbGllcyB0byBTZXJ2aWNlIENvbm5lY3QuIFdlIHJlY29tbWVuZCB0aGF0IHlvdSBzZXQgdGhpcyBwYXJhbWV0ZXIgdG8gYmUgY29uc2lzdGVudCB3aXRoIHRoZSBwcm90b2NvbCB0aGF0IHlvdXIgYXBwbGljYXRpb24gdXNlcy4gSWYgeW91IHNldCB0aGlzIHBhcmFtZXRlciwgQW1hem9uIEVDUyBhZGRzIHByb3RvY29sLXNwZWNpZmljIGNvbm5lY3Rpb24gaGFuZGxpbmcgdG8gdGhlIFNlcnZpY2UgQ29ubmVjdCBwcm94eS4gSWYgeW91IHNldCB0aGlzIHBhcmFtZXRlciwgQW1hem9uIEVDUyBhZGRzIHByb3RvY29sLXNwZWNpZmljIHRlbGVtZXRyeSBpbiB0aGUgQW1hem9uIEVDUyBjb25zb2xlIGFuZCBDbG91ZFdhdGNoLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB5b3UgZG9uJ3Qgc2V0IGEgdmFsdWUgZm9yIHRoaXMgcGFyYW1ldGVyLCB0aGVuIFRDUCBpcyB1c2VkLiBIb3dldmVyLCBBbWF6b24gRUNTIGRvZXNuJ3QgYWRkIHByb3RvY29sLXNwZWNpZmljIHRlbGVtZXRyeSBmb3IgVENQLlxuICAgICAgICAgKlxuICAgICAgICAgKiBUYXNrcyB0aGF0IHJ1biBpbiBhIG5hbWVzcGFjZSBjYW4gdXNlIHNob3J0IG5hbWVzIHRvIGNvbm5lY3QgdG8gc2VydmljZXMgaW4gdGhlIG5hbWVzcGFjZS4gVGFza3MgY2FuIGNvbm5lY3QgdG8gc2VydmljZXMgYWNyb3NzIGFsbCBvZiB0aGUgY2x1c3RlcnMgaW4gdGhlIG5hbWVzcGFjZS4gVGFza3MgY29ubmVjdCB0aHJvdWdoIGEgbWFuYWdlZCBwcm94eSBjb250YWluZXIgdGhhdCBjb2xsZWN0cyBsb2dzIGFuZCBtZXRyaWNzIGZvciBpbmNyZWFzZWQgdmlzaWJpbGl0eS4gT25seSB0aGUgdGFza3MgdGhhdCBBbWF6b24gRUNTIHNlcnZpY2VzIGNyZWF0ZSBhcmUgc3VwcG9ydGVkIHdpdGggU2VydmljZSBDb25uZWN0LiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtTZXJ2aWNlIENvbm5lY3RdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3NlcnZpY2UtY29ubmVjdC5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1wb3J0bWFwcGluZy5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tcG9ydG1hcHBpbmctYXBwcHJvdG9jb2xcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGFwcFByb3RvY29sPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHBvcnQgbnVtYmVyIG9uIHRoZSBjb250YWluZXIgdGhhdCdzIGJvdW5kIHRvIHRoZSB1c2VyLXNwZWNpZmllZCBvciBhdXRvbWF0aWNhbGx5IGFzc2lnbmVkIGhvc3QgcG9ydC5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgeW91IHVzZSBjb250YWluZXJzIGluIGEgdGFzayB3aXRoIHRoZSBgYXdzdnBjYCBvciBgaG9zdGAgbmV0d29yayBtb2RlLCBzcGVjaWZ5IHRoZSBleHBvc2VkIHBvcnRzIHVzaW5nIGBjb250YWluZXJQb3J0YCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSB1c2UgY29udGFpbmVycyBpbiBhIHRhc2sgd2l0aCB0aGUgYGJyaWRnZWAgbmV0d29yayBtb2RlIGFuZCB5b3Ugc3BlY2lmeSBhIGNvbnRhaW5lciBwb3J0IGFuZCBub3QgYSBob3N0IHBvcnQsIHlvdXIgY29udGFpbmVyIGF1dG9tYXRpY2FsbHkgcmVjZWl2ZXMgYSBob3N0IHBvcnQgaW4gdGhlIGVwaGVtZXJhbCBwb3J0IHJhbmdlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIGBob3N0UG9ydGAgLiBQb3J0IG1hcHBpbmdzIHRoYXQgYXJlIGF1dG9tYXRpY2FsbHkgYXNzaWduZWQgaW4gdGhpcyB3YXkgZG8gbm90IGNvdW50IHRvd2FyZCB0aGUgMTAwIHJlc2VydmVkIHBvcnRzIGxpbWl0IG9mIGEgY29udGFpbmVyIGluc3RhbmNlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1wb3J0bWFwcGluZy5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tcG9ydG1hcHBpbmctY29udGFpbmVycG9ydFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY29udGFpbmVyUG9ydD86IG51bWJlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwb3J0IG51bWJlciByYW5nZSBvbiB0aGUgY29udGFpbmVyIHRoYXQncyBib3VuZCB0byB0aGUgZHluYW1pY2FsbHkgbWFwcGVkIGhvc3QgcG9ydCByYW5nZS5cbiAgICAgICAgICpcbiAgICAgICAgICogVGhlIGZvbGxvd2luZyBydWxlcyBhcHBseSB3aGVuIHlvdSBzcGVjaWZ5IGEgYGNvbnRhaW5lclBvcnRSYW5nZWAgOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIFlvdSBtdXN0IHVzZSBlaXRoZXIgdGhlIGBicmlkZ2VgIG5ldHdvcmsgbW9kZSBvciB0aGUgYGF3c3ZwY2AgbmV0d29yayBtb2RlLlxuICAgICAgICAgKiAtIFRoaXMgcGFyYW1ldGVyIGlzIGF2YWlsYWJsZSBmb3IgYm90aCB0aGUgRUMyIGFuZCBBV1MgRmFyZ2F0ZSBsYXVuY2ggdHlwZXMuXG4gICAgICAgICAqIC0gVGhpcyBwYXJhbWV0ZXIgaXMgYXZhaWxhYmxlIGZvciBib3RoIHRoZSBMaW51eCBhbmQgV2luZG93cyBvcGVyYXRpbmcgc3lzdGVtcy5cbiAgICAgICAgICogLSBUaGUgY29udGFpbmVyIGluc3RhbmNlIG11c3QgaGF2ZSBhdCBsZWFzdCB2ZXJzaW9uIDEuNjcuMCBvZiB0aGUgY29udGFpbmVyIGFnZW50IGFuZCBhdCBsZWFzdCB2ZXJzaW9uIDEuNjcuMC0xIG9mIHRoZSBgZWNzLWluaXRgIHBhY2thZ2VcbiAgICAgICAgICogLSBZb3UgY2FuIHNwZWNpZnkgYSBtYXhpbXVtIG9mIDEwMCBwb3J0IHJhbmdlcyBwZXIgY29udGFpbmVyLlxuICAgICAgICAgKiAtIFlvdSBkbyBub3Qgc3BlY2lmeSBhIGBob3N0UG9ydFJhbmdlYCAuIFRoZSB2YWx1ZSBvZiB0aGUgYGhvc3RQb3J0UmFuZ2VgIGlzIHNldCBhcyBmb2xsb3dzOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIEZvciBjb250YWluZXJzIGluIGEgdGFzayB3aXRoIHRoZSBgYXdzdnBjYCBuZXR3b3JrIG1vZGUsIHRoZSBgaG9zdFBvcnRgIGlzIHNldCB0byB0aGUgc2FtZSB2YWx1ZSBhcyB0aGUgYGNvbnRhaW5lclBvcnRgIC4gVGhpcyBpcyBhIHN0YXRpYyBtYXBwaW5nIHN0cmF0ZWd5LlxuICAgICAgICAgKiAtIEZvciBjb250YWluZXJzIGluIGEgdGFzayB3aXRoIHRoZSBgYnJpZGdlYCBuZXR3b3JrIG1vZGUsIHRoZSBBbWF6b24gRUNTIGFnZW50IGZpbmRzIG9wZW4gaG9zdCBwb3J0cyBmcm9tIHRoZSBkZWZhdWx0IGVwaGVtZXJhbCByYW5nZSBhbmQgcGFzc2VzIGl0IHRvIGRvY2tlciB0byBiaW5kIHRoZW0gdG8gdGhlIGNvbnRhaW5lciBwb3J0cy5cbiAgICAgICAgICogLSBUaGUgYGNvbnRhaW5lclBvcnRSYW5nZWAgdmFsaWQgdmFsdWVzIGFyZSBiZXR3ZWVuIDEgYW5kIDY1NTM1LlxuICAgICAgICAgKiAtIEEgcG9ydCBjYW4gb25seSBiZSBpbmNsdWRlZCBpbiBvbmUgcG9ydCBtYXBwaW5nIHBlciBjb250YWluZXIuXG4gICAgICAgICAqIC0gWW91IGNhbm5vdCBzcGVjaWZ5IG92ZXJsYXBwaW5nIHBvcnQgcmFuZ2VzLlxuICAgICAgICAgKiAtIFRoZSBmaXJzdCBwb3J0IGluIHRoZSByYW5nZSBtdXN0IGJlIGxlc3MgdGhhbiBsYXN0IHBvcnQgaW4gdGhlIHJhbmdlLlxuICAgICAgICAgKiAtIERvY2tlciByZWNvbW1lbmRzIHRoYXQgeW91IHR1cm4gb2ZmIHRoZSBkb2NrZXItcHJveHkgaW4gdGhlIERvY2tlciBkYWVtb24gY29uZmlnIGZpbGUgd2hlbiB5b3UgaGF2ZSBhIGxhcmdlIG51bWJlciBvZiBwb3J0cy5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbSXNzdWUgIzExMTg1XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9naXRodWIuY29tL21vYnkvbW9ieS9pc3N1ZXMvMTExODUpIG9uIHRoZSBHaXRodWIgd2Vic2l0ZS5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIGluZm9ybWF0aW9uIGFib3V0IGhvdyB0byB0dXJuIG9mZiB0aGUgZG9ja2VyLXByb3h5IGluIHRoZSBEb2NrZXIgZGFlbW9uIGNvbmZpZyBmaWxlLCBzZWUgW0RvY2tlciBkYWVtb25dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2Jvb3RzdHJhcF9jb250YWluZXJfaW5zdGFuY2UuaHRtbCNib290c3RyYXBfZG9ja2VyX2RhZW1vbikgaW4gdGhlICpBbWF6b24gRUNTIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiBZb3UgY2FuIGNhbGwgW2BEZXNjcmliZVRhc2tzYF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVRhc2tzLmh0bWwpIHRvIHZpZXcgdGhlIGBob3N0UG9ydFJhbmdlYCB3aGljaCBhcmUgdGhlIGhvc3QgcG9ydHMgdGhhdCBhcmUgYm91bmQgdG8gdGhlIGNvbnRhaW5lciBwb3J0cy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tcG9ydG1hcHBpbmcuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLXBvcnRtYXBwaW5nLWNvbnRhaW5lcnBvcnRyYW5nZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY29udGFpbmVyUG9ydFJhbmdlPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHBvcnQgbnVtYmVyIG9uIHRoZSBjb250YWluZXIgaW5zdGFuY2UgdG8gcmVzZXJ2ZSBmb3IgeW91ciBjb250YWluZXIuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSBzcGVjaWZ5IGEgYGNvbnRhaW5lclBvcnRSYW5nZWAgLCBsZWF2ZSB0aGlzIGZpZWxkIGVtcHR5IGFuZCB0aGUgdmFsdWUgb2YgdGhlIGBob3N0UG9ydGAgaXMgc2V0IGFzIGZvbGxvd3M6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gRm9yIGNvbnRhaW5lcnMgaW4gYSB0YXNrIHdpdGggdGhlIGBhd3N2cGNgIG5ldHdvcmsgbW9kZSwgdGhlIGBob3N0UG9ydGAgaXMgc2V0IHRvIHRoZSBzYW1lIHZhbHVlIGFzIHRoZSBgY29udGFpbmVyUG9ydGAgLiBUaGlzIGlzIGEgc3RhdGljIG1hcHBpbmcgc3RyYXRlZ3kuXG4gICAgICAgICAqIC0gRm9yIGNvbnRhaW5lcnMgaW4gYSB0YXNrIHdpdGggdGhlIGBicmlkZ2VgIG5ldHdvcmsgbW9kZSwgdGhlIEFtYXpvbiBFQ1MgYWdlbnQgZmluZHMgb3BlbiBwb3J0cyBvbiB0aGUgaG9zdCBhbmQgYXV0b21hdGljYWxseSBiaW5kcyB0aGVtIHRvIHRoZSBjb250YWluZXIgcG9ydHMuIFRoaXMgaXMgYSBkeW5hbWljIG1hcHBpbmcgc3RyYXRlZ3kuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSB1c2UgY29udGFpbmVycyBpbiBhIHRhc2sgd2l0aCB0aGUgYGF3c3ZwY2Agb3IgYGhvc3RgIG5ldHdvcmsgbW9kZSwgdGhlIGBob3N0UG9ydGAgY2FuIGVpdGhlciBiZSBsZWZ0IGJsYW5rIG9yIHNldCB0byB0aGUgc2FtZSB2YWx1ZSBhcyB0aGUgYGNvbnRhaW5lclBvcnRgIC5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgeW91IHVzZSBjb250YWluZXJzIGluIGEgdGFzayB3aXRoIHRoZSBgYnJpZGdlYCBuZXR3b3JrIG1vZGUsIHlvdSBjYW4gc3BlY2lmeSBhIG5vbi1yZXNlcnZlZCBob3N0IHBvcnQgZm9yIHlvdXIgY29udGFpbmVyIHBvcnQgbWFwcGluZywgb3IgeW91IGNhbiBvbWl0IHRoZSBgaG9zdFBvcnRgIChvciBzZXQgaXQgdG8gYDBgICkgd2hpbGUgc3BlY2lmeWluZyBhIGBjb250YWluZXJQb3J0YCBhbmQgeW91ciBjb250YWluZXIgYXV0b21hdGljYWxseSByZWNlaXZlcyBhIHBvcnQgaW4gdGhlIGVwaGVtZXJhbCBwb3J0IHJhbmdlIGZvciB5b3VyIGNvbnRhaW5lciBpbnN0YW5jZSBvcGVyYXRpbmcgc3lzdGVtIGFuZCBEb2NrZXIgdmVyc2lvbi5cbiAgICAgICAgICpcbiAgICAgICAgICogVGhlIGRlZmF1bHQgZXBoZW1lcmFsIHBvcnQgcmFuZ2UgZm9yIERvY2tlciB2ZXJzaW9uIDEuNi4wIGFuZCBsYXRlciBpcyBsaXN0ZWQgb24gdGhlIGluc3RhbmNlIHVuZGVyIGAvcHJvYy9zeXMvbmV0L2lwdjQvaXBfbG9jYWxfcG9ydF9yYW5nZWAgLiBJZiB0aGlzIGtlcm5lbCBwYXJhbWV0ZXIgaXMgdW5hdmFpbGFibGUsIHRoZSBkZWZhdWx0IGVwaGVtZXJhbCBwb3J0IHJhbmdlIGZyb20gNDkxNTMgdGhyb3VnaCA2NTUzNSBpcyB1c2VkLiBEbyBub3QgYXR0ZW1wdCB0byBzcGVjaWZ5IGEgaG9zdCBwb3J0IGluIHRoZSBlcGhlbWVyYWwgcG9ydCByYW5nZSBhcyB0aGVzZSBhcmUgcmVzZXJ2ZWQgZm9yIGF1dG9tYXRpYyBhc3NpZ25tZW50LiBJbiBnZW5lcmFsLCBwb3J0cyBiZWxvdyAzMjc2OCBhcmUgb3V0c2lkZSBvZiB0aGUgZXBoZW1lcmFsIHBvcnQgcmFuZ2UuXG4gICAgICAgICAqXG4gICAgICAgICAqIFRoZSBkZWZhdWx0IHJlc2VydmVkIHBvcnRzIGFyZSAyMiBmb3IgU1NILCB0aGUgRG9ja2VyIHBvcnRzIDIzNzUgYW5kIDIzNzYsIGFuZCB0aGUgQW1hem9uIEVDUyBjb250YWluZXIgYWdlbnQgcG9ydHMgNTE2NzgtNTE2ODAuIEFueSBob3N0IHBvcnQgdGhhdCB3YXMgcHJldmlvdXNseSBzcGVjaWZpZWQgaW4gYSBydW5uaW5nIHRhc2sgaXMgYWxzbyByZXNlcnZlZCB3aGlsZSB0aGUgdGFzayBpcyBydW5uaW5nLiBUaGF0IGlzLCBhZnRlciBhIHRhc2sgc3RvcHMsIHRoZSBob3N0IHBvcnQgaXMgcmVsZWFzZWQuIFRoZSBjdXJyZW50IHJlc2VydmVkIHBvcnRzIGFyZSBkaXNwbGF5ZWQgaW4gdGhlIGByZW1haW5pbmdSZXNvdXJjZXNgIG9mIFtEZXNjcmliZUNvbnRhaW5lckluc3RhbmNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUNvbnRhaW5lckluc3RhbmNlcy5odG1sKSBvdXRwdXQuIEEgY29udGFpbmVyIGluc3RhbmNlIGNhbiBoYXZlIHVwIHRvIDEwMCByZXNlcnZlZCBwb3J0cyBhdCBhIHRpbWUuIFRoaXMgbnVtYmVyIGluY2x1ZGVzIHRoZSBkZWZhdWx0IHJlc2VydmVkIHBvcnRzLiBBdXRvbWF0aWNhbGx5IGFzc2lnbmVkIHBvcnRzIGFyZW4ndCBpbmNsdWRlZCBpbiB0aGUgMTAwIHJlc2VydmVkIHBvcnRzIHF1b3RhLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1wb3J0bWFwcGluZy5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tcG9ydG1hcHBpbmctaG9zdHBvcnRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGhvc3RQb3J0PzogbnVtYmVyO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5hbWUgdGhhdCdzIHVzZWQgZm9yIHRoZSBwb3J0IG1hcHBpbmcuIFRoaXMgcGFyYW1ldGVyIG9ubHkgYXBwbGllcyB0byBTZXJ2aWNlIENvbm5lY3QuIFRoaXMgcGFyYW1ldGVyIGlzIHRoZSBuYW1lIHRoYXQgeW91IHVzZSBpbiB0aGUgYHNlcnZpY2VDb25uZWN0Q29uZmlndXJhdGlvbmAgb2YgYSBzZXJ2aWNlLiBUaGUgbmFtZSBjYW4gaW5jbHVkZSB1cCB0byA2NCBjaGFyYWN0ZXJzLiBUaGUgY2hhcmFjdGVycyBjYW4gaW5jbHVkZSBsb3dlcmNhc2UgbGV0dGVycywgbnVtYmVycywgdW5kZXJzY29yZXMgKF8pLCBhbmQgaHlwaGVucyAoLSkuIFRoZSBuYW1lIGNhbid0IHN0YXJ0IHdpdGggYSBoeXBoZW4uXG4gICAgICAgICAqXG4gICAgICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1NlcnZpY2UgQ29ubmVjdF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvc2VydmljZS1jb25uZWN0Lmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXBvcnRtYXBwaW5nLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1wb3J0bWFwcGluZy1uYW1lXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBuYW1lPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHByb3RvY29sIHVzZWQgZm9yIHRoZSBwb3J0IG1hcHBpbmcuIFZhbGlkIHZhbHVlcyBhcmUgYHRjcGAgYW5kIGB1ZHBgIC4gVGhlIGRlZmF1bHQgaXMgYHRjcGAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1wb3J0bWFwcGluZy5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tcG9ydG1hcHBpbmctcHJvdG9jb2xcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHByb3RvY29sPzogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBQb3J0TWFwcGluZ1Byb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBQb3J0TWFwcGluZ1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uX1BvcnRNYXBwaW5nUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdhcHBQcm90b2NvbCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5hcHBQcm90b2NvbCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY29udGFpbmVyUG9ydCcsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5jb250YWluZXJQb3J0KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjb250YWluZXJQb3J0UmFuZ2UnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY29udGFpbmVyUG9ydFJhbmdlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdob3N0UG9ydCcsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5ob3N0UG9ydCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5uYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwcm90b2NvbCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5wcm90b2NvbCkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJQb3J0TWFwcGluZ1Byb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLlBvcnRNYXBwaW5nYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBQb3J0TWFwcGluZ1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLlBvcnRNYXBwaW5nYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblRhc2tEZWZpbml0aW9uUG9ydE1hcHBpbmdQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVGFza0RlZmluaXRpb25fUG9ydE1hcHBpbmdQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQXBwUHJvdG9jb2w6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuYXBwUHJvdG9jb2wpLFxuICAgICAgICBDb250YWluZXJQb3J0OiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNvbnRhaW5lclBvcnQpLFxuICAgICAgICBDb250YWluZXJQb3J0UmFuZ2U6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY29udGFpbmVyUG9ydFJhbmdlKSxcbiAgICAgICAgSG9zdFBvcnQ6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaG9zdFBvcnQpLFxuICAgICAgICBOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm5hbWUpLFxuICAgICAgICBQcm90b2NvbDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wcm90b2NvbCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uUG9ydE1hcHBpbmdQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblRhc2tEZWZpbml0aW9uLlBvcnRNYXBwaW5nUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVGFza0RlZmluaXRpb24uUG9ydE1hcHBpbmdQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2FwcFByb3RvY29sJywgJ0FwcFByb3RvY29sJywgcHJvcGVydGllcy5BcHBQcm90b2NvbCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5BcHBQcm90b2NvbCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY29udGFpbmVyUG9ydCcsICdDb250YWluZXJQb3J0JywgcHJvcGVydGllcy5Db250YWluZXJQb3J0ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLkNvbnRhaW5lclBvcnQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2NvbnRhaW5lclBvcnRSYW5nZScsICdDb250YWluZXJQb3J0UmFuZ2UnLCBwcm9wZXJ0aWVzLkNvbnRhaW5lclBvcnRSYW5nZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Db250YWluZXJQb3J0UmFuZ2UpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2hvc3RQb3J0JywgJ0hvc3RQb3J0JywgcHJvcGVydGllcy5Ib3N0UG9ydCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5Ib3N0UG9ydCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbmFtZScsICdOYW1lJywgcHJvcGVydGllcy5OYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLk5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3Byb3RvY29sJywgJ1Byb3RvY29sJywgcHJvcGVydGllcy5Qcm90b2NvbCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Qcm90b2NvbCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblRhc2tEZWZpbml0aW9uIHtcbiAgICAvKipcbiAgICAgKiBUaGUgY29uZmlndXJhdGlvbiBkZXRhaWxzIGZvciB0aGUgQXBwIE1lc2ggcHJveHkuXG4gICAgICpcbiAgICAgKiBGb3IgdGFza3MgdGhhdCB1c2UgdGhlIEVDMiBsYXVuY2ggdHlwZSwgdGhlIGNvbnRhaW5lciBpbnN0YW5jZXMgcmVxdWlyZSBhdCBsZWFzdCB2ZXJzaW9uIDEuMjYuMCBvZiB0aGUgY29udGFpbmVyIGFnZW50IGFuZCBhdCBsZWFzdCB2ZXJzaW9uIDEuMjYuMC0xIG9mIHRoZSBgZWNzLWluaXRgIHBhY2thZ2UgdG8gdXNlIGEgcHJveHkgY29uZmlndXJhdGlvbi4gSWYgeW91ciBjb250YWluZXIgaW5zdGFuY2VzIGFyZSBsYXVuY2hlZCBmcm9tIHRoZSBBbWF6b24gRUNTIG9wdGltaXplZCBBTUkgdmVyc2lvbiBgMjAxOTAzMDFgIG9yIGxhdGVyLCB0aGVuIHRoZXkgY29udGFpbiB0aGUgcmVxdWlyZWQgdmVyc2lvbnMgb2YgdGhlIGNvbnRhaW5lciBhZ2VudCBhbmQgYGVjcy1pbml0YCAuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0FtYXpvbiBFQ1Mtb3B0aW1pemVkIExpbnV4IEFNSV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvZWNzLW9wdGltaXplZF9BTUkuaHRtbClcbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1wcm94eWNvbmZpZ3VyYXRpb24uaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgUHJveHlDb25maWd1cmF0aW9uUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5hbWUgb2YgdGhlIGNvbnRhaW5lciB0aGF0IHdpbGwgc2VydmUgYXMgdGhlIEFwcCBNZXNoIHByb3h5LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1wcm94eWNvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLXByb3h5Y29uZmlndXJhdGlvbi1jb250YWluZXJuYW1lXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBjb250YWluZXJOYW1lOiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgc2V0IG9mIG5ldHdvcmsgY29uZmlndXJhdGlvbiBwYXJhbWV0ZXJzIHRvIHByb3ZpZGUgdGhlIENvbnRhaW5lciBOZXR3b3JrIEludGVyZmFjZSAoQ05JKSBwbHVnaW4sIHNwZWNpZmllZCBhcyBrZXktdmFsdWUgcGFpcnMuXG4gICAgICAgICAqXG4gICAgICAgICAqIC0gYElnbm9yZWRVSURgIC0gKFJlcXVpcmVkKSBUaGUgdXNlciBJRCAoVUlEKSBvZiB0aGUgcHJveHkgY29udGFpbmVyIGFzIGRlZmluZWQgYnkgdGhlIGB1c2VyYCBwYXJhbWV0ZXIgaW4gYSBjb250YWluZXIgZGVmaW5pdGlvbi4gVGhpcyBpcyB1c2VkIHRvIGVuc3VyZSB0aGUgcHJveHkgaWdub3JlcyBpdHMgb3duIHRyYWZmaWMuIElmIGBJZ25vcmVkR0lEYCBpcyBzcGVjaWZpZWQsIHRoaXMgZmllbGQgY2FuIGJlIGVtcHR5LlxuICAgICAgICAgKiAtIGBJZ25vcmVkR0lEYCAtIChSZXF1aXJlZCkgVGhlIGdyb3VwIElEIChHSUQpIG9mIHRoZSBwcm94eSBjb250YWluZXIgYXMgZGVmaW5lZCBieSB0aGUgYHVzZXJgIHBhcmFtZXRlciBpbiBhIGNvbnRhaW5lciBkZWZpbml0aW9uLiBUaGlzIGlzIHVzZWQgdG8gZW5zdXJlIHRoZSBwcm94eSBpZ25vcmVzIGl0cyBvd24gdHJhZmZpYy4gSWYgYElnbm9yZWRVSURgIGlzIHNwZWNpZmllZCwgdGhpcyBmaWVsZCBjYW4gYmUgZW1wdHkuXG4gICAgICAgICAqIC0gYEFwcFBvcnRzYCAtIChSZXF1aXJlZCkgVGhlIGxpc3Qgb2YgcG9ydHMgdGhhdCB0aGUgYXBwbGljYXRpb24gdXNlcy4gTmV0d29yayB0cmFmZmljIHRvIHRoZXNlIHBvcnRzIGlzIGZvcndhcmRlZCB0byB0aGUgYFByb3h5SW5ncmVzc1BvcnRgIGFuZCBgUHJveHlFZ3Jlc3NQb3J0YCAuXG4gICAgICAgICAqIC0gYFByb3h5SW5ncmVzc1BvcnRgIC0gKFJlcXVpcmVkKSBTcGVjaWZpZXMgdGhlIHBvcnQgdGhhdCBpbmNvbWluZyB0cmFmZmljIHRvIHRoZSBgQXBwUG9ydHNgIGlzIGRpcmVjdGVkIHRvLlxuICAgICAgICAgKiAtIGBQcm94eUVncmVzc1BvcnRgIC0gKFJlcXVpcmVkKSBTcGVjaWZpZXMgdGhlIHBvcnQgdGhhdCBvdXRnb2luZyB0cmFmZmljIGZyb20gdGhlIGBBcHBQb3J0c2AgaXMgZGlyZWN0ZWQgdG8uXG4gICAgICAgICAqIC0gYEVncmVzc0lnbm9yZWRQb3J0c2AgLSAoUmVxdWlyZWQpIFRoZSBlZ3Jlc3MgdHJhZmZpYyBnb2luZyB0byB0aGUgc3BlY2lmaWVkIHBvcnRzIGlzIGlnbm9yZWQgYW5kIG5vdCByZWRpcmVjdGVkIHRvIHRoZSBgUHJveHlFZ3Jlc3NQb3J0YCAuIEl0IGNhbiBiZSBhbiBlbXB0eSBsaXN0LlxuICAgICAgICAgKiAtIGBFZ3Jlc3NJZ25vcmVkSVBzYCAtIChSZXF1aXJlZCkgVGhlIGVncmVzcyB0cmFmZmljIGdvaW5nIHRvIHRoZSBzcGVjaWZpZWQgSVAgYWRkcmVzc2VzIGlzIGlnbm9yZWQgYW5kIG5vdCByZWRpcmVjdGVkIHRvIHRoZSBgUHJveHlFZ3Jlc3NQb3J0YCAuIEl0IGNhbiBiZSBhbiBlbXB0eSBsaXN0LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1wcm94eWNvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLXByb3h5Y29uZmlndXJhdGlvbi1wcm94eWNvbmZpZ3VyYXRpb25wcm9wZXJ0aWVzXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBwcm94eUNvbmZpZ3VyYXRpb25Qcm9wZXJ0aWVzPzogQXJyYXk8Q2ZuVGFza0RlZmluaXRpb24uS2V5VmFsdWVQYWlyUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHByb3h5IHR5cGUuIFRoZSBvbmx5IHN1cHBvcnRlZCB2YWx1ZSBpcyBgQVBQTUVTSGAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1wcm94eWNvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLXByb3h5Y29uZmlndXJhdGlvbi10eXBlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB0eXBlPzogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBQcm94eUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgUHJveHlDb25maWd1cmF0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25fUHJveHlDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjb250YWluZXJOYW1lJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmNvbnRhaW5lck5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvbnRhaW5lck5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY29udGFpbmVyTmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncHJveHlDb25maWd1cmF0aW9uUHJvcGVydGllcycsIGNkay5saXN0VmFsaWRhdG9yKENmblRhc2tEZWZpbml0aW9uX0tleVZhbHVlUGFpclByb3BlcnR5VmFsaWRhdG9yKSkocHJvcGVydGllcy5wcm94eUNvbmZpZ3VyYXRpb25Qcm9wZXJ0aWVzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0eXBlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnR5cGUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiUHJveHlDb25maWd1cmF0aW9uUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uUHJveHlDb25maWd1cmF0aW9uYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBQcm94eUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5Qcm94eUNvbmZpZ3VyYXRpb25gIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuVGFza0RlZmluaXRpb25Qcm94eUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVGFza0RlZmluaXRpb25fUHJveHlDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIENvbnRhaW5lck5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY29udGFpbmVyTmFtZSksXG4gICAgICAgIFByb3h5Q29uZmlndXJhdGlvblByb3BlcnRpZXM6IGNkay5saXN0TWFwcGVyKGNmblRhc2tEZWZpbml0aW9uS2V5VmFsdWVQYWlyUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnByb3h5Q29uZmlndXJhdGlvblByb3BlcnRpZXMpLFxuICAgICAgICBUeXBlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnR5cGUpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvblByb3h5Q29uZmlndXJhdGlvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb24uUHJveHlDb25maWd1cmF0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVGFza0RlZmluaXRpb24uUHJveHlDb25maWd1cmF0aW9uUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjb250YWluZXJOYW1lJywgJ0NvbnRhaW5lck5hbWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNvbnRhaW5lck5hbWUpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3Byb3h5Q29uZmlndXJhdGlvblByb3BlcnRpZXMnLCAnUHJveHlDb25maWd1cmF0aW9uUHJvcGVydGllcycsIHByb3BlcnRpZXMuUHJveHlDb25maWd1cmF0aW9uUHJvcGVydGllcyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5UYXNrRGVmaW5pdGlvbktleVZhbHVlUGFpclByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLlByb3h5Q29uZmlndXJhdGlvblByb3BlcnRpZXMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3R5cGUnLCAnVHlwZScsIHByb3BlcnRpZXMuVHlwZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5UeXBlKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuVGFza0RlZmluaXRpb24ge1xuICAgIC8qKlxuICAgICAqIFRoZSByZXBvc2l0b3J5IGNyZWRlbnRpYWxzIGZvciBwcml2YXRlIHJlZ2lzdHJ5IGF1dGhlbnRpY2F0aW9uLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXJlcG9zaXRvcnljcmVkZW50aWFscy5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBSZXBvc2l0b3J5Q3JlZGVudGlhbHNQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIHNlY3JldCBjb250YWluaW5nIHRoZSBwcml2YXRlIHJlcG9zaXRvcnkgY3JlZGVudGlhbHMuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gV2hlbiB5b3UgdXNlIHRoZSBBbWF6b24gRUNTIEFQSSwgQVdTIENMSSAsIG9yIEFXUyBTREssIGlmIHRoZSBzZWNyZXQgZXhpc3RzIGluIHRoZSBzYW1lIFJlZ2lvbiBhcyB0aGUgdGFzayB0aGF0IHlvdSdyZSBsYXVuY2hpbmcgdGhlbiB5b3UgY2FuIHVzZSBlaXRoZXIgdGhlIGZ1bGwgQVJOIG9yIHRoZSBuYW1lIG9mIHRoZSBzZWNyZXQuIFdoZW4geW91IHVzZSB0aGUgQVdTIE1hbmFnZW1lbnQgQ29uc29sZSwgeW91IG11c3Qgc3BlY2lmeSB0aGUgZnVsbCBBUk4gb2YgdGhlIHNlY3JldC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tcmVwb3NpdG9yeWNyZWRlbnRpYWxzLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1yZXBvc2l0b3J5Y3JlZGVudGlhbHMtY3JlZGVudGlhbHNwYXJhbWV0ZXJcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNyZWRlbnRpYWxzUGFyYW1ldGVyPzogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBSZXBvc2l0b3J5Q3JlZGVudGlhbHNQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgUmVwb3NpdG9yeUNyZWRlbnRpYWxzUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25fUmVwb3NpdG9yeUNyZWRlbnRpYWxzUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjcmVkZW50aWFsc1BhcmFtZXRlcicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jcmVkZW50aWFsc1BhcmFtZXRlcikpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJSZXBvc2l0b3J5Q3JlZGVudGlhbHNQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5SZXBvc2l0b3J5Q3JlZGVudGlhbHNgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYFJlcG9zaXRvcnlDcmVkZW50aWFsc1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLlJlcG9zaXRvcnlDcmVkZW50aWFsc2AgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5UYXNrRGVmaW5pdGlvblJlcG9zaXRvcnlDcmVkZW50aWFsc1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5UYXNrRGVmaW5pdGlvbl9SZXBvc2l0b3J5Q3JlZGVudGlhbHNQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQ3JlZGVudGlhbHNQYXJhbWV0ZXI6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY3JlZGVudGlhbHNQYXJhbWV0ZXIpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvblJlcG9zaXRvcnlDcmVkZW50aWFsc1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb24uUmVwb3NpdG9yeUNyZWRlbnRpYWxzUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVGFza0RlZmluaXRpb24uUmVwb3NpdG9yeUNyZWRlbnRpYWxzUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjcmVkZW50aWFsc1BhcmFtZXRlcicsICdDcmVkZW50aWFsc1BhcmFtZXRlcicsIHByb3BlcnRpZXMuQ3JlZGVudGlhbHNQYXJhbWV0ZXIgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQ3JlZGVudGlhbHNQYXJhbWV0ZXIpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5UYXNrRGVmaW5pdGlvbiB7XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgYW5kIGFtb3VudCBvZiBhIHJlc291cmNlIHRvIGFzc2lnbiB0byBhIGNvbnRhaW5lci4gVGhlIHN1cHBvcnRlZCByZXNvdXJjZSB0eXBlcyBhcmUgR1BVcyBhbmQgRWxhc3RpYyBJbmZlcmVuY2UgYWNjZWxlcmF0b3JzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtXb3JraW5nIHdpdGggR1BVcyBvbiBBbWF6b24gRUNTXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9lY3MtZ3B1Lmh0bWwpIG9yIFtXb3JraW5nIHdpdGggQW1hem9uIEVsYXN0aWMgSW5mZXJlbmNlIG9uIEFtYXpvbiBFQ1NdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2Vjcy1pbmZlcmVuY2UuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tcmVzb3VyY2VyZXF1aXJlbWVudC5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBSZXNvdXJjZVJlcXVpcmVtZW50UHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHR5cGUgb2YgcmVzb3VyY2UgdG8gYXNzaWduIHRvIGEgY29udGFpbmVyLiBUaGUgc3VwcG9ydGVkIHZhbHVlcyBhcmUgYEdQVWAgb3IgYEluZmVyZW5jZUFjY2VsZXJhdG9yYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXJlc291cmNlcmVxdWlyZW1lbnQuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLXJlc291cmNlcmVxdWlyZW1lbnQtdHlwZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgdHlwZTogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIHJlc291cmNlIHR5cGUuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHRoZSBgR1BVYCB0eXBlIGlzIHVzZWQsIHRoZSB2YWx1ZSBpcyB0aGUgbnVtYmVyIG9mIHBoeXNpY2FsIGBHUFVzYCB0aGUgQW1hem9uIEVDUyBjb250YWluZXIgYWdlbnQgcmVzZXJ2ZXMgZm9yIHRoZSBjb250YWluZXIuIFRoZSBudW1iZXIgb2YgR1BVcyB0aGF0J3MgcmVzZXJ2ZWQgZm9yIGFsbCBjb250YWluZXJzIGluIGEgdGFzayBjYW4ndCBleGNlZWQgdGhlIG51bWJlciBvZiBhdmFpbGFibGUgR1BVcyBvbiB0aGUgY29udGFpbmVyIGluc3RhbmNlIHRoYXQgdGhlIHRhc2sgaXMgbGF1bmNoZWQgb24uXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHRoZSBgSW5mZXJlbmNlQWNjZWxlcmF0b3JgIHR5cGUgaXMgdXNlZCwgdGhlIGB2YWx1ZWAgbWF0Y2hlcyB0aGUgYGRldmljZU5hbWVgIGZvciBhbiBbSW5mZXJlbmNlQWNjZWxlcmF0b3JdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfSW5mZXJlbmNlQWNjZWxlcmF0b3IuaHRtbCkgc3BlY2lmaWVkIGluIGEgdGFzayBkZWZpbml0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1yZXNvdXJjZXJlcXVpcmVtZW50Lmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi1yZXNvdXJjZXJlcXVpcmVtZW50LXZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB2YWx1ZTogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBSZXNvdXJjZVJlcXVpcmVtZW50UHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYFJlc291cmNlUmVxdWlyZW1lbnRQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbl9SZXNvdXJjZVJlcXVpcmVtZW50UHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0eXBlJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnR5cGUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3R5cGUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMudHlwZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndmFsdWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMudmFsdWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3ZhbHVlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnZhbHVlKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIlJlc291cmNlUmVxdWlyZW1lbnRQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5SZXNvdXJjZVJlcXVpcmVtZW50YCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBSZXNvdXJjZVJlcXVpcmVtZW50UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uUmVzb3VyY2VSZXF1aXJlbWVudGAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5UYXNrRGVmaW5pdGlvblJlc291cmNlUmVxdWlyZW1lbnRQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVGFza0RlZmluaXRpb25fUmVzb3VyY2VSZXF1aXJlbWVudFByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBUeXBlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnR5cGUpLFxuICAgICAgICBWYWx1ZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy52YWx1ZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uUmVzb3VyY2VSZXF1aXJlbWVudFByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb24uUmVzb3VyY2VSZXF1aXJlbWVudFByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblRhc2tEZWZpbml0aW9uLlJlc291cmNlUmVxdWlyZW1lbnRQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3R5cGUnLCAnVHlwZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuVHlwZSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndmFsdWUnLCAnVmFsdWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlZhbHVlKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuVGFza0RlZmluaXRpb24ge1xuICAgIC8qKlxuICAgICAqIEluZm9ybWF0aW9uIGFib3V0IHRoZSBwbGF0Zm9ybSBmb3IgdGhlIEFtYXpvbiBFQ1Mgc2VydmljZSBvciB0YXNrLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgYFJ1bnRpbWVQbGF0Zm9ybWAgLCBzZWUgW1J1bnRpbWVQbGF0Zm9ybV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvdGFza19kZWZpbml0aW9uX3BhcmFtZXRlcnMuaHRtbCNydW50aW1lLXBsYXRmb3JtKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXJ1bnRpbWVwbGF0Zm9ybS5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBSdW50aW1lUGxhdGZvcm1Qcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZS5cbiAgICAgICAgICpcbiAgICAgICAgICogWW91IGNhbiBydW4geW91ciBMaW51eCB0YXNrcyBvbiBhbiBBUk0tYmFzZWQgcGxhdGZvcm0gYnkgc2V0dGluZyB0aGUgdmFsdWUgdG8gYEFSTTY0YCAuIFRoaXMgb3B0aW9uIGlzIGF2YWlsYWJsZSBmb3IgdGFza3MgdGhhdCBydW4gb24gTGludXggQW1hem9uIEVDMiBpbnN0YW5jZSBvciBMaW51eCBjb250YWluZXJzIG9uIEZhcmdhdGUuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXJ1bnRpbWVwbGF0Zm9ybS5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tcnVudGltZXBsYXRmb3JtLWNwdWFyY2hpdGVjdHVyZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY3B1QXJjaGl0ZWN0dXJlPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXJ1bnRpbWVwbGF0Zm9ybS5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tcnVudGltZXBsYXRmb3JtLW9wZXJhdGluZ3N5c3RlbWZhbWlseVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgb3BlcmF0aW5nU3lzdGVtRmFtaWx5Pzogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBSdW50aW1lUGxhdGZvcm1Qcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgUnVudGltZVBsYXRmb3JtUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25fUnVudGltZVBsYXRmb3JtUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjcHVBcmNoaXRlY3R1cmUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY3B1QXJjaGl0ZWN0dXJlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdvcGVyYXRpbmdTeXN0ZW1GYW1pbHknLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMub3BlcmF0aW5nU3lzdGVtRmFtaWx5KSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIlJ1bnRpbWVQbGF0Zm9ybVByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLlJ1bnRpbWVQbGF0Zm9ybWAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgUnVudGltZVBsYXRmb3JtUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uUnVudGltZVBsYXRmb3JtYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblRhc2tEZWZpbml0aW9uUnVudGltZVBsYXRmb3JtUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblRhc2tEZWZpbml0aW9uX1J1bnRpbWVQbGF0Zm9ybVByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBDcHVBcmNoaXRlY3R1cmU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY3B1QXJjaGl0ZWN0dXJlKSxcbiAgICAgICAgT3BlcmF0aW5nU3lzdGVtRmFtaWx5OiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm9wZXJhdGluZ1N5c3RlbUZhbWlseSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uUnVudGltZVBsYXRmb3JtUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5UYXNrRGVmaW5pdGlvbi5SdW50aW1lUGxhdGZvcm1Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5UYXNrRGVmaW5pdGlvbi5SdW50aW1lUGxhdGZvcm1Qcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2NwdUFyY2hpdGVjdHVyZScsICdDcHVBcmNoaXRlY3R1cmUnLCBwcm9wZXJ0aWVzLkNwdUFyY2hpdGVjdHVyZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5DcHVBcmNoaXRlY3R1cmUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ29wZXJhdGluZ1N5c3RlbUZhbWlseScsICdPcGVyYXRpbmdTeXN0ZW1GYW1pbHknLCBwcm9wZXJ0aWVzLk9wZXJhdGluZ1N5c3RlbUZhbWlseSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5PcGVyYXRpbmdTeXN0ZW1GYW1pbHkpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5UYXNrRGVmaW5pdGlvbiB7XG4gICAgLyoqXG4gICAgICogQW4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgc2VjcmV0IHRvIGV4cG9zZSB0byB5b3VyIGNvbnRhaW5lci4gU2VjcmV0cyBjYW4gYmUgZXhwb3NlZCB0byBhIGNvbnRhaW5lciBpbiB0aGUgZm9sbG93aW5nIHdheXM6XG4gICAgICpcbiAgICAgKiAtIFRvIGluamVjdCBzZW5zaXRpdmUgZGF0YSBpbnRvIHlvdXIgY29udGFpbmVycyBhcyBlbnZpcm9ubWVudCB2YXJpYWJsZXMsIHVzZSB0aGUgYHNlY3JldHNgIGNvbnRhaW5lciBkZWZpbml0aW9uIHBhcmFtZXRlci5cbiAgICAgKiAtIFRvIHJlZmVyZW5jZSBzZW5zaXRpdmUgaW5mb3JtYXRpb24gaW4gdGhlIGxvZyBjb25maWd1cmF0aW9uIG9mIGEgY29udGFpbmVyLCB1c2UgdGhlIGBzZWNyZXRPcHRpb25zYCBjb250YWluZXIgZGVmaW5pdGlvbiBwYXJhbWV0ZXIuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtTcGVjaWZ5aW5nIHNlbnNpdGl2ZSBkYXRhXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zcGVjaWZ5aW5nLXNlbnNpdGl2ZS1kYXRhLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tc2VjcmV0Lmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIFNlY3JldFByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBuYW1lIG9mIHRoZSBzZWNyZXQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXNlY3JldC5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tc2VjcmV0LW5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzZWNyZXQgdG8gZXhwb3NlIHRvIHRoZSBjb250YWluZXIuIFRoZSBzdXBwb3J0ZWQgdmFsdWVzIGFyZSBlaXRoZXIgdGhlIGZ1bGwgQVJOIG9mIHRoZSBBV1MgU2VjcmV0cyBNYW5hZ2VyIHNlY3JldCBvciB0aGUgZnVsbCBBUk4gb2YgdGhlIHBhcmFtZXRlciBpbiB0aGUgU1NNIFBhcmFtZXRlciBTdG9yZS5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIGluZm9ybWF0aW9uIGFib3V0IHRoZSByZXF1aXJlIEFXUyBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgcGVybWlzc2lvbnMsIHNlZSBbUmVxdWlyZWQgSUFNIHBlcm1pc3Npb25zIGZvciBBbWF6b24gRUNTIHNlY3JldHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3NwZWNpZnlpbmctc2Vuc2l0aXZlLWRhdGEtc2VjcmV0cy5odG1sI3NlY3JldHMtaWFtKSAoZm9yIFNlY3JldHMgTWFuYWdlcikgb3IgW1JlcXVpcmVkIElBTSBwZXJtaXNzaW9ucyBmb3IgQW1hem9uIEVDUyBzZWNyZXRzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zcGVjaWZ5aW5nLXNlbnNpdGl2ZS1kYXRhLXBhcmFtZXRlcnMuaHRtbCkgKGZvciBTeXN0ZW1zIE1hbmFnZXIgUGFyYW1ldGVyIHN0b3JlKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IElmIHRoZSBTU00gUGFyYW1ldGVyIFN0b3JlIHBhcmFtZXRlciBleGlzdHMgaW4gdGhlIHNhbWUgUmVnaW9uIGFzIHRoZSB0YXNrIHlvdSdyZSBsYXVuY2hpbmcsIHRoZW4geW91IGNhbiB1c2UgZWl0aGVyIHRoZSBmdWxsIEFSTiBvciBuYW1lIG9mIHRoZSBwYXJhbWV0ZXIuIElmIHRoZSBwYXJhbWV0ZXIgZXhpc3RzIGluIGEgZGlmZmVyZW50IFJlZ2lvbiwgdGhlbiB0aGUgZnVsbCBBUk4gbXVzdCBiZSBzcGVjaWZpZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXNlY3JldC5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tc2VjcmV0LXZhbHVlZnJvbVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgdmFsdWVGcm9tOiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYFNlY3JldFByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBTZWNyZXRQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbl9TZWNyZXRQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ25hbWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMubmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5uYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd2YWx1ZUZyb20nLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMudmFsdWVGcm9tKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd2YWx1ZUZyb20nLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMudmFsdWVGcm9tKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIlNlY3JldFByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLlNlY3JldGAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgU2VjcmV0UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uU2VjcmV0YCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblRhc2tEZWZpbml0aW9uU2VjcmV0UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblRhc2tEZWZpbml0aW9uX1NlY3JldFByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm5hbWUpLFxuICAgICAgICBWYWx1ZUZyb206IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMudmFsdWVGcm9tKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25TZWNyZXRQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblRhc2tEZWZpbml0aW9uLlNlY3JldFByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblRhc2tEZWZpbml0aW9uLlNlY3JldFByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbmFtZScsICdOYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5OYW1lKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd2YWx1ZUZyb20nLCAnVmFsdWVGcm9tJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5WYWx1ZUZyb20pKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5UYXNrRGVmaW5pdGlvbiB7XG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIG5hbWVzcGFjZWQga2VybmVsIHBhcmFtZXRlcnMgdG8gc2V0IGluIHRoZSBjb250YWluZXIuIFRoaXMgcGFyYW1ldGVyIG1hcHMgdG8gYFN5c2N0bHNgIGluIHRoZSBbQ3JlYXRlIGEgY29udGFpbmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8jb3BlcmF0aW9uL0NvbnRhaW5lckNyZWF0ZSkgc2VjdGlvbiBvZiB0aGUgW0RvY2tlciBSZW1vdGUgQVBJXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9kb2NzLmRvY2tlci5jb20vZW5naW5lL2FwaS92MS4zNS8pIGFuZCB0aGUgYC0tc3lzY3RsYCBvcHRpb24gdG8gW2RvY2tlciBydW5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jc2VjdXJpdHktY29uZmlndXJhdGlvbikgLlxuICAgICAqXG4gICAgICogV2UgZG9uJ3QgcmVjb21tZW5kIHRoYXQgeW91IHNwZWNpZnkgbmV0d29yay1yZWxhdGVkIGBzeXN0ZW1Db250cm9sc2AgcGFyYW1ldGVycyBmb3IgbXVsdGlwbGUgY29udGFpbmVycyBpbiBhIHNpbmdsZSB0YXNrLiBUaGlzIHRhc2sgYWxzbyB1c2VzIGVpdGhlciB0aGUgYGF3c3ZwY2Agb3IgYGhvc3RgIG5ldHdvcmsgbW9kZS4gSXQgZG9lcyBpdCBmb3IgdGhlIGZvbGxvd2luZyByZWFzb25zLlxuICAgICAqXG4gICAgICogLSBGb3IgdGFza3MgdGhhdCB1c2UgdGhlIGBhd3N2cGNgIG5ldHdvcmsgbW9kZSwgaWYgeW91IHNldCBgc3lzdGVtQ29udHJvbHNgIGZvciBhbnkgY29udGFpbmVyLCBpdCBhcHBsaWVzIHRvIGFsbCBjb250YWluZXJzIGluIHRoZSB0YXNrLiBJZiB5b3Ugc2V0IGRpZmZlcmVudCBgc3lzdGVtQ29udHJvbHNgIGZvciBtdWx0aXBsZSBjb250YWluZXJzIGluIGEgc2luZ2xlIHRhc2ssIHRoZSBjb250YWluZXIgdGhhdCdzIHN0YXJ0ZWQgbGFzdCBkZXRlcm1pbmVzIHdoaWNoIGBzeXN0ZW1Db250cm9sc2AgdGFrZSBlZmZlY3QuXG4gICAgICogLSBGb3IgdGFza3MgdGhhdCB1c2UgdGhlIGBob3N0YCBuZXR3b3JrIG1vZGUsIHRoZSBgc3lzdGVtQ29udHJvbHNgIHBhcmFtZXRlciBhcHBsaWVzIHRvIHRoZSBjb250YWluZXIgaW5zdGFuY2UncyBrZXJuZWwgcGFyYW1ldGVyIGFuZCB0aGF0IG9mIGFsbCBjb250YWluZXJzIG9mIGFueSB0YXNrcyBydW5uaW5nIG9uIHRoYXQgY29udGFpbmVyIGluc3RhbmNlLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXN5c3RlbWNvbnRyb2wuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgU3lzdGVtQ29udHJvbFByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBuYW1lc3BhY2VkIGtlcm5lbCBwYXJhbWV0ZXIgdG8gc2V0IGEgYHZhbHVlYCBmb3IuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXN5c3RlbWNvbnRyb2wuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLXN5c3RlbWNvbnRyb2wtbmFtZXNwYWNlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBuYW1lc3BhY2U/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdmFsdWUgZm9yIHRoZSBuYW1lc3BhY2VkIGtlcm5lbCBwYXJhbWV0ZXIgdGhhdCdzIHNwZWNpZmllZCBpbiBgbmFtZXNwYWNlYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXN5c3RlbWNvbnRyb2wuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLXN5c3RlbWNvbnRyb2wtdmFsdWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHZhbHVlPzogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBTeXN0ZW1Db250cm9sUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYFN5c3RlbUNvbnRyb2xQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbl9TeXN0ZW1Db250cm9sUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCduYW1lc3BhY2UnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMubmFtZXNwYWNlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd2YWx1ZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy52YWx1ZSkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJTeXN0ZW1Db250cm9sUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uU3lzdGVtQ29udHJvbGAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgU3lzdGVtQ29udHJvbFByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tEZWZpbml0aW9uLlN5c3RlbUNvbnRyb2xgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuVGFza0RlZmluaXRpb25TeXN0ZW1Db250cm9sUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblRhc2tEZWZpbml0aW9uX1N5c3RlbUNvbnRyb2xQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgTmFtZXNwYWNlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm5hbWVzcGFjZSksXG4gICAgICAgIFZhbHVlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnZhbHVlKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25TeXN0ZW1Db250cm9sUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5UYXNrRGVmaW5pdGlvbi5TeXN0ZW1Db250cm9sUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVGFza0RlZmluaXRpb24uU3lzdGVtQ29udHJvbFByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbmFtZXNwYWNlJywgJ05hbWVzcGFjZScsIHByb3BlcnRpZXMuTmFtZXNwYWNlICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLk5hbWVzcGFjZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndmFsdWUnLCAnVmFsdWUnLCBwcm9wZXJ0aWVzLlZhbHVlICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlZhbHVlKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuVGFza0RlZmluaXRpb24ge1xuICAgIC8qKlxuICAgICAqIFRoZSBjb25zdHJhaW50IG9uIHRhc2sgcGxhY2VtZW50IGluIHRoZSB0YXNrIGRlZmluaXRpb24uIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1Rhc2sgcGxhY2VtZW50IGNvbnN0cmFpbnRzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS90YXNrLXBsYWNlbWVudC1jb25zdHJhaW50cy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogPiBUYXNrIHBsYWNlbWVudCBjb25zdHJhaW50cyBhcmVuJ3Qgc3VwcG9ydGVkIGZvciB0YXNrcyBydW4gb24gQVdTIEZhcmdhdGUgLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXRhc2tkZWZpbml0aW9ucGxhY2VtZW50Y29uc3RyYWludC5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBUYXNrRGVmaW5pdGlvblBsYWNlbWVudENvbnN0cmFpbnRQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBIGNsdXN0ZXIgcXVlcnkgbGFuZ3VhZ2UgZXhwcmVzc2lvbiB0byBhcHBseSB0byB0aGUgY29uc3RyYWludC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQ2x1c3RlciBxdWVyeSBsYW5ndWFnZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvY2x1c3Rlci1xdWVyeS1sYW5ndWFnZS5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi10YXNrZGVmaW5pdGlvbnBsYWNlbWVudGNvbnN0cmFpbnQuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLXRhc2tkZWZpbml0aW9ucGxhY2VtZW50Y29uc3RyYWludC1leHByZXNzaW9uXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBleHByZXNzaW9uPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHR5cGUgb2YgY29uc3RyYWludC4gVGhlIGBNZW1iZXJPZmAgY29uc3RyYWludCByZXN0cmljdHMgc2VsZWN0aW9uIHRvIGJlIGZyb20gYSBncm91cCBvZiB2YWxpZCBjYW5kaWRhdGVzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi10YXNrZGVmaW5pdGlvbnBsYWNlbWVudGNvbnN0cmFpbnQuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLXRhc2tkZWZpbml0aW9ucGxhY2VtZW50Y29uc3RyYWludC10eXBlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB0eXBlOiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYFRhc2tEZWZpbml0aW9uUGxhY2VtZW50Q29uc3RyYWludFByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBUYXNrRGVmaW5pdGlvblBsYWNlbWVudENvbnN0cmFpbnRQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbl9UYXNrRGVmaW5pdGlvblBsYWNlbWVudENvbnN0cmFpbnRQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2V4cHJlc3Npb24nLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuZXhwcmVzc2lvbikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndHlwZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy50eXBlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0eXBlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnR5cGUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiVGFza0RlZmluaXRpb25QbGFjZW1lbnRDb25zdHJhaW50UHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uVGFza0RlZmluaXRpb25QbGFjZW1lbnRDb25zdHJhaW50YCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBUYXNrRGVmaW5pdGlvblBsYWNlbWVudENvbnN0cmFpbnRQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5UYXNrRGVmaW5pdGlvblBsYWNlbWVudENvbnN0cmFpbnRgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuVGFza0RlZmluaXRpb25UYXNrRGVmaW5pdGlvblBsYWNlbWVudENvbnN0cmFpbnRQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVGFza0RlZmluaXRpb25fVGFza0RlZmluaXRpb25QbGFjZW1lbnRDb25zdHJhaW50UHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEV4cHJlc3Npb246IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZXhwcmVzc2lvbiksXG4gICAgICAgIFR5cGU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMudHlwZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uVGFza0RlZmluaXRpb25QbGFjZW1lbnRDb25zdHJhaW50UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5UYXNrRGVmaW5pdGlvbi5UYXNrRGVmaW5pdGlvblBsYWNlbWVudENvbnN0cmFpbnRQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5UYXNrRGVmaW5pdGlvbi5UYXNrRGVmaW5pdGlvblBsYWNlbWVudENvbnN0cmFpbnRQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2V4cHJlc3Npb24nLCAnRXhwcmVzc2lvbicsIHByb3BlcnRpZXMuRXhwcmVzc2lvbiAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5FeHByZXNzaW9uKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0eXBlJywgJ1R5cGUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlR5cGUpKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5UYXNrRGVmaW5pdGlvbiB7XG4gICAgLyoqXG4gICAgICogVGhlIGNvbnRhaW5lciBwYXRoLCBtb3VudCBvcHRpb25zLCBhbmQgc2l6ZSBvZiB0aGUgdG1wZnMgbW91bnQuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tdG1wZnMuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgVG1wZnNQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYWJzb2x1dGUgZmlsZSBwYXRoIHdoZXJlIHRoZSB0bXBmcyB2b2x1bWUgaXMgdG8gYmUgbW91bnRlZC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tdG1wZnMuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLXRtcGZzLWNvbnRhaW5lcnBhdGhcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNvbnRhaW5lclBhdGg/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbGlzdCBvZiB0bXBmcyB2b2x1bWUgbW91bnQgb3B0aW9ucy5cbiAgICAgICAgICpcbiAgICAgICAgICogVmFsaWQgdmFsdWVzOiBgXCJkZWZhdWx0c1wiIHwgXCJyb1wiIHwgXCJyd1wiIHwgXCJzdWlkXCIgfCBcIm5vc3VpZFwiIHwgXCJkZXZcIiB8IFwibm9kZXZcIiB8IFwiZXhlY1wiIHwgXCJub2V4ZWNcIiB8IFwic3luY1wiIHwgXCJhc3luY1wiIHwgXCJkaXJzeW5jXCIgfCBcInJlbW91bnRcIiB8IFwibWFuZFwiIHwgXCJub21hbmRcIiB8IFwiYXRpbWVcIiB8IFwibm9hdGltZVwiIHwgXCJkaXJhdGltZVwiIHwgXCJub2RpcmF0aW1lXCIgfCBcImJpbmRcIiB8IFwicmJpbmRcIiB8IFwidW5iaW5kYWJsZVwiIHwgXCJydW5iaW5kYWJsZVwiIHwgXCJwcml2YXRlXCIgfCBcInJwcml2YXRlXCIgfCBcInNoYXJlZFwiIHwgXCJyc2hhcmVkXCIgfCBcInNsYXZlXCIgfCBcInJzbGF2ZVwiIHwgXCJyZWxhdGltZVwiIHwgXCJub3JlbGF0aW1lXCIgfCBcInN0cmljdGF0aW1lXCIgfCBcIm5vc3RyaWN0YXRpbWVcIiB8IFwibW9kZVwiIHwgXCJ1aWRcIiB8IFwiZ2lkXCIgfCBcIm5yX2lub2Rlc1wiIHwgXCJucl9ibG9ja3NcIiB8IFwibXBvbFwiYFxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi10bXBmcy5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tdG1wZnMtbW91bnRvcHRpb25zXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBtb3VudE9wdGlvbnM/OiBzdHJpbmdbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBtYXhpbXVtIHNpemUgKGluIE1pQikgb2YgdGhlIHRtcGZzIHZvbHVtZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tdG1wZnMuaHRtbCNjZm4tZWNzLXRhc2tkZWZpbml0aW9uLXRtcGZzLXNpemVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHNpemU6IG51bWJlcjtcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgVG1wZnNQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgVG1wZnNQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbl9UbXBmc1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY29udGFpbmVyUGF0aCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jb250YWluZXJQYXRoKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdtb3VudE9wdGlvbnMnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLm1vdW50T3B0aW9ucykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc2l6ZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5zaXplKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzaXplJywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLnNpemUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiVG1wZnNQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5UbXBmc2AgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgVG1wZnNQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5UbXBmc2AgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5UYXNrRGVmaW5pdGlvblRtcGZzUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblRhc2tEZWZpbml0aW9uX1RtcGZzUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIENvbnRhaW5lclBhdGg6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY29udGFpbmVyUGF0aCksXG4gICAgICAgIE1vdW50T3B0aW9uczogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMubW91bnRPcHRpb25zKSxcbiAgICAgICAgU2l6ZTogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zaXplKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25UbXBmc1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb24uVG1wZnNQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5UYXNrRGVmaW5pdGlvbi5UbXBmc1Byb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY29udGFpbmVyUGF0aCcsICdDb250YWluZXJQYXRoJywgcHJvcGVydGllcy5Db250YWluZXJQYXRoICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNvbnRhaW5lclBhdGgpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ21vdW50T3B0aW9ucycsICdNb3VudE9wdGlvbnMnLCBwcm9wZXJ0aWVzLk1vdW50T3B0aW9ucyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmdBcnJheShwcm9wZXJ0aWVzLk1vdW50T3B0aW9ucykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnc2l6ZScsICdTaXplJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5TaXplKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuVGFza0RlZmluaXRpb24ge1xuICAgIC8qKlxuICAgICAqIFRoZSBgdWxpbWl0YCBzZXR0aW5ncyB0byBwYXNzIHRvIHRoZSBjb250YWluZXIuXG4gICAgICpcbiAgICAgKiBBbWF6b24gRUNTIHRhc2tzIGhvc3RlZCBvbiBBV1MgRmFyZ2F0ZSB1c2UgdGhlIGRlZmF1bHQgcmVzb3VyY2UgbGltaXQgdmFsdWVzIHNldCBieSB0aGUgb3BlcmF0aW5nIHN5c3RlbSB3aXRoIHRoZSBleGNlcHRpb24gb2YgdGhlIGBub2ZpbGVgIHJlc291cmNlIGxpbWl0IHBhcmFtZXRlciB3aGljaCBBV1MgRmFyZ2F0ZSBvdmVycmlkZXMuIFRoZSBgbm9maWxlYCByZXNvdXJjZSBsaW1pdCBzZXRzIGEgcmVzdHJpY3Rpb24gb24gdGhlIG51bWJlciBvZiBvcGVuIGZpbGVzIHRoYXQgYSBjb250YWluZXIgY2FuIHVzZS4gVGhlIGRlZmF1bHQgYG5vZmlsZWAgc29mdCBsaW1pdCBpcyBgMTAyNGAgYW5kIHRoZSBkZWZhdWx0IGhhcmQgbGltaXQgaXMgYDQwOTZgIC5cbiAgICAgKlxuICAgICAqIFlvdSBjYW4gc3BlY2lmeSB0aGUgYHVsaW1pdGAgc2V0dGluZ3MgZm9yIGEgY29udGFpbmVyIGluIGEgdGFzayBkZWZpbml0aW9uLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXVsaW1pdC5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBVbGltaXRQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaGFyZCBsaW1pdCBmb3IgdGhlIGB1bGltaXRgIHR5cGUuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXVsaW1pdC5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tdWxpbWl0LWhhcmRsaW1pdFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgaGFyZExpbWl0OiBudW1iZXI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYHR5cGVgIG9mIHRoZSBgdWxpbWl0YCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXVsaW1pdC5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tdWxpbWl0LW5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzb2Z0IGxpbWl0IGZvciB0aGUgYHVsaW1pdGAgdHlwZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tdWxpbWl0Lmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi11bGltaXQtc29mdGxpbWl0XG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBzb2Z0TGltaXQ6IG51bWJlcjtcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgVWxpbWl0UHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYFVsaW1pdFByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblRhc2tEZWZpbml0aW9uX1VsaW1pdFByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaGFyZExpbWl0JywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmhhcmRMaW1pdCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaGFyZExpbWl0JywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLmhhcmRMaW1pdCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5uYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCduYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLm5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3NvZnRMaW1pdCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5zb2Z0TGltaXQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3NvZnRMaW1pdCcsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5zb2Z0TGltaXQpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiVWxpbWl0UHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uVWxpbWl0YCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBVbGltaXRQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5VbGltaXRgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuVGFza0RlZmluaXRpb25VbGltaXRQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVGFza0RlZmluaXRpb25fVWxpbWl0UHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEhhcmRMaW1pdDogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5oYXJkTGltaXQpLFxuICAgICAgICBOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm5hbWUpLFxuICAgICAgICBTb2Z0TGltaXQ6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuc29mdExpbWl0KSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25VbGltaXRQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblRhc2tEZWZpbml0aW9uLlVsaW1pdFByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblRhc2tEZWZpbml0aW9uLlVsaW1pdFByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaGFyZExpbWl0JywgJ0hhcmRMaW1pdCcsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuSGFyZExpbWl0KSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCduYW1lJywgJ05hbWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLk5hbWUpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3NvZnRMaW1pdCcsICdTb2Z0TGltaXQnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLlNvZnRMaW1pdCkpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblRhc2tEZWZpbml0aW9uIHtcbiAgICAvKipcbiAgICAgKiBUaGUgYFZvbHVtZWAgcHJvcGVydHkgc3BlY2lmaWVzIGEgZGF0YSB2b2x1bWUgdXNlZCBpbiBhIHRhc2sgZGVmaW5pdGlvbi4gRm9yIHRhc2tzIHRoYXQgdXNlIGEgRG9ja2VyIHZvbHVtZSwgc3BlY2lmeSBhIGBEb2NrZXJWb2x1bWVDb25maWd1cmF0aW9uYCAuIEZvciB0YXNrcyB0aGF0IHVzZSBhIGJpbmQgbW91bnQgaG9zdCB2b2x1bWUsIHNwZWNpZnkgYSBgaG9zdGAgYW5kIG9wdGlvbmFsIGBzb3VyY2VQYXRoYCAuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGBob3N0YCBhbmQgb3B0aW9uYWwgYHNvdXJjZVBhdGhgICwgc2VlIFtWb2x1bWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS90YXNrX2RlZmluaXRpb25fcGFyYW1ldGVycy5odG1sI3ZvbHVtZXMpIGFuZCBbVXNpbmcgRGF0YSBWb2x1bWVzIGluIFRhc2tzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS91c2luZ19kYXRhX3ZvbHVtZXMuaHRtbCkgLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXZvbHVtZS5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBWb2x1bWVQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBzcGVjaWZpZWQgd2hlbiB5b3UgdXNlIERvY2tlciB2b2x1bWVzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBXaW5kb3dzIGNvbnRhaW5lcnMgb25seSBzdXBwb3J0IHRoZSB1c2Ugb2YgdGhlIGBsb2NhbGAgZHJpdmVyLiBUbyB1c2UgYmluZCBtb3VudHMsIHNwZWNpZnkgdGhlIGBob3N0YCBwYXJhbWV0ZXIgaW5zdGVhZC5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBEb2NrZXIgdm9sdW1lcyBhcmVuJ3Qgc3VwcG9ydGVkIGJ5IHRhc2tzIHJ1biBvbiBBV1MgRmFyZ2F0ZSAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXZvbHVtZS5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tdm9sdW1lLWRvY2tlcnZvbHVtZWNvbmZpZ3VyYXRpb25cbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGRvY2tlclZvbHVtZUNvbmZpZ3VyYXRpb24/OiBDZm5UYXNrRGVmaW5pdGlvbi5Eb2NrZXJWb2x1bWVDb25maWd1cmF0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBzcGVjaWZpZWQgd2hlbiB5b3UgdXNlIGFuIEFtYXpvbiBFbGFzdGljIEZpbGUgU3lzdGVtIGZpbGUgc3lzdGVtIGZvciB0YXNrIHN0b3JhZ2UuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXZvbHVtZS5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tdm9sdW1lLWVmc3ZvbHVtZWNvbmZpZ3VyYXRpb25cbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGVmc1ZvbHVtZUNvbmZpZ3VyYXRpb24/OiBDZm5UYXNrRGVmaW5pdGlvbi5FRlNWb2x1bWVDb25maWd1cmF0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBzcGVjaWZpZWQgd2hlbiB5b3UgdXNlIGJpbmQgbW91bnQgaG9zdCB2b2x1bWVzLiBUaGUgY29udGVudHMgb2YgdGhlIGBob3N0YCBwYXJhbWV0ZXIgZGV0ZXJtaW5lIHdoZXRoZXIgeW91ciBiaW5kIG1vdW50IGhvc3Qgdm9sdW1lIHBlcnNpc3RzIG9uIHRoZSBob3N0IGNvbnRhaW5lciBpbnN0YW5jZSBhbmQgd2hlcmUgaXQncyBzdG9yZWQuIElmIHRoZSBgaG9zdGAgcGFyYW1ldGVyIGlzIGVtcHR5LCB0aGVuIHRoZSBEb2NrZXIgZGFlbW9uIGFzc2lnbnMgYSBob3N0IHBhdGggZm9yIHlvdXIgZGF0YSB2b2x1bWUuIEhvd2V2ZXIsIHRoZSBkYXRhIGlzbid0IGd1YXJhbnRlZWQgdG8gcGVyc2lzdCBhZnRlciB0aGUgY29udGFpbmVycyB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggaXQgc3RvcCBydW5uaW5nLlxuICAgICAgICAgKlxuICAgICAgICAgKiBXaW5kb3dzIGNvbnRhaW5lcnMgY2FuIG1vdW50IHdob2xlIGRpcmVjdG9yaWVzIG9uIHRoZSBzYW1lIGRyaXZlIGFzIGAkZW52OlByb2dyYW1EYXRhYCAuIFdpbmRvd3MgY29udGFpbmVycyBjYW4ndCBtb3VudCBkaXJlY3RvcmllcyBvbiBhIGRpZmZlcmVudCBkcml2ZSwgYW5kIG1vdW50IHBvaW50IGNhbid0IGJlIGFjcm9zcyBkcml2ZXMuIEZvciBleGFtcGxlLCB5b3UgY2FuIG1vdW50IGBDOlxcbXlcXHBhdGg6QzpcXG15XFxwYXRoYCBhbmQgYEQ6XFw6RDpcXGAgLCBidXQgbm90IGBEOlxcbXlcXHBhdGg6QzpcXG15XFxwYXRoYCBvciBgRDpcXDpDOlxcbXlcXHBhdGhgIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tdm9sdW1lLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi12b2x1bWUtaG9zdFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgaG9zdD86IENmblRhc2tEZWZpbml0aW9uLkhvc3RWb2x1bWVQcm9wZXJ0aWVzUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbmFtZSBvZiB0aGUgdm9sdW1lLiBVcCB0byAyNTUgbGV0dGVycyAodXBwZXJjYXNlIGFuZCBsb3dlcmNhc2UpLCBudW1iZXJzLCB1bmRlcnNjb3JlcywgYW5kIGh5cGhlbnMgYXJlIGFsbG93ZWQuIFRoaXMgbmFtZSBpcyByZWZlcmVuY2VkIGluIHRoZSBgc291cmNlVm9sdW1lYCBwYXJhbWV0ZXIgb2YgY29udGFpbmVyIGRlZmluaXRpb24gYG1vdW50UG9pbnRzYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXZvbHVtZS5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tdm9sdW1lLW5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IG5hbWU/OiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYFZvbHVtZVByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBWb2x1bWVQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvbl9Wb2x1bWVQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2RvY2tlclZvbHVtZUNvbmZpZ3VyYXRpb24nLCBDZm5UYXNrRGVmaW5pdGlvbl9Eb2NrZXJWb2x1bWVDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IpKHByb3BlcnRpZXMuZG9ja2VyVm9sdW1lQ29uZmlndXJhdGlvbikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZWZzVm9sdW1lQ29uZmlndXJhdGlvbicsIENmblRhc2tEZWZpbml0aW9uX0VGU1ZvbHVtZUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5lZnNWb2x1bWVDb25maWd1cmF0aW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdob3N0JywgQ2ZuVGFza0RlZmluaXRpb25fSG9zdFZvbHVtZVByb3BlcnRpZXNQcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5ob3N0KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCduYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLm5hbWUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiVm9sdW1lUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uVm9sdW1lYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBWb2x1bWVQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5Wb2x1bWVgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuVGFza0RlZmluaXRpb25Wb2x1bWVQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVGFza0RlZmluaXRpb25fVm9sdW1lUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIERvY2tlclZvbHVtZUNvbmZpZ3VyYXRpb246IGNmblRhc2tEZWZpbml0aW9uRG9ja2VyVm9sdW1lQ29uZmlndXJhdGlvblByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmRvY2tlclZvbHVtZUNvbmZpZ3VyYXRpb24pLFxuICAgICAgICBFRlNWb2x1bWVDb25maWd1cmF0aW9uOiBjZm5UYXNrRGVmaW5pdGlvbkVGU1ZvbHVtZUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5lZnNWb2x1bWVDb25maWd1cmF0aW9uKSxcbiAgICAgICAgSG9zdDogY2ZuVGFza0RlZmluaXRpb25Ib3N0Vm9sdW1lUHJvcGVydGllc1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmhvc3QpLFxuICAgICAgICBOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm5hbWUpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5UYXNrRGVmaW5pdGlvblZvbHVtZVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza0RlZmluaXRpb24uVm9sdW1lUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVGFza0RlZmluaXRpb24uVm9sdW1lUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdkb2NrZXJWb2x1bWVDb25maWd1cmF0aW9uJywgJ0RvY2tlclZvbHVtZUNvbmZpZ3VyYXRpb24nLCBwcm9wZXJ0aWVzLkRvY2tlclZvbHVtZUNvbmZpZ3VyYXRpb24gIT0gbnVsbCA/IENmblRhc2tEZWZpbml0aW9uRG9ja2VyVm9sdW1lQ29uZmlndXJhdGlvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuRG9ja2VyVm9sdW1lQ29uZmlndXJhdGlvbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZWZzVm9sdW1lQ29uZmlndXJhdGlvbicsICdFRlNWb2x1bWVDb25maWd1cmF0aW9uJywgcHJvcGVydGllcy5FRlNWb2x1bWVDb25maWd1cmF0aW9uICE9IG51bGwgPyBDZm5UYXNrRGVmaW5pdGlvbkVGU1ZvbHVtZUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLkVGU1ZvbHVtZUNvbmZpZ3VyYXRpb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2hvc3QnLCAnSG9zdCcsIHByb3BlcnRpZXMuSG9zdCAhPSBudWxsID8gQ2ZuVGFza0RlZmluaXRpb25Ib3N0Vm9sdW1lUHJvcGVydGllc1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuSG9zdCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbmFtZScsICdOYW1lJywgcHJvcGVydGllcy5OYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLk5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5UYXNrRGVmaW5pdGlvbiB7XG4gICAgLyoqXG4gICAgICogRGV0YWlscyBvbiBhIGRhdGEgdm9sdW1lIGZyb20gYW5vdGhlciBjb250YWluZXIgaW4gdGhlIHNhbWUgdGFzayBkZWZpbml0aW9uLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tkZWZpbml0aW9uLXZvbHVtZWZyb20uaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgVm9sdW1lRnJvbVByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIElmIHRoaXMgdmFsdWUgaXMgYHRydWVgICwgdGhlIGNvbnRhaW5lciBoYXMgcmVhZC1vbmx5IGFjY2VzcyB0byB0aGUgdm9sdW1lLiBJZiB0aGlzIHZhbHVlIGlzIGBmYWxzZWAgLCB0aGVuIHRoZSBjb250YWluZXIgY2FuIHdyaXRlIHRvIHRoZSB2b2x1bWUuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGBmYWxzZWAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi12b2x1bWVmcm9tLmh0bWwjY2ZuLWVjcy10YXNrZGVmaW5pdGlvbi12b2x1bWVmcm9tLXJlYWRvbmx5XG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSByZWFkT25seT86IGJvb2xlYW4gfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbmFtZSBvZiBhbm90aGVyIGNvbnRhaW5lciB3aXRoaW4gdGhlIHNhbWUgdGFzayBkZWZpbml0aW9uIHRvIG1vdW50IHZvbHVtZXMgZnJvbS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza2RlZmluaXRpb24tdm9sdW1lZnJvbS5odG1sI2Nmbi1lY3MtdGFza2RlZmluaXRpb24tdm9sdW1lZnJvbS1zb3VyY2Vjb250YWluZXJcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHNvdXJjZUNvbnRhaW5lcj86IHN0cmluZztcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgVm9sdW1lRnJvbVByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBWb2x1bWVGcm9tUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25fVm9sdW1lRnJvbVByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncmVhZE9ubHknLCBjZGsudmFsaWRhdGVCb29sZWFuKShwcm9wZXJ0aWVzLnJlYWRPbmx5KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzb3VyY2VDb250YWluZXInLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuc291cmNlQ29udGFpbmVyKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIlZvbHVtZUZyb21Qcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvbi5Wb2x1bWVGcm9tYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBWb2x1bWVGcm9tUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza0RlZmluaXRpb24uVm9sdW1lRnJvbWAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5UYXNrRGVmaW5pdGlvblZvbHVtZUZyb21Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVGFza0RlZmluaXRpb25fVm9sdW1lRnJvbVByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBSZWFkT25seTogY2RrLmJvb2xlYW5Ub0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucmVhZE9ubHkpLFxuICAgICAgICBTb3VyY2VDb250YWluZXI6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuc291cmNlQ29udGFpbmVyKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuVGFza0RlZmluaXRpb25Wb2x1bWVGcm9tUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5UYXNrRGVmaW5pdGlvbi5Wb2x1bWVGcm9tUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVGFza0RlZmluaXRpb24uVm9sdW1lRnJvbVByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncmVhZE9ubHknLCAnUmVhZE9ubHknLCBwcm9wZXJ0aWVzLlJlYWRPbmx5ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5SZWFkT25seSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnc291cmNlQ29udGFpbmVyJywgJ1NvdXJjZUNvbnRhaW5lcicsIHByb3BlcnRpZXMuU291cmNlQ29udGFpbmVyICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlNvdXJjZUNvbnRhaW5lcikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmblRhc2tTZXRgXG4gKlxuICogQHN0cnVjdFxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrc2V0Lmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5UYXNrU2V0UHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogVGhlIHNob3J0IG5hbWUgb3IgZnVsbCBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgY2x1c3RlciB0aGF0IGhvc3RzIHRoZSBzZXJ2aWNlIHRvIGNyZWF0ZSB0aGUgdGFzayBzZXQgaW4uXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtdGFza3NldC5odG1sI2Nmbi1lY3MtdGFza3NldC1jbHVzdGVyXG4gICAgICovXG4gICAgcmVhZG9ubHkgY2x1c3Rlcjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHNob3J0IG5hbWUgb3IgZnVsbCBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgc2VydmljZSB0byBjcmVhdGUgdGhlIHRhc2sgc2V0IGluLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tzZXQuaHRtbCNjZm4tZWNzLXRhc2tzZXQtc2VydmljZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IHNlcnZpY2U6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSB0YXNrIGRlZmluaXRpb24gZm9yIHRoZSB0YXNrcyBpbiB0aGUgdGFzayBzZXQgdG8gdXNlLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tzZXQuaHRtbCNjZm4tZWNzLXRhc2tzZXQtdGFza2RlZmluaXRpb25cbiAgICAgKi9cbiAgICByZWFkb25seSB0YXNrRGVmaW5pdGlvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQW4gb3B0aW9uYWwgbm9uLXVuaXF1ZSB0YWcgdGhhdCBpZGVudGlmaWVzIHRoaXMgdGFzayBzZXQgaW4gZXh0ZXJuYWwgc3lzdGVtcy4gSWYgdGhlIHRhc2sgc2V0IGlzIGFzc29jaWF0ZWQgd2l0aCBhIHNlcnZpY2UgZGlzY292ZXJ5IHJlZ2lzdHJ5LCB0aGUgdGFza3MgaW4gdGhpcyB0YXNrIHNldCB3aWxsIGhhdmUgdGhlIGBFQ1NfVEFTS19TRVRfRVhURVJOQUxfSURgIEFXUyBDbG91ZCBNYXAgYXR0cmlidXRlIHNldCB0byB0aGUgcHJvdmlkZWQgdmFsdWUuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtdGFza3NldC5odG1sI2Nmbi1lY3MtdGFza3NldC1leHRlcm5hbGlkXG4gICAgICovXG4gICAgcmVhZG9ubHkgZXh0ZXJuYWxJZD86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBsYXVuY2ggdHlwZSB0aGF0IG5ldyB0YXNrcyBpbiB0aGUgdGFzayBzZXQgdXNlcy4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQW1hem9uIEVDUyBsYXVuY2ggdHlwZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2xhdW5jaF90eXBlcy5odG1sKSBpbiB0aGUgKkFtYXpvbiBFbGFzdGljIENvbnRhaW5lciBTZXJ2aWNlIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogSWYgYSBgbGF1bmNoVHlwZWAgaXMgc3BlY2lmaWVkLCB0aGUgYGNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneWAgcGFyYW1ldGVyIG11c3QgYmUgb21pdHRlZC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrc2V0Lmh0bWwjY2ZuLWVjcy10YXNrc2V0LWxhdW5jaHR5cGVcbiAgICAgKi9cbiAgICByZWFkb25seSBsYXVuY2hUeXBlPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBsb2FkIGJhbGFuY2VyIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIGxvYWQgYmFsYW5jZXIgdG8gdXNlIHdpdGggdGhlIHRhc2sgc2V0LiBUaGUgc3VwcG9ydGVkIGxvYWQgYmFsYW5jZXIgdHlwZXMgYXJlIGVpdGhlciBhbiBBcHBsaWNhdGlvbiBMb2FkIEJhbGFuY2VyIG9yIGEgTmV0d29yayBMb2FkIEJhbGFuY2VyLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tzZXQuaHRtbCNjZm4tZWNzLXRhc2tzZXQtbG9hZGJhbGFuY2Vyc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IGxvYWRCYWxhbmNlcnM/OiBBcnJheTxDZm5UYXNrU2V0LkxvYWRCYWxhbmNlclByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuZXR3b3JrIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSB0YXNrIHNldC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrc2V0Lmh0bWwjY2ZuLWVjcy10YXNrc2V0LW5ldHdvcmtjb25maWd1cmF0aW9uXG4gICAgICovXG4gICAgcmVhZG9ubHkgbmV0d29ya0NvbmZpZ3VyYXRpb24/OiBDZm5UYXNrU2V0Lk5ldHdvcmtDb25maWd1cmF0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gdmVyc2lvbiB0aGF0IHRoZSB0YXNrcyBpbiB0aGUgdGFzayBzZXQgdXNlcy4gQSBwbGF0Zm9ybSB2ZXJzaW9uIGlzIHNwZWNpZmllZCBvbmx5IGZvciB0YXNrcyB1c2luZyB0aGUgRmFyZ2F0ZSBsYXVuY2ggdHlwZS4gSWYgb25lIGlzbid0IHNwZWNpZmllZCwgdGhlIGBMQVRFU1RgIHBsYXRmb3JtIHZlcnNpb24gaXMgdXNlZC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrc2V0Lmh0bWwjY2ZuLWVjcy10YXNrc2V0LXBsYXRmb3JtdmVyc2lvblxuICAgICAqL1xuICAgIHJlYWRvbmx5IHBsYXRmb3JtVmVyc2lvbj86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEEgZmxvYXRpbmctcG9pbnQgcGVyY2VudGFnZSBvZiB5b3VyIGRlc2lyZWQgbnVtYmVyIG9mIHRhc2tzIHRvIHBsYWNlIGFuZCBrZWVwIHJ1bm5pbmcgaW4gdGhlIHRhc2sgc2V0LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tzZXQuaHRtbCNjZm4tZWNzLXRhc2tzZXQtc2NhbGVcbiAgICAgKi9cbiAgICByZWFkb25seSBzY2FsZT86IENmblRhc2tTZXQuU2NhbGVQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBkZXRhaWxzIG9mIHRoZSBzZXJ2aWNlIGRpc2NvdmVyeSByZWdpc3RyaWVzIHRvIGFzc2lnbiB0byB0aGlzIHRhc2sgc2V0LiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtTZXJ2aWNlIGRpc2NvdmVyeV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvc2VydmljZS1kaXNjb3ZlcnkuaHRtbCkgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tzZXQuaHRtbCNjZm4tZWNzLXRhc2tzZXQtc2VydmljZXJlZ2lzdHJpZXNcbiAgICAgKi9cbiAgICByZWFkb25seSBzZXJ2aWNlUmVnaXN0cmllcz86IEFycmF5PENmblRhc2tTZXQuU2VydmljZVJlZ2lzdHJ5UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmblRhc2tTZXRQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuVGFza1NldFByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblRhc2tTZXRQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NsdXN0ZXInLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMuY2x1c3RlcikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY2x1c3RlcicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jbHVzdGVyKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdleHRlcm5hbElkJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmV4dGVybmFsSWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2xhdW5jaFR5cGUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMubGF1bmNoVHlwZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbG9hZEJhbGFuY2VycycsIGNkay5saXN0VmFsaWRhdG9yKENmblRhc2tTZXRfTG9hZEJhbGFuY2VyUHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLmxvYWRCYWxhbmNlcnMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ25ldHdvcmtDb25maWd1cmF0aW9uJywgQ2ZuVGFza1NldF9OZXR3b3JrQ29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKShwcm9wZXJ0aWVzLm5ldHdvcmtDb25maWd1cmF0aW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwbGF0Zm9ybVZlcnNpb24nLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucGxhdGZvcm1WZXJzaW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzY2FsZScsIENmblRhc2tTZXRfU2NhbGVQcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5zY2FsZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc2VydmljZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5zZXJ2aWNlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzZXJ2aWNlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnNlcnZpY2UpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3NlcnZpY2VSZWdpc3RyaWVzJywgY2RrLmxpc3RWYWxpZGF0b3IoQ2ZuVGFza1NldF9TZXJ2aWNlUmVnaXN0cnlQcm9wZXJ0eVZhbGlkYXRvcikpKHByb3BlcnRpZXMuc2VydmljZVJlZ2lzdHJpZXMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3Rhc2tEZWZpbml0aW9uJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnRhc2tEZWZpbml0aW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0YXNrRGVmaW5pdGlvbicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy50YXNrRGVmaW5pdGlvbikpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5UYXNrU2V0UHJvcHNcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza1NldGAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuVGFza1NldFByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tTZXRgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuVGFza1NldFByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5UYXNrU2V0UHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIENsdXN0ZXI6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY2x1c3RlciksXG4gICAgICAgIFNlcnZpY2U6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuc2VydmljZSksXG4gICAgICAgIFRhc2tEZWZpbml0aW9uOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnRhc2tEZWZpbml0aW9uKSxcbiAgICAgICAgRXh0ZXJuYWxJZDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5leHRlcm5hbElkKSxcbiAgICAgICAgTGF1bmNoVHlwZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5sYXVuY2hUeXBlKSxcbiAgICAgICAgTG9hZEJhbGFuY2VyczogY2RrLmxpc3RNYXBwZXIoY2ZuVGFza1NldExvYWRCYWxhbmNlclByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5sb2FkQmFsYW5jZXJzKSxcbiAgICAgICAgTmV0d29ya0NvbmZpZ3VyYXRpb246IGNmblRhc2tTZXROZXR3b3JrQ29uZmlndXJhdGlvblByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm5ldHdvcmtDb25maWd1cmF0aW9uKSxcbiAgICAgICAgUGxhdGZvcm1WZXJzaW9uOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBsYXRmb3JtVmVyc2lvbiksXG4gICAgICAgIFNjYWxlOiBjZm5UYXNrU2V0U2NhbGVQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zY2FsZSksXG4gICAgICAgIFNlcnZpY2VSZWdpc3RyaWVzOiBjZGsubGlzdE1hcHBlcihjZm5UYXNrU2V0U2VydmljZVJlZ2lzdHJ5UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnNlcnZpY2VSZWdpc3RyaWVzKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuVGFza1NldFByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza1NldFByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5UYXNrU2V0UHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjbHVzdGVyJywgJ0NsdXN0ZXInLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNsdXN0ZXIpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3NlcnZpY2UnLCAnU2VydmljZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuU2VydmljZSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndGFza0RlZmluaXRpb24nLCAnVGFza0RlZmluaXRpb24nLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlRhc2tEZWZpbml0aW9uKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdleHRlcm5hbElkJywgJ0V4dGVybmFsSWQnLCBwcm9wZXJ0aWVzLkV4dGVybmFsSWQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuRXh0ZXJuYWxJZCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbGF1bmNoVHlwZScsICdMYXVuY2hUeXBlJywgcHJvcGVydGllcy5MYXVuY2hUeXBlICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkxhdW5jaFR5cGUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2xvYWRCYWxhbmNlcnMnLCAnTG9hZEJhbGFuY2VycycsIHByb3BlcnRpZXMuTG9hZEJhbGFuY2VycyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5UYXNrU2V0TG9hZEJhbGFuY2VyUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuTG9hZEJhbGFuY2VycykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbmV0d29ya0NvbmZpZ3VyYXRpb24nLCAnTmV0d29ya0NvbmZpZ3VyYXRpb24nLCBwcm9wZXJ0aWVzLk5ldHdvcmtDb25maWd1cmF0aW9uICE9IG51bGwgPyBDZm5UYXNrU2V0TmV0d29ya0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLk5ldHdvcmtDb25maWd1cmF0aW9uKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwbGF0Zm9ybVZlcnNpb24nLCAnUGxhdGZvcm1WZXJzaW9uJywgcHJvcGVydGllcy5QbGF0Zm9ybVZlcnNpb24gIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuUGxhdGZvcm1WZXJzaW9uKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzY2FsZScsICdTY2FsZScsIHByb3BlcnRpZXMuU2NhbGUgIT0gbnVsbCA/IENmblRhc2tTZXRTY2FsZVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuU2NhbGUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3NlcnZpY2VSZWdpc3RyaWVzJywgJ1NlcnZpY2VSZWdpc3RyaWVzJywgcHJvcGVydGllcy5TZXJ2aWNlUmVnaXN0cmllcyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5UYXNrU2V0U2VydmljZVJlZ2lzdHJ5UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuU2VydmljZVJlZ2lzdHJpZXMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBBIENsb3VkRm9ybWF0aW9uIGBBV1M6OkVDUzo6VGFza1NldGBcbiAqXG4gKiBDcmVhdGUgYSB0YXNrIHNldCBpbiB0aGUgc3BlY2lmaWVkIGNsdXN0ZXIgYW5kIHNlcnZpY2UuIFRoaXMgaXMgdXNlZCB3aGVuIGEgc2VydmljZSB1c2VzIHRoZSBgRVhURVJOQUxgIGRlcGxveW1lbnQgY29udHJvbGxlciB0eXBlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBbWF6b24gRUNTIGRlcGxveW1lbnQgdHlwZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2RlcGxveW1lbnQtdHlwZXMuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAqXG4gKiBAY2xvdWRmb3JtYXRpb25SZXNvdXJjZSBBV1M6OkVDUzo6VGFza1NldFxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrc2V0Lmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIENmblRhc2tTZXQgZXh0ZW5kcyBjZGsuQ2ZuUmVzb3VyY2UgaW1wbGVtZW50cyBjZGsuSUluc3BlY3RhYmxlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgdHlwZSBuYW1lIGZvciB0aGlzIHJlc291cmNlIGNsYXNzLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSA9IFwiQVdTOjpFQ1M6OlRhc2tTZXRcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmblRhc2tTZXQge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmblRhc2tTZXRQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihyZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgQ2ZuVGFza1NldChzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgSUQgb2YgdGhlIHRhc2sgc2V0LlxuICAgICAqIEBjbG91ZGZvcm1hdGlvbkF0dHJpYnV0ZSBJZFxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBhdHRySWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBzaG9ydCBuYW1lIG9yIGZ1bGwgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIGNsdXN0ZXIgdGhhdCBob3N0cyB0aGUgc2VydmljZSB0byBjcmVhdGUgdGhlIHRhc2sgc2V0IGluLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tzZXQuaHRtbCNjZm4tZWNzLXRhc2tzZXQtY2x1c3RlclxuICAgICAqL1xuICAgIHB1YmxpYyBjbHVzdGVyOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc2hvcnQgbmFtZSBvciBmdWxsIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIG9mIHRoZSBzZXJ2aWNlIHRvIGNyZWF0ZSB0aGUgdGFzayBzZXQgaW4uXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtdGFza3NldC5odG1sI2Nmbi1lY3MtdGFza3NldC1zZXJ2aWNlXG4gICAgICovXG4gICAgcHVibGljIHNlcnZpY2U6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSB0YXNrIGRlZmluaXRpb24gZm9yIHRoZSB0YXNrcyBpbiB0aGUgdGFzayBzZXQgdG8gdXNlLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tzZXQuaHRtbCNjZm4tZWNzLXRhc2tzZXQtdGFza2RlZmluaXRpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgdGFza0RlZmluaXRpb246IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEFuIG9wdGlvbmFsIG5vbi11bmlxdWUgdGFnIHRoYXQgaWRlbnRpZmllcyB0aGlzIHRhc2sgc2V0IGluIGV4dGVybmFsIHN5c3RlbXMuIElmIHRoZSB0YXNrIHNldCBpcyBhc3NvY2lhdGVkIHdpdGggYSBzZXJ2aWNlIGRpc2NvdmVyeSByZWdpc3RyeSwgdGhlIHRhc2tzIGluIHRoaXMgdGFzayBzZXQgd2lsbCBoYXZlIHRoZSBgRUNTX1RBU0tfU0VUX0VYVEVSTkFMX0lEYCBBV1MgQ2xvdWQgTWFwIGF0dHJpYnV0ZSBzZXQgdG8gdGhlIHByb3ZpZGVkIHZhbHVlLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWNzLXRhc2tzZXQuaHRtbCNjZm4tZWNzLXRhc2tzZXQtZXh0ZXJuYWxpZFxuICAgICAqL1xuICAgIHB1YmxpYyBleHRlcm5hbElkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbGF1bmNoIHR5cGUgdGhhdCBuZXcgdGFza3MgaW4gdGhlIHRhc2sgc2V0IHVzZXMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0FtYXpvbiBFQ1MgbGF1bmNoIHR5cGVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9sYXVuY2hfdHlwZXMuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIElmIGEgYGxhdW5jaFR5cGVgIGlzIHNwZWNpZmllZCwgdGhlIGBjYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3lgIHBhcmFtZXRlciBtdXN0IGJlIG9taXR0ZWQuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtdGFza3NldC5odG1sI2Nmbi1lY3MtdGFza3NldC1sYXVuY2h0eXBlXG4gICAgICovXG4gICAgcHVibGljIGxhdW5jaFR5cGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEEgbG9hZCBiYWxhbmNlciBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBsb2FkIGJhbGFuY2VyIHRvIHVzZSB3aXRoIHRoZSB0YXNrIHNldC4gVGhlIHN1cHBvcnRlZCBsb2FkIGJhbGFuY2VyIHR5cGVzIGFyZSBlaXRoZXIgYW4gQXBwbGljYXRpb24gTG9hZCBCYWxhbmNlciBvciBhIE5ldHdvcmsgTG9hZCBCYWxhbmNlci5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrc2V0Lmh0bWwjY2ZuLWVjcy10YXNrc2V0LWxvYWRiYWxhbmNlcnNcbiAgICAgKi9cbiAgICBwdWJsaWMgbG9hZEJhbGFuY2VyczogQXJyYXk8Q2ZuVGFza1NldC5Mb2FkQmFsYW5jZXJQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmV0d29yayBjb25maWd1cmF0aW9uIGZvciB0aGUgdGFzayBzZXQuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtdGFza3NldC5odG1sI2Nmbi1lY3MtdGFza3NldC1uZXR3b3JrY29uZmlndXJhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBuZXR3b3JrQ29uZmlndXJhdGlvbjogQ2ZuVGFza1NldC5OZXR3b3JrQ29uZmlndXJhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIHZlcnNpb24gdGhhdCB0aGUgdGFza3MgaW4gdGhlIHRhc2sgc2V0IHVzZXMuIEEgcGxhdGZvcm0gdmVyc2lvbiBpcyBzcGVjaWZpZWQgb25seSBmb3IgdGFza3MgdXNpbmcgdGhlIEZhcmdhdGUgbGF1bmNoIHR5cGUuIElmIG9uZSBpc24ndCBzcGVjaWZpZWQsIHRoZSBgTEFURVNUYCBwbGF0Zm9ybSB2ZXJzaW9uIGlzIHVzZWQuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lY3MtdGFza3NldC5odG1sI2Nmbi1lY3MtdGFza3NldC1wbGF0Zm9ybXZlcnNpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgcGxhdGZvcm1WZXJzaW9uOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBBIGZsb2F0aW5nLXBvaW50IHBlcmNlbnRhZ2Ugb2YgeW91ciBkZXNpcmVkIG51bWJlciBvZiB0YXNrcyB0byBwbGFjZSBhbmQga2VlcCBydW5uaW5nIGluIHRoZSB0YXNrIHNldC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrc2V0Lmh0bWwjY2ZuLWVjcy10YXNrc2V0LXNjYWxlXG4gICAgICovXG4gICAgcHVibGljIHNjYWxlOiBDZm5UYXNrU2V0LlNjYWxlUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZGV0YWlscyBvZiB0aGUgc2VydmljZSBkaXNjb3ZlcnkgcmVnaXN0cmllcyB0byBhc3NpZ24gdG8gdGhpcyB0YXNrIHNldC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbU2VydmljZSBkaXNjb3ZlcnldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3NlcnZpY2UtZGlzY292ZXJ5Lmh0bWwpIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjcy10YXNrc2V0Lmh0bWwjY2ZuLWVjcy10YXNrc2V0LXNlcnZpY2VyZWdpc3RyaWVzXG4gICAgICovXG4gICAgcHVibGljIHNlcnZpY2VSZWdpc3RyaWVzOiBBcnJheTxDZm5UYXNrU2V0LlNlcnZpY2VSZWdpc3RyeVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpFQ1M6OlRhc2tTZXRgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNjb3BlIC0gc2NvcGUgaW4gd2hpY2ggdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkXG4gICAgICogQHBhcmFtIGlkICAgIC0gc2NvcGVkIGlkIG9mIHRoZSByZXNvdXJjZVxuICAgICAqIEBwYXJhbSBwcm9wcyAtIHJlc291cmNlIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENmblRhc2tTZXRQcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuVGFza1NldC5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ2NsdXN0ZXInLCB0aGlzKTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ3NlcnZpY2UnLCB0aGlzKTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ3Rhc2tEZWZpbml0aW9uJywgdGhpcyk7XG4gICAgICAgIHRoaXMuYXR0cklkID0gY2RrLlRva2VuLmFzU3RyaW5nKHRoaXMuZ2V0QXR0KCdJZCcpKTtcblxuICAgICAgICB0aGlzLmNsdXN0ZXIgPSBwcm9wcy5jbHVzdGVyO1xuICAgICAgICB0aGlzLnNlcnZpY2UgPSBwcm9wcy5zZXJ2aWNlO1xuICAgICAgICB0aGlzLnRhc2tEZWZpbml0aW9uID0gcHJvcHMudGFza0RlZmluaXRpb247XG4gICAgICAgIHRoaXMuZXh0ZXJuYWxJZCA9IHByb3BzLmV4dGVybmFsSWQ7XG4gICAgICAgIHRoaXMubGF1bmNoVHlwZSA9IHByb3BzLmxhdW5jaFR5cGU7XG4gICAgICAgIHRoaXMubG9hZEJhbGFuY2VycyA9IHByb3BzLmxvYWRCYWxhbmNlcnM7XG4gICAgICAgIHRoaXMubmV0d29ya0NvbmZpZ3VyYXRpb24gPSBwcm9wcy5uZXR3b3JrQ29uZmlndXJhdGlvbjtcbiAgICAgICAgdGhpcy5wbGF0Zm9ybVZlcnNpb24gPSBwcm9wcy5wbGF0Zm9ybVZlcnNpb247XG4gICAgICAgIHRoaXMuc2NhbGUgPSBwcm9wcy5zY2FsZTtcbiAgICAgICAgdGhpcy5zZXJ2aWNlUmVnaXN0cmllcyA9IHByb3BzLnNlcnZpY2VSZWdpc3RyaWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuVGFza1NldC5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FKTtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246cHJvcHNcIiwgdGhpcy5jZm5Qcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGNmblByb3BlcnRpZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY2x1c3RlcjogdGhpcy5jbHVzdGVyLFxuICAgICAgICAgICAgc2VydmljZTogdGhpcy5zZXJ2aWNlLFxuICAgICAgICAgICAgdGFza0RlZmluaXRpb246IHRoaXMudGFza0RlZmluaXRpb24sXG4gICAgICAgICAgICBleHRlcm5hbElkOiB0aGlzLmV4dGVybmFsSWQsXG4gICAgICAgICAgICBsYXVuY2hUeXBlOiB0aGlzLmxhdW5jaFR5cGUsXG4gICAgICAgICAgICBsb2FkQmFsYW5jZXJzOiB0aGlzLmxvYWRCYWxhbmNlcnMsXG4gICAgICAgICAgICBuZXR3b3JrQ29uZmlndXJhdGlvbjogdGhpcy5uZXR3b3JrQ29uZmlndXJhdGlvbixcbiAgICAgICAgICAgIHBsYXRmb3JtVmVyc2lvbjogdGhpcy5wbGF0Zm9ybVZlcnNpb24sXG4gICAgICAgICAgICBzY2FsZTogdGhpcy5zY2FsZSxcbiAgICAgICAgICAgIHNlcnZpY2VSZWdpc3RyaWVzOiB0aGlzLnNlcnZpY2VSZWdpc3RyaWVzLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmblRhc2tTZXRQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcHMpO1xuICAgIH1cbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5UYXNrU2V0IHtcbiAgICAvKipcbiAgICAgKiBBbiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBuZXR3b3JraW5nIGRldGFpbHMgZm9yIGEgdGFzayBvciBzZXJ2aWNlLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tzZXQtYXdzdnBjY29uZmlndXJhdGlvbi5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBBd3NWcGNDb25maWd1cmF0aW9uUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogV2hldGhlciB0aGUgdGFzaydzIGVsYXN0aWMgbmV0d29yayBpbnRlcmZhY2UgcmVjZWl2ZXMgYSBwdWJsaWMgSVAgYWRkcmVzcy4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgYERJU0FCTEVEYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tzZXQtYXdzdnBjY29uZmlndXJhdGlvbi5odG1sI2Nmbi1lY3MtdGFza3NldC1hd3N2cGNjb25maWd1cmF0aW9uLWFzc2lnbnB1YmxpY2lwXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBhc3NpZ25QdWJsaWNJcD86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBJRHMgb2YgdGhlIHNlY3VyaXR5IGdyb3VwcyBhc3NvY2lhdGVkIHdpdGggdGhlIHRhc2sgb3Igc2VydmljZS4gSWYgeW91IGRvbid0IHNwZWNpZnkgYSBzZWN1cml0eSBncm91cCwgdGhlIGRlZmF1bHQgc2VjdXJpdHkgZ3JvdXAgZm9yIHRoZSBWUEMgaXMgdXNlZC4gVGhlcmUncyBhIGxpbWl0IG9mIDUgc2VjdXJpdHkgZ3JvdXBzIHRoYXQgY2FuIGJlIHNwZWNpZmllZCBwZXIgYEF3c1ZwY0NvbmZpZ3VyYXRpb25gIC5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBBbGwgc3BlY2lmaWVkIHNlY3VyaXR5IGdyb3VwcyBtdXN0IGJlIGZyb20gdGhlIHNhbWUgVlBDLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrc2V0LWF3c3ZwY2NvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLXRhc2tzZXQtYXdzdnBjY29uZmlndXJhdGlvbi1zZWN1cml0eWdyb3Vwc1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgc2VjdXJpdHlHcm91cHM/OiBzdHJpbmdbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBJRHMgb2YgdGhlIHN1Ym5ldHMgYXNzb2NpYXRlZCB3aXRoIHRoZSB0YXNrIG9yIHNlcnZpY2UuIFRoZXJlJ3MgYSBsaW1pdCBvZiAxNiBzdWJuZXRzIHRoYXQgY2FuIGJlIHNwZWNpZmllZCBwZXIgYEF3c1ZwY0NvbmZpZ3VyYXRpb25gIC5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBBbGwgc3BlY2lmaWVkIHN1Ym5ldHMgbXVzdCBiZSBmcm9tIHRoZSBzYW1lIFZQQy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza3NldC1hd3N2cGNjb25maWd1cmF0aW9uLmh0bWwjY2ZuLWVjcy10YXNrc2V0LWF3c3ZwY2NvbmZpZ3VyYXRpb24tc3VibmV0c1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgc3VibmV0czogc3RyaW5nW107XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYEF3c1ZwY0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQXdzVnBjQ29uZmlndXJhdGlvblByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblRhc2tTZXRfQXdzVnBjQ29uZmlndXJhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignYXNzaWduUHVibGljSXAnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuYXNzaWduUHVibGljSXApKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3NlY3VyaXR5R3JvdXBzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5zZWN1cml0eUdyb3VwcykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc3VibmV0cycsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5zdWJuZXRzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzdWJuZXRzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5zdWJuZXRzKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkF3c1ZwY0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrU2V0LkF3c1ZwY0NvbmZpZ3VyYXRpb25gIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEF3c1ZwY0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrU2V0LkF3c1ZwY0NvbmZpZ3VyYXRpb25gIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuVGFza1NldEF3c1ZwY0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVGFza1NldF9Bd3NWcGNDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEFzc2lnblB1YmxpY0lwOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmFzc2lnblB1YmxpY0lwKSxcbiAgICAgICAgU2VjdXJpdHlHcm91cHM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnNlY3VyaXR5R3JvdXBzKSxcbiAgICAgICAgU3VibmV0czogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuc3VibmV0cyksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblRhc2tTZXRBd3NWcGNDb25maWd1cmF0aW9uUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5UYXNrU2V0LkF3c1ZwY0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5UYXNrU2V0LkF3c1ZwY0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2Fzc2lnblB1YmxpY0lwJywgJ0Fzc2lnblB1YmxpY0lwJywgcHJvcGVydGllcy5Bc3NpZ25QdWJsaWNJcCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Bc3NpZ25QdWJsaWNJcCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnc2VjdXJpdHlHcm91cHMnLCAnU2VjdXJpdHlHcm91cHMnLCBwcm9wZXJ0aWVzLlNlY3VyaXR5R3JvdXBzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuU2VjdXJpdHlHcm91cHMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3N1Ym5ldHMnLCAnU3VibmV0cycsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5TdWJuZXRzKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuVGFza1NldCB7XG4gICAgLyoqXG4gICAgICogVGhlIGxvYWQgYmFsYW5jZXIgY29uZmlndXJhdGlvbiB0byB1c2Ugd2l0aCBhIHNlcnZpY2Ugb3IgdGFzayBzZXQuXG4gICAgICpcbiAgICAgKiBXaGVuIHlvdSBhZGQsIHVwZGF0ZSwgb3IgcmVtb3ZlIGEgbG9hZCBiYWxhbmNlciBjb25maWd1cmF0aW9uLCBBbWF6b24gRUNTIHN0YXJ0cyBhIG5ldyBkZXBsb3ltZW50IHdpdGggdGhlIHVwZGF0ZWQgRWxhc3RpYyBMb2FkIEJhbGFuY2luZyBjb25maWd1cmF0aW9uLiBUaGlzIGNhdXNlcyB0YXNrcyB0byByZWdpc3RlciB0byBhbmQgZGVyZWdpc3RlciBmcm9tIGxvYWQgYmFsYW5jZXJzLlxuICAgICAqXG4gICAgICogV2UgcmVjb21tZW5kIHRoYXQgeW91IHZlcmlmeSB0aGlzIG9uIGEgdGVzdCBlbnZpcm9ubWVudCBiZWZvcmUgeW91IHVwZGF0ZSB0aGUgRWxhc3RpYyBMb2FkIEJhbGFuY2luZyBjb25maWd1cmF0aW9uLlxuICAgICAqXG4gICAgICogQSBzZXJ2aWNlLWxpbmtlZCByb2xlIGlzIHJlcXVpcmVkIGZvciBzZXJ2aWNlcyB0aGF0IHVzZSBtdWx0aXBsZSB0YXJnZXQgZ3JvdXBzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtVc2luZyBzZXJ2aWNlLWxpbmtlZCByb2xlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvdXNpbmctc2VydmljZS1saW5rZWQtcm9sZXMuaHRtbCkgaW4gdGhlICpBbWF6b24gRWxhc3RpYyBDb250YWluZXIgU2VydmljZSBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrc2V0LWxvYWRiYWxhbmNlci5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBMb2FkQmFsYW5jZXJQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbmFtZSBvZiB0aGUgY29udGFpbmVyIChhcyBpdCBhcHBlYXJzIGluIGEgY29udGFpbmVyIGRlZmluaXRpb24pIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBsb2FkIGJhbGFuY2VyLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrc2V0LWxvYWRiYWxhbmNlci5odG1sI2Nmbi1lY3MtdGFza3NldC1sb2FkYmFsYW5jZXItY29udGFpbmVybmFtZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY29udGFpbmVyTmFtZT86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwb3J0IG9uIHRoZSBjb250YWluZXIgdG8gYXNzb2NpYXRlIHdpdGggdGhlIGxvYWQgYmFsYW5jZXIuIFRoaXMgcG9ydCBtdXN0IGNvcnJlc3BvbmQgdG8gYSBgY29udGFpbmVyUG9ydGAgaW4gdGhlIHRhc2sgZGVmaW5pdGlvbiB0aGUgdGFza3MgaW4gdGhlIHNlcnZpY2UgYXJlIHVzaW5nLiBGb3IgdGFza3MgdGhhdCB1c2UgdGhlIEVDMiBsYXVuY2ggdHlwZSwgdGhlIGNvbnRhaW5lciBpbnN0YW5jZSB0aGV5J3JlIGxhdW5jaGVkIG9uIG11c3QgYWxsb3cgaW5ncmVzcyB0cmFmZmljIG9uIHRoZSBgaG9zdFBvcnRgIG9mIHRoZSBwb3J0IG1hcHBpbmcuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tzZXQtbG9hZGJhbGFuY2VyLmh0bWwjY2ZuLWVjcy10YXNrc2V0LWxvYWRiYWxhbmNlci1jb250YWluZXJwb3J0XG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBjb250YWluZXJQb3J0PzogbnVtYmVyO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5hbWUgb2YgdGhlIGxvYWQgYmFsYW5jZXIgdG8gYXNzb2NpYXRlIHdpdGggdGhlIEFtYXpvbiBFQ1Mgc2VydmljZSBvciB0YXNrIHNldC5cbiAgICAgICAgICpcbiAgICAgICAgICogQSBsb2FkIGJhbGFuY2VyIG5hbWUgaXMgb25seSBzcGVjaWZpZWQgd2hlbiB1c2luZyBhIENsYXNzaWMgTG9hZCBCYWxhbmNlci4gSWYgeW91IGFyZSB1c2luZyBhbiBBcHBsaWNhdGlvbiBMb2FkIEJhbGFuY2VyIG9yIGEgTmV0d29yayBMb2FkIEJhbGFuY2VyIHRoZSBsb2FkIGJhbGFuY2VyIG5hbWUgcGFyYW1ldGVyIHNob3VsZCBiZSBvbWl0dGVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrc2V0LWxvYWRiYWxhbmNlci5odG1sI2Nmbi1lY3MtdGFza3NldC1sb2FkYmFsYW5jZXItbG9hZGJhbGFuY2VybmFtZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbG9hZEJhbGFuY2VyTmFtZT86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBmdWxsIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIG9mIHRoZSBFbGFzdGljIExvYWQgQmFsYW5jaW5nIHRhcmdldCBncm91cCBvciBncm91cHMgYXNzb2NpYXRlZCB3aXRoIGEgc2VydmljZSBvciB0YXNrIHNldC5cbiAgICAgICAgICpcbiAgICAgICAgICogQSB0YXJnZXQgZ3JvdXAgQVJOIGlzIG9ubHkgc3BlY2lmaWVkIHdoZW4gdXNpbmcgYW4gQXBwbGljYXRpb24gTG9hZCBCYWxhbmNlciBvciBOZXR3b3JrIExvYWQgQmFsYW5jZXIuIElmIHlvdSdyZSB1c2luZyBhIENsYXNzaWMgTG9hZCBCYWxhbmNlciwgb21pdCB0aGUgdGFyZ2V0IGdyb3VwIEFSTi5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIHNlcnZpY2VzIHVzaW5nIHRoZSBgRUNTYCBkZXBsb3ltZW50IGNvbnRyb2xsZXIsIHlvdSBjYW4gc3BlY2lmeSBvbmUgb3IgbXVsdGlwbGUgdGFyZ2V0IGdyb3Vwcy4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbUmVnaXN0ZXJpbmcgbXVsdGlwbGUgdGFyZ2V0IGdyb3VwcyB3aXRoIGEgc2VydmljZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvcmVnaXN0ZXItbXVsdGlwbGUtdGFyZ2V0Z3JvdXBzLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEZvciBzZXJ2aWNlcyB1c2luZyB0aGUgYENPREVfREVQTE9ZYCBkZXBsb3ltZW50IGNvbnRyb2xsZXIsIHlvdSdyZSByZXF1aXJlZCB0byBkZWZpbmUgdHdvIHRhcmdldCBncm91cHMgZm9yIHRoZSBsb2FkIGJhbGFuY2VyLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtCbHVlL2dyZWVuIGRlcGxveW1lbnQgd2l0aCBDb2RlRGVwbG95XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9kZXBsb3ltZW50LXR5cGUtYmx1ZWdyZWVuLmh0bWwpIGluIHRoZSAqQW1hem9uIEVsYXN0aWMgQ29udGFpbmVyIFNlcnZpY2UgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gSWYgeW91ciBzZXJ2aWNlJ3MgdGFzayBkZWZpbml0aW9uIHVzZXMgdGhlIGBhd3N2cGNgIG5ldHdvcmsgbW9kZSwgeW91IG11c3QgY2hvb3NlIGBpcGAgYXMgdGhlIHRhcmdldCB0eXBlLCBub3QgYGluc3RhbmNlYCAuIERvIHRoaXMgd2hlbiBjcmVhdGluZyB5b3VyIHRhcmdldCBncm91cHMgYmVjYXVzZSB0YXNrcyB0aGF0IHVzZSB0aGUgYGF3c3ZwY2AgbmV0d29yayBtb2RlIGFyZSBhc3NvY2lhdGVkIHdpdGggYW4gZWxhc3RpYyBuZXR3b3JrIGludGVyZmFjZSwgbm90IGFuIEFtYXpvbiBFQzIgaW5zdGFuY2UuIFRoaXMgbmV0d29yayBtb2RlIGlzIHJlcXVpcmVkIGZvciB0aGUgRmFyZ2F0ZSBsYXVuY2ggdHlwZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza3NldC1sb2FkYmFsYW5jZXIuaHRtbCNjZm4tZWNzLXRhc2tzZXQtbG9hZGJhbGFuY2VyLXRhcmdldGdyb3VwYXJuXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB0YXJnZXRHcm91cEFybj86IHN0cmluZztcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgTG9hZEJhbGFuY2VyUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYExvYWRCYWxhbmNlclByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblRhc2tTZXRfTG9hZEJhbGFuY2VyUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjb250YWluZXJOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmNvbnRhaW5lck5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvbnRhaW5lclBvcnQnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMuY29udGFpbmVyUG9ydCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbG9hZEJhbGFuY2VyTmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5sb2FkQmFsYW5jZXJOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0YXJnZXRHcm91cEFybicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy50YXJnZXRHcm91cEFybikpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJMb2FkQmFsYW5jZXJQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrU2V0LkxvYWRCYWxhbmNlcmAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgTG9hZEJhbGFuY2VyUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza1NldC5Mb2FkQmFsYW5jZXJgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuVGFza1NldExvYWRCYWxhbmNlclByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5UYXNrU2V0X0xvYWRCYWxhbmNlclByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBDb250YWluZXJOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNvbnRhaW5lck5hbWUpLFxuICAgICAgICBDb250YWluZXJQb3J0OiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNvbnRhaW5lclBvcnQpLFxuICAgICAgICBMb2FkQmFsYW5jZXJOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmxvYWRCYWxhbmNlck5hbWUpLFxuICAgICAgICBUYXJnZXRHcm91cEFybjogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy50YXJnZXRHcm91cEFybiksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblRhc2tTZXRMb2FkQmFsYW5jZXJQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblRhc2tTZXQuTG9hZEJhbGFuY2VyUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVGFza1NldC5Mb2FkQmFsYW5jZXJQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2NvbnRhaW5lck5hbWUnLCAnQ29udGFpbmVyTmFtZScsIHByb3BlcnRpZXMuQ29udGFpbmVyTmFtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Db250YWluZXJOYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjb250YWluZXJQb3J0JywgJ0NvbnRhaW5lclBvcnQnLCBwcm9wZXJ0aWVzLkNvbnRhaW5lclBvcnQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuQ29udGFpbmVyUG9ydCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbG9hZEJhbGFuY2VyTmFtZScsICdMb2FkQmFsYW5jZXJOYW1lJywgcHJvcGVydGllcy5Mb2FkQmFsYW5jZXJOYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkxvYWRCYWxhbmNlck5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3RhcmdldEdyb3VwQXJuJywgJ1RhcmdldEdyb3VwQXJuJywgcHJvcGVydGllcy5UYXJnZXRHcm91cEFybiAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5UYXJnZXRHcm91cEFybikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblRhc2tTZXQge1xuICAgIC8qKlxuICAgICAqIFRoZSBuZXR3b3JrIGNvbmZpZ3VyYXRpb24gZm9yIGEgdGFzayBvciBzZXJ2aWNlLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tzZXQtbmV0d29ya2NvbmZpZ3VyYXRpb24uaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgTmV0d29ya0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgVlBDIHN1Ym5ldHMgYW5kIHNlY3VyaXR5IGdyb3VwcyB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggYSB0YXNrLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IEFsbCBzcGVjaWZpZWQgc3VibmV0cyBhbmQgc2VjdXJpdHkgZ3JvdXBzIG11c3QgYmUgZnJvbSB0aGUgc2FtZSBWUEMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tzZXQtbmV0d29ya2NvbmZpZ3VyYXRpb24uaHRtbCNjZm4tZWNzLXRhc2tzZXQtbmV0d29ya2NvbmZpZ3VyYXRpb24tYXdzdnBjY29uZmlndXJhdGlvblxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgYXdzVnBjQ29uZmlndXJhdGlvbj86IENmblRhc2tTZXQuQXdzVnBjQ29uZmlndXJhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBOZXR3b3JrQ29uZmlndXJhdGlvblByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBOZXR3b3JrQ29uZmlndXJhdGlvblByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblRhc2tTZXRfTmV0d29ya0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2F3c1ZwY0NvbmZpZ3VyYXRpb24nLCBDZm5UYXNrU2V0X0F3c1ZwY0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5hd3NWcGNDb25maWd1cmF0aW9uKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIk5ldHdvcmtDb25maWd1cmF0aW9uUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza1NldC5OZXR3b3JrQ29uZmlndXJhdGlvbmAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgTmV0d29ya0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrU2V0Lk5ldHdvcmtDb25maWd1cmF0aW9uYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblRhc2tTZXROZXR3b3JrQ29uZmlndXJhdGlvblByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5UYXNrU2V0X05ldHdvcmtDb25maWd1cmF0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEF3c1ZwY0NvbmZpZ3VyYXRpb246IGNmblRhc2tTZXRBd3NWcGNDb25maWd1cmF0aW9uUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuYXdzVnBjQ29uZmlndXJhdGlvbiksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblRhc2tTZXROZXR3b3JrQ29uZmlndXJhdGlvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza1NldC5OZXR3b3JrQ29uZmlndXJhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblRhc2tTZXQuTmV0d29ya0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2F3c1ZwY0NvbmZpZ3VyYXRpb24nLCAnQXdzVnBjQ29uZmlndXJhdGlvbicsIHByb3BlcnRpZXMuQXdzVnBjQ29uZmlndXJhdGlvbiAhPSBudWxsID8gQ2ZuVGFza1NldEF3c1ZwY0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLkF3c1ZwY0NvbmZpZ3VyYXRpb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5UYXNrU2V0IHtcbiAgICAvKipcbiAgICAgKiBBIGZsb2F0aW5nLXBvaW50IHBlcmNlbnRhZ2Ugb2YgdGhlIGRlc2lyZWQgbnVtYmVyIG9mIHRhc2tzIHRvIHBsYWNlIGFuZCBrZWVwIHJ1bm5pbmcgaW4gdGhlIHRhc2sgc2V0LlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tzZXQtc2NhbGUuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgU2NhbGVQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdW5pdCBvZiBtZWFzdXJlIGZvciB0aGUgc2NhbGUgdmFsdWUuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tzZXQtc2NhbGUuaHRtbCNjZm4tZWNzLXRhc2tzZXQtc2NhbGUtdW5pdFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgdW5pdD86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2YWx1ZSwgc3BlY2lmaWVkIGFzIGEgcGVyY2VudCB0b3RhbCBvZiBhIHNlcnZpY2UncyBgZGVzaXJlZENvdW50YCAsIHRvIHNjYWxlIHRoZSB0YXNrIHNldC4gQWNjZXB0ZWQgdmFsdWVzIGFyZSBudW1iZXJzIGJldHdlZW4gMCBhbmQgMTAwLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrc2V0LXNjYWxlLmh0bWwjY2ZuLWVjcy10YXNrc2V0LXNjYWxlLXZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB2YWx1ZT86IG51bWJlcjtcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgU2NhbGVQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgU2NhbGVQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5UYXNrU2V0X1NjYWxlUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd1bml0JywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnVuaXQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3ZhbHVlJywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLnZhbHVlKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIlNjYWxlUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkVDUzo6VGFza1NldC5TY2FsZWAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgU2NhbGVQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrU2V0LlNjYWxlYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblRhc2tTZXRTY2FsZVByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5UYXNrU2V0X1NjYWxlUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIFVuaXQ6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMudW5pdCksXG4gICAgICAgIFZhbHVlOiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnZhbHVlKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuVGFza1NldFNjYWxlUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5UYXNrU2V0LlNjYWxlUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVGFza1NldC5TY2FsZVByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndW5pdCcsICdVbml0JywgcHJvcGVydGllcy5Vbml0ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlVuaXQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3ZhbHVlJywgJ1ZhbHVlJywgcHJvcGVydGllcy5WYWx1ZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5WYWx1ZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblRhc2tTZXQge1xuICAgIC8qKlxuICAgICAqIFRoZSBkZXRhaWxzIGZvciB0aGUgc2VydmljZSByZWdpc3RyeS5cbiAgICAgKlxuICAgICAqIEVhY2ggc2VydmljZSBtYXkgYmUgYXNzb2NpYXRlZCB3aXRoIG9uZSBzZXJ2aWNlIHJlZ2lzdHJ5LiBNdWx0aXBsZSBzZXJ2aWNlIHJlZ2lzdHJpZXMgZm9yIGVhY2ggc2VydmljZSBhcmUgbm90IHN1cHBvcnRlZC5cbiAgICAgKlxuICAgICAqIFdoZW4geW91IGFkZCwgdXBkYXRlLCBvciByZW1vdmUgdGhlIHNlcnZpY2UgcmVnaXN0cmllcyBjb25maWd1cmF0aW9uLCBBbWF6b24gRUNTIHN0YXJ0cyBhIG5ldyBkZXBsb3ltZW50LiBOZXcgdGFza3MgYXJlIHJlZ2lzdGVyZWQgYW5kIGRlcmVnaXN0ZXJlZCB0byB0aGUgdXBkYXRlZCBzZXJ2aWNlIHJlZ2lzdHJ5IGNvbmZpZ3VyYXRpb24uXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza3NldC1zZXJ2aWNlcmVnaXN0cnkuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgU2VydmljZVJlZ2lzdHJ5UHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGNvbnRhaW5lciBuYW1lIHZhbHVlIHRvIGJlIHVzZWQgZm9yIHlvdXIgc2VydmljZSBkaXNjb3Zlcnkgc2VydmljZS4gSXQncyBhbHJlYWR5IHNwZWNpZmllZCBpbiB0aGUgdGFzayBkZWZpbml0aW9uLiBJZiB0aGUgdGFzayBkZWZpbml0aW9uIHRoYXQgeW91ciBzZXJ2aWNlIHRhc2sgc3BlY2lmaWVzIHVzZXMgdGhlIGBicmlkZ2VgIG9yIGBob3N0YCBuZXR3b3JrIG1vZGUsIHlvdSBtdXN0IHNwZWNpZnkgYSBgY29udGFpbmVyTmFtZWAgYW5kIGBjb250YWluZXJQb3J0YCBjb21iaW5hdGlvbiBmcm9tIHRoZSB0YXNrIGRlZmluaXRpb24uIElmIHRoZSB0YXNrIGRlZmluaXRpb24gdGhhdCB5b3VyIHNlcnZpY2UgdGFzayBzcGVjaWZpZXMgdXNlcyB0aGUgYGF3c3ZwY2AgbmV0d29yayBtb2RlIGFuZCBhIHR5cGUgU1JWIEROUyByZWNvcmQgaXMgdXNlZCwgeW91IG11c3Qgc3BlY2lmeSBlaXRoZXIgYSBgY29udGFpbmVyTmFtZWAgYW5kIGBjb250YWluZXJQb3J0YCBjb21iaW5hdGlvbiBvciBhIGBwb3J0YCB2YWx1ZS4gSG93ZXZlciwgeW91IGNhbid0IHNwZWNpZnkgYm90aC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza3NldC1zZXJ2aWNlcmVnaXN0cnkuaHRtbCNjZm4tZWNzLXRhc2tzZXQtc2VydmljZXJlZ2lzdHJ5LWNvbnRhaW5lcm5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNvbnRhaW5lck5hbWU/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcG9ydCB2YWx1ZSB0byBiZSB1c2VkIGZvciB5b3VyIHNlcnZpY2UgZGlzY292ZXJ5IHNlcnZpY2UuIEl0J3MgYWxyZWFkeSBzcGVjaWZpZWQgaW4gdGhlIHRhc2sgZGVmaW5pdGlvbi4gSWYgdGhlIHRhc2sgZGVmaW5pdGlvbiB5b3VyIHNlcnZpY2UgdGFzayBzcGVjaWZpZXMgdXNlcyB0aGUgYGJyaWRnZWAgb3IgYGhvc3RgIG5ldHdvcmsgbW9kZSwgeW91IG11c3Qgc3BlY2lmeSBhIGBjb250YWluZXJOYW1lYCBhbmQgYGNvbnRhaW5lclBvcnRgIGNvbWJpbmF0aW9uIGZyb20gdGhlIHRhc2sgZGVmaW5pdGlvbi4gSWYgdGhlIHRhc2sgZGVmaW5pdGlvbiB5b3VyIHNlcnZpY2UgdGFzayBzcGVjaWZpZXMgdXNlcyB0aGUgYGF3c3ZwY2AgbmV0d29yayBtb2RlIGFuZCBhIHR5cGUgU1JWIEROUyByZWNvcmQgaXMgdXNlZCwgeW91IG11c3Qgc3BlY2lmeSBlaXRoZXIgYSBgY29udGFpbmVyTmFtZWAgYW5kIGBjb250YWluZXJQb3J0YCBjb21iaW5hdGlvbiBvciBhIGBwb3J0YCB2YWx1ZS4gSG93ZXZlciwgeW91IGNhbid0IHNwZWNpZnkgYm90aC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lY3MtdGFza3NldC1zZXJ2aWNlcmVnaXN0cnkuaHRtbCNjZm4tZWNzLXRhc2tzZXQtc2VydmljZXJlZ2lzdHJ5LWNvbnRhaW5lcnBvcnRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNvbnRhaW5lclBvcnQ/OiBudW1iZXI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcG9ydCB2YWx1ZSB1c2VkIGlmIHlvdXIgc2VydmljZSBkaXNjb3Zlcnkgc2VydmljZSBzcGVjaWZpZWQgYW4gU1JWIHJlY29yZC4gVGhpcyBmaWVsZCBtaWdodCBiZSB1c2VkIGlmIGJvdGggdGhlIGBhd3N2cGNgIG5ldHdvcmsgbW9kZSBhbmQgU1JWIHJlY29yZHMgYXJlIHVzZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWNzLXRhc2tzZXQtc2VydmljZXJlZ2lzdHJ5Lmh0bWwjY2ZuLWVjcy10YXNrc2V0LXNlcnZpY2VyZWdpc3RyeS1wb3J0XG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBwb3J0PzogbnVtYmVyO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIG9mIHRoZSBzZXJ2aWNlIHJlZ2lzdHJ5LiBUaGUgY3VycmVudGx5IHN1cHBvcnRlZCBzZXJ2aWNlIHJlZ2lzdHJ5IGlzIEFXUyBDbG91ZCBNYXAgLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtDcmVhdGVTZXJ2aWNlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWQtbWFwL2xhdGVzdC9hcGkvQVBJX0NyZWF0ZVNlcnZpY2UuaHRtbCkgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrc2V0LXNlcnZpY2VyZWdpc3RyeS5odG1sI2Nmbi1lY3MtdGFza3NldC1zZXJ2aWNlcmVnaXN0cnktcmVnaXN0cnlhcm5cbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHJlZ2lzdHJ5QXJuPzogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBTZXJ2aWNlUmVnaXN0cnlQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgU2VydmljZVJlZ2lzdHJ5UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuVGFza1NldF9TZXJ2aWNlUmVnaXN0cnlQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvbnRhaW5lck5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY29udGFpbmVyTmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY29udGFpbmVyUG9ydCcsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5jb250YWluZXJQb3J0KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwb3J0JywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLnBvcnQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3JlZ2lzdHJ5QXJuJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnJlZ2lzdHJ5QXJuKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIlNlcnZpY2VSZWdpc3RyeVByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpFQ1M6OlRhc2tTZXQuU2VydmljZVJlZ2lzdHJ5YCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBTZXJ2aWNlUmVnaXN0cnlQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6RUNTOjpUYXNrU2V0LlNlcnZpY2VSZWdpc3RyeWAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5UYXNrU2V0U2VydmljZVJlZ2lzdHJ5UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblRhc2tTZXRfU2VydmljZVJlZ2lzdHJ5UHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIENvbnRhaW5lck5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY29udGFpbmVyTmFtZSksXG4gICAgICAgIENvbnRhaW5lclBvcnQ6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY29udGFpbmVyUG9ydCksXG4gICAgICAgIFBvcnQ6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucG9ydCksXG4gICAgICAgIFJlZ2lzdHJ5QXJuOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnJlZ2lzdHJ5QXJuKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuVGFza1NldFNlcnZpY2VSZWdpc3RyeVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVGFza1NldC5TZXJ2aWNlUmVnaXN0cnlQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5UYXNrU2V0LlNlcnZpY2VSZWdpc3RyeVByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY29udGFpbmVyTmFtZScsICdDb250YWluZXJOYW1lJywgcHJvcGVydGllcy5Db250YWluZXJOYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNvbnRhaW5lck5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2NvbnRhaW5lclBvcnQnLCAnQ29udGFpbmVyUG9ydCcsIHByb3BlcnRpZXMuQ29udGFpbmVyUG9ydCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5Db250YWluZXJQb3J0KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwb3J0JywgJ1BvcnQnLCBwcm9wZXJ0aWVzLlBvcnQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuUG9ydCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncmVnaXN0cnlBcm4nLCAnUmVnaXN0cnlBcm4nLCBwcm9wZXJ0aWVzLlJlZ2lzdHJ5QXJuICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlJlZ2lzdHJ5QXJuKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG4iXX0=
\No newline at end of file