@fgv/ts-utils 1.2.1 → 1.4.0

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 (78) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +4 -0
  3. package/brand.d.ts +8 -0
  4. package/brand.d.ts.map +1 -0
  5. package/brand.js +24 -0
  6. package/converter.d.ts +149 -105
  7. package/converter.d.ts.map +1 -0
  8. package/converter.js +46 -59
  9. package/converters.d.ts +432 -194
  10. package/converters.d.ts.map +1 -0
  11. package/converters.js +262 -151
  12. package/csvHelpers.d.ts +7 -0
  13. package/csvHelpers.d.ts.map +1 -0
  14. package/csvHelpers.js +12 -2
  15. package/extendedArray.d.ts +46 -0
  16. package/extendedArray.d.ts.map +1 -0
  17. package/extendedArray.js +46 -1
  18. package/formatter.d.ts +53 -0
  19. package/formatter.d.ts.map +1 -0
  20. package/formatter.js +24 -1
  21. package/hash.d.ts +31 -3
  22. package/hash.d.ts.map +1 -0
  23. package/hash.js +36 -5
  24. package/index.d.ts +8 -3
  25. package/index.d.ts.map +1 -0
  26. package/index.js +18 -6
  27. package/logger.d.ts +3 -2
  28. package/logger.d.ts.map +1 -0
  29. package/logger.js +1 -1
  30. package/normalize.d.ts +43 -0
  31. package/normalize.d.ts.map +1 -0
  32. package/normalize.js +139 -0
  33. package/package.json +13 -9
  34. package/rangeOf.d.ts +96 -0
  35. package/rangeOf.d.ts.map +1 -0
  36. package/rangeOf.js +80 -1
  37. package/result.d.ts +393 -39
  38. package/result.d.ts.map +1 -0
  39. package/result.js +259 -49
  40. package/utils.d.ts +71 -27
  41. package/utils.d.ts.map +1 -0
  42. package/utils.js +74 -29
  43. package/validation/boolean.d.ts +27 -0
  44. package/validation/boolean.d.ts.map +1 -0
  45. package/validation/boolean.js +59 -0
  46. package/validation/classes.d.ts +5 -0
  47. package/validation/classes.d.ts.map +1 -0
  48. package/validation/classes.js +34 -0
  49. package/validation/field.d.ts +43 -0
  50. package/validation/field.d.ts.map +1 -0
  51. package/validation/field.js +72 -0
  52. package/validation/genericValidator.d.ts +84 -0
  53. package/validation/genericValidator.d.ts.map +1 -0
  54. package/validation/genericValidator.js +138 -0
  55. package/validation/index.d.ts +7 -0
  56. package/validation/index.d.ts.map +1 -0
  57. package/validation/index.js +59 -0
  58. package/validation/number.d.ts +27 -0
  59. package/validation/number.d.ts.map +1 -0
  60. package/validation/number.js +57 -0
  61. package/validation/object.d.ts +115 -0
  62. package/validation/object.d.ts.map +1 -0
  63. package/validation/object.js +143 -0
  64. package/validation/string.d.ts +27 -0
  65. package/validation/string.d.ts.map +1 -0
  66. package/validation/string.js +57 -0
  67. package/validation/traits.d.ts +68 -0
  68. package/validation/traits.d.ts.map +1 -0
  69. package/validation/traits.js +58 -0
  70. package/validation/validator.d.ts +82 -0
  71. package/validation/validator.d.ts.map +1 -0
  72. package/validation/validator.js +24 -0
  73. package/validation/validatorBase.d.ts +25 -0
  74. package/validation/validatorBase.d.ts.map +1 -0
  75. package/validation/validatorBase.js +44 -0
  76. package/validation/validators.d.ts +32 -0
  77. package/validation/validators.d.ts.map +1 -0
  78. package/validation/validators.js +59 -0
package/converters.js CHANGED
@@ -33,29 +33,43 @@ const extendedArray_1 = require("./extendedArray");
33
33
  const mustache_1 = __importDefault(require("mustache"));
34
34
  const utils_1 = require("./utils");
35
35
  /**
36
- * The @see StringConverter class extends @see BaseConverter to provide string-specific helper
37
- * functions.
36
+ * The {@link Converters.StringConverter | StringConverter} class extends {@link BaseConverter}
37
+ * to provide string-specific helper methods.
38
+ * @public
38
39
  */
