@decaf-ts/decorator-validation 1.6.5 → 1.7.1

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.
Files changed (149) hide show
  1. package/dist/decorator-validation.cjs +1202 -386
  2. package/dist/decorator-validation.esm.cjs +1158 -341
  3. package/lib/constants/index.cjs +1 -1
  4. package/lib/esm/index.d.ts +5 -37
  5. package/lib/esm/index.js +6 -38
  6. package/lib/esm/model/Model.d.ts +107 -35
  7. package/lib/esm/model/Model.js +110 -45
  8. package/lib/esm/model/constants.d.ts +3 -3
  9. package/lib/esm/model/constants.js +4 -4
  10. package/lib/esm/model/construction.d.ts +3 -3
  11. package/lib/esm/model/construction.js +4 -4
  12. package/lib/esm/model/decorators.d.ts +3 -3
  13. package/lib/esm/model/decorators.js +5 -3
  14. package/lib/esm/model/index.d.ts +1 -0
  15. package/lib/esm/model/index.js +2 -1
  16. package/lib/esm/model/types.d.ts +30 -11
  17. package/lib/esm/model/types.js +1 -1
  18. package/lib/esm/model/utils.d.ts +3 -0
  19. package/lib/esm/model/utils.js +11 -0
  20. package/lib/esm/model/validation.d.ts +5 -5
  21. package/lib/esm/model/validation.js +8 -9
  22. package/lib/esm/utils/Decoration.d.ts +123 -0
  23. package/lib/esm/utils/Decoration.js +192 -0
  24. package/lib/esm/utils/constants.d.ts +27 -9
  25. package/lib/esm/utils/constants.js +28 -10
  26. package/lib/esm/utils/dates.d.ts +26 -16
  27. package/lib/esm/utils/dates.js +27 -17
  28. package/lib/esm/utils/decorators.d.ts +41 -0
  29. package/lib/esm/utils/decorators.js +42 -1
  30. package/lib/esm/utils/hashing.d.ts +50 -6
  31. package/lib/esm/utils/hashing.js +49 -5
  32. package/lib/esm/utils/index.d.ts +1 -0
  33. package/lib/esm/utils/index.js +2 -1
  34. package/lib/esm/utils/registry.d.ts +3 -3
  35. package/lib/esm/utils/registry.js +1 -1
  36. package/lib/esm/utils/serialization.d.ts +1 -1
  37. package/lib/esm/utils/serialization.js +4 -3
  38. package/lib/esm/utils/strings.d.ts +4 -4
  39. package/lib/esm/utils/strings.js +5 -5
  40. package/lib/esm/utils/types.d.ts +123 -16
  41. package/lib/esm/utils/types.js +1 -1
  42. package/lib/esm/validation/Validators/DateValidator.d.ts +40 -8
  43. package/lib/esm/validation/Validators/DateValidator.js +41 -9
  44. package/lib/esm/validation/Validators/EmailValidator.d.ts +39 -7
  45. package/lib/esm/validation/Validators/EmailValidator.js +40 -8
  46. package/lib/esm/validation/Validators/ListValidator.d.ts +44 -6
  47. package/lib/esm/validation/Validators/ListValidator.js +45 -7
  48. package/lib/esm/validation/Validators/MaxValidator.d.ts +52 -6
  49. package/lib/esm/validation/Validators/MaxValidator.js +53 -7
  50. package/lib/esm/validation/Validators/MinValidator.d.ts +52 -6
  51. package/lib/esm/validation/Validators/MinValidator.js +53 -7
  52. package/lib/esm/validation/Validators/PasswordValidator.js +1 -1
  53. package/lib/esm/validation/Validators/PatternValidator.d.ts +75 -9
  54. package/lib/esm/validation/Validators/PatternValidator.js +76 -10
  55. package/lib/esm/validation/Validators/RequiredValidator.d.ts +52 -6
  56. package/lib/esm/validation/Validators/RequiredValidator.js +53 -7
  57. package/lib/esm/validation/Validators/TypeValidator.d.ts +60 -6
  58. package/lib/esm/validation/Validators/TypeValidator.js +69 -7
  59. package/lib/esm/validation/Validators/URLValidator.d.ts +41 -7
  60. package/lib/esm/validation/Validators/URLValidator.js +42 -8
  61. package/lib/esm/validation/Validators/Validator.d.ts +76 -16
  62. package/lib/esm/validation/Validators/Validator.js +68 -11
  63. package/lib/esm/validation/Validators/ValidatorRegistry.d.ts +1 -7
  64. package/lib/esm/validation/Validators/ValidatorRegistry.js +4 -11
  65. package/lib/esm/validation/decorators.d.ts +50 -40
  66. package/lib/esm/validation/decorators.js +102 -53
  67. package/lib/esm/validation/types.d.ts +146 -28
  68. package/lib/esm/validation/types.js +1 -1
  69. package/lib/index.cjs +7 -39
  70. package/lib/index.d.ts +5 -37
  71. package/lib/model/Model.cjs +114 -51
  72. package/lib/model/Model.d.ts +107 -35
  73. package/lib/model/constants.cjs +4 -4
  74. package/lib/model/constants.d.ts +3 -3
  75. package/lib/model/construction.cjs +4 -4
  76. package/lib/model/construction.d.ts +3 -3
  77. package/lib/model/decorators.cjs +6 -4
  78. package/lib/model/decorators.d.ts +3 -3
  79. package/lib/model/index.cjs +2 -1
  80. package/lib/model/index.d.ts +1 -0
  81. package/lib/model/types.cjs +1 -1
  82. package/lib/model/types.d.ts +30 -11
  83. package/lib/model/utils.cjs +15 -0
  84. package/lib/model/utils.d.ts +3 -0
  85. package/lib/model/validation.cjs +11 -12
  86. package/lib/model/validation.d.ts +5 -5
  87. package/lib/utils/Decoration.cjs +196 -0
  88. package/lib/utils/Decoration.d.ts +123 -0
  89. package/lib/utils/constants.cjs +29 -11
  90. package/lib/utils/constants.d.ts +27 -9
  91. package/lib/utils/dates.cjs +28 -18
  92. package/lib/utils/dates.d.ts +26 -16
  93. package/lib/utils/decorators.cjs +42 -1
  94. package/lib/utils/decorators.d.ts +41 -0
  95. package/lib/utils/hashing.cjs +49 -5
  96. package/lib/utils/hashing.d.ts +50 -6
  97. package/lib/utils/index.cjs +2 -1
  98. package/lib/utils/index.d.ts +1 -0
  99. package/lib/utils/registry.cjs +1 -1
  100. package/lib/utils/registry.d.ts +3 -3
  101. package/lib/utils/serialization.cjs +5 -4
  102. package/lib/utils/serialization.d.ts +1 -1
  103. package/lib/utils/strings.cjs +5 -5
  104. package/lib/utils/strings.d.ts +4 -4
  105. package/lib/utils/types.cjs +1 -1
  106. package/lib/utils/types.d.ts +123 -16
  107. package/lib/validation/Validation.cjs +1 -1
  108. package/lib/validation/Validators/DateValidator.cjs +41 -9
  109. package/lib/validation/Validators/DateValidator.d.ts +40 -8
  110. package/lib/validation/Validators/DiffValidator.cjs +1 -1
  111. package/lib/validation/Validators/EmailValidator.cjs +40 -8
  112. package/lib/validation/Validators/EmailValidator.d.ts +39 -7
  113. package/lib/validation/Validators/EqualsValidator.cjs +1 -1
  114. package/lib/validation/Validators/GreaterThanOrEqualValidator.cjs +1 -1
  115. package/lib/validation/Validators/GreaterThanValidator.cjs +1 -1
  116. package/lib/validation/Validators/LessThanOrEqualValidator.cjs +1 -1
  117. package/lib/validation/Validators/LessThanValidator.cjs +1 -1
  118. package/lib/validation/Validators/ListValidator.cjs +45 -7
  119. package/lib/validation/Validators/ListValidator.d.ts +44 -6
  120. package/lib/validation/Validators/MaxLengthValidator.cjs +1 -1
  121. package/lib/validation/Validators/MaxValidator.cjs +53 -7
  122. package/lib/validation/Validators/MaxValidator.d.ts +52 -6
  123. package/lib/validation/Validators/MinLengthValidator.cjs +1 -1
  124. package/lib/validation/Validators/MinValidator.cjs +53 -7
  125. package/lib/validation/Validators/MinValidator.d.ts +52 -6
  126. package/lib/validation/Validators/PasswordValidator.cjs +1 -1
  127. package/lib/validation/Validators/PatternValidator.cjs +76 -10
  128. package/lib/validation/Validators/PatternValidator.d.ts +75 -9
  129. package/lib/validation/Validators/RequiredValidator.cjs +53 -7
  130. package/lib/validation/Validators/RequiredValidator.d.ts +52 -6
  131. package/lib/validation/Validators/StepValidator.cjs +1 -1
  132. package/lib/validation/Validators/TypeValidator.cjs +71 -9
  133. package/lib/validation/Validators/TypeValidator.d.ts +60 -6
  134. package/lib/validation/Validators/URLValidator.cjs +42 -8
  135. package/lib/validation/Validators/URLValidator.d.ts +41 -7
  136. package/lib/validation/Validators/Validator.cjs +69 -12
  137. package/lib/validation/Validators/Validator.d.ts +76 -16
  138. package/lib/validation/Validators/ValidatorRegistry.cjs +4 -12
  139. package/lib/validation/Validators/ValidatorRegistry.d.ts +1 -7
  140. package/lib/validation/Validators/constants.cjs +2 -2
  141. package/lib/validation/Validators/decorators.cjs +2 -2
  142. package/lib/validation/Validators/index.cjs +1 -1
  143. package/lib/validation/Validators/utils.cjs +3 -3
  144. package/lib/validation/decorators.cjs +105 -56
  145. package/lib/validation/decorators.d.ts +50 -40
  146. package/lib/validation/index.cjs +1 -1
  147. package/lib/validation/types.cjs +1 -1
  148. package/lib/validation/types.d.ts +146 -28
  149. package/package.json +2 -1
@@ -1,29 +1,27 @@
1
1
  import 'reflect-metadata';
2
2
  import { apply, metadata, Reflection, isEqual } from '@decaf-ts/reflection';
3
+ import { __decorate, __metadata } from 'tslib';
3
4
 
4
5
  /**
5
- * Symbol used to internally track the parent object during nested validation.
6
- *
7
- * This key is attached to child objects to provide context about their parent
8
- * in the object hierarchy, enabling validations that depend on parent values.
9
- *
10
- * @constant VALIDATION_PARENT_KEY
11
- * @memberOf module:decorator-validation.Model
12
- */
13
- const VALIDATION_PARENT_KEY = Symbol("_validationParentRef");
14
-
15
- /**
16
- * @summary Defines the various Model keys used for reflection
17
- *
18
- * @property {string} REFLECT prefix to all other keys
19
- * @property {string} TYPE type key
20
- * @property {string} PARAMS method params key
21
- * @property {string} RETURN method return key
22
- * @property {string} MODEL model key
23
- * @property {string} ANCHOR anchor key. will serve as a ghost property in the model
24
- *
25
- * @constant ModelKeys
26
- * @memberOf module:decorator-validation.Model
6
+ * @description Enum containing metadata keys used for reflection in the model system
7
+ * @summary Defines the various Model keys used for reflection and metadata storage.
8
+ * These keys are used throughout the library to store and retrieve metadata about models,
9
+ * their properties, and their behavior.
10
+ *
11
+ * @property {string} REFLECT - Prefix to all other keys, used as a namespace
12
+ * @property {string} TYPE - Key for storing design type information
13
+ * @property {string} PARAMS - Key for storing method parameter types
14
+ * @property {string} RETURN - Key for storing method return type
15
+ * @property {string} MODEL - Key for identifying model metadata
16
+ * @property {string} ANCHOR - Anchor key that serves as a ghost property in the model
17
+ * @property {string} CONSTRUCTION - Key for storing construction information
18
+ * @property {string} ATTRIBUTE - Key for storing attribute metadata
19
+ * @property {string} HASHING - Key for storing hashing configuration
20
+ * @property {string} SERIALIZATION - Key for storing serialization configuration
21
+ *
22
+ * @readonly
23
+ * @enum {string}
24
+ * @memberOf module:decorator-validation
27
25
  * @category Model
28
26
  */
29
27
  var ModelKeys;
@@ -39,6 +37,16 @@ var ModelKeys;
39
37
  ModelKeys["HASHING"] = "hashing";
40
38
  ModelKeys["SERIALIZATION"] = "serialization";
41
39
  })(ModelKeys || (ModelKeys = {}));
40
+ /**
41
+ * @description Default flavour identifier for the decorator system
42
+ * @summary Defines the default flavour used by the Decoration class when no specific flavour is provided.
43
+ * This constant is used throughout the library as the fallback flavour for decorators.
44
+ *
45
+ * @const {string}
46
+ * @memberOf module:decorator-validation
47
+ * @category Model
48
+ */
49
+ const DefaultFlavour = "decaf";
42
50
 
43
51
  /**
44
52
  * @summary Keys used for comparison-based validations.
@@ -225,8 +233,8 @@ const DEFAULT_PATTERNS = {
225
233
  * @return {string} formatted string
226
234
  *
227
235
  * @function stringFormat
228
- * @memberOf module:decorator-validation.Utils.Format
229
- * @category Format
236
+ * @memberOf module:decorator-validation
237
+ * @category Model
230
238
  */
231
239
  function stringFormat(string, ...args) {
232
240
  return string.replace(/{(\d+)}/g, function (match, number) {
@@ -244,8 +252,8 @@ function stringFormat(string, ...args) {
244
252
  * @return {string} formatted string
245
253
  *
246
254
  * @function sf
247
- * @memberOf module:decorator-validation.Utils.Format
248
- * @category Format
255
+ * @memberOf module:decorator-validation
256
+ * @category Model
249
257
  */
250
258
  const sf = stringFormat;
251
259
 
@@ -257,8 +265,8 @@ const sf = stringFormat;
257
265
  * @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?)
258
266
  *
259
267
  * @function dateFromFormat
260
- * @memberOf module:decorator-validation.Utils.Dates
261
- * @category Format
268
+ * @memberOf module:decorator-validation
269
+ * @category Model
262
270
  */
263
271
  function dateFromFormat(date, format) {
264
272
  let formatRegexp = format;
@@ -345,11 +353,16 @@ function dateFromFormat(date, format) {
345
353
  return new Date(year, month - 1, day, hour, minutes, seconds, ms);
346
354
  }
347
355
  /**
348
- * @summary Binds a date format to a string
349
- * @param {Date} [date]
350
- * @param {string} [format]
351
- * @memberOf module:decorator-validation.Utils.Format
352
- * @category Utilities
356
+ * @description Binds a specific date format to a Date object's toString and toISOString methods
357
+ * @summary Modifies a Date object to return a formatted string when toString or toISOString is called.
358
+ * This function overrides the default toString and toISOString methods of the Date object to return
359
+ * the date formatted according to the specified format string.
360
+ * @param {Date} [date] The Date object to modify
361
+ * @param {string} [format] The format string to use for formatting the date
362
+ * @return {Date|undefined} The modified Date object or undefined if no date was provided
363
+ * @function bindDateToString
364
+ * @memberOf module:decorator-validation
365
+ * @category Model
353
366
  */
354
367
  function bindDateToString(date, format) {
355
368
  if (!date)
@@ -369,9 +382,14 @@ function bindDateToString(date, format) {
369
382
  return date;
370
383
  }
371
384
  /**
372
- * @summary Helper function to be used instead of instanceOf Date
373
- * @param date
374
- * @memberOf module:decorator-validation.Utils.Dates
385
+ * @description Safely checks if a value is a valid Date object
386
+ * @summary A utility function that determines if a value is a valid Date object.
387
+ * This function is more reliable than using instanceof Date as it also checks
388
+ * that the date is not NaN, which can happen with invalid date strings.
389
+ * @param {any} date The value to check
390
+ * @return {boolean} True if the value is a valid Date object, false otherwise
391
+ * @function isValidDate
392
+ * @memberOf module:decorator-validation
375
393
  * @category Validation
376
394
  */
377
395
  function isValidDate(date) {
@@ -386,8 +404,8 @@ function isValidDate(date) {
386
404
  * @return {string}
387
405
  *
388
406
  * @function twoDigitPad
389
- * @memberOf module:decorator-validation.Utils.Format
390
- * @category Format
407
+ * @memberOf module:decorator-validation
408
+ * @category Model
391
409
  */
392
410
  function twoDigitPad(num) {
393
411
  return num < 10 ? "0" + num : num.toString();
@@ -417,8 +435,8 @@ function twoDigitPad(num) {
417
435
  * @return {string} the formatted date
418
436
  *
419
437
  * @function formatDate
420
- * @memberOf module:decorator-validation.Utils.Dates
421
- * @category Format
438
+ * @memberOf module:decorator-validation
439
+ * @category Model
422
440
  */
423
441
  function formatDate(date, patternStr = "yyyy/MM/dd") {
424
442
  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);
@@ -452,8 +470,8 @@ function formatDate(date, patternStr = "yyyy/MM/dd") {
452
470
  * @summary Parses a date from a specified format
453
471
  * @param {string} format
454
472
  * @param {string | Date | number} [v]
455
- * @memberOf module:decorator-validation.Utils.Dates
456
- * @category Format
473
+ * @memberOf module:decorator-validation
474
+ * @category Model
457
475
  */
458
476
  function parseDate(format, v) {
459
477
  let value = undefined;
@@ -490,6 +508,225 @@ function parseDate(format, v) {
490
508
  return bindDateToString(value, format);
491
509
  }
492
510
 
511
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
512
+ function defaultFlavourResolver(target) {
513
+ return DefaultFlavour;
514
+ }
515
+ /**
516
+ * @description A decorator management class that handles flavoured decorators
517
+ * @summary The Decoration class provides a builder pattern for creating and managing decorators with different flavours.
518
+ * It supports registering, extending, and applying decorators with context-aware flavour resolution.
519
+ * The class implements a fluent interface for defining, extending, and applying decorators with different flavours,
520
+ * allowing for framework-specific decorator implementations while maintaining a consistent API.
521
+ * @template T Type of the decorator (ClassDecorator | PropertyDecorator | MethodDecorator)
522
+ * @param {string} [flavour] Optional flavour parameter for the decorator context
523
+ * @class
524
+ * @category Model
525
+ * @example
526
+ * ```typescript
527
+ * // Create a new decoration for 'component' with default flavour
528
+ * const componentDecorator = new Decoration()
529
+ * .for('component')
530
+ * .define(customComponentDecorator);
531
+ *
532
+ * // Create a flavoured decoration
533
+ * const vueComponent = new Decoration('vue')
534
+ * .for('component')
535
+ * .define(vueComponentDecorator);
536
+ *
537
+ * // Apply the decoration
538
+ * @componentDecorator
539
+ * class MyComponent {}
540
+ * ```
541
+ * @mermaid
542
+ * sequenceDiagram
543
+ * participant C as Client
544
+ * participant D as Decoration
545
+ * participant R as FlavourResolver
546
+ * participant F as DecoratorFactory
547
+ *
548
+ * C->>D: new Decoration(flavour)
549
+ * C->>D: for(key)
550
+ * C->>D: define(decorators)
551
+ * D->>D: register(key, flavour, decorators)
552
+ * D->>F: decoratorFactory(key, flavour)
553
+ * F->>R: resolve(target)
554
+ * R-->>F: resolved flavour
555
+ * F->>F: apply decorators
556
+ * F-->>C: decorated target
557
+ */
558
+ class Decoration {
559
+ /**
560
+ * @description Static map of registered decorators
561
+ * @summary Stores all registered decorators organized by key and flavour
562
+ */
563
+ static { this.decorators = {}; }
564
+ /**
565
+ * @description Function to resolve flavour from a target
566
+ * @summary Resolver function that determines the appropriate flavour for a given target
567
+ */
568
+ static { this.flavourResolver = defaultFlavourResolver; }
569
+ constructor(flavour = DefaultFlavour) {
570
+ this.flavour = flavour;
571
+ }
572
+ /**
573
+ * @description Sets the key for the decoration builder
574
+ * @summary Initializes a new decoration chain with the specified key
575
+ * @param {string} key The identifier for the decorator
576
+ * @return {DecorationBuilderMid} Builder instance for method chaining
577
+ */
578
+ for(key) {
579
+ this.key = key;
580
+ return this;
581
+ }
582
+ /**
583
+ * @description Adds decorators to the current context
584
+ * @summary Internal method to add decorators with addon support
585
+ * @param {boolean} [addon=false] Whether the decorators are addons
586
+ * @param decorators Array of decorators
587
+ * @return {this} Current instance for chaining
588
+ */
589
+ decorate(addon = false, ...decorators) {
590
+ if (!this.key)
591
+ throw new Error("key must be provided before decorators can be added");
592
+ if ((!decorators || !decorators.length) &&
593
+ !addon &&
594
+ this.flavour !== DefaultFlavour)
595
+ throw new Error("Must provide overrides or addons to override or extend decaf's decorators");
596
+ if (this.flavour === DefaultFlavour && addon)
597
+ throw new Error("Default flavour cannot be extended");
598
+ this[addon ? "extras" : "decorators"] = new Set([
599
+ ...(this[addon ? "extras" : "decorators"] || new Set()).values(),
600
+ ...decorators,
601
+ ]);
602
+ return this;
603
+ }
604
+ /**
605
+ * @description Defines the base decorators
606
+ * @summary Sets the primary decorators for the current context
607
+ * @param decorators Decorators to define
608
+ * @return Builder instance for finishing the chain
609
+ */
610
+ define(...decorators) {
611
+ return this.decorate(false, ...decorators);
612
+ }
613
+ /**
614
+ * @description Extends existing decorators
615
+ * @summary Adds additional decorators to the current context
616
+ * @param decorators Additional decorators
617
+ * @return {DecorationBuilderBuild} Builder instance for building the decorator
618
+ */
619
+ extend(...decorators) {
620
+ return this.decorate(true, ...decorators);
621
+ }
622
+ decoratorFactory(key, f = DefaultFlavour) {
623
+ const contextDecorator = function contextDecorator(target, propertyKey, descriptor) {
624
+ const flavour = Decoration.flavourResolver(target);
625
+ let decorators;
626
+ const extras = Decoration.decorators[key][flavour]
627
+ ? Decoration.decorators[key][flavour].extras
628
+ : Decoration.decorators[key][DefaultFlavour].extras;
629
+ if (Decoration.decorators[key] &&
630
+ Decoration.decorators[key][flavour] &&
631
+ Decoration.decorators[key][flavour].decorators) {
632
+ decorators = Decoration.decorators[key][flavour].decorators;
633
+ }
634
+ else {
635
+ decorators = Decoration.decorators[key][DefaultFlavour].decorators;
636
+ }
637
+ [
638
+ ...(decorators ? decorators.values() : []),
639
+ ...(extras ? extras.values() : []),
640
+ ].forEach((d) => d(target, propertyKey, descriptor, descriptor));
641
+ // return apply(
642
+ //
643
+ // )(target, propertyKey, descriptor);
644
+ };
645
+ Object.defineProperty(contextDecorator, "name", {
646
+ value: [f, key].join("_decorator_for_"),
647
+ writable: false,
648
+ });
649
+ return contextDecorator;
650
+ }
651
+ /**
652
+ * @description Creates the final decorator function
653
+ * @summary Builds and returns the decorator factory function
654
+ * @return {function(any, any?, TypedPropertyDescriptor?): any} The generated decorator function
655
+ */
656
+ apply() {
657
+ if (!this.key)
658
+ throw new Error("No key provided for the decoration builder");
659
+ Decoration.register(this.key, this.flavour, this.decorators, this.extras);
660
+ return this.decoratorFactory(this.key, this.flavour);
661
+ }
662
+ /**
663
+ * @description Registers decorators for a specific key and flavour
664
+ * @summary Internal method to store decorators in the static registry
665
+ * @param {string} key Decorator key
666
+ * @param {string} flavour Decorator flavour
667
+ * @param [decorators] Primary decorators
668
+ * @param [extras] Additional decorators
669
+ */
670
+ static register(key, flavour, decorators, extras) {
671
+ if (!key)
672
+ throw new Error("No key provided for the decoration builder");
673
+ if (!decorators)
674
+ throw new Error("No decorators provided for the decoration builder");
675
+ if (!flavour)
676
+ throw new Error("No flavour provided for the decoration builder");
677
+ if (!Decoration.decorators[key])
678
+ Decoration.decorators[key] = {};
679
+ if (!Decoration.decorators[key][flavour])
680
+ Decoration.decorators[key][flavour] = {};
681
+ if (decorators)
682
+ Decoration.decorators[key][flavour].decorators = decorators;
683
+ if (extras)
684
+ Decoration.decorators[key][flavour].extras = extras;
685
+ }
686
+ /**
687
+ * @description Sets the global flavour resolver
688
+ * @summary Configures the function used to determine decorator flavours
689
+ * @param {FlavourResolver} resolver Function to resolve flavours
690
+ */
691
+ static setFlavourResolver(resolver) {
692
+ Decoration.flavourResolver = resolver;
693
+ }
694
+ static for(key) {
695
+ return new Decoration().for(key);
696
+ }
697
+ static flavouredAs(flavour) {
698
+ return new Decoration(flavour);
699
+ }
700
+ }
701
+
702
+ /**
703
+ * @description Property decorator factory for model attributes
704
+ * @summary Creates a decorator that marks class properties as model attributes. The decorator maintains a list
705
+ * of property keys under a specified metadata key in the model. If the key doesn't exist, it creates a new array;
706
+ * if it exists, it appends the property key to the existing array, avoiding duplicates.
707
+ *
708
+ * @param {string} [key=ModelKeys.ATTRIBUTE] - The metadata key under which to store the property name
709
+ * @return {function(object, any?): void} Decorator function that registers the property
710
+ *
711
+ * @function prop
712
+ * @category Decorators
713
+ *
714
+ * @mermaid
715
+ * sequenceDiagram
716
+ * participant D as Decorator
717
+ * participant M as Model
718
+ *
719
+ * D->>M: Check if key exists
720
+ * alt key exists
721
+ * M-->>D: Return existing props array
722
+ * else key doesn't exist
723
+ * D->>M: Create new props array
724
+ * end
725
+ * D->>M: Check if property exists
726
+ * alt property not in array
727
+ * D->>M: Add property to array
728
+ * end
729
+ */
493
730
  function prop(key = ModelKeys.ATTRIBUTE) {
494
731
  return (model, propertyKey) => {
495
732
  let props;
@@ -503,6 +740,19 @@ function prop(key = ModelKeys.ATTRIBUTE) {
503
740
  props.push(propertyKey);
504
741
  };
505
742
  }
743
+ /**
744
+ * @description Combined property decorator factory for metadata and attribute marking
745
+ * @summary Creates a decorator that both marks a property as a model attribute and assigns metadata to it.
746
+ * Combines the functionality of prop() and metadata() decorators.
747
+ *
748
+ * @template V - The type of the metadata value
749
+ * @param {string} key - The metadata key
750
+ * @param {V} value - The metadata value to associate with the property
751
+ * @return {Function} Combined decorator function
752
+ *
753
+ * @function propMetadata
754
+ * @category Decorators
755
+ */
506
756
  function propMetadata(key, value) {
507
757
  return apply(prop(), metadata(key, value));
508
758
  }
@@ -514,8 +764,8 @@ function propMetadata(key, value) {
514
764
  * @return {number} hash value of obj
515
765
  *
516
766
  * @function hashCode
517
- * @memberOf module:decorator-validation.Utils.Hashing
518
- * @category Hashing
767
+ * @memberOf module:decorator-validation
768
+ * @category Model
519
769
  */
520
770
  function hashCode(obj) {
521
771
  obj = String(obj);
@@ -534,8 +784,8 @@ function hashCode(obj) {
534
784
  * @return {string} the resulting hash
535
785
  *
536
786
  * @function hashObj
537
- * @memberOf module:decorator-validation.Utils.Hashing
538
- * @category Hashing
787
+ * @memberOf module:decorator-validation
788
+ * @category Model
539
789
  */
540
790
  function hashObj(obj) {
541
791
  const hashReducer = function (h, el) {
@@ -562,17 +812,61 @@ function hashObj(obj) {
562
812
  return (typeof result === "number" ? Math.abs(result) : result).toString();
563
813
  }
564
814
  const DefaultHashingMethod = "default";
815
+ /**
816
+ * @description Manages hashing methods and provides a unified hashing interface
817
+ * @summary A utility class that provides a registry for different hashing functions and methods to hash objects.
818
+ * The class maintains a cache of registered hashing functions and allows setting a default hashing method.
819
+ * It prevents direct instantiation and provides static methods for registration and hashing.
820
+ *
821
+ * @class Hashing
822
+ * @category Model
823
+ *
824
+ * @example
825
+ * ```typescript
826
+ * // Register a custom hashing function
827
+ * Hashing.register('md5', (obj) => createMD5Hash(obj), true);
828
+ *
829
+ * // Hash an object using default method
830
+ * const hash1 = Hashing.hash(myObject);
831
+ *
832
+ * // Hash using specific method
833
+ * const hash2 = Hashing.hash(myObject, 'md5');
834
+ * ```
835
+ */
565
836
  class Hashing {
837
+ /**
838
+ * @description Current default hashing method identifier
839
+ * @private
840
+ */
566
841
  static { this.current = DefaultHashingMethod; }
842
+ /**
843
+ * @description Cache of registered hashing functions
844
+ * @private
845
+ */
567
846
  static { this.cache = {
568
847
  default: hashObj,
569
848
  }; }
570
849
  constructor() { }
850
+ /**
851
+ * @description Retrieves a registered hashing function
852
+ * @summary Fetches a hashing function from the cache by its key. Throws an error if the method is not registered.
853
+ *
854
+ * @param {string} key - The identifier of the hashing function to retrieve
855
+ * @return {HashingFunction} The requested hashing function
856
+ * @private
857
+ */
571
858
  static get(key) {
572
859
  if (key in this.cache)
573
860
  return this.cache[key];
574
861
  throw new Error(`No hashing method registered under ${key}`);
575
862
  }
863
+ /**
864
+ * @description Registers a new hashing function
865
+ * @summary Adds a new hashing function to the registry. Optionally sets it as the default method.
866
+ * Throws an error if a method with the same key is already registered.
867
+ *
868
+ * @param {string} key - The identifier for the hashing function
869
+ */
576
870
  static register(key, func, setDefault = false) {
577
871
  if (key in this.cache)
578
872
  throw new Error(`Hashing method ${key} already registered`);
@@ -652,7 +946,7 @@ class ModelErrorDefinition {
652
946
  * @property {string} BIGINT references the bigint primitive
653
947
  *
654
948
  * @constant Primitives
655
- * @memberOf module:decorator-validation.Model
949
+ * @memberOf module:decorator-validation
656
950
  */
657
951
  var Primitives;
658
952
  (function (Primitives) {
@@ -672,7 +966,7 @@ var Primitives;
672
966
  * @property {string} DATE
673
967
  *
674
968
  * @constant ReservedModels
675
- * @memberOf module:decorator-validation.Model
969
+ * @memberOf module:decorator-validation
676
970
  */
677
971
  var ReservedModels;
678
972
  (function (ReservedModels) {
@@ -698,7 +992,7 @@ var ReservedModels;
698
992
  * @property {string} BIGINT
699
993
  *
700
994
  * @constant jsTypes
701
- * @memberOf module:decorator-validation.Model
995
+ * @memberOf module:decorator-validation
702
996
  */
703
997
  const jsTypes = [
704
998
  "string",
@@ -714,13 +1008,118 @@ const jsTypes = [
714
1008
  ];
715
1009
 
716
1010
  /**
717
- * @summary Duck typing for Validators
718
- * @function isValidator
719
- * @param val
1011
+ * Symbol used to internally track the parent object during nested validation.
1012
+ *
1013
+ * This key is attached to child objects to provide context about their parent
1014
+ * in the object hierarchy, enabling validations that depend on parent values.
1015
+ *
1016
+ * @constant VALIDATION_PARENT_KEY
1017
+ * @memberOf module:decorator-validation.Model
720
1018
  */
721
- function isValidator(val) {
722
- return val.constructor && val["hasErrors"];
1019
+ const VALIDATION_PARENT_KEY = Symbol("_validationParentRef");
1020
+
1021
+ /**
1022
+ * @description Abstract base class for all validators in the validation framework
1023
+ * @summary The Validator class provides the foundation for all validator implementations.
1024
+ * It handles type checking, error message formatting, and defines the common interface
1025
+ * that all validators must implement. This class is designed to be extended by specific
1026
+ * validator implementations that provide concrete validation logic.
1027
+ *
1028
+ * @param {string} message - Default error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#DEFAULT}
1029
+ * @param {string[]} acceptedTypes - Array of type names that this validator can validate
1030
+ *
1031
+ * @class Validator
1032
+ * @abstract
1033
+ *
1034
+ * @example
1035
+ * ```typescript
1036
+ * // Example of extending the Validator class to create a custom validator
1037
+ * class CustomValidator extends Validator<CustomValidatorOptions> {
1038
+ * constructor(message: string = "Custom validation failed") {
1039
+ * // Specify that this validator accepts String and Number types
1040
+ * super(message, String.name, Number.name);
1041
+ * }
1042
+ *
1043
+ * public hasErrors(value: any, options?: CustomValidatorOptions): string | undefined {
1044
+ * // Implement custom validation logic
1045
+ * if (someCondition) {
1046
+ * return this.getMessage(options?.message || this.message);
1047
+ * }
1048
+ * return undefined; // No errors
1049
+ * }
1050
+ * }
1051
+ * ```
1052
+ *
1053
+ * @mermaid
1054
+ * sequenceDiagram
1055
+ * participant C as Client
1056
+ * participant V as Validator Subclass
1057
+ * participant B as Base Validator
1058
+ *
1059
+ * C->>V: new CustomValidator(message)
1060
+ * V->>B: super(message, acceptedTypes)
1061
+ * B->>B: Store message and types
1062
+ * B->>B: Wrap hasErrors with type checking
1063
+ * C->>V: hasErrors(value, options)
1064
+ * alt value type not in acceptedTypes
1065
+ * B-->>C: Type error message
1066
+ * else value type is accepted
1067
+ * V->>V: Custom validation logic
1068
+ * V-->>C: Validation result
1069
+ * end
1070
+ *
1071
+ * @category Validators
1072
+ */
1073
+ class Validator {
1074
+ constructor(message = DEFAULT_ERROR_MESSAGES.DEFAULT, ...acceptedTypes) {
1075
+ this.message = message;
1076
+ if (acceptedTypes.length)
1077
+ this.acceptedTypes = acceptedTypes;
1078
+ if (this.acceptedTypes)
1079
+ this.hasErrors = this.checkTypeAndHasErrors(this.hasErrors.bind(this));
1080
+ }
1081
+ /**
1082
+ * @description Formats an error message with optional arguments
1083
+ * @summary Creates a formatted error message by replacing placeholders with provided arguments.
1084
+ * This method uses the string formatting utility to generate consistent error messages
1085
+ * across all validators.
1086
+ *
1087
+ * @param {string} message - The message template with placeholders
1088
+ * @param {...any} args - Values to insert into the message template
1089
+ * @return {string} The formatted error message
1090
+ * @protected
1091
+ */
1092
+ getMessage(message, ...args) {
1093
+ return sf(message, ...args);
1094
+ }
1095
+ /**
1096
+ * @description Creates a type-checking wrapper around the hasErrors method
1097
+ * @summary Wraps the hasErrors method with type validation logic to ensure that
1098
+ * the value being validated is of an accepted type before performing specific validation.
1099
+ * This method is called during construction if acceptedTypes are provided.
1100
+ *
1101
+ * @param {Function} unbound - The original hasErrors method to be wrapped
1102
+ * @return {Function} A new function that performs type checking before calling the original method
1103
+ * @private
1104
+ */
1105
+ checkTypeAndHasErrors(unbound) {
1106
+ return function (value, ...args) {
1107
+ if (value === undefined || !this.acceptedTypes)
1108
+ return unbound(value, ...args);
1109
+ if (!Reflection.checkTypes(value, this.acceptedTypes))
1110
+ return this.getMessage(DEFAULT_ERROR_MESSAGES.TYPE, this.acceptedTypes.join(", "), typeof value);
1111
+ return unbound(value, ...args);
1112
+ }.bind(this);
1113
+ }
1114
+ /**
1115
+ * @summary Duck typing for Validators
1116
+ * @param val
1117
+ */
1118
+ static isValidator(val) {
1119
+ return val.constructor && !!val["hasErrors"];
1120
+ }
723
1121
  }
1122
+
724
1123
  /**
725
1124
  * @summary Base Implementation of a Validator Registry
726
1125
  *
@@ -759,7 +1158,7 @@ class ValidatorRegistry {
759
1158
  if (!(validatorKey in this.cache))
760
1159
  return undefined;
761
1160
  const classOrInstance = this.cache[validatorKey];
762
- if (isValidator(classOrInstance))
1161
+ if (Validator.isValidator(classOrInstance))
763
1162
  return classOrInstance;
764
1163
  const constructor = classOrInstance.default || classOrInstance;
765
1164
  const instance = new constructor();
@@ -773,7 +1172,7 @@ class ValidatorRegistry {
773
1172
  */
774
1173
  register(...validator) {
775
1174
  validator.forEach((v) => {
776
- if (isValidator(v)) {
1175
+ if (Validator.isValidator(v)) {
777
1176
  // const k =
778
1177
  if (v.validationKey in this.cache)
779
1178
  return;
@@ -867,13 +1266,13 @@ class Validation {
867
1266
  /**
868
1267
  * @summary Analyses the decorations of the properties and validates the obj according to them
869
1268
  *
870
- * @typedef T extends Model
871
- * @prop {T} obj Model object to validate
1269
+ * @typedef M extends Model
1270
+ * @prop {M} obj Model object to validate
872
1271
  * @prop {string[]} [propsToIgnore] object properties to ignore in the validation
873
1272
  *
874
1273
  * @function validate
875
- * @memberOf module:decorator-validation.Validation
876
- * @category Validation
1274
+ * @memberOf module:decorator-validation
1275
+ * @category Model
877
1276
  */
878
1277
  function validate(obj, ...propsToIgnore) {
879
1278
  const decoratedProperties = [];
@@ -953,7 +1352,7 @@ function validate(obj, ...propsToIgnore) {
953
1352
  try {
954
1353
  if (value && !value[VALIDATION_PARENT_KEY])
955
1354
  value[VALIDATION_PARENT_KEY] = obj; // TODO: freeze?
956
- return isModel(value)
1355
+ return Model.isModel(value)
957
1356
  ? value.hasErrors()
958
1357
  : allowedTypes.includes(typeof value)
959
1358
  ? undefined
@@ -989,7 +1388,7 @@ function validate(obj, ...propsToIgnore) {
989
1388
  err = validate(prop, obj[prop]);
990
1389
  }
991
1390
  catch (e) {
992
- console.warn(sf("Model should be validatable but its not: " + e));
1391
+ console.warn(`Model should be validatable but its not: ${e}`);
993
1392
  }
994
1393
  }
995
1394
  }
@@ -1002,51 +1401,80 @@ function validate(obj, ...propsToIgnore) {
1002
1401
  return result ? new ModelErrorDefinition(result) : undefined;
1003
1402
  }
1004
1403
 
1005
- let modelBuilderFunction;
1006
- let actingModelRegistry;
1007
- function isPropertyModel(target, attribute) {
1008
- if (isModel(target[attribute]))
1009
- return true;
1010
- const metadata = Reflect.getMetadata(ModelKeys.TYPE, target, attribute);
1011
- return Model.get(metadata.name) ? metadata.name : undefined;
1404
+ function getModelKey(str) {
1405
+ return ModelKeys.REFLECT + str;
1012
1406
  }
1013
- /**
1014
- * @summary For Serialization/deserialization purposes.
1015
- * @description Reads the {@link ModelKeys.ANCHOR} property of a {@link Model} to discover the class to instantiate
1016
- *
1017
- * @function isModel
1018
- * @memberOf module:decorator-validation.Validation
1019
- * @category Validation
1020
- */
1021
- function isModel(target) {
1022
- try {
1023
- return target instanceof Model || !!Model.getMetadata(target);
1024
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1025
- }
1026
- catch (e) {
1027
- return false;
1028
- }
1407
+ function getMetadata(model) {
1408
+ const metadata = Reflect.getMetadata(getModelKey(ModelKeys.MODEL), model.constructor);
1409
+ if (!metadata)
1410
+ throw new Error("could not find metadata for provided " + model.constructor.name);
1411
+ return metadata;
1029
1412
  }
1413
+
1414
+ let modelBuilderFunction;
1415
+ let actingModelRegistry;
1030
1416
  /**
1031
- * @summary Util class to enable serialization and correct rebuilding
1417
+ * @description Registry manager for model constructors that enables serialization and rebuilding
1418
+ * @summary The ModelRegistryManager implements the ModelRegistry interface and provides
1419
+ * functionality for registering, retrieving, and building model instances. It maintains
1420
+ * a cache of model constructors indexed by name, allowing for efficient lookup and instantiation.
1421
+ * This class is essential for the serialization and deserialization of model objects.
1032
1422
  *
1033
- * @param {string} anchorKey defaults to {@link ModelKeys.ANCHOR}. The property name where the registered class name is stored;
1034
- * @param {function(Record<string, any>): boolean} [testFunction] method to test if the provided object is a Model Object. defaults to {@link isModel}
1423
+ * @param {function(Record<string, any>): boolean} [testFunction] - Function to test if an object is a model, defaults to {@link Model#isModel}
1035
1424
  *
1036
1425
  * @class ModelRegistryManager
1037
- * @implements ModelRegistry
1038
- *
1426
+ * @template M Type of model that can be registered, must extend Model
1427
+ * @implements ModelRegistry<M>
1039
1428
  * @category Model
1429
+ *
1430
+ * @example
1431
+ * ```typescript
1432
+ * // Create a model registry
1433
+ * const registry = new ModelRegistryManager();
1434
+ *
1435
+ * // Register a model class
1436
+ * registry.register(User);
1437
+ *
1438
+ * // Retrieve a model constructor by name
1439
+ * const UserClass = registry.get("User");
1440
+ *
1441
+ * // Build a model instance from a plain object
1442
+ * const userData = { name: "John", age: 30 };
1443
+ * const user = registry.build(userData, "User");
1444
+ * ```
1445
+ *
1446
+ * @mermaid
1447
+ * sequenceDiagram
1448
+ * participant C as Client
1449
+ * participant R as ModelRegistryManager
1450
+ * participant M as Model Class
1451
+ *
1452
+ * C->>R: new ModelRegistryManager(testFunction)
1453
+ * C->>R: register(ModelClass)
1454
+ * R->>R: Store in cache
1455
+ * C->>R: get("ModelName")
1456
+ * R-->>C: ModelClass constructor
1457
+ * C->>R: build(data, "ModelName")
1458
+ * R->>R: Get constructor from cache
1459
+ * R->>M: new ModelClass(data)
1460
+ * M-->>R: Model instance
1461
+ * R-->>C: Model instance
1040
1462
  */
1041
1463
  class ModelRegistryManager {
1042
- constructor(testFunction = isModel) {
1464
+ constructor(testFunction = Model.isModel) {
1043
1465
  this.cache = {};
1044
1466
  this.testFunction = testFunction;
1045
1467
  }
1046
1468
  /**
1047
- * @summary register new Models
1048
- * @param {any} constructor
1049
- * @param {string} [name] when not defined, the name of the constructor will be used
1469
+ * @description Registers a model constructor with the registry
1470
+ * @summary Adds a model constructor to the registry cache, making it available for
1471
+ * later retrieval and instantiation. If no name is provided, the constructor's name
1472
+ * property is used as the key in the registry.
1473
+ *
1474
+ * @param {ModelConstructor<M>} constructor - The model constructor to register
1475
+ * @param {string} [name] - Optional name to register the constructor under, defaults to constructor.name
1476
+ * @return {void}
1477
+ * @throws {Error} If the constructor is not a function
1050
1478
  */
1051
1479
  register(constructor, name) {
1052
1480
  if (typeof constructor !== "function")
@@ -1078,7 +1506,7 @@ class ModelRegistryManager {
1078
1506
  throw new Error("Provided obj is not a Model object");
1079
1507
  const name = clazz || Model.getMetadata(obj);
1080
1508
  if (!(name in this.cache))
1081
- throw new Error(sf("Provided class {0} is not a registered Model object", name));
1509
+ throw new Error(`Provided class ${name} is not a registered Model object`);
1082
1510
  return new this.cache[name](obj);
1083
1511
  }
1084
1512
  }
@@ -1086,9 +1514,10 @@ class ModelRegistryManager {
1086
1514
  * @summary Bulk Registers Models
1087
1515
  * @description Useful when using bundlers that might not evaluate all the code at once
1088
1516
  *
1089
- * @param {Array<Constructor<T>> | Array<{name: string, constructor: Constructor<T>}>} [models]
1517
+ * @template M extends Model
1518
+ * @param {Array<Constructor<M>> | Array<{name: string, constructor: Constructor<M>}>} [models]
1090
1519
  *
1091
- * @memberOf module:decorator-validation.Model
1520
+ * @memberOf module:decorator-validation
1092
1521
  * @category Model
1093
1522
  */
1094
1523
  function bulkModelRegister(...models) {
@@ -1105,9 +1534,10 @@ function bulkModelRegister(...models) {
1105
1534
  * - Have all their required properties marked with '!';
1106
1535
  * - Have all their optional properties marked as '?':
1107
1536
  *
1108
- * @param {Model | {}} model base object from which to populate properties from
1537
+ * @param {ModelArg<Model>} model base object from which to populate properties from
1109
1538
  *
1110
1539
  * @class Model
1540
+ * @category Model
1111
1541
  * @abstract
1112
1542
  * @implements Validatable
1113
1543
  * @implements Serializable
@@ -1206,7 +1636,7 @@ class Model {
1206
1636
  obj[prop] ?? undefined;
1207
1637
  if (typeof self[prop] !== "object")
1208
1638
  continue;
1209
- const propM = isPropertyModel(self, prop);
1639
+ const propM = Model.isPropertyModel(self, prop);
1210
1640
  if (propM) {
1211
1641
  try {
1212
1642
  self[prop] = Model.build(self[prop], typeof propM === "string" ? propM : undefined);
@@ -1219,7 +1649,7 @@ class Model {
1219
1649
  const allDecorators = Reflection.getPropertyDecorators(ValidationKeys.REFLECT, self, prop).decorators;
1220
1650
  decorators = allDecorators.filter((d) => [ModelKeys.TYPE, ValidationKeys.TYPE].indexOf(d.key) !== -1);
1221
1651
  if (!decorators || !decorators.length)
1222
- throw new Error(sf("failed to find decorators for property {0}", prop));
1652
+ throw new Error(`failed to find decorators for property ${prop}`);
1223
1653
  dec = decorators.pop();
1224
1654
  const clazz = dec.props.name
1225
1655
  ? [dec.props.name]
@@ -1335,10 +1765,7 @@ class Model {
1335
1765
  return Model.getRegistry().build(obj, clazz);
1336
1766
  }
1337
1767
  static getMetadata(model) {
1338
- const metadata = Reflect.getMetadata(Model.key(ModelKeys.MODEL), model.constructor);
1339
- if (!metadata)
1340
- throw new Error("could not find metadata for provided " + model.constructor.name);
1341
- return metadata;
1768
+ return getMetadata(model);
1342
1769
  }
1343
1770
  static getAttributes(model) {
1344
1771
  const result = [];
@@ -1378,7 +1805,54 @@ class Model {
1378
1805
  * @param {string} str
1379
1806
  */
1380
1807
  static key(str) {
1381
- return ModelKeys.REFLECT + str;
1808
+ return getModelKey(str);
1809
+ }
1810
+ /**
1811
+ * @description Determines if an object is a model instance or has model metadata
1812
+ * @summary Checks whether a given object is either an instance of the Model class or
1813
+ * has model metadata attached to it. This function is essential for serialization and
1814
+ * deserialization processes, as it helps identify model objects that need special handling.
1815
+ * It safely handles potential errors during metadata retrieval.
1816
+ *
1817
+ * @param {Record<string, any>} target - The object to check
1818
+ * @return {boolean} True if the object is a model instance or has model metadata, false otherwise
1819
+ *
1820
+ * @example
1821
+ * ```typescript
1822
+ * // Check if an object is a model
1823
+ * const user = new User({ name: "John" });
1824
+ * const isUserModel = isModel(user); // true
1825
+ *
1826
+ * // Check a plain object
1827
+ * const plainObject = { name: "John" };
1828
+ * const isPlainObjectModel = isModel(plainObject); // false
1829
+ * ```
1830
+ */
1831
+ static isModel(target) {
1832
+ try {
1833
+ return target instanceof Model || !!Model.getMetadata(target);
1834
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1835
+ }
1836
+ catch (e) {
1837
+ return false;
1838
+ }
1839
+ }
1840
+ /**
1841
+ * @description Checks if a property of a model is itself a model or has a model type
1842
+ * @summary Determines whether a specific property of a model instance is either a model instance
1843
+ * or has a type that is registered as a model. This function is used for model serialization
1844
+ * and deserialization to properly handle nested models.
1845
+ * @template M extends {@link Model}
1846
+ * @param {M} target - The model instance to check
1847
+ * @param {string} attribute - The property name to check
1848
+ * @return {boolean | string | undefined} Returns true if the property is a model instance,
1849
+ * the model name if the property has a model type, or undefined if not a model
1850
+ */
1851
+ static isPropertyModel(target, attribute) {
1852
+ if (Model.isModel(target[attribute]))
1853
+ return true;
1854
+ const metadata = Reflect.getMetadata(ModelKeys.TYPE, target, attribute);
1855
+ return Model.get(metadata.name) ? metadata.name : undefined;
1382
1856
  }
1383
1857
  }
1384
1858
 
@@ -1394,7 +1868,7 @@ const DefaultSerializationMethod = "json";
1394
1868
  * @class JSONSerializer
1395
1869
  * @implements Serializer
1396
1870
  *
1397
- * @category Serialization
1871
+ * @category Model
1398
1872
  */
1399
1873
  class JSONSerializer {
1400
1874
  constructor() { }
@@ -1409,7 +1883,7 @@ class JSONSerializer {
1409
1883
  preSerialize(model) {
1410
1884
  // TODO: nested preserialization (so increase performance when deserializing)
1411
1885
  const toSerialize = Object.assign({}, model);
1412
- const metadata = Model.getMetadata(model);
1886
+ const metadata = getMetadata(model);
1413
1887
  toSerialize[ModelKeys.ANCHOR] = metadata || model.constructor.name;
1414
1888
  return toSerialize;
1415
1889
  }
@@ -1470,84 +1944,6 @@ class Serialization {
1470
1944
  }
1471
1945
  }
1472
1946
 
1473
- /******************************************************************************
1474
- Copyright (c) Microsoft Corporation.
1475
-
1476
- Permission to use, copy, modify, and/or distribute this software for any
1477
- purpose with or without fee is hereby granted.
1478
-
1479
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
1480
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1481
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1482
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1483
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1484
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1485
- PERFORMANCE OF THIS SOFTWARE.
1486
- ***************************************************************************** */
1487
- /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
1488
-
1489
-
1490
- function __decorate(decorators, target, key, desc) {
1491
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1492
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1493
- 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;
1494
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1495
- }
1496
-
1497
- function __metadata(metadataKey, metadataValue) {
1498
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
1499
- }
1500
-
1501
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
1502
- var e = new Error(message);
1503
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1504
- };
1505
-
1506
- /**
1507
- * @summary Base Implementation for Validators
1508
- * @description Provides the underlying functionality for {@link Validator}s
1509
- *
1510
- * @param {string} validationKey the key to register the validator under
1511
- * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#DEFAULT}
1512
- * @param {string[]} [acceptedTypes] defines the value types this validator can validate
1513
- *
1514
- * @class Validator
1515
- * @abstract
1516
- * @category Validators
1517
- */
1518
- class Validator {
1519
- constructor(message = DEFAULT_ERROR_MESSAGES.DEFAULT, ...acceptedTypes) {
1520
- this.message = message;
1521
- if (acceptedTypes.length)
1522
- this.acceptedTypes = acceptedTypes;
1523
- if (this.acceptedTypes)
1524
- this.hasErrors = this.checkTypeAndHasErrors(this.hasErrors.bind(this));
1525
- }
1526
- /**
1527
- * @summary builds the error message
1528
- * @param {string} message
1529
- * @param {any[]} args
1530
- * @protected
1531
- */
1532
- getMessage(message, ...args) {
1533
- return sf(message, ...args);
1534
- }
1535
- /**
1536
- * @summary Validates type
1537
- * @param {any} unbound
1538
- * @private
1539
- */
1540
- checkTypeAndHasErrors(unbound) {
1541
- return function (value, ...args) {
1542
- if (value === undefined || !this.acceptedTypes)
1543
- return unbound(value, ...args);
1544
- if (!Reflection.checkTypes(value, this.acceptedTypes))
1545
- return this.getMessage(DEFAULT_ERROR_MESSAGES.TYPE, this.acceptedTypes.join(", "), typeof value);
1546
- return unbound(value, ...args);
1547
- }.bind(this);
1548
- }
1549
- }
1550
-
1551
1947
  /**
1552
1948
  * @summary Marks the class as a validator for a certain key.
1553
1949
  * @description Registers the class in the {@link Validation} with the provided key
@@ -1572,26 +1968,58 @@ function validator(...keys) {
1572
1968
  }
1573
1969
 
1574
1970
  /**
1575
- * @summary Date Validator
1576
- *
1577
- * @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#DATE}
1578
- *
1971
+ * @description Validator for checking if a value is a valid date
1972
+ * @summary The DateValidator checks if a value is a valid date object or a string that can be converted to a valid date.
1973
+ * It validates that the value represents a real date and not an invalid date like "2023-02-31".
1974
+ * @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#DATE}
1579
1975
  * @class DateValidator
1580
1976
  * @extends Validator
1581
1977
  *
1582
1978
  * @category Validators
1979
+ * @example
1980
+ * ```typescript
1981
+ * // Create a date validator with default error message
1982
+ * const dateValidator = new DateValidator();
1983
+ *
1984
+ * // Create a date validator with custom error message
1985
+ * const customDateValidator = new DateValidator("Please enter a valid date");
1986
+ *
1987
+ * // Validate a date
1988
+ * const result = dateValidator.hasErrors(new Date()); // undefined (valid)
1989
+ * const invalidResult = dateValidator.hasErrors("not a date"); // Returns error message (invalid)
1990
+ * ```
1991
+ * @mermaid
1992
+ * sequenceDiagram
1993
+ * participant C as Client
1994
+ * participant V as DateValidator
1995
+ *
1996
+ * C->>V: new DateValidator(message)
1997
+ * C->>V: hasErrors(value, options)
1998
+ * alt value is undefined
1999
+ * V-->>C: undefined (valid)
2000
+ * else value is string
2001
+ * V->>V: Convert to Date
2002
+ * end
2003
+ * alt Date is invalid (NaN)
2004
+ * V-->>C: Error message
2005
+ * else Date is valid
2006
+ * V-->>C: undefined (valid)
2007
+ * end
1583
2008
  */
1584
2009
  let DateValidator = class DateValidator extends Validator {
1585
2010
  constructor(message = DEFAULT_ERROR_MESSAGES.DATE) {
1586
2011
  super(message, Number.name, Date.name, String.name);
1587
2012
  }
1588
2013
  /**
1589
- * @summary Validates a model
2014
+ * @description Checks if the provided value is a valid date
2015
+ * @summary Validates that the given value is a valid date. If the value is a string,
2016
+ * it attempts to convert it to a Date object. Returns an error message if the date is invalid,
2017
+ * or undefined if the date is valid or if the value is undefined.
1590
2018
  *
1591
- * @param {Date | string} value
1592
- * @param {DateValidatorOptions} [options]
2019
+ * @param {Date | string} value - The value to validate, can be a Date object or a string
2020
+ * @param {DateValidatorOptions} [options={}] - Optional configuration options for the validator
1593
2021
  *
1594
- * @return {string | undefined}
2022
+ * @return {string | undefined} Error message if validation fails, undefined if validation passes
1595
2023
  *
1596
2024
  * @override
1597
2025
  *
@@ -1827,16 +2255,73 @@ DiffValidator = __decorate([
1827
2255
  __metadata("design:paramtypes", [String])
1828
2256
  ], DiffValidator);
1829
2257
 
2258
+ /**
2259
+ * @description Regular expression for parsing string patterns with flags
2260
+ * @summary This regular expression is used to parse string patterns in the format "/pattern/flags".
2261
+ * It captures the pattern and flags separately, allowing the creation of a RegExp object
2262
+ * with the appropriate flags.
2263
+ *
2264
+ * @const {RegExp}
2265
+ * @memberOf module:decorator-validation
2266
+ * @category Validation
2267
+ */
1830
2268
  const regexpParser = new RegExp("^/(.+)/([gimus]*)$");
1831
2269
  /**
1832
- * @summary Pattern Validator
2270
+ * @description Validator for checking if a string matches a regular expression pattern
2271
+ * @summary The PatternValidator checks if a string value matches a specified regular expression pattern.
2272
+ * It supports both RegExp objects and string representations of patterns, including those with flags.
2273
+ * This validator is the foundation for specialized validators like EmailValidator and URLValidator,
2274
+ * and is typically used with the @pattern decorator.
1833
2275
  *
1834
- * @param {string} [key] defaults to {@link ValidationKeys#PATTERN}
1835
- * @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#PATTERN}
2276
+ * @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#PATTERN}
1836
2277
  *
1837
2278
  * @class PatternValidator
1838
2279
  * @extends Validator
1839
2280
  *
2281
+ * @example
2282
+ * ```typescript
2283
+ * // Create a pattern validator with default error message
2284
+ * const patternValidator = new PatternValidator();
2285
+ *
2286
+ * // Create a pattern validator with custom error message
2287
+ * const customPatternValidator = new PatternValidator("Value must match the required format");
2288
+ *
2289
+ * // Validate using a RegExp object
2290
+ * const regexOptions = { pattern: /^[A-Z][a-z]+$/ };
2291
+ * patternValidator.hasErrors("Hello", regexOptions); // undefined (valid)
2292
+ * patternValidator.hasErrors("hello", regexOptions); // Returns error message (invalid)
2293
+ *
2294
+ * // Validate using a string pattern
2295
+ * const stringOptions = { pattern: "^\\d{3}-\\d{2}-\\d{4}$" };
2296
+ * patternValidator.hasErrors("123-45-6789", stringOptions); // undefined (valid)
2297
+ *
2298
+ * // Validate using a string pattern with flags
2299
+ * const flagOptions = { pattern: "/^hello$/i" };
2300
+ * patternValidator.hasErrors("Hello", flagOptions); // undefined (valid)
2301
+ * ```
2302
+ *
2303
+ * @mermaid
2304
+ * sequenceDiagram
2305
+ * participant C as Client
2306
+ * participant V as PatternValidator
2307
+ *
2308
+ * C->>V: new PatternValidator(message)
2309
+ * C->>V: hasErrors(value, options)
2310
+ * alt value is empty
2311
+ * V-->>C: undefined (valid)
2312
+ * else pattern is missing
2313
+ * V-->>C: Error: Missing Pattern
2314
+ * else pattern is string
2315
+ * V->>V: getPattern(pattern)
2316
+ * end
2317
+ * V->>V: Reset pattern.lastIndex
2318
+ * V->>V: Test value against pattern
2319
+ * alt pattern test passes
2320
+ * V-->>C: undefined (valid)
2321
+ * else pattern test fails
2322
+ * V-->>C: Error message
2323
+ * end
2324
+ *
1840
2325
  * @category Validators
1841
2326
  */
1842
2327
  let PatternValidator = class PatternValidator extends Validator {
@@ -1844,9 +2329,12 @@ let PatternValidator = class PatternValidator extends Validator {
1844
2329
  super(message, "string");
1845
2330
  }
1846
2331
  /**
1847
- * @summary parses and validates a pattern
2332
+ * @description Converts a string pattern to a RegExp object
2333
+ * @summary Parses a string representation of a regular expression and converts it to a RegExp object.
2334
+ * It handles both simple string patterns and patterns with flags in the format "/pattern/flags".
1848
2335
  *
1849
- * @param {string} pattern
2336
+ * @param {string} pattern - The string pattern to convert
2337
+ * @return {RegExp} A RegExp object created from the string pattern
1850
2338
  * @private
1851
2339
  */
1852
2340
  getPattern(pattern) {
@@ -1856,12 +2344,18 @@ let PatternValidator = class PatternValidator extends Validator {
1856
2344
  return new RegExp(match[1], match[2]);
1857
2345
  }
1858
2346
  /**
1859
- * @summary Validates a Model
2347
+ * @description Checks if a string matches a regular expression pattern
2348
+ * @summary Validates that the provided string matches the pattern specified in the options.
2349
+ * If the pattern is provided as a string, it's converted to a RegExp object using the getPattern method.
2350
+ * The method resets the pattern's lastIndex property to ensure consistent validation results
2351
+ * for patterns with the global flag.
1860
2352
  *
1861
- * @param {string} value
1862
- * @param {PatternValidatorOptions} options
2353
+ * @param {string} value - The string to validate against the pattern
2354
+ * @param {PatternValidatorOptions} options - Configuration options containing the pattern
1863
2355
  *
1864
- * @return {string | undefined}
2356
+ * @return {string | undefined} Error message if validation fails, undefined if validation passes
2357
+ *
2358
+ * @throws {Error} If no pattern is provided in the options
1865
2359
  *
1866
2360
  * @override
1867
2361
  *
@@ -1886,13 +2380,42 @@ PatternValidator = __decorate([
1886
2380
  ], PatternValidator);
1887
2381
 
1888
2382
  /**
1889
- * @summary Email Validator
2383
+ * @description Validator for checking if a string is a valid email address
2384
+ * @summary The EmailValidator checks if a string matches a standard email address pattern.
2385
+ * It extends the PatternValidator and uses a predefined email regex pattern to validate email addresses.
2386
+ * This validator is typically used with the @email decorator.
1890
2387
  *
1891
- * @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#EMAIL}
2388
+ * @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#EMAIL}
1892
2389
  *
1893
2390
  * @class EmailValidator
1894
2391
  * @extends PatternValidator
1895
2392
  *
2393
+ * @example
2394
+ * ```typescript
2395
+ * // Create an email validator with default error message
2396
+ * const emailValidator = new EmailValidator();
2397
+ *
2398
+ * // Create an email validator with custom error message
2399
+ * const customEmailValidator = new EmailValidator("Please enter a valid email address");
2400
+ *
2401
+ * // Validate an email
2402
+ * const result = emailValidator.hasErrors("user@example.com"); // undefined (valid)
2403
+ * const invalidResult = emailValidator.hasErrors("invalid-email"); // Returns error message (invalid)
2404
+ * ```
2405
+ *
2406
+ * @mermaid
2407
+ * sequenceDiagram
2408
+ * participant C as Client
2409
+ * participant E as EmailValidator
2410
+ * participant P as PatternValidator
2411
+ *
2412
+ * C->>E: new EmailValidator(message)
2413
+ * E->>P: super(message)
2414
+ * C->>E: hasErrors(value, options)
2415
+ * E->>P: super.hasErrors(value, options with EMAIL pattern)
2416
+ * P-->>E: validation result
2417
+ * E-->>C: validation result
2418
+ *
1896
2419
  * @category Validators
1897
2420
  */
1898
2421
  let EmailValidator = class EmailValidator extends PatternValidator {
@@ -1900,16 +2423,19 @@ let EmailValidator = class EmailValidator extends PatternValidator {
1900
2423
  super(message);
1901
2424
  }
1902
2425
  /**
1903
- * @summary Validates a model
2426
+ * @description Checks if a string is a valid email address
2427
+ * @summary Validates that the provided string matches the email pattern.
2428
+ * This method extends the PatternValidator's hasErrors method by ensuring
2429
+ * the email pattern is used, even if not explicitly provided in the options.
1904
2430
  *
1905
- * @param {string} value
1906
- * @param {PatternValidatorOptions} [options]
2431
+ * @param {string} value - The string to validate as an email address
2432
+ * @param {PatternValidatorOptions} [options={}] - Optional configuration options
1907
2433
  *
1908
- * @return {string | undefined}
2434
+ * @return {string | undefined} Error message if validation fails, undefined if validation passes
1909
2435
  *
1910
2436
  * @override
1911
2437
  *
1912
- * @see Validator#hasErrors
2438
+ * @see PatternValidator#hasErrors
1913
2439
  */
1914
2440
  hasErrors(value, options = {}) {
1915
2441
  return super.hasErrors(value, {
@@ -2168,13 +2694,48 @@ LessThanOrEqualValidator = __decorate([
2168
2694
  ], LessThanOrEqualValidator);
2169
2695
 
2170
2696
  /**
2171
- * @summary List Validator
2697
+ * @description Validator for checking if elements in a list or set match expected types
2698
+ * @summary The ListValidator validates that all elements in an array or Set match the expected types.
2699
+ * It checks each element against a list of allowed class types and ensures type consistency.
2700
+ * This validator is typically used with the @list decorator.
2172
2701
  *
2173
- * @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#LIST}
2702
+ * @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#LIST}
2174
2703
  *
2175
2704
  * @class ListValidator
2176
2705
  * @extends Validator
2177
2706
  *
2707
+ * @example
2708
+ * ```typescript
2709
+ * // Create a list validator with default error message
2710
+ * const listValidator = new ListValidator();
2711
+ *
2712
+ * // Create a list validator with custom error message
2713
+ * const customListValidator = new ListValidator("All items must be of the specified type");
2714
+ *
2715
+ * // Validate a list
2716
+ * const options = { clazz: ["String", "Number"] };
2717
+ * const result = listValidator.hasErrors(["test", 123], options); // undefined (valid)
2718
+ * const invalidResult = listValidator.hasErrors([new Date()], options); // Returns error message (invalid)
2719
+ * ```
2720
+ *
2721
+ * @mermaid
2722
+ * sequenceDiagram
2723
+ * participant C as Client
2724
+ * participant V as ListValidator
2725
+ *
2726
+ * C->>V: new ListValidator(message)
2727
+ * C->>V: hasErrors(value, options)
2728
+ * alt value is empty
2729
+ * V-->>C: undefined (valid)
2730
+ * else value has elements
2731
+ * V->>V: Check each element's type
2732
+ * alt All elements match allowed types
2733
+ * V-->>C: undefined (valid)
2734
+ * else Some elements don't match
2735
+ * V-->>C: Error message
2736
+ * end
2737
+ * end
2738
+ *
2178
2739
  * @category Validators
2179
2740
  */
2180
2741
  let ListValidator = class ListValidator extends Validator {
@@ -2182,12 +2743,15 @@ let ListValidator = class ListValidator extends Validator {
2182
2743
  super(message, Array.name, Set.name);
2183
2744
  }
2184
2745
  /**
2185
- * @summary Validates a model
2746
+ * @description Checks if all elements in a list or set match the expected types
2747
+ * @summary Validates that each element in the provided array or Set matches one of the
2748
+ * class types specified in the options. For object types, it checks the constructor name,
2749
+ * and for primitive types, it compares against the lowercase type name.
2186
2750
  *
2187
- * @param {any[] | Set<any>} value
2188
- * @param {ListValidatorOptions} options
2751
+ * @param {any[] | Set<any>} value - The array or Set to validate
2752
+ * @param {ListValidatorOptions} options - Configuration options containing the allowed class types
2189
2753
  *
2190
- * @return {string | undefined}
2754
+ * @return {string | undefined} Error message if validation fails, undefined if validation passes
2191
2755
  *
2192
2756
  * @override
2193
2757
  *
@@ -2263,13 +2827,55 @@ MaxLengthValidator = __decorate([
2263
2827
  ], MaxLengthValidator);
2264
2828
 
2265
2829
  /**
2266
- * @summary Max Validator
2830
+ * @description Validator for checking if a value is less than or equal to a maximum
2831
+ * @summary The MaxValidator checks if a numeric value, date, or string is less than or equal to
2832
+ * a specified maximum value. It supports comparing numbers directly, dates chronologically,
2833
+ * and strings lexicographically. This validator is typically used with the @max decorator.
2267
2834
  *
2268
- * @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#MAX}
2835
+ * @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#MAX}
2269
2836
  *
2270
2837
  * @class MaxValidator
2271
2838
  * @extends Validator
2272
2839
  *
2840
+ * @example
2841
+ * ```typescript
2842
+ * // Create a max validator with default error message
2843
+ * const maxValidator = new MaxValidator();
2844
+ *
2845
+ * // Create a max validator with custom error message
2846
+ * const customMaxValidator = new MaxValidator("Value must not exceed {0}");
2847
+ *
2848
+ * // Validate a number
2849
+ * const numOptions = { max: 100, message: "Number too large" };
2850
+ * const numResult = maxValidator.hasErrors(50, numOptions); // undefined (valid)
2851
+ * const invalidNumResult = maxValidator.hasErrors(150, numOptions); // Returns error message (invalid)
2852
+ *
2853
+ * // Validate a date
2854
+ * const dateOptions = { max: new Date(2023, 11, 31) };
2855
+ * const dateResult = maxValidator.hasErrors(new Date(2023, 5, 15), dateOptions); // undefined (valid)
2856
+ * ```
2857
+ *
2858
+ * @mermaid
2859
+ * sequenceDiagram
2860
+ * participant C as Client
2861
+ * participant V as MaxValidator
2862
+ *
2863
+ * C->>V: new MaxValidator(message)
2864
+ * C->>V: hasErrors(value, options)
2865
+ * alt value is undefined
2866
+ * V-->>C: undefined (valid)
2867
+ * else value is Date and max is not Date
2868
+ * V->>V: Convert max to Date
2869
+ * alt conversion fails
2870
+ * V-->>C: Error: Invalid Max param
2871
+ * end
2872
+ * end
2873
+ * alt value > max
2874
+ * V-->>C: Error message
2875
+ * else value <= max
2876
+ * V-->>C: undefined (valid)
2877
+ * end
2878
+ *
2273
2879
  * @category Validators
2274
2880
  */
2275
2881
  let MaxValidator = class MaxValidator extends Validator {
@@ -2277,12 +2883,16 @@ let MaxValidator = class MaxValidator extends Validator {
2277
2883
  super(message, "number", "Date", "string");
2278
2884
  }
2279
2885
  /**
2280
- * @summary Validates a Model
2886
+ * @description Checks if a value is less than or equal to a maximum
2887
+ * @summary Validates that the provided value does not exceed the maximum value
2888
+ * specified in the options. For dates, it performs chronological comparison,
2889
+ * converting string representations to Date objects if necessary. For numbers
2890
+ * and strings, it performs direct comparison.
2281
2891
  *
2282
- * @param {string} value
2283
- * @param {MaxValidatorOptions} options
2892
+ * @param {number | Date | string} value - The value to validate
2893
+ * @param {MaxValidatorOptions} options - Configuration options containing the maximum value
2284
2894
  *
2285
- * @return {string | undefined}
2895
+ * @return {string | undefined} Error message if validation fails, undefined if validation passes
2286
2896
  *
2287
2897
  * @override
2288
2898
  *
@@ -2348,13 +2958,55 @@ MinLengthValidator = __decorate([
2348
2958
  ], MinLengthValidator);
2349
2959
 
2350
2960
  /**
2351
- * @summary Min Validator
2961
+ * @description Validator for checking if a value is greater than or equal to a minimum
2962
+ * @summary The MinValidator checks if a numeric value, date, or string is greater than or equal to
2963
+ * a specified minimum value. It supports comparing numbers directly, dates chronologically,
2964
+ * and strings lexicographically. This validator is typically used with the @min decorator.
2352
2965
  *
2353
- * @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#MIN}
2966
+ * @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#MIN}
2354
2967
  *
2355
2968
  * @class MinValidator
2356
2969
  * @extends Validator
2357
2970
  *
2971
+ * @example
2972
+ * ```typescript
2973
+ * // Create a min validator with default error message
2974
+ * const minValidator = new MinValidator();
2975
+ *
2976
+ * // Create a min validator with custom error message
2977
+ * const customMinValidator = new MinValidator("Value must be at least {0}");
2978
+ *
2979
+ * // Validate a number
2980
+ * const numOptions = { min: 10, message: "Number too small" };
2981
+ * const numResult = minValidator.hasErrors(50, numOptions); // undefined (valid)
2982
+ * const invalidNumResult = minValidator.hasErrors(5, numOptions); // Returns error message (invalid)
2983
+ *
2984
+ * // Validate a date
2985
+ * const dateOptions = { min: new Date(2023, 0, 1) };
2986
+ * const dateResult = minValidator.hasErrors(new Date(2023, 5, 15), dateOptions); // undefined (valid)
2987
+ * ```
2988
+ *
2989
+ * @mermaid
2990
+ * sequenceDiagram
2991
+ * participant C as Client
2992
+ * participant V as MinValidator
2993
+ *
2994
+ * C->>V: new MinValidator(message)
2995
+ * C->>V: hasErrors(value, options)
2996
+ * alt value is undefined
2997
+ * V-->>C: undefined (valid)
2998
+ * else value is Date and min is not Date
2999
+ * V->>V: Convert min to Date
3000
+ * alt conversion fails
3001
+ * V-->>C: Error: Invalid Min param
3002
+ * end
3003
+ * end
3004
+ * alt value < min
3005
+ * V-->>C: Error message
3006
+ * else value >= min
3007
+ * V-->>C: undefined (valid)
3008
+ * end
3009
+ *
2358
3010
  * @category Validators
2359
3011
  */
2360
3012
  let MinValidator = class MinValidator extends Validator {
@@ -2362,12 +3014,16 @@ let MinValidator = class MinValidator extends Validator {
2362
3014
  super(message, "number", "Date", "string");
2363
3015
  }
2364
3016
  /**
2365
- * @summary Validates Model
3017
+ * @description Checks if a value is greater than or equal to a minimum
3018
+ * @summary Validates that the provided value is not less than the minimum value
3019
+ * specified in the options. For dates, it performs chronological comparison,
3020
+ * converting string representations to Date objects if necessary. For numbers
3021
+ * and strings, it performs direct comparison.
2366
3022
  *
2367
- * @param {string} value
2368
- * @param {MaxValidatorOptions} options
3023
+ * @param {number | Date | string} value - The value to validate
3024
+ * @param {MinValidatorOptions} options - Configuration options containing the minimum value
2369
3025
  *
2370
- * @return {string | undefined}
3026
+ * @return {string | undefined} Error message if validation fails, undefined if validation passes
2371
3027
  *
2372
3028
  * @override
2373
3029
  *
@@ -2431,13 +3087,55 @@ PasswordValidator = __decorate([
2431
3087
  ], PasswordValidator);
2432
3088
 
2433
3089
  /**
2434
- * @summary Required Validator
3090
+ * @description Validator for checking if a value is present and not empty
3091
+ * @summary The RequiredValidator ensures that a value is provided and not empty.
3092
+ * It handles different types of values appropriately: for booleans and numbers,
3093
+ * it checks if they're undefined; for other types (strings, arrays, objects),
3094
+ * it checks if they're falsy. This validator is typically used with the @required decorator
3095
+ * and is often the first validation applied to important fields.
2435
3096
  *
2436
- * @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#REQUIRED}
3097
+ * @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#REQUIRED}
2437
3098
  *
2438
3099
  * @class RequiredValidator
2439
3100
  * @extends Validator
2440
3101
  *
3102
+ * @example
3103
+ * ```typescript
3104
+ * // Create a required validator with default error message
3105
+ * const requiredValidator = new RequiredValidator();
3106
+ *
3107
+ * // Create a required validator with custom error message
3108
+ * const customRequiredValidator = new RequiredValidator("This field is mandatory");
3109
+ *
3110
+ * // Validate different types of values
3111
+ * requiredValidator.hasErrors("Hello"); // undefined (valid)
3112
+ * requiredValidator.hasErrors(""); // Returns error message (invalid)
3113
+ * requiredValidator.hasErrors(0); // undefined (valid - 0 is a valid number)
3114
+ * requiredValidator.hasErrors(null); // Returns error message (invalid)
3115
+ * requiredValidator.hasErrors([]); // undefined (valid - empty array is still an array)
3116
+ * ```
3117
+ *
3118
+ * @mermaid
3119
+ * sequenceDiagram
3120
+ * participant C as Client
3121
+ * participant V as RequiredValidator
3122
+ *
3123
+ * C->>V: new RequiredValidator(message)
3124
+ * C->>V: hasErrors(value, options)
3125
+ * alt typeof value is boolean or number
3126
+ * alt value is undefined
3127
+ * V-->>C: Error message
3128
+ * else value is defined
3129
+ * V-->>C: undefined (valid)
3130
+ * end
3131
+ * else other types
3132
+ * alt value is falsy (null, undefined, empty string)
3133
+ * V-->>C: Error message
3134
+ * else value is truthy
3135
+ * V-->>C: undefined (valid)
3136
+ * end
3137
+ * end
3138
+ *
2441
3139
  * @category Validators
2442
3140
  */
2443
3141
  let RequiredValidator = class RequiredValidator extends Validator {
@@ -2445,12 +3143,16 @@ let RequiredValidator = class RequiredValidator extends Validator {
2445
3143
  super(message);
2446
3144
  }
2447
3145
  /**
2448
- * @summary Validates a model
3146
+ * @description Checks if a value is present and not empty
3147
+ * @summary Validates that the provided value exists and is not empty.
3148
+ * The validation logic varies by type:
3149
+ * - For booleans and numbers: checks if the value is undefined
3150
+ * - For other types (strings, arrays, objects): checks if the value is falsy
2449
3151
  *
2450
- * @param {string} value
2451
- * @param {ValidatorOptions} [options={}]
3152
+ * @param {any} value - The value to validate
3153
+ * @param {ValidatorOptions} [options={}] - Optional configuration options
2452
3154
  *
2453
- * @return {string | undefined}
3155
+ * @return {string | undefined} Error message if validation fails, undefined if validation passes
2454
3156
  *
2455
3157
  * @override
2456
3158
  *
@@ -2516,11 +3218,61 @@ StepValidator = __decorate([
2516
3218
  ], StepValidator);
2517
3219
 
2518
3220
  /**
2519
- * @summary Required Validator
3221
+ * @description Validator for checking if a value is of the expected type(s)
3222
+ * @summary The TypeValidator ensures that a value matches one of the specified types.
3223
+ * It can validate against a single type, multiple types, or a type with a specific name.
3224
+ * This validator is typically used with the @type decorator and is fundamental for
3225
+ * ensuring type safety in validated models.
2520
3226
  *
2521
- * @class RequiredValidator
3227
+ * @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#TYPE}
3228
+ *
3229
+ * @class TypeValidator
2522
3230
  * @extends Validator
2523
3231
  *
3232
+ * @example
3233
+ * ```typescript
3234
+ * // Create a type validator with default error message
3235
+ * const typeValidator = new TypeValidator();
3236
+ *
3237
+ * // Create a type validator with custom error message
3238
+ * const customTypeValidator = new TypeValidator("Value must be of type {0}, but got {1}");
3239
+ *
3240
+ * // Validate against a single type
3241
+ * const stringOptions = { types: "string" };
3242
+ * typeValidator.hasErrors("hello", stringOptions); // undefined (valid)
3243
+ * typeValidator.hasErrors(123, stringOptions); // Returns error message (invalid)
3244
+ *
3245
+ * // Validate against multiple types
3246
+ * const multiOptions = { types: ["string", "number"] };
3247
+ * typeValidator.hasErrors("hello", multiOptions); // undefined (valid)
3248
+ * typeValidator.hasErrors(123, multiOptions); // undefined (valid)
3249
+ * typeValidator.hasErrors(true, multiOptions); // Returns error message (invalid)
3250
+ *
3251
+ * // Validate against a class type
3252
+ * const classOptions = { types: { name: "Date" } };
3253
+ * typeValidator.hasErrors(new Date(), classOptions); // undefined (valid)
3254
+ * ```
3255
+ *
3256
+ * @mermaid
3257
+ * sequenceDiagram
3258
+ * participant C as Client
3259
+ * participant V as TypeValidator
3260
+ * participant R as Reflection
3261
+ *
3262
+ * C->>V: new TypeValidator(message)
3263
+ * C->>V: hasErrors(value, options)
3264
+ * alt value is undefined
3265
+ * V-->>C: undefined (valid)
3266
+ * else value is defined
3267
+ * V->>R: evaluateDesignTypes(value, types)
3268
+ * alt type evaluation passes
3269
+ * V-->>C: undefined (valid)
3270
+ * else type evaluation fails
3271
+ * V->>V: Format error message with type info
3272
+ * V-->>C: Error message
3273
+ * end
3274
+ * end
3275
+ *
2524
3276
  * @category Validators
2525
3277
  */
2526
3278
  let TypeValidator = class TypeValidator extends Validator {
@@ -2528,11 +3280,15 @@ let TypeValidator = class TypeValidator extends Validator {
2528
3280
  super(message);
2529
3281
  }
2530
3282
  /**
2531
- * @summary Validates a model
2532
- * @param {string} value
2533
- * @param {TypeValidatorOptions} options
3283
+ * @description Checks if a value is of the expected type(s)
3284
+ * @summary Validates that the provided value matches one of the specified types.
3285
+ * It uses the Reflection utility to evaluate if the value's type matches the expected types.
3286
+ * The method skips validation for undefined values to avoid conflicts with the RequiredValidator.
2534
3287
  *
2535
- * @return {string | undefined}
3288
+ * @param {any} value - The value to validate
3289
+ * @param {TypeValidatorOptions} options - Configuration options containing the expected types
3290
+ *
3291
+ * @return {string | undefined} Error message if validation fails, undefined if validation passes
2536
3292
  *
2537
3293
  * @override
2538
3294
  *
@@ -2554,6 +3310,14 @@ TypeValidator = __decorate([
2554
3310
  validator(ValidationKeys.TYPE),
2555
3311
  __metadata("design:paramtypes", [String])
2556
3312
  ], TypeValidator);
3313
+ /**
3314
+ * @description Register the TypeValidator with the Validation registry
3315
+ * @summary This registration associates the TypeValidator with the ModelKeys.TYPE key,
3316
+ * allowing it to be used for validating design types. The save flag is set to false
3317
+ * to prevent the validator from being saved in the standard validator registry.
3318
+ *
3319
+ * @memberOf module:decorator-validation
3320
+ */
2557
3321
  Validation.register({
2558
3322
  validator: TypeValidator,
2559
3323
  validationKey: ModelKeys.TYPE,
@@ -2561,12 +3325,43 @@ Validation.register({
2561
3325
  });
2562
3326
 
2563
3327
  /**
2564
- * @summary URL Validator
2565
- * @description Pattern from {@link https://gist.github.com/dperini/729294}
3328
+ * @description Validator for checking if a string is a valid URL
3329
+ * @summary The URLValidator checks if a string matches a standard URL pattern.
3330
+ * It extends the PatternValidator and uses a robust URL regex pattern to validate web addresses.
3331
+ * The pattern is sourced from {@link https://gist.github.com/dperini/729294} and is widely
3332
+ * recognized for its accuracy in validating URLs. This validator is typically used with the @url decorator.
3333
+ *
3334
+ * @param {string} [message] - Custom error message to display when validation fails, defaults to {@link DEFAULT_ERROR_MESSAGES#URL}
2566
3335
  *
2567
3336
  * @class URLValidator
2568
3337
  * @extends PatternValidator
2569
3338
  *
3339
+ * @example
3340
+ * ```typescript
3341
+ * // Create a URL validator with default error message
3342
+ * const urlValidator = new URLValidator();
3343
+ *
3344
+ * // Create a URL validator with custom error message
3345
+ * const customUrlValidator = new URLValidator("Please enter a valid web address");
3346
+ *
3347
+ * // Validate a URL
3348
+ * const result = urlValidator.hasErrors("https://example.com"); // undefined (valid)
3349
+ * const invalidResult = urlValidator.hasErrors("not-a-url"); // Returns error message (invalid)
3350
+ * ```
3351
+ *
3352
+ * @mermaid
3353
+ * sequenceDiagram
3354
+ * participant C as Client
3355
+ * participant U as URLValidator
3356
+ * participant P as PatternValidator
3357
+ *
3358
+ * C->>U: new URLValidator(message)
3359
+ * U->>P: super(message)
3360
+ * C->>U: hasErrors(value, options)
3361
+ * U->>P: super.hasErrors(value, options with URL pattern)
3362
+ * P-->>U: validation result
3363
+ * U-->>C: validation result
3364
+ *
2570
3365
  * @category Validators
2571
3366
  */
2572
3367
  let URLValidator = class URLValidator extends PatternValidator {
@@ -2574,16 +3369,19 @@ let URLValidator = class URLValidator extends PatternValidator {
2574
3369
  super(message);
2575
3370
  }
2576
3371
  /**
2577
- * @summary Validates a model
3372
+ * @description Checks if a string is a valid URL
3373
+ * @summary Validates that the provided string matches the URL pattern.
3374
+ * This method extends the PatternValidator's hasErrors method by ensuring
3375
+ * the URL pattern is used, even if not explicitly provided in the options.
2578
3376
  *
2579
- * @param {string} value
2580
- * @param {PatternValidatorOptions} [options={}]
3377
+ * @param {string} value - The string to validate as a URL
3378
+ * @param {PatternValidatorOptions} [options={}] - Optional configuration options
2581
3379
  *
2582
- * @return {string | undefined}
3380
+ * @return {string | undefined} Error message if validation fails, undefined if validation passes
2583
3381
  *
2584
3382
  * @override
2585
3383
  *
2586
- * @see Validator#hasErrors
3384
+ * @see PatternValidator#hasErrors
2587
3385
  */
2588
3386
  hasErrors(value, options = {}) {
2589
3387
  return super.hasErrors(value, {
@@ -2598,37 +3396,69 @@ URLValidator = __decorate([
2598
3396
  ], URLValidator);
2599
3397
 
2600
3398
  /**
2601
- * @summary Marks the property as required.
2602
- * @description Validators to validate a decorated property must use key {@link ValidationKeys#REQUIRED}
3399
+ * @description Property decorator that marks a field as required
3400
+ * @summary Marks the property as required, causing validation to fail if the property is undefined, null, or empty.
3401
+ * Validators to validate a decorated property must use key {@link ValidationKeys#REQUIRED}.
3402
+ * This decorator is commonly used as the first validation step for important fields.
2603
3403
  *
2604
- * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#REQUIRED}
3404
+ * @param {string} [message] - The error message to display when validation fails. Defaults to {@link DEFAULT_ERROR_MESSAGES#REQUIRED}
3405
+ * @return {PropertyDecorator} A decorator function that can be applied to class properties
2605
3406
  *
2606
3407
  * @function required
2607
- *
2608
3408
  * @category Decorators
3409
+ *
3410
+ * @example
3411
+ * ```typescript
3412
+ * class User {
3413
+ * @required()
3414
+ * username: string;
3415
+ *
3416
+ * @required("Email address is mandatory")
3417
+ * email: string;
3418
+ * }
3419
+ * ```
2609
3420
  */
2610
3421
  function required(message = DEFAULT_ERROR_MESSAGES.REQUIRED) {
2611
- return propMetadata(Validation.key(ValidationKeys.REQUIRED), {
3422
+ const key = Validation.key(ValidationKeys.REQUIRED);
3423
+ return Decoration.for(key)
3424
+ .define(propMetadata(key, {
2612
3425
  message: message,
2613
- });
3426
+ }))
3427
+ .apply();
2614
3428
  }
2615
3429
  /**
2616
- * @summary Defines a minimum value for the property
2617
- * @description Validators to validate a decorated property must use key {@link ValidationKeys#MIN}
3430
+ * @description Property decorator that enforces a minimum value constraint
3431
+ * @summary Defines a minimum value for the property, causing validation to fail if the property value is less than the specified minimum.
3432
+ * Validators to validate a decorated property must use key {@link ValidationKeys#MIN}.
3433
+ * This decorator works with numeric values and dates.
2618
3434
  *
2619
- * @param {number | Date} value
2620
- * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#MIN}
3435
+ * @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
3436
+ * @param {string} [message] - The error message to display when validation fails. Defaults to {@link DEFAULT_ERROR_MESSAGES#MIN}
3437
+ * @return {PropertyDecorator} A decorator function that can be applied to class properties
2621
3438
  *
2622
3439
  * @function min
2623
- * @memberOf module:decorator-validation.Decorators.Validation
2624
3440
  * @category Decorators
3441
+ *
3442
+ * @example
3443
+ * ```typescript
3444
+ * class Product {
3445
+ * @min(0)
3446
+ * price: number;
3447
+ *
3448
+ * @min(new Date(2023, 0, 1), "Date must be after January 1, 2023")
3449
+ * releaseDate: Date;
3450
+ * }
3451
+ * ```
2625
3452
  */
2626
3453
  function min(value, message = DEFAULT_ERROR_MESSAGES.MIN) {
2627
- return propMetadata(Validation.key(ValidationKeys.MIN), {
3454
+ const key = Validation.key(ValidationKeys.MIN);
3455
+ return Decoration.for(key)
3456
+ .define(propMetadata(key, {
2628
3457
  [ValidationKeys.MIN]: value,
2629
3458
  message: message,
2630
3459
  types: [Number.name, Date.name],
2631
- });
3460
+ }))
3461
+ .apply();
2632
3462
  }
2633
3463
  /**
2634
3464
  * @summary Defines a maximum value for the property
@@ -2638,15 +3468,17 @@ function min(value, message = DEFAULT_ERROR_MESSAGES.MIN) {
2638
3468
  * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#MAX}
2639
3469
  *
2640
3470
  * @function max
2641
- * @memberOf module:decorator-validation.Decorators.Validation
2642
3471
  * @category Decorators
2643
3472
  */
2644
3473
  function max(value, message = DEFAULT_ERROR_MESSAGES.MAX) {
2645
- return propMetadata(Validation.key(ValidationKeys.MAX), {
3474
+ const key = Validation.key(ValidationKeys.MAX);
3475
+ return Decoration.for(key)
3476
+ .define(propMetadata(key, {
2646
3477
  [ValidationKeys.MAX]: value,
2647
3478
  message: message,
2648
3479
  types: [Number.name, Date.name],
2649
- });
3480
+ }))
3481
+ .apply();
2650
3482
  }
2651
3483
  /**
2652
3484
  * @summary Defines a step value for the property
@@ -2656,15 +3488,17 @@ function max(value, message = DEFAULT_ERROR_MESSAGES.MAX) {
2656
3488
  * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#STEP}
2657
3489
  *
2658
3490
  * @function step
2659
- * @memberOf module:decorator-validation.Decorators.Validation
2660
3491
  * @category Decorators
2661
3492
  */
2662
3493
  function step(value, message = DEFAULT_ERROR_MESSAGES.STEP) {
2663
- return propMetadata(Validation.key(ValidationKeys.STEP), {
3494
+ const key = Validation.key(ValidationKeys.STEP);
3495
+ return Decoration.for(key)
3496
+ .define(propMetadata(key, {
2664
3497
  [ValidationKeys.STEP]: value,
2665
3498
  message: message,
2666
3499
  types: [Number.name],
2667
- });
3500
+ }))
3501
+ .apply();
2668
3502
  }
2669
3503
  /**
2670
3504
  * @summary Defines a minimum length for the property
@@ -2674,15 +3508,17 @@ function step(value, message = DEFAULT_ERROR_MESSAGES.STEP) {
2674
3508
  * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#MIN_LENGTH}
2675
3509
  *
2676
3510
  * @function minlength
2677
- * @memberOf module:decorator-validation.Decorators.Validation
2678
3511
  * @category Decorators
2679
3512
  */
2680
3513
  function minlength(value, message = DEFAULT_ERROR_MESSAGES.MIN_LENGTH) {
2681
- return propMetadata(Validation.key(ValidationKeys.MIN_LENGTH), {
3514
+ const key = Validation.key(ValidationKeys.MIN_LENGTH);
3515
+ return Decoration.for(key)
3516
+ .define(propMetadata(key, {
2682
3517
  [ValidationKeys.MIN_LENGTH]: value,
2683
3518
  message: message,
2684
3519
  types: [String.name, Array.name, Set.name],
2685
- });
3520
+ }))
3521
+ .apply();
2686
3522
  }
2687
3523
  /**
2688
3524
  * @summary Defines a maximum length for the property
@@ -2692,15 +3528,17 @@ function minlength(value, message = DEFAULT_ERROR_MESSAGES.MIN_LENGTH) {
2692
3528
  * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#MAX_LENGTH}
2693
3529
  *
2694
3530
  * @function maxlength
2695
- * @memberOf module:decorator-validation.Decorators.Validation
2696
3531
  * @category Decorators
2697
3532
  */
2698
3533
  function maxlength(value, message = DEFAULT_ERROR_MESSAGES.MAX_LENGTH) {
2699
- return propMetadata(Validation.key(ValidationKeys.MAX_LENGTH), {
3534
+ const key = Validation.key(ValidationKeys.MAX_LENGTH);
3535
+ return Decoration.for(key)
3536
+ .define(propMetadata(key, {
2700
3537
  [ValidationKeys.MAX_LENGTH]: value,
2701
3538
  message: message,
2702
3539
  types: [String.name, Array.name, Set.name],
2703
- });
3540
+ }))
3541
+ .apply();
2704
3542
  }
2705
3543
  /**
2706
3544
  * @summary Defines a RegExp pattern the property must respect
@@ -2710,15 +3548,17 @@ function maxlength(value, message = DEFAULT_ERROR_MESSAGES.MAX_LENGTH) {
2710
3548
  * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#PATTERN}
2711
3549
  *
2712
3550
  * @function pattern
2713
- * @memberOf module:decorator-validation.Decorators.Validation
2714
3551
  * @category Decorators
2715
3552
  */
2716
3553
  function pattern(value, message = DEFAULT_ERROR_MESSAGES.PATTERN) {
2717
- return propMetadata(Validation.key(ValidationKeys.PATTERN), {
3554
+ const key = Validation.key(ValidationKeys.PATTERN);
3555
+ return Decoration.for(key)
3556
+ .define(propMetadata(key, {
2718
3557
  [ValidationKeys.PATTERN]: typeof value === "string" ? value : value.toString(),
2719
3558
  message: message,
2720
3559
  types: [String.name],
2721
- });
3560
+ }))
3561
+ .apply();
2722
3562
  }
2723
3563
  /**
2724
3564
  * @summary Defines the property as an email
@@ -2727,15 +3567,17 @@ function pattern(value, message = DEFAULT_ERROR_MESSAGES.PATTERN) {
2727
3567
  * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#EMAIL}
2728
3568
  *
2729
3569
  * @function email
2730
- * @memberOf module:decorator-validation.Decorators.Validation
2731
3570
  * @category Decorators
2732
3571
  */
2733
3572
  function email(message = DEFAULT_ERROR_MESSAGES.EMAIL) {
2734
- return propMetadata(Validation.key(ValidationKeys.EMAIL), {
3573
+ const key = Validation.key(ValidationKeys.EMAIL);
3574
+ return Decoration.for(key)
3575
+ .define(propMetadata(key, {
2735
3576
  [ValidationKeys.PATTERN]: DEFAULT_PATTERNS.EMAIL,
2736
3577
  message: message,
2737
3578
  types: [String.name],
2738
- });
3579
+ }))
3580
+ .apply();
2739
3581
  }
2740
3582
  /**
2741
3583
  * @summary Defines the property as an URL
@@ -2744,15 +3586,17 @@ function email(message = DEFAULT_ERROR_MESSAGES.EMAIL) {
2744
3586
  * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#URL}
2745
3587
  *
2746
3588
  * @function url
2747
- * @memberOf module:decorator-validation.Decorators.Validation
2748
3589
  * @category Decorators
2749
3590
  */
2750
3591
  function url(message = DEFAULT_ERROR_MESSAGES.URL) {
2751
- return propMetadata(Validation.key(ValidationKeys.URL), {
3592
+ const key = Validation.key(ValidationKeys.URL);
3593
+ return Decoration.for(key)
3594
+ .define(propMetadata(key, {
2752
3595
  [ValidationKeys.PATTERN]: DEFAULT_PATTERNS.URL,
2753
3596
  message: message,
2754
3597
  types: [String.name],
2755
- });
3598
+ }))
3599
+ .apply();
2756
3600
  }
2757
3601
  /**
2758
3602
  * @summary Enforces type verification
@@ -2762,14 +3606,16 @@ function url(message = DEFAULT_ERROR_MESSAGES.URL) {
2762
3606
  * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#TYPE}
2763
3607
  *
2764
3608
  * @function type
2765
- * @memberOf module:decorator-validation.Decorators.Validation
2766
3609
  * @category Decorators
2767
3610
  */
2768
3611
  function type(types, message = DEFAULT_ERROR_MESSAGES.TYPE) {
2769
- return propMetadata(Validation.key(ValidationKeys.TYPE), {
3612
+ const key = Validation.key(ValidationKeys.TYPE);
3613
+ return Decoration.for(key)
3614
+ .define(propMetadata(key, {
2770
3615
  customTypes: types,
2771
3616
  message: message,
2772
- });
3617
+ }))
3618
+ .apply();
2773
3619
  }
2774
3620
  /**
2775
3621
  * @summary Date Handler Decorator
@@ -2779,16 +3625,15 @@ function type(types, message = DEFAULT_ERROR_MESSAGES.TYPE) {
2779
3625
  *
2780
3626
  * @param {string} format accepted format according to {@link formatDate}
2781
3627
  * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#DATE}
2782
- * @param {Constructor<Validator>} [validator] the Validator to be used. Defaults to {@link DateValidator}
2783
3628
  *
2784
3629
  * @function date
2785
3630
  *
2786
- * @memberOf module:decorator-validation.Decorators.Validation
2787
3631
  * @category Decorators
2788
3632
  */
2789
3633
  function date(format = "dd/MM/yyyy", message = DEFAULT_ERROR_MESSAGES.DATE) {
2790
- return (target, propertyKey) => {
2791
- propMetadata(Validation.key(ValidationKeys.DATE), {
3634
+ const key = Validation.key(ValidationKeys.DATE);
3635
+ const dateDec = (target, propertyKey) => {
3636
+ propMetadata(key, {
2792
3637
  [ValidationKeys.FORMAT]: format,
2793
3638
  message: message,
2794
3639
  types: [Date.name],
@@ -2821,26 +3666,28 @@ function date(format = "dd/MM/yyyy", message = DEFAULT_ERROR_MESSAGES.DATE) {
2821
3666
  },
2822
3667
  });
2823
3668
  };
3669
+ return Decoration.for(key).define(dateDec).apply();
2824
3670
  }
2825
3671
  /**
2826
3672
  * @summary Password Handler Decorator
2827
3673
  * @description Validators to validate a decorated property must use key {@link ValidationKeys#PASSWORD}
2828
3674
  *
2829
- * @param {RegExp} [pattern] defaults to {@link PasswordPatterns#CHAR8_ONE_OF_EACH}
3675
+ * @param {RegExp} [pattern] defaults to {@link DEFAULT_PATTERNS#CHAR8_ONE_OF_EACH}
2830
3676
  * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES#PASSWORD}
2831
- * @param {Constructor<Validator>} [validator] Defaults to {@link PasswordValidator}
2832
3677
  *
2833
3678
  * @function password
2834
3679
  *
2835
- * @memberOf module:decorator-validation.Decorators.Validation
2836
3680
  * @category Decorators
2837
3681
  */
2838
3682
  function password(pattern = DEFAULT_PATTERNS.PASSWORD.CHAR8_ONE_OF_EACH, message = DEFAULT_ERROR_MESSAGES.PASSWORD) {
2839
- return propMetadata(Validation.key(ValidationKeys.PASSWORD), {
3683
+ const key = Validation.key(ValidationKeys.PASSWORD);
3684
+ return Decoration.for(key)
3685
+ .define(propMetadata(key, {
2840
3686
  [ValidationKeys.PATTERN]: pattern,
2841
3687
  message: message,
2842
3688
  types: [String.name],
2843
- });
3689
+ }))
3690
+ .apply();
2844
3691
  }
2845
3692
  /**
2846
3693
  * @summary List Decorator
@@ -2849,19 +3696,20 @@ function password(pattern = DEFAULT_PATTERNS.PASSWORD.CHAR8_ONE_OF_EACH, message
2849
3696
  * @param {ModelConstructor} clazz
2850
3697
  * @param {string} [collection] The collection being used. defaults to Array
2851
3698
  * @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#LIST}
2852
- * @param {Constructor<Validator>} [validator] defaults to {@link ListValidator}
2853
3699
  *
2854
3700
  * @function list
2855
3701
  *
2856
- * @memberOf module:decorator-validation.Decorators.Validation
2857
3702
  * @category Decorators
2858
3703
  */
2859
3704
  function list(clazz, collection = "Array", message = DEFAULT_ERROR_MESSAGES.LIST) {
2860
- return propMetadata(Validation.key(ValidationKeys.LIST), {
3705
+ const key = Validation.key(ValidationKeys.LIST);
3706
+ return Decoration.for(key)
3707
+ .define(propMetadata(key, {
2861
3708
  clazz: Array.isArray(clazz) ? clazz.map((c) => c.name) : [clazz.name],
2862
3709
  type: collection,
2863
3710
  message: message,
2864
- });
3711
+ }))
3712
+ .apply();
2865
3713
  }
2866
3714
  /**
2867
3715
  * @summary Set Decorator
@@ -2869,11 +3717,9 @@ function list(clazz, collection = "Array", message = DEFAULT_ERROR_MESSAGES.LIST
2869
3717
  *
2870
3718
  * @param {ModelConstructor} clazz
2871
3719
  * @param {string} [message] defaults to {@link DEFAULT_ERROR_MESSAGES#LIST}
2872
- * @param {Constructor<Validator>} [validator]
2873
3720
  *
2874
3721
  * @function set
2875
3722
  *
2876
- * @memberOf module:decorator-validation.Decorators.Validation
2877
3723
  * @category Decorators
2878
3724
  */
2879
3725
  function set(clazz, message = DEFAULT_ERROR_MESSAGES.LIST) {
@@ -3008,7 +3854,7 @@ function gte(propertyToCompare, message = DEFAULT_ERROR_MESSAGES.GREATER_THAN_OR
3008
3854
  * @return {T} the new instance
3009
3855
  *
3010
3856
  * @function construct
3011
- * @memberOf module:decorator-validation.Construction
3857
+ * @memberOf module:decorator-validation
3012
3858
  */
3013
3859
  function construct(constructor, ...args) {
3014
3860
  const _constr = (...argz) => new constructor(...argz);
@@ -3020,7 +3866,7 @@ function construct(constructor, ...args) {
3020
3866
  * @param {object} obj
3021
3867
  *
3022
3868
  * @function findLastProtoBeforeObject
3023
- * @memberOf module:decorator-validation.Construction
3869
+ * @memberOf module:decorator-validation
3024
3870
  */
3025
3871
  function findLastProtoBeforeObject(obj) {
3026
3872
  let prototype = Object.getPrototypeOf(obj);
@@ -3041,7 +3887,7 @@ function findLastProtoBeforeObject(obj) {
3041
3887
  * @param {unknown} obj
3042
3888
  *
3043
3889
  * @function bindModelPrototype
3044
- * @memberOf module:decorator-validation.Construction
3890
+ * @memberOf module:decorator-validation
3045
3891
  */
3046
3892
  function bindModelPrototype(obj) {
3047
3893
  if (obj instanceof Model)
@@ -3076,8 +3922,7 @@ function bindModelPrototype(obj) {
3076
3922
  *
3077
3923
  * @function model
3078
3924
  *
3079
- * @memberOf module:decorator-validation.Model
3080
- *
3925
+ * @category Decorators
3081
3926
  */
3082
3927
  function model(instanceCallback) {
3083
3928
  return ((original) => {
@@ -3096,6 +3941,9 @@ function model(instanceCallback) {
3096
3941
  };
3097
3942
  // copy prototype so instanceof operator still works
3098
3943
  newConstructor.prototype = original.prototype;
3944
+ Reflect.getMetadataKeys(original).forEach((key) => {
3945
+ Reflect.defineMetadata(key, Reflect.getMetadata(key, original), newConstructor);
3946
+ });
3099
3947
  // Sets the proper constructor name for type verification
3100
3948
  Object.defineProperty(newConstructor, "name", {
3101
3949
  writable: false,
@@ -3124,43 +3972,12 @@ function serializedBy(serializer, ...args) {
3124
3972
 
3125
3973
  /**
3126
3974
  * @module decorator-validation
3975
+ * @description TypeScript decorator-based validation library
3976
+ * @summary This module provides a comprehensive validation framework using TypeScript decorators.
3977
+ * It exposes utility functions, validation decorators, and model-related functionality for
3978
+ * implementing type-safe, declarative validation in TypeScript applications.
3127
3979
  */
3128
- /**
3129
- * @summary Model definition functionality
3130
- * @description defines the base class and related functionality
3131
- *
3132
- * @namespace Model
3133
- * @memberOf module:decorator-validation
3134
- */
3135
- /**
3136
- * @summary Holds all the supported decorators
3137
- * @namespace Decorators
3138
- * @memberOf module:decorator-validation
3139
- */
3140
- /**
3141
- * @summary Validation related functionality
3142
- * @description Defines the Model validation apis and base classes for validators
3143
- *
3144
- * @namespace Validation
3145
- * @memberOf module:decorator-validation
3146
- */
3147
- /**
3148
- * @namespace Dates
3149
- * @memberOf module:decorator-validation
3150
- */
3151
- /**
3152
- * @namespace Hashing
3153
- * @memberOf module:decorator-validation
3154
- */
3155
- /**
3156
- * @namespace Serialization
3157
- * @memberOf module:decorator-validation
3158
- */
3159
- /**
3160
- * @namespace Format
3161
- * @memberOf module:decorator-validation
3162
- */
3163
- const VERSION = "1.6.5";
3980
+ const VERSION = "1.7.1";
3164
3981
 
3165
- export { COMPARISON_ERROR_MESSAGES, ComparisonValidationKeys, DAYS_OF_WEEK_NAMES, DEFAULT_ERROR_MESSAGES, DEFAULT_PATTERNS, DateValidator, DefaultHashingMethod, DefaultSerializationMethod, DiffValidator, EmailValidator, EqualsValidator, GreaterThanOrEqualValidator, GreaterThanValidator, Hashing, JSONSerializer, LessThanOrEqualValidator, LessThanValidator, ListValidator, MONTH_NAMES, MaxLengthValidator, MaxValidator, MinLengthValidator, MinValidator, Model, ModelErrorDefinition, ModelKeys, ModelRegistryManager, PasswordValidator, PatternValidator, Primitives, RequiredValidator, ReservedModels, Serialization, StepValidator, TypeValidator, URLValidator, VALIDATION_PARENT_KEY, VERSION, Validation, ValidationKeys, Validator, ValidatorRegistry, bindDateToString, bindModelPrototype, bulkModelRegister, construct, date, dateFromFormat, diff, email, eq, findLastProtoBeforeObject, formatDate, getValueByPath, gt, gte, hashCode, hashObj, hashedBy, isGreaterThan, isLessThan, isModel, isPropertyModel, isValidDate, isValidForGteOrLteComparison, isValidator, jsTypes, list, lt, lte, max, maxlength, min, minlength, model, parseDate, password, pattern, prop, propMetadata, regexpParser, required, serializedBy, set, sf, step, stringFormat, twoDigitPad, type, url, validate, validator };
3166
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVjb3JhdG9yLXZhbGlkYXRpb24uZXNtLmNqcyIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbnN0YW50cy92YWxpZGF0aW9uLnRzIiwiLi4vc3JjL3V0aWxzL2NvbnN0YW50cy50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3V0aWxzL3N0cmluZ3MudHMiLCIuLi9zcmMvdXRpbHMvZGF0ZXMudHMiLCIuLi9zcmMvdXRpbHMvZGVjb3JhdG9ycy50cyIsIi4uL3NyYy91dGlscy9oYXNoaW5nLnRzIiwiLi4vc3JjL21vZGVsL01vZGVsRXJyb3JEZWZpbml0aW9uLnRzIiwiLi4vc3JjL21vZGVsL2NvbnN0YW50cy50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvVmFsaWRhdG9yUmVnaXN0cnkudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0aW9uLnRzIiwiLi4vc3JjL21vZGVsL3ZhbGlkYXRpb24udHMiLCIuLi9zcmMvbW9kZWwvTW9kZWwudHMiLCIuLi9zcmMvdXRpbHMvc2VyaWFsaXphdGlvbi50cyIsIi4uL25vZGVfbW9kdWxlcy90c2xpYi90c2xpYi5lczYuanMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL1ZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvZGVjb3JhdG9ycy50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvRGF0ZVZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvdXRpbHMudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL0RpZmZWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL1BhdHRlcm5WYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL0VtYWlsVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9FcXVhbHNWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL0dyZWF0ZXJUaGFuVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9HcmVhdGVyVGhhbk9yRXF1YWxWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL0xlc3NUaGFuVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9MZXNzVGhhbk9yRXF1YWxWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL0xpc3RWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL01heExlbmd0aFZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvTWF4VmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9NaW5MZW5ndGhWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL01pblZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvUGFzc3dvcmRWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL1JlcXVpcmVkVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9TdGVwVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9UeXBlVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9VUkxWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL21vZGVsL2NvbnN0cnVjdGlvbi50cyIsIi4uL3NyYy9tb2RlbC9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU3ltYm9sIHVzZWQgdG8gaW50ZXJuYWxseSB0cmFjayB0aGUgcGFyZW50IG9iamVjdCBkdXJpbmcgbmVzdGVkIHZhbGlkYXRpb24uXG4gKlxuICogVGhpcyBrZXkgaXMgYXR0YWNoZWQgdG8gY2hpbGQgb2JqZWN0cyB0byBwcm92aWRlIGNvbnRleHQgYWJvdXQgdGhlaXIgcGFyZW50XG4gKiBpbiB0aGUgb2JqZWN0IGhpZXJhcmNoeSwgZW5hYmxpbmcgdmFsaWRhdGlvbnMgdGhhdCBkZXBlbmQgb24gcGFyZW50IHZhbHVlcy5cbiAqXG4gKiBAY29uc3RhbnQgVkFMSURBVElPTl9QQVJFTlRfS0VZXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLk1vZGVsXG4gKi9cbmV4cG9ydCBjb25zdCBWQUxJREFUSU9OX1BBUkVOVF9LRVkgPSBTeW1ib2woXCJfdmFsaWRhdGlvblBhcmVudFJlZlwiKTtcbiIsIi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgdmFyaW91cyBNb2RlbCBrZXlzIHVzZWQgZm9yIHJlZmxlY3Rpb25cbiAqXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUkVGTEVDVCBwcmVmaXggdG8gYWxsIG90aGVyIGtleXNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBUWVBFIHR5cGUga2V5XG4gKiBAcHJvcGVydHkge3N0cmluZ30gUEFSQU1TIG1ldGhvZCBwYXJhbXMga2V5XG4gKiBAcHJvcGVydHkge3N0cmluZ30gUkVUVVJOIG1ldGhvZCByZXR1cm4ga2V5XG4gKiBAcHJvcGVydHkge3N0cmluZ30gTU9ERUwgbW9kZWwga2V5XG4gKiBAcHJvcGVydHkge3N0cmluZ30gQU5DSE9SIGFuY2hvciBrZXkuIHdpbGwgc2VydmUgYXMgYSBnaG9zdCBwcm9wZXJ0eSBpbiB0aGUgbW9kZWxcbiAqXG4gKiBAY29uc3RhbnQgTW9kZWxLZXlzXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLk1vZGVsXG4gKiBAY2F0ZWdvcnkgTW9kZWxcbiAqL1xuZXhwb3J0IGVudW0gTW9kZWxLZXlzIHtcbiAgUkVGTEVDVCA9IFwiZGVjYWYubW9kZWwuXCIsXG4gIFRZUEUgPSBcImRlc2lnbjp0eXBlXCIsXG4gIFBBUkFNUyA9IFwiZGVzaWduOnBhcmFtdHlwZXNcIixcbiAgUkVUVVJOID0gXCJkZXNpZ246cmV0dXJudHlwZVwiLFxuICBNT0RFTCA9IFwibW9kZWxcIixcbiAgQU5DSE9SID0gXCJfX21vZGVsXCIsXG4gIENPTlNUUlVDVElPTiA9IFwiY29uc3RydWN0ZWQtYnlcIixcbiAgQVRUUklCVVRFID0gXCJfX2F0dHJpYnV0ZXNcIixcbiAgSEFTSElORyA9IFwiaGFzaGluZ1wiLFxuICBTRVJJQUxJWkFUSU9OID0gXCJzZXJpYWxpemF0aW9uXCIsXG59XG4iLCJpbXBvcnQgeyBNb2RlbEtleXMgfSBmcm9tIFwiLi4vLi4vdXRpbHMvY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgS2V5cyB1c2VkIGZvciBjb21wYXJpc29uLWJhc2VkIHZhbGlkYXRpb25zLlxuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBFUVVBTFMgLSBWYWxpZGF0ZXMgaWYgdHdvIHZhbHVlcyBhcmUgZXF1YWwuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gRElGRiAtIFZhbGlkYXRlcyBpZiB0d28gdmFsdWVzIGFyZSBkaWZmZXJlbnQuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTEVTU19USEFOIC0gVmFsaWRhdGVzIGlmIGEgdmFsdWUgaXMgbGVzcyB0aGFuIGFub3RoZXIuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTEVTU19USEFOX09SX0VRVUFMIC0gVmFsaWRhdGVzIGlmIGEgdmFsdWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGFub3RoZXIuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gR1JFQVRFUl9USEFOIC0gVmFsaWRhdGVzIGlmIGEgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIGFub3RoZXIuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gR1JFQVRFUl9USEFOX09SX0VRVUFMIC0gVmFsaWRhdGVzIGlmIGEgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGFub3RoZXIuXG4gKlxuICogQGNvbnN0YW50IENvbXBhcmlzb25WYWxpZGF0aW9uS2V5c1xuICogQG1lbWJlcm9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5WYWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdGlvblxuICovXG5leHBvcnQgY29uc3QgQ29tcGFyaXNvblZhbGlkYXRpb25LZXlzID0ge1xuICBFUVVBTFM6IFwiZXF1YWxzXCIsXG4gIERJRkY6IFwiZGlmZmVyZW50XCIsXG4gIExFU1NfVEhBTjogXCJsZXNzVGhhblwiLFxuICBMRVNTX1RIQU5fT1JfRVFVQUw6IFwibGVzc1RoYW5PckVxdWFsXCIsXG4gIEdSRUFURVJfVEhBTjogXCJncmVhdGVyVGhhblwiLFxuICBHUkVBVEVSX1RIQU5fT1JfRVFVQUw6IFwiZ3JlYXRlclRoYW5PckVxdWFsXCIsXG59IGFzIGNvbnN0O1xuXG4vKipcbiAqIEBzdW1tYXJ5IFRoZSBrZXlzIHVzZWQgZm9yIHZhbGlkYXRpb25cbiAqXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUkVGTEVDVCBwcmVmaXhlcyBvdGhlcnNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBSRVFVSVJFRCBzZXRzIGFzIHJlcXVpcmVkXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUlOIGRlZmluZXMgbWluIHZhbHVlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUFYIGRlZmluZXMgbWF4IHZhbHVlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gU1RFUCBkZWZpbmVzIHN0ZXBcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBNSU5fTEVOR1RIIGRlZmluZXMgbWluIGxlbmd0aFxuICogQHByb3BlcnR5IHtzdHJpbmd9IE1BWF9MRU5HVEggZGVmaW5lcyBtYXggbGVuZ3RoXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUEFUVEVSTiBkZWZpbmVzIHBhdHRlcm5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBFTUFJTCBkZWZpbmVzIGVtYWlsXG4gKiBAcHJvcGVydHkge3N0cmluZ30gVVJMIGRlZmluZXMgdXJsXG4gKiBAcHJvcGVydHkge3N0cmluZ30gREFURSBkZWZpbmVzIGRhdGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBUWVBFIGRlZmluZXMgdHlwZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFBBU1NXT1JEIGRlZmluZXMgcGFzc3dvcmRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBMSVNUIGRlZmluZXMgbGlzdFxuICpcbiAqIEBjb25zdGFudCBWYWxpZGF0aW9uS2V5c1xuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5WYWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdGlvblxuICovXG5leHBvcnQgY29uc3QgVmFsaWRhdGlvbktleXMgPSB7XG4gIFJFRkxFQ1Q6IGAke01vZGVsS2V5cy5SRUZMRUNUfXZhbGlkYXRpb24uYCxcbiAgVkFMSURBVE9SOiBcInZhbGlkYXRvclwiLFxuICBSRVFVSVJFRDogXCJyZXF1aXJlZFwiLFxuICBNSU46IFwibWluXCIsXG4gIE1BWDogXCJtYXhcIixcbiAgU1RFUDogXCJzdGVwXCIsXG4gIE1JTl9MRU5HVEg6IFwibWlubGVuZ3RoXCIsXG4gIE1BWF9MRU5HVEg6IFwibWF4bGVuZ3RoXCIsXG4gIFBBVFRFUk46IFwicGF0dGVyblwiLFxuICBFTUFJTDogXCJlbWFpbFwiLFxuICBVUkw6IFwidXJsXCIsXG4gIERBVEU6IFwiZGF0ZVwiLFxuICBUWVBFOiBcInR5cGVcIixcbiAgUEFTU1dPUkQ6IFwicGFzc3dvcmRcIixcbiAgTElTVDogXCJsaXN0XCIsXG4gIEZPUk1BVDogXCJmb3JtYXRcIixcbiAgLi4uQ29tcGFyaXNvblZhbGlkYXRpb25LZXlzLFxufSBhcyBjb25zdDtcblxuLyoqXG4gKiBAc3VtbWFyeSBsaXN0IG9mIG1vbnRoIG5hbWVzXG4gKiBAZGVzY3JpcHRpb24gU3RvcmVzIG1vbnRoIG5hbWVzLiBDYW4gYmUgY2hhbmdlZCBmb3IgbG9jYWxpemF0aW9uIHB1cnBvc2VzXG4gKlxuICogQGNvbnN0YW50IE1PTlRIX05BTUVTXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBNT05USF9OQU1FUyA9IFtcbiAgXCJKYW51YXJ5XCIsXG4gIFwiRmVicnVhcnlcIixcbiAgXCJNYXJjaFwiLFxuICBcIkFwcmlsXCIsXG4gIFwiTWF5XCIsXG4gIFwiSnVuZVwiLFxuICBcIkp1bHlcIixcbiAgXCJBdWd1c3RcIixcbiAgXCJTZXB0ZW1iZXJcIixcbiAgXCJPY3RvYmVyXCIsXG4gIFwiTm92ZW1iZXJcIixcbiAgXCJEZWNlbWJlclwiLFxuXTtcblxuLyoqXG4gKiBAc3VtbWFyeSBsaXN0IG9mIG5hbWVzIG9mIGRheXMgb2YgdGhlIHdlZWtcbiAqIEBkZXNjcmlwdGlvbiBTdG9yZXMgbmFtZXMgZm9yIGRheXMgb2YgdGhlIHdlZWsuIENhbiBiZSBjaGFuZ2VkIGZvciBsb2NhbGl6YXRpb24gcHVycG9zZXNcbiAqXG4gKiBAY29uc3RhbnQgREFZU19PRl9XRUVLX05BTUVTXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBEQVlTX09GX1dFRUtfTkFNRVMgPSBbXG4gIFwiU3VuZGF5XCIsXG4gIFwiTW9uZGF5XCIsXG4gIFwiVHVlc2RheVwiLFxuICBcIldlZG5lc2RheVwiLFxuICBcIlRodXJzZGF5XCIsXG4gIFwiRnJpZGF5XCIsXG4gIFwiU2F0dXJkYXlcIixcbl07XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgZGVmYXVsdCBlcnJvciBtZXNzYWdlc1xuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBSRVFVSVJFRCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBNSU4gZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUFYIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IE1JTl9MRU5HVEggZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUFYX0xFTkdUSCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBQQVRURVJOIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IEVNQUlMIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFVSTCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBUWVBFIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFNURVAgZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gREFURSBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBERUZBVUxUIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFBBU1NXT1JEIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IExJU1QgZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTElTVF9JTlNJREUgZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTU9ERUxfTk9UX0ZPVU5EIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICpcbiAqIEBjb25zdGFudCBERUZBVUxUX0VSUk9SX01FU1NBR0VTXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0VSUk9SX01FU1NBR0VTOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICBSRVFVSVJFRDogXCJUaGlzIGZpZWxkIGlzIHJlcXVpcmVkXCIsXG4gIE1JTjogXCJUaGUgbWluaW11bSB2YWx1ZSBpcyB7MH1cIixcbiAgTUFYOiBcIlRoZSBtYXhpbXVtIHZhbHVlIGlzIHswfVwiLFxuICBNSU5fTEVOR1RIOiBcIlRoZSBtaW5pbXVtIGxlbmd0aCBpcyB7MH1cIixcbiAgTUFYX0xFTkdUSDogXCJUaGUgbWF4aW11bSBsZW5ndGggaXMgezB9XCIsXG4gIFBBVFRFUk46IFwiVGhlIHZhbHVlIGRvZXMgbm90IG1hdGNoIHRoZSBwYXR0ZXJuXCIsXG4gIEVNQUlMOiBcIlRoZSB2YWx1ZSBpcyBub3QgYSB2YWxpZCBlbWFpbFwiLFxuICBVUkw6IFwiVGhlIHZhbHVlIGlzIG5vdCBhIHZhbGlkIFVSTFwiLFxuICBUWVBFOiBcIkludmFsaWQgdHlwZS4gRXhwZWN0ZWQgezB9LCByZWNlaXZlZCB7MX1cIixcbiAgU1RFUDogXCJJbnZhbGlkIHZhbHVlLiBOb3QgYSBzdGVwIG9mIHswfVwiLFxuICBEQVRFOiBcIkludmFsaWQgdmFsdWUuIG5vdCBhIHZhbGlkIERhdGVcIixcbiAgREVGQVVMVDogXCJUaGVyZSBpcyBhbiBFcnJvclwiLFxuICBQQVNTV09SRDpcbiAgICBcIk11c3QgYmUgYXQgbGVhc3QgOCBjaGFyYWN0ZXJzIGFuZCBjb250YWluIG9uZSBvZiBudW1iZXIsIGxvd2VyIGFuZCB1cHBlciBjYXNlIGxldHRlcnMsIGFuZCBzcGVjaWFsIGNoYXJhY3RlciAoQCQhJSo/Jl8tLiwpXCIsXG4gIExJU1Q6IFwiSW52YWxpZCBsaXN0IG9mIHswfVwiLFxuICBNT0RFTF9OT1RfRk9VTkQ6IFwiTm8gbW9kZWwgcmVnaXN0ZXJlZCB1bmRlciB7MH1cIixcbiAgRVFVQUxTOiBcIlRoaXMgZmllbGQgbXVzdCBiZSBlcXVhbCB0byBmaWVsZCB7MH1cIixcbiAgRElGRjogXCJUaGlzIGZpZWxkIG11c3QgYmUgZGlmZmVyZW50IGZyb20gZmllbGQgezB9XCIsXG4gIExFU1NfVEhBTjogXCJUaGlzIGZpZWxkIG11c3QgYmUgbGVzcyB0aGFuIGZpZWxkIHswfVwiLFxuICBMRVNTX1RIQU5fT1JfRVFVQUw6IFwiVGhpcyBmaWVsZCBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byBmaWVsZCB7MH1cIixcbiAgR1JFQVRFUl9USEFOOiBcIlRoaXMgZmllbGQgbXVzdCBiZSBncmVhdGVyIHRoYW4gZmllbGQgezB9XCIsXG4gIEdSRUFURVJfVEhBTl9PUl9FUVVBTDpcbiAgICBcIlRoaXMgZmllbGQgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gZmllbGQgezB9XCIsXG59O1xuXG5leHBvcnQgY29uc3QgQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUyA9IHtcbiAgSU5WQUxJRF9QQVRIOlxuICAgIFwiSW52YWxpZCBwYXRoIGFyZ3VtZW50LiBFeHBlY3RlZCBub24tZW1wdHkgc3RyaW5nIGJ1dCByZWNlaXZlZDogJ3swfSdcIixcbiAgQ09OVEVYVF9OT1RfT0JKRUNUX0NPTVBBUklTT046XG4gICAgXCJVbmFibGUgdG8gYWNjZXNzIHBhcmVudCBhdCBsZXZlbCB7MH0gZm9yIHBhdGggJ3sxfSc6IGN1cnJlbnQgY29udGV4dCBpcyBub3QgYW4gb2JqZWN0XCIsXG4gIE5PX1BBUkVOVF9DT01QQVJJU09OOlxuICAgIFwiVW5hYmxlIHRvIGFjY2VzcyBwYXJlbnQgYXQgbGV2ZWwgezB9IGZvciBwYXRoICd7MX0nOiBubyBwYXJlbnQgYXZhaWxhYmxlXCIsXG4gIFBST1BFUlRZX05PVF9GT1VORDpcbiAgICBcIkZhaWxlZCB0byByZXNvbHZlIHBhdGggezB9OiBwcm9wZXJ0eSAnezF9JyBkb2VzIG5vdCBleGlzdC5cIixcbiAgUFJPUEVSVFlfTk9UX0ZPVU5EX09OX1BBUkVOVDpcbiAgICBcIkZhaWxlZCB0byByZXNvbHZlIHBhdGggezB9OiBwcm9wZXJ0eSAnezF9JyBkb2VzIG5vdCBleGlzdCBvbiBwYXJlbnQuXCIsXG4gIFBST1BFUlRZX05PVF9GT1VORF9BRlRFUl9QQVJFTlQ6XG4gICAgXCJGYWlsZWQgdG8gcmVzb2x2ZSBwYXRoIHswfTogcHJvcGVydHkgJ3sxfScgZG9lcyBub3QgZXhpc3QgYWZ0ZXIgezJ9IHBhcmVudCBsZXZlbChzKS5cIixcbiAgVU5TVVBQT1JURURfVFlQRVNfQ09NUEFSSVNPTjpcbiAgICBcIlVuc3VwcG9ydGVkIHR5cGVzIGZvciBjb21wYXJpc29uOiAnezB9JyBhbmQgJ3sxfSdcIixcbiAgTlVMTF9PUl9VTkRFRklORURfQ09NUEFSSVNPTjpcbiAgICBcIkNvbXBhcmlzb24gZmFpbGVkIGR1ZSB0byBudWxsIG9yIHVuZGVmaW5lZCB2YWx1ZVwiLFxuICBJTlZBTElEX0RBVEVfQ09NUEFSSVNPTjogXCJJbnZhbGlkIERhdGUgb2JqZWN0cyBhcmUgbm90IGNvbXBhcmFibGVcIixcbiAgVFlQRV9NSVNNQVRDSF9DT01QQVJJU09OOlxuICAgIFwiQ2Fubm90IGNvbXBhcmUgdmFsdWVzIG9mIGRpZmZlcmVudCB0eXBlczogezB9IGFuZCB7MX0uXCIsXG4gIE5BTl9DT01QQVJJU09OOiBcIkNvbXBhcmlzb24gbm90IHN1cHBvcnRlZCBmb3IgTmFOIHZhbHVlc1wiLFxufTtcblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSB2YXJpb3VzIGRlZmF1bHQgcmVnZXhwIHBhdHRlcm5zIHVzZWRcbiAqXG4gKiBAZW51bSBERUZBVUxUX1BBVFRFUk5TXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX1BBVFRFUk5TID0ge1xuICBFTUFJTDpcbiAgICAvW2EtekEtWjAtOSEjJCUmJyorLz0/Xl9ge3x9fi1dKyg/OlxcLlthLXpBLVowLTkhIyQlJicqKy89P15fYHt8fX4tXSspKkAoPzpbYS16QS1aMC05XSg/OlthLXowLTktXSpbYS16QS1aMC05XSk/XFwuKStbYS16QS1aMC05XSg/OlthLXpBLVowLTktXSpbYS16QS1aMC05XSk/LyxcbiAgVVJMOiAvXig/Oig/Oig/Omh0dHBzP3xmdHApOik/XFwvXFwvKSg/OlxcUysoPzo6XFxTKik/QCk/KD86KD8hKD86MTB8MTI3KSg/OlxcLlxcZHsxLDN9KXszfSkoPyEoPzoxNjlcXC4yNTR8MTkyXFwuMTY4KSg/OlxcLlxcZHsxLDN9KXsyfSkoPyExNzJcXC4oPzoxWzYtOV18MlxcZHwzWzAtMV0pKD86XFwuXFxkezEsM30pezJ9KSg/OlsxLTldXFxkP3wxXFxkXFxkfDJbMDFdXFxkfDIyWzAtM10pKD86XFwuKD86MT9cXGR7MSwyfXwyWzAtNF1cXGR8MjVbMC01XSkpezJ9KD86XFwuKD86WzEtOV1cXGQ/fDFcXGRcXGR8MlswLTRdXFxkfDI1WzAtNF0pKXwoPzooPzpbYS16MC05XFx1MDBhMS1cXHVmZmZmXVthLXowLTlcXHUwMGExLVxcdWZmZmZfLV17MCw2Mn0pP1thLXowLTlcXHUwMGExLVxcdWZmZmZdXFwuKSsoPzpbYS16XFx1MDBhMS1cXHVmZmZmXXsyLH1cXC4/KSkoPzo6XFxkezIsNX0pPyg/OlsvPyNdXFxTKik/JC9pLFxuICBQQVNTV09SRDoge1xuICAgIENIQVI4X09ORV9PRl9FQUNIOlxuICAgICAgL14oPz0uKlthLXpdKSg/PS4qW0EtWl0pKD89LipcXGQpKD89LipbQCQhJSo/Jl9cXC0uLF0pW0EtWmEtelxcZEAkISUqPyZfXFwtLixdezgsfSQvZyxcbiAgfSxcbn07XG4iLCIvKipcbiAqIEBzdW1tYXJ5IFV0aWwgZnVuY3Rpb24gdG8gcHJvdmlkZSBzdHJpbmcgZm9ybWF0IGZ1bmN0aW9uYWxpdHkgc2ltaWxhciB0byBDIydzIHN0cmluZy5mb3JtYXRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZyB8IG51bWJlcj59IFthcmdzXSByZXBsYWNlbWVudHMgbWFkZSBieSBvcmRlciBvZiBhcHBlYXJhbmNlIChyZXBsYWNlbWVudDAgd2lsIHJlcGxhY2UgezB9IGFuZCBzbyBvbilcbiAqIEByZXR1cm4ge3N0cmluZ30gZm9ybWF0dGVkIHN0cmluZ1xuICpcbiAqIEBmdW5jdGlvbiBzdHJpbmdGb3JtYXRcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uVXRpbHMuRm9ybWF0XG4gKiBAY2F0ZWdvcnkgRm9ybWF0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdHJpbmdGb3JtYXQoc3RyaW5nOiBzdHJpbmcsIC4uLmFyZ3M6IChzdHJpbmcgfCBudW1iZXIpW10pIHtcbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC97KFxcZCspfS9nLCBmdW5jdGlvbiAobWF0Y2gsIG51bWJlcikge1xuICAgIHJldHVybiB0eXBlb2YgYXJnc1tudW1iZXJdICE9PSBcInVuZGVmaW5lZFwiXG4gICAgICA/IGFyZ3NbbnVtYmVyXS50b1N0cmluZygpXG4gICAgICA6IFwidW5kZWZpbmVkXCI7XG4gIH0pO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFV0aWwgZnVuY3Rpb24gdG8gcHJvdmlkZSBzdHJpbmcgZm9ybWF0IGZ1bmN0aW9uYWxpdHkgc2ltaWxhciB0byBDIydzIHN0cmluZy5mb3JtYXRcbiAqIEBkZXNjcmlwdGlvbiBhbGlhcyBmb3Ige0BsaW5rIHN0cmluZ0Zvcm1hdH1cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nXG4gKiBAcGFyYW0ge3N0cmluZ30gYXJncyByZXBsYWNlbWVudHMgbWFkZSBieSBvcmRlciBvZiBhcHBlYXJhbmNlIChyZXBsYWNlbWVudDAgd2lsIHJlcGxhY2UgezB9IGFuZCBzbyBvbilcbiAqIEByZXR1cm4ge3N0cmluZ30gZm9ybWF0dGVkIHN0cmluZ1xuICpcbiAqIEBmdW5jdGlvbiBzZlxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5VdGlscy5Gb3JtYXRcbiAqIEBjYXRlZ29yeSBGb3JtYXRcbiAqL1xuZXhwb3J0IGNvbnN0IHNmID0gc3RyaW5nRm9ybWF0O1xuIiwiaW1wb3J0IFwicmVmbGVjdC1tZXRhZGF0YVwiO1xuaW1wb3J0IHtcbiAgREFZU19PRl9XRUVLX05BTUVTLFxuICBNT05USF9OQU1FUyxcbn0gZnJvbSBcIi4uL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9jb25zdGFudHNcIjtcbmltcG9ydCB7IHNmIH0gZnJvbSBcIi4vc3RyaW5nc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFJldmVyc2VzIHRoZSBwcm9jZXNzIGZyb20ge0BsaW5rIGZvcm1hdERhdGV9XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGRhdGUgdGhlIGRhdGUgc3RyaW5nIHRvIGJlIGNvbnZlcnRlZCBiYWNrIGludG8gZGF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IGZvcm1hdCB0aGUgZGF0ZSBmb3JtYXRcbiAqIEByZXR1cm4ge0RhdGV9IHRoZSBkYXRlIGZyb20gdGhlIGZvcm1hdCBvciB0aGUgc3RhbmRhcmQgbmV3IERhdGUoe0Bwcm9wIGRhdGV9KSBpZiB0aGUgc3RyaW5nIGNvdWxkbid0IGJlIHBhcnNlZCAoYXJlIHlvdSBzdXJlIHRoZSBmb3JtYXQgbWF0Y2hlcyB0aGUgc3RyaW5nPylcbiAqXG4gKiBAZnVuY3Rpb24gZGF0ZUZyb21Gb3JtYXRcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uVXRpbHMuRGF0ZXNcbiAqIEBjYXRlZ29yeSBGb3JtYXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRhdGVGcm9tRm9ybWF0KGRhdGU6IHN0cmluZywgZm9ybWF0OiBzdHJpbmcpIHtcbiAgbGV0IGZvcm1hdFJlZ2V4cDogc3RyaW5nID0gZm9ybWF0O1xuXG4gIC8vIEhvdXJcbiAgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgvaGgvKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcImhoXCIsIFwiKD88aG91cj5cXFxcZHsyfSlcIik7XG4gIGVsc2UgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgvaC8pKVxuICAgIGZvcm1hdFJlZ2V4cCA9IGZvcm1hdFJlZ2V4cC5yZXBsYWNlKFwiaFwiLCBcIig/PGhvdXI+XFxcXGR7MSwyfSlcIik7XG4gIGVsc2UgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgvSEgvKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcIkhIXCIsIFwiKD88aG91cj5cXFxcZHsyfSlcIik7XG4gIGVsc2UgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgvSC8pKVxuICAgIGZvcm1hdFJlZ2V4cCA9IGZvcm1hdFJlZ2V4cC5yZXBsYWNlKFwiSFwiLCBcIig/PGhvdXI+XFxcXGR7MSwyfSlcIik7XG5cbiAgLy8gTWludXRlc1xuICBpZiAoZm9ybWF0UmVnZXhwLm1hdGNoKC9tbS8pKVxuICAgIGZvcm1hdFJlZ2V4cCA9IGZvcm1hdFJlZ2V4cC5yZXBsYWNlKFwibW1cIiwgXCIoPzxtaW51dGVzPlxcXFxkezJ9KVwiKTtcbiAgZWxzZSBpZiAoZm9ybWF0UmVnZXhwLm1hdGNoKC9tLykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJtXCIsIFwiKD88bWludXRlcz5cXFxcZHsxLDJ9KVwiKTtcblxuICAvLyBTZWNvbmRzXG4gIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL3NzLykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJzc1wiLCBcIig/PHNlY29uZHM+XFxcXGR7Mn0pXCIpO1xuICBlbHNlIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL3MvKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcInNcIiwgXCIoPzxzZWNvbmRzPlxcXFxkezEsMn0pXCIpO1xuXG4gIC8vIERheVxuICBpZiAoZm9ybWF0UmVnZXhwLm1hdGNoKC9kZC8pKVxuICAgIGZvcm1hdFJlZ2V4cCA9IGZvcm1hdFJlZ2V4cC5yZXBsYWNlKFwiZGRcIiwgXCIoPzxkYXk+XFxcXGR7Mn0pXCIpO1xuICBlbHNlIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL2QvKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcImRcIiwgXCIoPzxkYXk+XFxcXGR7MSwyfSlcIik7XG5cbiAgLy8gRGF5IE9mIFdlZWtcbiAgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgvRUVFRS8pKVxuICAgIGZvcm1hdFJlZ2V4cCA9IGZvcm1hdFJlZ2V4cC5yZXBsYWNlKFwiRUVFRVwiLCBcIig/PGRheW9md2Vlaz5cXFxcdyspXCIpO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZHVwZS1lbHNlLWlmXG4gIGVsc2UgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgvRUVFRS8pKVxuICAgIGZvcm1hdFJlZ2V4cCA9IGZvcm1hdFJlZ2V4cC5yZXBsYWNlKFwiRUVFXCIsIFwiKD88ZGF5b2Z3ZWVrPlxcXFx3KylcIik7XG5cbiAgLy8gWWVhclxuICBpZiAoZm9ybWF0UmVnZXhwLm1hdGNoKC95eXl5LykpXG4gICAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwLnJlcGxhY2UoXCJ5eXl5XCIsIFwiKD88eWVhcj5cXFxcZHs0fSlcIik7XG4gIGVsc2UgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgveXkvKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcInl5XCIsIFwiKD88eWVhcj5cXFxcZHsyfSlcIik7XG5cbiAgLy8gTW9udGhcbiAgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgvTU1NTS8pKVxuICAgIGZvcm1hdFJlZ2V4cCA9IGZvcm1hdFJlZ2V4cC5yZXBsYWNlKFwiTU1NTVwiLCBcIig/PG1vbnRobmFtZT5cXFxcdyspXCIpO1xuICBlbHNlIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL01NTS8pKVxuICAgIGZvcm1hdFJlZ2V4cCA9IGZvcm1hdFJlZ2V4cC5yZXBsYWNlKFwiTU1NXCIsIFwiKD88bW9udGhuYW1lc21hbGw+XFxcXHcrKVwiKTtcbiAgaWYgKGZvcm1hdFJlZ2V4cC5tYXRjaCgvTU0vKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcIk1NXCIsIFwiKD88bW9udGg+XFxcXGR7Mn0pXCIpO1xuICBlbHNlIGlmIChmb3JtYXRSZWdleHAubWF0Y2goL00vKSlcbiAgICBmb3JtYXRSZWdleHAgPSBmb3JtYXRSZWdleHAucmVwbGFjZShcIk1cIiwgXCIoPzxtb250aD5cXFxcZHsxLDJ9KVwiKTtcblxuICAvLyBNaWxpcyBhbmQgQW0gUG1cbiAgZm9ybWF0UmVnZXhwID0gZm9ybWF0UmVnZXhwXG4gICAgLnJlcGxhY2UoXCJTXCIsIFwiKD88bWlsaXM+XFxcXGR7MSwzfSlcIilcbiAgICAucmVwbGFjZShcImFhYVwiLCBcIig/PGFtcG0+XFxcXHd7Mn0pXCIpO1xuXG4gIGNvbnN0IHJlZ2V4cCA9IG5ldyBSZWdFeHAoZm9ybWF0UmVnZXhwLCBcImdcIik7XG5cbiAgY29uc3QgbWF0Y2g6IHtcbiAgICBncm91cHM6IHtcbiAgICAgIHllYXI/OiBzdHJpbmc7XG4gICAgICBkYXk/OiBzdHJpbmc7XG4gICAgICBhbXBtPzogc3RyaW5nO1xuICAgICAgaG91cj86IHN0cmluZztcbiAgICAgIG1pbnV0ZXM/OiBzdHJpbmc7XG4gICAgICBzZWNvbmRzPzogc3RyaW5nO1xuICAgICAgbWlsaXM/OiBzdHJpbmc7XG4gICAgICBtb250aG5hbWU/OiBzdHJpbmc7XG4gICAgICBtb250aG5hbWVzbWFsbD86IHN0cmluZztcbiAgICAgIG1vbnRoPzogc3RyaW5nO1xuICAgIH07XG4gIH0gPSByZWdleHAuZXhlYyhkYXRlKSBhcyBhbnk7XG5cbiAgaWYgKCFtYXRjaCB8fCAhbWF0Y2guZ3JvdXBzKSByZXR1cm4gbmV3IERhdGUoZGF0ZSk7XG5cbiAgY29uc3Qgc2FmZVBhcnNlSW50ID0gZnVuY3Rpb24gKG4/OiBzdHJpbmcpIHtcbiAgICBpZiAoIW4pIHJldHVybiAwO1xuICAgIGNvbnN0IHJlc3VsdCA9IHBhcnNlSW50KG4pO1xuXG4gICAgcmV0dXJuIGlzTmFOKHJlc3VsdCkgPyAwIDogcmVzdWx0O1xuICB9O1xuXG4gIGNvbnN0IHllYXIgPSBzYWZlUGFyc2VJbnQobWF0Y2guZ3JvdXBzLnllYXIpO1xuICBjb25zdCBkYXkgPSBzYWZlUGFyc2VJbnQobWF0Y2guZ3JvdXBzLmRheSk7XG5cbiAgY29uc3QgYW1QbSA9IG1hdGNoLmdyb3Vwcy5hbXBtO1xuICBsZXQgaG91ciA9IHNhZmVQYXJzZUludChtYXRjaC5ncm91cHMuaG91cik7XG5cbiAgaWYgKGFtUG0pIGhvdXIgPSBhbVBtID09PSBcIlBNXCIgPyBob3VyICsgMTIgOiBob3VyO1xuXG4gIGNvbnN0IG1pbnV0ZXMgPSBzYWZlUGFyc2VJbnQobWF0Y2guZ3JvdXBzLm1pbnV0ZXMpO1xuICBjb25zdCBzZWNvbmRzID0gc2FmZVBhcnNlSW50KG1hdGNoLmdyb3Vwcy5zZWNvbmRzKTtcbiAgY29uc3QgbXMgPSBzYWZlUGFyc2VJbnQobWF0Y2guZ3JvdXBzLm1pbGlzKTtcblxuICBjb25zdCBtb250aE5hbWUgPSBtYXRjaC5ncm91cHMubW9udGhuYW1lO1xuICBjb25zdCBtb250aE5hbWVTbWFsbCA9IG1hdGNoLmdyb3Vwcy5tb250aG5hbWVzbWFsbDtcbiAgbGV0IG1vbnRoOiBudW1iZXIgfCBzdHJpbmcgPSBtYXRjaC5ncm91cHMubW9udGggYXMgc3RyaW5nO1xuICBpZiAobW9udGhOYW1lKSBtb250aCA9IE1PTlRIX05BTUVTLmluZGV4T2YobW9udGhOYW1lKTtcbiAgZWxzZSBpZiAobW9udGhOYW1lU21hbGwpIHtcbiAgICBjb25zdCBtID0gTU9OVEhfTkFNRVMuZmluZCgobSkgPT5cbiAgICAgIG0udG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKG1vbnRoTmFtZVNtYWxsLnRvTG93ZXJDYXNlKCkpXG4gICAgKTtcbiAgICBpZiAoIW0pIHJldHVybiBuZXcgRGF0ZShkYXRlKTtcbiAgICBtb250aCA9IE1PTlRIX05BTUVTLmluZGV4T2YobSk7XG4gIH0gZWxzZSBtb250aCA9IHNhZmVQYXJzZUludChgJHttb250aH1gKTtcblxuICByZXR1cm4gbmV3IERhdGUoeWVhciwgbW9udGggLSAxLCBkYXksIGhvdXIsIG1pbnV0ZXMsIHNlY29uZHMsIG1zKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBCaW5kcyBhIGRhdGUgZm9ybWF0IHRvIGEgc3RyaW5nXG4gKiBAcGFyYW0ge0RhdGV9IFtkYXRlXVxuICogQHBhcmFtIHtzdHJpbmd9IFtmb3JtYXRdXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlV0aWxzLkZvcm1hdFxuICogQGNhdGVnb3J5IFV0aWxpdGllc1xuICovXG5leHBvcnQgZnVuY3Rpb24gYmluZERhdGVUb1N0cmluZyhkYXRlOiBEYXRlIHwgdW5kZWZpbmVkLCBmb3JtYXQ6IHN0cmluZykge1xuICBpZiAoIWRhdGUpIHJldHVybjtcbiAgY29uc3QgZnVuYyA9ICgpID0+IGZvcm1hdERhdGUoZGF0ZSwgZm9ybWF0KTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGRhdGUsIFwidG9JU09TdHJpbmdcIiwge1xuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgdmFsdWU6IGZ1bmMsXG4gIH0pO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZGF0ZSwgXCJ0b1N0cmluZ1wiLCB7XG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICB2YWx1ZTogZnVuYyxcbiAgfSk7XG4gIC8vIE9iamVjdC5zZXRQcm90b3R5cGVPZihkYXRlLCBEYXRlLnByb3RvdHlwZSk7XG4gIHJldHVybiBkYXRlO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IEhlbHBlciBmdW5jdGlvbiB0byBiZSB1c2VkIGluc3RlYWQgb2YgaW5zdGFuY2VPZiBEYXRlXG4gKiBAcGFyYW0gZGF0ZVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5VdGlscy5EYXRlc1xuICogQGNhdGVnb3J5IFZhbGlkYXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWREYXRlKGRhdGU6IGFueSk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIGRhdGUgJiZcbiAgICBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZGF0ZSkgPT09IFwiW29iamVjdCBEYXRlXVwiICYmXG4gICAgIU51bWJlci5pc05hTihkYXRlKVxuICApO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFV0aWwgZnVuY3Rpb24gdG8gcGFkIG51bWJlcnNcbiAqIEBwYXJhbSB7bnVtYmVyfSBudW1cbiAqXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKlxuICogQGZ1bmN0aW9uIHR3b0RpZ2l0UGFkXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlV0aWxzLkZvcm1hdFxuICogQGNhdGVnb3J5IEZvcm1hdFxuICovXG5leHBvcnQgZnVuY3Rpb24gdHdvRGlnaXRQYWQobnVtOiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gbnVtIDwgMTAgPyBcIjBcIiArIG51bSA6IG51bS50b1N0cmluZygpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERhdGUgRm9ybWF0IEhhbmRsaW5nXG4gKiBAZGVzY3JpcHRpb24gQ29kZSBmcm9tIHtAbGluayBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zNTUyNDYxL2hvdy10by1mb3JtYXQtYS1qYXZhc2NyaXB0LWRhdGV9XG4gKlxuICogPHByZT5cbiAqICAgICAgVXNpbmcgc2ltaWxhciBmb3JtYXR0aW5nIGFzIE1vbWVudC5qcywgQ2xhc3MgRGF0ZVRpbWVGb3JtYXR0ZXIgKEphdmEpLCBhbmQgQ2xhc3MgU2ltcGxlRGF0ZUZvcm1hdCAoSmF2YSksXG4gKiAgICAgIEkgaW1wbGVtZW50ZWQgYSBjb21wcmVoZW5zaXZlIHNvbHV0aW9uIGZvcm1hdERhdGUoZGF0ZSwgcGF0dGVyblN0cikgd2hlcmUgdGhlIGNvZGUgaXMgZWFzeSB0byByZWFkIGFuZCBtb2RpZnkuXG4gKiAgICAgIFlvdSBjYW4gZGlzcGxheSBkYXRlLCB0aW1lLCBBTS9QTSwgZXRjLlxuICpcbiAqICAgICAgRGF0ZSBhbmQgVGltZSBQYXR0ZXJuc1xuICogICAgICB5eSA9IDItZGlnaXQgeWVhcjsgeXl5eSA9IGZ1bGwgeWVhclxuICogICAgICBNID0gZGlnaXQgbW9udGg7IE1NID0gMi1kaWdpdCBtb250aDsgTU1NID0gc2hvcnQgbW9udGggbmFtZTsgTU1NTSA9IGZ1bGwgbW9udGggbmFtZVxuICogICAgICBFRUVFID0gZnVsbCB3ZWVrZGF5IG5hbWU7IEVFRSA9IHNob3J0IHdlZWtkYXkgbmFtZVxuICogICAgICBkID0gZGlnaXQgZGF5OyBkZCA9IDItZGlnaXQgZGF5XG4gKiAgICAgIGggPSBob3VycyBhbS9wbTsgaGggPSAyLWRpZ2l0IGhvdXJzIGFtL3BtOyBIID0gaG91cnM7IEhIID0gMi1kaWdpdCBob3Vyc1xuICogICAgICBtID0gbWludXRlczsgbW0gPSAyLWRpZ2l0IG1pbnV0ZXM7IGFhYSA9IEFNL1BNXG4gKiAgICAgIHMgPSBzZWNvbmRzOyBzcyA9IDItZGlnaXQgc2Vjb25kc1xuICogICAgICBTID0gbWlsaXNlY29uZHNcbiAqIDwvcHJlPlxuICpcbiAqIEBwYXJhbSB7RGF0ZX0gZGF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IFtwYXR0ZXJuU3RyXSBkZWZhdWx0cyB0byAneXl5eS9NTS9kZCdcbiAqIEByZXR1cm4ge3N0cmluZ30gdGhlIGZvcm1hdHRlZCBkYXRlXG4gKlxuICogQGZ1bmN0aW9uIGZvcm1hdERhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uVXRpbHMuRGF0ZXNcbiAqIEBjYXRlZ29yeSBGb3JtYXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdERhdGUoZGF0ZTogRGF0ZSwgcGF0dGVyblN0cjogc3RyaW5nID0gXCJ5eXl5L01NL2RkXCIpIHtcbiAgY29uc3QgZGF5OiBudW1iZXIgPSBkYXRlLmdldERhdGUoKSxcbiAgICBtb250aDogbnVtYmVyID0gZGF0ZS5nZXRNb250aCgpLFxuICAgIHllYXI6IG51bWJlciA9IGRhdGUuZ2V0RnVsbFllYXIoKSxcbiAgICBob3VyOiBudW1iZXIgPSBkYXRlLmdldEhvdXJzKCksXG4gICAgbWludXRlOiBudW1iZXIgPSBkYXRlLmdldE1pbnV0ZXMoKSxcbiAgICBzZWNvbmQ6IG51bWJlciA9IGRhdGUuZ2V0U2Vjb25kcygpLFxuICAgIG1pbGlzZWNvbmRzOiBudW1iZXIgPSBkYXRlLmdldE1pbGxpc2Vjb25kcygpLFxuICAgIGg6IG51bWJlciA9IGhvdXIgJSAxMixcbiAgICBoaDogc3RyaW5nID0gdHdvRGlnaXRQYWQoaCksXG4gICAgSEg6IHN0cmluZyA9IHR3b0RpZ2l0UGFkKGhvdXIpLFxuICAgIG1tOiBzdHJpbmcgPSB0d29EaWdpdFBhZChtaW51dGUpLFxuICAgIHNzOiBzdHJpbmcgPSB0d29EaWdpdFBhZChzZWNvbmQpLFxuICAgIGFhYTogc3RyaW5nID0gaG91ciA8IDEyID8gXCJBTVwiIDogXCJQTVwiLFxuICAgIEVFRUU6IHN0cmluZyA9IERBWVNfT0ZfV0VFS19OQU1FU1tkYXRlLmdldERheSgpXSxcbiAgICBFRUU6IHN0cmluZyA9IEVFRUUuc3Vic3RyKDAsIDMpLFxuICAgIGRkOiBzdHJpbmcgPSB0d29EaWdpdFBhZChkYXkpLFxuICAgIE06IG51bWJlciA9IG1vbnRoICsgMSxcbiAgICBNTTogc3RyaW5nID0gdHdvRGlnaXRQYWQoTSksXG4gICAgTU1NTTogc3RyaW5nID0gTU9OVEhfTkFNRVNbbW9udGhdLFxuICAgIE1NTTogc3RyaW5nID0gTU1NTS5zdWJzdHIoMCwgMyksXG4gICAgeXl5eTogc3RyaW5nID0geWVhciArIFwiXCIsXG4gICAgeXk6IHN0cmluZyA9IHl5eXkuc3Vic3RyKDIsIDIpO1xuICAvLyBjaGVja3MgdG8gc2VlIGlmIG1vbnRoIG5hbWUgd2lsbCBiZSB1c2VkXG4gIHBhdHRlcm5TdHIgPSBwYXR0ZXJuU3RyXG4gICAgLnJlcGxhY2UoXCJoaFwiLCBoaClcbiAgICAucmVwbGFjZShcImhcIiwgaC50b1N0cmluZygpKVxuICAgIC5yZXBsYWNlKFwiSEhcIiwgSEgpXG4gICAgLnJlcGxhY2UoXCJIXCIsIGhvdXIudG9TdHJpbmcoKSlcbiAgICAucmVwbGFjZShcIm1tXCIsIG1tKVxuICAgIC5yZXBsYWNlKFwibVwiLCBtaW51dGUudG9TdHJpbmcoKSlcbiAgICAucmVwbGFjZShcInNzXCIsIHNzKVxuICAgIC5yZXBsYWNlKFwic1wiLCBzZWNvbmQudG9TdHJpbmcoKSlcbiAgICAucmVwbGFjZShcIlNcIiwgbWlsaXNlY29uZHMudG9TdHJpbmcoKSlcbiAgICAucmVwbGFjZShcImRkXCIsIGRkKVxuICAgIC5yZXBsYWNlKFwiZFwiLCBkYXkudG9TdHJpbmcoKSlcblxuICAgIC5yZXBsYWNlKFwiRUVFRVwiLCBFRUVFKVxuICAgIC5yZXBsYWNlKFwiRUVFXCIsIEVFRSlcbiAgICAucmVwbGFjZShcInl5eXlcIiwgeXl5eSlcbiAgICAucmVwbGFjZShcInl5XCIsIHl5KVxuICAgIC5yZXBsYWNlKFwiYWFhXCIsIGFhYSk7XG4gIGlmIChwYXR0ZXJuU3RyLmluZGV4T2YoXCJNTU1cIikgPiAtMSkge1xuICAgIHBhdHRlcm5TdHIgPSBwYXR0ZXJuU3RyLnJlcGxhY2UoXCJNTU1NXCIsIE1NTU0pLnJlcGxhY2UoXCJNTU1cIiwgTU1NKTtcbiAgfSBlbHNlIHtcbiAgICBwYXR0ZXJuU3RyID0gcGF0dGVyblN0ci5yZXBsYWNlKFwiTU1cIiwgTU0pLnJlcGxhY2UoXCJNXCIsIE0udG9TdHJpbmcoKSk7XG4gIH1cbiAgcmV0dXJuIHBhdHRlcm5TdHI7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgUGFyc2VzIGEgZGF0ZSBmcm9tIGEgc3BlY2lmaWVkIGZvcm1hdFxuICogQHBhcmFtIHtzdHJpbmd9IGZvcm1hdFxuICogQHBhcmFtIHtzdHJpbmcgfCBEYXRlIHwgbnVtYmVyfSBbdl1cbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uVXRpbHMuRGF0ZXNcbiAqIEBjYXRlZ29yeSBGb3JtYXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlRGF0ZShmb3JtYXQ6IHN0cmluZywgdj86IHN0cmluZyB8IERhdGUgfCBudW1iZXIpIHtcbiAgbGV0IHZhbHVlOiBEYXRlIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gIGlmICghdikgcmV0dXJuIHVuZGVmaW5lZDtcblxuICBpZiAodiBpbnN0YW5jZW9mIERhdGUpXG4gICAgdHJ5IHtcbiAgICAgIHZhbHVlID0gZGF0ZUZyb21Gb3JtYXQoZm9ybWF0RGF0ZSh2IGFzIERhdGUsIGZvcm1hdCksIGZvcm1hdCk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIHNmKFwiQ291bGQgbm90IGNvbnZlcnQgZGF0ZSB7MH0gdG8gZm9ybWF0OiB7MX1cIiwgdi50b1N0cmluZygpLCBmb3JtYXQpXG4gICAgICApO1xuICAgIH1cbiAgZWxzZSBpZiAodHlwZW9mIHYgPT09IFwic3RyaW5nXCIpIHtcbiAgICB2YWx1ZSA9IGRhdGVGcm9tRm9ybWF0KHYsIGZvcm1hdCk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHYgPT09IFwibnVtYmVyXCIpIHtcbiAgICBjb25zdCBkID0gbmV3IERhdGUodik7XG4gICAgdmFsdWUgPSBkYXRlRnJvbUZvcm1hdChmb3JtYXREYXRlKGQsIGZvcm1hdCksIGZvcm1hdCk7XG4gIH0gZWxzZSBpZiAoaXNWYWxpZERhdGUodikpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgZCA9IG5ldyBEYXRlKHYpO1xuICAgICAgdmFsdWUgPSBkYXRlRnJvbUZvcm1hdChmb3JtYXREYXRlKGQsIGZvcm1hdCksIGZvcm1hdCk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBzZihcIkNvdWxkIG5vdCBjb252ZXJ0IGRhdGUgezB9IHRvIGZvcm1hdDogezF9XCIsIHYsIGZvcm1hdClcbiAgICAgICk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB2YWx1ZSBwcm92aWRlZCAke3Z9YCk7XG4gIH1cbiAgcmV0dXJuIGJpbmREYXRlVG9TdHJpbmcodmFsdWUsIGZvcm1hdCk7XG59XG4iLCJpbXBvcnQgeyBhcHBseSwgbWV0YWRhdGEgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IE1vZGVsS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gcHJvcChrZXk6IHN0cmluZyA9IE1vZGVsS2V5cy5BVFRSSUJVVEUpIHtcbiAgcmV0dXJuIChtb2RlbDogb2JqZWN0LCBwcm9wZXJ0eUtleT86IGFueSk6IHZvaWQgPT4ge1xuICAgIGxldCBwcm9wczogc3RyaW5nW107XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2RlbCwga2V5KSkge1xuICAgICAgcHJvcHMgPSAobW9kZWwgYXMgYW55KVtrZXldO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm9wcyA9IChtb2RlbCBhcyBhbnkpW2tleV0gPSBbXTtcbiAgICB9XG4gICAgaWYgKCFwcm9wcy5pbmNsdWRlcyhwcm9wZXJ0eUtleSBhcyBzdHJpbmcpKVxuICAgICAgcHJvcHMucHVzaChwcm9wZXJ0eUtleSBhcyBzdHJpbmcpO1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHJvcE1ldGFkYXRhPFY+KGtleTogc3RyaW5nLCB2YWx1ZTogVikge1xuICByZXR1cm4gYXBwbHkocHJvcCgpLCBtZXRhZGF0YTxWPihrZXksIHZhbHVlKSk7XG59XG4iLCIvKipcbiAqIEBzdW1tYXJ5IE1pbWljcyBKYXZhJ3MgU3RyaW5nJ3MgSGFzaCBpbXBsZW1lbnRhdGlvblxuICpcbiAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyIHwgc3ltYm9sIHwgRGF0ZX0gb2JqXG4gKiBAcmV0dXJuIHtudW1iZXJ9IGhhc2ggdmFsdWUgb2Ygb2JqXG4gKlxuICogQGZ1bmN0aW9uIGhhc2hDb2RlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlV0aWxzLkhhc2hpbmdcbiAqIEBjYXRlZ29yeSBIYXNoaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNoQ29kZShvYmo6IHN0cmluZyB8IG51bWJlciB8IHN5bWJvbCB8IERhdGUpOiBzdHJpbmcge1xuICBvYmogPSBTdHJpbmcob2JqKTtcbiAgbGV0IGhhc2ggPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGNoYXJhY3RlciA9IG9iai5jaGFyQ29kZUF0KGkpO1xuICAgIGhhc2ggPSAoaGFzaCA8PCA1KSAtIGhhc2ggKyBjaGFyYWN0ZXI7XG4gICAgaGFzaCA9IGhhc2ggJiBoYXNoOyAvLyBDb252ZXJ0IHRvIDMyYml0IGludGVnZXJcbiAgfVxuICByZXR1cm4gaGFzaC50b1N0cmluZygpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgdGVoIHR5cGUgZm9yIGEgSGFzaGluZyBmdW5jdGlvblxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5VdGlscy5IYXNoaW5nXG4gKiBAY2F0ZWdvcnkgSGFzaGluZ1xuICovXG5leHBvcnQgdHlwZSBIYXNoaW5nRnVuY3Rpb24gPSAodmFsdWU6IGFueSwgLi4uYXJnczogYW55W10pID0+IHN0cmluZztcblxuLyoqXG4gKiBAc3VtbWFyeSBIYXNoZXMgYW4gb2JqZWN0IGJ5IGNvbWJpbmluZyB0aGUgaGFzaCBvZiBhbGwgaXRzIHByb3BlcnRpZXNcbiAqXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IG9ialxuICogQHJldHVybiB7c3RyaW5nfSB0aGUgcmVzdWx0aW5nIGhhc2hcbiAqXG4gKiBAZnVuY3Rpb24gaGFzaE9ialxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5VdGlscy5IYXNoaW5nXG4gKiBAY2F0ZWdvcnkgSGFzaGluZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzaE9iaihvYmo6IFJlY29yZDxzdHJpbmcsIGFueT4gfCBhbnlbXSk6IHN0cmluZyB7XG4gIGNvbnN0IGhhc2hSZWR1Y2VyID0gZnVuY3Rpb24gKGg6IG51bWJlciB8IHN0cmluZywgZWw6IGFueSk6IHN0cmluZyB8IG51bWJlciB7XG4gICAgY29uc3QgZWxIYXNoID0gaGFzaEZ1bmN0aW9uKGVsKTtcblxuICAgIGlmICh0eXBlb2YgZWxIYXNoID09PSBcInN0cmluZ1wiKVxuICAgICAgcmV0dXJuIGhhc2hGdW5jdGlvbigoKGggYXMgc3RyaW5nKSB8fCBcIlwiKSArIGhhc2hGdW5jdGlvbihlbCkpO1xuXG4gICAgaCA9IGggfHwgMDtcbiAgICBoID0gKChoIGFzIG51bWJlcikgPDwgNSkgLSAoaCBhcyBudW1iZXIpICsgZWxIYXNoO1xuICAgIHJldHVybiBoICYgaDtcbiAgfTtcblxuICBjb25zdCBmdW5jOiBIYXNoaW5nRnVuY3Rpb24gPSBoYXNoQ29kZTtcblxuICBjb25zdCBoYXNoRnVuY3Rpb24gPSBmdW5jdGlvbiAodmFsdWU6IGFueSk6IHN0cmluZyB8IG51bWJlciB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIFwiXCI7XG4gICAgaWYgKFtcInN0cmluZ1wiLCBcIm51bWJlclwiLCBcInN5bWJvbFwiXS5pbmRleE9mKHR5cGVvZiB2YWx1ZSkgIT09IC0xKVxuICAgICAgcmV0dXJuIGZ1bmModmFsdWUudG9TdHJpbmcoKSk7XG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkgcmV0dXJuIGZ1bmModmFsdWUuZ2V0VGltZSgpKTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiB2YWx1ZS5yZWR1Y2UoaGFzaFJlZHVjZXIsIHVuZGVmaW5lZCk7XG4gICAgcmV0dXJuIChPYmplY3QudmFsdWVzKHZhbHVlKSBhcyAoc3RyaW5nIHwgbnVtYmVyKVtdKS5yZWR1Y2UoXG4gICAgICBoYXNoUmVkdWNlcixcbiAgICAgIHVuZGVmaW5lZCBhcyB1bmtub3duIGFzIHN0cmluZyB8IG51bWJlclxuICAgICk7XG4gIH07XG5cbiAgY29uc3QgcmVzdWx0ID0gT2JqZWN0LnZhbHVlcyhvYmopLnJlZHVjZShoYXNoUmVkdWNlciwgMCk7XG5cbiAgcmV0dXJuICh0eXBlb2YgcmVzdWx0ID09PSBcIm51bWJlclwiID8gTWF0aC5hYnMocmVzdWx0KSA6IHJlc3VsdCkudG9TdHJpbmcoKTtcbn1cblxuZXhwb3J0IGNvbnN0IERlZmF1bHRIYXNoaW5nTWV0aG9kID0gXCJkZWZhdWx0XCI7XG5cbmV4cG9ydCBjbGFzcyBIYXNoaW5nIHtcbiAgcHJpdmF0ZSBzdGF0aWMgY3VycmVudDogc3RyaW5nID0gRGVmYXVsdEhhc2hpbmdNZXRob2Q7XG5cbiAgcHJpdmF0ZSBzdGF0aWMgY2FjaGU6IFJlY29yZDxzdHJpbmcsIEhhc2hpbmdGdW5jdGlvbj4gPSB7XG4gICAgZGVmYXVsdDogaGFzaE9iaixcbiAgfTtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cblxuICBwcml2YXRlIHN0YXRpYyBnZXQoa2V5OiBzdHJpbmcpOiBhbnkge1xuICAgIGlmIChrZXkgaW4gdGhpcy5jYWNoZSkgcmV0dXJuIHRoaXMuY2FjaGVba2V5XTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIGhhc2hpbmcgbWV0aG9kIHJlZ2lzdGVyZWQgdW5kZXIgJHtrZXl9YCk7XG4gIH1cblxuICBzdGF0aWMgcmVnaXN0ZXIoXG4gICAga2V5OiBzdHJpbmcsXG4gICAgZnVuYzogSGFzaGluZ0Z1bmN0aW9uLFxuICAgIHNldERlZmF1bHQgPSBmYWxzZVxuICApOiB2b2lkIHtcbiAgICBpZiAoa2V5IGluIHRoaXMuY2FjaGUpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEhhc2hpbmcgbWV0aG9kICR7a2V5fSBhbHJlYWR5IHJlZ2lzdGVyZWRgKTtcbiAgICB0aGlzLmNhY2hlW2tleV0gPSBmdW5jO1xuICAgIGlmIChzZXREZWZhdWx0KSB0aGlzLmN1cnJlbnQgPSBrZXk7XG4gIH1cblxuICBzdGF0aWMgaGFzaChvYmo6IGFueSwgbWV0aG9kPzogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGlmICghbWV0aG9kKSByZXR1cm4gdGhpcy5nZXQodGhpcy5jdXJyZW50KShvYmosIC4uLmFyZ3MpO1xuICAgIHJldHVybiB0aGlzLmdldChtZXRob2QpKG9iaiwgLi4uYXJncyk7XG4gIH1cblxuICBzdGF0aWMgc2V0RGVmYXVsdChtZXRob2Q6IHN0cmluZykge1xuICAgIHRoaXMuY3VycmVudCA9IHRoaXMuZ2V0KG1ldGhvZCk7XG4gIH1cbn1cbiIsImltcG9ydCB7IE1vZGVsRXJyb3JzIH0gZnJvbSBcIi4uL3ZhbGlkYXRpb24vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBIZWxwZXIgQ2xhc3MgdG8gaG9sZCB0aGUgZXJyb3IgcmVzdWx0c1xuICogQGRlc2NyaXB0aW9uIGhvbGRzIGVycm9yIHJlc3VsdHMgaW4gYW4gJ2luZGV4YWJsZScgbWFubmVyXG4gKiB3aGlsZSBzdGlsbCBwcm92aWRpbmcgdGhlIHNhbWUgcmVzdWx0IG9uIHRvU3RyaW5nXG4gKlxuICogQHBhcmFtIHtNb2RlbEVycm9yc30gZXJyb3JzXG4gKlxuICogQGNsYXNzIE1vZGVsRXJyb3JEZWZpbml0aW9uXG4gKlxuICogQGNhdGVnb3J5IE1vZGVsXG4gKi9cbmV4cG9ydCBjbGFzcyBNb2RlbEVycm9yRGVmaW5pdGlvbiB7XG4gIFtpbmRleGVyOiBzdHJpbmddOlxuICAgIHwgUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPlxuICAgIHwgKCgpID0+IHN0cmluZyB8IHVuZGVmaW5lZCk7XG5cbiAgY29uc3RydWN0b3IoZXJyb3JzOiBNb2RlbEVycm9ycykge1xuICAgIGZvciAoY29uc3QgcHJvcCBpbiBlcnJvcnMpIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXJyb3JzLCBwcm9wKSAmJiBlcnJvcnNbcHJvcF0pXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzIGFzIGFueSwgcHJvcCwge1xuICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICB2YWx1ZTogZXJyb3JzW3Byb3BdLFxuICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IE91dHB1dHMgdGhlIGNsYXNzIHRvIGEgbmljZSByZWFkYWJsZSBzdHJpbmdcbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqL1xuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIGNvbnN0IHNlbGY6IGFueSA9IHRoaXMgYXMgYW55O1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhzZWxmKVxuICAgICAgLmZpbHRlcihcbiAgICAgICAgKGspID0+XG4gICAgICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNlbGYsIGspICYmXG4gICAgICAgICAgdHlwZW9mIHNlbGZba10gIT09IFwiZnVuY3Rpb25cIlxuICAgICAgKVxuICAgICAgLnJlZHVjZSgoYWNjdW06IHN0cmluZywgcHJvcCkgPT4ge1xuICAgICAgICBsZXQgcHJvcEVycm9yOiBzdHJpbmcgfCB1bmRlZmluZWQgPSBPYmplY3Qua2V5cyhzZWxmW3Byb3BdKS5yZWR1Y2UoXG4gICAgICAgICAgKHByb3BBY2N1bTogdW5kZWZpbmVkIHwgc3RyaW5nLCBrZXkpID0+IHtcbiAgICAgICAgICAgIGlmICghcHJvcEFjY3VtKSBwcm9wQWNjdW0gPSBzZWxmW3Byb3BdW2tleV07XG4gICAgICAgICAgICBlbHNlIHByb3BBY2N1bSArPSBgXFxuJHtzZWxmW3Byb3BdW2tleV19YDtcbiAgICAgICAgICAgIHJldHVybiBwcm9wQWNjdW07XG4gICAgICAgICAgfSxcbiAgICAgICAgICB1bmRlZmluZWRcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAocHJvcEVycm9yKSB7XG4gICAgICAgICAgcHJvcEVycm9yID0gYCR7cHJvcH0gLSAke3Byb3BFcnJvcn1gO1xuICAgICAgICAgIGlmICghYWNjdW0pIGFjY3VtID0gcHJvcEVycm9yO1xuICAgICAgICAgIGVsc2UgYWNjdW0gKz0gYFxcbiR7cHJvcEVycm9yfWA7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LCBcIlwiKTtcbiAgfVxufVxuIiwiLyoqXG4gKiBAc3VtbWFyeSBSZWZlcmVuY2VzIHRoZSByZWxldmFudCBKUyBwcmltaXRpdmVzXG4gKlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFNUUklORyByZWZlcmVuY2VzIHRoZSBzdHJpbmcgcHJpbWl0aXZlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTlVNQkVSIHJlZmVyZW5jZXMgdGhlIG51bWJlciBwcmltaXRpdmVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBCT09MRUFOIHJlZmVyZW5jZXMgdGhlIGJvb2xlYW4gcHJpbWl0aXZlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gQklHSU5UIHJlZmVyZW5jZXMgdGhlIGJpZ2ludCBwcmltaXRpdmVcbiAqXG4gKiBAY29uc3RhbnQgUHJpbWl0aXZlc1xuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5Nb2RlbFxuICovXG5leHBvcnQgZW51bSBQcmltaXRpdmVzIHtcbiAgU1RSSU5HID0gXCJzdHJpbmdcIixcbiAgTlVNQkVSID0gXCJudW1iZXJcIixcbiAgQk9PTEVBTiA9IFwiYm9vbGVhblwiLFxuICBCSUdJTlQgPSBcImJpZ2ludFwiLFxufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFJlZmVyZW5jZXMgdGhlIFJlc2VydmVkIG1vZGVsIG5hbWVzIHRvIGlnbm9yZSBkdXJpbmcgTW9kZWwgcmVidWlsZGluZ1xuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBTVFJJTkdcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBPQkpFQ1RcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBOVU1CRVJcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBCT09MRUFOXG4gKiBAcHJvcGVydHkge3N0cmluZ30gQklHSU5UXG4gKiBAcHJvcGVydHkge3N0cmluZ30gREFURVxuICpcbiAqIEBjb25zdGFudCBSZXNlcnZlZE1vZGVsc1xuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5Nb2RlbFxuICovXG5leHBvcnQgZW51bSBSZXNlcnZlZE1vZGVscyB7XG4gIFNUUklORyA9IFwic3RyaW5nXCIsXG4gIE9CSkVDVCA9IFwib2JqZWN0XCIsXG4gIE5VTUJFUiA9IFwibnVtYmVyXCIsXG4gIEJPT0xFQU4gPSBcImJvb2xlYW5cIixcbiAgQklHSU5UID0gXCJiaWdpbnRcIixcbiAgREFURSA9IFwiZGF0ZVwiLFxufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFJlZmVyZW5jZXMgdGhlIGJhc2ljIHN1cHBvcnRlZCBqcyB0eXBlc1xuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzdHJpbmdcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBhcnJheVxuICogQHByb3BlcnR5IHtzdHJpbmd9IG51bWJlclxuICogQHByb3BlcnR5IHtzdHJpbmd9IGJvb2xlYW5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzeW1ib2xcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBmdW5jdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IG9iamVjdFxuICogQHByb3BlcnR5IHtzdHJpbmd9IHVuZGVmaW5lZFxuICogQHByb3BlcnR5IHtzdHJpbmd9IG51bGxcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBCSUdJTlRcbiAqXG4gKiBAY29uc3RhbnQganNUeXBlc1xuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5Nb2RlbFxuICovXG5leHBvcnQgY29uc3QganNUeXBlcyA9IFtcbiAgXCJzdHJpbmdcIixcbiAgXCJhcnJheVwiLFxuICBcIm51bWJlclwiLFxuICBcImJvb2xlYW5cIixcbiAgXCJzeW1ib2xcIixcbiAgXCJmdW5jdGlvblwiLFxuICBcIm9iamVjdFwiLFxuICBcInVuZGVmaW5lZFwiLFxuICBcIm51bGxcIixcbiAgXCJiaWdpbnRcIixcbl07XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3JEZWZpbml0aW9uIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBJVmFsaWRhdG9yUmVnaXN0cnkgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB0eXBlIHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgRHVjayB0eXBpbmcgZm9yIFZhbGlkYXRvcnNcbiAqIEBmdW5jdGlvbiBpc1ZhbGlkYXRvclxuICogQHBhcmFtIHZhbFxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZGF0b3IodmFsOiBhbnkpIHtcbiAgcmV0dXJuIHZhbC5jb25zdHJ1Y3RvciAmJiB2YWxbXCJoYXNFcnJvcnNcIl07XG59XG5cbi8qKlxuICogQHN1bW1hcnkgQmFzZSBJbXBsZW1lbnRhdGlvbiBvZiBhIFZhbGlkYXRvciBSZWdpc3RyeVxuICpcbiAqIEBwcm9wIHtWYWxpZGF0b3JbXX0gW3ZhbGlkYXRvcnNdIHRoZSBpbml0aWFsIHZhbGlkYXRvcnMgdG8gcmVnaXN0ZXJcbiAqXG4gKiBAY2xhc3MgVmFsaWRhdG9yUmVnaXN0cnlcbiAqIEBpbXBsZW1lbnRzIElWYWxpZGF0b3JSZWdpc3RyeTxUPlxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBWYWxpZGF0b3JSZWdpc3RyeTxUIGV4dGVuZHMgVmFsaWRhdG9yPlxuICBpbXBsZW1lbnRzIElWYWxpZGF0b3JSZWdpc3RyeTxUPlxue1xuICBwcml2YXRlIGNhY2hlOiBhbnkgPSB7fTtcbiAgcHJpdmF0ZSBjdXN0b21LZXlDYWNoZTogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcblxuICBjb25zdHJ1Y3RvciguLi52YWxpZGF0b3JzOiAoVmFsaWRhdG9yRGVmaW5pdGlvbiB8IFZhbGlkYXRvcilbXSkge1xuICAgIHRoaXMuY3VzdG9tS2V5Q2FjaGUgPSB7fTtcbiAgICB0aGlzLnJlZ2lzdGVyKC4uLnZhbGlkYXRvcnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHJldHJpZXZlcyB0aGUgY3VzdG9tIGtleXNcbiAgICovXG4gIGdldEN1c3RvbUtleXMoKTogeyBbaW5kZXhlcjogc3RyaW5nXTogc3RyaW5nIH0ge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCB0aGlzLmN1c3RvbUtleUNhY2hlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSByZXRyaWV2ZXMgdGhlIHJlZ2lzdGVyZWQgdmFsaWRhdG9ycyBrZXlzXG4gICAqL1xuICBnZXRLZXlzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5jYWNoZSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIGEgdmFsaWRhdG9yXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWxpZGF0b3JLZXkgb25lIG9mIHRoZSB7QGxpbmsgVmFsaWRhdGlvbktleXN9XG4gICAqIEByZXR1cm4ge1ZhbGlkYXRvciB8IHVuZGVmaW5lZH0gdGhlIHJlZ2lzdGVyZWQgVmFsaWRhdG9yIG9yIHVuZGVmaW5lZCBpZiB0aGVyZSBpcyBub25vIG1hdGNoaW5nIHRoZSBwcm92aWRlZCBrZXlcbiAgICovXG4gIGdldDxUIGV4dGVuZHMgVmFsaWRhdG9yPih2YWxpZGF0b3JLZXk6IHN0cmluZyk6IFQgfCB1bmRlZmluZWQge1xuICAgIGlmICghKHZhbGlkYXRvcktleSBpbiB0aGlzLmNhY2hlKSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IGNsYXNzT3JJbnN0YW5jZSA9IHRoaXMuY2FjaGVbdmFsaWRhdG9yS2V5XTtcbiAgICBpZiAoaXNWYWxpZGF0b3IoY2xhc3NPckluc3RhbmNlKSkgcmV0dXJuIGNsYXNzT3JJbnN0YW5jZSBhcyBUO1xuICAgIGNvbnN0IGNvbnN0cnVjdG9yID0gY2xhc3NPckluc3RhbmNlLmRlZmF1bHQgfHwgY2xhc3NPckluc3RhbmNlO1xuICAgIGNvbnN0IGluc3RhbmNlID0gbmV3IGNvbnN0cnVjdG9yKCk7XG4gICAgdGhpcy5jYWNoZVt2YWxpZGF0b3JLZXldID0gaW5zdGFuY2U7XG4gICAgcmV0dXJuIGluc3RhbmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJlZ2lzdGVycyB0aGUgcHJvdmlkZWQgdmFsaWRhdG9ycyBvbnRvIHRoZSByZWdpc3RyeVxuICAgKlxuICAgKiBAcGFyYW0ge1RbXSB8IFZhbGlkYXRvckRlZmluaXRpb25bXX0gdmFsaWRhdG9yXG4gICAqL1xuICByZWdpc3RlcjxUIGV4dGVuZHMgVmFsaWRhdG9yPihcbiAgICAuLi52YWxpZGF0b3I6IChWYWxpZGF0b3JEZWZpbml0aW9uIHwgVClbXVxuICApOiB2b2lkIHtcbiAgICB2YWxpZGF0b3IuZm9yRWFjaCgodikgPT4ge1xuICAgICAgaWYgKGlzVmFsaWRhdG9yKHYpKSB7XG4gICAgICAgIC8vIGNvbnN0IGsgPVxuXG4gICAgICAgIGlmICgodiBhcyBWYWxpZGF0b3JEZWZpbml0aW9uKS52YWxpZGF0aW9uS2V5IGluIHRoaXMuY2FjaGUpIHJldHVybjtcbiAgICAgICAgdGhpcy5jYWNoZVsodiBhcyBWYWxpZGF0b3JEZWZpbml0aW9uKS52YWxpZGF0aW9uS2V5XSA9IHY7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCB7IHZhbGlkYXRpb25LZXksIHZhbGlkYXRvciwgc2F2ZSB9ID0gdiBhcyBWYWxpZGF0b3JEZWZpbml0aW9uO1xuICAgICAgICBpZiAodmFsaWRhdGlvbktleSBpbiB0aGlzLmNhY2hlKSByZXR1cm47XG4gICAgICAgIHRoaXMuY2FjaGVbdmFsaWRhdGlvbktleV0gPSB2YWxpZGF0b3I7XG4gICAgICAgIGlmICghc2F2ZSkgcmV0dXJuO1xuICAgICAgICBjb25zdCBvYmo6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgICAgICAgb2JqW3ZhbGlkYXRpb25LZXkudG9VcHBlckNhc2UoKV0gPSB2YWxpZGF0aW9uS2V5O1xuXG4gICAgICAgIHRoaXMuY3VzdG9tS2V5Q2FjaGUgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLmN1c3RvbUtleUNhY2hlLCBvYmopO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tIFwiLi9WYWxpZGF0b3JzL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgSVZhbGlkYXRvclJlZ2lzdHJ5LCBWYWxpZGF0b3JEZWZpbml0aW9uIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IFZhbGlkYXRvclJlZ2lzdHJ5IH0gZnJvbSBcIi4vVmFsaWRhdG9ycy9WYWxpZGF0b3JSZWdpc3RyeVwiO1xuaW1wb3J0IHsgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9WYWxpZGF0b3JzL2NvbnN0YW50c1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFN0YXRpYyBjbGFzcyBhY3RpbmcgYXMgYSBuYW1lc3BhY2UgZm9yIHRoZSBWYWxpZGF0aW9uXG4gKlxuICogQGNsYXNzIFZhbGlkYXRpb25cbiAqIEBzdGF0aWNcbiAqXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdGlvblxuICovXG5leHBvcnQgY2xhc3MgVmFsaWRhdGlvbiB7XG4gIHByaXZhdGUgc3RhdGljIGFjdGluZ1ZhbGlkYXRvclJlZ2lzdHJ5PzogSVZhbGlkYXRvclJlZ2lzdHJ5PFZhbGlkYXRvcj4gPVxuICAgIHVuZGVmaW5lZDtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cblxuICAvKipcbiAgICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgYWN0aW5nIFZhbGlkYXRvclJlZ2lzdHJ5XG4gICAqXG4gICAqIEBwYXJhbSB7SVZhbGlkYXRvclJlZ2lzdHJ5fSB2YWxpZGF0b3JSZWdpc3RyeSB0aGUgbmV3IGltcGxlbWVudGF0aW9uIG9mIHRoZSB2YWxpZGF0b3IgUmVnaXN0cnlcbiAgICogQHBhcmFtIHtmdW5jdGlvbihWYWxpZGF0b3IpOiBWYWxpZGF0b3J9IFttaWdyYXRpb25IYW5kbGVyXSB0aGUgbWV0aG9kIHRvIG1hcCB0aGUgdmFsaWRhdG9yIGlmIHJlcXVpcmVkO1xuICAgKi9cbiAgc3RhdGljIHNldFJlZ2lzdHJ5KFxuICAgIHZhbGlkYXRvclJlZ2lzdHJ5OiBJVmFsaWRhdG9yUmVnaXN0cnk8VmFsaWRhdG9yPixcbiAgICBtaWdyYXRpb25IYW5kbGVyPzogKHZhbGlkYXRvcjogVmFsaWRhdG9yKSA9PiBWYWxpZGF0b3JcbiAgKSB7XG4gICAgaWYgKG1pZ3JhdGlvbkhhbmRsZXIgJiYgVmFsaWRhdGlvbi5hY3RpbmdWYWxpZGF0b3JSZWdpc3RyeSlcbiAgICAgIFZhbGlkYXRpb24uYWN0aW5nVmFsaWRhdG9yUmVnaXN0cnkuZ2V0S2V5cygpLmZvckVhY2goKGs6IHN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCB2YWxpZGF0b3IgPSB2YWxpZGF0b3JSZWdpc3RyeS5nZXQoayk7XG4gICAgICAgIGlmICh2YWxpZGF0b3IpIHZhbGlkYXRvclJlZ2lzdHJ5LnJlZ2lzdGVyKG1pZ3JhdGlvbkhhbmRsZXIodmFsaWRhdG9yKSk7XG4gICAgICB9KTtcbiAgICBWYWxpZGF0aW9uLmFjdGluZ1ZhbGlkYXRvclJlZ2lzdHJ5ID0gdmFsaWRhdG9yUmVnaXN0cnk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgUmV0dXJucyB0aGUgY3VycmVudCBWYWxpZGF0b3JSZWdpc3RyeVxuICAgKlxuICAgKiBAcmV0dXJuIElWYWxpZGF0b3JSZWdpc3RyeSwgZGVmYXVsdHMgdG8ge0BsaW5rIFZhbGlkYXRvclJlZ2lzdHJ5fVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0UmVnaXN0cnkoKSB7XG4gICAgaWYgKCFWYWxpZGF0aW9uLmFjdGluZ1ZhbGlkYXRvclJlZ2lzdHJ5KVxuICAgICAgVmFsaWRhdGlvbi5hY3RpbmdWYWxpZGF0b3JSZWdpc3RyeSA9IG5ldyBWYWxpZGF0b3JSZWdpc3RyeSgpO1xuICAgIHJldHVybiBWYWxpZGF0aW9uLmFjdGluZ1ZhbGlkYXRvclJlZ2lzdHJ5O1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyBhIHZhbGlkYXRvclxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsaWRhdG9yS2V5IG9uZSBvZiB0aGUge0BsaW5rIFZhbGlkYXRpb25LZXlzfVxuICAgKiBAcmV0dXJuIHtWYWxpZGF0b3IgfCB1bmRlZmluZWR9IHRoZSByZWdpc3RlcmVkIFZhbGlkYXRvciBvciB1bmRlZmluZWQgaWYgdGhlcmUgaXMgbm9ubyBtYXRjaGluZyB0aGUgcHJvdmlkZWQga2V5XG4gICAqL1xuICBzdGF0aWMgZ2V0PFQgZXh0ZW5kcyBWYWxpZGF0b3I+KHZhbGlkYXRvcktleTogc3RyaW5nKTogVCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIFZhbGlkYXRpb24uZ2V0UmVnaXN0cnkoKS5nZXQodmFsaWRhdG9yS2V5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZWdpc3RlcnMgdGhlIHByb3ZpZGVkIHZhbGlkYXRvcnMgb250byB0aGUgcmVnaXN0cnlcbiAgICpcbiAgICogQHBhcmFtIHtUW10gfCBWYWxpZGF0b3JEZWZpbml0aW9uW119IHZhbGlkYXRvclxuICAgKi9cbiAgc3RhdGljIHJlZ2lzdGVyPFQgZXh0ZW5kcyBWYWxpZGF0b3I+KFxuICAgIC4uLnZhbGlkYXRvcjogKFZhbGlkYXRvckRlZmluaXRpb24gfCBUKVtdXG4gICk6IHZvaWQge1xuICAgIHJldHVybiBWYWxpZGF0aW9uLmdldFJlZ2lzdHJ5KCkucmVnaXN0ZXIoLi4udmFsaWRhdG9yKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBCdWlsZHMgdGhlIGtleSB0byBzdG9yZSBhcyBNZXRhZGF0YSB1bmRlciBSZWZsZWN0aW9uc1xuICAgKiBAZGVzY3JpcHRpb24gY29uY2F0ZW5hdGVzIHtAbGluayBWYWxpZGF0aW9uS2V5cyNSRUZMRUNUfSB3aXRoIHRoZSBwcm92aWRlZCBrZXlcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICAgKi9cbiAgc3RhdGljIGtleShrZXk6IHN0cmluZykge1xuICAgIHJldHVybiBWYWxpZGF0aW9uS2V5cy5SRUZMRUNUICsga2V5O1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgYWxsIHJlZ2lzdGVyZWQgdmFsaWRhdGlvbiBrZXlzXG4gICAqL1xuICBzdGF0aWMga2V5cygpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRSZWdpc3RyeSgpLmdldEtleXMoKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgTW9kZWxFcnJvckRlZmluaXRpb24gfSBmcm9tIFwiLi9Nb2RlbEVycm9yRGVmaW5pdGlvblwiO1xuaW1wb3J0IHsgRGVjb3JhdG9yTWV0YWRhdGEsIFJlZmxlY3Rpb24gfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IE1vZGVsS2V5cyB9IGZyb20gXCIuLi91dGlscy9jb25zdGFudHNcIjtcbmltcG9ydCB7IHNmIH0gZnJvbSBcIi4uL3V0aWxzL3N0cmluZ3NcIjtcbmltcG9ydCB7IFJlc2VydmVkTW9kZWxzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBWQUxJREFUSU9OX1BBUkVOVF9LRVkgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBWYWxpZGF0YWJsZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBpc01vZGVsLCBNb2RlbCB9IGZyb20gXCIuL01vZGVsXCI7XG5pbXBvcnQgeyBWYWxpZGF0aW9uIH0gZnJvbSBcIi4uL3ZhbGlkYXRpb24vVmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi4vdmFsaWRhdGlvbi9WYWxpZGF0b3JzL2NvbnN0YW50c1wiO1xuaW1wb3J0IHtcbiAgTW9kZWxFcnJvcnMsXG4gIFZhbGlkYXRpb25Qcm9wZXJ0eURlY29yYXRvckRlZmluaXRpb24sXG4gIFZhbGlkYXRvck9wdGlvbnMsXG59IGZyb20gXCIuLi92YWxpZGF0aW9uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgQW5hbHlzZXMgdGhlIGRlY29yYXRpb25zIG9mIHRoZSBwcm9wZXJ0aWVzIGFuZCB2YWxpZGF0ZXMgdGhlIG9iaiBhY2NvcmRpbmcgdG8gdGhlbVxuICpcbiAqIEB0eXBlZGVmIFQgZXh0ZW5kcyBNb2RlbFxuICogQHByb3Age1R9IG9iaiBNb2RlbCBvYmplY3QgdG8gdmFsaWRhdGVcbiAqIEBwcm9wIHtzdHJpbmdbXX0gW3Byb3BzVG9JZ25vcmVdIG9iamVjdCBwcm9wZXJ0aWVzIHRvIGlnbm9yZSBpbiB0aGUgdmFsaWRhdGlvblxuICpcbiAqIEBmdW5jdGlvbiB2YWxpZGF0ZVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5WYWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGU8VCBleHRlbmRzIE1vZGVsPihcbiAgb2JqOiBULFxuICAuLi5wcm9wc1RvSWdub3JlOiBzdHJpbmdbXVxuKTogTW9kZWxFcnJvckRlZmluaXRpb24gfCB1bmRlZmluZWQge1xuICBjb25zdCBkZWNvcmF0ZWRQcm9wZXJ0aWVzOiBWYWxpZGF0aW9uUHJvcGVydHlEZWNvcmF0b3JEZWZpbml0aW9uW10gPSBbXTtcbiAgZm9yIChjb25zdCBwcm9wIGluIG9iailcbiAgICBpZiAoXG4gICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKSAmJlxuICAgICAgcHJvcHNUb0lnbm9yZS5pbmRleE9mKHByb3ApID09PSAtMVxuICAgIClcbiAgICAgIGRlY29yYXRlZFByb3BlcnRpZXMucHVzaChcbiAgICAgICAgUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICAgICAgVmFsaWRhdGlvbktleXMuUkVGTEVDVCxcbiAgICAgICAgICBvYmosXG4gICAgICAgICAgcHJvcFxuICAgICAgICApIGFzIFZhbGlkYXRpb25Qcm9wZXJ0eURlY29yYXRvckRlZmluaXRpb25cbiAgICAgICk7XG5cbiAgbGV0IHJlc3VsdDogTW9kZWxFcnJvcnMgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cbiAgZm9yIChjb25zdCBkZWNvcmF0ZWRQcm9wZXJ0eSBvZiBkZWNvcmF0ZWRQcm9wZXJ0aWVzKSB7XG4gICAgY29uc3QgeyBwcm9wLCBkZWNvcmF0b3JzIH0gPSBkZWNvcmF0ZWRQcm9wZXJ0eTtcblxuICAgIGlmICghZGVjb3JhdG9ycyB8fCAhZGVjb3JhdG9ycy5sZW5ndGgpIGNvbnRpbnVlO1xuXG4gICAgY29uc3QgZGVmYXVsdFR5cGVEZWNvcmF0b3I6IERlY29yYXRvck1ldGFkYXRhID0gZGVjb3JhdG9yc1swXTtcblxuICAgIC8vIHRyaWVzIHRvIGZpbmQgYW55IHR5cGUgZGVjb3JhdG9ycyBvciBvdGhlciBkZWNvcmF0b3JzIHRoYXQgYWxyZWFkeSBlbmZvcmNlIHR5cGUgKHRoZSBvbmVzIHdpdGggdGhlIGFsbG93ZWQgdHlwZXMgcHJvcGVydHkgZGVmaW5lZCkuIGlmIHNvLCBza2lwIHRoZSBkZWZhdWx0IHR5cGUgdmVyaWZpY2F0aW9uXG4gICAgaWYgKFxuICAgICAgZGVjb3JhdG9ycy5maW5kKChkKSA9PiB7XG4gICAgICAgIGlmIChkLmtleSA9PT0gVmFsaWRhdGlvbktleXMuVFlQRSkgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiAhIWQucHJvcHMudHlwZXM/LmZpbmQoXG4gICAgICAgICAgKHQpID0+IHQgPT09IGRlZmF1bHRUeXBlRGVjb3JhdG9yLnByb3BzLm5hbWVcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKSB7XG4gICAgICBkZWNvcmF0b3JzLnNoaWZ0KCk7IC8vIHJlbW92ZSB0aGUgZGVzaWduOnR5cGUgZGVjb3JhdG9yLCBzaW5jZSB0aGUgdHlwZSB3aWxsIGFscmVhZHkgYmUgY2hlY2tlZFxuICAgIH1cblxuICAgIGxldCBlcnJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gICAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgZGVjb3JhdG9ycykge1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gVmFsaWRhdGlvbi5nZXQoZGVjb3JhdG9yLmtleSk7XG4gICAgICBpZiAoIXZhbGlkYXRvcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgdmFsaWRhdG9yIGZvciAke2RlY29yYXRvci5rZXl9YCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRlY29yYXRvclByb3BzID1cbiAgICAgICAgZGVjb3JhdG9yLmtleSA9PT0gTW9kZWxLZXlzLlRZUEVcbiAgICAgICAgICA/IFtkZWNvcmF0b3IucHJvcHNdXG4gICAgICAgICAgOiBkZWNvcmF0b3IucHJvcHMgfHwge307XG5cbiAgICAgIGNvbnN0IGVycjogc3RyaW5nIHwgdW5kZWZpbmVkID0gdmFsaWRhdG9yLmhhc0Vycm9ycyhcbiAgICAgICAgKG9iaiBhcyBhbnkpW3Byb3AudG9TdHJpbmcoKV0sXG4gICAgICAgIGRlY29yYXRvclByb3BzIGFzIFZhbGlkYXRvck9wdGlvbnMsXG4gICAgICAgIG9iaiAvLyBUT0RPOiBBc3NlcnQgdHlwZSBhbmQgZGVlcCBPYmplY3QuZnJlZXplXG4gICAgICApO1xuXG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIGVycnMgPSBlcnJzIHx8IHt9O1xuICAgICAgICBlcnJzW2RlY29yYXRvci5rZXldID0gZXJyO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlcnJzKSB7XG4gICAgICByZXN1bHQgPSByZXN1bHQgfHwge307XG4gICAgICByZXN1bHRbZGVjb3JhdGVkUHJvcGVydHkucHJvcC50b1N0cmluZygpXSA9IGVycnM7XG4gICAgfVxuICB9XG5cbiAgLy8gdGVzdHMgbmVzdGVkIGNsYXNzZXNcbiAgZm9yIChjb25zdCBwcm9wIG9mIE9iamVjdC5rZXlzKG9iaikuZmlsdGVyKChrKSA9PiAhcmVzdWx0IHx8ICFyZXN1bHRba10pKSB7XG4gICAgbGV0IGVycjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIC8vIGlmIGEgbmVzdGVkIE1vZGVsXG4gICAgY29uc3QgYWxsRGVjb3JhdG9ycyA9IFJlZmxlY3Rpb24uZ2V0UHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgVmFsaWRhdGlvbktleXMuUkVGTEVDVCxcbiAgICAgIG9iaixcbiAgICAgIHByb3BcbiAgICApLmRlY29yYXRvcnM7XG4gICAgY29uc3QgZGVjb3JhdG9ycyA9IFJlZmxlY3Rpb24uZ2V0UHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgVmFsaWRhdGlvbktleXMuUkVGTEVDVCxcbiAgICAgIG9iaixcbiAgICAgIHByb3BcbiAgICApLmRlY29yYXRvcnMuZmlsdGVyKFxuICAgICAgKGQ6IHsga2V5OiBzdHJpbmcgfSkgPT5cbiAgICAgICAgW01vZGVsS2V5cy5UWVBFLCBWYWxpZGF0aW9uS2V5cy5UWVBFIGFzIHN0cmluZ10uaW5kZXhPZihkLmtleSkgIT09IC0xXG4gICAgKTtcbiAgICBpZiAoIWRlY29yYXRvcnMgfHwgIWRlY29yYXRvcnMubGVuZ3RoKSBjb250aW51ZTtcbiAgICBjb25zdCBkZWMgPSBkZWNvcmF0b3JzLnBvcCgpIGFzIERlY29yYXRvck1ldGFkYXRhO1xuICAgIGNvbnN0IGNsYXp6ID0gZGVjLnByb3BzLm5hbWVcbiAgICAgID8gW2RlYy5wcm9wcy5uYW1lXVxuICAgICAgOiBBcnJheS5pc0FycmF5KGRlYy5wcm9wcy5jdXN0b21UeXBlcylcbiAgICAgICAgPyBkZWMucHJvcHMuY3VzdG9tVHlwZXNcbiAgICAgICAgOiBbZGVjLnByb3BzLmN1c3RvbVR5cGVzXTtcbiAgICBjb25zdCByZXNlcnZlZCA9IE9iamVjdC52YWx1ZXMoUmVzZXJ2ZWRNb2RlbHMpLm1hcCgodikgPT5cbiAgICAgIHYudG9Mb3dlckNhc2UoKVxuICAgICkgYXMgc3RyaW5nW107XG5cbiAgICBmb3IgKGNvbnN0IGMgb2YgY2xhenopIHtcbiAgICAgIGlmIChyZXNlcnZlZC5pbmRleE9mKGMudG9Mb3dlckNhc2UoKSkgPT09IC0xKSB7XG4gICAgICAgIGNvbnN0IHR5cGVEZWNvcmF0b3JLZXkgPSBBcnJheS5pc0FycmF5KChvYmogYXMgYW55KVtwcm9wXSlcbiAgICAgICAgICA/IFZhbGlkYXRpb25LZXlzLkxJU1RcbiAgICAgICAgICA6IFZhbGlkYXRpb25LZXlzLlRZUEU7XG4gICAgICAgIGNvbnN0IHR5cGVzOiBhbnkgPVxuICAgICAgICAgIGFsbERlY29yYXRvcnMuZmluZChcbiAgICAgICAgICAgIChkOiB7IGtleTogc3RyaW5nIH0pID0+IGQua2V5ID09PSB0eXBlRGVjb3JhdG9yS2V5XG4gICAgICAgICAgKSB8fCB7fTtcbiAgICAgICAgbGV0IGFsbG93ZWRUeXBlczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgaWYgKHR5cGVzICYmIHR5cGVzLnByb3BzKSB7XG4gICAgICAgICAgY29uc3QgY3VzdG9tVHlwZXMgPSBBcnJheS5pc0FycmF5KChvYmogYXMgYW55KVtwcm9wXSlcbiAgICAgICAgICAgID8gdHlwZXMucHJvcHMuY2xhc3NcbiAgICAgICAgICAgIDogdHlwZXMucHJvcHMuY3VzdG9tVHlwZXM7XG4gICAgICAgICAgaWYgKGN1c3RvbVR5cGVzKVxuICAgICAgICAgICAgYWxsb3dlZFR5cGVzID0gQXJyYXkuaXNBcnJheShjdXN0b21UeXBlcylcbiAgICAgICAgICAgICAgPyBjdXN0b21UeXBlcy5tYXAoKHQpID0+IGAke3R9YC50b0xvd2VyQ2FzZSgpKVxuICAgICAgICAgICAgICA6IFtjdXN0b21UeXBlcy50b0xvd2VyQ2FzZSgpXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHZhbGlkYXRlID0gKHByb3A6IHN0cmluZywgdmFsdWU6IGFueSk6IGFueSA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIilcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHZhbHVlICYmICF2YWx1ZVtWQUxJREFUSU9OX1BBUkVOVF9LRVldKVxuICAgICAgICAgICAgICB2YWx1ZVtWQUxJREFUSU9OX1BBUkVOVF9LRVldID0gb2JqOyAvLyBUT0RPOiBmcmVlemU/XG5cbiAgICAgICAgICAgIHJldHVybiBpc01vZGVsKHZhbHVlKVxuICAgICAgICAgICAgICA/IHZhbHVlLmhhc0Vycm9ycygpXG4gICAgICAgICAgICAgIDogYWxsb3dlZFR5cGVzLmluY2x1ZGVzKHR5cGVvZiB2YWx1ZSlcbiAgICAgICAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIDogXCJWYWx1ZSBoYXMgbm8gdmFsaWRhdGFibGUgdHlwZVwiO1xuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICBpZiAodmFsdWUgJiYgdmFsdWVbVkFMSURBVElPTl9QQVJFTlRfS0VZXSlcbiAgICAgICAgICAgICAgZGVsZXRlIHZhbHVlW1ZBTElEQVRJT05fUEFSRU5UX0tFWV07XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHN3aXRjaCAoYykge1xuICAgICAgICAgIGNhc2UgQXJyYXkubmFtZTpcbiAgICAgICAgICBjYXNlIFNldC5uYW1lOlxuICAgICAgICAgICAgaWYgKGFsbERlY29yYXRvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGxpc3REZWMgPSBhbGxEZWNvcmF0b3JzLmZpbmQoXG4gICAgICAgICAgICAgICAgKGQ6IHsga2V5OiBzdHJpbmcgfSkgPT4gZC5rZXkgPT09IFZhbGlkYXRpb25LZXlzLkxJU1RcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgaWYgKGxpc3REZWMpIHtcbiAgICAgICAgICAgICAgICBlcnIgPSAoXG4gICAgICAgICAgICAgICAgICBjID09PSBBcnJheS5uYW1lXG4gICAgICAgICAgICAgICAgICAgID8gKG9iaiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+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+KVtwcm9wXSA9XG4gICAgICAgIChvYmogYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0gPz8gdW5kZWZpbmVkO1xuICAgICAgaWYgKHR5cGVvZiAoc2VsZiBhcyBhbnkpW3Byb3BdICE9PSBcIm9iamVjdFwiKSBjb250aW51ZTtcbiAgICAgIGNvbnN0IHByb3BNID0gaXNQcm9wZXJ0eU1vZGVsKHNlbGYsIHByb3ApO1xuICAgICAgaWYgKHByb3BNKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgKHNlbGYgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0gPSBNb2RlbC5idWlsZChcbiAgICAgICAgICAgIChzZWxmIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdLFxuICAgICAgICAgICAgdHlwZW9mIHByb3BNID09PSBcInN0cmluZ1wiID8gcHJvcE0gOiB1bmRlZmluZWRcbiAgICAgICAgICApO1xuICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYWxsRGVjb3JhdG9yczogRGVjb3JhdG9yTWV0YWRhdGFbXSA9XG4gICAgICAgIFJlZmxlY3Rpb24uZ2V0UHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgICAgIFZhbGlkYXRpb25LZXlzLlJFRkxFQ1QsXG4gICAgICAgICAgc2VsZixcbiAgICAgICAgICBwcm9wXG4gICAgICAgICkuZGVjb3JhdG9ycztcbiAgICAgIGRlY29yYXRvcnMgPSBhbGxEZWNvcmF0b3JzLmZpbHRlcihcbiAgICAgICAgKGQ6IERlY29yYXRvck1ldGFkYXRhKSA9PlxuICAgICAgICAgIFtNb2RlbEtleXMuVFlQRSwgVmFsaWRhdGlvbktleXMuVFlQRSBhcyBzdHJpbmddLmluZGV4T2YoZC5rZXkpICE9PSAtMVxuICAgICAgKTtcbiAgICAgIGlmICghZGVjb3JhdG9ycyB8fCAhZGVjb3JhdG9ycy5sZW5ndGgpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihzZihcImZhaWxlZCB0byBmaW5kIGRlY29yYXRvcnMgZm9yIHByb3BlcnR5IHswfVwiLCBwcm9wKSk7XG4gICAgICBkZWMgPSBkZWNvcmF0b3JzLnBvcCgpIGFzIERlY29yYXRvck1ldGFkYXRhO1xuICAgICAgY29uc3QgY2xhenogPSBkZWMucHJvcHMubmFtZVxuICAgICAgICA/IFtkZWMucHJvcHMubmFtZV1cbiAgICAgICAgOiBBcnJheS5pc0FycmF5KGRlYy5wcm9wcy5jdXN0b21UeXBlcylcbiAgICAgICAgICA/IGRlYy5wcm9wcy5jdXN0b21UeXBlc1xuICAgICAgICAgIDogW2RlYy5wcm9wcy5jdXN0b21UeXBlc107XG4gICAgICBjb25zdCByZXNlcnZlZCA9IE9iamVjdC52YWx1ZXMoUmVzZXJ2ZWRNb2RlbHMpLm1hcCgodikgPT5cbiAgICAgICAgdi50b0xvd2VyQ2FzZSgpXG4gICAgICApIGFzIHN0cmluZ1tdO1xuXG4gICAgICBjbGF6ei5mb3JFYWNoKChjKSA9PiB7XG4gICAgICAgIGlmIChyZXNlcnZlZC5pbmRleE9mKGMudG9Mb3dlckNhc2UoKSkgPT09IC0xKVxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzd2l0Y2ggKGMpIHtcbiAgICAgICAgICAgICAgY2FzZSBcIkFycmF5XCI6XG4gICAgICAgICAgICAgIGNhc2UgXCJTZXRcIjpcbiAgICAgICAgICAgICAgICBpZiAoYWxsRGVjb3JhdG9ycy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGxpc3REZWMgPSBhbGxEZWNvcmF0b3JzLmZpbmQoXG4gICAgICAgICAgICAgICAgICAgIChkKSA9PiBkLmtleSA9PT0gVmFsaWRhdGlvbktleXMuTElTVFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgIGlmIChsaXN0RGVjKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNsYXp6TmFtZSA9IChsaXN0RGVjLnByb3BzLmNsYXp6IGFzIHN0cmluZ1tdKS5maW5kKFxuICAgICAgICAgICAgICAgICAgICAgICh0OiBzdHJpbmcpID0+ICFqc1R5cGVzLmluY2x1ZGVzKHQudG9Mb3dlckNhc2UoKSlcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT09IFwiQXJyYXlcIilcbiAgICAgICAgICAgICAgICAgICAgICAoc2VsZiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXSA9IChcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYgYXMgUmVjb3JkPHN0cmluZywgYW55PlxuICAgICAgICAgICAgICAgICAgICAgIClbcHJvcF0ubWFwKChlbDogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gW1wib2JqZWN0XCIsIFwiZnVuY3Rpb25cIl0uaW5jbHVkZXModHlwZW9mIGVsKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjbGF6ek5hbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPyBNb2RlbC5idWlsZChlbCwgY2xhenpOYW1lKVxuICAgICAgICAgICAgICAgICAgICAgICAgICA6IGVsO1xuICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PT0gXCJTZXRcIikge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHMgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCB2IG9mIChzZWxmIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtcIm9iamVjdFwiLCBcImZ1bmN0aW9uXCJdLmluY2x1ZGVzKHR5cGVvZiB2KSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjbGF6ek5hbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBzLmFkZChNb2RlbC5idWlsZCh2LCBjbGF6ek5hbWUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHMuYWRkKHYpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAoc2VsZiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXSA9IHM7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgaWYgKChzZWxmIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdKVxuICAgICAgICAgICAgICAgICAgKHNlbGYgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0gPSBNb2RlbC5idWlsZChcbiAgICAgICAgICAgICAgICAgICAgKHNlbGYgYXMgYW55KVtwcm9wXSxcbiAgICAgICAgICAgICAgICAgICAgY1xuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGUpO1xuICAgICAgICAgICAgLy8gZG8gbm90aGluZy4gd2UgaGF2ZSBubyByZWdpc3RyeSBvZiB0aGlzIGNsYXNzXG4gICAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBzZWxmO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFNldHMgdGhlIEdsb2JhbCB7QGxpbmsgTW9kZWxCdWlsZGVyRnVuY3Rpb259XG4gICAqIEBwYXJhbSB7TW9kZWxCdWlsZGVyRnVuY3Rpb259IFtidWlsZGVyXVxuICAgKi9cbiAgc3RhdGljIHNldEJ1aWxkZXIoYnVpbGRlcj86IE1vZGVsQnVpbGRlckZ1bmN0aW9uKSB7XG4gICAgbW9kZWxCdWlsZGVyRnVuY3Rpb24gPSBidWlsZGVyO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgY3VycmVudCBnbG9iYWwge0BsaW5rIE1vZGVsQnVpbGRlckZ1bmN0aW9ufVxuICAgKi9cbiAgc3RhdGljIGdldEJ1aWxkZXIoKTogTW9kZWxCdWlsZGVyRnVuY3Rpb24gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBtb2RlbEJ1aWxkZXJGdW5jdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHtAbGluayBNb2RlbFJlZ2lzdHJ5TWFuYWdlcn1cbiAgICpcbiAgICogQHJldHVybiBNb2RlbFJlZ2lzdHJ5LCBkZWZhdWx0cyB0byB7QGxpbmsgTW9kZWxSZWdpc3RyeU1hbmFnZXJ9XG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBnZXRSZWdpc3RyeSgpIHtcbiAgICBpZiAoIWFjdGluZ01vZGVsUmVnaXN0cnkpIGFjdGluZ01vZGVsUmVnaXN0cnkgPSBuZXcgTW9kZWxSZWdpc3RyeU1hbmFnZXIoKTtcbiAgICByZXR1cm4gYWN0aW5nTW9kZWxSZWdpc3RyeTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGFjdGluZ01vZGVsUmVnaXN0cnlcbiAgICpcbiAgICogQHBhcmFtIHtCdWlsZGVyUmVnaXN0cnl9IG1vZGVsUmVnaXN0cnkgdGhlIG5ldyBpbXBsZW1lbnRhdGlvbiBvZiBSZWdpc3RyeVxuICAgKi9cbiAgc3RhdGljIHNldFJlZ2lzdHJ5KG1vZGVsUmVnaXN0cnk6IEJ1aWxkZXJSZWdpc3RyeTxhbnk+KSB7XG4gICAgYWN0aW5nTW9kZWxSZWdpc3RyeSA9IG1vZGVsUmVnaXN0cnk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgcmVnaXN0ZXIgbmV3IE1vZGVsc1xuICAgKiBAcGFyYW0ge2FueX0gY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtuYW1lXSB3aGVuIG5vdCBkZWZpbmVkLCB0aGUgbmFtZSBvZiB0aGUgY29uc3RydWN0b3Igd2lsbCBiZSB1c2VkXG4gICAqXG4gICAqIEBzZWUgTW9kZWxSZWdpc3RyeVxuICAgKi9cbiAgc3RhdGljIHJlZ2lzdGVyPFQgZXh0ZW5kcyBNb2RlbD4oXG4gICAgY29uc3RydWN0b3I6IE1vZGVsQ29uc3RydWN0b3I8VD4sXG4gICAgbmFtZT86IHN0cmluZ1xuICApOiB2b2lkIHtcbiAgICByZXR1cm4gTW9kZWwuZ2V0UmVnaXN0cnkoKS5yZWdpc3Rlcihjb25zdHJ1Y3RvciwgbmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgR2V0cyBhIHJlZ2lzdGVyZWQgTW9kZWwge0BsaW5rIE1vZGVsQ29uc3RydWN0b3J9XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAqXG4gICAqIEBzZWUgTW9kZWxSZWdpc3RyeVxuICAgKi9cbiAgc3RhdGljIGdldDxUIGV4dGVuZHMgTW9kZWw+KG5hbWU6IHN0cmluZyk6IE1vZGVsQ29uc3RydWN0b3I8VD4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBNb2RlbC5nZXRSZWdpc3RyeSgpLmdldChuYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IG9ialxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2NsYXp6XSB3aGVuIHByb3ZpZGVkLCBpdCB3aWxsIGF0dGVtcHQgdG8gZmluZCB0aGUgbWF0Y2hpbmcgY29uc3RydWN0b3JcbiAgICpcbiAgICogQHRocm93cyBFcnJvciBJZiBjbGF6eiBpcyBub3QgZm91bmQsIG9yIG9iaiBpcyBub3QgYSB7QGxpbmsgTW9kZWx9IG1lYW5pbmcgaXQgaGFzIG5vIHtAbGluayBNb2RlbEtleXMuQU5DSE9SfSBwcm9wZXJ0eVxuICAgKlxuICAgKiBAc2VlIE1vZGVsUmVnaXN0cnlcbiAgICovXG4gIHN0YXRpYyBidWlsZDxUIGV4dGVuZHMgTW9kZWw+KFxuICAgIG9iajogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9LFxuICAgIGNsYXp6Pzogc3RyaW5nXG4gICk6IFQge1xuICAgIHJldHVybiBNb2RlbC5nZXRSZWdpc3RyeSgpLmJ1aWxkKG9iaiwgY2xhenopO1xuICB9XG5cbiAgc3RhdGljIGdldE1ldGFkYXRhPFYgZXh0ZW5kcyBNb2RlbD4obW9kZWw6IFYpIHtcbiAgICBjb25zdCBtZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICBNb2RlbC5rZXkoTW9kZWxLZXlzLk1PREVMKSxcbiAgICAgIG1vZGVsLmNvbnN0cnVjdG9yXG4gICAgKTtcbiAgICBpZiAoIW1ldGFkYXRhKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcImNvdWxkIG5vdCBmaW5kIG1ldGFkYXRhIGZvciBwcm92aWRlZCBcIiArIG1vZGVsLmNvbnN0cnVjdG9yLm5hbWVcbiAgICAgICk7XG4gICAgcmV0dXJuIG1ldGFkYXRhO1xuICB9XG5cbiAgc3RhdGljIGdldEF0dHJpYnV0ZXM8ViBleHRlbmRzIE1vZGVsPihtb2RlbDogQ29uc3RydWN0b3I8Vj4gfCBWKSB7XG4gICAgY29uc3QgcmVzdWx0OiBzdHJpbmdbXSA9IFtdO1xuICAgIGxldCBwcm90b3R5cGUgPVxuICAgICAgbW9kZWwgaW5zdGFuY2VvZiBNb2RlbFxuICAgICAgICA/IE9iamVjdC5nZXRQcm90b3R5cGVPZihtb2RlbClcbiAgICAgICAgOiAobW9kZWwgYXMgYW55KS5wcm90b3R5cGU7XG4gICAgd2hpbGUgKHByb3RvdHlwZSAhPSBudWxsKSB7XG4gICAgICBjb25zdCBwcm9wczogc3RyaW5nW10gPSBwcm90b3R5cGVbTW9kZWxLZXlzLkFUVFJJQlVURV07XG4gICAgICBpZiAocHJvcHMpIHtcbiAgICAgICAgcmVzdWx0LnB1c2goLi4ucHJvcHMpO1xuICAgICAgfVxuICAgICAgcHJvdG90eXBlID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvdHlwZSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBzdGF0aWMgZXF1YWxzPFYgZXh0ZW5kcyBNb2RlbD4ob2JqMTogViwgb2JqMjogViwgLi4uZXhjZXB0aW9uczogYW55W10pIHtcbiAgICByZXR1cm4gaXNFcXVhbChvYmoxLCBvYmoyLCAuLi5leGNlcHRpb25zKTtcbiAgfVxuXG4gIHN0YXRpYyBoYXNFcnJvcnM8ViBleHRlbmRzIE1vZGVsPihtb2RlbDogViwgLi4ucHJvcHNUb0lnbm9yZTogc3RyaW5nW10pIHtcbiAgICByZXR1cm4gdmFsaWRhdGUobW9kZWwsIC4uLnByb3BzVG9JZ25vcmUpO1xuICB9XG5cbiAgc3RhdGljIHNlcmlhbGl6ZTxWIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBWKSB7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgTW9kZWwua2V5KE1vZGVsS2V5cy5TRVJJQUxJWkFUSU9OKSxcbiAgICAgIG1vZGVsLmNvbnN0cnVjdG9yXG4gICAgKTtcblxuICAgIGlmIChtZXRhZGF0YSAmJiBtZXRhZGF0YS5zZXJpYWxpemVyKVxuICAgICAgcmV0dXJuIFNlcmlhbGl6YXRpb24uc2VyaWFsaXplKFxuICAgICAgICB0aGlzLFxuICAgICAgICBtZXRhZGF0YS5zZXJpYWxpemVyLFxuICAgICAgICAuLi4obWV0YWRhdGEuYXJncyB8fCBbXSlcbiAgICAgICk7XG4gICAgcmV0dXJuIFNlcmlhbGl6YXRpb24uc2VyaWFsaXplKG1vZGVsKTtcbiAgfVxuXG4gIHN0YXRpYyBoYXNoPFYgZXh0ZW5kcyBNb2RlbD4obW9kZWw6IFYpIHtcbiAgICBjb25zdCBtZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICBNb2RlbC5rZXkoTW9kZWxLZXlzLkhBU0hJTkcpLFxuICAgICAgbW9kZWwuY29uc3RydWN0b3JcbiAgICApO1xuXG4gICAgaWYgKG1ldGFkYXRhICYmIG1ldGFkYXRhLmFsZ29yaXRobSlcbiAgICAgIHJldHVybiBIYXNoaW5nLmhhc2gobW9kZWwsIG1ldGFkYXRhLmFsZ29yaXRobSwgLi4uKG1ldGFkYXRhLmFyZ3MgfHwgW10pKTtcbiAgICByZXR1cm4gSGFzaGluZy5oYXNoKG1vZGVsKTtcbiAgfVxuICAvKipcbiAgICogQHN1bW1hcnkgQnVpbGRzIHRoZSBrZXkgdG8gc3RvcmUgYXMgTWV0YWRhdGEgdW5kZXIgUmVmbGVjdGlvbnNcbiAgICogQGRlc2NyaXB0aW9uIGNvbmNhdGVuYXRlcyB7QGxpbmsgTW9kZWxLZXlzI1JFRkxFQ1R9IHdpdGggdGhlIHByb3ZpZGVkIGtleVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gICAqL1xuICBzdGF0aWMga2V5KHN0cjogc3RyaW5nKSB7XG4gICAgcmV0dXJuIE1vZGVsS2V5cy5SRUZMRUNUICsgc3RyO1xuICB9XG59XG4iLCJpbXBvcnQgeyBDb25zdHJ1Y3RvciB9IGZyb20gXCIuLi9tb2RlbC90eXBlc1wiO1xuaW1wb3J0IHsgU2VyaWFsaXplciB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCIuLi9tb2RlbC9Nb2RlbFwiO1xuaW1wb3J0IHsgTW9kZWxLZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbmV4cG9ydCBjb25zdCBEZWZhdWx0U2VyaWFsaXphdGlvbk1ldGhvZCA9IFwianNvblwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IENvbmNyZXRlIGltcGxlbWVudGF0aW9uIG9mIGEge0BsaW5rIFNlcmlhbGl6ZXJ9IGluIEpTT04gZm9ybWF0XG4gKiBAZGVzY3JpcHRpb24gSlMncyBuYXRpdmUgSlNPTi5zdHJpbmdpZnkgKHVzZWQgaGVyZSkgaXMgbm90IGRldGVybWluaXN0aWNcbiAqIGFuZCB0aGVyZWZvcmUgc2hvdWxkIG5vdCBiZSB1c2VkIGZvciBoYXNoaW5nIHB1cnBvc2VzXG4gKlxuICogVG8ga2VlcCBkZXBlbmRlbmNpZXMgbG93LCB3ZSB3aWxsIG5vdCBpbXBsZW1lbnQgdGhpcywgYnV0IHdlIHJlY29tbWVuZFxuICogaW1wbGVtZW50aW5nIGEgc2ltaWxhciB7QGxpbmsgSlNPTlNlcmlhbGl6ZXJ9IHVzaW5nICdkZXRlcm1pbmlzdGljLWpzb24nIGxpYnJhcmllc1xuICpcbiAqIEBjbGFzcyBKU09OU2VyaWFsaXplclxuICogQGltcGxlbWVudHMgU2VyaWFsaXplclxuICpcbiAqIEBjYXRlZ29yeSBTZXJpYWxpemF0aW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBKU09OU2VyaWFsaXplcjxUIGV4dGVuZHMgTW9kZWw+IGltcGxlbWVudHMgU2VyaWFsaXplcjxUPiB7XG4gIGNvbnN0cnVjdG9yKCkge31cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHByZXBhcmVzIHRoZSBtb2RlbCBmb3Igc2VyaWFsaXphdGlvblxuICAgKiBAZGVzY3JpcHRpb24gcmV0dXJucyBhIHNoYWxsb3cgY29weSBvZiB0aGUgb2JqZWN0LCBjb250YWluaW5nIGFuIGVudW1lcmFibGUge0BsaW5rIE1vZGVsS2V5cyNBTkNIT1J9IHByb3BlcnR5XG4gICAqIHNvIHRoZSBvYmplY3QgY2FuIGJlIHJlY29nbml6ZWQgdXBvbiBkZXNlcmlhbGl6YXRpb25cbiAgICpcbiAgICogQHBhcmFtIHtUfSBtb2RlbFxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBwcm90ZWN0ZWQgcHJlU2VyaWFsaXplKG1vZGVsOiBUKSB7XG4gICAgLy8gVE9ETzogbmVzdGVkIHByZXNlcmlhbGl6YXRpb24gKHNvIGluY3JlYXNlIHBlcmZvcm1hbmNlIHdoZW4gZGVzZXJpYWxpemluZylcbiAgICBjb25zdCB0b1NlcmlhbGl6ZTogUmVjb3JkPHN0cmluZywgYW55PiA9IE9iamVjdC5hc3NpZ24oe30sIG1vZGVsKTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IE1vZGVsLmdldE1ldGFkYXRhKG1vZGVsKTtcbiAgICB0b1NlcmlhbGl6ZVtNb2RlbEtleXMuQU5DSE9SXSA9IG1ldGFkYXRhIHx8IG1vZGVsLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgcmV0dXJuIHRvU2VyaWFsaXplO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJlYnVpbGRzIGEgbW9kZWwgZnJvbSBhIHNlcmlhbGl6YXRpb25cbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0clxuICAgKlxuICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgaXQgZmFpbHMgdG8gcGFyc2UgdGhlIHN0cmluZywgb3IgdG8gYnVpbGQgdGhlIG1vZGVsXG4gICAqL1xuICBkZXNlcmlhbGl6ZShzdHI6IHN0cmluZyk6IFQge1xuICAgIGNvbnN0IGRlc2VyaWFsaXphdGlvbiA9IEpTT04ucGFyc2Uoc3RyKTtcbiAgICBjb25zdCBjbGFzc05hbWUgPSBkZXNlcmlhbGl6YXRpb25bTW9kZWxLZXlzLkFOQ0hPUl07XG4gICAgaWYgKCFjbGFzc05hbWUpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZCBub3QgZmluZCBjbGFzcyByZWZlcmVuY2UgaW4gc2VyaWFsaXplZCBtb2RlbFwiKTtcbiAgICBjb25zdCBtb2RlbDogVCA9IE1vZGVsLmJ1aWxkKGRlc2VyaWFsaXphdGlvbiwgY2xhc3NOYW1lKSBhcyB1bmtub3duIGFzIFQ7XG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFNlcmlhbGl6ZXMgYSBtb2RlbFxuICAgKiBAcGFyYW0ge1R9IG1vZGVsXG4gICAqXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBpZiBmYWlscyB0byBzZXJpYWxpemVcbiAgICovXG4gIHNlcmlhbGl6ZShtb2RlbDogVCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRoaXMucHJlU2VyaWFsaXplKG1vZGVsKSk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNlcmlhbGl6YXRpb24ge1xuICBwcml2YXRlIHN0YXRpYyBjdXJyZW50OiBzdHJpbmcgPSBEZWZhdWx0U2VyaWFsaXphdGlvbk1ldGhvZDtcblxuICBwcml2YXRlIHN0YXRpYyBjYWNoZTogUmVjb3JkPHN0cmluZywgU2VyaWFsaXplcjxhbnk+PiA9IHtcbiAgICBqc29uOiBuZXcgSlNPTlNlcmlhbGl6ZXIoKSxcbiAgfTtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cblxuICBwcml2YXRlIHN0YXRpYyBnZXQoa2V5OiBzdHJpbmcpOiBhbnkge1xuICAgIGlmIChrZXkgaW4gdGhpcy5jYWNoZSkgcmV0dXJuIHRoaXMuY2FjaGVba2V5XTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIHNlcmlhbGl6YXRpb24gbWV0aG9kIHJlZ2lzdGVyZWQgdW5kZXIgJHtrZXl9YCk7XG4gIH1cblxuICBzdGF0aWMgcmVnaXN0ZXIoXG4gICAga2V5OiBzdHJpbmcsXG4gICAgZnVuYzogQ29uc3RydWN0b3I8U2VyaWFsaXplcjxhbnk+PixcbiAgICBzZXREZWZhdWx0ID0gZmFsc2VcbiAgKTogdm9pZCB7XG4gICAgaWYgKGtleSBpbiB0aGlzLmNhY2hlKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBTZXJpYWxpemF0aW9uIG1ldGhvZCAke2tleX0gYWxyZWFkeSByZWdpc3RlcmVkYCk7XG4gICAgdGhpcy5jYWNoZVtrZXldID0gbmV3IGZ1bmMoKTtcbiAgICBpZiAoc2V0RGVmYXVsdCkgdGhpcy5jdXJyZW50ID0ga2V5O1xuICB9XG5cbiAgc3RhdGljIHNlcmlhbGl6ZShvYmo6IGFueSwgbWV0aG9kPzogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGlmICghbWV0aG9kKSByZXR1cm4gdGhpcy5nZXQodGhpcy5jdXJyZW50KS5zZXJpYWxpemUob2JqLCAuLi5hcmdzKTtcbiAgICByZXR1cm4gdGhpcy5nZXQobWV0aG9kKS5zZXJpYWxpemUob2JqLCAuLi5hcmdzKTtcbiAgfVxuXG4gIHN0YXRpYyBkZXNlcmlhbGl6ZShvYmo6IHN0cmluZywgbWV0aG9kPzogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGlmICghbWV0aG9kKSByZXR1cm4gdGhpcy5nZXQodGhpcy5jdXJyZW50KS5kZXNlcmlhbGl6ZShvYmosIC4uLmFyZ3MpO1xuICAgIHJldHVybiB0aGlzLmdldChtZXRob2QpLmRlc2VyaWFsaXplKG9iaiwgLi4uYXJncyk7XG4gIH1cblxuICBzdGF0aWMgc2V0RGVmYXVsdChtZXRob2Q6IHN0cmluZykge1xuICAgIHRoaXMuY3VycmVudCA9IHRoaXMuZ2V0KG1ldGhvZCk7XG4gIH1cbn1cbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uXHJcblxyXG5QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcclxucHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLlxyXG5cclxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxyXG5SRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFlcclxuQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgRElSRUNULFxyXG5JTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cclxuTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1JcclxuT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUlxyXG5QRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSwgU3VwcHJlc3NlZEVycm9yLCBTeW1ib2wsIEl0ZXJhdG9yICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2VzRGVjb3JhdGUoY3RvciwgZGVzY3JpcHRvckluLCBkZWNvcmF0b3JzLCBjb250ZXh0SW4sIGluaXRpYWxpemVycywgZXh0cmFJbml0aWFsaXplcnMpIHtcclxuICAgIGZ1bmN0aW9uIGFjY2VwdChmKSB7IGlmIChmICE9PSB2b2lkIDAgJiYgdHlwZW9mIGYgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkZ1bmN0aW9uIGV4cGVjdGVkXCIpOyByZXR1cm4gZjsgfVxyXG4gICAgdmFyIGtpbmQgPSBjb250ZXh0SW4ua2luZCwga2V5ID0ga2luZCA9PT0gXCJnZXR0ZXJcIiA/IFwiZ2V0XCIgOiBraW5kID09PSBcInNldHRlclwiID8gXCJzZXRcIiA6IFwidmFsdWVcIjtcclxuICAgIHZhciB0YXJnZXQgPSAhZGVzY3JpcHRvckluICYmIGN0b3IgPyBjb250ZXh0SW5bXCJzdGF0aWNcIl0gPyBjdG9yIDogY3Rvci5wcm90b3R5cGUgOiBudWxsO1xyXG4gICAgdmFyIGRlc2NyaXB0b3IgPSBkZXNjcmlwdG9ySW4gfHwgKHRhcmdldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBjb250ZXh0SW4ubmFtZSkgOiB7fSk7XHJcbiAgICB2YXIgXywgZG9uZSA9IGZhbHNlO1xyXG4gICAgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICB2YXIgY29udGV4dCA9IHt9O1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluKSBjb250ZXh0W3BdID0gcCA9PT0gXCJhY2Nlc3NcIiA/IHt9IDogY29udGV4dEluW3BdO1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluLmFjY2VzcykgY29udGV4dC5hY2Nlc3NbcF0gPSBjb250ZXh0SW4uYWNjZXNzW3BdO1xyXG4gICAgICAgIGNvbnRleHQuYWRkSW5pdGlhbGl6ZXIgPSBmdW5jdGlvbiAoZikgeyBpZiAoZG9uZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBhZGQgaW5pdGlhbGl6ZXJzIGFmdGVyIGRlY29yYXRpb24gaGFzIGNvbXBsZXRlZFwiKTsgZXh0cmFJbml0aWFsaXplcnMucHVzaChhY2NlcHQoZiB8fCBudWxsKSk7IH07XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9ICgwLCBkZWNvcmF0b3JzW2ldKShraW5kID09PSBcImFjY2Vzc29yXCIgPyB7IGdldDogZGVzY3JpcHRvci5nZXQsIHNldDogZGVzY3JpcHRvci5zZXQgfSA6IGRlc2NyaXB0b3Jba2V5XSwgY29udGV4dCk7XHJcbiAgICAgICAgaWYgKGtpbmQgPT09IFwiYWNjZXNzb3JcIikge1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSB2b2lkIDApIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsIHx8IHR5cGVvZiByZXN1bHQgIT09IFwib2JqZWN0XCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJPYmplY3QgZXhwZWN0ZWRcIik7XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5nZXQpKSBkZXNjcmlwdG9yLmdldCA9IF87XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5zZXQpKSBkZXNjcmlwdG9yLnNldCA9IF87XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5pbml0KSkgaW5pdGlhbGl6ZXJzLnVuc2hpZnQoXyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKF8gPSBhY2NlcHQocmVzdWx0KSkge1xyXG4gICAgICAgICAgICBpZiAoa2luZCA9PT0gXCJmaWVsZFwiKSBpbml0aWFsaXplcnMudW5zaGlmdChfKTtcclxuICAgICAgICAgICAgZWxzZSBkZXNjcmlwdG9yW2tleV0gPSBfO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICh0YXJnZXQpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGNvbnRleHRJbi5uYW1lLCBkZXNjcmlwdG9yKTtcclxuICAgIGRvbmUgPSB0cnVlO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcnVuSW5pdGlhbGl6ZXJzKHRoaXNBcmcsIGluaXRpYWxpemVycywgdmFsdWUpIHtcclxuICAgIHZhciB1c2VWYWx1ZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAyO1xyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbml0aWFsaXplcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICB2YWx1ZSA9IHVzZVZhbHVlID8gaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZywgdmFsdWUpIDogaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdXNlVmFsdWUgPyB2YWx1ZSA6IHZvaWQgMDtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Byb3BLZXkoeCkge1xyXG4gICAgcmV0dXJuIHR5cGVvZiB4ID09PSBcInN5bWJvbFwiID8geCA6IFwiXCIuY29uY2F0KHgpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc2V0RnVuY3Rpb25OYW1lKGYsIG5hbWUsIHByZWZpeCkge1xyXG4gICAgaWYgKHR5cGVvZiBuYW1lID09PSBcInN5bWJvbFwiKSBuYW1lID0gbmFtZS5kZXNjcmlwdGlvbiA/IFwiW1wiLmNvbmNhdChuYW1lLmRlc2NyaXB0aW9uLCBcIl1cIikgOiBcIlwiO1xyXG4gICAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmLCBcIm5hbWVcIiwgeyBjb25maWd1cmFibGU6IHRydWUsIHZhbHVlOiBwcmVmaXggPyBcIlwiLmNvbmNhdChwcmVmaXgsIFwiIFwiLCBuYW1lKSA6IG5hbWUgfSk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0Lm1ldGFkYXRhID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXRlcih0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2dlbmVyYXRvcih0aGlzQXJnLCBib2R5KSB7XHJcbiAgICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnID0gT2JqZWN0LmNyZWF0ZSgodHlwZW9mIEl0ZXJhdG9yID09PSBcImZ1bmN0aW9uXCIgPyBJdGVyYXRvciA6IE9iamVjdCkucHJvdG90eXBlKTtcclxuICAgIHJldHVybiBnLm5leHQgPSB2ZXJiKDApLCBnW1widGhyb3dcIl0gPSB2ZXJiKDEpLCBnW1wicmV0dXJuXCJdID0gdmVyYigyKSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChnICYmIChnID0gMCwgb3BbMF0gJiYgKF8gPSAwKSksIF8pIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcclxuICAgICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cclxuICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2NyZWF0ZUJpbmRpbmcgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xyXG4gICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcclxuICAgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xyXG4gICAgfVxyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcclxufSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBvW2syXSA9IG1ba107XHJcbn0pO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBvKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIHApKSBfX2NyZWF0ZUJpbmRpbmcobywgbSwgcCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7XHJcbiAgICB2YXIgcyA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBTeW1ib2wuaXRlcmF0b3IsIG0gPSBzICYmIG9bc10sIGkgPSAwO1xyXG4gICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICBpZiAobyAmJiB0eXBlb2Ygby5sZW5ndGggPT09IFwibnVtYmVyXCIpIHJldHVybiB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IocyA/IFwiT2JqZWN0IGlzIG5vdCBpdGVyYWJsZS5cIiA6IFwiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVhZChvLCBuKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheXMoKSB7XHJcbiAgICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcclxuICAgIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcclxuICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcclxuICAgICAgICAgICAgcltrXSA9IGFbal07XHJcbiAgICByZXR1cm4gcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXkodG8sIGZyb20sIHBhY2spIHtcclxuICAgIGlmIChwYWNrIHx8IGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIGZvciAodmFyIGkgPSAwLCBsID0gZnJvbS5sZW5ndGgsIGFyOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKGFyIHx8ICEoaSBpbiBmcm9tKSkge1xyXG4gICAgICAgICAgICBpZiAoIWFyKSBhciA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20sIDAsIGkpO1xyXG4gICAgICAgICAgICBhcltpXSA9IGZyb21baV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRvLmNvbmNhdChhciB8fCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tKSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0KHYpIHtcclxuICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgX19hd2FpdCA/ICh0aGlzLnYgPSB2LCB0aGlzKSA6IG5ldyBfX2F3YWl0KHYpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0dlbmVyYXRvcih0aGlzQXJnLCBfYXJndW1lbnRzLCBnZW5lcmF0b3IpIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgZyA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSwgaSwgcSA9IFtdO1xyXG4gICAgcmV0dXJuIGkgPSBPYmplY3QuY3JlYXRlKCh0eXBlb2YgQXN5bmNJdGVyYXRvciA9PT0gXCJmdW5jdGlvblwiID8gQXN5bmNJdGVyYXRvciA6IE9iamVjdCkucHJvdG90eXBlKSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiLCBhd2FpdFJldHVybiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIGF3YWl0UmV0dXJuKGYpIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBQcm9taXNlLnJlc29sdmUodikudGhlbihmLCByZWplY3QpOyB9OyB9XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaWYgKGdbbl0pIHsgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgaWYgKGYpIGlbbl0gPSBmKGlbbl0pOyB9IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBmYWxzZSB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY1ZhbHVlcyhvKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIG0gPSBvW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSwgaTtcclxuICAgIHJldHVybiBtID8gbS5jYWxsKG8pIDogKG8gPSB0eXBlb2YgX192YWx1ZXMgPT09IFwiZnVuY3Rpb25cIiA/IF9fdmFsdWVzKG8pIDogb1tTeW1ib2wuaXRlcmF0b3JdKCksIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpKTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpW25dID0gb1tuXSAmJiBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgeyB2ID0gb1tuXSh2KSwgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgdi5kb25lLCB2LnZhbHVlKTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIGQsIHYpIHsgUHJvbWlzZS5yZXNvbHZlKHYpLnRoZW4oZnVuY3Rpb24odikgeyByZXNvbHZlKHsgdmFsdWU6IHYsIGRvbmU6IGQgfSk7IH0sIHJlamVjdCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWFrZVRlbXBsYXRlT2JqZWN0KGNvb2tlZCwgcmF3KSB7XHJcbiAgICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb29rZWQsIFwicmF3XCIsIHsgdmFsdWU6IHJhdyB9KTsgfSBlbHNlIHsgY29va2VkLnJhdyA9IHJhdzsgfVxyXG4gICAgcmV0dXJuIGNvb2tlZDtcclxufTtcclxuXHJcbnZhciBfX3NldE1vZHVsZURlZmF1bHQgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBcImRlZmF1bHRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdiB9KTtcclxufSkgOiBmdW5jdGlvbihvLCB2KSB7XHJcbiAgICBvW1wiZGVmYXVsdFwiXSA9IHY7XHJcbn07XHJcblxyXG52YXIgb3duS2V5cyA9IGZ1bmN0aW9uKG8pIHtcclxuICAgIG93bktleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyB8fCBmdW5jdGlvbiAobykge1xyXG4gICAgICAgIHZhciBhciA9IFtdO1xyXG4gICAgICAgIGZvciAodmFyIGsgaW4gbykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBrKSkgYXJbYXIubGVuZ3RoXSA9IGs7XHJcbiAgICAgICAgcmV0dXJuIGFyO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBvd25LZXlzKG8pO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0U3Rhcihtb2QpIHtcclxuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XHJcbiAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgPSBvd25LZXlzKG1vZCksIGkgPSAwOyBpIDwgay5sZW5ndGg7IGkrKykgaWYgKGtbaV0gIT09IFwiZGVmYXVsdFwiKSBfX2NyZWF0ZUJpbmRpbmcocmVzdWx0LCBtb2QsIGtbaV0pO1xyXG4gICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEdldChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcclxuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcclxuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRTZXQocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEluKHN0YXRlLCByZWNlaXZlcikge1xyXG4gICAgaWYgKHJlY2VpdmVyID09PSBudWxsIHx8ICh0eXBlb2YgcmVjZWl2ZXIgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlY2VpdmVyICE9PSBcImZ1bmN0aW9uXCIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHVzZSAnaW4nIG9wZXJhdG9yIG9uIG5vbi1vYmplY3RcIik7XHJcbiAgICByZXR1cm4gdHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciA9PT0gc3RhdGUgOiBzdGF0ZS5oYXMocmVjZWl2ZXIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hZGREaXNwb3NhYmxlUmVzb3VyY2UoZW52LCB2YWx1ZSwgYXN5bmMpIHtcclxuICAgIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdm9pZCAwKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZC5cIik7XHJcbiAgICAgICAgdmFyIGRpc3Bvc2UsIGlubmVyO1xyXG4gICAgICAgIGlmIChhc3luYykge1xyXG4gICAgICAgICAgICBpZiAoIVN5bWJvbC5hc3luY0Rpc3Bvc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNEaXNwb3NlIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgICAgICAgICAgZGlzcG9zZSA9IHZhbHVlW1N5bWJvbC5hc3luY0Rpc3Bvc2VdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZGlzcG9zZSA9PT0gdm9pZCAwKSB7XHJcbiAgICAgICAgICAgIGlmICghU3ltYm9sLmRpc3Bvc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuZGlzcG9zZSBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICAgICAgICAgIGRpc3Bvc2UgPSB2YWx1ZVtTeW1ib2wuZGlzcG9zZV07XHJcbiAgICAgICAgICAgIGlmIChhc3luYykgaW5uZXIgPSBkaXNwb3NlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodHlwZW9mIGRpc3Bvc2UgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBub3QgZGlzcG9zYWJsZS5cIik7XHJcbiAgICAgICAgaWYgKGlubmVyKSBkaXNwb3NlID0gZnVuY3Rpb24oKSB7IHRyeSB7IGlubmVyLmNhbGwodGhpcyk7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIFByb21pc2UucmVqZWN0KGUpOyB9IH07XHJcbiAgICAgICAgZW52LnN0YWNrLnB1c2goeyB2YWx1ZTogdmFsdWUsIGRpc3Bvc2U6IGRpc3Bvc2UsIGFzeW5jOiBhc3luYyB9KTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGFzeW5jKSB7XHJcbiAgICAgICAgZW52LnN0YWNrLnB1c2goeyBhc3luYzogdHJ1ZSB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiB2YWx1ZTtcclxuXHJcbn1cclxuXHJcbnZhciBfU3VwcHJlc3NlZEVycm9yID0gdHlwZW9mIFN1cHByZXNzZWRFcnJvciA9PT0gXCJmdW5jdGlvblwiID8gU3VwcHJlc3NlZEVycm9yIDogZnVuY3Rpb24gKGVycm9yLCBzdXBwcmVzc2VkLCBtZXNzYWdlKSB7XHJcbiAgICB2YXIgZSA9IG5ldyBFcnJvcihtZXNzYWdlKTtcclxuICAgIHJldHVybiBlLm5hbWUgPSBcIlN1cHByZXNzZWRFcnJvclwiLCBlLmVycm9yID0gZXJyb3IsIGUuc3VwcHJlc3NlZCA9IHN1cHByZXNzZWQsIGU7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kaXNwb3NlUmVzb3VyY2VzKGVudikge1xyXG4gICAgZnVuY3Rpb24gZmFpbChlKSB7XHJcbiAgICAgICAgZW52LmVycm9yID0gZW52Lmhhc0Vycm9yID8gbmV3IF9TdXBwcmVzc2VkRXJyb3IoZSwgZW52LmVycm9yLCBcIkFuIGVycm9yIHdhcyBzdXBwcmVzc2VkIGR1cmluZyBkaXNwb3NhbC5cIikgOiBlO1xyXG4gICAgICAgIGVudi5oYXNFcnJvciA9IHRydWU7XHJcbiAgICB9XHJcbiAgICB2YXIgciwgcyA9IDA7XHJcbiAgICBmdW5jdGlvbiBuZXh0KCkge1xyXG4gICAgICAgIHdoaWxlIChyID0gZW52LnN0YWNrLnBvcCgpKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXIuYXN5bmMgJiYgcyA9PT0gMSkgcmV0dXJuIHMgPSAwLCBlbnYuc3RhY2sucHVzaChyKSwgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihuZXh0KTtcclxuICAgICAgICAgICAgICAgIGlmIChyLmRpc3Bvc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gci5kaXNwb3NlLmNhbGwoci52YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHIuYXN5bmMpIHJldHVybiBzIHw9IDIsIFByb21pc2UucmVzb2x2ZShyZXN1bHQpLnRoZW4obmV4dCwgZnVuY3Rpb24oZSkgeyBmYWlsKGUpOyByZXR1cm4gbmV4dCgpOyB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgcyB8PSAxO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBmYWlsKGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChzID09PSAxKSByZXR1cm4gZW52Lmhhc0Vycm9yID8gUHJvbWlzZS5yZWplY3QoZW52LmVycm9yKSA6IFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIGlmIChlbnYuaGFzRXJyb3IpIHRocm93IGVudi5lcnJvcjtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXh0KCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Jld3JpdGVSZWxhdGl2ZUltcG9ydEV4dGVuc2lvbihwYXRoLCBwcmVzZXJ2ZUpzeCkge1xyXG4gICAgaWYgKHR5cGVvZiBwYXRoID09PSBcInN0cmluZ1wiICYmIC9eXFwuXFwuP1xcLy8udGVzdChwYXRoKSkge1xyXG4gICAgICAgIHJldHVybiBwYXRoLnJlcGxhY2UoL1xcLih0c3gpJHwoKD86XFwuZCk/KSgoPzpcXC5bXi4vXSs/KT8pXFwuKFtjbV0/KXRzJC9pLCBmdW5jdGlvbiAobSwgdHN4LCBkLCBleHQsIGNtKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0c3ggPyBwcmVzZXJ2ZUpzeCA/IFwiLmpzeFwiIDogXCIuanNcIiA6IGQgJiYgKCFleHQgfHwgIWNtKSA/IG0gOiAoZCArIGV4dCArIFwiLlwiICsgY20udG9Mb3dlckNhc2UoKSArIFwianNcIik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcGF0aDtcclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQge1xyXG4gICAgX19leHRlbmRzOiBfX2V4dGVuZHMsXHJcbiAgICBfX2Fzc2lnbjogX19hc3NpZ24sXHJcbiAgICBfX3Jlc3Q6IF9fcmVzdCxcclxuICAgIF9fZGVjb3JhdGU6IF9fZGVjb3JhdGUsXHJcbiAgICBfX3BhcmFtOiBfX3BhcmFtLFxyXG4gICAgX19lc0RlY29yYXRlOiBfX2VzRGVjb3JhdGUsXHJcbiAgICBfX3J1bkluaXRpYWxpemVyczogX19ydW5Jbml0aWFsaXplcnMsXHJcbiAgICBfX3Byb3BLZXk6IF9fcHJvcEtleSxcclxuICAgIF9fc2V0RnVuY3Rpb25OYW1lOiBfX3NldEZ1bmN0aW9uTmFtZSxcclxuICAgIF9fbWV0YWRhdGE6IF9fbWV0YWRhdGEsXHJcbiAgICBfX2F3YWl0ZXI6IF9fYXdhaXRlcixcclxuICAgIF9fZ2VuZXJhdG9yOiBfX2dlbmVyYXRvcixcclxuICAgIF9fY3JlYXRlQmluZGluZzogX19jcmVhdGVCaW5kaW5nLFxyXG4gICAgX19leHBvcnRTdGFyOiBfX2V4cG9ydFN0YXIsXHJcbiAgICBfX3ZhbHVlczogX192YWx1ZXMsXHJcbiAgICBfX3JlYWQ6IF9fcmVhZCxcclxuICAgIF9fc3ByZWFkOiBfX3NwcmVhZCxcclxuICAgIF9fc3ByZWFkQXJyYXlzOiBfX3NwcmVhZEFycmF5cyxcclxuICAgIF9fc3ByZWFkQXJyYXk6IF9fc3ByZWFkQXJyYXksXHJcbiAgICBfX2F3YWl0OiBfX2F3YWl0LFxyXG4gICAgX19hc3luY0dlbmVyYXRvcjogX19hc3luY0dlbmVyYXRvcixcclxuICAgIF9fYXN5bmNEZWxlZ2F0b3I6IF9fYXN5bmNEZWxlZ2F0b3IsXHJcbiAgICBfX2FzeW5jVmFsdWVzOiBfX2FzeW5jVmFsdWVzLFxyXG4gICAgX19tYWtlVGVtcGxhdGVPYmplY3Q6IF9fbWFrZVRlbXBsYXRlT2JqZWN0LFxyXG4gICAgX19pbXBvcnRTdGFyOiBfX2ltcG9ydFN0YXIsXHJcbiAgICBfX2ltcG9ydERlZmF1bHQ6IF9faW1wb3J0RGVmYXVsdCxcclxuICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQ6IF9fY2xhc3NQcml2YXRlRmllbGRHZXQsXHJcbiAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0OiBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0LFxyXG4gICAgX19jbGFzc1ByaXZhdGVGaWVsZEluOiBfX2NsYXNzUHJpdmF0ZUZpZWxkSW4sXHJcbiAgICBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZTogX19hZGREaXNwb3NhYmxlUmVzb3VyY2UsXHJcbiAgICBfX2Rpc3Bvc2VSZXNvdXJjZXM6IF9fZGlzcG9zZVJlc291cmNlcyxcclxuICAgIF9fcmV3cml0ZVJlbGF0aXZlSW1wb3J0RXh0ZW5zaW9uOiBfX3Jld3JpdGVSZWxhdGl2ZUltcG9ydEV4dGVuc2lvbixcclxufTtcclxuIiwiaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgc2YgfSBmcm9tIFwiLi4vLi4vdXRpbHMvc3RyaW5nc1wiO1xuaW1wb3J0IHsgUmVmbGVjdGlvbiB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IEJhc2UgSW1wbGVtZW50YXRpb24gZm9yIFZhbGlkYXRvcnNcbiAqIEBkZXNjcmlwdGlvbiBQcm92aWRlcyB0aGUgdW5kZXJseWluZyBmdW5jdGlvbmFsaXR5IGZvciB7QGxpbmsgVmFsaWRhdG9yfXNcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdmFsaWRhdGlvbktleSB0aGUga2V5IHRvIHJlZ2lzdGVyIHRoZSB2YWxpZGF0b3IgdW5kZXJcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gdGhlIGVycm9yIG1lc3NhZ2UuIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0RFRkFVTFR9XG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBbYWNjZXB0ZWRUeXBlc10gZGVmaW5lcyB0aGUgdmFsdWUgdHlwZXMgdGhpcyB2YWxpZGF0b3IgY2FuIHZhbGlkYXRlXG4gKlxuICogQGNsYXNzIFZhbGlkYXRvclxuICogQGFic3RyYWN0XG4gKiBAY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgVmFsaWRhdG9yPFYgZXh0ZW5kcyBWYWxpZGF0b3JPcHRpb25zID0gVmFsaWRhdG9yT3B0aW9ucz4ge1xuICByZWFkb25seSBtZXNzYWdlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGFjY2VwdGVkVHlwZXM/OiBzdHJpbmdbXTtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoXG4gICAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5ERUZBVUxULFxuICAgIC4uLmFjY2VwdGVkVHlwZXM6IHN0cmluZ1tdXG4gICkge1xuICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG5cbiAgICBpZiAoYWNjZXB0ZWRUeXBlcy5sZW5ndGgpIHRoaXMuYWNjZXB0ZWRUeXBlcyA9IGFjY2VwdGVkVHlwZXM7XG4gICAgaWYgKHRoaXMuYWNjZXB0ZWRUeXBlcylcbiAgICAgIHRoaXMuaGFzRXJyb3JzID0gdGhpcy5jaGVja1R5cGVBbmRIYXNFcnJvcnModGhpcy5oYXNFcnJvcnMuYmluZCh0aGlzKSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgYnVpbGRzIHRoZSBlcnJvciBtZXNzYWdlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gICAqIEBwYXJhbSB7YW55W119IGFyZ3NcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE1lc3NhZ2UobWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIHJldHVybiBzZihtZXNzYWdlLCAuLi5hcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgdHlwZVxuICAgKiBAcGFyYW0ge2FueX0gdW5ib3VuZFxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBjaGVja1R5cGVBbmRIYXNFcnJvcnMoXG4gICAgdW5ib3VuZDogKHZhbHVlOiBhbnksIC4uLmFyZ3M6IGFueVtdKSA9PiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChcbiAgICAgIHRoaXM6IFZhbGlkYXRvcixcbiAgICAgIHZhbHVlOiBhbnksXG4gICAgICAuLi5hcmdzOiBhbnlbXVxuICAgICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCAhdGhpcy5hY2NlcHRlZFR5cGVzKVxuICAgICAgICByZXR1cm4gdW5ib3VuZCh2YWx1ZSwgLi4uYXJncyk7XG4gICAgICBpZiAoIVJlZmxlY3Rpb24uY2hlY2tUeXBlcyh2YWx1ZSwgdGhpcy5hY2NlcHRlZFR5cGVzKSlcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZShcbiAgICAgICAgICBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlRZUEUsXG4gICAgICAgICAgdGhpcy5hY2NlcHRlZFR5cGVzLmpvaW4oXCIsIFwiKSxcbiAgICAgICAgICB0eXBlb2YgdmFsdWVcbiAgICAgICAgKTtcbiAgICAgIHJldHVybiB1bmJvdW5kKHZhbHVlLCAuLi5hcmdzKTtcbiAgICB9LmJpbmQodGhpcyk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIGFuIGF0dHJpYnV0ZVxuICAgKiBAcGFyYW0ge2FueX0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gYmUgdmFsaWRhdGVkLlxuICAgKiBAcGFyYW0ge1ZhbGlkYXRvck9wdGlvbnN9IFtvcHRpb25zXSBWYWxpZGF0ZSBvcHRpb25zIGZvciBjdXN0b21pemluZyB0aGUgbW9kZWwgdmFsaWRhdGlvbiBiZWhhdmlvclxuICAgKiBAcGFyYW0ge2FueX0gW2luc3RhbmNlT2JqXSAtIFRoZSBvYmplY3QgaW5zdGFuY2UgdGhhdCBjb250YWlucyB0aGUga2V5LXZhbHVlIGJlaW5nIHZhbGlkYXRlZC4gVXNlZCBmb3IgY3Jvc3MtZmllbGQgdmFsaWRhdGlvbi4gRGVmYXVsdHMgdG8gYW4gZW1wdHkgb2JqZWN0LlxuICAgKlxuICAgKiBAcmV0dXJucyBBbiBlcnJvciBtZXNzYWdlIHN0cmluZyBpZiB2YWxpZGF0aW9uIGZhaWxzOyBvdGhlcndpc2UsIGB1bmRlZmluZWRgLlxuICAgKlxuICAgKiBAYWJzdHJhY3RcbiAgICpcbiAgICogQHNlZSBNb2RlbCNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBhYnN0cmFjdCBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IGFueSxcbiAgICBvcHRpb25zPzogVixcbiAgICBpbnN0YW5jZU9iaj86IGFueVxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tIFwiLi9WYWxpZGF0b3JcIjtcbmltcG9ydCB7IFZhbGlkYXRpb24gfSBmcm9tIFwiLi4vVmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IgfSBmcm9tIFwiLi4vLi4vbW9kZWwvdHlwZXNcIjtcbmltcG9ydCB7IFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBhcHBseSwgbWV0YWRhdGEgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IFZhbGlkYXRvckRlZmluaXRpb24gfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBNYXJrcyB0aGUgY2xhc3MgYXMgYSB2YWxpZGF0b3IgZm9yIGEgY2VydGFpbiBrZXkuXG4gKiBAZGVzY3JpcHRpb24gUmVnaXN0ZXJzIHRoZSBjbGFzcyBpbiB0aGUge0BsaW5rIFZhbGlkYXRpb259IHdpdGggdGhlIHByb3ZpZGVkIGtleVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlzIHRoZSB2YWxpZGF0aW9uIGtleVxuICpcbiAqIEBmdW5jdGlvbiB2YWxpZGF0b3JcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdG9yPFQgZXh0ZW5kcyBWYWxpZGF0b3I+KC4uLmtleXM6IHN0cmluZ1tdKSB7XG4gIHJldHVybiBhcHBseShcbiAgICAoKG9yaWdpbmFsOiBDb25zdHJ1Y3RvcjxUPikgPT4ge1xuICAgICAga2V5cy5mb3JFYWNoKChrOiBzdHJpbmcpID0+IHtcbiAgICAgICAgVmFsaWRhdGlvbi5yZWdpc3Rlcih7XG4gICAgICAgICAgdmFsaWRhdG9yOiBvcmlnaW5hbCxcbiAgICAgICAgICB2YWxpZGF0aW9uS2V5OiBrLFxuICAgICAgICAgIHNhdmU6IHRydWUsXG4gICAgICAgIH0gYXMgVmFsaWRhdG9yRGVmaW5pdGlvbik7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBvcmlnaW5hbDtcbiAgICB9KSBhcyBDbGFzc0RlY29yYXRvcixcbiAgICBtZXRhZGF0YShWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5WQUxJREFUT1IpLCBrZXlzKVxuICApO1xufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgRGF0ZVZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBEYXRlIFZhbGlkYXRvclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjREFURX1cbiAqXG4gKiBAY2xhc3MgRGF0ZVZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5EQVRFKVxuZXhwb3J0IGNsYXNzIERhdGVWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3I8RGF0ZVZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5EQVRFKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgTnVtYmVyLm5hbWUsIERhdGUubmFtZSwgU3RyaW5nLm5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIG1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSB7RGF0ZSB8IHN0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtEYXRlVmFsaWRhdG9yT3B0aW9uc30gW29wdGlvbnNdXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogRGF0ZSB8IHN0cmluZyxcbiAgICBvcHRpb25zOiBEYXRlVmFsaWRhdG9yT3B0aW9ucyA9IHt9XG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybjtcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHZhbHVlID0gbmV3IERhdGUodmFsdWUpO1xuXG4gICAgaWYgKE51bWJlci5pc05hTih2YWx1ZS5nZXREYXRlKCkpKSB7XG4gICAgICBjb25zdCB7IG1lc3NhZ2UgPSBcIlwiIH0gPSBvcHRpb25zO1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZShtZXNzYWdlIHx8IHRoaXMubWVzc2FnZSk7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgeyBWQUxJREFUSU9OX1BBUkVOVF9LRVkgfSBmcm9tIFwiLi4vLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBzZiB9IGZyb20gXCIuLi8uLi91dGlscy9zdHJpbmdzXCI7XG5pbXBvcnQgeyBDT01QQVJJU09OX0VSUk9SX01FU1NBR0VTIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbi8qKlxuICogU2FmZWx5IHJldHJpZXZlcyBhIG5lc3RlZCBwcm9wZXJ0eSB2YWx1ZSBmcm9tIGFuIG9iamVjdCB1c2luZyBhIGRvdC1ub3RhdGVkIHBhdGggc3RyaW5nLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIC0gVGhlIGV4cGVjdGVkIHJldHVybiB0eXBlIG9mIHRoZSBwcm9wZXJ0eSB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IG9iaiAtIFRoZSBzb3VyY2Ugb2JqZWN0IHRvIHJldHJpZXZlIHRoZSB2YWx1ZSBmcm9tLlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBBIGRvdC1zZXBhcmF0ZWQgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgcGF0aCB0byB0aGUgZGVzaXJlZCBwcm9wZXJ0eSAoZS5nLiwgXCJ1c2VyLmFkZHJlc3Muc3RyZWV0XCIpLlxuICpcbiAqIEByZXR1cm5zIHtUfSAtIFRoZSB2YWx1ZSBmb3VuZCBhdCB0aGUgc3BlY2lmaWVkIHBhdGhcbiAqXG4gKiBAdGhyb3dzIHtFcnJvcn0gLSBUaHJvd3MgYW4gZXJyb3IgaWYgdGhlIHBhdGggaXMgbm90IGEgbm9uLWVtcHR5IHN0cmluZyBvciBpZiBhbnkgcGFydCBvZiB0aGUgcGF0aCBkb2VzIG5vdCBleGlzdCBpbiB0aGUgb2JqZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmFsdWVCeVBhdGg8VD4ob2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBwYXRoOiBzdHJpbmcpOiBUIHtcbiAgaWYgKHR5cGVvZiBwYXRoICE9PSBcInN0cmluZ1wiIHx8ICFwYXRoLnRyaW0oKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihzZihDT01QQVJJU09OX0VSUk9SX01FU1NBR0VTLklOVkFMSURfUEFUSCwgcGF0aCkpO1xuICB9XG5cbiAgLy8gUHJvY2VzcyBwYXJlbnQgZGlyZWN0b3J5IGFjY2VzcyAoLi4vKVxuICBjb25zdCBwYXJlbnRBY2Nlc3NvcnMgPSBwYXRoLm1hdGNoKC9cXC5cXC5cXC8vZykgfHwgW107XG4gIGNvbnN0IHBhcmVudExldmVsID0gcGFyZW50QWNjZXNzb3JzLmxlbmd0aDtcbiAgY29uc3QgY2xlYW5QYXRoID0gcGF0aC5yZXBsYWNlKC9cXC5cXC5cXC8vZywgXCJcIik7XG5cbiAgLy8gTmF2aWdhdGUgdXAgdGhlIHBhcmVudCBjaGFpblxuICBsZXQgY3VycmVudENvbnRleHQ6IGFueSA9IG9iajtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJlbnRMZXZlbDsgaSsrKSB7XG4gICAgaWYgKCFjdXJyZW50Q29udGV4dCB8fCB0eXBlb2YgY3VycmVudENvbnRleHQgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgc2YoQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUy5DT05URVhUX05PVF9PQkpFQ1RfQ09NUEFSSVNPTiwgaSArIDEsIHBhdGgpXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghY3VycmVudENvbnRleHRbVkFMSURBVElPTl9QQVJFTlRfS0VZXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBzZihDT01QQVJJU09OX0VSUk9SX01FU1NBR0VTLk5PX1BBUkVOVF9DT01QQVJJU09OLCBpICsgMSwgcGF0aClcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY3VycmVudENvbnRleHQgPSBjdXJyZW50Q29udGV4dFtWQUxJREFUSU9OX1BBUkVOVF9LRVldO1xuICB9XG5cbiAgLy8gUHJvY2VzcyBkb3Qgbm90YXRpb24gcGF0aFxuICBjb25zdCBwYXJ0cyA9IGNsZWFuUGF0aC5zcGxpdChcIi5cIik7XG4gIGxldCBjdXJyZW50VmFsdWU6IGFueSA9IGN1cnJlbnRDb250ZXh0O1xuXG4gIGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuICAgIGlmIChcbiAgICAgIGN1cnJlbnRWYWx1ZSAhPT0gbnVsbCAmJlxuICAgICAgdHlwZW9mIGN1cnJlbnRWYWx1ZSA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgcGFydCBpbiBjdXJyZW50VmFsdWVcbiAgICApIHtcbiAgICAgIGN1cnJlbnRWYWx1ZSA9IChjdXJyZW50VmFsdWUgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcGFydF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGVycm9yTXNnVGVtcGxhdGUgPVxuICAgICAgICBwYXJlbnRMZXZlbCA9PT0gMFxuICAgICAgICAgID8gQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUy5QUk9QRVJUWV9OT1RfRk9VTkRcbiAgICAgICAgICA6IHBhcmVudExldmVsID09PSAxXG4gICAgICAgICAgICA/IENPTVBBUklTT05fRVJST1JfTUVTU0FHRVMuUFJPUEVSVFlfTk9UX0ZPVU5EX09OX1BBUkVOVFxuICAgICAgICAgICAgOiBDT01QQVJJU09OX0VSUk9SX01FU1NBR0VTLlBST1BFUlRZX05PVF9GT1VORF9BRlRFUl9QQVJFTlQ7XG5cbiAgICAgIHRocm93IG5ldyBFcnJvcihzZihlcnJvck1zZ1RlbXBsYXRlLCBwYXRoLCBwYXJ0LCBwYXJlbnRMZXZlbCkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBjdXJyZW50VmFsdWUgYXMgVDtcbn1cblxuY29uc3QgZ2V0VHlwZU5hbWUgPSAodmFsdWU6IHVua25vd24pOiBzdHJpbmcgPT4ge1xuICBpZiAodmFsdWUgPT09IG51bGwpIHJldHVybiBcIm51bGxcIjtcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkgcmV0dXJuIFwiRGF0ZVwiO1xuICBpZiAoTnVtYmVyLmlzTmFOKHZhbHVlKSkgcmV0dXJuIFwiTmFOXCI7XG4gIGlmICh2YWx1ZSA9PT0gSW5maW5pdHkpIHJldHVybiBcIkluZmluaXR5XCI7XG4gIGlmICh2YWx1ZSA9PT0gLUluZmluaXR5KSByZXR1cm4gXCItSW5maW5pdHlcIjtcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSByZXR1cm4gXCJhcnJheVwiO1xuICByZXR1cm4gdHlwZW9mIHZhbHVlO1xufTtcblxuY29uc3QgaXNTdXBwb3J0ZWQgPSAoXG4gIHZhbHVlOiB1bmtub3duXG4pOiB2YWx1ZSBpcyB1bmRlZmluZWQgfCBudW1iZXIgfCBiaWdpbnQgfCBEYXRlID0+IHtcbiAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgaW5zdGFuY2VvZiBEYXRlKSByZXR1cm4gdHJ1ZTtcblxuICBpZiAodHlwZW9mIHZhbHVlID09PSBcImJpZ2ludFwiKSByZXR1cm4gdHJ1ZTtcblxuICAvLyBOdW1iZXJzIG11c3QgYmUgZmluaXRlIChleGNsdWRlcyBOYU4sIEluZmluaXR5LCAtSW5maW5pdHkpXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIpIHJldHVybiBOdW1iZXIuaXNGaW5pdGUodmFsdWUpO1xuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbi8qKlxuICogVmFsaWRhdGVzIHdoZXRoZXIgdHdvIHZhbHVlcyBhcmUgZWxpZ2libGUgZm9yIGNvbXBhcmlzb24gdXNpbmcgPj0gb3IgPD0gb3BlcmF0b3JzLlxuICpcbiAqIFN1cHBvcnRlZCB0eXBlczogYHVuZGVmaW5lZGAsIGBudW1iZXJgLCBgYmlnaW50YCwgYW5kIGBEYXRlYC5cbiAqXG4gKiBAcGFyYW0gYSAtIFRoZSBmaXJzdCB2YWx1ZSB0byBjb21wYXJlLlxuICogQHBhcmFtIGIgLSBUaGUgc2Vjb25kIHZhbHVlIHRvIGNvbXBhcmUuXG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgYm90aCB2YWx1ZXMgYXJlIG9mIHN1cHBvcnRlZCB0eXBlcy5cbiAqXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGVpdGhlciB2YWx1ZSBpcyBvZiBhbiB1bnN1cHBvcnRlZCB0eXBlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZEZvckd0ZU9yTHRlQ29tcGFyaXNvbihhOiBhbnksIGI6IGFueSk6IGJvb2xlYW4ge1xuICBpZiAoaXNTdXBwb3J0ZWQoYSkgJiYgaXNTdXBwb3J0ZWQoYikpIHJldHVybiB0cnVlO1xuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgc2YoXG4gICAgICBDT01QQVJJU09OX0VSUk9SX01FU1NBR0VTLlVOU1VQUE9SVEVEX1RZUEVTX0NPTVBBUklTT04sXG4gICAgICBnZXRUeXBlTmFtZShhKSxcbiAgICAgIGdldFR5cGVOYW1lKGIpXG4gICAgKVxuICApO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IENvbXBhcmVzIHR3byB2YWx1ZXMgdG8gZGV0ZXJtaW5lIGlmIHRoZSBmaXJzdCBpcyBsZXNzIHRoYW4gdGhlIHNlY29uZC5cbiAqIEBkZXNjcmlwdGlvbiBTdXBwb3J0cyBudW1iZXJzIGFuZCBkYXRlcy4gVGhyb3dzIGFuIGVycm9yIGZvciB1bnN1cHBvcnRlZCB0eXBlcy5cbiAqXG4gKiBAcGFyYW0ge2FueX0gYSAtIFRoZSBmaXJzdCB2YWx1ZSB0byBjb21wYXJlLlxuICogQHBhcmFtIHthbnl9IGIgLSBUaGUgc2Vjb25kIHZhbHVlIHRvIGNvbXBhcmUgYWdhaW5zdC5cbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBgYWAgaXMgbGVzcyB0aGFuIGBiYCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICpcbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiBlaXRoZXIgYGFgIG9yIGBiYCBpcyBgbnVsbGAgb3IgYHVuZGVmaW5lZGAuXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIHZhbHVlcyBhcmUgb2YgbWlzbWF0Y2hlZCBvciB1bnN1cHBvcnRlZCB0eXBlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTGVzc1RoYW4oYTogYW55LCBiOiBhbnkpOiBib29sZWFuIHtcbiAgaWYgKFtudWxsLCB1bmRlZmluZWRdLmluY2x1ZGVzKGEpIHx8IFtudWxsLCB1bmRlZmluZWRdLmluY2x1ZGVzKGIpKVxuICAgIHRocm93IG5ldyBFcnJvcihDT01QQVJJU09OX0VSUk9SX01FU1NBR0VTLk5VTExfT1JfVU5ERUZJTkVEX0NPTVBBUklTT04pO1xuXG4gIC8vIFZhbGlkYXRlIHR5cGUgY29tcGF0aWJpbGl0eVxuICBjb25zdCBhVHlwZSA9IHR5cGVvZiBhO1xuICBjb25zdCBiVHlwZSA9IHR5cGVvZiBiO1xuXG4gIGlmIChhVHlwZSAhPT0gYlR5cGUpIHtcbiAgICAvLyBBbGxvdyBudW1iZXIgWCBiaWdpbnRcbiAgICBpZiAoYVR5cGUgPT09IFwiYmlnaW50XCIgJiYgYlR5cGUgPT09IFwibnVtYmVyXCIpXG4gICAgICByZXR1cm4gTnVtYmVyKGEpIDwgKGIgYXMgbnVtYmVyKTtcbiAgICBpZiAoYVR5cGUgPT09IFwibnVtYmVyXCIgJiYgYlR5cGUgPT09IFwiYmlnaW50XCIpXG4gICAgICByZXR1cm4gKGEgYXMgbnVtYmVyKSA8IE51bWJlcihiKTtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgc2YoQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUy5UWVBFX01JU01BVENIX0NPTVBBUklTT04sIGFUeXBlLCBiVHlwZSlcbiAgICApO1xuICB9XG5cbiAgaWYgKFxuICAgIChhVHlwZSA9PT0gXCJudW1iZXJcIiAmJiBiVHlwZSA9PT0gXCJudW1iZXJcIikgfHxcbiAgICAoYVR5cGUgPT09IFwiYmlnaW50XCIgJiYgYlR5cGUgPT09IFwiYmlnaW50XCIpXG4gICkge1xuICAgIGlmIChOdW1iZXIuaXNOYU4oYSkgfHwgTnVtYmVyLmlzTmFOKGIpKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihDT01QQVJJU09OX0VSUk9SX01FU1NBR0VTLk5BTl9DT01QQVJJU09OKTtcbiAgICByZXR1cm4gYSA8IGI7XG4gIH1cblxuICBpZiAoYSBpbnN0YW5jZW9mIERhdGUgJiYgYiBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICBpZiAoaXNOYU4oYS5nZXRUaW1lKCkpIHx8IGlzTmFOKGIuZ2V0VGltZSgpKSlcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUy5JTlZBTElEX0RBVEVfQ09NUEFSSVNPTik7XG4gICAgcmV0dXJuIGEuZ2V0VGltZSgpIDwgYi5nZXRUaW1lKCk7XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgIHNmKFxuICAgICAgQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUy5VTlNVUFBPUlRFRF9UWVBFU19DT01QQVJJU09OLFxuICAgICAgZ2V0VHlwZU5hbWUoYSksXG4gICAgICBnZXRUeXBlTmFtZShiKVxuICAgIClcbiAgKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYGFgIGlzIGdyZWF0ZXIgdGhhbiBgYmAuXG4gKiBTdXBwb3J0cyBjb21wYXJpc29uIGZvciBudW1iZXJzIGFuZCBEYXRlIG9iamVjdHMuXG4gKlxuICogQHBhcmFtIHthbnl9IGEgLSBUaGUgdmFsdWUgdG8gdmFsaWRhdGUuXG4gKiBAcGFyYW0ge2FueX0gYiAtIFRoZSB2YWx1ZSB0byBjb21wYXJlIGFnYWluc3QuXG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgYGFgIGlzIGdyZWF0ZXIgdGhhbiBgYmAsIG90aGVyd2lzZSBmYWxzZS5cbiAqXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgZWl0aGVyIGBhYCBvciBgYmAgaXMgYG51bGxgIG9yIGB1bmRlZmluZWRgLlxuICogQHRocm93cyB7VHlwZUVycm9yfSBJZiB2YWx1ZXMgYXJlIG9mIG1pc21hdGNoZWQgb3IgdW5zdXBwb3J0ZWQgdHlwZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0dyZWF0ZXJUaGFuKGE6IGFueSwgYjogYW55KTogYm9vbGVhbiB7XG4gIGlmIChbbnVsbCwgdW5kZWZpbmVkXS5pbmNsdWRlcyhhKSB8fCBbbnVsbCwgdW5kZWZpbmVkXS5pbmNsdWRlcyhiKSlcbiAgICB0aHJvdyBuZXcgRXJyb3IoQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUy5OVUxMX09SX1VOREVGSU5FRF9DT01QQVJJU09OKTtcblxuICBjb25zdCBhVHlwZSA9IHR5cGVvZiBhO1xuICBjb25zdCBiVHlwZSA9IHR5cGVvZiBiO1xuXG4gIGlmIChhVHlwZSAhPT0gYlR5cGUpIHtcbiAgICAvLyBBbGxvdyBudW1iZXIgWCBiaWdpbnRcbiAgICBpZiAoYVR5cGUgPT09IFwiYmlnaW50XCIgJiYgYlR5cGUgPT09IFwibnVtYmVyXCIpXG4gICAgICByZXR1cm4gTnVtYmVyKGEpID4gKGIgYXMgbnVtYmVyKTtcbiAgICBpZiAoYVR5cGUgPT09IFwibnVtYmVyXCIgJiYgYlR5cGUgPT09IFwiYmlnaW50XCIpXG4gICAgICByZXR1cm4gKGEgYXMgbnVtYmVyKSA+IE51bWJlcihiKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBzZihDT01QQVJJU09OX0VSUk9SX01FU1NBR0VTLlRZUEVfTUlTTUFUQ0hfQ09NUEFSSVNPTiwgYVR5cGUsIGJUeXBlKVxuICAgICk7XG4gIH1cblxuICBpZiAoXG4gICAgKGFUeXBlID09PSBcIm51bWJlclwiICYmIGJUeXBlID09PSBcIm51bWJlclwiKSB8fFxuICAgIChhVHlwZSA9PT0gXCJiaWdpbnRcIiAmJiBiVHlwZSA9PT0gXCJiaWdpbnRcIilcbiAgKSB7XG4gICAgaWYgKE51bWJlci5pc05hTihhKSB8fCBOdW1iZXIuaXNOYU4oYikpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKENPTVBBUklTT05fRVJST1JfTUVTU0FHRVMuTkFOX0NPTVBBUklTT04pO1xuICAgIHJldHVybiBhID4gYjtcbiAgfVxuXG4gIGlmIChhIGluc3RhbmNlb2YgRGF0ZSAmJiBiIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgIGlmIChpc05hTihhLmdldFRpbWUoKSkgfHwgaXNOYU4oYi5nZXRUaW1lKCkpKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihDT01QQVJJU09OX0VSUk9SX01FU1NBR0VTLklOVkFMSURfREFURV9DT01QQVJJU09OKTtcbiAgICByZXR1cm4gYS5nZXRUaW1lKCkgPiBiLmdldFRpbWUoKTtcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgc2YoXG4gICAgICBDT01QQVJJU09OX0VSUk9SX01FU1NBR0VTLlVOU1VQUE9SVEVEX1RZUEVTX0NPTVBBUklTT04sXG4gICAgICBnZXRUeXBlTmFtZShhKSxcbiAgICAgIGdldFR5cGVOYW1lKGIpXG4gICAgKVxuICApO1xufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgRGlmZlZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IGlzRXF1YWwgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IGdldFZhbHVlQnlQYXRoIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBEaWZmIFZhbGlkYXRvclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjRGlmZlZhbGlkYXRvcn1cbiAqXG4gKiBAY2xhc3MgRGlmZlZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5ESUZGKVxuZXhwb3J0IGNsYXNzIERpZmZWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3I8RGlmZlZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5ESUZGKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIGEgbW9kZWxcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gICAqIEBwYXJhbSB7Q29tcGFyaXNvblZhbGlkYXRvck9wdGlvbnN9IG9wdGlvbnNcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBhbnksXG4gICAgb3B0aW9uczogRGlmZlZhbGlkYXRvck9wdGlvbnMsXG4gICAgaW5zdGFuY2U6IGFueVxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGxldCBjb21wYXJpc29uUHJvcGVydHlWYWx1ZTogYW55O1xuICAgIHRyeSB7XG4gICAgICBjb21wYXJpc29uUHJvcGVydHlWYWx1ZSA9IGdldFZhbHVlQnlQYXRoKFxuICAgICAgICBpbnN0YW5jZSxcbiAgICAgICAgb3B0aW9uc1tWYWxpZGF0aW9uS2V5cy5ESUZGXVxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldE1lc3NhZ2UoZS5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGlzRXF1YWwodmFsdWUsIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlKVxuICAgICAgPyB0aGlzLmdldE1lc3NhZ2UoXG4gICAgICAgICAgb3B0aW9ucy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSxcbiAgICAgICAgICBvcHRpb25zW1ZhbGlkYXRpb25LZXlzLkRJRkZdXG4gICAgICAgIClcbiAgICAgIDogdW5kZWZpbmVkO1xuICB9XG59XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tIFwiLi9WYWxpZGF0b3JcIjtcbmltcG9ydCB7IERFRkFVTFRfRVJST1JfTUVTU0FHRVMsIFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBQYXR0ZXJuVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG5leHBvcnQgY29uc3QgcmVnZXhwUGFyc2VyOiBSZWdFeHAgPSBuZXcgUmVnRXhwKFwiXi8oLispLyhbZ2ltdXNdKikkXCIpO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFBhdHRlcm4gVmFsaWRhdG9yXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIGRlZmF1bHRzIHRvIHtAbGluayBWYWxpZGF0aW9uS2V5cyNQQVRURVJOfVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNQQVRURVJOfVxuICpcbiAqIEBjbGFzcyBQYXR0ZXJuVmFsaWRhdG9yXG4gKiBAZXh0ZW5kcyBWYWxpZGF0b3JcbiAqXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5AdmFsaWRhdG9yKFZhbGlkYXRpb25LZXlzLlBBVFRFUk4pXG5leHBvcnQgY2xhc3MgUGF0dGVyblZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvcjxQYXR0ZXJuVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlBBVFRFUk4pIHtcbiAgICBzdXBlcihtZXNzYWdlLCBcInN0cmluZ1wiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBwYXJzZXMgYW5kIHZhbGlkYXRlcyBhIHBhdHRlcm5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhdHRlcm5cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgZ2V0UGF0dGVybihwYXR0ZXJuOiBzdHJpbmcpOiBSZWdFeHAge1xuICAgIGlmICghcmVnZXhwUGFyc2VyLnRlc3QocGF0dGVybikpIHJldHVybiBuZXcgUmVnRXhwKHBhdHRlcm4pO1xuICAgIGNvbnN0IG1hdGNoOiBhbnkgPSBwYXR0ZXJuLm1hdGNoKHJlZ2V4cFBhcnNlcik7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAobWF0Y2hbMV0sIG1hdGNoWzJdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSBNb2RlbFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtQYXR0ZXJuVmFsaWRhdG9yT3B0aW9uc30gb3B0aW9uc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9XG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IHN0cmluZyxcbiAgICBvcHRpb25zOiBQYXR0ZXJuVmFsaWRhdG9yT3B0aW9uc1xuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICghdmFsdWUpIHJldHVybjtcblxuICAgIGxldCB7IHBhdHRlcm4gfSA9IG9wdGlvbnM7XG4gICAgaWYgKCFwYXR0ZXJuKSB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIFBhdHRlcm5cIik7XG4gICAgcGF0dGVybiA9IHR5cGVvZiBwYXR0ZXJuID09PSBcInN0cmluZ1wiID8gdGhpcy5nZXRQYXR0ZXJuKHBhdHRlcm4pIDogcGF0dGVybjtcbiAgICBwYXR0ZXJuLmxhc3RJbmRleCA9IDA7IC8vIHJlc2V0cyBwYXR0ZXJuIHBvc2l0aW9uIGZvciByZXBlYXQgdmFsaWRhdGlvbiByZXF1ZXN0c1xuICAgIHJldHVybiAhcGF0dGVybi50ZXN0KHZhbHVlKVxuICAgICAgPyB0aGlzLmdldE1lc3NhZ2Uob3B0aW9ucy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSlcbiAgICAgIDogdW5kZWZpbmVkO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBERUZBVUxUX0VSUk9SX01FU1NBR0VTLFxuICBERUZBVUxUX1BBVFRFUk5TLFxuICBWYWxpZGF0aW9uS2V5cyxcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBQYXR0ZXJuVmFsaWRhdG9yIH0gZnJvbSBcIi4vUGF0dGVyblZhbGlkYXRvclwiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgUGF0dGVyblZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBFbWFpbCBWYWxpZGF0b3JcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0VNQUlMfVxuICpcbiAqIEBjbGFzcyBFbWFpbFZhbGlkYXRvclxuICogQGV4dGVuZHMgUGF0dGVyblZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuRU1BSUwpXG5leHBvcnQgY2xhc3MgRW1haWxWYWxpZGF0b3IgZXh0ZW5kcyBQYXR0ZXJuVmFsaWRhdG9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5FTUFJTCkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIG1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1BhdHRlcm5WYWxpZGF0b3JPcHRpb25zfSBbb3B0aW9uc11cbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBzdHJpbmcsXG4gICAgb3B0aW9uczogUGF0dGVyblZhbGlkYXRvck9wdGlvbnMgPSB7fVxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBzdXBlci5oYXNFcnJvcnModmFsdWUsIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBwYXR0ZXJuOiBvcHRpb25zPy5wYXR0ZXJuIHx8IERFRkFVTFRfUEFUVEVSTlMuRU1BSUwsXG4gICAgfSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IEVxdWFsc1ZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IGlzRXF1YWwgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IGdldFZhbHVlQnlQYXRoIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBFcXVhbHMgVmFsaWRhdG9yXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNFUVVBTFN9XG4gKlxuICogQGNsYXNzIEVxdWFsc1ZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5FUVVBTFMpXG5leHBvcnQgY2xhc3MgRXF1YWxzVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPEVxdWFsc1ZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5FUVVBTFMpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSBtb2RlbFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtDb21wYXJpc29uVmFsaWRhdG9yT3B0aW9uc30gb3B0aW9uc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9XG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IGFueSxcbiAgICBvcHRpb25zOiBFcXVhbHNWYWxpZGF0b3JPcHRpb25zLFxuICAgIGluc3RhbmNlOiBhbnlcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBsZXQgY29tcGFyaXNvblByb3BlcnR5VmFsdWU6IGFueTtcbiAgICB0cnkge1xuICAgICAgY29tcGFyaXNvblByb3BlcnR5VmFsdWUgPSBnZXRWYWx1ZUJ5UGF0aChcbiAgICAgICAgaW5zdGFuY2UsXG4gICAgICAgIG9wdGlvbnNbVmFsaWRhdGlvbktleXMuRVFVQUxTXVxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldE1lc3NhZ2UoZS5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGlzRXF1YWwodmFsdWUsIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlKVxuICAgICAgPyB1bmRlZmluZWRcbiAgICAgIDogdGhpcy5nZXRNZXNzYWdlKFxuICAgICAgICAgIG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsXG4gICAgICAgICAgb3B0aW9uc1tWYWxpZGF0aW9uS2V5cy5FUVVBTFNdXG4gICAgICAgICk7XG4gIH1cbn1cblxuLy8gVmFsaWRhdGlvbi5yZWdpc3Rlcih7XG4vLyAgIHZhbGlkYXRvcjogRXF1YWxzVmFsaWRhdG9yLFxuLy8gICB2YWxpZGF0aW9uS2V5OiBWYWxpZGF0aW9uS2V5cy5FUVVBTFMsXG4vLyAgIHNhdmU6IGZhbHNlLFxuLy8gfSBhcyBWYWxpZGF0b3JEZWZpbml0aW9uKTtcbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IEdyZWF0ZXJUaGFuVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0VmFsdWVCeVBhdGgsIGlzR3JlYXRlclRoYW4gfSBmcm9tIFwiLi91dGlsc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IEdyZWF0ZXIgVGhhbiBWYWxpZGF0b3JcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0dSRUFURVJfVEhBTn1cbiAqXG4gKiBAY2xhc3MgR3JlYXRlclRoYW5WYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuR1JFQVRFUl9USEFOKVxuZXhwb3J0IGNsYXNzIEdyZWF0ZXJUaGFuVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPEdyZWF0ZXJUaGFuVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkdSRUFURVJfVEhBTikge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIG1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKiBAcGFyYW0ge0NvbXBhcmlzb25WYWxpZGF0b3JPcHRpb25zfSBvcHRpb25zXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogYW55LFxuICAgIG9wdGlvbnM6IEdyZWF0ZXJUaGFuVmFsaWRhdG9yT3B0aW9ucyxcbiAgICBpbnN0YW5jZTogYW55XG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgbGV0IGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlOiBhbnk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlID0gZ2V0VmFsdWVCeVBhdGgoXG4gICAgICAgIGluc3RhbmNlLFxuICAgICAgICBvcHRpb25zW1ZhbGlkYXRpb25LZXlzLkdSRUFURVJfVEhBTl1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRNZXNzYWdlKGUubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBpZiAoIWlzR3JlYXRlclRoYW4odmFsdWUsIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlKSlcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZShlLm1lc3NhZ2UsIG9wdGlvbnNbVmFsaWRhdGlvbktleXMuR1JFQVRFUl9USEFOXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgR3JlYXRlclRoYW5PckVxdWFsVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgZ2V0VmFsdWVCeVBhdGgsXG4gIGlzR3JlYXRlclRoYW4sXG4gIGlzVmFsaWRGb3JHdGVPckx0ZUNvbXBhcmlzb24sXG59IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBpc0VxdWFsIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgR3JlYXRlciBUaGFuIG9yIEVxdWFsIFZhbGlkYXRvclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjR1JFQVRFUl9USEFOX09SX0VRVUFMfVxuICpcbiAqIEBjbGFzcyBHcmVhdGVyVGhhbk9yRXF1YWxWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuR1JFQVRFUl9USEFOX09SX0VRVUFMKVxuZXhwb3J0IGNsYXNzIEdyZWF0ZXJUaGFuT3JFcXVhbFZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvcjxHcmVhdGVyVGhhbk9yRXF1YWxWYWxpZGF0b3JPcHRpb25zPiB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuR1JFQVRFUl9USEFOX09SX0VRVUFMKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIGEgbW9kZWxcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gICAqIEBwYXJhbSB7Q29tcGFyaXNvblZhbGlkYXRvck9wdGlvbnN9IG9wdGlvbnNcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBhbnksXG4gICAgb3B0aW9uczogR3JlYXRlclRoYW5PckVxdWFsVmFsaWRhdG9yT3B0aW9ucyxcbiAgICBpbnN0YW5jZTogYW55XG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgbGV0IGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlOiBhbnk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlID0gZ2V0VmFsdWVCeVBhdGgoXG4gICAgICAgIGluc3RhbmNlLFxuICAgICAgICBvcHRpb25zW1ZhbGlkYXRpb25LZXlzLkdSRUFURVJfVEhBTl9PUl9FUVVBTF1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRNZXNzYWdlKGUubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBpZiAoXG4gICAgICAgIChpc1ZhbGlkRm9yR3RlT3JMdGVDb21wYXJpc29uKHZhbHVlLCBjb21wYXJpc29uUHJvcGVydHlWYWx1ZSkgJiZcbiAgICAgICAgICBpc0VxdWFsKHZhbHVlLCBjb21wYXJpc29uUHJvcGVydHlWYWx1ZSkpIHx8XG4gICAgICAgIGlzR3JlYXRlclRoYW4odmFsdWUsIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlKVxuICAgICAgKVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgICB0aHJvdyBuZXcgRXJyb3Iob3B0aW9ucy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRNZXNzYWdlKFxuICAgICAgICBlLm1lc3NhZ2UsXG4gICAgICAgIG9wdGlvbnNbVmFsaWRhdGlvbktleXMuR1JFQVRFUl9USEFOX09SX0VRVUFMXVxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IExlc3NUaGFuVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0VmFsdWVCeVBhdGgsIGlzTGVzc1RoYW4gfSBmcm9tIFwiLi91dGlsc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IExlc3MgVGhhbiBWYWxpZGF0b3JcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0xFU1NfVEhBTn1cbiAqXG4gKiBAY2xhc3MgTGVzc1RoYW5WYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuTEVTU19USEFOKVxuZXhwb3J0IGNsYXNzIExlc3NUaGFuVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPExlc3NUaGFuVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkxFU1NfVEhBTikge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIG1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKiBAcGFyYW0ge0NvbXBhcmlzb25WYWxpZGF0b3JPcHRpb25zfSBvcHRpb25zXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogYW55LFxuICAgIG9wdGlvbnM6IExlc3NUaGFuVmFsaWRhdG9yT3B0aW9ucyxcbiAgICBpbnN0YW5jZTogYW55XG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgbGV0IGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlOiBhbnk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlID0gZ2V0VmFsdWVCeVBhdGgoXG4gICAgICAgIGluc3RhbmNlLFxuICAgICAgICBvcHRpb25zW1ZhbGlkYXRpb25LZXlzLkxFU1NfVEhBTl1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRNZXNzYWdlKGUubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBpZiAoIWlzTGVzc1RoYW4odmFsdWUsIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlKSlcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZShlLm1lc3NhZ2UsIG9wdGlvbnNbVmFsaWRhdGlvbktleXMuTEVTU19USEFOXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHR5cGUgeyBMZXNzVGhhbk9yRXF1YWxWYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQge1xuICBnZXRWYWx1ZUJ5UGF0aCxcbiAgaXNMZXNzVGhhbixcbiAgaXNWYWxpZEZvckd0ZU9yTHRlQ29tcGFyaXNvbixcbn0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IGlzRXF1YWwgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBMZXNzIFRoYW4gb3IgRXF1YWwgVmFsaWRhdG9yXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNMRVNTX1RIQU5fT1JfRVFVQUx9XG4gKlxuICogQGNsYXNzIExlc3NUaGFuT3JFcXVhbFZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5MRVNTX1RIQU5fT1JfRVFVQUwpXG5leHBvcnQgY2xhc3MgTGVzc1RoYW5PckVxdWFsVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPExlc3NUaGFuT3JFcXVhbFZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5MRVNTX1RIQU5fT1JfRVFVQUwpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSBtb2RlbFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtDb21wYXJpc29uVmFsaWRhdG9yT3B0aW9uc30gb3B0aW9uc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9XG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IGFueSxcbiAgICBvcHRpb25zOiBMZXNzVGhhbk9yRXF1YWxWYWxpZGF0b3JPcHRpb25zLFxuICAgIGluc3RhbmNlOiBhbnlcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBsZXQgY29tcGFyaXNvblByb3BlcnR5VmFsdWU6IGFueTtcbiAgICB0cnkge1xuICAgICAgY29tcGFyaXNvblByb3BlcnR5VmFsdWUgPSBnZXRWYWx1ZUJ5UGF0aChcbiAgICAgICAgaW5zdGFuY2UsXG4gICAgICAgIG9wdGlvbnNbVmFsaWRhdGlvbktleXMuTEVTU19USEFOX09SX0VRVUFMXVxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldE1lc3NhZ2UoZS5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGlmIChcbiAgICAgICAgKGlzVmFsaWRGb3JHdGVPckx0ZUNvbXBhcmlzb24odmFsdWUsIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlKSAmJlxuICAgICAgICAgIGlzRXF1YWwodmFsdWUsIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlKSkgfHxcbiAgICAgICAgaXNMZXNzVGhhbih2YWx1ZSwgY29tcGFyaXNvblByb3BlcnR5VmFsdWUpXG4gICAgICApXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgIHRocm93IG5ldyBFcnJvcihvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldE1lc3NhZ2UoXG4gICAgICAgIGUubWVzc2FnZSxcbiAgICAgICAgb3B0aW9uc1tWYWxpZGF0aW9uS2V5cy5MRVNTX1RIQU5fT1JfRVFVQUxdXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgTGlzdFZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBMaXN0IFZhbGlkYXRvclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjTElTVH1cbiAqXG4gKiBAY2xhc3MgTGlzdFZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5MSVNUKVxuZXhwb3J0IGNsYXNzIExpc3RWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3I8TGlzdFZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5MSVNUKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgQXJyYXkubmFtZSwgU2V0Lm5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIG1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSB7YW55W10gfCBTZXQ8YW55Pn0gdmFsdWVcbiAgICogQHBhcmFtIHtMaXN0VmFsaWRhdG9yT3B0aW9uc30gb3B0aW9uc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9XG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogYW55W10gfCBTZXQ8YW55PixcbiAgICBvcHRpb25zOiBMaXN0VmFsaWRhdG9yT3B0aW9uc1xuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICghdmFsdWUgfHwgKEFycmF5LmlzQXJyYXkodmFsdWUpID8gIXZhbHVlLmxlbmd0aCA6ICF2YWx1ZS5zaXplKSkgcmV0dXJuO1xuXG4gICAgY29uc3QgY2xhenogPSBBcnJheS5pc0FycmF5KG9wdGlvbnMuY2xhenopXG4gICAgICA/IG9wdGlvbnMuY2xhenpcbiAgICAgIDogW29wdGlvbnMuY2xhenpdO1xuICAgIGxldCB2YWw6IGFueSxcbiAgICAgIGlzVmFsaWQgPSB0cnVlO1xuICAgIGZvciAoXG4gICAgICBsZXQgaSA9IDA7XG4gICAgICBpIDwgKEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUubGVuZ3RoIDogdmFsdWUuc2l6ZSk7XG4gICAgICBpKytcbiAgICApIHtcbiAgICAgIHZhbCA9ICh2YWx1ZSBhcyBhbnkpW2ldO1xuICAgICAgc3dpdGNoICh0eXBlb2YgdmFsKSB7XG4gICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgY2FzZSBcImZ1bmN0aW9uXCI6XG4gICAgICAgICAgaXNWYWxpZCA9IGNsYXp6LmluY2x1ZGVzKCh2YWwgYXMgb2JqZWN0KS5jb25zdHJ1Y3Rvcj8ubmFtZSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgaXNWYWxpZCA9IGNsYXp6LnNvbWUoKGM6IHN0cmluZykgPT4gdHlwZW9mIHZhbCA9PT0gYy50b0xvd2VyQ2FzZSgpKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaXNWYWxpZFxuICAgICAgPyB1bmRlZmluZWRcbiAgICAgIDogdGhpcy5nZXRNZXNzYWdlKG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsIGNsYXp6KTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBWYWxpZGF0aW9uS2V5cywgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgTWF4TGVuZ3RoVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IE1heGltdW0gTGVuZ3RoIFZhbGlkYXRvclxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRlcyBzdHJpbmdzIGFuZCBBcnJheXMgb24gdGhlaXIgbWF4aW11bSBsZW5ndGhcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI01BWF9MRU5HVEh9XG4gKlxuICogQGNsYXNzIE1pbkxlbmd0aFZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5NQVhfTEVOR1RIKVxuZXhwb3J0IGNsYXNzIE1heExlbmd0aFZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvcjxNYXhMZW5ndGhWYWxpZGF0b3JPcHRpb25zPiB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuTUFYX0xFTkdUSCkge1xuICAgIHN1cGVyKG1lc3NhZ2UsIFN0cmluZy5uYW1lLCBBcnJheS5uYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSBtb2RlbFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtNYXhMZW5ndGhWYWxpZGF0b3JPcHRpb25zfSBvcHRpb25zXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogc3RyaW5nIHwgYW55W10sXG4gICAgb3B0aW9uczogTWF4TGVuZ3RoVmFsaWRhdG9yT3B0aW9uc1xuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIpIHJldHVybjtcbiAgICByZXR1cm4gdmFsdWUubGVuZ3RoID4gb3B0aW9ucy5tYXhsZW5ndGhcbiAgICAgID8gdGhpcy5nZXRNZXNzYWdlKG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsIG9wdGlvbnMubWF4bGVuZ3RoKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IE1heFZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBNYXggVmFsaWRhdG9yXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNNQVh9XG4gKlxuICogQGNsYXNzIE1heFZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5NQVgpXG5leHBvcnQgY2xhc3MgTWF4VmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPE1heFZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5NQVgpIHtcbiAgICBzdXBlcihtZXNzYWdlLCBcIm51bWJlclwiLCBcIkRhdGVcIiwgXCJzdHJpbmdcIik7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIGEgTW9kZWxcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gICAqIEBwYXJhbSB7TWF4VmFsaWRhdG9yT3B0aW9uc30gb3B0aW9uc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9XG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IG51bWJlciB8IERhdGUgfCBzdHJpbmcsXG4gICAgb3B0aW9uczogTWF4VmFsaWRhdG9yT3B0aW9uc1xuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIpIHJldHVybjtcblxuICAgIGxldCB7IG1heCB9ID0gb3B0aW9ucztcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlICYmICEobWF4IGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgIG1heCA9IG5ldyBEYXRlKG1heCk7XG4gICAgICBpZiAoTnVtYmVyLmlzTmFOKG1heC5nZXREYXRlKCkpKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIE1heCBwYXJhbSBkZWZpbmVkXCIpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZSA+IG1heFxuICAgICAgPyB0aGlzLmdldE1lc3NhZ2Uob3B0aW9ucy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSwgbWF4KVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IE1pbkxlbmd0aFZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBNaW5pbXVtIExlbmd0aCBWYWxpZGF0b3JcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0ZXMgc3RyaW5ncyBhbmQgQXJyYXlzIG9uIHRoZWlyIG1pbmltdW0gbGVuZ3RoXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNNSU5fTEVOR1RIfVxuICpcbiAqIEBjbGFzcyBNaW5MZW5ndGhWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuTUlOX0xFTkdUSClcbmV4cG9ydCBjbGFzcyBNaW5MZW5ndGhWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3I8TWluTGVuZ3RoVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLk1JTl9MRU5HVEgpIHtcbiAgICBzdXBlcihtZXNzYWdlLCBTdHJpbmcubmFtZSwgQXJyYXkubmFtZSk7XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmcgfCBBcnJheX0gdmFsdWVcbiAgICogQHBhcmFtIHtNaW5MZW5ndGhWYWxpZGF0b3JPcHRpb25zfSBvcHRpb25zXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAgICpcbiAgICogQG1lbWJlck9mIE1pbkxlbmd0aFZhbGlkYXRvclxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBzdHJpbmcgfCBhbnlbXSxcbiAgICBvcHRpb25zOiBNaW5MZW5ndGhWYWxpZGF0b3JPcHRpb25zXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuO1xuICAgIHJldHVybiB2YWx1ZS5sZW5ndGggPCBvcHRpb25zLm1pbmxlbmd0aFxuICAgICAgPyB0aGlzLmdldE1lc3NhZ2Uob3B0aW9ucy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSwgb3B0aW9ucy5taW5sZW5ndGgpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgTWluVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IE1pbiBWYWxpZGF0b3JcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI01JTn1cbiAqXG4gKiBAY2xhc3MgTWluVmFsaWRhdG9yXG4gKiBAZXh0ZW5kcyBWYWxpZGF0b3JcbiAqXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5AdmFsaWRhdG9yKFZhbGlkYXRpb25LZXlzLk1JTilcbmV4cG9ydCBjbGFzcyBNaW5WYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3I8TWluVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLk1JTikge1xuICAgIHN1cGVyKG1lc3NhZ2UsIFwibnVtYmVyXCIsIFwiRGF0ZVwiLCBcInN0cmluZ1wiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgTW9kZWxcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gICAqIEBwYXJhbSB7TWF4VmFsaWRhdG9yT3B0aW9uc30gb3B0aW9uc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9XG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IG51bWJlciB8IERhdGUgfCBzdHJpbmcsXG4gICAgb3B0aW9uczogTWluVmFsaWRhdG9yT3B0aW9uc1xuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIpIHJldHVybjtcblxuICAgIGxldCB7IG1pbiB9ID0gb3B0aW9ucztcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlICYmICEobWluIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgIG1pbiA9IG5ldyBEYXRlKG1pbik7XG4gICAgICBpZiAoTnVtYmVyLmlzTmFOKG1pbi5nZXREYXRlKCkpKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIE1pbiBwYXJhbSBkZWZpbmVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWUgPCBtaW5cbiAgICAgID8gdGhpcy5nZXRNZXNzYWdlKG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsIG1pbilcbiAgICAgIDogdW5kZWZpbmVkO1xuICB9XG59XG4iLCJpbXBvcnQgeyBQYXR0ZXJuVmFsaWRhdG9yIH0gZnJvbSBcIi4vUGF0dGVyblZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IFBhdHRlcm5WYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgSGFuZGxlcyBQYXNzd29yZCBWYWxpZGF0aW9uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFtlcnJvck1lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1BBU1NXT1JEfVxuICpcbiAqIEBjbGFzcyBQYXNzd29yZFZhbGlkYXRvclxuICogQGV4dGVuZHMgUGF0dGVyblZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuUEFTU1dPUkQpXG5leHBvcnQgY2xhc3MgUGFzc3dvcmRWYWxpZGF0b3IgZXh0ZW5kcyBQYXR0ZXJuVmFsaWRhdG9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZSA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuUEFTU1dPUkQpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSBtb2RlbFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtQYXR0ZXJuVmFsaWRhdG9yT3B0aW9uc30gW29wdGlvbnM9e31dXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgUGF0dGVyblZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IHN0cmluZyxcbiAgICBvcHRpb25zOiBQYXR0ZXJuVmFsaWRhdG9yT3B0aW9ucyA9IHt9XG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHN1cGVyLmhhc0Vycm9ycyh2YWx1ZSwge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIG1lc3NhZ2U6IG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsXG4gICAgfSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IFZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBSZXF1aXJlZCBWYWxpZGF0b3JcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1JFUVVJUkVEfVxuICpcbiAqIEBjbGFzcyBSZXF1aXJlZFZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5SRVFVSVJFRClcbmV4cG9ydCBjbGFzcyBSZXF1aXJlZFZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuUkVRVUlSRUQpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSBtb2RlbFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtWYWxpZGF0b3JPcHRpb25zfSBbb3B0aW9ucz17fV1cbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBhbnksXG4gICAgb3B0aW9uczogVmFsaWRhdG9yT3B0aW9ucyA9IHt9XG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgc3dpdGNoICh0eXBlb2YgdmFsdWUpIHtcbiAgICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCJcbiAgICAgICAgICA/IHRoaXMuZ2V0TWVzc2FnZShvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlKVxuICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuICF2YWx1ZVxuICAgICAgICAgID8gdGhpcy5nZXRNZXNzYWdlKG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tIFwiLi9WYWxpZGF0b3JcIjtcbmltcG9ydCB7IERFRkFVTFRfRVJST1JfTUVTU0FHRVMsIFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBTdGVwVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFN0ZXAgVmFsaWRhdG9yXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNTVEVQfVxuICpcbiAqIEBjbGFzcyBTdGVwVmFsaWRhdG9yXG4gKiBAZXh0ZW5kcyBWYWxpZGF0b3JcbiAqXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5AdmFsaWRhdG9yKFZhbGlkYXRpb25LZXlzLlNURVApXG5leHBvcnQgY2xhc3MgU3RlcFZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvcjxTdGVwVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlNURVApIHtcbiAgICBzdXBlcihtZXNzYWdlLCBcIm51bWJlclwiLCBcInN0cmluZ1wiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSBtb2RlbFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0ZXBcbiAgICogQHBhcmFtIHtTdGVwVmFsaWRhdG9yT3B0aW9uc30gb3B0aW9uc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9XG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IG51bWJlciB8IHN0cmluZyxcbiAgICBvcHRpb25zOiBTdGVwVmFsaWRhdG9yT3B0aW9uc1xuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIpIHJldHVybjtcbiAgICByZXR1cm4gTnVtYmVyKHZhbHVlKSAlIE51bWJlcihvcHRpb25zLnN0ZXApICE9PSAwXG4gICAgICA/IHRoaXMuZ2V0TWVzc2FnZShvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlLCBvcHRpb25zLnN0ZXApXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgVmFsaWRhdGlvbiB9IGZyb20gXCIuLi9WYWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBUeXBlVmFsaWRhdG9yT3B0aW9ucywgVmFsaWRhdG9yRGVmaW5pdGlvbiB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgTW9kZWxLZXlzIH0gZnJvbSBcIi4uLy4uL3V0aWxzL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgUmVmbGVjdGlvbiB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFJlcXVpcmVkIFZhbGlkYXRvclxuICpcbiAqIEBjbGFzcyBSZXF1aXJlZFZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5UWVBFKVxuZXhwb3J0IGNsYXNzIFR5cGVWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3I8VHlwZVZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5UWVBFKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIGEgbW9kZWxcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gICAqIEBwYXJhbSB7VHlwZVZhbGlkYXRvck9wdGlvbnN9IG9wdGlvbnNcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBhbnksXG4gICAgb3B0aW9uczogVHlwZVZhbGlkYXRvck9wdGlvbnNcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuOyAvLyBEb24ndCB0cnkgYW5kIGVuZm9yY2UgdHlwZSBpZiB1bmRlZmluZWRcbiAgICBjb25zdCB7IHR5cGVzLCBtZXNzYWdlIH0gPSBvcHRpb25zO1xuICAgIGlmICghUmVmbGVjdGlvbi5ldmFsdWF0ZURlc2lnblR5cGVzKHZhbHVlLCB0eXBlcykpXG4gICAgICByZXR1cm4gdGhpcy5nZXRNZXNzYWdlKFxuICAgICAgICBtZXNzYWdlIHx8IHRoaXMubWVzc2FnZSxcbiAgICAgICAgdHlwZW9mIHR5cGVzID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgPyB0eXBlc1xuICAgICAgICAgIDogQXJyYXkuaXNBcnJheSh0eXBlcylcbiAgICAgICAgICAgID8gdHlwZXMuam9pbihcIiwgXCIpXG4gICAgICAgICAgICA6IHR5cGVzLm5hbWUsXG4gICAgICAgIHR5cGVvZiB2YWx1ZVxuICAgICAgKTtcbiAgfVxufVxuXG5WYWxpZGF0aW9uLnJlZ2lzdGVyKHtcbiAgdmFsaWRhdG9yOiBUeXBlVmFsaWRhdG9yLFxuICB2YWxpZGF0aW9uS2V5OiBNb2RlbEtleXMuVFlQRSxcbiAgc2F2ZTogZmFsc2UsXG59IGFzIFZhbGlkYXRvckRlZmluaXRpb24pO1xuIiwiaW1wb3J0IHtcbiAgVmFsaWRhdGlvbktleXMsXG4gIERFRkFVTFRfRVJST1JfTUVTU0FHRVMsXG4gIERFRkFVTFRfUEFUVEVSTlMsXG59IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgUGF0dGVyblZhbGlkYXRvciB9IGZyb20gXCIuL1BhdHRlcm5WYWxpZGF0b3JcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IFBhdHRlcm5WYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgVVJMIFZhbGlkYXRvclxuICogQGRlc2NyaXB0aW9uIFBhdHRlcm4gZnJvbSB7QGxpbmsgaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vZHBlcmluaS83MjkyOTR9XG4gKlxuICogQGNsYXNzIFVSTFZhbGlkYXRvclxuICogQGV4dGVuZHMgUGF0dGVyblZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuVVJMKVxuZXhwb3J0IGNsYXNzIFVSTFZhbGlkYXRvciBleHRlbmRzIFBhdHRlcm5WYWxpZGF0b3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlVSTCkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIG1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1BhdHRlcm5WYWxpZGF0b3JPcHRpb25zfSBbb3B0aW9ucz17fV1cbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBzdHJpbmcsXG4gICAgb3B0aW9uczogUGF0dGVyblZhbGlkYXRvck9wdGlvbnMgPSB7fVxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBzdXBlci5oYXNFcnJvcnModmFsdWUsIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBwYXR0ZXJuOiBvcHRpb25zLnBhdHRlcm4gfHwgREVGQVVMVF9QQVRURVJOUy5VUkwsXG4gICAgfSk7XG4gIH1cbn1cbiIsImltcG9ydCBcInJlZmxlY3QtbWV0YWRhdGFcIjtcbmltcG9ydCB7XG4gIERpZmZWYWxpZGF0b3JPcHRpb25zLFxuICBFcXVhbHNWYWxpZGF0b3JPcHRpb25zLFxuICBHcmVhdGVyVGhhbk9yRXF1YWxWYWxpZGF0b3JPcHRpb25zLFxuICBHcmVhdGVyVGhhblZhbGlkYXRvck9wdGlvbnMsXG4gIExlc3NUaGFuT3JFcXVhbFZhbGlkYXRvck9wdGlvbnMsXG4gIExlc3NUaGFuVmFsaWRhdG9yT3B0aW9ucyxcbiAgVmFsaWRhdGlvbk1ldGFkYXRhLFxufSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyxcbiAgREVGQVVMVF9QQVRURVJOUyxcbiAgVmFsaWRhdGlvbktleXMsXG59IGZyb20gXCIuL1ZhbGlkYXRvcnMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBzZiB9IGZyb20gXCIuLi91dGlscy9zdHJpbmdzXCI7XG5pbXBvcnQgeyBNb2RlbENvbnN0cnVjdG9yIH0gZnJvbSBcIi4uL21vZGVsL3R5cGVzXCI7XG5pbXBvcnQgeyBwYXJzZURhdGUgfSBmcm9tIFwiLi4vdXRpbHMvZGF0ZXNcIjtcbmltcG9ydCB7IHByb3BNZXRhZGF0YSB9IGZyb20gXCIuLi91dGlscy9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBWYWxpZGF0aW9uIH0gZnJvbSBcIi4vVmFsaWRhdGlvblwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IE1hcmtzIHRoZSBwcm9wZXJ0eSBhcyByZXF1aXJlZC5cbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3JzIHRvIHZhbGlkYXRlIGEgZGVjb3JhdGVkIHByb3BlcnR5IG11c3QgdXNlIGtleSB7QGxpbmsgVmFsaWRhdGlvbktleXMjUkVRVUlSRUR9XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjUkVRVUlSRUR9XG4gKlxuICogQGZ1bmN0aW9uIHJlcXVpcmVkXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVkKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuUkVRVUlSRUQpIHtcbiAgcmV0dXJuIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KFxuICAgIFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLlJFUVVJUkVEKSxcbiAgICB7XG4gICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgbWluaW11bSB2YWx1ZSBmb3IgdGhlIHByb3BlcnR5XG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdG9ycyB0byB2YWxpZGF0ZSBhIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IHVzZSBrZXkge0BsaW5rIFZhbGlkYXRpb25LZXlzI01JTn1cbiAqXG4gKiBAcGFyYW0ge251bWJlciB8IERhdGV9IHZhbHVlXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIHRoZSBlcnJvciBtZXNzYWdlLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNNSU59XG4gKlxuICogQGZ1bmN0aW9uIG1pblxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5EZWNvcmF0b3JzLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtaW4oXG4gIHZhbHVlOiBudW1iZXIgfCBEYXRlIHwgc3RyaW5nLFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLk1JTlxuKSB7XG4gIHJldHVybiBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5NSU4pLCB7XG4gICAgW1ZhbGlkYXRpb25LZXlzLk1JTl06IHZhbHVlLFxuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgdHlwZXM6IFtOdW1iZXIubmFtZSwgRGF0ZS5uYW1lXSxcbiAgfSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIG1heGltdW0gdmFsdWUgZm9yIHRoZSBwcm9wZXJ0eVxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNNQVh9XG4gKlxuICogQHBhcmFtIHtudW1iZXIgfCBEYXRlfSB2YWx1ZVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjTUFYfVxuICpcbiAqIEBmdW5jdGlvbiBtYXhcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uRGVjb3JhdG9ycy5WYWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWF4KFxuICB2YWx1ZTogbnVtYmVyIHwgRGF0ZSB8IHN0cmluZyxcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5NQVhcbikge1xuICByZXR1cm4gcHJvcE1ldGFkYXRhPFZhbGlkYXRpb25NZXRhZGF0YT4oVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuTUFYKSwge1xuICAgIFtWYWxpZGF0aW9uS2V5cy5NQVhdOiB2YWx1ZSxcbiAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgIHR5cGVzOiBbTnVtYmVyLm5hbWUsIERhdGUubmFtZV0sXG4gIH0pO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBzdGVwIHZhbHVlIGZvciB0aGUgcHJvcGVydHlcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3JzIHRvIHZhbGlkYXRlIGEgZGVjb3JhdGVkIHByb3BlcnR5IG11c3QgdXNlIGtleSB7QGxpbmsgVmFsaWRhdGlvbktleXMjU1RFUH1cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gdGhlIGVycm9yIG1lc3NhZ2UuIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1NURVB9XG4gKlxuICogQGZ1bmN0aW9uIHN0ZXBcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uRGVjb3JhdG9ycy5WYWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gc3RlcChcbiAgdmFsdWU6IG51bWJlcixcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5TVEVQXG4pIHtcbiAgcmV0dXJuIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLlNURVApLCB7XG4gICAgW1ZhbGlkYXRpb25LZXlzLlNURVBdOiB2YWx1ZSxcbiAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgIHR5cGVzOiBbTnVtYmVyLm5hbWVdLFxuICB9KTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgbWluaW11bSBsZW5ndGggZm9yIHRoZSBwcm9wZXJ0eVxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNNSU5fTEVOR1RIfVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjTUlOX0xFTkdUSH1cbiAqXG4gKiBAZnVuY3Rpb24gbWlubGVuZ3RoXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLkRlY29yYXRvcnMuVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1pbmxlbmd0aChcbiAgdmFsdWU6IG51bWJlcixcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5NSU5fTEVOR1RIXG4pIHtcbiAgcmV0dXJuIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KFxuICAgIFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLk1JTl9MRU5HVEgpLFxuICAgIHtcbiAgICAgIFtWYWxpZGF0aW9uS2V5cy5NSU5fTEVOR1RIXTogdmFsdWUsXG4gICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgdHlwZXM6IFtTdHJpbmcubmFtZSwgQXJyYXkubmFtZSwgU2V0Lm5hbWVdLFxuICAgIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgbWF4aW11bSBsZW5ndGggZm9yIHRoZSBwcm9wZXJ0eVxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNNQVhfTEVOR1RIfVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjTUFYX0xFTkdUSH1cbiAqXG4gKiBAZnVuY3Rpb24gbWF4bGVuZ3RoXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLkRlY29yYXRvcnMuVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1heGxlbmd0aChcbiAgdmFsdWU6IG51bWJlcixcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5NQVhfTEVOR1RIXG4pIHtcbiAgcmV0dXJuIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KFxuICAgIFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLk1BWF9MRU5HVEgpLFxuICAgIHtcbiAgICAgIFtWYWxpZGF0aW9uS2V5cy5NQVhfTEVOR1RIXTogdmFsdWUsXG4gICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgdHlwZXM6IFtTdHJpbmcubmFtZSwgQXJyYXkubmFtZSwgU2V0Lm5hbWVdLFxuICAgIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgUmVnRXhwIHBhdHRlcm4gdGhlIHByb3BlcnR5IG11c3QgcmVzcGVjdFxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNQQVRURVJOfVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjUEFUVEVSTn1cbiAqXG4gKiBAZnVuY3Rpb24gcGF0dGVyblxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5EZWNvcmF0b3JzLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXR0ZXJuKFxuICB2YWx1ZTogUmVnRXhwIHwgc3RyaW5nLFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlBBVFRFUk5cbikge1xuICByZXR1cm4gcHJvcE1ldGFkYXRhPFZhbGlkYXRpb25NZXRhZGF0YT4oXG4gICAgVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuUEFUVEVSTiksXG4gICAge1xuICAgICAgW1ZhbGlkYXRpb25LZXlzLlBBVFRFUk5dOlxuICAgICAgICB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgPyB2YWx1ZSA6IHZhbHVlLnRvU3RyaW5nKCksXG4gICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgdHlwZXM6IFtTdHJpbmcubmFtZV0sXG4gICAgfVxuICApO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIHByb3BlcnR5IGFzIGFuIGVtYWlsXG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdG9ycyB0byB2YWxpZGF0ZSBhIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IHVzZSBrZXkge0BsaW5rIFZhbGlkYXRpb25LZXlzI0VNQUlMfVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gdGhlIGVycm9yIG1lc3NhZ2UuIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0VNQUlMfVxuICpcbiAqIEBmdW5jdGlvbiBlbWFpbFxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5EZWNvcmF0b3JzLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbWFpbChtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkVNQUlMKSB7XG4gIHJldHVybiBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihcbiAgICBWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5FTUFJTCksXG4gICAge1xuICAgICAgW1ZhbGlkYXRpb25LZXlzLlBBVFRFUk5dOiBERUZBVUxUX1BBVFRFUk5TLkVNQUlMLFxuICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgIHR5cGVzOiBbU3RyaW5nLm5hbWVdLFxuICAgIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBwcm9wZXJ0eSBhcyBhbiBVUkxcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3JzIHRvIHZhbGlkYXRlIGEgZGVjb3JhdGVkIHByb3BlcnR5IG11c3QgdXNlIGtleSB7QGxpbmsgVmFsaWRhdGlvbktleXMjVVJMfVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gdGhlIGVycm9yIG1lc3NhZ2UuIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1VSTH1cbiAqXG4gKiBAZnVuY3Rpb24gdXJsXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLkRlY29yYXRvcnMuVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVybChtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlVSTCkge1xuICByZXR1cm4gcHJvcE1ldGFkYXRhPFZhbGlkYXRpb25NZXRhZGF0YT4oVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuVVJMKSwge1xuICAgIFtWYWxpZGF0aW9uS2V5cy5QQVRURVJOXTogREVGQVVMVF9QQVRURVJOUy5VUkwsXG4gICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICB0eXBlczogW1N0cmluZy5uYW1lXSxcbiAgfSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRW5mb3JjZXMgdHlwZSB2ZXJpZmljYXRpb25cbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3JzIHRvIHZhbGlkYXRlIGEgZGVjb3JhdGVkIHByb3BlcnR5IG11c3QgdXNlIGtleSB7QGxpbmsgVmFsaWRhdGlvbktleXMjVFlQRX1cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ1tdIHwgc3RyaW5nfSB0eXBlcyBhY2NlcHRlZCB0eXBlc1xuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjVFlQRX1cbiAqXG4gKiBAZnVuY3Rpb24gdHlwZVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5EZWNvcmF0b3JzLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0eXBlKFxuICB0eXBlczogc3RyaW5nW10gfCBzdHJpbmcsXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuVFlQRVxuKSB7XG4gIHJldHVybiBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5UWVBFKSwge1xuICAgIGN1c3RvbVR5cGVzOiB0eXBlcyxcbiAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICB9KTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEYXRlIEhhbmRsZXIgRGVjb3JhdG9yXG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdG9ycyB0byB2YWxpZGF0ZSBhIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IHVzZSBrZXkge0BsaW5rIFZhbGlkYXRpb25LZXlzI0RBVEV9XG4gKlxuICogV2lsbCBlbmZvcmNlIHNlcmlhbGl6YXRpb24gYWNjb3JkaW5nIHRvIHRoZSBzZWxlY3RlZCBmb3JtYXRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZm9ybWF0IGFjY2VwdGVkIGZvcm1hdCBhY2NvcmRpbmcgdG8ge0BsaW5rIGZvcm1hdERhdGV9XG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIHRoZSBlcnJvciBtZXNzYWdlLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNEQVRFfVxuICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxWYWxpZGF0b3I+fSBbdmFsaWRhdG9yXSB0aGUgVmFsaWRhdG9yIHRvIGJlIHVzZWQuIERlZmF1bHRzIHRvIHtAbGluayBEYXRlVmFsaWRhdG9yfVxuICpcbiAqIEBmdW5jdGlvbiBkYXRlXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5EZWNvcmF0b3JzLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkYXRlKFxuICBmb3JtYXQ6IHN0cmluZyA9IFwiZGQvTU0veXl5eVwiLFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkRBVEVcbikge1xuICByZXR1cm4gKHRhcmdldDogUmVjb3JkPHN0cmluZywgYW55PiwgcHJvcGVydHlLZXk/OiBhbnkpOiBhbnkgPT4ge1xuICAgIHByb3BNZXRhZGF0YShWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5EQVRFKSwge1xuICAgICAgW1ZhbGlkYXRpb25LZXlzLkZPUk1BVF06IGZvcm1hdCxcbiAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICB0eXBlczogW0RhdGUubmFtZV0sXG4gICAgfSkodGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG5cbiAgICBjb25zdCB2YWx1ZXMgPSBuZXcgV2Vha01hcCgpO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICBzZXQodGhpczogYW55LCBuZXdWYWx1ZTogc3RyaW5nIHwgRGF0ZSkge1xuICAgICAgICBjb25zdCBkZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0aGlzLCBwcm9wZXJ0eUtleSk7XG4gICAgICAgIGlmICghZGVzY3JpcHRvciB8fCBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSlcbiAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgcHJvcGVydHlLZXksIHtcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgZ2V0OiAoKSA9PiB2YWx1ZXMuZ2V0KHRoaXMpLFxuICAgICAgICAgICAgc2V0OiAobmV3VmFsdWU6IHN0cmluZyB8IERhdGUgfCBudW1iZXIpID0+IHtcbiAgICAgICAgICAgICAgbGV0IHZhbDogRGF0ZSB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB2YWwgPSBwYXJzZURhdGUoZm9ybWF0LCBuZXdWYWx1ZSk7XG4gICAgICAgICAgICAgICAgdmFsdWVzLnNldCh0aGlzLCB2YWwpO1xuICAgICAgICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKHNmKFwiRmFpbGVkIHRvIHBhcnNlIGRhdGU6IHswfVwiLCBlLm1lc3NhZ2UgfHwgZSkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICB0aGlzW3Byb3BlcnR5S2V5XSA9IG5ld1ZhbHVlO1xuICAgICAgfSxcbiAgICAgIGdldCgpIHtcbiAgICAgICAgY29uc29sZS5sb2coXCJoZXJlXCIpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBQYXNzd29yZCBIYW5kbGVyIERlY29yYXRvclxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNQQVNTV09SRH1cbiAqXG4gKiBAcGFyYW0ge1JlZ0V4cH0gW3BhdHRlcm5dIGRlZmF1bHRzIHRvIHtAbGluayBQYXNzd29yZFBhdHRlcm5zI0NIQVI4X09ORV9PRl9FQUNIfVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjUEFTU1dPUkR9XG4gKiBAcGFyYW0ge0NvbnN0cnVjdG9yPFZhbGlkYXRvcj59IFt2YWxpZGF0b3JdIERlZmF1bHRzIHRvIHtAbGluayBQYXNzd29yZFZhbGlkYXRvcn1cbiAqXG4gKiBAZnVuY3Rpb24gcGFzc3dvcmRcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLkRlY29yYXRvcnMuVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhc3N3b3JkKFxuICBwYXR0ZXJuOiBSZWdFeHAgPSBERUZBVUxUX1BBVFRFUk5TLlBBU1NXT1JELkNIQVI4X09ORV9PRl9FQUNILFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlBBU1NXT1JEXG4pIHtcbiAgcmV0dXJuIHByb3BNZXRhZGF0YShWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5QQVNTV09SRCksIHtcbiAgICBbVmFsaWRhdGlvbktleXMuUEFUVEVSTl06IHBhdHRlcm4sXG4gICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICB0eXBlczogW1N0cmluZy5uYW1lXSxcbiAgfSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgTGlzdCBEZWNvcmF0b3JcbiAqIEBkZXNjcmlwdGlvbiBBbHNvIHNldHMgdGhlIHtAbGluayB0eXBlfSB0byB0aGUgcHJvdmlkZWQgY29sbGVjdGlvblxuICpcbiAqIEBwYXJhbSB7TW9kZWxDb25zdHJ1Y3Rvcn0gY2xhenpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbY29sbGVjdGlvbl0gVGhlIGNvbGxlY3Rpb24gYmVpbmcgdXNlZC4gZGVmYXVsdHMgdG8gQXJyYXlcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjTElTVH1cbiAqIEBwYXJhbSB7Q29uc3RydWN0b3I8VmFsaWRhdG9yPn0gW3ZhbGlkYXRvcl0gZGVmYXVsdHMgdG8ge0BsaW5rIExpc3RWYWxpZGF0b3J9XG4gKlxuICogQGZ1bmN0aW9uIGxpc3RcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLkRlY29yYXRvcnMuVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3QoXG4gIGNsYXp6OiBNb2RlbENvbnN0cnVjdG9yPGFueT4gfCBNb2RlbENvbnN0cnVjdG9yPGFueT5bXSxcbiAgY29sbGVjdGlvbjogXCJBcnJheVwiIHwgXCJTZXRcIiA9IFwiQXJyYXlcIixcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5MSVNUXG4pIHtcbiAgcmV0dXJuIHByb3BNZXRhZGF0YShWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5MSVNUKSwge1xuICAgIGNsYXp6OiBBcnJheS5pc0FycmF5KGNsYXp6KSA/IGNsYXp6Lm1hcCgoYykgPT4gYy5uYW1lKSA6IFtjbGF6ei5uYW1lXSxcbiAgICB0eXBlOiBjb2xsZWN0aW9uLFxuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gIH0pO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFNldCBEZWNvcmF0b3JcbiAqIEBkZXNjcmlwdGlvbiBXcmFwcGVyIGZvciB7QGxpbmsgbGlzdH0gd2l0aCB0aGUgJ1NldCcgQ29sbGVjdGlvblxuICpcbiAqIEBwYXJhbSB7TW9kZWxDb25zdHJ1Y3Rvcn0gY2xhenpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjTElTVH1cbiAqIEBwYXJhbSB7Q29uc3RydWN0b3I8VmFsaWRhdG9yPn0gW3ZhbGlkYXRvcl1cbiAqXG4gKiBAZnVuY3Rpb24gc2V0XG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5EZWNvcmF0b3JzLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXQoXG4gIGNsYXp6OiBNb2RlbENvbnN0cnVjdG9yPGFueT4sXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuTElTVFxuKSB7XG4gIHJldHVybiBsaXN0KGNsYXp6LCBcIlNldFwiLCBtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWNsYXJlcyB0aGF0IHRoZSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCBiZSBlcXVhbCB0byBhbm90aGVyIHNwZWNpZmllZCBwcm9wZXJ0eS5cbiAqIEBkZXNjcmlwdGlvbiBBcHBsaWVzIHRoZSB7QGxpbmsgVmFsaWRhdGlvbktleXMuRVFVQUxTfSB2YWxpZGF0b3IgdG8gZW5zdXJlIHRoZSBkZWNvcmF0ZWQgdmFsdWUgbWF0Y2hlcyB0aGUgdmFsdWUgb2YgdGhlIGdpdmVuIHByb3BlcnR5LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eVRvQ29tcGFyZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0byBjb21wYXJlIGVxdWFsaXR5IGFnYWluc3QuXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2U9REVGQVVMVF9FUlJPUl9NRVNTQUdFUy5FUVVBTFNdIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gcmV0dXJuIGlmIHZhbGlkYXRpb24gZmFpbHMuXG4gKlxuICogQHJldHVybnMge1Byb3BlcnR5RGVjb3JhdG9yfSBBIHByb3BlcnR5IGRlY29yYXRvciB1c2VkIHRvIHJlZ2lzdGVyIHRoZSBlcXVhbGl0eSB2YWxpZGF0aW9uIG1ldGFkYXRhLlxuICpcbiAqIEBmdW5jdGlvbiBlcVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5EZWNvcmF0b3JzLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlcShcbiAgcHJvcGVydHlUb0NvbXBhcmU6IHN0cmluZyxcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5FUVVBTFNcbikge1xuICBjb25zdCBvcHRpb25zOiBFcXVhbHNWYWxpZGF0b3JPcHRpb25zID0ge1xuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgW1ZhbGlkYXRpb25LZXlzLkVRVUFMU106IHByb3BlcnR5VG9Db21wYXJlLFxuICB9O1xuXG4gIHJldHVybiBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihcbiAgICBWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5FUVVBTFMpLFxuICAgIG9wdGlvbnMgYXMgVmFsaWRhdGlvbk1ldGFkYXRhXG4gICk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVjbGFyZXMgdGhhdCB0aGUgZGVjb3JhdGVkIHByb3BlcnR5IG11c3QgYmUgZGlmZmVyZW50IGZyb20gYW5vdGhlciBzcGVjaWZpZWQgcHJvcGVydHkuXG4gKiBAZGVzY3JpcHRpb24gQXBwbGllcyB0aGUge0BsaW5rIFZhbGlkYXRpb25LZXlzLkRJRkZ9IHZhbGlkYXRvciB0byBlbnN1cmUgdGhlIGRlY29yYXRlZCB2YWx1ZSBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgdmFsdWUgb2YgdGhlIGdpdmVuIHByb3BlcnR5LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eVRvQ29tcGFyZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0byBjb21wYXJlIGRpZmZlcmVuY2UgYWdhaW5zdC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZT1ERUZBVUxUX0VSUk9SX01FU1NBR0VTLkRJRkZdIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gcmV0dXJuIGlmIHZhbGlkYXRpb24gZmFpbHMuXG4gKlxuICogQHJldHVybnMge1Byb3BlcnR5RGVjb3JhdG9yfSBBIHByb3BlcnR5IGRlY29yYXRvciB1c2VkIHRvIHJlZ2lzdGVyIHRoZSBkaWZmZXJlbmNlIHZhbGlkYXRpb24gbWV0YWRhdGEuXG4gKlxuICogQGZ1bmN0aW9uIGRpZmZcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uRGVjb3JhdG9ycy5WYWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZGlmZihcbiAgcHJvcGVydHlUb0NvbXBhcmU6IHN0cmluZyxcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5ESUZGXG4pIHtcbiAgY29uc3Qgb3B0aW9uczogRGlmZlZhbGlkYXRvck9wdGlvbnMgPSB7XG4gICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICBbVmFsaWRhdGlvbktleXMuRElGRl06IHByb3BlcnR5VG9Db21wYXJlLFxuICB9O1xuXG4gIHJldHVybiBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihcbiAgICBWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5ESUZGKSxcbiAgICBvcHRpb25zIGFzIFZhbGlkYXRpb25NZXRhZGF0YVxuICApO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlY2xhcmVzIHRoYXQgdGhlIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IGJlIGxlc3MgdGhhbiBhbm90aGVyIHNwZWNpZmllZCBwcm9wZXJ0eS5cbiAqIEBkZXNjcmlwdGlvbiBBcHBsaWVzIHRoZSB7QGxpbmsgVmFsaWRhdGlvbktleXMuTEVTU19USEFOfSB2YWxpZGF0b3IgdG8gZW5zdXJlIHRoZSBkZWNvcmF0ZWQgdmFsdWUgaXMgbGVzcyB0aGFuIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gcHJvcGVydHkuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHByb3BlcnR5VG9Db21wYXJlIC0gVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIGNvbXBhcmUgYWdhaW5zdC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZT1ERUZBVUxUX0VSUk9SX01FU1NBR0VTLkxFU1NfVEhBTl0gLSBDdXN0b20gZXJyb3IgbWVzc2FnZSB0byByZXR1cm4gaWYgdmFsaWRhdGlvbiBmYWlscy5cbiAqXG4gKiBAcmV0dXJucyB7UHJvcGVydHlEZWNvcmF0b3J9IEEgcHJvcGVydHkgZGVjb3JhdG9yIHVzZWQgdG8gcmVnaXN0ZXIgdGhlIGxlc3MgdGhhbiB2YWxpZGF0aW9uIG1ldGFkYXRhLlxuICpcbiAqIEBmdW5jdGlvbiBsdFxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5EZWNvcmF0b3JzLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsdChcbiAgcHJvcGVydHlUb0NvbXBhcmU6IHN0cmluZyxcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5MRVNTX1RIQU5cbikge1xuICBjb25zdCBvcHRpb25zOiBMZXNzVGhhblZhbGlkYXRvck9wdGlvbnMgPSB7XG4gICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICBbVmFsaWRhdGlvbktleXMuTEVTU19USEFOXTogcHJvcGVydHlUb0NvbXBhcmUsXG4gIH07XG5cbiAgcmV0dXJuIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KFxuICAgIFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLkxFU1NfVEhBTiksXG4gICAgb3B0aW9ucyBhcyBWYWxpZGF0aW9uTWV0YWRhdGFcbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWNsYXJlcyB0aGF0IHRoZSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCBiZSBlcXVhbCBvciBsZXNzIHRoYW4gYW5vdGhlciBzcGVjaWZpZWQgcHJvcGVydHkuXG4gKiBAZGVzY3JpcHRpb24gQXBwbGllcyB0aGUge0BsaW5rIFZhbGlkYXRpb25LZXlzLkxFU1NfVEhBTl9PUl9FUVVBTH0gdmFsaWRhdG9yIHRvIGVuc3VyZSB0aGUgZGVjb3JhdGVkIHZhbHVlIGlzIGVxdWFsIG9yIGxlc3MgdGhhbiB0aGUgdmFsdWUgb2YgdGhlIGdpdmVuIHByb3BlcnR5LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eVRvQ29tcGFyZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0byBjb21wYXJlIGFnYWluc3QuXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2U9REVGQVVMVF9FUlJPUl9NRVNTQUdFUy5MRVNTX1RIQU5fT1JfRVFVQUxdIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gcmV0dXJuIGlmIHZhbGlkYXRpb24gZmFpbHMuXG4gKlxuICogQHJldHVybnMge1Byb3BlcnR5RGVjb3JhdG9yfSBBIHByb3BlcnR5IGRlY29yYXRvciB1c2VkIHRvIHJlZ2lzdGVyIHRoZSBsZXNzIHRoYW4gb3IgZXF1YWwgdmFsaWRhdGlvbiBtZXRhZGF0YS5cbiAqXG4gKiBAZnVuY3Rpb24gbHRlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLkRlY29yYXRvcnMuVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGx0ZShcbiAgcHJvcGVydHlUb0NvbXBhcmU6IHN0cmluZyxcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5MRVNTX1RIQU5fT1JfRVFVQUxcbikge1xuICBjb25zdCBvcHRpb25zOiBMZXNzVGhhbk9yRXF1YWxWYWxpZGF0b3JPcHRpb25zID0ge1xuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgW1ZhbGlkYXRpb25LZXlzLkxFU1NfVEhBTl9PUl9FUVVBTF06IHByb3BlcnR5VG9Db21wYXJlLFxuICB9O1xuXG4gIHJldHVybiBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihcbiAgICBWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5MRVNTX1RIQU5fT1JfRVFVQUwpLFxuICAgIG9wdGlvbnMgYXMgVmFsaWRhdGlvbk1ldGFkYXRhXG4gICk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVjbGFyZXMgdGhhdCB0aGUgZGVjb3JhdGVkIHByb3BlcnR5IG11c3QgYmUgZ3JlYXRlciB0aGFuIGFub3RoZXIgc3BlY2lmaWVkIHByb3BlcnR5LlxuICogQGRlc2NyaXB0aW9uIEFwcGxpZXMgdGhlIHtAbGluayBWYWxpZGF0aW9uS2V5cy5HUkVBVEVSX1RIQU59IHZhbGlkYXRvciB0byBlbnN1cmUgdGhlIGRlY29yYXRlZCB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gdGhlIHZhbHVlIG9mIHRoZSBnaXZlbiBwcm9wZXJ0eS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvcGVydHlUb0NvbXBhcmUgLSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgdG8gY29tcGFyZSBhZ2FpbnN0LlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlPURFRkFVTFRfRVJST1JfTUVTU0FHRVMuR1JFQVRFUl9USEFOXSAtIEN1c3RvbSBlcnJvciBtZXNzYWdlIHRvIHJldHVybiBpZiB2YWxpZGF0aW9uIGZhaWxzLlxuICpcbiAqIEByZXR1cm5zIHtQcm9wZXJ0eURlY29yYXRvcn0gQSBwcm9wZXJ0eSBkZWNvcmF0b3IgdXNlZCB0byByZWdpc3RlciB0aGUgZ3JlYXRlciB0aGFuIHZhbGlkYXRpb24gbWV0YWRhdGEuXG4gKlxuICogQGZ1bmN0aW9uIGd0XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLkRlY29yYXRvcnMuVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGd0KFxuICBwcm9wZXJ0eVRvQ29tcGFyZTogc3RyaW5nLFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkdSRUFURVJfVEhBTlxuKSB7XG4gIGNvbnN0IG9wdGlvbnM6IEdyZWF0ZXJUaGFuVmFsaWRhdG9yT3B0aW9ucyA9IHtcbiAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgIFtWYWxpZGF0aW9uS2V5cy5HUkVBVEVSX1RIQU5dOiBwcm9wZXJ0eVRvQ29tcGFyZSxcbiAgfTtcblxuICByZXR1cm4gcHJvcE1ldGFkYXRhPFZhbGlkYXRpb25NZXRhZGF0YT4oXG4gICAgVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuR1JFQVRFUl9USEFOKSxcbiAgICBvcHRpb25zIGFzIFZhbGlkYXRpb25NZXRhZGF0YVxuICApO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlY2xhcmVzIHRoYXQgdGhlIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IGJlIGVxdWFsIG9yIGdyZWF0ZXIgdGhhbiBhbm90aGVyIHNwZWNpZmllZCBwcm9wZXJ0eS5cbiAqIEBkZXNjcmlwdGlvbiBBcHBsaWVzIHRoZSB7QGxpbmsgVmFsaWRhdGlvbktleXMuR1JFQVRFUl9USEFOX09SX0VRVUFMfSB2YWxpZGF0b3IgdG8gZW5zdXJlIHRoZSBkZWNvcmF0ZWQgdmFsdWUgaXMgZXF1YWwgb3IgZ3JlYXRlciB0aGFuIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gcHJvcGVydHkuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHByb3BlcnR5VG9Db21wYXJlIC0gVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIGNvbXBhcmUgYWdhaW5zdC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZT1ERUZBVUxUX0VSUk9SX01FU1NBR0VTLkdSRUFURVJfVEhBTl9PUl9FUVVBTF0gLSBDdXN0b20gZXJyb3IgbWVzc2FnZSB0byByZXR1cm4gaWYgdmFsaWRhdGlvbiBmYWlscy5cbiAqXG4gKiBAcmV0dXJucyB7UHJvcGVydHlEZWNvcmF0b3J9IEEgcHJvcGVydHkgZGVjb3JhdG9yIHVzZWQgdG8gcmVnaXN0ZXIgdGhlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB2YWxpZGF0aW9uIG1ldGFkYXRhLlxuICpcbiAqIEBmdW5jdGlvbiBndGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uRGVjb3JhdG9ycy5WYWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ3RlKFxuICBwcm9wZXJ0eVRvQ29tcGFyZTogc3RyaW5nLFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkdSRUFURVJfVEhBTl9PUl9FUVVBTFxuKSB7XG4gIGNvbnN0IG9wdGlvbnM6IEdyZWF0ZXJUaGFuT3JFcXVhbFZhbGlkYXRvck9wdGlvbnMgPSB7XG4gICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICBbVmFsaWRhdGlvbktleXMuR1JFQVRFUl9USEFOX09SX0VRVUFMXTogcHJvcGVydHlUb0NvbXBhcmUsXG4gIH07XG5cbiAgcmV0dXJuIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KFxuICAgIFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLkdSRUFURVJfVEhBTl9PUl9FUVVBTCksXG4gICAgb3B0aW9ucyBhcyBWYWxpZGF0aW9uTWV0YWRhdGFcbiAgKTtcbn1cbiIsImltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIi4vTW9kZWxcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBIZWxwZXIgRnVuY3Rpb24gdG8gb3ZlcnJpZGUgY29uc3RydWN0b3JzXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7YW55W119IFthcmdzXVxuICogQHJldHVybiB7VH0gdGhlIG5ldyBpbnN0YW5jZVxuICpcbiAqIEBmdW5jdGlvbiBjb25zdHJ1Y3RcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uQ29uc3RydWN0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb25zdHJ1Y3Q8VCBleHRlbmRzIE1vZGVsPihcbiAgY29uc3RydWN0b3I6IGFueSxcbiAgLi4uYXJnczogYW55W11cbik6IFQge1xuICBjb25zdCBfY29uc3RyID0gKC4uLmFyZ3o6IGFueVtdKSA9PiBuZXcgY29uc3RydWN0b3IoLi4uYXJneik7XG4gIF9jb25zdHIucHJvdG90eXBlID0gY29uc3RydWN0b3IucHJvdG90eXBlO1xuICByZXR1cm4gX2NvbnN0ciguLi5hcmdzKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBSZWN1cnNpdmVseSBmaW5kcyB0aGUgbGFzdCBwcm90b3R5cGUgYmVmb3JlIE9iamVjdFxuICogQHBhcmFtIHtvYmplY3R9IG9ialxuICpcbiAqIEBmdW5jdGlvbiBmaW5kTGFzdFByb3RvQmVmb3JlT2JqZWN0XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLkNvbnN0cnVjdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZExhc3RQcm90b0JlZm9yZU9iamVjdChvYmo6IG9iamVjdCk6IG9iamVjdCB7XG4gIGxldCBwcm90b3R5cGU6IGFueSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmopO1xuICBpZiAocHJvdG90eXBlID09PSBPYmplY3QucHJvdG90eXBlKSByZXR1cm4gb2JqO1xuICB3aGlsZSAocHJvdG90eXBlICE9PSBPYmplY3QucHJvdG90eXBlKSB7XG4gICAgcHJvdG90eXBlID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvdHlwZSk7XG4gICAgaWYgKHByb3RvdHlwZSA9PT0gT2JqZWN0LnByb3RvdHlwZSkgcmV0dXJuIHByb3RvdHlwZTtcbiAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvdHlwZSkgPT09IE9iamVjdC5wcm90b3R5cGUpIHJldHVybiBwcm90b3R5cGU7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKFwiQ291bGQgbm90IGZpbmQgcHJvcGVyIHByb3RvdHlwZVwiKTtcbn1cblxuLyoqXG4gKiBAc3VtYXJ5IGJpbmRzIHRoZSB7QGxpbmsgTW9kZWx9IGNsYXNzIGFzIGEgcm9vdCBwcm90b3R5cGUgb2YgdGhlIHByb3ZpZGVkIGluc3RhbmNlXG4gKlxuICogQHBhcmFtIHt1bmtub3dufSBvYmpcbiAqXG4gKiBAZnVuY3Rpb24gYmluZE1vZGVsUHJvdG90eXBlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLkNvbnN0cnVjdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gYmluZE1vZGVsUHJvdG90eXBlKG9iajogdW5rbm93bikge1xuICBpZiAob2JqIGluc3RhbmNlb2YgTW9kZWwpIHJldHVybjtcblxuICBmdW5jdGlvbiBiaW5kUHJvdG90eXBlKG9ialRvT3ZlcnJpZGU6IHVua25vd24sIHByb3RvdHlwZTogb2JqZWN0KSB7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG9ialRvT3ZlcnJpZGUsIHByb3RvdHlwZSk7XG4gIH1cblxuICBjb25zdCBwcm90b3R5cGU6IGFueSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmopO1xuICBpZiAocHJvdG90eXBlID09PSBPYmplY3QucHJvdG90eXBlKSB7XG4gICAgcmV0dXJuIGJpbmRQcm90b3R5cGUob2JqLCBNb2RlbC5wcm90b3R5cGUpO1xuICB9XG4gIHdoaWxlIChwcm90b3R5cGUgIT09IE9iamVjdC5wcm90b3R5cGUpIHtcbiAgICBjb25zdCBwcm90ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvdHlwZSk7XG4gICAgaWYgKFxuICAgICAgcHJvdCA9PT0gT2JqZWN0LnByb3RvdHlwZSB8fFxuICAgICAgT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3QpID09PSBPYmplY3QucHJvdG90eXBlXG4gICAgKSB7XG4gICAgICByZXR1cm4gYmluZFByb3RvdHlwZShwcm90b3R5cGUsIE1vZGVsLnByb3RvdHlwZSk7XG4gICAgfVxuICB9XG4gIHRocm93IG5ldyBFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHByb3BlciBwcm90b3R5cGUgdG8gYmluZFwiKTtcbn1cbiIsImltcG9ydCB7IGJpbmRNb2RlbFByb3RvdHlwZSwgY29uc3RydWN0IH0gZnJvbSBcIi4vY29uc3RydWN0aW9uXCI7XG5pbXBvcnQgeyBNb2RlbEtleXMgfSBmcm9tIFwiLi4vdXRpbHMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCIuL01vZGVsXCI7XG5pbXBvcnQgeyBtZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IGRlZmluZXMgdGhlIHRwZSBvcyBhbiBJbnN0YW5jZUNhbGxiYWNrIGZ1bmN0aW9uXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5Nb2RlbFxuICovXG5leHBvcnQgdHlwZSBJbnN0YW5jZUNhbGxiYWNrID0gKGluc3RhbmNlOiBhbnksIC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkO1xuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBjbGFzcyBhcyBhIE1vZGVsIGNsYXNzXG4gKiBAZGVzY3JpcHRpb25cbiAqXG4gKiAtIFJlZ2lzdGVycyB0aGUgY2xhc3MgdW5kZXIgdGhlIG1vZGVsIHJlZ2lzdHJ5IHNvIGl0IGNhbiBiZSBlYXNpbHkgcmVidWlsdDtcbiAqIC0gT3ZlcnJpZGVzIHRoZSBjbGFzcyBjb25zdHJ1Y3RvcjtcbiAqIC0gUnVucyB0aGUgZ2xvYmFsIHtAbGluayBNb2RlbEJ1aWxkZXJGdW5jdGlvbn0gaWYgZGVmaW5lZDtcbiAqIC0gUnVucyB0aGUgb3B0aW9uYWwge0BsaW5rIEluc3RhbmNlQ2FsbGJhY2t9IGlmIHByb3ZpZGVkO1xuICpcbiAqIEBwYXJhbSB7SW5zdGFuY2VDYWxsYmFja30gW2luc3RhbmNlQ2FsbGJhY2tdIG9wdGlvbmFsIGNhbGxiYWNrIHRoYXQgd2lsbCBiZSBjYWxsZWQgd2l0aCB0aGUgaW5zdGFuY2UgdXBvbiBpbnN0YW50aWF0aW9uLiBkZWZhdWx0cyB0byB1bmRlZmluZWRcbiAqXG4gKiBAZnVuY3Rpb24gbW9kZWxcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLk1vZGVsXG4gKlxuICovXG5leHBvcnQgZnVuY3Rpb24gbW9kZWwoaW5zdGFuY2VDYWxsYmFjaz86IEluc3RhbmNlQ2FsbGJhY2spIHtcbiAgcmV0dXJuICgob3JpZ2luYWw6IGFueSkgPT4ge1xuICAgIC8vIHRoZSBuZXcgY29uc3RydWN0b3IgYmVoYXZpb3VyXG4gICAgY29uc3QgbmV3Q29uc3RydWN0b3I6IGFueSA9IGZ1bmN0aW9uICguLi5hcmdzOiBhbnlbXSkge1xuICAgICAgY29uc3QgaW5zdGFuY2U6IFJldHVyblR5cGU8dHlwZW9mIG9yaWdpbmFsPiA9IGNvbnN0cnVjdChcbiAgICAgICAgb3JpZ2luYWwsXG4gICAgICAgIC4uLmFyZ3NcbiAgICAgICk7XG4gICAgICBiaW5kTW9kZWxQcm90b3R5cGUoaW5zdGFuY2UpO1xuICAgICAgLy8gcnVuIGEgYnVpbGRlciBmdW5jdGlvbiBpZiBkZWZpbmVkIHdpdGggdGhlIGZpcnN0IGFyZ3VtZW50IChUaGUgTW9kZWxBcmcpXG4gICAgICBjb25zdCBidWlsZGVyID0gTW9kZWwuZ2V0QnVpbGRlcigpO1xuICAgICAgaWYgKGJ1aWxkZXIpIGJ1aWxkZXIoaW5zdGFuY2UsIGFyZ3MubGVuZ3RoID8gYXJnc1swXSA6IHVuZGVmaW5lZCk7XG5cbiAgICAgIG1ldGFkYXRhKE1vZGVsLmtleShNb2RlbEtleXMuTU9ERUwpLCBvcmlnaW5hbC5uYW1lKShpbnN0YW5jZS5jb25zdHJ1Y3Rvcik7XG5cbiAgICAgIGlmIChpbnN0YW5jZUNhbGxiYWNrKSBpbnN0YW5jZUNhbGxiYWNrKGluc3RhbmNlLCAuLi5hcmdzKTtcblxuICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgIH07XG5cbiAgICAvLyBjb3B5IHByb3RvdHlwZSBzbyBpbnN0YW5jZW9mIG9wZXJhdG9yIHN0aWxsIHdvcmtzXG4gICAgbmV3Q29uc3RydWN0b3IucHJvdG90eXBlID0gb3JpZ2luYWwucHJvdG90eXBlO1xuICAgIC8vIFNldHMgdGhlIHByb3BlciBjb25zdHJ1Y3RvciBuYW1lIGZvciB0eXBlIHZlcmlmaWNhdGlvblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuZXdDb25zdHJ1Y3RvciwgXCJuYW1lXCIsIHtcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgdmFsdWU6IG9yaWdpbmFsLnByb3RvdHlwZS5jb25zdHJ1Y3Rvci5uYW1lLFxuICAgIH0pO1xuXG4gICAgbWV0YWRhdGEoTW9kZWwua2V5KE1vZGVsS2V5cy5NT0RFTCksIG9yaWdpbmFsLm5hbWUpKG9yaWdpbmFsKTtcblxuICAgIE1vZGVsLnJlZ2lzdGVyKG5ld0NvbnN0cnVjdG9yLCBvcmlnaW5hbC5uYW1lKTtcblxuICAgIC8vIHJldHVybiBuZXcgY29uc3RydWN0b3IgKHdpbGwgb3ZlcnJpZGUgb3JpZ2luYWwpXG4gICAgcmV0dXJuIG5ld0NvbnN0cnVjdG9yO1xuICB9KSBhcyBhbnk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNoZWRCeShhbGdvcml0aG06IHN0cmluZywgLi4uYXJnczogYW55W10pIHtcbiAgcmV0dXJuIG1ldGFkYXRhKE1vZGVsLmtleShNb2RlbEtleXMuSEFTSElORyksIHtcbiAgICBhbGdvcml0aG06IGFsZ29yaXRobSxcbiAgICBhcmdzOiBhcmdzLFxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNlcmlhbGl6ZWRCeShzZXJpYWxpemVyOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKSB7XG4gIHJldHVybiBtZXRhZGF0YShNb2RlbC5rZXkoTW9kZWxLZXlzLlNFUklBTElaQVRJT04pLCB7XG4gICAgc2VyaWFsaXplcjogc2VyaWFsaXplcixcbiAgICBhcmdzOiBhcmdzLFxuICB9KTtcbn1cbiIsIi8qKlxuICogQG1vZHVsZSBkZWNvcmF0b3ItdmFsaWRhdGlvblxuICovXG5cbi8qKlxuICogQHN1bW1hcnkgTW9kZWwgZGVmaW5pdGlvbiBmdW5jdGlvbmFsaXR5XG4gKiBAZGVzY3JpcHRpb24gZGVmaW5lcyB0aGUgYmFzZSBjbGFzcyBhbmQgcmVsYXRlZCBmdW5jdGlvbmFsaXR5XG4gKlxuICogQG5hbWVzcGFjZSBNb2RlbFxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICovXG5cbi8qKlxuICogQHN1bW1hcnkgSG9sZHMgYWxsIHRoZSBzdXBwb3J0ZWQgZGVjb3JhdG9yc1xuICogQG5hbWVzcGFjZSBEZWNvcmF0b3JzXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uXG4gKi9cblxuLyoqXG4gKiBAc3VtbWFyeSBWYWxpZGF0aW9uIHJlbGF0ZWQgZnVuY3Rpb25hbGl0eVxuICogQGRlc2NyaXB0aW9uIERlZmluZXMgdGhlIE1vZGVsIHZhbGlkYXRpb24gYXBpcyBhbmQgYmFzZSBjbGFzc2VzIGZvciB2YWxpZGF0b3JzXG4gKlxuICogQG5hbWVzcGFjZSBWYWxpZGF0aW9uXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uXG4gKi9cblxuLyoqXG4gKiBAbmFtZXNwYWNlIERhdGVzXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uXG4gKi9cblxuLyoqXG4gKiBAbmFtZXNwYWNlIEhhc2hpbmdcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqL1xuXG4vKipcbiAqIEBuYW1lc3BhY2UgU2VyaWFsaXphdGlvblxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICovXG5cbi8qKlxuICogQG5hbWVzcGFjZSBGb3JtYXRcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqL1xuXG5leHBvcnQgKiBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi92YWxpZGF0aW9uXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9tb2RlbFwiO1xuXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7Ozs7Ozs7QUFRRztNQUNVLHFCQUFxQixHQUFHLE1BQU0sQ0FBQyxzQkFBc0I7O0FDVGxFOzs7Ozs7Ozs7Ozs7O0FBYUc7SUFDUztBQUFaLENBQUEsVUFBWSxTQUFTLEVBQUE7QUFDbkIsSUFBQSxTQUFBLENBQUEsU0FBQSxDQUFBLEdBQUEsY0FBd0I7QUFDeEIsSUFBQSxTQUFBLENBQUEsTUFBQSxDQUFBLEdBQUEsYUFBb0I7QUFDcEIsSUFBQSxTQUFBLENBQUEsUUFBQSxDQUFBLEdBQUEsbUJBQTRCO0FBQzVCLElBQUEsU0FBQSxDQUFBLFFBQUEsQ0FBQSxHQUFBLG1CQUE0QjtBQUM1QixJQUFBLFNBQUEsQ0FBQSxPQUFBLENBQUEsR0FBQSxPQUFlO0FBQ2YsSUFBQSxTQUFBLENBQUEsUUFBQSxDQUFBLEdBQUEsU0FBa0I7QUFDbEIsSUFBQSxTQUFBLENBQUEsY0FBQSxDQUFBLEdBQUEsZ0JBQStCO0FBQy9CLElBQUEsU0FBQSxDQUFBLFdBQUEsQ0FBQSxHQUFBLGNBQTBCO0FBQzFCLElBQUEsU0FBQSxDQUFBLFNBQUEsQ0FBQSxHQUFBLFNBQW1CO0FBQ25CLElBQUEsU0FBQSxDQUFBLGVBQUEsQ0FBQSxHQUFBLGVBQStCO0FBQ2pDLENBQUMsRUFYVyxTQUFTLEtBQVQsU0FBUyxHQVdwQixFQUFBLENBQUEsQ0FBQTs7QUN2QkQ7Ozs7Ozs7Ozs7Ozs7QUFhRztBQUNVLE1BQUEsd0JBQXdC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
3982
+ export { COMPARISON_ERROR_MESSAGES, ComparisonValidationKeys, DAYS_OF_WEEK_NAMES, DEFAULT_ERROR_MESSAGES, DEFAULT_PATTERNS, DateValidator, Decoration, DefaultFlavour, DefaultHashingMethod, DefaultSerializationMethod, DiffValidator, EmailValidator, EqualsValidator, GreaterThanOrEqualValidator, GreaterThanValidator, Hashing, JSONSerializer, LessThanOrEqualValidator, LessThanValidator, ListValidator, MONTH_NAMES, MaxLengthValidator, MaxValidator, MinLengthValidator, MinValidator, Model, ModelErrorDefinition, ModelKeys, ModelRegistryManager, PasswordValidator, PatternValidator, Primitives, RequiredValidator, ReservedModels, Serialization, StepValidator, TypeValidator, URLValidator, VERSION, Validation, ValidationKeys, Validator, ValidatorRegistry, bindDateToString, bindModelPrototype, bulkModelRegister, construct, date, dateFromFormat, diff, email, eq, findLastProtoBeforeObject, formatDate, getMetadata, getModelKey, getValueByPath, gt, gte, hashCode, hashObj, hashedBy, isGreaterThan, isLessThan, isValidDate, isValidForGteOrLteComparison, jsTypes, list, lt, lte, max, maxlength, min, minlength, model, parseDate, password, pattern, prop, propMetadata, regexpParser, required, serializedBy, set, sf, step, stringFormat, twoDigitPad, type, url, validate, validator };
3983
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVjb3JhdG9yLXZhbGlkYXRpb24uZXNtLmNqcyIsInNvdXJjZXMiOlsiLi4vc3JjL3V0aWxzL2NvbnN0YW50cy50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3V0aWxzL3N0cmluZ3MudHMiLCIuLi9zcmMvdXRpbHMvZGF0ZXMudHMiLCIuLi9zcmMvdXRpbHMvRGVjb3JhdGlvbi50cyIsIi4uL3NyYy91dGlscy9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL3V0aWxzL2hhc2hpbmcudHMiLCIuLi9zcmMvbW9kZWwvTW9kZWxFcnJvckRlZmluaXRpb24udHMiLCIuLi9zcmMvbW9kZWwvY29uc3RhbnRzLnRzIiwiLi4vc3JjL2NvbnN0YW50cy92YWxpZGF0aW9uLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9WYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL1ZhbGlkYXRvclJlZ2lzdHJ5LnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdGlvbi50cyIsIi4uL3NyYy9tb2RlbC92YWxpZGF0aW9uLnRzIiwiLi4vc3JjL21vZGVsL3V0aWxzLnRzIiwiLi4vc3JjL21vZGVsL01vZGVsLnRzIiwiLi4vc3JjL3V0aWxzL3NlcmlhbGl6YXRpb24udHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL2RlY29yYXRvcnMudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL0RhdGVWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL3V0aWxzLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9EaWZmVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9QYXR0ZXJuVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9FbWFpbFZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvRXF1YWxzVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9HcmVhdGVyVGhhblZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvR3JlYXRlclRoYW5PckVxdWFsVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9MZXNzVGhhblZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvTGVzc1RoYW5PckVxdWFsVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9MaXN0VmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9NYXhMZW5ndGhWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL01heFZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvTWluTGVuZ3RoVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9NaW5WYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9WYWxpZGF0b3JzL1Bhc3N3b3JkVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9SZXF1aXJlZFZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvU3RlcFZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvVHlwZVZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvVVJMVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vZGVjb3JhdG9ycy50cyIsIi4uL3NyYy9tb2RlbC9jb25zdHJ1Y3Rpb24udHMiLCIuLi9zcmMvbW9kZWwvZGVjb3JhdG9ycy50cyIsIi4uL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBkZXNjcmlwdGlvbiBFbnVtIGNvbnRhaW5pbmcgbWV0YWRhdGEga2V5cyB1c2VkIGZvciByZWZsZWN0aW9uIGluIHRoZSBtb2RlbCBzeXN0ZW1cbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIHZhcmlvdXMgTW9kZWwga2V5cyB1c2VkIGZvciByZWZsZWN0aW9uIGFuZCBtZXRhZGF0YSBzdG9yYWdlLlxuICogVGhlc2Uga2V5cyBhcmUgdXNlZCB0aHJvdWdob3V0IHRoZSBsaWJyYXJ5IHRvIHN0b3JlIGFuZCByZXRyaWV2ZSBtZXRhZGF0YSBhYm91dCBtb2RlbHMsXG4gKiB0aGVpciBwcm9wZXJ0aWVzLCBhbmQgdGhlaXIgYmVoYXZpb3IuXG4gKlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFJFRkxFQ1QgLSBQcmVmaXggdG8gYWxsIG90aGVyIGtleXMsIHVzZWQgYXMgYSBuYW1lc3BhY2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBUWVBFIC0gS2V5IGZvciBzdG9yaW5nIGRlc2lnbiB0eXBlIGluZm9ybWF0aW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUEFSQU1TIC0gS2V5IGZvciBzdG9yaW5nIG1ldGhvZCBwYXJhbWV0ZXIgdHlwZXNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBSRVRVUk4gLSBLZXkgZm9yIHN0b3JpbmcgbWV0aG9kIHJldHVybiB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTU9ERUwgLSBLZXkgZm9yIGlkZW50aWZ5aW5nIG1vZGVsIG1ldGFkYXRhXG4gKiBAcHJvcGVydHkge3N0cmluZ30gQU5DSE9SIC0gQW5jaG9yIGtleSB0aGF0IHNlcnZlcyBhcyBhIGdob3N0IHByb3BlcnR5IGluIHRoZSBtb2RlbFxuICogQHByb3BlcnR5IHtzdHJpbmd9IENPTlNUUlVDVElPTiAtIEtleSBmb3Igc3RvcmluZyBjb25zdHJ1Y3Rpb24gaW5mb3JtYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBBVFRSSUJVVEUgLSBLZXkgZm9yIHN0b3JpbmcgYXR0cmlidXRlIG1ldGFkYXRhXG4gKiBAcHJvcGVydHkge3N0cmluZ30gSEFTSElORyAtIEtleSBmb3Igc3RvcmluZyBoYXNoaW5nIGNvbmZpZ3VyYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBTRVJJQUxJWkFUSU9OIC0gS2V5IGZvciBzdG9yaW5nIHNlcmlhbGl6YXRpb24gY29uZmlndXJhdGlvblxuICpcbiAqIEByZWFkb25seVxuICogQGVudW0ge3N0cmluZ31cbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgZW51bSBNb2RlbEtleXMge1xuICBSRUZMRUNUID0gXCJkZWNhZi5tb2RlbC5cIixcbiAgVFlQRSA9IFwiZGVzaWduOnR5cGVcIixcbiAgUEFSQU1TID0gXCJkZXNpZ246cGFyYW10eXBlc1wiLFxuICBSRVRVUk4gPSBcImRlc2lnbjpyZXR1cm50eXBlXCIsXG4gIE1PREVMID0gXCJtb2RlbFwiLFxuICBBTkNIT1IgPSBcIl9fbW9kZWxcIixcbiAgQ09OU1RSVUNUSU9OID0gXCJjb25zdHJ1Y3RlZC1ieVwiLFxuICBBVFRSSUJVVEUgPSBcIl9fYXR0cmlidXRlc1wiLFxuICBIQVNISU5HID0gXCJoYXNoaW5nXCIsXG4gIFNFUklBTElaQVRJT04gPSBcInNlcmlhbGl6YXRpb25cIixcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVmYXVsdCBmbGF2b3VyIGlkZW50aWZpZXIgZm9yIHRoZSBkZWNvcmF0b3Igc3lzdGVtXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBkZWZhdWx0IGZsYXZvdXIgdXNlZCBieSB0aGUgRGVjb3JhdGlvbiBjbGFzcyB3aGVuIG5vIHNwZWNpZmljIGZsYXZvdXIgaXMgcHJvdmlkZWQuXG4gKiBUaGlzIGNvbnN0YW50IGlzIHVzZWQgdGhyb3VnaG91dCB0aGUgbGlicmFyeSBhcyB0aGUgZmFsbGJhY2sgZmxhdm91ciBmb3IgZGVjb3JhdG9ycy5cbiAqXG4gKiBAY29uc3Qge3N0cmluZ31cbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgY29uc3QgRGVmYXVsdEZsYXZvdXIgPSBcImRlY2FmXCI7XG4iLCJpbXBvcnQgeyBNb2RlbEtleXMgfSBmcm9tIFwiLi4vLi4vdXRpbHMvY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgS2V5cyB1c2VkIGZvciBjb21wYXJpc29uLWJhc2VkIHZhbGlkYXRpb25zLlxuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBFUVVBTFMgLSBWYWxpZGF0ZXMgaWYgdHdvIHZhbHVlcyBhcmUgZXF1YWwuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gRElGRiAtIFZhbGlkYXRlcyBpZiB0d28gdmFsdWVzIGFyZSBkaWZmZXJlbnQuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTEVTU19USEFOIC0gVmFsaWRhdGVzIGlmIGEgdmFsdWUgaXMgbGVzcyB0aGFuIGFub3RoZXIuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTEVTU19USEFOX09SX0VRVUFMIC0gVmFsaWRhdGVzIGlmIGEgdmFsdWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGFub3RoZXIuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gR1JFQVRFUl9USEFOIC0gVmFsaWRhdGVzIGlmIGEgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIGFub3RoZXIuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gR1JFQVRFUl9USEFOX09SX0VRVUFMIC0gVmFsaWRhdGVzIGlmIGEgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGFub3RoZXIuXG4gKlxuICogQGNvbnN0YW50IENvbXBhcmlzb25WYWxpZGF0aW9uS2V5c1xuICogQG1lbWJlcm9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5WYWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdGlvblxuICovXG5leHBvcnQgY29uc3QgQ29tcGFyaXNvblZhbGlkYXRpb25LZXlzID0ge1xuICBFUVVBTFM6IFwiZXF1YWxzXCIsXG4gIERJRkY6IFwiZGlmZmVyZW50XCIsXG4gIExFU1NfVEhBTjogXCJsZXNzVGhhblwiLFxuICBMRVNTX1RIQU5fT1JfRVFVQUw6IFwibGVzc1RoYW5PckVxdWFsXCIsXG4gIEdSRUFURVJfVEhBTjogXCJncmVhdGVyVGhhblwiLFxuICBHUkVBVEVSX1RIQU5fT1JfRVFVQUw6IFwiZ3JlYXRlclRoYW5PckVxdWFsXCIsXG59IGFzIGNvbnN0O1xuXG4vKipcbiAqIEBzdW1tYXJ5IFRoZSBrZXlzIHVzZWQgZm9yIHZhbGlkYXRpb25cbiAqXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUkVGTEVDVCBwcmVmaXhlcyBvdGhlcnNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBSRVFVSVJFRCBzZXRzIGFzIHJlcXVpcmVkXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUlOIGRlZmluZXMgbWluIHZhbHVlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUFYIGRlZmluZXMgbWF4IHZhbHVlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gU1RFUCBkZWZpbmVzIHN0ZXBcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBNSU5fTEVOR1RIIGRlZmluZXMgbWluIGxlbmd0aFxuICogQHByb3BlcnR5IHtzdHJpbmd9IE1BWF9MRU5HVEggZGVmaW5lcyBtYXggbGVuZ3RoXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUEFUVEVSTiBkZWZpbmVzIHBhdHRlcm5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBFTUFJTCBkZWZpbmVzIGVtYWlsXG4gKiBAcHJvcGVydHkge3N0cmluZ30gVVJMIGRlZmluZXMgdXJsXG4gKiBAcHJvcGVydHkge3N0cmluZ30gREFURSBkZWZpbmVzIGRhdGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBUWVBFIGRlZmluZXMgdHlwZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFBBU1NXT1JEIGRlZmluZXMgcGFzc3dvcmRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBMSVNUIGRlZmluZXMgbGlzdFxuICpcbiAqIEBjb25zdGFudCBWYWxpZGF0aW9uS2V5c1xuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5WYWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdGlvblxuICovXG5leHBvcnQgY29uc3QgVmFsaWRhdGlvbktleXMgPSB7XG4gIFJFRkxFQ1Q6IGAke01vZGVsS2V5cy5SRUZMRUNUfXZhbGlkYXRpb24uYCxcbiAgVkFMSURBVE9SOiBcInZhbGlkYXRvclwiLFxuICBSRVFVSVJFRDogXCJyZXF1aXJlZFwiLFxuICBNSU46IFwibWluXCIsXG4gIE1BWDogXCJtYXhcIixcbiAgU1RFUDogXCJzdGVwXCIsXG4gIE1JTl9MRU5HVEg6IFwibWlubGVuZ3RoXCIsXG4gIE1BWF9MRU5HVEg6IFwibWF4bGVuZ3RoXCIsXG4gIFBBVFRFUk46IFwicGF0dGVyblwiLFxuICBFTUFJTDogXCJlbWFpbFwiLFxuICBVUkw6IFwidXJsXCIsXG4gIERBVEU6IFwiZGF0ZVwiLFxuICBUWVBFOiBcInR5cGVcIixcbiAgUEFTU1dPUkQ6IFwicGFzc3dvcmRcIixcbiAgTElTVDogXCJsaXN0XCIsXG4gIEZPUk1BVDogXCJmb3JtYXRcIixcbiAgLi4uQ29tcGFyaXNvblZhbGlkYXRpb25LZXlzLFxufSBhcyBjb25zdDtcblxuLyoqXG4gKiBAc3VtbWFyeSBsaXN0IG9mIG1vbnRoIG5hbWVzXG4gKiBAZGVzY3JpcHRpb24gU3RvcmVzIG1vbnRoIG5hbWVzLiBDYW4gYmUgY2hhbmdlZCBmb3IgbG9jYWxpemF0aW9uIHB1cnBvc2VzXG4gKlxuICogQGNvbnN0YW50IE1PTlRIX05BTUVTXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBNT05USF9OQU1FUyA9IFtcbiAgXCJKYW51YXJ5XCIsXG4gIFwiRmVicnVhcnlcIixcbiAgXCJNYXJjaFwiLFxuICBcIkFwcmlsXCIsXG4gIFwiTWF5XCIsXG4gIFwiSnVuZVwiLFxuICBcIkp1bHlcIixcbiAgXCJBdWd1c3RcIixcbiAgXCJTZXB0ZW1iZXJcIixcbiAgXCJPY3RvYmVyXCIsXG4gIFwiTm92ZW1iZXJcIixcbiAgXCJEZWNlbWJlclwiLFxuXTtcblxuLyoqXG4gKiBAc3VtbWFyeSBsaXN0IG9mIG5hbWVzIG9mIGRheXMgb2YgdGhlIHdlZWtcbiAqIEBkZXNjcmlwdGlvbiBTdG9yZXMgbmFtZXMgZm9yIGRheXMgb2YgdGhlIHdlZWsuIENhbiBiZSBjaGFuZ2VkIGZvciBsb2NhbGl6YXRpb24gcHVycG9zZXNcbiAqXG4gKiBAY29uc3RhbnQgREFZU19PRl9XRUVLX05BTUVTXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBEQVlTX09GX1dFRUtfTkFNRVMgPSBbXG4gIFwiU3VuZGF5XCIsXG4gIFwiTW9uZGF5XCIsXG4gIFwiVHVlc2RheVwiLFxuICBcIldlZG5lc2RheVwiLFxuICBcIlRodXJzZGF5XCIsXG4gIFwiRnJpZGF5XCIsXG4gIFwiU2F0dXJkYXlcIixcbl07XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgZGVmYXVsdCBlcnJvciBtZXNzYWdlc1xuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBSRVFVSVJFRCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBNSU4gZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUFYIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IE1JTl9MRU5HVEggZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUFYX0xFTkdUSCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBQQVRURVJOIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IEVNQUlMIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFVSTCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBUWVBFIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFNURVAgZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gREFURSBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBERUZBVUxUIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFBBU1NXT1JEIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IExJU1QgZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTElTVF9JTlNJREUgZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTU9ERUxfTk9UX0ZPVU5EIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICpcbiAqIEBjb25zdGFudCBERUZBVUxUX0VSUk9SX01FU1NBR0VTXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0VSUk9SX01FU1NBR0VTOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICBSRVFVSVJFRDogXCJUaGlzIGZpZWxkIGlzIHJlcXVpcmVkXCIsXG4gIE1JTjogXCJUaGUgbWluaW11bSB2YWx1ZSBpcyB7MH1cIixcbiAgTUFYOiBcIlRoZSBtYXhpbXVtIHZhbHVlIGlzIHswfVwiLFxuICBNSU5fTEVOR1RIOiBcIlRoZSBtaW5pbXVtIGxlbmd0aCBpcyB7MH1cIixcbiAgTUFYX0xFTkdUSDogXCJUaGUgbWF4aW11bSBsZW5ndGggaXMgezB9XCIsXG4gIFBBVFRFUk46IFwiVGhlIHZhbHVlIGRvZXMgbm90IG1hdGNoIHRoZSBwYXR0ZXJuXCIsXG4gIEVNQUlMOiBcIlRoZSB2YWx1ZSBpcyBub3QgYSB2YWxpZCBlbWFpbFwiLFxuICBVUkw6IFwiVGhlIHZhbHVlIGlzIG5vdCBhIHZhbGlkIFVSTFwiLFxuICBUWVBFOiBcIkludmFsaWQgdHlwZS4gRXhwZWN0ZWQgezB9LCByZWNlaXZlZCB7MX1cIixcbiAgU1RFUDogXCJJbnZhbGlkIHZhbHVlLiBOb3QgYSBzdGVwIG9mIHswfVwiLFxuICBEQVRFOiBcIkludmFsaWQgdmFsdWUuIG5vdCBhIHZhbGlkIERhdGVcIixcbiAgREVGQVVMVDogXCJUaGVyZSBpcyBhbiBFcnJvclwiLFxuICBQQVNTV09SRDpcbiAgICBcIk11c3QgYmUgYXQgbGVhc3QgOCBjaGFyYWN0ZXJzIGFuZCBjb250YWluIG9uZSBvZiBudW1iZXIsIGxvd2VyIGFuZCB1cHBlciBjYXNlIGxldHRlcnMsIGFuZCBzcGVjaWFsIGNoYXJhY3RlciAoQCQhJSo/Jl8tLiwpXCIsXG4gIExJU1Q6IFwiSW52YWxpZCBsaXN0IG9mIHswfVwiLFxuICBNT0RFTF9OT1RfRk9VTkQ6IFwiTm8gbW9kZWwgcmVnaXN0ZXJlZCB1bmRlciB7MH1cIixcbiAgRVFVQUxTOiBcIlRoaXMgZmllbGQgbXVzdCBiZSBlcXVhbCB0byBmaWVsZCB7MH1cIixcbiAgRElGRjogXCJUaGlzIGZpZWxkIG11c3QgYmUgZGlmZmVyZW50IGZyb20gZmllbGQgezB9XCIsXG4gIExFU1NfVEhBTjogXCJUaGlzIGZpZWxkIG11c3QgYmUgbGVzcyB0aGFuIGZpZWxkIHswfVwiLFxuICBMRVNTX1RIQU5fT1JfRVFVQUw6IFwiVGhpcyBmaWVsZCBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byBmaWVsZCB7MH1cIixcbiAgR1JFQVRFUl9USEFOOiBcIlRoaXMgZmllbGQgbXVzdCBiZSBncmVhdGVyIHRoYW4gZmllbGQgezB9XCIsXG4gIEdSRUFURVJfVEhBTl9PUl9FUVVBTDpcbiAgICBcIlRoaXMgZmllbGQgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gZmllbGQgezB9XCIsXG59O1xuXG5leHBvcnQgY29uc3QgQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUyA9IHtcbiAgSU5WQUxJRF9QQVRIOlxuICAgIFwiSW52YWxpZCBwYXRoIGFyZ3VtZW50LiBFeHBlY3RlZCBub24tZW1wdHkgc3RyaW5nIGJ1dCByZWNlaXZlZDogJ3swfSdcIixcbiAgQ09OVEVYVF9OT1RfT0JKRUNUX0NPTVBBUklTT046XG4gICAgXCJVbmFibGUgdG8gYWNjZXNzIHBhcmVudCBhdCBsZXZlbCB7MH0gZm9yIHBhdGggJ3sxfSc6IGN1cnJlbnQgY29udGV4dCBpcyBub3QgYW4gb2JqZWN0XCIsXG4gIE5PX1BBUkVOVF9DT01QQVJJU09OOlxuICAgIFwiVW5hYmxlIHRvIGFjY2VzcyBwYXJlbnQgYXQgbGV2ZWwgezB9IGZvciBwYXRoICd7MX0nOiBubyBwYXJlbnQgYXZhaWxhYmxlXCIsXG4gIFBST1BFUlRZX05PVF9GT1VORDpcbiAgICBcIkZhaWxlZCB0byByZXNvbHZlIHBhdGggezB9OiBwcm9wZXJ0eSAnezF9JyBkb2VzIG5vdCBleGlzdC5cIixcbiAgUFJPUEVSVFlfTk9UX0ZPVU5EX09OX1BBUkVOVDpcbiAgICBcIkZhaWxlZCB0byByZXNvbHZlIHBhdGggezB9OiBwcm9wZXJ0eSAnezF9JyBkb2VzIG5vdCBleGlzdCBvbiBwYXJlbnQuXCIsXG4gIFBST1BFUlRZX05PVF9GT1VORF9BRlRFUl9QQVJFTlQ6XG4gICAgXCJGYWlsZWQgdG8gcmVzb2x2ZSBwYXRoIHswfTogcHJvcGVydHkgJ3sxfScgZG9lcyBub3QgZXhpc3QgYWZ0ZXIgezJ9IHBhcmVudCBsZXZlbChzKS5cIixcbiAgVU5TVVBQT1JURURfVFlQRVNfQ09NUEFSSVNPTjpcbiAgICBcIlVuc3VwcG9ydGVkIHR5cGVzIGZvciBjb21wYXJpc29uOiAnezB9JyBhbmQgJ3sxfSdcIixcbiAgTlVMTF9PUl9VTkRFRklORURfQ09NUEFSSVNPTjpcbiAgICBcIkNvbXBhcmlzb24gZmFpbGVkIGR1ZSB0byBudWxsIG9yIHVuZGVmaW5lZCB2YWx1ZVwiLFxuICBJTlZBTElEX0RBVEVfQ09NUEFSSVNPTjogXCJJbnZhbGlkIERhdGUgb2JqZWN0cyBhcmUgbm90IGNvbXBhcmFibGVcIixcbiAgVFlQRV9NSVNNQVRDSF9DT01QQVJJU09OOlxuICAgIFwiQ2Fubm90IGNvbXBhcmUgdmFsdWVzIG9mIGRpZmZlcmVudCB0eXBlczogezB9IGFuZCB7MX0uXCIsXG4gIE5BTl9DT01QQVJJU09OOiBcIkNvbXBhcmlzb24gbm90IHN1cHBvcnRlZCBmb3IgTmFOIHZhbHVlc1wiLFxufTtcblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSB2YXJpb3VzIGRlZmF1bHQgcmVnZXhwIHBhdHRlcm5zIHVzZWRcbiAqXG4gKiBAZW51bSBERUZBVUxUX1BBVFRFUk5TXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX1BBVFRFUk5TID0ge1xuICBFTUFJTDpcbiAgICAvW2EtekEtWjAtOSEjJCUmJyorLz0/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/OiBTZXQ8Q2xhc3NEZWNvcmF0b3IgfCBQcm9wZXJ0eURlY29yYXRvciB8IE1ldGhvZERlY29yYXRvcj47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDdXJyZW50IGRlY29yYXRvciBrZXlcbiAgICovXG4gIHByaXZhdGUga2V5Pzogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZmxhdm91cjogc3RyaW5nID0gRGVmYXVsdEZsYXZvdXIpIHt9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBrZXkgZm9yIHRoZSBkZWNvcmF0aW9uIGJ1aWxkZXJcbiAgICogQHN1bW1hcnkgSW5pdGlhbGl6ZXMgYSBuZXcgZGVjb3JhdGlvbiBjaGFpbiB3aXRoIHRoZSBzcGVjaWZpZWQga2V5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGlkZW50aWZpZXIgZm9yIHRoZSBkZWNvcmF0b3JcbiAgICogQHJldHVybiB7RGVjb3JhdGlvbkJ1aWxkZXJNaWR9IEJ1aWxkZXIgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZ1xuICAgKi9cbiAgZm9yKGtleTogc3RyaW5nKTogRGVjb3JhdGlvbkJ1aWxkZXJNaWQge1xuICAgIHRoaXMua2V5ID0ga2V5O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBZGRzIGRlY29yYXRvcnMgdG8gdGhlIGN1cnJlbnQgY29udGV4dFxuICAgKiBAc3VtbWFyeSBJbnRlcm5hbCBtZXRob2QgdG8gYWRkIGRlY29yYXRvcnMgd2l0aCBhZGRvbiBzdXBwb3J0XG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2FkZG9uPWZhbHNlXSBXaGV0aGVyIHRoZSBkZWNvcmF0b3JzIGFyZSBhZGRvbnNcbiAgICogQHBhcmFtIGRlY29yYXRvcnMgQXJyYXkgb2YgZGVjb3JhdG9yc1xuICAgKiBAcmV0dXJuIHt0aGlzfSBDdXJyZW50IGluc3RhbmNlIGZvciBjaGFpbmluZ1xuICAgKi9cbiAgcHJpdmF0ZSBkZWNvcmF0ZShcbiAgICBhZGRvbjogYm9vbGVhbiA9IGZhbHNlLFxuICAgIC4uLmRlY29yYXRvcnM6IChDbGFzc0RlY29yYXRvciB8IFByb3BlcnR5RGVjb3JhdG9yIHwgTWV0aG9kRGVjb3JhdG9yKVtdXG4gICk6IHRoaXMge1xuICAgIGlmICghdGhpcy5rZXkpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJrZXkgbXVzdCBiZSBwcm92aWRlZCBiZWZvcmUgZGVjb3JhdG9ycyBjYW4gYmUgYWRkZWRcIik7XG4gICAgaWYgKFxuICAgICAgKCFkZWNvcmF0b3JzIHx8ICFkZWNvcmF0b3JzLmxlbmd0aCkgJiZcbiAgICAgICFhZGRvbiAmJlxuICAgICAgdGhpcy5mbGF2b3VyICE9PSBEZWZhdWx0Rmxhdm91clxuICAgIClcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJNdXN0IHByb3ZpZGUgb3ZlcnJpZGVzIG9yIGFkZG9ucyB0byBvdmVycmlkZSBvciBleHRlbmQgZGVjYWYncyBkZWNvcmF0b3JzXCJcbiAgICAgICk7XG4gICAgaWYgKHRoaXMuZmxhdm91ciA9PT0gRGVmYXVsdEZsYXZvdXIgJiYgYWRkb24pXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEZWZhdWx0IGZsYXZvdXIgY2Fubm90IGJlIGV4dGVuZGVkXCIpO1xuXG4gICAgdGhpc1thZGRvbiA/IFwiZXh0cmFzXCIgOiBcImRlY29yYXRvcnNcIl0gPSBuZXcgU2V0KFtcbiAgICAgIC4uLih0aGlzW2FkZG9uID8gXCJleHRyYXNcIiA6IFwiZGVjb3JhdG9yc1wiXSB8fCBuZXcgU2V0KCkpLnZhbHVlcygpLFxuICAgICAgLi4uZGVjb3JhdG9ycyxcbiAgICBdKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBEZWZpbmVzIHRoZSBiYXNlIGRlY29yYXRvcnNcbiAgICogQHN1bW1hcnkgU2V0cyB0aGUgcHJpbWFyeSBkZWNvcmF0b3JzIGZvciB0aGUgY3VycmVudCBjb250ZXh0XG4gICAqIEBwYXJhbSBkZWNvcmF0b3JzIERlY29yYXRvcnMgdG8gZGVmaW5lXG4gICAqIEByZXR1cm4gQnVpbGRlciBpbnN0YW5jZSBmb3IgZmluaXNoaW5nIHRoZSBjaGFpblxuICAgKi9cbiAgZGVmaW5lKFxuICAgIC4uLmRlY29yYXRvcnM6IChDbGFzc0RlY29yYXRvciB8IFByb3BlcnR5RGVjb3JhdG9yIHwgTWV0aG9kRGVjb3JhdG9yKVtdXG4gICk6IERlY29yYXRpb25CdWlsZGVyRW5kICYgRGVjb3JhdGlvbkJ1aWxkZXJCdWlsZCB7XG4gICAgcmV0dXJuIHRoaXMuZGVjb3JhdGUoZmFsc2UsIC4uLmRlY29yYXRvcnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFeHRlbmRzIGV4aXN0aW5nIGRlY29yYXRvcnNcbiAgICogQHN1bW1hcnkgQWRkcyBhZGRpdGlvbmFsIGRlY29yYXRvcnMgdG8gdGhlIGN1cnJlbnQgY29udGV4dFxuICAgKiBAcGFyYW0gZGVjb3JhdG9ycyBBZGRpdGlvbmFsIGRlY29yYXRvcnNcbiAgICogQHJldHVybiB7RGVjb3JhdGlvbkJ1aWxkZXJCdWlsZH0gQnVpbGRlciBpbnN0YW5jZSBmb3IgYnVpbGRpbmcgdGhlIGRlY29yYXRvclxuICAgKi9cbiAgZXh0ZW5kKFxuICAgIC4uLmRlY29yYXRvcnM6IChDbGFzc0RlY29yYXRvciB8IFByb3BlcnR5RGVjb3JhdG9yIHwgTWV0aG9kRGVjb3JhdG9yKVtdXG4gICk6IERlY29yYXRpb25CdWlsZGVyQnVpbGQge1xuICAgIHJldHVybiB0aGlzLmRlY29yYXRlKHRydWUsIC4uLmRlY29yYXRvcnMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGRlY29yYXRvckZhY3Rvcnkoa2V5OiBzdHJpbmcsIGY6IHN0cmluZyA9IERlZmF1bHRGbGF2b3VyKSB7XG4gICAgY29uc3QgY29udGV4dERlY29yYXRvciA9IGZ1bmN0aW9uIGNvbnRleHREZWNvcmF0b3IoXG4gICAgICB0YXJnZXQ6IG9iamVjdCxcbiAgICAgIHByb3BlcnR5S2V5PzogYW55LFxuICAgICAgZGVzY3JpcHRvcj86IFR5cGVkUHJvcGVydHlEZXNjcmlwdG9yPGFueT5cbiAgICApIHtcbiAgICAgIGNvbnN0IGZsYXZvdXIgPSBEZWNvcmF0aW9uLmZsYXZvdXJSZXNvbHZlcih0YXJnZXQpO1xuICAgICAgbGV0IGRlY29yYXRvcnM7XG4gICAgICBjb25zdCBleHRyYXMgPSBEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XVtmbGF2b3VyXVxuICAgICAgICA/IERlY29yYXRpb24uZGVjb3JhdG9yc1trZXldW2ZsYXZvdXJdLmV4dHJhc1xuICAgICAgICA6IERlY29yYXRpb24uZGVjb3JhdG9yc1trZXldW0RlZmF1bHRGbGF2b3VyXS5leHRyYXM7XG4gICAgICBpZiAoXG4gICAgICAgIERlY29yYXRpb24uZGVjb3JhdG9yc1trZXldICYmXG4gICAgICAgIERlY29yYXRpb24uZGVjb3JhdG9yc1trZXldW2ZsYXZvdXJdICYmXG4gICAgICAgIERlY29yYXRpb24uZGVjb3JhdG9yc1trZXldW2ZsYXZvdXJdLmRlY29yYXRvcnNcbiAgICAgICkge1xuICAgICAgICBkZWNvcmF0b3JzID0gRGVjb3JhdGlvbi5kZWNvcmF0b3JzW2tleV1bZmxhdm91cl0uZGVjb3JhdG9ycztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlY29yYXRvcnMgPSBEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XVtEZWZhdWx0Rmxhdm91cl0uZGVjb3JhdG9ycztcbiAgICAgIH1cbiAgICAgIFtcbiAgICAgICAgLi4uKGRlY29yYXRvcnMgPyBkZWNvcmF0b3JzLnZhbHVlcygpIDogW10pLFxuICAgICAgICAuLi4oZXh0cmFzID8gZXh0cmFzLnZhbHVlcygpIDogW10pLFxuICAgICAgXS5mb3JFYWNoKChkKSA9PiAoZCBhcyBhbnkpKHRhcmdldCwgcHJvcGVydHlLZXksIGRlc2NyaXB0b3IsIGRlc2NyaXB0b3IpKTtcbiAgICAgIC8vIHJldHVybiBhcHBseShcbiAgICAgIC8vXG4gICAgICAvLyApKHRhcmdldCwgcHJvcGVydHlLZXksIGRlc2NyaXB0b3IpO1xuICAgIH07XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvbnRleHREZWNvcmF0b3IsIFwibmFtZVwiLCB7XG4gICAgICB2YWx1ZTogW2YsIGtleV0uam9pbihcIl9kZWNvcmF0b3JfZm9yX1wiKSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICB9KTtcbiAgICByZXR1cm4gY29udGV4dERlY29yYXRvcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyB0aGUgZmluYWwgZGVjb3JhdG9yIGZ1bmN0aW9uXG4gICAqIEBzdW1tYXJ5IEJ1aWxkcyBhbmQgcmV0dXJucyB0aGUgZGVjb3JhdG9yIGZhY3RvcnkgZnVuY3Rpb25cbiAgICogQHJldHVybiB7ZnVuY3Rpb24oYW55LCBhbnk/LCBUeXBlZFByb3BlcnR5RGVzY3JpcHRvcj8pOiBhbnl9IFRoZSBnZW5lcmF0ZWQgZGVjb3JhdG9yIGZ1bmN0aW9uXG4gICAqL1xuICBhcHBseSgpOiAoXG4gICAgdGFyZ2V0OiBhbnksXG4gICAgcHJvcGVydHlLZXk/OiBhbnksXG4gICAgZGVzY3JpcHRvcj86IFR5cGVkUHJvcGVydHlEZXNjcmlwdG9yPGFueT5cbiAgKSA9PiBhbnkge1xuICAgIGlmICghdGhpcy5rZXkpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBrZXkgcHJvdmlkZWQgZm9yIHRoZSBkZWNvcmF0aW9uIGJ1aWxkZXJcIik7XG4gICAgRGVjb3JhdGlvbi5yZWdpc3Rlcih0aGlzLmtleSwgdGhpcy5mbGF2b3VyLCB0aGlzLmRlY29yYXRvcnMsIHRoaXMuZXh0cmFzKTtcbiAgICByZXR1cm4gdGhpcy5kZWNvcmF0b3JGYWN0b3J5KHRoaXMua2V5LCB0aGlzLmZsYXZvdXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWdpc3RlcnMgZGVjb3JhdG9ycyBmb3IgYSBzcGVjaWZpYyBrZXkgYW5kIGZsYXZvdXJcbiAgICogQHN1bW1hcnkgSW50ZXJuYWwgbWV0aG9kIHRvIHN0b3JlIGRlY29yYXRvcnMgaW4gdGhlIHN0YXRpYyByZWdpc3RyeVxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IERlY29yYXRvciBrZXlcbiAgICogQHBhcmFtIHtzdHJpbmd9IGZsYXZvdXIgRGVjb3JhdG9yIGZsYXZvdXJcbiAgICogQHBhcmFtIFtkZWNvcmF0b3JzXSBQcmltYXJ5IGRlY29yYXRvcnNcbiAgICogQHBhcmFtIFtleHRyYXNdIEFkZGl0aW9uYWwgZGVjb3JhdG9yc1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgcmVnaXN0ZXIoXG4gICAga2V5OiBzdHJpbmcsXG4gICAgZmxhdm91cjogc3RyaW5nLFxuICAgIGRlY29yYXRvcnM/OiBTZXQ8Q2xhc3NEZWNvcmF0b3IgfCBQcm9wZXJ0eURlY29yYXRvciB8IE1ldGhvZERlY29yYXRvcj4sXG4gICAgZXh0cmFzPzogU2V0PENsYXNzRGVjb3JhdG9yIHwgUHJvcGVydHlEZWNvcmF0b3IgfCBNZXRob2REZWNvcmF0b3I+XG4gICkge1xuICAgIGlmICgha2V5KSB0aHJvdyBuZXcgRXJyb3IoXCJObyBrZXkgcHJvdmlkZWQgZm9yIHRoZSBkZWNvcmF0aW9uIGJ1aWxkZXJcIik7XG4gICAgaWYgKCFkZWNvcmF0b3JzKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gZGVjb3JhdG9ycyBwcm92aWRlZCBmb3IgdGhlIGRlY29yYXRpb24gYnVpbGRlclwiKTtcbiAgICBpZiAoIWZsYXZvdXIpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBmbGF2b3VyIHByb3ZpZGVkIGZvciB0aGUgZGVjb3JhdGlvbiBidWlsZGVyXCIpO1xuXG4gICAgaWYgKCFEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XSkgRGVjb3JhdGlvbi5kZWNvcmF0b3JzW2tleV0gPSB7fTtcbiAgICBpZiAoIURlY29yYXRpb24uZGVjb3JhdG9yc1trZXldW2ZsYXZvdXJdKVxuICAgICAgRGVjb3JhdGlvbi5kZWNvcmF0b3JzW2tleV1bZmxhdm91cl0gPSB7fTtcbiAgICBpZiAoZGVjb3JhdG9ycykgRGVjb3JhdGlvbi5kZWNvcmF0b3JzW2tleV1bZmxhdm91cl0uZGVjb3JhdG9ycyA9IGRlY29yYXRvcnM7XG4gICAgaWYgKGV4dHJhcykgRGVjb3JhdGlvbi5kZWNvcmF0b3JzW2tleV1bZmxhdm91cl0uZXh0cmFzID0gZXh0cmFzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBnbG9iYWwgZmxhdm91ciByZXNvbHZlclxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBmdW5jdGlvbiB1c2VkIHRvIGRldGVybWluZSBkZWNvcmF0b3IgZmxhdm91cnNcbiAgICogQHBhcmFtIHtGbGF2b3VyUmVzb2x2ZXJ9IHJlc29sdmVyIEZ1bmN0aW9uIHRvIHJlc29sdmUgZmxhdm91cnNcbiAgICovXG4gIHN0YXRpYyBzZXRGbGF2b3VyUmVzb2x2ZXIocmVzb2x2ZXI6IEZsYXZvdXJSZXNvbHZlcikge1xuICAgIERlY29yYXRpb24uZmxhdm91clJlc29sdmVyID0gcmVzb2x2ZXI7XG4gIH1cblxuICBzdGF0aWMgZm9yKGtleTogc3RyaW5nKTogRGVjb3JhdGlvbkJ1aWxkZXJNaWQge1xuICAgIHJldHVybiBuZXcgRGVjb3JhdGlvbigpLmZvcihrZXkpO1xuICB9XG5cbiAgc3RhdGljIGZsYXZvdXJlZEFzKGZsYXZvdXI6IHN0cmluZyk6IERlY29yYXRpb25CdWlsZGVyU3RhcnQge1xuICAgIHJldHVybiBuZXcgRGVjb3JhdGlvbihmbGF2b3VyKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgYXBwbHksIG1ldGFkYXRhIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBNb2RlbEtleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUHJvcGVydHkgZGVjb3JhdG9yIGZhY3RvcnkgZm9yIG1vZGVsIGF0dHJpYnV0ZXNcbiAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBkZWNvcmF0b3IgdGhhdCBtYXJrcyBjbGFzcyBwcm9wZXJ0aWVzIGFzIG1vZGVsIGF0dHJpYnV0ZXMuIFRoZSBkZWNvcmF0b3IgbWFpbnRhaW5zIGEgbGlzdFxuICogb2YgcHJvcGVydHkga2V5cyB1bmRlciBhIHNwZWNpZmllZCBtZXRhZGF0YSBrZXkgaW4gdGhlIG1vZGVsLiBJZiB0aGUga2V5IGRvZXNuJ3QgZXhpc3QsIGl0IGNyZWF0ZXMgYSBuZXcgYXJyYXk7XG4gKiBpZiBpdCBleGlzdHMsIGl0IGFwcGVuZHMgdGhlIHByb3BlcnR5IGtleSB0byB0aGUgZXhpc3RpbmcgYXJyYXksIGF2b2lkaW5nIGR1cGxpY2F0ZXMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFtrZXk9TW9kZWxLZXlzLkFUVFJJQlVURV0gLSBUaGUgbWV0YWRhdGEga2V5IHVuZGVyIHdoaWNoIHRvIHN0b3JlIHRoZSBwcm9wZXJ0eSBuYW1lXG4gKiBAcmV0dXJuIHtmdW5jdGlvbihvYmplY3QsIGFueT8pOiB2b2lkfSBEZWNvcmF0b3IgZnVuY3Rpb24gdGhhdCByZWdpc3RlcnMgdGhlIHByb3BlcnR5XG4gKlxuICogQGZ1bmN0aW9uIHByb3BcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICAgcGFydGljaXBhbnQgRCBhcyBEZWNvcmF0b3JcbiAqICAgIHBhcnRpY2lwYW50IE0gYXMgTW9kZWxcbiAqXG4gKiAgICBELT4+TTogQ2hlY2sgaWYga2V5IGV4aXN0c1xuICogICAgYWx0IGtleSBleGlzdHNcbiAqICAgICAgICBNLS0+PkQ6IFJldHVybiBleGlzdGluZyBwcm9wcyBhcnJheVxuICogICAgZWxzZSBrZXkgZG9lc24ndCBleGlzdFxuICogICAgICAgIEQtPj5NOiBDcmVhdGUgbmV3IHByb3BzIGFycmF5XG4gKiAgICBlbmRcbiAqICAgIEQtPj5NOiBDaGVjayBpZiBwcm9wZXJ0eSBleGlzdHNcbiAqICAgIGFsdCBwcm9wZXJ0eSBub3QgaW4gYXJyYXlcbiAqICAgICAgICBELT4+TTogQWRkIHByb3BlcnR5IHRvIGFycmF5XG4gKiAgICBlbmRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByb3Aoa2V5OiBzdHJpbmcgPSBNb2RlbEtleXMuQVRUUklCVVRFKSB7XG4gIHJldHVybiAobW9kZWw6IG9iamVjdCwgcHJvcGVydHlLZXk/OiBhbnkpOiB2b2lkID0+IHtcbiAgICBsZXQgcHJvcHM6IHN0cmluZ1tdO1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9kZWwsIGtleSkpIHtcbiAgICAgIHByb3BzID0gKG1vZGVsIGFzIGFueSlba2V5XTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvcHMgPSAobW9kZWwgYXMgYW55KVtrZXldID0gW107XG4gICAgfVxuICAgIGlmICghcHJvcHMuaW5jbHVkZXMocHJvcGVydHlLZXkgYXMgc3RyaW5nKSlcbiAgICAgIHByb3BzLnB1c2gocHJvcGVydHlLZXkgYXMgc3RyaW5nKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29tYmluZWQgcHJvcGVydHkgZGVjb3JhdG9yIGZhY3RvcnkgZm9yIG1ldGFkYXRhIGFuZCBhdHRyaWJ1dGUgbWFya2luZ1xuICogQHN1bW1hcnkgQ3JlYXRlcyBhIGRlY29yYXRvciB0aGF0IGJvdGggbWFya3MgYSBwcm9wZXJ0eSBhcyBhIG1vZGVsIGF0dHJpYnV0ZSBhbmQgYXNzaWducyBtZXRhZGF0YSB0byBpdC5cbiAqIENvbWJpbmVzIHRoZSBmdW5jdGlvbmFsaXR5IG9mIHByb3AoKSBhbmQgbWV0YWRhdGEoKSBkZWNvcmF0b3JzLlxuICpcbiAqIEB0ZW1wbGF0ZSBWIC0gVGhlIHR5cGUgb2YgdGhlIG1ldGFkYXRhIHZhbHVlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gVGhlIG1ldGFkYXRhIGtleVxuICogQHBhcmFtIHtWfSB2YWx1ZSAtIFRoZSBtZXRhZGF0YSB2YWx1ZSB0byBhc3NvY2lhdGUgd2l0aCB0aGUgcHJvcGVydHlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBDb21iaW5lZCBkZWNvcmF0b3IgZnVuY3Rpb25cbiAqXG4gKiBAZnVuY3Rpb24gcHJvcE1ldGFkYXRhXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvcE1ldGFkYXRhPFY+KGtleTogc3RyaW5nLCB2YWx1ZTogVikge1xuICByZXR1cm4gYXBwbHkocHJvcCgpLCBtZXRhZGF0YTxWPihrZXksIHZhbHVlKSk7XG59XG4iLCIvKipcbiAqIEBzdW1tYXJ5IE1pbWljcyBKYXZhJ3MgU3RyaW5nJ3MgSGFzaCBpbXBsZW1lbnRhdGlvblxuICpcbiAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyIHwgc3ltYm9sIHwgRGF0ZX0gb2JqXG4gKiBAcmV0dXJuIHtudW1iZXJ9IGhhc2ggdmFsdWUgb2Ygb2JqXG4gKlxuICogQGZ1bmN0aW9uIGhhc2hDb2RlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgTW9kZWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc2hDb2RlKG9iajogc3RyaW5nIHwgbnVtYmVyIHwgc3ltYm9sIHwgRGF0ZSk6IHN0cmluZyB7XG4gIG9iaiA9IFN0cmluZyhvYmopO1xuICBsZXQgaGFzaCA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgY2hhcmFjdGVyID0gb2JqLmNoYXJDb2RlQXQoaSk7XG4gICAgaGFzaCA9IChoYXNoIDw8IDUpIC0gaGFzaCArIGNoYXJhY3RlcjtcbiAgICBoYXNoID0gaGFzaCAmIGhhc2g7IC8vIENvbnZlcnQgdG8gMzJiaXQgaW50ZWdlclxuICB9XG4gIHJldHVybiBoYXNoLnRvU3RyaW5nKCk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyB0ZWggdHlwZSBmb3IgYSBIYXNoaW5nIGZ1bmN0aW9uXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgTW9kZWxcbiAqL1xuZXhwb3J0IHR5cGUgSGFzaGluZ0Z1bmN0aW9uID0gKHZhbHVlOiBhbnksIC4uLmFyZ3M6IGFueVtdKSA9PiBzdHJpbmc7XG5cbi8qKlxuICogQHN1bW1hcnkgSGFzaGVzIGFuIG9iamVjdCBieSBjb21iaW5pbmcgdGhlIGhhc2ggb2YgYWxsIGl0cyBwcm9wZXJ0aWVzXG4gKlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBvYmpcbiAqIEByZXR1cm4ge3N0cmluZ30gdGhlIHJlc3VsdGluZyBoYXNoXG4gKlxuICogQGZ1bmN0aW9uIGhhc2hPYmpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzaE9iaihvYmo6IFJlY29yZDxzdHJpbmcsIGFueT4gfCBhbnlbXSk6IHN0cmluZyB7XG4gIGNvbnN0IGhhc2hSZWR1Y2VyID0gZnVuY3Rpb24gKGg6IG51bWJlciB8IHN0cmluZywgZWw6IGFueSk6IHN0cmluZyB8IG51bWJlciB7XG4gICAgY29uc3QgZWxIYXNoID0gaGFzaEZ1bmN0aW9uKGVsKTtcblxuICAgIGlmICh0eXBlb2YgZWxIYXNoID09PSBcInN0cmluZ1wiKVxuICAgICAgcmV0dXJuIGhhc2hGdW5jdGlvbigoKGggYXMgc3RyaW5nKSB8fCBcIlwiKSArIGhhc2hGdW5jdGlvbihlbCkpO1xuXG4gICAgaCA9IGggfHwgMDtcbiAgICBoID0gKChoIGFzIG51bWJlcikgPDwgNSkgLSAoaCBhcyBudW1iZXIpICsgZWxIYXNoO1xuICAgIHJldHVybiBoICYgaDtcbiAgfTtcblxuICBjb25zdCBmdW5jOiBIYXNoaW5nRnVuY3Rpb24gPSBoYXNoQ29kZTtcblxuICBjb25zdCBoYXNoRnVuY3Rpb24gPSBmdW5jdGlvbiAodmFsdWU6IGFueSk6IHN0cmluZyB8IG51bWJlciB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIFwiXCI7XG4gICAgaWYgKFtcInN0cmluZ1wiLCBcIm51bWJlclwiLCBcInN5bWJvbFwiXS5pbmRleE9mKHR5cGVvZiB2YWx1ZSkgIT09IC0xKVxuICAgICAgcmV0dXJuIGZ1bmModmFsdWUudG9TdHJpbmcoKSk7XG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkgcmV0dXJuIGZ1bmModmFsdWUuZ2V0VGltZSgpKTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiB2YWx1ZS5yZWR1Y2UoaGFzaFJlZHVjZXIsIHVuZGVmaW5lZCk7XG4gICAgcmV0dXJuIChPYmplY3QudmFsdWVzKHZhbHVlKSBhcyAoc3RyaW5nIHwgbnVtYmVyKVtdKS5yZWR1Y2UoXG4gICAgICBoYXNoUmVkdWNlcixcbiAgICAgIHVuZGVmaW5lZCBhcyB1bmtub3duIGFzIHN0cmluZyB8IG51bWJlclxuICAgICk7XG4gIH07XG5cbiAgY29uc3QgcmVzdWx0ID0gT2JqZWN0LnZhbHVlcyhvYmopLnJlZHVjZShoYXNoUmVkdWNlciwgMCk7XG5cbiAgcmV0dXJuICh0eXBlb2YgcmVzdWx0ID09PSBcIm51bWJlclwiID8gTWF0aC5hYnMocmVzdWx0KSA6IHJlc3VsdCkudG9TdHJpbmcoKTtcbn1cblxuZXhwb3J0IGNvbnN0IERlZmF1bHRIYXNoaW5nTWV0aG9kID0gXCJkZWZhdWx0XCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1hbmFnZXMgaGFzaGluZyBtZXRob2RzIGFuZCBwcm92aWRlcyBhIHVuaWZpZWQgaGFzaGluZyBpbnRlcmZhY2VcbiAqIEBzdW1tYXJ5IEEgdXRpbGl0eSBjbGFzcyB0aGF0IHByb3ZpZGVzIGEgcmVnaXN0cnkgZm9yIGRpZmZlcmVudCBoYXNoaW5nIGZ1bmN0aW9ucyBhbmQgbWV0aG9kcyB0byBoYXNoIG9iamVjdHMuXG4gKiBUaGUgY2xhc3MgbWFpbnRhaW5zIGEgY2FjaGUgb2YgcmVnaXN0ZXJlZCBoYXNoaW5nIGZ1bmN0aW9ucyBhbmQgYWxsb3dzIHNldHRpbmcgYSBkZWZhdWx0IGhhc2hpbmcgbWV0aG9kLlxuICogSXQgcHJldmVudHMgZGlyZWN0IGluc3RhbnRpYXRpb24gYW5kIHByb3ZpZGVzIHN0YXRpYyBtZXRob2RzIGZvciByZWdpc3RyYXRpb24gYW5kIGhhc2hpbmcuXG4gKlxuICogQGNsYXNzIEhhc2hpbmdcbiAqIEBjYXRlZ29yeSBNb2RlbFxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBSZWdpc3RlciBhIGN1c3RvbSBoYXNoaW5nIGZ1bmN0aW9uXG4gKiBIYXNoaW5nLnJlZ2lzdGVyKCdtZDUnLCAob2JqKSA9PiBjcmVhdGVNRDVIYXNoKG9iaiksIHRydWUpO1xuICpcbiAqIC8vIEhhc2ggYW4gb2JqZWN0IHVzaW5nIGRlZmF1bHQgbWV0aG9kXG4gKiBjb25zdCBoYXNoMSA9IEhhc2hpbmcuaGFzaChteU9iamVjdCk7XG4gKlxuICogLy8gSGFzaCB1c2luZyBzcGVjaWZpYyBtZXRob2RcbiAqIGNvbnN0IGhhc2gyID0gSGFzaGluZy5oYXNoKG15T2JqZWN0LCAnbWQ1Jyk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIEhhc2hpbmcge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEN1cnJlbnQgZGVmYXVsdCBoYXNoaW5nIG1ldGhvZCBpZGVudGlmaWVyXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBjdXJyZW50OiBzdHJpbmcgPSBEZWZhdWx0SGFzaGluZ01ldGhvZDtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENhY2hlIG9mIHJlZ2lzdGVyZWQgaGFzaGluZyBmdW5jdGlvbnNcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGNhY2hlOiBSZWNvcmQ8c3RyaW5nLCBIYXNoaW5nRnVuY3Rpb24+ID0ge1xuICAgIGRlZmF1bHQ6IGhhc2hPYmosXG4gIH07XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYSByZWdpc3RlcmVkIGhhc2hpbmcgZnVuY3Rpb25cbiAgICogQHN1bW1hcnkgRmV0Y2hlcyBhIGhhc2hpbmcgZnVuY3Rpb24gZnJvbSB0aGUgY2FjaGUgYnkgaXRzIGtleS4gVGhyb3dzIGFuIGVycm9yIGlmIHRoZSBtZXRob2QgaXMgbm90IHJlZ2lzdGVyZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBUaGUgaWRlbnRpZmllciBvZiB0aGUgaGFzaGluZyBmdW5jdGlvbiB0byByZXRyaWV2ZVxuICAgKiBAcmV0dXJuIHtIYXNoaW5nRnVuY3Rpb259IFRoZSByZXF1ZXN0ZWQgaGFzaGluZyBmdW5jdGlvblxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0KGtleTogc3RyaW5nKTogYW55IHtcbiAgICBpZiAoa2V5IGluIHRoaXMuY2FjaGUpIHJldHVybiB0aGlzLmNhY2hlW2tleV07XG4gICAgdGhyb3cgbmV3IEVycm9yKGBObyBoYXNoaW5nIG1ldGhvZCByZWdpc3RlcmVkIHVuZGVyICR7a2V5fWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWdpc3RlcnMgYSBuZXcgaGFzaGluZyBmdW5jdGlvblxuICAgKiBAc3VtbWFyeSBBZGRzIGEgbmV3IGhhc2hpbmcgZnVuY3Rpb24gdG8gdGhlIHJlZ2lzdHJ5LiBPcHRpb25hbGx5IHNldHMgaXQgYXMgdGhlIGRlZmF1bHQgbWV0aG9kLlxuICAgKiBUaHJvd3MgYW4gZXJyb3IgaWYgYSBtZXRob2Qgd2l0aCB0aGUgc2FtZSBrZXkgaXMgYWxyZWFkeSByZWdpc3RlcmVkLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gVGhlIGlkZW50aWZpZXIgZm9yIHRoZSBoYXNoaW5nIGZ1bmN0aW9uXG4gICAqL1xuICBzdGF0aWMgcmVnaXN0ZXIoXG4gICAga2V5OiBzdHJpbmcsXG4gICAgZnVuYzogSGFzaGluZ0Z1bmN0aW9uLFxuICAgIHNldERlZmF1bHQgPSBmYWxzZVxuICApOiB2b2lkIHtcbiAgICBpZiAoa2V5IGluIHRoaXMuY2FjaGUpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEhhc2hpbmcgbWV0aG9kICR7a2V5fSBhbHJlYWR5IHJlZ2lzdGVyZWRgKTtcbiAgICB0aGlzLmNhY2hlW2tleV0gPSBmdW5jO1xuICAgIGlmIChzZXREZWZhdWx0KSB0aGlzLmN1cnJlbnQgPSBrZXk7XG4gIH1cblxuICBzdGF0aWMgaGFzaChvYmo6IGFueSwgbWV0aG9kPzogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGlmICghbWV0aG9kKSByZXR1cm4gdGhpcy5nZXQodGhpcy5jdXJyZW50KShvYmosIC4uLmFyZ3MpO1xuICAgIHJldHVybiB0aGlzLmdldChtZXRob2QpKG9iaiwgLi4uYXJncyk7XG4gIH1cblxuICBzdGF0aWMgc2V0RGVmYXVsdChtZXRob2Q6IHN0cmluZykge1xuICAgIHRoaXMuY3VycmVudCA9IHRoaXMuZ2V0KG1ldGhvZCk7XG4gIH1cbn1cbiIsImltcG9ydCB7IE1vZGVsRXJyb3JzIH0gZnJvbSBcIi4uL3ZhbGlkYXRpb24vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBIZWxwZXIgQ2xhc3MgdG8gaG9sZCB0aGUgZXJyb3IgcmVzdWx0c1xuICogQGRlc2NyaXB0aW9uIGhvbGRzIGVycm9yIHJlc3VsdHMgaW4gYW4gJ2luZGV4YWJsZScgbWFubmVyXG4gKiB3aGlsZSBzdGlsbCBwcm92aWRpbmcgdGhlIHNhbWUgcmVzdWx0IG9uIHRvU3RyaW5nXG4gKlxuICogQHBhcmFtIHtNb2RlbEVycm9yc30gZXJyb3JzXG4gKlxuICogQGNsYXNzIE1vZGVsRXJyb3JEZWZpbml0aW9uXG4gKlxuICogQGNhdGVnb3J5IE1vZGVsXG4gKi9cbmV4cG9ydCBjbGFzcyBNb2RlbEVycm9yRGVmaW5pdGlvbiB7XG4gIFtpbmRleGVyOiBzdHJpbmddOlxuICAgIHwgUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPlxuICAgIHwgKCgpID0+IHN0cmluZyB8IHVuZGVmaW5lZCk7XG5cbiAgY29uc3RydWN0b3IoZXJyb3JzOiBNb2RlbEVycm9ycykge1xuICAgIGZvciAoY29uc3QgcHJvcCBpbiBlcnJvcnMpIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXJyb3JzLCBwcm9wKSAmJiBlcnJvcnNbcHJvcF0pXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzIGFzIGFueSwgcHJvcCwge1xuICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICB2YWx1ZTogZXJyb3JzW3Byb3BdLFxuICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IE91dHB1dHMgdGhlIGNsYXNzIHRvIGEgbmljZSByZWFkYWJsZSBzdHJpbmdcbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqL1xuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIGNvbnN0IHNlbGY6IGFueSA9IHRoaXMgYXMgYW55O1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhzZWxmKVxuICAgICAgLmZpbHRlcihcbiAgICAgICAgKGspID0+XG4gICAgICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNlbGYsIGspICYmXG4gICAgICAgICAgdHlwZW9mIHNlbGZba10gIT09IFwiZnVuY3Rpb25cIlxuICAgICAgKVxuICAgICAgLnJlZHVjZSgoYWNjdW06IHN0cmluZywgcHJvcCkgPT4ge1xuICAgICAgICBsZXQgcHJvcEVycm9yOiBzdHJpbmcgfCB1bmRlZmluZWQgPSBPYmplY3Qua2V5cyhzZWxmW3Byb3BdKS5yZWR1Y2UoXG4gICAgICAgICAgKHByb3BBY2N1bTogdW5kZWZpbmVkIHwgc3RyaW5nLCBrZXkpID0+IHtcbiAgICAgICAgICAgIGlmICghcHJvcEFjY3VtKSBwcm9wQWNjdW0gPSBzZWxmW3Byb3BdW2tleV07XG4gICAgICAgICAgICBlbHNlIHByb3BBY2N1bSArPSBgXFxuJHtzZWxmW3Byb3BdW2tleV19YDtcbiAgICAgICAgICAgIHJldHVybiBwcm9wQWNjdW07XG4gICAgICAgICAgfSxcbiAgICAgICAgICB1bmRlZmluZWRcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAocHJvcEVycm9yKSB7XG4gICAgICAgICAgcHJvcEVycm9yID0gYCR7cHJvcH0gLSAke3Byb3BFcnJvcn1gO1xuICAgICAgICAgIGlmICghYWNjdW0pIGFjY3VtID0gcHJvcEVycm9yO1xuICAgICAgICAgIGVsc2UgYWNjdW0gKz0gYFxcbiR7cHJvcEVycm9yfWA7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LCBcIlwiKTtcbiAgfVxufVxuIiwiLyoqXG4gKiBAc3VtbWFyeSBSZWZlcmVuY2VzIHRoZSByZWxldmFudCBKUyBwcmltaXRpdmVzXG4gKlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFNUUklORyByZWZlcmVuY2VzIHRoZSBzdHJpbmcgcHJpbWl0aXZlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTlVNQkVSIHJlZmVyZW5jZXMgdGhlIG51bWJlciBwcmltaXRpdmVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBCT09MRUFOIHJlZmVyZW5jZXMgdGhlIGJvb2xlYW4gcHJpbWl0aXZlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gQklHSU5UIHJlZmVyZW5jZXMgdGhlIGJpZ2ludCBwcmltaXRpdmVcbiAqXG4gKiBAY29uc3RhbnQgUHJpbWl0aXZlc1xuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICovXG5leHBvcnQgZW51bSBQcmltaXRpdmVzIHtcbiAgU1RSSU5HID0gXCJzdHJpbmdcIixcbiAgTlVNQkVSID0gXCJudW1iZXJcIixcbiAgQk9PTEVBTiA9IFwiYm9vbGVhblwiLFxuICBCSUdJTlQgPSBcImJpZ2ludFwiLFxufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFJlZmVyZW5jZXMgdGhlIFJlc2VydmVkIG1vZGVsIG5hbWVzIHRvIGlnbm9yZSBkdXJpbmcgTW9kZWwgcmVidWlsZGluZ1xuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBTVFJJTkdcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBPQkpFQ1RcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBOVU1CRVJcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBCT09MRUFOXG4gKiBAcHJvcGVydHkge3N0cmluZ30gQklHSU5UXG4gKiBAcHJvcGVydHkge3N0cmluZ30gREFURVxuICpcbiAqIEBjb25zdGFudCBSZXNlcnZlZE1vZGVsc1xuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICovXG5leHBvcnQgZW51bSBSZXNlcnZlZE1vZGVscyB7XG4gIFNUUklORyA9IFwic3RyaW5nXCIsXG4gIE9CSkVDVCA9IFwib2JqZWN0XCIsXG4gIE5VTUJFUiA9IFwibnVtYmVyXCIsXG4gIEJPT0xFQU4gPSBcImJvb2xlYW5cIixcbiAgQklHSU5UID0gXCJiaWdpbnRcIixcbiAgREFURSA9IFwiZGF0ZVwiLFxufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFJlZmVyZW5jZXMgdGhlIGJhc2ljIHN1cHBvcnRlZCBqcyB0eXBlc1xuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzdHJpbmdcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBhcnJheVxuICogQHByb3BlcnR5IHtzdHJpbmd9IG51bWJlclxuICogQHByb3BlcnR5IHtzdHJpbmd9IGJvb2xlYW5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzeW1ib2xcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBmdW5jdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IG9iamVjdFxuICogQHByb3BlcnR5IHtzdHJpbmd9IHVuZGVmaW5lZFxuICogQHByb3BlcnR5IHtzdHJpbmd9IG51bGxcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBCSUdJTlRcbiAqXG4gKiBAY29uc3RhbnQganNUeXBlc1xuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICovXG5leHBvcnQgY29uc3QganNUeXBlcyA9IFtcbiAgXCJzdHJpbmdcIixcbiAgXCJhcnJheVwiLFxuICBcIm51bWJlclwiLFxuICBcImJvb2xlYW5cIixcbiAgXCJzeW1ib2xcIixcbiAgXCJmdW5jdGlvblwiLFxuICBcIm9iamVjdFwiLFxuICBcInVuZGVmaW5lZFwiLFxuICBcIm51bGxcIixcbiAgXCJiaWdpbnRcIixcbl07XG4iLCIvKipcbiAqIFN5bWJvbCB1c2VkIHRvIGludGVybmFsbHkgdHJhY2sgdGhlIHBhcmVudCBvYmplY3QgZHVyaW5nIG5lc3RlZCB2YWxpZGF0aW9uLlxuICpcbiAqIFRoaXMga2V5IGlzIGF0dGFjaGVkIHRvIGNoaWxkIG9iamVjdHMgdG8gcHJvdmlkZSBjb250ZXh0IGFib3V0IHRoZWlyIHBhcmVudFxuICogaW4gdGhlIG9iamVjdCBoaWVyYXJjaHksIGVuYWJsaW5nIHZhbGlkYXRpb25zIHRoYXQgZGVwZW5kIG9uIHBhcmVudCB2YWx1ZXMuXG4gKlxuICogQGNvbnN0YW50IFZBTElEQVRJT05fUEFSRU5UX0tFWVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5Nb2RlbFxuICovXG5leHBvcnQgY29uc3QgVkFMSURBVElPTl9QQVJFTlRfS0VZID0gU3ltYm9sKFwiX3ZhbGlkYXRpb25QYXJlbnRSZWZcIik7XG4iLCJpbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBzZiB9IGZyb20gXCIuLi8uLi91dGlscy9zdHJpbmdzXCI7XG5pbXBvcnQgeyBSZWZsZWN0aW9uIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBWYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEFic3RyYWN0IGJhc2UgY2xhc3MgZm9yIGFsbCB2YWxpZGF0b3JzIGluIHRoZSB2YWxpZGF0aW9uIGZyYW1ld29ya1xuICogQHN1bW1hcnkgVGhlIFZhbGlkYXRvciBjbGFzcyBwcm92aWRlcyB0aGUgZm91bmRhdGlvbiBmb3IgYWxsIHZhbGlkYXRvciBpbXBsZW1lbnRhdGlvbnMuXG4gKiBJdCBoYW5kbGVzIHR5cGUgY2hlY2tpbmcsIGVycm9yIG1lc3NhZ2UgZm9ybWF0dGluZywgYW5kIGRlZmluZXMgdGhlIGNvbW1vbiBpbnRlcmZhY2VcbiAqIHRoYXQgYWxsIHZhbGlkYXRvcnMgbXVzdCBpbXBsZW1lbnQuIFRoaXMgY2xhc3MgaXMgZGVzaWduZWQgdG8gYmUgZXh0ZW5kZWQgYnkgc3BlY2lmaWNcbiAqIHZhbGlkYXRvciBpbXBsZW1lbnRhdGlvbnMgdGhhdCBwcm92aWRlIGNvbmNyZXRlIHZhbGlkYXRpb24gbG9naWMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBEZWZhdWx0IGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIHZhbGlkYXRpb24gZmFpbHMsIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0RFRkFVTFR9XG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBhY2NlcHRlZFR5cGVzIC0gQXJyYXkgb2YgdHlwZSBuYW1lcyB0aGF0IHRoaXMgdmFsaWRhdG9yIGNhbiB2YWxpZGF0ZVxuICpcbiAqIEBjbGFzcyBWYWxpZGF0b3JcbiAqIEBhYnN0cmFjdFxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBFeGFtcGxlIG9mIGV4dGVuZGluZyB0aGUgVmFsaWRhdG9yIGNsYXNzIHRvIGNyZWF0ZSBhIGN1c3RvbSB2YWxpZGF0b3JcbiAqIGNsYXNzIEN1c3RvbVZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvcjxDdXN0b21WYWxpZGF0b3JPcHRpb25zPiB7XG4gKiAgIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IFwiQ3VzdG9tIHZhbGlkYXRpb24gZmFpbGVkXCIpIHtcbiAqICAgICAvLyBTcGVjaWZ5IHRoYXQgdGhpcyB2YWxpZGF0b3IgYWNjZXB0cyBTdHJpbmcgYW5kIE51bWJlciB0eXBlc1xuICogICAgIHN1cGVyKG1lc3NhZ2UsIFN0cmluZy5uYW1lLCBOdW1iZXIubmFtZSk7XG4gKiAgIH1cbiAqXG4gKiAgIHB1YmxpYyBoYXNFcnJvcnModmFsdWU6IGFueSwgb3B0aW9ucz86IEN1c3RvbVZhbGlkYXRvck9wdGlvbnMpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICogICAgIC8vIEltcGxlbWVudCBjdXN0b20gdmFsaWRhdGlvbiBsb2dpY1xuICogICAgIGlmIChzb21lQ29uZGl0aW9uKSB7XG4gKiAgICAgICByZXR1cm4gdGhpcy5nZXRNZXNzYWdlKG9wdGlvbnM/Lm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlKTtcbiAqICAgICB9XG4gKiAgICAgcmV0dXJuIHVuZGVmaW5lZDsgLy8gTm8gZXJyb3JzXG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQyBhcyBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgViBhcyBWYWxpZGF0b3IgU3ViY2xhc3NcbiAqICAgcGFydGljaXBhbnQgQiBhcyBCYXNlIFZhbGlkYXRvclxuICpcbiAqICAgQy0+PlY6IG5ldyBDdXN0b21WYWxpZGF0b3IobWVzc2FnZSlcbiAqICAgVi0+PkI6IHN1cGVyKG1lc3NhZ2UsIGFjY2VwdGVkVHlwZXMpXG4gKiAgIEItPj5COiBTdG9yZSBtZXNzYWdlIGFuZCB0eXBlc1xuICogICBCLT4+QjogV3JhcCBoYXNFcnJvcnMgd2l0aCB0eXBlIGNoZWNraW5nXG4gKiAgIEMtPj5WOiBoYXNFcnJvcnModmFsdWUsIG9wdGlvbnMpXG4gKiAgIGFsdCB2YWx1ZSB0eXBlIG5vdCBpbiBhY2NlcHRlZFR5cGVzXG4gKiAgICAgQi0tPj5DOiBUeXBlIGVycm9yIG1lc3NhZ2VcbiAqICAgZWxzZSB2YWx1ZSB0eXBlIGlzIGFjY2VwdGVkXG4gKiAgICAgVi0+PlY6IEN1c3RvbSB2YWxpZGF0aW9uIGxvZ2ljXG4gKiAgICAgVi0tPj5DOiBWYWxpZGF0aW9uIHJlc3VsdFxuICogICBlbmRcbiAqXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgVmFsaWRhdG9yPFYgZXh0ZW5kcyBWYWxpZGF0b3JPcHRpb25zID0gVmFsaWRhdG9yT3B0aW9ucz4ge1xuICByZWFkb25seSBtZXNzYWdlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGFjY2VwdGVkVHlwZXM/OiBzdHJpbmdbXTtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoXG4gICAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5ERUZBVUxULFxuICAgIC4uLmFjY2VwdGVkVHlwZXM6IHN0cmluZ1tdXG4gICkge1xuICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG5cbiAgICBpZiAoYWNjZXB0ZWRUeXBlcy5sZW5ndGgpIHRoaXMuYWNjZXB0ZWRUeXBlcyA9IGFjY2VwdGVkVHlwZXM7XG4gICAgaWYgKHRoaXMuYWNjZXB0ZWRUeXBlcylcbiAgICAgIHRoaXMuaGFzRXJyb3JzID0gdGhpcy5jaGVja1R5cGVBbmRIYXNFcnJvcnModGhpcy5oYXNFcnJvcnMuYmluZCh0aGlzKSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEZvcm1hdHMgYW4gZXJyb3IgbWVzc2FnZSB3aXRoIG9wdGlvbmFsIGFyZ3VtZW50c1xuICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgZm9ybWF0dGVkIGVycm9yIG1lc3NhZ2UgYnkgcmVwbGFjaW5nIHBsYWNlaG9sZGVycyB3aXRoIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAgICogVGhpcyBtZXRob2QgdXNlcyB0aGUgc3RyaW5nIGZvcm1hdHRpbmcgdXRpbGl0eSB0byBnZW5lcmF0ZSBjb25zaXN0ZW50IGVycm9yIG1lc3NhZ2VzXG4gICAqIGFjcm9zcyBhbGwgdmFsaWRhdG9ycy5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBUaGUgbWVzc2FnZSB0ZW1wbGF0ZSB3aXRoIHBsYWNlaG9sZGVyc1xuICAgKiBAcGFyYW0gey4uLmFueX0gYXJncyAtIFZhbHVlcyB0byBpbnNlcnQgaW50byB0aGUgbWVzc2FnZSB0ZW1wbGF0ZVxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBmb3JtYXR0ZWQgZXJyb3IgbWVzc2FnZVxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0TWVzc2FnZShtZXNzYWdlOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgcmV0dXJuIHNmKG1lc3NhZ2UsIC4uLmFyZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgdHlwZS1jaGVja2luZyB3cmFwcGVyIGFyb3VuZCB0aGUgaGFzRXJyb3JzIG1ldGhvZFxuICAgKiBAc3VtbWFyeSBXcmFwcyB0aGUgaGFzRXJyb3JzIG1ldGhvZCB3aXRoIHR5cGUgdmFsaWRhdGlvbiBsb2dpYyB0byBlbnN1cmUgdGhhdFxuICAgKiB0aGUgdmFsdWUgYmVpbmcgdmFsaWRhdGVkIGlzIG9mIGFuIGFjY2VwdGVkIHR5cGUgYmVmb3JlIHBlcmZvcm1pbmcgc3BlY2lmaWMgdmFsaWRhdGlvbi5cbiAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGR1cmluZyBjb25zdHJ1Y3Rpb24gaWYgYWNjZXB0ZWRUeXBlcyBhcmUgcHJvdmlkZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHVuYm91bmQgLSBUaGUgb3JpZ2luYWwgaGFzRXJyb3JzIG1ldGhvZCB0byBiZSB3cmFwcGVkXG4gICAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG5ldyBmdW5jdGlvbiB0aGF0IHBlcmZvcm1zIHR5cGUgY2hlY2tpbmcgYmVmb3JlIGNhbGxpbmcgdGhlIG9yaWdpbmFsIG1ldGhvZFxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBjaGVja1R5cGVBbmRIYXNFcnJvcnMoXG4gICAgdW5ib3VuZDogKHZhbHVlOiBhbnksIC4uLmFyZ3M6IGFueVtdKSA9PiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChcbiAgICAgIHRoaXM6IFZhbGlkYXRvcixcbiAgICAgIHZhbHVlOiBhbnksXG4gICAgICAuLi5hcmdzOiBhbnlbXVxuICAgICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCAhdGhpcy5hY2NlcHRlZFR5cGVzKVxuICAgICAgICByZXR1cm4gdW5ib3VuZCh2YWx1ZSwgLi4uYXJncyk7XG4gICAgICBpZiAoIVJlZmxlY3Rpb24uY2hlY2tUeXBlcyh2YWx1ZSwgdGhpcy5hY2NlcHRlZFR5cGVzKSlcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZShcbiAgICAgICAgICBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlRZUEUsXG4gICAgICAgICAgdGhpcy5hY2NlcHRlZFR5cGVzLmpvaW4oXCIsIFwiKSxcbiAgICAgICAgICB0eXBlb2YgdmFsdWVcbiAgICAgICAgKTtcbiAgICAgIHJldHVybiB1bmJvdW5kKHZhbHVlLCAuLi5hcmdzKTtcbiAgICB9LmJpbmQodGhpcyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFZhbGlkYXRlcyBhIHZhbHVlIGFnYWluc3Qgc3BlY2lmaWMgdmFsaWRhdGlvbiBydWxlc1xuICAgKiBAc3VtbWFyeSBBYnN0cmFjdCBtZXRob2QgdGhhdCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGFsbCB2YWxpZGF0b3Igc3ViY2xhc3Nlcy5cbiAgICogVGhpcyBtZXRob2QgY29udGFpbnMgdGhlIGNvcmUgdmFsaWRhdGlvbiBsb2dpYyB0aGF0IGRldGVybWluZXMgd2hldGhlciBhIHZhbHVlXG4gICAqIGlzIHZhbGlkIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWMgcnVsZXMgb2YgdGhlIHZhbGlkYXRvci4gSWYgdGhlIHZhbHVlIGlzIHZhbGlkLFxuICAgKiB0aGUgbWV0aG9kIHJldHVybnMgdW5kZWZpbmVkOyBvdGhlcndpc2UsIGl0IHJldHVybnMgYW4gZXJyb3IgbWVzc2FnZS5cbiAgICpcbiAgICogQHRlbXBsYXRlIFYgLSBUeXBlIG9mIHRoZSBvcHRpb25zIG9iamVjdCB0aGF0IGNhbiBiZSBwYXNzZWQgdG8gdGhlIHZhbGlkYXRvclxuICAgKiBAcGFyYW0ge2FueX0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gdmFsaWRhdGVcbiAgICogQHBhcmFtIHtWfSBbb3B0aW9uc10gLSBPcHRpb25hbCBjb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIGN1c3RvbWl6aW5nIHZhbGlkYXRpb24gYmVoYXZpb3JcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfSBFcnJvciBtZXNzYWdlIGlmIHZhbGlkYXRpb24gZmFpbHMsIHVuZGVmaW5lZCBpZiB2YWxpZGF0aW9uIHBhc3Nlc1xuICAgKlxuICAgKiBAYWJzdHJhY3RcbiAgICpcbiAgICogQHNlZSBNb2RlbCN2YWxpZGF0ZVxuICAgKi9cbiAgcHVibGljIGFic3RyYWN0IGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogYW55LFxuICAgIG9wdGlvbnM/OiBWLFxuICAgIGluc3RhbmNlT2JqPzogYW55XG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQHN1bW1hcnkgRHVjayB0eXBpbmcgZm9yIFZhbGlkYXRvcnNcbiAgICogQHBhcmFtIHZhbFxuICAgKi9cbiAgc3RhdGljIGlzVmFsaWRhdG9yKHZhbDogYW55KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHZhbC5jb25zdHJ1Y3RvciAmJiAhIXZhbFtcImhhc0Vycm9yc1wiXTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yRGVmaW5pdGlvbiB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgSVZhbGlkYXRvclJlZ2lzdHJ5IH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tIFwiLi9WYWxpZGF0b3JcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBCYXNlIEltcGxlbWVudGF0aW9uIG9mIGEgVmFsaWRhdG9yIFJlZ2lzdHJ5XG4gKlxuICogQHByb3Age1ZhbGlkYXRvcltdfSBbdmFsaWRhdG9yc10gdGhlIGluaXRpYWwgdmFsaWRhdG9ycyB0byByZWdpc3RlclxuICpcbiAqIEBjbGFzcyBWYWxpZGF0b3JSZWdpc3RyeVxuICogQGltcGxlbWVudHMgSVZhbGlkYXRvclJlZ2lzdHJ5PFQ+XG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRpb25cbiAqL1xuZXhwb3J0IGNsYXNzIFZhbGlkYXRvclJlZ2lzdHJ5PFQgZXh0ZW5kcyBWYWxpZGF0b3I+XG4gIGltcGxlbWVudHMgSVZhbGlkYXRvclJlZ2lzdHJ5PFQ+XG57XG4gIHByaXZhdGUgY2FjaGU6IGFueSA9IHt9O1xuICBwcml2YXRlIGN1c3RvbUtleUNhY2hlOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIGNvbnN0cnVjdG9yKC4uLnZhbGlkYXRvcnM6IChWYWxpZGF0b3JEZWZpbml0aW9uIHwgVmFsaWRhdG9yKVtdKSB7XG4gICAgdGhpcy5jdXN0b21LZXlDYWNoZSA9IHt9O1xuICAgIHRoaXMucmVnaXN0ZXIoLi4udmFsaWRhdG9ycyk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgcmV0cmlldmVzIHRoZSBjdXN0b20ga2V5c1xuICAgKi9cbiAgZ2V0Q3VzdG9tS2V5cygpOiB7IFtpbmRleGVyOiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHRoaXMuY3VzdG9tS2V5Q2FjaGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHJldHJpZXZlcyB0aGUgcmVnaXN0ZXJlZCB2YWxpZGF0b3JzIGtleXNcbiAgICovXG4gIGdldEtleXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLmNhY2hlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgYSB2YWxpZGF0b3JcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbGlkYXRvcktleSBvbmUgb2YgdGhlIHtAbGluayBWYWxpZGF0aW9uS2V5c31cbiAgICogQHJldHVybiB7VmFsaWRhdG9yIHwgdW5kZWZpbmVkfSB0aGUgcmVnaXN0ZXJlZCBWYWxpZGF0b3Igb3IgdW5kZWZpbmVkIGlmIHRoZXJlIGlzIG5vbm8gbWF0Y2hpbmcgdGhlIHByb3ZpZGVkIGtleVxuICAgKi9cbiAgZ2V0PFQgZXh0ZW5kcyBWYWxpZGF0b3I+KHZhbGlkYXRvcktleTogc3RyaW5nKTogVCB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCEodmFsaWRhdG9yS2V5IGluIHRoaXMuY2FjaGUpKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgY2xhc3NPckluc3RhbmNlID0gdGhpcy5jYWNoZVt2YWxpZGF0b3JLZXldO1xuICAgIGlmIChWYWxpZGF0b3IuaXNWYWxpZGF0b3IoY2xhc3NPckluc3RhbmNlKSkgcmV0dXJuIGNsYXNzT3JJbnN0YW5jZSBhcyBUO1xuICAgIGNvbnN0IGNvbnN0cnVjdG9yID0gY2xhc3NPckluc3RhbmNlLmRlZmF1bHQgfHwgY2xhc3NPckluc3RhbmNlO1xuICAgIGNvbnN0IGluc3RhbmNlID0gbmV3IGNvbnN0cnVjdG9yKCk7XG4gICAgdGhpcy5jYWNoZVt2YWxpZGF0b3JLZXldID0gaW5zdGFuY2U7XG4gICAgcmV0dXJuIGluc3RhbmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJlZ2lzdGVycyB0aGUgcHJvdmlkZWQgdmFsaWRhdG9ycyBvbnRvIHRoZSByZWdpc3RyeVxuICAgKlxuICAgKiBAcGFyYW0ge1RbXSB8IFZhbGlkYXRvckRlZmluaXRpb25bXX0gdmFsaWRhdG9yXG4gICAqL1xuICByZWdpc3RlcjxUIGV4dGVuZHMgVmFsaWRhdG9yPihcbiAgICAuLi52YWxpZGF0b3I6IChWYWxpZGF0b3JEZWZpbml0aW9uIHwgVClbXVxuICApOiB2b2lkIHtcbiAgICB2YWxpZGF0b3IuZm9yRWFjaCgodikgPT4ge1xuICAgICAgaWYgKFZhbGlkYXRvci5pc1ZhbGlkYXRvcih2KSkge1xuICAgICAgICAvLyBjb25zdCBrID1cblxuICAgICAgICBpZiAoKHYgYXMgVmFsaWRhdG9yRGVmaW5pdGlvbikudmFsaWRhdGlvbktleSBpbiB0aGlzLmNhY2hlKSByZXR1cm47XG4gICAgICAgIHRoaXMuY2FjaGVbKHYgYXMgVmFsaWRhdG9yRGVmaW5pdGlvbikudmFsaWRhdGlvbktleV0gPSB2O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgeyB2YWxpZGF0aW9uS2V5LCB2YWxpZGF0b3IsIHNhdmUgfSA9IHYgYXMgVmFsaWRhdG9yRGVmaW5pdGlvbjtcbiAgICAgICAgaWYgKHZhbGlkYXRpb25LZXkgaW4gdGhpcy5jYWNoZSkgcmV0dXJuO1xuICAgICAgICB0aGlzLmNhY2hlW3ZhbGlkYXRpb25LZXldID0gdmFsaWRhdG9yO1xuICAgICAgICBpZiAoIXNhdmUpIHJldHVybjtcbiAgICAgICAgY29uc3Qgb2JqOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gICAgICAgIG9ialt2YWxpZGF0aW9uS2V5LnRvVXBwZXJDYXNlKCldID0gdmFsaWRhdGlvbktleTtcblxuICAgICAgICB0aGlzLmN1c3RvbUtleUNhY2hlID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5jdXN0b21LZXlDYWNoZSwgb2JqKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9ycy9WYWxpZGF0b3JcIjtcbmltcG9ydCB7IElWYWxpZGF0b3JSZWdpc3RyeSwgVmFsaWRhdG9yRGVmaW5pdGlvbiB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBWYWxpZGF0b3JSZWdpc3RyeSB9IGZyb20gXCIuL1ZhbGlkYXRvcnMvVmFsaWRhdG9yUmVnaXN0cnlcIjtcbmltcG9ydCB7IFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vVmFsaWRhdG9ycy9jb25zdGFudHNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBTdGF0aWMgY2xhc3MgYWN0aW5nIGFzIGEgbmFtZXNwYWNlIGZvciB0aGUgVmFsaWRhdGlvblxuICpcbiAqIEBjbGFzcyBWYWxpZGF0aW9uXG4gKiBAc3RhdGljXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRpb25cbiAqL1xuZXhwb3J0IGNsYXNzIFZhbGlkYXRpb24ge1xuICBwcml2YXRlIHN0YXRpYyBhY3RpbmdWYWxpZGF0b3JSZWdpc3RyeT86IElWYWxpZGF0b3JSZWdpc3RyeTxWYWxpZGF0b3I+ID1cbiAgICB1bmRlZmluZWQ7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIGFjdGluZyBWYWxpZGF0b3JSZWdpc3RyeVxuICAgKlxuICAgKiBAcGFyYW0ge0lWYWxpZGF0b3JSZWdpc3RyeX0gdmFsaWRhdG9yUmVnaXN0cnkgdGhlIG5ldyBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgdmFsaWRhdG9yIFJlZ2lzdHJ5XG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oVmFsaWRhdG9yKTogVmFsaWRhdG9yfSBbbWlncmF0aW9uSGFuZGxlcl0gdGhlIG1ldGhvZCB0byBtYXAgdGhlIHZhbGlkYXRvciBpZiByZXF1aXJlZDtcbiAgICovXG4gIHN0YXRpYyBzZXRSZWdpc3RyeShcbiAgICB2YWxpZGF0b3JSZWdpc3RyeTogSVZhbGlkYXRvclJlZ2lzdHJ5PFZhbGlkYXRvcj4sXG4gICAgbWlncmF0aW9uSGFuZGxlcj86ICh2YWxpZGF0b3I6IFZhbGlkYXRvcikgPT4gVmFsaWRhdG9yXG4gICkge1xuICAgIGlmIChtaWdyYXRpb25IYW5kbGVyICYmIFZhbGlkYXRpb24uYWN0aW5nVmFsaWRhdG9yUmVnaXN0cnkpXG4gICAgICBWYWxpZGF0aW9uLmFjdGluZ1ZhbGlkYXRvclJlZ2lzdHJ5LmdldEtleXMoKS5mb3JFYWNoKChrOiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgdmFsaWRhdG9yID0gdmFsaWRhdG9yUmVnaXN0cnkuZ2V0KGspO1xuICAgICAgICBpZiAodmFsaWRhdG9yKSB2YWxpZGF0b3JSZWdpc3RyeS5yZWdpc3RlcihtaWdyYXRpb25IYW5kbGVyKHZhbGlkYXRvcikpO1xuICAgICAgfSk7XG4gICAgVmFsaWRhdGlvbi5hY3RpbmdWYWxpZGF0b3JSZWdpc3RyeSA9IHZhbGlkYXRvclJlZ2lzdHJ5O1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIGN1cnJlbnQgVmFsaWRhdG9yUmVnaXN0cnlcbiAgICpcbiAgICogQHJldHVybiBJVmFsaWRhdG9yUmVnaXN0cnksIGRlZmF1bHRzIHRvIHtAbGluayBWYWxpZGF0b3JSZWdpc3RyeX1cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdldFJlZ2lzdHJ5KCkge1xuICAgIGlmICghVmFsaWRhdGlvbi5hY3RpbmdWYWxpZGF0b3JSZWdpc3RyeSlcbiAgICAgIFZhbGlkYXRpb24uYWN0aW5nVmFsaWRhdG9yUmVnaXN0cnkgPSBuZXcgVmFsaWRhdG9yUmVnaXN0cnkoKTtcbiAgICByZXR1cm4gVmFsaWRhdGlvbi5hY3RpbmdWYWxpZGF0b3JSZWdpc3RyeTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgYSB2YWxpZGF0b3JcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbGlkYXRvcktleSBvbmUgb2YgdGhlIHtAbGluayBWYWxpZGF0aW9uS2V5c31cbiAgICogQHJldHVybiB7VmFsaWRhdG9yIHwgdW5kZWZpbmVkfSB0aGUgcmVnaXN0ZXJlZCBWYWxpZGF0b3Igb3IgdW5kZWZpbmVkIGlmIHRoZXJlIGlzIG5vbm8gbWF0Y2hpbmcgdGhlIHByb3ZpZGVkIGtleVxuICAgKi9cbiAgc3RhdGljIGdldDxUIGV4dGVuZHMgVmFsaWRhdG9yPih2YWxpZGF0b3JLZXk6IHN0cmluZyk6IFQgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBWYWxpZGF0aW9uLmdldFJlZ2lzdHJ5KCkuZ2V0KHZhbGlkYXRvcktleSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgUmVnaXN0ZXJzIHRoZSBwcm92aWRlZCB2YWxpZGF0b3JzIG9udG8gdGhlIHJlZ2lzdHJ5XG4gICAqXG4gICAqIEBwYXJhbSB7VFtdIHwgVmFsaWRhdG9yRGVmaW5pdGlvbltdfSB2YWxpZGF0b3JcbiAgICovXG4gIHN0YXRpYyByZWdpc3RlcjxUIGV4dGVuZHMgVmFsaWRhdG9yPihcbiAgICAuLi52YWxpZGF0b3I6IChWYWxpZGF0b3JEZWZpbml0aW9uIHwgVClbXVxuICApOiB2b2lkIHtcbiAgICByZXR1cm4gVmFsaWRhdGlvbi5nZXRSZWdpc3RyeSgpLnJlZ2lzdGVyKC4uLnZhbGlkYXRvcik7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgQnVpbGRzIHRoZSBrZXkgdG8gc3RvcmUgYXMgTWV0YWRhdGEgdW5kZXIgUmVmbGVjdGlvbnNcbiAgICogQGRlc2NyaXB0aW9uIGNvbmNhdGVuYXRlcyB7QGxpbmsgVmFsaWRhdGlvbktleXMjUkVGTEVDVH0gd2l0aCB0aGUgcHJvdmlkZWQga2V5XG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAgICovXG4gIHN0YXRpYyBrZXkoa2V5OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gVmFsaWRhdGlvbktleXMuUkVGTEVDVCArIGtleTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZXR1cm5zIGFsbCByZWdpc3RlcmVkIHZhbGlkYXRpb24ga2V5c1xuICAgKi9cbiAgc3RhdGljIGtleXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UmVnaXN0cnkoKS5nZXRLZXlzKCk7XG4gIH1cbn1cbiIsImltcG9ydCB7IE1vZGVsRXJyb3JEZWZpbml0aW9uIH0gZnJvbSBcIi4vTW9kZWxFcnJvckRlZmluaXRpb25cIjtcbmltcG9ydCB7IERlY29yYXRvck1ldGFkYXRhLCBSZWZsZWN0aW9uIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBNb2RlbEtleXMgfSBmcm9tIFwiLi4vdXRpbHMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBSZXNlcnZlZE1vZGVscyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgVkFMSURBVElPTl9QQVJFTlRfS0VZIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgVmFsaWRhdGFibGUgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiLi9Nb2RlbFwiO1xuaW1wb3J0IHsgVmFsaWRhdGlvbiB9IGZyb20gXCIuLi92YWxpZGF0aW9uL1ZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4uL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9jb25zdGFudHNcIjtcbmltcG9ydCB7XG4gIE1vZGVsRXJyb3JzLFxuICBWYWxpZGF0aW9uUHJvcGVydHlEZWNvcmF0b3JEZWZpbml0aW9uLFxuICBWYWxpZGF0b3JPcHRpb25zLFxufSBmcm9tIFwiLi4vdmFsaWRhdGlvbi90eXBlc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IEFuYWx5c2VzIHRoZSBkZWNvcmF0aW9ucyBvZiB0aGUgcHJvcGVydGllcyBhbmQgdmFsaWRhdGVzIHRoZSBvYmogYWNjb3JkaW5nIHRvIHRoZW1cbiAqXG4gKiBAdHlwZWRlZiBNIGV4dGVuZHMgTW9kZWxcbiAqIEBwcm9wIHtNfSBvYmogTW9kZWwgb2JqZWN0IHRvIHZhbGlkYXRlXG4gKiBAcHJvcCB7c3RyaW5nW119IFtwcm9wc1RvSWdub3JlXSBvYmplY3QgcHJvcGVydGllcyB0byBpZ25vcmUgaW4gdGhlIHZhbGlkYXRpb25cbiAqXG4gKiBAZnVuY3Rpb24gdmFsaWRhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGU8TSBleHRlbmRzIE1vZGVsPihcbiAgb2JqOiBNLFxuICAuLi5wcm9wc1RvSWdub3JlOiBzdHJpbmdbXVxuKTogTW9kZWxFcnJvckRlZmluaXRpb24gfCB1bmRlZmluZWQge1xuICBjb25zdCBkZWNvcmF0ZWRQcm9wZXJ0aWVzOiBWYWxpZGF0aW9uUHJvcGVydHlEZWNvcmF0b3JEZWZpbml0aW9uW10gPSBbXTtcbiAgZm9yIChjb25zdCBwcm9wIGluIG9iailcbiAgICBpZiAoXG4gICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKSAmJlxuICAgICAgcHJvcHNUb0lnbm9yZS5pbmRleE9mKHByb3ApID09PSAtMVxuICAgIClcbiAgICAgIGRlY29yYXRlZFByb3BlcnRpZXMucHVzaChcbiAgICAgICAgUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICAgICAgVmFsaWRhdGlvbktleXMuUkVGTEVDVCxcbiAgICAgICAgICBvYmosXG4gICAgICAgICAgcHJvcFxuICAgICAgICApIGFzIFZhbGlkYXRpb25Qcm9wZXJ0eURlY29yYXRvckRlZmluaXRpb25cbiAgICAgICk7XG5cbiAgbGV0IHJlc3VsdDogTW9kZWxFcnJvcnMgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cbiAgZm9yIChjb25zdCBkZWNvcmF0ZWRQcm9wZXJ0eSBvZiBkZWNvcmF0ZWRQcm9wZXJ0aWVzKSB7XG4gICAgY29uc3QgeyBwcm9wLCBkZWNvcmF0b3JzIH0gPSBkZWNvcmF0ZWRQcm9wZXJ0eTtcblxuICAgIGlmICghZGVjb3JhdG9ycyB8fCAhZGVjb3JhdG9ycy5sZW5ndGgpIGNvbnRpbnVlO1xuXG4gICAgY29uc3QgZGVmYXVsdFR5cGVEZWNvcmF0b3I6IERlY29yYXRvck1ldGFkYXRhID0gZGVjb3JhdG9yc1swXTtcblxuICAgIC8vIHRyaWVzIHRvIGZpbmQgYW55IHR5cGUgZGVjb3JhdG9ycyBvciBvdGhlciBkZWNvcmF0b3JzIHRoYXQgYWxyZWFkeSBlbmZvcmNlIHR5cGUgKHRoZSBvbmVzIHdpdGggdGhlIGFsbG93ZWQgdHlwZXMgcHJvcGVydHkgZGVmaW5lZCkuIGlmIHNvLCBza2lwIHRoZSBkZWZhdWx0IHR5cGUgdmVyaWZpY2F0aW9uXG4gICAgaWYgKFxuICAgICAgZGVjb3JhdG9ycy5maW5kKChkKSA9PiB7XG4gICAgICAgIGlmIChkLmtleSA9PT0gVmFsaWRhdGlvbktleXMuVFlQRSkgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiAhIWQucHJvcHMudHlwZXM/LmZpbmQoXG4gICAgICAgICAgKHQpID0+IHQgPT09IGRlZmF1bHRUeXBlRGVjb3JhdG9yLnByb3BzLm5hbWVcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKSB7XG4gICAgICBkZWNvcmF0b3JzLnNoaWZ0KCk7IC8vIHJlbW92ZSB0aGUgZGVzaWduOnR5cGUgZGVjb3JhdG9yLCBzaW5jZSB0aGUgdHlwZSB3aWxsIGFscmVhZHkgYmUgY2hlY2tlZFxuICAgIH1cblxuICAgIGxldCBlcnJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gICAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgZGVjb3JhdG9ycykge1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gVmFsaWRhdGlvbi5nZXQoZGVjb3JhdG9yLmtleSk7XG4gICAgICBpZiAoIXZhbGlkYXRvcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgdmFsaWRhdG9yIGZvciAke2RlY29yYXRvci5rZXl9YCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRlY29yYXRvclByb3BzID1cbiAgICAgICAgZGVjb3JhdG9yLmtleSA9PT0gTW9kZWxLZXlzLlRZUEVcbiAgICAgICAgICA/IFtkZWNvcmF0b3IucHJvcHNdXG4gICAgICAgICAgOiBkZWNvcmF0b3IucHJvcHMgfHwge307XG5cbiAgICAgIGNvbnN0IGVycjogc3RyaW5nIHwgdW5kZWZpbmVkID0gdmFsaWRhdG9yLmhhc0Vycm9ycyhcbiAgICAgICAgKG9iaiBhcyBhbnkpW3Byb3AudG9TdHJpbmcoKV0sXG4gICAgICAgIGRlY29yYXRvclByb3BzIGFzIFZhbGlkYXRvck9wdGlvbnMsXG4gICAgICAgIG9iaiAvLyBUT0RPOiBBc3NlcnQgdHlwZSBhbmQgZGVlcCBPYmplY3QuZnJlZXplXG4gICAgICApO1xuXG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIGVycnMgPSBlcnJzIHx8IHt9O1xuICAgICAgICBlcnJzW2RlY29yYXRvci5rZXldID0gZXJyO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlcnJzKSB7XG4gICAgICByZXN1bHQgPSByZXN1bHQgfHwge307XG4gICAgICByZXN1bHRbZGVjb3JhdGVkUHJvcGVydHkucHJvcC50b1N0cmluZygpXSA9IGVycnM7XG4gICAgfVxuICB9XG5cbiAgLy8gdGVzdHMgbmVzdGVkIGNsYXNzZXNcbiAgZm9yIChjb25zdCBwcm9wIG9mIE9iamVjdC5rZXlzKG9iaikuZmlsdGVyKChrKSA9PiAhcmVzdWx0IHx8ICFyZXN1bHRba10pKSB7XG4gICAgbGV0IGVycjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIC8vIGlmIGEgbmVzdGVkIE1vZGVsXG4gICAgY29uc3QgYWxsRGVjb3JhdG9ycyA9IFJlZmxlY3Rpb24uZ2V0UHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgVmFsaWRhdGlvbktleXMuUkVGTEVDVCxcbiAgICAgIG9iaixcbiAgICAgIHByb3BcbiAgICApLmRlY29yYXRvcnM7XG4gICAgY29uc3QgZGVjb3JhdG9ycyA9IFJlZmxlY3Rpb24uZ2V0UHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgVmFsaWRhdGlvbktleXMuUkVGTEVDVCxcbiAgICAgIG9iaixcbiAgICAgIHByb3BcbiAgICApLmRlY29yYXRvcnMuZmlsdGVyKFxuICAgICAgKGQ6IHsga2V5OiBzdHJpbmcgfSkgPT5cbiAgICAgICAgW01vZGVsS2V5cy5UWVBFLCBWYWxpZGF0aW9uS2V5cy5UWVBFIGFzIHN0cmluZ10uaW5kZXhPZihkLmtleSkgIT09IC0xXG4gICAgKTtcbiAgICBpZiAoIWRlY29yYXRvcnMgfHwgIWRlY29yYXRvcnMubGVuZ3RoKSBjb250aW51ZTtcbiAgICBjb25zdCBkZWMgPSBkZWNvcmF0b3JzLnBvcCgpIGFzIERlY29yYXRvck1ldGFkYXRhO1xuICAgIGNvbnN0IGNsYXp6ID0gZGVjLnByb3BzLm5hbWVcbiAgICAgID8gW2RlYy5wcm9wcy5uYW1lXVxuICAgICAgOiBBcnJheS5pc0FycmF5KGRlYy5wcm9wcy5jdXN0b21UeXBlcylcbiAgICAgICAgPyBkZWMucHJvcHMuY3VzdG9tVHlwZXNcbiAgICAgICAgOiBbZGVjLnByb3BzLmN1c3RvbVR5cGVzXTtcbiAgICBjb25zdCByZXNlcnZlZCA9IE9iamVjdC52YWx1ZXMoUmVzZXJ2ZWRNb2RlbHMpLm1hcCgodikgPT5cbiAgICAgIHYudG9Mb3dlckNhc2UoKVxuICAgICkgYXMgc3RyaW5nW107XG5cbiAgICBmb3IgKGNvbnN0IGMgb2YgY2xhenopIHtcbiAgICAgIGlmIChyZXNlcnZlZC5pbmRleE9mKGMudG9Mb3dlckNhc2UoKSkgPT09IC0xKSB7XG4gICAgICAgIGNvbnN0IHR5cGVEZWNvcmF0b3JLZXkgPSBBcnJheS5pc0FycmF5KChvYmogYXMgYW55KVtwcm9wXSlcbiAgICAgICAgICA/IFZhbGlkYXRpb25LZXlzLkxJU1RcbiAgICAgICAgICA6IFZhbGlkYXRpb25LZXlzLlRZUEU7XG4gICAgICAgIGNvbnN0IHR5cGVzOiBhbnkgPVxuICAgICAgICAgIGFsbERlY29yYXRvcnMuZmluZChcbiAgICAgICAgICAgIChkOiB7IGtleTogc3RyaW5nIH0pID0+IGQua2V5ID09PSB0eXBlRGVjb3JhdG9yS2V5XG4gICAgICAgICAgKSB8fCB7fTtcbiAgICAgICAgbGV0IGFsbG93ZWRUeXBlczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgaWYgKHR5cGVzICYmIHR5cGVzLnByb3BzKSB7XG4gICAgICAgICAgY29uc3QgY3VzdG9tVHlwZXMgPSBBcnJheS5pc0FycmF5KChvYmogYXMgYW55KVtwcm9wXSlcbiAgICAgICAgICAgID8gdHlwZXMucHJvcHMuY2xhc3NcbiAgICAgICAgICAgIDogdHlwZXMucHJvcHMuY3VzdG9tVHlwZXM7XG4gICAgICAgICAgaWYgKGN1c3RvbVR5cGVzKVxuICAgICAgICAgICAgYWxsb3dlZFR5cGVzID0gQXJyYXkuaXNBcnJheShjdXN0b21UeXBlcylcbiAgICAgICAgICAgICAgPyBjdXN0b21UeXBlcy5tYXAoKHQpID0+IGAke3R9YC50b0xvd2VyQ2FzZSgpKVxuICAgICAgICAgICAgICA6IFtjdXN0b21UeXBlcy50b0xvd2VyQ2FzZSgpXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHZhbGlkYXRlID0gKHByb3A6IHN0cmluZywgdmFsdWU6IGFueSk6IGFueSA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIilcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHZhbHVlICYmICF2YWx1ZVtWQUxJREFUSU9OX1BBUkVOVF9LRVldKVxuICAgICAgICAgICAgICB2YWx1ZVtWQUxJREFUSU9OX1BBUkVOVF9LRVldID0gb2JqOyAvLyBUT0RPOiBmcmVlemU/XG5cbiAgICAgICAgICAgIHJldHVybiBNb2RlbC5pc01vZGVsKHZhbHVlKVxuICAgICAgICAgICAgICA/IHZhbHVlLmhhc0Vycm9ycygpXG4gICAgICAgICAgICAgIDogYWxsb3dlZFR5cGVzLmluY2x1ZGVzKHR5cGVvZiB2YWx1ZSlcbiAgICAgICAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIDogXCJWYWx1ZSBoYXMgbm8gdmFsaWRhdGFibGUgdHlwZVwiO1xuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICBpZiAodmFsdWUgJiYgdmFsdWVbVkFMSURBVElPTl9QQVJFTlRfS0VZXSlcbiAgICAgICAgICAgICAgZGVsZXRlIHZhbHVlW1ZBTElEQVRJT05fUEFSRU5UX0tFWV07XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHN3aXRjaCAoYykge1xuICAgICAgICAgIGNhc2UgQXJyYXkubmFtZTpcbiAgICAgICAgICBjYXNlIFNldC5uYW1lOlxuICAgICAgICAgICAgaWYgKGFsbERlY29yYXRvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGxpc3REZWMgPSBhbGxEZWNvcmF0b3JzLmZpbmQoXG4gICAgICAgICAgICAgICAgKGQ6IHsga2V5OiBzdHJpbmcgfSkgPT4gZC5rZXkgPT09IFZhbGlkYXRpb25LZXlzLkxJU1RcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgaWYgKGxpc3REZWMpIHtcbiAgICAgICAgICAgICAgICBlcnIgPSAoXG4gICAgICAgICAgICAgICAgICBjID09PSBBcnJheS5uYW1lXG4gICAgICAgICAgICAgICAgICAgID8gKG9iaiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXVxuICAgICAgICAgICAgICAgICAgICA6IC8vIElmIGl0J3MgYSBTZXRcbiAgICAgICAgICAgICAgICAgICAgICAob2JqIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdLnZhbHVlcygpXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgLm1hcCgodjogVmFsaWRhdGFibGUpID0+IHZhbGlkYXRlKHByb3AsIHYpKVxuICAgICAgICAgICAgICAgICAgLmZpbHRlcigoZTogYW55KSA9PiAhIWUpIGFzIGFueTtcbiAgICAgICAgICAgICAgICBpZiAoIWVycj8ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAvLyBpZiB0aGUgcmVzdWx0IGlzIGFuIGVtcHR5IGxpc3QuLi5cbiAgICAgICAgICAgICAgICAgIGVyciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBpZiAoKG9iaiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXSlcbiAgICAgICAgICAgICAgICBlcnIgPSB2YWxpZGF0ZShwcm9wLCAob2JqIGFzIGFueSlbcHJvcF0pO1xuICAgICAgICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYE1vZGVsIHNob3VsZCBiZSB2YWxpZGF0YWJsZSBidXQgaXRzIG5vdDogJHtlfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdCB8fCB7fTtcbiAgICAgICAgcmVzdWx0W3Byb3BdID0gZXJyIGFzIGFueTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0ID8gbmV3IE1vZGVsRXJyb3JEZWZpbml0aW9uKHJlc3VsdCkgOiB1bmRlZmluZWQ7XG59XG4iLCJpbXBvcnQgeyBNb2RlbEtleXMgfSBmcm9tIFwiLi4vdXRpbHMvY29uc3RhbnRzXCI7XG5pbXBvcnQgdHlwZSB7IE1vZGVsIH0gZnJvbSBcIi4vTW9kZWxcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1vZGVsS2V5KHN0cjogc3RyaW5nKSB7XG4gIHJldHVybiBNb2RlbEtleXMuUkVGTEVDVCArIHN0cjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1ldGFkYXRhPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0pIHtcbiAgY29uc3QgbWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgIGdldE1vZGVsS2V5KE1vZGVsS2V5cy5NT0RFTCksXG4gICAgbW9kZWwuY29uc3RydWN0b3JcbiAgKTtcbiAgaWYgKCFtZXRhZGF0YSlcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBcImNvdWxkIG5vdCBmaW5kIG1ldGFkYXRhIGZvciBwcm92aWRlZCBcIiArIG1vZGVsLmNvbnN0cnVjdG9yLm5hbWVcbiAgICApO1xuICByZXR1cm4gbWV0YWRhdGE7XG59XG4iLCJpbXBvcnQgeyBTZXJpYWxpemF0aW9uIH0gZnJvbSBcIi4uL3V0aWxzL3NlcmlhbGl6YXRpb25cIjtcbmltcG9ydCB7IEJ1aWxkZXJSZWdpc3RyeSB9IGZyb20gXCIuLi91dGlscy9yZWdpc3RyeVwiO1xuaW1wb3J0IHsgTW9kZWxFcnJvckRlZmluaXRpb24gfSBmcm9tIFwiLi9Nb2RlbEVycm9yRGVmaW5pdGlvblwiO1xuaW1wb3J0IHtcbiAgQ29tcGFyYWJsZSxcbiAgQ29uc3RydWN0b3IsXG4gIEhhc2hhYmxlLFxuICBNb2RlbEFyZyxcbiAgTW9kZWxCdWlsZGVyRnVuY3Rpb24sXG4gIE1vZGVsQ29uc3RydWN0b3IsXG4gIFNlcmlhbGl6YWJsZSxcbiAgVmFsaWRhdGFibGUsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBEZWNvcmF0b3JNZXRhZGF0YSwgaXNFcXVhbCwgUmVmbGVjdGlvbiB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgdmFsaWRhdGUgfSBmcm9tIFwiLi92YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBIYXNoaW5nIH0gZnJvbSBcIi4uL3V0aWxzL2hhc2hpbmdcIjtcbmltcG9ydCB7IE1vZGVsS2V5cyB9IGZyb20gXCIuLi91dGlscy9jb25zdGFudHNcIjtcbmltcG9ydCB7IFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4uL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9jb25zdGFudHNcIjtcbmltcG9ydCB7IGpzVHlwZXMsIFJlc2VydmVkTW9kZWxzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBnZXRNb2RlbEtleSwgZ2V0TWV0YWRhdGEgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5sZXQgbW9kZWxCdWlsZGVyRnVuY3Rpb246IE1vZGVsQnVpbGRlckZ1bmN0aW9uIHwgdW5kZWZpbmVkO1xubGV0IGFjdGluZ01vZGVsUmVnaXN0cnk6IEJ1aWxkZXJSZWdpc3RyeTxhbnk+O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZWdpc3RyeSB0eXBlIGZvciBzdG9yaW5nIGFuZCByZXRyaWV2aW5nIG1vZGVsIGNvbnN0cnVjdG9yc1xuICogQHN1bW1hcnkgVGhlIE1vZGVsUmVnaXN0cnkgdHlwZSBkZWZpbmVzIGEgcmVnaXN0cnkgZm9yIG1vZGVsIGNvbnN0cnVjdG9ycyB0aGF0IGV4dGVuZHNcbiAqIHRoZSBCdWlsZGVyUmVnaXN0cnkgaW50ZXJmYWNlLiBJdCBwcm92aWRlcyBhIHN0YW5kYXJkaXplZCB3YXkgdG8gcmVnaXN0ZXIsIHJldHJpZXZlLFxuICogYW5kIGJ1aWxkIG1vZGVsIGluc3RhbmNlcywgZW5hYmxpbmcgdGhlIG1vZGVsIHN5c3RlbSB0byB3b3JrIHdpdGggZGlmZmVyZW50IHR5cGVzIG9mIG1vZGVscy5cbiAqXG4gKiBAaW50ZXJmYWNlIE1vZGVsUmVnaXN0cnlcbiAqIEB0ZW1wbGF0ZSBUIFR5cGUgb2YgbW9kZWwgdGhhdCBjYW4gYmUgcmVnaXN0ZXJlZCwgbXVzdCBleHRlbmQgTW9kZWxcbiAqIEBleHRlbmRzIEJ1aWxkZXJSZWdpc3RyeTxUPlxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICogQGNhdGVnb3J5IE1vZGVsXG4gKi9cbmV4cG9ydCB0eXBlIE1vZGVsUmVnaXN0cnk8VCBleHRlbmRzIE1vZGVsPiA9IEJ1aWxkZXJSZWdpc3RyeTxUPjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmVnaXN0cnkgbWFuYWdlciBmb3IgbW9kZWwgY29uc3RydWN0b3JzIHRoYXQgZW5hYmxlcyBzZXJpYWxpemF0aW9uIGFuZCByZWJ1aWxkaW5nXG4gKiBAc3VtbWFyeSBUaGUgTW9kZWxSZWdpc3RyeU1hbmFnZXIgaW1wbGVtZW50cyB0aGUgTW9kZWxSZWdpc3RyeSBpbnRlcmZhY2UgYW5kIHByb3ZpZGVzXG4gKiBmdW5jdGlvbmFsaXR5IGZvciByZWdpc3RlcmluZywgcmV0cmlldmluZywgYW5kIGJ1aWxkaW5nIG1vZGVsIGluc3RhbmNlcy4gSXQgbWFpbnRhaW5zXG4gKiBhIGNhY2hlIG9mIG1vZGVsIGNvbnN0cnVjdG9ycyBpbmRleGVkIGJ5IG5hbWUsIGFsbG93aW5nIGZvciBlZmZpY2llbnQgbG9va3VwIGFuZCBpbnN0YW50aWF0aW9uLlxuICogVGhpcyBjbGFzcyBpcyBlc3NlbnRpYWwgZm9yIHRoZSBzZXJpYWxpemF0aW9uIGFuZCBkZXNlcmlhbGl6YXRpb24gb2YgbW9kZWwgb2JqZWN0cy5cbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFJlY29yZDxzdHJpbmcsIGFueT4pOiBib29sZWFufSBbdGVzdEZ1bmN0aW9uXSAtIEZ1bmN0aW9uIHRvIHRlc3QgaWYgYW4gb2JqZWN0IGlzIGEgbW9kZWwsIGRlZmF1bHRzIHRvIHtAbGluayBNb2RlbCNpc01vZGVsfVxuICpcbiAqIEBjbGFzcyBNb2RlbFJlZ2lzdHJ5TWFuYWdlclxuICogQHRlbXBsYXRlIE0gVHlwZSBvZiBtb2RlbCB0aGF0IGNhbiBiZSByZWdpc3RlcmVkLCBtdXN0IGV4dGVuZCBNb2RlbFxuICogQGltcGxlbWVudHMgTW9kZWxSZWdpc3RyeTxNPlxuICogQGNhdGVnb3J5IE1vZGVsXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIENyZWF0ZSBhIG1vZGVsIHJlZ2lzdHJ5XG4gKiBjb25zdCByZWdpc3RyeSA9IG5ldyBNb2RlbFJlZ2lzdHJ5TWFuYWdlcigpO1xuICpcbiAqIC8vIFJlZ2lzdGVyIGEgbW9kZWwgY2xhc3NcbiAqIHJlZ2lzdHJ5LnJlZ2lzdGVyKFVzZXIpO1xuICpcbiAqIC8vIFJldHJpZXZlIGEgbW9kZWwgY29uc3RydWN0b3IgYnkgbmFtZVxuICogY29uc3QgVXNlckNsYXNzID0gcmVnaXN0cnkuZ2V0KFwiVXNlclwiKTtcbiAqXG4gKiAvLyBCdWlsZCBhIG1vZGVsIGluc3RhbmNlIGZyb20gYSBwbGFpbiBvYmplY3RcbiAqIGNvbnN0IHVzZXJEYXRhID0geyBuYW1lOiBcIkpvaG5cIiwgYWdlOiAzMCB9O1xuICogY29uc3QgdXNlciA9IHJlZ2lzdHJ5LmJ1aWxkKHVzZXJEYXRhLCBcIlVzZXJcIik7XG4gKiBgYGBcbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IFIgYXMgTW9kZWxSZWdpc3RyeU1hbmFnZXJcbiAqICAgcGFydGljaXBhbnQgTSBhcyBNb2RlbCBDbGFzc1xuICpcbiAqICAgQy0+PlI6IG5ldyBNb2RlbFJlZ2lzdHJ5TWFuYWdlcih0ZXN0RnVuY3Rpb24pXG4gKiAgIEMtPj5SOiByZWdpc3RlcihNb2RlbENsYXNzKVxuICogICBSLT4+UjogU3RvcmUgaW4gY2FjaGVcbiAqICAgQy0+PlI6IGdldChcIk1vZGVsTmFtZVwiKVxuICogICBSLS0+PkM6IE1vZGVsQ2xhc3MgY29uc3RydWN0b3JcbiAqICAgQy0+PlI6IGJ1aWxkKGRhdGEsIFwiTW9kZWxOYW1lXCIpXG4gKiAgIFItPj5SOiBHZXQgY29uc3RydWN0b3IgZnJvbSBjYWNoZVxuICogICBSLT4+TTogbmV3IE1vZGVsQ2xhc3MoZGF0YSlcbiAqICAgTS0tPj5SOiBNb2RlbCBpbnN0YW5jZVxuICogICBSLS0+PkM6IE1vZGVsIGluc3RhbmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBNb2RlbFJlZ2lzdHJ5TWFuYWdlcjxNIGV4dGVuZHMgTW9kZWw+IGltcGxlbWVudHMgTW9kZWxSZWdpc3RyeTxNPiB7XG4gIHByaXZhdGUgY2FjaGU6IFJlY29yZDxzdHJpbmcsIE1vZGVsQ29uc3RydWN0b3I8TT4+ID0ge307XG4gIHByaXZhdGUgcmVhZG9ubHkgdGVzdEZ1bmN0aW9uOiAob2JqOiBvYmplY3QpID0+IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgdGVzdEZ1bmN0aW9uOiAob2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiBib29sZWFuID0gTW9kZWwuaXNNb2RlbFxuICApIHtcbiAgICB0aGlzLnRlc3RGdW5jdGlvbiA9IHRlc3RGdW5jdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVnaXN0ZXJzIGEgbW9kZWwgY29uc3RydWN0b3Igd2l0aCB0aGUgcmVnaXN0cnlcbiAgICogQHN1bW1hcnkgQWRkcyBhIG1vZGVsIGNvbnN0cnVjdG9yIHRvIHRoZSByZWdpc3RyeSBjYWNoZSwgbWFraW5nIGl0IGF2YWlsYWJsZSBmb3JcbiAgICogbGF0ZXIgcmV0cmlldmFsIGFuZCBpbnN0YW50aWF0aW9uLiBJZiBubyBuYW1lIGlzIHByb3ZpZGVkLCB0aGUgY29uc3RydWN0b3IncyBuYW1lXG4gICAqIHByb3BlcnR5IGlzIHVzZWQgYXMgdGhlIGtleSBpbiB0aGUgcmVnaXN0cnkuXG4gICAqXG4gICAqIEBwYXJhbSB7TW9kZWxDb25zdHJ1Y3RvcjxNPn0gY29uc3RydWN0b3IgLSBUaGUgbW9kZWwgY29uc3RydWN0b3IgdG8gcmVnaXN0ZXJcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtuYW1lXSAtIE9wdGlvbmFsIG5hbWUgdG8gcmVnaXN0ZXIgdGhlIGNvbnN0cnVjdG9yIHVuZGVyLCBkZWZhdWx0cyB0byBjb25zdHJ1Y3Rvci5uYW1lXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgY29uc3RydWN0b3IgaXMgbm90IGEgZnVuY3Rpb25cbiAgICovXG4gIHJlZ2lzdGVyKGNvbnN0cnVjdG9yOiBNb2RlbENvbnN0cnVjdG9yPE0+LCBuYW1lPzogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHR5cGVvZiBjb25zdHJ1Y3RvciAhPT0gXCJmdW5jdGlvblwiKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcIk1vZGVsIHJlZ2lzdGVyaW5nIGZhaWxlZC4gTWlzc2luZyBDbGFzcyBuYW1lIG9yIGNvbnN0cnVjdG9yXCJcbiAgICAgICk7XG4gICAgbmFtZSA9IG5hbWUgfHwgY29uc3RydWN0b3IubmFtZTtcbiAgICB0aGlzLmNhY2hlW25hbWVdID0gY29uc3RydWN0b3I7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgR2V0cyBhIHJlZ2lzdGVyZWQgTW9kZWwge0BsaW5rIE1vZGVsQ29uc3RydWN0b3J9XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAqL1xuICBnZXQobmFtZTogc3RyaW5nKTogTW9kZWxDb25zdHJ1Y3RvcjxNPiB8IHVuZGVmaW5lZCB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlW25hbWVdO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBvYmpcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtjbGF6el0gd2hlbiBwcm92aWRlZCwgaXQgd2lsbCBhdHRlbXB0IHRvIGZpbmQgdGhlIG1hdGNoaW5nIGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEB0aHJvd3MgRXJyb3IgSWYgY2xhenogaXMgbm90IGZvdW5kLCBvciBvYmogaXMgbm90IGEge0BsaW5rIE1vZGVsfSBtZWFuaW5nIGl0IGhhcyBubyB7QGxpbmsgTW9kZWxLZXlzLkFOQ0hPUn0gcHJvcGVydHlcbiAgICovXG4gIGJ1aWxkKG9iajogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9LCBjbGF6ej86IHN0cmluZyk6IE0ge1xuICAgIGlmICghY2xhenogJiYgIXRoaXMudGVzdEZ1bmN0aW9uKG9iaikpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJQcm92aWRlZCBvYmogaXMgbm90IGEgTW9kZWwgb2JqZWN0XCIpO1xuICAgIGNvbnN0IG5hbWUgPSBjbGF6eiB8fCBNb2RlbC5nZXRNZXRhZGF0YShvYmogYXMgYW55KTtcbiAgICBpZiAoIShuYW1lIGluIHRoaXMuY2FjaGUpKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgUHJvdmlkZWQgY2xhc3MgJHtuYW1lfSBpcyBub3QgYSByZWdpc3RlcmVkIE1vZGVsIG9iamVjdGBcbiAgICAgICk7XG4gICAgcmV0dXJuIG5ldyB0aGlzLmNhY2hlW25hbWVdKG9iaik7XG4gIH1cbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBCdWxrIFJlZ2lzdGVycyBNb2RlbHNcbiAqIEBkZXNjcmlwdGlvbiBVc2VmdWwgd2hlbiB1c2luZyBidW5kbGVycyB0aGF0IG1pZ2h0IG5vdCBldmFsdWF0ZSBhbGwgdGhlIGNvZGUgYXQgb25jZVxuICpcbiAqIEB0ZW1wbGF0ZSBNIGV4dGVuZHMgTW9kZWxcbiAqIEBwYXJhbSB7QXJyYXk8Q29uc3RydWN0b3I8TT4+IHwgQXJyYXk8e25hbWU6IHN0cmluZywgY29uc3RydWN0b3I6IENvbnN0cnVjdG9yPE0+fT59IFttb2RlbHNdXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvblxuICogQGNhdGVnb3J5IE1vZGVsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWxrTW9kZWxSZWdpc3RlcjxNIGV4dGVuZHMgTW9kZWw+KFxuICAuLi5tb2RlbHM6IChDb25zdHJ1Y3RvcjxNPiB8IHsgbmFtZTogc3RyaW5nOyBjb25zdHJ1Y3RvcjogQ29uc3RydWN0b3I8TT4gfSlbXVxuKSB7XG4gIG1vZGVscy5mb3JFYWNoKFxuICAgIChtOiBDb25zdHJ1Y3RvcjxNPiB8IHsgbmFtZTogc3RyaW5nOyBjb25zdHJ1Y3RvcjogQ29uc3RydWN0b3I8TT4gfSkgPT4ge1xuICAgICAgY29uc3QgY29uc3RydWN0b3I6IENvbnN0cnVjdG9yPE0+ID0gKFxuICAgICAgICBtLmNvbnN0cnVjdG9yID8gbS5jb25zdHJ1Y3RvciA6IG1cbiAgICAgICkgYXMgQ29uc3RydWN0b3I8TT47XG4gICAgICBNb2RlbC5yZWdpc3Rlcihjb25zdHJ1Y3RvciwgKG0gYXMgQ29uc3RydWN0b3I8TT4pLm5hbWUpO1xuICAgIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBBYnN0cmFjdCBjbGFzcyByZXByZXNlbnRpbmcgYSBWYWxpZGF0YWJsZSBNb2RlbCBvYmplY3RcbiAqIEBkZXNjcmlwdGlvbiBNZWFudCB0byBiZSB1c2VkIGFzIGEgYmFzZSBjbGFzcyBmb3IgYWxsIE1vZGVsIGNsYXNzZXNcbiAqXG4gKiBNb2RlbCBvYmplY3RzIG11c3Q6XG4gKiAgLSBIYXZlIGFsbCB0aGVpciByZXF1aXJlZCBwcm9wZXJ0aWVzIG1hcmtlZCB3aXRoICchJztcbiAqICAtIEhhdmUgYWxsIHRoZWlyIG9wdGlvbmFsIHByb3BlcnRpZXMgbWFya2VkIGFzICc/JzpcbiAqXG4gKiBAcGFyYW0ge01vZGVsQXJnPE1vZGVsPn0gbW9kZWwgYmFzZSBvYmplY3QgZnJvbSB3aGljaCB0byBwb3B1bGF0ZSBwcm9wZXJ0aWVzIGZyb21cbiAqXG4gKiBAY2xhc3MgTW9kZWxcbiAqIEBjYXRlZ29yeSBNb2RlbFxuICogQGFic3RyYWN0XG4gKiBAaW1wbGVtZW50cyBWYWxpZGF0YWJsZVxuICogQGltcGxlbWVudHMgU2VyaWFsaXphYmxlXG4gKlxuICogQGV4YW1wbGVcbiAqICAgICAgY2xhc3MgQ2xhc3NOYW1lIHtcbiAqICAgICAgICAgIEByZXF1aXJlZCgpXG4gKiAgICAgICAgICByZXF1aXJlZFByb3BlcnR5TmFtZSE6IFByb3BlcnR5VHlwZTtcbiAqXG4gKiAgICAgICAgICBvcHRpb25hbFByb3BlcnR5TmFtZT86IFByb3BlcnR5VHlwZTtcbiAqICAgICAgfVxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgTW9kZWxcbiAgaW1wbGVtZW50cyBWYWxpZGF0YWJsZSwgU2VyaWFsaXphYmxlLCBIYXNoYWJsZSwgQ29tcGFyYWJsZTxNb2RlbD5cbntcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoYXJnPzogTW9kZWxBcmc8TW9kZWw+KSB7fVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgdGhlIG9iamVjdCBhY2NvcmRpbmcgdG8gaXRzIGRlY29yYXRlZCBwcm9wZXJ0aWVzXG4gICAqXG4gICAqIEBwYXJhbSB7YW55W119IFtleGNlcHRpb25zXSBwcm9wZXJ0aWVzIGluIHRoZSBvYmplY3QgdG8gYmUgaWdub3JlZCBmb3IgdGhlIHZhbGlkYXRpb24uIE1hcmtlZCBhcyAnYW55JyB0byBhbGxvdyBmb3IgZXh0ZW5zaW9uIGJ1dCBleHBlY3RzIHN0cmluZ3NcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoLi4uZXhjZXB0aW9uczogYW55W10pOiBNb2RlbEVycm9yRGVmaW5pdGlvbiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHZhbGlkYXRlKHRoaXMsIC4uLmV4Y2VwdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IENvbXBhcmUgb2JqZWN0IGVxdWFsaXR5IHJlY3Vyc2l2ZWx5XG4gICAqIEBwYXJhbSB7YW55fSBvYmogb2JqZWN0IHRvIGNvbXBhcmUgdG9cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtleGNlcHRpb25zXSBwcm9wZXJ0eSBuYW1lcyB0byBiZSBleGNsdWRlZCBmcm9tIHRoZSBjb21wYXJpc29uXG4gICAqL1xuICBwdWJsaWMgZXF1YWxzKG9iajogYW55LCAuLi5leGNlcHRpb25zOiBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc0VxdWFsKHRoaXMsIG9iaiwgLi4uZXhjZXB0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgUmV0dXJucyB0aGUgc2VyaWFsaXplZCBtb2RlbCBhY2NvcmRpbmcgdG8gdGhlIGN1cnJlbnRseSBkZWZpbmVkIHtAbGluayBTZXJpYWxpemVyfVxuICAgKi9cbiAgc2VyaWFsaXplKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIE1vZGVsLnNlcmlhbGl6ZSh0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBPdmVycmlkZSB0aGUgaW1wbGVtZW50YXRpb24gZm9yIGpzJ3MgJ3RvU3RyaW5nKCknIHdoaWNoIHN1Y2tzLi4uXG4gICAqIEBvdmVycmlkZVxuICAgKi9cbiAgcHVibGljIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IubmFtZSArIFwiOiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMsIHVuZGVmaW5lZCwgMik7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgRGVmaW5lcyBhIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIG9iamVjdCBoYXNoLiBSZWxpZXMgb24gYSB2ZXJ5IGJhc2ljIGltcGxlbWVudGF0aW9uIGJhc2VkIG9uIEphdmEncyBzdHJpbmcgaGFzaDtcbiAgICovXG4gIHB1YmxpYyBoYXNoKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIE1vZGVsLmhhc2godGhpcyk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgRGVzZXJpYWxpemVzIGEgTW9kZWxcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0clxuICAgKlxuICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgaXQgZmFpbHMgdG8gcGFyc2UgdGhlIHN0cmluZywgb3IgaWYgaXQgZmFpbHMgdG8gYnVpbGQgdGhlIG1vZGVsXG4gICAqL1xuICBzdGF0aWMgZGVzZXJpYWxpemUoc3RyOiBzdHJpbmcpIHtcbiAgICBjb25zdCBtZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICBNb2RlbC5rZXkoTW9kZWxLZXlzLlNFUklBTElaQVRJT04pLFxuICAgICAgdGhpcy5jb25zdHJ1Y3RvclxuICAgICk7XG5cbiAgICBpZiAobWV0YWRhdGEgJiYgbWV0YWRhdGEuc2VyaWFsaXplcilcbiAgICAgIHJldHVybiBTZXJpYWxpemF0aW9uLmRlc2VyaWFsaXplKFxuICAgICAgICBzdHIsXG4gICAgICAgIG1ldGFkYXRhLnNlcmlhbGl6ZXIsXG4gICAgICAgIC4uLihtZXRhZGF0YS5hcmdzIHx8IFtdKVxuICAgICAgKTtcbiAgICByZXR1cm4gU2VyaWFsaXphdGlvbi5kZXNlcmlhbGl6ZShzdHIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJlcG9wdWxhdGVzIHRoZSBPYmplY3QgcHJvcGVydGllcyB3aXRoIHRoZSBvbmVzIGZyb20gdGhlIG5ldyBvYmplY3RcbiAgICogQGRlc2NyaXB0aW9uIEl0ZXJhdGVzIGFsbCBjb21tb24gcHJvcGVydGllcyBvZiBvYmogKGlmIGV4aXN0aW5nKSBhbmQgc2VsZiwgYW5kIGNvcGllcyB0aGVtIG9udG8gc2VsZlxuICAgKlxuICAgKiBAcGFyYW0ge1R9IHNlbGZcbiAgICogQHBhcmFtIHtUIHwgUmVjb3JkPHN0cmluZywgYW55Pn0gW29ial1cbiAgICpcbiAgICovXG4gIHN0YXRpYyBmcm9tT2JqZWN0PFQgZXh0ZW5kcyBNb2RlbD4oXG4gICAgc2VsZjogVCxcbiAgICBvYmo/OiBUIHwgUmVjb3JkPHN0cmluZywgYW55PlxuICApOiBUIHtcbiAgICBpZiAoIW9iaikgb2JqID0ge307XG4gICAgZm9yIChjb25zdCBwcm9wIG9mIE1vZGVsLmdldEF0dHJpYnV0ZXMoc2VsZikpIHtcbiAgICAgIChzZWxmIGFzIGFueSlbcHJvcF0gPSAob2JqIGFzIGFueSlbcHJvcF0gfHwgdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gc2VsZjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZXBvcHVsYXRlcyB0aGUgaW5zdGFuY2Ugd2l0aCB0aGUgb25lcyBmcm9tIHRoZSBuZXcgTW9kZWwgT2JqZWN0XG4gICAqIEBkZXNjcmlwdGlvbiBJdGVyYXRlcyBhbGwgY29tbW9uIHByb3BlcnRpZXMgb2Ygb2JqIChpZiBleGlzdGluZykgYW5kIHNlbGYsIGFuZCBjb3BpZXMgdGhlbSBvbnRvIHNlbGYuXG4gICAqIElzIGF3YXJlIG9mIG5lc3RlZCBNb2RlbCBPYmplY3RzIGFuZCByZWJ1aWxkcyB0aGVtIGFsc28uXG4gICAqIFdoZW4gTGlzdCBwcm9wZXJ0aWVzIGFyZSBkZWNvcmF0ZWQgd2l0aCB7QGxpbmsgbGlzdH0sIHRoZXkgbGlzdCBpdGVtcyB3aWxsIGFsc28gYmUgcmVidWlsdFxuICAgKlxuICAgKiBAcGFyYW0ge1R9IHNlbGZcbiAgICogQHBhcmFtIHtUIHwgUmVjb3JkPHN0cmluZywgYW55Pn0gW29ial1cbiAgICpcbiAgICovXG4gIHN0YXRpYyBmcm9tTW9kZWw8VCBleHRlbmRzIE1vZGVsPihzZWxmOiBULCBvYmo/OiBUIHwgUmVjb3JkPHN0cmluZywgYW55Pik6IFQge1xuICAgIGlmICghb2JqKSBvYmogPSB7fTtcblxuICAgIGxldCBkZWNvcmF0b3JzOiBEZWNvcmF0b3JNZXRhZGF0YVtdLCBkZWM6IERlY29yYXRvck1ldGFkYXRhO1xuXG4gICAgY29uc3QgcHJvcHMgPSBNb2RlbC5nZXRBdHRyaWJ1dGVzKHNlbGYpO1xuXG4gICAgZm9yIChjb25zdCBwcm9wIG9mIHByb3BzKSB7XG4gICAgICAoc2VsZiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXSA9XG4gICAgICAgIChvYmogYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0gPz8gdW5kZWZpbmVkO1xuICAgICAgaWYgKHR5cGVvZiAoc2VsZiBhcyBhbnkpW3Byb3BdICE9PSBcIm9iamVjdFwiKSBjb250aW51ZTtcbiAgICAgIGNvbnN0IHByb3BNID0gTW9kZWwuaXNQcm9wZXJ0eU1vZGVsKHNlbGYsIHByb3ApO1xuICAgICAgaWYgKHByb3BNKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgKHNlbGYgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0gPSBNb2RlbC5idWlsZChcbiAgICAgICAgICAgIChzZWxmIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdLFxuICAgICAgICAgICAgdHlwZW9mIHByb3BNID09PSBcInN0cmluZ1wiID8gcHJvcE0gOiB1bmRlZmluZWRcbiAgICAgICAgICApO1xuICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYWxsRGVjb3JhdG9yczogRGVjb3JhdG9yTWV0YWRhdGFbXSA9XG4gICAgICAgIFJlZmxlY3Rpb24uZ2V0UHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgICAgIFZhbGlkYXRpb25LZXlzLlJFRkxFQ1QsXG4gICAgICAgICAgc2VsZixcbiAgICAgICAgICBwcm9wXG4gICAgICAgICkuZGVjb3JhdG9ycztcbiAgICAgIGRlY29yYXRvcnMgPSBhbGxEZWNvcmF0b3JzLmZpbHRlcihcbiAgICAgICAgKGQ6IERlY29yYXRvck1ldGFkYXRhKSA9PlxuICAgICAgICAgIFtNb2RlbEtleXMuVFlQRSwgVmFsaWRhdGlvbktleXMuVFlQRSBhcyBzdHJpbmddLmluZGV4T2YoZC5rZXkpICE9PSAtMVxuICAgICAgKTtcbiAgICAgIGlmICghZGVjb3JhdG9ycyB8fCAhZGVjb3JhdG9ycy5sZW5ndGgpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZmFpbGVkIHRvIGZpbmQgZGVjb3JhdG9ycyBmb3IgcHJvcGVydHkgJHtwcm9wfWApO1xuICAgICAgZGVjID0gZGVjb3JhdG9ycy5wb3AoKSBhcyBEZWNvcmF0b3JNZXRhZGF0YTtcbiAgICAgIGNvbnN0IGNsYXp6ID0gZGVjLnByb3BzLm5hbWVcbiAgICAgICAgPyBbZGVjLnByb3BzLm5hbWVdXG4gICAgICAgIDogQXJyYXkuaXNBcnJheShkZWMucHJvcHMuY3VzdG9tVHlwZXMpXG4gICAgICAgICAgPyBkZWMucHJvcHMuY3VzdG9tVHlwZXNcbiAgICAgICAgICA6IFtkZWMucHJvcHMuY3VzdG9tVHlwZXNdO1xuICAgICAgY29uc3QgcmVzZXJ2ZWQgPSBPYmplY3QudmFsdWVzKFJlc2VydmVkTW9kZWxzKS5tYXAoKHYpID0+XG4gICAgICAgIHYudG9Mb3dlckNhc2UoKVxuICAgICAgKSBhcyBzdHJpbmdbXTtcblxuICAgICAgY2xhenouZm9yRWFjaCgoYykgPT4ge1xuICAgICAgICBpZiAocmVzZXJ2ZWQuaW5kZXhPZihjLnRvTG93ZXJDYXNlKCkpID09PSAtMSlcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgc3dpdGNoIChjKSB7XG4gICAgICAgICAgICAgIGNhc2UgXCJBcnJheVwiOlxuICAgICAgICAgICAgICBjYXNlIFwiU2V0XCI6XG4gICAgICAgICAgICAgICAgaWYgKGFsbERlY29yYXRvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBsaXN0RGVjID0gYWxsRGVjb3JhdG9ycy5maW5kKFxuICAgICAgICAgICAgICAgICAgICAoZCkgPT4gZC5rZXkgPT09IFZhbGlkYXRpb25LZXlzLkxJU1RcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICBpZiAobGlzdERlYykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjbGF6ek5hbWUgPSAobGlzdERlYy5wcm9wcy5jbGF6eiBhcyBzdHJpbmdbXSkuZmluZChcbiAgICAgICAgICAgICAgICAgICAgICAodDogc3RyaW5nKSA9PiAhanNUeXBlcy5pbmNsdWRlcyh0LnRvTG93ZXJDYXNlKCkpXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjID09PSBcIkFycmF5XCIpXG4gICAgICAgICAgICAgICAgICAgICAgKHNlbGYgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0gPSAoXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmIGFzIFJlY29yZDxzdHJpbmcsIGFueT5cbiAgICAgICAgICAgICAgICAgICAgICApW3Byb3BdLm1hcCgoZWw6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtcIm9iamVjdFwiLCBcImZ1bmN0aW9uXCJdLmluY2x1ZGVzKHR5cGVvZiBlbCkgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhenpOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgID8gTW9kZWwuYnVpbGQoZWwsIGNsYXp6TmFtZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgOiBlbDtcbiAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT09IFwiU2V0XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzID0gbmV3IFNldCgpO1xuICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdiBvZiAoc2VsZiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICBbXCJvYmplY3RcIiwgXCJmdW5jdGlvblwiXS5pbmNsdWRlcyh0eXBlb2YgdikgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhenpOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcy5hZGQoTW9kZWwuYnVpbGQodiwgY2xhenpOYW1lKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBzLmFkZCh2KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgKHNlbGYgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0gPSBzO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGlmICgoc2VsZiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXSlcbiAgICAgICAgICAgICAgICAgIChzZWxmIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdID0gTW9kZWwuYnVpbGQoXG4gICAgICAgICAgICAgICAgICAgIChzZWxmIGFzIGFueSlbcHJvcF0sXG4gICAgICAgICAgICAgICAgICAgIGNcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcuIHdlIGhhdmUgbm8gcmVnaXN0cnkgb2YgdGhpcyBjbGFzc1xuICAgICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gc2VsZjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBTZXRzIHRoZSBHbG9iYWwge0BsaW5rIE1vZGVsQnVpbGRlckZ1bmN0aW9ufVxuICAgKiBAcGFyYW0ge01vZGVsQnVpbGRlckZ1bmN0aW9ufSBbYnVpbGRlcl1cbiAgICovXG4gIHN0YXRpYyBzZXRCdWlsZGVyKGJ1aWxkZXI/OiBNb2RlbEJ1aWxkZXJGdW5jdGlvbikge1xuICAgIG1vZGVsQnVpbGRlckZ1bmN0aW9uID0gYnVpbGRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgdGhlIGN1cnJlbnQgZ2xvYmFsIHtAbGluayBNb2RlbEJ1aWxkZXJGdW5jdGlvbn1cbiAgICovXG4gIHN0YXRpYyBnZXRCdWlsZGVyKCk6IE1vZGVsQnVpbGRlckZ1bmN0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gbW9kZWxCdWlsZGVyRnVuY3Rpb247XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY3VycmVudCB7QGxpbmsgTW9kZWxSZWdpc3RyeU1hbmFnZXJ9XG4gICAqXG4gICAqIEByZXR1cm4gTW9kZWxSZWdpc3RyeSwgZGVmYXVsdHMgdG8ge0BsaW5rIE1vZGVsUmVnaXN0cnlNYW5hZ2VyfVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0UmVnaXN0cnkoKSB7XG4gICAgaWYgKCFhY3RpbmdNb2RlbFJlZ2lzdHJ5KSBhY3RpbmdNb2RlbFJlZ2lzdHJ5ID0gbmV3IE1vZGVsUmVnaXN0cnlNYW5hZ2VyKCk7XG4gICAgcmV0dXJuIGFjdGluZ01vZGVsUmVnaXN0cnk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY3VycmVudCBhY3RpbmdNb2RlbFJlZ2lzdHJ5XG4gICAqXG4gICAqIEBwYXJhbSB7QnVpbGRlclJlZ2lzdHJ5fSBtb2RlbFJlZ2lzdHJ5IHRoZSBuZXcgaW1wbGVtZW50YXRpb24gb2YgUmVnaXN0cnlcbiAgICovXG4gIHN0YXRpYyBzZXRSZWdpc3RyeShtb2RlbFJlZ2lzdHJ5OiBCdWlsZGVyUmVnaXN0cnk8YW55Pikge1xuICAgIGFjdGluZ01vZGVsUmVnaXN0cnkgPSBtb2RlbFJlZ2lzdHJ5O1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHJlZ2lzdGVyIG5ldyBNb2RlbHNcbiAgICogQHBhcmFtIHthbnl9IGNvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbbmFtZV0gd2hlbiBub3QgZGVmaW5lZCwgdGhlIG5hbWUgb2YgdGhlIGNvbnN0cnVjdG9yIHdpbGwgYmUgdXNlZFxuICAgKlxuICAgKiBAc2VlIE1vZGVsUmVnaXN0cnlcbiAgICovXG4gIHN0YXRpYyByZWdpc3RlcjxUIGV4dGVuZHMgTW9kZWw+KFxuICAgIGNvbnN0cnVjdG9yOiBNb2RlbENvbnN0cnVjdG9yPFQ+LFxuICAgIG5hbWU/OiBzdHJpbmdcbiAgKTogdm9pZCB7XG4gICAgcmV0dXJuIE1vZGVsLmdldFJlZ2lzdHJ5KCkucmVnaXN0ZXIoY29uc3RydWN0b3IsIG5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEdldHMgYSByZWdpc3RlcmVkIE1vZGVsIHtAbGluayBNb2RlbENvbnN0cnVjdG9yfVxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICAgKlxuICAgKiBAc2VlIE1vZGVsUmVnaXN0cnlcbiAgICovXG4gIHN0YXRpYyBnZXQ8VCBleHRlbmRzIE1vZGVsPihuYW1lOiBzdHJpbmcpOiBNb2RlbENvbnN0cnVjdG9yPFQ+IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gTW9kZWwuZ2V0UmVnaXN0cnkoKS5nZXQobmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBvYmpcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtjbGF6el0gd2hlbiBwcm92aWRlZCwgaXQgd2lsbCBhdHRlbXB0IHRvIGZpbmQgdGhlIG1hdGNoaW5nIGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEB0aHJvd3MgRXJyb3IgSWYgY2xhenogaXMgbm90IGZvdW5kLCBvciBvYmogaXMgbm90IGEge0BsaW5rIE1vZGVsfSBtZWFuaW5nIGl0IGhhcyBubyB7QGxpbmsgTW9kZWxLZXlzLkFOQ0hPUn0gcHJvcGVydHlcbiAgICpcbiAgICogQHNlZSBNb2RlbFJlZ2lzdHJ5XG4gICAqL1xuICBzdGF0aWMgYnVpbGQ8VCBleHRlbmRzIE1vZGVsPihcbiAgICBvYmo6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fSxcbiAgICBjbGF6ej86IHN0cmluZ1xuICApOiBUIHtcbiAgICByZXR1cm4gTW9kZWwuZ2V0UmVnaXN0cnkoKS5idWlsZChvYmosIGNsYXp6KTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRNZXRhZGF0YTxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNKSB7XG4gICAgcmV0dXJuIGdldE1ldGFkYXRhPE0+KG1vZGVsKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRBdHRyaWJ1dGVzPFYgZXh0ZW5kcyBNb2RlbD4obW9kZWw6IENvbnN0cnVjdG9yPFY+IHwgVikge1xuICAgIGNvbnN0IHJlc3VsdDogc3RyaW5nW10gPSBbXTtcbiAgICBsZXQgcHJvdG90eXBlID1cbiAgICAgIG1vZGVsIGluc3RhbmNlb2YgTW9kZWxcbiAgICAgICAgPyBPYmplY3QuZ2V0UHJvdG90eXBlT2YobW9kZWwpXG4gICAgICAgIDogKG1vZGVsIGFzIGFueSkucHJvdG90eXBlO1xuICAgIHdoaWxlIChwcm90b3R5cGUgIT0gbnVsbCkge1xuICAgICAgY29uc3QgcHJvcHM6IHN0cmluZ1tdID0gcHJvdG90eXBlW01vZGVsS2V5cy5BVFRSSUJVVEVdO1xuICAgICAgaWYgKHByb3BzKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKC4uLnByb3BzKTtcbiAgICAgIH1cbiAgICAgIHByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90b3R5cGUpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgc3RhdGljIGVxdWFsczxNIGV4dGVuZHMgTW9kZWw+KG9iajE6IE0sIG9iajI6IE0sIC4uLmV4Y2VwdGlvbnM6IGFueVtdKSB7XG4gICAgcmV0dXJuIGlzRXF1YWwob2JqMSwgb2JqMiwgLi4uZXhjZXB0aW9ucyk7XG4gIH1cblxuICBzdGF0aWMgaGFzRXJyb3JzPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0sIC4uLnByb3BzVG9JZ25vcmU6IHN0cmluZ1tdKSB7XG4gICAgcmV0dXJuIHZhbGlkYXRlKG1vZGVsLCAuLi5wcm9wc1RvSWdub3JlKTtcbiAgfVxuXG4gIHN0YXRpYyBzZXJpYWxpemU8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogTSkge1xuICAgIGNvbnN0IG1ldGFkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgIE1vZGVsLmtleShNb2RlbEtleXMuU0VSSUFMSVpBVElPTiksXG4gICAgICBtb2RlbC5jb25zdHJ1Y3RvclxuICAgICk7XG5cbiAgICBpZiAobWV0YWRhdGEgJiYgbWV0YWRhdGEuc2VyaWFsaXplcilcbiAgICAgIHJldHVybiBTZXJpYWxpemF0aW9uLnNlcmlhbGl6ZShcbiAgICAgICAgdGhpcyxcbiAgICAgICAgbWV0YWRhdGEuc2VyaWFsaXplcixcbiAgICAgICAgLi4uKG1ldGFkYXRhLmFyZ3MgfHwgW10pXG4gICAgICApO1xuICAgIHJldHVybiBTZXJpYWxpemF0aW9uLnNlcmlhbGl6ZShtb2RlbCk7XG4gIH1cblxuICBzdGF0aWMgaGFzaDxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNKSB7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgTW9kZWwua2V5KE1vZGVsS2V5cy5IQVNISU5HKSxcbiAgICAgIG1vZGVsLmNvbnN0cnVjdG9yXG4gICAgKTtcblxuICAgIGlmIChtZXRhZGF0YSAmJiBtZXRhZGF0YS5hbGdvcml0aG0pXG4gICAgICByZXR1cm4gSGFzaGluZy5oYXNoKG1vZGVsLCBtZXRhZGF0YS5hbGdvcml0aG0sIC4uLihtZXRhZGF0YS5hcmdzIHx8IFtdKSk7XG4gICAgcmV0dXJuIEhhc2hpbmcuaGFzaChtb2RlbCk7XG4gIH1cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEJ1aWxkcyB0aGUga2V5IHRvIHN0b3JlIGFzIE1ldGFkYXRhIHVuZGVyIFJlZmxlY3Rpb25zXG4gICAqIEBkZXNjcmlwdGlvbiBjb25jYXRlbmF0ZXMge0BsaW5rIE1vZGVsS2V5cyNSRUZMRUNUfSB3aXRoIHRoZSBwcm92aWRlZCBrZXlcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0clxuICAgKi9cbiAgc3RhdGljIGtleShzdHI6IHN0cmluZykge1xuICAgIHJldHVybiBnZXRNb2RlbEtleShzdHIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBEZXRlcm1pbmVzIGlmIGFuIG9iamVjdCBpcyBhIG1vZGVsIGluc3RhbmNlIG9yIGhhcyBtb2RlbCBtZXRhZGF0YVxuICAgKiBAc3VtbWFyeSBDaGVja3Mgd2hldGhlciBhIGdpdmVuIG9iamVjdCBpcyBlaXRoZXIgYW4gaW5zdGFuY2Ugb2YgdGhlIE1vZGVsIGNsYXNzIG9yXG4gICAqIGhhcyBtb2RlbCBtZXRhZGF0YSBhdHRhY2hlZCB0byBpdC4gVGhpcyBmdW5jdGlvbiBpcyBlc3NlbnRpYWwgZm9yIHNlcmlhbGl6YXRpb24gYW5kXG4gICAqIGRlc2VyaWFsaXphdGlvbiBwcm9jZXNzZXMsIGFzIGl0IGhlbHBzIGlkZW50aWZ5IG1vZGVsIG9iamVjdHMgdGhhdCBuZWVkIHNwZWNpYWwgaGFuZGxpbmcuXG4gICAqIEl0IHNhZmVseSBoYW5kbGVzIHBvdGVudGlhbCBlcnJvcnMgZHVyaW5nIG1ldGFkYXRhIHJldHJpZXZhbC5cbiAgICpcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSB0YXJnZXQgLSBUaGUgb2JqZWN0IHRvIGNoZWNrXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIG9iamVjdCBpcyBhIG1vZGVsIGluc3RhbmNlIG9yIGhhcyBtb2RlbCBtZXRhZGF0YSwgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogLy8gQ2hlY2sgaWYgYW4gb2JqZWN0IGlzIGEgbW9kZWxcbiAgICogY29uc3QgdXNlciA9IG5ldyBVc2VyKHsgbmFtZTogXCJKb2huXCIgfSk7XG4gICAqIGNvbnN0IGlzVXNlck1vZGVsID0gaXNNb2RlbCh1c2VyKTsgLy8gdHJ1ZVxuICAgKlxuICAgKiAvLyBDaGVjayBhIHBsYWluIG9iamVjdFxuICAgKiBjb25zdCBwbGFpbk9iamVjdCA9IHsgbmFtZTogXCJKb2huXCIgfTtcbiAgICogY29uc3QgaXNQbGFpbk9iamVjdE1vZGVsID0gaXNNb2RlbChwbGFpbk9iamVjdCk7IC8vIGZhbHNlXG4gICAqIGBgYFxuICAgKi9cbiAgc3RhdGljIGlzTW9kZWwodGFyZ2V0OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB0YXJnZXQgaW5zdGFuY2VvZiBNb2RlbCB8fCAhIU1vZGVsLmdldE1ldGFkYXRhKHRhcmdldCBhcyBhbnkpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ2hlY2tzIGlmIGEgcHJvcGVydHkgb2YgYSBtb2RlbCBpcyBpdHNlbGYgYSBtb2RlbCBvciBoYXMgYSBtb2RlbCB0eXBlXG4gICAqIEBzdW1tYXJ5IERldGVybWluZXMgd2hldGhlciBhIHNwZWNpZmljIHByb3BlcnR5IG9mIGEgbW9kZWwgaW5zdGFuY2UgaXMgZWl0aGVyIGEgbW9kZWwgaW5zdGFuY2VcbiAgICogb3IgaGFzIGEgdHlwZSB0aGF0IGlzIHJlZ2lzdGVyZWQgYXMgYSBtb2RlbC4gVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGZvciBtb2RlbCBzZXJpYWxpemF0aW9uXG4gICAqIGFuZCBkZXNlcmlhbGl6YXRpb24gdG8gcHJvcGVybHkgaGFuZGxlIG5lc3RlZCBtb2RlbHMuXG4gICAqIEB0ZW1wbGF0ZSBNIGV4dGVuZHMge0BsaW5rIE1vZGVsfVxuICAgKiBAcGFyYW0ge019IHRhcmdldCAtIFRoZSBtb2RlbCBpbnN0YW5jZSB0byBjaGVja1xuICAgKiBAcGFyYW0ge3N0cmluZ30gYXR0cmlidXRlIC0gVGhlIHByb3BlcnR5IG5hbWUgdG8gY2hlY2tcbiAgICogQHJldHVybiB7Ym9vbGVhbiB8IHN0cmluZyB8IHVuZGVmaW5lZH0gUmV0dXJucyB0cnVlIGlmIHRoZSBwcm9wZXJ0eSBpcyBhIG1vZGVsIGluc3RhbmNlLFxuICAgKiB0aGUgbW9kZWwgbmFtZSBpZiB0aGUgcHJvcGVydHkgaGFzIGEgbW9kZWwgdHlwZSwgb3IgdW5kZWZpbmVkIGlmIG5vdCBhIG1vZGVsXG4gICAqL1xuICBzdGF0aWMgaXNQcm9wZXJ0eU1vZGVsPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgdGFyZ2V0OiBNLFxuICAgIGF0dHJpYnV0ZTogc3RyaW5nXG4gICk6IGJvb2xlYW4gfCBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmIChNb2RlbC5pc01vZGVsKCh0YXJnZXQgYXMgUmVjb3JkPHN0cmluZywgYW55PilbYXR0cmlidXRlXSkpIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShNb2RlbEtleXMuVFlQRSwgdGFyZ2V0LCBhdHRyaWJ1dGUpO1xuICAgIHJldHVybiBNb2RlbC5nZXQobWV0YWRhdGEubmFtZSkgPyBtZXRhZGF0YS5uYW1lIDogdW5kZWZpbmVkO1xuICB9XG59XG4iLCJpbXBvcnQgeyBDb25zdHJ1Y3RvciB9IGZyb20gXCIuLi9tb2RlbC90eXBlc1wiO1xuaW1wb3J0IHsgU2VyaWFsaXplciB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCIuLi9tb2RlbC9Nb2RlbFwiO1xuaW1wb3J0IHsgTW9kZWxLZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBnZXRNZXRhZGF0YSB9IGZyb20gXCIuLi9tb2RlbC91dGlsc1wiO1xuXG5leHBvcnQgY29uc3QgRGVmYXVsdFNlcmlhbGl6YXRpb25NZXRob2QgPSBcImpzb25cIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBDb25jcmV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBhIHtAbGluayBTZXJpYWxpemVyfSBpbiBKU09OIGZvcm1hdFxuICogQGRlc2NyaXB0aW9uIEpTJ3MgbmF0aXZlIEpTT04uc3RyaW5naWZ5ICh1c2VkIGhlcmUpIGlzIG5vdCBkZXRlcm1pbmlzdGljXG4gKiBhbmQgdGhlcmVmb3JlIHNob3VsZCBub3QgYmUgdXNlZCBmb3IgaGFzaGluZyBwdXJwb3Nlc1xuICpcbiAqIFRvIGtlZXAgZGVwZW5kZW5jaWVzIGxvdywgd2Ugd2lsbCBub3QgaW1wbGVtZW50IHRoaXMsIGJ1dCB3ZSByZWNvbW1lbmRcbiAqIGltcGxlbWVudGluZyBhIHNpbWlsYXIge0BsaW5rIEpTT05TZXJpYWxpemVyfSB1c2luZyAnZGV0ZXJtaW5pc3RpYy1qc29uJyBsaWJyYXJpZXNcbiAqXG4gKiBAY2xhc3MgSlNPTlNlcmlhbGl6ZXJcbiAqIEBpbXBsZW1lbnRzIFNlcmlhbGl6ZXJcbiAqXG4gKiBAY2F0ZWdvcnkgTW9kZWxcbiAqL1xuZXhwb3J0IGNsYXNzIEpTT05TZXJpYWxpemVyPFQgZXh0ZW5kcyBNb2RlbD4gaW1wbGVtZW50cyBTZXJpYWxpemVyPFQ+IHtcbiAgY29uc3RydWN0b3IoKSB7fVxuICAvKipcbiAgICogQHN1bW1hcnkgcHJlcGFyZXMgdGhlIG1vZGVsIGZvciBzZXJpYWxpemF0aW9uXG4gICAqIEBkZXNjcmlwdGlvbiByZXR1cm5zIGEgc2hhbGxvdyBjb3B5IG9mIHRoZSBvYmplY3QsIGNvbnRhaW5pbmcgYW4gZW51bWVyYWJsZSB7QGxpbmsgTW9kZWxLZXlzI0FOQ0hPUn0gcHJvcGVydHlcbiAgICogc28gdGhlIG9iamVjdCBjYW4gYmUgcmVjb2duaXplZCB1cG9uIGRlc2VyaWFsaXphdGlvblxuICAgKlxuICAgKiBAcGFyYW0ge1R9IG1vZGVsXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIHByb3RlY3RlZCBwcmVTZXJpYWxpemUobW9kZWw6IFQpIHtcbiAgICAvLyBUT0RPOiBuZXN0ZWQgcHJlc2VyaWFsaXphdGlvbiAoc28gaW5jcmVhc2UgcGVyZm9ybWFuY2Ugd2hlbiBkZXNlcmlhbGl6aW5nKVxuICAgIGNvbnN0IHRvU2VyaWFsaXplOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gT2JqZWN0LmFzc2lnbih7fSwgbW9kZWwpO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gZ2V0TWV0YWRhdGEobW9kZWwpO1xuICAgIHRvU2VyaWFsaXplW01vZGVsS2V5cy5BTkNIT1JdID0gbWV0YWRhdGEgfHwgbW9kZWwuY29uc3RydWN0b3IubmFtZTtcbiAgICByZXR1cm4gdG9TZXJpYWxpemU7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgUmVidWlsZHMgYSBtb2RlbCBmcm9tIGEgc2VyaWFsaXphdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gICAqXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBpdCBmYWlscyB0byBwYXJzZSB0aGUgc3RyaW5nLCBvciB0byBidWlsZCB0aGUgbW9kZWxcbiAgICovXG4gIGRlc2VyaWFsaXplKHN0cjogc3RyaW5nKTogVCB7XG4gICAgY29uc3QgZGVzZXJpYWxpemF0aW9uID0gSlNPTi5wYXJzZShzdHIpO1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGRlc2VyaWFsaXphdGlvbltNb2RlbEtleXMuQU5DSE9SXTtcbiAgICBpZiAoIWNsYXNzTmFtZSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvdWxkIG5vdCBmaW5kIGNsYXNzIHJlZmVyZW5jZSBpbiBzZXJpYWxpemVkIG1vZGVsXCIpO1xuICAgIGNvbnN0IG1vZGVsOiBUID0gTW9kZWwuYnVpbGQoZGVzZXJpYWxpemF0aW9uLCBjbGFzc05hbWUpIGFzIHVua25vd24gYXMgVDtcbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgU2VyaWFsaXplcyBhIG1vZGVsXG4gICAqIEBwYXJhbSB7VH0gbW9kZWxcbiAgICpcbiAgICogQHRocm93cyB7RXJyb3J9IGlmIGZhaWxzIHRvIHNlcmlhbGl6ZVxuICAgKi9cbiAgc2VyaWFsaXplKG1vZGVsOiBUKTogc3RyaW5nIHtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodGhpcy5wcmVTZXJpYWxpemUobW9kZWwpKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgU2VyaWFsaXphdGlvbiB7XG4gIHByaXZhdGUgc3RhdGljIGN1cnJlbnQ6IHN0cmluZyA9IERlZmF1bHRTZXJpYWxpemF0aW9uTWV0aG9kO1xuXG4gIHByaXZhdGUgc3RhdGljIGNhY2hlOiBSZWNvcmQ8c3RyaW5nLCBTZXJpYWxpemVyPGFueT4+ID0ge1xuICAgIGpzb246IG5ldyBKU09OU2VyaWFsaXplcigpLFxuICB9O1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7fVxuXG4gIHByaXZhdGUgc3RhdGljIGdldChrZXk6IHN0cmluZyk6IGFueSB7XG4gICAgaWYgKGtleSBpbiB0aGlzLmNhY2hlKSByZXR1cm4gdGhpcy5jYWNoZVtrZXldO1xuICAgIHRocm93IG5ldyBFcnJvcihgTm8gc2VyaWFsaXphdGlvbiBtZXRob2QgcmVnaXN0ZXJlZCB1bmRlciAke2tleX1gKTtcbiAgfVxuXG4gIHN0YXRpYyByZWdpc3RlcihcbiAgICBrZXk6IHN0cmluZyxcbiAgICBmdW5jOiBDb25zdHJ1Y3RvcjxTZXJpYWxpemVyPGFueT4+LFxuICAgIHNldERlZmF1bHQgPSBmYWxzZVxuICApOiB2b2lkIHtcbiAgICBpZiAoa2V5IGluIHRoaXMuY2FjaGUpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFNlcmlhbGl6YXRpb24gbWV0aG9kICR7a2V5fSBhbHJlYWR5IHJlZ2lzdGVyZWRgKTtcbiAgICB0aGlzLmNhY2hlW2tleV0gPSBuZXcgZnVuYygpO1xuICAgIGlmIChzZXREZWZhdWx0KSB0aGlzLmN1cnJlbnQgPSBrZXk7XG4gIH1cblxuICBzdGF0aWMgc2VyaWFsaXplKG9iajogYW55LCBtZXRob2Q/OiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgaWYgKCFtZXRob2QpIHJldHVybiB0aGlzLmdldCh0aGlzLmN1cnJlbnQpLnNlcmlhbGl6ZShvYmosIC4uLmFyZ3MpO1xuICAgIHJldHVybiB0aGlzLmdldChtZXRob2QpLnNlcmlhbGl6ZShvYmosIC4uLmFyZ3MpO1xuICB9XG5cbiAgc3RhdGljIGRlc2VyaWFsaXplKG9iajogc3RyaW5nLCBtZXRob2Q/OiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgaWYgKCFtZXRob2QpIHJldHVybiB0aGlzLmdldCh0aGlzLmN1cnJlbnQpLmRlc2VyaWFsaXplKG9iaiwgLi4uYXJncyk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KG1ldGhvZCkuZGVzZXJpYWxpemUob2JqLCAuLi5hcmdzKTtcbiAgfVxuXG4gIHN0YXRpYyBzZXREZWZhdWx0KG1ldGhvZDogc3RyaW5nKSB7XG4gICAgdGhpcy5jdXJyZW50ID0gdGhpcy5nZXQobWV0aG9kKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBWYWxpZGF0aW9uIH0gZnJvbSBcIi4uL1ZhbGlkYXRpb25cIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yIH0gZnJvbSBcIi4uLy4uL21vZGVsL3R5cGVzXCI7XG5pbXBvcnQgeyBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgYXBwbHksIG1ldGFkYXRhIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBWYWxpZGF0b3JEZWZpbml0aW9uIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgTWFya3MgdGhlIGNsYXNzIGFzIGEgdmFsaWRhdG9yIGZvciBhIGNlcnRhaW4ga2V5LlxuICogQGRlc2NyaXB0aW9uIFJlZ2lzdGVycyB0aGUgY2xhc3MgaW4gdGhlIHtAbGluayBWYWxpZGF0aW9ufSB3aXRoIHRoZSBwcm92aWRlZCBrZXlcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5cyB0aGUgdmFsaWRhdGlvbiBrZXlcbiAqXG4gKiBAZnVuY3Rpb24gdmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRvcjxUIGV4dGVuZHMgVmFsaWRhdG9yPiguLi5rZXlzOiBzdHJpbmdbXSkge1xuICByZXR1cm4gYXBwbHkoXG4gICAgKChvcmlnaW5hbDogQ29uc3RydWN0b3I8VD4pID0+IHtcbiAgICAgIGtleXMuZm9yRWFjaCgoazogc3RyaW5nKSA9PiB7XG4gICAgICAgIFZhbGlkYXRpb24ucmVnaXN0ZXIoe1xuICAgICAgICAgIHZhbGlkYXRvcjogb3JpZ2luYWwsXG4gICAgICAgICAgdmFsaWRhdGlvbktleTogayxcbiAgICAgICAgICBzYXZlOiB0cnVlLFxuICAgICAgICB9IGFzIFZhbGlkYXRvckRlZmluaXRpb24pO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gb3JpZ2luYWw7XG4gICAgfSkgYXMgQ2xhc3NEZWNvcmF0b3IsXG4gICAgbWV0YWRhdGEoVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuVkFMSURBVE9SKSwga2V5cylcbiAgKTtcbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IERhdGVWYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvciBmb3IgY2hlY2tpbmcgaWYgYSB2YWx1ZSBpcyBhIHZhbGlkIGRhdGVcbiAqIEBzdW1tYXJ5IFRoZSBEYXRlVmFsaWRhdG9yIGNoZWNrcyBpZiBhIHZhbHVlIGlzIGEgdmFsaWQgZGF0ZSBvYmplY3Qgb3IgYSBzdHJpbmcgdGhhdCBjYW4gYmUgY29udmVydGVkIHRvIGEgdmFsaWQgZGF0ZS5cbiAqIEl0IHZhbGlkYXRlcyB0aGF0IHRoZSB2YWx1ZSByZXByZXNlbnRzIGEgcmVhbCBkYXRlIGFuZCBub3QgYW4gaW52YWxpZCBkYXRlIGxpa2UgXCIyMDIzLTAyLTMxXCIuXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIHZhbGlkYXRpb24gZmFpbHMsIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0RBVEV9XG4gKiBAY2xhc3MgRGF0ZVZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBDcmVhdGUgYSBkYXRlIHZhbGlkYXRvciB3aXRoIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogY29uc3QgZGF0ZVZhbGlkYXRvciA9IG5ldyBEYXRlVmFsaWRhdG9yKCk7XG4gKlxuICogLy8gQ3JlYXRlIGEgZGF0ZSB2YWxpZGF0b3Igd2l0aCBjdXN0b20gZXJyb3IgbWVzc2FnZVxuICogY29uc3QgY3VzdG9tRGF0ZVZhbGlkYXRvciA9IG5ldyBEYXRlVmFsaWRhdG9yKFwiUGxlYXNlIGVudGVyIGEgdmFsaWQgZGF0ZVwiKTtcbiAqXG4gKiAvLyBWYWxpZGF0ZSBhIGRhdGVcbiAqIGNvbnN0IHJlc3VsdCA9IGRhdGVWYWxpZGF0b3IuaGFzRXJyb3JzKG5ldyBEYXRlKCkpOyAvLyB1bmRlZmluZWQgKHZhbGlkKVxuICogY29uc3QgaW52YWxpZFJlc3VsdCA9IGRhdGVWYWxpZGF0b3IuaGFzRXJyb3JzKFwibm90IGEgZGF0ZVwiKTsgLy8gUmV0dXJucyBlcnJvciBtZXNzYWdlIChpbnZhbGlkKVxuICogYGBgXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IFYgYXMgRGF0ZVZhbGlkYXRvclxuICpcbiAqICAgQy0+PlY6IG5ldyBEYXRlVmFsaWRhdG9yKG1lc3NhZ2UpXG4gKiAgIEMtPj5WOiBoYXNFcnJvcnModmFsdWUsIG9wdGlvbnMpXG4gKiAgIGFsdCB2YWx1ZSBpcyB1bmRlZmluZWRcbiAqICAgICBWLS0+PkM6IHVuZGVmaW5lZCAodmFsaWQpXG4gKiAgIGVsc2UgdmFsdWUgaXMgc3RyaW5nXG4gKiAgICAgVi0+PlY6IENvbnZlcnQgdG8gRGF0ZVxuICogICBlbmRcbiAqICAgYWx0IERhdGUgaXMgaW52YWxpZCAoTmFOKVxuICogICAgIFYtLT4+QzogRXJyb3IgbWVzc2FnZVxuICogICBlbHNlIERhdGUgaXMgdmFsaWRcbiAqICAgICBWLS0+PkM6IHVuZGVmaW5lZCAodmFsaWQpXG4gKiAgIGVuZFxuICovXG5AdmFsaWRhdG9yKFZhbGlkYXRpb25LZXlzLkRBVEUpXG5leHBvcnQgY2xhc3MgRGF0ZVZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvcjxEYXRlVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkRBVEUpIHtcbiAgICBzdXBlcihtZXNzYWdlLCBOdW1iZXIubmFtZSwgRGF0ZS5uYW1lLCBTdHJpbmcubmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENoZWNrcyBpZiB0aGUgcHJvdmlkZWQgdmFsdWUgaXMgYSB2YWxpZCBkYXRlXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyB0aGF0IHRoZSBnaXZlbiB2YWx1ZSBpcyBhIHZhbGlkIGRhdGUuIElmIHRoZSB2YWx1ZSBpcyBhIHN0cmluZyxcbiAgICogaXQgYXR0ZW1wdHMgdG8gY29udmVydCBpdCB0byBhIERhdGUgb2JqZWN0LiBSZXR1cm5zIGFuIGVycm9yIG1lc3NhZ2UgaWYgdGhlIGRhdGUgaXMgaW52YWxpZCxcbiAgICogb3IgdW5kZWZpbmVkIGlmIHRoZSBkYXRlIGlzIHZhbGlkIG9yIGlmIHRoZSB2YWx1ZSBpcyB1bmRlZmluZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7RGF0ZSB8IHN0cmluZ30gdmFsdWUgLSBUaGUgdmFsdWUgdG8gdmFsaWRhdGUsIGNhbiBiZSBhIERhdGUgb2JqZWN0IG9yIGEgc3RyaW5nXG4gICAqIEBwYXJhbSB7RGF0ZVZhbGlkYXRvck9wdGlvbnN9IFtvcHRpb25zPXt9XSAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgdGhlIHZhbGlkYXRvclxuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9IEVycm9yIG1lc3NhZ2UgaWYgdmFsaWRhdGlvbiBmYWlscywgdW5kZWZpbmVkIGlmIHZhbGlkYXRpb24gcGFzc2VzXG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IERhdGUgfCBzdHJpbmcsXG4gICAgb3B0aW9uczogRGF0ZVZhbGlkYXRvck9wdGlvbnMgPSB7fVxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB2YWx1ZSA9IG5ldyBEYXRlKHZhbHVlKTtcblxuICAgIGlmIChOdW1iZXIuaXNOYU4odmFsdWUuZ2V0RGF0ZSgpKSkge1xuICAgICAgY29uc3QgeyBtZXNzYWdlID0gXCJcIiB9ID0gb3B0aW9ucztcbiAgICAgIHJldHVybiB0aGlzLmdldE1lc3NhZ2UobWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgVkFMSURBVElPTl9QQVJFTlRfS0VZIH0gZnJvbSBcIi4uLy4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgc2YgfSBmcm9tIFwiLi4vLi4vdXRpbHMvc3RyaW5nc1wiO1xuaW1wb3J0IHsgQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuXG4vKipcbiAqIFNhZmVseSByZXRyaWV2ZXMgYSBuZXN0ZWQgcHJvcGVydHkgdmFsdWUgZnJvbSBhbiBvYmplY3QgdXNpbmcgYSBkb3Qtbm90YXRlZCBwYXRoIHN0cmluZy5cbiAqXG4gKiBAdGVtcGxhdGUgVCAtIFRoZSBleHBlY3RlZCByZXR1cm4gdHlwZSBvZiB0aGUgcHJvcGVydHkgdmFsdWUuXG4gKlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBvYmogLSBUaGUgc291cmNlIG9iamVjdCB0byByZXRyaWV2ZSB0aGUgdmFsdWUgZnJvbS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gQSBkb3Qtc2VwYXJhdGVkIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHBhdGggdG8gdGhlIGRlc2lyZWQgcHJvcGVydHkgKGUuZy4sIFwidXNlci5hZGRyZXNzLnN0cmVldFwiKS5cbiAqXG4gKiBAcmV0dXJucyB7VH0gLSBUaGUgdmFsdWUgZm91bmQgYXQgdGhlIHNwZWNpZmllZCBwYXRoXG4gKlxuICogQHRocm93cyB7RXJyb3J9IC0gVGhyb3dzIGFuIGVycm9yIGlmIHRoZSBwYXRoIGlzIG5vdCBhIG5vbi1lbXB0eSBzdHJpbmcgb3IgaWYgYW55IHBhcnQgb2YgdGhlIHBhdGggZG9lcyBub3QgZXhpc3QgaW4gdGhlIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFZhbHVlQnlQYXRoPFQ+KG9iajogUmVjb3JkPHN0cmluZywgYW55PiwgcGF0aDogc3RyaW5nKTogVCB7XG4gIGlmICh0eXBlb2YgcGF0aCAhPT0gXCJzdHJpbmdcIiB8fCAhcGF0aC50cmltKCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3Ioc2YoQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUy5JTlZBTElEX1BBVEgsIHBhdGgpKTtcbiAgfVxuXG4gIC8vIFByb2Nlc3MgcGFyZW50IGRpcmVjdG9yeSBhY2Nlc3MgKC4uLylcbiAgY29uc3QgcGFyZW50QWNjZXNzb3JzID0gcGF0aC5tYXRjaCgvXFwuXFwuXFwvL2cpIHx8IFtdO1xuICBjb25zdCBwYXJlbnRMZXZlbCA9IHBhcmVudEFjY2Vzc29ycy5sZW5ndGg7XG4gIGNvbnN0IGNsZWFuUGF0aCA9IHBhdGgucmVwbGFjZSgvXFwuXFwuXFwvL2csIFwiXCIpO1xuXG4gIC8vIE5hdmlnYXRlIHVwIHRoZSBwYXJlbnQgY2hhaW5cbiAgbGV0IGN1cnJlbnRDb250ZXh0OiBhbnkgPSBvYmo7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyZW50TGV2ZWw7IGkrKykge1xuICAgIGlmICghY3VycmVudENvbnRleHQgfHwgdHlwZW9mIGN1cnJlbnRDb250ZXh0ICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIHNmKENPTVBBUklTT05fRVJST1JfTUVTU0FHRVMuQ09OVEVYVF9OT1RfT0JKRUNUX0NPTVBBUklTT04sIGkgKyAxLCBwYXRoKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIWN1cnJlbnRDb250ZXh0W1ZBTElEQVRJT05fUEFSRU5UX0tFWV0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgc2YoQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUy5OT19QQVJFTlRfQ09NUEFSSVNPTiwgaSArIDEsIHBhdGgpXG4gICAgICApO1xuICAgIH1cblxuICAgIGN1cnJlbnRDb250ZXh0ID0gY3VycmVudENvbnRleHRbVkFMSURBVElPTl9QQVJFTlRfS0VZXTtcbiAgfVxuXG4gIC8vIFByb2Nlc3MgZG90IG5vdGF0aW9uIHBhdGhcbiAgY29uc3QgcGFydHMgPSBjbGVhblBhdGguc3BsaXQoXCIuXCIpO1xuICBsZXQgY3VycmVudFZhbHVlOiBhbnkgPSBjdXJyZW50Q29udGV4dDtcblxuICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICBpZiAoXG4gICAgICBjdXJyZW50VmFsdWUgIT09IG51bGwgJiZcbiAgICAgIHR5cGVvZiBjdXJyZW50VmFsdWUgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgIHBhcnQgaW4gY3VycmVudFZhbHVlXG4gICAgKSB7XG4gICAgICBjdXJyZW50VmFsdWUgPSAoY3VycmVudFZhbHVlIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3BhcnRdO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBlcnJvck1zZ1RlbXBsYXRlID1cbiAgICAgICAgcGFyZW50TGV2ZWwgPT09IDBcbiAgICAgICAgICA/IENPTVBBUklTT05fRVJST1JfTUVTU0FHRVMuUFJPUEVSVFlfTk9UX0ZPVU5EXG4gICAgICAgICAgOiBwYXJlbnRMZXZlbCA9PT0gMVxuICAgICAgICAgICAgPyBDT01QQVJJU09OX0VSUk9SX01FU1NBR0VTLlBST1BFUlRZX05PVF9GT1VORF9PTl9QQVJFTlRcbiAgICAgICAgICAgIDogQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUy5QUk9QRVJUWV9OT1RfRk9VTkRfQUZURVJfUEFSRU5UO1xuXG4gICAgICB0aHJvdyBuZXcgRXJyb3Ioc2YoZXJyb3JNc2dUZW1wbGF0ZSwgcGF0aCwgcGFydCwgcGFyZW50TGV2ZWwpKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY3VycmVudFZhbHVlIGFzIFQ7XG59XG5cbmNvbnN0IGdldFR5cGVOYW1lID0gKHZhbHVlOiB1bmtub3duKTogc3RyaW5nID0+IHtcbiAgaWYgKHZhbHVlID09PSBudWxsKSByZXR1cm4gXCJudWxsXCI7XG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHJldHVybiBcIkRhdGVcIjtcbiAgaWYgKE51bWJlci5pc05hTih2YWx1ZSkpIHJldHVybiBcIk5hTlwiO1xuICBpZiAodmFsdWUgPT09IEluZmluaXR5KSByZXR1cm4gXCJJbmZpbml0eVwiO1xuICBpZiAodmFsdWUgPT09IC1JbmZpbml0eSkgcmV0dXJuIFwiLUluZmluaXR5XCI7XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuIFwiYXJyYXlcIjtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZTtcbn07XG5cbmNvbnN0IGlzU3VwcG9ydGVkID0gKFxuICB2YWx1ZTogdW5rbm93blxuKTogdmFsdWUgaXMgdW5kZWZpbmVkIHwgbnVtYmVyIHwgYmlnaW50IHwgRGF0ZSA9PiB7XG4gIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkgcmV0dXJuIHRydWU7XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJiaWdpbnRcIikgcmV0dXJuIHRydWU7XG5cbiAgLy8gTnVtYmVycyBtdXN0IGJlIGZpbml0ZSAoZXhjbHVkZXMgTmFOLCBJbmZpbml0eSwgLUluZmluaXR5KVxuICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiKSByZXR1cm4gTnVtYmVyLmlzRmluaXRlKHZhbHVlKTtcblxuICByZXR1cm4gZmFsc2U7XG59O1xuXG4vKipcbiAqIFZhbGlkYXRlcyB3aGV0aGVyIHR3byB2YWx1ZXMgYXJlIGVsaWdpYmxlIGZvciBjb21wYXJpc29uIHVzaW5nID49IG9yIDw9IG9wZXJhdG9ycy5cbiAqXG4gKiBTdXBwb3J0ZWQgdHlwZXM6IGB1bmRlZmluZWRgLCBgbnVtYmVyYCwgYGJpZ2ludGAsIGFuZCBgRGF0ZWAuXG4gKlxuICogQHBhcmFtIGEgLSBUaGUgZmlyc3QgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSBiIC0gVGhlIHNlY29uZCB2YWx1ZSB0byBjb21wYXJlLlxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIGJvdGggdmFsdWVzIGFyZSBvZiBzdXBwb3J0ZWQgdHlwZXMuXG4gKlxuICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBlaXRoZXIgdmFsdWUgaXMgb2YgYW4gdW5zdXBwb3J0ZWQgdHlwZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRGb3JHdGVPckx0ZUNvbXBhcmlzb24oYTogYW55LCBiOiBhbnkpOiBib29sZWFuIHtcbiAgaWYgKGlzU3VwcG9ydGVkKGEpICYmIGlzU3VwcG9ydGVkKGIpKSByZXR1cm4gdHJ1ZTtcblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgIHNmKFxuICAgICAgQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUy5VTlNVUFBPUlRFRF9UWVBFU19DT01QQVJJU09OLFxuICAgICAgZ2V0VHlwZU5hbWUoYSksXG4gICAgICBnZXRUeXBlTmFtZShiKVxuICAgIClcbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBDb21wYXJlcyB0d28gdmFsdWVzIHRvIGRldGVybWluZSBpZiB0aGUgZmlyc3QgaXMgbGVzcyB0aGFuIHRoZSBzZWNvbmQuXG4gKiBAZGVzY3JpcHRpb24gU3VwcG9ydHMgbnVtYmVycyBhbmQgZGF0ZXMuIFRocm93cyBhbiBlcnJvciBmb3IgdW5zdXBwb3J0ZWQgdHlwZXMuXG4gKlxuICogQHBhcmFtIHthbnl9IGEgLSBUaGUgZmlyc3QgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7YW55fSBiIC0gVGhlIHNlY29uZCB2YWx1ZSB0byBjb21wYXJlIGFnYWluc3QuXG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgYGFgIGlzIGxlc3MgdGhhbiBgYmAsIGZhbHNlIG90aGVyd2lzZS5cbiAqXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgZWl0aGVyIGBhYCBvciBgYmAgaXMgYG51bGxgIG9yIGB1bmRlZmluZWRgLlxuICogQHRocm93cyB7VHlwZUVycm9yfSBJZiB2YWx1ZXMgYXJlIG9mIG1pc21hdGNoZWQgb3IgdW5zdXBwb3J0ZWQgdHlwZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0xlc3NUaGFuKGE6IGFueSwgYjogYW55KTogYm9vbGVhbiB7XG4gIGlmIChbbnVsbCwgdW5kZWZpbmVkXS5pbmNsdWRlcyhhKSB8fCBbbnVsbCwgdW5kZWZpbmVkXS5pbmNsdWRlcyhiKSlcbiAgICB0aHJvdyBuZXcgRXJyb3IoQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUy5OVUxMX09SX1VOREVGSU5FRF9DT01QQVJJU09OKTtcblxuICAvLyBWYWxpZGF0ZSB0eXBlIGNvbXBhdGliaWxpdHlcbiAgY29uc3QgYVR5cGUgPSB0eXBlb2YgYTtcbiAgY29uc3QgYlR5cGUgPSB0eXBlb2YgYjtcblxuICBpZiAoYVR5cGUgIT09IGJUeXBlKSB7XG4gICAgLy8gQWxsb3cgbnVtYmVyIFggYmlnaW50XG4gICAgaWYgKGFUeXBlID09PSBcImJpZ2ludFwiICYmIGJUeXBlID09PSBcIm51bWJlclwiKVxuICAgICAgcmV0dXJuIE51bWJlcihhKSA8IChiIGFzIG51bWJlcik7XG4gICAgaWYgKGFUeXBlID09PSBcIm51bWJlclwiICYmIGJUeXBlID09PSBcImJpZ2ludFwiKVxuICAgICAgcmV0dXJuIChhIGFzIG51bWJlcikgPCBOdW1iZXIoYik7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgIHNmKENPTVBBUklTT05fRVJST1JfTUVTU0FHRVMuVFlQRV9NSVNNQVRDSF9DT01QQVJJU09OLCBhVHlwZSwgYlR5cGUpXG4gICAgKTtcbiAgfVxuXG4gIGlmIChcbiAgICAoYVR5cGUgPT09IFwibnVtYmVyXCIgJiYgYlR5cGUgPT09IFwibnVtYmVyXCIpIHx8XG4gICAgKGFUeXBlID09PSBcImJpZ2ludFwiICYmIGJUeXBlID09PSBcImJpZ2ludFwiKVxuICApIHtcbiAgICBpZiAoTnVtYmVyLmlzTmFOKGEpIHx8IE51bWJlci5pc05hTihiKSlcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUy5OQU5fQ09NUEFSSVNPTik7XG4gICAgcmV0dXJuIGEgPCBiO1xuICB9XG5cbiAgaWYgKGEgaW5zdGFuY2VvZiBEYXRlICYmIGIgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgaWYgKGlzTmFOKGEuZ2V0VGltZSgpKSB8fCBpc05hTihiLmdldFRpbWUoKSkpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKENPTVBBUklTT05fRVJST1JfTUVTU0FHRVMuSU5WQUxJRF9EQVRFX0NPTVBBUklTT04pO1xuICAgIHJldHVybiBhLmdldFRpbWUoKSA8IGIuZ2V0VGltZSgpO1xuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICBzZihcbiAgICAgIENPTVBBUklTT05fRVJST1JfTUVTU0FHRVMuVU5TVVBQT1JURURfVFlQRVNfQ09NUEFSSVNPTixcbiAgICAgIGdldFR5cGVOYW1lKGEpLFxuICAgICAgZ2V0VHlwZU5hbWUoYilcbiAgICApXG4gICk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGBhYCBpcyBncmVhdGVyIHRoYW4gYGJgLlxuICogU3VwcG9ydHMgY29tcGFyaXNvbiBmb3IgbnVtYmVycyBhbmQgRGF0ZSBvYmplY3RzLlxuICpcbiAqIEBwYXJhbSB7YW55fSBhIC0gVGhlIHZhbHVlIHRvIHZhbGlkYXRlLlxuICogQHBhcmFtIHthbnl9IGIgLSBUaGUgdmFsdWUgdG8gY29tcGFyZSBhZ2FpbnN0LlxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIGBhYCBpcyBncmVhdGVyIHRoYW4gYGJgLCBvdGhlcndpc2UgZmFsc2UuXG4gKlxuICogQHRocm93cyB7RXJyb3J9IElmIGVpdGhlciBgYWAgb3IgYGJgIGlzIGBudWxsYCBvciBgdW5kZWZpbmVkYC5cbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgdmFsdWVzIGFyZSBvZiBtaXNtYXRjaGVkIG9yIHVuc3VwcG9ydGVkIHR5cGVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNHcmVhdGVyVGhhbihhOiBhbnksIGI6IGFueSk6IGJvb2xlYW4ge1xuICBpZiAoW251bGwsIHVuZGVmaW5lZF0uaW5jbHVkZXMoYSkgfHwgW251bGwsIHVuZGVmaW5lZF0uaW5jbHVkZXMoYikpXG4gICAgdGhyb3cgbmV3IEVycm9yKENPTVBBUklTT05fRVJST1JfTUVTU0FHRVMuTlVMTF9PUl9VTkRFRklORURfQ09NUEFSSVNPTik7XG5cbiAgY29uc3QgYVR5cGUgPSB0eXBlb2YgYTtcbiAgY29uc3QgYlR5cGUgPSB0eXBlb2YgYjtcblxuICBpZiAoYVR5cGUgIT09IGJUeXBlKSB7XG4gICAgLy8gQWxsb3cgbnVtYmVyIFggYmlnaW50XG4gICAgaWYgKGFUeXBlID09PSBcImJpZ2ludFwiICYmIGJUeXBlID09PSBcIm51bWJlclwiKVxuICAgICAgcmV0dXJuIE51bWJlcihhKSA+IChiIGFzIG51bWJlcik7XG4gICAgaWYgKGFUeXBlID09PSBcIm51bWJlclwiICYmIGJUeXBlID09PSBcImJpZ2ludFwiKVxuICAgICAgcmV0dXJuIChhIGFzIG51bWJlcikgPiBOdW1iZXIoYik7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgc2YoQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUy5UWVBFX01JU01BVENIX0NPTVBBUklTT04sIGFUeXBlLCBiVHlwZSlcbiAgICApO1xuICB9XG5cbiAgaWYgKFxuICAgIChhVHlwZSA9PT0gXCJudW1iZXJcIiAmJiBiVHlwZSA9PT0gXCJudW1iZXJcIikgfHxcbiAgICAoYVR5cGUgPT09IFwiYmlnaW50XCIgJiYgYlR5cGUgPT09IFwiYmlnaW50XCIpXG4gICkge1xuICAgIGlmIChOdW1iZXIuaXNOYU4oYSkgfHwgTnVtYmVyLmlzTmFOKGIpKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihDT01QQVJJU09OX0VSUk9SX01FU1NBR0VTLk5BTl9DT01QQVJJU09OKTtcbiAgICByZXR1cm4gYSA+IGI7XG4gIH1cblxuICBpZiAoYSBpbnN0YW5jZW9mIERhdGUgJiYgYiBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICBpZiAoaXNOYU4oYS5nZXRUaW1lKCkpIHx8IGlzTmFOKGIuZ2V0VGltZSgpKSlcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUy5JTlZBTElEX0RBVEVfQ09NUEFSSVNPTik7XG4gICAgcmV0dXJuIGEuZ2V0VGltZSgpID4gYi5nZXRUaW1lKCk7XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgIHNmKFxuICAgICAgQ09NUEFSSVNPTl9FUlJPUl9NRVNTQUdFUy5VTlNVUFBPUlRFRF9UWVBFU19DT01QQVJJU09OLFxuICAgICAgZ2V0VHlwZU5hbWUoYSksXG4gICAgICBnZXRUeXBlTmFtZShiKVxuICAgIClcbiAgKTtcbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IERpZmZWYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBpc0VxdWFsIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBnZXRWYWx1ZUJ5UGF0aCB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgRGlmZiBWYWxpZGF0b3JcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0RpZmZWYWxpZGF0b3J9XG4gKlxuICogQGNsYXNzIERpZmZWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuRElGRilcbmV4cG9ydCBjbGFzcyBEaWZmVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPERpZmZWYWxpZGF0b3JPcHRpb25zPiB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuRElGRikge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIG1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKiBAcGFyYW0ge0NvbXBhcmlzb25WYWxpZGF0b3JPcHRpb25zfSBvcHRpb25zXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogYW55LFxuICAgIG9wdGlvbnM6IERpZmZWYWxpZGF0b3JPcHRpb25zLFxuICAgIGluc3RhbmNlOiBhbnlcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBsZXQgY29tcGFyaXNvblByb3BlcnR5VmFsdWU6IGFueTtcbiAgICB0cnkge1xuICAgICAgY29tcGFyaXNvblByb3BlcnR5VmFsdWUgPSBnZXRWYWx1ZUJ5UGF0aChcbiAgICAgICAgaW5zdGFuY2UsXG4gICAgICAgIG9wdGlvbnNbVmFsaWRhdGlvbktleXMuRElGRl1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRNZXNzYWdlKGUubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpO1xuICAgIH1cblxuICAgIHJldHVybiBpc0VxdWFsKHZhbHVlLCBjb21wYXJpc29uUHJvcGVydHlWYWx1ZSlcbiAgICAgID8gdGhpcy5nZXRNZXNzYWdlKFxuICAgICAgICAgIG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsXG4gICAgICAgICAgb3B0aW9uc1tWYWxpZGF0aW9uS2V5cy5ESUZGXVxuICAgICAgICApXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgUGF0dGVyblZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmVndWxhciBleHByZXNzaW9uIGZvciBwYXJzaW5nIHN0cmluZyBwYXR0ZXJucyB3aXRoIGZsYWdzXG4gKiBAc3VtbWFyeSBUaGlzIHJlZ3VsYXIgZXhwcmVzc2lvbiBpcyB1c2VkIHRvIHBhcnNlIHN0cmluZyBwYXR0ZXJucyBpbiB0aGUgZm9ybWF0IFwiL3BhdHRlcm4vZmxhZ3NcIi5cbiAqIEl0IGNhcHR1cmVzIHRoZSBwYXR0ZXJuIGFuZCBmbGFncyBzZXBhcmF0ZWx5LCBhbGxvd2luZyB0aGUgY3JlYXRpb24gb2YgYSBSZWdFeHAgb2JqZWN0XG4gKiB3aXRoIHRoZSBhcHByb3ByaWF0ZSBmbGFncy5cbiAqXG4gKiBAY29uc3Qge1JlZ0V4cH1cbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCByZWdleHBQYXJzZXI6IFJlZ0V4cCA9IG5ldyBSZWdFeHAoXCJeLyguKykvKFtnaW11c10qKSRcIik7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvciBmb3IgY2hlY2tpbmcgaWYgYSBzdHJpbmcgbWF0Y2hlcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBwYXR0ZXJuXG4gKiBAc3VtbWFyeSBUaGUgUGF0dGVyblZhbGlkYXRvciBjaGVja3MgaWYgYSBzdHJpbmcgdmFsdWUgbWF0Y2hlcyBhIHNwZWNpZmllZCByZWd1bGFyIGV4cHJlc3Npb24gcGF0dGVybi5cbiAqIEl0IHN1cHBvcnRzIGJvdGggUmVnRXhwIG9iamVjdHMgYW5kIHN0cmluZyByZXByZXNlbnRhdGlvbnMgb2YgcGF0dGVybnMsIGluY2x1ZGluZyB0aG9zZSB3aXRoIGZsYWdzLlxuICogVGhpcyB2YWxpZGF0b3IgaXMgdGhlIGZvdW5kYXRpb24gZm9yIHNwZWNpYWxpemVkIHZhbGlkYXRvcnMgbGlrZSBFbWFpbFZhbGlkYXRvciBhbmQgVVJMVmFsaWRhdG9yLFxuICogYW5kIGlzIHR5cGljYWxseSB1c2VkIHdpdGggdGhlIEBwYXR0ZXJuIGRlY29yYXRvci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIHZhbGlkYXRpb24gZmFpbHMsIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1BBVFRFUk59XG4gKlxuICogQGNsYXNzIFBhdHRlcm5WYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBDcmVhdGUgYSBwYXR0ZXJuIHZhbGlkYXRvciB3aXRoIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogY29uc3QgcGF0dGVyblZhbGlkYXRvciA9IG5ldyBQYXR0ZXJuVmFsaWRhdG9yKCk7XG4gKlxuICogLy8gQ3JlYXRlIGEgcGF0dGVybiB2YWxpZGF0b3Igd2l0aCBjdXN0b20gZXJyb3IgbWVzc2FnZVxuICogY29uc3QgY3VzdG9tUGF0dGVyblZhbGlkYXRvciA9IG5ldyBQYXR0ZXJuVmFsaWRhdG9yKFwiVmFsdWUgbXVzdCBtYXRjaCB0aGUgcmVxdWlyZWQgZm9ybWF0XCIpO1xuICpcbiAqIC8vIFZhbGlkYXRlIHVzaW5nIGEgUmVnRXhwIG9iamVjdFxuICogY29uc3QgcmVnZXhPcHRpb25zID0geyBwYXR0ZXJuOiAvXltBLVpdW2Etel0rJC8gfTtcbiAqIHBhdHRlcm5WYWxpZGF0b3IuaGFzRXJyb3JzKFwiSGVsbG9cIiwgcmVnZXhPcHRpb25zKTsgLy8gdW5kZWZpbmVkICh2YWxpZClcbiAqIHBhdHRlcm5WYWxpZGF0b3IuaGFzRXJyb3JzKFwiaGVsbG9cIiwgcmVnZXhPcHRpb25zKTsgLy8gUmV0dXJucyBlcnJvciBtZXNzYWdlIChpbnZhbGlkKVxuICpcbiAqIC8vIFZhbGlkYXRlIHVzaW5nIGEgc3RyaW5nIHBhdHRlcm5cbiAqIGNvbnN0IHN0cmluZ09wdGlvbnMgPSB7IHBhdHRlcm46IFwiXlxcXFxkezN9LVxcXFxkezJ9LVxcXFxkezR9JFwiIH07XG4gKiBwYXR0ZXJuVmFsaWRhdG9yLmhhc0Vycm9ycyhcIjEyMy00NS02Nzg5XCIsIHN0cmluZ09wdGlvbnMpOyAvLyB1bmRlZmluZWQgKHZhbGlkKVxuICpcbiAqIC8vIFZhbGlkYXRlIHVzaW5nIGEgc3RyaW5nIHBhdHRlcm4gd2l0aCBmbGFnc1xuICogY29uc3QgZmxhZ09wdGlvbnMgPSB7IHBhdHRlcm46IFwiL15oZWxsbyQvaVwiIH07XG4gKiBwYXR0ZXJuVmFsaWRhdG9yLmhhc0Vycm9ycyhcIkhlbGxvXCIsIGZsYWdPcHRpb25zKTsgLy8gdW5kZWZpbmVkICh2YWxpZClcbiAqIGBgYFxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQyBhcyBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgViBhcyBQYXR0ZXJuVmFsaWRhdG9yXG4gKlxuICogICBDLT4+VjogbmV3IFBhdHRlcm5WYWxpZGF0b3IobWVzc2FnZSlcbiAqICAgQy0+PlY6IGhhc0Vycm9ycyh2YWx1ZSwgb3B0aW9ucylcbiAqICAgYWx0IHZhbHVlIGlzIGVtcHR5XG4gKiAgICAgVi0tPj5DOiB1bmRlZmluZWQgKHZhbGlkKVxuICogICBlbHNlIHBhdHRlcm4gaXMgbWlzc2luZ1xuICogICAgIFYtLT4+QzogRXJyb3I6IE1pc3NpbmcgUGF0dGVyblxuICogICBlbHNlIHBhdHRlcm4gaXMgc3RyaW5nXG4gKiAgICAgVi0+PlY6IGdldFBhdHRlcm4ocGF0dGVybilcbiAqICAgZW5kXG4gKiAgIFYtPj5WOiBSZXNldCBwYXR0ZXJuLmxhc3RJbmRleFxuICogICBWLT4+VjogVGVzdCB2YWx1ZSBhZ2FpbnN0IHBhdHRlcm5cbiAqICAgYWx0IHBhdHRlcm4gdGVzdCBwYXNzZXNcbiAqICAgICBWLS0+PkM6IHVuZGVmaW5lZCAodmFsaWQpXG4gKiAgIGVsc2UgcGF0dGVybiB0ZXN0IGZhaWxzXG4gKiAgICAgVi0tPj5DOiBFcnJvciBtZXNzYWdlXG4gKiAgIGVuZFxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuUEFUVEVSTilcbmV4cG9ydCBjbGFzcyBQYXR0ZXJuVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPFBhdHRlcm5WYWxpZGF0b3JPcHRpb25zPiB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuUEFUVEVSTikge1xuICAgIHN1cGVyKG1lc3NhZ2UsIFwic3RyaW5nXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBhIHN0cmluZyBwYXR0ZXJuIHRvIGEgUmVnRXhwIG9iamVjdFxuICAgKiBAc3VtbWFyeSBQYXJzZXMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSByZWd1bGFyIGV4cHJlc3Npb24gYW5kIGNvbnZlcnRzIGl0IHRvIGEgUmVnRXhwIG9iamVjdC5cbiAgICogSXQgaGFuZGxlcyBib3RoIHNpbXBsZSBzdHJpbmcgcGF0dGVybnMgYW5kIHBhdHRlcm5zIHdpdGggZmxhZ3MgaW4gdGhlIGZvcm1hdCBcIi9wYXR0ZXJuL2ZsYWdzXCIuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXR0ZXJuIC0gVGhlIHN0cmluZyBwYXR0ZXJuIHRvIGNvbnZlcnRcbiAgICogQHJldHVybiB7UmVnRXhwfSBBIFJlZ0V4cCBvYmplY3QgY3JlYXRlZCBmcm9tIHRoZSBzdHJpbmcgcGF0dGVyblxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBnZXRQYXR0ZXJuKHBhdHRlcm46IHN0cmluZyk6IFJlZ0V4cCB7XG4gICAgaWYgKCFyZWdleHBQYXJzZXIudGVzdChwYXR0ZXJuKSkgcmV0dXJuIG5ldyBSZWdFeHAocGF0dGVybik7XG4gICAgY29uc3QgbWF0Y2g6IGFueSA9IHBhdHRlcm4ubWF0Y2gocmVnZXhwUGFyc2VyKTtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cChtYXRjaFsxXSwgbWF0Y2hbMl0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYSBzdHJpbmcgbWF0Y2hlcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBwYXR0ZXJuXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyB0aGF0IHRoZSBwcm92aWRlZCBzdHJpbmcgbWF0Y2hlcyB0aGUgcGF0dGVybiBzcGVjaWZpZWQgaW4gdGhlIG9wdGlvbnMuXG4gICAqIElmIHRoZSBwYXR0ZXJuIGlzIHByb3ZpZGVkIGFzIGEgc3RyaW5nLCBpdCdzIGNvbnZlcnRlZCB0byBhIFJlZ0V4cCBvYmplY3QgdXNpbmcgdGhlIGdldFBhdHRlcm4gbWV0aG9kLlxuICAgKiBUaGUgbWV0aG9kIHJlc2V0cyB0aGUgcGF0dGVybidzIGxhc3RJbmRleCBwcm9wZXJ0eSB0byBlbnN1cmUgY29uc2lzdGVudCB2YWxpZGF0aW9uIHJlc3VsdHNcbiAgICogZm9yIHBhdHRlcm5zIHdpdGggdGhlIGdsb2JhbCBmbGFnLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgLSBUaGUgc3RyaW5nIHRvIHZhbGlkYXRlIGFnYWluc3QgdGhlIHBhdHRlcm5cbiAgICogQHBhcmFtIHtQYXR0ZXJuVmFsaWRhdG9yT3B0aW9uc30gb3B0aW9ucyAtIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBjb250YWluaW5nIHRoZSBwYXR0ZXJuXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH0gRXJyb3IgbWVzc2FnZSBpZiB2YWxpZGF0aW9uIGZhaWxzLCB1bmRlZmluZWQgaWYgdmFsaWRhdGlvbiBwYXNzZXNcbiAgICpcbiAgICogQHRocm93cyB7RXJyb3J9IElmIG5vIHBhdHRlcm4gaXMgcHJvdmlkZWQgaW4gdGhlIG9wdGlvbnNcbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogc3RyaW5nLFxuICAgIG9wdGlvbnM6IFBhdHRlcm5WYWxpZGF0b3JPcHRpb25zXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCF2YWx1ZSkgcmV0dXJuO1xuXG4gICAgbGV0IHsgcGF0dGVybiB9ID0gb3B0aW9ucztcbiAgICBpZiAoIXBhdHRlcm4pIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgUGF0dGVyblwiKTtcbiAgICBwYXR0ZXJuID0gdHlwZW9mIHBhdHRlcm4gPT09IFwic3RyaW5nXCIgPyB0aGlzLmdldFBhdHRlcm4ocGF0dGVybikgOiBwYXR0ZXJuO1xuICAgIHBhdHRlcm4ubGFzdEluZGV4ID0gMDsgLy8gcmVzZXRzIHBhdHRlcm4gcG9zaXRpb24gZm9yIHJlcGVhdCB2YWxpZGF0aW9uIHJlcXVlc3RzXG4gICAgcmV0dXJuICFwYXR0ZXJuLnRlc3QodmFsdWUpXG4gICAgICA/IHRoaXMuZ2V0TWVzc2FnZShvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIERFRkFVTFRfRVJST1JfTUVTU0FHRVMsXG4gIERFRkFVTFRfUEFUVEVSTlMsXG4gIFZhbGlkYXRpb25LZXlzLFxufSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFBhdHRlcm5WYWxpZGF0b3IgfSBmcm9tIFwiLi9QYXR0ZXJuVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBQYXR0ZXJuVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3IgZm9yIGNoZWNraW5nIGlmIGEgc3RyaW5nIGlzIGEgdmFsaWQgZW1haWwgYWRkcmVzc1xuICogQHN1bW1hcnkgVGhlIEVtYWlsVmFsaWRhdG9yIGNoZWNrcyBpZiBhIHN0cmluZyBtYXRjaGVzIGEgc3RhbmRhcmQgZW1haWwgYWRkcmVzcyBwYXR0ZXJuLlxuICogSXQgZXh0ZW5kcyB0aGUgUGF0dGVyblZhbGlkYXRvciBhbmQgdXNlcyBhIHByZWRlZmluZWQgZW1haWwgcmVnZXggcGF0dGVybiB0byB2YWxpZGF0ZSBlbWFpbCBhZGRyZXNzZXMuXG4gKiBUaGlzIHZhbGlkYXRvciBpcyB0eXBpY2FsbHkgdXNlZCB3aXRoIHRoZSBAZW1haWwgZGVjb3JhdG9yLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gLSBDdXN0b20gZXJyb3IgbWVzc2FnZSB0byBkaXNwbGF5IHdoZW4gdmFsaWRhdGlvbiBmYWlscywgZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjRU1BSUx9XG4gKlxuICogQGNsYXNzIEVtYWlsVmFsaWRhdG9yXG4gKiBAZXh0ZW5kcyBQYXR0ZXJuVmFsaWRhdG9yXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIENyZWF0ZSBhbiBlbWFpbCB2YWxpZGF0b3Igd2l0aCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIGNvbnN0IGVtYWlsVmFsaWRhdG9yID0gbmV3IEVtYWlsVmFsaWRhdG9yKCk7XG4gKlxuICogLy8gQ3JlYXRlIGFuIGVtYWlsIHZhbGlkYXRvciB3aXRoIGN1c3RvbSBlcnJvciBtZXNzYWdlXG4gKiBjb25zdCBjdXN0b21FbWFpbFZhbGlkYXRvciA9IG5ldyBFbWFpbFZhbGlkYXRvcihcIlBsZWFzZSBlbnRlciBhIHZhbGlkIGVtYWlsIGFkZHJlc3NcIik7XG4gKlxuICogLy8gVmFsaWRhdGUgYW4gZW1haWxcbiAqIGNvbnN0IHJlc3VsdCA9IGVtYWlsVmFsaWRhdG9yLmhhc0Vycm9ycyhcInVzZXJAZXhhbXBsZS5jb21cIik7IC8vIHVuZGVmaW5lZCAodmFsaWQpXG4gKiBjb25zdCBpbnZhbGlkUmVzdWx0ID0gZW1haWxWYWxpZGF0b3IuaGFzRXJyb3JzKFwiaW52YWxpZC1lbWFpbFwiKTsgLy8gUmV0dXJucyBlcnJvciBtZXNzYWdlIChpbnZhbGlkKVxuICogYGBgXG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENsaWVudFxuICogICBwYXJ0aWNpcGFudCBFIGFzIEVtYWlsVmFsaWRhdG9yXG4gKiAgIHBhcnRpY2lwYW50IFAgYXMgUGF0dGVyblZhbGlkYXRvclxuICpcbiAqICAgQy0+PkU6IG5ldyBFbWFpbFZhbGlkYXRvcihtZXNzYWdlKVxuICogICBFLT4+UDogc3VwZXIobWVzc2FnZSlcbiAqICAgQy0+PkU6IGhhc0Vycm9ycyh2YWx1ZSwgb3B0aW9ucylcbiAqICAgRS0+PlA6IHN1cGVyLmhhc0Vycm9ycyh2YWx1ZSwgb3B0aW9ucyB3aXRoIEVNQUlMIHBhdHRlcm4pXG4gKiAgIFAtLT4+RTogdmFsaWRhdGlvbiByZXN1bHRcbiAqICAgRS0tPj5DOiB2YWxpZGF0aW9uIHJlc3VsdFxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuRU1BSUwpXG5leHBvcnQgY2xhc3MgRW1haWxWYWxpZGF0b3IgZXh0ZW5kcyBQYXR0ZXJuVmFsaWRhdG9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5FTUFJTCkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYSBzdHJpbmcgaXMgYSB2YWxpZCBlbWFpbCBhZGRyZXNzXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyB0aGF0IHRoZSBwcm92aWRlZCBzdHJpbmcgbWF0Y2hlcyB0aGUgZW1haWwgcGF0dGVybi5cbiAgICogVGhpcyBtZXRob2QgZXh0ZW5kcyB0aGUgUGF0dGVyblZhbGlkYXRvcidzIGhhc0Vycm9ycyBtZXRob2QgYnkgZW5zdXJpbmdcbiAgICogdGhlIGVtYWlsIHBhdHRlcm4gaXMgdXNlZCwgZXZlbiBpZiBub3QgZXhwbGljaXRseSBwcm92aWRlZCBpbiB0aGUgb3B0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gVGhlIHN0cmluZyB0byB2YWxpZGF0ZSBhcyBhbiBlbWFpbCBhZGRyZXNzXG4gICAqIEBwYXJhbSB7UGF0dGVyblZhbGlkYXRvck9wdGlvbnN9IFtvcHRpb25zPXt9XSAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gb3B0aW9uc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9IEVycm9yIG1lc3NhZ2UgaWYgdmFsaWRhdGlvbiBmYWlscywgdW5kZWZpbmVkIGlmIHZhbGlkYXRpb24gcGFzc2VzXG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFBhdHRlcm5WYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBzdHJpbmcsXG4gICAgb3B0aW9uczogUGF0dGVyblZhbGlkYXRvck9wdGlvbnMgPSB7fVxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBzdXBlci5oYXNFcnJvcnModmFsdWUsIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBwYXR0ZXJuOiBvcHRpb25zPy5wYXR0ZXJuIHx8IERFRkFVTFRfUEFUVEVSTlMuRU1BSUwsXG4gICAgfSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IEVxdWFsc1ZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IGlzRXF1YWwgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IGdldFZhbHVlQnlQYXRoIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBFcXVhbHMgVmFsaWRhdG9yXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNFUVVBTFN9XG4gKlxuICogQGNsYXNzIEVxdWFsc1ZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5FUVVBTFMpXG5leHBvcnQgY2xhc3MgRXF1YWxzVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPEVxdWFsc1ZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5FUVVBTFMpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSBtb2RlbFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtDb21wYXJpc29uVmFsaWRhdG9yT3B0aW9uc30gb3B0aW9uc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9XG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IGFueSxcbiAgICBvcHRpb25zOiBFcXVhbHNWYWxpZGF0b3JPcHRpb25zLFxuICAgIGluc3RhbmNlOiBhbnlcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBsZXQgY29tcGFyaXNvblByb3BlcnR5VmFsdWU6IGFueTtcbiAgICB0cnkge1xuICAgICAgY29tcGFyaXNvblByb3BlcnR5VmFsdWUgPSBnZXRWYWx1ZUJ5UGF0aChcbiAgICAgICAgaW5zdGFuY2UsXG4gICAgICAgIG9wdGlvbnNbVmFsaWRhdGlvbktleXMuRVFVQUxTXVxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldE1lc3NhZ2UoZS5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGlzRXF1YWwodmFsdWUsIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlKVxuICAgICAgPyB1bmRlZmluZWRcbiAgICAgIDogdGhpcy5nZXRNZXNzYWdlKFxuICAgICAgICAgIG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsXG4gICAgICAgICAgb3B0aW9uc1tWYWxpZGF0aW9uS2V5cy5FUVVBTFNdXG4gICAgICAgICk7XG4gIH1cbn1cblxuLy8gVmFsaWRhdGlvbi5yZWdpc3Rlcih7XG4vLyAgIHZhbGlkYXRvcjogRXF1YWxzVmFsaWRhdG9yLFxuLy8gICB2YWxpZGF0aW9uS2V5OiBWYWxpZGF0aW9uS2V5cy5FUVVBTFMsXG4vLyAgIHNhdmU6IGZhbHNlLFxuLy8gfSBhcyBWYWxpZGF0b3JEZWZpbml0aW9uKTtcbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IEdyZWF0ZXJUaGFuVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0VmFsdWVCeVBhdGgsIGlzR3JlYXRlclRoYW4gfSBmcm9tIFwiLi91dGlsc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IEdyZWF0ZXIgVGhhbiBWYWxpZGF0b3JcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0dSRUFURVJfVEhBTn1cbiAqXG4gKiBAY2xhc3MgR3JlYXRlclRoYW5WYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuR1JFQVRFUl9USEFOKVxuZXhwb3J0IGNsYXNzIEdyZWF0ZXJUaGFuVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPEdyZWF0ZXJUaGFuVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkdSRUFURVJfVEhBTikge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIG1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKiBAcGFyYW0ge0NvbXBhcmlzb25WYWxpZGF0b3JPcHRpb25zfSBvcHRpb25zXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogYW55LFxuICAgIG9wdGlvbnM6IEdyZWF0ZXJUaGFuVmFsaWRhdG9yT3B0aW9ucyxcbiAgICBpbnN0YW5jZTogYW55XG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgbGV0IGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlOiBhbnk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlID0gZ2V0VmFsdWVCeVBhdGgoXG4gICAgICAgIGluc3RhbmNlLFxuICAgICAgICBvcHRpb25zW1ZhbGlkYXRpb25LZXlzLkdSRUFURVJfVEhBTl1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRNZXNzYWdlKGUubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBpZiAoIWlzR3JlYXRlclRoYW4odmFsdWUsIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlKSlcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZShlLm1lc3NhZ2UsIG9wdGlvbnNbVmFsaWRhdGlvbktleXMuR1JFQVRFUl9USEFOXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgR3JlYXRlclRoYW5PckVxdWFsVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgZ2V0VmFsdWVCeVBhdGgsXG4gIGlzR3JlYXRlclRoYW4sXG4gIGlzVmFsaWRGb3JHdGVPckx0ZUNvbXBhcmlzb24sXG59IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBpc0VxdWFsIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgR3JlYXRlciBUaGFuIG9yIEVxdWFsIFZhbGlkYXRvclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjR1JFQVRFUl9USEFOX09SX0VRVUFMfVxuICpcbiAqIEBjbGFzcyBHcmVhdGVyVGhhbk9yRXF1YWxWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuR1JFQVRFUl9USEFOX09SX0VRVUFMKVxuZXhwb3J0IGNsYXNzIEdyZWF0ZXJUaGFuT3JFcXVhbFZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvcjxHcmVhdGVyVGhhbk9yRXF1YWxWYWxpZGF0b3JPcHRpb25zPiB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuR1JFQVRFUl9USEFOX09SX0VRVUFMKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIGEgbW9kZWxcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gICAqIEBwYXJhbSB7Q29tcGFyaXNvblZhbGlkYXRvck9wdGlvbnN9IG9wdGlvbnNcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBhbnksXG4gICAgb3B0aW9uczogR3JlYXRlclRoYW5PckVxdWFsVmFsaWRhdG9yT3B0aW9ucyxcbiAgICBpbnN0YW5jZTogYW55XG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgbGV0IGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlOiBhbnk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlID0gZ2V0VmFsdWVCeVBhdGgoXG4gICAgICAgIGluc3RhbmNlLFxuICAgICAgICBvcHRpb25zW1ZhbGlkYXRpb25LZXlzLkdSRUFURVJfVEhBTl9PUl9FUVVBTF1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRNZXNzYWdlKGUubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBpZiAoXG4gICAgICAgIChpc1ZhbGlkRm9yR3RlT3JMdGVDb21wYXJpc29uKHZhbHVlLCBjb21wYXJpc29uUHJvcGVydHlWYWx1ZSkgJiZcbiAgICAgICAgICBpc0VxdWFsKHZhbHVlLCBjb21wYXJpc29uUHJvcGVydHlWYWx1ZSkpIHx8XG4gICAgICAgIGlzR3JlYXRlclRoYW4odmFsdWUsIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlKVxuICAgICAgKVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgICB0aHJvdyBuZXcgRXJyb3Iob3B0aW9ucy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRNZXNzYWdlKFxuICAgICAgICBlLm1lc3NhZ2UsXG4gICAgICAgIG9wdGlvbnNbVmFsaWRhdGlvbktleXMuR1JFQVRFUl9USEFOX09SX0VRVUFMXVxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IExlc3NUaGFuVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0VmFsdWVCeVBhdGgsIGlzTGVzc1RoYW4gfSBmcm9tIFwiLi91dGlsc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IExlc3MgVGhhbiBWYWxpZGF0b3JcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0xFU1NfVEhBTn1cbiAqXG4gKiBAY2xhc3MgTGVzc1RoYW5WYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuTEVTU19USEFOKVxuZXhwb3J0IGNsYXNzIExlc3NUaGFuVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPExlc3NUaGFuVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkxFU1NfVEhBTikge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIG1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKiBAcGFyYW0ge0NvbXBhcmlzb25WYWxpZGF0b3JPcHRpb25zfSBvcHRpb25zXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgcHVibGljIGhhc0Vycm9ycyhcbiAgICB2YWx1ZTogYW55LFxuICAgIG9wdGlvbnM6IExlc3NUaGFuVmFsaWRhdG9yT3B0aW9ucyxcbiAgICBpbnN0YW5jZTogYW55XG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgbGV0IGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlOiBhbnk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlID0gZ2V0VmFsdWVCeVBhdGgoXG4gICAgICAgIGluc3RhbmNlLFxuICAgICAgICBvcHRpb25zW1ZhbGlkYXRpb25LZXlzLkxFU1NfVEhBTl1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRNZXNzYWdlKGUubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBpZiAoIWlzTGVzc1RoYW4odmFsdWUsIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlKSlcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZShlLm1lc3NhZ2UsIG9wdGlvbnNbVmFsaWRhdGlvbktleXMuTEVTU19USEFOXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHR5cGUgeyBMZXNzVGhhbk9yRXF1YWxWYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQge1xuICBnZXRWYWx1ZUJ5UGF0aCxcbiAgaXNMZXNzVGhhbixcbiAgaXNWYWxpZEZvckd0ZU9yTHRlQ29tcGFyaXNvbixcbn0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IGlzRXF1YWwgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBMZXNzIFRoYW4gb3IgRXF1YWwgVmFsaWRhdG9yXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNMRVNTX1RIQU5fT1JfRVFVQUx9XG4gKlxuICogQGNsYXNzIExlc3NUaGFuT3JFcXVhbFZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5MRVNTX1RIQU5fT1JfRVFVQUwpXG5leHBvcnQgY2xhc3MgTGVzc1RoYW5PckVxdWFsVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPExlc3NUaGFuT3JFcXVhbFZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5MRVNTX1RIQU5fT1JfRVFVQUwpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSBtb2RlbFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtDb21wYXJpc29uVmFsaWRhdG9yT3B0aW9uc30gb3B0aW9uc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9XG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IGFueSxcbiAgICBvcHRpb25zOiBMZXNzVGhhbk9yRXF1YWxWYWxpZGF0b3JPcHRpb25zLFxuICAgIGluc3RhbmNlOiBhbnlcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBsZXQgY29tcGFyaXNvblByb3BlcnR5VmFsdWU6IGFueTtcbiAgICB0cnkge1xuICAgICAgY29tcGFyaXNvblByb3BlcnR5VmFsdWUgPSBnZXRWYWx1ZUJ5UGF0aChcbiAgICAgICAgaW5zdGFuY2UsXG4gICAgICAgIG9wdGlvbnNbVmFsaWRhdGlvbktleXMuTEVTU19USEFOX09SX0VRVUFMXVxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldE1lc3NhZ2UoZS5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGlmIChcbiAgICAgICAgKGlzVmFsaWRGb3JHdGVPckx0ZUNvbXBhcmlzb24odmFsdWUsIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlKSAmJlxuICAgICAgICAgIGlzRXF1YWwodmFsdWUsIGNvbXBhcmlzb25Qcm9wZXJ0eVZhbHVlKSkgfHxcbiAgICAgICAgaXNMZXNzVGhhbih2YWx1ZSwgY29tcGFyaXNvblByb3BlcnR5VmFsdWUpXG4gICAgICApXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgIHRocm93IG5ldyBFcnJvcihvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldE1lc3NhZ2UoXG4gICAgICAgIGUubWVzc2FnZSxcbiAgICAgICAgb3B0aW9uc1tWYWxpZGF0aW9uS2V5cy5MRVNTX1RIQU5fT1JfRVFVQUxdXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgTGlzdFZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdG9yIGZvciBjaGVja2luZyBpZiBlbGVtZW50cyBpbiBhIGxpc3Qgb3Igc2V0IG1hdGNoIGV4cGVjdGVkIHR5cGVzXG4gKiBAc3VtbWFyeSBUaGUgTGlzdFZhbGlkYXRvciB2YWxpZGF0ZXMgdGhhdCBhbGwgZWxlbWVudHMgaW4gYW4gYXJyYXkgb3IgU2V0IG1hdGNoIHRoZSBleHBlY3RlZCB0eXBlcy5cbiAqIEl0IGNoZWNrcyBlYWNoIGVsZW1lbnQgYWdhaW5zdCBhIGxpc3Qgb2YgYWxsb3dlZCBjbGFzcyB0eXBlcyBhbmQgZW5zdXJlcyB0eXBlIGNvbnNpc3RlbmN5LlxuICogVGhpcyB2YWxpZGF0b3IgaXMgdHlwaWNhbGx5IHVzZWQgd2l0aCB0aGUgQGxpc3QgZGVjb3JhdG9yLlxuICogXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIHZhbGlkYXRpb24gZmFpbHMsIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI0xJU1R9XG4gKiBcbiAqIEBjbGFzcyBMaXN0VmFsaWRhdG9yXG4gKiBAZXh0ZW5kcyBWYWxpZGF0b3JcbiAqIFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIENyZWF0ZSBhIGxpc3QgdmFsaWRhdG9yIHdpdGggZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBjb25zdCBsaXN0VmFsaWRhdG9yID0gbmV3IExpc3RWYWxpZGF0b3IoKTtcbiAqIFxuICogLy8gQ3JlYXRlIGEgbGlzdCB2YWxpZGF0b3Igd2l0aCBjdXN0b20gZXJyb3IgbWVzc2FnZVxuICogY29uc3QgY3VzdG9tTGlzdFZhbGlkYXRvciA9IG5ldyBMaXN0VmFsaWRhdG9yKFwiQWxsIGl0ZW1zIG11c3QgYmUgb2YgdGhlIHNwZWNpZmllZCB0eXBlXCIpO1xuICogXG4gKiAvLyBWYWxpZGF0ZSBhIGxpc3RcbiAqIGNvbnN0IG9wdGlvbnMgPSB7IGNsYXp6OiBbXCJTdHJpbmdcIiwgXCJOdW1iZXJcIl0gfTtcbiAqIGNvbnN0IHJlc3VsdCA9IGxpc3RWYWxpZGF0b3IuaGFzRXJyb3JzKFtcInRlc3RcIiwgMTIzXSwgb3B0aW9ucyk7IC8vIHVuZGVmaW5lZCAodmFsaWQpXG4gKiBjb25zdCBpbnZhbGlkUmVzdWx0ID0gbGlzdFZhbGlkYXRvci5oYXNFcnJvcnMoW25ldyBEYXRlKCldLCBvcHRpb25zKTsgLy8gUmV0dXJucyBlcnJvciBtZXNzYWdlIChpbnZhbGlkKVxuICogYGBgXG4gKiBcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQyBhcyBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgViBhcyBMaXN0VmFsaWRhdG9yXG4gKiAgIFxuICogICBDLT4+VjogbmV3IExpc3RWYWxpZGF0b3IobWVzc2FnZSlcbiAqICAgQy0+PlY6IGhhc0Vycm9ycyh2YWx1ZSwgb3B0aW9ucylcbiAqICAgYWx0IHZhbHVlIGlzIGVtcHR5XG4gKiAgICAgVi0tPj5DOiB1bmRlZmluZWQgKHZhbGlkKVxuICogICBlbHNlIHZhbHVlIGhhcyBlbGVtZW50c1xuICogICAgIFYtPj5WOiBDaGVjayBlYWNoIGVsZW1lbnQncyB0eXBlXG4gKiAgICAgYWx0IEFsbCBlbGVtZW50cyBtYXRjaCBhbGxvd2VkIHR5cGVzXG4gKiAgICAgICBWLS0+PkM6IHVuZGVmaW5lZCAodmFsaWQpXG4gKiAgICAgZWxzZSBTb21lIGVsZW1lbnRzIGRvbid0IG1hdGNoXG4gKiAgICAgICBWLS0+PkM6IEVycm9yIG1lc3NhZ2VcbiAqICAgICBlbmRcbiAqICAgZW5kXG4gKiBcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuTElTVClcbmV4cG9ydCBjbGFzcyBMaXN0VmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPExpc3RWYWxpZGF0b3JPcHRpb25zPiB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuTElTVCkge1xuICAgIHN1cGVyKG1lc3NhZ2UsIEFycmF5Lm5hbWUsIFNldC5uYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ2hlY2tzIGlmIGFsbCBlbGVtZW50cyBpbiBhIGxpc3Qgb3Igc2V0IG1hdGNoIHRoZSBleHBlY3RlZCB0eXBlc1xuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgdGhhdCBlYWNoIGVsZW1lbnQgaW4gdGhlIHByb3ZpZGVkIGFycmF5IG9yIFNldCBtYXRjaGVzIG9uZSBvZiB0aGUgXG4gICAqIGNsYXNzIHR5cGVzIHNwZWNpZmllZCBpbiB0aGUgb3B0aW9ucy4gRm9yIG9iamVjdCB0eXBlcywgaXQgY2hlY2tzIHRoZSBjb25zdHJ1Y3RvciBuYW1lLFxuICAgKiBhbmQgZm9yIHByaW1pdGl2ZSB0eXBlcywgaXQgY29tcGFyZXMgYWdhaW5zdCB0aGUgbG93ZXJjYXNlIHR5cGUgbmFtZS5cbiAgICpcbiAgICogQHBhcmFtIHthbnlbXSB8IFNldDxhbnk+fSB2YWx1ZSAtIFRoZSBhcnJheSBvciBTZXQgdG8gdmFsaWRhdGVcbiAgICogQHBhcmFtIHtMaXN0VmFsaWRhdG9yT3B0aW9uc30gb3B0aW9ucyAtIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBjb250YWluaW5nIHRoZSBhbGxvd2VkIGNsYXNzIHR5cGVzXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH0gRXJyb3IgbWVzc2FnZSBpZiB2YWxpZGF0aW9uIGZhaWxzLCB1bmRlZmluZWQgaWYgdmFsaWRhdGlvbiBwYXNzZXNcbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgVmFsaWRhdG9yI2hhc0Vycm9yc1xuICAgKi9cbiAgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBhbnlbXSB8IFNldDxhbnk+LFxuICAgIG9wdGlvbnM6IExpc3RWYWxpZGF0b3JPcHRpb25zXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCF2YWx1ZSB8fCAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyAhdmFsdWUubGVuZ3RoIDogIXZhbHVlLnNpemUpKSByZXR1cm47XG5cbiAgICBjb25zdCBjbGF6eiA9IEFycmF5LmlzQXJyYXkob3B0aW9ucy5jbGF6eilcbiAgICAgID8gb3B0aW9ucy5jbGF6elxuICAgICAgOiBbb3B0aW9ucy5jbGF6el07XG4gICAgbGV0IHZhbDogYW55LFxuICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgZm9yIChcbiAgICAgIGxldCBpID0gMDtcbiAgICAgIGkgPCAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZS5sZW5ndGggOiB2YWx1ZS5zaXplKTtcbiAgICAgIGkrK1xuICAgICkge1xuICAgICAgdmFsID0gKHZhbHVlIGFzIGFueSlbaV07XG4gICAgICBzd2l0Y2ggKHR5cGVvZiB2YWwpIHtcbiAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICBjYXNlIFwiZnVuY3Rpb25cIjpcbiAgICAgICAgICBpc1ZhbGlkID0gY2xhenouaW5jbHVkZXMoKHZhbCBhcyBvYmplY3QpLmNvbnN0cnVjdG9yPy5uYW1lKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBpc1ZhbGlkID0gY2xhenouc29tZSgoYzogc3RyaW5nKSA9PiB0eXBlb2YgdmFsID09PSBjLnRvTG93ZXJDYXNlKCkpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBpc1ZhbGlkXG4gICAgICA/IHVuZGVmaW5lZFxuICAgICAgOiB0aGlzLmdldE1lc3NhZ2Uob3B0aW9ucy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSwgY2xhenopO1xuICB9XG59XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tIFwiLi9WYWxpZGF0b3JcIjtcbmltcG9ydCB7IFZhbGlkYXRpb25LZXlzLCBERUZBVUxUX0VSUk9SX01FU1NBR0VTIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBNYXhMZW5ndGhWYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgTWF4aW11bSBMZW5ndGggVmFsaWRhdG9yXG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdGVzIHN0cmluZ3MgYW5kIEFycmF5cyBvbiB0aGVpciBtYXhpbXVtIGxlbmd0aFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gZGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjTUFYX0xFTkdUSH1cbiAqXG4gKiBAY2xhc3MgTWluTGVuZ3RoVmFsaWRhdG9yXG4gKiBAZXh0ZW5kcyBWYWxpZGF0b3JcbiAqXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5AdmFsaWRhdG9yKFZhbGlkYXRpb25LZXlzLk1BWF9MRU5HVEgpXG5leHBvcnQgY2xhc3MgTWF4TGVuZ3RoVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPE1heExlbmd0aFZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5NQVhfTEVOR1RIKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgU3RyaW5nLm5hbWUsIEFycmF5Lm5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIG1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKiBAcGFyYW0ge01heExlbmd0aFZhbGlkYXRvck9wdGlvbnN9IG9wdGlvbnNcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBzdHJpbmcgfCBhbnlbXSxcbiAgICBvcHRpb25zOiBNYXhMZW5ndGhWYWxpZGF0b3JPcHRpb25zXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuO1xuICAgIHJldHVybiB2YWx1ZS5sZW5ndGggPiBvcHRpb25zLm1heGxlbmd0aFxuICAgICAgPyB0aGlzLmdldE1lc3NhZ2Uob3B0aW9ucy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSwgb3B0aW9ucy5tYXhsZW5ndGgpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgTWF4VmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3IgZm9yIGNoZWNraW5nIGlmIGEgdmFsdWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGEgbWF4aW11bVxuICogQHN1bW1hcnkgVGhlIE1heFZhbGlkYXRvciBjaGVja3MgaWYgYSBudW1lcmljIHZhbHVlLCBkYXRlLCBvciBzdHJpbmcgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvXG4gKiBhIHNwZWNpZmllZCBtYXhpbXVtIHZhbHVlLiBJdCBzdXBwb3J0cyBjb21wYXJpbmcgbnVtYmVycyBkaXJlY3RseSwgZGF0ZXMgY2hyb25vbG9naWNhbGx5LFxuICogYW5kIHN0cmluZ3MgbGV4aWNvZ3JhcGhpY2FsbHkuIFRoaXMgdmFsaWRhdG9yIGlzIHR5cGljYWxseSB1c2VkIHdpdGggdGhlIEBtYXggZGVjb3JhdG9yLlxuICogXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIHZhbGlkYXRpb24gZmFpbHMsIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI01BWH1cbiAqIFxuICogQGNsYXNzIE1heFZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBDcmVhdGUgYSBtYXggdmFsaWRhdG9yIHdpdGggZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBjb25zdCBtYXhWYWxpZGF0b3IgPSBuZXcgTWF4VmFsaWRhdG9yKCk7XG4gKiBcbiAqIC8vIENyZWF0ZSBhIG1heCB2YWxpZGF0b3Igd2l0aCBjdXN0b20gZXJyb3IgbWVzc2FnZVxuICogY29uc3QgY3VzdG9tTWF4VmFsaWRhdG9yID0gbmV3IE1heFZhbGlkYXRvcihcIlZhbHVlIG11c3Qgbm90IGV4Y2VlZCB7MH1cIik7XG4gKiBcbiAqIC8vIFZhbGlkYXRlIGEgbnVtYmVyXG4gKiBjb25zdCBudW1PcHRpb25zID0geyBtYXg6IDEwMCwgbWVzc2FnZTogXCJOdW1iZXIgdG9vIGxhcmdlXCIgfTtcbiAqIGNvbnN0IG51bVJlc3VsdCA9IG1heFZhbGlkYXRvci5oYXNFcnJvcnMoNTAsIG51bU9wdGlvbnMpOyAvLyB1bmRlZmluZWQgKHZhbGlkKVxuICogY29uc3QgaW52YWxpZE51bVJlc3VsdCA9IG1heFZhbGlkYXRvci5oYXNFcnJvcnMoMTUwLCBudW1PcHRpb25zKTsgLy8gUmV0dXJucyBlcnJvciBtZXNzYWdlIChpbnZhbGlkKVxuICogXG4gKiAvLyBWYWxpZGF0ZSBhIGRhdGVcbiAqIGNvbnN0IGRhdGVPcHRpb25zID0geyBtYXg6IG5ldyBEYXRlKDIwMjMsIDExLCAzMSkgfTtcbiAqIGNvbnN0IGRhdGVSZXN1bHQgPSBtYXhWYWxpZGF0b3IuaGFzRXJyb3JzKG5ldyBEYXRlKDIwMjMsIDUsIDE1KSwgZGF0ZU9wdGlvbnMpOyAvLyB1bmRlZmluZWQgKHZhbGlkKVxuICogYGBgXG4gKiBcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQyBhcyBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgViBhcyBNYXhWYWxpZGF0b3JcbiAqICAgXG4gKiAgIEMtPj5WOiBuZXcgTWF4VmFsaWRhdG9yKG1lc3NhZ2UpXG4gKiAgIEMtPj5WOiBoYXNFcnJvcnModmFsdWUsIG9wdGlvbnMpXG4gKiAgIGFsdCB2YWx1ZSBpcyB1bmRlZmluZWRcbiAqICAgICBWLS0+PkM6IHVuZGVmaW5lZCAodmFsaWQpXG4gKiAgIGVsc2UgdmFsdWUgaXMgRGF0ZSBhbmQgbWF4IGlzIG5vdCBEYXRlXG4gKiAgICAgVi0+PlY6IENvbnZlcnQgbWF4IHRvIERhdGVcbiAqICAgICBhbHQgY29udmVyc2lvbiBmYWlsc1xuICogICAgICAgVi0tPj5DOiBFcnJvcjogSW52YWxpZCBNYXggcGFyYW1cbiAqICAgICBlbmRcbiAqICAgZW5kXG4gKiAgIGFsdCB2YWx1ZSA+IG1heFxuICogICAgIFYtLT4+QzogRXJyb3IgbWVzc2FnZVxuICogICBlbHNlIHZhbHVlIDw9IG1heFxuICogICAgIFYtLT4+QzogdW5kZWZpbmVkICh2YWxpZClcbiAqICAgZW5kXG4gKiBcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuTUFYKVxuZXhwb3J0IGNsYXNzIE1heFZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvcjxNYXhWYWxpZGF0b3JPcHRpb25zPiB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuTUFYKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgXCJudW1iZXJcIiwgXCJEYXRlXCIsIFwic3RyaW5nXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYSB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gYSBtYXhpbXVtXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyB0aGF0IHRoZSBwcm92aWRlZCB2YWx1ZSBkb2VzIG5vdCBleGNlZWQgdGhlIG1heGltdW0gdmFsdWVcbiAgICogc3BlY2lmaWVkIGluIHRoZSBvcHRpb25zLiBGb3IgZGF0ZXMsIGl0IHBlcmZvcm1zIGNocm9ub2xvZ2ljYWwgY29tcGFyaXNvbixcbiAgICogY29udmVydGluZyBzdHJpbmcgcmVwcmVzZW50YXRpb25zIHRvIERhdGUgb2JqZWN0cyBpZiBuZWNlc3NhcnkuIEZvciBudW1iZXJzXG4gICAqIGFuZCBzdHJpbmdzLCBpdCBwZXJmb3JtcyBkaXJlY3QgY29tcGFyaXNvbi5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXIgfCBEYXRlIHwgc3RyaW5nfSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byB2YWxpZGF0ZVxuICAgKiBAcGFyYW0ge01heFZhbGlkYXRvck9wdGlvbnN9IG9wdGlvbnMgLSBDb25maWd1cmF0aW9uIG9wdGlvbnMgY29udGFpbmluZyB0aGUgbWF4aW11bSB2YWx1ZVxuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9IEVycm9yIG1lc3NhZ2UgaWYgdmFsaWRhdGlvbiBmYWlscywgdW5kZWZpbmVkIGlmIHZhbGlkYXRpb24gcGFzc2VzXG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IG51bWJlciB8IERhdGUgfCBzdHJpbmcsXG4gICAgb3B0aW9uczogTWF4VmFsaWRhdG9yT3B0aW9uc1xuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIpIHJldHVybjtcblxuICAgIGxldCB7IG1heCB9ID0gb3B0aW9ucztcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlICYmICEobWF4IGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgIG1heCA9IG5ldyBEYXRlKG1heCk7XG4gICAgICBpZiAoTnVtYmVyLmlzTmFOKG1heC5nZXREYXRlKCkpKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIE1heCBwYXJhbSBkZWZpbmVkXCIpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZSA+IG1heFxuICAgICAgPyB0aGlzLmdldE1lc3NhZ2Uob3B0aW9ucy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSwgbWF4KVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IE1pbkxlbmd0aFZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBNaW5pbXVtIExlbmd0aCBWYWxpZGF0b3JcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0ZXMgc3RyaW5ncyBhbmQgQXJyYXlzIG9uIHRoZWlyIG1pbmltdW0gbGVuZ3RoXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNNSU5fTEVOR1RIfVxuICpcbiAqIEBjbGFzcyBNaW5MZW5ndGhWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuTUlOX0xFTkdUSClcbmV4cG9ydCBjbGFzcyBNaW5MZW5ndGhWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3I8TWluTGVuZ3RoVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLk1JTl9MRU5HVEgpIHtcbiAgICBzdXBlcihtZXNzYWdlLCBTdHJpbmcubmFtZSwgQXJyYXkubmFtZSk7XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmcgfCBBcnJheX0gdmFsdWVcbiAgICogQHBhcmFtIHtNaW5MZW5ndGhWYWxpZGF0b3JPcHRpb25zfSBvcHRpb25zXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAgICpcbiAgICogQG1lbWJlck9mIE1pbkxlbmd0aFZhbGlkYXRvclxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBzdHJpbmcgfCBhbnlbXSxcbiAgICBvcHRpb25zOiBNaW5MZW5ndGhWYWxpZGF0b3JPcHRpb25zXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuO1xuICAgIHJldHVybiB2YWx1ZS5sZW5ndGggPCBvcHRpb25zLm1pbmxlbmd0aFxuICAgICAgPyB0aGlzLmdldE1lc3NhZ2Uob3B0aW9ucy5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSwgb3B0aW9ucy5taW5sZW5ndGgpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgTWluVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3IgZm9yIGNoZWNraW5nIGlmIGEgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGEgbWluaW11bVxuICogQHN1bW1hcnkgVGhlIE1pblZhbGlkYXRvciBjaGVja3MgaWYgYSBudW1lcmljIHZhbHVlLCBkYXRlLCBvciBzdHJpbmcgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvXG4gKiBhIHNwZWNpZmllZCBtaW5pbXVtIHZhbHVlLiBJdCBzdXBwb3J0cyBjb21wYXJpbmcgbnVtYmVycyBkaXJlY3RseSwgZGF0ZXMgY2hyb25vbG9naWNhbGx5LFxuICogYW5kIHN0cmluZ3MgbGV4aWNvZ3JhcGhpY2FsbHkuIFRoaXMgdmFsaWRhdG9yIGlzIHR5cGljYWxseSB1c2VkIHdpdGggdGhlIEBtaW4gZGVjb3JhdG9yLlxuICogXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIHZhbGlkYXRpb24gZmFpbHMsIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI01JTn1cbiAqIFxuICogQGNsYXNzIE1pblZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBDcmVhdGUgYSBtaW4gdmFsaWRhdG9yIHdpdGggZGVmYXVsdCBlcnJvciBtZXNzYWdlXG4gKiBjb25zdCBtaW5WYWxpZGF0b3IgPSBuZXcgTWluVmFsaWRhdG9yKCk7XG4gKiBcbiAqIC8vIENyZWF0ZSBhIG1pbiB2YWxpZGF0b3Igd2l0aCBjdXN0b20gZXJyb3IgbWVzc2FnZVxuICogY29uc3QgY3VzdG9tTWluVmFsaWRhdG9yID0gbmV3IE1pblZhbGlkYXRvcihcIlZhbHVlIG11c3QgYmUgYXQgbGVhc3QgezB9XCIpO1xuICogXG4gKiAvLyBWYWxpZGF0ZSBhIG51bWJlclxuICogY29uc3QgbnVtT3B0aW9ucyA9IHsgbWluOiAxMCwgbWVzc2FnZTogXCJOdW1iZXIgdG9vIHNtYWxsXCIgfTtcbiAqIGNvbnN0IG51bVJlc3VsdCA9IG1pblZhbGlkYXRvci5oYXNFcnJvcnMoNTAsIG51bU9wdGlvbnMpOyAvLyB1bmRlZmluZWQgKHZhbGlkKVxuICogY29uc3QgaW52YWxpZE51bVJlc3VsdCA9IG1pblZhbGlkYXRvci5oYXNFcnJvcnMoNSwgbnVtT3B0aW9ucyk7IC8vIFJldHVybnMgZXJyb3IgbWVzc2FnZSAoaW52YWxpZClcbiAqIFxuICogLy8gVmFsaWRhdGUgYSBkYXRlXG4gKiBjb25zdCBkYXRlT3B0aW9ucyA9IHsgbWluOiBuZXcgRGF0ZSgyMDIzLCAwLCAxKSB9O1xuICogY29uc3QgZGF0ZVJlc3VsdCA9IG1pblZhbGlkYXRvci5oYXNFcnJvcnMobmV3IERhdGUoMjAyMywgNSwgMTUpLCBkYXRlT3B0aW9ucyk7IC8vIHVuZGVmaW5lZCAodmFsaWQpXG4gKiBgYGBcbiAqIFxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENsaWVudFxuICogICBwYXJ0aWNpcGFudCBWIGFzIE1pblZhbGlkYXRvclxuICogICBcbiAqICAgQy0+PlY6IG5ldyBNaW5WYWxpZGF0b3IobWVzc2FnZSlcbiAqICAgQy0+PlY6IGhhc0Vycm9ycyh2YWx1ZSwgb3B0aW9ucylcbiAqICAgYWx0IHZhbHVlIGlzIHVuZGVmaW5lZFxuICogICAgIFYtLT4+QzogdW5kZWZpbmVkICh2YWxpZClcbiAqICAgZWxzZSB2YWx1ZSBpcyBEYXRlIGFuZCBtaW4gaXMgbm90IERhdGVcbiAqICAgICBWLT4+VjogQ29udmVydCBtaW4gdG8gRGF0ZVxuICogICAgIGFsdCBjb252ZXJzaW9uIGZhaWxzXG4gKiAgICAgICBWLS0+PkM6IEVycm9yOiBJbnZhbGlkIE1pbiBwYXJhbVxuICogICAgIGVuZFxuICogICBlbmRcbiAqICAgYWx0IHZhbHVlIDwgbWluXG4gKiAgICAgVi0tPj5DOiBFcnJvciBtZXNzYWdlXG4gKiAgIGVsc2UgdmFsdWUgPj0gbWluXG4gKiAgICAgVi0tPj5DOiB1bmRlZmluZWQgKHZhbGlkKVxuICogICBlbmRcbiAqIFxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5NSU4pXG5leHBvcnQgY2xhc3MgTWluVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yPE1pblZhbGlkYXRvck9wdGlvbnM+IHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5NSU4pIHtcbiAgICBzdXBlcihtZXNzYWdlLCBcIm51bWJlclwiLCBcIkRhdGVcIiwgXCJzdHJpbmdcIik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENoZWNrcyBpZiBhIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBhIG1pbmltdW1cbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIHRoYXQgdGhlIHByb3ZpZGVkIHZhbHVlIGlzIG5vdCBsZXNzIHRoYW4gdGhlIG1pbmltdW0gdmFsdWVcbiAgICogc3BlY2lmaWVkIGluIHRoZSBvcHRpb25zLiBGb3IgZGF0ZXMsIGl0IHBlcmZvcm1zIGNocm9ub2xvZ2ljYWwgY29tcGFyaXNvbixcbiAgICogY29udmVydGluZyBzdHJpbmcgcmVwcmVzZW50YXRpb25zIHRvIERhdGUgb2JqZWN0cyBpZiBuZWNlc3NhcnkuIEZvciBudW1iZXJzXG4gICAqIGFuZCBzdHJpbmdzLCBpdCBwZXJmb3JtcyBkaXJlY3QgY29tcGFyaXNvbi5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXIgfCBEYXRlIHwgc3RyaW5nfSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byB2YWxpZGF0ZVxuICAgKiBAcGFyYW0ge01pblZhbGlkYXRvck9wdGlvbnN9IG9wdGlvbnMgLSBDb25maWd1cmF0aW9uIG9wdGlvbnMgY29udGFpbmluZyB0aGUgbWluaW11bSB2YWx1ZVxuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9IEVycm9yIG1lc3NhZ2UgaWYgdmFsaWRhdGlvbiBmYWlscywgdW5kZWZpbmVkIGlmIHZhbGlkYXRpb24gcGFzc2VzXG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IG51bWJlciB8IERhdGUgfCBzdHJpbmcsXG4gICAgb3B0aW9uczogTWluVmFsaWRhdG9yT3B0aW9uc1xuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIpIHJldHVybjtcblxuICAgIGxldCB7IG1pbiB9ID0gb3B0aW9ucztcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlICYmICEobWluIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgIG1pbiA9IG5ldyBEYXRlKG1pbik7XG4gICAgICBpZiAoTnVtYmVyLmlzTmFOKG1pbi5nZXREYXRlKCkpKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIE1pbiBwYXJhbSBkZWZpbmVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWUgPCBtaW5cbiAgICAgID8gdGhpcy5nZXRNZXNzYWdlKG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsIG1pbilcbiAgICAgIDogdW5kZWZpbmVkO1xuICB9XG59XG4iLCJpbXBvcnQgeyBQYXR0ZXJuVmFsaWRhdG9yIH0gZnJvbSBcIi4vUGF0dGVyblZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IFBhdHRlcm5WYWxpZGF0b3JPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgSGFuZGxlcyBQYXNzd29yZCBWYWxpZGF0aW9uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFtlcnJvck1lc3NhZ2VdIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1BBU1NXT1JEfVxuICpcbiAqIEBjbGFzcyBQYXNzd29yZFZhbGlkYXRvclxuICogQGV4dGVuZHMgUGF0dGVyblZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuUEFTU1dPUkQpXG5leHBvcnQgY2xhc3MgUGFzc3dvcmRWYWxpZGF0b3IgZXh0ZW5kcyBQYXR0ZXJuVmFsaWRhdG9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZSA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuUEFTU1dPUkQpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSBtb2RlbFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtQYXR0ZXJuVmFsaWRhdG9yT3B0aW9uc30gW29wdGlvbnM9e31dXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgUGF0dGVyblZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IHN0cmluZyxcbiAgICBvcHRpb25zOiBQYXR0ZXJuVmFsaWRhdG9yT3B0aW9ucyA9IHt9XG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHN1cGVyLmhhc0Vycm9ycyh2YWx1ZSwge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIG1lc3NhZ2U6IG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsXG4gICAgfSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gXCIuL1ZhbGlkYXRvclwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IFZhbGlkYXRvck9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdG9yIGZvciBjaGVja2luZyBpZiBhIHZhbHVlIGlzIHByZXNlbnQgYW5kIG5vdCBlbXB0eVxuICogQHN1bW1hcnkgVGhlIFJlcXVpcmVkVmFsaWRhdG9yIGVuc3VyZXMgdGhhdCBhIHZhbHVlIGlzIHByb3ZpZGVkIGFuZCBub3QgZW1wdHkuXG4gKiBJdCBoYW5kbGVzIGRpZmZlcmVudCB0eXBlcyBvZiB2YWx1ZXMgYXBwcm9wcmlhdGVseTogZm9yIGJvb2xlYW5zIGFuZCBudW1iZXJzLFxuICogaXQgY2hlY2tzIGlmIHRoZXkncmUgdW5kZWZpbmVkOyBmb3Igb3RoZXIgdHlwZXMgKHN0cmluZ3MsIGFycmF5cywgb2JqZWN0cyksXG4gKiBpdCBjaGVja3MgaWYgdGhleSdyZSBmYWxzeS4gVGhpcyB2YWxpZGF0b3IgaXMgdHlwaWNhbGx5IHVzZWQgd2l0aCB0aGUgQHJlcXVpcmVkIGRlY29yYXRvclxuICogYW5kIGlzIG9mdGVuIHRoZSBmaXJzdCB2YWxpZGF0aW9uIGFwcGxpZWQgdG8gaW1wb3J0YW50IGZpZWxkcy5cbiAqIFxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSAtIEN1c3RvbSBlcnJvciBtZXNzYWdlIHRvIGRpc3BsYXkgd2hlbiB2YWxpZGF0aW9uIGZhaWxzLCBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNSRVFVSVJFRH1cbiAqIFxuICogQGNsYXNzIFJlcXVpcmVkVmFsaWRhdG9yXG4gKiBAZXh0ZW5kcyBWYWxpZGF0b3JcbiAqIFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIENyZWF0ZSBhIHJlcXVpcmVkIHZhbGlkYXRvciB3aXRoIGRlZmF1bHQgZXJyb3IgbWVzc2FnZVxuICogY29uc3QgcmVxdWlyZWRWYWxpZGF0b3IgPSBuZXcgUmVxdWlyZWRWYWxpZGF0b3IoKTtcbiAqIFxuICogLy8gQ3JlYXRlIGEgcmVxdWlyZWQgdmFsaWRhdG9yIHdpdGggY3VzdG9tIGVycm9yIG1lc3NhZ2VcbiAqIGNvbnN0IGN1c3RvbVJlcXVpcmVkVmFsaWRhdG9yID0gbmV3IFJlcXVpcmVkVmFsaWRhdG9yKFwiVGhpcyBmaWVsZCBpcyBtYW5kYXRvcnlcIik7XG4gKiBcbiAqIC8vIFZhbGlkYXRlIGRpZmZlcmVudCB0eXBlcyBvZiB2YWx1ZXNcbiAqIHJlcXVpcmVkVmFsaWRhdG9yLmhhc0Vycm9ycyhcIkhlbGxvXCIpOyAvLyB1bmRlZmluZWQgKHZhbGlkKVxuICogcmVxdWlyZWRWYWxpZGF0b3IuaGFzRXJyb3JzKFwiXCIpOyAvLyBSZXR1cm5zIGVycm9yIG1lc3NhZ2UgKGludmFsaWQpXG4gKiByZXF1aXJlZFZhbGlkYXRvci5oYXNFcnJvcnMoMCk7IC8vIHVuZGVmaW5lZCAodmFsaWQgLSAwIGlzIGEgdmFsaWQgbnVtYmVyKVxuICogcmVxdWlyZWRWYWxpZGF0b3IuaGFzRXJyb3JzKG51bGwpOyAvLyBSZXR1cm5zIGVycm9yIG1lc3NhZ2UgKGludmFsaWQpXG4gKiByZXF1aXJlZFZhbGlkYXRvci5oYXNFcnJvcnMoW10pOyAvLyB1bmRlZmluZWQgKHZhbGlkIC0gZW1wdHkgYXJyYXkgaXMgc3RpbGwgYW4gYXJyYXkpXG4gKiBgYGBcbiAqIFxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENsaWVudFxuICogICBwYXJ0aWNpcGFudCBWIGFzIFJlcXVpcmVkVmFsaWRhdG9yXG4gKiAgIFxuICogICBDLT4+VjogbmV3IFJlcXVpcmVkVmFsaWRhdG9yKG1lc3NhZ2UpXG4gKiAgIEMtPj5WOiBoYXNFcnJvcnModmFsdWUsIG9wdGlvbnMpXG4gKiAgIGFsdCB0eXBlb2YgdmFsdWUgaXMgYm9vbGVhbiBvciBudW1iZXJcbiAqICAgICBhbHQgdmFsdWUgaXMgdW5kZWZpbmVkXG4gKiAgICAgICBWLS0+PkM6IEVycm9yIG1lc3NhZ2VcbiAqICAgICBlbHNlIHZhbHVlIGlzIGRlZmluZWRcbiAqICAgICAgIFYtLT4+QzogdW5kZWZpbmVkICh2YWxpZClcbiAqICAgICBlbmRcbiAqICAgZWxzZSBvdGhlciB0eXBlc1xuICogICAgIGFsdCB2YWx1ZSBpcyBmYWxzeSAobnVsbCwgdW5kZWZpbmVkLCBlbXB0eSBzdHJpbmcpXG4gKiAgICAgICBWLS0+PkM6IEVycm9yIG1lc3NhZ2VcbiAqICAgICBlbHNlIHZhbHVlIGlzIHRydXRoeVxuICogICAgICAgVi0tPj5DOiB1bmRlZmluZWQgKHZhbGlkKVxuICogICAgIGVuZFxuICogICBlbmRcbiAqIFxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihWYWxpZGF0aW9uS2V5cy5SRVFVSVJFRClcbmV4cG9ydCBjbGFzcyBSZXF1aXJlZFZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuUkVRVUlSRUQpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ2hlY2tzIGlmIGEgdmFsdWUgaXMgcHJlc2VudCBhbmQgbm90IGVtcHR5XG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyB0aGF0IHRoZSBwcm92aWRlZCB2YWx1ZSBleGlzdHMgYW5kIGlzIG5vdCBlbXB0eS5cbiAgICogVGhlIHZhbGlkYXRpb24gbG9naWMgdmFyaWVzIGJ5IHR5cGU6XG4gICAqIC0gRm9yIGJvb2xlYW5zIGFuZCBudW1iZXJzOiBjaGVja3MgaWYgdGhlIHZhbHVlIGlzIHVuZGVmaW5lZFxuICAgKiAtIEZvciBvdGhlciB0eXBlcyAoc3RyaW5ncywgYXJyYXlzLCBvYmplY3RzKTogY2hlY2tzIGlmIHRoZSB2YWx1ZSBpcyBmYWxzeVxuICAgKlxuICAgKiBAcGFyYW0ge2FueX0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gdmFsaWRhdGVcbiAgICogQHBhcmFtIHtWYWxpZGF0b3JPcHRpb25zfSBbb3B0aW9ucz17fV0gLSBPcHRpb25hbCBjb25maWd1cmF0aW9uIG9wdGlvbnNcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfSBFcnJvciBtZXNzYWdlIGlmIHZhbGlkYXRpb24gZmFpbHMsIHVuZGVmaW5lZCBpZiB2YWxpZGF0aW9uIHBhc3Nlc1xuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBWYWxpZGF0b3IjaGFzRXJyb3JzXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKFxuICAgIHZhbHVlOiBhbnksXG4gICAgb3B0aW9uczogVmFsaWRhdG9yT3B0aW9ucyA9IHt9XG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgc3dpdGNoICh0eXBlb2YgdmFsdWUpIHtcbiAgICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCJcbiAgICAgICAgICA/IHRoaXMuZ2V0TWVzc2FnZShvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlKVxuICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuICF2YWx1ZVxuICAgICAgICAgID8gdGhpcy5nZXRNZXNzYWdlKG9wdGlvbnMubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tIFwiLi9WYWxpZGF0b3JcIjtcbmltcG9ydCB7IERFRkFVTFRfRVJST1JfTUVTU0FHRVMsIFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBTdGVwVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFN0ZXAgVmFsaWRhdG9yXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNTVEVQfVxuICpcbiAqIEBjbGFzcyBTdGVwVmFsaWRhdG9yXG4gKiBAZXh0ZW5kcyBWYWxpZGF0b3JcbiAqXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5AdmFsaWRhdG9yKFZhbGlkYXRpb25LZXlzLlNURVApXG5leHBvcnQgY2xhc3MgU3RlcFZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvcjxTdGVwVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlNURVApIHtcbiAgICBzdXBlcihtZXNzYWdlLCBcIm51bWJlclwiLCBcInN0cmluZ1wiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSBtb2RlbFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0ZXBcbiAgICogQHBhcmFtIHtTdGVwVmFsaWRhdG9yT3B0aW9uc30gb3B0aW9uc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9XG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IG51bWJlciB8IHN0cmluZyxcbiAgICBvcHRpb25zOiBTdGVwVmFsaWRhdG9yT3B0aW9uc1xuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIpIHJldHVybjtcbiAgICByZXR1cm4gTnVtYmVyKHZhbHVlKSAlIE51bWJlcihvcHRpb25zLnN0ZXApICE9PSAwXG4gICAgICA/IHRoaXMuZ2V0TWVzc2FnZShvcHRpb25zLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlLCBvcHRpb25zLnN0ZXApXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSBcIi4vVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgdmFsaWRhdG9yIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgVmFsaWRhdGlvbiB9IGZyb20gXCIuLi9WYWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBUeXBlVmFsaWRhdG9yT3B0aW9ucywgVmFsaWRhdG9yRGVmaW5pdGlvbiB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgTW9kZWxLZXlzIH0gZnJvbSBcIi4uLy4uL3V0aWxzL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgUmVmbGVjdGlvbiB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3IgZm9yIGNoZWNraW5nIGlmIGEgdmFsdWUgaXMgb2YgdGhlIGV4cGVjdGVkIHR5cGUocylcbiAqIEBzdW1tYXJ5IFRoZSBUeXBlVmFsaWRhdG9yIGVuc3VyZXMgdGhhdCBhIHZhbHVlIG1hdGNoZXMgb25lIG9mIHRoZSBzcGVjaWZpZWQgdHlwZXMuXG4gKiBJdCBjYW4gdmFsaWRhdGUgYWdhaW5zdCBhIHNpbmdsZSB0eXBlLCBtdWx0aXBsZSB0eXBlcywgb3IgYSB0eXBlIHdpdGggYSBzcGVjaWZpYyBuYW1lLlxuICogVGhpcyB2YWxpZGF0b3IgaXMgdHlwaWNhbGx5IHVzZWQgd2l0aCB0aGUgQHR5cGUgZGVjb3JhdG9yIGFuZCBpcyBmdW5kYW1lbnRhbCBmb3JcbiAqIGVuc3VyaW5nIHR5cGUgc2FmZXR5IGluIHZhbGlkYXRlZCBtb2RlbHMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSAtIEN1c3RvbSBlcnJvciBtZXNzYWdlIHRvIGRpc3BsYXkgd2hlbiB2YWxpZGF0aW9uIGZhaWxzLCBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNUWVBFfVxuICpcbiAqIEBjbGFzcyBUeXBlVmFsaWRhdG9yXG4gKiBAZXh0ZW5kcyBWYWxpZGF0b3JcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gQ3JlYXRlIGEgdHlwZSB2YWxpZGF0b3Igd2l0aCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIGNvbnN0IHR5cGVWYWxpZGF0b3IgPSBuZXcgVHlwZVZhbGlkYXRvcigpO1xuICpcbiAqIC8vIENyZWF0ZSBhIHR5cGUgdmFsaWRhdG9yIHdpdGggY3VzdG9tIGVycm9yIG1lc3NhZ2VcbiAqIGNvbnN0IGN1c3RvbVR5cGVWYWxpZGF0b3IgPSBuZXcgVHlwZVZhbGlkYXRvcihcIlZhbHVlIG11c3QgYmUgb2YgdHlwZSB7MH0sIGJ1dCBnb3QgezF9XCIpO1xuICpcbiAqIC8vIFZhbGlkYXRlIGFnYWluc3QgYSBzaW5nbGUgdHlwZVxuICogY29uc3Qgc3RyaW5nT3B0aW9ucyA9IHsgdHlwZXM6IFwic3RyaW5nXCIgfTtcbiAqIHR5cGVWYWxpZGF0b3IuaGFzRXJyb3JzKFwiaGVsbG9cIiwgc3RyaW5nT3B0aW9ucyk7IC8vIHVuZGVmaW5lZCAodmFsaWQpXG4gKiB0eXBlVmFsaWRhdG9yLmhhc0Vycm9ycygxMjMsIHN0cmluZ09wdGlvbnMpOyAvLyBSZXR1cm5zIGVycm9yIG1lc3NhZ2UgKGludmFsaWQpXG4gKlxuICogLy8gVmFsaWRhdGUgYWdhaW5zdCBtdWx0aXBsZSB0eXBlc1xuICogY29uc3QgbXVsdGlPcHRpb25zID0geyB0eXBlczogW1wic3RyaW5nXCIsIFwibnVtYmVyXCJdIH07XG4gKiB0eXBlVmFsaWRhdG9yLmhhc0Vycm9ycyhcImhlbGxvXCIsIG11bHRpT3B0aW9ucyk7IC8vIHVuZGVmaW5lZCAodmFsaWQpXG4gKiB0eXBlVmFsaWRhdG9yLmhhc0Vycm9ycygxMjMsIG11bHRpT3B0aW9ucyk7IC8vIHVuZGVmaW5lZCAodmFsaWQpXG4gKiB0eXBlVmFsaWRhdG9yLmhhc0Vycm9ycyh0cnVlLCBtdWx0aU9wdGlvbnMpOyAvLyBSZXR1cm5zIGVycm9yIG1lc3NhZ2UgKGludmFsaWQpXG4gKlxuICogLy8gVmFsaWRhdGUgYWdhaW5zdCBhIGNsYXNzIHR5cGVcbiAqIGNvbnN0IGNsYXNzT3B0aW9ucyA9IHsgdHlwZXM6IHsgbmFtZTogXCJEYXRlXCIgfSB9O1xuICogdHlwZVZhbGlkYXRvci5oYXNFcnJvcnMobmV3IERhdGUoKSwgY2xhc3NPcHRpb25zKTsgLy8gdW5kZWZpbmVkICh2YWxpZClcbiAqIGBgYFxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQyBhcyBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgViBhcyBUeXBlVmFsaWRhdG9yXG4gKiAgIHBhcnRpY2lwYW50IFIgYXMgUmVmbGVjdGlvblxuICpcbiAqICAgQy0+PlY6IG5ldyBUeXBlVmFsaWRhdG9yKG1lc3NhZ2UpXG4gKiAgIEMtPj5WOiBoYXNFcnJvcnModmFsdWUsIG9wdGlvbnMpXG4gKiAgIGFsdCB2YWx1ZSBpcyB1bmRlZmluZWRcbiAqICAgICBWLS0+PkM6IHVuZGVmaW5lZCAodmFsaWQpXG4gKiAgIGVsc2UgdmFsdWUgaXMgZGVmaW5lZFxuICogICAgIFYtPj5SOiBldmFsdWF0ZURlc2lnblR5cGVzKHZhbHVlLCB0eXBlcylcbiAqICAgICBhbHQgdHlwZSBldmFsdWF0aW9uIHBhc3Nlc1xuICogICAgICAgVi0tPj5DOiB1bmRlZmluZWQgKHZhbGlkKVxuICogICAgIGVsc2UgdHlwZSBldmFsdWF0aW9uIGZhaWxzXG4gKiAgICAgICBWLT4+VjogRm9ybWF0IGVycm9yIG1lc3NhZ2Ugd2l0aCB0eXBlIGluZm9cbiAqICAgICAgIFYtLT4+QzogRXJyb3IgbWVzc2FnZVxuICogICAgIGVuZFxuICogICBlbmRcbiAqXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5AdmFsaWRhdG9yKFZhbGlkYXRpb25LZXlzLlRZUEUpXG5leHBvcnQgY2xhc3MgVHlwZVZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvcjxUeXBlVmFsaWRhdG9yT3B0aW9ucz4ge1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlRZUEUpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ2hlY2tzIGlmIGEgdmFsdWUgaXMgb2YgdGhlIGV4cGVjdGVkIHR5cGUocylcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIHRoYXQgdGhlIHByb3ZpZGVkIHZhbHVlIG1hdGNoZXMgb25lIG9mIHRoZSBzcGVjaWZpZWQgdHlwZXMuXG4gICAqIEl0IHVzZXMgdGhlIFJlZmxlY3Rpb24gdXRpbGl0eSB0byBldmFsdWF0ZSBpZiB0aGUgdmFsdWUncyB0eXBlIG1hdGNoZXMgdGhlIGV4cGVjdGVkIHR5cGVzLlxuICAgKiBUaGUgbWV0aG9kIHNraXBzIHZhbGlkYXRpb24gZm9yIHVuZGVmaW5lZCB2YWx1ZXMgdG8gYXZvaWQgY29uZmxpY3RzIHdpdGggdGhlIFJlcXVpcmVkVmFsaWRhdG9yLlxuICAgKlxuICAgKiBAcGFyYW0ge2FueX0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gdmFsaWRhdGVcbiAgICogQHBhcmFtIHtUeXBlVmFsaWRhdG9yT3B0aW9uc30gb3B0aW9ucyAtIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBjb250YWluaW5nIHRoZSBleHBlY3RlZCB0eXBlc1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9IEVycm9yIG1lc3NhZ2UgaWYgdmFsaWRhdGlvbiBmYWlscywgdW5kZWZpbmVkIGlmIHZhbGlkYXRpb24gcGFzc2VzXG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKlxuICAgKiBAc2VlIFZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IGFueSxcbiAgICBvcHRpb25zOiBUeXBlVmFsaWRhdG9yT3B0aW9uc1xuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm47IC8vIERvbid0IHRyeSBhbmQgZW5mb3JjZSB0eXBlIGlmIHVuZGVmaW5lZFxuICAgIGNvbnN0IHsgdHlwZXMsIG1lc3NhZ2UgfSA9IG9wdGlvbnM7XG4gICAgaWYgKCFSZWZsZWN0aW9uLmV2YWx1YXRlRGVzaWduVHlwZXModmFsdWUsIHR5cGVzKSlcbiAgICAgIHJldHVybiB0aGlzLmdldE1lc3NhZ2UoXG4gICAgICAgIG1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlLFxuICAgICAgICB0eXBlb2YgdHlwZXMgPT09IFwic3RyaW5nXCJcbiAgICAgICAgICA/IHR5cGVzXG4gICAgICAgICAgOiBBcnJheS5pc0FycmF5KHR5cGVzKVxuICAgICAgICAgICAgPyB0eXBlcy5qb2luKFwiLCBcIilcbiAgICAgICAgICAgIDogdHlwZXMubmFtZSxcbiAgICAgICAgdHlwZW9mIHZhbHVlXG4gICAgICApO1xuICB9XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFJlZ2lzdGVyIHRoZSBUeXBlVmFsaWRhdG9yIHdpdGggdGhlIFZhbGlkYXRpb24gcmVnaXN0cnlcbiAqIEBzdW1tYXJ5IFRoaXMgcmVnaXN0cmF0aW9uIGFzc29jaWF0ZXMgdGhlIFR5cGVWYWxpZGF0b3Igd2l0aCB0aGUgTW9kZWxLZXlzLlRZUEUga2V5LFxuICogYWxsb3dpbmcgaXQgdG8gYmUgdXNlZCBmb3IgdmFsaWRhdGluZyBkZXNpZ24gdHlwZXMuIFRoZSBzYXZlIGZsYWcgaXMgc2V0IHRvIGZhbHNlXG4gKiB0byBwcmV2ZW50IHRoZSB2YWxpZGF0b3IgZnJvbSBiZWluZyBzYXZlZCBpbiB0aGUgc3RhbmRhcmQgdmFsaWRhdG9yIHJlZ2lzdHJ5LlxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqL1xuVmFsaWRhdGlvbi5yZWdpc3Rlcih7XG4gIHZhbGlkYXRvcjogVHlwZVZhbGlkYXRvcixcbiAgdmFsaWRhdGlvbktleTogTW9kZWxLZXlzLlRZUEUsXG4gIHNhdmU6IGZhbHNlLFxufSBhcyBWYWxpZGF0b3JEZWZpbml0aW9uKTtcbiIsImltcG9ydCB7XG4gIFZhbGlkYXRpb25LZXlzLFxuICBERUZBVUxUX0VSUk9SX01FU1NBR0VTLFxuICBERUZBVUxUX1BBVFRFUk5TLFxufSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFBhdHRlcm5WYWxpZGF0b3IgfSBmcm9tIFwiLi9QYXR0ZXJuVmFsaWRhdG9yXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBQYXR0ZXJuVmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3IgZm9yIGNoZWNraW5nIGlmIGEgc3RyaW5nIGlzIGEgdmFsaWQgVVJMXG4gKiBAc3VtbWFyeSBUaGUgVVJMVmFsaWRhdG9yIGNoZWNrcyBpZiBhIHN0cmluZyBtYXRjaGVzIGEgc3RhbmRhcmQgVVJMIHBhdHRlcm4uXG4gKiBJdCBleHRlbmRzIHRoZSBQYXR0ZXJuVmFsaWRhdG9yIGFuZCB1c2VzIGEgcm9idXN0IFVSTCByZWdleCBwYXR0ZXJuIHRvIHZhbGlkYXRlIHdlYiBhZGRyZXNzZXMuXG4gKiBUaGUgcGF0dGVybiBpcyBzb3VyY2VkIGZyb20ge0BsaW5rIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL2RwZXJpbmkvNzI5Mjk0fSBhbmQgaXMgd2lkZWx5XG4gKiByZWNvZ25pemVkIGZvciBpdHMgYWNjdXJhY3kgaW4gdmFsaWRhdGluZyBVUkxzLiBUaGlzIHZhbGlkYXRvciBpcyB0eXBpY2FsbHkgdXNlZCB3aXRoIHRoZSBAdXJsIGRlY29yYXRvci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSB3aGVuIHZhbGlkYXRpb24gZmFpbHMsIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1VSTH1cbiAqXG4gKiBAY2xhc3MgVVJMVmFsaWRhdG9yXG4gKiBAZXh0ZW5kcyBQYXR0ZXJuVmFsaWRhdG9yXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIENyZWF0ZSBhIFVSTCB2YWxpZGF0b3Igd2l0aCBkZWZhdWx0IGVycm9yIG1lc3NhZ2VcbiAqIGNvbnN0IHVybFZhbGlkYXRvciA9IG5ldyBVUkxWYWxpZGF0b3IoKTtcbiAqXG4gKiAvLyBDcmVhdGUgYSBVUkwgdmFsaWRhdG9yIHdpdGggY3VzdG9tIGVycm9yIG1lc3NhZ2VcbiAqIGNvbnN0IGN1c3RvbVVybFZhbGlkYXRvciA9IG5ldyBVUkxWYWxpZGF0b3IoXCJQbGVhc2UgZW50ZXIgYSB2YWxpZCB3ZWIgYWRkcmVzc1wiKTtcbiAqXG4gKiAvLyBWYWxpZGF0ZSBhIFVSTFxuICogY29uc3QgcmVzdWx0ID0gdXJsVmFsaWRhdG9yLmhhc0Vycm9ycyhcImh0dHBzOi8vZXhhbXBsZS5jb21cIik7IC8vIHVuZGVmaW5lZCAodmFsaWQpXG4gKiBjb25zdCBpbnZhbGlkUmVzdWx0ID0gdXJsVmFsaWRhdG9yLmhhc0Vycm9ycyhcIm5vdC1hLXVybFwiKTsgLy8gUmV0dXJucyBlcnJvciBtZXNzYWdlIChpbnZhbGlkKVxuICogYGBgXG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENsaWVudFxuICogICBwYXJ0aWNpcGFudCBVIGFzIFVSTFZhbGlkYXRvclxuICogICBwYXJ0aWNpcGFudCBQIGFzIFBhdHRlcm5WYWxpZGF0b3JcbiAqXG4gKiAgIEMtPj5VOiBuZXcgVVJMVmFsaWRhdG9yKG1lc3NhZ2UpXG4gKiAgIFUtPj5QOiBzdXBlcihtZXNzYWdlKVxuICogICBDLT4+VTogaGFzRXJyb3JzKHZhbHVlLCBvcHRpb25zKVxuICogICBVLT4+UDogc3VwZXIuaGFzRXJyb3JzKHZhbHVlLCBvcHRpb25zIHdpdGggVVJMIHBhdHRlcm4pXG4gKiAgIFAtLT4+VTogdmFsaWRhdGlvbiByZXN1bHRcbiAqICAgVS0tPj5DOiB2YWxpZGF0aW9uIHJlc3VsdFxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVmFsaWRhdGlvbktleXMuVVJMKVxuZXhwb3J0IGNsYXNzIFVSTFZhbGlkYXRvciBleHRlbmRzIFBhdHRlcm5WYWxpZGF0b3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlVSTCkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYSBzdHJpbmcgaXMgYSB2YWxpZCBVUkxcbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIHRoYXQgdGhlIHByb3ZpZGVkIHN0cmluZyBtYXRjaGVzIHRoZSBVUkwgcGF0dGVybi5cbiAgICogVGhpcyBtZXRob2QgZXh0ZW5kcyB0aGUgUGF0dGVyblZhbGlkYXRvcidzIGhhc0Vycm9ycyBtZXRob2QgYnkgZW5zdXJpbmdcbiAgICogdGhlIFVSTCBwYXR0ZXJuIGlzIHVzZWQsIGV2ZW4gaWYgbm90IGV4cGxpY2l0bHkgcHJvdmlkZWQgaW4gdGhlIG9wdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSAtIFRoZSBzdHJpbmcgdG8gdmFsaWRhdGUgYXMgYSBVUkxcbiAgICogQHBhcmFtIHtQYXR0ZXJuVmFsaWRhdG9yT3B0aW9uc30gW29wdGlvbnM9e31dIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvbiBvcHRpb25zXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH0gRXJyb3IgbWVzc2FnZSBpZiB2YWxpZGF0aW9uIGZhaWxzLCB1bmRlZmluZWQgaWYgdmFsaWRhdGlvbiBwYXNzZXNcbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgUGF0dGVyblZhbGlkYXRvciNoYXNFcnJvcnNcbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBoYXNFcnJvcnMoXG4gICAgdmFsdWU6IHN0cmluZyxcbiAgICBvcHRpb25zOiBQYXR0ZXJuVmFsaWRhdG9yT3B0aW9ucyA9IHt9XG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHN1cGVyLmhhc0Vycm9ycyh2YWx1ZSwge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIHBhdHRlcm46IG9wdGlvbnMucGF0dGVybiB8fCBERUZBVUxUX1BBVFRFUk5TLlVSTCxcbiAgICB9KTtcbiAgfVxufVxuIiwiaW1wb3J0IFwicmVmbGVjdC1tZXRhZGF0YVwiO1xuaW1wb3J0IHtcbiAgRGlmZlZhbGlkYXRvck9wdGlvbnMsXG4gIEVxdWFsc1ZhbGlkYXRvck9wdGlvbnMsXG4gIEdyZWF0ZXJUaGFuT3JFcXVhbFZhbGlkYXRvck9wdGlvbnMsXG4gIEdyZWF0ZXJUaGFuVmFsaWRhdG9yT3B0aW9ucyxcbiAgTGVzc1RoYW5PckVxdWFsVmFsaWRhdG9yT3B0aW9ucyxcbiAgTGVzc1RoYW5WYWxpZGF0b3JPcHRpb25zLFxuICBWYWxpZGF0aW9uTWV0YWRhdGEsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQge1xuICBERUZBVUxUX0VSUk9SX01FU1NBR0VTLFxuICBERUZBVUxUX1BBVFRFUk5TLFxuICBWYWxpZGF0aW9uS2V5cyxcbn0gZnJvbSBcIi4vVmFsaWRhdG9ycy9jb25zdGFudHNcIjtcbmltcG9ydCB7IHNmIH0gZnJvbSBcIi4uL3V0aWxzL3N0cmluZ3NcIjtcbmltcG9ydCB7IE1vZGVsQ29uc3RydWN0b3IgfSBmcm9tIFwiLi4vbW9kZWwvdHlwZXNcIjtcbmltcG9ydCB7IHBhcnNlRGF0ZSB9IGZyb20gXCIuLi91dGlscy9kYXRlc1wiO1xuaW1wb3J0IHsgcHJvcE1ldGFkYXRhIH0gZnJvbSBcIi4uL3V0aWxzL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IFZhbGlkYXRpb24gfSBmcm9tIFwiLi9WYWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBEZWNvcmF0aW9uIH0gZnJvbSBcIi4uL3V0aWxzL0RlY29yYXRpb25cIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUHJvcGVydHkgZGVjb3JhdG9yIHRoYXQgbWFya3MgYSBmaWVsZCBhcyByZXF1aXJlZFxuICogQHN1bW1hcnkgTWFya3MgdGhlIHByb3BlcnR5IGFzIHJlcXVpcmVkLCBjYXVzaW5nIHZhbGlkYXRpb24gdG8gZmFpbCBpZiB0aGUgcHJvcGVydHkgaXMgdW5kZWZpbmVkLCBudWxsLCBvciBlbXB0eS5cbiAqIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNSRVFVSVJFRH0uXG4gKiBUaGlzIGRlY29yYXRvciBpcyBjb21tb25seSB1c2VkIGFzIHRoZSBmaXJzdCB2YWxpZGF0aW9uIHN0ZXAgZm9yIGltcG9ydGFudCBmaWVsZHMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSAtIFRoZSBlcnJvciBtZXNzYWdlIHRvIGRpc3BsYXkgd2hlbiB2YWxpZGF0aW9uIGZhaWxzLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNSRVFVSVJFRH1cbiAqIEByZXR1cm4ge1Byb3BlcnR5RGVjb3JhdG9yfSBBIGRlY29yYXRvciBmdW5jdGlvbiB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGNsYXNzIHByb3BlcnRpZXNcbiAqXG4gKiBAZnVuY3Rpb24gcmVxdWlyZWRcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNsYXNzIFVzZXIge1xuICogICBAcmVxdWlyZWQoKVxuICogICB1c2VybmFtZTogc3RyaW5nO1xuICpcbiAqICAgQHJlcXVpcmVkKFwiRW1haWwgYWRkcmVzcyBpcyBtYW5kYXRvcnlcIilcbiAqICAgZW1haWw6IHN0cmluZztcbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZWQobWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5SRVFVSVJFRCkge1xuICBjb25zdCBrZXkgPSBWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5SRVFVSVJFRCk7XG4gIHJldHVybiBEZWNvcmF0aW9uLmZvcihrZXkpXG4gICAgLmRlZmluZShcbiAgICAgIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KGtleSwge1xuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgfSlcbiAgICApXG4gICAgLmFwcGx5KCk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFByb3BlcnR5IGRlY29yYXRvciB0aGF0IGVuZm9yY2VzIGEgbWluaW11bSB2YWx1ZSBjb25zdHJhaW50XG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgbWluaW11bSB2YWx1ZSBmb3IgdGhlIHByb3BlcnR5LCBjYXVzaW5nIHZhbGlkYXRpb24gdG8gZmFpbCBpZiB0aGUgcHJvcGVydHkgdmFsdWUgaXMgbGVzcyB0aGFuIHRoZSBzcGVjaWZpZWQgbWluaW11bS5cbiAqIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNNSU59LlxuICogVGhpcyBkZWNvcmF0b3Igd29ya3Mgd2l0aCBudW1lcmljIHZhbHVlcyBhbmQgZGF0ZXMuXG4gKlxuICogQHBhcmFtIHtudW1iZXIgfCBEYXRlIHwgc3RyaW5nfSB2YWx1ZSAtIFRoZSBtaW5pbXVtIHZhbHVlIGFsbG93ZWQuIEZvciBkYXRlcywgY2FuIGJlIGEgRGF0ZSBvYmplY3Qgb3IgYSBzdHJpbmcgdGhhdCBjYW4gYmUgY29udmVydGVkIHRvIGEgZGF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSAtIFRoZSBlcnJvciBtZXNzYWdlIHRvIGRpc3BsYXkgd2hlbiB2YWxpZGF0aW9uIGZhaWxzLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNNSU59XG4gKiBAcmV0dXJuIHtQcm9wZXJ0eURlY29yYXRvcn0gQSBkZWNvcmF0b3IgZnVuY3Rpb24gdGhhdCBjYW4gYmUgYXBwbGllZCB0byBjbGFzcyBwcm9wZXJ0aWVzXG4gKlxuICogQGZ1bmN0aW9uIG1pblxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY2xhc3MgUHJvZHVjdCB7XG4gKiAgIEBtaW4oMClcbiAqICAgcHJpY2U6IG51bWJlcjtcbiAqXG4gKiAgIEBtaW4obmV3IERhdGUoMjAyMywgMCwgMSksIFwiRGF0ZSBtdXN0IGJlIGFmdGVyIEphbnVhcnkgMSwgMjAyM1wiKVxuICogICByZWxlYXNlRGF0ZTogRGF0ZTtcbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gbWluKFxuICB2YWx1ZTogbnVtYmVyIHwgRGF0ZSB8IHN0cmluZyxcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5NSU5cbikge1xuICBjb25zdCBrZXkgPSBWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5NSU4pO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoXG4gICAgICBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihrZXksIHtcbiAgICAgICAgW1ZhbGlkYXRpb25LZXlzLk1JTl06IHZhbHVlLFxuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICB0eXBlczogW051bWJlci5uYW1lLCBEYXRlLm5hbWVdLFxuICAgICAgfSlcbiAgICApXG4gICAgLmFwcGx5KCk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIG1heGltdW0gdmFsdWUgZm9yIHRoZSBwcm9wZXJ0eVxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNNQVh9XG4gKlxuICogQHBhcmFtIHtudW1iZXIgfCBEYXRlfSB2YWx1ZVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjTUFYfVxuICpcbiAqIEBmdW5jdGlvbiBtYXhcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXgoXG4gIHZhbHVlOiBudW1iZXIgfCBEYXRlIHwgc3RyaW5nLFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLk1BWFxuKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLk1BWCk7XG4gIHJldHVybiBEZWNvcmF0aW9uLmZvcihrZXkpXG4gICAgLmRlZmluZShcbiAgICAgIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KGtleSwge1xuICAgICAgICBbVmFsaWRhdGlvbktleXMuTUFYXTogdmFsdWUsXG4gICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICAgIHR5cGVzOiBbTnVtYmVyLm5hbWUsIERhdGUubmFtZV0sXG4gICAgICB9KVxuICAgIClcbiAgICAuYXBwbHkoKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgc3RlcCB2YWx1ZSBmb3IgdGhlIHByb3BlcnR5XG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdG9ycyB0byB2YWxpZGF0ZSBhIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IHVzZSBrZXkge0BsaW5rIFZhbGlkYXRpb25LZXlzI1NURVB9XG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIHRoZSBlcnJvciBtZXNzYWdlLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNTVEVQfVxuICpcbiAqIEBmdW5jdGlvbiBzdGVwXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gc3RlcChcbiAgdmFsdWU6IG51bWJlcixcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5TVEVQXG4pIHtcbiAgY29uc3Qga2V5ID0gVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuU1RFUCk7XG4gIHJldHVybiBEZWNvcmF0aW9uLmZvcihrZXkpXG4gICAgLmRlZmluZShcbiAgICAgIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KGtleSwge1xuICAgICAgICBbVmFsaWRhdGlvbktleXMuU1RFUF06IHZhbHVlLFxuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICB0eXBlczogW051bWJlci5uYW1lXSxcbiAgICAgIH0pXG4gICAgKVxuICAgIC5hcHBseSgpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBtaW5pbXVtIGxlbmd0aCBmb3IgdGhlIHByb3BlcnR5XG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdG9ycyB0byB2YWxpZGF0ZSBhIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IHVzZSBrZXkge0BsaW5rIFZhbGlkYXRpb25LZXlzI01JTl9MRU5HVEh9XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIHRoZSBlcnJvciBtZXNzYWdlLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNNSU5fTEVOR1RIfVxuICpcbiAqIEBmdW5jdGlvbiBtaW5sZW5ndGhcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtaW5sZW5ndGgoXG4gIHZhbHVlOiBudW1iZXIsXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuTUlOX0xFTkdUSFxuKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLk1JTl9MRU5HVEgpO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoXG4gICAgICBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihrZXksIHtcbiAgICAgICAgW1ZhbGlkYXRpb25LZXlzLk1JTl9MRU5HVEhdOiB2YWx1ZSxcbiAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgICAgdHlwZXM6IFtTdHJpbmcubmFtZSwgQXJyYXkubmFtZSwgU2V0Lm5hbWVdLFxuICAgICAgfSlcbiAgICApXG4gICAgLmFwcGx5KCk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIG1heGltdW0gbGVuZ3RoIGZvciB0aGUgcHJvcGVydHlcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3JzIHRvIHZhbGlkYXRlIGEgZGVjb3JhdGVkIHByb3BlcnR5IG11c3QgdXNlIGtleSB7QGxpbmsgVmFsaWRhdGlvbktleXMjTUFYX0xFTkdUSH1cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gdGhlIGVycm9yIG1lc3NhZ2UuIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI01BWF9MRU5HVEh9XG4gKlxuICogQGZ1bmN0aW9uIG1heGxlbmd0aFxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1heGxlbmd0aChcbiAgdmFsdWU6IG51bWJlcixcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5NQVhfTEVOR1RIXG4pIHtcbiAgY29uc3Qga2V5ID0gVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuTUFYX0xFTkdUSCk7XG4gIHJldHVybiBEZWNvcmF0aW9uLmZvcihrZXkpXG4gICAgLmRlZmluZShcbiAgICAgIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KGtleSwge1xuICAgICAgICBbVmFsaWRhdGlvbktleXMuTUFYX0xFTkdUSF06IHZhbHVlLFxuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICB0eXBlczogW1N0cmluZy5uYW1lLCBBcnJheS5uYW1lLCBTZXQubmFtZV0sXG4gICAgICB9KVxuICAgIClcbiAgICAuYXBwbHkoKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgUmVnRXhwIHBhdHRlcm4gdGhlIHByb3BlcnR5IG11c3QgcmVzcGVjdFxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNQQVRURVJOfVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjUEFUVEVSTn1cbiAqXG4gKiBAZnVuY3Rpb24gcGF0dGVyblxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhdHRlcm4oXG4gIHZhbHVlOiBSZWdFeHAgfCBzdHJpbmcsXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuUEFUVEVSTlxuKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLlBBVFRFUk4pO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoXG4gICAgICBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihrZXksIHtcbiAgICAgICAgW1ZhbGlkYXRpb25LZXlzLlBBVFRFUk5dOlxuICAgICAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiA/IHZhbHVlIDogdmFsdWUudG9TdHJpbmcoKSxcbiAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgICAgdHlwZXM6IFtTdHJpbmcubmFtZV0sXG4gICAgICB9KVxuICAgIClcbiAgICAuYXBwbHkoKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBwcm9wZXJ0eSBhcyBhbiBlbWFpbFxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNFTUFJTH1cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIHRoZSBlcnJvciBtZXNzYWdlLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNFTUFJTH1cbiAqXG4gKiBAZnVuY3Rpb24gZW1haWxcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbWFpbChtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkVNQUlMKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLkVNQUlMKTtcbiAgcmV0dXJuIERlY29yYXRpb24uZm9yKGtleSlcbiAgICAuZGVmaW5lKFxuICAgICAgcHJvcE1ldGFkYXRhPFZhbGlkYXRpb25NZXRhZGF0YT4oa2V5LCB7XG4gICAgICAgIFtWYWxpZGF0aW9uS2V5cy5QQVRURVJOXTogREVGQVVMVF9QQVRURVJOUy5FTUFJTCxcbiAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgICAgdHlwZXM6IFtTdHJpbmcubmFtZV0sXG4gICAgICB9KVxuICAgIClcbiAgICAuYXBwbHkoKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBwcm9wZXJ0eSBhcyBhbiBVUkxcbiAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0b3JzIHRvIHZhbGlkYXRlIGEgZGVjb3JhdGVkIHByb3BlcnR5IG11c3QgdXNlIGtleSB7QGxpbmsgVmFsaWRhdGlvbktleXMjVVJMfVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gdGhlIGVycm9yIG1lc3NhZ2UuIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1VSTH1cbiAqXG4gKiBAZnVuY3Rpb24gdXJsXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdXJsKG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuVVJMKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLlVSTCk7XG4gIHJldHVybiBEZWNvcmF0aW9uLmZvcihrZXkpXG4gICAgLmRlZmluZShcbiAgICAgIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KGtleSwge1xuICAgICAgICBbVmFsaWRhdGlvbktleXMuUEFUVEVSTl06IERFRkFVTFRfUEFUVEVSTlMuVVJMLFxuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICB0eXBlczogW1N0cmluZy5uYW1lXSxcbiAgICAgIH0pXG4gICAgKVxuICAgIC5hcHBseSgpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IEVuZm9yY2VzIHR5cGUgdmVyaWZpY2F0aW9uXG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdG9ycyB0byB2YWxpZGF0ZSBhIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IHVzZSBrZXkge0BsaW5rIFZhbGlkYXRpb25LZXlzI1RZUEV9XG4gKlxuICogQHBhcmFtIHtzdHJpbmdbXSB8IHN0cmluZ30gdHlwZXMgYWNjZXB0ZWQgdHlwZXNcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gdGhlIGVycm9yIG1lc3NhZ2UuIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX0VSUk9SX01FU1NBR0VTI1RZUEV9XG4gKlxuICogQGZ1bmN0aW9uIHR5cGVcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0eXBlKFxuICB0eXBlczogc3RyaW5nW10gfCBzdHJpbmcsXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuVFlQRVxuKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLlRZUEUpO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoXG4gICAgICBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihrZXksIHtcbiAgICAgICAgY3VzdG9tVHlwZXM6IHR5cGVzLFxuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgfSlcbiAgICApXG4gICAgLmFwcGx5KCk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGF0ZSBIYW5kbGVyIERlY29yYXRvclxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNEQVRFfVxuICpcbiAqIFdpbGwgZW5mb3JjZSBzZXJpYWxpemF0aW9uIGFjY29yZGluZyB0byB0aGUgc2VsZWN0ZWQgZm9ybWF0XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGZvcm1hdCBhY2NlcHRlZCBmb3JtYXQgYWNjb3JkaW5nIHRvIHtAbGluayBmb3JtYXREYXRlfVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjREFURX1cbiAqXG4gKiBAZnVuY3Rpb24gZGF0ZVxuICpcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkYXRlKFxuICBmb3JtYXQ6IHN0cmluZyA9IFwiZGQvTU0veXl5eVwiLFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkRBVEVcbikge1xuICBjb25zdCBrZXkgPSBWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5EQVRFKTtcbiAgY29uc3QgZGF0ZURlYyA9ICh0YXJnZXQ6IFJlY29yZDxzdHJpbmcsIGFueT4sIHByb3BlcnR5S2V5PzogYW55KTogYW55ID0+IHtcbiAgICBwcm9wTWV0YWRhdGEoa2V5LCB7XG4gICAgICBbVmFsaWRhdGlvbktleXMuRk9STUFUXTogZm9ybWF0LFxuICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgIHR5cGVzOiBbRGF0ZS5uYW1lXSxcbiAgICB9KSh0YXJnZXQsIHByb3BlcnR5S2V5KTtcblxuICAgIGNvbnN0IHZhbHVlcyA9IG5ldyBXZWFrTWFwKCk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSwge1xuICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgIHNldCh0aGlzOiBhbnksIG5ld1ZhbHVlOiBzdHJpbmcgfCBEYXRlKSB7XG4gICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRoaXMsIHByb3BlcnR5S2V5KTtcbiAgICAgICAgaWYgKCFkZXNjcmlwdG9yIHx8IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlKVxuICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBwcm9wZXJ0eUtleSwge1xuICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICAgICAgICBnZXQ6ICgpID0+IHZhbHVlcy5nZXQodGhpcyksXG4gICAgICAgICAgICBzZXQ6IChuZXdWYWx1ZTogc3RyaW5nIHwgRGF0ZSB8IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgICBsZXQgdmFsOiBEYXRlIHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHZhbCA9IHBhcnNlRGF0ZShmb3JtYXQsIG5ld1ZhbHVlKTtcbiAgICAgICAgICAgICAgICB2YWx1ZXMuc2V0KHRoaXMsIHZhbCk7XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3Ioc2YoXCJGYWlsZWQgdG8gcGFyc2UgZGF0ZTogezB9XCIsIGUubWVzc2FnZSB8fCBlKSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIHRoaXNbcHJvcGVydHlLZXldID0gbmV3VmFsdWU7XG4gICAgICB9LFxuICAgICAgZ2V0KCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcImhlcmVcIik7XG4gICAgICB9LFxuICAgIH0pO1xuICB9O1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KS5kZWZpbmUoZGF0ZURlYykuYXBwbHkoKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBQYXNzd29yZCBIYW5kbGVyIERlY29yYXRvclxuICogQGRlc2NyaXB0aW9uIFZhbGlkYXRvcnMgdG8gdmFsaWRhdGUgYSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCB1c2Uga2V5IHtAbGluayBWYWxpZGF0aW9uS2V5cyNQQVNTV09SRH1cbiAqXG4gKiBAcGFyYW0ge1JlZ0V4cH0gW3BhdHRlcm5dIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX1BBVFRFUk5TI0NIQVI4X09ORV9PRl9FQUNIfVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMjUEFTU1dPUkR9XG4gKlxuICogQGZ1bmN0aW9uIHBhc3N3b3JkXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhc3N3b3JkKFxuICBwYXR0ZXJuOiBSZWdFeHAgPSBERUZBVUxUX1BBVFRFUk5TLlBBU1NXT1JELkNIQVI4X09ORV9PRl9FQUNILFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlBBU1NXT1JEXG4pIHtcbiAgY29uc3Qga2V5ID0gVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuUEFTU1dPUkQpO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoXG4gICAgICBwcm9wTWV0YWRhdGEoa2V5LCB7XG4gICAgICAgIFtWYWxpZGF0aW9uS2V5cy5QQVRURVJOXTogcGF0dGVybixcbiAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgICAgdHlwZXM6IFtTdHJpbmcubmFtZV0sXG4gICAgICB9KVxuICAgIClcbiAgICAuYXBwbHkoKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBMaXN0IERlY29yYXRvclxuICogQGRlc2NyaXB0aW9uIEFsc28gc2V0cyB0aGUge0BsaW5rIHR5cGV9IHRvIHRoZSBwcm92aWRlZCBjb2xsZWN0aW9uXG4gKlxuICogQHBhcmFtIHtNb2RlbENvbnN0cnVjdG9yfSBjbGF6elxuICogQHBhcmFtIHtzdHJpbmd9IFtjb2xsZWN0aW9uXSBUaGUgY29sbGVjdGlvbiBiZWluZyB1c2VkLiBkZWZhdWx0cyB0byBBcnJheVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNMSVNUfVxuICpcbiAqIEBmdW5jdGlvbiBsaXN0XG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3QoXG4gIGNsYXp6OiBNb2RlbENvbnN0cnVjdG9yPGFueT4gfCBNb2RlbENvbnN0cnVjdG9yPGFueT5bXSxcbiAgY29sbGVjdGlvbjogXCJBcnJheVwiIHwgXCJTZXRcIiA9IFwiQXJyYXlcIixcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5MSVNUXG4pIHtcbiAgY29uc3Qga2V5ID0gVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuTElTVCk7XG4gIHJldHVybiBEZWNvcmF0aW9uLmZvcihrZXkpXG4gICAgLmRlZmluZShcbiAgICAgIHByb3BNZXRhZGF0YShrZXksIHtcbiAgICAgICAgY2xheno6IEFycmF5LmlzQXJyYXkoY2xhenopID8gY2xhenoubWFwKChjKSA9PiBjLm5hbWUpIDogW2NsYXp6Lm5hbWVdLFxuICAgICAgICB0eXBlOiBjb2xsZWN0aW9uLFxuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgfSlcbiAgICApXG4gICAgLmFwcGx5KCk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgU2V0IERlY29yYXRvclxuICogQGRlc2NyaXB0aW9uIFdyYXBwZXIgZm9yIHtAbGluayBsaXN0fSB3aXRoIHRoZSAnU2V0JyBDb2xsZWN0aW9uXG4gKlxuICogQHBhcmFtIHtNb2RlbENvbnN0cnVjdG9yfSBjbGF6elxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyNMSVNUfVxuICpcbiAqIEBmdW5jdGlvbiBzZXRcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0KFxuICBjbGF6ejogTW9kZWxDb25zdHJ1Y3Rvcjxhbnk+LFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLkxJU1Rcbikge1xuICByZXR1cm4gbGlzdChjbGF6eiwgXCJTZXRcIiwgbWVzc2FnZSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVjbGFyZXMgdGhhdCB0aGUgZGVjb3JhdGVkIHByb3BlcnR5IG11c3QgYmUgZXF1YWwgdG8gYW5vdGhlciBzcGVjaWZpZWQgcHJvcGVydHkuXG4gKiBAZGVzY3JpcHRpb24gQXBwbGllcyB0aGUge0BsaW5rIFZhbGlkYXRpb25LZXlzLkVRVUFMU30gdmFsaWRhdG9yIHRvIGVuc3VyZSB0aGUgZGVjb3JhdGVkIHZhbHVlIG1hdGNoZXMgdGhlIHZhbHVlIG9mIHRoZSBnaXZlbiBwcm9wZXJ0eS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvcGVydHlUb0NvbXBhcmUgLSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgdG8gY29tcGFyZSBlcXVhbGl0eSBhZ2FpbnN0LlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlPURFRkFVTFRfRVJST1JfTUVTU0FHRVMuRVFVQUxTXSAtIEN1c3RvbSBlcnJvciBtZXNzYWdlIHRvIHJldHVybiBpZiB2YWxpZGF0aW9uIGZhaWxzLlxuICpcbiAqIEByZXR1cm5zIHtQcm9wZXJ0eURlY29yYXRvcn0gQSBwcm9wZXJ0eSBkZWNvcmF0b3IgdXNlZCB0byByZWdpc3RlciB0aGUgZXF1YWxpdHkgdmFsaWRhdGlvbiBtZXRhZGF0YS5cbiAqXG4gKiBAZnVuY3Rpb24gZXFcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uRGVjb3JhdG9ycy5WYWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZXEoXG4gIHByb3BlcnR5VG9Db21wYXJlOiBzdHJpbmcsXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuRVFVQUxTXG4pIHtcbiAgY29uc3Qgb3B0aW9uczogRXF1YWxzVmFsaWRhdG9yT3B0aW9ucyA9IHtcbiAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgIFtWYWxpZGF0aW9uS2V5cy5FUVVBTFNdOiBwcm9wZXJ0eVRvQ29tcGFyZSxcbiAgfTtcblxuICByZXR1cm4gcHJvcE1ldGFkYXRhPFZhbGlkYXRpb25NZXRhZGF0YT4oXG4gICAgVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuRVFVQUxTKSxcbiAgICBvcHRpb25zIGFzIFZhbGlkYXRpb25NZXRhZGF0YVxuICApO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlY2xhcmVzIHRoYXQgdGhlIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IGJlIGRpZmZlcmVudCBmcm9tIGFub3RoZXIgc3BlY2lmaWVkIHByb3BlcnR5LlxuICogQGRlc2NyaXB0aW9uIEFwcGxpZXMgdGhlIHtAbGluayBWYWxpZGF0aW9uS2V5cy5ESUZGfSB2YWxpZGF0b3IgdG8gZW5zdXJlIHRoZSBkZWNvcmF0ZWQgdmFsdWUgaXMgZGlmZmVyZW50IGZyb20gdGhlIHZhbHVlIG9mIHRoZSBnaXZlbiBwcm9wZXJ0eS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvcGVydHlUb0NvbXBhcmUgLSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgdG8gY29tcGFyZSBkaWZmZXJlbmNlIGFnYWluc3QuXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2U9REVGQVVMVF9FUlJPUl9NRVNTQUdFUy5ESUZGXSAtIEN1c3RvbSBlcnJvciBtZXNzYWdlIHRvIHJldHVybiBpZiB2YWxpZGF0aW9uIGZhaWxzLlxuICpcbiAqIEByZXR1cm5zIHtQcm9wZXJ0eURlY29yYXRvcn0gQSBwcm9wZXJ0eSBkZWNvcmF0b3IgdXNlZCB0byByZWdpc3RlciB0aGUgZGlmZmVyZW5jZSB2YWxpZGF0aW9uIG1ldGFkYXRhLlxuICpcbiAqIEBmdW5jdGlvbiBkaWZmXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLkRlY29yYXRvcnMuVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpZmYoXG4gIHByb3BlcnR5VG9Db21wYXJlOiBzdHJpbmcsXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuRElGRlxuKSB7XG4gIGNvbnN0IG9wdGlvbnM6IERpZmZWYWxpZGF0b3JPcHRpb25zID0ge1xuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgW1ZhbGlkYXRpb25LZXlzLkRJRkZdOiBwcm9wZXJ0eVRvQ29tcGFyZSxcbiAgfTtcblxuICByZXR1cm4gcHJvcE1ldGFkYXRhPFZhbGlkYXRpb25NZXRhZGF0YT4oXG4gICAgVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuRElGRiksXG4gICAgb3B0aW9ucyBhcyBWYWxpZGF0aW9uTWV0YWRhdGFcbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWNsYXJlcyB0aGF0IHRoZSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCBiZSBsZXNzIHRoYW4gYW5vdGhlciBzcGVjaWZpZWQgcHJvcGVydHkuXG4gKiBAZGVzY3JpcHRpb24gQXBwbGllcyB0aGUge0BsaW5rIFZhbGlkYXRpb25LZXlzLkxFU1NfVEhBTn0gdmFsaWRhdG9yIHRvIGVuc3VyZSB0aGUgZGVjb3JhdGVkIHZhbHVlIGlzIGxlc3MgdGhhbiB0aGUgdmFsdWUgb2YgdGhlIGdpdmVuIHByb3BlcnR5LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eVRvQ29tcGFyZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0byBjb21wYXJlIGFnYWluc3QuXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2U9REVGQVVMVF9FUlJPUl9NRVNTQUdFUy5MRVNTX1RIQU5dIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gcmV0dXJuIGlmIHZhbGlkYXRpb24gZmFpbHMuXG4gKlxuICogQHJldHVybnMge1Byb3BlcnR5RGVjb3JhdG9yfSBBIHByb3BlcnR5IGRlY29yYXRvciB1c2VkIHRvIHJlZ2lzdGVyIHRoZSBsZXNzIHRoYW4gdmFsaWRhdGlvbiBtZXRhZGF0YS5cbiAqXG4gKiBAZnVuY3Rpb24gbHRcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb24uRGVjb3JhdG9ycy5WYWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbHQoXG4gIHByb3BlcnR5VG9Db21wYXJlOiBzdHJpbmcsXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuTEVTU19USEFOXG4pIHtcbiAgY29uc3Qgb3B0aW9uczogTGVzc1RoYW5WYWxpZGF0b3JPcHRpb25zID0ge1xuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgW1ZhbGlkYXRpb25LZXlzLkxFU1NfVEhBTl06IHByb3BlcnR5VG9Db21wYXJlLFxuICB9O1xuXG4gIHJldHVybiBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihcbiAgICBWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5MRVNTX1RIQU4pLFxuICAgIG9wdGlvbnMgYXMgVmFsaWRhdGlvbk1ldGFkYXRhXG4gICk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVjbGFyZXMgdGhhdCB0aGUgZGVjb3JhdGVkIHByb3BlcnR5IG11c3QgYmUgZXF1YWwgb3IgbGVzcyB0aGFuIGFub3RoZXIgc3BlY2lmaWVkIHByb3BlcnR5LlxuICogQGRlc2NyaXB0aW9uIEFwcGxpZXMgdGhlIHtAbGluayBWYWxpZGF0aW9uS2V5cy5MRVNTX1RIQU5fT1JfRVFVQUx9IHZhbGlkYXRvciB0byBlbnN1cmUgdGhlIGRlY29yYXRlZCB2YWx1ZSBpcyBlcXVhbCBvciBsZXNzIHRoYW4gdGhlIHZhbHVlIG9mIHRoZSBnaXZlbiBwcm9wZXJ0eS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvcGVydHlUb0NvbXBhcmUgLSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgdG8gY29tcGFyZSBhZ2FpbnN0LlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlPURFRkFVTFRfRVJST1JfTUVTU0FHRVMuTEVTU19USEFOX09SX0VRVUFMXSAtIEN1c3RvbSBlcnJvciBtZXNzYWdlIHRvIHJldHVybiBpZiB2YWxpZGF0aW9uIGZhaWxzLlxuICpcbiAqIEByZXR1cm5zIHtQcm9wZXJ0eURlY29yYXRvcn0gQSBwcm9wZXJ0eSBkZWNvcmF0b3IgdXNlZCB0byByZWdpc3RlciB0aGUgbGVzcyB0aGFuIG9yIGVxdWFsIHZhbGlkYXRpb24gbWV0YWRhdGEuXG4gKlxuICogQGZ1bmN0aW9uIGx0ZVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5EZWNvcmF0b3JzLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsdGUoXG4gIHByb3BlcnR5VG9Db21wYXJlOiBzdHJpbmcsXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuTEVTU19USEFOX09SX0VRVUFMXG4pIHtcbiAgY29uc3Qgb3B0aW9uczogTGVzc1RoYW5PckVxdWFsVmFsaWRhdG9yT3B0aW9ucyA9IHtcbiAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgIFtWYWxpZGF0aW9uS2V5cy5MRVNTX1RIQU5fT1JfRVFVQUxdOiBwcm9wZXJ0eVRvQ29tcGFyZSxcbiAgfTtcblxuICByZXR1cm4gcHJvcE1ldGFkYXRhPFZhbGlkYXRpb25NZXRhZGF0YT4oXG4gICAgVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuTEVTU19USEFOX09SX0VRVUFMKSxcbiAgICBvcHRpb25zIGFzIFZhbGlkYXRpb25NZXRhZGF0YVxuICApO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlY2xhcmVzIHRoYXQgdGhlIGRlY29yYXRlZCBwcm9wZXJ0eSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBhbm90aGVyIHNwZWNpZmllZCBwcm9wZXJ0eS5cbiAqIEBkZXNjcmlwdGlvbiBBcHBsaWVzIHRoZSB7QGxpbmsgVmFsaWRhdGlvbktleXMuR1JFQVRFUl9USEFOfSB2YWxpZGF0b3IgdG8gZW5zdXJlIHRoZSBkZWNvcmF0ZWQgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gcHJvcGVydHkuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHByb3BlcnR5VG9Db21wYXJlIC0gVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIGNvbXBhcmUgYWdhaW5zdC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZT1ERUZBVUxUX0VSUk9SX01FU1NBR0VTLkdSRUFURVJfVEhBTl0gLSBDdXN0b20gZXJyb3IgbWVzc2FnZSB0byByZXR1cm4gaWYgdmFsaWRhdGlvbiBmYWlscy5cbiAqXG4gKiBAcmV0dXJucyB7UHJvcGVydHlEZWNvcmF0b3J9IEEgcHJvcGVydHkgZGVjb3JhdG9yIHVzZWQgdG8gcmVnaXN0ZXIgdGhlIGdyZWF0ZXIgdGhhbiB2YWxpZGF0aW9uIG1ldGFkYXRhLlxuICpcbiAqIEBmdW5jdGlvbiBndFxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0b3ItdmFsaWRhdGlvbi5EZWNvcmF0b3JzLlZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBndChcbiAgcHJvcGVydHlUb0NvbXBhcmU6IHN0cmluZyxcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5HUkVBVEVSX1RIQU5cbikge1xuICBjb25zdCBvcHRpb25zOiBHcmVhdGVyVGhhblZhbGlkYXRvck9wdGlvbnMgPSB7XG4gICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICBbVmFsaWRhdGlvbktleXMuR1JFQVRFUl9USEFOXTogcHJvcGVydHlUb0NvbXBhcmUsXG4gIH07XG5cbiAgcmV0dXJuIHByb3BNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+KFxuICAgIFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLkdSRUFURVJfVEhBTiksXG4gICAgb3B0aW9ucyBhcyBWYWxpZGF0aW9uTWV0YWRhdGFcbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWNsYXJlcyB0aGF0IHRoZSBkZWNvcmF0ZWQgcHJvcGVydHkgbXVzdCBiZSBlcXVhbCBvciBncmVhdGVyIHRoYW4gYW5vdGhlciBzcGVjaWZpZWQgcHJvcGVydHkuXG4gKiBAZGVzY3JpcHRpb24gQXBwbGllcyB0aGUge0BsaW5rIFZhbGlkYXRpb25LZXlzLkdSRUFURVJfVEhBTl9PUl9FUVVBTH0gdmFsaWRhdG9yIHRvIGVuc3VyZSB0aGUgZGVjb3JhdGVkIHZhbHVlIGlzIGVxdWFsIG9yIGdyZWF0ZXIgdGhhbiB0aGUgdmFsdWUgb2YgdGhlIGdpdmVuIHByb3BlcnR5LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eVRvQ29tcGFyZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0byBjb21wYXJlIGFnYWluc3QuXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2U9REVGQVVMVF9FUlJPUl9NRVNTQUdFUy5HUkVBVEVSX1RIQU5fT1JfRVFVQUxdIC0gQ3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gcmV0dXJuIGlmIHZhbGlkYXRpb24gZmFpbHMuXG4gKlxuICogQHJldHVybnMge1Byb3BlcnR5RGVjb3JhdG9yfSBBIHByb3BlcnR5IGRlY29yYXRvciB1c2VkIHRvIHJlZ2lzdGVyIHRoZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdmFsaWRhdGlvbiBtZXRhZGF0YS5cbiAqXG4gKiBAZnVuY3Rpb24gZ3RlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uLkRlY29yYXRvcnMuVmFsaWRhdGlvblxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGd0ZShcbiAgcHJvcGVydHlUb0NvbXBhcmU6IHN0cmluZyxcbiAgbWVzc2FnZTogc3RyaW5nID0gREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5HUkVBVEVSX1RIQU5fT1JfRVFVQUxcbikge1xuICBjb25zdCBvcHRpb25zOiBHcmVhdGVyVGhhbk9yRXF1YWxWYWxpZGF0b3JPcHRpb25zID0ge1xuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgW1ZhbGlkYXRpb25LZXlzLkdSRUFURVJfVEhBTl9PUl9FUVVBTF06IHByb3BlcnR5VG9Db21wYXJlLFxuICB9O1xuXG4gIHJldHVybiBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihcbiAgICBWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5HUkVBVEVSX1RIQU5fT1JfRVFVQUwpLFxuICAgIG9wdGlvbnMgYXMgVmFsaWRhdGlvbk1ldGFkYXRhXG4gICk7XG59XG4iLCJpbXBvcnQgeyBNb2RlbCB9IGZyb20gXCIuL01vZGVsXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgSGVscGVyIEZ1bmN0aW9uIHRvIG92ZXJyaWRlIGNvbnN0cnVjdG9yc1xuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge2FueVtdfSBbYXJnc11cbiAqIEByZXR1cm4ge1R9IHRoZSBuZXcgaW5zdGFuY2VcbiAqXG4gKiBAZnVuY3Rpb24gY29uc3RydWN0XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb25zdHJ1Y3Q8VCBleHRlbmRzIE1vZGVsPihcbiAgY29uc3RydWN0b3I6IGFueSxcbiAgLi4uYXJnczogYW55W11cbik6IFQge1xuICBjb25zdCBfY29uc3RyID0gKC4uLmFyZ3o6IGFueVtdKSA9PiBuZXcgY29uc3RydWN0b3IoLi4uYXJneik7XG4gIF9jb25zdHIucHJvdG90eXBlID0gY29uc3RydWN0b3IucHJvdG90eXBlO1xuICByZXR1cm4gX2NvbnN0ciguLi5hcmdzKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBSZWN1cnNpdmVseSBmaW5kcyB0aGUgbGFzdCBwcm90b3R5cGUgYmVmb3JlIE9iamVjdFxuICogQHBhcmFtIHtvYmplY3R9IG9ialxuICpcbiAqIEBmdW5jdGlvbiBmaW5kTGFzdFByb3RvQmVmb3JlT2JqZWN0XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kTGFzdFByb3RvQmVmb3JlT2JqZWN0KG9iajogb2JqZWN0KTogb2JqZWN0IHtcbiAgbGV0IHByb3RvdHlwZTogYW55ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iaik7XG4gIGlmIChwcm90b3R5cGUgPT09IE9iamVjdC5wcm90b3R5cGUpIHJldHVybiBvYmo7XG4gIHdoaWxlIChwcm90b3R5cGUgIT09IE9iamVjdC5wcm90b3R5cGUpIHtcbiAgICBwcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG90eXBlKTtcbiAgICBpZiAocHJvdG90eXBlID09PSBPYmplY3QucHJvdG90eXBlKSByZXR1cm4gcHJvdG90eXBlO1xuICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG90eXBlKSA9PT0gT2JqZWN0LnByb3RvdHlwZSkgcmV0dXJuIHByb3RvdHlwZTtcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZCBub3QgZmluZCBwcm9wZXIgcHJvdG90eXBlXCIpO1xufVxuXG4vKipcbiAqIEBzdW1hcnkgYmluZHMgdGhlIHtAbGluayBNb2RlbH0gY2xhc3MgYXMgYSByb290IHByb3RvdHlwZSBvZiB0aGUgcHJvdmlkZWQgaW5zdGFuY2VcbiAqXG4gKiBAcGFyYW0ge3Vua25vd259IG9ialxuICpcbiAqIEBmdW5jdGlvbiBiaW5kTW9kZWxQcm90b3R5cGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJpbmRNb2RlbFByb3RvdHlwZShvYmo6IHVua25vd24pIHtcbiAgaWYgKG9iaiBpbnN0YW5jZW9mIE1vZGVsKSByZXR1cm47XG5cbiAgZnVuY3Rpb24gYmluZFByb3RvdHlwZShvYmpUb092ZXJyaWRlOiB1bmtub3duLCBwcm90b3R5cGU6IG9iamVjdCkge1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZihvYmpUb092ZXJyaWRlLCBwcm90b3R5cGUpO1xuICB9XG5cbiAgY29uc3QgcHJvdG90eXBlOiBhbnkgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKTtcbiAgaWYgKHByb3RvdHlwZSA9PT0gT2JqZWN0LnByb3RvdHlwZSkge1xuICAgIHJldHVybiBiaW5kUHJvdG90eXBlKG9iaiwgTW9kZWwucHJvdG90eXBlKTtcbiAgfVxuICB3aGlsZSAocHJvdG90eXBlICE9PSBPYmplY3QucHJvdG90eXBlKSB7XG4gICAgY29uc3QgcHJvdCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90b3R5cGUpO1xuICAgIGlmIChcbiAgICAgIHByb3QgPT09IE9iamVjdC5wcm90b3R5cGUgfHxcbiAgICAgIE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90KSA9PT0gT2JqZWN0LnByb3RvdHlwZVxuICAgICkge1xuICAgICAgcmV0dXJuIGJpbmRQcm90b3R5cGUocHJvdG90eXBlLCBNb2RlbC5wcm90b3R5cGUpO1xuICAgIH1cbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZCBub3QgZmluZCBwcm9wZXIgcHJvdG90eXBlIHRvIGJpbmRcIik7XG59XG4iLCJpbXBvcnQgeyBiaW5kTW9kZWxQcm90b3R5cGUsIGNvbnN0cnVjdCB9IGZyb20gXCIuL2NvbnN0cnVjdGlvblwiO1xuaW1wb3J0IHsgTW9kZWxLZXlzIH0gZnJvbSBcIi4uL3V0aWxzL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiLi9Nb2RlbFwiO1xuaW1wb3J0IHsgbWV0YWRhdGEgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBkZWZpbmVzIHRoZSB0cGUgb3MgYW4gSW5zdGFuY2VDYWxsYmFjayBmdW5jdGlvblxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgdHlwZSBJbnN0YW5jZUNhbGxiYWNrID0gKGluc3RhbmNlOiBhbnksIC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkO1xuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBjbGFzcyBhcyBhIE1vZGVsIGNsYXNzXG4gKiBAZGVzY3JpcHRpb25cbiAqXG4gKiAtIFJlZ2lzdGVycyB0aGUgY2xhc3MgdW5kZXIgdGhlIG1vZGVsIHJlZ2lzdHJ5IHNvIGl0IGNhbiBiZSBlYXNpbHkgcmVidWlsdDtcbiAqIC0gT3ZlcnJpZGVzIHRoZSBjbGFzcyBjb25zdHJ1Y3RvcjtcbiAqIC0gUnVucyB0aGUgZ2xvYmFsIHtAbGluayBNb2RlbEJ1aWxkZXJGdW5jdGlvbn0gaWYgZGVmaW5lZDtcbiAqIC0gUnVucyB0aGUgb3B0aW9uYWwge0BsaW5rIEluc3RhbmNlQ2FsbGJhY2t9IGlmIHByb3ZpZGVkO1xuICpcbiAqIEBwYXJhbSB7SW5zdGFuY2VDYWxsYmFja30gW2luc3RhbmNlQ2FsbGJhY2tdIG9wdGlvbmFsIGNhbGxiYWNrIHRoYXQgd2lsbCBiZSBjYWxsZWQgd2l0aCB0aGUgaW5zdGFuY2UgdXBvbiBpbnN0YW50aWF0aW9uLiBkZWZhdWx0cyB0byB1bmRlZmluZWRcbiAqXG4gKiBAZnVuY3Rpb24gbW9kZWxcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbW9kZWwoaW5zdGFuY2VDYWxsYmFjaz86IEluc3RhbmNlQ2FsbGJhY2spIHtcbiAgcmV0dXJuICgob3JpZ2luYWw6IGFueSkgPT4ge1xuICAgIC8vIHRoZSBuZXcgY29uc3RydWN0b3IgYmVoYXZpb3VyXG4gICAgY29uc3QgbmV3Q29uc3RydWN0b3I6IGFueSA9IGZ1bmN0aW9uICguLi5hcmdzOiBhbnlbXSkge1xuICAgICAgY29uc3QgaW5zdGFuY2U6IFJldHVyblR5cGU8dHlwZW9mIG9yaWdpbmFsPiA9IGNvbnN0cnVjdChcbiAgICAgICAgb3JpZ2luYWwsXG4gICAgICAgIC4uLmFyZ3NcbiAgICAgICk7XG4gICAgICBiaW5kTW9kZWxQcm90b3R5cGUoaW5zdGFuY2UpO1xuICAgICAgLy8gcnVuIGEgYnVpbGRlciBmdW5jdGlvbiBpZiBkZWZpbmVkIHdpdGggdGhlIGZpcnN0IGFyZ3VtZW50IChUaGUgTW9kZWxBcmcpXG4gICAgICBjb25zdCBidWlsZGVyID0gTW9kZWwuZ2V0QnVpbGRlcigpO1xuICAgICAgaWYgKGJ1aWxkZXIpIGJ1aWxkZXIoaW5zdGFuY2UsIGFyZ3MubGVuZ3RoID8gYXJnc1swXSA6IHVuZGVmaW5lZCk7XG5cbiAgICAgIG1ldGFkYXRhKE1vZGVsLmtleShNb2RlbEtleXMuTU9ERUwpLCBvcmlnaW5hbC5uYW1lKShpbnN0YW5jZS5jb25zdHJ1Y3Rvcik7XG5cbiAgICAgIGlmIChpbnN0YW5jZUNhbGxiYWNrKSBpbnN0YW5jZUNhbGxiYWNrKGluc3RhbmNlLCAuLi5hcmdzKTtcblxuICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgIH07XG5cbiAgICAvLyBjb3B5IHByb3RvdHlwZSBzbyBpbnN0YW5jZW9mIG9wZXJhdG9yIHN0aWxsIHdvcmtzXG4gICAgbmV3Q29uc3RydWN0b3IucHJvdG90eXBlID0gb3JpZ2luYWwucHJvdG90eXBlO1xuXG4gICAgUmVmbGVjdC5nZXRNZXRhZGF0YUtleXMob3JpZ2luYWwpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcbiAgICAgICAga2V5LFxuICAgICAgICBSZWZsZWN0LmdldE1ldGFkYXRhKGtleSwgb3JpZ2luYWwpLFxuICAgICAgICBuZXdDb25zdHJ1Y3RvclxuICAgICAgKTtcbiAgICB9KTtcbiAgICAvLyBTZXRzIHRoZSBwcm9wZXIgY29uc3RydWN0b3IgbmFtZSBmb3IgdHlwZSB2ZXJpZmljYXRpb25cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobmV3Q29uc3RydWN0b3IsIFwibmFtZVwiLCB7XG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgIHZhbHVlOiBvcmlnaW5hbC5wcm90b3R5cGUuY29uc3RydWN0b3IubmFtZSxcbiAgICB9KTtcblxuICAgIG1ldGFkYXRhKE1vZGVsLmtleShNb2RlbEtleXMuTU9ERUwpLCBvcmlnaW5hbC5uYW1lKShvcmlnaW5hbCk7XG5cbiAgICBNb2RlbC5yZWdpc3RlcihuZXdDb25zdHJ1Y3Rvciwgb3JpZ2luYWwubmFtZSk7XG5cbiAgICAvLyByZXR1cm4gbmV3IGNvbnN0cnVjdG9yICh3aWxsIG92ZXJyaWRlIG9yaWdpbmFsKVxuICAgIHJldHVybiBuZXdDb25zdHJ1Y3RvcjtcbiAgfSkgYXMgYW55O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFzaGVkQnkoYWxnb3JpdGhtOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKSB7XG4gIHJldHVybiBtZXRhZGF0YShNb2RlbC5rZXkoTW9kZWxLZXlzLkhBU0hJTkcpLCB7XG4gICAgYWxnb3JpdGhtOiBhbGdvcml0aG0sXG4gICAgYXJnczogYXJncyxcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVkQnkoc2VyaWFsaXplcjogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkge1xuICByZXR1cm4gbWV0YWRhdGEoTW9kZWwua2V5KE1vZGVsS2V5cy5TRVJJQUxJWkFUSU9OKSwge1xuICAgIHNlcmlhbGl6ZXI6IHNlcmlhbGl6ZXIsXG4gICAgYXJnczogYXJncyxcbiAgfSk7XG59XG4iLCIvKipcbiAqIEBtb2R1bGUgZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIEBkZXNjcmlwdGlvbiBUeXBlU2NyaXB0IGRlY29yYXRvci1iYXNlZCB2YWxpZGF0aW9uIGxpYnJhcnlcbiAqIEBzdW1tYXJ5IFRoaXMgbW9kdWxlIHByb3ZpZGVzIGEgY29tcHJlaGVuc2l2ZSB2YWxpZGF0aW9uIGZyYW1ld29yayB1c2luZyBUeXBlU2NyaXB0IGRlY29yYXRvcnMuXG4gKiBJdCBleHBvc2VzIHV0aWxpdHkgZnVuY3Rpb25zLCB2YWxpZGF0aW9uIGRlY29yYXRvcnMsIGFuZCBtb2RlbC1yZWxhdGVkIGZ1bmN0aW9uYWxpdHkgZm9yXG4gKiBpbXBsZW1lbnRpbmcgdHlwZS1zYWZlLCBkZWNsYXJhdGl2ZSB2YWxpZGF0aW9uIGluIFR5cGVTY3JpcHQgYXBwbGljYXRpb25zLlxuICovXG5leHBvcnQgKiBmcm9tIFwiLi91dGlsc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdmFsaWRhdGlvblwiO1xuZXhwb3J0ICogZnJvbSBcIi4vbW9kZWxcIjtcblxuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6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