UNPKG

224 kBJavaScriptView Raw
1"use strict";
2var _a, _b, _c, _d;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.ReplaceKey = exports.BucketAccessControl = exports.EventType = exports.BucketEncryption = exports.Bucket = exports.ObjectOwnership = exports.InventoryObjectVersion = exports.InventoryFrequency = exports.InventoryFormat = exports.RedirectProtocol = exports.HttpMethods = exports.BlockPublicAccess = exports.BucketBase = void 0;
5const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
6const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
7const os_1 = require("os");
8const path = require("path");
9const events = require("@aws-cdk/aws-events");
10const iam = require("@aws-cdk/aws-iam");
11const kms = require("@aws-cdk/aws-kms");
12const core_1 = require("@aws-cdk/core");
13const cxapi = require("@aws-cdk/cx-api");
14const bucket_policy_1 = require("./bucket-policy");
15const notifications_resource_1 = require("./notifications-resource");
16const perms = require("./perms");
17const s3_generated_1 = require("./s3.generated");
18const util_1 = require("./util");
19const AUTO_DELETE_OBJECTS_RESOURCE_TYPE = 'Custom::S3AutoDeleteObjects';
20const AUTO_DELETE_OBJECTS_TAG = 'aws-cdk:auto-delete-objects';
21/**
22 * Represents an S3 Bucket.
23 *
24 * Buckets can be either defined within this stack:
25 *
26 * new Bucket(this, 'MyBucket', { props });
27 *
28 * Or imported from an existing bucket:
29 *
30 * Bucket.import(this, 'MyImportedBucket', { bucketArn: ... });
31 *
32 * You can also export a bucket and import it into another stack:
33 *
34 * const ref = myBucket.export();
35 * Bucket.import(this, 'MyImportedBucket', ref);
36 *
37 */
38class BucketBase extends core_1.Resource {
39 constructor(scope, id, props = {}) {
40 super(scope, id, props);
41 }
42 /**
43 * Define a CloudWatch event that triggers when something happens to this repository
44 *
45 * Requires that there exists at least one CloudTrail Trail in your account
46 * that captures the event. This method will not create the Trail.
47 *
48 * @param id The id of the rule
49 * @param options Options for adding the rule
50 */
51 onCloudTrailEvent(id, options = {}) {
52 var _e, _f;
53 try {
54 jsiiDeprecationWarnings._aws_cdk_aws_s3_OnCloudTrailBucketEventOptions(options);
55 }
56 catch (error) {
57 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
58 Error.captureStackTrace(error, this.onCloudTrailEvent);
59 }
60 throw error;
61 }
62 const rule = new events.Rule(this, id, options);
63 rule.addTarget(options.target);
64 rule.addEventPattern({
65 source: ['aws.s3'],
66 detailType: ['AWS API Call via CloudTrail'],
67 detail: {
68 resources: {
69 ARN: (_f = (_e = options.paths) === null || _e === void 0 ? void 0 : _e.map(p => this.arnForObjects(p))) !== null && _f !== void 0 ? _f : [this.bucketArn],
70 },
71 },
72 });
73 return rule;
74 }
75 /**
76 * Defines an AWS CloudWatch event that triggers when an object is uploaded
77 * to the specified paths (keys) in this bucket using the PutObject API call.
78 *
79 * Note that some tools like `aws s3 cp` will automatically use either
80 * PutObject or the multipart upload API depending on the file size,
81 * so using `onCloudTrailWriteObject` may be preferable.
82 *
83 * Requires that there exists at least one CloudTrail Trail in your account
84 * that captures the event. This method will not create the Trail.
85 *
86 * @param id The id of the rule
87 * @param options Options for adding the rule
88 */
89 onCloudTrailPutObject(id, options = {}) {
90 try {
91 jsiiDeprecationWarnings._aws_cdk_aws_s3_OnCloudTrailBucketEventOptions(options);
92 }
93 catch (error) {
94 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
95 Error.captureStackTrace(error, this.onCloudTrailPutObject);
96 }
97 throw error;
98 }
99 const rule = this.onCloudTrailEvent(id, options);
100 rule.addEventPattern({
101 detail: {
102 eventName: ['PutObject'],
103 },
104 });
105 return rule;
106 }
107 /**
108 * Defines an AWS CloudWatch event that triggers when an object at the
109 * specified paths (keys) in this bucket are written to. This includes
110 * the events PutObject, CopyObject, and CompleteMultipartUpload.
111 *
112 * Note that some tools like `aws s3 cp` will automatically use either
113 * PutObject or the multipart upload API depending on the file size,
114 * so using this method may be preferable to `onCloudTrailPutObject`.
115 *
116 * Requires that there exists at least one CloudTrail Trail in your account
117 * that captures the event. This method will not create the Trail.
118 *
119 * @param id The id of the rule
120 * @param options Options for adding the rule
121 */
122 onCloudTrailWriteObject(id, options = {}) {
123 try {
124 jsiiDeprecationWarnings._aws_cdk_aws_s3_OnCloudTrailBucketEventOptions(options);
125 }
126 catch (error) {
127 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
128 Error.captureStackTrace(error, this.onCloudTrailWriteObject);
129 }
130 throw error;
131 }
132 const rule = this.onCloudTrailEvent(id, options);
133 rule.addEventPattern({
134 detail: {
135 eventName: [
136 'CompleteMultipartUpload',
137 'CopyObject',
138 'PutObject',
139 ],
140 requestParameters: {
141 bucketName: [this.bucketName],
142 key: options.paths,
143 },
144 },
145 });
146 return rule;
147 }
148 /**
149 * Adds a statement to the resource policy for a principal (i.e.
150 * account/role/service) to perform actions on this bucket and/or its
151 * contents. Use `bucketArn` and `arnForObjects(keys)` to obtain ARNs for
152 * this bucket or objects.
153 *
154 * Note that the policy statement may or may not be added to the policy.
155 * For example, when an `IBucket` is created from an existing bucket,
156 * it's not possible to tell whether the bucket already has a policy
157 * attached, let alone to re-use that policy to add more statements to it.
158 * So it's safest to do nothing in these cases.
159 *
160 * @param permission the policy statement to be added to the bucket's
161 * policy.
162 * @returns metadata about the execution of this method. If the policy
163 * was not added, the value of `statementAdded` will be `false`. You
164 * should always check this value to make sure that the operation was
165 * actually carried out. Otherwise, synthesis and deploy will terminate
166 * silently, which may be confusing.
167 */
168 addToResourcePolicy(permission) {
169 if (!this.policy && this.autoCreatePolicy) {
170 this.policy = new bucket_policy_1.BucketPolicy(this, 'Policy', { bucket: this });
171 }
172 if (this.policy) {
173 this.policy.document.addStatements(permission);
174 return { statementAdded: true, policyDependable: this.policy };
175 }
176 return { statementAdded: false };
177 }
178 validate() {
179 var _e;
180 const errors = super.validate();
181 errors.push(...((_e = this.policy) === null || _e === void 0 ? void 0 : _e.document.validateForResourcePolicy()) || []);
182 return errors;
183 }
184 /**
185 * The https URL of an S3 object. Specify `regional: false` at the options
186 * for non-regional URLs. For example:
187 *
188 * - `https://s3.us-west-1.amazonaws.com/onlybucket`
189 * - `https://s3.us-west-1.amazonaws.com/bucket/key`
190 * - `https://s3.cn-north-1.amazonaws.com.cn/china-bucket/mykey`
191 *
192 * @param key The S3 key of the object. If not specified, the URL of the
193 * bucket is returned.
194 * @returns an ObjectS3Url token
195 */
196 urlForObject(key) {
197 const stack = core_1.Stack.of(this);
198 const prefix = `https://s3.${this.env.region}.${stack.urlSuffix}/`;
199 if (typeof key !== 'string') {
200 return this.urlJoin(prefix, this.bucketName);
201 }
202 return this.urlJoin(prefix, this.bucketName, key);
203 }
204 /**
205 * The https Transfer Acceleration URL of an S3 object. Specify `dualStack: true` at the options
206 * for dual-stack endpoint (connect to the bucket over IPv6). For example:
207 *
208 * - `https://bucket.s3-accelerate.amazonaws.com`
209 * - `https://bucket.s3-accelerate.amazonaws.com/key`
210 *
211 * @param key The S3 key of the object. If not specified, the URL of the
212 * bucket is returned.
213 * @param options Options for generating URL.
214 * @returns an TransferAccelerationUrl token
215 */
216 transferAccelerationUrlForObject(key, options) {
217 try {
218 jsiiDeprecationWarnings._aws_cdk_aws_s3_TransferAccelerationUrlOptions(options);
219 }
220 catch (error) {
221 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
222 Error.captureStackTrace(error, this.transferAccelerationUrlForObject);
223 }
224 throw error;
225 }
226 const dualStack = (options === null || options === void 0 ? void 0 : options.dualStack) ? '.dualstack' : '';
227 const prefix = `https://${this.bucketName}.s3-accelerate${dualStack}.amazonaws.com/`;
228 if (typeof key !== 'string') {
229 return this.urlJoin(prefix);
230 }
231 return this.urlJoin(prefix, key);
232 }
233 /**
234 * The virtual hosted-style URL of an S3 object. Specify `regional: false` at
235 * the options for non-regional URL. For example:
236 *
237 * - `https://only-bucket.s3.us-west-1.amazonaws.com`
238 * - `https://bucket.s3.us-west-1.amazonaws.com/key`
239 * - `https://bucket.s3.amazonaws.com/key`
240 * - `https://china-bucket.s3.cn-north-1.amazonaws.com.cn/mykey`
241 *
242 * @param key The S3 key of the object. If not specified, the URL of the
243 * bucket is returned.
244 * @param options Options for generating URL.
245 * @returns an ObjectS3Url token
246 */
247 virtualHostedUrlForObject(key, options) {
248 var _e;
249 try {
250 jsiiDeprecationWarnings._aws_cdk_aws_s3_VirtualHostedStyleUrlOptions(options);
251 }
252 catch (error) {
253 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
254 Error.captureStackTrace(error, this.virtualHostedUrlForObject);
255 }
256 throw error;
257 }
258 const domainName = ((_e = options === null || options === void 0 ? void 0 : options.regional) !== null && _e !== void 0 ? _e : true) ? this.bucketRegionalDomainName : this.bucketDomainName;
259 const prefix = `https://${domainName}`;
260 if (typeof key !== 'string') {
261 return prefix;
262 }
263 return this.urlJoin(prefix, key);
264 }
265 /**
266 * The S3 URL of an S3 object. For example:
267 *
268 * - `s3://onlybucket`
269 * - `s3://bucket/key`
270 *
271 * @param key The S3 key of the object. If not specified, the S3 URL of the
272 * bucket is returned.
273 * @returns an ObjectS3Url token
274 */
275 s3UrlForObject(key) {
276 const prefix = 's3://';
277 if (typeof key !== 'string') {
278 return this.urlJoin(prefix, this.bucketName);
279 }
280 return this.urlJoin(prefix, this.bucketName, key);
281 }
282 /**
283 * Returns an ARN that represents all objects within the bucket that match
284 * the key pattern specified. To represent all keys, specify ``"*"``.
285 *
286 * If you need to specify a keyPattern with multiple components, concatenate them into a single string, e.g.:
287 *
288 * arnForObjects(`home/${team}/${user}/*`)
289 *
290 */
291 arnForObjects(keyPattern) {
292 return `${this.bucketArn}/${keyPattern}`;
293 }
294 /**
295 * Grant read permissions for this bucket and it's contents to an IAM
296 * principal (Role/Group/User).
297 *
298 * If encryption is used, permission to use the key to decrypt the contents
299 * of the bucket will also be granted to the same principal.
300 *
301 * @param identity The principal
302 * @param objectsKeyPattern Restrict the permission to a certain key pattern (default '*')
303 */
304 grantRead(identity, objectsKeyPattern = '*') {
305 return this.grant(identity, perms.BUCKET_READ_ACTIONS, perms.KEY_READ_ACTIONS, this.bucketArn, this.arnForObjects(objectsKeyPattern));
306 }
307 grantWrite(identity, objectsKeyPattern = '*') {
308 return this.grant(identity, this.writeActions, perms.KEY_WRITE_ACTIONS, this.bucketArn, this.arnForObjects(objectsKeyPattern));
309 }
310 /**
311 * Grants s3:PutObject* and s3:Abort* permissions for this bucket to an IAM principal.
312 *
313 * If encryption is used, permission to use the key to encrypt the contents
314 * of written files will also be granted to the same principal.
315 * @param identity The principal
316 * @param objectsKeyPattern Restrict the permission to a certain key pattern (default '*')
317 */
318 grantPut(identity, objectsKeyPattern = '*') {
319 return this.grant(identity, this.putActions, perms.KEY_WRITE_ACTIONS, this.arnForObjects(objectsKeyPattern));
320 }
321 grantPutAcl(identity, objectsKeyPattern = '*') {
322 return this.grant(identity, perms.BUCKET_PUT_ACL_ACTIONS, [], this.arnForObjects(objectsKeyPattern));
323 }
324 /**
325 * Grants s3:DeleteObject* permission to an IAM principal for objects
326 * in this bucket.
327 *
328 * @param identity The principal
329 * @param objectsKeyPattern Restrict the permission to a certain key pattern (default '*')
330 */
331 grantDelete(identity, objectsKeyPattern = '*') {
332 return this.grant(identity, perms.BUCKET_DELETE_ACTIONS, [], this.arnForObjects(objectsKeyPattern));
333 }
334 grantReadWrite(identity, objectsKeyPattern = '*') {
335 const bucketActions = perms.BUCKET_READ_ACTIONS.concat(this.writeActions);
336 // we need unique permissions because some permissions are common between read and write key actions
337 const keyActions = [...new Set([...perms.KEY_READ_ACTIONS, ...perms.KEY_WRITE_ACTIONS])];
338 return this.grant(identity, bucketActions, keyActions, this.bucketArn, this.arnForObjects(objectsKeyPattern));
339 }
340 /**
341 * Allows unrestricted access to objects from this bucket.
342 *
343 * IMPORTANT: This permission allows anyone to perform actions on S3 objects
344 * in this bucket, which is useful for when you configure your bucket as a
345 * website and want everyone to be able to read objects in the bucket without
346 * needing to authenticate.
347 *
348 * Without arguments, this method will grant read ("s3:GetObject") access to
349 * all objects ("*") in the bucket.
350 *
351 * The method returns the `iam.Grant` object, which can then be modified
352 * as needed. For example, you can add a condition that will restrict access only
353 * to an IPv4 range like this:
354 *
355 * const grant = bucket.grantPublicAccess();
356 * grant.resourceStatement!.addCondition(‘IpAddress’, { “aws:SourceIp”: “54.240.143.0/24” });
357 *
358 * Note that if this `IBucket` refers to an existing bucket, possibly not
359 * managed by CloudFormation, this method will have no effect, since it's
360 * impossible to modify the policy of an existing bucket.
361 *
362 * @param keyPrefix the prefix of S3 object keys (e.g. `home/*`). Default is "*".
363 * @param allowedActions the set of S3 actions to allow. Default is "s3:GetObject".
364 */
365 grantPublicAccess(keyPrefix = '*', ...allowedActions) {
366 if (this.disallowPublicAccess) {
367 throw new Error("Cannot grant public access when 'blockPublicPolicy' is enabled");
368 }
369 allowedActions = allowedActions.length > 0 ? allowedActions : ['s3:GetObject'];
370 return iam.Grant.addToPrincipalOrResource({
371 actions: allowedActions,
372 resourceArns: [this.arnForObjects(keyPrefix)],
373 grantee: new iam.AnyPrincipal(),
374 resource: this,
375 });
376 }
377 /**
378 * Adds a bucket notification event destination.
379 * @param event The event to trigger the notification
380 * @param dest The notification destination (Lambda, SNS Topic or SQS Queue)
381 *
382 * @param filters S3 object key filter rules to determine which objects
383 * trigger this event. Each filter must include a `prefix` and/or `suffix`
384 * that will be matched against the s3 object key. Refer to the S3 Developer Guide
385 * for details about allowed filter rules.
386 *
387 * @see https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html#notification-how-to-filtering
388 *
389 * @example
390 *
391 * declare const myLambda: lambda.Function;
392 * const bucket = new s3.Bucket(this, 'MyBucket');
393 * bucket.addEventNotification(s3.EventType.OBJECT_CREATED, new s3n.LambdaDestination(myLambda), {prefix: 'home/myusername/*'});
394 *
395 * @see
396 * https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html
397 */
398 addEventNotification(event, dest, ...filters) {
399 try {
400 jsiiDeprecationWarnings._aws_cdk_aws_s3_EventType(event);
401 jsiiDeprecationWarnings._aws_cdk_aws_s3_IBucketNotificationDestination(dest);
402 jsiiDeprecationWarnings._aws_cdk_aws_s3_NotificationKeyFilter(filters);
403 }
404 catch (error) {
405 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
406 Error.captureStackTrace(error, this.addEventNotification);
407 }
408 throw error;
409 }
410 this.withNotifications(notifications => notifications.addNotification(event, dest, ...filters));
411 }
412 withNotifications(cb) {
413 if (!this.notifications) {
414 this.notifications = new notifications_resource_1.BucketNotifications(this, 'Notifications', {
415 bucket: this,
416 handlerRole: this.notificationsHandlerRole,
417 });
418 }
419 cb(this.notifications);
420 }
421 /**
422 * Subscribes a destination to receive notifications when an object is
423 * created in the bucket. This is identical to calling
424 * `onEvent(EventType.OBJECT_CREATED)`.
425 *
426 * @param dest The notification destination (see onEvent)
427 * @param filters Filters (see onEvent)
428 */
429 addObjectCreatedNotification(dest, ...filters) {
430 try {
431 jsiiDeprecationWarnings._aws_cdk_aws_s3_IBucketNotificationDestination(dest);
432 jsiiDeprecationWarnings._aws_cdk_aws_s3_NotificationKeyFilter(filters);
433 }
434 catch (error) {
435 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
436 Error.captureStackTrace(error, this.addObjectCreatedNotification);
437 }
438 throw error;
439 }
440 return this.addEventNotification(EventType.OBJECT_CREATED, dest, ...filters);
441 }
442 /**
443 * Subscribes a destination to receive notifications when an object is
444 * removed from the bucket. This is identical to calling
445 * `onEvent(EventType.OBJECT_REMOVED)`.
446 *
447 * @param dest The notification destination (see onEvent)
448 * @param filters Filters (see onEvent)
449 */
450 addObjectRemovedNotification(dest, ...filters) {
451 try {
452 jsiiDeprecationWarnings._aws_cdk_aws_s3_IBucketNotificationDestination(dest);
453 jsiiDeprecationWarnings._aws_cdk_aws_s3_NotificationKeyFilter(filters);
454 }
455 catch (error) {
456 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
457 Error.captureStackTrace(error, this.addObjectRemovedNotification);
458 }
459 throw error;
460 }
461 return this.addEventNotification(EventType.OBJECT_REMOVED, dest, ...filters);
462 }
463 enableEventBridgeNotification() {
464 this.withNotifications(notifications => notifications.enableEventBridgeNotification());
465 }
466 get writeActions() {
467 return [
468 ...perms.BUCKET_DELETE_ACTIONS,
469 ...this.putActions,
470 ];
471 }
472 get putActions() {
473 return core_1.FeatureFlags.of(this).isEnabled(cxapi.S3_GRANT_WRITE_WITHOUT_ACL)
474 ? perms.BUCKET_PUT_ACTIONS
475 : perms.LEGACY_BUCKET_PUT_ACTIONS;
476 }
477 urlJoin(...components) {
478 return components.reduce((result, component) => {
479 if (result.endsWith('/')) {
480 result = result.slice(0, -1);
481 }
482 if (component.startsWith('/')) {
483 component = component.slice(1);
484 }
485 return `${result}/${component}`;
486 });
487 }
488 grant(grantee, bucketActions, keyActions, resourceArn, ...otherResourceArns) {
489 const resources = [resourceArn, ...otherResourceArns];
490 const ret = iam.Grant.addToPrincipalOrResource({
491 grantee,
492 actions: bucketActions,
493 resourceArns: resources,
494 resource: this,
495 });
496 if (this.encryptionKey && keyActions && keyActions.length !== 0) {
497 this.encryptionKey.grant(grantee, ...keyActions);
498 }
499 return ret;
500 }
501}
502exports.BucketBase = BucketBase;
503_a = JSII_RTTI_SYMBOL_1;
504BucketBase[_a] = { fqn: "@aws-cdk/aws-s3.BucketBase", version: "1.156.1" };
505class BlockPublicAccess {
506 constructor(options) {
507 try {
508 jsiiDeprecationWarnings._aws_cdk_aws_s3_BlockPublicAccessOptions(options);
509 }
510 catch (error) {
511 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
512 Error.captureStackTrace(error, this.constructor);
513 }
514 throw error;
515 }
516 this.blockPublicAcls = options.blockPublicAcls;
517 this.blockPublicPolicy = options.blockPublicPolicy;
518 this.ignorePublicAcls = options.ignorePublicAcls;
519 this.restrictPublicBuckets = options.restrictPublicBuckets;
520 }
521}
522exports.BlockPublicAccess = BlockPublicAccess;
523_b = JSII_RTTI_SYMBOL_1;
524BlockPublicAccess[_b] = { fqn: "@aws-cdk/aws-s3.BlockPublicAccess", version: "1.156.1" };
525BlockPublicAccess.BLOCK_ALL = new BlockPublicAccess({
526 blockPublicAcls: true,
527 blockPublicPolicy: true,
528 ignorePublicAcls: true,
529 restrictPublicBuckets: true,
530});
531BlockPublicAccess.BLOCK_ACLS = new BlockPublicAccess({
532 blockPublicAcls: true,
533 ignorePublicAcls: true,
534});
535/**
536 * All http request methods
537 */
538var HttpMethods;
539(function (HttpMethods) {
540 /**
541 * The GET method requests a representation of the specified resource.
542 */
543 HttpMethods["GET"] = "GET";
544 /**
545 * The PUT method replaces all current representations of the target resource with the request payload.
546 */
547 HttpMethods["PUT"] = "PUT";
548 /**
549 * The HEAD method asks for a response identical to that of a GET request, but without the response body.
550 */
551 HttpMethods["HEAD"] = "HEAD";
552 /**
553 * The POST method is used to submit an entity to the specified resource, often causing a change in state or side effects on the server.
554 */
555 HttpMethods["POST"] = "POST";
556 /**
557 * The DELETE method deletes the specified resource.
558 */
559 HttpMethods["DELETE"] = "DELETE";
560})(HttpMethods = exports.HttpMethods || (exports.HttpMethods = {}));
561/**
562 * All http request methods
563 */
564var RedirectProtocol;
565(function (RedirectProtocol) {
566 RedirectProtocol["HTTP"] = "http";
567 RedirectProtocol["HTTPS"] = "https";
568})(RedirectProtocol = exports.RedirectProtocol || (exports.RedirectProtocol = {}));
569/**
570 * All supported inventory list formats.
571 */
572var InventoryFormat;
573(function (InventoryFormat) {
574 /**
575 * Generate the inventory list as CSV.
576 */
577 InventoryFormat["CSV"] = "CSV";
578 /**
579 * Generate the inventory list as Parquet.
580 */
581 InventoryFormat["PARQUET"] = "Parquet";
582 /**
583 * Generate the inventory list as ORC.
584 */
585 InventoryFormat["ORC"] = "ORC";
586})(InventoryFormat = exports.InventoryFormat || (exports.InventoryFormat = {}));
587/**
588 * All supported inventory frequencies.
589 */
590var InventoryFrequency;
591(function (InventoryFrequency) {
592 /**
593 * A report is generated every day.
594 */
595 InventoryFrequency["DAILY"] = "Daily";
596 /**
597 * A report is generated every Sunday (UTC timezone) after the initial report.
598 */
599 InventoryFrequency["WEEKLY"] = "Weekly";
600})(InventoryFrequency = exports.InventoryFrequency || (exports.InventoryFrequency = {}));
601/**
602 * Inventory version support.
603 */
604var InventoryObjectVersion;
605(function (InventoryObjectVersion) {
606 /**
607 * Includes all versions of each object in the report.
608 */
609 InventoryObjectVersion["ALL"] = "All";
610 /**
611 * Includes only the current version of each object in the report.
612 */
613 InventoryObjectVersion["CURRENT"] = "Current";
614})(InventoryObjectVersion = exports.InventoryObjectVersion || (exports.InventoryObjectVersion = {}));
615/**
616 * The ObjectOwnership of the bucket.
617 *
618 * @see https://docs.aws.amazon.com/AmazonS3/latest/dev/about-object-ownership.html
619 *
620 */
621var ObjectOwnership;
622(function (ObjectOwnership) {
623 /**
624 * ACLs are disabled, and the bucket owner automatically owns
625 * and has full control over every object in the bucket.
626 * ACLs no longer affect permissions to data in the S3 bucket.
627 * The bucket uses policies to define access control.
628 */
629 ObjectOwnership["BUCKET_OWNER_ENFORCED"] = "BucketOwnerEnforced";
630 /**
631 * Objects uploaded to the bucket change ownership to the bucket owner .
632 */
633 ObjectOwnership["BUCKET_OWNER_PREFERRED"] = "BucketOwnerPreferred";
634 /**
635 * The uploading account will own the object.
636 */
637 ObjectOwnership["OBJECT_WRITER"] = "ObjectWriter";
638})(ObjectOwnership = exports.ObjectOwnership || (exports.ObjectOwnership = {}));
639/**
640 * An S3 bucket with associated policy objects
641 *
642 * This bucket does not yet have all features that exposed by the underlying
643 * BucketResource.
644 */
645class Bucket extends BucketBase {
646 constructor(scope, id, props = {}) {
647 var _e;
648 super(scope, id, {
649 physicalName: props.bucketName,
650 });
651 this.autoCreatePolicy = true;
652 this.lifecycleRules = [];
653 this.metrics = [];
654 this.cors = [];
655 this.inventories = [];
656 try {
657 jsiiDeprecationWarnings._aws_cdk_aws_s3_BucketProps(props);
658 }
659 catch (error) {
660 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
661 Error.captureStackTrace(error, this.constructor);
662 }
663 throw error;
664 }
665 this.notificationsHandlerRole = props.notificationsHandlerRole;
666 const { bucketEncryption, encryptionKey } = this.parseEncryption(props);
667 Bucket.validateBucketName(this.physicalName);
668 const websiteConfiguration = this.renderWebsiteConfiguration(props);
669 this.isWebsite = (websiteConfiguration !== undefined);
670 const resource = new s3_generated_1.CfnBucket(this, 'Resource', {
671 bucketName: this.physicalName,
672 bucketEncryption,
673 versioningConfiguration: props.versioned ? { status: 'Enabled' } : undefined,
674 lifecycleConfiguration: core_1.Lazy.any({ produce: () => this.parseLifecycleConfiguration() }),
675 websiteConfiguration,
676 publicAccessBlockConfiguration: props.blockPublicAccess,
677 metricsConfigurations: core_1.Lazy.any({ produce: () => this.parseMetricConfiguration() }),
678 corsConfiguration: core_1.Lazy.any({ produce: () => this.parseCorsConfiguration() }),
679 accessControl: core_1.Lazy.string({ produce: () => this.accessControl }),
680 loggingConfiguration: this.parseServerAccessLogs(props),
681 inventoryConfigurations: core_1.Lazy.any({ produce: () => this.parseInventoryConfiguration() }),
682 ownershipControls: this.parseOwnershipControls(props),
683 accelerateConfiguration: props.transferAcceleration ? { accelerationStatus: 'Enabled' } : undefined,
684 intelligentTieringConfigurations: this.parseTieringConfig(props),
685 });
686 this._resource = resource;
687 resource.applyRemovalPolicy(props.removalPolicy);
688 this.versioned = props.versioned;
689 this.encryptionKey = encryptionKey;
690 this.eventBridgeEnabled = props.eventBridgeEnabled;
691 this.bucketName = this.getResourceNameAttribute(resource.ref);
692 this.bucketArn = this.getResourceArnAttribute(resource.attrArn, {
693 region: '',
694 account: '',
695 service: 's3',
696 resource: this.physicalName,
697 });
698 this.bucketDomainName = resource.attrDomainName;
699 this.bucketWebsiteUrl = resource.attrWebsiteUrl;
700 this.bucketWebsiteDomainName = core_1.Fn.select(2, core_1.Fn.split('/', this.bucketWebsiteUrl));
701 this.bucketDualStackDomainName = resource.attrDualStackDomainName;
702 this.bucketRegionalDomainName = resource.attrRegionalDomainName;
703 this.disallowPublicAccess = props.blockPublicAccess && props.blockPublicAccess.blockPublicPolicy;
704 this.accessControl = props.accessControl;
705 // Enforce AWS Foundational Security Best Practice
706 if (props.enforceSSL) {
707 this.enforceSSLStatement();
708 }
709 if (props.serverAccessLogsBucket instanceof Bucket) {
710 props.serverAccessLogsBucket.allowLogDelivery();
711 }
712 for (const inventory of (_e = props.inventories) !== null && _e !== void 0 ? _e : []) {
713 this.addInventory(inventory);
714 }
715 // Add all bucket metric configurations rules
716 (props.metrics || []).forEach(this.addMetric.bind(this));
717 // Add all cors configuration rules
718 (props.cors || []).forEach(this.addCorsRule.bind(this));
719 // Add all lifecycle rules
720 (props.lifecycleRules || []).forEach(this.addLifecycleRule.bind(this));
721 if (props.publicReadAccess) {
722 this.grantPublicAccess();
723 }
724 if (props.autoDeleteObjects) {
725 if (props.removalPolicy !== core_1.RemovalPolicy.DESTROY) {
726 throw new Error('Cannot use \'autoDeleteObjects\' property on a bucket without setting removal policy to \'DESTROY\'.');
727 }
728 this.enableAutoDeleteObjects();
729 }
730 if (this.eventBridgeEnabled) {
731 this.enableEventBridgeNotification();
732 }
733 }
734 static fromBucketArn(scope, id, bucketArn) {
735 return Bucket.fromBucketAttributes(scope, id, { bucketArn });
736 }
737 static fromBucketName(scope, id, bucketName) {
738 return Bucket.fromBucketAttributes(scope, id, { bucketName });
739 }
740 /**
741 * Creates a Bucket construct that represents an external bucket.
742 *
743 * @param scope The parent creating construct (usually `this`).
744 * @param id The construct's name.
745 * @param attrs A `BucketAttributes` object. Can be obtained from a call to
746 * `bucket.export()` or manually created.
747 */
748 static fromBucketAttributes(scope, id, attrs) {
749 var _e;
750 try {
751 jsiiDeprecationWarnings._aws_cdk_aws_s3_BucketAttributes(attrs);
752 }
753 catch (error) {
754 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
755 Error.captureStackTrace(error, this.fromBucketAttributes);
756 }
757 throw error;
758 }
759 const stack = core_1.Stack.of(scope);
760 const region = (_e = attrs.region) !== null && _e !== void 0 ? _e : stack.region;
761 const urlSuffix = stack.urlSuffix;
762 const bucketName = util_1.parseBucketName(scope, attrs);
763 if (!bucketName) {
764 throw new Error('Bucket name is required');
765 }
766 Bucket.validateBucketName(bucketName);
767 const newUrlFormat = attrs.bucketWebsiteNewUrlFormat === undefined
768 ? false
769 : attrs.bucketWebsiteNewUrlFormat;
770 const websiteDomain = newUrlFormat
771 ? `${bucketName}.s3-website.${region}.${urlSuffix}`
772 : `${bucketName}.s3-website-${region}.${urlSuffix}`;
773 class Import extends BucketBase {
774 constructor() {
775 var _e;
776 super(...arguments);
777 this.bucketName = bucketName;
778 this.bucketArn = util_1.parseBucketArn(scope, attrs);
779 this.bucketDomainName = attrs.bucketDomainName || `${bucketName}.s3.${urlSuffix}`;
780 this.bucketWebsiteUrl = attrs.bucketWebsiteUrl || `http://${websiteDomain}`;
781 this.bucketWebsiteDomainName = attrs.bucketWebsiteUrl ? core_1.Fn.select(2, core_1.Fn.split('/', attrs.bucketWebsiteUrl)) : websiteDomain;
782 this.bucketRegionalDomainName = attrs.bucketRegionalDomainName || `${bucketName}.s3.${region}.${urlSuffix}`;
783 this.bucketDualStackDomainName = attrs.bucketDualStackDomainName || `${bucketName}.s3.dualstack.${region}.${urlSuffix}`;
784 this.bucketWebsiteNewUrlFormat = newUrlFormat;
785 this.encryptionKey = attrs.encryptionKey;
786 this.isWebsite = (_e = attrs.isWebsite) !== null && _e !== void 0 ? _e : false;
787 this.policy = undefined;
788 this.autoCreatePolicy = false;
789 this.disallowPublicAccess = false;
790 this.notificationsHandlerRole = attrs.notificationsHandlerRole;
791 }
792 /**
793 * Exports this bucket from the stack.
794 */
795 export() {
796 return attrs;
797 }
798 }
799 return new Import(scope, id, {
800 account: attrs.account,
801 region: attrs.region,
802 });
803 }
804 /**
805 * Thrown an exception if the given bucket name is not valid.
806 *
807 * @param physicalName name of the bucket.
808 */
809 static validateBucketName(physicalName) {
810 const bucketName = physicalName;
811 if (!bucketName || core_1.Token.isUnresolved(bucketName)) {
812 // the name is a late-bound value, not a defined string,
813 // so skip validation
814 return;
815 }
816 const errors = [];
817 // Rules codified from https://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html
818 if (bucketName.length < 3 || bucketName.length > 63) {
819 errors.push('Bucket name must be at least 3 and no more than 63 characters');
820 }
821 const charsetMatch = bucketName.match(/[^a-z0-9.-]/);
822 if (charsetMatch) {
823 errors.push('Bucket name must only contain lowercase characters and the symbols, period (.) and dash (-) '
824 + `(offset: ${charsetMatch.index})`);
825 }
826 if (!/[a-z0-9]/.test(bucketName.charAt(0))) {
827 errors.push('Bucket name must start and end with a lowercase character or number '
828 + '(offset: 0)');
829 }
830 if (!/[a-z0-9]/.test(bucketName.charAt(bucketName.length - 1))) {
831 errors.push('Bucket name must start and end with a lowercase character or number '
832 + `(offset: ${bucketName.length - 1})`);
833 }
834 const consecSymbolMatch = bucketName.match(/\.-|-\.|\.\./);
835 if (consecSymbolMatch) {
836 errors.push('Bucket name must not have dash next to period, or period next to dash, or consecutive periods '
837 + `(offset: ${consecSymbolMatch.index})`);
838 }
839 if (/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(bucketName)) {
840 errors.push('Bucket name must not resemble an IP address');
841 }
842 if (errors.length > 0) {
843 throw new Error(`Invalid S3 bucket name (value: ${bucketName})${os_1.EOL}${errors.join(os_1.EOL)}`);
844 }
845 }
846 /**
847 * Add a lifecycle rule to the bucket
848 *
849 * @param rule The rule to add
850 */
851 addLifecycleRule(rule) {
852 try {
853 jsiiDeprecationWarnings._aws_cdk_aws_s3_LifecycleRule(rule);
854 }
855 catch (error) {
856 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
857 Error.captureStackTrace(error, this.addLifecycleRule);
858 }
859 throw error;
860 }
861 if ((rule.noncurrentVersionExpiration !== undefined
862 || (rule.noncurrentVersionTransitions && rule.noncurrentVersionTransitions.length > 0))
863 && !this.versioned) {
864 throw new Error("Cannot use 'noncurrent' rules on a nonversioned bucket");
865 }
866 this.lifecycleRules.push(rule);
867 }
868 /**
869 * Adds a metrics configuration for the CloudWatch request metrics from the bucket.
870 *
871 * @param metric The metric configuration to add
872 */
873 addMetric(metric) {
874 try {
875 jsiiDeprecationWarnings._aws_cdk_aws_s3_BucketMetrics(metric);
876 }
877 catch (error) {
878 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
879 Error.captureStackTrace(error, this.addMetric);
880 }
881 throw error;
882 }
883 this.metrics.push(metric);
884 }
885 /**
886 * Adds a cross-origin access configuration for objects in an Amazon S3 bucket
887 *
888 * @param rule The CORS configuration rule to add
889 */
890 addCorsRule(rule) {
891 try {
892 jsiiDeprecationWarnings._aws_cdk_aws_s3_CorsRule(rule);
893 }
894 catch (error) {
895 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
896 Error.captureStackTrace(error, this.addCorsRule);
897 }
898 throw error;
899 }
900 this.cors.push(rule);
901 }
902 /**
903 * Add an inventory configuration.
904 *
905 * @param inventory configuration to add
906 */
907 addInventory(inventory) {
908 try {
909 jsiiDeprecationWarnings._aws_cdk_aws_s3_Inventory(inventory);
910 }
911 catch (error) {
912 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
913 Error.captureStackTrace(error, this.addInventory);
914 }
915 throw error;
916 }
917 this.inventories.push(inventory);
918 }
919 /**
920 * Adds an iam statement to enforce SSL requests only.
921 */
922 enforceSSLStatement() {
923 const statement = new iam.PolicyStatement({
924 actions: ['s3:*'],
925 conditions: {
926 Bool: { 'aws:SecureTransport': 'false' },
927 },
928 effect: iam.Effect.DENY,
929 resources: [
930 this.bucketArn,
931 this.arnForObjects('*'),
932 ],
933 principals: [new iam.AnyPrincipal()],
934 });
935 this.addToResourcePolicy(statement);
936 }
937 /**
938 * Set up key properties and return the Bucket encryption property from the
939 * user's configuration.
940 */
941 parseEncryption(props) {
942 // default based on whether encryptionKey is specified
943 let encryptionType = props.encryption;
944 if (encryptionType === undefined) {
945 encryptionType = props.encryptionKey ? BucketEncryption.KMS : BucketEncryption.UNENCRYPTED;
946 }
947 // if encryption key is set, encryption must be set to KMS.
948 if (encryptionType !== BucketEncryption.KMS && props.encryptionKey) {
949 throw new Error(`encryptionKey is specified, so 'encryption' must be set to KMS (value: ${encryptionType})`);
950 }
951 // if bucketKeyEnabled is set, encryption must be set to KMS.
952 if (props.bucketKeyEnabled && encryptionType !== BucketEncryption.KMS) {
953 throw new Error(`bucketKeyEnabled is specified, so 'encryption' must be set to KMS (value: ${encryptionType})`);
954 }
955 if (encryptionType === BucketEncryption.UNENCRYPTED) {
956 return { bucketEncryption: undefined, encryptionKey: undefined };
957 }
958 if (encryptionType === BucketEncryption.KMS) {
959 const encryptionKey = props.encryptionKey || new kms.Key(this, 'Key', {
960 description: `Created by ${this.node.path}`,
961 });
962 const bucketEncryption = {
963 serverSideEncryptionConfiguration: [
964 {
965 bucketKeyEnabled: props.bucketKeyEnabled,
966 serverSideEncryptionByDefault: {
967 sseAlgorithm: 'aws:kms',
968 kmsMasterKeyId: encryptionKey.keyArn,
969 },
970 },
971 ],
972 };
973 return { encryptionKey, bucketEncryption };
974 }
975 if (encryptionType === BucketEncryption.S3_MANAGED) {
976 const bucketEncryption = {
977 serverSideEncryptionConfiguration: [
978 { serverSideEncryptionByDefault: { sseAlgorithm: 'AES256' } },
979 ],
980 };
981 return { bucketEncryption };
982 }
983 if (encryptionType === BucketEncryption.KMS_MANAGED) {
984 const bucketEncryption = {
985 serverSideEncryptionConfiguration: [
986 { serverSideEncryptionByDefault: { sseAlgorithm: 'aws:kms' } },
987 ],
988 };
989 return { bucketEncryption };
990 }
991 throw new Error(`Unexpected 'encryptionType': ${encryptionType}`);
992 }
993 /**
994 * Parse the lifecycle configuration out of the bucket props
995 * @param props Par
996 */
997 parseLifecycleConfiguration() {
998 if (!this.lifecycleRules || this.lifecycleRules.length === 0) {
999 return undefined;
1000 }
1001 const self = this;
1002 return { rules: this.lifecycleRules.map(parseLifecycleRule) };
1003 function parseLifecycleRule(rule) {
1004 var _e, _f;
1005 const enabled = (_e = rule.enabled) !== null && _e !== void 0 ? _e : true;
1006 const x = {
1007 // eslint-disable-next-line max-len
1008 abortIncompleteMultipartUpload: rule.abortIncompleteMultipartUploadAfter !== undefined ? { daysAfterInitiation: rule.abortIncompleteMultipartUploadAfter.toDays() } : undefined,
1009 expirationDate: rule.expirationDate,
1010 expirationInDays: (_f = rule.expiration) === null || _f === void 0 ? void 0 : _f.toDays(),
1011 id: rule.id,
1012 noncurrentVersionExpirationInDays: rule.noncurrentVersionExpiration && rule.noncurrentVersionExpiration.toDays(),
1013 noncurrentVersionTransitions: mapOrUndefined(rule.noncurrentVersionTransitions, t => ({
1014 storageClass: t.storageClass.value,
1015 transitionInDays: t.transitionAfter.toDays(),
1016 newerNoncurrentVersions: t.noncurrentVersionsToRetain,
1017 })),
1018 prefix: rule.prefix,
1019 status: enabled ? 'Enabled' : 'Disabled',
1020 transitions: mapOrUndefined(rule.transitions, t => ({
1021 storageClass: t.storageClass.value,
1022 transitionDate: t.transitionDate,
1023 transitionInDays: t.transitionAfter && t.transitionAfter.toDays(),
1024 })),
1025 expiredObjectDeleteMarker: rule.expiredObjectDeleteMarker,
1026 tagFilters: self.parseTagFilters(rule.tagFilters),
1027 };
1028 return x;
1029 }
1030 }
1031 parseServerAccessLogs(props) {
1032 var _e;
1033 if (!props.serverAccessLogsBucket && !props.serverAccessLogsPrefix) {
1034 return undefined;
1035 }
1036 return {
1037 destinationBucketName: (_e = props.serverAccessLogsBucket) === null || _e === void 0 ? void 0 : _e.bucketName,
1038 logFilePrefix: props.serverAccessLogsPrefix,
1039 };
1040 }
1041 parseMetricConfiguration() {
1042 if (!this.metrics || this.metrics.length === 0) {
1043 return undefined;
1044 }
1045 const self = this;
1046 return this.metrics.map(parseMetric);
1047 function parseMetric(metric) {
1048 return {
1049 id: metric.id,
1050 prefix: metric.prefix,
1051 tagFilters: self.parseTagFilters(metric.tagFilters),
1052 };
1053 }
1054 }
1055 parseCorsConfiguration() {
1056 if (!this.cors || this.cors.length === 0) {
1057 return undefined;
1058 }
1059 return { corsRules: this.cors.map(parseCors) };
1060 function parseCors(rule) {
1061 return {
1062 id: rule.id,
1063 maxAge: rule.maxAge,
1064 allowedHeaders: rule.allowedHeaders,
1065 allowedMethods: rule.allowedMethods,
1066 allowedOrigins: rule.allowedOrigins,
1067 exposedHeaders: rule.exposedHeaders,
1068 };
1069 }
1070 }
1071 parseTagFilters(tagFilters) {
1072 if (!tagFilters || tagFilters.length === 0) {
1073 return undefined;
1074 }
1075 return Object.keys(tagFilters).map(tag => ({
1076 key: tag,
1077 value: tagFilters[tag],
1078 }));
1079 }
1080 parseOwnershipControls({ objectOwnership }) {
1081 if (!objectOwnership) {
1082 return undefined;
1083 }
1084 return {
1085 rules: [{
1086 objectOwnership,
1087 }],
1088 };
1089 }
1090 parseTieringConfig({ intelligentTieringConfigurations }) {
1091 if (!intelligentTieringConfigurations) {
1092 return undefined;
1093 }
1094 return intelligentTieringConfigurations.map(config => {
1095 const tierings = [];
1096 if (config.archiveAccessTierTime) {
1097 tierings.push({
1098 accessTier: 'ARCHIVE_ACCESS',
1099 days: config.archiveAccessTierTime.toDays({ integral: true }),
1100 });
1101 }
1102 if (config.deepArchiveAccessTierTime) {
1103 tierings.push({
1104 accessTier: 'DEEP_ARCHIVE_ACCESS',
1105 days: config.deepArchiveAccessTierTime.toDays({ integral: true }),
1106 });
1107 }
1108 return {
1109 id: config.name,
1110 prefix: config.prefix,
1111 status: 'Enabled',
1112 tagFilters: config.tags,
1113 tierings: tierings,
1114 };
1115 });
1116 }
1117 renderWebsiteConfiguration(props) {
1118 if (!props.websiteErrorDocument && !props.websiteIndexDocument && !props.websiteRedirect && !props.websiteRoutingRules) {
1119 return undefined;
1120 }
1121 if (props.websiteErrorDocument && !props.websiteIndexDocument) {
1122 throw new Error('"websiteIndexDocument" is required if "websiteErrorDocument" is set');
1123 }
1124 if (props.websiteRedirect && (props.websiteErrorDocument || props.websiteIndexDocument || props.websiteRoutingRules)) {
1125 throw new Error('"websiteIndexDocument", "websiteErrorDocument" and, "websiteRoutingRules" cannot be set if "websiteRedirect" is used');
1126 }
1127 const routingRules = props.websiteRoutingRules ? props.websiteRoutingRules.map((rule) => {
1128 if (rule.condition && !rule.condition.httpErrorCodeReturnedEquals && !rule.condition.keyPrefixEquals) {
1129 throw new Error('The condition property cannot be an empty object');
1130 }
1131 return {
1132 redirectRule: {
1133 hostName: rule.hostName,
1134 httpRedirectCode: rule.httpRedirectCode,
1135 protocol: rule.protocol,
1136 replaceKeyWith: rule.replaceKey && rule.replaceKey.withKey,
1137 replaceKeyPrefixWith: rule.replaceKey && rule.replaceKey.prefixWithKey,
1138 },
1139 routingRuleCondition: rule.condition,
1140 };
1141 }) : undefined;
1142 return {
1143 indexDocument: props.websiteIndexDocument,
1144 errorDocument: props.websiteErrorDocument,
1145 redirectAllRequestsTo: props.websiteRedirect,
1146 routingRules,
1147 };
1148 }
1149 /**
1150 * Allows the LogDelivery group to write, fails if ACL was set differently.
1151 *
1152 * @see
1153 * https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl
1154 */
1155 allowLogDelivery() {
1156 if (this.accessControl && this.accessControl !== BucketAccessControl.LOG_DELIVERY_WRITE) {
1157 throw new Error("Cannot enable log delivery to this bucket because the bucket's ACL has been set and can't be changed");
1158 }
1159 this.accessControl = BucketAccessControl.LOG_DELIVERY_WRITE;
1160 }
1161 parseInventoryConfiguration() {
1162 if (!this.inventories || this.inventories.length === 0) {
1163 return undefined;
1164 }
1165 return this.inventories.map((inventory, index) => {
1166 var _e, _f, _g, _h, _j, _k;
1167 const format = (_e = inventory.format) !== null && _e !== void 0 ? _e : InventoryFormat.CSV;
1168 const frequency = (_f = inventory.frequency) !== null && _f !== void 0 ? _f : InventoryFrequency.WEEKLY;
1169 const id = (_g = inventory.inventoryId) !== null && _g !== void 0 ? _g : `${this.node.id}Inventory${index}`;
1170 if (inventory.destination.bucket instanceof Bucket) {
1171 inventory.destination.bucket.addToResourcePolicy(new iam.PolicyStatement({
1172 effect: iam.Effect.ALLOW,
1173 actions: ['s3:PutObject'],
1174 resources: [
1175 inventory.destination.bucket.bucketArn,
1176 inventory.destination.bucket.arnForObjects(`${(_h = inventory.destination.prefix) !== null && _h !== void 0 ? _h : ''}*`),
1177 ],
1178 principals: [new iam.ServicePrincipal('s3.amazonaws.com')],
1179 conditions: {
1180 ArnLike: {
1181 'aws:SourceArn': this.bucketArn,
1182 },
1183 },
1184 }));
1185 }
1186 return {
1187 id,
1188 destination: {
1189 bucketArn: inventory.destination.bucket.bucketArn,
1190 bucketAccountId: inventory.destination.bucketOwner,
1191 prefix: inventory.destination.prefix,
1192 format,
1193 },
1194 enabled: (_j = inventory.enabled) !== null && _j !== void 0 ? _j : true,
1195 includedObjectVersions: (_k = inventory.includeObjectVersions) !== null && _k !== void 0 ? _k : InventoryObjectVersion.ALL,
1196 scheduleFrequency: frequency,
1197 optionalFields: inventory.optionalFields,
1198 prefix: inventory.objectsPrefix,
1199 };
1200 });
1201 }
1202 enableAutoDeleteObjects() {
1203 const provider = core_1.CustomResourceProvider.getOrCreateProvider(this, AUTO_DELETE_OBJECTS_RESOURCE_TYPE, {
1204 codeDirectory: path.join(__dirname, 'auto-delete-objects-handler'),
1205 runtime: core_1.CustomResourceProviderRuntime.NODEJS_12_X,
1206 description: `Lambda function for auto-deleting objects in ${this.bucketName} S3 bucket.`,
1207 });
1208 // Use a bucket policy to allow the custom resource to delete
1209 // objects in the bucket
1210 this.addToResourcePolicy(new iam.PolicyStatement({
1211 actions: [
1212 // list objects
1213 ...perms.BUCKET_READ_METADATA_ACTIONS,
1214 ...perms.BUCKET_DELETE_ACTIONS,
1215 ],
1216 resources: [
1217 this.bucketArn,
1218 this.arnForObjects('*'),
1219 ],
1220 principals: [new iam.ArnPrincipal(provider.roleArn)],
1221 }));
1222 const customResource = new core_1.CustomResource(this, 'AutoDeleteObjectsCustomResource', {
1223 resourceType: AUTO_DELETE_OBJECTS_RESOURCE_TYPE,
1224 serviceToken: provider.serviceToken,
1225 properties: {
1226 BucketName: this.bucketName,
1227 },
1228 });
1229 // Ensure bucket policy is deleted AFTER the custom resource otherwise
1230 // we don't have permissions to list and delete in the bucket.
1231 // (add a `if` to make TS happy)
1232 if (this.policy) {
1233 customResource.node.addDependency(this.policy);
1234 }
1235 // We also tag the bucket to record the fact that we want it autodeleted.
1236 // The custom resource will check this tag before actually doing the delete.
1237 // Because tagging and untagging will ALWAYS happen before the CR is deleted,
1238 // we can set `autoDeleteObjects: false` without the removal of the CR emptying
1239 // the bucket as a side effect.
1240 core_1.Tags.of(this._resource).add(AUTO_DELETE_OBJECTS_TAG, 'true');
1241 }
1242}
1243exports.Bucket = Bucket;
1244_c = JSII_RTTI_SYMBOL_1;
1245Bucket[_c] = { fqn: "@aws-cdk/aws-s3.Bucket", version: "1.156.1" };
1246/**
1247 * What kind of server-side encryption to apply to this bucket
1248 */
1249var BucketEncryption;
1250(function (BucketEncryption) {
1251 /**
1252 * Objects in the bucket are not encrypted.
1253 */
1254 BucketEncryption["UNENCRYPTED"] = "NONE";
1255 /**
1256 * Server-side KMS encryption with a master key managed by KMS.
1257 */
1258 BucketEncryption["KMS_MANAGED"] = "MANAGED";
1259 /**
1260 * Server-side encryption with a master key managed by S3.
1261 */
1262 BucketEncryption["S3_MANAGED"] = "S3MANAGED";
1263 /**
1264 * Server-side encryption with a KMS key managed by the user.
1265 * If `encryptionKey` is specified, this key will be used, otherwise, one will be defined.
1266 */
1267 BucketEncryption["KMS"] = "KMS";
1268})(BucketEncryption = exports.BucketEncryption || (exports.BucketEncryption = {}));
1269/**
1270 * Notification event types.
1271 * @link https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-event-types-and-destinations.html#supported-notification-event-types
1272 */
1273var EventType;
1274(function (EventType) {
1275 /**
1276 * Amazon S3 APIs such as PUT, POST, and COPY can create an object. Using
1277 * these event types, you can enable notification when an object is created
1278 * using a specific API, or you can use the s3:ObjectCreated:* event type to
1279 * request notification regardless of the API that was used to create an
1280 * object.
1281 */
1282 EventType["OBJECT_CREATED"] = "s3:ObjectCreated:*";
1283 /**
1284 * Amazon S3 APIs such as PUT, POST, and COPY can create an object. Using
1285 * these event types, you can enable notification when an object is created
1286 * using a specific API, or you can use the s3:ObjectCreated:* event type to
1287 * request notification regardless of the API that was used to create an
1288 * object.
1289 */
1290 EventType["OBJECT_CREATED_PUT"] = "s3:ObjectCreated:Put";
1291 /**
1292 * Amazon S3 APIs such as PUT, POST, and COPY can create an object. Using
1293 * these event types, you can enable notification when an object is created
1294 * using a specific API, or you can use the s3:ObjectCreated:* event type to
1295 * request notification regardless of the API that was used to create an
1296 * object.
1297 */
1298 EventType["OBJECT_CREATED_POST"] = "s3:ObjectCreated:Post";
1299 /**
1300 * Amazon S3 APIs such as PUT, POST, and COPY can create an object. Using
1301 * these event types, you can enable notification when an object is created
1302 * using a specific API, or you can use the s3:ObjectCreated:* event type to
1303 * request notification regardless of the API that was used to create an
1304 * object.
1305 */
1306 EventType["OBJECT_CREATED_COPY"] = "s3:ObjectCreated:Copy";
1307 /**
1308 * Amazon S3 APIs such as PUT, POST, and COPY can create an object. Using
1309 * these event types, you can enable notification when an object is created
1310 * using a specific API, or you can use the s3:ObjectCreated:* event type to
1311 * request notification regardless of the API that was used to create an
1312 * object.
1313 */
1314 EventType["OBJECT_CREATED_COMPLETE_MULTIPART_UPLOAD"] = "s3:ObjectCreated:CompleteMultipartUpload";
1315 /**
1316 * By using the ObjectRemoved event types, you can enable notification when
1317 * an object or a batch of objects is removed from a bucket.
1318 *
1319 * You can request notification when an object is deleted or a versioned
1320 * object is permanently deleted by using the s3:ObjectRemoved:Delete event
1321 * type. Or you can request notification when a delete marker is created for
1322 * a versioned object by using s3:ObjectRemoved:DeleteMarkerCreated. For
1323 * information about deleting versioned objects, see Deleting Object
1324 * Versions. You can also use a wildcard s3:ObjectRemoved:* to request
1325 * notification anytime an object is deleted.
1326 *
1327 * You will not receive event notifications from automatic deletes from
1328 * lifecycle policies or from failed operations.
1329 */
1330 EventType["OBJECT_REMOVED"] = "s3:ObjectRemoved:*";
1331 /**
1332 * By using the ObjectRemoved event types, you can enable notification when
1333 * an object or a batch of objects is removed from a bucket.
1334 *
1335 * You can request notification when an object is deleted or a versioned
1336 * object is permanently deleted by using the s3:ObjectRemoved:Delete event
1337 * type. Or you can request notification when a delete marker is created for
1338 * a versioned object by using s3:ObjectRemoved:DeleteMarkerCreated. For
1339 * information about deleting versioned objects, see Deleting Object
1340 * Versions. You can also use a wildcard s3:ObjectRemoved:* to request
1341 * notification anytime an object is deleted.
1342 *
1343 * You will not receive event notifications from automatic deletes from
1344 * lifecycle policies or from failed operations.
1345 */
1346 EventType["OBJECT_REMOVED_DELETE"] = "s3:ObjectRemoved:Delete";
1347 /**
1348 * By using the ObjectRemoved event types, you can enable notification when
1349 * an object or a batch of objects is removed from a bucket.
1350 *
1351 * You can request notification when an object is deleted or a versioned
1352 * object is permanently deleted by using the s3:ObjectRemoved:Delete event
1353 * type. Or you can request notification when a delete marker is created for
1354 * a versioned object by using s3:ObjectRemoved:DeleteMarkerCreated. For
1355 * information about deleting versioned objects, see Deleting Object
1356 * Versions. You can also use a wildcard s3:ObjectRemoved:* to request
1357 * notification anytime an object is deleted.
1358 *
1359 * You will not receive event notifications from automatic deletes from
1360 * lifecycle policies or from failed operations.
1361 */
1362 EventType["OBJECT_REMOVED_DELETE_MARKER_CREATED"] = "s3:ObjectRemoved:DeleteMarkerCreated";
1363 /**
1364 * Using restore object event types you can receive notifications for
1365 * initiation and completion when restoring objects from the S3 Glacier
1366 * storage class.
1367 *
1368 * You use s3:ObjectRestore:Post to request notification of object restoration
1369 * initiation.
1370 */
1371 EventType["OBJECT_RESTORE_POST"] = "s3:ObjectRestore:Post";
1372 /**
1373 * Using restore object event types you can receive notifications for
1374 * initiation and completion when restoring objects from the S3 Glacier
1375 * storage class.
1376 *
1377 * You use s3:ObjectRestore:Completed to request notification of
1378 * restoration completion.
1379 */
1380 EventType["OBJECT_RESTORE_COMPLETED"] = "s3:ObjectRestore:Completed";
1381 /**
1382 * Using restore object event types you can receive notifications for
1383 * initiation and completion when restoring objects from the S3 Glacier
1384 * storage class.
1385 *
1386 * You use s3:ObjectRestore:Delete to request notification of
1387 * restoration completion.
1388 */
1389 EventType["OBJECT_RESTORE_DELETE"] = "s3:ObjectRestore:Delete";
1390 /**
1391 * You can use this event type to request Amazon S3 to send a notification
1392 * message when Amazon S3 detects that an object of the RRS storage class is
1393 * lost.
1394 */
1395 EventType["REDUCED_REDUNDANCY_LOST_OBJECT"] = "s3:ReducedRedundancyLostObject";
1396 /**
1397 * You receive this notification event when an object that was eligible for
1398 * replication using Amazon S3 Replication Time Control failed to replicate.
1399 */
1400 EventType["REPLICATION_OPERATION_FAILED_REPLICATION"] = "s3:Replication:OperationFailedReplication";
1401 /**
1402 * You receive this notification event when an object that was eligible for
1403 * replication using Amazon S3 Replication Time Control exceeded the 15-minute
1404 * threshold for replication.
1405 */
1406 EventType["REPLICATION_OPERATION_MISSED_THRESHOLD"] = "s3:Replication:OperationMissedThreshold";
1407 /**
1408 * You receive this notification event for an object that was eligible for
1409 * replication using the Amazon S3 Replication Time Control feature replicated
1410 * after the 15-minute threshold.
1411 */
1412 EventType["REPLICATION_OPERATION_REPLICATED_AFTER_THRESHOLD"] = "s3:Replication:OperationReplicatedAfterThreshold";
1413 /**
1414 * You receive this notification event for an object that was eligible for
1415 * replication using Amazon S3 Replication Time Control but is no longer tracked
1416 * by replication metrics.
1417 */
1418 EventType["REPLICATION_OPERATION_NOT_TRACKED"] = "s3:Replication:OperationNotTracked";
1419 /**
1420 * By using the LifecycleExpiration event types, you can receive a notification
1421 * when Amazon S3 deletes an object based on your S3 Lifecycle configuration.
1422 */
1423 EventType["LIFECYCLE_EXPIRATION"] = "s3:LifecycleExpiration:*";
1424 /**
1425 * The s3:LifecycleExpiration:Delete event type notifies you when an object
1426 * in an unversioned bucket is deleted.
1427 * It also notifies you when an object version is permanently deleted by an
1428 * S3 Lifecycle configuration.
1429 */
1430 EventType["LIFECYCLE_EXPIRATION_DELETE"] = "s3:LifecycleExpiration:Delete";
1431 /**
1432 * The s3:LifecycleExpiration:DeleteMarkerCreated event type notifies you
1433 * when S3 Lifecycle creates a delete marker when a current version of an
1434 * object in versioned bucket is deleted.
1435 */
1436 EventType["LIFECYCLE_EXPIRATION_DELETE_MARKER_CREATED"] = "s3:LifecycleExpiration:DeleteMarkerCreated";
1437 /**
1438 * You receive this notification event when an object is transitioned to
1439 * another Amazon S3 storage class by an S3 Lifecycle configuration.
1440 */
1441 EventType["LIFECYCLE_TRANSITION"] = "s3:LifecycleTransition";
1442 /**
1443 * You receive this notification event when an object within the
1444 * S3 Intelligent-Tiering storage class moved to the Archive Access tier or
1445 * Deep Archive Access tier.
1446 */
1447 EventType["INTELLIGENT_TIERING"] = "s3:IntelligentTiering";
1448 /**
1449 * By using the ObjectTagging event types, you can enable notification when
1450 * an object tag is added or deleted from an object.
1451 */
1452 EventType["OBJECT_TAGGING"] = "s3:ObjectTagging:*";
1453 /**
1454 * The s3:ObjectTagging:Put event type notifies you when a tag is PUT on an
1455 * object or an existing tag is updated.
1456
1457 */
1458 EventType["OBJECT_TAGGING_PUT"] = "s3:ObjectTagging:Put";
1459 /**
1460 * The s3:ObjectTagging:Delete event type notifies you when a tag is removed
1461 * from an object.
1462 */
1463 EventType["OBJECT_TAGGING_DELETE"] = "s3:ObjectTagging:Delete";
1464 /**
1465 * You receive this notification event when an ACL is PUT on an object or when
1466 * an existing ACL is changed.
1467 * An event is not generated when a request results in no change to an
1468 * object’s ACL.
1469 */
1470 EventType["OBJECT_ACL_PUT"] = "s3:ObjectAcl:Put";
1471})(EventType = exports.EventType || (exports.EventType = {}));
1472/**
1473 * Default bucket access control types.
1474 *
1475 * @see https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html
1476 */
1477var BucketAccessControl;
1478(function (BucketAccessControl) {
1479 /**
1480 * Owner gets FULL_CONTROL. No one else has access rights.
1481 */
1482 BucketAccessControl["PRIVATE"] = "Private";
1483 /**
1484 * Owner gets FULL_CONTROL. The AllUsers group gets READ access.
1485 */
1486 BucketAccessControl["PUBLIC_READ"] = "PublicRead";
1487 /**
1488 * Owner gets FULL_CONTROL. The AllUsers group gets READ and WRITE access.
1489 * Granting this on a bucket is generally not recommended.
1490 */
1491 BucketAccessControl["PUBLIC_READ_WRITE"] = "PublicReadWrite";
1492 /**
1493 * Owner gets FULL_CONTROL. The AuthenticatedUsers group gets READ access.
1494 */
1495 BucketAccessControl["AUTHENTICATED_READ"] = "AuthenticatedRead";
1496 /**
1497 * The LogDelivery group gets WRITE and READ_ACP permissions on the bucket.
1498 * @see https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerLogs.html
1499 */
1500 BucketAccessControl["LOG_DELIVERY_WRITE"] = "LogDeliveryWrite";
1501 /**
1502 * Object owner gets FULL_CONTROL. Bucket owner gets READ access.
1503 * If you specify this canned ACL when creating a bucket, Amazon S3 ignores it.
1504 */
1505 BucketAccessControl["BUCKET_OWNER_READ"] = "BucketOwnerRead";
1506 /**
1507 * Both the object owner and the bucket owner get FULL_CONTROL over the object.
1508 * If you specify this canned ACL when creating a bucket, Amazon S3 ignores it.
1509 */
1510 BucketAccessControl["BUCKET_OWNER_FULL_CONTROL"] = "BucketOwnerFullControl";
1511 /**
1512 * Owner gets FULL_CONTROL. Amazon EC2 gets READ access to GET an Amazon Machine Image (AMI) bundle from Amazon S3.
1513 */
1514 BucketAccessControl["AWS_EXEC_READ"] = "AwsExecRead";
1515})(BucketAccessControl = exports.BucketAccessControl || (exports.BucketAccessControl = {}));
1516class ReplaceKey {
1517 constructor(withKey, prefixWithKey) {
1518 this.withKey = withKey;
1519 this.prefixWithKey = prefixWithKey;
1520 }
1521 /**
1522 * The specific object key to use in the redirect request
1523 */
1524 static with(keyReplacement) {
1525 return new this(keyReplacement);
1526 }
1527 /**
1528 * The object key prefix to use in the redirect request
1529 */
1530 static prefixWith(keyReplacement) {
1531 return new this(undefined, keyReplacement);
1532 }
1533}
1534exports.ReplaceKey = ReplaceKey;
1535_d = JSII_RTTI_SYMBOL_1;
1536ReplaceKey[_d] = { fqn: "@aws-cdk/aws-s3.ReplaceKey", version: "1.156.1" };
1537function mapOrUndefined(list, callback) {
1538 if (!list || list.length === 0) {
1539 return undefined;
1540 }
1541 return list.map(callback);
1542}
1543//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVja2V0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYnVja2V0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLDJCQUF5QjtBQUN6Qiw2QkFBNkI7QUFDN0IsOENBQThDO0FBQzlDLHdDQUF3QztBQUN4Qyx3Q0FBd0M7QUFDeEMsd0NBR3VCO0FBQ3ZCLHlDQUF5QztBQUV6QyxtREFBK0M7QUFFL0MscUVBQStEO0FBQy9ELGlDQUFpQztBQUVqQyxpREFBMkM7QUFDM0MsaUNBQXlEO0FBRXpELE1BQU0saUNBQWlDLEdBQUcsNkJBQTZCLENBQUM7QUFDeEUsTUFBTSx1QkFBdUIsR0FBRyw2QkFBNkIsQ0FBQztBQWthOUQ7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7QUFDSCxNQUFzQixVQUFXLFNBQVEsZUFBUTtJQTBDL0MsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxRQUF1QixFQUFFO1FBQ2pFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO0tBQ3pCO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSSxpQkFBaUIsQ0FBQyxFQUFVLEVBQUUsVUFBMEMsRUFBRTs7Ozs7Ozs7Ozs7UUFDL0UsTUFBTSxJQUFJLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDaEQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDL0IsSUFBSSxDQUFDLGVBQWUsQ0FBQztZQUNuQixNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUM7WUFDbEIsVUFBVSxFQUFFLENBQUMsNkJBQTZCLENBQUM7WUFDM0MsTUFBTSxFQUFFO2dCQUNOLFNBQVMsRUFBRTtvQkFDVCxHQUFHLGNBQUUsT0FBTyxDQUFDLEtBQUssMENBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsb0NB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QUFJLENBQUMsY0FBc0I7UUFDdkMsT0FBTyxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztLQUNqQztJQUVEOztPQUVHO0lBQ0ksTUFBTSxDQUFDLFVBQVUsQ0FBQyxjQUFzQjtRQUM3QyxPQUFPLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxjQUFjLENBQUMsQ0FBQztLQUM1Qzs7QUFiSCxnQ0FpQkM7OztBQW9FRCxTQUFTLGNBQWMsQ0FBTyxJQUFxQixFQUFFLFFBQTJCO0lBQzlFLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7UUFDOUIsT0FBTyxTQUFTLENBQUM7S0FDbEI7SUFFRCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDNUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEVPTCB9IGZyb20gJ29zJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgKiBhcyBldmVudHMgZnJvbSAnQGF3cy1jZGsvYXdzLWV2ZW50cyc7XG5pbXBvcnQgKiBhcyBpYW0gZnJvbSAnQGF3cy1jZGsvYXdzLWlhbSc7XG5pbXBvcnQgKiBhcyBrbXMgZnJvbSAnQGF3cy1jZGsvYXdzLWttcyc7XG5pbXBvcnQge1xuICBGbiwgSVJlc291cmNlLCBMYXp5LCBSZW1vdmFsUG9saWN5LCBSZXNvdXJjZSwgUmVzb3VyY2VQcm9wcywgU3RhY2ssIFRva2VuLFxuICBDdXN0b21SZXNvdXJjZSwgQ3VzdG9tUmVzb3VyY2VQcm92aWRlciwgQ3VzdG9tUmVzb3VyY2VQcm92aWRlclJ1bnRpbWUsIEZlYXR1cmVGbGFncywgVGFncywgRHVyYXRpb24sXG59IGZyb20gJ0Bhd3MtY2RrL2NvcmUnO1xuaW1wb3J0ICogYXMgY3hhcGkgZnJvbSAnQGF3cy1jZGsvY3gtYXBpJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgQnVja2V0UG9saWN5IH0gZnJvbSAnLi9idWNrZXQtcG9saWN5JztcbmltcG9ydCB7IElCdWNrZXROb3RpZmljYXRpb25EZXN0aW5hdGlvbiB9IGZyb20gJy4vZGVzdGluYXRpb24nO1xuaW1wb3J0IHsgQnVja2V0Tm90aWZpY2F0aW9ucyB9IGZyb20gJy4vbm90aWZpY2F0aW9ucy1yZXNvdXJjZSc7XG5pbXBvcnQgKiBhcyBwZXJtcyBmcm9tICcuL3Blcm1zJztcbmltcG9ydCB7IExpZmVjeWNsZVJ1bGUgfSBmcm9tICcuL3J1bGUnO1xuaW1wb3J0IHsgQ2ZuQnVja2V0IH0gZnJvbSAnLi9zMy5nZW5lcmF0ZWQnO1xuaW1wb3J0IHsgcGFyc2VCdWNrZXRBcm4sIHBhcnNlQnVja2V0TmFtZSB9IGZyb20gJy4vdXRpbCc7XG5cbmNvbnN0IEFVVE9fREVMRVRFX09CSkVDVFNfUkVTT1VSQ0VfVFlQRSA9ICdDdXN0b206OlMzQXV0b0RlbGV0ZU9iamVjdHMnO1xuY29uc3QgQVVUT19ERUxFVEVfT0JKRUNUU19UQUcgPSAnYXdzLWNkazphdXRvLWRlbGV0ZS1vYmplY3RzJztcblxuZXhwb3J0IGludGVyZmFjZSBJQnVja2V0IGV4dGVuZHMgSVJlc291cmNlIHtcbiAgLyoqXG4gICAqIFRoZSBBUk4gb2YgdGhlIGJ1Y2tldC5cbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgYnVja2V0QXJuOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBidWNrZXQuXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IGJ1Y2tldE5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIFVSTCBvZiB0aGUgc3RhdGljIHdlYnNpdGUuXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IGJ1Y2tldFdlYnNpdGVVcmw6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIERvbWFpbiBuYW1lIG9mIHRoZSBzdGF0aWMgd2Vic2l0ZS5cbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgYnVja2V0V2Vic2l0ZURvbWFpbk5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIElQdjQgRE5TIG5hbWUgb2YgdGhlIHNwZWNpZmllZCBidWNrZXQuXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IGJ1Y2tldERvbWFpbk5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIElQdjYgRE5TIG5hbWUgb2YgdGhlIHNwZWNpZmllZCBidWNrZXQuXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IGJ1Y2tldER1YWxTdGFja0RvbWFpbk5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHJlZ2lvbmFsIGRvbWFpbiBuYW1lIG9mIHRoZSBzcGVjaWZpZWQgYnVja2V0LlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSBidWNrZXRSZWdpb25hbERvbWFpbk5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogSWYgdGhpcyBidWNrZXQgaGFzIGJlZW4gY29uZmlndXJlZCBmb3Igc3RhdGljIHdlYnNpdGUgaG9zdGluZy5cbiAgICovXG4gIHJlYWRvbmx5IGlzV2Vic2l0ZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIEtNUyBlbmNyeXB0aW9uIGtleSBhc3NvY2lhdGVkIHdpdGggdGhpcyBidWNrZXQuXG4gICAqL1xuICByZWFkb25seSBlbmNyeXB0aW9uS2V5Pzoga21zLklLZXk7XG5cbiAgLyoqXG4gICAqIFRoZSByZXNvdXJjZSBwb2xpY3kgYXNzb2NpYXRlZCB3aXRoIHRoaXMgYnVja2V0LlxuICAgKlxuICAgKiBJZiBgYXV0b0NyZWF0ZVBvbGljeWAgaXMgdHJ1ZSwgYSBgQnVja2V0UG9saWN5YCB3aWxsIGJlIGNyZWF0ZWQgdXBvbiB0aGVcbiAgICogZmlyc3QgY2FsbCB0byBhZGRUb1Jlc291cmNlUG9saWN5KHMpLlxuICAgKi9cbiAgcG9saWN5PzogQnVja2V0UG9saWN5O1xuXG4gIC8qKlxuICAgKiBBZGRzIGEgc3RhdGVtZW50IHRvIHRoZSByZXNvdXJjZSBwb2xpY3kgZm9yIGEgcHJpbmNpcGFsIChpLmUuXG4gICAqIGFjY291bnQvcm9sZS9zZXJ2aWNlKSB0byBwZXJmb3JtIGFjdGlvbnMgb24gdGhpcyBidWNrZXQgYW5kL29yIGl0c1xuICAgKiBjb250ZW50cy4gVXNlIGBidWNrZXRBcm5gIGFuZCBgYXJuRm9yT2JqZWN0cyhrZXlzKWAgdG8gb2J0YWluIEFSTnMgZm9yXG4gICAqIHRoaXMgYnVja2V0IG9yIG9iamVjdHMuXG4gICAqXG4gICAqIE5vdGUgdGhhdCB0aGUgcG9saWN5IHN0YXRlbWVudCBtYXkgb3IgbWF5IG5vdCBiZSBhZGRlZCB0byB0aGUgcG9saWN5LlxuICAgKiBGb3IgZXhhbXBsZSwgd2hlbiBhbiBgSUJ1Y2tldGAgaXMgY3JlYXRlZCBmcm9tIGFuIGV4aXN0aW5nIGJ1Y2tldCxcbiAgICogaXQncyBub3QgcG9zc2libGUgdG8gdGVsbCB3aGV0aGVyIHRoZSBidWNrZXQgYWxyZWFkeSBoYXMgYSBwb2xpY3lcbiAgICogYXR0YWNoZWQsIGxldCBhbG9uZSB0byByZS11c2UgdGhhdCBwb2xpY3kgdG8gYWRkIG1vcmUgc3RhdGVtZW50cyB0byBpdC5cbiAgICogU28gaXQncyBzYWZlc3QgdG8gZG8gbm90aGluZyBpbiB0aGVzZSBjYXNlcy5cbiAgICpcbiAgICogQHBhcmFtIHBlcm1pc3Npb24gdGhlIHBvbGljeSBzdGF0ZW1lbnQgdG8gYmUgYWRkZWQgdG8gdGhlIGJ1Y2tldCdzXG4gICAqIHBvbGljeS5cbiAgICogQHJldHVybnMgbWV0YWRhdGEgYWJvdXQgdGhlIGV4ZWN1dGlvbiBvZiB0aGlzIG1ldGhvZC4gSWYgdGhlIHBvbGljeVxuICAgKiB3YXMgbm90IGFkZGVkLCB0aGUgdmFsdWUgb2YgYHN0YXRlbWVudEFkZGVkYCB3aWxsIGJlIGBmYWxzZWAuIFlvdVxuICAgKiBzaG91bGQgYWx3YXlzIGNoZWNrIHRoaXMgdmFsdWUgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIG9wZXJhdGlvbiB3YXNcbiAgICogYWN0dWFsbHkgY2FycmllZCBvdXQuIE90aGVyd2lzZSwgc3ludGhlc2lzIGFuZCBkZXBsb3kgd2lsbCB0ZXJtaW5hdGVcbiAgICogc2lsZW50bHksIHdoaWNoIG1heSBiZSBjb25mdXNpbmcuXG4gICAqL1xuICBhZGRUb1Jlc291cmNlUG9saWN5KHBlcm1pc3Npb246IGlhbS5Qb2xpY3lTdGF0ZW1lbnQpOiBpYW0uQWRkVG9SZXNvdXJjZVBvbGljeVJlc3VsdDtcblxuICAvKipcbiAgICogVGhlIGh0dHBzIFVSTCBvZiBhbiBTMyBvYmplY3QuIEZvciBleGFtcGxlOlxuICAgKlxuICAgKiAtIGBodHRwczovL3MzLnVzLXdlc3QtMS5hbWF6b25hd3MuY29tL29ubHlidWNrZXRgXG4gICAqIC0gYGh0dHBzOi8vczMudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20vYnVja2V0L2tleWBcbiAgICogLSBgaHR0cHM6Ly9zMy5jbi1ub3J0aC0xLmFtYXpvbmF3cy5jb20uY24vY2hpbmEtYnVja2V0L215a2V5YFxuICAgKiBAcGFyYW0ga2V5IFRoZSBTMyBrZXkgb2YgdGhlIG9iamVjdC4gSWYgbm90IHNwZWNpZmllZCwgdGhlIFVSTCBvZiB0aGVcbiAgICogICAgICBidWNrZXQgaXMgcmV0dXJuZWQuXG4gICAqIEByZXR1cm5zIGFuIE9iamVjdFMzVXJsIHRva2VuXG4gICAqL1xuICB1cmxGb3JPYmplY3Qoa2V5Pzogc3RyaW5nKTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgaHR0cHMgVHJhbnNmZXIgQWNjZWxlcmF0aW9uIFVSTCBvZiBhbiBTMyBvYmplY3QuIFNwZWNpZnkgYGR1YWxTdGFjazogdHJ1ZWAgYXQgdGhlIG9wdGlvbnNcbiAgICogZm9yIGR1YWwtc3RhY2sgZW5kcG9pbnQgKGNvbm5lY3QgdG8gdGhlIGJ1Y2tldCBvdmVyIElQdjYpLiBGb3IgZXhhbXBsZTpcbiAgICpcbiAgICogLSBgaHR0cHM6Ly9idWNrZXQuczMtYWNjZWxlcmF0ZS5hbWF6b25hd3MuY29tYFxuICAgKiAtIGBodHRwczovL2J1Y2tldC5zMy1hY2NlbGVyYXRlLmFtYXpvbmF3cy5jb20va2V5YFxuICAgKlxuICAgKiBAcGFyYW0ga2V5IFRoZSBTMyBrZXkgb2YgdGhlIG9iamVjdC4gSWYgbm90IHNwZWNpZmllZCwgdGhlIFVSTCBvZiB0aGVcbiAgICogICAgICBidWNrZXQgaXMgcmV0dXJuZWQuXG4gICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbnMgZm9yIGdlbmVyYXRpbmcgVVJMLlxuICAgKiBAcmV0dXJucyBhbiBUcmFuc2ZlckFjY2VsZXJhdGlvblVybCB0b2tlblxuICAgKi9cbiAgdHJhbnNmZXJBY2NlbGVyYXRpb25VcmxGb3JPYmplY3Qoa2V5Pzogc3RyaW5nLCBvcHRpb25zPzogVHJhbnNmZXJBY2NlbGVyYXRpb25VcmxPcHRpb25zKTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgdmlydHVhbCBob3N0ZWQtc3R5bGUgVVJMIG9mIGFuIFMzIG9iamVjdC4gU3BlY2lmeSBgcmVnaW9uYWw6IGZhbHNlYCBhdFxuICAgKiB0aGUgb3B0aW9ucyBmb3Igbm9uLXJlZ2lvbmFsIFVSTC4gRm9yIGV4YW1wbGU6XG4gICAqXG4gICAqIC0gYGh0dHBzOi8vb25seS1idWNrZXQuczMudXMtd2VzdC0xLmFtYXpvbmF3cy5jb21gXG4gICAqIC0gYGh0dHBzOi8vYnVja2V0LnMzLnVzLXdlc3QtMS5hbWF6b25hd3MuY29tL2tleWBcbiAgICogLSBgaHR0cHM6Ly9idWNrZXQuczMuYW1hem9uYXdzLmNvbS9rZXlgXG4gICAqIC0gYGh0dHBzOi8vY2hpbmEtYnVja2V0LnMzLmNuLW5vcnRoLTEuYW1hem9uYXdzLmNvbS5jbi9teWtleWBcbiAgICogQHBhcmFtIGtleSBUaGUgUzMga2V5IG9mIHRoZSBvYmplY3QuIElmIG5vdCBzcGVjaWZpZWQsIHRoZSBVUkwgb2YgdGhlXG4gICAqICAgICAgYnVja2V0IGlzIHJldHVybmVkLlxuICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIGZvciBnZW5lcmF0aW5nIFVSTC5cbiAgICogQHJldHVybnMgYW4gT2JqZWN0UzNVcmwgdG9rZW5cbiAgICovXG4gIHZpcnR1YWxIb3N0ZWRVcmxGb3JPYmplY3Qoa2V5Pzogc3RyaW5nLCBvcHRpb25zPzogVmlydHVhbEhvc3RlZFN0eWxlVXJsT3B0aW9ucyk6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIFMzIFVSTCBvZiBhbiBTMyBvYmplY3QuIEZvciBleGFtcGxlOlxuICAgKiAtIGBzMzovL29ubHlidWNrZXRgXG4gICAqIC0gYHMzOi8vYnVja2V0L2tleWBcbiAgICogQHBhcmFtIGtleSBUaGUgUzMga2V5IG9mIHRoZSBvYmplY3QuIElmIG5vdCBzcGVjaWZpZWQsIHRoZSBTMyBVUkwgb2YgdGhlXG4gICAqICAgICAgYnVja2V0IGlzIHJldHVybmVkLlxuICAgKiBAcmV0dXJucyBhbiBPYmplY3RTM1VybCB0b2tlblxuICAgKi9cbiAgczNVcmxGb3JPYmplY3Qoa2V5Pzogc3RyaW5nKTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIEFSTiB0aGF0IHJlcHJlc2VudHMgYWxsIG9iamVjdHMgd2l0aGluIHRoZSBidWNrZXQgdGhhdCBtYXRjaFxuICAgKiB0aGUga2V5IHBhdHRlcm4gc3BlY2lmaWVkLiBUbyByZXByZXNlbnQgYWxsIGtleXMsIHNwZWNpZnkgYGBcIipcImBgLlxuICAgKi9cbiAgYXJuRm9yT2JqZWN0cyhrZXlQYXR0ZXJuOiBzdHJpbmcpOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEdyYW50IHJlYWQgcGVybWlzc2lvbnMgZm9yIHRoaXMgYnVja2V0IGFuZCBpdCdzIGNvbnRlbnRzIHRvIGFuIElBTVxuICAgKiBwcmluY2lwYWwgKFJvbGUvR3JvdXAvVXNlcikuXG4gICAqXG4gICAqIElmIGVuY3J5cHRpb24gaXMgdXNlZCwgcGVybWlzc2lvbiB0byB1c2UgdGhlIGtleSB0byBkZWNyeXB0IHRoZSBjb250ZW50c1xuICAgKiBvZiB0aGUgYnVja2V0IHdpbGwgYWxzbyBiZSBncmFudGVkIHRvIHRoZSBzYW1lIHByaW5jaXBhbC5cbiAgICpcbiAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBwcmluY2lwYWxcbiAgICogQHBhcmFtIG9iamVjdHNLZXlQYXR0ZXJuIFJlc3RyaWN0IHRoZSBwZXJtaXNzaW9uIHRvIGEgY2VydGFpbiBrZXkgcGF0dGVybiAoZGVmYXVsdCAnKicpXG4gICAqL1xuICBncmFudFJlYWQoaWRlbnRpdHk6IGlhbS5JR3JhbnRhYmxlLCBvYmplY3RzS2V5UGF0dGVybj86IGFueSk6IGlhbS5HcmFudDtcblxuICAvKipcbiAgICogR3JhbnQgd3JpdGUgcGVybWlzc2lvbnMgdG8gdGhpcyBidWNrZXQgdG8gYW4gSUFNIHByaW5jaXBhbC5cbiAgICpcbiAgICogSWYgZW5jcnlwdGlvbiBpcyB1c2VkLCBwZXJtaXNzaW9uIHRvIHVzZSB0aGUga2V5IHRvIGVuY3J5cHQgdGhlIGNvbnRlbnRzXG4gICAqIG9mIHdyaXR0ZW4gZmlsZXMgd2lsbCBhbHNvIGJlIGdyYW50ZWQgdG8gdGhlIHNhbWUgcHJpbmNpcGFsLlxuICAgKlxuICAgKiBCZWZvcmUgQ0RLIHZlcnNpb24gMS44NS4wLCB0aGlzIG1ldGhvZCBncmFudGVkIHRoZSBgczM6UHV0T2JqZWN0KmAgcGVybWlzc2lvbiB0aGF0IGluY2x1ZGVkIGBzMzpQdXRPYmplY3RBY2xgLFxuICAgKiB3aGljaCBjb3VsZCBiZSB1c2VkIHRvIGdyYW50IHJlYWQvd3JpdGUgb2JqZWN0IGFjY2VzcyB0byBJQU0gcHJpbmNpcGFscyBpbiBvdGhlciBhY2NvdW50cy5cbiAgICogSWYgeW91IHdhbnQgdG8gZ2V0IHJpZCBvZiB0aGF0IGJlaGF2aW9yLCB1cGRhdGUgeW91ciBDREsgdmVyc2lvbiB0byAxLjg1LjAgb3IgbGF0ZXIsXG4gICAqIGFuZCBtYWtlIHN1cmUgdGhlIGBAYXdzLWNkay9hd3MtczM6Z3JhbnRXcml0ZVdpdGhvdXRBY2xgIGZlYXR1cmUgZmxhZyBpcyBzZXQgdG8gYHRydWVgXG4gICAqIGluIHRoZSBgY29udGV4dGAga2V5IG9mIHlvdXIgY2RrLmpzb24gZmlsZS5cbiAgICogSWYgeW91J3ZlIGFscmVhZHkgdXBkYXRlZCwgYnV0IHN0aWxsIG5lZWQgdGhlIHByaW5jaXBhbCB0byBoYXZlIHBlcm1pc3Npb25zIHRvIG1vZGlmeSB0aGUgQUNMcyxcbiAgICogdXNlIHRoZSB7QGxpbmsgZ3JhbnRQdXRBY2x9IG1ldGhvZC5cbiAgICpcbiAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBwcmluY2lwYWxcbiAgICogQHBhcmFtIG9iamVjdHNLZXlQYXR0ZXJuIFJlc3RyaWN0IHRoZSBwZXJtaXNzaW9uIHRvIGEgY2VydGFpbiBrZXkgcGF0dGVybiAoZGVmYXVsdCAnKicpXG4gICAqL1xuICBncmFudFdyaXRlKGlkZW50aXR5OiBpYW0uSUdyYW50YWJsZSwgb2JqZWN0c0tleVBhdHRlcm4/OiBhbnkpOiBpYW0uR3JhbnQ7XG5cbiAgLyoqXG4gICAqIEdyYW50cyBzMzpQdXRPYmplY3QqIGFuZCBzMzpBYm9ydCogcGVybWlzc2lvbnMgZm9yIHRoaXMgYnVja2V0IHRvIGFuIElBTSBwcmluY2lwYWwuXG4gICAqXG4gICAqIElmIGVuY3J5cHRpb24gaXMgdXNlZCwgcGVybWlzc2lvbiB0byB1c2UgdGhlIGtleSB0byBlbmNyeXB0IHRoZSBjb250ZW50c1xuICAgKiBvZiB3cml0dGVuIGZpbGVzIHdpbGwgYWxzbyBiZSBncmFudGVkIHRvIHRoZSBzYW1lIHByaW5jaXBhbC5cbiAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBwcmluY2lwYWxcbiAgICogQHBhcmFtIG9iamVjdHNLZXlQYXR0ZXJuIFJlc3RyaWN0IHRoZSBwZXJtaXNzaW9uIHRvIGEgY2VydGFpbiBrZXkgcGF0dGVybiAoZGVmYXVsdCAnKicpXG4gICAqL1xuICBncmFudFB1dChpZGVudGl0eTogaWFtLklHcmFudGFibGUsIG9iamVjdHNLZXlQYXR0ZXJuPzogYW55KTogaWFtLkdyYW50O1xuXG4gIC8qKlxuICAgKiBHcmFudCB0aGUgZ2l2ZW4gSUFNIGlkZW50aXR5IHBlcm1pc3Npb25zIHRvIG1vZGlmeSB0aGUgQUNMcyBvZiBvYmplY3RzIGluIHRoZSBnaXZlbiBCdWNrZXQuXG4gICAqXG4gICAqIElmIHlvdXIgYXBwbGljYXRpb24gaGFzIHRoZSAnQGF3cy1jZGsvYXdzLXMzOmdyYW50V3JpdGVXaXRob3V0QWNsJyBmZWF0dXJlIGZsYWcgc2V0LFxuICAgKiBjYWxsaW5nIHtAbGluayBncmFudFdyaXRlfSBvciB7QGxpbmsgZ3JhbnRSZWFkV3JpdGV9IG5vIGxvbmdlciBncmFudHMgcGVybWlzc2lvbnMgdG8gbW9kaWZ5IHRoZSBBQ0xzIG9mIHRoZSBvYmplY3RzO1xuICAgKiBpbiB0aGlzIGNhc2UsIGlmIHlvdSBuZWVkIHRvIG1vZGlmeSBvYmplY3QgQUNMcywgY2FsbCB0aGlzIG1ldGhvZCBleHBsaWNpdGx5LlxuICAgKlxuICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIHByaW5jaXBhbFxuICAgKiBAcGFyYW0gb2JqZWN0c0tleVBhdHRlcm4gUmVzdHJpY3QgdGhlIHBlcm1pc3Npb24gdG8gYSBjZXJ0YWluIGtleSBwYXR0ZXJuIChkZWZhdWx0ICcqJylcbiAgICovXG4gIGdyYW50UHV0QWNsKGlkZW50aXR5OiBpYW0uSUdyYW50YWJsZSwgb2JqZWN0c0tleVBhdHRlcm4/OiBzdHJpbmcpOiBpYW0uR3JhbnQ7XG5cbiAgLyoqXG4gICAqIEdyYW50cyBzMzpEZWxldGVPYmplY3QqIHBlcm1pc3Npb24gdG8gYW4gSUFNIHByaW5jaXBhbCBmb3Igb2JqZWN0c1xuICAgKiBpbiB0aGlzIGJ1Y2tldC5cbiAgICpcbiAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBwcmluY2lwYWxcbiAgICogQHBhcmFtIG9iamVjdHNLZXlQYXR0ZXJuIFJlc3RyaWN0IHRoZSBwZXJtaXNzaW9uIHRvIGEgY2VydGFpbiBrZXkgcGF0dGVybiAoZGVmYXVsdCAnKicpXG4gICAqL1xuICBncmFudERlbGV0ZShpZGVudGl0eTogaWFtLklHcmFudGFibGUsIG9iamVjdHNLZXlQYXR0ZXJuPzogYW55KTogaWFtLkdyYW50O1xuXG4gIC8qKlxuICAgKiBHcmFudHMgcmVhZC93cml0ZSBwZXJtaXNzaW9ucyBmb3IgdGhpcyBidWNrZXQgYW5kIGl0J3MgY29udGVudHMgdG8gYW4gSUFNXG4gICAqIHByaW5jaXBhbCAoUm9sZS9Hcm91cC9Vc2VyKS5cbiAgICpcbiAgICogSWYgYW4gZW5jcnlwdGlvbiBrZXkgaXMgdXNlZCwgcGVybWlzc2lvbiB0byB1c2UgdGhlIGtleSBmb3JcbiAgICogZW5jcnlwdC9kZWNyeXB0IHdpbGwgYWxzbyBiZSBncmFudGVkLlxuICAgKlxuICAgKiBCZWZvcmUgQ0RLIHZlcnNpb24gMS44NS4wLCB0aGlzIG1ldGhvZCBncmFudGVkIHRoZSBgczM6UHV0T2JqZWN0KmAgcGVybWlzc2lvbiB0aGF0IGluY2x1ZGVkIGBzMzpQdXRPYmplY3RBY2xgLFxuICAgKiB3aGljaCBjb3VsZCBiZSB1c2VkIHRvIGdyYW50IHJlYWQvd3JpdGUgb2JqZWN0IGFjY2VzcyB0byBJQU0gcHJpbmNpcGFscyBpbiBvdGhlciBhY2NvdW50cy5cbiAgICogSWYgeW91IHdhbnQgdG8gZ2V0IHJpZCBvZiB0aGF0IGJlaGF2aW9yLCB1cGRhdGUgeW91ciBDREsgdmVyc2lvbiB0byAxLjg1LjAgb3IgbGF0ZXIsXG4gICAqIGFuZCBtYWtlIHN1cmUgdGhlIGBAYXdzLWNkay9hd3MtczM6Z3JhbnRXcml0ZVdpdGhvdXRBY2xgIGZlYXR1cmUgZmxhZyBpcyBzZXQgdG8gYHRydWVgXG4gICAqIGluIHRoZSBgY29udGV4dGAga2V5IG9mIHlvdXIgY2RrLmpzb24gZmlsZS5cbiAgICogSWYgeW91J3ZlIGFscmVhZHkgdXBkYXRlZCwgYnV0IHN0aWxsIG5lZWQgdGhlIHByaW5jaXBhbCB0byBoYXZlIHBlcm1pc3Npb25zIHRvIG1vZGlmeSB0aGUgQUNMcyxcbiAgICogdXNlIHRoZSB7QGxpbmsgZ3JhbnRQdXRBY2x9IG1ldGhvZC5cbiAgICpcbiAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBwcmluY2lwYWxcbiAgICogQHBhcmFtIG9iamVjdHNLZXlQYXR0ZXJuIFJlc3RyaWN0IHRoZSBwZXJtaXNzaW9uIHRvIGEgY2VydGFpbiBrZXkgcGF0dGVybiAoZGVmYXVsdCAnKicpXG4gICAqL1xuICBncmFudFJlYWRXcml0ZShpZGVudGl0eTogaWFtLklHcmFudGFibGUsIG9iamVjdHNLZXlQYXR0ZXJuPzogYW55KTogaWFtLkdyYW50O1xuXG4gIC8qKlxuICAgKiBBbGxvd3MgdW5yZXN0cmljdGVkIGFjY2VzcyB0byBvYmplY3RzIGZyb20gdGhpcyBidWNrZXQuXG4gICAqXG4gICAqIElNUE9SVEFOVDogVGhpcyBwZXJtaXNzaW9uIGFsbG93cyBhbnlvbmUgdG8gcGVyZm9ybSBhY3Rpb25zIG9uIFMzIG9iamVjdHNcbiAgICogaW4gdGhpcyBidWNrZXQsIHdoaWNoIGlzIHVzZWZ1bCBmb3Igd2hlbiB5b3UgY29uZmlndXJlIHlvdXIgYnVja2V0IGFzIGFcbiAgICogd2Vic2l0ZSBhbmQgd2FudCBldmVyeW9uZSB0byBiZSBhYmxlIHRvIHJlYWQgb2JqZWN0cyBpbiB0aGUgYnVja2V0IHdpdGhvdXRcbiAgICogbmVlZGluZyB0byBhdXRoZW50aWNhdGUuXG4gICAqXG4gICAqIFdpdGhvdXQgYXJndW1lbnRzLCB0aGlzIG1ldGhvZCB3aWxsIGdyYW50IHJlYWQgKFwiczM6R2V0T2JqZWN0XCIpIGFjY2VzcyB0b1xuICAgKiBhbGwgb2JqZWN0cyAoXCIqXCIpIGluIHRoZSBidWNrZXQuXG4gICAqXG4gICAqIFRoZSBtZXRob2QgcmV0dXJucyB0aGUgYGlhbS5HcmFudGAgb2JqZWN0LCB3aGljaCBjYW4gdGhlbiBiZSBtb2RpZmllZFxuICAgKiBhcyBuZWVkZWQuIEZvciBleGFtcGxlLCB5b3UgY2FuIGFkZCBhIGNvbmRpdGlvbiB0aGF0IHdpbGwgcmVzdHJpY3QgYWNjZXNzIG9ubHlcbiAgICogdG8gYW4gSVB2NCByYW5nZSBsaWtlIHRoaXM6XG4gICAqXG4gICAqICAgICBjb25zdCBncmFudCA9IGJ1Y2tldC5ncmFudFB1YmxpY0FjY2VzcygpO1xuICAgKiAgICAgZ3JhbnQucmVzb3VyY2VTdGF0ZW1lbnQhLmFkZENvbmRpdGlvbijigJhJcEFkZHJlc3PigJksIHsg4oCcYXdzOlNvdXJjZUlw4oCdOiDigJw1NC4yNDAuMTQzLjAvMjTigJ0gfSk7XG4gICAqXG4gICAqXG4gICAqIEBwYXJhbSBrZXlQcmVmaXggdGhlIHByZWZpeCBvZiBTMyBvYmplY3Qga2V5cyAoZS5nLiBgaG9tZS8qYCkuIERlZmF1bHQgaXMgXCIqXCIuXG4gICAqIEBwYXJhbSBhbGxvd2VkQWN0aW9ucyB0aGUgc2V0IG9mIFMzIGFjdGlvbnMgdG8gYWxsb3cuIERlZmF1bHQgaXMgXCJzMzpHZXRPYmplY3RcIi5cbiAgICogQHJldHVybnMgVGhlIGBpYW0uUG9saWN5U3RhdGVtZW50YCBvYmplY3QsIHdoaWNoIGNhbiBiZSB1c2VkIHRvIGFwcGx5IGUuZy4gY29uZGl0aW9ucy5cbiAgICovXG4gIGdyYW50UHVibGljQWNjZXNzKGtleVByZWZpeD86IHN0cmluZywgLi4uYWxsb3dlZEFjdGlvbnM6IHN0cmluZ1tdKTogaWFtLkdyYW50O1xuXG4gIC8qKlxuICAgKiBEZWZpbmVzIGEgQ2xvdWRXYXRjaCBldmVudCB0aGF0IHRyaWdnZXJzIHdoZW4gc29tZXRoaW5nIGhhcHBlbnMgdG8gdGhpcyBidWNrZXRcbiAgICpcbiAgICogUmVxdWlyZXMgdGhhdCB0aGVyZSBleGlzdHMgYXQgbGVhc3Qgb25lIENsb3VkVHJhaWwgVHJhaWwgaW4geW91ciBhY2NvdW50XG4gICAqIHRoYXQgY2FwdHVyZXMgdGhlIGV2ZW50LiBUaGlzIG1ldGhvZCB3aWxsIG5vdCBjcmVhdGUgdGhlIFRyYWlsLlxuICAgKlxuICAgKiBAcGFyYW0gaWQgVGhlIGlkIG9mIHRoZSBydWxlXG4gICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbnMgZm9yIGFkZGluZyB0aGUgcnVsZVxuICAgKi9cbiAgb25DbG91ZFRyYWlsRXZlbnQoaWQ6IHN0cmluZywgb3B0aW9ucz86IE9uQ2xvdWRUcmFpbEJ1Y2tldEV2ZW50T3B0aW9ucyk6IGV2ZW50cy5SdWxlO1xuXG4gIC8qKlxuICAgKiBEZWZpbmVzIGFuIEFXUyBDbG91ZFdhdGNoIGV2ZW50IHRoYXQgdHJpZ2dlcnMgd2hlbiBhbiBvYmplY3QgaXMgdXBsb2FkZWRcbiAgICogdG8gdGhlIHNwZWNpZmllZCBwYXRocyAoa2V5cykgaW4gdGhpcyBidWNrZXQgdXNpbmcgdGhlIFB1dE9iamVjdCBBUEkgY2FsbC5cbiAgICpcbiAgICogTm90ZSB0aGF0IHNvbWUgdG9vbHMgbGlrZSBgYXdzIHMzIGNwYCB3aWxsIGF1dG9tYXRpY2FsbHkgdXNlIGVpdGhlclxuICAgKiBQdXRPYmplY3Qgb3IgdGhlIG11bHRpcGFydCB1cGxvYWQgQVBJIGRlcGVuZGluZyBvbiB0aGUgZmlsZSBzaXplLFxuICAgKiBzbyB1c2luZyBgb25DbG91ZFRyYWlsV3JpdGVPYmplY3RgIG1heSBiZSBwcmVmZXJhYmxlLlxuICAgKlxuICAgKiBSZXF1aXJlcyB0aGF0IHRoZXJlIGV4aXN0cyBhdCBsZWFzdCBvbmUgQ2xvdWRUcmFpbCBUcmFpbCBpbiB5b3VyIGFjY291bnRcbiAgICogdGhhdCBjYXB0dXJlcyB0aGUgZXZlbnQuIFRoaXMgbWV0aG9kIHdpbGwgbm90IGNyZWF0ZSB0aGUgVHJhaWwuXG4gICAqXG4gICAqIEBwYXJhbSBpZCBUaGUgaWQgb2YgdGhlIHJ1bGVcbiAgICogQHBhcmFtIG9wdGlvbnMgT3B0aW9ucyBmb3IgYWRkaW5nIHRoZSBydWxlXG4gICAqL1xuICBvbkNsb3VkVHJhaWxQdXRPYmplY3QoaWQ6IHN0cmluZywgb3B0aW9ucz86IE9uQ2xvdWRUcmFpbEJ1Y2tldEV2ZW50T3B0aW9ucyk6IGV2ZW50cy5SdWxlO1xuXG4gIC8qKlxuICAgKiBEZWZpbmVzIGFuIEFXUyBDbG91ZFdhdGNoIGV2ZW50IHRoYXQgdHJpZ2dlcnMgd2hlbiBhbiBvYmplY3QgYXQgdGhlXG4gICAqIHNwZWNpZmllZCBwYXRocyAoa2V5cykgaW4gdGhpcyBidWNrZXQgYXJlIHdyaXR0ZW4gdG8uICBUaGlzIGluY2x1ZGVzXG4gICAqIHRoZSBldmVudHMgUHV0T2JqZWN0LCBDb3B5T2JqZWN0LCBhbmQgQ29tcGxldGVNdWx0aXBhcnRVcGxvYWQuXG4gICAqXG4gICAqIE5vdGUgdGhhdCBzb21lIHRvb2xzIGxpa2UgYGF3cyBzMyBjcGAgd2lsbCBhdXRvbWF0aWNhbGx5IHVzZSBlaXRoZXJcbiAgICogUHV0T2JqZWN0IG9yIHRoZSBtdWx0aXBhcnQgdXBsb2FkIEFQSSBkZXBlbmRpbmcgb24gdGhlIGZpbGUgc2l6ZSxcbiAgICogc28gdXNpbmcgdGhpcyBtZXRob2QgbWF5IGJlIHByZWZlcmFibGUgdG8gYG9uQ2xvdWRUcmFpbFB1dE9iamVjdGAuXG4gICAqXG4gICAqIFJlcXVpcmVzIHRoYXQgdGhlcmUgZXhpc3RzIGF0IGxlYXN0IG9uZSBDbG91ZFRyYWlsIFRyYWlsIGluIHlvdXIgYWNjb3VudFxuICAgKiB0aGF0IGNhcHR1cmVzIHRoZSBldmVudC4gVGhpcyBtZXRob2Qgd2lsbCBub3QgY3JlYXRlIHRoZSBUcmFpbC5cbiAgICpcbiAgICogQHBhcmFtIGlkIFRoZSBpZCBvZiB0aGUgcnVsZVxuICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIGZvciBhZGRpbmcgdGhlIHJ1bGVcbiAgICovXG4gIG9uQ2xvdWRUcmFpbFdyaXRlT2JqZWN0KGlkOiBzdHJpbmcsIG9wdGlvbnM/OiBPbkNsb3VkVHJhaWxCdWNrZXRFdmVudE9wdGlvbnMpOiBldmVudHMuUnVsZTtcblxuICAvKipcbiAgICogQWRkcyBhIGJ1Y2tldCBub3RpZmljYXRpb24gZXZlbnQgZGVzdGluYXRpb24uXG4gICAqIEBwYXJhbSBldmVudCBUaGUgZXZlbnQgdG8gdHJpZ2dlciB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSBkZXN0IFRoZSBub3RpZmljYXRpb24gZGVzdGluYXRpb24gKExhbWJkYSwgU05TIFRvcGljIG9yIFNRUyBRdWV1ZSlcbiAgICpcbiAgICogQHBhcmFtIGZpbHRlcnMgUzMgb2JqZWN0IGtleSBmaWx0ZXIgcnVsZXMgdG8gZGV0ZXJtaW5lIHdoaWNoIG9iamVjdHNcbiAgICogdHJpZ2dlciB0aGlzIGV2ZW50LiBFYWNoIGZpbHRlciBtdXN0IGluY2x1ZGUgYSBgcHJlZml4YCBhbmQvb3IgYHN1ZmZpeGBcbiAgICogdGhhdCB3aWxsIGJlIG1hdGNoZWQgYWdhaW5zdCB0aGUgczMgb2JqZWN0IGtleS4gUmVmZXIgdG8gdGhlIFMzIERldmVsb3BlciBHdWlkZVxuICAgKiBmb3IgZGV0YWlscyBhYm91dCBhbGxvd2VkIGZpbHRlciBydWxlcy5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uUzMvbGF0ZXN0L2Rldi9Ob3RpZmljYXRpb25Ib3dUby5odG1sI25vdGlmaWNhdGlvbi1ob3ctdG8tZmlsdGVyaW5nXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqXG4gICAqICAgIGRlY2xhcmUgY29uc3QgbXlMYW1iZGE6IGxhbWJkYS5GdW5jdGlvbjtcbiAgICogICAgY29uc3QgYnVja2V0ID0gbmV3IHMzLkJ1Y2tldCh0aGlzLCAnTXlCdWNrZXQnKTtcbiAgICogICAgYnVja2V0LmFkZEV2ZW50Tm90aWZpY2F0aW9uKHMzLkV2ZW50VHlwZS5PQkpFQ1RfQ1JFQVRFRCwgbmV3IHMzbi5MYW1iZGFEZXN0aW5hdGlvbihteUxhbWJkYSksIHtwcmVmaXg6ICdob21lL215dXNlcm5hbWUvKid9KVxuICAgKlxuICAgKiBAc2VlXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25TMy9sYXRlc3QvZGV2L05vdGlmaWNhdGlvbkhvd1RvLmh0bWxcbiAgICovXG4gIGFkZEV2ZW50Tm90aWZpY2F0aW9uKGV2ZW50OiBFdmVudFR5cGUsIGRlc3Q6IElCdWNrZXROb3RpZmljYXRpb25EZXN0aW5hdGlvbiwgLi4uZmlsdGVyczogTm90aWZpY2F0aW9uS2V5RmlsdGVyW10pOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBTdWJzY3JpYmVzIGEgZGVzdGluYXRpb24gdG8gcmVjZWl2ZSBub3RpZmljYXRpb25zIHdoZW4gYW4gb2JqZWN0IGlzXG4gICAqIGNyZWF0ZWQgaW4gdGhlIGJ1Y2tldC4gVGhpcyBpcyBpZGVudGljYWwgdG8gY2FsbGluZ1xuICAgKiBgb25FdmVudChzMy5FdmVudFR5cGUuT0JKRUNUX0NSRUFURUQpYC5cbiAgICpcbiAgICogQHBhcmFtIGRlc3QgVGhlIG5vdGlmaWNhdGlvbiBkZXN0aW5hdGlvbiAoc2VlIG9uRXZlbnQpXG4gICAqIEBwYXJhbSBmaWx0ZXJzIEZpbHRlcnMgKHNlZSBvbkV2ZW50KVxuICAgKi9cbiAgYWRkT2JqZWN0Q3JlYXRlZE5vdGlmaWNhdGlvbihkZXN0OiBJQnVja2V0Tm90aWZpY2F0aW9uRGVzdGluYXRpb24sIC4uLmZpbHRlcnM6IE5vdGlmaWNhdGlvbktleUZpbHRlcltdKTogdm9pZFxuXG4gIC8qKlxuICAgKiBTdWJzY3JpYmVzIGEgZGVzdGluYXRpb24gdG8gcmVjZWl2ZSBub3RpZmljYXRpb25zIHdoZW4gYW4gb2JqZWN0IGlzXG4gICAqIHJlbW92ZWQgZnJvbSB0aGUgYnVja2V0LiBUaGlzIGlzIGlkZW50aWNhbCB0byBjYWxsaW5nXG4gICAqIGBvbkV2ZW50KEV2ZW50VHlwZS5PQkpFQ1RfUkVNT1ZFRClgLlxuICAgKlxuICAgKiBAcGFyYW0gZGVzdCBUaGUgbm90aWZpY2F0aW9uIGRlc3RpbmF0aW9uIChzZWUgb25FdmVudClcbiAgICogQHBhcmFtIGZpbHRlcnMgRmlsdGVycyAoc2VlIG9uRXZlbnQpXG4gICAqL1xuICBhZGRPYmplY3RSZW1vdmVkTm90aWZpY2F0aW9uKGRlc3Q6IElCdWNrZXROb3RpZmljYXRpb25EZXN0aW5hdGlvbiwgLi4uZmlsdGVyczogTm90aWZpY2F0aW9uS2V5RmlsdGVyW10pOiB2b2lkO1xufVxuXG4vKipcbiAqIEEgcmVmZXJlbmNlIHRvIGEgYnVja2V0IG91dHNpZGUgdGhpcyBzdGFja1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEJ1Y2tldEF0dHJpYnV0ZXMge1xuICAvKipcbiAgICogVGhlIEFSTiBvZiB0aGUgYnVja2V0LiBBdCBsZWFzdCBvbmUgb2YgYnVja2V0QXJuIG9yIGJ1Y2tldE5hbWUgbXVzdCBiZVxuICAgKiBkZWZpbmVkIGluIG9yZGVyIHRvIGluaXRpYWxpemUgYSBidWNrZXQgcmVmLlxuICAgKi9cbiAgcmVhZG9ubHkgYnVja2V0QXJuPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgYnVja2V0LiBJZiB0aGUgdW5kZXJseWluZyB2YWx1ZSBvZiBBUk4gaXMgYSBzdHJpbmcsIHRoZVxuICAgKiBuYW1lIHdpbGwgYmUgcGFyc2VkIGZyb20gdGhlIEFSTi4gT3RoZXJ3aXNlLCB0aGUgbmFtZSBpcyBvcHRpb25hbCwgYnV0XG4gICAqIHNvbWUgZmVhdHVyZXMgdGhhdCByZXF1aXJlIHRoZSBidWNrZXQgbmFtZSBzdWNoIGFzIGF1dG8tY3JlYXRpbmcgYSBidWNrZXRcbiAgICogcG9saWN5LCB3b24ndCB3b3JrLlxuICAgKi9cbiAgcmVhZG9ubHkgYnVja2V0TmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGRvbWFpbiBuYW1lIG9mIHRoZSBidWNrZXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IEluZmVycmVkIGZyb20gYnVja2V0IG5hbWVcbiAgICovXG4gIHJlYWRvbmx5IGJ1Y2tldERvbWFpbk5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB3ZWJzaXRlIFVSTCBvZiB0aGUgYnVja2V0IChpZiBzdGF0aWMgd2ViIGhvc3RpbmcgaXMgZW5hYmxlZCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IEluZmVycmVkIGZyb20gYnVja2V0IG5hbWVcbiAgICovXG4gIHJlYWRvbmx5IGJ1Y2tldFdlYnNpdGVVcmw/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSByZWdpb25hbCBkb21haW4gbmFtZSBvZiB0aGUgc3BlY2lmaWVkIGJ1Y2tldC5cbiAgICovXG4gIHJlYWRvbmx5IGJ1Y2tldFJlZ2lvbmFsRG9tYWluTmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIElQdjYgRE5TIG5hbWUgb2YgdGhlIHNwZWNpZmllZCBidWNrZXQuXG4gICAqL1xuICByZWFkb25seSBidWNrZXREdWFsU3RhY2tEb21haW5OYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZm9ybWF0IG9mIHRoZSB3ZWJzaXRlIFVSTCBvZiB0aGUgYnVja2V0LiBUaGlzIHNob3VsZCBiZSB0cnVlIGZvclxuICAgKiByZWdpb25zIGxhdW5jaGVkIHNpbmNlIDIwMTQuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBidWNrZXRXZWJzaXRlTmV3VXJsRm9ybWF0PzogYm9vbGVhbjtcblxuICByZWFkb25seSBlbmNyeXB0aW9uS2V5Pzoga21zLklLZXk7XG5cbiAgLyoqXG4gICAqIElmIHRoaXMgYnVja2V0IGhhcyBiZWVuIGNvbmZpZ3VyZWQgZm9yIHN0YXRpYyB3ZWJzaXRlIGhvc3RpbmcuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBpc1dlYnNpdGU/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgYWNjb3VudCB0aGlzIGV4aXN0aW5nIGJ1Y2tldCBiZWxvbmdzIHRvLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGl0J3MgYXNzdW1lZCB0aGUgYnVja2V0IGJlbG9uZ3MgdG8gdGhlIHNhbWUgYWNjb3VudCBhcyB0aGUgc2NvcGUgaXQncyBiZWluZyBpbXBvcnRlZCBpbnRvXG4gICAqL1xuICByZWFkb25seSBhY2NvdW50Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVnaW9uIHRoaXMgZXhpc3RpbmcgYnVja2V0IGlzIGluLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGl0J3MgYXNzdW1lZCB0aGUgYnVja2V0IGlzIGluIHRoZSBzYW1lIHJlZ2lvbiBhcyB0aGUgc2NvcGUgaXQncyBiZWluZyBpbXBvcnRlZCBpbnRvXG4gICAqL1xuICByZWFkb25seSByZWdpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSByb2xlIHRvIGJlIHVzZWQgYnkgdGhlIG5vdGlmaWNhdGlvbnMgaGFuZGxlclxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGEgbmV3IHJvbGUgd2lsbCBiZSBjcmVhdGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgbm90aWZpY2F0aW9uc0hhbmRsZXJSb2xlPzogaWFtLklSb2xlO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYW4gUzMgQnVja2V0LlxuICpcbiAqIEJ1Y2tldHMgY2FuIGJlIGVpdGhlciBkZWZpbmVkIHdpdGhpbiB0aGlzIHN0YWNrOlxuICpcbiAqICAgbmV3IEJ1Y2tldCh0aGlzLCAnTXlCdWNrZXQnLCB7IHByb3BzIH0pO1xuICpcbiAqIE9yIGltcG9ydGVkIGZyb20gYW4gZXhpc3RpbmcgYnVja2V0OlxuICpcbiAqICAgQnVja2V0LmltcG9ydCh0aGlzLCAnTXlJbXBvcnRlZEJ1Y2tldCcsIHsgYnVja2V0QXJuOiAuLi4gfSk7XG4gKlxuICogWW91IGNhbiBhbHNvIGV4cG9ydCBhIGJ1Y2tldCBhbmQgaW1wb3J0IGl0IGludG8gYW5vdGhlciBzdGFjazpcbiAqXG4gKiAgIGNvbnN0IHJlZiA9IG15QnVja2V0LmV4cG9ydCgpO1xuICogICBCdWNrZXQuaW1wb3J0KHRoaXMsICdNeUltcG9ydGVkQnVja2V0JywgcmVmKTtcbiAqXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBCdWNrZXRCYXNlIGV4dGVuZHMgUmVzb3VyY2UgaW1wbGVtZW50cyBJQnVja2V0IHtcbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IGJ1Y2tldEFybjogc3RyaW5nO1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgYnVja2V0TmFtZTogc3RyaW5nO1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgYnVja2V0RG9tYWluTmFtZTogc3RyaW5nO1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgYnVja2V0V2Vic2l0ZVVybDogc3RyaW5nO1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgYnVja2V0V2Vic2l0ZURvbWFpbk5hbWU6IHN0cmluZztcbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IGJ1Y2tldFJlZ2lvbmFsRG9tYWluTmFtZTogc3RyaW5nO1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgYnVja2V0RHVhbFN0YWNrRG9tYWluTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBLTVMgZW5jcnlwdGlvbiBrZXkgYXNzb2NpYXRlZCB3aXRoIHRoaXMgYnVja2V0LlxuICAgKi9cbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IGVuY3J5cHRpb25LZXk/OiBrbXMuSUtleTtcblxuICAvKipcbiAgICogSWYgdGhpcyBidWNrZXQgaGFzIGJlZW4gY29uZmlndXJlZCBmb3Igc3RhdGljIHdlYnNpdGUgaG9zdGluZy5cbiAgICovXG4gIHB1YmxpYyBhYnN0cmFjdCByZWFkb25seSBpc1dlYnNpdGU/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVzb3VyY2UgcG9saWN5IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGJ1Y2tldC5cbiAgICpcbiAgICogSWYgYGF1dG9DcmVhdGVQb2xpY3lgIGlzIHRydWUsIGEgYEJ1Y2tldFBvbGljeWAgd2lsbCBiZSBjcmVhdGVkIHVwb24gdGhlXG4gICAqIGZpcnN0IGNhbGwgdG8gYWRkVG9SZXNvdXJjZVBvbGljeShzKS5cbiAgICovXG4gIHB1YmxpYyBhYnN0cmFjdCBwb2xpY3k/OiBCdWNrZXRQb2xpY3k7XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyBpZiBhIGJ1Y2tldCByZXNvdXJjZSBwb2xpY3kgc2hvdWxkIGF1dG9tYXRpY2FsbHkgY3JlYXRlZCB1cG9uXG4gICAqIHRoZSBmaXJzdCBjYWxsIHRvIGBhZGRUb1Jlc291cmNlUG9saWN5YC5cbiAgICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBhdXRvQ3JlYXRlUG9saWN5OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGRpc2FsbG93IHB1YmxpYyBhY2Nlc3NcbiAgICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBkaXNhbGxvd1B1YmxpY0FjY2Vzcz86IGJvb2xlYW47XG5cbiAgcHJpdmF0ZSBub3RpZmljYXRpb25zPzogQnVja2V0Tm90aWZpY2F0aW9ucztcblxuICBwcm90ZWN0ZWQgbm90aWZpY2F0aW9uc0hhbmRsZXJSb2xlPzogaWFtLklSb2xlO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBSZXNvdXJjZVByb3BzID0ge30pIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHByb3BzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWZpbmUgYSBDbG91ZFdhdGNoIGV2ZW50IHRoYXQgdHJpZ2dlcnMgd2hlbiBzb21ldGhpbmcgaGFwcGVucyB0byB0aGlzIHJlcG9zaXRvcnlcbiAgICpcbiAgICogUmVxdWlyZXMgdGhhdCB0aGVyZSBleGlzdHMgYXQgbGVhc3Qgb25lIENsb3VkVHJhaWwgVHJhaWwgaW4geW91ciBhY2NvdW50XG4gICAqIHRoYXQgY2FwdHVyZXMgdGhlIGV2ZW50LiBUaGlzIG1ldGhvZCB3aWxsIG5vdCBjcmVhdGUgdGhlIFRyYWlsLlxuICAgKlxuICAgKiBAcGFyYW0gaWQgVGhlIGlkIG9mIHRoZSBydWxlXG4gICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbnMgZm9yIGFkZGluZyB0aGUgcnVsZVxuICAgKi9cbiAgcHVibGljIG9uQ2xvdWRUcmFpbEV2ZW50KGlkOiBzdHJpbmcsIG9wdGlvbnM6IE9uQ2xvdWRUcmFpbEJ1Y2tldEV2ZW50T3B0aW9ucyA9IHt9KTogZXZlbnRzLlJ1bGUge1xuICAgIGNvbnN0IHJ1bGUgPSBuZXcgZXZlbnRzLlJ1bGUodGhpcywgaWQsIG9wdGlvbnMpO1xuICAgIHJ1bGUuYWRkVGFyZ2V0KG9wdGlvbnMudGFyZ2V0KTtcbiAgICBydWxlLmFkZEV2ZW50UGF0dGVybih7XG4gICAgICBzb3VyY2U6IFsnYXdzLnMzJ10sXG4gICAgICBkZXRhaWxUeXBlOiBbJ0FXUyBBUEkgQ2FsbCB2aWEgQ2xvdWRUcmFpbCddLFxuICAgICAgZGV0YWlsOiB7XG4gICAgICAgIHJlc291cmNlczoge1xuICAgICAgICAgIEFSTjogb3B0aW9ucy5wYXRocz8ubWFwKHAgPT4gdGhpcy5hcm5Gb3JPYmplY3RzKHApKSA/PyBbdGhpcy5idWNrZXRBcm5dLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcbiAgICByZXR1cm4gcnVsZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWZpbmVzIGFuIEFXUyBDbG91ZFdhdGNoIGV2ZW50IHRoYXQgdHJpZ2dlcnMgd2hlbiBhbiBvYmplY3QgaXMgdXBsb2FkZWRcbiAgICogdG8gdGhlIHNwZWNpZmllZCBwYXRocyAoa2V5cykgaW4gdGhpcyBidWNrZXQgdXNpbmcgdGhlIFB1dE9iamVjdCBBUEkgY2FsbC5cbiAgICpcbiAgICogTm90ZSB0aGF0IHNvbWUgdG9vbHMgbGlrZSBgYXdzIHMzIGNwYCB3aWxsIGF1dG9tYXRpY2FsbHkgdXNlIGVpdGhlclxuICAgKiBQdXRPYmplY3Qgb3IgdGhlIG11bHRpcGFydCB1cGxvYWQgQVBJIGRlcGVuZGluZyBvbiB0aGUgZmlsZSBzaXplLFxuICAgKiBzbyB1c2luZyBgb25DbG91ZFRyYWlsV3JpdGVPYmplY3RgIG1heSBiZSBwcmVmZXJhYmxlLlxuICAgKlxuICAgKiBSZXF1aXJlcyB0aGF0IHRoZXJlIGV4aXN0cyBhdCBsZWFzdCBvbmUgQ2xvdWRUcmFpbCBUcmFpbCBpbiB5b3VyIGFjY291bnRcbiAgICogdGhhdCBjYXB0dXJlcyB0aGUgZXZlbnQuIFRoaXMgbWV0aG9kIHdpbGwgbm90IGNyZWF0ZSB0aGUgVHJhaWwuXG4gICAqXG4gICAqIEBwYXJhbSBpZCBUaGUgaWQgb2YgdGhlIHJ1bGVcbiAgICogQHBhcmFtIG9wdGlvbnMgT3B0aW9ucyBmb3IgYWRkaW5nIHRoZSBydWxlXG4gICAqL1xuICBwdWJsaWMgb25DbG91ZFRyYWlsUHV0T2JqZWN0KGlkOiBzdHJpbmcsIG9wdGlvbnM6IE9uQ2xvdWRUcmFpbEJ1Y2tldEV2ZW50T3B0aW9ucyA9IHt9KTogZXZlbnRzLlJ1bGUge1xuICAgIGNvbnN0IHJ1bGUgPSB0aGlzLm9uQ2xvdWRUcmFpbEV2ZW50KGlkLCBvcHRpb25zKTtcbiAgICBydWxlLmFkZEV2ZW50UGF0dGVybih7XG4gICAgICBkZXRhaWw6IHtcbiAgICAgICAgZXZlbnROYW1lOiBbJ1B1dE9iamVjdCddLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICByZXR1cm4gcnVsZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWZpbmVzIGFuIEFXUyBDbG91ZFdhdGNoIGV2ZW50IHRoYXQgdHJpZ2dlcnMgd2hlbiBhbiBvYmplY3QgYXQgdGhlXG4gICAqIHNwZWNpZmllZCBwYXRocyAoa2V5cykgaW4gdGhpcyBidWNrZXQgYXJlIHdyaXR0ZW4gdG8uICBUaGlzIGluY2x1ZGVzXG4gICAqIHRoZSBldmVudHMgUHV0T2JqZWN0LCBDb3B5T2JqZWN0LCBhbmQgQ29tcGxldGVNdWx0aXBhcnRVcGxvYWQuXG4gICAqXG4gICAqIE5vdGUgdGhhdCBzb21lIHRvb2xzIGxpa2UgYGF3cyBzMyBjcGAgd2lsbCBhdXRvbWF0aWNhbGx5IHVzZSBlaXRoZXJcbiAgICogUHV0T2JqZWN0IG9yIHRoZSBtdWx0aXBhcnQgdXBsb2FkIEFQSSBkZXBlbmRpbmcgb24gdGhlIGZpbGUgc2l6ZSxcbiAgICogc28gdXNpbmcgdGhpcyBtZXRob2QgbWF5IGJlIHByZWZlcmFibGUgdG8gYG9uQ2xvdWRUcmFpbFB1dE9iamVjdGAuXG4gICAqXG4gICAqIFJlcXVpcmVzIHRoYXQgdGhlcmUgZXhpc3RzIGF0IGxlYXN0IG9uZSBDbG91ZFRyYWlsIFRyYWlsIGluIHlvdXIgYWNjb3VudFxuICAgKiB0aGF0IGNhcHR1cmVzIHRoZSBldmVudC4gVGhpcyBtZXRob2Qgd2lsbCBub3QgY3JlYXRlIHRoZSBUcmFpbC5cbiAgICpcbiAgICogQHBhcmFtIGlkIFRoZSBpZCBvZiB0aGUgcnVsZVxuICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIGZvciBhZGRpbmcgdGhlIHJ1bGVcbiAgICovXG4gIHB1YmxpYyBvbkNsb3VkVHJhaWxXcml0ZU9iamVjdChpZDogc3RyaW5nLCBvcHRpb25zOiBPbkNsb3VkVHJhaWxCdWNrZXRFdmVudE9wdGlvbnMgPSB7fSk6IGV2ZW50cy5SdWxlIHtcbiAgICBjb25zdCBydWxlID0gdGhpcy5vbkNsb3VkVHJhaWxFdmVudChpZCwgb3B0aW9ucyk7XG4gICAgcnVsZS5hZGRFdmVudFBhdHRlcm4oe1xuICAgICAgZGV0YWlsOiB7XG4gICAgICAgIGV2ZW50TmFtZTogW1xuICAgICAgICAgICdDb21wbGV0ZU11bHRpcGFydFVwbG9hZCcsXG4gICAgICAgICAgJ0NvcHlPYmplY3QnLFxuICAgICAgICAgICdQdXRPYmplY3QnLFxuICAgICAgICBdLFxuICAgICAgICByZXF1ZXN0UGFyYW1ldGVyczoge1xuICAgICAgICAgIGJ1Y2tldE5hbWU6IFt0aGlzLmJ1Y2tldE5hbWVdLFxuICAgICAgICAgIGtleTogb3B0aW9ucy5wYXRocyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgcmV0dXJuIHJ1bGU7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHN0YXRlbWVudCB0byB0aGUgcmVzb3VyY2UgcG9saWN5IGZvciBhIHByaW5jaXBhbCAoaS5lLlxuICAgKiBhY2NvdW50L3JvbGUvc2VydmljZSkgdG8gcGVyZm9ybSBhY3Rpb25zIG9uIHRoaXMgYnVja2V0IGFuZC9vciBpdHNcbiAgICogY29udGVudHMuIFVzZSBgYnVja2V0QXJuYCBhbmQgYGFybkZvck9iamVjdHMoa2V5cylgIHRvIG9idGFpbiBBUk5zIGZvclxuICAgKiB0aGlzIGJ1Y2tldCBvciBvYmplY3RzLlxuICAgKlxuICAgKiBOb3RlIHRoYXQgdGhlIHBvbGljeSBzdGF0ZW1lbnQgbWF5IG9yIG1heSBub3QgYmUgYWRkZWQgdG8gdGhlIHBvbGljeS5cbiAgICogRm9yIGV4YW1wbGUsIHdoZW4gYW4gYElCdWNrZXRgIGlzIGNyZWF0ZWQgZnJvbSBhbiBleGlzdGluZyBidWNrZXQsXG4gICAqIGl0J3Mgbm90IHBvc3NpYmxlIHRvIHRlbGwgd2hldGhlciB0aGUgYnVja2V0IGFscmVhZHkgaGFzIGEgcG9saWN5XG4gICAqIGF0dGFjaGVkLCBsZXQgYWxvbmUgdG8gcmUtdXNlIHRoYXQgcG9saWN5IHRvIGFkZCBtb3JlIHN0YXRlbWVudHMgdG8gaXQuXG4gICAqIFNvIGl0J3Mgc2FmZXN0IHRvIGRvIG5vdGhpbmcgaW4gdGhlc2UgY2FzZXMuXG4gICAqXG4gICAqIEBwYXJhbSBwZXJtaXNzaW9uIHRoZSBwb2xpY3kgc3RhdGVtZW50IHRvIGJlIGFkZGVkIHRvIHRoZSBidWNrZXQnc1xuICAgKiBwb2xpY3kuXG4gICAqIEByZXR1cm5zIG1ldGFkYXRhIGFib3V0IHRoZSBleGVjdXRpb24gb2YgdGhpcyBtZXRob2QuIElmIHRoZSBwb2xpY3lcbiAgICogd2FzIG5vdCBhZGRlZCwgdGhlIHZhbHVlIG9mIGBzdGF0ZW1lbnRBZGRlZGAgd2lsbCBiZSBgZmFsc2VgLiBZb3VcbiAgICogc2hvdWxkIGFsd2F5cyBjaGVjayB0aGlzIHZhbHVlIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBvcGVyYXRpb24gd2FzXG4gICAqIGFjdHVhbGx5IGNhcnJpZWQgb3V0LiBPdGhlcndpc2UsIHN5bnRoZXNpcyBhbmQgZGVwbG95IHdpbGwgdGVybWluYXRlXG4gICAqIHNpbGVudGx5LCB3aGljaCBtYXkgYmUgY29uZnVzaW5nLlxuICAgKi9cbiAgcHVibGljIGFkZFRvUmVzb3VyY2VQb2xpY3kocGVybWlzc2lvbjogaWFtLlBvbGljeVN0YXRlbWVudCk6IGlhbS5BZGRUb1Jlc291cmNlUG9saWN5UmVzdWx0IHtcbiAgICBpZiAoIXRoaXMucG9saWN5ICYmIHRoaXMuYXV0b0NyZWF0ZVBvbGljeSkge1xuICAgICAgdGhpcy5wb2xpY3kgPSBuZXcgQnVja2V0UG9saWN5KHRoaXMsICdQb2xpY3knLCB7IGJ1Y2tldDogdGhpcyB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wb2xpY3kpIHtcbiAgICAgIHRoaXMucG9saWN5LmRvY3VtZW50LmFkZFN0YXRlbWVudHMocGVybWlzc2lvbik7XG4gICAgICByZXR1cm4geyBzdGF0ZW1lbnRBZGRlZDogdHJ1ZSwgcG9saWN5RGVwZW5kYWJsZTogdGhpcy5wb2xpY3kgfTtcbiAgICB9XG5cbiAgICByZXR1cm4geyBzdGF0ZW1lbnRBZGRlZDogZmFsc2UgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCB2YWxpZGF0ZSgpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgZXJyb3JzID0gc3VwZXIudmFsaWRhdGUoKTtcbiAgICBlcnJvcnMucHVzaCguLi50aGlzLnBvbGljeT8uZG9jdW1lbnQudmFsaWRhdGVGb3JSZXNvdXJjZVBvbGljeSgpIHx8IFtdKTtcbiAgICByZXR1cm4gZXJyb3JzO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBodHRwcyBVUkwgb2YgYW4gUzMgb2JqZWN0LiBTcGVjaWZ5IGByZWdpb25hbDogZmFsc2VgIGF0IHRoZSBvcHRpb25zXG4gICAqIGZvciBub24tcmVnaW9uYWwgVVJMcy4gRm9yIGV4YW1wbGU6XG4gICAqXG4gICAqIC0gYGh0dHBzOi8vczMudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20vb25seWJ1Y2tldGBcbiAgICogLSBgaHR0cHM6Ly9zMy51cy13ZXN0LTEuYW1hem9uYXdzLmNvbS9idWNrZXQva2V5YFxuICAgKiAtIGBodHRwczovL3MzLmNuLW5vcnRoLTEuYW1hem9uYXdzLmNvbS5jbi9jaGluYS1idWNrZXQvbXlrZXlgXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgVGhlIFMzIGtleSBvZiB0aGUgb2JqZWN0LiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgVVJMIG9mIHRoZVxuICAgKiAgICAgIGJ1Y2tldCBpcyByZXR1cm5lZC5cbiAgICogQHJldHVybnMgYW4gT2JqZWN0UzNVcmwgdG9rZW5cbiAgICovXG4gIHB1YmxpYyB1cmxGb3JPYmplY3Qoa2V5Pzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHRoaXMpO1xuICAgIGNvbnN0IHByZWZpeCA9IGBodHRwczovL3MzLiR7dGhpcy5lbnYucmVnaW9ufS4ke3N0YWNrLnVybFN1ZmZpeH0vYDtcbiAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB0aGlzLnVybEpvaW4ocHJlZml4LCB0aGlzLmJ1Y2tldE5hbWUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy51cmxKb2luKHByZWZpeCwgdGhpcy5idWNrZXROYW1lLCBrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBodHRwcyBUcmFuc2ZlciBBY2NlbGVyYXRpb24gVVJMIG9mIGFuIFMzIG9iamVjdC4gU3BlY2lmeSBgZHVhbFN0YWNrOiB0cnVlYCBhdCB0aGUgb3B0aW9uc1xuICAgKiBmb3IgZHVhbC1zdGFjayBlbmRwb2ludCAoY29ubmVjdCB0byB0aGUgYnVja2V0IG92ZXIgSVB2NikuIEZvciBleGFtcGxlOlxuICAgKlxuICAgKiAtIGBodHRwczovL2J1Y2tldC5zMy1hY2NlbGVyYXRlLmFtYXpvbmF3cy5jb21gXG4gICAqIC0gYGh0dHBzOi8vYnVja2V0LnMzLWFjY2VsZXJhdGUuYW1hem9uYXdzLmNvbS9rZXlgXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgVGhlIFMzIGtleSBvZiB0aGUgb2JqZWN0LiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgVVJMIG9mIHRoZVxuICAgKiAgICAgIGJ1Y2tldCBpcyByZXR1cm5lZC5cbiAgICogQHBhcmFtIG9wdGlvbnMgT3B0aW9ucyBmb3IgZ2VuZXJhdGluZyBVUkwuXG4gICAqIEByZXR1cm5zIGFuIFRyYW5zZmVyQWNjZWxlcmF0aW9uVXJsIHRva2VuXG4gICAqL1xuICBwdWJsaWMgdHJhbnNmZXJBY2NlbGVyYXRpb25VcmxGb3JPYmplY3Qoa2V5Pzogc3RyaW5nLCBvcHRpb25zPzogVHJhbnNmZXJBY2NlbGVyYXRpb25VcmxPcHRpb25zKTogc3RyaW5nIHtcbiAgICBjb25zdCBkdWFsU3RhY2sgPSBvcHRpb25zPy5kdWFsU3RhY2sgPyAnLmR1YWxzdGFjaycgOiAnJztcbiAgICBjb25zdCBwcmVmaXggPSBgaHR0cHM6Ly8ke3RoaXMuYnVja2V0TmFtZX0uczMtYWNjZWxlcmF0ZSR7ZHVhbFN0YWNrfS5hbWF6b25hd3MuY29tL2A7XG4gICAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gdGhpcy51cmxKb2luKHByZWZpeCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnVybEpvaW4ocHJlZml4LCBrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB2aXJ0dWFsIGhvc3RlZC1zdHlsZSBVUkwgb2YgYW4gUzMgb2JqZWN0LiBTcGVjaWZ5IGByZWdpb25hbDogZmFsc2VgIGF0XG4gICAqIHRoZSBvcHRpb25zIGZvciBub24tcmVnaW9uYWwgVVJMLiBGb3IgZXhhbXBsZTpcbiAgICpcbiAgICogLSBgaHR0cHM6Ly9vbmx5LWJ1Y2tldC5zMy51cy13ZXN0LTEuYW1hem9uYXdzLmNvbWBcbiAgICogLSBgaHR0cHM6Ly9idWNrZXQuczMudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20va2V5YFxuICAgKiAtIGBodHRwczovL2J1Y2tldC5zMy5hbWF6b25hd3MuY29tL2tleWBcbiAgICogLSBgaHR0cHM6Ly9jaGluYS1idWNrZXQuczMuY24tbm9ydGgtMS5hbWF6b25hd3MuY29tLmNuL215a2V5YFxuICAgKlxuICAgKiBAcGFyYW0ga2V5IFRoZSBTMyBrZXkgb2YgdGhlIG9iamVjdC4gSWYgbm90IHNwZWNpZmllZCwgdGhlIFVSTCBvZiB0aGVcbiAgICogICAgICBidWNrZXQgaXMgcmV0dXJuZWQuXG4gICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbnMgZm9yIGdlbmVyYXRpbmcgVVJMLlxuICAgKiBAcmV0dXJucyBhbiBPYmplY3RTM1VybCB0b2tlblxuICAgKi9cbiAgcHVibGljIHZpcnR1YWxIb3N0ZWRVcmxGb3JPYmplY3Qoa2V5Pzogc3RyaW5nLCBvcHRpb25zPzogVmlydHVhbEhvc3RlZFN0eWxlVXJsT3B0aW9ucyk6IHN0cmluZyB7XG4gICAgY29uc3QgZG9tYWluTmFtZSA9IG9wdGlvbnM/LnJlZ2lvbmFsID8/IHRydWUgPyB0aGlzLmJ1Y2tldFJlZ2lvbmFsRG9tYWluTmFtZSA6IHRoaXMuYnVja2V0RG9tYWluTmFtZTtcbiAgICBjb25zdCBwcmVmaXggPSBgaHR0cHM6Ly8ke2RvbWFpbk5hbWV9YDtcbiAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBwcmVmaXg7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnVybEpvaW4ocHJlZml4LCBrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBTMyBVUkwgb2YgYW4gUzMgb2JqZWN0LiBGb3IgZXhhbXBsZTpcbiAgICpcbiAgICogLSBgczM6Ly9vbmx5YnVja2V0YFxuICAgKiAtIGBzMzovL2J1Y2tldC9rZXlgXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgVGhlIFMzIGtleSBvZiB0aGUgb2JqZWN0LiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgUzMgVVJMIG9mIHRoZVxuICAgKiAgICAgIGJ1Y2tldCBpcyByZXR1cm5lZC5cbiAgICogQHJldHVybnMgYW4gT2JqZWN0UzNVcmwgdG9rZW5cbiAgICovXG4gIHB1YmxpYyBzM1VybEZvck9iamVjdChrZXk/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHByZWZpeCA9ICdzMzovLyc7XG4gICAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gdGhpcy51cmxKb2luKHByZWZpeCwgdGhpcy5idWNrZXROYW1lKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudXJsSm9pbihwcmVmaXgsIHRoaXMuYnVja2V0TmFtZSwga2V5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIEFSTiB0aGF0IHJlcHJlc2VudHMgYWxsIG9iamVjdHMgd2l0aGluIHRoZSBidWNrZXQgdGhhdCBtYXRjaFxuICAgKiB0aGUga2V5IHBhdHRlcm4gc3BlY2lmaWVkLiBUbyByZXByZXNlbnQgYWxsIGtleXMsIHNwZWNpZnkgYGBcIipcImBgLlxuICAgKlxuICAgKiBJZiB5b3UgbmVlZCB0byBzcGVjaWZ5IGEga2V5UGF0dGVybiB3aXRoIG11bHRpcGxlIGNvbXBvbmVudHMsIGNvbmNhdGVuYXRlIHRoZW0gaW50byBhIHNpbmdsZSBzdHJpbmcsIGUuZy46XG4gICAqXG4gICAqICAgYXJuRm9yT2JqZWN0cyhgaG9tZS8ke3RlYW19LyR7dXNlcn0vKmApXG4gICAqXG4gICAqL1xuICBwdWJsaWMgYXJuRm9yT2JqZWN0cyhrZXlQYXR0ZXJuOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHt0aGlzLmJ1Y2tldEFybn0vJHtrZXlQYXR0ZXJufWA7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnQgcmVhZCBwZXJtaXNzaW9ucyBmb3IgdGhpcyBidWNrZXQgYW5kIGl0J3MgY29udGVudHMgdG8gYW4gSUFNXG4gICAqIHByaW5jaXBhbCAoUm9sZS9Hcm91cC9Vc2VyKS5cbiAgICpcbiAgICogSWYgZW5jcnlwdGlvbiBpcyB1c2VkLCBwZXJtaXNzaW9uIHRvIHVzZSB0aGUga2V5IHRvIGRlY3J5cHQgdGhlIGNvbnRlbnRzXG4gICAqIG9mIHRoZSBidWNrZXQgd2lsbCBhbHNvIGJlIGdyYW50ZWQgdG8gdGhlIHNhbWUgcHJpbmNpcGFsLlxuICAgKlxuICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIHByaW5jaXBhbFxuICAgKiBAcGFyYW0gb2JqZWN0c0tleVBhdHRlcm4gUmVzdHJpY3QgdGhlIHBlcm1pc3Npb24gdG8gYSBjZXJ0YWluIGtleSBwYXR0ZXJuIChkZWZhdWx0ICcqJylcbiAgICovXG4gIHB1YmxpYyBncmFudFJlYWQoaWRlbnRpdHk6IGlhbS5JR3JhbnRhYmxlLCBvYmplY3RzS2V5UGF0dGVybjogYW55ID0gJyonKSB7XG4gICAgcmV0dXJuIHRoaXMuZ3JhbnQoaWRlbnRpdHksIHBlcm1zLkJVQ0tFVF9SRUFEX0FDVElPTlMsIHBlcm1zLktFWV9SRUFEX0FDVElPTlMsXG4gICAgICB0aGlzLmJ1Y2tldEFybixcbiAgICAgIHRoaXMuYXJuRm9yT2JqZWN0cyhvYmplY3RzS2V5UGF0dGVybikpO1xuICB9XG5cbiAgcHVibGljIGdyYW50V3JpdGUoaWRlbnRpdHk6IGlhbS5JR3JhbnRhYmxlLCBvYmplY3RzS2V5UGF0dGVybjogYW55ID0gJyonKSB7XG4gICAgcmV0dXJuIHRoaXMuZ3JhbnQoaWRlbnRpdHksIHRoaXMud3JpdGVBY3Rpb25zLCBwZXJtcy5LRVlfV1JJVEVfQUNUSU9OUyxcbiAgICAgIHRoaXMuYnVja2V0QXJuLFxuICAgICAgdGhpcy5hcm5Gb3JPYmplY3RzKG9iamVjdHNLZXlQYXR0ZXJuKSk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHMzOlB1dE9iamVjdCogYW5kIHMzOkFib3J0KiBwZXJtaXNzaW9ucyBmb3IgdGhpcyBidWNrZXQgdG8gYW4gSUFNIHByaW5jaXBhbC5cbiAgICpcbiAgICogSWYgZW5jcnlwdGlvbiBpcyB1c2VkLCBwZXJtaXNzaW9uIHRvIHVzZSB0aGUga2V5IHRvIGVuY3J5cHQgdGhlIGNvbnRlbnRzXG4gICAqIG9mIHdyaXR0ZW4gZmlsZXMgd2lsbCBhbHNvIGJlIGdyYW50ZWQgdG8gdGhlIHNhbWUgcHJpbmNpcGFsLlxuICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIHByaW5jaXBhbFxuICAgKiBAcGFyYW0gb2JqZWN0c0tleVBhdHRlcm4gUmVzdHJpY3QgdGhlIHBlcm1pc3Npb24gdG8gYSBjZXJ0YWluIGtleSBwYXR0ZXJuIChkZWZhdWx0ICcqJylcbiAgICovXG4gIHB1YmxpYyBncmFudFB1dChpZGVudGl0eTogaWFtLklHcmFudGFibGUsIG9iamVjdHNLZXlQYXR0ZXJuOiBhbnkgPSAnKicpIHtcbiAgICByZXR1cm4gdGhpcy5ncmFudChpZGVudGl0eSwgdGhpcy5wdXRBY3Rpb25zLCBwZXJtcy5LRVlfV1JJVEVfQUNUSU9OUyxcbiAgICAgIHRoaXMuYXJuRm9yT2JqZWN0cyhvYmplY3RzS2V5UGF0dGVybikpO1xuICB9XG5cbiAgcHVibGljIGdyYW50UHV0QWNsKGlkZW50aXR5OiBpYW0uSUdyYW50YWJsZSwgb2JqZWN0c0tleVBhdHRlcm46IHN0cmluZyA9ICcqJykge1xuICAgIHJldHVybiB0aGlzLmdyYW50KGlkZW50aXR5LCBwZXJtcy5CVUNLRVRfUFVUX0FDTF9BQ1RJT05TLCBbXSxcbiAgICAgIHRoaXMuYXJuRm9yT2JqZWN0cyhvYmplY3RzS2V5UGF0dGVybikpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBzMzpEZWxldGVPYmplY3QqIHBlcm1pc3Npb24gdG8gYW4gSUFNIHByaW5jaXBhbCBmb3Igb2JqZWN0c1xuICAgKiBpbiB0aGlzIGJ1Y2tldC5cbiAgICpcbiAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBwcmluY2lwYWxcbiAgICogQHBhcmFtIG9iamVjdHNLZXlQYXR0ZXJuIFJlc3RyaWN0IHRoZSBwZXJtaXNzaW9uIHRvIGEgY2VydGFpbiBrZXkgcGF0dGVybiAoZGVmYXVsdCAnKicpXG4gICAqL1xuICBwdWJsaWMgZ3JhbnREZWxldGUoaWRlbnRpdHk6IGlhbS5JR3JhbnRhYmxlLCBvYmplY3RzS2V5UGF0dGVybjogYW55ID0gJyonKSB7XG4gICAgcmV0dXJuIHRoaXMuZ3JhbnQoaWRlbnRpdHksIHBlcm1zLkJVQ0tFVF9ERUxFVEVfQUNUSU9OUywgW10sXG4gICAgICB0aGlzLmFybkZvck9iamVjdHMob2JqZWN0c0tleVBhdHRlcm4pKTtcbiAgfVxuXG4gIHB1YmxpYyBncmFudFJlYWRXcml0ZShpZGVudGl0eTogaWFtLklHcmFudGFibGUsIG9iamVjdHNLZXlQYXR0ZXJuOiBhbnkgPSAnKicpIHtcbiAgICBjb25zdCBidWNrZXRBY3Rpb25zID0gcGVybXMuQlVDS0VUX1JFQURfQUNUSU9OUy5jb25jYXQodGhpcy53cml0ZUFjdGlvbnMpO1xuICAgIC8vIHdlIG5lZWQgdW5pcXVlIHBlcm1pc3Npb25zIGJlY2F1c2Ugc29tZSBwZXJtaXNzaW9ucyBhcmUgY29tbW9uIGJldHdlZW4gcmVhZCBhbmQgd3JpdGUga2V5IGFjdGlvbnNcbiAgICBjb25zdCBrZXlBY3Rpb25zID0gWy4uLm5ldyBTZXQoWy4uLnBlcm1zLktFWV9SRUFEX0FDVElPTlMsIC4uLnBlcm1zLktFWV9XUklURV9BQ1RJT05TXSldO1xuXG4gICAgcmV0dXJuIHRoaXMuZ3JhbnQoaWRlbnRpdHksXG4gICAgICBidWNrZXRBY3Rpb25zLFxuICAgICAga2V5QWN0aW9ucyxcbiAgICAgIHRoaXMuYnVja2V0QXJuLFxuICAgICAgdGhpcy5hcm5Gb3JPYmplY3RzKG9iamVjdHNLZXlQYXR0ZXJuKSk7XG4gIH1cblxuICAvKipcbiAgICogQWxsb3dzIHVucmVzdHJpY3RlZCBhY2Nlc3MgdG8gb2JqZWN0cyBmcm9tIHRoaXMgYnVja2V0LlxuICAgKlxuICAgKiBJTVBPUlRBTlQ6IFRoaXMgcGVybWlzc2lvbiBhbGxvd3MgYW55b25lIHRvIHBlcmZvcm0gYWN0aW9ucyBvbiBTMyBvYmplY3RzXG4gICAqIGluIHRoaXMgYnVja2V0LCB3aGljaCBpcyB1c2VmdWwgZm9yIHdoZW4geW91IGNvbmZpZ3VyZSB5b3VyIGJ1Y2tldCBhcyBhXG4gICAqIHdlYnNpdGUgYW5kIHdhbnQgZXZlcnlvbmUgdG8gYmUgYWJsZSB0byByZWFkIG9iamVjdHMgaW4gdGhlIGJ1Y2tldCB3aXRob3V0XG4gICAqIG5lZWRpbmcgdG8gYXV0aGVudGljYXRlLlxuICAgKlxuICAgKiBXaXRob3V0IGFyZ3VtZW50cywgdGhpcyBtZXRob2Qgd2lsbCBncmFudCByZWFkIChcInMzOkdldE9iamVjdFwiKSBhY2Nlc3MgdG9cbiAgICogYWxsIG9iamVjdHMgKFwiKlwiKSBpbiB0aGUgYnVja2V0LlxuICAgKlxuICAgKiBUaGUgbWV0aG9kIHJldHVybnMgdGhlIGBpYW0uR3JhbnRgIG9iamVjdCwgd2hpY2ggY2FuIHRoZW4gYmUgbW9kaWZpZWRcbiAgICogYXMgbmVlZGVkLiBGb3IgZXhhbXBsZSwgeW91IGNhbiBhZGQgYSBjb25kaXRpb24gdGhhdCB3aWxsIHJlc3RyaWN0IGFjY2VzcyBvbmx5XG4gICAqIHRvIGFuIElQdjQgcmFuZ2UgbGlrZSB0aGlzOlxuICAgKlxuICAgKiAgICAgY29uc3QgZ3JhbnQgPSBidWNrZXQuZ3JhbnRQdWJsaWNBY2Nlc3MoKTtcbiAgICogICAgIGdyYW50LnJlc291cmNlU3RhdGVtZW50IS5hZGRDb25kaXRpb24o4oCYSXBBZGRyZXNz4oCZLCB7IOKAnGF3czpTb3VyY2VJcOKAnTog4oCcNTQuMjQwLjE0My4wLzI04oCdIH0pO1xuICAgKlxuICAgKiBOb3RlIHRoYXQgaWYgdGhpcyBgSUJ1Y2tldGAgcmVmZXJzIHRvIGFuIGV4aXN0aW5nIGJ1Y2tldCwgcG9zc2libHkgbm90XG4gICAqIG1hbmFnZWQgYnkgQ2xvdWRGb3JtYXRpb24sIHRoaXMgbWV0aG9kIHdpbGwgaGF2ZSBubyBlZmZlY3QsIHNpbmNlIGl0J3NcbiAgICogaW1wb3NzaWJsZSB0byBtb2RpZnkgdGhlIHBvbGljeSBvZiBhbiBleGlzdGluZyBidWNrZXQuXG4gICAqXG4gICAqIEBwYXJhbSBrZXlQcmVmaXggdGhlIHByZWZpeCBvZiBTMyBvYmplY3Qga2V5cyAoZS5nLiBgaG9tZS8qYCkuIERlZmF1bHQgaXMgXCIqXCIuXG4gICAqIEBwYXJhbSBhbGxvd2VkQWN0aW9ucyB0aGUgc2V0IG9mIFMzIGFjdGlvbnMgdG8gYWxsb3cuIERlZmF1bHQgaXMgXCJzMzpHZXRPYmplY3RcIi5cbiAgICovXG4gIHB1YmxpYyBncmFudFB1YmxpY0FjY2VzcyhrZXlQcmVmaXggPSAnKicsIC4uLmFsbG93ZWRBY3Rpb25zOiBzdHJpbmdbXSkge1xuICAgIGlmICh0aGlzLmRpc2FsbG93UHVibGljQWNjZXNzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgZ3JhbnQgcHVibGljIGFjY2VzcyB3aGVuICdibG9ja1B1YmxpY1BvbGljeScgaXMgZW5hYmxlZFwiKTtcbiAgICB9XG5cbiAgICBhbGxvd2VkQWN0aW9ucyA9IGFsbG93ZWRBY3Rpb25zLmxlbmd0aCA+IDAgPyBhbGxvd2VkQWN0aW9ucyA6IFsnczM6R2V0T2JqZWN0J107XG5cbiAgICByZXR1cm4gaWFtLkdyYW50LmFkZFRvUHJpbmNpcGFsT3JSZXNvdXJjZSh7XG4gICAgICBhY3Rpb25zOiBhbGxvd2VkQWN0aW9ucyxcbiAgICAgIHJlc291cmNlQXJuczogW3RoaXMuYXJuRm9yT2JqZWN0cyhrZXlQcmVmaXgpXSxcbiAgICAgIGdyYW50ZWU6IG5ldyBpYW0uQW55UHJpbmNpcGFsKCksXG4gICAgICByZXNvdXJjZTogdGhpcyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgYnVja2V0IG5vdGlmaWNhdGlvbiBldmVudCBkZXN0aW5hdGlvbi5cbiAgICogQHBhcmFtIGV2ZW50IFRoZSBldmVudCB0byB0cmlnZ2VyIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIGRlc3QgVGhlIG5vdGlmaWNhdGlvbiBkZXN0aW5hdGlvbiAoTGFtYmRhLCBTTlMgVG9waWMgb3IgU1FTIFF1ZXVlKVxuICAgKlxuICAgKiBAcGFyYW0gZmlsdGVycyBTMyBvYmplY3Qga2V5IGZpbHRlciBydWxlcyB0byBkZXRlcm1pbmUgd2hpY2ggb2JqZWN0c1xuICAgKiB0cmlnZ2VyIHRoaXMgZXZlbnQuIEVhY2ggZmlsdGVyIG11c3QgaW5jbHVkZSBhIGBwcmVmaXhgIGFuZC9vciBgc3VmZml4YFxuICAgKiB0aGF0IHdpbGwgYmUgbWF0Y2hlZCBhZ2FpbnN0IHRoZSBzMyBvYmplY3Qga2V5LiBSZWZlciB0byB0aGUgUzMgRGV2ZWxvcGVyIEd1aWRlXG4gICAqIGZvciBkZXRhaWxzIGFib3V0IGFsbG93ZWQgZmlsdGVyIHJ1bGVzLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25TMy9sYXRlc3QvZGV2L05vdGlmaWNhdGlvbkhvd1RvLmh0bWwjbm90aWZpY2F0aW9uLWhvdy10by1maWx0ZXJpbmdcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogICAgZGVjbGFyZSBjb25zdCBteUxhbWJkYTogbGFtYmRhLkZ1bmN0aW9uO1xuICAgKiAgICBjb25zdCBidWNrZXQgPSBuZXcgczMuQnVja2V0KHRoaXMsICdNeUJ1Y2tldCcpO1xuICAgKiAgICBidWNrZXQuYWRkRXZlbnROb3RpZmljYXRpb24oczMuRXZlbnRUeXBlLk9CSkVDVF9DUkVBVEVELCBuZXcgczNuLkxhbWJkYURlc3RpbmF0aW9uKG15TGFtYmRhKSwge3ByZWZpeDogJ2hvbWUvbXl1c2VybmFtZS8qJ30pO1xuICAgKlxuICAgKiBAc2VlXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25TMy9sYXRlc3QvZGV2L05vdGlmaWNhdGlvbkhvd1RvLmh0bWxcbiAgICovXG4gIHB1YmxpYyBhZGRFdmVudE5vdGlmaWNhdGlvbihldmVudDogRXZlbnRUeXBlLCBkZXN0OiBJQnVja2V0Tm90aWZpY2F0aW9uRGVzdGluYXRpb24sIC4uLmZpbHRlcnM6IE5vdGlmaWNhdGlvbktleUZpbHRlcltdKSB7XG4gICAgdGhpcy53aXRoTm90aWZpY2F0aW9ucyhub3RpZmljYXRpb25zID0+IG5vdGlmaWNhdGlvbnMuYWRkTm90aWZpY2F0aW9uKGV2ZW50LCBkZXN0LCAuLi5maWx0ZXJzKSk7XG4gIH1cblxuICBwcml2YXRlIHdpdGhOb3RpZmljYXRpb25zKGNiOiAobm90aWZpY2F0aW9uczogQnVja2V0Tm90aWZpY2F0aW9ucykgPT4gdm9pZCkge1xuICAgIGlmICghdGhpcy5ub3RpZmljYXRpb25zKSB7XG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMgPSBuZXcgQnVja2V0Tm90aWZpY2F0aW9ucyh0aGlzLCAnTm90aWZpY2F0aW9ucycsIHtcbiAgICAgICAgYnVja2V0OiB0aGlzLFxuICAgICAgICBoYW5kbGVyUm9sZTogdGhpcy5ub3RpZmljYXRpb25zSGFuZGxlclJvbGUsXG4gICAgICB9KTtcbiAgICB9XG4gICAgY2IodGhpcy5ub3RpZmljYXRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWJzY3JpYmVzIGEgZGVzdGluYXRpb24gdG8gcmVjZWl2ZSBub3RpZmljYXRpb25zIHdoZW4gYW4gb2JqZWN0IGlzXG4gICAqIGNyZWF0ZWQgaW4gdGhlIGJ1Y2tldC4gVGhpcyBpcyBpZGVudGljYWwgdG8gY2FsbGluZ1xuICAgKiBgb25FdmVudChFdmVudFR5cGUuT0JKRUNUX0NSRUFURUQpYC5cbiAgICpcbiAgICogQHBhcmFtIGRlc3QgVGhlIG5vdGlmaWNhdGlvbiBkZXN0aW5hdGlvbiAoc2VlIG9uRXZlbnQpXG4gICAqIEBwYXJhbSBmaWx0ZXJzIEZpbHRlcnMgKHNlZSBvbkV2ZW50KVxuICAgKi9cbiAgcHVibGljIGFkZE9iamVjdENyZWF0ZWROb3RpZmljYXRpb24oZGVzdDogSUJ1Y2tldE5vdGlmaWNhdGlvbkRlc3RpbmF0aW9uLCAuLi5maWx0ZXJzOiBOb3RpZmljYXRpb25LZXlGaWx0ZXJbXSkge1xuICAgIHJldHVybiB0aGlzLmFkZEV2ZW50Tm90aWZpY2F0aW9uKEV2ZW50VHlwZS5PQkpFQ1RfQ1JFQVRFRCwgZGVzdCwgLi4uZmlsdGVycyk7XG4gIH1cblxuICAvKipcbiAgICogU3Vic2NyaWJlcyBhIGRlc3RpbmF0aW9uIHRvIHJlY2VpdmUgbm90aWZpY2F0aW9ucyB3aGVuIGFuIG9iamVjdCBpc1xuICAgKiByZW1vdmVkIGZyb20gdGhlIGJ1Y2tldC4gVGhpcyBpcyBpZGVudGljYWwgdG8gY2FsbGluZ1xuICAgKiBgb25FdmVudChFdmVudFR5cGUuT0JKRUNUX1JFTU9WRUQpYC5cbiAgICpcbiAgICogQHBhcmFtIGRlc3QgVGhlIG5vdGlmaWNhdGlvbiBkZXN0aW5hdGlvbiAoc2VlIG9uRXZlbnQpXG4gICAqIEBwYXJhbSBmaWx0ZXJzIEZpbHRlcnMgKHNlZSBvbkV2ZW50KVxuICAgKi9cbiAgcHVibGljIGFkZE9iamVjdFJlbW92ZWROb3RpZmljYXRpb24oZGVzdDogSUJ1Y2tldE5vdGlmaWNhdGlvbkRlc3RpbmF0aW9uLCAuLi5maWx0ZXJzOiBOb3RpZmljYXRpb25LZXlGaWx0ZXJbXSkge1xuICAgIHJldHVybiB0aGlzLmFkZEV2ZW50Tm90aWZpY2F0aW9uKEV2ZW50VHlwZS5PQkpFQ1RfUkVNT1ZFRCwgZGVzdCwgLi4uZmlsdGVycyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZW5hYmxlRXZlbnRCcmlkZ2VOb3RpZmljYXRpb24oKSB7XG4gICAgdGhpcy53aXRoTm90aWZpY2F0aW9ucyhub3RpZmljYXRpb25zID0+IG5vdGlmaWNhdGlvbnMuZW5hYmxlRXZlbnRCcmlkZ2VOb3RpZmljYXRpb24oKSk7XG4gIH1cblxuICBwcml2YXRlIGdldCB3cml0ZUFjdGlvbnMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBbXG4gICAgICAuLi5wZXJtcy5CVUNLRVRfREVMRVRFX0FDVElPTlMsXG4gICAgICAuLi50aGlzLnB1dEFjdGlvbnMsXG4gICAgXTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IHB1dEFjdGlvbnMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBGZWF0dXJlRmxhZ3Mub2YodGhpcykuaXNFbmFibGVkKGN4YXBpLlMzX0dSQU5UX1dSSVRFX1dJVEhPVVRfQUNMKVxuICAgICAgPyBwZXJtcy5CVUNLRVRfUFVUX0FDVElPTlNcbiAgICAgIDogcGVybXMuTEVHQUNZX0JVQ0tFVF9QVVRfQUNUSU9OUztcbiAgfVxuXG4gIHByaXZhdGUgdXJsSm9pbiguLi5jb21wb25lbnRzOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNvbXBvbmVudHMucmVkdWNlKChyZXN1bHQsIGNvbXBvbmVudCkgPT4ge1xuICAgICAgaWYgKHJlc3VsdC5lbmRzV2l0aCgnLycpKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zbGljZSgwLCAtMSk7XG4gICAgICB9XG4gICAgICBpZiAoY29tcG9uZW50LnN0YXJ0c1dpdGgoJy8nKSkge1xuICAgICAgICBjb21wb25lbnQgPSBjb21wb25lbnQuc2xpY2UoMSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYCR7cmVzdWx0fS8ke2NvbXBvbmVudH1gO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBncmFudChcbiAgICBncmFudGVlOiBpYW0uSUdyYW50YWJsZSxcbiAgICBidWNrZXRBY3Rpb25zOiBzdHJpbmdbXSxcbiAgICBrZXlBY3Rpb25zOiBzdHJpbmdbXSxcbiAgICByZXNvdXJjZUFybjogc3RyaW5nLCAuLi5vdGhlclJlc291cmNlQXJuczogc3RyaW5nW10pIHtcbiAgICBjb25zdCByZXNvdXJjZXMgPSBbcmVzb3VyY2VBcm4sIC4uLm90aGVyUmVzb3VyY2VBcm5zXTtcblxuICAgIGNvbnN0IHJldCA9IGlhbS5HcmFudC5hZGRUb1ByaW5jaXBhbE9yUmVzb3VyY2Uoe1xuICAgICAgZ3JhbnRlZSxcbiAgICAgIGFjdGlvbnM6IGJ1Y2tldEFjdGlvbnMsXG4gICAgICByZXNvdXJjZUFybnM6IHJlc291cmNlcyxcbiAgICAgIHJlc291cmNlOiB0aGlzLFxuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuZW5jcnlwdGlvbktleSAmJiBrZXlBY3Rpb25zICYmIGtleUFjdGlvbnMubGVuZ3RoICE9PSAwKSB7XG4gICAgICB0aGlzLmVuY3J5cHRpb25LZXkuZ3JhbnQoZ3JhbnRlZSwgLi4ua2V5QWN0aW9ucyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJldDtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJsb2NrUHVibGljQWNjZXNzT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGJsb2NrIHB1YmxpYyBBQ0xzXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvblMzL2xhdGVzdC9kZXYvYWNjZXNzLWNvbnRyb2wtYmxvY2stcHVibGljLWFjY2Vzcy5odG1sI2FjY2Vzcy1jb250cm9sLWJsb2NrLXB1YmxpYy1hY2Nlc3Mtb3B0aW9uc1xuICAgKi9cbiAgcmVhZG9ubHkgYmxvY2tQdWJsaWNBY2xzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hldGhlciB0byBibG9jayBwdWJsaWMgcG9saWN5XG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvblMzL2xhdGVzdC9kZXYvYWNjZXNzLWNvbnRyb2wtYmxvY2stcHVibGljLWFjY2Vzcy5odG1sI2FjY2Vzcy1jb250cm9sLWJsb2NrLXB1YmxpYy1hY2Nlc3Mtb3B0aW9uc1xuICAgKi9cbiAgcmVhZG9ubHkgYmxvY2tQdWJsaWNQb2xpY3k/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGlnbm9yZSBwdWJsaWMgQUNMc1xuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25TMy9sYXRlc3QvZGV2L2FjY2Vzcy1jb250cm9sLWJsb2NrLXB1YmxpYy1hY2Nlc3MuaHRtbCNhY2Nlc3MtY29udHJvbC1ibG9jay1wdWJsaWMtYWNjZXNzLW9wdGlvbnNcbiAgICovXG4gIHJlYWRvbmx5IGlnbm9yZVB1YmxpY0FjbHM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHJlc3RyaWN0IHB1YmxpYyBhY2Nlc3NcbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uUzMvbGF0ZXN0L2Rldi9hY2Nlc3MtY29udHJvbC1ibG9jay1wdWJsaWMtYWNjZXNzLmh0bWwjYWNjZXNzLWNvbnRyb2wtYmxvY2stcHVibGljLWFjY2Vzcy1vcHRpb25zXG4gICAqL1xuICByZWFkb25seSByZXN0cmljdFB1YmxpY0J1Y2tldHM/OiBib29sZWFuO1xufVxuXG5leHBvcnQgY2xhc3MgQmxvY2tQdWJsaWNBY2Nlc3Mge1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IEJMT0NLX0FMTCA9IG5ldyBCbG9ja1B1YmxpY0FjY2Vzcyh7XG4gICAgYmxvY2tQdWJsaWNBY2xzOiB0cnVlLFxuICAgIGJsb2NrUHVibGljUG9saWN5OiB0cnVlLFxuICAgIGlnbm9yZVB1YmxpY0FjbHM6IHRydWUsXG4gICAgcmVzdHJpY3RQdWJsaWNCdWNrZXRzOiB0cnVlLFxuICB9KTtcblxuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IEJMT0NLX0FDTFMgPSBuZXcgQmxvY2tQdWJsaWNBY2Nlc3Moe1xuICAgIGJsb2NrUHVibGljQWNsczogdHJ1ZSxcbiAgICBpZ25vcmVQdWJsaWNBY2xzOiB0cnVlLFxuICB9KTtcblxuICBwdWJsaWMgYmxvY2tQdWJsaWNBY2xzOiBib29sZWFuIHwgdW5kZWZpbmVkO1xuICBwdWJsaWMgYmxvY2tQdWJsaWNQb2xpY3k6IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4gIHB1YmxpYyBpZ25vcmVQdWJsaWNBY2xzOiBib29sZWFuIHwgdW5kZWZpbmVkO1xuICBwdWJsaWMgcmVzdHJpY3RQdWJsaWNCdWNrZXRzOiBib29sZWFuIHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IEJsb2NrUHVibGljQWNjZXNzT3B0aW9ucykge1xuICAgIHRoaXMuYmxvY2tQdWJsaWNBY2xzID0gb3B0aW9ucy5ibG9ja1B1YmxpY0FjbHM7XG4gICAgdGhpcy5ibG9ja1B1YmxpY1BvbGljeSA9IG9wdGlvbnMuYmxvY2tQdWJsaWNQb2xpY3k7XG4gICAgdGhpcy5pZ25vcmVQdWJsaWNBY2xzID0gb3B0aW9ucy5pZ25vcmVQdWJsaWNBY2xzO1xuICAgIHRoaXMucmVzdHJpY3RQdWJsaWNCdWNrZXRzID0gb3B0aW9ucy5yZXN0cmljdFB1YmxpY0J1Y2tldHM7XG4gIH1cbn1cblxuLyoqXG4gKiBTcGVjaWZpZXMgYSBtZXRyaWNzIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBDbG91ZFdhdGNoIHJlcXVlc3QgbWV0cmljcyBmcm9tIGFuIEFtYXpvbiBTMyBidWNrZXQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQnVja2V0TWV0cmljcyB7XG4gIC8qKlxuICAgKiBUaGUgSUQgdXNlZCB0byBpZGVudGlmeSB0aGUgbWV0cmljcyBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBwcmVmaXggdGhhdCBhbiBvYmplY3QgbXVzdCBoYXZlIHRvIGJlIGluY2x1ZGVkIGluIHRoZSBtZXRyaWNzIHJlc3VsdHMuXG4gICAqL1xuICByZWFkb25seSBwcmVmaXg/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgYSBsaXN0IG9mIHRhZyBmaWx0ZXJzIHRvIHVzZSBhcyBhIG1ldHJpY3MgY29uZmlndXJhdGlvbiBmaWx0ZXIuXG4gICAqIFRoZSBtZXRyaWNzIGNvbmZpZ3VyYXRpb24gaW5jbHVkZXMgb25seSBvYmplY3RzIHRoYXQgbWVldCB0aGUgZmlsdGVyJ3MgY3JpdGVyaWEuXG4gICAqL1xuICByZWFkb25seSB0YWdGaWx0ZXJzPzogeyBbdGFnOiBzdHJpbmddOiBhbnkgfTtcbn1cblxuLyoqXG4gKiBBbGwgaHR0cCByZXF1ZXN0IG1ldGhvZHNcbiAqL1xuZXhwb3J0IGVudW0gSHR0cE1ldGhvZHMge1xuICAvKipcbiAgICogVGhlIEdFVCBtZXRob2QgcmVxdWVzdHMgYSByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3BlY2lmaWVkIHJlc291cmNlLlxuICAgKi9cbiAgR0VUID0gJ0dFVCcsXG4gIC8qKlxuICAgKiBUaGUgUFVUIG1ldGhvZCByZXBsYWNlcyBhbGwgY3VycmVudCByZXByZXNlbnRhdGlvbnMgb2YgdGhlIHRhcmdldCByZXNvdXJjZSB3aXRoIHRoZSByZXF1ZXN0IHBheWxvYWQuXG4gICAqL1xuICBQVVQgPSAnUFVUJyxcbiAgLyoqXG4gICAqIFRoZSBIRUFEIG1ldGhvZCBhc2tzIGZvciBhIHJlc3BvbnNlIGlkZW50aWNhbCB0byB0aGF0IG9mIGEgR0VUIHJlcXVlc3QsIGJ1dCB3aXRob3V0IHRoZSByZXNwb25zZSBib2R5LlxuICAgKi9cbiAgSEVBRCA9ICdIRUFEJyxcbiAgLyoqXG4gICAqIFRoZSBQT1NUIG1ldGhvZCBpcyB1c2VkIHRvIHN1Ym1pdCBhbiBlbnRpdHkgdG8gdGhlIHNwZWNpZmllZCByZXNvdXJjZSwgb2Z0ZW4gY2F1c2luZyBhIGNoYW5nZSBpbiBzdGF0ZSBvciBzaWRlIGVmZmVjdHMgb24gdGhlIHNlcnZlci5cbiAgICovXG4gIFBPU1QgPSAnUE9TVCcsXG4gIC8qKlxuICAgKiBUaGUgREVMRVRFIG1ldGhvZCBkZWxldGVzIHRoZSBzcGVjaWZpZWQgcmVzb3VyY2UuXG4gICAqL1xuICBERUxFVEUgPSAnREVMRVRFJyxcbn1cblxuLyoqXG4gKiBTcGVjaWZpZXMgYSBjcm9zcy1vcmlnaW4gYWNjZXNzIHJ1bGUgZm9yIGFuIEFtYXpvbiBTMyBidWNrZXQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29yc1J1bGUge1xuICAvKipcbiAgICogQSB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhpcyBydWxlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGlkIHNwZWNpZmllZC5cbiAgICovXG4gIHJlYWRvbmx5IGlkPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHRpbWUgaW4gc2Vjb25kcyB0aGF0IHlvdXIgYnJvd3NlciBpcyB0byBjYWNoZSB0aGUgcHJlZmxpZ2h0IHJlc3BvbnNlIGZvciB0aGUgc3BlY2lmaWVkIHJlc291cmNlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGNhY2hpbmcuXG4gICAqL1xuICByZWFkb25seSBtYXhBZ2U/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBIZWFkZXJzIHRoYXQgYXJlIHNwZWNpZmllZCBpbiB0aGUgQWNjZXNzLUNvbnRyb2wtUmVxdWVzdC1IZWFkZXJzIGhlYWRlci5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBoZWFkZXJzIGFsbG93ZWQuXG4gICAqL1xuICByZWFkb25seSBhbGxvd2VkSGVhZGVycz86IHN0cmluZ1tdO1xuICAvKipcbiAgICogQW4gSFRUUCBtZXRob2QgdGhhdCB5b3UgYWxsb3cgdGhlIG9yaWdpbiB0byBleGVjdXRlLlxuICAgKi9cbiAgcmVhZG9ubHkgYWxsb3dlZE1ldGhvZHM6IEh0dHBNZXRob2RzW107XG4gIC8qKlxuICAgKiBPbmUgb3IgbW9yZSBvcmlnaW5zIHlvdSB3YW50IGN1c3RvbWVycyB0byBiZSBhYmxlIHRvIGFjY2VzcyB0aGUgYnVja2V0IGZyb20uXG4gICAqL1xuICByZWFkb25seSBhbGxvd2VkT3JpZ2luczogc3RyaW5nW107XG4gIC8qKlxuICAgKiBPbmUgb3IgbW9yZSBoZWFkZXJzIGluIHRoZSByZXNwb25zZSB0aGF0IHlvdSB3YW50IGN1c3RvbWVycyB0byBiZSBhYmxlIHRvIGFjY2VzcyBmcm9tIHRoZWlyIGFwcGxpY2F0aW9ucy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBoZWFkZXJzIGV4cG9zZWQuXG4gICAqL1xuICByZWFkb25seSBleHBvc2VkSGVhZGVycz86IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIEFsbCBodHRwIHJlcXVlc3QgbWV0aG9kc1xuICovXG5leHBvcnQgZW51bSBSZWRpcmVjdFByb3RvY29sIHtcbiAgSFRUUCA9ICdodHRwJyxcbiAgSFRUUFMgPSAnaHR0cHMnLFxufVxuXG4vKipcbiAqIFNwZWNpZmllcyBhIHJlZGlyZWN0IGJlaGF2aW9yIG9mIGFsbCByZXF1ZXN0cyB0byBhIHdlYnNpdGUgZW5kcG9pbnQgb2YgYSBidWNrZXQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVkaXJlY3RUYXJnZXQge1xuICAvKipcbiAgICogTmFtZSBvZiB0aGUgaG9zdCB3aGVyZSByZXF1ZXN0cyBhcmUgcmVkaXJlY3RlZFxuICAgKi9cbiAgcmVhZG9ubHkgaG9zdE5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogUHJvdG9jb2wgdG8gdXNlIHdoZW4gcmVkaXJlY3RpbmcgcmVxdWVzdHNcbiAgICpcbiAgICogQGRlZmF1bHQgLSBUaGUgcHJvdG9jb2wgdXNlZCBpbiB0aGUgb3JpZ2luYWwgcmVxdWVzdC5cbiAgICovXG4gIHJlYWRvbmx5IHByb3RvY29sPzogUmVkaXJlY3RQcm90b2NvbDtcbn1cblxuLyoqXG4gKiBBbGwgc3VwcG9ydGVkIGludmVudG9yeSBsaXN0IGZvcm1hdHMuXG4gKi9cbmV4cG9ydCBlbnVtIEludmVudG9yeUZvcm1hdCB7XG4gIC8qKlxuICAgKiBHZW5lcmF0ZSB0aGUgaW52ZW50b3J5IGxpc3QgYXMgQ1NWLlxuICAgKi9cbiAgQ1NWID0gJ0NTVicsXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSB0aGUgaW52ZW50b3J5IGxpc3QgYXMgUGFycXVldC5cbiAgICovXG4gIFBBUlFVRVQgPSAnUGFycXVldCcsXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSB0aGUgaW52ZW50b3J5IGxpc3QgYXMgT1JDLlxuICAgKi9cbiAgT1JDID0gJ09SQycsXG59XG5cbi8qKlxuICogQWxsIHN1cHBvcnRlZCBpbnZlbnRvcnkgZnJlcXVlbmNpZXMuXG4gKi9cbmV4cG9ydCBlbnVtIEludmVudG9yeUZyZXF1ZW5jeSB7XG4gIC8qKlxuICAgKiBBIHJlcG9ydCBpcyBnZW5lcmF0ZWQgZXZlcnkgZGF5LlxuICAgKi9cbiAgREFJTFkgPSAnRGFpbHknLFxuICAvKipcbiAgICogQSByZXBvcnQgaXMgZ2VuZXJhdGVkIGV2ZXJ5IFN1bmRheSAoVVRDIHRpbWV6b25lKSBhZnRlciB0aGUgaW5pdGlhbCByZXBvcnQuXG4gICAqL1xuICBXRUVLTFkgPSAnV2Vla2x5J1xufVxuXG4vKipcbiAqIEludmVudG9yeSB2ZXJzaW9uIHN1cHBvcnQuXG4gKi9cbmV4cG9ydCBlbnVtIEludmVudG9yeU9iamVjdFZlcnNpb24ge1xuICAvKipcbiAgICogSW5jbHVkZXMgYWxsIHZlcnNpb25zIG9mIGVhY2ggb2JqZWN0IGluIHRoZSByZXBvcnQuXG4gICAqL1xuICBBTEwgPSAnQWxsJyxcbiAgLyoqXG4gICAqIEluY2x1ZGVzIG9ubHkgdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiBlYWNoIG9iamVjdCBpbiB0aGUgcmVwb3J0LlxuICAgKi9cbiAgQ1VSUkVOVCA9ICdDdXJyZW50Jyxcbn1cblxuLyoqXG4gKiBUaGUgZGVzdGluYXRpb24gb2YgdGhlIGludmVudG9yeS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbnZlbnRvcnlEZXN0aW5hdGlvbiB7XG4gIC8qKlxuICAgKiBCdWNrZXQgd2hlcmUgYWxsIGludmVudG9yaWVzIHdpbGwgYmUgc2F2ZWQgaW4uXG4gICAqL1xuICByZWFkb25seSBidWNrZXQ6IElCdWNrZXQ7XG4gIC8qKlxuICAgKiBUaGUgcHJlZml4IHRvIGJlIHVzZWQgd2hlbiBzYXZpbmcgdGhlIGludmVudG9yeS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBwcmVmaXguXG4gICAqL1xuICByZWFkb25seSBwcmVmaXg/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgYWNjb3VudCBJRCB0aGF0IG93bnMgdGhlIGRlc3RpbmF0aW9uIFMzIGJ1Y2tldC5cbiAgICogSWYgbm8gYWNjb3VudCBJRCBpcyBwcm92aWRlZCwgdGhlIG93bmVyIGlzIG5vdCB2YWxpZGF0ZWQgYmVmb3JlIGV4cG9ydGluZyBkYXRhLlxuICAgKiBJdCdzIHJlY29tbWVuZGVkIHRvIHNldCBhbiBhY2NvdW50IElEIHRvIHByZXZlbnQgcHJvYmxlbXMgaWYgdGhlIGRlc3RpbmF0aW9uIGJ1Y2tldCBvd25lcnNoaXAgY2hhbmdlcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBhY2NvdW50IElELlxuICAgKi9cbiAgcmVhZG9ubHkgYnVja2V0T3duZXI/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogU3BlY2lmaWVzIHRoZSBpbnZlbnRvcnkgY29uZmlndXJhdGlvbiBvZiBhbiBTMyBCdWNrZXQuXG4gKlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uUzMvbGF0ZXN0L2Rldi9zdG9yYWdlLWludmVudG9yeS5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW52ZW50b3J5IHtcbiAgLyoqXG4gICAqIFRoZSBkZXN0aW5hdGlvbiBvZiB0aGUgaW52ZW50b3J5LlxuICAgKi9cbiAgcmVhZG9ubHkgZGVzdGluYXRpb246IEludmVudG9yeURlc3RpbmF0aW9uO1xuICAvKipcbiAgICogVGhlIGludmVudG9yeSB3aWxsIG9ubHkgaW5jbHVkZSBvYmplY3RzIHRoYXQgbWVldCB0aGUgcHJlZml4IGZpbHRlciBjcml0ZXJpYS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBvYmplY3RzIHByZWZpeFxuICAgKi9cbiAgcmVhZG9ubHkgb2JqZWN0c1ByZWZpeD86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBmb3JtYXQgb2YgdGhlIGludmVudG9yeS5cbiAgICpcbiAgICogQGRlZmF1bHQgSW52ZW50b3J5Rm9ybWF0LkNTVlxuICAgKi9cbiAgcmVhZG9ubHkgZm9ybWF0PzogSW52ZW50b3J5Rm9ybWF0O1xuICAvKipcbiAgICogV2hldGhlciB0aGUgaW52ZW50b3J5IGlzIGVuYWJsZWQgb3IgZGlzYWJsZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGVuYWJsZWQ/OiBib29sZWFuO1xuICAvKipcbiAgICogVGhlIGludmVudG9yeSBjb25maWd1cmF0aW9uIElELlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGdlbmVyYXRlZCBJRC5cbiAgICovXG4gIHJlYWRvbmx5IGludmVudG9yeUlkPzogc3RyaW5nO1xuICAvKipcbiAgICogRnJlcXVlbmN5IGF0IHdoaWNoIHRoZSBpbnZlbnRvcnkgc2hvdWxkIGJlIGdlbmVyYXRlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgSW52ZW50b3J5RnJlcXVlbmN5LldFRUtMWVxuICAgKi9cbiAgcmVhZG9ubHkgZnJlcXVlbmN5PzogSW52ZW50b3J5RnJlcXVlbmN5O1xuICAvKipcbiAgICogSWYgdGhlIGludmVudG9yeSBzaG91bGQgY29udGFpbiBhbGwgdGhlIG9iamVjdCB2ZXJzaW9ucyBvciBvbmx5IHRoZSBjdXJyZW50IG9uZS5cbiAgICpcbiAgICogQGRlZmF1bHQgSW52ZW50b3J5T2JqZWN0VmVyc2lvbi5BTExcbiAgICovXG4gIHJlYWRvbmx5IGluY2x1ZGVPYmplY3RWZXJzaW9ucz86IEludmVudG9yeU9iamVjdFZlcnNpb247XG4gIC8qKlxuICAgKiBBIGxpc3Qgb2Ygb3B0aW9uYWwgZmllbGRzIHRvIGJlIGluY2x1ZGVkIGluIHRoZSBpbnZlbnRvcnkgcmVzdWx0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIG9wdGlvbmFsIGZpZWxkcy5cbiAgICovXG4gIHJlYWRvbmx5IG9wdGlvbmFsRmllbGRzPzogc3RyaW5nW107XG59XG4vKipcbiAgICogVGhlIE9iamVjdE93bmVyc2hpcCBvZiB0aGUgYnVja2V0LlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25TMy9sYXRlc3QvZGV2L2Fib3V0LW9iamVjdC1vd25lcnNoaXAuaHRtbFxuICAgKlxuICAgKi9cbmV4cG9ydCBlbnVtIE9iamVjdE93bmVyc2hpcCB7XG4gIC8qKlxuICAgKiBBQ0xzIGFyZSBkaXNhYmxlZCwgYW5kIHRoZSBidWNrZXQgb3duZXIgYXV0b21hdGljYWxseSBvd25zXG4gICAqIGFuZCBoYXMgZnVsbCBjb250cm9sIG92ZXIgZXZlcnkgb2JqZWN0IGluIHRoZSBidWNrZXQuXG4gICAqIEFDTHMgbm8gbG9uZ2VyIGFmZmVjdCBwZXJtaXNzaW9ucyB0byBkYXRhIGluIHRoZSBTMyBidWNrZXQuXG4gICAqIFRoZSBidWNrZXQgdXNlcyBwb2xpY2llcyB0byBkZWZpbmUgYWNjZXNzIGNvbnRyb2wuXG4gICAqL1xuICBCVUNLRVRfT1dORVJfRU5GT1JDRUQgPSAnQnVja2V0T3duZXJFbmZvcmNlZCcsXG4gIC8qKlxuICAgKiBPYmplY3RzIHVwbG9hZGVkIHRvIHRoZSBidWNrZXQgY2hhbmdlIG93bmVyc2hpcCB0byB0aGUgYnVja2V0IG93bmVyIC5cbiAgICovXG4gIEJVQ0tFVF9PV05FUl9QUkVGRVJSRUQgPSAnQnVja2V0T3duZXJQcmVmZXJyZWQnLFxuICAvKipcbiAgICogVGhlIHVwbG9hZGluZyBhY2NvdW50IHdpbGwgb3duIHRoZSBvYmplY3QuXG4gICAqL1xuICBPQkpFQ1RfV1JJVEVSID0gJ09iamVjdFdyaXRlcicsXG59XG4vKipcbiAqIFRoZSBpbnRlbGxpZ2VudCB0aWVyaW5nIGNvbmZpZ3VyYXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW50ZWxsaWdlbnRUaWVyaW5nQ29uZmlndXJhdGlvbiB7XG4gIC8qKlxuICAgKiBDb25maWd1cmF0aW9uIG5hbWVcbiAgICovXG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuXG4gIC8qKlxuICAgKiBBZGQgYSBmaWx0ZXIgdG8gbGltaXQgdGhlIHNjb3BlIG9mIHRoaXMgY29uZmlndXJhdGlvbiB0byBhIHNpbmdsZSBwcmVmaXguXG4gICAqXG4gICAqIEBkZWZhdWx0IHRoaXMgY29uZmlndXJhdGlvbiB3aWxsIGFwcGx5IHRvICoqYWxsKiogb2JqZWN0cyBpbiB0aGUgYnVja2V0LlxuICAgKi9cbiAgcmVhZG9ubHkgcHJlZml4Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBZb3UgY2FuIGxpbWl0IHRoZSBzY29wZSBvZiB0aGlzIHJ1bGUgdG8gdGhlIGtleSB2YWx1ZSBwYWlycyBhZGRlZCBiZWxvdy5cbiAgICpcbiAgICogQGRlZmF1bHQgTm8gZmlsdGVyaW5nIHdpbGwgYmUgcGVyZm9ybWVkIG9uIHRhZ3NcbiAgICovXG4gIHJlYWRvbmx5IHRhZ3M/OiBUYWdbXTtcblxuICAvKipcbiAgICogV2hlbiBlbmFibGVkLCBJbnRlbGxpZ2VudC1UaWVyaW5nIHdpbGwgYXV0b21hdGljYWxseSBtb3ZlIG9iamVjdHMgdGhhdFxuICAgKiBoYXZlbuKAmXQgYmVlbiBhY2Nlc3NlZCBmb3IgYSBtaW5pbXVtIG9mIDkwIGRheXMgdG8gdGhlIEFyY2hpdmUgQWNjZXNzIHRpZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IE9iamVjdHMgd2lsbCBub3QgbW92ZSB0byBHbGFjaWVyXG4gICAqL1xuICByZWFkb25seSBhcmNoaXZlQWNjZXNzVGllclRpbWU/OiBEdXJhdGlvbjtcblxuICAvKipcbiAgICogV2hlbiBlbmFibGVkLCBJbnRlbGxpZ2VudC1UaWVyaW5nIHdpbGwgYXV0b21hdGljYWxseSBtb3ZlIG9iamVjdHMgdGhhdFxuICAgKiBoYXZlbuKAmXQgYmVlbiBhY2Nlc3NlZCBmb3IgYSBtaW5pbXVtIG9mIDE4MCBkYXlzIHRvIHRoZSBEZWVwIEFyY2hpdmUgQWNjZXNzXG4gICAqIHRpZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IE9iamVjdHMgd2lsbCBub3QgbW92ZSB0byBHbGFjaWVyIERlZXAgQWNjZXNzXG4gICAqL1xuICByZWFkb25seSBkZWVwQXJjaGl2ZUFjY2Vzc1RpZXJUaW1lPzogRHVyYXRpb247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnVja2V0UHJvcHMge1xuICAvKipcbiAgICogVGhlIGtpbmQgb2Ygc2VydmVyLXNpZGUgZW5jcnlwdGlvbiB0byBhcHBseSB0byB0aGlzIGJ1Y2tldC5cbiAgICpcbiAgICogSWYgeW91IGNob29zZSBLTVMsIHlvdSBjYW4gc3BlY2lmeSBhIEtNUyBrZXkgdmlhIGBlbmNyeXB0aW9uS2V5YC4gSWZcbiAgICogZW5jcnlwdGlvbiBrZXkgaXMgbm90IHNwZWNpZmllZCwgYSBrZXkgd2lsbCBhdXRvbWF0aWNhbGx5IGJlIGNyZWF0ZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYEttc2AgaWYgYGVuY3J5cHRpb25LZXlgIGlzIHNwZWNpZmllZCwgb3IgYFVuZW5jcnlwdGVkYCBvdGhlcndpc2UuXG4gICAqL1xuICByZWFkb25seSBlbmNyeXB0aW9uPzogQnVja2V0RW5jcnlwdGlvbjtcblxuICAvKipcbiAgICogRXh0ZXJuYWwgS01TIGtleSB0byB1c2UgZm9yIGJ1Y2tldCBlbmNyeXB0aW9uLlxuICAgKlxuICAgKiBUaGUgJ2VuY3J5cHRpb24nIHByb3BlcnR5IG11c3QgYmUgZWl0aGVyIG5vdCBzcGVjaWZpZWQgb3Igc2V0IHRvIFwiS21zXCIuXG4gICAqIEFuIGVycm9yIHdpbGwgYmUgZW1pdHRlZCBpZiBlbmNyeXB0aW9uIGlzIHNldCB0byBcIlVuZW5jcnlwdGVkXCIgb3JcbiAgICogXCJNYW5hZ2VkXCIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gSWYgZW5jcnlwdGlvbiBpcyBzZXQgdG8gXCJLbXNcIiBhbmQgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWQsXG4gICAqIGEgbmV3IEtNUyBrZXkgd2lsbCBiZSBjcmVhdGVkIGFuZCBhc3NvY2lhdGVkIHdpdGggdGhpcyBidWNrZXQuXG4gICAqL1xuICByZWFkb25seSBlbmNyeXB0aW9uS2V5Pzoga21zLklLZXk7XG5cbiAgLyoqXG4gICogRW5mb3JjZXMgU1NMIGZvciByZXF1ZXN0cy4gUzMuNSBvZiB0aGUgQVdTIEZvdW5kYXRpb25hbCBTZWN1cml0eSBCZXN0IFByYWN0aWNlcyBSZWdhcmRpbmcgUzMuXG4gICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY29uZmlnL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zMy1idWNrZXQtc3NsLXJlcXVlc3RzLW9ubHkuaHRtbFxuICAqXG4gICogQGRlZmF1bHQgZmFsc2VcbiAgKi9cbiAgcmVhZG9ubHkgZW5mb3JjZVNTTD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB3aGV0aGVyIEFtYXpvbiBTMyBzaG91bGQgdXNlIGFuIFMzIEJ1Y2tldCBLZXkgd2l0aCBzZXJ2ZXItc2lkZVxuICAgKiBlbmNyeXB0aW9uIHVzaW5nIEtNUyAoU1NFLUtNUykgZm9yIG5ldyBvYmplY3RzIGluIHRoZSBidWNrZXQuXG4gICAqXG4gICAqIE9ubHkgcmVsZXZhbnQsIHdoZW4gRW5jcnlwdGlvbiBpcyBzZXQgdG8ge0BsaW5rIEJ1Y2tldEVuY3J5cHRpb24uS01TfVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGZhbHNlXG4gICAqL1xuICByZWFkb25seSBidWNrZXRLZXlFbmFibGVkPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogUGh5c2ljYWwgbmFtZSBvZiB0aGlzIGJ1Y2tldC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBBc3NpZ25lZCBieSBDbG91ZEZvcm1hdGlvbiAocmVjb21tZW5kZWQpLlxuICAgKi9cbiAgcmVhZG9ubHkgYnVja2V0TmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogUG9saWN5IHRvIGFwcGx5IHdoZW4gdGhlIGJ1Y2tldCBpcyByZW1vdmVkIGZyb20gdGhpcyBzdGFjay5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBUaGUgYnVja2V0IHdpbGwgYmUgb3JwaGFuZWQuXG4gICAqL1xuICByZWFkb25seSByZW1vdmFsUG9saWN5PzogUmVtb3ZhbFBvbGljeTtcblxuICAvKipcbiAgICogV2hldGhlciBhbGwgb2JqZWN0cyBzaG91bGQgYmUgYXV0b21hdGljYWxseSBkZWxldGVkIHdoZW4gdGhlIGJ1Y2tldCBpc1xuICAgKiByZW1vdmVkIGZyb20gdGhlIHN0YWNrIG9yIHdoZW4gdGhlIHN0YWNrIGlzIGRlbGV0ZWQuXG4gICAqXG4gICAqIFJlcXVpcmVzIHRoZSBgcmVtb3ZhbFBvbGljeWAgdG8gYmUgc2V0IHRvIGBSZW1vdmFsUG9saWN5LkRFU1RST1lgLlxuICAgKlxuICAgKiAqKldhcm5pbmcqKiBpZiB5b3UgaGF2ZSBkZXBsb3llZCBhIGJ1Y2tldCB3aXRoIGBhdXRvRGVsZXRlT2JqZWN0czogdHJ1ZWAsXG4gICAqIHN3aXRjaGluZyB0aGlzIHRvIGBmYWxzZWAgaW4gYSBDREsgdmVyc2lvbiAqYmVmb3JlKiBgMS4xMjYuMGAgd2lsbCBsZWFkIHRvXG4gICAqIGFsbCBvYmplY3RzIGluIHRoZSBidWNrZXQgYmVpbmcgZGVsZXRlZC4gQmUgc3VyZSB0byB1cGRhdGUgeW91ciBidWNrZXQgcmVzb3VyY2VzXG4gICAqIGJ5IGRlcGxveWluZyB3aXRoIENESyB2ZXJzaW9uIGAxLjEyNi4wYCBvciBsYXRlciAqKmJlZm9yZSoqIHN3aXRjaGluZyB0aGlzIHZhbHVlIHRvIGBmYWxzZWAuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBhdXRvRGVsZXRlT2JqZWN0cz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhpcyBidWNrZXQgc2hvdWxkIGhhdmUgdmVyc2lvbmluZyB0dXJuZWQgb24gb3Igbm90LlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbmVkPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hldGhlciB0aGlzIGJ1Y2tldCBzaG91bGQgc2VuZCBub3RpZmljYXRpb25zIHRvIEFtYXpvbiBFdmVudEJyaWRnZSBvciBub3QuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBldmVudEJyaWRnZUVuYWJsZWQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBSdWxlcyB0aGF0IGRlZmluZSBob3cgQW1hem9uIFMzIG1hbmFnZXMgb2JqZWN0cyBkdXJpbmcgdGhlaXIgbGlmZXRpbWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gbGlmZWN5Y2xlIHJ1bGVzLlxuICAgKi9cbiAgcmVhZG9ubHkgbGlmZWN5Y2xlUnVsZXM/OiBMaWZlY3ljbGVSdWxlW107XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBpbmRleCBkb2N1bWVudCAoZS5nLiBcImluZGV4Lmh0bWxcIikgZm9yIHRoZSB3ZWJzaXRlLiBFbmFibGVzIHN0YXRpYyB3ZWJzaXRlXG4gICAqIGhvc3RpbmcgZm9yIHRoaXMgYnVja2V0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGluZGV4IGRvY3VtZW50LlxuICAgKi9cbiAgcmVhZG9ubHkgd2Vic2l0ZUluZGV4RG9jdW1lbnQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBlcnJvciBkb2N1bWVudCAoZS5nLiBcIjQwNC5odG1sXCIpIGZvciB0aGUgd2Vic2l0ZS5cbiAgICogYHdlYnNpdGVJbmRleERvY3VtZW50YCBtdXN0IGFsc28gYmUgc2V0IGlmIHRoaXMgaXMgc2V0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGVycm9yIGRvY3VtZW50LlxuICAgKi9cbiAgcmVhZG9ubHkgd2Vic2l0ZUVycm9yRG9jdW1lbnQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB0aGUgcmVkaXJlY3QgYmVoYXZpb3Igb2YgYWxsIHJlcXVlc3RzIHRvIGEgd2Vic2l0ZSBlbmRwb2ludCBvZiBhIGJ1Y2tldC5cbiAgICpcbiAgICogSWYgeW91IHNwZWNpZnkgdGhpcyBwcm9wZXJ0eSwgeW91IGNhbid0IHNwZWNpZnkgXCJ3ZWJzaXRlSW5kZXhEb2N1bWVudFwiLCBcIndlYnNpdGVFcnJvckRvY3VtZW50XCIgbm9yICwgXCJ3ZWJzaXRlUm91dGluZ1J1bGVzXCIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gcmVkaXJlY3Rpb24uXG4gICAqL1xuICByZWFkb25seSB3ZWJzaXRlUmVkaXJlY3Q/OiBSZWRpcmVjdFRhcmdldDtcblxuICAvKipcbiAgICogUnVsZXMgdGhhdCBkZWZpbmUgd2hlbiBhIHJlZGlyZWN0IGlzIGFwcGxpZWQgYW5kIHRoZSByZWRpcmVjdCBiZWhhdmlvclxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIHJlZGlyZWN0aW9uIHJ1bGVzLlxuICAgKi9cbiAgcmVhZG9ubHkgd2Vic2l0ZVJvdXRpbmdSdWxlcz86IFJvdXRpbmdSdWxlW107XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyBhIGNhbm5lZCBBQ0wgdGhhdCBncmFudHMgcHJlZGVmaW5lZCBwZXJtaXNzaW9ucyB0byB0aGUgYnVja2V0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBCdWNrZXRBY2Nlc3NDb250cm9sLlBSSVZBVEVcbiAgICovXG4gIHJlYWRvbmx5IGFjY2Vzc0NvbnRyb2w/OiBCdWNrZXRBY2Nlc3NDb250cm9sO1xuXG4gIC8qKlxuICAgKiBHcmFudHMgcHVibGljIHJlYWQgYWNjZXNzIHRvIGFsbCBvYmplY3RzIGluIHRoZSBidWNrZXQuXG4gICAqIFNpbWlsYXIgdG8gY2FsbGluZyBgYnVja2V0LmdyYW50UHVibGljQWNjZXNzKClgXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBwdWJsaWNSZWFkQWNjZXNzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIGJsb2NrIHB1YmxpYyBhY2Nlc3MgY29uZmlndXJhdGlvbiBvZiB0aGlzIGJ1Y2tldC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uUzMvbGF0ZXN0L2Rldi9hY2Nlc3MtY29udHJvbC1ibG9jay1wdWJsaWMtYWNjZXNzLmh0bWxcbiAgICpcbiAgICpcbiAgICogQGRlZmF1bHQgLSBDbG91ZEZvcm1hdGlvbiBkZWZhdWx0cyB3aWxsIGFwcGx5LiBOZXcgYnVja2V0cyBhbmQgb2JqZWN0cyBkb24ndCBhbGxvdyBwdWJsaWMgYWNjZXNzLCBidXQgdXNlcnMgY2FuIG1vZGlmeSBidWNrZXQgcG9saWNpZXMgb3Igb2JqZWN0IHBlcm1pc3Npb25zIHRvIGFsbG93IHB1YmxpYyBhY2Nlc3NcbiAgICovXG4gIHJlYWRvbmx5IGJsb2NrUHVibGljQWNjZXNzPzogQmxvY2tQdWJsaWNBY2Nlc3M7XG5cbiAgLyoqXG4gICAqIFRoZSBtZXRyaWNzIGNvbmZpZ3VyYXRpb24gb2YgdGhpcyBidWNrZXQuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtczMtYnVja2V0LW1ldHJpY3Njb25maWd1cmF0aW9uLmh0bWxcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBtZXRyaWNzIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICByZWFkb25seSBtZXRyaWNzPzogQnVja2V0TWV0cmljc1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgQ09SUyBjb25maWd1cmF0aW9uIG9mIHRoaXMgYnVja2V0LlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXMzLWJ1Y2tldC1jb3JzLmh0bWxcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBDT1JTIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICByZWFkb25seSBjb3JzPzogQ29yc1J1bGVbXTtcblxuICAvKipcbiAgICogRGVzdGluYXRpb24gYnVja2V0IGZvciB0aGUgc2VydmVyIGFjY2VzcyBsb2dzLlxuICAgKiBAZGVmYXVsdCAtIElmIFwic2VydmVyQWNjZXNzTG9nc1ByZWZpeFwiIHVuZGVmaW5lZCAtIGFjY2VzcyBsb2dzIGRpc2FibGVkLCBvdGhlcndpc2UgLSBsb2cgdG8gY3VycmVudCBidWNrZXQuXG4gICAqL1xuICByZWFkb25seSBzZXJ2ZXJBY2Nlc3NMb2dzQnVja2V0PzogSUJ1Y2tldDtcblxuICAvKipcbiAgICogT3B0aW9uYWwgbG9nIGZpbGUgcHJlZml4IHRvIHVzZSBmb3IgdGhlIGJ1Y2tldCdzIGFjY2VzcyBsb2dzLlxuICAgKiBJZiBkZWZpbmVkIHdpdGhvdXQgXCJzZXJ2ZXJBY2Nlc3NMb2dzQnVja2V0XCIsIGVuYWJsZXMgYWNjZXNzIGxvZ3MgdG8gY3VycmVudCBidWNrZXQgd2l0aCB0aGlzIHByZWZpeC5cbiAgICogQGRlZmF1bHQgLSBObyBsb2cgZmlsZSBwcmVmaXhcbiAgICovXG4gIHJlYWRvbmx5IHNlcnZlckFjY2Vzc0xvZ3NQcmVmaXg/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBpbnZlbnRvcnkgY29uZmlndXJhdGlvbiBvZiB0aGUgYnVja2V0LlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25TMy9sYXRlc3QvZGV2L3N0b3JhZ2UtaW52ZW50b3J5Lmh0bWxcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBpbnZlbnRvcnkgY29uZmlndXJhdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgaW52ZW50b3JpZXM/OiBJbnZlbnRvcnlbXTtcbiAgLyoqXG4gICAqIFRoZSBvYmplY3RPd25lcnNoaXAgb2YgdGhlIGJ1Y2tldC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uUzMvbGF0ZXN0L2Rldi9hYm91dC1vYmplY3Qtb3duZXJzaGlwLmh0bWxcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBPYmplY3RPd25lcnNoaXAgY29uZmlndXJhdGlvbiwgdXBsb2FkaW5nIGFjY291bnQgd2lsbCBvd24gdGhlIG9iamVjdC5cbiAgICpcbiAgICovXG4gIHJlYWRvbmx5IG9iamVjdE93bmVyc2hpcD86IE9iamVjdE93bmVyc2hpcDtcblxuICAvKipcbiAgICogV2hldGhlciB0aGlzIGJ1Y2tldCBzaG91bGQgaGF2ZSB0cmFuc2ZlciBhY2NlbGVyYXRpb24gdHVybmVkIG9uIG9yIG5vdC5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zZmVyQWNjZWxlcmF0aW9uPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIHJvbGUgdG8gYmUgdXNlZCBieSB0aGUgbm90aWZpY2F0aW9ucyBoYW5kbGVyXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYSBuZXcgcm9sZSB3aWxsIGJlIGNyZWF0ZWQuXG4gICAqL1xuICByZWFkb25seSBub3RpZmljYXRpb25zSGFuZGxlclJvbGU/OiBpYW0uSVJvbGU7XG5cbiAgLyoqXG4gICAqIEludGVsaWdlbnQgVGllcmluZyBDb25maWd1cmF0aW9uc1xuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25TMy9sYXRlc3QvdXNlcmd1aWRlL2ludGVsbGlnZW50LXRpZXJpbmcuaHRtbFxuICAgKlxuICAgKiBAZGVmYXVsdCBObyBJbnRlbGxpZ2VudCBUaWllcmluZyBDb25maWd1cmF0aW9ucy5cbiAgICovXG4gIHJlYWRvbmx5IGludGVsbGlnZW50VGllcmluZ0NvbmZpZ3VyYXRpb25zPzogSW50ZWxsaWdlbnRUaWVyaW5nQ29uZmlndXJhdGlvbltdO1xufVxuXG5cbi8qKlxuICogVGFnXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGFnIHtcblxuICAvKipcbiAgICoga2V5IHRvIGUgdGFnZ2VkXG4gICAqL1xuICByZWFkb25seSBrZXk6IHN0cmluZztcbiAgLyoqXG4gICAqIGFkZGl0aW9uYWwgdmFsdWVcbiAgICovXG4gIHJlYWRvbmx5IHZhbHVlOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQW4gUzMgYnVja2V0IHdpdGggYXNzb2NpYXRlZCBwb2xpY3kgb2JqZWN0c1xuICpcbiAqIFRoaXMgYnVja2V0IGRvZXMgbm90IHlldCBoYXZlIGFsbCBmZWF0dXJlcyB0aGF0IGV4cG9zZWQgYnkgdGhlIHVuZGVybHlpbmdcbiAqIEJ1Y2tldFJlc291cmNlLlxuICovXG5leHBvcnQgY2xhc3MgQnVja2V0IGV4dGVuZHMgQnVja2V0QmFzZSB7XG5cbiAgcHVibGljIHN0YXRpYyBmcm9tQnVja2V0QXJuKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIGJ1Y2tldEFybjogc3RyaW5nKTogSUJ1Y2tldCB7XG4gICAgcmV0dXJuIEJ1Y2tldC5mcm9tQnVja2V0QXR0cmlidXRlcyhzY29wZSwgaWQsIHsgYnVja2V0QXJuIH0pO1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyBmcm9tQnVja2V0TmFtZShzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcpOiBJQnVja2V0IHtcbiAgICByZXR1cm4gQnVja2V0LmZyb21CdWNrZXRBdHRyaWJ1dGVzKHNjb3BlLCBpZCwgeyBidWNrZXROYW1lIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBCdWNrZXQgY29uc3RydWN0IHRoYXQgcmVwcmVzZW50cyBhbiBleHRlcm5hbCBidWNrZXQuXG4gICAqXG4gICAqIEBwYXJhbSBzY29wZSBUaGUgcGFyZW50IGNyZWF0aW5nIGNvbnN0cnVjdCAodXN1YWxseSBgdGhpc2ApLlxuICAgKiBAcGFyYW0gaWQgVGhlIGNvbnN0cnVjdCdzIG5hbWUuXG4gICAqIEBwYXJhbSBhdHRycyBBIGBCdWNrZXRBdHRyaWJ1dGVzYCBvYmplY3QuIENhbiBiZSBvYnRhaW5lZCBmcm9tIGEgY2FsbCB0b1xuICAgKiBgYnVja2V0LmV4cG9ydCgpYCBvciBtYW51YWxseSBjcmVhdGVkLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tQnVja2V0QXR0cmlidXRlcyhzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBhdHRyczogQnVja2V0QXR0cmlidXRlcyk6IElCdWNrZXQge1xuICAgIGNvbnN0IHN0YWNrID0gU3RhY2sub2Yoc2NvcGUpO1xuICAgIGNvbnN0IHJlZ2lvbiA9IGF0dHJzLnJlZ2lvbiA/PyBzdGFjay5yZWdpb247XG4gICAgY29uc3QgdXJsU3VmZml4ID0gc3RhY2sudXJsU3VmZml4O1xuXG4gICAgY29uc3QgYnVja2V0TmFtZSA9IHBhcnNlQnVja2V0TmFtZShzY29wZSwgYXR0cnMpO1xuICAgIGlmICghYnVja2V0TmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdCdWNrZXQgbmFtZSBpcyByZXF1aXJlZCcpO1xuICAgIH1cbiAgICBCdWNrZXQudmFsaWRhdGVCdWNrZXROYW1lKGJ1Y2tldE5hbWUpO1xuXG4gICAgY29uc3QgbmV3VXJsRm9ybWF0ID0gYXR0cnMuYnVja2V0V2Vic2l0ZU5ld1VybEZvcm1hdCA9PT0gdW5kZWZpbmVkXG4gICAgICA/IGZhbHNlXG4gICAgICA6IGF0dHJzLmJ1Y2tldFdlYnNpdGVOZXdVcmxGb3JtYXQ7XG5cbiAgICBjb25zdCB3ZWJzaXRlRG9tYWluID0gbmV3VXJsRm9ybWF0XG4gICAgICA/IGAke2J1Y2tldE5hbWV9LnMzLXdlYnNpdGUuJHtyZWdpb259LiR7dXJsU3VmZml4fWBcbiAgICAgIDogYCR7YnVja2V0TmFtZX0uczMtd2Vic2l0ZS0ke3JlZ2lvbn0uJHt1cmxTdWZmaXh9YDtcblxuICAgIGNsYXNzIEltcG9ydCBleHRlbmRzIEJ1Y2tldEJhc2Uge1xuICAgICAgcHVibGljIHJlYWRvbmx5IGJ1Y2tldE5hbWUgPSBidWNrZXROYW1lITtcbiAgICAgIHB1YmxpYyByZWFkb25seSBidWNrZXRBcm4gPSBwYXJzZUJ1Y2tldEFybihzY29wZSwgYXR0cnMpO1xuICAgICAgcHVibGljIHJlYWRvbmx5IGJ1Y2tldERvbWFpbk5hbWUgPSBhdHRycy5idWNrZXREb21haW5OYW1lIHx8IGAke2J1Y2tldE5hbWV9LnMzLiR7dXJsU3VmZml4fWA7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgYnVja2V0V2Vic2l0ZVVybCA9IGF0dHJzLmJ1Y2tldFdlYnNpdGVVcmwgfHwgYGh0dHA6Ly8ke3dlYnNpdGVEb21haW59YDtcbiAgICAgIHB1YmxpYyByZWFkb25seSBidWNrZXRXZWJzaXRlRG9tYWluTmFtZSA9IGF0dHJzLmJ1Y2tldFdlYnNpdGVVcmwgPyBGbi5zZWxlY3QoMiwgRm4uc3BsaXQoJy8nLCBhdHRycy5idWNrZXRXZWJzaXRlVXJsKSkgOiB3ZWJzaXRlRG9tYWluO1xuICAgICAgcHVibGljIHJlYWRvbmx5IGJ1Y2tldFJlZ2lvbmFsRG9tYWluTmFtZSA9IGF0dHJzLmJ1Y2tldFJlZ2lvbmFsRG9tYWluTmFtZSB8fCBgJHtidWNrZXROYW1lfS5zMy4ke3JlZ2lvbn0uJHt1cmxTdWZmaXh9YDtcbiAgICAgIHB1YmxpYyByZWFkb25seSBidWNrZXREdWFsU3RhY2tEb21haW5OYW1lID0gYXR0cnMuYnVja2V0RHVhbFN0YWNrRG9tYWluTmFtZSB8fCBgJHtidWNrZXROYW1lfS5zMy5kdWFsc3RhY2suJHtyZWdpb259LiR7dXJsU3VmZml4fWA7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgYnVja2V0V2Vic2l0ZU5ld1VybEZvcm1hdCA9IG5ld1VybEZvcm1hdDtcbiAgICAgIHB1YmxpYyByZWFkb25seSBlbmNyeXB0aW9uS2V5ID0gYXR0cnMuZW5jcnlwdGlvbktleTtcbiAgICAgIHB1YmxpYyByZWFkb25seSBpc1dlYnNpdGUgPSBhdHRycy5pc1dlYnNpdGUgPz8gZmFsc2U7XG4gICAgICBwdWJsaWMgcG9saWN5PzogQnVja2V0UG9saWN5ID0gdW5kZWZpbmVkO1xuICAgICAgcHJvdGVjdGVkIGF1dG9DcmVhdGVQb2xpY3kgPSBmYWxzZTtcbiAgICAgIHByb3RlY3RlZCBkaXNhbGxvd1B1YmxpY0FjY2VzcyA9IGZhbHNlO1xuICAgICAgcHJvdGVjdGVkIG5vdGlmaWNhdGlvbnNIYW5kbGVyUm9sZSA9IGF0dHJzLm5vdGlmaWNhdGlvbnNIYW5kbGVyUm9sZTtcblxuICAgICAgLyoqXG4gICAgICAgKiBFeHBvcnRzIHRoaXMgYnVja2V0IGZyb20gdGhlIHN0YWNrLlxuICAgICAgICovXG4gICAgICBwdWJsaWMgZXhwb3J0KCkge1xuICAgICAgICByZXR1cm4gYXR0cnM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoc2NvcGUsIGlkLCB7XG4gICAgICBhY2NvdW50OiBhdHRycy5hY2NvdW50LFxuICAgICAgcmVnaW9uOiBhdHRycy5yZWdpb24sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVGhyb3duIGFuIGV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gYnVja2V0IG5hbWUgaXMgbm90IHZhbGlkLlxuICAgKlxuICAgKiBAcGFyYW0gcGh5c2ljYWxOYW1lIG5hbWUgb2YgdGhlIGJ1Y2tldC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgdmFsaWRhdGVCdWNrZXROYW1lKHBoeXNpY2FsTmFtZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgYnVja2V0TmFtZSA9IHBoeXNpY2FsTmFtZTtcbiAgICBpZiAoIWJ1Y2tldE5hbWUgfHwgVG9rZW4uaXNVbnJlc29sdmVkKGJ1Y2tldE5hbWUpKSB7XG4gICAgICAvLyB0aGUgbmFtZSBpcyBhIGxhdGUtYm91bmQgdmFsdWUsIG5vdCBhIGRlZmluZWQgc3RyaW5nLFxuICAgICAgLy8gc28gc2tpcCB2YWxpZGF0aW9uXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gUnVsZXMgY29kaWZpZWQgZnJvbSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uUzMvbGF0ZXN0L2Rldi9CdWNrZXRSZXN0cmljdGlvbnMuaHRtbFxuICAgIGlmIChidWNrZXROYW1lLmxlbmd0aCA8IDMgfHwgYnVja2V0TmFtZS5sZW5ndGggPiA2Mykge1xuICAgICAgZXJyb3JzLnB1c2goJ0J1Y2tldCBuYW1lIG11c3QgYmUgYXQgbGVhc3QgMyBhbmQgbm8gbW9yZSB0aGFuIDYzIGNoYXJhY3RlcnMnKTtcbiAgICB9XG4gICAgY29uc3QgY2hhcnNldE1hdGNoID0gYnVja2V0TmFtZS5tYXRjaCgvW15hLXowLTkuLV0vKTtcbiAgICBpZiAoY2hhcnNldE1hdGNoKSB7XG4gICAgICBlcnJvcnMucHVzaCgnQnVja2V0IG5hbWUgbXVzdCBvbmx5IGNvbnRhaW4gbG93ZXJjYXNlIGNoYXJhY3RlcnMgYW5kIHRoZSBzeW1ib2xzLCBwZXJpb2QgKC4pIGFuZCBkYXNoICgtKSAnXG4gICAgICAgICsgYChvZmZzZXQ6ICR7Y2hhcnNldE1hdGNoLmluZGV4fSlgKTtcbiAgICB9XG4gICAgaWYgKCEvW2EtejAtOV0vLnRlc3QoYnVja2V0TmFtZS5jaGFyQXQoMCkpKSB7XG4gICAgICBlcnJvcnMucHVzaCgnQnVja2V0IG5hbWUgbXVzdCBzdGFydCBhbmQgZW5kIHdpdGggYSBsb3dlcmNhc2UgY2hhcmFjdGVyIG9yIG51bWJlciAnXG4gICAgICAgICsgJyhvZmZzZXQ6IDApJyk7XG4gICAgfVxuICAgIGlmICghL1thLXowLTldLy50ZXN0KGJ1Y2tldE5hbWUuY2hhckF0KGJ1Y2tldE5hbWUubGVuZ3RoIC0gMSkpKSB7XG4gICAgICBlcnJvcnMucHVzaCgnQnVja2V0IG5hbWUgbXVzdCBzdGFydCBhbmQgZW5kIHdpdGggYSBsb3dlcmNhc2UgY2hhcmFjdGVyIG9yIG51bWJlciAnXG4gICAgICAgICsgYChvZmZzZXQ6ICR7YnVja2V0TmFtZS5sZW5ndGggLSAxfSlgKTtcbiAgICB9XG4gICAgY29uc3QgY29uc2VjU3ltYm9sTWF0Y2ggPSBidWNrZXROYW1lLm1hdGNoKC9cXC4tfC1cXC58XFwuXFwuLyk7XG4gICAgaWYgKGNvbnNlY1N5bWJvbE1hdGNoKSB7XG4gICAgICBlcnJvcnMucHVzaCgnQnVja2V0IG5hbWUgbXVzdCBub3QgaGF2ZSBkYXNoIG5leHQgdG8gcGVyaW9kLCBvciBwZXJpb2QgbmV4dCB0byBkYXNoLCBvciBjb25zZWN1dGl2ZSBwZXJpb2RzICdcbiAgICAgICAgKyBgKG9mZnNldDogJHtjb25zZWNTeW1ib2xNYXRjaC5pbmRleH0pYCk7XG4gICAgfVxuICAgIGlmICgvXlxcZHsxLDN9XFwuXFxkezEsM31cXC5cXGR7MSwzfVxcLlxcZHsxLDN9JC8udGVzdChidWNrZXROYW1lKSkge1xuICAgICAgZXJyb3JzLnB1c2goJ0J1Y2tldCBuYW1lIG11c3Qgbm90IHJlc2VtYmxlIGFuIElQIGFkZHJlc3MnKTtcbiAgICB9XG5cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBTMyBidWNrZXQgbmFtZSAodmFsdWU6ICR7YnVja2V0TmFtZX0pJHtFT0x9JHtlcnJvcnMuam9pbihFT0wpfWApO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyByZWFkb25seSBidWNrZXRBcm46IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGJ1Y2tldE5hbWU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGJ1Y2tldERvbWFpbk5hbWU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGJ1Y2tldFdlYnNpdGVVcmw6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGJ1Y2tldFdlYnNpdGVEb21haW5OYW1lOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBidWNrZXREdWFsU3RhY2tEb21haW5OYW1lOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBidWNrZXRSZWdpb25hbERvbWFpbk5hbWU6IHN0cmluZztcblxuICBwdWJsaWMgcmVhZG9ubHkgZW5jcnlwdGlvbktleT86IGttcy5JS2V5O1xuICBwdWJsaWMgcmVhZG9ubHkgaXNXZWJzaXRlPzogYm9vbGVhbjtcbiAgcHVibGljIHBvbGljeT86IEJ1Y2tldFBvbGljeTtcbiAgcHJvdGVjdGVkIGF1dG9DcmVhdGVQb2xpY3kgPSB0cnVlO1xuICBwcm90ZWN0ZWQgZGlzYWxsb3dQdWJsaWNBY2Nlc3M/OiBib29sZWFuO1xuICBwcml2YXRlIGFjY2Vzc0NvbnRyb2w/OiBCdWNrZXRBY2Nlc3NDb250cm9sO1xuICBwcml2YXRlIHJlYWRvbmx5IGxpZmVjeWNsZVJ1bGVzOiBMaWZlY3ljbGVSdWxlW10gPSBbXTtcbiAgcHJpdmF0ZSByZWFkb25seSB2ZXJzaW9uZWQ/OiBib29sZWFuO1xuICBwcml2YXRlIHJlYWRvbmx5IGV2ZW50QnJpZGdlRW5hYmxlZD86IGJvb2xlYW47XG4gIHByaXZhdGUgcmVhZG9ubHkgbWV0cmljczogQnVja2V0TWV0cmljc1tdID0gW107XG4gIHByaXZhdGUgcmVhZG9ubHkgY29yczogQ29yc1J1bGVbXSA9IFtdO1xuICBwcml2YXRlIHJlYWRvbmx5IGludmVudG9yaWVzOiBJbnZlbnRvcnlbXSA9IFtdO1xuICBwcml2YXRlIHJlYWRvbmx5IF9yZXNvdXJjZTogQ2ZuQnVja2V0O1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBCdWNrZXRQcm9wcyA9IHt9KSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBwaHlzaWNhbE5hbWU6IHByb3BzLmJ1Y2tldE5hbWUsXG4gICAgfSk7XG5cbiAgICB0aGlzLm5vdGlmaWNhdGlvbnNIYW5kbGVyUm9sZSA9IHByb3BzLm5vdGlmaWNhdGlvbnNIYW5kbGVyUm9sZTtcblxuICAgIGNvbnN0IHsgYnVja2V0RW5jcnlwdGlvbiwgZW5jcnlwdGlvbktleSB9ID0gdGhpcy5wYXJzZUVuY3J5cHRpb24ocHJvcHMpO1xuXG4gICAgQnVja2V0LnZhbGlkYXRlQnVja2V0TmFtZSh0aGlzLnBoeXNpY2FsTmFtZSk7XG5cbiAgICBjb25zdCB3ZWJzaXRlQ29uZmlndXJhdGlvbiA9IHRoaXMucmVuZGVyV2Vic2l0ZUNvbmZpZ3VyYXRpb24ocHJvcHMpO1xuICAgIHRoaXMuaXNXZWJzaXRlID0gKHdlYnNpdGVDb25maWd1cmF0aW9uICE9PSB1bmRlZmluZWQpO1xuXG4gICAgY29uc3QgcmVzb3VyY2UgPSBuZXcgQ2ZuQnVja2V0KHRoaXMsICdSZXNvdXJjZScsIHtcbiAgICAgIGJ1Y2tldE5hbWU6IHRoaXMucGh5c2ljYWxOYW1lLFxuICAgICAgYnVja2V0RW5jcnlwdGlvbixcbiAgICAgIHZlcnNpb25pbmdDb25maWd1cmF0aW9uOiBwcm9wcy52ZXJzaW9uZWQgPyB7IHN0YXR1czogJ0VuYWJsZWQnIH0gOiB1bmRlZmluZWQsXG4gICAgICBsaWZlY3ljbGVDb25maWd1cmF0aW9uOiBMYXp5LmFueSh7IHByb2R1Y2U6ICgpID0+IHRoaXMucGFyc2VMaWZlY3ljbGVDb25maWd1cmF0aW9uKCkgfSksXG4gICAgICB3ZWJzaXRlQ29uZmlndXJhdGlvbixcbiAgICAgIHB1YmxpY0FjY2Vzc0Jsb2NrQ29uZmlndXJhdGlvbjogcHJvcHMuYmxvY2tQdWJsaWNBY2Nlc3MsXG4gICAgICBtZXRyaWNzQ29uZmlndXJhdGlvbnM6IExhenkuYW55KHsgcHJvZHVjZTogKCkgPT4gdGhpcy5wYXJzZU1ldHJpY0NvbmZpZ3VyYXRpb24oKSB9KSxcbiAgICAgIGNvcnNDb25maWd1cmF0aW9uOiBMYXp5LmFueSh7IHByb2R1Y2U6ICgpID0+IHRoaXMucGFyc2VDb3JzQ29uZmlndXJhdGlvbigpIH0pLFxuICAgICAgYWNjZXNzQ29udHJvbDogTGF6eS5zdHJpbmcoeyBwcm9kdWNlOiAoKSA9PiB0aGlzLmFjY2Vzc0NvbnRyb2wgfSksXG4gICAgICBsb2dnaW5nQ29uZmlndXJhdGlvbjogdGhpcy5wYXJzZVNlcnZlckFjY2Vzc0xvZ3MocHJvcHMpLFxuICAgICAgaW52ZW50b3J5Q29uZmlndXJhdGlvbnM6IExhenkuYW55KHsgcHJvZHVjZTogKCkgPT4gdGhpcy5wYXJzZUludmVudG9yeUNvbmZpZ3VyYXRpb24oKSB9KSxcbiAgICAgIG93bmVyc2hpcENvbnRyb2xzOiB0aGlzLnBhcnNlT3duZXJzaGlwQ29udHJvbHMocHJvcHMpLFxuICAgICAgYWNjZWxlcmF0ZUNvbmZpZ3VyYXRpb246IHByb3BzLnRyYW5zZmVyQWNjZWxlcmF0aW9uID8geyBhY2NlbGVyYXRpb25TdGF0dXM6ICdFbmFibGVkJyB9IDogdW5kZWZpbmVkLFxuICAgICAgaW50ZWxsaWdlbnRUaWVyaW5nQ29uZmlndXJhdGlvbnM6IHRoaXMucGFyc2VUaWVyaW5nQ29uZmlnKHByb3BzKSxcbiAgICB9KTtcbiAgICB0aGlzLl9yZXNvdXJjZSA9IHJlc291cmNlO1xuXG4gICAgcmVzb3VyY2UuYXBwbHlSZW1vdmFsUG9saWN5KHByb3BzLnJlbW92YWxQb2xpY3kpO1xuXG4gICAgdGhpcy52ZXJzaW9uZWQgPSBwcm9wcy52ZXJzaW9uZWQ7XG4gICAgdGhpcy5lbmNyeXB0aW9uS2V5ID0gZW5jcnlwdGlvbktleTtcbiAgICB0aGlzLmV2ZW50QnJpZGdlRW5hYmxlZCA9IHByb3BzLmV2ZW50QnJpZGdlRW5hYmxlZDtcblxuICAgIHRoaXMuYnVja2V0TmFtZSA9IHRoaXMuZ2V0UmVzb3VyY2VOYW1lQXR0cmlidXRlKHJlc291cmNlLnJlZik7XG4gICAgdGhpcy5idWNrZXRBcm4gPSB0aGlzLmdldFJlc291cmNlQXJuQXR0cmlidXRlKHJlc291cmNlLmF0dHJBcm4sIHtcbiAgICAgIHJlZ2lvbjogJycsXG4gICAgICBhY2NvdW50OiAnJyxcbiAgICAgIHNlcnZpY2U6ICdzMycsXG4gICAgICByZXNvdXJjZTogdGhpcy5waHlzaWNhbE5hbWUsXG4gICAgfSk7XG5cbiAgICB0aGlzLmJ1Y2tldERvbWFpbk5hbWUgPSByZXNvdXJjZS5hdHRyRG9tYWluTmFtZTtcbiAgICB0aGlzLmJ1Y2tldFdlYnNpdGVVcmwgPSByZXNvdXJjZS5hdHRyV2Vic2l0ZVVybDtcbiAgICB0aGlzLmJ1Y2tldFdlYnNpdGVEb21haW5OYW1lID0gRm4uc2VsZWN0KDIsIEZuLnNwbGl0KCcvJywgdGhpcy5idWNrZXRXZWJzaXRlVXJsKSk7XG4gICAgdGhpcy5idWNrZXREdWFsU3RhY2tEb21haW5OYW1lID0gcmVzb3VyY2UuYXR0ckR1YWxTdGFja0RvbWFpbk5hbWU7XG4gICAgdGhpcy5idWNrZXRSZWdpb25hbERvbWFpbk5hbWUgPSByZXNvdXJjZS5hdHRyUmVnaW9uYWxEb21haW5OYW1lO1xuXG4gICAgdGhpcy5kaXNhbGxvd1B1YmxpY0FjY2VzcyA9IHByb3BzLmJsb2NrUHVibGljQWNjZXNzICYmIHByb3BzLmJsb2NrUHVibGljQWNjZXNzLmJsb2NrUHVibGljUG9saWN5O1xuICAgIHRoaXMuYWNjZXNzQ29udHJvbCA9IHByb3BzLmFjY2Vzc0NvbnRyb2w7XG5cbiAgICAvLyBFbmZvcmNlIEFXUyBGb3VuZGF0aW9uYWwgU2VjdXJpdHkgQmVzdCBQcmFjdGljZVxuICAgIGlmIChwcm9wcy5lbmZvcmNlU1NMKSB7XG4gICAgICB0aGlzLmVuZm9yY2VTU0xTdGF0ZW1lbnQoKTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuc2VydmVyQWNjZXNzTG9nc0J1Y2tldCBpbnN0YW5jZW9mIEJ1Y2tldCkge1xuICAgICAgcHJvcHMuc2VydmVyQWNjZXNzTG9nc0J1Y2tldC5hbGxvd0xvZ0RlbGl2ZXJ5KCk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBpbnZlbnRvcnkgb2YgcHJvcHMuaW52ZW50b3JpZXMgPz8gW10pIHtcbiAgICAgIHRoaXMuYWRkSW52ZW50b3J5KGludmVudG9yeSk7XG4gICAgfVxuXG4gICAgLy8gQWRkIGFsbCBidWNrZXQgbWV0cmljIGNvbmZpZ3VyYXRpb25zIHJ1bGVzXG4gICAgKHByb3BzLm1ldHJpY3MgfHwgW10pLmZvckVhY2godGhpcy5hZGRNZXRyaWMuYmluZCh0aGlzKSk7XG4gICAgLy8gQWRkIGFsbCBjb3JzIGNvbmZpZ3VyYXRpb24gcnVsZXNcbiAgICAocHJvcHMuY29ycyB8fCBbXSkuZm9yRWFjaCh0aGlzLmFkZENvcnNSdWxlLmJpbmQodGhpcykpO1xuXG4gICAgLy8gQWRkIGFsbCBsaWZlY3ljbGUgcnVsZXNcbiAgICAocHJvcHMubGlmZWN5Y2xlUnVsZXMgfHwgW10pLmZvckVhY2godGhpcy5hZGRMaWZlY3ljbGVSdWxlLmJpbmQodGhpcykpO1xuXG4gICAgaWYgKHByb3BzLnB1YmxpY1JlYWRBY2Nlc3MpIHtcbiAgICAgIHRoaXMuZ3JhbnRQdWJsaWNBY2Nlc3MoKTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuYXV0b0RlbGV0ZU9iamVjdHMpIHtcbiAgICAgIGlmIChwcm9wcy5yZW1vdmFsUG9saWN5ICE9PSBSZW1vdmFsUG9saWN5LkRFU1RST1kpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgdXNlIFxcJ2F1dG9EZWxldGVPYmplY3RzXFwnIHByb3BlcnR5IG9uIGEgYnVja2V0IHdpdGhvdXQgc2V0dGluZyByZW1vdmFsIHBvbGljeSB0byBcXCdERVNUUk9ZXFwnLicpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmVuYWJsZUF1dG9EZWxldGVPYmplY3RzKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZXZlbnRCcmlkZ2VFbmFibGVkKSB7XG4gICAgICB0aGlzLmVuYWJsZUV2ZW50QnJpZGdlTm90aWZpY2F0aW9uKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIGxpZmVjeWNsZSBydWxlIHRvIHRoZSBidWNrZXRcbiAgICpcbiAgICogQHBhcmFtIHJ1bGUgVGhlIHJ1bGUgdG8gYWRkXG4gICAqL1xuICBwdWJsaWMgYWRkTGlmZWN5Y2xlUnVsZShydWxlOiBMaWZlY3ljbGVSdWxlKSB7XG4gICAgaWYgKChydWxlLm5vbmN1cnJlbnRWZXJzaW9uRXhwaXJhdGlvbiAhPT0gdW5kZWZpbmVkXG4gICAgICB8fCAocnVsZS5ub25jdXJyZW50VmVyc2lvblRyYW5zaXRpb25zICYmIHJ1bGUubm9uY3VycmVudFZlcnNpb25UcmFuc2l0aW9ucy5sZW5ndGggPiAwKSlcbiAgICAgICYmICF0aGlzLnZlcnNpb25lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IHVzZSAnbm9uY3VycmVudCcgcnVsZXMgb24gYSBub252ZXJzaW9uZWQgYnVja2V0XCIpO1xuICAgIH1cblxuICAgIHRoaXMubGlmZWN5Y2xlUnVsZXMucHVzaChydWxlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgbWV0cmljcyBjb25maWd1cmF0aW9uIGZvciB0aGUgQ2xvdWRXYXRjaCByZXF1ZXN0IG1ldHJpY3MgZnJvbSB0aGUgYnVja2V0LlxuICAgKlxuICAgKiBAcGFyYW0gbWV0cmljIFRoZSBtZXRyaWMgY29uZmlndXJhdGlvbiB0byBhZGRcbiAgICovXG4gIHB1YmxpYyBhZGRNZXRyaWMobWV0cmljOiBCdWNrZXRNZXRyaWNzKSB7XG4gICAgdGhpcy5tZXRyaWNzLnB1c2gobWV0cmljKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgY3Jvc3Mtb3JpZ2luIGFjY2VzcyBjb25maWd1cmF0aW9uIGZvciBvYmplY3RzIGluIGFuIEFtYXpvbiBTMyBidWNrZXRcbiAgICpcbiAgICogQHBhcmFtIHJ1bGUgVGhlIENPUlMgY29uZmlndXJhdGlvbiBydWxlIHRvIGFkZFxuICAgKi9cbiAgcHVibGljIGFkZENvcnNSdWxlKHJ1bGU6IENvcnNSdWxlKSB7XG4gICAgdGhpcy5jb3JzLnB1c2gocnVsZSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGFuIGludmVudG9yeSBjb25maWd1cmF0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gaW52ZW50b3J5IGNvbmZpZ3VyYXRpb24gdG8gYWRkXG4gICAqL1xuICBwdWJsaWMgYWRkSW52ZW50b3J5KGludmVudG9yeTogSW52ZW50b3J5KTogdm9pZCB7XG4gICAgdGhpcy5pbnZlbnRvcmllcy5wdXNoKGludmVudG9yeSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhbiBpYW0gc3RhdGVtZW50IHRvIGVuZm9yY2UgU1NMIHJlcXVlc3RzIG9ubHkuXG4gICAqL1xuICBwcml2YXRlIGVuZm9yY2VTU0xTdGF0ZW1lbnQoKSB7XG4gICAgY29uc3Qgc3RhdGVtZW50ID0gbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgYWN0aW9uczogWydzMzoqJ10sXG4gICAgICBjb25kaXRpb25zOiB7XG4gICAgICAgIEJvb2w6IHsgJ2F3czpTZWN1cmVUcmFuc3BvcnQnOiAnZmFsc2UnIH0sXG4gICAgICB9LFxuICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkRFTlksXG4gICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAgdGhpcy5idWNrZXRBcm4sXG4gICAgICAgIHRoaXMuYXJuRm9yT2JqZWN0cygnKicpLFxuICAgICAgXSxcbiAgICAgIHByaW5jaXBhbHM6IFtuZXcgaWFtLkFueVByaW5jaXBhbCgpXSxcbiAgICB9KTtcbiAgICB0aGlzLmFkZFRvUmVzb3VyY2VQb2xpY3koc3RhdGVtZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdXAga2V5IHByb3BlcnRpZXMgYW5kIHJldHVybiB0aGUgQnVja2V0IGVuY3J5cHRpb24gcHJvcGVydHkgZnJvbSB0aGVcbiAgICogdXNlcidzIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBwcml2YXRlIHBhcnNlRW5jcnlwdGlvbihwcm9wczogQnVja2V0UHJvcHMpOiB7XG4gICAgYnVja2V0RW5jcnlwdGlvbj86IENmbkJ1Y2tldC5CdWNrZXRFbmNyeXB0aW9uUHJvcGVydHksXG4gICAgZW5jcnlwdGlvbktleT86IGttcy5JS2V5XG4gIH0ge1xuXG4gICAgLy8gZGVmYXVsdCBiYXNlZCBvbiB3aGV0aGVyIGVuY3J5cHRpb25LZXkgaXMgc3BlY2lmaWVkXG4gICAgbGV0IGVuY3J5cHRpb25UeXBlID0gcHJvcHMuZW5jcnlwdGlvbjtcbiAgICBpZiAoZW5jcnlwdGlvblR5cGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgZW5jcnlwdGlvblR5cGUgPSBwcm9wcy5lbmNyeXB0aW9uS2V5ID8gQnVja2V0RW5jcnlwdGlvbi5LTVMgOiBCdWNrZXRFbmNyeXB0aW9uLlVORU5DUllQVEVEO1xuICAgIH1cblxuICAgIC8vIGlmIGVuY3J5cHRpb24ga2V5IGlzIHNldCwgZW5jcnlwdGlvbiBtdXN0IGJlIHNldCB0byBLTVMuXG4gICAgaWYgKGVuY3J5cHRpb25UeXBlICE9PSBCdWNrZXRFbmNyeXB0aW9uLktNUyAmJiBwcm9wcy5lbmNyeXB0aW9uS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGVuY3J5cHRpb25LZXkgaXMgc3BlY2lmaWVkLCBzbyAnZW5jcnlwdGlvbicgbXVzdCBiZSBzZXQgdG8gS01TICh2YWx1ZTogJHtlbmNyeXB0aW9uVHlwZX0pYCk7XG4gICAgfVxuXG4gICAgLy8gaWYgYnVja2V0S2V5RW5hYmxlZCBpcyBzZXQsIGVuY3J5cHRpb24gbXVzdCBiZSBzZXQgdG8gS01TLlxuICAgIGlmIChwcm9wcy5idWNrZXRLZXlFbmFibGVkICYmIGVuY3J5cHRpb25UeXBlICE9PSBCdWNrZXRFbmNyeXB0aW9uLktNUykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBidWNrZXRLZXlFbmFibGVkIGlzIHNwZWNpZmllZCwgc28gJ2VuY3J5cHRpb24nIG11c3QgYmUgc2V0IHRvIEtNUyAodmFsdWU6ICR7ZW5jcnlwdGlvblR5cGV9KWApO1xuICAgIH1cblxuICAgIGlmIChlbmNyeXB0aW9uVHlwZSA9PT0gQnVja2V0RW5jcnlwdGlvbi5VTkVOQ1JZUFRFRCkge1xuICAgICAgcmV0dXJuIHsgYnVja2V0RW5jcnlwdGlvbjogdW5kZWZpbmVkLCBlbmNyeXB0aW9uS2V5OiB1bmRlZmluZWQgfTtcbiAgICB9XG5cbiAgICBpZiAoZW5jcnlwdGlvblR5cGUgPT09IEJ1Y2tldEVuY3J5cHRpb24uS01TKSB7XG4gICAgICBjb25zdCBlbmNyeXB0aW9uS2V5ID0gcHJvcHMuZW5jcnlwdGlvbktleSB8fCBuZXcga21zLktleSh0aGlzLCAnS2V5Jywge1xuICAgICAgICBkZXNjcmlwdGlvbjogYENyZWF0ZWQgYnkgJHt0aGlzLm5vZGUucGF0aH1gLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGJ1Y2tldEVuY3J5cHRpb24gPSB7XG4gICAgICAgIHNlcnZlclNpZGVFbmNyeXB0aW9uQ29uZmlndXJhdGlvbjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGJ1Y2tldEtleUVuYWJsZWQ6IHByb3BzLmJ1Y2tldEtleUVuYWJsZWQsXG4gICAgICAgICAgICBzZXJ2ZXJTaWRlRW5jcnlwdGlvbkJ5RGVmYXVsdDoge1xuICAgICAgICAgICAgICBzc2VBbGdvcml0aG06ICdhd3M6a21zJyxcbiAgICAgICAgICAgICAga21zTWFzdGVyS2V5SWQ6IGVuY3J5cHRpb25LZXkua2V5QXJuLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICAgIHJldHVybiB7IGVuY3J5cHRpb25LZXksIGJ1Y2tldEVuY3J5cHRpb24gfTtcbiAgICB9XG5cbiAgICBpZiAoZW5jcnlwdGlvblR5cGUgPT09IEJ1Y2tldEVuY3J5cHRpb24uUzNfTUFOQUdFRCkge1xuICAgICAgY29uc3QgYnVja2V0RW5jcnlwdGlvbiA9IHtcbiAgICAgICAgc2VydmVyU2lkZUVuY3J5cHRpb25Db25maWd1cmF0aW9uOiBbXG4gICAgICAgICAgeyBzZXJ2ZXJTaWRlRW5jcnlwdGlvbkJ5RGVmYXVsdDogeyBzc2VBbGdvcml0aG06ICdBRVMyNTYnIH0gfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiB7IGJ1Y2tldEVuY3J5cHRpb24gfTtcbiAgICB9XG5cbiAgICBpZiAoZW5jcnlwdGlvblR5cGUgPT09IEJ1Y2tldEVuY3J5cHRpb24uS01TX01BTkFHRUQpIHtcbiAgICAgIGNvbnN0IGJ1Y2tldEVuY3J5cHRpb24gPSB7XG4gICAgICAgIHNlcnZlclNpZGVFbmNyeXB0aW9uQ29uZmlndXJhdGlvbjogW1xuICAgICAgICAgIHsgc2VydmVyU2lkZUVuY3J5cHRpb25CeURlZmF1bHQ6IHsgc3NlQWxnb3JpdGhtOiAnYXdzOmttcycgfSB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICAgIHJldHVybiB7IGJ1Y2tldEVuY3J5cHRpb24gfTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgJ2VuY3J5cHRpb25UeXBlJzogJHtlbmNyeXB0aW9uVHlwZX1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZSB0aGUgbGlmZWN5Y2xlIGNvbmZpZ3VyYXRpb24gb3V0IG9mIHRoZSBidWNrZXQgcHJvcHNcbiAgICogQHBhcmFtIHByb3BzIFBhclxuICAgKi9cbiAgcHJpdmF0ZSBwYXJzZUxpZmVjeWNsZUNvbmZpZ3VyYXRpb24oKTogQ2ZuQnVja2V0LkxpZmVjeWNsZUNvbmZpZ3VyYXRpb25Qcm9wZXJ0eSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCF0aGlzLmxpZmVjeWNsZVJ1bGVzIHx8IHRoaXMubGlmZWN5Y2xlUnVsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgcmV0dXJuIHsgcnVsZXM6IHRoaXMubGlmZWN5Y2xlUnVsZXMubWFwKHBhcnNlTGlmZWN5Y2xlUnVsZSkgfTtcblxuICAgIGZ1bmN0aW9uIHBhcnNlTGlmZWN5Y2xlUnVsZShydWxlOiBMaWZlY3ljbGVSdWxlKTogQ2ZuQnVja2V0LlJ1bGVQcm9wZXJ0eSB7XG4gICAgICBjb25zdCBlbmFibGVkID0gcnVsZS5lbmFibGVkID8/IHRydWU7XG5cbiAgICAgIGNvbnN0IHg6IENmbkJ1Y2tldC5SdWxlUHJvcGVydHkgPSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICAgIGFib3J0SW5jb21wbGV0ZU11bHRpcGFydFVwbG9hZDogcnVsZS5hYm9ydEluY29tcGxldGVNdWx0aXBhcnRVcGxvYWRBZnRlciAhPT0gdW5kZWZpbmVkID8geyBkYXlzQWZ0ZXJJbml0aWF0aW9uOiBydWxlLmFib3J0SW5jb21wbGV0ZU11bHRpcGFydFVwbG9hZEFmdGVyLnRvRGF5cygpIH0gOiB1bmRlZmluZWQsXG4gICAgICAgIGV4cGlyYXRpb25EYXRlOiBydWxlLmV4cGlyYXRpb25EYXRlLFxuICAgICAgICBleHBpcmF0aW9uSW5EYXlzOiBydWxlLmV4cGlyYXRpb24/LnRvRGF5cygpLFxuICAgICAgICBpZDogcnVsZS5pZCxcbiAgICAgICAgbm9uY3VycmVudFZlcnNpb25FeHBpcmF0aW9uSW5EYXlzOiBydWxlLm5vbmN1cnJlbnRWZXJzaW9uRXhwaXJhdGlvbiAmJiBydWxlLm5vbmN1cnJlbnRWZXJzaW9uRXhwaXJhdGlvbi50b0RheXMoKSxcbiAgICAgICAgbm9uY3VycmVudFZlcnNpb25UcmFuc2l0aW9uczogbWFwT3JVbmRlZmluZWQocnVsZS5ub25jdXJyZW50VmVyc2lvblRyYW5zaXRpb25zLCB0ID0+ICh7XG4gICAgICAgICAgc3RvcmFnZUNsYXNzOiB0LnN0b3JhZ2VDbGFzcy52YWx1ZSxcbiAgICAgICAgICB0cmFuc2l0aW9uSW5EYXlzOiB0LnRyYW5zaXRpb25BZnRlci50b0RheXMoKSxcbiAgICAgICAgICBuZXdlck5vbmN1cnJlbnRWZXJzaW9uczogdC5ub25jdXJyZW50VmVyc2lvbnNUb1JldGFpbixcbiAgICAgICAgfSkpLFxuICAgICAgICBwcmVmaXg6IHJ1bGUucHJlZml4LFxuICAgICAgICBzdGF0dXM6IGVuYWJsZWQgPyAnRW5hYmxlZCcgOiAnRGlzYWJsZWQnLFxuICAgICAgICB0cmFuc2l0aW9uczogbWFwT3JVbmRlZmluZWQocnVsZS50cmFuc2l0aW9ucywgdCA9PiAoe1xuICAgICAgICAgIHN0b3JhZ2VDbGFzczogdC5zdG9yYWdlQ2xhc3MudmFsdWUsXG4gICAgICAgICAgdHJhbnNpdGlvbkRhdGU6IHQudHJhbnNpdGlvbkRhdGUsXG4gICAgICAgICAgdHJhbnNpdGlvbkluRGF5czogdC50cmFuc2l0aW9uQWZ0ZXIgJiYgdC50cmFuc2l0aW9uQWZ0ZXIudG9EYXlzKCksXG4gICAgICAgIH0pKSxcbiAgICAgICAgZXhwaXJlZE9iamVjdERlbGV0ZU1hcmtlcjogcnVsZS5leHBpcmVkT2JqZWN0RGVsZXRlTWFya2VyLFxuICAgICAgICB0YWdGaWx0ZXJzOiBzZWxmLnBhcnNlVGFnRmlsdGVycyhydWxlLnRhZ0ZpbHRlcnMpLFxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHg7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVNlcnZlckFjY2Vzc0xvZ3MocHJvcHM6IEJ1Y2tldFByb3BzKTogQ2ZuQnVja2V0LkxvZ2dpbmdDb25maWd1cmF0aW9uUHJvcGVydHkgfCB1bmRlZmluZWQge1xuICAgIGlmICghcHJvcHMuc2VydmVyQWNjZXNzTG9nc0J1Y2tldCAmJiAhcHJvcHMuc2VydmVyQWNjZXNzTG9nc1ByZWZpeCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGVzdGluYXRpb25CdWNrZXROYW1lOiBwcm9wcy5zZXJ2ZXJBY2Nlc3NMb2dzQnVja2V0Py5idWNrZXROYW1lLFxuICAgICAgbG9nRmlsZVByZWZpeDogcHJvcHMuc2VydmVyQWNjZXNzTG9nc1ByZWZpeCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZU1ldHJpY0NvbmZpZ3VyYXRpb24oKTogQ2ZuQnVja2V0Lk1ldHJpY3NDb25maWd1cmF0aW9uUHJvcGVydHlbXSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCF0aGlzLm1ldHJpY3MgfHwgdGhpcy5tZXRyaWNzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIHJldHVybiB0aGlzLm1ldHJpY3MubWFwKHBhcnNlTWV0cmljKTtcblxuICAgIGZ1bmN0aW9uIHBhcnNlTWV0cmljKG1ldHJpYzogQnVja2V0TWV0cmljcyk6IENmbkJ1Y2tldC5NZXRyaWNzQ29uZmlndXJhdGlvblByb3BlcnR5IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGlkOiBtZXRyaWMuaWQsXG4gICAgICAgIHByZWZpeDogbWV0cmljLnByZWZpeCxcbiAgICAgICAgdGFnRmlsdGVyczogc2VsZi5wYXJzZVRhZ0ZpbHRlcnMobWV0cmljLnRhZ0ZpbHRlcnMpLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHBhcnNlQ29yc0NvbmZpZ3VyYXRpb24oKTogQ2ZuQnVja2V0LkNvcnNDb25maWd1cmF0aW9uUHJvcGVydHkgfCB1bmRlZmluZWQge1xuICAgIGlmICghdGhpcy5jb3JzIHx8IHRoaXMuY29ycy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgY29yc1J1bGVzOiB0aGlzLmNvcnMubWFwKHBhcnNlQ29ycykgfTtcblxuICAgIGZ1bmN0aW9uIHBhcnNlQ29ycyhydWxlOiBDb3JzUnVsZSk6IENmbkJ1Y2tldC5Db3JzUnVsZVByb3BlcnR5IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGlkOiBydWxlLmlkLFxuICAgICAgICBtYXhBZ2U6IHJ1bGUubWF4QWdlLFxuICAgICAgICBhbGxvd2VkSGVhZGVyczogcnVsZS5hbGxvd2VkSGVhZGVycyxcbiAgICAgICAgYWxsb3dlZE1ldGhvZHM6IHJ1bGUuYWxsb3dlZE1ldGhvZHMsXG4gICAgICAgIGFsbG93ZWRPcmlnaW5zOiBydWxlLmFsbG93ZWRPcmlnaW5zLFxuICAgICAgICBleHBvc2VkSGVhZGVyczogcnVsZS5leHBvc2VkSGVhZGVycyxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVRhZ0ZpbHRlcnModGFnRmlsdGVycz86IHsgW3RhZzogc3RyaW5nXTogYW55IH0pIHtcbiAgICBpZiAoIXRhZ0ZpbHRlcnMgfHwgdGFnRmlsdGVycy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHRhZ0ZpbHRlcnMpLm1hcCh0YWcgPT4gKHtcbiAgICAgIGtleTogdGFnLFxuICAgICAgdmFsdWU6IHRhZ0ZpbHRlcnNbdGFnXSxcbiAgICB9KSk7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlT3duZXJzaGlwQ29udHJvbHMoeyBvYmplY3RPd25lcnNoaXAgfTogQnVja2V0UHJvcHMpOiBDZm5CdWNrZXQuT3duZXJzaGlwQ29udHJvbHNQcm9wZXJ0eSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCFvYmplY3RPd25lcnNoaXApIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBydWxlczogW3tcbiAgICAgICAgb2JqZWN0T3duZXJzaGlwLFxuICAgICAgfV0sXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VUaWVyaW5nQ29uZmlnKHsgaW50ZWxsaWdlbnRUaWVyaW5nQ29uZmlndXJhdGlvbnMgfTogQnVja2V0UHJvcHMpOiBDZm5CdWNrZXQuSW50ZWxsaWdlbnRUaWVyaW5nQ29uZmlndXJhdGlvblByb3BlcnR5W10gfCB1bmRlZmluZWQge1xuICAgIGlmICghaW50ZWxsaWdlbnRUaWVyaW5nQ29uZmlndXJhdGlvbnMpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGludGVsbGlnZW50VGllcmluZ0NvbmZpZ3VyYXRpb25zLm1hcChjb25maWcgPT4ge1xuICAgICAgY29uc3QgdGllcmluZ3MgPSBbXTtcbiAgICAgIGlmIChjb25maWcuYXJjaGl2ZUFjY2Vzc1RpZXJUaW1lKSB7XG4gICAgICAgIHRpZXJpbmdzLnB1c2goe1xuICAgICAgICAgIGFjY2Vzc1RpZXI6ICdBUkNISVZFX0FDQ0VTUycsXG4gICAgICAgICAgZGF5czogY29uZmlnLmFyY2hpdmVBY2Nlc3NUaWVyVGltZS50b0RheXMoeyBpbnRlZ3JhbDogdHJ1ZSB9KSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoY29uZmlnLmRlZXBBcmNoaXZlQWNjZXNzVGllclRpbWUpIHtcbiAgICAgICAgdGllcmluZ3MucHVzaCh7XG4gICAgICAgICAgYWNjZXNzVGllcjogJ0RFRVBfQVJDSElWRV9BQ0NFU1MnLFxuICAgICAgICAgIGRheXM6IGNvbmZpZy5kZWVwQXJjaGl2ZUFjY2Vzc1RpZXJUaW1lLnRvRGF5cyh7IGludGVncmFsOiB0cnVlIH0pLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGlkOiBjb25maWcubmFtZSxcbiAgICAgICAgcHJlZml4OiBjb25maWcucHJlZml4LFxuICAgICAgICBzdGF0dXM6ICdFbmFibGVkJyxcbiAgICAgICAgdGFnRmlsdGVyczogY29uZmlnLnRhZ3MsXG4gICAgICAgIHRpZXJpbmdzOiB0aWVyaW5ncyxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlbmRlcldlYnNpdGVDb25maWd1cmF0aW9uKHByb3BzOiBCdWNrZXRQcm9wcyk6IENmbkJ1Y2tldC5XZWJzaXRlQ29uZmlndXJhdGlvblByb3BlcnR5IHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIXByb3BzLndlYnNpdGVFcnJvckRvY3VtZW50ICYmICFwcm9wcy53ZWJzaXRlSW5kZXhEb2N1bWVudCAmJiAhcHJvcHMud2Vic2l0ZVJlZGlyZWN0ICYmICFwcm9wcy53ZWJzaXRlUm91dGluZ1J1bGVzKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmIChwcm9wcy53ZWJzaXRlRXJyb3JEb2N1bWVudCAmJiAhcHJvcHMud2Vic2l0ZUluZGV4RG9jdW1lbnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignXCJ3ZWJzaXRlSW5kZXhEb2N1bWVudFwiIGlzIHJlcXVpcmVkIGlmIFwid2Vic2l0ZUVycm9yRG9jdW1lbnRcIiBpcyBzZXQnKTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMud2Vic2l0ZVJlZGlyZWN0ICYmIChwcm9wcy53ZWJzaXRlRXJyb3JEb2N1bWVudCB8fCBwcm9wcy53ZWJzaXRlSW5kZXhEb2N1bWVudCB8fCBwcm9wcy53ZWJzaXRlUm91dGluZ1J1bGVzKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdcIndlYnNpdGVJbmRleERvY3VtZW50XCIsIFwid2Vic2l0ZUVycm9yRG9jdW1lbnRcIiBhbmQsIFwid2Vic2l0ZVJvdXRpbmdSdWxlc1wiIGNhbm5vdCBiZSBzZXQgaWYgXCJ3ZWJzaXRlUmVkaXJlY3RcIiBpcyB1c2VkJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgcm91dGluZ1J1bGVzID0gcHJvcHMud2Vic2l0ZVJvdXRpbmdSdWxlcyA/IHByb3BzLndlYnNpdGVSb3V0aW5nUnVsZXMubWFwPENmbkJ1Y2tldC5Sb3V0aW5nUnVsZVByb3BlcnR5PigocnVsZSkgPT4ge1xuICAgICAgaWYgKHJ1bGUuY29uZGl0aW9uICYmICFydWxlLmNvbmRpdGlvbi5odHRwRXJyb3JDb2RlUmV0dXJuZWRFcXVhbHMgJiYgIXJ1bGUuY29uZGl0aW9uLmtleVByZWZpeEVxdWFscykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjb25kaXRpb24gcHJvcGVydHkgY2Fubm90IGJlIGFuIGVtcHR5IG9iamVjdCcpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICByZWRpcmVjdFJ1bGU6IHtcbiAgICAgICAgICBob3N0TmFtZTogcnVsZS5ob3N0TmFtZSxcbiAgICAgICAgICBodHRwUmVkaXJlY3RDb2RlOiBydWxlLmh0dHBSZWRpcmVjdENvZGUsXG4gICAgICAgICAgcHJvdG9jb2w6IHJ1bGUucHJvdG9jb2wsXG4gICAgICAgICAgcmVwbGFjZUtleVdpdGg6IHJ1bGUucmVwbGFjZUtleSAmJiBydWxlLnJlcGxhY2VLZXkud2l0aEtleSxcbiAgICAgICAgICByZXBsYWNlS2V5UHJlZml4V2l0aDogcnVsZS5yZXBsYWNlS2V5ICYmIHJ1bGUucmVwbGFjZUtleS5wcmVmaXhXaXRoS2V5LFxuICAgICAgICB9LFxuICAgICAgICByb3V0aW5nUnVsZUNvbmRpdGlvbjogcnVsZS5jb25kaXRpb24sXG4gICAgICB9O1xuICAgIH0pIDogdW5kZWZpbmVkO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGluZGV4RG9jdW1lbnQ6IHByb3BzLndlYnNpdGVJbmRleERvY3VtZW50LFxuICAgICAgZXJyb3JEb2N1bWVudDogcHJvcHMud2Vic2l0ZUVycm9yRG9jdW1lbnQsXG4gICAgICByZWRpcmVjdEFsbFJlcXVlc3RzVG86IHByb3BzLndlYnNpdGVSZWRpcmVjdCxcbiAgICAgIHJvdXRpbmdSdWxlcyxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFsbG93cyB0aGUgTG9nRGVsaXZlcnkgZ3JvdXAgdG8gd3JpdGUsIGZhaWxzIGlmIEFDTCB3YXMgc2V0IGRpZmZlcmVudGx5LlxuICAgKlxuICAgKiBAc2VlXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25TMy9sYXRlc3QvZGV2L2FjbC1vdmVydmlldy5odG1sI2Nhbm5lZC1hY2xcbiAgICovXG4gIHByaXZhdGUgYWxsb3dMb2dEZWxpdmVyeSgpIHtcbiAgICBpZiAodGhpcy5hY2Nlc3NDb250cm9sICYmIHRoaXMuYWNjZXNzQ29udHJvbCAhPT0gQnVja2V0QWNjZXNzQ29udHJvbC5MT0dfREVMSVZFUllfV1JJVEUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBlbmFibGUgbG9nIGRlbGl2ZXJ5IHRvIHRoaXMgYnVja2V0IGJlY2F1c2UgdGhlIGJ1Y2tldCdzIEFDTCBoYXMgYmVlbiBzZXQgYW5kIGNhbid0IGJlIGNoYW5nZWRcIik7XG4gICAgfVxuXG4gICAgdGhpcy5hY2Nlc3NDb250cm9sID0gQnVja2V0QWNjZXNzQ29udHJvbC5MT0dfREVMSVZFUllfV1JJVEU7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlSW52ZW50b3J5Q29uZmlndXJhdGlvbigpOiBDZm5CdWNrZXQuSW52ZW50b3J5Q29uZmlndXJhdGlvblByb3BlcnR5W10gfCB1bmRlZmluZWQge1xuICAgIGlmICghdGhpcy5pbnZlbnRvcmllcyB8fCB0aGlzLmludmVudG9yaWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5pbnZlbnRvcmllcy5tYXAoKGludmVudG9yeSwgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IGZvcm1hdCA9IGludmVudG9yeS5mb3JtYXQgPz8gSW52ZW50b3J5Rm9ybWF0LkNTVjtcbiAgICAgIGNvbnN0IGZyZXF1ZW5jeSA9IGludmVudG9yeS5mcmVxdWVuY3kgPz8gSW52ZW50b3J5RnJlcXVlbmN5LldFRUtMWTtcbiAgICAgIGNvbnN0IGlkID0gaW52ZW50b3J5LmludmVudG9yeUlkID8/IGAke3RoaXMubm9kZS5pZH1JbnZlbnRvcnkke2luZGV4fWA7XG5cbiAgICAgIGlmIChpbnZlbnRvcnkuZGVzdGluYXRpb24uYnVja2V0IGluc3RhbmNlb2YgQnVja2V0KSB7XG4gICAgICAgIGludmVudG9yeS5kZXN0aW5hdGlvbi5idWNrZXQuYWRkVG9SZXNvdXJjZVBvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgICAgIGFjdGlvbnM6IFsnczM6UHV0T2JqZWN0J10sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgICAgICBpbnZlbnRvcnkuZGVzdGluYXRpb24uYnVja2V0LmJ1Y2tldEFybixcbiAgICAgICAgICAgIGludmVudG9yeS5kZXN0aW5hdGlvbi5idWNrZXQuYXJuRm9yT2JqZWN0cyhgJHtpbnZlbnRvcnkuZGVzdGluYXRpb24ucHJlZml4ID8/ICcnfSpgKSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHByaW5jaXBhbHM6IFtuZXcgaWFtLlNlcnZpY2VQcmluY2lwYWwoJ3MzLmFtYXpvbmF3cy5jb20nKV0sXG4gICAgICAgICAgY29uZGl0aW9uczoge1xuICAgICAgICAgICAgQXJuTGlrZToge1xuICAgICAgICAgICAgICAnYXdzOlNvdXJjZUFybic6IHRoaXMuYnVja2V0QXJuLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGlkLFxuICAgICAgICBkZXN0aW5hdGlvbjoge1xuICAgICAgICAgIGJ1Y2tldEFybjogaW52ZW50b3J5LmRlc3RpbmF0aW9uLmJ1Y2tldC5idWNrZXRBcm4sXG4gICAgICAgICAgYnVja2V0QWNjb3VudElkOiBpbnZlbnRvcnkuZGVzdGluYXRpb24uYnVja2V0T3duZXIsXG4gICAgICAgICAgcHJlZml4OiBpbnZlbnRvcnkuZGVzdGluYXRpb24ucHJlZml4LFxuICAgICAgICAgIGZvcm1hdCxcbiAgICAgICAgfSxcbiAgICAgICAgZW5hYmxlZDogaW52ZW50b3J5LmVuYWJsZWQgPz8gdHJ1ZSxcbiAgICAgICAgaW5jbHVkZWRPYmplY3RWZXJzaW9uczogaW52ZW50b3J5LmluY2x1ZGVPYmplY3RWZXJzaW9ucyA/PyBJbnZlbnRvcnlPYmplY3RWZXJzaW9uLkFMTCxcbiAgICAgICAgc2NoZWR1bGVGcmVxdWVuY3k6IGZyZXF1ZW5jeSxcbiAgICAgICAgb3B0aW9uYWxGaWVsZHM6IGludmVudG9yeS5vcHRpb25hbEZpZWxkcyxcbiAgICAgICAgcHJlZml4OiBpbnZlbnRvcnkub2JqZWN0c1ByZWZpeCxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGVuYWJsZUF1dG9EZWxldGVPYmplY3RzKCkge1xuICAgIGNvbnN0IHByb3ZpZGVyID0gQ3VzdG9tUmVzb3VyY2VQcm92aWRlci5nZXRPckNyZWF0ZVByb3ZpZGVyKHRoaXMsIEFVVE9fREVMRVRFX09CSkVDVFNfUkVTT1VSQ0VfVFlQRSwge1xuICAgICAgY29kZURpcmVjdG9yeTogcGF0aC5qb2luKF9fZGlybmFtZSwgJ2F1dG8tZGVsZXRlLW9iamVjdHMtaGFuZGxlcicpLFxuICAgICAgcnVudGltZTogQ3VzdG9tUmVzb3VyY2VQcm92aWRlclJ1bnRpbWUuTk9ERUpTXzEyX1gsXG4gICAgICBkZXNjcmlwdGlvbjogYExhbWJkYSBmdW5jdGlvbiBmb3IgYXV0by1kZWxldGluZyBvYmplY3RzIGluICR7dGhpcy5idWNrZXROYW1lfSBTMyBidWNrZXQuYCxcbiAgICB9KTtcblxuICAgIC8vIFVzZSBhIGJ1Y2tldCBwb2xpY3kgdG8gYWxsb3cgdGhlIGN1c3RvbSByZXNvdXJjZSB0byBkZWxldGVcbiAgICAvLyBvYmplY3RzIGluIHRoZSBidWNrZXRcbiAgICB0aGlzLmFkZFRvUmVzb3VyY2VQb2xpY3kobmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgYWN0aW9uczogW1xuICAgICAgICAvLyBsaXN0IG9iamVjdHNcbiAgICAgICAgLi4ucGVybXMuQlVDS0VUX1JFQURfTUVUQURBVEFfQUNUSU9OUyxcbiAgICAgICAgLi4ucGVybXMuQlVDS0VUX0RFTEVURV9BQ1RJT05TLCAvLyBhbmQgdGhlbiBkZWxldGUgdGhlbVxuICAgICAgXSxcbiAgICAgIHJlc291cmNlczogW1xuICAgICAgICB0aGlzLmJ1Y2tldEFybixcbiAgICAgICAgdGhpcy5hcm5Gb3JPYmplY3RzKCcqJyksXG4gICAgICBdLFxuICAgICAgcHJpbmNpcGFsczogW25ldyBpYW0uQXJuUHJpbmNpcGFsKHByb3ZpZGVyLnJvbGVBcm4pXSxcbiAgICB9KSk7XG5cbiAgICBjb25zdCBjdXN0b21SZXNvdXJjZSA9IG5ldyBDdXN0b21SZXNvdXJjZSh0aGlzLCAnQXV0b0RlbGV0ZU9iamVjdHNDdXN0b21SZXNvdXJjZScsIHtcbiAgICAgIHJlc291cmNlVHlwZTogQVVUT19ERUxFVEVfT0JKRUNUU19SRVNPVVJDRV9UWVBFLFxuICAgICAgc2VydmljZVRva2VuOiBwcm92aWRlci5zZXJ2aWNlVG9rZW4sXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIEJ1Y2tldE5hbWU6IHRoaXMuYnVja2V0TmFtZSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyBFbnN1cmUgYnVja2V0IHBvbGljeSBpcyBkZWxldGVkIEFGVEVSIHRoZSBjdXN0b20gcmVzb3VyY2Ugb3RoZXJ3aXNlXG4gICAgLy8gd2UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBsaXN0IGFuZCBkZWxldGUgaW4gdGhlIGJ1Y2tldC5cbiAgICAvLyAoYWRkIGEgYGlmYCB0byBtYWtlIFRTIGhhcHB5KVxuICAgIGlmICh0aGlzLnBvbGljeSkge1xuICAgICAgY3VzdG9tUmVzb3VyY2Uubm9kZS5hZGREZXBlbmRlbmN5KHRoaXMucG9saWN5KTtcbiAgICB9XG5cbiAgICAvLyBXZSBhbHNvIHRhZyB0aGUgYnVja2V0IHRvIHJlY29yZCB0aGUgZmFjdCB0aGF0IHdlIHdhbnQgaXQgYXV0b2RlbGV0ZWQuXG4gICAgLy8gVGhlIGN1c3RvbSByZXNvdXJjZSB3aWxsIGNoZWNrIHRoaXMgdGFnIGJlZm9yZSBhY3R1YWxseSBkb2luZyB0aGUgZGVsZXRlLlxuICAgIC8vIEJlY2F1c2UgdGFnZ2luZyBhbmQgdW50YWdnaW5nIHdpbGwgQUxXQVlTIGhhcHBlbiBiZWZvcmUgdGhlIENSIGlzIGRlbGV0ZWQsXG4gICAgLy8gd2UgY2FuIHNldCBgYXV0b0RlbGV0ZU9iamVjdHM6IGZhbHNlYCB3aXRob3V0IHRoZSByZW1vdmFsIG9mIHRoZSBDUiBlbXB0eWluZ1xuICAgIC8vIHRoZSBidWNrZXQgYXMgYSBzaWRlIGVmZmVjdC5cbiAgICBUYWdzLm9mKHRoaXMuX3Jlc291cmNlKS5hZGQoQVVUT19ERUxFVEVfT0JKRUNUU19UQUcsICd0cnVlJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBXaGF0IGtpbmQgb2Ygc2VydmVyLXNpZGUgZW5jcnlwdGlvbiB0byBhcHBseSB0byB0aGlzIGJ1Y2tldFxuICovXG5leHBvcnQgZW51bSBCdWNrZXRFbmNyeXB0aW9uIHtcbiAgLyoqXG4gICAqIE9iamVjdHMgaW4gdGhlIGJ1Y2tldCBhcmUgbm90IGVuY3J5cHRlZC5cbiAgICovXG4gIFVORU5DUllQVEVEID0gJ05PTkUnLFxuXG4gIC8qKlxuICAgKiBTZXJ2ZXItc2lkZSBLTVMgZW5jcnlwdGlvbiB3aXRoIGEgbWFzdGVyIGtleSBtYW5hZ2VkIGJ5IEtNUy5cbiAgICovXG4gIEtNU19NQU5BR0VEID0gJ01BTkFHRUQnLFxuXG4gIC8qKlxuICAgKiBTZXJ2ZXItc2lkZSBlbmNyeXB0aW9uIHdpdGggYSBtYXN0ZXIga2V5IG1hbmFnZWQgYnkgUzMuXG4gICAqL1xuICBTM19NQU5BR0VEID0gJ1MzTUFOQUdFRCcsXG5cbiAgLyoqXG4gICAqIFNlcnZlci1zaWRlIGVuY3J5cHRpb24gd2l0aCBhIEtNUyBrZXkgbWFuYWdlZCBieSB0aGUgdXNlci5cbiAgICogSWYgYGVuY3J5cHRpb25LZXlgIGlzIHNwZWNpZmllZCwgdGhpcyBrZXkgd2lsbCBiZSB1c2VkLCBvdGhlcndpc2UsIG9uZSB3aWxsIGJlIGRlZmluZWQuXG4gICAqL1xuICBLTVMgPSAnS01TJyxcbn1cblxuLyoqXG4gKiBOb3RpZmljYXRpb24gZXZlbnQgdHlwZXMuXG4gKiBAbGluayBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uUzMvbGF0ZXN0L3VzZXJndWlkZS9ub3RpZmljYXRpb24taG93LXRvLWV2ZW50LXR5cGVzLWFuZC1kZXN0aW5hdGlvbnMuaHRtbCNzdXBwb3J0ZWQtbm90aWZpY2F0aW9uLWV2ZW50LXR5cGVzXG4gKi9cbmV4cG9ydCBlbnVtIEV2ZW50VHlwZSB7XG4gIC8qKlxuICAgKiBBbWF6b24gUzMgQVBJcyBzdWNoIGFzIFBVVCwgUE9TVCwgYW5kIENPUFkgY2FuIGNyZWF0ZSBhbiBvYmplY3QuIFVzaW5nXG4gICAqIHRoZXNlIGV2ZW50IHR5cGVzLCB5b3UgY2FuIGVuYWJsZSBub3RpZmljYXRpb24gd2hlbiBhbiBvYmplY3QgaXMgY3JlYXRlZFxuICAgKiB1c2luZyBhIHNwZWNpZmljIEFQSSwgb3IgeW91IGNhbiB1c2UgdGhlIHMzOk9iamVjdENyZWF0ZWQ6KiBldmVudCB0eXBlIHRvXG4gICAqIHJlcXVlc3Qgbm90aWZpY2F0aW9uIHJlZ2FyZGxlc3Mgb2YgdGhlIEFQSSB0aGF0IHdhcyB1c2VkIHRvIGNyZWF0ZSBhblxuICAgKiBvYmplY3QuXG4gICAqL1xuICBPQkpFQ1RfQ1JFQVRFRCA9ICdzMzpPYmplY3RDcmVhdGVkOionLFxuXG4gIC8qKlxuICAgKiBBbWF6b24gUzMgQVBJcyBzdWNoIGFzIFBVVCwgUE9TVCwgYW5kIENPUFkgY2FuIGNyZWF0ZSBhbiBvYmplY3QuIFVzaW5nXG4gICAqIHRoZXNlIGV2ZW50IHR5cGVzLCB5b3UgY2FuIGVuYWJsZSBub3RpZmljYXRpb24gd2hlbiBhbiBvYmplY3QgaXMgY3JlYXRlZFxuICAgKiB1c2luZyBhIHNwZWNpZmljIEFQSSwgb3IgeW91IGNhbiB1c2UgdGhlIHMzOk9iamVjdENyZWF0ZWQ6KiBldmVudCB0eXBlIHRvXG4gICAqIHJlcXVlc3Qgbm90aWZpY2F0aW9uIHJlZ2FyZGxlc3Mgb2YgdGhlIEFQSSB0aGF0IHdhcyB1c2VkIHRvIGNyZWF0ZSBhblxuICAgKiBvYmplY3QuXG4gICAqL1xuICBPQkpFQ1RfQ1JFQVRFRF9QVVQgPSAnczM6T2JqZWN0Q3JlYXRlZDpQdXQnLFxuXG4gIC8qKlxuICAgKiBBbWF6b24gUzMgQVBJcyBzdWNoIGFzIFBVVCwgUE9TVCwgYW5kIENPUFkgY2FuIGNyZWF0ZSBhbiBvYmplY3QuIFVzaW5nXG4gICAqIHRoZXNlIGV2ZW50IHR5cGVzLCB5b3UgY2FuIGVuYWJsZSBub3RpZmljYXRpb24gd2hlbiBhbiBvYmplY3QgaXMgY3JlYXRlZFxuICAgKiB1c2luZyBhIHNwZWNpZmljIEFQSSwgb3IgeW91IGNhbiB1c2UgdGhlIHMzOk9iamVjdENyZWF0ZWQ6KiBldmVudCB0eXBlIHRvXG4gICAqIHJlcXVlc3Qgbm90aWZpY2F0aW9uIHJlZ2FyZGxlc3Mgb2YgdGhlIEFQSSB0aGF0IHdhcyB1c2VkIHRvIGNyZWF0ZSBhblxuICAgKiBvYmplY3QuXG4gICAqL1xuICBPQkpFQ1RfQ1JFQVRFRF9QT1NUID0gJ3MzOk9iamVjdENyZWF0ZWQ6UG9zdCcsXG5cbiAgLyoqXG4gICAqIEFtYXpvbiBTMyBBUElzIHN1Y2ggYXMgUFVULCBQT1NULCBhbmQgQ09QWSBjYW4gY3JlYXRlIGFuIG9iamVjdC4gVXNpbmdcbiAgICogdGhlc2UgZXZlbnQgdHlwZXMsIHlvdSBjYW4gZW5hYmxlIG5vdGlmaWNhdGlvbiB3aGVuIGFuIG9iamVjdCBpcyBjcmVhdGVkXG4gICAqIHVzaW5nIGEgc3BlY2lmaWMgQVBJLCBvciB5b3UgY2FuIHVzZSB0aGUgczM6T2JqZWN0Q3JlYXRlZDoqIGV2ZW50IHR5cGUgdG9cbiAgICogcmVxdWVzdCBub3RpZmljYXRpb24gcmVnYXJkbGVzcyBvZiB0aGUgQVBJIHRoYXQgd2FzIHVzZWQgdG8gY3JlYXRlIGFuXG4gICAqIG9iamVjdC5cbiAgICovXG4gIE9CSkVDVF9DUkVBVEVEX0NPUFkgPSAnczM6T2JqZWN0Q3JlYXRlZDpDb3B5JyxcblxuICAvKipcbiAgICogQW1hem9uIFMzIEFQSXMgc3VjaCBhcyBQVVQsIFBPU1QsIGFuZCBDT1BZIGNhbiBjcmVhdGUgYW4gb2JqZWN0LiBVc2luZ1xuICAgKiB0aGVzZSBldmVudCB0eXBlcywgeW91IGNhbiBlbmFibGUgbm90aWZpY2F0aW9uIHdoZW4gYW4gb2JqZWN0IGlzIGNyZWF0ZWRcbiAgICogdXNpbmcgYSBzcGVjaWZpYyBBUEksIG9yIHlvdSBjYW4gdXNlIHRoZSBzMzpPYmplY3RDcmVhdGVkOiogZXZlbnQgdHlwZSB0b1xuICAgKiByZXF1ZXN0IG5vdGlmaWNhdGlvbiByZWdhcmRsZXNzIG9mIHRoZSBBUEkgdGhhdCB3YXMgdXNlZCB0byBjcmVhdGUgYW5cbiAgICogb2JqZWN0LlxuICAgKi9cbiAgT0JKRUNUX0NSRUFURURfQ09NUExFVEVfTVVMVElQQVJUX1VQTE9BRCA9ICdzMzpPYmplY3RDcmVhdGVkOkNvbXBsZXRlTXVsdGlwYXJ0VXBsb2FkJyxcblxuICAvKipcbiAgICogQnkgdXNpbmcgdGhlIE9iamVjdFJlbW92ZWQgZXZlbnQgdHlwZXMsIHlvdSBjYW4gZW5hYmxlIG5vdGlmaWNhdGlvbiB3aGVuXG4gICAqIGFuIG9iamVjdCBvciBhIGJhdGNoIG9mIG9iamVjdHMgaXMgcmVtb3ZlZCBmcm9tIGEgYnVja2V0LlxuICAgKlxuICAgKiBZb3UgY2FuIHJlcXVlc3Qgbm90aWZpY2F0aW9uIHdoZW4gYW4gb2JqZWN0IGlzIGRlbGV0ZWQgb3IgYSB2ZXJzaW9uZWRcbiAgICogb2JqZWN0IGlzIHBlcm1hbmVudGx5IGRlbGV0ZWQgYnkgdXNpbmcgdGhlIHMzOk9iamVjdFJlbW92ZWQ6RGVsZXRlIGV2ZW50XG4gICAqIHR5cGUuIE9yIHlvdSBjYW4gcmVxdWVzdCBub3RpZmljYXRpb24gd2hlbiBhIGRlbGV0ZSBtYXJrZXIgaXMgY3JlYXRlZCBmb3JcbiAgICogYSB2ZXJzaW9uZWQgb2JqZWN0IGJ5IHVzaW5nIHMzOk9iamVjdFJlbW92ZWQ6RGVsZXRlTWFya2VyQ3JlYXRlZC4gRm9yXG4gICAqIGluZm9ybWF0aW9uIGFib3V0IGRlbGV0aW5nIHZlcnNpb25lZCBvYmplY3RzLCBzZWUgRGVsZXRpbmcgT2JqZWN0XG4gICAqIFZlcnNpb25zLiBZb3UgY2FuIGFsc28gdXNlIGEgd2lsZGNhcmQgczM6T2JqZWN0UmVtb3ZlZDoqIHRvIHJlcXVlc3RcbiAgICogbm90aWZpY2F0aW9uIGFueXRpbWUgYW4gb2JqZWN0IGlzIGRlbGV0ZWQuXG4gICAqXG4gICAqIFlvdSB3aWxsIG5vdCByZWNlaXZlIGV2ZW50IG5vdGlmaWNhdGlvbnMgZnJvbSBhdXRvbWF0aWMgZGVsZXRlcyBmcm9tXG4gICAqIGxpZmVjeWNsZSBwb2xpY2llcyBvciBmcm9tIGZhaWxlZCBvcGVyYXRpb25zLlxuICAgKi9cbiAgT0JKRUNUX1JFTU9WRUQgPSAnczM6T2JqZWN0UmVtb3ZlZDoqJyxcblxuICAvKipcbiAgICogQnkgdXNpbmcgdGhlIE9iamVjdFJlbW92ZWQgZXZlbnQgdHlwZXMsIHlvdSBjYW4gZW5hYmxlIG5vdGlmaWNhdGlvbiB3aGVuXG4gICAqIGFuIG9iamVjdCBvciBhIGJhdGNoIG9mIG9iamVjdHMgaXMgcmVtb3ZlZCBmcm9tIGEgYnVja2V0LlxuICAgKlxuICAgKiBZb3UgY2FuIHJlcXVlc3Qgbm90aWZpY2F0aW9uIHdoZW4gYW4gb2JqZWN0IGlzIGRlbGV0ZWQgb3IgYSB2ZXJzaW9uZWRcbiAgICogb2JqZWN0IGlzIHBlcm1hbmVudGx5IGRlbGV0ZWQgYnkgdXNpbmcgdGhlIHMzOk9iamVjdFJlbW92ZWQ6RGVsZXRlIGV2ZW50XG4gICAqIHR5cGUuIE9yIHlvdSBjYW4gcmVxdWVzdCBub3RpZmljYXRpb24gd2hlbiBhIGRlbGV0ZSBtYXJrZXIgaXMgY3JlYXRlZCBmb3JcbiAgICogYSB2ZXJzaW9uZWQgb2JqZWN0IGJ5IHVzaW5nIHMzOk9iamVjdFJlbW92ZWQ6RGVsZXRlTWFya2VyQ3JlYXRlZC4gRm9yXG4gICAqIGluZm9ybWF0aW9uIGFib3V0IGRlbGV0aW5nIHZlcnNpb25lZCBvYmplY3RzLCBzZWUgRGVsZXRpbmcgT2JqZWN0XG4gICAqIFZlcnNpb25zLiBZb3UgY2FuIGFsc28gdXNlIGEgd2lsZGNhcmQgczM6T2JqZWN0UmVtb3ZlZDoqIHRvIHJlcXVlc3RcbiAgICogbm90aWZpY2F0aW9uIGFueXRpbWUgYW4gb2JqZWN0IGlzIGRlbGV0ZWQuXG4gICAqXG4gICAqIFlvdSB3aWxsIG5vdCByZWNlaXZlIGV2ZW50IG5vdGlmaWNhdGlvbnMgZnJvbSBhdXRvbWF0aWMgZGVsZXRlcyBmcm9tXG4gICAqIGxpZmVjeWNsZSBwb2xpY2llcyBvciBmcm9tIGZhaWxlZCBvcGVyYXRpb25zLlxuICAgKi9cbiAgT0JKRUNUX1JFTU9WRURfREVMRVRFID0gJ3MzOk9iamVjdFJlbW92ZWQ6RGVsZXRlJyxcblxuICAvKipcbiAgICogQnkgdXNpbmcgdGhlIE9iamVjdFJlbW92ZWQgZXZlbnQgdHlwZXMsIHlvdSBjYW4gZW5hYmxlIG5vdGlmaWNhdGlvbiB3aGVuXG4gICAqIGFuIG9iamVjdCBvciBhIGJhdGNoIG9mIG9iamVjdHMgaXMgcmVtb3ZlZCBmcm9tIGEgYnVja2V0LlxuICAgKlxuICAgKiBZb3UgY2FuIHJlcXVlc3Qgbm90aWZpY2F0aW9uIHdoZW4gYW4gb2JqZWN0IGlzIGRlbGV0ZWQgb3IgYSB2ZXJzaW9uZWRcbiAgICogb2JqZWN0IGlzIHBlcm1hbmVudGx5IGRlbGV0ZWQgYnkgdXNpbmcgdGhlIHMzOk9iamVjdFJlbW92ZWQ6RGVsZXRlIGV2ZW50XG4gICAqIHR5cGUuIE9yIHlvdSBjYW4gcmVxdWVzdCBub3RpZmljYXRpb24gd2hlbiBhIGRlbGV0ZSBtYXJrZXIgaXMgY3JlYXRlZCBmb3JcbiAgICogYSB2ZXJzaW9uZWQgb2JqZWN0IGJ5IHVzaW5nIHMzOk9iamVjdFJlbW92ZWQ6RGVsZXRlTWFya2VyQ3JlYXRlZC4gRm9yXG4gICAqIGluZm9ybWF0aW9uIGFib3V0IGRlbGV0aW5nIHZlcnNpb25lZCBvYmplY3RzLCBzZWUgRGVsZXRpbmcgT2JqZWN0XG4gICAqIFZlcnNpb25zLiBZb3UgY2FuIGFsc28gdXNlIGEgd2lsZGNhcmQgczM6T2JqZWN0UmVtb3ZlZDoqIHRvIHJlcXVlc3RcbiAgICogbm90aWZpY2F0aW9uIGFueXRpbWUgYW4gb2JqZWN0IGlzIGRlbGV0ZWQuXG4gICAqXG4gICAqIFlvdSB3aWxsIG5vdCByZWNlaXZlIGV2ZW50IG5vdGlmaWNhdGlvbnMgZnJvbSBhdXRvbWF0aWMgZGVsZXRlcyBmcm9tXG4gICAqIGxpZmVjeWNsZSBwb2xpY2llcyBvciBmcm9tIGZhaWxlZCBvcGVyYXRpb25zLlxuICAgKi9cbiAgT0JKRUNUX1JFTU9WRURfREVMRVRFX01BUktFUl9DUkVBVEVEID0gJ3MzOk9iamVjdFJlbW92ZWQ6RGVsZXRlTWFya2VyQ3JlYXRlZCcsXG5cbiAgLyoqXG4gICAqIFVzaW5nIHJlc3RvcmUgb2JqZWN0IGV2ZW50IHR5cGVzIHlvdSBjYW4gcmVjZWl2ZSBub3RpZmljYXRpb25zIGZvclxuICAgKiBpbml0aWF0aW9uIGFuZCBjb21wbGV0aW9uIHdoZW4gcmVzdG9yaW5nIG9iamVjdHMgZnJvbSB0aGUgUzMgR2xhY2llclxuICAgKiBzdG9yYWdlIGNsYXNzLlxuICAgKlxuICAgKiBZb3UgdXNlIHMzOk9iamVjdFJlc3RvcmU6UG9zdCB0byByZXF1ZXN0IG5vdGlmaWNhdGlvbiBvZiBvYmplY3QgcmVzdG9yYXRpb25cbiAgICogaW5pdGlhdGlvbi5cbiAgICovXG4gIE9CSkVDVF9SRVNUT1JFX1BPU1QgPSAnczM6T2JqZWN0UmVzdG9yZTpQb3N0JyxcblxuICAvKipcbiAgICogVXNpbmcgcmVzdG9yZSBvYmplY3QgZXZlbnQgdHlwZXMgeW91IGNhbiByZWNlaXZlIG5vdGlmaWNhdGlvbnMgZm9yXG4gICAqIGluaXRpYXRpb24gYW5kIGNvbXBsZXRpb24gd2hlbiByZXN0b3Jpbmcgb2JqZWN0cyBmcm9tIHRoZSBTMyBHbGFjaWVyXG4gICAqIHN0b3JhZ2UgY2xhc3MuXG4gICAqXG4gICAqIFlvdSB1c2UgczM6T2JqZWN0UmVzdG9yZTpDb21wbGV0ZWQgdG8gcmVxdWVzdCBub3RpZmljYXRpb24gb2ZcbiAgICogcmVzdG9yYXRpb24gY29tcGxldGlvbi5cbiAgICovXG4gIE9CSkVDVF9SRVNUT1JFX0NPTVBMRVRFRCA9ICdzMzpPYmplY3RSZXN0b3JlOkNvbXBsZXRlZCcsXG5cbiAgLyoqXG4gICAqIFVzaW5nIHJlc3RvcmUgb2JqZWN0IGV2ZW50IHR5cGVzIHlvdSBjYW4gcmVjZWl2ZSBub3RpZmljYXRpb25zIGZvclxuICAgKiBpbml0aWF0aW9uIGFuZCBjb21wbGV0aW9uIHdoZW4gcmVzdG9yaW5nIG9iamVjdHMgZnJvbSB0aGUgUzMgR2xhY2llclxuICAgKiBzdG9yYWdlIGNsYXNzLlxuICAgKlxuICAgKiBZb3UgdXNlIHMzOk9iamVjdFJlc3RvcmU6RGVsZXRlIHRvIHJlcXVlc3Qgbm90aWZpY2F0aW9uIG9mXG4gICAqIHJlc3RvcmF0aW9uIGNvbXBsZXRpb24uXG4gICAqL1xuICBPQkpFQ1RfUkVTVE9SRV9ERUxFVEUgPSAnczM6T2JqZWN0UmVzdG9yZTpEZWxldGUnLFxuXG4gIC8qKlxuICAgKiBZb3UgY2FuIHVzZSB0aGlzIGV2ZW50IHR5cGUgdG8gcmVxdWVzdCBBbWF6b24gUzMgdG8gc2VuZCBhIG5vdGlmaWNhdGlvblxuICAgKiBtZXNzYWdlIHdoZW4gQW1hem9uIFMzIGRldGVjdHMgdGhhdCBhbiBvYmplY3Qgb2YgdGhlIFJSUyBzdG9yYWdlIGNsYXNzIGlzXG4gICAqIGxvc3QuXG4gICAqL1xuICBSRURVQ0VEX1JFRFVOREFOQ1lfTE9TVF9PQkpFQ1QgPSAnczM6UmVkdWNlZFJlZHVuZGFuY3lMb3N0T2JqZWN0JyxcblxuICAvKipcbiAgICogWW91IHJlY2VpdmUgdGhpcyBub3RpZmljYXRpb24gZXZlbnQgd2hlbiBhbiBvYmplY3QgdGhhdCB3YXMgZWxpZ2libGUgZm9yXG4gICAqIHJlcGxpY2F0aW9uIHVzaW5nIEFtYXpvbiBTMyBSZXBsaWNhdGlvbiBUaW1lIENvbnRyb2wgZmFpbGVkIHRvIHJlcGxpY2F0ZS5cbiAgICovXG4gIFJFUExJQ0FUSU9OX09QRVJBVElPTl9GQUlMRURfUkVQTElDQVRJT04gPSAnczM6UmVwbGljYXRpb246T3BlcmF0aW9uRmFpbGVkUmVwbGljYXRpb24nLFxuXG4gIC8qKlxuICAgKiBZb3UgcmVjZWl2ZSB0aGlzIG5vdGlmaWNhdGlvbiBldmVudCB3aGVuIGFuIG9iamVjdCB0aGF0IHdhcyBlbGlnaWJsZSBmb3JcbiAgICogcmVwbGljYXRpb24gdXNpbmcgQW1hem9uIFMzIFJlcGxpY2F0aW9uIFRpbWUgQ29udHJvbCBleGNlZWRlZCB0aGUgMTUtbWludXRlXG4gICAqIHRocmVzaG9sZCBmb3IgcmVwbGljYXRpb24uXG4gICAqL1xuICBSRVBMSUNBVElPTl9PUEVSQVRJT05fTUlTU0VEX1RIUkVTSE9MRCA9ICdzMzpSZXBsaWNhdGlvbjpPcGVyYXRpb25NaXNzZWRUaHJlc2hvbGQnLFxuXG4gIC8qKlxuICAgKiBZb3UgcmVjZWl2ZSB0aGlzIG5vdGlmaWNhdGlvbiBldmVudCBmb3IgYW4gb2JqZWN0IHRoYXQgd2FzIGVsaWdpYmxlIGZvclxuICAgKiByZXBsaWNhdGlvbiB1c2luZyB0aGUgQW1hem9uIFMzIFJlcGxpY2F0aW9uIFRpbWUgQ29udHJvbCBmZWF0dXJlIHJlcGxpY2F0ZWRcbiAgICogYWZ0ZXIgdGhlIDE1LW1pbnV0ZSB0aHJlc2hvbGQuXG4gICAqL1xuICBSRVBMSUNBVElPTl9PUEVSQVRJT05fUkVQTElDQVRFRF9BRlRFUl9USFJFU0hPTEQgPSAnczM6UmVwbGljYXRpb246T3BlcmF0aW9uUmVwbGljYXRlZEFmdGVyVGhyZXNob2xkJyxcblxuICAvKipcbiAgICogWW91IHJlY2VpdmUgdGhpcyBub3RpZmljYXRpb24gZXZlbnQgZm9yIGFuIG9iamVjdCB0aGF0IHdhcyBlbGlnaWJsZSBmb3JcbiAgICogcmVwbGljYXRpb24gdXNpbmcgQW1hem9uIFMzIFJlcGxpY2F0aW9uIFRpbWUgQ29udHJvbCBidXQgaXMgbm8gbG9uZ2VyIHRyYWNrZWRcbiAgICogYnkgcmVwbGljYXRpb24gbWV0cmljcy5cbiAgICovXG4gIFJFUExJQ0FUSU9OX09QRVJBVElPTl9OT1RfVFJBQ0tFRCA9ICdzMzpSZXBsaWNhdGlvbjpPcGVyYXRpb25Ob3RUcmFja2VkJyxcblxuICAvKipcbiAgICogQnkgdXNpbmcgdGhlIExpZmVjeWNsZUV4cGlyYXRpb24gZXZlbnQgdHlwZXMsIHlvdSBjYW4gcmVjZWl2ZSBhIG5vdGlmaWNhdGlvblxuICAgKiB3aGVuIEFtYXpvbiBTMyBkZWxldGVzIGFuIG9iamVjdCBiYXNlZCBvbiB5b3VyIFMzIExpZmVjeWNsZSBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgTElGRUNZQ0xFX0VYUElSQVRJT04gPSAnczM6TGlmZWN5Y2xlRXhwaXJhdGlvbjoqJyxcblxuICAvKipcbiAgICogVGhlIHMzOkxpZmVjeWNsZUV4cGlyYXRpb246RGVsZXRlIGV2ZW50IHR5cGUgbm90aWZpZXMgeW91IHdoZW4gYW4gb2JqZWN0XG4gICAqIGluIGFuIHVudmVyc2lvbmVkIGJ1Y2tldCBpcyBkZWxldGVkLlxuICAgKiBJdCBhbHNvIG5vdGlmaWVzIHlvdSB3aGVuIGFuIG9iamVjdCB2ZXJzaW9uIGlzIHBlcm1hbmVudGx5IGRlbGV0ZWQgYnkgYW5cbiAgICogUzMgTGlmZWN5Y2xlIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBMSUZFQ1lDTEVfRVhQSVJBVElPTl9ERUxFVEUgPSAnczM6TGlmZWN5Y2xlRXhwaXJhdGlvbjpEZWxldGUnLFxuXG4gIC8qKlxuICAgKiBUaGUgczM6TGlmZWN5Y2xlRXhwaXJhdGlvbjpEZWxldGVNYXJrZXJDcmVhdGVkIGV2ZW50IHR5cGUgbm90aWZpZXMgeW91XG4gICAqIHdoZW4gUzMgTGlmZWN5Y2xlIGNyZWF0ZXMgYSBkZWxldGUgbWFya2VyIHdoZW4gYSBjdXJyZW50IHZlcnNpb24gb2YgYW5cbiAgICogb2JqZWN0IGluIHZlcnNpb25lZCBidWNrZXQgaXMgZGVsZXRlZC5cbiAgICovXG4gIExJRkVDWUNMRV9FWFBJUkFUSU9OX0RFTEVURV9NQVJLRVJfQ1JFQVRFRCA9ICdzMzpMaWZlY3ljbGVFeHBpcmF0aW9uOkRlbGV0ZU1hcmtlckNyZWF0ZWQnLFxuXG4gIC8qKlxuICAgKiBZb3UgcmVjZWl2ZSB0aGlzIG5vdGlmaWNhdGlvbiBldmVudCB3aGVuIGFuIG9iamVjdCBpcyB0cmFuc2l0aW9uZWQgdG9cbiAgICogYW5vdGhlciBBbWF6b24gUzMgc3RvcmFnZSBjbGFzcyBieSBhbiBTMyBMaWZlY3ljbGUgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIExJRkVDWUNMRV9UUkFOU0lUSU9OID0gJ3MzOkxpZmVjeWNsZVRyYW5zaXRpb24nLFxuXG4gIC8qKlxuICAgKiBZb3UgcmVjZWl2ZSB0aGlzIG5vdGlmaWNhdGlvbiBldmVudCB3aGVuIGFuIG9iamVjdCB3aXRoaW4gdGhlXG4gICAqIFMzIEludGVsbGlnZW50LVRpZXJpbmcgc3RvcmFnZSBjbGFzcyBtb3ZlZCB0byB0aGUgQXJjaGl2ZSBBY2Nlc3MgdGllciBvclxuICAgKiBEZWVwIEFyY2hpdmUgQWNjZXNzIHRpZXIuXG4gICAqL1xuICBJTlRFTExJR0VOVF9USUVSSU5HID0gJ3MzOkludGVsbGlnZW50VGllcmluZycsXG5cbiAgLyoqXG4gICAqIEJ5IHVzaW5nIHRoZSBPYmplY3RUYWdnaW5nIGV2ZW50IHR5cGVzLCB5b3UgY2FuIGVuYWJsZSBub3RpZmljYXRpb24gd2hlblxuICAgKiBhbiBvYmplY3QgdGFnIGlzIGFkZGVkIG9yIGRlbGV0ZWQgZnJvbSBhbiBvYmplY3QuXG4gICAqL1xuICBPQkpFQ1RfVEFHR0lORyA9ICdzMzpPYmplY3RUYWdnaW5nOionLFxuXG4gIC8qKlxuICAgKiBUaGUgczM6T2JqZWN0VGFnZ2luZzpQdXQgZXZlbnQgdHlwZSBub3RpZmllcyB5b3Ugd2hlbiBhIHRhZyBpcyBQVVQgb24gYW5cbiAgICogb2JqZWN0IG9yIGFuIGV4aXN0aW5nIHRhZyBpcyB1cGRhdGVkLlxuXG4gICAqL1xuICBPQkpFQ1RfVEFHR0lOR19QVVQgPSAnczM6T2JqZWN0VGFnZ2luZzpQdXQnLFxuXG4gIC8qKlxuICAgKiBUaGUgczM6T2JqZWN0VGFnZ2luZzpEZWxldGUgZXZlbnQgdHlwZSBub3RpZmllcyB5b3Ugd2hlbiBhIHRhZyBpcyByZW1vdmVkXG4gICAqIGZyb20gYW4gb2JqZWN0LlxuICAgKi9cbiAgT0JKRUNUX1RBR0dJTkdfREVMRVRFID0gJ3MzOk9iamVjdFRhZ2dpbmc6RGVsZXRlJyxcblxuICAvKipcbiAgICogWW91IHJlY2VpdmUgdGhpcyBub3RpZmljYXRpb24gZXZlbnQgd2hlbiBhbiBBQ0wgaXMgUFVUIG9uIGFuIG9iamVjdCBvciB3aGVuXG4gICAqIGFuIGV4aXN0aW5nIEFDTCBpcyBjaGFuZ2VkLlxuICAgKiBBbiBldmVudCBpcyBub3QgZ2VuZXJhdGVkIHdoZW4gYSByZXF1ZXN0IHJlc3VsdHMgaW4gbm8gY2hhbmdlIHRvIGFuXG4gICAqIG9iamVjdOKAmXMgQUNMLlxuICAgKi9cbiAgT0JKRUNUX0FDTF9QVVQgPSAnczM6T2JqZWN0QWNsOlB1dCcsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTm90aWZpY2F0aW9uS2V5RmlsdGVyIHtcbiAgLyoqXG4gICAqIFMzIGtleXMgbXVzdCBoYXZlIHRoZSBzcGVjaWZpZWQgcHJlZml4LlxuICAgKi9cbiAgcmVhZG9ubHkgcHJlZml4Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTMyBrZXlzIG11c3QgaGF2ZSB0aGUgc3BlY2lmaWVkIHN1ZmZpeC5cbiAgICovXG4gIHJlYWRvbmx5IHN1ZmZpeD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciB0aGUgb25DbG91ZFRyYWlsUHV0T2JqZWN0IG1ldGhvZFxuICovXG5leHBvcnQgaW50ZXJmYWNlIE9uQ2xvdWRUcmFpbEJ1Y2tldEV2ZW50T3B0aW9ucyBleHRlbmRzIGV2ZW50cy5PbkV2ZW50T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBPbmx5IHdhdGNoIGNoYW5nZXMgdG8gdGhlc2Ugb2JqZWN0IHBhdGhzXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gV2F0Y2ggY2hhbmdlcyB0byBhbGwgb2JqZWN0c1xuICAgKi9cbiAgcmVhZG9ubHkgcGF0aHM/OiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBEZWZhdWx0IGJ1Y2tldCBhY2Nlc3MgY29udHJvbCB0eXBlcy5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25TMy9sYXRlc3QvZGV2L2FjbC1vdmVydmlldy5odG1sXG4gKi9cbmV4cG9ydCBlbnVtIEJ1Y2tldEFjY2Vzc0NvbnRyb2wge1xuICAvKipcbiAgICogT3duZXIgZ2V0cyBGVUxMX0NPTlRST0wuIE5vIG9uZSBlbHNlIGhhcyBhY2Nlc3MgcmlnaHRzLlxuICAgKi9cbiAgUFJJVkFURSA9ICdQcml2YXRlJyxcblxuICAvKipcbiAgICogT3duZXIgZ2V0cyBGVUxMX0NPTlRST0wuIFRoZSBBbGxVc2VycyBncm91cCBnZXRzIFJFQUQgYWNjZXNzLlxuICAgKi9cbiAgUFVCTElDX1JFQUQgPSAnUHVibGljUmVhZCcsXG5cbiAgLyoqXG4gICAqIE93bmVyIGdldHMgRlVMTF9DT05UUk9MLiBUaGUgQWxsVXNlcnMgZ3JvdXAgZ2V0cyBSRUFEIGFuZCBXUklURSBhY2Nlc3MuXG4gICAqIEdyYW50aW5nIHRoaXMgb24gYSBidWNrZXQgaXMgZ2VuZXJhbGx5IG5vdCByZWNvbW1lbmRlZC5cbiAgICovXG4gIFBVQkxJQ19SRUFEX1dSSVRFID0gJ1B1YmxpY1JlYWRXcml0ZScsXG5cbiAgLyoqXG4gICAqIE93bmVyIGdldHMgRlVMTF9DT05UUk9MLiBUaGUgQXV0aGVudGljYXRlZFVzZXJzIGdyb3VwIGdldHMgUkVBRCBhY2Nlc3MuXG4gICAqL1xuICBBVVRIRU5USUNBVEVEX1JFQUQgPSAnQXV0aGVudGljYXRlZFJlYWQnLFxuXG4gIC8qKlxuICAgKiBUaGUgTG9nRGVsaXZlcnkgZ3JvdXAgZ2V0cyBXUklURSBhbmQgUkVBRF9BQ1AgcGVybWlzc2lvbnMgb24gdGhlIGJ1Y2tldC5cbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uUzMvbGF0ZXN0L2Rldi9TZXJ2ZXJMb2dzLmh0bWxcbiAgICovXG4gIExPR19ERUxJVkVSWV9XUklURSA9ICdMb2dEZWxpdmVyeVdyaXRlJyxcblxuICAvKipcbiAgICogT2JqZWN0IG93bmVyIGdldHMgRlVMTF9DT05UUk9MLiBCdWNrZXQgb3duZXIgZ2V0cyBSRUFEIGFjY2Vzcy5cbiAgICogSWYgeW91IHNwZWNpZnkgdGhpcyBjYW5uZWQgQUNMIHdoZW4gY3JlYXRpbmcgYSBidWNrZXQsIEFtYXpvbiBTMyBpZ25vcmVzIGl0LlxuICAgKi9cbiAgQlVDS0VUX09XTkVSX1JFQUQgPSAnQnVja2V0T3duZXJSZWFkJyxcblxuICAvKipcbiAgICogQm90aCB0aGUgb2JqZWN0IG93bmVyIGFuZCB0aGUgYnVja2V0IG93bmVyIGdldCBGVUxMX0NPTlRST0wgb3ZlciB0aGUgb2JqZWN0LlxuICAgKiBJZiB5b3Ugc3BlY2lmeSB0aGlzIGNhbm5lZCBBQ0wgd2hlbiBjcmVhdGluZyBhIGJ1Y2tldCwgQW1hem9uIFMzIGlnbm9yZXMgaXQuXG4gICAqL1xuICBCVUNLRVRfT1dORVJfRlVMTF9DT05UUk9MID0gJ0J1Y2tldE93bmVyRnVsbENvbnRyb2wnLFxuXG4gIC8qKlxuICAgKiBPd25lciBnZXRzIEZVTExfQ09OVFJPTC4gQW1hem9uIEVDMiBnZXRzIFJFQUQgYWNjZXNzIHRvIEdFVCBhbiBBbWF6b24gTWFjaGluZSBJbWFnZSAoQU1JKSBidW5kbGUgZnJvbSBBbWF6b24gUzMuXG4gICAqL1xuICBBV1NfRVhFQ19SRUFEID0gJ0F3c0V4ZWNSZWFkJyxcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSb3V0aW5nUnVsZUNvbmRpdGlvbiB7XG4gIC8qKlxuICAgKiBUaGUgSFRUUCBlcnJvciBjb2RlIHdoZW4gdGhlIHJlZGlyZWN0IGlzIGFwcGxpZWRcbiAgICpcbiAgICogSW4gdGhlIGV2ZW50IG9mIGFuIGVycm9yLCBpZiB0aGUgZXJyb3IgY29kZSBlcXVhbHMgdGhpcyB2YWx1ZSwgdGhlbiB0aGUgc3BlY2lmaWVkIHJlZGlyZWN0IGlzIGFwcGxpZWQuXG4gICAqXG4gICAqIElmIGJvdGggY29uZGl0aW9uIHByb3BlcnRpZXMgYXJlIHNwZWNpZmllZCwgYm90aCBtdXN0IGJlIHRydWUgZm9yIHRoZSByZWRpcmVjdCB0byBiZSBhcHBsaWVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFRoZSBIVFRQIGVycm9yIGNvZGUgd2lsbCBub3QgYmUgdmVyaWZpZWRcbiAgICovXG4gIHJlYWRvbmx5IGh0dHBFcnJvckNvZGVSZXR1cm5lZEVxdWFscz86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG9iamVjdCBrZXkgbmFtZSBwcmVmaXggd2hlbiB0aGUgcmVkaXJlY3QgaXMgYXBwbGllZFxuICAgKlxuICAgKiBJZiBib3RoIGNvbmRpdGlvbiBwcm9wZXJ0aWVzIGFyZSBzcGVjaWZpZWQsIGJvdGggbXVzdCBiZSB0cnVlIGZvciB0aGUgcmVkaXJlY3QgdG8gYmUgYXBwbGllZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBUaGUgb2JqZWN0IGtleSBuYW1lIHdpbGwgbm90IGJlIHZlcmlmaWVkXG4gICAqL1xuICByZWFkb25seSBrZXlQcmVmaXhFcXVhbHM/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBSZXBsYWNlS2V5IHtcbiAgLyoqXG4gICAqIFRoZSBzcGVjaWZpYyBvYmplY3Qga2V5IHRvIHVzZSBpbiB0aGUgcmVkaXJlY3QgcmVxdWVzdFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyB3aXRoKGtleVJlcGxhY2VtZW50OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gbmV3IHRoaXMoa2V5UmVwbGFjZW1lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBvYmplY3Qga2V5IHByZWZpeCB0byB1c2UgaW4gdGhlIHJlZGlyZWN0IHJlcXVlc3RcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcHJlZml4V2l0aChrZXlSZXBsYWNlbWVudDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIG5ldyB0aGlzKHVuZGVmaW5lZCwga2V5UmVwbGFjZW1lbnQpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgd2l0aEtleT86IHN0cmluZywgcHVibGljIHJlYWRvbmx5IHByZWZpeFdpdGhLZXk/OiBzdHJpbmcpIHtcbiAgfVxufVxuXG4vKipcbiAqIFJ1bGUgdGhhdCBkZWZpbmUgd2hlbiBhIHJlZGlyZWN0IGlzIGFwcGxpZWQgYW5kIHRoZSByZWRpcmVjdCBiZWhhdmlvci5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25TMy9sYXRlc3QvZGV2L2hvdy10by1wYWdlLXJlZGlyZWN0Lmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSb3V0aW5nUnVsZSB7XG4gIC8qKlxuICAgKiBUaGUgaG9zdCBuYW1lIHRvIHVzZSBpbiB0aGUgcmVkaXJlY3QgcmVxdWVzdFxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFRoZSBob3N0IG5hbWUgdXNlZCBpbiB0aGUgb3JpZ2luYWwgcmVxdWVzdC5cbiAgICovXG4gIHJlYWRvbmx5IGhvc3ROYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgSFRUUCByZWRpcmVjdCBjb2RlIHRvIHVzZSBvbiB0aGUgcmVzcG9uc2VcbiAgICpcbiAgICogQGRlZmF1bHQgXCIzMDFcIiAtIE1vdmVkIFBlcm1hbmVudGx5XG4gICAqL1xuICByZWFkb25seSBodHRwUmVkaXJlY3RDb2RlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBQcm90b2NvbCB0byB1c2Ugd2hlbiByZWRpcmVjdGluZyByZXF1ZXN0c1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIFRoZSBwcm90b2NvbCB1c2VkIGluIHRoZSBvcmlnaW5hbCByZXF1ZXN0LlxuICAgKi9cbiAgcmVhZG9ubHkgcHJvdG9jb2w/OiBSZWRpcmVjdFByb3RvY29sO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgdGhlIG9iamVjdCBrZXkgcHJlZml4IHRvIHVzZSBpbiB0aGUgcmVkaXJlY3QgcmVxdWVzdFxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFRoZSBrZXkgd2lsbCBub3QgYmUgcmVwbGFjZWRcbiAgICovXG4gIHJlYWRvbmx5IHJlcGxhY2VLZXk/OiBSZXBsYWNlS2V5O1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgYSBjb25kaXRpb24gdGhhdCBtdXN0IGJlIG1ldCBmb3IgdGhlIHNwZWNpZmllZCByZWRpcmVjdCB0byBhcHBseS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBjb25kaXRpb25cbiAgICovXG4gIHJlYWRvbmx5IGNvbmRpdGlvbj86IFJvdXRpbmdSdWxlQ29uZGl0aW9uO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGNyZWF0aW5nIFZpcnR1YWwtSG9zdGVkIHN0eWxlIFVSTC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBWaXJ0dWFsSG9zdGVkU3R5bGVVcmxPcHRpb25zIHtcbiAgLyoqXG4gICAqIFNwZWNpZmllcyB0aGUgVVJMIGluY2x1ZGVzIHRoZSByZWdpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgcmVnaW9uYWw/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGNyZWF0aW5nIGEgVHJhbnNmZXIgQWNjZWxlcmF0aW9uIFVSTC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUcmFuc2ZlckFjY2VsZXJhdGlvblVybE9wdGlvbnMge1xuICAvKipcbiAgICogRHVhbC1zdGFjayBzdXBwb3J0IHRvIGNvbm5lY3QgdG8gdGhlIGJ1Y2tldCBvdmVyIElQdjYuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGR1YWxTdGFjaz86IGJvb2xlYW47XG59XG5cbmZ1bmN0aW9uIG1hcE9yVW5kZWZpbmVkPFQsIFU+KGxpc3Q6IFRbXSB8IHVuZGVmaW5lZCwgY2FsbGJhY2s6IChlbGVtZW50OiBUKSA9PiBVKTogVVtdIHwgdW5kZWZpbmVkIHtcbiAgaWYgKCFsaXN0IHx8IGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJldHVybiBsaXN0Lm1hcChjYWxsYmFjayk7XG59XG4iXX0=
\No newline at end of file