UNPKG

213 kBJavaScriptView Raw
1"use strict";
2var _a, _b, _c, _d, _e, _f, _g;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.CfnSubscriptionFilter = exports.CfnResourcePolicy = exports.CfnQueryDefinition = exports.CfnMetricFilter = exports.CfnLogStream = exports.CfnLogGroup = exports.CfnDestination = void 0;
5const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
6const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
7// Copyright 2012-2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
8// Generated from the AWS CloudFormation Resource Specification
9// See: docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html
10// @cfn2ts:meta@ {"generated":"2023-06-19T15:14:53.111Z","fingerprint":"llnG/qlR+NiSCttCc1xKsjVrffuZQp0ajLLbXy2+BOo="}
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 `CfnDestinationProps`
16 *
17 * @param properties - the TypeScript properties of a `CfnDestinationProps`
18 *
19 * @returns the result of the validation.
20 */
21function CfnDestinationPropsValidator(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('destinationName', cdk.requiredValidator)(properties.destinationName));
30 errors.collect(cdk.propertyValidator('destinationName', cdk.validateString)(properties.destinationName));
31 errors.collect(cdk.propertyValidator('destinationPolicy', cdk.validateString)(properties.destinationPolicy));
32 errors.collect(cdk.propertyValidator('roleArn', cdk.requiredValidator)(properties.roleArn));
33 errors.collect(cdk.propertyValidator('roleArn', cdk.validateString)(properties.roleArn));
34 errors.collect(cdk.propertyValidator('targetArn', cdk.requiredValidator)(properties.targetArn));
35 errors.collect(cdk.propertyValidator('targetArn', cdk.validateString)(properties.targetArn));
36 return errors.wrap('supplied properties not correct for "CfnDestinationProps"');
37}
38/**
39 * Renders the AWS CloudFormation properties of an `AWS::Logs::Destination` resource
40 *
41 * @param properties - the TypeScript properties of a `CfnDestinationProps`
42 *
43 * @returns the AWS CloudFormation properties of an `AWS::Logs::Destination` resource.
44 */
45// @ts-ignore TS6133
46function cfnDestinationPropsToCloudFormation(properties) {
47 if (!cdk.canInspect(properties)) {
48 return properties;
49 }
50 CfnDestinationPropsValidator(properties).assertSuccess();
51 return {
52 DestinationName: cdk.stringToCloudFormation(properties.destinationName),
53 RoleArn: cdk.stringToCloudFormation(properties.roleArn),
54 TargetArn: cdk.stringToCloudFormation(properties.targetArn),
55 DestinationPolicy: cdk.stringToCloudFormation(properties.destinationPolicy),
56 };
57}
58// @ts-ignore TS6133
59function CfnDestinationPropsFromCloudFormation(properties) {
60 properties = properties == null ? {} : properties;
61 if (typeof properties !== 'object') {
62 return new cfn_parse.FromCloudFormationResult(properties);
63 }
64 const ret = new cfn_parse.FromCloudFormationPropertyObject();
65 ret.addPropertyResult('destinationName', 'DestinationName', cfn_parse.FromCloudFormation.getString(properties.DestinationName));
66 ret.addPropertyResult('roleArn', 'RoleArn', cfn_parse.FromCloudFormation.getString(properties.RoleArn));
67 ret.addPropertyResult('targetArn', 'TargetArn', cfn_parse.FromCloudFormation.getString(properties.TargetArn));
68 ret.addPropertyResult('destinationPolicy', 'DestinationPolicy', properties.DestinationPolicy != null ? cfn_parse.FromCloudFormation.getString(properties.DestinationPolicy) : undefined);
69 ret.addUnrecognizedPropertiesAsExtra(properties);
70 return ret;
71}
72/**
73 * A CloudFormation `AWS::Logs::Destination`
74 *
75 * The AWS::Logs::Destination resource specifies a CloudWatch Logs destination. A destination encapsulates a physical resource (such as an Amazon Kinesis data stream) and enables you to subscribe that resource to a stream of log events.
76 *
77 * @cloudformationResource AWS::Logs::Destination
78 * @stability external
79 *
80 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-destination.html
81 */
82class CfnDestination extends cdk.CfnResource {
83 /**
84 * Create a new `AWS::Logs::Destination`.
85 *
86 * @param scope - scope in which this resource is defined
87 * @param id - scoped id of the resource
88 * @param props - resource properties
89 */
90 constructor(scope, id, props) {
91 super(scope, id, { type: CfnDestination.CFN_RESOURCE_TYPE_NAME, properties: props });
92 try {
93 jsiiDeprecationWarnings._aws_cdk_aws_logs_CfnDestinationProps(props);
94 }
95 catch (error) {
96 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
97 Error.captureStackTrace(error, CfnDestination);
98 }
99 throw error;
100 }
101 cdk.requireProperty(props, 'destinationName', this);
102 cdk.requireProperty(props, 'roleArn', this);
103 cdk.requireProperty(props, 'targetArn', this);
104 this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
105 this.destinationName = props.destinationName;
106 this.roleArn = props.roleArn;
107 this.targetArn = props.targetArn;
108 this.destinationPolicy = props.destinationPolicy;
109 }
110 /**
111 * A factory method that creates a new instance of this class from an object
112 * containing the CloudFormation properties of this resource.
113 * Used in the @aws-cdk/cloudformation-include module.
114 *
115 * @internal
116 */
117 static _fromCloudFormation(scope, id, resourceAttributes, options) {
118 resourceAttributes = resourceAttributes || {};
119 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
120 const propsResult = CfnDestinationPropsFromCloudFormation(resourceProperties);
121 const ret = new CfnDestination(scope, id, propsResult.value);
122 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
123 ret.addPropertyOverride(propKey, propVal);
124 }
125 options.parser.handleAttributes(ret, resourceAttributes, id);
126 return ret;
127 }
128 /**
129 * Examines the CloudFormation resource and discloses attributes.
130 *
131 * @param inspector - tree inspector to collect and process attributes
132 *
133 */
134 inspect(inspector) {
135 inspector.addAttribute("aws:cdk:cloudformation:type", CfnDestination.CFN_RESOURCE_TYPE_NAME);
136 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
137 }
138 get cfnProperties() {
139 return {
140 destinationName: this.destinationName,
141 roleArn: this.roleArn,
142 targetArn: this.targetArn,
143 destinationPolicy: this.destinationPolicy,
144 };
145 }
146 renderProperties(props) {
147 return cfnDestinationPropsToCloudFormation(props);
148 }
149}
150exports.CfnDestination = CfnDestination;
151_a = JSII_RTTI_SYMBOL_1;
152CfnDestination[_a] = { fqn: "@aws-cdk/aws-logs.CfnDestination", version: "1.204.0" };
153/**
154 * The CloudFormation resource type name for this resource class.
155 */
156CfnDestination.CFN_RESOURCE_TYPE_NAME = "AWS::Logs::Destination";
157/**
158 * Determine whether the given properties match those of a `CfnLogGroupProps`
159 *
160 * @param properties - the TypeScript properties of a `CfnLogGroupProps`
161 *
162 * @returns the result of the validation.
163 */
164function CfnLogGroupPropsValidator(properties) {
165 if (!cdk.canInspect(properties)) {
166 return cdk.VALIDATION_SUCCESS;
167 }
168 const errors = new cdk.ValidationResults();
169 if (typeof properties !== 'object') {
170 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
171 }
172 errors.collect(cdk.propertyValidator('dataProtectionPolicy', cdk.validateObject)(properties.dataProtectionPolicy));
173 errors.collect(cdk.propertyValidator('kmsKeyId', cdk.validateString)(properties.kmsKeyId));
174 errors.collect(cdk.propertyValidator('logGroupName', cdk.validateString)(properties.logGroupName));
175 errors.collect(cdk.propertyValidator('retentionInDays', cdk.validateNumber)(properties.retentionInDays));
176 errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
177 return errors.wrap('supplied properties not correct for "CfnLogGroupProps"');
178}
179/**
180 * Renders the AWS CloudFormation properties of an `AWS::Logs::LogGroup` resource
181 *
182 * @param properties - the TypeScript properties of a `CfnLogGroupProps`
183 *
184 * @returns the AWS CloudFormation properties of an `AWS::Logs::LogGroup` resource.
185 */
186// @ts-ignore TS6133
187function cfnLogGroupPropsToCloudFormation(properties) {
188 if (!cdk.canInspect(properties)) {
189 return properties;
190 }
191 CfnLogGroupPropsValidator(properties).assertSuccess();
192 return {
193 DataProtectionPolicy: cdk.objectToCloudFormation(properties.dataProtectionPolicy),
194 KmsKeyId: cdk.stringToCloudFormation(properties.kmsKeyId),
195 LogGroupName: cdk.stringToCloudFormation(properties.logGroupName),
196 RetentionInDays: cdk.numberToCloudFormation(properties.retentionInDays),
197 Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
198 };
199}
200// @ts-ignore TS6133
201function CfnLogGroupPropsFromCloudFormation(properties) {
202 properties = properties == null ? {} : properties;
203 if (typeof properties !== 'object') {
204 return new cfn_parse.FromCloudFormationResult(properties);
205 }
206 const ret = new cfn_parse.FromCloudFormationPropertyObject();
207 ret.addPropertyResult('dataProtectionPolicy', 'DataProtectionPolicy', properties.DataProtectionPolicy != null ? cfn_parse.FromCloudFormation.getAny(properties.DataProtectionPolicy) : undefined);
208 ret.addPropertyResult('kmsKeyId', 'KmsKeyId', properties.KmsKeyId != null ? cfn_parse.FromCloudFormation.getString(properties.KmsKeyId) : undefined);
209 ret.addPropertyResult('logGroupName', 'LogGroupName', properties.LogGroupName != null ? cfn_parse.FromCloudFormation.getString(properties.LogGroupName) : undefined);
210 ret.addPropertyResult('retentionInDays', 'RetentionInDays', properties.RetentionInDays != null ? cfn_parse.FromCloudFormation.getNumber(properties.RetentionInDays) : undefined);
211 ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
212 ret.addUnrecognizedPropertiesAsExtra(properties);
213 return ret;
214}
215/**
216 * A CloudFormation `AWS::Logs::LogGroup`
217 *
218 * The `AWS::Logs::LogGroup` resource specifies a log group. A log group defines common properties for log streams, such as their retention and access control rules. Each log stream must belong to one log group.
219 *
220 * You can create up to 1,000,000 log groups per Region per account. You must use the following guidelines when naming a log group:
221 *
222 * - Log group names must be unique within a Region for an AWS account.
223 * - Log group names can be between 1 and 512 characters long.
224 * - Log group names consist of the following characters: a-z, A-Z, 0-9, '_' (underscore), '-' (hyphen), '/' (forward slash), and '.' (period).
225 *
226 * @cloudformationResource AWS::Logs::LogGroup
227 * @stability external
228 *
229 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-loggroup.html
230 */
231class CfnLogGroup extends cdk.CfnResource {
232 /**
233 * Create a new `AWS::Logs::LogGroup`.
234 *
235 * @param scope - scope in which this resource is defined
236 * @param id - scoped id of the resource
237 * @param props - resource properties
238 */
239 constructor(scope, id, props = {}) {
240 super(scope, id, { type: CfnLogGroup.CFN_RESOURCE_TYPE_NAME, properties: props });
241 try {
242 jsiiDeprecationWarnings._aws_cdk_aws_logs_CfnLogGroupProps(props);
243 }
244 catch (error) {
245 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
246 Error.captureStackTrace(error, CfnLogGroup);
247 }
248 throw error;
249 }
250 this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
251 this.dataProtectionPolicy = props.dataProtectionPolicy;
252 this.kmsKeyId = props.kmsKeyId;
253 this.logGroupName = props.logGroupName;
254 this.retentionInDays = props.retentionInDays;
255 this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::Logs::LogGroup", props.tags, { tagPropertyName: 'tags' });
256 if (this.node.scope && cdk.Resource.isResource(this.node.scope)) {
257 this.node.addValidation({ validate: () => this.cfnOptions.deletionPolicy === undefined
258 ? ['\'AWS::Logs::LogGroup\' is a stateful resource type, and you must specify a Removal Policy for it. Call \'resource.applyRemovalPolicy()\'.']
259 : [] });
260 }
261 }
262 /**
263 * A factory method that creates a new instance of this class from an object
264 * containing the CloudFormation properties of this resource.
265 * Used in the @aws-cdk/cloudformation-include module.
266 *
267 * @internal
268 */
269 static _fromCloudFormation(scope, id, resourceAttributes, options) {
270 resourceAttributes = resourceAttributes || {};
271 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
272 const propsResult = CfnLogGroupPropsFromCloudFormation(resourceProperties);
273 const ret = new CfnLogGroup(scope, id, propsResult.value);
274 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
275 ret.addPropertyOverride(propKey, propVal);
276 }
277 options.parser.handleAttributes(ret, resourceAttributes, id);
278 return ret;
279 }
280 /**
281 * Examines the CloudFormation resource and discloses attributes.
282 *
283 * @param inspector - tree inspector to collect and process attributes
284 *
285 */
286 inspect(inspector) {
287 inspector.addAttribute("aws:cdk:cloudformation:type", CfnLogGroup.CFN_RESOURCE_TYPE_NAME);
288 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
289 }
290 get cfnProperties() {
291 return {
292 dataProtectionPolicy: this.dataProtectionPolicy,
293 kmsKeyId: this.kmsKeyId,
294 logGroupName: this.logGroupName,
295 retentionInDays: this.retentionInDays,
296 tags: this.tags.renderTags(),
297 };
298 }
299 renderProperties(props) {
300 return cfnLogGroupPropsToCloudFormation(props);
301 }
302}
303exports.CfnLogGroup = CfnLogGroup;
304_b = JSII_RTTI_SYMBOL_1;
305CfnLogGroup[_b] = { fqn: "@aws-cdk/aws-logs.CfnLogGroup", version: "1.204.0" };
306/**
307 * The CloudFormation resource type name for this resource class.
308 */
309CfnLogGroup.CFN_RESOURCE_TYPE_NAME = "AWS::Logs::LogGroup";
310/**
311 * Determine whether the given properties match those of a `CfnLogStreamProps`
312 *
313 * @param properties - the TypeScript properties of a `CfnLogStreamProps`
314 *
315 * @returns the result of the validation.
316 */
317function CfnLogStreamPropsValidator(properties) {
318 if (!cdk.canInspect(properties)) {
319 return cdk.VALIDATION_SUCCESS;
320 }
321 const errors = new cdk.ValidationResults();
322 if (typeof properties !== 'object') {
323 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
324 }
325 errors.collect(cdk.propertyValidator('logGroupName', cdk.requiredValidator)(properties.logGroupName));
326 errors.collect(cdk.propertyValidator('logGroupName', cdk.validateString)(properties.logGroupName));
327 errors.collect(cdk.propertyValidator('logStreamName', cdk.validateString)(properties.logStreamName));
328 return errors.wrap('supplied properties not correct for "CfnLogStreamProps"');
329}
330/**
331 * Renders the AWS CloudFormation properties of an `AWS::Logs::LogStream` resource
332 *
333 * @param properties - the TypeScript properties of a `CfnLogStreamProps`
334 *
335 * @returns the AWS CloudFormation properties of an `AWS::Logs::LogStream` resource.
336 */
337// @ts-ignore TS6133
338function cfnLogStreamPropsToCloudFormation(properties) {
339 if (!cdk.canInspect(properties)) {
340 return properties;
341 }
342 CfnLogStreamPropsValidator(properties).assertSuccess();
343 return {
344 LogGroupName: cdk.stringToCloudFormation(properties.logGroupName),
345 LogStreamName: cdk.stringToCloudFormation(properties.logStreamName),
346 };
347}
348// @ts-ignore TS6133
349function CfnLogStreamPropsFromCloudFormation(properties) {
350 properties = properties == null ? {} : properties;
351 if (typeof properties !== 'object') {
352 return new cfn_parse.FromCloudFormationResult(properties);
353 }
354 const ret = new cfn_parse.FromCloudFormationPropertyObject();
355 ret.addPropertyResult('logGroupName', 'LogGroupName', cfn_parse.FromCloudFormation.getString(properties.LogGroupName));
356 ret.addPropertyResult('logStreamName', 'LogStreamName', properties.LogStreamName != null ? cfn_parse.FromCloudFormation.getString(properties.LogStreamName) : undefined);
357 ret.addUnrecognizedPropertiesAsExtra(properties);
358 return ret;
359}
360/**
361 * A CloudFormation `AWS::Logs::LogStream`
362 *
363 * The `AWS::Logs::LogStream` resource specifies an Amazon CloudWatch Logs log stream in a specific log group. A log stream represents the sequence of events coming from an application instance or resource that you are monitoring.
364 *
365 * There is no limit on the number of log streams that you can create for a log group.
366 *
367 * You must use the following guidelines when naming a log stream:
368 *
369 * - Log stream names must be unique within the log group.
370 * - Log stream names can be between 1 and 512 characters long.
371 * - The ':' (colon) and '*' (asterisk) characters are not allowed.
372 *
373 * @cloudformationResource AWS::Logs::LogStream
374 * @stability external
375 *
376 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-logstream.html
377 */
378class CfnLogStream extends cdk.CfnResource {
379 /**
380 * Create a new `AWS::Logs::LogStream`.
381 *
382 * @param scope - scope in which this resource is defined
383 * @param id - scoped id of the resource
384 * @param props - resource properties
385 */
386 constructor(scope, id, props) {
387 super(scope, id, { type: CfnLogStream.CFN_RESOURCE_TYPE_NAME, properties: props });
388 try {
389 jsiiDeprecationWarnings._aws_cdk_aws_logs_CfnLogStreamProps(props);
390 }
391 catch (error) {
392 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
393 Error.captureStackTrace(error, CfnLogStream);
394 }
395 throw error;
396 }
397 cdk.requireProperty(props, 'logGroupName', this);
398 this.logGroupName = props.logGroupName;
399 this.logStreamName = props.logStreamName;
400 }
401 /**
402 * A factory method that creates a new instance of this class from an object
403 * containing the CloudFormation properties of this resource.
404 * Used in the @aws-cdk/cloudformation-include module.
405 *
406 * @internal
407 */
408 static _fromCloudFormation(scope, id, resourceAttributes, options) {
409 resourceAttributes = resourceAttributes || {};
410 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
411 const propsResult = CfnLogStreamPropsFromCloudFormation(resourceProperties);
412 const ret = new CfnLogStream(scope, id, propsResult.value);
413 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
414 ret.addPropertyOverride(propKey, propVal);
415 }
416 options.parser.handleAttributes(ret, resourceAttributes, id);
417 return ret;
418 }
419 /**
420 * Examines the CloudFormation resource and discloses attributes.
421 *
422 * @param inspector - tree inspector to collect and process attributes
423 *
424 */
425 inspect(inspector) {
426 inspector.addAttribute("aws:cdk:cloudformation:type", CfnLogStream.CFN_RESOURCE_TYPE_NAME);
427 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
428 }
429 get cfnProperties() {
430 return {
431 logGroupName: this.logGroupName,
432 logStreamName: this.logStreamName,
433 };
434 }
435 renderProperties(props) {
436 return cfnLogStreamPropsToCloudFormation(props);
437 }
438}
439exports.CfnLogStream = CfnLogStream;
440_c = JSII_RTTI_SYMBOL_1;
441CfnLogStream[_c] = { fqn: "@aws-cdk/aws-logs.CfnLogStream", version: "1.204.0" };
442/**
443 * The CloudFormation resource type name for this resource class.
444 */
445CfnLogStream.CFN_RESOURCE_TYPE_NAME = "AWS::Logs::LogStream";
446/**
447 * Determine whether the given properties match those of a `CfnMetricFilterProps`
448 *
449 * @param properties - the TypeScript properties of a `CfnMetricFilterProps`
450 *
451 * @returns the result of the validation.
452 */
453function CfnMetricFilterPropsValidator(properties) {
454 if (!cdk.canInspect(properties)) {
455 return cdk.VALIDATION_SUCCESS;
456 }
457 const errors = new cdk.ValidationResults();
458 if (typeof properties !== 'object') {
459 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
460 }
461 errors.collect(cdk.propertyValidator('filterName', cdk.validateString)(properties.filterName));
462 errors.collect(cdk.propertyValidator('filterPattern', cdk.requiredValidator)(properties.filterPattern));
463 errors.collect(cdk.propertyValidator('filterPattern', cdk.validateString)(properties.filterPattern));
464 errors.collect(cdk.propertyValidator('logGroupName', cdk.requiredValidator)(properties.logGroupName));
465 errors.collect(cdk.propertyValidator('logGroupName', cdk.validateString)(properties.logGroupName));
466 errors.collect(cdk.propertyValidator('metricTransformations', cdk.requiredValidator)(properties.metricTransformations));
467 errors.collect(cdk.propertyValidator('metricTransformations', cdk.listValidator(CfnMetricFilter_MetricTransformationPropertyValidator))(properties.metricTransformations));
468 return errors.wrap('supplied properties not correct for "CfnMetricFilterProps"');
469}
470/**
471 * Renders the AWS CloudFormation properties of an `AWS::Logs::MetricFilter` resource
472 *
473 * @param properties - the TypeScript properties of a `CfnMetricFilterProps`
474 *
475 * @returns the AWS CloudFormation properties of an `AWS::Logs::MetricFilter` resource.
476 */
477// @ts-ignore TS6133
478function cfnMetricFilterPropsToCloudFormation(properties) {
479 if (!cdk.canInspect(properties)) {
480 return properties;
481 }
482 CfnMetricFilterPropsValidator(properties).assertSuccess();
483 return {
484 FilterPattern: cdk.stringToCloudFormation(properties.filterPattern),
485 LogGroupName: cdk.stringToCloudFormation(properties.logGroupName),
486 MetricTransformations: cdk.listMapper(cfnMetricFilterMetricTransformationPropertyToCloudFormation)(properties.metricTransformations),
487 FilterName: cdk.stringToCloudFormation(properties.filterName),
488 };
489}
490// @ts-ignore TS6133
491function CfnMetricFilterPropsFromCloudFormation(properties) {
492 properties = properties == null ? {} : properties;
493 if (typeof properties !== 'object') {
494 return new cfn_parse.FromCloudFormationResult(properties);
495 }
496 const ret = new cfn_parse.FromCloudFormationPropertyObject();
497 ret.addPropertyResult('filterPattern', 'FilterPattern', cfn_parse.FromCloudFormation.getString(properties.FilterPattern));
498 ret.addPropertyResult('logGroupName', 'LogGroupName', cfn_parse.FromCloudFormation.getString(properties.LogGroupName));
499 ret.addPropertyResult('metricTransformations', 'MetricTransformations', cfn_parse.FromCloudFormation.getArray(CfnMetricFilterMetricTransformationPropertyFromCloudFormation)(properties.MetricTransformations));
500 ret.addPropertyResult('filterName', 'FilterName', properties.FilterName != null ? cfn_parse.FromCloudFormation.getString(properties.FilterName) : undefined);
501 ret.addUnrecognizedPropertiesAsExtra(properties);
502 return ret;
503}
504/**
505 * A CloudFormation `AWS::Logs::MetricFilter`
506 *
507 * The `AWS::Logs::MetricFilter` resource specifies a metric filter that describes how CloudWatch Logs extracts information from logs and transforms it into Amazon CloudWatch metrics. If you have multiple metric filters that are associated with a log group, all the filters are applied to the log streams in that group.
508 *
509 * The maximum number of metric filters that can be associated with a log group is 100.
510 *
511 * @cloudformationResource AWS::Logs::MetricFilter
512 * @stability external
513 *
514 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-metricfilter.html
515 */
516class CfnMetricFilter extends cdk.CfnResource {
517 /**
518 * Create a new `AWS::Logs::MetricFilter`.
519 *
520 * @param scope - scope in which this resource is defined
521 * @param id - scoped id of the resource
522 * @param props - resource properties
523 */
524 constructor(scope, id, props) {
525 super(scope, id, { type: CfnMetricFilter.CFN_RESOURCE_TYPE_NAME, properties: props });
526 try {
527 jsiiDeprecationWarnings._aws_cdk_aws_logs_CfnMetricFilterProps(props);
528 }
529 catch (error) {
530 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
531 Error.captureStackTrace(error, CfnMetricFilter);
532 }
533 throw error;
534 }
535 cdk.requireProperty(props, 'filterPattern', this);
536 cdk.requireProperty(props, 'logGroupName', this);
537 cdk.requireProperty(props, 'metricTransformations', this);
538 this.filterPattern = props.filterPattern;
539 this.logGroupName = props.logGroupName;
540 this.metricTransformations = props.metricTransformations;
541 this.filterName = props.filterName;
542 }
543 /**
544 * A factory method that creates a new instance of this class from an object
545 * containing the CloudFormation properties of this resource.
546 * Used in the @aws-cdk/cloudformation-include module.
547 *
548 * @internal
549 */
550 static _fromCloudFormation(scope, id, resourceAttributes, options) {
551 resourceAttributes = resourceAttributes || {};
552 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
553 const propsResult = CfnMetricFilterPropsFromCloudFormation(resourceProperties);
554 const ret = new CfnMetricFilter(scope, id, propsResult.value);
555 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
556 ret.addPropertyOverride(propKey, propVal);
557 }
558 options.parser.handleAttributes(ret, resourceAttributes, id);
559 return ret;
560 }
561 /**
562 * Examines the CloudFormation resource and discloses attributes.
563 *
564 * @param inspector - tree inspector to collect and process attributes
565 *
566 */
567 inspect(inspector) {
568 inspector.addAttribute("aws:cdk:cloudformation:type", CfnMetricFilter.CFN_RESOURCE_TYPE_NAME);
569 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
570 }
571 get cfnProperties() {
572 return {
573 filterPattern: this.filterPattern,
574 logGroupName: this.logGroupName,
575 metricTransformations: this.metricTransformations,
576 filterName: this.filterName,
577 };
578 }
579 renderProperties(props) {
580 return cfnMetricFilterPropsToCloudFormation(props);
581 }
582}
583exports.CfnMetricFilter = CfnMetricFilter;
584_d = JSII_RTTI_SYMBOL_1;
585CfnMetricFilter[_d] = { fqn: "@aws-cdk/aws-logs.CfnMetricFilter", version: "1.204.0" };
586/**
587 * The CloudFormation resource type name for this resource class.
588 */
589CfnMetricFilter.CFN_RESOURCE_TYPE_NAME = "AWS::Logs::MetricFilter";
590/**
591 * Determine whether the given properties match those of a `DimensionProperty`
592 *
593 * @param properties - the TypeScript properties of a `DimensionProperty`
594 *
595 * @returns the result of the validation.
596 */
597function CfnMetricFilter_DimensionPropertyValidator(properties) {
598 if (!cdk.canInspect(properties)) {
599 return cdk.VALIDATION_SUCCESS;
600 }
601 const errors = new cdk.ValidationResults();
602 if (typeof properties !== 'object') {
603 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
604 }
605 errors.collect(cdk.propertyValidator('key', cdk.requiredValidator)(properties.key));
606 errors.collect(cdk.propertyValidator('key', cdk.validateString)(properties.key));
607 errors.collect(cdk.propertyValidator('value', cdk.requiredValidator)(properties.value));
608 errors.collect(cdk.propertyValidator('value', cdk.validateString)(properties.value));
609 return errors.wrap('supplied properties not correct for "DimensionProperty"');
610}
611/**
612 * Renders the AWS CloudFormation properties of an `AWS::Logs::MetricFilter.Dimension` resource
613 *
614 * @param properties - the TypeScript properties of a `DimensionProperty`
615 *
616 * @returns the AWS CloudFormation properties of an `AWS::Logs::MetricFilter.Dimension` resource.
617 */
618// @ts-ignore TS6133
619function cfnMetricFilterDimensionPropertyToCloudFormation(properties) {
620 if (!cdk.canInspect(properties)) {
621 return properties;
622 }
623 CfnMetricFilter_DimensionPropertyValidator(properties).assertSuccess();
624 return {
625 Key: cdk.stringToCloudFormation(properties.key),
626 Value: cdk.stringToCloudFormation(properties.value),
627 };
628}
629// @ts-ignore TS6133
630function CfnMetricFilterDimensionPropertyFromCloudFormation(properties) {
631 if (cdk.isResolvableObject(properties)) {
632 return new cfn_parse.FromCloudFormationResult(properties);
633 }
634 properties = properties == null ? {} : properties;
635 if (typeof properties !== 'object') {
636 return new cfn_parse.FromCloudFormationResult(properties);
637 }
638 const ret = new cfn_parse.FromCloudFormationPropertyObject();
639 ret.addPropertyResult('key', 'Key', cfn_parse.FromCloudFormation.getString(properties.Key));
640 ret.addPropertyResult('value', 'Value', cfn_parse.FromCloudFormation.getString(properties.Value));
641 ret.addUnrecognizedPropertiesAsExtra(properties);
642 return ret;
643}
644/**
645 * Determine whether the given properties match those of a `MetricTransformationProperty`
646 *
647 * @param properties - the TypeScript properties of a `MetricTransformationProperty`
648 *
649 * @returns the result of the validation.
650 */
651function CfnMetricFilter_MetricTransformationPropertyValidator(properties) {
652 if (!cdk.canInspect(properties)) {
653 return cdk.VALIDATION_SUCCESS;
654 }
655 const errors = new cdk.ValidationResults();
656 if (typeof properties !== 'object') {
657 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
658 }
659 errors.collect(cdk.propertyValidator('defaultValue', cdk.validateNumber)(properties.defaultValue));
660 errors.collect(cdk.propertyValidator('dimensions', cdk.listValidator(CfnMetricFilter_DimensionPropertyValidator))(properties.dimensions));
661 errors.collect(cdk.propertyValidator('metricName', cdk.requiredValidator)(properties.metricName));
662 errors.collect(cdk.propertyValidator('metricName', cdk.validateString)(properties.metricName));
663 errors.collect(cdk.propertyValidator('metricNamespace', cdk.requiredValidator)(properties.metricNamespace));
664 errors.collect(cdk.propertyValidator('metricNamespace', cdk.validateString)(properties.metricNamespace));
665 errors.collect(cdk.propertyValidator('metricValue', cdk.requiredValidator)(properties.metricValue));
666 errors.collect(cdk.propertyValidator('metricValue', cdk.validateString)(properties.metricValue));
667 errors.collect(cdk.propertyValidator('unit', cdk.validateString)(properties.unit));
668 return errors.wrap('supplied properties not correct for "MetricTransformationProperty"');
669}
670/**
671 * Renders the AWS CloudFormation properties of an `AWS::Logs::MetricFilter.MetricTransformation` resource
672 *
673 * @param properties - the TypeScript properties of a `MetricTransformationProperty`
674 *
675 * @returns the AWS CloudFormation properties of an `AWS::Logs::MetricFilter.MetricTransformation` resource.
676 */
677// @ts-ignore TS6133
678function cfnMetricFilterMetricTransformationPropertyToCloudFormation(properties) {
679 if (!cdk.canInspect(properties)) {
680 return properties;
681 }
682 CfnMetricFilter_MetricTransformationPropertyValidator(properties).assertSuccess();
683 return {
684 DefaultValue: cdk.numberToCloudFormation(properties.defaultValue),
685 Dimensions: cdk.listMapper(cfnMetricFilterDimensionPropertyToCloudFormation)(properties.dimensions),
686 MetricName: cdk.stringToCloudFormation(properties.metricName),
687 MetricNamespace: cdk.stringToCloudFormation(properties.metricNamespace),
688 MetricValue: cdk.stringToCloudFormation(properties.metricValue),
689 Unit: cdk.stringToCloudFormation(properties.unit),
690 };
691}
692// @ts-ignore TS6133
693function CfnMetricFilterMetricTransformationPropertyFromCloudFormation(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('defaultValue', 'DefaultValue', properties.DefaultValue != null ? cfn_parse.FromCloudFormation.getNumber(properties.DefaultValue) : undefined);
703 ret.addPropertyResult('dimensions', 'Dimensions', properties.Dimensions != null ? cfn_parse.FromCloudFormation.getArray(CfnMetricFilterDimensionPropertyFromCloudFormation)(properties.Dimensions) : undefined);
704 ret.addPropertyResult('metricName', 'MetricName', cfn_parse.FromCloudFormation.getString(properties.MetricName));
705 ret.addPropertyResult('metricNamespace', 'MetricNamespace', cfn_parse.FromCloudFormation.getString(properties.MetricNamespace));
706 ret.addPropertyResult('metricValue', 'MetricValue', cfn_parse.FromCloudFormation.getString(properties.MetricValue));
707 ret.addPropertyResult('unit', 'Unit', properties.Unit != null ? cfn_parse.FromCloudFormation.getString(properties.Unit) : undefined);
708 ret.addUnrecognizedPropertiesAsExtra(properties);
709 return ret;
710}
711/**
712 * Determine whether the given properties match those of a `CfnQueryDefinitionProps`
713 *
714 * @param properties - the TypeScript properties of a `CfnQueryDefinitionProps`
715 *
716 * @returns the result of the validation.
717 */
718function CfnQueryDefinitionPropsValidator(properties) {
719 if (!cdk.canInspect(properties)) {
720 return cdk.VALIDATION_SUCCESS;
721 }
722 const errors = new cdk.ValidationResults();
723 if (typeof properties !== 'object') {
724 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
725 }
726 errors.collect(cdk.propertyValidator('logGroupNames', cdk.listValidator(cdk.validateString))(properties.logGroupNames));
727 errors.collect(cdk.propertyValidator('name', cdk.requiredValidator)(properties.name));
728 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
729 errors.collect(cdk.propertyValidator('queryString', cdk.requiredValidator)(properties.queryString));
730 errors.collect(cdk.propertyValidator('queryString', cdk.validateString)(properties.queryString));
731 return errors.wrap('supplied properties not correct for "CfnQueryDefinitionProps"');
732}
733/**
734 * Renders the AWS CloudFormation properties of an `AWS::Logs::QueryDefinition` resource
735 *
736 * @param properties - the TypeScript properties of a `CfnQueryDefinitionProps`
737 *
738 * @returns the AWS CloudFormation properties of an `AWS::Logs::QueryDefinition` resource.
739 */
740// @ts-ignore TS6133
741function cfnQueryDefinitionPropsToCloudFormation(properties) {
742 if (!cdk.canInspect(properties)) {
743 return properties;
744 }
745 CfnQueryDefinitionPropsValidator(properties).assertSuccess();
746 return {
747 Name: cdk.stringToCloudFormation(properties.name),
748 QueryString: cdk.stringToCloudFormation(properties.queryString),
749 LogGroupNames: cdk.listMapper(cdk.stringToCloudFormation)(properties.logGroupNames),
750 };
751}
752// @ts-ignore TS6133
753function CfnQueryDefinitionPropsFromCloudFormation(properties) {
754 properties = properties == null ? {} : properties;
755 if (typeof properties !== 'object') {
756 return new cfn_parse.FromCloudFormationResult(properties);
757 }
758 const ret = new cfn_parse.FromCloudFormationPropertyObject();
759 ret.addPropertyResult('name', 'Name', cfn_parse.FromCloudFormation.getString(properties.Name));
760 ret.addPropertyResult('queryString', 'QueryString', cfn_parse.FromCloudFormation.getString(properties.QueryString));
761 ret.addPropertyResult('logGroupNames', 'LogGroupNames', properties.LogGroupNames != null ? cfn_parse.FromCloudFormation.getStringArray(properties.LogGroupNames) : undefined);
762 ret.addUnrecognizedPropertiesAsExtra(properties);
763 return ret;
764}
765/**
766 * A CloudFormation `AWS::Logs::QueryDefinition`
767 *
768 * Creates a query definition for CloudWatch Logs Insights. For more information, see [Analyzing Log Data with CloudWatch Logs Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html) .
769 *
770 * @cloudformationResource AWS::Logs::QueryDefinition
771 * @stability external
772 *
773 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-querydefinition.html
774 */
775class CfnQueryDefinition extends cdk.CfnResource {
776 /**
777 * Create a new `AWS::Logs::QueryDefinition`.
778 *
779 * @param scope - scope in which this resource is defined
780 * @param id - scoped id of the resource
781 * @param props - resource properties
782 */
783 constructor(scope, id, props) {
784 super(scope, id, { type: CfnQueryDefinition.CFN_RESOURCE_TYPE_NAME, properties: props });
785 try {
786 jsiiDeprecationWarnings._aws_cdk_aws_logs_CfnQueryDefinitionProps(props);
787 }
788 catch (error) {
789 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
790 Error.captureStackTrace(error, CfnQueryDefinition);
791 }
792 throw error;
793 }
794 cdk.requireProperty(props, 'name', this);
795 cdk.requireProperty(props, 'queryString', this);
796 this.attrQueryDefinitionId = cdk.Token.asString(this.getAtt('QueryDefinitionId'));
797 this.name = props.name;
798 this.queryString = props.queryString;
799 this.logGroupNames = props.logGroupNames;
800 }
801 /**
802 * A factory method that creates a new instance of this class from an object
803 * containing the CloudFormation properties of this resource.
804 * Used in the @aws-cdk/cloudformation-include module.
805 *
806 * @internal
807 */
808 static _fromCloudFormation(scope, id, resourceAttributes, options) {
809 resourceAttributes = resourceAttributes || {};
810 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
811 const propsResult = CfnQueryDefinitionPropsFromCloudFormation(resourceProperties);
812 const ret = new CfnQueryDefinition(scope, id, propsResult.value);
813 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
814 ret.addPropertyOverride(propKey, propVal);
815 }
816 options.parser.handleAttributes(ret, resourceAttributes, id);
817 return ret;
818 }
819 /**
820 * Examines the CloudFormation resource and discloses attributes.
821 *
822 * @param inspector - tree inspector to collect and process attributes
823 *
824 */
825 inspect(inspector) {
826 inspector.addAttribute("aws:cdk:cloudformation:type", CfnQueryDefinition.CFN_RESOURCE_TYPE_NAME);
827 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
828 }
829 get cfnProperties() {
830 return {
831 name: this.name,
832 queryString: this.queryString,
833 logGroupNames: this.logGroupNames,
834 };
835 }
836 renderProperties(props) {
837 return cfnQueryDefinitionPropsToCloudFormation(props);
838 }
839}
840exports.CfnQueryDefinition = CfnQueryDefinition;
841_e = JSII_RTTI_SYMBOL_1;
842CfnQueryDefinition[_e] = { fqn: "@aws-cdk/aws-logs.CfnQueryDefinition", version: "1.204.0" };
843/**
844 * The CloudFormation resource type name for this resource class.
845 */
846CfnQueryDefinition.CFN_RESOURCE_TYPE_NAME = "AWS::Logs::QueryDefinition";
847/**
848 * Determine whether the given properties match those of a `CfnResourcePolicyProps`
849 *
850 * @param properties - the TypeScript properties of a `CfnResourcePolicyProps`
851 *
852 * @returns the result of the validation.
853 */
854function CfnResourcePolicyPropsValidator(properties) {
855 if (!cdk.canInspect(properties)) {
856 return cdk.VALIDATION_SUCCESS;
857 }
858 const errors = new cdk.ValidationResults();
859 if (typeof properties !== 'object') {
860 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
861 }
862 errors.collect(cdk.propertyValidator('policyDocument', cdk.requiredValidator)(properties.policyDocument));
863 errors.collect(cdk.propertyValidator('policyDocument', cdk.validateString)(properties.policyDocument));
864 errors.collect(cdk.propertyValidator('policyName', cdk.requiredValidator)(properties.policyName));
865 errors.collect(cdk.propertyValidator('policyName', cdk.validateString)(properties.policyName));
866 return errors.wrap('supplied properties not correct for "CfnResourcePolicyProps"');
867}
868/**
869 * Renders the AWS CloudFormation properties of an `AWS::Logs::ResourcePolicy` resource
870 *
871 * @param properties - the TypeScript properties of a `CfnResourcePolicyProps`
872 *
873 * @returns the AWS CloudFormation properties of an `AWS::Logs::ResourcePolicy` resource.
874 */
875// @ts-ignore TS6133
876function cfnResourcePolicyPropsToCloudFormation(properties) {
877 if (!cdk.canInspect(properties)) {
878 return properties;
879 }
880 CfnResourcePolicyPropsValidator(properties).assertSuccess();
881 return {
882 PolicyDocument: cdk.stringToCloudFormation(properties.policyDocument),
883 PolicyName: cdk.stringToCloudFormation(properties.policyName),
884 };
885}
886// @ts-ignore TS6133
887function CfnResourcePolicyPropsFromCloudFormation(properties) {
888 properties = properties == null ? {} : properties;
889 if (typeof properties !== 'object') {
890 return new cfn_parse.FromCloudFormationResult(properties);
891 }
892 const ret = new cfn_parse.FromCloudFormationPropertyObject();
893 ret.addPropertyResult('policyDocument', 'PolicyDocument', cfn_parse.FromCloudFormation.getString(properties.PolicyDocument));
894 ret.addPropertyResult('policyName', 'PolicyName', cfn_parse.FromCloudFormation.getString(properties.PolicyName));
895 ret.addUnrecognizedPropertiesAsExtra(properties);
896 return ret;
897}
898/**
899 * A CloudFormation `AWS::Logs::ResourcePolicy`
900 *
901 * Creates or updates a resource policy that allows other AWS services to put log events to this account. An account can have up to 10 resource policies per AWS Region.
902 *
903 * @cloudformationResource AWS::Logs::ResourcePolicy
904 * @stability external
905 *
906 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-resourcepolicy.html
907 */
908class CfnResourcePolicy extends cdk.CfnResource {
909 /**
910 * Create a new `AWS::Logs::ResourcePolicy`.
911 *
912 * @param scope - scope in which this resource is defined
913 * @param id - scoped id of the resource
914 * @param props - resource properties
915 */
916 constructor(scope, id, props) {
917 super(scope, id, { type: CfnResourcePolicy.CFN_RESOURCE_TYPE_NAME, properties: props });
918 try {
919 jsiiDeprecationWarnings._aws_cdk_aws_logs_CfnResourcePolicyProps(props);
920 }
921 catch (error) {
922 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
923 Error.captureStackTrace(error, CfnResourcePolicy);
924 }
925 throw error;
926 }
927 cdk.requireProperty(props, 'policyDocument', this);
928 cdk.requireProperty(props, 'policyName', this);
929 this.policyDocument = props.policyDocument;
930 this.policyName = props.policyName;
931 }
932 /**
933 * A factory method that creates a new instance of this class from an object
934 * containing the CloudFormation properties of this resource.
935 * Used in the @aws-cdk/cloudformation-include module.
936 *
937 * @internal
938 */
939 static _fromCloudFormation(scope, id, resourceAttributes, options) {
940 resourceAttributes = resourceAttributes || {};
941 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
942 const propsResult = CfnResourcePolicyPropsFromCloudFormation(resourceProperties);
943 const ret = new CfnResourcePolicy(scope, id, propsResult.value);
944 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
945 ret.addPropertyOverride(propKey, propVal);
946 }
947 options.parser.handleAttributes(ret, resourceAttributes, id);
948 return ret;
949 }
950 /**
951 * Examines the CloudFormation resource and discloses attributes.
952 *
953 * @param inspector - tree inspector to collect and process attributes
954 *
955 */
956 inspect(inspector) {
957 inspector.addAttribute("aws:cdk:cloudformation:type", CfnResourcePolicy.CFN_RESOURCE_TYPE_NAME);
958 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
959 }
960 get cfnProperties() {
961 return {
962 policyDocument: this.policyDocument,
963 policyName: this.policyName,
964 };
965 }
966 renderProperties(props) {
967 return cfnResourcePolicyPropsToCloudFormation(props);
968 }
969}
970exports.CfnResourcePolicy = CfnResourcePolicy;
971_f = JSII_RTTI_SYMBOL_1;
972CfnResourcePolicy[_f] = { fqn: "@aws-cdk/aws-logs.CfnResourcePolicy", version: "1.204.0" };
973/**
974 * The CloudFormation resource type name for this resource class.
975 */
976CfnResourcePolicy.CFN_RESOURCE_TYPE_NAME = "AWS::Logs::ResourcePolicy";
977/**
978 * Determine whether the given properties match those of a `CfnSubscriptionFilterProps`
979 *
980 * @param properties - the TypeScript properties of a `CfnSubscriptionFilterProps`
981 *
982 * @returns the result of the validation.
983 */
984function CfnSubscriptionFilterPropsValidator(properties) {
985 if (!cdk.canInspect(properties)) {
986 return cdk.VALIDATION_SUCCESS;
987 }
988 const errors = new cdk.ValidationResults();
989 if (typeof properties !== 'object') {
990 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
991 }
992 errors.collect(cdk.propertyValidator('destinationArn', cdk.requiredValidator)(properties.destinationArn));
993 errors.collect(cdk.propertyValidator('destinationArn', cdk.validateString)(properties.destinationArn));
994 errors.collect(cdk.propertyValidator('distribution', cdk.validateString)(properties.distribution));
995 errors.collect(cdk.propertyValidator('filterName', cdk.validateString)(properties.filterName));
996 errors.collect(cdk.propertyValidator('filterPattern', cdk.requiredValidator)(properties.filterPattern));
997 errors.collect(cdk.propertyValidator('filterPattern', cdk.validateString)(properties.filterPattern));
998 errors.collect(cdk.propertyValidator('logGroupName', cdk.requiredValidator)(properties.logGroupName));
999 errors.collect(cdk.propertyValidator('logGroupName', cdk.validateString)(properties.logGroupName));
1000 errors.collect(cdk.propertyValidator('roleArn', cdk.validateString)(properties.roleArn));
1001 return errors.wrap('supplied properties not correct for "CfnSubscriptionFilterProps"');
1002}
1003/**
1004 * Renders the AWS CloudFormation properties of an `AWS::Logs::SubscriptionFilter` resource
1005 *
1006 * @param properties - the TypeScript properties of a `CfnSubscriptionFilterProps`
1007 *
1008 * @returns the AWS CloudFormation properties of an `AWS::Logs::SubscriptionFilter` resource.
1009 */
1010// @ts-ignore TS6133
1011function cfnSubscriptionFilterPropsToCloudFormation(properties) {
1012 if (!cdk.canInspect(properties)) {
1013 return properties;
1014 }
1015 CfnSubscriptionFilterPropsValidator(properties).assertSuccess();
1016 return {
1017 DestinationArn: cdk.stringToCloudFormation(properties.destinationArn),
1018 FilterPattern: cdk.stringToCloudFormation(properties.filterPattern),
1019 LogGroupName: cdk.stringToCloudFormation(properties.logGroupName),
1020 Distribution: cdk.stringToCloudFormation(properties.distribution),
1021 FilterName: cdk.stringToCloudFormation(properties.filterName),
1022 RoleArn: cdk.stringToCloudFormation(properties.roleArn),
1023 };
1024}
1025// @ts-ignore TS6133
1026function CfnSubscriptionFilterPropsFromCloudFormation(properties) {
1027 properties = properties == null ? {} : properties;
1028 if (typeof properties !== 'object') {
1029 return new cfn_parse.FromCloudFormationResult(properties);
1030 }
1031 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1032 ret.addPropertyResult('destinationArn', 'DestinationArn', cfn_parse.FromCloudFormation.getString(properties.DestinationArn));
1033 ret.addPropertyResult('filterPattern', 'FilterPattern', cfn_parse.FromCloudFormation.getString(properties.FilterPattern));
1034 ret.addPropertyResult('logGroupName', 'LogGroupName', cfn_parse.FromCloudFormation.getString(properties.LogGroupName));
1035 ret.addPropertyResult('distribution', 'Distribution', properties.Distribution != null ? cfn_parse.FromCloudFormation.getString(properties.Distribution) : undefined);
1036 ret.addPropertyResult('filterName', 'FilterName', properties.FilterName != null ? cfn_parse.FromCloudFormation.getString(properties.FilterName) : undefined);
1037 ret.addPropertyResult('roleArn', 'RoleArn', properties.RoleArn != null ? cfn_parse.FromCloudFormation.getString(properties.RoleArn) : undefined);
1038 ret.addUnrecognizedPropertiesAsExtra(properties);
1039 return ret;
1040}
1041/**
1042 * A CloudFormation `AWS::Logs::SubscriptionFilter`
1043 *
1044 * The `AWS::Logs::SubscriptionFilter` resource specifies a subscription filter and associates it with the specified log group. Subscription filters allow you to subscribe to a real-time stream of log events and have them delivered to a specific destination. Currently, the supported destinations are:
1045 *
1046 * - An Amazon Kinesis data stream belonging to the same account as the subscription filter, for same-account delivery.
1047 * - A logical destination that belongs to a different account, for cross-account delivery.
1048 * - An Amazon Kinesis Firehose delivery stream that belongs to the same account as the subscription filter, for same-account delivery.
1049 * - An AWS Lambda function that belongs to the same account as the subscription filter, for same-account delivery.
1050 *
1051 * There can be as many as two subscription filters associated with a log group.
1052 *
1053 * @cloudformationResource AWS::Logs::SubscriptionFilter
1054 * @stability external
1055 *
1056 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-subscriptionfilter.html
1057 */
1058class CfnSubscriptionFilter extends cdk.CfnResource {
1059 /**
1060 * Create a new `AWS::Logs::SubscriptionFilter`.
1061 *
1062 * @param scope - scope in which this resource is defined
1063 * @param id - scoped id of the resource
1064 * @param props - resource properties
1065 */
1066 constructor(scope, id, props) {
1067 super(scope, id, { type: CfnSubscriptionFilter.CFN_RESOURCE_TYPE_NAME, properties: props });
1068 try {
1069 jsiiDeprecationWarnings._aws_cdk_aws_logs_CfnSubscriptionFilterProps(props);
1070 }
1071 catch (error) {
1072 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
1073 Error.captureStackTrace(error, CfnSubscriptionFilter);
1074 }
1075 throw error;
1076 }
1077 cdk.requireProperty(props, 'destinationArn', this);
1078 cdk.requireProperty(props, 'filterPattern', this);
1079 cdk.requireProperty(props, 'logGroupName', this);
1080 this.destinationArn = props.destinationArn;
1081 this.filterPattern = props.filterPattern;
1082 this.logGroupName = props.logGroupName;
1083 this.distribution = props.distribution;
1084 this.filterName = props.filterName;
1085 this.roleArn = props.roleArn;
1086 }
1087 /**
1088 * A factory method that creates a new instance of this class from an object
1089 * containing the CloudFormation properties of this resource.
1090 * Used in the @aws-cdk/cloudformation-include module.
1091 *
1092 * @internal
1093 */
1094 static _fromCloudFormation(scope, id, resourceAttributes, options) {
1095 resourceAttributes = resourceAttributes || {};
1096 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
1097 const propsResult = CfnSubscriptionFilterPropsFromCloudFormation(resourceProperties);
1098 const ret = new CfnSubscriptionFilter(scope, id, propsResult.value);
1099 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
1100 ret.addPropertyOverride(propKey, propVal);
1101 }
1102 options.parser.handleAttributes(ret, resourceAttributes, id);
1103 return ret;
1104 }
1105 /**
1106 * Examines the CloudFormation resource and discloses attributes.
1107 *
1108 * @param inspector - tree inspector to collect and process attributes
1109 *
1110 */
1111 inspect(inspector) {
1112 inspector.addAttribute("aws:cdk:cloudformation:type", CfnSubscriptionFilter.CFN_RESOURCE_TYPE_NAME);
1113 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
1114 }
1115 get cfnProperties() {
1116 return {
1117 destinationArn: this.destinationArn,
1118 filterPattern: this.filterPattern,
1119 logGroupName: this.logGroupName,
1120 distribution: this.distribution,
1121 filterName: this.filterName,
1122 roleArn: this.roleArn,
1123 };
1124 }
1125 renderProperties(props) {
1126 return cfnSubscriptionFilterPropsToCloudFormation(props);
1127 }
1128}
1129exports.CfnSubscriptionFilter = CfnSubscriptionFilter;
1130_g = JSII_RTTI_SYMBOL_1;
1131CfnSubscriptionFilter[_g] = { fqn: "@aws-cdk/aws-logs.CfnSubscriptionFilter", version: "1.204.0" };
1132/**
1133 * The CloudFormation resource type name for this resource class.
1134 */
1135CfnSubscriptionFilter.CFN_RESOURCE_TYPE_NAME = "AWS::Logs::SubscriptionFilter";
1136//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9ncy5nZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJsb2dzLmdlbmVyYXRlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSwrRUFBK0U7QUFDL0UsK0RBQStEO0FBQy9ELDhGQUE4RjtBQUM5RixzSEFBc0g7QUFFdEgsNEJBQTRCLENBQUMsaUVBQWlFO0FBRTlGLHFDQUFxQztBQUNyQyxnRUFBZ0U7QUF5Q2hFOzs7Ozs7R0FNRztBQUNILFNBQVMsNEJBQTRCLENBQUMsVUFBZTtJQUNqRCxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsRUFBRTtRQUFFLE9BQU8sR0FBRyxDQUFDLGtCQUFrQixDQUFDO0tBQUU7SUFDbkUsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUMzQyxJQUFJLE9BQU8sVUFBVSxLQUFLLFFBQVEsRUFBRTtRQUNoQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksR0FBRyxDQUFDLGdCQUFnQixDQUFDLG9DQUFvQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQy9HO0lBQ0QsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsaUJBQWlCLEVBQUUsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUMsVUFBVSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7SUFDNUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsaUJBQWlCLEVBQUUsR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO0lBQ3pHLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLG1CQUFtQixFQUFFLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxVQUFVLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxD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LEVBQUUsSUFBSSxDQUFDLGNBQWM7WUFDbkMsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhO1lBQ2pDLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWTtZQUMvQixZQUFZLEVBQUUsSUFBSSxDQUFDLFlBQVk7WUFDL0IsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQzNCLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztTQUN4QixDQUFDO0tBQ0w7SUFFUyxnQkFBZ0IsQ0FBQyxLQUEyQjtRQUNsRCxPQUFPLDBDQUEwQyxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQzVEOztBQWhITCxzREFpSEM7OztBQWhIRzs7R0FFRztBQUNvQiw0Q0FBc0IsR0FBRywrQkFBK0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDEyLTIwMjMgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbi8vIEdlbmVyYXRlZCBmcm9tIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gUmVzb3VyY2UgU3BlY2lmaWNhdGlvblxuLy8gU2VlOiBkb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvY2ZuLXJlc291cmNlLXNwZWNpZmljYXRpb24uaHRtbFxuLy8gQGNmbjJ0czptZXRhQCB7XCJnZW5lcmF0ZWRcIjpcIjIwMjMtMDYtMTlUMTU6MTQ6NTMuMTExWlwiLFwiZmluZ2VycHJpbnRcIjpcImxsbkcvcWxSK05pU0N0dENjMXhLc2pWcmZmdVpRcDBhakxMYlh5MitCT289XCJ9XG5cbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi8gLy8gVGhpcyBpcyBnZW5lcmF0ZWQgY29kZSAtIGxpbmUgbGVuZ3RocyBhcmUgZGlmZmljdWx0IHRvIGNvbnRyb2xcblxuaW1wb3J0ICogYXMgY2RrIGZyb20gJ0Bhd3MtY2RrL2NvcmUnO1xuaW1wb3J0ICogYXMgY2ZuX3BhcnNlIGZyb20gJ0Bhd3MtY2RrL2NvcmUvbGliL2hlbHBlcnMtaW50ZXJuYWwnO1xuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmbkRlc3RpbmF0aW9uYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLWRlc3RpbmF0aW9uLmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5EZXN0aW5hdGlvblByb3BzIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBkZXN0aW5hdGlvbi5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtZGVzdGluYXRpb24uaHRtbCNjZm4tbG9ncy1kZXN0aW5hdGlvbi1kZXN0aW5hdGlvbm5hbWVcbiAgICAgKi9cbiAgICByZWFkb25seSBkZXN0aW5hdGlvbk5hbWU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBBUk4gb2YgYW4gSUFNIHJvbGUgdGhhdCBwZXJtaXRzIENsb3VkV2F0Y2ggTG9ncyB0byBzZW5kIGRhdGEgdG8gdGhlIHNwZWNpZmllZCBBV1MgcmVzb3VyY2UuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLWRlc3RpbmF0aW9uLmh0bWwjY2ZuLWxvZ3MtZGVzdGluYXRpb24tcm9sZWFyblxuICAgICAqL1xuICAgIHJlYWRvbmx5IHJvbGVBcm46IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgcGh5c2ljYWwgdGFyZ2V0IHdoZXJlIHRoZSBsb2cgZXZlbnRzIGFyZSBkZWxpdmVyZWQgKGZvciBleGFtcGxlLCBhIEtpbmVzaXMgc3RyZWFtKS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtZGVzdGluYXRpb24uaHRtbCNjZm4tbG9ncy1kZXN0aW5hdGlvbi10YXJnZXRhcm5cbiAgICAgKi9cbiAgICByZWFkb25seSB0YXJnZXRBcm46IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEFuIElBTSBwb2xpY3kgZG9jdW1lbnQgdGhhdCBnb3Zlcm5zIHdoaWNoIEFXUyBhY2NvdW50cyBjYW4gY3JlYXRlIHN1YnNjcmlwdGlvbiBmaWx0ZXJzIGFnYWluc3QgdGhpcyBkZXN0aW5hdGlvbi5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtZGVzdGluYXRpb24uaHRtbCNjZm4tbG9ncy1kZXN0aW5hdGlvbi1kZXN0aW5hdGlvbnBvbGljeVxuICAgICAqL1xuICAgIHJlYWRvbmx5IGRlc3RpbmF0aW9uUG9saWN5Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmbkRlc3RpbmF0aW9uUHJvcHNgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbkRlc3RpbmF0aW9uUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuRGVzdGluYXRpb25Qcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2Rlc3RpbmF0aW9uTmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5kZXN0aW5hdGlvbk5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2Rlc3RpbmF0aW9uTmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5kZXN0aW5hdGlvbk5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2Rlc3RpbmF0aW9uUG9saWN5JywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmRlc3RpbmF0aW9uUG9saWN5KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyb2xlQXJuJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnJvbGVBcm4pKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3JvbGVBcm4nLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucm9sZUFybikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndGFyZ2V0QXJuJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnRhcmdldEFybikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndGFyZ2V0QXJuJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnRhcmdldEFybikpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5EZXN0aW5hdGlvblByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpMb2dzOjpEZXN0aW5hdGlvbmAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuRGVzdGluYXRpb25Qcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6TG9nczo6RGVzdGluYXRpb25gIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuRGVzdGluYXRpb25Qcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuRGVzdGluYXRpb25Qcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgRGVzdGluYXRpb25OYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmRlc3RpbmF0aW9uTmFtZSksXG4gICAgICAgIFJvbGVBcm46IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucm9sZUFybiksXG4gICAgICAgIFRhcmdldEFybjogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy50YXJnZXRBcm4pLFxuICAgICAgICBEZXN0aW5hdGlvblBvbGljeTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5kZXN0aW5hdGlvblBvbGljeSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkRlc3RpbmF0aW9uUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5EZXN0aW5hdGlvblByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5EZXN0aW5hdGlvblByb3BzPigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZGVzdGluYXRpb25OYW1lJywgJ0Rlc3RpbmF0aW9uTmFtZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuRGVzdGluYXRpb25OYW1lKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdyb2xlQXJuJywgJ1JvbGVBcm4nLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlJvbGVBcm4pKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3RhcmdldEFybicsICdUYXJnZXRBcm4nLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlRhcmdldEFybikpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZGVzdGluYXRpb25Qb2xpY3knLCAnRGVzdGluYXRpb25Qb2xpY3knLCBwcm9wZXJ0aWVzLkRlc3RpbmF0aW9uUG9saWN5ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkRlc3RpbmF0aW9uUG9saWN5KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpMb2dzOjpEZXN0aW5hdGlvbmBcbiAqXG4gKiBUaGUgQVdTOjpMb2dzOjpEZXN0aW5hdGlvbiByZXNvdXJjZSBzcGVjaWZpZXMgYSBDbG91ZFdhdGNoIExvZ3MgZGVzdGluYXRpb24uIEEgZGVzdGluYXRpb24gZW5jYXBzdWxhdGVzIGEgcGh5c2ljYWwgcmVzb3VyY2UgKHN1Y2ggYXMgYW4gQW1hem9uIEtpbmVzaXMgZGF0YSBzdHJlYW0pIGFuZCBlbmFibGVzIHlvdSB0byBzdWJzY3JpYmUgdGhhdCByZXNvdXJjZSB0byBhIHN0cmVhbSBvZiBsb2cgZXZlbnRzLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6TG9nczo6RGVzdGluYXRpb25cbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLWRlc3RpbmF0aW9uLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIENmbkRlc3RpbmF0aW9uIGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6TG9nczo6RGVzdGluYXRpb25cIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmbkRlc3RpbmF0aW9uIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5EZXN0aW5hdGlvblByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5EZXN0aW5hdGlvbihzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgQVJOIG9mIHRoZSBDbG91ZFdhdGNoIExvZ3MgZGVzdGluYXRpb24sIHN1Y2ggYXMgYGFybjphd3M6bG9nczp1cy13ZXN0LTE6MTIzNDU2Nzg5MDEyOmRlc3RpbmF0aW9uOk15RGVzdGluYXRpb25gIC5cbiAgICAgKiBAY2xvdWRmb3JtYXRpb25BdHRyaWJ1dGUgQXJuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGF0dHJBcm46IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBkZXN0aW5hdGlvbi5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtZGVzdGluYXRpb24uaHRtbCNjZm4tbG9ncy1kZXN0aW5hdGlvbi1kZXN0aW5hdGlvbm5hbWVcbiAgICAgKi9cbiAgICBwdWJsaWMgZGVzdGluYXRpb25OYW1lOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgQVJOIG9mIGFuIElBTSByb2xlIHRoYXQgcGVybWl0cyBDbG91ZFdhdGNoIExvZ3MgdG8gc2VuZCBkYXRhIHRvIHRoZSBzcGVjaWZpZWQgQVdTIHJlc291cmNlLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1kZXN0aW5hdGlvbi5odG1sI2Nmbi1sb2dzLWRlc3RpbmF0aW9uLXJvbGVhcm5cbiAgICAgKi9cbiAgICBwdWJsaWMgcm9sZUFybjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIG9mIHRoZSBwaHlzaWNhbCB0YXJnZXQgd2hlcmUgdGhlIGxvZyBldmVudHMgYXJlIGRlbGl2ZXJlZCAoZm9yIGV4YW1wbGUsIGEgS2luZXNpcyBzdHJlYW0pLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1kZXN0aW5hdGlvbi5odG1sI2Nmbi1sb2dzLWRlc3RpbmF0aW9uLXRhcmdldGFyblxuICAgICAqL1xuICAgIHB1YmxpYyB0YXJnZXRBcm46IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEFuIElBTSBwb2xpY3kgZG9jdW1lbnQgdGhhdCBnb3Zlcm5zIHdoaWNoIEFXUyBhY2NvdW50cyBjYW4gY3JlYXRlIHN1YnNjcmlwdGlvbiBmaWx0ZXJzIGFnYWluc3QgdGhpcyBkZXN0aW5hdGlvbi5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtZGVzdGluYXRpb24uaHRtbCNjZm4tbG9ncy1kZXN0aW5hdGlvbi1kZXN0aW5hdGlvbnBvbGljeVxuICAgICAqL1xuICAgIHB1YmxpYyBkZXN0aW5hdGlvblBvbGljeTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGBBV1M6OkxvZ3M6OkRlc3RpbmF0aW9uYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5EZXN0aW5hdGlvblByb3BzKSB7XG4gICAgICAgIHN1cGVyKHNjb3BlLCBpZCwgeyB0eXBlOiBDZm5EZXN0aW5hdGlvbi5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ2Rlc3RpbmF0aW9uTmFtZScsIHRoaXMpO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAncm9sZUFybicsIHRoaXMpO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAndGFyZ2V0QXJuJywgdGhpcyk7XG4gICAgICAgIHRoaXMuYXR0ckFybiA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnQXJuJykpO1xuXG4gICAgICAgIHRoaXMuZGVzdGluYXRpb25OYW1lID0gcHJvcHMuZGVzdGluYXRpb25OYW1lO1xuICAgICAgICB0aGlzLnJvbGVBcm4gPSBwcm9wcy5yb2xlQXJuO1xuICAgICAgICB0aGlzLnRhcmdldEFybiA9IHByb3BzLnRhcmdldEFybjtcbiAgICAgICAgdGhpcy5kZXN0aW5hdGlvblBvbGljeSA9IHByb3BzLmRlc3RpbmF0aW9uUG9saWN5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuRGVzdGluYXRpb24uQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGRlc3RpbmF0aW9uTmFtZTogdGhpcy5kZXN0aW5hdGlvbk5hbWUsXG4gICAgICAgICAgICByb2xlQXJuOiB0aGlzLnJvbGVBcm4sXG4gICAgICAgICAgICB0YXJnZXRBcm46IHRoaXMudGFyZ2V0QXJuLFxuICAgICAgICAgICAgZGVzdGluYXRpb25Qb2xpY3k6IHRoaXMuZGVzdGluYXRpb25Qb2xpY3ksXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlbmRlclByb3BlcnRpZXMocHJvcHM6IHtba2V5OiBzdHJpbmddOiBhbnl9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4gY2ZuRGVzdGluYXRpb25Qcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcHMpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIGBDZm5Mb2dHcm91cGBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1sb2dncm91cC5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2ZuTG9nR3JvdXBQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZGF0YSBwcm90ZWN0aW9uIHBvbGljeSBhbmQgYXNzaWducyBpdCB0byB0aGUgbG9nIGdyb3VwLiBBIGRhdGEgcHJvdGVjdGlvbiBwb2xpY3kgY2FuIGhlbHAgc2FmZWd1YXJkIHNlbnNpdGl2ZSBkYXRhIHRoYXQncyBpbmdlc3RlZCBieSB0aGUgbG9nIGdyb3VwIGJ5IGF1ZGl0aW5nIGFuZCBtYXNraW5nIHRoZSBzZW5zaXRpdmUgbG9nIGRhdGEuIFdoZW4gYSB1c2VyIHdobyBkb2VzIG5vdCBoYXZlIHBlcm1pc3Npb24gdG8gdmlldyBtYXNrZWQgZGF0YSB2aWV3cyBhIGxvZyBldmVudCB0aGF0IGluY2x1ZGVzIG1hc2tlZCBkYXRhLCB0aGUgc2Vuc2l0aXZlIGRhdGEgaXMgcmVwbGFjZWQgYnkgYXN0ZXJpc2tzLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24sIGluY2x1ZGluZyBhIGxpc3Qgb2YgdHlwZXMgb2YgZGF0YSB0aGF0IGNhbiBiZSBhdWRpdGVkIGFuZCBtYXNrZWQsIHNlZSBbUHJvdGVjdCBzZW5zaXRpdmUgbG9nIGRhdGEgd2l0aCBtYXNraW5nXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRXYXRjaC9sYXRlc3QvbG9ncy9tYXNrLXNlbnNpdGl2ZS1sb2ctZGF0YS5odG1sKSAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLWxvZ2dyb3VwLmh0bWwjY2ZuLWxvZ3MtbG9nZ3JvdXAtZGF0YXByb3RlY3Rpb25wb2xpY3lcbiAgICAgKi9cbiAgICByZWFkb25seSBkYXRhUHJvdGVjdGlvblBvbGljeT86IGFueSB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgQVdTIEtNUyBrZXkgdG8gdXNlIHdoZW4gZW5jcnlwdGluZyBsb2cgZGF0YS5cbiAgICAgKlxuICAgICAqIFRvIGFzc29jaWF0ZSBhbiBBV1MgS01TIGtleSB3aXRoIHRoZSBsb2cgZ3JvdXAsIHNwZWNpZnkgdGhlIEFSTiBvZiB0aGF0IEtNUyBrZXkgaGVyZS4gSWYgeW91IGRvIHNvLCBpbmdlc3RlZCBkYXRhIGlzIGVuY3J5cHRlZCB1c2luZyB0aGlzIGtleS4gVGhpcyBhc3NvY2lhdGlvbiBpcyBzdG9yZWQgYXMgbG9uZyBhcyB0aGUgZGF0YSBlbmNyeXB0ZWQgd2l0aCB0aGUgS01TIGtleSBpcyBzdGlsbCB3aXRoaW4gQ2xvdWRXYXRjaCBMb2dzIC4gVGhpcyBlbmFibGVzIENsb3VkV2F0Y2ggTG9ncyB0byBkZWNyeXB0IHRoaXMgZGF0YSB3aGVuZXZlciBpdCBpcyByZXF1ZXN0ZWQuXG4gICAgICpcbiAgICAgKiBJZiB5b3UgYXR0ZW1wdCB0byBhc3NvY2lhdGUgYSBLTVMga2V5IHdpdGggdGhlIGxvZyBncm91cCBidXQgdGhlIEtNUyBrZXkgZG9lc24ndCBleGlzdCBvciBpcyBkZWFjdGl2YXRlZCwgeW91IHdpbGwgcmVjZWl2ZSBhbiBgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbmAgZXJyb3IuXG4gICAgICpcbiAgICAgKiBMb2cgZ3JvdXAgZGF0YSBpcyBhbHdheXMgZW5jcnlwdGVkIGluIENsb3VkV2F0Y2ggTG9ncyAuIElmIHlvdSBvbWl0IHRoaXMga2V5LCB0aGUgZW5jcnlwdGlvbiBkb2VzIG5vdCB1c2UgQVdTIEtNUyAuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0VuY3J5cHQgbG9nIGRhdGEgaW4gQ2xvdWRXYXRjaCBMb2dzIHVzaW5nIEFXUyBLZXkgTWFuYWdlbWVudCBTZXJ2aWNlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRXYXRjaC9sYXRlc3QvbG9ncy9lbmNyeXB0LWxvZy1kYXRhLWttcy5odG1sKVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1sb2dncm91cC5odG1sI2Nmbi1sb2dzLWxvZ2dyb3VwLWttc2tleWlkXG4gICAgICovXG4gICAgcmVhZG9ubHkga21zS2V5SWQ/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgbG9nIGdyb3VwLiBJZiB5b3UgZG9uJ3Qgc3BlY2lmeSBhIG5hbWUsIEFXUyBDbG91ZEZvcm1hdGlvbiBnZW5lcmF0ZXMgYSB1bmlxdWUgSUQgZm9yIHRoZSBsb2cgZ3JvdXAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLWxvZ2dyb3VwLmh0bWwjY2ZuLWxvZ3MtbG9nZ3JvdXAtbG9nZ3JvdXBuYW1lXG4gICAgICovXG4gICAgcmVhZG9ubHkgbG9nR3JvdXBOYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBkYXlzIHRvIHJldGFpbiB0aGUgbG9nIGV2ZW50cyBpbiB0aGUgc3BlY2lmaWVkIGxvZyBncm91cC4gUG9zc2libGUgdmFsdWVzIGFyZTogMSwgMywgNSwgNywgMTQsIDMwLCA2MCwgOTAsIDEyMCwgMTUwLCAxODAsIDM2NSwgNDAwLCA1NDUsIDczMSwgMTA5NiwgMTgyNywgMjE5MiwgMjU1NywgMjkyMiwgMzI4OCwgYW5kIDM2NTMuXG4gICAgICpcbiAgICAgKiBUbyBzZXQgYSBsb2cgZ3JvdXAgc28gdGhhdCBpdHMgbG9nIGV2ZW50cyBkbyBub3QgZXhwaXJlLCB1c2UgW0RlbGV0ZVJldGVudGlvblBvbGljeV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2hMb2dzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZVJldGVudGlvblBvbGljeS5odG1sKSAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLWxvZ2dyb3VwLmh0bWwjY2ZuLWxvZ3MtbG9nZ3JvdXAtcmV0ZW50aW9uaW5kYXlzXG4gICAgICovXG4gICAgcmVhZG9ubHkgcmV0ZW50aW9uSW5EYXlzPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogQW4gYXJyYXkgb2Yga2V5LXZhbHVlIHBhaXJzIHRvIGFwcGx5IHRvIHRoZSBsb2cgZ3JvdXAuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtUYWddKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJlc291cmNlLXRhZ3MuaHRtbCkgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1sb2dncm91cC5odG1sI2Nmbi1sb2dzLWxvZ2dyb3VwLXRhZ3NcbiAgICAgKi9cbiAgICByZWFkb25seSB0YWdzPzogY2RrLkNmblRhZ1tdO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmbkxvZ0dyb3VwUHJvcHNgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbkxvZ0dyb3VwUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuTG9nR3JvdXBQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2RhdGFQcm90ZWN0aW9uUG9saWN5JywgY2RrLnZhbGlkYXRlT2JqZWN0KShwcm9wZXJ0aWVzLmRhdGFQcm90ZWN0aW9uUG9saWN5KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdrbXNLZXlJZCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5rbXNLZXlJZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbG9nR3JvdXBOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmxvZ0dyb3VwTmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncmV0ZW50aW9uSW5EYXlzJywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLnJldGVudGlvbkluRGF5cykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndGFncycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZUNmblRhZykpKHByb3BlcnRpZXMudGFncykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5Mb2dHcm91cFByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpMb2dzOjpMb2dHcm91cGAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuTG9nR3JvdXBQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6TG9nczo6TG9nR3JvdXBgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuTG9nR3JvdXBQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuTG9nR3JvdXBQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgRGF0YVByb3RlY3Rpb25Qb2xpY3k6IGNkay5vYmplY3RUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZGF0YVByb3RlY3Rpb25Qb2xpY3kpLFxuICAgICAgICBLbXNLZXlJZDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5rbXNLZXlJZCksXG4gICAgICAgIExvZ0dyb3VwTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5sb2dHcm91cE5hbWUpLFxuICAgICAgICBSZXRlbnRpb25JbkRheXM6IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucmV0ZW50aW9uSW5EYXlzKSxcbiAgICAgICAgVGFnczogY2RrLmxpc3RNYXBwZXIoY2RrLmNmblRhZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMudGFncyksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkxvZ0dyb3VwUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5Mb2dHcm91cFByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5Mb2dHcm91cFByb3BzPigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZGF0YVByb3RlY3Rpb25Qb2xpY3knLCAnRGF0YVByb3RlY3Rpb25Qb2xpY3knLCBwcm9wZXJ0aWVzLkRhdGFQcm90ZWN0aW9uUG9saWN5ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFueShwcm9wZXJ0aWVzLkRhdGFQcm90ZWN0aW9uUG9saWN5KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdrbXNLZXlJZCcsICdLbXNLZXlJZCcsIHByb3BlcnRpZXMuS21zS2V5SWQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuS21zS2V5SWQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2xvZ0dyb3VwTmFtZScsICdMb2dHcm91cE5hbWUnLCBwcm9wZXJ0aWVzLkxvZ0dyb3VwTmFtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Mb2dHcm91cE5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3JldGVudGlvbkluRGF5cycsICdSZXRlbnRpb25JbkRheXMnLCBwcm9wZXJ0aWVzLlJldGVudGlvbkluRGF5cyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5SZXRlbnRpb25JbkRheXMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3RhZ3MnLCAnVGFncycsIHByb3BlcnRpZXMuVGFncyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldENmblRhZykocHJvcGVydGllcy5UYWdzKSA6IHVuZGVmaW5lZCBhcyBhbnkpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6TG9nczo6TG9nR3JvdXBgXG4gKlxuICogVGhlIGBBV1M6OkxvZ3M6OkxvZ0dyb3VwYCByZXNvdXJjZSBzcGVjaWZpZXMgYSBsb2cgZ3JvdXAuIEEgbG9nIGdyb3VwIGRlZmluZXMgY29tbW9uIHByb3BlcnRpZXMgZm9yIGxvZyBzdHJlYW1zLCBzdWNoIGFzIHRoZWlyIHJldGVudGlvbiBhbmQgYWNjZXNzIGNvbnRyb2wgcnVsZXMuIEVhY2ggbG9nIHN0cmVhbSBtdXN0IGJlbG9uZyB0byBvbmUgbG9nIGdyb3VwLlxuICpcbiAqIFlvdSBjYW4gY3JlYXRlIHVwIHRvIDEsMDAwLDAwMCBsb2cgZ3JvdXBzIHBlciBSZWdpb24gcGVyIGFjY291bnQuIFlvdSBtdXN0IHVzZSB0aGUgZm9sbG93aW5nIGd1aWRlbGluZXMgd2hlbiBuYW1pbmcgYSBsb2cgZ3JvdXA6XG4gKlxuICogLSBMb2cgZ3JvdXAgbmFtZXMgbXVzdCBiZSB1bmlxdWUgd2l0aGluIGEgUmVnaW9uIGZvciBhbiBBV1MgYWNjb3VudC5cbiAqIC0gTG9nIGdyb3VwIG5hbWVzIGNhbiBiZSBiZXR3ZWVuIDEgYW5kIDUxMiBjaGFyYWN0ZXJzIGxvbmcuXG4gKiAtIExvZyBncm91cCBuYW1lcyBjb25zaXN0IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogYS16LCBBLVosIDAtOSwgJ18nICh1bmRlcnNjb3JlKSwgJy0nIChoeXBoZW4pLCAnLycgKGZvcndhcmQgc2xhc2gpLCBhbmQgJy4nIChwZXJpb2QpLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6TG9nczo6TG9nR3JvdXBcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLWxvZ2dyb3VwLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIENmbkxvZ0dyb3VwIGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6TG9nczo6TG9nR3JvdXBcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmbkxvZ0dyb3VwIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5Mb2dHcm91cFByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5Mb2dHcm91cChzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgQVJOIG9mIHRoZSBsb2cgZ3JvdXAsIHN1Y2ggYXMgYGFybjphd3M6bG9nczp1cy13ZXN0LTE6MTIzNDU2Nzg5MDEyOmxvZy1ncm91cDovbXlzdGFjay10ZXN0Z3JvdXAtMTJBQkMxQUIxMkExOipgXG4gICAgICogQGNsb3VkZm9ybWF0aW9uQXR0cmlidXRlIEFyblxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBhdHRyQXJuOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZGF0YSBwcm90ZWN0aW9uIHBvbGljeSBhbmQgYXNzaWducyBpdCB0byB0aGUgbG9nIGdyb3VwLiBBIGRhdGEgcHJvdGVjdGlvbiBwb2xpY3kgY2FuIGhlbHAgc2FmZWd1YXJkIHNlbnNpdGl2ZSBkYXRhIHRoYXQncyBpbmdlc3RlZCBieSB0aGUgbG9nIGdyb3VwIGJ5IGF1ZGl0aW5nIGFuZCBtYXNraW5nIHRoZSBzZW5zaXRpdmUgbG9nIGRhdGEuIFdoZW4gYSB1c2VyIHdobyBkb2VzIG5vdCBoYXZlIHBlcm1pc3Npb24gdG8gdmlldyBtYXNrZWQgZGF0YSB2aWV3cyBhIGxvZyBldmVudCB0aGF0IGluY2x1ZGVzIG1hc2tlZCBkYXRhLCB0aGUgc2Vuc2l0aXZlIGRhdGEgaXMgcmVwbGFjZWQgYnkgYXN0ZXJpc2tzLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24sIGluY2x1ZGluZyBhIGxpc3Qgb2YgdHlwZXMgb2YgZGF0YSB0aGF0IGNhbiBiZSBhdWRpdGVkIGFuZCBtYXNrZWQsIHNlZSBbUHJvdGVjdCBzZW5zaXRpdmUgbG9nIGRhdGEgd2l0aCBtYXNraW5nXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRXYXRjaC9sYXRlc3QvbG9ncy9tYXNrLXNlbnNpdGl2ZS1sb2ctZGF0YS5odG1sKSAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLWxvZ2dyb3VwLmh0bWwjY2ZuLWxvZ3MtbG9nZ3JvdXAtZGF0YXByb3RlY3Rpb25wb2xpY3lcbiAgICAgKi9cbiAgICBwdWJsaWMgZGF0YVByb3RlY3Rpb25Qb2xpY3k6IGFueSB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgQVdTIEtNUyBrZXkgdG8gdXNlIHdoZW4gZW5jcnlwdGluZyBsb2cgZGF0YS5cbiAgICAgKlxuICAgICAqIFRvIGFzc29jaWF0ZSBhbiBBV1MgS01TIGtleSB3aXRoIHRoZSBsb2cgZ3JvdXAsIHNwZWNpZnkgdGhlIEFSTiBvZiB0aGF0IEtNUyBrZXkgaGVyZS4gSWYgeW91IGRvIHNvLCBpbmdlc3RlZCBkYXRhIGlzIGVuY3J5cHRlZCB1c2luZyB0aGlzIGtleS4gVGhpcyBhc3NvY2lhdGlvbiBpcyBzdG9yZWQgYXMgbG9uZyBhcyB0aGUgZGF0YSBlbmNyeXB0ZWQgd2l0aCB0aGUgS01TIGtleSBpcyBzdGlsbCB3aXRoaW4gQ2xvdWRXYXRjaCBMb2dzIC4gVGhpcyBlbmFibGVzIENsb3VkV2F0Y2ggTG9ncyB0byBkZWNyeXB0IHRoaXMgZGF0YSB3aGVuZXZlciBpdCBpcyByZXF1ZXN0ZWQuXG4gICAgICpcbiAgICAgKiBJZiB5b3UgYXR0ZW1wdCB0byBhc3NvY2lhdGUgYSBLTVMga2V5IHdpdGggdGhlIGxvZyBncm91cCBidXQgdGhlIEtNUyBrZXkgZG9lc24ndCBleGlzdCBvciBpcyBkZWFjdGl2YXRlZCwgeW91IHdpbGwgcmVjZWl2ZSBhbiBgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbmAgZXJyb3IuXG4gICAgICpcbiAgICAgKiBMb2cgZ3JvdXAgZGF0YSBpcyBhbHdheXMgZW5jcnlwdGVkIGluIENsb3VkV2F0Y2ggTG9ncyAuIElmIHlvdSBvbWl0IHRoaXMga2V5LCB0aGUgZW5jcnlwdGlvbiBkb2VzIG5vdCB1c2UgQVdTIEtNUyAuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0VuY3J5cHQgbG9nIGRhdGEgaW4gQ2xvdWRXYXRjaCBMb2dzIHVzaW5nIEFXUyBLZXkgTWFuYWdlbWVudCBTZXJ2aWNlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRXYXRjaC9sYXRlc3QvbG9ncy9lbmNyeXB0LWxvZy1kYXRhLWttcy5odG1sKVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1sb2dncm91cC5odG1sI2Nmbi1sb2dzLWxvZ2dyb3VwLWttc2tleWlkXG4gICAgICovXG4gICAgcHVibGljIGttc0tleUlkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgbG9nIGdyb3VwLiBJZiB5b3UgZG9uJ3Qgc3BlY2lmeSBhIG5hbWUsIEFXUyBDbG91ZEZvcm1hdGlvbiBnZW5lcmF0ZXMgYSB1bmlxdWUgSUQgZm9yIHRoZSBsb2cgZ3JvdXAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLWxvZ2dyb3VwLmh0bWwjY2ZuLWxvZ3MtbG9nZ3JvdXAtbG9nZ3JvdXBuYW1lXG4gICAgICovXG4gICAgcHVibGljIGxvZ0dyb3VwTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBkYXlzIHRvIHJldGFpbiB0aGUgbG9nIGV2ZW50cyBpbiB0aGUgc3BlY2lmaWVkIGxvZyBncm91cC4gUG9zc2libGUgdmFsdWVzIGFyZTogMSwgMywgNSwgNywgMTQsIDMwLCA2MCwgOTAsIDEyMCwgMTUwLCAxODAsIDM2NSwgNDAwLCA1NDUsIDczMSwgMTA5NiwgMTgyNywgMjE5MiwgMjU1NywgMjkyMiwgMzI4OCwgYW5kIDM2NTMuXG4gICAgICpcbiAgICAgKiBUbyBzZXQgYSBsb2cgZ3JvdXAgc28gdGhhdCBpdHMgbG9nIGV2ZW50cyBkbyBub3QgZXhwaXJlLCB1c2UgW0RlbGV0ZVJldGVudGlvblBvbGljeV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2hMb2dzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZVJldGVudGlvblBvbGljeS5odG1sKSAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLWxvZ2dyb3VwLmh0bWwjY2ZuLWxvZ3MtbG9nZ3JvdXAtcmV0ZW50aW9uaW5kYXlzXG4gICAgICovXG4gICAgcHVibGljIHJldGVudGlvbkluRGF5czogbnVtYmVyIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQW4gYXJyYXkgb2Yga2V5LXZhbHVlIHBhaXJzIHRvIGFwcGx5IHRvIHRoZSBsb2cgZ3JvdXAuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtUYWddKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJlc291cmNlLXRhZ3MuaHRtbCkgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1sb2dncm91cC5odG1sI2Nmbi1sb2dzLWxvZ2dyb3VwLXRhZ3NcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgdGFnczogY2RrLlRhZ01hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6TG9nczo6TG9nR3JvdXBgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNjb3BlIC0gc2NvcGUgaW4gd2hpY2ggdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkXG4gICAgICogQHBhcmFtIGlkICAgIC0gc2NvcGVkIGlkIG9mIHRoZSByZXNvdXJjZVxuICAgICAqIEBwYXJhbSBwcm9wcyAtIHJlc291cmNlIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENmbkxvZ0dyb3VwUHJvcHMgPSB7fSkge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuTG9nR3JvdXAuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIHRoaXMuYXR0ckFybiA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnQXJuJykpO1xuXG4gICAgICAgIHRoaXMuZGF0YVByb3RlY3Rpb25Qb2xpY3kgPSBwcm9wcy5kYXRhUHJvdGVjdGlvblBvbGljeTtcbiAgICAgICAgdGhpcy5rbXNLZXlJZCA9IHByb3BzLmttc0tleUlkO1xuICAgICAgICB0aGlzLmxvZ0dyb3VwTmFtZSA9IHByb3BzLmxvZ0dyb3VwTmFtZTtcbiAgICAgICAgdGhpcy5yZXRlbnRpb25JbkRheXMgPSBwcm9wcy5yZXRlbnRpb25JbkRheXM7XG4gICAgICAgIHRoaXMudGFncyA9IG5ldyBjZGsuVGFnTWFuYWdlcihjZGsuVGFnVHlwZS5TVEFOREFSRCwgXCJBV1M6OkxvZ3M6OkxvZ0dyb3VwXCIsIHByb3BzLnRhZ3MsIHsgdGFnUHJvcGVydHlOYW1lOiAndGFncycgfSk7XG4gICAgICAgIGlmICh0aGlzLm5vZGUuc2NvcGUgJiYgY2RrLlJlc291cmNlLmlzUmVzb3VyY2UodGhpcy5ub2RlLnNjb3BlKSkge1xuICAgICAgICAgICAgdGhpcy5ub2RlLmFkZFZhbGlkYXRpb24oeyB2YWxpZGF0ZTogKCkgPT4gdGhpcy5jZm5PcHRpb25zLmRlbGV0aW9uUG9saWN5ID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgPyBbJ1xcJ0FXUzo6TG9nczo6TG9nR3JvdXBcXCcgaXMgYSBzdGF0ZWZ1bCByZXNvdXJjZSB0eXBlLCBhbmQgeW91IG11c3Qgc3BlY2lmeSBhIFJlbW92YWwgUG9saWN5IGZvciBpdC4gQ2FsbCBcXCdyZXNvdXJjZS5hcHBseVJlbW92YWxQb2xpY3koKVxcJy4nXVxuICAgICAgICAgICAgICA6IFtdIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5Mb2dHcm91cC5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FKTtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246cHJvcHNcIiwgdGhpcy5jZm5Qcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGNmblByb3BlcnRpZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZGF0YVByb3RlY3Rpb25Qb2xpY3k6IHRoaXMuZGF0YVByb3RlY3Rpb25Qb2xpY3ksXG4gICAgICAgICAgICBrbXNLZXlJZDogdGhpcy5rbXNLZXlJZCxcbiAgICAgICAgICAgIGxvZ0dyb3VwTmFtZTogdGhpcy5sb2dHcm91cE5hbWUsXG4gICAgICAgICAgICByZXRlbnRpb25JbkRheXM6IHRoaXMucmV0ZW50aW9uSW5EYXlzLFxuICAgICAgICAgICAgdGFnczogdGhpcy50YWdzLnJlbmRlclRhZ3MoKSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5Mb2dHcm91cFByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wcyk7XG4gICAgfVxufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmbkxvZ1N0cmVhbWBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1sb2dzdHJlYW0uaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENmbkxvZ1N0cmVhbVByb3BzIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBsb2cgZ3JvdXAgd2hlcmUgdGhlIGxvZyBzdHJlYW0gaXMgY3JlYXRlZC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtbG9nc3RyZWFtLmh0bWwjY2ZuLWxvZ3MtbG9nc3RyZWFtLWxvZ2dyb3VwbmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IGxvZ0dyb3VwTmFtZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGxvZyBzdHJlYW0uIFRoZSBuYW1lIG11c3QgYmUgdW5pcXVlIHdpdGhpbiB0aGUgbG9nIGdyb3VwLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1sb2dzdHJlYW0uaHRtbCNjZm4tbG9ncy1sb2dzdHJlYW0tbG9nc3RyZWFtbmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IGxvZ1N0cmVhbU5hbWU/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgQ2ZuTG9nU3RyZWFtUHJvcHNgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbkxvZ1N0cmVhbVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmbkxvZ1N0cmVhbVByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbG9nR3JvdXBOYW1lJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmxvZ0dyb3VwTmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbG9nR3JvdXBOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmxvZ0dyb3VwTmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbG9nU3RyZWFtTmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5sb2dTdHJlYW1OYW1lKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNmbkxvZ1N0cmVhbVByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpMb2dzOjpMb2dTdHJlYW1gIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbkxvZ1N0cmVhbVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpMb2dzOjpMb2dTdHJlYW1gIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuTG9nU3RyZWFtUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbkxvZ1N0cmVhbVByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBMb2dHcm91cE5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubG9nR3JvdXBOYW1lKSxcbiAgICAgICAgTG9nU3RyZWFtTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5sb2dTdHJlYW1OYW1lKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuTG9nU3RyZWFtUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5Mb2dTdHJlYW1Qcm9wcz4ge1xuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuTG9nU3RyZWFtUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdsb2dHcm91cE5hbWUnLCAnTG9nR3JvdXBOYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Mb2dHcm91cE5hbWUpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2xvZ1N0cmVhbU5hbWUnLCAnTG9nU3RyZWFtTmFtZScsIHByb3BlcnRpZXMuTG9nU3RyZWFtTmFtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Mb2dTdHJlYW1OYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpMb2dzOjpMb2dTdHJlYW1gXG4gKlxuICogVGhlIGBBV1M6OkxvZ3M6OkxvZ1N0cmVhbWAgcmVzb3VyY2Ugc3BlY2lmaWVzIGFuIEFtYXpvbiBDbG91ZFdhdGNoIExvZ3MgbG9nIHN0cmVhbSBpbiBhIHNwZWNpZmljIGxvZyBncm91cC4gQSBsb2cgc3RyZWFtIHJlcHJlc2VudHMgdGhlIHNlcXVlbmNlIG9mIGV2ZW50cyBjb21pbmcgZnJvbSBhbiBhcHBsaWNhdGlvbiBpbnN0YW5jZSBvciByZXNvdXJjZSB0aGF0IHlvdSBhcmUgbW9uaXRvcmluZy5cbiAqXG4gKiBUaGVyZSBpcyBubyBsaW1pdCBvbiB0aGUgbnVtYmVyIG9mIGxvZyBzdHJlYW1zIHRoYXQgeW91IGNhbiBjcmVhdGUgZm9yIGEgbG9nIGdyb3VwLlxuICpcbiAqIFlvdSBtdXN0IHVzZSB0aGUgZm9sbG93aW5nIGd1aWRlbGluZXMgd2hlbiBuYW1pbmcgYSBsb2cgc3RyZWFtOlxuICpcbiAqIC0gTG9nIHN0cmVhbSBuYW1lcyBtdXN0IGJlIHVuaXF1ZSB3aXRoaW4gdGhlIGxvZyBncm91cC5cbiAqIC0gTG9nIHN0cmVhbSBuYW1lcyBjYW4gYmUgYmV0d2VlbiAxIGFuZCA1MTIgY2hhcmFjdGVycyBsb25nLlxuICogLSBUaGUgJzonIChjb2xvbikgYW5kICcqJyAoYXN0ZXJpc2spIGNoYXJhY3RlcnMgYXJlIG5vdCBhbGxvd2VkLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6TG9nczo6TG9nU3RyZWFtXG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1sb2dzdHJlYW0uaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuTG9nU3RyZWFtIGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6TG9nczo6TG9nU3RyZWFtXCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5Mb2dTdHJlYW0ge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmbkxvZ1N0cmVhbVByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5Mb2dTdHJlYW0oc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGxvZyBncm91cCB3aGVyZSB0aGUgbG9nIHN0cmVhbSBpcyBjcmVhdGVkLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1sb2dzdHJlYW0uaHRtbCNjZm4tbG9ncy1sb2dzdHJlYW0tbG9nZ3JvdXBuYW1lXG4gICAgICovXG4gICAgcHVibGljIGxvZ0dyb3VwTmFtZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGxvZyBzdHJlYW0uIFRoZSBuYW1lIG11c3QgYmUgdW5pcXVlIHdpdGhpbiB0aGUgbG9nIGdyb3VwLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1sb2dzdHJlYW0uaHRtbCNjZm4tbG9ncy1sb2dzdHJlYW0tbG9nc3RyZWFtbmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyBsb2dTdHJlYW1OYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6TG9nczo6TG9nU3RyZWFtYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5Mb2dTdHJlYW1Qcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuTG9nU3RyZWFtLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUsIHByb3BlcnRpZXM6IHByb3BzIH0pO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAnbG9nR3JvdXBOYW1lJywgdGhpcyk7XG5cbiAgICAgICAgdGhpcy5sb2dHcm91cE5hbWUgPSBwcm9wcy5sb2dHcm91cE5hbWU7XG4gICAgICAgIHRoaXMubG9nU3RyZWFtTmFtZSA9IHByb3BzLmxvZ1N0cmVhbU5hbWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5Mb2dTdHJlYW0uQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGxvZ0dyb3VwTmFtZTogdGhpcy5sb2dHcm91cE5hbWUsXG4gICAgICAgICAgICBsb2dTdHJlYW1OYW1lOiB0aGlzLmxvZ1N0cmVhbU5hbWUsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlbmRlclByb3BlcnRpZXMocHJvcHM6IHtba2V5OiBzdHJpbmddOiBhbnl9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4gY2ZuTG9nU3RyZWFtUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuTWV0cmljRmlsdGVyYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLW1ldHJpY2ZpbHRlci5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2ZuTWV0cmljRmlsdGVyUHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogQSBmaWx0ZXIgcGF0dGVybiBmb3IgZXh0cmFjdGluZyBtZXRyaWMgZGF0YSBvdXQgb2YgaW5nZXN0ZWQgbG9nIGV2ZW50cy4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbRmlsdGVyIGFuZCBQYXR0ZXJuIFN5bnRheF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L2xvZ3MvRmlsdGVyQW5kUGF0dGVyblN5bnRheC5odG1sKSAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLW1ldHJpY2ZpbHRlci5odG1sI2Nmbi1sb2dzLW1ldHJpY2ZpbHRlci1maWx0ZXJwYXR0ZXJuXG4gICAgICovXG4gICAgcmVhZG9ubHkgZmlsdGVyUGF0dGVybjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgYW4gZXhpc3RpbmcgbG9nIGdyb3VwIHRoYXQgeW91IHdhbnQgdG8gYXNzb2NpYXRlIHdpdGggdGhpcyBtZXRyaWMgZmlsdGVyLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1tZXRyaWNmaWx0ZXIuaHRtbCNjZm4tbG9ncy1tZXRyaWNmaWx0ZXItbG9nZ3JvdXBuYW1lXG4gICAgICovXG4gICAgcmVhZG9ubHkgbG9nR3JvdXBOYW1lOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWV0cmljIHRyYW5zZm9ybWF0aW9ucy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtbWV0cmljZmlsdGVyLmh0bWwjY2ZuLWxvZ3MtbWV0cmljZmlsdGVyLW1ldHJpY3RyYW5zZm9ybWF0aW9uc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IG1ldHJpY1RyYW5zZm9ybWF0aW9uczogQXJyYXk8Q2ZuTWV0cmljRmlsdGVyLk1ldHJpY1RyYW5zZm9ybWF0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG1ldHJpYyBmaWx0ZXIuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLW1ldHJpY2ZpbHRlci5odG1sI2Nmbi1sb2dzLW1ldHJpY2ZpbHRlci1maWx0ZXJuYW1lXG4gICAgICovXG4gICAgcmVhZG9ubHkgZmlsdGVyTmFtZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDZm5NZXRyaWNGaWx0ZXJQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuTWV0cmljRmlsdGVyUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuTWV0cmljRmlsdGVyUHJvcHNWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdmaWx0ZXJOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmZpbHRlck5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2ZpbHRlclBhdHRlcm4nLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMuZmlsdGVyUGF0dGVybikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZmlsdGVyUGF0dGVybicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5maWx0ZXJQYXR0ZXJuKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdsb2dHcm91cE5hbWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMubG9nR3JvdXBOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdsb2dHcm91cE5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMubG9nR3JvdXBOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdtZXRyaWNUcmFuc2Zvcm1hdGlvbnMnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMubWV0cmljVHJhbnNmb3JtYXRpb25zKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdtZXRyaWNUcmFuc2Zvcm1hdGlvbnMnLCBjZGsubGlzdFZhbGlkYXRvcihDZm5NZXRyaWNGaWx0ZXJfTWV0cmljVHJhbnNmb3JtYXRpb25Qcm9wZXJ0eVZhbGlkYXRvcikpKHByb3BlcnRpZXMubWV0cmljVHJhbnNmb3JtYXRpb25zKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNmbk1ldHJpY0ZpbHRlclByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpMb2dzOjpNZXRyaWNGaWx0ZXJgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbk1ldHJpY0ZpbHRlclByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpMb2dzOjpNZXRyaWNGaWx0ZXJgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuTWV0cmljRmlsdGVyUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbk1ldHJpY0ZpbHRlclByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBGaWx0ZXJQYXR0ZXJuOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmZpbHRlclBhdHRlcm4pLFxuICAgICAgICBMb2dHcm91cE5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubG9nR3JvdXBOYW1lKSxcbiAgICAgICAgTWV0cmljVHJhbnNmb3JtYXRpb25zOiBjZGsubGlzdE1hcHBlcihjZm5NZXRyaWNGaWx0ZXJNZXRyaWNUcmFuc2Zvcm1hdGlvblByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5tZXRyaWNUcmFuc2Zvcm1hdGlvbnMpLFxuICAgICAgICBGaWx0ZXJOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmZpbHRlck5hbWUpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5NZXRyaWNGaWx0ZXJQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbk1ldHJpY0ZpbHRlclByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5NZXRyaWNGaWx0ZXJQcm9wcz4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2ZpbHRlclBhdHRlcm4nLCAnRmlsdGVyUGF0dGVybicsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuRmlsdGVyUGF0dGVybikpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbG9nR3JvdXBOYW1lJywgJ0xvZ0dyb3VwTmFtZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuTG9nR3JvdXBOYW1lKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdtZXRyaWNUcmFuc2Zvcm1hdGlvbnMnLCAnTWV0cmljVHJhbnNmb3JtYXRpb25zJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5NZXRyaWNGaWx0ZXJNZXRyaWNUcmFuc2Zvcm1hdGlvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLk1ldHJpY1RyYW5zZm9ybWF0aW9ucykpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZmlsdGVyTmFtZScsICdGaWx0ZXJOYW1lJywgcHJvcGVydGllcy5GaWx0ZXJOYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkZpbHRlck5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBBIENsb3VkRm9ybWF0aW9uIGBBV1M6OkxvZ3M6Ok1ldHJpY0ZpbHRlcmBcbiAqXG4gKiBUaGUgYEFXUzo6TG9nczo6TWV0cmljRmlsdGVyYCByZXNvdXJjZSBzcGVjaWZpZXMgYSBtZXRyaWMgZmlsdGVyIHRoYXQgZGVzY3JpYmVzIGhvdyBDbG91ZFdhdGNoIExvZ3MgZXh0cmFjdHMgaW5mb3JtYXRpb24gZnJvbSBsb2dzIGFuZCB0cmFuc2Zvcm1zIGl0IGludG8gQW1hem9uIENsb3VkV2F0Y2ggbWV0cmljcy4gSWYgeW91IGhhdmUgbXVsdGlwbGUgbWV0cmljIGZpbHRlcnMgdGhhdCBhcmUgYXNzb2NpYXRlZCB3aXRoIGEgbG9nIGdyb3VwLCBhbGwgdGhlIGZpbHRlcnMgYXJlIGFwcGxpZWQgdG8gdGhlIGxvZyBzdHJlYW1zIGluIHRoYXQgZ3JvdXAuXG4gKlxuICogVGhlIG1heGltdW0gbnVtYmVyIG9mIG1ldHJpYyBmaWx0ZXJzIHRoYXQgY2FuIGJlIGFzc29jaWF0ZWQgd2l0aCBhIGxvZyBncm91cCBpcyAxMDAuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpMb2dzOjpNZXRyaWNGaWx0ZXJcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLW1ldHJpY2ZpbHRlci5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5NZXRyaWNGaWx0ZXIgZXh0ZW5kcyBjZGsuQ2ZuUmVzb3VyY2UgaW1wbGVtZW50cyBjZGsuSUluc3BlY3RhYmxlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgdHlwZSBuYW1lIGZvciB0aGlzIHJlc291cmNlIGNsYXNzLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSA9IFwiQVdTOjpMb2dzOjpNZXRyaWNGaWx0ZXJcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmbk1ldHJpY0ZpbHRlciB7XG4gICAgICAgIHJlc291cmNlQXR0cmlidXRlcyA9IHJlc291cmNlQXR0cmlidXRlcyB8fCB7fTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VQcm9wZXJ0aWVzID0gb3B0aW9ucy5wYXJzZXIucGFyc2VWYWx1ZShyZXNvdXJjZUF0dHJpYnV0ZXMuUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHByb3BzUmVzdWx0ID0gQ2ZuTWV0cmljRmlsdGVyUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmbk1ldHJpY0ZpbHRlcihzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIGZpbHRlciBwYXR0ZXJuIGZvciBleHRyYWN0aW5nIG1ldHJpYyBkYXRhIG91dCBvZiBpbmdlc3RlZCBsb2cgZXZlbnRzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtGaWx0ZXIgYW5kIFBhdHRlcm4gU3ludGF4XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRXYXRjaC9sYXRlc3QvbG9ncy9GaWx0ZXJBbmRQYXR0ZXJuU3ludGF4Lmh0bWwpIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtbWV0cmljZmlsdGVyLmh0bWwjY2ZuLWxvZ3MtbWV0cmljZmlsdGVyLWZpbHRlcnBhdHRlcm5cbiAgICAgKi9cbiAgICBwdWJsaWMgZmlsdGVyUGF0dGVybjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgYW4gZXhpc3RpbmcgbG9nIGdyb3VwIHRoYXQgeW91IHdhbnQgdG8gYXNzb2NpYXRlIHdpdGggdGhpcyBtZXRyaWMgZmlsdGVyLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1tZXRyaWNmaWx0ZXIuaHRtbCNjZm4tbG9ncy1tZXRyaWNmaWx0ZXItbG9nZ3JvdXBuYW1lXG4gICAgICovXG4gICAgcHVibGljIGxvZ0dyb3VwTmFtZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG1ldHJpYyB0cmFuc2Zvcm1hdGlvbnMuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLW1ldHJpY2ZpbHRlci5odG1sI2Nmbi1sb2dzLW1ldHJpY2ZpbHRlci1tZXRyaWN0cmFuc2Zvcm1hdGlvbnNcbiAgICAgKi9cbiAgICBwdWJsaWMgbWV0cmljVHJhbnNmb3JtYXRpb25zOiBBcnJheTxDZm5NZXRyaWNGaWx0ZXIuTWV0cmljVHJhbnNmb3JtYXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgbWV0cmljIGZpbHRlci5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtbWV0cmljZmlsdGVyLmh0bWwjY2ZuLWxvZ3MtbWV0cmljZmlsdGVyLWZpbHRlcm5hbWVcbiAgICAgKi9cbiAgICBwdWJsaWMgZmlsdGVyTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGBBV1M6OkxvZ3M6Ok1ldHJpY0ZpbHRlcmAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuTWV0cmljRmlsdGVyUHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmbk1ldHJpY0ZpbHRlci5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ2ZpbHRlclBhdHRlcm4nLCB0aGlzKTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ2xvZ0dyb3VwTmFtZScsIHRoaXMpO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAnbWV0cmljVHJhbnNmb3JtYXRpb25zJywgdGhpcyk7XG5cbiAgICAgICAgdGhpcy5maWx0ZXJQYXR0ZXJuID0gcHJvcHMuZmlsdGVyUGF0dGVybjtcbiAgICAgICAgdGhpcy5sb2dHcm91cE5hbWUgPSBwcm9wcy5sb2dHcm91cE5hbWU7XG4gICAgICAgIHRoaXMubWV0cmljVHJhbnNmb3JtYXRpb25zID0gcHJvcHMubWV0cmljVHJhbnNmb3JtYXRpb25zO1xuICAgICAgICB0aGlzLmZpbHRlck5hbWUgPSBwcm9wcy5maWx0ZXJOYW1lO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuTWV0cmljRmlsdGVyLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBmaWx0ZXJQYXR0ZXJuOiB0aGlzLmZpbHRlclBhdHRlcm4sXG4gICAgICAgICAgICBsb2dHcm91cE5hbWU6IHRoaXMubG9nR3JvdXBOYW1lLFxuICAgICAgICAgICAgbWV0cmljVHJhbnNmb3JtYXRpb25zOiB0aGlzLm1ldHJpY1RyYW5zZm9ybWF0aW9ucyxcbiAgICAgICAgICAgIGZpbHRlck5hbWU6IHRoaXMuZmlsdGVyTmFtZSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5NZXRyaWNGaWx0ZXJQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcHMpO1xuICAgIH1cbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5NZXRyaWNGaWx0ZXIge1xuICAgIC8qKlxuICAgICAqIFNwZWNpZmllcyB0aGUgQ2xvdWRXYXRjaCBtZXRyaWMgZGltZW5zaW9ucyB0byBwdWJsaXNoIHdpdGggdGhpcyBtZXRyaWMuXG4gICAgICpcbiAgICAgKiBCZWNhdXNlIGRpbWVuc2lvbnMgYXJlIHBhcnQgb2YgdGhlIHVuaXF1ZSBpZGVudGlmaWVyIGZvciBhIG1ldHJpYywgd2hlbmV2ZXIgYSB1bmlxdWUgZGltZW5zaW9uIG5hbWUvdmFsdWUgcGFpciBpcyBleHRyYWN0ZWQgZnJvbSB5b3VyIGxvZ3MsIHlvdSBhcmUgY3JlYXRpbmcgYSBuZXcgdmFyaWF0aW9uIG9mIHRoYXQgbWV0cmljLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgcHVibGlzaGluZyBkaW1lbnNpb25zIHdpdGggbWV0cmljcyBjcmVhdGVkIGJ5IG1ldHJpYyBmaWx0ZXJzLCBzZWUgW1B1Ymxpc2hpbmcgZGltZW5zaW9ucyB3aXRoIG1ldHJpY3MgZnJvbSB2YWx1ZXMgaW4gSlNPTiBvciBzcGFjZS1kZWxpbWl0ZWQgbG9nIGV2ZW50c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L2xvZ3MvRmlsdGVyQW5kUGF0dGVyblN5bnRheC5odG1sI2xvZ3MtbWV0cmljLWZpbHRlcnMtZGltZW5zaW9ucykgLlxuICAgICAqXG4gICAgICogPiBNZXRyaWNzIGV4dHJhY3RlZCBmcm9tIGxvZyBldmVudHMgYXJlIGNoYXJnZWQgYXMgY3VzdG9tIG1ldHJpY3MuIFRvIHByZXZlbnQgdW5leHBlY3RlZCBoaWdoIGNoYXJnZXMsIGRvIG5vdCBzcGVjaWZ5IGhpZ2gtY2FyZGluYWxpdHkgZmllbGRzIHN1Y2ggYXMgYElQQWRkcmVzc2Agb3IgYHJlcXVlc3RJRGAgYXMgZGltZW5zaW9ucy4gRWFjaCBkaWZmZXJlbnQgdmFsdWUgZm91bmQgZm9yIGEgZGltZW5zaW9uIGlzIHRyZWF0ZWQgYXMgYSBzZXBhcmF0ZSBtZXRyaWMgYW5kIGFjY3J1ZXMgY2hhcmdlcyBhcyBhIHNlcGFyYXRlIGN1c3RvbSBtZXRyaWMuXG4gICAgICogPlxuICAgICAqID4gVG8gaGVscCBwcmV2ZW50IGFjY2lkZW50YWwgaGlnaCBjaGFyZ2VzLCBBbWF6b24gZGlzYWJsZXMgYSBtZXRyaWMgZmlsdGVyIGlmIGl0IGdlbmVyYXRlcyAxMDAwIGRpZmZlcmVudCBuYW1lL3ZhbHVlIHBhaXJzIGZvciB0aGUgZGltZW5zaW9ucyB0aGF0IHlvdSBoYXZlIHNwZWNpZmllZCB3aXRoaW4gYSBjZXJ0YWluIGFtb3VudCBvZiB0aW1lLlxuICAgICAqID5cbiAgICAgKiA+IFlvdSBjYW4gYWxzbyBzZXQgdXAgYSBiaWxsaW5nIGFsYXJtIHRvIGFsZXJ0IHlvdSBpZiB5b3VyIGNoYXJnZXMgYXJlIGhpZ2hlciB0aGFuIGV4cGVjdGVkLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtDcmVhdGluZyBhIEJpbGxpbmcgQWxhcm0gdG8gTW9uaXRvciBZb3VyIEVzdGltYXRlZCBBV1MgQ2hhcmdlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L21vbml0b3JpbmcvbW9uaXRvcl9lc3RpbWF0ZWRfY2hhcmdlc193aXRoX2Nsb3Vkd2F0Y2guaHRtbCkgLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtbG9ncy1tZXRyaWNmaWx0ZXItZGltZW5zaW9uLmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIERpbWVuc2lvblByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBuYW1lIGZvciB0aGUgQ2xvdWRXYXRjaCBtZXRyaWMgZGltZW5zaW9uIHRoYXQgdGhlIG1ldHJpYyBmaWx0ZXIgY3JlYXRlcy5cbiAgICAgICAgICpcbiAgICAgICAgICogRGltZW5zaW9uIG5hbWVzIG11c3QgY29udGFpbiBvbmx5IEFTQ0lJIGNoYXJhY3RlcnMsIG11c3QgaW5jbHVkZSBhdCBsZWFzdCBvbmUgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVyLCBhbmQgY2Fubm90IHN0YXJ0IHdpdGggYSBjb2xvbiAoOikuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtbG9ncy1tZXRyaWNmaWx0ZXItZGltZW5zaW9uLmh0bWwjY2ZuLWxvZ3MtbWV0cmljZmlsdGVyLWRpbWVuc2lvbi1rZXlcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGtleTogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGxvZyBldmVudCBmaWVsZCB0aGF0IHdpbGwgY29udGFpbiB0aGUgdmFsdWUgZm9yIHRoaXMgZGltZW5zaW9uLiBUaGlzIGRpbWVuc2lvbiB3aWxsIG9ubHkgYmUgcHVibGlzaGVkIGZvciBhIG1ldHJpYyBpZiB0aGUgdmFsdWUgaXMgZm91bmQgaW4gdGhlIGxvZyBldmVudC4gRm9yIGV4YW1wbGUsIGAkLmV2ZW50VHlwZWAgZm9yIEpTT04gbG9nIGV2ZW50cywgb3IgYCRzZXJ2ZXJgIGZvciBzcGFjZS1kZWxpbWl0ZWQgbG9nIGV2ZW50cy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1sb2dzLW1ldHJpY2ZpbHRlci1kaW1lbnNpb24uaHRtbCNjZm4tbG9ncy1tZXRyaWNmaWx0ZXItZGltZW5zaW9uLXZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB2YWx1ZTogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBEaW1lbnNpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgRGltZW5zaW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuTWV0cmljRmlsdGVyX0RpbWVuc2lvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigna2V5JywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmtleSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigna2V5JywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmtleSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndmFsdWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMudmFsdWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3ZhbHVlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnZhbHVlKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkRpbWVuc2lvblByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpMb2dzOjpNZXRyaWNGaWx0ZXIuRGltZW5zaW9uYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBEaW1lbnNpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6TG9nczo6TWV0cmljRmlsdGVyLkRpbWVuc2lvbmAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5NZXRyaWNGaWx0ZXJEaW1lbnNpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuTWV0cmljRmlsdGVyX0RpbWVuc2lvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBLZXk6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMua2V5KSxcbiAgICAgICAgVmFsdWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMudmFsdWUpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5NZXRyaWNGaWx0ZXJEaW1lbnNpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbk1ldHJpY0ZpbHRlci5EaW1lbnNpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5NZXRyaWNGaWx0ZXIuRGltZW5zaW9uUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdrZXknLCAnS2V5JywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5LZXkpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3ZhbHVlJywgJ1ZhbHVlJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5WYWx1ZSkpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmbk1ldHJpY0ZpbHRlciB7XG4gICAgLyoqXG4gICAgICogYE1ldHJpY1RyYW5zZm9ybWF0aW9uYCBpcyBhIHByb3BlcnR5IG9mIHRoZSBgQVdTOjpMb2dzOjpNZXRyaWNGaWx0ZXJgIHJlc291cmNlIHRoYXQgZGVzY3JpYmVzIGhvdyB0byB0cmFuc2Zvcm0gbG9nIHN0cmVhbXMgaW50byBhIENsb3VkV2F0Y2ggbWV0cmljLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtbG9ncy1tZXRyaWNmaWx0ZXItbWV0cmljdHJhbnNmb3JtYXRpb24uaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgTWV0cmljVHJhbnNmb3JtYXRpb25Qcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiAoT3B0aW9uYWwpIFRoZSB2YWx1ZSB0byBlbWl0IHdoZW4gYSBmaWx0ZXIgcGF0dGVybiBkb2VzIG5vdCBtYXRjaCBhIGxvZyBldmVudC4gVGhpcyB2YWx1ZSBjYW4gYmUgbnVsbC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1sb2dzLW1ldHJpY2ZpbHRlci1tZXRyaWN0cmFuc2Zvcm1hdGlvbi5odG1sI2Nmbi1sb2dzLW1ldHJpY2ZpbHRlci1tZXRyaWN0cmFuc2Zvcm1hdGlvbi1kZWZhdWx0dmFsdWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGRlZmF1bHRWYWx1ZT86IG51bWJlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBmaWVsZHMgdG8gdXNlIGFzIGRpbWVuc2lvbnMgZm9yIHRoZSBtZXRyaWMuIE9uZSBtZXRyaWMgZmlsdGVyIGNhbiBpbmNsdWRlIGFzIG1hbnkgYXMgdGhyZWUgZGltZW5zaW9ucy5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBNZXRyaWNzIGV4dHJhY3RlZCBmcm9tIGxvZyBldmVudHMgYXJlIGNoYXJnZWQgYXMgY3VzdG9tIG1ldHJpY3MuIFRvIHByZXZlbnQgdW5leHBlY3RlZCBoaWdoIGNoYXJnZXMsIGRvIG5vdCBzcGVjaWZ5IGhpZ2gtY2FyZGluYWxpdHkgZmllbGRzIHN1Y2ggYXMgYElQQWRkcmVzc2Agb3IgYHJlcXVlc3RJRGAgYXMgZGltZW5zaW9ucy4gRWFjaCBkaWZmZXJlbnQgdmFsdWUgZm91bmQgZm9yIGEgZGltZW5zaW9uIGlzIHRyZWF0ZWQgYXMgYSBzZXBhcmF0ZSBtZXRyaWMgYW5kIGFjY3J1ZXMgY2hhcmdlcyBhcyBhIHNlcGFyYXRlIGN1c3RvbSBtZXRyaWMuXG4gICAgICAgICAqID5cbiAgICAgICAgICogPiBDbG91ZFdhdGNoIExvZ3MgZGlzYWJsZXMgYSBtZXRyaWMgZmlsdGVyIGlmIGl0IGdlbmVyYXRlcyAxMDAwIGRpZmZlcmVudCBuYW1lL3ZhbHVlIHBhaXJzIGZvciB5b3VyIHNwZWNpZmllZCBkaW1lbnNpb25zIHdpdGhpbiBhIGNlcnRhaW4gYW1vdW50IG9mIHRpbWUuIFRoaXMgaGVscHMgdG8gcHJldmVudCBhY2NpZGVudGFsIGhpZ2ggY2hhcmdlcy5cbiAgICAgICAgICogPlxuICAgICAgICAgKiA+IFlvdSBjYW4gYWxzbyBzZXQgdXAgYSBiaWxsaW5nIGFsYXJtIHRvIGFsZXJ0IHlvdSBpZiB5b3VyIGNoYXJnZXMgYXJlIGhpZ2hlciB0aGFuIGV4cGVjdGVkLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtDcmVhdGluZyBhIEJpbGxpbmcgQWxhcm0gdG8gTW9uaXRvciBZb3VyIEVzdGltYXRlZCBBV1MgQ2hhcmdlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L21vbml0b3JpbmcvbW9uaXRvcl9lc3RpbWF0ZWRfY2hhcmdlc193aXRoX2Nsb3Vkd2F0Y2guaHRtbCkgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWxvZ3MtbWV0cmljZmlsdGVyLW1ldHJpY3RyYW5zZm9ybWF0aW9uLmh0bWwjY2ZuLWxvZ3MtbWV0cmljZmlsdGVyLW1ldHJpY3RyYW5zZm9ybWF0aW9uLWRpbWVuc2lvbnNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGRpbWVuc2lvbnM/OiBBcnJheTxDZm5NZXRyaWNGaWx0ZXIuRGltZW5zaW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5hbWUgb2YgdGhlIENsb3VkV2F0Y2ggbWV0cmljLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWxvZ3MtbWV0cmljZmlsdGVyLW1ldHJpY3RyYW5zZm9ybWF0aW9uLmh0bWwjY2ZuLWxvZ3MtbWV0cmljZmlsdGVyLW1ldHJpY3RyYW5zZm9ybWF0aW9uLW1ldHJpY25hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IG1ldHJpY05hbWU6IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgY3VzdG9tIG5hbWVzcGFjZSB0byBjb250YWluIHlvdXIgbWV0cmljIGluIENsb3VkV2F0Y2guIFVzZSBuYW1lc3BhY2VzIHRvIGdyb3VwIHRvZ2V0aGVyIG1ldHJpY3MgdGhhdCBhcmUgc2ltaWxhci4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbTmFtZXNwYWNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L21vbml0b3JpbmcvY2xvdWR3YXRjaF9jb25jZXB0cy5odG1sI05hbWVzcGFjZSkgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWxvZ3MtbWV0cmljZmlsdGVyLW1ldHJpY3RyYW5zZm9ybWF0aW9uLmh0bWwjY2ZuLWxvZ3MtbWV0cmljZmlsdGVyLW1ldHJpY3RyYW5zZm9ybWF0aW9uLW1ldHJpY25hbWVzcGFjZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbWV0cmljTmFtZXNwYWNlOiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdmFsdWUgdGhhdCBpcyBwdWJsaXNoZWQgdG8gdGhlIENsb3VkV2F0Y2ggbWV0cmljLiBGb3IgZXhhbXBsZSwgaWYgeW91J3JlIGNvdW50aW5nIHRoZSBvY2N1cnJlbmNlcyBvZiBhIHBhcnRpY3VsYXIgdGVybSBsaWtlIGBFcnJvcmAgLCBzcGVjaWZ5IDEgZm9yIHRoZSBtZXRyaWMgdmFsdWUuIElmIHlvdSdyZSBjb3VudGluZyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRyYW5zZmVycmVkLCByZWZlcmVuY2UgdGhlIHZhbHVlIHRoYXQgaXMgaW4gdGhlIGxvZyBldmVudCBieSB1c2luZyAkLiBmb2xsb3dlZCBieSB0aGUgbmFtZSBvZiB0aGUgZmllbGQgdGhhdCB5b3Ugc3BlY2lmaWVkIGluIHRoZSBmaWx0ZXIgcGF0dGVybiwgc3VjaCBhcyBgJC5zaXplYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtbG9ncy1tZXRyaWNmaWx0ZXItbWV0cmljdHJhbnNmb3JtYXRpb24uaHRtbCNjZm4tbG9ncy1tZXRyaWNmaWx0ZXItbWV0cmljdHJhbnNmb3JtYXRpb24tbWV0cmljdmFsdWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IG1ldHJpY1ZhbHVlOiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdW5pdCB0byBhc3NpZ24gdG8gdGhlIG1ldHJpYy4gSWYgeW91IG9taXQgdGhpcywgdGhlIHVuaXQgaXMgc2V0IGFzIGBOb25lYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtbG9ncy1tZXRyaWNmaWx0ZXItbWV0cmljdHJhbnNmb3JtYXRpb24uaHRtbCNjZm4tbG9ncy1tZXRyaWNmaWx0ZXItbWV0cmljdHJhbnNmb3JtYXRpb24tdW5pdFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgdW5pdD86IHN0cmluZztcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgTWV0cmljVHJhbnNmb3JtYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgTWV0cmljVHJhbnNmb3JtYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5NZXRyaWNGaWx0ZXJfTWV0cmljVHJhbnNmb3JtYXRpb25Qcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2RlZmF1bHRWYWx1ZScsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5kZWZhdWx0VmFsdWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2RpbWVuc2lvbnMnLCBjZGsubGlzdFZhbGlkYXRvcihDZm5NZXRyaWNGaWx0ZXJfRGltZW5zaW9uUHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLmRpbWVuc2lvbnMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ21ldHJpY05hbWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMubWV0cmljTmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbWV0cmljTmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5tZXRyaWNOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdtZXRyaWNOYW1lc3BhY2UnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMubWV0cmljTmFtZXNwYWNlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdtZXRyaWNOYW1lc3BhY2UnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMubWV0cmljTmFtZXNwYWNlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdtZXRyaWNWYWx1ZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5tZXRyaWNWYWx1ZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbWV0cmljVmFsdWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMubWV0cmljVmFsdWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3VuaXQnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMudW5pdCkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJNZXRyaWNUcmFuc2Zvcm1hdGlvblByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpMb2dzOjpNZXRyaWNGaWx0ZXIuTWV0cmljVHJhbnNmb3JtYXRpb25gIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYE1ldHJpY1RyYW5zZm9ybWF0aW9uUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkxvZ3M6Ok1ldHJpY0ZpbHRlci5NZXRyaWNUcmFuc2Zvcm1hdGlvbmAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5NZXRyaWNGaWx0ZXJNZXRyaWNUcmFuc2Zvcm1hdGlvblByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5NZXRyaWNGaWx0ZXJfTWV0cmljVHJhbnNmb3JtYXRpb25Qcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgRGVmYXVsdFZhbHVlOiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmRlZmF1bHRWYWx1ZSksXG4gICAgICAgIERpbWVuc2lvbnM6IGNkay5saXN0TWFwcGVyKGNmbk1ldHJpY0ZpbHRlckRpbWVuc2lvblByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5kaW1lbnNpb25zKSxcbiAgICAgICAgTWV0cmljTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5tZXRyaWNOYW1lKSxcbiAgICAgICAgTWV0cmljTmFtZXNwYWNlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm1ldHJpY05hbWVzcGFjZSksXG4gICAgICAgIE1ldHJpY1ZhbHVlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm1ldHJpY1ZhbHVlKSxcbiAgICAgICAgVW5pdDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy51bml0KSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuTWV0cmljRmlsdGVyTWV0cmljVHJhbnNmb3JtYXRpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbk1ldHJpY0ZpbHRlci5NZXRyaWNUcmFuc2Zvcm1hdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbk1ldHJpY0ZpbHRlci5NZXRyaWNUcmFuc2Zvcm1hdGlvblByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZGVmYXVsdFZhbHVlJywgJ0RlZmF1bHRWYWx1ZScsIHByb3BlcnRpZXMuRGVmYXVsdFZhbHVlICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLkRlZmF1bHRWYWx1ZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZGltZW5zaW9ucycsICdEaW1lbnNpb25zJywgcHJvcGVydGllcy5EaW1lbnNpb25zICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KENmbk1ldHJpY0ZpbHRlckRpbWVuc2lvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLkRpbWVuc2lvbnMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ21ldHJpY05hbWUnLCAnTWV0cmljTmFtZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuTWV0cmljTmFtZSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbWV0cmljTmFtZXNwYWNlJywgJ01ldHJpY05hbWVzcGFjZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuTWV0cmljTmFtZXNwYWNlKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdtZXRyaWNWYWx1ZScsICdNZXRyaWNWYWx1ZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuTWV0cmljVmFsdWUpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3VuaXQnLCAnVW5pdCcsIHByb3BlcnRpZXMuVW5pdCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Vbml0KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuUXVlcnlEZWZpbml0aW9uYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLXF1ZXJ5ZGVmaW5pdGlvbi5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2ZuUXVlcnlEZWZpbml0aW9uUHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogQSBuYW1lIGZvciB0aGUgcXVlcnkgZGVmaW5pdGlvbi5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtcXVlcnlkZWZpbml0aW9uLmh0bWwjY2ZuLWxvZ3MtcXVlcnlkZWZpbml0aW9uLW5hbWVcbiAgICAgKi9cbiAgICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcXVlcnkgc3RyaW5nIHRvIHVzZSBmb3IgdGhpcyBxdWVyeSBkZWZpbml0aW9uLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtDbG91ZFdhdGNoIExvZ3MgSW5zaWdodHMgUXVlcnkgU3ludGF4XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRXYXRjaC9sYXRlc3QvbG9ncy9DV0xfUXVlcnlTeW50YXguaHRtbCkgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1xdWVyeWRlZmluaXRpb24uaHRtbCNjZm4tbG9ncy1xdWVyeWRlZmluaXRpb24tcXVlcnlzdHJpbmdcbiAgICAgKi9cbiAgICByZWFkb25seSBxdWVyeVN0cmluZzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVXNlIHRoaXMgcGFyYW1ldGVyIGlmIHlvdSB3YW50IHRoZSBxdWVyeSB0byBxdWVyeSBvbmx5IGNlcnRhaW4gbG9nIGdyb3Vwcy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtcXVlcnlkZWZpbml0aW9uLmh0bWwjY2ZuLWxvZ3MtcXVlcnlkZWZpbml0aW9uLWxvZ2dyb3VwbmFtZXNcbiAgICAgKi9cbiAgICByZWFkb25seSBsb2dHcm91cE5hbWVzPzogc3RyaW5nW107XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgQ2ZuUXVlcnlEZWZpbml0aW9uUHJvcHNgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblF1ZXJ5RGVmaW5pdGlvblByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblF1ZXJ5RGVmaW5pdGlvblByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbG9nR3JvdXBOYW1lcycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMubG9nR3JvdXBOYW1lcykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5uYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCduYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLm5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3F1ZXJ5U3RyaW5nJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnF1ZXJ5U3RyaW5nKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdxdWVyeVN0cmluZycsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5xdWVyeVN0cmluZykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5RdWVyeURlZmluaXRpb25Qcm9wc1wiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6TG9nczo6UXVlcnlEZWZpbml0aW9uYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5RdWVyeURlZmluaXRpb25Qcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6TG9nczo6UXVlcnlEZWZpbml0aW9uYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblF1ZXJ5RGVmaW5pdGlvblByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5RdWVyeURlZmluaXRpb25Qcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5uYW1lKSxcbiAgICAgICAgUXVlcnlTdHJpbmc6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucXVlcnlTdHJpbmcpLFxuICAgICAgICBMb2dHcm91cE5hbWVzOiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5sb2dHcm91cE5hbWVzKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuUXVlcnlEZWZpbml0aW9uUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5RdWVyeURlZmluaXRpb25Qcm9wcz4ge1xuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuUXVlcnlEZWZpbml0aW9uUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCduYW1lJywgJ05hbWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLk5hbWUpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3F1ZXJ5U3RyaW5nJywgJ1F1ZXJ5U3RyaW5nJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5RdWVyeVN0cmluZykpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbG9nR3JvdXBOYW1lcycsICdMb2dHcm91cE5hbWVzJywgcHJvcGVydGllcy5Mb2dHcm91cE5hbWVzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuTG9nR3JvdXBOYW1lcykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6TG9nczo6UXVlcnlEZWZpbml0aW9uYFxuICpcbiAqIENyZWF0ZXMgYSBxdWVyeSBkZWZpbml0aW9uIGZvciBDbG91ZFdhdGNoIExvZ3MgSW5zaWdodHMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0FuYWx5emluZyBMb2cgRGF0YSB3aXRoIENsb3VkV2F0Y2ggTG9ncyBJbnNpZ2h0c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L2xvZ3MvQW5hbHl6aW5nTG9nRGF0YS5odG1sKSAuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpMb2dzOjpRdWVyeURlZmluaXRpb25cbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLXF1ZXJ5ZGVmaW5pdGlvbi5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5RdWVyeURlZmluaXRpb24gZXh0ZW5kcyBjZGsuQ2ZuUmVzb3VyY2UgaW1wbGVtZW50cyBjZGsuSUluc3BlY3RhYmxlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgdHlwZSBuYW1lIGZvciB0aGlzIHJlc291cmNlIGNsYXNzLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSA9IFwiQVdTOjpMb2dzOjpRdWVyeURlZmluaXRpb25cIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmblF1ZXJ5RGVmaW5pdGlvbiB7XG4gICAgICAgIHJlc291cmNlQXR0cmlidXRlcyA9IHJlc291cmNlQXR0cmlidXRlcyB8fCB7fTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VQcm9wZXJ0aWVzID0gb3B0aW9ucy5wYXJzZXIucGFyc2VWYWx1ZShyZXNvdXJjZUF0dHJpYnV0ZXMuUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHByb3BzUmVzdWx0ID0gQ2ZuUXVlcnlEZWZpbml0aW9uUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmblF1ZXJ5RGVmaW5pdGlvbihzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgSUQgb2YgdGhlIHF1ZXJ5IGRlZmluaXRpb24uXG4gICAgICogQGNsb3VkZm9ybWF0aW9uQXR0cmlidXRlIFF1ZXJ5RGVmaW5pdGlvbklkXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGF0dHJRdWVyeURlZmluaXRpb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBuYW1lIGZvciB0aGUgcXVlcnkgZGVmaW5pdGlvbi5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtcXVlcnlkZWZpbml0aW9uLmh0bWwjY2ZuLWxvZ3MtcXVlcnlkZWZpbml0aW9uLW5hbWVcbiAgICAgKi9cbiAgICBwdWJsaWMgbmFtZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHF1ZXJ5IHN0cmluZyB0byB1c2UgZm9yIHRoaXMgcXVlcnkgZGVmaW5pdGlvbi4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQ2xvdWRXYXRjaCBMb2dzIEluc2lnaHRzIFF1ZXJ5IFN5bnRheF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L2xvZ3MvQ1dMX1F1ZXJ5U3ludGF4Lmh0bWwpIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtcXVlcnlkZWZpbml0aW9uLmh0bWwjY2ZuLWxvZ3MtcXVlcnlkZWZpbml0aW9uLXF1ZXJ5c3RyaW5nXG4gICAgICovXG4gICAgcHVibGljIHF1ZXJ5U3RyaW5nOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBVc2UgdGhpcyBwYXJhbWV0ZXIgaWYgeW91IHdhbnQgdGhlIHF1ZXJ5IHRvIHF1ZXJ5IG9ubHkgY2VydGFpbiBsb2cgZ3JvdXBzLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1xdWVyeWRlZmluaXRpb24uaHRtbCNjZm4tbG9ncy1xdWVyeWRlZmluaXRpb24tbG9nZ3JvdXBuYW1lc1xuICAgICAqL1xuICAgIHB1YmxpYyBsb2dHcm91cE5hbWVzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpMb2dzOjpRdWVyeURlZmluaXRpb25gLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNjb3BlIC0gc2NvcGUgaW4gd2hpY2ggdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkXG4gICAgICogQHBhcmFtIGlkICAgIC0gc2NvcGVkIGlkIG9mIHRoZSByZXNvdXJjZVxuICAgICAqIEBwYXJhbSBwcm9wcyAtIHJlc291cmNlIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENmblF1ZXJ5RGVmaW5pdGlvblByb3BzKSB7XG4gICAgICAgIHN1cGVyKHNjb3BlLCBpZCwgeyB0eXBlOiBDZm5RdWVyeURlZmluaXRpb24uQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICduYW1lJywgdGhpcyk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICdxdWVyeVN0cmluZycsIHRoaXMpO1xuICAgICAgICB0aGlzLmF0dHJRdWVyeURlZmluaXRpb25JZCA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnUXVlcnlEZWZpbml0aW9uSWQnKSk7XG5cbiAgICAgICAgdGhpcy5uYW1lID0gcHJvcHMubmFtZTtcbiAgICAgICAgdGhpcy5xdWVyeVN0cmluZyA9IHByb3BzLnF1ZXJ5U3RyaW5nO1xuICAgICAgICB0aGlzLmxvZ0dyb3VwTmFtZXMgPSBwcm9wcy5sb2dHcm91cE5hbWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuUXVlcnlEZWZpbml0aW9uLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgICAgICBxdWVyeVN0cmluZzogdGhpcy5xdWVyeVN0cmluZyxcbiAgICAgICAgICAgIGxvZ0dyb3VwTmFtZXM6IHRoaXMubG9nR3JvdXBOYW1lcyxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5RdWVyeURlZmluaXRpb25Qcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcHMpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIGBDZm5SZXNvdXJjZVBvbGljeWBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1yZXNvdXJjZXBvbGljeS5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2ZuUmVzb3VyY2VQb2xpY3lQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZGV0YWlscyBvZiB0aGUgcG9saWN5LiBJdCBtdXN0IGJlIGZvcm1hdHRlZCBpbiBKU09OLCBhbmQgeW91IG11c3QgdXNlIGJhY2tzbGFzaGVzIHRvIGVzY2FwZSBjaGFyYWN0ZXJzIHRoYXQgbmVlZCB0byBiZSBlc2NhcGVkIGluIEpTT04gc3RyaW5ncywgc3VjaCBhcyBkb3VibGUgcXVvdGUgbWFya3MuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLXJlc291cmNlcG9saWN5Lmh0bWwjY2ZuLWxvZ3MtcmVzb3VyY2Vwb2xpY3ktcG9saWN5ZG9jdW1lbnRcbiAgICAgKi9cbiAgICByZWFkb25seSBwb2xpY3lEb2N1bWVudDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIHBvbGljeS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtcmVzb3VyY2Vwb2xpY3kuaHRtbCNjZm4tbG9ncy1yZXNvdXJjZXBvbGljeS1wb2xpY3luYW1lXG4gICAgICovXG4gICAgcmVhZG9ubHkgcG9saWN5TmFtZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmblJlc291cmNlUG9saWN5UHJvcHNgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblJlc291cmNlUG9saWN5UHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuUmVzb3VyY2VQb2xpY3lQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvbGljeURvY3VtZW50JywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnBvbGljeURvY3VtZW50KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwb2xpY3lEb2N1bWVudCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5wb2xpY3lEb2N1bWVudCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWN5TmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5wb2xpY3lOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwb2xpY3lOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnBvbGljeU5hbWUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuUmVzb3VyY2VQb2xpY3lQcm9wc1wiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6TG9nczo6UmVzb3VyY2VQb2xpY3lgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblJlc291cmNlUG9saWN5UHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkxvZ3M6OlJlc291cmNlUG9saWN5YCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblJlc291cmNlUG9saWN5UHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblJlc291cmNlUG9saWN5UHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIFBvbGljeURvY3VtZW50OiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBvbGljeURvY3VtZW50KSxcbiAgICAgICAgUG9saWN5TmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wb2xpY3lOYW1lKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuUmVzb3VyY2VQb2xpY3lQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblJlc291cmNlUG9saWN5UHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblJlc291cmNlUG9saWN5UHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwb2xpY3lEb2N1bWVudCcsICdQb2xpY3lEb2N1bWVudCcsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuUG9saWN5RG9jdW1lbnQpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BvbGljeU5hbWUnLCAnUG9saWN5TmFtZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuUG9saWN5TmFtZSkpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6TG9nczo6UmVzb3VyY2VQb2xpY3lgXG4gKlxuICogQ3JlYXRlcyBvciB1cGRhdGVzIGEgcmVzb3VyY2UgcG9saWN5IHRoYXQgYWxsb3dzIG90aGVyIEFXUyBzZXJ2aWNlcyB0byBwdXQgbG9nIGV2ZW50cyB0byB0aGlzIGFjY291bnQuIEFuIGFjY291bnQgY2FuIGhhdmUgdXAgdG8gMTAgcmVzb3VyY2UgcG9saWNpZXMgcGVyIEFXUyBSZWdpb24uXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpMb2dzOjpSZXNvdXJjZVBvbGljeVxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtcmVzb3VyY2Vwb2xpY3kuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuUmVzb3VyY2VQb2xpY3kgZXh0ZW5kcyBjZGsuQ2ZuUmVzb3VyY2UgaW1wbGVtZW50cyBjZGsuSUluc3BlY3RhYmxlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgdHlwZSBuYW1lIGZvciB0aGlzIHJlc291cmNlIGNsYXNzLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSA9IFwiQVdTOjpMb2dzOjpSZXNvdXJjZVBvbGljeVwiO1xuXG4gICAgLyoqXG4gICAgICogQSBmYWN0b3J5IG1ldGhvZCB0aGF0IGNyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBmcm9tIGFuIG9iamVjdFxuICAgICAqIGNvbnRhaW5pbmcgdGhlIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgdGhpcyByZXNvdXJjZS5cbiAgICAgKiBVc2VkIGluIHRoZSBAYXdzLWNkay9jbG91ZGZvcm1hdGlvbi1pbmNsdWRlIG1vZHVsZS5cbiAgICAgKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgX2Zyb21DbG91ZEZvcm1hdGlvbihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcmVzb3VyY2VBdHRyaWJ1dGVzOiBhbnksIG9wdGlvbnM6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25PcHRpb25zKTogQ2ZuUmVzb3VyY2VQb2xpY3kge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmblJlc291cmNlUG9saWN5UHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmblJlc291cmNlUG9saWN5KHNjb3BlLCBpZCwgcHJvcHNSZXN1bHQudmFsdWUpO1xuICAgICAgICBmb3IgKGNvbnN0IFtwcm9wS2V5LCBwcm9wVmFsXSBvZiBPYmplY3QuZW50cmllcyhwcm9wc1Jlc3VsdC5leHRyYVByb3BlcnRpZXMpKSAge1xuICAgICAgICAgICAgcmV0LmFkZFByb3BlcnR5T3ZlcnJpZGUocHJvcEtleSwgcHJvcFZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5wYXJzZXIuaGFuZGxlQXR0cmlidXRlcyhyZXQsIHJlc291cmNlQXR0cmlidXRlcywgaWQpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBkZXRhaWxzIG9mIHRoZSBwb2xpY3kuIEl0IG11c3QgYmUgZm9ybWF0dGVkIGluIEpTT04sIGFuZCB5b3UgbXVzdCB1c2UgYmFja3NsYXNoZXMgdG8gZXNjYXBlIGNoYXJhY3RlcnMgdGhhdCBuZWVkIHRvIGJlIGVzY2FwZWQgaW4gSlNPTiBzdHJpbmdzLCBzdWNoIGFzIGRvdWJsZSBxdW90ZSBtYXJrcy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtcmVzb3VyY2Vwb2xpY3kuaHRtbCNjZm4tbG9ncy1yZXNvdXJjZXBvbGljeS1wb2xpY3lkb2N1bWVudFxuICAgICAqL1xuICAgIHB1YmxpYyBwb2xpY3lEb2N1bWVudDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIHBvbGljeS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtcmVzb3VyY2Vwb2xpY3kuaHRtbCNjZm4tbG9ncy1yZXNvdXJjZXBvbGljeS1wb2xpY3luYW1lXG4gICAgICovXG4gICAgcHVibGljIHBvbGljeU5hbWU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpMb2dzOjpSZXNvdXJjZVBvbGljeWAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuUmVzb3VyY2VQb2xpY3lQcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuUmVzb3VyY2VQb2xpY3kuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICdwb2xpY3lEb2N1bWVudCcsIHRoaXMpO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAncG9saWN5TmFtZScsIHRoaXMpO1xuXG4gICAgICAgIHRoaXMucG9saWN5RG9jdW1lbnQgPSBwcm9wcy5wb2xpY3lEb2N1bWVudDtcbiAgICAgICAgdGhpcy5wb2xpY3lOYW1lID0gcHJvcHMucG9saWN5TmFtZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmblJlc291cmNlUG9saWN5LkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBwb2xpY3lEb2N1bWVudDogdGhpcy5wb2xpY3lEb2N1bWVudCxcbiAgICAgICAgICAgIHBvbGljeU5hbWU6IHRoaXMucG9saWN5TmFtZSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5SZXNvdXJjZVBvbGljeVByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wcyk7XG4gICAgfVxufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmblN1YnNjcmlwdGlvbkZpbHRlcmBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1zdWJzY3JpcHRpb25maWx0ZXIuaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENmblN1YnNjcmlwdGlvbkZpbHRlclByb3BzIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgZGVzdGluYXRpb24uXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLXN1YnNjcmlwdGlvbmZpbHRlci5odG1sI2Nmbi1sb2dzLXN1YnNjcmlwdGlvbmZpbHRlci1kZXN0aW5hdGlvbmFyblxuICAgICAqL1xuICAgIHJlYWRvbmx5IGRlc3RpbmF0aW9uQXJuOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZmlsdGVyaW5nIGV4cHJlc3Npb25zIHRoYXQgcmVzdHJpY3Qgd2hhdCBnZXRzIGRlbGl2ZXJlZCB0byB0aGUgZGVzdGluYXRpb24gQVdTIHJlc291cmNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZmlsdGVyIHBhdHRlcm4gc3ludGF4LCBzZWUgW0ZpbHRlciBhbmQgUGF0dGVybiBTeW50YXhdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25DbG91ZFdhdGNoL2xhdGVzdC9sb2dzL0ZpbHRlckFuZFBhdHRlcm5TeW50YXguaHRtbCkgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1zdWJzY3JpcHRpb25maWx0ZXIuaHRtbCNjZm4tbG9ncy1zdWJzY3JpcHRpb25maWx0ZXItZmlsdGVycGF0dGVyblxuICAgICAqL1xuICAgIHJlYWRvbmx5IGZpbHRlclBhdHRlcm46IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBsb2cgZ3JvdXAgdG8gYXNzb2NpYXRlIHdpdGggdGhlIHN1YnNjcmlwdGlvbiBmaWx0ZXIuIEFsbCBsb2cgZXZlbnRzIHRoYXQgYXJlIHVwbG9hZGVkIHRvIHRoaXMgbG9nIGdyb3VwIGFyZSBmaWx0ZXJlZCBhbmQgZGVsaXZlcmVkIHRvIHRoZSBzcGVjaWZpZWQgQVdTIHJlc291cmNlIGlmIHRoZSBmaWx0ZXIgcGF0dGVybiBtYXRjaGVzIHRoZSBsb2cgZXZlbnRzLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1zdWJzY3JpcHRpb25maWx0ZXIuaHRtbCNjZm4tbG9ncy1zdWJzY3JpcHRpb25maWx0ZXItbG9nZ3JvdXBuYW1lXG4gICAgICovXG4gICAgcmVhZG9ubHkgbG9nR3JvdXBOYW1lOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWV0aG9kIHVzZWQgdG8gZGlzdHJpYnV0ZSBsb2cgZGF0YSB0byB0aGUgZGVzdGluYXRpb24sIHdoaWNoIGNhbiBiZSBlaXRoZXIgcmFuZG9tIG9yIGdyb3VwZWQgYnkgbG9nIHN0cmVhbS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3Mtc3Vic2NyaXB0aW9uZmlsdGVyLmh0bWwjY2ZuLWxvZ3Mtc3Vic2NyaXB0aW9uZmlsdGVyLWRpc3RyaWJ1dGlvblxuICAgICAqL1xuICAgIHJlYWRvbmx5IGRpc3RyaWJ1dGlvbj86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBzdWJzY3JpcHRpb24gZmlsdGVyLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1zdWJzY3JpcHRpb25maWx0ZXIuaHRtbCNjZm4tbG9ncy1zdWJzY3JpcHRpb25maWx0ZXItZmlsdGVybmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IGZpbHRlck5hbWU/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgQVJOIG9mIGFuIElBTSByb2xlIHRoYXQgZ3JhbnRzIENsb3VkV2F0Y2ggTG9ncyBwZXJtaXNzaW9ucyB0byBkZWxpdmVyIGluZ2VzdGVkIGxvZyBldmVudHMgdG8gdGhlIGRlc3RpbmF0aW9uIHN0cmVhbS4gWW91IGRvbid0IG5lZWQgdG8gcHJvdmlkZSB0aGUgQVJOIHdoZW4geW91IGFyZSB3b3JraW5nIHdpdGggYSBsb2dpY2FsIGRlc3RpbmF0aW9uIGZvciBjcm9zcy1hY2NvdW50IGRlbGl2ZXJ5LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1zdWJzY3JpcHRpb25maWx0ZXIuaHRtbCNjZm4tbG9ncy1zdWJzY3JpcHRpb25maWx0ZXItcm9sZWFyblxuICAgICAqL1xuICAgIHJlYWRvbmx5IHJvbGVBcm4/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgQ2ZuU3Vic2NyaXB0aW9uRmlsdGVyUHJvcHNgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblN1YnNjcmlwdGlvbkZpbHRlclByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblN1YnNjcmlwdGlvbkZpbHRlclByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZGVzdGluYXRpb25Bcm4nLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMuZGVzdGluYXRpb25Bcm4pKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2Rlc3RpbmF0aW9uQXJuJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmRlc3RpbmF0aW9uQXJuKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdkaXN0cmlidXRpb24nLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuZGlzdHJpYnV0aW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdmaWx0ZXJOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmZpbHRlck5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2ZpbHRlclBhdHRlcm4nLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMuZmlsdGVyUGF0dGVybikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZmlsdGVyUGF0dGVybicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5maWx0ZXJQYXR0ZXJuKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdsb2dHcm91cE5hbWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMubG9nR3JvdXBOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdsb2dHcm91cE5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMubG9nR3JvdXBOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyb2xlQXJuJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnJvbGVBcm4pKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuU3Vic2NyaXB0aW9uRmlsdGVyUHJvcHNcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkxvZ3M6OlN1YnNjcmlwdGlvbkZpbHRlcmAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuU3Vic2NyaXB0aW9uRmlsdGVyUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OkxvZ3M6OlN1YnNjcmlwdGlvbkZpbHRlcmAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5TdWJzY3JpcHRpb25GaWx0ZXJQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuU3Vic2NyaXB0aW9uRmlsdGVyUHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIERlc3RpbmF0aW9uQXJuOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmRlc3RpbmF0aW9uQXJuKSxcbiAgICAgICAgRmlsdGVyUGF0dGVybjogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5maWx0ZXJQYXR0ZXJuKSxcbiAgICAgICAgTG9nR3JvdXBOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmxvZ0dyb3VwTmFtZSksXG4gICAgICAgIERpc3RyaWJ1dGlvbjogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5kaXN0cmlidXRpb24pLFxuICAgICAgICBGaWx0ZXJOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmZpbHRlck5hbWUpLFxuICAgICAgICBSb2xlQXJuOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnJvbGVBcm4pLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5TdWJzY3JpcHRpb25GaWx0ZXJQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblN1YnNjcmlwdGlvbkZpbHRlclByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5TdWJzY3JpcHRpb25GaWx0ZXJQcm9wcz4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2Rlc3RpbmF0aW9uQXJuJywgJ0Rlc3RpbmF0aW9uQXJuJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5EZXN0aW5hdGlvbkFybikpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZmlsdGVyUGF0dGVybicsICdGaWx0ZXJQYXR0ZXJuJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5GaWx0ZXJQYXR0ZXJuKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdsb2dHcm91cE5hbWUnLCAnTG9nR3JvdXBOYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Mb2dHcm91cE5hbWUpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2Rpc3RyaWJ1dGlvbicsICdEaXN0cmlidXRpb24nLCBwcm9wZXJ0aWVzLkRpc3RyaWJ1dGlvbiAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5EaXN0cmlidXRpb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2ZpbHRlck5hbWUnLCAnRmlsdGVyTmFtZScsIHByb3BlcnRpZXMuRmlsdGVyTmFtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5GaWx0ZXJOYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdyb2xlQXJuJywgJ1JvbGVBcm4nLCBwcm9wZXJ0aWVzLlJvbGVBcm4gIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuUm9sZUFybikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6TG9nczo6U3Vic2NyaXB0aW9uRmlsdGVyYFxuICpcbiAqIFRoZSBgQVdTOjpMb2dzOjpTdWJzY3JpcHRpb25GaWx0ZXJgIHJlc291cmNlIHNwZWNpZmllcyBhIHN1YnNjcmlwdGlvbiBmaWx0ZXIgYW5kIGFzc29jaWF0ZXMgaXQgd2l0aCB0aGUgc3BlY2lmaWVkIGxvZyBncm91cC4gU3Vic2NyaXB0aW9uIGZpbHRlcnMgYWxsb3cgeW91IHRvIHN1YnNjcmliZSB0byBhIHJlYWwtdGltZSBzdHJlYW0gb2YgbG9nIGV2ZW50cyBhbmQgaGF2ZSB0aGVtIGRlbGl2ZXJlZCB0byBhIHNwZWNpZmljIGRlc3RpbmF0aW9uLiBDdXJyZW50bHksIHRoZSBzdXBwb3J0ZWQgZGVzdGluYXRpb25zIGFyZTpcbiAqXG4gKiAtIEFuIEFtYXpvbiBLaW5lc2lzIGRhdGEgc3RyZWFtIGJlbG9uZ2luZyB0byB0aGUgc2FtZSBhY2NvdW50IGFzIHRoZSBzdWJzY3JpcHRpb24gZmlsdGVyLCBmb3Igc2FtZS1hY2NvdW50IGRlbGl2ZXJ5LlxuICogLSBBIGxvZ2ljYWwgZGVzdGluYXRpb24gdGhhdCBiZWxvbmdzIHRvIGEgZGlmZmVyZW50IGFjY291bnQsIGZvciBjcm9zcy1hY2NvdW50IGRlbGl2ZXJ5LlxuICogLSBBbiBBbWF6b24gS2luZXNpcyBGaXJlaG9zZSBkZWxpdmVyeSBzdHJlYW0gdGhhdCBiZWxvbmdzIHRvIHRoZSBzYW1lIGFjY291bnQgYXMgdGhlIHN1YnNjcmlwdGlvbiBmaWx0ZXIsIGZvciBzYW1lLWFjY291bnQgZGVsaXZlcnkuXG4gKiAtIEFuIEFXUyBMYW1iZGEgZnVuY3Rpb24gdGhhdCBiZWxvbmdzIHRvIHRoZSBzYW1lIGFjY291bnQgYXMgdGhlIHN1YnNjcmlwdGlvbiBmaWx0ZXIsIGZvciBzYW1lLWFjY291bnQgZGVsaXZlcnkuXG4gKlxuICogVGhlcmUgY2FuIGJlIGFzIG1hbnkgYXMgdHdvIHN1YnNjcmlwdGlvbiBmaWx0ZXJzIGFzc29jaWF0ZWQgd2l0aCBhIGxvZyBncm91cC5cbiAqXG4gKiBAY2xvdWRmb3JtYXRpb25SZXNvdXJjZSBBV1M6OkxvZ3M6OlN1YnNjcmlwdGlvbkZpbHRlclxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3Mtc3Vic2NyaXB0aW9uZmlsdGVyLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIENmblN1YnNjcmlwdGlvbkZpbHRlciBleHRlbmRzIGNkay5DZm5SZXNvdXJjZSBpbXBsZW1lbnRzIGNkay5JSW5zcGVjdGFibGUge1xuICAgIC8qKlxuICAgICAqIFRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSB0eXBlIG5hbWUgZm9yIHRoaXMgcmVzb3VyY2UgY2xhc3MuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBDRk5fUkVTT1VSQ0VfVFlQRV9OQU1FID0gXCJBV1M6OkxvZ3M6OlN1YnNjcmlwdGlvbkZpbHRlclwiO1xuXG4gICAgLyoqXG4gICAgICogQSBmYWN0b3J5IG1ldGhvZCB0aGF0IGNyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBmcm9tIGFuIG9iamVjdFxuICAgICAqIGNvbnRhaW5pbmcgdGhlIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgdGhpcyByZXNvdXJjZS5cbiAgICAgKiBVc2VkIGluIHRoZSBAYXdzLWNkay9jbG91ZGZvcm1hdGlvbi1pbmNsdWRlIG1vZHVsZS5cbiAgICAgKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgX2Zyb21DbG91ZEZvcm1hdGlvbihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcmVzb3VyY2VBdHRyaWJ1dGVzOiBhbnksIG9wdGlvbnM6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25PcHRpb25zKTogQ2ZuU3Vic2NyaXB0aW9uRmlsdGVyIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5TdWJzY3JpcHRpb25GaWx0ZXJQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihyZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgQ2ZuU3Vic2NyaXB0aW9uRmlsdGVyKHNjb3BlLCBpZCwgcHJvcHNSZXN1bHQudmFsdWUpO1xuICAgICAgICBmb3IgKGNvbnN0IFtwcm9wS2V5LCBwcm9wVmFsXSBvZiBPYmplY3QuZW50cmllcyhwcm9wc1Jlc3VsdC5leHRyYVByb3BlcnRpZXMpKSAge1xuICAgICAgICAgICAgcmV0LmFkZFByb3BlcnR5T3ZlcnJpZGUocHJvcEtleSwgcHJvcFZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5wYXJzZXIuaGFuZGxlQXR0cmlidXRlcyhyZXQsIHJlc291cmNlQXR0cmlidXRlcywgaWQpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgZGVzdGluYXRpb24uXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLXN1YnNjcmlwdGlvbmZpbHRlci5odG1sI2Nmbi1sb2dzLXN1YnNjcmlwdGlvbmZpbHRlci1kZXN0aW5hdGlvbmFyblxuICAgICAqL1xuICAgIHB1YmxpYyBkZXN0aW5hdGlvbkFybjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGZpbHRlcmluZyBleHByZXNzaW9ucyB0aGF0IHJlc3RyaWN0IHdoYXQgZ2V0cyBkZWxpdmVyZWQgdG8gdGhlIGRlc3RpbmF0aW9uIEFXUyByZXNvdXJjZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGZpbHRlciBwYXR0ZXJuIHN5bnRheCwgc2VlIFtGaWx0ZXIgYW5kIFBhdHRlcm4gU3ludGF4XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRXYXRjaC9sYXRlc3QvbG9ncy9GaWx0ZXJBbmRQYXR0ZXJuU3ludGF4Lmh0bWwpIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3Mtc3Vic2NyaXB0aW9uZmlsdGVyLmh0bWwjY2ZuLWxvZ3Mtc3Vic2NyaXB0aW9uZmlsdGVyLWZpbHRlcnBhdHRlcm5cbiAgICAgKi9cbiAgICBwdWJsaWMgZmlsdGVyUGF0dGVybjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGxvZyBncm91cCB0byBhc3NvY2lhdGUgd2l0aCB0aGUgc3Vic2NyaXB0aW9uIGZpbHRlci4gQWxsIGxvZyBldmVudHMgdGhhdCBhcmUgdXBsb2FkZWQgdG8gdGhpcyBsb2cgZ3JvdXAgYXJlIGZpbHRlcmVkIGFuZCBkZWxpdmVyZWQgdG8gdGhlIHNwZWNpZmllZCBBV1MgcmVzb3VyY2UgaWYgdGhlIGZpbHRlciBwYXR0ZXJuIG1hdGNoZXMgdGhlIGxvZyBldmVudHMuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1sb2dzLXN1YnNjcmlwdGlvbmZpbHRlci5odG1sI2Nmbi1sb2dzLXN1YnNjcmlwdGlvbmZpbHRlci1sb2dncm91cG5hbWVcbiAgICAgKi9cbiAgICBwdWJsaWMgbG9nR3JvdXBOYW1lOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWV0aG9kIHVzZWQgdG8gZGlzdHJpYnV0ZSBsb2cgZGF0YSB0byB0aGUgZGVzdGluYXRpb24sIHdoaWNoIGNhbiBiZSBlaXRoZXIgcmFuZG9tIG9yIGdyb3VwZWQgYnkgbG9nIHN0cmVhbS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3Mtc3Vic2NyaXB0aW9uZmlsdGVyLmh0bWwjY2ZuLWxvZ3Mtc3Vic2NyaXB0aW9uZmlsdGVyLWRpc3RyaWJ1dGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBkaXN0cmlidXRpb246IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBzdWJzY3JpcHRpb24gZmlsdGVyLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1zdWJzY3JpcHRpb25maWx0ZXIuaHRtbCNjZm4tbG9ncy1zdWJzY3JpcHRpb25maWx0ZXItZmlsdGVybmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyBmaWx0ZXJOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgQVJOIG9mIGFuIElBTSByb2xlIHRoYXQgZ3JhbnRzIENsb3VkV2F0Y2ggTG9ncyBwZXJtaXNzaW9ucyB0byBkZWxpdmVyIGluZ2VzdGVkIGxvZyBldmVudHMgdG8gdGhlIGRlc3RpbmF0aW9uIHN0cmVhbS4gWW91IGRvbid0IG5lZWQgdG8gcHJvdmlkZSB0aGUgQVJOIHdoZW4geW91IGFyZSB3b3JraW5nIHdpdGggYSBsb2dpY2FsIGRlc3RpbmF0aW9uIGZvciBjcm9zcy1hY2NvdW50IGRlbGl2ZXJ5LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtbG9ncy1zdWJzY3JpcHRpb25maWx0ZXIuaHRtbCNjZm4tbG9ncy1zdWJzY3JpcHRpb25maWx0ZXItcm9sZWFyblxuICAgICAqL1xuICAgIHB1YmxpYyByb2xlQXJuOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6TG9nczo6U3Vic2NyaXB0aW9uRmlsdGVyYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5TdWJzY3JpcHRpb25GaWx0ZXJQcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuU3Vic2NyaXB0aW9uRmlsdGVyLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUsIHByb3BlcnRpZXM6IHByb3BzIH0pO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAnZGVzdGluYXRpb25Bcm4nLCB0aGlzKTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ2ZpbHRlclBhdHRlcm4nLCB0aGlzKTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ2xvZ0dyb3VwTmFtZScsIHRoaXMpO1xuXG4gICAgICAgIHRoaXMuZGVzdGluYXRpb25Bcm4gPSBwcm9wcy5kZXN0aW5hdGlvbkFybjtcbiAgICAgICAgdGhpcy5maWx0ZXJQYXR0ZXJuID0gcHJvcHMuZmlsdGVyUGF0dGVybjtcbiAgICAgICAgdGhpcy5sb2dHcm91cE5hbWUgPSBwcm9wcy5sb2dHcm91cE5hbWU7XG4gICAgICAgIHRoaXMuZGlzdHJpYnV0aW9uID0gcHJvcHMuZGlzdHJpYnV0aW9uO1xuICAgICAgICB0aGlzLmZpbHRlck5hbWUgPSBwcm9wcy5maWx0ZXJOYW1lO1xuICAgICAgICB0aGlzLnJvbGVBcm4gPSBwcm9wcy5yb2xlQXJuO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuU3Vic2NyaXB0aW9uRmlsdGVyLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBkZXN0aW5hdGlvbkFybjogdGhpcy5kZXN0aW5hdGlvbkFybixcbiAgICAgICAgICAgIGZpbHRlclBhdHRlcm46IHRoaXMuZmlsdGVyUGF0dGVybixcbiAgICAgICAgICAgIGxvZ0dyb3VwTmFtZTogdGhpcy5sb2dHcm91cE5hbWUsXG4gICAgICAgICAgICBkaXN0cmlidXRpb246IHRoaXMuZGlzdHJpYnV0aW9uLFxuICAgICAgICAgICAgZmlsdGVyTmFtZTogdGhpcy5maWx0ZXJOYW1lLFxuICAgICAgICAgICAgcm9sZUFybjogdGhpcy5yb2xlQXJuLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmblN1YnNjcmlwdGlvbkZpbHRlclByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wcyk7XG4gICAgfVxufVxuIl19
\No newline at end of file