@decaf-ts/decorator-validation 1.6.0 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -2
- package/dist/decorator-validation.cjs +1169 -366
- package/dist/decorator-validation.esm.cjs +1139 -334
- package/lib/esm/index.d.ts +5 -36
- package/lib/esm/index.js +6 -37
- package/lib/esm/model/Model.d.ts +100 -29
- package/lib/esm/model/Model.js +103 -36
- package/lib/esm/model/constants.d.ts +3 -3
- package/lib/esm/model/constants.js +4 -4
- package/lib/esm/model/construction.d.ts +3 -3
- package/lib/esm/model/construction.js +4 -4
- package/lib/esm/model/decorators.d.ts +4 -4
- package/lib/esm/model/decorators.js +6 -5
- package/lib/esm/model/types.d.ts +30 -11
- package/lib/esm/model/types.js +1 -1
- package/lib/esm/model/validation.d.ts +2 -2
- package/lib/esm/model/validation.js +5 -5
- package/lib/esm/utils/Decoration.d.ts +123 -0
- package/lib/esm/utils/Decoration.js +188 -0
- package/lib/esm/utils/constants.d.ts +27 -9
- package/lib/esm/utils/constants.js +28 -10
- package/lib/esm/utils/dates.d.ts +26 -16
- package/lib/esm/utils/dates.js +27 -17
- package/lib/esm/utils/decorators.d.ts +41 -0
- package/lib/esm/utils/decorators.js +42 -1
- package/lib/esm/utils/hashing.d.ts +50 -6
- package/lib/esm/utils/hashing.js +49 -5
- package/lib/esm/utils/index.d.ts +1 -0
- package/lib/esm/utils/index.js +2 -1
- package/lib/esm/utils/registry.d.ts +2 -2
- package/lib/esm/utils/registry.js +1 -1
- package/lib/esm/utils/serialization.d.ts +1 -1
- package/lib/esm/utils/serialization.js +2 -2
- package/lib/esm/utils/strings.d.ts +4 -4
- package/lib/esm/utils/strings.js +5 -5
- package/lib/esm/utils/types.d.ts +123 -16
- package/lib/esm/utils/types.js +1 -1
- package/lib/esm/validation/Validators/DateValidator.d.ts +40 -8
- package/lib/esm/validation/Validators/DateValidator.js +41 -9
- package/lib/esm/validation/Validators/EmailValidator.d.ts +39 -7
- package/lib/esm/validation/Validators/EmailValidator.js +40 -8
- package/lib/esm/validation/Validators/ListValidator.d.ts +44 -6
- package/lib/esm/validation/Validators/ListValidator.js +45 -7
- package/lib/esm/validation/Validators/MaxLengthValidator.js +3 -3
- package/lib/esm/validation/Validators/MaxValidator.d.ts +52 -6
- package/lib/esm/validation/Validators/MaxValidator.js +53 -7
- package/lib/esm/validation/Validators/MinLengthValidator.js +3 -3
- package/lib/esm/validation/Validators/MinValidator.d.ts +52 -6
- package/lib/esm/validation/Validators/MinValidator.js +53 -7
- package/lib/esm/validation/Validators/PatternValidator.d.ts +75 -9
- package/lib/esm/validation/Validators/PatternValidator.js +76 -10
- package/lib/esm/validation/Validators/RequiredValidator.d.ts +52 -6
- package/lib/esm/validation/Validators/RequiredValidator.js +53 -7
- package/lib/esm/validation/Validators/TypeValidator.d.ts +60 -6
- package/lib/esm/validation/Validators/TypeValidator.js +69 -7
- package/lib/esm/validation/Validators/URLValidator.d.ts +41 -7
- package/lib/esm/validation/Validators/URLValidator.js +42 -8
- package/lib/esm/validation/Validators/Validator.d.ts +77 -14
- package/lib/esm/validation/Validators/Validator.js +68 -11
- package/lib/esm/validation/Validators/ValidatorRegistry.d.ts +1 -7
- package/lib/esm/validation/Validators/ValidatorRegistry.js +4 -11
- package/lib/esm/validation/Validators/constants.d.ts +16 -15
- package/lib/esm/validation/Validators/constants.js +2 -1
- package/lib/esm/validation/decorators.d.ts +50 -40
- package/lib/esm/validation/decorators.js +112 -63
- package/lib/esm/validation/types.d.ts +154 -36
- package/lib/esm/validation/types.js +2 -2
- package/lib/index.cjs +7 -38
- package/lib/index.d.ts +5 -36
- package/lib/model/Model.cjs +103 -38
- package/lib/model/Model.d.ts +100 -29
- package/lib/model/constants.cjs +4 -4
- package/lib/model/constants.d.ts +3 -3
- package/lib/model/construction.cjs +4 -4
- package/lib/model/construction.d.ts +3 -3
- package/lib/model/decorators.cjs +6 -5
- package/lib/model/decorators.d.ts +4 -4
- package/lib/model/types.cjs +1 -1
- package/lib/model/types.d.ts +30 -11
- package/lib/model/validation.cjs +4 -4
- package/lib/model/validation.d.ts +2 -2
- package/lib/utils/Decoration.cjs +192 -0
- package/lib/utils/Decoration.d.ts +123 -0
- package/lib/utils/constants.cjs +29 -11
- package/lib/utils/constants.d.ts +27 -9
- package/lib/utils/dates.cjs +27 -17
- package/lib/utils/dates.d.ts +26 -16
- package/lib/utils/decorators.cjs +42 -1
- package/lib/utils/decorators.d.ts +41 -0
- package/lib/utils/hashing.cjs +49 -5
- package/lib/utils/hashing.d.ts +50 -6
- package/lib/utils/index.cjs +2 -1
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/registry.cjs +1 -1
- package/lib/utils/registry.d.ts +2 -2
- package/lib/utils/serialization.cjs +2 -2
- package/lib/utils/serialization.d.ts +1 -1
- package/lib/utils/strings.cjs +5 -5
- package/lib/utils/strings.d.ts +4 -4
- package/lib/utils/types.cjs +1 -1
- package/lib/utils/types.d.ts +123 -16
- package/lib/validation/Validators/DateValidator.cjs +41 -9
- package/lib/validation/Validators/DateValidator.d.ts +40 -8
- package/lib/validation/Validators/EmailValidator.cjs +40 -8
- package/lib/validation/Validators/EmailValidator.d.ts +39 -7
- package/lib/validation/Validators/ListValidator.cjs +45 -7
- package/lib/validation/Validators/ListValidator.d.ts +44 -6
- package/lib/validation/Validators/MaxLengthValidator.cjs +3 -3
- package/lib/validation/Validators/MaxValidator.cjs +53 -7
- package/lib/validation/Validators/MaxValidator.d.ts +52 -6
- package/lib/validation/Validators/MinLengthValidator.cjs +3 -3
- package/lib/validation/Validators/MinValidator.cjs +53 -7
- package/lib/validation/Validators/MinValidator.d.ts +52 -6
- package/lib/validation/Validators/PatternValidator.cjs +76 -10
- package/lib/validation/Validators/PatternValidator.d.ts +75 -9
- package/lib/validation/Validators/RequiredValidator.cjs +53 -7
- package/lib/validation/Validators/RequiredValidator.d.ts +52 -6
- package/lib/validation/Validators/TypeValidator.cjs +69 -7
- package/lib/validation/Validators/TypeValidator.d.ts +60 -6
- package/lib/validation/Validators/URLValidator.cjs +42 -8
- package/lib/validation/Validators/URLValidator.d.ts +41 -7
- package/lib/validation/Validators/Validator.cjs +68 -11
- package/lib/validation/Validators/Validator.d.ts +77 -14
- package/lib/validation/Validators/ValidatorRegistry.cjs +4 -12
- package/lib/validation/Validators/ValidatorRegistry.d.ts +1 -7
- package/lib/validation/Validators/constants.cjs +2 -1
- package/lib/validation/Validators/constants.d.ts +16 -15
- package/lib/validation/decorators.cjs +112 -63
- package/lib/validation/decorators.d.ts +50 -40
- package/lib/validation/types.cjs +2 -1
- package/lib/validation/types.d.ts +154 -36
- package/package.json +2 -2
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('reflect-metadata'), require('@decaf-ts/reflection')) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'reflect-metadata', '@decaf-ts/reflection'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["decorator-validation"] = {}, null, global.reflection));
|
|
5
|
-
})(this, (function (exports, reflectMetadata, reflection) { 'use strict';
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('reflect-metadata'), require('@decaf-ts/reflection'), require('tslib')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'reflect-metadata', '@decaf-ts/reflection', 'tslib'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["decorator-validation"] = {}, null, global.reflection, global.tslib));
|
|
5
|
+
})(this, (function (exports, reflectMetadata, reflection, tslib) { 'use strict';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* @
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* @property {string}
|
|
14
|
-
* @property {string}
|
|
15
|
-
* @property {string}
|
|
16
|
-
*
|
|
17
|
-
* @
|
|
18
|
-
* @
|
|
8
|
+
* @description Enum containing metadata keys used for reflection in the model system
|
|
9
|
+
* @summary Defines the various Model keys used for reflection and metadata storage.
|
|
10
|
+
* These keys are used throughout the library to store and retrieve metadata about models,
|
|
11
|
+
* their properties, and their behavior.
|
|
12
|
+
*
|
|
13
|
+
* @property {string} REFLECT - Prefix to all other keys, used as a namespace
|
|
14
|
+
* @property {string} TYPE - Key for storing design type information
|
|
15
|
+
* @property {string} PARAMS - Key for storing method parameter types
|
|
16
|
+
* @property {string} RETURN - Key for storing method return type
|
|
17
|
+
* @property {string} MODEL - Key for identifying model metadata
|
|
18
|
+
* @property {string} ANCHOR - Anchor key that serves as a ghost property in the model
|
|
19
|
+
* @property {string} CONSTRUCTION - Key for storing construction information
|
|
20
|
+
* @property {string} ATTRIBUTE - Key for storing attribute metadata
|
|
21
|
+
* @property {string} HASHING - Key for storing hashing configuration
|
|
22
|
+
* @property {string} SERIALIZATION - Key for storing serialization configuration
|
|
23
|
+
*
|
|
24
|
+
* @readonly
|
|
25
|
+
* @enum {string}
|
|
26
|
+
* @memberOf module:decorator-validation
|
|
19
27
|
* @category Model
|
|
20
28
|
*/
|
|
21
29
|
exports.ModelKeys = void 0;
|
|
@@ -31,6 +39,16 @@
|
|
|
31
39
|
ModelKeys["HASHING"] = "hashing";
|
|
32
40
|
ModelKeys["SERIALIZATION"] = "serialization";
|
|
33
41
|
})(exports.ModelKeys || (exports.ModelKeys = {}));
|
|
42
|
+
/**
|
|
43
|
+
* @description Default flavour identifier for the decorator system
|
|
44
|
+
* @summary Defines the default flavour used by the Decoration class when no specific flavour is provided.
|
|
45
|
+
* This constant is used throughout the library as the fallback flavour for decorators.
|
|
46
|
+
*
|
|
47
|
+
* @const {string}
|
|
48
|
+
* @memberOf module:decorator-validation
|
|
49
|
+
* @category Model
|
|
50
|
+
*/
|
|
51
|
+
const DefaultFlavour = "decaf";
|
|
34
52
|
|
|
35
53
|
/**
|
|
36
54
|
* @summary The keys used for validation
|
|
@@ -70,6 +88,7 @@
|
|
|
70
88
|
TYPE: "type",
|
|
71
89
|
PASSWORD: "password",
|
|
72
90
|
LIST: "list",
|
|
91
|
+
FORMAT: "format",
|
|
73
92
|
};
|
|
74
93
|
/**
|
|
75
94
|
* @summary list of month names
|
|
@@ -174,8 +193,8 @@
|
|
|
174
193
|
* @return {string} formatted string
|
|
175
194
|
*
|
|
176
195
|
* @function stringFormat
|
|
177
|
-
* @memberOf module:decorator-validation
|
|
178
|
-
* @category
|
|
196
|
+
* @memberOf module:decorator-validation
|
|
197
|
+
* @category Model
|
|
179
198
|
*/
|
|
180
199
|
function stringFormat(string, ...args) {
|
|
181
200
|
return string.replace(/{(\d+)}/g, function (match, number) {
|
|
@@ -193,8 +212,8 @@
|
|
|
193
212
|
* @return {string} formatted string
|
|
194
213
|
*
|
|
195
214
|
* @function sf
|
|
196
|
-
* @memberOf module:decorator-validation
|
|
197
|
-
* @category
|
|
215
|
+
* @memberOf module:decorator-validation
|
|
216
|
+
* @category Model
|
|
198
217
|
*/
|
|
199
218
|
const sf = stringFormat;
|
|
200
219
|
|
|
@@ -206,8 +225,8 @@
|
|
|
206
225
|
* @return {Date} the date from the format or the standard new Date({@prop date}) if the string couldn't be parsed (are you sure the format matches the string?)
|
|
207
226
|
*
|
|
208
227
|
* @function dateFromFormat
|
|
209
|
-
* @memberOf module:decorator-validation
|
|
210
|
-
* @category
|
|
228
|
+
* @memberOf module:decorator-validation
|
|
229
|
+
* @category Model
|
|
211
230
|
*/
|
|
212
231
|
function dateFromFormat(date, format) {
|
|
213
232
|
let formatRegexp = format;
|
|
@@ -294,11 +313,16 @@
|
|
|
294
313
|
return new Date(year, month - 1, day, hour, minutes, seconds, ms);
|
|
295
314
|
}
|
|
296
315
|
/**
|
|
297
|
-
* @
|
|
298
|
-
* @
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
* @
|
|
316
|
+
* @description Binds a specific date format to a Date object's toString and toISOString methods
|
|
317
|
+
* @summary Modifies a Date object to return a formatted string when toString or toISOString is called.
|
|
318
|
+
* This function overrides the default toString and toISOString methods of the Date object to return
|
|
319
|
+
* the date formatted according to the specified format string.
|
|
320
|
+
* @param {Date} [date] The Date object to modify
|
|
321
|
+
* @param {string} [format] The format string to use for formatting the date
|
|
322
|
+
* @return {Date|undefined} The modified Date object or undefined if no date was provided
|
|
323
|
+
* @function bindDateToString
|
|
324
|
+
* @memberOf module:decorator-validation
|
|
325
|
+
* @category Model
|
|
302
326
|
*/
|
|
303
327
|
function bindDateToString(date, format) {
|
|
304
328
|
if (!date)
|
|
@@ -318,9 +342,14 @@
|
|
|
318
342
|
return date;
|
|
319
343
|
}
|
|
320
344
|
/**
|
|
321
|
-
* @
|
|
322
|
-
* @
|
|
323
|
-
*
|
|
345
|
+
* @description Safely checks if a value is a valid Date object
|
|
346
|
+
* @summary A utility function that determines if a value is a valid Date object.
|
|
347
|
+
* This function is more reliable than using instanceof Date as it also checks
|
|
348
|
+
* that the date is not NaN, which can happen with invalid date strings.
|
|
349
|
+
* @param {any} date The value to check
|
|
350
|
+
* @return {boolean} True if the value is a valid Date object, false otherwise
|
|
351
|
+
* @function isValidDate
|
|
352
|
+
* @memberOf module:decorator-validation
|
|
324
353
|
* @category Validation
|
|
325
354
|
*/
|
|
326
355
|
function isValidDate(date) {
|
|
@@ -335,8 +364,8 @@
|
|
|
335
364
|
* @return {string}
|
|
336
365
|
*
|
|
337
366
|
* @function twoDigitPad
|
|
338
|
-
* @memberOf module:decorator-validation
|
|
339
|
-
* @category
|
|
367
|
+
* @memberOf module:decorator-validation
|
|
368
|
+
* @category Model
|
|
340
369
|
*/
|
|
341
370
|
function twoDigitPad(num) {
|
|
342
371
|
return num < 10 ? "0" + num : num.toString();
|
|
@@ -366,8 +395,8 @@
|
|
|
366
395
|
* @return {string} the formatted date
|
|
367
396
|
*
|
|
368
397
|
* @function formatDate
|
|
369
|
-
* @memberOf module:decorator-validation
|
|
370
|
-
* @category
|
|
398
|
+
* @memberOf module:decorator-validation
|
|
399
|
+
* @category Model
|
|
371
400
|
*/
|
|
372
401
|
function formatDate(date, patternStr = "yyyy/MM/dd") {
|
|
373
402
|
const day = date.getDate(), month = date.getMonth(), year = date.getFullYear(), hour = date.getHours(), minute = date.getMinutes(), second = date.getSeconds(), miliseconds = date.getMilliseconds(), h = hour % 12, hh = twoDigitPad(h), HH = twoDigitPad(hour), mm = twoDigitPad(minute), ss = twoDigitPad(second), aaa = hour < 12 ? "AM" : "PM", EEEE = DAYS_OF_WEEK_NAMES[date.getDay()], EEE = EEEE.substr(0, 3), dd = twoDigitPad(day), M = month + 1, MM = twoDigitPad(M), MMMM = MONTH_NAMES[month], MMM = MMMM.substr(0, 3), yyyy = year + "", yy = yyyy.substr(2, 2);
|
|
@@ -401,8 +430,8 @@
|
|
|
401
430
|
* @summary Parses a date from a specified format
|
|
402
431
|
* @param {string} format
|
|
403
432
|
* @param {string | Date | number} [v]
|
|
404
|
-
* @memberOf module:decorator-validation
|
|
405
|
-
* @category
|
|
433
|
+
* @memberOf module:decorator-validation
|
|
434
|
+
* @category Model
|
|
406
435
|
*/
|
|
407
436
|
function parseDate(format, v) {
|
|
408
437
|
let value = undefined;
|
|
@@ -439,6 +468,221 @@
|
|
|
439
468
|
return bindDateToString(value, format);
|
|
440
469
|
}
|
|
441
470
|
|
|
471
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
472
|
+
function defaultFlavourResolver(target) {
|
|
473
|
+
return DefaultFlavour;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* @description A decorator management class that handles flavoured decorators
|
|
477
|
+
* @summary The Decoration class provides a builder pattern for creating and managing decorators with different flavours.
|
|
478
|
+
* It supports registering, extending, and applying decorators with context-aware flavour resolution.
|
|
479
|
+
* The class implements a fluent interface for defining, extending, and applying decorators with different flavours,
|
|
480
|
+
* allowing for framework-specific decorator implementations while maintaining a consistent API.
|
|
481
|
+
* @template T Type of the decorator (ClassDecorator | PropertyDecorator | MethodDecorator)
|
|
482
|
+
* @param {string} [flavour] Optional flavour parameter for the decorator context
|
|
483
|
+
* @class
|
|
484
|
+
* @category Model
|
|
485
|
+
* @example
|
|
486
|
+
* ```typescript
|
|
487
|
+
* // Create a new decoration for 'component' with default flavour
|
|
488
|
+
* const componentDecorator = new Decoration()
|
|
489
|
+
* .for('component')
|
|
490
|
+
* .define(customComponentDecorator);
|
|
491
|
+
*
|
|
492
|
+
* // Create a flavoured decoration
|
|
493
|
+
* const vueComponent = new Decoration('vue')
|
|
494
|
+
* .for('component')
|
|
495
|
+
* .define(vueComponentDecorator);
|
|
496
|
+
*
|
|
497
|
+
* // Apply the decoration
|
|
498
|
+
* @componentDecorator
|
|
499
|
+
* class MyComponent {}
|
|
500
|
+
* ```
|
|
501
|
+
* @mermaid
|
|
502
|
+
* sequenceDiagram
|
|
503
|
+
* participant C as Client
|
|
504
|
+
* participant D as Decoration
|
|
505
|
+
* participant R as FlavourResolver
|
|
506
|
+
* participant F as DecoratorFactory
|
|
507
|
+
*
|
|
508
|
+
* C->>D: new Decoration(flavour)
|
|
509
|
+
* C->>D: for(key)
|
|
510
|
+
* C->>D: define(decorators)
|
|
511
|
+
* D->>D: register(key, flavour, decorators)
|
|
512
|
+
* D->>F: decoratorFactory(key, flavour)
|
|
513
|
+
* F->>R: resolve(target)
|
|
514
|
+
* R-->>F: resolved flavour
|
|
515
|
+
* F->>F: apply decorators
|
|
516
|
+
* F-->>C: decorated target
|
|
517
|
+
*/
|
|
518
|
+
class Decoration {
|
|
519
|
+
/**
|
|
520
|
+
* @description Static map of registered decorators
|
|
521
|
+
* @summary Stores all registered decorators organized by key and flavour
|
|
522
|
+
*/
|
|
523
|
+
static { this.decorators = {}; }
|
|
524
|
+
/**
|
|
525
|
+
* @description Function to resolve flavour from a target
|
|
526
|
+
* @summary Resolver function that determines the appropriate flavour for a given target
|
|
527
|
+
*/
|
|
528
|
+
static { this.flavourResolver = defaultFlavourResolver; }
|
|
529
|
+
constructor(flavour = DefaultFlavour) {
|
|
530
|
+
this.flavour = flavour;
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* @description Sets the key for the decoration builder
|
|
534
|
+
* @summary Initializes a new decoration chain with the specified key
|
|
535
|
+
* @param {string} key The identifier for the decorator
|
|
536
|
+
* @return {DecorationBuilderMid} Builder instance for method chaining
|
|
537
|
+
*/
|
|
538
|
+
for(key) {
|
|
539
|
+
this.key = key;
|
|
540
|
+
return this;
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* @description Adds decorators to the current context
|
|
544
|
+
* @summary Internal method to add decorators with addon support
|
|
545
|
+
* @param {boolean} [addon=false] Whether the decorators are addons
|
|
546
|
+
* @param decorators Array of decorators
|
|
547
|
+
* @return {this} Current instance for chaining
|
|
548
|
+
*/
|
|
549
|
+
decorate(addon = false, ...decorators) {
|
|
550
|
+
if (!this.key)
|
|
551
|
+
throw new Error("key must be provided before decorators can be added");
|
|
552
|
+
if (!addon && !this.decorators && this.flavour !== DefaultFlavour)
|
|
553
|
+
throw new Error("Must provide overrides or addons to override or extend decaf's decorators");
|
|
554
|
+
if (this.flavour === DefaultFlavour && addon)
|
|
555
|
+
throw new Error("Default flavour cannot be extended");
|
|
556
|
+
this[addon ? "extras" : "decorators"] = new Set([
|
|
557
|
+
...(this[addon ? "extras" : "decorators"] || new Set()).values(),
|
|
558
|
+
...decorators,
|
|
559
|
+
]);
|
|
560
|
+
return this;
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* @description Defines the base decorators
|
|
564
|
+
* @summary Sets the primary decorators for the current context
|
|
565
|
+
* @param decorators Decorators to define
|
|
566
|
+
* @return Builder instance for finishing the chain
|
|
567
|
+
*/
|
|
568
|
+
define(...decorators) {
|
|
569
|
+
return this.decorate(false, ...decorators);
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* @description Extends existing decorators
|
|
573
|
+
* @summary Adds additional decorators to the current context
|
|
574
|
+
* @param decorators Additional decorators
|
|
575
|
+
* @return {DecorationBuilderBuild} Builder instance for building the decorator
|
|
576
|
+
*/
|
|
577
|
+
extend(...decorators) {
|
|
578
|
+
return this.decorate(true, ...decorators);
|
|
579
|
+
}
|
|
580
|
+
decoratorFactory(key, f = DefaultFlavour) {
|
|
581
|
+
const contextDecorator = function contextDecorator(target, propertyKey, descriptor) {
|
|
582
|
+
const flavour = Decoration.flavourResolver(target);
|
|
583
|
+
let decorators;
|
|
584
|
+
const extras = Decoration.decorators[key][flavour].extras;
|
|
585
|
+
if (Decoration.decorators[key] &&
|
|
586
|
+
Decoration.decorators[key][flavour] &&
|
|
587
|
+
Decoration.decorators[key][flavour].decorators) {
|
|
588
|
+
decorators = Decoration.decorators[key][flavour].decorators;
|
|
589
|
+
}
|
|
590
|
+
else {
|
|
591
|
+
decorators = Decoration.decorators[key][DefaultFlavour].decorators;
|
|
592
|
+
}
|
|
593
|
+
[
|
|
594
|
+
...(decorators ? decorators.values() : []),
|
|
595
|
+
...(extras ? extras.values() : []),
|
|
596
|
+
].forEach((d) => d(target, propertyKey, descriptor, descriptor));
|
|
597
|
+
// return apply(
|
|
598
|
+
//
|
|
599
|
+
// )(target, propertyKey, descriptor);
|
|
600
|
+
};
|
|
601
|
+
Object.defineProperty(contextDecorator, "name", {
|
|
602
|
+
value: [f, key].join("_decorator_for_"),
|
|
603
|
+
writable: false,
|
|
604
|
+
});
|
|
605
|
+
return contextDecorator;
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* @description Creates the final decorator function
|
|
609
|
+
* @summary Builds and returns the decorator factory function
|
|
610
|
+
* @return {function(object, any?, TypedPropertyDescriptor?): any} The generated decorator function
|
|
611
|
+
*/
|
|
612
|
+
apply() {
|
|
613
|
+
if (!this.key)
|
|
614
|
+
throw new Error("No key provided for the decoration builder");
|
|
615
|
+
Decoration.register(this.key, this.flavour, this.decorators, this.extras);
|
|
616
|
+
return this.decoratorFactory(this.key, this.flavour);
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* @description Registers decorators for a specific key and flavour
|
|
620
|
+
* @summary Internal method to store decorators in the static registry
|
|
621
|
+
* @param {string} key Decorator key
|
|
622
|
+
* @param {string} flavour Decorator flavour
|
|
623
|
+
* @param [decorators] Primary decorators
|
|
624
|
+
* @param [extras] Additional decorators
|
|
625
|
+
*/
|
|
626
|
+
static register(key, flavour, decorators, extras) {
|
|
627
|
+
if (!key)
|
|
628
|
+
throw new Error("No key provided for the decoration builder");
|
|
629
|
+
if (!decorators)
|
|
630
|
+
throw new Error("No decorators provided for the decoration builder");
|
|
631
|
+
if (!flavour)
|
|
632
|
+
throw new Error("No flavour provided for the decoration builder");
|
|
633
|
+
if (!Decoration.decorators[key])
|
|
634
|
+
Decoration.decorators[key] = {};
|
|
635
|
+
if (!Decoration.decorators[key][flavour])
|
|
636
|
+
Decoration.decorators[key][flavour] = {};
|
|
637
|
+
if (decorators)
|
|
638
|
+
Decoration.decorators[key][flavour].decorators = decorators;
|
|
639
|
+
if (extras)
|
|
640
|
+
Decoration.decorators[key][flavour].extras = extras;
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* @description Sets the global flavour resolver
|
|
644
|
+
* @summary Configures the function used to determine decorator flavours
|
|
645
|
+
* @param {FlavourResolver} resolver Function to resolve flavours
|
|
646
|
+
*/
|
|
647
|
+
static setFlavourResolver(resolver) {
|
|
648
|
+
Decoration.flavourResolver = resolver;
|
|
649
|
+
}
|
|
650
|
+
static for(key) {
|
|
651
|
+
return new Decoration().for(key);
|
|
652
|
+
}
|
|
653
|
+
static flavouredAs(flavour) {
|
|
654
|
+
return new Decoration(flavour);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* @description Property decorator factory for model attributes
|
|
660
|
+
* @summary Creates a decorator that marks class properties as model attributes. The decorator maintains a list
|
|
661
|
+
* of property keys under a specified metadata key in the model. If the key doesn't exist, it creates a new array;
|
|
662
|
+
* if it exists, it appends the property key to the existing array, avoiding duplicates.
|
|
663
|
+
*
|
|
664
|
+
* @param {string} [key=ModelKeys.ATTRIBUTE] - The metadata key under which to store the property name
|
|
665
|
+
* @return {function(object, any?): void} Decorator function that registers the property
|
|
666
|
+
*
|
|
667
|
+
* @function prop
|
|
668
|
+
* @category Decorators
|
|
669
|
+
*
|
|
670
|
+
* @mermaid
|
|
671
|
+
* sequenceDiagram
|
|
672
|
+
* participant D as Decorator
|
|
673
|
+
* participant M as Model
|
|
674
|
+
*
|
|
675
|
+
* D->>M: Check if key exists
|
|
676
|
+
* alt key exists
|
|
677
|
+
* M-->>D: Return existing props array
|
|
678
|
+
* else key doesn't exist
|
|
679
|
+
* D->>M: Create new props array
|
|
680
|
+
* end
|
|
681
|
+
* D->>M: Check if property exists
|
|
682
|
+
* alt property not in array
|
|
683
|
+
* D->>M: Add property to array
|
|
684
|
+
* end
|
|
685
|
+
*/
|
|
442
686
|
function prop(key = exports.ModelKeys.ATTRIBUTE) {
|
|
443
687
|
return (model, propertyKey) => {
|
|
444
688
|
let props;
|
|
@@ -452,6 +696,19 @@
|
|
|
452
696
|
props.push(propertyKey);
|
|
453
697
|
};
|
|
454
698
|
}
|
|
699
|
+
/**
|
|
700
|
+
* @description Combined property decorator factory for metadata and attribute marking
|
|
701
|
+
* @summary Creates a decorator that both marks a property as a model attribute and assigns metadata to it.
|
|
702
|
+
* Combines the functionality of prop() and metadata() decorators.
|
|
703
|
+
*
|
|
704
|
+
* @template V - The type of the metadata value
|
|
705
|
+
* @param {string} key - The metadata key
|
|
706
|
+
* @param {V} value - The metadata value to associate with the property
|
|
707
|
+
* @return {Function} Combined decorator function
|
|
708
|
+
*
|
|
709
|
+
* @function propMetadata
|
|
710
|
+
* @category Decorators
|
|
711
|
+
*/
|
|
455
712
|
function propMetadata(key, value) {
|
|
456
713
|
return reflection.apply(prop(), reflection.metadata(key, value));
|
|
457
714
|
}
|
|
@@ -463,8 +720,8 @@
|
|
|
463
720
|
* @return {number} hash value of obj
|
|
464
721
|
*
|
|
465
722
|
* @function hashCode
|
|
466
|
-
* @memberOf module:decorator-validation
|
|
467
|
-
* @category
|
|
723
|
+
* @memberOf module:decorator-validation
|
|
724
|
+
* @category Model
|
|
468
725
|
*/
|
|
469
726
|
function hashCode(obj) {
|
|
470
727
|
obj = String(obj);
|
|
@@ -483,8 +740,8 @@
|
|
|
483
740
|
* @return {string} the resulting hash
|
|
484
741
|
*
|
|
485
742
|
* @function hashObj
|
|
486
|
-
* @memberOf module:decorator-validation
|
|
487
|
-
* @category
|
|
743
|
+
* @memberOf module:decorator-validation
|
|
744
|
+
* @category Model
|
|
488
745
|
*/
|
|
489
746
|
function hashObj(obj) {
|
|
490
747
|
const hashReducer = function (h, el) {
|
|
@@ -511,17 +768,61 @@
|
|
|
511
768
|
return (typeof result === "number" ? Math.abs(result) : result).toString();
|
|
512
769
|
}
|
|
513
770
|
const DefaultHashingMethod = "default";
|
|
771
|
+
/**
|
|
772
|
+
* @description Manages hashing methods and provides a unified hashing interface
|
|
773
|
+
* @summary A utility class that provides a registry for different hashing functions and methods to hash objects.
|
|
774
|
+
* The class maintains a cache of registered hashing functions and allows setting a default hashing method.
|
|
775
|
+
* It prevents direct instantiation and provides static methods for registration and hashing.
|
|
776
|
+
*
|
|
777
|
+
* @class Hashing
|
|
778
|
+
* @category Model
|
|
779
|
+
*
|
|
780
|
+
* @example
|
|
781
|
+
* ```typescript
|
|
782
|
+
* // Register a custom hashing function
|
|
783
|
+
* Hashing.register('md5', (obj) => createMD5Hash(obj), true);
|
|
784
|
+
*
|
|
785
|
+
* // Hash an object using default method
|
|
786
|
+
* const hash1 = Hashing.hash(myObject);
|
|
787
|
+
*
|
|
788
|
+
* // Hash using specific method
|
|
789
|
+
* const hash2 = Hashing.hash(myObject, 'md5');
|
|
790
|
+
* ```
|
|
791
|
+
*/
|
|
514
792
|
class Hashing {
|
|
793
|
+
/**
|
|
794
|
+
* @description Current default hashing method identifier
|
|
795
|
+
* @private
|
|
796
|
+
*/
|
|
515
797
|
static { this.current = DefaultHashingMethod; }
|
|
798
|
+
/**
|
|
799
|
+
* @description Cache of registered hashing functions
|
|
800
|
+
* @private
|
|
801
|
+
*/
|
|
516
802
|
static { this.cache = {
|
|
517
803
|
default: hashObj,
|
|
518
804
|
}; }
|
|
519
805
|
constructor() { }
|
|
806
|
+
/**
|
|
807
|
+
* @description Retrieves a registered hashing function
|
|
808
|
+
* @summary Fetches a hashing function from the cache by its key. Throws an error if the method is not registered.
|
|
809
|
+
*
|
|
810
|
+
* @param {string} key - The identifier of the hashing function to retrieve
|
|
811
|
+
* @return {HashingFunction} The requested hashing function
|
|
812
|
+
* @private
|
|
813
|
+
*/
|
|
520
814
|
static get(key) {
|
|
521
815
|
if (key in this.cache)
|
|
522
816
|
return this.cache[key];
|
|
523
817
|
throw new Error(`No hashing method registered under ${key}`);
|
|
524
818
|
}
|
|
819
|
+
/**
|
|
820
|
+
* @description Registers a new hashing function
|
|
821
|
+
* @summary Adds a new hashing function to the registry. Optionally sets it as the default method.
|
|
822
|
+
* Throws an error if a method with the same key is already registered.
|
|
823
|
+
*
|
|
824
|
+
* @param {string} key - The identifier for the hashing function
|
|
825
|
+
*/
|
|
525
826
|
static register(key, func, setDefault = false) {
|
|
526
827
|
if (key in this.cache)
|
|
527
828
|
throw new Error(`Hashing method ${key} already registered`);
|
|
@@ -601,7 +902,7 @@
|
|
|
601
902
|
* @property {string} BIGINT references the bigint primitive
|
|
602
903
|
*
|
|
603
904
|
* @constant Primitives
|
|
604
|
-
* @memberOf module:decorator-validation
|
|
905
|
+
* @memberOf module:decorator-validation
|
|
605
906
|
*/
|
|
606
907
|
exports.Primitives = void 0;
|
|
607
908
|
(function (Primitives) {
|
|
@@ -621,7 +922,7 @@
|
|
|
621
922
|
* @property {string} DATE
|
|
622
923
|
*
|
|
623
924
|
* @constant ReservedModels
|
|
624
|
-
* @memberOf module:decorator-validation
|
|
925
|
+
* @memberOf module:decorator-validation
|
|
625
926
|
*/
|
|
626
927
|
exports.ReservedModels = void 0;
|
|
627
928
|
(function (ReservedModels) {
|
|
@@ -647,7 +948,7 @@
|
|
|
647
948
|
* @property {string} BIGINT
|
|
648
949
|
*
|
|
649
950
|
* @constant jsTypes
|
|
650
|
-
* @memberOf module:decorator-validation
|
|
951
|
+
* @memberOf module:decorator-validation
|
|
651
952
|
*/
|
|
652
953
|
const jsTypes = [
|
|
653
954
|
"string",
|
|
@@ -663,13 +964,107 @@
|
|
|
663
964
|
];
|
|
664
965
|
|
|
665
966
|
/**
|
|
666
|
-
* @
|
|
667
|
-
* @
|
|
668
|
-
*
|
|
967
|
+
* @description Abstract base class for all validators in the validation framework
|
|
968
|
+
* @summary The Validator class provides the foundation for all validator implementations.
|
|
969
|
+
* It handles type checking, error message formatting, and defines the common interface
|
|
970
|
+
* that all validators must implement. This class is designed to be extended by specific
|
|
971
|
+
* validator implementations that provide concrete validation logic.
|
|
972
|
+
*
|
|
973
|
+
* @param {string} message - Default error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#DEFAULT}
|
|
974
|
+
* @param {string[]} acceptedTypes - Array of type names that this validator can validate
|
|
975
|
+
*
|
|
976
|
+
* @class Validator
|
|
977
|
+
* @abstract
|
|
978
|
+
*
|
|
979
|
+
* @example
|
|
980
|
+
* ```typescript
|
|
981
|
+
* // Example of extending the Validator class to create a custom validator
|
|
982
|
+
* class CustomValidator extends Validator<CustomValidatorOptions> {
|
|
983
|
+
* constructor(message: string = "Custom validation failed") {
|
|
984
|
+
* // Specify that this validator accepts String and Number types
|
|
985
|
+
* super(message, String.name, Number.name);
|
|
986
|
+
* }
|
|
987
|
+
*
|
|
988
|
+
* public hasErrors(value: any, options?: CustomValidatorOptions): string | undefined {
|
|
989
|
+
* // Implement custom validation logic
|
|
990
|
+
* if (someCondition) {
|
|
991
|
+
* return this.getMessage(options?.message || this.message);
|
|
992
|
+
* }
|
|
993
|
+
* return undefined; // No errors
|
|
994
|
+
* }
|
|
995
|
+
* }
|
|
996
|
+
* ```
|
|
997
|
+
*
|
|
998
|
+
* @mermaid
|
|
999
|
+
* sequenceDiagram
|
|
1000
|
+
* participant C as Client
|
|
1001
|
+
* participant V as Validator Subclass
|
|
1002
|
+
* participant B as Base Validator
|
|
1003
|
+
*
|
|
1004
|
+
* C->>V: new CustomValidator(message)
|
|
1005
|
+
* V->>B: super(message, acceptedTypes)
|
|
1006
|
+
* B->>B: Store message and types
|
|
1007
|
+
* B->>B: Wrap hasErrors with type checking
|
|
1008
|
+
* C->>V: hasErrors(value, options)
|
|
1009
|
+
* alt value type not in acceptedTypes
|
|
1010
|
+
* B-->>C: Type error message
|
|
1011
|
+
* else value type is accepted
|
|
1012
|
+
* V->>V: Custom validation logic
|
|
1013
|
+
* V-->>C: Validation result
|
|
1014
|
+
* end
|
|
1015
|
+
*
|
|
1016
|
+
* @category Validators
|
|
669
1017
|
*/
|
|
670
|
-
|
|
671
|
-
|
|
1018
|
+
class Validator {
|
|
1019
|
+
constructor(message = DEFAULT_ERROR_MESSAGES.DEFAULT, ...acceptedTypes) {
|
|
1020
|
+
this.message = message;
|
|
1021
|
+
if (acceptedTypes.length)
|
|
1022
|
+
this.acceptedTypes = acceptedTypes;
|
|
1023
|
+
if (this.acceptedTypes)
|
|
1024
|
+
this.hasErrors = this.checkTypeAndHasErrors(this.hasErrors.bind(this));
|
|
1025
|
+
}
|
|
1026
|
+
/**
|
|
1027
|
+
* @description Formats an error message with optional arguments
|
|
1028
|
+
* @summary Creates a formatted error message by replacing placeholders with provided arguments.
|
|
1029
|
+
* This method uses the string formatting utility to generate consistent error messages
|
|
1030
|
+
* across all validators.
|
|
1031
|
+
*
|
|
1032
|
+
* @param {string} message - The message template with placeholders
|
|
1033
|
+
* @param {...any} args - Values to insert into the message template
|
|
1034
|
+
* @return {string} The formatted error message
|
|
1035
|
+
* @protected
|
|
1036
|
+
*/
|
|
1037
|
+
getMessage(message, ...args) {
|
|
1038
|
+
return sf(message, ...args);
|
|
1039
|
+
}
|
|
1040
|
+
/**
|
|
1041
|
+
* @description Creates a type-checking wrapper around the hasErrors method
|
|
1042
|
+
* @summary Wraps the hasErrors method with type validation logic to ensure that
|
|
1043
|
+
* the value being validated is of an accepted type before performing specific validation.
|
|
1044
|
+
* This method is called during construction if acceptedTypes are provided.
|
|
1045
|
+
*
|
|
1046
|
+
* @param {Function} unbound - The original hasErrors method to be wrapped
|
|
1047
|
+
* @return {Function} A new function that performs type checking before calling the original method
|
|
1048
|
+
* @private
|
|
1049
|
+
*/
|
|
1050
|
+
checkTypeAndHasErrors(unbound) {
|
|
1051
|
+
return function (value, ...args) {
|
|
1052
|
+
if (value === undefined || !this.acceptedTypes)
|
|
1053
|
+
return unbound(value, ...args);
|
|
1054
|
+
if (!reflection.Reflection.checkTypes(value, this.acceptedTypes))
|
|
1055
|
+
return this.getMessage(DEFAULT_ERROR_MESSAGES.TYPE, this.acceptedTypes.join(", "), typeof value);
|
|
1056
|
+
return unbound(value, ...args);
|
|
1057
|
+
}.bind(this);
|
|
1058
|
+
}
|
|
1059
|
+
/**
|
|
1060
|
+
* @summary Duck typing for Validators
|
|
1061
|
+
* @param val
|
|
1062
|
+
*/
|
|
1063
|
+
static isValidator(val) {
|
|
1064
|
+
return val.constructor && !!val["hasErrors"];
|
|
1065
|
+
}
|
|
672
1066
|
}
|
|
1067
|
+
|
|
673
1068
|
/**
|
|
674
1069
|
* @summary Base Implementation of a Validator Registry
|
|
675
1070
|
*
|
|
@@ -708,7 +1103,7 @@
|
|
|
708
1103
|
if (!(validatorKey in this.cache))
|
|
709
1104
|
return undefined;
|
|
710
1105
|
const classOrInstance = this.cache[validatorKey];
|
|
711
|
-
if (isValidator(classOrInstance))
|
|
1106
|
+
if (Validator.isValidator(classOrInstance))
|
|
712
1107
|
return classOrInstance;
|
|
713
1108
|
const constructor = classOrInstance.default || classOrInstance;
|
|
714
1109
|
const instance = new constructor();
|
|
@@ -722,7 +1117,7 @@
|
|
|
722
1117
|
*/
|
|
723
1118
|
register(...validator) {
|
|
724
1119
|
validator.forEach((v) => {
|
|
725
|
-
if (isValidator(v)) {
|
|
1120
|
+
if (Validator.isValidator(v)) {
|
|
726
1121
|
// const k =
|
|
727
1122
|
if (v.validationKey in this.cache)
|
|
728
1123
|
return;
|
|
@@ -821,8 +1216,8 @@
|
|
|
821
1216
|
* @prop {string[]} [propsToIgnore] object properties to ignore in the validation
|
|
822
1217
|
*
|
|
823
1218
|
* @function validate
|
|
824
|
-
* @memberOf module:decorator-validation
|
|
825
|
-
* @category
|
|
1219
|
+
* @memberOf module:decorator-validation
|
|
1220
|
+
* @category Model
|
|
826
1221
|
*/
|
|
827
1222
|
function validate(obj, ...propsToIgnore) {
|
|
828
1223
|
const decoratedProperties = [];
|
|
@@ -897,7 +1292,7 @@
|
|
|
897
1292
|
}
|
|
898
1293
|
const validate = (prop, value) => {
|
|
899
1294
|
if (typeof value === "object" || typeof value === "function")
|
|
900
|
-
return isModel(value)
|
|
1295
|
+
return Model.isModel(value)
|
|
901
1296
|
? value.hasErrors()
|
|
902
1297
|
: allowedTypes.includes(typeof value)
|
|
903
1298
|
? undefined
|
|
@@ -943,49 +1338,68 @@
|
|
|
943
1338
|
|
|
944
1339
|
let modelBuilderFunction;
|
|
945
1340
|
let actingModelRegistry;
|
|
946
|
-
function isPropertyModel(target, attribute) {
|
|
947
|
-
if (isModel(target[attribute]))
|
|
948
|
-
return true;
|
|
949
|
-
const metadata = Reflect.getMetadata(exports.ModelKeys.TYPE, target, attribute);
|
|
950
|
-
return Model.get(metadata.name) ? metadata.name : undefined;
|
|
951
|
-
}
|
|
952
|
-
/**
|
|
953
|
-
* @summary For Serialization/deserialization purposes.
|
|
954
|
-
* @description Reads the {@link ModelKeys.ANCHOR} property of a {@link Model} to discover the class to instantiate
|
|
955
|
-
*
|
|
956
|
-
* @function isModel
|
|
957
|
-
* @memberOf module:decorator-validation.Validation
|
|
958
|
-
* @category Validation
|
|
959
|
-
*/
|
|
960
|
-
function isModel(target) {
|
|
961
|
-
try {
|
|
962
|
-
return target instanceof Model || !!Model.getMetadata(target);
|
|
963
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
964
|
-
}
|
|
965
|
-
catch (e) {
|
|
966
|
-
return false;
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
1341
|
/**
|
|
970
|
-
* @
|
|
1342
|
+
* @description Registry manager for model constructors that enables serialization and rebuilding
|
|
1343
|
+
* @summary The ModelRegistryManager implements the ModelRegistry interface and provides
|
|
1344
|
+
* functionality for registering, retrieving, and building model instances. It maintains
|
|
1345
|
+
* a cache of model constructors indexed by name, allowing for efficient lookup and instantiation.
|
|
1346
|
+
* This class is essential for the serialization and deserialization of model objects.
|
|
971
1347
|
*
|
|
972
|
-
* @param {string}
|
|
973
|
-
* @param {function(Record<string, any>): boolean} [testFunction] method to test if the provided object is a Model Object. defaults to {@link isModel}
|
|
1348
|
+
* @param {function(Record<string, any>): boolean} [testFunction] - Function to test if an object is a model, defaults to {@link isModel}
|
|
974
1349
|
*
|
|
975
1350
|
* @class ModelRegistryManager
|
|
976
|
-
* @
|
|
977
|
-
*
|
|
1351
|
+
* @template M Type of model that can be registered, must extend Model
|
|
1352
|
+
* @implements ModelRegistry<M>
|
|
978
1353
|
* @category Model
|
|
1354
|
+
*
|
|
1355
|
+
* @example
|
|
1356
|
+
* ```typescript
|
|
1357
|
+
* // Create a model registry
|
|
1358
|
+
* const registry = new ModelRegistryManager();
|
|
1359
|
+
*
|
|
1360
|
+
* // Register a model class
|
|
1361
|
+
* registry.register(User);
|
|
1362
|
+
*
|
|
1363
|
+
* // Retrieve a model constructor by name
|
|
1364
|
+
* const UserClass = registry.get("User");
|
|
1365
|
+
*
|
|
1366
|
+
* // Build a model instance from a plain object
|
|
1367
|
+
* const userData = { name: "John", age: 30 };
|
|
1368
|
+
* const user = registry.build(userData, "User");
|
|
1369
|
+
* ```
|
|
1370
|
+
*
|
|
1371
|
+
* @mermaid
|
|
1372
|
+
* sequenceDiagram
|
|
1373
|
+
* participant C as Client
|
|
1374
|
+
* participant R as ModelRegistryManager
|
|
1375
|
+
* participant M as Model Class
|
|
1376
|
+
*
|
|
1377
|
+
* C->>R: new ModelRegistryManager(testFunction)
|
|
1378
|
+
* C->>R: register(ModelClass)
|
|
1379
|
+
* R->>R: Store in cache
|
|
1380
|
+
* C->>R: get("ModelName")
|
|
1381
|
+
* R-->>C: ModelClass constructor
|
|
1382
|
+
* C->>R: build(data, "ModelName")
|
|
1383
|
+
* R->>R: Get constructor from cache
|
|
1384
|
+
* R->>M: new ModelClass(data)
|
|
1385
|
+
* M-->>R: Model instance
|
|
1386
|
+
* R-->>C: Model instance
|
|
979
1387
|
*/
|
|
980
1388
|
class ModelRegistryManager {
|
|
981
|
-
constructor(testFunction = isModel) {
|
|
1389
|
+
constructor(testFunction = Model.isModel) {
|
|
982
1390
|
this.cache = {};
|
|
983
1391
|
this.testFunction = testFunction;
|
|
984
1392
|
}
|
|
985
1393
|
/**
|
|
986
|
-
* @
|
|
987
|
-
* @
|
|
988
|
-
*
|
|
1394
|
+
* @description Registers a model constructor with the registry
|
|
1395
|
+
* @summary Adds a model constructor to the registry cache, making it available for
|
|
1396
|
+
* later retrieval and instantiation. If no name is provided, the constructor's name
|
|
1397
|
+
* property is used as the key in the registry.
|
|
1398
|
+
*
|
|
1399
|
+
* @param {ModelConstructor<M>} constructor - The model constructor to register
|
|
1400
|
+
* @param {string} [name] - Optional name to register the constructor under, defaults to constructor.name
|
|
1401
|
+
* @return {void}
|
|
1402
|
+
* @throws {Error} If the constructor is not a function
|
|
989
1403
|
*/
|
|
990
1404
|
register(constructor, name) {
|
|
991
1405
|
if (typeof constructor !== "function")
|
|
@@ -1027,7 +1441,7 @@
|
|
|
1027
1441
|
*
|
|
1028
1442
|
* @param {Array<Constructor<T>> | Array<{name: string, constructor: Constructor<T>}>} [models]
|
|
1029
1443
|
*
|
|
1030
|
-
* @memberOf module:decorator-validation
|
|
1444
|
+
* @memberOf module:decorator-validation
|
|
1031
1445
|
* @category Model
|
|
1032
1446
|
*/
|
|
1033
1447
|
function bulkModelRegister(...models) {
|
|
@@ -1044,9 +1458,10 @@
|
|
|
1044
1458
|
* - Have all their required properties marked with '!';
|
|
1045
1459
|
* - Have all their optional properties marked as '?':
|
|
1046
1460
|
*
|
|
1047
|
-
* @param {Model
|
|
1461
|
+
* @param {ModelArg<Model>} model base object from which to populate properties from
|
|
1048
1462
|
*
|
|
1049
1463
|
* @class Model
|
|
1464
|
+
* @category Model
|
|
1050
1465
|
* @abstract
|
|
1051
1466
|
* @implements Validatable
|
|
1052
1467
|
* @implements Serializable
|
|
@@ -1145,7 +1560,7 @@
|
|
|
1145
1560
|
obj[prop] || undefined;
|
|
1146
1561
|
if (typeof self[prop] !== "object")
|
|
1147
1562
|
continue;
|
|
1148
|
-
const propM = isPropertyModel(self, prop);
|
|
1563
|
+
const propM = Model.isPropertyModel(self, prop);
|
|
1149
1564
|
if (propM) {
|
|
1150
1565
|
try {
|
|
1151
1566
|
self[prop] = Model.build(self[prop], typeof propM === "string" ? propM : undefined);
|
|
@@ -1319,6 +1734,53 @@
|
|
|
1319
1734
|
static key(str) {
|
|
1320
1735
|
return exports.ModelKeys.REFLECT + str;
|
|
1321
1736
|
}
|
|
1737
|
+
/**
|
|
1738
|
+
* @description Determines if an object is a model instance or has model metadata
|
|
1739
|
+
* @summary Checks whether a given object is either an instance of the Model class or
|
|
1740
|
+
* has model metadata attached to it. This function is essential for serialization and
|
|
1741
|
+
* deserialization processes, as it helps identify model objects that need special handling.
|
|
1742
|
+
* It safely handles potential errors during metadata retrieval.
|
|
1743
|
+
*
|
|
1744
|
+
* @param {Record<string, any>} target - The object to check
|
|
1745
|
+
* @return {boolean} True if the object is a model instance or has model metadata, false otherwise
|
|
1746
|
+
*
|
|
1747
|
+
* @example
|
|
1748
|
+
* ```typescript
|
|
1749
|
+
* // Check if an object is a model
|
|
1750
|
+
* const user = new User({ name: "John" });
|
|
1751
|
+
* const isUserModel = isModel(user); // true
|
|
1752
|
+
*
|
|
1753
|
+
* // Check a plain object
|
|
1754
|
+
* const plainObject = { name: "John" };
|
|
1755
|
+
* const isPlainObjectModel = isModel(plainObject); // false
|
|
1756
|
+
* ```
|
|
1757
|
+
*/
|
|
1758
|
+
static isModel(target) {
|
|
1759
|
+
try {
|
|
1760
|
+
return target instanceof Model || !!Model.getMetadata(target);
|
|
1761
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1762
|
+
}
|
|
1763
|
+
catch (e) {
|
|
1764
|
+
return false;
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
/**
|
|
1768
|
+
* @description Checks if a property of a model is itself a model or has a model type
|
|
1769
|
+
* @summary Determines whether a specific property of a model instance is either a model instance
|
|
1770
|
+
* or has a type that is registered as a model. This function is used for model serialization
|
|
1771
|
+
* and deserialization to properly handle nested models.
|
|
1772
|
+
* @template M extends {@link Model}
|
|
1773
|
+
* @param {M} target - The model instance to check
|
|
1774
|
+
* @param {string} attribute - The property name to check
|
|
1775
|
+
* @return {boolean | string | undefined} Returns true if the property is a model instance,
|
|
1776
|
+
* the model name if the property has a model type, or undefined if not a model
|
|
1777
|
+
*/
|
|
1778
|
+
static isPropertyModel(target, attribute) {
|
|
1779
|
+
if (Model.isModel(target[attribute]))
|
|
1780
|
+
return true;
|
|
1781
|
+
const metadata = Reflect.getMetadata(exports.ModelKeys.TYPE, target, attribute);
|
|
1782
|
+
return Model.get(metadata.name) ? metadata.name : undefined;
|
|
1783
|
+
}
|
|
1322
1784
|
}
|
|
1323
1785
|
|
|
1324
1786
|
const DefaultSerializationMethod = "json";
|
|
@@ -1333,7 +1795,7 @@
|
|
|
1333
1795
|
* @class JSONSerializer
|
|
1334
1796
|
* @implements Serializer
|
|
1335
1797
|
*
|
|
1336
|
-
* @category
|
|
1798
|
+
* @category Model
|
|
1337
1799
|
*/
|
|
1338
1800
|
class JSONSerializer {
|
|
1339
1801
|
constructor() { }
|
|
@@ -1409,84 +1871,6 @@
|
|
|
1409
1871
|
}
|
|
1410
1872
|
}
|
|
1411
1873
|
|
|
1412
|
-
/******************************************************************************
|
|
1413
|
-
Copyright (c) Microsoft Corporation.
|
|
1414
|
-
|
|
1415
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
1416
|
-
purpose with or without fee is hereby granted.
|
|
1417
|
-
|
|
1418
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
1419
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
1420
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
1421
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
1422
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
1423
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
1424
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
1425
|
-
***************************************************************************** */
|
|
1426
|
-
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
function __decorate(decorators, target, key, desc) {
|
|
1430
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1431
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1432
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1433
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1434
|
-
}
|
|
1435
|
-
|
|
1436
|
-
function __metadata(metadataKey, metadataValue) {
|
|
1437
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
|
-
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
1441
|
-
var e = new Error(message);
|
|
1442
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
1443
|
-
};
|
|
1444
|
-
|
|
1445
|
-
/**
|
|
1446
|
-
* @summary Base Implementation for Validators
|
|
1447
|
-
* @description Provides the underlying functionality for {@link Validator}s
|
|
1448
|
-
*
|
|
1449
|
-
* @param {string} validationKey the key to register the validator under
|
|
1450
|
-
* @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#DEFAULT}
|
|
1451
|
-
* @param {string[]} [acceptedTypes] defines the value types this validator can validate
|
|
1452
|
-
*
|
|
1453
|
-
* @class Validator
|
|
1454
|
-
* @abstract
|
|
1455
|
-
* @category Validators
|
|
1456
|
-
*/
|
|
1457
|
-
class Validator {
|
|
1458
|
-
constructor(message = DEFAULT_ERROR_MESSAGES.DEFAULT, ...acceptedTypes) {
|
|
1459
|
-
this.message = message;
|
|
1460
|
-
if (acceptedTypes.length)
|
|
1461
|
-
this.acceptedTypes = acceptedTypes;
|
|
1462
|
-
if (this.acceptedTypes)
|
|
1463
|
-
this.hasErrors = this.checkTypeAndHasErrors(this.hasErrors.bind(this));
|
|
1464
|
-
}
|
|
1465
|
-
/**
|
|
1466
|
-
* @summary builds the error message
|
|
1467
|
-
* @param {string} message
|
|
1468
|
-
* @param {any[]} args
|
|
1469
|
-
* @protected
|
|
1470
|
-
*/
|
|
1471
|
-
getMessage(message, ...args) {
|
|
1472
|
-
return sf(message, ...args);
|
|
1473
|
-
}
|
|
1474
|
-
/**
|
|
1475
|
-
* @summary Validates type
|
|
1476
|
-
* @param {any} unbound
|
|
1477
|
-
* @private
|
|
1478
|
-
*/
|
|
1479
|
-
checkTypeAndHasErrors(unbound) {
|
|
1480
|
-
return function (value, ...args) {
|
|
1481
|
-
if (value === undefined || !this.acceptedTypes)
|
|
1482
|
-
return unbound(value, ...args);
|
|
1483
|
-
if (!reflection.Reflection.checkTypes(value, this.acceptedTypes))
|
|
1484
|
-
return this.getMessage(DEFAULT_ERROR_MESSAGES.TYPE, this.acceptedTypes.join(", "), typeof value);
|
|
1485
|
-
return unbound(value, ...args);
|
|
1486
|
-
}.bind(this);
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
|
-
|
|
1490
1874
|
/**
|
|
1491
1875
|
* @summary Marks the class as a validator for a certain key.
|
|
1492
1876
|
* @description Registers the class in the {@link Validation} with the provided key
|
|
@@ -1511,26 +1895,58 @@
|
|
|
1511
1895
|
}
|
|
1512
1896
|
|
|
1513
1897
|
/**
|
|
1514
|
-
* @
|
|
1515
|
-
*
|
|
1516
|
-
*
|
|
1517
|
-
*
|
|
1898
|
+
* @description Validator for checking if a value is a valid date
|
|
1899
|
+
* @summary The DateValidator checks if a value is a valid date object or a string that can be converted to a valid date.
|
|
1900
|
+
* It validates that the value represents a real date and not an invalid date like "2023-02-31".
|
|
1901
|
+
* @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#DATE}
|
|
1518
1902
|
* @class DateValidator
|
|
1519
1903
|
* @extends Validator
|
|
1520
1904
|
*
|
|
1521
1905
|
* @category Validators
|
|
1906
|
+
* @example
|
|
1907
|
+
* ```typescript
|
|
1908
|
+
* // Create a date validator with default error message
|
|
1909
|
+
* const dateValidator = new DateValidator();
|
|
1910
|
+
*
|
|
1911
|
+
* // Create a date validator with custom error message
|
|
1912
|
+
* const customDateValidator = new DateValidator("Please enter a valid date");
|
|
1913
|
+
*
|
|
1914
|
+
* // Validate a date
|
|
1915
|
+
* const result = dateValidator.hasErrors(new Date()); // undefined (valid)
|
|
1916
|
+
* const invalidResult = dateValidator.hasErrors("not a date"); // Returns error message (invalid)
|
|
1917
|
+
* ```
|
|
1918
|
+
* @mermaid
|
|
1919
|
+
* sequenceDiagram
|
|
1920
|
+
* participant C as Client
|
|
1921
|
+
* participant V as DateValidator
|
|
1922
|
+
*
|
|
1923
|
+
* C->>V: new DateValidator(message)
|
|
1924
|
+
* C->>V: hasErrors(value, options)
|
|
1925
|
+
* alt value is undefined
|
|
1926
|
+
* V-->>C: undefined (valid)
|
|
1927
|
+
* else value is string
|
|
1928
|
+
* V->>V: Convert to Date
|
|
1929
|
+
* end
|
|
1930
|
+
* alt Date is invalid (NaN)
|
|
1931
|
+
* V-->>C: Error message
|
|
1932
|
+
* else Date is valid
|
|
1933
|
+
* V-->>C: undefined (valid)
|
|
1934
|
+
* end
|
|
1522
1935
|
*/
|
|
1523
1936
|
exports.DateValidator = class DateValidator extends Validator {
|
|
1524
1937
|
constructor(message = DEFAULT_ERROR_MESSAGES.DATE) {
|
|
1525
1938
|
super(message, Number.name, Date.name, String.name);
|
|
1526
1939
|
}
|
|
1527
1940
|
/**
|
|
1528
|
-
* @
|
|
1941
|
+
* @description Checks if the provided value is a valid date
|
|
1942
|
+
* @summary Validates that the given value is a valid date. If the value is a string,
|
|
1943
|
+
* it attempts to convert it to a Date object. Returns an error message if the date is invalid,
|
|
1944
|
+
* or undefined if the date is valid or if the value is undefined.
|
|
1529
1945
|
*
|
|
1530
|
-
* @param {Date | string} value
|
|
1531
|
-
* @param {DateValidatorOptions} [options]
|
|
1946
|
+
* @param {Date | string} value - The value to validate, can be a Date object or a string
|
|
1947
|
+
* @param {DateValidatorOptions} [options={}] - Optional configuration options for the validator
|
|
1532
1948
|
*
|
|
1533
|
-
* @return {string | undefined}
|
|
1949
|
+
* @return {string | undefined} Error message if validation fails, undefined if validation passes
|
|
1534
1950
|
*
|
|
1535
1951
|
* @override
|
|
1536
1952
|
*
|
|
@@ -1547,21 +1963,78 @@
|
|
|
1547
1963
|
}
|
|
1548
1964
|
}
|
|
1549
1965
|
};
|
|
1550
|
-
exports.DateValidator = __decorate([
|
|
1966
|
+
exports.DateValidator = tslib.__decorate([
|
|
1551
1967
|
validator(ValidationKeys.DATE),
|
|
1552
|
-
__metadata("design:paramtypes", [String])
|
|
1968
|
+
tslib.__metadata("design:paramtypes", [String])
|
|
1553
1969
|
], exports.DateValidator);
|
|
1554
1970
|
|
|
1971
|
+
/**
|
|
1972
|
+
* @description Regular expression for parsing string patterns with flags
|
|
1973
|
+
* @summary This regular expression is used to parse string patterns in the format "/pattern/flags".
|
|
1974
|
+
* It captures the pattern and flags separately, allowing the creation of a RegExp object
|
|
1975
|
+
* with the appropriate flags.
|
|
1976
|
+
*
|
|
1977
|
+
* @const {RegExp}
|
|
1978
|
+
* @memberOf module:decorator-validation
|
|
1979
|
+
* @category Validation
|
|
1980
|
+
*/
|
|
1555
1981
|
const regexpParser = new RegExp("^/(.+)/([gimus]*)$");
|
|
1556
1982
|
/**
|
|
1557
|
-
* @
|
|
1983
|
+
* @description Validator for checking if a string matches a regular expression pattern
|
|
1984
|
+
* @summary The PatternValidator checks if a string value matches a specified regular expression pattern.
|
|
1985
|
+
* It supports both RegExp objects and string representations of patterns, including those with flags.
|
|
1986
|
+
* This validator is the foundation for specialized validators like EmailValidator and URLValidator,
|
|
1987
|
+
* and is typically used with the @pattern decorator.
|
|
1558
1988
|
*
|
|
1559
|
-
* @param {string} [
|
|
1560
|
-
* @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#PATTERN}
|
|
1989
|
+
* @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#PATTERN}
|
|
1561
1990
|
*
|
|
1562
1991
|
* @class PatternValidator
|
|
1563
1992
|
* @extends Validator
|
|
1564
1993
|
*
|
|
1994
|
+
* @example
|
|
1995
|
+
* ```typescript
|
|
1996
|
+
* // Create a pattern validator with default error message
|
|
1997
|
+
* const patternValidator = new PatternValidator();
|
|
1998
|
+
*
|
|
1999
|
+
* // Create a pattern validator with custom error message
|
|
2000
|
+
* const customPatternValidator = new PatternValidator("Value must match the required format");
|
|
2001
|
+
*
|
|
2002
|
+
* // Validate using a RegExp object
|
|
2003
|
+
* const regexOptions = { pattern: /^[A-Z][a-z]+$/ };
|
|
2004
|
+
* patternValidator.hasErrors("Hello", regexOptions); // undefined (valid)
|
|
2005
|
+
* patternValidator.hasErrors("hello", regexOptions); // Returns error message (invalid)
|
|
2006
|
+
*
|
|
2007
|
+
* // Validate using a string pattern
|
|
2008
|
+
* const stringOptions = { pattern: "^\\d{3}-\\d{2}-\\d{4}$" };
|
|
2009
|
+
* patternValidator.hasErrors("123-45-6789", stringOptions); // undefined (valid)
|
|
2010
|
+
*
|
|
2011
|
+
* // Validate using a string pattern with flags
|
|
2012
|
+
* const flagOptions = { pattern: "/^hello$/i" };
|
|
2013
|
+
* patternValidator.hasErrors("Hello", flagOptions); // undefined (valid)
|
|
2014
|
+
* ```
|
|
2015
|
+
*
|
|
2016
|
+
* @mermaid
|
|
2017
|
+
* sequenceDiagram
|
|
2018
|
+
* participant C as Client
|
|
2019
|
+
* participant V as PatternValidator
|
|
2020
|
+
*
|
|
2021
|
+
* C->>V: new PatternValidator(message)
|
|
2022
|
+
* C->>V: hasErrors(value, options)
|
|
2023
|
+
* alt value is empty
|
|
2024
|
+
* V-->>C: undefined (valid)
|
|
2025
|
+
* else pattern is missing
|
|
2026
|
+
* V-->>C: Error: Missing Pattern
|
|
2027
|
+
* else pattern is string
|
|
2028
|
+
* V->>V: getPattern(pattern)
|
|
2029
|
+
* end
|
|
2030
|
+
* V->>V: Reset pattern.lastIndex
|
|
2031
|
+
* V->>V: Test value against pattern
|
|
2032
|
+
* alt pattern test passes
|
|
2033
|
+
* V-->>C: undefined (valid)
|
|
2034
|
+
* else pattern test fails
|
|
2035
|
+
* V-->>C: Error message
|
|
2036
|
+
* end
|
|
2037
|
+
*
|
|
1565
2038
|
* @category Validators
|
|
1566
2039
|
*/
|
|
1567
2040
|
exports.PatternValidator = class PatternValidator extends Validator {
|
|
@@ -1569,9 +2042,12 @@
|
|
|
1569
2042
|
super(message, "string");
|
|
1570
2043
|
}
|
|
1571
2044
|
/**
|
|
1572
|
-
* @
|
|
2045
|
+
* @description Converts a string pattern to a RegExp object
|
|
2046
|
+
* @summary Parses a string representation of a regular expression and converts it to a RegExp object.
|
|
2047
|
+
* It handles both simple string patterns and patterns with flags in the format "/pattern/flags".
|
|
1573
2048
|
*
|
|
1574
|
-
* @param {string} pattern
|
|
2049
|
+
* @param {string} pattern - The string pattern to convert
|
|
2050
|
+
* @return {RegExp} A RegExp object created from the string pattern
|
|
1575
2051
|
* @private
|
|
1576
2052
|
*/
|
|
1577
2053
|
getPattern(pattern) {
|
|
@@ -1581,12 +2057,18 @@
|
|
|
1581
2057
|
return new RegExp(match[1], match[2]);
|
|
1582
2058
|
}
|
|
1583
2059
|
/**
|
|
1584
|
-
* @
|
|
2060
|
+
* @description Checks if a string matches a regular expression pattern
|
|
2061
|
+
* @summary Validates that the provided string matches the pattern specified in the options.
|
|
2062
|
+
* If the pattern is provided as a string, it's converted to a RegExp object using the getPattern method.
|
|
2063
|
+
* The method resets the pattern's lastIndex property to ensure consistent validation results
|
|
2064
|
+
* for patterns with the global flag.
|
|
1585
2065
|
*
|
|
1586
|
-
* @param {string} value
|
|
1587
|
-
* @param {PatternValidatorOptions} options
|
|
2066
|
+
* @param {string} value - The string to validate against the pattern
|
|
2067
|
+
* @param {PatternValidatorOptions} options - Configuration options containing the pattern
|
|
1588
2068
|
*
|
|
1589
|
-
* @return {string | undefined}
|
|
2069
|
+
* @return {string | undefined} Error message if validation fails, undefined if validation passes
|
|
2070
|
+
*
|
|
2071
|
+
* @throws {Error} If no pattern is provided in the options
|
|
1590
2072
|
*
|
|
1591
2073
|
* @override
|
|
1592
2074
|
*
|
|
@@ -1605,19 +2087,48 @@
|
|
|
1605
2087
|
: undefined;
|
|
1606
2088
|
}
|
|
1607
2089
|
};
|
|
1608
|
-
exports.PatternValidator = __decorate([
|
|
2090
|
+
exports.PatternValidator = tslib.__decorate([
|
|
1609
2091
|
validator(ValidationKeys.PATTERN),
|
|
1610
|
-
__metadata("design:paramtypes", [String])
|
|
2092
|
+
tslib.__metadata("design:paramtypes", [String])
|
|
1611
2093
|
], exports.PatternValidator);
|
|
1612
2094
|
|
|
1613
2095
|
/**
|
|
1614
|
-
* @
|
|
2096
|
+
* @description Validator for checking if a string is a valid email address
|
|
2097
|
+
* @summary The EmailValidator checks if a string matches a standard email address pattern.
|
|
2098
|
+
* It extends the PatternValidator and uses a predefined email regex pattern to validate email addresses.
|
|
2099
|
+
* This validator is typically used with the @email decorator.
|
|
1615
2100
|
*
|
|
1616
|
-
* @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#EMAIL}
|
|
2101
|
+
* @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#EMAIL}
|
|
1617
2102
|
*
|
|
1618
2103
|
* @class EmailValidator
|
|
1619
2104
|
* @extends PatternValidator
|
|
1620
2105
|
*
|
|
2106
|
+
* @example
|
|
2107
|
+
* ```typescript
|
|
2108
|
+
* // Create an email validator with default error message
|
|
2109
|
+
* const emailValidator = new EmailValidator();
|
|
2110
|
+
*
|
|
2111
|
+
* // Create an email validator with custom error message
|
|
2112
|
+
* const customEmailValidator = new EmailValidator("Please enter a valid email address");
|
|
2113
|
+
*
|
|
2114
|
+
* // Validate an email
|
|
2115
|
+
* const result = emailValidator.hasErrors("user@example.com"); // undefined (valid)
|
|
2116
|
+
* const invalidResult = emailValidator.hasErrors("invalid-email"); // Returns error message (invalid)
|
|
2117
|
+
* ```
|
|
2118
|
+
*
|
|
2119
|
+
* @mermaid
|
|
2120
|
+
* sequenceDiagram
|
|
2121
|
+
* participant C as Client
|
|
2122
|
+
* participant E as EmailValidator
|
|
2123
|
+
* participant P as PatternValidator
|
|
2124
|
+
*
|
|
2125
|
+
* C->>E: new EmailValidator(message)
|
|
2126
|
+
* E->>P: super(message)
|
|
2127
|
+
* C->>E: hasErrors(value, options)
|
|
2128
|
+
* E->>P: super.hasErrors(value, options with EMAIL pattern)
|
|
2129
|
+
* P-->>E: validation result
|
|
2130
|
+
* E-->>C: validation result
|
|
2131
|
+
*
|
|
1621
2132
|
* @category Validators
|
|
1622
2133
|
*/
|
|
1623
2134
|
exports.EmailValidator = class EmailValidator extends exports.PatternValidator {
|
|
@@ -1625,16 +2136,19 @@
|
|
|
1625
2136
|
super(message);
|
|
1626
2137
|
}
|
|
1627
2138
|
/**
|
|
1628
|
-
* @
|
|
2139
|
+
* @description Checks if a string is a valid email address
|
|
2140
|
+
* @summary Validates that the provided string matches the email pattern.
|
|
2141
|
+
* This method extends the PatternValidator's hasErrors method by ensuring
|
|
2142
|
+
* the email pattern is used, even if not explicitly provided in the options.
|
|
1629
2143
|
*
|
|
1630
|
-
* @param {string} value
|
|
1631
|
-
* @param {PatternValidatorOptions} [options]
|
|
2144
|
+
* @param {string} value - The string to validate as an email address
|
|
2145
|
+
* @param {PatternValidatorOptions} [options={}] - Optional configuration options
|
|
1632
2146
|
*
|
|
1633
|
-
* @return {string | undefined}
|
|
2147
|
+
* @return {string | undefined} Error message if validation fails, undefined if validation passes
|
|
1634
2148
|
*
|
|
1635
2149
|
* @override
|
|
1636
2150
|
*
|
|
1637
|
-
* @see
|
|
2151
|
+
* @see PatternValidator#hasErrors
|
|
1638
2152
|
*/
|
|
1639
2153
|
hasErrors(value, options = {}) {
|
|
1640
2154
|
return super.hasErrors(value, {
|
|
@@ -1643,19 +2157,54 @@
|
|
|
1643
2157
|
});
|
|
1644
2158
|
}
|
|
1645
2159
|
};
|
|
1646
|
-
exports.EmailValidator = __decorate([
|
|
2160
|
+
exports.EmailValidator = tslib.__decorate([
|
|
1647
2161
|
validator(ValidationKeys.EMAIL),
|
|
1648
|
-
__metadata("design:paramtypes", [String])
|
|
2162
|
+
tslib.__metadata("design:paramtypes", [String])
|
|
1649
2163
|
], exports.EmailValidator);
|
|
1650
2164
|
|
|
1651
2165
|
/**
|
|
1652
|
-
* @
|
|
2166
|
+
* @description Validator for checking if elements in a list or set match expected types
|
|
2167
|
+
* @summary The ListValidator validates that all elements in an array or Set match the expected types.
|
|
2168
|
+
* It checks each element against a list of allowed class types and ensures type consistency.
|
|
2169
|
+
* This validator is typically used with the @list decorator.
|
|
1653
2170
|
*
|
|
1654
|
-
* @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#LIST}
|
|
2171
|
+
* @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#LIST}
|
|
1655
2172
|
*
|
|
1656
2173
|
* @class ListValidator
|
|
1657
2174
|
* @extends Validator
|
|
1658
2175
|
*
|
|
2176
|
+
* @example
|
|
2177
|
+
* ```typescript
|
|
2178
|
+
* // Create a list validator with default error message
|
|
2179
|
+
* const listValidator = new ListValidator();
|
|
2180
|
+
*
|
|
2181
|
+
* // Create a list validator with custom error message
|
|
2182
|
+
* const customListValidator = new ListValidator("All items must be of the specified type");
|
|
2183
|
+
*
|
|
2184
|
+
* // Validate a list
|
|
2185
|
+
* const options = { clazz: ["String", "Number"] };
|
|
2186
|
+
* const result = listValidator.hasErrors(["test", 123], options); // undefined (valid)
|
|
2187
|
+
* const invalidResult = listValidator.hasErrors([new Date()], options); // Returns error message (invalid)
|
|
2188
|
+
* ```
|
|
2189
|
+
*
|
|
2190
|
+
* @mermaid
|
|
2191
|
+
* sequenceDiagram
|
|
2192
|
+
* participant C as Client
|
|
2193
|
+
* participant V as ListValidator
|
|
2194
|
+
*
|
|
2195
|
+
* C->>V: new ListValidator(message)
|
|
2196
|
+
* C->>V: hasErrors(value, options)
|
|
2197
|
+
* alt value is empty
|
|
2198
|
+
* V-->>C: undefined (valid)
|
|
2199
|
+
* else value has elements
|
|
2200
|
+
* V->>V: Check each element's type
|
|
2201
|
+
* alt All elements match allowed types
|
|
2202
|
+
* V-->>C: undefined (valid)
|
|
2203
|
+
* else Some elements don't match
|
|
2204
|
+
* V-->>C: Error message
|
|
2205
|
+
* end
|
|
2206
|
+
* end
|
|
2207
|
+
*
|
|
1659
2208
|
* @category Validators
|
|
1660
2209
|
*/
|
|
1661
2210
|
exports.ListValidator = class ListValidator extends Validator {
|
|
@@ -1663,12 +2212,15 @@
|
|
|
1663
2212
|
super(message, Array.name, Set.name);
|
|
1664
2213
|
}
|
|
1665
2214
|
/**
|
|
1666
|
-
* @
|
|
2215
|
+
* @description Checks if all elements in a list or set match the expected types
|
|
2216
|
+
* @summary Validates that each element in the provided array or Set matches one of the
|
|
2217
|
+
* class types specified in the options. For object types, it checks the constructor name,
|
|
2218
|
+
* and for primitive types, it compares against the lowercase type name.
|
|
1667
2219
|
*
|
|
1668
|
-
* @param {any[] | Set<any>} value
|
|
1669
|
-
* @param {ListValidatorOptions} options
|
|
2220
|
+
* @param {any[] | Set<any>} value - The array or Set to validate
|
|
2221
|
+
* @param {ListValidatorOptions} options - Configuration options containing the allowed class types
|
|
1670
2222
|
*
|
|
1671
|
-
* @return {string | undefined}
|
|
2223
|
+
* @return {string | undefined} Error message if validation fails, undefined if validation passes
|
|
1672
2224
|
*
|
|
1673
2225
|
* @override
|
|
1674
2226
|
*
|
|
@@ -1698,9 +2250,9 @@
|
|
|
1698
2250
|
: this.getMessage(options.message || this.message, clazz);
|
|
1699
2251
|
}
|
|
1700
2252
|
};
|
|
1701
|
-
exports.ListValidator = __decorate([
|
|
2253
|
+
exports.ListValidator = tslib.__decorate([
|
|
1702
2254
|
validator(ValidationKeys.LIST),
|
|
1703
|
-
__metadata("design:paramtypes", [String])
|
|
2255
|
+
tslib.__metadata("design:paramtypes", [String])
|
|
1704
2256
|
], exports.ListValidator);
|
|
1705
2257
|
|
|
1706
2258
|
/**
|
|
@@ -1733,24 +2285,66 @@
|
|
|
1733
2285
|
hasErrors(value, options) {
|
|
1734
2286
|
if (typeof value === "undefined")
|
|
1735
2287
|
return;
|
|
1736
|
-
return value.length > options.
|
|
1737
|
-
? this.getMessage(options.message || this.message, options.
|
|
2288
|
+
return value.length > options.maxlength
|
|
2289
|
+
? this.getMessage(options.message || this.message, options.maxlength)
|
|
1738
2290
|
: undefined;
|
|
1739
2291
|
}
|
|
1740
2292
|
};
|
|
1741
|
-
exports.MaxLengthValidator = __decorate([
|
|
2293
|
+
exports.MaxLengthValidator = tslib.__decorate([
|
|
1742
2294
|
validator(ValidationKeys.MAX_LENGTH),
|
|
1743
|
-
__metadata("design:paramtypes", [String])
|
|
2295
|
+
tslib.__metadata("design:paramtypes", [String])
|
|
1744
2296
|
], exports.MaxLengthValidator);
|
|
1745
2297
|
|
|
1746
2298
|
/**
|
|
1747
|
-
* @
|
|
2299
|
+
* @description Validator for checking if a value is less than or equal to a maximum
|
|
2300
|
+
* @summary The MaxValidator checks if a numeric value, date, or string is less than or equal to
|
|
2301
|
+
* a specified maximum value. It supports comparing numbers directly, dates chronologically,
|
|
2302
|
+
* and strings lexicographically. This validator is typically used with the @max decorator.
|
|
1748
2303
|
*
|
|
1749
|
-
* @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#MAX}
|
|
2304
|
+
* @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#MAX}
|
|
1750
2305
|
*
|
|
1751
2306
|
* @class MaxValidator
|
|
1752
2307
|
* @extends Validator
|
|
1753
2308
|
*
|
|
2309
|
+
* @example
|
|
2310
|
+
* ```typescript
|
|
2311
|
+
* // Create a max validator with default error message
|
|
2312
|
+
* const maxValidator = new MaxValidator();
|
|
2313
|
+
*
|
|
2314
|
+
* // Create a max validator with custom error message
|
|
2315
|
+
* const customMaxValidator = new MaxValidator("Value must not exceed {0}");
|
|
2316
|
+
*
|
|
2317
|
+
* // Validate a number
|
|
2318
|
+
* const numOptions = { max: 100, message: "Number too large" };
|
|
2319
|
+
* const numResult = maxValidator.hasErrors(50, numOptions); // undefined (valid)
|
|
2320
|
+
* const invalidNumResult = maxValidator.hasErrors(150, numOptions); // Returns error message (invalid)
|
|
2321
|
+
*
|
|
2322
|
+
* // Validate a date
|
|
2323
|
+
* const dateOptions = { max: new Date(2023, 11, 31) };
|
|
2324
|
+
* const dateResult = maxValidator.hasErrors(new Date(2023, 5, 15), dateOptions); // undefined (valid)
|
|
2325
|
+
* ```
|
|
2326
|
+
*
|
|
2327
|
+
* @mermaid
|
|
2328
|
+
* sequenceDiagram
|
|
2329
|
+
* participant C as Client
|
|
2330
|
+
* participant V as MaxValidator
|
|
2331
|
+
*
|
|
2332
|
+
* C->>V: new MaxValidator(message)
|
|
2333
|
+
* C->>V: hasErrors(value, options)
|
|
2334
|
+
* alt value is undefined
|
|
2335
|
+
* V-->>C: undefined (valid)
|
|
2336
|
+
* else value is Date and max is not Date
|
|
2337
|
+
* V->>V: Convert max to Date
|
|
2338
|
+
* alt conversion fails
|
|
2339
|
+
* V-->>C: Error: Invalid Max param
|
|
2340
|
+
* end
|
|
2341
|
+
* end
|
|
2342
|
+
* alt value > max
|
|
2343
|
+
* V-->>C: Error message
|
|
2344
|
+
* else value <= max
|
|
2345
|
+
* V-->>C: undefined (valid)
|
|
2346
|
+
* end
|
|
2347
|
+
*
|
|
1754
2348
|
* @category Validators
|
|
1755
2349
|
*/
|
|
1756
2350
|
exports.MaxValidator = class MaxValidator extends Validator {
|
|
@@ -1758,12 +2352,16 @@
|
|
|
1758
2352
|
super(message, "number", "Date", "string");
|
|
1759
2353
|
}
|
|
1760
2354
|
/**
|
|
1761
|
-
* @
|
|
2355
|
+
* @description Checks if a value is less than or equal to a maximum
|
|
2356
|
+
* @summary Validates that the provided value does not exceed the maximum value
|
|
2357
|
+
* specified in the options. For dates, it performs chronological comparison,
|
|
2358
|
+
* converting string representations to Date objects if necessary. For numbers
|
|
2359
|
+
* and strings, it performs direct comparison.
|
|
1762
2360
|
*
|
|
1763
|
-
* @param {string} value
|
|
1764
|
-
* @param {MaxValidatorOptions} options
|
|
2361
|
+
* @param {number | Date | string} value - The value to validate
|
|
2362
|
+
* @param {MaxValidatorOptions} options - Configuration options containing the maximum value
|
|
1765
2363
|
*
|
|
1766
|
-
* @return {string | undefined}
|
|
2364
|
+
* @return {string | undefined} Error message if validation fails, undefined if validation passes
|
|
1767
2365
|
*
|
|
1768
2366
|
* @override
|
|
1769
2367
|
*
|
|
@@ -1783,9 +2381,9 @@
|
|
|
1783
2381
|
: undefined;
|
|
1784
2382
|
}
|
|
1785
2383
|
};
|
|
1786
|
-
exports.MaxValidator = __decorate([
|
|
2384
|
+
exports.MaxValidator = tslib.__decorate([
|
|
1787
2385
|
validator(ValidationKeys.MAX),
|
|
1788
|
-
__metadata("design:paramtypes", [String])
|
|
2386
|
+
tslib.__metadata("design:paramtypes", [String])
|
|
1789
2387
|
], exports.MaxValidator);
|
|
1790
2388
|
|
|
1791
2389
|
/**
|
|
@@ -1818,24 +2416,66 @@
|
|
|
1818
2416
|
hasErrors(value, options) {
|
|
1819
2417
|
if (typeof value === "undefined")
|
|
1820
2418
|
return;
|
|
1821
|
-
return value.length < options.
|
|
1822
|
-
? this.getMessage(options.message || this.message, options.
|
|
2419
|
+
return value.length < options.minlength
|
|
2420
|
+
? this.getMessage(options.message || this.message, options.minlength)
|
|
1823
2421
|
: undefined;
|
|
1824
2422
|
}
|
|
1825
2423
|
};
|
|
1826
|
-
exports.MinLengthValidator = __decorate([
|
|
2424
|
+
exports.MinLengthValidator = tslib.__decorate([
|
|
1827
2425
|
validator(ValidationKeys.MIN_LENGTH),
|
|
1828
|
-
__metadata("design:paramtypes", [String])
|
|
2426
|
+
tslib.__metadata("design:paramtypes", [String])
|
|
1829
2427
|
], exports.MinLengthValidator);
|
|
1830
2428
|
|
|
1831
2429
|
/**
|
|
1832
|
-
* @
|
|
2430
|
+
* @description Validator for checking if a value is greater than or equal to a minimum
|
|
2431
|
+
* @summary The MinValidator checks if a numeric value, date, or string is greater than or equal to
|
|
2432
|
+
* a specified minimum value. It supports comparing numbers directly, dates chronologically,
|
|
2433
|
+
* and strings lexicographically. This validator is typically used with the @min decorator.
|
|
1833
2434
|
*
|
|
1834
|
-
* @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#MIN}
|
|
2435
|
+
* @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#MIN}
|
|
1835
2436
|
*
|
|
1836
2437
|
* @class MinValidator
|
|
1837
2438
|
* @extends Validator
|
|
1838
2439
|
*
|
|
2440
|
+
* @example
|
|
2441
|
+
* ```typescript
|
|
2442
|
+
* // Create a min validator with default error message
|
|
2443
|
+
* const minValidator = new MinValidator();
|
|
2444
|
+
*
|
|
2445
|
+
* // Create a min validator with custom error message
|
|
2446
|
+
* const customMinValidator = new MinValidator("Value must be at least {0}");
|
|
2447
|
+
*
|
|
2448
|
+
* // Validate a number
|
|
2449
|
+
* const numOptions = { min: 10, message: "Number too small" };
|
|
2450
|
+
* const numResult = minValidator.hasErrors(50, numOptions); // undefined (valid)
|
|
2451
|
+
* const invalidNumResult = minValidator.hasErrors(5, numOptions); // Returns error message (invalid)
|
|
2452
|
+
*
|
|
2453
|
+
* // Validate a date
|
|
2454
|
+
* const dateOptions = { min: new Date(2023, 0, 1) };
|
|
2455
|
+
* const dateResult = minValidator.hasErrors(new Date(2023, 5, 15), dateOptions); // undefined (valid)
|
|
2456
|
+
* ```
|
|
2457
|
+
*
|
|
2458
|
+
* @mermaid
|
|
2459
|
+
* sequenceDiagram
|
|
2460
|
+
* participant C as Client
|
|
2461
|
+
* participant V as MinValidator
|
|
2462
|
+
*
|
|
2463
|
+
* C->>V: new MinValidator(message)
|
|
2464
|
+
* C->>V: hasErrors(value, options)
|
|
2465
|
+
* alt value is undefined
|
|
2466
|
+
* V-->>C: undefined (valid)
|
|
2467
|
+
* else value is Date and min is not Date
|
|
2468
|
+
* V->>V: Convert min to Date
|
|
2469
|
+
* alt conversion fails
|
|
2470
|
+
* V-->>C: Error: Invalid Min param
|
|
2471
|
+
* end
|
|
2472
|
+
* end
|
|
2473
|
+
* alt value < min
|
|
2474
|
+
* V-->>C: Error message
|
|
2475
|
+
* else value >= min
|
|
2476
|
+
* V-->>C: undefined (valid)
|
|
2477
|
+
* end
|
|
2478
|
+
*
|
|
1839
2479
|
* @category Validators
|
|
1840
2480
|
*/
|
|
1841
2481
|
exports.MinValidator = class MinValidator extends Validator {
|
|
@@ -1843,12 +2483,16 @@
|
|
|
1843
2483
|
super(message, "number", "Date", "string");
|
|
1844
2484
|
}
|
|
1845
2485
|
/**
|
|
1846
|
-
* @
|
|
2486
|
+
* @description Checks if a value is greater than or equal to a minimum
|
|
2487
|
+
* @summary Validates that the provided value is not less than the minimum value
|
|
2488
|
+
* specified in the options. For dates, it performs chronological comparison,
|
|
2489
|
+
* converting string representations to Date objects if necessary. For numbers
|
|
2490
|
+
* and strings, it performs direct comparison.
|
|
1847
2491
|
*
|
|
1848
|
-
* @param {string} value
|
|
1849
|
-
* @param {
|
|
2492
|
+
* @param {number | Date | string} value - The value to validate
|
|
2493
|
+
* @param {MinValidatorOptions} options - Configuration options containing the minimum value
|
|
1850
2494
|
*
|
|
1851
|
-
* @return {string | undefined}
|
|
2495
|
+
* @return {string | undefined} Error message if validation fails, undefined if validation passes
|
|
1852
2496
|
*
|
|
1853
2497
|
* @override
|
|
1854
2498
|
*
|
|
@@ -1868,9 +2512,9 @@
|
|
|
1868
2512
|
: undefined;
|
|
1869
2513
|
}
|
|
1870
2514
|
};
|
|
1871
|
-
exports.MinValidator = __decorate([
|
|
2515
|
+
exports.MinValidator = tslib.__decorate([
|
|
1872
2516
|
validator(ValidationKeys.MIN),
|
|
1873
|
-
__metadata("design:paramtypes", [String])
|
|
2517
|
+
tslib.__metadata("design:paramtypes", [String])
|
|
1874
2518
|
], exports.MinValidator);
|
|
1875
2519
|
|
|
1876
2520
|
/**
|
|
@@ -1906,19 +2550,61 @@
|
|
|
1906
2550
|
});
|
|
1907
2551
|
}
|
|
1908
2552
|
};
|
|
1909
|
-
exports.PasswordValidator = __decorate([
|
|
2553
|
+
exports.PasswordValidator = tslib.__decorate([
|
|
1910
2554
|
validator(ValidationKeys.PASSWORD),
|
|
1911
|
-
__metadata("design:paramtypes", [Object])
|
|
2555
|
+
tslib.__metadata("design:paramtypes", [Object])
|
|
1912
2556
|
], exports.PasswordValidator);
|
|
1913
2557
|
|
|
1914
2558
|
/**
|
|
1915
|
-
* @
|
|
2559
|
+
* @description Validator for checking if a value is present and not empty
|
|
2560
|
+
* @summary The RequiredValidator ensures that a value is provided and not empty.
|
|
2561
|
+
* It handles different types of values appropriately: for booleans and numbers,
|
|
2562
|
+
* it checks if they're undefined; for other types (strings, arrays, objects),
|
|
2563
|
+
* it checks if they're falsy. This validator is typically used with the @required decorator
|
|
2564
|
+
* and is often the first validation applied to important fields.
|
|
1916
2565
|
*
|
|
1917
|
-
* @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#REQUIRED}
|
|
2566
|
+
* @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#REQUIRED}
|
|
1918
2567
|
*
|
|
1919
2568
|
* @class RequiredValidator
|
|
1920
2569
|
* @extends Validator
|
|
1921
2570
|
*
|
|
2571
|
+
* @example
|
|
2572
|
+
* ```typescript
|
|
2573
|
+
* // Create a required validator with default error message
|
|
2574
|
+
* const requiredValidator = new RequiredValidator();
|
|
2575
|
+
*
|
|
2576
|
+
* // Create a required validator with custom error message
|
|
2577
|
+
* const customRequiredValidator = new RequiredValidator("This field is mandatory");
|
|
2578
|
+
*
|
|
2579
|
+
* // Validate different types of values
|
|
2580
|
+
* requiredValidator.hasErrors("Hello"); // undefined (valid)
|
|
2581
|
+
* requiredValidator.hasErrors(""); // Returns error message (invalid)
|
|
2582
|
+
* requiredValidator.hasErrors(0); // undefined (valid - 0 is a valid number)
|
|
2583
|
+
* requiredValidator.hasErrors(null); // Returns error message (invalid)
|
|
2584
|
+
* requiredValidator.hasErrors([]); // undefined (valid - empty array is still an array)
|
|
2585
|
+
* ```
|
|
2586
|
+
*
|
|
2587
|
+
* @mermaid
|
|
2588
|
+
* sequenceDiagram
|
|
2589
|
+
* participant C as Client
|
|
2590
|
+
* participant V as RequiredValidator
|
|
2591
|
+
*
|
|
2592
|
+
* C->>V: new RequiredValidator(message)
|
|
2593
|
+
* C->>V: hasErrors(value, options)
|
|
2594
|
+
* alt typeof value is boolean or number
|
|
2595
|
+
* alt value is undefined
|
|
2596
|
+
* V-->>C: Error message
|
|
2597
|
+
* else value is defined
|
|
2598
|
+
* V-->>C: undefined (valid)
|
|
2599
|
+
* end
|
|
2600
|
+
* else other types
|
|
2601
|
+
* alt value is falsy (null, undefined, empty string)
|
|
2602
|
+
* V-->>C: Error message
|
|
2603
|
+
* else value is truthy
|
|
2604
|
+
* V-->>C: undefined (valid)
|
|
2605
|
+
* end
|
|
2606
|
+
* end
|
|
2607
|
+
*
|
|
1922
2608
|
* @category Validators
|
|
1923
2609
|
*/
|
|
1924
2610
|
exports.RequiredValidator = class RequiredValidator extends Validator {
|
|
@@ -1926,12 +2612,16 @@
|
|
|
1926
2612
|
super(message);
|
|
1927
2613
|
}
|
|
1928
2614
|
/**
|
|
1929
|
-
* @
|
|
2615
|
+
* @description Checks if a value is present and not empty
|
|
2616
|
+
* @summary Validates that the provided value exists and is not empty.
|
|
2617
|
+
* The validation logic varies by type:
|
|
2618
|
+
* - For booleans and numbers: checks if the value is undefined
|
|
2619
|
+
* - For other types (strings, arrays, objects): checks if the value is falsy
|
|
1930
2620
|
*
|
|
1931
|
-
* @param {
|
|
1932
|
-
* @param {ValidatorOptions} [options={}]
|
|
2621
|
+
* @param {any} value - The value to validate
|
|
2622
|
+
* @param {ValidatorOptions} [options={}] - Optional configuration options
|
|
1933
2623
|
*
|
|
1934
|
-
* @return {string | undefined}
|
|
2624
|
+
* @return {string | undefined} Error message if validation fails, undefined if validation passes
|
|
1935
2625
|
*
|
|
1936
2626
|
* @override
|
|
1937
2627
|
*
|
|
@@ -1951,9 +2641,9 @@
|
|
|
1951
2641
|
}
|
|
1952
2642
|
}
|
|
1953
2643
|
};
|
|
1954
|
-
exports.RequiredValidator = __decorate([
|
|
2644
|
+
exports.RequiredValidator = tslib.__decorate([
|
|
1955
2645
|
validator(ValidationKeys.REQUIRED),
|
|
1956
|
-
__metadata("design:paramtypes", [String])
|
|
2646
|
+
tslib.__metadata("design:paramtypes", [String])
|
|
1957
2647
|
], exports.RequiredValidator);
|
|
1958
2648
|
|
|
1959
2649
|
/**
|
|
@@ -1991,17 +2681,67 @@
|
|
|
1991
2681
|
: undefined;
|
|
1992
2682
|
}
|
|
1993
2683
|
};
|
|
1994
|
-
exports.StepValidator = __decorate([
|
|
2684
|
+
exports.StepValidator = tslib.__decorate([
|
|
1995
2685
|
validator(ValidationKeys.STEP),
|
|
1996
|
-
__metadata("design:paramtypes", [String])
|
|
2686
|
+
tslib.__metadata("design:paramtypes", [String])
|
|
1997
2687
|
], exports.StepValidator);
|
|
1998
2688
|
|
|
1999
2689
|
/**
|
|
2000
|
-
* @
|
|
2690
|
+
* @description Validator for checking if a value is of the expected type(s)
|
|
2691
|
+
* @summary The TypeValidator ensures that a value matches one of the specified types.
|
|
2692
|
+
* It can validate against a single type, multiple types, or a type with a specific name.
|
|
2693
|
+
* This validator is typically used with the @type decorator and is fundamental for
|
|
2694
|
+
* ensuring type safety in validated models.
|
|
2001
2695
|
*
|
|
2002
|
-
* @
|
|
2696
|
+
* @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#TYPE}
|
|
2697
|
+
*
|
|
2698
|
+
* @class TypeValidator
|
|
2003
2699
|
* @extends Validator
|
|
2004
2700
|
*
|
|
2701
|
+
* @example
|
|
2702
|
+
* ```typescript
|
|
2703
|
+
* // Create a type validator with default error message
|
|
2704
|
+
* const typeValidator = new TypeValidator();
|
|
2705
|
+
*
|
|
2706
|
+
* // Create a type validator with custom error message
|
|
2707
|
+
* const customTypeValidator = new TypeValidator("Value must be of type {0}, but got {1}");
|
|
2708
|
+
*
|
|
2709
|
+
* // Validate against a single type
|
|
2710
|
+
* const stringOptions = { types: "string" };
|
|
2711
|
+
* typeValidator.hasErrors("hello", stringOptions); // undefined (valid)
|
|
2712
|
+
* typeValidator.hasErrors(123, stringOptions); // Returns error message (invalid)
|
|
2713
|
+
*
|
|
2714
|
+
* // Validate against multiple types
|
|
2715
|
+
* const multiOptions = { types: ["string", "number"] };
|
|
2716
|
+
* typeValidator.hasErrors("hello", multiOptions); // undefined (valid)
|
|
2717
|
+
* typeValidator.hasErrors(123, multiOptions); // undefined (valid)
|
|
2718
|
+
* typeValidator.hasErrors(true, multiOptions); // Returns error message (invalid)
|
|
2719
|
+
*
|
|
2720
|
+
* // Validate against a class type
|
|
2721
|
+
* const classOptions = { types: { name: "Date" } };
|
|
2722
|
+
* typeValidator.hasErrors(new Date(), classOptions); // undefined (valid)
|
|
2723
|
+
* ```
|
|
2724
|
+
*
|
|
2725
|
+
* @mermaid
|
|
2726
|
+
* sequenceDiagram
|
|
2727
|
+
* participant C as Client
|
|
2728
|
+
* participant V as TypeValidator
|
|
2729
|
+
* participant R as Reflection
|
|
2730
|
+
*
|
|
2731
|
+
* C->>V: new TypeValidator(message)
|
|
2732
|
+
* C->>V: hasErrors(value, options)
|
|
2733
|
+
* alt value is undefined
|
|
2734
|
+
* V-->>C: undefined (valid)
|
|
2735
|
+
* else value is defined
|
|
2736
|
+
* V->>R: evaluateDesignTypes(value, types)
|
|
2737
|
+
* alt type evaluation passes
|
|
2738
|
+
* V-->>C: undefined (valid)
|
|
2739
|
+
* else type evaluation fails
|
|
2740
|
+
* V->>V: Format error message with type info
|
|
2741
|
+
* V-->>C: Error message
|
|
2742
|
+
* end
|
|
2743
|
+
* end
|
|
2744
|
+
*
|
|
2005
2745
|
* @category Validators
|
|
2006
2746
|
*/
|
|
2007
2747
|
exports.TypeValidator = class TypeValidator extends Validator {
|
|
@@ -2009,11 +2749,15 @@
|
|
|
2009
2749
|
super(message);
|
|
2010
2750
|
}
|
|
2011
2751
|
/**
|
|
2012
|
-
* @
|
|
2013
|
-
* @
|
|
2014
|
-
*
|
|
2752
|
+
* @description Checks if a value is of the expected type(s)
|
|
2753
|
+
* @summary Validates that the provided value matches one of the specified types.
|
|
2754
|
+
* It uses the Reflection utility to evaluate if the value's type matches the expected types.
|
|
2755
|
+
* The method skips validation for undefined values to avoid conflicts with the RequiredValidator.
|
|
2015
2756
|
*
|
|
2016
|
-
* @
|
|
2757
|
+
* @param {any} value - The value to validate
|
|
2758
|
+
* @param {TypeValidatorOptions} options - Configuration options containing the expected types
|
|
2759
|
+
*
|
|
2760
|
+
* @return {string | undefined} Error message if validation fails, undefined if validation passes
|
|
2017
2761
|
*
|
|
2018
2762
|
* @override
|
|
2019
2763
|
*
|
|
@@ -2031,10 +2775,18 @@
|
|
|
2031
2775
|
: types.name, typeof value);
|
|
2032
2776
|
}
|
|
2033
2777
|
};
|
|
2034
|
-
exports.TypeValidator = __decorate([
|
|
2778
|
+
exports.TypeValidator = tslib.__decorate([
|
|
2035
2779
|
validator(ValidationKeys.TYPE),
|
|
2036
|
-
__metadata("design:paramtypes", [String])
|
|
2780
|
+
tslib.__metadata("design:paramtypes", [String])
|
|
2037
2781
|
], exports.TypeValidator);
|
|
2782
|
+
/**
|
|
2783
|
+
* @description Register the TypeValidator with the Validation registry
|
|
2784
|
+
* @summary This registration associates the TypeValidator with the ModelKeys.TYPE key,
|
|
2785
|
+
* allowing it to be used for validating design types. The save flag is set to false
|
|
2786
|
+
* to prevent the validator from being saved in the standard validator registry.
|
|
2787
|
+
*
|
|
2788
|
+
* @memberOf module:decorator-validation
|
|
2789
|
+
*/
|
|
2038
2790
|
Validation.register({
|
|
2039
2791
|
validator: exports.TypeValidator,
|
|
2040
2792
|
validationKey: exports.ModelKeys.TYPE,
|
|
@@ -2042,12 +2794,43 @@
|
|
|
2042
2794
|
});
|
|
2043
2795
|
|
|
2044
2796
|
/**
|
|
2045
|
-
* @
|
|
2046
|
-
* @
|
|
2797
|
+
* @description Validator for checking if a string is a valid URL
|
|
2798
|
+
* @summary The URLValidator checks if a string matches a standard URL pattern.
|
|
2799
|
+
* It extends the PatternValidator and uses a robust URL regex pattern to validate web addresses.
|
|
2800
|
+
* The pattern is sourced from {@link https://gist.github.com/dperini/729294} and is widely
|
|
2801
|
+
* recognized for its accuracy in validating URLs. This validator is typically used with the @url decorator.
|
|
2802
|
+
*
|
|
2803
|
+
* @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#URL}
|
|
2047
2804
|
*
|
|
2048
2805
|
* @class URLValidator
|
|
2049
2806
|
* @extends PatternValidator
|
|
2050
2807
|
*
|
|
2808
|
+
* @example
|
|
2809
|
+
* ```typescript
|
|
2810
|
+
* // Create a URL validator with default error message
|
|
2811
|
+
* const urlValidator = new URLValidator();
|
|
2812
|
+
*
|
|
2813
|
+
* // Create a URL validator with custom error message
|
|
2814
|
+
* const customUrlValidator = new URLValidator("Please enter a valid web address");
|
|
2815
|
+
*
|
|
2816
|
+
* // Validate a URL
|
|
2817
|
+
* const result = urlValidator.hasErrors("https://example.com"); // undefined (valid)
|
|
2818
|
+
* const invalidResult = urlValidator.hasErrors("not-a-url"); // Returns error message (invalid)
|
|
2819
|
+
* ```
|
|
2820
|
+
*
|
|
2821
|
+
* @mermaid
|
|
2822
|
+
* sequenceDiagram
|
|
2823
|
+
* participant C as Client
|
|
2824
|
+
* participant U as URLValidator
|
|
2825
|
+
* participant P as PatternValidator
|
|
2826
|
+
*
|
|
2827
|
+
* C->>U: new URLValidator(message)
|
|
2828
|
+
* U->>P: super(message)
|
|
2829
|
+
* C->>U: hasErrors(value, options)
|
|
2830
|
+
* U->>P: super.hasErrors(value, options with URL pattern)
|
|
2831
|
+
* P-->>U: validation result
|
|
2832
|
+
* U-->>C: validation result
|
|
2833
|
+
*
|
|
2051
2834
|
* @category Validators
|
|
2052
2835
|
*/
|
|
2053
2836
|
exports.URLValidator = class URLValidator extends exports.PatternValidator {
|
|
@@ -2055,16 +2838,19 @@
|
|
|
2055
2838
|
super(message);
|
|
2056
2839
|
}
|
|
2057
2840
|
/**
|
|
2058
|
-
* @
|
|
2841
|
+
* @description Checks if a string is a valid URL
|
|
2842
|
+
* @summary Validates that the provided string matches the URL pattern.
|
|
2843
|
+
* This method extends the PatternValidator's hasErrors method by ensuring
|
|
2844
|
+
* the URL pattern is used, even if not explicitly provided in the options.
|
|
2059
2845
|
*
|
|
2060
|
-
* @param {string} value
|
|
2061
|
-
* @param {PatternValidatorOptions} [options={}]
|
|
2846
|
+
* @param {string} value - The string to validate as a URL
|
|
2847
|
+
* @param {PatternValidatorOptions} [options={}] - Optional configuration options
|
|
2062
2848
|
*
|
|
2063
|
-
* @return {string | undefined}
|
|
2849
|
+
* @return {string | undefined} Error message if validation fails, undefined if validation passes
|
|
2064
2850
|
*
|
|
2065
2851
|
* @override
|
|
2066
2852
|
*
|
|
2067
|
-
* @see
|
|
2853
|
+
* @see PatternValidator#hasErrors
|
|
2068
2854
|
*/
|
|
2069
2855
|
hasErrors(value, options = {}) {
|
|
2070
2856
|
return super.hasErrors(value, {
|
|
@@ -2073,43 +2859,75 @@
|
|
|
2073
2859
|
});
|
|
2074
2860
|
}
|
|
2075
2861
|
};
|
|
2076
|
-
exports.URLValidator = __decorate([
|
|
2862
|
+
exports.URLValidator = tslib.__decorate([
|
|
2077
2863
|
validator(ValidationKeys.URL),
|
|
2078
|
-
__metadata("design:paramtypes", [String])
|
|
2864
|
+
tslib.__metadata("design:paramtypes", [String])
|
|
2079
2865
|
], exports.URLValidator);
|
|
2080
2866
|
|
|
2081
2867
|
/**
|
|
2082
|
-
* @
|
|
2083
|
-
* @
|
|
2868
|
+
* @description Property decorator that marks a field as required
|
|
2869
|
+
* @summary Marks the property as required, causing validation to fail if the property is undefined, null, or empty.
|
|
2870
|
+
* Validators to validate a decorated property must use key {@link ValidationKeys#REQUIRED}.
|
|
2871
|
+
* This decorator is commonly used as the first validation step for important fields.
|
|
2084
2872
|
*
|
|
2085
|
-
* @param {string} [message]
|
|
2873
|
+
* @param {string} [message] - The error message to display when validation fails. Defaults to {@link DEFAULT_ERROR_MESSAGES#REQUIRED}
|
|
2874
|
+
* @return {PropertyDecorator} A decorator function that can be applied to class properties
|
|
2086
2875
|
*
|
|
2087
2876
|
* @function required
|
|
2088
|
-
*
|
|
2089
2877
|
* @category Decorators
|
|
2878
|
+
*
|
|
2879
|
+
* @example
|
|
2880
|
+
* ```typescript
|
|
2881
|
+
* class User {
|
|
2882
|
+
* @required()
|
|
2883
|
+
* username: string;
|
|
2884
|
+
*
|
|
2885
|
+
* @required("Email address is mandatory")
|
|
2886
|
+
* email: string;
|
|
2887
|
+
* }
|
|
2888
|
+
* ```
|
|
2090
2889
|
*/
|
|
2091
2890
|
function required(message = DEFAULT_ERROR_MESSAGES.REQUIRED) {
|
|
2092
|
-
|
|
2891
|
+
const key = Validation.key(ValidationKeys.REQUIRED);
|
|
2892
|
+
return Decoration.for(key)
|
|
2893
|
+
.define(propMetadata(key, {
|
|
2093
2894
|
message: message,
|
|
2094
|
-
})
|
|
2895
|
+
}))
|
|
2896
|
+
.apply();
|
|
2095
2897
|
}
|
|
2096
2898
|
/**
|
|
2097
|
-
* @
|
|
2098
|
-
* @
|
|
2899
|
+
* @description Property decorator that enforces a minimum value constraint
|
|
2900
|
+
* @summary Defines a minimum value for the property, causing validation to fail if the property value is less than the specified minimum.
|
|
2901
|
+
* Validators to validate a decorated property must use key {@link ValidationKeys#MIN}.
|
|
2902
|
+
* This decorator works with numeric values and dates.
|
|
2099
2903
|
*
|
|
2100
|
-
* @param {number | Date} value
|
|
2101
|
-
* @param {string} [message]
|
|
2904
|
+
* @param {number | Date | string} value - The minimum value allowed. For dates, can be a Date object or a string that can be converted to a date
|
|
2905
|
+
* @param {string} [message] - The error message to display when validation fails. Defaults to {@link DEFAULT_ERROR_MESSAGES#MIN}
|
|
2906
|
+
* @return {PropertyDecorator} A decorator function that can be applied to class properties
|
|
2102
2907
|
*
|
|
2103
2908
|
* @function min
|
|
2104
|
-
* @memberOf module:decorator-validation.Decorators.Validation
|
|
2105
2909
|
* @category Decorators
|
|
2910
|
+
*
|
|
2911
|
+
* @example
|
|
2912
|
+
* ```typescript
|
|
2913
|
+
* class Product {
|
|
2914
|
+
* @min(0)
|
|
2915
|
+
* price: number;
|
|
2916
|
+
*
|
|
2917
|
+
* @min(new Date(2023, 0, 1), "Date must be after January 1, 2023")
|
|
2918
|
+
* releaseDate: Date;
|
|
2919
|
+
* }
|
|
2920
|
+
* ```
|
|
2106
2921
|
*/
|
|
2107
2922
|
function min(value, message = DEFAULT_ERROR_MESSAGES.MIN) {
|
|
2108
|
-
|
|
2109
|
-
|
|
2923
|
+
const key = Validation.key(ValidationKeys.MIN);
|
|
2924
|
+
return Decoration.for(key)
|
|
2925
|
+
.define(propMetadata(Validation.key(ValidationKeys.MIN), {
|
|
2926
|
+
[ValidationKeys.MIN]: value,
|
|
2110
2927
|
message: message,
|
|
2111
2928
|
types: [Number.name, Date.name],
|
|
2112
|
-
})
|
|
2929
|
+
}))
|
|
2930
|
+
.apply();
|
|
2113
2931
|
}
|
|
2114
2932
|
/**
|
|
2115
2933
|
* @summary Defines a maximum value for the property
|
|
@@ -2119,15 +2937,17 @@
|
|
|
2119
2937
|
* @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#MAX}
|
|
2120
2938
|
*
|
|
2121
2939
|
* @function max
|
|
2122
|
-
* @memberOf module:decorator-validation.Decorators.Validation
|
|
2123
2940
|
* @category Decorators
|
|
2124
2941
|
*/
|
|
2125
2942
|
function max(value, message = DEFAULT_ERROR_MESSAGES.MAX) {
|
|
2126
|
-
|
|
2127
|
-
|
|
2943
|
+
const key = Validation.key(ValidationKeys.MAX);
|
|
2944
|
+
return Decoration.for(key)
|
|
2945
|
+
.define(propMetadata(key, {
|
|
2946
|
+
[ValidationKeys.MAX]: value,
|
|
2128
2947
|
message: message,
|
|
2129
2948
|
types: [Number.name, Date.name],
|
|
2130
|
-
})
|
|
2949
|
+
}))
|
|
2950
|
+
.apply();
|
|
2131
2951
|
}
|
|
2132
2952
|
/**
|
|
2133
2953
|
* @summary Defines a step value for the property
|
|
@@ -2137,15 +2957,17 @@
|
|
|
2137
2957
|
* @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#STEP}
|
|
2138
2958
|
*
|
|
2139
2959
|
* @function step
|
|
2140
|
-
* @memberOf module:decorator-validation.Decorators.Validation
|
|
2141
2960
|
* @category Decorators
|
|
2142
2961
|
*/
|
|
2143
2962
|
function step(value, message = DEFAULT_ERROR_MESSAGES.STEP) {
|
|
2144
|
-
|
|
2145
|
-
|
|
2963
|
+
const key = Validation.key(ValidationKeys.STEP);
|
|
2964
|
+
return Decoration.for(key)
|
|
2965
|
+
.define(propMetadata(key, {
|
|
2966
|
+
[ValidationKeys.STEP]: value,
|
|
2146
2967
|
message: message,
|
|
2147
2968
|
types: [Number.name],
|
|
2148
|
-
})
|
|
2969
|
+
}))
|
|
2970
|
+
.apply();
|
|
2149
2971
|
}
|
|
2150
2972
|
/**
|
|
2151
2973
|
* @summary Defines a minimum length for the property
|
|
@@ -2155,15 +2977,17 @@
|
|
|
2155
2977
|
* @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#MIN_LENGTH}
|
|
2156
2978
|
*
|
|
2157
2979
|
* @function minlength
|
|
2158
|
-
* @memberOf module:decorator-validation.Decorators.Validation
|
|
2159
2980
|
* @category Decorators
|
|
2160
2981
|
*/
|
|
2161
2982
|
function minlength(value, message = DEFAULT_ERROR_MESSAGES.MIN_LENGTH) {
|
|
2162
|
-
|
|
2163
|
-
|
|
2983
|
+
const key = Validation.key(ValidationKeys.MIN_LENGTH);
|
|
2984
|
+
return Decoration.for(key)
|
|
2985
|
+
.define(propMetadata(key, {
|
|
2986
|
+
[ValidationKeys.MIN_LENGTH]: value,
|
|
2164
2987
|
message: message,
|
|
2165
2988
|
types: [String.name, Array.name, Set.name],
|
|
2166
|
-
})
|
|
2989
|
+
}))
|
|
2990
|
+
.apply();
|
|
2167
2991
|
}
|
|
2168
2992
|
/**
|
|
2169
2993
|
* @summary Defines a maximum length for the property
|
|
@@ -2173,15 +2997,17 @@
|
|
|
2173
2997
|
* @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#MAX_LENGTH}
|
|
2174
2998
|
*
|
|
2175
2999
|
* @function maxlength
|
|
2176
|
-
* @memberOf module:decorator-validation.Decorators.Validation
|
|
2177
3000
|
* @category Decorators
|
|
2178
3001
|
*/
|
|
2179
3002
|
function maxlength(value, message = DEFAULT_ERROR_MESSAGES.MAX_LENGTH) {
|
|
2180
|
-
|
|
2181
|
-
|
|
3003
|
+
const key = Validation.key(ValidationKeys.MAX_LENGTH);
|
|
3004
|
+
return Decoration.for(key)
|
|
3005
|
+
.define(propMetadata(key, {
|
|
3006
|
+
[ValidationKeys.MAX_LENGTH]: value,
|
|
2182
3007
|
message: message,
|
|
2183
3008
|
types: [String.name, Array.name, Set.name],
|
|
2184
|
-
})
|
|
3009
|
+
}))
|
|
3010
|
+
.apply();
|
|
2185
3011
|
}
|
|
2186
3012
|
/**
|
|
2187
3013
|
* @summary Defines a RegExp pattern the property must respect
|
|
@@ -2191,15 +3017,17 @@
|
|
|
2191
3017
|
* @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#PATTERN}
|
|
2192
3018
|
*
|
|
2193
3019
|
* @function pattern
|
|
2194
|
-
* @memberOf module:decorator-validation.Decorators.Validation
|
|
2195
3020
|
* @category Decorators
|
|
2196
3021
|
*/
|
|
2197
3022
|
function pattern(value, message = DEFAULT_ERROR_MESSAGES.PATTERN) {
|
|
2198
|
-
|
|
2199
|
-
|
|
3023
|
+
const key = Validation.key(ValidationKeys.PATTERN);
|
|
3024
|
+
return Decoration.for(key)
|
|
3025
|
+
.define(propMetadata(Validation.key(ValidationKeys.PATTERN), {
|
|
3026
|
+
[ValidationKeys.PATTERN]: typeof value === "string" ? value : value.toString(),
|
|
2200
3027
|
message: message,
|
|
2201
3028
|
types: [String.name],
|
|
2202
|
-
})
|
|
3029
|
+
}))
|
|
3030
|
+
.apply();
|
|
2203
3031
|
}
|
|
2204
3032
|
/**
|
|
2205
3033
|
* @summary Defines the property as an email
|
|
@@ -2208,15 +3036,17 @@
|
|
|
2208
3036
|
* @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#EMAIL}
|
|
2209
3037
|
*
|
|
2210
3038
|
* @function email
|
|
2211
|
-
* @memberOf module:decorator-validation.Decorators.Validation
|
|
2212
3039
|
* @category Decorators
|
|
2213
3040
|
*/
|
|
2214
3041
|
function email(message = DEFAULT_ERROR_MESSAGES.EMAIL) {
|
|
2215
|
-
|
|
2216
|
-
|
|
3042
|
+
const key = Validation.key(ValidationKeys.EMAIL);
|
|
3043
|
+
return Decoration.for(key)
|
|
3044
|
+
.define(propMetadata(Validation.key(ValidationKeys.EMAIL), {
|
|
3045
|
+
[ValidationKeys.PATTERN]: DEFAULT_PATTERNS.EMAIL,
|
|
2217
3046
|
message: message,
|
|
2218
3047
|
types: [String.name],
|
|
2219
|
-
})
|
|
3048
|
+
}))
|
|
3049
|
+
.apply();
|
|
2220
3050
|
}
|
|
2221
3051
|
/**
|
|
2222
3052
|
* @summary Defines the property as an URL
|
|
@@ -2225,15 +3055,17 @@
|
|
|
2225
3055
|
* @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#URL}
|
|
2226
3056
|
*
|
|
2227
3057
|
* @function url
|
|
2228
|
-
* @memberOf module:decorator-validation.Decorators.Validation
|
|
2229
3058
|
* @category Decorators
|
|
2230
3059
|
*/
|
|
2231
3060
|
function url(message = DEFAULT_ERROR_MESSAGES.URL) {
|
|
2232
|
-
|
|
2233
|
-
|
|
3061
|
+
const key = Validation.key(ValidationKeys.URL);
|
|
3062
|
+
return Decoration.for(key)
|
|
3063
|
+
.define(propMetadata(Validation.key(ValidationKeys.URL), {
|
|
3064
|
+
[ValidationKeys.PATTERN]: DEFAULT_PATTERNS.URL,
|
|
2234
3065
|
message: message,
|
|
2235
3066
|
types: [String.name],
|
|
2236
|
-
})
|
|
3067
|
+
}))
|
|
3068
|
+
.apply();
|
|
2237
3069
|
}
|
|
2238
3070
|
/**
|
|
2239
3071
|
* @summary Enforces type verification
|
|
@@ -2243,14 +3075,16 @@
|
|
|
2243
3075
|
* @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#TYPE}
|
|
2244
3076
|
*
|
|
2245
3077
|
* @function type
|
|
2246
|
-
* @memberOf module:decorator-validation.Decorators.Validation
|
|
2247
3078
|
* @category Decorators
|
|
2248
3079
|
*/
|
|
2249
3080
|
function type(types, message = DEFAULT_ERROR_MESSAGES.TYPE) {
|
|
2250
|
-
|
|
3081
|
+
const key = Validation.key(ValidationKeys.TYPE);
|
|
3082
|
+
return Decoration.for(key)
|
|
3083
|
+
.define(propMetadata(Validation.key(ValidationKeys.TYPE), {
|
|
2251
3084
|
customTypes: types,
|
|
2252
3085
|
message: message,
|
|
2253
|
-
})
|
|
3086
|
+
}))
|
|
3087
|
+
.apply();
|
|
2254
3088
|
}
|
|
2255
3089
|
/**
|
|
2256
3090
|
* @summary Date Handler Decorator
|
|
@@ -2260,17 +3094,16 @@
|
|
|
2260
3094
|
*
|
|
2261
3095
|
* @param {string} format accepted format according to {@link formatDate}
|
|
2262
3096
|
* @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#DATE}
|
|
2263
|
-
* @param {Constructor<Validator>} [validator] the Validator to be used. Defaults to {@link DateValidator}
|
|
2264
3097
|
*
|
|
2265
3098
|
* @function date
|
|
2266
3099
|
*
|
|
2267
|
-
* @memberOf module:decorator-validation.Decorators.Validation
|
|
2268
3100
|
* @category Decorators
|
|
2269
3101
|
*/
|
|
2270
3102
|
function date(format = "dd/MM/yyyy", message = DEFAULT_ERROR_MESSAGES.DATE) {
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
3103
|
+
const key = Validation.key(ValidationKeys.DATE);
|
|
3104
|
+
const dateDec = (target, propertyKey) => {
|
|
3105
|
+
propMetadata(key, {
|
|
3106
|
+
[ValidationKeys.FORMAT]: format,
|
|
2274
3107
|
message: message,
|
|
2275
3108
|
types: [Date.name],
|
|
2276
3109
|
})(target, propertyKey);
|
|
@@ -2302,26 +3135,28 @@
|
|
|
2302
3135
|
},
|
|
2303
3136
|
});
|
|
2304
3137
|
};
|
|
3138
|
+
return Decoration.for(key).define(dateDec).apply();
|
|
2305
3139
|
}
|
|
2306
3140
|
/**
|
|
2307
3141
|
* @summary Password Handler Decorator
|
|
2308
3142
|
* @description Validators to validate a decorated property must use key {@link ValidationKeys#PASSWORD}
|
|
2309
3143
|
*
|
|
2310
|
-
* @param {RegExp} [pattern] defaults to {@link
|
|
3144
|
+
* @param {RegExp} [pattern] defaults to {@link DEFAULT_PATTERNS#CHAR8_ONE_OF_EACH}
|
|
2311
3145
|
* @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#PASSWORD}
|
|
2312
|
-
* @param {Constructor<Validator>} [validator] Defaults to {@link PasswordValidator}
|
|
2313
3146
|
*
|
|
2314
3147
|
* @function password
|
|
2315
3148
|
*
|
|
2316
|
-
* @memberOf module:decorator-validation.Decorators.Validation
|
|
2317
3149
|
* @category Decorators
|
|
2318
3150
|
*/
|
|
2319
3151
|
function password(pattern = DEFAULT_PATTERNS.PASSWORD.CHAR8_ONE_OF_EACH, message = DEFAULT_ERROR_MESSAGES.PASSWORD) {
|
|
2320
|
-
|
|
2321
|
-
|
|
3152
|
+
const key = Validation.key(ValidationKeys.PASSWORD);
|
|
3153
|
+
return Decoration.for(key)
|
|
3154
|
+
.define(propMetadata(key, {
|
|
3155
|
+
[ValidationKeys.PATTERN]: pattern,
|
|
2322
3156
|
message: message,
|
|
2323
3157
|
types: [String.name],
|
|
2324
|
-
})
|
|
3158
|
+
}))
|
|
3159
|
+
.apply();
|
|
2325
3160
|
}
|
|
2326
3161
|
/**
|
|
2327
3162
|
* @summary List Decorator
|
|
@@ -2330,19 +3165,20 @@
|
|
|
2330
3165
|
* @param {ModelConstructor} clazz
|
|
2331
3166
|
* @param {string} [collection] The collection being used. defaults to Array
|
|
2332
3167
|
* @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#LIST}
|
|
2333
|
-
* @param {Constructor<Validator>} [validator] defaults to {@link ListValidator}
|
|
2334
3168
|
*
|
|
2335
3169
|
* @function list
|
|
2336
3170
|
*
|
|
2337
|
-
* @memberOf module:decorator-validation.Decorators.Validation
|
|
2338
3171
|
* @category Decorators
|
|
2339
3172
|
*/
|
|
2340
3173
|
function list(clazz, collection = "Array", message = DEFAULT_ERROR_MESSAGES.LIST) {
|
|
2341
|
-
|
|
3174
|
+
const key = Validation.key(ValidationKeys.LIST);
|
|
3175
|
+
return Decoration.for(key)
|
|
3176
|
+
.define(propMetadata(key, {
|
|
2342
3177
|
clazz: Array.isArray(clazz) ? clazz.map((c) => c.name) : [clazz.name],
|
|
2343
3178
|
type: collection,
|
|
2344
3179
|
message: message,
|
|
2345
|
-
})
|
|
3180
|
+
}))
|
|
3181
|
+
.apply();
|
|
2346
3182
|
}
|
|
2347
3183
|
/**
|
|
2348
3184
|
* @summary Set Decorator
|
|
@@ -2350,11 +3186,9 @@
|
|
|
2350
3186
|
*
|
|
2351
3187
|
* @param {ModelConstructor} clazz
|
|
2352
3188
|
* @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#LIST}
|
|
2353
|
-
* @param {Constructor<Validator>} [validator]
|
|
2354
3189
|
*
|
|
2355
3190
|
* @function set
|
|
2356
3191
|
*
|
|
2357
|
-
* @memberOf module:decorator-validation.Decorators.Validation
|
|
2358
3192
|
* @category Decorators
|
|
2359
3193
|
*/
|
|
2360
3194
|
function set(clazz, message = DEFAULT_ERROR_MESSAGES.LIST) {
|
|
@@ -2369,7 +3203,7 @@
|
|
|
2369
3203
|
* @return {T} the new instance
|
|
2370
3204
|
*
|
|
2371
3205
|
* @function construct
|
|
2372
|
-
* @memberOf module:decorator-validation
|
|
3206
|
+
* @memberOf module:decorator-validation
|
|
2373
3207
|
*/
|
|
2374
3208
|
function construct(constructor, ...args) {
|
|
2375
3209
|
const _constr = (...argz) => new constructor(...argz);
|
|
@@ -2381,7 +3215,7 @@
|
|
|
2381
3215
|
* @param {object} obj
|
|
2382
3216
|
*
|
|
2383
3217
|
* @function findLastProtoBeforeObject
|
|
2384
|
-
* @memberOf module:decorator-validation
|
|
3218
|
+
* @memberOf module:decorator-validation
|
|
2385
3219
|
*/
|
|
2386
3220
|
function findLastProtoBeforeObject(obj) {
|
|
2387
3221
|
let prototype = Object.getPrototypeOf(obj);
|
|
@@ -2402,7 +3236,7 @@
|
|
|
2402
3236
|
* @param {unknown} obj
|
|
2403
3237
|
*
|
|
2404
3238
|
* @function bindModelPrototype
|
|
2405
|
-
* @memberOf module:decorator-validation
|
|
3239
|
+
* @memberOf module:decorator-validation
|
|
2406
3240
|
*/
|
|
2407
3241
|
function bindModelPrototype(obj) {
|
|
2408
3242
|
if (obj instanceof Model)
|
|
@@ -2437,11 +3271,10 @@
|
|
|
2437
3271
|
*
|
|
2438
3272
|
* @function model
|
|
2439
3273
|
*
|
|
2440
|
-
* @
|
|
2441
|
-
*
|
|
3274
|
+
* @category Decorators
|
|
2442
3275
|
*/
|
|
2443
3276
|
function model(instanceCallback) {
|
|
2444
|
-
|
|
3277
|
+
function modelDec(original) {
|
|
2445
3278
|
// the new constructor behaviour
|
|
2446
3279
|
const newConstructor = function (...args) {
|
|
2447
3280
|
const instance = construct(original, ...args);
|
|
@@ -2468,7 +3301,9 @@
|
|
|
2468
3301
|
Model.register(newConstructor, original.name);
|
|
2469
3302
|
// return new constructor (will override original)
|
|
2470
3303
|
return newConstructor;
|
|
2471
|
-
}
|
|
3304
|
+
}
|
|
3305
|
+
// return Decoration.for(key).define(modelDec).apply();
|
|
3306
|
+
return modelDec;
|
|
2472
3307
|
}
|
|
2473
3308
|
function hashedBy(algorithm, ...args) {
|
|
2474
3309
|
return reflection.metadata(Model.key(exports.ModelKeys.HASHING), {
|
|
@@ -2485,47 +3320,18 @@
|
|
|
2485
3320
|
|
|
2486
3321
|
/**
|
|
2487
3322
|
* @module decorator-validation
|
|
3323
|
+
* @description TypeScript decorator-based validation library
|
|
3324
|
+
* @summary This module provides a comprehensive validation framework using TypeScript decorators.
|
|
3325
|
+
* It exposes utility functions, validation decorators, and model-related functionality for
|
|
3326
|
+
* implementing type-safe, declarative validation in TypeScript applications.
|
|
2488
3327
|
*/
|
|
2489
|
-
|
|
2490
|
-
* @summary Model definition functionality
|
|
2491
|
-
* @description defines the base class and related functionality
|
|
2492
|
-
*
|
|
2493
|
-
* @namespace Model
|
|
2494
|
-
* @memberOf module:decorator-validation
|
|
2495
|
-
*/
|
|
2496
|
-
/**
|
|
2497
|
-
* @summary Holds all the supported decorators
|
|
2498
|
-
* @namespace Decorators
|
|
2499
|
-
* @memberOf module:decorator-validation
|
|
2500
|
-
*/
|
|
2501
|
-
/**
|
|
2502
|
-
* @summary Validation related functionality
|
|
2503
|
-
* @description Defines the Model validation apis and base classes for validators
|
|
2504
|
-
*
|
|
2505
|
-
* @namespace Validation
|
|
2506
|
-
* @memberOf module:decorator-validation
|
|
2507
|
-
*/
|
|
2508
|
-
/**
|
|
2509
|
-
* @namespace Dates
|
|
2510
|
-
* @memberOf module:decorator-validation
|
|
2511
|
-
*/
|
|
2512
|
-
/**
|
|
2513
|
-
* @namespace Hashing
|
|
2514
|
-
* @memberOf module:decorator-validation
|
|
2515
|
-
*/
|
|
2516
|
-
/**
|
|
2517
|
-
* @namespace Serialization
|
|
2518
|
-
* @memberOf module:decorator-validation
|
|
2519
|
-
*/
|
|
2520
|
-
/**
|
|
2521
|
-
* @namespace Format
|
|
2522
|
-
* @memberOf module:decorator-validation
|
|
2523
|
-
*/
|
|
2524
|
-
const VERSION = "1.6.0";
|
|
3328
|
+
const VERSION = "1.6.2";
|
|
2525
3329
|
|
|
2526
3330
|
exports.DAYS_OF_WEEK_NAMES = DAYS_OF_WEEK_NAMES;
|
|
2527
3331
|
exports.DEFAULT_ERROR_MESSAGES = DEFAULT_ERROR_MESSAGES;
|
|
2528
3332
|
exports.DEFAULT_PATTERNS = DEFAULT_PATTERNS;
|
|
3333
|
+
exports.Decoration = Decoration;
|
|
3334
|
+
exports.DefaultFlavour = DefaultFlavour;
|
|
2529
3335
|
exports.DefaultHashingMethod = DefaultHashingMethod;
|
|
2530
3336
|
exports.DefaultSerializationMethod = DefaultSerializationMethod;
|
|
2531
3337
|
exports.Hashing = Hashing;
|
|
@@ -2552,10 +3358,7 @@
|
|
|
2552
3358
|
exports.hashCode = hashCode;
|
|
2553
3359
|
exports.hashObj = hashObj;
|
|
2554
3360
|
exports.hashedBy = hashedBy;
|
|
2555
|
-
exports.isModel = isModel;
|
|
2556
|
-
exports.isPropertyModel = isPropertyModel;
|
|
2557
3361
|
exports.isValidDate = isValidDate;
|
|
2558
|
-
exports.isValidator = isValidator;
|
|
2559
3362
|
exports.jsTypes = jsTypes;
|
|
2560
3363
|
exports.list = list;
|
|
2561
3364
|
exports.max = max;
|
|
@@ -2582,4 +3385,4 @@
|
|
|
2582
3385
|
exports.validator = validator;
|
|
2583
3386
|
|
|
2584
3387
|
}));
|
|
2585
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVjb3JhdG9yLXZhbGlkYXRpb24uY2pzIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9jb25zdGFudHMudHMiLCIuLi9zcmMvdXRpbHMvc3RyaW5ncy50cyIsIi4uL3NyYy91dGlscy9kYXRlcy50cyIsIi4uL3NyYy91dGlscy9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL3V0aWxzL2hhc2hpbmcudHMiLCIuLi9zcmMvbW9kZWwvTW9kZWxFcnJvckRlZmluaXRpb24udHMiLCIuLi9zcmMvbW9kZWwvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9WYWxpZGF0b3JSZWdpc3RyeS50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRpb24udHMiLCIuLi9zcmMvbW9kZWwvdmFsaWRhdGlvbi50cyIsIi4uL3NyYy9tb2RlbC9Nb2RlbC50cyIsIi4uL3NyYy91dGlscy9zZXJpYWxpemF0aW9uLnRzIiwiLi4vbm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9EYXRlVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9QYXR0ZXJuVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9FbWFpbFZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvTGlzdFZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvTWF4TGVuZ3RoVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9NYXhWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL01pbkxlbmd0aFZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvTWluVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9QYXNzd29yZFZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvUmVxdWlyZWRWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL1N0ZXBWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL1R5cGVWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL1VSTFZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL2RlY29yYXRvcnMudHMiLCIuLi9zcmMvbW9kZWwvY29uc3RydWN0aW9uLnRzIiwiLi4vc3JjL21vZGVsL2RlY29yYXRvcnMudHMiLCIuLi9zcmMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSB2YXJpb3VzIE1vZGVsIGtleXMgdXNlZCBmb3IgcmVmbGVjdGlvblxuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBSRUZMRUNUIHByZWZpeCB0byBhbGwgb3RoZXIga2V5c1xuICogQHByb3BlcnR5IHtzdHJpbmd9IFRZUEUgdHlwZSBrZXlcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBQQVJBTVMgbWV0aG9kIHBhcmFtcyBrZXlcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBSRVRVUk4gbWV0aG9kIHJldHVybiBrZXlcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBNT0RFTCBtb2RlbCBrZXlcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBBTkNIT1IgYW5jaG9yIGtleS4gd2lsbCBzZXJ2ZSBhcyBhIGdob3N0IHByb3BlcnR5IGluIHRoZSBtb2RlbFxuICpcbiAqIEBjb25zdGFudCBNb2RlbEtleXNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uTW9kZWxcbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgZW51bSBNb2RlbEtleXMge1xuICBSRUZMRUNUID0gXCJkZWNhZi5tb2RlbC5cIixcbiAgVFlQRSA9IFwiZGVzaWduOnR5cGVcIixcbiAgUEFSQU1TID0gXCJkZXNpZ246cGFyYW10eXBlc1wiLFxuICBSRVRVUk4gPSBcImRlc2lnbjpyZXR1cm50eXBlXCIsXG4gIE1PREVMID0gXCJtb2RlbFwiLFxuICBBTkNIT1IgPSBcIl9fbW9kZWxcIixcbiAgQ09OU1RSVUNUSU9OID0gXCJjb25zdHJ1Y3RlZC1ieVwiLFxuICBBVFRSSUJVVEUgPSBcIl9fYXR0cmlidXRlc1wiLFxuICBIQVNISU5HID0gXCJoYXNoaW5nXCIsXG4gIFNFUklBTElaQVRJT04gPSBcInNlcmlhbGl6YXRpb25cIixcbn1cbiIsImltcG9ydCB7IE1vZGVsS2V5cyB9IGZyb20gXCIuLi8uLi91dGlscy9jb25zdGFudHNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBUaGUga2V5cyB1c2VkIGZvciB2YWxpZGF0aW9uXG4gKlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFJFRkxFQ1QgcHJlZml4ZXMgb3RoZXJzXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUkVRVUlSRUQgc2V0cyBhcyByZXF1aXJlZFxuICogQHByb3BlcnR5IHtzdHJpbmd9IE1JTiBkZWZpbmVzIG1pbiB2YWx1ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IE1BWCBkZWZpbmVzIG1heCB2YWx1ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFNURVAgZGVmaW5lcyBzdGVwXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUlOX0xFTkdUSCBkZWZpbmVzIG1pbiBsZW5ndGhcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBNQVhfTEVOR1RIIGRlZmluZXMgbWF4IGxlbmd0aFxuICogQHByb3BlcnR5IHtzdHJpbmd9IFBBVFRFUk4gZGVmaW5lcyBwYXR0ZXJuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gRU1BSUwgZGVmaW5lcyBlbWFpbFxuICogQHByb3BlcnR5IHtzdHJpbmd9IFVSTCBkZWZpbmVzIHVybFxuICogQHByb3BlcnR5IHtzdHJpbmd9IERBVEUgZGVmaW5lcyBkYXRlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gVFlQRSBkZWZpbmVzIHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBQQVNTV09SRCBkZWZpbmVzIHBhc3N3b3JkXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTElTVCBkZWZpbmVzIGxpc3RcbiAqXG4gKiBAY29uc3RhbnQgVmFsaWRhdGlvbktleXNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IFZhbGlkYXRpb25cbiAqL1xuZXhwb3J0IGNvbnN0IFZhbGlkYXRpb25LZXlzID0ge1xuICBSRUZMRUNUOiBgJHtNb2RlbEtleXMuUkVGTEVDVH12YWxpZGF0aW9uLmAsXG4gIFZBTElEQVRPUjogXCJ2YWxpZGF0b3JcIixcbiAgUkVRVUlSRUQ6IFwicmVxdWlyZWRcIixcbiAgTUlOOiBcIm1pblwiLFxuICBNQVg6IFwibWF4XCIsXG4gIFNURVA6IFwic3RlcFwiLFxuICBNSU5fTEVOR1RIOiBcIm1pbmxlbmd0aFwiLFxuICBNQVhfTEVOR1RIOiBcIm1heGxlbmd0aFwiLFxuICBQQVRURVJOOiBcInBhdHRlcm5cIixcbiAgRU1BSUw6IFwiZW1haWxcIixcbiAgVVJMOiBcInVybFwiLFxuICBEQVRFOiBcImRhdGVcIixcbiAgVFlQRTogXCJ0eXBlXCIsXG4gIFBBU1NXT1JEOiBcInBhc3N3b3JkXCIsXG4gIExJU1Q6IFwibGlzdFwiLFxufTtcblxuLyoqXG4gKiBAc3VtbWFyeSBsaXN0IG9mIG1vbnRoIG5hbWVzXG4gKiBAZGVzY3JpcHRpb24gU3RvcmVzIG1vbnRoIG5hbWVzLiBDYW4gYmUgY2hhbmdlZCBmb3IgbG9jYWxpemF0aW9uIHB1cnBvc2VzXG4gKlxuICogQGNvbnN0YW50IE1PTlRIX05BTUVTXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBNT05USF9OQU1FUyA9IFtcbiAgXCJKYW51YXJ5XCIsXG4gIFwiRmVicnVhcnlcIixcbiAgXCJNYXJjaFwiLFxuICBcIkFwcmlsXCIsXG4gIFwiTWF5XCIsXG4gIFwiSnVuZVwiLFxuICBcIkp1bHlcIixcbiAgXCJBdWd1c3RcIixcbiAgXCJTZXB0ZW1iZXJcIixcbiAgXCJPY3RvYmVyXCIsXG4gIFwiTm92ZW1iZXJcIixcbiAgXCJEZWNlbWJlclwiLFxuXTtcblxuLyoqXG4gKiBAc3VtbWFyeSBsaXN0IG9mIG5hbWVzIG9mIGRheXMgb2YgdGhlIHdlZWtcbiAqIEBkZXNjcmlwdGlvbiBTdG9yZXMgbmFtZXMgZm9yIGRheXMgb2YgdGhlIHdlZWsuIENhbiBiZSBjaGFuZ2VkIGZvciBsb2NhbGl6YXRpb24gcHVycG9zZXNcbiAqXG4gKiBAY29uc3RhbnQgREFZU19PRl9XRUVLX05BTUVTXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBEQVlTX09GX1dFRUtfTkFNRVMgPSBbXG4gIFwiU3VuZGF5XCIsXG4gIFwiTW9uZGF5XCIsXG4gIFwiVHVlc2RheVwiLFxuICBcIldlZG5lc2RheVwiLFxuICBcIlRodXJzZGF5XCIsXG4gIFwiRnJpZGF5XCIsXG4gIFwiU2F0dXJkYXlcIixcbl07XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgZGVmYXVsdCBlcnJvciBtZXNzYWdlc1xuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBSRVFVSVJFRCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBNSU4gZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUFYIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IE1JTl9MRU5HVEggZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUFYX0xFTkdUSCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBQQVRURVJOIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IEVNQUlMIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFVSTCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBUWVBFIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFNURVAgZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gREFURSBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBERUZBVUxUIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFBBU1NXT1JEIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IExJU1QgZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTElTVF9JTlNJREUgZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTU9ERUxfTk9UX0ZPVU5EIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICpcbiAqIEBjb25zdGFudCBERUZBVUxUX0VSUk9SX01FU1NBR0VTXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0VSUk9SX01FU1NBR0VTOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICBSRVFVSVJFRDogXCJUaGlzIGZpZWxkIGlzIHJlcXVpcmVkXCIsXG4gIE1JTjogXCJUaGUgbWluaW11bSB2YWx1ZSBpcyB7MH1cIixcbiAgTUFYOiBcIlRoZSBtYXhpbXVtIHZhbHVlIGlzIHswfVwiLFxuICBNSU5fTEVOR1RIOiBcIlRoZSBtaW5pbXVtIGxlbmd0aCBpcyB7MH1cIixcbiAgTUFYX0xFTkdUSDogXCJUaGUgbWF4aW11bSBsZW5ndGggaXMgezB9XCIsXG4gIFBBVFRFUk46IFwiVGhlIHZhbHVlIGRvZXMgbm90IG1hdGNoIHRoZSBwYXR0ZXJuXCIsXG4gIEVNQUlMOiBcIlRoZSB2YWx1ZSBpcyBub3QgYSB2YWxpZCBlbWFpbFwiLFxuICBVUkw6IFwiVGhlIHZhbHVlIGlzIG5vdCBhIHZhbGlkIFVSTFwiLFxuICBUWVBFOiBcIkludmFsaWQgdHlwZS4gRXhwZWN0ZWQgezB9LCByZWNlaXZlZCB7MX1cIixcbiAgU1RFUDogXCJJbnZhbGlkIHZhbHVlLiBOb3QgYSBzdGVwIG9mIHswfVwiLFxuICBEQVRFOiBcIkludmFsaWQgdmFsdWUuIG5vdCBhIHZhbGlkIERhdGVcIixcbiAgREVGQVVMVDogXCJUaGVyZSBpcyBhbiBFcnJvclwiLFxuICBQQVNTV09SRDpcbiAgICBcIk11c3QgYmUgYXQgbGVhc3QgOCBjaGFyYWN0ZXJzIGFuZCBjb250YWluIG9uZSBvZiBudW1iZXIsIGxvd2VyIGFuZCB1cHBlciBjYXNlIGxldHRlcnMsIGFuZCBzcGVjaWFsIGNoYXJhY3RlciAoQCQhJSo/Jl8tLiwpXCIsXG4gIExJU1Q6IFwiSW52YWxpZCBsaXN0IG9mIHswfVwiLFxuICBNT0RFTF9OT1RfRk9VTkQ6IFwiTm8gbW9kZWwgcmVnaXN0ZXJlZCB1bmRlciB7MH1cIixcbn07XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgdmFyaW91cyBkZWZhdWx0IHJlZ2V4cCBwYXR0ZXJucyB1c2VkXG4gKlxuICogQGVudW0gREVGQVVMVF9QQVRURVJOU1xuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5WYWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdGlvblxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9QQVRURVJOUyA9IHtcbiAgRU1BSUw6XG4gICAgL1thLXpBLVowLTkhIyQlJicqKy89P15fYHt8fX4tXSsoPzpcXC5bYS16QS1aMC05ISMkJSYnKisvPT9eX2B7fH1+LV0rKSpAKD86W2EtekEtWjAtOV0oPzpbYS16MC05LV0qW2EtekEtWjAtOV0pP1xcLikrW2EtekEtWjAtOV0oPzpbYS16QS1aMC05LV0qW2EtekEtWjAtOV0pPy8sXG4gIFVSTDogL14oPzooPzooPzpodHRwcz98ZnRwKTopP1xcL1xcLykoPzpcXFMrKD86OlxcUyopP0ApPyg/Oig/ISg/OjEwfDEyNykoPzpcXC5cXGR7MSwzfSl7M30pKD8hKD86MTY5XFwuMjU0fDE5MlxcLjE2OCkoPzpcXC5cXGR7MSwzfSl7Mn0pKD8hMTcyXFwuKD86MVs2LTldfDJcXGR8M1swLTFdKSg/OlxcLlxcZHsxLDN9KXsyfSkoPzpbMS05XVxcZD98MVxcZFxcZHwyWzAxXVxcZHwyMlswLTNdKSg/OlxcLig/OjE/XFxkezEsMn18MlswLTRdXFxkfDI1WzAtNV0pKXsyfSg/OlxcLig/OlsxLTldXFxkP3wxXFxkXFxkfDJbMC00XVxcZHwyNVswLTRdKSl8KD86KD86W2EtejAtOVxcdTAwYTEtXFx1ZmZmZl1bYS16MC05XFx1MDBhMS1cXHVmZmZmXy1dezAsNjJ9KT9bYS16MC05XFx1MDBhMS1cXHVmZmZmXVxcLikrKD86W2EtelxcdTAwYTEtXFx1ZmZmZl17Mix9XFwuPykpKD86OlxcZHsyLDV9KT8oPzpbLz8jXVxcUyopPyQvaSxcbiAgUEFTU1dPUkQ6IHtcbiAgICBDSEFSOF9PTkVfT0ZfRUFDSDpcbiAgICAgIC9eKD89LipbYS16XSkoPz0uKltBLVpdKSg/PS4qXFxkKSg/PS4qW0AkISUqPyZfXFwtLixdKVtBLVphLXpcXGRAJCElKj8mX1xcLS4sXXs4LH0kL2csXG4gIH0sXG59O1xuIiwiLyoqXG4gKiBAc3VtbWFyeSBVdGlsIGZ1bmN0aW9uIHRvIHByb3ZpZGUgc3RyaW5nIGZvcm1hdCBmdW5jdGlvbmFsaXR5IHNpbWlsYXIgdG8gQyMncyBzdHJpbmcuZm9ybWF0XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZ1xuICogQHBhcmFtIHtBcnJheTxzdHJpbmcgfCBudW1iZXI+fSBbYXJnc10gcmVwbGFjZW1lbnRzIG1hZGUgYnkgb3JkZXIgb2YgYXBwZWFyYW5jZSAocmVwbGFjZW1lbnQwIHdpbCByZXBsYWNlIHswfSBhbmQgc28gb24pXG4gKiBAcmV0dXJuIHtzdHJpbmd9IGZvcm1hdHRlZCBzdHJpbmdcbiAqXG4gKiBAZnVuY3Rpb24gc3RyaW5nRm9ybWF0XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlV0aWxzLkZvcm1hdFxuICogQGNhdGVnb3J5IEZvcm1hdFxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RyaW5nRm9ybWF0KHN0cmluZzogc3RyaW5nLCAuLi5hcmdzOiAoc3RyaW5nIHwgbnVtYmVyKVtdKSB7XG4gIHJldHVybiBzdHJpbmcucmVwbGFjZSgveyhcXGQrKX0vZywgZnVuY3Rpb24gKG1hdGNoLCBudW1iZXIpIHtcbiAgICByZXR1cm4gdHlwZW9mIGFyZ3NbbnVtYmVyXSAhPT0gXCJ1bmRlZmluZWRcIlxuICAgICAgPyBhcmdzW251bWJlcl0udG9TdHJpbmcoKVxuICAgICAgOiBcInVuZGVmaW5lZFwiO1xuICB9KTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBVdGlsIGZ1bmN0aW9uIHRvIHByb3ZpZGUgc3RyaW5nIGZvcm1hdCBmdW5jdGlvbmFsaXR5IHNpbWlsYXIgdG8gQyMncyBzdHJpbmcuZm9ybWF0XG4gKiBAZGVzY3JpcHRpb24gYWxpYXMgZm9yIHtAbGluayBzdHJpbmdGb3JtYXR9XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZ1xuICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MgcmVwbGFjZW1lbnRzIG1hZGUgYnkgb3JkZXIgb2YgYXBwZWFyYW5jZSAocmVwbGFjZW1lbnQwIHdpbCByZXBsYWNlIHswfSBhbmQgc28gb24pXG4gKiBAcmV0dXJuIHtzdHJpbmd9IGZvcm1hdHRlZCBzdHJpbmdcbiAqXG4gKiBAZnVuY3Rpb24gc2ZcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uVXRpbHMuRm9ybWF0XG4gKiBAY2F0ZWdvcnkgRm9ybWF0XG4gKi9cbmV4cG9ydCBjb25zdCBzZiA9IHN0cmluZ0Zvcm1hdDtcbiIsImltcG9ydCBcInJlZmxlY3QtbWV0YWRhdGFcIjtcbmltcG9ydCB7XG4gIERBWVNfT0ZfV0VFS19OQU1FUyxcbiAgTU9OVEhfTkFNRVMsXG59IGZyb20gXCIuLi92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBzZiB9IGZyb20gXCIuL3N0cmluZ3NcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBSZXZlcnNlcyB0aGUgcHJvY2VzcyBmcm9tIHtAbGluayBmb3JtYXREYXRlfVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBkYXRlIHRoZSBkYXRlIHN0cmluZyB0byBiZSBjb252ZXJ0ZWQgYmFjayBpbnRvIGRhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBmb3JtYXQgdGhlIGRhdGUgZm9ybWF0XG4gKiBAcmV0dXJuIHtEYXRlfSB0aGUgZGF0ZSBmcm9tIHRoZSBmb3JtYXQgb3IgdGhlIHN0YW5kYXJkIG5ldyBEYXRlKHtAcHJvcCBkYXRlfSkgaWYgdGhlIHN0cmluZyBjb3VsZG4ndCBiZSBwYXJzZWQgKGFyZSB5b3Ugc3VyZSB0aGUgZm9ybWF0IG1hdGNoZXMgdGhlIHN0cmluZz8pXG4gKlxuICogQGZ1bmN0aW9uIGRhdGVGcm9tRm9ybWF0XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlV0aWxzLkRhdGVzXG4gKiBAY2F0ZWdvcnkgRm9ybWF0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkYXRlRnJvbUZvcm1hdChkYXRlOiBzdHJpbmcsIGZvcm1hdDogc3RyaW5nKSB7XG4gIGxldCBmb3JtYXRSZWdleHA6IHN0cmluZyA9IGZvcm1hdDtcblxuICAvLyBIb3VyXG4gIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL2hoLykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJoaFwiLCBcIig/PGhvdXI+XFxcXGR7Mn0pXCIpO1xuICBlbHNlIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL2gvKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcImhcIiwgXCIoPzxob3VyPlxcXFxkezEsMn0pXCIpO1xuICBlbHNlIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL0hILykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJISFwiLCBcIig/PGhvdXI+XFxcXGR7Mn0pXCIpO1xuICBlbHNlIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL0gvKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcIkhcIiwgXCIoPzxob3VyPlxcXFxkezEsMn0pXCIpO1xuXG4gIC8vIE1pbnV0ZXNcbiAgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgvbW0vKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcIm1tXCIsIFwiKD88bWludXRlcz5cXFxcZHsyfSlcIik7XG4gIGVsc2UgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgvbS8pKVxuICAgIGZvcm1hdFJlZ2V4cCA9IGZvcm1hdFJlZ2V4cC5yZXBsYWNlKFwibVwiLCBcIig/PG1pbnV0ZXM+XFxcXGR7MSwyfSlcIik7XG5cbiAgLy8gU2Vjb25kc1xuICBpZiAoZm9ybWF0UmVnZXhwLm1hdGNoKC9zcy8pKVxuICAgIGZvcm1hdFJlZ2V4cCA9IGZvcm1hdFJlZ2V4cC5yZXBsYWNlKFwic3NcIiwgXCIoPzxzZWNvbmRzPlxcXFxkezJ9KVwiKTtcbiAgZWxzZSBpZiAoZm9ybWF0UmVnZXhwLm1hdGNoKC9zLykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJzXCIsIFwiKD88c2Vjb25kcz5cXFxcZHsxLDJ9KVwiKTtcblxuICAvLyBEYXlcbiAgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgvZGQvKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcImRkXCIsIFwiKD88ZGF5PlxcXFxkezJ9KVwiKTtcbiAgZWxzZSBpZiAoZm9ybWF0UmVnZXhwLm1hdGNoKC9kLykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJkXCIsIFwiKD88ZGF5PlxcXFxkezEsMn0pXCIpO1xuXG4gIC8vIERheSBPZiBXZWVrXG4gIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL0VFRUUvKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcIkVFRUVcIiwgXCIoPzxkYXlvZndlZWs+XFxcXHcrKVwiKTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWR1cGUtZWxzZS1pZlxuICBlbHNlIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL0VFRUUvKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcIkVFRVwiLCBcIig/PGRheW9md2Vlaz5cXFxcdyspXCIpO1xuXG4gIC8vIFllYXJcbiAgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgveXl5eS8pKVxuICAgIGZvcm1hdFJlZ2V4cCA9IGZvcm1hdFJlZ2V4cC5yZXBsYWNlKFwieXl5eVwiLCBcIig/PHllYXI+XFxcXGR7NH0pXCIpO1xuICBlbHNlIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL3l5LykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJ5eVwiLCBcIig/PHllYXI+XFxcXGR7Mn0pXCIpO1xuXG4gIC8vIE1vbnRoXG4gIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL01NTU0vKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcIk1NTU1cIiwgXCIoPzxtb250aG5hbWU+XFxcXHcrKVwiKTtcbiAgZWxzZSBpZiAoZm9ybWF0UmVnZXhwLm1hdGNoKC9NTU0vKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcIk1NTVwiLCBcIig/PG1vbnRobmFtZXNtYWxsPlxcXFx3KylcIik7XG4gIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL01NLykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJNTVwiLCBcIig/PG1vbnRoPlxcXFxkezJ9KVwiKTtcbiAgZWxzZSBpZiAoZm9ybWF0UmVnZXhwLm1hdGNoKC9NLykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJNXCIsIFwiKD88bW9udGg+XFxcXGR7MSwyfSlcIik7XG5cbiAgLy8gTWlsaXMgYW5kIEFtIFBtXG4gIGZvcm1hdFJlZ2V4cCA9IGZvcm1hdFJlZ2V4cFxuICAgIC5yZXBsYWNlKFwiU1wiLCBcIig/PG1pbGlzPlxcXFxkezEsM30pXCIpXG4gICAgLnJlcGxhY2UoXCJhYWFcIiwgXCIoPzxhbXBtPlxcXFx3ezJ9KVwiKTtcblxuICBjb25zdCByZWdleHAgPSBuZXcgUmVnRXhwKGZvcm1hdFJlZ2V4cCwgXCJnXCIpO1xuXG4gIGNvbnN0IG1hdGNoOiB7XG4gICAgZ3JvdXBzOiB7XG4gICAgICB5ZWFyPzogc3RyaW5nO1xuICAgICAgZGF5Pzogc3RyaW5nO1xuICAgICAgYW1wbT86IHN0cmluZztcbiAgICAgIGhvdXI/OiBzdHJpbmc7XG4gICAgICBtaW51dGVzPzogc3RyaW5nO1xuICAgICAgc2Vjb25kcz86IHN0cmluZztcbiAgICAgIG1pbGlzPzogc3RyaW5nO1xuICAgICAgbW9udGhuYW1lPzogc3RyaW5nO1xuICAgICAgbW9udGhuYW1lc21hbGw/OiBzdHJpbmc7XG4gICAgICBtb250aD86IHN0cmluZztcbiAgICB9O1xuICB9ID0gcmVnZXhwLmV4ZWMoZGF0ZSkgYXMgYW55O1xuXG4gIGlmICghbWF0Y2ggfHwgIW1hdGNoLmdyb3VwcykgcmV0dXJuIG5ldyBEYXRlKGRhdGUpO1xuXG4gIGNvbnN0IHNhZmVQYXJzZUludCA9IGZ1bmN0aW9uIChuPzogc3RyaW5nKSB7XG4gICAgaWYgKCFuKSByZXR1cm4gMDtcbiAgICBjb25zdCByZXN1bHQgPSBwYXJzZUludChuKTtcblxuICAgIHJldHVybiBpc05hTihyZXN1bHQpID8gMCA6IHJlc3VsdDtcbiAgfTtcblxuICBjb25zdCB5ZWFyID0gc2FmZVBhcnNlSW50KG1hdGNoLmdyb3Vwcy55ZWFyKTtcbiAgY29uc3QgZGF5ID0gc2FmZVBhcnNlSW50KG1hdGNoLmdyb3Vwcy5kYXkpO1xuXG4gIGNvbnN0IGFtUG0gPSBtYXRjaC5ncm91cHMuYW1wbTtcbiAgbGV0IGhvdXIgPSBzYWZlUGFyc2VJbnQobWF0Y2guZ3JvdXBzLmhvdXIpO1xuXG4gIGlmIChhbVBtKSBob3VyID0gYW1QbSA9PT0gXCJQTVwiID8gaG91ciArIDEyIDogaG91cjtcblxuICBjb25zdCBtaW51dGVzID0gc2FmZVBhcnNlSW50KG1hdGNoLmdyb3Vwcy5taW51dGVzKTtcbiAgY29uc3Qgc2Vjb25kcyA9IHNhZmVQYXJzZUludChtYXRjaC5ncm91cHMuc2Vjb25kcyk7XG4gIGNvbnN0IG1zID0gc2FmZVBhcnNlSW50KG1hdGNoLmdyb3Vwcy5taWxpcyk7XG5cbiAgY29uc3QgbW9udGhOYW1lID0gbWF0Y2guZ3JvdXBzLm1vbnRobmFtZTtcbiAgY29uc3QgbW9udGhOYW1lU21hbGwgPSBtYXRjaC5ncm91cHMubW9udGhuYW1lc21hbGw7XG4gIGxldCBtb250aDogbnVtYmVyIHwgc3RyaW5nID0gbWF0Y2guZ3JvdXBzLm1vbnRoIGFzIHN0cmluZztcbiAgaWYgKG1vbnRoTmFtZSkgbW9udGggPSBNT05USF9OQU1FUy5pbmRleE9mKG1vbnRoTmFtZSk7XG4gIGVsc2UgaWYgKG1vbnRoTmFtZVNtYWxsKSB7XG4gICAgY29uc3QgbSA9IE1PTlRIX05BTUVTLmZpbmQoKG0pID0+XG4gICAgICBtLnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aChtb250aE5hbWVTbWFsbC50b0xvd2VyQ2FzZSgpKVxuICAgICk7XG4gICAgaWYgKCFtKSByZXR1cm4gbmV3IERhdGUoZGF0ZSk7XG4gICAgbW9udGggPSBNT05USF9OQU1FUy5pbmRleE9mKG0pO1xuICB9IGVsc2UgbW9udGggPSBzYWZlUGFyc2VJbnQoYCR7bW9udGh9YCk7XG5cbiAgcmV0dXJuIG5ldyBEYXRlKHllYXIsIG1vbnRoIC0gMSwgZGF5LCBob3VyLCBtaW51dGVzLCBzZWNvbmRzLCBtcyk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgQmluZHMgYSBkYXRlIGZvcm1hdCB0byBhIHN0cmluZ1xuICogQHBhcmFtIHtEYXRlfSBbZGF0ZV1cbiAqIEBwYXJhbSB7c3RyaW5nfSBbZm9ybWF0XVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5VdGlscy5Gb3JtYXRcbiAqIEBjYXRlZ29yeSBVdGlsaXRpZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJpbmREYXRlVG9TdHJpbmcoZGF0ZTogRGF0ZSB8IHVuZGVmaW5lZCwgZm9ybWF0OiBzdHJpbmcpIHtcbiAgaWYgKCFkYXRlKSByZXR1cm47XG4gIGNvbnN0IGZ1bmMgPSAoKSA9PiBmb3JtYXREYXRlKGRhdGUsIGZvcm1hdCk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShkYXRlLCBcInRvSVNPU3RyaW5nXCIsIHtcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgIHZhbHVlOiBmdW5jLFxuICB9KTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGRhdGUsIFwidG9TdHJpbmdcIiwge1xuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgdmFsdWU6IGZ1bmMsXG4gIH0pO1xuICAvLyBPYmplY3Quc2V0UHJvdG90eXBlT2YoZGF0ZSwgRGF0ZS5wcm90b3R5cGUpO1xuICByZXR1cm4gZGF0ZTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBIZWxwZXIgZnVuY3Rpb24gdG8gYmUgdXNlZCBpbnN0ZWFkIG9mIGluc3RhbmNlT2YgRGF0ZVxuICogQHBhcmFtIGRhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uVXRpbHMuRGF0ZXNcbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkRGF0ZShkYXRlOiBhbnkpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBkYXRlICYmXG4gICAgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGRhdGUpID09PSBcIltvYmplY3QgRGF0ZV1cIiAmJlxuICAgICFOdW1iZXIuaXNOYU4oZGF0ZSlcbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBVdGlsIGZ1bmN0aW9uIHRvIHBhZCBudW1iZXJzXG4gKiBAcGFyYW0ge251bWJlcn0gbnVtXG4gKlxuICogQHJldHVybiB7c3RyaW5nfVxuICpcbiAqIEBmdW5jdGlvbiB0d29EaWdpdFBhZFxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5VdGlscy5Gb3JtYXRcbiAqIEBjYXRlZ29yeSBGb3JtYXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHR3b0RpZ2l0UGFkKG51bTogbnVtYmVyKTogc3RyaW5nIHtcbiAgcmV0dXJuIG51bSA8IDEwID8gXCIwXCIgKyBudW0gOiBudW0udG9TdHJpbmcoKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEYXRlIEZvcm1hdCBIYW5kbGluZ1xuICogQGRlc2NyaXB0aW9uIENvZGUgZnJvbSB7QGxpbmsgaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzU1MjQ2MS9ob3ctdG8tZm9ybWF0LWEtamF2YXNjcmlwdC1kYXRlfVxuICpcbiAqIDxwcmU+XG4gKiAgICAgIFVzaW5nIHNpbWlsYXIgZm9ybWF0dGluZyBhcyBNb21lbnQuanMsIENsYXNzIERhdGVUaW1lRm9ybWF0dGVyIChKYXZhKSwgYW5kIENsYXNzIFNpbXBsZURhdGVGb3JtYXQgKEphdmEpLFxuICogICAgICBJIGltcGxlbWVudGVkIGEgY29tcHJlaGVuc2l2ZSBzb2x1dGlvbiBmb3JtYXREYXRlKGRhdGUsIHBhdHRlcm5TdHIpIHdoZXJlIHRoZSBjb2RlIGlzIGVhc3kgdG8gcmVhZCBhbmQgbW9kaWZ5LlxuICogICAgICBZb3UgY2FuIGRpc3BsYXkgZGF0ZSwgdGltZSwgQU0vUE0sIGV0Yy5cbiAqXG4gKiAgICAgIERhdGUgYW5kIFRpbWUgUGF0dGVybnNcbiAqICAgICAgeXkgPSAyLWRpZ2l0IHllYXI7IHl5eXkgPSBmdWxsIHllYXJcbiAqICAgICAgTSA9IGRpZ2l0IG1vbnRoOyBNTSA9IDItZGlnaXQgbW9udGg7IE1NTSA9IHNob3J0IG1vbnRoIG5hbWU7IE1NTU0gPSBmdWxsIG1vbnRoIG5hbWVcbiAqICAgICAgRUVFRSA9IGZ1bGwgd2Vla2RheSBuYW1lOyBFRUUgPSBzaG9ydCB3ZWVrZGF5IG5hbWVcbiAqICAgICAgZCA9IGRpZ2l0IGRheTsgZGQgPSAyLWRpZ2l0IGRheVxuICogICAgICBoID0gaG91cnMgYW0vcG07IGhoID0gMi1kaWdpdCBob3VycyBhbS9wbTsgSCA9IGhvdXJzOyBISCA9IDItZGlnaXQgaG91cnNcbiAqICAgICAgbSA9IG1pbnV0ZXM7IG1tID0gMi1kaWdpdCBtaW51dGVzOyBhYWEgPSBBTS9QTVxuICogICAgICBzID0gc2Vjb25kczsgc3MgPSAyLWRpZ2l0IHNlY29uZHNcbiAqICAgICAgUyA9IG1pbGlzZWNvbmRzXG4gKiA8L3ByZT5cbiAqXG4gKiBAcGFyYW0ge0RhdGV9IGRhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0dGVyblN0cl0gZGVmYXVsdHMgdG8gJ3l5eXkvTU0vZGQnXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHRoZSBmb3JtYXR0ZWQgZGF0ZVxuICpcbiAqIEBmdW5jdGlvbiBmb3JtYXREYXRlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlV0aWxzLkRhdGVzXG4gKiBAY2F0ZWdvcnkgRm9ybWF0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXREYXRlKGRhdGU6IERhdGUsIHBhdHRlcm5TdHI6IHN0cmluZyA9IFwieXl5eS9NTS9kZFwiKSB7XG4gIGNvbnN0IGRheTogbnVtYmVyID0gZGF0ZS5nZXREYXRlKCksXG4gICAgbW9udGg6IG51bWJlciA9IGRhdGUuZ2V0TW9udGgoKSxcbiAgICB5ZWFyOiBudW1iZXIgPSBkYXRlLmdldEZ1bGxZZWFyKCksXG4gICAgaG91cjogbnVtYmVyID0gZGF0ZS5nZXRIb3VycygpLFxuICAgIG1pbnV0ZTogbnVtYmVyID0gZGF0ZS5nZXRNaW51dGVzKCksXG4gICAgc2Vjb25kOiBudW1iZXIgPSBkYXRlLmdldFNlY29uZHMoKSxcbiAgICBtaWxpc2Vjb25kczogbnVtYmVyID0gZGF0ZS5nZXRNaWxsaXNlY29uZHMoKSxcbiAgICBoOiBudW1iZXIgPSBob3VyICUgMTIsXG4gICAgaGg6IHN0cmluZyA9IHR3b0RpZ2l0UGFkKGgpLFxuICAgIEhIOiBzdHJpbmcgPSB0d29EaWdpdFBhZChob3VyKSxcbiAgICBtbTogc3RyaW5nID0gdHdvRGlnaXRQYWQobWludXRlKSxcbiAgICBzczogc3RyaW5nID0gdHdvRGlnaXRQYWQoc2Vjb25kKSxcbiAgICBhYWE6IHN0cmluZyA9IGhvdXIgPCAxMiA/IFwiQU1cIiA6IFwiUE1cIixcbiAgICBFRUVFOiBzdHJpbmcgPSBEQVlTX09GX1dFRUtfTkFNRVNbZGF0ZS5nZXREYXkoKV0sXG4gICAgRUVFOiBzdHJpbmcgPSBFRUVFLnN1YnN0cigwLCAzKSxcbiAgICBkZDogc3RyaW5nID0gdHdvRGlnaXRQYWQoZGF5KSxcbiAgICBNOiBudW1iZXIgPSBtb250aCArIDEsXG4gICAgTU06IHN0cmluZyA9IHR3b0RpZ2l0UGFkKE0pLFxuICAgIE1NTU06IHN0cmluZyA9IE1PTlRIX05BTUVTW21vbnRoXSxcbiAgICBNTU06IHN0cmluZyA9IE1NTU0uc3Vic3RyKDAsIDMpLFxuICAgIHl5eXk6IHN0cmluZyA9IHllYXIgKyBcIlwiLFxuICAgIHl5OiBzdHJpbmcgPSB5eXl5LnN1YnN0cigyLCAyKTtcbiAgLy8gY2hlY2tzIHRvIHNlZSBpZiBtb250aCBuYW1lIHdpbGwgYmUgdXNlZFxuICBwYXR0ZXJuU3RyID0gcGF0dGVyblN0clxuICAgIC5yZXBsYWNlKFwiaGhcIiwgaGgpXG4gICAgLnJlcGxhY2UoXCJoXCIsIGgudG9TdHJpbmcoKSlcbiAgICAucmVwbGFjZShcIkhIXCIsIEhIKVxuICAgIC5yZXBsYWNlKFwiSFwiLCBob3VyLnRvU3RyaW5nKCkpXG4gICAgLnJlcGxhY2UoXCJtbVwiLCBtbSlcbiAgICAucmVwbGFjZShcIm1cIiwgbWludXRlLnRvU3RyaW5nKCkpXG4gICAgLnJlcGxhY2UoXCJzc1wiLCBzcylcbiAgICAucmVwbGFjZShcInNcIiwgc2Vjb25kLnRvU3RyaW5nKCkpXG4gICAgLnJlcGxhY2UoXCJTXCIsIG1pbGlzZWNvbmRzLnRvU3RyaW5nKCkpXG4gICAgLnJlcGxhY2UoXCJkZFwiLCBkZClcbiAgICAucmVwbGFjZShcImRcIiwgZGF5LnRvU3RyaW5nKCkpXG5cbiAgICAucmVwbGFjZShcIkVFRUVcIiwgRUVFRSlcbiAgICAucmVwbGFjZShcIkVFRVwiLCBFRUUpXG4gICAgLnJlcGxhY2UoXCJ5eXl5XCIsIHl5eXkpXG4gICAgLnJlcGxhY2UoXCJ5eVwiLCB5eSlcbiAgICAucmVwbGFjZShcImFhYVwiLCBhYWEpO1xuICBpZiAocGF0dGVyblN0ci5pbmRleE9mKFwiTU1NXCIpID4gLTEpIHtcbiAgICBwYXR0ZXJuU3RyID0gcGF0dGVyblN0ci5yZXBsYWNlKFwiTU1NTVwiLCBNTU1NKS5yZXBsYWNlKFwiTU1NXCIsIE1NTSk7XG4gIH0gZWxzZSB7XG4gICAgcGF0dGVyblN0ciA9IHBhdHRlcm5TdHIucmVwbGFjZShcIk1NXCIsIE1NKS5yZXBsYWNlKFwiTVwiLCBNLnRvU3RyaW5nKCkpO1xuICB9XG4gIHJldHVybiBwYXR0ZXJuU3RyO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFBhcnNlcyBhIGRhdGUgZnJvbSBhIHNwZWNpZmllZCBmb3JtYXRcbiAqIEBwYXJhbSB7c3RyaW5nfSBmb3JtYXRcbiAqIEBwYXJhbSB7c3RyaW5nIHwgRGF0ZSB8IG51bWJlcn0gW3ZdXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlV0aWxzLkRhdGVzXG4gKiBAY2F0ZWdvcnkgRm9ybWF0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZURhdGUoZm9ybWF0OiBzdHJpbmcsIHY/OiBzdHJpbmcgfCBEYXRlIHwgbnVtYmVyKSB7XG4gIGxldCB2YWx1ZTogRGF0ZSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICBpZiAoIXYpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgaWYgKHYgaW5zdGFuY2VvZiBEYXRlKVxuICAgIHRyeSB7XG4gICAgICB2YWx1ZSA9IGRhdGVGcm9tRm9ybWF0KGZvcm1hdERhdGUodiBhcyBEYXRlLCBmb3JtYXQpLCBmb3JtYXQpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBzZihcIkNvdWxkIG5vdCBjb252ZXJ0IGRhdGUgezB9IHRvIGZvcm1hdDogezF9XCIsIHYudG9TdHJpbmcoKSwgZm9ybWF0KVxuICAgICAgKTtcbiAgICB9XG4gIGVsc2UgaWYgKHR5cGVvZiB2ID09PSBcInN0cmluZ1wiKSB7XG4gICAgdmFsdWUgPSBkYXRlRnJvbUZvcm1hdCh2LCBmb3JtYXQpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiB2ID09PSBcIm51bWJlclwiKSB7XG4gICAgY29uc3QgZCA9IG5ldyBEYXRlKHYpO1xuICAgIHZhbHVlID0gZGF0ZUZyb21Gb3JtYXQoZm9ybWF0RGF0ZShkLCBmb3JtYXQpLCBmb3JtYXQpO1xuICB9IGVsc2UgaWYgKGlzVmFsaWREYXRlKHYpKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGQgPSBuZXcgRGF0ZSh2KTtcbiAgICAgIHZhbHVlID0gZGF0ZUZyb21Gb3JtYXQoZm9ybWF0RGF0ZShkLCBmb3JtYXQpLCBmb3JtYXQpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgc2YoXCJDb3VsZCBub3QgY29udmVydCBkYXRlIHswfSB0byBmb3JtYXQ6IHsxfVwiLCB2LCBmb3JtYXQpXG4gICAgICApO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgdmFsdWUgcHJvdmlkZWQgJHt2fWApO1xuICB9XG4gIHJldHVybiBiaW5kRGF0ZVRvU3RyaW5nKHZhbHVlLCBmb3JtYXQpO1xufVxuIiwiaW1wb3J0IHsgYXBwbHksIG1ldGFkYXRhIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBNb2RlbEtleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHByb3Aoa2V5OiBzdHJpbmcgPSBNb2RlbEtleXMuQVRUUklCVVRFKSB7XG4gIHJldHVybiAobW9kZWw6IG9iamVjdCwgcHJvcGVydHlLZXk/OiBhbnkpOiB2b2lkID0+IHtcbiAgICBsZXQgcHJvcHM6IHN0cmluZ1tdO1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9kZWwsIGtleSkpIHtcbiAgICAgIHByb3BzID0gKG1vZGVsIGFzIGFueSlba2V5XTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvcHMgPSAobW9kZWwgYXMgYW55KVtrZXldID0gW107XG4gICAgfVxuICAgIGlmICghcHJvcHMuaW5jbHVkZXMocHJvcGVydHlLZXkgYXMgc3RyaW5nKSlcbiAgICAgIHByb3BzLnB1c2gocHJvcGVydHlLZXkgYXMgc3RyaW5nKTtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHByb3BNZXRhZGF0YTxWPihrZXk6IHN0cmluZywgdmFsdWU6IFYpIHtcbiAgcmV0dXJuIGFwcGx5KHByb3AoKSwgbWV0YWRhdGE8Vj4oa2V5LCB2YWx1ZSkpO1xufVxuIiwiLyoqXG4gKiBAc3VtbWFyeSBNaW1pY3MgSmF2YSdzIFN0cmluZydzIEhhc2ggaW1wbGVtZW50YXRpb25cbiAqXG4gKiBAcGFyYW0ge3N0cmluZyB8IG51bWJlciB8IHN5bWJvbCB8IERhdGV9IG9ialxuICogQHJldHVybiB7bnVtYmVyfSBoYXNoIHZhbHVlIG9mIG9ialxuICpcbiAqIEBmdW5jdGlvbiBoYXNoQ29kZVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5VdGlscy5IYXNoaW5nXG4gKiBAY2F0ZWdvcnkgSGFzaGluZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzaENvZGUob2JqOiBzdHJpbmcgfCBudW1iZXIgfCBzeW1ib2wgfCBEYXRlKTogc3RyaW5nIHtcbiAgb2JqID0gU3RyaW5nKG9iaik7XG4gIGxldCBoYXNoID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjaGFyYWN0ZXIgPSBvYmouY2hhckNvZGVBdChpKTtcbiAgICBoYXNoID0gKGhhc2ggPDwgNSkgLSBoYXNoICsgY2hhcmFjdGVyO1xuICAgIGhhc2ggPSBoYXNoICYgaGFzaDsgLy8gQ29udmVydCB0byAzMmJpdCBpbnRlZ2VyXG4gIH1cbiAgcmV0dXJuIGhhc2gudG9TdHJpbmcoKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRlaCB0eXBlIGZvciBhIEhhc2hpbmcgZnVuY3Rpb25cbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uVXRpbHMuSGFzaGluZ1xuICogQGNhdGVnb3J5IEhhc2hpbmdcbiAqL1xuZXhwb3J0IHR5cGUgSGFzaGluZ0Z1bmN0aW9uID0gKHZhbHVlOiBhbnksIC4uLmFyZ3M6IGFueVtdKSA9PiBzdHJpbmc7XG5cbi8qKlxuICogQHN1bW1hcnkgSGFzaGVzIGFuIG9iamVjdCBieSBjb21iaW5pbmcgdGhlIGhhc2ggb2YgYWxsIGl0cyBwcm9wZXJ0aWVzXG4gKlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBvYmpcbiAqIEByZXR1cm4ge3N0cmluZ30gdGhlIHJlc3VsdGluZyBoYXNoXG4gKlxuICogQGZ1bmN0aW9uIGhhc2hPYmpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uVXRpbHMuSGFzaGluZ1xuICogQGNhdGVnb3J5IEhhc2hpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc2hPYmoob2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgYW55W10pOiBzdHJpbmcge1xuICBjb25zdCBoYXNoUmVkdWNlciA9IGZ1bmN0aW9uIChoOiBudW1iZXIgfCBzdHJpbmcsIGVsOiBhbnkpOiBzdHJpbmcgfCBudW1iZXIge1xuICAgIGNvbnN0IGVsSGFzaCA9IGhhc2hGdW5jdGlvbihlbCk7XG5cbiAgICBpZiAodHlwZW9mIGVsSGFzaCA9PT0gXCJzdHJpbmdcIilcbiAgICAgIHJldHVybiBoYXNoRnVuY3Rpb24oKChoIGFzIHN0cmluZykgfHwgXCJcIikgKyBoYXNoRnVuY3Rpb24oZWwpKTtcblxuICAgIGggPSBoIHx8IDA7XG4gICAgaCA9ICgoaCBhcyBudW1iZXIpIDw8IDUpIC0gKGggYXMgbnVtYmVyKSArIGVsSGFzaDtcbiAgICByZXR1cm4gaCAmIGg7XG4gIH07XG5cbiAgY29uc3QgZnVuYzogSGFzaGluZ0Z1bmN0aW9uID0gaGFzaENvZGU7XG5cbiAgY29uc3QgaGFzaEZ1bmN0aW9uID0gZnVuY3Rpb24gKHZhbHVlOiBhbnkpOiBzdHJpbmcgfCBudW1iZXIge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIpIHJldHVybiBcIlwiO1xuICAgIGlmIChbXCJzdHJpbmdcIiwgXCJudW1iZXJcIiwgXCJzeW1ib2xcIl0uaW5kZXhPZih0eXBlb2YgdmFsdWUpICE9PSAtMSlcbiAgICAgIHJldHVybiBmdW5jKHZhbHVlLnRvU3RyaW5nKCkpO1xuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHJldHVybiBmdW5jKHZhbHVlLmdldFRpbWUoKSk7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSByZXR1cm4gdmFsdWUucmVkdWNlKGhhc2hSZWR1Y2VyLCB1bmRlZmluZWQpO1xuICAgIHJldHVybiAoT2JqZWN0LnZhbHVlcyh2YWx1ZSkgYXMgKHN0cmluZyB8IG51bWJlcilbXSkucmVkdWNlKFxuICAgICAgaGFzaFJlZHVjZXIsXG4gICAgICB1bmRlZmluZWQgYXMgdW5rbm93biBhcyBzdHJpbmcgfCBudW1iZXJcbiAgICApO1xuICB9O1xuXG4gIGNvbnN0IHJlc3VsdCA9IE9iamVjdC52YWx1ZXMob2JqKS5yZWR1Y2UoaGFzaFJlZHVjZXIsIDApO1xuXG4gIHJldHVybiAodHlwZW9mIHJlc3VsdCA9PT0gXCJudW1iZXJcIiA/IE1hdGguYWJzKHJlc3VsdCkgOiByZXN1bHQpLnRvU3RyaW5nKCk7XG59XG5cbmV4cG9ydCBjb25zdCBEZWZhdWx0SGFzaGluZ01ldGhvZCA9IFwiZGVmYXVsdFwiO1xuXG5leHBvcnQgY2xhc3MgSGFzaGluZyB7XG4gIHByaXZhdGUgc3RhdGljIGN1cnJlbnQ6IHN0cmluZyA9IERlZmF1bHRIYXNoaW5nTWV0aG9kO1xuXG4gIHByaXZhdGUgc3RhdGljIGNhY2hlOiBSZWNvcmQ8c3RyaW5nLCBIYXNoaW5nRnVuY3Rpb24+ID0ge1xuICAgIGRlZmF1bHQ6IGhhc2hPYmosXG4gIH07XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0KGtleTogc3RyaW5nKTogYW55IHtcbiAgICBpZiAoa2V5IGluIHRoaXMuY2FjaGUpIHJldHVybiB0aGlzLmNhY2hlW2tleV07XG4gICAgdGhyb3cgbmV3IEVycm9yKGBObyBoYXNoaW5nIG1ldGhvZCByZWdpc3RlcmVkIHVuZGVyICR7a2V5fWApO1xuICB9XG5cbiAgc3RhdGljIHJlZ2lzdGVyKFxuICAgIGtleTogc3RyaW5nLFxuICAgIGZ1bmM6IEhhc2hpbmdGdW5jdGlvbixcbiAgICBzZXREZWZhdWx0ID0gZmFsc2VcbiAgKTogdm9pZCB7XG4gICAgaWYgKGtleSBpbiB0aGlzLmNhY2hlKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBIYXNoaW5nIG1ldGhvZCAke2tleX0gYWxyZWFkeSByZWdpc3RlcmVkYCk7XG4gICAgdGhpcy5jYWNoZVtrZXldID0gZnVuYztcbiAgICBpZiAoc2V0RGVmYXVsdCkgdGhpcy5jdXJyZW50ID0ga2V5O1xuICB9XG5cbiAgc3RhdGljIGhhc2gob2JqOiBhbnksIG1ldGhvZD86IHN0cmluZywgLi4uYXJnczogYW55W10pIHtcbiAgICBpZiAoIW1ldGhvZCkgcmV0dXJuIHRoaXMuZ2V0KHRoaXMuY3VycmVudCkob2JqLCAuLi5hcmdzKTtcbiAgICByZXR1cm4gdGhpcy5nZXQobWV0aG9kKShvYmosIC4uLmFyZ3MpO1xuICB9XG5cbiAgc3RhdGljIHNldERlZmF1bHQobWV0aG9kOiBzdHJpbmcpIHtcbiAgICB0aGlzLmN1cnJlbnQgPSB0aGlzLmdldChtZXRob2QpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBNb2RlbEVycm9ycyB9IGZyb20gXCIuLi92YWxpZGF0aW9uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgSGVscGVyIENsYXNzIHRvIGhvbGQgdGhlIGVycm9yIHJlc3VsdHNcbiAqIEBkZXNjcmlwdGlvbiBob2xkcyBlcnJvciByZXN1bHRzIGluIGFuICdpbmRleGFibGUnIG1hbm5lclxuICogd2hpbGUgc3RpbGwgcHJvdmlkaW5nIHRoZSBzYW1lIHJlc3VsdCBvbiB0b1N0cmluZ1xuICpcbiAqIEBwYXJhbSB7TW9kZWxFcnJvcnN9IGVycm9yc1xuICpcbiAqIEBjbGFzcyBNb2RlbEVycm9yRGVmaW5pdGlvblxuICpcbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgY2xhc3MgTW9kZWxFcnJvckRlZmluaXRpb24ge1xuICBbaW5kZXhlcjogc3RyaW5nXTpcbiAgICB8IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD5cbiAgICB8ICgoKSA9PiBzdHJpbmcgfCB1bmRlZmluZWQpO1xuXG4gIGNvbnN0cnVjdG9yKGVycm9yczogTW9kZWxFcnJvcnMpIHtcbiAgICBmb3IgKGNvbnN0IHByb3AgaW4gZXJyb3JzKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGVycm9ycywgcHJvcCkgJiYgZXJyb3JzW3Byb3BdKVxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcyBhcyBhbnksIHByb3AsIHtcbiAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICAgICAgdmFsdWU6IGVycm9yc1twcm9wXSxcbiAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBPdXRwdXRzIHRoZSBjbGFzcyB0byBhIG5pY2UgcmVhZGFibGUgc3RyaW5nXG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKi9cbiAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICBjb25zdCBzZWxmOiBhbnkgPSB0aGlzIGFzIGFueTtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMoc2VsZilcbiAgICAgIC5maWx0ZXIoXG4gICAgICAgIChrKSA9PlxuICAgICAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzZWxmLCBrKSAmJlxuICAgICAgICAgIHR5cGVvZiBzZWxmW2tdICE9PSBcImZ1bmN0aW9uXCJcbiAgICAgIClcbiAgICAgIC5yZWR1Y2UoKGFjY3VtOiBzdHJpbmcsIHByb3ApID0+IHtcbiAgICAgICAgbGV0IHByb3BFcnJvcjogc3RyaW5nIHwgdW5kZWZpbmVkID0gT2JqZWN0LmtleXMoc2VsZltwcm9wXSkucmVkdWNlKFxuICAgICAgICAgIChwcm9wQWNjdW06IHVuZGVmaW5lZCB8IHN0cmluZywga2V5KSA9PiB7XG4gICAgICAgICAgICBpZiAoIXByb3BBY2N1bSkgcHJvcEFjY3VtID0gc2VsZltwcm9wXVtrZXldO1xuICAgICAgICAgICAgZWxzZSBwcm9wQWNjdW0gKz0gYFxcbiR7c2VsZltwcm9wXVtrZXldfWA7XG4gICAgICAgICAgICByZXR1cm4gcHJvcEFjY3VtO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgdW5kZWZpbmVkXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHByb3BFcnJvcikge1xuICAgICAgICAgIHByb3BFcnJvciA9IGAke3Byb3B9IC0gJHtwcm9wRXJyb3J9YDtcbiAgICAgICAgICBpZiAoIWFjY3VtKSBhY2N1bSA9IHByb3BFcnJvcjtcbiAgICAgICAgICBlbHNlIGFjY3VtICs9IGBcXG4ke3Byb3BFcnJvcn1gO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgfSwgXCJcIik7XG4gIH1cbn1cbiIsIi8qKlxuICogQHN1bW1hcnkgUmVmZXJlbmNlcyB0aGUgcmVsZXZhbnQgSlMgcHJpbWl0aXZlc1xuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBTVFJJTkcgcmVmZXJlbmNlcyB0aGUgc3RyaW5nIHByaW1pdGl2ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IE5VTUJFUiByZWZlcmVuY2VzIHRoZSBudW1iZXIgcHJpbWl0aXZlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gQk9PTEVBTiByZWZlcmVuY2VzIHRoZSBib29sZWFuIHByaW1pdGl2ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IEJJR0lOVCByZWZlcmVuY2VzIHRoZSBiaWdpbnQgcHJpbWl0aXZlXG4gKlxuICogQGNvbnN0YW50IFByaW1pdGl2ZXNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uTW9kZWxcbiAqL1xuZXhwb3J0IGVudW0gUHJpbWl0aXZlcyB7XG4gIFNUUklORyA9IFwic3RyaW5nXCIsXG4gIE5VTUJFUiA9IFwibnVtYmVyXCIsXG4gIEJPT0xFQU4gPSBcImJvb2xlYW5cIixcbiAgQklHSU5UID0gXCJiaWdpbnRcIixcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBSZWZlcmVuY2VzIHRoZSBSZXNlcnZlZCBtb2RlbCBuYW1lcyB0byBpZ25vcmUgZHVyaW5nIE1vZGVsIHJlYnVpbGRpbmdcbiAqXG4gKiBAcHJvcGVydHkge3N0cmluZ30gU1RSSU5HXG4gKiBAcHJvcGVydHkge3N0cmluZ30gT0JKRUNUXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTlVNQkVSXG4gKiBAcHJvcGVydHkge3N0cmluZ30gQk9PTEVBTlxuICogQHByb3BlcnR5IHtzdHJpbmd9IEJJR0lOVFxuICogQHByb3BlcnR5IHtzdHJpbmd9IERBVEVcbiAqXG4gKiBAY29uc3RhbnQgUmVzZXJ2ZWRNb2RlbHNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uTW9kZWxcbiAqL1xuZXhwb3J0IGVudW0gUmVzZXJ2ZWRNb2RlbHMge1xuICBTVFJJTkcgPSBcInN0cmluZ1wiLFxuICBPQkpFQ1QgPSBcIm9iamVjdFwiLFxuICBOVU1CRVIgPSBcIm51bWJlclwiLFxuICBCT09MRUFOID0gXCJib29sZWFuXCIsXG4gIEJJR0lOVCA9IFwiYmlnaW50XCIsXG4gIERBVEUgPSBcImRhdGVcIixcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBSZWZlcmVuY2VzIHRoZSBiYXNpYyBzdXBwb3J0ZWQganMgdHlwZXNcbiAqXG4gKiBAcHJvcGVydHkge3N0cmluZ30gc3RyaW5nXG4gKiBAcHJvcGVydHkge3N0cmluZ30gYXJyYXlcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBudW1iZXJcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBib29sZWFuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gc3ltYm9sXG4gKiBAcHJvcGVydHkge3N0cmluZ30gZnVuY3Rpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBvYmplY3RcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB1bmRlZmluZWRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBudWxsXG4gKiBAcHJvcGVydHkge3N0cmluZ30gQklHSU5UXG4gKlxuICogQGNvbnN0YW50IGpzVHlwZXNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uTW9kZWxcbiAqL1xuZXhwb3J0IGNvbnN0IGpzVHlwZXMgPSBbXG4gIFwic3RyaW5nXCIsXG4gIFwiYXJyYXlcIixcbiAgXCJudW1iZXJcIixcbiAgXCJib29sZWFuXCIsXG4gIFwic3ltYm9sXCIsXG4gIFwiZnVuY3Rpb25cIixcbiAgXCJvYmplY3RcIixcbiAgXCJ1bmRlZmluZWRcIixcbiAgXCJudWxsXCIsXG4gIFwiYmlnaW50XCIsXG5dO1xuIiwiaW1wb3J0IHsgVmFsaWRhdG9yRGVmaW5pdGlvbiB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgSVZhbGlkYXRvclJlZ2lzdHJ5IH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgdHlwZSB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IER1Y2sgdHlwaW5nIGZvciBWYWxpZGF0b3JzXG4gKiBAZnVuY3Rpb24gaXNWYWxpZGF0b3JcbiAqIEBwYXJhbSB2YWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRhdG9yKHZhbDogYW55KSB7XG4gIHJldHVybiB2YWwuY29uc3RydWN0b3IgJiYgdmFsW1wiaGFzRXJyb3JzXCJdO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IEJhc2UgSW1wbGVtZW50YXRpb24gb2YgYSBWYWxpZGF0b3IgUmVnaXN0cnlcbiAqXG4gKiBAcHJvcCB7VmFsaWRhdG9yW119IFt2YWxpZGF0b3JzXSB0aGUgaW5pdGlhbCB2YWxpZGF0b3JzIHRvIHJlZ2lzdGVyXG4gKlxuICogQGNsYXNzIFZhbGlkYXRvclJlZ2lzdHJ5XG4gKiBAaW1wbGVtZW50cyBJVmFsaWRhdG9yUmVnaXN0cnk8VD5cbiAqXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdGlvblxuICovXG5leHBvcnQgY2xhc3MgVmFsaWRhdG9yUmVnaXN0cnk8VCBleHRlbmRzIFZhbGlkYXRvcj5cbiAgaW1wbGVtZW50cyBJVmFsaWRhdG9yUmVnaXN0cnk8VD5cbntcbiAgcHJpdmF0ZSBjYWNoZTogYW55ID0ge307XG4gIHByaXZhdGUgY3VzdG9tS2V5Q2FjaGU6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG5cbiAgY29uc3RydWN0b3IoLi4udmFsaWRhdG9yczogKFZhbGlkYXRvckRlZmluaXRpb24gfCBWYWxpZGF0b3IpW10pIHtcbiAgICB0aGlzLmN1c3RvbUtleUNhY2hlID0ge307XG4gICAgdGhpcy5yZWdpc3RlciguLi52YWxpZGF0b3JzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSByZXRyaWV2ZXMgdGhlIGN1c3RvbSBrZXlzXG4gICAqL1xuICBnZXRDdXN0b21LZXlzKCk6IHsgW2luZGV4ZXI6IHN0cmluZ106IHN0cmluZyB9IHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5jdXN0b21LZXlDYWNoZSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgcmV0cmlldmVzIHRoZSByZWdpc3RlcmVkIHZhbGlkYXRvcnMga2V5c1xuICAgKi9cbiAgZ2V0S2V5cygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuY2FjaGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyBhIHZhbGlkYXRvclxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsaWRhdG9yS2V5IG9uZSBvZiB0aGUge0BsaW5rIFZhbGlkYXRpb25LZXlzfVxuICAgKiBAcmV0dXJuIHtWYWxpZGF0b3IgfCB1bmRlZmluZWR9IHRoZSByZWdpc3RlcmVkIFZhbGlkYXRvciBvciB1bmRlZmluZWQgaWYgdGhlcmUgaXMgbm9ubyBtYXRjaGluZyB0aGUgcHJvdmlkZWQga2V5XG4gICAqL1xuICBnZXQ8VCBleHRlbmRzIFZhbGlkYXRvcj4odmFsaWRhdG9yS2V5OiBzdHJpbmcpOiBUIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoISh2YWxpZGF0b3JLZXkgaW4gdGhpcy5jYWNoZSkpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBjbGFzc09ySW5zdGFuY2UgPSB0aGlzLmNhY2hlW3ZhbGlkYXRvcktleV07XG4gICAgaWYgKGlzVmFsaWRhdG9yKGNsYXNzT3JJbnN0YW5jZSkpIHJldHVybiBjbGFzc09ySW5zdGFuY2UgYXMgVDtcbiAgICBjb25zdCBjb25zdHJ1Y3RvciA9IGNsYXNzT3JJbnN0YW5jZS5kZWZhdWx0IHx8IGNsYXNzT3JJbnN0YW5jZTtcbiAgICBjb25zdCBpbnN0YW5jZSA9IG5ldyBjb25zdHJ1Y3RvcigpO1xuICAgIHRoaXMuY2FjaGVbdmFsaWRhdG9yS2V5XSA9IGluc3RhbmNlO1xuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZWdpc3RlcnMgdGhlIHByb3ZpZGVkIHZhbGlkYXRvcnMgb250byB0aGUgcmVnaXN0cnlcbiAgICpcbiAgICogQHBhcmFtIHtUW10gfCBWYWxpZGF0b3JEZWZpbml0aW9uW119IHZhbGlkYXRvclxuICAgKi9cbiAgcmVnaXN0ZXI8VCBleHRlbmRzIFZhbGlkYXRvcj4oXG4gICAgLi4udmFsaWRhdG9yOiAoVmFsaWRhdG9yRGVmaW5pdGlvbiB8IFQpW11cbiAgKTogdm9pZCB7XG4gICAgdmFsaWRhdG9yLmZvckVhY2goKHYpID0+IHtcbiAgICAgIGlmIChpc1ZhbGlkYXRvcih2KSkge1xuICAgICAgICAvLyBjb25zdCBrID1cblxuICAgICAgICBpZiAoKHYgYXMgVmFsaWRhdG9yRGVmaW5pdGlvbikudmFsaWRhdGlvbktleSBpbiB0aGlzLmNhY2hlKSByZXR1cm47XG4gICAgICAgIHRoaXMuY2FjaGVbKHYgYXMgVmFsaWRhdG9yRGVmaW5pdGlvbikudmFsaWRhdGlvbktleV0gPSB2O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgeyB2YWxpZGF0aW9uS2V5LCB2YWxpZGF0b3IsIHNhdmUgfSA9IHYgYXMgVmFsaWRhdG9yRGVmaW5pdGlvbjtcbiAgICAgICAgaWYgKHZhbGlkYXRpb25LZXkgaW4gdGhpcy5jYWNoZSkgcmV0dXJuO1xuICAgICAgICB0aGlzLmNhY2hlW3ZhbGlkYXRpb25LZXldID0gdmFsaWRhdG9yO1xuICAgICAgICBpZiAoIXNhdmUpIHJldHVybjtcbiAgICAgICAgY29uc3Qgb2JqOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gICAgICAgIG9ialt2YWxpZGF0aW9uS2V5LnRvVXBwZXJDYXNlKCldID0gdmFsaWRhdGlvbktleTtcblxuICAgICAgICB0aGlzLmN1c3RvbUtleUNhY2hlID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5jdXN0b21LZXlDYWNoZSwgb2JqKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9ycy9WYWxpZGF0b3JcIjtcbmltcG9ydCB7IElWYWxpZGF0b3JSZWdpc3RyeSwgVmFsaWRhdG9yRGVmaW5pdGlvbiB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBWYWxpZGF0b3JSZWdpc3RyeSB9IGZyb20gXCIuL1ZhbGlkYXRvcnMvVmFsaWRhdG9yUmVnaXN0cnlcIjtcbmltcG9ydCB7IFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vVmFsaWRhdG9ycy9jb25zdGFudHNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBTdGF0aWMgY2xhc3MgYWN0aW5nIGFzIGEgbmFtZXNwYWNlIGZvciB0aGUgVmFsaWRhdGlvblxuICpcbiAqIEBjbGFzcyBWYWxpZGF0aW9uXG4gKiBAc3RhdGljXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRpb25cbiAqL1xuZXhwb3J0IGNsYXNzIFZhbGlkYXRpb24ge1xuICBwcml2YXRlIHN0YXRpYyBhY3RpbmdWYWxpZGF0b3JSZWdpc3RyeT86IElWYWxpZGF0b3JSZWdpc3RyeTxWYWxpZGF0b3I+ID1cbiAgICB1bmRlZmluZWQ7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIGFjdGluZyBWYWxpZGF0b3JSZWdpc3RyeVxuICAgKlxuICAgKiBAcGFyYW0ge0lWYWxpZGF0b3JSZWdpc3RyeX0gdmFsaWRhdG9yUmVnaXN0cnkgdGhlIG5ldyBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgdmFsaWRhdG9yIFJlZ2lzdHJ5XG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oVmFsaWRhdG9yKTogVmFsaWRhdG9yfSBbbWlncmF0aW9uSGFuZGxlcl0gdGhlIG1ldGhvZCB0byBtYXAgdGhlIHZhbGlkYXRvciBpZiByZXF1aXJlZDtcbiAgICovXG4gIHN0YXRpYyBzZXRSZWdpc3RyeShcbiAgICB2YWxpZGF0b3JSZWdpc3RyeTogSVZhbGlkYXRvclJlZ2lzdHJ5PFZhbGlkYXRvcj4sXG4gICAgbWlncmF0aW9uSGFuZGxlcj86ICh2YWxpZGF0b3I6IFZhbGlkYXRvcikgPT4gVmFsaWRhdG9yXG4gICkge1xuICAgIGlmIChtaWdyYXRpb25IYW5kbGVyICYmIFZhbGlkYXRpb24uYWN0aW5nVmFsaWRhdG9yUmVnaXN0cnkpXG4gICAgICBWYWxpZGF0aW9uLmFjdGluZ1ZhbGlkYXRvclJlZ2lzdHJ5LmdldEtleXMoKS5mb3JFYWNoKChrOiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgdmFsaWRhdG9yID0gdmFsaWRhdG9yUmVnaXN0cnkuZ2V0KGspO1xuICAgICAgICBpZiAodmFsaWRhdG9yKSB2YWxpZGF0b3JSZWdpc3RyeS5yZWdpc3RlcihtaWdyYXRpb25IYW5kbGVyKHZhbGlkYXRvcikpO1xuICAgICAgfSk7XG4gICAgVmFsaWRhdGlvbi5hY3RpbmdWYWxpZGF0b3JSZWdpc3RyeSA9IHZhbGlkYXRvclJlZ2lzdHJ5O1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIGN1cnJlbnQgVmFsaWRhdG9yUmVnaXN0cnlcbiAgICpcbiAgICogQHJldHVybiBJVmFsaWRhdG9yUmVnaXN0cnksIGRlZmF1bHRzIHRvIHtAbGluayBWYWxpZGF0b3JSZWdpc3RyeX1cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdldFJlZ2lzdHJ5KCkge1xuICAgIGlmICghVmFsaWRhdGlvbi5hY3RpbmdWYWxpZGF0b3JSZWdpc3RyeSlcbiAgICAgIFZhbGlkYXRpb24uYWN0aW5nVmFsaWRhdG9yUmVnaXN0cnkgPSBuZXcgVmFsaWRhdG9yUmVnaXN0cnkoKTtcbiAgICByZXR1cm4gVmFsaWRhdGlvbi5hY3RpbmdWYWxpZGF0b3JSZWdpc3RyeTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgYSB2YWxpZGF0b3JcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbGlkYXRvcktleSBvbmUgb2YgdGhlIHtAbGluayBWYWxpZGF0aW9uS2V5c31cbiAgICogQHJldHVybiB7VmFsaWRhdG9yIHwgdW5kZWZpbmVkfSB0aGUgcmVnaXN0ZXJlZCBWYWxpZGF0b3Igb3IgdW5kZWZpbmVkIGlmIHRoZXJlIGlzIG5vbm8gbWF0Y2hpbmcgdGhlIHByb3ZpZGVkIGtleVxuICAgKi9cbiAgc3RhdGljIGdldDxUIGV4dGVuZHMgVmFsaWRhdG9yPih2YWxpZGF0b3JLZXk6IHN0cmluZyk6IFQgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBWYWxpZGF0aW9uLmdldFJlZ2lzdHJ5KCkuZ2V0KHZhbGlkYXRvcktleSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgUmVnaXN0ZXJzIHRoZSBwcm92aWRlZCB2YWxpZGF0b3JzIG9udG8gdGhlIHJlZ2lzdHJ5XG4gICAqXG4gICAqIEBwYXJhbSB7VFtdIHwgVmFsaWRhdG9yRGVmaW5pdGlvbltdfSB2YWxpZGF0b3JcbiAgICovXG4gIHN0YXRpYyByZWdpc3RlcjxUIGV4dGVuZHMgVmFsaWRhdG9yPihcbiAgICAuLi52YWxpZGF0b3I6IChWYWxpZGF0b3JEZWZpbml0aW9uIHwgVClbXVxuICApOiB2b2lkIHtcbiAgICByZXR1cm4gVmFsaWRhdGlvbi5nZXRSZWdpc3RyeSgpLnJlZ2lzdGVyKC4uLnZhbGlkYXRvcik7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgQnVpbGRzIHRoZSBrZXkgdG8gc3RvcmUgYXMgTWV0YWRhdGEgdW5kZXIgUmVmbGVjdGlvbnNcbiAgICogQGRlc2NyaXB0aW9uIGNvbmNhdGVuYXRlcyB7QGxpbmsgVmFsaWRhdGlvbktleXMjUkVGTEVDVH0gd2l0aCB0aGUgcHJvdmlkZWQga2V5XG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAgICovXG4gIHN0YXRpYyBrZXkoa2V5OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gVmFsaWRhdGlvbktleXMuUkVGTEVDVCArIGtleTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZXR1cm5zIGFsbCByZWdpc3RlcmVkIHZhbGlkYXRpb24ga2V5c1xuICAgKi9cbiAgc3RhdGljIGtleXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UmVnaXN0cnkoKS5nZXRLZXlzKCk7XG4gIH1cbn1cbiIsImltcG9ydCB7IE1vZGVsRXJyb3JEZWZpbml0aW9uIH0gZnJvbSBcIi4vTW9kZWxFcnJvckRlZmluaXRpb25cIjtcbmltcG9ydCB7IERlY29yYXRvck1ldGFkYXRhLCBSZWZsZWN0aW9uIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBNb2RlbEtleXMgfSBmcm9tIFwiLi4vdXRpbHMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBzZiB9IGZyb20gXCIuLi91dGlscy9zdHJpbmdzXCI7XG5pbXBvcnQgeyBSZXNlcnZlZE1vZGVscyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgVmFsaWRhdGFibGUgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgaXNNb2RlbCwgTW9kZWwgfSBmcm9tIFwiLi9Nb2RlbFwiO1xuaW1wb3J0IHsgVmFsaWRhdGlvbiB9IGZyb20gXCIuLi92YWxpZGF0aW9uL1ZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4uL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9jb25zdGFudHNcIjtcbmltcG9ydCB7XG4gIE1vZGVsRXJyb3JzLFxuICBWYWxpZGF0aW9uUHJvcGVydHlEZWNvcmF0b3JEZWZpbml0aW9uLFxufSBmcm9tIFwiLi4vdmFsaWRhdGlvbi90eXBlc1wiO1xuaW1wb3J0IHsgVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi92YWxpZGF0aW9uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgQW5hbHlzZXMgdGhlIGRlY29yYXRpb25zIG9mIHRoZSBwcm9wZXJ0aWVzIGFuZCB2YWxpZGF0ZXMgdGhlIG9iaiBhY2NvcmRpbmcgdG8gdGhlbVxuICpcbiAqIEB0eXBlZGVmIFQgZXh0ZW5kcyBNb2RlbFxuICogQHByb3Age1R9IG9iaiBNb2RlbCBvYmplY3QgdG8gdmFsaWRhdGVcbiAqIEBwcm9wIHtzdHJpbmdbXX0gW3Byb3BzVG9JZ25vcmVdIG9iamVjdCBwcm9wZXJ0aWVzIHRvIGlnbm9yZSBpbiB0aGUgdmFsaWRhdGlvblxuICpcbiAqIEBmdW5jdGlvbiB2YWxpZGF0ZVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5WYWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGU8VCBleHRlbmRzIE1vZGVsPihcbiAgb2JqOiBULFxuICAuLi5wcm9wc1RvSWdub3JlOiBzdHJpbmdbXVxuKTogTW9kZWxFcnJvckRlZmluaXRpb24gfCB1bmRlZmluZWQge1xuICBjb25zdCBkZWNvcmF0ZWRQcm9wZXJ0aWVzOiBWYWxpZGF0aW9uUHJvcGVydHlEZWNvcmF0b3JEZWZpbml0aW9uW10gPSBbXTtcbiAgZm9yIChjb25zdCBwcm9wIGluIG9iailcbiAgICBpZiAoXG4gICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKSAmJlxuICAgICAgcHJvcHNUb0lnbm9yZS5pbmRleE9mKHByb3ApID09PSAtMVxuICAgIClcbiAgICAgIGRlY29yYXRlZFByb3BlcnRpZXMucHVzaChcbiAgICAgICAgUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICAgICAgVmFsaWRhdGlvbktleXMuUkVGTEVDVCxcbiAgICAgICAgICBvYmosXG4gICAgICAgICAgcHJvcFxuICAgICAgICApIGFzIFZhbGlkYXRpb25Qcm9wZXJ0eURlY29yYXRvckRlZmluaXRpb25cbiAgICAgICk7XG5cbiAgbGV0IHJlc3VsdDogTW9kZWxFcnJvcnMgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cbiAgZm9yIChjb25zdCBkZWNvcmF0ZWRQcm9wZXJ0eSBvZiBkZWNvcmF0ZWRQcm9wZXJ0aWVzKSB7XG4gICAgY29uc3QgeyBwcm9wLCBkZWNvcmF0b3JzIH0gPSBkZWNvcmF0ZWRQcm9wZXJ0eTtcblxuICAgIGlmICghZGVjb3JhdG9ycyB8fCAhZGVjb3JhdG9ycy5sZW5ndGgpIGNvbnRpbnVlO1xuXG4gICAgY29uc3QgZGVmYXVsdFR5cGVEZWNvcmF0b3I6IERlY29yYXRvck1ldGFkYXRhID0gZGVjb3JhdG9yc1swXTtcblxuICAgIC8vIHRyaWVzIHRvIGZpbmQgYW55IHR5cGUgZGVjb3JhdG9ycyBvciBvdGhlciBkZWNvcmF0b3JzIHRoYXQgYWxyZWFkeSBlbmZvcmNlIHR5cGUgKHRoZSBvbmVzIHdpdGggdGhlIGFsbG93ZWQgdHlwZXMgcHJvcGVydHkgZGVmaW5lZCkuIGlmIHNvLCBza2lwIHRoZSBkZWZhdWx0IHR5cGUgdmVyaWZpY2F0aW9uXG4gICAgaWYgKFxuICAgICAgZGVjb3JhdG9ycy5maW5kKChkKSA9PiB7XG4gICAgICAgIGlmIChkLmtleSA9PT0gVmFsaWRhdGlvbktleXMuVFlQRSkgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiAhIWQucHJvcHMudHlwZXM/LmZpbmQoXG4gICAgICAgICAgKHQpID0+IHQgPT09IGRlZmF1bHRUeXBlRGVjb3JhdG9yLnByb3BzLm5hbWVcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKSB7XG4gICAgICBkZWNvcmF0b3JzLnNoaWZ0KCk7IC8vIHJlbW92ZSB0aGUgZGVzaWduOnR5cGUgZGVjb3JhdG9yLCBzaW5jZSB0aGUgdHlwZSB3aWxsIGFscmVhZHkgYmUgY2hlY2tlZFxuICAgIH1cblxuICAgIGxldCBlcnJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gICAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgZGVjb3JhdG9ycykge1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gVmFsaWRhdGlvbi5nZXQoZGVjb3JhdG9yLmtleSk7XG4gICAgICBpZiAoIXZhbGlkYXRvcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgdmFsaWRhdG9yIGZvciAke2RlY29yYXRvci5rZXl9YCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRlY29yYXRvclByb3BzID1cbiAgICAgICAgZGVjb3JhdG9yLmtleSA9PT0gTW9kZWxLZXlzLlRZUEVcbiAgICAgICAgICA/IFtkZWNvcmF0b3IucHJvcHNdXG4gICAgICAgICAgOiBkZWNvcmF0b3IucHJvcHMgfHwge307XG5cbiAgICAgIGNvbnN0IGVycjogc3RyaW5nIHwgdW5kZWZpbmVkID0gdmFsaWRhdG9yLmhhc0Vycm9ycyhcbiAgICAgICAgKG9iaiBhcyBhbnkpW3Byb3AudG9TdHJpbmcoKV0sXG4gICAgICAgIGRlY29yYXRvclByb3BzIGFzIFZhbGlkYXRvck9wdGlvbnNcbiAgICAgICk7XG5cbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgZXJycyA9IGVycnMgfHwge307XG4gICAgICAgIGVycnNbZGVjb3JhdG9yLmtleV0gPSBlcnI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVycnMpIHtcbiAgICAgIHJlc3VsdCA9IHJlc3VsdCB8fCB7fTtcbiAgICAgIHJlc3VsdFtkZWNvcmF0ZWRQcm9wZXJ0eS5wcm9wLnRvU3RyaW5nKCldID0gZXJycztcbiAgICB9XG4gIH1cblxuICAvLyB0ZXN0cyBuZXN0ZWQgY2xhc3Nlc1xuICBmb3IgKGNvbnN0IHByb3Agb2YgT2JqZWN0LmtleXMob2JqKS5maWx0ZXIoKGspID0+ICFyZXN1bHQgfHwgIXJlc3VsdFtrXSkpIHtcbiAgICBsZXQgZXJyOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgLy8gaWYgYSBuZXN0ZWQgTW9kZWxcbiAgICBjb25zdCBhbGxEZWNvcmF0b3JzID0gUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICBWYWxpZGF0aW9uS2V5cy5SRUZMRUNULFxuICAgICAgb2JqLFxuICAgICAgcHJvcFxuICAgICkuZGVjb3JhdG9ycztcbiAgICBjb25zdCBkZWNvcmF0b3JzID0gUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICBWYWxpZGF0aW9uS2V5cy5SRUZMRUNULFxuICAgICAgb2JqLFxuICAgICAgcHJvcFxuICAgICkuZGVjb3JhdG9ycy5maWx0ZXIoXG4gICAgICAoZDogeyBrZXk6IHN0cmluZyB9KSA9PlxuICAgICAgICBbTW9kZWxLZXlzLlRZUEUsIFZhbGlkYXRpb25LZXlzLlRZUEVdLmluZGV4T2YoZC5rZXkpICE9PSAtMVxuICAgICk7XG4gICAgaWYgKCFkZWNvcmF0b3JzIHx8ICFkZWNvcmF0b3JzLmxlbmd0aCkgY29udGludWU7XG4gICAgY29uc3QgZGVjID0gZGVjb3JhdG9ycy5wb3AoKSBhcyBEZWNvcmF0b3JNZXRhZGF0YTtcbiAgICBjb25zdCBjbGF6eiA9IGRlYy5wcm9wcy5uYW1lXG4gICAgICA/IFtkZWMucHJvcHMubmFtZV1cbiAgICAgIDogQXJyYXkuaXNBcnJheShkZWMucHJvcHMuY3VzdG9tVHlwZXMpXG4gICAgICAgID8gZGVjLnByb3BzLmN1c3RvbVR5cGVzXG4gICAgICAgIDogW2RlYy5wcm9wcy5jdXN0b21UeXBlc107XG4gICAgY29uc3QgcmVzZXJ2ZWQgPSBPYmplY3QudmFsdWVzKFJlc2VydmVkTW9kZWxzKS5tYXAoKHYpID0+XG4gICAgICB2LnRvTG93ZXJDYXNlKClcbiAgICApIGFzIHN0cmluZ1tdO1xuXG4gICAgZm9yIChjb25zdCBjIG9mIGNsYXp6KSB7XG4gICAgICBpZiAocmVzZXJ2ZWQuaW5kZXhPZihjLnRvTG93ZXJDYXNlKCkpID09PSAtMSkge1xuICAgICAgICBjb25zdCB0eXBlRGVjb3JhdG9yS2V5ID0gQXJyYXkuaXNBcnJheSgob2JqIGFzIGFueSlbcHJvcF0pXG4gICAgICAgICAgPyBWYWxpZGF0aW9uS2V5cy5MSVNUXG4gICAgICAgICAgOiBWYWxpZGF0aW9uS2V5cy5UWVBFO1xuICAgICAgICBjb25zdCB0eXBlczogYW55ID1cbiAgICAgICAgICBhbGxEZWNvcmF0b3JzLmZpbmQoXG4gICAgICAgICAgICAoZDogeyBrZXk6IHN0cmluZyB9KSA9PiBkLmtleSA9PT0gdHlwZURlY29yYXRvcktleVxuICAgICAgICAgICkgfHwge307XG4gICAgICAgIGxldCBhbGxvd2VkVHlwZXM6IHN0cmluZ1tdID0gW107XG4gICAgICAgIGlmICh0eXBlcyAmJiB0eXBlcy5wcm9wcykge1xuICAgICAgICAgIGNvbnN0IGN1c3RvbVR5cGVzID0gQXJyYXkuaXNBcnJheSgob2JqIGFzIGFueSlbcHJvcF0pXG4gICAgICAgICAgICA/IHR5cGVzLnByb3BzLmNsYXNzXG4gICAgICAgICAgICA6IHR5cGVzLnByb3BzLmN1c3RvbVR5cGVzO1xuICAgICAgICAgIGlmIChjdXN0b21UeXBlcylcbiAgICAgICAgICAgIGFsbG93ZWRUeXBlcyA9IEFycmF5LmlzQXJyYXkoY3VzdG9tVHlwZXMpXG4gICAgICAgICAgICAgID8gY3VzdG9tVHlwZXMubWFwKCh0KSA9PiBgJHt0fWAudG9Mb3dlckNhc2UoKSlcbiAgICAgICAgICAgICAgOiBbY3VzdG9tVHlwZXMudG9Mb3dlckNhc2UoKV07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2YWxpZGF0ZSA9IChwcm9wOiBzdHJpbmcsIHZhbHVlOiBhbnkpOiBhbnkgPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIpXG4gICAgICAgICAgICByZXR1cm4gaXNNb2RlbCh2YWx1ZSlcbiAgICAgICAgICAgICAgPyAodmFsdWUgYXMgTW9kZWwpLmhhc0Vycm9ycygpXG4gICAgICAgICAgICAgIDogYWxsb3dlZFR5cGVzLmluY2x1ZGVzKHR5cGVvZiB2YWx1ZSlcbiAgICAgICAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIDogXCJWYWx1ZSBoYXMgbm8gdmFsaWRhdGFibGUgdHlwZVwiO1xuICAgICAgICB9O1xuXG4gICAgICAgIHN3aXRjaCAoYykge1xuICAgICAgICAgIGNhc2UgQXJyYXkubmFtZTpcbiAgICAgICAgICBjYXNlIFNldC5uYW1lOlxuICAgICAgICAgICAgaWYgKGFsbERlY29yYXRvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGxpc3REZWMgPSBhbGxEZWNvcmF0b3JzLmZpbmQoXG4gICAgICAgICAgICAgICAgKGQ6IHsga2V5OiBzdHJpbmcgfSkgPT4gZC5rZXkgPT09IFZhbGlkYXRpb25LZXlzLkxJU1RcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgaWYgKGxpc3REZWMpIHtcbiAgICAgICAgICAgICAgICBlcnIgPSAoXG4gICAgICAgICAgICAgICAgICBjID09PSBBcnJheS5uYW1lXG4gICAgICAgICAgICAgICAgICAgID8gKG9iaiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXVxuICAgICAgICAgICAgICAgICAgICA6IC8vIElmIGl0J3MgYSBTZXRcbiAgICAgICAgICAgICAgICAgICAgICAob2JqIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdLnZhbHVlcygpXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgLm1hcCgodjogVmFsaWRhdGFibGUpID0+IHZhbGlkYXRlKHByb3AsIHYpKVxuICAgICAgICAgICAgICAgICAgLmZpbHRlcigoZTogYW55KSA9PiAhIWUpIGFzIGFueTtcbiAgICAgICAgICAgICAgICBpZiAoIWVycj8ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAvLyBpZiB0aGUgcmVzdWx0IGlzIGFuIGVtcHR5IGxpc3QuLi5cbiAgICAgICAgICAgICAgICAgIGVyciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBpZiAoKG9iaiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXSlcbiAgICAgICAgICAgICAgICBlcnIgPSB2YWxpZGF0ZShwcm9wLCAob2JqIGFzIGFueSlbcHJvcF0pO1xuICAgICAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUud2FybihzZihcIk1vZGVsIHNob3VsZCBiZSB2YWxpZGF0YWJsZSBidXQgaXRzIG5vdDogXCIgKyBlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgcmVzdWx0ID0gcmVzdWx0IHx8IHt9O1xuICAgICAgICByZXN1bHRbcHJvcF0gPSBlcnIgYXMgYW55O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQgPyBuZXcgTW9kZWxFcnJvckRlZmluaXRpb24ocmVzdWx0KSA6IHVuZGVmaW5lZDtcbn1cbiIsImltcG9ydCB7IFNlcmlhbGl6YXRpb24gfSBmcm9tIFwiLi4vdXRpbHMvc2VyaWFsaXphdGlvblwiO1xuaW1wb3J0IHsgQnVpbGRlclJlZ2lzdHJ5IH0gZnJvbSBcIi4uL3V0aWxzL3JlZ2lzdHJ5XCI7XG5pbXBvcnQgeyBNb2RlbEVycm9yRGVmaW5pdGlvbiB9IGZyb20gXCIuL01vZGVsRXJyb3JEZWZpbml0aW9uXCI7XG5pbXBvcnQge1xuICBDb21wYXJhYmxlLFxuICBDb25zdHJ1Y3RvcixcbiAgSGFzaGFibGUsXG4gIE1vZGVsQXJnLFxuICBNb2RlbEJ1aWxkZXJGdW5jdGlvbixcbiAgTW9kZWxDb25zdHJ1Y3RvcixcbiAgU2VyaWFsaXphYmxlLFxuICBWYWxpZGF0YWJsZSxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IERlY29yYXRvck1ldGFkYXRhLCBpc0VxdWFsLCBSZWZsZWN0aW9uIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZSB9IGZyb20gXCIuL3ZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEhhc2hpbmcgfSBmcm9tIFwiLi4vdXRpbHMvaGFzaGluZ1wiO1xuaW1wb3J0IHsgTW9kZWxLZXlzIH0gZnJvbSBcIi4uL3V0aWxzL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi4vdmFsaWRhdGlvbi9WYWxpZGF0b3JzL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgc2YgfSBmcm9tIFwiLi4vdXRpbHMvc3RyaW5nc1wiO1xuaW1wb3J0IHsganNUeXBlcywgUmVzZXJ2ZWRNb2RlbHMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxubGV0IG1vZGVsQnVpbGRlckZ1bmN0aW9uOiBNb2RlbEJ1aWxkZXJGdW5jdGlvbiB8IHVuZGVmaW5lZDtcbmxldCBhY3RpbmdNb2RlbFJlZ2lzdHJ5OiBCdWlsZGVyUmVnaXN0cnk8YW55PjtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzUHJvcGVydHlNb2RlbDxNIGV4dGVuZHMgTW9kZWw+KFxuICB0YXJnZXQ6IE0sXG4gIGF0dHJpYnV0ZTogc3RyaW5nXG4pOiBib29sZWFuIHwgc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgaWYgKGlzTW9kZWwoKHRhcmdldCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVthdHRyaWJ1dGVdKSkgcmV0dXJuIHRydWU7XG4gIGNvbnN0IG1ldGFkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShNb2RlbEtleXMuVFlQRSwgdGFyZ2V0LCBhdHRyaWJ1dGUpO1xuICByZXR1cm4gTW9kZWwuZ2V0KG1ldGFkYXRhLm5hbWUpID8gbWV0YWRhdGEubmFtZSA6IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBGb3IgU2VyaWFsaXphdGlvbi9kZXNlcmlhbGl6YXRpb24gcHVycG9zZXMuXG4gKiBAZGVzY3JpcHRpb24gUmVhZHMgdGhlIHtAbGluayBNb2RlbEtleXMuQU5DSE9SfSBwcm9wZXJ0eSBvZiBhIHtAbGluayBNb2RlbH0gdG8gZGlzY292ZXIgdGhlIGNsYXNzIHRvIGluc3RhbnRpYXRlXG4gKlxuICogQGZ1bmN0aW9uIGlzTW9kZWxcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IFZhbGlkYXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTW9kZWwodGFyZ2V0OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHRhcmdldCBpbnN0YW5jZW9mIE1vZGVsIHx8ICEhTW9kZWwuZ2V0TWV0YWRhdGEodGFyZ2V0IGFzIGFueSk7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBNb2RlbFJlZ2lzdHJ5IEludGVyZmFjZVxuICpcbiAqIEBpbnRlcmZhY2UgTW9kZWxSZWdpc3RyeVxuICogQGV4dGVuZHMgQnVpbGRlclJlZ2lzdHJ5PE1vZGVsPlxuICpcbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgdHlwZSBNb2RlbFJlZ2lzdHJ5PFQgZXh0ZW5kcyBNb2RlbD4gPSBCdWlsZGVyUmVnaXN0cnk8VD47XG5cbi8qKlxuICogQHN1bW1hcnkgVXRpbCBjbGFzcyB0byBlbmFibGUgc2VyaWFsaXphdGlvbiBhbmQgY29ycmVjdCByZWJ1aWxkaW5nXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGFuY2hvcktleSBkZWZhdWx0cyB0byB7QGxpbmsgTW9kZWxLZXlzLkFOQ0hPUn0uIFRoZSBwcm9wZXJ0eSBuYW1lIHdoZXJlIHRoZSByZWdpc3RlcmVkIGNsYXNzIG5hbWUgaXMgc3RvcmVkO1xuICogQHBhcmFtIHtmdW5jdGlvbihSZWNvcmQ8c3RyaW5nLCBhbnk+KTogYm9vbGVhbn0gW3Rlc3RGdW5jdGlvbl0gbWV0aG9kIHRvIHRlc3QgaWYgdGhlIHByb3ZpZGVkIG9iamVjdCBpcyBhIE1vZGVsIE9iamVjdC4gZGVmYXVsdHMgdG8ge0BsaW5rIGlzTW9kZWx9XG4gKlxuICogQGNsYXNzIE1vZGVsUmVnaXN0cnlNYW5hZ2VyXG4gKiBAaW1wbGVtZW50cyBNb2RlbFJlZ2lzdHJ5XG4gKlxuICogQGNhdGVnb3J5IE1vZGVsXG4gKi9cbmV4cG9ydCBjbGFzcyBNb2RlbFJlZ2lzdHJ5TWFuYWdlcjxUIGV4dGVuZHMgTW9kZWw+IGltcGxlbWVudHMgTW9kZWxSZWdpc3RyeTxUPiB7XG4gIHByaXZhdGUgY2FjaGU6IFJlY29yZDxzdHJpbmcsIE1vZGVsQ29uc3RydWN0b3I8VD4+ID0ge307XG4gIHByaXZhdGUgcmVhZG9ubHkgdGVzdEZ1bmN0aW9uOiAob2JqOiBvYmplY3QpID0+IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IodGVzdEZ1bmN0aW9uOiAob2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiBib29sZWFuID0gaXNNb2RlbCkge1xuICAgIHRoaXMudGVzdEZ1bmN0aW9uID0gdGVzdEZ1bmN0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHJlZ2lzdGVyIG5ldyBNb2RlbHNcbiAgICogQHBhcmFtIHthbnl9IGNvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbbmFtZV0gd2hlbiBub3QgZGVmaW5lZCwgdGhlIG5hbWUgb2YgdGhlIGNvbnN0cnVjdG9yIHdpbGwgYmUgdXNlZFxuICAgKi9cbiAgcmVnaXN0ZXIoY29uc3RydWN0b3I6IE1vZGVsQ29uc3RydWN0b3I8VD4sIG5hbWU/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodHlwZW9mIGNvbnN0cnVjdG9yICE9PSBcImZ1bmN0aW9uXCIpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiTW9kZWwgcmVnaXN0ZXJpbmcgZmFpbGVkLiBNaXNzaW5nIENsYXNzIG5hbWUgb3IgY29uc3RydWN0b3JcIlxuICAgICAgKTtcbiAgICBuYW1lID0gbmFtZSB8fCBjb25zdHJ1Y3Rvci5uYW1lO1xuICAgIHRoaXMuY2FjaGVbbmFtZV0gPSBjb25zdHJ1Y3RvcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBHZXRzIGEgcmVnaXN0ZXJlZCBNb2RlbCB7QGxpbmsgTW9kZWxDb25zdHJ1Y3Rvcn1cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICovXG4gIGdldChuYW1lOiBzdHJpbmcpOiBNb2RlbENvbnN0cnVjdG9yPFQ+IHwgdW5kZWZpbmVkIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVbbmFtZV07XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IG9ialxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2NsYXp6XSB3aGVuIHByb3ZpZGVkLCBpdCB3aWxsIGF0dGVtcHQgdG8gZmluZCB0aGUgbWF0Y2hpbmcgY29uc3RydWN0b3JcbiAgICpcbiAgICogQHRocm93cyBFcnJvciBJZiBjbGF6eiBpcyBub3QgZm91bmQsIG9yIG9iaiBpcyBub3QgYSB7QGxpbmsgTW9kZWx9IG1lYW5pbmcgaXQgaGFzIG5vIHtAbGluayBNb2RlbEtleXMuQU5DSE9SfSBwcm9wZXJ0eVxuICAgKi9cbiAgYnVpbGQob2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge30sIGNsYXp6Pzogc3RyaW5nKTogVCB7XG4gICAgaWYgKCFjbGF6eiAmJiAhdGhpcy50ZXN0RnVuY3Rpb24ob2JqKSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlByb3ZpZGVkIG9iaiBpcyBub3QgYSBNb2RlbCBvYmplY3RcIik7XG4gICAgY29uc3QgbmFtZSA9IGNsYXp6IHx8IE1vZGVsLmdldE1ldGFkYXRhKG9iaiBhcyBhbnkpO1xuICAgIGlmICghKG5hbWUgaW4gdGhpcy5jYWNoZSkpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIHNmKFwiUHJvdmlkZWQgY2xhc3MgezB9IGlzIG5vdCBhIHJlZ2lzdGVyZWQgTW9kZWwgb2JqZWN0XCIsIG5hbWUpXG4gICAgICApO1xuICAgIHJldHVybiBuZXcgdGhpcy5jYWNoZVtuYW1lXShvYmopO1xuICB9XG59XG5cbi8qKlxuICogQHN1bW1hcnkgQnVsayBSZWdpc3RlcnMgTW9kZWxzXG4gKiBAZGVzY3JpcHRpb24gVXNlZnVsIHdoZW4gdXNpbmcgYnVuZGxlcnMgdGhhdCBtaWdodCBub3QgZXZhbHVhdGUgYWxsIHRoZSBjb2RlIGF0IG9uY2VcbiAqXG4gKiBAcGFyYW0ge0FycmF5PENvbnN0cnVjdG9yPFQ+PiB8IEFycmF5PHtuYW1lOiBzdHJpbmcsIGNvbnN0cnVjdG9yOiBDb25zdHJ1Y3RvcjxUPn0+fSBbbW9kZWxzXVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uTW9kZWxcbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVsa01vZGVsUmVnaXN0ZXI8VCBleHRlbmRzIE1vZGVsPihcbiAgLi4ubW9kZWxzOiAoQ29uc3RydWN0b3I8VD4gfCB7IG5hbWU6IHN0cmluZzsgY29uc3RydWN0b3I6IENvbnN0cnVjdG9yPFQ+IH0pW11cbikge1xuICBtb2RlbHMuZm9yRWFjaChcbiAgICAobTogQ29uc3RydWN0b3I8VD4gfCB7IG5hbWU6IHN0cmluZzsgY29uc3RydWN0b3I6IENvbnN0cnVjdG9yPFQ+IH0pID0+IHtcbiAgICAgIGNvbnN0IGNvbnN0cnVjdG9yOiBDb25zdHJ1Y3RvcjxUPiA9IChcbiAgICAgICAgbS5jb25zdHJ1Y3RvciA/IG0uY29uc3RydWN0b3IgOiBtXG4gICAgICApIGFzIENvbnN0cnVjdG9yPFQ+O1xuICAgICAgTW9kZWwucmVnaXN0ZXIoY29uc3RydWN0b3IsIChtIGFzIENvbnN0cnVjdG9yPFQ+KS5uYW1lKTtcbiAgICB9XG4gICk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgQWJzdHJhY3QgY2xhc3MgcmVwcmVzZW50aW5nIGEgVmFsaWRhdGFibGUgTW9kZWwgb2JqZWN0XG4gKiBAZGVzY3JpcHRpb24gTWVhbnQgdG8gYmUgdXNlZCBhcyBhIGJhc2UgY2xhc3MgZm9yIGFsbCBNb2RlbCBjbGFzc2VzXG4gKlxuICogTW9kZWwgb2JqZWN0cyBtdXN0OlxuICogIC0gSGF2ZSBhbGwgdGhlaXIgcmVxdWlyZWQgcHJvcGVydGllcyBtYXJrZWQgd2l0aCAnISc7XG4gKiAgLSBIYXZlIGFsbCB0aGVpciBvcHRpb25hbCBwcm9wZXJ0aWVzIG1hcmtlZCBhcyAnPyc6XG4gKlxuICogQHBhcmFtIHtNb2RlbCB8IHt9fSBtb2RlbCBiYXNlIG9iamVjdCBmcm9tIHdoaWNoIHRvIHBvcHVsYXRlIHByb3BlcnRpZXMgZnJvbVxuICpcbiAqIEBjbGFzcyBNb2RlbFxuICogQGFic3RyYWN0XG4gKiBAaW1wbGVtZW50cyBWYWxpZGF0YWJsZVxuICogQGltcGxlbWVudHMgU2VyaWFsaXphYmxlXG4gKlxuICogQGV4YW1wbGVcbiAqICAgICAgY2xhc3MgQ2xhc3NOYW1lIHtcbiAqICAgICAgICAgIEByZXF1aXJlZCgpXG4gKiAgICAgICAgICByZXF1aXJlZFByb3BlcnR5TmFtZSE6IFByb3BlcnR5VHlwZTtcbiAqXG4gKiAgICAgICAgICBvcHRpb25hbFByb3BlcnR5TmFtZT86IFByb3BlcnR5VHlwZTtcbiAqICAgICAgfVxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgTW9kZWxcbiAgaW1wbGVtZW50cyBWYWxpZGF0YWJsZSwgU2VyaWFsaXphYmxlLCBIYXNoYWJsZSwgQ29tcGFyYWJsZTxNb2RlbD5cbntcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoYXJnPzogTW9kZWxBcmc8TW9kZWw+KSB7fVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgdGhlIG9iamVjdCBhY2NvcmRpbmcgdG8gaXRzIGRlY29yYXRlZCBwcm9wZXJ0aWVzXG4gICAqXG4gICAqIEBwYXJhbSB7YW55W119IFtleGNlcHRpb25zXSBwcm9wZXJ0aWVzIGluIHRoZSBvYmplY3QgdG8gYmUgaWdub3JlZCBmb3IgdGhlIHZhbGlkYXRpb24uIE1hcmtlZCBhcyAnYW55JyB0byBhbGxvdyBmb3IgZXh0ZW5zaW9uIGJ1dCBleHBlY3RzIHN0cmluZ3NcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoLi4uZXhjZXB0aW9uczogYW55W10pOiBNb2RlbEVycm9yRGVmaW5pdGlvbiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHZhbGlkYXRlKHRoaXMsIC4uLmV4Y2VwdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IENvbXBhcmUgb2JqZWN0IGVxdWFsaXR5IHJlY3Vyc2l2ZWx5XG4gICAqIEBwYXJhbSB7YW55fSBvYmogb2JqZWN0IHRvIGNvbXBhcmUgdG9cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtleGNlcHRpb25zXSBwcm9wZXJ0eSBuYW1lcyB0byBiZSBleGNsdWRlZCBmcm9tIHRoZSBjb21wYXJpc29uXG4gICAqL1xuICBwdWJsaWMgZXF1YWxzKG9iajogYW55LCAuLi5leGNlcHRpb25zOiBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc0VxdWFsKHRoaXMsIG9iaiwgLi4uZXhjZXB0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgUmV0dXJucyB0aGUgc2VyaWFsaXplZCBtb2RlbCBhY2NvcmRpbmcgdG8gdGhlIGN1cnJlbnRseSBkZWZpbmVkIHtAbGluayBTZXJpYWxpemVyfVxuICAgKi9cbiAgc2VyaWFsaXplKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIE1vZGVsLnNlcmlhbGl6ZSh0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBPdmVycmlkZSB0aGUgaW1wbGVtZW50YXRpb24gZm9yIGpzJ3MgJ3RvU3RyaW5nKCknIHdoaWNoIHN1Y2tzLi4uXG4gICAqIEBvdmVycmlkZVxuICAgKi9cbiAgcHVibGljIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IubmFtZSArIFwiOiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMsIHVuZGVmaW5lZCwgMik7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgRGVmaW5lcyBhIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIG9iamVjdCBoYXNoLiBSZWxpZXMgb24gYSB2ZXJ5IGJhc2ljIGltcGxlbWVudGF0aW9uIGJhc2VkIG9uIEphdmEncyBzdHJpbmcgaGFzaDtcbiAgICovXG4gIHB1YmxpYyBoYXNoKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIE1vZGVsLmhhc2godGhpcyk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgRGVzZXJpYWxpemVzIGEgTW9kZWxcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0clxuICAgKlxuICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgaXQgZmFpbHMgdG8gcGFyc2UgdGhlIHN0cmluZywgb3IgaWYgaXQgZmFpbHMgdG8gYnVpbGQgdGhlIG1vZGVsXG4gICAqL1xuICBzdGF0aWMgZGVzZXJpYWxpemUoc3RyOiBzdHJpbmcpIHtcbiAgICBjb25zdCBtZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICBNb2RlbC5rZXkoTW9kZWxLZXlzLlNFUklBTElaQVRJT04pLFxuICAgICAgdGhpcy5jb25zdHJ1Y3RvclxuICAgICk7XG5cbiAgICBpZiAobWV0YWRhdGEgJiYgbWV0YWRhdGEuc2VyaWFsaXplcilcbiAgICAgIHJldHVybiBTZXJpYWxpemF0aW9uLmRlc2VyaWFsaXplKFxuICAgICAgICBzdHIsXG4gICAgICAgIG1ldGFkYXRhLnNlcmlhbGl6ZXIsXG4gICAgICAgIC4uLihtZXRhZGF0YS5hcmdzIHx8IFtdKVxuICAgICAgKTtcbiAgICByZXR1cm4gU2VyaWFsaXphdGlvbi5kZXNlcmlhbGl6ZShzdHIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJlcG9wdWxhdGVzIHRoZSBPYmplY3QgcHJvcGVydGllcyB3aXRoIHRoZSBvbmVzIGZyb20gdGhlIG5ldyBvYmplY3RcbiAgICogQGRlc2NyaXB0aW9uIEl0ZXJhdGVzIGFsbCBjb21tb24gcHJvcGVydGllcyBvZiBvYmogKGlmIGV4aXN0aW5nKSBhbmQgc2VsZiwgYW5kIGNvcGllcyB0aGVtIG9udG8gc2VsZlxuICAgKlxuICAgKiBAcGFyYW0ge1R9IHNlbGZcbiAgICogQHBhcmFtIHtUIHwgUmVjb3JkPHN0cmluZywgYW55Pn0gW29ial1cbiAgICpcbiAgICovXG4gIHN0YXRpYyBmcm9tT2JqZWN0PFQgZXh0ZW5kcyBNb2RlbD4oXG4gICAgc2VsZjogVCxcbiAgICBvYmo/OiBUIHwgUmVjb3JkPHN0cmluZywgYW55PlxuICApOiBUIHtcbiAgICBpZiAoIW9iaikgb2JqID0ge307XG4gICAgZm9yIChjb25zdCBwcm9wIG9mIE1vZGVsLmdldEF0dHJpYnV0ZXMoc2VsZikpIHtcbiAgICAgIChzZWxmIGFzIGFueSlbcHJvcF0gPSAob2JqIGFzIGFueSlbcHJvcF0gfHwgdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gc2VsZjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZXBvcHVsYXRlcyB0aGUgaW5zdGFuY2Ugd2l0aCB0aGUgb25lcyBmcm9tIHRoZSBuZXcgTW9kZWwgT2JqZWN0XG4gICAqIEBkZXNjcmlwdGlvbiBJdGVyYXRlcyBhbGwgY29tbW9uIHByb3BlcnRpZXMgb2Ygb2JqIChpZiBleGlzdGluZykgYW5kIHNlbGYsIGFuZCBjb3BpZXMgdGhlbSBvbnRvIHNlbGYuXG4gICAqIElzIGF3YXJlIG9mIG5lc3RlZCBNb2RlbCBPYmplY3RzIGFuZCByZWJ1aWxkcyB0aGVtIGFsc28uXG4gICAqIFdoZW4gTGlzdCBwcm9wZXJ0aWVzIGFyZSBkZWNvcmF0ZWQgd2l0aCB7QGxpbmsgbGlzdH0sIHRoZXkgbGlzdCBpdGVtcyB3aWxsIGFsc28gYmUgcmVidWlsdFxuICAgKlxuICAgKiBAcGFyYW0ge1R9IHNlbGZcbiAgICogQHBhcmFtIHtUIHwgUmVjb3JkPHN0cmluZywgYW55Pn0gW29ial1cbiAgICpcbiAgICovXG4gIHN0YXRpYyBmcm9tTW9kZWw8VCBleHRlbmRzIE1vZGVsPihzZWxmOiBULCBvYmo/OiBUIHwgUmVjb3JkPHN0cmluZywgYW55Pik6IFQge1xuICAgIGlmICghb2JqKSBvYmogPSB7fTtcblxuICAgIGxldCBkZWNvcmF0b3JzOiBEZWNvcmF0b3JNZXRhZGF0YVtdLCBkZWM6IERlY29yYXRvck1ldGFkYXRhO1xuXG4gICAgY29uc3QgcHJvcHMgPSBNb2RlbC5nZXRBdHRyaWJ1dGVzKHNlbGYpO1xuXG4gICAgZm9yIChjb25zdCBwcm9wIG9mIHByb3BzKSB7XG4gICAgICAoc2VsZiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXSA9XG4gICAgICAgIChvYmogYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0gfHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKHR5cGVvZiAoc2VsZiBhcyBhbnkpW3Byb3BdICE9PSBcIm9iamVjdFwiKSBjb250aW51ZTtcbiAgICAgIGNvbnN0IHByb3BNID0gaXNQcm9wZXJ0eU1vZGVsKHNlbGYsIHByb3ApO1xuICAgICAgaWYgKHByb3BNKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgKHNlbGYgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0gPSBNb2RlbC5idWlsZChcbiAgICAgICAgICAgIChzZWxmIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdLFxuICAgICAgICAgICAgdHlwZW9mIHByb3BNID09PSBcInN0cmluZ1wiID8gcHJvcE0gOiB1bmRlZmluZWRcbiAgICAgICAgICApO1xuICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYWxsRGVjb3JhdG9yczogRGVjb3JhdG9yTWV0YWRhdGFbXSA9XG4gICAgICAgIFJlZmxlY3Rpb24uZ2V0UHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgICAgIFZhbGlkYXRpb25LZXlzLlJFRkxFQ1QsXG4gICAgICAgICAgc2VsZixcbiAgICAgICAgICBwcm9wXG4gICAgICAgICkuZGVjb3JhdG9ycztcbiAgICAgIGRlY29yYXRvcnMgPSBhbGxEZWNvcmF0b3JzLmZpbHRlcihcbiAgICAgICAgKGQ6IERlY29yYXRvck1ldGFkYXRhKSA9PlxuICAgICAgICAgIFtNb2RlbEtleXMuVFlQRSwgVmFsaWRhdGlvbktleXMuVFlQRV0uaW5kZXhPZihkLmtleSkgIT09IC0xXG4gICAgICApO1xuICAgICAgaWYgKCFkZWNvcmF0b3JzIHx8ICFkZWNvcmF0b3JzLmxlbmd0aClcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKHNmKFwiZmFpbGVkIHRvIGZpbmQgZGVjb3JhdG9ycyBmb3IgcHJvcGVydHkgezB9XCIsIHByb3ApKTtcbiAgICAgIGRlYyA9IGRlY29yYXRvcnMucG9wKCkgYXMgRGVjb3JhdG9yTWV0YWRhdGE7XG4gICAgICBjb25zdCBjbGF6eiA9IGRlYy5wcm9wcy5uYW1lXG4gICAgICAgID8gW2RlYy5wcm9wcy5uYW1lXVxuICAgICAgICA6IEFycmF5LmlzQXJyYXkoZGVjLnByb3BzLmN1c3RvbVR5cGVzKVxuICAgICAgICAgID8gZGVjLnByb3BzLmN1c3RvbVR5cGVzXG4gICAgICAgICAgOiBbZGVjLnByb3BzLmN1c3RvbVR5cGVzXTtcbiAgICAgIGNvbnN0IHJlc2VydmVkID0gT2JqZWN0LnZhbHVlcyhSZXNlcnZlZE1vZGVscykubWFwKCh2KSA9PlxuICAgICAgICB2LnRvTG93ZXJDYXNlKClcbiAgICAgICkgYXMgc3RyaW5nW107XG5cbiAgICAgIGNsYXp6LmZvckVhY2goKGMpID0+IHtcbiAgICAgICAgaWYgKHJlc2VydmVkLmluZGV4T2YoYy50b0xvd2VyQ2FzZSgpKSA9PT0gLTEpXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHN3aXRjaCAoYykge1xuICAgICAgICAgICAgICBjYXNlIFwiQXJyYXlcIjpcbiAgICAgICAgICAgICAgY2FzZSBcIlNldFwiOlxuICAgICAgICAgICAgICAgIGlmIChhbGxEZWNvcmF0b3JzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgbGlzdERlYyA9IGFsbERlY29yYXRvcnMuZmluZChcbiAgICAgICAgICAgICAgICAgICAgKGQpID0+IGQua2V5ID09PSBWYWxpZGF0aW9uS2V5cy5MSVNUXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgaWYgKGxpc3REZWMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2xhenpOYW1lID0gKGxpc3REZWMucHJvcHMuY2xhenogYXMgc3RyaW5nW10pLmZpbmQoXG4gICAgICAgICAgICAgICAgICAgICAgKHQ6IHN0cmluZykgPT4gIWpzVHlwZXMuaW5jbHVkZXModC50b0xvd2VyQ2FzZSgpKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PT0gXCJBcnJheVwiKVxuICAgICAgICAgICAgICAgICAgICAgIChzZWxmIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdID0gKFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICAgICAgICAgICAgICAgICAgICAgKVtwcm9wXS5tYXAoKGVsOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbXCJvYmplY3RcIiwgXCJmdW5jdGlvblwiXS5pbmNsdWRlcyh0eXBlb2YgZWwpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXp6TmFtZVxuICAgICAgICAgICAgICAgICAgICAgICAgICA/IE1vZGVsLmJ1aWxkKGVsLCBjbGF6ek5hbWUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDogZWw7XG4gICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjID09PSBcIlNldFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgcyA9IG5ldyBTZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHYgb2YgKHNlbGYgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW1wib2JqZWN0XCIsIFwiZnVuY3Rpb25cIl0uaW5jbHVkZXModHlwZW9mIHYpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXp6TmFtZVxuICAgICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHMuYWRkKE1vZGVsLmJ1aWxkKHYsIGNsYXp6TmFtZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcy5hZGQodik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIChzZWxmIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdID0gcztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpZiAoKHNlbGYgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0pXG4gICAgICAgICAgICAgICAgICAoc2VsZiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXSA9IE1vZGVsLmJ1aWxkKFxuICAgICAgICAgICAgICAgICAgICAoc2VsZiBhcyBhbnkpW3Byb3BdLFxuICAgICAgICAgICAgICAgICAgICBjXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coZSk7XG4gICAgICAgICAgICAvLyBkbyBub3RoaW5nLiB3ZSBoYXZlIG5vIHJlZ2lzdHJ5IG9mIHRoaXMgY2xhc3NcbiAgICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHNlbGY7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgU2V0cyB0aGUgR2xvYmFsIHtAbGluayBNb2RlbEJ1aWxkZXJGdW5jdGlvbn1cbiAgICogQHBhcmFtIHtNb2RlbEJ1aWxkZXJGdW5jdGlvbn0gW2J1aWxkZXJdXG4gICAqL1xuICBzdGF0aWMgc2V0QnVpbGRlcihidWlsZGVyPzogTW9kZWxCdWlsZGVyRnVuY3Rpb24pIHtcbiAgICBtb2RlbEJ1aWxkZXJGdW5jdGlvbiA9IGJ1aWxkZXI7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSBjdXJyZW50IGdsb2JhbCB7QGxpbmsgTW9kZWxCdWlsZGVyRnVuY3Rpb259XG4gICAqL1xuICBzdGF0aWMgZ2V0QnVpbGRlcigpOiBNb2RlbEJ1aWxkZXJGdW5jdGlvbiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIG1vZGVsQnVpbGRlckZ1bmN0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGN1cnJlbnQge0BsaW5rIE1vZGVsUmVnaXN0cnlNYW5hZ2VyfVxuICAgKlxuICAgKiBAcmV0dXJuIE1vZGVsUmVnaXN0cnksIGRlZmF1bHRzIHRvIHtAbGluayBNb2RlbFJlZ2lzdHJ5TWFuYWdlcn1cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdldFJlZ2lzdHJ5KCkge1xuICAgIGlmICghYWN0aW5nTW9kZWxSZWdpc3RyeSkgYWN0aW5nTW9kZWxSZWdpc3RyeSA9IG5ldyBNb2RlbFJlZ2lzdHJ5TWFuYWdlcigpO1xuICAgIHJldHVybiBhY3RpbmdNb2RlbFJlZ2lzdHJ5O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGN1cnJlbnQgYWN0aW5nTW9kZWxSZWdpc3RyeVxuICAgKlxuICAgKiBAcGFyYW0ge0J1aWxkZXJSZWdpc3RyeX0gbW9kZWxSZWdpc3RyeSB0aGUgbmV3IGltcGxlbWVudGF0aW9uIG9mIFJlZ2lzdHJ5XG4gICAqL1xuICBzdGF0aWMgc2V0UmVnaXN0cnkobW9kZWxSZWdpc3RyeTogQnVpbGRlclJlZ2lzdHJ5PGFueT4pIHtcbiAgICBhY3RpbmdNb2RlbFJlZ2lzdHJ5ID0gbW9kZWxSZWdpc3RyeTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSByZWdpc3RlciBuZXcgTW9kZWxzXG4gICAqIEBwYXJhbSB7YW55fSBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge3N0cmluZ30gW25hbWVdIHdoZW4gbm90IGRlZmluZWQsIHRoZSBuYW1lIG9mIHRoZSBjb25zdHJ1Y3RvciB3aWxsIGJlIHVzZWRcbiAgICpcbiAgICogQHNlZSBNb2RlbFJlZ2lzdHJ5XG4gICAqL1xuICBzdGF0aWMgcmVnaXN0ZXI8VCBleHRlbmRzIE1vZGVsPihcbiAgICBjb25zdHJ1Y3RvcjogTW9kZWxDb25zdHJ1Y3RvcjxUPixcbiAgICBuYW1lPzogc3RyaW5nXG4gICk6IHZvaWQge1xuICAgIHJldHVybiBNb2RlbC5nZXRSZWdpc3RyeSgpLnJlZ2lzdGVyKGNvbnN0cnVjdG9yLCBuYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBHZXRzIGEgcmVnaXN0ZXJlZCBNb2RlbCB7QGxpbmsgTW9kZWxDb25zdHJ1Y3Rvcn1cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICpcbiAgICogQHNlZSBNb2RlbFJlZ2lzdHJ5XG4gICAqL1xuICBzdGF0aWMgZ2V0PFQgZXh0ZW5kcyBNb2RlbD4obmFtZTogc3RyaW5nKTogTW9kZWxDb25zdHJ1Y3RvcjxUPiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIE1vZGVsLmdldFJlZ2lzdHJ5KCkuZ2V0KG5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gb2JqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbY2xhenpdIHdoZW4gcHJvdmlkZWQsIGl0IHdpbGwgYXR0ZW1wdCB0byBmaW5kIHRoZSBtYXRjaGluZyBjb25zdHJ1Y3RvclxuICAgKlxuICAgKiBAdGhyb3dzIEVycm9yIElmIGNsYXp6IGlzIG5vdCBmb3VuZCwgb3Igb2JqIGlzIG5vdCBhIHtAbGluayBNb2RlbH0gbWVhbmluZyBpdCBoYXMgbm8ge0BsaW5rIE1vZGVsS2V5cy5BTkNIT1J9IHByb3BlcnR5XG4gICAqXG4gICAqIEBzZWUgTW9kZWxSZWdpc3RyeVxuICAgKi9cbiAgc3RhdGljIGJ1aWxkPFQgZXh0ZW5kcyBNb2RlbD4oXG4gICAgb2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge30sXG4gICAgY2xheno/OiBzdHJpbmdcbiAgKTogVCB7XG4gICAgcmV0dXJuIE1vZGVsLmdldFJlZ2lzdHJ5KCkuYnVpbGQob2JqLCBjbGF6eik7XG4gIH1cblxuICBzdGF0aWMgZ2V0TWV0YWRhdGE8ViBleHRlbmRzIE1vZGVsPihtb2RlbDogVikge1xuICAgIGNvbnN0IG1ldGFkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgIE1vZGVsLmtleShNb2RlbEtleXMuTU9ERUwpLFxuICAgICAgbW9kZWwuY29uc3RydWN0b3JcbiAgICApO1xuICAgIGlmICghbWV0YWRhdGEpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiY291bGQgbm90IGZpbmQgbWV0YWRhdGEgZm9yIHByb3ZpZGVkIFwiICsgbW9kZWwuY29uc3RydWN0b3IubmFtZVxuICAgICAgKTtcbiAgICByZXR1cm4gbWV0YWRhdGE7XG4gIH1cblxuICBzdGF0aWMgZ2V0QXR0cmlidXRlczxWIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBDb25zdHJ1Y3RvcjxWPiB8IFYpIHtcbiAgICBjb25zdCByZXN1bHQ6IHN0cmluZ1tdID0gW107XG4gICAgbGV0IHByb3RvdHlwZSA9XG4gICAgICBtb2RlbCBpbnN0YW5jZW9mIE1vZGVsXG4gICAgICAgID8gT2JqZWN0LmdldFByb3RvdHlwZU9mKG1vZGVsKVxuICAgICAgICA6IChtb2RlbCBhcyBhbnkpLnByb3RvdHlwZTtcbiAgICB3aGlsZSAocHJvdG90eXBlICE9IG51bGwpIHtcbiAgICAgIGNvbnN0IHByb3BzOiBzdHJpbmdbXSA9IHByb3RvdHlwZVtNb2RlbEtleXMuQVRUUklCVVRFXTtcbiAgICAgIGlmIChwcm9wcykge1xuICAgICAgICByZXN1bHQucHVzaCguLi5wcm9wcyk7XG4gICAgICB9XG4gICAgICBwcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG90eXBlKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHN0YXRpYyBlcXVhbHM8ViBleHRlbmRzIE1vZGVsPihvYmoxOiBWLCBvYmoyOiBWLCAuLi5leGNlcHRpb25zOiBhbnlbXSkge1xuICAgIHJldHVybiBpc0VxdWFsKG9iajEsIG9iajIsIC4uLmV4Y2VwdGlvbnMpO1xuICB9XG5cbiAgc3RhdGljIGhhc0Vycm9yczxWIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBWLCAuLi5wcm9wc1RvSWdub3JlOiBzdHJpbmdbXSkge1xuICAgIHJldHVybiB2YWxpZGF0ZShtb2RlbCwgLi4ucHJvcHNUb0lnbm9yZSk7XG4gIH1cblxuICBzdGF0aWMgc2VyaWFsaXplPFYgZXh0ZW5kcyBNb2RlbD4obW9kZWw6IFYpIHtcbiAgICBjb25zdCBtZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICBNb2RlbC5rZXkoTW9kZWxLZXlzLlNFUklBTElaQVRJT04pLFxuICAgICAgbW9kZWwuY29uc3RydWN0b3JcbiAgICApO1xuXG4gICAgaWYgKG1ldGFkYXRhICYmIG1ldGFkYXRhLnNlcmlhbGl6ZXIpXG4gICAgICByZXR1cm4gU2VyaWFsaXphdGlvbi5zZXJpYWxpemUoXG4gICAgICAgIHRoaXMsXG4gICAgICAgIG1ldGFkYXRhLnNlcmlhbGl6ZXIsXG4gICAgICAgIC4uLihtZXRhZGF0YS5hcmdzIHx8IFtdKVxuICAgICAgKTtcbiAgICByZXR1cm4gU2VyaWFsaXphdGlvbi5zZXJpYWxpemUobW9kZWwpO1xuICB9XG5cbiAgc3RhdGljIGhhc2g8ViBleHRlbmRzIE1vZGVsPihtb2RlbDogVikge1xuICAgIGNvbnN0IG1ldGFkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgIE1vZGVsLmtleShNb2RlbEtleXMuSEFTSElORyksXG4gICAgICBtb2RlbC5jb25zdHJ1Y3RvclxuICAgICk7XG5cbiAgICBpZiAobWV0YWRhdGEgJiYgbWV0YWRhdGEuYWxnb3JpdGhtKVxuICAgICAgcmV0dXJuIEhhc2hpbmcuaGFzaChtb2RlbCwgbWV0YWRhdGEuYWxnb3JpdGhtLCAuLi4obWV0YWRhdGEuYXJncyB8fCBbXSkpO1xuICAgIHJldHVybiBIYXNoaW5nLmhhc2gobW9kZWwpO1xuICB9XG4gIC8qKlxuICAgKiBAc3VtbWFyeSBCdWlsZHMgdGhlIGtleSB0byBzdG9yZSBhcyBNZXRhZGF0YSB1bmRlciBSZWZsZWN0aW9uc1xuICAgKiBAZGVzY3JpcHRpb24gY29uY2F0ZW5hdGVzIHtAbGluayBNb2RlbEtleXMjUkVGTEVDVH0gd2l0aCB0aGUgcHJvdmlkZWQga2V5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAgICovXG4gIHN0YXRpYyBrZXkoc3RyOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gTW9kZWxLZXlzLlJFRkxFQ1QgKyBzdHI7XG4gIH1cbn1cbiIsImltcG9ydCB7IENvbnN0cnVjdG9yIH0gZnJvbSBcIi4uL21vZGVsL3R5cGVzXCI7XG5pbXBvcnQgeyBTZXJpYWxpemVyIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIi4uL21vZGVsL01vZGVsXCI7XG5pbXBvcnQgeyBNb2RlbEtleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuZXhwb3J0IGNvbnN0IERlZmF1bHRTZXJpYWxpemF0aW9uTWV0aG9kID0gXCJqc29uXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgQ29uY3JldGUgaW1wbGVtZW50YXRpb24gb2YgYSB7QGxpbmsgU2VyaWFsaXplcn0gaW4gSlNPTiBmb3JtYXRcbiAqIEBkZXNjcmlwdGlvbiBKUydzIG5hdGl2ZSBKU09OLnN0cmluZ2lmeSAodXNlZCBoZXJlKSBpcyBub3QgZGV0ZXJtaW5pc3RpY1xuICogYW5kIHRoZXJlZm9yZSBzaG91bGQgbm90IGJlIHVzZWQgZm9yIGhhc2hpbmcgcHVycG9zZXNcbiAqXG4gKiBUbyBrZWVwIGRlcGVuZGVuY2llcyBsb3csIHdlIHdpbGwgbm90IGltcGxlbWVudCB0aGlzLCBidXQgd2UgcmVjb21tZW5kXG4gKiBpbXBsZW1lbnRpbmcgYSBzaW1pbGFyIHtAbGluayBKU09OU2VyaWFsaXplcn0gdXNpbmcgJ2RldGVybWluaXN0aWMtanNvbicgbGlicmFyaWVzXG4gKlxuICogQGNsYXNzIEpTT05TZXJpYWxpemVyXG4gKiBAaW1wbGVtZW50cyBTZXJpYWxpemVyXG4gKlxuICogQGNhdGVnb3J5IFNlcmlhbGl6YXRpb25cbiAqL1xuZXhwb3J0IGNsYXNzIEpTT05TZXJpYWxpemVyPFQgZXh0ZW5kcyBNb2RlbD4gaW1wbGVtZW50cyBTZXJpYWxpemVyPFQ+IHtcbiAgY29uc3RydWN0b3IoKSB7fVxuICAvKipcbiAgICogQHN1bW1hcnkgcHJlcGFyZXMgdGhlIG1vZGVsIGZvciBzZXJpYWxpemF0aW9uXG4gICAqIEBkZXNjcmlwdGlvbiByZXR1cm5zIGEgc2hhbGxvdyBjb3B5IG9mIHRoZSBvYmplY3QsIGNvbnRhaW5pbmcgYW4gZW51bWVyYWJsZSB7QGxpbmsgTW9kZWxLZXlzI0FOQ0hPUn0gcHJvcGVydHlcbiAgICogc28gdGhlIG9iamVjdCBjYW4gYmUgcmVjb2duaXplZCB1cG9uIGRlc2VyaWFsaXphdGlvblxuICAgKlxuICAgKiBAcGFyYW0ge1R9IG1vZGVsXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIHByb3RlY3RlZCBwcmVTZXJpYWxpemUobW9kZWw6IFQpIHtcbiAgICAvLyBUT0RPOiBuZXN0ZWQgcHJlc2VyaWFsaXphdGlvbiAoc28gaW5jcmVhc2UgcGVyZm9ybWFuY2Ugd2hlbiBkZXNlcmlhbGl6aW5nKVxuICAgIGNvbnN0IHRvU2VyaWFsaXplOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gT2JqZWN0LmFzc2lnbih7fSwgbW9kZWwpO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gTW9kZWwuZ2V0TWV0YWRhdGEobW9kZWwpO1xuICAgIHRvU2VyaWFsaXplW01vZGVsS2V5cy5BTkNIT1JdID0gbWV0YWRhdGEgfHwgbW9kZWwuY29uc3RydWN0b3IubmFtZTtcbiAgICByZXR1cm4gdG9TZXJpYWxpemU7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgUmVidWlsZHMgYSBtb2RlbCBmcm9tIGEgc2VyaWFsaXphdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gICAqXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBpdCBmYWlscyB0byBwYXJzZSB0aGUgc3RyaW5nLCBvciB0byBidWlsZCB0aGUgbW9kZWxcbiAgICovXG4gIGRlc2VyaWFsaXplKHN0cjogc3RyaW5nKTogVCB7XG4gICAgY29uc3QgZGVzZXJpYWxpemF0aW9uID0gSlNPTi5wYXJzZShzdHIpO1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGRlc2VyaWFsaXphdGlvbltNb2RlbEtleXMuQU5DSE9SXTtcbiAgICBpZiAoIWNsYXNzTmFtZSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvdWxkIG5vdCBmaW5kIGNsYXNzIHJlZmVyZW5jZSBpbiBzZXJpYWxpemVkIG1vZGVsXCIpO1xuICAgIGNvbnN0IG1vZGVsOiBUID0gTW9kZWwuYnVpbGQoZGVzZXJpYWxpemF0aW9uLCBjbGFzc05hbWUpIGFzIHVua25vd24gYXMgVDtcbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgU2VyaWFsaXplcyBhIG1vZGVsXG4gICAqIEBwYXJhbSB7VH0gbW9kZWxcbiAgICpcbiAgICogQHRocm93cyB7RXJyb3J9IGlmIGZhaWxzIHRvIHNlcmlhbGl6ZVxuICAgKi9cbiAgc2VyaWFsaXplKG1vZGVsOiBUKTogc3RyaW5nIHtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodGhpcy5wcmVTZXJpYWxpemUobW9kZWwpKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgU2VyaWFsaXphdGlvbiB7XG4gIHByaXZhdGUgc3RhdGljIGN1cnJlbnQ6IHN0cmluZyA9IERlZmF1bHRTZXJpYWxpemF0aW9uTWV0aG9kO1xuXG4gIHByaXZhdGUgc3RhdGljIGNhY2hlOiBSZWNvcmQ8c3RyaW5nLCBTZXJpYWxpemVyPGFueT4+ID0ge1xuICAgIGpzb246IG5ldyBKU09OU2VyaWFsaXplcigpLFxuICB9O1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7fVxuXG4gIHByaXZhdGUgc3RhdGljIGdldChrZXk6IHN0cmluZyk6IGFueSB7XG4gICAgaWYgKGtleSBpbiB0aGlzLmNhY2hlKSByZXR1cm4gdGhpcy5jYWNoZVtrZXldO1xuICAgIHRocm93IG5ldyBFcnJvcihgTm8gc2VyaWFsaXphdGlvbiBtZXRob2QgcmVnaXN0ZXJlZCB1bmRlciAke2tleX1gKTtcbiAgfVxuXG4gIHN0YXRpYyByZWdpc3RlcihcbiAgICBrZXk6IHN0cmluZyxcbiAgICBmdW5jOiBDb25zdHJ1Y3RvcjxTZXJpYWxpemVyPGFueT4+LFxuICAgIHNldERlZmF1bHQgPSBmYWxzZVxuICApOiB2b2lkIHtcbiAgICBpZiAoa2V5IGluIHRoaXMuY2FjaGUpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFNlcmlhbGl6YXRpb24gbWV0aG9kICR7a2V5fSBhbHJlYWR5IHJlZ2lzdGVyZWRgKTtcbiAgICB0aGlzLmNhY2hlW2tleV0gPSBuZXcgZnVuYygpO1xuICAgIGlmIChzZXREZWZhdWx0KSB0aGlzLmN1cnJlbnQgPSBrZXk7XG4gIH1cblxuICBzdGF0aWMgc2VyaWFsaXplKG9iajogYW55LCBtZXRob2Q/OiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgaWYgKCFtZXRob2QpIHJldHVybiB0aGlzLmdldCh0aGlzLmN1cnJlbnQpLnNlcmlhbGl6ZShvYmosIC4uLmFyZ3MpO1xuICAgIHJldHVybiB0aGlzLmdldChtZXRob2QpLnNlcmlhbGl6ZShvYmosIC4uLmFyZ3MpO1xuICB9XG5cbiAgc3RhdGljIGRlc2VyaWFsaXplKG9iajogc3RyaW5nLCBtZXRob2Q/OiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgaWYgKCFtZXRob2QpIHJldHVybiB0aGlzLmdldCh0aGlzLmN1cnJlbnQpLmRlc2VyaWFsaXplKG9iaiwgLi4uYXJncyk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KG1ldGhvZCkuZGVzZXJpYWxpemUob2JqLCAuLi5hcmdzKTtcbiAgfVxuXG4gIHN0YXRpYyBzZXREZWZhdWx0KG1ldGhvZDogc3RyaW5nKSB7XG4gICAgdGhpcy5jdXJyZW50ID0gdGhpcy5nZXQobWV0aG9kKTtcbiAgfVxufVxuIiwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlLCBTdXBwcmVzc2VkRXJyb3IsIFN5bWJvbCwgSXRlcmF0b3IgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXNEZWNvcmF0ZShjdG9yLCBkZXNjcmlwdG9ySW4sIGRlY29yYXRvcnMsIGNvbnRleHRJbiwgaW5pdGlhbGl6ZXJzLCBleHRyYUluaXRpYWxpemVycykge1xyXG4gICAgZnVuY3Rpb24gYWNjZXB0KGYpIHsgaWYgKGYgIT09IHZvaWQgMCAmJiB0eXBlb2YgZiAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRnVuY3Rpb24gZXhwZWN0ZWRcIik7IHJldHVybiBmOyB9XHJcbiAgICB2YXIga2luZCA9IGNvbnRleHRJbi5raW5kLCBrZXkgPSBraW5kID09PSBcImdldHRlclwiID8gXCJnZXRcIiA6IGtpbmQgPT09IFwic2V0dGVyXCIgPyBcInNldFwiIDogXCJ2YWx1ZVwiO1xyXG4gICAgdmFyIHRhcmdldCA9ICFkZXNjcmlwdG9ySW4gJiYgY3RvciA/IGNvbnRleHRJbltcInN0YXRpY1wiXSA/IGN0b3IgOiBjdG9yLnByb3RvdHlwZSA6IG51bGw7XHJcbiAgICB2YXIgZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JJbiB8fCAodGFyZ2V0ID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGNvbnRleHRJbi5uYW1lKSA6IHt9KTtcclxuICAgIHZhciBfLCBkb25lID0gZmFsc2U7XHJcbiAgICBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgIHZhciBjb250ZXh0ID0ge307XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4pIGNvbnRleHRbcF0gPSBwID09PSBcImFjY2Vzc1wiID8ge30gOiBjb250ZXh0SW5bcF07XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4uYWNjZXNzKSBjb250ZXh0LmFjY2Vzc1twXSA9IGNvbnRleHRJbi5hY2Nlc3NbcF07XHJcbiAgICAgICAgY29udGV4dC5hZGRJbml0aWFsaXplciA9IGZ1bmN0aW9uIChmKSB7IGlmIChkb25lKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGFkZCBpbml0aWFsaXplcnMgYWZ0ZXIgZGVjb3JhdGlvbiBoYXMgY29tcGxldGVkXCIpOyBleHRyYUluaXRpYWxpemVycy5wdXNoKGFjY2VwdChmIHx8IG51bGwpKTsgfTtcclxuICAgICAgICB2YXIgcmVzdWx0ID0gKDAsIGRlY29yYXRvcnNbaV0pKGtpbmQgPT09IFwiYWNjZXNzb3JcIiA/IHsgZ2V0OiBkZXNjcmlwdG9yLmdldCwgc2V0OiBkZXNjcmlwdG9yLnNldCB9IDogZGVzY3JpcHRvcltrZXldLCBjb250ZXh0KTtcclxuICAgICAgICBpZiAoa2luZCA9PT0gXCJhY2Nlc3NvclwiKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IHZvaWQgMCkgY29udGludWU7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IG51bGwgfHwgdHlwZW9mIHJlc3VsdCAhPT0gXCJvYmplY3RcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZFwiKTtcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmdldCkpIGRlc2NyaXB0b3IuZ2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LnNldCkpIGRlc2NyaXB0b3Iuc2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmluaXQpKSBpbml0aWFsaXplcnMudW5zaGlmdChfKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoXyA9IGFjY2VwdChyZXN1bHQpKSB7XHJcbiAgICAgICAgICAgIGlmIChraW5kID09PSBcImZpZWxkXCIpIGluaXRpYWxpemVycy51bnNoaWZ0KF8pO1xyXG4gICAgICAgICAgICBlbHNlIGRlc2NyaXB0b3Jba2V5XSA9IF87XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHRhcmdldCkgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgY29udGV4dEluLm5hbWUsIGRlc2NyaXB0b3IpO1xyXG4gICAgZG9uZSA9IHRydWU7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19ydW5Jbml0aWFsaXplcnModGhpc0FyZywgaW5pdGlhbGl6ZXJzLCB2YWx1ZSkge1xyXG4gICAgdmFyIHVzZVZhbHVlID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGluaXRpYWxpemVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIHZhbHVlID0gdXNlVmFsdWUgPyBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnLCB2YWx1ZSkgOiBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnKTtcclxuICAgIH1cclxuICAgIHJldHVybiB1c2VWYWx1ZSA/IHZhbHVlIDogdm9pZCAwO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcHJvcEtleSh4KSB7XHJcbiAgICByZXR1cm4gdHlwZW9mIHggPT09IFwic3ltYm9sXCIgPyB4IDogXCJcIi5jb25jYXQoeCk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zZXRGdW5jdGlvbk5hbWUoZiwgbmFtZSwgcHJlZml4KSB7XHJcbiAgICBpZiAodHlwZW9mIG5hbWUgPT09IFwic3ltYm9sXCIpIG5hbWUgPSBuYW1lLmRlc2NyaXB0aW9uID8gXCJbXCIuY29uY2F0KG5hbWUuZGVzY3JpcHRpb24sIFwiXVwiKSA6IFwiXCI7XHJcbiAgICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KGYsIFwibmFtZVwiLCB7IGNvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHByZWZpeCA/IFwiXCIuY29uY2F0KHByZWZpeCwgXCIgXCIsIG5hbWUpIDogbmFtZSB9KTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGcgPSBPYmplY3QuY3JlYXRlKCh0eXBlb2YgSXRlcmF0b3IgPT09IFwiZnVuY3Rpb25cIiA/IEl0ZXJhdG9yIDogT2JqZWN0KS5wcm90b3R5cGUpO1xyXG4gICAgcmV0dXJuIGcubmV4dCA9IHZlcmIoMCksIGdbXCJ0aHJvd1wiXSA9IHZlcmIoMSksIGdbXCJyZXR1cm5cIl0gPSB2ZXJiKDIpLCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcclxuICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgd2hpbGUgKGcgJiYgKGcgPSAwLCBvcFswXSAmJiAoXyA9IDApKSwgXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fY3JlYXRlQmluZGluZyA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XHJcbiAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xyXG4gICAgICAgIGRlc2MgPSB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH07XHJcbiAgICB9XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIGRlc2MpO1xyXG59KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIG9bazJdID0gbVtrXTtcclxufSk7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHBvcnRTdGFyKG0sIG8pIHtcclxuICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobywgcCkpIF9fY3JlYXRlQmluZGluZyhvLCBtLCBwKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcclxuICAgIHZhciBzID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIFN5bWJvbC5pdGVyYXRvciwgbSA9IHMgJiYgb1tzXSwgaSA9IDA7XHJcbiAgICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcclxuICAgIGlmIChvICYmIHR5cGVvZiBvLmxlbmd0aCA9PT0gXCJudW1iZXJcIikgcmV0dXJuIHtcclxuICAgICAgICBuZXh0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihzID8gXCJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLlwiIDogXCJTeW1ib2wuaXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXTtcclxuICAgIGlmICghbSkgcmV0dXJuIG87XHJcbiAgICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgd2hpbGUgKChuID09PSB2b2lkIDAgfHwgbi0tID4gMCkgJiYgIShyID0gaS5uZXh0KCkpLmRvbmUpIGFyLnB1c2goci52YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyb3IpIHsgZSA9IHsgZXJyb3I6IGVycm9yIH07IH1cclxuICAgIGZpbmFsbHkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChyICYmICFyLmRvbmUgJiYgKG0gPSBpW1wicmV0dXJuXCJdKSkgbS5jYWxsKGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cclxuICAgIH1cclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZCgpIHtcclxuICAgIGZvciAodmFyIGFyID0gW10sIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5cygpIHtcclxuICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xyXG4gICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxyXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxyXG4gICAgICAgICAgICByW2tdID0gYVtqXTtcclxuICAgIHJldHVybiByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheSh0bywgZnJvbSwgcGFjaykge1xyXG4gICAgaWYgKHBhY2sgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMikgZm9yICh2YXIgaSA9IDAsIGwgPSBmcm9tLmxlbmd0aCwgYXI7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICBpZiAoYXIgfHwgIShpIGluIGZyb20pKSB7XHJcbiAgICAgICAgICAgIGlmICghYXIpIGFyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSwgMCwgaSk7XHJcbiAgICAgICAgICAgIGFyW2ldID0gZnJvbVtpXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdG8uY29uY2F0KGFyIHx8IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20pKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IE9iamVjdC5jcmVhdGUoKHR5cGVvZiBBc3luY0l0ZXJhdG9yID09PSBcImZ1bmN0aW9uXCIgPyBBc3luY0l0ZXJhdG9yIDogT2JqZWN0KS5wcm90b3R5cGUpLCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIsIGF3YWl0UmV0dXJuKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gYXdhaXRSZXR1cm4oZikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGYsIHJlamVjdCk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpZiAoZ1tuXSkgeyBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyBpZiAoZikgaVtuXSA9IGYoaVtuXSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IGZhbHNlIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxufTtcclxuXHJcbnZhciBvd25LZXlzID0gZnVuY3Rpb24obykge1xyXG4gICAgb3duS2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzIHx8IGZ1bmN0aW9uIChvKSB7XHJcbiAgICAgICAgdmFyIGFyID0gW107XHJcbiAgICAgICAgZm9yICh2YXIgayBpbiBvKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIGspKSBhclthci5sZW5ndGhdID0gaztcclxuICAgICAgICByZXR1cm4gYXI7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIG93bktleXMobyk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xyXG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayA9IG93bktleXMobW9kKSwgaSA9IDA7IGkgPCBrLmxlbmd0aDsgaSsrKSBpZiAoa1tpXSAhPT0gXCJkZWZhdWx0XCIpIF9fY3JlYXRlQmluZGluZyhyZXN1bHQsIG1vZCwga1tpXSk7XHJcbiAgICBfX3NldE1vZHVsZURlZmF1bHQocmVzdWx0LCBtb2QpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcclxuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkSW4oc3RhdGUsIHJlY2VpdmVyKSB7XHJcbiAgICBpZiAocmVjZWl2ZXIgPT09IG51bGwgfHwgKHR5cGVvZiByZWNlaXZlciAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcmVjZWl2ZXIgIT09IFwiZnVuY3Rpb25cIikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgdXNlICdpbicgb3BlcmF0b3Igb24gbm9uLW9iamVjdFwiKTtcclxuICAgIHJldHVybiB0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyID09PSBzdGF0ZSA6IHN0YXRlLmhhcyhyZWNlaXZlcik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZShlbnYsIHZhbHVlLCBhc3luYykge1xyXG4gICAgaWYgKHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB2b2lkIDApIHtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiB2YWx1ZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IGV4cGVjdGVkLlwiKTtcclxuICAgICAgICB2YXIgZGlzcG9zZSwgaW5uZXI7XHJcbiAgICAgICAgaWYgKGFzeW5jKSB7XHJcbiAgICAgICAgICAgIGlmICghU3ltYm9sLmFzeW5jRGlzcG9zZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0Rpc3Bvc2UgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgICAgICAgICBkaXNwb3NlID0gdmFsdWVbU3ltYm9sLmFzeW5jRGlzcG9zZV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChkaXNwb3NlID09PSB2b2lkIDApIHtcclxuICAgICAgICAgICAgaWYgKCFTeW1ib2wuZGlzcG9zZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5kaXNwb3NlIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgICAgICAgICAgZGlzcG9zZSA9IHZhbHVlW1N5bWJvbC5kaXNwb3NlXTtcclxuICAgICAgICAgICAgaWYgKGFzeW5jKSBpbm5lciA9IGRpc3Bvc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0eXBlb2YgZGlzcG9zZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IG5vdCBkaXNwb3NhYmxlLlwiKTtcclxuICAgICAgICBpZiAoaW5uZXIpIGRpc3Bvc2UgPSBmdW5jdGlvbigpIHsgdHJ5IHsgaW5uZXIuY2FsbCh0aGlzKTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7IH0gfTtcclxuICAgICAgICBlbnYuc3RhY2sucHVzaCh7IHZhbHVlOiB2YWx1ZSwgZGlzcG9zZTogZGlzcG9zZSwgYXN5bmM6IGFzeW5jIH0pO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoYXN5bmMpIHtcclxuICAgICAgICBlbnYuc3RhY2sucHVzaCh7IGFzeW5jOiB0cnVlIH0pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHZhbHVlO1xyXG5cclxufVxyXG5cclxudmFyIF9TdXBwcmVzc2VkRXJyb3IgPSB0eXBlb2YgU3VwcHJlc3NlZEVycm9yID09PSBcImZ1bmN0aW9uXCIgPyBTdXBwcmVzc2VkRXJyb3IgOiBmdW5jdGlvbiAoZXJyb3IsIHN1cHByZXNzZWQsIG1lc3NhZ2UpIHtcclxuICAgIHZhciBlID0gbmV3IEVycm9yKG1lc3NhZ2UpO1xyXG4gICAgcmV0dXJuIGUubmFtZSA9IFwiU3VwcHJlc3NlZEVycm9yXCIsIGUuZXJyb3IgPSBlcnJvciwgZS5zdXBwcmVzc2VkID0gc3VwcHJlc3NlZCwgZTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2Rpc3Bvc2VSZXNvdXJjZXMoZW52KSB7XHJcbiAgICBmdW5jdGlvbiBmYWlsKGUpIHtcclxuICAgICAgICBlbnYuZXJyb3IgPSBlbnYuaGFzRXJyb3IgPyBuZXcgX1N1cHByZXNzZWRFcnJvcihlLCBlbnYuZXJyb3IsIFwiQW4gZXJyb3Igd2FzIHN1cHByZXNzZWQgZHVyaW5nIGRpc3Bvc2FsLlwiKSA6IGU7XHJcbiAgICAgICAgZW52Lmhhc0Vycm9yID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIHZhciByLCBzID0gMDtcclxuICAgIGZ1bmN0aW9uIG5leHQoKSB7XHJcbiAgICAgICAgd2hpbGUgKHIgPSBlbnYuc3RhY2sucG9wKCkpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGlmICghci5hc3luYyAmJiBzID09PSAxKSByZXR1cm4gcyA9IDAsIGVudi5zdGFjay5wdXNoKHIpLCBQcm9taXNlLnJlc29sdmUoKS50aGVuKG5leHQpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHIuZGlzcG9zZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSByLmRpc3Bvc2UuY2FsbChyLnZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoci5hc3luYykgcmV0dXJuIHMgfD0gMiwgUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCkudGhlbihuZXh0LCBmdW5jdGlvbihlKSB7IGZhaWwoZSk7IHJldHVybiBuZXh0KCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBzIHw9IDE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIGZhaWwoZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHMgPT09IDEpIHJldHVybiBlbnYuaGFzRXJyb3IgPyBQcm9taXNlLnJlamVjdChlbnYuZXJyb3IpIDogUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgaWYgKGVudi5oYXNFcnJvcikgdGhyb3cgZW52LmVycm9yO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5leHQoKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmV3cml0ZVJlbGF0aXZlSW1wb3J0RXh0ZW5zaW9uKHBhdGgsIHByZXNlcnZlSnN4KSB7XHJcbiAgICBpZiAodHlwZW9mIHBhdGggPT09IFwic3RyaW5nXCIgJiYgL15cXC5cXC4/XFwvLy50ZXN0KHBhdGgpKSB7XHJcbiAgICAgICAgcmV0dXJuIHBhdGgucmVwbGFjZSgvXFwuKHRzeCkkfCgoPzpcXC5kKT8pKCg/OlxcLlteLi9dKz8pPylcXC4oW2NtXT8pdHMkL2ksIGZ1bmN0aW9uIChtLCB0c3gsIGQsIGV4dCwgY20pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRzeCA/IHByZXNlcnZlSnN4ID8gXCIuanN4XCIgOiBcIi5qc1wiIDogZCAmJiAoIWV4dCB8fCAhY20pID8gbSA6IChkICsgZXh0ICsgXCIuXCIgKyBjbS50b0xvd2VyQ2FzZSgpICsgXCJqc1wiKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiBwYXRoO1xyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCB7XHJcbiAgICBfX2V4dGVuZHM6IF9fZXh0ZW5kcyxcclxuICAgIF9fYXNzaWduOiBfX2Fzc2lnbixcclxuICAgIF9fcmVzdDogX19yZXN0LFxyXG4gICAgX19kZWNvcmF0ZTogX19kZWNvcmF0ZSxcclxuICAgIF9fcGFyYW06IF9fcGFyYW0sXHJcbiAgICBfX2VzRGVjb3JhdGU6IF9fZXNEZWNvcmF0ZSxcclxuICAgIF9fcnVuSW5pdGlhbGl6ZXJzOiBfX3J1bkluaXRpYWxpemVycyxcclxuICAgIF9fcHJvcEtleTogX19wcm9wS2V5LFxyXG4gICAgX19zZXRGdW5jdGlvbk5hbWU6IF9fc2V0RnVuY3Rpb25OYW1lLFxyXG4gICAgX19tZXRhZGF0YTogX19tZXRhZGF0YSxcclxuICAgIF9fYXdhaXRlcjogX19hd2FpdGVyLFxyXG4gICAgX19nZW5lcmF0b3I6IF9fZ2VuZXJhdG9yLFxyXG4gICAgX19jcmVhdGVCaW5kaW5nOiBfX2NyZWF0ZUJpbmRpbmcsXHJcbiAgICBfX2V4cG9ydFN0YXI6IF9fZXhwb3J0U3RhcixcclxuICAgIF9fdmFsdWVzOiBfX3ZhbHVlcyxcclxuICAgIF9fcmVhZDogX19yZWFkLFxyXG4gICAgX19zcHJlYWQ6IF9fc3ByZWFkLFxyXG4gICAgX19zcHJlYWRBcnJheXM6IF9fc3ByZWFkQXJyYXlzLFxyXG4gICAgX19zcHJlYWRBcnJheTogX19zcHJlYWRBcnJheSxcclxuICAgIF9fYXdhaXQ6IF9fYXdhaXQsXHJcbiAgICBfX2FzeW5jR2VuZXJhdG9yOiBfX2FzeW5jR2VuZXJhdG9yLFxyXG4gICAgX19hc3luY0RlbGVnYXRvcjogX19hc3luY0RlbGVnYXRvcixcclxuICAgIF9fYXN5bmNWYWx1ZXM6IF9fYXN5bmNWYWx1ZXMsXHJcbiAgICBfX21ha2VUZW1wbGF0ZU9iamVjdDogX19tYWtlVGVtcGxhdGVPYmplY3QsXHJcbiAgICBfX2ltcG9ydFN0YXI6IF9faW1wb3J0U3RhcixcclxuICAgIF9faW1wb3J0RGVmYXVsdDogX19pbXBvcnREZWZhdWx0LFxyXG4gICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldDogX19jbGFzc1ByaXZhdGVGaWVsZEdldCxcclxuICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQ6IF9fY2xhc3NQcml2YXRlRmllbGRTZXQsXHJcbiAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkSW46IF9fY2xhc3NQcml2YXRlRmllbGRJbixcclxuICAgIF9fYWRkRGlzcG9zYWJsZVJlc291cmNlOiBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZSxcclxuICAgIF9fZGlzcG9zZVJlc291cmNlczogX19kaXNwb3NlUmVzb3VyY2VzLFxyXG4gICAgX19yZXdyaXRlUmVsYXRpdmVJbXBvcnRFeHRlbnNpb246IF9fcmV3cml0ZVJlbGF0aXZlSW1wb3J0RXh0ZW5zaW9uLFxyXG59O1xyXG4iLCJpbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBzZiB9IGZyb20gXCIuLi8uLi91dGlscy9zdHJpbmdzXCI7XG5pbXBvcnQgeyBSZWZsZWN0aW9uIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBWYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgQmFzZSBJbXBsZW1lbnRhdGlvbiBmb3IgVmFsaWRhdG9yc1xuICogQGRlc2NyaXB0aW9uIFByb3ZpZGVzIHRoZSB1bmRlcmx5aW5nIGZ1bmN0aW9uYWxpdHkgZm9yIHtAbGluayBWYWxpZGF0b3J9c1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB2YWxpZGF0aW9uS2V5IHRoZSBrZXkgdG8gcmVnaXN0ZXIgdGhlIHZhbGlkYXRvciB1bmRlclxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjREVGQVVMVH1cbiAqIEBwYXJhbSB7c3RyaW5nW119IFthY2NlcHRlZFR5cGVzXSBkZWZpbmVzIHRoZSB2YWx1ZSB0eXBlcyB0aGlzIHZhbGlkYXRvciBjYW4gdmFsaWRhdGVcbiAqXG4gKiBAY2xhc3MgVmFsaWRhdG9yXG4gKiBAYWJzdHJhY3RcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBWYWxpZGF0b3I8ViBleHRlbmRzIFZhbGlkYXRvck9wdGlvbnMgPSBWYWxpZGF0b3JPcHRpb25zPiB7XG4gIHJlYWRvbmx5IG1lc3NhZ2U6IHN0cmluZztcbiAgcmVhZG9ubHkgYWNjZXB0ZWRUeXBlcz86IHN0cmluZ1tdO1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihcbiAgICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkRFRkFVTFQsXG4gICAgLi4uYWNjZXB0ZWRUeXBlczogc3RyaW5nW11cbiAgKSB7XG4gICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcblxuICAgIGlmIChhY2NlcHRlZFR5cGVzLmxlbmd0aCkgdGhpcy5hY2NlcHRlZFR5cGVzID0gYWNjZXB0ZWRUeXBlcztcbiAgICBpZiAodGhpcy5hY2NlcHRlZFR5cGVzKVxuICAgICAgdGhpcy5oYXNFcnJvcnMgPSB0aGlzLmNoZWNrVHlwZUFuZEhhc0Vycm9ycyh0aGlzLmhhc0Vycm9ycy5iaW5kKHRoaXMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBidWlsZHMgdGhlIGVycm9yIG1lc3NhZ2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2VcbiAgICogQHBhcmFtIHthbnlbXX0gYXJnc1xuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0TWVzc2FnZShtZXNzYWdlOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgcmV0dXJuIHNmKG1lc3NhZ2UsIC4uLmFyZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyB0eXBlXG4gICAqIEBwYXJhbSB7YW55fSB1bmJvdW5kXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGNoZWNrVHlwZUFuZEhhc0Vycm9ycyhcbiAgICB1bmJvdW5kOiAodmFsdWU6IGFueSwgLi4uYXJnczogYW55W10pID0+IHN0cmluZyB8IHVuZGVmaW5lZFxuICApIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKFxuICAgICAgdGhpczogVmFsaWRhdG9yLFxuICAgICAgdmFsdWU6IGFueSxcbiAgICAgIC4uLmFyZ3M6IGFueVtdXG4gICAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8ICF0aGlzLmFjY2VwdGVkVHlwZXMpXG4gICAgICAgIHJldHVybiB1bmJvdW5kKHZhbHVlLCAuLi5hcmdzKTtcbiAgICAgIGlmICghUmVmbGVjdGlvbi5jaGVja1R5cGVzKHZhbHVlLCB0aGlzLmFjY2VwdGVkVHlwZXMpKVxuICAgICAgICByZXR1cm4gdGhpcy5nZXRNZXNzYWdlKFxuICAgICAgICAgIERFRkFVTFRfRVJST1JfTUVTU0FHRVMuVFlQRSxcbiAgICAgICAgICB0aGlzLmFjY2VwdGVkVHlwZXMuam9pbihcIiwgXCIpLFxuICAgICAgICAgIHR5cGVvZiB2YWx1ZVxuICAgICAgICApO1xuICAgICAgcmV0dXJuIHVuYm91bmQodmFsdWUsIC4uLmFyZ3MpO1xuICAgIH0uYmluZCh0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYW4gYXR0cmlidXRlXG4gICAqIEBwYXJhbSB7YW55fSB2YWx1ZVxuICAgKiBAcGFyYW0ge1ZhbGlkYXRvck9wdGlvbnN9IFtvcHRpb25zXSBWYWxpZGF0ZSBvcHRpb25zIGZvciBjdXN0b21pemluZyB0aGUgbW9kZWwgdmFsaWRhdGlvbiBiZWhhdmlvclxuICAgKlxuICAgKiBAYWJzdHJhY3RcbiAgICpcbiAgICogQHNlZSBNb2RlbCNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBhYnN0cmFjdCBoYXNFcnJvcnModmFsdWU6IGFueSwgb3B0aW9ucz86IFYpOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tIFwiLi9WYWxpZGF0b3JcIjtcbmltcG9ydCB7IFZhbGlkYXRpb24gfSBmcm9tIFwiLi4vVmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IgfSBmcm9tIFwiLi4vLi4vbW9kZWwvdHlwZXNcIjtcbmltcG9ydCB7IFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBhcHBseSwgbWV0YWRhdGEgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IFZhbGlkYXRvckRlZmluaXRpb24gfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBNYXJrcyB0aGUgY2xhc3MgYXMgYSB2YWxpZGF0b3IgZm9yIGEgY2VydGFpbiBrZXkuXG4gKiBAZGVzY3JpcHRpb24gUmVnaXN0ZXJzIHRoZSBjbGFzcyBpbiB0aGUge0BsaW5rIFZhbGlkYXRpb259IHdpdGggdGhlIHByb3ZpZGVkIGtleVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlzIHRoZSB2YWxpZGF0aW9uIGtleVxuICpcbiAqIEBmdW5jdGlvbiB2YWxpZGF0b3JcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdG9yPFQgZXh0ZW5kcyBWYWxpZGF0b3I+KC4uLmtleXM6IHN0cmluZ1tdKSB7XG4gIHJldHVybiBhcHBseShcbiAgICAoKG9yaWdpbmFsOiBDb25zdHJ1Y3RvcjxUPikgPT4ge1xuICAgICAga2V5cy5mb3JFYWNoKChrOiBzdHJpbmcpID0+IHtcbiAgICAgICAgVmFsaWRhdGlvbi5yZWdpc3Rlcih7XG4gICAgICAgICAgdmFsaWRhdG9yOiBvcmlnaW5hbCxcbiAgICAgICAgICB2YWxpZGF0aW9uS2V5OiBrLFxuICAgICAgICAgIHNhdmU6IHRydWUsXG4gICAgICAgIH0gYXMgVmFsaWRhdG9yRGVmaW5pdGlvbik7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBvcmlnaW5hbDtcbiAgICB9KSBhcyBDbGFzc0RlY29yYXRvcixcbiAgICBtZXRhZGF0YShWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5WQUxJREFUT1IpLCBrZXlzKVxuICApO1xufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgRGF0ZVZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBEYXRlIFZhbGlkYXRvclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjREFURX1cbiAqXG4gKiBAY2xhc3MgRGF0ZVZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5EQVRFKVxuZXhwb3J0IGNsYXNzIERhdGVWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3I8RGF0ZVZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5EQVRFKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgTnVtYmVyLm5hbWUsIERhdGUubmFtZSwgU3RyaW5nLm5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIG1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSB7RGF0ZSB8IHN0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtEYXRlVmFsaWRhdG9yT3B0aW9uc30gW29wdGlvbnNdXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogRGF0ZSB8IHN0cmluZyxcbiAgICBvcHRpb25zOiBEYXRlVmFsaWRhdG9yT3B0aW9ucyA9IHt9XG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybjtcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHZhbHVlID0gbmV3IERhdGUodmFsdWUpO1xuXG4gICAgaWYgKE51bWJlci5pc05hTih2YWx1ZS5nZXREYXRlKCkpKSB7XG4gICAgICBjb25zdCB7IG1lc3NhZ2UgPSBcIlwiIH0gPSBvcHRpb25zO1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZShtZXNzYWdlIHx8IHRoaXMubWVzc2FnZSk7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tIFwiLi9WYWxpZGF0b3JcIjtcbmltcG9ydCB7IERFRkFVTFRfRVJST1JfTUVTU0FHRVMsIFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBQYXR0ZXJuVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG5leHBvcnQgY29uc3QgcmVnZXhwUGFyc2VyOiBSZWdFeHAgPSBuZXcgUmVnRXhwKFwiXi8oLispLyhbZ2ltdXNdKikkXCIpO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFBhdHRlcm4gVmFsaWRhdG9yXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIGRlZmF1bHRzIHRvIHtAbGluayBWYWxpZGF0aW9uS2V5cyNQQVRURVJOfVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNQQVRURVJOfVxuICpcbiAqIEBjbGFzcyBQYXR0ZXJuVmFsaWRhdG9yXG4gKiBAZXh0ZW5kcyBWYWxpZGF0b3JcbiAqXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5AdmFsaWRhdG9yKFZhbGlkYXRpb25LZXlzLlBBVFRFUk4pXG5leHBvcnQgY2xhc3MgUGF0dGVyblZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvcjxQYXR0ZXJuVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlBBVFRFUk4pIHtcbiAgICBzdXBlcihtZXNzYWdlLCBcInN0cmluZ1wiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBwYXJzZXMgYW5kIHZhbGlkYXRlcyBhIHBhdHRlcm5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhdHRlcm5cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgZ2V0UGF0dGVybihwYXR0ZXJuOiBzdHJpbmcpOiBSZWdFeHAge1xuICAgIGlmICghcmVnZXhwUGFyc2VyLnRlc3QocGF0dGVybikpIHJldHVybiBuZXcgUmVnRXhwKHBhdHRlcm4pO1xuICAgIGNvbnN0IG1hdGNoOiBhbnkgPSBwYXR0ZXJuLm1hdGNoKHJlZ2V4cFBhcnNlcik7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAobWF0Y2hbMV0sIG1hdGNoWzJdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSBNb2RlbFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtQYXR0ZXJuVmFsaWRhdG9yT3B0aW9uc30gb3B0aW9uc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9XG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IHN0cmluZyxcbiAgICBvcHRpb25zOiBQYXR0ZXJuVmFsaWRhdG9yT3B0aW9uc1xuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICghdmFsdWUpIHJldHVybjtcblxuICAgIGxldCB7IHBhdHRlcm4gfSA9IG9wdGlvbnM7XG4gICAgaWYgKCFwYXR0ZXJuKSB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIFBhdHRlcm5cIik7XG4gICAgcGF0dGVybiA9IHR5cGVvZiBwYXR0ZXJuID09PSBcInN0cmluZ1wiID8gdGhpcy5nZXRQYXR0ZXJuKHBhdHRlcm4pIDogcGF0dGVybjtcbiAgICBwYXR0ZXJuLmxhc3RJbmRleCA9IDA7IC8vIHJlc2V0cyBwYXR0ZXJuIHBvc2l0aW9uIGZvciByZXBlYXQgdmFsaWRhdGlvbiByZXF1ZXN0c1xuICAgIHJldHVybiAhcGF0dGVybi50ZXN0KHZhbHVlKVxuICAgICAgPyB0aGlzLmdldE1lc3NhZ2Uob3B0aW9ucy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSlcbiAgICAgIDogdW5kZWZpbmVkO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBERUZBVUxUX0VSUk9SX01FU1NBR0VTLFxuICBERUZBVUxUX1BBVFRFUk5TLFxuICBWYWxpZGF0aW9uS2V5cyxcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBQYXR0ZXJuVmFsaWRhdG9yIH0gZnJvbSBcIi4vUGF0dGVyblZhbGlkYXRvclwiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgUGF0dGVyblZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBFbWFpbCBWYWxpZGF0b3JcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0VNQUlMfVxuICpcbiAqIEBjbGFzcyBFbWFpbFZhbGlkYXRvclxuICogQGV4dGVuZHMgUGF0dGVyblZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuRU1BSUwpXG5leHBvcnQgY2xhc3MgRW1haWxWYWxpZGF0b3IgZXh0ZW5kcyBQYXR0ZXJuVmFsaWRhdG9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5FTUFJTCkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIG1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1BhdHRlcm5WYWxpZGF0b3JPcHRpb25zfSBbb3B0aW9uc11cbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBzdHJpbmcsXG4gICAgb3B0aW9uczogUGF0dGVyblZhbGlkYXRvck9wdGlvbnMgPSB7fVxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBzdXBlci5oYXNFcnJvcnModmFsdWUsIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBwYXR0ZXJuOiBvcHRpb25zPy5wYXR0ZXJuIHx8IERFRkFVTFRfUEFUVEVSTlMuRU1BSUwsXG4gICAgfSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IExpc3RWYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgTGlzdCBWYWxpZGF0b3JcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0xJU1R9XG4gKlxuICogQGNsYXNzIExpc3RWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuTElTVClcbmV4cG9ydCBjbGFzcyBMaXN0VmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPExpc3RWYWxpZGF0b3JPcHRpb25zPiB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuTElTVCkge1xuICAgIHN1cGVyKG1lc3NhZ2UsIEFycmF5Lm5hbWUsIFNldC5uYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSBtb2RlbFxuICAgKlxuICAgKiBAcGFyYW0ge2FueVtdIHwgU2V0PGFueT59IHZhbHVlXG4gICAqIEBwYXJhbSB7TGlzdFZhbGlkYXRvck9wdGlvbnN9IG9wdGlvbnNcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IGFueVtdIHwgU2V0PGFueT4sXG4gICAgb3B0aW9uczogTGlzdFZhbGlkYXRvck9wdGlvbnNcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIXZhbHVlIHx8IChBcnJheS5pc0FycmF5KHZhbHVlKSA/ICF2YWx1ZS5sZW5ndGggOiAhdmFsdWUuc2l6ZSkpIHJldHVybjtcblxuICAgIGNvbnN0IGNsYXp6ID0gQXJyYXkuaXNBcnJheShvcHRpb25zLmNsYXp6KVxuICAgICAgPyBvcHRpb25zLmNsYXp6XG4gICAgICA6IFtvcHRpb25zLmNsYXp6XTtcbiAgICBsZXQgdmFsOiBhbnksXG4gICAgICBpc1ZhbGlkID0gdHJ1ZTtcbiAgICBmb3IgKFxuICAgICAgbGV0IGkgPSAwO1xuICAgICAgaSA8IChBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlLmxlbmd0aCA6IHZhbHVlLnNpemUpO1xuICAgICAgaSsrXG4gICAgKSB7XG4gICAgICB2YWwgPSAodmFsdWUgYXMgYW55KVtpXTtcbiAgICAgIHN3aXRjaCAodHlwZW9mIHZhbCkge1xuICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgIGNhc2UgXCJmdW5jdGlvblwiOlxuICAgICAgICAgIGlzVmFsaWQgPSBjbGF6ei5pbmNsdWRlcygodmFsIGFzIG9iamVjdCkuY29uc3RydWN0b3I/Lm5hbWUpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGlzVmFsaWQgPSBjbGF6ei5zb21lKChjOiBzdHJpbmcpID0+IHR5cGVvZiB2YWwgPT09IGMudG9Mb3dlckNhc2UoKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGlzVmFsaWRcbiAgICAgID8gdW5kZWZpbmVkXG4gICAgICA6IHRoaXMuZ2V0TWVzc2FnZShvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlLCBjbGF6eik7XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgVmFsaWRhdGlvbktleXMsIERFRkFVTFRfRVJST1JfTUVTU0FHRVMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IE1heExlbmd0aFZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBNYXhpbXVtIExlbmd0aCBWYWxpZGF0b3JcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0ZXMgc3RyaW5ncyBhbmQgQXJyYXlzIG9uIHRoZWlyIG1heGltdW0gbGVuZ3RoXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNNQVhfTEVOR1RIfVxuICpcbiAqIEBjbGFzcyBNaW5MZW5ndGhWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuTUFYX0xFTkdUSClcbmV4cG9ydCBjbGFzcyBNYXhMZW5ndGhWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3I8TWF4TGVuZ3RoVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLk1BWF9MRU5HVEgpIHtcbiAgICBzdXBlcihtZXNzYWdlLCBTdHJpbmcubmFtZSwgQXJyYXkubmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIGEgbW9kZWxcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gICAqIEBwYXJhbSB7TWF4TGVuZ3RoVmFsaWRhdG9yT3B0aW9uc30gb3B0aW9uc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9XG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IHN0cmluZyB8IGFueVtdLFxuICAgIG9wdGlvbnM6IE1heExlbmd0aFZhbGlkYXRvck9wdGlvbnNcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm47XG4gICAgcmV0dXJuIHZhbHVlLmxlbmd0aCA+IG9wdGlvbnMubWF4TGVuZ3RoXG4gICAgICA/IHRoaXMuZ2V0TWVzc2FnZShvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlLCBvcHRpb25zLm1heExlbmd0aClcbiAgICAgIDogdW5kZWZpbmVkO1xuICB9XG59XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tIFwiLi9WYWxpZGF0b3JcIjtcbmltcG9ydCB7IERFRkFVTFRfRVJST1JfTUVTU0FHRVMsIFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBNYXhWYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgTWF4IFZhbGlkYXRvclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjTUFYfVxuICpcbiAqIEBjbGFzcyBNYXhWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuTUFYKVxuZXhwb3J0IGNsYXNzIE1heFZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvcjxNYXhWYWxpZGF0b3JPcHRpb25zPiB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuTUFYKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgXCJudW1iZXJcIiwgXCJEYXRlXCIsIFwic3RyaW5nXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIE1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKiBAcGFyYW0ge01heFZhbGlkYXRvck9wdGlvbnN9IG9wdGlvbnNcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBudW1iZXIgfCBEYXRlIHwgc3RyaW5nLFxuICAgIG9wdGlvbnM6IE1heFZhbGlkYXRvck9wdGlvbnNcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm47XG5cbiAgICBsZXQgeyBtYXggfSA9IG9wdGlvbnM7XG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSAmJiAhKG1heCBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICBtYXggPSBuZXcgRGF0ZShtYXgpO1xuICAgICAgaWYgKE51bWJlci5pc05hTihtYXguZ2V0RGF0ZSgpKSlcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBNYXggcGFyYW0gZGVmaW5lZFwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWUgPiBtYXhcbiAgICAgID8gdGhpcy5nZXRNZXNzYWdlKG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsIG1heClcbiAgICAgIDogdW5kZWZpbmVkO1xuICB9XG59XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tIFwiLi9WYWxpZGF0b3JcIjtcbmltcG9ydCB7IERFRkFVTFRfRVJST1JfTUVTU0FHRVMsIFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBNaW5MZW5ndGhWYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgTWluaW11bSBMZW5ndGggVmFsaWRhdG9yXG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdGVzIHN0cmluZ3MgYW5kIEFycmF5cyBvbiB0aGVpciBtaW5pbXVtIGxlbmd0aFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjTUlOX0xFTkdUSH1cbiAqXG4gKiBAY2xhc3MgTWluTGVuZ3RoVmFsaWRhdG9yXG4gKiBAZXh0ZW5kcyBWYWxpZGF0b3JcbiAqXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5AdmFsaWRhdG9yKFZhbGlkYXRpb25LZXlzLk1JTl9MRU5HVEgpXG5leHBvcnQgY2xhc3MgTWluTGVuZ3RoVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPE1pbkxlbmd0aFZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5NSU5fTEVOR1RIKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgU3RyaW5nLm5hbWUsIEFycmF5Lm5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgQXJyYXl9IHZhbHVlXG4gICAqIEBwYXJhbSB7TWluTGVuZ3RoVmFsaWRhdG9yT3B0aW9uc30gb3B0aW9uc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9XG4gICAqXG4gICAqIEBtZW1iZXJPZiBNaW5MZW5ndGhWYWxpZGF0b3JcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogc3RyaW5nIHwgYW55W10sXG4gICAgb3B0aW9uczogTWluTGVuZ3RoVmFsaWRhdG9yT3B0aW9uc1xuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIpIHJldHVybjtcbiAgICByZXR1cm4gdmFsdWUubGVuZ3RoIDwgb3B0aW9ucy5taW5MZW5ndGhcbiAgICAgID8gdGhpcy5nZXRNZXNzYWdlKG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsIG9wdGlvbnMubWluTGVuZ3RoKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IE1pblZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBNaW4gVmFsaWRhdG9yXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNNSU59XG4gKlxuICogQGNsYXNzIE1pblZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5NSU4pXG5leHBvcnQgY2xhc3MgTWluVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPE1pblZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5NSU4pIHtcbiAgICBzdXBlcihtZXNzYWdlLCBcIm51bWJlclwiLCBcIkRhdGVcIiwgXCJzdHJpbmdcIik7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIE1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKiBAcGFyYW0ge01heFZhbGlkYXRvck9wdGlvbnN9IG9wdGlvbnNcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBudW1iZXIgfCBEYXRlIHwgc3RyaW5nLFxuICAgIG9wdGlvbnM6IE1pblZhbGlkYXRvck9wdGlvbnNcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm47XG5cbiAgICBsZXQgeyBtaW4gfSA9IG9wdGlvbnM7XG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSAmJiAhKG1pbiBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICBtaW4gPSBuZXcgRGF0ZShtaW4pO1xuICAgICAgaWYgKE51bWJlci5pc05hTihtaW4uZ2V0RGF0ZSgpKSlcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBNaW4gcGFyYW0gZGVmaW5lZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlIDwgbWluXG4gICAgICA/IHRoaXMuZ2V0TWVzc2FnZShvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlLCBtaW4pXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiaW1wb3J0IHsgUGF0dGVyblZhbGlkYXRvciB9IGZyb20gXCIuL1BhdHRlcm5WYWxpZGF0b3JcIjtcbmltcG9ydCB7IERFRkFVTFRfRVJST1JfTUVTU0FHRVMsIFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBQYXR0ZXJuVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IEhhbmRsZXMgUGFzc3dvcmQgVmFsaWRhdGlvblxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbZXJyb3JNZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNQQVNTV09SRH1cbiAqXG4gKiBAY2xhc3MgUGFzc3dvcmRWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFBhdHRlcm5WYWxpZGF0b3JcbiAqXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5AdmFsaWRhdG9yKFZhbGlkYXRpb25LZXlzLlBBU1NXT1JEKVxuZXhwb3J0IGNsYXNzIFBhc3N3b3JkVmFsaWRhdG9yIGV4dGVuZHMgUGF0dGVyblZhbGlkYXRvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlBBU1NXT1JEKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIGEgbW9kZWxcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gICAqIEBwYXJhbSB7UGF0dGVyblZhbGlkYXRvck9wdGlvbnN9IFtvcHRpb25zPXt9XVxuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9XG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFBhdHRlcm5WYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBzdHJpbmcsXG4gICAgb3B0aW9uczogUGF0dGVyblZhbGlkYXRvck9wdGlvbnMgPSB7fVxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBzdXBlci5oYXNFcnJvcnModmFsdWUsIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBtZXNzYWdlOiBvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlLFxuICAgIH0pO1xuICB9XG59XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tIFwiLi9WYWxpZGF0b3JcIjtcbmltcG9ydCB7IERFRkFVTFRfRVJST1JfTUVTU0FHRVMsIFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBWYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgUmVxdWlyZWQgVmFsaWRhdG9yXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNSRVFVSVJFRH1cbiAqXG4gKiBAY2xhc3MgUmVxdWlyZWRWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuUkVRVUlSRUQpXG5leHBvcnQgY2xhc3MgUmVxdWlyZWRWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlJFUVVJUkVEKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIGEgbW9kZWxcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gICAqIEBwYXJhbSB7VmFsaWRhdG9yT3B0aW9uc30gW29wdGlvbnM9e31dXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogYW55LFxuICAgIG9wdGlvbnM6IFZhbGlkYXRvck9wdGlvbnMgPSB7fVxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHN3aXRjaCAodHlwZW9mIHZhbHVlKSB7XG4gICAgICBjYXNlIFwiYm9vbGVhblwiOlxuICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiXG4gICAgICAgICAgPyB0aGlzLmdldE1lc3NhZ2Uob3B0aW9ucy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSlcbiAgICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAhdmFsdWVcbiAgICAgICAgICA/IHRoaXMuZ2V0TWVzc2FnZShvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlKVxuICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgU3RlcFZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBTdGVwIFZhbGlkYXRvclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjU1RFUH1cbiAqXG4gKiBAY2xhc3MgU3RlcFZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5TVEVQKVxuZXhwb3J0IGNsYXNzIFN0ZXBWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3I8U3RlcFZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5TVEVQKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgXCJudW1iZXJcIiwgXCJzdHJpbmdcIik7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIGEgbW9kZWxcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdGVwXG4gICAqIEBwYXJhbSB7U3RlcFZhbGlkYXRvck9wdGlvbnN9IG9wdGlvbnNcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBudW1iZXIgfCBzdHJpbmcsXG4gICAgb3B0aW9uczogU3RlcFZhbGlkYXRvck9wdGlvbnNcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm47XG4gICAgcmV0dXJuIE51bWJlcih2YWx1ZSkgJSBOdW1iZXIob3B0aW9ucy5zdGVwKSAhPT0gMFxuICAgICAgPyB0aGlzLmdldE1lc3NhZ2Uob3B0aW9ucy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSwgb3B0aW9ucy5zdGVwKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IFZhbGlkYXRpb24gfSBmcm9tIFwiLi4vVmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgVHlwZVZhbGlkYXRvck9wdGlvbnMsIFZhbGlkYXRvckRlZmluaXRpb24gfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IE1vZGVsS2V5cyB9IGZyb20gXCIuLi8uLi91dGlscy9jb25zdGFudHNcIjtcbmltcG9ydCB7IFJlZmxlY3Rpb24gfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBSZXF1aXJlZCBWYWxpZGF0b3JcbiAqXG4gKiBAY2xhc3MgUmVxdWlyZWRWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuVFlQRSlcbmV4cG9ydCBjbGFzcyBUeXBlVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPFR5cGVWYWxpZGF0b3JPcHRpb25zPiB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuVFlQRSkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIG1vZGVsXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1R5cGVWYWxpZGF0b3JPcHRpb25zfSBvcHRpb25zXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogYW55LFxuICAgIG9wdGlvbnM6IFR5cGVWYWxpZGF0b3JPcHRpb25zXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybjsgLy8gRG9uJ3QgdHJ5IGFuZCBlbmZvcmNlIHR5cGUgaWYgdW5kZWZpbmVkXG4gICAgY29uc3QgeyB0eXBlcywgbWVzc2FnZSB9ID0gb3B0aW9ucztcbiAgICBpZiAoIVJlZmxlY3Rpb24uZXZhbHVhdGVEZXNpZ25UeXBlcyh2YWx1ZSwgdHlwZXMpKVxuICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZShcbiAgICAgICAgbWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsXG4gICAgICAgIHR5cGVvZiB0eXBlcyA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgID8gdHlwZXNcbiAgICAgICAgICA6IEFycmF5LmlzQXJyYXkodHlwZXMpXG4gICAgICAgICAgICA/IHR5cGVzLmpvaW4oXCIsIFwiKVxuICAgICAgICAgICAgOiB0eXBlcy5uYW1lLFxuICAgICAgICB0eXBlb2YgdmFsdWVcbiAgICAgICk7XG4gIH1cbn1cblxuVmFsaWRhdGlvbi5yZWdpc3Rlcih7XG4gIHZhbGlkYXRvcjogVHlwZVZhbGlkYXRvcixcbiAgdmFsaWRhdGlvbktleTogTW9kZWxLZXlzLlRZUEUsXG4gIHNhdmU6IGZhbHNlLFxufSBhcyBWYWxpZGF0b3JEZWZpbml0aW9uKTtcbiIsImltcG9ydCB7XG4gIFZhbGlkYXRpb25LZXlzLFxuICBERUZBVUxUX0VSUk9SX01FU1NBR0VTLFxuICBERUZBVUxUX1BBVFRFUk5TLFxufSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFBhdHRlcm5WYWxpZGF0b3IgfSBmcm9tIFwiLi9QYXR0ZXJuVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBQYXR0ZXJuVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFVSTCBWYWxpZGF0b3JcbiAqIEBkZXNjcmlwdGlvbiBQYXR0ZXJuIGZyb20ge0BsaW5rIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL2RwZXJpbmkvNzI5Mjk0fVxuICpcbiAqIEBjbGFzcyBVUkxWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFBhdHRlcm5WYWxpZGF0b3JcbiAqXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5AdmFsaWRhdG9yKFZhbGlkYXRpb25LZXlzLlVSTClcbmV4cG9ydCBjbGFzcyBVUkxWYWxpZGF0b3IgZXh0ZW5kcyBQYXR0ZXJuVmFsaWRhdG9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5VUkwpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSBtb2RlbFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtQYXR0ZXJuVmFsaWRhdG9yT3B0aW9uc30gW29wdGlvbnM9e31dXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogc3RyaW5nLFxuICAgIG9wdGlvbnM6IFBhdHRlcm5WYWxpZGF0b3JPcHRpb25zID0ge31cbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gc3VwZXIuaGFzRXJyb3JzKHZhbHVlLCB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgcGF0dGVybjogb3B0aW9ucy5wYXR0ZXJuIHx8IERFRkFVTFRfUEFUVEVSTlMuVVJMLFxuICAgIH0pO1xuICB9XG59XG4iLCJpbXBvcnQgXCJyZWZsZWN0LW1ldGFkYXRhXCI7XG5pbXBvcnQgeyBWYWxpZGF0aW9uTWV0YWRhdGEgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyxcbiAgREVGQVVMVF9QQVRURVJOUyxcbiAgVmFsaWRhdGlvbktleXMsXG59IGZyb20gXCIuL1ZhbGlkYXRvcnMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBzZiB9IGZyb20gXCIuLi91dGlscy9zdHJpbmdzXCI7XG5pbXBvcnQgeyBNb2RlbENvbnN0cnVjdG9yIH0gZnJvbSBcIi4uL21vZGVsL3R5cGVzXCI7XG5pbXBvcnQgeyBwYXJzZURhdGUgfSBmcm9tIFwiLi4vdXRpbHMvZGF0ZXNcIjtcbmltcG9ydCB7IHByb3BNZXRhZGF0YSB9IGZyb20gXCIuLi91dGlscy9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBWYWxpZGF0aW9uIH0gZnJvbSBcIi4vVmFsaWRhdGlvblwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IE1hcmtzIHRoZSBwcm9wZXJ0eSBhcyByZXF1aXJlZC5cbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3JzIHRvIHZhbGlkYXRlIGEgZGVjb3JhdGVkIHByb3BlcnR5IG11c3QgdXNlIGtleSB7QGxpbmsgVmFsaWRhdGlvbktleXMjUkVRVUlSRUR9XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjUkVRVUlSRUR9XG4gKlxuICogQGZ1bmN0aW9uIHJlcXVpcmVkXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVkKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuUkVRVUlSRUQpIHtcbiAgcmV0dXJuIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KFxuICAgIFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLlJFUVVJUkVEKSxcbiAgICB7XG4gICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgbWluaW11bSB2YWx1ZSBmb3IgdGhlIHByb3BlcnR5XG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdG9ycyB0byB2YWxpZGF0ZSBhIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IHVzZSBrZXkge0BsaW5rIFZhbGlkYXRpb25LZXlzI01JTn1cbiAqXG4gKiBAcGFyYW0ge251bWJlciB8IERhdGV9IHZhbHVlXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIHRoZSBlcnJvciBtZXNzYWdlLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNNSU59XG4gKlxuICogQGZ1bmN0aW9uIG1pblxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5EZWNvcmF0b3JzLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtaW4oXG4gIHZhbHVlOiBudW1iZXIgfCBEYXRlIHwgc3RyaW5nLFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLk1JTlxuKSB7XG4gIHJldHVybiBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5NSU4pLCB7XG4gICAgbWluOiB2YWx1ZSxcbiAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgIHR5cGVzOiBbTnVtYmVyLm5hbWUsIERhdGUubmFtZV0sXG4gIH0pO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBtYXhpbXVtIHZhbHVlIGZvciB0aGUgcHJvcGVydHlcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3JzIHRvIHZhbGlkYXRlIGEgZGVjb3JhdGVkIHByb3BlcnR5IG11c3QgdXNlIGtleSB7QGxpbmsgVmFsaWRhdGlvbktleXMjTUFYfVxuICpcbiAqIEBwYXJhbSB7bnVtYmVyIHwgRGF0ZX0gdmFsdWVcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gdGhlIGVycm9yIG1lc3NhZ2UuIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI01BWH1cbiAqXG4gKiBAZnVuY3Rpb24gbWF4XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLkRlY29yYXRvcnMuVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1heChcbiAgdmFsdWU6IG51bWJlciB8IERhdGUgfCBzdHJpbmcsXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuTUFYXG4pIHtcbiAgcmV0dXJuIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLk1BWCksIHtcbiAgICBtYXg6IHZhbHVlLFxuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgdHlwZXM6IFtOdW1iZXIubmFtZSwgRGF0ZS5uYW1lXSxcbiAgfSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIHN0ZXAgdmFsdWUgZm9yIHRoZSBwcm9wZXJ0eVxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNTVEVQfVxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjU1RFUH1cbiAqXG4gKiBAZnVuY3Rpb24gc3RlcFxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5EZWNvcmF0b3JzLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGVwKFxuICB2YWx1ZTogbnVtYmVyLFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlNURVBcbikge1xuICByZXR1cm4gcHJvcE1ldGFkYXRhPFZhbGlkYXRpb25NZXRhZGF0YT4oVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuU1RFUCksIHtcbiAgICBzdGVwOiB2YWx1ZSxcbiAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgIHR5cGVzOiBbTnVtYmVyLm5hbWVdLFxuICB9KTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgbWluaW11bSBsZW5ndGggZm9yIHRoZSBwcm9wZXJ0eVxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNNSU5fTEVOR1RIfVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjTUlOX0xFTkdUSH1cbiAqXG4gKiBAZnVuY3Rpb24gbWlubGVuZ3RoXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLkRlY29yYXRvcnMuVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1pbmxlbmd0aChcbiAgdmFsdWU6IG51bWJlcixcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5NSU5fTEVOR1RIXG4pIHtcbiAgcmV0dXJuIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KFxuICAgIFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLk1JTl9MRU5HVEgpLFxuICAgIHtcbiAgICAgIG1pbkxlbmd0aDogdmFsdWUsXG4gICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgdHlwZXM6IFtTdHJpbmcubmFtZSwgQXJyYXkubmFtZSwgU2V0Lm5hbWVdLFxuICAgIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgbWF4aW11bSBsZW5ndGggZm9yIHRoZSBwcm9wZXJ0eVxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNNQVhfTEVOR1RIfVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjTUFYX0xFTkdUSH1cbiAqXG4gKiBAZnVuY3Rpb24gbWF4bGVuZ3RoXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLkRlY29yYXRvcnMuVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1heGxlbmd0aChcbiAgdmFsdWU6IG51bWJlcixcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5NQVhfTEVOR1RIXG4pIHtcbiAgcmV0dXJuIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KFxuICAgIFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLk1BWF9MRU5HVEgpLFxuICAgIHtcbiAgICAgIG1heExlbmd0aDogdmFsdWUsXG4gICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgdHlwZXM6IFtTdHJpbmcubmFtZSwgQXJyYXkubmFtZSwgU2V0Lm5hbWVdLFxuICAgIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgUmVnRXhwIHBhdHRlcm4gdGhlIHByb3BlcnR5IG11c3QgcmVzcGVjdFxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNQQVRURVJOfVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjUEFUVEVSTn1cbiAqXG4gKiBAZnVuY3Rpb24gcGF0dGVyblxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5EZWNvcmF0b3JzLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXR0ZXJuKFxuICB2YWx1ZTogUmVnRXhwIHwgc3RyaW5nLFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlBBVFRFUk5cbikge1xuICByZXR1cm4gcHJvcE1ldGFkYXRhPFZhbGlkYXRpb25NZXRhZGF0YT4oXG4gICAgVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuUEFUVEVSTiksXG4gICAge1xuICAgICAgcGF0dGVybjogdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiID8gdmFsdWUgOiB2YWx1ZS50b1N0cmluZygpLFxuICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgIHR5cGVzOiBbU3RyaW5nLm5hbWVdLFxuICAgIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBwcm9wZXJ0eSBhcyBhbiBlbWFpbFxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNFTUFJTH1cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIHRoZSBlcnJvciBtZXNzYWdlLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNFTUFJTH1cbiAqXG4gKiBAZnVuY3Rpb24gZW1haWxcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uRGVjb3JhdG9ycy5WYWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZW1haWwobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5FTUFJTCkge1xuICByZXR1cm4gcHJvcE1ldGFkYXRhPFZhbGlkYXRpb25NZXRhZGF0YT4oXG4gICAgVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuRU1BSUwpLFxuICAgIHtcbiAgICAgIHBhdHRlcm46IERFRkFVTFRfUEFUVEVSTlMuRU1BSUwsXG4gICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgdHlwZXM6IFtTdHJpbmcubmFtZV0sXG4gICAgfVxuICApO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIHByb3BlcnR5IGFzIGFuIFVSTFxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNVUkx9XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjVVJMfVxuICpcbiAqIEBmdW5jdGlvbiB1cmxcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uRGVjb3JhdG9ycy5WYWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdXJsKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuVVJMKSB7XG4gIHJldHVybiBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5VUkwpLCB7XG4gICAgcGF0dGVybjogREVGQVVMVF9QQVRURVJOUy5VUkwsXG4gICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICB0eXBlczogW1N0cmluZy5uYW1lXSxcbiAgfSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRW5mb3JjZXMgdHlwZSB2ZXJpZmljYXRpb25cbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3JzIHRvIHZhbGlkYXRlIGEgZGVjb3JhdGVkIHByb3BlcnR5IG11c3QgdXNlIGtleSB7QGxpbmsgVmFsaWRhdGlvbktleXMjVFlQRX1cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ1tdIHwgc3RyaW5nfSB0eXBlcyBhY2NlcHRlZCB0eXBlc1xuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjVFlQRX1cbiAqXG4gKiBAZnVuY3Rpb24gdHlwZVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5EZWNvcmF0b3JzLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0eXBlKFxuICB0eXBlczogc3RyaW5nW10gfCBzdHJpbmcsXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuVFlQRVxuKSB7XG4gIHJldHVybiBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5UWVBFKSwge1xuICAgIGN1c3RvbVR5cGVzOiB0eXBlcyxcbiAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICB9KTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEYXRlIEhhbmRsZXIgRGVjb3JhdG9yXG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdG9ycyB0byB2YWxpZGF0ZSBhIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IHVzZSBrZXkge0BsaW5rIFZhbGlkYXRpb25LZXlzI0RBVEV9XG4gKlxuICogV2lsbCBlbmZvcmNlIHNlcmlhbGl6YXRpb24gYWNjb3JkaW5nIHRvIHRoZSBzZWxlY3RlZCBmb3JtYXRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZm9ybWF0IGFjY2VwdGVkIGZvcm1hdCBhY2NvcmRpbmcgdG8ge0BsaW5rIGZvcm1hdERhdGV9XG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIHRoZSBlcnJvciBtZXNzYWdlLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNEQVRFfVxuICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxWYWxpZGF0b3I+fSBbdmFsaWRhdG9yXSB0aGUgVmFsaWRhdG9yIHRvIGJlIHVzZWQuIERlZmF1bHRzIHRvIHtAbGluayBEYXRlVmFsaWRhdG9yfVxuICpcbiAqIEBmdW5jdGlvbiBkYXRlXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5EZWNvcmF0b3JzLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkYXRlKFxuICBmb3JtYXQ6IHN0cmluZyA9IFwiZGQvTU0veXl5eVwiLFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkRBVEVcbikge1xuICByZXR1cm4gKHRhcmdldDogUmVjb3JkPHN0cmluZywgYW55PiwgcHJvcGVydHlLZXk/OiBhbnkpOiBhbnkgPT4ge1xuICAgIHByb3BNZXRhZGF0YShWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5EQVRFKSwge1xuICAgICAgZm9ybWF0OiBmb3JtYXQsXG4gICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgdHlwZXM6IFtEYXRlLm5hbWVdLFxuICAgIH0pKHRhcmdldCwgcHJvcGVydHlLZXkpO1xuXG4gICAgY29uc3QgdmFsdWVzID0gbmV3IFdlYWtNYXAoKTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5S2V5LCB7XG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgc2V0KHRoaXM6IGFueSwgbmV3VmFsdWU6IHN0cmluZyB8IERhdGUpIHtcbiAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGhpcywgcHJvcGVydHlLZXkpO1xuICAgICAgICBpZiAoIWRlc2NyaXB0b3IgfHwgZGVzY3JpcHRvci5jb25maWd1cmFibGUpXG4gICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIHByb3BlcnR5S2V5LCB7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGdldDogKCkgPT4gdmFsdWVzLmdldCh0aGlzKSxcbiAgICAgICAgICAgIHNldDogKG5ld1ZhbHVlOiBzdHJpbmcgfCBEYXRlIHwgbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICAgIGxldCB2YWw6IERhdGUgfCB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdmFsID0gcGFyc2VEYXRlKGZvcm1hdCwgbmV3VmFsdWUpO1xuICAgICAgICAgICAgICAgIHZhbHVlcy5zZXQodGhpcywgdmFsKTtcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihzZihcIkZhaWxlZCB0byBwYXJzZSBkYXRlOiB7MH1cIiwgZS5tZXNzYWdlIHx8IGUpKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgdGhpc1twcm9wZXJ0eUtleV0gPSBuZXdWYWx1ZTtcbiAgICAgIH0sXG4gICAgICBnZXQoKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiaGVyZVwiKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH07XG59XG5cbi8qKlxuICogQHN1bW1hcnkgUGFzc3dvcmQgSGFuZGxlciBEZWNvcmF0b3JcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3JzIHRvIHZhbGlkYXRlIGEgZGVjb3JhdGVkIHByb3BlcnR5IG11c3QgdXNlIGtleSB7QGxpbmsgVmFsaWRhdGlvbktleXMjUEFTU1dPUkR9XG4gKlxuICogQHBhcmFtIHtSZWdFeHB9IFtwYXR0ZXJuXSBkZWZhdWx0cyB0byB7QGxpbmsgUGFzc3dvcmRQYXR0ZXJucyNDSEFSOF9PTkVfT0ZfRUFDSH1cbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gdGhlIGVycm9yIG1lc3NhZ2UuIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1BBU1NXT1JEfVxuICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxWYWxpZGF0b3I+fSBbdmFsaWRhdG9yXSBEZWZhdWx0cyB0byB7QGxpbmsgUGFzc3dvcmRWYWxpZGF0b3J9XG4gKlxuICogQGZ1bmN0aW9uIHBhc3N3b3JkXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5EZWNvcmF0b3JzLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXNzd29yZChcbiAgcGF0dGVybjogUmVnRXhwID0gREVGQVVMVF9QQVRURVJOUy5QQVNTV09SRC5DSEFSOF9PTkVfT0ZfRUFDSCxcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5QQVNTV09SRFxuKSB7XG4gIHJldHVybiBwcm9wTWV0YWRhdGEoVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuUEFTU1dPUkQpLCB7XG4gICAgcGF0dGVybjogcGF0dGVybixcbiAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgIHR5cGVzOiBbU3RyaW5nLm5hbWVdLFxuICB9KTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBMaXN0IERlY29yYXRvclxuICogQGRlc2NyaXB0aW9uIEFsc28gc2V0cyB0aGUge0BsaW5rIHR5cGV9IHRvIHRoZSBwcm92aWRlZCBjb2xsZWN0aW9uXG4gKlxuICogQHBhcmFtIHtNb2RlbENvbnN0cnVjdG9yfSBjbGF6elxuICogQHBhcmFtIHtzdHJpbmd9IFtjb2xsZWN0aW9uXSBUaGUgY29sbGVjdGlvbiBiZWluZyB1c2VkLiBkZWZhdWx0cyB0byBBcnJheVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNMSVNUfVxuICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxWYWxpZGF0b3I+fSBbdmFsaWRhdG9yXSBkZWZhdWx0cyB0byB7QGxpbmsgTGlzdFZhbGlkYXRvcn1cbiAqXG4gKiBAZnVuY3Rpb24gbGlzdFxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uRGVjb3JhdG9ycy5WYWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbGlzdChcbiAgY2xheno6IE1vZGVsQ29uc3RydWN0b3I8YW55PiB8IE1vZGVsQ29uc3RydWN0b3I8YW55PltdLFxuICBjb2xsZWN0aW9uOiBcIkFycmF5XCIgfCBcIlNldFwiID0gXCJBcnJheVwiLFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkxJU1Rcbikge1xuICByZXR1cm4gcHJvcE1ldGFkYXRhKFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLkxJU1QpLCB7XG4gICAgY2xheno6IEFycmF5LmlzQXJyYXkoY2xhenopID8gY2xhenoubWFwKChjKSA9PiBjLm5hbWUpIDogW2NsYXp6Lm5hbWVdLFxuICAgIHR5cGU6IGNvbGxlY3Rpb24sXG4gICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgfSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgU2V0IERlY29yYXRvclxuICogQGRlc2NyaXB0aW9uIFdyYXBwZXIgZm9yIHtAbGluayBsaXN0fSB3aXRoIHRoZSAnU2V0JyBDb2xsZWN0aW9uXG4gKlxuICogQHBhcmFtIHtNb2RlbENvbnN0cnVjdG9yfSBjbGF6elxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNMSVNUfVxuICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxWYWxpZGF0b3I+fSBbdmFsaWRhdG9yXVxuICpcbiAqIEBmdW5jdGlvbiBzZXRcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLkRlY29yYXRvcnMuVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldChcbiAgY2xheno6IE1vZGVsQ29uc3RydWN0b3I8YW55PixcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5MSVNUXG4pIHtcbiAgcmV0dXJuIGxpc3QoY2xhenosIFwiU2V0XCIsIG1lc3NhZ2UpO1xufVxuIiwiaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiLi9Nb2RlbFwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IEhlbHBlciBGdW5jdGlvbiB0byBvdmVycmlkZSBjb25zdHJ1Y3RvcnNcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHthbnlbXX0gW2FyZ3NdXG4gKiBAcmV0dXJuIHtUfSB0aGUgbmV3IGluc3RhbmNlXG4gKlxuICogQGZ1bmN0aW9uIGNvbnN0cnVjdFxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5Db25zdHJ1Y3Rpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbnN0cnVjdDxUIGV4dGVuZHMgTW9kZWw+KFxuICBjb25zdHJ1Y3RvcjogYW55LFxuICAuLi5hcmdzOiBhbnlbXVxuKTogVCB7XG4gIGNvbnN0IF9jb25zdHIgPSAoLi4uYXJnejogYW55W10pID0+IG5ldyBjb25zdHJ1Y3RvciguLi5hcmd6KTtcbiAgX2NvbnN0ci5wcm90b3R5cGUgPSBjb25zdHJ1Y3Rvci5wcm90b3R5cGU7XG4gIHJldHVybiBfY29uc3RyKC4uLmFyZ3MpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFJlY3Vyc2l2ZWx5IGZpbmRzIHRoZSBsYXN0IHByb3RvdHlwZSBiZWZvcmUgT2JqZWN0XG4gKiBAcGFyYW0ge29iamVjdH0gb2JqXG4gKlxuICogQGZ1bmN0aW9uIGZpbmRMYXN0UHJvdG9CZWZvcmVPYmplY3RcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uQ29uc3RydWN0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kTGFzdFByb3RvQmVmb3JlT2JqZWN0KG9iajogb2JqZWN0KTogb2JqZWN0IHtcbiAgbGV0IHByb3RvdHlwZTogYW55ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iaik7XG4gIGlmIChwcm90b3R5cGUgPT09IE9iamVjdC5wcm90b3R5cGUpIHJldHVybiBvYmo7XG4gIHdoaWxlIChwcm90b3R5cGUgIT09IE9iamVjdC5wcm90b3R5cGUpIHtcbiAgICBwcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG90eXBlKTtcbiAgICBpZiAocHJvdG90eXBlID09PSBPYmplY3QucHJvdG90eXBlKSByZXR1cm4gcHJvdG90eXBlO1xuICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG90eXBlKSA9PT0gT2JqZWN0LnByb3RvdHlwZSkgcmV0dXJuIHByb3RvdHlwZTtcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZCBub3QgZmluZCBwcm9wZXIgcHJvdG90eXBlXCIpO1xufVxuXG4vKipcbiAqIEBzdW1hcnkgYmluZHMgdGhlIHtAbGluayBNb2RlbH0gY2xhc3MgYXMgYSByb290IHByb3RvdHlwZSBvZiB0aGUgcHJvdmlkZWQgaW5zdGFuY2VcbiAqXG4gKiBAcGFyYW0ge3Vua25vd259IG9ialxuICpcbiAqIEBmdW5jdGlvbiBiaW5kTW9kZWxQcm90b3R5cGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uQ29uc3RydWN0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiaW5kTW9kZWxQcm90b3R5cGUob2JqOiB1bmtub3duKSB7XG4gIGlmIChvYmogaW5zdGFuY2VvZiBNb2RlbCkgcmV0dXJuO1xuXG4gIGZ1bmN0aW9uIGJpbmRQcm90b3R5cGUob2JqVG9PdmVycmlkZTogdW5rbm93biwgcHJvdG90eXBlOiBvYmplY3QpIHtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2Yob2JqVG9PdmVycmlkZSwgcHJvdG90eXBlKTtcbiAgfVxuXG4gIGNvbnN0IHByb3RvdHlwZTogYW55ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iaik7XG4gIGlmIChwcm90b3R5cGUgPT09IE9iamVjdC5wcm90b3R5cGUpIHtcbiAgICByZXR1cm4gYmluZFByb3RvdHlwZShvYmosIE1vZGVsLnByb3RvdHlwZSk7XG4gIH1cbiAgd2hpbGUgKHByb3RvdHlwZSAhPT0gT2JqZWN0LnByb3RvdHlwZSkge1xuICAgIGNvbnN0IHByb3QgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG90eXBlKTtcbiAgICBpZiAoXG4gICAgICBwcm90ID09PSBPYmplY3QucHJvdG90eXBlIHx8XG4gICAgICBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdCkgPT09IE9iamVjdC5wcm90b3R5cGVcbiAgICApIHtcbiAgICAgIHJldHVybiBiaW5kUHJvdG90eXBlKHByb3RvdHlwZSwgTW9kZWwucHJvdG90eXBlKTtcbiAgICB9XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKFwiQ291bGQgbm90IGZpbmQgcHJvcGVyIHByb3RvdHlwZSB0byBiaW5kXCIpO1xufVxuIiwiaW1wb3J0IHsgYmluZE1vZGVsUHJvdG90eXBlLCBjb25zdHJ1Y3QgfSBmcm9tIFwiLi9jb25zdHJ1Y3Rpb25cIjtcbmltcG9ydCB7IE1vZGVsS2V5cyB9IGZyb20gXCIuLi91dGlscy9jb25zdGFudHNcIjtcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIi4vTW9kZWxcIjtcbmltcG9ydCB7IG1ldGFkYXRhIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgZGVmaW5lcyB0aGUgdHBlIG9zIGFuIEluc3RhbmNlQ2FsbGJhY2sgZnVuY3Rpb25cbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLk1vZGVsXG4gKi9cbmV4cG9ydCB0eXBlIEluc3RhbmNlQ2FsbGJhY2sgPSAoaW5zdGFuY2U6IGFueSwgLi4uYXJnczogYW55W10pID0+IHZvaWQ7XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGNsYXNzIGFzIGEgTW9kZWwgY2xhc3NcbiAqIEBkZXNjcmlwdGlvblxuICpcbiAqIC0gUmVnaXN0ZXJzIHRoZSBjbGFzcyB1bmRlciB0aGUgbW9kZWwgcmVnaXN0cnkgc28gaXQgY2FuIGJlIGVhc2lseSByZWJ1aWx0O1xuICogLSBPdmVycmlkZXMgdGhlIGNsYXNzIGNvbnN0cnVjdG9yO1xuICogLSBSdW5zIHRoZSBnbG9iYWwge0BsaW5rIE1vZGVsQnVpbGRlckZ1bmN0aW9ufSBpZiBkZWZpbmVkO1xuICogLSBSdW5zIHRoZSBvcHRpb25hbCB7QGxpbmsgSW5zdGFuY2VDYWxsYmFja30gaWYgcHJvdmlkZWQ7XG4gKlxuICogQHBhcmFtIHtJbnN0YW5jZUNhbGxiYWNrfSBbaW5zdGFuY2VDYWxsYmFja10gb3B0aW9uYWwgY2FsbGJhY2sgdGhhdCB3aWxsIGJlIGNhbGxlZCB3aXRoIHRoZSBpbnN0YW5jZSB1cG9uIGluc3RhbnRpYXRpb24uIGRlZmF1bHRzIHRvIHVuZGVmaW5lZFxuICpcbiAqIEBmdW5jdGlvbiBtb2RlbFxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uTW9kZWxcbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb2RlbChpbnN0YW5jZUNhbGxiYWNrPzogSW5zdGFuY2VDYWxsYmFjaykge1xuICByZXR1cm4gKChvcmlnaW5hbDogYW55KSA9PiB7XG4gICAgLy8gdGhlIG5ldyBjb25zdHJ1Y3RvciBiZWhhdmlvdXJcbiAgICBjb25zdCBuZXdDb25zdHJ1Y3RvcjogYW55ID0gZnVuY3Rpb24gKC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgICBjb25zdCBpbnN0YW5jZTogUmV0dXJuVHlwZTx0eXBlb2Ygb3JpZ2luYWw+ID0gY29uc3RydWN0KFxuICAgICAgICBvcmlnaW5hbCxcbiAgICAgICAgLi4uYXJnc1xuICAgICAgKTtcbiAgICAgIGJpbmRNb2RlbFByb3RvdHlwZShpbnN0YW5jZSk7XG4gICAgICAvLyBydW4gYSBidWlsZGVyIGZ1bmN0aW9uIGlmIGRlZmluZWQgd2l0aCB0aGUgZmlyc3QgYXJndW1lbnQgKFRoZSBNb2RlbEFyZylcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBNb2RlbC5nZXRCdWlsZGVyKCk7XG4gICAgICBpZiAoYnVpbGRlcikgYnVpbGRlcihpbnN0YW5jZSwgYXJncy5sZW5ndGggPyBhcmdzWzBdIDogdW5kZWZpbmVkKTtcblxuICAgICAgbWV0YWRhdGEoTW9kZWwua2V5KE1vZGVsS2V5cy5NT0RFTCksIG9yaWdpbmFsLm5hbWUpKGluc3RhbmNlLmNvbnN0cnVjdG9yKTtcblxuICAgICAgaWYgKGluc3RhbmNlQ2FsbGJhY2spIGluc3RhbmNlQ2FsbGJhY2soaW5zdGFuY2UsIC4uLmFyZ3MpO1xuXG4gICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgfTtcblxuICAgIC8vIGNvcHkgcHJvdG90eXBlIHNvIGluc3RhbmNlb2Ygb3BlcmF0b3Igc3RpbGwgd29ya3NcbiAgICBuZXdDb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSBvcmlnaW5hbC5wcm90b3R5cGU7XG4gICAgLy8gU2V0cyB0aGUgcHJvcGVyIGNvbnN0cnVjdG9yIG5hbWUgZm9yIHR5cGUgdmVyaWZpY2F0aW9uXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5ld0NvbnN0cnVjdG9yLCBcIm5hbWVcIiwge1xuICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICB2YWx1ZTogb3JpZ2luYWwucHJvdG90eXBlLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgfSk7XG5cbiAgICBtZXRhZGF0YShNb2RlbC5rZXkoTW9kZWxLZXlzLk1PREVMKSwgb3JpZ2luYWwubmFtZSkob3JpZ2luYWwpO1xuXG4gICAgTW9kZWwucmVnaXN0ZXIobmV3Q29uc3RydWN0b3IsIG9yaWdpbmFsLm5hbWUpO1xuXG4gICAgLy8gcmV0dXJuIG5ldyBjb25zdHJ1Y3RvciAod2lsbCBvdmVycmlkZSBvcmlnaW5hbClcbiAgICByZXR1cm4gbmV3Q29uc3RydWN0b3I7XG4gIH0pIGFzIGFueTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc2hlZEJ5KGFsZ29yaXRobTogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkge1xuICByZXR1cm4gbWV0YWRhdGEoTW9kZWwua2V5KE1vZGVsS2V5cy5IQVNISU5HKSwge1xuICAgIGFsZ29yaXRobTogYWxnb3JpdGhtLFxuICAgIGFyZ3M6IGFyZ3MsXG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2VyaWFsaXplZEJ5KHNlcmlhbGl6ZXI6IHN0cmluZywgLi4uYXJnczogYW55W10pIHtcbiAgcmV0dXJuIG1ldGFkYXRhKE1vZGVsLmtleShNb2RlbEtleXMuU0VSSUFMSVpBVElPTiksIHtcbiAgICBzZXJpYWxpemVyOiBzZXJpYWxpemVyLFxuICAgIGFyZ3M6IGFyZ3MsXG4gIH0pO1xufVxuIiwiLyoqXG4gKiBAbW9kdWxlIGRlY29yYXRvci12YWxpZGF0aW9uXG4gKi9cblxuLyoqXG4gKiBAc3VtbWFyeSBNb2RlbCBkZWZpbml0aW9uIGZ1bmN0aW9uYWxpdHlcbiAqIEBkZXNjcmlwdGlvbiBkZWZpbmVzIHRoZSBiYXNlIGNsYXNzIGFuZCByZWxhdGVkIGZ1bmN0aW9uYWxpdHlcbiAqXG4gKiBAbmFtZXNwYWNlIE1vZGVsXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uXG4gKi9cblxuLyoqXG4gKiBAc3VtbWFyeSBIb2xkcyBhbGwgdGhlIHN1cHBvcnRlZCBkZWNvcmF0b3JzXG4gKiBAbmFtZXNwYWNlIERlY29yYXRvcnNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqL1xuXG4vKipcbiAqIEBzdW1tYXJ5IFZhbGlkYXRpb24gcmVsYXRlZCBmdW5jdGlvbmFsaXR5XG4gKiBAZGVzY3JpcHRpb24gRGVmaW5lcyB0aGUgTW9kZWwgdmFsaWRhdGlvbiBhcGlzIGFuZCBiYXNlIGNsYXNzZXMgZm9yIHZhbGlkYXRvcnNcbiAqXG4gKiBAbmFtZXNwYWNlIFZhbGlkYXRpb25cbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqL1xuXG4vKipcbiAqIEBuYW1lc3BhY2UgRGF0ZXNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqL1xuXG4vKipcbiAqIEBuYW1lc3BhY2UgSGFzaGluZ1xuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICovXG5cbi8qKlxuICogQG5hbWVzcGFjZSBTZXJpYWxpemF0aW9uXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uXG4gKi9cblxuLyoqXG4gKiBAbmFtZXNwYWNlIEZvcm1hdFxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICovXG5cbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi92YWxpZGF0aW9uXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9tb2RlbFwiO1xuXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbiJdLCJuYW1lcyI6WyJNb2RlbEtleXMiLCJhcHBseSIsIm1ldGFkYXRhIiwiUHJpbWl0aXZlcyIsIlJlc2VydmVkTW9kZWxzIiwiUmVmbGVjdGlvbiIsImlzRXF1YWwiLCJEYXRlVmFsaWRhdG9yIiwiUGF0dGVyblZhbGlkYXRvciIsIkVtYWlsVmFsaWRhdG9yIiwiTGlzdFZhbGlkYXRvciIsIk1heExlbmd0aFZhbGlkYXRvciIsIk1heFZhbGlkYXRvciIsIk1pbkxlbmd0aFZhbGlkYXRvciIsIk1pblZhbGlkYXRvciIsIlBhc3N3b3JkVmFsaWRhdG9yIiwiUmVxdWlyZWRWYWxpZGF0b3IiLCJTdGVwVmFsaWRhdG9yIiwiVHlwZVZhbGlkYXRvciIsIlVSTFZhbGlkYXRvciJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0lBQUE7Ozs7Ozs7Ozs7Ozs7SUFhRztBQUNTQTtJQUFaLENBQUEsVUFBWSxTQUFTLEVBQUE7SUFDbkIsSUFBQSxTQUFBLENBQUEsU0FBQSxDQUFBLEdBQUEsY0FBd0I7SUFDeEIsSUFBQSxTQUFBLENBQUEsTUFBQSxDQUFBLEdBQUEsYUFBb0I7SUFDcEIsSUFBQSxTQUFBLENBQUEsUUFBQSxDQUFBLEdBQUEsbUJBQTRCO0lBQzVCLElBQUEsU0FBQSxDQUFBLFFBQUEsQ0FBQSxHQUFBLG1CQUE0QjtJQUM1QixJQUFBLFNBQUEsQ0FBQSxPQUFBLENBQUEsR0FBQSxPQUFlO0lBQ2YsSUFBQSxTQUFBLENBQUEsUUFBQSxDQUFBLEdBQUEsU0FBa0I7SUFDbEIsSUFBQSxTQUFB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
|
|
3388
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVjb3JhdG9yLXZhbGlkYXRpb24uY2pzIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9jb25zdGFudHMudHMiLCIuLi9zcmMvdXRpbHMvc3RyaW5ncy50cyIsIi4uL3NyYy91dGlscy9kYXRlcy50cyIsIi4uL3NyYy91dGlscy9EZWNvcmF0aW9uLnRzIiwiLi4vc3JjL3V0aWxzL2RlY29yYXRvcnMudHMiLCIuLi9zcmMvdXRpbHMvaGFzaGluZy50cyIsIi4uL3NyYy9tb2RlbC9Nb2RlbEVycm9yRGVmaW5pdGlvbi50cyIsIi4uL3NyYy9tb2RlbC9jb25zdGFudHMudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL1ZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvVmFsaWRhdG9yUmVnaXN0cnkudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0aW9uLnRzIiwiLi4vc3JjL21vZGVsL3ZhbGlkYXRpb24udHMiLCIuLi9zcmMvbW9kZWwvTW9kZWwudHMiLCIuLi9zcmMvdXRpbHMvc2VyaWFsaXphdGlvbi50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvZGVjb3JhdG9ycy50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvRGF0ZVZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvUGF0dGVyblZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvRW1haWxWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL0xpc3RWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL01heExlbmd0aFZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvTWF4VmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9NaW5MZW5ndGhWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL01pblZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvUGFzc3dvcmRWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL1JlcXVpcmVkVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9TdGVwVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9UeXBlVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9VUkxWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL21vZGVsL2NvbnN0cnVjdGlvbi50cyIsIi4uL3NyYy9tb2RlbC9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGRlc2NyaXB0aW9uIEVudW0gY29udGFpbmluZyBtZXRhZGF0YSBrZXlzIHVzZWQgZm9yIHJlZmxlY3Rpb24gaW4gdGhlIG1vZGVsIHN5c3RlbVxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgdmFyaW91cyBNb2RlbCBrZXlzIHVzZWQgZm9yIHJlZmxlY3Rpb24gYW5kIG1ldGFkYXRhIHN0b3JhZ2UuXG4gKiBUaGVzZSBrZXlzIGFyZSB1c2VkIHRocm91Z2hvdXQgdGhlIGxpYnJhcnkgdG8gc3RvcmUgYW5kIHJldHJpZXZlIG1ldGFkYXRhIGFib3V0IG1vZGVscyxcbiAqIHRoZWlyIHByb3BlcnRpZXMsIGFuZCB0aGVpciBiZWhhdmlvci5cbiAqXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUkVGTEVDVCAtIFByZWZpeCB0byBhbGwgb3RoZXIga2V5cywgdXNlZCBhcyBhIG5hbWVzcGFjZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFRZUEUgLSBLZXkgZm9yIHN0b3JpbmcgZGVzaWduIHR5cGUgaW5mb3JtYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBQQVJBTVMgLSBLZXkgZm9yIHN0b3JpbmcgbWV0aG9kIHBhcmFtZXRlciB0eXBlc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IFJFVFVSTiAtIEtleSBmb3Igc3RvcmluZyBtZXRob2QgcmV0dXJuIHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBNT0RFTCAtIEtleSBmb3IgaWRlbnRpZnlpbmcgbW9kZWwgbWV0YWRhdGFcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBBTkNIT1IgLSBBbmNob3Iga2V5IHRoYXQgc2VydmVzIGFzIGEgZ2hvc3QgcHJvcGVydHkgaW4gdGhlIG1vZGVsXG4gKiBAcHJvcGVydHkge3N0cmluZ30gQ09OU1RSVUNUSU9OIC0gS2V5IGZvciBzdG9yaW5nIGNvbnN0cnVjdGlvbiBpbmZvcm1hdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IEFUVFJJQlVURSAtIEtleSBmb3Igc3RvcmluZyBhdHRyaWJ1dGUgbWV0YWRhdGFcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBIQVNISU5HIC0gS2V5IGZvciBzdG9yaW5nIGhhc2hpbmcgY29uZmlndXJhdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IFNFUklBTElaQVRJT04gLSBLZXkgZm9yIHN0b3Jpbmcgc2VyaWFsaXphdGlvbiBjb25maWd1cmF0aW9uXG4gKlxuICogQHJlYWRvbmx5XG4gKiBAZW51bSB7c3RyaW5nfVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICogQGNhdGVnb3J5IE1vZGVsXG4gKi9cbmV4cG9ydCBlbnVtIE1vZGVsS2V5cyB7XG4gIFJFRkxFQ1QgPSBcImRlY2FmLm1vZGVsLlwiLFxuICBUWVBFID0gXCJkZXNpZ246dHlwZVwiLFxuICBQQVJBTVMgPSBcImRlc2lnbjpwYXJhbXR5cGVzXCIsXG4gIFJFVFVSTiA9IFwiZGVzaWduOnJldHVybnR5cGVcIixcbiAgTU9ERUwgPSBcIm1vZGVsXCIsXG4gIEFOQ0hPUiA9IFwiX19tb2RlbFwiLFxuICBDT05TVFJVQ1RJT04gPSBcImNvbnN0cnVjdGVkLWJ5XCIsXG4gIEFUVFJJQlVURSA9IFwiX19hdHRyaWJ1dGVzXCIsXG4gIEhBU0hJTkcgPSBcImhhc2hpbmdcIixcbiAgU0VSSUFMSVpBVElPTiA9IFwic2VyaWFsaXphdGlvblwiLFxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IGZsYXZvdXIgaWRlbnRpZmllciBmb3IgdGhlIGRlY29yYXRvciBzeXN0ZW1cbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIGRlZmF1bHQgZmxhdm91ciB1c2VkIGJ5IHRoZSBEZWNvcmF0aW9uIGNsYXNzIHdoZW4gbm8gc3BlY2lmaWMgZmxhdm91ciBpcyBwcm92aWRlZC5cbiAqIFRoaXMgY29uc3RhbnQgaXMgdXNlZCB0aHJvdWdob3V0IHRoZSBsaWJyYXJ5IGFzIHRoZSBmYWxsYmFjayBmbGF2b3VyIGZvciBkZWNvcmF0b3JzLlxuICpcbiAqIEBjb25zdCB7c3RyaW5nfVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICogQGNhdGVnb3J5IE1vZGVsXG4gKi9cbmV4cG9ydCBjb25zdCBEZWZhdWx0Rmxhdm91ciA9IFwiZGVjYWZcIjtcbiIsImltcG9ydCB7IE1vZGVsS2V5cyB9IGZyb20gXCIuLi8uLi91dGlscy9jb25zdGFudHNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBUaGUga2V5cyB1c2VkIGZvciB2YWxpZGF0aW9uXG4gKlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFJFRkxFQ1QgcHJlZml4ZXMgb3RoZXJzXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUkVRVUlSRUQgc2V0cyBhcyByZXF1aXJlZFxuICogQHByb3BlcnR5IHtzdHJpbmd9IE1JTiBkZWZpbmVzIG1pbiB2YWx1ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IE1BWCBkZWZpbmVzIG1heCB2YWx1ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFNURVAgZGVmaW5lcyBzdGVwXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUlOX0xFTkdUSCBkZWZpbmVzIG1pbiBsZW5ndGhcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBNQVhfTEVOR1RIIGRlZmluZXMgbWF4IGxlbmd0aFxuICogQHByb3BlcnR5IHtzdHJpbmd9IFBBVFRFUk4gZGVmaW5lcyBwYXR0ZXJuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gRU1BSUwgZGVmaW5lcyBlbWFpbFxuICogQHByb3BlcnR5IHtzdHJpbmd9IFVSTCBkZWZpbmVzIHVybFxuICogQHByb3BlcnR5IHtzdHJpbmd9IERBVEUgZGVmaW5lcyBkYXRlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gVFlQRSBkZWZpbmVzIHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBQQVNTV09SRCBkZWZpbmVzIHBhc3N3b3JkXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTElTVCBkZWZpbmVzIGxpc3RcbiAqXG4gKiBAY29uc3RhbnQgVmFsaWRhdGlvbktleXNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IFZhbGlkYXRpb25cbiAqL1xuZXhwb3J0IGNvbnN0IFZhbGlkYXRpb25LZXlzID0ge1xuICBSRUZMRUNUOiBgJHtNb2RlbEtleXMuUkVGTEVDVH12YWxpZGF0aW9uLmAsXG4gIFZBTElEQVRPUjogXCJ2YWxpZGF0b3JcIixcbiAgUkVRVUlSRUQ6IFwicmVxdWlyZWRcIixcbiAgTUlOOiBcIm1pblwiLFxuICBNQVg6IFwibWF4XCIsXG4gIFNURVA6IFwic3RlcFwiLFxuICBNSU5fTEVOR1RIOiBcIm1pbmxlbmd0aFwiLFxuICBNQVhfTEVOR1RIOiBcIm1heGxlbmd0aFwiLFxuICBQQVRURVJOOiBcInBhdHRlcm5cIixcbiAgRU1BSUw6IFwiZW1haWxcIixcbiAgVVJMOiBcInVybFwiLFxuICBEQVRFOiBcImRhdGVcIixcbiAgVFlQRTogXCJ0eXBlXCIsXG4gIFBBU1NXT1JEOiBcInBhc3N3b3JkXCIsXG4gIExJU1Q6IFwibGlzdFwiLFxuICBGT1JNQVQ6IFwiZm9ybWF0XCIsXG59IGFzIGNvbnN0O1xuXG4vKipcbiAqIEBzdW1tYXJ5IGxpc3Qgb2YgbW9udGggbmFtZXNcbiAqIEBkZXNjcmlwdGlvbiBTdG9yZXMgbW9udGggbmFtZXMuIENhbiBiZSBjaGFuZ2VkIGZvciBsb2NhbGl6YXRpb24gcHVycG9zZXNcbiAqXG4gKiBAY29uc3RhbnQgTU9OVEhfTkFNRVNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IFZhbGlkYXRpb25cbiAqL1xuZXhwb3J0IGNvbnN0IE1PTlRIX05BTUVTID0gW1xuICBcIkphbnVhcnlcIixcbiAgXCJGZWJydWFyeVwiLFxuICBcIk1hcmNoXCIsXG4gIFwiQXByaWxcIixcbiAgXCJNYXlcIixcbiAgXCJKdW5lXCIsXG4gIFwiSnVseVwiLFxuICBcIkF1Z3VzdFwiLFxuICBcIlNlcHRlbWJlclwiLFxuICBcIk9jdG9iZXJcIixcbiAgXCJOb3ZlbWJlclwiLFxuICBcIkRlY2VtYmVyXCIsXG5dO1xuXG4vKipcbiAqIEBzdW1tYXJ5IGxpc3Qgb2YgbmFtZXMgb2YgZGF5cyBvZiB0aGUgd2Vla1xuICogQGRlc2NyaXB0aW9uIFN0b3JlcyBuYW1lcyBmb3IgZGF5cyBvZiB0aGUgd2Vlay4gQ2FuIGJlIGNoYW5nZWQgZm9yIGxvY2FsaXphdGlvbiBwdXJwb3Nlc1xuICpcbiAqIEBjb25zdGFudCBEQVlTX09GX1dFRUtfTkFNRVNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IFZhbGlkYXRpb25cbiAqL1xuZXhwb3J0IGNvbnN0IERBWVNfT0ZfV0VFS19OQU1FUyA9IFtcbiAgXCJTdW5kYXlcIixcbiAgXCJNb25kYXlcIixcbiAgXCJUdWVzZGF5XCIsXG4gIFwiV2VkbmVzZGF5XCIsXG4gIFwiVGh1cnNkYXlcIixcbiAgXCJGcmlkYXlcIixcbiAgXCJTYXR1cmRheVwiLFxuXTtcblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBkZWZhdWx0IGVycm9yIG1lc3NhZ2VzXG4gKlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFJFUVVJUkVEIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IE1JTiBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBNQVggZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUlOX0xFTkdUSCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBNQVhfTEVOR1RIIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFBBVFRFUk4gZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gRU1BSUwgZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gVVJMIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFRZUEUgZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gU1RFUCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBEQVRFIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IERFRkFVTFQgZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUEFTU1dPUkQgZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTElTVCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBMSVNUX0lOU0lERSBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBNT0RFTF9OT1RfRk9VTkQgZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKlxuICogQGNvbnN0YW50IERFRkFVTFRfRVJST1JfTUVTU0FHRVNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IFZhbGlkYXRpb25cbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfRVJST1JfTUVTU0FHRVM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gIFJFUVVJUkVEOiBcIlRoaXMgZmllbGQgaXMgcmVxdWlyZWRcIixcbiAgTUlOOiBcIlRoZSBtaW5pbXVtIHZhbHVlIGlzIHswfVwiLFxuICBNQVg6IFwiVGhlIG1heGltdW0gdmFsdWUgaXMgezB9XCIsXG4gIE1JTl9MRU5HVEg6IFwiVGhlIG1pbmltdW0gbGVuZ3RoIGlzIHswfVwiLFxuICBNQVhfTEVOR1RIOiBcIlRoZSBtYXhpbXVtIGxlbmd0aCBpcyB7MH1cIixcbiAgUEFUVEVSTjogXCJUaGUgdmFsdWUgZG9lcyBub3QgbWF0Y2ggdGhlIHBhdHRlcm5cIixcbiAgRU1BSUw6IFwiVGhlIHZhbHVlIGlzIG5vdCBhIHZhbGlkIGVtYWlsXCIsXG4gIFVSTDogXCJUaGUgdmFsdWUgaXMgbm90IGEgdmFsaWQgVVJMXCIsXG4gIFRZUEU6IFwiSW52YWxpZCB0eXBlLiBFeHBlY3RlZCB7MH0sIHJlY2VpdmVkIHsxfVwiLFxuICBTVEVQOiBcIkludmFsaWQgdmFsdWUuIE5vdCBhIHN0ZXAgb2YgezB9XCIsXG4gIERBVEU6IFwiSW52YWxpZCB2YWx1ZS4gbm90IGEgdmFsaWQgRGF0ZVwiLFxuICBERUZBVUxUOiBcIlRoZXJlIGlzIGFuIEVycm9yXCIsXG4gIFBBU1NXT1JEOlxuICAgIFwiTXVzdCBiZSBhdCBsZWFzdCA4IGNoYXJhY3RlcnMgYW5kIGNvbnRhaW4gb25lIG9mIG51bWJlciwgbG93ZXIgYW5kIHVwcGVyIGNhc2UgbGV0dGVycywgYW5kIHNwZWNpYWwgY2hhcmFjdGVyIChAJCElKj8mXy0uLClcIixcbiAgTElTVDogXCJJbnZhbGlkIGxpc3Qgb2YgezB9XCIsXG4gIE1PREVMX05PVF9GT1VORDogXCJObyBtb2RlbCByZWdpc3RlcmVkIHVuZGVyIHswfVwiLFxufTtcblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSB2YXJpb3VzIGRlZmF1bHQgcmVnZXhwIHBhdHRlcm5zIHVzZWRcbiAqXG4gKiBAZW51bSBERUZBVUxUX1BBVFRFUk5TXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX1BBVFRFUk5TID0ge1xuICBFTUFJTDpcbiAgICAvW2EtekEtWjAtOSEjJCUmJyorLz0/Xl9ge3x9fi1dKyg/OlxcLlthLXpBLVowLTkhIyQlJicqKy89P15fYHt8fX4tXSspKkAoPzpbYS16QS1aMC05XSg/OlthLXowLTktXSpbYS16QS1aMC05XSk/XFwuKStbYS16QS1aMC05XSg/OlthLXpBLVowLTktXSpbYS16QS1aMC05XSk/LyxcbiAgVVJMOiAvXig/Oig/Oig/Omh0dHBzP3xmdHApOik/XFwvXFwvKSg/OlxcUysoPzo6XFxTKik/QCk/KD86KD8hKD86MTB8MTI3KSg/OlxcLlxcZHsxLDN9KXszfSkoPyEoPzoxNjlcXC4yNTR8MTkyXFwuMTY4KSg/OlxcLlxcZHsxLDN9KXsyfSkoPyExNzJcXC4oPzoxWzYtOV18MlxcZHwzWzAtMV0pKD86XFwuXFxkezEsM30pezJ9KSg/OlsxLTldXFxkP3wxXFxkXFxkfDJbMDFdXFxkfDIyWzAtM10pKD86XFwuKD86MT9cXGR7MSwyfXwyWzAtNF1cXGR8MjVbMC01XSkpezJ9KD86XFwuKD86WzEtOV1cXGQ/fDFcXGRcXGR8MlswLTRdXFxkfDI1WzAtNF0pKXwoPzooPzpbYS16MC05XFx1MDBhMS1cXHVmZmZmXVthLXowLTlcXHUwMGExLVxcdWZmZmZfLV17MCw2Mn0pP1thLXowLTlcXHUwMGExLVxcdWZmZmZdXFwuKSsoPzpbYS16XFx1MDBhMS1cXHVmZmZmXXsyLH1cXC4/KSkoPzo6XFxkezIsNX0pPyg/OlsvPyNdXFxTKik/JC9pLFxuICBQQVNTV09SRDoge1xuICAgIENIQVI4X09ORV9PRl9FQUNIOlxuICAgICAgL14oPz0uKlthLXpdKSg/PS4qW0EtWl0pKD89LipcXGQpKD89LipbQCQhJSo/Jl9cXC0uLF0pW0EtWmEtelxcZEAkISUqPyZfXFwtLixdezgsfSQvZyxcbiAgfSxcbn07XG4iLCIvKipcbiAqIEBzdW1tYXJ5IFV0aWwgZnVuY3Rpb24gdG8gcHJvdmlkZSBzdHJpbmcgZm9ybWF0IGZ1bmN0aW9uYWxpdHkgc2ltaWxhciB0byBDIydzIHN0cmluZy5mb3JtYXRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZyB8IG51bWJlcj59IFthcmdzXSByZXBsYWNlbWVudHMgbWFkZSBieSBvcmRlciBvZiBhcHBlYXJhbmNlIChyZXBsYWNlbWVudDAgd2lsIHJlcGxhY2UgezB9IGFuZCBzbyBvbilcbiAqIEByZXR1cm4ge3N0cmluZ30gZm9ybWF0dGVkIHN0cmluZ1xuICpcbiAqIEBmdW5jdGlvbiBzdHJpbmdGb3JtYXRcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RyaW5nRm9ybWF0KHN0cmluZzogc3RyaW5nLCAuLi5hcmdzOiAoc3RyaW5nIHwgbnVtYmVyKVtdKSB7XG4gIHJldHVybiBzdHJpbmcucmVwbGFjZSgveyhcXGQrKX0vZywgZnVuY3Rpb24gKG1hdGNoLCBudW1iZXIpIHtcbiAgICByZXR1cm4gdHlwZW9mIGFyZ3NbbnVtYmVyXSAhPT0gXCJ1bmRlZmluZWRcIlxuICAgICAgPyBhcmdzW251bWJlcl0udG9TdHJpbmcoKVxuICAgICAgOiBcInVuZGVmaW5lZFwiO1xuICB9KTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBVdGlsIGZ1bmN0aW9uIHRvIHByb3ZpZGUgc3RyaW5nIGZvcm1hdCBmdW5jdGlvbmFsaXR5IHNpbWlsYXIgdG8gQyMncyBzdHJpbmcuZm9ybWF0XG4gKiBAZGVzY3JpcHRpb24gYWxpYXMgZm9yIHtAbGluayBzdHJpbmdGb3JtYXR9XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZ1xuICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MgcmVwbGFjZW1lbnRzIG1hZGUgYnkgb3JkZXIgb2YgYXBwZWFyYW5jZSAocmVwbGFjZW1lbnQwIHdpbCByZXBsYWNlIHswfSBhbmQgc28gb24pXG4gKiBAcmV0dXJuIHtzdHJpbmd9IGZvcm1hdHRlZCBzdHJpbmdcbiAqXG4gKiBAZnVuY3Rpb24gc2ZcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgY29uc3Qgc2YgPSBzdHJpbmdGb3JtYXQ7XG4iLCJpbXBvcnQgXCJyZWZsZWN0LW1ldGFkYXRhXCI7XG5pbXBvcnQge1xuICBEQVlTX09GX1dFRUtfTkFNRVMsXG4gIE1PTlRIX05BTUVTLFxufSBmcm9tIFwiLi4vdmFsaWRhdGlvbi9WYWxpZGF0b3JzL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgc2YgfSBmcm9tIFwiLi9zdHJpbmdzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgUmV2ZXJzZXMgdGhlIHByb2Nlc3MgZnJvbSB7QGxpbmsgZm9ybWF0RGF0ZX1cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZGF0ZSB0aGUgZGF0ZSBzdHJpbmcgdG8gYmUgY29udmVydGVkIGJhY2sgaW50byBkYXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gZm9ybWF0IHRoZSBkYXRlIGZvcm1hdFxuICogQHJldHVybiB7RGF0ZX0gdGhlIGRhdGUgZnJvbSB0aGUgZm9ybWF0IG9yIHRoZSBzdGFuZGFyZCBuZXcgRGF0ZSh7QHByb3AgZGF0ZX0pIGlmIHRoZSBzdHJpbmcgY291bGRuJ3QgYmUgcGFyc2VkIChhcmUgeW91IHN1cmUgdGhlIGZvcm1hdCBtYXRjaGVzIHRoZSBzdHJpbmc/KVxuICpcbiAqIEBmdW5jdGlvbiBkYXRlRnJvbUZvcm1hdFxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICogQGNhdGVnb3J5IE1vZGVsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkYXRlRnJvbUZvcm1hdChkYXRlOiBzdHJpbmcsIGZvcm1hdDogc3RyaW5nKSB7XG4gIGxldCBmb3JtYXRSZWdleHA6IHN0cmluZyA9IGZvcm1hdDtcblxuICAvLyBIb3VyXG4gIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL2hoLykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJoaFwiLCBcIig/PGhvdXI+XFxcXGR7Mn0pXCIpO1xuICBlbHNlIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL2gvKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcImhcIiwgXCIoPzxob3VyPlxcXFxkezEsMn0pXCIpO1xuICBlbHNlIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL0hILykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJISFwiLCBcIig/PGhvdXI+XFxcXGR7Mn0pXCIpO1xuICBlbHNlIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL0gvKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcIkhcIiwgXCIoPzxob3VyPlxcXFxkezEsMn0pXCIpO1xuXG4gIC8vIE1pbnV0ZXNcbiAgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgvbW0vKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcIm1tXCIsIFwiKD88bWludXRlcz5cXFxcZHsyfSlcIik7XG4gIGVsc2UgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgvbS8pKVxuICAgIGZvcm1hdFJlZ2V4cCA9IGZvcm1hdFJlZ2V4cC5yZXBsYWNlKFwibVwiLCBcIig/PG1pbnV0ZXM+XFxcXGR7MSwyfSlcIik7XG5cbiAgLy8gU2Vjb25kc1xuICBpZiAoZm9ybWF0UmVnZXhwLm1hdGNoKC9zcy8pKVxuICAgIGZvcm1hdFJlZ2V4cCA9IGZvcm1hdFJlZ2V4cC5yZXBsYWNlKFwic3NcIiwgXCIoPzxzZWNvbmRzPlxcXFxkezJ9KVwiKTtcbiAgZWxzZSBpZiAoZm9ybWF0UmVnZXhwLm1hdGNoKC9zLykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJzXCIsIFwiKD88c2Vjb25kcz5cXFxcZHsxLDJ9KVwiKTtcblxuICAvLyBEYXlcbiAgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgvZGQvKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcImRkXCIsIFwiKD88ZGF5PlxcXFxkezJ9KVwiKTtcbiAgZWxzZSBpZiAoZm9ybWF0UmVnZXhwLm1hdGNoKC9kLykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJkXCIsIFwiKD88ZGF5PlxcXFxkezEsMn0pXCIpO1xuXG4gIC8vIERheSBPZiBXZWVrXG4gIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL0VFRUUvKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcIkVFRUVcIiwgXCIoPzxkYXlvZndlZWs+XFxcXHcrKVwiKTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWR1cGUtZWxzZS1pZlxuICBlbHNlIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL0VFRUUvKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcIkVFRVwiLCBcIig/PGRheW9md2Vlaz5cXFxcdyspXCIpO1xuXG4gIC8vIFllYXJcbiAgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgveXl5eS8pKVxuICAgIGZvcm1hdFJlZ2V4cCA9IGZvcm1hdFJlZ2V4cC5yZXBsYWNlKFwieXl5eVwiLCBcIig/PHllYXI+XFxcXGR7NH0pXCIpO1xuICBlbHNlIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL3l5LykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJ5eVwiLCBcIig/PHllYXI+XFxcXGR7Mn0pXCIpO1xuXG4gIC8vIE1vbnRoXG4gIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL01NTU0vKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcIk1NTU1cIiwgXCIoPzxtb250aG5hbWU+XFxcXHcrKVwiKTtcbiAgZWxzZSBpZiAoZm9ybWF0UmVnZXhwLm1hdGNoKC9NTU0vKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcIk1NTVwiLCBcIig/PG1vbnRobmFtZXNtYWxsPlxcXFx3KylcIik7XG4gIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL01NLykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJNTVwiLCBcIig/PG1vbnRoPlxcXFxkezJ9KVwiKTtcbiAgZWxzZSBpZiAoZm9ybWF0UmVnZXhwLm1hdGNoKC9NLykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJNXCIsIFwiKD88bW9udGg+XFxcXGR7MSwyfSlcIik7XG5cbiAgLy8gTWlsaXMgYW5kIEFtIFBtXG4gIGZvcm1hdFJlZ2V4cCA9IGZvcm1hdFJlZ2V4cFxuICAgIC5yZXBsYWNlKFwiU1wiLCBcIig/PG1pbGlzPlxcXFxkezEsM30pXCIpXG4gICAgLnJlcGxhY2UoXCJhYWFcIiwgXCIoPzxhbXBtPlxcXFx3ezJ9KVwiKTtcblxuICBjb25zdCByZWdleHAgPSBuZXcgUmVnRXhwKGZvcm1hdFJlZ2V4cCwgXCJnXCIpO1xuXG4gIGNvbnN0IG1hdGNoOiB7XG4gICAgZ3JvdXBzOiB7XG4gICAgICB5ZWFyPzogc3RyaW5nO1xuICAgICAgZGF5Pzogc3RyaW5nO1xuICAgICAgYW1wbT86IHN0cmluZztcbiAgICAgIGhvdXI/OiBzdHJpbmc7XG4gICAgICBtaW51dGVzPzogc3RyaW5nO1xuICAgICAgc2Vjb25kcz86IHN0cmluZztcbiAgICAgIG1pbGlzPzogc3RyaW5nO1xuICAgICAgbW9udGhuYW1lPzogc3RyaW5nO1xuICAgICAgbW9udGhuYW1lc21hbGw/OiBzdHJpbmc7XG4gICAgICBtb250aD86IHN0cmluZztcbiAgICB9O1xuICB9ID0gcmVnZXhwLmV4ZWMoZGF0ZSkgYXMgYW55O1xuXG4gIGlmICghbWF0Y2ggfHwgIW1hdGNoLmdyb3VwcykgcmV0dXJuIG5ldyBEYXRlKGRhdGUpO1xuXG4gIGNvbnN0IHNhZmVQYXJzZUludCA9IGZ1bmN0aW9uIChuPzogc3RyaW5nKSB7XG4gICAgaWYgKCFuKSByZXR1cm4gMDtcbiAgICBjb25zdCByZXN1bHQgPSBwYXJzZUludChuKTtcblxuICAgIHJldHVybiBpc05hTihyZXN1bHQpID8gMCA6IHJlc3VsdDtcbiAgfTtcblxuICBjb25zdCB5ZWFyID0gc2FmZVBhcnNlSW50KG1hdGNoLmdyb3Vwcy55ZWFyKTtcbiAgY29uc3QgZGF5ID0gc2FmZVBhcnNlSW50KG1hdGNoLmdyb3Vwcy5kYXkpO1xuXG4gIGNvbnN0IGFtUG0gPSBtYXRjaC5ncm91cHMuYW1wbTtcbiAgbGV0IGhvdXIgPSBzYWZlUGFyc2VJbnQobWF0Y2guZ3JvdXBzLmhvdXIpO1xuXG4gIGlmIChhbVBtKSBob3VyID0gYW1QbSA9PT0gXCJQTVwiID8gaG91ciArIDEyIDogaG91cjtcblxuICBjb25zdCBtaW51dGVzID0gc2FmZVBhcnNlSW50KG1hdGNoLmdyb3Vwcy5taW51dGVzKTtcbiAgY29uc3Qgc2Vjb25kcyA9IHNhZmVQYXJzZUludChtYXRjaC5ncm91cHMuc2Vjb25kcyk7XG4gIGNvbnN0IG1zID0gc2FmZVBhcnNlSW50KG1hdGNoLmdyb3Vwcy5taWxpcyk7XG5cbiAgY29uc3QgbW9udGhOYW1lID0gbWF0Y2guZ3JvdXBzLm1vbnRobmFtZTtcbiAgY29uc3QgbW9udGhOYW1lU21hbGwgPSBtYXRjaC5ncm91cHMubW9udGhuYW1lc21hbGw7XG4gIGxldCBtb250aDogbnVtYmVyIHwgc3RyaW5nID0gbWF0Y2guZ3JvdXBzLm1vbnRoIGFzIHN0cmluZztcbiAgaWYgKG1vbnRoTmFtZSkgbW9udGggPSBNT05USF9OQU1FUy5pbmRleE9mKG1vbnRoTmFtZSk7XG4gIGVsc2UgaWYgKG1vbnRoTmFtZVNtYWxsKSB7XG4gICAgY29uc3QgbSA9IE1PTlRIX05BTUVTLmZpbmQoKG0pID0+XG4gICAgICBtLnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aChtb250aE5hbWVTbWFsbC50b0xvd2VyQ2FzZSgpKVxuICAgICk7XG4gICAgaWYgKCFtKSByZXR1cm4gbmV3IERhdGUoZGF0ZSk7XG4gICAgbW9udGggPSBNT05USF9OQU1FUy5pbmRleE9mKG0pO1xuICB9IGVsc2UgbW9udGggPSBzYWZlUGFyc2VJbnQoYCR7bW9udGh9YCk7XG5cbiAgcmV0dXJuIG5ldyBEYXRlKHllYXIsIG1vbnRoIC0gMSwgZGF5LCBob3VyLCBtaW51dGVzLCBzZWNvbmRzLCBtcyk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEJpbmRzIGEgc3BlY2lmaWMgZGF0ZSBmb3JtYXQgdG8gYSBEYXRlIG9iamVjdCdzIHRvU3RyaW5nIGFuZCB0b0lTT1N0cmluZyBtZXRob2RzXG4gKiBAc3VtbWFyeSBNb2RpZmllcyBhIERhdGUgb2JqZWN0IHRvIHJldHVybiBhIGZvcm1hdHRlZCBzdHJpbmcgd2hlbiB0b1N0cmluZyBvciB0b0lTT1N0cmluZyBpcyBjYWxsZWQuXG4gKiBUaGlzIGZ1bmN0aW9uIG92ZXJyaWRlcyB0aGUgZGVmYXVsdCB0b1N0cmluZyBhbmQgdG9JU09TdHJpbmcgbWV0aG9kcyBvZiB0aGUgRGF0ZSBvYmplY3QgdG8gcmV0dXJuXG4gKiB0aGUgZGF0ZSBmb3JtYXR0ZWQgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgZm9ybWF0IHN0cmluZy5cbiAqIEBwYXJhbSB7RGF0ZX0gW2RhdGVdIFRoZSBEYXRlIG9iamVjdCB0byBtb2RpZnlcbiAqIEBwYXJhbSB7c3RyaW5nfSBbZm9ybWF0XSBUaGUgZm9ybWF0IHN0cmluZyB0byB1c2UgZm9yIGZvcm1hdHRpbmcgdGhlIGRhdGVcbiAqIEByZXR1cm4ge0RhdGV8dW5kZWZpbmVkfSBUaGUgbW9kaWZpZWQgRGF0ZSBvYmplY3Qgb3IgdW5kZWZpbmVkIGlmIG5vIGRhdGUgd2FzIHByb3ZpZGVkXG4gKiBAZnVuY3Rpb24gYmluZERhdGVUb1N0cmluZ1xuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICogQGNhdGVnb3J5IE1vZGVsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiaW5kRGF0ZVRvU3RyaW5nKGRhdGU6IERhdGUgfCB1bmRlZmluZWQsIGZvcm1hdDogc3RyaW5nKSB7XG4gIGlmICghZGF0ZSkgcmV0dXJuO1xuICBjb25zdCBmdW5jID0gKCkgPT4gZm9ybWF0RGF0ZShkYXRlLCBmb3JtYXQpO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZGF0ZSwgXCJ0b0lTT1N0cmluZ1wiLCB7XG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICB2YWx1ZTogZnVuYyxcbiAgfSk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShkYXRlLCBcInRvU3RyaW5nXCIsIHtcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgIHZhbHVlOiBmdW5jLFxuICB9KTtcbiAgLy8gT2JqZWN0LnNldFByb3RvdHlwZU9mKGRhdGUsIERhdGUucHJvdG90eXBlKTtcbiAgcmV0dXJuIGRhdGU7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFNhZmVseSBjaGVja3MgaWYgYSB2YWx1ZSBpcyBhIHZhbGlkIERhdGUgb2JqZWN0XG4gKiBAc3VtbWFyeSBBIHV0aWxpdHkgZnVuY3Rpb24gdGhhdCBkZXRlcm1pbmVzIGlmIGEgdmFsdWUgaXMgYSB2YWxpZCBEYXRlIG9iamVjdC5cbiAqIFRoaXMgZnVuY3Rpb24gaXMgbW9yZSByZWxpYWJsZSB0aGFuIHVzaW5nIGluc3RhbmNlb2YgRGF0ZSBhcyBpdCBhbHNvIGNoZWNrc1xuICogdGhhdCB0aGUgZGF0ZSBpcyBub3QgTmFOLCB3aGljaCBjYW4gaGFwcGVuIHdpdGggaW52YWxpZCBkYXRlIHN0cmluZ3MuXG4gKiBAcGFyYW0ge2FueX0gZGF0ZSBUaGUgdmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIHZhbHVlIGlzIGEgdmFsaWQgRGF0ZSBvYmplY3QsIGZhbHNlIG90aGVyd2lzZVxuICogQGZ1bmN0aW9uIGlzVmFsaWREYXRlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZERhdGUoZGF0ZTogYW55KTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgZGF0ZSAmJlxuICAgIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChkYXRlKSA9PT0gXCJbb2JqZWN0IERhdGVdXCIgJiZcbiAgICAhTnVtYmVyLmlzTmFOKGRhdGUpXG4gICk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgVXRpbCBmdW5jdGlvbiB0byBwYWQgbnVtYmVyc1xuICogQHBhcmFtIHtudW1iZXJ9IG51bVxuICpcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqXG4gKiBAZnVuY3Rpb24gdHdvRGlnaXRQYWRcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgZnVuY3Rpb24gdHdvRGlnaXRQYWQobnVtOiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gbnVtIDwgMTAgPyBcIjBcIiArIG51bSA6IG51bS50b1N0cmluZygpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERhdGUgRm9ybWF0IEhhbmRsaW5nXG4gKiBAZGVzY3JpcHRpb24gQ29kZSBmcm9tIHtAbGluayBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zNTUyNDYxL2hvdy10by1mb3JtYXQtYS1qYXZhc2NyaXB0LWRhdGV9XG4gKlxuICogPHByZT5cbiAqICAgICAgVXNpbmcgc2ltaWxhciBmb3JtYXR0aW5nIGFzIE1vbWVudC5qcywgQ2xhc3MgRGF0ZVRpbWVGb3JtYXR0ZXIgKEphdmEpLCBhbmQgQ2xhc3MgU2ltcGxlRGF0ZUZvcm1hdCAoSmF2YSksXG4gKiAgICAgIEkgaW1wbGVtZW50ZWQgYSBjb21wcmVoZW5zaXZlIHNvbHV0aW9uIGZvcm1hdERhdGUoZGF0ZSwgcGF0dGVyblN0cikgd2hlcmUgdGhlIGNvZGUgaXMgZWFzeSB0byByZWFkIGFuZCBtb2RpZnkuXG4gKiAgICAgIFlvdSBjYW4gZGlzcGxheSBkYXRlLCB0aW1lLCBBTS9QTSwgZXRjLlxuICpcbiAqICAgICAgRGF0ZSBhbmQgVGltZSBQYXR0ZXJuc1xuICogICAgICB5eSA9IDItZGlnaXQgeWVhcjsgeXl5eSA9IGZ1bGwgeWVhclxuICogICAgICBNID0gZGlnaXQgbW9udGg7IE1NID0gMi1kaWdpdCBtb250aDsgTU1NID0gc2hvcnQgbW9udGggbmFtZTsgTU1NTSA9IGZ1bGwgbW9udGggbmFtZVxuICogICAgICBFRUVFID0gZnVsbCB3ZWVrZGF5IG5hbWU7IEVFRSA9IHNob3J0IHdlZWtkYXkgbmFtZVxuICogICAgICBkID0gZGlnaXQgZGF5OyBkZCA9IDItZGlnaXQgZGF5XG4gKiAgICAgIGggPSBob3VycyBhbS9wbTsgaGggPSAyLWRpZ2l0IGhvdXJzIGFtL3BtOyBIID0gaG91cnM7IEhIID0gMi1kaWdpdCBob3Vyc1xuICogICAgICBtID0gbWludXRlczsgbW0gPSAyLWRpZ2l0IG1pbnV0ZXM7IGFhYSA9IEFNL1BNXG4gKiAgICAgIHMgPSBzZWNvbmRzOyBzcyA9IDItZGlnaXQgc2Vjb25kc1xuICogICAgICBTID0gbWlsaXNlY29uZHNcbiAqIDwvcHJlPlxuICpcbiAqIEBwYXJhbSB7RGF0ZX0gZGF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IFtwYXR0ZXJuU3RyXSBkZWZhdWx0cyB0byAneXl5eS9NTS9kZCdcbiAqIEByZXR1cm4ge3N0cmluZ30gdGhlIGZvcm1hdHRlZCBkYXRlXG4gKlxuICogQGZ1bmN0aW9uIGZvcm1hdERhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0RGF0ZShkYXRlOiBEYXRlLCBwYXR0ZXJuU3RyOiBzdHJpbmcgPSBcInl5eXkvTU0vZGRcIikge1xuICBjb25zdCBkYXk6IG51bWJlciA9IGRhdGUuZ2V0RGF0ZSgpLFxuICAgIG1vbnRoOiBudW1iZXIgPSBkYXRlLmdldE1vbnRoKCksXG4gICAgeWVhcjogbnVtYmVyID0gZGF0ZS5nZXRGdWxsWWVhcigpLFxuICAgIGhvdXI6IG51bWJlciA9IGRhdGUuZ2V0SG91cnMoKSxcbiAgICBtaW51dGU6IG51bWJlciA9IGRhdGUuZ2V0TWludXRlcygpLFxuICAgIHNlY29uZDogbnVtYmVyID0gZGF0ZS5nZXRTZWNvbmRzKCksXG4gICAgbWlsaXNlY29uZHM6IG51bWJlciA9IGRhdGUuZ2V0TWlsbGlzZWNvbmRzKCksXG4gICAgaDogbnVtYmVyID0gaG91ciAlIDEyLFxuICAgIGhoOiBzdHJpbmcgPSB0d29EaWdpdFBhZChoKSxcbiAgICBISDogc3RyaW5nID0gdHdvRGlnaXRQYWQoaG91ciksXG4gICAgbW06IHN0cmluZyA9IHR3b0RpZ2l0UGFkKG1pbnV0ZSksXG4gICAgc3M6IHN0cmluZyA9IHR3b0RpZ2l0UGFkKHNlY29uZCksXG4gICAgYWFhOiBzdHJpbmcgPSBob3VyIDwgMTIgPyBcIkFNXCIgOiBcIlBNXCIsXG4gICAgRUVFRTogc3RyaW5nID0gREFZU19PRl9XRUVLX05BTUVTW2RhdGUuZ2V0RGF5KCldLFxuICAgIEVFRTogc3RyaW5nID0gRUVFRS5zdWJzdHIoMCwgMyksXG4gICAgZGQ6IHN0cmluZyA9IHR3b0RpZ2l0UGFkKGRheSksXG4gICAgTTogbnVtYmVyID0gbW9udGggKyAxLFxuICAgIE1NOiBzdHJpbmcgPSB0d29EaWdpdFBhZChNKSxcbiAgICBNTU1NOiBzdHJpbmcgPSBNT05USF9OQU1FU1ttb250aF0sXG4gICAgTU1NOiBzdHJpbmcgPSBNTU1NLnN1YnN0cigwLCAzKSxcbiAgICB5eXl5OiBzdHJpbmcgPSB5ZWFyICsgXCJcIixcbiAgICB5eTogc3RyaW5nID0geXl5eS5zdWJzdHIoMiwgMik7XG4gIC8vIGNoZWNrcyB0byBzZWUgaWYgbW9udGggbmFtZSB3aWxsIGJlIHVzZWRcbiAgcGF0dGVyblN0ciA9IHBhdHRlcm5TdHJcbiAgICAucmVwbGFjZShcImhoXCIsIGhoKVxuICAgIC5yZXBsYWNlKFwiaFwiLCBoLnRvU3RyaW5nKCkpXG4gICAgLnJlcGxhY2UoXCJISFwiLCBISClcbiAgICAucmVwbGFjZShcIkhcIiwgaG91ci50b1N0cmluZygpKVxuICAgIC5yZXBsYWNlKFwibW1cIiwgbW0pXG4gICAgLnJlcGxhY2UoXCJtXCIsIG1pbnV0ZS50b1N0cmluZygpKVxuICAgIC5yZXBsYWNlKFwic3NcIiwgc3MpXG4gICAgLnJlcGxhY2UoXCJzXCIsIHNlY29uZC50b1N0cmluZygpKVxuICAgIC5yZXBsYWNlKFwiU1wiLCBtaWxpc2Vjb25kcy50b1N0cmluZygpKVxuICAgIC5yZXBsYWNlKFwiZGRcIiwgZGQpXG4gICAgLnJlcGxhY2UoXCJkXCIsIGRheS50b1N0cmluZygpKVxuXG4gICAgLnJlcGxhY2UoXCJFRUVFXCIsIEVFRUUpXG4gICAgLnJlcGxhY2UoXCJFRUVcIiwgRUVFKVxuICAgIC5yZXBsYWNlKFwieXl5eVwiLCB5eXl5KVxuICAgIC5yZXBsYWNlKFwieXlcIiwgeXkpXG4gICAgLnJlcGxhY2UoXCJhYWFcIiwgYWFhKTtcbiAgaWYgKHBhdHRlcm5TdHIuaW5kZXhPZihcIk1NTVwiKSA+IC0xKSB7XG4gICAgcGF0dGVyblN0ciA9IHBhdHRlcm5TdHIucmVwbGFjZShcIk1NTU1cIiwgTU1NTSkucmVwbGFjZShcIk1NTVwiLCBNTU0pO1xuICB9IGVsc2Uge1xuICAgIHBhdHRlcm5TdHIgPSBwYXR0ZXJuU3RyLnJlcGxhY2UoXCJNTVwiLCBNTSkucmVwbGFjZShcIk1cIiwgTS50b1N0cmluZygpKTtcbiAgfVxuICByZXR1cm4gcGF0dGVyblN0cjtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBQYXJzZXMgYSBkYXRlIGZyb20gYSBzcGVjaWZpZWQgZm9ybWF0XG4gKiBAcGFyYW0ge3N0cmluZ30gZm9ybWF0XG4gKiBAcGFyYW0ge3N0cmluZyB8IERhdGUgfCBudW1iZXJ9IFt2XVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICogQGNhdGVnb3J5IE1vZGVsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZURhdGUoZm9ybWF0OiBzdHJpbmcsIHY/OiBzdHJpbmcgfCBEYXRlIHwgbnVtYmVyKSB7XG4gIGxldCB2YWx1ZTogRGF0ZSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICBpZiAoIXYpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgaWYgKHYgaW5zdGFuY2VvZiBEYXRlKVxuICAgIHRyeSB7XG4gICAgICB2YWx1ZSA9IGRhdGVGcm9tRm9ybWF0KGZvcm1hdERhdGUodiBhcyBEYXRlLCBmb3JtYXQpLCBmb3JtYXQpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBzZihcIkNvdWxkIG5vdCBjb252ZXJ0IGRhdGUgezB9IHRvIGZvcm1hdDogezF9XCIsIHYudG9TdHJpbmcoKSwgZm9ybWF0KVxuICAgICAgKTtcbiAgICB9XG4gIGVsc2UgaWYgKHR5cGVvZiB2ID09PSBcInN0cmluZ1wiKSB7XG4gICAgdmFsdWUgPSBkYXRlRnJvbUZvcm1hdCh2LCBmb3JtYXQpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiB2ID09PSBcIm51bWJlclwiKSB7XG4gICAgY29uc3QgZCA9IG5ldyBEYXRlKHYpO1xuICAgIHZhbHVlID0gZGF0ZUZyb21Gb3JtYXQoZm9ybWF0RGF0ZShkLCBmb3JtYXQpLCBmb3JtYXQpO1xuICB9IGVsc2UgaWYgKGlzVmFsaWREYXRlKHYpKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGQgPSBuZXcgRGF0ZSh2KTtcbiAgICAgIHZhbHVlID0gZGF0ZUZyb21Gb3JtYXQoZm9ybWF0RGF0ZShkLCBmb3JtYXQpLCBmb3JtYXQpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgc2YoXCJDb3VsZCBub3QgY29udmVydCBkYXRlIHswfSB0byBmb3JtYXQ6IHsxfVwiLCB2LCBmb3JtYXQpXG4gICAgICApO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgdmFsdWUgcHJvdmlkZWQgJHt2fWApO1xuICB9XG4gIHJldHVybiBiaW5kRGF0ZVRvU3RyaW5nKHZhbHVlLCBmb3JtYXQpO1xufVxuIiwiaW1wb3J0IHtcbiAgRGVjb3JhdGlvbkJ1aWxkZXJCdWlsZCxcbiAgRGVjb3JhdGlvbkJ1aWxkZXJFbmQsXG4gIERlY29yYXRpb25CdWlsZGVyTWlkLFxuICBEZWNvcmF0aW9uQnVpbGRlclN0YXJ0LFxuICBGbGF2b3VyUmVzb2x2ZXIsXG4gIElEZWNvcmF0aW9uQnVpbGRlcixcbn0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IERlZmF1bHRGbGF2b3VyIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbmZ1bmN0aW9uIGRlZmF1bHRGbGF2b3VyUmVzb2x2ZXIodGFyZ2V0OiBvYmplY3QpIHtcbiAgcmV0dXJuIERlZmF1bHRGbGF2b3VyO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBIGRlY29yYXRvciBtYW5hZ2VtZW50IGNsYXNzIHRoYXQgaGFuZGxlcyBmbGF2b3VyZWQgZGVjb3JhdG9yc1xuICogQHN1bW1hcnkgVGhlIERlY29yYXRpb24gY2xhc3MgcHJvdmlkZXMgYSBidWlsZGVyIHBhdHRlcm4gZm9yIGNyZWF0aW5nIGFuZCBtYW5hZ2luZyBkZWNvcmF0b3JzIHdpdGggZGlmZmVyZW50IGZsYXZvdXJzLlxuICogSXQgc3VwcG9ydHMgcmVnaXN0ZXJpbmcsIGV4dGVuZGluZywgYW5kIGFwcGx5aW5nIGRlY29yYXRvcnMgd2l0aCBjb250ZXh0LWF3YXJlIGZsYXZvdXIgcmVzb2x1dGlvbi5cbiAqIFRoZSBjbGFzcyBpbXBsZW1lbnRzIGEgZmx1ZW50IGludGVyZmFjZSBmb3IgZGVmaW5pbmcsIGV4dGVuZGluZywgYW5kIGFwcGx5aW5nIGRlY29yYXRvcnMgd2l0aCBkaWZmZXJlbnQgZmxhdm91cnMsXG4gKiBhbGxvd2luZyBmb3IgZnJhbWV3b3JrLXNwZWNpZmljIGRlY29yYXRvciBpbXBsZW1lbnRhdGlvbnMgd2hpbGUgbWFpbnRhaW5pbmcgYSBjb25zaXN0ZW50IEFQSS5cbiAqIEB0ZW1wbGF0ZSBUIFR5cGUgb2YgdGhlIGRlY29yYXRvciAoQ2xhc3NEZWNvcmF0b3IgfCBQcm9wZXJ0eURlY29yYXRvciB8IE1ldGhvZERlY29yYXRvcilcbiAqIEBwYXJhbSB7c3RyaW5nfSBbZmxhdm91cl0gT3B0aW9uYWwgZmxhdm91ciBwYXJhbWV0ZXIgZm9yIHRoZSBkZWNvcmF0b3IgY29udGV4dFxuICogQGNsYXNzXG4gKiBAY2F0ZWdvcnkgTW9kZWxcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBDcmVhdGUgYSBuZXcgZGVjb3JhdGlvbiBmb3IgJ2NvbXBvbmVudCcgd2l0aCBkZWZhdWx0IGZsYXZvdXJcbiAqIGNvbnN0IGNvbXBvbmVudERlY29yYXRvciA9IG5ldyBEZWNvcmF0aW9uKClcbiAqICAgLmZvcignY29tcG9uZW50JylcbiAqICAgLmRlZmluZShjdXN0b21Db21wb25lbnREZWNvcmF0b3IpO1xuICpcbiAqIC8vIENyZWF0ZSBhIGZsYXZvdXJlZCBkZWNvcmF0aW9uXG4gKiBjb25zdCB2dWVDb21wb25lbnQgPSBuZXcgRGVjb3JhdGlvbigndnVlJylcbiAqICAgLmZvcignY29tcG9uZW50JylcbiAqICAgLmRlZmluZSh2dWVDb21wb25lbnREZWNvcmF0b3IpO1xuICpcbiAqIC8vIEFwcGx5IHRoZSBkZWNvcmF0aW9uXG4gKiBAY29tcG9uZW50RGVjb3JhdG9yXG4gKiBjbGFzcyBNeUNvbXBvbmVudCB7fVxuICogYGBgXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IEQgYXMgRGVjb3JhdGlvblxuICogICBwYXJ0aWNpcGFudCBSIGFzIEZsYXZvdXJSZXNvbHZlclxuICogICBwYXJ0aWNpcGFudCBGIGFzIERlY29yYXRvckZhY3RvcnlcbiAqXG4gKiAgIEMtPj5EOiBuZXcgRGVjb3JhdGlvbihmbGF2b3VyKVxuICogICBDLT4+RDogZm9yKGtleSlcbiAqICAgQy0+PkQ6IGRlZmluZShkZWNvcmF0b3JzKVxuICogICBELT4+RDogcmVnaXN0ZXIoa2V5LCBmbGF2b3VyLCBkZWNvcmF0b3JzKVxuICogICBELT4+RjogZGVjb3JhdG9yRmFjdG9yeShrZXksIGZsYXZvdXIpXG4gKiAgIEYtPj5SOiByZXNvbHZlKHRhcmdldClcbiAqICAgUi0tPj5GOiByZXNvbHZlZCBmbGF2b3VyXG4gKiAgIEYtPj5GOiBhcHBseSBkZWNvcmF0b3JzXG4gKiAgIEYtLT4+QzogZGVjb3JhdGVkIHRhcmdldFxuICovXG5leHBvcnQgY2xhc3MgRGVjb3JhdGlvbiBpbXBsZW1lbnRzIElEZWNvcmF0aW9uQnVpbGRlciB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU3RhdGljIG1hcCBvZiByZWdpc3RlcmVkIGRlY29yYXRvcnNcbiAgICogQHN1bW1hcnkgU3RvcmVzIGFsbCByZWdpc3RlcmVkIGRlY29yYXRvcnMgb3JnYW5pemVkIGJ5IGtleSBhbmQgZmxhdm91clxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZGVjb3JhdG9yczogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICBSZWNvcmQ8XG4gICAgICBzdHJpbmcsXG4gICAgICB7XG4gICAgICAgIGRlY29yYXRvcnM/OiBTZXQ8Q2xhc3NEZWNvcmF0b3IgfCBQcm9wZXJ0eURlY29yYXRvciB8IE1ldGhvZERlY29yYXRvcj47XG4gICAgICAgIGV4dHJhcz86IFNldDxDbGFzc0RlY29yYXRvciB8IFByb3BlcnR5RGVjb3JhdG9yIHwgTWV0aG9kRGVjb3JhdG9yPjtcbiAgICAgIH1cbiAgICA+XG4gID4gPSB7fTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEZ1bmN0aW9uIHRvIHJlc29sdmUgZmxhdm91ciBmcm9tIGEgdGFyZ2V0XG4gICAqIEBzdW1tYXJ5IFJlc29sdmVyIGZ1bmN0aW9uIHRoYXQgZGV0ZXJtaW5lcyB0aGUgYXBwcm9wcmlhdGUgZmxhdm91ciBmb3IgYSBnaXZlbiB0YXJnZXRcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGZsYXZvdXJSZXNvbHZlcjogRmxhdm91clJlc29sdmVyID0gZGVmYXVsdEZsYXZvdXJSZXNvbHZlcjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldCBvZiBkZWNvcmF0b3JzIGZvciB0aGUgY3VycmVudCBjb250ZXh0XG4gICAqL1xuICBwcml2YXRlIGRlY29yYXRvcnM/OiBTZXQ8XG4gICAgQ2xhc3NEZWNvcmF0b3IgfCBQcm9wZXJ0eURlY29yYXRvciB8IE1ldGhvZERlY29yYXRvclxuICA+O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0IG9mIGFkZGl0aW9uYWwgZGVjb3JhdG9yc1xuICAgKi9cbiAgcHJpdmF0ZSBleHRyYXM/OiBTZXQ8Q2xhc3NEZWNvcmF0b3IgfCBQcm9wZXJ0eURlY29yYXRvciB8IE1ldGhvZERlY29yYXRvcj47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDdXJyZW50IGRlY29yYXRvciBrZXlcbiAgICovXG4gIHByaXZhdGUga2V5Pzogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZmxhdm91cjogc3RyaW5nID0gRGVmYXVsdEZsYXZvdXIpIHt9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBrZXkgZm9yIHRoZSBkZWNvcmF0aW9uIGJ1aWxkZXJcbiAgICogQHN1bW1hcnkgSW5pdGlhbGl6ZXMgYSBuZXcgZGVjb3JhdGlvbiBjaGFpbiB3aXRoIHRoZSBzcGVjaWZpZWQga2V5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGlkZW50aWZpZXIgZm9yIHRoZSBkZWNvcmF0b3JcbiAgICogQHJldHVybiB7RGVjb3JhdGlvbkJ1aWxkZXJNaWR9IEJ1aWxkZXIgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZ1xuICAgKi9cbiAgZm9yKGtleTogc3RyaW5nKTogRGVjb3JhdGlvbkJ1aWxkZXJNaWQge1xuICAgIHRoaXMua2V5ID0ga2V5O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBZGRzIGRlY29yYXRvcnMgdG8gdGhlIGN1cnJlbnQgY29udGV4dFxuICAgKiBAc3VtbWFyeSBJbnRlcm5hbCBtZXRob2QgdG8gYWRkIGRlY29yYXRvcnMgd2l0aCBhZGRvbiBzdXBwb3J0XG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2FkZG9uPWZhbHNlXSBXaGV0aGVyIHRoZSBkZWNvcmF0b3JzIGFyZSBhZGRvbnNcbiAgICogQHBhcmFtIGRlY29yYXRvcnMgQXJyYXkgb2YgZGVjb3JhdG9yc1xuICAgKiBAcmV0dXJuIHt0aGlzfSBDdXJyZW50IGluc3RhbmNlIGZvciBjaGFpbmluZ1xuICAgKi9cbiAgcHJpdmF0ZSBkZWNvcmF0ZShcbiAgICBhZGRvbjogYm9vbGVhbiA9IGZhbHNlLFxuICAgIC4uLmRlY29yYXRvcnM6IChDbGFzc0RlY29yYXRvciB8IFByb3BlcnR5RGVjb3JhdG9yIHwgTWV0aG9kRGVjb3JhdG9yKVtdXG4gICk6IHRoaXMge1xuICAgIGlmICghdGhpcy5rZXkpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJrZXkgbXVzdCBiZSBwcm92aWRlZCBiZWZvcmUgZGVjb3JhdG9ycyBjYW4gYmUgYWRkZWRcIik7XG4gICAgaWYgKCFhZGRvbiAmJiAhdGhpcy5kZWNvcmF0b3JzICYmIHRoaXMuZmxhdm91ciAhPT0gRGVmYXVsdEZsYXZvdXIpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiTXVzdCBwcm92aWRlIG92ZXJyaWRlcyBvciBhZGRvbnMgdG8gb3ZlcnJpZGUgb3IgZXh0ZW5kIGRlY2FmJ3MgZGVjb3JhdG9yc1wiXG4gICAgICApO1xuICAgIGlmICh0aGlzLmZsYXZvdXIgPT09IERlZmF1bHRGbGF2b3VyICYmIGFkZG9uKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRGVmYXVsdCBmbGF2b3VyIGNhbm5vdCBiZSBleHRlbmRlZFwiKTtcblxuICAgIHRoaXNbYWRkb24gPyBcImV4dHJhc1wiIDogXCJkZWNvcmF0b3JzXCJdID0gbmV3IFNldChbXG4gICAgICAuLi4odGhpc1thZGRvbiA/IFwiZXh0cmFzXCIgOiBcImRlY29yYXRvcnNcIl0gfHwgbmV3IFNldCgpKS52YWx1ZXMoKSxcbiAgICAgIC4uLmRlY29yYXRvcnMsXG4gICAgXSk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRGVmaW5lcyB0aGUgYmFzZSBkZWNvcmF0b3JzXG4gICAqIEBzdW1tYXJ5IFNldHMgdGhlIHByaW1hcnkgZGVjb3JhdG9ycyBmb3IgdGhlIGN1cnJlbnQgY29udGV4dFxuICAgKiBAcGFyYW0gZGVjb3JhdG9ycyBEZWNvcmF0b3JzIHRvIGRlZmluZVxuICAgKiBAcmV0dXJuIEJ1aWxkZXIgaW5zdGFuY2UgZm9yIGZpbmlzaGluZyB0aGUgY2hhaW5cbiAgICovXG4gIGRlZmluZShcbiAgICAuLi5kZWNvcmF0b3JzOiAoQ2xhc3NEZWNvcmF0b3IgfCBQcm9wZXJ0eURlY29yYXRvciB8IE1ldGhvZERlY29yYXRvcilbXVxuICApOiBEZWNvcmF0aW9uQnVpbGRlckVuZCAmIERlY29yYXRpb25CdWlsZGVyQnVpbGQge1xuICAgIHJldHVybiB0aGlzLmRlY29yYXRlKGZhbHNlLCAuLi5kZWNvcmF0b3JzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRXh0ZW5kcyBleGlzdGluZyBkZWNvcmF0b3JzXG4gICAqIEBzdW1tYXJ5IEFkZHMgYWRkaXRpb25hbCBkZWNvcmF0b3JzIHRvIHRoZSBjdXJyZW50IGNvbnRleHRcbiAgICogQHBhcmFtIGRlY29yYXRvcnMgQWRkaXRpb25hbCBkZWNvcmF0b3JzXG4gICAqIEByZXR1cm4ge0RlY29yYXRpb25CdWlsZGVyQnVpbGR9IEJ1aWxkZXIgaW5zdGFuY2UgZm9yIGJ1aWxkaW5nIHRoZSBkZWNvcmF0b3JcbiAgICovXG4gIGV4dGVuZChcbiAgICAuLi5kZWNvcmF0b3JzOiAoQ2xhc3NEZWNvcmF0b3IgfCBQcm9wZXJ0eURlY29yYXRvciB8IE1ldGhvZERlY29yYXRvcilbXVxuICApOiBEZWNvcmF0aW9uQnVpbGRlckJ1aWxkIHtcbiAgICByZXR1cm4gdGhpcy5kZWNvcmF0ZSh0cnVlLCAuLi5kZWNvcmF0b3JzKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBkZWNvcmF0b3JGYWN0b3J5KGtleTogc3RyaW5nLCBmOiBzdHJpbmcgPSBEZWZhdWx0Rmxhdm91cikge1xuICAgIGNvbnN0IGNvbnRleHREZWNvcmF0b3IgPSBmdW5jdGlvbiBjb250ZXh0RGVjb3JhdG9yKFxuICAgICAgdGFyZ2V0OiBvYmplY3QsXG4gICAgICBwcm9wZXJ0eUtleT86IGFueSxcbiAgICAgIGRlc2NyaXB0b3I/OiBUeXBlZFByb3BlcnR5RGVzY3JpcHRvcjxhbnk+XG4gICAgKSB7XG4gICAgICBjb25zdCBmbGF2b3VyID0gRGVjb3JhdGlvbi5mbGF2b3VyUmVzb2x2ZXIodGFyZ2V0KTtcbiAgICAgIGxldCBkZWNvcmF0b3JzO1xuICAgICAgY29uc3QgZXh0cmFzID0gRGVjb3JhdGlvbi5kZWNvcmF0b3JzW2tleV1bZmxhdm91cl0uZXh0cmFzO1xuICAgICAgaWYgKFxuICAgICAgICBEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XSAmJlxuICAgICAgICBEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XVtmbGF2b3VyXSAmJlxuICAgICAgICBEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XVtmbGF2b3VyXS5kZWNvcmF0b3JzXG4gICAgICApIHtcbiAgICAgICAgZGVjb3JhdG9ycyA9IERlY29yYXRpb24uZGVjb3JhdG9yc1trZXldW2ZsYXZvdXJdLmRlY29yYXRvcnM7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWNvcmF0b3JzID0gRGVjb3JhdGlvbi5kZWNvcmF0b3JzW2tleV1bRGVmYXVsdEZsYXZvdXJdLmRlY29yYXRvcnM7XG4gICAgICB9XG4gICAgICBbXG4gICAgICAgIC4uLihkZWNvcmF0b3JzID8gZGVjb3JhdG9ycy52YWx1ZXMoKSA6IFtdKSxcbiAgICAgICAgLi4uKGV4dHJhcyA/IGV4dHJhcy52YWx1ZXMoKSA6IFtdKSxcbiAgICAgIF0uZm9yRWFjaCgoZCkgPT4gKGQgYXMgYW55KSh0YXJnZXQsIHByb3BlcnR5S2V5LCBkZXNjcmlwdG9yLCBkZXNjcmlwdG9yKSk7XG4gICAgICAvLyByZXR1cm4gYXBwbHkoXG4gICAgICAvL1xuICAgICAgLy8gKSh0YXJnZXQsIHByb3BlcnR5S2V5LCBkZXNjcmlwdG9yKTtcbiAgICB9O1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb250ZXh0RGVjb3JhdG9yLCBcIm5hbWVcIiwge1xuICAgICAgdmFsdWU6IFtmLCBrZXldLmpvaW4oXCJfZGVjb3JhdG9yX2Zvcl9cIiksXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgfSk7XG4gICAgcmV0dXJuIGNvbnRleHREZWNvcmF0b3I7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgdGhlIGZpbmFsIGRlY29yYXRvciBmdW5jdGlvblxuICAgKiBAc3VtbWFyeSBCdWlsZHMgYW5kIHJldHVybnMgdGhlIGRlY29yYXRvciBmYWN0b3J5IGZ1bmN0aW9uXG4gICAqIEByZXR1cm4ge2Z1bmN0aW9uKG9iamVjdCwgYW55PywgVHlwZWRQcm9wZXJ0eURlc2NyaXB0b3I/KTogYW55fSBUaGUgZ2VuZXJhdGVkIGRlY29yYXRvciBmdW5jdGlvblxuICAgKi9cbiAgYXBwbHkoKTogKFxuICAgIHRhcmdldDogb2JqZWN0LFxuICAgIHByb3BlcnR5S2V5PzogYW55LFxuICAgIGRlc2NyaXB0b3I/OiBUeXBlZFByb3BlcnR5RGVzY3JpcHRvcjxhbnk+XG4gICkgPT4gYW55IHtcbiAgICBpZiAoIXRoaXMua2V5KVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8ga2V5IHByb3ZpZGVkIGZvciB0aGUgZGVjb3JhdGlvbiBidWlsZGVyXCIpO1xuICAgIERlY29yYXRpb24ucmVnaXN0ZXIodGhpcy5rZXksIHRoaXMuZmxhdm91ciwgdGhpcy5kZWNvcmF0b3JzLCB0aGlzLmV4dHJhcyk7XG4gICAgcmV0dXJuIHRoaXMuZGVjb3JhdG9yRmFjdG9yeSh0aGlzLmtleSwgdGhpcy5mbGF2b3VyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVnaXN0ZXJzIGRlY29yYXRvcnMgZm9yIGEgc3BlY2lmaWMga2V5IGFuZCBmbGF2b3VyXG4gICAqIEBzdW1tYXJ5IEludGVybmFsIG1ldGhvZCB0byBzdG9yZSBkZWNvcmF0b3JzIGluIHRoZSBzdGF0aWMgcmVnaXN0cnlcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBEZWNvcmF0b3Iga2V5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmbGF2b3VyIERlY29yYXRvciBmbGF2b3VyXG4gICAqIEBwYXJhbSBbZGVjb3JhdG9yc10gUHJpbWFyeSBkZWNvcmF0b3JzXG4gICAqIEBwYXJhbSBbZXh0cmFzXSBBZGRpdGlvbmFsIGRlY29yYXRvcnNcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHJlZ2lzdGVyKFxuICAgIGtleTogc3RyaW5nLFxuICAgIGZsYXZvdXI6IHN0cmluZyxcbiAgICBkZWNvcmF0b3JzPzogU2V0PENsYXNzRGVjb3JhdG9yIHwgUHJvcGVydHlEZWNvcmF0b3IgfCBNZXRob2REZWNvcmF0b3I+LFxuICAgIGV4dHJhcz86IFNldDxDbGFzc0RlY29yYXRvciB8IFByb3BlcnR5RGVjb3JhdG9yIHwgTWV0aG9kRGVjb3JhdG9yPlxuICApIHtcbiAgICBpZiAoIWtleSkgdGhyb3cgbmV3IEVycm9yKFwiTm8ga2V5IHByb3ZpZGVkIGZvciB0aGUgZGVjb3JhdGlvbiBidWlsZGVyXCIpO1xuICAgIGlmICghZGVjb3JhdG9ycylcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGRlY29yYXRvcnMgcHJvdmlkZWQgZm9yIHRoZSBkZWNvcmF0aW9uIGJ1aWxkZXJcIik7XG4gICAgaWYgKCFmbGF2b3VyKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gZmxhdm91ciBwcm92aWRlZCBmb3IgdGhlIGRlY29yYXRpb24gYnVpbGRlclwiKTtcblxuICAgIGlmICghRGVjb3JhdGlvbi5kZWNvcmF0b3JzW2tleV0pIERlY29yYXRpb24uZGVjb3JhdG9yc1trZXldID0ge307XG4gICAgaWYgKCFEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XVtmbGF2b3VyXSlcbiAgICAgIERlY29yYXRpb24uZGVjb3JhdG9yc1trZXldW2ZsYXZvdXJdID0ge307XG4gICAgaWYgKGRlY29yYXRvcnMpIERlY29yYXRpb24uZGVjb3JhdG9yc1trZXldW2ZsYXZvdXJdLmRlY29yYXRvcnMgPSBkZWNvcmF0b3JzO1xuICAgIGlmIChleHRyYXMpIERlY29yYXRpb24uZGVjb3JhdG9yc1trZXldW2ZsYXZvdXJdLmV4dHJhcyA9IGV4dHJhcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgZ2xvYmFsIGZsYXZvdXIgcmVzb2x2ZXJcbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgZnVuY3Rpb24gdXNlZCB0byBkZXRlcm1pbmUgZGVjb3JhdG9yIGZsYXZvdXJzXG4gICAqIEBwYXJhbSB7Rmxhdm91clJlc29sdmVyfSByZXNvbHZlciBGdW5jdGlvbiB0byByZXNvbHZlIGZsYXZvdXJzXG4gICAqL1xuICBzdGF0aWMgc2V0Rmxhdm91clJlc29sdmVyKHJlc29sdmVyOiBGbGF2b3VyUmVzb2x2ZXIpIHtcbiAgICBEZWNvcmF0aW9uLmZsYXZvdXJSZXNvbHZlciA9IHJlc29sdmVyO1xuICB9XG5cbiAgc3RhdGljIGZvcihrZXk6IHN0cmluZyk6IERlY29yYXRpb25CdWlsZGVyTWlkIHtcbiAgICByZXR1cm4gbmV3IERlY29yYXRpb24oKS5mb3Ioa2V5KTtcbiAgfVxuXG4gIHN0YXRpYyBmbGF2b3VyZWRBcyhmbGF2b3VyOiBzdHJpbmcpOiBEZWNvcmF0aW9uQnVpbGRlclN0YXJ0IHtcbiAgICByZXR1cm4gbmV3IERlY29yYXRpb24oZmxhdm91cik7XG4gIH1cbn1cbiIsImltcG9ydCB7IGFwcGx5LCBtZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgTW9kZWxLZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFByb3BlcnR5IGRlY29yYXRvciBmYWN0b3J5IGZvciBtb2RlbCBhdHRyaWJ1dGVzXG4gKiBAc3VtbWFyeSBDcmVhdGVzIGEgZGVjb3JhdG9yIHRoYXQgbWFya3MgY2xhc3MgcHJvcGVydGllcyBhcyBtb2RlbCBhdHRyaWJ1dGVzLiBUaGUgZGVjb3JhdG9yIG1haW50YWlucyBhIGxpc3RcbiAqIG9mIHByb3BlcnR5IGtleXMgdW5kZXIgYSBzcGVjaWZpZWQgbWV0YWRhdGEga2V5IGluIHRoZSBtb2RlbC4gSWYgdGhlIGtleSBkb2Vzbid0IGV4aXN0LCBpdCBjcmVhdGVzIGEgbmV3IGFycmF5O1xuICogaWYgaXQgZXhpc3RzLCBpdCBhcHBlbmRzIHRoZSBwcm9wZXJ0eSBrZXkgdG8gdGhlIGV4aXN0aW5nIGFycmF5LCBhdm9pZGluZyBkdXBsaWNhdGVzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBba2V5PU1vZGVsS2V5cy5BVFRSSUJVVEVdIC0gVGhlIG1ldGFkYXRhIGtleSB1bmRlciB3aGljaCB0byBzdG9yZSB0aGUgcHJvcGVydHkgbmFtZVxuICogQHJldHVybiB7ZnVuY3Rpb24ob2JqZWN0LCBhbnk/KTogdm9pZH0gRGVjb3JhdG9yIGZ1bmN0aW9uIHRoYXQgcmVnaXN0ZXJzIHRoZSBwcm9wZXJ0eVxuICpcbiAqIEBmdW5jdGlvbiBwcm9wXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgIHBhcnRpY2lwYW50IEQgYXMgRGVjb3JhdG9yXG4gKiAgICBwYXJ0aWNpcGFudCBNIGFzIE1vZGVsXG4gKlxuICogICAgRC0+Pk06IENoZWNrIGlmIGtleSBleGlzdHNcbiAqICAgIGFsdCBrZXkgZXhpc3RzXG4gKiAgICAgICAgTS0tPj5EOiBSZXR1cm4gZXhpc3RpbmcgcHJvcHMgYXJyYXlcbiAqICAgIGVsc2Uga2V5IGRvZXNuJ3QgZXhpc3RcbiAqICAgICAgICBELT4+TTogQ3JlYXRlIG5ldyBwcm9wcyBhcnJheVxuICogICAgZW5kXG4gKiAgICBELT4+TTogQ2hlY2sgaWYgcHJvcGVydHkgZXhpc3RzXG4gKiAgICBhbHQgcHJvcGVydHkgbm90IGluIGFycmF5XG4gKiAgICAgICAgRC0+Pk06IEFkZCBwcm9wZXJ0eSB0byBhcnJheVxuICogICAgZW5kXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm9wKGtleTogc3RyaW5nID0gTW9kZWxLZXlzLkFUVFJJQlVURSkge1xuICByZXR1cm4gKG1vZGVsOiBvYmplY3QsIHByb3BlcnR5S2V5PzogYW55KTogdm9pZCA9PiB7XG4gICAgbGV0IHByb3BzOiBzdHJpbmdbXTtcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZGVsLCBrZXkpKSB7XG4gICAgICBwcm9wcyA9IChtb2RlbCBhcyBhbnkpW2tleV07XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb3BzID0gKG1vZGVsIGFzIGFueSlba2V5XSA9IFtdO1xuICAgIH1cbiAgICBpZiAoIXByb3BzLmluY2x1ZGVzKHByb3BlcnR5S2V5IGFzIHN0cmluZykpXG4gICAgICBwcm9wcy5wdXNoKHByb3BlcnR5S2V5IGFzIHN0cmluZyk7XG4gIH07XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvbWJpbmVkIHByb3BlcnR5IGRlY29yYXRvciBmYWN0b3J5IGZvciBtZXRhZGF0YSBhbmQgYXR0cmlidXRlIG1hcmtpbmdcbiAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBkZWNvcmF0b3IgdGhhdCBib3RoIG1hcmtzIGEgcHJvcGVydHkgYXMgYSBtb2RlbCBhdHRyaWJ1dGUgYW5kIGFzc2lnbnMgbWV0YWRhdGEgdG8gaXQuXG4gKiBDb21iaW5lcyB0aGUgZnVuY3Rpb25hbGl0eSBvZiBwcm9wKCkgYW5kIG1ldGFkYXRhKCkgZGVjb3JhdG9ycy5cbiAqXG4gKiBAdGVtcGxhdGUgViAtIFRoZSB0eXBlIG9mIHRoZSBtZXRhZGF0YSB2YWx1ZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSBtZXRhZGF0YSBrZXlcbiAqIEBwYXJhbSB7Vn0gdmFsdWUgLSBUaGUgbWV0YWRhdGEgdmFsdWUgdG8gYXNzb2NpYXRlIHdpdGggdGhlIHByb3BlcnR5XG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQ29tYmluZWQgZGVjb3JhdG9yIGZ1bmN0aW9uXG4gKlxuICogQGZ1bmN0aW9uIHByb3BNZXRhZGF0YVxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByb3BNZXRhZGF0YTxWPihrZXk6IHN0cmluZywgdmFsdWU6IFYpIHtcbiAgcmV0dXJuIGFwcGx5KHByb3AoKSwgbWV0YWRhdGE8Vj4oa2V5LCB2YWx1ZSkpO1xufVxuIiwiLyoqXG4gKiBAc3VtbWFyeSBNaW1pY3MgSmF2YSdzIFN0cmluZydzIEhhc2ggaW1wbGVtZW50YXRpb25cbiAqXG4gKiBAcGFyYW0ge3N0cmluZyB8IG51bWJlciB8IHN5bWJvbCB8IERhdGV9IG9ialxuICogQHJldHVybiB7bnVtYmVyfSBoYXNoIHZhbHVlIG9mIG9ialxuICpcbiAqIEBmdW5jdGlvbiBoYXNoQ29kZVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICogQGNhdGVnb3J5IE1vZGVsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNoQ29kZShvYmo6IHN0cmluZyB8IG51bWJlciB8IHN5bWJvbCB8IERhdGUpOiBzdHJpbmcge1xuICBvYmogPSBTdHJpbmcob2JqKTtcbiAgbGV0IGhhc2ggPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGNoYXJhY3RlciA9IG9iai5jaGFyQ29kZUF0KGkpO1xuICAgIGhhc2ggPSAoaGFzaCA8PCA1KSAtIGhhc2ggKyBjaGFyYWN0ZXI7XG4gICAgaGFzaCA9IGhhc2ggJiBoYXNoOyAvLyBDb252ZXJ0IHRvIDMyYml0IGludGVnZXJcbiAgfVxuICByZXR1cm4gaGFzaC50b1N0cmluZygpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgdGVoIHR5cGUgZm9yIGEgSGFzaGluZyBmdW5jdGlvblxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICogQGNhdGVnb3J5IE1vZGVsXG4gKi9cbmV4cG9ydCB0eXBlIEhhc2hpbmdGdW5jdGlvbiA9ICh2YWx1ZTogYW55LCAuLi5hcmdzOiBhbnlbXSkgPT4gc3RyaW5nO1xuXG4vKipcbiAqIEBzdW1tYXJ5IEhhc2hlcyBhbiBvYmplY3QgYnkgY29tYmluaW5nIHRoZSBoYXNoIG9mIGFsbCBpdHMgcHJvcGVydGllc1xuICpcbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gb2JqXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHRoZSByZXN1bHRpbmcgaGFzaFxuICpcbiAqIEBmdW5jdGlvbiBoYXNoT2JqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgTW9kZWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc2hPYmoob2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgYW55W10pOiBzdHJpbmcge1xuICBjb25zdCBoYXNoUmVkdWNlciA9IGZ1bmN0aW9uIChoOiBudW1iZXIgfCBzdHJpbmcsIGVsOiBhbnkpOiBzdHJpbmcgfCBudW1iZXIge1xuICAgIGNvbnN0IGVsSGFzaCA9IGhhc2hGdW5jdGlvbihlbCk7XG5cbiAgICBpZiAodHlwZW9mIGVsSGFzaCA9PT0gXCJzdHJpbmdcIilcbiAgICAgIHJldHVybiBoYXNoRnVuY3Rpb24oKChoIGFzIHN0cmluZykgfHwgXCJcIikgKyBoYXNoRnVuY3Rpb24oZWwpKTtcblxuICAgIGggPSBoIHx8IDA7XG4gICAgaCA9ICgoaCBhcyBudW1iZXIpIDw8IDUpIC0gKGggYXMgbnVtYmVyKSArIGVsSGFzaDtcbiAgICByZXR1cm4gaCAmIGg7XG4gIH07XG5cbiAgY29uc3QgZnVuYzogSGFzaGluZ0Z1bmN0aW9uID0gaGFzaENvZGU7XG5cbiAgY29uc3QgaGFzaEZ1bmN0aW9uID0gZnVuY3Rpb24gKHZhbHVlOiBhbnkpOiBzdHJpbmcgfCBudW1iZXIge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIpIHJldHVybiBcIlwiO1xuICAgIGlmIChbXCJzdHJpbmdcIiwgXCJudW1iZXJcIiwgXCJzeW1ib2xcIl0uaW5kZXhPZih0eXBlb2YgdmFsdWUpICE9PSAtMSlcbiAgICAgIHJldHVybiBmdW5jKHZhbHVlLnRvU3RyaW5nKCkpO1xuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHJldHVybiBmdW5jKHZhbHVlLmdldFRpbWUoKSk7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSByZXR1cm4gdmFsdWUucmVkdWNlKGhhc2hSZWR1Y2VyLCB1bmRlZmluZWQpO1xuICAgIHJldHVybiAoT2JqZWN0LnZhbHVlcyh2YWx1ZSkgYXMgKHN0cmluZyB8IG51bWJlcilbXSkucmVkdWNlKFxuICAgICAgaGFzaFJlZHVjZXIsXG4gICAgICB1bmRlZmluZWQgYXMgdW5rbm93biBhcyBzdHJpbmcgfCBudW1iZXJcbiAgICApO1xuICB9O1xuXG4gIGNvbnN0IHJlc3VsdCA9IE9iamVjdC52YWx1ZXMob2JqKS5yZWR1Y2UoaGFzaFJlZHVjZXIsIDApO1xuXG4gIHJldHVybiAodHlwZW9mIHJlc3VsdCA9PT0gXCJudW1iZXJcIiA/IE1hdGguYWJzKHJlc3VsdCkgOiByZXN1bHQpLnRvU3RyaW5nKCk7XG59XG5cbmV4cG9ydCBjb25zdCBEZWZhdWx0SGFzaGluZ01ldGhvZCA9IFwiZGVmYXVsdFwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNYW5hZ2VzIGhhc2hpbmcgbWV0aG9kcyBhbmQgcHJvdmlkZXMgYSB1bmlmaWVkIGhhc2hpbmcgaW50ZXJmYWNlXG4gKiBAc3VtbWFyeSBBIHV0aWxpdHkgY2xhc3MgdGhhdCBwcm92aWRlcyBhIHJlZ2lzdHJ5IGZvciBkaWZmZXJlbnQgaGFzaGluZyBmdW5jdGlvbnMgYW5kIG1ldGhvZHMgdG8gaGFzaCBvYmplY3RzLlxuICogVGhlIGNsYXNzIG1haW50YWlucyBhIGNhY2hlIG9mIHJlZ2lzdGVyZWQgaGFzaGluZyBmdW5jdGlvbnMgYW5kIGFsbG93cyBzZXR0aW5nIGEgZGVmYXVsdCBoYXNoaW5nIG1ldGhvZC5cbiAqIEl0IHByZXZlbnRzIGRpcmVjdCBpbnN0YW50aWF0aW9uIGFuZCBwcm92aWRlcyBzdGF0aWMgbWV0aG9kcyBmb3IgcmVnaXN0cmF0aW9uIGFuZCBoYXNoaW5nLlxuICpcbiAqIEBjbGFzcyBIYXNoaW5nXG4gKiBAY2F0ZWdvcnkgTW9kZWxcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gUmVnaXN0ZXIgYSBjdXN0b20gaGFzaGluZyBmdW5jdGlvblxuICogSGFzaGluZy5yZWdpc3RlcignbWQ1JywgKG9iaikgPT4gY3JlYXRlTUQ1SGFzaChvYmopLCB0cnVlKTtcbiAqXG4gKiAvLyBIYXNoIGFuIG9iamVjdCB1c2luZyBkZWZhdWx0IG1ldGhvZFxuICogY29uc3QgaGFzaDEgPSBIYXNoaW5nLmhhc2gobXlPYmplY3QpO1xuICpcbiAqIC8vIEhhc2ggdXNpbmcgc3BlY2lmaWMgbWV0aG9kXG4gKiBjb25zdCBoYXNoMiA9IEhhc2hpbmcuaGFzaChteU9iamVjdCwgJ21kNScpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBIYXNoaW5nIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDdXJyZW50IGRlZmF1bHQgaGFzaGluZyBtZXRob2QgaWRlbnRpZmllclxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgY3VycmVudDogc3RyaW5nID0gRGVmYXVsdEhhc2hpbmdNZXRob2Q7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDYWNoZSBvZiByZWdpc3RlcmVkIGhhc2hpbmcgZnVuY3Rpb25zXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBjYWNoZTogUmVjb3JkPHN0cmluZywgSGFzaGluZ0Z1bmN0aW9uPiA9IHtcbiAgICBkZWZhdWx0OiBoYXNoT2JqLFxuICB9O1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7fVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgcmVnaXN0ZXJlZCBoYXNoaW5nIGZ1bmN0aW9uXG4gICAqIEBzdW1tYXJ5IEZldGNoZXMgYSBoYXNoaW5nIGZ1bmN0aW9uIGZyb20gdGhlIGNhY2hlIGJ5IGl0cyBrZXkuIFRocm93cyBhbiBlcnJvciBpZiB0aGUgbWV0aG9kIGlzIG5vdCByZWdpc3RlcmVkLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gVGhlIGlkZW50aWZpZXIgb2YgdGhlIGhhc2hpbmcgZnVuY3Rpb24gdG8gcmV0cmlldmVcbiAgICogQHJldHVybiB7SGFzaGluZ0Z1bmN0aW9ufSBUaGUgcmVxdWVzdGVkIGhhc2hpbmcgZnVuY3Rpb25cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdldChrZXk6IHN0cmluZyk6IGFueSB7XG4gICAgaWYgKGtleSBpbiB0aGlzLmNhY2hlKSByZXR1cm4gdGhpcy5jYWNoZVtrZXldO1xuICAgIHRocm93IG5ldyBFcnJvcihgTm8gaGFzaGluZyBtZXRob2QgcmVnaXN0ZXJlZCB1bmRlciAke2tleX1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVnaXN0ZXJzIGEgbmV3IGhhc2hpbmcgZnVuY3Rpb25cbiAgICogQHN1bW1hcnkgQWRkcyBhIG5ldyBoYXNoaW5nIGZ1bmN0aW9uIHRvIHRoZSByZWdpc3RyeS4gT3B0aW9uYWxseSBzZXRzIGl0IGFzIHRoZSBkZWZhdWx0IG1ldGhvZC5cbiAgICogVGhyb3dzIGFuIGVycm9yIGlmIGEgbWV0aG9kIHdpdGggdGhlIHNhbWUga2V5IGlzIGFscmVhZHkgcmVnaXN0ZXJlZC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSBpZGVudGlmaWVyIGZvciB0aGUgaGFzaGluZyBmdW5jdGlvblxuICAgKi9cbiAgc3RhdGljIHJlZ2lzdGVyKFxuICAgIGtleTogc3RyaW5nLFxuICAgIGZ1bmM6IEhhc2hpbmdGdW5jdGlvbixcbiAgICBzZXREZWZhdWx0ID0gZmFsc2VcbiAgKTogdm9pZCB7XG4gICAgaWYgKGtleSBpbiB0aGlzLmNhY2hlKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBIYXNoaW5nIG1ldGhvZCAke2tleX0gYWxyZWFkeSByZWdpc3RlcmVkYCk7XG4gICAgdGhpcy5jYWNoZVtrZXldID0gZnVuYztcbiAgICBpZiAoc2V0RGVmYXVsdCkgdGhpcy5jdXJyZW50ID0ga2V5O1xuICB9XG5cbiAgc3RhdGljIGhhc2gob2JqOiBhbnksIG1ldGhvZD86IHN0cmluZywgLi4uYXJnczogYW55W10pIHtcbiAgICBpZiAoIW1ldGhvZCkgcmV0dXJuIHRoaXMuZ2V0KHRoaXMuY3VycmVudCkob2JqLCAuLi5hcmdzKTtcbiAgICByZXR1cm4gdGhpcy5nZXQobWV0aG9kKShvYmosIC4uLmFyZ3MpO1xuICB9XG5cbiAgc3RhdGljIHNldERlZmF1bHQobWV0aG9kOiBzdHJpbmcpIHtcbiAgICB0aGlzLmN1cnJlbnQgPSB0aGlzLmdldChtZXRob2QpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBNb2RlbEVycm9ycyB9IGZyb20gXCIuLi92YWxpZGF0aW9uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgSGVscGVyIENsYXNzIHRvIGhvbGQgdGhlIGVycm9yIHJlc3VsdHNcbiAqIEBkZXNjcmlwdGlvbiBob2xkcyBlcnJvciByZXN1bHRzIGluIGFuICdpbmRleGFibGUnIG1hbm5lclxuICogd2hpbGUgc3RpbGwgcHJvdmlkaW5nIHRoZSBzYW1lIHJlc3VsdCBvbiB0b1N0cmluZ1xuICpcbiAqIEBwYXJhbSB7TW9kZWxFcnJvcnN9IGVycm9yc1xuICpcbiAqIEBjbGFzcyBNb2RlbEVycm9yRGVmaW5pdGlvblxuICpcbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgY2xhc3MgTW9kZWxFcnJvckRlZmluaXRpb24ge1xuICBbaW5kZXhlcjogc3RyaW5nXTpcbiAgICB8IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD5cbiAgICB8ICgoKSA9PiBzdHJpbmcgfCB1bmRlZmluZWQpO1xuXG4gIGNvbnN0cnVjdG9yKGVycm9yczogTW9kZWxFcnJvcnMpIHtcbiAgICBmb3IgKGNvbnN0IHByb3AgaW4gZXJyb3JzKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGVycm9ycywgcHJvcCkgJiYgZXJyb3JzW3Byb3BdKVxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcyBhcyBhbnksIHByb3AsIHtcbiAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICAgICAgdmFsdWU6IGVycm9yc1twcm9wXSxcbiAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBPdXRwdXRzIHRoZSBjbGFzcyB0byBhIG5pY2UgcmVhZGFibGUgc3RyaW5nXG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKi9cbiAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICBjb25zdCBzZWxmOiBhbnkgPSB0aGlzIGFzIGFueTtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMoc2VsZilcbiAgICAgIC5maWx0ZXIoXG4gICAgICAgIChrKSA9PlxuICAgICAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzZWxmLCBrKSAmJlxuICAgICAgICAgIHR5cGVvZiBzZWxmW2tdICE9PSBcImZ1bmN0aW9uXCJcbiAgICAgIClcbiAgICAgIC5yZWR1Y2UoKGFjY3VtOiBzdHJpbmcsIHByb3ApID0+IHtcbiAgICAgICAgbGV0IHByb3BFcnJvcjogc3RyaW5nIHwgdW5kZWZpbmVkID0gT2JqZWN0LmtleXMoc2VsZltwcm9wXSkucmVkdWNlKFxuICAgICAgICAgIChwcm9wQWNjdW06IHVuZGVmaW5lZCB8IHN0cmluZywga2V5KSA9PiB7XG4gICAgICAgICAgICBpZiAoIXByb3BBY2N1bSkgcHJvcEFjY3VtID0gc2VsZltwcm9wXVtrZXldO1xuICAgICAgICAgICAgZWxzZSBwcm9wQWNjdW0gKz0gYFxcbiR7c2VsZltwcm9wXVtrZXldfWA7XG4gICAgICAgICAgICByZXR1cm4gcHJvcEFjY3VtO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgdW5kZWZpbmVkXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHByb3BFcnJvcikge1xuICAgICAgICAgIHByb3BFcnJvciA9IGAke3Byb3B9IC0gJHtwcm9wRXJyb3J9YDtcbiAgICAgICAgICBpZiAoIWFjY3VtKSBhY2N1bSA9IHByb3BFcnJvcjtcbiAgICAgICAgICBlbHNlIGFjY3VtICs9IGBcXG4ke3Byb3BFcnJvcn1gO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgfSwgXCJcIik7XG4gIH1cbn1cbiIsIi8qKlxuICogQHN1bW1hcnkgUmVmZXJlbmNlcyB0aGUgcmVsZXZhbnQgSlMgcHJpbWl0aXZlc1xuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBTVFJJTkcgcmVmZXJlbmNlcyB0aGUgc3RyaW5nIHByaW1pdGl2ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IE5VTUJFUiByZWZlcmVuY2VzIHRoZSBudW1iZXIgcHJpbWl0aXZlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gQk9PTEVBTiByZWZlcmVuY2VzIHRoZSBib29sZWFuIHByaW1pdGl2ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IEJJR0lOVCByZWZlcmVuY2VzIHRoZSBiaWdpbnQgcHJpbWl0aXZlXG4gKlxuICogQGNvbnN0YW50IFByaW1pdGl2ZXNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqL1xuZXhwb3J0IGVudW0gUHJpbWl0aXZlcyB7XG4gIFNUUklORyA9IFwic3RyaW5nXCIsXG4gIE5VTUJFUiA9IFwibnVtYmVyXCIsXG4gIEJPT0xFQU4gPSBcImJvb2xlYW5cIixcbiAgQklHSU5UID0gXCJiaWdpbnRcIixcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBSZWZlcmVuY2VzIHRoZSBSZXNlcnZlZCBtb2RlbCBuYW1lcyB0byBpZ25vcmUgZHVyaW5nIE1vZGVsIHJlYnVpbGRpbmdcbiAqXG4gKiBAcHJvcGVydHkge3N0cmluZ30gU1RSSU5HXG4gKiBAcHJvcGVydHkge3N0cmluZ30gT0JKRUNUXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTlVNQkVSXG4gKiBAcHJvcGVydHkge3N0cmluZ30gQk9PTEVBTlxuICogQHByb3BlcnR5IHtzdHJpbmd9IEJJR0lOVFxuICogQHByb3BlcnR5IHtzdHJpbmd9IERBVEVcbiAqXG4gKiBAY29uc3RhbnQgUmVzZXJ2ZWRNb2RlbHNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqL1xuZXhwb3J0IGVudW0gUmVzZXJ2ZWRNb2RlbHMge1xuICBTVFJJTkcgPSBcInN0cmluZ1wiLFxuICBPQkpFQ1QgPSBcIm9iamVjdFwiLFxuICBOVU1CRVIgPSBcIm51bWJlclwiLFxuICBCT09MRUFOID0gXCJib29sZWFuXCIsXG4gIEJJR0lOVCA9IFwiYmlnaW50XCIsXG4gIERBVEUgPSBcImRhdGVcIixcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBSZWZlcmVuY2VzIHRoZSBiYXNpYyBzdXBwb3J0ZWQganMgdHlwZXNcbiAqXG4gKiBAcHJvcGVydHkge3N0cmluZ30gc3RyaW5nXG4gKiBAcHJvcGVydHkge3N0cmluZ30gYXJyYXlcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBudW1iZXJcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBib29sZWFuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gc3ltYm9sXG4gKiBAcHJvcGVydHkge3N0cmluZ30gZnVuY3Rpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBvYmplY3RcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB1bmRlZmluZWRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBudWxsXG4gKiBAcHJvcGVydHkge3N0cmluZ30gQklHSU5UXG4gKlxuICogQGNvbnN0YW50IGpzVHlwZXNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqL1xuZXhwb3J0IGNvbnN0IGpzVHlwZXMgPSBbXG4gIFwic3RyaW5nXCIsXG4gIFwiYXJyYXlcIixcbiAgXCJudW1iZXJcIixcbiAgXCJib29sZWFuXCIsXG4gIFwic3ltYm9sXCIsXG4gIFwiZnVuY3Rpb25cIixcbiAgXCJvYmplY3RcIixcbiAgXCJ1bmRlZmluZWRcIixcbiAgXCJudWxsXCIsXG4gIFwiYmlnaW50XCIsXG5dO1xuIiwiaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgc2YgfSBmcm9tIFwiLi4vLi4vdXRpbHMvc3RyaW5nc1wiO1xuaW1wb3J0IHsgUmVmbGVjdGlvbiB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBhbGwgdmFsaWRhdG9ycyBpbiB0aGUgdmFsaWRhdGlvbiBmcmFtZXdvcmtcbiAqIEBzdW1tYXJ5IFRoZSBWYWxpZGF0b3IgY2xhc3MgcHJvdmlkZXMgdGhlIGZvdW5kYXRpb24gZm9yIGFsbCB2YWxpZGF0b3IgaW1wbGVtZW50YXRpb25zLlxuICogSXQgaGFuZGxlcyB0eXBlIGNoZWNraW5nLCBlcnJvciBtZXNzYWdlIGZvcm1hdHRpbmcsIGFuZCBkZWZpbmVzIHRoZSBjb21tb24gaW50ZXJmYWNlXG4gKiB0aGF0IGFsbCB2YWxpZGF0b3JzIG11c3QgaW1wbGVtZW50LiBUaGlzIGNsYXNzIGlzIGRlc2lnbmVkIHRvIGJlIGV4dGVuZGVkIGJ5IHNwZWNpZmljXG4gKiB2YWxpZGF0b3IgaW1wbGVtZW50YXRpb25zIHRoYXQgcHJvdmlkZSBjb25jcmV0ZSB2YWxpZGF0aW9uIGxvZ2ljLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gRGVmYXVsdCBlcnJvciBtZXNzYWdlIHRvIGRpc3BsYXkgd2hlbiB2YWxpZGF0aW9uIGZhaWxzLCBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNERUZBVUxUfVxuICogQHBhcmFtIHtzdHJpbmdbXX0gYWNjZXB0ZWRUeXBlcyAtIEFycmF5IG9mIHR5cGUgbmFtZXMgdGhhdCB0aGlzIHZhbGlkYXRvciBjYW4gdmFsaWRhdGVcbiAqXG4gKiBAY2xhc3MgVmFsaWRhdG9yXG4gKiBAYWJzdHJhY3RcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gRXhhbXBsZSBvZiBleHRlbmRpbmcgdGhlIFZhbGlkYXRvciBjbGFzcyB0byBjcmVhdGUgYSBjdXN0b20gdmFsaWRhdG9yXG4gKiBjbGFzcyBDdXN0b21WYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3I8Q3VzdG9tVmFsaWRhdG9yT3B0aW9ucz4ge1xuICogICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBcIkN1c3RvbSB2YWxpZGF0aW9uIGZhaWxlZFwiKSB7XG4gKiAgICAgLy8gU3BlY2lmeSB0aGF0IHRoaXMgdmFsaWRhdG9yIGFjY2VwdHMgU3RyaW5nIGFuZCBOdW1iZXIgdHlwZXNcbiAqICAgICBzdXBlcihtZXNzYWdlLCBTdHJpbmcubmFtZSwgTnVtYmVyLm5hbWUpO1xuICogICB9XG4gKlxuICogICBwdWJsaWMgaGFzRXJyb3JzKHZhbHVlOiBhbnksIG9wdGlvbnM/OiBDdXN0b21WYWxpZGF0b3JPcHRpb25zKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAqICAgICAvLyBJbXBsZW1lbnQgY3VzdG9tIHZhbGlkYXRpb24gbG9naWNcbiAqICAgICBpZiAoc29tZUNvbmRpdGlvbikge1xuICogICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZShvcHRpb25zPy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSk7XG4gKiAgICAgfVxuICogICAgIHJldHVybiB1bmRlZmluZWQ7IC8vIE5vIGVycm9yc1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IFYgYXMgVmFsaWRhdG9yIFN1YmNsYXNzXG4gKiAgIHBhcnRpY2lwYW50IEIgYXMgQmFzZSBWYWxpZGF0b3JcbiAqXG4gKiAgIEMtPj5WOiBuZXcgQ3VzdG9tVmFsaWRhdG9yKG1lc3NhZ2UpXG4gKiAgIFYtPj5COiBzdXBlcihtZXNzYWdlLCBhY2NlcHRlZFR5cGVzKVxuICogICBCLT4+QjogU3RvcmUgbWVzc2FnZSBhbmQgdHlwZXNcbiAqICAgQi0+PkI6IFdyYXAgaGFzRXJyb3JzIHdpdGggdHlwZSBjaGVja2luZ1xuICogICBDLT4+VjogaGFzRXJyb3JzKHZhbHVlLCBvcHRpb25zKVxuICogICBhbHQgdmFsdWUgdHlwZSBub3QgaW4gYWNjZXB0ZWRUeXBlc1xuICogICAgIEItLT4+QzogVHlwZSBlcnJvciBtZXNzYWdlXG4gKiAgIGVsc2UgdmFsdWUgdHlwZSBpcyBhY2NlcHRlZFxuICogICAgIFYtPj5WOiBDdXN0b20gdmFsaWRhdGlvbiBsb2dpY1xuICogICAgIFYtLT4+QzogVmFsaWRhdGlvbiByZXN1bHRcbiAqICAgZW5kXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFZhbGlkYXRvcjxWIGV4dGVuZHMgVmFsaWRhdG9yT3B0aW9ucyA9IFZhbGlkYXRvck9wdGlvbnM+IHtcbiAgcmVhZG9ubHkgbWVzc2FnZTogc3RyaW5nO1xuICByZWFkb25seSBhY2NlcHRlZFR5cGVzPzogc3RyaW5nW107XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKFxuICAgIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuREVGQVVMVCxcbiAgICAuLi5hY2NlcHRlZFR5cGVzOiBzdHJpbmdbXVxuICApIHtcbiAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuXG4gICAgaWYgKGFjY2VwdGVkVHlwZXMubGVuZ3RoKSB0aGlzLmFjY2VwdGVkVHlwZXMgPSBhY2NlcHRlZFR5cGVzO1xuICAgIGlmICh0aGlzLmFjY2VwdGVkVHlwZXMpXG4gICAgICB0aGlzLmhhc0Vycm9ycyA9IHRoaXMuY2hlY2tUeXBlQW5kSGFzRXJyb3JzKHRoaXMuaGFzRXJyb3JzLmJpbmQodGhpcykpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBGb3JtYXRzIGFuIGVycm9yIG1lc3NhZ2Ugd2l0aCBvcHRpb25hbCBhcmd1bWVudHNcbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIGZvcm1hdHRlZCBlcnJvciBtZXNzYWdlIGJ5IHJlcGxhY2luZyBwbGFjZWhvbGRlcnMgd2l0aCBwcm92aWRlZCBhcmd1bWVudHMuXG4gICAqIFRoaXMgbWV0aG9kIHVzZXMgdGhlIHN0cmluZyBmb3JtYXR0aW5nIHV0aWxpdHkgdG8gZ2VuZXJhdGUgY29uc2lzdGVudCBlcnJvciBtZXNzYWdlc1xuICAgKiBhY3Jvc3MgYWxsIHZhbGlkYXRvcnMuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gVGhlIG1lc3NhZ2UgdGVtcGxhdGUgd2l0aCBwbGFjZWhvbGRlcnNcbiAgICogQHBhcmFtIHsuLi5hbnl9IGFyZ3MgLSBWYWx1ZXMgdG8gaW5zZXJ0IGludG8gdGhlIG1lc3NhZ2UgdGVtcGxhdGVcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIGVycm9yIG1lc3NhZ2VcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE1lc3NhZ2UobWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIHJldHVybiBzZihtZXNzYWdlLCAuLi5hcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIHR5cGUtY2hlY2tpbmcgd3JhcHBlciBhcm91bmQgdGhlIGhhc0Vycm9ycyBtZXRob2RcbiAgICogQHN1bW1hcnkgV3JhcHMgdGhlIGhhc0Vycm9ycyBtZXRob2Qgd2l0aCB0eXBlIHZhbGlkYXRpb24gbG9naWMgdG8gZW5zdXJlIHRoYXRcbiAgICogdGhlIHZhbHVlIGJlaW5nIHZhbGlkYXRlZCBpcyBvZiBhbiBhY2NlcHRlZCB0eXBlIGJlZm9yZSBwZXJmb3JtaW5nIHNwZWNpZmljIHZhbGlkYXRpb24uXG4gICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBkdXJpbmcgY29uc3RydWN0aW9uIGlmIGFjY2VwdGVkVHlwZXMgYXJlIHByb3ZpZGVkLlxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB1bmJvdW5kIC0gVGhlIG9yaWdpbmFsIGhhc0Vycm9ycyBtZXRob2QgdG8gYmUgd3JhcHBlZFxuICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBuZXcgZnVuY3Rpb24gdGhhdCBwZXJmb3JtcyB0eXBlIGNoZWNraW5nIGJlZm9yZSBjYWxsaW5nIHRoZSBvcmlnaW5hbCBtZXRob2RcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgY2hlY2tUeXBlQW5kSGFzRXJyb3JzKFxuICAgIHVuYm91bmQ6ICh2YWx1ZTogYW55LCAuLi5hcmdzOiBhbnlbXSkgPT4gc3RyaW5nIHwgdW5kZWZpbmVkXG4gICkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoXG4gICAgICB0aGlzOiBWYWxpZGF0b3IsXG4gICAgICB2YWx1ZTogYW55LFxuICAgICAgLi4uYXJnczogYW55W11cbiAgICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgIXRoaXMuYWNjZXB0ZWRUeXBlcylcbiAgICAgICAgcmV0dXJuIHVuYm91bmQodmFsdWUsIC4uLmFyZ3MpO1xuICAgICAgaWYgKCFSZWZsZWN0aW9uLmNoZWNrVHlwZXModmFsdWUsIHRoaXMuYWNjZXB0ZWRUeXBlcykpXG4gICAgICAgIHJldHVybiB0aGlzLmdldE1lc3NhZ2UoXG4gICAgICAgICAgREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5UWVBFLFxuICAgICAgICAgIHRoaXMuYWNjZXB0ZWRUeXBlcy5qb2luKFwiLCBcIiksXG4gICAgICAgICAgdHlwZW9mIHZhbHVlXG4gICAgICAgICk7XG4gICAgICByZXR1cm4gdW5ib3VuZCh2YWx1ZSwgLi4uYXJncyk7XG4gICAgfS5iaW5kKHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0ZXMgYSB2YWx1ZSBhZ2FpbnN0IHNwZWNpZmljIHZhbGlkYXRpb24gcnVsZXNcbiAgICogQHN1bW1hcnkgQWJzdHJhY3QgbWV0aG9kIHRoYXQgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBhbGwgdmFsaWRhdG9yIHN1YmNsYXNzZXMuXG4gICAqIFRoaXMgbWV0aG9kIGNvbnRhaW5zIHRoZSBjb3JlIHZhbGlkYXRpb24gbG9naWMgdGhhdCBkZXRlcm1pbmVzIHdoZXRoZXIgYSB2YWx1ZVxuICAgKiBpcyB2YWxpZCBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljIHJ1bGVzIG9mIHRoZSB2YWxpZGF0b3IuIElmIHRoZSB2YWx1ZSBpcyB2YWxpZCxcbiAgICogdGhlIG1ldGhvZCByZXR1cm5zIHVuZGVmaW5lZDsgb3RoZXJ3aXNlLCBpdCByZXR1cm5zIGFuIGVycm9yIG1lc3NhZ2UuXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSBWIC0gVHlwZSBvZiB0aGUgb3B0aW9ucyBvYmplY3QgdGhhdCBjYW4gYmUgcGFzc2VkIHRvIHRoZSB2YWxpZGF0b3JcbiAgICogQHBhcmFtIHthbnl9IHZhbHVlIC0gVGhlIHZhbHVlIHRvIHZhbGlkYXRlXG4gICAqIEBwYXJhbSB7Vn0gW29wdGlvbnNdIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvbiBvcHRpb25zIGZvciBjdXN0b21pemluZyB2YWxpZGF0aW9uIGJlaGF2aW9yXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH0gRXJyb3IgbWVzc2FnZSBpZiB2YWxpZGF0aW9uIGZhaWxzLCB1bmRlZmluZWQgaWYgdmFsaWRhdGlvbiBwYXNzZXNcbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqXG4gICAqIEBzZWUgTW9kZWwjdmFsaWRhdGVcbiAgICovXG4gIHB1YmxpYyBhYnN0cmFjdCBoYXNFcnJvcnModmFsdWU6IGFueSwgb3B0aW9ucz86IFYpOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IER1Y2sgdHlwaW5nIGZvciBWYWxpZGF0b3JzXG4gICAqIEBwYXJhbSB2YWxcbiAgICovXG4gIHN0YXRpYyBpc1ZhbGlkYXRvcih2YWw6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB2YWwuY29uc3RydWN0b3IgJiYgISF2YWxbXCJoYXNFcnJvcnNcIl07XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvckRlZmluaXRpb24gfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IElWYWxpZGF0b3JSZWdpc3RyeSB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgQmFzZSBJbXBsZW1lbnRhdGlvbiBvZiBhIFZhbGlkYXRvciBSZWdpc3RyeVxuICpcbiAqIEBwcm9wIHtWYWxpZGF0b3JbXX0gW3ZhbGlkYXRvcnNdIHRoZSBpbml0aWFsIHZhbGlkYXRvcnMgdG8gcmVnaXN0ZXJcbiAqXG4gKiBAY2xhc3MgVmFsaWRhdG9yUmVnaXN0cnlcbiAqIEBpbXBsZW1lbnRzIElWYWxpZGF0b3JSZWdpc3RyeTxUPlxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBWYWxpZGF0b3JSZWdpc3RyeTxUIGV4dGVuZHMgVmFsaWRhdG9yPlxuICBpbXBsZW1lbnRzIElWYWxpZGF0b3JSZWdpc3RyeTxUPlxue1xuICBwcml2YXRlIGNhY2hlOiBhbnkgPSB7fTtcbiAgcHJpdmF0ZSBjdXN0b21LZXlDYWNoZTogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcblxuICBjb25zdHJ1Y3RvciguLi52YWxpZGF0b3JzOiAoVmFsaWRhdG9yRGVmaW5pdGlvbiB8IFZhbGlkYXRvcilbXSkge1xuICAgIHRoaXMuY3VzdG9tS2V5Q2FjaGUgPSB7fTtcbiAgICB0aGlzLnJlZ2lzdGVyKC4uLnZhbGlkYXRvcnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHJldHJpZXZlcyB0aGUgY3VzdG9tIGtleXNcbiAgICovXG4gIGdldEN1c3RvbUtleXMoKTogeyBbaW5kZXhlcjogc3RyaW5nXTogc3RyaW5nIH0ge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCB0aGlzLmN1c3RvbUtleUNhY2hlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSByZXRyaWV2ZXMgdGhlIHJlZ2lzdGVyZWQgdmFsaWRhdG9ycyBrZXlzXG4gICAqL1xuICBnZXRLZXlzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5jYWNoZSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIGEgdmFsaWRhdG9yXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWxpZGF0b3JLZXkgb25lIG9mIHRoZSB7QGxpbmsgVmFsaWRhdGlvbktleXN9XG4gICAqIEByZXR1cm4ge1ZhbGlkYXRvciB8IHVuZGVmaW5lZH0gdGhlIHJlZ2lzdGVyZWQgVmFsaWRhdG9yIG9yIHVuZGVmaW5lZCBpZiB0aGVyZSBpcyBub25vIG1hdGNoaW5nIHRoZSBwcm92aWRlZCBrZXlcbiAgICovXG4gIGdldDxUIGV4dGVuZHMgVmFsaWRhdG9yPih2YWxpZGF0b3JLZXk6IHN0cmluZyk6IFQgfCB1bmRlZmluZWQge1xuICAgIGlmICghKHZhbGlkYXRvcktleSBpbiB0aGlzLmNhY2hlKSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IGNsYXNzT3JJbnN0YW5jZSA9IHRoaXMuY2FjaGVbdmFsaWRhdG9yS2V5XTtcbiAgICBpZiAoVmFsaWRhdG9yLmlzVmFsaWRhdG9yKGNsYXNzT3JJbnN0YW5jZSkpIHJldHVybiBjbGFzc09ySW5zdGFuY2UgYXMgVDtcbiAgICBjb25zdCBjb25zdHJ1Y3RvciA9IGNsYXNzT3JJbnN0YW5jZS5kZWZhdWx0IHx8IGNsYXNzT3JJbnN0YW5jZTtcbiAgICBjb25zdCBpbnN0YW5jZSA9IG5ldyBjb25zdHJ1Y3RvcigpO1xuICAgIHRoaXMuY2FjaGVbdmFsaWRhdG9yS2V5XSA9IGluc3RhbmNlO1xuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZWdpc3RlcnMgdGhlIHByb3ZpZGVkIHZhbGlkYXRvcnMgb250byB0aGUgcmVnaXN0cnlcbiAgICpcbiAgICogQHBhcmFtIHtUW10gfCBWYWxpZGF0b3JEZWZpbml0aW9uW119IHZhbGlkYXRvclxuICAgKi9cbiAgcmVnaXN0ZXI8VCBleHRlbmRzIFZhbGlkYXRvcj4oXG4gICAgLi4udmFsaWRhdG9yOiAoVmFsaWRhdG9yRGVmaW5pdGlvbiB8IFQpW11cbiAgKTogdm9pZCB7XG4gICAgdmFsaWRhdG9yLmZvckVhY2goKHYpID0+IHtcbiAgICAgIGlmIChWYWxpZGF0b3IuaXNWYWxpZGF0b3IodikpIHtcbiAgICAgICAgLy8gY29uc3QgayA9XG5cbiAgICAgICAgaWYgKCh2IGFzIFZhbGlkYXRvckRlZmluaXRpb24pLnZhbGlkYXRpb25LZXkgaW4gdGhpcy5jYWNoZSkgcmV0dXJuO1xuICAgICAgICB0aGlzLmNhY2hlWyh2IGFzIFZhbGlkYXRvckRlZmluaXRpb24pLnZhbGlkYXRpb25LZXldID0gdjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHsgdmFsaWRhdGlvbktleSwgdmFsaWRhdG9yLCBzYXZlIH0gPSB2IGFzIFZhbGlkYXRvckRlZmluaXRpb247XG4gICAgICAgIGlmICh2YWxpZGF0aW9uS2V5IGluIHRoaXMuY2FjaGUpIHJldHVybjtcbiAgICAgICAgdGhpcy5jYWNoZVt2YWxpZGF0aW9uS2V5XSA9IHZhbGlkYXRvcjtcbiAgICAgICAgaWYgKCFzYXZlKSByZXR1cm47XG4gICAgICAgIGNvbnN0IG9iajogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICAgICAgICBvYmpbdmFsaWRhdGlvbktleS50b1VwcGVyQ2FzZSgpXSA9IHZhbGlkYXRpb25LZXk7XG5cbiAgICAgICAgdGhpcy5jdXN0b21LZXlDYWNoZSA9IE9iamVjdC5hc3NpZ24oe30sIHRoaXMuY3VzdG9tS2V5Q2FjaGUsIG9iaik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvcnMvVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBJVmFsaWRhdG9yUmVnaXN0cnksIFZhbGlkYXRvckRlZmluaXRpb24gfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgVmFsaWRhdG9yUmVnaXN0cnkgfSBmcm9tIFwiLi9WYWxpZGF0b3JzL1ZhbGlkYXRvclJlZ2lzdHJ5XCI7XG5pbXBvcnQgeyBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL1ZhbGlkYXRvcnMvY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgU3RhdGljIGNsYXNzIGFjdGluZyBhcyBhIG5hbWVzcGFjZSBmb3IgdGhlIFZhbGlkYXRpb25cbiAqXG4gKiBAY2xhc3MgVmFsaWRhdGlvblxuICogQHN0YXRpY1xuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBWYWxpZGF0aW9uIHtcbiAgcHJpdmF0ZSBzdGF0aWMgYWN0aW5nVmFsaWRhdG9yUmVnaXN0cnk/OiBJVmFsaWRhdG9yUmVnaXN0cnk8VmFsaWRhdG9yPiA9XG4gICAgdW5kZWZpbmVkO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7fVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBhY3RpbmcgVmFsaWRhdG9yUmVnaXN0cnlcbiAgICpcbiAgICogQHBhcmFtIHtJVmFsaWRhdG9yUmVnaXN0cnl9IHZhbGlkYXRvclJlZ2lzdHJ5IHRoZSBuZXcgaW1wbGVtZW50YXRpb24gb2YgdGhlIHZhbGlkYXRvciBSZWdpc3RyeVxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKFZhbGlkYXRvcik6IFZhbGlkYXRvcn0gW21pZ3JhdGlvbkhhbmRsZXJdIHRoZSBtZXRob2QgdG8gbWFwIHRoZSB2YWxpZGF0b3IgaWYgcmVxdWlyZWQ7XG4gICAqL1xuICBzdGF0aWMgc2V0UmVnaXN0cnkoXG4gICAgdmFsaWRhdG9yUmVnaXN0cnk6IElWYWxpZGF0b3JSZWdpc3RyeTxWYWxpZGF0b3I+LFxuICAgIG1pZ3JhdGlvbkhhbmRsZXI/OiAodmFsaWRhdG9yOiBWYWxpZGF0b3IpID0+IFZhbGlkYXRvclxuICApIHtcbiAgICBpZiAobWlncmF0aW9uSGFuZGxlciAmJiBWYWxpZGF0aW9uLmFjdGluZ1ZhbGlkYXRvclJlZ2lzdHJ5KVxuICAgICAgVmFsaWRhdGlvbi5hY3RpbmdWYWxpZGF0b3JSZWdpc3RyeS5nZXRLZXlzKCkuZm9yRWFjaCgoazogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbGlkYXRvciA9IHZhbGlkYXRvclJlZ2lzdHJ5LmdldChrKTtcbiAgICAgICAgaWYgKHZhbGlkYXRvcikgdmFsaWRhdG9yUmVnaXN0cnkucmVnaXN0ZXIobWlncmF0aW9uSGFuZGxlcih2YWxpZGF0b3IpKTtcbiAgICAgIH0pO1xuICAgIFZhbGlkYXRpb24uYWN0aW5nVmFsaWRhdG9yUmVnaXN0cnkgPSB2YWxpZGF0b3JSZWdpc3RyeTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZXR1cm5zIHRoZSBjdXJyZW50IFZhbGlkYXRvclJlZ2lzdHJ5XG4gICAqXG4gICAqIEByZXR1cm4gSVZhbGlkYXRvclJlZ2lzdHJ5LCBkZWZhdWx0cyB0byB7QGxpbmsgVmFsaWRhdG9yUmVnaXN0cnl9XG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBnZXRSZWdpc3RyeSgpIHtcbiAgICBpZiAoIVZhbGlkYXRpb24uYWN0aW5nVmFsaWRhdG9yUmVnaXN0cnkpXG4gICAgICBWYWxpZGF0aW9uLmFjdGluZ1ZhbGlkYXRvclJlZ2lzdHJ5ID0gbmV3IFZhbGlkYXRvclJlZ2lzdHJ5KCk7XG4gICAgcmV0dXJuIFZhbGlkYXRpb24uYWN0aW5nVmFsaWRhdG9yUmVnaXN0cnk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIGEgdmFsaWRhdG9yXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWxpZGF0b3JLZXkgb25lIG9mIHRoZSB7QGxpbmsgVmFsaWRhdGlvbktleXN9XG4gICAqIEByZXR1cm4ge1ZhbGlkYXRvciB8IHVuZGVmaW5lZH0gdGhlIHJlZ2lzdGVyZWQgVmFsaWRhdG9yIG9yIHVuZGVmaW5lZCBpZiB0aGVyZSBpcyBub25vIG1hdGNoaW5nIHRoZSBwcm92aWRlZCBrZXlcbiAgICovXG4gIHN0YXRpYyBnZXQ8VCBleHRlbmRzIFZhbGlkYXRvcj4odmFsaWRhdG9yS2V5OiBzdHJpbmcpOiBUIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gVmFsaWRhdGlvbi5nZXRSZWdpc3RyeSgpLmdldCh2YWxpZGF0b3JLZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJlZ2lzdGVycyB0aGUgcHJvdmlkZWQgdmFsaWRhdG9ycyBvbnRvIHRoZSByZWdpc3RyeVxuICAgKlxuICAgKiBAcGFyYW0ge1RbXSB8IFZhbGlkYXRvckRlZmluaXRpb25bXX0gdmFsaWRhdG9yXG4gICAqL1xuICBzdGF0aWMgcmVnaXN0ZXI8VCBleHRlbmRzIFZhbGlkYXRvcj4oXG4gICAgLi4udmFsaWRhdG9yOiAoVmFsaWRhdG9yRGVmaW5pdGlvbiB8IFQpW11cbiAgKTogdm9pZCB7XG4gICAgcmV0dXJuIFZhbGlkYXRpb24uZ2V0UmVnaXN0cnkoKS5yZWdpc3RlciguLi52YWxpZGF0b3IpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEJ1aWxkcyB0aGUga2V5IHRvIHN0b3JlIGFzIE1ldGFkYXRhIHVuZGVyIFJlZmxlY3Rpb25zXG4gICAqIEBkZXNjcmlwdGlvbiBjb25jYXRlbmF0ZXMge0BsaW5rIFZhbGlkYXRpb25LZXlzI1JFRkxFQ1R9IHdpdGggdGhlIHByb3ZpZGVkIGtleVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gICAqL1xuICBzdGF0aWMga2V5KGtleTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIFZhbGlkYXRpb25LZXlzLlJFRkxFQ1QgKyBrZXk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgUmV0dXJucyBhbGwgcmVnaXN0ZXJlZCB2YWxpZGF0aW9uIGtleXNcbiAgICovXG4gIHN0YXRpYyBrZXlzKCkge1xuICAgIHJldHVybiB0aGlzLmdldFJlZ2lzdHJ5KCkuZ2V0S2V5cygpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBNb2RlbEVycm9yRGVmaW5pdGlvbiB9IGZyb20gXCIuL01vZGVsRXJyb3JEZWZpbml0aW9uXCI7XG5pbXBvcnQgeyBEZWNvcmF0b3JNZXRhZGF0YSwgUmVmbGVjdGlvbiB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgTW9kZWxLZXlzIH0gZnJvbSBcIi4uL3V0aWxzL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgc2YgfSBmcm9tIFwiLi4vdXRpbHMvc3RyaW5nc1wiO1xuaW1wb3J0IHsgUmVzZXJ2ZWRNb2RlbHMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFZhbGlkYXRhYmxlIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIi4vTW9kZWxcIjtcbmltcG9ydCB7IFZhbGlkYXRpb24gfSBmcm9tIFwiLi4vdmFsaWRhdGlvbi9WYWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuLi92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvY29uc3RhbnRzXCI7XG5pbXBvcnQge1xuICBNb2RlbEVycm9ycyxcbiAgVmFsaWRhdGlvblByb3BlcnR5RGVjb3JhdG9yRGVmaW5pdGlvbixcbn0gZnJvbSBcIi4uL3ZhbGlkYXRpb24vdHlwZXNcIjtcbmltcG9ydCB7IFZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdmFsaWRhdGlvbi90eXBlc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IEFuYWx5c2VzIHRoZSBkZWNvcmF0aW9ucyBvZiB0aGUgcHJvcGVydGllcyBhbmQgdmFsaWRhdGVzIHRoZSBvYmogYWNjb3JkaW5nIHRvIHRoZW1cbiAqXG4gKiBAdHlwZWRlZiBUIGV4dGVuZHMgTW9kZWxcbiAqIEBwcm9wIHtUfSBvYmogTW9kZWwgb2JqZWN0IHRvIHZhbGlkYXRlXG4gKiBAcHJvcCB7c3RyaW5nW119IFtwcm9wc1RvSWdub3JlXSBvYmplY3QgcHJvcGVydGllcyB0byBpZ25vcmUgaW4gdGhlIHZhbGlkYXRpb25cbiAqXG4gKiBAZnVuY3Rpb24gdmFsaWRhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGU8VCBleHRlbmRzIE1vZGVsPihcbiAgb2JqOiBULFxuICAuLi5wcm9wc1RvSWdub3JlOiBzdHJpbmdbXVxuKTogTW9kZWxFcnJvckRlZmluaXRpb24gfCB1bmRlZmluZWQge1xuICBjb25zdCBkZWNvcmF0ZWRQcm9wZXJ0aWVzOiBWYWxpZGF0aW9uUHJvcGVydHlEZWNvcmF0b3JEZWZpbml0aW9uW10gPSBbXTtcbiAgZm9yIChjb25zdCBwcm9wIGluIG9iailcbiAgICBpZiAoXG4gICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKSAmJlxuICAgICAgcHJvcHNUb0lnbm9yZS5pbmRleE9mKHByb3ApID09PSAtMVxuICAgIClcbiAgICAgIGRlY29yYXRlZFByb3BlcnRpZXMucHVzaChcbiAgICAgICAgUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICAgICAgVmFsaWRhdGlvbktleXMuUkVGTEVDVCxcbiAgICAgICAgICBvYmosXG4gICAgICAgICAgcHJvcFxuICAgICAgICApIGFzIFZhbGlkYXRpb25Qcm9wZXJ0eURlY29yYXRvckRlZmluaXRpb25cbiAgICAgICk7XG5cbiAgbGV0IHJlc3VsdDogTW9kZWxFcnJvcnMgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cbiAgZm9yIChjb25zdCBkZWNvcmF0ZWRQcm9wZXJ0eSBvZiBkZWNvcmF0ZWRQcm9wZXJ0aWVzKSB7XG4gICAgY29uc3QgeyBwcm9wLCBkZWNvcmF0b3JzIH0gPSBkZWNvcmF0ZWRQcm9wZXJ0eTtcblxuICAgIGlmICghZGVjb3JhdG9ycyB8fCAhZGVjb3JhdG9ycy5sZW5ndGgpIGNvbnRpbnVlO1xuXG4gICAgY29uc3QgZGVmYXVsdFR5cGVEZWNvcmF0b3I6IERlY29yYXRvck1ldGFkYXRhID0gZGVjb3JhdG9yc1swXTtcblxuICAgIC8vIHRyaWVzIHRvIGZpbmQgYW55IHR5cGUgZGVjb3JhdG9ycyBvciBvdGhlciBkZWNvcmF0b3JzIHRoYXQgYWxyZWFkeSBlbmZvcmNlIHR5cGUgKHRoZSBvbmVzIHdpdGggdGhlIGFsbG93ZWQgdHlwZXMgcHJvcGVydHkgZGVmaW5lZCkuIGlmIHNvLCBza2lwIHRoZSBkZWZhdWx0IHR5cGUgdmVyaWZpY2F0aW9uXG4gICAgaWYgKFxuICAgICAgZGVjb3JhdG9ycy5maW5kKChkKSA9PiB7XG4gICAgICAgIGlmIChkLmtleSA9PT0gVmFsaWRhdGlvbktleXMuVFlQRSkgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiAhIWQucHJvcHMudHlwZXM/LmZpbmQoXG4gICAgICAgICAgKHQpID0+IHQgPT09IGRlZmF1bHRUeXBlRGVjb3JhdG9yLnByb3BzLm5hbWVcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKSB7XG4gICAgICBkZWNvcmF0b3JzLnNoaWZ0KCk7IC8vIHJlbW92ZSB0aGUgZGVzaWduOnR5cGUgZGVjb3JhdG9yLCBzaW5jZSB0aGUgdHlwZSB3aWxsIGFscmVhZHkgYmUgY2hlY2tlZFxuICAgIH1cblxuICAgIGxldCBlcnJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gICAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgZGVjb3JhdG9ycykge1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gVmFsaWRhdGlvbi5nZXQoZGVjb3JhdG9yLmtleSk7XG4gICAgICBpZiAoIXZhbGlkYXRvcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgdmFsaWRhdG9yIGZvciAke2RlY29yYXRvci5rZXl9YCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRlY29yYXRvclByb3BzID1cbiAgICAgICAgZGVjb3JhdG9yLmtleSA9PT0gTW9kZWxLZXlzLlRZUEVcbiAgICAgICAgICA/IFtkZWNvcmF0b3IucHJvcHNdXG4gICAgICAgICAgOiBkZWNvcmF0b3IucHJvcHMgfHwge307XG5cbiAgICAgIGNvbnN0IGVycjogc3RyaW5nIHwgdW5kZWZpbmVkID0gdmFsaWRhdG9yLmhhc0Vycm9ycyhcbiAgICAgICAgKG9iaiBhcyBhbnkpW3Byb3AudG9TdHJpbmcoKV0sXG4gICAgICAgIGRlY29yYXRvclByb3BzIGFzIFZhbGlkYXRvck9wdGlvbnNcbiAgICAgICk7XG5cbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgZXJycyA9IGVycnMgfHwge307XG4gICAgICAgIGVycnNbZGVjb3JhdG9yLmtleV0gPSBlcnI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVycnMpIHtcbiAgICAgIHJlc3VsdCA9IHJlc3VsdCB8fCB7fTtcbiAgICAgIHJlc3VsdFtkZWNvcmF0ZWRQcm9wZXJ0eS5wcm9wLnRvU3RyaW5nKCldID0gZXJycztcbiAgICB9XG4gIH1cblxuICAvLyB0ZXN0cyBuZXN0ZWQgY2xhc3Nlc1xuICBmb3IgKGNvbnN0IHByb3Agb2YgT2JqZWN0LmtleXMob2JqKS5maWx0ZXIoKGspID0+ICFyZXN1bHQgfHwgIXJlc3VsdFtrXSkpIHtcbiAgICBsZXQgZXJyOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgLy8gaWYgYSBuZXN0ZWQgTW9kZWxcbiAgICBjb25zdCBhbGxEZWNvcmF0b3JzID0gUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICBWYWxpZGF0aW9uS2V5cy5SRUZMRUNULFxuICAgICAgb2JqLFxuICAgICAgcHJvcFxuICAgICkuZGVjb3JhdG9ycztcbiAgICBjb25zdCBkZWNvcmF0b3JzID0gUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICBWYWxpZGF0aW9uS2V5cy5SRUZMRUNULFxuICAgICAgb2JqLFxuICAgICAgcHJvcFxuICAgICkuZGVjb3JhdG9ycy5maWx0ZXIoXG4gICAgICAoZDogeyBrZXk6IHN0cmluZyB9KSA9PlxuICAgICAgICBbTW9kZWxLZXlzLlRZUEUsIFZhbGlkYXRpb25LZXlzLlRZUEUgYXMgc3RyaW5nXS5pbmRleE9mKGQua2V5KSAhPT0gLTFcbiAgICApO1xuICAgIGlmICghZGVjb3JhdG9ycyB8fCAhZGVjb3JhdG9ycy5sZW5ndGgpIGNvbnRpbnVlO1xuICAgIGNvbnN0IGRlYyA9IGRlY29yYXRvcnMucG9wKCkgYXMgRGVjb3JhdG9yTWV0YWRhdGE7XG4gICAgY29uc3QgY2xhenogPSBkZWMucHJvcHMubmFtZVxuICAgICAgPyBbZGVjLnByb3BzLm5hbWVdXG4gICAgICA6IEFycmF5LmlzQXJyYXkoZGVjLnByb3BzLmN1c3RvbVR5cGVzKVxuICAgICAgICA/IGRlYy5wcm9wcy5jdXN0b21UeXBlc1xuICAgICAgICA6IFtkZWMucHJvcHMuY3VzdG9tVHlwZXNdO1xuICAgIGNvbnN0IHJlc2VydmVkID0gT2JqZWN0LnZhbHVlcyhSZXNlcnZlZE1vZGVscykubWFwKCh2KSA9PlxuICAgICAgdi50b0xvd2VyQ2FzZSgpXG4gICAgKSBhcyBzdHJpbmdbXTtcblxuICAgIGZvciAoY29uc3QgYyBvZiBjbGF6eikge1xuICAgICAgaWYgKHJlc2VydmVkLmluZGV4T2YoYy50b0xvd2VyQ2FzZSgpKSA9PT0gLTEpIHtcbiAgICAgICAgY29uc3QgdHlwZURlY29yYXRvcktleSA9IEFycmF5LmlzQXJyYXkoKG9iaiBhcyBhbnkpW3Byb3BdKVxuICAgICAgICAgID8gVmFsaWRhdGlvbktleXMuTElTVFxuICAgICAgICAgIDogVmFsaWRhdGlvbktleXMuVFlQRTtcbiAgICAgICAgY29uc3QgdHlwZXM6IGFueSA9XG4gICAgICAgICAgYWxsRGVjb3JhdG9ycy5maW5kKFxuICAgICAgICAgICAgKGQ6IHsga2V5OiBzdHJpbmcgfSkgPT4gZC5rZXkgPT09IHR5cGVEZWNvcmF0b3JLZXlcbiAgICAgICAgICApIHx8IHt9O1xuICAgICAgICBsZXQgYWxsb3dlZFR5cGVzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICBpZiAodHlwZXMgJiYgdHlwZXMucHJvcHMpIHtcbiAgICAgICAgICBjb25zdCBjdXN0b21UeXBlcyA9IEFycmF5LmlzQXJyYXkoKG9iaiBhcyBhbnkpW3Byb3BdKVxuICAgICAgICAgICAgPyB0eXBlcy5wcm9wcy5jbGFzc1xuICAgICAgICAgICAgOiB0eXBlcy5wcm9wcy5jdXN0b21UeXBlcztcbiAgICAgICAgICBpZiAoY3VzdG9tVHlwZXMpXG4gICAgICAgICAgICBhbGxvd2VkVHlwZXMgPSBBcnJheS5pc0FycmF5KGN1c3RvbVR5cGVzKVxuICAgICAgICAgICAgICA/IGN1c3RvbVR5cGVzLm1hcCgodCkgPT4gYCR7dH1gLnRvTG93ZXJDYXNlKCkpXG4gICAgICAgICAgICAgIDogW2N1c3RvbVR5cGVzLnRvTG93ZXJDYXNlKCldO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdmFsaWRhdGUgPSAocHJvcDogc3RyaW5nLCB2YWx1ZTogYW55KTogYW55ID0+IHtcbiAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiKVxuICAgICAgICAgICAgcmV0dXJuIE1vZGVsLmlzTW9kZWwodmFsdWUpXG4gICAgICAgICAgICAgID8gKHZhbHVlIGFzIE1vZGVsKS5oYXNFcnJvcnMoKVxuICAgICAgICAgICAgICA6IGFsbG93ZWRUeXBlcy5pbmNsdWRlcyh0eXBlb2YgdmFsdWUpXG4gICAgICAgICAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICA6IFwiVmFsdWUgaGFzIG5vIHZhbGlkYXRhYmxlIHR5cGVcIjtcbiAgICAgICAgfTtcblxuICAgICAgICBzd2l0Y2ggKGMpIHtcbiAgICAgICAgICBjYXNlIEFycmF5Lm5hbWU6XG4gICAgICAgICAgY2FzZSBTZXQubmFtZTpcbiAgICAgICAgICAgIGlmIChhbGxEZWNvcmF0b3JzLmxlbmd0aCkge1xuICAgICAgICAgICAgICBjb25zdCBsaXN0RGVjID0gYWxsRGVjb3JhdG9ycy5maW5kKFxuICAgICAgICAgICAgICAgIChkOiB7IGtleTogc3RyaW5nIH0pID0+IGQua2V5ID09PSBWYWxpZGF0aW9uS2V5cy5MSVNUXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGlmIChsaXN0RGVjKSB7XG4gICAgICAgICAgICAgICAgZXJyID0gKFxuICAgICAgICAgICAgICAgICAgYyA9PT0gQXJyYXkubmFtZVxuICAgICAgICAgICAgICAgICAgICA/IChvYmogYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF1cbiAgICAgICAgICAgICAgICAgICAgOiAvLyBJZiBpdCdzIGEgU2V0XG4gICAgICAgICAgICAgICAgICAgICAgKG9iaiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXS52YWx1ZXMoKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgIC5tYXAoKHY6IFZhbGlkYXRhYmxlKSA9PiB2YWxpZGF0ZShwcm9wLCB2KSlcbiAgICAgICAgICAgICAgICAgIC5maWx0ZXIoKGU6IGFueSkgPT4gISFlKSBhcyBhbnk7XG4gICAgICAgICAgICAgICAgaWYgKCFlcnI/Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlIHJlc3VsdCBpcyBhbiBlbXB0eSBsaXN0Li4uXG4gICAgICAgICAgICAgICAgICBlcnIgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgaWYgKChvYmogYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0pXG4gICAgICAgICAgICAgICAgZXJyID0gdmFsaWRhdGUocHJvcCwgKG9iaiBhcyBhbnkpW3Byb3BdKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oc2YoXCJNb2RlbCBzaG91bGQgYmUgdmFsaWRhdGFibGUgYnV0IGl0cyBub3Q6IFwiICsgZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdCB8fCB7fTtcbiAgICAgICAgcmVzdWx0W3Byb3BdID0gZXJyIGFzIGFueTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0ID8gbmV3IE1vZGVsRXJyb3JEZWZpbml0aW9uKHJlc3VsdCkgOiB1bmRlZmluZWQ7XG59XG4iLCJpbXBvcnQgeyBTZXJpYWxpemF0aW9uIH0gZnJvbSBcIi4uL3V0aWxzL3NlcmlhbGl6YXRpb25cIjtcbmltcG9ydCB7IEJ1aWxkZXJSZWdpc3RyeSB9IGZyb20gXCIuLi91dGlscy9yZWdpc3RyeVwiO1xuaW1wb3J0IHsgTW9kZWxFcnJvckRlZmluaXRpb24gfSBmcm9tIFwiLi9Nb2RlbEVycm9yRGVmaW5pdGlvblwiO1xuaW1wb3J0IHtcbiAgQ29tcGFyYWJsZSxcbiAgQ29uc3RydWN0b3IsXG4gIEhhc2hhYmxlLFxuICBNb2RlbEFyZyxcbiAgTW9kZWxCdWlsZGVyRnVuY3Rpb24sXG4gIE1vZGVsQ29uc3RydWN0b3IsXG4gIFNlcmlhbGl6YWJsZSxcbiAgVmFsaWRhdGFibGUsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBEZWNvcmF0b3JNZXRhZGF0YSwgaXNFcXVhbCwgUmVmbGVjdGlvbiB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgdmFsaWRhdGUgfSBmcm9tIFwiLi92YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBIYXNoaW5nIH0gZnJvbSBcIi4uL3V0aWxzL2hhc2hpbmdcIjtcbmltcG9ydCB7IE1vZGVsS2V5cyB9IGZyb20gXCIuLi91dGlscy9jb25zdGFudHNcIjtcbmltcG9ydCB7IFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4uL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9jb25zdGFudHNcIjtcbmltcG9ydCB7IHNmIH0gZnJvbSBcIi4uL3V0aWxzL3N0cmluZ3NcIjtcbmltcG9ydCB7IGpzVHlwZXMsIFJlc2VydmVkTW9kZWxzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbmxldCBtb2RlbEJ1aWxkZXJGdW5jdGlvbjogTW9kZWxCdWlsZGVyRnVuY3Rpb24gfCB1bmRlZmluZWQ7XG5sZXQgYWN0aW5nTW9kZWxSZWdpc3RyeTogQnVpbGRlclJlZ2lzdHJ5PGFueT47XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFJlZ2lzdHJ5IHR5cGUgZm9yIHN0b3JpbmcgYW5kIHJldHJpZXZpbmcgbW9kZWwgY29uc3RydWN0b3JzXG4gKiBAc3VtbWFyeSBUaGUgTW9kZWxSZWdpc3RyeSB0eXBlIGRlZmluZXMgYSByZWdpc3RyeSBmb3IgbW9kZWwgY29uc3RydWN0b3JzIHRoYXQgZXh0ZW5kc1xuICogdGhlIEJ1aWxkZXJSZWdpc3RyeSBpbnRlcmZhY2UuIEl0IHByb3ZpZGVzIGEgc3RhbmRhcmRpemVkIHdheSB0byByZWdpc3RlciwgcmV0cmlldmUsXG4gKiBhbmQgYnVpbGQgbW9kZWwgaW5zdGFuY2VzLCBlbmFibGluZyB0aGUgbW9kZWwgc3lzdGVtIHRvIHdvcmsgd2l0aCBkaWZmZXJlbnQgdHlwZXMgb2YgbW9kZWxzLlxuICpcbiAqIEBpbnRlcmZhY2UgTW9kZWxSZWdpc3RyeVxuICogQHRlbXBsYXRlIFQgVHlwZSBvZiBtb2RlbCB0aGF0IGNhbiBiZSByZWdpc3RlcmVkLCBtdXN0IGV4dGVuZCBNb2RlbFxuICogQGV4dGVuZHMgQnVpbGRlclJlZ2lzdHJ5PFQ+XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgTW9kZWxcbiAqL1xuZXhwb3J0IHR5cGUgTW9kZWxSZWdpc3RyeTxUIGV4dGVuZHMgTW9kZWw+ID0gQnVpbGRlclJlZ2lzdHJ5PFQ+O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZWdpc3RyeSBtYW5hZ2VyIGZvciBtb2RlbCBjb25zdHJ1Y3RvcnMgdGhhdCBlbmFibGVzIHNlcmlhbGl6YXRpb24gYW5kIHJlYnVpbGRpbmdcbiAqIEBzdW1tYXJ5IFRoZSBNb2RlbFJlZ2lzdHJ5TWFuYWdlciBpbXBsZW1lbnRzIHRoZSBNb2RlbFJlZ2lzdHJ5IGludGVyZmFjZSBhbmQgcHJvdmlkZXNcbiAqIGZ1bmN0aW9uYWxpdHkgZm9yIHJlZ2lzdGVyaW5nLCByZXRyaWV2aW5nLCBhbmQgYnVpbGRpbmcgbW9kZWwgaW5zdGFuY2VzLiBJdCBtYWludGFpbnNcbiAqIGEgY2FjaGUgb2YgbW9kZWwgY29uc3RydWN0b3JzIGluZGV4ZWQgYnkgbmFtZSwgYWxsb3dpbmcgZm9yIGVmZmljaWVudCBsb29rdXAgYW5kIGluc3RhbnRpYXRpb24uXG4gKiBUaGlzIGNsYXNzIGlzIGVzc2VudGlhbCBmb3IgdGhlIHNlcmlhbGl6YXRpb24gYW5kIGRlc2VyaWFsaXphdGlvbiBvZiBtb2RlbCBvYmplY3RzLlxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oUmVjb3JkPHN0cmluZywgYW55Pik6IGJvb2xlYW59IFt0ZXN0RnVuY3Rpb25dIC0gRnVuY3Rpb24gdG8gdGVzdCBpZiBhbiBvYmplY3QgaXMgYSBtb2RlbCwgZGVmYXVsdHMgdG8ge0BsaW5rIGlzTW9kZWx9XG4gKlxuICogQGNsYXNzIE1vZGVsUmVnaXN0cnlNYW5hZ2VyXG4gKiBAdGVtcGxhdGUgTSBUeXBlIG9mIG1vZGVsIHRoYXQgY2FuIGJlIHJlZ2lzdGVyZWQsIG11c3QgZXh0ZW5kIE1vZGVsXG4gKiBAaW1wbGVtZW50cyBNb2RlbFJlZ2lzdHJ5PE0+XG4gKiBAY2F0ZWdvcnkgTW9kZWxcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gQ3JlYXRlIGEgbW9kZWwgcmVnaXN0cnlcbiAqIGNvbnN0IHJlZ2lzdHJ5ID0gbmV3IE1vZGVsUmVnaXN0cnlNYW5hZ2VyKCk7XG4gKlxuICogLy8gUmVnaXN0ZXIgYSBtb2RlbCBjbGFzc1xuICogcmVnaXN0cnkucmVnaXN0ZXIoVXNlcik7XG4gKlxuICogLy8gUmV0cmlldmUgYSBtb2RlbCBjb25zdHJ1Y3RvciBieSBuYW1lXG4gKiBjb25zdCBVc2VyQ2xhc3MgPSByZWdpc3RyeS5nZXQoXCJVc2VyXCIpO1xuICpcbiAqIC8vIEJ1aWxkIGEgbW9kZWwgaW5zdGFuY2UgZnJvbSBhIHBsYWluIG9iamVjdFxuICogY29uc3QgdXNlckRhdGEgPSB7IG5hbWU6IFwiSm9oblwiLCBhZ2U6IDMwIH07XG4gKiBjb25zdCB1c2VyID0gcmVnaXN0cnkuYnVpbGQodXNlckRhdGEsIFwiVXNlclwiKTtcbiAqIGBgYFxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQyBhcyBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgUiBhcyBNb2RlbFJlZ2lzdHJ5TWFuYWdlclxuICogICBwYXJ0aWNpcGFudCBNIGFzIE1vZGVsIENsYXNzXG4gKlxuICogICBDLT4+UjogbmV3IE1vZGVsUmVnaXN0cnlNYW5hZ2VyKHRlc3RGdW5jdGlvbilcbiAqICAgQy0+PlI6IHJlZ2lzdGVyKE1vZGVsQ2xhc3MpXG4gKiAgIFItPj5SOiBTdG9yZSBpbiBjYWNoZVxuICogICBDLT4+UjogZ2V0KFwiTW9kZWxOYW1lXCIpXG4gKiAgIFItLT4+QzogTW9kZWxDbGFzcyBjb25zdHJ1Y3RvclxuICogICBDLT4+UjogYnVpbGQoZGF0YSwgXCJNb2RlbE5hbWVcIilcbiAqICAgUi0+PlI6IEdldCBjb25zdHJ1Y3RvciBmcm9tIGNhY2hlXG4gKiAgIFItPj5NOiBuZXcgTW9kZWxDbGFzcyhkYXRhKVxuICogICBNLS0+PlI6IE1vZGVsIGluc3RhbmNlXG4gKiAgIFItLT4+QzogTW9kZWwgaW5zdGFuY2VcbiAqL1xuZXhwb3J0IGNsYXNzIE1vZGVsUmVnaXN0cnlNYW5hZ2VyPE0gZXh0ZW5kcyBNb2RlbD4gaW1wbGVtZW50cyBNb2RlbFJlZ2lzdHJ5PE0+IHtcbiAgcHJpdmF0ZSBjYWNoZTogUmVjb3JkPHN0cmluZywgTW9kZWxDb25zdHJ1Y3RvcjxNPj4gPSB7fTtcbiAgcHJpdmF0ZSByZWFkb25seSB0ZXN0RnVuY3Rpb246IChvYmo6IG9iamVjdCkgPT4gYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICB0ZXN0RnVuY3Rpb246IChvYmo6IFJlY29yZDxzdHJpbmcsIGFueT4pID0+IGJvb2xlYW4gPSBNb2RlbC5pc01vZGVsXG4gICkge1xuICAgIHRoaXMudGVzdEZ1bmN0aW9uID0gdGVzdEZ1bmN0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWdpc3RlcnMgYSBtb2RlbCBjb25zdHJ1Y3RvciB3aXRoIHRoZSByZWdpc3RyeVxuICAgKiBAc3VtbWFyeSBBZGRzIGEgbW9kZWwgY29uc3RydWN0b3IgdG8gdGhlIHJlZ2lzdHJ5IGNhY2hlLCBtYWtpbmcgaXQgYXZhaWxhYmxlIGZvclxuICAgKiBsYXRlciByZXRyaWV2YWwgYW5kIGluc3RhbnRpYXRpb24uIElmIG5vIG5hbWUgaXMgcHJvdmlkZWQsIHRoZSBjb25zdHJ1Y3RvcidzIG5hbWVcbiAgICogcHJvcGVydHkgaXMgdXNlZCBhcyB0aGUga2V5IGluIHRoZSByZWdpc3RyeS5cbiAgICpcbiAgICogQHBhcmFtIHtNb2RlbENvbnN0cnVjdG9yPE0+fSBjb25zdHJ1Y3RvciAtIFRoZSBtb2RlbCBjb25zdHJ1Y3RvciB0byByZWdpc3RlclxuICAgKiBAcGFyYW0ge3N0cmluZ30gW25hbWVdIC0gT3B0aW9uYWwgbmFtZSB0byByZWdpc3RlciB0aGUgY29uc3RydWN0b3IgdW5kZXIsIGRlZmF1bHRzIHRvIGNvbnN0cnVjdG9yLm5hbWVcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBjb25zdHJ1Y3RvciBpcyBub3QgYSBmdW5jdGlvblxuICAgKi9cbiAgcmVnaXN0ZXIoY29uc3RydWN0b3I6IE1vZGVsQ29uc3RydWN0b3I8TT4sIG5hbWU/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodHlwZW9mIGNvbnN0cnVjdG9yICE9PSBcImZ1bmN0aW9uXCIpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiTW9kZWwgcmVnaXN0ZXJpbmcgZmFpbGVkLiBNaXNzaW5nIENsYXNzIG5hbWUgb3IgY29uc3RydWN0b3JcIlxuICAgICAgKTtcbiAgICBuYW1lID0gbmFtZSB8fCBjb25zdHJ1Y3Rvci5uYW1lO1xuICAgIHRoaXMuY2FjaGVbbmFtZV0gPSBjb25zdHJ1Y3RvcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBHZXRzIGEgcmVnaXN0ZXJlZCBNb2RlbCB7QGxpbmsgTW9kZWxDb25zdHJ1Y3Rvcn1cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICovXG4gIGdldChuYW1lOiBzdHJpbmcpOiBNb2RlbENvbnN0cnVjdG9yPE0+IHwgdW5kZWZpbmVkIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVbbmFtZV07XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IG9ialxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2NsYXp6XSB3aGVuIHByb3ZpZGVkLCBpdCB3aWxsIGF0dGVtcHQgdG8gZmluZCB0aGUgbWF0Y2hpbmcgY29uc3RydWN0b3JcbiAgICpcbiAgICogQHRocm93cyBFcnJvciBJZiBjbGF6eiBpcyBub3QgZm91bmQsIG9yIG9iaiBpcyBub3QgYSB7QGxpbmsgTW9kZWx9IG1lYW5pbmcgaXQgaGFzIG5vIHtAbGluayBNb2RlbEtleXMuQU5DSE9SfSBwcm9wZXJ0eVxuICAgKi9cbiAgYnVpbGQob2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge30sIGNsYXp6Pzogc3RyaW5nKTogTSB7XG4gICAgaWYgKCFjbGF6eiAmJiAhdGhpcy50ZXN0RnVuY3Rpb24ob2JqKSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlByb3ZpZGVkIG9iaiBpcyBub3QgYSBNb2RlbCBvYmplY3RcIik7XG4gICAgY29uc3QgbmFtZSA9IGNsYXp6IHx8IE1vZGVsLmdldE1ldGFkYXRhKG9iaiBhcyBhbnkpO1xuICAgIGlmICghKG5hbWUgaW4gdGhpcy5jYWNoZSkpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIHNmKFwiUHJvdmlkZWQgY2xhc3MgezB9IGlzIG5vdCBhIHJlZ2lzdGVyZWQgTW9kZWwgb2JqZWN0XCIsIG5hbWUpXG4gICAgICApO1xuICAgIHJldHVybiBuZXcgdGhpcy5jYWNoZVtuYW1lXShvYmopO1xuICB9XG59XG5cbi8qKlxuICogQHN1bW1hcnkgQnVsayBSZWdpc3RlcnMgTW9kZWxzXG4gKiBAZGVzY3JpcHRpb24gVXNlZnVsIHdoZW4gdXNpbmcgYnVuZGxlcnMgdGhhdCBtaWdodCBub3QgZXZhbHVhdGUgYWxsIHRoZSBjb2RlIGF0IG9uY2VcbiAqXG4gKiBAcGFyYW0ge0FycmF5PENvbnN0cnVjdG9yPFQ+PiB8IEFycmF5PHtuYW1lOiBzdHJpbmcsIGNvbnN0cnVjdG9yOiBDb25zdHJ1Y3RvcjxUPn0+fSBbbW9kZWxzXVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVsa01vZGVsUmVnaXN0ZXI8TSBleHRlbmRzIE1vZGVsPihcbiAgLi4ubW9kZWxzOiAoQ29uc3RydWN0b3I8TT4gfCB7IG5hbWU6IHN0cmluZzsgY29uc3RydWN0b3I6IENvbnN0cnVjdG9yPE0+IH0pW11cbikge1xuICBtb2RlbHMuZm9yRWFjaChcbiAgICAobTogQ29uc3RydWN0b3I8TT4gfCB7IG5hbWU6IHN0cmluZzsgY29uc3RydWN0b3I6IENvbnN0cnVjdG9yPE0+IH0pID0+IHtcbiAgICAgIGNvbnN0IGNvbnN0cnVjdG9yOiBDb25zdHJ1Y3RvcjxNPiA9IChcbiAgICAgICAgbS5jb25zdHJ1Y3RvciA/IG0uY29uc3RydWN0b3IgOiBtXG4gICAgICApIGFzIENvbnN0cnVjdG9yPE0+O1xuICAgICAgTW9kZWwucmVnaXN0ZXIoY29uc3RydWN0b3IsIChtIGFzIENvbnN0cnVjdG9yPE0+KS5uYW1lKTtcbiAgICB9XG4gICk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgQWJzdHJhY3QgY2xhc3MgcmVwcmVzZW50aW5nIGEgVmFsaWRhdGFibGUgTW9kZWwgb2JqZWN0XG4gKiBAZGVzY3JpcHRpb24gTWVhbnQgdG8gYmUgdXNlZCBhcyBhIGJhc2UgY2xhc3MgZm9yIGFsbCBNb2RlbCBjbGFzc2VzXG4gKlxuICogTW9kZWwgb2JqZWN0cyBtdXN0OlxuICogIC0gSGF2ZSBhbGwgdGhlaXIgcmVxdWlyZWQgcHJvcGVydGllcyBtYXJrZWQgd2l0aCAnISc7XG4gKiAgLSBIYXZlIGFsbCB0aGVpciBvcHRpb25hbCBwcm9wZXJ0aWVzIG1hcmtlZCBhcyAnPyc6XG4gKlxuICogQHBhcmFtIHtNb2RlbEFyZzxNb2RlbD59IG1vZGVsIGJhc2Ugb2JqZWN0IGZyb20gd2hpY2ggdG8gcG9wdWxhdGUgcHJvcGVydGllcyBmcm9tXG4gKlxuICogQGNsYXNzIE1vZGVsXG4gKiBAY2F0ZWdvcnkgTW9kZWxcbiAqIEBhYnN0cmFjdFxuICogQGltcGxlbWVudHMgVmFsaWRhdGFibGVcbiAqIEBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZVxuICpcbiAqIEBleGFtcGxlXG4gKiAgICAgIGNsYXNzIENsYXNzTmFtZSB7XG4gKiAgICAgICAgICBAcmVxdWlyZWQoKVxuICogICAgICAgICAgcmVxdWlyZWRQcm9wZXJ0eU5hbWUhOiBQcm9wZXJ0eVR5cGU7XG4gKlxuICogICAgICAgICAgb3B0aW9uYWxQcm9wZXJ0eU5hbWU/OiBQcm9wZXJ0eVR5cGU7XG4gKiAgICAgIH1cbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIE1vZGVsXG4gIGltcGxlbWVudHMgVmFsaWRhdGFibGUsIFNlcmlhbGl6YWJsZSwgSGFzaGFibGUsIENvbXBhcmFibGU8TW9kZWw+XG57XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKGFyZz86IE1vZGVsQXJnPE1vZGVsPikge31cblxuICAvKipcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIHRoZSBvYmplY3QgYWNjb3JkaW5nIHRvIGl0cyBkZWNvcmF0ZWQgcHJvcGVydGllc1xuICAgKlxuICAgKiBAcGFyYW0ge2FueVtdfSBbZXhjZXB0aW9uc10gcHJvcGVydGllcyBpbiB0aGUgb2JqZWN0IHRvIGJlIGlnbm9yZWQgZm9yIHRoZSB2YWxpZGF0aW9uLiBNYXJrZWQgYXMgJ2FueScgdG8gYWxsb3cgZm9yIGV4dGVuc2lvbiBidXQgZXhwZWN0cyBzdHJpbmdzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKC4uLmV4Y2VwdGlvbnM6IGFueVtdKTogTW9kZWxFcnJvckRlZmluaXRpb24gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB2YWxpZGF0ZSh0aGlzLCAuLi5leGNlcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBDb21wYXJlIG9iamVjdCBlcXVhbGl0eSByZWN1cnNpdmVseVxuICAgKiBAcGFyYW0ge2FueX0gb2JqIG9iamVjdCB0byBjb21wYXJlIHRvXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZXhjZXB0aW9uc10gcHJvcGVydHkgbmFtZXMgdG8gYmUgZXhjbHVkZWQgZnJvbSB0aGUgY29tcGFyaXNvblxuICAgKi9cbiAgcHVibGljIGVxdWFscyhvYmo6IGFueSwgLi4uZXhjZXB0aW9uczogc3RyaW5nW10pOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNFcXVhbCh0aGlzLCBvYmosIC4uLmV4Y2VwdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIHNlcmlhbGl6ZWQgbW9kZWwgYWNjb3JkaW5nIHRvIHRoZSBjdXJyZW50bHkgZGVmaW5lZCB7QGxpbmsgU2VyaWFsaXplcn1cbiAgICovXG4gIHNlcmlhbGl6ZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiBNb2RlbC5zZXJpYWxpemUodGhpcyk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgT3ZlcnJpZGUgdGhlIGltcGxlbWVudGF0aW9uIGZvciBqcydzICd0b1N0cmluZygpJyB3aGljaCBzdWNrcy4uLlxuICAgKiBAb3ZlcnJpZGVcbiAgICovXG4gIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLm5hbWUgKyBcIjogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLCB1bmRlZmluZWQsIDIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IERlZmluZXMgYSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGZvciBvYmplY3QgaGFzaC4gUmVsaWVzIG9uIGEgdmVyeSBiYXNpYyBpbXBsZW1lbnRhdGlvbiBiYXNlZCBvbiBKYXZhJ3Mgc3RyaW5nIGhhc2g7XG4gICAqL1xuICBwdWJsaWMgaGFzaCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBNb2RlbC5oYXNoKHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IERlc2VyaWFsaXplcyBhIE1vZGVsXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAgICpcbiAgICogQHRocm93cyB7RXJyb3J9IElmIGl0IGZhaWxzIHRvIHBhcnNlIHRoZSBzdHJpbmcsIG9yIGlmIGl0IGZhaWxzIHRvIGJ1aWxkIHRoZSBtb2RlbFxuICAgKi9cbiAgc3RhdGljIGRlc2VyaWFsaXplKHN0cjogc3RyaW5nKSB7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgTW9kZWwua2V5KE1vZGVsS2V5cy5TRVJJQUxJWkFUSU9OKSxcbiAgICAgIHRoaXMuY29uc3RydWN0b3JcbiAgICApO1xuXG4gICAgaWYgKG1ldGFkYXRhICYmIG1ldGFkYXRhLnNlcmlhbGl6ZXIpXG4gICAgICByZXR1cm4gU2VyaWFsaXphdGlvbi5kZXNlcmlhbGl6ZShcbiAgICAgICAgc3RyLFxuICAgICAgICBtZXRhZGF0YS5zZXJpYWxpemVyLFxuICAgICAgICAuLi4obWV0YWRhdGEuYXJncyB8fCBbXSlcbiAgICAgICk7XG4gICAgcmV0dXJuIFNlcmlhbGl6YXRpb24uZGVzZXJpYWxpemUoc3RyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZXBvcHVsYXRlcyB0aGUgT2JqZWN0IHByb3BlcnRpZXMgd2l0aCB0aGUgb25lcyBmcm9tIHRoZSBuZXcgb2JqZWN0XG4gICAqIEBkZXNjcmlwdGlvbiBJdGVyYXRlcyBhbGwgY29tbW9uIHByb3BlcnRpZXMgb2Ygb2JqIChpZiBleGlzdGluZykgYW5kIHNlbGYsIGFuZCBjb3BpZXMgdGhlbSBvbnRvIHNlbGZcbiAgICpcbiAgICogQHBhcmFtIHtUfSBzZWxmXG4gICAqIEBwYXJhbSB7VCB8IFJlY29yZDxzdHJpbmcsIGFueT59IFtvYmpdXG4gICAqXG4gICAqL1xuICBzdGF0aWMgZnJvbU9iamVjdDxUIGV4dGVuZHMgTW9kZWw+KFxuICAgIHNlbGY6IFQsXG4gICAgb2JqPzogVCB8IFJlY29yZDxzdHJpbmcsIGFueT5cbiAgKTogVCB7XG4gICAgaWYgKCFvYmopIG9iaiA9IHt9O1xuICAgIGZvciAoY29uc3QgcHJvcCBvZiBNb2RlbC5nZXRBdHRyaWJ1dGVzKHNlbGYpKSB7XG4gICAgICAoc2VsZiBhcyBhbnkpW3Byb3BdID0gKG9iaiBhcyBhbnkpW3Byb3BdIHx8IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIHNlbGY7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgUmVwb3B1bGF0ZXMgdGhlIGluc3RhbmNlIHdpdGggdGhlIG9uZXMgZnJvbSB0aGUgbmV3IE1vZGVsIE9iamVjdFxuICAgKiBAZGVzY3JpcHRpb24gSXRlcmF0ZXMgYWxsIGNvbW1vbiBwcm9wZXJ0aWVzIG9mIG9iaiAoaWYgZXhpc3RpbmcpIGFuZCBzZWxmLCBhbmQgY29waWVzIHRoZW0gb250byBzZWxmLlxuICAgKiBJcyBhd2FyZSBvZiBuZXN0ZWQgTW9kZWwgT2JqZWN0cyBhbmQgcmVidWlsZHMgdGhlbSBhbHNvLlxuICAgKiBXaGVuIExpc3QgcHJvcGVydGllcyBhcmUgZGVjb3JhdGVkIHdpdGgge0BsaW5rIGxpc3R9LCB0aGV5IGxpc3QgaXRlbXMgd2lsbCBhbHNvIGJlIHJlYnVpbHRcbiAgICpcbiAgICogQHBhcmFtIHtUfSBzZWxmXG4gICAqIEBwYXJhbSB7VCB8IFJlY29yZDxzdHJpbmcsIGFueT59IFtvYmpdXG4gICAqXG4gICAqL1xuICBzdGF0aWMgZnJvbU1vZGVsPFQgZXh0ZW5kcyBNb2RlbD4oc2VsZjogVCwgb2JqPzogVCB8IFJlY29yZDxzdHJpbmcsIGFueT4pOiBUIHtcbiAgICBpZiAoIW9iaikgb2JqID0ge307XG5cbiAgICBsZXQgZGVjb3JhdG9yczogRGVjb3JhdG9yTWV0YWRhdGFbXSwgZGVjOiBEZWNvcmF0b3JNZXRhZGF0YTtcblxuICAgIGNvbnN0IHByb3BzID0gTW9kZWwuZ2V0QXR0cmlidXRlcyhzZWxmKTtcblxuICAgIGZvciAoY29uc3QgcHJvcCBvZiBwcm9wcykge1xuICAgICAgKHNlbGYgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0gPVxuICAgICAgICAob2JqIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdIHx8IHVuZGVmaW5lZDtcbiAgICAgIGlmICh0eXBlb2YgKHNlbGYgYXMgYW55KVtwcm9wXSAhPT0gXCJvYmplY3RcIikgY29udGludWU7XG4gICAgICBjb25zdCBwcm9wTSA9IE1vZGVsLmlzUHJvcGVydHlNb2RlbChzZWxmLCBwcm9wKTtcbiAgICAgIGlmIChwcm9wTSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIChzZWxmIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdID0gTW9kZWwuYnVpbGQoXG4gICAgICAgICAgICAoc2VsZiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXSxcbiAgICAgICAgICAgIHR5cGVvZiBwcm9wTSA9PT0gXCJzdHJpbmdcIiA/IHByb3BNIDogdW5kZWZpbmVkXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgY29uc29sZS5sb2coZSk7XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFsbERlY29yYXRvcnM6IERlY29yYXRvck1ldGFkYXRhW10gPVxuICAgICAgICBSZWZsZWN0aW9uLmdldFByb3BlcnR5RGVjb3JhdG9ycyhcbiAgICAgICAgICBWYWxpZGF0aW9uS2V5cy5SRUZMRUNULFxuICAgICAgICAgIHNlbGYsXG4gICAgICAgICAgcHJvcFxuICAgICAgICApLmRlY29yYXRvcnM7XG4gICAgICBkZWNvcmF0b3JzID0gYWxsRGVjb3JhdG9ycy5maWx0ZXIoXG4gICAgICAgIChkOiBEZWNvcmF0b3JNZXRhZGF0YSkgPT5cbiAgICAgICAgICBbTW9kZWxLZXlzLlRZUEUsIFZhbGlkYXRpb25LZXlzLlRZUEUgYXMgc3RyaW5nXS5pbmRleE9mKGQua2V5KSAhPT0gLTFcbiAgICAgICk7XG4gICAgICBpZiAoIWRlY29yYXRvcnMgfHwgIWRlY29yYXRvcnMubGVuZ3RoKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3Ioc2YoXCJmYWlsZWQgdG8gZmluZCBkZWNvcmF0b3JzIGZvciBwcm9wZXJ0eSB7MH1cIiwgcHJvcCkpO1xuICAgICAgZGVjID0gZGVjb3JhdG9ycy5wb3AoKSBhcyBEZWNvcmF0b3JNZXRhZGF0YTtcbiAgICAgIGNvbnN0IGNsYXp6ID0gZGVjLnByb3BzLm5hbWVcbiAgICAgICAgPyBbZGVjLnByb3BzLm5hbWVdXG4gICAgICAgIDogQXJyYXkuaXNBcnJheShkZWMucHJvcHMuY3VzdG9tVHlwZXMpXG4gICAgICAgICAgPyBkZWMucHJvcHMuY3VzdG9tVHlwZXNcbiAgICAgICAgICA6IFtkZWMucHJvcHMuY3VzdG9tVHlwZXNdO1xuICAgICAgY29uc3QgcmVzZXJ2ZWQgPSBPYmplY3QudmFsdWVzKFJlc2VydmVkTW9kZWxzKS5tYXAoKHYpID0+XG4gICAgICAgIHYudG9Mb3dlckNhc2UoKVxuICAgICAgKSBhcyBzdHJpbmdbXTtcblxuICAgICAgY2xhenouZm9yRWFjaCgoYykgPT4ge1xuICAgICAgICBpZiAocmVzZXJ2ZWQuaW5kZXhPZihjLnRvTG93ZXJDYXNlKCkpID09PSAtMSlcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgc3dpdGNoIChjKSB7XG4gICAgICAgICAgICAgIGNhc2UgXCJBcnJheVwiOlxuICAgICAgICAgICAgICBjYXNlIFwiU2V0XCI6XG4gICAgICAgICAgICAgICAgaWYgKGFsbERlY29yYXRvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBsaXN0RGVjID0gYWxsRGVjb3JhdG9ycy5maW5kKFxuICAgICAgICAgICAgICAgICAgICAoZCkgPT4gZC5rZXkgPT09IFZhbGlkYXRpb25LZXlzLkxJU1RcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICBpZiAobGlzdERlYykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjbGF6ek5hbWUgPSAobGlzdERlYy5wcm9wcy5jbGF6eiBhcyBzdHJpbmdbXSkuZmluZChcbiAgICAgICAgICAgICAgICAgICAgICAodDogc3RyaW5nKSA9PiAhanNUeXBlcy5pbmNsdWRlcyh0LnRvTG93ZXJDYXNlKCkpXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjID09PSBcIkFycmF5XCIpXG4gICAgICAgICAgICAgICAgICAgICAgKHNlbGYgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0gPSAoXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmIGFzIFJlY29yZDxzdHJpbmcsIGFueT5cbiAgICAgICAgICAgICAgICAgICAgICApW3Byb3BdLm1hcCgoZWw6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtcIm9iamVjdFwiLCBcImZ1bmN0aW9uXCJdLmluY2x1ZGVzKHR5cGVvZiBlbCkgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhenpOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgID8gTW9kZWwuYnVpbGQoZWwsIGNsYXp6TmFtZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgOiBlbDtcbiAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT09IFwiU2V0XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzID0gbmV3IFNldCgpO1xuICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdiBvZiAoc2VsZiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICBbXCJvYmplY3RcIiwgXCJmdW5jdGlvblwiXS5pbmNsdWRlcyh0eXBlb2YgdikgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhenpOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcy5hZGQoTW9kZWwuYnVpbGQodiwgY2xhenpOYW1lKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBzLmFkZCh2KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgKHNlbGYgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0gPSBzO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGlmICgoc2VsZiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXSlcbiAgICAgICAgICAgICAgICAgIChzZWxmIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdID0gTW9kZWwuYnVpbGQoXG4gICAgICAgICAgICAgICAgICAgIChzZWxmIGFzIGFueSlbcHJvcF0sXG4gICAgICAgICAgICAgICAgICAgIGNcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcuIHdlIGhhdmUgbm8gcmVnaXN0cnkgb2YgdGhpcyBjbGFzc1xuICAgICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gc2VsZjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBTZXRzIHRoZSBHbG9iYWwge0BsaW5rIE1vZGVsQnVpbGRlckZ1bmN0aW9ufVxuICAgKiBAcGFyYW0ge01vZGVsQnVpbGRlckZ1bmN0aW9ufSBbYnVpbGRlcl1cbiAgICovXG4gIHN0YXRpYyBzZXRCdWlsZGVyKGJ1aWxkZXI/OiBNb2RlbEJ1aWxkZXJGdW5jdGlvbikge1xuICAgIG1vZGVsQnVpbGRlckZ1bmN0aW9uID0gYnVpbGRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgdGhlIGN1cnJlbnQgZ2xvYmFsIHtAbGluayBNb2RlbEJ1aWxkZXJGdW5jdGlvbn1cbiAgICovXG4gIHN0YXRpYyBnZXRCdWlsZGVyKCk6IE1vZGVsQnVpbGRlckZ1bmN0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gbW9kZWxCdWlsZGVyRnVuY3Rpb247XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY3VycmVudCB7QGxpbmsgTW9kZWxSZWdpc3RyeU1hbmFnZXJ9XG4gICAqXG4gICAqIEByZXR1cm4gTW9kZWxSZWdpc3RyeSwgZGVmYXVsdHMgdG8ge0BsaW5rIE1vZGVsUmVnaXN0cnlNYW5hZ2VyfVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0UmVnaXN0cnkoKSB7XG4gICAgaWYgKCFhY3RpbmdNb2RlbFJlZ2lzdHJ5KSBhY3RpbmdNb2RlbFJlZ2lzdHJ5ID0gbmV3IE1vZGVsUmVnaXN0cnlNYW5hZ2VyKCk7XG4gICAgcmV0dXJuIGFjdGluZ01vZGVsUmVnaXN0cnk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY3VycmVudCBhY3RpbmdNb2RlbFJlZ2lzdHJ5XG4gICAqXG4gICAqIEBwYXJhbSB7QnVpbGRlclJlZ2lzdHJ5fSBtb2RlbFJlZ2lzdHJ5IHRoZSBuZXcgaW1wbGVtZW50YXRpb24gb2YgUmVnaXN0cnlcbiAgICovXG4gIHN0YXRpYyBzZXRSZWdpc3RyeShtb2RlbFJlZ2lzdHJ5OiBCdWlsZGVyUmVnaXN0cnk8YW55Pikge1xuICAgIGFjdGluZ01vZGVsUmVnaXN0cnkgPSBtb2RlbFJlZ2lzdHJ5O1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHJlZ2lzdGVyIG5ldyBNb2RlbHNcbiAgICogQHBhcmFtIHthbnl9IGNvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbbmFtZV0gd2hlbiBub3QgZGVmaW5lZCwgdGhlIG5hbWUgb2YgdGhlIGNvbnN0cnVjdG9yIHdpbGwgYmUgdXNlZFxuICAgKlxuICAgKiBAc2VlIE1vZGVsUmVnaXN0cnlcbiAgICovXG4gIHN0YXRpYyByZWdpc3RlcjxUIGV4dGVuZHMgTW9kZWw+KFxuICAgIGNvbnN0cnVjdG9yOiBNb2RlbENvbnN0cnVjdG9yPFQ+LFxuICAgIG5hbWU/OiBzdHJpbmdcbiAgKTogdm9pZCB7XG4gICAgcmV0dXJuIE1vZGVsLmdldFJlZ2lzdHJ5KCkucmVnaXN0ZXIoY29uc3RydWN0b3IsIG5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEdldHMgYSByZWdpc3RlcmVkIE1vZGVsIHtAbGluayBNb2RlbENvbnN0cnVjdG9yfVxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICAgKlxuICAgKiBAc2VlIE1vZGVsUmVnaXN0cnlcbiAgICovXG4gIHN0YXRpYyBnZXQ8VCBleHRlbmRzIE1vZGVsPihuYW1lOiBzdHJpbmcpOiBNb2RlbENvbnN0cnVjdG9yPFQ+IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gTW9kZWwuZ2V0UmVnaXN0cnkoKS5nZXQobmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBvYmpcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtjbGF6el0gd2hlbiBwcm92aWRlZCwgaXQgd2lsbCBhdHRlbXB0IHRvIGZpbmQgdGhlIG1hdGNoaW5nIGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEB0aHJvd3MgRXJyb3IgSWYgY2xhenogaXMgbm90IGZvdW5kLCBvciBvYmogaXMgbm90IGEge0BsaW5rIE1vZGVsfSBtZWFuaW5nIGl0IGhhcyBubyB7QGxpbmsgTW9kZWxLZXlzLkFOQ0hPUn0gcHJvcGVydHlcbiAgICpcbiAgICogQHNlZSBNb2RlbFJlZ2lzdHJ5XG4gICAqL1xuICBzdGF0aWMgYnVpbGQ8VCBleHRlbmRzIE1vZGVsPihcbiAgICBvYmo6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fSxcbiAgICBjbGF6ej86IHN0cmluZ1xuICApOiBUIHtcbiAgICByZXR1cm4gTW9kZWwuZ2V0UmVnaXN0cnkoKS5idWlsZChvYmosIGNsYXp6KTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRNZXRhZGF0YTxWIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBWKSB7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgTW9kZWwua2V5KE1vZGVsS2V5cy5NT0RFTCksXG4gICAgICBtb2RlbC5jb25zdHJ1Y3RvclxuICAgICk7XG4gICAgaWYgKCFtZXRhZGF0YSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJjb3VsZCBub3QgZmluZCBtZXRhZGF0YSBmb3IgcHJvdmlkZWQgXCIgKyBtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lXG4gICAgICApO1xuICAgIHJldHVybiBtZXRhZGF0YTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRBdHRyaWJ1dGVzPFYgZXh0ZW5kcyBNb2RlbD4obW9kZWw6IENvbnN0cnVjdG9yPFY+IHwgVikge1xuICAgIGNvbnN0IHJlc3VsdDogc3RyaW5nW10gPSBbXTtcbiAgICBsZXQgcHJvdG90eXBlID1cbiAgICAgIG1vZGVsIGluc3RhbmNlb2YgTW9kZWxcbiAgICAgICAgPyBPYmplY3QuZ2V0UHJvdG90eXBlT2YobW9kZWwpXG4gICAgICAgIDogKG1vZGVsIGFzIGFueSkucHJvdG90eXBlO1xuICAgIHdoaWxlIChwcm90b3R5cGUgIT0gbnVsbCkge1xuICAgICAgY29uc3QgcHJvcHM6IHN0cmluZ1tdID0gcHJvdG90eXBlW01vZGVsS2V5cy5BVFRSSUJVVEVdO1xuICAgICAgaWYgKHByb3BzKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKC4uLnByb3BzKTtcbiAgICAgIH1cbiAgICAgIHByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90b3R5cGUpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgc3RhdGljIGVxdWFsczxWIGV4dGVuZHMgTW9kZWw+KG9iajE6IFYsIG9iajI6IFYsIC4uLmV4Y2VwdGlvbnM6IGFueVtdKSB7XG4gICAgcmV0dXJuIGlzRXF1YWwob2JqMSwgb2JqMiwgLi4uZXhjZXB0aW9ucyk7XG4gIH1cblxuICBzdGF0aWMgaGFzRXJyb3JzPFYgZXh0ZW5kcyBNb2RlbD4obW9kZWw6IFYsIC4uLnByb3BzVG9JZ25vcmU6IHN0cmluZ1tdKSB7XG4gICAgcmV0dXJuIHZhbGlkYXRlKG1vZGVsLCAuLi5wcm9wc1RvSWdub3JlKTtcbiAgfVxuXG4gIHN0YXRpYyBzZXJpYWxpemU8ViBleHRlbmRzIE1vZGVsPihtb2RlbDogVikge1xuICAgIGNvbnN0IG1ldGFkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgIE1vZGVsLmtleShNb2RlbEtleXMuU0VSSUFMSVpBVElPTiksXG4gICAgICBtb2RlbC5jb25zdHJ1Y3RvclxuICAgICk7XG5cbiAgICBpZiAobWV0YWRhdGEgJiYgbWV0YWRhdGEuc2VyaWFsaXplcilcbiAgICAgIHJldHVybiBTZXJpYWxpemF0aW9uLnNlcmlhbGl6ZShcbiAgICAgICAgdGhpcyxcbiAgICAgICAgbWV0YWRhdGEuc2VyaWFsaXplcixcbiAgICAgICAgLi4uKG1ldGFkYXRhLmFyZ3MgfHwgW10pXG4gICAgICApO1xuICAgIHJldHVybiBTZXJpYWxpemF0aW9uLnNlcmlhbGl6ZShtb2RlbCk7XG4gIH1cblxuICBzdGF0aWMgaGFzaDxWIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBWKSB7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgTW9kZWwua2V5KE1vZGVsS2V5cy5IQVNISU5HKSxcbiAgICAgIG1vZGVsLmNvbnN0cnVjdG9yXG4gICAgKTtcblxuICAgIGlmIChtZXRhZGF0YSAmJiBtZXRhZGF0YS5hbGdvcml0aG0pXG4gICAgICByZXR1cm4gSGFzaGluZy5oYXNoKG1vZGVsLCBtZXRhZGF0YS5hbGdvcml0aG0sIC4uLihtZXRhZGF0YS5hcmdzIHx8IFtdKSk7XG4gICAgcmV0dXJuIEhhc2hpbmcuaGFzaChtb2RlbCk7XG4gIH1cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEJ1aWxkcyB0aGUga2V5IHRvIHN0b3JlIGFzIE1ldGFkYXRhIHVuZGVyIFJlZmxlY3Rpb25zXG4gICAqIEBkZXNjcmlwdGlvbiBjb25jYXRlbmF0ZXMge0BsaW5rIE1vZGVsS2V5cyNSRUZMRUNUfSB3aXRoIHRoZSBwcm92aWRlZCBrZXlcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0clxuICAgKi9cbiAgc3RhdGljIGtleShzdHI6IHN0cmluZykge1xuICAgIHJldHVybiBNb2RlbEtleXMuUkVGTEVDVCArIHN0cjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRGV0ZXJtaW5lcyBpZiBhbiBvYmplY3QgaXMgYSBtb2RlbCBpbnN0YW5jZSBvciBoYXMgbW9kZWwgbWV0YWRhdGFcbiAgICogQHN1bW1hcnkgQ2hlY2tzIHdoZXRoZXIgYSBnaXZlbiBvYmplY3QgaXMgZWl0aGVyIGFuIGluc3RhbmNlIG9mIHRoZSBNb2RlbCBjbGFzcyBvclxuICAgKiBoYXMgbW9kZWwgbWV0YWRhdGEgYXR0YWNoZWQgdG8gaXQuIFRoaXMgZnVuY3Rpb24gaXMgZXNzZW50aWFsIGZvciBzZXJpYWxpemF0aW9uIGFuZFxuICAgKiBkZXNlcmlhbGl6YXRpb24gcHJvY2Vzc2VzLCBhcyBpdCBoZWxwcyBpZGVudGlmeSBtb2RlbCBvYmplY3RzIHRoYXQgbmVlZCBzcGVjaWFsIGhhbmRsaW5nLlxuICAgKiBJdCBzYWZlbHkgaGFuZGxlcyBwb3RlbnRpYWwgZXJyb3JzIGR1cmluZyBtZXRhZGF0YSByZXRyaWV2YWwuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gdGFyZ2V0IC0gVGhlIG9iamVjdCB0byBjaGVja1xuICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBvYmplY3QgaXMgYSBtb2RlbCBpbnN0YW5jZSBvciBoYXMgbW9kZWwgbWV0YWRhdGEsIGZhbHNlIG90aGVyd2lzZVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIC8vIENoZWNrIGlmIGFuIG9iamVjdCBpcyBhIG1vZGVsXG4gICAqIGNvbnN0IHVzZXIgPSBuZXcgVXNlcih7IG5hbWU6IFwiSm9oblwiIH0pO1xuICAgKiBjb25zdCBpc1VzZXJNb2RlbCA9IGlzTW9kZWwodXNlcik7IC8vIHRydWVcbiAgICpcbiAgICogLy8gQ2hlY2sgYSBwbGFpbiBvYmplY3RcbiAgICogY29uc3QgcGxhaW5PYmplY3QgPSB7IG5hbWU6IFwiSm9oblwiIH07XG4gICAqIGNvbnN0IGlzUGxhaW5PYmplY3RNb2RlbCA9IGlzTW9kZWwocGxhaW5PYmplY3QpOyAvLyBmYWxzZVxuICAgKiBgYGBcbiAgICovXG4gIHN0YXRpYyBpc01vZGVsKHRhcmdldDogUmVjb3JkPHN0cmluZywgYW55Pikge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gdGFyZ2V0IGluc3RhbmNlb2YgTW9kZWwgfHwgISFNb2RlbC5nZXRNZXRhZGF0YSh0YXJnZXQgYXMgYW55KTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENoZWNrcyBpZiBhIHByb3BlcnR5IG9mIGEgbW9kZWwgaXMgaXRzZWxmIGEgbW9kZWwgb3IgaGFzIGEgbW9kZWwgdHlwZVxuICAgKiBAc3VtbWFyeSBEZXRlcm1pbmVzIHdoZXRoZXIgYSBzcGVjaWZpYyBwcm9wZXJ0eSBvZiBhIG1vZGVsIGluc3RhbmNlIGlzIGVpdGhlciBhIG1vZGVsIGluc3RhbmNlXG4gICAqIG9yIGhhcyBhIHR5cGUgdGhhdCBpcyByZWdpc3RlcmVkIGFzIGEgbW9kZWwuIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCBmb3IgbW9kZWwgc2VyaWFsaXphdGlvblxuICAgKiBhbmQgZGVzZXJpYWxpemF0aW9uIHRvIHByb3Blcmx5IGhhbmRsZSBuZXN0ZWQgbW9kZWxzLlxuICAgKiBAdGVtcGxhdGUgTSBleHRlbmRzIHtAbGluayBNb2RlbH1cbiAgICogQHBhcmFtIHtNfSB0YXJnZXQgLSBUaGUgbW9kZWwgaW5zdGFuY2UgdG8gY2hlY2tcbiAgICogQHBhcmFtIHtzdHJpbmd9IGF0dHJpYnV0ZSAtIFRoZSBwcm9wZXJ0eSBuYW1lIHRvIGNoZWNrXG4gICAqIEByZXR1cm4ge2Jvb2xlYW4gfCBzdHJpbmcgfCB1bmRlZmluZWR9IFJldHVybnMgdHJ1ZSBpZiB0aGUgcHJvcGVydHkgaXMgYSBtb2RlbCBpbnN0YW5jZSxcbiAgICogdGhlIG1vZGVsIG5hbWUgaWYgdGhlIHByb3BlcnR5IGhhcyBhIG1vZGVsIHR5cGUsIG9yIHVuZGVmaW5lZCBpZiBub3QgYSBtb2RlbFxuICAgKi9cbiAgc3RhdGljIGlzUHJvcGVydHlNb2RlbDxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIHRhcmdldDogTSxcbiAgICBhdHRyaWJ1dGU6IHN0cmluZ1xuICApOiBib29sZWFuIHwgc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoTW9kZWwuaXNNb2RlbCgodGFyZ2V0IGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW2F0dHJpYnV0ZV0pKSByZXR1cm4gdHJ1ZTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoTW9kZWxLZXlzLlRZUEUsIHRhcmdldCwgYXR0cmlidXRlKTtcbiAgICByZXR1cm4gTW9kZWwuZ2V0KG1ldGFkYXRhLm5hbWUpID8gbWV0YWRhdGEubmFtZSA6IHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiaW1wb3J0IHsgQ29uc3RydWN0b3IgfSBmcm9tIFwiLi4vbW9kZWwvdHlwZXNcIjtcbmltcG9ydCB7IFNlcmlhbGl6ZXIgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiLi4vbW9kZWwvTW9kZWxcIjtcbmltcG9ydCB7IE1vZGVsS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuXG5leHBvcnQgY29uc3QgRGVmYXVsdFNlcmlhbGl6YXRpb25NZXRob2QgPSBcImpzb25cIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBDb25jcmV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBhIHtAbGluayBTZXJpYWxpemVyfSBpbiBKU09OIGZvcm1hdFxuICogQGRlc2NyaXB0aW9uIEpTJ3MgbmF0aXZlIEpTT04uc3RyaW5naWZ5ICh1c2VkIGhlcmUpIGlzIG5vdCBkZXRlcm1pbmlzdGljXG4gKiBhbmQgdGhlcmVmb3JlIHNob3VsZCBub3QgYmUgdXNlZCBmb3IgaGFzaGluZyBwdXJwb3Nlc1xuICpcbiAqIFRvIGtlZXAgZGVwZW5kZW5jaWVzIGxvdywgd2Ugd2lsbCBub3QgaW1wbGVtZW50IHRoaXMsIGJ1dCB3ZSByZWNvbW1lbmRcbiAqIGltcGxlbWVudGluZyBhIHNpbWlsYXIge0BsaW5rIEpTT05TZXJpYWxpemVyfSB1c2luZyAnZGV0ZXJtaW5pc3RpYy1qc29uJyBsaWJyYXJpZXNcbiAqXG4gKiBAY2xhc3MgSlNPTlNlcmlhbGl6ZXJcbiAqIEBpbXBsZW1lbnRzIFNlcmlhbGl6ZXJcbiAqXG4gKiBAY2F0ZWdvcnkgTW9kZWxcbiAqL1xuZXhwb3J0IGNsYXNzIEpTT05TZXJpYWxpemVyPFQgZXh0ZW5kcyBNb2RlbD4gaW1wbGVtZW50cyBTZXJpYWxpemVyPFQ+IHtcbiAgY29uc3RydWN0b3IoKSB7fVxuICAvKipcbiAgICogQHN1bW1hcnkgcHJlcGFyZXMgdGhlIG1vZGVsIGZvciBzZXJpYWxpemF0aW9uXG4gICAqIEBkZXNjcmlwdGlvbiByZXR1cm5zIGEgc2hhbGxvdyBjb3B5IG9mIHRoZSBvYmplY3QsIGNvbnRhaW5pbmcgYW4gZW51bWVyYWJsZSB7QGxpbmsgTW9kZWxLZXlzI0FOQ0hPUn0gcHJvcGVydHlcbiAgICogc28gdGhlIG9iamVjdCBjYW4gYmUgcmVjb2duaXplZCB1cG9uIGRlc2VyaWFsaXphdGlvblxuICAgKlxuICAgKiBAcGFyYW0ge1R9IG1vZGVsXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIHByb3RlY3RlZCBwcmVTZXJpYWxpemUobW9kZWw6IFQpIHtcbiAgICAvLyBUT0RPOiBuZXN0ZWQgcHJlc2VyaWFsaXphdGlvbiAoc28gaW5jcmVhc2UgcGVyZm9ybWFuY2Ugd2hlbiBkZXNlcmlhbGl6aW5nKVxuICAgIGNvbnN0IHRvU2VyaWFsaXplOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gT2JqZWN0LmFzc2lnbih7fSwgbW9kZWwpO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gTW9kZWwuZ2V0TWV0YWRhdGEobW9kZWwpO1xuICAgIHRvU2VyaWFsaXplW01vZGVsS2V5cy5BTkNIT1JdID0gbWV0YWRhdGEgfHwgbW9kZWwuY29uc3RydWN0b3IubmFtZTtcbiAgICByZXR1cm4gdG9TZXJpYWxpemU7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgUmVidWlsZHMgYSBtb2RlbCBmcm9tIGEgc2VyaWFsaXphdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gICAqXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBpdCBmYWlscyB0byBwYXJzZSB0aGUgc3RyaW5nLCBvciB0byBidWlsZCB0aGUgbW9kZWxcbiAgICovXG4gIGRlc2VyaWFsaXplKHN0cjogc3RyaW5nKTogVCB7XG4gICAgY29uc3QgZGVzZXJpYWxpemF0aW9uID0gSlNPTi5wYXJzZShzdHIpO1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGRlc2VyaWFsaXphdGlvbltNb2RlbEtleXMuQU5DSE9SXTtcbiAgICBpZiAoIWNsYXNzTmFtZSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvdWxkIG5vdCBmaW5kIGNsYXNzIHJlZmVyZW5jZSBpbiBzZXJpYWxpemVkIG1vZGVsXCIpO1xuICAgIGNvbnN0IG1vZGVsOiBUID0gTW9kZWwuYnVpbGQoZGVzZXJpYWxpemF0aW9uLCBjbGFzc05hbWUpIGFzIHVua25vd24gYXMgVDtcbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgU2VyaWFsaXplcyBhIG1vZGVsXG4gICAqIEBwYXJhbSB7VH0gbW9kZWxcbiAgICpcbiAgICogQHRocm93cyB7RXJyb3J9IGlmIGZhaWxzIHRvIHNlcmlhbGl6ZVxuICAgKi9cbiAgc2VyaWFsaXplKG1vZGVsOiBUKTogc3RyaW5nIHtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodGhpcy5wcmVTZXJpYWxpemUobW9kZWwpKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgU2VyaWFsaXphdGlvbiB7XG4gIHByaXZhdGUgc3RhdGljIGN1cnJlbnQ6IHN0cmluZyA9IERlZmF1bHRTZXJpYWxpemF0aW9uTWV0aG9kO1xuXG4gIHByaXZhdGUgc3RhdGljIGNhY2hlOiBSZWNvcmQ8c3RyaW5nLCBTZXJpYWxpemVyPGFueT4+ID0ge1xuICAgIGpzb246IG5ldyBKU09OU2VyaWFsaXplcigpLFxuICB9O1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7fVxuXG4gIHByaXZhdGUgc3RhdGljIGdldChrZXk6IHN0cmluZyk6IGFueSB7XG4gICAgaWYgKGtleSBpbiB0aGlzLmNhY2hlKSByZXR1cm4gdGhpcy5jYWNoZVtrZXldO1xuICAgIHRocm93IG5ldyBFcnJvcihgTm8gc2VyaWFsaXphdGlvbiBtZXRob2QgcmVnaXN0ZXJlZCB1bmRlciAke2tleX1gKTtcbiAgfVxuXG4gIHN0YXRpYyByZWdpc3RlcihcbiAgICBrZXk6IHN0cmluZyxcbiAgICBmdW5jOiBDb25zdHJ1Y3RvcjxTZXJpYWxpemVyPGFueT4+LFxuICAgIHNldERlZmF1bHQgPSBmYWxzZVxuICApOiB2b2lkIHtcbiAgICBpZiAoa2V5IGluIHRoaXMuY2FjaGUpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFNlcmlhbGl6YXRpb24gbWV0aG9kICR7a2V5fSBhbHJlYWR5IHJlZ2lzdGVyZWRgKTtcbiAgICB0aGlzLmNhY2hlW2tleV0gPSBuZXcgZnVuYygpO1xuICAgIGlmIChzZXREZWZhdWx0KSB0aGlzLmN1cnJlbnQgPSBrZXk7XG4gIH1cblxuICBzdGF0aWMgc2VyaWFsaXplKG9iajogYW55LCBtZXRob2Q/OiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgaWYgKCFtZXRob2QpIHJldHVybiB0aGlzLmdldCh0aGlzLmN1cnJlbnQpLnNlcmlhbGl6ZShvYmosIC4uLmFyZ3MpO1xuICAgIHJldHVybiB0aGlzLmdldChtZXRob2QpLnNlcmlhbGl6ZShvYmosIC4uLmFyZ3MpO1xuICB9XG5cbiAgc3RhdGljIGRlc2VyaWFsaXplKG9iajogc3RyaW5nLCBtZXRob2Q/OiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgaWYgKCFtZXRob2QpIHJldHVybiB0aGlzLmdldCh0aGlzLmN1cnJlbnQpLmRlc2VyaWFsaXplKG9iaiwgLi4uYXJncyk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KG1ldGhvZCkuZGVzZXJpYWxpemUob2JqLCAuLi5hcmdzKTtcbiAgfVxuXG4gIHN0YXRpYyBzZXREZWZhdWx0KG1ldGhvZDogc3RyaW5nKSB7XG4gICAgdGhpcy5jdXJyZW50ID0gdGhpcy5nZXQobWV0aG9kKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBWYWxpZGF0aW9uIH0gZnJvbSBcIi4uL1ZhbGlkYXRpb25cIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yIH0gZnJvbSBcIi4uLy4uL21vZGVsL3R5cGVzXCI7XG5pbXBvcnQgeyBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgYXBwbHksIG1ldGFkYXRhIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBWYWxpZGF0b3JEZWZpbml0aW9uIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgTWFya3MgdGhlIGNsYXNzIGFzIGEgdmFsaWRhdG9yIGZvciBhIGNlcnRhaW4ga2V5LlxuICogQGRlc2NyaXB0aW9uIFJlZ2lzdGVycyB0aGUgY2xhc3MgaW4gdGhlIHtAbGluayBWYWxpZGF0aW9ufSB3aXRoIHRoZSBwcm92aWRlZCBrZXlcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5cyB0aGUgdmFsaWRhdGlvbiBrZXlcbiAqXG4gKiBAZnVuY3Rpb24gdmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRvcjxUIGV4dGVuZHMgVmFsaWRhdG9yPiguLi5rZXlzOiBzdHJpbmdbXSkge1xuICByZXR1cm4gYXBwbHkoXG4gICAgKChvcmlnaW5hbDogQ29uc3RydWN0b3I8VD4pID0+IHtcbiAgICAgIGtleXMuZm9yRWFjaCgoazogc3RyaW5nKSA9PiB7XG4gICAgICAgIFZhbGlkYXRpb24ucmVnaXN0ZXIoe1xuICAgICAgICAgIHZhbGlkYXRvcjogb3JpZ2luYWwsXG4gICAgICAgICAgdmFsaWRhdGlvbktleTogayxcbiAgICAgICAgICBzYXZlOiB0cnVlLFxuICAgICAgICB9IGFzIFZhbGlkYXRvckRlZmluaXRpb24pO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gb3JpZ2luYWw7XG4gICAgfSkgYXMgQ2xhc3NEZWNvcmF0b3IsXG4gICAgbWV0YWRhdGEoVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuVkFMSURBVE9SKSwga2V5cylcbiAgKTtcbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IERhdGVWYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvciBmb3IgY2hlY2tpbmcgaWYgYSB2YWx1ZSBpcyBhIHZhbGlkIGRhdGVcbiAqIEBzdW1tYXJ5IFRoZSBEYXRlVmFsaWRhdG9yIGNoZWNrcyBpZiBhIHZhbHVlIGlzIGEgdmFsaWQgZGF0ZSBvYmplY3Qgb3IgYSBzdHJpbmcgdGhhdCBjYW4gYmUgY29udmVydGVkIHRvIGEgdmFsaWQgZGF0ZS5cbiAqIEl0IHZhbGlkYXRlcyB0aGF0IHRoZSB2YWx1ZSByZXByZXNlbnRzIGEgcmVhbCBkYXRlIGFuZCBub3QgYW4gaW52YWxpZCBkYXRlIGxpa2UgXCIyMDIzLTAyLTMxXCIuXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIHZhbGlkYXRpb24gZmFpbHMsIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0RBVEV9XG4gKiBAY2xhc3MgRGF0ZVZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBDcmVhdGUgYSBkYXRlIHZhbGlkYXRvciB3aXRoIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogY29uc3QgZGF0ZVZhbGlkYXRvciA9IG5ldyBEYXRlVmFsaWRhdG9yKCk7XG4gKlxuICogLy8gQ3JlYXRlIGEgZGF0ZSB2YWxpZGF0b3Igd2l0aCBjdXN0b20gZXJyb3IgbWVzc2FnZVxuICogY29uc3QgY3VzdG9tRGF0ZVZhbGlkYXRvciA9IG5ldyBEYXRlVmFsaWRhdG9yKFwiUGxlYXNlIGVudGVyIGEgdmFsaWQgZGF0ZVwiKTtcbiAqXG4gKiAvLyBWYWxpZGF0ZSBhIGRhdGVcbiAqIGNvbnN0IHJlc3VsdCA9IGRhdGVWYWxpZGF0b3IuaGFzRXJyb3JzKG5ldyBEYXRlKCkpOyAvLyB1bmRlZmluZWQgKHZhbGlkKVxuICogY29uc3QgaW52YWxpZFJlc3VsdCA9IGRhdGVWYWxpZGF0b3IuaGFzRXJyb3JzKFwibm90IGEgZGF0ZVwiKTsgLy8gUmV0dXJucyBlcnJvciBtZXNzYWdlIChpbnZhbGlkKVxuICogYGBgXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IFYgYXMgRGF0ZVZhbGlkYXRvclxuICpcbiAqICAgQy0+PlY6IG5ldyBEYXRlVmFsaWRhdG9yKG1lc3NhZ2UpXG4gKiAgIEMtPj5WOiBoYXNFcnJvcnModmFsdWUsIG9wdGlvbnMpXG4gKiAgIGFsdCB2YWx1ZSBpcyB1bmRlZmluZWRcbiAqICAgICBWLS0+PkM6IHVuZGVmaW5lZCAodmFsaWQpXG4gKiAgIGVsc2UgdmFsdWUgaXMgc3RyaW5nXG4gKiAgICAgVi0+PlY6IENvbnZlcnQgdG8gRGF0ZVxuICogICBlbmRcbiAqICAgYWx0IERhdGUgaXMgaW52YWxpZCAoTmFOKVxuICogICAgIFYtLT4+QzogRXJyb3IgbWVzc2FnZVxuICogICBlbHNlIERhdGUgaXMgdmFsaWRcbiAqICAgICBWLS0+PkM6IHVuZGVmaW5lZCAodmFsaWQpXG4gKiAgIGVuZFxuICovXG5AdmFsaWRhdG9yKFZhbGlkYXRpb25LZXlzLkRBVEUpXG5leHBvcnQgY2xhc3MgRGF0ZVZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvcjxEYXRlVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkRBVEUpIHtcbiAgICBzdXBlcihtZXNzYWdlLCBOdW1iZXIubmFtZSwgRGF0ZS5uYW1lLCBTdHJpbmcubmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENoZWNrcyBpZiB0aGUgcHJvdmlkZWQgdmFsdWUgaXMgYSB2YWxpZCBkYXRlXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyB0aGF0IHRoZSBnaXZlbiB2YWx1ZSBpcyBhIHZhbGlkIGRhdGUuIElmIHRoZSB2YWx1ZSBpcyBhIHN0cmluZyxcbiAgICogaXQgYXR0ZW1wdHMgdG8gY29udmVydCBpdCB0byBhIERhdGUgb2JqZWN0LiBSZXR1cm5zIGFuIGVycm9yIG1lc3NhZ2UgaWYgdGhlIGRhdGUgaXMgaW52YWxpZCxcbiAgICogb3IgdW5kZWZpbmVkIGlmIHRoZSBkYXRlIGlzIHZhbGlkIG9yIGlmIHRoZSB2YWx1ZSBpcyB1bmRlZmluZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7RGF0ZSB8IHN0cmluZ30gdmFsdWUgLSBUaGUgdmFsdWUgdG8gdmFsaWRhdGUsIGNhbiBiZSBhIERhdGUgb2JqZWN0IG9yIGEgc3RyaW5nXG4gICAqIEBwYXJhbSB7RGF0ZVZhbGlkYXRvck9wdGlvbnN9IFtvcHRpb25zPXt9XSAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgdGhlIHZhbGlkYXRvclxuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9IEVycm9yIG1lc3NhZ2UgaWYgdmFsaWRhdGlvbiBmYWlscywgdW5kZWZpbmVkIGlmIHZhbGlkYXRpb24gcGFzc2VzXG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IERhdGUgfCBzdHJpbmcsXG4gICAgb3B0aW9uczogRGF0ZVZhbGlkYXRvck9wdGlvbnMgPSB7fVxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB2YWx1ZSA9IG5ldyBEYXRlKHZhbHVlKTtcblxuICAgIGlmIChOdW1iZXIuaXNOYU4odmFsdWUuZ2V0RGF0ZSgpKSkge1xuICAgICAgY29uc3QgeyBtZXNzYWdlID0gXCJcIiB9ID0gb3B0aW9ucztcbiAgICAgIHJldHVybiB0aGlzLmdldE1lc3NhZ2UobWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgUGF0dGVyblZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmVndWxhciBleHByZXNzaW9uIGZvciBwYXJzaW5nIHN0cmluZyBwYXR0ZXJucyB3aXRoIGZsYWdzXG4gKiBAc3VtbWFyeSBUaGlzIHJlZ3VsYXIgZXhwcmVzc2lvbiBpcyB1c2VkIHRvIHBhcnNlIHN0cmluZyBwYXR0ZXJucyBpbiB0aGUgZm9ybWF0IFwiL3BhdHRlcm4vZmxhZ3NcIi5cbiAqIEl0IGNhcHR1cmVzIHRoZSBwYXR0ZXJuIGFuZCBmbGFncyBzZXBhcmF0ZWx5LCBhbGxvd2luZyB0aGUgY3JlYXRpb24gb2YgYSBSZWdFeHAgb2JqZWN0XG4gKiB3aXRoIHRoZSBhcHByb3ByaWF0ZSBmbGFncy5cbiAqXG4gKiBAY29uc3Qge1JlZ0V4cH1cbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCByZWdleHBQYXJzZXI6IFJlZ0V4cCA9IG5ldyBSZWdFeHAoXCJeLyguKykvKFtnaW11c10qKSRcIik7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvciBmb3IgY2hlY2tpbmcgaWYgYSBzdHJpbmcgbWF0Y2hlcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBwYXR0ZXJuXG4gKiBAc3VtbWFyeSBUaGUgUGF0dGVyblZhbGlkYXRvciBjaGVja3MgaWYgYSBzdHJpbmcgdmFsdWUgbWF0Y2hlcyBhIHNwZWNpZmllZCByZWd1bGFyIGV4cHJlc3Npb24gcGF0dGVybi5cbiAqIEl0IHN1cHBvcnRzIGJvdGggUmVnRXhwIG9iamVjdHMgYW5kIHN0cmluZyByZXByZXNlbnRhdGlvbnMgb2YgcGF0dGVybnMsIGluY2x1ZGluZyB0aG9zZSB3aXRoIGZsYWdzLlxuICogVGhpcyB2YWxpZGF0b3IgaXMgdGhlIGZvdW5kYXRpb24gZm9yIHNwZWNpYWxpemVkIHZhbGlkYXRvcnMgbGlrZSBFbWFpbFZhbGlkYXRvciBhbmQgVVJMVmFsaWRhdG9yLFxuICogYW5kIGlzIHR5cGljYWxseSB1c2VkIHdpdGggdGhlIEBwYXR0ZXJuIGRlY29yYXRvci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIHZhbGlkYXRpb24gZmFpbHMsIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1BBVFRFUk59XG4gKlxuICogQGNsYXNzIFBhdHRlcm5WYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBDcmVhdGUgYSBwYXR0ZXJuIHZhbGlkYXRvciB3aXRoIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogY29uc3QgcGF0dGVyblZhbGlkYXRvciA9IG5ldyBQYXR0ZXJuVmFsaWRhdG9yKCk7XG4gKlxuICogLy8gQ3JlYXRlIGEgcGF0dGVybiB2YWxpZGF0b3Igd2l0aCBjdXN0b20gZXJyb3IgbWVzc2FnZVxuICogY29uc3QgY3VzdG9tUGF0dGVyblZhbGlkYXRvciA9IG5ldyBQYXR0ZXJuVmFsaWRhdG9yKFwiVmFsdWUgbXVzdCBtYXRjaCB0aGUgcmVxdWlyZWQgZm9ybWF0XCIpO1xuICpcbiAqIC8vIFZhbGlkYXRlIHVzaW5nIGEgUmVnRXhwIG9iamVjdFxuICogY29uc3QgcmVnZXhPcHRpb25zID0geyBwYXR0ZXJuOiAvXltBLVpdW2Etel0rJC8gfTtcbiAqIHBhdHRlcm5WYWxpZGF0b3IuaGFzRXJyb3JzKFwiSGVsbG9cIiwgcmVnZXhPcHRpb25zKTsgLy8gdW5kZWZpbmVkICh2YWxpZClcbiAqIHBhdHRlcm5WYWxpZGF0b3IuaGFzRXJyb3JzKFwiaGVsbG9cIiwgcmVnZXhPcHRpb25zKTsgLy8gUmV0dXJucyBlcnJvciBtZXNzYWdlIChpbnZhbGlkKVxuICpcbiAqIC8vIFZhbGlkYXRlIHVzaW5nIGEgc3RyaW5nIHBhdHRlcm5cbiAqIGNvbnN0IHN0cmluZ09wdGlvbnMgPSB7IHBhdHRlcm46IFwiXlxcXFxkezN9LVxcXFxkezJ9LVxcXFxkezR9JFwiIH07XG4gKiBwYXR0ZXJuVmFsaWRhdG9yLmhhc0Vycm9ycyhcIjEyMy00NS02Nzg5XCIsIHN0cmluZ09wdGlvbnMpOyAvLyB1bmRlZmluZWQgKHZhbGlkKVxuICpcbiAqIC8vIFZhbGlkYXRlIHVzaW5nIGEgc3RyaW5nIHBhdHRlcm4gd2l0aCBmbGFnc1xuICogY29uc3QgZmxhZ09wdGlvbnMgPSB7IHBhdHRlcm46IFwiL15oZWxsbyQvaVwiIH07XG4gKiBwYXR0ZXJuVmFsaWRhdG9yLmhhc0Vycm9ycyhcIkhlbGxvXCIsIGZsYWdPcHRpb25zKTsgLy8gdW5kZWZpbmVkICh2YWxpZClcbiAqIGBgYFxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQyBhcyBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgViBhcyBQYXR0ZXJuVmFsaWRhdG9yXG4gKlxuICogICBDLT4+VjogbmV3IFBhdHRlcm5WYWxpZGF0b3IobWVzc2FnZSlcbiAqICAgQy0+PlY6IGhhc0Vycm9ycyh2YWx1ZSwgb3B0aW9ucylcbiAqICAgYWx0IHZhbHVlIGlzIGVtcHR5XG4gKiAgICAgVi0tPj5DOiB1bmRlZmluZWQgKHZhbGlkKVxuICogICBlbHNlIHBhdHRlcm4gaXMgbWlzc2luZ1xuICogICAgIFYtLT4+QzogRXJyb3I6IE1pc3NpbmcgUGF0dGVyblxuICogICBlbHNlIHBhdHRlcm4gaXMgc3RyaW5nXG4gKiAgICAgVi0+PlY6IGdldFBhdHRlcm4ocGF0dGVybilcbiAqICAgZW5kXG4gKiAgIFYtPj5WOiBSZXNldCBwYXR0ZXJuLmxhc3RJbmRleFxuICogICBWLT4+VjogVGVzdCB2YWx1ZSBhZ2FpbnN0IHBhdHRlcm5cbiAqICAgYWx0IHBhdHRlcm4gdGVzdCBwYXNzZXNcbiAqICAgICBWLS0+PkM6IHVuZGVmaW5lZCAodmFsaWQpXG4gKiAgIGVsc2UgcGF0dGVybiB0ZXN0IGZhaWxzXG4gKiAgICAgVi0tPj5DOiBFcnJvciBtZXNzYWdlXG4gKiAgIGVuZFxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuUEFUVEVSTilcbmV4cG9ydCBjbGFzcyBQYXR0ZXJuVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPFBhdHRlcm5WYWxpZGF0b3JPcHRpb25zPiB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuUEFUVEVSTikge1xuICAgIHN1cGVyKG1lc3NhZ2UsIFwic3RyaW5nXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBhIHN0cmluZyBwYXR0ZXJuIHRvIGEgUmVnRXhwIG9iamVjdFxuICAgKiBAc3VtbWFyeSBQYXJzZXMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSByZWd1bGFyIGV4cHJlc3Npb24gYW5kIGNvbnZlcnRzIGl0IHRvIGEgUmVnRXhwIG9iamVjdC5cbiAgICogSXQgaGFuZGxlcyBib3RoIHNpbXBsZSBzdHJpbmcgcGF0dGVybnMgYW5kIHBhdHRlcm5zIHdpdGggZmxhZ3MgaW4gdGhlIGZvcm1hdCBcIi9wYXR0ZXJuL2ZsYWdzXCIuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXR0ZXJuIC0gVGhlIHN0cmluZyBwYXR0ZXJuIHRvIGNvbnZlcnRcbiAgICogQHJldHVybiB7UmVnRXhwfSBBIFJlZ0V4cCBvYmplY3QgY3JlYXRlZCBmcm9tIHRoZSBzdHJpbmcgcGF0dGVyblxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBnZXRQYXR0ZXJuKHBhdHRlcm46IHN0cmluZyk6IFJlZ0V4cCB7XG4gICAgaWYgKCFyZWdleHBQYXJzZXIudGVzdChwYXR0ZXJuKSkgcmV0dXJuIG5ldyBSZWdFeHAocGF0dGVybik7XG4gICAgY29uc3QgbWF0Y2g6IGFueSA9IHBhdHRlcm4ubWF0Y2gocmVnZXhwUGFyc2VyKTtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cChtYXRjaFsxXSwgbWF0Y2hbMl0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYSBzdHJpbmcgbWF0Y2hlcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBwYXR0ZXJuXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyB0aGF0IHRoZSBwcm92aWRlZCBzdHJpbmcgbWF0Y2hlcyB0aGUgcGF0dGVybiBzcGVjaWZpZWQgaW4gdGhlIG9wdGlvbnMuXG4gICAqIElmIHRoZSBwYXR0ZXJuIGlzIHByb3ZpZGVkIGFzIGEgc3RyaW5nLCBpdCdzIGNvbnZlcnRlZCB0byBhIFJlZ0V4cCBvYmplY3QgdXNpbmcgdGhlIGdldFBhdHRlcm4gbWV0aG9kLlxuICAgKiBUaGUgbWV0aG9kIHJlc2V0cyB0aGUgcGF0dGVybidzIGxhc3RJbmRleCBwcm9wZXJ0eSB0byBlbnN1cmUgY29uc2lzdGVudCB2YWxpZGF0aW9uIHJlc3VsdHNcbiAgICogZm9yIHBhdHRlcm5zIHdpdGggdGhlIGdsb2JhbCBmbGFnLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgLSBUaGUgc3RyaW5nIHRvIHZhbGlkYXRlIGFnYWluc3QgdGhlIHBhdHRlcm5cbiAgICogQHBhcmFtIHtQYXR0ZXJuVmFsaWRhdG9yT3B0aW9uc30gb3B0aW9ucyAtIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBjb250YWluaW5nIHRoZSBwYXR0ZXJuXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH0gRXJyb3IgbWVzc2FnZSBpZiB2YWxpZGF0aW9uIGZhaWxzLCB1bmRlZmluZWQgaWYgdmFsaWRhdGlvbiBwYXNzZXNcbiAgICpcbiAgICogQHRocm93cyB7RXJyb3J9IElmIG5vIHBhdHRlcm4gaXMgcHJvdmlkZWQgaW4gdGhlIG9wdGlvbnNcbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogc3RyaW5nLFxuICAgIG9wdGlvbnM6IFBhdHRlcm5WYWxpZGF0b3JPcHRpb25zXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCF2YWx1ZSkgcmV0dXJuO1xuXG4gICAgbGV0IHsgcGF0dGVybiB9ID0gb3B0aW9ucztcbiAgICBpZiAoIXBhdHRlcm4pIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgUGF0dGVyblwiKTtcbiAgICBwYXR0ZXJuID0gdHlwZW9mIHBhdHRlcm4gPT09IFwic3RyaW5nXCIgPyB0aGlzLmdldFBhdHRlcm4ocGF0dGVybikgOiBwYXR0ZXJuO1xuICAgIHBhdHRlcm4ubGFzdEluZGV4ID0gMDsgLy8gcmVzZXRzIHBhdHRlcm4gcG9zaXRpb24gZm9yIHJlcGVhdCB2YWxpZGF0aW9uIHJlcXVlc3RzXG4gICAgcmV0dXJuICFwYXR0ZXJuLnRlc3QodmFsdWUpXG4gICAgICA/IHRoaXMuZ2V0TWVzc2FnZShvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIERFRkFVTFRfRVJST1JfTUVTU0FHRVMsXG4gIERFRkFVTFRfUEFUVEVSTlMsXG4gIFZhbGlkYXRpb25LZXlzLFxufSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFBhdHRlcm5WYWxpZGF0b3IgfSBmcm9tIFwiLi9QYXR0ZXJuVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBQYXR0ZXJuVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3IgZm9yIGNoZWNraW5nIGlmIGEgc3RyaW5nIGlzIGEgdmFsaWQgZW1haWwgYWRkcmVzc1xuICogQHN1bW1hcnkgVGhlIEVtYWlsVmFsaWRhdG9yIGNoZWNrcyBpZiBhIHN0cmluZyBtYXRjaGVzIGEgc3RhbmRhcmQgZW1haWwgYWRkcmVzcyBwYXR0ZXJuLlxuICogSXQgZXh0ZW5kcyB0aGUgUGF0dGVyblZhbGlkYXRvciBhbmQgdXNlcyBhIHByZWRlZmluZWQgZW1haWwgcmVnZXggcGF0dGVybiB0byB2YWxpZGF0ZSBlbWFpbCBhZGRyZXNzZXMuXG4gKiBUaGlzIHZhbGlkYXRvciBpcyB0eXBpY2FsbHkgdXNlZCB3aXRoIHRoZSBAZW1haWwgZGVjb3JhdG9yLlxuICogXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIHZhbGlkYXRpb24gZmFpbHMsIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0VNQUlMfVxuICogXG4gKiBAY2xhc3MgRW1haWxWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFBhdHRlcm5WYWxpZGF0b3JcbiAqIFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIENyZWF0ZSBhbiBlbWFpbCB2YWxpZGF0b3Igd2l0aCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIGNvbnN0IGVtYWlsVmFsaWRhdG9yID0gbmV3IEVtYWlsVmFsaWRhdG9yKCk7XG4gKiBcbiAqIC8vIENyZWF0ZSBhbiBlbWFpbCB2YWxpZGF0b3Igd2l0aCBjdXN0b20gZXJyb3IgbWVzc2FnZVxuICogY29uc3QgY3VzdG9tRW1haWxWYWxpZGF0b3IgPSBuZXcgRW1haWxWYWxpZGF0b3IoXCJQbGVhc2UgZW50ZXIgYSB2YWxpZCBlbWFpbCBhZGRyZXNzXCIpO1xuICogXG4gKiAvLyBWYWxpZGF0ZSBhbiBlbWFpbFxuICogY29uc3QgcmVzdWx0ID0gZW1haWxWYWxpZGF0b3IuaGFzRXJyb3JzKFwidXNlckBleGFtcGxlLmNvbVwiKTsgLy8gdW5kZWZpbmVkICh2YWxpZClcbiAqIGNvbnN0IGludmFsaWRSZXN1bHQgPSBlbWFpbFZhbGlkYXRvci5oYXNFcnJvcnMoXCJpbnZhbGlkLWVtYWlsXCIpOyAvLyBSZXR1cm5zIGVycm9yIG1lc3NhZ2UgKGludmFsaWQpXG4gKiBgYGBcbiAqIFxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENsaWVudFxuICogICBwYXJ0aWNpcGFudCBFIGFzIEVtYWlsVmFsaWRhdG9yXG4gKiAgIHBhcnRpY2lwYW50IFAgYXMgUGF0dGVyblZhbGlkYXRvclxuICogICBcbiAqICAgQy0+PkU6IG5ldyBFbWFpbFZhbGlkYXRvcihtZXNzYWdlKVxuICogICBFLT4+UDogc3VwZXIobWVzc2FnZSlcbiAqICAgQy0+PkU6IGhhc0Vycm9ycyh2YWx1ZSwgb3B0aW9ucylcbiAqICAgRS0+PlA6IHN1cGVyLmhhc0Vycm9ycyh2YWx1ZSwgb3B0aW9ucyB3aXRoIEVNQUlMIHBhdHRlcm4pXG4gKiAgIFAtLT4+RTogdmFsaWRhdGlvbiByZXN1bHRcbiAqICAgRS0tPj5DOiB2YWxpZGF0aW9uIHJlc3VsdFxuICogXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5AdmFsaWRhdG9yKFZhbGlkYXRpb25LZXlzLkVNQUlMKVxuZXhwb3J0IGNsYXNzIEVtYWlsVmFsaWRhdG9yIGV4dGVuZHMgUGF0dGVyblZhbGlkYXRvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuRU1BSUwpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ2hlY2tzIGlmIGEgc3RyaW5nIGlzIGEgdmFsaWQgZW1haWwgYWRkcmVzc1xuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgdGhhdCB0aGUgcHJvdmlkZWQgc3RyaW5nIG1hdGNoZXMgdGhlIGVtYWlsIHBhdHRlcm4uXG4gICAqIFRoaXMgbWV0aG9kIGV4dGVuZHMgdGhlIFBhdHRlcm5WYWxpZGF0b3IncyBoYXNFcnJvcnMgbWV0aG9kIGJ5IGVuc3VyaW5nXG4gICAqIHRoZSBlbWFpbCBwYXR0ZXJuIGlzIHVzZWQsIGV2ZW4gaWYgbm90IGV4cGxpY2l0bHkgcHJvdmlkZWQgaW4gdGhlIG9wdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSAtIFRoZSBzdHJpbmcgdG8gdmFsaWRhdGUgYXMgYW4gZW1haWwgYWRkcmVzc1xuICAgKiBAcGFyYW0ge1BhdHRlcm5WYWxpZGF0b3JPcHRpb25zfSBbb3B0aW9ucz17fV0gLSBPcHRpb25hbCBjb25maWd1cmF0aW9uIG9wdGlvbnNcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfSBFcnJvciBtZXNzYWdlIGlmIHZhbGlkYXRpb24gZmFpbHMsIHVuZGVmaW5lZCBpZiB2YWxpZGF0aW9uIHBhc3Nlc1xuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBQYXR0ZXJuVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogc3RyaW5nLFxuICAgIG9wdGlvbnM6IFBhdHRlcm5WYWxpZGF0b3JPcHRpb25zID0ge31cbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gc3VwZXIuaGFzRXJyb3JzKHZhbHVlLCB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgcGF0dGVybjogb3B0aW9ucz8ucGF0dGVybiB8fCBERUZBVUxUX1BBVFRFUk5TLkVNQUlMLFxuICAgIH0pO1xuICB9XG59XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tIFwiLi9WYWxpZGF0b3JcIjtcbmltcG9ydCB7IERFRkFVTFRfRVJST1JfTUVTU0FHRVMsIFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBMaXN0VmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3IgZm9yIGNoZWNraW5nIGlmIGVsZW1lbnRzIGluIGEgbGlzdCBvciBzZXQgbWF0Y2ggZXhwZWN0ZWQgdHlwZXNcbiAqIEBzdW1tYXJ5IFRoZSBMaXN0VmFsaWRhdG9yIHZhbGlkYXRlcyB0aGF0IGFsbCBlbGVtZW50cyBpbiBhbiBhcnJheSBvciBTZXQgbWF0Y2ggdGhlIGV4cGVjdGVkIHR5cGVzLlxuICogSXQgY2hlY2tzIGVhY2ggZWxlbWVudCBhZ2FpbnN0IGEgbGlzdCBvZiBhbGxvd2VkIGNsYXNzIHR5cGVzIGFuZCBlbnN1cmVzIHR5cGUgY29uc2lzdGVuY3kuXG4gKiBUaGlzIHZhbGlkYXRvciBpcyB0eXBpY2FsbHkgdXNlZCB3aXRoIHRoZSBAbGlzdCBkZWNvcmF0b3IuXG4gKiBcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gLSBDdXN0b20gZXJyb3IgbWVzc2FnZSB0byBkaXNwbGF5IHdoZW4gdmFsaWRhdGlvbiBmYWlscywgZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjTElTVH1cbiAqIFxuICogQGNsYXNzIExpc3RWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICogXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gQ3JlYXRlIGEgbGlzdCB2YWxpZGF0b3Igd2l0aCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIGNvbnN0IGxpc3RWYWxpZGF0b3IgPSBuZXcgTGlzdFZhbGlkYXRvcigpO1xuICogXG4gKiAvLyBDcmVhdGUgYSBsaXN0IHZhbGlkYXRvciB3aXRoIGN1c3RvbSBlcnJvciBtZXNzYWdlXG4gKiBjb25zdCBjdXN0b21MaXN0VmFsaWRhdG9yID0gbmV3IExpc3RWYWxpZGF0b3IoXCJBbGwgaXRlbXMgbXVzdCBiZSBvZiB0aGUgc3BlY2lmaWVkIHR5cGVcIik7XG4gKiBcbiAqIC8vIFZhbGlkYXRlIGEgbGlzdFxuICogY29uc3Qgb3B0aW9ucyA9IHsgY2xheno6IFtcIlN0cmluZ1wiLCBcIk51bWJlclwiXSB9O1xuICogY29uc3QgcmVzdWx0ID0gbGlzdFZhbGlkYXRvci5oYXNFcnJvcnMoW1widGVzdFwiLCAxMjNdLCBvcHRpb25zKTsgLy8gdW5kZWZpbmVkICh2YWxpZClcbiAqIGNvbnN0IGludmFsaWRSZXN1bHQgPSBsaXN0VmFsaWRhdG9yLmhhc0Vycm9ycyhbbmV3IERhdGUoKV0sIG9wdGlvbnMpOyAvLyBSZXR1cm5zIGVycm9yIG1lc3NhZ2UgKGludmFsaWQpXG4gKiBgYGBcbiAqIFxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENsaWVudFxuICogICBwYXJ0aWNpcGFudCBWIGFzIExpc3RWYWxpZGF0b3JcbiAqICAgXG4gKiAgIEMtPj5WOiBuZXcgTGlzdFZhbGlkYXRvcihtZXNzYWdlKVxuICogICBDLT4+VjogaGFzRXJyb3JzKHZhbHVlLCBvcHRpb25zKVxuICogICBhbHQgdmFsdWUgaXMgZW1wdHlcbiAqICAgICBWLS0+PkM6IHVuZGVmaW5lZCAodmFsaWQpXG4gKiAgIGVsc2UgdmFsdWUgaGFzIGVsZW1lbnRzXG4gKiAgICAgVi0+PlY6IENoZWNrIGVhY2ggZWxlbWVudCdzIHR5cGVcbiAqICAgICBhbHQgQWxsIGVsZW1lbnRzIG1hdGNoIGFsbG93ZWQgdHlwZXNcbiAqICAgICAgIFYtLT4+QzogdW5kZWZpbmVkICh2YWxpZClcbiAqICAgICBlbHNlIFNvbWUgZWxlbWVudHMgZG9uJ3QgbWF0Y2hcbiAqICAgICAgIFYtLT4+QzogRXJyb3IgbWVzc2FnZVxuICogICAgIGVuZFxuICogICBlbmRcbiAqIFxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5MSVNUKVxuZXhwb3J0IGNsYXNzIExpc3RWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3I8TGlzdFZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5MSVNUKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgQXJyYXkubmFtZSwgU2V0Lm5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYWxsIGVsZW1lbnRzIGluIGEgbGlzdCBvciBzZXQgbWF0Y2ggdGhlIGV4cGVjdGVkIHR5cGVzXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyB0aGF0IGVhY2ggZWxlbWVudCBpbiB0aGUgcHJvdmlkZWQgYXJyYXkgb3IgU2V0IG1hdGNoZXMgb25lIG9mIHRoZSBcbiAgICogY2xhc3MgdHlwZXMgc3BlY2lmaWVkIGluIHRoZSBvcHRpb25zLiBGb3Igb2JqZWN0IHR5cGVzLCBpdCBjaGVja3MgdGhlIGNvbnN0cnVjdG9yIG5hbWUsXG4gICAqIGFuZCBmb3IgcHJpbWl0aXZlIHR5cGVzLCBpdCBjb21wYXJlcyBhZ2FpbnN0IHRoZSBsb3dlcmNhc2UgdHlwZSBuYW1lLlxuICAgKlxuICAgKiBAcGFyYW0ge2FueVtdIHwgU2V0PGFueT59IHZhbHVlIC0gVGhlIGFycmF5IG9yIFNldCB0byB2YWxpZGF0ZVxuICAgKiBAcGFyYW0ge0xpc3RWYWxpZGF0b3JPcHRpb25zfSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGNvbnRhaW5pbmcgdGhlIGFsbG93ZWQgY2xhc3MgdHlwZXNcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfSBFcnJvciBtZXNzYWdlIGlmIHZhbGlkYXRpb24gZmFpbHMsIHVuZGVmaW5lZCBpZiB2YWxpZGF0aW9uIHBhc3Nlc1xuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IGFueVtdIHwgU2V0PGFueT4sXG4gICAgb3B0aW9uczogTGlzdFZhbGlkYXRvck9wdGlvbnNcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIXZhbHVlIHx8IChBcnJheS5pc0FycmF5KHZhbHVlKSA/ICF2YWx1ZS5sZW5ndGggOiAhdmFsdWUuc2l6ZSkpIHJldHVybjtcblxuICAgIGNvbnN0IGNsYXp6ID0gQXJyYXkuaXNBcnJheShvcHRpb25zLmNsYXp6KVxuICAgICAgPyBvcHRpb25zLmNsYXp6XG4gICAgICA6IFtvcHRpb25zLmNsYXp6XTtcbiAgICBsZXQgdmFsOiBhbnksXG4gICAgICBpc1ZhbGlkID0gdHJ1ZTtcbiAgICBmb3IgKFxuICAgICAgbGV0IGkgPSAwO1xuICAgICAgaSA8IChBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlLmxlbmd0aCA6IHZhbHVlLnNpemUpO1xuICAgICAgaSsrXG4gICAgKSB7XG4gICAgICB2YWwgPSAodmFsdWUgYXMgYW55KVtpXTtcbiAgICAgIHN3aXRjaCAodHlwZW9mIHZhbCkge1xuICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgIGNhc2UgXCJmdW5jdGlvblwiOlxuICAgICAgICAgIGlzVmFsaWQgPSBjbGF6ei5pbmNsdWRlcygodmFsIGFzIG9iamVjdCkuY29uc3RydWN0b3I/Lm5hbWUpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGlzVmFsaWQgPSBjbGF6ei5zb21lKChjOiBzdHJpbmcpID0+IHR5cGVvZiB2YWwgPT09IGMudG9Mb3dlckNhc2UoKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGlzVmFsaWRcbiAgICAgID8gdW5kZWZpbmVkXG4gICAgICA6IHRoaXMuZ2V0TWVzc2FnZShvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlLCBjbGF6eik7XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgVmFsaWRhdGlvbktleXMsIERFRkFVTFRfRVJST1JfTUVTU0FHRVMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IE1heExlbmd0aFZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBNYXhpbXVtIExlbmd0aCBWYWxpZGF0b3JcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0ZXMgc3RyaW5ncyBhbmQgQXJyYXlzIG9uIHRoZWlyIG1heGltdW0gbGVuZ3RoXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNNQVhfTEVOR1RIfVxuICpcbiAqIEBjbGFzcyBNaW5MZW5ndGhWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuTUFYX0xFTkdUSClcbmV4cG9ydCBjbGFzcyBNYXhMZW5ndGhWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3I8TWF4TGVuZ3RoVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLk1BWF9MRU5HVEgpIHtcbiAgICBzdXBlcihtZXNzYWdlLCBTdHJpbmcubmFtZSwgQXJyYXkubmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIGEgbW9kZWxcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gICAqIEBwYXJhbSB7TWF4TGVuZ3RoVmFsaWRhdG9yT3B0aW9uc30gb3B0aW9uc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9XG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IHN0cmluZyB8IGFueVtdLFxuICAgIG9wdGlvbnM6IE1heExlbmd0aFZhbGlkYXRvck9wdGlvbnNcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm47XG4gICAgcmV0dXJuIHZhbHVlLmxlbmd0aCA+IG9wdGlvbnMubWF4bGVuZ3RoXG4gICAgICA/IHRoaXMuZ2V0TWVzc2FnZShvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlLCBvcHRpb25zLm1heGxlbmd0aClcbiAgICAgIDogdW5kZWZpbmVkO1xuICB9XG59XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tIFwiLi9WYWxpZGF0b3JcIjtcbmltcG9ydCB7IERFRkFVTFRfRVJST1JfTUVTU0FHRVMsIFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBNYXhWYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvciBmb3IgY2hlY2tpbmcgaWYgYSB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gYSBtYXhpbXVtXG4gKiBAc3VtbWFyeSBUaGUgTWF4VmFsaWRhdG9yIGNoZWNrcyBpZiBhIG51bWVyaWMgdmFsdWUsIGRhdGUsIG9yIHN0cmluZyBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG9cbiAqIGEgc3BlY2lmaWVkIG1heGltdW0gdmFsdWUuIEl0IHN1cHBvcnRzIGNvbXBhcmluZyBudW1iZXJzIGRpcmVjdGx5LCBkYXRlcyBjaHJvbm9sb2dpY2FsbHksXG4gKiBhbmQgc3RyaW5ncyBsZXhpY29ncmFwaGljYWxseS4gVGhpcyB2YWxpZGF0b3IgaXMgdHlwaWNhbGx5IHVzZWQgd2l0aCB0aGUgQG1heCBkZWNvcmF0b3IuXG4gKiBcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gLSBDdXN0b20gZXJyb3IgbWVzc2FnZSB0byBkaXNwbGF5IHdoZW4gdmFsaWRhdGlvbiBmYWlscywgZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjTUFYfVxuICogXG4gKiBAY2xhc3MgTWF4VmFsaWRhdG9yXG4gKiBAZXh0ZW5kcyBWYWxpZGF0b3JcbiAqIFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIENyZWF0ZSBhIG1heCB2YWxpZGF0b3Igd2l0aCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIGNvbnN0IG1heFZhbGlkYXRvciA9IG5ldyBNYXhWYWxpZGF0b3IoKTtcbiAqIFxuICogLy8gQ3JlYXRlIGEgbWF4IHZhbGlkYXRvciB3aXRoIGN1c3RvbSBlcnJvciBtZXNzYWdlXG4gKiBjb25zdCBjdXN0b21NYXhWYWxpZGF0b3IgPSBuZXcgTWF4VmFsaWRhdG9yKFwiVmFsdWUgbXVzdCBub3QgZXhjZWVkIHswfVwiKTtcbiAqIFxuICogLy8gVmFsaWRhdGUgYSBudW1iZXJcbiAqIGNvbnN0IG51bU9wdGlvbnMgPSB7IG1heDogMTAwLCBtZXNzYWdlOiBcIk51bWJlciB0b28gbGFyZ2VcIiB9O1xuICogY29uc3QgbnVtUmVzdWx0ID0gbWF4VmFsaWRhdG9yLmhhc0Vycm9ycyg1MCwgbnVtT3B0aW9ucyk7IC8vIHVuZGVmaW5lZCAodmFsaWQpXG4gKiBjb25zdCBpbnZhbGlkTnVtUmVzdWx0ID0gbWF4VmFsaWRhdG9yLmhhc0Vycm9ycygxNTAsIG51bU9wdGlvbnMpOyAvLyBSZXR1cm5zIGVycm9yIG1lc3NhZ2UgKGludmFsaWQpXG4gKiBcbiAqIC8vIFZhbGlkYXRlIGEgZGF0ZVxuICogY29uc3QgZGF0ZU9wdGlvbnMgPSB7IG1heDogbmV3IERhdGUoMjAyMywgMTEsIDMxKSB9O1xuICogY29uc3QgZGF0ZVJlc3VsdCA9IG1heFZhbGlkYXRvci5oYXNFcnJvcnMobmV3IERhdGUoMjAyMywgNSwgMTUpLCBkYXRlT3B0aW9ucyk7IC8vIHVuZGVmaW5lZCAodmFsaWQpXG4gKiBgYGBcbiAqIFxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENsaWVudFxuICogICBwYXJ0aWNpcGFudCBWIGFzIE1heFZhbGlkYXRvclxuICogICBcbiAqICAgQy0+PlY6IG5ldyBNYXhWYWxpZGF0b3IobWVzc2FnZSlcbiAqICAgQy0+PlY6IGhhc0Vycm9ycyh2YWx1ZSwgb3B0aW9ucylcbiAqICAgYWx0IHZhbHVlIGlzIHVuZGVmaW5lZFxuICogICAgIFYtLT4+QzogdW5kZWZpbmVkICh2YWxpZClcbiAqICAgZWxzZSB2YWx1ZSBpcyBEYXRlIGFuZCBtYXggaXMgbm90IERhdGVcbiAqICAgICBWLT4+VjogQ29udmVydCBtYXggdG8gRGF0ZVxuICogICAgIGFsdCBjb252ZXJzaW9uIGZhaWxzXG4gKiAgICAgICBWLS0+PkM6IEVycm9yOiBJbnZhbGlkIE1heCBwYXJhbVxuICogICAgIGVuZFxuICogICBlbmRcbiAqICAgYWx0IHZhbHVlID4gbWF4XG4gKiAgICAgVi0tPj5DOiBFcnJvciBtZXNzYWdlXG4gKiAgIGVsc2UgdmFsdWUgPD0gbWF4XG4gKiAgICAgVi0tPj5DOiB1bmRlZmluZWQgKHZhbGlkKVxuICogICBlbmRcbiAqIFxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5NQVgpXG5leHBvcnQgY2xhc3MgTWF4VmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPE1heFZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5NQVgpIHtcbiAgICBzdXBlcihtZXNzYWdlLCBcIm51bWJlclwiLCBcIkRhdGVcIiwgXCJzdHJpbmdcIik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENoZWNrcyBpZiBhIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byBhIG1heGltdW1cbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIHRoYXQgdGhlIHByb3ZpZGVkIHZhbHVlIGRvZXMgbm90IGV4Y2VlZCB0aGUgbWF4aW11bSB2YWx1ZVxuICAgKiBzcGVjaWZpZWQgaW4gdGhlIG9wdGlvbnMuIEZvciBkYXRlcywgaXQgcGVyZm9ybXMgY2hyb25vbG9naWNhbCBjb21wYXJpc29uLFxuICAgKiBjb252ZXJ0aW5nIHN0cmluZyByZXByZXNlbnRhdGlvbnMgdG8gRGF0ZSBvYmplY3RzIGlmIG5lY2Vzc2FyeS4gRm9yIG51bWJlcnNcbiAgICogYW5kIHN0cmluZ3MsIGl0IHBlcmZvcm1zIGRpcmVjdCBjb21wYXJpc29uLlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlciB8IERhdGUgfCBzdHJpbmd9IHZhbHVlIC0gVGhlIHZhbHVlIHRvIHZhbGlkYXRlXG4gICAqIEBwYXJhbSB7TWF4VmFsaWRhdG9yT3B0aW9uc30gb3B0aW9ucyAtIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBjb250YWluaW5nIHRoZSBtYXhpbXVtIHZhbHVlXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH0gRXJyb3IgbWVzc2FnZSBpZiB2YWxpZGF0aW9uIGZhaWxzLCB1bmRlZmluZWQgaWYgdmFsaWRhdGlvbiBwYXNzZXNcbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogbnVtYmVyIHwgRGF0ZSB8IHN0cmluZyxcbiAgICBvcHRpb25zOiBNYXhWYWxpZGF0b3JPcHRpb25zXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuO1xuXG4gICAgbGV0IHsgbWF4IH0gPSBvcHRpb25zO1xuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUgJiYgIShtYXggaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgbWF4ID0gbmV3IERhdGUobWF4KTtcbiAgICAgIGlmIChOdW1iZXIuaXNOYU4obWF4LmdldERhdGUoKSkpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgTWF4IHBhcmFtIGRlZmluZWRcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlID4gbWF4XG4gICAgICA/IHRoaXMuZ2V0TWVzc2FnZShvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlLCBtYXgpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgTWluTGVuZ3RoVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IE1pbmltdW0gTGVuZ3RoIFZhbGlkYXRvclxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRlcyBzdHJpbmdzIGFuZCBBcnJheXMgb24gdGhlaXIgbWluaW11bSBsZW5ndGhcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI01JTl9MRU5HVEh9XG4gKlxuICogQGNsYXNzIE1pbkxlbmd0aFZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5NSU5fTEVOR1RIKVxuZXhwb3J0IGNsYXNzIE1pbkxlbmd0aFZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvcjxNaW5MZW5ndGhWYWxpZGF0b3JPcHRpb25zPiB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuTUlOX0xFTkdUSCkge1xuICAgIHN1cGVyKG1lc3NhZ2UsIFN0cmluZy5uYW1lLCBBcnJheS5uYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IEFycmF5fSB2YWx1ZVxuICAgKiBAcGFyYW0ge01pbkxlbmd0aFZhbGlkYXRvck9wdGlvbnN9IG9wdGlvbnNcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICAgKlxuICAgKiBAbWVtYmVyT2YgTWluTGVuZ3RoVmFsaWRhdG9yXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IHN0cmluZyB8IGFueVtdLFxuICAgIG9wdGlvbnM6IE1pbkxlbmd0aFZhbGlkYXRvck9wdGlvbnNcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm47XG4gICAgcmV0dXJuIHZhbHVlLmxlbmd0aCA8IG9wdGlvbnMubWlubGVuZ3RoXG4gICAgICA/IHRoaXMuZ2V0TWVzc2FnZShvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlLCBvcHRpb25zLm1pbmxlbmd0aClcbiAgICAgIDogdW5kZWZpbmVkO1xuICB9XG59XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tIFwiLi9WYWxpZGF0b3JcIjtcbmltcG9ydCB7IERFRkFVTFRfRVJST1JfTUVTU0FHRVMsIFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBNaW5WYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvciBmb3IgY2hlY2tpbmcgaWYgYSB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYSBtaW5pbXVtXG4gKiBAc3VtbWFyeSBUaGUgTWluVmFsaWRhdG9yIGNoZWNrcyBpZiBhIG51bWVyaWMgdmFsdWUsIGRhdGUsIG9yIHN0cmluZyBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG9cbiAqIGEgc3BlY2lmaWVkIG1pbmltdW0gdmFsdWUuIEl0IHN1cHBvcnRzIGNvbXBhcmluZyBudW1iZXJzIGRpcmVjdGx5LCBkYXRlcyBjaHJvbm9sb2dpY2FsbHksXG4gKiBhbmQgc3RyaW5ncyBsZXhpY29ncmFwaGljYWxseS4gVGhpcyB2YWxpZGF0b3IgaXMgdHlwaWNhbGx5IHVzZWQgd2l0aCB0aGUgQG1pbiBkZWNvcmF0b3IuXG4gKiBcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gLSBDdXN0b20gZXJyb3IgbWVzc2FnZSB0byBkaXNwbGF5IHdoZW4gdmFsaWRhdGlvbiBmYWlscywgZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjTUlOfVxuICogXG4gKiBAY2xhc3MgTWluVmFsaWRhdG9yXG4gKiBAZXh0ZW5kcyBWYWxpZGF0b3JcbiAqIFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIENyZWF0ZSBhIG1pbiB2YWxpZGF0b3Igd2l0aCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIGNvbnN0IG1pblZhbGlkYXRvciA9IG5ldyBNaW5WYWxpZGF0b3IoKTtcbiAqIFxuICogLy8gQ3JlYXRlIGEgbWluIHZhbGlkYXRvciB3aXRoIGN1c3RvbSBlcnJvciBtZXNzYWdlXG4gKiBjb25zdCBjdXN0b21NaW5WYWxpZGF0b3IgPSBuZXcgTWluVmFsaWRhdG9yKFwiVmFsdWUgbXVzdCBiZSBhdCBsZWFzdCB7MH1cIik7XG4gKiBcbiAqIC8vIFZhbGlkYXRlIGEgbnVtYmVyXG4gKiBjb25zdCBudW1PcHRpb25zID0geyBtaW46IDEwLCBtZXNzYWdlOiBcIk51bWJlciB0b28gc21hbGxcIiB9O1xuICogY29uc3QgbnVtUmVzdWx0ID0gbWluVmFsaWRhdG9yLmhhc0Vycm9ycyg1MCwgbnVtT3B0aW9ucyk7IC8vIHVuZGVmaW5lZCAodmFsaWQpXG4gKiBjb25zdCBpbnZhbGlkTnVtUmVzdWx0ID0gbWluVmFsaWRhdG9yLmhhc0Vycm9ycyg1LCBudW1PcHRpb25zKTsgLy8gUmV0dXJucyBlcnJvciBtZXNzYWdlIChpbnZhbGlkKVxuICogXG4gKiAvLyBWYWxpZGF0ZSBhIGRhdGVcbiAqIGNvbnN0IGRhdGVPcHRpb25zID0geyBtaW46IG5ldyBEYXRlKDIwMjMsIDAsIDEpIH07XG4gKiBjb25zdCBkYXRlUmVzdWx0ID0gbWluVmFsaWRhdG9yLmhhc0Vycm9ycyhuZXcgRGF0ZSgyMDIzLCA1LCAxNSksIGRhdGVPcHRpb25zKTsgLy8gdW5kZWZpbmVkICh2YWxpZClcbiAqIGBgYFxuICogXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IFYgYXMgTWluVmFsaWRhdG9yXG4gKiAgIFxuICogICBDLT4+VjogbmV3IE1pblZhbGlkYXRvcihtZXNzYWdlKVxuICogICBDLT4+VjogaGFzRXJyb3JzKHZhbHVlLCBvcHRpb25zKVxuICogICBhbHQgdmFsdWUgaXMgdW5kZWZpbmVkXG4gKiAgICAgVi0tPj5DOiB1bmRlZmluZWQgKHZhbGlkKVxuICogICBlbHNlIHZhbHVlIGlzIERhdGUgYW5kIG1pbiBpcyBub3QgRGF0ZVxuICogICAgIFYtPj5WOiBDb252ZXJ0IG1pbiB0byBEYXRlXG4gKiAgICAgYWx0IGNvbnZlcnNpb24gZmFpbHNcbiAqICAgICAgIFYtLT4+QzogRXJyb3I6IEludmFsaWQgTWluIHBhcmFtXG4gKiAgICAgZW5kXG4gKiAgIGVuZFxuICogICBhbHQgdmFsdWUgPCBtaW5cbiAqICAgICBWLS0+PkM6IEVycm9yIG1lc3NhZ2VcbiAqICAgZWxzZSB2YWx1ZSA+PSBtaW5cbiAqICAgICBWLS0+PkM6IHVuZGVmaW5lZCAodmFsaWQpXG4gKiAgIGVuZFxuICogXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5AdmFsaWRhdG9yKFZhbGlkYXRpb25LZXlzLk1JTilcbmV4cG9ydCBjbGFzcyBNaW5WYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3I8TWluVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLk1JTikge1xuICAgIHN1cGVyKG1lc3NhZ2UsIFwibnVtYmVyXCIsIFwiRGF0ZVwiLCBcInN0cmluZ1wiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ2hlY2tzIGlmIGEgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGEgbWluaW11bVxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgdGhhdCB0aGUgcHJvdmlkZWQgdmFsdWUgaXMgbm90IGxlc3MgdGhhbiB0aGUgbWluaW11bSB2YWx1ZVxuICAgKiBzcGVjaWZpZWQgaW4gdGhlIG9wdGlvbnMuIEZvciBkYXRlcywgaXQgcGVyZm9ybXMgY2hyb25vbG9naWNhbCBjb21wYXJpc29uLFxuICAgKiBjb252ZXJ0aW5nIHN0cmluZyByZXByZXNlbnRhdGlvbnMgdG8gRGF0ZSBvYmplY3RzIGlmIG5lY2Vzc2FyeS4gRm9yIG51bWJlcnNcbiAgICogYW5kIHN0cmluZ3MsIGl0IHBlcmZvcm1zIGRpcmVjdCBjb21wYXJpc29uLlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlciB8IERhdGUgfCBzdHJpbmd9IHZhbHVlIC0gVGhlIHZhbHVlIHRvIHZhbGlkYXRlXG4gICAqIEBwYXJhbSB7TWluVmFsaWRhdG9yT3B0aW9uc30gb3B0aW9ucyAtIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBjb250YWluaW5nIHRoZSBtaW5pbXVtIHZhbHVlXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH0gRXJyb3IgbWVzc2FnZSBpZiB2YWxpZGF0aW9uIGZhaWxzLCB1bmRlZmluZWQgaWYgdmFsaWRhdGlvbiBwYXNzZXNcbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogbnVtYmVyIHwgRGF0ZSB8IHN0cmluZyxcbiAgICBvcHRpb25zOiBNaW5WYWxpZGF0b3JPcHRpb25zXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuO1xuXG4gICAgbGV0IHsgbWluIH0gPSBvcHRpb25zO1xuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUgJiYgIShtaW4gaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgbWluID0gbmV3IERhdGUobWluKTtcbiAgICAgIGlmIChOdW1iZXIuaXNOYU4obWluLmdldERhdGUoKSkpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgTWluIHBhcmFtIGRlZmluZWRcIik7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZSA8IG1pblxuICAgICAgPyB0aGlzLmdldE1lc3NhZ2Uob3B0aW9ucy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSwgbWluKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIH1cbn1cbiIsImltcG9ydCB7IFBhdHRlcm5WYWxpZGF0b3IgfSBmcm9tIFwiLi9QYXR0ZXJuVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgUGF0dGVyblZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBIYW5kbGVzIFBhc3N3b3JkIFZhbGlkYXRpb25cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW2Vycm9yTWVzc2FnZV0gZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjUEFTU1dPUkR9XG4gKlxuICogQGNsYXNzIFBhc3N3b3JkVmFsaWRhdG9yXG4gKiBAZXh0ZW5kcyBQYXR0ZXJuVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5QQVNTV09SRClcbmV4cG9ydCBjbGFzcyBQYXNzd29yZFZhbGlkYXRvciBleHRlbmRzIFBhdHRlcm5WYWxpZGF0b3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5QQVNTV09SRCkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIG1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1BhdHRlcm5WYWxpZGF0b3JPcHRpb25zfSBbb3B0aW9ucz17fV1cbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBQYXR0ZXJuVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogc3RyaW5nLFxuICAgIG9wdGlvbnM6IFBhdHRlcm5WYWxpZGF0b3JPcHRpb25zID0ge31cbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gc3VwZXIuaGFzRXJyb3JzKHZhbHVlLCB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgbWVzc2FnZTogb3B0aW9ucy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSxcbiAgICB9KTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3IgZm9yIGNoZWNraW5nIGlmIGEgdmFsdWUgaXMgcHJlc2VudCBhbmQgbm90IGVtcHR5XG4gKiBAc3VtbWFyeSBUaGUgUmVxdWlyZWRWYWxpZGF0b3IgZW5zdXJlcyB0aGF0IGEgdmFsdWUgaXMgcHJvdmlkZWQgYW5kIG5vdCBlbXB0eS5cbiAqIEl0IGhhbmRsZXMgZGlmZmVyZW50IHR5cGVzIG9mIHZhbHVlcyBhcHByb3ByaWF0ZWx5OiBmb3IgYm9vbGVhbnMgYW5kIG51bWJlcnMsXG4gKiBpdCBjaGVja3MgaWYgdGhleSdyZSB1bmRlZmluZWQ7IGZvciBvdGhlciB0eXBlcyAoc3RyaW5ncywgYXJyYXlzLCBvYmplY3RzKSxcbiAqIGl0IGNoZWNrcyBpZiB0aGV5J3JlIGZhbHN5LiBUaGlzIHZhbGlkYXRvciBpcyB0eXBpY2FsbHkgdXNlZCB3aXRoIHRoZSBAcmVxdWlyZWQgZGVjb3JhdG9yXG4gKiBhbmQgaXMgb2Z0ZW4gdGhlIGZpcnN0IHZhbGlkYXRpb24gYXBwbGllZCB0byBpbXBvcnRhbnQgZmllbGRzLlxuICogXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIHZhbGlkYXRpb24gZmFpbHMsIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1JFUVVJUkVEfVxuICogXG4gKiBAY2xhc3MgUmVxdWlyZWRWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICogXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gQ3JlYXRlIGEgcmVxdWlyZWQgdmFsaWRhdG9yIHdpdGggZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBjb25zdCByZXF1aXJlZFZhbGlkYXRvciA9IG5ldyBSZXF1aXJlZFZhbGlkYXRvcigpO1xuICogXG4gKiAvLyBDcmVhdGUgYSByZXF1aXJlZCB2YWxpZGF0b3Igd2l0aCBjdXN0b20gZXJyb3IgbWVzc2FnZVxuICogY29uc3QgY3VzdG9tUmVxdWlyZWRWYWxpZGF0b3IgPSBuZXcgUmVxdWlyZWRWYWxpZGF0b3IoXCJUaGlzIGZpZWxkIGlzIG1hbmRhdG9yeVwiKTtcbiAqIFxuICogLy8gVmFsaWRhdGUgZGlmZmVyZW50IHR5cGVzIG9mIHZhbHVlc1xuICogcmVxdWlyZWRWYWxpZGF0b3IuaGFzRXJyb3JzKFwiSGVsbG9cIik7IC8vIHVuZGVmaW5lZCAodmFsaWQpXG4gKiByZXF1aXJlZFZhbGlkYXRvci5oYXNFcnJvcnMoXCJcIik7IC8vIFJldHVybnMgZXJyb3IgbWVzc2FnZSAoaW52YWxpZClcbiAqIHJlcXVpcmVkVmFsaWRhdG9yLmhhc0Vycm9ycygwKTsgLy8gdW5kZWZpbmVkICh2YWxpZCAtIDAgaXMgYSB2YWxpZCBudW1iZXIpXG4gKiByZXF1aXJlZFZhbGlkYXRvci5oYXNFcnJvcnMobnVsbCk7IC8vIFJldHVybnMgZXJyb3IgbWVzc2FnZSAoaW52YWxpZClcbiAqIHJlcXVpcmVkVmFsaWRhdG9yLmhhc0Vycm9ycyhbXSk7IC8vIHVuZGVmaW5lZCAodmFsaWQgLSBlbXB0eSBhcnJheSBpcyBzdGlsbCBhbiBhcnJheSlcbiAqIGBgYFxuICogXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IFYgYXMgUmVxdWlyZWRWYWxpZGF0b3JcbiAqICAgXG4gKiAgIEMtPj5WOiBuZXcgUmVxdWlyZWRWYWxpZGF0b3IobWVzc2FnZSlcbiAqICAgQy0+PlY6IGhhc0Vycm9ycyh2YWx1ZSwgb3B0aW9ucylcbiAqICAgYWx0IHR5cGVvZiB2YWx1ZSBpcyBib29sZWFuIG9yIG51bWJlclxuICogICAgIGFsdCB2YWx1ZSBpcyB1bmRlZmluZWRcbiAqICAgICAgIFYtLT4+QzogRXJyb3IgbWVzc2FnZVxuICogICAgIGVsc2UgdmFsdWUgaXMgZGVmaW5lZFxuICogICAgICAgVi0tPj5DOiB1bmRlZmluZWQgKHZhbGlkKVxuICogICAgIGVuZFxuICogICBlbHNlIG90aGVyIHR5cGVzXG4gKiAgICAgYWx0IHZhbHVlIGlzIGZhbHN5IChudWxsLCB1bmRlZmluZWQsIGVtcHR5IHN0cmluZylcbiAqICAgICAgIFYtLT4+QzogRXJyb3IgbWVzc2FnZVxuICogICAgIGVsc2UgdmFsdWUgaXMgdHJ1dGh5XG4gKiAgICAgICBWLS0+PkM6IHVuZGVmaW5lZCAodmFsaWQpXG4gKiAgICAgZW5kXG4gKiAgIGVuZFxuICogXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5AdmFsaWRhdG9yKFZhbGlkYXRpb25LZXlzLlJFUVVJUkVEKVxuZXhwb3J0IGNsYXNzIFJlcXVpcmVkVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5SRVFVSVJFRCkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYSB2YWx1ZSBpcyBwcmVzZW50IGFuZCBub3QgZW1wdHlcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIHRoYXQgdGhlIHByb3ZpZGVkIHZhbHVlIGV4aXN0cyBhbmQgaXMgbm90IGVtcHR5LlxuICAgKiBUaGUgdmFsaWRhdGlvbiBsb2dpYyB2YXJpZXMgYnkgdHlwZTpcbiAgICogLSBGb3IgYm9vbGVhbnMgYW5kIG51bWJlcnM6IGNoZWNrcyBpZiB0aGUgdmFsdWUgaXMgdW5kZWZpbmVkXG4gICAqIC0gRm9yIG90aGVyIHR5cGVzIChzdHJpbmdzLCBhcnJheXMsIG9iamVjdHMpOiBjaGVja3MgaWYgdGhlIHZhbHVlIGlzIGZhbHN5XG4gICAqXG4gICAqIEBwYXJhbSB7YW55fSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byB2YWxpZGF0ZVxuICAgKiBAcGFyYW0ge1ZhbGlkYXRvck9wdGlvbnN9IFtvcHRpb25zPXt9XSAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gb3B0aW9uc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9IEVycm9yIG1lc3NhZ2UgaWYgdmFsaWRhdGlvbiBmYWlscywgdW5kZWZpbmVkIGlmIHZhbGlkYXRpb24gcGFzc2VzXG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IGFueSxcbiAgICBvcHRpb25zOiBWYWxpZGF0b3JPcHRpb25zID0ge31cbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBzd2l0Y2ggKHR5cGVvZiB2YWx1ZSkge1xuICAgICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJ1bmRlZmluZWRcIlxuICAgICAgICAgID8gdGhpcy5nZXRNZXNzYWdlKG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gIXZhbHVlXG4gICAgICAgICAgPyB0aGlzLmdldE1lc3NhZ2Uob3B0aW9ucy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSlcbiAgICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IFN0ZXBWYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgU3RlcCBWYWxpZGF0b3JcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1NURVB9XG4gKlxuICogQGNsYXNzIFN0ZXBWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuU1RFUClcbmV4cG9ydCBjbGFzcyBTdGVwVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPFN0ZXBWYWxpZGF0b3JPcHRpb25zPiB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuU1RFUCkge1xuICAgIHN1cGVyKG1lc3NhZ2UsIFwibnVtYmVyXCIsIFwic3RyaW5nXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIG1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RlcFxuICAgKiBAcGFyYW0ge1N0ZXBWYWxpZGF0b3JPcHRpb25zfSBvcHRpb25zXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogbnVtYmVyIHwgc3RyaW5nLFxuICAgIG9wdGlvbnM6IFN0ZXBWYWxpZGF0b3JPcHRpb25zXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuO1xuICAgIHJldHVybiBOdW1iZXIodmFsdWUpICUgTnVtYmVyKG9wdGlvbnMuc3RlcCkgIT09IDBcbiAgICAgID8gdGhpcy5nZXRNZXNzYWdlKG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsIG9wdGlvbnMuc3RlcClcbiAgICAgIDogdW5kZWZpbmVkO1xuICB9XG59XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tIFwiLi9WYWxpZGF0b3JcIjtcbmltcG9ydCB7IERFRkFVTFRfRVJST1JfTUVTU0FHRVMsIFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBWYWxpZGF0aW9uIH0gZnJvbSBcIi4uL1ZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFR5cGVWYWxpZGF0b3JPcHRpb25zLCBWYWxpZGF0b3JEZWZpbml0aW9uIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBNb2RlbEtleXMgfSBmcm9tIFwiLi4vLi4vdXRpbHMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBSZWZsZWN0aW9uIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvciBmb3IgY2hlY2tpbmcgaWYgYSB2YWx1ZSBpcyBvZiB0aGUgZXhwZWN0ZWQgdHlwZShzKVxuICogQHN1bW1hcnkgVGhlIFR5cGVWYWxpZGF0b3IgZW5zdXJlcyB0aGF0IGEgdmFsdWUgbWF0Y2hlcyBvbmUgb2YgdGhlIHNwZWNpZmllZCB0eXBlcy5cbiAqIEl0IGNhbiB2YWxpZGF0ZSBhZ2FpbnN0IGEgc2luZ2xlIHR5cGUsIG11bHRpcGxlIHR5cGVzLCBvciBhIHR5cGUgd2l0aCBhIHNwZWNpZmljIG5hbWUuXG4gKiBUaGlzIHZhbGlkYXRvciBpcyB0eXBpY2FsbHkgdXNlZCB3aXRoIHRoZSBAdHlwZSBkZWNvcmF0b3IgYW5kIGlzIGZ1bmRhbWVudGFsIGZvclxuICogZW5zdXJpbmcgdHlwZSBzYWZldHkgaW4gdmFsaWRhdGVkIG1vZGVscy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIHZhbGlkYXRpb24gZmFpbHMsIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1RZUEV9XG4gKlxuICogQGNsYXNzIFR5cGVWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBDcmVhdGUgYSB0eXBlIHZhbGlkYXRvciB3aXRoIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogY29uc3QgdHlwZVZhbGlkYXRvciA9IG5ldyBUeXBlVmFsaWRhdG9yKCk7XG4gKlxuICogLy8gQ3JlYXRlIGEgdHlwZSB2YWxpZGF0b3Igd2l0aCBjdXN0b20gZXJyb3IgbWVzc2FnZVxuICogY29uc3QgY3VzdG9tVHlwZVZhbGlkYXRvciA9IG5ldyBUeXBlVmFsaWRhdG9yKFwiVmFsdWUgbXVzdCBiZSBvZiB0eXBlIHswfSwgYnV0IGdvdCB7MX1cIik7XG4gKlxuICogLy8gVmFsaWRhdGUgYWdhaW5zdCBhIHNpbmdsZSB0eXBlXG4gKiBjb25zdCBzdHJpbmdPcHRpb25zID0geyB0eXBlczogXCJzdHJpbmdcIiB9O1xuICogdHlwZVZhbGlkYXRvci5oYXNFcnJvcnMoXCJoZWxsb1wiLCBzdHJpbmdPcHRpb25zKTsgLy8gdW5kZWZpbmVkICh2YWxpZClcbiAqIHR5cGVWYWxpZGF0b3IuaGFzRXJyb3JzKDEyMywgc3RyaW5nT3B0aW9ucyk7IC8vIFJldHVybnMgZXJyb3IgbWVzc2FnZSAoaW52YWxpZClcbiAqXG4gKiAvLyBWYWxpZGF0ZSBhZ2FpbnN0IG11bHRpcGxlIHR5cGVzXG4gKiBjb25zdCBtdWx0aU9wdGlvbnMgPSB7IHR5cGVzOiBbXCJzdHJpbmdcIiwgXCJudW1iZXJcIl0gfTtcbiAqIHR5cGVWYWxpZGF0b3IuaGFzRXJyb3JzKFwiaGVsbG9cIiwgbXVsdGlPcHRpb25zKTsgLy8gdW5kZWZpbmVkICh2YWxpZClcbiAqIHR5cGVWYWxpZGF0b3IuaGFzRXJyb3JzKDEyMywgbXVsdGlPcHRpb25zKTsgLy8gdW5kZWZpbmVkICh2YWxpZClcbiAqIHR5cGVWYWxpZGF0b3IuaGFzRXJyb3JzKHRydWUsIG11bHRpT3B0aW9ucyk7IC8vIFJldHVybnMgZXJyb3IgbWVzc2FnZSAoaW52YWxpZClcbiAqXG4gKiAvLyBWYWxpZGF0ZSBhZ2FpbnN0IGEgY2xhc3MgdHlwZVxuICogY29uc3QgY2xhc3NPcHRpb25zID0geyB0eXBlczogeyBuYW1lOiBcIkRhdGVcIiB9IH07XG4gKiB0eXBlVmFsaWRhdG9yLmhhc0Vycm9ycyhuZXcgRGF0ZSgpLCBjbGFzc09wdGlvbnMpOyAvLyB1bmRlZmluZWQgKHZhbGlkKVxuICogYGBgXG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENsaWVudFxuICogICBwYXJ0aWNpcGFudCBWIGFzIFR5cGVWYWxpZGF0b3JcbiAqICAgcGFydGljaXBhbnQgUiBhcyBSZWZsZWN0aW9uXG4gKlxuICogICBDLT4+VjogbmV3IFR5cGVWYWxpZGF0b3IobWVzc2FnZSlcbiAqICAgQy0+PlY6IGhhc0Vycm9ycyh2YWx1ZSwgb3B0aW9ucylcbiAqICAgYWx0IHZhbHVlIGlzIHVuZGVmaW5lZFxuICogICAgIFYtLT4+QzogdW5kZWZpbmVkICh2YWxpZClcbiAqICAgZWxzZSB2YWx1ZSBpcyBkZWZpbmVkXG4gKiAgICAgVi0+PlI6IGV2YWx1YXRlRGVzaWduVHlwZXModmFsdWUsIHR5cGVzKVxuICogICAgIGFsdCB0eXBlIGV2YWx1YXRpb24gcGFzc2VzXG4gKiAgICAgICBWLS0+PkM6IHVuZGVmaW5lZCAodmFsaWQpXG4gKiAgICAgZWxzZSB0eXBlIGV2YWx1YXRpb24gZmFpbHNcbiAqICAgICAgIFYtPj5WOiBGb3JtYXQgZXJyb3IgbWVzc2FnZSB3aXRoIHR5cGUgaW5mb1xuICogICAgICAgVi0tPj5DOiBFcnJvciBtZXNzYWdlXG4gKiAgICAgZW5kXG4gKiAgIGVuZFxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuVFlQRSlcbmV4cG9ydCBjbGFzcyBUeXBlVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPFR5cGVWYWxpZGF0b3JPcHRpb25zPiB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuVFlQRSkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYSB2YWx1ZSBpcyBvZiB0aGUgZXhwZWN0ZWQgdHlwZShzKVxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgdGhhdCB0aGUgcHJvdmlkZWQgdmFsdWUgbWF0Y2hlcyBvbmUgb2YgdGhlIHNwZWNpZmllZCB0eXBlcy5cbiAgICogSXQgdXNlcyB0aGUgUmVmbGVjdGlvbiB1dGlsaXR5IHRvIGV2YWx1YXRlIGlmIHRoZSB2YWx1ZSdzIHR5cGUgbWF0Y2hlcyB0aGUgZXhwZWN0ZWQgdHlwZXMuXG4gICAqIFRoZSBtZXRob2Qgc2tpcHMgdmFsaWRhdGlvbiBmb3IgdW5kZWZpbmVkIHZhbHVlcyB0byBhdm9pZCBjb25mbGljdHMgd2l0aCB0aGUgUmVxdWlyZWRWYWxpZGF0b3IuXG4gICAqXG4gICAqIEBwYXJhbSB7YW55fSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byB2YWxpZGF0ZVxuICAgKiBAcGFyYW0ge1R5cGVWYWxpZGF0b3JPcHRpb25zfSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGNvbnRhaW5pbmcgdGhlIGV4cGVjdGVkIHR5cGVzXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH0gRXJyb3IgbWVzc2FnZSBpZiB2YWxpZGF0aW9uIGZhaWxzLCB1bmRlZmluZWQgaWYgdmFsaWRhdGlvbiBwYXNzZXNcbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogYW55LFxuICAgIG9wdGlvbnM6IFR5cGVWYWxpZGF0b3JPcHRpb25zXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybjsgLy8gRG9uJ3QgdHJ5IGFuZCBlbmZvcmNlIHR5cGUgaWYgdW5kZWZpbmVkXG4gICAgY29uc3QgeyB0eXBlcywgbWVzc2FnZSB9ID0gb3B0aW9ucztcbiAgICBpZiAoIVJlZmxlY3Rpb24uZXZhbHVhdGVEZXNpZ25UeXBlcyh2YWx1ZSwgdHlwZXMpKVxuICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZShcbiAgICAgICAgbWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsXG4gICAgICAgIHR5cGVvZiB0eXBlcyA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgID8gdHlwZXNcbiAgICAgICAgICA6IEFycmF5LmlzQXJyYXkodHlwZXMpXG4gICAgICAgICAgICA/IHR5cGVzLmpvaW4oXCIsIFwiKVxuICAgICAgICAgICAgOiB0eXBlcy5uYW1lLFxuICAgICAgICB0eXBlb2YgdmFsdWVcbiAgICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmVnaXN0ZXIgdGhlIFR5cGVWYWxpZGF0b3Igd2l0aCB0aGUgVmFsaWRhdGlvbiByZWdpc3RyeVxuICogQHN1bW1hcnkgVGhpcyByZWdpc3RyYXRpb24gYXNzb2NpYXRlcyB0aGUgVHlwZVZhbGlkYXRvciB3aXRoIHRoZSBNb2RlbEtleXMuVFlQRSBrZXksXG4gKiBhbGxvd2luZyBpdCB0byBiZSB1c2VkIGZvciB2YWxpZGF0aW5nIGRlc2lnbiB0eXBlcy4gVGhlIHNhdmUgZmxhZyBpcyBzZXQgdG8gZmFsc2VcbiAqIHRvIHByZXZlbnQgdGhlIHZhbGlkYXRvciBmcm9tIGJlaW5nIHNhdmVkIGluIHRoZSBzdGFuZGFyZCB2YWxpZGF0b3IgcmVnaXN0cnkuXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICovXG5WYWxpZGF0aW9uLnJlZ2lzdGVyKHtcbiAgdmFsaWRhdG9yOiBUeXBlVmFsaWRhdG9yLFxuICB2YWxpZGF0aW9uS2V5OiBNb2RlbEtleXMuVFlQRSxcbiAgc2F2ZTogZmFsc2UsXG59IGFzIFZhbGlkYXRvckRlZmluaXRpb24pO1xuIiwiaW1wb3J0IHtcbiAgVmFsaWRhdGlvbktleXMsXG4gIERFRkFVTFRfRVJST1JfTUVTU0FHRVMsXG4gIERFRkFVTFRfUEFUVEVSTlMsXG59IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgUGF0dGVyblZhbGlkYXRvciB9IGZyb20gXCIuL1BhdHRlcm5WYWxpZGF0b3JcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IFBhdHRlcm5WYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvciBmb3IgY2hlY2tpbmcgaWYgYSBzdHJpbmcgaXMgYSB2YWxpZCBVUkxcbiAqIEBzdW1tYXJ5IFRoZSBVUkxWYWxpZGF0b3IgY2hlY2tzIGlmIGEgc3RyaW5nIG1hdGNoZXMgYSBzdGFuZGFyZCBVUkwgcGF0dGVybi5cbiAqIEl0IGV4dGVuZHMgdGhlIFBhdHRlcm5WYWxpZGF0b3IgYW5kIHVzZXMgYSByb2J1c3QgVVJMIHJlZ2V4IHBhdHRlcm4gdG8gdmFsaWRhdGUgd2ViIGFkZHJlc3Nlcy5cbiAqIFRoZSBwYXR0ZXJuIGlzIHNvdXJjZWQgZnJvbSB7QGxpbmsgaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vZHBlcmluaS83MjkyOTR9IGFuZCBpcyB3aWRlbHlcbiAqIHJlY29nbml6ZWQgZm9yIGl0cyBhY2N1cmFjeSBpbiB2YWxpZGF0aW5nIFVSTHMuIFRoaXMgdmFsaWRhdG9yIGlzIHR5cGljYWxseSB1c2VkIHdpdGggdGhlIEB1cmwgZGVjb3JhdG9yLlxuICogXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIHZhbGlkYXRpb24gZmFpbHMsIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1VSTH1cbiAqIFxuICogQGNsYXNzIFVSTFZhbGlkYXRvclxuICogQGV4dGVuZHMgUGF0dGVyblZhbGlkYXRvclxuICogXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gQ3JlYXRlIGEgVVJMIHZhbGlkYXRvciB3aXRoIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogY29uc3QgdXJsVmFsaWRhdG9yID0gbmV3IFVSTFZhbGlkYXRvcigpO1xuICogXG4gKiAvLyBDcmVhdGUgYSBVUkwgdmFsaWRhdG9yIHdpdGggY3VzdG9tIGVycm9yIG1lc3NhZ2VcbiAqIGNvbnN0IGN1c3RvbVVybFZhbGlkYXRvciA9IG5ldyBVUkxWYWxpZGF0b3IoXCJQbGVhc2UgZW50ZXIgYSB2YWxpZCB3ZWIgYWRkcmVzc1wiKTtcbiAqIFxuICogLy8gVmFsaWRhdGUgYSBVUkxcbiAqIGNvbnN0IHJlc3VsdCA9IHVybFZhbGlkYXRvci5oYXNFcnJvcnMoXCJodHRwczovL2V4YW1wbGUuY29tXCIpOyAvLyB1bmRlZmluZWQgKHZhbGlkKVxuICogY29uc3QgaW52YWxpZFJlc3VsdCA9IHVybFZhbGlkYXRvci5oYXNFcnJvcnMoXCJub3QtYS11cmxcIik7IC8vIFJldHVybnMgZXJyb3IgbWVzc2FnZSAoaW52YWxpZClcbiAqIGBgYFxuICogXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IFUgYXMgVVJMVmFsaWRhdG9yXG4gKiAgIHBhcnRpY2lwYW50IFAgYXMgUGF0dGVyblZhbGlkYXRvclxuICogICBcbiAqICAgQy0+PlU6IG5ldyBVUkxWYWxpZGF0b3IobWVzc2FnZSlcbiAqICAgVS0+PlA6IHN1cGVyKG1lc3NhZ2UpXG4gKiAgIEMtPj5VOiBoYXNFcnJvcnModmFsdWUsIG9wdGlvbnMpXG4gKiAgIFUtPj5QOiBzdXBlci5oYXNFcnJvcnModmFsdWUsIG9wdGlvbnMgd2l0aCBVUkwgcGF0dGVybilcbiAqICAgUC0tPj5VOiB2YWxpZGF0aW9uIHJlc3VsdFxuICogICBVLS0+PkM6IHZhbGlkYXRpb24gcmVzdWx0XG4gKiBcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuVVJMKVxuZXhwb3J0IGNsYXNzIFVSTFZhbGlkYXRvciBleHRlbmRzIFBhdHRlcm5WYWxpZGF0b3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlVSTCkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYSBzdHJpbmcgaXMgYSB2YWxpZCBVUkxcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIHRoYXQgdGhlIHByb3ZpZGVkIHN0cmluZyBtYXRjaGVzIHRoZSBVUkwgcGF0dGVybi5cbiAgICogVGhpcyBtZXRob2QgZXh0ZW5kcyB0aGUgUGF0dGVyblZhbGlkYXRvcidzIGhhc0Vycm9ycyBtZXRob2QgYnkgZW5zdXJpbmdcbiAgICogdGhlIFVSTCBwYXR0ZXJuIGlzIHVzZWQsIGV2ZW4gaWYgbm90IGV4cGxpY2l0bHkgcHJvdmlkZWQgaW4gdGhlIG9wdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSAtIFRoZSBzdHJpbmcgdG8gdmFsaWRhdGUgYXMgYSBVUkxcbiAgICogQHBhcmFtIHtQYXR0ZXJuVmFsaWRhdG9yT3B0aW9uc30gW29wdGlvbnM9e31dIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvbiBvcHRpb25zXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH0gRXJyb3IgbWVzc2FnZSBpZiB2YWxpZGF0aW9uIGZhaWxzLCB1bmRlZmluZWQgaWYgdmFsaWRhdGlvbiBwYXNzZXNcbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgUGF0dGVyblZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IHN0cmluZyxcbiAgICBvcHRpb25zOiBQYXR0ZXJuVmFsaWRhdG9yT3B0aW9ucyA9IHt9XG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHN1cGVyLmhhc0Vycm9ycyh2YWx1ZSwge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIHBhdHRlcm46IG9wdGlvbnMucGF0dGVybiB8fCBERUZBVUxUX1BBVFRFUk5TLlVSTCxcbiAgICB9KTtcbiAgfVxufVxuIiwiaW1wb3J0IFwicmVmbGVjdC1tZXRhZGF0YVwiO1xuaW1wb3J0IHsgVmFsaWRhdGlvbk1ldGFkYXRhIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7XG4gIERFRkFVTFRfRVJST1JfTUVTU0FHRVMsXG4gIERFRkFVTFRfUEFUVEVSTlMsXG4gIFZhbGlkYXRpb25LZXlzLFxufSBmcm9tIFwiLi9WYWxpZGF0b3JzL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgc2YgfSBmcm9tIFwiLi4vdXRpbHMvc3RyaW5nc1wiO1xuaW1wb3J0IHsgTW9kZWxDb25zdHJ1Y3RvciB9IGZyb20gXCIuLi9tb2RlbC90eXBlc1wiO1xuaW1wb3J0IHsgcGFyc2VEYXRlIH0gZnJvbSBcIi4uL3V0aWxzL2RhdGVzXCI7XG5pbXBvcnQgeyBwcm9wTWV0YWRhdGEgfSBmcm9tIFwiLi4vdXRpbHMvZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgVmFsaWRhdGlvbiB9IGZyb20gXCIuL1ZhbGlkYXRpb25cIjtcbmltcG9ydCB7IERlY29yYXRpb24gfSBmcm9tIFwiLi4vdXRpbHMvRGVjb3JhdGlvblwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBQcm9wZXJ0eSBkZWNvcmF0b3IgdGhhdCBtYXJrcyBhIGZpZWxkIGFzIHJlcXVpcmVkXG4gKiBAc3VtbWFyeSBNYXJrcyB0aGUgcHJvcGVydHkgYXMgcmVxdWlyZWQsIGNhdXNpbmcgdmFsaWRhdGlvbiB0byBmYWlsIGlmIHRoZSBwcm9wZXJ0eSBpcyB1bmRlZmluZWQsIG51bGwsIG9yIGVtcHR5LlxuICogVmFsaWRhdG9ycyB0byB2YWxpZGF0ZSBhIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IHVzZSBrZXkge0BsaW5rIFZhbGlkYXRpb25LZXlzI1JFUVVJUkVEfS5cbiAqIFRoaXMgZGVjb3JhdG9yIGlzIGNvbW1vbmx5IHVzZWQgYXMgdGhlIGZpcnN0IHZhbGlkYXRpb24gc3RlcCBmb3IgaW1wb3J0YW50IGZpZWxkcy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIC0gVGhlIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIHZhbGlkYXRpb24gZmFpbHMuIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1JFUVVJUkVEfVxuICogQHJldHVybiB7UHJvcGVydHlEZWNvcmF0b3J9IEEgZGVjb3JhdG9yIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gY2xhc3MgcHJvcGVydGllc1xuICpcbiAqIEBmdW5jdGlvbiByZXF1aXJlZFxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY2xhc3MgVXNlciB7XG4gKiAgIEByZXF1aXJlZCgpXG4gKiAgIHVzZXJuYW1lOiBzdHJpbmc7XG4gKlxuICogICBAcmVxdWlyZWQoXCJFbWFpbCBhZGRyZXNzIGlzIG1hbmRhdG9yeVwiKVxuICogICBlbWFpbDogc3RyaW5nO1xuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlZChtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlJFUVVJUkVEKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLlJFUVVJUkVEKTtcbiAgcmV0dXJuIERlY29yYXRpb24uZm9yKGtleSlcbiAgICAuZGVmaW5lKFxuICAgICAgcHJvcE1ldGFkYXRhPFZhbGlkYXRpb25NZXRhZGF0YT4oa2V5LCB7XG4gICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICB9KVxuICAgIClcbiAgICAuYXBwbHkoKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUHJvcGVydHkgZGVjb3JhdG9yIHRoYXQgZW5mb3JjZXMgYSBtaW5pbXVtIHZhbHVlIGNvbnN0cmFpbnRcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBtaW5pbXVtIHZhbHVlIGZvciB0aGUgcHJvcGVydHksIGNhdXNpbmcgdmFsaWRhdGlvbiB0byBmYWlsIGlmIHRoZSBwcm9wZXJ0eSB2YWx1ZSBpcyBsZXNzIHRoYW4gdGhlIHNwZWNpZmllZCBtaW5pbXVtLlxuICogVmFsaWRhdG9ycyB0byB2YWxpZGF0ZSBhIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IHVzZSBrZXkge0BsaW5rIFZhbGlkYXRpb25LZXlzI01JTn0uXG4gKiBUaGlzIGRlY29yYXRvciB3b3JrcyB3aXRoIG51bWVyaWMgdmFsdWVzIGFuZCBkYXRlcy5cbiAqXG4gKiBAcGFyYW0ge251bWJlciB8IERhdGUgfCBzdHJpbmd9IHZhbHVlIC0gVGhlIG1pbmltdW0gdmFsdWUgYWxsb3dlZC4gRm9yIGRhdGVzLCBjYW4gYmUgYSBEYXRlIG9iamVjdCBvciBhIHN0cmluZyB0aGF0IGNhbiBiZSBjb252ZXJ0ZWQgdG8gYSBkYXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIC0gVGhlIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIHZhbGlkYXRpb24gZmFpbHMuIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI01JTn1cbiAqIEByZXR1cm4ge1Byb3BlcnR5RGVjb3JhdG9yfSBBIGRlY29yYXRvciBmdW5jdGlvbiB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGNsYXNzIHByb3BlcnRpZXNcbiAqXG4gKiBAZnVuY3Rpb24gbWluXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjbGFzcyBQcm9kdWN0IHtcbiAqICAgQG1pbigwKVxuICogICBwcmljZTogbnVtYmVyO1xuICpcbiAqICAgQG1pbihuZXcgRGF0ZSgyMDIzLCAwLCAxKSwgXCJEYXRlIG11c3QgYmUgYWZ0ZXIgSmFudWFyeSAxLCAyMDIzXCIpXG4gKiAgIHJlbGVhc2VEYXRlOiBEYXRlO1xuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtaW4oXG4gIHZhbHVlOiBudW1iZXIgfCBEYXRlIHwgc3RyaW5nLFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLk1JTlxuKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLk1JTik7XG4gIHJldHVybiBEZWNvcmF0aW9uLmZvcihrZXkpXG4gICAgLmRlZmluZShcbiAgICAgIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLk1JTiksIHtcbiAgICAgICAgW1ZhbGlkYXRpb25LZXlzLk1JTl06IHZhbHVlLFxuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICB0eXBlczogW051bWJlci5uYW1lLCBEYXRlLm5hbWVdLFxuICAgICAgfSlcbiAgICApXG4gICAgLmFwcGx5KCk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIG1heGltdW0gdmFsdWUgZm9yIHRoZSBwcm9wZXJ0eVxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNNQVh9XG4gKlxuICogQHBhcmFtIHtudW1iZXIgfCBEYXRlfSB2YWx1ZVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjTUFYfVxuICpcbiAqIEBmdW5jdGlvbiBtYXhcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXgoXG4gIHZhbHVlOiBudW1iZXIgfCBEYXRlIHwgc3RyaW5nLFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLk1BWFxuKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLk1BWCk7XG4gIHJldHVybiBEZWNvcmF0aW9uLmZvcihrZXkpXG4gICAgLmRlZmluZShcbiAgICAgIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KGtleSwge1xuICAgICAgICBbVmFsaWRhdGlvbktleXMuTUFYXTogdmFsdWUsXG4gICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICAgIHR5cGVzOiBbTnVtYmVyLm5hbWUsIERhdGUubmFtZV0sXG4gICAgICB9KVxuICAgIClcbiAgICAuYXBwbHkoKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgc3RlcCB2YWx1ZSBmb3IgdGhlIHByb3BlcnR5XG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdG9ycyB0byB2YWxpZGF0ZSBhIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IHVzZSBrZXkge0BsaW5rIFZhbGlkYXRpb25LZXlzI1NURVB9XG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIHRoZSBlcnJvciBtZXNzYWdlLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNTVEVQfVxuICpcbiAqIEBmdW5jdGlvbiBzdGVwXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gc3RlcChcbiAgdmFsdWU6IG51bWJlcixcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5TVEVQXG4pIHtcbiAgY29uc3Qga2V5ID0gVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuU1RFUCk7XG4gIHJldHVybiBEZWNvcmF0aW9uLmZvcihrZXkpXG4gICAgLmRlZmluZShcbiAgICAgIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KGtleSwge1xuICAgICAgICBbVmFsaWRhdGlvbktleXMuU1RFUF06IHZhbHVlLFxuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICB0eXBlczogW051bWJlci5uYW1lXSxcbiAgICAgIH0pXG4gICAgKVxuICAgIC5hcHBseSgpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBtaW5pbXVtIGxlbmd0aCBmb3IgdGhlIHByb3BlcnR5XG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdG9ycyB0byB2YWxpZGF0ZSBhIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IHVzZSBrZXkge0BsaW5rIFZhbGlkYXRpb25LZXlzI01JTl9MRU5HVEh9XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIHRoZSBlcnJvciBtZXNzYWdlLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNNSU5fTEVOR1RIfVxuICpcbiAqIEBmdW5jdGlvbiBtaW5sZW5ndGhcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtaW5sZW5ndGgoXG4gIHZhbHVlOiBudW1iZXIsXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuTUlOX0xFTkdUSFxuKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLk1JTl9MRU5HVEgpO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoXG4gICAgICBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihrZXksIHtcbiAgICAgICAgW1ZhbGlkYXRpb25LZXlzLk1JTl9MRU5HVEhdOiB2YWx1ZSxcbiAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgICAgdHlwZXM6IFtTdHJpbmcubmFtZSwgQXJyYXkubmFtZSwgU2V0Lm5hbWVdLFxuICAgICAgfSlcbiAgICApXG4gICAgLmFwcGx5KCk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIG1heGltdW0gbGVuZ3RoIGZvciB0aGUgcHJvcGVydHlcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3JzIHRvIHZhbGlkYXRlIGEgZGVjb3JhdGVkIHByb3BlcnR5IG11c3QgdXNlIGtleSB7QGxpbmsgVmFsaWRhdGlvbktleXMjTUFYX0xFTkdUSH1cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gdGhlIGVycm9yIG1lc3NhZ2UuIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI01BWF9MRU5HVEh9XG4gKlxuICogQGZ1bmN0aW9uIG1heGxlbmd0aFxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1heGxlbmd0aChcbiAgdmFsdWU6IG51bWJlcixcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5NQVhfTEVOR1RIXG4pIHtcbiAgY29uc3Qga2V5ID0gVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuTUFYX0xFTkdUSCk7XG4gIHJldHVybiBEZWNvcmF0aW9uLmZvcihrZXkpXG4gICAgLmRlZmluZShcbiAgICAgIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KGtleSwge1xuICAgICAgICBbVmFsaWRhdGlvbktleXMuTUFYX0xFTkdUSF06IHZhbHVlLFxuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICB0eXBlczogW1N0cmluZy5uYW1lLCBBcnJheS5uYW1lLCBTZXQubmFtZV0sXG4gICAgICB9KVxuICAgIClcbiAgICAuYXBwbHkoKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgUmVnRXhwIHBhdHRlcm4gdGhlIHByb3BlcnR5IG11c3QgcmVzcGVjdFxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNQQVRURVJOfVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjUEFUVEVSTn1cbiAqXG4gKiBAZnVuY3Rpb24gcGF0dGVyblxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhdHRlcm4oXG4gIHZhbHVlOiBSZWdFeHAgfCBzdHJpbmcsXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuUEFUVEVSTlxuKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLlBBVFRFUk4pO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoXG4gICAgICBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5QQVRURVJOKSwge1xuICAgICAgICBbVmFsaWRhdGlvbktleXMuUEFUVEVSTl06XG4gICAgICAgICAgdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiID8gdmFsdWUgOiB2YWx1ZS50b1N0cmluZygpLFxuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICB0eXBlczogW1N0cmluZy5uYW1lXSxcbiAgICAgIH0pXG4gICAgKVxuICAgIC5hcHBseSgpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIHByb3BlcnR5IGFzIGFuIGVtYWlsXG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdG9ycyB0byB2YWxpZGF0ZSBhIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IHVzZSBrZXkge0BsaW5rIFZhbGlkYXRpb25LZXlzI0VNQUlMfVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gdGhlIGVycm9yIG1lc3NhZ2UuIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0VNQUlMfVxuICpcbiAqIEBmdW5jdGlvbiBlbWFpbFxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVtYWlsKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuRU1BSUwpIHtcbiAgY29uc3Qga2V5ID0gVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuRU1BSUwpO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoXG4gICAgICBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5FTUFJTCksIHtcbiAgICAgICAgW1ZhbGlkYXRpb25LZXlzLlBBVFRFUk5dOiBERUZBVUxUX1BBVFRFUk5TLkVNQUlMLFxuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICB0eXBlczogW1N0cmluZy5uYW1lXSxcbiAgICAgIH0pXG4gICAgKVxuICAgIC5hcHBseSgpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIHByb3BlcnR5IGFzIGFuIFVSTFxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNVUkx9XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjVVJMfVxuICpcbiAqIEBmdW5jdGlvbiB1cmxcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cmwobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5VUkwpIHtcbiAgY29uc3Qga2V5ID0gVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuVVJMKTtcbiAgcmV0dXJuIERlY29yYXRpb24uZm9yKGtleSlcbiAgICAuZGVmaW5lKFxuICAgICAgcHJvcE1ldGFkYXRhPFZhbGlkYXRpb25NZXRhZGF0YT4oVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuVVJMKSwge1xuICAgICAgICBbVmFsaWRhdGlvbktleXMuUEFUVEVSTl06IERFRkFVTFRfUEFUVEVSTlMuVVJMLFxuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICB0eXBlczogW1N0cmluZy5uYW1lXSxcbiAgICAgIH0pXG4gICAgKVxuICAgIC5hcHBseSgpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IEVuZm9yY2VzIHR5cGUgdmVyaWZpY2F0aW9uXG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdG9ycyB0byB2YWxpZGF0ZSBhIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IHVzZSBrZXkge0BsaW5rIFZhbGlkYXRpb25LZXlzI1RZUEV9XG4gKlxuICogQHBhcmFtIHtzdHJpbmdbXSB8IHN0cmluZ30gdHlwZXMgYWNjZXB0ZWQgdHlwZXNcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gdGhlIGVycm9yIG1lc3NhZ2UuIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1RZUEV9XG4gKlxuICogQGZ1bmN0aW9uIHR5cGVcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0eXBlKFxuICB0eXBlczogc3RyaW5nW10gfCBzdHJpbmcsXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuVFlQRVxuKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLlRZUEUpO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoXG4gICAgICBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5UWVBFKSwge1xuICAgICAgICBjdXN0b21UeXBlczogdHlwZXMsXG4gICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICB9KVxuICAgIClcbiAgICAuYXBwbHkoKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEYXRlIEhhbmRsZXIgRGVjb3JhdG9yXG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdG9ycyB0byB2YWxpZGF0ZSBhIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IHVzZSBrZXkge0BsaW5rIFZhbGlkYXRpb25LZXlzI0RBVEV9XG4gKlxuICogV2lsbCBlbmZvcmNlIHNlcmlhbGl6YXRpb24gYWNjb3JkaW5nIHRvIHRoZSBzZWxlY3RlZCBmb3JtYXRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZm9ybWF0IGFjY2VwdGVkIGZvcm1hdCBhY2NvcmRpbmcgdG8ge0BsaW5rIGZvcm1hdERhdGV9XG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIHRoZSBlcnJvciBtZXNzYWdlLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNEQVRFfVxuICpcbiAqIEBmdW5jdGlvbiBkYXRlXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRhdGUoXG4gIGZvcm1hdDogc3RyaW5nID0gXCJkZC9NTS95eXl5XCIsXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuREFURVxuKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLkRBVEUpO1xuICBjb25zdCBkYXRlRGVjID0gKHRhcmdldDogUmVjb3JkPHN0cmluZywgYW55PiwgcHJvcGVydHlLZXk/OiBhbnkpOiBhbnkgPT4ge1xuICAgIHByb3BNZXRhZGF0YShrZXksIHtcbiAgICAgIFtWYWxpZGF0aW9uS2V5cy5GT1JNQVRdOiBmb3JtYXQsXG4gICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgdHlwZXM6IFtEYXRlLm5hbWVdLFxuICAgIH0pKHRhcmdldCwgcHJvcGVydHlLZXkpO1xuXG4gICAgY29uc3QgdmFsdWVzID0gbmV3IFdlYWtNYXAoKTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5S2V5LCB7XG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgc2V0KHRoaXM6IGFueSwgbmV3VmFsdWU6IHN0cmluZyB8IERhdGUpIHtcbiAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGhpcywgcHJvcGVydHlLZXkpO1xuICAgICAgICBpZiAoIWRlc2NyaXB0b3IgfHwgZGVzY3JpcHRvci5jb25maWd1cmFibGUpXG4gICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIHByb3BlcnR5S2V5LCB7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGdldDogKCkgPT4gdmFsdWVzLmdldCh0aGlzKSxcbiAgICAgICAgICAgIHNldDogKG5ld1ZhbHVlOiBzdHJpbmcgfCBEYXRlIHwgbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICAgIGxldCB2YWw6IERhdGUgfCB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdmFsID0gcGFyc2VEYXRlKGZvcm1hdCwgbmV3VmFsdWUpO1xuICAgICAgICAgICAgICAgIHZhbHVlcy5zZXQodGhpcywgdmFsKTtcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihzZihcIkZhaWxlZCB0byBwYXJzZSBkYXRlOiB7MH1cIiwgZS5tZXNzYWdlIHx8IGUpKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgdGhpc1twcm9wZXJ0eUtleV0gPSBuZXdWYWx1ZTtcbiAgICAgIH0sXG4gICAgICBnZXQoKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiaGVyZVwiKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH07XG4gIHJldHVybiBEZWNvcmF0aW9uLmZvcihrZXkpLmRlZmluZShkYXRlRGVjKS5hcHBseSgpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFBhc3N3b3JkIEhhbmRsZXIgRGVjb3JhdG9yXG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdG9ycyB0byB2YWxpZGF0ZSBhIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IHVzZSBrZXkge0BsaW5rIFZhbGlkYXRpb25LZXlzI1BBU1NXT1JEfVxuICpcbiAqIEBwYXJhbSB7UmVnRXhwfSBbcGF0dGVybl0gZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfUEFUVEVSTlMjQ0hBUjhfT05FX09GX0VBQ0h9XG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIHRoZSBlcnJvciBtZXNzYWdlLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNQQVNTV09SRH1cbiAqXG4gKiBAZnVuY3Rpb24gcGFzc3dvcmRcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGFzc3dvcmQoXG4gIHBhdHRlcm46IFJlZ0V4cCA9IERFRkFVTFRfUEFUVEVSTlMuUEFTU1dPUkQuQ0hBUjhfT05FX09GX0VBQ0gsXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuUEFTU1dPUkRcbikge1xuICBjb25zdCBrZXkgPSBWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5QQVNTV09SRCk7XG4gIHJldHVybiBEZWNvcmF0aW9uLmZvcihrZXkpXG4gICAgLmRlZmluZShcbiAgICAgIHByb3BNZXRhZGF0YShrZXksIHtcbiAgICAgICAgW1ZhbGlkYXRpb25LZXlzLlBBVFRFUk5dOiBwYXR0ZXJuLFxuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICB0eXBlczogW1N0cmluZy5uYW1lXSxcbiAgICAgIH0pXG4gICAgKVxuICAgIC5hcHBseSgpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IExpc3QgRGVjb3JhdG9yXG4gKiBAZGVzY3JpcHRpb24gQWxzbyBzZXRzIHRoZSB7QGxpbmsgdHlwZX0gdG8gdGhlIHByb3ZpZGVkIGNvbGxlY3Rpb25cbiAqXG4gKiBAcGFyYW0ge01vZGVsQ29uc3RydWN0b3J9IGNsYXp6XG4gKiBAcGFyYW0ge3N0cmluZ30gW2NvbGxlY3Rpb25dIFRoZSBjb2xsZWN0aW9uIGJlaW5nIHVzZWQuIGRlZmF1bHRzIHRvIEFycmF5XG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0xJU1R9XG4gKlxuICogQGZ1bmN0aW9uIGxpc3RcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbGlzdChcbiAgY2xheno6IE1vZGVsQ29uc3RydWN0b3I8YW55PiB8IE1vZGVsQ29uc3RydWN0b3I8YW55PltdLFxuICBjb2xsZWN0aW9uOiBcIkFycmF5XCIgfCBcIlNldFwiID0gXCJBcnJheVwiLFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkxJU1Rcbikge1xuICBjb25zdCBrZXkgPSBWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5MSVNUKTtcbiAgcmV0dXJuIERlY29yYXRpb24uZm9yKGtleSlcbiAgICAuZGVmaW5lKFxuICAgICAgcHJvcE1ldGFkYXRhKGtleSwge1xuICAgICAgICBjbGF6ejogQXJyYXkuaXNBcnJheShjbGF6eikgPyBjbGF6ei5tYXAoKGMpID0+IGMubmFtZSkgOiBbY2xhenoubmFtZV0sXG4gICAgICAgIHR5cGU6IGNvbGxlY3Rpb24sXG4gICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICB9KVxuICAgIClcbiAgICAuYXBwbHkoKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBTZXQgRGVjb3JhdG9yXG4gKiBAZGVzY3JpcHRpb24gV3JhcHBlciBmb3Ige0BsaW5rIGxpc3R9IHdpdGggdGhlICdTZXQnIENvbGxlY3Rpb25cbiAqXG4gKiBAcGFyYW0ge01vZGVsQ29uc3RydWN0b3J9IGNsYXp6XG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0xJU1R9XG4gKlxuICogQGZ1bmN0aW9uIHNldFxuICpcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXQoXG4gIGNsYXp6OiBNb2RlbENvbnN0cnVjdG9yPGFueT4sXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuTElTVFxuKSB7XG4gIHJldHVybiBsaXN0KGNsYXp6LCBcIlNldFwiLCBtZXNzYWdlKTtcbn1cbiIsImltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIi4vTW9kZWxcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBIZWxwZXIgRnVuY3Rpb24gdG8gb3ZlcnJpZGUgY29uc3RydWN0b3JzXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7YW55W119IFthcmdzXVxuICogQHJldHVybiB7VH0gdGhlIG5ldyBpbnN0YW5jZVxuICpcbiAqIEBmdW5jdGlvbiBjb25zdHJ1Y3RcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbnN0cnVjdDxUIGV4dGVuZHMgTW9kZWw+KFxuICBjb25zdHJ1Y3RvcjogYW55LFxuICAuLi5hcmdzOiBhbnlbXVxuKTogVCB7XG4gIGNvbnN0IF9jb25zdHIgPSAoLi4uYXJnejogYW55W10pID0+IG5ldyBjb25zdHJ1Y3RvciguLi5hcmd6KTtcbiAgX2NvbnN0ci5wcm90b3R5cGUgPSBjb25zdHJ1Y3Rvci5wcm90b3R5cGU7XG4gIHJldHVybiBfY29uc3RyKC4uLmFyZ3MpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFJlY3Vyc2l2ZWx5IGZpbmRzIHRoZSBsYXN0IHByb3RvdHlwZSBiZWZvcmUgT2JqZWN0XG4gKiBAcGFyYW0ge29iamVjdH0gb2JqXG4gKlxuICogQGZ1bmN0aW9uIGZpbmRMYXN0UHJvdG9CZWZvcmVPYmplY3RcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRMYXN0UHJvdG9CZWZvcmVPYmplY3Qob2JqOiBvYmplY3QpOiBvYmplY3Qge1xuICBsZXQgcHJvdG90eXBlOiBhbnkgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKTtcbiAgaWYgKHByb3RvdHlwZSA9PT0gT2JqZWN0LnByb3RvdHlwZSkgcmV0dXJuIG9iajtcbiAgd2hpbGUgKHByb3RvdHlwZSAhPT0gT2JqZWN0LnByb3RvdHlwZSkge1xuICAgIHByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90b3R5cGUpO1xuICAgIGlmIChwcm90b3R5cGUgPT09IE9iamVjdC5wcm90b3R5cGUpIHJldHVybiBwcm90b3R5cGU7XG4gICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90b3R5cGUpID09PSBPYmplY3QucHJvdG90eXBlKSByZXR1cm4gcHJvdG90eXBlO1xuICB9XG4gIHRocm93IG5ldyBFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHByb3BlciBwcm90b3R5cGVcIik7XG59XG5cbi8qKlxuICogQHN1bWFyeSBiaW5kcyB0aGUge0BsaW5rIE1vZGVsfSBjbGFzcyBhcyBhIHJvb3QgcHJvdG90eXBlIG9mIHRoZSBwcm92aWRlZCBpbnN0YW5jZVxuICpcbiAqIEBwYXJhbSB7dW5rbm93bn0gb2JqXG4gKlxuICogQGZ1bmN0aW9uIGJpbmRNb2RlbFByb3RvdHlwZVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gYmluZE1vZGVsUHJvdG90eXBlKG9iajogdW5rbm93bikge1xuICBpZiAob2JqIGluc3RhbmNlb2YgTW9kZWwpIHJldHVybjtcblxuICBmdW5jdGlvbiBiaW5kUHJvdG90eXBlKG9ialRvT3ZlcnJpZGU6IHVua25vd24sIHByb3RvdHlwZTogb2JqZWN0KSB7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG9ialRvT3ZlcnJpZGUsIHByb3RvdHlwZSk7XG4gIH1cblxuICBjb25zdCBwcm90b3R5cGU6IGFueSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmopO1xuICBpZiAocHJvdG90eXBlID09PSBPYmplY3QucHJvdG90eXBlKSB7XG4gICAgcmV0dXJuIGJpbmRQcm90b3R5cGUob2JqLCBNb2RlbC5wcm90b3R5cGUpO1xuICB9XG4gIHdoaWxlIChwcm90b3R5cGUgIT09IE9iamVjdC5wcm90b3R5cGUpIHtcbiAgICBjb25zdCBwcm90ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvdHlwZSk7XG4gICAgaWYgKFxuICAgICAgcHJvdCA9PT0gT2JqZWN0LnByb3RvdHlwZSB8fFxuICAgICAgT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3QpID09PSBPYmplY3QucHJvdG90eXBlXG4gICAgKSB7XG4gICAgICByZXR1cm4gYmluZFByb3RvdHlwZShwcm90b3R5cGUsIE1vZGVsLnByb3RvdHlwZSk7XG4gICAgfVxuICB9XG4gIHRocm93IG5ldyBFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHByb3BlciBwcm90b3R5cGUgdG8gYmluZFwiKTtcbn1cbiIsImltcG9ydCB7IGJpbmRNb2RlbFByb3RvdHlwZSwgY29uc3RydWN0IH0gZnJvbSBcIi4vY29uc3RydWN0aW9uXCI7XG5pbXBvcnQgeyBNb2RlbEtleXMgfSBmcm9tIFwiLi4vdXRpbHMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCIuL01vZGVsXCI7XG5pbXBvcnQgeyBtZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IGRlZmluZXMgdGhlIHRwZSBvcyBhbiBJbnN0YW5jZUNhbGxiYWNrIGZ1bmN0aW9uXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICogQGNhdGVnb3J5IE1vZGVsXG4gKi9cbmV4cG9ydCB0eXBlIEluc3RhbmNlQ2FsbGJhY2sgPSAoaW5zdGFuY2U6IGFueSwgLi4uYXJnczogYW55W10pID0+IHZvaWQ7XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGNsYXNzIGFzIGEgTW9kZWwgY2xhc3NcbiAqIEBkZXNjcmlwdGlvblxuICpcbiAqIC0gUmVnaXN0ZXJzIHRoZSBjbGFzcyB1bmRlciB0aGUgbW9kZWwgcmVnaXN0cnkgc28gaXQgY2FuIGJlIGVhc2lseSByZWJ1aWx0O1xuICogLSBPdmVycmlkZXMgdGhlIGNsYXNzIGNvbnN0cnVjdG9yO1xuICogLSBSdW5zIHRoZSBnbG9iYWwge0BsaW5rIE1vZGVsQnVpbGRlckZ1bmN0aW9ufSBpZiBkZWZpbmVkO1xuICogLSBSdW5zIHRoZSBvcHRpb25hbCB7QGxpbmsgSW5zdGFuY2VDYWxsYmFja30gaWYgcHJvdmlkZWQ7XG4gKlxuICogQHBhcmFtIHtJbnN0YW5jZUNhbGxiYWNrfSBbaW5zdGFuY2VDYWxsYmFja10gb3B0aW9uYWwgY2FsbGJhY2sgdGhhdCB3aWxsIGJlIGNhbGxlZCB3aXRoIHRoZSBpbnN0YW5jZSB1cG9uIGluc3RhbnRpYXRpb24uIGRlZmF1bHRzIHRvIHVuZGVmaW5lZFxuICpcbiAqIEBmdW5jdGlvbiBtb2RlbFxuICpcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb2RlbChpbnN0YW5jZUNhbGxiYWNrPzogSW5zdGFuY2VDYWxsYmFjaykge1xuICBmdW5jdGlvbiBtb2RlbERlYyhvcmlnaW5hbDogYW55KSB7XG4gICAgLy8gdGhlIG5ldyBjb25zdHJ1Y3RvciBiZWhhdmlvdXJcbiAgICBjb25zdCBuZXdDb25zdHJ1Y3RvcjogYW55ID0gZnVuY3Rpb24gKC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgICBjb25zdCBpbnN0YW5jZTogUmV0dXJuVHlwZTx0eXBlb2Ygb3JpZ2luYWw+ID0gY29uc3RydWN0KFxuICAgICAgICBvcmlnaW5hbCxcbiAgICAgICAgLi4uYXJnc1xuICAgICAgKTtcbiAgICAgIGJpbmRNb2RlbFByb3RvdHlwZShpbnN0YW5jZSk7XG4gICAgICAvLyBydW4gYSBidWlsZGVyIGZ1bmN0aW9uIGlmIGRlZmluZWQgd2l0aCB0aGUgZmlyc3QgYXJndW1lbnQgKFRoZSBNb2RlbEFyZylcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBNb2RlbC5nZXRCdWlsZGVyKCk7XG4gICAgICBpZiAoYnVpbGRlcikgYnVpbGRlcihpbnN0YW5jZSwgYXJncy5sZW5ndGggPyBhcmdzWzBdIDogdW5kZWZpbmVkKTtcblxuICAgICAgbWV0YWRhdGEoTW9kZWwua2V5KE1vZGVsS2V5cy5NT0RFTCksIG9yaWdpbmFsLm5hbWUpKGluc3RhbmNlLmNvbnN0cnVjdG9yKTtcblxuICAgICAgaWYgKGluc3RhbmNlQ2FsbGJhY2spIGluc3RhbmNlQ2FsbGJhY2soaW5zdGFuY2UsIC4uLmFyZ3MpO1xuXG4gICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgfTtcblxuICAgIC8vIGNvcHkgcHJvdG90eXBlIHNvIGluc3RhbmNlb2Ygb3BlcmF0b3Igc3RpbGwgd29ya3NcbiAgICBuZXdDb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSBvcmlnaW5hbC5wcm90b3R5cGU7XG4gICAgLy8gU2V0cyB0aGUgcHJvcGVyIGNvbnN0cnVjdG9yIG5hbWUgZm9yIHR5cGUgdmVyaWZpY2F0aW9uXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5ld0NvbnN0cnVjdG9yLCBcIm5hbWVcIiwge1xuICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICB2YWx1ZTogb3JpZ2luYWwucHJvdG90eXBlLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgfSk7XG5cbiAgICBtZXRhZGF0YShNb2RlbC5rZXkoTW9kZWxLZXlzLk1PREVMKSwgb3JpZ2luYWwubmFtZSkob3JpZ2luYWwpO1xuXG4gICAgTW9kZWwucmVnaXN0ZXIobmV3Q29uc3RydWN0b3IsIG9yaWdpbmFsLm5hbWUpO1xuXG4gICAgLy8gcmV0dXJuIG5ldyBjb25zdHJ1Y3RvciAod2lsbCBvdmVycmlkZSBvcmlnaW5hbClcbiAgICByZXR1cm4gbmV3Q29uc3RydWN0b3I7XG4gIH1cbiAgLy8gcmV0dXJuIERlY29yYXRpb24uZm9yKGtleSkuZGVmaW5lKG1vZGVsRGVjKS5hcHBseSgpO1xuXG4gIHJldHVybiBtb2RlbERlYztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc2hlZEJ5KGFsZ29yaXRobTogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkge1xuICByZXR1cm4gbWV0YWRhdGEoTW9kZWwua2V5KE1vZGVsS2V5cy5IQVNISU5HKSwge1xuICAgIGFsZ29yaXRobTogYWxnb3JpdGhtLFxuICAgIGFyZ3M6IGFyZ3MsXG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2VyaWFsaXplZEJ5KHNlcmlhbGl6ZXI6IHN0cmluZywgLi4uYXJnczogYW55W10pIHtcbiAgcmV0dXJuIG1ldGFkYXRhKE1vZGVsLmtleShNb2RlbEtleXMuU0VSSUFMSVpBVElPTiksIHtcbiAgICBzZXJpYWxpemVyOiBzZXJpYWxpemVyLFxuICAgIGFyZ3M6IGFyZ3MsXG4gIH0pO1xufVxuIiwiLyoqXG4gKiBAbW9kdWxlIGRlY29yYXRvci12YWxpZGF0aW9uXG4gKiBAZGVzY3JpcHRpb24gVHlwZVNjcmlwdCBkZWNvcmF0b3ItYmFzZWQgdmFsaWRhdGlvbiBsaWJyYXJ5XG4gKiBAc3VtbWFyeSBUaGlzIG1vZHVsZSBwcm92aWRlcyBhIGNvbXByZWhlbnNpdmUgdmFsaWRhdGlvbiBmcmFtZXdvcmsgdXNpbmcgVHlwZVNjcmlwdCBkZWNvcmF0b3JzLlxuICogSXQgZXhwb3NlcyB1dGlsaXR5IGZ1bmN0aW9ucywgdmFsaWRhdGlvbiBkZWNvcmF0b3JzLCBhbmQgbW9kZWwtcmVsYXRlZCBmdW5jdGlvbmFsaXR5IGZvclxuICogaW1wbGVtZW50aW5nIHR5cGUtc2FmZSwgZGVjbGFyYXRpdmUgdmFsaWRhdGlvbiBpbiBUeXBlU2NyaXB0IGFwcGxpY2F0aW9ucy5cbiAqL1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3ZhbGlkYXRpb25cIjtcbmV4cG9ydCAqIGZyb20gXCIuL21vZGVsXCI7XG5cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gXCIjI1ZFUlNJT04jI1wiO1xuIl0sIm5hbWVzIjpbIk1vZGVsS2V5cyIsImFwcGx5IiwibWV0YWRhdGEiLCJQcmltaXRpdmVzIiwiUmVzZXJ2ZWRNb2RlbHMiLCJSZWZsZWN0aW9uIiwiaXNFcXVhbCIsIkRhdGVWYWxpZGF0b3IiLCJfX2RlY29yYXRlIiwiUGF0dGVyblZhbGlkYXRvciIsIkVtYWlsVmFsaWRhdG9yIiwiTGlzdFZhbGlkYXRvciIsIk1heExlbmd0aFZhbGlkYXRvciIsIk1heFZhbGlkYXRvciIsIk1pbkxlbmd0aFZhbGlkYXRvciIsIk1pblZhbGlkYXRvciIsIlBhc3N3b3JkVmFsaWRhdG9yIiwiUmVxdWlyZWRWYWxpZGF0b3IiLCJTdGVwVmFsaWRhdG9yIiwiVHlwZVZhbGlkYXRvciIsIlVSTFZhbGlkYXRvciJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0lBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQXFCRztBQUNTQTtJQUFaLENBQUEsVUFBWSxTQUFTLEVBQUE7SUFDbkIsSUFBQSxTQUFBLENBQUEsU0FBQSxDQUFBLEdBQUEsY0FBd0I7SUFDeEIsSUFBQSxTQUFBLENBQUEsTUFBQSxDQUFBLEdBQUEsYUFBb0I7SUFDcEIsSUFBQSxTQUFBLENBQUEsUUFBQSxDQUFBLEdBQUEsbUJBQTRCO0lBQzVCLElBQUEsU0FBQSxDQUFBLFFBQUEsQ0FBQSxHQUFBLG1CQUE0QjtJQUM1QixJQUFBLFNBQUEsQ0FBQSxPQUFBLENBQUEsR0FBQSxPQUFlO0lBQ2YsSUFBQSxTQUFBLENBQUEsUUFBQSxDQUFBLEdBQUEsU0FBa0I7SUFDbEIsSUFBQSxTQUFBLENBQUEsY0FBQSxDQUFBLEdBQUEsZ0JBQStCO0lBQy9CLElBQUEsU0FBQSxDQUFBLFdBQUEsQ0FBQSxHQUFBLGNBQTBCO0lBQzFCLElBQUEsU0FBQSxDQUFBLFNBQUEsQ0FBQSxHQUFBLFNBQW1CO0lBQ25CLElBQUEsU0FBQSxD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
|