39
40
  class StringConverter extends converter_1.BaseConverter {
40
41
  /**
41
- * Construct a new @see StringConverter
42
- * @param defaultContext Optional context used by the conversion
43
- * @param traits Optional traits to be applied to the conversion
44
- * @param converter Optional converter to be used for the conversion
42
+ * Construct a new {@link Converters.StringConverter | StringConverter}.
43
+ * @param defaultContext - Optional context used by the conversion.
44
+ * @param traits - Optional traits to be applied to the conversion.
45
+ * @param converter - Optional conversion function to be used for the conversion.
45
46
  */
46
47
  constructor(defaultContext, traits, converter = StringConverter._convert) {
47
48
  super(converter, defaultContext, traits);
48
49
  }
50
+ /**
51
+ * @internal
52
+ */
49
53
  static _convert(from) {
50
54
  return typeof from === 'string'
51
55
  ? (0, result_1.succeed)(from)
52
56
  : (0, result_1.fail)(`Not a string: ${JSON.stringify(from)}`);
53
57
  }
58
+ /**
59
+ * @internal
60
+ */
54
61
  static _wrap(wrapped, converter, traits) {
55
62
  return new StringConverter(undefined, undefined, (from) => {
56
63
  return wrapped.convert(from).onSuccess(converter);
57
64
  })._with(wrapped._traits(traits));
58
65
  }
66
+ /**
67
+ * Concrete implementation of {@link Converters.StringConverter.(matching#string) | StringConverter.matching(string)},
68
+ * {@link Converters.StringConverter.(matching#array) | StringConverter.matching(string[])},
69
+ * {@link Converters.StringConverter.(matching#set) | StringConverter.matching(Set<string>)}, and
70
+ * {@link Converters.StringConverter.(matching#regexp) | StringConverter.matching(RegExp)}.
71
+ * @internal
72
+ */
59
73
  matching(match, options) {
60
74
  const message = options === null || options === void 0 ? void 0 : options.message;
61
75
  if (typeof match === 'string') {
@@ -100,12 +114,18 @@ exports.StringConverter = StringConverter;
100
114
  /**
101
115
  * A converter to convert unknown to string. Values of type
102
116
  * string succeed. Anything else fails.
117
+ * @public
103
118
  */
104
119
  exports.string = new StringConverter();
105
120
  /**
106
- * Helper function to create a converter which converts unknown to string, applying
107
- * template conversions supplied at construction time or at runtime as context.
108
- * @param defaultContext optional default context to use for template values
121
+ * Helper function to create a {@link Converters.StringConverter | StringConverter} which converts
122
+ * `unknown` to `string`, applying template conversions supplied at construction time or at
123
+ * runtime as context.
124
+ * @remarks
125
+ * Template conversions are applied using `mustache` syntax.
126
+ * @param defaultContext - Optional default context to use for template values.
127
+ * @returns A new {@link Converter} returning `string`.
128
+ * @public
109
129
  */
110
130
  function templateString(defaultContext) {
111
131
  return new StringConverter(defaultContext, undefined, (from, _self, context) => {
@@ -117,9 +137,14 @@ function templateString(defaultContext) {
117
137
  }
118
138
  exports.templateString = templateString;
119
139
  /**
120
- * A converter to convert unknown to one of a set of supplied enumerated values. Anything else fails.
140
+ * Helper function to create a {@link Converter} which converts `unknown` to one of a set of supplied
141
+ * enumerated values. Anything else fails.
142
+ *
143
+ * @remarks
121
144
  * Allowed enumerated values can also be supplied as context at conversion time.
122
- * @param values Array of allowed values
145
+ * @param values - Array of allowed values.
146
+ * @returns A new {@link Converter} returning `<T>`.
147
+ * @public
123
148
  */
124
149
  function enumeratedValue(values) {
125
150
  return new converter_1.BaseConverter((from, _self, context) => {
@@ -130,14 +155,17 @@ function enumeratedValue(values) {
130
155
  }
131
156
  exports.enumeratedValue = enumeratedValue;
132
157
  /**
133
- * Converts unknown to one of a set of supplied enumerated values, mapping any of multiple supplied
134
- * values to the enumeration. Enables mapping of multiple input values to a consistent internal
135
- * representation (so e.g. 'y', 'yes', 'true' and true can all map to boolean true)
136
- * @param map An array of tuples describing the mapping. The first element of each tuple is the result
158
+ * Helper function to create a {@link Converter} which converts `unknown` to one of a set of supplied enumerated
159
+ * values, mapping any of multiple supplied values to the enumeration.
160
+ * @remarks
161
+ * Enables mapping of multiple input values to a consistent internal representation (so e.g. `'y'`, `'yes'`,
162
+ * `'true'`, `1` and `true` can all map to boolean `true`)
163
+ * @param map - An array of tuples describing the mapping. The first element of each tuple is the result
137
164
  * value, the second is the set of values that map to the result. Tuples are evaluated in the order
138
165
  * supplied and are not checked for duplicates.
139
- * @param message an optional error message
140
- * @returns The mapped value
166
+ * @param message - An optional error message.
167
+ * @returns A {@link Converter} which applies the mapping and yields `<T>` on success.
168
+ * @public
141
169
  */
142
170
  function mappedEnumeratedValue(map, message) {
143
171
  return new converter_1.BaseConverter((from, _self, _context) => {
@@ -151,9 +179,11 @@ function mappedEnumeratedValue(map, message) {
151
179
  }
152
180
  exports.mappedEnumeratedValue = mappedEnumeratedValue;
153
181
  /**
154
- * A converter to convert unknown to some value. Succeeds with the supplied value if an identity
155
- * comparison succeeds, fails otherwise.
156
- * @param value The value to be compared
182
+ * Helper function to create a {@link Converter} which converts `unknown` to some supplied literal value. Succeeds with
183
+ * the supplied value if an identity comparison succeeds, fails otherwise.
184
+ * @param value - The value to be compared.
185
+ * @returns A {@link Converter} which returns the supplied value on success.
186
+ * @public
157
187
  */
158
188
  function literal(value) {
159
189
  return new converter_1.BaseConverter((from, _self, _context) => {
@@ -163,13 +193,16 @@ function literal(value) {
163
193
  exports.literal = literal;
164
194
  /**
165
195
  * Deprecated alias for @see literal
166
- * @param value The value to be compared
167
- * @deprecated use literal instead
196
+ * @param value - The value to be compared.
197
+ * @deprecated Use {@link Converters.literal} instead.
198
+ * @internal
168
199
  */
169
200
  exports.value = literal;
170
201
  /**
171
- * A converter to convert unknown to a number. Numbers and strings
172
- * with a numeric format succeed. Anything else fails.
202
+ * A {@link Converter} which converts `unknown` to a `number`.
203
+ * @remarks
204
+ * Numbers and strings with a numeric format succeed. Anything else fails.
205
+ * @public
173
206
  */
174
207
  exports.number = new converter_1.BaseConverter((from) => {
175
208
  if (typeof from !== 'number') {
@@ -181,9 +214,11 @@ exports.number = new converter_1.BaseConverter((from) => {
181
214
  return (0, result_1.succeed)(from);
182
215
  });
183
216
  /**
184
- * A converter to convert unknown to boolean. Boolean values or the
185
- * case-insensitive strings 'true' and 'false' succeed. Anything
186
- * else fails.
217
+ * A {@link Converter} which converts `unknown` to `boolean`.
218
+ * @remarks
219
+ * Boolean values or the case-insensitive strings `'true'` and `'false'` succeed.
220
+ * Anything else fails.
221
+ * @public
187
222
  */
188
223
  exports.boolean = new converter_1.BaseConverter((from) => {
189
224
  if (typeof from === 'boolean') {
@@ -198,15 +233,19 @@ exports.boolean = new converter_1.BaseConverter((from) => {
198
233
  return (0, result_1.fail)(`Not a boolean: ${JSON.stringify(from)}`);
199
234
  });
200
235
  /**
201
- * A converter to convert an optional string value. Values of type string
202
- * are returned. Anything else returns success with an undefined value.
236
+ * A {@link Converter} which converts an optional `string` value. Values of type
237
+ * `string` are returned. Anything else returns {@link Success} with value `undefined`.
238
+ * @public
203
239
  */
204
240
  exports.optionalString = exports.string.optional();
205
241
  /**
206
- * Creates a converter which converts any string into an array of strings
207
- * by separating at a supplied delimiter. Delimeter may also be supplied
208
- * as context at conversion time.
209
- * @param delimiter The delimiter at which to split.
242
+ * Helper function to create a {@link Converter} which converts any `string` into an
243
+ * array of `string`, by separating at a supplied delimiter.
244
+ * @remarks
245
+ * Delimiter may also be supplied as context at conversion time.
246
+ * @param delimiter - The delimiter at which to split.
247
+ * @returns A new {@link Converter} returning `string[]`.
248
+ * @public
210
249
  */
211
250
  function delimitedString(delimiter, options = 'filtered') {
212
251
  return new converter_1.BaseConverter((from, _self, context) => {
@@ -223,7 +262,9 @@ function delimitedString(delimiter, options = 'filtered') {
223
262
  }
224
263
  exports.delimitedString = delimitedString;
225
264
  /**
226
- * A converter to convert an iso formatted string, a number or a Date object to a Date object
265
+ * A {@link Converter} which converts an iso formatted string, a number or a `Date` object to
266
+ * a `Date` object.
267
+ * @public
227
268
  */
228
269
  exports.isoDate = new converter_1.BaseConverter((from) => {
229
270
  if (typeof from === 'string') {
@@ -242,29 +283,37 @@ exports.isoDate = new converter_1.BaseConverter((from) => {
242
283
  return (0, result_1.fail)(`Cannot convert ${JSON.stringify(from)} to Date`);
243
284
  });
244
285
  /**
245
- * A converter to convert an optional number value. Values of type number
246
- * or numeric strings are converted and returned. Anything else returns
247
- * success with an undefined value.
286
+ * A {@link Converter} which converts an optional `number` value.
287
+ * @remarks
288
+ * Values of type `number` or numeric strings are converted and returned.
289
+ * Anything else returns {@link Success} with value `undefined`.
290
+ * @public
248
291
  */
249
292
  exports.optionalNumber = exports.number.optional();
250
293
  /**
251
- * A converter to convert an optional boolean value. Values of type boolean
252
- * or strings that match (case-insensitive) 'true' or 'false' are converted
253
- * and returned. Anything else returns success with an undefined value.
294
+ * A {@link Converter} to convert an optional `boolean` value.
295
+ * @remarks
296
+ * Values of type `boolean` or strings that match (case-insensitive) `'true'`
297
+ * or `'false'` are converted and returned. Anything else returns {@link Success}
298
+ * with value `undefined`.
299
+ * @public
254
300
  */
255
301
  exports.optionalBoolean = exports.boolean.optional();
256
302
  /**
257
- * A helper wrapper for polymorphic fields. Invokes the wrapped converters
258
- * in sequence, returning the first successful result. Returns an error
259
- * if none of the supplied converters can convert the value.
260
- *
261
- * If onError is 'ignoreErrors' (default), then errors from any of the
303
+ * A helper function to create a {@link Converter} for polymorphic values. Returns a
304
+ * converter which Invokes the wrapped converters in sequence, returning the first successful
305
+ * result. Returns an error if none of the supplied converters can convert the value.
306
+ * @remarks
307
+ * If `onError` is `ignoreErrors` (default), then errors from any of the
262
308
  * converters are ignored provided that some converter succeeds. If
263
- * onError is 'failOnError', then an error from any converter fails the entire
309
+ * onError is `failOnError`, then an error from any converter fails the entire
264
310
  * conversion.
265
311
  *
266
- * @param converters An ordered list of converters to be considered
267
- * @param onError Specifies treatment of unconvertable elements
312
+ * @param converters - An ordered list of {@link Converter | converters} to be considered.
313
+ * @param onError - Specifies treatment of unconvertible elements.
314
+ * @returns A new {@link Converter} which yields a value from the union of the types returned
315
+ * by the wrapped converters.
316
+ * @public
268
317
  */
269
318
  function oneOf(converters, onError = 'ignoreErrors') {
270
319
  return new converter_1.BaseConverter((from, _self, context) => {
@@ -286,11 +335,14 @@ function oneOf(converters, onError = 'ignoreErrors') {
286
335
  }
287
336
  exports.oneOf = oneOf;
288
337
  /**
289
- * A helper wrapper for converting an array of <T>. If onError is 'failOnError' (default),
290
- * then the entire conversion fails if any element cannot be converted. If onError
291
- * is 'ignoreErrors', failing elements are silently ignored.
292
- * @param converter Converter used to convert each item in the array
293
- * @param ignoreErrors Specifies treatment of unconvertable elements
338
+ * A helper function to create a {@link Converter} which converts `unknown` to an array of `<T>`.
339
+ * @remarks
340
+ * If `onError` is `'failOnError'` (default), then the entire conversion fails if any element cannot
341
+ * be converted. If `onError` is `'ignoreErrors'`, then failing elements are silently ignored.
342
+ * @param converter - {@link Converter} used to convert each item in the array.
343
+ * @param ignoreErrors - Specifies treatment of unconvertible elements.
344
+ * @returns A {@link Converter} which returns an array of `<T>`.
345
+ * @public
294
346
  */
295
347
  function arrayOf(converter, onError = 'failOnError') {
296
348
  return new converter_1.BaseConverter((from, _self, context) => {
@@ -315,11 +367,13 @@ function arrayOf(converter, onError = 'failOnError') {
315
367
  }
316
368
  exports.arrayOf = arrayOf;
317
369
  /**
318
- * A helper wrapper for converting to Itemrray<T>. If onError is 'failOnError' (default),
319
- * then the entire conversion fails if any element cannot be converted. If onError
320
- * is 'ignoreErrors', failing elements are silently ignored.
321
- * @param converter Converter used to convert each item in the array
322
- * @param ignoreErrors Specifies treatment of unconvertable elements
370
+ * A helper function to create a {@link Converter} which converts `unknown` to {@link ExtendedArray | ExtendedArray<T>}.
371
+ * @remarks
372
+ * If `onError` is `'failOnError'` (default), then the entire conversion fails if any element cannot
373
+ * be converted. If `onError` is `'ignoreErrors'`, then failing elements are silently ignored.
374
+ * @param converter - {@link Converter} used to convert each item in the array
375
+ * @param ignoreErrors - Specifies treatment of unconvertible elements
376
+ * @beta
323
377
  */
324
378
  function extendedArrayOf(label, converter, onError = 'failOnError') {
325
379
  return arrayOf(converter, onError).map((items) => {
@@ -328,15 +382,27 @@ function extendedArrayOf(label, converter, onError = 'failOnError') {
328
382
  }
329
383
  exports.extendedArrayOf = extendedArrayOf;
330
384
  /**
331
- * Converter to convert an unknown to an array of strings. Conversion succeeds
332
- * and returns the supplied value if it as an array of strings, fails otherwise.
385
+ * {@link Converter} to convert an `unknown` to an array of `string`.
386
+ * @remarks
387
+ * Returns {@link Success} with the the supplied value if it as an array
388
+ * of strings, returns {@link Failure} with an error message otherwise.
389
+ * @public
333
390
  */
334
391
  exports.stringArray = arrayOf(exports.string);
335
392
  /**
336
- * Converter to convert an unknown to an array of numbers. Conversion succeeds
337
- * and returns the supplied value if it as an array of numbers, fails otherwise.
393
+ * {@link Converter} to convert an `unknown` to an array of `number`.
394
+ * @remarks
395
+ * Returns {@link Success} with the the supplied value if it as an array
396
+ * of numbers, returns {@link Failure} with an error message otherwise.
397
+ * @public
338
398
  */
339
399
  exports.numberArray = arrayOf(exports.number);
400
+ /**
401
+ * Concrete implementation of {@link Converters.(recordOf:default) | Converters.recordOf(Converter<T>)},
402
+ * {@link Converters.(recordOf:withOnError) | Converters.recordOf(Converter<T>, 'fail'|'ignore')}, and
403
+ * {@link Converters.(recordOf:withOptions) | Converters.recordOf(Converter<T>, KeyedConverterOptions)}.
404
+ * @internal
405
+ */
340
406
  function recordOf(converter, option = 'fail') {
341
407
  const options = (typeof option === 'string') ? { onError: option } : { onError: 'fail', ...option };
342
408
  return new converter_1.BaseConverter((from, _self, context) => {
@@ -366,6 +432,12 @@ function recordOf(converter, option = 'fail') {
366
432
  });
367
433
  }
368
434
  exports.recordOf = recordOf;
435
+ /**
436
+ * Concrete implementation of {@link Converters.(mapOf:default) | Converters.mapOf(Converter<T>)},
437
+ * {@link Converters.(mapOf:withOnError) | Converters.mapOf(Converter<T>, 'fail'|'ignore')}, and
438
+ * {@link Converters.(mapOf:withOptions) | Converters.mapOf(Converter<T>, KeyedConverterOptions)}.
439
+ * @internal
440
+ */
369
441
  function mapOf(converter, option = 'fail') {
370
442
  const options = (typeof option === 'string') ? { onError: option } : { onError: 'fail', ...option };
371
443
  return new converter_1.BaseConverter((from, _self, context) => {
@@ -396,12 +468,16 @@ function mapOf(converter, option = 'fail') {
396
468
  }
397
469
  exports.mapOf = mapOf;
398
470
  /**
399
- * Gets a converter which validates that a supplied value is of a type validated by
400
- * a supplied validator and returns it.
401
- * @param validator A validator function to determine if the converted value is valid
402
- * @param description A description of the validate type for use in error messages
403
- * @returns If validator returns true, suceeds with from coerced to T. Fails with an error
404
- * message otherwise.
471
+ * Helper function to create a {@link Converter} which validates that a supplied value is
472
+ * of a type validated by a supplied validator function and returns it.
473
+ * @remarks
474
+ * If `validator` succeeds, this {@link Converter} returns {@link Success} with the supplied
475
+ * value of `from` coerced to type `<T>`. Returns a {@link Failure} with additional
476
+ * information otherwise.
477
+ * @param validator - A validator function to determine if the converted value is valid.
478
+ * @param description - A description of the validated type for use in error messages.
479
+ * @returns A new {@link Converter | Converter<T>} which applies the supplied validation.
480
+ * @public
405
481
  */
406
482
  function validateWith(validator, description) {
407
483
  return new converter_1.BaseConverter((from, _self, _context) => {
@@ -413,11 +489,14 @@ function validateWith(validator, description) {
413
489
  }
414
490
  exports.validateWith = validateWith;
415
491
  /**
416
- * A helper function to extract and convert an element from an array. Succeeds and returns
417
- * the converted value if the element exists in the supplied parameter and can be converted.
418
- * Fails otherwise.
419
- * @param index The index of the field to be extracted.
420
- * @param converter Converter used to convert the extracted element.
492
+ * A helper function to create a {@link Converter} which extracts and converts an element from an array.
493
+ * @remarks
494
+ * The returned {@link Converter} returns {@link Success} with the converted value if the element exists
495
+ * in the supplied array and can be converted. Returns {@link Failure} with an error message otherwise.
496
+ * @param index - The index of the element to be extracted.
497
+ * @param converter - A {@link Converter} used to convert the extracted element.
498
+ * @returns A {@link Converter | Converter<T>} which extracts the specified element from an array.
499
+ * @public
421
500
  */
422
501
  function element(index, converter) {
423
502
  return new converter_1.BaseConverter((from, _self, context) => {
@@ -435,13 +514,16 @@ function element(index, converter) {
435
514
  }
436
515
  exports.element = element;
437
516
  /**
438
- * A helper function to extract and convert an optional element from an array. Succeeds
439
- * and returns the converted value if the element exists in the supplied parameter and can
440
- * be converted. Succeeds with undefined if the parameter is an array but the index is too
441
- * large. Fails if the supplied parameter is not an array, if the requested index is negative,
442
- * or if the element cannot be converted.
443
- * @param name The name of the field to be extracted.
444
- * @param converter Converter used to convert the extracted field.
517
+ * A helper function to create a {@link Converter} which extracts and converts an optional element from an array.
518
+ * @remarks
519
+ * The resulting {@link Converter} returns {@link Success} with the converted value if the element exists
520
+ * in the supplied array and can be converted. Returns {@link Success} with value `undefined` if the parameter
521
+ * is an array but the index is out of range. Returns {@link Failure} with a message if the supplied parameter
522
+ * is not an array, if the requested index is negative, or if the element cannot be converted.
523
+ * @param index - The index of the element to be extracted.
524
+ * @param converter - A {@link Converter} used to convert the extracted element.
525
+ * @returns A {@link Converter | Converter<T>} which extracts the specified element from an array.
526
+ * @public
445
527
  */
446
528
  function optionalElement(index, converter) {
447
529
  return new converter_1.BaseConverter((from, _self, context) => {
@@ -459,11 +541,15 @@ function optionalElement(index, converter) {
459
541
  }
460
542
  exports.optionalElement = optionalElement;
461
543
  /**
462
- * A helper function to extract and convert a field from an object. Succeeds and returns
463
- * the converted value if the field exists in the supplied parameter and can be converted.
464
- * Fails otherwise.
465
- * @param name The name of the field to be extracted.
466
- * @param converter Converter used to convert the extracted field.
544
+ * A helper function to create a {@link Converter} which extracts and convert a property specified
545
+ * by name from an object.
546
+ * @remarks
547
+ * The resulting {@link Converter} returns {@link Success} with the converted value of the corresponding
548
+ * object property if the field exists and can be converted. Returns {@link Failure} with an error message
549
+ * otherwise.
550
+ * @param name - The name of the field to be extracted.
551
+ * @param converter - {@link Converter} used to convert the extracted field.
552
+ * @public
467
553
  */
468
554
  function field(name, converter) {
469
555
  return new converter_1.BaseConverter((from, _self, context) => {
@@ -480,12 +566,16 @@ function field(name, converter) {
480
566
  }
481
567
  exports.field = field;
482
568
  /**
483
- * A helper function to extract and convert an optional field from an object. Succeeds
484
- * and returns the converted value if the field exists in the supplied parameter and can
485
- * be converted. Succeeds with undefined if the parameter is an object but the named field
486
- * is not present. Fails if the supplied parameter is not an object.
487
- * @param name The name of the field to be extracted.
488
- * @param converter Converter used to convert the extracted field.
569
+ * A helper function to create a {@link Converter} which extracts and convert a property specified
570
+ * by name from an object.
571
+ * @remarks
572
+ * The resulting {@link Converter} returns {@link Success} with the converted value of the corresponding
573
+ * object property if the field exists and can be converted. Returns {@link Success} with value `undefined`
574
+ * if the supplied parameter is an object but the named field is not present. Returns {@link Failure} with
575
+ * an error message otherwise.
576
+ * @param name - The name of the field to be extracted.
577
+ * @param converter - {@link Converter} used to convert the extracted field.
578
+ * @public
489
579
  */
490
580
  function optionalField(name, converter) {
491
581
  return new converter_1.BaseConverter((from, _self, context) => {
@@ -508,12 +598,21 @@ function optionalField(name, converter) {
508
598
  }
509
599
  exports.optionalField = optionalField;
510
600
  /**
511
- * Converter to convert an object of type T without changing shape, given a @see FieldConverters<T>.
512
- * If all of the required fields exist and can be converted, returns a new object with the converted
513
- * values under the original key names. If any required fields do not exist or cannot be converted,
514
- * the entire conversion fails. See @see ObjectConverterOptions for other conversion options.
601
+ * A {@link Converter} which converts an object of type `<T>` without changing shape, given
602
+ * a {@link Converters.FieldConverters | FieldConverters<T>} for the fields in the object.
603
+ * @remarks
604
+ * By default, if all of the required fields exist and can be converted, returns a new object with
605
+ * the converted values under the original key names. If any required fields do not exist or cannot
606
+ * be converted, the entire conversion fails. See {@link Converters.ObjectConverterOptions | ObjectConverterOptions}
607
+ * for other conversion options.
608
+ * @public
515
609
  */
516
610
  class ObjectConverter extends converter_1.BaseConverter {
611
+ /**
612
+ * Concrete implementation of {@link Converters.ObjectConverter.(constructor:withOptions)}
613
+ * and {@link Converters.ObjectConverter.(constructor:withKeys)}.
614
+ * @internal
615
+ */
517
616
  constructor(fields, opt) {
518
617
  super((from, _self, context) => {
519
618
  var _a, _b;
@@ -557,64 +656,64 @@ class ObjectConverter extends converter_1.BaseConverter {
557
656
  this.options = opt !== null && opt !== void 0 ? opt : {};
558
657
  }
559
658
  }
659
+ /**
660
+ * Concrete implementation of
661
+ * {@link Converters.ObjectConverter.(partial:withOptions) | ObjectConverter.partial(ObjectConverterOptions)} and
662
+ * {@link Converters.ObjectConverter.(partial:withKeys) | ObjectConverter.partial((keyof T)[]}.
663
+ * @internal
664
+ */
560
665
  partial(opt) {
561
666
  return new ObjectConverter(this.fields, opt)._with(this._traits());
562
667
  }
563
- addPartial(addOptionalFields) {
668
+ /**
669
+ * Creates a new {@link Converters.ObjectConverter | ObjectConverter} derived from this one but with
670
+ * new optional properties as specified by a supplied array of `keyof T`.
671
+ * @param addOptionalProperties - The keys to be made optional.
672
+ * @returns A new {@link Converters.ObjectConverter | ObjectConverter} with the additional optional source
673
+ * properties.
674
+ */
675
+ addPartial(addOptionalProperties) {
564
676
  var _a;
565
- return this.partial([...(_a = this.options.optionalFields) !== null && _a !== void 0 ? _a : [], ...addOptionalFields])._with(this._traits());
677
+ return this.partial([...(_a = this.options.optionalFields) !== null && _a !== void 0 ? _a : [], ...addOptionalProperties])._with(this._traits());
566
678
  }
567
679
  }
568
680
  exports.ObjectConverter = ObjectConverter;
569
681
  /**
570
- * Helper to convert an object without changing shape. The source parameter is an object with
571
- * key names that correspond to the target object and the appropriate corresponding converter
572
- * as the property value. If all of the requested fields exist and can be converted, returns a
573
- * new object with the converted values under the original key names. If any fields do not exist
574
- * or cannot be converted, the entire conversion fails.
575
- *
576
- * Fields that succeed but convert to undefined are omitted from the result object but do not
577
- * fail the conversion.
578
- * @param fields An object containing defining the shape and converters to be applied.
579
- * @param opt An @see ObjectConverterOptions<T> containing options for the object converter, or
580
- * an array of (keyof T) containing optional keys.
682
+ * Concrete implementation of {@link Converters.(object:withOptions) | Converters.object(fields, options)}
683
+ * and {@link Converters.(object:withKeys) | Converters.objects(fields, optionalKeys)}.
684
+ * @internal
581
685
  */
582
- function object(fields, opt) {
583
- return new ObjectConverter(fields, opt);
686
+ function object(properties, options) {
687
+ return new ObjectConverter(properties, options);
584
688
  }
585
689
  exports.object = object;
586
690
  /**
587
- * Helper to convert an object without changing shape. The source parameter is an object with
588
- * key names that correspond to the target object and the appropriate corresponding converter
589
- * as the property value. If all of the requested fields exist and can be converted, returns a
590
- * new object with the converted values under the original key names. If any fields do not exist
591
- * or cannot be converted, the entire conversion fails.
592
- *
593
- * Fields that succeed but convert to undefined are omitted from the result object but do not
594
- * fail the conversion.
595
- *
596
- * The conversion fails if any unexpected fields are encountered.
597
- *
598
- * @param fields An object containing defining the shape and converters to be applied.
599
- * @param opt - An @see ObjectConverterOptions<T> containing options for the object converter, or
600
- * an array of (keyof T) containing optional keys.
691
+ * Concrete implementation for {@link Converters.(strictObject:withOptions) | Converters.strictObject(fields, options)}
692
+ * and {@link Converters.(strictObject:withKeys) | Converters.strictObject(fields, optional)}.
693
+ * @internal
601
694
  */
602
- function strictObject(fields, opt) {
695
+ function strictObject(properties, opt) {
603
696
  const options = (opt && Array.isArray(opt))
604
697
  ? { strict: true, optionalFields: opt }
605
698
  : { ...(opt !== null && opt !== void 0 ? opt : {}), strict: true };
606
- return new ObjectConverter(fields, options);
699
+ return new ObjectConverter(properties, options);
607
700
  }
608
701
  exports.strictObject = strictObject;
609
702
  /**
610
- * Helper to convert a discriminated property without changing shape. Takes the name of the
611
- * discriminator property and a string-keyed record of object converters, and invokes the
612
- * converter that corresponds to the value of the discriminator property in the source object.
613
- * Fails if the source is not an object or if the discriminator property is missing or has
614
- * a value not present in the converters.
615
- * @param discriminatorProp Name of the property used to discriminate types
616
- * @param converters String-keyed record of converters to invoke, where key corresponds to a value of the
617
- * discriminator property.
703
+ * Helper to create a {@link Converter} which converts a discriminated object without changing shape.
704
+ * @remarks
705
+ * Takes the name of the discriminator property and a
706
+ * {@link Converters.DiscriminatedObjectConverters | string-keyed Record of converters}. During conversion,
707
+ * the resulting {@link Converter} invokes the converter from `converters` that corresponds to the value of
708
+ * the discriminator property in the source object.
709
+ *
710
+ * If the source is not an object, the discriminator property is missing, or the discriminator has
711
+ * a value not present in the converters, conversion fails and returns {@link Failure} with more information.
712
+ * @param discriminatorProp - Name of the property used to discriminate types.
713
+ * @param converters - {@link Converters.DiscriminatedObjectConverters | String-keyed record of converters} to
714
+ * invoke, where each key corresponds to a value of the discriminator property.
715
+ * @returns A {@link Converter} which converts the corresponding discriminated object.
716
+ * @public
618
717
  */
619
718
  function discriminatedObject(discriminatorProp, converters) {
620
719
  return new converter_1.BaseConverter((from) => {
@@ -634,29 +733,33 @@ function discriminatedObject(discriminatorProp, converters) {
634
733
  }
635
734
  exports.discriminatedObject = discriminatedObject;
636
735
  /**
637
- * Helper to convert an object to a new object with a different shape. The source parameter is
638
- * an object with key names that correspond to the target object, and an approriate _field_
639
- * converter that will extract and convert a single field from the source object.
736
+ * Helper to create a {@link Converter} which converts a source object to a new object with a
737
+ * different shape.
640
738
  *
641
- * If all of the extracted fields exist and can be converted, returns a new object with the
642
- * converted values under the original key names. If any fields to be extracted do not exist
643
- * or cannot be converted, the entire conversion fails.
739
+ * @remarks
740
+ * On successful conversion, the resulting {@link Converter} returns {@link Success} with a new
741
+ * object, which contains the converted values under the key names specified at initialization time.
742
+ * It returns {@link Failure} with an error message if any fields to be extracted do not exist
743
+ * or cannot be converted.
644
744
  *
645
745
  * Fields that succeed but convert to undefined are omitted from the result object but do not
646
746
  * fail the conversion.
647
747
  *
648
- * @param fields An object defining the shape of the target object and the field converters
649
- * to be used to construct it.
748
+ * @param properties - An object with key names that correspond to the target object and an
749
+ * appropriate {@link Converters.FieldConverters | FieldConverter} which extracts and converts
750
+ * a single filed from the source object.
751
+ * @returns A {@link Converter} with the specified conversion behavior.
752
+ * @public
650
753
  */
651
- function transform(fields) {
754
+ function transform(properties) {
652
755
  return new converter_1.BaseConverter((from, _self, context) => {
653
756
  // eslint bug thinks key is used before defined
654
757
  // eslint-disable-next-line no-use-before-define
655
758
  const converted = {};
656
759
  const errors = [];
657
- for (const key in fields) {
658
- if (fields[key]) {
659
- const result = fields[key].convert(from, context);
760
+ for (const key in properties) {
761
+ if (properties[key]) {
762
+ const result = properties[key].convert(from, context);
660
763
  if (result.isSuccess() && (result.value !== undefined)) {
661
764
  converted[key] = result.value;
662
765
  }
@@ -670,16 +773,18 @@ function transform(fields) {
670
773
  }
671
774
  exports.transform = transform;
672
775
  /**
673
- * A helper wrapper to convert a range of some other comparable type
674
- * @param converter Converter used to convert min and max extent of the raid
675
- * @param constructor Optional static constructor to instantiate the object
776
+ * A helper wrapper to construct a {@link Converter} which converts to an arbitrary strongly-typed
777
+ * range of some comparable type.
778
+ * @param converter - {@link Converter} used to convert `min` and `max` extent of the range.
779
+ * @param constructor - Static constructor to instantiate the object.
780
+ * @public
676
781
  */
677
782
  function rangeTypeOf(converter, constructor) {
678
783
  return new converter_1.BaseConverter((from, _self, context) => {
679
784
  const result = object({
680
785
  min: converter,
681
786
  max: converter,
682
- }, ['min', 'max']).convert(from, context);
787
+ }, { optionalFields: ['min', 'max'] }).convert(from, context);
683
788
  if (result.isSuccess()) {
684
789
  return constructor({ min: result.value.min, max: result.value.max });
685
790
  }
@@ -687,8 +792,14 @@ function rangeTypeOf(converter, constructor) {
687
792
  });
688
793
  }
689
794
  exports.rangeTypeOf = rangeTypeOf;
795
+ /**
796
+ * A helper wrapper to construct a {@link Converter} which converts to {@link RangeOf | RangeOf<T>}
797
+ * where `<T>` is some comparable type.
798
+ * @param converter - {@link Converter} used to convert `min` and `max` extent of the range.
799
+ * @public
800
+ */
690
801
  function rangeOf(converter) {
691
802
  return rangeTypeOf(converter, rangeOf_1.RangeOf.createRange);
692
803
  }
693
804
  exports.rangeOf = rangeOf;
694
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVydGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb252ZXJ0ZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUNILDJDQUF3RTtBQUN4RSx1Q0FBdUQ7QUFDdkQscUNBQWdFO0FBRWhFLGlDQUFpQztBQUNqQyxtREFBZ0Q7QUFDaEQsd0RBQWdDO0FBQ2hDLG1DQUFrQztBQWVsQzs7O0dBR0c7QUFDSCxNQUFhLGVBQXlELFNBQVEseUJBQW9CO0lBQzlGOzs7OztPQUtHO0lBQ0gsWUFDSSxjQUFtQixFQUNuQixNQUF3QixFQUN4QixZQUFnRixlQUFlLENBQUMsUUFBUTtRQUV4RyxLQUFLLENBQUMsU0FBUyxFQUFFLGNBQWMsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRVMsTUFBTSxDQUFDLFFBQVEsQ0FBbUIsSUFBYTtRQUNyRCxPQUFPLE9BQU8sSUFBSSxLQUFLLFFBQVE7WUFDM0IsQ0FBQyxDQUFDLElBQUEsZ0JBQU8sRUFBQyxJQUFTLENBQUM7WUFDcEIsQ0FBQyxDQUFDLElBQUEsYUFBSSxFQUFDLGlCQUFpQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRVMsTUFBTSxDQUFDLEtBQUssQ0FDbEIsT0FBK0IsRUFDL0IsU0FBaUMsRUFDakMsTUFBd0I7UUFFeEIsT0FBTyxJQUFJLGVBQWUsQ0FBUSxTQUFTLEVBQUUsU0FBUyxFQUFFLENBQUMsSUFBYSxFQUFFLEVBQUU7WUFDdEUsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN0RCxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUF5Q00sUUFBUSxDQUFDLEtB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Z0IsU0FBMkI7SUFDOUQsT0FBTyxXQUFXLENBQW9CLFNBQVMsRUFBRSxpQkFBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQzFFLENBQUM7QUFGRCwwQkFFQyIsInNvdXJjZXNDb250ZW50IjpbIlxuLypcbiAqIENvcHlyaWdodCAoYykgMjAyMCBFcmlrIEZvcnR1bmVcbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4gKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4gKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4gKiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsXG4gKiBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuICogT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEVcbiAqIFNPRlRXQVJFLlxuICovXG5pbXBvcnQgeyBCYXNlQ29udmVydGVyLCBDb252ZXJ0ZXIsIENvbnZlcnRlclRyYWl0cyB9IGZyb20gJy4vY29udmVydGVyJztcbmltcG9ydCB7IFJhbmdlT2YsIFJhbmdlT2ZQcm9wZXJ0aWVzIH0gZnJvbSAnLi9yYW5nZU9mJztcbmltcG9ydCB7IFJlc3VsdCwgY2FwdHVyZVJlc3VsdCwgZmFpbCwgc3VjY2VlZCB9IGZyb20gJy4vcmVzdWx0JztcblxuaW1wb3J0IHsgRGF0ZVRpbWUgfSBmcm9tICdsdXhvbic7XG5pbXBvcnQgeyBFeHRlbmRlZEFycmF5IH0gZnJvbSAnLi9leHRlbmRlZEFycmF5JztcbmltcG9ydCBNdXN0YWNoZSBmcm9tICdtdXN0YWNoZSc7XG5pbXBvcnQgeyBpc0tleU9mIH0gZnJvbSAnLi91dGlscyc7XG5cbnR5cGUgT25FcnJvciA9ICdmYWlsT25FcnJvcicgfCAnaWdub3JlRXJyb3JzJztcblxuLyoqXG4gKiBPcHRpb25zIGZvciBAc2VlIFN0cmluZ0NvbnZlcnRlciBtYWNoaW5nIG1ldGhvZFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0cmluZ01hdGNoT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICogQW4gb3B0aW9uYWwgbWVzc2FnZSB0byBiZSBkaXNwbGF5ZWQgaWYgYSBub24tbWF0Y2hpbmcgc3RyaW5nXG4gICAgICogaXMgZW5jb3VudGVyZWQuXG4gICAgICovXG4gICAgbWVzc2FnZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgQHNlZSBTdHJpbmdDb252ZXJ0ZXIgY2xhc3MgZXh0ZW5kcyBAc2VlIEJhc2VDb252ZXJ0ZXIgdG8gcHJvdmlkZSBzdHJpbmctc3BlY2lmaWMgaGVscGVyXG4gKiBmdW5jdGlvbnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJpbmdDb252ZXJ0ZXI8VCBleHRlbmRzIHN0cmluZyA9IHN0cmluZywgVEMgPSB1bmtub3duPiBleHRlbmRzIEJhc2VDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3QgYSBuZXcgQHNlZSBTdHJpbmdDb252ZXJ0ZXJcbiAgICAgKiBAcGFyYW0gZGVmYXVsdENvbnRleHQgT3B0aW9uYWwgY29udGV4dCB1c2VkIGJ5IHRoZSBjb252ZXJzaW9uXG4gICAgICogQHBhcmFtIHRyYWl0cyBPcHRpb25hbCB0cmFpdHMgdG8gYmUgYXBwbGllZCB0byB0aGUgY29udmVyc2lvblxuICAgICAqIEBwYXJhbSBjb252ZXJ0ZXIgT3B0aW9uYWwgY29udmVydGVyIHRvIGJlIHVzZWQgZm9yIHRoZSBjb252ZXJzaW9uXG4gICAgICovXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKFxuICAgICAgICBkZWZhdWx0Q29udGV4dD86IFRDLFxuICAgICAgICB0cmFpdHM/OiBDb252ZXJ0ZXJUcmFpdHMsXG4gICAgICAgIGNvbnZlcnRlcjogKGZyb206IHVua25vd24sIHNlbGY6IENvbnZlcnRlcjxULCBUQz4sIGNvbnRleHQ/OiBUQykgPT4gUmVzdWx0PFQ+ID0gU3RyaW5nQ29udmVydGVyLl9jb252ZXJ0LFxuICAgICkge1xuICAgICAgICBzdXBlcihjb252ZXJ0ZXIsIGRlZmF1bHRDb250ZXh0LCB0cmFpdHMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBzdGF0aWMgX2NvbnZlcnQ8VCBleHRlbmRzIHN0cmluZz4oZnJvbTogdW5rbm93bik6IFJlc3VsdDxUPiB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgZnJvbSA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgID8gc3VjY2VlZChmcm9tIGFzIFQpXG4gICAgICAgICAgICA6IGZhaWwoYE5vdCBhIHN0cmluZzogJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgc3RhdGljIF93cmFwPFQgZXh0ZW5kcyBzdHJpbmcsIFRDPihcbiAgICAgICAgd3JhcHBlZDogU3RyaW5nQ29udmVydGVyPFQsIFRDPixcbiAgICAgICAgY29udmVydGVyOiAoZnJvbTogVCkgPT4gUmVzdWx0PFQ+LFxuICAgICAgICB0cmFpdHM/OiBDb252ZXJ0ZXJUcmFpdHNcbiAgICApOiBTdHJpbmdDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdDb252ZXJ0ZXI8VCwgVEM+KHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAoZnJvbTogdW5rbm93bikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHdyYXBwZWQuY29udmVydChmcm9tKS5vblN1Y2Nlc3MoY29udmVydGVyKTtcbiAgICAgICAgfSkuX3dpdGgod3JhcHBlZC5fdHJhaXRzKHRyYWl0cykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBAc2VlIFN0cmluZ0NvbnZlcnRlciB3aGljaCBjb25zdHJhaW5zIHRoZSByZXN1bHQgdG8gbWF0Y2ggYSBzdXBwbGllZFxuICAgICAqIHN0cmluZy5cbiAgICAgKiBAcGFyYW0gbWF0Y2ggVGhlIHN0cmluZyB0byBiZSBtYXRjaGVkXG4gICAgICogQHBhcmFtIG9wdGlvbnMgT3B0aW9uYWwgQHNlZSBTdHJpbmdNYXRjaE9wdGlvbnMgZm9yIHRoaXMgY29udmVyc2lvblxuICAgICAqIEByZXR1cm5zIEBzZWUgU3VjY2VzcyB3aXRoIGEgbWF0Y2hpbmcgc3RyaW5nIG9yIEBzZWUgRmFpbHVyZSB3aXRoIGFuIGluZm9ybWF0aXZlXG4gICAgICogZXJyb3IgaWYgdGhlIHN0cmluZyBkb2VzIG5vdCBtYXRjaC5cbiAgICAgKi9cbiAgICBwdWJsaWMgbWF0Y2hpbmcobWF0Y2g6IHN0cmluZywgb3B0aW9ucz86IFBhcnRpYWw8U3RyaW5nTWF0Y2hPcHRpb25zPik6IFN0cmluZ0NvbnZlcnRlcjxULCBUQz47XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgQHNlZSBTdHJpbmdDb252ZXJ0ZXIgd2hpY2ggY29uc3RyYWlucyB0aGUgcmVzdWx0IHRvIG1hdGNoIG9uZSBvZiBhIHN1cHBsaWVkXG4gICAgICogYXJyYXkgb2Ygc3RyaW5ncy5cbiAgICAgKiBAcGFyYW0gbWF0Y2ggVGhlIGFycmF5IHRvIGJlIHNlYXJjaGVkXG4gICAgICogQHBhcmFtIG9wdGlvbnMgT3B0aW9uYWwgQHNlZSBTdHJpbmdNYXRjaE9wdGlvbnMgZm9yIHRoaXMgY29udmVyc2lvblxuICAgICAqIEByZXR1cm5zIEBzZWUgU3VjY2VzcyB3aXRoIGEgbWF0Y2hpbmcgc3RyaW5nIG9yIEBzZWUgRmFpbHVyZSB3aXRoIGFuIGluZm9ybWF0aXZlXG4gICAgICogZXJyb3IgaWYgdGhlIHN0cmluZyBkb2VzIG5vdCBtYXRjaC5cbiAgICAgKi9cbiAgICBwdWJsaWMgbWF0Y2hpbmcobWF0Y2g6IHN0cmluZ1tdLCBvcHRpb25zPzogUGFydGlhbDxTdHJpbmdNYXRjaE9wdGlvbnM+KTogU3RyaW5nQ29udmVydGVyPFQsIFRDPjtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBAc2VlIFN0cmluZ0NvbnZlcnRlciB3aGljaCBjb25zdHJhaW5zIHRoZSByZXN1bHQgdG8gbWF0Y2ggb25lIG9mIGEgc3VwcGxpZWRcbiAgICAgKiBTZXQgb2Ygc3RyaW5ncy5cbiAgICAgKiBAcGFyYW0gbWF0Y2ggVGhlIFNldCB0byBiZSB0ZXN0ZWRcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25hbCBAc2VlIFN0cmluZ01hdGNoT3B0aW9ucyBmb3IgdGhpcyBjb252ZXJzaW9uXG4gICAgICogQHJldHVybnMgQHNlZSBTdWNjZXNzIHdpdGggYSBtYXRjaGluZyBzdHJpbmcgb3IgQHNlZSBGYWlsdXJlIHdpdGggYW4gaW5mb3JtYXRpdmVcbiAgICAgKiBlcnJvciBpZiB0aGUgc3RyaW5nIGRvZXMgbm90IG1hdGNoLlxuICAgICAqL1xuICAgIHB1YmxpYyBtYXRjaGluZyhtYXRjaDogU2V0PFQ+LCBvcHRpb25zPzogUGFydGlhbDxTdHJpbmdNYXRjaE9wdGlvbnM+KTogU3RyaW5nQ29udmVydGVyPFQsIFRDPjtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBAc2VlIFN0cmluZ0NvbnZlcnRlciB3aGljaCBjb25zdHJhaW5zIHRoZSByZXN1bHQgdG8gbWF0Y2ggYSBzdXBwbGllZCByZWd1bGFyXG4gICAgICogZXhwcmVzc2lvbi5cbiAgICAgKiBAcGFyYW0gbWF0Y2ggVGhlIEBzZWUgUmVnRXhwIHRvIGJlIHRlc3RlZFxuICAgICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbmFsIEBzZWUgU3RyaW5nTWF0Y2hPcHRpb25zIGZvciB0aGlzIGNvbnZlcnNpb25cbiAgICAgKiBAcmV0dXJucyBAc2VlIFN1Y2Nlc3Mgd2l0aCBhIG1hdGNoaW5nIHN0cmluZyBvciBAc2VlIEZhaWx1cmUgd2l0aCBhbiBpbmZvcm1hdGl2ZVxuICAgICAqIGVycm9yIGlmIHRoZSBzdHJpbmcgZG9lcyBub3QgbWF0Y2guXG4gICAgICovXG4gICAgcHVibGljIG1hdGNoaW5nKG1hdGNoOiBSZWdFeHAsIG9wdGlvbnM/OiBQYXJ0aWFsPFN0cmluZ01hdGNoT3B0aW9ucz4pOiBTdHJpbmdDb252ZXJ0ZXI8VCwgVEM+O1xuICAgIHB1YmxpYyBtYXRjaGluZyhtYXRjaDogc3RyaW5nIHwgc3RyaW5nW10gfCBTZXQ8VD4gfCBSZWdFeHAsIG9wdGlvbnM/OiBQYXJ0aWFsPFN0cmluZ01hdGNoT3B0aW9ucz4pOiBTdHJpbmdDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IG9wdGlvbnM/Lm1lc3NhZ2U7XG4gICAgICAgIGlmICh0eXBlb2YgbWF0Y2ggPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gU3RyaW5nQ29udmVydGVyLl93cmFwPFQsIFRDPih0aGlzLCAoZnJvbTogVCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiAobWF0Y2ggPT09IGZyb20pXG4gICAgICAgICAgICAgICAgICAgID8gc3VjY2VlZChmcm9tIGFzIFQpXG4gICAgICAgICAgICAgICAgICAgIDogZmFpbChtZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgICAgICA/IGBcIiR7ZnJvbX1cIjogJHttZXNzYWdlfWBcbiAgICAgICAgICAgICAgICAgICAgICAgIDogYFwiJHtmcm9tfVwiOiBkb2VzIG5vdCBtYXRjaCBcIiR7bWF0Y2h9XCJgKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG1hdGNoIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXR1cm4gU3RyaW5nQ29udmVydGVyLl93cmFwPFQsIFRDPih0aGlzLCAoZnJvbTogVCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiAobWF0Y2gudGVzdChmcm9tKSlcbiAgICAgICAgICAgICAgICAgICAgPyBzdWNjZWVkKGZyb20gYXMgVClcbiAgICAgICAgICAgICAgICAgICAgOiBmYWlsKG1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgID8gYFwiJHtmcm9tfVwiOiAke21lc3NhZ2V9YFxuICAgICAgICAgICAgICAgICAgICAgICAgOiBgXCIke2Zyb219XCI6IGRvZXMgbm90IG1hdGNoIFwiJHttYXRjaH1cImApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobWF0Y2ggaW5zdGFuY2VvZiBTZXQpIHtcbiAgICAgICAgICAgIHJldHVybiBTdHJpbmdDb252ZXJ0ZXIuX3dyYXA8VCwgVEM+KHRoaXMsIChmcm9tOiBUKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChtYXRjaC5oYXMoZnJvbSkpXG4gICAgICAgICAgICAgICAgICAgID8gc3VjY2VlZChmcm9tIGFzIFQpXG4gICAgICAgICAgICAgICAgICAgIDogZmFpbChtZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgICAgICA/IGBcIiR7ZnJvbX1cIjogJHttZXNzYWdlfWBcbiAgICAgICAgICAgICAgICAgICAgICAgIDogYFwiJHtmcm9tfVwiOiBub3QgZm91bmQgaW4gc2V0YCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBTdHJpbmdDb252ZXJ0ZXIuX3dyYXA8VCwgVEM+KHRoaXMsIChmcm9tOiBUKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChtYXRjaC5pbmNsdWRlcyhmcm9tKSlcbiAgICAgICAgICAgICAgICAgICAgPyBzdWNjZWVkKGZyb20gYXMgVClcbiAgICAgICAgICAgICAgICAgICAgOiBmYWlsKG1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgID8gYFwiJHtmcm9tfVwiOiAke21lc3NhZ2V9YFxuICAgICAgICAgICAgICAgICAgICAgICAgOiBgXCIke2Zyb219XCI6IG5vdCBmb3VuZCBpbiBbJHttYXRjaC5qb2luKCcsJyl9XWApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogQSBjb252ZXJ0ZXIgdG8gY29udmVydCB1bmtub3duIHRvIHN0cmluZy4gVmFsdWVzIG9mIHR5cGVcbiAqIHN0cmluZyBzdWNjZWVkLiAgQW55dGhpbmcgZWxzZSBmYWlscy5cbiAqL1xuZXhwb3J0IGNvbnN0IHN0cmluZyA9IG5ldyBTdHJpbmdDb252ZXJ0ZXIoKTtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEgY29udmVydGVyIHdoaWNoIGNvbnZlcnRzIHVua25vd24gdG8gc3RyaW5nLCBhcHBseWluZ1xuICogdGVtcGxhdGUgY29udmVyc2lvbnMgc3VwcGxpZWQgYXQgY29uc3RydWN0aW9uIHRpbWUgb3IgYXQgcnVudGltZSBhcyBjb250ZXh0LlxuICogQHBhcmFtIGRlZmF1bHRDb250ZXh0IG9wdGlvbmFsIGRlZmF1bHQgY29udGV4dCB0byB1c2UgZm9yIHRlbXBsYXRlIHZhbHVlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdGVtcGxhdGVTdHJpbmcoZGVmYXVsdENvbnRleHQ/OiB1bmtub3duKTogU3RyaW5nQ29udmVydGVyPHN0cmluZywgdW5rbm93bj4ge1xuICAgIHJldHVybiBuZXcgU3RyaW5nQ29udmVydGVyPHN0cmluZywgdW5rbm93bj4oZGVmYXVsdENvbnRleHQsIHVuZGVmaW5lZCwgKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8c3RyaW5nLCB1bmtub3duPiwgY29udGV4dD86IHVua25vd24pID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBmcm9tICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYE5vdCBhIHN0cmluZzogJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FwdHVyZVJlc3VsdCgoKSA9PiBNdXN0YWNoZS5yZW5kZXIoZnJvbSwgY29udGV4dCkpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEEgY29udmVydGVyIHRvIGNvbnZlcnQgdW5rbm93biB0byBvbmUgb2YgYSBzZXQgb2Ygc3VwcGxpZWQgZW51bWVyYXRlZCB2YWx1ZXMuIEFueXRoaW5nIGVsc2UgZmFpbHMuXG4gKiBBbGxvd2VkIGVudW1lcmF0ZWQgdmFsdWVzIGNhbiBhbHNvIGJlIHN1cHBsaWVkIGFzIGNvbnRleHQgYXQgY29udmVyc2lvbiB0aW1lLlxuICogQHBhcmFtIHZhbHVlcyBBcnJheSBvZiBhbGxvd2VkIHZhbHVlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZW51bWVyYXRlZFZhbHVlPFQ+KHZhbHVlczogVFtdKTogQ29udmVydGVyPFQsIFRbXT4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxULCBUW10+LCBjb250ZXh0PzogVFtdKTogUmVzdWx0PFQ+ID0+IHtcbiAgICAgICAgY29uc3QgdiA9IGNvbnRleHQgPz8gdmFsdWVzO1xuICAgICAgICBjb25zdCBpbmRleCA9IHYuaW5kZXhPZihmcm9tIGFzIFQpO1xuICAgICAgICByZXR1cm4gKGluZGV4ID49IDAgPyBzdWNjZWVkKHZbaW5kZXhdKSA6IGZhaWwoYEludmFsaWQgZW51bWVyYXRlZCB2YWx1ZSAke0pTT04uc3RyaW5naWZ5KGZyb20pfWApKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB1bmtub3duIHRvIG9uZSBvZiBhIHNldCBvZiBzdXBwbGllZCBlbnVtZXJhdGVkIHZhbHVlcywgbWFwcGluZyBhbnkgb2YgbXVsdGlwbGUgc3VwcGxpZWRcbiAqIHZhbHVlcyB0byB0aGUgZW51bWVyYXRpb24uIEVuYWJsZXMgbWFwcGluZyBvZiBtdWx0aXBsZSBpbnB1dCB2YWx1ZXMgdG8gYSBjb25zaXN0ZW50IGludGVybmFsXG4gKiByZXByZXNlbnRhdGlvbiAoc28gZS5nLiAneScsICd5ZXMnLCAndHJ1ZScgYW5kIHRydWUgY2FuIGFsbCBtYXAgdG8gYm9vbGVhbiB0cnVlKVxuICogQHBhcmFtIG1hcCBBbiBhcnJheSBvZiB0dXBsZXMgZGVzY3JpYmluZyB0aGUgbWFwcGluZy4gVGhlIGZpcnN0IGVsZW1lbnQgb2YgZWFjaCB0dXBsZSBpcyB0aGUgcmVzdWx0XG4gKiB2YWx1ZSwgdGhlIHNlY29uZCBpcyB0aGUgc2V0IG9mIHZhbHVlcyB0aGF0IG1hcCB0byB0aGUgcmVzdWx0LiAgVHVwbGVzIGFyZSBldmFsdWF0ZWQgaW4gdGhlIG9yZGVyXG4gKiBzdXBwbGllZCBhbmQgYXJlIG5vdCBjaGVja2VkIGZvciBkdXBsaWNhdGVzLlxuICogQHBhcmFtIG1lc3NhZ2UgYW4gb3B0aW9uYWwgZXJyb3IgbWVzc2FnZVxuICogQHJldHVybnMgVGhlIG1hcHBlZCB2YWx1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFwcGVkRW51bWVyYXRlZFZhbHVlPFQ+KG1hcDogW1QsIHVua25vd25bXV1bXSwgbWVzc2FnZT86IHN0cmluZyk6IENvbnZlcnRlcjxULCB1bmRlZmluZWQ+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VCwgdW5kZWZpbmVkPiwgX2NvbnRleHQ/OiB1bmtub3duKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBtYXApIHtcbiAgICAgICAgICAgIGlmIChpdGVtWzFdLmluY2x1ZGVzKGZyb20pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1Y2NlZWQoaXRlbVswXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhaWwobWVzc2FnZSA/IGAke0pTT04uc3RyaW5naWZ5KGZyb20pfTogJHttZXNzYWdlfWAgOiBgQ2Fubm90IG1hcCAnJHtKU09OLnN0cmluZ2lmeShmcm9tKX0nIHRvIGEgc3VwcG9ydGVkIHZhbHVlYCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBjb252ZXJ0ZXIgdG8gY29udmVydCB1bmtub3duIHRvIHNvbWUgdmFsdWUuIFN1Y2NlZWRzIHdpdGggdGhlIHN1cHBsaWVkIHZhbHVlIGlmIGFuIGlkZW50aXR5XG4gKiBjb21wYXJpc29uIHN1Y2NlZWRzLCBmYWlscyBvdGhlcndpc2UuXG4gKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIGJlIGNvbXBhcmVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaXRlcmFsPFQ+KHZhbHVlOiBUKTogQ29udmVydGVyPFQsIHVua25vd24+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXI8VCwgdW5rbm93bj4oKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VCwgdW5rbm93bj4sIF9jb250ZXh0PzogdW5rbm93bik6IFJlc3VsdDxUPiA9PiB7XG4gICAgICAgIHJldHVybiAoZnJvbSA9PT0gdmFsdWUpID8gc3VjY2VlZCh2YWx1ZSkgOiBmYWlsKGAke0pTT04uc3RyaW5naWZ5KGZyb20pfTogZG9lcyBub3QgbWF0Y2ggJHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9YCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogRGVwcmVjYXRlZCBhbGlhcyBmb3IgQHNlZSBsaXRlcmFsXG4gKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIGJlIGNvbXBhcmVkXG4gKiBAZGVwcmVjYXRlZCB1c2UgbGl0ZXJhbCBpbnN0ZWFkXG4gKi9cbmV4cG9ydCBjb25zdCB2YWx1ZSA9IGxpdGVyYWw7XG5cbi8qKlxuICogQSBjb252ZXJ0ZXIgdG8gY29udmVydCB1bmtub3duIHRvIGEgbnVtYmVyLiAgTnVtYmVycyBhbmQgc3RyaW5nc1xuICogd2l0aCBhIG51bWVyaWMgZm9ybWF0IHN1Y2NlZWQuICBBbnl0aGluZyBlbHNlIGZhaWxzLlxuICovXG5leHBvcnQgY29uc3QgbnVtYmVyID0gbmV3IEJhc2VDb252ZXJ0ZXI8bnVtYmVyPigoZnJvbTogdW5rbm93bikgPT4ge1xuICAgIGlmICh0eXBlb2YgZnJvbSAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgY29uc3QgbnVtOiBudW1iZXIgPSAodHlwZW9mIGZyb20gPT09ICdzdHJpbmcnID8gTnVtYmVyKGZyb20pIDogTmFOKTtcbiAgICAgICAgcmV0dXJuIGlzTmFOKG51bSlcbiAgICAgICAgICAgID8gZmFpbChgTm90IGEgbnVtYmVyOiAke0pTT04uc3RyaW5naWZ5KGZyb20pfWApXG4gICAgICAgICAgICA6IHN1Y2NlZWQobnVtKTtcbiAgICB9XG4gICAgcmV0dXJuIHN1Y2NlZWQoZnJvbSk7XG59KTtcblxuLyoqXG4gKiBBIGNvbnZlcnRlciB0byBjb252ZXJ0IHVua25vd24gdG8gYm9vbGVhbi4gQm9vbGVhbiB2YWx1ZXMgb3IgdGhlXG4gKiBjYXNlLWluc2Vuc2l0aXZlIHN0cmluZ3MgJ3RydWUnIGFuZCAnZmFsc2UnIHN1Y2NlZWQuICBBbnl0aGluZ1xuICogZWxzZSBmYWlscy5cbiAqL1xuZXhwb3J0IGNvbnN0IGJvb2xlYW4gPSBuZXcgQmFzZUNvbnZlcnRlcjxib29sZWFuPigoZnJvbTogdW5rbm93bikgPT4ge1xuICAgIGlmICh0eXBlb2YgZnJvbSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHJldHVybiBzdWNjZWVkKGZyb20gYXMgYm9vbGVhbik7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBmcm9tID09PSAnc3RyaW5nJykge1xuICAgICAgICBzd2l0Y2ggKGZyb20udG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSAndHJ1ZSc6IHJldHVybiBzdWNjZWVkKHRydWUpO1xuICAgICAgICAgICAgY2FzZSAnZmFsc2UnOiByZXR1cm4gc3VjY2VlZChmYWxzZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhaWwoYE5vdCBhIGJvb2xlYW46ICR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9YCk7XG59KTtcblxuLyoqXG4gKiBBIGNvbnZlcnRlciB0byBjb252ZXJ0IGFuIG9wdGlvbmFsIHN0cmluZyB2YWx1ZS4gVmFsdWVzIG9mIHR5cGUgc3RyaW5nXG4gKiBhcmUgcmV0dXJuZWQuICBBbnl0aGluZyBlbHNlIHJldHVybnMgc3VjY2VzcyB3aXRoIGFuIHVuZGVmaW5lZCB2YWx1ZS5cbiAqL1xuZXhwb3J0IGNvbnN0IG9wdGlvbmFsU3RyaW5nID0gc3RyaW5nLm9wdGlvbmFsKCk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNvbnZlcnRlciB3aGljaCBjb252ZXJ0cyBhbnkgc3RyaW5nIGludG8gYW4gYXJyYXkgb2Ygc3RyaW5nc1xuICogYnkgc2VwYXJhdGluZyBhdCBhIHN1cHBsaWVkIGRlbGltaXRlci4gRGVsaW1ldGVyIG1heSBhbHNvIGJlIHN1cHBsaWVkXG4gKiBhcyBjb250ZXh0IGF0IGNvbnZlcnNpb24gdGltZS5cbiAqIEBwYXJhbSBkZWxpbWl0ZXIgVGhlIGRlbGltaXRlciBhdCB3aGljaCB0byBzcGxpdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlbGltaXRlZFN0cmluZyhkZWxpbWl0ZXI6IHN0cmluZywgb3B0aW9uczogJ2ZpbHRlcmVkJ3wnYWxsJyA9ICdmaWx0ZXJlZCcpOiBDb252ZXJ0ZXI8c3RyaW5nW10sIHN0cmluZz4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcjxzdHJpbmdbXSwgc3RyaW5nPigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxzdHJpbmdbXSwgc3RyaW5nPiwgY29udGV4dD86IHN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBzdHJpbmcuY29udmVydChmcm9tKTtcbiAgICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSkge1xuICAgICAgICAgICAgbGV0IHN0cmluZ3MgPSByZXN1bHQudmFsdWUuc3BsaXQoY29udGV4dCA/PyBkZWxpbWl0ZXIpO1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMgIT09ICdhbGwnKSB7XG4gICAgICAgICAgICAgICAgc3RyaW5ncyA9IHN0cmluZ3MuZmlsdGVyKChzKSA9PiAocy50cmltKCkubGVuZ3RoID4gMCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN1Y2NlZWQoc3RyaW5ncyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhaWwocmVzdWx0Lm1lc3NhZ2UpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEEgY29udmVydGVyIHRvIGNvbnZlcnQgYW4gaXNvIGZvcm1hdHRlZCBzdHJpbmcsIGEgbnVtYmVyIG9yIGEgRGF0ZSBvYmplY3QgdG8gYSBEYXRlIG9iamVjdFxuICovXG5leHBvcnQgY29uc3QgaXNvRGF0ZSA9IG5ldyBCYXNlQ29udmVydGVyPERhdGU+KChmcm9tOiB1bmtub3duKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBmcm9tID09PSAnc3RyaW5nJykge1xuICAgICAgICBjb25zdCBkdCA9IERhdGVUaW1lLmZyb21JU08oZnJvbSk7XG4gICAgICAgIGlmIChkdC5pc1ZhbGlkKSB7XG4gICAgICAgICAgICByZXR1cm4gc3VjY2VlZChkdC50b0pTRGF0ZSgpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFpbChgSW52YWxpZCBkYXRlOiAke2R0LmludmFsaWRFeHBsYW5hdGlvbn1gKTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIGZyb20gPT09ICdudW1iZXInKSB7XG4gICAgICAgIHJldHVybiBzdWNjZWVkKG5ldyBEYXRlKGZyb20pKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoZnJvbSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgcmV0dXJuIHN1Y2NlZWQoZnJvbSk7XG4gICAgfVxuICAgIHJldHVybiBmYWlsKGBDYW5ub3QgY29udmVydCAke0pTT04uc3RyaW5naWZ5KGZyb20pfSB0byBEYXRlYCk7XG59KTtcblxuLyoqXG4gKiBBIGNvbnZlcnRlciB0byBjb252ZXJ0IGFuIG9wdGlvbmFsIG51bWJlciB2YWx1ZS4gVmFsdWVzIG9mIHR5cGUgbnVtYmVyXG4gKiBvciBudW1lcmljIHN0cmluZ3MgYXJlIGNvbnZlcnRlZCBhbmQgcmV0dXJuZWQuIEFueXRoaW5nIGVsc2UgcmV0dXJuc1xuICogc3VjY2VzcyB3aXRoIGFuIHVuZGVmaW5lZCB2YWx1ZS5cbiAqL1xuZXhwb3J0IGNvbnN0IG9wdGlvbmFsTnVtYmVyID0gbnVtYmVyLm9wdGlvbmFsKCk7XG5cbi8qKlxuICogQSBjb252ZXJ0ZXIgdG8gY29udmVydCBhbiBvcHRpb25hbCBib29sZWFuIHZhbHVlLiBWYWx1ZXMgb2YgdHlwZSBib29sZWFuXG4gKiBvciBzdHJpbmdzIHRoYXQgbWF0Y2ggKGNhc2UtaW5zZW5zaXRpdmUpICd0cnVlJyBvciAnZmFsc2UnIGFyZSBjb252ZXJ0ZWRcbiAqIGFuZCByZXR1cm5lZC4gIEFueXRoaW5nIGVsc2UgcmV0dXJucyBzdWNjZXNzIHdpdGggYW4gdW5kZWZpbmVkIHZhbHVlLlxuICovXG5leHBvcnQgY29uc3Qgb3B0aW9uYWxCb29sZWFuID0gYm9vbGVhbi5vcHRpb25hbCgpO1xuXG4vKipcbiAqIEEgaGVscGVyIHdyYXBwZXIgZm9yIHBvbHltb3JwaGljIGZpZWxkcy4gSW52b2tlcyB0aGUgd3JhcHBlZCBjb252ZXJ0ZXJzXG4gKiBpbiBzZXF1ZW5jZSwgcmV0dXJuaW5nIHRoZSBmaXJzdCBzdWNjZXNzZnVsIHJlc3VsdC4gIFJldHVybnMgYW4gZXJyb3JcbiAqIGlmIG5vbmUgb2YgdGhlIHN1cHBsaWVkIGNvbnZlcnRlcnMgY2FuIGNvbnZlcnQgdGhlIHZhbHVlLlxuICpcbiAqIElmIG9uRXJyb3IgaXMgJ2lnbm9yZUVycm9ycycgKGRlZmF1bHQpLCB0aGVuIGVycm9ycyBmcm9tIGFueSBvZiB0aGVcbiAqIGNvbnZlcnRlcnMgYXJlIGlnbm9yZWQgcHJvdmlkZWQgdGhhdCBzb21lIGNvbnZlcnRlciBzdWNjZWVkcy4gIElmXG4gKiBvbkVycm9yIGlzICdmYWlsT25FcnJvcicsIHRoZW4gYW4gZXJyb3IgZnJvbSBhbnkgY29udmVydGVyIGZhaWxzIHRoZSBlbnRpcmVcbiAqIGNvbnZlcnNpb24uXG4gKlxuICogQHBhcmFtIGNvbnZlcnRlcnMgQW4gb3JkZXJlZCBsaXN0IG9mIGNvbnZlcnRlcnMgdG8gYmUgY29uc2lkZXJlZFxuICogQHBhcmFtIG9uRXJyb3IgU3BlY2lmaWVzIHRyZWF0bWVudCBvZiB1bmNvbnZlcnRhYmxlIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbmVPZjxULCBUQz11bmtub3duPihjb252ZXJ0ZXJzOiBBcnJheTxDb252ZXJ0ZXI8VCwgVEM+Piwgb25FcnJvcjogT25FcnJvciA9ICdpZ25vcmVFcnJvcnMnKTogQ29udmVydGVyPFQsIFRDPiB7XG4gICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyKChmcm9tOiB1bmtub3duLCBfc2VsZiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBjb252ZXJ0ZXIgb2YgY29udmVydGVycykge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gY29udmVydGVyLmNvbnZlcnQoZnJvbSwgY29udGV4dCk7XG4gICAgICAgICAgICBpZiAocmVzdWx0LmlzU3VjY2VzcygpICYmIChyZXN1bHQudmFsdWUgIT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVzdWx0LmlzRmFpbHVyZSgpKSB7XG4gICAgICAgICAgICAgICAgaWYgKG9uRXJyb3IgPT09ICdmYWlsT25FcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZXJyb3JzLnB1c2gocmVzdWx0Lm1lc3NhZ2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWlsKGBObyBtYXRjaGluZyBjb252ZXJ0ZXIgZm9yICR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9OiAke2Vycm9ycy5qb2luKCdcXG4nKX1gKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBIGhlbHBlciB3cmFwcGVyIGZvciBjb252ZXJ0aW5nIGFuIGFycmF5IG9mIDxUPi4gIElmIG9uRXJyb3IgaXMgJ2ZhaWxPbkVycm9yJyAoZGVmYXVsdCksXG4gKiB0aGVuIHRoZSBlbnRpcmUgY29udmVyc2lvbiBmYWlscyBpZiBhbnkgZWxlbWVudCBjYW5ub3QgYmUgY29udmVydGVkLiAgSWYgb25FcnJvclxuICogaXMgJ2lnbm9yZUVycm9ycycsIGZhaWxpbmcgZWxlbWVudHMgYXJlIHNpbGVudGx5IGlnbm9yZWQuXG4gKiBAcGFyYW0gY29udmVydGVyIENvbnZlcnRlciB1c2VkIHRvIGNvbnZlcnQgZWFjaCBpdGVtIGluIHRoZSBhcnJheVxuICogQHBhcmFtIGlnbm9yZUVycm9ycyBTcGVjaWZpZXMgdHJlYXRtZW50IG9mIHVuY29udmVydGFibGUgZWxlbWVudHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFycmF5T2Y8VCwgVEM9dW5kZWZpbmVkPihjb252ZXJ0ZXI6IENvbnZlcnRlcjxULCBUQz4sIG9uRXJyb3I6IE9uRXJyb3IgPSAnZmFpbE9uRXJyb3InKTogQ29udmVydGVyPFRbXSwgVEM+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VFtdLCBUQz4sIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoZnJvbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKGBOb3QgYW4gYXJyYXk6ICR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdWNjZXNzZXM6IFRbXSA9IFtdO1xuICAgICAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG4gICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBmcm9tKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBjb252ZXJ0ZXIuY29udmVydChpdGVtLCBjb250ZXh0KTtcbiAgICAgICAgICAgIGlmIChyZXN1bHQuaXNTdWNjZXNzKCkgJiYgcmVzdWx0LnZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzZXMucHVzaChyZXN1bHQudmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAocmVzdWx0LmlzRmFpbHVyZSgpKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JzLnB1c2gocmVzdWx0Lm1lc3NhZ2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChlcnJvcnMubGVuZ3RoID09PSAwKSB8fCAob25FcnJvciA9PT0gJ2lnbm9yZUVycm9ycycpXG4gICAgICAgICAgICA/IHN1Y2NlZWQoc3VjY2Vzc2VzKVxuICAgICAgICAgICAgOiBmYWlsKGVycm9ycy5qb2luKCdcXG4nKSk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBoZWxwZXIgd3JhcHBlciBmb3IgY29udmVydGluZyB0byBJdGVtcnJheTxUPi4gIElmIG9uRXJyb3IgaXMgJ2ZhaWxPbkVycm9yJyAoZGVmYXVsdCksXG4gKiB0aGVuIHRoZSBlbnRpcmUgY29udmVyc2lvbiBmYWlscyBpZiBhbnkgZWxlbWVudCBjYW5ub3QgYmUgY29udmVydGVkLiAgSWYgb25FcnJvclxuICogaXMgJ2lnbm9yZUVycm9ycycsIGZhaWxpbmcgZWxlbWVudHMgYXJlIHNpbGVudGx5IGlnbm9yZWQuXG4gKiBAcGFyYW0gY29udmVydGVyIENvbnZlcnRlciB1c2VkIHRvIGNvbnZlcnQgZWFjaCBpdGVtIGluIHRoZSBhcnJheVxuICogQHBhcmFtIGlnbm9yZUVycm9ycyBTcGVjaWZpZXMgdHJlYXRtZW50IG9mIHVuY29udmVydGFibGUgZWxlbWVudHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4dGVuZGVkQXJyYXlPZjxULCBUQz11bmRlZmluZWQ+KGxhYmVsOiBzdHJpbmcsIGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPiwgb25FcnJvcjogT25FcnJvciA9ICdmYWlsT25FcnJvcicpOiBDb252ZXJ0ZXI8RXh0ZW5kZWRBcnJheTxUPiwgVEM+IHtcbiAgICByZXR1cm4gYXJyYXlPZihjb252ZXJ0ZXIsIG9uRXJyb3IpLm1hcCgoaXRlbXM6IFRbXSkgPT4ge1xuICAgICAgICByZXR1cm4gY2FwdHVyZVJlc3VsdCgoKSA9PiBuZXcgRXh0ZW5kZWRBcnJheShsYWJlbCwgLi4uaXRlbXMpKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0ZXIgdG8gY29udmVydCBhbiB1bmtub3duIHRvIGFuIGFycmF5IG9mIHN0cmluZ3MuIENvbnZlcnNpb24gc3VjY2VlZHNcbiAqIGFuZCByZXR1cm5zIHRoZSBzdXBwbGllZCB2YWx1ZSBpZiBpdCBhcyBhbiBhcnJheSBvZiBzdHJpbmdzLCBmYWlscyBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBjb25zdCBzdHJpbmdBcnJheSA9IGFycmF5T2Yoc3RyaW5nKTtcblxuLyoqXG4gKiBDb252ZXJ0ZXIgdG8gY29udmVydCBhbiB1bmtub3duIHRvIGFuIGFycmF5IG9mIG51bWJlcnMuIENvbnZlcnNpb24gc3VjY2VlZHNcbiAqIGFuZCByZXR1cm5zIHRoZSBzdXBwbGllZCB2YWx1ZSBpZiBpdCBhcyBhbiBhcnJheSBvZiBudW1iZXJzLCBmYWlscyBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBjb25zdCBudW1iZXJBcnJheSA9IGFycmF5T2YobnVtYmVyKTtcblxuLyoqXG4gKiBPcHRpb25zIGZvciAncmVjb3JkT2YnIGFuZCAnbWFwT2YnIGNvbnZlcnRlcnNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBLZXllZENvbnZlcnRlck9wdGlvbnM8VCBleHRlbmRzIHN0cmluZyA9IHN0cmluZywgVEM9dW5kZWZpbmVkPiB7XG4gICAgb25FcnJvcj86ICdmYWlsJ3wnaWdub3JlJztcbiAgICBrZXlDb252ZXJ0ZXI/OiBDb252ZXJ0ZXI8VCwgVEM+O1xufVxuXG4vKipcbiAqIEEgaGVscGVyIHdyYXBwZXIgdG8gY29udmVydCB0aGUgc3RyaW5nLWtleWVkIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0IHRvIGEgUmVjb3JkIG9mIFQuXG4gKiBDb252ZXJzaW9uIGZhaWxzIGlmIGFueSBlbGVtZW50IGNhbm5vdCBiZSBjb252ZXJ0ZWQuICBJZiBvbkVycm9yIGlzICdpZ25vcmUnIGZhaWxpbmdcbiAqIGVsZW1lbnRzIGFyZSBzaWxlbnRseSBpZ25vcmVkLlxuICogQHBhcmFtIGNvbnZlcnRlciBDb252ZXJ0ZXIgdXNlZCB0byBjb252ZXJ0IGVhY2ggaXRlbSBpbiB0aGUgcmVjb3JkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRPZjxULCBUQz11bmRlZmluZWQsIFRLIGV4dGVuZHMgc3RyaW5nPXN0cmluZz4oY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+KTogQ29udmVydGVyPFJlY29yZDxUSywgVD4sIFRDPjtcblxuLyoqXG4gKiBBIGhlbHBlciB3cmFwcGVyIHRvIGNvbnZlcnQgdGhlIHN0cmluZy1rZXllZCBwcm9wZXJ0aWVzIG9mIGFuIG9iamVjdCB0byBhIFJlY29yZCBvZiBULlxuICogSWYgb25FcnJvciBpcyAnZmFpbCcgKGRlZmF1bHQpLCAgdGhlbiB0aGUgZW50aXJlIGNvbnZlcnNpb24gZmFpbHMgaWYgYW55IGVsZW1lbnRcbiAqIGNhbm5vdCBiZSBjb252ZXJ0ZWQuICBJZiBvbkVycm9yIGlzICdpZ25vcmUnIGZhaWxpbmcgZWxlbWVudHMgYXJlIHNpbGVudGx5IGlnbm9yZWQuXG4gKiBAcGFyYW0gY29udmVydGVyIENvbnZlcnRlciB1c2VkIHRvIGNvbnZlcnQgZWFjaCBpdGVtIGluIHRoZSByZWNvcmRcbiAqIEBwYXJhbSBvbkVycm9yIFNwZWNpZmllcyB0cmVhdG1lbnQgb2YgdW5jb252ZXJ0YWJsZSBlbGVtZW50c1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkT2Y8VCwgVEM9dW5kZWZpbmVkLCBUSyBleHRlbmRzIHN0cmluZz1zdHJpbmc+KFxuICAgIGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPixcbiAgICBvbkVycm9yOiAnZmFpbCd8J2lnbm9yZSdcbik6IENvbnZlcnRlcjxSZWNvcmQ8VEssIFQ+LCBUQz47XG5cbi8qKlxuICogQSBoZWxwZXIgd3JhcHBlciB0byBjb252ZXJ0IHRoZSBzdHJpbmcta2V5ZWQgcHJvcGVydGllcyBvZiBhbiBvYmplY3QgdG8gYSBSZWNvcmQgb2YgVC5cbiAqIElmIG9wdGlvbnMgc3BlY2lmeSBhIGtleSBjb252ZXJ0ZXIgaXQgd2lsbCBiZSBhcHBsaWVkIHRvIGVhY2gga2V5LlxuICogSWYgb25FcnJvciBpcyAnZmFpbCcgKGRlZmF1bHQpLCAgdGhlbiB0aGUgZW50aXJlIGNvbnZlcnNpb24gZmFpbHMgaWYgYW55IGtleSBvciBlbGVtZW50XG4gKiBjYW5ub3QgYmUgY29udmVydGVkLiAgSWYgb25FcnJvciBpcyAnaWdub3JlJyBmYWlsaW5nIGVsZW1lbnRzIGFyZSBzaWxlbnRseSBpZ25vcmVkLlxuICogQHBhcmFtIGNvbnZlcnRlciBDb252ZXJ0ZXIgdXNlZCB0byBjb252ZXJ0IGVhY2ggaXRlbSBpbiB0aGUgcmVjb3JkXG4gKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25hbCBAc2VlIEtleWVkQ29udmVydGVyT3B0aW9uc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkT2Y8VCwgVEM9dW5kZWZpbmVkLCBUSyBleHRlbmRzIHN0cmluZz1zdHJpbmc+KFxuICAgIGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPixcbiAgICBvcHRpb25zOiBLZXllZENvbnZlcnRlck9wdGlvbnM8VEssIFRDPlxuKTogQ29udmVydGVyPFJlY29yZDxUSywgVD4sIFRDPjtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlY29yZE9mPFQsIFRDPXVuZGVmaW5lZCwgVEsgZXh0ZW5kcyBzdHJpbmc9c3RyaW5nPihcbiAgICBjb252ZXJ0ZXI6IENvbnZlcnRlcjxULCBUQz4sXG4gICAgb3B0aW9uOiAnZmFpbCd8J2lnbm9yZSd8S2V5ZWRDb252ZXJ0ZXJPcHRpb25zPFRLLCBUQz4gPSAnZmFpbCdcbik6IENvbnZlcnRlcjxSZWNvcmQ8VEssIFQ+LCBUQz4ge1xuICAgIGNvbnN0IG9wdGlvbnM6IEtleWVkQ29udmVydGVyT3B0aW9uczxUSywgVEM+ID0gKHR5cGVvZiBvcHRpb24gPT09ICdzdHJpbmcnKSA/IHsgb25FcnJvcjogb3B0aW9uIH0gOiB7IG9uRXJyb3I6ICdmYWlsJywgLi4ub3B0aW9uIH07XG4gICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyKChmcm9tOiB1bmtub3duLCBfc2VsZjogQ29udmVydGVyPFJlY29yZDxUSywgVD4sIFRDPiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgIGlmICgodHlwZW9mIGZyb20gIT09ICdvYmplY3QnKSB8fCAoZnJvbSA9PT0gbnVsbCkgfHwgQXJyYXkuaXNBcnJheShmcm9tKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYE5vdCBhIHN0cmluZy1rZXllZCBvYmplY3Q6ICR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZWNvcmQ6IFJlY29yZDxzdHJpbmcsIFQ+ID0ge307XG4gICAgICAgIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBmcm9tKSB7XG4gICAgICAgICAgICBpZiAoaXNLZXlPZihrZXksIGZyb20pKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgd3JpdGVLZXlSZXN1bHQgPSBvcHRpb25zLmtleUNvbnZlcnRlcj8uY29udmVydChrZXksIGNvbnRleHQpID8/IHN1Y2NlZWQoa2V5KTtcblxuICAgICAgICAgICAgICAgIHdyaXRlS2V5UmVzdWx0Lm9uU3VjY2Vzcygod3JpdGVLZXkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnZlcnRlci5jb252ZXJ0KGZyb21ba2V5XSBhcyB1bmtub3duLCBjb250ZXh0KS5vblN1Y2Nlc3MoKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWNvcmRbd3JpdGVLZXldID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VjY2VlZCh0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSkub25GYWlsdXJlKChtZXNzYWdlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9ycy5wdXNoKG1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFpbChtZXNzYWdlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoZXJyb3JzLmxlbmd0aCA9PT0gMCkgfHwgKG9wdGlvbnMub25FcnJvciA9PT0gJ2lnbm9yZScpXG4gICAgICAgICAgICA/IHN1Y2NlZWQocmVjb3JkKVxuICAgICAgICAgICAgOiBmYWlsKGVycm9ycy5qb2luKCdcXG4nKSk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBoZWxwZXIgd3JhcHBlciB0byBjb252ZXJ0IHRoZSBzdHJpbmcta2V5ZWQgcHJvcGVydGllcyBvZiBhbiBvYmplY3QgdG8gYSBNYXAgb2YgVC5cbiAqIENvbnZlcnNpb24gZmFpbHMgaWYgYW55IGVsZW1lbnQgY2Fubm90IGJlIGNvbnZlcnRlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgQ29udmVydGVyIHVzZWQgdG8gY29udmVydCBlYWNoIGl0ZW0gaW4gdGhlIG1hcFxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFwT2Y8VCwgVEMgPSB1bmRlZmluZWQsIFRLIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPihjb252ZXJ0ZXI6IENvbnZlcnRlcjxULCBUQz4pOiBDb252ZXJ0ZXI8TWFwPFRLLCBUPiwgVEM+O1xuXG4vKipcbiAqIEEgaGVscGVyIHdyYXBwZXIgdG8gY29udmVydCB0aGUgc3RyaW5nLWtleWVkIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0IHRvIGEgTWFwIG9mIFQuXG4gKiBJZiBvbkVycm9yIGlzICdmYWlsJyAoZGVmYXVsdCksICB0aGVuIHRoZSBlbnRpcmUgY29udmVyc2lvbiBmYWlscyBpZiBhbnkgZWxlbWVudFxuICogY2Fubm90IGJlIGNvbnZlcnRlZC4gIElmIG9uRXJyb3IgaXMgJ2lnbm9yZScgZmFpbGluZyBlbGVtZW50cyBhcmUgc2lsZW50bHkgaWdub3JlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgQ29udmVydGVyIHVzZWQgdG8gY29udmVydCBlYWNoIGl0ZW0gaW4gdGhlIG1hcFxuICogQHBhcmFtIG9uRXJyb3IgU3BlY2lmaWVzIHRyZWF0bWVudCBvZiB1bmNvbnZlcnRhYmxlIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXBPZjxULCBUQyA9IHVuZGVmaW5lZCwgVEsgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+KFxuICAgIGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPixcbiAgICBvbkVycm9yOiAnZmFpbCcgfCAnaWdub3JlJ1xuKTogQ29udmVydGVyPE1hcDxUSywgVD4sIFRDPjtcblxuLyoqXG4gKiBBIGhlbHBlciB3cmFwcGVyIHRvIGNvbnZlcnQgdGhlIHN0cmluZy1rZXllZCBwcm9wZXJ0aWVzIG9mIGFuIG9iamVjdCB0byBhIE1hcCBvZiBULlxuICogSWYgb3B0aW9ucyBzcGVjaWZ5IGEga2V5IGNvbnZlcnRlciBpdCB3aWxsIGJlIGFwcGxpZWQgdG8gZWFjaCBrZXkuXG4gKiBJZiBvbkVycm9yIGlzICdmYWlsJyAoZGVmYXVsdCksICB0aGVuIHRoZSBlbnRpcmUgY29udmVyc2lvbiBmYWlscyBpZiBhbnkga2V5IG9yIGVsZW1lbnRcbiAqIGNhbm5vdCBiZSBjb252ZXJ0ZWQuICBJZiBvbkVycm9yIGlzICdpZ25vcmUnIGZhaWxpbmcgZWxlbWVudHMgYXJlIHNpbGVudGx5IGlnbm9yZWQuXG4gKiBAcGFyYW0gY29udmVydGVyIENvbnZlcnRlciB1c2VkIHRvIGNvbnZlcnQgZWFjaCBpdGVtIGluIHRoZSBtYXBcbiAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbmFsIEBzZWUgS2V5ZWRDb252ZXJ0ZXJPcHRpb25zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXBPZjxULCBUQyA9IHVuZGVmaW5lZCwgVEsgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+KFxuICAgIGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPixcbiAgICBvcHRpb25zOiBLZXllZENvbnZlcnRlck9wdGlvbnM8VEssIFRDPlxuKTogQ29udmVydGVyPE1hcDxUSywgVD4sIFRDPjtcblxuZXhwb3J0IGZ1bmN0aW9uIG1hcE9mPFQsIFRDID0gdW5kZWZpbmVkLCBUSyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4oXG4gICAgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+LFxuICAgIG9wdGlvbjogJ2ZhaWwnIHwgJ2lnbm9yZScgfCBLZXllZENvbnZlcnRlck9wdGlvbnM8VEssIFRDPiA9ICdmYWlsJ1xuKTogQ29udmVydGVyPE1hcDxUSywgVD4sIFRDPiB7XG4gICAgY29uc3Qgb3B0aW9ucyA9ICh0eXBlb2Ygb3B0aW9uID09PSAnc3RyaW5nJykgPyB7IG9uRXJyb3I6IG9wdGlvbiB9IDogeyBvbkVycm9yOiAnZmFpbCcsIC4uLm9wdGlvbiB9O1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxNYXA8VEssIFQ+LCBUQz4sIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICBpZiAoKHR5cGVvZiBmcm9tICE9PSAnb2JqZWN0JykgfHwgKGZyb20gPT09IG51bGwpIHx8IEFycmF5LmlzQXJyYXkoZnJvbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKGBOb3QgYSBzdHJpbmcta2V5ZWQgb2JqZWN0OiAke0pTT04uc3RyaW5naWZ5KGZyb20pfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbWFwID0gbmV3IE1hcDxUSywgVD4oKTtcbiAgICAgICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGZyb20pIHtcbiAgICAgICAgICAgIGlmIChpc0tleU9mKGtleSwgZnJvbSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB3cml0ZUtleVJlc3VsdCA9IG9wdGlvbnMua2V5Q29udmVydGVyPy5jb252ZXJ0KGtleSwgY29udGV4dCkgPz8gc3VjY2VlZChrZXkpO1xuXG4gICAgICAgICAgICAgICAgd3JpdGVLZXlSZXN1bHQub25TdWNjZXNzKCh3cml0ZUtleSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udmVydGVyLmNvbnZlcnQoZnJvbVtrZXldIGFzIHVua25vd24sIGNvbnRleHQpLm9uU3VjY2VzcygodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcC5zZXQod3JpdGVLZXksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWNjZWVkKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KS5vbkZhaWx1cmUoKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JzLnB1c2gobWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWlsKG1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChlcnJvcnMubGVuZ3RoID09PSAwKSB8fCAob3B0aW9ucy5vbkVycm9yID09PSAnaWdub3JlJylcbiAgICAgICAgICAgID8gc3VjY2VlZChtYXApXG4gICAgICAgICAgICA6IGZhaWwoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBHZXRzIGEgY29udmVydGVyIHdoaWNoIHZhbGlkYXRlcyB0aGF0IGEgc3VwcGxpZWQgdmFsdWUgaXMgb2YgYSB0eXBlIHZhbGlkYXRlZCBieVxuICogYSBzdXBwbGllZCB2YWxpZGF0b3IgYW5kIHJldHVybnMgaXQuXG4gKiBAcGFyYW0gdmFsaWRhdG9yIEEgdmFsaWRhdG9yIGZ1bmN0aW9uIHRvIGRldGVybWluZSBpZiB0aGUgY29udmVydGVkIHZhbHVlIGlzIHZhbGlkXG4gKiBAcGFyYW0gZGVzY3JpcHRpb24gQSBkZXNjcmlwdGlvbiBvZiB0aGUgdmFsaWRhdGUgdHlwZSBmb3IgdXNlIGluIGVycm9yIG1lc3NhZ2VzXG4gKiBAcmV0dXJucyBJZiB2YWxpZGF0b3IgcmV0dXJucyB0cnVlLCBzdWNlZWRzIHdpdGggZnJvbSBjb2VyY2VkIHRvIFQuICBGYWlscyB3aXRoIGFuIGVycm9yXG4gKiBtZXNzYWdlIG90aGVyd2lzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlV2l0aDxULCBUQz11bmRlZmluZWQ+KHZhbGlkYXRvcjogKGZyb206IHVua25vd24pID0+IGZyb20gaXMgVCwgZGVzY3JpcHRpb24/OiBzdHJpbmcpOiBDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VCwgVEM+LCBfY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgIGlmICh2YWxpZGF0b3IoZnJvbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBzdWNjZWVkKGZyb20pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWlsKGAke0pTT04uc3RyaW5naWZ5KGZyb20pfTogaW52YWxpZCAke2Rlc2NyaXB0aW9uID8/ICd2YWx1ZSd9YCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gZXh0cmFjdCBhbmQgY29udmVydCBhbiBlbGVtZW50IGZyb20gYW4gYXJyYXkuIFN1Y2NlZWRzIGFuZCByZXR1cm5zXG4gKiB0aGUgY29udmVydGVkIHZhbHVlIGlmIHRoZSBlbGVtZW50IGV4aXN0cyBpbiB0aGUgc3VwcGxpZWQgcGFyYW1ldGVyIGFuZCBjYW4gYmUgY29udmVydGVkLlxuICogRmFpbHMgb3RoZXJ3aXNlLlxuICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZmllbGQgdG8gYmUgZXh0cmFjdGVkLlxuICogQHBhcmFtIGNvbnZlcnRlciBDb252ZXJ0ZXIgdXNlZCB0byBjb252ZXJ0IHRoZSBleHRyYWN0ZWQgZWxlbWVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVsZW1lbnQ8VCwgVEM9dW5kZWZpbmVkPihpbmRleDogbnVtYmVyLCBjb252ZXJ0ZXI6IENvbnZlcnRlcjxULCBUQz4pOiBDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VCwgVEM+LCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYCR7aW5kZXh9OiBjYW5ub3QgY29udmVydCBmb3IgYSBuZWdhdGl2ZSBlbGVtZW50IGluZGV4YCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIUFycmF5LmlzQXJyYXkoZnJvbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKCdlbGVtZW50IGNvbnZlcnRlcjogc291cmNlIGlzIG5vdCBhbiBhcnJheScpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGluZGV4ID49IGZyb20ubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFpbChgJHtpbmRleH06IGVsZW1lbnQgY29udmVydGVyIGluZGV4IG91dCBvZiByYW5nZSAoMC4uJHtmcm9tLmxlbmd0aCAtIDF9KWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb252ZXJ0ZXIuY29udmVydChmcm9tW2luZGV4XSwgY29udGV4dCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gZXh0cmFjdCBhbmQgY29udmVydCBhbiBvcHRpb25hbCBlbGVtZW50IGZyb20gYW4gYXJyYXkuIFN1Y2NlZWRzXG4gKiBhbmQgcmV0dXJucyB0aGUgY29udmVydGVkIHZhbHVlIGlmIHRoZSBlbGVtZW50IGV4aXN0cyBpbiB0aGUgc3VwcGxpZWQgcGFyYW1ldGVyIGFuZCBjYW5cbiAqIGJlIGNvbnZlcnRlZC4gU3VjY2VlZHMgd2l0aCB1bmRlZmluZWQgaWYgdGhlIHBhcmFtZXRlciBpcyBhbiBhcnJheSBidXQgdGhlIGluZGV4IGlzIHRvb1xuICogbGFyZ2UuIEZhaWxzIGlmIHRoZSBzdXBwbGllZCBwYXJhbWV0ZXIgaXMgbm90IGFuIGFycmF5LCBpZiB0aGUgcmVxdWVzdGVkIGluZGV4IGlzIG5lZ2F0aXZlLFxuICogb3IgaWYgdGhlIGVsZW1lbnQgY2Fubm90IGJlIGNvbnZlcnRlZC5cbiAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBiZSBleHRyYWN0ZWQuXG4gKiBAcGFyYW0gY29udmVydGVyIENvbnZlcnRlciB1c2VkIHRvIGNvbnZlcnQgdGhlIGV4dHJhY3RlZCBmaWVsZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9wdGlvbmFsRWxlbWVudDxULCBUQz11bmRlZmluZWQ+KGluZGV4OiBudW1iZXIsIGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPik6IENvbnZlcnRlcjxUfHVuZGVmaW5lZCwgVEM+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VHx1bmRlZmluZWQsIFRDPiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgIGlmIChpbmRleCA8IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKGAke2luZGV4fTogY2Fubm90IGNvbnZlcnQgZm9yIGEgbmVnYXRpdmUgZWxlbWVudCBpbmRleGApO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCFBcnJheS5pc0FycmF5KGZyb20pKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFpbCgnZWxlbWVudCBjb252ZXJ0ZXI6IHNvdXJjZSBpcyBub3QgYW4gYXJyYXknKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpbmRleCA+PSBmcm9tLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHN1Y2NlZWQodW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29udmVydGVyLmNvbnZlcnQoZnJvbVtpbmRleF0sIGNvbnRleHQpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIGV4dHJhY3QgYW5kIGNvbnZlcnQgYSBmaWVsZCBmcm9tIGFuIG9iamVjdC4gU3VjY2VlZHMgYW5kIHJldHVybnNcbiAqIHRoZSBjb252ZXJ0ZWQgdmFsdWUgaWYgdGhlIGZpZWxkIGV4aXN0cyBpbiB0aGUgc3VwcGxpZWQgcGFyYW1ldGVyIGFuZCBjYW4gYmUgY29udmVydGVkLlxuICogRmFpbHMgb3RoZXJ3aXNlLlxuICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGJlIGV4dHJhY3RlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgQ29udmVydGVyIHVzZWQgdG8gY29udmVydCB0aGUgZXh0cmFjdGVkIGZpZWxkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZmllbGQ8VCwgVEM9dW5kZWZpbmVkPihuYW1lOiBzdHJpbmcsIGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPik6IENvbnZlcnRlcjxULCBUQz4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxULCBUQz4sIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIGZyb20gPT09ICdvYmplY3QnICYmICghQXJyYXkuaXNBcnJheShmcm9tKSkgJiYgZnJvbSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKGlzS2V5T2YobmFtZSwgZnJvbSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udmVydGVyLmNvbnZlcnQoZnJvbVtuYW1lXSwgY29udGV4dCkub25GYWlsdXJlKChtZXNzYWdlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWlsKGBGaWVsZCAke25hbWV9OiAke21lc3NhZ2V9YCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFpbChgRmllbGQgJHtuYW1lfSBub3QgZm91bmQgaW46ICR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhaWwoYENhbm5vdCBjb252ZXJ0IGZpZWxkIFwiJHtuYW1lfVwiIGZyb20gbm9uLW9iamVjdCAke0pTT04uc3RyaW5naWZ5KGZyb20pfWApO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIGV4dHJhY3QgYW5kIGNvbnZlcnQgYW4gb3B0aW9uYWwgZmllbGQgZnJvbSBhbiBvYmplY3QuIFN1Y2NlZWRzXG4gKiBhbmQgcmV0dXJucyB0aGUgY29udmVydGVkIHZhbHVlIGlmIHRoZSBmaWVsZCBleGlzdHMgaW4gdGhlIHN1cHBsaWVkIHBhcmFtZXRlciBhbmQgY2FuXG4gKiBiZSBjb252ZXJ0ZWQuIFN1Y2NlZWRzIHdpdGggdW5kZWZpbmVkIGlmIHRoZSBwYXJhbWV0ZXIgaXMgYW4gb2JqZWN0IGJ1dCB0aGUgbmFtZWQgZmllbGRcbiAqIGlzIG5vdCBwcmVzZW50LiBGYWlscyBpZiB0aGUgc3VwcGxpZWQgcGFyYW1ldGVyIGlzIG5vdCBhbiBvYmplY3QuXG4gKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZmllbGQgdG8gYmUgZXh0cmFjdGVkLlxuICogQHBhcmFtIGNvbnZlcnRlciBDb252ZXJ0ZXIgdXNlZCB0byBjb252ZXJ0IHRoZSBleHRyYWN0ZWQgZmllbGQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvcHRpb25hbEZpZWxkPFQsIFRDPXVuZGVmaW5lZD4obmFtZTogc3RyaW5nLCBjb252ZXJ0ZXI6IENvbnZlcnRlcjxULCBUQz4pOiBDb252ZXJ0ZXI8VHx1bmRlZmluZWQsIFRDPiB7XG4gICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyKChmcm9tOiB1bmtub3duLCBfc2VsZjogQ29udmVydGVyPFR8dW5kZWZpbmVkLCBUQz4sIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIGZyb20gPT09ICdvYmplY3QnICYmICghQXJyYXkuaXNBcnJheShmcm9tKSkgJiYgZnJvbSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKGlzS2V5T2YobmFtZSwgZnJvbSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBjb252ZXJ0ZXIuY29udmVydChmcm9tW25hbWVdLCBjb250ZXh0KS5vbkZhaWx1cmUoKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhaWwoYCR7bmFtZX06ICR7bWVzc2FnZX1gKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIC8vIGlmIGNvbnZlcnNpb24gd2FzIHN1Y2Nlc3NmdWwgb3IgaW5wdXQgd2FzIHVuZGVmaW5lZCB3ZVxuICAgICAgICAgICAgICAgIC8vIHN1Y2NlZWQgd2l0aCAndW5kZWZpbmVkJywgYnV0IHdlIHByb3BhZ2F0ZSBhY3R1YWxcbiAgICAgICAgICAgICAgICAvLyBmYWlsdXJlcy5cbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmlzU3VjY2VzcygpIHx8IChmcm9tW25hbWVdICE9PSB1bmRlZmluZWQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN1Y2NlZWQodW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFpbChgQ2Fubm90IGNvbnZlcnQgZmllbGQgXCIke25hbWV9XCIgZnJvbSBub24tb2JqZWN0ICR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9YCk7XG4gICAgfSwgdW5kZWZpbmVkLCB7IGlzT3B0aW9uYWw6IHRydWUgfSk7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgYW4gQHNlZSBPYmplY3RDb252ZXJ0ZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT2JqZWN0Q29udmVydGVyT3B0aW9uczxUPiB7XG4gICAgLyoqXG4gICAgICogSWYgcHJlc2VudCwgbGlzdHMgb3B0aW9uYWwgZmllbGRzLiBNaXNzaW5nIG5vbi1vcHRpb25hbCBmaWVsZHMgY2F1c2UgYW4gZXJyb3IuXG4gICAgICovXG4gICAgb3B0aW9uYWxGaWVsZHM/OiAoa2V5b2YgVClbXTtcbiAgICAvKipcbiAgICAgKiBJZiB0cnVlLCB1bnJlY29nbml6ZWQgZmllbGRzIHlpZWxkIGFuIGVycm9yLiAgSWYgZmFsc2Ugb3IgdW5kZWZpbmVkIChkZWZhdWx0KSxcbiAgICAgKiB1bnJlY29nbml6ZWQgZmllbGRzIGFyZSBpZ25vcmVkLlxuICAgICAqL1xuICAgIHN0cmljdD86IGJvb2xlYW47XG59XG5cbi8qKlxuICogUGVyLXByb3BlcnR5IGNvbnZlcnRlcnMgZm9yIGVhY2ggb2YgdGhlIHByb3BlcnRpZXMgaW4gdHlwZSBULlxuICovXG5leHBvcnQgdHlwZSBGaWVsZENvbnZlcnRlcnM8VCwgVEM9dW5rbm93bj4gPSB7IFsga2V5IGluIGtleW9mIFQgXTogQ29udmVydGVyPFRba2V5XSwgVEM+IH07XG5cbi8qKlxuICogQ29udmVydGVyIHRvIGNvbnZlcnQgYW4gb2JqZWN0IG9mIHR5cGUgVCB3aXRob3V0IGNoYW5naW5nIHNoYXBlLCBnaXZlbiBhIEBzZWUgRmllbGRDb252ZXJ0ZXJzPFQ+LlxuICogSWYgYWxsIG9mIHRoZSByZXF1aXJlZCBmaWVsZHMgZXhpc3QgYW5kIGNhbiBiZSBjb252ZXJ0ZWQsIHJldHVybnMgYSBuZXcgb2JqZWN0IHdpdGggdGhlIGNvbnZlcnRlZFxuICogdmFsdWVzIHVuZGVyIHRoZSBvcmlnaW5hbCBrZXkgbmFtZXMuICBJZiBhbnkgcmVxdWlyZWQgZmllbGRzIGRvIG5vdCBleGlzdCBvciBjYW5ub3QgYmUgY29udmVydGVkLFxuICogdGhlIGVudGlyZSBjb252ZXJzaW9uIGZhaWxzLiAgU2VlIEBzZWUgT2JqZWN0Q29udmVydGVyT3B0aW9ucyBmb3Igb3RoZXIgY29udmVyc2lvbiBvcHRpb25zLlxuICovXG5leHBvcnQgY2xhc3MgT2JqZWN0Q29udmVydGVyPFQsIFRDPXVua25vd24+IGV4dGVuZHMgQmFzZUNvbnZlcnRlcjxULCBUQz4ge1xuICAgIHB1YmxpYyByZWFkb25seSBmaWVsZHM6IEZpZWxkQ29udmVydGVyczxUPjtcbiAgICBwdWJsaWMgcmVhZG9ubHkgb3B0aW9uczogT2JqZWN0Q29udmVydGVyT3B0aW9uczxUPjtcblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgQHNlZSBPYmplY3RDb252ZXJ0ZXI8VD4gdXNpbmcgb3B0aW9ucyBzdXBwbGllZCBpbiBhblxuICAgICAqIG9wdGlvbmFsIEBzZWUgT2JqZWN0Q29udmVydGVyT3B0aW9uczxUPi5cbiAgICAgKiBAcGFyYW0gZmllbGRzIEEgQHNlZSBGaWVsZENvbnZlcnRlcnM8VD4gY29udGFpbmluZyBjb252ZXJ0ZXJzIGZvciBlYWNoIGZpZWxkXG4gICAgICogQHBhcmFtIG9wdGlvbnMgQW4gb3B0aW9uYWwgQHNlZSBPYmplY3RDb252ZXJ0ZXJPcHRpb25zIHRvIGNvbmZpZ3VyZSB0aGUgY29udmVyc2lvblxuICAgICAqL1xuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihmaWVsZHM6IEZpZWxkQ29udmVydGVyczxULCBUQz4sIG9wdGlvbnM/OiBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+KVxuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBAc2VlIE9iamVjdENvbnZlcnRlcjxUPiB1c2luZyBvcHRpb25hbCBmaWVsZHMgc3VwcGxpZWQgaW4gYW5cbiAgICAgKiBvcHRpb25hbCBhcnJheSBvZiBrZXlvZiBULlxuICAgICAqIEBwYXJhbSBmaWVsZHMgQSBAc2VlIEZpZWxkQ29udmVydGVyczxUPiBjb250YWluaW5nIGNvbnZlcnRlcnMgZm9yIGVhY2ggZmllbGRcbiAgICAgKiBAcGFyYW0gb3B0aW9uYWwgQW4gb3B0aW9uYWwgYXJyYXkgb2Yga2V5b2YgVCBsaXN0aW5nIGZpZWxkcyB0aGF0IGFyZSBub3QgcmVxdWlyZWQuXG4gICAgICovXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKGZpZWxkczogRmllbGRDb252ZXJ0ZXJzPFQsIFRDPiwgb3B0aW9uYWw/OiAoa2V5b2YgVClbXSk7XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKGZpZWxkczogRmllbGRDb252ZXJ0ZXJzPFQsIFRDPiwgb3B0PzogT2JqZWN0Q29udmVydGVyT3B0aW9uczxUPnwoa2V5b2YgVClbXSkge1xuICAgICAgICBzdXBlcigoZnJvbTogdW5rbm93biwgX3NlbGYsIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICAgICAgLy8gZXNsaW50IGJ1ZyB0aGlua3Mga2V5IGlzIHVzZWQgYmVmb3JlIGRlZmluZWRcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11c2UtYmVmb3JlLWRlZmluZVxuICAgICAgICAgICAgY29uc3QgY29udmVydGVkID0ge30gYXMgeyBba2V5IGluIGtleW9mIFRdOiBUW2tleV0gfTtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIGZpZWxkcykge1xuICAgICAgICAgICAgICAgIGlmIChmaWVsZHNba2V5XSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpc09wdGlvbmFsID0gKGZpZWxkc1trZXldLmlzT3B0aW9uYWwgfHwgdGhpcy5vcHRpb25zLm9wdGlvbmFsRmllbGRzPy5pbmNsdWRlcyhrZXkpKSA/PyBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gaXNPcHRpb25hbFxuICAgICAgICAgICAgICAgICAgICAgICAgPyBvcHRpb25hbEZpZWxkKGtleSwgZmllbGRzW2tleV0pLmNvbnZlcnQoZnJvbSwgY29udGV4dClcbiAgICAgICAgICAgICAgICAgICAgICAgIDogZmllbGQoa2V5LCBmaWVsZHNba2V5XSkuY29udmVydChmcm9tLCBjb250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSAmJiAocmVzdWx0LnZhbHVlICE9PSB1bmRlZmluZWQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ZWRba2V5XSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChyZXN1bHQuaXNGYWlsdXJlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ycy5wdXNoKHJlc3VsdC5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zdHJpY3QgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoKHR5cGVvZiBmcm9tID09PSAnb2JqZWN0JykgJiYgKCFBcnJheS5pc0FycmF5KGZyb20pKSkge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBmcm9tKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZnJvbS5oYXNPd25Qcm9wZXJ0eShrZXkpICYmICghaXNLZXlPZihrZXksIGZpZWxkcykgfHwgKGZpZWxkc1trZXldID09PSB1bmRlZmluZWQpKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ycy5wdXNoKGAke2tleX06IHVuZXhwZWN0ZWQgcHJvcGVydHkgaW4gc291cmNlIG9iamVjdGApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcnMucHVzaCgnc291cmNlIGlzIG5vdCBhbiBvYmplY3QnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gKGVycm9ycy5sZW5ndGggPT09IDApID8gc3VjY2VlZChjb252ZXJ0ZWQpIDogZmFpbChlcnJvcnMuam9pbignXFxuJykpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmZpZWxkcyA9IGZpZWxkcztcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkob3B0KSkge1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zID0geyBvcHRpb25hbEZpZWxkczogb3B0IH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHQgPz8ge307XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgcGFydGlhbChvcHRpb25zOiBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+KTogT2JqZWN0Q29udmVydGVyPFBhcnRpYWw8VD4sIFRDPjtcbiAgICBwdWJsaWMgcGFydGlhbChvcHRpb25hbD86IChrZXlvZiBUKVtdKTogT2JqZWN0Q29udmVydGVyPFBhcnRpYWw8VD4sIFRDPjtcbiAgICBwdWJsaWMgcGFydGlhbChvcHQ/OiBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+fChrZXlvZiBUKVtdKTogT2JqZWN0Q29udmVydGVyPFBhcnRpYWw8VD4sIFRDPiB7XG4gICAgICAgIHJldHVybiBuZXcgT2JqZWN0Q29udmVydGVyPFBhcnRpYWw8VD4sIFRDPih0aGlzLmZpZWxkcyBhcyBGaWVsZENvbnZlcnRlcnM8UGFydGlhbDxUPiwgVEM+LCBvcHQgYXMgT2JqZWN0Q29udmVydGVyT3B0aW9uczxQYXJ0aWFsPFQ+PikuX3dpdGgodGhpcy5fdHJhaXRzKCkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhZGRQYXJ0aWFsKGFkZE9wdGlvbmFsRmllbGRzOiAoa2V5b2YgVClbXSk6IE9iamVjdENvbnZlcnRlcjxQYXJ0aWFsPFQ+LCBUQz4ge1xuICAgICAgICByZXR1cm4gdGhpcy5wYXJ0aWFsKFsuLi50aGlzLm9wdGlvbnMub3B0aW9uYWxGaWVsZHMgPz8gW10sIC4uLmFkZE9wdGlvbmFsRmllbGRzXSkuX3dpdGgodGhpcy5fdHJhaXRzKCkpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBIZWxwZXIgdG8gY29udmVydCBhbiBvYmplY3Qgd2l0aG91dCBjaGFuZ2luZyBzaGFwZS4gVGhlIHNvdXJjZSBwYXJhbWV0ZXIgaXMgYW4gb2JqZWN0IHdpdGhcbiAqIGtleSBuYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdGhlIHRhcmdldCBvYmplY3QgYW5kIHRoZSBhcHByb3ByaWF0ZSBjb3JyZXNwb25kaW5nIGNvbnZlcnRlclxuICogYXMgdGhlIHByb3BlcnR5IHZhbHVlLiBJZiBhbGwgb2YgdGhlIHJlcXVlc3RlZCBmaWVsZHMgZXhpc3QgYW5kIGNhbiBiZSBjb252ZXJ0ZWQsIHJldHVybnMgYVxuICogbmV3IG9iamVjdCB3aXRoIHRoZSBjb252ZXJ0ZWQgdmFsdWVzIHVuZGVyIHRoZSBvcmlnaW5hbCBrZXkgbmFtZXMuICBJZiBhbnkgZmllbGRzIGRvIG5vdCBleGlzdFxuICogb3IgY2Fubm90IGJlIGNvbnZlcnRlZCwgdGhlIGVudGlyZSBjb252ZXJzaW9uIGZhaWxzLlxuICpcbiAqIEZpZWxkcyB0aGF0IHN1Y2NlZWQgYnV0IGNvbnZlcnQgdG8gdW5kZWZpbmVkIGFyZSBvbWl0dGVkIGZyb20gdGhlIHJlc3VsdCBvYmplY3QgYnV0IGRvIG5vdFxuICogZmFpbCB0aGUgY29udmVyc2lvbi5cbiAqIEBwYXJhbSBmaWVsZHMgQW4gb2JqZWN0IGNvbnRhaW5pbmcgZGVmaW5pbmcgdGhlIHNoYXBlIGFuZCBjb252ZXJ0ZXJzIHRvIGJlIGFwcGxpZWQuXG4gKiBAcGFyYW0gb3B0IEFuIEBzZWUgT2JqZWN0Q29udmVydGVyT3B0aW9uczxUPiBjb250YWluaW5nIG9wdGlvbnMgZm9yIHRoZSBvYmplY3QgY29udmVydGVyLCBvclxuICogYW4gYXJyYXkgb2YgKGtleW9mIFQpIGNvbnRhaW5pbmcgb3B0aW9uYWwga2V5cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9iamVjdDxUPihmaWVsZHM6IEZpZWxkQ29udmVydGVyczxUPiwgb3B0PzogKGtleW9mIFQpW118T2JqZWN0Q29udmVydGVyT3B0aW9uczxUPik6IE9iamVjdENvbnZlcnRlcjxUPiB7XG4gICAgcmV0dXJuIG5ldyBPYmplY3RDb252ZXJ0ZXIoZmllbGRzLCBvcHQgYXMgT2JqZWN0Q29udmVydGVyT3B0aW9uczxUPik7XG59XG5cbi8qKlxuICogSGVscGVyIHRvIGNvbnZlcnQgYW4gb2JqZWN0IHdpdGhvdXQgY2hhbmdpbmcgc2hhcGUuIFRoZSBzb3VyY2UgcGFyYW1ldGVyIGlzIGFuIG9iamVjdCB3aXRoXG4gKiBrZXkgbmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHRoZSB0YXJnZXQgb2JqZWN0IGFuZCB0aGUgYXBwcm9wcmlhdGUgY29ycmVzcG9uZGluZyBjb252ZXJ0ZXJcbiAqIGFzIHRoZSBwcm9wZXJ0eSB2YWx1ZS4gSWYgYWxsIG9mIHRoZSByZXF1ZXN0ZWQgZmllbGRzIGV4aXN0IGFuZCBjYW4gYmUgY29udmVydGVkLCByZXR1cm5zIGFcbiAqIG5ldyBvYmplY3Qgd2l0aCB0aGUgY29udmVydGVkIHZhbHVlcyB1bmRlciB0aGUgb3JpZ2luYWwga2V5IG5hbWVzLiAgSWYgYW55IGZpZWxkcyBkbyBub3QgZXhpc3RcbiAqIG9yIGNhbm5vdCBiZSBjb252ZXJ0ZWQsIHRoZSBlbnRpcmUgY29udmVyc2lvbiBmYWlscy5cbiAqXG4gKiBGaWVsZHMgdGhhdCBzdWNjZWVkIGJ1dCBjb252ZXJ0IHRvIHVuZGVmaW5lZCBhcmUgb21pdHRlZCBmcm9tIHRoZSByZXN1bHQgb2JqZWN0IGJ1dCBkbyBub3RcbiAqIGZhaWwgdGhlIGNvbnZlcnNpb24uXG4gKlxuICogVGhlIGNvbnZlcnNpb24gZmFpbHMgaWYgYW55IHVuZXhwZWN0ZWQgZmllbGRzIGFyZSBlbmNvdW50ZXJlZC5cbiAqXG4gKiBAcGFyYW0gZmllbGRzIEFuIG9iamVjdCBjb250YWluaW5nIGRlZmluaW5nIHRoZSBzaGFwZSBhbmQgY29udmVydGVycyB0byBiZSBhcHBsaWVkLlxuICogQHBhcmFtIG9wdCAtIEFuIEBzZWUgT2JqZWN0Q29udmVydGVyT3B0aW9uczxUPiBjb250YWluaW5nIG9wdGlvbnMgZm9yIHRoZSBvYmplY3QgY29udmVydGVyLCBvclxuICogYW4gYXJyYXkgb2YgKGtleW9mIFQpIGNvbnRhaW5pbmcgb3B0aW9uYWwga2V5cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0cmljdE9iamVjdDxUPihcbiAgICBmaWVsZHM6IEZpZWxkQ29udmVydGVyczxUPixcbiAgICBvcHQ/OiAoa2V5b2YgVClbXXxPbWl0PE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD4sICdzdHJpY3QnPixcbik6IE9iamVjdENvbnZlcnRlcjxUPiB7XG4gICAgY29uc3Qgb3B0aW9uczogT2JqZWN0Q29udmVydGVyT3B0aW9uczxUPiA9IChvcHQgJiYgQXJyYXkuaXNBcnJheShvcHQpKVxuICAgICAgICA/IHsgc3RyaWN0OiB0cnVlLCBvcHRpb25hbEZpZWxkczogb3B0IH1cbiAgICAgICAgOiB7IC4uLihvcHQgPz8ge30pLCBzdHJpY3Q6IHRydWUgfTtcbiAgICByZXR1cm4gbmV3IE9iamVjdENvbnZlcnRlcihmaWVsZHMsIG9wdGlvbnMpO1xufVxuXG5leHBvcnQgdHlwZSBEaXNjcmltaW5hdGVkT2JqZWN0Q29udmVydGVyczxULCBURCBleHRlbmRzIHN0cmluZyA9IHN0cmluZywgVEM9dW5rbm93bj4gPSBSZWNvcmQ8VEQsIENvbnZlcnRlcjxULCBUQz4+O1xuXG4vKipcbiAqIEhlbHBlciB0byBjb252ZXJ0IGEgZGlzY3JpbWluYXRlZCBwcm9wZXJ0eSB3aXRob3V0IGNoYW5naW5nIHNoYXBlLiAgVGFrZXMgdGhlIG5hbWUgb2YgdGhlXG4gKiBkaXNjcmltaW5hdG9yIHByb3BlcnR5IGFuZCBhIHN0cmluZy1rZXllZCByZWNvcmQgb2Ygb2JqZWN0IGNvbnZlcnRlcnMsIGFuZCBpbnZva2VzIHRoZVxuICogY29udmVydGVyIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIHZhbHVlIG9mIHRoZSBkaXNjcmltaW5hdG9yIHByb3BlcnR5IGluIHRoZSBzb3VyY2Ugb2JqZWN0LlxuICogRmFpbHMgaWYgdGhlIHNvdXJjZSBpcyBub3QgYW4gb2JqZWN0IG9yIGlmIHRoZSBkaXNjcmltaW5hdG9yIHByb3BlcnR5IGlzIG1pc3Npbmcgb3IgaGFzXG4gKiBhIHZhbHVlIG5vdCBwcmVzZW50IGluIHRoZSBjb252ZXJ0ZXJzLlxuICogQHBhcmFtIGRpc2NyaW1pbmF0b3JQcm9wIE5hbWUgb2YgdGhlIHByb3BlcnR5IHVzZWQgdG8gZGlzY3JpbWluYXRlIHR5cGVzXG4gKiBAcGFyYW0gY29udmVydGVycyBTdHJpbmcta2V5ZWQgcmVjb3JkIG9mIGNvbnZlcnRlcnMgdG8gaW52b2tlLCB3aGVyZSBrZXkgY29ycmVzcG9uZHMgdG8gYSB2YWx1ZSBvZiB0aGVcbiAqIGRpc2NyaW1pbmF0b3IgcHJvcGVydHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXNjcmltaW5hdGVkT2JqZWN0PFQsIFREIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nLCBUQz11bmtub3duPihkaXNjcmltaW5hdG9yUHJvcDogc3RyaW5nLCBjb252ZXJ0ZXJzOiBEaXNjcmltaW5hdGVkT2JqZWN0Q29udmVydGVyczxULCBURD4pOiBDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24pID0+IHtcbiAgICAgICAgaWYgKCh0eXBlb2YgZnJvbSAhPT0gJ29iamVjdCcpIHx8IEFycmF5LmlzQXJyYXkoZnJvbSkgfHwgZnJvbSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYE5vdCBhIGRpc2NyaW1pbmF0ZWQgb2JqZWN0OiBcIiR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9XCJgKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoKCFpc0tleU9mKGRpc2NyaW1pbmF0b3JQcm9wLCBmcm9tKSkgfHwgKCFmcm9tW2Rpc2NyaW1pbmF0b3JQcm9wXSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKGBEaXNjcmltaW5hdG9yIHByb3BlcnR5ICR7ZGlzY3JpbWluYXRvclByb3B9IG5vdCBwcmVzZW50IGluIFwiJHtKU09OLnN0cmluZ2lmeShmcm9tKX1cImApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZGlzY3JpbWluYXRvclZhbHVlID0gZnJvbVtkaXNjcmltaW5hdG9yUHJvcF0gYXMgVEQ7XG4gICAgICAgIGNvbnN0IGNvbnZlcnRlciA9IGNvbnZlcnRlcnNbZGlzY3JpbWluYXRvclZhbHVlXTtcbiAgICAgICAgaWYgKGNvbnZlcnRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFpbChgTm8gY29udmVydGVyIGZvciBkaXNjcmltaW5hdG9yICR7ZGlzY3JpbWluYXRvclByb3B9PVwiJHtkaXNjcmltaW5hdG9yVmFsdWV9XCJgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29udmVydGVyLmNvbnZlcnQoZnJvbSk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogSGVscGVyIHRvIGNvbnZlcnQgYW4gb2JqZWN0IHRvIGEgbmV3IG9iamVjdCB3aXRoIGEgZGlmZmVyZW50IHNoYXBlLiBUaGUgc291cmNlIHBhcmFtZXRlciBpc1xuICogYW4gb2JqZWN0IHdpdGgga2V5IG5hbWVzIHRoYXQgY29ycmVzcG9uZCB0byB0aGUgdGFyZ2V0IG9iamVjdCwgYW5kIGFuIGFwcHJvcmlhdGUgX2ZpZWxkX1xuICogY29udmVydGVyIHRoYXQgd2lsbCBleHRyYWN0IGFuZCBjb252ZXJ0IGEgc2luZ2xlIGZpZWxkIGZyb20gdGhlIHNvdXJjZSBvYmplY3QuXG4gKlxuICogSWYgYWxsIG9mIHRoZSBleHRyYWN0ZWQgZmllbGRzIGV4aXN0IGFuZCBjYW4gYmUgY29udmVydGVkLCByZXR1cm5zIGEgbmV3IG9iamVjdCB3aXRoIHRoZVxuICogY29udmVydGVkIHZhbHVlcyB1bmRlciB0aGUgb3JpZ2luYWwga2V5IG5hbWVzLiAgSWYgYW55IGZpZWxkcyB0byBiZSBleHRyYWN0ZWQgZG8gbm90IGV4aXN0XG4gKiBvciBjYW5ub3QgYmUgY29udmVydGVkLCB0aGUgZW50aXJlIGNvbnZlcnNpb24gZmFpbHMuXG4gKlxuICogRmllbGRzIHRoYXQgc3VjY2VlZCBidXQgY29udmVydCB0byB1bmRlZmluZWQgYXJlIG9taXR0ZWQgZnJvbSB0aGUgcmVzdWx0IG9iamVjdCBidXQgZG8gbm90XG4gKiBmYWlsIHRoZSBjb252ZXJzaW9uLlxuICpcbiAqIEBwYXJhbSBmaWVsZHMgQW4gb2JqZWN0IGRlZmluaW5nIHRoZSBzaGFwZSBvZiB0aGUgdGFyZ2V0IG9iamVjdCBhbmQgdGhlIGZpZWxkIGNvbnZlcnRlcnNcbiAqIHRvIGJlIHVzZWQgdG8gY29uc3RydWN0IGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtPFQsIFRDPXVua25vd24+KGZpZWxkczogRmllbGRDb252ZXJ0ZXJzPFQsIFRDPik6IENvbnZlcnRlcjxULCBUQz4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGYsIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICAvLyBlc2xpbnQgYnVnIHRoaW5rcyBrZXkgaXMgdXNlZCBiZWZvcmUgZGVmaW5lZFxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlLWJlZm9yZS1kZWZpbmVcbiAgICAgICAgY29uc3QgY29udmVydGVkID0ge30gYXMgeyBbIGtleSBpbiBrZXlvZiBUXTogVFtrZXldIH07XG4gICAgICAgIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBmaWVsZHMpIHtcbiAgICAgICAgICAgIGlmIChmaWVsZHNba2V5XSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGZpZWxkc1trZXldLmNvbnZlcnQoZnJvbSwgY29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSAmJiAocmVzdWx0LnZhbHVlICE9PSB1bmRlZmluZWQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnZlcnRlZFtrZXldID0gcmVzdWx0LnZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChyZXN1bHQuaXNGYWlsdXJlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JzLnB1c2gocmVzdWx0Lm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoZXJyb3JzLmxlbmd0aCA9PT0gMCkgPyBzdWNjZWVkKGNvbnZlcnRlZCkgOiBmYWlsKGVycm9ycy5qb2luKCdcXG4nKSk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBoZWxwZXIgd3JhcHBlciB0byBjb252ZXJ0IGEgcmFuZ2Ugb2Ygc29tZSBvdGhlciBjb21wYXJhYmxlIHR5cGVcbiAqIEBwYXJhbSBjb252ZXJ0ZXIgQ29udmVydGVyIHVzZWQgdG8gY29udmVydCBtaW4gYW5kIG1heCBleHRlbnQgb2YgdGhlIHJhaWRcbiAqIEBwYXJhbSBjb25zdHJ1Y3RvciBPcHRpb25hbCBzdGF0aWMgY29uc3RydWN0b3IgdG8gaW5zdGFudGlhdGUgdGhlIG9iamVjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmFuZ2VUeXBlT2Y8VCwgUlQgZXh0ZW5kcyBSYW5nZU9mPFQ+LCBUQz11bmtub3duPihjb252ZXJ0ZXI6IENvbnZlcnRlcjxULCBUQz4sIGNvbnN0cnVjdG9yOiAoaW5pdDogUmFuZ2VPZlByb3BlcnRpZXM8VD4pID0+IFJlc3VsdDxSVD4pOiBDb252ZXJ0ZXI8UlQsIFRDPiB7XG4gICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyKChmcm9tOiB1bmtub3duLCBfc2VsZiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IG9iamVjdCh7XG4gICAgICAgICAgICBtaW46IGNvbnZlcnRlcixcbiAgICAgICAgICAgIG1heDogY29udmVydGVyLFxuICAgICAgICB9LCBbJ21pbicsICdtYXgnXSkuY29udmVydChmcm9tLCBjb250ZXh0KTtcbiAgICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cnVjdG9yKHsgbWluOiByZXN1bHQudmFsdWUubWluLCBtYXg6IHJlc3VsdC52YWx1ZS5tYXggfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhaWwocmVzdWx0Lm1lc3NhZ2UpO1xuICAgIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmFuZ2VPZjxULCBUQz11bmtub3duPihjb252ZXJ0ZXI6IENvbnZlcnRlcjxULCBUQz4pOiBDb252ZXJ0ZXI8UmFuZ2VPZjxUPiwgVEM+IHtcbiAgICByZXR1cm4gcmFuZ2VUeXBlT2Y8VCwgUmFuZ2VPZjxUPiwgVEM+KGNvbnZlcnRlciwgUmFuZ2VPZi5jcmVhdGVSYW5nZSk7XG59XG4iXX0=
805
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVydGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb252ZXJ0ZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUNILDJDQUF3RTtBQUN4RSx1Q0FBdUQ7QUFDdkQscUNBQWdFO0FBRWhFLGlDQUFpQztBQUNqQyxtREFBZ0Q7QUFDaEQsd0RBQWdDO0FBQ2hDLG1DQUFrQztBQWlCbEM7Ozs7R0FJRztBQUNILE1BQWEsZUFBeUQsU0FBUSx5QkFBb0I7SUFDOUY7Ozs7O09BS0c7SUFDSCxZQUNJLGNBQW1CLEVBQ25CLE1BQXdCLEVBQ3hCLFlBQWdGLGVBQWUsQ0FBQyxRQUFRO1FBRXhHLEtBQUssQ0FBQyxTQUFTLEVBQUUsY0FBYyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRDs7T0FFRztJQUNPLE1BQU0sQ0FBQyxRQUFRLENBQW1CLElBQWE7UUFDckQsT0FBTyxPQUFPLElBQUksS0FBSyxRQUFRO1lBQzNCLENBQUMsQ0FBQyxJQUFBLGdCQUFPLEVBQUMsSUFBUyxDQUFDO1lBQ3BCLENBQUMsQ0FBQyxJQUFBLGFBQUksRUFBQyxpQkFBaUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVEOztPQUVHO0lBQ08sTUFBTSxDQUFDLEtBQUssQ0FDbEIsT0FBK0IsRUFDL0IsU0FBaUMsRUFDakMsTUFBd0I7UUFFeEIsT0FBTyxJQUFJLGVBQWUsQ0FBUSxTQUFTLEVBQUUsU0FBUyxFQUFFLENBQUMsSUFBYSxFQUFFLEVBQUU7WUFDdEUsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN0RCxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3RD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QU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7U0FDeEU7UUFDRCxPQUFPLElBQUEsYUFBSSxFQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNoQyxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFYRCxrQ0FXQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBZ0IsT0FBTyxDQUFnQixTQUEyQjtJQUM5RCxPQUFPLFdBQVcsQ0FBb0IsU0FBUyxFQUFFLGlCQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUUsQ0FBQztBQUZELDBCQUVDIiwic291cmNlc0NvbnRlbnQiOlsiXG4vKlxuICogQ29weXJpZ2h0IChjKSAyMDIwIEVyaWsgRm9ydHVuZVxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbiAqIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbiAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGxcbiAqIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4gKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRVxuICogU09GVFdBUkUuXG4gKi9cbmltcG9ydCB7IEJhc2VDb252ZXJ0ZXIsIENvbnZlcnRlciwgQ29udmVydGVyVHJhaXRzIH0gZnJvbSAnLi9jb252ZXJ0ZXInO1xuaW1wb3J0IHsgUmFuZ2VPZiwgUmFuZ2VPZlByb3BlcnRpZXMgfSBmcm9tICcuL3JhbmdlT2YnO1xuaW1wb3J0IHsgUmVzdWx0LCBjYXB0dXJlUmVzdWx0LCBmYWlsLCBzdWNjZWVkIH0gZnJvbSAnLi9yZXN1bHQnO1xuXG5pbXBvcnQgeyBEYXRlVGltZSB9IGZyb20gJ2x1eG9uJztcbmltcG9ydCB7IEV4dGVuZGVkQXJyYXkgfSBmcm9tICcuL2V4dGVuZGVkQXJyYXknO1xuaW1wb3J0IE11c3RhY2hlIGZyb20gJ211c3RhY2hlJztcbmltcG9ydCB7IGlzS2V5T2YgfSBmcm9tICcuL3V0aWxzJztcblxudHlwZSBPbkVycm9yID0gJ2ZhaWxPbkVycm9yJyB8ICdpZ25vcmVFcnJvcnMnO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBDb252ZXJ0ZXJzLlN0cmluZ0NvbnZlcnRlciB8IFN0cmluZ0NvbnZlcnRlcn1cbiAqIG1hdGNoaW5nIG1ldGhvZFxuICogQHB1YmxpY1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0cmluZ01hdGNoT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICogQW4gb3B0aW9uYWwgbWVzc2FnZSB0byBiZSBkaXNwbGF5ZWQgaWYgYSBub24tbWF0Y2hpbmcgc3RyaW5nXG4gICAgICogaXMgZW5jb3VudGVyZWQuXG4gICAgICovXG4gICAgbWVzc2FnZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nQ29udmVydGVyIHwgU3RyaW5nQ29udmVydGVyfSBjbGFzcyBleHRlbmRzIHtAbGluayBCYXNlQ29udmVydGVyfVxuICogdG8gcHJvdmlkZSBzdHJpbmctc3BlY2lmaWMgaGVscGVyIG1ldGhvZHMuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJpbmdDb252ZXJ0ZXI8VCBleHRlbmRzIHN0cmluZyA9IHN0cmluZywgVEMgPSB1bmtub3duPiBleHRlbmRzIEJhc2VDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3QgYSBuZXcge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nQ29udmVydGVyIHwgU3RyaW5nQ29udmVydGVyfS5cbiAgICAgKiBAcGFyYW0gZGVmYXVsdENvbnRleHQgLSBPcHRpb25hbCBjb250ZXh0IHVzZWQgYnkgdGhlIGNvbnZlcnNpb24uXG4gICAgICogQHBhcmFtIHRyYWl0cyAtIE9wdGlvbmFsIHRyYWl0cyB0byBiZSBhcHBsaWVkIHRvIHRoZSBjb252ZXJzaW9uLlxuICAgICAqIEBwYXJhbSBjb252ZXJ0ZXIgLSBPcHRpb25hbCBjb252ZXJzaW9uIGZ1bmN0aW9uIHRvIGJlIHVzZWQgZm9yIHRoZSBjb252ZXJzaW9uLlxuICAgICAqL1xuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICAgICAgZGVmYXVsdENvbnRleHQ/OiBUQyxcbiAgICAgICAgdHJhaXRzPzogQ29udmVydGVyVHJhaXRzLFxuICAgICAgICBjb252ZXJ0ZXI6IChmcm9tOiB1bmtub3duLCBzZWxmOiBDb252ZXJ0ZXI8VCwgVEM+LCBjb250ZXh0PzogVEMpID0+IFJlc3VsdDxUPiA9IFN0cmluZ0NvbnZlcnRlci5fY29udmVydCxcbiAgICApIHtcbiAgICAgICAgc3VwZXIoY29udmVydGVyLCBkZWZhdWx0Q29udGV4dCwgdHJhaXRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgc3RhdGljIF9jb252ZXJ0PFQgZXh0ZW5kcyBzdHJpbmc+KGZyb206IHVua25vd24pOiBSZXN1bHQ8VD4ge1xuICAgICAgICByZXR1cm4gdHlwZW9mIGZyb20gPT09ICdzdHJpbmcnXG4gICAgICAgICAgICA/IHN1Y2NlZWQoZnJvbSBhcyBUKVxuICAgICAgICAgICAgOiBmYWlsKGBOb3QgYSBzdHJpbmc6ICR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9YCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHN0YXRpYyBfd3JhcDxUIGV4dGVuZHMgc3RyaW5nLCBUQz4oXG4gICAgICAgIHdyYXBwZWQ6IFN0cmluZ0NvbnZlcnRlcjxULCBUQz4sXG4gICAgICAgIGNvbnZlcnRlcjogKGZyb206IFQpID0+IFJlc3VsdDxUPixcbiAgICAgICAgdHJhaXRzPzogQ29udmVydGVyVHJhaXRzXG4gICAgKTogU3RyaW5nQ29udmVydGVyPFQsIFRDPiB7XG4gICAgICAgIHJldHVybiBuZXcgU3RyaW5nQ29udmVydGVyPFQsIFRDPih1bmRlZmluZWQsIHVuZGVmaW5lZCwgKGZyb206IHVua25vd24pID0+IHtcbiAgICAgICAgICAgIHJldHVybiB3cmFwcGVkLmNvbnZlcnQoZnJvbSkub25TdWNjZXNzKGNvbnZlcnRlcik7XG4gICAgICAgIH0pLl93aXRoKHdyYXBwZWQuX3RyYWl0cyh0cmFpdHMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nQ29udmVydGVyIHwgU3RyaW5nQ29udmVydGVyfSB3aGljaCBjb25zdHJhaW5zIHRoZSByZXN1bHQgdG8gbWF0Y2hcbiAgICAgKiBhIHN1cHBsaWVkIHN0cmluZy5cbiAgICAgKiBAcGFyYW0gbWF0Y2ggLSBUaGUgc3RyaW5nIHRvIGJlIG1hdGNoZWRcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIHtAbGluayBDb252ZXJ0ZXJzLlN0cmluZ01hdGNoT3B0aW9uc30gZm9yIHRoaXMgY29udmVyc2lvbi5cbiAgICAgKiBAcmV0dXJucyB7QGxpbmsgU3VjY2Vzc30gd2l0aCBhIG1hdGNoaW5nIHN0cmluZyBvciB7QGxpbmsgRmFpbHVyZX0gd2l0aCBhbiBpbmZvcm1hdGl2ZVxuICAgICAqIGVycm9yIGlmIHRoZSBzdHJpbmcgZG9lcyBub3QgbWF0Y2guXG4gICAgICoge0BsYWJlbCBzdHJpbmd9XG4gICAgICovXG4gICAgcHVibGljIG1hdGNoaW5nKG1hdGNoOiBzdHJpbmcsIG9wdGlvbnM/OiBQYXJ0aWFsPFN0cmluZ01hdGNoT3B0aW9ucz4pOiBTdHJpbmdDb252ZXJ0ZXI8VCwgVEM+O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHtAbGluayBDb252ZXJ0ZXJzLlN0cmluZ0NvbnZlcnRlciB8IFN0cmluZ0NvbnZlcnRlcn0gd2hpY2ggY29uc3RyYWlucyB0aGUgcmVzdWx0IHRvIG1hdGNoXG4gICAgICogb25lIG9mIGEgc3VwcGxpZWQgYXJyYXkgb2Ygc3RyaW5ncy5cbiAgICAgKiBAcGFyYW0gbWF0Y2ggLSBUaGUgYXJyYXkgb2YgYWxsb3dlZCBzdHJpbmdzLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nTWF0Y2hPcHRpb25zfSBmb3IgdGhpcyBjb252ZXJzaW9uLlxuICAgICAqIEByZXR1cm5zIHtAbGluayBTdWNjZXNzfSB3aXRoIGEgbWF0Y2hpbmcgc3RyaW5nIG9yIHtAbGluayBGYWlsdXJlfSB3aXRoIGFuIGluZm9ybWF0aXZlXG4gICAgICogZXJyb3IgaWYgdGhlIHN0cmluZyBkb2VzIG5vdCBtYXRjaC5cbiAgICAgKiB7QGxhYmVsIGFycmF5fVxuICAgICAqL1xuICAgIHB1YmxpYyBtYXRjaGluZyhtYXRjaDogc3RyaW5nW10sIG9wdGlvbnM/OiBQYXJ0aWFsPFN0cmluZ01hdGNoT3B0aW9ucz4pOiBTdHJpbmdDb252ZXJ0ZXI8VCwgVEM+O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHtAbGluayBDb252ZXJ0ZXJzLlN0cmluZ0NvbnZlcnRlciB8IFN0cmluZ0NvbnZlcnRlcn0gd2hpY2ggY29uc3RyYWlucyB0aGUgcmVzdWx0IHRvIG1hdGNoXG4gICAgICogb25lIG9mIGEgc3VwcGxpZWQgYFNldGAgb2Ygc3RyaW5ncy5cbiAgICAgKiBAcGFyYW0gbWF0Y2ggLSBUaGUgYFNldGAgb2YgYWxsb3dlZCBzdHJpbmdzLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nTWF0Y2hPcHRpb25zfSBmb3IgdGhpcyBjb252ZXJzaW9uLlxuICAgICAqIEByZXR1cm5zIHtAbGluayBTdWNjZXNzfSB3aXRoIGEgbWF0Y2hpbmcgc3RyaW5nIG9yIHtAbGluayBGYWlsdXJlfSB3aXRoIGFuIGluZm9ybWF0aXZlXG4gICAgICogZXJyb3IgaWYgdGhlIHN0cmluZyBkb2VzIG5vdCBtYXRjaC5cbiAgICAgKiB7QGxhYmVsIHNldH1cbiAgICAgKi9cbiAgICBwdWJsaWMgbWF0Y2hpbmcobWF0Y2g6IFNldDxUPiwgb3B0aW9ucz86IFBhcnRpYWw8U3RyaW5nTWF0Y2hPcHRpb25zPik6IFN0cmluZ0NvbnZlcnRlcjxULCBUQz47XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nQ29udmVydGVyIHwgU3RyaW5nQ29udmVydGVyfSB3aGljaCBjb25zdHJhaW5zIHRoZSByZXN1bHQgdG8gbWF0Y2hcbiAgICAgKiBhIHN1cHBsaWVkIHJlZ3VsYXIgZXhwcmVzc2lvbi5cbiAgICAgKiBAcGFyYW0gbWF0Y2ggLSBUaGUgcmVndWxhciBleHByZXNzaW9uIHRvIGJlIHVzZWQgYXMgYSBjb25zdHJhaW50LlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nTWF0Y2hPcHRpb25zfSBmb3IgdGhpcyBjb252ZXJzaW9uXG4gICAgICogQHJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggYSBtYXRjaGluZyBzdHJpbmcgb3Ige0BsaW5rIEZhaWx1cmV9IHdpdGggYW4gaW5mb3JtYXRpdmVcbiAgICAgKiBlcnJvciBpZiB0aGUgc3RyaW5nIGRvZXMgbm90IG1hdGNoLlxuICAgICAqIHtAbGFiZWwgcmVnZXhwfVxuICAgICAqL1xuICAgIHB1YmxpYyBtYXRjaGluZyhtYXRjaDogUmVnRXhwLCBvcHRpb25zPzogUGFydGlhbDxTdHJpbmdNYXRjaE9wdGlvbnM+KTogU3RyaW5nQ29udmVydGVyPFQsIFRDPjtcbiAgICAvKipcbiAgICAgKiBDb25jcmV0ZSBpbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgQ29udmVydGVycy5TdHJpbmdDb252ZXJ0ZXIuKG1hdGNoaW5nI3N0cmluZykgfCBTdHJpbmdDb252ZXJ0ZXIubWF0Y2hpbmcoc3RyaW5nKX0sXG4gICAgICoge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nQ29udmVydGVyLihtYXRjaGluZyNhcnJheSkgfCBTdHJpbmdDb252ZXJ0ZXIubWF0Y2hpbmcoc3RyaW5nW10pfSxcbiAgICAgKiB7QGxpbmsgQ29udmVydGVycy5TdHJpbmdDb252ZXJ0ZXIuKG1hdGNoaW5nI3NldCkgfCBTdHJpbmdDb252ZXJ0ZXIubWF0Y2hpbmcoU2V0PHN0cmluZz4pfSwgYW5kXG4gICAgICoge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nQ29udmVydGVyLihtYXRjaGluZyNyZWdleHApIHwgU3RyaW5nQ29udmVydGVyLm1hdGNoaW5nKFJlZ0V4cCl9LlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBtYXRjaGluZyhtYXRjaDogc3RyaW5nIHwgc3RyaW5nW10gfCBTZXQ8VD4gfCBSZWdFeHAsIG9wdGlvbnM/OiBQYXJ0aWFsPFN0cmluZ01hdGNoT3B0aW9ucz4pOiBTdHJpbmdDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IG9wdGlvbnM/Lm1lc3NhZ2U7XG4gICAgICAgIGlmICh0eXBlb2YgbWF0Y2ggPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gU3RyaW5nQ29udmVydGVyLl93cmFwPFQsIFRDPih0aGlzLCAoZnJvbTogVCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiAobWF0Y2ggPT09IGZyb20pXG4gICAgICAgICAgICAgICAgICAgID8gc3VjY2VlZChmcm9tIGFzIFQpXG4gICAgICAgICAgICAgICAgICAgIDogZmFpbChtZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgICAgICA/IGBcIiR7ZnJvbX1cIjogJHttZXNzYWdlfWBcbiAgICAgICAgICAgICAgICAgICAgICAgIDogYFwiJHtmcm9tfVwiOiBkb2VzIG5vdCBtYXRjaCBcIiR7bWF0Y2h9XCJgKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG1hdGNoIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXR1cm4gU3RyaW5nQ29udmVydGVyLl93cmFwPFQsIFRDPih0aGlzLCAoZnJvbTogVCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiAobWF0Y2gudGVzdChmcm9tKSlcbiAgICAgICAgICAgICAgICAgICAgPyBzdWNjZWVkKGZyb20gYXMgVClcbiAgICAgICAgICAgICAgICAgICAgOiBmYWlsKG1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgID8gYFwiJHtmcm9tfVwiOiAke21lc3NhZ2V9YFxuICAgICAgICAgICAgICAgICAgICAgICAgOiBgXCIke2Zyb219XCI6IGRvZXMgbm90IG1hdGNoIFwiJHttYXRjaH1cImApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobWF0Y2ggaW5zdGFuY2VvZiBTZXQpIHtcbiAgICAgICAgICAgIHJldHVybiBTdHJpbmdDb252ZXJ0ZXIuX3dyYXA8VCwgVEM+KHRoaXMsIChmcm9tOiBUKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChtYXRjaC5oYXMoZnJvbSkpXG4gICAgICAgICAgICAgICAgICAgID8gc3VjY2VlZChmcm9tIGFzIFQpXG4gICAgICAgICAgICAgICAgICAgIDogZmFpbChtZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgICAgICA/IGBcIiR7ZnJvbX1cIjogJHttZXNzYWdlfWBcbiAgICAgICAgICAgICAgICAgICAgICAgIDogYFwiJHtmcm9tfVwiOiBub3QgZm91bmQgaW4gc2V0YCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBTdHJpbmdDb252ZXJ0ZXIuX3dyYXA8VCwgVEM+KHRoaXMsIChmcm9tOiBUKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChtYXRjaC5pbmNsdWRlcyhmcm9tKSlcbiAgICAgICAgICAgICAgICAgICAgPyBzdWNjZWVkKGZyb20gYXMgVClcbiAgICAgICAgICAgICAgICAgICAgOiBmYWlsKG1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgID8gYFwiJHtmcm9tfVwiOiAke21lc3NhZ2V9YFxuICAgICAgICAgICAgICAgICAgICAgICAgOiBgXCIke2Zyb219XCI6IG5vdCBmb3VuZCBpbiBbJHttYXRjaC5qb2luKCcsJyl9XWApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogQSBjb252ZXJ0ZXIgdG8gY29udmVydCB1bmtub3duIHRvIHN0cmluZy4gVmFsdWVzIG9mIHR5cGVcbiAqIHN0cmluZyBzdWNjZWVkLiAgQW55dGhpbmcgZWxzZSBmYWlscy5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IHN0cmluZyA9IG5ldyBTdHJpbmdDb252ZXJ0ZXIoKTtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nQ29udmVydGVyIHwgU3RyaW5nQ29udmVydGVyfSB3aGljaCBjb252ZXJ0c1xuICogYHVua25vd25gIHRvIGBzdHJpbmdgLCBhcHBseWluZyB0ZW1wbGF0ZSBjb252ZXJzaW9ucyBzdXBwbGllZCBhdCBjb25zdHJ1Y3Rpb24gdGltZSBvciBhdFxuICogcnVudGltZSBhcyBjb250ZXh0LlxuICogQHJlbWFya3NcbiAqIFRlbXBsYXRlIGNvbnZlcnNpb25zIGFyZSBhcHBsaWVkIHVzaW5nIGBtdXN0YWNoZWAgc3ludGF4LlxuICogQHBhcmFtIGRlZmF1bHRDb250ZXh0IC0gT3B0aW9uYWwgZGVmYXVsdCBjb250ZXh0IHRvIHVzZSBmb3IgdGVtcGxhdGUgdmFsdWVzLlxuICogQHJldHVybnMgQSBuZXcge0BsaW5rIENvbnZlcnRlcn0gcmV0dXJuaW5nIGBzdHJpbmdgLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gdGVtcGxhdGVTdHJpbmcoZGVmYXVsdENvbnRleHQ/OiB1bmtub3duKTogU3RyaW5nQ29udmVydGVyPHN0cmluZywgdW5rbm93bj4ge1xuICAgIHJldHVybiBuZXcgU3RyaW5nQ29udmVydGVyPHN0cmluZywgdW5rbm93bj4oZGVmYXVsdENvbnRleHQsIHVuZGVmaW5lZCwgKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8c3RyaW5nLCB1bmtub3duPiwgY29udGV4dD86IHVua25vd24pID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBmcm9tICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYE5vdCBhIHN0cmluZzogJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FwdHVyZVJlc3VsdCgoKSA9PiBNdXN0YWNoZS5yZW5kZXIoZnJvbSwgY29udGV4dCkpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBjb252ZXJ0cyBgdW5rbm93bmAgdG8gb25lIG9mIGEgc2V0IG9mIHN1cHBsaWVkXG4gKiBlbnVtZXJhdGVkIHZhbHVlcy4gQW55dGhpbmcgZWxzZSBmYWlscy5cbiAqXG4gKiBAcmVtYXJrc1xuICogQWxsb3dlZCBlbnVtZXJhdGVkIHZhbHVlcyBjYW4gYWxzbyBiZSBzdXBwbGllZCBhcyBjb250ZXh0IGF0IGNvbnZlcnNpb24gdGltZS5cbiAqIEBwYXJhbSB2YWx1ZXMgLSBBcnJheSBvZiBhbGxvd2VkIHZhbHVlcy5cbiAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBDb252ZXJ0ZXJ9IHJldHVybmluZyBgPFQ+YC5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVudW1lcmF0ZWRWYWx1ZTxUPih2YWx1ZXM6IFRbXSk6IENvbnZlcnRlcjxULCBUW10+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VCwgVFtdPiwgY29udGV4dD86IFRbXSk6IFJlc3VsdDxUPiA9PiB7XG4gICAgICAgIGNvbnN0IHYgPSBjb250ZXh0ID8/IHZhbHVlcztcbiAgICAgICAgY29uc3QgaW5kZXggPSB2LmluZGV4T2YoZnJvbSBhcyBUKTtcbiAgICAgICAgcmV0dXJuIChpbmRleCA+PSAwID8gc3VjY2VlZCh2W2luZGV4XSkgOiBmYWlsKGBJbnZhbGlkIGVudW1lcmF0ZWQgdmFsdWUgJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKSk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIGB1bmtub3duYCB0byBvbmUgb2YgYSBzZXQgb2Ygc3VwcGxpZWQgZW51bWVyYXRlZFxuICogdmFsdWVzLCBtYXBwaW5nIGFueSBvZiBtdWx0aXBsZSBzdXBwbGllZCB2YWx1ZXMgdG8gdGhlIGVudW1lcmF0aW9uLlxuICogQHJlbWFya3NcbiAqIEVuYWJsZXMgbWFwcGluZyBvZiBtdWx0aXBsZSBpbnB1dCB2YWx1ZXMgdG8gYSBjb25zaXN0ZW50IGludGVybmFsIHJlcHJlc2VudGF0aW9uIChzbyBlLmcuIGAneSdgLCBgJ3llcydgLFxuICogYCd0cnVlJ2AsIGAxYCBhbmQgYHRydWVgIGNhbiBhbGwgbWFwIHRvIGJvb2xlYW4gYHRydWVgKVxuICogQHBhcmFtIG1hcCAtIEFuIGFycmF5IG9mIHR1cGxlcyBkZXNjcmliaW5nIHRoZSBtYXBwaW5nLiBUaGUgZmlyc3QgZWxlbWVudCBvZiBlYWNoIHR1cGxlIGlzIHRoZSByZXN1bHRcbiAqIHZhbHVlLCB0aGUgc2Vjb25kIGlzIHRoZSBzZXQgb2YgdmFsdWVzIHRoYXQgbWFwIHRvIHRoZSByZXN1bHQuICBUdXBsZXMgYXJlIGV2YWx1YXRlZCBpbiB0aGUgb3JkZXJcbiAqIHN1cHBsaWVkIGFuZCBhcmUgbm90IGNoZWNrZWQgZm9yIGR1cGxpY2F0ZXMuXG4gKiBAcGFyYW0gbWVzc2FnZSAtIEFuIG9wdGlvbmFsIGVycm9yIG1lc3NhZ2UuXG4gKiBAcmV0dXJucyBBIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGFwcGxpZXMgdGhlIG1hcHBpbmcgYW5kIHlpZWxkcyBgPFQ+YCBvbiBzdWNjZXNzLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWFwcGVkRW51bWVyYXRlZFZhbHVlPFQ+KG1hcDogW1QsIHVua25vd25bXV1bXSwgbWVzc2FnZT86IHN0cmluZyk6IENvbnZlcnRlcjxULCB1bmRlZmluZWQ+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VCwgdW5kZWZpbmVkPiwgX2NvbnRleHQ/OiB1bmtub3duKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBtYXApIHtcbiAgICAgICAgICAgIGlmIChpdGVtWzFdLmluY2x1ZGVzKGZyb20pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1Y2NlZWQoaXRlbVswXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhaWwobWVzc2FnZSA/IGAke0pTT04uc3RyaW5naWZ5KGZyb20pfTogJHttZXNzYWdlfWAgOiBgQ2Fubm90IG1hcCAnJHtKU09OLnN0cmluZ2lmeShmcm9tKX0nIHRvIGEgc3VwcG9ydGVkIHZhbHVlYCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIGB1bmtub3duYCB0byBzb21lIHN1cHBsaWVkIGxpdGVyYWwgdmFsdWUuIFN1Y2NlZWRzIHdpdGhcbiAqIHRoZSBzdXBwbGllZCB2YWx1ZSBpZiBhbiBpZGVudGl0eSBjb21wYXJpc29uIHN1Y2NlZWRzLCBmYWlscyBvdGhlcndpc2UuXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gYmUgY29tcGFyZWQuXG4gKiBAcmV0dXJucyBBIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIHJldHVybnMgdGhlIHN1cHBsaWVkIHZhbHVlIG9uIHN1Y2Nlc3MuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaXRlcmFsPFQ+KHZhbHVlOiBUKTogQ29udmVydGVyPFQsIHVua25vd24+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXI8VCwgdW5rbm93bj4oKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VCwgdW5rbm93bj4sIF9jb250ZXh0PzogdW5rbm93bik6IFJlc3VsdDxUPiA9PiB7XG4gICAgICAgIHJldHVybiAoZnJvbSA9PT0gdmFsdWUpID8gc3VjY2VlZCh2YWx1ZSkgOiBmYWlsKGAke0pTT04uc3RyaW5naWZ5KGZyb20pfTogZG9lcyBub3QgbWF0Y2ggJHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9YCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogRGVwcmVjYXRlZCBhbGlhcyBmb3IgQHNlZSBsaXRlcmFsXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gYmUgY29tcGFyZWQuXG4gKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rIENvbnZlcnRlcnMubGl0ZXJhbH0gaW5zdGVhZC5cbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgdmFsdWUgPSBsaXRlcmFsO1xuXG4vKipcbiAqIEEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggY29udmVydHMgYHVua25vd25gIHRvIGEgYG51bWJlcmAuXG4gKiBAcmVtYXJrc1xuICogTnVtYmVycyBhbmQgc3RyaW5ncyB3aXRoIGEgbnVtZXJpYyBmb3JtYXQgc3VjY2VlZC4gQW55dGhpbmcgZWxzZSBmYWlscy5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IG51bWJlciA9IG5ldyBCYXNlQ29udmVydGVyPG51bWJlcj4oKGZyb206IHVua25vd24pID0+IHtcbiAgICBpZiAodHlwZW9mIGZyb20gIT09ICdudW1iZXInKSB7XG4gICAgICAgIGNvbnN0IG51bTogbnVtYmVyID0gKHR5cGVvZiBmcm9tID09PSAnc3RyaW5nJyA/IE51bWJlcihmcm9tKSA6IE5hTik7XG4gICAgICAgIHJldHVybiBpc05hTihudW0pXG4gICAgICAgICAgICA/IGZhaWwoYE5vdCBhIG51bWJlcjogJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKVxuICAgICAgICAgICAgOiBzdWNjZWVkKG51bSk7XG4gICAgfVxuICAgIHJldHVybiBzdWNjZWVkKGZyb20pO1xufSk7XG5cbi8qKlxuICogQSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBjb252ZXJ0cyBgdW5rbm93bmAgdG8gYGJvb2xlYW5gLlxuICogQHJlbWFya3NcbiAqIEJvb2xlYW4gdmFsdWVzIG9yIHRoZSBjYXNlLWluc2Vuc2l0aXZlIHN0cmluZ3MgYCd0cnVlJ2AgYW5kIGAnZmFsc2UnYCBzdWNjZWVkLlxuICogQW55dGhpbmcgZWxzZSBmYWlscy5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IGJvb2xlYW4gPSBuZXcgQmFzZUNvbnZlcnRlcjxib29sZWFuPigoZnJvbTogdW5rbm93bikgPT4ge1xuICAgIGlmICh0eXBlb2YgZnJvbSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHJldHVybiBzdWNjZWVkKGZyb20gYXMgYm9vbGVhbik7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBmcm9tID09PSAnc3RyaW5nJykge1xuICAgICAgICBzd2l0Y2ggKGZyb20udG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSAndHJ1ZSc6IHJldHVybiBzdWNjZWVkKHRydWUpO1xuICAgICAgICAgICAgY2FzZSAnZmFsc2UnOiByZXR1cm4gc3VjY2VlZChmYWxzZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhaWwoYE5vdCBhIGJvb2xlYW46ICR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9YCk7XG59KTtcblxuLyoqXG4gKiBBIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIGFuIG9wdGlvbmFsIGBzdHJpbmdgIHZhbHVlLiBWYWx1ZXMgb2YgdHlwZVxuICogYHN0cmluZ2AgYXJlIHJldHVybmVkLiAgQW55dGhpbmcgZWxzZSByZXR1cm5zIHtAbGluayBTdWNjZXNzfSB3aXRoIHZhbHVlIGB1bmRlZmluZWRgLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3Qgb3B0aW9uYWxTdHJpbmcgPSBzdHJpbmcub3B0aW9uYWwoKTtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggY29udmVydHMgYW55IGBzdHJpbmdgIGludG8gYW5cbiAqIGFycmF5IG9mIGBzdHJpbmdgLCBieSBzZXBhcmF0aW5nIGF0IGEgc3VwcGxpZWQgZGVsaW1pdGVyLlxuICogQHJlbWFya3NcbiAqIERlbGltaXRlciBtYXkgYWxzbyBiZSBzdXBwbGllZCBhcyBjb250ZXh0IGF0IGNvbnZlcnNpb24gdGltZS5cbiAqIEBwYXJhbSBkZWxpbWl0ZXIgLSBUaGUgZGVsaW1pdGVyIGF0IHdoaWNoIHRvIHNwbGl0LlxuICogQHJldHVybnMgQSBuZXcge0BsaW5rIENvbnZlcnRlcn0gcmV0dXJuaW5nIGBzdHJpbmdbXWAuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWxpbWl0ZWRTdHJpbmcoZGVsaW1pdGVyOiBzdHJpbmcsIG9wdGlvbnM6ICdmaWx0ZXJlZCd8J2FsbCcgPSAnZmlsdGVyZWQnKTogQ29udmVydGVyPHN0cmluZ1tdLCBzdHJpbmc+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXI8c3RyaW5nW10sIHN0cmluZz4oKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8c3RyaW5nW10sIHN0cmluZz4sIGNvbnRleHQ/OiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gc3RyaW5nLmNvbnZlcnQoZnJvbSk7XG4gICAgICAgIGlmIChyZXN1bHQuaXNTdWNjZXNzKCkpIHtcbiAgICAgICAgICAgIGxldCBzdHJpbmdzID0gcmVzdWx0LnZhbHVlLnNwbGl0KGNvbnRleHQgPz8gZGVsaW1pdGVyKTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zICE9PSAnYWxsJykge1xuICAgICAgICAgICAgICAgIHN0cmluZ3MgPSBzdHJpbmdzLmZpbHRlcigocykgPT4gKHMudHJpbSgpLmxlbmd0aCA+IDApKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdWNjZWVkKHN0cmluZ3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWlsKHJlc3VsdC5tZXNzYWdlKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIGFuIGlzbyBmb3JtYXR0ZWQgc3RyaW5nLCBhIG51bWJlciBvciBhIGBEYXRlYCBvYmplY3QgdG9cbiAqIGEgYERhdGVgIG9iamVjdC5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IGlzb0RhdGUgPSBuZXcgQmFzZUNvbnZlcnRlcjxEYXRlPigoZnJvbTogdW5rbm93bikgPT4ge1xuICAgIGlmICh0eXBlb2YgZnJvbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc3QgZHQgPSBEYXRlVGltZS5mcm9tSVNPKGZyb20pO1xuICAgICAgICBpZiAoZHQuaXNWYWxpZCkge1xuICAgICAgICAgICAgcmV0dXJuIHN1Y2NlZWQoZHQudG9KU0RhdGUoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhaWwoYEludmFsaWQgZGF0ZTogJHtkdC5pbnZhbGlkRXhwbGFuYXRpb259YCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBmcm9tID09PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gc3VjY2VlZChuZXcgRGF0ZShmcm9tKSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGZyb20gaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgIHJldHVybiBzdWNjZWVkKGZyb20pO1xuICAgIH1cbiAgICByZXR1cm4gZmFpbChgQ2Fubm90IGNvbnZlcnQgJHtKU09OLnN0cmluZ2lmeShmcm9tKX0gdG8gRGF0ZWApO1xufSk7XG5cbi8qKlxuICogQSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBjb252ZXJ0cyBhbiBvcHRpb25hbCBgbnVtYmVyYCB2YWx1ZS5cbiAqIEByZW1hcmtzXG4gKiBWYWx1ZXMgb2YgdHlwZSBgbnVtYmVyYCBvciBudW1lcmljIHN0cmluZ3MgYXJlIGNvbnZlcnRlZCBhbmQgcmV0dXJuZWQuXG4gKiBBbnl0aGluZyBlbHNlIHJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggdmFsdWUgYHVuZGVmaW5lZGAuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBvcHRpb25hbE51bWJlciA9IG51bWJlci5vcHRpb25hbCgpO1xuXG4vKipcbiAqIEEge0BsaW5rIENvbnZlcnRlcn0gdG8gY29udmVydCBhbiBvcHRpb25hbCBgYm9vbGVhbmAgdmFsdWUuXG4gKiBAcmVtYXJrc1xuICogVmFsdWVzIG9mIHR5cGUgYGJvb2xlYW5gIG9yIHN0cmluZ3MgdGhhdCBtYXRjaCAoY2FzZS1pbnNlbnNpdGl2ZSkgYCd0cnVlJ2BcbiAqIG9yIGAnZmFsc2UnYCBhcmUgY29udmVydGVkIGFuZCByZXR1cm5lZC4gIEFueXRoaW5nIGVsc2UgcmV0dXJucyB7QGxpbmsgU3VjY2Vzc31cbiAqIHdpdGggdmFsdWUgYHVuZGVmaW5lZGAuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBvcHRpb25hbEJvb2xlYW4gPSBib29sZWFuLm9wdGlvbmFsKCk7XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcn0gZm9yIHBvbHltb3JwaGljIHZhbHVlcy4gIFJldHVybnMgYVxuICogY29udmVydGVyIHdoaWNoIEludm9rZXMgdGhlIHdyYXBwZWQgY29udmVydGVycyBpbiBzZXF1ZW5jZSwgcmV0dXJuaW5nIHRoZSBmaXJzdCBzdWNjZXNzZnVsXG4gKiByZXN1bHQuICBSZXR1cm5zIGFuIGVycm9yIGlmIG5vbmUgb2YgdGhlIHN1cHBsaWVkIGNvbnZlcnRlcnMgY2FuIGNvbnZlcnQgdGhlIHZhbHVlLlxuICogQHJlbWFya3NcbiAqIElmIGBvbkVycm9yYCBpcyBgaWdub3JlRXJyb3JzYCAoZGVmYXVsdCksIHRoZW4gZXJyb3JzIGZyb20gYW55IG9mIHRoZVxuICogY29udmVydGVycyBhcmUgaWdub3JlZCBwcm92aWRlZCB0aGF0IHNvbWUgY29udmVydGVyIHN1Y2NlZWRzLiAgSWZcbiAqIG9uRXJyb3IgaXMgYGZhaWxPbkVycm9yYCwgdGhlbiBhbiBlcnJvciBmcm9tIGFueSBjb252ZXJ0ZXIgZmFpbHMgdGhlIGVudGlyZVxuICogY29udmVyc2lvbi5cbiAqXG4gKiBAcGFyYW0gY29udmVydGVycyAtIEFuIG9yZGVyZWQgbGlzdCBvZiB7QGxpbmsgQ29udmVydGVyIHwgY29udmVydGVyc30gdG8gYmUgY29uc2lkZXJlZC5cbiAqIEBwYXJhbSBvbkVycm9yIC0gU3BlY2lmaWVzIHRyZWF0bWVudCBvZiB1bmNvbnZlcnRpYmxlIGVsZW1lbnRzLlxuICogQHJldHVybnMgQSBuZXcge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggeWllbGRzIGEgdmFsdWUgZnJvbSB0aGUgdW5pb24gb2YgdGhlIHR5cGVzIHJldHVybmVkXG4gKiBieSB0aGUgd3JhcHBlZCBjb252ZXJ0ZXJzLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gb25lT2Y8VCwgVEM9dW5rbm93bj4oY29udmVydGVyczogQXJyYXk8Q29udmVydGVyPFQsIFRDPj4sIG9uRXJyb3I6IE9uRXJyb3IgPSAnaWdub3JlRXJyb3JzJyk6IENvbnZlcnRlcjxULCBUQz4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGYsIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG4gICAgICAgIGZvciAoY29uc3QgY29udmVydGVyIG9mIGNvbnZlcnRlcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnZlcnRlci5jb252ZXJ0KGZyb20sIGNvbnRleHQpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSAmJiAocmVzdWx0LnZhbHVlICE9PSB1bmRlZmluZWQpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJlc3VsdC5pc0ZhaWx1cmUoKSkge1xuICAgICAgICAgICAgICAgIGlmIChvbkVycm9yID09PSAnZmFpbE9uRXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVycm9ycy5wdXNoKHJlc3VsdC5tZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFpbChgTm8gbWF0Y2hpbmcgY29udmVydGVyIGZvciAke0pTT04uc3RyaW5naWZ5KGZyb20pfTogJHtlcnJvcnMuam9pbignXFxuJyl9YCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggY29udmVydHMgYHVua25vd25gIHRvIGFuIGFycmF5IG9mIGA8VD5gLlxuICogQHJlbWFya3NcbiAqIElmIGBvbkVycm9yYCBpcyBgJ2ZhaWxPbkVycm9yJ2AgKGRlZmF1bHQpLCB0aGVuIHRoZSBlbnRpcmUgY29udmVyc2lvbiBmYWlscyBpZiBhbnkgZWxlbWVudCBjYW5ub3RcbiAqIGJlIGNvbnZlcnRlZC4gIElmIGBvbkVycm9yYCBpcyBgJ2lnbm9yZUVycm9ycydgLCB0aGVuIGZhaWxpbmcgZWxlbWVudHMgYXJlIHNpbGVudGx5IGlnbm9yZWQuXG4gKiBAcGFyYW0gY29udmVydGVyIC0ge0BsaW5rIENvbnZlcnRlcn0gdXNlZCB0byBjb252ZXJ0IGVhY2ggaXRlbSBpbiB0aGUgYXJyYXkuXG4gKiBAcGFyYW0gaWdub3JlRXJyb3JzIC0gU3BlY2lmaWVzIHRyZWF0bWVudCBvZiB1bmNvbnZlcnRpYmxlIGVsZW1lbnRzLlxuICogQHJldHVybnMgQSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCByZXR1cm5zIGFuIGFycmF5IG9mIGA8VD5gLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlPZjxULCBUQz11bmRlZmluZWQ+KGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPiwgb25FcnJvcjogT25FcnJvciA9ICdmYWlsT25FcnJvcicpOiBDb252ZXJ0ZXI8VFtdLCBUQz4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxUW10sIFRDPiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShmcm9tKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYE5vdCBhbiBhcnJheTogJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN1Y2Nlc3NlczogVFtdID0gW107XG4gICAgICAgIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGZyb20pIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnZlcnRlci5jb252ZXJ0KGl0ZW0sIGNvbnRleHQpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSAmJiByZXN1bHQudmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3Nlcy5wdXNoKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChyZXN1bHQuaXNGYWlsdXJlKCkpIHtcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChyZXN1bHQubWVzc2FnZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gKGVycm9ycy5sZW5ndGggPT09IDApIHx8IChvbkVycm9yID09PSAnaWdub3JlRXJyb3JzJylcbiAgICAgICAgICAgID8gc3VjY2VlZChzdWNjZXNzZXMpXG4gICAgICAgICAgICA6IGZhaWwoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBIGhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBjb252ZXJ0cyBgdW5rbm93bmAgdG8ge0BsaW5rIEV4dGVuZGVkQXJyYXkgfCBFeHRlbmRlZEFycmF5PFQ+fS5cbiAqIEByZW1hcmtzXG4gKiBJZiBgb25FcnJvcmAgaXMgYCdmYWlsT25FcnJvcidgIChkZWZhdWx0KSwgdGhlbiB0aGUgZW50aXJlIGNvbnZlcnNpb24gZmFpbHMgaWYgYW55IGVsZW1lbnQgY2Fubm90XG4gKiBiZSBjb252ZXJ0ZWQuICBJZiBgb25FcnJvcmAgaXMgYCdpZ25vcmVFcnJvcnMnYCwgdGhlbiBmYWlsaW5nIGVsZW1lbnRzIGFyZSBzaWxlbnRseSBpZ25vcmVkLlxuICogQHBhcmFtIGNvbnZlcnRlciAtIHtAbGluayBDb252ZXJ0ZXJ9IHVzZWQgdG8gY29udmVydCBlYWNoIGl0ZW0gaW4gdGhlIGFycmF5XG4gKiBAcGFyYW0gaWdub3JlRXJyb3JzIC0gU3BlY2lmaWVzIHRyZWF0bWVudCBvZiB1bmNvbnZlcnRpYmxlIGVsZW1lbnRzXG4gKiBAYmV0YVxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0ZW5kZWRBcnJheU9mPFQsIFRDPXVuZGVmaW5lZD4obGFiZWw6IHN0cmluZywgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+LCBvbkVycm9yOiBPbkVycm9yID0gJ2ZhaWxPbkVycm9yJyk6IENvbnZlcnRlcjxFeHRlbmRlZEFycmF5PFQ+LCBUQz4ge1xuICAgIHJldHVybiBhcnJheU9mKGNvbnZlcnRlciwgb25FcnJvcikubWFwKChpdGVtczogVFtdKSA9PiB7XG4gICAgICAgIHJldHVybiBjYXB0dXJlUmVzdWx0KCgpID0+IG5ldyBFeHRlbmRlZEFycmF5KGxhYmVsLCAuLi5pdGVtcykpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIHtAbGluayBDb252ZXJ0ZXJ9IHRvIGNvbnZlcnQgYW4gYHVua25vd25gIHRvIGFuIGFycmF5IG9mIGBzdHJpbmdgLlxuICogQHJlbWFya3NcbiAqIFJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggdGhlIHRoZSBzdXBwbGllZCB2YWx1ZSBpZiBpdCBhcyBhbiBhcnJheVxuICogb2Ygc3RyaW5ncywgcmV0dXJucyB7QGxpbmsgRmFpbHVyZX0gd2l0aCBhbiBlcnJvciBtZXNzYWdlIG90aGVyd2lzZS5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IHN0cmluZ0FycmF5ID0gYXJyYXlPZihzdHJpbmcpO1xuXG4vKipcbiAqIHtAbGluayBDb252ZXJ0ZXJ9IHRvIGNvbnZlcnQgYW4gYHVua25vd25gIHRvIGFuIGFycmF5IG9mIGBudW1iZXJgLlxuICogQHJlbWFya3NcbiAqIFJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggdGhlIHRoZSBzdXBwbGllZCB2YWx1ZSBpZiBpdCBhcyBhbiBhcnJheVxuICogb2YgbnVtYmVycywgcmV0dXJucyB7QGxpbmsgRmFpbHVyZX0gd2l0aCBhbiBlcnJvciBtZXNzYWdlIG90aGVyd2lzZS5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IG51bWJlckFycmF5ID0gYXJyYXlPZihudW1iZXIpO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBDb252ZXJ0ZXJzLihyZWNvcmRPZjp3aXRoT3B0aW9ucyl9IGFuZCB7QGxpbmsgQ29udmVydGVycy4obWFwT2Y6d2l0aE9wdGlvbnMpfVxuICogaGVscGVyIGZ1bmN0aW9ucy5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBLZXllZENvbnZlcnRlck9wdGlvbnM8VCBleHRlbmRzIHN0cmluZyA9IHN0cmluZywgVEM9dW5kZWZpbmVkPiB7XG4gICAgLyoqXG4gICAgICogaWYgYG9uRXJyb3JgIGlzIGAnZmFpbCdgIChkZWZhdWx0KSwgdGhlbiB0aGUgZW50aXJlIGNvbnZlcnNpb24gZmFpbHMgaWYgYW55IGtleSBvciBlbGVtZW50XG4gICAgICogY2Fubm90IGJlIGNvbnZlcnRlZC4gIElmIGBvbkVycm9yYCBpcyBgJ2lnbm9yZSdgLCBmYWlsaW5nIGVsZW1lbnRzIGFyZSBzaWxlbnRseSBpZ25vcmVkLlxuICAgICAqL1xuICAgIG9uRXJyb3I/OiAnZmFpbCd8J2lnbm9yZSc7XG4gICAgLyoqXG4gICAgICogSWYgcHJlc2VudCwgYGtleUNvbnZlcnRlcmAgaXMgdXNlZCB0byBjb252ZXJ0IHRoZSBzb3VyY2Ugb2JqZWN0IHByb3BlcnR5IG5hbWVzIHRvXG4gICAgICoga2V5cyBpbiB0aGUgcmVzdWx0aW5nIG1hcCBvciByZWNvcmQuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBDYW4gYmUgdXNlZCB0byBjb2VyY2Uga2V5IG5hbWVzIHRvIHN1cHBvcnRlZCB2YWx1ZXMgYW5kL29yIHN0cm9uZyB0eXBlcy5cbiAgICAgKi9cbiAgICBrZXlDb252ZXJ0ZXI/OiBDb252ZXJ0ZXI8VCwgVEM+O1xufVxuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIHRoZSBgc3RyaW5nYC1rZXllZCBwcm9wZXJ0aWVzXG4gKiB1c2luZyBhIHN1cHBsaWVkIHtAbGluayBDb252ZXJ0ZXIgfCBDb252ZXJ0ZXI8VD59IHRvIHByb2R1Y2UgYSBgUmVjb3JkPHN0cmluZywgVD5gLlxuICogQHJlbWFya3NcbiAqIFRoZSByZXN1bHRpbmcgY29udmVydGVyIGZhaWxzIGNvbnZlcnNpb24gaWYgYW55IGVsZW1lbnQgY2Fubm90IGJlIGNvbnZlcnRlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgLSB7QGxpbmsgQ29udmVydGVyfSB1c2VkIHRvIGNvbnZlcnQgZWFjaCBpdGVtIGluIHRoZSBzb3VyY2Ugb2JqZWN0LlxuICogQHJldHVybnMgQSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCByZXR1cm5zIGBSZWNvcmQ8c3RyaW5nLCBUPmAuXG4gKiB7QGxhYmVsIGRlZmF1bHR9XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRPZjxULCBUQz11bmRlZmluZWQsIFRLIGV4dGVuZHMgc3RyaW5nPXN0cmluZz4oY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+KTogQ29udmVydGVyPFJlY29yZDxUSywgVD4sIFRDPjtcblxuLyoqXG4gKiBBIGhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBjb252ZXJ0cyB0aGUgYHN0cmluZ2Ata2V5ZWQgcHJvcGVydGllc1xuICogdXNpbmcgYSBzdXBwbGllZCB7QGxpbmsgQ29udmVydGVyIHwgQ29udmVydGVyPFQ+fSB0byBwcm9kdWNlIGEgYFJlY29yZDxzdHJpbmcsIFQ+YCBhbmQgb3B0aW9uYWxseVxuICogc3BlY2lmaWVkIGhhbmRsaW5nIG9mIGVsZW1lbnRzIHRoYXQgY2Fubm90IGJlIGNvbnZlcnRlZC5cbiAqIEByZW1hcmtzXG4gKiBpZiBgb25FcnJvcmAgaXMgYCdmYWlsJ2AgKGRlZmF1bHQpLCB0aGVuIHRoZSBlbnRpcmUgY29udmVyc2lvbiBmYWlscyBpZiBhbnkga2V5IG9yIGVsZW1lbnRcbiAqIGNhbm5vdCBiZSBjb252ZXJ0ZWQuICBJZiBgb25FcnJvcmAgaXMgYCdpZ25vcmUnYCwgZmFpbGluZyBlbGVtZW50cyBhcmUgc2lsZW50bHkgaWdub3JlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgLSB7QGxpbmsgQ29udmVydGVyfSB1c2VkIHRvIGNvbnZlcnQgZWFjaCBpdGVtIGluIHRoZSBzb3VyY2Ugb2JqZWN0LlxuICogQHJldHVybnMgQSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCByZXR1cm5zIGBSZWNvcmQ8c3RyaW5nLCBUPmAuXG4gKiB7QGxhYmVsIHdpdGhPbkVycm9yfVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkT2Y8VCwgVEM9dW5kZWZpbmVkLCBUSyBleHRlbmRzIHN0cmluZz1zdHJpbmc+KFxuICAgIGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPixcbiAgICBvbkVycm9yOiAnZmFpbCd8J2lnbm9yZSdcbik6IENvbnZlcnRlcjxSZWNvcmQ8VEssIFQ+LCBUQz47XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggY29udmVydHMgdGhlIGBzdHJpbmdgLWtleWVkIHByb3BlcnRpZXNcbiAqIHVzaW5nIGEgc3VwcGxpZWQge0BsaW5rIENvbnZlcnRlciB8IENvbnZlcnRlcjxUPn0gdG8gcHJvZHVjZSBhIGBSZWNvcmQ8VEssIFQ+YC5cbiAqIEByZW1hcmtzXG4gKiBJZiBwcmVzZW50LCB0aGUgc3VwcGxpZWQge0BsaW5rIENvbnZlcnRlcnMuS2V5ZWRDb252ZXJ0ZXJPcHRpb25zIHwgb3B0aW9uc30gY2FuIHByb3ZpZGUgYSBzdHJvbmdseS10eXBlZFxuICogY29udmVydGVyIGZvciBrZXlzIGFuZC9vciBjb250cm9sIHRoZSBoYW5kbGluZyBvZiBlbGVtZW50cyB0aGF0IGZhaWwgY29udmVyc2lvbi5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgLSB7QGxpbmsgQ29udmVydGVyfSB1c2VkIHRvIGNvbnZlcnQgZWFjaCBpdGVtIGluIHRoZSBzb3VyY2Ugb2JqZWN0LlxuICogQHBhcmFtIG9wdGlvbnMgLSBPcHRpb25hbCB7QGxpbmsgQ29udmVydGVycy5LZXllZENvbnZlcnRlck9wdGlvbnMgfCBLZXllZENvbnZlcnRlck9wdGlvbnM8VEssIFRDPn0gd2hpY2hcbiAqIHN1cHBsaWVzIGEga2V5IGNvbnZlcnRlciBhbmQvb3IgZXJyb3ItaGFuZGxpbmcgb3B0aW9ucy5cbiAqIEByZXR1cm5zIEEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggcmV0dXJucyBgUmVjb3JkPFRLLCBUPmAuXG4gKiB7QGxhYmVsIHdpdGhPcHRpb25zfVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkT2Y8VCwgVEM9dW5kZWZpbmVkLCBUSyBleHRlbmRzIHN0cmluZz1zdHJpbmc+KFxuICAgIGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPixcbiAgICBvcHRpb25zOiBLZXllZENvbnZlcnRlck9wdGlvbnM8VEssIFRDPlxuKTogQ29udmVydGVyPFJlY29yZDxUSywgVD4sIFRDPjtcblxuLyoqXG4gKiBDb25jcmV0ZSBpbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgQ29udmVydGVycy4ocmVjb3JkT2Y6ZGVmYXVsdCkgfCBDb252ZXJ0ZXJzLnJlY29yZE9mKENvbnZlcnRlcjxUPil9LFxuICoge0BsaW5rIENvbnZlcnRlcnMuKHJlY29yZE9mOndpdGhPbkVycm9yKSB8IENvbnZlcnRlcnMucmVjb3JkT2YoQ29udmVydGVyPFQ+LCAnZmFpbCd8J2lnbm9yZScpfSwgYW5kXG4gKiB7QGxpbmsgQ29udmVydGVycy4ocmVjb3JkT2Y6d2l0aE9wdGlvbnMpIHwgQ29udmVydGVycy5yZWNvcmRPZihDb252ZXJ0ZXI8VD4sIEtleWVkQ29udmVydGVyT3B0aW9ucyl9LlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRPZjxULCBUQz11bmRlZmluZWQsIFRLIGV4dGVuZHMgc3RyaW5nPXN0cmluZz4oXG4gICAgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+LFxuICAgIG9wdGlvbjogJ2ZhaWwnfCdpZ25vcmUnfEtleWVkQ29udmVydGVyT3B0aW9uczxUSywgVEM+ID0gJ2ZhaWwnXG4pOiBDb252ZXJ0ZXI8UmVjb3JkPFRLLCBUPiwgVEM+IHtcbiAgICBjb25zdCBvcHRpb25zOiBLZXllZENvbnZlcnRlck9wdGlvbnM8VEssIFRDPiA9ICh0eXBlb2Ygb3B0aW9uID09PSAnc3RyaW5nJykgPyB7IG9uRXJyb3I6IG9wdGlvbiB9IDogeyBvbkVycm9yOiAnZmFpbCcsIC4uLm9wdGlvbiB9O1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxSZWNvcmQ8VEssIFQ+LCBUQz4sIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICBpZiAoKHR5cGVvZiBmcm9tICE9PSAnb2JqZWN0JykgfHwgKGZyb20gPT09IG51bGwpIHx8IEFycmF5LmlzQXJyYXkoZnJvbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKGBOb3QgYSBzdHJpbmcta2V5ZWQgb2JqZWN0OiAke0pTT04uc3RyaW5naWZ5KGZyb20pfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVjb3JkOiBSZWNvcmQ8c3RyaW5nLCBUPiA9IHt9O1xuICAgICAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG5cbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZnJvbSkge1xuICAgICAgICAgICAgaWYgKGlzS2V5T2Yoa2V5LCBmcm9tKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHdyaXRlS2V5UmVzdWx0ID0gb3B0aW9ucy5rZXlDb252ZXJ0ZXI/LmNvbnZlcnQoa2V5LCBjb250ZXh0KSA/PyBzdWNjZWVkKGtleSk7XG5cbiAgICAgICAgICAgICAgICB3cml0ZUtleVJlc3VsdC5vblN1Y2Nlc3MoKHdyaXRlS2V5KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb252ZXJ0ZXIuY29udmVydChmcm9tW2tleV0gYXMgdW5rbm93biwgY29udGV4dCkub25TdWNjZXNzKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkW3dyaXRlS2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1Y2NlZWQodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pLm9uRmFpbHVyZSgobWVzc2FnZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChtZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhaWwobWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gKGVycm9ycy5sZW5ndGggPT09IDApIHx8IChvcHRpb25zLm9uRXJyb3IgPT09ICdpZ25vcmUnKVxuICAgICAgICAgICAgPyBzdWNjZWVkKHJlY29yZClcbiAgICAgICAgICAgIDogZmFpbChlcnJvcnMuam9pbignXFxuJykpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIHRoZSBgc3RyaW5nYC1rZXllZCBwcm9wZXJ0aWVzXG4gKiB1c2luZyBhIHN1cHBsaWVkIHtAbGluayBDb252ZXJ0ZXIgfCBDb252ZXJ0ZXI8VD59IHRvIHByb2R1Y2UgYSBgTWFwPHN0cmluZywgVD5gLlxuICogQHJlbWFya3NcbiAqIFRoZSByZXN1bHRpbmcgY29udmVydGVyIGZhaWxzIGNvbnZlcnNpb24gaWYgYW55IGVsZW1lbnQgY2Fubm90IGJlIGNvbnZlcnRlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgLSB7QGxpbmsgQ29udmVydGVyfSB1c2VkIHRvIGNvbnZlcnQgZWFjaCBpdGVtIGluIHRoZSBzb3VyY2Ugb2JqZWN0LlxuICogQHJldHVybnMgQSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCByZXR1cm5zIGBNYXA8c3RyaW5nLCBUPmAuXG4gKiB7QGxhYmVsIGRlZmF1bHR9XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXBPZjxULCBUQyA9IHVuZGVmaW5lZCwgVEsgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+KGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPik6IENvbnZlcnRlcjxNYXA8VEssIFQ+LCBUQz47XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggY29udmVydHMgdGhlIGBzdHJpbmdgLWtleWVkIHByb3BlcnRpZXNcbiAqIHVzaW5nIGEgc3VwcGxpZWQge0BsaW5rIENvbnZlcnRlciB8IENvbnZlcnRlcjxUPn0gdG8gcHJvZHVjZSBhIGBNYXA8c3RyaW5nLCBUPmAgYW5kIG9wdGlvbmFsbHlcbiAqIHNwZWNpZmllZCBoYW5kbGluZyBvZiBlbGVtZW50cyB0aGF0IGNhbm5vdCBiZSBjb252ZXJ0ZWQuXG4gKiBAcmVtYXJrc1xuICogaWYgYG9uRXJyb3JgIGlzIGAnZmFpbCdgIChkZWZhdWx0KSwgdGhlbiB0aGUgZW50aXJlIGNvbnZlcnNpb24gZmFpbHMgaWYgYW55IGtleSBvciBlbGVtZW50XG4gKiBjYW5ub3QgYmUgY29udmVydGVkLiAgSWYgYG9uRXJyb3JgIGlzIGAnaWdub3JlJ2AsIGZhaWxpbmcgZWxlbWVudHMgYXJlIHNpbGVudGx5IGlnbm9yZWQuXG4gKiBAcGFyYW0gY29udmVydGVyIC0ge0BsaW5rIENvbnZlcnRlcn0gdXNlZCB0byBjb252ZXJ0IGVhY2ggaXRlbSBpbiB0aGUgc291cmNlIG9iamVjdC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggcmV0dXJucyBgTWFwPHN0cmluZywgVD5gLlxuICoge0BsYWJlbCB3aXRoT25FcnJvcn1cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcE9mPFQsIFRDID0gdW5kZWZpbmVkLCBUSyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4oXG4gICAgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+LFxuICAgIG9uRXJyb3I6ICdmYWlsJyB8ICdpZ25vcmUnXG4pOiBDb252ZXJ0ZXI8TWFwPFRLLCBUPiwgVEM+O1xuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIHRoZSBgc3RyaW5nYC1rZXllZCBwcm9wZXJ0aWVzXG4gKiB1c2luZyBhIHN1cHBsaWVkIHtAbGluayBDb252ZXJ0ZXIgfCBDb252ZXJ0ZXI8VD59IHRvIHByb2R1Y2UgYSBgTWFwPFRLLCBUPmAuXG4gKiBAcmVtYXJrc1xuICogSWYgcHJlc2VudCwgdGhlIHN1cHBsaWVkIHtAbGluayBDb252ZXJ0ZXJzLktleWVkQ29udmVydGVyT3B0aW9ucyB8IG9wdGlvbnN9IGNhbiBwcm92aWRlIGEgc3Ryb25nbHktdHlwZWRcbiAqIGNvbnZlcnRlciBmb3Iga2V5cyBhbmQvb3IgY29udHJvbCB0aGUgaGFuZGxpbmcgb2YgZWxlbWVudHMgdGhhdCBmYWlsIGNvbnZlcnNpb24uXG4gKiBAcGFyYW0gY29udmVydGVyIC0ge0BsaW5rIENvbnZlcnRlcn0gdXNlZCB0byBjb252ZXJ0IGVhY2ggaXRlbSBpbiB0aGUgc291cmNlIG9iamVjdC5cbiAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwge0BsaW5rIENvbnZlcnRlcnMuS2V5ZWRDb252ZXJ0ZXJPcHRpb25zIHwgS2V5ZWRDb252ZXJ0ZXJPcHRpb25zPFRLLCBUQz59IHdoaWNoXG4gKiBzdXBwbGllcyBhIGtleSBjb252ZXJ0ZXIgYW5kL29yIGVycm9yLWhhbmRsaW5nIG9wdGlvbnMuXG4gKiBAcmV0dXJucyBBIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIHJldHVybnMgYE1hcDxUSywgVD5gLlxuICoge0BsYWJlbCB3aXRoT3B0aW9uc31cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcE9mPFQsIFRDID0gdW5kZWZpbmVkLCBUSyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4oXG4gICAgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+LFxuICAgIG9wdGlvbnM6IEtleWVkQ29udmVydGVyT3B0aW9uczxUSywgVEM+XG4pOiBDb252ZXJ0ZXI8TWFwPFRLLCBUPiwgVEM+O1xuXG4vKipcbiAqIENvbmNyZXRlIGltcGxlbWVudGF0aW9uIG9mIHtAbGluayBDb252ZXJ0ZXJzLihtYXBPZjpkZWZhdWx0KSB8IENvbnZlcnRlcnMubWFwT2YoQ29udmVydGVyPFQ+KX0sXG4gKiB7QGxpbmsgQ29udmVydGVycy4obWFwT2Y6d2l0aE9uRXJyb3IpIHwgQ29udmVydGVycy5tYXBPZihDb252ZXJ0ZXI8VD4sICdmYWlsJ3wnaWdub3JlJyl9LCBhbmRcbiAqIHtAbGluayBDb252ZXJ0ZXJzLihtYXBPZjp3aXRoT3B0aW9ucykgfCBDb252ZXJ0ZXJzLm1hcE9mKENvbnZlcnRlcjxUPiwgS2V5ZWRDb252ZXJ0ZXJPcHRpb25zKX0uXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcE9mPFQsIFRDID0gdW5kZWZpbmVkLCBUSyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4oXG4gICAgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+LFxuICAgIG9wdGlvbjogJ2ZhaWwnIHwgJ2lnbm9yZScgfCBLZXllZENvbnZlcnRlck9wdGlvbnM8VEssIFRDPiA9ICdmYWlsJ1xuKTogQ29udmVydGVyPE1hcDxUSywgVD4sIFRDPiB7XG4gICAgY29uc3Qgb3B0aW9ucyA9ICh0eXBlb2Ygb3B0aW9uID09PSAnc3RyaW5nJykgPyB7IG9uRXJyb3I6IG9wdGlvbiB9IDogeyBvbkVycm9yOiAnZmFpbCcsIC4uLm9wdGlvbiB9O1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxNYXA8VEssIFQ+LCBUQz4sIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICBpZiAoKHR5cGVvZiBmcm9tICE9PSAnb2JqZWN0JykgfHwgKGZyb20gPT09IG51bGwpIHx8IEFycmF5LmlzQXJyYXkoZnJvbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKGBOb3QgYSBzdHJpbmcta2V5ZWQgb2JqZWN0OiAke0pTT04uc3RyaW5naWZ5KGZyb20pfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbWFwID0gbmV3IE1hcDxUSywgVD4oKTtcbiAgICAgICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGZyb20pIHtcbiAgICAgICAgICAgIGlmIChpc0tleU9mKGtleSwgZnJvbSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB3cml0ZUtleVJlc3VsdCA9IG9wdGlvbnMua2V5Q29udmVydGVyPy5jb252ZXJ0KGtleSwgY29udGV4dCkgPz8gc3VjY2VlZChrZXkpO1xuXG4gICAgICAgICAgICAgICAgd3JpdGVLZXlSZXN1bHQub25TdWNjZXNzKCh3cml0ZUtleSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udmVydGVyLmNvbnZlcnQoZnJvbVtrZXldIGFzIHVua25vd24sIGNvbnRleHQpLm9uU3VjY2VzcygodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcC5zZXQod3JpdGVLZXksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWNjZWVkKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KS5vbkZhaWx1cmUoKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JzLnB1c2gobWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWlsKG1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChlcnJvcnMubGVuZ3RoID09PSAwKSB8fCAob3B0aW9ucy5vbkVycm9yID09PSAnaWdub3JlJylcbiAgICAgICAgICAgID8gc3VjY2VlZChtYXApXG4gICAgICAgICAgICA6IGZhaWwoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlICBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIHZhbGlkYXRlcyB0aGF0IGEgc3VwcGxpZWQgdmFsdWUgaXNcbiAqIG9mIGEgdHlwZSB2YWxpZGF0ZWQgYnkgYSBzdXBwbGllZCB2YWxpZGF0b3IgZnVuY3Rpb24gYW5kIHJldHVybnMgaXQuXG4gKiBAcmVtYXJrc1xuICogSWYgYHZhbGlkYXRvcmAgc3VjY2VlZHMsIHRoaXMge0BsaW5rIENvbnZlcnRlcn0gcmV0dXJucyB7QGxpbmsgU3VjY2Vzc30gd2l0aCB0aGUgc3VwcGxpZWRcbiAqIHZhbHVlIG9mIGBmcm9tYCBjb2VyY2VkIHRvIHR5cGUgYDxUPmAuICBSZXR1cm5zIGEge0BsaW5rIEZhaWx1cmV9IHdpdGggYWRkaXRpb25hbFxuICogaW5mb3JtYXRpb24gb3RoZXJ3aXNlLlxuICogQHBhcmFtIHZhbGlkYXRvciAtIEEgdmFsaWRhdG9yIGZ1bmN0aW9uIHRvIGRldGVybWluZSBpZiB0aGUgY29udmVydGVkIHZhbHVlIGlzIHZhbGlkLlxuICogQHBhcmFtIGRlc2NyaXB0aW9uIC0gQSBkZXNjcmlwdGlvbiBvZiB0aGUgdmFsaWRhdGVkIHR5cGUgZm9yIHVzZSBpbiBlcnJvciBtZXNzYWdlcy5cbiAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBDb252ZXJ0ZXIgfCBDb252ZXJ0ZXI8VD59IHdoaWNoIGFwcGxpZXMgdGhlIHN1cHBsaWVkIHZhbGlkYXRpb24uXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVdpdGg8VCwgVEM9dW5kZWZpbmVkPih2YWxpZGF0b3I6IChmcm9tOiB1bmtub3duKSA9PiBmcm9tIGlzIFQsIGRlc2NyaXB0aW9uPzogc3RyaW5nKTogQ29udmVydGVyPFQsIFRDPiB7XG4gICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyKChmcm9tOiB1bmtub3duLCBfc2VsZjogQ29udmVydGVyPFQsIFRDPiwgX2NvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICBpZiAodmFsaWRhdG9yKGZyb20pKSB7XG4gICAgICAgICAgICByZXR1cm4gc3VjY2VlZChmcm9tKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFpbChgJHtKU09OLnN0cmluZ2lmeShmcm9tKX06IGludmFsaWQgJHtkZXNjcmlwdGlvbiA/PyAndmFsdWUnfWApO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGV4dHJhY3RzIGFuZCBjb252ZXJ0cyBhbiBlbGVtZW50IGZyb20gYW4gYXJyYXkuXG4gKiBAcmVtYXJrc1xuICogVGhlIHJldHVybmVkIHtAbGluayBDb252ZXJ0ZXJ9IHJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggdGhlIGNvbnZlcnRlZCB2YWx1ZSBpZiB0aGUgZWxlbWVudCBleGlzdHNcbiAqIGluIHRoZSBzdXBwbGllZCBhcnJheSBhbmQgY2FuIGJlIGNvbnZlcnRlZC4gUmV0dXJucyB7QGxpbmsgRmFpbHVyZX0gd2l0aCBhbiBlcnJvciBtZXNzYWdlIG90aGVyd2lzZS5cbiAqIEBwYXJhbSBpbmRleCAtIFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byBiZSBleHRyYWN0ZWQuXG4gKiBAcGFyYW0gY29udmVydGVyIC0gQSB7QGxpbmsgQ29udmVydGVyfSB1c2VkIHRvIGNvbnZlcnQgdGhlIGV4dHJhY3RlZCBlbGVtZW50LlxuICogQHJldHVybnMgQSB7QGxpbmsgQ29udmVydGVyIHwgQ29udmVydGVyPFQ+fSB3aGljaCBleHRyYWN0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgZnJvbSBhbiBhcnJheS5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVsZW1lbnQ8VCwgVEM9dW5kZWZpbmVkPihpbmRleDogbnVtYmVyLCBjb252ZXJ0ZXI6IENvbnZlcnRlcjxULCBUQz4pOiBDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VCwgVEM+LCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYCR7aW5kZXh9OiBjYW5ub3QgY29udmVydCBmb3IgYSBuZWdhdGl2ZSBlbGVtZW50IGluZGV4YCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIUFycmF5LmlzQXJyYXkoZnJvbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKCdlbGVtZW50IGNvbnZlcnRlcjogc291cmNlIGlzIG5vdCBhbiBhcnJheScpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGluZGV4ID49IGZyb20ubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFpbChgJHtpbmRleH06IGVsZW1lbnQgY29udmVydGVyIGluZGV4IG91dCBvZiByYW5nZSAoMC4uJHtmcm9tLmxlbmd0aCAtIDF9KWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb252ZXJ0ZXIuY29udmVydChmcm9tW2luZGV4XSwgY29udGV4dCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggZXh0cmFjdHMgYW5kIGNvbnZlcnRzIGFuIG9wdGlvbmFsIGVsZW1lbnQgZnJvbSBhbiBhcnJheS5cbiAqIEByZW1hcmtzXG4gKiBUaGUgcmVzdWx0aW5nIHtAbGluayBDb252ZXJ0ZXJ9IHJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggdGhlIGNvbnZlcnRlZCB2YWx1ZSBpZiB0aGUgZWxlbWVudCBleGlzdHNcbiAqIGluIHRoZSBzdXBwbGllZCBhcnJheSBhbmQgY2FuIGJlIGNvbnZlcnRlZC4gUmV0dXJucyB7QGxpbmsgU3VjY2Vzc30gd2l0aCB2YWx1ZSBgdW5kZWZpbmVkYCBpZiB0aGUgcGFyYW1ldGVyXG4gKiBpcyBhbiBhcnJheSBidXQgdGhlIGluZGV4IGlzIG91dCBvZiByYW5nZS4gUmV0dXJucyB7QGxpbmsgRmFpbHVyZX0gd2l0aCBhIG1lc3NhZ2UgaWYgdGhlIHN1cHBsaWVkIHBhcmFtZXRlclxuICogaXMgbm90IGFuIGFycmF5LCBpZiB0aGUgcmVxdWVzdGVkIGluZGV4IGlzIG5lZ2F0aXZlLCBvciBpZiB0aGUgZWxlbWVudCBjYW5ub3QgYmUgY29udmVydGVkLlxuICogQHBhcmFtIGluZGV4IC0gVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIGJlIGV4dHJhY3RlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgLSBBIHtAbGluayBDb252ZXJ0ZXJ9IHVzZWQgdG8gY29udmVydCB0aGUgZXh0cmFjdGVkIGVsZW1lbnQuXG4gKiBAcmV0dXJucyBBIHtAbGluayBDb252ZXJ0ZXIgfCBDb252ZXJ0ZXI8VD59IHdoaWNoIGV4dHJhY3RzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBmcm9tIGFuIGFycmF5LlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gb3B0aW9uYWxFbGVtZW50PFQsIFRDPXVuZGVmaW5lZD4oaW5kZXg6IG51bWJlciwgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+KTogQ29udmVydGVyPFR8dW5kZWZpbmVkLCBUQz4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxUfHVuZGVmaW5lZCwgVEM+LCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYCR7aW5kZXh9OiBjYW5ub3QgY29udmVydCBmb3IgYSBuZWdhdGl2ZSBlbGVtZW50IGluZGV4YCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIUFycmF5LmlzQXJyYXkoZnJvbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKCdlbGVtZW50IGNvbnZlcnRlcjogc291cmNlIGlzIG5vdCBhbiBhcnJheScpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGluZGV4ID49IGZyb20ubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gc3VjY2VlZCh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb252ZXJ0ZXIuY29udmVydChmcm9tW2luZGV4XSwgY29udGV4dCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggZXh0cmFjdHMgYW5kIGNvbnZlcnQgYSBwcm9wZXJ0eSBzcGVjaWZpZWRcbiAqIGJ5IG5hbWUgZnJvbSBhbiBvYmplY3QuXG4gKiBAcmVtYXJrc1xuICogVGhlIHJlc3VsdGluZyB7QGxpbmsgQ29udmVydGVyfSByZXR1cm5zIHtAbGluayBTdWNjZXNzfSB3aXRoIHRoZSBjb252ZXJ0ZWQgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmdcbiAqIG9iamVjdCBwcm9wZXJ0eSBpZiB0aGUgZmllbGQgZXhpc3RzIGFuZCBjYW4gYmUgY29udmVydGVkLiBSZXR1cm5zIHtAbGluayBGYWlsdXJlfSB3aXRoIGFuIGVycm9yIG1lc3NhZ2VcbiAqIG90aGVyd2lzZS5cbiAqIEBwYXJhbSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGJlIGV4dHJhY3RlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgLSB7QGxpbmsgQ29udmVydGVyfSB1c2VkIHRvIGNvbnZlcnQgdGhlIGV4dHJhY3RlZCBmaWVsZC5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpZWxkPFQsIFRDPXVuZGVmaW5lZD4obmFtZTogc3RyaW5nLCBjb252ZXJ0ZXI6IENvbnZlcnRlcjxULCBUQz4pOiBDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VCwgVEM+LCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBmcm9tID09PSAnb2JqZWN0JyAmJiAoIUFycmF5LmlzQXJyYXkoZnJvbSkpICYmIGZyb20gIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChpc0tleU9mKG5hbWUsIGZyb20pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnZlcnRlci5jb252ZXJ0KGZyb21bbmFtZV0sIGNvbnRleHQpLm9uRmFpbHVyZSgobWVzc2FnZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFpbChgRmllbGQgJHtuYW1lfTogJHttZXNzYWdlfWApO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYEZpZWxkICR7bmFtZX0gbm90IGZvdW5kIGluOiAke0pTT04uc3RyaW5naWZ5KGZyb20pfWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWlsKGBDYW5ub3QgY29udmVydCBmaWVsZCBcIiR7bmFtZX1cIiBmcm9tIG5vbi1vYmplY3QgJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBIGhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBleHRyYWN0cyBhbmQgY29udmVydCBhIHByb3BlcnR5IHNwZWNpZmllZFxuICogYnkgbmFtZSBmcm9tIGFuIG9iamVjdC5cbiAqIEByZW1hcmtzXG4gKiBUaGUgcmVzdWx0aW5nIHtAbGluayBDb252ZXJ0ZXJ9IHJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggdGhlIGNvbnZlcnRlZCB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZ1xuICogb2JqZWN0IHByb3BlcnR5IGlmIHRoZSBmaWVsZCBleGlzdHMgYW5kIGNhbiBiZSBjb252ZXJ0ZWQuIFJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggdmFsdWUgYHVuZGVmaW5lZGBcbiAqIGlmIHRoZSBzdXBwbGllZCBwYXJhbWV0ZXIgaXMgYW4gb2JqZWN0IGJ1dCB0aGUgbmFtZWQgZmllbGQgaXMgbm90IHByZXNlbnQuICBSZXR1cm5zIHtAbGluayBGYWlsdXJlfSB3aXRoXG4gKiBhbiBlcnJvciBtZXNzYWdlIG90aGVyd2lzZS5cbiAqIEBwYXJhbSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGJlIGV4dHJhY3RlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgLSB7QGxpbmsgQ29udmVydGVyfSB1c2VkIHRvIGNvbnZlcnQgdGhlIGV4dHJhY3RlZCBmaWVsZC5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9wdGlvbmFsRmllbGQ8VCwgVEM9dW5kZWZpbmVkPihuYW1lOiBzdHJpbmcsIGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPik6IENvbnZlcnRlcjxUfHVuZGVmaW5lZCwgVEM+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VHx1bmRlZmluZWQsIFRDPiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgZnJvbSA9PT0gJ29iamVjdCcgJiYgKCFBcnJheS5pc0FycmF5KGZyb20pKSAmJiBmcm9tICE9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoaXNLZXlPZihuYW1lLCBmcm9tKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnZlcnRlci5jb252ZXJ0KGZyb21bbmFtZV0sIGNvbnRleHQpLm9uRmFpbHVyZSgobWVzc2FnZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFpbChgJHtuYW1lfTogJHttZXNzYWdlfWApO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgLy8gaWYgY29udmVyc2lvbiB3YXMgc3VjY2Vzc2Z1bCBvciBpbnB1dCB3YXMgdW5kZWZpbmVkIHdlXG4gICAgICAgICAgICAgICAgLy8gc3VjY2VlZCB3aXRoICd1bmRlZmluZWQnLCBidXQgd2UgcHJvcGFnYXRlIGFjdHVhbFxuICAgICAgICAgICAgICAgIC8vIGZhaWx1cmVzLlxuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuaXNTdWNjZXNzKCkgfHwgKGZyb21bbmFtZV0gIT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc3VjY2VlZCh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWlsKGBDYW5ub3QgY29udmVydCBmaWVsZCBcIiR7bmFtZX1cIiBmcm9tIG5vbi1vYmplY3QgJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKTtcbiAgICB9LCB1bmRlZmluZWQsIHsgaXNPcHRpb25hbDogdHJ1ZSB9KTtcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBhbiB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIgfCBPYmplY3RDb252ZXJ0ZXJ9LlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgaW50ZXJmYWNlIE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD4ge1xuICAgIC8qKlxuICAgICAqIElmIHByZXNlbnQsIGxpc3RzIG9wdGlvbmFsIGZpZWxkcy4gTWlzc2luZyBub24tb3B0aW9uYWwgZmllbGRzIGNhdXNlIGFuIGVycm9yLlxuICAgICAqL1xuICAgIG9wdGlvbmFsRmllbGRzPzogKGtleW9mIFQpW107XG4gICAgLyoqXG4gICAgICogSWYgdHJ1ZSwgdW5yZWNvZ25pemVkIGZpZWxkcyB5aWVsZCBhbiBlcnJvci4gIElmIGZhbHNlIG9yIHVuZGVmaW5lZCAoZGVmYXVsdCksXG4gICAgICogdW5yZWNvZ25pemVkIGZpZWxkcyBhcmUgaWdub3JlZC5cbiAgICAgKi9cbiAgICBzdHJpY3Q/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFBlci1wcm9wZXJ0eSBjb252ZXJ0ZXJzIGZvciBlYWNoIG9mIHRoZSBwcm9wZXJ0aWVzIGluIHR5cGUgVC5cbiAqIEByZW1hcmtzXG4gKiBVc2VkIHRvIGNvbnN0cnVjdCBhIHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlciB8IE9iamVjdENvbnZlcnRlcn1cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IHR5cGUgRmllbGRDb252ZXJ0ZXJzPFQsIFRDPXVua25vd24+ID0geyBbIGtleSBpbiBrZXlvZiBUIF06IENvbnZlcnRlcjxUW2tleV0sIFRDPiB9O1xuXG4vKipcbiAqIEEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggY29udmVydHMgYW4gb2JqZWN0IG9mIHR5cGUgYDxUPmAgd2l0aG91dCBjaGFuZ2luZyBzaGFwZSwgZ2l2ZW5cbiAqIGEge0BsaW5rIENvbnZlcnRlcnMuRmllbGRDb252ZXJ0ZXJzIHwgRmllbGRDb252ZXJ0ZXJzPFQ+fSBmb3IgdGhlIGZpZWxkcyBpbiB0aGUgb2JqZWN0LlxuICogQHJlbWFya3NcbiAqIEJ5IGRlZmF1bHQsIGlmIGFsbCBvZiB0aGUgcmVxdWlyZWQgZmllbGRzIGV4aXN0IGFuZCBjYW4gYmUgY29udmVydGVkLCByZXR1cm5zIGEgbmV3IG9iamVjdCB3aXRoXG4gKiB0aGUgY29udmVydGVkIHZhbHVlcyB1bmRlciB0aGUgb3JpZ2luYWwga2V5IG5hbWVzLiAgSWYgYW55IHJlcXVpcmVkIGZpZWxkcyBkbyBub3QgZXhpc3Qgb3IgY2Fubm90XG4gKiBiZSBjb252ZXJ0ZWQsIHRoZSBlbnRpcmUgY29udmVyc2lvbiBmYWlscy4gU2VlIHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlck9wdGlvbnMgfCBPYmplY3RDb252ZXJ0ZXJPcHRpb25zfVxuICogZm9yIG90aGVyIGNvbnZlcnNpb24gb3B0aW9ucy5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNsYXNzIE9iamVjdENvbnZlcnRlcjxULCBUQz11bmtub3duPiBleHRlbmRzIEJhc2VDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICAvKipcbiAgICAgKiBGaWVsZHMgY29udmVydGVkIGJ5IHRoaXMge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyIHwgT2JqZWN0Q29udmVydGVyfS5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgZmllbGRzOiBGaWVsZENvbnZlcnRlcnM8VD47XG4gICAgLyoqXG4gICAgICogT3B0aW9ucyB1c2VkIHRvIGluaXRpYWxpemUgdGhpcyB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIgfCBPYmplY3RDb252ZXJ0ZXJ9LlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBvcHRpb25zOiBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+O1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIgfCBPYmplY3RDb252ZXJ0ZXI8VD59IHVzaW5nIG9wdGlvbnNcbiAgICAgKiBzdXBwbGllZCBpbiBhIHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlck9wdGlvbnMgfCBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+fS5cbiAgICAgKiBAcGFyYW0gZmllbGRzIC0gQSB7QGxpbmsgQ29udmVydGVycy5GaWVsZENvbnZlcnRlcnMgfCBGaWVsZENvbnZlcnRlcnM8VD59IGNvbnRhaW5pbmdcbiAgICAgKiBhIHtAbGluayBDb252ZXJ0ZXJ9IGZvciBlYWNoIGZpZWxkXG4gICAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBAc2VlIE9iamVjdENvbnZlcnRlck9wdGlvbnMgdG8gY29uZmlndXJlIHRoZSBjb252ZXJzaW9uXG4gICAgICoge0BsYWJlbCB3aXRoT3B0aW9uc31cbiAgICAgKi9cbiAgICBwdWJsaWMgY29uc3RydWN0b3IoZmllbGRzOiBGaWVsZENvbnZlcnRlcnM8VCwgVEM+LCBvcHRpb25zPzogT2JqZWN0Q29udmVydGVyT3B0aW9uczxUPilcblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyIHwgT2JqZWN0Q29udmVydGVyPFQ+fSB3aXRoIG9wdGlvbmFsXG4gICAgICogcHJvcGVydGllcyBzcGVjaWZpZWQgYXMgYW4gYXJyYXkgb2YgYGtleW9mIFRgLlxuICAgICAqIEBwYXJhbSBmaWVsZHMgLSBBIHtAbGluayBDb252ZXJ0ZXJzLkZpZWxkQ29udmVydGVycyB8IEZpZWxkQ29udmVydGVyczxUPn0gY29udGFpbmluZ1xuICAgICAqIGEge0BsaW5rIENvbnZlcnRlcn0gZm9yIGVhY2ggZmllbGQuXG4gICAgICogQHBhcmFtIG9wdGlvbmFsIC0gQW4gYXJyYXkgb2YgYGtleW9mIFRgIGxpc3RpbmcgZmllbGRzIHRoYXQgYXJlIG5vdCByZXF1aXJlZC5cbiAgICAgKiB7QGxhYmVsIHdpdGhLZXlzfVxuICAgICAqL1xuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihmaWVsZHM6IEZpZWxkQ29udmVydGVyczxULCBUQz4sIG9wdGlvbmFsPzogKGtleW9mIFQpW10pO1xuICAgIC8qKlxuICAgICAqIENvbmNyZXRlIGltcGxlbWVudGF0aW9uIG9mIHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlci4oY29uc3RydWN0b3I6d2l0aE9wdGlvbnMpfVxuICAgICAqIGFuZCB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIuKGNvbnN0cnVjdG9yOndpdGhLZXlzKX0uXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKGZpZWxkczogRmllbGRDb252ZXJ0ZXJzPFQsIFRDPiwgb3B0PzogT2JqZWN0Q29udmVydGVyT3B0aW9uczxUPnwoa2V5b2YgVClbXSkge1xuICAgICAgICBzdXBlcigoZnJvbTogdW5rbm93biwgX3NlbGYsIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICAgICAgLy8gZXNsaW50IGJ1ZyB0aGlua3Mga2V5IGlzIHVzZWQgYmVmb3JlIGRlZmluZWRcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11c2UtYmVmb3JlLWRlZmluZVxuICAgICAgICAgICAgY29uc3QgY29udmVydGVkID0ge30gYXMgeyBba2V5IGluIGtleW9mIFRdOiBUW2tleV0gfTtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIGZpZWxkcykge1xuICAgICAgICAgICAgICAgIGlmIChmaWVsZHNba2V5XSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpc09wdGlvbmFsID0gKGZpZWxkc1trZXldLmlzT3B0aW9uYWwgfHwgdGhpcy5vcHRpb25zLm9wdGlvbmFsRmllbGRzPy5pbmNsdWRlcyhrZXkpKSA/PyBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gaXNPcHRpb25hbFxuICAgICAgICAgICAgICAgICAgICAgICAgPyBvcHRpb25hbEZpZWxkKGtleSwgZmllbGRzW2tleV0pLmNvbnZlcnQoZnJvbSwgY29udGV4dClcbiAgICAgICAgICAgICAgICAgICAgICAgIDogZmllbGQoa2V5LCBmaWVsZHNba2V5XSkuY29udmVydChmcm9tLCBjb250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSAmJiAocmVzdWx0LnZhbHVlICE9PSB1bmRlZmluZWQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ZWRba2V5XSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChyZXN1bHQuaXNGYWlsdXJlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ycy5wdXNoKHJlc3VsdC5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zdHJpY3QgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoKHR5cGVvZiBmcm9tID09PSAnb2JqZWN0JykgJiYgKCFBcnJheS5pc0FycmF5KGZyb20pKSkge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBmcm9tKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZnJvbS5oYXNPd25Qcm9wZXJ0eShrZXkpICYmICghaXNLZXlPZihrZXksIGZpZWxkcykgfHwgKGZpZWxkc1trZXldID09PSB1bmRlZmluZWQpKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ycy5wdXNoKGAke2tleX06IHVuZXhwZWN0ZWQgcHJvcGVydHkgaW4gc291cmNlIG9iamVjdGApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcnMucHVzaCgnc291cmNlIGlzIG5vdCBhbiBvYmplY3QnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gKGVycm9ycy5sZW5ndGggPT09IDApID8gc3VjY2VlZChjb252ZXJ0ZWQpIDogZmFpbChlcnJvcnMuam9pbignXFxuJykpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmZpZWxkcyA9IGZpZWxkcztcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkob3B0KSkge1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zID0geyBvcHRpb25hbEZpZWxkczogb3B0IH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHQgPz8ge307XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlciB8IE9iamVjdENvbnZlcnRlcn0gZGVyaXZlZCBmcm9tIHRoaXMgb25lIGJ1dCB3aXRoXG4gICAgICogbmV3IG9wdGlvbmFsIHByb3BlcnRpZXMgYXMgc3BlY2lmaWVkIGJ5IGEgc3VwcGxpZWQge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyT3B0aW9ucyB8IE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD59LlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gVGhlIHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlck9wdGlvbnMgfCBvcHRpb25zfSB0byBiZSBhcHBsaWVkIHRvIHRoZSBuZXdcbiAgICAgKiBjb252ZXJ0ZXIuXG4gICAgICogQHJldHVybnMgQSBuZXcge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyIHwgT2JqZWN0Q29udmVydGVyfSB3aXRoIHRoZSBhZGRpdGlvbmFsIG9wdGlvbmFsIHNvdXJjZSBwcm9wZXJ0aWVzLlxuICAgICAqIHtAbGFiZWwgd2l0aE9wdGlvbnN9XG4gICAgICovXG4gICAgcHVibGljIHBhcnRpYWwob3B0aW9uczogT2JqZWN0Q29udmVydGVyT3B0aW9uczxUPik6IE9iamVjdENvbnZlcnRlcjxQYXJ0aWFsPFQ+LCBUQz47XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlciB8IE9iamVjdENvbnZlcnRlcn0gZGVyaXZlZCBmcm9tIHRoaXMgb25lIGJ1dCB3aXRoXG4gICAgICogbmV3IG9wdGlvbmFsIHByb3BlcnRpZXMgYXMgc3BlY2lmaWVkIGJ5IGEgc3VwcGxpZWQgYXJyYXkgb2YgYGtleW9mIFRgLlxuICAgICAqIEBwYXJhbSBvcHRpb25hbCAtIFRoZSBrZXlzIG9mIHRoZSBzb3VyY2Ugb2JqZWN0IHByb3BlcnRpZXMgdG8gYmUgbWFkZSBvcHRpb25hbC5cbiAgICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIgfCBPYmplY3RDb252ZXJ0ZXJ9IHdpdGggdGhlIGFkZGl0aW9uYWwgb3B0aW9uYWwgc291cmNlXG4gICAgICogcHJvcGVydGllcy5cbiAgICAgKiB7QGxhYmVsIHdpdGhLZXlzfVxuICAgICAqL1xuICAgIHB1YmxpYyBwYXJ0aWFsKG9wdGlvbmFsPzogKGtleW9mIFQpW10pOiBPYmplY3RDb252ZXJ0ZXI8UGFydGlhbDxUPiwgVEM+O1xuICAgIC8qKlxuICAgICAqIENvbmNyZXRlIGltcGxlbWVudGF0aW9uIG9mXG4gICAgICoge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyLihwYXJ0aWFsOndpdGhPcHRpb25zKSB8IE9iamVjdENvbnZlcnRlci5wYXJ0aWFsKE9iamVjdENvbnZlcnRlck9wdGlvbnMpfSBhbmRcbiAgICAgKiB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIuKHBhcnRpYWw6d2l0aEtleXMpIHwgT2JqZWN0Q29udmVydGVyLnBhcnRpYWwoKGtleW9mIFQpW119LlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBwYXJ0aWFsKG9wdD86IE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD58KGtleW9mIFQpW10pOiBPYmplY3RDb252ZXJ0ZXI8UGFydGlhbDxUPiwgVEM+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RDb252ZXJ0ZXI8UGFydGlhbDxUPiwgVEM+KHRoaXMuZmllbGRzIGFzIEZpZWxkQ29udmVydGVyczxQYXJ0aWFsPFQ+LCBUQz4sIG9wdCBhcyBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFBhcnRpYWw8VD4+KS5fd2l0aCh0aGlzLl90cmFpdHMoKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIgfCBPYmplY3RDb252ZXJ0ZXJ9IGRlcml2ZWQgZnJvbSB0aGlzIG9uZSBidXQgd2l0aFxuICAgICAqIG5ldyBvcHRpb25hbCBwcm9wZXJ0aWVzIGFzIHNwZWNpZmllZCBieSBhIHN1cHBsaWVkIGFycmF5IG9mIGBrZXlvZiBUYC5cbiAgICAgKiBAcGFyYW0gYWRkT3B0aW9uYWxQcm9wZXJ0aWVzIC0gVGhlIGtleXMgdG8gYmUgbWFkZSBvcHRpb25hbC5cbiAgICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIgfCBPYmplY3RDb252ZXJ0ZXJ9IHdpdGggdGhlIGFkZGl0aW9uYWwgb3B0aW9uYWwgc291cmNlXG4gICAgICogcHJvcGVydGllcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgYWRkUGFydGlhbChhZGRPcHRpb25hbFByb3BlcnRpZXM6IChrZXlvZiBUKVtdKTogT2JqZWN0Q29udmVydGVyPFBhcnRpYWw8VD4sIFRDPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcnRpYWwoWy4uLnRoaXMub3B0aW9ucy5vcHRpb25hbEZpZWxkcyA/PyBbXSwgLi4uYWRkT3B0aW9uYWxQcm9wZXJ0aWVzXSkuX3dpdGgodGhpcy5fdHJhaXRzKCkpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyIHwgT2JqZWN0Q29udmVydGVyPFQ+fSB3aGljaCBjb252ZXJ0cyBhbiBvYmplY3RcbiAqIHdpdGhvdXQgY2hhbmdpbmcgc2hhcGUsIGdpdmVuIGEge0BsaW5rIENvbnZlcnRlcnMuRmllbGRDb252ZXJ0ZXJzIHwgRmllbGRDb252ZXJ0ZXJzPFQ+fSBhbmQgYW4gb3B0aW9uYWxcbiAqIHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlck9wdGlvbnMgfCBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+fSB0byBmdXJ0aGVyIHJlZmluZSBjb252ZXJzaW9uIGJlaGF2aW9yLlxuICogQHJlbWFya3NcbiAqIEJ5IGRlZmF1bHQsIGlmIGFsbCBvZiB0aGUgcmVxdWVzdGVkIGZpZWxkcyBleGlzdCBhbmQgY2FuIGJlIGNvbnZlcnRlZCwgcmV0dXJucyB7QGxpbmsgU3VjY2Vzc31cbiAqIHdpdGggYSBuZXcgb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIGNvbnZlcnRlZCB2YWx1ZXMgdW5kZXIgdGhlIG9yaWdpbmFsIGtleSBuYW1lcy4gIElmIGFueSByZXF1aXJlZCBwcm9wZXJ0aWVzXG4gKiBkbyBub3QgZXhpc3Qgb3IgY2Fubm90IGJlIGNvbnZlcnRlZCwgdGhlIGVudGlyZSBjb252ZXJzaW9uIGZhaWxzLCByZXR1cm5pbmcge0BsaW5rIEZhaWx1cmV9IHdpdGggYWRkaXRpb25hbFxuICogZXJyb3IgaW5mb3JtYXRpb24uXG4gKlxuICogRmllbGRzIHRoYXQgc3VjY2VlZCBidXQgY29udmVydCB0byB1bmRlZmluZWQgYXJlIG9taXR0ZWQgZnJvbSB0aGUgcmVzdWx0IG9iamVjdCBidXQgZG8gbm90XG4gKiBmYWlsIHRoZSBjb252ZXJzaW9uLlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSBBbiB7QGxpbmsgQ29udmVydGVycy5GaWVsZENvbnZlcnRlcnMgfCBGaWVsZENvbnZlcnRlcnM8VD59IGRlZmluaW5nIHRoZSBzaGFwZSBvZiB0aGVcbiAqIHNvdXJjZSBvYmplY3QgYW5kIHtAbGluayBDb252ZXJ0ZXIgfCBjb252ZXJ0ZXJzfSB0byBiZSBhcHBsaWVkIHRvIGVhY2ggcHJvcGVydGllcy5cbiAqIEBwYXJhbSBvcHRpb25zIC0gQW4ge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyT3B0aW9ucyB8IE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD59IGNvbnRhaW5pbmcgb3B0aW9uc1xuICogZm9yIHRoZSBvYmplY3QgY29udmVydGVyLlxuICogQHJldHVybnMgQSBuZXcge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyIHwgT2JqZWN0Q29udmVydGVyfSB3aGljaCBhcHBsaWVzIHRoZSBzcGVjaWZpZWQgY29udmVyc2lvbnMuXG4gKiB7QGxhYmVsIHdpdGhPcHRpb25zfVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gb2JqZWN0PFQ+KHByb3BlcnRpZXM6IEZpZWxkQ29udmVydGVyczxUPiwgb3B0aW9ucz86IE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD4pOiBPYmplY3RDb252ZXJ0ZXI8VD47XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlciB8IE9iamVjdENvbnZlcnRlcjxUPn0gd2hpY2ggY29udmVydHMgYW4gb2JqZWN0XG4gKiB3aXRob3V0IGNoYW5naW5nIHNoYXBlLCBnaXZlbiBhIHtAbGluayBDb252ZXJ0ZXJzLkZpZWxkQ29udmVydGVycyB8IEZpZWxkQ29udmVydGVyczxUPn0gYW5kIGEgc2V0IG9mXG4gKiBvcHRpb25hbCBwcm9wZXJ0aWVzLlxuICogQHJlbWFya3NcbiAqIEJ5IGRlZmF1bHQsIGlmIGFsbCBvZiB0aGUgcmVxdWVzdGVkIGZpZWxkcyBleGlzdCBhbmQgY2FuIGJlIGNvbnZlcnRlZCwgcmV0dXJucyB7QGxpbmsgU3VjY2Vzc31cbiAqIHdpdGggYSBuZXcgb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIGNvbnZlcnRlZCB2YWx1ZXMgdW5kZXIgdGhlIG9yaWdpbmFsIGtleSBuYW1lcy4gIElmIGFueSByZXF1aXJlZCBwcm9wZXJ0aWVzXG4gKiBkbyBub3QgZXhpc3Qgb3IgY2Fubm90IGJlIGNvbnZlcnRlZCwgdGhlIGVudGlyZSBjb252ZXJzaW9uIGZhaWxzLCByZXR1cm5pbmcge0BsaW5rIEZhaWx1cmV9IHdpdGggYWRkaXRpb25hbFxuICogZXJyb3IgaW5mb3JtYXRpb24uXG4gKlxuICogRmllbGRzIHRoYXQgc3VjY2VlZCBidXQgY29udmVydCB0byB1bmRlZmluZWQgYXJlIG9taXR0ZWQgZnJvbSB0aGUgcmVzdWx0IG9iamVjdCBidXQgZG8gbm90XG4gKiBmYWlsIHRoZSBjb252ZXJzaW9uLlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSBBbiB7QGxpbmsgQ29udmVydGVycy5GaWVsZENvbnZlcnRlcnMgfCBGaWVsZENvbnZlcnRlcnM8VD59IGRlZmluaW5nIHRoZSBzaGFwZSBvZiB0aGVcbiAqIHNvdXJjZSBvYmplY3QgYW5kIHtAbGluayBDb252ZXJ0ZXIgfCBjb252ZXJ0ZXJzfSB0byBiZSBhcHBsaWVkIHRvIGVhY2ggcHJvcGVydGllcy5cbiAqIEBwYXJhbSBvcHRpb25hbCAtIEFuIGFycmF5IG9mIGAoa2V5b2YgVClgIGxpc3RpbmcgdGhlIGtleXMgdG8gYmUgY29uc2lkZXJlZCBvcHRpb25hbC5cbiAqIHtAbGFiZWwgd2l0aEtleXN9XG4gKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIgfCBPYmplY3RDb252ZXJ0ZXJ9IHdoaWNoIGFwcGxpZXMgdGhlIHNwZWNpZmllZCBjb252ZXJzaW9ucy5cbiAqIEBwdWJsaWNcbiAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgQ29udmVydGVycy4ob2JqZWN0OndpdGhPcHRpb25zKSB8IENvbnZlcnRlcnMub2JqZWN0KGZpZWxkcywgb3B0aW9ucyl9IGluc3RlYWQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG9iamVjdDxUPihwcm9wZXJ0aWVzOiBGaWVsZENvbnZlcnRlcnM8VD4sIG9wdGlvbmFsOiAoa2V5b2YgVClbXSk6IE9iamVjdENvbnZlcnRlcjxUPjtcbi8qKlxuICogQ29uY3JldGUgaW1wbGVtZW50YXRpb24gb2Yge0BsaW5rIENvbnZlcnRlcnMuKG9iamVjdDp3aXRoT3B0aW9ucykgfCBDb252ZXJ0ZXJzLm9iamVjdChmaWVsZHMsIG9wdGlvbnMpfVxuICogYW5kIHtAbGluayBDb252ZXJ0ZXJzLihvYmplY3Q6d2l0aEtleXMpIHwgQ29udmVydGVycy5vYmplY3RzKGZpZWxkcywgb3B0aW9uYWxLZXlzKX0uXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9iamVjdDxUPihwcm9wZXJ0aWVzOiBGaWVsZENvbnZlcnRlcnM8VD4sIG9wdGlvbnM/OiAoa2V5b2YgVClbXXxPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+KTogT2JqZWN0Q29udmVydGVyPFQ+IHtcbiAgICByZXR1cm4gbmV3IE9iamVjdENvbnZlcnRlcihwcm9wZXJ0aWVzLCBvcHRpb25zIGFzIE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD4pO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHRoZSB7QGxpbmsgQ29udmVydGVycy4oc3RyaWN0T2JqZWN0OndpdGhPcHRpb25zKX0gaGVscGVyIGZ1bmN0aW9uLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgdHlwZSBTdHJpY3RPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+ID0gT21pdDxPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+LCAnc3RyaWN0Jz47XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlciB8IE9iamVjdENvbnZlcnRlcn0gd2hpY2ggY29udmVydHMgYW4gb2JqZWN0XG4gKiB3aXRob3V0IGNoYW5naW5nIHNoYXBlLCBhIHtAbGluayBDb252ZXJ0ZXJzLkZpZWxkQ29udmVydGVycyB8IEZpZWxkQ29udmVydGVyczxUPn0gYW5kIGFuIG9wdGlvbmFsXG4gKiB7QGxpbmsgQ29udmVydGVycy5TdHJpY3RPYmplY3RDb252ZXJ0ZXJPcHRpb25zIHwgU3RyaWN0T2JqZWN0Q29udmVydGVyT3B0aW9uczxUPn0gdG8gZnVydGhlciByZWZpbmVcbiAqIGNvbnZlcnNpb24gYmVoYXZpb3IuXG4gKlxuICogQHJlbWFya3NcbiAqIEZpZWxkcyB0aGF0IHN1Y2NlZWQgYnV0IGNvbnZlcnQgdG8gdW5kZWZpbmVkIGFyZSBvbWl0dGVkIGZyb20gdGhlIHJlc3VsdCBvYmplY3QgYnV0IGRvIG5vdFxuICogZmFpbCB0aGUgY29udmVyc2lvbi5cbiAqXG4gKiBUaGUgY29udmVyc2lvbiBmYWlscyBpZiBhbnkgdW5leHBlY3RlZCBmaWVsZHMgYXJlIGVuY291bnRlcmVkLlxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gQW4gb2JqZWN0IGNvbnRhaW5pbmcgZGVmaW5pbmcgdGhlIHNoYXBlIGFuZCBjb252ZXJ0ZXJzIHRvIGJlIGFwcGxpZWQuXG4gKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIEBzZWUgU3RyaWN0T2JqZWN0Q29udmVydGVyT3B0aW9uczxUPiBjb250YWluaW5nIG9wdGlvbnMgZm9yIHRoZSBvYmplY3QgY29udmVydGVyLlxuICogQHJldHVybnMgQSBuZXcge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyIHwgT2JqZWN0Q29udmVydGVyfSB3aGljaCBhcHBsaWVzIHRoZSBzcGVjaWZpZWQgY29udmVyc2lvbnMuXG4gKiB7QGxhYmVsIHdpdGhPcHRpb25zfVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gc3RyaWN0T2JqZWN0PFQ+KHByb3BlcnRpZXM6IEZpZWxkQ29udmVydGVyczxUPiwgb3B0aW9ucz86IFN0cmljdE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD4pOiBPYmplY3RDb252ZXJ0ZXI8VD47XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlciB8IE9iamVjdENvbnZlcnRlcn0gd2hpY2ggY29udmVydHMgYW4gb2JqZWN0XG4gKiB3aXRob3V0IGNoYW5naW5nIHNoYXBlLCBhIHtAbGluayBDb252ZXJ0ZXJzLkZpZWxkQ29udmVydGVycyB8IEZpZWxkQ29udmVydGVyczxUPn0gYW5kIGFuIG9wdGlvbmFsXG4gKiB7QGxpbmsgQ29udmVydGVycy5TdHJpY3RPYmplY3RDb252ZXJ0ZXJPcHRpb25zIHwgU3RyaWN0T2JqZWN0Q29udmVydGVyT3B0aW9uczxUPn0gdG8gZnVydGhlciByZWZpbmVcbiAqIGNvbnZlcnNpb24gYmVoYXZpb3IuXG4gKlxuICogQHJlbWFya3NcbiAqIEZpZWxkcyB0aGF0IHN1Y2NlZWQgYnV0IGNvbnZlcnQgdG8gdW5kZWZpbmVkIGFyZSBvbWl0dGVkIGZyb20gdGhlIHJlc3VsdCBvYmplY3QgYnV0IGRvIG5vdFxuICogZmFpbCB0aGUgY29udmVyc2lvbi5cbiAqXG4gKiBUaGUgY29udmVyc2lvbiBmYWlscyBpZiBhbnkgdW5leHBlY3RlZCBmaWVsZHMgYXJlIGVuY291bnRlcmVkLlxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gQW4gb2JqZWN0IGNvbnRhaW5pbmcgZGVmaW5pbmcgdGhlIHNoYXBlIGFuZCBjb252ZXJ0ZXJzIHRvIGJlIGFwcGxpZWQuXG4gKiBAcGFyYW0gb3B0aW9uYWwgLSBBbiBhcnJheSBvZiBga2V5b2YgVGAgY29udGFpbmluZyBrZXlzIHRvIGJlIGNvbnNpZGVyZWQgb3B0aW9uYWwuXG4gKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIgfCBPYmplY3RDb252ZXJ0ZXJ9IHdoaWNoIGFwcGxpZXMgdGhlIHNwZWNpZmllZCBjb252ZXJzaW9ucy5cbiAqIHtAbGFiZWwgd2l0aEtleXN9XG4gKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rIENvbnZlcnRlcnMuKHN0cmljdE9iamVjdDp3aXRoT3B0aW9ucykgfCBDb252ZXJ0ZXJzLnN0cmljdE9iamVjdChvcHRpb25zKX0gaW5zdGVhZC5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0cmljdE9iamVjdDxUPihwcm9wZXJ0aWVzOiBGaWVsZENvbnZlcnRlcnM8VD4sIG9wdGlvbmFsOiAoa2V5b2YgVClbXSk6IE9iamVjdENvbnZlcnRlcjxUPjtcbi8qKlxuICogQ29uY3JldGUgaW1wbGVtZW50YXRpb24gZm9yIHtAbGluayBDb252ZXJ0ZXJzLihzdHJpY3RPYmplY3Q6d2l0aE9wdGlvbnMpIHwgQ29udmVydGVycy5zdHJpY3RPYmplY3QoZmllbGRzLCBvcHRpb25zKX1cbiAqIGFuZCB7QGxpbmsgQ29udmVydGVycy4oc3RyaWN0T2JqZWN0OndpdGhLZXlzKSB8IENvbnZlcnRlcnMuc3RyaWN0T2JqZWN0KGZpZWxkcywgb3B0aW9uYWwpfS5cbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RyaWN0T2JqZWN0PFQ+KFxuICAgIHByb3BlcnRpZXM6IEZpZWxkQ29udmVydGVyczxUPixcbiAgICBvcHQ/OiAoa2V5b2YgVClbXXxTdHJpY3RPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+LFxuKTogT2JqZWN0Q29udmVydGVyPFQ+IHtcbiAgICBjb25zdCBvcHRpb25zOiBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+ID0gKG9wdCAmJiBBcnJheS5pc0FycmF5KG9wdCkpXG4gICAgICAgID8geyBzdHJpY3Q6IHRydWUsIG9wdGlvbmFsRmllbGRzOiBvcHQgfVxuICAgICAgICA6IHsgLi4uKG9wdCA/PyB7fSksIHN0cmljdDogdHJ1ZSB9O1xuICAgIHJldHVybiBuZXcgT2JqZWN0Q29udmVydGVyKHByb3BlcnRpZXMsIG9wdGlvbnMpO1xufVxuXG4vKipcbiAqIEEgc3RyaW5nLWtleWVkIGBSZWNvcmQ8c3RyaW5nLCBDb252ZXJ0ZXI+YCB3aGljaCBtYXBzIHNwZWNpZmljIHtAbGluayBDb252ZXJ0ZXIgfCBjb252ZXJ0ZXJzfSB0byB0aGVcbiAqIHZhbHVlIG9mIGEgZGlzY3JpbWluYXRvciBwcm9wZXJ0eS5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IHR5cGUgRGlzY3JpbWluYXRlZE9iamVjdENvbnZlcnRlcnM8VCwgVEQgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmcsIFRDPXVua25vd24+ID0gUmVjb3JkPFRELCBDb252ZXJ0ZXI8VCwgVEM+PjtcblxuLyoqXG4gKiBIZWxwZXIgdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggY29udmVydHMgYSBkaXNjcmltaW5hdGVkIG9iamVjdCB3aXRob3V0IGNoYW5naW5nIHNoYXBlLlxuICogQHJlbWFya3NcbiAqIFRha2VzIHRoZSBuYW1lIG9mIHRoZSBkaXNjcmltaW5hdG9yIHByb3BlcnR5IGFuZCBhXG4gKiB7QGxpbmsgQ29udmVydGVycy5EaXNjcmltaW5hdGVkT2JqZWN0Q29udmVydGVycyB8IHN0cmluZy1rZXllZCBSZWNvcmQgb2YgY29udmVydGVyc30uIER1cmluZyBjb252ZXJzaW9uLFxuICogdGhlIHJlc3VsdGluZyB7QGxpbmsgQ29udmVydGVyfSBpbnZva2VzIHRoZSBjb252ZXJ0ZXIgZnJvbSBgY29udmVydGVyc2AgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgdmFsdWUgb2ZcbiAqIHRoZSBkaXNjcmltaW5hdG9yIHByb3BlcnR5IGluIHRoZSBzb3VyY2Ugb2JqZWN0LlxuICpcbiAqIElmIHRoZSBzb3VyY2UgaXMgbm90IGFuIG9iamVjdCwgdGhlIGRpc2NyaW1pbmF0b3IgcHJvcGVydHkgaXMgbWlzc2luZywgb3IgdGhlIGRpc2NyaW1pbmF0b3IgaGFzXG4gKiBhIHZhbHVlIG5vdCBwcmVzZW50IGluIHRoZSBjb252ZXJ0ZXJzLCBjb252ZXJzaW9uIGZhaWxzIGFuZCByZXR1cm5zIHtAbGluayBGYWlsdXJlfSB3aXRoIG1vcmUgaW5mb3JtYXRpb24uXG4gKiBAcGFyYW0gZGlzY3JpbWluYXRvclByb3AgLSBOYW1lIG9mIHRoZSBwcm9wZXJ0eSB1c2VkIHRvIGRpc2NyaW1pbmF0ZSB0eXBlcy5cbiAqIEBwYXJhbSBjb252ZXJ0ZXJzIC0ge0BsaW5rIENvbnZlcnRlcnMuRGlzY3JpbWluYXRlZE9iamVjdENvbnZlcnRlcnMgfCBTdHJpbmcta2V5ZWQgcmVjb3JkIG9mIGNvbnZlcnRlcnN9IHRvXG4gKiBpbnZva2UsIHdoZXJlIGVhY2gga2V5IGNvcnJlc3BvbmRzIHRvIGEgdmFsdWUgb2YgdGhlIGRpc2NyaW1pbmF0b3IgcHJvcGVydHkuXG4gKiBAcmV0dXJucyBBIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIHRoZSBjb3JyZXNwb25kaW5nIGRpc2NyaW1pbmF0ZWQgb2JqZWN0LlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gZGlzY3JpbWluYXRlZE9iamVjdDxULCBURCBleHRlbmRzIHN0cmluZyA9IHN0cmluZywgVEM9dW5rbm93bj4oZGlzY3JpbWluYXRvclByb3A6IHN0cmluZywgY29udmVydGVyczogRGlzY3JpbWluYXRlZE9iamVjdENvbnZlcnRlcnM8VCwgVEQ+KTogQ29udmVydGVyPFQsIFRDPiB7XG4gICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyKChmcm9tOiB1bmtub3duKSA9PiB7XG4gICAgICAgIGlmICgodHlwZW9mIGZyb20gIT09ICdvYmplY3QnKSB8fCBBcnJheS5pc0FycmF5KGZyb20pIHx8IGZyb20gPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKGBOb3QgYSBkaXNjcmltaW5hdGVkIG9iamVjdDogXCIke0pTT04uc3RyaW5naWZ5KGZyb20pfVwiYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCghaXNLZXlPZihkaXNjcmltaW5hdG9yUHJvcCwgZnJvbSkpIHx8ICghZnJvbVtkaXNjcmltaW5hdG9yUHJvcF0pKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFpbChgRGlzY3JpbWluYXRvciBwcm9wZXJ0eSAke2Rpc2NyaW1pbmF0b3JQcm9wfSBub3QgcHJlc2VudCBpbiBcIiR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9XCJgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGRpc2NyaW1pbmF0b3JWYWx1ZSA9IGZyb21bZGlzY3JpbWluYXRvclByb3BdIGFzIFREO1xuICAgICAgICBjb25zdCBjb252ZXJ0ZXIgPSBjb252ZXJ0ZXJzW2Rpc2NyaW1pbmF0b3JWYWx1ZV07XG4gICAgICAgIGlmIChjb252ZXJ0ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYE5vIGNvbnZlcnRlciBmb3IgZGlzY3JpbWluYXRvciAke2Rpc2NyaW1pbmF0b3JQcm9wfT1cIiR7ZGlzY3JpbWluYXRvclZhbHVlfVwiYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbnZlcnRlci5jb252ZXJ0KGZyb20pO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEhlbHBlciB0byBjcmVhdGUgYSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBjb252ZXJ0cyBhIHNvdXJjZSBvYmplY3QgdG8gYSBuZXcgb2JqZWN0IHdpdGggYVxuICogZGlmZmVyZW50IHNoYXBlLlxuICpcbiAqIEByZW1hcmtzXG4gKiBPbiBzdWNjZXNzZnVsIGNvbnZlcnNpb24sIHRoZSByZXN1bHRpbmcge0BsaW5rIENvbnZlcnRlcn0gcmV0dXJucyB7QGxpbmsgU3VjY2Vzc30gd2l0aCBhIG5ld1xuICogb2JqZWN0LCB3aGljaCBjb250YWlucyB0aGUgY29udmVydGVkIHZhbHVlcyB1bmRlciB0aGUga2V5IG5hbWVzIHNwZWNpZmllZCBhdCBpbml0aWFsaXphdGlvbiB0aW1lLlxuICogSXQgcmV0dXJucyB7QGxpbmsgRmFpbHVyZX0gd2l0aCBhbiBlcnJvciBtZXNzYWdlIGlmIGFueSBmaWVsZHMgdG8gYmUgZXh0cmFjdGVkIGRvIG5vdCBleGlzdFxuICogb3IgY2Fubm90IGJlIGNvbnZlcnRlZC5cbiAqXG4gKiBGaWVsZHMgdGhhdCBzdWNjZWVkIGJ1dCBjb252ZXJ0IHRvIHVuZGVmaW5lZCBhcmUgb21pdHRlZCBmcm9tIHRoZSByZXN1bHQgb2JqZWN0IGJ1dCBkbyBub3RcbiAqIGZhaWwgdGhlIGNvbnZlcnNpb24uXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSBBbiBvYmplY3Qgd2l0aCBrZXkgbmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHRoZSB0YXJnZXQgb2JqZWN0IGFuZCBhblxuICogYXBwcm9wcmlhdGUge0BsaW5rIENvbnZlcnRlcnMuRmllbGRDb252ZXJ0ZXJzIHwgRmllbGRDb252ZXJ0ZXJ9IHdoaWNoIGV4dHJhY3RzIGFuZCBjb252ZXJ0c1xuICogYSBzaW5nbGUgZmlsZWQgZnJvbSB0aGUgc291cmNlIG9iamVjdC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIENvbnZlcnRlcn0gd2l0aCB0aGUgc3BlY2lmaWVkIGNvbnZlcnNpb24gYmVoYXZpb3IuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm08VCwgVEM9dW5rbm93bj4ocHJvcGVydGllczogRmllbGRDb252ZXJ0ZXJzPFQsIFRDPik6IENvbnZlcnRlcjxULCBUQz4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGYsIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICAvLyBlc2xpbnQgYnVnIHRoaW5rcyBrZXkgaXMgdXNlZCBiZWZvcmUgZGVmaW5lZFxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlLWJlZm9yZS1kZWZpbmVcbiAgICAgICAgY29uc3QgY29udmVydGVkID0ge30gYXMgeyBbIGtleSBpbiBrZXlvZiBUXTogVFtrZXldIH07XG4gICAgICAgIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXldKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gcHJvcGVydGllc1trZXldLmNvbnZlcnQoZnJvbSwgY29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSAmJiAocmVzdWx0LnZhbHVlICE9PSB1bmRlZmluZWQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnZlcnRlZFtrZXldID0gcmVzdWx0LnZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChyZXN1bHQuaXNGYWlsdXJlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JzLnB1c2gocmVzdWx0Lm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoZXJyb3JzLmxlbmd0aCA9PT0gMCkgPyBzdWNjZWVkKGNvbnZlcnRlZCkgOiBmYWlsKGVycm9ycy5qb2luKCdcXG4nKSk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBoZWxwZXIgd3JhcHBlciB0byBjb25zdHJ1Y3QgYSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBjb252ZXJ0cyB0byBhbiBhcmJpdHJhcnkgc3Ryb25nbHktdHlwZWRcbiAqIHJhbmdlIG9mIHNvbWUgY29tcGFyYWJsZSB0eXBlLlxuICogQHBhcmFtIGNvbnZlcnRlciAtIHtAbGluayBDb252ZXJ0ZXJ9IHVzZWQgdG8gY29udmVydCBgbWluYCBhbmQgYG1heGAgZXh0ZW50IG9mIHRoZSByYW5nZS5cbiAqIEBwYXJhbSBjb25zdHJ1Y3RvciAtIFN0YXRpYyBjb25zdHJ1Y3RvciB0byBpbnN0YW50aWF0ZSB0aGUgb2JqZWN0LlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmFuZ2VUeXBlT2Y8VCwgUlQgZXh0ZW5kcyBSYW5nZU9mPFQ+LCBUQz11bmtub3duPihjb252ZXJ0ZXI6IENvbnZlcnRlcjxULCBUQz4sIGNvbnN0cnVjdG9yOiAoaW5pdDogUmFuZ2VPZlByb3BlcnRpZXM8VD4pID0+IFJlc3VsdDxSVD4pOiBDb252ZXJ0ZXI8UlQsIFRDPiB7XG4gICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyKChmcm9tOiB1bmtub3duLCBfc2VsZiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IG9iamVjdCh7XG4gICAgICAgICAgICBtaW46IGNvbnZlcnRlcixcbiAgICAgICAgICAgIG1heDogY29udmVydGVyLFxuICAgICAgICB9LCB7IG9wdGlvbmFsRmllbGRzOiBbJ21pbicsICdtYXgnXSB9KS5jb252ZXJ0KGZyb20sIGNvbnRleHQpO1xuICAgICAgICBpZiAocmVzdWx0LmlzU3VjY2VzcygpKSB7XG4gICAgICAgICAgICByZXR1cm4gY29uc3RydWN0b3IoeyBtaW46IHJlc3VsdC52YWx1ZS5taW4sIG1heDogcmVzdWx0LnZhbHVlLm1heCB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFpbChyZXN1bHQubWVzc2FnZSk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBoZWxwZXIgd3JhcHBlciB0byBjb25zdHJ1Y3QgYSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBjb252ZXJ0cyB0byB7QGxpbmsgUmFuZ2VPZiB8IFJhbmdlT2Y8VD59XG4gKiB3aGVyZSBgPFQ+YCBpcyBzb21lIGNvbXBhcmFibGUgdHlwZS5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgLSB7QGxpbmsgQ29udmVydGVyfSB1c2VkIHRvIGNvbnZlcnQgYG1pbmAgYW5kIGBtYXhgIGV4dGVudCBvZiB0aGUgcmFuZ2UuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByYW5nZU9mPFQsIFRDPXVua25vd24+KGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPik6IENvbnZlcnRlcjxSYW5nZU9mPFQ+LCBUQz4ge1xuICAgIHJldHVybiByYW5nZVR5cGVPZjxULCBSYW5nZU9mPFQ+LCBUQz4oY29udmVydGVyLCBSYW5nZU9mLmNyZWF0ZVJhbmdlKTtcbn1cbiJdfQ==