UNPKG

512 kBJavaScriptView Raw
1"use strict";
2var _a, _b, _c, _d, _e, _f;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.CfnRecordSetGroup = exports.CfnRecordSet = exports.CfnKeySigningKey = exports.CfnHostedZone = exports.CfnHealthCheck = exports.CfnDNSSEC = void 0;
5const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
6const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
7// Copyright 2012-2022 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":"2022-06-14T13:26:19.796Z","fingerprint":"QNOBFTdd3AaNEhIWkon+24g3H6E5Qvhzr/GS7mw34MI="}
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 `CfnDNSSECProps`
16 *
17 * @param properties - the TypeScript properties of a `CfnDNSSECProps`
18 *
19 * @returns the result of the validation.
20 */
21function CfnDNSSECPropsValidator(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('hostedZoneId', cdk.requiredValidator)(properties.hostedZoneId));
30 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.validateString)(properties.hostedZoneId));
31 return errors.wrap('supplied properties not correct for "CfnDNSSECProps"');
32}
33/**
34 * Renders the AWS CloudFormation properties of an `AWS::Route53::DNSSEC` resource
35 *
36 * @param properties - the TypeScript properties of a `CfnDNSSECProps`
37 *
38 * @returns the AWS CloudFormation properties of an `AWS::Route53::DNSSEC` resource.
39 */
40// @ts-ignore TS6133
41function cfnDNSSECPropsToCloudFormation(properties) {
42 if (!cdk.canInspect(properties)) {
43 return properties;
44 }
45 CfnDNSSECPropsValidator(properties).assertSuccess();
46 return {
47 HostedZoneId: cdk.stringToCloudFormation(properties.hostedZoneId),
48 };
49}
50// @ts-ignore TS6133
51function CfnDNSSECPropsFromCloudFormation(properties) {
52 properties = properties == null ? {} : properties;
53 if (typeof properties !== 'object') {
54 return new cfn_parse.FromCloudFormationResult(properties);
55 }
56 const ret = new cfn_parse.FromCloudFormationPropertyObject();
57 ret.addPropertyResult('hostedZoneId', 'HostedZoneId', cfn_parse.FromCloudFormation.getString(properties.HostedZoneId));
58 ret.addUnrecognizedPropertiesAsExtra(properties);
59 return ret;
60}
61/**
62 * A CloudFormation `AWS::Route53::DNSSEC`
63 *
64 * The `AWS::Route53::DNSSEC` resource is used to enable DNSSEC signing in a hosted zone.
65 *
66 * @cloudformationResource AWS::Route53::DNSSEC
67 * @stability external
68 *
69 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53-dnssec.html
70 */
71class CfnDNSSEC extends cdk.CfnResource {
72 /**
73 * Create a new `AWS::Route53::DNSSEC`.
74 *
75 * @param scope - scope in which this resource is defined
76 * @param id - scoped id of the resource
77 * @param props - resource properties
78 */
79 constructor(scope, id, props) {
80 super(scope, id, { type: CfnDNSSEC.CFN_RESOURCE_TYPE_NAME, properties: props });
81 try {
82 jsiiDeprecationWarnings._aws_cdk_aws_route53_CfnDNSSECProps(props);
83 }
84 catch (error) {
85 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
86 Error.captureStackTrace(error, CfnDNSSEC);
87 }
88 throw error;
89 }
90 cdk.requireProperty(props, 'hostedZoneId', this);
91 this.hostedZoneId = props.hostedZoneId;
92 }
93 /**
94 * A factory method that creates a new instance of this class from an object
95 * containing the CloudFormation properties of this resource.
96 * Used in the @aws-cdk/cloudformation-include module.
97 *
98 * @internal
99 */
100 static _fromCloudFormation(scope, id, resourceAttributes, options) {
101 resourceAttributes = resourceAttributes || {};
102 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
103 const propsResult = CfnDNSSECPropsFromCloudFormation(resourceProperties);
104 const ret = new CfnDNSSEC(scope, id, propsResult.value);
105 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
106 ret.addPropertyOverride(propKey, propVal);
107 }
108 options.parser.handleAttributes(ret, resourceAttributes, id);
109 return ret;
110 }
111 /**
112 * Examines the CloudFormation resource and discloses attributes.
113 *
114 * @param inspector - tree inspector to collect and process attributes
115 *
116 */
117 inspect(inspector) {
118 inspector.addAttribute("aws:cdk:cloudformation:type", CfnDNSSEC.CFN_RESOURCE_TYPE_NAME);
119 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
120 }
121 get cfnProperties() {
122 return {
123 hostedZoneId: this.hostedZoneId,
124 };
125 }
126 renderProperties(props) {
127 return cfnDNSSECPropsToCloudFormation(props);
128 }
129}
130exports.CfnDNSSEC = CfnDNSSEC;
131_a = JSII_RTTI_SYMBOL_1;
132CfnDNSSEC[_a] = { fqn: "@aws-cdk/aws-route53.CfnDNSSEC", version: "1.160.0" };
133/**
134 * The CloudFormation resource type name for this resource class.
135 */
136CfnDNSSEC.CFN_RESOURCE_TYPE_NAME = "AWS::Route53::DNSSEC";
137/**
138 * Determine whether the given properties match those of a `CfnHealthCheckProps`
139 *
140 * @param properties - the TypeScript properties of a `CfnHealthCheckProps`
141 *
142 * @returns the result of the validation.
143 */
144function CfnHealthCheckPropsValidator(properties) {
145 if (!cdk.canInspect(properties)) {
146 return cdk.VALIDATION_SUCCESS;
147 }
148 const errors = new cdk.ValidationResults();
149 if (typeof properties !== 'object') {
150 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
151 }
152 errors.collect(cdk.propertyValidator('healthCheckConfig', cdk.requiredValidator)(properties.healthCheckConfig));
153 errors.collect(cdk.propertyValidator('healthCheckConfig', CfnHealthCheck_HealthCheckConfigPropertyValidator)(properties.healthCheckConfig));
154 errors.collect(cdk.propertyValidator('healthCheckTags', cdk.listValidator(CfnHealthCheck_HealthCheckTagPropertyValidator))(properties.healthCheckTags));
155 return errors.wrap('supplied properties not correct for "CfnHealthCheckProps"');
156}
157/**
158 * Renders the AWS CloudFormation properties of an `AWS::Route53::HealthCheck` resource
159 *
160 * @param properties - the TypeScript properties of a `CfnHealthCheckProps`
161 *
162 * @returns the AWS CloudFormation properties of an `AWS::Route53::HealthCheck` resource.
163 */
164// @ts-ignore TS6133
165function cfnHealthCheckPropsToCloudFormation(properties) {
166 if (!cdk.canInspect(properties)) {
167 return properties;
168 }
169 CfnHealthCheckPropsValidator(properties).assertSuccess();
170 return {
171 HealthCheckConfig: cfnHealthCheckHealthCheckConfigPropertyToCloudFormation(properties.healthCheckConfig),
172 HealthCheckTags: cdk.listMapper(cfnHealthCheckHealthCheckTagPropertyToCloudFormation)(properties.healthCheckTags),
173 };
174}
175// @ts-ignore TS6133
176function CfnHealthCheckPropsFromCloudFormation(properties) {
177 properties = properties == null ? {} : properties;
178 if (typeof properties !== 'object') {
179 return new cfn_parse.FromCloudFormationResult(properties);
180 }
181 const ret = new cfn_parse.FromCloudFormationPropertyObject();
182 ret.addPropertyResult('healthCheckConfig', 'HealthCheckConfig', CfnHealthCheckHealthCheckConfigPropertyFromCloudFormation(properties.HealthCheckConfig));
183 ret.addPropertyResult('healthCheckTags', 'HealthCheckTags', properties.HealthCheckTags != null ? cfn_parse.FromCloudFormation.getArray(CfnHealthCheckHealthCheckTagPropertyFromCloudFormation)(properties.HealthCheckTags) : undefined);
184 ret.addUnrecognizedPropertiesAsExtra(properties);
185 return ret;
186}
187/**
188 * A CloudFormation `AWS::Route53::HealthCheck`
189 *
190 * The `AWS::Route53::HealthCheck` resource is a Route 53 resource type that contains settings for a Route 53 health check.
191 *
192 * For information about associating health checks with records, see [HealthCheckId](https://docs.aws.amazon.com/Route53/latest/APIReference/API_ResourceRecordSet.html#Route53-Type-ResourceRecordSet-HealthCheckId) in [ChangeResourceRecordSets](https://docs.aws.amazon.com/Route53/latest/APIReference/API_ChangeResourceRecordSets.html) .
193 *
194 * > You can't create a health check with simple routing.
195 *
196 * *ELB Load Balancers*
197 *
198 * If you're registering EC2 instances with an Elastic Load Balancing (ELB) load balancer, do not create Amazon Route 53 health checks for the EC2 instances. When you register an EC2 instance with a load balancer, you configure settings for an ELB health check, which performs a similar function to a Route 53 health check.
199 *
200 * *Private Hosted Zones*
201 *
202 * You can associate health checks with failover records in a private hosted zone. Note the following:
203 *
204 * - Route 53 health checkers are outside the VPC. To check the health of an endpoint within a VPC by IP address, you must assign a public IP address to the instance in the VPC.
205 * - You can configure a health checker to check the health of an external resource that the instance relies on, such as a database server.
206 * - You can create a CloudWatch metric, associate an alarm with the metric, and then create a health check that is based on the state of the alarm. For example, you might create a CloudWatch metric that checks the status of the Amazon EC2 `StatusCheckFailed` metric, add an alarm to the metric, and then create a health check that is based on the state of the alarm. For information about creating CloudWatch metrics and alarms by using the CloudWatch console, see the [Amazon CloudWatch User Guide](https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/WhatIsCloudWatch.html) .
207 *
208 * @cloudformationResource AWS::Route53::HealthCheck
209 * @stability external
210 *
211 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53-healthcheck.html
212 */
213class CfnHealthCheck extends cdk.CfnResource {
214 /**
215 * Create a new `AWS::Route53::HealthCheck`.
216 *
217 * @param scope - scope in which this resource is defined
218 * @param id - scoped id of the resource
219 * @param props - resource properties
220 */
221 constructor(scope, id, props) {
222 super(scope, id, { type: CfnHealthCheck.CFN_RESOURCE_TYPE_NAME, properties: props });
223 try {
224 jsiiDeprecationWarnings._aws_cdk_aws_route53_CfnHealthCheckProps(props);
225 }
226 catch (error) {
227 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
228 Error.captureStackTrace(error, CfnHealthCheck);
229 }
230 throw error;
231 }
232 cdk.requireProperty(props, 'healthCheckConfig', this);
233 this.attrHealthCheckId = cdk.Token.asString(this.getAtt('HealthCheckId'));
234 this.healthCheckConfig = props.healthCheckConfig;
235 this.healthCheckTags = props.healthCheckTags;
236 }
237 /**
238 * A factory method that creates a new instance of this class from an object
239 * containing the CloudFormation properties of this resource.
240 * Used in the @aws-cdk/cloudformation-include module.
241 *
242 * @internal
243 */
244 static _fromCloudFormation(scope, id, resourceAttributes, options) {
245 resourceAttributes = resourceAttributes || {};
246 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
247 const propsResult = CfnHealthCheckPropsFromCloudFormation(resourceProperties);
248 const ret = new CfnHealthCheck(scope, id, propsResult.value);
249 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
250 ret.addPropertyOverride(propKey, propVal);
251 }
252 options.parser.handleAttributes(ret, resourceAttributes, id);
253 return ret;
254 }
255 /**
256 * Examines the CloudFormation resource and discloses attributes.
257 *
258 * @param inspector - tree inspector to collect and process attributes
259 *
260 */
261 inspect(inspector) {
262 inspector.addAttribute("aws:cdk:cloudformation:type", CfnHealthCheck.CFN_RESOURCE_TYPE_NAME);
263 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
264 }
265 get cfnProperties() {
266 return {
267 healthCheckConfig: this.healthCheckConfig,
268 healthCheckTags: this.healthCheckTags,
269 };
270 }
271 renderProperties(props) {
272 return cfnHealthCheckPropsToCloudFormation(props);
273 }
274}
275exports.CfnHealthCheck = CfnHealthCheck;
276_b = JSII_RTTI_SYMBOL_1;
277CfnHealthCheck[_b] = { fqn: "@aws-cdk/aws-route53.CfnHealthCheck", version: "1.160.0" };
278/**
279 * The CloudFormation resource type name for this resource class.
280 */
281CfnHealthCheck.CFN_RESOURCE_TYPE_NAME = "AWS::Route53::HealthCheck";
282/**
283 * Determine whether the given properties match those of a `AlarmIdentifierProperty`
284 *
285 * @param properties - the TypeScript properties of a `AlarmIdentifierProperty`
286 *
287 * @returns the result of the validation.
288 */
289function CfnHealthCheck_AlarmIdentifierPropertyValidator(properties) {
290 if (!cdk.canInspect(properties)) {
291 return cdk.VALIDATION_SUCCESS;
292 }
293 const errors = new cdk.ValidationResults();
294 if (typeof properties !== 'object') {
295 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
296 }
297 errors.collect(cdk.propertyValidator('name', cdk.requiredValidator)(properties.name));
298 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
299 errors.collect(cdk.propertyValidator('region', cdk.requiredValidator)(properties.region));
300 errors.collect(cdk.propertyValidator('region', cdk.validateString)(properties.region));
301 return errors.wrap('supplied properties not correct for "AlarmIdentifierProperty"');
302}
303/**
304 * Renders the AWS CloudFormation properties of an `AWS::Route53::HealthCheck.AlarmIdentifier` resource
305 *
306 * @param properties - the TypeScript properties of a `AlarmIdentifierProperty`
307 *
308 * @returns the AWS CloudFormation properties of an `AWS::Route53::HealthCheck.AlarmIdentifier` resource.
309 */
310// @ts-ignore TS6133
311function cfnHealthCheckAlarmIdentifierPropertyToCloudFormation(properties) {
312 if (!cdk.canInspect(properties)) {
313 return properties;
314 }
315 CfnHealthCheck_AlarmIdentifierPropertyValidator(properties).assertSuccess();
316 return {
317 Name: cdk.stringToCloudFormation(properties.name),
318 Region: cdk.stringToCloudFormation(properties.region),
319 };
320}
321// @ts-ignore TS6133
322function CfnHealthCheckAlarmIdentifierPropertyFromCloudFormation(properties) {
323 if (cdk.isResolvableObject(properties)) {
324 return new cfn_parse.FromCloudFormationResult(properties);
325 }
326 properties = properties == null ? {} : properties;
327 if (typeof properties !== 'object') {
328 return new cfn_parse.FromCloudFormationResult(properties);
329 }
330 const ret = new cfn_parse.FromCloudFormationPropertyObject();
331 ret.addPropertyResult('name', 'Name', cfn_parse.FromCloudFormation.getString(properties.Name));
332 ret.addPropertyResult('region', 'Region', cfn_parse.FromCloudFormation.getString(properties.Region));
333 ret.addUnrecognizedPropertiesAsExtra(properties);
334 return ret;
335}
336/**
337 * Determine whether the given properties match those of a `HealthCheckConfigProperty`
338 *
339 * @param properties - the TypeScript properties of a `HealthCheckConfigProperty`
340 *
341 * @returns the result of the validation.
342 */
343function CfnHealthCheck_HealthCheckConfigPropertyValidator(properties) {
344 if (!cdk.canInspect(properties)) {
345 return cdk.VALIDATION_SUCCESS;
346 }
347 const errors = new cdk.ValidationResults();
348 if (typeof properties !== 'object') {
349 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
350 }
351 errors.collect(cdk.propertyValidator('alarmIdentifier', CfnHealthCheck_AlarmIdentifierPropertyValidator)(properties.alarmIdentifier));
352 errors.collect(cdk.propertyValidator('childHealthChecks', cdk.listValidator(cdk.validateString))(properties.childHealthChecks));
353 errors.collect(cdk.propertyValidator('enableSni', cdk.validateBoolean)(properties.enableSni));
354 errors.collect(cdk.propertyValidator('failureThreshold', cdk.validateNumber)(properties.failureThreshold));
355 errors.collect(cdk.propertyValidator('fullyQualifiedDomainName', cdk.validateString)(properties.fullyQualifiedDomainName));
356 errors.collect(cdk.propertyValidator('healthThreshold', cdk.validateNumber)(properties.healthThreshold));
357 errors.collect(cdk.propertyValidator('ipAddress', cdk.validateString)(properties.ipAddress));
358 errors.collect(cdk.propertyValidator('insufficientDataHealthStatus', cdk.validateString)(properties.insufficientDataHealthStatus));
359 errors.collect(cdk.propertyValidator('inverted', cdk.validateBoolean)(properties.inverted));
360 errors.collect(cdk.propertyValidator('measureLatency', cdk.validateBoolean)(properties.measureLatency));
361 errors.collect(cdk.propertyValidator('port', cdk.validateNumber)(properties.port));
362 errors.collect(cdk.propertyValidator('regions', cdk.listValidator(cdk.validateString))(properties.regions));
363 errors.collect(cdk.propertyValidator('requestInterval', cdk.validateNumber)(properties.requestInterval));
364 errors.collect(cdk.propertyValidator('resourcePath', cdk.validateString)(properties.resourcePath));
365 errors.collect(cdk.propertyValidator('routingControlArn', cdk.validateString)(properties.routingControlArn));
366 errors.collect(cdk.propertyValidator('searchString', cdk.validateString)(properties.searchString));
367 errors.collect(cdk.propertyValidator('type', cdk.requiredValidator)(properties.type));
368 errors.collect(cdk.propertyValidator('type', cdk.validateString)(properties.type));
369 return errors.wrap('supplied properties not correct for "HealthCheckConfigProperty"');
370}
371/**
372 * Renders the AWS CloudFormation properties of an `AWS::Route53::HealthCheck.HealthCheckConfig` resource
373 *
374 * @param properties - the TypeScript properties of a `HealthCheckConfigProperty`
375 *
376 * @returns the AWS CloudFormation properties of an `AWS::Route53::HealthCheck.HealthCheckConfig` resource.
377 */
378// @ts-ignore TS6133
379function cfnHealthCheckHealthCheckConfigPropertyToCloudFormation(properties) {
380 if (!cdk.canInspect(properties)) {
381 return properties;
382 }
383 CfnHealthCheck_HealthCheckConfigPropertyValidator(properties).assertSuccess();
384 return {
385 AlarmIdentifier: cfnHealthCheckAlarmIdentifierPropertyToCloudFormation(properties.alarmIdentifier),
386 ChildHealthChecks: cdk.listMapper(cdk.stringToCloudFormation)(properties.childHealthChecks),
387 EnableSNI: cdk.booleanToCloudFormation(properties.enableSni),
388 FailureThreshold: cdk.numberToCloudFormation(properties.failureThreshold),
389 FullyQualifiedDomainName: cdk.stringToCloudFormation(properties.fullyQualifiedDomainName),
390 HealthThreshold: cdk.numberToCloudFormation(properties.healthThreshold),
391 IPAddress: cdk.stringToCloudFormation(properties.ipAddress),
392 InsufficientDataHealthStatus: cdk.stringToCloudFormation(properties.insufficientDataHealthStatus),
393 Inverted: cdk.booleanToCloudFormation(properties.inverted),
394 MeasureLatency: cdk.booleanToCloudFormation(properties.measureLatency),
395 Port: cdk.numberToCloudFormation(properties.port),
396 Regions: cdk.listMapper(cdk.stringToCloudFormation)(properties.regions),
397 RequestInterval: cdk.numberToCloudFormation(properties.requestInterval),
398 ResourcePath: cdk.stringToCloudFormation(properties.resourcePath),
399 RoutingControlArn: cdk.stringToCloudFormation(properties.routingControlArn),
400 SearchString: cdk.stringToCloudFormation(properties.searchString),
401 Type: cdk.stringToCloudFormation(properties.type),
402 };
403}
404// @ts-ignore TS6133
405function CfnHealthCheckHealthCheckConfigPropertyFromCloudFormation(properties) {
406 if (cdk.isResolvableObject(properties)) {
407 return new cfn_parse.FromCloudFormationResult(properties);
408 }
409 properties = properties == null ? {} : properties;
410 if (typeof properties !== 'object') {
411 return new cfn_parse.FromCloudFormationResult(properties);
412 }
413 const ret = new cfn_parse.FromCloudFormationPropertyObject();
414 ret.addPropertyResult('alarmIdentifier', 'AlarmIdentifier', properties.AlarmIdentifier != null ? CfnHealthCheckAlarmIdentifierPropertyFromCloudFormation(properties.AlarmIdentifier) : undefined);
415 ret.addPropertyResult('childHealthChecks', 'ChildHealthChecks', properties.ChildHealthChecks != null ? cfn_parse.FromCloudFormation.getStringArray(properties.ChildHealthChecks) : undefined);
416 ret.addPropertyResult('enableSni', 'EnableSNI', properties.EnableSNI != null ? cfn_parse.FromCloudFormation.getBoolean(properties.EnableSNI) : undefined);
417 ret.addPropertyResult('failureThreshold', 'FailureThreshold', properties.FailureThreshold != null ? cfn_parse.FromCloudFormation.getNumber(properties.FailureThreshold) : undefined);
418 ret.addPropertyResult('fullyQualifiedDomainName', 'FullyQualifiedDomainName', properties.FullyQualifiedDomainName != null ? cfn_parse.FromCloudFormation.getString(properties.FullyQualifiedDomainName) : undefined);
419 ret.addPropertyResult('healthThreshold', 'HealthThreshold', properties.HealthThreshold != null ? cfn_parse.FromCloudFormation.getNumber(properties.HealthThreshold) : undefined);
420 ret.addPropertyResult('ipAddress', 'IPAddress', properties.IPAddress != null ? cfn_parse.FromCloudFormation.getString(properties.IPAddress) : undefined);
421 ret.addPropertyResult('insufficientDataHealthStatus', 'InsufficientDataHealthStatus', properties.InsufficientDataHealthStatus != null ? cfn_parse.FromCloudFormation.getString(properties.InsufficientDataHealthStatus) : undefined);
422 ret.addPropertyResult('inverted', 'Inverted', properties.Inverted != null ? cfn_parse.FromCloudFormation.getBoolean(properties.Inverted) : undefined);
423 ret.addPropertyResult('measureLatency', 'MeasureLatency', properties.MeasureLatency != null ? cfn_parse.FromCloudFormation.getBoolean(properties.MeasureLatency) : undefined);
424 ret.addPropertyResult('port', 'Port', properties.Port != null ? cfn_parse.FromCloudFormation.getNumber(properties.Port) : undefined);
425 ret.addPropertyResult('regions', 'Regions', properties.Regions != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Regions) : undefined);
426 ret.addPropertyResult('requestInterval', 'RequestInterval', properties.RequestInterval != null ? cfn_parse.FromCloudFormation.getNumber(properties.RequestInterval) : undefined);
427 ret.addPropertyResult('resourcePath', 'ResourcePath', properties.ResourcePath != null ? cfn_parse.FromCloudFormation.getString(properties.ResourcePath) : undefined);
428 ret.addPropertyResult('routingControlArn', 'RoutingControlArn', properties.RoutingControlArn != null ? cfn_parse.FromCloudFormation.getString(properties.RoutingControlArn) : undefined);
429 ret.addPropertyResult('searchString', 'SearchString', properties.SearchString != null ? cfn_parse.FromCloudFormation.getString(properties.SearchString) : undefined);
430 ret.addPropertyResult('type', 'Type', cfn_parse.FromCloudFormation.getString(properties.Type));
431 ret.addUnrecognizedPropertiesAsExtra(properties);
432 return ret;
433}
434/**
435 * Determine whether the given properties match those of a `HealthCheckTagProperty`
436 *
437 * @param properties - the TypeScript properties of a `HealthCheckTagProperty`
438 *
439 * @returns the result of the validation.
440 */
441function CfnHealthCheck_HealthCheckTagPropertyValidator(properties) {
442 if (!cdk.canInspect(properties)) {
443 return cdk.VALIDATION_SUCCESS;
444 }
445 const errors = new cdk.ValidationResults();
446 if (typeof properties !== 'object') {
447 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
448 }
449 errors.collect(cdk.propertyValidator('key', cdk.requiredValidator)(properties.key));
450 errors.collect(cdk.propertyValidator('key', cdk.validateString)(properties.key));
451 errors.collect(cdk.propertyValidator('value', cdk.requiredValidator)(properties.value));
452 errors.collect(cdk.propertyValidator('value', cdk.validateString)(properties.value));
453 return errors.wrap('supplied properties not correct for "HealthCheckTagProperty"');
454}
455/**
456 * Renders the AWS CloudFormation properties of an `AWS::Route53::HealthCheck.HealthCheckTag` resource
457 *
458 * @param properties - the TypeScript properties of a `HealthCheckTagProperty`
459 *
460 * @returns the AWS CloudFormation properties of an `AWS::Route53::HealthCheck.HealthCheckTag` resource.
461 */
462// @ts-ignore TS6133
463function cfnHealthCheckHealthCheckTagPropertyToCloudFormation(properties) {
464 if (!cdk.canInspect(properties)) {
465 return properties;
466 }
467 CfnHealthCheck_HealthCheckTagPropertyValidator(properties).assertSuccess();
468 return {
469 Key: cdk.stringToCloudFormation(properties.key),
470 Value: cdk.stringToCloudFormation(properties.value),
471 };
472}
473// @ts-ignore TS6133
474function CfnHealthCheckHealthCheckTagPropertyFromCloudFormation(properties) {
475 if (cdk.isResolvableObject(properties)) {
476 return new cfn_parse.FromCloudFormationResult(properties);
477 }
478 properties = properties == null ? {} : properties;
479 if (typeof properties !== 'object') {
480 return new cfn_parse.FromCloudFormationResult(properties);
481 }
482 const ret = new cfn_parse.FromCloudFormationPropertyObject();
483 ret.addPropertyResult('key', 'Key', cfn_parse.FromCloudFormation.getString(properties.Key));
484 ret.addPropertyResult('value', 'Value', cfn_parse.FromCloudFormation.getString(properties.Value));
485 ret.addUnrecognizedPropertiesAsExtra(properties);
486 return ret;
487}
488/**
489 * Determine whether the given properties match those of a `CfnHostedZoneProps`
490 *
491 * @param properties - the TypeScript properties of a `CfnHostedZoneProps`
492 *
493 * @returns the result of the validation.
494 */
495function CfnHostedZonePropsValidator(properties) {
496 if (!cdk.canInspect(properties)) {
497 return cdk.VALIDATION_SUCCESS;
498 }
499 const errors = new cdk.ValidationResults();
500 if (typeof properties !== 'object') {
501 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
502 }
503 errors.collect(cdk.propertyValidator('hostedZoneConfig', CfnHostedZone_HostedZoneConfigPropertyValidator)(properties.hostedZoneConfig));
504 errors.collect(cdk.propertyValidator('hostedZoneTags', cdk.listValidator(CfnHostedZone_HostedZoneTagPropertyValidator))(properties.hostedZoneTags));
505 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
506 errors.collect(cdk.propertyValidator('queryLoggingConfig', CfnHostedZone_QueryLoggingConfigPropertyValidator)(properties.queryLoggingConfig));
507 errors.collect(cdk.propertyValidator('vpcs', cdk.listValidator(CfnHostedZone_VPCPropertyValidator))(properties.vpcs));
508 return errors.wrap('supplied properties not correct for "CfnHostedZoneProps"');
509}
510/**
511 * Renders the AWS CloudFormation properties of an `AWS::Route53::HostedZone` resource
512 *
513 * @param properties - the TypeScript properties of a `CfnHostedZoneProps`
514 *
515 * @returns the AWS CloudFormation properties of an `AWS::Route53::HostedZone` resource.
516 */
517// @ts-ignore TS6133
518function cfnHostedZonePropsToCloudFormation(properties) {
519 if (!cdk.canInspect(properties)) {
520 return properties;
521 }
522 CfnHostedZonePropsValidator(properties).assertSuccess();
523 return {
524 HostedZoneConfig: cfnHostedZoneHostedZoneConfigPropertyToCloudFormation(properties.hostedZoneConfig),
525 HostedZoneTags: cdk.listMapper(cfnHostedZoneHostedZoneTagPropertyToCloudFormation)(properties.hostedZoneTags),
526 Name: cdk.stringToCloudFormation(properties.name),
527 QueryLoggingConfig: cfnHostedZoneQueryLoggingConfigPropertyToCloudFormation(properties.queryLoggingConfig),
528 VPCs: cdk.listMapper(cfnHostedZoneVPCPropertyToCloudFormation)(properties.vpcs),
529 };
530}
531// @ts-ignore TS6133
532function CfnHostedZonePropsFromCloudFormation(properties) {
533 properties = properties == null ? {} : properties;
534 if (typeof properties !== 'object') {
535 return new cfn_parse.FromCloudFormationResult(properties);
536 }
537 const ret = new cfn_parse.FromCloudFormationPropertyObject();
538 ret.addPropertyResult('hostedZoneConfig', 'HostedZoneConfig', properties.HostedZoneConfig != null ? CfnHostedZoneHostedZoneConfigPropertyFromCloudFormation(properties.HostedZoneConfig) : undefined);
539 ret.addPropertyResult('hostedZoneTags', 'HostedZoneTags', properties.HostedZoneTags != null ? cfn_parse.FromCloudFormation.getArray(CfnHostedZoneHostedZoneTagPropertyFromCloudFormation)(properties.HostedZoneTags) : undefined);
540 ret.addPropertyResult('name', 'Name', properties.Name != null ? cfn_parse.FromCloudFormation.getString(properties.Name) : undefined);
541 ret.addPropertyResult('queryLoggingConfig', 'QueryLoggingConfig', properties.QueryLoggingConfig != null ? CfnHostedZoneQueryLoggingConfigPropertyFromCloudFormation(properties.QueryLoggingConfig) : undefined);
542 ret.addPropertyResult('vpcs', 'VPCs', properties.VPCs != null ? cfn_parse.FromCloudFormation.getArray(CfnHostedZoneVPCPropertyFromCloudFormation)(properties.VPCs) : undefined);
543 ret.addUnrecognizedPropertiesAsExtra(properties);
544 return ret;
545}
546/**
547 * A CloudFormation `AWS::Route53::HostedZone`
548 *
549 * Creates a new public or private hosted zone. You create records in a public hosted zone to define how you want to route traffic on the internet for a domain, such as example.com, and its subdomains (apex.example.com, acme.example.com). You create records in a private hosted zone to define how you want to route traffic for a domain and its subdomains within one or more Amazon Virtual Private Clouds (Amazon VPCs).
550 *
551 * > You can't convert a public hosted zone to a private hosted zone or vice versa. Instead, you must create a new hosted zone with the same name and create new resource record sets.
552 *
553 * For more information about charges for hosted zones, see [Amazon Route 53 Pricing](https://docs.aws.amazon.com/route53/pricing/) .
554 *
555 * Note the following:
556 *
557 * - You can't create a hosted zone for a top-level domain (TLD) such as .com.
558 * - For public hosted zones, Route 53 automatically creates a default SOA record and four NS records for the zone. For more information about SOA and NS records, see [NS and SOA Records that Route 53 Creates for a Hosted Zone](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/SOA-NSrecords.html) in the *Amazon Route 53 Developer Guide* .
559 *
560 * If you want to use the same name servers for multiple public hosted zones, you can optionally associate a reusable delegation set with the hosted zone. See the `DelegationSetId` element.
561 * - If your domain is registered with a registrar other than Route 53, you must update the name servers with your registrar to make Route 53 the DNS service for the domain. For more information, see [Migrating DNS Service for an Existing Domain to Amazon Route 53](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/MigratingDNS.html) in the *Amazon Route 53 Developer Guide* .
562 *
563 * When you submit a `CreateHostedZone` request, the initial status of the hosted zone is `PENDING` . For public hosted zones, this means that the NS and SOA records are not yet available on all Route 53 DNS servers. When the NS and SOA records are available, the status of the zone changes to `INSYNC` .
564 *
565 * The `CreateHostedZone` request requires the caller to have an `ec2:DescribeVpcs` permission.
566 *
567 * > When creating private hosted zones, the Amazon VPC must belong to the same partition where the hosted zone is created. A partition is a group of AWS Regions . Each AWS account is scoped to one partition.
568 * >
569 * > The following are the supported partitions:
570 * >
571 * > - `aws` - AWS Regions
572 * > - `aws-cn` - China Regions
573 * > - `aws-us-gov` - AWS GovCloud (US) Region
574 * >
575 * > For more information, see [Access Management](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) in the *AWS General Reference* .
576 *
577 * @cloudformationResource AWS::Route53::HostedZone
578 * @stability external
579 *
580 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53-hostedzone.html
581 */
582class CfnHostedZone extends cdk.CfnResource {
583 /**
584 * Create a new `AWS::Route53::HostedZone`.
585 *
586 * @param scope - scope in which this resource is defined
587 * @param id - scoped id of the resource
588 * @param props - resource properties
589 */
590 constructor(scope, id, props = {}) {
591 super(scope, id, { type: CfnHostedZone.CFN_RESOURCE_TYPE_NAME, properties: props });
592 try {
593 jsiiDeprecationWarnings._aws_cdk_aws_route53_CfnHostedZoneProps(props);
594 }
595 catch (error) {
596 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
597 Error.captureStackTrace(error, CfnHostedZone);
598 }
599 throw error;
600 }
601 this.attrId = cdk.Token.asString(this.getAtt('Id'));
602 this.attrNameServers = cdk.Token.asList(this.getAtt('NameServers'));
603 this.hostedZoneConfig = props.hostedZoneConfig;
604 this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::Route53::HostedZone", props.hostedZoneTags, { tagPropertyName: 'hostedZoneTags' });
605 this.name = props.name;
606 this.queryLoggingConfig = props.queryLoggingConfig;
607 this.vpcs = props.vpcs;
608 }
609 /**
610 * A factory method that creates a new instance of this class from an object
611 * containing the CloudFormation properties of this resource.
612 * Used in the @aws-cdk/cloudformation-include module.
613 *
614 * @internal
615 */
616 static _fromCloudFormation(scope, id, resourceAttributes, options) {
617 resourceAttributes = resourceAttributes || {};
618 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
619 const propsResult = CfnHostedZonePropsFromCloudFormation(resourceProperties);
620 const ret = new CfnHostedZone(scope, id, propsResult.value);
621 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
622 ret.addPropertyOverride(propKey, propVal);
623 }
624 options.parser.handleAttributes(ret, resourceAttributes, id);
625 return ret;
626 }
627 /**
628 * Examines the CloudFormation resource and discloses attributes.
629 *
630 * @param inspector - tree inspector to collect and process attributes
631 *
632 */
633 inspect(inspector) {
634 inspector.addAttribute("aws:cdk:cloudformation:type", CfnHostedZone.CFN_RESOURCE_TYPE_NAME);
635 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
636 }
637 get cfnProperties() {
638 return {
639 hostedZoneConfig: this.hostedZoneConfig,
640 hostedZoneTags: this.tags.renderTags(),
641 name: this.name,
642 queryLoggingConfig: this.queryLoggingConfig,
643 vpcs: this.vpcs,
644 };
645 }
646 renderProperties(props) {
647 return cfnHostedZonePropsToCloudFormation(props);
648 }
649}
650exports.CfnHostedZone = CfnHostedZone;
651_c = JSII_RTTI_SYMBOL_1;
652CfnHostedZone[_c] = { fqn: "@aws-cdk/aws-route53.CfnHostedZone", version: "1.160.0" };
653/**
654 * The CloudFormation resource type name for this resource class.
655 */
656CfnHostedZone.CFN_RESOURCE_TYPE_NAME = "AWS::Route53::HostedZone";
657/**
658 * Determine whether the given properties match those of a `HostedZoneConfigProperty`
659 *
660 * @param properties - the TypeScript properties of a `HostedZoneConfigProperty`
661 *
662 * @returns the result of the validation.
663 */
664function CfnHostedZone_HostedZoneConfigPropertyValidator(properties) {
665 if (!cdk.canInspect(properties)) {
666 return cdk.VALIDATION_SUCCESS;
667 }
668 const errors = new cdk.ValidationResults();
669 if (typeof properties !== 'object') {
670 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
671 }
672 errors.collect(cdk.propertyValidator('comment', cdk.validateString)(properties.comment));
673 return errors.wrap('supplied properties not correct for "HostedZoneConfigProperty"');
674}
675/**
676 * Renders the AWS CloudFormation properties of an `AWS::Route53::HostedZone.HostedZoneConfig` resource
677 *
678 * @param properties - the TypeScript properties of a `HostedZoneConfigProperty`
679 *
680 * @returns the AWS CloudFormation properties of an `AWS::Route53::HostedZone.HostedZoneConfig` resource.
681 */
682// @ts-ignore TS6133
683function cfnHostedZoneHostedZoneConfigPropertyToCloudFormation(properties) {
684 if (!cdk.canInspect(properties)) {
685 return properties;
686 }
687 CfnHostedZone_HostedZoneConfigPropertyValidator(properties).assertSuccess();
688 return {
689 Comment: cdk.stringToCloudFormation(properties.comment),
690 };
691}
692// @ts-ignore TS6133
693function CfnHostedZoneHostedZoneConfigPropertyFromCloudFormation(properties) {
694 if (cdk.isResolvableObject(properties)) {
695 return new cfn_parse.FromCloudFormationResult(properties);
696 }
697 properties = properties == null ? {} : properties;
698 if (typeof properties !== 'object') {
699 return new cfn_parse.FromCloudFormationResult(properties);
700 }
701 const ret = new cfn_parse.FromCloudFormationPropertyObject();
702 ret.addPropertyResult('comment', 'Comment', properties.Comment != null ? cfn_parse.FromCloudFormation.getString(properties.Comment) : undefined);
703 ret.addUnrecognizedPropertiesAsExtra(properties);
704 return ret;
705}
706/**
707 * Determine whether the given properties match those of a `HostedZoneTagProperty`
708 *
709 * @param properties - the TypeScript properties of a `HostedZoneTagProperty`
710 *
711 * @returns the result of the validation.
712 */
713function CfnHostedZone_HostedZoneTagPropertyValidator(properties) {
714 if (!cdk.canInspect(properties)) {
715 return cdk.VALIDATION_SUCCESS;
716 }
717 const errors = new cdk.ValidationResults();
718 if (typeof properties !== 'object') {
719 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
720 }
721 errors.collect(cdk.propertyValidator('key', cdk.requiredValidator)(properties.key));
722 errors.collect(cdk.propertyValidator('key', cdk.validateString)(properties.key));
723 errors.collect(cdk.propertyValidator('value', cdk.requiredValidator)(properties.value));
724 errors.collect(cdk.propertyValidator('value', cdk.validateString)(properties.value));
725 return errors.wrap('supplied properties not correct for "HostedZoneTagProperty"');
726}
727/**
728 * Renders the AWS CloudFormation properties of an `AWS::Route53::HostedZone.HostedZoneTag` resource
729 *
730 * @param properties - the TypeScript properties of a `HostedZoneTagProperty`
731 *
732 * @returns the AWS CloudFormation properties of an `AWS::Route53::HostedZone.HostedZoneTag` resource.
733 */
734// @ts-ignore TS6133
735function cfnHostedZoneHostedZoneTagPropertyToCloudFormation(properties) {
736 if (!cdk.canInspect(properties)) {
737 return properties;
738 }
739 CfnHostedZone_HostedZoneTagPropertyValidator(properties).assertSuccess();
740 return {
741 Key: cdk.stringToCloudFormation(properties.key),
742 Value: cdk.stringToCloudFormation(properties.value),
743 };
744}
745// @ts-ignore TS6133
746function CfnHostedZoneHostedZoneTagPropertyFromCloudFormation(properties) {
747 if (cdk.isResolvableObject(properties)) {
748 return new cfn_parse.FromCloudFormationResult(properties);
749 }
750 properties = properties == null ? {} : properties;
751 if (typeof properties !== 'object') {
752 return new cfn_parse.FromCloudFormationResult(properties);
753 }
754 const ret = new cfn_parse.FromCloudFormationPropertyObject();
755 ret.addPropertyResult('key', 'Key', cfn_parse.FromCloudFormation.getString(properties.Key));
756 ret.addPropertyResult('value', 'Value', cfn_parse.FromCloudFormation.getString(properties.Value));
757 ret.addUnrecognizedPropertiesAsExtra(properties);
758 return ret;
759}
760/**
761 * Determine whether the given properties match those of a `QueryLoggingConfigProperty`
762 *
763 * @param properties - the TypeScript properties of a `QueryLoggingConfigProperty`
764 *
765 * @returns the result of the validation.
766 */
767function CfnHostedZone_QueryLoggingConfigPropertyValidator(properties) {
768 if (!cdk.canInspect(properties)) {
769 return cdk.VALIDATION_SUCCESS;
770 }
771 const errors = new cdk.ValidationResults();
772 if (typeof properties !== 'object') {
773 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
774 }
775 errors.collect(cdk.propertyValidator('cloudWatchLogsLogGroupArn', cdk.requiredValidator)(properties.cloudWatchLogsLogGroupArn));
776 errors.collect(cdk.propertyValidator('cloudWatchLogsLogGroupArn', cdk.validateString)(properties.cloudWatchLogsLogGroupArn));
777 return errors.wrap('supplied properties not correct for "QueryLoggingConfigProperty"');
778}
779/**
780 * Renders the AWS CloudFormation properties of an `AWS::Route53::HostedZone.QueryLoggingConfig` resource
781 *
782 * @param properties - the TypeScript properties of a `QueryLoggingConfigProperty`
783 *
784 * @returns the AWS CloudFormation properties of an `AWS::Route53::HostedZone.QueryLoggingConfig` resource.
785 */
786// @ts-ignore TS6133
787function cfnHostedZoneQueryLoggingConfigPropertyToCloudFormation(properties) {
788 if (!cdk.canInspect(properties)) {
789 return properties;
790 }
791 CfnHostedZone_QueryLoggingConfigPropertyValidator(properties).assertSuccess();
792 return {
793 CloudWatchLogsLogGroupArn: cdk.stringToCloudFormation(properties.cloudWatchLogsLogGroupArn),
794 };
795}
796// @ts-ignore TS6133
797function CfnHostedZoneQueryLoggingConfigPropertyFromCloudFormation(properties) {
798 if (cdk.isResolvableObject(properties)) {
799 return new cfn_parse.FromCloudFormationResult(properties);
800 }
801 properties = properties == null ? {} : properties;
802 if (typeof properties !== 'object') {
803 return new cfn_parse.FromCloudFormationResult(properties);
804 }
805 const ret = new cfn_parse.FromCloudFormationPropertyObject();
806 ret.addPropertyResult('cloudWatchLogsLogGroupArn', 'CloudWatchLogsLogGroupArn', cfn_parse.FromCloudFormation.getString(properties.CloudWatchLogsLogGroupArn));
807 ret.addUnrecognizedPropertiesAsExtra(properties);
808 return ret;
809}
810/**
811 * Determine whether the given properties match those of a `VPCProperty`
812 *
813 * @param properties - the TypeScript properties of a `VPCProperty`
814 *
815 * @returns the result of the validation.
816 */
817function CfnHostedZone_VPCPropertyValidator(properties) {
818 if (!cdk.canInspect(properties)) {
819 return cdk.VALIDATION_SUCCESS;
820 }
821 const errors = new cdk.ValidationResults();
822 if (typeof properties !== 'object') {
823 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
824 }
825 errors.collect(cdk.propertyValidator('vpcId', cdk.requiredValidator)(properties.vpcId));
826 errors.collect(cdk.propertyValidator('vpcId', cdk.validateString)(properties.vpcId));
827 errors.collect(cdk.propertyValidator('vpcRegion', cdk.requiredValidator)(properties.vpcRegion));
828 errors.collect(cdk.propertyValidator('vpcRegion', cdk.validateString)(properties.vpcRegion));
829 return errors.wrap('supplied properties not correct for "VPCProperty"');
830}
831/**
832 * Renders the AWS CloudFormation properties of an `AWS::Route53::HostedZone.VPC` resource
833 *
834 * @param properties - the TypeScript properties of a `VPCProperty`
835 *
836 * @returns the AWS CloudFormation properties of an `AWS::Route53::HostedZone.VPC` resource.
837 */
838// @ts-ignore TS6133
839function cfnHostedZoneVPCPropertyToCloudFormation(properties) {
840 if (!cdk.canInspect(properties)) {
841 return properties;
842 }
843 CfnHostedZone_VPCPropertyValidator(properties).assertSuccess();
844 return {
845 VPCId: cdk.stringToCloudFormation(properties.vpcId),
846 VPCRegion: cdk.stringToCloudFormation(properties.vpcRegion),
847 };
848}
849// @ts-ignore TS6133
850function CfnHostedZoneVPCPropertyFromCloudFormation(properties) {
851 if (cdk.isResolvableObject(properties)) {
852 return new cfn_parse.FromCloudFormationResult(properties);
853 }
854 properties = properties == null ? {} : properties;
855 if (typeof properties !== 'object') {
856 return new cfn_parse.FromCloudFormationResult(properties);
857 }
858 const ret = new cfn_parse.FromCloudFormationPropertyObject();
859 ret.addPropertyResult('vpcId', 'VPCId', cfn_parse.FromCloudFormation.getString(properties.VPCId));
860 ret.addPropertyResult('vpcRegion', 'VPCRegion', cfn_parse.FromCloudFormation.getString(properties.VPCRegion));
861 ret.addUnrecognizedPropertiesAsExtra(properties);
862 return ret;
863}
864/**
865 * Determine whether the given properties match those of a `CfnKeySigningKeyProps`
866 *
867 * @param properties - the TypeScript properties of a `CfnKeySigningKeyProps`
868 *
869 * @returns the result of the validation.
870 */
871function CfnKeySigningKeyPropsValidator(properties) {
872 if (!cdk.canInspect(properties)) {
873 return cdk.VALIDATION_SUCCESS;
874 }
875 const errors = new cdk.ValidationResults();
876 if (typeof properties !== 'object') {
877 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
878 }
879 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.requiredValidator)(properties.hostedZoneId));
880 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.validateString)(properties.hostedZoneId));
881 errors.collect(cdk.propertyValidator('keyManagementServiceArn', cdk.requiredValidator)(properties.keyManagementServiceArn));
882 errors.collect(cdk.propertyValidator('keyManagementServiceArn', cdk.validateString)(properties.keyManagementServiceArn));
883 errors.collect(cdk.propertyValidator('name', cdk.requiredValidator)(properties.name));
884 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
885 errors.collect(cdk.propertyValidator('status', cdk.requiredValidator)(properties.status));
886 errors.collect(cdk.propertyValidator('status', cdk.validateString)(properties.status));
887 return errors.wrap('supplied properties not correct for "CfnKeySigningKeyProps"');
888}
889/**
890 * Renders the AWS CloudFormation properties of an `AWS::Route53::KeySigningKey` resource
891 *
892 * @param properties - the TypeScript properties of a `CfnKeySigningKeyProps`
893 *
894 * @returns the AWS CloudFormation properties of an `AWS::Route53::KeySigningKey` resource.
895 */
896// @ts-ignore TS6133
897function cfnKeySigningKeyPropsToCloudFormation(properties) {
898 if (!cdk.canInspect(properties)) {
899 return properties;
900 }
901 CfnKeySigningKeyPropsValidator(properties).assertSuccess();
902 return {
903 HostedZoneId: cdk.stringToCloudFormation(properties.hostedZoneId),
904 KeyManagementServiceArn: cdk.stringToCloudFormation(properties.keyManagementServiceArn),
905 Name: cdk.stringToCloudFormation(properties.name),
906 Status: cdk.stringToCloudFormation(properties.status),
907 };
908}
909// @ts-ignore TS6133
910function CfnKeySigningKeyPropsFromCloudFormation(properties) {
911 properties = properties == null ? {} : properties;
912 if (typeof properties !== 'object') {
913 return new cfn_parse.FromCloudFormationResult(properties);
914 }
915 const ret = new cfn_parse.FromCloudFormationPropertyObject();
916 ret.addPropertyResult('hostedZoneId', 'HostedZoneId', cfn_parse.FromCloudFormation.getString(properties.HostedZoneId));
917 ret.addPropertyResult('keyManagementServiceArn', 'KeyManagementServiceArn', cfn_parse.FromCloudFormation.getString(properties.KeyManagementServiceArn));
918 ret.addPropertyResult('name', 'Name', cfn_parse.FromCloudFormation.getString(properties.Name));
919 ret.addPropertyResult('status', 'Status', cfn_parse.FromCloudFormation.getString(properties.Status));
920 ret.addUnrecognizedPropertiesAsExtra(properties);
921 return ret;
922}
923/**
924 * A CloudFormation `AWS::Route53::KeySigningKey`
925 *
926 * The `AWS::Route53::KeySigningKey` resource creates a new key-signing key (KSK) in a hosted zone. The hosted zone ID is passed as a parameter in the KSK properties. You can specify the properties of this KSK using the `Name` , `Status` , and `KeyManagementServiceArn` properties of the resource.
927 *
928 * @cloudformationResource AWS::Route53::KeySigningKey
929 * @stability external
930 *
931 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53-keysigningkey.html
932 */
933class CfnKeySigningKey extends cdk.CfnResource {
934 /**
935 * Create a new `AWS::Route53::KeySigningKey`.
936 *
937 * @param scope - scope in which this resource is defined
938 * @param id - scoped id of the resource
939 * @param props - resource properties
940 */
941 constructor(scope, id, props) {
942 super(scope, id, { type: CfnKeySigningKey.CFN_RESOURCE_TYPE_NAME, properties: props });
943 try {
944 jsiiDeprecationWarnings._aws_cdk_aws_route53_CfnKeySigningKeyProps(props);
945 }
946 catch (error) {
947 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
948 Error.captureStackTrace(error, CfnKeySigningKey);
949 }
950 throw error;
951 }
952 cdk.requireProperty(props, 'hostedZoneId', this);
953 cdk.requireProperty(props, 'keyManagementServiceArn', this);
954 cdk.requireProperty(props, 'name', this);
955 cdk.requireProperty(props, 'status', this);
956 this.hostedZoneId = props.hostedZoneId;
957 this.keyManagementServiceArn = props.keyManagementServiceArn;
958 this.name = props.name;
959 this.status = props.status;
960 }
961 /**
962 * A factory method that creates a new instance of this class from an object
963 * containing the CloudFormation properties of this resource.
964 * Used in the @aws-cdk/cloudformation-include module.
965 *
966 * @internal
967 */
968 static _fromCloudFormation(scope, id, resourceAttributes, options) {
969 resourceAttributes = resourceAttributes || {};
970 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
971 const propsResult = CfnKeySigningKeyPropsFromCloudFormation(resourceProperties);
972 const ret = new CfnKeySigningKey(scope, id, propsResult.value);
973 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
974 ret.addPropertyOverride(propKey, propVal);
975 }
976 options.parser.handleAttributes(ret, resourceAttributes, id);
977 return ret;
978 }
979 /**
980 * Examines the CloudFormation resource and discloses attributes.
981 *
982 * @param inspector - tree inspector to collect and process attributes
983 *
984 */
985 inspect(inspector) {
986 inspector.addAttribute("aws:cdk:cloudformation:type", CfnKeySigningKey.CFN_RESOURCE_TYPE_NAME);
987 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
988 }
989 get cfnProperties() {
990 return {
991 hostedZoneId: this.hostedZoneId,
992 keyManagementServiceArn: this.keyManagementServiceArn,
993 name: this.name,
994 status: this.status,
995 };
996 }
997 renderProperties(props) {
998 return cfnKeySigningKeyPropsToCloudFormation(props);
999 }
1000}
1001exports.CfnKeySigningKey = CfnKeySigningKey;
1002_d = JSII_RTTI_SYMBOL_1;
1003CfnKeySigningKey[_d] = { fqn: "@aws-cdk/aws-route53.CfnKeySigningKey", version: "1.160.0" };
1004/**
1005 * The CloudFormation resource type name for this resource class.
1006 */
1007CfnKeySigningKey.CFN_RESOURCE_TYPE_NAME = "AWS::Route53::KeySigningKey";
1008/**
1009 * Determine whether the given properties match those of a `CfnRecordSetProps`
1010 *
1011 * @param properties - the TypeScript properties of a `CfnRecordSetProps`
1012 *
1013 * @returns the result of the validation.
1014 */
1015function CfnRecordSetPropsValidator(properties) {
1016 if (!cdk.canInspect(properties)) {
1017 return cdk.VALIDATION_SUCCESS;
1018 }
1019 const errors = new cdk.ValidationResults();
1020 if (typeof properties !== 'object') {
1021 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1022 }
1023 errors.collect(cdk.propertyValidator('aliasTarget', CfnRecordSet_AliasTargetPropertyValidator)(properties.aliasTarget));
1024 errors.collect(cdk.propertyValidator('comment', cdk.validateString)(properties.comment));
1025 errors.collect(cdk.propertyValidator('failover', cdk.validateString)(properties.failover));
1026 errors.collect(cdk.propertyValidator('geoLocation', CfnRecordSet_GeoLocationPropertyValidator)(properties.geoLocation));
1027 errors.collect(cdk.propertyValidator('healthCheckId', cdk.validateString)(properties.healthCheckId));
1028 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.validateString)(properties.hostedZoneId));
1029 errors.collect(cdk.propertyValidator('hostedZoneName', cdk.validateString)(properties.hostedZoneName));
1030 errors.collect(cdk.propertyValidator('multiValueAnswer', cdk.validateBoolean)(properties.multiValueAnswer));
1031 errors.collect(cdk.propertyValidator('name', cdk.requiredValidator)(properties.name));
1032 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
1033 errors.collect(cdk.propertyValidator('region', cdk.validateString)(properties.region));
1034 errors.collect(cdk.propertyValidator('resourceRecords', cdk.listValidator(cdk.validateString))(properties.resourceRecords));
1035 errors.collect(cdk.propertyValidator('setIdentifier', cdk.validateString)(properties.setIdentifier));
1036 errors.collect(cdk.propertyValidator('ttl', cdk.validateString)(properties.ttl));
1037 errors.collect(cdk.propertyValidator('type', cdk.requiredValidator)(properties.type));
1038 errors.collect(cdk.propertyValidator('type', cdk.validateString)(properties.type));
1039 errors.collect(cdk.propertyValidator('weight', cdk.validateNumber)(properties.weight));
1040 return errors.wrap('supplied properties not correct for "CfnRecordSetProps"');
1041}
1042/**
1043 * Renders the AWS CloudFormation properties of an `AWS::Route53::RecordSet` resource
1044 *
1045 * @param properties - the TypeScript properties of a `CfnRecordSetProps`
1046 *
1047 * @returns the AWS CloudFormation properties of an `AWS::Route53::RecordSet` resource.
1048 */
1049// @ts-ignore TS6133
1050function cfnRecordSetPropsToCloudFormation(properties) {
1051 if (!cdk.canInspect(properties)) {
1052 return properties;
1053 }
1054 CfnRecordSetPropsValidator(properties).assertSuccess();
1055 return {
1056 Name: cdk.stringToCloudFormation(properties.name),
1057 Type: cdk.stringToCloudFormation(properties.type),
1058 AliasTarget: cfnRecordSetAliasTargetPropertyToCloudFormation(properties.aliasTarget),
1059 Comment: cdk.stringToCloudFormation(properties.comment),
1060 Failover: cdk.stringToCloudFormation(properties.failover),
1061 GeoLocation: cfnRecordSetGeoLocationPropertyToCloudFormation(properties.geoLocation),
1062 HealthCheckId: cdk.stringToCloudFormation(properties.healthCheckId),
1063 HostedZoneId: cdk.stringToCloudFormation(properties.hostedZoneId),
1064 HostedZoneName: cdk.stringToCloudFormation(properties.hostedZoneName),
1065 MultiValueAnswer: cdk.booleanToCloudFormation(properties.multiValueAnswer),
1066 Region: cdk.stringToCloudFormation(properties.region),
1067 ResourceRecords: cdk.listMapper(cdk.stringToCloudFormation)(properties.resourceRecords),
1068 SetIdentifier: cdk.stringToCloudFormation(properties.setIdentifier),
1069 TTL: cdk.stringToCloudFormation(properties.ttl),
1070 Weight: cdk.numberToCloudFormation(properties.weight),
1071 };
1072}
1073// @ts-ignore TS6133
1074function CfnRecordSetPropsFromCloudFormation(properties) {
1075 properties = properties == null ? {} : properties;
1076 if (typeof properties !== 'object') {
1077 return new cfn_parse.FromCloudFormationResult(properties);
1078 }
1079 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1080 ret.addPropertyResult('name', 'Name', cfn_parse.FromCloudFormation.getString(properties.Name));
1081 ret.addPropertyResult('type', 'Type', cfn_parse.FromCloudFormation.getString(properties.Type));
1082 ret.addPropertyResult('aliasTarget', 'AliasTarget', properties.AliasTarget != null ? CfnRecordSetAliasTargetPropertyFromCloudFormation(properties.AliasTarget) : undefined);
1083 ret.addPropertyResult('comment', 'Comment', properties.Comment != null ? cfn_parse.FromCloudFormation.getString(properties.Comment) : undefined);
1084 ret.addPropertyResult('failover', 'Failover', properties.Failover != null ? cfn_parse.FromCloudFormation.getString(properties.Failover) : undefined);
1085 ret.addPropertyResult('geoLocation', 'GeoLocation', properties.GeoLocation != null ? CfnRecordSetGeoLocationPropertyFromCloudFormation(properties.GeoLocation) : undefined);
1086 ret.addPropertyResult('healthCheckId', 'HealthCheckId', properties.HealthCheckId != null ? cfn_parse.FromCloudFormation.getString(properties.HealthCheckId) : undefined);
1087 ret.addPropertyResult('hostedZoneId', 'HostedZoneId', properties.HostedZoneId != null ? cfn_parse.FromCloudFormation.getString(properties.HostedZoneId) : undefined);
1088 ret.addPropertyResult('hostedZoneName', 'HostedZoneName', properties.HostedZoneName != null ? cfn_parse.FromCloudFormation.getString(properties.HostedZoneName) : undefined);
1089 ret.addPropertyResult('multiValueAnswer', 'MultiValueAnswer', properties.MultiValueAnswer != null ? cfn_parse.FromCloudFormation.getBoolean(properties.MultiValueAnswer) : undefined);
1090 ret.addPropertyResult('region', 'Region', properties.Region != null ? cfn_parse.FromCloudFormation.getString(properties.Region) : undefined);
1091 ret.addPropertyResult('resourceRecords', 'ResourceRecords', properties.ResourceRecords != null ? cfn_parse.FromCloudFormation.getStringArray(properties.ResourceRecords) : undefined);
1092 ret.addPropertyResult('setIdentifier', 'SetIdentifier', properties.SetIdentifier != null ? cfn_parse.FromCloudFormation.getString(properties.SetIdentifier) : undefined);
1093 ret.addPropertyResult('ttl', 'TTL', properties.TTL != null ? cfn_parse.FromCloudFormation.getString(properties.TTL) : undefined);
1094 ret.addPropertyResult('weight', 'Weight', properties.Weight != null ? cfn_parse.FromCloudFormation.getNumber(properties.Weight) : undefined);
1095 ret.addUnrecognizedPropertiesAsExtra(properties);
1096 return ret;
1097}
1098/**
1099 * A CloudFormation `AWS::Route53::RecordSet`
1100 *
1101 * Information about the record that you want to create.
1102 *
1103 * The `AWS::Route53::RecordSet` type can be used as a standalone resource or as an embedded property in the `AWS::Route53::RecordSetGroup` type. Note that some `AWS::Route53::RecordSet` properties are valid only when used within `AWS::Route53::RecordSetGroup` .
1104 *
1105 * For more information, see [ChangeResourceRecordSets](https://docs.aws.amazon.com/Route53/latest/APIReference/API_ChangeResourceRecordSets.html) in the *Amazon Route 53 API Reference* .
1106 *
1107 * @cloudformationResource AWS::Route53::RecordSet
1108 * @stability external
1109 *
1110 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-recordset.html
1111 */
1112class CfnRecordSet extends cdk.CfnResource {
1113 /**
1114 * Create a new `AWS::Route53::RecordSet`.
1115 *
1116 * @param scope - scope in which this resource is defined
1117 * @param id - scoped id of the resource
1118 * @param props - resource properties
1119 */
1120 constructor(scope, id, props) {
1121 super(scope, id, { type: CfnRecordSet.CFN_RESOURCE_TYPE_NAME, properties: props });
1122 try {
1123 jsiiDeprecationWarnings._aws_cdk_aws_route53_CfnRecordSetProps(props);
1124 }
1125 catch (error) {
1126 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
1127 Error.captureStackTrace(error, CfnRecordSet);
1128 }
1129 throw error;
1130 }
1131 cdk.requireProperty(props, 'name', this);
1132 cdk.requireProperty(props, 'type', this);
1133 this.name = props.name;
1134 this.type = props.type;
1135 this.aliasTarget = props.aliasTarget;
1136 this.comment = props.comment;
1137 this.failover = props.failover;
1138 this.geoLocation = props.geoLocation;
1139 this.healthCheckId = props.healthCheckId;
1140 this.hostedZoneId = props.hostedZoneId;
1141 this.hostedZoneName = props.hostedZoneName;
1142 this.multiValueAnswer = props.multiValueAnswer;
1143 this.region = props.region;
1144 this.resourceRecords = props.resourceRecords;
1145 this.setIdentifier = props.setIdentifier;
1146 this.ttl = props.ttl;
1147 this.weight = props.weight;
1148 }
1149 /**
1150 * A factory method that creates a new instance of this class from an object
1151 * containing the CloudFormation properties of this resource.
1152 * Used in the @aws-cdk/cloudformation-include module.
1153 *
1154 * @internal
1155 */
1156 static _fromCloudFormation(scope, id, resourceAttributes, options) {
1157 resourceAttributes = resourceAttributes || {};
1158 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
1159 const propsResult = CfnRecordSetPropsFromCloudFormation(resourceProperties);
1160 const ret = new CfnRecordSet(scope, id, propsResult.value);
1161 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
1162 ret.addPropertyOverride(propKey, propVal);
1163 }
1164 options.parser.handleAttributes(ret, resourceAttributes, id);
1165 return ret;
1166 }
1167 /**
1168 * Examines the CloudFormation resource and discloses attributes.
1169 *
1170 * @param inspector - tree inspector to collect and process attributes
1171 *
1172 */
1173 inspect(inspector) {
1174 inspector.addAttribute("aws:cdk:cloudformation:type", CfnRecordSet.CFN_RESOURCE_TYPE_NAME);
1175 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
1176 }
1177 get cfnProperties() {
1178 return {
1179 name: this.name,
1180 type: this.type,
1181 aliasTarget: this.aliasTarget,
1182 comment: this.comment,
1183 failover: this.failover,
1184 geoLocation: this.geoLocation,
1185 healthCheckId: this.healthCheckId,
1186 hostedZoneId: this.hostedZoneId,
1187 hostedZoneName: this.hostedZoneName,
1188 multiValueAnswer: this.multiValueAnswer,
1189 region: this.region,
1190 resourceRecords: this.resourceRecords,
1191 setIdentifier: this.setIdentifier,
1192 ttl: this.ttl,
1193 weight: this.weight,
1194 };
1195 }
1196 renderProperties(props) {
1197 return cfnRecordSetPropsToCloudFormation(props);
1198 }
1199}
1200exports.CfnRecordSet = CfnRecordSet;
1201_e = JSII_RTTI_SYMBOL_1;
1202CfnRecordSet[_e] = { fqn: "@aws-cdk/aws-route53.CfnRecordSet", version: "1.160.0" };
1203/**
1204 * The CloudFormation resource type name for this resource class.
1205 */
1206CfnRecordSet.CFN_RESOURCE_TYPE_NAME = "AWS::Route53::RecordSet";
1207/**
1208 * Determine whether the given properties match those of a `AliasTargetProperty`
1209 *
1210 * @param properties - the TypeScript properties of a `AliasTargetProperty`
1211 *
1212 * @returns the result of the validation.
1213 */
1214function CfnRecordSet_AliasTargetPropertyValidator(properties) {
1215 if (!cdk.canInspect(properties)) {
1216 return cdk.VALIDATION_SUCCESS;
1217 }
1218 const errors = new cdk.ValidationResults();
1219 if (typeof properties !== 'object') {
1220 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1221 }
1222 errors.collect(cdk.propertyValidator('dnsName', cdk.requiredValidator)(properties.dnsName));
1223 errors.collect(cdk.propertyValidator('dnsName', cdk.validateString)(properties.dnsName));
1224 errors.collect(cdk.propertyValidator('evaluateTargetHealth', cdk.validateBoolean)(properties.evaluateTargetHealth));
1225 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.requiredValidator)(properties.hostedZoneId));
1226 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.validateString)(properties.hostedZoneId));
1227 return errors.wrap('supplied properties not correct for "AliasTargetProperty"');
1228}
1229/**
1230 * Renders the AWS CloudFormation properties of an `AWS::Route53::RecordSet.AliasTarget` resource
1231 *
1232 * @param properties - the TypeScript properties of a `AliasTargetProperty`
1233 *
1234 * @returns the AWS CloudFormation properties of an `AWS::Route53::RecordSet.AliasTarget` resource.
1235 */
1236// @ts-ignore TS6133
1237function cfnRecordSetAliasTargetPropertyToCloudFormation(properties) {
1238 if (!cdk.canInspect(properties)) {
1239 return properties;
1240 }
1241 CfnRecordSet_AliasTargetPropertyValidator(properties).assertSuccess();
1242 return {
1243 DNSName: cdk.stringToCloudFormation(properties.dnsName),
1244 EvaluateTargetHealth: cdk.booleanToCloudFormation(properties.evaluateTargetHealth),
1245 HostedZoneId: cdk.stringToCloudFormation(properties.hostedZoneId),
1246 };
1247}
1248// @ts-ignore TS6133
1249function CfnRecordSetAliasTargetPropertyFromCloudFormation(properties) {
1250 if (cdk.isResolvableObject(properties)) {
1251 return new cfn_parse.FromCloudFormationResult(properties);
1252 }
1253 properties = properties == null ? {} : properties;
1254 if (typeof properties !== 'object') {
1255 return new cfn_parse.FromCloudFormationResult(properties);
1256 }
1257 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1258 ret.addPropertyResult('dnsName', 'DNSName', cfn_parse.FromCloudFormation.getString(properties.DNSName));
1259 ret.addPropertyResult('evaluateTargetHealth', 'EvaluateTargetHealth', properties.EvaluateTargetHealth != null ? cfn_parse.FromCloudFormation.getBoolean(properties.EvaluateTargetHealth) : undefined);
1260 ret.addPropertyResult('hostedZoneId', 'HostedZoneId', cfn_parse.FromCloudFormation.getString(properties.HostedZoneId));
1261 ret.addUnrecognizedPropertiesAsExtra(properties);
1262 return ret;
1263}
1264/**
1265 * Determine whether the given properties match those of a `GeoLocationProperty`
1266 *
1267 * @param properties - the TypeScript properties of a `GeoLocationProperty`
1268 *
1269 * @returns the result of the validation.
1270 */
1271function CfnRecordSet_GeoLocationPropertyValidator(properties) {
1272 if (!cdk.canInspect(properties)) {
1273 return cdk.VALIDATION_SUCCESS;
1274 }
1275 const errors = new cdk.ValidationResults();
1276 if (typeof properties !== 'object') {
1277 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1278 }
1279 errors.collect(cdk.propertyValidator('continentCode', cdk.validateString)(properties.continentCode));
1280 errors.collect(cdk.propertyValidator('countryCode', cdk.validateString)(properties.countryCode));
1281 errors.collect(cdk.propertyValidator('subdivisionCode', cdk.validateString)(properties.subdivisionCode));
1282 return errors.wrap('supplied properties not correct for "GeoLocationProperty"');
1283}
1284/**
1285 * Renders the AWS CloudFormation properties of an `AWS::Route53::RecordSet.GeoLocation` resource
1286 *
1287 * @param properties - the TypeScript properties of a `GeoLocationProperty`
1288 *
1289 * @returns the AWS CloudFormation properties of an `AWS::Route53::RecordSet.GeoLocation` resource.
1290 */
1291// @ts-ignore TS6133
1292function cfnRecordSetGeoLocationPropertyToCloudFormation(properties) {
1293 if (!cdk.canInspect(properties)) {
1294 return properties;
1295 }
1296 CfnRecordSet_GeoLocationPropertyValidator(properties).assertSuccess();
1297 return {
1298 ContinentCode: cdk.stringToCloudFormation(properties.continentCode),
1299 CountryCode: cdk.stringToCloudFormation(properties.countryCode),
1300 SubdivisionCode: cdk.stringToCloudFormation(properties.subdivisionCode),
1301 };
1302}
1303// @ts-ignore TS6133
1304function CfnRecordSetGeoLocationPropertyFromCloudFormation(properties) {
1305 if (cdk.isResolvableObject(properties)) {
1306 return new cfn_parse.FromCloudFormationResult(properties);
1307 }
1308 properties = properties == null ? {} : properties;
1309 if (typeof properties !== 'object') {
1310 return new cfn_parse.FromCloudFormationResult(properties);
1311 }
1312 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1313 ret.addPropertyResult('continentCode', 'ContinentCode', properties.ContinentCode != null ? cfn_parse.FromCloudFormation.getString(properties.ContinentCode) : undefined);
1314 ret.addPropertyResult('countryCode', 'CountryCode', properties.CountryCode != null ? cfn_parse.FromCloudFormation.getString(properties.CountryCode) : undefined);
1315 ret.addPropertyResult('subdivisionCode', 'SubdivisionCode', properties.SubdivisionCode != null ? cfn_parse.FromCloudFormation.getString(properties.SubdivisionCode) : undefined);
1316 ret.addUnrecognizedPropertiesAsExtra(properties);
1317 return ret;
1318}
1319/**
1320 * Determine whether the given properties match those of a `CfnRecordSetGroupProps`
1321 *
1322 * @param properties - the TypeScript properties of a `CfnRecordSetGroupProps`
1323 *
1324 * @returns the result of the validation.
1325 */
1326function CfnRecordSetGroupPropsValidator(properties) {
1327 if (!cdk.canInspect(properties)) {
1328 return cdk.VALIDATION_SUCCESS;
1329 }
1330 const errors = new cdk.ValidationResults();
1331 if (typeof properties !== 'object') {
1332 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1333 }
1334 errors.collect(cdk.propertyValidator('comment', cdk.validateString)(properties.comment));
1335 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.validateString)(properties.hostedZoneId));
1336 errors.collect(cdk.propertyValidator('hostedZoneName', cdk.validateString)(properties.hostedZoneName));
1337 errors.collect(cdk.propertyValidator('recordSets', cdk.listValidator(CfnRecordSetGroup_RecordSetPropertyValidator))(properties.recordSets));
1338 return errors.wrap('supplied properties not correct for "CfnRecordSetGroupProps"');
1339}
1340/**
1341 * Renders the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup` resource
1342 *
1343 * @param properties - the TypeScript properties of a `CfnRecordSetGroupProps`
1344 *
1345 * @returns the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup` resource.
1346 */
1347// @ts-ignore TS6133
1348function cfnRecordSetGroupPropsToCloudFormation(properties) {
1349 if (!cdk.canInspect(properties)) {
1350 return properties;
1351 }
1352 CfnRecordSetGroupPropsValidator(properties).assertSuccess();
1353 return {
1354 Comment: cdk.stringToCloudFormation(properties.comment),
1355 HostedZoneId: cdk.stringToCloudFormation(properties.hostedZoneId),
1356 HostedZoneName: cdk.stringToCloudFormation(properties.hostedZoneName),
1357 RecordSets: cdk.listMapper(cfnRecordSetGroupRecordSetPropertyToCloudFormation)(properties.recordSets),
1358 };
1359}
1360// @ts-ignore TS6133
1361function CfnRecordSetGroupPropsFromCloudFormation(properties) {
1362 properties = properties == null ? {} : properties;
1363 if (typeof properties !== 'object') {
1364 return new cfn_parse.FromCloudFormationResult(properties);
1365 }
1366 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1367 ret.addPropertyResult('comment', 'Comment', properties.Comment != null ? cfn_parse.FromCloudFormation.getString(properties.Comment) : undefined);
1368 ret.addPropertyResult('hostedZoneId', 'HostedZoneId', properties.HostedZoneId != null ? cfn_parse.FromCloudFormation.getString(properties.HostedZoneId) : undefined);
1369 ret.addPropertyResult('hostedZoneName', 'HostedZoneName', properties.HostedZoneName != null ? cfn_parse.FromCloudFormation.getString(properties.HostedZoneName) : undefined);
1370 ret.addPropertyResult('recordSets', 'RecordSets', properties.RecordSets != null ? cfn_parse.FromCloudFormation.getArray(CfnRecordSetGroupRecordSetPropertyFromCloudFormation)(properties.RecordSets) : undefined);
1371 ret.addUnrecognizedPropertiesAsExtra(properties);
1372 return ret;
1373}
1374/**
1375 * A CloudFormation `AWS::Route53::RecordSetGroup`
1376 *
1377 * A complex type that contains an optional comment, the name and ID of the hosted zone that you want to make changes in, and values for the records that you want to create.
1378 *
1379 * @cloudformationResource AWS::Route53::RecordSetGroup
1380 * @stability external
1381 *
1382 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53-recordsetgroup.html
1383 */
1384class CfnRecordSetGroup extends cdk.CfnResource {
1385 /**
1386 * Create a new `AWS::Route53::RecordSetGroup`.
1387 *
1388 * @param scope - scope in which this resource is defined
1389 * @param id - scoped id of the resource
1390 * @param props - resource properties
1391 */
1392 constructor(scope, id, props = {}) {
1393 super(scope, id, { type: CfnRecordSetGroup.CFN_RESOURCE_TYPE_NAME, properties: props });
1394 try {
1395 jsiiDeprecationWarnings._aws_cdk_aws_route53_CfnRecordSetGroupProps(props);
1396 }
1397 catch (error) {
1398 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
1399 Error.captureStackTrace(error, CfnRecordSetGroup);
1400 }
1401 throw error;
1402 }
1403 this.comment = props.comment;
1404 this.hostedZoneId = props.hostedZoneId;
1405 this.hostedZoneName = props.hostedZoneName;
1406 this.recordSets = props.recordSets;
1407 }
1408 /**
1409 * A factory method that creates a new instance of this class from an object
1410 * containing the CloudFormation properties of this resource.
1411 * Used in the @aws-cdk/cloudformation-include module.
1412 *
1413 * @internal
1414 */
1415 static _fromCloudFormation(scope, id, resourceAttributes, options) {
1416 resourceAttributes = resourceAttributes || {};
1417 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
1418 const propsResult = CfnRecordSetGroupPropsFromCloudFormation(resourceProperties);
1419 const ret = new CfnRecordSetGroup(scope, id, propsResult.value);
1420 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
1421 ret.addPropertyOverride(propKey, propVal);
1422 }
1423 options.parser.handleAttributes(ret, resourceAttributes, id);
1424 return ret;
1425 }
1426 /**
1427 * Examines the CloudFormation resource and discloses attributes.
1428 *
1429 * @param inspector - tree inspector to collect and process attributes
1430 *
1431 */
1432 inspect(inspector) {
1433 inspector.addAttribute("aws:cdk:cloudformation:type", CfnRecordSetGroup.CFN_RESOURCE_TYPE_NAME);
1434 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
1435 }
1436 get cfnProperties() {
1437 return {
1438 comment: this.comment,
1439 hostedZoneId: this.hostedZoneId,
1440 hostedZoneName: this.hostedZoneName,
1441 recordSets: this.recordSets,
1442 };
1443 }
1444 renderProperties(props) {
1445 return cfnRecordSetGroupPropsToCloudFormation(props);
1446 }
1447}
1448exports.CfnRecordSetGroup = CfnRecordSetGroup;
1449_f = JSII_RTTI_SYMBOL_1;
1450CfnRecordSetGroup[_f] = { fqn: "@aws-cdk/aws-route53.CfnRecordSetGroup", version: "1.160.0" };
1451/**
1452 * The CloudFormation resource type name for this resource class.
1453 */
1454CfnRecordSetGroup.CFN_RESOURCE_TYPE_NAME = "AWS::Route53::RecordSetGroup";
1455/**
1456 * Determine whether the given properties match those of a `AliasTargetProperty`
1457 *
1458 * @param properties - the TypeScript properties of a `AliasTargetProperty`
1459 *
1460 * @returns the result of the validation.
1461 */
1462function CfnRecordSetGroup_AliasTargetPropertyValidator(properties) {
1463 if (!cdk.canInspect(properties)) {
1464 return cdk.VALIDATION_SUCCESS;
1465 }
1466 const errors = new cdk.ValidationResults();
1467 if (typeof properties !== 'object') {
1468 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1469 }
1470 errors.collect(cdk.propertyValidator('dnsName', cdk.requiredValidator)(properties.dnsName));
1471 errors.collect(cdk.propertyValidator('dnsName', cdk.validateString)(properties.dnsName));
1472 errors.collect(cdk.propertyValidator('evaluateTargetHealth', cdk.validateBoolean)(properties.evaluateTargetHealth));
1473 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.requiredValidator)(properties.hostedZoneId));
1474 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.validateString)(properties.hostedZoneId));
1475 return errors.wrap('supplied properties not correct for "AliasTargetProperty"');
1476}
1477/**
1478 * Renders the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup.AliasTarget` resource
1479 *
1480 * @param properties - the TypeScript properties of a `AliasTargetProperty`
1481 *
1482 * @returns the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup.AliasTarget` resource.
1483 */
1484// @ts-ignore TS6133
1485function cfnRecordSetGroupAliasTargetPropertyToCloudFormation(properties) {
1486 if (!cdk.canInspect(properties)) {
1487 return properties;
1488 }
1489 CfnRecordSetGroup_AliasTargetPropertyValidator(properties).assertSuccess();
1490 return {
1491 DNSName: cdk.stringToCloudFormation(properties.dnsName),
1492 EvaluateTargetHealth: cdk.booleanToCloudFormation(properties.evaluateTargetHealth),
1493 HostedZoneId: cdk.stringToCloudFormation(properties.hostedZoneId),
1494 };
1495}
1496// @ts-ignore TS6133
1497function CfnRecordSetGroupAliasTargetPropertyFromCloudFormation(properties) {
1498 if (cdk.isResolvableObject(properties)) {
1499 return new cfn_parse.FromCloudFormationResult(properties);
1500 }
1501 properties = properties == null ? {} : properties;
1502 if (typeof properties !== 'object') {
1503 return new cfn_parse.FromCloudFormationResult(properties);
1504 }
1505 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1506 ret.addPropertyResult('dnsName', 'DNSName', cfn_parse.FromCloudFormation.getString(properties.DNSName));
1507 ret.addPropertyResult('evaluateTargetHealth', 'EvaluateTargetHealth', properties.EvaluateTargetHealth != null ? cfn_parse.FromCloudFormation.getBoolean(properties.EvaluateTargetHealth) : undefined);
1508 ret.addPropertyResult('hostedZoneId', 'HostedZoneId', cfn_parse.FromCloudFormation.getString(properties.HostedZoneId));
1509 ret.addUnrecognizedPropertiesAsExtra(properties);
1510 return ret;
1511}
1512/**
1513 * Determine whether the given properties match those of a `GeoLocationProperty`
1514 *
1515 * @param properties - the TypeScript properties of a `GeoLocationProperty`
1516 *
1517 * @returns the result of the validation.
1518 */
1519function CfnRecordSetGroup_GeoLocationPropertyValidator(properties) {
1520 if (!cdk.canInspect(properties)) {
1521 return cdk.VALIDATION_SUCCESS;
1522 }
1523 const errors = new cdk.ValidationResults();
1524 if (typeof properties !== 'object') {
1525 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1526 }
1527 errors.collect(cdk.propertyValidator('continentCode', cdk.validateString)(properties.continentCode));
1528 errors.collect(cdk.propertyValidator('countryCode', cdk.validateString)(properties.countryCode));
1529 errors.collect(cdk.propertyValidator('subdivisionCode', cdk.validateString)(properties.subdivisionCode));
1530 return errors.wrap('supplied properties not correct for "GeoLocationProperty"');
1531}
1532/**
1533 * Renders the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup.GeoLocation` resource
1534 *
1535 * @param properties - the TypeScript properties of a `GeoLocationProperty`
1536 *
1537 * @returns the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup.GeoLocation` resource.
1538 */
1539// @ts-ignore TS6133
1540function cfnRecordSetGroupGeoLocationPropertyToCloudFormation(properties) {
1541 if (!cdk.canInspect(properties)) {
1542 return properties;
1543 }
1544 CfnRecordSetGroup_GeoLocationPropertyValidator(properties).assertSuccess();
1545 return {
1546 ContinentCode: cdk.stringToCloudFormation(properties.continentCode),
1547 CountryCode: cdk.stringToCloudFormation(properties.countryCode),
1548 SubdivisionCode: cdk.stringToCloudFormation(properties.subdivisionCode),
1549 };
1550}
1551// @ts-ignore TS6133
1552function CfnRecordSetGroupGeoLocationPropertyFromCloudFormation(properties) {
1553 if (cdk.isResolvableObject(properties)) {
1554 return new cfn_parse.FromCloudFormationResult(properties);
1555 }
1556 properties = properties == null ? {} : properties;
1557 if (typeof properties !== 'object') {
1558 return new cfn_parse.FromCloudFormationResult(properties);
1559 }
1560 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1561 ret.addPropertyResult('continentCode', 'ContinentCode', properties.ContinentCode != null ? cfn_parse.FromCloudFormation.getString(properties.ContinentCode) : undefined);
1562 ret.addPropertyResult('countryCode', 'CountryCode', properties.CountryCode != null ? cfn_parse.FromCloudFormation.getString(properties.CountryCode) : undefined);
1563 ret.addPropertyResult('subdivisionCode', 'SubdivisionCode', properties.SubdivisionCode != null ? cfn_parse.FromCloudFormation.getString(properties.SubdivisionCode) : undefined);
1564 ret.addUnrecognizedPropertiesAsExtra(properties);
1565 return ret;
1566}
1567/**
1568 * Determine whether the given properties match those of a `RecordSetProperty`
1569 *
1570 * @param properties - the TypeScript properties of a `RecordSetProperty`
1571 *
1572 * @returns the result of the validation.
1573 */
1574function CfnRecordSetGroup_RecordSetPropertyValidator(properties) {
1575 if (!cdk.canInspect(properties)) {
1576 return cdk.VALIDATION_SUCCESS;
1577 }
1578 const errors = new cdk.ValidationResults();
1579 if (typeof properties !== 'object') {
1580 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1581 }
1582 errors.collect(cdk.propertyValidator('aliasTarget', CfnRecordSetGroup_AliasTargetPropertyValidator)(properties.aliasTarget));
1583 errors.collect(cdk.propertyValidator('failover', cdk.validateString)(properties.failover));
1584 errors.collect(cdk.propertyValidator('geoLocation', CfnRecordSetGroup_GeoLocationPropertyValidator)(properties.geoLocation));
1585 errors.collect(cdk.propertyValidator('healthCheckId', cdk.validateString)(properties.healthCheckId));
1586 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.validateString)(properties.hostedZoneId));
1587 errors.collect(cdk.propertyValidator('hostedZoneName', cdk.validateString)(properties.hostedZoneName));
1588 errors.collect(cdk.propertyValidator('multiValueAnswer', cdk.validateBoolean)(properties.multiValueAnswer));
1589 errors.collect(cdk.propertyValidator('name', cdk.requiredValidator)(properties.name));
1590 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
1591 errors.collect(cdk.propertyValidator('region', cdk.validateString)(properties.region));
1592 errors.collect(cdk.propertyValidator('resourceRecords', cdk.listValidator(cdk.validateString))(properties.resourceRecords));
1593 errors.collect(cdk.propertyValidator('setIdentifier', cdk.validateString)(properties.setIdentifier));
1594 errors.collect(cdk.propertyValidator('ttl', cdk.validateString)(properties.ttl));
1595 errors.collect(cdk.propertyValidator('type', cdk.requiredValidator)(properties.type));
1596 errors.collect(cdk.propertyValidator('type', cdk.validateString)(properties.type));
1597 errors.collect(cdk.propertyValidator('weight', cdk.validateNumber)(properties.weight));
1598 return errors.wrap('supplied properties not correct for "RecordSetProperty"');
1599}
1600/**
1601 * Renders the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup.RecordSet` resource
1602 *
1603 * @param properties - the TypeScript properties of a `RecordSetProperty`
1604 *
1605 * @returns the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup.RecordSet` resource.
1606 */
1607// @ts-ignore TS6133
1608function cfnRecordSetGroupRecordSetPropertyToCloudFormation(properties) {
1609 if (!cdk.canInspect(properties)) {
1610 return properties;
1611 }
1612 CfnRecordSetGroup_RecordSetPropertyValidator(properties).assertSuccess();
1613 return {
1614 AliasTarget: cfnRecordSetGroupAliasTargetPropertyToCloudFormation(properties.aliasTarget),
1615 Failover: cdk.stringToCloudFormation(properties.failover),
1616 GeoLocation: cfnRecordSetGroupGeoLocationPropertyToCloudFormation(properties.geoLocation),
1617 HealthCheckId: cdk.stringToCloudFormation(properties.healthCheckId),
1618 HostedZoneId: cdk.stringToCloudFormation(properties.hostedZoneId),
1619 HostedZoneName: cdk.stringToCloudFormation(properties.hostedZoneName),
1620 MultiValueAnswer: cdk.booleanToCloudFormation(properties.multiValueAnswer),
1621 Name: cdk.stringToCloudFormation(properties.name),
1622 Region: cdk.stringToCloudFormation(properties.region),
1623 ResourceRecords: cdk.listMapper(cdk.stringToCloudFormation)(properties.resourceRecords),
1624 SetIdentifier: cdk.stringToCloudFormation(properties.setIdentifier),
1625 TTL: cdk.stringToCloudFormation(properties.ttl),
1626 Type: cdk.stringToCloudFormation(properties.type),
1627 Weight: cdk.numberToCloudFormation(properties.weight),
1628 };
1629}
1630// @ts-ignore TS6133
1631function CfnRecordSetGroupRecordSetPropertyFromCloudFormation(properties) {
1632 if (cdk.isResolvableObject(properties)) {
1633 return new cfn_parse.FromCloudFormationResult(properties);
1634 }
1635 properties = properties == null ? {} : properties;
1636 if (typeof properties !== 'object') {
1637 return new cfn_parse.FromCloudFormationResult(properties);
1638 }
1639 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1640 ret.addPropertyResult('aliasTarget', 'AliasTarget', properties.AliasTarget != null ? CfnRecordSetGroupAliasTargetPropertyFromCloudFormation(properties.AliasTarget) : undefined);
1641 ret.addPropertyResult('failover', 'Failover', properties.Failover != null ? cfn_parse.FromCloudFormation.getString(properties.Failover) : undefined);
1642 ret.addPropertyResult('geoLocation', 'GeoLocation', properties.GeoLocation != null ? CfnRecordSetGroupGeoLocationPropertyFromCloudFormation(properties.GeoLocation) : undefined);
1643 ret.addPropertyResult('healthCheckId', 'HealthCheckId', properties.HealthCheckId != null ? cfn_parse.FromCloudFormation.getString(properties.HealthCheckId) : undefined);
1644 ret.addPropertyResult('hostedZoneId', 'HostedZoneId', properties.HostedZoneId != null ? cfn_parse.FromCloudFormation.getString(properties.HostedZoneId) : undefined);
1645 ret.addPropertyResult('hostedZoneName', 'HostedZoneName', properties.HostedZoneName != null ? cfn_parse.FromCloudFormation.getString(properties.HostedZoneName) : undefined);
1646 ret.addPropertyResult('multiValueAnswer', 'MultiValueAnswer', properties.MultiValueAnswer != null ? cfn_parse.FromCloudFormation.getBoolean(properties.MultiValueAnswer) : undefined);
1647 ret.addPropertyResult('name', 'Name', cfn_parse.FromCloudFormation.getString(properties.Name));
1648 ret.addPropertyResult('region', 'Region', properties.Region != null ? cfn_parse.FromCloudFormation.getString(properties.Region) : undefined);
1649 ret.addPropertyResult('resourceRecords', 'ResourceRecords', properties.ResourceRecords != null ? cfn_parse.FromCloudFormation.getStringArray(properties.ResourceRecords) : undefined);
1650 ret.addPropertyResult('setIdentifier', 'SetIdentifier', properties.SetIdentifier != null ? cfn_parse.FromCloudFormation.getString(properties.SetIdentifier) : undefined);
1651 ret.addPropertyResult('ttl', 'TTL', properties.TTL != null ? cfn_parse.FromCloudFormation.getString(properties.TTL) : undefined);
1652 ret.addPropertyResult('type', 'Type', cfn_parse.FromCloudFormation.getString(properties.Type));
1653 ret.addPropertyResult('weight', 'Weight', properties.Weight != null ? cfn_parse.FromCloudFormation.getNumber(properties.Weight) : undefined);
1654 ret.addUnrecognizedPropertiesAsExtra(properties);
1655 return ret;
1656}
1657//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGU1My5nZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJyb3V0ZTUzLmdlbmVyYXRlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSwrRUFBK0U7QUFDL0UsK0RBQStEO0FBQy9ELDhGQUE4RjtBQUM5RixzSEFBc0g7QUFFdEgsNEJBQTRCLENBQUMsaUVBQWlFO0FBRTlGLHFDQUFxQztBQUNyQyxnRUFBZ0U7QUFvQmhFOzs7Ozs7R0FNRztBQUNILFNBQVMsdUJBQXVCLENBQUMsVUFBZTtJQUM1QyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsRUFBRTtRQUFFLE9BQU8sR0FBRyxDQUFDLGtCQUFrQixDQUFDO0tBQUU7SUFDbkUsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUMzQyxJQUFJLE9BQU8sVUFBVSxLQUFLLFFBQVEsRUFBRTtRQUNoQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksR0FBRyxDQUFDLGdCQUFnQixDQUFDLG9DQUFvQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQy9HO0lBQ0QsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsY0FBYyxFQUFFLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQ3RHLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLGNBQWMsRUFBRSxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7SUFDbkcsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLHNEQUFzRCxDQUFDLENBQUM7QUFDL0UsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILG9CQUFvQjtBQUNwQixTQUFTLDhCQUE4QixDQUFDLFVB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QUFVLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3pLLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxjQUFjLEVBQUUsY0FBYyxFQUFFLFVBQVUsQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDckssR0FBRyxDQUFDLGlCQUFpQixDQUFDLGdCQUFnQixFQUFFLGdCQUFnQixFQUFFLFVBQVUsQ0FBQyxjQUFjLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0ssR0FBRyxDQUFDLGlCQUFpQixDQUFDLGtCQUFrQixFQUFFLGtCQUFrQixFQUFFLFVBQVUsQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3RMLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0ksR0FBRyxDQUFDLGlCQUFpQixDQUFDLGlCQUFpQixFQUFFLGlCQUFpQixFQUFFLFVBQVUsQ0FBQyxlQUFlLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMs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LGVBQWUsRUFBRSxlQUFlLEVBQUUsVUFBVSxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN6SyxHQUFHLENBQUMsaUJBQWlCLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxVQUFVLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2pJLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDL0YsR0FBRyxDQUFDLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsVUFBVSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUM3SSxHQUFHLENBQUMsZ0NBQWdDLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDakQsT0FBTyxHQUFHLENBQUM7QUFDZixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMTItMjAyMiBBbWF6b24uY29tLCBJbmMuIG9yIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuLy8gR2VuZXJhdGVkIGZyb20gdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBSZXNvdXJjZSBTcGVjaWZpY2F0aW9uXG4vLyBTZWU6IGRvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9jZm4tcmVzb3VyY2Utc3BlY2lmaWNhdGlvbi5odG1sXG4vLyBAY2ZuMnRzOm1ldGFAIHtcImdlbmVyYXRlZFwiOlwiMjAyMi0wNi0xNFQxMzoyNjoxOS43OTZaXCIsXCJmaW5nZXJwcmludFwiOlwiUU5PQkZUZGQzQWFORWhJV2tvbisyNGczSDZFNVF2aHpyL0dTN213MzRNST1cIn1cblxuLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqLyAvLyBUaGlzIGlzIGdlbmVyYXRlZCBjb2RlIC0gbGluZSBsZW5ndGhzIGFyZSBkaWZmaWN1bHQgdG8gY29udHJvbFxuXG5pbXBvcnQgKiBhcyBjZGsgZnJvbSAnQGF3cy1jZGsvY29yZSc7XG5pbXBvcnQgKiBhcyBjZm5fcGFyc2UgZnJvbSAnQGF3cy1jZGsvY29yZS9saWIvaGVscGVycy1pbnRlcm5hbCc7XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuRE5TU0VDYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWRuc3NlYy5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2ZuRE5TU0VDUHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogQSB1bmlxdWUgc3RyaW5nIChJRCkgdGhhdCBpcyB1c2VkIHRvIGlkZW50aWZ5IGEgaG9zdGVkIHpvbmUuIEZvciBleGFtcGxlOiBgWjAwMDAxMTExQTFBQkNhYUFCQzExYCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWRuc3NlYy5odG1sI2Nmbi1yb3V0ZTUzLWRuc3NlYy1ob3N0ZWR6b25laWRcbiAgICAgKi9cbiAgICByZWFkb25seSBob3N0ZWRab25lSWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDZm5ETlNTRUNQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuRE5TU0VDUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuRE5TU0VDUHJvcHNWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdob3N0ZWRab25lSWQnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMuaG9zdGVkWm9uZUlkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdob3N0ZWRab25lSWQnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuaG9zdGVkWm9uZUlkKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNmbkROU1NFQ1Byb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpETlNTRUNgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbkROU1NFQ1Byb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpETlNTRUNgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuRE5TU0VDUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbkROU1NFQ1Byb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBIb3N0ZWRab25lSWQ6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaG9zdGVkWm9uZUlkKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuRE5TU0VDUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5ETlNTRUNQcm9wcz4ge1xuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuRE5TU0VDUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdob3N0ZWRab25lSWQnLCAnSG9zdGVkWm9uZUlkJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Ib3N0ZWRab25lSWQpKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBBIENsb3VkRm9ybWF0aW9uIGBBV1M6OlJvdXRlNTM6OkROU1NFQ2BcbiAqXG4gKiBUaGUgYEFXUzo6Um91dGU1Mzo6RE5TU0VDYCByZXNvdXJjZSBpcyB1c2VkIHRvIGVuYWJsZSBETlNTRUMgc2lnbmluZyBpbiBhIGhvc3RlZCB6b25lLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6Um91dGU1Mzo6RE5TU0VDXG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1kbnNzZWMuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuRE5TU0VDIGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6Um91dGU1Mzo6RE5TU0VDXCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5ETlNTRUMge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmbkROU1NFQ1Byb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5ETlNTRUMoc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSB1bmlxdWUgc3RyaW5nIChJRCkgdGhhdCBpcyB1c2VkIHRvIGlkZW50aWZ5IGEgaG9zdGVkIHpvbmUuIEZvciBleGFtcGxlOiBgWjAwMDAxMTExQTFBQkNhYUFCQzExYCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWRuc3NlYy5odG1sI2Nmbi1yb3V0ZTUzLWRuc3NlYy1ob3N0ZWR6b25laWRcbiAgICAgKi9cbiAgICBwdWJsaWMgaG9zdGVkWm9uZUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6Um91dGU1Mzo6RE5TU0VDYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5ETlNTRUNQcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuRE5TU0VDLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUsIHByb3BlcnRpZXM6IHByb3BzIH0pO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAnaG9zdGVkWm9uZUlkJywgdGhpcyk7XG5cbiAgICAgICAgdGhpcy5ob3N0ZWRab25lSWQgPSBwcm9wcy5ob3N0ZWRab25lSWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5ETlNTRUMuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGhvc3RlZFpvbmVJZDogdGhpcy5ob3N0ZWRab25lSWQsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlbmRlclByb3BlcnRpZXMocHJvcHM6IHtba2V5OiBzdHJpbmddOiBhbnl9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4gY2ZuRE5TU0VDUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuSGVhbHRoQ2hlY2tgXG4gKlxuICogQHN0cnVjdFxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtaGVhbHRoY2hlY2suaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENmbkhlYWx0aENoZWNrUHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogQSBjb21wbGV4IHR5cGUgdGhhdCBjb250YWlucyBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhYm91dCBvbmUgaGVhbHRoIGNoZWNrLlxuICAgICAqXG4gICAgICogRm9yIHRoZSB2YWx1ZXMgdG8gZW50ZXIgZm9yIGBIZWFsdGhDaGVja0NvbmZpZ2AgLCBzZWUgW0hlYWx0aENoZWNrQ29uZmlnXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9IZWFsdGhDaGVja0NvbmZpZy5odG1sKVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1oZWFsdGhjaGVjay5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnXG4gICAgICovXG4gICAgcmVhZG9ubHkgaGVhbHRoQ2hlY2tDb25maWc6IENmbkhlYWx0aENoZWNrLkhlYWx0aENoZWNrQ29uZmlnUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYEhlYWx0aENoZWNrVGFnc2AgcHJvcGVydHkgZGVzY3JpYmVzIGtleS12YWx1ZSBwYWlycyB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggYW4gYEFXUzo6Um91dGU1Mzo6SGVhbHRoQ2hlY2tgIHJlc291cmNlLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1oZWFsdGhjaGVjay5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrdGFnc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IGhlYWx0aENoZWNrVGFncz86IEFycmF5PENmbkhlYWx0aENoZWNrLkhlYWx0aENoZWNrVGFnUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmbkhlYWx0aENoZWNrUHJvcHNgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbkhlYWx0aENoZWNrUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuSGVhbHRoQ2hlY2tQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hlYWx0aENoZWNrQ29uZmlnJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmhlYWx0aENoZWNrQ29uZmlnKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdoZWFsdGhDaGVja0NvbmZpZycsIENmbkhlYWx0aENoZWNrX0hlYWx0aENoZWNrQ29uZmlnUHJvcGVydHlWYWxpZGF0b3IpKHByb3BlcnRpZXMuaGVhbHRoQ2hlY2tDb25maWcpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hlYWx0aENoZWNrVGFncycsIGNkay5saXN0VmFsaWRhdG9yKENmbkhlYWx0aENoZWNrX0hlYWx0aENoZWNrVGFnUHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLmhlYWx0aENoZWNrVGFncykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5IZWFsdGhDaGVja1Byb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpIZWFsdGhDaGVja2AgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuSGVhbHRoQ2hlY2tQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6SGVhbHRoQ2hlY2tgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuSGVhbHRoQ2hlY2tQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuSGVhbHRoQ2hlY2tQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgSGVhbHRoQ2hlY2tDb25maWc6IGNmbkhlYWx0aENoZWNrSGVhbHRoQ2hlY2tDb25maWdQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5oZWFsdGhDaGVja0NvbmZpZyksXG4gICAgICAgIEhlYWx0aENoZWNrVGFnczogY2RrLmxpc3RNYXBwZXIoY2ZuSGVhbHRoQ2hlY2tIZWFsdGhDaGVja1RhZ1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5oZWFsdGhDaGVja1RhZ3MpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5IZWFsdGhDaGVja1Byb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuSGVhbHRoQ2hlY2tQcm9wcz4ge1xuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuSGVhbHRoQ2hlY2tQcm9wcz4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2hlYWx0aENoZWNrQ29uZmlnJywgJ0hlYWx0aENoZWNrQ29uZmlnJywgQ2ZuSGVhbHRoQ2hlY2tIZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuSGVhbHRoQ2hlY2tDb25maWcpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2hlYWx0aENoZWNrVGFncycsICdIZWFsdGhDaGVja1RhZ3MnLCBwcm9wZXJ0aWVzLkhlYWx0aENoZWNrVGFncyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5IZWFsdGhDaGVja0hlYWx0aENoZWNrVGFnUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuSGVhbHRoQ2hlY2tUYWdzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpSb3V0ZTUzOjpIZWFsdGhDaGVja2BcbiAqXG4gKiBUaGUgYEFXUzo6Um91dGU1Mzo6SGVhbHRoQ2hlY2tgIHJlc291cmNlIGlzIGEgUm91dGUgNTMgcmVzb3VyY2UgdHlwZSB0aGF0IGNvbnRhaW5zIHNldHRpbmdzIGZvciBhIFJvdXRlIDUzIGhlYWx0aCBjaGVjay5cbiAqXG4gKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgYXNzb2NpYXRpbmcgaGVhbHRoIGNoZWNrcyB3aXRoIHJlY29yZHMsIHNlZSBbSGVhbHRoQ2hlY2tJZF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUmVzb3VyY2VSZWNvcmRTZXQuaHRtbCNSb3V0ZTUzLVR5cGUtUmVzb3VyY2VSZWNvcmRTZXQtSGVhbHRoQ2hlY2tJZCkgaW4gW0NoYW5nZVJlc291cmNlUmVjb3JkU2V0c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ2hhbmdlUmVzb3VyY2VSZWNvcmRTZXRzLmh0bWwpIC5cbiAqXG4gKiA+IFlvdSBjYW4ndCBjcmVhdGUgYSBoZWFsdGggY2hlY2sgd2l0aCBzaW1wbGUgcm91dGluZy5cbiAqXG4gKiAqRUxCIExvYWQgQmFsYW5jZXJzKlxuICpcbiAqIElmIHlvdSdyZSByZWdpc3RlcmluZyBFQzIgaW5zdGFuY2VzIHdpdGggYW4gRWxhc3RpYyBMb2FkIEJhbGFuY2luZyAoRUxCKSBsb2FkIGJhbGFuY2VyLCBkbyBub3QgY3JlYXRlIEFtYXpvbiBSb3V0ZSA1MyBoZWFsdGggY2hlY2tzIGZvciB0aGUgRUMyIGluc3RhbmNlcy4gV2hlbiB5b3UgcmVnaXN0ZXIgYW4gRUMyIGluc3RhbmNlIHdpdGggYSBsb2FkIGJhbGFuY2VyLCB5b3UgY29uZmlndXJlIHNldHRpbmdzIGZvciBhbiBFTEIgaGVhbHRoIGNoZWNrLCB3aGljaCBwZXJmb3JtcyBhIHNpbWlsYXIgZnVuY3Rpb24gdG8gYSBSb3V0ZSA1MyBoZWFsdGggY2hlY2suXG4gKlxuICogKlByaXZhdGUgSG9zdGVkIFpvbmVzKlxuICpcbiAqIFlvdSBjYW4gYXNzb2NpYXRlIGhlYWx0aCBjaGVja3Mgd2l0aCBmYWlsb3ZlciByZWNvcmRzIGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZS4gTm90ZSB0aGUgZm9sbG93aW5nOlxuICpcbiAqIC0gUm91dGUgNTMgaGVhbHRoIGNoZWNrZXJzIGFyZSBvdXRzaWRlIHRoZSBWUEMuIFRvIGNoZWNrIHRoZSBoZWFsdGggb2YgYW4gZW5kcG9pbnQgd2l0aGluIGEgVlBDIGJ5IElQIGFkZHJlc3MsIHlvdSBtdXN0IGFzc2lnbiBhIHB1YmxpYyBJUCBhZGRyZXNzIHRvIHRoZSBpbnN0YW5jZSBpbiB0aGUgVlBDLlxuICogLSBZb3UgY2FuIGNvbmZpZ3VyZSBhIGhlYWx0aCBjaGVja2VyIHRvIGNoZWNrIHRoZSBoZWFsdGggb2YgYW4gZXh0ZXJuYWwgcmVzb3VyY2UgdGhhdCB0aGUgaW5zdGFuY2UgcmVsaWVzIG9uLCBzdWNoIGFzIGEgZGF0YWJhc2Ugc2VydmVyLlxuICogLSBZb3UgY2FuIGNyZWF0ZSBhIENsb3VkV2F0Y2ggbWV0cmljLCBhc3NvY2lhdGUgYW4gYWxhcm0gd2l0aCB0aGUgbWV0cmljLCBhbmQgdGhlbiBjcmVhdGUgYSBoZWFsdGggY2hlY2sgdGhhdCBpcyBiYXNlZCBvbiB0aGUgc3RhdGUgb2YgdGhlIGFsYXJtLiBGb3IgZXhhbXBsZSwgeW91IG1pZ2h0IGNyZWF0ZSBhIENsb3VkV2F0Y2ggbWV0cmljIHRoYXQgY2hlY2tzIHRoZSBzdGF0dXMgb2YgdGhlIEFtYXpvbiBFQzIgYFN0YXR1c0NoZWNrRmFpbGVkYCBtZXRyaWMsIGFkZCBhbiBhbGFybSB0byB0aGUgbWV0cmljLCBhbmQgdGhlbiBjcmVhdGUgYSBoZWFsdGggY2hlY2sgdGhhdCBpcyBiYXNlZCBvbiB0aGUgc3RhdGUgb2YgdGhlIGFsYXJtLiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgY3JlYXRpbmcgQ2xvdWRXYXRjaCBtZXRyaWNzIGFuZCBhbGFybXMgYnkgdXNpbmcgdGhlIENsb3VkV2F0Y2ggY29uc29sZSwgc2VlIHRoZSBbQW1hem9uIENsb3VkV2F0Y2ggVXNlciBHdWlkZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L0RldmVsb3Blckd1aWRlL1doYXRJc0Nsb3VkV2F0Y2guaHRtbCkgLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6Um91dGU1Mzo6SGVhbHRoQ2hlY2tcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWhlYWx0aGNoZWNrLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIENmbkhlYWx0aENoZWNrIGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6Um91dGU1Mzo6SGVhbHRoQ2hlY2tcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmbkhlYWx0aENoZWNrIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5IZWFsdGhDaGVja1Byb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5IZWFsdGhDaGVjayhzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgaWRlbnRpZmllciB0aGF0IEFtYXpvbiBSb3V0ZSA1MyBhc3NpZ25lZCB0byB0aGUgaGVhbHRoIGNoZWNrIHdoZW4geW91IGNyZWF0ZWQgaXQuIFdoZW4geW91IGFkZCBvciB1cGRhdGUgYSByZXNvdXJjZSByZWNvcmQgc2V0LCB5b3UgdXNlIHRoaXMgdmFsdWUgdG8gc3BlY2lmeSB3aGljaCBoZWFsdGggY2hlY2sgdG8gdXNlLiBUaGUgdmFsdWUgY2FuIGJlIHVwIHRvIDY0IGNoYXJhY3RlcnMgbG9uZy5cbiAgICAgKiBAY2xvdWRmb3JtYXRpb25BdHRyaWJ1dGUgSGVhbHRoQ2hlY2tJZFxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBhdHRySGVhbHRoQ2hlY2tJZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBjb21wbGV4IHR5cGUgdGhhdCBjb250YWlucyBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhYm91dCBvbmUgaGVhbHRoIGNoZWNrLlxuICAgICAqXG4gICAgICogRm9yIHRoZSB2YWx1ZXMgdG8gZW50ZXIgZm9yIGBIZWFsdGhDaGVja0NvbmZpZ2AgLCBzZWUgW0hlYWx0aENoZWNrQ29uZmlnXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9IZWFsdGhDaGVja0NvbmZpZy5odG1sKVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1oZWFsdGhjaGVjay5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnXG4gICAgICovXG4gICAgcHVibGljIGhlYWx0aENoZWNrQ29uZmlnOiBDZm5IZWFsdGhDaGVjay5IZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGBIZWFsdGhDaGVja1RhZ3NgIHByb3BlcnR5IGRlc2NyaWJlcyBrZXktdmFsdWUgcGFpcnMgdGhhdCBhcmUgYXNzb2NpYXRlZCB3aXRoIGFuIGBBV1M6OlJvdXRlNTM6OkhlYWx0aENoZWNrYCByZXNvdXJjZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtaGVhbHRoY2hlY2suaHRtbCNjZm4tcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja3RhZ3NcbiAgICAgKi9cbiAgICBwdWJsaWMgaGVhbHRoQ2hlY2tUYWdzOiBBcnJheTxDZm5IZWFsdGhDaGVjay5IZWFsdGhDaGVja1RhZ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpSb3V0ZTUzOjpIZWFsdGhDaGVja2AuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuSGVhbHRoQ2hlY2tQcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuSGVhbHRoQ2hlY2suQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICdoZWFsdGhDaGVja0NvbmZpZycsIHRoaXMpO1xuICAgICAgICB0aGlzLmF0dHJIZWFsdGhDaGVja0lkID0gY2RrLlRva2VuLmFzU3RyaW5nKHRoaXMuZ2V0QXR0KCdIZWFsdGhDaGVja0lkJykpO1xuXG4gICAgICAgIHRoaXMuaGVhbHRoQ2hlY2tDb25maWcgPSBwcm9wcy5oZWFsdGhDaGVja0NvbmZpZztcbiAgICAgICAgdGhpcy5oZWFsdGhDaGVja1RhZ3MgPSBwcm9wcy5oZWFsdGhDaGVja1RhZ3M7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5IZWFsdGhDaGVjay5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FKTtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246cHJvcHNcIiwgdGhpcy5jZm5Qcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGNmblByb3BlcnRpZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaGVhbHRoQ2hlY2tDb25maWc6IHRoaXMuaGVhbHRoQ2hlY2tDb25maWcsXG4gICAgICAgICAgICBoZWFsdGhDaGVja1RhZ3M6IHRoaXMuaGVhbHRoQ2hlY2tUYWdzLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmbkhlYWx0aENoZWNrUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuSGVhbHRoQ2hlY2sge1xuICAgIC8qKlxuICAgICAqXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWFsYXJtaWRlbnRpZmllci5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBBbGFybUlkZW50aWZpZXJQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBgQ2ZuSGVhbHRoQ2hlY2suQWxhcm1JZGVudGlmaWVyUHJvcGVydHkuTmFtZWBcbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWFsYXJtaWRlbnRpZmllci5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWFsYXJtaWRlbnRpZmllci1uYW1lXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBgQ2ZuSGVhbHRoQ2hlY2suQWxhcm1JZGVudGlmaWVyUHJvcGVydHkuUmVnaW9uYFxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaGVhbHRoY2hlY2stYWxhcm1pZGVudGlmaWVyLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2stYWxhcm1pZGVudGlmaWVyLXJlZ2lvblxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcmVnaW9uOiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYEFsYXJtSWRlbnRpZmllclByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBBbGFybUlkZW50aWZpZXJQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5IZWFsdGhDaGVja19BbGFybUlkZW50aWZpZXJQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ25hbWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMubmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5uYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyZWdpb24nLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMucmVnaW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyZWdpb24nLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucmVnaW9uKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkFsYXJtSWRlbnRpZmllclByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpIZWFsdGhDaGVjay5BbGFybUlkZW50aWZpZXJgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEFsYXJtSWRlbnRpZmllclByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpIZWFsdGhDaGVjay5BbGFybUlkZW50aWZpZXJgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuSGVhbHRoQ2hlY2tBbGFybUlkZW50aWZpZXJQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuSGVhbHRoQ2hlY2tfQWxhcm1JZGVudGlmaWVyUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIE5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubmFtZSksXG4gICAgICAgIFJlZ2lvbjogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5yZWdpb24pLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5IZWFsdGhDaGVja0FsYXJtSWRlbnRpZmllclByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuSGVhbHRoQ2hlY2suQWxhcm1JZGVudGlmaWVyUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuSGVhbHRoQ2hlY2suQWxhcm1JZGVudGlmaWVyUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCduYW1lJywgJ05hbWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLk5hbWUpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3JlZ2lvbicsICdSZWdpb24nLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlJlZ2lvbikpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmbkhlYWx0aENoZWNrIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBIZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGBDZm5IZWFsdGhDaGVjay5IZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5LkFsYXJtSWRlbnRpZmllcmBcbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctYWxhcm1pZGVudGlmaWVyXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBhbGFybUlkZW50aWZpZXI/OiBDZm5IZWFsdGhDaGVjay5BbGFybUlkZW50aWZpZXJQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGBDZm5IZWFsdGhDaGVjay5IZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5LkNoaWxkSGVhbHRoQ2hlY2tzYFxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWcuaHRtbCNjZm4tcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy1jaGlsZGhlYWx0aGNoZWNrc1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY2hpbGRIZWFsdGhDaGVja3M/OiBzdHJpbmdbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGBDZm5IZWFsdGhDaGVjay5IZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5LkVuYWJsZVNOSWBcbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctZW5hYmxlc25pXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBlbmFibGVTbmk/OiBib29sZWFuIHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogYENmbkhlYWx0aENoZWNrLkhlYWx0aENoZWNrQ29uZmlnUHJvcGVydHkuRmFpbHVyZVRocmVzaG9sZGBcbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctZmFpbHVyZXRocmVzaG9sZFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgZmFpbHVyZVRocmVzaG9sZD86IG51bWJlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGBDZm5IZWFsdGhDaGVjay5IZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5LkZ1bGx5UXVhbGlmaWVkRG9tYWluTmFtZWBcbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctZnVsbHlxdWFsaWZpZWRkb21haW5uYW1lXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBmdWxseVF1YWxpZmllZERvbWFpbk5hbWU/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBgQ2ZuSGVhbHRoQ2hlY2suSGVhbHRoQ2hlY2tDb25maWdQcm9wZXJ0eS5IZWFsdGhUaHJlc2hvbGRgXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLWhlYWx0aHRocmVzaG9sZFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgaGVhbHRoVGhyZXNob2xkPzogbnVtYmVyO1xuICAgICAgICAvKipcbiAgICAgICAgICogYENmbkhlYWx0aENoZWNrLkhlYWx0aENoZWNrQ29uZmlnUHJvcGVydHkuSVBBZGRyZXNzYFxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWcuaHRtbCNjZm4tcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy1pcGFkZHJlc3NcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGlwQWRkcmVzcz86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGBDZm5IZWFsdGhDaGVjay5IZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5Lkluc3VmZmljaWVudERhdGFIZWFsdGhTdGF0dXNgXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLWluc3VmZmljaWVudGRhdGFoZWFsdGhzdGF0dXNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGluc3VmZmljaWVudERhdGFIZWFsdGhTdGF0dXM/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBgQ2ZuSGVhbHRoQ2hlY2suSGVhbHRoQ2hlY2tDb25maWdQcm9wZXJ0eS5JbnZlcnRlZGBcbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctaW52ZXJ0ZWRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGludmVydGVkPzogYm9vbGVhbiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGBDZm5IZWFsdGhDaGVjay5IZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5Lk1lYXN1cmVMYXRlbmN5YFxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWcuaHRtbCNjZm4tcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy1tZWFzdXJlbGF0ZW5jeVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbWVhc3VyZUxhdGVuY3k/OiBib29sZWFuIHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogYENmbkhlYWx0aENoZWNrLkhlYWx0aENoZWNrQ29uZmlnUHJvcGVydHkuUG9ydGBcbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctcG9ydFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcG9ydD86IG51bWJlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGBDZm5IZWFsdGhDaGVjay5IZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5LlJlZ2lvbnNgXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLXJlZ2lvbnNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHJlZ2lvbnM/OiBzdHJpbmdbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGBDZm5IZWFsdGhDaGVjay5IZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5LlJlcXVlc3RJbnRlcnZhbGBcbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctcmVxdWVzdGludGVydmFsXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSByZXF1ZXN0SW50ZXJ2YWw/OiBudW1iZXI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBgQ2ZuSGVhbHRoQ2hlY2suSGVhbHRoQ2hlY2tDb25maWdQcm9wZXJ0eS5SZXNvdXJjZVBhdGhgXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLXJlc291cmNlcGF0aFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcmVzb3VyY2VQYXRoPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogYENmbkhlYWx0aENoZWNrLkhlYWx0aENoZWNrQ29uZmlnUHJvcGVydHkuUm91dGluZ0NvbnRyb2xBcm5gXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLXJvdXRpbmdjb250cm9sYXJuXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSByb3V0aW5nQ29udHJvbEFybj86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGBDZm5IZWFsdGhDaGVjay5IZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5LlNlYXJjaFN0cmluZ2BcbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctc2VhcmNoc3RyaW5nXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBzZWFyY2hTdHJpbmc/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBgQ2ZuSGVhbHRoQ2hlY2suSGVhbHRoQ2hlY2tDb25maWdQcm9wZXJ0eS5UeXBlYFxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWcuaHRtbCNjZm4tcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy10eXBlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB0eXBlOiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYEhlYWx0aENoZWNrQ29uZmlnUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEhlYWx0aENoZWNrQ29uZmlnUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuSGVhbHRoQ2hlY2tfSGVhbHRoQ2hlY2tDb25maWdQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2FsYXJtSWRlbnRpZmllcicsIENmbkhlYWx0aENoZWNrX0FsYXJtSWRlbnRpZmllclByb3BlcnR5VmFsaWRhdG9yKShwcm9wZXJ0aWVzLmFsYXJtSWRlbnRpZmllcikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY2hpbGRIZWFsdGhDaGVja3MnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLmNoaWxkSGVhbHRoQ2hlY2tzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdlbmFibGVTbmknLCBjZGsudmFsaWRhdGVCb29sZWFuKShwcm9wZXJ0aWVzLmVuYWJsZVNuaSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZmFpbHVyZVRocmVzaG9sZCcsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5mYWlsdXJlVGhyZXNob2xkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdmdWxseVF1YWxpZmllZERvbWFpbk5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuZnVsbHlRdWFsaWZpZWREb21haW5OYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdoZWFsdGhUaHJlc2hvbGQnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMuaGVhbHRoVGhyZXNob2xkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdpcEFkZHJlc3MnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuaXBBZGRyZXNzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdpbnN1ZmZpY2llbnREYXRhSGVhbHRoU3RhdHVzJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmluc3VmZmljaWVudERhdGFIZWFsdGhTdGF0dXMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2ludmVydGVkJywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5pbnZlcnRlZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbWVhc3VyZUxhdGVuY3knLCBjZGsudmFsaWRhdGVCb29sZWFuKShwcm9wZXJ0aWVzLm1lYXN1cmVMYXRlbmN5KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwb3J0JywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLnBvcnQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3JlZ2lvbnMnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLnJlZ2lvbnMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3JlcXVlc3RJbnRlcnZhbCcsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5yZXF1ZXN0SW50ZXJ2YWwpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3Jlc291cmNlUGF0aCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5yZXNvdXJjZVBhdGgpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3JvdXRpbmdDb250cm9sQXJuJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnJvdXRpbmdDb250cm9sQXJuKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzZWFyY2hTdHJpbmcnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuc2VhcmNoU3RyaW5nKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0eXBlJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnR5cGUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3R5cGUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMudHlwZSkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJIZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpIZWFsdGhDaGVjay5IZWFsdGhDaGVja0NvbmZpZ2AgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgSGVhbHRoQ2hlY2tDb25maWdQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6SGVhbHRoQ2hlY2suSGVhbHRoQ2hlY2tDb25maWdgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuSGVhbHRoQ2hlY2tIZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5IZWFsdGhDaGVja19IZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBBbGFybUlkZW50aWZpZXI6IGNmbkhlYWx0aENoZWNrQWxhcm1JZGVudGlmaWVyUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuYWxhcm1JZGVudGlmaWVyKSxcbiAgICAgICAgQ2hpbGRIZWFsdGhDaGVja3M6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLmNoaWxkSGVhbHRoQ2hlY2tzKSxcbiAgICAgICAgRW5hYmxlU05JOiBjZGsuYm9vbGVhblRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5lbmFibGVTbmkpLFxuICAgICAgICBGYWlsdXJlVGhyZXNob2xkOiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmZhaWx1cmVUaHJlc2hvbGQpLFxuICAgICAgICBGdWxseVF1YWxpZmllZERvbWFpbk5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZnVsbHlRdWFsaWZpZWREb21haW5OYW1lKSxcbiAgICAgICAgSGVhbHRoVGhyZXNob2xkOiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmhlYWx0aFRocmVzaG9sZCksXG4gICAgICAgIElQQWRkcmVzczogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5pcEFkZHJlc3MpLFxuICAgICAgICBJbnN1ZmZpY2llbnREYXRhSGVhbHRoU3RhdHVzOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmluc3VmZmljaWVudERhdGFIZWFsdGhTdGF0dXMpLFxuICAgICAgICBJbnZlcnRlZDogY2RrLmJvb2xlYW5Ub0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaW52ZXJ0ZWQpLFxuICAgICAgICBNZWFzdXJlTGF0ZW5jeTogY2RrLmJvb2xlYW5Ub0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubWVhc3VyZUxhdGVuY3kpLFxuICAgICAgICBQb3J0OiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBvcnQpLFxuICAgICAgICBSZWdpb25zOiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5yZWdpb25zKSxcbiAgICAgICAgUmVxdWVzdEludGVydmFsOiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnJlcXVlc3RJbnRlcnZhbCksXG4gICAgICAgIFJlc291cmNlUGF0aDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5yZXNvdXJjZVBhdGgpLFxuICAgICAgICBSb3V0aW5nQ29udHJvbEFybjogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5yb3V0aW5nQ29udHJvbEFybiksXG4gICAgICAgIFNlYXJjaFN0cmluZzogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zZWFyY2hTdHJpbmcpLFxuICAgICAgICBUeXBlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnR5cGUpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5IZWFsdGhDaGVja0hlYWx0aENoZWNrQ29uZmlnUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5IZWFsdGhDaGVjay5IZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbkhlYWx0aENoZWNrLkhlYWx0aENoZWNrQ29uZmlnUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdhbGFybUlkZW50aWZpZXInLCAnQWxhcm1JZGVudGlmaWVyJywgcHJvcGVydGllcy5BbGFybUlkZW50aWZpZXIgIT0gbnVsbCA/IENmbkhlYWx0aENoZWNrQWxhcm1JZGVudGlmaWVyUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5BbGFybUlkZW50aWZpZXIpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2NoaWxkSGVhbHRoQ2hlY2tzJywgJ0NoaWxkSGVhbHRoQ2hlY2tzJywgcHJvcGVydGllcy5DaGlsZEhlYWx0aENoZWNrcyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmdBcnJheShwcm9wZXJ0aWVzLkNoaWxkSGVhbHRoQ2hlY2tzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdlbmFibGVTbmknLCAnRW5hYmxlU05JJywgcHJvcGVydGllcy5FbmFibGVTTkkgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Qm9vbGVhbihwcm9wZXJ0aWVzLkVuYWJsZVNOSSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZmFpbHVyZVRocmVzaG9sZCcsICdGYWlsdXJlVGhyZXNob2xkJywgcHJvcGVydGllcy5GYWlsdXJlVGhyZXNob2xkICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLkZhaWx1cmVUaHJlc2hvbGQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2Z1bGx5UXVhbGlmaWVkRG9tYWluTmFtZScsICdGdWxseVF1YWxpZmllZERvbWFpbk5hbWUnLCBwcm9wZXJ0aWVzLkZ1bGx5UXVhbGlmaWVkRG9tYWluTmFtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5GdWxseVF1YWxpZmllZERvbWFpbk5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2hlYWx0aFRocmVzaG9sZCcsICdIZWFsdGhUaHJlc2hvbGQnLCBwcm9wZXJ0aWVzLkhlYWx0aFRocmVzaG9sZCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5IZWFsdGhUaHJlc2hvbGQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2lwQWRkcmVzcycsICdJUEFkZHJlc3MnLCBwcm9wZXJ0aWVzLklQQWRkcmVzcyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5JUEFkZHJlc3MpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2luc3VmZmljaWVudERhdGFIZWFsdGhTdGF0dXMnLCAnSW5zdWZmaWNpZW50RGF0YUhlYWx0aFN0YXR1cycsIHByb3BlcnRpZXMuSW5zdWZmaWNpZW50RGF0YUhlYWx0aFN0YXR1cyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5JbnN1ZmZpY2llbnREYXRhSGVhbHRoU3RhdHVzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdpbnZlcnRlZCcsICdJbnZlcnRlZCcsIHByb3BlcnRpZXMuSW52ZXJ0ZWQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Qm9vbGVhbihwcm9wZXJ0aWVzLkludmVydGVkKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdtZWFzdXJlTGF0ZW5jeScsICdNZWFzdXJlTGF0ZW5jeScsIHByb3BlcnRpZXMuTWVhc3VyZUxhdGVuY3kgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Qm9vbGVhbihwcm9wZXJ0aWVzLk1lYXN1cmVMYXRlbmN5KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwb3J0JywgJ1BvcnQnLCBwcm9wZXJ0aWVzLlBvcnQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuUG9ydCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncmVnaW9ucycsICdSZWdpb25zJywgcHJvcGVydGllcy5SZWdpb25zICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuUmVnaW9ucykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncmVxdWVzdEludGVydmFsJywgJ1JlcXVlc3RJbnRlcnZhbCcsIHByb3BlcnRpZXMuUmVxdWVzdEludGVydmFsICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLlJlcXVlc3RJbnRlcnZhbCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncmVzb3VyY2VQYXRoJywgJ1Jlc291cmNlUGF0aCcsIHByb3BlcnRpZXMuUmVzb3VyY2VQYXRoICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlJlc291cmNlUGF0aCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncm91dGluZ0NvbnRyb2xBcm4nLCAnUm91dGluZ0NvbnRyb2xBcm4nLCBwcm9wZXJ0aWVzLlJvdXRpbmdDb250cm9sQXJuICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlJvdXRpbmdDb250cm9sQXJuKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzZWFyY2hTdHJpbmcnLCAnU2VhcmNoU3RyaW5nJywgcHJvcGVydGllcy5TZWFyY2hTdHJpbmcgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuU2VhcmNoU3RyaW5nKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0eXBlJywgJ1R5cGUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlR5cGUpKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5IZWFsdGhDaGVjayB7XG4gICAgLyoqXG4gICAgICogVGhlIGBIZWFsdGhDaGVja1RhZ2AgcHJvcGVydHkgZGVzY3JpYmVzIG9uZSBrZXktdmFsdWUgcGFpciB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCBhbiBgQVdTOjpSb3V0ZTUzOjpIZWFsdGhDaGVja2AgcmVzb3VyY2UuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrdGFnLmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIEhlYWx0aENoZWNrVGFnUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHZhbHVlIG9mIGBLZXlgIGRlcGVuZHMgb24gdGhlIG9wZXJhdGlvbiB0aGF0IHlvdSB3YW50IHRvIHBlcmZvcm06XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKkFkZCBhIHRhZyB0byBhIGhlYWx0aCBjaGVjayBvciBob3N0ZWQgem9uZSogOiBgS2V5YCBpcyB0aGUgbmFtZSB0aGF0IHlvdSB3YW50IHRvIGdpdmUgdGhlIG5ldyB0YWcuXG4gICAgICAgICAqIC0gKkVkaXQgYSB0YWcqIDogYEtleWAgaXMgdGhlIG5hbWUgb2YgdGhlIHRhZyB0aGF0IHlvdSB3YW50IHRvIGNoYW5nZSB0aGUgYFZhbHVlYCBmb3IuXG4gICAgICAgICAqIC0gKkRlbGV0ZSBhIGtleSogOiBgS2V5YCBpcyB0aGUgbmFtZSBvZiB0aGUgdGFnIHlvdSB3YW50IHRvIHJlbW92ZS5cbiAgICAgICAgICogLSAqR2l2ZSBhIG5hbWUgdG8gYSBoZWFsdGggY2hlY2sqIDogRWRpdCB0aGUgZGVmYXVsdCBgTmFtZWAgdGFnLiBJbiB0aGUgQW1hem9uIFJvdXRlIDUzIGNvbnNvbGUsIHRoZSBsaXN0IG9mIHlvdXIgaGVhbHRoIGNoZWNrcyBpbmNsdWRlcyBhICpOYW1lKiBjb2x1bW4gdGhhdCBsZXRzIHlvdSBzZWUgdGhlIG5hbWUgdGhhdCB5b3UndmUgZ2l2ZW4gdG8gZWFjaCBoZWFsdGggY2hlY2suXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja3RhZy5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrdGFnLWtleVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkga2V5OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdmFsdWUgb2YgYFZhbHVlYCBkZXBlbmRzIG9uIHRoZSBvcGVyYXRpb24gdGhhdCB5b3Ugd2FudCB0byBwZXJmb3JtOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICpBZGQgYSB0YWcgdG8gYSBoZWFsdGggY2hlY2sgb3IgaG9zdGVkIHpvbmUqIDogYFZhbHVlYCBpcyB0aGUgdmFsdWUgdGhhdCB5b3Ugd2FudCB0byBnaXZlIHRoZSBuZXcgdGFnLlxuICAgICAgICAgKiAtICpFZGl0IGEgdGFnKiA6IGBWYWx1ZWAgaXMgdGhlIG5ldyB2YWx1ZSB0aGF0IHlvdSB3YW50IHRvIGFzc2lnbiB0aGUgdGFnLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2t0YWcuaHRtbCNjZm4tcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja3RhZy12YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgdmFsdWU6IHN0cmluZztcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgSGVhbHRoQ2hlY2tUYWdQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgSGVhbHRoQ2hlY2tUYWdQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5IZWFsdGhDaGVja19IZWFsdGhDaGVja1RhZ1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigna2V5JywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmtleSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigna2V5JywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmtleSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndmFsdWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMudmFsdWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3ZhbHVlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnZhbHVlKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkhlYWx0aENoZWNrVGFnUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OkhlYWx0aENoZWNrLkhlYWx0aENoZWNrVGFnYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBIZWFsdGhDaGVja1RhZ1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpIZWFsdGhDaGVjay5IZWFsdGhDaGVja1RhZ2AgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5IZWFsdGhDaGVja0hlYWx0aENoZWNrVGFnUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbkhlYWx0aENoZWNrX0hlYWx0aENoZWNrVGFnUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEtleTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5rZXkpLFxuICAgICAgICBWYWx1ZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy52YWx1ZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkhlYWx0aENoZWNrSGVhbHRoQ2hlY2tUYWdQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbkhlYWx0aENoZWNrLkhlYWx0aENoZWNrVGFnUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuSGVhbHRoQ2hlY2suSGVhbHRoQ2hlY2tUYWdQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2tleScsICdLZXknLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLktleSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndmFsdWUnLCAnVmFsdWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlZhbHVlKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuSG9zdGVkWm9uZWBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1ob3N0ZWR6b25lLmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5Ib3N0ZWRab25lUHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogQSBjb21wbGV4IHR5cGUgdGhhdCBjb250YWlucyBhbiBvcHRpb25hbCBjb21tZW50LlxuICAgICAqXG4gICAgICogSWYgeW91IGRvbid0IHdhbnQgdG8gc3BlY2lmeSBhIGNvbW1lbnQsIG9taXQgdGhlIGBIb3N0ZWRab25lQ29uZmlnYCBhbmQgYENvbW1lbnRgIGVsZW1lbnRzLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1ob3N0ZWR6b25lLmh0bWwjY2ZuLXJvdXRlNTMtaG9zdGVkem9uZS1ob3N0ZWR6b25lY29uZmlnXG4gICAgICovXG4gICAgcmVhZG9ubHkgaG9zdGVkWm9uZUNvbmZpZz86IENmbkhvc3RlZFpvbmUuSG9zdGVkWm9uZUNvbmZpZ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogQWRkcywgZWRpdHMsIG9yIGRlbGV0ZXMgdGFncyBmb3IgYSBoZWFsdGggY2hlY2sgb3IgYSBob3N0ZWQgem9uZS5cbiAgICAgKlxuICAgICAqIEZvciBpbmZvcm1hdGlvbiBhYm91dCB1c2luZyB0YWdzIGZvciBjb3N0IGFsbG9jYXRpb24sIHNlZSBbVXNpbmcgQ29zdCBBbGxvY2F0aW9uIFRhZ3NdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hd3NhY2NvdW50YmlsbGluZy9sYXRlc3QvYWJvdXR2Mi9jb3N0LWFsbG9jLXRhZ3MuaHRtbCkgaW4gdGhlICpBV1MgQmlsbGluZyBhbmQgQ29zdCBNYW5hZ2VtZW50IFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtaG9zdGVkem9uZS5odG1sI2Nmbi1yb3V0ZTUzLWhvc3RlZHpvbmUtaG9zdGVkem9uZXRhZ3NcbiAgICAgKi9cbiAgICByZWFkb25seSBob3N0ZWRab25lVGFncz86IENmbkhvc3RlZFpvbmUuSG9zdGVkWm9uZVRhZ1Byb3BlcnR5W107XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgZG9tYWluLiBTcGVjaWZ5IGEgZnVsbHkgcXVhbGlmaWVkIGRvbWFpbiBuYW1lLCBmb3IgZXhhbXBsZSwgKnd3dy5leGFtcGxlLmNvbSogLiBUaGUgdHJhaWxpbmcgZG90IGlzIG9wdGlvbmFsOyBBbWF6b24gUm91dGUgNTMgYXNzdW1lcyB0aGF0IHRoZSBkb21haW4gbmFtZSBpcyBmdWxseSBxdWFsaWZpZWQuIFRoaXMgbWVhbnMgdGhhdCBSb3V0ZSA1MyB0cmVhdHMgKnd3dy5leGFtcGxlLmNvbSogKHdpdGhvdXQgYSB0cmFpbGluZyBkb3QpIGFuZCAqd3d3LmV4YW1wbGUuY29tLiogKHdpdGggYSB0cmFpbGluZyBkb3QpIGFzIGlkZW50aWNhbC5cbiAgICAgKlxuICAgICAqIElmIHlvdSdyZSBjcmVhdGluZyBhIHB1YmxpYyBob3N0ZWQgem9uZSwgdGhpcyBpcyB0aGUgbmFtZSB5b3UgaGF2ZSByZWdpc3RlcmVkIHdpdGggeW91ciBETlMgcmVnaXN0cmFyLiBJZiB5b3VyIGRvbWFpbiBuYW1lIGlzIHJlZ2lzdGVyZWQgd2l0aCBhIHJlZ2lzdHJhciBvdGhlciB0aGFuIFJvdXRlIDUzLCBjaGFuZ2UgdGhlIG5hbWUgc2VydmVycyBmb3IgeW91ciBkb21haW4gdG8gdGhlIHNldCBvZiBgTmFtZVNlcnZlcnNgIHRoYXQgYXJlIHJldHVybmVkIGJ5IHRoZSBgRm46OkdldEF0dGAgaW50cmluc2ljIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1ob3N0ZWR6b25lLmh0bWwjY2ZuLXJvdXRlNTMtaG9zdGVkem9uZS1uYW1lXG4gICAgICovXG4gICAgcmVhZG9ubHkgbmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjb25maWd1cmF0aW9uIGZvciBETlMgcXVlcnkgbG9nZ2luZy4gQWZ0ZXIgeW91IGNyZWF0ZSBhIHF1ZXJ5IGxvZ2dpbmcgY29uZmlndXJhdGlvbiwgQW1hem9uIFJvdXRlIDUzIGJlZ2lucyB0byBwdWJsaXNoIGxvZyBkYXRhIHRvIGFuIEFtYXpvbiBDbG91ZFdhdGNoIExvZ3MgbG9nIGdyb3VwLlxuICAgICAqXG4gICAgICogRE5TIHF1ZXJ5IGxvZ3MgY29udGFpbiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcXVlcmllcyB0aGF0IFJvdXRlIDUzIHJlY2VpdmVzIGZvciBhIHNwZWNpZmllZCBwdWJsaWMgaG9zdGVkIHpvbmUsIHN1Y2ggYXMgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gUm91dGUgNTMgZWRnZSBsb2NhdGlvbiB0aGF0IHJlc3BvbmRlZCB0byB0aGUgRE5TIHF1ZXJ5XG4gICAgICogLSBEb21haW4gb3Igc3ViZG9tYWluIHRoYXQgd2FzIHJlcXVlc3RlZFxuICAgICAqIC0gRE5TIHJlY29yZCB0eXBlLCBzdWNoIGFzIEEgb3IgQUFBQVxuICAgICAqIC0gRE5TIHJlc3BvbnNlIGNvZGUsIHN1Y2ggYXMgYE5vRXJyb3JgIG9yIGBTZXJ2RmFpbGBcbiAgICAgKlxuICAgICAqIC0gKipMb2cgR3JvdXAgYW5kIFJlc291cmNlIFBvbGljeSoqIC0gQmVmb3JlIHlvdSBjcmVhdGUgYSBxdWVyeSBsb2dnaW5nIGNvbmZpZ3VyYXRpb24sIHBlcmZvcm0gdGhlIGZvbGxvd2luZyBvcGVyYXRpb25zLlxuICAgICAqXG4gICAgICogPiBJZiB5b3UgY3JlYXRlIGEgcXVlcnkgbG9nZ2luZyBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBSb3V0ZSA1MyBjb25zb2xlLCBSb3V0ZSA1MyBwZXJmb3JtcyB0aGVzZSBvcGVyYXRpb25zIGF1dG9tYXRpY2FsbHkuXG4gICAgICpcbiAgICAgKiAtIENyZWF0ZSBhIENsb3VkV2F0Y2ggTG9ncyBsb2cgZ3JvdXAsIGFuZCBtYWtlIG5vdGUgb2YgdGhlIEFSTiwgd2hpY2ggeW91IHNwZWNpZnkgd2hlbiB5b3UgY3JlYXRlIGEgcXVlcnkgbG9nZ2luZyBjb25maWd1cmF0aW9uLiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIFlvdSBtdXN0IGNyZWF0ZSB0aGUgbG9nIGdyb3VwIGluIHRoZSB1cy1lYXN0LTEgcmVnaW9uLlxuICAgICAqIC0gWW91IG11c3QgdXNlIHRoZSBzYW1lIEFXUyBhY2NvdW50IHRvIGNyZWF0ZSB0aGUgbG9nIGdyb3VwIGFuZCB0aGUgaG9zdGVkIHpvbmUgdGhhdCB5b3Ugd2FudCB0byBjb25maWd1cmUgcXVlcnkgbG9nZ2luZyBmb3IuXG4gICAgICogLSBXaGVuIHlvdSBjcmVhdGUgbG9nIGdyb3VwcyBmb3IgcXVlcnkgbG9nZ2luZywgd2UgcmVjb21tZW5kIHRoYXQgeW91IHVzZSBhIGNvbnNpc3RlbnQgcHJlZml4LCBmb3IgZXhhbXBsZTpcbiAgICAgKlxuICAgICAqIGAvYXdzL3JvdXRlNTMvICpob3N0ZWQgem9uZSBuYW1lKmBcbiAgICAgKlxuICAgICAqIEluIHRoZSBuZXh0IHN0ZXAsIHlvdSdsbCBjcmVhdGUgYSByZXNvdXJjZSBwb2xpY3ksIHdoaWNoIGNvbnRyb2xzIGFjY2VzcyB0byBvbmUgb3IgbW9yZSBsb2cgZ3JvdXBzIGFuZCB0aGUgYXNzb2NpYXRlZCBBV1MgcmVzb3VyY2VzLCBzdWNoIGFzIFJvdXRlIDUzIGhvc3RlZCB6b25lcy4gVGhlcmUncyBhIGxpbWl0IG9uIHRoZSBudW1iZXIgb2YgcmVzb3VyY2UgcG9saWNpZXMgdGhhdCB5b3UgY2FuIGNyZWF0ZSwgc28gd2UgcmVjb21tZW5kIHRoYXQgeW91IHVzZSBhIGNvbnNpc3RlbnQgcHJlZml4IHNvIHlvdSBjYW4gdXNlIHRoZSBzYW1lIHJlc291cmNlIHBvbGljeSBmb3IgYWxsIHRoZSBsb2cgZ3JvdXBzIHRoYXQgeW91IGNyZWF0ZSBmb3IgcXVlcnkgbG9nZ2luZy5cbiAgICAgKiAtIENyZWF0ZSBhIENsb3VkV2F0Y2ggTG9ncyByZXNvdXJjZSBwb2xpY3ksIGFuZCBnaXZlIGl0IHRoZSBwZXJtaXNzaW9ucyB0aGF0IFJvdXRlIDUzIG5lZWRzIHRvIGNyZWF0ZSBsb2cgc3RyZWFtcyBhbmQgdG8gc2VuZCBxdWVyeSBsb2dzIHRvIGxvZyBzdHJlYW1zLiBGb3IgdGhlIHZhbHVlIG9mIGBSZXNvdXJjZWAgLCBzcGVjaWZ5IHRoZSBBUk4gZm9yIHRoZSBsb2cgZ3JvdXAgdGhhdCB5b3UgY3JlYXRlZCBpbiB0aGUgcHJldmlvdXMgc3RlcC4gVG8gdXNlIHRoZSBzYW1lIHJlc291cmNlIHBvbGljeSBmb3IgYWxsIHRoZSBDbG91ZFdhdGNoIExvZ3MgbG9nIGdyb3VwcyB0aGF0IHlvdSBjcmVhdGVkIGZvciBxdWVyeSBsb2dnaW5nIGNvbmZpZ3VyYXRpb25zLCByZXBsYWNlIHRoZSBob3N0ZWQgem9uZSBuYW1lIHdpdGggYCpgICwgZm9yIGV4YW1wbGU6XG4gICAgICpcbiAgICAgKiBgYXJuOmF3czpsb2dzOnVzLWVhc3QtMToxMjM0MTIzNDEyMzQ6bG9nLWdyb3VwOi9hd3Mvcm91dGU1My8qYFxuICAgICAqXG4gICAgICogVG8gYXZvaWQgdGhlIGNvbmZ1c2VkIGRlcHV0eSBwcm9ibGVtLCBhIHNlY3VyaXR5IGlzc3VlIHdoZXJlIGFuIGVudGl0eSB3aXRob3V0IGEgcGVybWlzc2lvbiBmb3IgYW4gYWN0aW9uIGNhbiBjb2VyY2UgYSBtb3JlLXByaXZpbGVnZWQgZW50aXR5IHRvIHBlcmZvcm0gaXQsIHlvdSBjYW4gb3B0aW9uYWxseSBsaW1pdCB0aGUgcGVybWlzc2lvbnMgdGhhdCBhIHNlcnZpY2UgaGFzIHRvIGEgcmVzb3VyY2UgaW4gYSByZXNvdXJjZS1iYXNlZCBwb2xpY3kgYnkgc3VwcGx5aW5nIHRoZSBmb2xsb3dpbmcgdmFsdWVzOlxuICAgICAqXG4gICAgICogLSBGb3IgYGF3czpTb3VyY2VBcm5gICwgc3VwcGx5IHRoZSBob3N0ZWQgem9uZSBBUk4gdXNlZCBpbiBjcmVhdGluZyB0aGUgcXVlcnkgbG9nZ2luZyBjb25maWd1cmF0aW9uLiBGb3IgZXhhbXBsZSwgYGF3czpTb3VyY2VBcm46IGFybjphd3M6cm91dGU1Mzo6Omhvc3RlZHpvbmUvaG9zdGVkIHpvbmUgSURgIC5cbiAgICAgKiAtIEZvciBgYXdzOlNvdXJjZUFjY291bnRgICwgc3VwcGx5IHRoZSBhY2NvdW50IElEIGZvciB0aGUgYWNjb3VudCB0aGF0IGNyZWF0ZXMgdGhlIHF1ZXJ5IGxvZ2dpbmcgY29uZmlndXJhdGlvbi4gRm9yIGV4YW1wbGUsIGBhd3M6U291cmNlQWNjb3VudDoxMTExMTExMTExMTFgIC5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1RoZSBjb25mdXNlZCBkZXB1dHkgcHJvYmxlbV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2NvbmZ1c2VkLWRlcHV0eS5odG1sKSBpbiB0aGUgKkFXUyBJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogPiBZb3UgY2FuJ3QgdXNlIHRoZSBDbG91ZFdhdGNoIGNvbnNvbGUgdG8gY3JlYXRlIG9yIGVkaXQgYSByZXNvdXJjZSBwb2xpY3kuIFlvdSBtdXN0IHVzZSB0aGUgQ2xvdWRXYXRjaCBBUEksIG9uZSBvZiB0aGUgQVdTIFNES3MsIG9yIHRoZSBBV1MgQ0xJIC5cbiAgICAgKiAtICoqTG9nIFN0cmVhbXMgYW5kIEVkZ2UgTG9jYXRpb25zKiogLSBXaGVuIFJvdXRlIDUzIGZpbmlzaGVzIGNyZWF0aW5nIHRoZSBjb25maWd1cmF0aW9uIGZvciBETlMgcXVlcnkgbG9nZ2luZywgaXQgZG9lcyB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBDcmVhdGVzIGEgbG9nIHN0cmVhbSBmb3IgYW4gZWRnZSBsb2NhdGlvbiB0aGUgZmlyc3QgdGltZSB0aGF0IHRoZSBlZGdlIGxvY2F0aW9uIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIGZvciB0aGUgc3BlY2lmaWVkIGhvc3RlZCB6b25lLiBUaGF0IGxvZyBzdHJlYW0gaXMgdXNlZCB0byBsb2cgYWxsIHF1ZXJpZXMgdGhhdCBSb3V0ZSA1MyByZXNwb25kcyB0byBmb3IgdGhhdCBlZGdlIGxvY2F0aW9uLlxuICAgICAqIC0gQmVnaW5zIHRvIHNlbmQgcXVlcnkgbG9ncyB0byB0aGUgYXBwbGljYWJsZSBsb2cgc3RyZWFtLlxuICAgICAqXG4gICAgICogVGhlIG5hbWUgb2YgZWFjaCBsb2cgc3RyZWFtIGlzIGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OlxuICAgICAqXG4gICAgICogYCpob3N0ZWQgem9uZSBJRCogLyAqZWRnZSBsb2NhdGlvbiBjb2RlKmBcbiAgICAgKlxuICAgICAqIFRoZSBlZGdlIGxvY2F0aW9uIGNvZGUgaXMgYSB0aHJlZS1sZXR0ZXIgY29kZSBhbmQgYW4gYXJiaXRyYXJpbHkgYXNzaWduZWQgbnVtYmVyLCBmb3IgZXhhbXBsZSwgREZXMy4gVGhlIHRocmVlLWxldHRlciBjb2RlIHR5cGljYWxseSBjb3JyZXNwb25kcyB3aXRoIHRoZSBJbnRlcm5hdGlvbmFsIEFpciBUcmFuc3BvcnQgQXNzb2NpYXRpb24gYWlycG9ydCBjb2RlIGZvciBhbiBhaXJwb3J0IG5lYXIgdGhlIGVkZ2UgbG9jYXRpb24uIChUaGVzZSBhYmJyZXZpYXRpb25zIG1pZ2h0IGNoYW5nZSBpbiB0aGUgZnV0dXJlLikgRm9yIGEgbGlzdCBvZiBlZGdlIGxvY2F0aW9ucywgc2VlIFwiVGhlIFJvdXRlIDUzIEdsb2JhbCBOZXR3b3JrXCIgb24gdGhlIFtSb3V0ZSA1MyBQcm9kdWN0IERldGFpbHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yb3V0ZTUzL2RldGFpbHMvKSBwYWdlLlxuICAgICAqIC0gKipRdWVyaWVzIFRoYXQgQXJlIExvZ2dlZCoqIC0gUXVlcnkgbG9ncyBjb250YWluIG9ubHkgdGhlIHF1ZXJpZXMgdGhhdCBETlMgcmVzb2x2ZXJzIGZvcndhcmQgdG8gUm91dGUgNTMuIElmIGEgRE5TIHJlc29sdmVyIGhhcyBhbHJlYWR5IGNhY2hlZCB0aGUgcmVzcG9uc2UgdG8gYSBxdWVyeSAoc3VjaCBhcyB0aGUgSVAgYWRkcmVzcyBmb3IgYSBsb2FkIGJhbGFuY2VyIGZvciBleGFtcGxlLmNvbSksIHRoZSByZXNvbHZlciB3aWxsIGNvbnRpbnVlIHRvIHJldHVybiB0aGUgY2FjaGVkIHJlc3BvbnNlLiBJdCBkb2Vzbid0IGZvcndhcmQgYW5vdGhlciBxdWVyeSB0byBSb3V0ZSA1MyB1bnRpbCB0aGUgVFRMIGZvciB0aGUgY29ycmVzcG9uZGluZyByZXNvdXJjZSByZWNvcmQgc2V0IGV4cGlyZXMuIERlcGVuZGluZyBvbiBob3cgbWFueSBETlMgcXVlcmllcyBhcmUgc3VibWl0dGVkIGZvciBhIHJlc291cmNlIHJlY29yZCBzZXQsIGFuZCBkZXBlbmRpbmcgb24gdGhlIFRUTCBmb3IgdGhhdCByZXNvdXJjZSByZWNvcmQgc2V0LCBxdWVyeSBsb2dzIG1pZ2h0IGNvbnRhaW4gaW5mb3JtYXRpb24gYWJvdXQgb25seSBvbmUgcXVlcnkgb3V0IG9mIGV2ZXJ5IHNldmVyYWwgdGhvdXNhbmQgcXVlcmllcyB0aGF0IGFyZSBzdWJtaXR0ZWQgdG8gRE5TLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBob3cgRE5TIHdvcmtzLCBzZWUgW1JvdXRpbmcgSW50ZXJuZXQgVHJhZmZpYyB0byBZb3VyIFdlYnNpdGUgb3IgV2ViIEFwcGxpY2F0aW9uXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvd2VsY29tZS1kbnMtc2VydmljZS5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKiAtICoqTG9nIEZpbGUgRm9ybWF0KiogLSBGb3IgYSBsaXN0IG9mIHRoZSB2YWx1ZXMgaW4gZWFjaCBxdWVyeSBsb2cgYW5kIHRoZSBmb3JtYXQgb2YgZWFjaCB2YWx1ZSwgc2VlIFtMb2dnaW5nIEROUyBRdWVyaWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvcXVlcnktbG9ncy5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKiAtICoqUHJpY2luZyoqIC0gRm9yIGluZm9ybWF0aW9uIGFib3V0IGNoYXJnZXMgZm9yIHF1ZXJ5IGxvZ3MsIHNlZSBbQW1hem9uIENsb3VkV2F0Y2ggUHJpY2luZ10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nsb3Vkd2F0Y2gvcHJpY2luZy8pIC5cbiAgICAgKiAtICoqSG93IHRvIFN0b3AgTG9nZ2luZyoqIC0gSWYgeW91IHdhbnQgUm91dGUgNTMgdG8gc3RvcCBzZW5kaW5nIHF1ZXJ5IGxvZ3MgdG8gQ2xvdWRXYXRjaCBMb2dzLCBkZWxldGUgdGhlIHF1ZXJ5IGxvZ2dpbmcgY29uZmlndXJhdGlvbi4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbRGVsZXRlUXVlcnlMb2dnaW5nQ29uZmlnXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVRdWVyeUxvZ2dpbmdDb25maWcuaHRtbCkgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1ob3N0ZWR6b25lLmh0bWwjY2ZuLXJvdXRlNTMtaG9zdGVkem9uZS1xdWVyeWxvZ2dpbmdjb25maWdcbiAgICAgKi9cbiAgICByZWFkb25seSBxdWVyeUxvZ2dpbmdDb25maWc/OiBDZm5Ib3N0ZWRab25lLlF1ZXJ5TG9nZ2luZ0NvbmZpZ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogKlByaXZhdGUgaG9zdGVkIHpvbmVzOiogQSBjb21wbGV4IHR5cGUgdGhhdCBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgVlBDcyB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBob3N0ZWQgem9uZS5cbiAgICAgKlxuICAgICAqID4gRm9yIHB1YmxpYyBob3N0ZWQgem9uZXMsIG9taXQgYFZQQ3NgICwgYFZQQ0lkYCAsIGFuZCBgVlBDUmVnaW9uYCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWhvc3RlZHpvbmUuaHRtbCNjZm4tcm91dGU1My1ob3N0ZWR6b25lLXZwY3NcbiAgICAgKi9cbiAgICByZWFkb25seSB2cGNzPzogQXJyYXk8Q2ZuSG9zdGVkWm9uZS5WUENQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGU7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgQ2ZuSG9zdGVkWm9uZVByb3BzYFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5Ib3N0ZWRab25lUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuSG9zdGVkWm9uZVByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaG9zdGVkWm9uZUNvbmZpZycsIENmbkhvc3RlZFpvbmVfSG9zdGVkWm9uZUNvbmZpZ1Byb3BlcnR5VmFsaWRhdG9yKShwcm9wZXJ0aWVzLmhvc3RlZFpvbmVDb25maWcpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hvc3RlZFpvbmVUYWdzJywgY2RrLmxpc3RWYWxpZGF0b3IoQ2ZuSG9zdGVkWm9uZV9Ib3N0ZWRab25lVGFnUHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLmhvc3RlZFpvbmVUYWdzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCduYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLm5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3F1ZXJ5TG9nZ2luZ0NvbmZpZycsIENmbkhvc3RlZFpvbmVfUXVlcnlMb2dnaW5nQ29uZmlnUHJvcGVydHlWYWxpZGF0b3IpKHByb3BlcnRpZXMucXVlcnlMb2dnaW5nQ29uZmlnKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd2cGNzJywgY2RrLmxpc3RWYWxpZGF0b3IoQ2ZuSG9zdGVkWm9uZV9WUENQcm9wZXJ0eVZhbGlkYXRvcikpKHByb3BlcnRpZXMudnBjcykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5Ib3N0ZWRab25lUHJvcHNcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6Okhvc3RlZFpvbmVgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbkhvc3RlZFpvbmVQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6SG9zdGVkWm9uZWAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5Ib3N0ZWRab25lUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbkhvc3RlZFpvbmVQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgSG9zdGVkWm9uZUNvbmZpZzogY2ZuSG9zdGVkWm9uZUhvc3RlZFpvbmVDb25maWdQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5ob3N0ZWRab25lQ29uZmlnKSxcbiAgICAgICAgSG9zdGVkWm9uZVRhZ3M6IGNkay5saXN0TWFwcGVyKGNmbkhvc3RlZFpvbmVIb3N0ZWRab25lVGFnUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLmhvc3RlZFpvbmVUYWdzKSxcbiAgICAgICAgTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5uYW1lKSxcbiAgICAgICAgUXVlcnlMb2dnaW5nQ29uZmlnOiBjZm5Ib3N0ZWRab25lUXVlcnlMb2dnaW5nQ29uZmlnUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucXVlcnlMb2dnaW5nQ29uZmlnKSxcbiAgICAgICAgVlBDczogY2RrLmxpc3RNYXBwZXIoY2ZuSG9zdGVkWm9uZVZQQ1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy52cGNzKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuSG9zdGVkWm9uZVByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuSG9zdGVkWm9uZVByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5Ib3N0ZWRab25lUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdob3N0ZWRab25lQ29uZmlnJywgJ0hvc3RlZFpvbmVDb25maWcnLCBwcm9wZXJ0aWVzLkhvc3RlZFpvbmVDb25maWcgIT0gbnVsbCA/IENmbkhvc3RlZFpvbmVIb3N0ZWRab25lQ29uZmlnUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5Ib3N0ZWRab25lQ29uZmlnKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdob3N0ZWRab25lVGFncycsICdIb3N0ZWRab25lVGFncycsIHByb3BlcnRpZXMuSG9zdGVkWm9uZVRhZ3MgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoQ2ZuSG9zdGVkWm9uZUhvc3RlZFpvbmVUYWdQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5Ib3N0ZWRab25lVGFncykgOiB1bmRlZmluZWQgYXMgYW55KTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ25hbWUnLCAnTmFtZScsIHByb3BlcnRpZXMuTmFtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5OYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdxdWVyeUxvZ2dpbmdDb25maWcnLCAnUXVlcnlMb2dnaW5nQ29uZmlnJywgcHJvcGVydGllcy5RdWVyeUxvZ2dpbmdDb25maWcgIT0gbnVsbCA/IENmbkhvc3RlZFpvbmVRdWVyeUxvZ2dpbmdDb25maWdQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLlF1ZXJ5TG9nZ2luZ0NvbmZpZykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndnBjcycsICdWUENzJywgcHJvcGVydGllcy5WUENzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KENmbkhvc3RlZFpvbmVWUENQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5WUENzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpSb3V0ZTUzOjpIb3N0ZWRab25lYFxuICpcbiAqIENyZWF0ZXMgYSBuZXcgcHVibGljIG9yIHByaXZhdGUgaG9zdGVkIHpvbmUuIFlvdSBjcmVhdGUgcmVjb3JkcyBpbiBhIHB1YmxpYyBob3N0ZWQgem9uZSB0byBkZWZpbmUgaG93IHlvdSB3YW50IHRvIHJvdXRlIHRyYWZmaWMgb24gdGhlIGludGVybmV0IGZvciBhIGRvbWFpbiwgc3VjaCBhcyBleGFtcGxlLmNvbSwgYW5kIGl0cyBzdWJkb21haW5zIChhcGV4LmV4YW1wbGUuY29tLCBhY21lLmV4YW1wbGUuY29tKS4gWW91IGNyZWF0ZSByZWNvcmRzIGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSB0byBkZWZpbmUgaG93IHlvdSB3YW50IHRvIHJvdXRlIHRyYWZmaWMgZm9yIGEgZG9tYWluIGFuZCBpdHMgc3ViZG9tYWlucyB3aXRoaW4gb25lIG9yIG1vcmUgQW1hem9uIFZpcnR1YWwgUHJpdmF0ZSBDbG91ZHMgKEFtYXpvbiBWUENzKS5cbiAqXG4gKiA+IFlvdSBjYW4ndCBjb252ZXJ0IGEgcHVibGljIGhvc3RlZCB6b25lIHRvIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSBvciB2aWNlIHZlcnNhLiBJbnN0ZWFkLCB5b3UgbXVzdCBjcmVhdGUgYSBuZXcgaG9zdGVkIHpvbmUgd2l0aCB0aGUgc2FtZSBuYW1lIGFuZCBjcmVhdGUgbmV3IHJlc291cmNlIHJlY29yZCBzZXRzLlxuICpcbiAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGNoYXJnZXMgZm9yIGhvc3RlZCB6b25lcywgc2VlIFtBbWF6b24gUm91dGUgNTMgUHJpY2luZ10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JvdXRlNTMvcHJpY2luZy8pIC5cbiAqXG4gKiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gKlxuICogLSBZb3UgY2FuJ3QgY3JlYXRlIGEgaG9zdGVkIHpvbmUgZm9yIGEgdG9wLWxldmVsIGRvbWFpbiAoVExEKSBzdWNoIGFzIC5jb20uXG4gKiAtIEZvciBwdWJsaWMgaG9zdGVkIHpvbmVzLCBSb3V0ZSA1MyBhdXRvbWF0aWNhbGx5IGNyZWF0ZXMgYSBkZWZhdWx0IFNPQSByZWNvcmQgYW5kIGZvdXIgTlMgcmVjb3JkcyBmb3IgdGhlIHpvbmUuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IFNPQSBhbmQgTlMgcmVjb3Jkcywgc2VlIFtOUyBhbmQgU09BIFJlY29yZHMgdGhhdCBSb3V0ZSA1MyBDcmVhdGVzIGZvciBhIEhvc3RlZCBab25lXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvU09BLU5TcmVjb3Jkcy5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAqXG4gKiBJZiB5b3Ugd2FudCB0byB1c2UgdGhlIHNhbWUgbmFtZSBzZXJ2ZXJzIGZvciBtdWx0aXBsZSBwdWJsaWMgaG9zdGVkIHpvbmVzLCB5b3UgY2FuIG9wdGlvbmFsbHkgYXNzb2NpYXRlIGEgcmV1c2FibGUgZGVsZWdhdGlvbiBzZXQgd2l0aCB0aGUgaG9zdGVkIHpvbmUuIFNlZSB0aGUgYERlbGVnYXRpb25TZXRJZGAgZWxlbWVudC5cbiAqIC0gSWYgeW91ciBkb21haW4gaXMgcmVnaXN0ZXJlZCB3aXRoIGEgcmVnaXN0cmFyIG90aGVyIHRoYW4gUm91dGUgNTMsIHlvdSBtdXN0IHVwZGF0ZSB0aGUgbmFtZSBzZXJ2ZXJzIHdpdGggeW91ciByZWdpc3RyYXIgdG8gbWFrZSBSb3V0ZSA1MyB0aGUgRE5TIHNlcnZpY2UgZm9yIHRoZSBkb21haW4uIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW01pZ3JhdGluZyBETlMgU2VydmljZSBmb3IgYW4gRXhpc3RpbmcgRG9tYWluIHRvIEFtYXpvbiBSb3V0ZSA1M10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL01pZ3JhdGluZ0ROUy5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAqXG4gKiBXaGVuIHlvdSBzdWJtaXQgYSBgQ3JlYXRlSG9zdGVkWm9uZWAgcmVxdWVzdCwgdGhlIGluaXRpYWwgc3RhdHVzIG9mIHRoZSBob3N0ZWQgem9uZSBpcyBgUEVORElOR2AgLiBGb3IgcHVibGljIGhvc3RlZCB6b25lcywgdGhpcyBtZWFucyB0aGF0IHRoZSBOUyBhbmQgU09BIHJlY29yZHMgYXJlIG5vdCB5ZXQgYXZhaWxhYmxlIG9uIGFsbCBSb3V0ZSA1MyBETlMgc2VydmVycy4gV2hlbiB0aGUgTlMgYW5kIFNPQSByZWNvcmRzIGFyZSBhdmFpbGFibGUsIHRoZSBzdGF0dXMgb2YgdGhlIHpvbmUgY2hhbmdlcyB0byBgSU5TWU5DYCAuXG4gKlxuICogVGhlIGBDcmVhdGVIb3N0ZWRab25lYCByZXF1ZXN0IHJlcXVpcmVzIHRoZSBjYWxsZXIgdG8gaGF2ZSBhbiBgZWMyOkRlc2NyaWJlVnBjc2AgcGVybWlzc2lvbi5cbiAqXG4gKiA+IFdoZW4gY3JlYXRpbmcgcHJpdmF0ZSBob3N0ZWQgem9uZXMsIHRoZSBBbWF6b24gVlBDIG11c3QgYmVsb25nIHRvIHRoZSBzYW1lIHBhcnRpdGlvbiB3aGVyZSB0aGUgaG9zdGVkIHpvbmUgaXMgY3JlYXRlZC4gQSBwYXJ0aXRpb24gaXMgYSBncm91cCBvZiBBV1MgUmVnaW9ucyAuIEVhY2ggQVdTIGFjY291bnQgaXMgc2NvcGVkIHRvIG9uZSBwYXJ0aXRpb24uXG4gKiA+XG4gKiA+IFRoZSBmb2xsb3dpbmcgYXJlIHRoZSBzdXBwb3J0ZWQgcGFydGl0aW9uczpcbiAqID5cbiAqID4gLSBgYXdzYCAtIEFXUyBSZWdpb25zXG4gKiA+IC0gYGF3cy1jbmAgLSBDaGluYSBSZWdpb25zXG4gKiA+IC0gYGF3cy11cy1nb3ZgIC0gQVdTIEdvdkNsb3VkIChVUykgUmVnaW9uXG4gKiA+XG4gKiA+IEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0FjY2VzcyBNYW5hZ2VtZW50XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2VuZXJhbC9sYXRlc3QvZ3IvYXdzLWFybnMtYW5kLW5hbWVzcGFjZXMuaHRtbCkgaW4gdGhlICpBV1MgR2VuZXJhbCBSZWZlcmVuY2UqIC5cbiAqXG4gKiBAY2xvdWRmb3JtYXRpb25SZXNvdXJjZSBBV1M6OlJvdXRlNTM6Okhvc3RlZFpvbmVcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWhvc3RlZHpvbmUuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuSG9zdGVkWm9uZSBleHRlbmRzIGNkay5DZm5SZXNvdXJjZSBpbXBsZW1lbnRzIGNkay5JSW5zcGVjdGFibGUge1xuICAgIC8qKlxuICAgICAqIFRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSB0eXBlIG5hbWUgZm9yIHRoaXMgcmVzb3VyY2UgY2xhc3MuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBDRk5fUkVTT1VSQ0VfVFlQRV9OQU1FID0gXCJBV1M6OlJvdXRlNTM6Okhvc3RlZFpvbmVcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmbkhvc3RlZFpvbmUge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmbkhvc3RlZFpvbmVQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihyZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgQ2ZuSG9zdGVkWm9uZShzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgSUQgdGhhdCBBbWF6b24gUm91dGUgNTMgYXNzaWduZWQgdG8gdGhlIGhvc3RlZCB6b25lIHdoZW4geW91IGNyZWF0ZWQgaXQuXG4gICAgICogQGNsb3VkZm9ybWF0aW9uQXR0cmlidXRlIElkXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGF0dHJJZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgc2V0IG9mIG5hbWUgc2VydmVycyBmb3IgdGhlIHNwZWNpZmljIGhvc3RlZCB6b25lLiBGb3IgZXhhbXBsZTogYG5zMS5leGFtcGxlLmNvbWAgLlxuICAgICAqXG4gICAgICogVGhpcyBhdHRyaWJ1dGUgaXMgbm90IHN1cHBvcnRlZCBmb3IgcHJpdmF0ZSBob3N0ZWQgem9uZXMuXG4gICAgICogQGNsb3VkZm9ybWF0aW9uQXR0cmlidXRlIE5hbWVTZXJ2ZXJzXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGF0dHJOYW1lU2VydmVyczogc3RyaW5nW107XG5cbiAgICAvKipcbiAgICAgKiBBIGNvbXBsZXggdHlwZSB0aGF0IGNvbnRhaW5zIGFuIG9wdGlvbmFsIGNvbW1lbnQuXG4gICAgICpcbiAgICAgKiBJZiB5b3UgZG9uJ3Qgd2FudCB0byBzcGVjaWZ5IGEgY29tbWVudCwgb21pdCB0aGUgYEhvc3RlZFpvbmVDb25maWdgIGFuZCBgQ29tbWVudGAgZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWhvc3RlZHpvbmUuaHRtbCNjZm4tcm91dGU1My1ob3N0ZWR6b25lLWhvc3RlZHpvbmVjb25maWdcbiAgICAgKi9cbiAgICBwdWJsaWMgaG9zdGVkWm9uZUNvbmZpZzogQ2ZuSG9zdGVkWm9uZS5Ib3N0ZWRab25lQ29uZmlnUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzLCBlZGl0cywgb3IgZGVsZXRlcyB0YWdzIGZvciBhIGhlYWx0aCBjaGVjayBvciBhIGhvc3RlZCB6b25lLlxuICAgICAqXG4gICAgICogRm9yIGluZm9ybWF0aW9uIGFib3V0IHVzaW5nIHRhZ3MgZm9yIGNvc3QgYWxsb2NhdGlvbiwgc2VlIFtVc2luZyBDb3N0IEFsbG9jYXRpb24gVGFnc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2F3c2FjY291bnRiaWxsaW5nL2xhdGVzdC9hYm91dHYyL2Nvc3QtYWxsb2MtdGFncy5odG1sKSBpbiB0aGUgKkFXUyBCaWxsaW5nIGFuZCBDb3N0IE1hbmFnZW1lbnQgVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1ob3N0ZWR6b25lLmh0bWwjY2ZuLXJvdXRlNTMtaG9zdGVkem9uZS1ob3N0ZWR6b25ldGFnc1xuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSB0YWdzOiBjZGsuVGFnTWFuYWdlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBkb21haW4uIFNwZWNpZnkgYSBmdWxseSBxdWFsaWZpZWQgZG9tYWluIG5hbWUsIGZvciBleGFtcGxlLCAqd3d3LmV4YW1wbGUuY29tKiAuIFRoZSB0cmFpbGluZyBkb3QgaXMgb3B0aW9uYWw7IEFtYXpvbiBSb3V0ZSA1MyBhc3N1bWVzIHRoYXQgdGhlIGRvbWFpbiBuYW1lIGlzIGZ1bGx5IHF1YWxpZmllZC4gVGhpcyBtZWFucyB0aGF0IFJvdXRlIDUzIHRyZWF0cyAqd3d3LmV4YW1wbGUuY29tKiAod2l0aG91dCBhIHRyYWlsaW5nIGRvdCkgYW5kICp3d3cuZXhhbXBsZS5jb20uKiAod2l0aCBhIHRyYWlsaW5nIGRvdCkgYXMgaWRlbnRpY2FsLlxuICAgICAqXG4gICAgICogSWYgeW91J3JlIGNyZWF0aW5nIGEgcHVibGljIGhvc3RlZCB6b25lLCB0aGlzIGlzIHRoZSBuYW1lIHlvdSBoYXZlIHJlZ2lzdGVyZWQgd2l0aCB5b3VyIEROUyByZWdpc3RyYXIuIElmIHlvdXIgZG9tYWluIG5hbWUgaXMgcmVnaXN0ZXJlZCB3aXRoIGEgcmVnaXN0cmFyIG90aGVyIHRoYW4gUm91dGUgNTMsIGNoYW5nZSB0aGUgbmFtZSBzZXJ2ZXJzIGZvciB5b3VyIGRvbWFpbiB0byB0aGUgc2V0IG9mIGBOYW1lU2VydmVyc2AgdGhhdCBhcmUgcmV0dXJuZWQgYnkgdGhlIGBGbjo6R2V0QXR0YCBpbnRyaW5zaWMgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWhvc3RlZHpvbmUuaHRtbCNjZm4tcm91dGU1My1ob3N0ZWR6b25lLW5hbWVcbiAgICAgKi9cbiAgICBwdWJsaWMgbmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNvbmZpZ3VyYXRpb24gZm9yIEROUyBxdWVyeSBsb2dnaW5nLiBBZnRlciB5b3UgY3JlYXRlIGEgcXVlcnkgbG9nZ2luZyBjb25maWd1cmF0aW9uLCBBbWF6b24gUm91dGUgNTMgYmVnaW5zIHRvIHB1Ymxpc2ggbG9nIGRhdGEgdG8gYW4gQW1hem9uIENsb3VkV2F0Y2ggTG9ncyBsb2cgZ3JvdXAuXG4gICAgICpcbiAgICAgKiBETlMgcXVlcnkgbG9ncyBjb250YWluIGluZm9ybWF0aW9uIGFib3V0IHRoZSBxdWVyaWVzIHRoYXQgUm91dGUgNTMgcmVjZWl2ZXMgZm9yIGEgc3BlY2lmaWVkIHB1YmxpYyBob3N0ZWQgem9uZSwgc3VjaCBhcyB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBSb3V0ZSA1MyBlZGdlIGxvY2F0aW9uIHRoYXQgcmVzcG9uZGVkIHRvIHRoZSBETlMgcXVlcnlcbiAgICAgKiAtIERvbWFpbiBvciBzdWJkb21haW4gdGhhdCB3YXMgcmVxdWVzdGVkXG4gICAgICogLSBETlMgcmVjb3JkIHR5cGUsIHN1Y2ggYXMgQSBvciBBQUFBXG4gICAgICogLSBETlMgcmVzcG9uc2UgY29kZSwgc3VjaCBhcyBgTm9FcnJvcmAgb3IgYFNlcnZGYWlsYFxuICAgICAqXG4gICAgICogLSAqKkxvZyBHcm91cCBhbmQgUmVzb3VyY2UgUG9saWN5KiogLSBCZWZvcmUgeW91IGNyZWF0ZSBhIHF1ZXJ5IGxvZ2dpbmcgY29uZmlndXJhdGlvbiwgcGVyZm9ybSB0aGUgZm9sbG93aW5nIG9wZXJhdGlvbnMuXG4gICAgICpcbiAgICAgKiA+IElmIHlvdSBjcmVhdGUgYSBxdWVyeSBsb2dnaW5nIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIFJvdXRlIDUzIGNvbnNvbGUsIFJvdXRlIDUzIHBlcmZvcm1zIHRoZXNlIG9wZXJhdGlvbnMgYXV0b21hdGljYWxseS5cbiAgICAgKlxuICAgICAqIC0gQ3JlYXRlIGEgQ2xvdWRXYXRjaCBMb2dzIGxvZyBncm91cCwgYW5kIG1ha2Ugbm90ZSBvZiB0aGUgQVJOLCB3aGljaCB5b3Ugc3BlY2lmeSB3aGVuIHlvdSBjcmVhdGUgYSBxdWVyeSBsb2dnaW5nIGNvbmZpZ3VyYXRpb24uIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gWW91IG11c3QgY3JlYXRlIHRoZSBsb2cgZ3JvdXAgaW4gdGhlIHVzLWVhc3QtMSByZWdpb24uXG4gICAgICogLSBZb3UgbXVzdCB1c2UgdGhlIHNhbWUgQVdTIGFjY291bnQgdG8gY3JlYXRlIHRoZSBsb2cgZ3JvdXAgYW5kIHRoZSBob3N0ZWQgem9uZSB0aGF0IHlvdSB3YW50IHRvIGNvbmZpZ3VyZSBxdWVyeSBsb2dnaW5nIGZvci5cbiAgICAgKiAtIFdoZW4geW91IGNyZWF0ZSBsb2cgZ3JvdXBzIGZvciBxdWVyeSBsb2dnaW5nLCB3ZSByZWNvbW1lbmQgdGhhdCB5b3UgdXNlIGEgY29uc2lzdGVudCBwcmVmaXgsIGZvciBleGFtcGxlOlxuICAgICAqXG4gICAgICogYC9hd3Mvcm91dGU1My8gKmhvc3RlZCB6b25lIG5hbWUqYFxuICAgICAqXG4gICAgICogSW4gdGhlIG5leHQgc3RlcCwgeW91J2xsIGNyZWF0ZSBhIHJlc291cmNlIHBvbGljeSwgd2hpY2ggY29udHJvbHMgYWNjZXNzIHRvIG9uZSBvciBtb3JlIGxvZyBncm91cHMgYW5kIHRoZSBhc3NvY2lhdGVkIEFXUyByZXNvdXJjZXMsIHN1Y2ggYXMgUm91dGUgNTMgaG9zdGVkIHpvbmVzLiBUaGVyZSdzIGEgbGltaXQgb24gdGhlIG51bWJlciBvZiByZXNvdXJjZSBwb2xpY2llcyB0aGF0IHlvdSBjYW4gY3JlYXRlLCBzbyB3ZSByZWNvbW1lbmQgdGhhdCB5b3UgdXNlIGEgY29uc2lzdGVudCBwcmVmaXggc28geW91IGNhbiB1c2UgdGhlIHNhbWUgcmVzb3VyY2UgcG9saWN5IGZvciBhbGwgdGhlIGxvZyBncm91cHMgdGhhdCB5b3UgY3JlYXRlIGZvciBxdWVyeSBsb2dnaW5nLlxuICAgICAqIC0gQ3JlYXRlIGEgQ2xvdWRXYXRjaCBMb2dzIHJlc291cmNlIHBvbGljeSwgYW5kIGdpdmUgaXQgdGhlIHBlcm1pc3Npb25zIHRoYXQgUm91dGUgNTMgbmVlZHMgdG8gY3JlYXRlIGxvZyBzdHJlYW1zIGFuZCB0byBzZW5kIHF1ZXJ5IGxvZ3MgdG8gbG9nIHN0cmVhbXMuIEZvciB0aGUgdmFsdWUgb2YgYFJlc291cmNlYCAsIHNwZWNpZnkgdGhlIEFSTiBmb3IgdGhlIGxvZyBncm91cCB0aGF0IHlvdSBjcmVhdGVkIGluIHRoZSBwcmV2aW91cyBzdGVwLiBUbyB1c2UgdGhlIHNhbWUgcmVzb3VyY2UgcG9saWN5IGZvciBhbGwgdGhlIENsb3VkV2F0Y2ggTG9ncyBsb2cgZ3JvdXBzIHRoYXQgeW91IGNyZWF0ZWQgZm9yIHF1ZXJ5IGxvZ2dpbmcgY29uZmlndXJhdGlvbnMsIHJlcGxhY2UgdGhlIGhvc3RlZCB6b25lIG5hbWUgd2l0aCBgKmAgLCBmb3IgZXhhbXBsZTpcbiAgICAgKlxuICAgICAqIGBhcm46YXdzOmxvZ3M6dXMtZWFzdC0xOjEyMzQxMjM0MTIzNDpsb2ctZ3JvdXA6L2F3cy9yb3V0ZTUzLypgXG4gICAgICpcbiAgICAgKiBUbyBhdm9pZCB0aGUgY29uZnVzZWQgZGVwdXR5IHByb2JsZW0sIGEgc2VjdXJpdHkgaXNzdWUgd2hlcmUgYW4gZW50aXR5IHdpdGhvdXQgYSBwZXJtaXNzaW9uIGZvciBhbiBhY3Rpb24gY2FuIGNvZXJjZSBhIG1vcmUtcHJpdmlsZWdlZCBlbnRpdHkgdG8gcGVyZm9ybSBpdCwgeW91IGNhbiBvcHRpb25hbGx5IGxpbWl0IHRoZSBwZXJtaXNzaW9ucyB0aGF0IGEgc2VydmljZSBoYXMgdG8gYSByZXNvdXJjZSBpbiBhIHJlc291cmNlLWJhc2VkIHBvbGljeSBieSBzdXBwbHlpbmcgdGhlIGZvbGxvd2luZyB2YWx1ZXM6XG4gICAgICpcbiAgICAgKiAtIEZvciBgYXdzOlNvdXJjZUFybmAgLCBzdXBwbHkgdGhlIGhvc3RlZCB6b25lIEFSTiB1c2VkIGluIGNyZWF0aW5nIHRoZSBxdWVyeSBsb2dnaW5nIGNvbmZpZ3VyYXRpb24uIEZvciBleGFtcGxlLCBgYXdzOlNvdXJjZUFybjogYXJuOmF3czpyb3V0ZTUzOjo6aG9zdGVkem9uZS9ob3N0ZWQgem9uZSBJRGAgLlxuICAgICAqIC0gRm9yIGBhd3M6U291cmNlQWNjb3VudGAgLCBzdXBwbHkgdGhlIGFjY291bnQgSUQgZm9yIHRoZSBhY2NvdW50IHRoYXQgY3JlYXRlcyB0aGUgcXVlcnkgbG9nZ2luZyBjb25maWd1cmF0aW9uLiBGb3IgZXhhbXBsZSwgYGF3czpTb3VyY2VBY2NvdW50OjExMTExMTExMTExMWAgLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbVGhlIGNvbmZ1c2VkIGRlcHV0eSBwcm9ibGVtXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvY29uZnVzZWQtZGVwdXR5Lmh0bWwpIGluIHRoZSAqQVdTIElBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiA+IFlvdSBjYW4ndCB1c2UgdGhlIENsb3VkV2F0Y2ggY29uc29sZSB0byBjcmVhdGUgb3IgZWRpdCBhIHJlc291cmNlIHBvbGljeS4gWW91IG11c3QgdXNlIHRoZSBDbG91ZFdhdGNoIEFQSSwgb25lIG9mIHRoZSBBV1MgU0RLcywgb3IgdGhlIEFXUyBDTEkgLlxuICAgICAqIC0gKipMb2cgU3RyZWFtcyBhbmQgRWRnZSBMb2NhdGlvbnMqKiAtIFdoZW4gUm91dGUgNTMgZmluaXNoZXMgY3JlYXRpbmcgdGhlIGNvbmZpZ3VyYXRpb24gZm9yIEROUyBxdWVyeSBsb2dnaW5nLCBpdCBkb2VzIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIENyZWF0ZXMgYSBsb2cgc3RyZWFtIGZvciBhbiBlZGdlIGxvY2F0aW9uIHRoZSBmaXJzdCB0aW1lIHRoYXQgdGhlIGVkZ2UgbG9jYXRpb24gcmVzcG9uZHMgdG8gRE5TIHF1ZXJpZXMgZm9yIHRoZSBzcGVjaWZpZWQgaG9zdGVkIHpvbmUuIFRoYXQgbG9nIHN0cmVhbSBpcyB1c2VkIHRvIGxvZyBhbGwgcXVlcmllcyB0aGF0IFJvdXRlIDUzIHJlc3BvbmRzIHRvIGZvciB0aGF0IGVkZ2UgbG9jYXRpb24uXG4gICAgICogLSBCZWdpbnMgdG8gc2VuZCBxdWVyeSBsb2dzIHRvIHRoZSBhcHBsaWNhYmxlIGxvZyBzdHJlYW0uXG4gICAgICpcbiAgICAgKiBUaGUgbmFtZSBvZiBlYWNoIGxvZyBzdHJlYW0gaXMgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6XG4gICAgICpcbiAgICAgKiBgKmhvc3RlZCB6b25lIElEKiAvICplZGdlIGxvY2F0aW9uIGNvZGUqYFxuICAgICAqXG4gICAgICogVGhlIGVkZ2UgbG9jYXRpb24gY29kZSBpcyBhIHRocmVlLWxldHRlciBjb2RlIGFuZCBhbiBhcmJpdHJhcmlseSBhc3NpZ25lZCBudW1iZXIsIGZvciBleGFtcGxlLCBERlczLiBUaGUgdGhyZWUtbGV0dGVyIGNvZGUgdHlwaWNhbGx5IGNvcnJlc3BvbmRzIHdpdGggdGhlIEludGVybmF0aW9uYWwgQWlyIFRyYW5zcG9ydCBBc3NvY2lhdGlvbiBhaXJwb3J0IGNvZGUgZm9yIGFuIGFpcnBvcnQgbmVhciB0aGUgZWRnZSBsb2NhdGlvbi4gKFRoZXNlIGFiYnJldmlhdGlvbnMgbWlnaHQgY2hhbmdlIGluIHRoZSBmdXR1cmUuKSBGb3IgYSBsaXN0IG9mIGVkZ2UgbG9jYXRpb25zLCBzZWUgXCJUaGUgUm91dGUgNTMgR2xvYmFsIE5ldHdvcmtcIiBvbiB0aGUgW1JvdXRlIDUzIFByb2R1Y3QgRGV0YWlsc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JvdXRlNTMvZGV0YWlscy8pIHBhZ2UuXG4gICAgICogLSAqKlF1ZXJpZXMgVGhhdCBBcmUgTG9nZ2VkKiogLSBRdWVyeSBsb2dzIGNvbnRhaW4gb25seSB0aGUgcXVlcmllcyB0aGF0IEROUyByZXNvbHZlcnMgZm9yd2FyZCB0byBSb3V0ZSA1My4gSWYgYSBETlMgcmVzb2x2ZXIgaGFzIGFscmVhZHkgY2FjaGVkIHRoZSByZXNwb25zZSB0byBhIHF1ZXJ5IChzdWNoIGFzIHRoZSBJUCBhZGRyZXNzIGZvciBhIGxvYWQgYmFsYW5jZXIgZm9yIGV4YW1wbGUuY29tKSwgdGhlIHJlc29sdmVyIHdpbGwgY29udGludWUgdG8gcmV0dXJuIHRoZSBjYWNoZWQgcmVzcG9uc2UuIEl0IGRvZXNuJ3QgZm9yd2FyZCBhbm90aGVyIHF1ZXJ5IHRvIFJvdXRlIDUzIHVudGlsIHRoZSBUVEwgZm9yIHRoZSBjb3JyZXNwb25kaW5nIHJlc291cmNlIHJlY29yZCBzZXQgZXhwaXJlcy4gRGVwZW5kaW5nIG9uIGhvdyBtYW55IEROUyBxdWVyaWVzIGFyZSBzdWJtaXR0ZWQgZm9yIGEgcmVzb3VyY2UgcmVjb3JkIHNldCwgYW5kIGRlcGVuZGluZyBvbiB0aGUgVFRMIGZvciB0aGF0IHJlc291cmNlIHJlY29yZCBzZXQsIHF1ZXJ5IGxvZ3MgbWlnaHQgY29udGFpbiBpbmZvcm1hdGlvbiBhYm91dCBvbmx5IG9uZSBxdWVyeSBvdXQgb2YgZXZlcnkgc2V2ZXJhbCB0aG91c2FuZCBxdWVyaWVzIHRoYXQgYXJlIHN1Ym1pdHRlZCB0byBETlMuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGhvdyBETlMgd29ya3MsIHNlZSBbUm91dGluZyBJbnRlcm5ldCBUcmFmZmljIHRvIFlvdXIgV2Vic2l0ZSBvciBXZWIgQXBwbGljYXRpb25dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS93ZWxjb21lLWRucy1zZXJ2aWNlLmh0bWwpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqIC0gKipMb2cgRmlsZSBGb3JtYXQqKiAtIEZvciBhIGxpc3Qgb2YgdGhlIHZhbHVlcyBpbiBlYWNoIHF1ZXJ5IGxvZyBhbmQgdGhlIGZvcm1hdCBvZiBlYWNoIHZhbHVlLCBzZWUgW0xvZ2dpbmcgRE5TIFF1ZXJpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9xdWVyeS1sb2dzLmh0bWwpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqIC0gKipQcmljaW5nKiogLSBGb3IgaW5mb3JtYXRpb24gYWJvdXQgY2hhcmdlcyBmb3IgcXVlcnkgbG9ncywgc2VlIFtBbWF6b24gQ2xvdWRXYXRjaCBQcmljaW5nXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWR3YXRjaC9wcmljaW5nLykgLlxuICAgICAqIC0gKipIb3cgdG8gU3RvcCBMb2dnaW5nKiogLSBJZiB5b3Ugd2FudCBSb3V0ZSA1MyB0byBzdG9wIHNlbmRpbmcgcXVlcnkgbG9ncyB0byBDbG91ZFdhdGNoIExvZ3MsIGRlbGV0ZSB0aGUgcXVlcnkgbG9nZ2luZyBjb25maWd1cmF0aW9uLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtEZWxldGVRdWVyeUxvZ2dpbmdDb25maWddKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZVF1ZXJ5TG9nZ2luZ0NvbmZpZy5odG1sKSAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWhvc3RlZHpvbmUuaHRtbCNjZm4tcm91dGU1My1ob3N0ZWR6b25lLXF1ZXJ5bG9nZ2luZ2NvbmZpZ1xuICAgICAqL1xuICAgIHB1YmxpYyBxdWVyeUxvZ2dpbmdDb25maWc6IENmbkhvc3RlZFpvbmUuUXVlcnlMb2dnaW5nQ29uZmlnUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiAqUHJpdmF0ZSBob3N0ZWQgem9uZXM6KiBBIGNvbXBsZXggdHlwZSB0aGF0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBWUENzIHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGhvc3RlZCB6b25lLlxuICAgICAqXG4gICAgICogPiBGb3IgcHVibGljIGhvc3RlZCB6b25lcywgb21pdCBgVlBDc2AgLCBgVlBDSWRgICwgYW5kIGBWUENSZWdpb25gIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtaG9zdGVkem9uZS5odG1sI2Nmbi1yb3V0ZTUzLWhvc3RlZHpvbmUtdnBjc1xuICAgICAqL1xuICAgIHB1YmxpYyB2cGNzOiBBcnJheTxDZm5Ib3N0ZWRab25lLlZQQ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpSb3V0ZTUzOjpIb3N0ZWRab25lYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5Ib3N0ZWRab25lUHJvcHMgPSB7fSkge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuSG9zdGVkWm9uZS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgdGhpcy5hdHRySWQgPSBjZGsuVG9rZW4uYXNTdHJpbmcodGhpcy5nZXRBdHQoJ0lkJykpO1xuICAgICAgICB0aGlzLmF0dHJOYW1lU2VydmVycyA9IGNkay5Ub2tlbi5hc0xpc3QodGhpcy5nZXRBdHQoJ05hbWVTZXJ2ZXJzJykpO1xuXG4gICAgICAgIHRoaXMuaG9zdGVkWm9uZUNvbmZpZyA9IHByb3BzLmhvc3RlZFpvbmVDb25maWc7XG4gICAgICAgIHRoaXMudGFncyA9IG5ldyBjZGsuVGFnTWFuYWdlcihjZGsuVGFnVHlwZS5TVEFOREFSRCwgXCJBV1M6OlJvdXRlNTM6Okhvc3RlZFpvbmVcIiwgcHJvcHMuaG9zdGVkWm9uZVRhZ3MsIHsgdGFnUHJvcGVydHlOYW1lOiAnaG9zdGVkWm9uZVRhZ3MnIH0pO1xuICAgICAgICB0aGlzLm5hbWUgPSBwcm9wcy5uYW1lO1xuICAgICAgICB0aGlzLnF1ZXJ5TG9nZ2luZ0NvbmZpZyA9IHByb3BzLnF1ZXJ5TG9nZ2luZ0NvbmZpZztcbiAgICAgICAgdGhpcy52cGNzID0gcHJvcHMudnBjcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmbkhvc3RlZFpvbmUuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGhvc3RlZFpvbmVDb25maWc6IHRoaXMuaG9zdGVkWm9uZUNvbmZpZyxcbiAgICAgICAgICAgIGhvc3RlZFpvbmVUYWdzOiB0aGlzLnRhZ3MucmVuZGVyVGFncygpLFxuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICAgICAgcXVlcnlMb2dnaW5nQ29uZmlnOiB0aGlzLnF1ZXJ5TG9nZ2luZ0NvbmZpZyxcbiAgICAgICAgICAgIHZwY3M6IHRoaXMudnBjcyxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5Ib3N0ZWRab25lUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuSG9zdGVkWm9uZSB7XG4gICAgLyoqXG4gICAgICogQSBjb21wbGV4IHR5cGUgdGhhdCBjb250YWlucyBhbiBvcHRpb25hbCBjb21tZW50IGFib3V0IHlvdXIgaG9zdGVkIHpvbmUuIElmIHlvdSBkb24ndCB3YW50IHRvIHNwZWNpZnkgYSBjb21tZW50LCBvbWl0IGJvdGggdGhlIGBIb3N0ZWRab25lQ29uZmlnYCBhbmQgYENvbW1lbnRgIGVsZW1lbnRzLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1ob3N0ZWR6b25lLWhvc3RlZHpvbmVjb25maWcuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgSG9zdGVkWm9uZUNvbmZpZ1Byb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFueSBjb21tZW50cyB0aGF0IHlvdSB3YW50IHRvIGluY2x1ZGUgYWJvdXQgdGhlIGhvc3RlZCB6b25lLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaG9zdGVkem9uZS1ob3N0ZWR6b25lY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaG9zdGVkem9uZS1ob3N0ZWR6b25lY29uZmlnLWNvbW1lbnRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNvbW1lbnQ/OiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYEhvc3RlZFpvbmVDb25maWdQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgSG9zdGVkWm9uZUNvbmZpZ1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmbkhvc3RlZFpvbmVfSG9zdGVkWm9uZUNvbmZpZ1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY29tbWVudCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jb21tZW50KSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkhvc3RlZFpvbmVDb25maWdQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6SG9zdGVkWm9uZS5Ib3N0ZWRab25lQ29uZmlnYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBIb3N0ZWRab25lQ29uZmlnUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6Okhvc3RlZFpvbmUuSG9zdGVkWm9uZUNvbmZpZ2AgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5Ib3N0ZWRab25lSG9zdGVkWm9uZUNvbmZpZ1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5Ib3N0ZWRab25lX0hvc3RlZFpvbmVDb25maWdQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQ29tbWVudDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5jb21tZW50KSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuSG9zdGVkWm9uZUhvc3RlZFpvbmVDb25maWdQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbkhvc3RlZFpvbmUuSG9zdGVkWm9uZUNvbmZpZ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbkhvc3RlZFpvbmUuSG9zdGVkWm9uZUNvbmZpZ1Byb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY29tbWVudCcsICdDb21tZW50JywgcHJvcGVydGllcy5Db21tZW50ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNvbW1lbnQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5Ib3N0ZWRab25lIHtcbiAgICAvKipcbiAgICAgKiBBIGNvbXBsZXggdHlwZSB0aGF0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGEgdGFnIHRoYXQgeW91IHdhbnQgdG8gYWRkIG9yIGVkaXQgZm9yIHRoZSBzcGVjaWZpZWQgaGVhbHRoIGNoZWNrIG9yIGhvc3RlZCB6b25lLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1ob3N0ZWR6b25lLWhvc3RlZHpvbmV0YWcuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgSG9zdGVkWm9uZVRhZ1Byb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2YWx1ZSBvZiBgS2V5YCBkZXBlbmRzIG9uIHRoZSBvcGVyYXRpb24gdGhhdCB5b3Ugd2FudCB0byBwZXJmb3JtOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICpBZGQgYSB0YWcgdG8gYSBoZWFsdGggY2hlY2sgb3IgaG9zdGVkIHpvbmUqIDogYEtleWAgaXMgdGhlIG5hbWUgdGhhdCB5b3Ugd2FudCB0byBnaXZlIHRoZSBuZXcgdGFnLlxuICAgICAgICAgKiAtICpFZGl0IGEgdGFnKiA6IGBLZXlgIGlzIHRoZSBuYW1lIG9mIHRoZSB0YWcgdGhhdCB5b3Ugd2FudCB0byBjaGFuZ2UgdGhlIGBWYWx1ZWAgZm9yLlxuICAgICAgICAgKiAtICpEZWxldGUgYSBrZXkqIDogYEtleWAgaXMgdGhlIG5hbWUgb2YgdGhlIHRhZyB5b3Ugd2FudCB0byByZW1vdmUuXG4gICAgICAgICAqIC0gKkdpdmUgYSBuYW1lIHRvIGEgaGVhbHRoIGNoZWNrKiA6IEVkaXQgdGhlIGRlZmF1bHQgYE5hbWVgIHRhZy4gSW4gdGhlIEFtYXpvbiBSb3V0ZSA1MyBjb25zb2xlLCB0aGUgbGlzdCBvZiB5b3VyIGhlYWx0aCBjaGVja3MgaW5jbHVkZXMgYSAqTmFtZSogY29sdW1uIHRoYXQgbGV0cyB5b3Ugc2VlIHRoZSBuYW1lIHRoYXQgeW91J3ZlIGdpdmVuIHRvIGVhY2ggaGVhbHRoIGNoZWNrLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaG9zdGVkem9uZS1ob3N0ZWR6b25ldGFnLmh0bWwjY2ZuLXJvdXRlNTMtaG9zdGVkem9uZS1ob3N0ZWR6b25ldGFnLWtleVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkga2V5OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdmFsdWUgb2YgYFZhbHVlYCBkZXBlbmRzIG9uIHRoZSBvcGVyYXRpb24gdGhhdCB5b3Ugd2FudCB0byBwZXJmb3JtOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICpBZGQgYSB0YWcgdG8gYSBoZWFsdGggY2hlY2sgb3IgaG9zdGVkIHpvbmUqIDogYFZhbHVlYCBpcyB0aGUgdmFsdWUgdGhhdCB5b3Ugd2FudCB0byBnaXZlIHRoZSBuZXcgdGFnLlxuICAgICAgICAgKiAtICpFZGl0IGEgdGFnKiA6IGBWYWx1ZWAgaXMgdGhlIG5ldyB2YWx1ZSB0aGF0IHlvdSB3YW50IHRvIGFzc2lnbiB0aGUgdGFnLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaG9zdGVkem9uZS1ob3N0ZWR6b25ldGFnLmh0bWwjY2ZuLXJvdXRlNTMtaG9zdGVkem9uZS1ob3N0ZWR6b25ldGFnLXZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB2YWx1ZTogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBIb3N0ZWRab25lVGFnUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEhvc3RlZFpvbmVUYWdQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5Ib3N0ZWRab25lX0hvc3RlZFpvbmVUYWdQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2tleScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5rZXkpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2tleScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5rZXkpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3ZhbHVlJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnZhbHVlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd2YWx1ZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy52YWx1ZSkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJIb3N0ZWRab25lVGFnUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6Okhvc3RlZFpvbmUuSG9zdGVkWm9uZVRhZ2AgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgSG9zdGVkWm9uZVRhZ1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpIb3N0ZWRab25lLkhvc3RlZFpvbmVUYWdgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuSG9zdGVkWm9uZUhvc3RlZFpvbmVUYWdQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuSG9zdGVkWm9uZV9Ib3N0ZWRab25lVGFnUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEtleTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5rZXkpLFxuICAgICAgICBWYWx1ZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy52YWx1ZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkhvc3RlZFpvbmVIb3N0ZWRab25lVGFnUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5Ib3N0ZWRab25lLkhvc3RlZFpvbmVUYWdQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5Ib3N0ZWRab25lLkhvc3RlZFpvbmVUYWdQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2tleScsICdLZXknLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLktleSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndmFsdWUnLCAnVmFsdWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlZhbHVlKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuSG9zdGVkWm9uZSB7XG4gICAgLyoqXG4gICAgICogQSBjb21wbGV4IHR5cGUgdGhhdCBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBhIGNvbmZpZ3VyYXRpb24gZm9yIEROUyBxdWVyeSBsb2dnaW5nLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1ob3N0ZWR6b25lLXF1ZXJ5bG9nZ2luZ2NvbmZpZy5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBRdWVyeUxvZ2dpbmdDb25maWdQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIENsb3VkV2F0Y2ggTG9ncyBsb2cgZ3JvdXAgdGhhdCBBbWF6b24gUm91dGUgNTMgaXMgcHVibGlzaGluZyBsb2dzIHRvLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaG9zdGVkem9uZS1xdWVyeWxvZ2dpbmdjb25maWcuaHRtbCNjZm4tcm91dGU1My1ob3N0ZWR6b25lLXF1ZXJ5bG9nZ2luZ2NvbmZpZy1jbG91ZHdhdGNobG9nc2xvZ2dyb3VwYXJuXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBjbG91ZFdhdGNoTG9nc0xvZ0dyb3VwQXJuOiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYFF1ZXJ5TG9nZ2luZ0NvbmZpZ1Byb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBRdWVyeUxvZ2dpbmdDb25maWdQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5Ib3N0ZWRab25lX1F1ZXJ5TG9nZ2luZ0NvbmZpZ1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY2xvdWRXYXRjaExvZ3NMb2dHcm91cEFybicsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5jbG91ZFdhdGNoTG9nc0xvZ0dyb3VwQXJuKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjbG91ZFdhdGNoTG9nc0xvZ0dyb3VwQXJuJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmNsb3VkV2F0Y2hMb2dzTG9nR3JvdXBBcm4pKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiUXVlcnlMb2dnaW5nQ29uZmlnUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6Okhvc3RlZFpvbmUuUXVlcnlMb2dnaW5nQ29uZmlnYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBRdWVyeUxvZ2dpbmdDb25maWdQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6SG9zdGVkWm9uZS5RdWVyeUxvZ2dpbmdDb25maWdgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuSG9zdGVkWm9uZVF1ZXJ5TG9nZ2luZ0NvbmZpZ1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5Ib3N0ZWRab25lX1F1ZXJ5TG9nZ2luZ0NvbmZpZ1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBDbG91ZFdhdGNoTG9nc0xvZ0dyb3VwQXJuOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNsb3VkV2F0Y2hMb2dzTG9nR3JvdXBBcm4pLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5Ib3N0ZWRab25lUXVlcnlMb2dnaW5nQ29uZmlnUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5Ib3N0ZWRab25lLlF1ZXJ5TG9nZ2luZ0NvbmZpZ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbkhvc3RlZFpvbmUuUXVlcnlMb2dnaW5nQ29uZmlnUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjbG91ZFdhdGNoTG9nc0xvZ0dyb3VwQXJuJywgJ0Nsb3VkV2F0Y2hMb2dzTG9nR3JvdXBBcm4nLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNsb3VkV2F0Y2hMb2dzTG9nR3JvdXBBcm4pKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5Ib3N0ZWRab25lIHtcbiAgICAvKipcbiAgICAgKiAqUHJpdmF0ZSBob3N0ZWQgem9uZXMgb25seToqIEEgY29tcGxleCB0eXBlIHRoYXQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgYW4gQW1hem9uIFZQQy4gUm91dGUgNTMgUmVzb2x2ZXIgdXNlcyB0aGUgcmVjb3JkcyBpbiB0aGUgcHJpdmF0ZSBob3N0ZWQgem9uZSB0byByb3V0ZSB0cmFmZmljIGluIHRoYXQgVlBDLlxuICAgICAqXG4gICAgICogPiBGb3IgcHVibGljIGhvc3RlZCB6b25lcywgb21pdCBgVlBDc2AgLCBgVlBDSWRgICwgYW5kIGBWUENSZWdpb25gIC5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaG9zdGVkem9uZS12cGMuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgVlBDUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogKlByaXZhdGUgaG9zdGVkIHpvbmVzIG9ubHk6KiBUaGUgSUQgb2YgYW4gQW1hem9uIFZQQy5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBGb3IgcHVibGljIGhvc3RlZCB6b25lcywgb21pdCBgVlBDc2AgLCBgVlBDSWRgICwgYW5kIGBWUENSZWdpb25gIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhvc3RlZHpvbmUtdnBjLmh0bWwjY2ZuLXJvdXRlNTMtaG9zdGVkem9uZS12cGMtdnBjaWRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHZwY0lkOiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiAqUHJpdmF0ZSBob3N0ZWQgem9uZXMgb25seToqIFRoZSByZWdpb24gdGhhdCBhbiBBbWF6b24gVlBDIHdhcyBjcmVhdGVkIGluLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IEZvciBwdWJsaWMgaG9zdGVkIHpvbmVzLCBvbWl0IGBWUENzYCAsIGBWUENJZGAgLCBhbmQgYFZQQ1JlZ2lvbmAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaG9zdGVkem9uZS12cGMuaHRtbCNjZm4tcm91dGU1My1ob3N0ZWR6b25lLXZwYy12cGNyZWdpb25cbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHZwY1JlZ2lvbjogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBWUENQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgVlBDUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuSG9zdGVkWm9uZV9WUENQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3ZwY0lkJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnZwY0lkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd2cGNJZCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy52cGNJZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndnBjUmVnaW9uJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnZwY1JlZ2lvbikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndnBjUmVnaW9uJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnZwY1JlZ2lvbikpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJWUENQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6SG9zdGVkWm9uZS5WUENgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYFZQQ1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpIb3N0ZWRab25lLlZQQ2AgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5Ib3N0ZWRab25lVlBDUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbkhvc3RlZFpvbmVfVlBDUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIFZQQ0lkOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnZwY0lkKSxcbiAgICAgICAgVlBDUmVnaW9uOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnZwY1JlZ2lvbiksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkhvc3RlZFpvbmVWUENQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbkhvc3RlZFpvbmUuVlBDUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuSG9zdGVkWm9uZS5WUENQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3ZwY0lkJywgJ1ZQQ0lkJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5WUENJZCkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndnBjUmVnaW9uJywgJ1ZQQ1JlZ2lvbicsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuVlBDUmVnaW9uKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuS2V5U2lnbmluZ0tleWBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1rZXlzaWduaW5na2V5Lmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5LZXlTaWduaW5nS2V5UHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogVGhlIHVuaXF1ZSBzdHJpbmcgKElEKSB0aGF0IGlzIHVzZWQgdG8gaWRlbnRpZnkgYSBob3N0ZWQgem9uZS4gRm9yIGV4YW1wbGU6IGBaMDAwMDExMTFBMUFCQ2FhQUJDMTFgIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMta2V5c2lnbmluZ2tleS5odG1sI2Nmbi1yb3V0ZTUzLWtleXNpZ25pbmdrZXktaG9zdGVkem9uZWlkXG4gICAgICovXG4gICAgcmVhZG9ubHkgaG9zdGVkWm9uZUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgQW1hem9uIHJlc291cmNlIG5hbWUgKEFSTikgZm9yIGEgY3VzdG9tZXIgbWFuYWdlZCBjdXN0b21lciBtYXN0ZXIga2V5IChDTUspIGluIEFXUyBLZXkgTWFuYWdlbWVudCBTZXJ2aWNlICggQVdTIEtNUyApLiBUaGUgYEtleU1hbmFnZW1lbnRTZXJ2aWNlQXJuYCBtdXN0IGJlIHVuaXF1ZSBmb3IgZWFjaCBrZXktc2lnbmluZyBrZXkgKEtTSykgaW4gYSBzaW5nbGUgaG9zdGVkIHpvbmUuIEZvciBleGFtcGxlOiBgYXJuOmF3czprbXM6dXMtZWFzdC0xOjExMTEyMjIyMzMzMzprZXkvMTExYTIyMjItYTExYi0xYWIxLTJhYjItMWFiMjFhMmIzYTExMWAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1rZXlzaWduaW5na2V5Lmh0bWwjY2ZuLXJvdXRlNTMta2V5c2lnbmluZ2tleS1rZXltYW5hZ2VtZW50c2VydmljZWFyblxuICAgICAqL1xuICAgIHJlYWRvbmx5IGtleU1hbmFnZW1lbnRTZXJ2aWNlQXJuOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBIHN0cmluZyB1c2VkIHRvIGlkZW50aWZ5IGEga2V5LXNpZ25pbmcga2V5IChLU0spLiBgTmFtZWAgY2FuIGluY2x1ZGUgbnVtYmVycywgbGV0dGVycywgYW5kIHVuZGVyc2NvcmVzIChfKS4gYE5hbWVgIG11c3QgYmUgdW5pcXVlIGZvciBlYWNoIGtleS1zaWduaW5nIGtleSBpbiB0aGUgc2FtZSBob3N0ZWQgem9uZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMta2V5c2lnbmluZ2tleS5odG1sI2Nmbi1yb3V0ZTUzLWtleXNpZ25pbmdrZXktbmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEEgc3RyaW5nIHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBrZXktc2lnbmluZyBrZXkgKEtTSykgc3RhdHVzLlxuICAgICAqXG4gICAgICogU3RhdHVzIGNhbiBoYXZlIG9uZSBvZiB0aGUgZm9sbG93aW5nIHZhbHVlczpcbiAgICAgKlxuICAgICAqIC0gKipBQ1RJVkUqKiAtIFRoZSBLU0sgaXMgYmVpbmcgdXNlZCBmb3Igc2lnbmluZy5cbiAgICAgKiAtICoqSU5BQ1RJVkUqKiAtIFRoZSBLU0sgaXMgbm90IGJlaW5nIHVzZWQgZm9yIHNpZ25pbmcuXG4gICAgICogLSAqKkRFTEVUSU5HKiogLSBUaGUgS1NLIGlzIGluIHRoZSBwcm9jZXNzIG9mIGJlaW5nIGRlbGV0ZWQuXG4gICAgICogLSAqKkFDVElPTl9ORUVERUQqKiAtIFRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoZSBLU0sgdGhhdCByZXF1aXJlcyB5b3UgdG8gdGFrZSBhY3Rpb24gdG8gcmVzb2x2ZS4gRm9yIGV4YW1wbGUsIHRoZSBjdXN0b21lciBtYW5hZ2VkIGtleSBtaWdodCBoYXZlIGJlZW4gZGVsZXRlZCwgb3IgdGhlIHBlcm1pc3Npb25zIGZvciB0aGUgY3VzdG9tZXIgbWFuYWdlZCBrZXkgbWlnaHQgaGF2ZSBiZWVuIGNoYW5nZWQuXG4gICAgICogLSAqKklOVEVSTkFMX0ZBSUxVUkUqKiAtIFRoZXJlIHdhcyBhbiBlcnJvciBkdXJpbmcgYSByZXF1ZXN0LiBCZWZvcmUgeW91IGNhbiBjb250aW51ZSB0byB3b3JrIHdpdGggRE5TU0VDIHNpZ25pbmcsIGluY2x1ZGluZyBhY3Rpb25zIHRoYXQgaW52b2x2ZSB0aGlzIEtTSywgeW91IG11c3QgY29ycmVjdCB0aGUgcHJvYmxlbS4gRm9yIGV4YW1wbGUsIHlvdSBtYXkgbmVlZCB0byBhY3RpdmF0ZSBvciBkZWFjdGl2YXRlIHRoZSBLU0suXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWtleXNpZ25pbmdrZXkuaHRtbCNjZm4tcm91dGU1My1rZXlzaWduaW5na2V5LXN0YXR1c1xuICAgICAqL1xuICAgIHJlYWRvbmx5IHN0YXR1czogc3RyaW5nO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmbktleVNpZ25pbmdLZXlQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuS2V5U2lnbmluZ0tleVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmbktleVNpZ25pbmdLZXlQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hvc3RlZFpvbmVJZCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5ob3N0ZWRab25lSWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hvc3RlZFpvbmVJZCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5ob3N0ZWRab25lSWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2tleU1hbmFnZW1lbnRTZXJ2aWNlQXJuJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmtleU1hbmFnZW1lbnRTZXJ2aWNlQXJuKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdrZXlNYW5hZ2VtZW50U2VydmljZUFybicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5rZXlNYW5hZ2VtZW50U2VydmljZUFybikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5uYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCduYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLm5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3N0YXR1cycsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5zdGF0dXMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3N0YXR1cycsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5zdGF0dXMpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuS2V5U2lnbmluZ0tleVByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpLZXlTaWduaW5nS2V5YCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5LZXlTaWduaW5nS2V5UHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OktleVNpZ25pbmdLZXlgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuS2V5U2lnbmluZ0tleVByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5LZXlTaWduaW5nS2V5UHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEhvc3RlZFpvbmVJZDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5ob3N0ZWRab25lSWQpLFxuICAgICAgICBLZXlNYW5hZ2VtZW50U2VydmljZUFybjogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5rZXlNYW5hZ2VtZW50U2VydmljZUFybiksXG4gICAgICAgIE5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubmFtZSksXG4gICAgICAgIFN0YXR1czogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zdGF0dXMpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5LZXlTaWduaW5nS2V5UHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5LZXlTaWduaW5nS2V5UHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbktleVNpZ25pbmdLZXlQcm9wcz4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2hvc3RlZFpvbmVJZCcsICdIb3N0ZWRab25lSWQnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkhvc3RlZFpvbmVJZCkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgna2V5TWFuYWdlbWVudFNlcnZpY2VBcm4nLCAnS2V5TWFuYWdlbWVudFNlcnZpY2VBcm4nLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLktleU1hbmFnZW1lbnRTZXJ2aWNlQXJuKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCduYW1lJywgJ05hbWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLk5hbWUpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3N0YXR1cycsICdTdGF0dXMnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlN0YXR1cykpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6Um91dGU1Mzo6S2V5U2lnbmluZ0tleWBcbiAqXG4gKiBUaGUgYEFXUzo6Um91dGU1Mzo6S2V5U2lnbmluZ0tleWAgcmVzb3VyY2UgY3JlYXRlcyBhIG5ldyBrZXktc2lnbmluZyBrZXkgKEtTSykgaW4gYSBob3N0ZWQgem9uZS4gVGhlIGhvc3RlZCB6b25lIElEIGlzIHBhc3NlZCBhcyBhIHBhcmFtZXRlciBpbiB0aGUgS1NLIHByb3BlcnRpZXMuIFlvdSBjYW4gc3BlY2lmeSB0aGUgcHJvcGVydGllcyBvZiB0aGlzIEtTSyB1c2luZyB0aGUgYE5hbWVgICwgYFN0YXR1c2AgLCBhbmQgYEtleU1hbmFnZW1lbnRTZXJ2aWNlQXJuYCBwcm9wZXJ0aWVzIG9mIHRoZSByZXNvdXJjZS5cbiAqXG4gKiBAY2xvdWRmb3JtYXRpb25SZXNvdXJjZSBBV1M6OlJvdXRlNTM6OktleVNpZ25pbmdLZXlcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWtleXNpZ25pbmdrZXkuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuS2V5U2lnbmluZ0tleSBleHRlbmRzIGNkay5DZm5SZXNvdXJjZSBpbXBsZW1lbnRzIGNkay5JSW5zcGVjdGFibGUge1xuICAgIC8qKlxuICAgICAqIFRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSB0eXBlIG5hbWUgZm9yIHRoaXMgcmVzb3VyY2UgY2xhc3MuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBDRk5fUkVTT1VSQ0VfVFlQRV9OQU1FID0gXCJBV1M6OlJvdXRlNTM6OktleVNpZ25pbmdLZXlcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmbktleVNpZ25pbmdLZXkge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmbktleVNpZ25pbmdLZXlQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihyZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgQ2ZuS2V5U2lnbmluZ0tleShzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdW5pcXVlIHN0cmluZyAoSUQpIHRoYXQgaXMgdXNlZCB0byBpZGVudGlmeSBhIGhvc3RlZCB6b25lLiBGb3IgZXhhbXBsZTogYFowMDAwMTExMUExQUJDYWFBQkMxMWAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1rZXlzaWduaW5na2V5Lmh0bWwjY2ZuLXJvdXRlNTMta2V5c2lnbmluZ2tleS1ob3N0ZWR6b25laWRcbiAgICAgKi9cbiAgICBwdWJsaWMgaG9zdGVkWm9uZUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgQW1hem9uIHJlc291cmNlIG5hbWUgKEFSTikgZm9yIGEgY3VzdG9tZXIgbWFuYWdlZCBjdXN0b21lciBtYXN0ZXIga2V5IChDTUspIGluIEFXUyBLZXkgTWFuYWdlbWVudCBTZXJ2aWNlICggQVdTIEtNUyApLiBUaGUgYEtleU1hbmFnZW1lbnRTZXJ2aWNlQXJuYCBtdXN0IGJlIHVuaXF1ZSBmb3IgZWFjaCBrZXktc2lnbmluZyBrZXkgKEtTSykgaW4gYSBzaW5nbGUgaG9zdGVkIHpvbmUuIEZvciBleGFtcGxlOiBgYXJuOmF3czprbXM6dXMtZWFzdC0xOjExMTEyMjIyMzMzMzprZXkvMTExYTIyMjItYTExYi0xYWIxLTJhYjItMWFiMjFhMmIzYTExMWAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1rZXlzaWduaW5na2V5Lmh0bWwjY2ZuLXJvdXRlNTMta2V5c2lnbmluZ2tleS1rZXltYW5hZ2VtZW50c2VydmljZWFyblxuICAgICAqL1xuICAgIHB1YmxpYyBrZXlNYW5hZ2VtZW50U2VydmljZUFybjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBzdHJpbmcgdXNlZCB0byBpZGVudGlmeSBhIGtleS1zaWduaW5nIGtleSAoS1NLKS4gYE5hbWVgIGNhbiBpbmNsdWRlIG51bWJlcnMsIGxldHRlcnMsIGFuZCB1bmRlcnNjb3JlcyAoXykuIGBOYW1lYCBtdXN0IGJlIHVuaXF1ZSBmb3IgZWFjaCBrZXktc2lnbmluZyBrZXkgaW4gdGhlIHNhbWUgaG9zdGVkIHpvbmUuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWtleXNpZ25pbmdrZXkuaHRtbCNjZm4tcm91dGU1My1rZXlzaWduaW5na2V5LW5hbWVcbiAgICAgKi9cbiAgICBwdWJsaWMgbmFtZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBzdHJpbmcgdGhhdCByZXByZXNlbnRzIHRoZSBjdXJyZW50IGtleS1zaWduaW5nIGtleSAoS1NLKSBzdGF0dXMuXG4gICAgICpcbiAgICAgKiBTdGF0dXMgY2FuIGhhdmUgb25lIG9mIHRoZSBmb2xsb3dpbmcgdmFsdWVzOlxuICAgICAqXG4gICAgICogLSAqKkFDVElWRSoqIC0gVGhlIEtTSyBpcyBiZWluZyB1c2VkIGZvciBzaWduaW5nLlxuICAgICAqIC0gKipJTkFDVElWRSoqIC0gVGhlIEtTSyBpcyBub3QgYmVpbmcgdXNlZCBmb3Igc2lnbmluZy5cbiAgICAgKiAtICoqREVMRVRJTkcqKiAtIFRoZSBLU0sgaXMgaW4gdGhlIHByb2Nlc3Mgb2YgYmVpbmcgZGVsZXRlZC5cbiAgICAgKiAtICoqQUNUSU9OX05FRURFRCoqIC0gVGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggdGhlIEtTSyB0aGF0IHJlcXVpcmVzIHlvdSB0byB0YWtlIGFjdGlvbiB0byByZXNvbHZlLiBGb3IgZXhhbXBsZSwgdGhlIGN1c3RvbWVyIG1hbmFnZWQga2V5IG1pZ2h0IGhhdmUgYmVlbiBkZWxldGVkLCBvciB0aGUgcGVybWlzc2lvbnMgZm9yIHRoZSBjdXN0b21lciBtYW5hZ2VkIGtleSBtaWdodCBoYXZlIGJlZW4gY2hhbmdlZC5cbiAgICAgKiAtICoqSU5URVJOQUxfRkFJTFVSRSoqIC0gVGhlcmUgd2FzIGFuIGVycm9yIGR1cmluZyBhIHJlcXVlc3QuIEJlZm9yZSB5b3UgY2FuIGNvbnRpbnVlIHRvIHdvcmsgd2l0aCBETlNTRUMgc2lnbmluZywgaW5jbHVkaW5nIGFjdGlvbnMgdGhhdCBpbnZvbHZlIHRoaXMgS1NLLCB5b3UgbXVzdCBjb3JyZWN0IHRoZSBwcm9ibGVtLiBGb3IgZXhhbXBsZSwgeW91IG1heSBuZWVkIHRvIGFjdGl2YXRlIG9yIGRlYWN0aXZhdGUgdGhlIEtTSy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMta2V5c2lnbmluZ2tleS5odG1sI2Nmbi1yb3V0ZTUzLWtleXNpZ25pbmdrZXktc3RhdHVzXG4gICAgICovXG4gICAgcHVibGljIHN0YXR1czogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGBBV1M6OlJvdXRlNTM6OktleVNpZ25pbmdLZXlgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNjb3BlIC0gc2NvcGUgaW4gd2hpY2ggdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkXG4gICAgICogQHBhcmFtIGlkICAgIC0gc2NvcGVkIGlkIG9mIHRoZSByZXNvdXJjZVxuICAgICAqIEBwYXJhbSBwcm9wcyAtIHJlc291cmNlIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENmbktleVNpZ25pbmdLZXlQcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuS2V5U2lnbmluZ0tleS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ2hvc3RlZFpvbmVJZCcsIHRoaXMpO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAna2V5TWFuYWdlbWVudFNlcnZpY2VBcm4nLCB0aGlzKTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ25hbWUnLCB0aGlzKTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ3N0YXR1cycsIHRoaXMpO1xuXG4gICAgICAgIHRoaXMuaG9zdGVkWm9uZUlkID0gcHJvcHMuaG9zdGVkWm9uZUlkO1xuICAgICAgICB0aGlzLmtleU1hbmFnZW1lbnRTZXJ2aWNlQXJuID0gcHJvcHMua2V5TWFuYWdlbWVudFNlcnZpY2VBcm47XG4gICAgICAgIHRoaXMubmFtZSA9IHByb3BzLm5hbWU7XG4gICAgICAgIHRoaXMuc3RhdHVzID0gcHJvcHMuc3RhdHVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuS2V5U2lnbmluZ0tleS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FKTtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246cHJvcHNcIiwgdGhpcy5jZm5Qcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGNmblByb3BlcnRpZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaG9zdGVkWm9uZUlkOiB0aGlzLmhvc3RlZFpvbmVJZCxcbiAgICAgICAgICAgIGtleU1hbmFnZW1lbnRTZXJ2aWNlQXJuOiB0aGlzLmtleU1hbmFnZW1lbnRTZXJ2aWNlQXJuLFxuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICAgICAgc3RhdHVzOiB0aGlzLnN0YXR1cyxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5LZXlTaWduaW5nS2V5UHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuUmVjb3JkU2V0YFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5SZWNvcmRTZXRQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiBGb3IgYENoYW5nZVJlc291cmNlUmVjb3JkU2V0c2AgcmVxdWVzdHMsIHRoZSBuYW1lIG9mIHRoZSByZWNvcmQgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUsIHVwZGF0ZSwgb3IgZGVsZXRlLiBGb3IgYExpc3RSZXNvdXJjZVJlY29yZFNldHNgIHJlc3BvbnNlcywgdGhlIG5hbWUgb2YgYSByZWNvcmQgaW4gdGhlIHNwZWNpZmllZCBob3N0ZWQgem9uZS5cbiAgICAgKlxuICAgICAqICpDaGFuZ2VSZXNvdXJjZVJlY29yZFNldHMgT25seSpcbiAgICAgKlxuICAgICAqIEVudGVyIGEgZnVsbHkgcXVhbGlmaWVkIGRvbWFpbiBuYW1lLCBmb3IgZXhhbXBsZSwgYHd3dy5leGFtcGxlLmNvbWAgLiBZb3UgY2FuIG9wdGlvbmFsbHkgaW5jbHVkZSBhIHRyYWlsaW5nIGRvdC4gSWYgeW91IG9taXQgdGhlIHRyYWlsaW5nIGRvdCwgQW1hem9uIFJvdXRlIDUzIGFzc3VtZXMgdGhhdCB0aGUgZG9tYWluIG5hbWUgdGhhdCB5b3Ugc3BlY2lmeSBpcyBmdWxseSBxdWFsaWZpZWQuIFRoaXMgbWVhbnMgdGhhdCBSb3V0ZSA1MyB0cmVhdHMgYHd3dy5leGFtcGxlLmNvbWAgKHdpdGhvdXQgYSB0cmFpbGluZyBkb3QpIGFuZCBgd3d3LmV4YW1wbGUuY29tLmAgKHdpdGggYSB0cmFpbGluZyBkb3QpIGFzIGlkZW50aWNhbC5cbiAgICAgKlxuICAgICAqIEZvciBpbmZvcm1hdGlvbiBhYm91dCBob3cgdG8gc3BlY2lmeSBjaGFyYWN0ZXJzIG90aGVyIHRoYW4gYGEtemAgLCBgMC05YCAsIGFuZCBgLWAgKGh5cGhlbikgYW5kIGhvdyB0byBzcGVjaWZ5IGludGVybmF0aW9uYWxpemVkIGRvbWFpbiBuYW1lcywgc2VlIFtETlMgRG9tYWluIE5hbWUgRm9ybWF0XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvRG9tYWluTmFtZUZvcm1hdC5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIFlvdSBjYW4gdXNlIHRoZSBhc3RlcmlzayAoKikgd2lsZGNhcmQgdG8gcmVwbGFjZSB0aGUgbGVmdG1vc3QgbGFiZWwgaW4gYSBkb21haW4gbmFtZSwgZm9yIGV4YW1wbGUsIGAqLmV4YW1wbGUuY29tYCAuIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gVGhlICogbXVzdCByZXBsYWNlIHRoZSBlbnRpcmUgbGFiZWwuIEZvciBleGFtcGxlLCB5b3UgY2FuJ3Qgc3BlY2lmeSBgKnByb2QuZXhhbXBsZS5jb21gIG9yIGBwcm9kKi5leGFtcGxlLmNvbWAgLlxuICAgICAqIC0gVGhlICogY2FuJ3QgcmVwbGFjZSBhbnkgb2YgdGhlIG1pZGRsZSBsYWJlbHMsIGZvciBleGFtcGxlLCBtYXJrZXRpbmcuKi5leGFtcGxlLmNvbS5cbiAgICAgKiAtIElmIHlvdSBpbmNsdWRlICogaW4gYW55IHBvc2l0aW9uIG90aGVyIHRoYW4gdGhlIGxlZnRtb3N0IGxhYmVsIGluIGEgZG9tYWluIG5hbWUsIEROUyB0cmVhdHMgaXQgYXMgYW4gKiBjaGFyYWN0ZXIgKEFTQ0lJIDQyKSwgbm90IGFzIGEgd2lsZGNhcmQuXG4gICAgICpcbiAgICAgKiA+IFlvdSBjYW4ndCB1c2UgdGhlICogd2lsZGNhcmQgZm9yIHJlc291cmNlIHJlY29yZHMgc2V0cyB0aGF0IGhhdmUgYSB0eXBlIG9mIE5TLlxuICAgICAqXG4gICAgICogWW91IGNhbiB1c2UgdGhlICogd2lsZGNhcmQgYXMgdGhlIGxlZnRtb3N0IGxhYmVsIGluIGEgZG9tYWluIG5hbWUsIGZvciBleGFtcGxlLCBgKi5leGFtcGxlLmNvbWAgLiBZb3UgY2FuJ3QgdXNlIGFuICogZm9yIG9uZSBvZiB0aGUgbWlkZGxlIGxhYmVscywgZm9yIGV4YW1wbGUsIGBtYXJrZXRpbmcuKi5leGFtcGxlLmNvbWAgLiBJbiBhZGRpdGlvbiwgdGhlICogbXVzdCByZXBsYWNlIHRoZSBlbnRpcmUgbGFiZWw7IGZvciBleGFtcGxlLCB5b3UgY2FuJ3Qgc3BlY2lmeSBgcHJvZCouZXhhbXBsZS5jb21gIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtbmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBETlMgcmVjb3JkIHR5cGUuIEZvciBpbmZvcm1hdGlvbiBhYm91dCBkaWZmZXJlbnQgcmVjb3JkIHR5cGVzIGFuZCBob3cgZGF0YSBpcyBlbmNvZGVkIGZvciB0aGVtLCBzZWUgW1N1cHBvcnRlZCBETlMgUmVzb3VyY2UgUmVjb3JkIFR5cGVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvUmVzb3VyY2VSZWNvcmRUeXBlcy5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIFZhbGlkIHZhbHVlcyBmb3IgYmFzaWMgcmVzb3VyY2UgcmVjb3JkIHNldHM6IGBBYCB8IGBBQUFBYCB8IGBDQUFgIHwgYENOQU1FYCB8IGBEU2AgfCBgTVhgIHwgYE5BUFRSYCB8IGBOU2AgfCBgUFRSYCB8IGBTT0FgIHwgYFNQRmAgfCBgU1JWYCB8IGBUWFRgXG4gICAgICpcbiAgICAgKiBWYWx1ZXMgZm9yIHdlaWdodGVkLCBsYXRlbmN5LCBnZW9sb2NhdGlvbiwgYW5kIGZhaWxvdmVyIHJlc291cmNlIHJlY29yZCBzZXRzOiBgQWAgfCBgQUFBQWAgfCBgQ0FBYCB8IGBDTkFNRWAgfCBgTVhgIHwgYE5BUFRSYCB8IGBQVFJgIHwgYFNQRmAgfCBgU1JWYCB8IGBUWFRgIC4gV2hlbiBjcmVhdGluZyBhIGdyb3VwIG9mIHdlaWdodGVkLCBsYXRlbmN5LCBnZW9sb2NhdGlvbiwgb3IgZmFpbG92ZXIgcmVzb3VyY2UgcmVjb3JkIHNldHMsIHNwZWNpZnkgdGhlIHNhbWUgdmFsdWUgZm9yIGFsbCBvZiB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gdGhlIGdyb3VwLlxuICAgICAqXG4gICAgICogVmFsaWQgdmFsdWVzIGZvciBtdWx0aXZhbHVlIGFuc3dlciByZXNvdXJjZSByZWNvcmQgc2V0czogYEFgIHwgYEFBQUFgIHwgYE1YYCB8IGBOQVBUUmAgfCBgUFRSYCB8IGBTUEZgIHwgYFNSVmAgfCBgVFhUYFxuICAgICAqXG4gICAgICogPiBTUEYgcmVjb3JkcyB3ZXJlIGZvcm1lcmx5IHVzZWQgdG8gdmVyaWZ5IHRoZSBpZGVudGl0eSBvZiB0aGUgc2VuZGVyIG9mIGVtYWlsIG1lc3NhZ2VzLiBIb3dldmVyLCB3ZSBubyBsb25nZXIgcmVjb21tZW5kIHRoYXQgeW91IGNyZWF0ZSByZXNvdXJjZSByZWNvcmQgc2V0cyBmb3Igd2hpY2ggdGhlIHZhbHVlIG9mIGBUeXBlYCBpcyBgU1BGYCAuIFJGQyA3MjA4LCAqU2VuZGVyIFBvbGljeSBGcmFtZXdvcmsgKFNQRikgZm9yIEF1dGhvcml6aW5nIFVzZSBvZiBEb21haW5zIGluIEVtYWlsLCBWZXJzaW9uIDEqICwgaGFzIGJlZW4gdXBkYXRlZCB0byBzYXksIFwiLi4uW0lddHMgZXhpc3RlbmNlIGFuZCBtZWNoYW5pc20gZGVmaW5lZCBpbiBbUkZDNDQwOF0gaGF2ZSBsZWQgdG8gc29tZSBpbnRlcm9wZXJhYmlsaXR5IGlzc3Vlcy4gQWNjb3JkaW5nbHksIGl0cyB1c2UgaXMgbm8gbG9uZ2VyIGFwcHJvcHJpYXRlIGZvciBTUEYgdmVyc2lvbiAxOyBpbXBsZW1lbnRhdGlvbnMgYXJlIG5vdCB0byB1c2UgaXQuXCIgSW4gUkZDIDcyMDgsIHNlZSBzZWN0aW9uIDE0LjEsIFtUaGUgU1BGIEROUyBSZWNvcmQgVHlwZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzcyMDgjc2VjdGlvbi0xNC4xKSAuXG4gICAgICpcbiAgICAgKiBWYWx1ZXMgZm9yIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzOlxuICAgICAqXG4gICAgICogLSAqQW1hem9uIEFQSSBHYXRld2F5IGN1c3RvbSByZWdpb25hbCBBUElzIGFuZCBlZGdlLW9wdGltaXplZCBBUElzOiogYEFgXG4gICAgICogLSAqQ2xvdWRGcm9udCBkaXN0cmlidXRpb25zOiogYEFgXG4gICAgICpcbiAgICAgKiBJZiBJUHY2IGlzIGVuYWJsZWQgZm9yIHRoZSBkaXN0cmlidXRpb24sIGNyZWF0ZSB0d28gcmVzb3VyY2UgcmVjb3JkIHNldHMgdG8gcm91dGUgdHJhZmZpYyB0byB5b3VyIGRpc3RyaWJ1dGlvbiwgb25lIHdpdGggYSB2YWx1ZSBvZiBgQWAgYW5kIG9uZSB3aXRoIGEgdmFsdWUgb2YgYEFBQUFgIC5cbiAgICAgKiAtICpBbWF6b24gQVBJIEdhdGV3YXkgZW52aXJvbm1lbnQgdGhhdCBoYXMgYSByZWdpb25hbGl6ZWQgc3ViZG9tYWluKiA6IGBBYFxuICAgICAqIC0gKkVMQiBsb2FkIGJhbGFuY2VyczoqIGBBYCB8IGBBQUFBYFxuICAgICAqIC0gKkFtYXpvbiBTMyBidWNrZXRzOiogYEFgXG4gICAgICogLSAqQW1hem9uIFZpcnR1YWwgUHJpdmF0ZSBDbG91ZCBpbnRlcmZhY2UgVlBDIGVuZHBvaW50cyogYEFgXG4gICAgICogLSAqQW5vdGhlciByZXNvdXJjZSByZWNvcmQgc2V0IGluIHRoaXMgaG9zdGVkIHpvbmU6KiBTcGVjaWZ5IHRoZSB0eXBlIG9mIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0IHRoYXQgeW91J3JlIGNyZWF0aW5nIHRoZSBhbGlhcyBmb3IuIEFsbCB2YWx1ZXMgYXJlIHN1cHBvcnRlZCBleGNlcHQgYE5TYCBhbmQgYFNPQWAgLlxuICAgICAqXG4gICAgICogPiBJZiB5b3UncmUgY3JlYXRpbmcgYW4gYWxpYXMgcmVjb3JkIHRoYXQgaGFzIHRoZSBzYW1lIG5hbWUgYXMgdGhlIGhvc3RlZCB6b25lIChrbm93biBhcyB0aGUgem9uZSBhcGV4KSwgeW91IGNhbid0IHJvdXRlIHRyYWZmaWMgdG8gYSByZWNvcmQgZm9yIHdoaWNoIHRoZSB2YWx1ZSBvZiBgVHlwZWAgaXMgYENOQU1FYCAuIFRoaXMgaXMgYmVjYXVzZSB0aGUgYWxpYXMgcmVjb3JkIG11c3QgaGF2ZSB0aGUgc2FtZSB0eXBlIGFzIHRoZSByZWNvcmQgeW91J3JlIHJvdXRpbmcgdHJhZmZpYyB0bywgYW5kIGNyZWF0aW5nIGEgQ05BTUUgcmVjb3JkIGZvciB0aGUgem9uZSBhcGV4IGlzbid0IHN1cHBvcnRlZCBldmVuIGZvciBhbiBhbGlhcyByZWNvcmQuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LXR5cGVcbiAgICAgKi9cbiAgICByZWFkb25seSB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiAqQWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMgb25seToqIEluZm9ybWF0aW9uIGFib3V0IHRoZSBBV1MgcmVzb3VyY2UsIHN1Y2ggYXMgYSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbiBvciBhbiBBbWF6b24gUzMgYnVja2V0LCB0aGF0IHlvdSB3YW50IHRvIHJvdXRlIHRyYWZmaWMgdG8uXG4gICAgICpcbiAgICAgKiBJZiB5b3UncmUgY3JlYXRpbmcgcmVzb3VyY2UgcmVjb3JkcyBzZXRzIGZvciBhIHByaXZhdGUgaG9zdGVkIHpvbmUsIG5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gWW91IGNhbid0IGNyZWF0ZSBhbiBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0IGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSB0byByb3V0ZSB0cmFmZmljIHRvIGEgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24uXG4gICAgICogLSBDcmVhdGluZyBnZW9sb2NhdGlvbiBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0cyBvciBsYXRlbmN5IGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzIGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSBpcyB1bnN1cHBvcnRlZC5cbiAgICAgKiAtIEZvciBpbmZvcm1hdGlvbiBhYm91dCBjcmVhdGluZyBmYWlsb3ZlciByZXNvdXJjZSByZWNvcmQgc2V0cyBpbiBhIHByaXZhdGUgaG9zdGVkIHpvbmUsIHNlZSBbQ29uZmlndXJpbmcgRmFpbG92ZXIgaW4gYSBQcml2YXRlIEhvc3RlZCBab25lXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLXByaXZhdGUtaG9zdGVkLXpvbmVzLmh0bWwpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1hbGlhc3RhcmdldFxuICAgICAqL1xuICAgIHJlYWRvbmx5IGFsaWFzVGFyZ2V0PzogQ2ZuUmVjb3JkU2V0LkFsaWFzVGFyZ2V0UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiAqT3B0aW9uYWw6KiBBbnkgY29tbWVudHMgeW91IHdhbnQgdG8gaW5jbHVkZSBhYm91dCBhIGNoYW5nZSBiYXRjaCByZXF1ZXN0LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1jb21tZW50XG4gICAgICovXG4gICAgcmVhZG9ubHkgY29tbWVudD86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqICpGYWlsb3ZlciByZXNvdXJjZSByZWNvcmQgc2V0cyBvbmx5OiogVG8gY29uZmlndXJlIGZhaWxvdmVyLCB5b3UgYWRkIHRoZSBgRmFpbG92ZXJgIGVsZW1lbnQgdG8gdHdvIHJlc291cmNlIHJlY29yZCBzZXRzLiBGb3Igb25lIHJlc291cmNlIHJlY29yZCBzZXQsIHlvdSBzcGVjaWZ5IGBQUklNQVJZYCBhcyB0aGUgdmFsdWUgZm9yIGBGYWlsb3ZlcmAgOyBmb3IgdGhlIG90aGVyIHJlc291cmNlIHJlY29yZCBzZXQsIHlvdSBzcGVjaWZ5IGBTRUNPTkRBUllgIC4gSW4gYWRkaXRpb24sIHlvdSBpbmNsdWRlIHRoZSBgSGVhbHRoQ2hlY2tJZGAgZWxlbWVudCBhbmQgc3BlY2lmeSB0aGUgaGVhbHRoIGNoZWNrIHRoYXQgeW91IHdhbnQgQW1hem9uIFJvdXRlIDUzIHRvIHBlcmZvcm0gZm9yIGVhY2ggcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKlxuICAgICAqIEV4Y2VwdCB3aGVyZSBub3RlZCwgdGhlIGZvbGxvd2luZyBmYWlsb3ZlciBiZWhhdmlvcnMgYXNzdW1lIHRoYXQgeW91IGhhdmUgaW5jbHVkZWQgdGhlIGBIZWFsdGhDaGVja0lkYCBlbGVtZW50IGluIGJvdGggcmVzb3VyY2UgcmVjb3JkIHNldHM6XG4gICAgICpcbiAgICAgKiAtIFdoZW4gdGhlIHByaW1hcnkgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyBoZWFsdGh5LCBSb3V0ZSA1MyByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoIHRoZSBhcHBsaWNhYmxlIHZhbHVlIGZyb20gdGhlIHByaW1hcnkgcmVzb3VyY2UgcmVjb3JkIHNldCByZWdhcmRsZXNzIG9mIHRoZSBoZWFsdGggb2YgdGhlIHNlY29uZGFyeSByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqIC0gV2hlbiB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIHVuaGVhbHRoeSBhbmQgdGhlIHNlY29uZGFyeSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIGhlYWx0aHksIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdGhlIGFwcGxpY2FibGUgdmFsdWUgZnJvbSB0aGUgc2Vjb25kYXJ5IHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICogLSBXaGVuIHRoZSBzZWNvbmRhcnkgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdGhlIGFwcGxpY2FibGUgdmFsdWUgZnJvbSB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0IHJlZ2FyZGxlc3Mgb2YgdGhlIGhlYWx0aCBvZiB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqIC0gSWYgeW91IG9taXQgdGhlIGBIZWFsdGhDaGVja0lkYCBlbGVtZW50IGZvciB0aGUgc2Vjb25kYXJ5IHJlc291cmNlIHJlY29yZCBzZXQsIGFuZCBpZiB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgYWx3YXlzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdGhlIGFwcGxpY2FibGUgdmFsdWUgZnJvbSB0aGUgc2Vjb25kYXJ5IHJlc291cmNlIHJlY29yZCBzZXQuIFRoaXMgaXMgdHJ1ZSByZWdhcmRsZXNzIG9mIHRoZSBoZWFsdGggb2YgdGhlIGFzc29jaWF0ZWQgZW5kcG9pbnQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuJ3QgY3JlYXRlIG5vbi1mYWlsb3ZlciByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgdmFsdWVzIGZvciB0aGUgYE5hbWVgIGFuZCBgVHlwZWAgZWxlbWVudHMgYXMgZmFpbG92ZXIgcmVzb3VyY2UgcmVjb3JkIHNldHMuXG4gICAgICpcbiAgICAgKiBGb3IgZmFpbG92ZXIgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMsIHlvdSBtdXN0IGFsc28gaW5jbHVkZSB0aGUgYEV2YWx1YXRlVGFyZ2V0SGVhbHRoYCBlbGVtZW50IGFuZCBzZXQgdGhlIHZhbHVlIHRvIHRydWUuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBjb25maWd1cmluZyBmYWlsb3ZlciBmb3IgUm91dGUgNTMsIHNlZSB0aGUgZm9sbG93aW5nIHRvcGljcyBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIDpcbiAgICAgKlxuICAgICAqIC0gW1JvdXRlIDUzIEhlYWx0aCBDaGVja3MgYW5kIEROUyBGYWlsb3Zlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci5odG1sKVxuICAgICAqIC0gW0NvbmZpZ3VyaW5nIEZhaWxvdmVyIGluIGEgUHJpdmF0ZSBIb3N0ZWQgWm9uZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci1wcml2YXRlLWhvc3RlZC16b25lcy5odG1sKVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1mYWlsb3ZlclxuICAgICAqL1xuICAgIHJlYWRvbmx5IGZhaWxvdmVyPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogKkdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzIG9ubHk6KiBBIGNvbXBsZXggdHlwZSB0aGF0IGxldHMgeW91IGNvbnRyb2wgaG93IEFtYXpvbiBSb3V0ZSA1MyByZXNwb25kcyB0byBETlMgcXVlcmllcyBiYXNlZCBvbiB0aGUgZ2VvZ3JhcGhpYyBvcmlnaW4gb2YgdGhlIHF1ZXJ5LiBGb3IgZXhhbXBsZSwgaWYgeW91IHdhbnQgYWxsIHF1ZXJpZXMgZnJvbSBBZnJpY2EgdG8gYmUgcm91dGVkIHRvIGEgd2ViIHNlcnZlciB3aXRoIGFuIElQIGFkZHJlc3Mgb2YgYDE5Mi4wLjIuMTExYCAsIGNyZWF0ZSBhIHJlc291cmNlIHJlY29yZCBzZXQgd2l0aCBhIGBUeXBlYCBvZiBgQWAgYW5kIGEgYENvbnRpbmVudENvZGVgIG9mIGBBRmAgLlxuICAgICAqXG4gICAgICogPiBBbHRob3VnaCBjcmVhdGluZyBnZW9sb2NhdGlvbiBhbmQgZ2VvbG9jYXRpb24gYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gYSBwcml2YXRlIGhvc3RlZCB6b25lIGlzIGFsbG93ZWQsIGl0J3Mgbm90IHN1cHBvcnRlZC5cbiAgICAgKlxuICAgICAqIElmIHlvdSBjcmVhdGUgc2VwYXJhdGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgZm9yIG92ZXJsYXBwaW5nIGdlb2dyYXBoaWMgcmVnaW9ucyAoZm9yIGV4YW1wbGUsIG9uZSByZXNvdXJjZSByZWNvcmQgc2V0IGZvciBhIGNvbnRpbmVudCBhbmQgb25lIGZvciBhIGNvdW50cnkgb24gdGhlIHNhbWUgY29udGluZW50KSwgcHJpb3JpdHkgZ29lcyB0byB0aGUgc21hbGxlc3QgZ2VvZ3JhcGhpYyByZWdpb24uIFRoaXMgYWxsb3dzIHlvdSB0byByb3V0ZSBtb3N0IHF1ZXJpZXMgZm9yIGEgY29udGluZW50IHRvIG9uZSByZXNvdXJjZSBhbmQgdG8gcm91dGUgcXVlcmllcyBmb3IgYSBjb3VudHJ5IG9uIHRoYXQgY29udGluZW50IHRvIGEgZGlmZmVyZW50IHJlc291cmNlLlxuICAgICAqXG4gICAgICogWW91IGNhbid0IGNyZWF0ZSB0d28gZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBzcGVjaWZ5IHRoZSBzYW1lIGdlb2dyYXBoaWMgbG9jYXRpb24uXG4gICAgICpcbiAgICAgKiBUaGUgdmFsdWUgYCpgIGluIHRoZSBgQ291bnRyeUNvZGVgIGVsZW1lbnQgbWF0Y2hlcyBhbGwgZ2VvZ3JhcGhpYyBsb2NhdGlvbnMgdGhhdCBhcmVuJ3Qgc3BlY2lmaWVkIGluIG90aGVyIGdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSB2YWx1ZXMgZm9yIHRoZSBgTmFtZWAgYW5kIGBUeXBlYCBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqID4gR2VvbG9jYXRpb24gd29ya3MgYnkgbWFwcGluZyBJUCBhZGRyZXNzZXMgdG8gbG9jYXRpb25zLiBIb3dldmVyLCBzb21lIElQIGFkZHJlc3NlcyBhcmVuJ3QgbWFwcGVkIHRvIGdlb2dyYXBoaWMgbG9jYXRpb25zLCBzbyBldmVuIGlmIHlvdSBjcmVhdGUgZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBjb3ZlciBhbGwgc2V2ZW4gY29udGluZW50cywgUm91dGUgNTMgd2lsbCByZWNlaXZlIHNvbWUgRE5TIHF1ZXJpZXMgZnJvbSBsb2NhdGlvbnMgdGhhdCBpdCBjYW4ndCBpZGVudGlmeS4gV2UgcmVjb21tZW5kIHRoYXQgeW91IGNyZWF0ZSBhIHJlc291cmNlIHJlY29yZCBzZXQgZm9yIHdoaWNoIHRoZSB2YWx1ZSBvZiBgQ291bnRyeUNvZGVgIGlzIGAqYCAuIFR3byBncm91cHMgb2YgcXVlcmllcyBhcmUgcm91dGVkIHRvIHRoZSByZXNvdXJjZSB0aGF0IHlvdSBzcGVjaWZ5IGluIHRoaXMgcmVjb3JkOiBxdWVyaWVzIHRoYXQgY29tZSBmcm9tIGxvY2F0aW9ucyBmb3Igd2hpY2ggeW91IGhhdmVuJ3QgY3JlYXRlZCBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cyBhbmQgcXVlcmllcyBmcm9tIElQIGFkZHJlc3NlcyB0aGF0IGFyZW4ndCBtYXBwZWQgdG8gYSBsb2NhdGlvbi4gSWYgeW91IGRvbid0IGNyZWF0ZSBhIGAqYCByZXNvdXJjZSByZWNvcmQgc2V0LCBSb3V0ZSA1MyByZXR1cm5zIGEgXCJubyBhbnN3ZXJcIiByZXNwb25zZSBmb3IgcXVlcmllcyBmcm9tIHRob3NlIGxvY2F0aW9ucy5cbiAgICAgKlxuICAgICAqIFlvdSBjYW4ndCBjcmVhdGUgbm9uLWdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSB2YWx1ZXMgZm9yIHRoZSBgTmFtZWAgYW5kIGBUeXBlYCBlbGVtZW50cyBhcyBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtZ2VvbG9jYXRpb25cbiAgICAgKi9cbiAgICByZWFkb25seSBnZW9Mb2NhdGlvbj86IENmblJlY29yZFNldC5HZW9Mb2NhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogSWYgeW91IHdhbnQgQW1hem9uIFJvdXRlIDUzIHRvIHJldHVybiB0aGlzIHJlc291cmNlIHJlY29yZCBzZXQgaW4gcmVzcG9uc2UgdG8gYSBETlMgcXVlcnkgb25seSB3aGVuIHRoZSBzdGF0dXMgb2YgYSBoZWFsdGggY2hlY2sgaXMgaGVhbHRoeSwgaW5jbHVkZSB0aGUgYEhlYWx0aENoZWNrSWRgIGVsZW1lbnQgYW5kIHNwZWNpZnkgdGhlIElEIG9mIHRoZSBhcHBsaWNhYmxlIGhlYWx0aCBjaGVjay5cbiAgICAgKlxuICAgICAqIFJvdXRlIDUzIGRldGVybWluZXMgd2hldGhlciBhIHJlc291cmNlIHJlY29yZCBzZXQgaXMgaGVhbHRoeSBiYXNlZCBvbiBvbmUgb2YgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gQnkgcGVyaW9kaWNhbGx5IHNlbmRpbmcgYSByZXF1ZXN0IHRvIHRoZSBlbmRwb2ludCB0aGF0IGlzIHNwZWNpZmllZCBpbiB0aGUgaGVhbHRoIGNoZWNrXG4gICAgICogLSBCeSBhZ2dyZWdhdGluZyB0aGUgc3RhdHVzIG9mIGEgc3BlY2lmaWVkIGdyb3VwIG9mIGhlYWx0aCBjaGVja3MgKGNhbGN1bGF0ZWQgaGVhbHRoIGNoZWNrcylcbiAgICAgKiAtIEJ5IGRldGVybWluaW5nIHRoZSBjdXJyZW50IHN0YXRlIG9mIGEgQ2xvdWRXYXRjaCBhbGFybSAoQ2xvdWRXYXRjaCBtZXRyaWMgaGVhbHRoIGNoZWNrcylcbiAgICAgKlxuICAgICAqID4gUm91dGUgNTMgZG9lc24ndCBjaGVjayB0aGUgaGVhbHRoIG9mIHRoZSBlbmRwb2ludCB0aGF0IGlzIHNwZWNpZmllZCBpbiB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldCwgZm9yIGV4YW1wbGUsIHRoZSBlbmRwb2ludCBzcGVjaWZpZWQgYnkgdGhlIElQIGFkZHJlc3MgaW4gdGhlIGBWYWx1ZWAgZWxlbWVudC4gV2hlbiB5b3UgYWRkIGEgYEhlYWx0aENoZWNrSWRgIGVsZW1lbnQgdG8gYSByZXNvdXJjZSByZWNvcmQgc2V0LCBSb3V0ZSA1MyBjaGVja3MgdGhlIGhlYWx0aCBvZiB0aGUgZW5kcG9pbnQgdGhhdCB5b3Ugc3BlY2lmaWVkIGluIHRoZSBoZWFsdGggY2hlY2suXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIHRoZSBmb2xsb3dpbmcgdG9waWNzIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogOlxuICAgICAqXG4gICAgICogLSBbSG93IEFtYXpvbiBSb3V0ZSA1MyBEZXRlcm1pbmVzIFdoZXRoZXIgYW4gRW5kcG9pbnQgSXMgSGVhbHRoeV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci1kZXRlcm1pbmluZy1oZWFsdGgtb2YtZW5kcG9pbnRzLmh0bWwpXG4gICAgICogLSBbUm91dGUgNTMgSGVhbHRoIENoZWNrcyBhbmQgRE5TIEZhaWxvdmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLmh0bWwpXG4gICAgICogLSBbQ29uZmlndXJpbmcgRmFpbG92ZXIgaW4gYSBQcml2YXRlIEhvc3RlZCBab25lXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLXByaXZhdGUtaG9zdGVkLXpvbmVzLmh0bWwpXG4gICAgICpcbiAgICAgKiAqV2hlbiB0byBTcGVjaWZ5IEhlYWx0aENoZWNrSWQqXG4gICAgICpcbiAgICAgKiBTcGVjaWZ5aW5nIGEgdmFsdWUgZm9yIGBIZWFsdGhDaGVja0lkYCBpcyB1c2VmdWwgb25seSB3aGVuIFJvdXRlIDUzIGlzIGNob29zaW5nIGJldHdlZW4gdHdvIG9yIG1vcmUgcmVzb3VyY2UgcmVjb3JkIHNldHMgdG8gcmVzcG9uZCB0byBhIEROUyBxdWVyeSwgYW5kIHlvdSB3YW50IFJvdXRlIDUzIHRvIGJhc2UgdGhlIGNob2ljZSBpbiBwYXJ0IG9uIHRoZSBzdGF0dXMgb2YgYSBoZWFsdGggY2hlY2suIENvbmZpZ3VyaW5nIGhlYWx0aCBjaGVja3MgbWFrZXMgc2Vuc2Ugb25seSBpbiB0aGUgZm9sbG93aW5nIGNvbmZpZ3VyYXRpb25zOlxuICAgICAqXG4gICAgICogLSAqTm9uLWFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzKiA6IFlvdSdyZSBjaGVja2luZyB0aGUgaGVhbHRoIG9mIGEgZ3JvdXAgb2Ygbm9uLWFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSByb3V0aW5nIHBvbGljeSwgbmFtZSwgYW5kIHR5cGUgKHN1Y2ggYXMgbXVsdGlwbGUgd2VpZ2h0ZWQgcmVjb3JkcyBuYW1lZCB3d3cuZXhhbXBsZS5jb20gd2l0aCBhIHR5cGUgb2YgQSkgYW5kIHlvdSBzcGVjaWZ5IGhlYWx0aCBjaGVjayBJRHMgZm9yIGFsbCB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldHMuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgaGVhbHRoIGNoZWNrIHN0YXR1cyBmb3IgYSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIGhlYWx0aHksIFJvdXRlIDUzIGluY2x1ZGVzIHRoZSByZWNvcmQgYW1vbmcgdGhlIHJlY29yZHMgdGhhdCBpdCByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoLlxuICAgICAqXG4gICAgICogSWYgdGhlIGhlYWx0aCBjaGVjayBzdGF0dXMgZm9yIGEgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIHN0b3BzIHJlc3BvbmRpbmcgdG8gRE5TIHF1ZXJpZXMgdXNpbmcgdGhlIHZhbHVlIGZvciB0aGF0IHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgaGVhbHRoIGNoZWNrIHN0YXR1cyBmb3IgYWxsIHJlc291cmNlIHJlY29yZCBzZXRzIGluIHRoZSBncm91cCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIGNvbnNpZGVycyBhbGwgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gdGhlIGdyb3VwIGhlYWx0aHkgYW5kIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIGFjY29yZGluZ2x5LlxuICAgICAqIC0gKkFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzKiA6IFlvdSBzcGVjaWZ5IHRoZSBmb2xsb3dpbmcgc2V0dGluZ3M6XG4gICAgICpcbiAgICAgKiAtIFlvdSBzZXQgYEV2YWx1YXRlVGFyZ2V0SGVhbHRoYCB0byB0cnVlIGZvciBhbiBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0IGluIGEgZ3JvdXAgb2YgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIHJvdXRpbmcgcG9saWN5LCBuYW1lLCBhbmQgdHlwZSAoc3VjaCBhcyBtdWx0aXBsZSB3ZWlnaHRlZCByZWNvcmRzIG5hbWVkIHd3dy5leGFtcGxlLmNvbSB3aXRoIGEgdHlwZSBvZiBBKS5cbiAgICAgKiAtIFlvdSBjb25maWd1cmUgdGhlIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQgdG8gcm91dGUgdHJhZmZpYyB0byBhIG5vbi1hbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0IGluIHRoZSBzYW1lIGhvc3RlZCB6b25lLlxuICAgICAqIC0gWW91IHNwZWNpZnkgYSBoZWFsdGggY2hlY2sgSUQgZm9yIHRoZSBub24tYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKlxuICAgICAqIElmIHRoZSBoZWFsdGggY2hlY2sgc3RhdHVzIGlzIGhlYWx0aHksIFJvdXRlIDUzIGNvbnNpZGVycyB0aGUgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldCB0byBiZSBoZWFsdGh5IGFuZCBpbmNsdWRlcyB0aGUgYWxpYXMgcmVjb3JkIGFtb25nIHRoZSByZWNvcmRzIHRoYXQgaXQgcmVzcG9uZHMgdG8gRE5TIHF1ZXJpZXMgd2l0aC5cbiAgICAgKlxuICAgICAqIElmIHRoZSBoZWFsdGggY2hlY2sgc3RhdHVzIGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgc3RvcHMgcmVzcG9uZGluZyB0byBETlMgcXVlcmllcyB1c2luZyB0aGUgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKlxuICAgICAqID4gVGhlIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQgY2FuIGFsc28gcm91dGUgdHJhZmZpYyB0byBhICpncm91cCogb2Ygbm9uLWFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSByb3V0aW5nIHBvbGljeSwgbmFtZSwgYW5kIHR5cGUuIEluIHRoYXQgY29uZmlndXJhdGlvbiwgYXNzb2NpYXRlIGhlYWx0aCBjaGVja3Mgd2l0aCBhbGwgb2YgdGhlIHJlc291cmNlIHJlY29yZCBzZXRzIGluIHRoZSBncm91cCBvZiBub24tYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMuXG4gICAgICpcbiAgICAgKiAqR2VvbG9jYXRpb24gUm91dGluZypcbiAgICAgKlxuICAgICAqIEZvciBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cywgaWYgYW4gZW5kcG9pbnQgaXMgdW5oZWFsdGh5LCBSb3V0ZSA1MyBsb29rcyBmb3IgYSByZXNvdXJjZSByZWNvcmQgc2V0IGZvciB0aGUgbGFyZ2VyLCBhc3NvY2lhdGVkIGdlb2dyYXBoaWMgcmVnaW9uLiBGb3IgZXhhbXBsZSwgc3VwcG9zZSB5b3UgaGF2ZSByZXNvdXJjZSByZWNvcmQgc2V0cyBmb3IgYSBzdGF0ZSBpbiB0aGUgVW5pdGVkIFN0YXRlcywgZm9yIHRoZSBlbnRpcmUgVW5pdGVkIFN0YXRlcywgZm9yIE5vcnRoIEFtZXJpY2EsIGFuZCBhIHJlc291cmNlIHJlY29yZCBzZXQgdGhhdCBoYXMgYCpgIGZvciBgQ291bnRyeUNvZGVgIGlzIGAqYCAsIHdoaWNoIGFwcGxpZXMgdG8gYWxsIGxvY2F0aW9ucy4gSWYgdGhlIGVuZHBvaW50IGZvciB0aGUgc3RhdGUgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIGNoZWNrcyBmb3IgaGVhbHRoeSByZXNvdXJjZSByZWNvcmQgc2V0cyBpbiB0aGUgZm9sbG93aW5nIG9yZGVyIHVudGlsIGl0IGZpbmRzIGEgcmVzb3VyY2UgcmVjb3JkIHNldCBmb3Igd2hpY2ggdGhlIGVuZHBvaW50IGlzIGhlYWx0aHk6XG4gICAgICpcbiAgICAgKiAtIFRoZSBVbml0ZWQgU3RhdGVzXG4gICAgICogLSBOb3J0aCBBbWVyaWNhXG4gICAgICogLSBUaGUgZGVmYXVsdCByZXNvdXJjZSByZWNvcmQgc2V0XG4gICAgICpcbiAgICAgKiAqU3BlY2lmeWluZyB0aGUgSGVhbHRoIENoZWNrIEVuZHBvaW50IGJ5IERvbWFpbiBOYW1lKlxuICAgICAqXG4gICAgICogSWYgeW91ciBoZWFsdGggY2hlY2tzIHNwZWNpZnkgdGhlIGVuZHBvaW50IG9ubHkgYnkgZG9tYWluIG5hbWUsIHdlIHJlY29tbWVuZCB0aGF0IHlvdSBjcmVhdGUgYSBzZXBhcmF0ZSBoZWFsdGggY2hlY2sgZm9yIGVhY2ggZW5kcG9pbnQuIEZvciBleGFtcGxlLCBjcmVhdGUgYSBoZWFsdGggY2hlY2sgZm9yIGVhY2ggYEhUVFBgIHNlcnZlciB0aGF0IGlzIHNlcnZpbmcgY29udGVudCBmb3IgYHd3dy5leGFtcGxlLmNvbWAgLiBGb3IgdGhlIHZhbHVlIG9mIGBGdWxseVF1YWxpZmllZERvbWFpbk5hbWVgICwgc3BlY2lmeSB0aGUgZG9tYWluIG5hbWUgb2YgdGhlIHNlcnZlciAoc3VjaCBhcyBgdXMtZWFzdC0yLXd3dy5leGFtcGxlLmNvbWAgKSwgbm90IHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0cyAoIGB3d3cuZXhhbXBsZS5jb21gICkuXG4gICAgICpcbiAgICAgKiA+IEhlYWx0aCBjaGVjayByZXN1bHRzIHdpbGwgYmUgdW5wcmVkaWN0YWJsZSBpZiB5b3UgZG8gdGhlIGZvbGxvd2luZzpcbiAgICAgKiA+XG4gICAgICogPiAtIENyZWF0ZSBhIGhlYWx0aCBjaGVjayB0aGF0IGhhcyB0aGUgc2FtZSB2YWx1ZSBmb3IgYEZ1bGx5UXVhbGlmaWVkRG9tYWluTmFtZWAgYXMgdGhlIG5hbWUgb2YgYSByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqID4gLSBBc3NvY2lhdGUgdGhhdCBoZWFsdGggY2hlY2sgd2l0aCB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtaGVhbHRoY2hlY2tpZFxuICAgICAqL1xuICAgIHJlYWRvbmx5IGhlYWx0aENoZWNrSWQ/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgSUQgb2YgdGhlIGhvc3RlZCB6b25lIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlIHJlY29yZHMgaW4uXG4gICAgICpcbiAgICAgKiBTcGVjaWZ5IGVpdGhlciBgSG9zdGVkWm9uZU5hbWVgIG9yIGBIb3N0ZWRab25lSWRgICwgYnV0IG5vdCBib3RoLiBJZiB5b3UgaGF2ZSBtdWx0aXBsZSBob3N0ZWQgem9uZXMgd2l0aCB0aGUgc2FtZSBkb21haW4gbmFtZSwgeW91IG11c3Qgc3BlY2lmeSB0aGUgaG9zdGVkIHpvbmUgdXNpbmcgYEhvc3RlZFpvbmVJZGAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1ob3N0ZWR6b25laWRcbiAgICAgKi9cbiAgICByZWFkb25seSBob3N0ZWRab25lSWQ/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgaG9zdGVkIHpvbmUgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUgcmVjb3JkcyBpbi4gWW91IG11c3QgaW5jbHVkZSBhIHRyYWlsaW5nIGRvdCAoZm9yIGV4YW1wbGUsIGB3d3cuZXhhbXBsZS5jb20uYCApIGFzIHBhcnQgb2YgdGhlIGBIb3N0ZWRab25lTmFtZWAgLlxuICAgICAqXG4gICAgICogV2hlbiB5b3UgY3JlYXRlIGEgc3RhY2sgdXNpbmcgYW4gQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXQgdGhhdCBzcGVjaWZpZXMgYEhvc3RlZFpvbmVOYW1lYCAsIEFXUyBDbG91ZEZvcm1hdGlvbiBhdHRlbXB0cyB0byBmaW5kIGEgaG9zdGVkIHpvbmUgd2hvc2UgbmFtZSBtYXRjaGVzIHRoZSBIb3N0ZWRab25lTmFtZS4gSWYgQVdTIENsb3VkRm9ybWF0aW9uIGNhbm5vdCBmaW5kIGEgaG9zdGVkIHpvbmUgd2l0aCBhIG1hdGNoaW5nIGRvbWFpbiBuYW1lLCBvciBpZiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIGhvc3RlZCB6b25lIHdpdGggdGhlIHNwZWNpZmllZCBkb21haW4gbmFtZSwgQVdTIENsb3VkRm9ybWF0aW9uIHdpbGwgbm90IGNyZWF0ZSB0aGUgc3RhY2suXG4gICAgICpcbiAgICAgKiBTcGVjaWZ5IGVpdGhlciBgSG9zdGVkWm9uZU5hbWVgIG9yIGBIb3N0ZWRab25lSWRgICwgYnV0IG5vdCBib3RoLiBJZiB5b3UgaGF2ZSBtdWx0aXBsZSBob3N0ZWQgem9uZXMgd2l0aCB0aGUgc2FtZSBkb21haW4gbmFtZSwgeW91IG11c3Qgc3BlY2lmeSB0aGUgaG9zdGVkIHpvbmUgdXNpbmcgYEhvc3RlZFpvbmVJZGAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1ob3N0ZWR6b25lbmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IGhvc3RlZFpvbmVOYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogKk11bHRpdmFsdWUgYW5zd2VyIHJlc291cmNlIHJlY29yZCBzZXRzIG9ubHkqIDogVG8gcm91dGUgdHJhZmZpYyBhcHByb3hpbWF0ZWx5IHJhbmRvbWx5IHRvIG11bHRpcGxlIHJlc291cmNlcywgc3VjaCBhcyB3ZWIgc2VydmVycywgY3JlYXRlIG9uZSBtdWx0aXZhbHVlIGFuc3dlciByZWNvcmQgZm9yIGVhY2ggcmVzb3VyY2UgYW5kIHNwZWNpZnkgYHRydWVgIGZvciBgTXVsdGlWYWx1ZUFuc3dlcmAgLiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIElmIHlvdSBhc3NvY2lhdGUgYSBoZWFsdGggY2hlY2sgd2l0aCBhIG11bHRpdmFsdWUgYW5zd2VyIHJlc291cmNlIHJlY29yZCBzZXQsIEFtYXpvbiBSb3V0ZSA1MyByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIElQIGFkZHJlc3Mgb25seSB3aGVuIHRoZSBoZWFsdGggY2hlY2sgaXMgaGVhbHRoeS5cbiAgICAgKiAtIElmIHlvdSBkb24ndCBhc3NvY2lhdGUgYSBoZWFsdGggY2hlY2sgd2l0aCBhIG11bHRpdmFsdWUgYW5zd2VyIHJlY29yZCwgUm91dGUgNTMgYWx3YXlzIGNvbnNpZGVycyB0aGUgcmVjb3JkIHRvIGJlIGhlYWx0aHkuXG4gICAgICogLSBSb3V0ZSA1MyByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoIHVwIHRvIGVpZ2h0IGhlYWx0aHkgcmVjb3JkczsgaWYgeW91IGhhdmUgZWlnaHQgb3IgZmV3ZXIgaGVhbHRoeSByZWNvcmRzLCBSb3V0ZSA1MyByZXNwb25kcyB0byBhbGwgRE5TIHF1ZXJpZXMgd2l0aCBhbGwgdGhlIGhlYWx0aHkgcmVjb3Jkcy5cbiAgICAgKiAtIElmIHlvdSBoYXZlIG1vcmUgdGhhbiBlaWdodCBoZWFsdGh5IHJlY29yZHMsIFJvdXRlIDUzIHJlc3BvbmRzIHRvIGRpZmZlcmVudCBETlMgcmVzb2x2ZXJzIHdpdGggZGlmZmVyZW50IGNvbWJpbmF0aW9ucyBvZiBoZWFsdGh5IHJlY29yZHMuXG4gICAgICogLSBXaGVuIGFsbCByZWNvcmRzIGFyZSB1bmhlYWx0aHksIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdXAgdG8gZWlnaHQgdW5oZWFsdGh5IHJlY29yZHMuXG4gICAgICogLSBJZiBhIHJlc291cmNlIGJlY29tZXMgdW5hdmFpbGFibGUgYWZ0ZXIgYSByZXNvbHZlciBjYWNoZXMgYSByZXNwb25zZSwgY2xpZW50IHNvZnR3YXJlIHR5cGljYWxseSB0cmllcyBhbm90aGVyIG9mIHRoZSBJUCBhZGRyZXNzZXMgaW4gdGhlIHJlc3BvbnNlLlxuICAgICAqXG4gICAgICogWW91IGNhbid0IGNyZWF0ZSBtdWx0aXZhbHVlIGFuc3dlciBhbGlhcyByZWNvcmRzLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1tdWx0aXZhbHVlYW5zd2VyXG4gICAgICovXG4gICAgcmVhZG9ubHkgbXVsdGlWYWx1ZUFuc3dlcj86IGJvb2xlYW4gfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiAqTGF0ZW5jeS1iYXNlZCByZXNvdXJjZSByZWNvcmQgc2V0cyBvbmx5OiogVGhlIEFtYXpvbiBFQzIgUmVnaW9uIHdoZXJlIHlvdSBjcmVhdGVkIHRoZSByZXNvdXJjZSB0aGF0IHRoaXMgcmVzb3VyY2UgcmVjb3JkIHNldCByZWZlcnMgdG8uIFRoZSByZXNvdXJjZSB0eXBpY2FsbHkgaXMgYW4gQVdTIHJlc291cmNlLCBzdWNoIGFzIGFuIEVDMiBpbnN0YW5jZSBvciBhbiBFTEIgbG9hZCBiYWxhbmNlciwgYW5kIGlzIHJlZmVycmVkIHRvIGJ5IGFuIElQIGFkZHJlc3Mgb3IgYSBETlMgZG9tYWluIG5hbWUsIGRlcGVuZGluZyBvbiB0aGUgcmVjb3JkIHR5cGUuXG4gICAgICpcbiAgICAgKiA+IEFsdGhvdWdoIGNyZWF0aW5nIGxhdGVuY3kgYW5kIGxhdGVuY3kgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gYSBwcml2YXRlIGhvc3RlZCB6b25lIGlzIGFsbG93ZWQsIGl0J3Mgbm90IHN1cHBvcnRlZC5cbiAgICAgKlxuICAgICAqIFdoZW4gQW1hem9uIFJvdXRlIDUzIHJlY2VpdmVzIGEgRE5TIHF1ZXJ5IGZvciBhIGRvbWFpbiBuYW1lIGFuZCB0eXBlIGZvciB3aGljaCB5b3UgaGF2ZSBjcmVhdGVkIGxhdGVuY3kgcmVzb3VyY2UgcmVjb3JkIHNldHMsIFJvdXRlIDUzIHNlbGVjdHMgdGhlIGxhdGVuY3kgcmVzb3VyY2UgcmVjb3JkIHNldCB0aGF0IGhhcyB0aGUgbG93ZXN0IGxhdGVuY3kgYmV0d2VlbiB0aGUgZW5kIHVzZXIgYW5kIHRoZSBhc3NvY2lhdGVkIEFtYXpvbiBFQzIgUmVnaW9uLiBSb3V0ZSA1MyB0aGVuIHJldHVybnMgdGhlIHZhbHVlIHRoYXQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBzZWxlY3RlZCByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqXG4gICAgICogTm90ZSB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBZb3UgY2FuIG9ubHkgc3BlY2lmeSBvbmUgYFJlc291cmNlUmVjb3JkYCBwZXIgbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqIC0gWW91IGNhbiBvbmx5IGNyZWF0ZSBvbmUgbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0IGZvciBlYWNoIEFtYXpvbiBFQzIgUmVnaW9uLlxuICAgICAqIC0gWW91IGFyZW4ndCByZXF1aXJlZCB0byBjcmVhdGUgbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0cyBmb3IgYWxsIEFtYXpvbiBFQzIgUmVnaW9ucy4gUm91dGUgNTMgd2lsbCBjaG9vc2UgdGhlIHJlZ2lvbiB3aXRoIHRoZSBiZXN0IGxhdGVuY3kgZnJvbSBhbW9uZyB0aGUgcmVnaW9ucyB0aGF0IHlvdSBjcmVhdGUgbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0cyBmb3IuXG4gICAgICogLSBZb3UgY2FuJ3QgY3JlYXRlIG5vbi1sYXRlbmN5IHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSB2YWx1ZXMgZm9yIHRoZSBgTmFtZWAgYW5kIGBUeXBlYCBlbGVtZW50cyBhcyBsYXRlbmN5IHJlc291cmNlIHJlY29yZCBzZXRzLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1yZWdpb25cbiAgICAgKi9cbiAgICByZWFkb25seSByZWdpb24/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBPbmUgb3IgbW9yZSB2YWx1ZXMgdGhhdCBjb3JyZXNwb25kIHdpdGggdGhlIHZhbHVlIHRoYXQgeW91IHNwZWNpZmllZCBmb3IgdGhlIGBUeXBlYCBwcm9wZXJ0eS4gRm9yIGV4YW1wbGUsIGlmIHlvdSBzcGVjaWZpZWQgYEFgIGZvciBgVHlwZWAgLCB5b3Ugc3BlY2lmeSBvbmUgb3IgbW9yZSBJUCBhZGRyZXNzZXMgaW4gSVB2NCBmb3JtYXQgZm9yIGBSZXNvdXJjZVJlY29yZHNgIC4gRm9yIGluZm9ybWF0aW9uIGFib3V0IHRoZSBmb3JtYXQgb2YgdmFsdWVzIGZvciBlYWNoIHJlY29yZCB0eXBlLCBzZWUgW1N1cHBvcnRlZCBETlMgUmVzb3VyY2UgUmVjb3JkIFR5cGVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvUmVzb3VyY2VSZWNvcmRUeXBlcy5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gWW91IGNhbiBzcGVjaWZ5IG1vcmUgdGhhbiBvbmUgdmFsdWUgZm9yIGFsbCByZWNvcmQgdHlwZXMgZXhjZXB0IENOQU1FIGFuZCBTT0EuXG4gICAgICogLSBUaGUgbWF4aW11bSBsZW5ndGggb2YgYSB2YWx1ZSBpcyA0MDAwIGNoYXJhY3RlcnMuXG4gICAgICogLSBJZiB5b3UncmUgY3JlYXRpbmcgYW4gYWxpYXMgcmVjb3JkLCBvbWl0IGBSZXNvdXJjZVJlY29yZHNgIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtcmVzb3VyY2VyZWNvcmRzXG4gICAgICovXG4gICAgcmVhZG9ubHkgcmVzb3VyY2VSZWNvcmRzPzogc3RyaW5nW107XG5cbiAgICAvKipcbiAgICAgKiAqUmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIGEgcm91dGluZyBwb2xpY3kgb3RoZXIgdGhhbiBzaW1wbGU6KiBBbiBpZGVudGlmaWVyIHRoYXQgZGlmZmVyZW50aWF0ZXMgYW1vbmcgbXVsdGlwbGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIGNvbWJpbmF0aW9uIG9mIG5hbWUgYW5kIHR5cGUsIHN1Y2ggYXMgbXVsdGlwbGUgd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMgbmFtZWQgYWNtZS5leGFtcGxlLmNvbSB0aGF0IGhhdmUgYSB0eXBlIG9mIEEuIEluIGEgZ3JvdXAgb2YgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIG5hbWUgYW5kIHR5cGUsIHRoZSB2YWx1ZSBvZiBgU2V0SWRlbnRpZmllcmAgbXVzdCBiZSB1bmlxdWUgZm9yIGVhY2ggcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKlxuICAgICAqIEZvciBpbmZvcm1hdGlvbiBhYm91dCByb3V0aW5nIHBvbGljaWVzLCBzZWUgW0Nob29zaW5nIGEgUm91dGluZyBQb2xpY3ldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9yb3V0aW5nLXBvbGljeS5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtc2V0aWRlbnRpZmllclxuICAgICAqL1xuICAgIHJlYWRvbmx5IHNldElkZW50aWZpZXI/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVzb3VyY2UgcmVjb3JkIGNhY2hlIHRpbWUgdG8gbGl2ZSAoVFRMKSwgaW4gc2Vjb25kcy4gTm90ZSB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBJZiB5b3UncmUgY3JlYXRpbmcgb3IgdXBkYXRpbmcgYW4gYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldCwgb21pdCBgVFRMYCAuIEFtYXpvbiBSb3V0ZSA1MyB1c2VzIHRoZSB2YWx1ZSBvZiBgVFRMYCBmb3IgdGhlIGFsaWFzIHRhcmdldC5cbiAgICAgKiAtIElmIHlvdSdyZSBhc3NvY2lhdGluZyB0aGlzIHJlc291cmNlIHJlY29yZCBzZXQgd2l0aCBhIGhlYWx0aCBjaGVjayAoaWYgeW91J3JlIGFkZGluZyBhIGBIZWFsdGhDaGVja0lkYCBlbGVtZW50KSwgd2UgcmVjb21tZW5kIHRoYXQgeW91IHNwZWNpZnkgYSBgVFRMYCBvZiA2MCBzZWNvbmRzIG9yIGxlc3Mgc28gY2xpZW50cyByZXNwb25kIHF1aWNrbHkgdG8gY2hhbmdlcyBpbiBoZWFsdGggc3RhdHVzLlxuICAgICAqIC0gQWxsIG9mIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0cyBpbiBhIGdyb3VwIG9mIHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXRzIG11c3QgaGF2ZSB0aGUgc2FtZSB2YWx1ZSBmb3IgYFRUTGAgLlxuICAgICAqIC0gSWYgYSBncm91cCBvZiB3ZWlnaHRlZCByZXNvdXJjZSByZWNvcmQgc2V0cyBpbmNsdWRlcyBvbmUgb3IgbW9yZSB3ZWlnaHRlZCBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0cyBmb3Igd2hpY2ggdGhlIGFsaWFzIHRhcmdldCBpcyBhbiBFTEIgbG9hZCBiYWxhbmNlciwgd2UgcmVjb21tZW5kIHRoYXQgeW91IHNwZWNpZnkgYSBgVFRMYCBvZiA2MCBzZWNvbmRzIGZvciBhbGwgb2YgdGhlIG5vbi1hbGlhcyB3ZWlnaHRlZCByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgbmFtZSBhbmQgdHlwZS4gVmFsdWVzIG90aGVyIHRoYW4gNjAgc2Vjb25kcyAodGhlIFRUTCBmb3IgbG9hZCBiYWxhbmNlcnMpIHdpbGwgY2hhbmdlIHRoZSBlZmZlY3Qgb2YgdGhlIHZhbHVlcyB0aGF0IHlvdSBzcGVjaWZ5IGZvciBgV2VpZ2h0YCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LXR0bFxuICAgICAqL1xuICAgIHJlYWRvbmx5IHR0bD86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqICpXZWlnaHRlZCByZXNvdXJjZSByZWNvcmQgc2V0cyBvbmx5OiogQW1vbmcgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIGNvbWJpbmF0aW9uIG9mIEROUyBuYW1lIGFuZCB0eXBlLCBhIHZhbHVlIHRoYXQgZGV0ZXJtaW5lcyB0aGUgcHJvcG9ydGlvbiBvZiBETlMgcXVlcmllcyB0aGF0IEFtYXpvbiBSb3V0ZSA1MyByZXNwb25kcyB0byB1c2luZyB0aGUgY3VycmVudCByZXNvdXJjZSByZWNvcmQgc2V0LiBSb3V0ZSA1MyBjYWxjdWxhdGVzIHRoZSBzdW0gb2YgdGhlIHdlaWdodHMgZm9yIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgY29tYmluYXRpb24gb2YgRE5TIG5hbWUgYW5kIHR5cGUuIFJvdXRlIDUzIHRoZW4gcmVzcG9uZHMgdG8gcXVlcmllcyBiYXNlZCBvbiB0aGUgcmF0aW8gb2YgYSByZXNvdXJjZSdzIHdlaWdodCB0byB0aGUgdG90YWwuIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gWW91IG11c3Qgc3BlY2lmeSBhIHZhbHVlIGZvciB0aGUgYFdlaWdodGAgZWxlbWVudCBmb3IgZXZlcnkgd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKiAtIFlvdSBjYW4gb25seSBzcGVjaWZ5IG9uZSBgUmVzb3VyY2VSZWNvcmRgIHBlciB3ZWlnaHRlZCByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqIC0gWW91IGNhbid0IGNyZWF0ZSBsYXRlbmN5LCBmYWlsb3Zlciwgb3IgZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIHZhbHVlcyBmb3IgdGhlIGBOYW1lYCBhbmQgYFR5cGVgIGVsZW1lbnRzIGFzIHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXRzLlxuICAgICAqIC0gWW91IGNhbiBjcmVhdGUgYSBtYXhpbXVtIG9mIDEwMCB3ZWlnaHRlZCByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgdmFsdWVzIGZvciB0aGUgYE5hbWVgIGFuZCBgVHlwZWAgZWxlbWVudHMuXG4gICAgICogLSBGb3Igd2VpZ2h0ZWQgKGJ1dCBub3Qgd2VpZ2h0ZWQgYWxpYXMpIHJlc291cmNlIHJlY29yZCBzZXRzLCBpZiB5b3Ugc2V0IGBXZWlnaHRgIHRvIGAwYCBmb3IgYSByZXNvdXJjZSByZWNvcmQgc2V0LCBSb3V0ZSA1MyBuZXZlciByZXNwb25kcyB0byBxdWVyaWVzIHdpdGggdGhlIGFwcGxpY2FibGUgdmFsdWUgZm9yIHRoYXQgcmVzb3VyY2UgcmVjb3JkIHNldC4gSG93ZXZlciwgaWYgeW91IHNldCBgV2VpZ2h0YCB0byBgMGAgZm9yIGFsbCByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgY29tYmluYXRpb24gb2YgRE5TIG5hbWUgYW5kIHR5cGUsIHRyYWZmaWMgaXMgcm91dGVkIHRvIGFsbCByZXNvdXJjZXMgd2l0aCBlcXVhbCBwcm9iYWJpbGl0eS5cbiAgICAgKlxuICAgICAqIFRoZSBlZmZlY3Qgb2Ygc2V0dGluZyBgV2VpZ2h0YCB0byBgMGAgaXMgZGlmZmVyZW50IHdoZW4geW91IGFzc29jaWF0ZSBoZWFsdGggY2hlY2tzIHdpdGggd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW09wdGlvbnMgZm9yIENvbmZpZ3VyaW5nIFJvdXRlIDUzIEFjdGl2ZS1BY3RpdmUgYW5kIEFjdGl2ZS1QYXNzaXZlIEZhaWxvdmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLWNvbmZpZ3VyaW5nLW9wdGlvbnMuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LXdlaWdodFxuICAgICAqL1xuICAgIHJlYWRvbmx5IHdlaWdodD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDZm5SZWNvcmRTZXRQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuUmVjb3JkU2V0UHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuUmVjb3JkU2V0UHJvcHNWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdhbGlhc1RhcmdldCcsIENmblJlY29yZFNldF9BbGlhc1RhcmdldFByb3BlcnR5VmFsaWRhdG9yKShwcm9wZXJ0aWVzLmFsaWFzVGFyZ2V0KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjb21tZW50JywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmNvbW1lbnQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2ZhaWxvdmVyJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmZhaWxvdmVyKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdnZW9Mb2NhdGlvbicsIENmblJlY29yZFNldF9HZW9Mb2NhdGlvblByb3BlcnR5VmFsaWRhdG9yKShwcm9wZXJ0aWVzLmdlb0xvY2F0aW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdoZWFsdGhDaGVja0lkJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmhlYWx0aENoZWNrSWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hvc3RlZFpvbmVJZCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5ob3N0ZWRab25lSWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hvc3RlZFpvbmVOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmhvc3RlZFpvbmVOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdtdWx0aVZhbHVlQW5zd2VyJywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5tdWx0aVZhbHVlQW5zd2VyKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCduYW1lJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLm5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ25hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMubmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncmVnaW9uJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnJlZ2lvbikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncmVzb3VyY2VSZWNvcmRzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5yZXNvdXJjZVJlY29yZHMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3NldElkZW50aWZpZXInLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuc2V0SWRlbnRpZmllcikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndHRsJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnR0bCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndHlwZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy50eXBlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0eXBlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnR5cGUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3dlaWdodCcsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy53ZWlnaHQpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuUmVjb3JkU2V0UHJvcHNcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldGAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuUmVjb3JkU2V0UHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldGAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5SZWNvcmRTZXRQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuUmVjb3JkU2V0UHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIE5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubmFtZSksXG4gICAgICAgIFR5cGU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMudHlwZSksXG4gICAgICAgIEFsaWFzVGFyZ2V0OiBjZm5SZWNvcmRTZXRBbGlhc1RhcmdldFByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmFsaWFzVGFyZ2V0KSxcbiAgICAgICAgQ29tbWVudDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5jb21tZW50KSxcbiAgICAgICAgRmFpbG92ZXI6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZmFpbG92ZXIpLFxuICAgICAgICBHZW9Mb2NhdGlvbjogY2ZuUmVjb3JkU2V0R2VvTG9jYXRpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5nZW9Mb2NhdGlvbiksXG4gICAgICAgIEhlYWx0aENoZWNrSWQ6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaGVhbHRoQ2hlY2tJZCksXG4gICAgICAgIEhvc3RlZFpvbmVJZDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5ob3N0ZWRab25lSWQpLFxuICAgICAgICBIb3N0ZWRab25lTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5ob3N0ZWRab25lTmFtZSksXG4gICAgICAgIE11bHRpVmFsdWVBbnN3ZXI6IGNkay5ib29sZWFuVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm11bHRpVmFsdWVBbnN3ZXIpLFxuICAgICAgICBSZWdpb246IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucmVnaW9uKSxcbiAgICAgICAgUmVzb3VyY2VSZWNvcmRzOiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5yZXNvdXJjZVJlY29yZHMpLFxuICAgICAgICBTZXRJZGVudGlmaWVyOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnNldElkZW50aWZpZXIpLFxuICAgICAgICBUVEw6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMudHRsKSxcbiAgICAgICAgV2VpZ2h0OiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLndlaWdodCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblJlY29yZFNldFByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuUmVjb3JkU2V0UHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblJlY29yZFNldFByb3BzPigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbmFtZScsICdOYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5OYW1lKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0eXBlJywgJ1R5cGUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlR5cGUpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2FsaWFzVGFyZ2V0JywgJ0FsaWFzVGFyZ2V0JywgcHJvcGVydGllcy5BbGlhc1RhcmdldCAhPSBudWxsID8gQ2ZuUmVjb3JkU2V0QWxpYXNUYXJnZXRQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLkFsaWFzVGFyZ2V0KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjb21tZW50JywgJ0NvbW1lbnQnLCBwcm9wZXJ0aWVzLkNvbW1lbnQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQ29tbWVudCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZmFpbG92ZXInLCAnRmFpbG92ZXInLCBwcm9wZXJ0aWVzLkZhaWxvdmVyICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkZhaWxvdmVyKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdnZW9Mb2NhdGlvbicsICdHZW9Mb2NhdGlvbicsIHByb3BlcnRpZXMuR2VvTG9jYXRpb24gIT0gbnVsbCA/IENmblJlY29yZFNldEdlb0xvY2F0aW9uUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5HZW9Mb2NhdGlvbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaGVhbHRoQ2hlY2tJZCcsICdIZWFsdGhDaGVja0lkJywgcHJvcGVydGllcy5IZWFsdGhDaGVja0lkICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkhlYWx0aENoZWNrSWQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2hvc3RlZFpvbmVJZCcsICdIb3N0ZWRab25lSWQnLCBwcm9wZXJ0aWVzLkhvc3RlZFpvbmVJZCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Ib3N0ZWRab25lSWQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2hvc3RlZFpvbmVOYW1lJywgJ0hvc3RlZFpvbmVOYW1lJywgcHJvcGVydGllcy5Ib3N0ZWRab25lTmFtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Ib3N0ZWRab25lTmFtZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbXVsdGlWYWx1ZUFuc3dlcicsICdNdWx0aVZhbHVlQW5zd2VyJywgcHJvcGVydGllcy5NdWx0aVZhbHVlQW5zd2VyICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5NdWx0aVZhbHVlQW5zd2VyKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdyZWdpb24nLCAnUmVnaW9uJywgcHJvcGVydGllcy5SZWdpb24gIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuUmVnaW9uKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdyZXNvdXJjZVJlY29yZHMnLCAnUmVzb3VyY2VSZWNvcmRzJywgcHJvcGVydGllcy5SZXNvdXJjZVJlY29yZHMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5SZXNvdXJjZVJlY29yZHMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3NldElkZW50aWZpZXInLCAnU2V0SWRlbnRpZmllcicsIHByb3BlcnRpZXMuU2V0SWRlbnRpZmllciAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5TZXRJZGVudGlmaWVyKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0dGwnLCAnVFRMJywgcHJvcGVydGllcy5UVEwgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuVFRMKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd3ZWlnaHQnLCAnV2VpZ2h0JywgcHJvcGVydGllcy5XZWlnaHQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuV2VpZ2h0KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRgXG4gKlxuICogSW5mb3JtYXRpb24gYWJvdXQgdGhlIHJlY29yZCB0aGF0IHlvdSB3YW50IHRvIGNyZWF0ZS5cbiAqXG4gKiBUaGUgYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0YCB0eXBlIGNhbiBiZSB1c2VkIGFzIGEgc3RhbmRhbG9uZSByZXNvdXJjZSBvciBhcyBhbiBlbWJlZGRlZCBwcm9wZXJ0eSBpbiB0aGUgYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0R3JvdXBgIHR5cGUuIE5vdGUgdGhhdCBzb21lIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldGAgcHJvcGVydGllcyBhcmUgdmFsaWQgb25seSB3aGVuIHVzZWQgd2l0aGluIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldEdyb3VwYCAuXG4gKlxuICogRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQ2hhbmdlUmVzb3VyY2VSZWNvcmRTZXRzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DaGFuZ2VSZXNvdXJjZVJlY29yZFNldHMuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgQVBJIFJlZmVyZW5jZSogLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5SZWNvcmRTZXQgZXh0ZW5kcyBjZGsuQ2ZuUmVzb3VyY2UgaW1wbGVtZW50cyBjZGsuSUluc3BlY3RhYmxlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgdHlwZSBuYW1lIGZvciB0aGlzIHJlc291cmNlIGNsYXNzLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSA9IFwiQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmblJlY29yZFNldCB7XG4gICAgICAgIHJlc291cmNlQXR0cmlidXRlcyA9IHJlc291cmNlQXR0cmlidXRlcyB8fCB7fTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VQcm9wZXJ0aWVzID0gb3B0aW9ucy5wYXJzZXIucGFyc2VWYWx1ZShyZXNvdXJjZUF0dHJpYnV0ZXMuUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHByb3BzUmVzdWx0ID0gQ2ZuUmVjb3JkU2V0UHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmblJlY29yZFNldChzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGb3IgYENoYW5nZVJlc291cmNlUmVjb3JkU2V0c2AgcmVxdWVzdHMsIHRoZSBuYW1lIG9mIHRoZSByZWNvcmQgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUsIHVwZGF0ZSwgb3IgZGVsZXRlLiBGb3IgYExpc3RSZXNvdXJjZVJlY29yZFNldHNgIHJlc3BvbnNlcywgdGhlIG5hbWUgb2YgYSByZWNvcmQgaW4gdGhlIHNwZWNpZmllZCBob3N0ZWQgem9uZS5cbiAgICAgKlxuICAgICAqICpDaGFuZ2VSZXNvdXJjZVJlY29yZFNldHMgT25seSpcbiAgICAgKlxuICAgICAqIEVudGVyIGEgZnVsbHkgcXVhbGlmaWVkIGRvbWFpbiBuYW1lLCBmb3IgZXhhbXBsZSwgYHd3dy5leGFtcGxlLmNvbWAgLiBZb3UgY2FuIG9wdGlvbmFsbHkgaW5jbHVkZSBhIHRyYWlsaW5nIGRvdC4gSWYgeW91IG9taXQgdGhlIHRyYWlsaW5nIGRvdCwgQW1hem9uIFJvdXRlIDUzIGFzc3VtZXMgdGhhdCB0aGUgZG9tYWluIG5hbWUgdGhhdCB5b3Ugc3BlY2lmeSBpcyBmdWxseSBxdWFsaWZpZWQuIFRoaXMgbWVhbnMgdGhhdCBSb3V0ZSA1MyB0cmVhdHMgYHd3dy5leGFtcGxlLmNvbWAgKHdpdGhvdXQgYSB0cmFpbGluZyBkb3QpIGFuZCBgd3d3LmV4YW1wbGUuY29tLmAgKHdpdGggYSB0cmFpbGluZyBkb3QpIGFzIGlkZW50aWNhbC5cbiAgICAgKlxuICAgICAqIEZvciBpbmZvcm1hdGlvbiBhYm91dCBob3cgdG8gc3BlY2lmeSBjaGFyYWN0ZXJzIG90aGVyIHRoYW4gYGEtemAgLCBgMC05YCAsIGFuZCBgLWAgKGh5cGhlbikgYW5kIGhvdyB0byBzcGVjaWZ5IGludGVybmF0aW9uYWxpemVkIGRvbWFpbiBuYW1lcywgc2VlIFtETlMgRG9tYWluIE5hbWUgRm9ybWF0XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvRG9tYWluTmFtZUZvcm1hdC5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIFlvdSBjYW4gdXNlIHRoZSBhc3RlcmlzayAoKikgd2lsZGNhcmQgdG8gcmVwbGFjZSB0aGUgbGVmdG1vc3QgbGFiZWwgaW4gYSBkb21haW4gbmFtZSwgZm9yIGV4YW1wbGUsIGAqLmV4YW1wbGUuY29tYCAuIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gVGhlICogbXVzdCByZXBsYWNlIHRoZSBlbnRpcmUgbGFiZWwuIEZvciBleGFtcGxlLCB5b3UgY2FuJ3Qgc3BlY2lmeSBgKnByb2QuZXhhbXBsZS5jb21gIG9yIGBwcm9kKi5leGFtcGxlLmNvbWAgLlxuICAgICAqIC0gVGhlICogY2FuJ3QgcmVwbGFjZSBhbnkgb2YgdGhlIG1pZGRsZSBsYWJlbHMsIGZvciBleGFtcGxlLCBtYXJrZXRpbmcuKi5leGFtcGxlLmNvbS5cbiAgICAgKiAtIElmIHlvdSBpbmNsdWRlICogaW4gYW55IHBvc2l0aW9uIG90aGVyIHRoYW4gdGhlIGxlZnRtb3N0IGxhYmVsIGluIGEgZG9tYWluIG5hbWUsIEROUyB0cmVhdHMgaXQgYXMgYW4gKiBjaGFyYWN0ZXIgKEFTQ0lJIDQyKSwgbm90IGFzIGEgd2lsZGNhcmQuXG4gICAgICpcbiAgICAgKiA+IFlvdSBjYW4ndCB1c2UgdGhlICogd2lsZGNhcmQgZm9yIHJlc291cmNlIHJlY29yZHMgc2V0cyB0aGF0IGhhdmUgYSB0eXBlIG9mIE5TLlxuICAgICAqXG4gICAgICogWW91IGNhbiB1c2UgdGhlICogd2lsZGNhcmQgYXMgdGhlIGxlZnRtb3N0IGxhYmVsIGluIGEgZG9tYWluIG5hbWUsIGZvciBleGFtcGxlLCBgKi5leGFtcGxlLmNvbWAgLiBZb3UgY2FuJ3QgdXNlIGFuICogZm9yIG9uZSBvZiB0aGUgbWlkZGxlIGxhYmVscywgZm9yIGV4YW1wbGUsIGBtYXJrZXRpbmcuKi5leGFtcGxlLmNvbWAgLiBJbiBhZGRpdGlvbiwgdGhlICogbXVzdCByZXBsYWNlIHRoZSBlbnRpcmUgbGFiZWw7IGZvciBleGFtcGxlLCB5b3UgY2FuJ3Qgc3BlY2lmeSBgcHJvZCouZXhhbXBsZS5jb21gIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtbmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyBuYW1lOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgRE5TIHJlY29yZCB0eXBlLiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgZGlmZmVyZW50IHJlY29yZCB0eXBlcyBhbmQgaG93IGRhdGEgaXMgZW5jb2RlZCBmb3IgdGhlbSwgc2VlIFtTdXBwb3J0ZWQgRE5TIFJlc291cmNlIFJlY29yZCBUeXBlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL1Jlc291cmNlUmVjb3JkVHlwZXMuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBWYWxpZCB2YWx1ZXMgZm9yIGJhc2ljIHJlc291cmNlIHJlY29yZCBzZXRzOiBgQWAgfCBgQUFBQWAgfCBgQ0FBYCB8IGBDTkFNRWAgfCBgRFNgIHwgYE1YYCB8IGBOQVBUUmAgfCBgTlNgIHwgYFBUUmAgfCBgU09BYCB8IGBTUEZgIHwgYFNSVmAgfCBgVFhUYFxuICAgICAqXG4gICAgICogVmFsdWVzIGZvciB3ZWlnaHRlZCwgbGF0ZW5jeSwgZ2VvbG9jYXRpb24sIGFuZCBmYWlsb3ZlciByZXNvdXJjZSByZWNvcmQgc2V0czogYEFgIHwgYEFBQUFgIHwgYENBQWAgfCBgQ05BTUVgIHwgYE1YYCB8IGBOQVBUUmAgfCBgUFRSYCB8IGBTUEZgIHwgYFNSVmAgfCBgVFhUYCAuIFdoZW4gY3JlYXRpbmcgYSBncm91cCBvZiB3ZWlnaHRlZCwgbGF0ZW5jeSwgZ2VvbG9jYXRpb24sIG9yIGZhaWxvdmVyIHJlc291cmNlIHJlY29yZCBzZXRzLCBzcGVjaWZ5IHRoZSBzYW1lIHZhbHVlIGZvciBhbGwgb2YgdGhlIHJlc291cmNlIHJlY29yZCBzZXRzIGluIHRoZSBncm91cC5cbiAgICAgKlxuICAgICAqIFZhbGlkIHZhbHVlcyBmb3IgbXVsdGl2YWx1ZSBhbnN3ZXIgcmVzb3VyY2UgcmVjb3JkIHNldHM6IGBBYCB8IGBBQUFBYCB8IGBNWGAgfCBgTkFQVFJgIHwgYFBUUmAgfCBgU1BGYCB8IGBTUlZgIHwgYFRYVGBcbiAgICAgKlxuICAgICAqID4gU1BGIHJlY29yZHMgd2VyZSBmb3JtZXJseSB1c2VkIHRvIHZlcmlmeSB0aGUgaWRlbnRpdHkgb2YgdGhlIHNlbmRlciBvZiBlbWFpbCBtZXNzYWdlcy4gSG93ZXZlciwgd2Ugbm8gbG9uZ2VyIHJlY29tbWVuZCB0aGF0IHlvdSBjcmVhdGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgZm9yIHdoaWNoIHRoZSB2YWx1ZSBvZiBgVHlwZWAgaXMgYFNQRmAgLiBSRkMgNzIwOCwgKlNlbmRlciBQb2xpY3kgRnJhbWV3b3JrIChTUEYpIGZvciBBdXRob3JpemluZyBVc2Ugb2YgRG9tYWlucyBpbiBFbWFpbCwgVmVyc2lvbiAxKiAsIGhhcyBiZWVuIHVwZGF0ZWQgdG8gc2F5LCBcIi4uLltJXXRzIGV4aXN0ZW5jZSBhbmQgbWVjaGFuaXNtIGRlZmluZWQgaW4gW1JGQzQ0MDhdIGhhdmUgbGVkIHRvIHNvbWUgaW50ZXJvcGVyYWJpbGl0eSBpc3N1ZXMuIEFjY29yZGluZ2x5LCBpdHMgdXNlIGlzIG5vIGxvbmdlciBhcHByb3ByaWF0ZSBmb3IgU1BGIHZlcnNpb24gMTsgaW1wbGVtZW50YXRpb25zIGFyZSBub3QgdG8gdXNlIGl0LlwiIEluIFJGQyA3MjA4LCBzZWUgc2VjdGlvbiAxNC4xLCBbVGhlIFNQRiBETlMgUmVjb3JkIFR5cGVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM3MjA4I3NlY3Rpb24tMTQuMSkgLlxuICAgICAqXG4gICAgICogVmFsdWVzIGZvciBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0czpcbiAgICAgKlxuICAgICAqIC0gKkFtYXpvbiBBUEkgR2F0ZXdheSBjdXN0b20gcmVnaW9uYWwgQVBJcyBhbmQgZWRnZS1vcHRpbWl6ZWQgQVBJczoqIGBBYFxuICAgICAqIC0gKkNsb3VkRnJvbnQgZGlzdHJpYnV0aW9uczoqIGBBYFxuICAgICAqXG4gICAgICogSWYgSVB2NiBpcyBlbmFibGVkIGZvciB0aGUgZGlzdHJpYnV0aW9uLCBjcmVhdGUgdHdvIHJlc291cmNlIHJlY29yZCBzZXRzIHRvIHJvdXRlIHRyYWZmaWMgdG8geW91ciBkaXN0cmlidXRpb24sIG9uZSB3aXRoIGEgdmFsdWUgb2YgYEFgIGFuZCBvbmUgd2l0aCBhIHZhbHVlIG9mIGBBQUFBYCAuXG4gICAgICogLSAqQW1hem9uIEFQSSBHYXRld2F5IGVudmlyb25tZW50IHRoYXQgaGFzIGEgcmVnaW9uYWxpemVkIHN1YmRvbWFpbiogOiBgQWBcbiAgICAgKiAtICpFTEIgbG9hZCBiYWxhbmNlcnM6KiBgQWAgfCBgQUFBQWBcbiAgICAgKiAtICpBbWF6b24gUzMgYnVja2V0czoqIGBBYFxuICAgICAqIC0gKkFtYXpvbiBWaXJ0dWFsIFByaXZhdGUgQ2xvdWQgaW50ZXJmYWNlIFZQQyBlbmRwb2ludHMqIGBBYFxuICAgICAqIC0gKkFub3RoZXIgcmVzb3VyY2UgcmVjb3JkIHNldCBpbiB0aGlzIGhvc3RlZCB6b25lOiogU3BlY2lmeSB0aGUgdHlwZSBvZiB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldCB0aGF0IHlvdSdyZSBjcmVhdGluZyB0aGUgYWxpYXMgZm9yLiBBbGwgdmFsdWVzIGFyZSBzdXBwb3J0ZWQgZXhjZXB0IGBOU2AgYW5kIGBTT0FgIC5cbiAgICAgKlxuICAgICAqID4gSWYgeW91J3JlIGNyZWF0aW5nIGFuIGFsaWFzIHJlY29yZCB0aGF0IGhhcyB0aGUgc2FtZSBuYW1lIGFzIHRoZSBob3N0ZWQgem9uZSAoa25vd24gYXMgdGhlIHpvbmUgYXBleCksIHlvdSBjYW4ndCByb3V0ZSB0cmFmZmljIHRvIGEgcmVjb3JkIGZvciB3aGljaCB0aGUgdmFsdWUgb2YgYFR5cGVgIGlzIGBDTkFNRWAgLiBUaGlzIGlzIGJlY2F1c2UgdGhlIGFsaWFzIHJlY29yZCBtdXN0IGhhdmUgdGhlIHNhbWUgdHlwZSBhcyB0aGUgcmVjb3JkIHlvdSdyZSByb3V0aW5nIHRyYWZmaWMgdG8sIGFuZCBjcmVhdGluZyBhIENOQU1FIHJlY29yZCBmb3IgdGhlIHpvbmUgYXBleCBpc24ndCBzdXBwb3J0ZWQgZXZlbiBmb3IgYW4gYWxpYXMgcmVjb3JkLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC10eXBlXG4gICAgICovXG4gICAgcHVibGljIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqICpBbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0cyBvbmx5OiogSW5mb3JtYXRpb24gYWJvdXQgdGhlIEFXUyByZXNvdXJjZSwgc3VjaCBhcyBhIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uIG9yIGFuIEFtYXpvbiBTMyBidWNrZXQsIHRoYXQgeW91IHdhbnQgdG8gcm91dGUgdHJhZmZpYyB0by5cbiAgICAgKlxuICAgICAqIElmIHlvdSdyZSBjcmVhdGluZyByZXNvdXJjZSByZWNvcmRzIHNldHMgZm9yIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSwgbm90ZSB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBZb3UgY2FuJ3QgY3JlYXRlIGFuIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQgaW4gYSBwcml2YXRlIGhvc3RlZCB6b25lIHRvIHJvdXRlIHRyYWZmaWMgdG8gYSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbi5cbiAgICAgKiAtIENyZWF0aW5nIGdlb2xvY2F0aW9uIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzIG9yIGxhdGVuY3kgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gYSBwcml2YXRlIGhvc3RlZCB6b25lIGlzIHVuc3VwcG9ydGVkLlxuICAgICAqIC0gRm9yIGluZm9ybWF0aW9uIGFib3V0IGNyZWF0aW5nIGZhaWxvdmVyIHJlc291cmNlIHJlY29yZCBzZXRzIGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSwgc2VlIFtDb25maWd1cmluZyBGYWlsb3ZlciBpbiBhIFByaXZhdGUgSG9zdGVkIFpvbmVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9kbnMtZmFpbG92ZXItcHJpdmF0ZS1ob3N0ZWQtem9uZXMuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LWFsaWFzdGFyZ2V0XG4gICAgICovXG4gICAgcHVibGljIGFsaWFzVGFyZ2V0OiBDZm5SZWNvcmRTZXQuQWxpYXNUYXJnZXRQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqICpPcHRpb25hbDoqIEFueSBjb21tZW50cyB5b3Ugd2FudCB0byBpbmNsdWRlIGFib3V0IGEgY2hhbmdlIGJhdGNoIHJlcXVlc3QuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LWNvbW1lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgY29tbWVudDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogKkZhaWxvdmVyIHJlc291cmNlIHJlY29yZCBzZXRzIG9ubHk6KiBUbyBjb25maWd1cmUgZmFpbG92ZXIsIHlvdSBhZGQgdGhlIGBGYWlsb3ZlcmAgZWxlbWVudCB0byB0d28gcmVzb3VyY2UgcmVjb3JkIHNldHMuIEZvciBvbmUgcmVzb3VyY2UgcmVjb3JkIHNldCwgeW91IHNwZWNpZnkgYFBSSU1BUllgIGFzIHRoZSB2YWx1ZSBmb3IgYEZhaWxvdmVyYCA7IGZvciB0aGUgb3RoZXIgcmVzb3VyY2UgcmVjb3JkIHNldCwgeW91IHNwZWNpZnkgYFNFQ09OREFSWWAgLiBJbiBhZGRpdGlvbiwgeW91IGluY2x1ZGUgdGhlIGBIZWFsdGhDaGVja0lkYCBlbGVtZW50IGFuZCBzcGVjaWZ5IHRoZSBoZWFsdGggY2hlY2sgdGhhdCB5b3Ugd2FudCBBbWF6b24gUm91dGUgNTMgdG8gcGVyZm9ybSBmb3IgZWFjaCByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqXG4gICAgICogRXhjZXB0IHdoZXJlIG5vdGVkLCB0aGUgZm9sbG93aW5nIGZhaWxvdmVyIGJlaGF2aW9ycyBhc3N1bWUgdGhhdCB5b3UgaGF2ZSBpbmNsdWRlZCB0aGUgYEhlYWx0aENoZWNrSWRgIGVsZW1lbnQgaW4gYm90aCByZXNvdXJjZSByZWNvcmQgc2V0czpcbiAgICAgKlxuICAgICAqIC0gV2hlbiB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIGhlYWx0aHksIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdGhlIGFwcGxpY2FibGUgdmFsdWUgZnJvbSB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0IHJlZ2FyZGxlc3Mgb2YgdGhlIGhlYWx0aCBvZiB0aGUgc2Vjb25kYXJ5IHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICogLSBXaGVuIHRoZSBwcmltYXJ5IHJlc291cmNlIHJlY29yZCBzZXQgaXMgdW5oZWFsdGh5IGFuZCB0aGUgc2Vjb25kYXJ5IHJlc291cmNlIHJlY29yZCBzZXQgaXMgaGVhbHRoeSwgUm91dGUgNTMgcmVzcG9uZHMgdG8gRE5TIHF1ZXJpZXMgd2l0aCB0aGUgYXBwbGljYWJsZSB2YWx1ZSBmcm9tIHRoZSBzZWNvbmRhcnkgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKiAtIFdoZW4gdGhlIHNlY29uZGFyeSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgcmVzcG9uZHMgdG8gRE5TIHF1ZXJpZXMgd2l0aCB0aGUgYXBwbGljYWJsZSB2YWx1ZSBmcm9tIHRoZSBwcmltYXJ5IHJlc291cmNlIHJlY29yZCBzZXQgcmVnYXJkbGVzcyBvZiB0aGUgaGVhbHRoIG9mIHRoZSBwcmltYXJ5IHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICogLSBJZiB5b3Ugb21pdCB0aGUgYEhlYWx0aENoZWNrSWRgIGVsZW1lbnQgZm9yIHRoZSBzZWNvbmRhcnkgcmVzb3VyY2UgcmVjb3JkIHNldCwgYW5kIGlmIHRoZSBwcmltYXJ5IHJlc291cmNlIHJlY29yZCBzZXQgaXMgdW5oZWFsdGh5LCBSb3V0ZSA1MyBhbHdheXMgcmVzcG9uZHMgdG8gRE5TIHF1ZXJpZXMgd2l0aCB0aGUgYXBwbGljYWJsZSB2YWx1ZSBmcm9tIHRoZSBzZWNvbmRhcnkgcmVzb3VyY2UgcmVjb3JkIHNldC4gVGhpcyBpcyB0cnVlIHJlZ2FyZGxlc3Mgb2YgdGhlIGhlYWx0aCBvZiB0aGUgYXNzb2NpYXRlZCBlbmRwb2ludC5cbiAgICAgKlxuICAgICAqIFlvdSBjYW4ndCBjcmVhdGUgbm9uLWZhaWxvdmVyIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSB2YWx1ZXMgZm9yIHRoZSBgTmFtZWAgYW5kIGBUeXBlYCBlbGVtZW50cyBhcyBmYWlsb3ZlciByZXNvdXJjZSByZWNvcmQgc2V0cy5cbiAgICAgKlxuICAgICAqIEZvciBmYWlsb3ZlciBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0cywgeW91IG11c3QgYWxzbyBpbmNsdWRlIHRoZSBgRXZhbHVhdGVUYXJnZXRIZWFsdGhgIGVsZW1lbnQgYW5kIHNldCB0aGUgdmFsdWUgdG8gdHJ1ZS5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGNvbmZpZ3VyaW5nIGZhaWxvdmVyIGZvciBSb3V0ZSA1Mywgc2VlIHRoZSBmb2xsb3dpbmcgdG9waWNzIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogOlxuICAgICAqXG4gICAgICogLSBbUm91dGUgNTMgSGVhbHRoIENoZWNrcyBhbmQgRE5TIEZhaWxvdmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLmh0bWwpXG4gICAgICogLSBbQ29uZmlndXJpbmcgRmFpbG92ZXIgaW4gYSBQcml2YXRlIEhvc3RlZCBab25lXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLXByaXZhdGUtaG9zdGVkLXpvbmVzLmh0bWwpXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LWZhaWxvdmVyXG4gICAgICovXG4gICAgcHVibGljIGZhaWxvdmVyOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiAqR2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgb25seToqIEEgY29tcGxleCB0eXBlIHRoYXQgbGV0cyB5b3UgY29udHJvbCBob3cgQW1hem9uIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIGJhc2VkIG9uIHRoZSBnZW9ncmFwaGljIG9yaWdpbiBvZiB0aGUgcXVlcnkuIEZvciBleGFtcGxlLCBpZiB5b3Ugd2FudCBhbGwgcXVlcmllcyBmcm9tIEFmcmljYSB0byBiZSByb3V0ZWQgdG8gYSB3ZWIgc2VydmVyIHdpdGggYW4gSVAgYWRkcmVzcyBvZiBgMTkyLjAuMi4xMTFgICwgY3JlYXRlIGEgcmVzb3VyY2UgcmVjb3JkIHNldCB3aXRoIGEgYFR5cGVgIG9mIGBBYCBhbmQgYSBgQ29udGluZW50Q29kZWAgb2YgYEFGYCAuXG4gICAgICpcbiAgICAgKiA+IEFsdGhvdWdoIGNyZWF0aW5nIGdlb2xvY2F0aW9uIGFuZCBnZW9sb2NhdGlvbiBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0cyBpbiBhIHByaXZhdGUgaG9zdGVkIHpvbmUgaXMgYWxsb3dlZCwgaXQncyBub3Qgc3VwcG9ydGVkLlxuICAgICAqXG4gICAgICogSWYgeW91IGNyZWF0ZSBzZXBhcmF0ZSByZXNvdXJjZSByZWNvcmQgc2V0cyBmb3Igb3ZlcmxhcHBpbmcgZ2VvZ3JhcGhpYyByZWdpb25zIChmb3IgZXhhbXBsZSwgb25lIHJlc291cmNlIHJlY29yZCBzZXQgZm9yIGEgY29udGluZW50IGFuZCBvbmUgZm9yIGEgY291bnRyeSBvbiB0aGUgc2FtZSBjb250aW5lbnQpLCBwcmlvcml0eSBnb2VzIHRvIHRoZSBzbWFsbGVzdCBnZW9ncmFwaGljIHJlZ2lvbi4gVGhpcyBhbGxvd3MgeW91IHRvIHJvdXRlIG1vc3QgcXVlcmllcyBmb3IgYSBjb250aW5lbnQgdG8gb25lIHJlc291cmNlIGFuZCB0byByb3V0ZSBxdWVyaWVzIGZvciBhIGNvdW50cnkgb24gdGhhdCBjb250aW5lbnQgdG8gYSBkaWZmZXJlbnQgcmVzb3VyY2UuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuJ3QgY3JlYXRlIHR3byBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IHNwZWNpZnkgdGhlIHNhbWUgZ2VvZ3JhcGhpYyBsb2NhdGlvbi5cbiAgICAgKlxuICAgICAqIFRoZSB2YWx1ZSBgKmAgaW4gdGhlIGBDb3VudHJ5Q29kZWAgZWxlbWVudCBtYXRjaGVzIGFsbCBnZW9ncmFwaGljIGxvY2F0aW9ucyB0aGF0IGFyZW4ndCBzcGVjaWZpZWQgaW4gb3RoZXIgZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIHZhbHVlcyBmb3IgdGhlIGBOYW1lYCBhbmQgYFR5cGVgIGVsZW1lbnRzLlxuICAgICAqXG4gICAgICogPiBHZW9sb2NhdGlvbiB3b3JrcyBieSBtYXBwaW5nIElQIGFkZHJlc3NlcyB0byBsb2NhdGlvbnMuIEhvd2V2ZXIsIHNvbWUgSVAgYWRkcmVzc2VzIGFyZW4ndCBtYXBwZWQgdG8gZ2VvZ3JhcGhpYyBsb2NhdGlvbnMsIHNvIGV2ZW4gaWYgeW91IGNyZWF0ZSBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGNvdmVyIGFsbCBzZXZlbiBjb250aW5lbnRzLCBSb3V0ZSA1MyB3aWxsIHJlY2VpdmUgc29tZSBETlMgcXVlcmllcyBmcm9tIGxvY2F0aW9ucyB0aGF0IGl0IGNhbid0IGlkZW50aWZ5LiBXZSByZWNvbW1lbmQgdGhhdCB5b3UgY3JlYXRlIGEgcmVzb3VyY2UgcmVjb3JkIHNldCBmb3Igd2hpY2ggdGhlIHZhbHVlIG9mIGBDb3VudHJ5Q29kZWAgaXMgYCpgIC4gVHdvIGdyb3VwcyBvZiBxdWVyaWVzIGFyZSByb3V0ZWQgdG8gdGhlIHJlc291cmNlIHRoYXQgeW91IHNwZWNpZnkgaW4gdGhpcyByZWNvcmQ6IHF1ZXJpZXMgdGhhdCBjb21lIGZyb20gbG9jYXRpb25zIGZvciB3aGljaCB5b3UgaGF2ZW4ndCBjcmVhdGVkIGdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzIGFuZCBxdWVyaWVzIGZyb20gSVAgYWRkcmVzc2VzIHRoYXQgYXJlbid0IG1hcHBlZCB0byBhIGxvY2F0aW9uLiBJZiB5b3UgZG9uJ3QgY3JlYXRlIGEgYCpgIHJlc291cmNlIHJlY29yZCBzZXQsIFJvdXRlIDUzIHJldHVybnMgYSBcIm5vIGFuc3dlclwiIHJlc3BvbnNlIGZvciBxdWVyaWVzIGZyb20gdGhvc2UgbG9jYXRpb25zLlxuICAgICAqXG4gICAgICogWW91IGNhbid0IGNyZWF0ZSBub24tZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIHZhbHVlcyBmb3IgdGhlIGBOYW1lYCBhbmQgYFR5cGVgIGVsZW1lbnRzIGFzIGdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1nZW9sb2NhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBnZW9Mb2NhdGlvbjogQ2ZuUmVjb3JkU2V0Lkdlb0xvY2F0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBJZiB5b3Ugd2FudCBBbWF6b24gUm91dGUgNTMgdG8gcmV0dXJuIHRoaXMgcmVzb3VyY2UgcmVjb3JkIHNldCBpbiByZXNwb25zZSB0byBhIEROUyBxdWVyeSBvbmx5IHdoZW4gdGhlIHN0YXR1cyBvZiBhIGhlYWx0aCBjaGVjayBpcyBoZWFsdGh5LCBpbmNsdWRlIHRoZSBgSGVhbHRoQ2hlY2tJZGAgZWxlbWVudCBhbmQgc3BlY2lmeSB0aGUgSUQgb2YgdGhlIGFwcGxpY2FibGUgaGVhbHRoIGNoZWNrLlxuICAgICAqXG4gICAgICogUm91dGUgNTMgZGV0ZXJtaW5lcyB3aGV0aGVyIGEgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyBoZWFsdGh5IGJhc2VkIG9uIG9uZSBvZiB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBCeSBwZXJpb2RpY2FsbHkgc2VuZGluZyBhIHJlcXVlc3QgdG8gdGhlIGVuZHBvaW50IHRoYXQgaXMgc3BlY2lmaWVkIGluIHRoZSBoZWFsdGggY2hlY2tcbiAgICAgKiAtIEJ5IGFnZ3JlZ2F0aW5nIHRoZSBzdGF0dXMgb2YgYSBzcGVjaWZpZWQgZ3JvdXAgb2YgaGVhbHRoIGNoZWNrcyAoY2FsY3VsYXRlZCBoZWFsdGggY2hlY2tzKVxuICAgICAqIC0gQnkgZGV0ZXJtaW5pbmcgdGhlIGN1cnJlbnQgc3RhdGUgb2YgYSBDbG91ZFdhdGNoIGFsYXJtIChDbG91ZFdhdGNoIG1ldHJpYyBoZWFsdGggY2hlY2tzKVxuICAgICAqXG4gICAgICogPiBSb3V0ZSA1MyBkb2Vzbid0IGNoZWNrIHRoZSBoZWFsdGggb2YgdGhlIGVuZHBvaW50IHRoYXQgaXMgc3BlY2lmaWVkIGluIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0LCBmb3IgZXhhbXBsZSwgdGhlIGVuZHBvaW50IHNwZWNpZmllZCBieSB0aGUgSVAgYWRkcmVzcyBpbiB0aGUgYFZhbHVlYCBlbGVtZW50LiBXaGVuIHlvdSBhZGQgYSBgSGVhbHRoQ2hlY2tJZGAgZWxlbWVudCB0byBhIHJlc291cmNlIHJlY29yZCBzZXQsIFJvdXRlIDUzIGNoZWNrcyB0aGUgaGVhbHRoIG9mIHRoZSBlbmRwb2ludCB0aGF0IHlvdSBzcGVjaWZpZWQgaW4gdGhlIGhlYWx0aCBjaGVjay5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgdGhlIGZvbGxvd2luZyB0b3BpY3MgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiA6XG4gICAgICpcbiAgICAgKiAtIFtIb3cgQW1hem9uIFJvdXRlIDUzIERldGVybWluZXMgV2hldGhlciBhbiBFbmRwb2ludCBJcyBIZWFsdGh5XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLWRldGVybWluaW5nLWhlYWx0aC1vZi1lbmRwb2ludHMuaHRtbClcbiAgICAgKiAtIFtSb3V0ZSA1MyBIZWFsdGggQ2hlY2tzIGFuZCBETlMgRmFpbG92ZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9kbnMtZmFpbG92ZXIuaHRtbClcbiAgICAgKiAtIFtDb25maWd1cmluZyBGYWlsb3ZlciBpbiBhIFByaXZhdGUgSG9zdGVkIFpvbmVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9kbnMtZmFpbG92ZXItcHJpdmF0ZS1ob3N0ZWQtem9uZXMuaHRtbClcbiAgICAgKlxuICAgICAqICpXaGVuIHRvIFNwZWNpZnkgSGVhbHRoQ2hlY2tJZCpcbiAgICAgKlxuICAgICAqIFNwZWNpZnlpbmcgYSB2YWx1ZSBmb3IgYEhlYWx0aENoZWNrSWRgIGlzIHVzZWZ1bCBvbmx5IHdoZW4gUm91dGUgNTMgaXMgY2hvb3NpbmcgYmV0d2VlbiB0d28gb3IgbW9yZSByZXNvdXJjZSByZWNvcmQgc2V0cyB0byByZXNwb25kIHRvIGEgRE5TIHF1ZXJ5LCBhbmQgeW91IHdhbnQgUm91dGUgNTMgdG8gYmFzZSB0aGUgY2hvaWNlIGluIHBhcnQgb24gdGhlIHN0YXR1cyBvZiBhIGhlYWx0aCBjaGVjay4gQ29uZmlndXJpbmcgaGVhbHRoIGNoZWNrcyBtYWtlcyBzZW5zZSBvbmx5IGluIHRoZSBmb2xsb3dpbmcgY29uZmlndXJhdGlvbnM6XG4gICAgICpcbiAgICAgKiAtICpOb24tYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMqIDogWW91J3JlIGNoZWNraW5nIHRoZSBoZWFsdGggb2YgYSBncm91cCBvZiBub24tYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIHJvdXRpbmcgcG9saWN5LCBuYW1lLCBhbmQgdHlwZSAoc3VjaCBhcyBtdWx0aXBsZSB3ZWlnaHRlZCByZWNvcmRzIG5hbWVkIHd3dy5leGFtcGxlLmNvbSB3aXRoIGEgdHlwZSBvZiBBKSBhbmQgeW91IHNwZWNpZnkgaGVhbHRoIGNoZWNrIElEcyBmb3IgYWxsIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0cy5cbiAgICAgKlxuICAgICAqIElmIHRoZSBoZWFsdGggY2hlY2sgc3RhdHVzIGZvciBhIHJlc291cmNlIHJlY29yZCBzZXQgaXMgaGVhbHRoeSwgUm91dGUgNTMgaW5jbHVkZXMgdGhlIHJlY29yZCBhbW9uZyB0aGUgcmVjb3JkcyB0aGF0IGl0IHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGguXG4gICAgICpcbiAgICAgKiBJZiB0aGUgaGVhbHRoIGNoZWNrIHN0YXR1cyBmb3IgYSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgc3RvcHMgcmVzcG9uZGluZyB0byBETlMgcXVlcmllcyB1c2luZyB0aGUgdmFsdWUgZm9yIHRoYXQgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKlxuICAgICAqIElmIHRoZSBoZWFsdGggY2hlY2sgc3RhdHVzIGZvciBhbGwgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gdGhlIGdyb3VwIGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgY29uc2lkZXJzIGFsbCByZXNvdXJjZSByZWNvcmQgc2V0cyBpbiB0aGUgZ3JvdXAgaGVhbHRoeSBhbmQgcmVzcG9uZHMgdG8gRE5TIHF1ZXJpZXMgYWNjb3JkaW5nbHkuXG4gICAgICogLSAqQWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMqIDogWW91IHNwZWNpZnkgdGhlIGZvbGxvd2luZyBzZXR0aW5nczpcbiAgICAgKlxuICAgICAqIC0gWW91IHNldCBgRXZhbHVhdGVUYXJnZXRIZWFsdGhgIHRvIHRydWUgZm9yIGFuIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQgaW4gYSBncm91cCBvZiByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgcm91dGluZyBwb2xpY3ksIG5hbWUsIGFuZCB0eXBlIChzdWNoIGFzIG11bHRpcGxlIHdlaWdodGVkIHJlY29yZHMgbmFtZWQgd3d3LmV4YW1wbGUuY29tIHdpdGggYSB0eXBlIG9mIEEpLlxuICAgICAqIC0gWW91IGNvbmZpZ3VyZSB0aGUgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldCB0byByb3V0ZSB0cmFmZmljIHRvIGEgbm9uLWFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQgaW4gdGhlIHNhbWUgaG9zdGVkIHpvbmUuXG4gICAgICogLSBZb3Ugc3BlY2lmeSBhIGhlYWx0aCBjaGVjayBJRCBmb3IgdGhlIG5vbi1hbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqXG4gICAgICogSWYgdGhlIGhlYWx0aCBjaGVjayBzdGF0dXMgaXMgaGVhbHRoeSwgUm91dGUgNTMgY29uc2lkZXJzIHRoZSBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0IHRvIGJlIGhlYWx0aHkgYW5kIGluY2x1ZGVzIHRoZSBhbGlhcyByZWNvcmQgYW1vbmcgdGhlIHJlY29yZHMgdGhhdCBpdCByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoLlxuICAgICAqXG4gICAgICogSWYgdGhlIGhlYWx0aCBjaGVjayBzdGF0dXMgaXMgdW5oZWFsdGh5LCBSb3V0ZSA1MyBzdG9wcyByZXNwb25kaW5nIHRvIEROUyBxdWVyaWVzIHVzaW5nIHRoZSBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqXG4gICAgICogPiBUaGUgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldCBjYW4gYWxzbyByb3V0ZSB0cmFmZmljIHRvIGEgKmdyb3VwKiBvZiBub24tYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIHJvdXRpbmcgcG9saWN5LCBuYW1lLCBhbmQgdHlwZS4gSW4gdGhhdCBjb25maWd1cmF0aW9uLCBhc3NvY2lhdGUgaGVhbHRoIGNoZWNrcyB3aXRoIGFsbCBvZiB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gdGhlIGdyb3VwIG9mIG5vbi1hbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0cy5cbiAgICAgKlxuICAgICAqICpHZW9sb2NhdGlvbiBSb3V0aW5nKlxuICAgICAqXG4gICAgICogRm9yIGdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzLCBpZiBhbiBlbmRwb2ludCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIGxvb2tzIGZvciBhIHJlc291cmNlIHJlY29yZCBzZXQgZm9yIHRoZSBsYXJnZXIsIGFzc29jaWF0ZWQgZ2VvZ3JhcGhpYyByZWdpb24uIEZvciBleGFtcGxlLCBzdXBwb3NlIHlvdSBoYXZlIHJlc291cmNlIHJlY29yZCBzZXRzIGZvciBhIHN0YXRlIGluIHRoZSBVbml0ZWQgU3RhdGVzLCBmb3IgdGhlIGVudGlyZSBVbml0ZWQgU3RhdGVzLCBmb3IgTm9ydGggQW1lcmljYSwgYW5kIGEgcmVzb3VyY2UgcmVjb3JkIHNldCB0aGF0IGhhcyBgKmAgZm9yIGBDb3VudHJ5Q29kZWAgaXMgYCpgICwgd2hpY2ggYXBwbGllcyB0byBhbGwgbG9jYXRpb25zLiBJZiB0aGUgZW5kcG9pbnQgZm9yIHRoZSBzdGF0ZSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgY2hlY2tzIGZvciBoZWFsdGh5IHJlc291cmNlIHJlY29yZCBzZXRzIGluIHRoZSBmb2xsb3dpbmcgb3JkZXIgdW50aWwgaXQgZmluZHMgYSByZXNvdXJjZSByZWNvcmQgc2V0IGZvciB3aGljaCB0aGUgZW5kcG9pbnQgaXMgaGVhbHRoeTpcbiAgICAgKlxuICAgICAqIC0gVGhlIFVuaXRlZCBTdGF0ZXNcbiAgICAgKiAtIE5vcnRoIEFtZXJpY2FcbiAgICAgKiAtIFRoZSBkZWZhdWx0IHJlc291cmNlIHJlY29yZCBzZXRcbiAgICAgKlxuICAgICAqICpTcGVjaWZ5aW5nIHRoZSBIZWFsdGggQ2hlY2sgRW5kcG9pbnQgYnkgRG9tYWluIE5hbWUqXG4gICAgICpcbiAgICAgKiBJZiB5b3VyIGhlYWx0aCBjaGVja3Mgc3BlY2lmeSB0aGUgZW5kcG9pbnQgb25seSBieSBkb21haW4gbmFtZSwgd2UgcmVjb21tZW5kIHRoYXQgeW91IGNyZWF0ZSBhIHNlcGFyYXRlIGhlYWx0aCBjaGVjayBmb3IgZWFjaCBlbmRwb2ludC4gRm9yIGV4YW1wbGUsIGNyZWF0ZSBhIGhlYWx0aCBjaGVjayBmb3IgZWFjaCBgSFRUUGAgc2VydmVyIHRoYXQgaXMgc2VydmluZyBjb250ZW50IGZvciBgd3d3LmV4YW1wbGUuY29tYCAuIEZvciB0aGUgdmFsdWUgb2YgYEZ1bGx5UXVhbGlmaWVkRG9tYWluTmFtZWAgLCBzcGVjaWZ5IHRoZSBkb21haW4gbmFtZSBvZiB0aGUgc2VydmVyIChzdWNoIGFzIGB1cy1lYXN0LTItd3d3LmV4YW1wbGUuY29tYCApLCBub3QgdGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIHJlY29yZCBzZXRzICggYHd3dy5leGFtcGxlLmNvbWAgKS5cbiAgICAgKlxuICAgICAqID4gSGVhbHRoIGNoZWNrIHJlc3VsdHMgd2lsbCBiZSB1bnByZWRpY3RhYmxlIGlmIHlvdSBkbyB0aGUgZm9sbG93aW5nOlxuICAgICAqID5cbiAgICAgKiA+IC0gQ3JlYXRlIGEgaGVhbHRoIGNoZWNrIHRoYXQgaGFzIHRoZSBzYW1lIHZhbHVlIGZvciBgRnVsbHlRdWFsaWZpZWREb21haW5OYW1lYCBhcyB0aGUgbmFtZSBvZiBhIHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICogPiAtIEFzc29jaWF0ZSB0aGF0IGhlYWx0aCBjaGVjayB3aXRoIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1oZWFsdGhjaGVja2lkXG4gICAgICovXG4gICAgcHVibGljIGhlYWx0aENoZWNrSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBJRCBvZiB0aGUgaG9zdGVkIHpvbmUgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUgcmVjb3JkcyBpbi5cbiAgICAgKlxuICAgICAqIFNwZWNpZnkgZWl0aGVyIGBIb3N0ZWRab25lTmFtZWAgb3IgYEhvc3RlZFpvbmVJZGAgLCBidXQgbm90IGJvdGguIElmIHlvdSBoYXZlIG11bHRpcGxlIGhvc3RlZCB6b25lcyB3aXRoIHRoZSBzYW1lIGRvbWFpbiBuYW1lLCB5b3UgbXVzdCBzcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSB1c2luZyBgSG9zdGVkWm9uZUlkYCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LWhvc3RlZHpvbmVpZFxuICAgICAqL1xuICAgIHB1YmxpYyBob3N0ZWRab25lSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBob3N0ZWQgem9uZSB0aGF0IHlvdSB3YW50IHRvIGNyZWF0ZSByZWNvcmRzIGluLiBZb3UgbXVzdCBpbmNsdWRlIGEgdHJhaWxpbmcgZG90IChmb3IgZXhhbXBsZSwgYHd3dy5leGFtcGxlLmNvbS5gICkgYXMgcGFydCBvZiB0aGUgYEhvc3RlZFpvbmVOYW1lYCAuXG4gICAgICpcbiAgICAgKiBXaGVuIHlvdSBjcmVhdGUgYSBzdGFjayB1c2luZyBhbiBBV1M6OlJvdXRlNTM6OlJlY29yZFNldCB0aGF0IHNwZWNpZmllcyBgSG9zdGVkWm9uZU5hbWVgICwgQVdTIENsb3VkRm9ybWF0aW9uIGF0dGVtcHRzIHRvIGZpbmQgYSBob3N0ZWQgem9uZSB3aG9zZSBuYW1lIG1hdGNoZXMgdGhlIEhvc3RlZFpvbmVOYW1lLiBJZiBBV1MgQ2xvdWRGb3JtYXRpb24gY2Fubm90IGZpbmQgYSBob3N0ZWQgem9uZSB3aXRoIGEgbWF0Y2hpbmcgZG9tYWluIG5hbWUsIG9yIGlmIHRoZXJlIGlzIG1vcmUgdGhhbiBvbmUgaG9zdGVkIHpvbmUgd2l0aCB0aGUgc3BlY2lmaWVkIGRvbWFpbiBuYW1lLCBBV1MgQ2xvdWRGb3JtYXRpb24gd2lsbCBub3QgY3JlYXRlIHRoZSBzdGFjay5cbiAgICAgKlxuICAgICAqIFNwZWNpZnkgZWl0aGVyIGBIb3N0ZWRab25lTmFtZWAgb3IgYEhvc3RlZFpvbmVJZGAgLCBidXQgbm90IGJvdGguIElmIHlvdSBoYXZlIG11bHRpcGxlIGhvc3RlZCB6b25lcyB3aXRoIHRoZSBzYW1lIGRvbWFpbiBuYW1lLCB5b3UgbXVzdCBzcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSB1c2luZyBgSG9zdGVkWm9uZUlkYCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LWhvc3RlZHpvbmVuYW1lXG4gICAgICovXG4gICAgcHVibGljIGhvc3RlZFpvbmVOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiAqTXVsdGl2YWx1ZSBhbnN3ZXIgcmVzb3VyY2UgcmVjb3JkIHNldHMgb25seSogOiBUbyByb3V0ZSB0cmFmZmljIGFwcHJveGltYXRlbHkgcmFuZG9tbHkgdG8gbXVsdGlwbGUgcmVzb3VyY2VzLCBzdWNoIGFzIHdlYiBzZXJ2ZXJzLCBjcmVhdGUgb25lIG11bHRpdmFsdWUgYW5zd2VyIHJlY29yZCBmb3IgZWFjaCByZXNvdXJjZSBhbmQgc3BlY2lmeSBgdHJ1ZWAgZm9yIGBNdWx0aVZhbHVlQW5zd2VyYCAuIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gSWYgeW91IGFzc29jaWF0ZSBhIGhlYWx0aCBjaGVjayB3aXRoIGEgbXVsdGl2YWx1ZSBhbnN3ZXIgcmVzb3VyY2UgcmVjb3JkIHNldCwgQW1hem9uIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgSVAgYWRkcmVzcyBvbmx5IHdoZW4gdGhlIGhlYWx0aCBjaGVjayBpcyBoZWFsdGh5LlxuICAgICAqIC0gSWYgeW91IGRvbid0IGFzc29jaWF0ZSBhIGhlYWx0aCBjaGVjayB3aXRoIGEgbXVsdGl2YWx1ZSBhbnN3ZXIgcmVjb3JkLCBSb3V0ZSA1MyBhbHdheXMgY29uc2lkZXJzIHRoZSByZWNvcmQgdG8gYmUgaGVhbHRoeS5cbiAgICAgKiAtIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdXAgdG8gZWlnaHQgaGVhbHRoeSByZWNvcmRzOyBpZiB5b3UgaGF2ZSBlaWdodCBvciBmZXdlciBoZWFsdGh5IHJlY29yZHMsIFJvdXRlIDUzIHJlc3BvbmRzIHRvIGFsbCBETlMgcXVlcmllcyB3aXRoIGFsbCB0aGUgaGVhbHRoeSByZWNvcmRzLlxuICAgICAqIC0gSWYgeW91IGhhdmUgbW9yZSB0aGFuIGVpZ2h0IGhlYWx0aHkgcmVjb3JkcywgUm91dGUgNTMgcmVzcG9uZHMgdG8gZGlmZmVyZW50IEROUyByZXNvbHZlcnMgd2l0aCBkaWZmZXJlbnQgY29tYmluYXRpb25zIG9mIGhlYWx0aHkgcmVjb3Jkcy5cbiAgICAgKiAtIFdoZW4gYWxsIHJlY29yZHMgYXJlIHVuaGVhbHRoeSwgUm91dGUgNTMgcmVzcG9uZHMgdG8gRE5TIHF1ZXJpZXMgd2l0aCB1cCB0byBlaWdodCB1bmhlYWx0aHkgcmVjb3Jkcy5cbiAgICAgKiAtIElmIGEgcmVzb3VyY2UgYmVjb21lcyB1bmF2YWlsYWJsZSBhZnRlciBhIHJlc29sdmVyIGNhY2hlcyBhIHJlc3BvbnNlLCBjbGllbnQgc29mdHdhcmUgdHlwaWNhbGx5IHRyaWVzIGFub3RoZXIgb2YgdGhlIElQIGFkZHJlc3NlcyBpbiB0aGUgcmVzcG9uc2UuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuJ3QgY3JlYXRlIG11bHRpdmFsdWUgYW5zd2VyIGFsaWFzIHJlY29yZHMuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LW11bHRpdmFsdWVhbnN3ZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgbXVsdGlWYWx1ZUFuc3dlcjogYm9vbGVhbiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqICpMYXRlbmN5LWJhc2VkIHJlc291cmNlIHJlY29yZCBzZXRzIG9ubHk6KiBUaGUgQW1hem9uIEVDMiBSZWdpb24gd2hlcmUgeW91IGNyZWF0ZWQgdGhlIHJlc291cmNlIHRoYXQgdGhpcyByZXNvdXJjZSByZWNvcmQgc2V0IHJlZmVycyB0by4gVGhlIHJlc291cmNlIHR5cGljYWxseSBpcyBhbiBBV1MgcmVzb3VyY2UsIHN1Y2ggYXMgYW4gRUMyIGluc3RhbmNlIG9yIGFuIEVMQiBsb2FkIGJhbGFuY2VyLCBhbmQgaXMgcmVmZXJyZWQgdG8gYnkgYW4gSVAgYWRkcmVzcyBvciBhIEROUyBkb21haW4gbmFtZSwgZGVwZW5kaW5nIG9uIHRoZSByZWNvcmQgdHlwZS5cbiAgICAgKlxuICAgICAqID4gQWx0aG91Z2ggY3JlYXRpbmcgbGF0ZW5jeSBhbmQgbGF0ZW5jeSBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0cyBpbiBhIHByaXZhdGUgaG9zdGVkIHpvbmUgaXMgYWxsb3dlZCwgaXQncyBub3Qgc3VwcG9ydGVkLlxuICAgICAqXG4gICAgICogV2hlbiBBbWF6b24gUm91dGUgNTMgcmVjZWl2ZXMgYSBETlMgcXVlcnkgZm9yIGEgZG9tYWluIG5hbWUgYW5kIHR5cGUgZm9yIHdoaWNoIHlvdSBoYXZlIGNyZWF0ZWQgbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0cywgUm91dGUgNTMgc2VsZWN0cyB0aGUgbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0IHRoYXQgaGFzIHRoZSBsb3dlc3QgbGF0ZW5jeSBiZXR3ZWVuIHRoZSBlbmQgdXNlciBhbmQgdGhlIGFzc29jaWF0ZWQgQW1hem9uIEVDMiBSZWdpb24uIFJvdXRlIDUzIHRoZW4gcmV0dXJucyB0aGUgdmFsdWUgdGhhdCBpcyBhc3NvY2lhdGVkIHdpdGggdGhlIHNlbGVjdGVkIHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICpcbiAgICAgKiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIFlvdSBjYW4gb25seSBzcGVjaWZ5IG9uZSBgUmVzb3VyY2VSZWNvcmRgIHBlciBsYXRlbmN5IHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICogLSBZb3UgY2FuIG9ubHkgY3JlYXRlIG9uZSBsYXRlbmN5IHJlc291cmNlIHJlY29yZCBzZXQgZm9yIGVhY2ggQW1hem9uIEVDMiBSZWdpb24uXG4gICAgICogLSBZb3UgYXJlbid0IHJlcXVpcmVkIHRvIGNyZWF0ZSBsYXRlbmN5IHJlc291cmNlIHJlY29yZCBzZXRzIGZvciBhbGwgQW1hem9uIEVDMiBSZWdpb25zLiBSb3V0ZSA1MyB3aWxsIGNob29zZSB0aGUgcmVnaW9uIHdpdGggdGhlIGJlc3QgbGF0ZW5jeSBmcm9tIGFtb25nIHRoZSByZWdpb25zIHRoYXQgeW91IGNyZWF0ZSBsYXRlbmN5IHJlc291cmNlIHJlY29yZCBzZXRzIGZvci5cbiAgICAgKiAtIFlvdSBjYW4ndCBjcmVhdGUgbm9uLWxhdGVuY3kgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIHZhbHVlcyBmb3IgdGhlIGBOYW1lYCBhbmQgYFR5cGVgIGVsZW1lbnRzIGFzIGxhdGVuY3kgcmVzb3VyY2UgcmVjb3JkIHNldHMuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LXJlZ2lvblxuICAgICAqL1xuICAgIHB1YmxpYyByZWdpb246IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIE9uZSBvciBtb3JlIHZhbHVlcyB0aGF0IGNvcnJlc3BvbmQgd2l0aCB0aGUgdmFsdWUgdGhhdCB5b3Ugc3BlY2lmaWVkIGZvciB0aGUgYFR5cGVgIHByb3BlcnR5LiBGb3IgZXhhbXBsZSwgaWYgeW91IHNwZWNpZmllZCBgQWAgZm9yIGBUeXBlYCAsIHlvdSBzcGVjaWZ5IG9uZSBvciBtb3JlIElQIGFkZHJlc3NlcyBpbiBJUHY0IGZvcm1hdCBmb3IgYFJlc291cmNlUmVjb3Jkc2AgLiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGZvcm1hdCBvZiB2YWx1ZXMgZm9yIGVhY2ggcmVjb3JkIHR5cGUsIHNlZSBbU3VwcG9ydGVkIEROUyBSZXNvdXJjZSBSZWNvcmQgVHlwZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9SZXNvdXJjZVJlY29yZFR5cGVzLmh0bWwpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogTm90ZSB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBZb3UgY2FuIHNwZWNpZnkgbW9yZSB0aGFuIG9uZSB2YWx1ZSBmb3IgYWxsIHJlY29yZCB0eXBlcyBleGNlcHQgQ05BTUUgYW5kIFNPQS5cbiAgICAgKiAtIFRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhIHZhbHVlIGlzIDQwMDAgY2hhcmFjdGVycy5cbiAgICAgKiAtIElmIHlvdSdyZSBjcmVhdGluZyBhbiBhbGlhcyByZWNvcmQsIG9taXQgYFJlc291cmNlUmVjb3Jkc2AgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1yZXNvdXJjZXJlY29yZHNcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVzb3VyY2VSZWNvcmRzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqICpSZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgYSByb3V0aW5nIHBvbGljeSBvdGhlciB0aGFuIHNpbXBsZToqIEFuIGlkZW50aWZpZXIgdGhhdCBkaWZmZXJlbnRpYXRlcyBhbW9uZyBtdWx0aXBsZSByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgY29tYmluYXRpb24gb2YgbmFtZSBhbmQgdHlwZSwgc3VjaCBhcyBtdWx0aXBsZSB3ZWlnaHRlZCByZXNvdXJjZSByZWNvcmQgc2V0cyBuYW1lZCBhY21lLmV4YW1wbGUuY29tIHRoYXQgaGF2ZSBhIHR5cGUgb2YgQS4gSW4gYSBncm91cCBvZiByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgbmFtZSBhbmQgdHlwZSwgdGhlIHZhbHVlIG9mIGBTZXRJZGVudGlmaWVyYCBtdXN0IGJlIHVuaXF1ZSBmb3IgZWFjaCByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqXG4gICAgICogRm9yIGluZm9ybWF0aW9uIGFib3V0IHJvdXRpbmcgcG9saWNpZXMsIHNlZSBbQ2hvb3NpbmcgYSBSb3V0aW5nIFBvbGljeV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL3JvdXRpbmctcG9saWN5Lmh0bWwpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1zZXRpZGVudGlmaWVyXG4gICAgICovXG4gICAgcHVibGljIHNldElkZW50aWZpZXI6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSByZXNvdXJjZSByZWNvcmQgY2FjaGUgdGltZSB0byBsaXZlIChUVEwpLCBpbiBzZWNvbmRzLiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIElmIHlvdSdyZSBjcmVhdGluZyBvciB1cGRhdGluZyBhbiBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0LCBvbWl0IGBUVExgIC4gQW1hem9uIFJvdXRlIDUzIHVzZXMgdGhlIHZhbHVlIG9mIGBUVExgIGZvciB0aGUgYWxpYXMgdGFyZ2V0LlxuICAgICAqIC0gSWYgeW91J3JlIGFzc29jaWF0aW5nIHRoaXMgcmVzb3VyY2UgcmVjb3JkIHNldCB3aXRoIGEgaGVhbHRoIGNoZWNrIChpZiB5b3UncmUgYWRkaW5nIGEgYEhlYWx0aENoZWNrSWRgIGVsZW1lbnQpLCB3ZSByZWNvbW1lbmQgdGhhdCB5b3Ugc3BlY2lmeSBhIGBUVExgIG9mIDYwIHNlY29uZHMgb3IgbGVzcyBzbyBjbGllbnRzIHJlc3BvbmQgcXVpY2tseSB0byBjaGFuZ2VzIGluIGhlYWx0aCBzdGF0dXMuXG4gICAgICogLSBBbGwgb2YgdGhlIHJlc291cmNlIHJlY29yZCBzZXRzIGluIGEgZ3JvdXAgb2Ygd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMgbXVzdCBoYXZlIHRoZSBzYW1lIHZhbHVlIGZvciBgVFRMYCAuXG4gICAgICogLSBJZiBhIGdyb3VwIG9mIHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXRzIGluY2x1ZGVzIG9uZSBvciBtb3JlIHdlaWdodGVkIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzIGZvciB3aGljaCB0aGUgYWxpYXMgdGFyZ2V0IGlzIGFuIEVMQiBsb2FkIGJhbGFuY2VyLCB3ZSByZWNvbW1lbmQgdGhhdCB5b3Ugc3BlY2lmeSBhIGBUVExgIG9mIDYwIHNlY29uZHMgZm9yIGFsbCBvZiB0aGUgbm9uLWFsaWFzIHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSBuYW1lIGFuZCB0eXBlLiBWYWx1ZXMgb3RoZXIgdGhhbiA2MCBzZWNvbmRzICh0aGUgVFRMIGZvciBsb2FkIGJhbGFuY2Vycykgd2lsbCBjaGFuZ2UgdGhlIGVmZmVjdCBvZiB0aGUgdmFsdWVzIHRoYXQgeW91IHNwZWNpZnkgZm9yIGBXZWlnaHRgIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtdHRsXG4gICAgICovXG4gICAgcHVibGljIHR0bDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogKldlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXRzIG9ubHk6KiBBbW9uZyByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgY29tYmluYXRpb24gb2YgRE5TIG5hbWUgYW5kIHR5cGUsIGEgdmFsdWUgdGhhdCBkZXRlcm1pbmVzIHRoZSBwcm9wb3J0aW9uIG9mIEROUyBxdWVyaWVzIHRoYXQgQW1hem9uIFJvdXRlIDUzIHJlc3BvbmRzIHRvIHVzaW5nIHRoZSBjdXJyZW50IHJlc291cmNlIHJlY29yZCBzZXQuIFJvdXRlIDUzIGNhbGN1bGF0ZXMgdGhlIHN1bSBvZiB0aGUgd2VpZ2h0cyBmb3IgdGhlIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSBjb21iaW5hdGlvbiBvZiBETlMgbmFtZSBhbmQgdHlwZS4gUm91dGUgNTMgdGhlbiByZXNwb25kcyB0byBxdWVyaWVzIGJhc2VkIG9uIHRoZSByYXRpbyBvZiBhIHJlc291cmNlJ3Mgd2VpZ2h0IHRvIHRoZSB0b3RhbC4gTm90ZSB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBZb3UgbXVzdCBzcGVjaWZ5IGEgdmFsdWUgZm9yIHRoZSBgV2VpZ2h0YCBlbGVtZW50IGZvciBldmVyeSB3ZWlnaHRlZCByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqIC0gWW91IGNhbiBvbmx5IHNwZWNpZnkgb25lIGBSZXNvdXJjZVJlY29yZGAgcGVyIHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICogLSBZb3UgY2FuJ3QgY3JlYXRlIGxhdGVuY3ksIGZhaWxvdmVyLCBvciBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgdmFsdWVzIGZvciB0aGUgYE5hbWVgIGFuZCBgVHlwZWAgZWxlbWVudHMgYXMgd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMuXG4gICAgICogLSBZb3UgY2FuIGNyZWF0ZSBhIG1heGltdW0gb2YgMTAwIHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSB2YWx1ZXMgZm9yIHRoZSBgTmFtZWAgYW5kIGBUeXBlYCBlbGVtZW50cy5cbiAgICAgKiAtIEZvciB3ZWlnaHRlZCAoYnV0IG5vdCB3ZWlnaHRlZCBhbGlhcykgcmVzb3VyY2UgcmVjb3JkIHNldHMsIGlmIHlvdSBzZXQgYFdlaWdodGAgdG8gYDBgIGZvciBhIHJlc291cmNlIHJlY29yZCBzZXQsIFJvdXRlIDUzIG5ldmVyIHJlc3BvbmRzIHRvIHF1ZXJpZXMgd2l0aCB0aGUgYXBwbGljYWJsZSB2YWx1ZSBmb3IgdGhhdCByZXNvdXJjZSByZWNvcmQgc2V0LiBIb3dldmVyLCBpZiB5b3Ugc2V0IGBXZWlnaHRgIHRvIGAwYCBmb3IgYWxsIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSBjb21iaW5hdGlvbiBvZiBETlMgbmFtZSBhbmQgdHlwZSwgdHJhZmZpYyBpcyByb3V0ZWQgdG8gYWxsIHJlc291cmNlcyB3aXRoIGVxdWFsIHByb2JhYmlsaXR5LlxuICAgICAqXG4gICAgICogVGhlIGVmZmVjdCBvZiBzZXR0aW5nIGBXZWlnaHRgIHRvIGAwYCBpcyBkaWZmZXJlbnQgd2hlbiB5b3UgYXNzb2NpYXRlIGhlYWx0aCBjaGVja3Mgd2l0aCB3ZWlnaHRlZCByZXNvdXJjZSByZWNvcmQgc2V0cy4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbT3B0aW9ucyBmb3IgQ29uZmlndXJpbmcgUm91dGUgNTMgQWN0aXZlLUFjdGl2ZSBhbmQgQWN0aXZlLVBhc3NpdmUgRmFpbG92ZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9kbnMtZmFpbG92ZXItY29uZmlndXJpbmctb3B0aW9ucy5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtd2VpZ2h0XG4gICAgICovXG4gICAgcHVibGljIHdlaWdodDogbnVtYmVyIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldGAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuUmVjb3JkU2V0UHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmblJlY29yZFNldC5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ25hbWUnLCB0aGlzKTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ3R5cGUnLCB0aGlzKTtcblxuICAgICAgICB0aGlzLm5hbWUgPSBwcm9wcy5uYW1lO1xuICAgICAgICB0aGlzLnR5cGUgPSBwcm9wcy50eXBlO1xuICAgICAgICB0aGlzLmFsaWFzVGFyZ2V0ID0gcHJvcHMuYWxpYXNUYXJnZXQ7XG4gICAgICAgIHRoaXMuY29tbWVudCA9IHByb3BzLmNvbW1lbnQ7XG4gICAgICAgIHRoaXMuZmFpbG92ZXIgPSBwcm9wcy5mYWlsb3ZlcjtcbiAgICAgICAgdGhpcy5nZW9Mb2NhdGlvbiA9IHByb3BzLmdlb0xvY2F0aW9uO1xuICAgICAgICB0aGlzLmhlYWx0aENoZWNrSWQgPSBwcm9wcy5oZWFsdGhDaGVja0lkO1xuICAgICAgICB0aGlzLmhvc3RlZFpvbmVJZCA9IHByb3BzLmhvc3RlZFpvbmVJZDtcbiAgICAgICAgdGhpcy5ob3N0ZWRab25lTmFtZSA9IHByb3BzLmhvc3RlZFpvbmVOYW1lO1xuICAgICAgICB0aGlzLm11bHRpVmFsdWVBbnN3ZXIgPSBwcm9wcy5tdWx0aVZhbHVlQW5zd2VyO1xuICAgICAgICB0aGlzLnJlZ2lvbiA9IHByb3BzLnJlZ2lvbjtcbiAgICAgICAgdGhpcy5yZXNvdXJjZVJlY29yZHMgPSBwcm9wcy5yZXNvdXJjZVJlY29yZHM7XG4gICAgICAgIHRoaXMuc2V0SWRlbnRpZmllciA9IHByb3BzLnNldElkZW50aWZpZXI7XG4gICAgICAgIHRoaXMudHRsID0gcHJvcHMudHRsO1xuICAgICAgICB0aGlzLndlaWdodCA9IHByb3BzLndlaWdodDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmblJlY29yZFNldC5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FKTtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246cHJvcHNcIiwgdGhpcy5jZm5Qcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGNmblByb3BlcnRpZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAgICAgICAgYWxpYXNUYXJnZXQ6IHRoaXMuYWxpYXNUYXJnZXQsXG4gICAgICAgICAgICBjb21tZW50OiB0aGlzLmNvbW1lbnQsXG4gICAgICAgICAgICBmYWlsb3ZlcjogdGhpcy5mYWlsb3ZlcixcbiAgICAgICAgICAgIGdlb0xvY2F0aW9uOiB0aGlzLmdlb0xvY2F0aW9uLFxuICAgICAgICAgICAgaGVhbHRoQ2hlY2tJZDogdGhpcy5oZWFsdGhDaGVja0lkLFxuICAgICAgICAgICAgaG9zdGVkWm9uZUlkOiB0aGlzLmhvc3RlZFpvbmVJZCxcbiAgICAgICAgICAgIGhvc3RlZFpvbmVOYW1lOiB0aGlzLmhvc3RlZFpvbmVOYW1lLFxuICAgICAgICAgICAgbXVsdGlWYWx1ZUFuc3dlcjogdGhpcy5tdWx0aVZhbHVlQW5zd2VyLFxuICAgICAgICAgICAgcmVnaW9uOiB0aGlzLnJlZ2lvbixcbiAgICAgICAgICAgIHJlc291cmNlUmVjb3JkczogdGhpcy5yZXNvdXJjZVJlY29yZHMsXG4gICAgICAgICAgICBzZXRJZGVudGlmaWVyOiB0aGlzLnNldElkZW50aWZpZXIsXG4gICAgICAgICAgICB0dGw6IHRoaXMudHRsLFxuICAgICAgICAgICAgd2VpZ2h0OiB0aGlzLndlaWdodCxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5SZWNvcmRTZXRQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcHMpO1xuICAgIH1cbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5SZWNvcmRTZXQge1xuICAgIC8qKlxuICAgICAqICpBbGlhcyByZWNvcmRzIG9ubHk6KiBJbmZvcm1hdGlvbiBhYm91dCB0aGUgQVdTIHJlc291cmNlLCBzdWNoIGFzIGEgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24gb3IgYW4gQW1hem9uIFMzIGJ1Y2tldCwgdGhhdCB5b3Ugd2FudCB0byByb3V0ZSB0cmFmZmljIHRvLlxuICAgICAqXG4gICAgICogV2hlbiBjcmVhdGluZyByZWNvcmRzIGZvciBhIHByaXZhdGUgaG9zdGVkIHpvbmUsIG5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gQ3JlYXRpbmcgZ2VvbG9jYXRpb24gYWxpYXMgYW5kIGxhdGVuY3kgYWxpYXMgcmVjb3JkcyBpbiBhIHByaXZhdGUgaG9zdGVkIHpvbmUgaXMgYWxsb3dlZCBidXQgbm90IHN1cHBvcnRlZC5cbiAgICAgKiAtIEZvciBpbmZvcm1hdGlvbiBhYm91dCBjcmVhdGluZyBmYWlsb3ZlciByZWNvcmRzIGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSwgc2VlIFtDb25maWd1cmluZyBGYWlsb3ZlciBpbiBhIFByaXZhdGUgSG9zdGVkIFpvbmVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9kbnMtZmFpbG92ZXItcHJpdmF0ZS1ob3N0ZWQtem9uZXMuaHRtbCkgLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1hbGlhc3RhcmdldC5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBBbGlhc1RhcmdldFByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqICpBbGlhcyByZWNvcmRzIG9ubHk6KiBUaGUgdmFsdWUgdGhhdCB5b3Ugc3BlY2lmeSBkZXBlbmRzIG9uIHdoZXJlIHlvdSB3YW50IHRvIHJvdXRlIHF1ZXJpZXM6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKipBbWF6b24gQVBJIEdhdGV3YXkgY3VzdG9tIHJlZ2lvbmFsIEFQSXMgYW5kIGVkZ2Utb3B0aW1pemVkIEFQSXMqKiAtIFNwZWNpZnkgdGhlIGFwcGxpY2FibGUgZG9tYWluIG5hbWUgZm9yIHlvdXIgQVBJLiBZb3UgY2FuIGdldCB0aGUgYXBwbGljYWJsZSB2YWx1ZSB1c2luZyB0aGUgQVdTIENMSSBjb21tYW5kIFtnZXQtZG9tYWluLW5hbWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xpL2xhdGVzdC9yZWZlcmVuY2UvYXBpZ2F0ZXdheS9nZXQtZG9tYWluLW5hbWVzLmh0bWwpIDpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBGb3IgcmVnaW9uYWwgQVBJcywgc3BlY2lmeSB0aGUgdmFsdWUgb2YgYHJlZ2lvbmFsRG9tYWluTmFtZWAgLlxuICAgICAgICAgKiAtIEZvciBlZGdlLW9wdGltaXplZCBBUElzLCBzcGVjaWZ5IHRoZSB2YWx1ZSBvZiBgZGlzdHJpYnV0aW9uRG9tYWluTmFtZWAgLiBUaGlzIGlzIHRoZSBuYW1lIG9mIHRoZSBhc3NvY2lhdGVkIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uLCBzdWNoIGFzIGBkYTFiMmMzZDRlNS5jbG91ZGZyb250Lm5ldGAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFRoZSBuYW1lIG9mIHRoZSByZWNvcmQgdGhhdCB5b3UncmUgY3JlYXRpbmcgbXVzdCBtYXRjaCBhIGN1c3RvbSBkb21haW4gbmFtZSBmb3IgeW91ciBBUEksIHN1Y2ggYXMgYGFwaS5leGFtcGxlLmNvbWAgLlxuICAgICAgICAgKiAtICoqQW1hem9uIFZpcnR1YWwgUHJpdmF0ZSBDbG91ZCBpbnRlcmZhY2UgVlBDIGVuZHBvaW50KiogLSBFbnRlciB0aGUgQVBJIGVuZHBvaW50IGZvciB0aGUgaW50ZXJmYWNlIGVuZHBvaW50LCBzdWNoIGFzIGB2cGNlLTEyMzQ1Njc4OWFiY2RlZjAxLWV4YW1wbGUtdXMtZWFzdC0xYS5lbGFzdGljbG9hZGJhbGFuY2luZy51cy1lYXN0LTEudnBjZS5hbWF6b25hd3MuY29tYCAuIEZvciBlZGdlLW9wdGltaXplZCBBUElzLCB0aGlzIGlzIHRoZSBkb21haW4gbmFtZSBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24uIFlvdSBjYW4gZ2V0IHRoZSB2YWx1ZSBvZiBgRG5zTmFtZWAgdXNpbmcgdGhlIEFXUyBDTEkgY29tbWFuZCBbZGVzY3JpYmUtdnBjLWVuZHBvaW50c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsaS9sYXRlc3QvcmVmZXJlbmNlL2VjMi9kZXNjcmliZS12cGMtZW5kcG9pbnRzLmh0bWwpIC5cbiAgICAgICAgICogLSAqKkNsb3VkRnJvbnQgZGlzdHJpYnV0aW9uKiogLSBTcGVjaWZ5IHRoZSBkb21haW4gbmFtZSB0aGF0IENsb3VkRnJvbnQgYXNzaWduZWQgd2hlbiB5b3UgY3JlYXRlZCB5b3VyIGRpc3RyaWJ1dGlvbi5cbiAgICAgICAgICpcbiAgICAgICAgICogWW91ciBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbiBtdXN0IGluY2x1ZGUgYW4gYWx0ZXJuYXRlIGRvbWFpbiBuYW1lIHRoYXQgbWF0Y2hlcyB0aGUgbmFtZSBvZiB0aGUgcmVjb3JkLiBGb3IgZXhhbXBsZSwgaWYgdGhlIG5hbWUgb2YgdGhlIHJlY29yZCBpcyAqYWNtZS5leGFtcGxlLmNvbSogLCB5b3VyIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uIG11c3QgaW5jbHVkZSAqYWNtZS5leGFtcGxlLmNvbSogYXMgb25lIG9mIHRoZSBhbHRlcm5hdGUgZG9tYWluIG5hbWVzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtVc2luZyBBbHRlcm5hdGUgRG9tYWluIE5hbWVzIChDTkFNRXMpXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRGcm9udC9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvQ05BTUVzLmh0bWwpIGluIHRoZSAqQW1hem9uIENsb3VkRnJvbnQgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIFlvdSBjYW4ndCBjcmVhdGUgYSByZWNvcmQgaW4gYSBwcml2YXRlIGhvc3RlZCB6b25lIHRvIHJvdXRlIHRyYWZmaWMgdG8gYSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbi5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBGb3IgZmFpbG92ZXIgYWxpYXMgcmVjb3JkcywgeW91IGNhbid0IHNwZWNpZnkgYSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbiBmb3IgYm90aCB0aGUgcHJpbWFyeSBhbmQgc2Vjb25kYXJ5IHJlY29yZHMuIEEgZGlzdHJpYnV0aW9uIG11c3QgaW5jbHVkZSBhbiBhbHRlcm5hdGUgZG9tYWluIG5hbWUgdGhhdCBtYXRjaGVzIHRoZSBuYW1lIG9mIHRoZSByZWNvcmQuIEhvd2V2ZXIsIHRoZSBwcmltYXJ5IGFuZCBzZWNvbmRhcnkgcmVjb3JkcyBoYXZlIHRoZSBzYW1lIG5hbWUsIGFuZCB5b3UgY2FuJ3QgaW5jbHVkZSB0aGUgc2FtZSBhbHRlcm5hdGUgZG9tYWluIG5hbWUgaW4gbW9yZSB0aGFuIG9uZSBkaXN0cmlidXRpb24uXG4gICAgICAgICAqIC0gKipFbGFzdGljIEJlYW5zdGFsayBlbnZpcm9ubWVudCoqIC0gSWYgdGhlIGRvbWFpbiBuYW1lIGZvciB5b3VyIEVsYXN0aWMgQmVhbnN0YWxrIGVudmlyb25tZW50IGluY2x1ZGVzIHRoZSByZWdpb24gdGhhdCB5b3UgZGVwbG95ZWQgdGhlIGVudmlyb25tZW50IGluLCB5b3UgY2FuIGNyZWF0ZSBhbiBhbGlhcyByZWNvcmQgdGhhdCByb3V0ZXMgdHJhZmZpYyB0byB0aGUgZW52aXJvbm1lbnQuIEZvciBleGFtcGxlLCB0aGUgZG9tYWluIG5hbWUgYG15LWVudmlyb25tZW50LiAqdXMtd2VzdC0yKiAuZWxhc3RpY2JlYW5zdGFsay5jb21gIGlzIGEgcmVnaW9uYWxpemVkIGRvbWFpbiBuYW1lLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IEZvciBlbnZpcm9ubWVudHMgdGhhdCB3ZXJlIGNyZWF0ZWQgYmVmb3JlIGVhcmx5IDIwMTYsIHRoZSBkb21haW4gbmFtZSBkb2Vzbid0IGluY2x1ZGUgdGhlIHJlZ2lvbi4gVG8gcm91dGUgdHJhZmZpYyB0byB0aGVzZSBlbnZpcm9ubWVudHMsIHlvdSBtdXN0IGNyZWF0ZSBhIENOQU1FIHJlY29yZCBpbnN0ZWFkIG9mIGFuIGFsaWFzIHJlY29yZC4gTm90ZSB0aGF0IHlvdSBjYW4ndCBjcmVhdGUgYSBDTkFNRSByZWNvcmQgZm9yIHRoZSByb290IGRvbWFpbiBuYW1lLiBGb3IgZXhhbXBsZSwgaWYgeW91ciBkb21haW4gbmFtZSBpcyBleGFtcGxlLmNvbSwgeW91IGNhbiBjcmVhdGUgYSByZWNvcmQgdGhhdCByb3V0ZXMgdHJhZmZpYyBmb3IgYWNtZS5leGFtcGxlLmNvbSB0byB5b3VyIEVsYXN0aWMgQmVhbnN0YWxrIGVudmlyb25tZW50LCBidXQgeW91IGNhbid0IGNyZWF0ZSBhIHJlY29yZCB0aGF0IHJvdXRlcyB0cmFmZmljIGZvciBleGFtcGxlLmNvbSB0byB5b3VyIEVsYXN0aWMgQmVhbnN0YWxrIGVudmlyb25tZW50LlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgRWxhc3RpYyBCZWFuc3RhbGsgZW52aXJvbm1lbnRzIHRoYXQgaGF2ZSByZWdpb25hbGl6ZWQgc3ViZG9tYWlucywgc3BlY2lmeSB0aGUgYENOQU1FYCBhdHRyaWJ1dGUgZm9yIHRoZSBlbnZpcm9ubWVudC4gWW91IGNhbiB1c2UgdGhlIGZvbGxvd2luZyBtZXRob2RzIHRvIGdldCB0aGUgdmFsdWUgb2YgdGhlIENOQU1FIGF0dHJpYnV0ZTpcbiAgICAgICAgICpcbiAgICAgICAgICogLSAqQVdTIE1hbmFnZW1lbnQgQ29uc29sZSogOiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgaG93IHRvIGdldCB0aGUgdmFsdWUgYnkgdXNpbmcgdGhlIGNvbnNvbGUsIHNlZSBbVXNpbmcgQ3VzdG9tIERvbWFpbnMgd2l0aCBBV1MgRWxhc3RpYyBCZWFuc3RhbGtdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljYmVhbnN0YWxrL2xhdGVzdC9kZy9jdXN0b21kb21haW5zLmh0bWwpIGluIHRoZSAqQVdTIEVsYXN0aWMgQmVhbnN0YWxrIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKiAtICpFbGFzdGljIEJlYW5zdGFsayBBUEkqIDogVXNlIHRoZSBgRGVzY3JpYmVFbnZpcm9ubWVudHNgIGFjdGlvbiB0byBnZXQgdGhlIHZhbHVlIG9mIHRoZSBgQ05BTUVgIGF0dHJpYnV0ZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbRGVzY3JpYmVFbnZpcm9ubWVudHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljYmVhbnN0YWxrL2xhdGVzdC9hcGkvQVBJX0Rlc2NyaWJlRW52aXJvbm1lbnRzLmh0bWwpIGluIHRoZSAqQVdTIEVsYXN0aWMgQmVhbnN0YWxrIEFQSSBSZWZlcmVuY2UqIC5cbiAgICAgICAgICogLSAqQVdTIENMSSogOiBVc2UgdGhlIGBkZXNjcmliZS1lbnZpcm9ubWVudHNgIGNvbW1hbmQgdG8gZ2V0IHRoZSB2YWx1ZSBvZiB0aGUgYENOQU1FYCBhdHRyaWJ1dGUuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW2Rlc2NyaWJlLWVudmlyb25tZW50c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsaS9sYXRlc3QvcmVmZXJlbmNlL2VsYXN0aWNiZWFuc3RhbGsvZGVzY3JpYmUtZW52aXJvbm1lbnRzLmh0bWwpIGluIHRoZSAqQVdTIENMSSogLlxuICAgICAgICAgKiAtICoqRUxCIGxvYWQgYmFsYW5jZXIqKiAtIFNwZWNpZnkgdGhlIEROUyBuYW1lIHRoYXQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBsb2FkIGJhbGFuY2VyLiBHZXQgdGhlIEROUyBuYW1lIGJ5IHVzaW5nIHRoZSBBV1MgTWFuYWdlbWVudCBDb25zb2xlICwgdGhlIEVMQiBBUEksIG9yIHRoZSBBV1MgQ0xJIC5cbiAgICAgICAgICpcbiAgICAgICAgICogLSAqQVdTIE1hbmFnZW1lbnQgQ29uc29sZSogOiBHbyB0byB0aGUgRUMyIHBhZ2UsIGNob29zZSAqTG9hZCBCYWxhbmNlcnMqIGluIHRoZSBuYXZpZ2F0aW9uIHBhbmUsIGNob29zZSB0aGUgbG9hZCBiYWxhbmNlciwgY2hvb3NlIHRoZSAqRGVzY3JpcHRpb24qIHRhYiwgYW5kIGdldCB0aGUgdmFsdWUgb2YgdGhlICpETlMgbmFtZSogZmllbGQuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSdyZSByb3V0aW5nIHRyYWZmaWMgdG8gYSBDbGFzc2ljIExvYWQgQmFsYW5jZXIsIGdldCB0aGUgdmFsdWUgdGhhdCBiZWdpbnMgd2l0aCAqZHVhbHN0YWNrKiAuIElmIHlvdSdyZSByb3V0aW5nIHRyYWZmaWMgdG8gYW5vdGhlciB0eXBlIG9mIGxvYWQgYmFsYW5jZXIsIGdldCB0aGUgdmFsdWUgdGhhdCBhcHBsaWVzIHRvIHRoZSByZWNvcmQgdHlwZSwgQSBvciBBQUFBLlxuICAgICAgICAgKiAtICpFbGFzdGljIExvYWQgQmFsYW5jaW5nIEFQSSogOiBVc2UgYERlc2NyaWJlTG9hZEJhbGFuY2Vyc2AgdG8gZ2V0IHRoZSB2YWx1ZSBvZiBgRE5TTmFtZWAgLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIHRoZSBhcHBsaWNhYmxlIGd1aWRlOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIENsYXNzaWMgTG9hZCBCYWxhbmNlcnM6IFtEZXNjcmliZUxvYWRCYWxhbmNlcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVMb2FkQmFsYW5jZXJzLmh0bWwpXG4gICAgICAgICAqIC0gQXBwbGljYXRpb24gYW5kIE5ldHdvcmsgTG9hZCBCYWxhbmNlcnM6IFtEZXNjcmliZUxvYWRCYWxhbmNlcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUxvYWRCYWxhbmNlcnMuaHRtbClcbiAgICAgICAgICogLSAqQ2xvdWRGb3JtYXRpb24gRm46OkdldEF0dCBpbnRyaW5zaWMgZnVuY3Rpb24qIDogVXNlIHRoZSBbRm46OkdldEF0dF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvaW50cmluc2ljLWZ1bmN0aW9uLXJlZmVyZW5jZS1nZXRhdHQuaHRtbCkgaW50cmluc2ljIGZ1bmN0aW9uIHRvIGdldCB0aGUgdmFsdWUgb2YgYEROU05hbWVgIDpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBbQ2xhc3NpYyBMb2FkIEJhbGFuY2Vyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWMyLWVsYi5odG1sI2F3cy1wcm9wZXJ0aWVzLWVjMi1lbGItcmV0dXJuLXZhbHVlcykgLlxuICAgICAgICAgKiAtIFtBcHBsaWNhdGlvbiBhbmQgTmV0d29yayBMb2FkIEJhbGFuY2Vyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVsYXN0aWNsb2FkYmFsYW5jaW5ndjItbG9hZGJhbGFuY2VyLmh0bWwjYXdzLXJlc291cmNlLWVsYXN0aWNsb2FkYmFsYW5jaW5ndjItbG9hZGJhbGFuY2VyLXJldHVybi12YWx1ZXMpIC5cbiAgICAgICAgICogLSAqQVdTIENMSSogOiBVc2UgYGRlc2NyaWJlLWxvYWQtYmFsYW5jZXJzYCB0byBnZXQgdGhlIHZhbHVlIG9mIGBETlNOYW1lYCAuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgdGhlIGFwcGxpY2FibGUgZ3VpZGU6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gQ2xhc3NpYyBMb2FkIEJhbGFuY2VyczogW2Rlc2NyaWJlLWxvYWQtYmFsYW5jZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xpL2xhdGVzdC9yZWZlcmVuY2UvZWxiL2Rlc2NyaWJlLWxvYWQtYmFsYW5jZXJzLmh0bWwpXG4gICAgICAgICAqIC0gQXBwbGljYXRpb24gYW5kIE5ldHdvcmsgTG9hZCBCYWxhbmNlcnM6IFtkZXNjcmliZS1sb2FkLWJhbGFuY2Vyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsaS9sYXRlc3QvcmVmZXJlbmNlL2VsYnYyL2Rlc2NyaWJlLWxvYWQtYmFsYW5jZXJzLmh0bWwpXG4gICAgICAgICAqIC0gKipHbG9iYWwgQWNjZWxlcmF0b3IgYWNjZWxlcmF0b3IqKiAtIFNwZWNpZnkgdGhlIEROUyBuYW1lIGZvciB5b3VyIGFjY2VsZXJhdG9yOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICpHbG9iYWwgQWNjZWxlcmF0b3IgQVBJKiA6IFRvIGdldCB0aGUgRE5TIG5hbWUsIHVzZSBbRGVzY3JpYmVBY2NlbGVyYXRvcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dsb2JhbC1hY2NlbGVyYXRvci9sYXRlc3QvYXBpL0FQSV9EZXNjcmliZUFjY2VsZXJhdG9yLmh0bWwpIC5cbiAgICAgICAgICogLSAqQVdTIENMSSogOiBUbyBnZXQgdGhlIEROUyBuYW1lLCB1c2UgW2Rlc2NyaWJlLWFjY2VsZXJhdG9yXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xpL2xhdGVzdC9yZWZlcmVuY2UvZ2xvYmFsYWNjZWxlcmF0b3IvZGVzY3JpYmUtYWNjZWxlcmF0b3IuaHRtbCkgLlxuICAgICAgICAgKiAtICoqQW1hem9uIFMzIGJ1Y2tldCB0aGF0IGlzIGNvbmZpZ3VyZWQgYXMgYSBzdGF0aWMgd2Vic2l0ZSoqIC0gU3BlY2lmeSB0aGUgZG9tYWluIG5hbWUgb2YgdGhlIEFtYXpvbiBTMyB3ZWJzaXRlIGVuZHBvaW50IHRoYXQgeW91IGNyZWF0ZWQgdGhlIGJ1Y2tldCBpbiwgZm9yIGV4YW1wbGUsIGBzMy13ZWJzaXRlLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tYCAuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHZhbGlkIHZhbHVlcywgc2VlIHRoZSB0YWJsZSBbQW1hem9uIFMzIFdlYnNpdGUgRW5kcG9pbnRzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2VuZXJhbC9sYXRlc3QvZ3IvczMuaHRtbCNzM193ZWJzaXRlX3JlZ2lvbl9lbmRwb2ludHMpIGluIHRoZSAqQW1hem9uIFdlYiBTZXJ2aWNlcyBHZW5lcmFsIFJlZmVyZW5jZSogLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB1c2luZyBTMyBidWNrZXRzIGZvciB3ZWJzaXRlcywgc2VlIFtHZXR0aW5nIFN0YXJ0ZWQgd2l0aCBBbWF6b24gUm91dGUgNTNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9nZXR0aW5nLXN0YXJ0ZWQuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlLipcbiAgICAgICAgICogLSAqKkFub3RoZXIgUm91dGUgNTMgcmVjb3JkKiogLSBTcGVjaWZ5IHRoZSB2YWx1ZSBvZiB0aGUgYE5hbWVgIGVsZW1lbnQgZm9yIGEgcmVjb3JkIGluIHRoZSBjdXJyZW50IGhvc3RlZCB6b25lLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IElmIHlvdSdyZSBjcmVhdGluZyBhbiBhbGlhcyByZWNvcmQgdGhhdCBoYXMgdGhlIHNhbWUgbmFtZSBhcyB0aGUgaG9zdGVkIHpvbmUgKGtub3duIGFzIHRoZSB6b25lIGFwZXgpLCB5b3UgY2FuJ3Qgc3BlY2lmeSB0aGUgZG9tYWluIG5hbWUgZm9yIGEgcmVjb3JkIGZvciB3aGljaCB0aGUgdmFsdWUgb2YgYFR5cGVgIGlzIGBDTkFNRWAgLiBUaGlzIGlzIGJlY2F1c2UgdGhlIGFsaWFzIHJlY29yZCBtdXN0IGhhdmUgdGhlIHNhbWUgdHlwZSBhcyB0aGUgcmVjb3JkIHRoYXQgeW91J3JlIHJvdXRpbmcgdHJhZmZpYyB0bywgYW5kIGNyZWF0aW5nIGEgQ05BTUUgcmVjb3JkIGZvciB0aGUgem9uZSBhcGV4IGlzbid0IHN1cHBvcnRlZCBldmVuIGZvciBhbiBhbGlhcyByZWNvcmQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1hbGlhc3RhcmdldC5odG1sI2Nmbi1yb3V0ZTUzLWFsaWFzdGFyZ2V0LWRuc2hvc3RuYW1lXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBkbnNOYW1lOiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiAqQXBwbGllcyBvbmx5IHRvIGFsaWFzLCBmYWlsb3ZlciBhbGlhcywgZ2VvbG9jYXRpb24gYWxpYXMsIGxhdGVuY3kgYWxpYXMsIGFuZCB3ZWlnaHRlZCBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0czoqIFdoZW4gYEV2YWx1YXRlVGFyZ2V0SGVhbHRoYCBpcyBgdHJ1ZWAgLCBhbiBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0IGluaGVyaXRzIHRoZSBoZWFsdGggb2YgdGhlIHJlZmVyZW5jZWQgQVdTIHJlc291cmNlLCBzdWNoIGFzIGFuIEVMQiBsb2FkIGJhbGFuY2VyIG9yIGFub3RoZXIgcmVzb3VyY2UgcmVjb3JkIHNldCBpbiB0aGUgaG9zdGVkIHpvbmUuXG4gICAgICAgICAqXG4gICAgICAgICAqIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgICAgICpcbiAgICAgICAgICogLSAqKkNsb3VkRnJvbnQgZGlzdHJpYnV0aW9ucyoqIC0gWW91IGNhbid0IHNldCBgRXZhbHVhdGVUYXJnZXRIZWFsdGhgIHRvIGB0cnVlYCB3aGVuIHRoZSBhbGlhcyB0YXJnZXQgaXMgYSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbi5cbiAgICAgICAgICogLSAqKkVsYXN0aWMgQmVhbnN0YWxrIGVudmlyb25tZW50cyB0aGF0IGhhdmUgcmVnaW9uYWxpemVkIHN1YmRvbWFpbnMqKiAtIElmIHlvdSBzcGVjaWZ5IGFuIEVsYXN0aWMgQmVhbnN0YWxrIGVudmlyb25tZW50IGluIGBETlNOYW1lYCBhbmQgdGhlIGVudmlyb25tZW50IGNvbnRhaW5zIGFuIEVMQiBsb2FkIGJhbGFuY2VyLCBFbGFzdGljIExvYWQgQmFsYW5jaW5nIHJvdXRlcyBxdWVyaWVzIG9ubHkgdG8gdGhlIGhlYWx0aHkgQW1hem9uIEVDMiBpbnN0YW5jZXMgdGhhdCBhcmUgcmVnaXN0ZXJlZCB3aXRoIHRoZSBsb2FkIGJhbGFuY2VyLiAoQW4gZW52aXJvbm1lbnQgYXV0b21hdGljYWxseSBjb250YWlucyBhbiBFTEIgbG9hZCBiYWxhbmNlciBpZiBpdCBpbmNsdWRlcyBtb3JlIHRoYW4gb25lIEFtYXpvbiBFQzIgaW5zdGFuY2UuKSBJZiB5b3Ugc2V0IGBFdmFsdWF0ZVRhcmdldEhlYWx0aGAgdG8gYHRydWVgIGFuZCBlaXRoZXIgbm8gQW1hem9uIEVDMiBpbnN0YW5jZXMgYXJlIGhlYWx0aHkgb3IgdGhlIGxvYWQgYmFsYW5jZXIgaXRzZWxmIGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgcm91dGVzIHF1ZXJpZXMgdG8gb3RoZXIgYXZhaWxhYmxlIHJlc291cmNlcyB0aGF0IGFyZSBoZWFsdGh5LCBpZiBhbnkuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHRoZSBlbnZpcm9ubWVudCBjb250YWlucyBhIHNpbmdsZSBBbWF6b24gRUMyIGluc3RhbmNlLCB0aGVyZSBhcmUgbm8gc3BlY2lhbCByZXF1aXJlbWVudHMuXG4gICAgICAgICAqIC0gKipFTEIgbG9hZCBiYWxhbmNlcnMqKiAtIEhlYWx0aCBjaGVja2luZyBiZWhhdmlvciBkZXBlbmRzIG9uIHRoZSB0eXBlIG9mIGxvYWQgYmFsYW5jZXI6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKkNsYXNzaWMgTG9hZCBCYWxhbmNlcnMqIDogSWYgeW91IHNwZWNpZnkgYW4gRUxCIENsYXNzaWMgTG9hZCBCYWxhbmNlciBpbiBgRE5TTmFtZWAgLCBFbGFzdGljIExvYWQgQmFsYW5jaW5nIHJvdXRlcyBxdWVyaWVzIG9ubHkgdG8gdGhlIGhlYWx0aHkgQW1hem9uIEVDMiBpbnN0YW5jZXMgdGhhdCBhcmUgcmVnaXN0ZXJlZCB3aXRoIHRoZSBsb2FkIGJhbGFuY2VyLiBJZiB5b3Ugc2V0IGBFdmFsdWF0ZVRhcmdldEhlYWx0aGAgdG8gYHRydWVgIGFuZCBlaXRoZXIgbm8gRUMyIGluc3RhbmNlcyBhcmUgaGVhbHRoeSBvciB0aGUgbG9hZCBiYWxhbmNlciBpdHNlbGYgaXMgdW5oZWFsdGh5LCBSb3V0ZSA1MyByb3V0ZXMgcXVlcmllcyB0byBvdGhlciByZXNvdXJjZXMuXG4gICAgICAgICAqIC0gKkFwcGxpY2F0aW9uIGFuZCBOZXR3b3JrIExvYWQgQmFsYW5jZXJzKiA6IElmIHlvdSBzcGVjaWZ5IGFuIEVMQiBBcHBsaWNhdGlvbiBvciBOZXR3b3JrIExvYWQgQmFsYW5jZXIgYW5kIHlvdSBzZXQgYEV2YWx1YXRlVGFyZ2V0SGVhbHRoYCB0byBgdHJ1ZWAgLCBSb3V0ZSA1MyByb3V0ZXMgcXVlcmllcyB0byB0aGUgbG9hZCBiYWxhbmNlciBiYXNlZCBvbiB0aGUgaGVhbHRoIG9mIHRoZSB0YXJnZXQgZ3JvdXBzIHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgbG9hZCBiYWxhbmNlcjpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBGb3IgYW4gQXBwbGljYXRpb24gb3IgTmV0d29yayBMb2FkIEJhbGFuY2VyIHRvIGJlIGNvbnNpZGVyZWQgaGVhbHRoeSwgZXZlcnkgdGFyZ2V0IGdyb3VwIHRoYXQgY29udGFpbnMgdGFyZ2V0cyBtdXN0IGNvbnRhaW4gYXQgbGVhc3Qgb25lIGhlYWx0aHkgdGFyZ2V0LiBJZiBhbnkgdGFyZ2V0IGdyb3VwIGNvbnRhaW5zIG9ubHkgdW5oZWFsdGh5IHRhcmdldHMsIHRoZSBsb2FkIGJhbGFuY2VyIGlzIGNvbnNpZGVyZWQgdW5oZWFsdGh5LCBhbmQgUm91dGUgNTMgcm91dGVzIHF1ZXJpZXMgdG8gb3RoZXIgcmVzb3VyY2VzLlxuICAgICAgICAgKiAtIEEgdGFyZ2V0IGdyb3VwIHRoYXQgaGFzIG5vIHJlZ2lzdGVyZWQgdGFyZ2V0cyBpcyBjb25zaWRlcmVkIHVuaGVhbHRoeS5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBXaGVuIHlvdSBjcmVhdGUgYSBsb2FkIGJhbGFuY2VyLCB5b3UgY29uZmlndXJlIHNldHRpbmdzIGZvciBFbGFzdGljIExvYWQgQmFsYW5jaW5nIGhlYWx0aCBjaGVja3M7IHRoZXkncmUgbm90IFJvdXRlIDUzIGhlYWx0aCBjaGVja3MsIGJ1dCB0aGV5IHBlcmZvcm0gYSBzaW1pbGFyIGZ1bmN0aW9uLiBEbyBub3QgY3JlYXRlIFJvdXRlIDUzIGhlYWx0aCBjaGVja3MgZm9yIHRoZSBFQzIgaW5zdGFuY2VzIHRoYXQgeW91IHJlZ2lzdGVyIHdpdGggYW4gRUxCIGxvYWQgYmFsYW5jZXIuXG4gICAgICAgICAqIC0gKipTMyBidWNrZXRzKiogLSBUaGVyZSBhcmUgbm8gc3BlY2lhbCByZXF1aXJlbWVudHMgZm9yIHNldHRpbmcgYEV2YWx1YXRlVGFyZ2V0SGVhbHRoYCB0byBgdHJ1ZWAgd2hlbiB0aGUgYWxpYXMgdGFyZ2V0IGlzIGFuIFMzIGJ1Y2tldC5cbiAgICAgICAgICogLSAqKk90aGVyIHJlY29yZHMgaW4gdGhlIHNhbWUgaG9zdGVkIHpvbmUqKiAtIElmIHRoZSBBV1MgcmVzb3VyY2UgdGhhdCB5b3Ugc3BlY2lmeSBpbiBgRE5TTmFtZWAgaXMgYSByZWNvcmQgb3IgYSBncm91cCBvZiByZWNvcmRzIChmb3IgZXhhbXBsZSwgYSBncm91cCBvZiB3ZWlnaHRlZCByZWNvcmRzKSBidXQgaXMgbm90IGFub3RoZXIgYWxpYXMgcmVjb3JkLCB3ZSByZWNvbW1lbmQgdGhhdCB5b3UgYXNzb2NpYXRlIGEgaGVhbHRoIGNoZWNrIHdpdGggYWxsIG9mIHRoZSByZWNvcmRzIGluIHRoZSBhbGlhcyB0YXJnZXQuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1doYXQgSGFwcGVucyBXaGVuIFlvdSBPbWl0IEhlYWx0aCBDaGVja3M/XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLWNvbXBsZXgtY29uZmlncy5odG1sI2Rucy1mYWlsb3Zlci1jb21wbGV4LWNvbmZpZ3MtaGMtb21pdHRpbmcpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhbmQgZXhhbXBsZXMsIHNlZSBbQW1hem9uIFJvdXRlIDUzIEhlYWx0aCBDaGVja3MgYW5kIEROUyBGYWlsb3Zlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWFsaWFzdGFyZ2V0Lmh0bWwjY2ZuLXJvdXRlNTMtYWxpYXN0YXJnZXQtZXZhbHVhdGV0YXJnZXRoZWFsdGhcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGV2YWx1YXRlVGFyZ2V0SGVhbHRoPzogYm9vbGVhbiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqICpBbGlhcyByZXNvdXJjZSByZWNvcmRzIHNldHMgb25seSogOiBUaGUgdmFsdWUgdXNlZCBkZXBlbmRzIG9uIHdoZXJlIHlvdSB3YW50IHRvIHJvdXRlIHRyYWZmaWM6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKipBbWF6b24gQVBJIEdhdGV3YXkgY3VzdG9tIHJlZ2lvbmFsIEFQSXMgYW5kIGVkZ2Utb3B0aW1pemVkIEFQSXMqKiAtIFNwZWNpZnkgdGhlIGhvc3RlZCB6b25lIElEIGZvciB5b3VyIEFQSS4gWW91IGNhbiBnZXQgdGhlIGFwcGxpY2FibGUgdmFsdWUgdXNpbmcgdGhlIEFXUyBDTEkgY29tbWFuZCBbZ2V0LWRvbWFpbi1uYW1lc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsaS9sYXRlc3QvcmVmZXJlbmNlL2FwaWdhdGV3YXkvZ2V0LWRvbWFpbi1uYW1lcy5odG1sKSA6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gRm9yIHJlZ2lvbmFsIEFQSXMsIHNwZWNpZnkgdGhlIHZhbHVlIG9mIGByZWdpb25hbEhvc3RlZFpvbmVJZGAgLlxuICAgICAgICAgKiAtIEZvciBlZGdlLW9wdGltaXplZCBBUElzLCBzcGVjaWZ5IHRoZSB2YWx1ZSBvZiBgZGlzdHJpYnV0aW9uSG9zdGVkWm9uZUlkYCAuXG4gICAgICAgICAqIC0gKipBbWF6b24gVmlydHVhbCBQcml2YXRlIENsb3VkIGludGVyZmFjZSBWUEMgZW5kcG9pbnQqKiAtIFNwZWNpZnkgdGhlIGhvc3RlZCB6b25lIElEIGZvciB5b3VyIGludGVyZmFjZSBlbmRwb2ludC4gWW91IGNhbiBnZXQgdGhlIHZhbHVlIG9mIGBIb3N0ZWRab25lSWRgIHVzaW5nIHRoZSBBV1MgQ0xJIGNvbW1hbmQgW2Rlc2NyaWJlLXZwYy1lbmRwb2ludHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGkvbGF0ZXN0L3JlZmVyZW5jZS9lYzIvZGVzY3JpYmUtdnBjLWVuZHBvaW50cy5odG1sKSAuXG4gICAgICAgICAqIC0gKipDbG91ZEZyb250IGRpc3RyaWJ1dGlvbioqIC0gU3BlY2lmeSBgWjJGRFROREFUQVFZVzJgIC4gVGhpcyBpcyBhbHdheXMgdGhlIGhvc3RlZCB6b25lIElEIHdoZW4geW91IGNyZWF0ZSBhbiBhbGlhcyByZWNvcmQgdGhhdCByb3V0ZXMgdHJhZmZpYyB0byBhIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IEFsaWFzIHJlY29yZHMgZm9yIENsb3VkRnJvbnQgY2FuJ3QgYmUgY3JlYXRlZCBpbiBhIHByaXZhdGUgem9uZS5cbiAgICAgICAgICogLSAqKkVsYXN0aWMgQmVhbnN0YWxrIGVudmlyb25tZW50KiogLSBTcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSBJRCBmb3IgdGhlIHJlZ2lvbiB0aGF0IHlvdSBjcmVhdGVkIHRoZSBlbnZpcm9ubWVudCBpbi4gVGhlIGVudmlyb25tZW50IG11c3QgaGF2ZSBhIHJlZ2lvbmFsaXplZCBzdWJkb21haW4uIEZvciBhIGxpc3Qgb2YgcmVnaW9ucyBhbmQgdGhlIGNvcnJlc3BvbmRpbmcgaG9zdGVkIHpvbmUgSURzLCBzZWUgW0FXUyBFbGFzdGljIEJlYW5zdGFsayBlbmRwb2ludHMgYW5kIHF1b3Rhc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dlbmVyYWwvbGF0ZXN0L2dyL2VsYXN0aWNiZWFuc3RhbGsuaHRtbCkgaW4gdGhlICpBbWF6b24gV2ViIFNlcnZpY2VzIEdlbmVyYWwgUmVmZXJlbmNlKiAuXG4gICAgICAgICAqIC0gKipFTEIgbG9hZCBiYWxhbmNlcioqIC0gU3BlY2lmeSB0aGUgdmFsdWUgb2YgdGhlIGhvc3RlZCB6b25lIElEIGZvciB0aGUgbG9hZCBiYWxhbmNlci4gVXNlIHRoZSBmb2xsb3dpbmcgbWV0aG9kcyB0byBnZXQgdGhlIGhvc3RlZCB6b25lIElEOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIFtTZXJ2aWNlIEVuZHBvaW50c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dlbmVyYWwvbGF0ZXN0L2dyL2VsYi5odG1sKSB0YWJsZSBpbiB0aGUgXCJFbGFzdGljIExvYWQgQmFsYW5jaW5nIEVuZHBvaW50cyBhbmQgUXVvdGFzXCIgdG9waWMgaW4gdGhlICpBbWF6b24gV2ViIFNlcnZpY2VzIEdlbmVyYWwgUmVmZXJlbmNlKiA6IFVzZSB0aGUgdmFsdWUgdGhhdCBjb3JyZXNwb25kcyB3aXRoIHRoZSByZWdpb24gdGhhdCB5b3UgY3JlYXRlZCB5b3VyIGxvYWQgYmFsYW5jZXIgaW4uIE5vdGUgdGhhdCB0aGVyZSBhcmUgc2VwYXJhdGUgY29sdW1ucyBmb3IgQXBwbGljYXRpb24gYW5kIENsYXNzaWMgTG9hZCBCYWxhbmNlcnMgYW5kIGZvciBOZXR3b3JrIExvYWQgQmFsYW5jZXJzLlxuICAgICAgICAgKiAtICpBV1MgTWFuYWdlbWVudCBDb25zb2xlKiA6IEdvIHRvIHRoZSBBbWF6b24gRUMyIHBhZ2UsIGNob29zZSAqTG9hZCBCYWxhbmNlcnMqIGluIHRoZSBuYXZpZ2F0aW9uIHBhbmUsIHNlbGVjdCB0aGUgbG9hZCBiYWxhbmNlciwgYW5kIGdldCB0aGUgdmFsdWUgb2YgdGhlICpIb3N0ZWQgem9uZSogZmllbGQgb24gdGhlICpEZXNjcmlwdGlvbiogdGFiLlxuICAgICAgICAgKiAtICpFbGFzdGljIExvYWQgQmFsYW5jaW5nIEFQSSogOiBVc2UgYERlc2NyaWJlTG9hZEJhbGFuY2Vyc2AgdG8gZ2V0IHRoZSBhcHBsaWNhYmxlIHZhbHVlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIHRoZSBhcHBsaWNhYmxlIGd1aWRlOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIENsYXNzaWMgTG9hZCBCYWxhbmNlcnM6IFVzZSBbRGVzY3JpYmVMb2FkQmFsYW5jZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlTG9hZEJhbGFuY2Vycy5odG1sKSB0byBnZXQgdGhlIHZhbHVlIG9mIGBDYW5vbmljYWxIb3N0ZWRab25lTmFtZUlEYCAuXG4gICAgICAgICAqIC0gQXBwbGljYXRpb24gYW5kIE5ldHdvcmsgTG9hZCBCYWxhbmNlcnM6IFVzZSBbRGVzY3JpYmVMb2FkQmFsYW5jZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVMb2FkQmFsYW5jZXJzLmh0bWwpIHRvIGdldCB0aGUgdmFsdWUgb2YgYENhbm9uaWNhbEhvc3RlZFpvbmVJRGAgLlxuICAgICAgICAgKiAtICpDbG91ZEZvcm1hdGlvbiBGbjo6R2V0QXR0IGludHJpbnNpYyBmdW5jdGlvbiogOiBVc2UgdGhlIFtGbjo6R2V0QXR0XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9pbnRyaW5zaWMtZnVuY3Rpb24tcmVmZXJlbmNlLWdldGF0dC5odG1sKSBpbnRyaW5zaWMgZnVuY3Rpb24gdG8gZ2V0IHRoZSBhcHBsaWNhYmxlIHZhbHVlOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIENsYXNzaWMgTG9hZCBCYWxhbmNlcnM6IEdldCBbQ2Fub25pY2FsSG9zdGVkWm9uZU5hbWVJRF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWMyLWVsYi5odG1sI2F3cy1wcm9wZXJ0aWVzLWVjMi1lbGItcmV0dXJuLXZhbHVlcykgLlxuICAgICAgICAgKiAtIEFwcGxpY2F0aW9uIGFuZCBOZXR3b3JrIExvYWQgQmFsYW5jZXJzOiBHZXQgW0Nhbm9uaWNhbEhvc3RlZFpvbmVJRF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVsYXN0aWNsb2FkYmFsYW5jaW5ndjItbG9hZGJhbGFuY2VyLmh0bWwjYXdzLXJlc291cmNlLWVsYXN0aWNsb2FkYmFsYW5jaW5ndjItbG9hZGJhbGFuY2VyLXJldHVybi12YWx1ZXMpIC5cbiAgICAgICAgICogLSAqQVdTIENMSSogOiBVc2UgYGRlc2NyaWJlLWxvYWQtYmFsYW5jZXJzYCB0byBnZXQgdGhlIGFwcGxpY2FibGUgdmFsdWUuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgdGhlIGFwcGxpY2FibGUgZ3VpZGU6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gQ2xhc3NpYyBMb2FkIEJhbGFuY2VyczogVXNlIFtkZXNjcmliZS1sb2FkLWJhbGFuY2Vyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsaS9sYXRlc3QvcmVmZXJlbmNlL2VsYi9kZXNjcmliZS1sb2FkLWJhbGFuY2Vycy5odG1sKSB0byBnZXQgdGhlIHZhbHVlIG9mIGBDYW5vbmljYWxIb3N0ZWRab25lTmFtZUlEYCAuXG4gICAgICAgICAqIC0gQXBwbGljYXRpb24gYW5kIE5ldHdvcmsgTG9hZCBCYWxhbmNlcnM6IFVzZSBbZGVzY3JpYmUtbG9hZC1iYWxhbmNlcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGkvbGF0ZXN0L3JlZmVyZW5jZS9lbGJ2Mi9kZXNjcmliZS1sb2FkLWJhbGFuY2Vycy5odG1sKSB0byBnZXQgdGhlIHZhbHVlIG9mIGBDYW5vbmljYWxIb3N0ZWRab25lSURgIC5cbiAgICAgICAgICogLSAqKkdsb2JhbCBBY2NlbGVyYXRvciBhY2NlbGVyYXRvcioqIC0gU3BlY2lmeSBgWjJCSjZYUTVGSzdVNEhgIC5cbiAgICAgICAgICogLSAqKkFuIEFtYXpvbiBTMyBidWNrZXQgY29uZmlndXJlZCBhcyBhIHN0YXRpYyB3ZWJzaXRlKiogLSBTcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSBJRCBmb3IgdGhlIHJlZ2lvbiB0aGF0IHlvdSBjcmVhdGVkIHRoZSBidWNrZXQgaW4uIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHZhbGlkIHZhbHVlcywgc2VlIHRoZSB0YWJsZSBbQW1hem9uIFMzIFdlYnNpdGUgRW5kcG9pbnRzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2VuZXJhbC9sYXRlc3QvZ3IvczMuaHRtbCNzM193ZWJzaXRlX3JlZ2lvbl9lbmRwb2ludHMpIGluIHRoZSAqQW1hem9uIFdlYiBTZXJ2aWNlcyBHZW5lcmFsIFJlZmVyZW5jZSogLlxuICAgICAgICAgKiAtICoqQW5vdGhlciBSb3V0ZSA1MyByZWNvcmQgaW4geW91ciBob3N0ZWQgem9uZSoqIC0gU3BlY2lmeSB0aGUgaG9zdGVkIHpvbmUgSUQgb2YgeW91ciBob3N0ZWQgem9uZS4gKEFuIGFsaWFzIHJlY29yZCBjYW4ndCByZWZlcmVuY2UgYSByZWNvcmQgaW4gYSBkaWZmZXJlbnQgaG9zdGVkIHpvbmUuKVxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtYWxpYXN0YXJnZXQuaHRtbCNjZm4tcm91dGU1My1hbGlhc3RhcmdldC1ob3N0ZWR6b25laWRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGhvc3RlZFpvbmVJZDogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBBbGlhc1RhcmdldFByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBBbGlhc1RhcmdldFByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblJlY29yZFNldF9BbGlhc1RhcmdldFByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZG5zTmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5kbnNOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdkbnNOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmRuc05hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2V2YWx1YXRlVGFyZ2V0SGVhbHRoJywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5ldmFsdWF0ZVRhcmdldEhlYWx0aCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaG9zdGVkWm9uZUlkJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmhvc3RlZFpvbmVJZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaG9zdGVkWm9uZUlkJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmhvc3RlZFpvbmVJZCkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJBbGlhc1RhcmdldFByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXQuQWxpYXNUYXJnZXRgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEFsaWFzVGFyZ2V0UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldC5BbGlhc1RhcmdldGAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5SZWNvcmRTZXRBbGlhc1RhcmdldFByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5SZWNvcmRTZXRfQWxpYXNUYXJnZXRQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgRE5TTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5kbnNOYW1lKSxcbiAgICAgICAgRXZhbHVhdGVUYXJnZXRIZWFsdGg6IGNkay5ib29sZWFuVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmV2YWx1YXRlVGFyZ2V0SGVhbHRoKSxcbiAgICAgICAgSG9zdGVkWm9uZUlkOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmhvc3RlZFpvbmVJZCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblJlY29yZFNldEFsaWFzVGFyZ2V0UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5SZWNvcmRTZXQuQWxpYXNUYXJnZXRQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5SZWNvcmRTZXQuQWxpYXNUYXJnZXRQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2Ruc05hbWUnLCAnRE5TTmFtZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuRE5TTmFtZSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZXZhbHVhdGVUYXJnZXRIZWFsdGgnLCAnRXZhbHVhdGVUYXJnZXRIZWFsdGgnLCBwcm9wZXJ0aWVzLkV2YWx1YXRlVGFyZ2V0SGVhbHRoICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5FdmFsdWF0ZVRhcmdldEhlYWx0aCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaG9zdGVkWm9uZUlkJywgJ0hvc3RlZFpvbmVJZCcsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuSG9zdGVkWm9uZUlkKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuUmVjb3JkU2V0IHtcbiAgICAvKipcbiAgICAgKiBBIGNvbXBsZXggdHlwZSB0aGF0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGEgZ2VvZ3JhcGhpYyBsb2NhdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0LWdlb2xvY2F0aW9uLmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIEdlb0xvY2F0aW9uUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogRm9yIGdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzLCBhIHR3by1sZXR0ZXIgYWJicmV2aWF0aW9uIHRoYXQgaWRlbnRpZmllcyBhIGNvbnRpbmVudC4gUm91dGUgNTMgc3VwcG9ydHMgdGhlIGZvbGxvd2luZyBjb250aW5lbnQgY29kZXM6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKkFGKiA6IEFmcmljYVxuICAgICAgICAgKiAtICpBTiogOiBBbnRhcmN0aWNhXG4gICAgICAgICAqIC0gKkFTKiA6IEFzaWFcbiAgICAgICAgICogLSAqRVUqIDogRXVyb3BlXG4gICAgICAgICAqIC0gKk9DKiA6IE9jZWFuaWFcbiAgICAgICAgICogLSAqTkEqIDogTm9ydGggQW1lcmljYVxuICAgICAgICAgKiAtICpTQSogOiBTb3V0aCBBbWVyaWNhXG4gICAgICAgICAqXG4gICAgICAgICAqIENvbnN0cmFpbnQ6IFNwZWNpZnlpbmcgYENvbnRpbmVudENvZGVgIHdpdGggZWl0aGVyIGBDb3VudHJ5Q29kZWAgb3IgYFN1YmRpdmlzaW9uQ29kZWAgcmV0dXJucyBhbiBgSW52YWxpZElucHV0YCBlcnJvci5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC1nZW9sb2NhdGlvbi5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1nZW9sb2NhdGlvbi1jb250aW5lbnRjb2RlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBjb250aW5lbnRDb2RlPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogRm9yIGdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzLCB0aGUgdHdvLWxldHRlciBjb2RlIGZvciBhIGNvdW50cnkuXG4gICAgICAgICAqXG4gICAgICAgICAqIFJvdXRlIDUzIHVzZXMgdGhlIHR3by1sZXR0ZXIgY291bnRyeSBjb2RlcyB0aGF0IGFyZSBzcGVjaWZpZWQgaW4gW0lTTyBzdGFuZGFyZCAzMTY2LTEgYWxwaGEtMl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT18zMTY2LTFfYWxwaGEtMikgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0LWdlb2xvY2F0aW9uLmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LWdlb2xvY2F0aW9uLWNvdW50cnljb2RlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBjb3VudHJ5Q29kZT86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEZvciBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cywgdGhlIHR3by1sZXR0ZXIgY29kZSBmb3IgYSBzdGF0ZSBvZiB0aGUgVW5pdGVkIFN0YXRlcy4gUm91dGUgNTMgZG9lc24ndCBzdXBwb3J0IGFueSBvdGhlciB2YWx1ZXMgZm9yIGBTdWJkaXZpc2lvbkNvZGVgIC4gRm9yIGEgbGlzdCBvZiBzdGF0ZSBhYmJyZXZpYXRpb25zLCBzZWUgW0FwcGVuZGl4IEI6IFR3b+KAk0xldHRlciBTdGF0ZSBhbmQgUG9zc2Vzc2lvbiBBYmJyZXZpYXRpb25zXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9wZS51c3BzLmNvbS90ZXh0L3B1YjI4LzI4YXBiLmh0bSkgb24gdGhlIFVuaXRlZCBTdGF0ZXMgUG9zdGFsIFNlcnZpY2Ugd2Vic2l0ZS5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgeW91IHNwZWNpZnkgYHN1YmRpdmlzaW9uY29kZWAgLCB5b3UgbXVzdCBhbHNvIHNwZWNpZnkgYFVTYCBmb3IgYENvdW50cnlDb2RlYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQtZ2VvbG9jYXRpb24uaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtZ2VvbG9jYXRpb24tc3ViZGl2aXNpb25jb2RlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBzdWJkaXZpc2lvbkNvZGU/OiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYEdlb0xvY2F0aW9uUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEdlb0xvY2F0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuUmVjb3JkU2V0X0dlb0xvY2F0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjb250aW5lbnRDb2RlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmNvbnRpbmVudENvZGUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvdW50cnlDb2RlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmNvdW50cnlDb2RlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzdWJkaXZpc2lvbkNvZGUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuc3ViZGl2aXNpb25Db2RlKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkdlb0xvY2F0aW9uUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldC5HZW9Mb2NhdGlvbmAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgR2VvTG9jYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0Lkdlb0xvY2F0aW9uYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblJlY29yZFNldEdlb0xvY2F0aW9uUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblJlY29yZFNldF9HZW9Mb2NhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBDb250aW5lbnRDb2RlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNvbnRpbmVudENvZGUpLFxuICAgICAgICBDb3VudHJ5Q29kZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5jb3VudHJ5Q29kZSksXG4gICAgICAgIFN1YmRpdmlzaW9uQ29kZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zdWJkaXZpc2lvbkNvZGUpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5SZWNvcmRTZXRHZW9Mb2NhdGlvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuUmVjb3JkU2V0Lkdlb0xvY2F0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuUmVjb3JkU2V0Lkdlb0xvY2F0aW9uUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjb250aW5lbnRDb2RlJywgJ0NvbnRpbmVudENvZGUnLCBwcm9wZXJ0aWVzLkNvbnRpbmVudENvZGUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQ29udGluZW50Q29kZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY291bnRyeUNvZGUnLCAnQ291bnRyeUNvZGUnLCBwcm9wZXJ0aWVzLkNvdW50cnlDb2RlICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNvdW50cnlDb2RlKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzdWJkaXZpc2lvbkNvZGUnLCAnU3ViZGl2aXNpb25Db2RlJywgcHJvcGVydGllcy5TdWJkaXZpc2lvbkNvZGUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuU3ViZGl2aXNpb25Db2RlKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuUmVjb3JkU2V0R3JvdXBgXG4gKlxuICogQHN0cnVjdFxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtcmVjb3Jkc2V0Z3JvdXAuaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENmblJlY29yZFNldEdyb3VwUHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogKk9wdGlvbmFsOiogQW55IGNvbW1lbnRzIHlvdSB3YW50IHRvIGluY2x1ZGUgYWJvdXQgYSBjaGFuZ2UgYmF0Y2ggcmVxdWVzdC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtcmVjb3Jkc2V0Z3JvdXAuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXRncm91cC1jb21tZW50XG4gICAgICovXG4gICAgcmVhZG9ubHkgY29tbWVudD86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBJRCBvZiB0aGUgaG9zdGVkIHpvbmUgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUgcmVjb3JkcyBpbi5cbiAgICAgKlxuICAgICAqIFNwZWNpZnkgZWl0aGVyIGBIb3N0ZWRab25lTmFtZWAgb3IgYEhvc3RlZFpvbmVJZGAgLCBidXQgbm90IGJvdGguIElmIHlvdSBoYXZlIG11bHRpcGxlIGhvc3RlZCB6b25lcyB3aXRoIHRoZSBzYW1lIGRvbWFpbiBuYW1lLCB5b3UgbXVzdCBzcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSB1c2luZyBgSG9zdGVkWm9uZUlkYCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLXJlY29yZHNldGdyb3VwLmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0Z3JvdXAtaG9zdGVkem9uZWlkXG4gICAgICovXG4gICAgcmVhZG9ubHkgaG9zdGVkWm9uZUlkPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGhvc3RlZCB6b25lIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlIHJlY29yZHMgaW4uIFlvdSBtdXN0IGluY2x1ZGUgYSB0cmFpbGluZyBkb3QgKGZvciBleGFtcGxlLCBgd3d3LmV4YW1wbGUuY29tLmAgKSBhcyBwYXJ0IG9mIHRoZSBgSG9zdGVkWm9uZU5hbWVgIC5cbiAgICAgKlxuICAgICAqIFdoZW4geW91IGNyZWF0ZSBhIHN0YWNrIHVzaW5nIGFuIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldGAgdGhhdCBzcGVjaWZpZXMgYEhvc3RlZFpvbmVOYW1lYCAsIEFXUyBDbG91ZEZvcm1hdGlvbiBhdHRlbXB0cyB0byBmaW5kIGEgaG9zdGVkIHpvbmUgd2hvc2UgbmFtZSBtYXRjaGVzIHRoZSBgSG9zdGVkWm9uZU5hbWVgIC4gSWYgQVdTIENsb3VkRm9ybWF0aW9uIGNhbid0IGZpbmQgYSBob3N0ZWQgem9uZSB3aXRoIGEgbWF0Y2hpbmcgZG9tYWluIG5hbWUsIG9yIGlmIHRoZXJlIGlzIG1vcmUgdGhhbiBvbmUgaG9zdGVkIHpvbmUgd2l0aCB0aGUgc3BlY2lmaWVkIGRvbWFpbiBuYW1lLCBBV1MgQ2xvdWRGb3JtYXRpb24gd2lsbCBub3QgY3JlYXRlIHRoZSBzdGFjay5cbiAgICAgKlxuICAgICAqIFNwZWNpZnkgZWl0aGVyIGBIb3N0ZWRab25lTmFtZWAgb3IgYEhvc3RlZFpvbmVJZGAgLCBidXQgbm90IGJvdGguIElmIHlvdSBoYXZlIG11bHRpcGxlIGhvc3RlZCB6b25lcyB3aXRoIHRoZSBzYW1lIGRvbWFpbiBuYW1lLCB5b3UgbXVzdCBzcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSB1c2luZyBgSG9zdGVkWm9uZUlkYCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLXJlY29yZHNldGdyb3VwLmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0Z3JvdXAtaG9zdGVkem9uZW5hbWVcbiAgICAgKi9cbiAgICByZWFkb25seSBob3N0ZWRab25lTmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEEgY29tcGxleCB0eXBlIHRoYXQgY29udGFpbnMgb25lIGBSZWNvcmRTZXRgIGVsZW1lbnQgZm9yIGVhY2ggcmVjb3JkIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1yZWNvcmRzZXRncm91cC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldGdyb3VwLXJlY29yZHNldHNcbiAgICAgKi9cbiAgICByZWFkb25seSByZWNvcmRTZXRzPzogQXJyYXk8Q2ZuUmVjb3JkU2V0R3JvdXAuUmVjb3JkU2V0UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmblJlY29yZFNldEdyb3VwUHJvcHNgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblJlY29yZFNldEdyb3VwUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuUmVjb3JkU2V0R3JvdXBQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvbW1lbnQnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY29tbWVudCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaG9zdGVkWm9uZUlkJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmhvc3RlZFpvbmVJZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaG9zdGVkWm9uZU5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuaG9zdGVkWm9uZU5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3JlY29yZFNldHMnLCBjZGsubGlzdFZhbGlkYXRvcihDZm5SZWNvcmRTZXRHcm91cF9SZWNvcmRTZXRQcm9wZXJ0eVZhbGlkYXRvcikpKHByb3BlcnRpZXMucmVjb3JkU2V0cykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5SZWNvcmRTZXRHcm91cFByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRHcm91cGAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuUmVjb3JkU2V0R3JvdXBQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0R3JvdXBgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuUmVjb3JkU2V0R3JvdXBQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuUmVjb3JkU2V0R3JvdXBQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQ29tbWVudDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5jb21tZW50KSxcbiAgICAgICAgSG9zdGVkWm9uZUlkOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmhvc3RlZFpvbmVJZCksXG4gICAgICAgIEhvc3RlZFpvbmVOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmhvc3RlZFpvbmVOYW1lKSxcbiAgICAgICAgUmVjb3JkU2V0czogY2RrLmxpc3RNYXBwZXIoY2ZuUmVjb3JkU2V0R3JvdXBSZWNvcmRTZXRQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMucmVjb3JkU2V0cyksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblJlY29yZFNldEdyb3VwUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5SZWNvcmRTZXRHcm91cFByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5SZWNvcmRTZXRHcm91cFByb3BzPigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY29tbWVudCcsICdDb21tZW50JywgcHJvcGVydGllcy5Db21tZW50ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNvbW1lbnQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2hvc3RlZFpvbmVJZCcsICdIb3N0ZWRab25lSWQnLCBwcm9wZXJ0aWVzLkhvc3RlZFpvbmVJZCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Ib3N0ZWRab25lSWQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2hvc3RlZFpvbmVOYW1lJywgJ0hvc3RlZFpvbmVOYW1lJywgcHJvcGVydGllcy5Ib3N0ZWRab25lTmFtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Ib3N0ZWRab25lTmFtZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncmVjb3JkU2V0cycsICdSZWNvcmRTZXRzJywgcHJvcGVydGllcy5SZWNvcmRTZXRzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KENmblJlY29yZFNldEdyb3VwUmVjb3JkU2V0UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuUmVjb3JkU2V0cykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0R3JvdXBgXG4gKlxuICogQSBjb21wbGV4IHR5cGUgdGhhdCBjb250YWlucyBhbiBvcHRpb25hbCBjb21tZW50LCB0aGUgbmFtZSBhbmQgSUQgb2YgdGhlIGhvc3RlZCB6b25lIHRoYXQgeW91IHdhbnQgdG8gbWFrZSBjaGFuZ2VzIGluLCBhbmQgdmFsdWVzIGZvciB0aGUgcmVjb3JkcyB0aGF0IHlvdSB3YW50IHRvIGNyZWF0ZS5cbiAqXG4gKiBAY2xvdWRmb3JtYXRpb25SZXNvdXJjZSBBV1M6OlJvdXRlNTM6OlJlY29yZFNldEdyb3VwXG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1yZWNvcmRzZXRncm91cC5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5SZWNvcmRTZXRHcm91cCBleHRlbmRzIGNkay5DZm5SZXNvdXJjZSBpbXBsZW1lbnRzIGNkay5JSW5zcGVjdGFibGUge1xuICAgIC8qKlxuICAgICAqIFRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSB0eXBlIG5hbWUgZm9yIHRoaXMgcmVzb3VyY2UgY2xhc3MuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBDRk5fUkVTT1VSQ0VfVFlQRV9OQU1FID0gXCJBV1M6OlJvdXRlNTM6OlJlY29yZFNldEdyb3VwXCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5SZWNvcmRTZXRHcm91cCB7XG4gICAgICAgIHJlc291cmNlQXR0cmlidXRlcyA9IHJlc291cmNlQXR0cmlidXRlcyB8fCB7fTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VQcm9wZXJ0aWVzID0gb3B0aW9ucy5wYXJzZXIucGFyc2VWYWx1ZShyZXNvdXJjZUF0dHJpYnV0ZXMuUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHByb3BzUmVzdWx0ID0gQ2ZuUmVjb3JkU2V0R3JvdXBQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihyZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgQ2ZuUmVjb3JkU2V0R3JvdXAoc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogKk9wdGlvbmFsOiogQW55IGNvbW1lbnRzIHlvdSB3YW50IHRvIGluY2x1ZGUgYWJvdXQgYSBjaGFuZ2UgYmF0Y2ggcmVxdWVzdC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtcmVjb3Jkc2V0Z3JvdXAuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXRncm91cC1jb21tZW50XG4gICAgICovXG4gICAgcHVibGljIGNvbW1lbnQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBJRCBvZiB0aGUgaG9zdGVkIHpvbmUgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUgcmVjb3JkcyBpbi5cbiAgICAgKlxuICAgICAqIFNwZWNpZnkgZWl0aGVyIGBIb3N0ZWRab25lTmFtZWAgb3IgYEhvc3RlZFpvbmVJZGAgLCBidXQgbm90IGJvdGguIElmIHlvdSBoYXZlIG11bHRpcGxlIGhvc3RlZCB6b25lcyB3aXRoIHRoZSBzYW1lIGRvbWFpbiBuYW1lLCB5b3UgbXVzdCBzcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSB1c2luZyBgSG9zdGVkWm9uZUlkYCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLXJlY29yZHNldGdyb3VwLmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0Z3JvdXAtaG9zdGVkem9uZWlkXG4gICAgICovXG4gICAgcHVibGljIGhvc3RlZFpvbmVJZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGhvc3RlZCB6b25lIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlIHJlY29yZHMgaW4uIFlvdSBtdXN0IGluY2x1ZGUgYSB0cmFpbGluZyBkb3QgKGZvciBleGFtcGxlLCBgd3d3LmV4YW1wbGUuY29tLmAgKSBhcyBwYXJ0IG9mIHRoZSBgSG9zdGVkWm9uZU5hbWVgIC5cbiAgICAgKlxuICAgICAqIFdoZW4geW91IGNyZWF0ZSBhIHN0YWNrIHVzaW5nIGFuIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldGAgdGhhdCBzcGVjaWZpZXMgYEhvc3RlZFpvbmVOYW1lYCAsIEFXUyBDbG91ZEZvcm1hdGlvbiBhdHRlbXB0cyB0byBmaW5kIGEgaG9zdGVkIHpvbmUgd2hvc2UgbmFtZSBtYXRjaGVzIHRoZSBgSG9zdGVkWm9uZU5hbWVgIC4gSWYgQVdTIENsb3VkRm9ybWF0aW9uIGNhbid0IGZpbmQgYSBob3N0ZWQgem9uZSB3aXRoIGEgbWF0Y2hpbmcgZG9tYWluIG5hbWUsIG9yIGlmIHRoZXJlIGlzIG1vcmUgdGhhbiBvbmUgaG9zdGVkIHpvbmUgd2l0aCB0aGUgc3BlY2lmaWVkIGRvbWFpbiBuYW1lLCBBV1MgQ2xvdWRGb3JtYXRpb24gd2lsbCBub3QgY3JlYXRlIHRoZSBzdGFjay5cbiAgICAgKlxuICAgICAqIFNwZWNpZnkgZWl0aGVyIGBIb3N0ZWRab25lTmFtZWAgb3IgYEhvc3RlZFpvbmVJZGAgLCBidXQgbm90IGJvdGguIElmIHlvdSBoYXZlIG11bHRpcGxlIGhvc3RlZCB6b25lcyB3aXRoIHRoZSBzYW1lIGRvbWFpbiBuYW1lLCB5b3UgbXVzdCBzcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSB1c2luZyBgSG9zdGVkWm9uZUlkYCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLXJlY29yZHNldGdyb3VwLmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0Z3JvdXAtaG9zdGVkem9uZW5hbWVcbiAgICAgKi9cbiAgICBwdWJsaWMgaG9zdGVkWm9uZU5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEEgY29tcGxleCB0eXBlIHRoYXQgY29udGFpbnMgb25lIGBSZWNvcmRTZXRgIGVsZW1lbnQgZm9yIGVhY2ggcmVjb3JkIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1yZWNvcmRzZXRncm91cC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldGdyb3VwLXJlY29yZHNldHNcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVjb3JkU2V0czogQXJyYXk8Q2ZuUmVjb3JkU2V0R3JvdXAuUmVjb3JkU2V0UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldEdyb3VwYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5SZWNvcmRTZXRHcm91cFByb3BzID0ge30pIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmblJlY29yZFNldEdyb3VwLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUsIHByb3BlcnRpZXM6IHByb3BzIH0pO1xuXG4gICAgICAgIHRoaXMuY29tbWVudCA9IHByb3BzLmNvbW1lbnQ7XG4gICAgICAgIHRoaXMuaG9zdGVkWm9uZUlkID0gcHJvcHMuaG9zdGVkWm9uZUlkO1xuICAgICAgICB0aGlzLmhvc3RlZFpvbmVOYW1lID0gcHJvcHMuaG9zdGVkWm9uZU5hbWU7XG4gICAgICAgIHRoaXMucmVjb3JkU2V0cyA9IHByb3BzLnJlY29yZFNldHM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5SZWNvcmRTZXRHcm91cC5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FKTtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246cHJvcHNcIiwgdGhpcy5jZm5Qcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGNmblByb3BlcnRpZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29tbWVudDogdGhpcy5jb21tZW50LFxuICAgICAgICAgICAgaG9zdGVkWm9uZUlkOiB0aGlzLmhvc3RlZFpvbmVJZCxcbiAgICAgICAgICAgIGhvc3RlZFpvbmVOYW1lOiB0aGlzLmhvc3RlZFpvbmVOYW1lLFxuICAgICAgICAgICAgcmVjb3JkU2V0czogdGhpcy5yZWNvcmRTZXRzLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmblJlY29yZFNldEdyb3VwUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuUmVjb3JkU2V0R3JvdXAge1xuICAgIC8qKlxuICAgICAqICpBbGlhcyByZWNvcmRzIG9ubHk6KiBJbmZvcm1hdGlvbiBhYm91dCB0aGUgQVdTIHJlc291cmNlLCBzdWNoIGFzIGEgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24gb3IgYW4gQW1hem9uIFMzIGJ1Y2tldCwgdGhhdCB5b3Ugd2FudCB0byByb3V0ZSB0cmFmZmljIHRvLlxuICAgICAqXG4gICAgICogV2hlbiBjcmVhdGluZyByZWNvcmRzIGZvciBhIHByaXZhdGUgaG9zdGVkIHpvbmUsIG5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gQ3JlYXRpbmcgZ2VvbG9jYXRpb24gYWxpYXMgYW5kIGxhdGVuY3kgYWxpYXMgcmVjb3JkcyBpbiBhIHByaXZhdGUgaG9zdGVkIHpvbmUgaXMgYWxsb3dlZCBidXQgbm90IHN1cHBvcnRlZC5cbiAgICAgKiAtIEZvciBpbmZvcm1hdGlvbiBhYm91dCBjcmVhdGluZyBmYWlsb3ZlciByZWNvcmRzIGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSwgc2VlIFtDb25maWd1cmluZyBGYWlsb3ZlciBpbiBhIFByaXZhdGUgSG9zdGVkIFpvbmVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9kbnMtZmFpbG92ZXItcHJpdmF0ZS1ob3N0ZWQtem9uZXMuaHRtbCkgLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1hbGlhc3RhcmdldC5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBBbGlhc1RhcmdldFByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqICpBbGlhcyByZWNvcmRzIG9ubHk6KiBUaGUgdmFsdWUgdGhhdCB5b3Ugc3BlY2lmeSBkZXBlbmRzIG9uIHdoZXJlIHlvdSB3YW50IHRvIHJvdXRlIHF1ZXJpZXM6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKipBbWF6b24gQVBJIEdhdGV3YXkgY3VzdG9tIHJlZ2lvbmFsIEFQSXMgYW5kIGVkZ2Utb3B0aW1pemVkIEFQSXMqKiAtIFNwZWNpZnkgdGhlIGFwcGxpY2FibGUgZG9tYWluIG5hbWUgZm9yIHlvdXIgQVBJLiBZb3UgY2FuIGdldCB0aGUgYXBwbGljYWJsZSB2YWx1ZSB1c2luZyB0aGUgQVdTIENMSSBjb21tYW5kIFtnZXQtZG9tYWluLW5hbWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xpL2xhdGVzdC9yZWZlcmVuY2UvYXBpZ2F0ZXdheS9nZXQtZG9tYWluLW5hbWVzLmh0bWwpIDpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBGb3IgcmVnaW9uYWwgQVBJcywgc3BlY2lmeSB0aGUgdmFsdWUgb2YgYHJlZ2lvbmFsRG9tYWluTmFtZWAgLlxuICAgICAgICAgKiAtIEZvciBlZGdlLW9wdGltaXplZCBBUElzLCBzcGVjaWZ5IHRoZSB2YWx1ZSBvZiBgZGlzdHJpYnV0aW9uRG9tYWluTmFtZWAgLiBUaGlzIGlzIHRoZSBuYW1lIG9mIHRoZSBhc3NvY2lhdGVkIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uLCBzdWNoIGFzIGBkYTFiMmMzZDRlNS5jbG91ZGZyb250Lm5ldGAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFRoZSBuYW1lIG9mIHRoZSByZWNvcmQgdGhhdCB5b3UncmUgY3JlYXRpbmcgbXVzdCBtYXRjaCBhIGN1c3RvbSBkb21haW4gbmFtZSBmb3IgeW91ciBBUEksIHN1Y2ggYXMgYGFwaS5leGFtcGxlLmNvbWAgLlxuICAgICAgICAgKiAtICoqQW1hem9uIFZpcnR1YWwgUHJpdmF0ZSBDbG91ZCBpbnRlcmZhY2UgVlBDIGVuZHBvaW50KiogLSBFbnRlciB0aGUgQVBJIGVuZHBvaW50IGZvciB0aGUgaW50ZXJmYWNlIGVuZHBvaW50LCBzdWNoIGFzIGB2cGNlLTEyMzQ1Njc4OWFiY2RlZjAxLWV4YW1wbGUtdXMtZWFzdC0xYS5lbGFzdGljbG9hZGJhbGFuY2luZy51cy1lYXN0LTEudnBjZS5hbWF6b25hd3MuY29tYCAuIEZvciBlZGdlLW9wdGltaXplZCBBUElzLCB0aGlzIGlzIHRoZSBkb21haW4gbmFtZSBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24uIFlvdSBjYW4gZ2V0IHRoZSB2YWx1ZSBvZiBgRG5zTmFtZWAgdXNpbmcgdGhlIEFXUyBDTEkgY29tbWFuZCBbZGVzY3JpYmUtdnBjLWVuZHBvaW50c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsaS9sYXRlc3QvcmVmZXJlbmNlL2VjMi9kZXNjcmliZS12cGMtZW5kcG9pbnRzLmh0bWwpIC5cbiAgICAgICAgICogLSAqKkNsb3VkRnJvbnQgZGlzdHJpYnV0aW9uKiogLSBTcGVjaWZ5IHRoZSBkb21haW4gbmFtZSB0aGF0IENsb3VkRnJvbnQgYXNzaWduZWQgd2hlbiB5b3UgY3JlYXRlZCB5b3VyIGRpc3RyaWJ1dGlvbi5cbiAgICAgICAgICpcbiAgICAgICAgICogWW91ciBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbiBtdXN0IGluY2x1ZGUgYW4gYWx0ZXJuYXRlIGRvbWFpbiBuYW1lIHRoYXQgbWF0Y2hlcyB0aGUgbmFtZSBvZiB0aGUgcmVjb3JkLiBGb3IgZXhhbXBsZSwgaWYgdGhlIG5hbWUgb2YgdGhlIHJlY29yZCBpcyAqYWNtZS5leGFtcGxlLmNvbSogLCB5b3VyIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uIG11c3QgaW5jbHVkZSAqYWNtZS5leGFtcGxlLmNvbSogYXMgb25lIG9mIHRoZSBhbHRlcm5hdGUgZG9tYWluIG5hbWVzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtVc2luZyBBbHRlcm5hdGUgRG9tYWluIE5hbWVzIChDTkFNRXMpXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRGcm9udC9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvQ05BTUVzLmh0bWwpIGluIHRoZSAqQW1hem9uIENsb3VkRnJvbnQgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIFlvdSBjYW4ndCBjcmVhdGUgYSByZWNvcmQgaW4gYSBwcml2YXRlIGhvc3RlZCB6b25lIHRvIHJvdXRlIHRyYWZmaWMgdG8gYSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbi5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBGb3IgZmFpbG92ZXIgYWxpYXMgcmVjb3JkcywgeW91IGNhbid0IHNwZWNpZnkgYSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbiBmb3IgYm90aCB0aGUgcHJpbWFyeSBhbmQgc2Vjb25kYXJ5IHJlY29yZHMuIEEgZGlzdHJpYnV0aW9uIG11c3QgaW5jbHVkZSBhbiBhbHRlcm5hdGUgZG9tYWluIG5hbWUgdGhhdCBtYXRjaGVzIHRoZSBuYW1lIG9mIHRoZSByZWNvcmQuIEhvd2V2ZXIsIHRoZSBwcmltYXJ5IGFuZCBzZWNvbmRhcnkgcmVjb3JkcyBoYXZlIHRoZSBzYW1lIG5hbWUsIGFuZCB5b3UgY2FuJ3QgaW5jbHVkZSB0aGUgc2FtZSBhbHRlcm5hdGUgZG9tYWluIG5hbWUgaW4gbW9yZSB0aGFuIG9uZSBkaXN0cmlidXRpb24uXG4gICAgICAgICAqIC0gKipFbGFzdGljIEJlYW5zdGFsayBlbnZpcm9ubWVudCoqIC0gSWYgdGhlIGRvbWFpbiBuYW1lIGZvciB5b3VyIEVsYXN0aWMgQmVhbnN0YWxrIGVudmlyb25tZW50IGluY2x1ZGVzIHRoZSByZWdpb24gdGhhdCB5b3UgZGVwbG95ZWQgdGhlIGVudmlyb25tZW50IGluLCB5b3UgY2FuIGNyZWF0ZSBhbiBhbGlhcyByZWNvcmQgdGhhdCByb3V0ZXMgdHJhZmZpYyB0byB0aGUgZW52aXJvbm1lbnQuIEZvciBleGFtcGxlLCB0aGUgZG9tYWluIG5hbWUgYG15LWVudmlyb25tZW50LiAqdXMtd2VzdC0yKiAuZWxhc3RpY2JlYW5zdGFsay5jb21gIGlzIGEgcmVnaW9uYWxpemVkIGRvbWFpbiBuYW1lLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IEZvciBlbnZpcm9ubWVudHMgdGhhdCB3ZXJlIGNyZWF0ZWQgYmVmb3JlIGVhcmx5IDIwMTYsIHRoZSBkb21haW4gbmFtZSBkb2Vzbid0IGluY2x1ZGUgdGhlIHJlZ2lvbi4gVG8gcm91dGUgdHJhZmZpYyB0byB0aGVzZSBlbnZpcm9ubWVudHMsIHlvdSBtdXN0IGNyZWF0ZSBhIENOQU1FIHJlY29yZCBpbnN0ZWFkIG9mIGFuIGFsaWFzIHJlY29yZC4gTm90ZSB0aGF0IHlvdSBjYW4ndCBjcmVhdGUgYSBDTkFNRSByZWNvcmQgZm9yIHRoZSByb290IGRvbWFpbiBuYW1lLiBGb3IgZXhhbXBsZSwgaWYgeW91ciBkb21haW4gbmFtZSBpcyBleGFtcGxlLmNvbSwgeW91IGNhbiBjcmVhdGUgYSByZWNvcmQgdGhhdCByb3V0ZXMgdHJhZmZpYyBmb3IgYWNtZS5leGFtcGxlLmNvbSB0byB5b3VyIEVsYXN0aWMgQmVhbnN0YWxrIGVudmlyb25tZW50LCBidXQgeW91IGNhbid0IGNyZWF0ZSBhIHJlY29yZCB0aGF0IHJvdXRlcyB0cmFmZmljIGZvciBleGFtcGxlLmNvbSB0byB5b3VyIEVsYXN0aWMgQmVhbnN0YWxrIGVudmlyb25tZW50LlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgRWxhc3RpYyBCZWFuc3RhbGsgZW52aXJvbm1lbnRzIHRoYXQgaGF2ZSByZWdpb25hbGl6ZWQgc3ViZG9tYWlucywgc3BlY2lmeSB0aGUgYENOQU1FYCBhdHRyaWJ1dGUgZm9yIHRoZSBlbnZpcm9ubWVudC4gWW91IGNhbiB1c2UgdGhlIGZvbGxvd2luZyBtZXRob2RzIHRvIGdldCB0aGUgdmFsdWUgb2YgdGhlIENOQU1FIGF0dHJpYnV0ZTpcbiAgICAgICAgICpcbiAgICAgICAgICogLSAqQVdTIE1hbmFnZW1lbnQgQ29uc29sZSogOiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgaG93IHRvIGdldCB0aGUgdmFsdWUgYnkgdXNpbmcgdGhlIGNvbnNvbGUsIHNlZSBbVXNpbmcgQ3VzdG9tIERvbWFpbnMgd2l0aCBBV1MgRWxhc3RpYyBCZWFuc3RhbGtdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljYmVhbnN0YWxrL2xhdGVzdC9kZy9jdXN0b21kb21haW5zLmh0bWwpIGluIHRoZSAqQVdTIEVsYXN0aWMgQmVhbnN0YWxrIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKiAtICpFbGFzdGljIEJlYW5zdGFsayBBUEkqIDogVXNlIHRoZSBgRGVzY3JpYmVFbnZpcm9ubWVudHNgIGFjdGlvbiB0byBnZXQgdGhlIHZhbHVlIG9mIHRoZSBgQ05BTUVgIGF0dHJpYnV0ZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbRGVzY3JpYmVFbnZpcm9ubWVudHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljYmVhbnN0YWxrL2xhdGVzdC9hcGkvQVBJX0Rlc2NyaWJlRW52aXJvbm1lbnRzLmh0bWwpIGluIHRoZSAqQVdTIEVsYXN0aWMgQmVhbnN0YWxrIEFQSSBSZWZlcmVuY2UqIC5cbiAgICAgICAgICogLSAqQVdTIENMSSogOiBVc2UgdGhlIGBkZXNjcmliZS1lbnZpcm9ubWVudHNgIGNvbW1hbmQgdG8gZ2V0IHRoZSB2YWx1ZSBvZiB0aGUgYENOQU1FYCBhdHRyaWJ1dGUuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW2Rlc2NyaWJlLWVudmlyb25tZW50c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsaS9sYXRlc3QvcmVmZXJlbmNlL2VsYXN0aWNiZWFuc3RhbGsvZGVzY3JpYmUtZW52aXJvbm1lbnRzLmh0bWwpIGluIHRoZSAqQVdTIENMSSogLlxuICAgICAgICAgKiAtICoqRUxCIGxvYWQgYmFsYW5jZXIqKiAtIFNwZWNpZnkgdGhlIEROUyBuYW1lIHRoYXQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBsb2FkIGJhbGFuY2VyLiBHZXQgdGhlIEROUyBuYW1lIGJ5IHVzaW5nIHRoZSBBV1MgTWFuYWdlbWVudCBDb25zb2xlICwgdGhlIEVMQiBBUEksIG9yIHRoZSBBV1MgQ0xJIC5cbiAgICAgICAgICpcbiAgICAgICAgICogLSAqQVdTIE1hbmFnZW1lbnQgQ29uc29sZSogOiBHbyB0byB0aGUgRUMyIHBhZ2UsIGNob29zZSAqTG9hZCBCYWxhbmNlcnMqIGluIHRoZSBuYXZpZ2F0aW9uIHBhbmUsIGNob29zZSB0aGUgbG9hZCBiYWxhbmNlciwgY2hvb3NlIHRoZSAqRGVzY3JpcHRpb24qIHRhYiwgYW5kIGdldCB0aGUgdmFsdWUgb2YgdGhlICpETlMgbmFtZSogZmllbGQuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSdyZSByb3V0aW5nIHRyYWZmaWMgdG8gYSBDbGFzc2ljIExvYWQgQmFsYW5jZXIsIGdldCB0aGUgdmFsdWUgdGhhdCBiZWdpbnMgd2l0aCAqZHVhbHN0YWNrKiAuIElmIHlvdSdyZSByb3V0aW5nIHRyYWZmaWMgdG8gYW5vdGhlciB0eXBlIG9mIGxvYWQgYmFsYW5jZXIsIGdldCB0aGUgdmFsdWUgdGhhdCBhcHBsaWVzIHRvIHRoZSByZWNvcmQgdHlwZSwgQSBvciBBQUFBLlxuICAgICAgICAgKiAtICpFbGFzdGljIExvYWQgQmFsYW5jaW5nIEFQSSogOiBVc2UgYERlc2NyaWJlTG9hZEJhbGFuY2Vyc2AgdG8gZ2V0IHRoZSB2YWx1ZSBvZiBgRE5TTmFtZWAgLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIHRoZSBhcHBsaWNhYmxlIGd1aWRlOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIENsYXNzaWMgTG9hZCBCYWxhbmNlcnM6IFtEZXNjcmliZUxvYWRCYWxhbmNlcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVMb2FkQmFsYW5jZXJzLmh0bWwpXG4gICAgICAgICAqIC0gQXBwbGljYXRpb24gYW5kIE5ldHdvcmsgTG9hZCBCYWxhbmNlcnM6IFtEZXNjcmliZUxvYWRCYWxhbmNlcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUxvYWRCYWxhbmNlcnMuaHRtbClcbiAgICAgICAgICogLSAqQ2xvdWRGb3JtYXRpb24gRm46OkdldEF0dCBpbnRyaW5zaWMgZnVuY3Rpb24qIDogVXNlIHRoZSBbRm46OkdldEF0dF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvaW50cmluc2ljLWZ1bmN0aW9uLXJlZmVyZW5jZS1nZXRhdHQuaHRtbCkgaW50cmluc2ljIGZ1bmN0aW9uIHRvIGdldCB0aGUgdmFsdWUgb2YgYEROU05hbWVgIDpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBbQ2xhc3NpYyBMb2FkIEJhbGFuY2Vyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWMyLWVsYi5odG1sI2F3cy1wcm9wZXJ0aWVzLWVjMi1lbGItcmV0dXJuLXZhbHVlcykgLlxuICAgICAgICAgKiAtIFtBcHBsaWNhdGlvbiBhbmQgTmV0d29yayBMb2FkIEJhbGFuY2Vyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVsYXN0aWNsb2FkYmFsYW5jaW5ndjItbG9hZGJhbGFuY2VyLmh0bWwjYXdzLXJlc291cmNlLWVsYXN0aWNsb2FkYmFsYW5jaW5ndjItbG9hZGJhbGFuY2VyLXJldHVybi12YWx1ZXMpIC5cbiAgICAgICAgICogLSAqQVdTIENMSSogOiBVc2UgYGRlc2NyaWJlLWxvYWQtYmFsYW5jZXJzYCB0byBnZXQgdGhlIHZhbHVlIG9mIGBETlNOYW1lYCAuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgdGhlIGFwcGxpY2FibGUgZ3VpZGU6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gQ2xhc3NpYyBMb2FkIEJhbGFuY2VyczogW2Rlc2NyaWJlLWxvYWQtYmFsYW5jZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xpL2xhdGVzdC9yZWZlcmVuY2UvZWxiL2Rlc2NyaWJlLWxvYWQtYmFsYW5jZXJzLmh0bWwpXG4gICAgICAgICAqIC0gQXBwbGljYXRpb24gYW5kIE5ldHdvcmsgTG9hZCBCYWxhbmNlcnM6IFtkZXNjcmliZS1sb2FkLWJhbGFuY2Vyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsaS9sYXRlc3QvcmVmZXJlbmNlL2VsYnYyL2Rlc2NyaWJlLWxvYWQtYmFsYW5jZXJzLmh0bWwpXG4gICAgICAgICAqIC0gKipHbG9iYWwgQWNjZWxlcmF0b3IgYWNjZWxlcmF0b3IqKiAtIFNwZWNpZnkgdGhlIEROUyBuYW1lIGZvciB5b3VyIGFjY2VsZXJhdG9yOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICpHbG9iYWwgQWNjZWxlcmF0b3IgQVBJKiA6IFRvIGdldCB0aGUgRE5TIG5hbWUsIHVzZSBbRGVzY3JpYmVBY2NlbGVyYXRvcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dsb2JhbC1hY2NlbGVyYXRvci9sYXRlc3QvYXBpL0FQSV9EZXNjcmliZUFjY2VsZXJhdG9yLmh0bWwpIC5cbiAgICAgICAgICogLSAqQVdTIENMSSogOiBUbyBnZXQgdGhlIEROUyBuYW1lLCB1c2UgW2Rlc2NyaWJlLWFjY2VsZXJhdG9yXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xpL2xhdGVzdC9yZWZlcmVuY2UvZ2xvYmFsYWNjZWxlcmF0b3IvZGVzY3JpYmUtYWNjZWxlcmF0b3IuaHRtbCkgLlxuICAgICAgICAgKiAtICoqQW1hem9uIFMzIGJ1Y2tldCB0aGF0IGlzIGNvbmZpZ3VyZWQgYXMgYSBzdGF0aWMgd2Vic2l0ZSoqIC0gU3BlY2lmeSB0aGUgZG9tYWluIG5hbWUgb2YgdGhlIEFtYXpvbiBTMyB3ZWJzaXRlIGVuZHBvaW50IHRoYXQgeW91IGNyZWF0ZWQgdGhlIGJ1Y2tldCBpbiwgZm9yIGV4YW1wbGUsIGBzMy13ZWJzaXRlLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tYCAuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHZhbGlkIHZhbHVlcywgc2VlIHRoZSB0YWJsZSBbQW1hem9uIFMzIFdlYnNpdGUgRW5kcG9pbnRzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2VuZXJhbC9sYXRlc3QvZ3IvczMuaHRtbCNzM193ZWJzaXRlX3JlZ2lvbl9lbmRwb2ludHMpIGluIHRoZSAqQW1hem9uIFdlYiBTZXJ2aWNlcyBHZW5lcmFsIFJlZmVyZW5jZSogLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB1c2luZyBTMyBidWNrZXRzIGZvciB3ZWJzaXRlcywgc2VlIFtHZXR0aW5nIFN0YXJ0ZWQgd2l0aCBBbWF6b24gUm91dGUgNTNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9nZXR0aW5nLXN0YXJ0ZWQuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlLipcbiAgICAgICAgICogLSAqKkFub3RoZXIgUm91dGUgNTMgcmVjb3JkKiogLSBTcGVjaWZ5IHRoZSB2YWx1ZSBvZiB0aGUgYE5hbWVgIGVsZW1lbnQgZm9yIGEgcmVjb3JkIGluIHRoZSBjdXJyZW50IGhvc3RlZCB6b25lLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IElmIHlvdSdyZSBjcmVhdGluZyBhbiBhbGlhcyByZWNvcmQgdGhhdCBoYXMgdGhlIHNhbWUgbmFtZSBhcyB0aGUgaG9zdGVkIHpvbmUgKGtub3duIGFzIHRoZSB6b25lIGFwZXgpLCB5b3UgY2FuJ3Qgc3BlY2lmeSB0aGUgZG9tYWluIG5hbWUgZm9yIGEgcmVjb3JkIGZvciB3aGljaCB0aGUgdmFsdWUgb2YgYFR5cGVgIGlzIGBDTkFNRWAgLiBUaGlzIGlzIGJlY2F1c2UgdGhlIGFsaWFzIHJlY29yZCBtdXN0IGhhdmUgdGhlIHNhbWUgdHlwZSBhcyB0aGUgcmVjb3JkIHRoYXQgeW91J3JlIHJvdXRpbmcgdHJhZmZpYyB0bywgYW5kIGNyZWF0aW5nIGEgQ05BTUUgcmVjb3JkIGZvciB0aGUgem9uZSBhcGV4IGlzbid0IHN1cHBvcnRlZCBldmVuIGZvciBhbiBhbGlhcyByZWNvcmQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1hbGlhc3RhcmdldC5odG1sI2Nmbi1yb3V0ZTUzLWFsaWFzdGFyZ2V0LWRuc2hvc3RuYW1lXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBkbnNOYW1lOiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiAqQXBwbGllcyBvbmx5IHRvIGFsaWFzIHJlY29yZHMgd2l0aCBhbnkgcm91dGluZyBwb2xpY3k6KiBXaGVuIGBFdmFsdWF0ZVRhcmdldEhlYWx0aGAgaXMgYHRydWVgICwgYW4gYWxpYXMgcmVjb3JkIGluaGVyaXRzIHRoZSBoZWFsdGggb2YgdGhlIHJlZmVyZW5jZWQgQVdTIHJlc291cmNlLCBzdWNoIGFzIGFuIEVMQiBsb2FkIGJhbGFuY2VyIG9yIGFub3RoZXIgcmVjb3JkIGluIHRoZSBob3N0ZWQgem9uZS5cbiAgICAgICAgICpcbiAgICAgICAgICogTm90ZSB0aGUgZm9sbG93aW5nOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICoqQ2xvdWRGcm9udCBkaXN0cmlidXRpb25zKiogLSBZb3UgY2FuJ3Qgc2V0IGBFdmFsdWF0ZVRhcmdldEhlYWx0aGAgdG8gYHRydWVgIHdoZW4gdGhlIGFsaWFzIHRhcmdldCBpcyBhIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uLlxuICAgICAgICAgKiAtICoqRWxhc3RpYyBCZWFuc3RhbGsgZW52aXJvbm1lbnRzIHRoYXQgaGF2ZSByZWdpb25hbGl6ZWQgc3ViZG9tYWlucyoqIC0gSWYgeW91IHNwZWNpZnkgYW4gRWxhc3RpYyBCZWFuc3RhbGsgZW52aXJvbm1lbnQgaW4gYEROU05hbWVgIGFuZCB0aGUgZW52aXJvbm1lbnQgY29udGFpbnMgYW4gRUxCIGxvYWQgYmFsYW5jZXIsIEVsYXN0aWMgTG9hZCBCYWxhbmNpbmcgcm91dGVzIHF1ZXJpZXMgb25seSB0byB0aGUgaGVhbHRoeSBBbWF6b24gRUMyIGluc3RhbmNlcyB0aGF0IGFyZSByZWdpc3RlcmVkIHdpdGggdGhlIGxvYWQgYmFsYW5jZXIuIChBbiBlbnZpcm9ubWVudCBhdXRvbWF0aWNhbGx5IGNvbnRhaW5zIGFuIEVMQiBsb2FkIGJhbGFuY2VyIGlmIGl0IGluY2x1ZGVzIG1vcmUgdGhhbiBvbmUgQW1hem9uIEVDMiBpbnN0YW5jZS4pIElmIHlvdSBzZXQgYEV2YWx1YXRlVGFyZ2V0SGVhbHRoYCB0byBgdHJ1ZWAgYW5kIGVpdGhlciBubyBBbWF6b24gRUMyIGluc3RhbmNlcyBhcmUgaGVhbHRoeSBvciB0aGUgbG9hZCBiYWxhbmNlciBpdHNlbGYgaXMgdW5oZWFsdGh5LCBSb3V0ZSA1MyByb3V0ZXMgcXVlcmllcyB0byBvdGhlciBhdmFpbGFibGUgcmVzb3VyY2VzIHRoYXQgYXJlIGhlYWx0aHksIGlmIGFueS5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgdGhlIGVudmlyb25tZW50IGNvbnRhaW5zIGEgc2luZ2xlIEFtYXpvbiBFQzIgaW5zdGFuY2UsIHRoZXJlIGFyZSBubyBzcGVjaWFsIHJlcXVpcmVtZW50cy5cbiAgICAgICAgICogLSAqKkVMQiBsb2FkIGJhbGFuY2VycyoqIC0gSGVhbHRoIGNoZWNraW5nIGJlaGF2aW9yIGRlcGVuZHMgb24gdGhlIHR5cGUgb2YgbG9hZCBiYWxhbmNlcjpcbiAgICAgICAgICpcbiAgICAgICAgICogLSAqQ2xhc3NpYyBMb2FkIEJhbGFuY2VycyogOiBJZiB5b3Ugc3BlY2lmeSBhbiBFTEIgQ2xhc3NpYyBMb2FkIEJhbGFuY2VyIGluIGBETlNOYW1lYCAsIEVsYXN0aWMgTG9hZCBCYWxhbmNpbmcgcm91dGVzIHF1ZXJpZXMgb25seSB0byB0aGUgaGVhbHRoeSBBbWF6b24gRUMyIGluc3RhbmNlcyB0aGF0IGFyZSByZWdpc3RlcmVkIHdpdGggdGhlIGxvYWQgYmFsYW5jZXIuIElmIHlvdSBzZXQgYEV2YWx1YXRlVGFyZ2V0SGVhbHRoYCB0byBgdHJ1ZWAgYW5kIGVpdGhlciBubyBFQzIgaW5zdGFuY2VzIGFyZSBoZWFsdGh5IG9yIHRoZSBsb2FkIGJhbGFuY2VyIGl0c2VsZiBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIHJvdXRlcyBxdWVyaWVzIHRvIG90aGVyIHJlc291cmNlcy5cbiAgICAgICAgICogLSAqQXBwbGljYXRpb24gYW5kIE5ldHdvcmsgTG9hZCBCYWxhbmNlcnMqIDogSWYgeW91IHNwZWNpZnkgYW4gRUxCIEFwcGxpY2F0aW9uIG9yIE5ldHdvcmsgTG9hZCBCYWxhbmNlciBhbmQgeW91IHNldCBgRXZhbHVhdGVUYXJnZXRIZWFsdGhgIHRvIGB0cnVlYCAsIFJvdXRlIDUzIHJvdXRlcyBxdWVyaWVzIHRvIHRoZSBsb2FkIGJhbGFuY2VyIGJhc2VkIG9uIHRoZSBoZWFsdGggb2YgdGhlIHRhcmdldCBncm91cHMgdGhhdCBhcmUgYXNzb2NpYXRlZCB3aXRoIHRoZSBsb2FkIGJhbGFuY2VyOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIEZvciBhbiBBcHBsaWNhdGlvbiBvciBOZXR3b3JrIExvYWQgQmFsYW5jZXIgdG8gYmUgY29uc2lkZXJlZCBoZWFsdGh5LCBldmVyeSB0YXJnZXQgZ3JvdXAgdGhhdCBjb250YWlucyB0YXJnZXRzIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgaGVhbHRoeSB0YXJnZXQuIElmIGFueSB0YXJnZXQgZ3JvdXAgY29udGFpbnMgb25seSB1bmhlYWx0aHkgdGFyZ2V0cywgdGhlIGxvYWQgYmFsYW5jZXIgaXMgY29uc2lkZXJlZCB1bmhlYWx0aHksIGFuZCBSb3V0ZSA1MyByb3V0ZXMgcXVlcmllcyB0byBvdGhlciByZXNvdXJjZXMuXG4gICAgICAgICAqIC0gQSB0YXJnZXQgZ3JvdXAgdGhhdCBoYXMgbm8gcmVnaXN0ZXJlZCB0YXJnZXRzIGlzIGNvbnNpZGVyZWQgdW5oZWFsdGh5LlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFdoZW4geW91IGNyZWF0ZSBhIGxvYWQgYmFsYW5jZXIsIHlvdSBjb25maWd1cmUgc2V0dGluZ3MgZm9yIEVsYXN0aWMgTG9hZCBCYWxhbmNpbmcgaGVhbHRoIGNoZWNrczsgdGhleSdyZSBub3QgUm91dGUgNTMgaGVhbHRoIGNoZWNrcywgYnV0IHRoZXkgcGVyZm9ybSBhIHNpbWlsYXIgZnVuY3Rpb24uIERvIG5vdCBjcmVhdGUgUm91dGUgNTMgaGVhbHRoIGNoZWNrcyBmb3IgdGhlIEVDMiBpbnN0YW5jZXMgdGhhdCB5b3UgcmVnaXN0ZXIgd2l0aCBhbiBFTEIgbG9hZCBiYWxhbmNlci5cbiAgICAgICAgICogLSAqKlMzIGJ1Y2tldHMqKiAtIFRoZXJlIGFyZSBubyBzcGVjaWFsIHJlcXVpcmVtZW50cyBmb3Igc2V0dGluZyBgRXZhbHVhdGVUYXJnZXRIZWFsdGhgIHRvIGB0cnVlYCB3aGVuIHRoZSBhbGlhcyB0YXJnZXQgaXMgYW4gUzMgYnVja2V0LlxuICAgICAgICAgKiAtICoqT3RoZXIgcmVjb3JkcyBpbiB0aGUgc2FtZSBob3N0ZWQgem9uZSoqIC0gSWYgdGhlIEFXUyByZXNvdXJjZSB0aGF0IHlvdSBzcGVjaWZ5IGluIGBETlNOYW1lYCBpcyBhIHJlY29yZCBvciBhIGdyb3VwIG9mIHJlY29yZHMgKGZvciBleGFtcGxlLCBhIGdyb3VwIG9mIHdlaWdodGVkIHJlY29yZHMpIGJ1dCBpcyBub3QgYW5vdGhlciBhbGlhcyByZWNvcmQsIHdlIHJlY29tbWVuZCB0aGF0IHlvdSBhc3NvY2lhdGUgYSBoZWFsdGggY2hlY2sgd2l0aCBhbGwgb2YgdGhlIHJlY29yZHMgaW4gdGhlIGFsaWFzIHRhcmdldC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbV2hhdCBIYXBwZW5zIFdoZW4gWW91IE9taXQgSGVhbHRoIENoZWNrcz9dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9kbnMtZmFpbG92ZXItY29tcGxleC1jb25maWdzLmh0bWwjZG5zLWZhaWxvdmVyLWNvbXBsZXgtY29uZmlncy1oYy1vbWl0dGluZykgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFuZCBleGFtcGxlcywgc2VlIFtBbWF6b24gUm91dGUgNTMgSGVhbHRoIENoZWNrcyBhbmQgRE5TIEZhaWxvdmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLmh0bWwpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtYWxpYXN0YXJnZXQuaHRtbCNjZm4tcm91dGU1My1hbGlhc3RhcmdldC1ldmFsdWF0ZXRhcmdldGhlYWx0aFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgZXZhbHVhdGVUYXJnZXRIZWFsdGg/OiBib29sZWFuIHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogKkFsaWFzIHJlc291cmNlIHJlY29yZHMgc2V0cyBvbmx5KiA6IFRoZSB2YWx1ZSB1c2VkIGRlcGVuZHMgb24gd2hlcmUgeW91IHdhbnQgdG8gcm91dGUgdHJhZmZpYzpcbiAgICAgICAgICpcbiAgICAgICAgICogLSAqKkFtYXpvbiBBUEkgR2F0ZXdheSBjdXN0b20gcmVnaW9uYWwgQVBJcyBhbmQgZWRnZS1vcHRpbWl6ZWQgQVBJcyoqIC0gU3BlY2lmeSB0aGUgaG9zdGVkIHpvbmUgSUQgZm9yIHlvdXIgQVBJLiBZb3UgY2FuIGdldCB0aGUgYXBwbGljYWJsZSB2YWx1ZSB1c2luZyB0aGUgQVdTIENMSSBjb21tYW5kIFtnZXQtZG9tYWluLW5hbWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xpL2xhdGVzdC9yZWZlcmVuY2UvYXBpZ2F0ZXdheS9nZXQtZG9tYWluLW5hbWVzLmh0bWwpIDpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBGb3IgcmVnaW9uYWwgQVBJcywgc3BlY2lmeSB0aGUgdmFsdWUgb2YgYHJlZ2lvbmFsSG9zdGVkWm9uZUlkYCAuXG4gICAgICAgICAqIC0gRm9yIGVkZ2Utb3B0aW1pemVkIEFQSXMsIHNwZWNpZnkgdGhlIHZhbHVlIG9mIGBkaXN0cmlidXRpb25Ib3N0ZWRab25lSWRgIC5cbiAgICAgICAgICogLSAqKkFtYXpvbiBWaXJ0dWFsIFByaXZhdGUgQ2xvdWQgaW50ZXJmYWNlIFZQQyBlbmRwb2ludCoqIC0gU3BlY2lmeSB0aGUgaG9zdGVkIHpvbmUgSUQgZm9yIHlvdXIgaW50ZXJmYWNlIGVuZHBvaW50LiBZb3UgY2FuIGdldCB0aGUgdmFsdWUgb2YgYEhvc3RlZFpvbmVJZGAgdXNpbmcgdGhlIEFXUyBDTEkgY29tbWFuZCBbZGVzY3JpYmUtdnBjLWVuZHBvaW50c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsaS9sYXRlc3QvcmVmZXJlbmNlL2VjMi9kZXNjcmliZS12cGMtZW5kcG9pbnRzLmh0bWwpIC5cbiAgICAgICAgICogLSAqKkNsb3VkRnJvbnQgZGlzdHJpYnV0aW9uKiogLSBTcGVjaWZ5IGBaMkZEVE5EQVRBUVlXMmAgLiBUaGlzIGlzIGFsd2F5cyB0aGUgaG9zdGVkIHpvbmUgSUQgd2hlbiB5b3UgY3JlYXRlIGFuIGFsaWFzIHJlY29yZCB0aGF0IHJvdXRlcyB0cmFmZmljIHRvIGEgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24uXG4gICAgICAgICAqXG4gICAgICAgICAqID4gQWxpYXMgcmVjb3JkcyBmb3IgQ2xvdWRGcm9udCBjYW4ndCBiZSBjcmVhdGVkIGluIGEgcHJpdmF0ZSB6b25lLlxuICAgICAgICAgKiAtICoqRWxhc3RpYyBCZWFuc3RhbGsgZW52aXJvbm1lbnQqKiAtIFNwZWNpZnkgdGhlIGhvc3RlZCB6b25lIElEIGZvciB0aGUgcmVnaW9uIHRoYXQgeW91IGNyZWF0ZWQgdGhlIGVudmlyb25tZW50IGluLiBUaGUgZW52aXJvbm1lbnQgbXVzdCBoYXZlIGEgcmVnaW9uYWxpemVkIHN1YmRvbWFpbi4gRm9yIGEgbGlzdCBvZiByZWdpb25zIGFuZCB0aGUgY29ycmVzcG9uZGluZyBob3N0ZWQgem9uZSBJRHMsIHNlZSBbQVdTIEVsYXN0aWMgQmVhbnN0YWxrIGVuZHBvaW50cyBhbmQgcXVvdGFzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2VuZXJhbC9sYXRlc3QvZ3IvZWxhc3RpY2JlYW5zdGFsay5odG1sKSBpbiB0aGUgKkFtYXpvbiBXZWIgU2VydmljZXMgR2VuZXJhbCBSZWZlcmVuY2UqIC5cbiAgICAgICAgICogLSAqKkVMQiBsb2FkIGJhbGFuY2VyKiogLSBTcGVjaWZ5IHRoZSB2YWx1ZSBvZiB0aGUgaG9zdGVkIHpvbmUgSUQgZm9yIHRoZSBsb2FkIGJhbGFuY2VyLiBVc2UgdGhlIGZvbGxvd2luZyBtZXRob2RzIHRvIGdldCB0aGUgaG9zdGVkIHpvbmUgSUQ6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gW1NlcnZpY2UgRW5kcG9pbnRzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2VuZXJhbC9sYXRlc3QvZ3IvZWxiLmh0bWwpIHRhYmxlIGluIHRoZSBcIkVsYXN0aWMgTG9hZCBCYWxhbmNpbmcgZW5kcG9pbnRzIGFuZCBxdW90YXNcIiB0b3BpYyBpbiB0aGUgKkFtYXpvbiBXZWIgU2VydmljZXMgR2VuZXJhbCBSZWZlcmVuY2UqIDogVXNlIHRoZSB2YWx1ZSB0aGF0IGNvcnJlc3BvbmRzIHdpdGggdGhlIHJlZ2lvbiB0aGF0IHlvdSBjcmVhdGVkIHlvdXIgbG9hZCBiYWxhbmNlciBpbi4gTm90ZSB0aGF0IHRoZXJlIGFyZSBzZXBhcmF0ZSBjb2x1bW5zIGZvciBBcHBsaWNhdGlvbiBhbmQgQ2xhc3NpYyBMb2FkIEJhbGFuY2VycyBhbmQgZm9yIE5ldHdvcmsgTG9hZCBCYWxhbmNlcnMuXG4gICAgICAgICAqIC0gKkFXUyBNYW5hZ2VtZW50IENvbnNvbGUqIDogR28gdG8gdGhlIEFtYXpvbiBFQzIgcGFnZSwgY2hvb3NlICpMb2FkIEJhbGFuY2VycyogaW4gdGhlIG5hdmlnYXRpb24gcGFuZSwgc2VsZWN0IHRoZSBsb2FkIGJhbGFuY2VyLCBhbmQgZ2V0IHRoZSB2YWx1ZSBvZiB0aGUgKkhvc3RlZCB6b25lKiBmaWVsZCBvbiB0aGUgKkRlc2NyaXB0aW9uKiB0YWIuXG4gICAgICAgICAqIC0gKkVsYXN0aWMgTG9hZCBCYWxhbmNpbmcgQVBJKiA6IFVzZSBgRGVzY3JpYmVMb2FkQmFsYW5jZXJzYCB0byBnZXQgdGhlIGFwcGxpY2FibGUgdmFsdWUuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgdGhlIGFwcGxpY2FibGUgZ3VpZGU6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gQ2xhc3NpYyBMb2FkIEJhbGFuY2VyczogVXNlIFtEZXNjcmliZUxvYWRCYWxhbmNlcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVMb2FkQmFsYW5jZXJzLmh0bWwpIHRvIGdldCB0aGUgdmFsdWUgb2YgYENhbm9uaWNhbEhvc3RlZFpvbmVOYW1lSURgIC5cbiAgICAgICAgICogLSBBcHBsaWNhdGlvbiBhbmQgTmV0d29yayBMb2FkIEJhbGFuY2VyczogVXNlIFtEZXNjcmliZUxvYWRCYWxhbmNlcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUxvYWRCYWxhbmNlcnMuaHRtbCkgdG8gZ2V0IHRoZSB2YWx1ZSBvZiBgQ2Fub25pY2FsSG9zdGVkWm9uZUlEYCAuXG4gICAgICAgICAqIC0gKkNsb3VkRm9ybWF0aW9uIEZuOjpHZXRBdHQgaW50cmluc2ljIGZ1bmN0aW9uKiA6IFVzZSB0aGUgW0ZuOjpHZXRBdHRdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2ludHJpbnNpYy1mdW5jdGlvbi1yZWZlcmVuY2UtZ2V0YXR0Lmh0bWwpIGludHJpbnNpYyBmdW5jdGlvbiB0byBnZXQgdGhlIGFwcGxpY2FibGUgdmFsdWU6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gQ2xhc3NpYyBMb2FkIEJhbGFuY2VyczogR2V0IFtDYW5vbmljYWxIb3N0ZWRab25lTmFtZUlEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lYzItZWxiLmh0bWwjYXdzLXByb3BlcnRpZXMtZWMyLWVsYi1yZXR1cm4tdmFsdWVzKSAuXG4gICAgICAgICAqIC0gQXBwbGljYXRpb24gYW5kIE5ldHdvcmsgTG9hZCBCYWxhbmNlcnM6IEdldCBbQ2Fub25pY2FsSG9zdGVkWm9uZUlEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWxhc3RpY2xvYWRiYWxhbmNpbmd2Mi1sb2FkYmFsYW5jZXIuaHRtbCNhd3MtcmVzb3VyY2UtZWxhc3RpY2xvYWRiYWxhbmNpbmd2Mi1sb2FkYmFsYW5jZXItcmV0dXJuLXZhbHVlcykgLlxuICAgICAgICAgKiAtICpBV1MgQ0xJKiA6IFVzZSBgZGVzY3JpYmUtbG9hZC1iYWxhbmNlcnNgIHRvIGdldCB0aGUgYXBwbGljYWJsZSB2YWx1ZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSB0aGUgYXBwbGljYWJsZSBndWlkZTpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBDbGFzc2ljIExvYWQgQmFsYW5jZXJzOiBVc2UgW2Rlc2NyaWJlLWxvYWQtYmFsYW5jZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xpL2xhdGVzdC9yZWZlcmVuY2UvZWxiL2Rlc2NyaWJlLWxvYWQtYmFsYW5jZXJzLmh0bWwpIHRvIGdldCB0aGUgdmFsdWUgb2YgYENhbm9uaWNhbEhvc3RlZFpvbmVOYW1lSURgIC5cbiAgICAgICAgICogLSBBcHBsaWNhdGlvbiBhbmQgTmV0d29yayBMb2FkIEJhbGFuY2VyczogVXNlIFtkZXNjcmliZS1sb2FkLWJhbGFuY2Vyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsaS9sYXRlc3QvcmVmZXJlbmNlL2VsYnYyL2Rlc2NyaWJlLWxvYWQtYmFsYW5jZXJzLmh0bWwpIHRvIGdldCB0aGUgdmFsdWUgb2YgYENhbm9uaWNhbEhvc3RlZFpvbmVJRGAgLlxuICAgICAgICAgKiAtICoqR2xvYmFsIEFjY2VsZXJhdG9yIGFjY2VsZXJhdG9yKiogLSBTcGVjaWZ5IGBaMkJKNlhRNUZLN1U0SGAgLlxuICAgICAgICAgKiAtICoqQW4gQW1hem9uIFMzIGJ1Y2tldCBjb25maWd1cmVkIGFzIGEgc3RhdGljIHdlYnNpdGUqKiAtIFNwZWNpZnkgdGhlIGhvc3RlZCB6b25lIElEIGZvciB0aGUgcmVnaW9uIHRoYXQgeW91IGNyZWF0ZWQgdGhlIGJ1Y2tldCBpbi4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdmFsaWQgdmFsdWVzLCBzZWUgdGhlIHRhYmxlIFtBbWF6b24gUzMgV2Vic2l0ZSBFbmRwb2ludHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nZW5lcmFsL2xhdGVzdC9nci9zMy5odG1sI3MzX3dlYnNpdGVfcmVnaW9uX2VuZHBvaW50cykgaW4gdGhlICpBbWF6b24gV2ViIFNlcnZpY2VzIEdlbmVyYWwgUmVmZXJlbmNlKiAuXG4gICAgICAgICAqIC0gKipBbm90aGVyIFJvdXRlIDUzIHJlY29yZCBpbiB5b3VyIGhvc3RlZCB6b25lKiogLSBTcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSBJRCBvZiB5b3VyIGhvc3RlZCB6b25lLiAoQW4gYWxpYXMgcmVjb3JkIGNhbid0IHJlZmVyZW5jZSBhIHJlY29yZCBpbiBhIGRpZmZlcmVudCBob3N0ZWQgem9uZS4pXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1hbGlhc3RhcmdldC5odG1sI2Nmbi1yb3V0ZTUzLWFsaWFzdGFyZ2V0LWhvc3RlZHpvbmVpZFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgaG9zdGVkWm9uZUlkOiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYEFsaWFzVGFyZ2V0UHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEFsaWFzVGFyZ2V0UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuUmVjb3JkU2V0R3JvdXBfQWxpYXNUYXJnZXRQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2Ruc05hbWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMuZG5zTmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZG5zTmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5kbnNOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdldmFsdWF0ZVRhcmdldEhlYWx0aCcsIGNkay52YWxpZGF0ZUJvb2xlYW4pKHByb3BlcnRpZXMuZXZhbHVhdGVUYXJnZXRIZWFsdGgpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hvc3RlZFpvbmVJZCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5ob3N0ZWRab25lSWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hvc3RlZFpvbmVJZCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5ob3N0ZWRab25lSWQpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQWxpYXNUYXJnZXRQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0R3JvdXAuQWxpYXNUYXJnZXRgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEFsaWFzVGFyZ2V0UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldEdyb3VwLkFsaWFzVGFyZ2V0YCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblJlY29yZFNldEdyb3VwQWxpYXNUYXJnZXRQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuUmVjb3JkU2V0R3JvdXBfQWxpYXNUYXJnZXRQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgRE5TTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5kbnNOYW1lKSxcbiAgICAgICAgRXZhbHVhdGVUYXJnZXRIZWFsdGg6IGNkay5ib29sZWFuVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmV2YWx1YXRlVGFyZ2V0SGVhbHRoKSxcbiAgICAgICAgSG9zdGVkWm9uZUlkOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmhvc3RlZFpvbmVJZCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblJlY29yZFNldEdyb3VwQWxpYXNUYXJnZXRQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblJlY29yZFNldEdyb3VwLkFsaWFzVGFyZ2V0UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuUmVjb3JkU2V0R3JvdXAuQWxpYXNUYXJnZXRQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2Ruc05hbWUnLCAnRE5TTmFtZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuRE5TTmFtZSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZXZhbHVhdGVUYXJnZXRIZWFsdGgnLCAnRXZhbHVhdGVUYXJnZXRIZWFsdGgnLCBwcm9wZXJ0aWVzLkV2YWx1YXRlVGFyZ2V0SGVhbHRoICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5FdmFsdWF0ZVRhcmdldEhlYWx0aCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaG9zdGVkWm9uZUlkJywgJ0hvc3RlZFpvbmVJZCcsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuSG9zdGVkWm9uZUlkKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuUmVjb3JkU2V0R3JvdXAge1xuICAgIC8qKlxuICAgICAqIEEgY29tcGxleCB0eXBlIHRoYXQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgYSBnZW9ncmFwaGljIGxvY2F0aW9uLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQtZ2VvbG9jYXRpb24uaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgR2VvTG9jYXRpb25Qcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBGb3IgZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMsIGEgdHdvLWxldHRlciBhYmJyZXZpYXRpb24gdGhhdCBpZGVudGlmaWVzIGEgY29udGluZW50LiBSb3V0ZSA1MyBzdXBwb3J0cyB0aGUgZm9sbG93aW5nIGNvbnRpbmVudCBjb2RlczpcbiAgICAgICAgICpcbiAgICAgICAgICogLSAqQUYqIDogQWZyaWNhXG4gICAgICAgICAqIC0gKkFOKiA6IEFudGFyY3RpY2FcbiAgICAgICAgICogLSAqQVMqIDogQXNpYVxuICAgICAgICAgKiAtICpFVSogOiBFdXJvcGVcbiAgICAgICAgICogLSAqT0MqIDogT2NlYW5pYVxuICAgICAgICAgKiAtICpOQSogOiBOb3J0aCBBbWVyaWNhXG4gICAgICAgICAqIC0gKlNBKiA6IFNvdXRoIEFtZXJpY2FcbiAgICAgICAgICpcbiAgICAgICAgICogQ29uc3RyYWludDogU3BlY2lmeWluZyBgQ29udGluZW50Q29kZWAgd2l0aCBlaXRoZXIgYENvdW50cnlDb2RlYCBvciBgU3ViZGl2aXNpb25Db2RlYCByZXR1cm5zIGFuIGBJbnZhbGlkSW5wdXRgIGVycm9yLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0LWdlb2xvY2F0aW9uLmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0Z3JvdXAtZ2VvbG9jYXRpb24tY29udGluZW50Y29kZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY29udGluZW50Q29kZT86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEZvciBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cywgdGhlIHR3by1sZXR0ZXIgY29kZSBmb3IgYSBjb3VudHJ5LlxuICAgICAgICAgKlxuICAgICAgICAgKiBSb3V0ZSA1MyB1c2VzIHRoZSB0d28tbGV0dGVyIGNvdW50cnkgY29kZXMgdGhhdCBhcmUgc3BlY2lmaWVkIGluIFtJU08gc3RhbmRhcmQgMzE2Ni0xIGFscGhhLTJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fMzE2Ni0xX2FscGhhLTIpIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC1nZW9sb2NhdGlvbi5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1nZW9sb2NhdGlvbi1jb3VudHJ5Y29kZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY291bnRyeUNvZGU/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBGb3IgZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMsIHRoZSB0d28tbGV0dGVyIGNvZGUgZm9yIGEgc3RhdGUgb2YgdGhlIFVuaXRlZCBTdGF0ZXMuIFJvdXRlIDUzIGRvZXNuJ3Qgc3VwcG9ydCBhbnkgb3RoZXIgdmFsdWVzIGZvciBgU3ViZGl2aXNpb25Db2RlYCAuIEZvciBhIGxpc3Qgb2Ygc3RhdGUgYWJicmV2aWF0aW9ucywgc2VlIFtBcHBlbmRpeCBCOiBUd2/igJNMZXR0ZXIgU3RhdGUgYW5kIFBvc3Nlc3Npb24gQWJicmV2aWF0aW9uc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vcGUudXNwcy5jb20vdGV4dC9wdWIyOC8yOGFwYi5odG0pIG9uIHRoZSBVbml0ZWQgU3RhdGVzIFBvc3RhbCBTZXJ2aWNlIHdlYnNpdGUuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSBzcGVjaWZ5IGBzdWJkaXZpc2lvbmNvZGVgICwgeW91IG11c3QgYWxzbyBzcGVjaWZ5IGBVU2AgZm9yIGBDb3VudHJ5Q29kZWAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0LWdlb2xvY2F0aW9uLmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LWdlb2xvY2F0aW9uLXN1YmRpdmlzaW9uY29kZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgc3ViZGl2aXNpb25Db2RlPzogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBHZW9Mb2NhdGlvblByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBHZW9Mb2NhdGlvblByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblJlY29yZFNldEdyb3VwX0dlb0xvY2F0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjb250aW5lbnRDb2RlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmNvbnRpbmVudENvZGUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvdW50cnlDb2RlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmNvdW50cnlDb2RlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzdWJkaXZpc2lvbkNvZGUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuc3ViZGl2aXNpb25Db2RlKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkdlb0xvY2F0aW9uUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldEdyb3VwLkdlb0xvY2F0aW9uYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBHZW9Mb2NhdGlvblByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRHcm91cC5HZW9Mb2NhdGlvbmAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5SZWNvcmRTZXRHcm91cEdlb0xvY2F0aW9uUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblJlY29yZFNldEdyb3VwX0dlb0xvY2F0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIENvbnRpbmVudENvZGU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY29udGluZW50Q29kZSksXG4gICAgICAgIENvdW50cnlDb2RlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNvdW50cnlDb2RlKSxcbiAgICAgICAgU3ViZGl2aXNpb25Db2RlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnN1YmRpdmlzaW9uQ29kZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblJlY29yZFNldEdyb3VwR2VvTG9jYXRpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblJlY29yZFNldEdyb3VwLkdlb0xvY2F0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuUmVjb3JkU2V0R3JvdXAuR2VvTG9jYXRpb25Qcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2NvbnRpbmVudENvZGUnLCAnQ29udGluZW50Q29kZScsIHByb3BlcnRpZXMuQ29udGluZW50Q29kZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Db250aW5lbnRDb2RlKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjb3VudHJ5Q29kZScsICdDb3VudHJ5Q29kZScsIHByb3BlcnRpZXMuQ291bnRyeUNvZGUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQ291bnRyeUNvZGUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3N1YmRpdmlzaW9uQ29kZScsICdTdWJkaXZpc2lvbkNvZGUnLCBwcm9wZXJ0aWVzLlN1YmRpdmlzaW9uQ29kZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5TdWJkaXZpc2lvbkNvZGUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5SZWNvcmRTZXRHcm91cCB7XG4gICAgLyoqXG4gICAgICogSW5mb3JtYXRpb24gYWJvdXQgb25lIHJlY29yZCB0aGF0IHlvdSB3YW50IHRvIGNyZWF0ZS5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIFJlY29yZFNldFByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqICpBbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0cyBvbmx5OiogSW5mb3JtYXRpb24gYWJvdXQgdGhlIEFXUyByZXNvdXJjZSwgc3VjaCBhcyBhIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uIG9yIGFuIEFtYXpvbiBTMyBidWNrZXQsIHRoYXQgeW91IHdhbnQgdG8gcm91dGUgdHJhZmZpYyB0by5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgeW91J3JlIGNyZWF0aW5nIHJlc291cmNlIHJlY29yZHMgc2V0cyBmb3IgYSBwcml2YXRlIGhvc3RlZCB6b25lLCBub3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gWW91IGNhbid0IGNyZWF0ZSBhbiBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0IGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSB0byByb3V0ZSB0cmFmZmljIHRvIGEgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24uXG4gICAgICAgICAqIC0gQ3JlYXRpbmcgZ2VvbG9jYXRpb24gYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMgb3IgbGF0ZW5jeSBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0cyBpbiBhIHByaXZhdGUgaG9zdGVkIHpvbmUgaXMgdW5zdXBwb3J0ZWQuXG4gICAgICAgICAqIC0gRm9yIGluZm9ybWF0aW9uIGFib3V0IGNyZWF0aW5nIGZhaWxvdmVyIHJlc291cmNlIHJlY29yZCBzZXRzIGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSwgc2VlIFtDb25maWd1cmluZyBGYWlsb3ZlciBpbiBhIFByaXZhdGUgSG9zdGVkIFpvbmVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9kbnMtZmFpbG92ZXItcHJpdmF0ZS1ob3N0ZWQtem9uZXMuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtYWxpYXN0YXJnZXRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGFsaWFzVGFyZ2V0PzogQ2ZuUmVjb3JkU2V0R3JvdXAuQWxpYXNUYXJnZXRQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqICpGYWlsb3ZlciByZXNvdXJjZSByZWNvcmQgc2V0cyBvbmx5OiogVG8gY29uZmlndXJlIGZhaWxvdmVyLCB5b3UgYWRkIHRoZSBgRmFpbG92ZXJgIGVsZW1lbnQgdG8gdHdvIHJlc291cmNlIHJlY29yZCBzZXRzLiBGb3Igb25lIHJlc291cmNlIHJlY29yZCBzZXQsIHlvdSBzcGVjaWZ5IGBQUklNQVJZYCBhcyB0aGUgdmFsdWUgZm9yIGBGYWlsb3ZlcmAgOyBmb3IgdGhlIG90aGVyIHJlc291cmNlIHJlY29yZCBzZXQsIHlvdSBzcGVjaWZ5IGBTRUNPTkRBUllgIC4gSW4gYWRkaXRpb24sIHlvdSBpbmNsdWRlIHRoZSBgSGVhbHRoQ2hlY2tJZGAgZWxlbWVudCBhbmQgc3BlY2lmeSB0aGUgaGVhbHRoIGNoZWNrIHRoYXQgeW91IHdhbnQgQW1hem9uIFJvdXRlIDUzIHRvIHBlcmZvcm0gZm9yIGVhY2ggcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgICAgICpcbiAgICAgICAgICogRXhjZXB0IHdoZXJlIG5vdGVkLCB0aGUgZm9sbG93aW5nIGZhaWxvdmVyIGJlaGF2aW9ycyBhc3N1bWUgdGhhdCB5b3UgaGF2ZSBpbmNsdWRlZCB0aGUgYEhlYWx0aENoZWNrSWRgIGVsZW1lbnQgaW4gYm90aCByZXNvdXJjZSByZWNvcmQgc2V0czpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBXaGVuIHRoZSBwcmltYXJ5IHJlc291cmNlIHJlY29yZCBzZXQgaXMgaGVhbHRoeSwgUm91dGUgNTMgcmVzcG9uZHMgdG8gRE5TIHF1ZXJpZXMgd2l0aCB0aGUgYXBwbGljYWJsZSB2YWx1ZSBmcm9tIHRoZSBwcmltYXJ5IHJlc291cmNlIHJlY29yZCBzZXQgcmVnYXJkbGVzcyBvZiB0aGUgaGVhbHRoIG9mIHRoZSBzZWNvbmRhcnkgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgICAgICogLSBXaGVuIHRoZSBwcmltYXJ5IHJlc291cmNlIHJlY29yZCBzZXQgaXMgdW5oZWFsdGh5IGFuZCB0aGUgc2Vjb25kYXJ5IHJlc291cmNlIHJlY29yZCBzZXQgaXMgaGVhbHRoeSwgUm91dGUgNTMgcmVzcG9uZHMgdG8gRE5TIHF1ZXJpZXMgd2l0aCB0aGUgYXBwbGljYWJsZSB2YWx1ZSBmcm9tIHRoZSBzZWNvbmRhcnkgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgICAgICogLSBXaGVuIHRoZSBzZWNvbmRhcnkgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdGhlIGFwcGxpY2FibGUgdmFsdWUgZnJvbSB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0IHJlZ2FyZGxlc3Mgb2YgdGhlIGhlYWx0aCBvZiB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAgICAgKiAtIElmIHlvdSBvbWl0IHRoZSBgSGVhbHRoQ2hlY2tJZGAgZWxlbWVudCBmb3IgdGhlIHNlY29uZGFyeSByZXNvdXJjZSByZWNvcmQgc2V0LCBhbmQgaWYgdGhlIHByaW1hcnkgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIGFsd2F5cyByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoIHRoZSBhcHBsaWNhYmxlIHZhbHVlIGZyb20gdGhlIHNlY29uZGFyeSByZXNvdXJjZSByZWNvcmQgc2V0LiBUaGlzIGlzIHRydWUgcmVnYXJkbGVzcyBvZiB0aGUgaGVhbHRoIG9mIHRoZSBhc3NvY2lhdGVkIGVuZHBvaW50LlxuICAgICAgICAgKlxuICAgICAgICAgKiBZb3UgY2FuJ3QgY3JlYXRlIG5vbi1mYWlsb3ZlciByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgdmFsdWVzIGZvciB0aGUgYE5hbWVgIGFuZCBgVHlwZWAgZWxlbWVudHMgYXMgZmFpbG92ZXIgcmVzb3VyY2UgcmVjb3JkIHNldHMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEZvciBmYWlsb3ZlciBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0cywgeW91IG11c3QgYWxzbyBpbmNsdWRlIHRoZSBgRXZhbHVhdGVUYXJnZXRIZWFsdGhgIGVsZW1lbnQgYW5kIHNldCB0aGUgdmFsdWUgdG8gdHJ1ZS5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgY29uZmlndXJpbmcgZmFpbG92ZXIgZm9yIFJvdXRlIDUzLCBzZWUgdGhlIGZvbGxvd2luZyB0b3BpY3MgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiA6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gW1JvdXRlIDUzIEhlYWx0aCBDaGVja3MgYW5kIEROUyBGYWlsb3Zlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci5odG1sKVxuICAgICAgICAgKiAtIFtDb25maWd1cmluZyBGYWlsb3ZlciBpbiBhIFByaXZhdGUgSG9zdGVkIFpvbmVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9kbnMtZmFpbG92ZXItcHJpdmF0ZS1ob3N0ZWQtem9uZXMuaHRtbClcbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1mYWlsb3ZlclxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgZmFpbG92ZXI/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiAqR2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgb25seToqIEEgY29tcGxleCB0eXBlIHRoYXQgbGV0cyB5b3UgY29udHJvbCBob3cgQW1hem9uIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIGJhc2VkIG9uIHRoZSBnZW9ncmFwaGljIG9yaWdpbiBvZiB0aGUgcXVlcnkuIEZvciBleGFtcGxlLCBpZiB5b3Ugd2FudCBhbGwgcXVlcmllcyBmcm9tIEFmcmljYSB0byBiZSByb3V0ZWQgdG8gYSB3ZWIgc2VydmVyIHdpdGggYW4gSVAgYWRkcmVzcyBvZiBgMTkyLjAuMi4xMTFgICwgY3JlYXRlIGEgcmVzb3VyY2UgcmVjb3JkIHNldCB3aXRoIGEgYFR5cGVgIG9mIGBBYCBhbmQgYSBgQ29udGluZW50Q29kZWAgb2YgYEFGYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gQWx0aG91Z2ggY3JlYXRpbmcgZ2VvbG9jYXRpb24gYW5kIGdlb2xvY2F0aW9uIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzIGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSBpcyBhbGxvd2VkLCBpdCdzIG5vdCBzdXBwb3J0ZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSBjcmVhdGUgc2VwYXJhdGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgZm9yIG92ZXJsYXBwaW5nIGdlb2dyYXBoaWMgcmVnaW9ucyAoZm9yIGV4YW1wbGUsIG9uZSByZXNvdXJjZSByZWNvcmQgc2V0IGZvciBhIGNvbnRpbmVudCBhbmQgb25lIGZvciBhIGNvdW50cnkgb24gdGhlIHNhbWUgY29udGluZW50KSwgcHJpb3JpdHkgZ29lcyB0byB0aGUgc21hbGxlc3QgZ2VvZ3JhcGhpYyByZWdpb24uIFRoaXMgYWxsb3dzIHlvdSB0byByb3V0ZSBtb3N0IHF1ZXJpZXMgZm9yIGEgY29udGluZW50IHRvIG9uZSByZXNvdXJjZSBhbmQgdG8gcm91dGUgcXVlcmllcyBmb3IgYSBjb3VudHJ5IG9uIHRoYXQgY29udGluZW50IHRvIGEgZGlmZmVyZW50IHJlc291cmNlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBZb3UgY2FuJ3QgY3JlYXRlIHR3byBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IHNwZWNpZnkgdGhlIHNhbWUgZ2VvZ3JhcGhpYyBsb2NhdGlvbi5cbiAgICAgICAgICpcbiAgICAgICAgICogVGhlIHZhbHVlIGAqYCBpbiB0aGUgYENvdW50cnlDb2RlYCBlbGVtZW50IG1hdGNoZXMgYWxsIGdlb2dyYXBoaWMgbG9jYXRpb25zIHRoYXQgYXJlbid0IHNwZWNpZmllZCBpbiBvdGhlciBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgdmFsdWVzIGZvciB0aGUgYE5hbWVgIGFuZCBgVHlwZWAgZWxlbWVudHMuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gR2VvbG9jYXRpb24gd29ya3MgYnkgbWFwcGluZyBJUCBhZGRyZXNzZXMgdG8gbG9jYXRpb25zLiBIb3dldmVyLCBzb21lIElQIGFkZHJlc3NlcyBhcmVuJ3QgbWFwcGVkIHRvIGdlb2dyYXBoaWMgbG9jYXRpb25zLCBzbyBldmVuIGlmIHlvdSBjcmVhdGUgZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBjb3ZlciBhbGwgc2V2ZW4gY29udGluZW50cywgUm91dGUgNTMgd2lsbCByZWNlaXZlIHNvbWUgRE5TIHF1ZXJpZXMgZnJvbSBsb2NhdGlvbnMgdGhhdCBpdCBjYW4ndCBpZGVudGlmeS4gV2UgcmVjb21tZW5kIHRoYXQgeW91IGNyZWF0ZSBhIHJlc291cmNlIHJlY29yZCBzZXQgZm9yIHdoaWNoIHRoZSB2YWx1ZSBvZiBgQ291bnRyeUNvZGVgIGlzIGAqYCAuIFR3byBncm91cHMgb2YgcXVlcmllcyBhcmUgcm91dGVkIHRvIHRoZSByZXNvdXJjZSB0aGF0IHlvdSBzcGVjaWZ5IGluIHRoaXMgcmVjb3JkOiBxdWVyaWVzIHRoYXQgY29tZSBmcm9tIGxvY2F0aW9ucyBmb3Igd2hpY2ggeW91IGhhdmVuJ3QgY3JlYXRlZCBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cyBhbmQgcXVlcmllcyBmcm9tIElQIGFkZHJlc3NlcyB0aGF0IGFyZW4ndCBtYXBwZWQgdG8gYSBsb2NhdGlvbi4gSWYgeW91IGRvbid0IGNyZWF0ZSBhIGAqYCByZXNvdXJjZSByZWNvcmQgc2V0LCBSb3V0ZSA1MyByZXR1cm5zIGEgXCJubyBhbnN3ZXJcIiByZXNwb25zZSBmb3IgcXVlcmllcyBmcm9tIHRob3NlIGxvY2F0aW9ucy5cbiAgICAgICAgICpcbiAgICAgICAgICogWW91IGNhbid0IGNyZWF0ZSBub24tZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIHZhbHVlcyBmb3IgdGhlIGBOYW1lYCBhbmQgYFR5cGVgIGVsZW1lbnRzIGFzIGdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LWdlb2xvY2F0aW9uXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBnZW9Mb2NhdGlvbj86IENmblJlY29yZFNldEdyb3VwLkdlb0xvY2F0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiB5b3Ugd2FudCBBbWF6b24gUm91dGUgNTMgdG8gcmV0dXJuIHRoaXMgcmVzb3VyY2UgcmVjb3JkIHNldCBpbiByZXNwb25zZSB0byBhIEROUyBxdWVyeSBvbmx5IHdoZW4gdGhlIHN0YXR1cyBvZiBhIGhlYWx0aCBjaGVjayBpcyBoZWFsdGh5LCBpbmNsdWRlIHRoZSBgSGVhbHRoQ2hlY2tJZGAgZWxlbWVudCBhbmQgc3BlY2lmeSB0aGUgSUQgb2YgdGhlIGFwcGxpY2FibGUgaGVhbHRoIGNoZWNrLlxuICAgICAgICAgKlxuICAgICAgICAgKiBSb3V0ZSA1MyBkZXRlcm1pbmVzIHdoZXRoZXIgYSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIGhlYWx0aHkgYmFzZWQgb24gb25lIG9mIHRoZSBmb2xsb3dpbmc6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gQnkgcGVyaW9kaWNhbGx5IHNlbmRpbmcgYSByZXF1ZXN0IHRvIHRoZSBlbmRwb2ludCB0aGF0IGlzIHNwZWNpZmllZCBpbiB0aGUgaGVhbHRoIGNoZWNrXG4gICAgICAgICAqIC0gQnkgYWdncmVnYXRpbmcgdGhlIHN0YXR1cyBvZiBhIHNwZWNpZmllZCBncm91cCBvZiBoZWFsdGggY2hlY2tzIChjYWxjdWxhdGVkIGhlYWx0aCBjaGVja3MpXG4gICAgICAgICAqIC0gQnkgZGV0ZXJtaW5pbmcgdGhlIGN1cnJlbnQgc3RhdGUgb2YgYSBDbG91ZFdhdGNoIGFsYXJtIChDbG91ZFdhdGNoIG1ldHJpYyBoZWFsdGggY2hlY2tzKVxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFJvdXRlIDUzIGRvZXNuJ3QgY2hlY2sgdGhlIGhlYWx0aCBvZiB0aGUgZW5kcG9pbnQgdGhhdCBpcyBzcGVjaWZpZWQgaW4gdGhlIHJlc291cmNlIHJlY29yZCBzZXQsIGZvciBleGFtcGxlLCB0aGUgZW5kcG9pbnQgc3BlY2lmaWVkIGJ5IHRoZSBJUCBhZGRyZXNzIGluIHRoZSBgVmFsdWVgIGVsZW1lbnQuIFdoZW4geW91IGFkZCBhIGBIZWFsdGhDaGVja0lkYCBlbGVtZW50IHRvIGEgcmVzb3VyY2UgcmVjb3JkIHNldCwgUm91dGUgNTMgY2hlY2tzIHRoZSBoZWFsdGggb2YgdGhlIGVuZHBvaW50IHRoYXQgeW91IHNwZWNpZmllZCBpbiB0aGUgaGVhbHRoIGNoZWNrLlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIHRoZSBmb2xsb3dpbmcgdG9waWNzIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIFtIb3cgQW1hem9uIFJvdXRlIDUzIERldGVybWluZXMgV2hldGhlciBhbiBFbmRwb2ludCBJcyBIZWFsdGh5XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLWRldGVybWluaW5nLWhlYWx0aC1vZi1lbmRwb2ludHMuaHRtbClcbiAgICAgICAgICogLSBbUm91dGUgNTMgSGVhbHRoIENoZWNrcyBhbmQgRE5TIEZhaWxvdmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLmh0bWwpXG4gICAgICAgICAqIC0gW0NvbmZpZ3VyaW5nIEZhaWxvdmVyIGluIGEgUHJpdmF0ZSBIb3N0ZWQgWm9uZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci1wcml2YXRlLWhvc3RlZC16b25lcy5odG1sKVxuICAgICAgICAgKlxuICAgICAgICAgKiAqV2hlbiB0byBTcGVjaWZ5IEhlYWx0aENoZWNrSWQqXG4gICAgICAgICAqXG4gICAgICAgICAqIFNwZWNpZnlpbmcgYSB2YWx1ZSBmb3IgYEhlYWx0aENoZWNrSWRgIGlzIHVzZWZ1bCBvbmx5IHdoZW4gUm91dGUgNTMgaXMgY2hvb3NpbmcgYmV0d2VlbiB0d28gb3IgbW9yZSByZXNvdXJjZSByZWNvcmQgc2V0cyB0byByZXNwb25kIHRvIGEgRE5TIHF1ZXJ5LCBhbmQgeW91IHdhbnQgUm91dGUgNTMgdG8gYmFzZSB0aGUgY2hvaWNlIGluIHBhcnQgb24gdGhlIHN0YXR1cyBvZiBhIGhlYWx0aCBjaGVjay4gQ29uZmlndXJpbmcgaGVhbHRoIGNoZWNrcyBtYWtlcyBzZW5zZSBvbmx5IGluIHRoZSBmb2xsb3dpbmcgY29uZmlndXJhdGlvbnM6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKk5vbi1hbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0cyogOiBZb3UncmUgY2hlY2tpbmcgdGhlIGhlYWx0aCBvZiBhIGdyb3VwIG9mIG5vbi1hbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgcm91dGluZyBwb2xpY3ksIG5hbWUsIGFuZCB0eXBlIChzdWNoIGFzIG11bHRpcGxlIHdlaWdodGVkIHJlY29yZHMgbmFtZWQgd3d3LmV4YW1wbGUuY29tIHdpdGggYSB0eXBlIG9mIEEpIGFuZCB5b3Ugc3BlY2lmeSBoZWFsdGggY2hlY2sgSURzIGZvciBhbGwgdGhlIHJlc291cmNlIHJlY29yZCBzZXRzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB0aGUgaGVhbHRoIGNoZWNrIHN0YXR1cyBmb3IgYSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIGhlYWx0aHksIFJvdXRlIDUzIGluY2x1ZGVzIHRoZSByZWNvcmQgYW1vbmcgdGhlIHJlY29yZHMgdGhhdCBpdCByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB0aGUgaGVhbHRoIGNoZWNrIHN0YXR1cyBmb3IgYSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgc3RvcHMgcmVzcG9uZGluZyB0byBETlMgcXVlcmllcyB1c2luZyB0aGUgdmFsdWUgZm9yIHRoYXQgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgdGhlIGhlYWx0aCBjaGVjayBzdGF0dXMgZm9yIGFsbCByZXNvdXJjZSByZWNvcmQgc2V0cyBpbiB0aGUgZ3JvdXAgaXMgdW5oZWFsdGh5LCBSb3V0ZSA1MyBjb25zaWRlcnMgYWxsIHJlc291cmNlIHJlY29yZCBzZXRzIGluIHRoZSBncm91cCBoZWFsdGh5IGFuZCByZXNwb25kcyB0byBETlMgcXVlcmllcyBhY2NvcmRpbmdseS5cbiAgICAgICAgICogLSAqQWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMqIDogWW91IHNwZWNpZnkgdGhlIGZvbGxvd2luZyBzZXR0aW5nczpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBZb3Ugc2V0IGBFdmFsdWF0ZVRhcmdldEhlYWx0aGAgdG8gdHJ1ZSBmb3IgYW4gYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldCBpbiBhIGdyb3VwIG9mIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSByb3V0aW5nIHBvbGljeSwgbmFtZSwgYW5kIHR5cGUgKHN1Y2ggYXMgbXVsdGlwbGUgd2VpZ2h0ZWQgcmVjb3JkcyBuYW1lZCB3d3cuZXhhbXBsZS5jb20gd2l0aCBhIHR5cGUgb2YgQSkuXG4gICAgICAgICAqIC0gWW91IGNvbmZpZ3VyZSB0aGUgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldCB0byByb3V0ZSB0cmFmZmljIHRvIGEgbm9uLWFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQgaW4gdGhlIHNhbWUgaG9zdGVkIHpvbmUuXG4gICAgICAgICAqIC0gWW91IHNwZWNpZnkgYSBoZWFsdGggY2hlY2sgSUQgZm9yIHRoZSBub24tYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgdGhlIGhlYWx0aCBjaGVjayBzdGF0dXMgaXMgaGVhbHRoeSwgUm91dGUgNTMgY29uc2lkZXJzIHRoZSBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0IHRvIGJlIGhlYWx0aHkgYW5kIGluY2x1ZGVzIHRoZSBhbGlhcyByZWNvcmQgYW1vbmcgdGhlIHJlY29yZHMgdGhhdCBpdCByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB0aGUgaGVhbHRoIGNoZWNrIHN0YXR1cyBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIHN0b3BzIHJlc3BvbmRpbmcgdG8gRE5TIHF1ZXJpZXMgdXNpbmcgdGhlIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gVGhlIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQgY2FuIGFsc28gcm91dGUgdHJhZmZpYyB0byBhICpncm91cCogb2Ygbm9uLWFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSByb3V0aW5nIHBvbGljeSwgbmFtZSwgYW5kIHR5cGUuIEluIHRoYXQgY29uZmlndXJhdGlvbiwgYXNzb2NpYXRlIGhlYWx0aCBjaGVja3Mgd2l0aCBhbGwgb2YgdGhlIHJlc291cmNlIHJlY29yZCBzZXRzIGluIHRoZSBncm91cCBvZiBub24tYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMuXG4gICAgICAgICAqXG4gICAgICAgICAqICpHZW9sb2NhdGlvbiBSb3V0aW5nKlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMsIGlmIGFuIGVuZHBvaW50IGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgbG9va3MgZm9yIGEgcmVzb3VyY2UgcmVjb3JkIHNldCBmb3IgdGhlIGxhcmdlciwgYXNzb2NpYXRlZCBnZW9ncmFwaGljIHJlZ2lvbi4gRm9yIGV4YW1wbGUsIHN1cHBvc2UgeW91IGhhdmUgcmVzb3VyY2UgcmVjb3JkIHNldHMgZm9yIGEgc3RhdGUgaW4gdGhlIFVuaXRlZCBTdGF0ZXMsIGZvciB0aGUgZW50aXJlIFVuaXRlZCBTdGF0ZXMsIGZvciBOb3J0aCBBbWVyaWNhLCBhbmQgYSByZXNvdXJjZSByZWNvcmQgc2V0IHRoYXQgaGFzIGAqYCBmb3IgYENvdW50cnlDb2RlYCBpcyBgKmAgLCB3aGljaCBhcHBsaWVzIHRvIGFsbCBsb2NhdGlvbnMuIElmIHRoZSBlbmRwb2ludCBmb3IgdGhlIHN0YXRlIHJlc291cmNlIHJlY29yZCBzZXQgaXMgdW5oZWFsdGh5LCBSb3V0ZSA1MyBjaGVja3MgZm9yIGhlYWx0aHkgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gdGhlIGZvbGxvd2luZyBvcmRlciB1bnRpbCBpdCBmaW5kcyBhIHJlc291cmNlIHJlY29yZCBzZXQgZm9yIHdoaWNoIHRoZSBlbmRwb2ludCBpcyBoZWFsdGh5OlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIFRoZSBVbml0ZWQgU3RhdGVzXG4gICAgICAgICAqIC0gTm9ydGggQW1lcmljYVxuICAgICAgICAgKiAtIFRoZSBkZWZhdWx0IHJlc291cmNlIHJlY29yZCBzZXRcbiAgICAgICAgICpcbiAgICAgICAgICogKlNwZWNpZnlpbmcgdGhlIEhlYWx0aCBDaGVjayBFbmRwb2ludCBieSBEb21haW4gTmFtZSpcbiAgICAgICAgICpcbiAgICAgICAgICogSWYgeW91ciBoZWFsdGggY2hlY2tzIHNwZWNpZnkgdGhlIGVuZHBvaW50IG9ubHkgYnkgZG9tYWluIG5hbWUsIHdlIHJlY29tbWVuZCB0aGF0IHlvdSBjcmVhdGUgYSBzZXBhcmF0ZSBoZWFsdGggY2hlY2sgZm9yIGVhY2ggZW5kcG9pbnQuIEZvciBleGFtcGxlLCBjcmVhdGUgYSBoZWFsdGggY2hlY2sgZm9yIGVhY2ggYEhUVFBgIHNlcnZlciB0aGF0IGlzIHNlcnZpbmcgY29udGVudCBmb3IgYHd3dy5leGFtcGxlLmNvbWAgLiBGb3IgdGhlIHZhbHVlIG9mIGBGdWxseVF1YWxpZmllZERvbWFpbk5hbWVgICwgc3BlY2lmeSB0aGUgZG9tYWluIG5hbWUgb2YgdGhlIHNlcnZlciAoc3VjaCBhcyBgdXMtZWFzdC0yLXd3dy5leGFtcGxlLmNvbWAgKSwgbm90IHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0cyAoIGB3d3cuZXhhbXBsZS5jb21gICkuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gSGVhbHRoIGNoZWNrIHJlc3VsdHMgd2lsbCBiZSB1bnByZWRpY3RhYmxlIGlmIHlvdSBkbyB0aGUgZm9sbG93aW5nOlxuICAgICAgICAgKiA+XG4gICAgICAgICAqID4gLSBDcmVhdGUgYSBoZWFsdGggY2hlY2sgdGhhdCBoYXMgdGhlIHNhbWUgdmFsdWUgZm9yIGBGdWxseVF1YWxpZmllZERvbWFpbk5hbWVgIGFzIHRoZSBuYW1lIG9mIGEgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgICAgICogPiAtIEFzc29jaWF0ZSB0aGF0IGhlYWx0aCBjaGVjayB3aXRoIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LWhlYWx0aGNoZWNraWRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGhlYWx0aENoZWNrSWQ/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgSUQgb2YgdGhlIGhvc3RlZCB6b25lIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlIHJlY29yZHMgaW4uXG4gICAgICAgICAqXG4gICAgICAgICAqIFNwZWNpZnkgZWl0aGVyIGBIb3N0ZWRab25lTmFtZWAgb3IgYEhvc3RlZFpvbmVJZGAgLCBidXQgbm90IGJvdGguIElmIHlvdSBoYXZlIG11bHRpcGxlIGhvc3RlZCB6b25lcyB3aXRoIHRoZSBzYW1lIGRvbWFpbiBuYW1lLCB5b3UgbXVzdCBzcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSB1c2luZyBgSG9zdGVkWm9uZUlkYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtaG9zdGVkem9uZWlkXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBob3N0ZWRab25lSWQ/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbmFtZSBvZiB0aGUgaG9zdGVkIHpvbmUgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUgcmVjb3JkcyBpbi4gWW91IG11c3QgaW5jbHVkZSBhIHRyYWlsaW5nIGRvdCAoZm9yIGV4YW1wbGUsIGB3d3cuZXhhbXBsZS5jb20uYCApIGFzIHBhcnQgb2YgdGhlIGBIb3N0ZWRab25lTmFtZWAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBXaGVuIHlvdSBjcmVhdGUgYSBzdGFjayB1c2luZyBhbiBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRgIHRoYXQgc3BlY2lmaWVzIGBIb3N0ZWRab25lTmFtZWAgLCBBV1MgQ2xvdWRGb3JtYXRpb24gYXR0ZW1wdHMgdG8gZmluZCBhIGhvc3RlZCB6b25lIHdob3NlIG5hbWUgbWF0Y2hlcyB0aGUgYEhvc3RlZFpvbmVOYW1lYCAuIElmIEFXUyBDbG91ZEZvcm1hdGlvbiBjYW4ndCBmaW5kIGEgaG9zdGVkIHpvbmUgd2l0aCBhIG1hdGNoaW5nIGRvbWFpbiBuYW1lLCBvciBpZiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIGhvc3RlZCB6b25lIHdpdGggdGhlIHNwZWNpZmllZCBkb21haW4gbmFtZSwgQVdTIENsb3VkRm9ybWF0aW9uIHdpbGwgbm90IGNyZWF0ZSB0aGUgc3RhY2suXG4gICAgICAgICAqXG4gICAgICAgICAqIFNwZWNpZnkgZWl0aGVyIGBIb3N0ZWRab25lTmFtZWAgb3IgYEhvc3RlZFpvbmVJZGAgLCBidXQgbm90IGJvdGguIElmIHlvdSBoYXZlIG11bHRpcGxlIGhvc3RlZCB6b25lcyB3aXRoIHRoZSBzYW1lIGRvbWFpbiBuYW1lLCB5b3UgbXVzdCBzcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSB1c2luZyBgSG9zdGVkWm9uZUlkYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtaG9zdGVkem9uZW5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGhvc3RlZFpvbmVOYW1lPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogKk11bHRpdmFsdWUgYW5zd2VyIHJlc291cmNlIHJlY29yZCBzZXRzIG9ubHkqIDogVG8gcm91dGUgdHJhZmZpYyBhcHByb3hpbWF0ZWx5IHJhbmRvbWx5IHRvIG11bHRpcGxlIHJlc291cmNlcywgc3VjaCBhcyB3ZWIgc2VydmVycywgY3JlYXRlIG9uZSBtdWx0aXZhbHVlIGFuc3dlciByZWNvcmQgZm9yIGVhY2ggcmVzb3VyY2UgYW5kIHNwZWNpZnkgYHRydWVgIGZvciBgTXVsdGlWYWx1ZUFuc3dlcmAgLiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gSWYgeW91IGFzc29jaWF0ZSBhIGhlYWx0aCBjaGVjayB3aXRoIGEgbXVsdGl2YWx1ZSBhbnN3ZXIgcmVzb3VyY2UgcmVjb3JkIHNldCwgQW1hem9uIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgSVAgYWRkcmVzcyBvbmx5IHdoZW4gdGhlIGhlYWx0aCBjaGVjayBpcyBoZWFsdGh5LlxuICAgICAgICAgKiAtIElmIHlvdSBkb24ndCBhc3NvY2lhdGUgYSBoZWFsdGggY2hlY2sgd2l0aCBhIG11bHRpdmFsdWUgYW5zd2VyIHJlY29yZCwgUm91dGUgNTMgYWx3YXlzIGNvbnNpZGVycyB0aGUgcmVjb3JkIHRvIGJlIGhlYWx0aHkuXG4gICAgICAgICAqIC0gUm91dGUgNTMgcmVzcG9uZHMgdG8gRE5TIHF1ZXJpZXMgd2l0aCB1cCB0byBlaWdodCBoZWFsdGh5IHJlY29yZHM7IGlmIHlvdSBoYXZlIGVpZ2h0IG9yIGZld2VyIGhlYWx0aHkgcmVjb3JkcywgUm91dGUgNTMgcmVzcG9uZHMgdG8gYWxsIEROUyBxdWVyaWVzIHdpdGggYWxsIHRoZSBoZWFsdGh5IHJlY29yZHMuXG4gICAgICAgICAqIC0gSWYgeW91IGhhdmUgbW9yZSB0aGFuIGVpZ2h0IGhlYWx0aHkgcmVjb3JkcywgUm91dGUgNTMgcmVzcG9uZHMgdG8gZGlmZmVyZW50IEROUyByZXNvbHZlcnMgd2l0aCBkaWZmZXJlbnQgY29tYmluYXRpb25zIG9mIGhlYWx0aHkgcmVjb3Jkcy5cbiAgICAgICAgICogLSBXaGVuIGFsbCByZWNvcmRzIGFyZSB1bmhlYWx0aHksIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdXAgdG8gZWlnaHQgdW5oZWFsdGh5IHJlY29yZHMuXG4gICAgICAgICAqIC0gSWYgYSByZXNvdXJjZSBiZWNvbWVzIHVuYXZhaWxhYmxlIGFmdGVyIGEgcmVzb2x2ZXIgY2FjaGVzIGEgcmVzcG9uc2UsIGNsaWVudCBzb2Z0d2FyZSB0eXBpY2FsbHkgdHJpZXMgYW5vdGhlciBvZiB0aGUgSVAgYWRkcmVzc2VzIGluIHRoZSByZXNwb25zZS5cbiAgICAgICAgICpcbiAgICAgICAgICogWW91IGNhbid0IGNyZWF0ZSBtdWx0aXZhbHVlIGFuc3dlciBhbGlhcyByZWNvcmRzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LW11bHRpdmFsdWVhbnN3ZXJcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IG11bHRpVmFsdWVBbnN3ZXI/OiBib29sZWFuIHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogRm9yIGBDaGFuZ2VSZXNvdXJjZVJlY29yZFNldHNgIHJlcXVlc3RzLCB0aGUgbmFtZSBvZiB0aGUgcmVjb3JkIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlLCB1cGRhdGUsIG9yIGRlbGV0ZS4gRm9yIGBMaXN0UmVzb3VyY2VSZWNvcmRTZXRzYCByZXNwb25zZXMsIHRoZSBuYW1lIG9mIGEgcmVjb3JkIGluIHRoZSBzcGVjaWZpZWQgaG9zdGVkIHpvbmUuXG4gICAgICAgICAqXG4gICAgICAgICAqICpDaGFuZ2VSZXNvdXJjZVJlY29yZFNldHMgT25seSpcbiAgICAgICAgICpcbiAgICAgICAgICogRW50ZXIgYSBmdWxseSBxdWFsaWZpZWQgZG9tYWluIG5hbWUsIGZvciBleGFtcGxlLCBgd3d3LmV4YW1wbGUuY29tYCAuIFlvdSBjYW4gb3B0aW9uYWxseSBpbmNsdWRlIGEgdHJhaWxpbmcgZG90LiBJZiB5b3Ugb21pdCB0aGUgdHJhaWxpbmcgZG90LCBBbWF6b24gUm91dGUgNTMgYXNzdW1lcyB0aGF0IHRoZSBkb21haW4gbmFtZSB0aGF0IHlvdSBzcGVjaWZ5IGlzIGZ1bGx5IHF1YWxpZmllZC4gVGhpcyBtZWFucyB0aGF0IFJvdXRlIDUzIHRyZWF0cyBgd3d3LmV4YW1wbGUuY29tYCAod2l0aG91dCBhIHRyYWlsaW5nIGRvdCkgYW5kIGB3d3cuZXhhbXBsZS5jb20uYCAod2l0aCBhIHRyYWlsaW5nIGRvdCkgYXMgaWRlbnRpY2FsLlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgaG93IHRvIHNwZWNpZnkgY2hhcmFjdGVycyBvdGhlciB0aGFuIGBhLXpgICwgYDAtOWAgLCBhbmQgYC1gIChoeXBoZW4pIGFuZCBob3cgdG8gc3BlY2lmeSBpbnRlcm5hdGlvbmFsaXplZCBkb21haW4gbmFtZXMsIHNlZSBbRE5TIERvbWFpbiBOYW1lIEZvcm1hdF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL0RvbWFpbk5hbWVGb3JtYXQuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIFlvdSBjYW4gdXNlIHRoZSBhc3RlcmlzayAoKikgd2lsZGNhcmQgdG8gcmVwbGFjZSB0aGUgbGVmdG1vc3QgbGFiZWwgaW4gYSBkb21haW4gbmFtZSwgZm9yIGV4YW1wbGUsIGAqLmV4YW1wbGUuY29tYCAuIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBUaGUgKiBtdXN0IHJlcGxhY2UgdGhlIGVudGlyZSBsYWJlbC4gRm9yIGV4YW1wbGUsIHlvdSBjYW4ndCBzcGVjaWZ5IGAqcHJvZC5leGFtcGxlLmNvbWAgb3IgYHByb2QqLmV4YW1wbGUuY29tYCAuXG4gICAgICAgICAqIC0gVGhlICogY2FuJ3QgcmVwbGFjZSBhbnkgb2YgdGhlIG1pZGRsZSBsYWJlbHMsIGZvciBleGFtcGxlLCBtYXJrZXRpbmcuKi5leGFtcGxlLmNvbS5cbiAgICAgICAgICogLSBJZiB5b3UgaW5jbHVkZSAqIGluIGFueSBwb3NpdGlvbiBvdGhlciB0aGFuIHRoZSBsZWZ0bW9zdCBsYWJlbCBpbiBhIGRvbWFpbiBuYW1lLCBETlMgdHJlYXRzIGl0IGFzIGFuICogY2hhcmFjdGVyIChBU0NJSSA0MiksIG5vdCBhcyBhIHdpbGRjYXJkLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFlvdSBjYW4ndCB1c2UgdGhlICogd2lsZGNhcmQgZm9yIHJlc291cmNlIHJlY29yZHMgc2V0cyB0aGF0IGhhdmUgYSB0eXBlIG9mIE5TLlxuICAgICAgICAgKlxuICAgICAgICAgKiBZb3UgY2FuIHVzZSB0aGUgKiB3aWxkY2FyZCBhcyB0aGUgbGVmdG1vc3QgbGFiZWwgaW4gYSBkb21haW4gbmFtZSwgZm9yIGV4YW1wbGUsIGAqLmV4YW1wbGUuY29tYCAuIFlvdSBjYW4ndCB1c2UgYW4gKiBmb3Igb25lIG9mIHRoZSBtaWRkbGUgbGFiZWxzLCBmb3IgZXhhbXBsZSwgYG1hcmtldGluZy4qLmV4YW1wbGUuY29tYCAuIEluIGFkZGl0aW9uLCB0aGUgKiBtdXN0IHJlcGxhY2UgdGhlIGVudGlyZSBsYWJlbDsgZm9yIGV4YW1wbGUsIHlvdSBjYW4ndCBzcGVjaWZ5IGBwcm9kKi5leGFtcGxlLmNvbWAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LW5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqICpMYXRlbmN5LWJhc2VkIHJlc291cmNlIHJlY29yZCBzZXRzIG9ubHk6KiBUaGUgQW1hem9uIEVDMiBSZWdpb24gd2hlcmUgeW91IGNyZWF0ZWQgdGhlIHJlc291cmNlIHRoYXQgdGhpcyByZXNvdXJjZSByZWNvcmQgc2V0IHJlZmVycyB0by4gVGhlIHJlc291cmNlIHR5cGljYWxseSBpcyBhbiBBV1MgcmVzb3VyY2UsIHN1Y2ggYXMgYW4gRUMyIGluc3RhbmNlIG9yIGFuIEVMQiBsb2FkIGJhbGFuY2VyLCBhbmQgaXMgcmVmZXJyZWQgdG8gYnkgYW4gSVAgYWRkcmVzcyBvciBhIEROUyBkb21haW4gbmFtZSwgZGVwZW5kaW5nIG9uIHRoZSByZWNvcmQgdHlwZS5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBBbHRob3VnaCBjcmVhdGluZyBsYXRlbmN5IGFuZCBsYXRlbmN5IGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzIGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSBpcyBhbGxvd2VkLCBpdCdzIG5vdCBzdXBwb3J0ZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIFdoZW4gQW1hem9uIFJvdXRlIDUzIHJlY2VpdmVzIGEgRE5TIHF1ZXJ5IGZvciBhIGRvbWFpbiBuYW1lIGFuZCB0eXBlIGZvciB3aGljaCB5b3UgaGF2ZSBjcmVhdGVkIGxhdGVuY3kgcmVzb3VyY2UgcmVjb3JkIHNldHMsIFJvdXRlIDUzIHNlbGVjdHMgdGhlIGxhdGVuY3kgcmVzb3VyY2UgcmVjb3JkIHNldCB0aGF0IGhhcyB0aGUgbG93ZXN0IGxhdGVuY3kgYmV0d2VlbiB0aGUgZW5kIHVzZXIgYW5kIHRoZSBhc3NvY2lhdGVkIEFtYXpvbiBFQzIgUmVnaW9uLiBSb3V0ZSA1MyB0aGVuIHJldHVybnMgdGhlIHZhbHVlIHRoYXQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBzZWxlY3RlZCByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAgICAgKlxuICAgICAgICAgKiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gWW91IGNhbiBvbmx5IHNwZWNpZnkgb25lIGBSZXNvdXJjZVJlY29yZGAgcGVyIGxhdGVuY3kgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgICAgICogLSBZb3UgY2FuIG9ubHkgY3JlYXRlIG9uZSBsYXRlbmN5IHJlc291cmNlIHJlY29yZCBzZXQgZm9yIGVhY2ggQW1hem9uIEVDMiBSZWdpb24uXG4gICAgICAgICAqIC0gWW91IGFyZW4ndCByZXF1aXJlZCB0byBjcmVhdGUgbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0cyBmb3IgYWxsIEFtYXpvbiBFQzIgUmVnaW9ucy4gUm91dGUgNTMgd2lsbCBjaG9vc2UgdGhlIHJlZ2lvbiB3aXRoIHRoZSBiZXN0IGxhdGVuY3kgZnJvbSBhbW9uZyB0aGUgcmVnaW9ucyB0aGF0IHlvdSBjcmVhdGUgbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0cyBmb3IuXG4gICAgICAgICAqIC0gWW91IGNhbid0IGNyZWF0ZSBub24tbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgdmFsdWVzIGZvciB0aGUgYE5hbWVgIGFuZCBgVHlwZWAgZWxlbWVudHMgYXMgbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0cy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1yZWdpb25cbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHJlZ2lvbj86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluZm9ybWF0aW9uIGFib3V0IHRoZSByZWNvcmRzIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlLiBFYWNoIHJlY29yZCBzaG91bGQgYmUgaW4gdGhlIGZvcm1hdCBhcHByb3ByaWF0ZSBmb3IgdGhlIHJlY29yZCB0eXBlIHNwZWNpZmllZCBieSB0aGUgYFR5cGVgIHByb3BlcnR5LiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgZGlmZmVyZW50IHJlY29yZCB0eXBlcyBhbmQgdGhlaXIgcmVjb3JkIGZvcm1hdHMsIHNlZSBbVmFsdWVzIFRoYXQgWW91IFNwZWNpZnkgV2hlbiBZb3UgQ3JlYXRlIG9yIEVkaXQgQW1hem9uIFJvdXRlIDUzIFJlY29yZHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9yZXNvdXJjZS1yZWNvcmQtc2V0cy12YWx1ZXMuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtcmVzb3VyY2VyZWNvcmRzXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSByZXNvdXJjZVJlY29yZHM/OiBzdHJpbmdbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqICpSZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgYSByb3V0aW5nIHBvbGljeSBvdGhlciB0aGFuIHNpbXBsZToqIEFuIGlkZW50aWZpZXIgdGhhdCBkaWZmZXJlbnRpYXRlcyBhbW9uZyBtdWx0aXBsZSByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgY29tYmluYXRpb24gb2YgbmFtZSBhbmQgdHlwZSwgc3VjaCBhcyBtdWx0aXBsZSB3ZWlnaHRlZCByZXNvdXJjZSByZWNvcmQgc2V0cyBuYW1lZCBhY21lLmV4YW1wbGUuY29tIHRoYXQgaGF2ZSBhIHR5cGUgb2YgQS4gSW4gYSBncm91cCBvZiByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgbmFtZSBhbmQgdHlwZSwgdGhlIHZhbHVlIG9mIGBTZXRJZGVudGlmaWVyYCBtdXN0IGJlIHVuaXF1ZSBmb3IgZWFjaCByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgcm91dGluZyBwb2xpY2llcywgc2VlIFtDaG9vc2luZyBhIFJvdXRpbmcgUG9saWN5XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvcm91dGluZy1wb2xpY3kuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtc2V0aWRlbnRpZmllclxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgc2V0SWRlbnRpZmllcj86IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSByZXNvdXJjZSByZWNvcmQgY2FjaGUgdGltZSB0byBsaXZlIChUVEwpLCBpbiBzZWNvbmRzLiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gSWYgeW91J3JlIGNyZWF0aW5nIG9yIHVwZGF0aW5nIGFuIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQsIG9taXQgYFRUTGAgLiBBbWF6b24gUm91dGUgNTMgdXNlcyB0aGUgdmFsdWUgb2YgYFRUTGAgZm9yIHRoZSBhbGlhcyB0YXJnZXQuXG4gICAgICAgICAqIC0gSWYgeW91J3JlIGFzc29jaWF0aW5nIHRoaXMgcmVzb3VyY2UgcmVjb3JkIHNldCB3aXRoIGEgaGVhbHRoIGNoZWNrIChpZiB5b3UncmUgYWRkaW5nIGEgYEhlYWx0aENoZWNrSWRgIGVsZW1lbnQpLCB3ZSByZWNvbW1lbmQgdGhhdCB5b3Ugc3BlY2lmeSBhIGBUVExgIG9mIDYwIHNlY29uZHMgb3IgbGVzcyBzbyBjbGllbnRzIHJlc3BvbmQgcXVpY2tseSB0byBjaGFuZ2VzIGluIGhlYWx0aCBzdGF0dXMuXG4gICAgICAgICAqIC0gQWxsIG9mIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0cyBpbiBhIGdyb3VwIG9mIHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXRzIG11c3QgaGF2ZSB0aGUgc2FtZSB2YWx1ZSBmb3IgYFRUTGAgLlxuICAgICAgICAgKiAtIElmIGEgZ3JvdXAgb2Ygd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW5jbHVkZXMgb25lIG9yIG1vcmUgd2VpZ2h0ZWQgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMgZm9yIHdoaWNoIHRoZSBhbGlhcyB0YXJnZXQgaXMgYW4gRUxCIGxvYWQgYmFsYW5jZXIsIHdlIHJlY29tbWVuZCB0aGF0IHlvdSBzcGVjaWZ5IGEgYFRUTGAgb2YgNjAgc2Vjb25kcyBmb3IgYWxsIG9mIHRoZSBub24tYWxpYXMgd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIG5hbWUgYW5kIHR5cGUuIFZhbHVlcyBvdGhlciB0aGFuIDYwIHNlY29uZHMgKHRoZSBUVEwgZm9yIGxvYWQgYmFsYW5jZXJzKSB3aWxsIGNoYW5nZSB0aGUgZWZmZWN0IG9mIHRoZSB2YWx1ZXMgdGhhdCB5b3Ugc3BlY2lmeSBmb3IgYFdlaWdodGAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LXR0bFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgdHRsPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIEROUyByZWNvcmQgdHlwZS4gRm9yIGluZm9ybWF0aW9uIGFib3V0IGRpZmZlcmVudCByZWNvcmQgdHlwZXMgYW5kIGhvdyBkYXRhIGlzIGVuY29kZWQgZm9yIHRoZW0sIHNlZSBbU3VwcG9ydGVkIEROUyBSZXNvdXJjZSBSZWNvcmQgVHlwZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9SZXNvdXJjZVJlY29yZFR5cGVzLmh0bWwpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiBWYWxpZCB2YWx1ZXMgZm9yIGJhc2ljIHJlc291cmNlIHJlY29yZCBzZXRzOiBgQWAgfCBgQUFBQWAgfCBgQ0FBYCB8IGBDTkFNRWAgfCBgRFNgIHwgYE1YYCB8IGBOQVBUUmAgfCBgTlNgIHwgYFBUUmAgfCBgU09BYCB8IGBTUEZgIHwgYFNSVmAgfCBgVFhUYFxuICAgICAgICAgKlxuICAgICAgICAgKiBWYWx1ZXMgZm9yIHdlaWdodGVkLCBsYXRlbmN5LCBnZW9sb2NhdGlvbiwgYW5kIGZhaWxvdmVyIHJlc291cmNlIHJlY29yZCBzZXRzOiBgQWAgfCBgQUFBQWAgfCBgQ0FBYCB8IGBDTkFNRWAgfCBgTVhgIHwgYE5BUFRSYCB8IGBQVFJgIHwgYFNQRmAgfCBgU1JWYCB8IGBUWFRgIC4gV2hlbiBjcmVhdGluZyBhIGdyb3VwIG9mIHdlaWdodGVkLCBsYXRlbmN5LCBnZW9sb2NhdGlvbiwgb3IgZmFpbG92ZXIgcmVzb3VyY2UgcmVjb3JkIHNldHMsIHNwZWNpZnkgdGhlIHNhbWUgdmFsdWUgZm9yIGFsbCBvZiB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gdGhlIGdyb3VwLlxuICAgICAgICAgKlxuICAgICAgICAgKiBWYWxpZCB2YWx1ZXMgZm9yIG11bHRpdmFsdWUgYW5zd2VyIHJlc291cmNlIHJlY29yZCBzZXRzOiBgQWAgfCBgQUFBQWAgfCBgTVhgIHwgYE5BUFRSYCB8IGBQVFJgIHwgYFNQRmAgfCBgU1JWYCB8IGBUWFRgXG4gICAgICAgICAqXG4gICAgICAgICAqID4gU1BGIHJlY29yZHMgd2VyZSBmb3JtZXJseSB1c2VkIHRvIHZlcmlmeSB0aGUgaWRlbnRpdHkgb2YgdGhlIHNlbmRlciBvZiBlbWFpbCBtZXNzYWdlcy4gSG93ZXZlciwgd2Ugbm8gbG9uZ2VyIHJlY29tbWVuZCB0aGF0IHlvdSBjcmVhdGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgZm9yIHdoaWNoIHRoZSB2YWx1ZSBvZiBgVHlwZWAgaXMgYFNQRmAgLiBSRkMgNzIwOCwgKlNlbmRlciBQb2xpY3kgRnJhbWV3b3JrIChTUEYpIGZvciBBdXRob3JpemluZyBVc2Ugb2YgRG9tYWlucyBpbiBFbWFpbCwgVmVyc2lvbiAxKiAsIGhhcyBiZWVuIHVwZGF0ZWQgdG8gc2F5LCBcIi4uLltJXXRzIGV4aXN0ZW5jZSBhbmQgbWVjaGFuaXNtIGRlZmluZWQgaW4gW1JGQzQ0MDhdIGhhdmUgbGVkIHRvIHNvbWUgaW50ZXJvcGVyYWJpbGl0eSBpc3N1ZXMuIEFjY29yZGluZ2x5LCBpdHMgdXNlIGlzIG5vIGxvbmdlciBhcHByb3ByaWF0ZSBmb3IgU1BGIHZlcnNpb24gMTsgaW1wbGVtZW50YXRpb25zIGFyZSBub3QgdG8gdXNlIGl0LlwiIEluIFJGQyA3MjA4LCBzZWUgc2VjdGlvbiAxNC4xLCBbVGhlIFNQRiBETlMgUmVjb3JkIFR5cGVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM3MjA4I3NlY3Rpb24tMTQuMSkgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBWYWx1ZXMgZm9yIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICpBbWF6b24gQVBJIEdhdGV3YXkgY3VzdG9tIHJlZ2lvbmFsIEFQSXMgYW5kIGVkZ2Utb3B0aW1pemVkIEFQSXM6KiBgQWBcbiAgICAgICAgICogLSAqQ2xvdWRGcm9udCBkaXN0cmlidXRpb25zOiogYEFgXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIElQdjYgaXMgZW5hYmxlZCBmb3IgdGhlIGRpc3RyaWJ1dGlvbiwgY3JlYXRlIHR3byByZXNvdXJjZSByZWNvcmQgc2V0cyB0byByb3V0ZSB0cmFmZmljIHRvIHlvdXIgZGlzdHJpYnV0aW9uLCBvbmUgd2l0aCBhIHZhbHVlIG9mIGBBYCBhbmQgb25lIHdpdGggYSB2YWx1ZSBvZiBgQUFBQWAgLlxuICAgICAgICAgKiAtICpBbWF6b24gQVBJIEdhdGV3YXkgZW52aXJvbm1lbnQgdGhhdCBoYXMgYSByZWdpb25hbGl6ZWQgc3ViZG9tYWluKiA6IGBBYFxuICAgICAgICAgKiAtICpFTEIgbG9hZCBiYWxhbmNlcnM6KiBgQWAgfCBgQUFBQWBcbiAgICAgICAgICogLSAqQW1hem9uIFMzIGJ1Y2tldHM6KiBgQWBcbiAgICAgICAgICogLSAqQW1hem9uIFZpcnR1YWwgUHJpdmF0ZSBDbG91ZCBpbnRlcmZhY2UgVlBDIGVuZHBvaW50cyogYEFgXG4gICAgICAgICAqIC0gKkFub3RoZXIgcmVzb3VyY2UgcmVjb3JkIHNldCBpbiB0aGlzIGhvc3RlZCB6b25lOiogU3BlY2lmeSB0aGUgdHlwZSBvZiB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldCB0aGF0IHlvdSdyZSBjcmVhdGluZyB0aGUgYWxpYXMgZm9yLiBBbGwgdmFsdWVzIGFyZSBzdXBwb3J0ZWQgZXhjZXB0IGBOU2AgYW5kIGBTT0FgIC5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBJZiB5b3UncmUgY3JlYXRpbmcgYW4gYWxpYXMgcmVjb3JkIHRoYXQgaGFzIHRoZSBzYW1lIG5hbWUgYXMgdGhlIGhvc3RlZCB6b25lIChrbm93biBhcyB0aGUgem9uZSBhcGV4KSwgeW91IGNhbid0IHJvdXRlIHRyYWZmaWMgdG8gYSByZWNvcmQgZm9yIHdoaWNoIHRoZSB2YWx1ZSBvZiBgVHlwZWAgaXMgYENOQU1FYCAuIFRoaXMgaXMgYmVjYXVzZSB0aGUgYWxpYXMgcmVjb3JkIG11c3QgaGF2ZSB0aGUgc2FtZSB0eXBlIGFzIHRoZSByZWNvcmQgeW91J3JlIHJvdXRpbmcgdHJhZmZpYyB0bywgYW5kIGNyZWF0aW5nIGEgQ05BTUUgcmVjb3JkIGZvciB0aGUgem9uZSBhcGV4IGlzbid0IHN1cHBvcnRlZCBldmVuIGZvciBhbiBhbGlhcyByZWNvcmQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtdHlwZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgdHlwZTogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogKldlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXRzIG9ubHk6KiBBbW9uZyByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgY29tYmluYXRpb24gb2YgRE5TIG5hbWUgYW5kIHR5cGUsIGEgdmFsdWUgdGhhdCBkZXRlcm1pbmVzIHRoZSBwcm9wb3J0aW9uIG9mIEROUyBxdWVyaWVzIHRoYXQgQW1hem9uIFJvdXRlIDUzIHJlc3BvbmRzIHRvIHVzaW5nIHRoZSBjdXJyZW50IHJlc291cmNlIHJlY29yZCBzZXQuIFJvdXRlIDUzIGNhbGN1bGF0ZXMgdGhlIHN1bSBvZiB0aGUgd2VpZ2h0cyBmb3IgdGhlIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSBjb21iaW5hdGlvbiBvZiBETlMgbmFtZSBhbmQgdHlwZS4gUm91dGUgNTMgdGhlbiByZXNwb25kcyB0byBxdWVyaWVzIGJhc2VkIG9uIHRoZSByYXRpbyBvZiBhIHJlc291cmNlJ3Mgd2VpZ2h0IHRvIHRoZSB0b3RhbC4gTm90ZSB0aGUgZm9sbG93aW5nOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIFlvdSBtdXN0IHNwZWNpZnkgYSB2YWx1ZSBmb3IgdGhlIGBXZWlnaHRgIGVsZW1lbnQgZm9yIGV2ZXJ5IHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICAgICAqIC0gWW91IGNhbiBvbmx5IHNwZWNpZnkgb25lIGBSZXNvdXJjZVJlY29yZGAgcGVyIHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICAgICAqIC0gWW91IGNhbid0IGNyZWF0ZSBsYXRlbmN5LCBmYWlsb3Zlciwgb3IgZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIHZhbHVlcyBmb3IgdGhlIGBOYW1lYCBhbmQgYFR5cGVgIGVsZW1lbnRzIGFzIHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXRzLlxuICAgICAgICAgKiAtIFlvdSBjYW4gY3JlYXRlIGEgbWF4aW11bSBvZiAxMDAgd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIHZhbHVlcyBmb3IgdGhlIGBOYW1lYCBhbmQgYFR5cGVgIGVsZW1lbnRzLlxuICAgICAgICAgKiAtIEZvciB3ZWlnaHRlZCAoYnV0IG5vdCB3ZWlnaHRlZCBhbGlhcykgcmVzb3VyY2UgcmVjb3JkIHNldHMsIGlmIHlvdSBzZXQgYFdlaWdodGAgdG8gYDBgIGZvciBhIHJlc291cmNlIHJlY29yZCBzZXQsIFJvdXRlIDUzIG5ldmVyIHJlc3BvbmRzIHRvIHF1ZXJpZXMgd2l0aCB0aGUgYXBwbGljYWJsZSB2YWx1ZSBmb3IgdGhhdCByZXNvdXJjZSByZWNvcmQgc2V0LiBIb3dldmVyLCBpZiB5b3Ugc2V0IGBXZWlnaHRgIHRvIGAwYCBmb3IgYWxsIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSBjb21iaW5hdGlvbiBvZiBETlMgbmFtZSBhbmQgdHlwZSwgdHJhZmZpYyBpcyByb3V0ZWQgdG8gYWxsIHJlc291cmNlcyB3aXRoIGVxdWFsIHByb2JhYmlsaXR5LlxuICAgICAgICAgKlxuICAgICAgICAgKiBUaGUgZWZmZWN0IG9mIHNldHRpbmcgYFdlaWdodGAgdG8gYDBgIGlzIGRpZmZlcmVudCB3aGVuIHlvdSBhc3NvY2lhdGUgaGVhbHRoIGNoZWNrcyB3aXRoIHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXRzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtPcHRpb25zIGZvciBDb25maWd1cmluZyBSb3V0ZSA1MyBBY3RpdmUtQWN0aXZlIGFuZCBBY3RpdmUtUGFzc2l2ZSBGYWlsb3Zlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci1jb25maWd1cmluZy1vcHRpb25zLmh0bWwpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LXdlaWdodFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgd2VpZ2h0PzogbnVtYmVyO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBSZWNvcmRTZXRQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgUmVjb3JkU2V0UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuUmVjb3JkU2V0R3JvdXBfUmVjb3JkU2V0UHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdhbGlhc1RhcmdldCcsIENmblJlY29yZFNldEdyb3VwX0FsaWFzVGFyZ2V0UHJvcGVydHlWYWxpZGF0b3IpKHByb3BlcnRpZXMuYWxpYXNUYXJnZXQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2ZhaWxvdmVyJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmZhaWxvdmVyKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdnZW9Mb2NhdGlvbicsIENmblJlY29yZFNldEdyb3VwX0dlb0xvY2F0aW9uUHJvcGVydHlWYWxpZGF0b3IpKHByb3BlcnRpZXMuZ2VvTG9jYXRpb24pKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hlYWx0aENoZWNrSWQnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuaGVhbHRoQ2hlY2tJZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaG9zdGVkWm9uZUlkJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmhvc3RlZFpvbmVJZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaG9zdGVkWm9uZU5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuaG9zdGVkWm9uZU5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ211bHRpVmFsdWVBbnN3ZXInLCBjZGsudmFsaWRhdGVCb29sZWFuKShwcm9wZXJ0aWVzLm11bHRpVmFsdWVBbnN3ZXIpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ25hbWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMubmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5uYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyZWdpb24nLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucmVnaW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyZXNvdXJjZVJlY29yZHMnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLnJlc291cmNlUmVjb3JkcykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc2V0SWRlbnRpZmllcicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5zZXRJZGVudGlmaWVyKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0dGwnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMudHRsKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0eXBlJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnR5cGUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3R5cGUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMudHlwZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignd2VpZ2h0JywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLndlaWdodCkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJSZWNvcmRTZXRQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0R3JvdXAuUmVjb3JkU2V0YCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBSZWNvcmRTZXRQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0R3JvdXAuUmVjb3JkU2V0YCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblJlY29yZFNldEdyb3VwUmVjb3JkU2V0UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblJlY29yZFNldEdyb3VwX1JlY29yZFNldFByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBBbGlhc1RhcmdldDogY2ZuUmVjb3JkU2V0R3JvdXBBbGlhc1RhcmdldFByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmFsaWFzVGFyZ2V0KSxcbiAgICAgICAgRmFpbG92ZXI6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZmFpbG92ZXIpLFxuICAgICAgICBHZW9Mb2NhdGlvbjogY2ZuUmVjb3JkU2V0R3JvdXBHZW9Mb2NhdGlvblByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmdlb0xvY2F0aW9uKSxcbiAgICAgICAgSGVhbHRoQ2hlY2tJZDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5oZWFsdGhDaGVja0lkKSxcbiAgICAgICAgSG9zdGVkWm9uZUlkOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmhvc3RlZFpvbmVJZCksXG4gICAgICAgIEhvc3RlZFpvbmVOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmhvc3RlZFpvbmVOYW1lKSxcbiAgICAgICAgTXVsdGlWYWx1ZUFuc3dlcjogY2RrLmJvb2xlYW5Ub0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubXVsdGlWYWx1ZUFuc3dlciksXG4gICAgICAgIE5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubmFtZSksXG4gICAgICAgIFJlZ2lvbjogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5yZWdpb24pLFxuICAgICAgICBSZXNvdXJjZVJlY29yZHM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnJlc291cmNlUmVjb3JkcyksXG4gICAgICAgIFNldElkZW50aWZpZXI6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuc2V0SWRlbnRpZmllciksXG4gICAgICAgIFRUTDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy50dGwpLFxuICAgICAgICBUeXBlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnR5cGUpLFxuICAgICAgICBXZWlnaHQ6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMud2VpZ2h0KSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuUmVjb3JkU2V0R3JvdXBSZWNvcmRTZXRQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblJlY29yZFNldEdyb3VwLlJlY29yZFNldFByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblJlY29yZFNldEdyb3VwLlJlY29yZFNldFByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnYWxpYXNUYXJnZXQnLCAnQWxpYXNUYXJnZXQnLCBwcm9wZXJ0aWVzLkFsaWFzVGFyZ2V0ICE9IG51bGwgPyBDZm5SZWNvcmRTZXRHcm91cEFsaWFzVGFyZ2V0UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5BbGlhc1RhcmdldCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZmFpbG92ZXInLCAnRmFpbG92ZXInLCBwcm9wZXJ0aWVzLkZhaWxvdmVyICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkZhaWxvdmVyKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdnZW9Mb2NhdGlvbicsICdHZW9Mb2NhdGlvbicsIHByb3BlcnRpZXMuR2VvTG9jYXRpb24gIT0gbnVsbCA/IENmblJlY29yZFNldEdyb3VwR2VvTG9jYXRpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLkdlb0xvY2F0aW9uKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdoZWFsdGhDaGVja0lkJywgJ0hlYWx0aENoZWNrSWQnLCBwcm9wZXJ0aWVzLkhlYWx0aENoZWNrSWQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuSGVhbHRoQ2hlY2tJZCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaG9zdGVkWm9uZUlkJywgJ0hvc3RlZFpvbmVJZCcsIHByb3BlcnRpZXMuSG9zdGVkWm9uZUlkICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkhvc3RlZFpvbmVJZCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaG9zdGVkWm9uZU5hbWUnLCAnSG9zdGVkWm9uZU5hbWUnLCBwcm9wZXJ0aWVzLkhvc3RlZFpvbmVOYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkhvc3RlZFpvbmVOYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdtdWx0aVZhbHVlQW5zd2VyJywgJ011bHRpVmFsdWVBbnN3ZXInLCBwcm9wZXJ0aWVzLk11bHRpVmFsdWVBbnN3ZXIgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Qm9vbGVhbihwcm9wZXJ0aWVzLk11bHRpVmFsdWVBbnN3ZXIpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ25hbWUnLCAnTmFtZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuTmFtZSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncmVnaW9uJywgJ1JlZ2lvbicsIHByb3BlcnRpZXMuUmVnaW9uICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlJlZ2lvbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncmVzb3VyY2VSZWNvcmRzJywgJ1Jlc291cmNlUmVjb3JkcycsIHByb3BlcnRpZXMuUmVzb3VyY2VSZWNvcmRzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuUmVzb3VyY2VSZWNvcmRzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzZXRJZGVudGlmaWVyJywgJ1NldElkZW50aWZpZXInLCBwcm9wZXJ0aWVzLlNldElkZW50aWZpZXIgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuU2V0SWRlbnRpZmllcikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndHRsJywgJ1RUTCcsIHByb3BlcnRpZXMuVFRMICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlRUTCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndHlwZScsICdUeXBlJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5UeXBlKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd3ZWlnaHQnLCAnV2VpZ2h0JywgcHJvcGVydGllcy5XZWlnaHQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuV2VpZ2h0KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG4iXX0=
\No newline at end of file