@fgv/ts-utils 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) 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 +59 -72
  9. package/converters.d.ts +432 -194
  10. package/converters.d.ts.map +1 -0
  11. package/converters.js +335 -224
  12. package/csvHelpers.d.ts +7 -0
  13. package/csvHelpers.d.ts.map +1 -0
  14. package/csvHelpers.js +14 -4
  15. package/extendedArray.d.ts +46 -0
  16. package/extendedArray.d.ts.map +1 -0
  17. package/extendedArray.js +53 -8
  18. package/formatter.d.ts +53 -0
  19. package/formatter.d.ts.map +1 -0
  20. package/formatter.js +27 -4
  21. package/hash.d.ts +51 -0
  22. package/hash.d.ts.map +1 -0
  23. package/hash.js +168 -0
  24. package/index.d.ts +7 -2
  25. package/index.d.ts.map +1 -0
  26. package/index.js +16 -5
  27. package/logger.d.ts +3 -2
  28. package/logger.d.ts.map +1 -0
  29. package/logger.js +12 -12
  30. package/package.json +24 -20
  31. package/rangeOf.d.ts +96 -0
  32. package/rangeOf.d.ts.map +1 -0
  33. package/rangeOf.js +81 -2
  34. package/result.d.ts +393 -39
  35. package/result.d.ts.map +1 -0
  36. package/result.js +259 -49
  37. package/ts-utils.d.ts +2475 -0
  38. package/tsdoc-metadata.json +11 -0
  39. package/utils.d.ts +71 -27
  40. package/utils.d.ts.map +1 -0
  41. package/utils.js +82 -37
  42. package/validation/boolean.d.ts +27 -0
  43. package/validation/boolean.d.ts.map +1 -0
  44. package/validation/boolean.js +59 -0
  45. package/validation/classes.d.ts +5 -0
  46. package/validation/classes.d.ts.map +1 -0
  47. package/validation/classes.js +34 -0
  48. package/validation/field.d.ts +43 -0
  49. package/validation/field.d.ts.map +1 -0
  50. package/validation/field.js +72 -0
  51. package/validation/genericValidator.d.ts +84 -0
  52. package/validation/genericValidator.d.ts.map +1 -0
  53. package/validation/genericValidator.js +138 -0
  54. package/validation/index.d.ts +7 -0
  55. package/validation/index.d.ts.map +1 -0
  56. package/validation/index.js +59 -0
  57. package/validation/number.d.ts +27 -0
  58. package/validation/number.d.ts.map +1 -0
  59. package/validation/number.js +57 -0
  60. package/validation/object.d.ts +115 -0
  61. package/validation/object.d.ts.map +1 -0
  62. package/validation/object.js +143 -0
  63. package/validation/string.d.ts +27 -0
  64. package/validation/string.d.ts.map +1 -0
  65. package/validation/string.js +57 -0
  66. package/validation/traits.d.ts +68 -0
  67. package/validation/traits.d.ts.map +1 -0
  68. package/validation/traits.js +58 -0
  69. package/validation/validator.d.ts +82 -0
  70. package/validation/validator.d.ts.map +1 -0
  71. package/validation/validator.js +24 -0
  72. package/validation/validatorBase.d.ts +25 -0
  73. package/validation/validatorBase.d.ts.map +1 -0
  74. package/validation/validatorBase.js +44 -0
  75. package/validation/validators.d.ts +32 -0
  76. package/validation/validators.d.ts.map +1 -0
  77. package/validation/validators.js +59 -0
package/result.js CHANGED
@@ -22,145 +22,334 @@
22
22
  */
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.populateObject = exports.allSucceed = exports.mapFailures = exports.mapSuccess = exports.mapDetailedResults = exports.mapResults = exports.captureResult = exports.propagateWithDetail = exports.failWithDetail = exports.succeedWithDetail = exports.DetailedFailure = exports.DetailedSuccess = exports.fail = exports.succeed = exports.Failure = exports.Success = void 0;
25
+ /**
26
+ * Reports a successful {@link IResult | result} from some operation and the
27
+ * corresponding value.
28
+ * @public
29
+ */
25
30
  class Success {
31
+ /**
32
+ * Constructs a {@link Success} with the supplied value.
33
+ * @param value - The value to be returned.
34
+ */
26
35
  constructor(value) {
36
+ /**
37
+ * {@inheritdoc IResult.success}
38
+ */
39
+ this.success = true;
27
40
  this._value = value;
28
41
  }
42
+ /**
43
+ * The result value returned by the successful operation.
44
+ */
45
+ get value() {
46
+ return this._value;
47
+ }
48
+ /**
49
+ * {@inheritdoc IResult.isSuccess}
50
+ */
29
51
  isSuccess() {
30
52
  return true;
31
53
  }
54
+ /**
55
+ * {@inheritdoc IResult.isFailure}
56
+ */
32
57
  isFailure() {
33
58
  return false;
34
59
  }
35
- get value() {
36
- return this._value;
37
- }
60
+ /**
61
+ * {@inheritdoc IResult.getValueOrThrow}
62
+ */
38
63
  getValueOrThrow(_logger) {
39
64
  return this._value;
40
65
  }
66
+ /**
67
+ * {@inheritdoc IResult.getValueOrDefault}
68
+ */
41
69
  getValueOrDefault(dflt) {
42
70
  var _a;
43
71
  return (_a = this._value) !== null && _a !== void 0 ? _a : dflt;
44
72
  }
73
+ /**
74
+ * {@inheritdoc IResult.onSuccess}
75
+ */
45
76
  onSuccess(cb) {
46
77
  return cb(this.value);
47
78
  }
79
+ /**
80
+ * {@inheritdoc IResult.onFailure}
81
+ */
48
82
  onFailure(_) {
49
83
  return this;
50
84
  }
85
+ /**
86
+ * {@inheritdoc IResult.withFailureDetail}
87
+ */
51
88
  withFailureDetail(_detail) {
52
89
  return succeedWithDetail(this.value);
53
90
  }
91
+ /**
92
+ * {@inheritdoc IResult.withDetail}
93
+ */
54
94
  withDetail(detail, successDetail) {
55
95
  return succeedWithDetail(this.value, successDetail !== null && successDetail !== void 0 ? successDetail : detail);
56
96
  }
57
97
  }
58
98
  exports.Success = Success;
99
+ /**
100
+ * Reports a failed {@link IResult | result} from some operation, with an error message.
101
+ * @public
102
+ */
59
103
  class Failure {
104
+ /**
105
+ * Constructs a {@link Failure} with the supplied message.
106
+ * @param message - Error message to be reported.
107
+ */
60
108
  constructor(message) {
109
+ /**
110
+ * {@inheritdoc IResult.success}
111
+ */
112
+ this.success = false;
61
113
  this._message = message;
62
114
  }
115
+ /**
116
+ * Gets the error message associated with this error.
117
+ */
118
+ get message() {
119
+ return this._message;
120
+ }
121
+ /**
122
+ * {@inheritdoc IResult.isSuccess}
123
+ */
63
124
  isSuccess() {
64
125
  return false;
65
126
  }
127
+ /**
128
+ * {@inheritdoc IResult.isFailure}
129
+ */
66
130
  isFailure() {
67
131
  return true;
68
132
  }
69
- get message() {
70
- return this._message;
71
- }
133
+ /**
134
+ * {@inheritdoc IResult.getValueOrThrow}
135
+ */
72
136
  getValueOrThrow(logger) {
73
137
  if (logger !== undefined) {
74
138
  logger.error(this._message);
75
139
  }
76
140
  throw new Error(this._message);
77
141
  }
142
+ /**
143
+ * {@inheritdoc IResult.getValueOrDefault}
144
+ */
78
145
  getValueOrDefault(dflt) {
79
146
  return dflt;
80
147
  }
148
+ /**
149
+ * {@inheritdoc IResult.onSuccess}
150
+ */
81
151
  onSuccess(_) {
82
152
  return new Failure(this.message);
83
153
  }
154
+ /**
155
+ * {@inheritdoc IResult.onFailure}
156
+ */
84
157
  onFailure(cb) {
85
158
  return cb(this.message);
86
159
  }
160
+ /**
161
+ * {@inheritdoc IResult.withFailureDetail}
162
+ */
87
163
  withFailureDetail(detail) {
88
164
  return failWithDetail(this.message, detail);
89
165
  }
166
+ /**
167
+ * {@inheritdoc IResult.withDetail}
168
+ */
90
169
  withDetail(detail, _successDetail) {
91
170
  return failWithDetail(this.message, detail);
92
171
  }
172
+ /**
173
+ * Get a 'friendly' string representation of this object.
174
+ * @remarks
175
+ * The string representation of a {@link Failure} value is the error message.
176
+ * @returns A string representing this object.
177
+ */
93
178
  toString() {
94
179
  return this.message;
95
180
  }
96
181
  }
97
182
  exports.Failure = Failure;
98
183
  /**
99
- * Helper function for successful return
100
- * @param val The value to be returned
184
+ * Returns {@link Success | Success<T>} with the supplied result value.
185
+ * @param value - The successful result value to be returned
186
+ * @public
101
187
  */
102
- function succeed(val) {
103
- return new Success(val);
188
+ function succeed(value) {
189
+ return new Success(value);
104
190
  }
105
191
  exports.succeed = succeed;
106
192
  /**
107
- * Helper function for error return
108
- * @param message Error message to be returned
193
+ * Returns {@link Failure | Failure<T>} with the supplied error message.
194
+ * @param message - Error message to be returned.
195
+ * @public
109
196
  */
110
197
  function fail(message) {
111
198
  return new Failure(message);
112
199
  }
113
200
  exports.fail = fail;
201
+ /**
202
+ * A {@link DetailedSuccess} extends {@link Success} to report optional success details in
203
+ * addition to the error message.
204
+ * @public
205
+ */
114
206
  class DetailedSuccess extends Success {
207
+ /**
208
+ * Constructs a new {@link DetailedSuccess | DetailedSuccess<T, TD>} with the supplied
209
+ * value and detail.
210
+ * @param value - The value to be returned.
211
+ * @param detail - An optional successful detail to be returned. If omitted, detail
212
+ * will be `undefined`.
213
+ */
115
214
  constructor(value, detail) {
116
215
  super(value);
117
216
  this._detail = detail;
118
217
  }
218
+ /**
219
+ * The success detail associated with this {@link DetailedSuccess}, or `undefined` if
220
+ * no detail was supplied.
221
+ */
119
222
  get detail() {
120
223
  return this._detail;
121
224
  }
225
+ /**
226
+ * Reports that this {@link DetailedSuccess} is a success.
227
+ * @remarks
228
+ * Always true for {@link DetailedSuccess} but can be used as type guard
229
+ * to discriminate {@link DetailedSuccess} from {@link DetailedFailure} in
230
+ * a {@link DetailedResult}.
231
+ * @returns `true`
232
+ */
122
233
  isSuccess() {
123
234
  return true;
124
235
  }
236
+ /**
237
+ * Invokes the supplied {@link DetailedSuccessContinuation | success callback} and propagates
238
+ * its returned {@link DetailedResult | DetailedResult<TN, TD>}.
239
+ * @remarks
240
+ * The success callback mutates the return type from `<T>` to `<TN>`.
241
+ * @param cb - The {@link DetailedSuccessContinuation | success callback} to be invoked.
242
+ * @returns The {@link DetailedResult | DetailedResult<T, TD>} returned by the success callback.
243
+ */
125
244
  onSuccess(cb) {
126
245
  return cb(this.value, this._detail);
127
246
  }
247
+ /**
248
+ * Propagates this {@link DetailedSuccess}.
249
+ * @remarks
250
+ * Failure does not mutate return type so we can return this event directly.
251
+ * @param _cb - {@link DetailedFailureContinuation | Failure callback} to be called
252
+ * on a {@link DetailedResult} in case of failure (ignored).
253
+ * @returns `this`
254
+ */
128
255
  onFailure(_cb) {
129
256
  return this;
130
257
  }
131
258
  }
132
259
  exports.DetailedSuccess = DetailedSuccess;
133
260
  /**
134
- * A DetailedFailure reports optional failure details in addition
135
- * to the standard failure message.
261
+ * A {@link DetailedFailure} extends {@link Failure} to report optional failure details in
262
+ * addition to the error message.
263
+ * @public
136
264
  */
137
265
  class DetailedFailure extends Failure {
266
+ /**
267
+ * Constructs a new {@link DetailedFailure | DetailedFailure<T, TD>} with the supplied
268
+ * message and detail.
269
+ * @param message - The message to be returned.
270
+ * @param detail - The error detail to be returned.
271
+ */
138
272
  constructor(message, detail) {
139
273
  super(message);
140
274
  this._detail = detail;
141
275
  }
276
+ /**
277
+ * The error detail associated with this {@link DetailedFailure}.
278
+ */
142
279
  get detail() {
143
280
  return this._detail;
144
281
  }
282
+ /**
283
+ * Reports that this {@link DetailedFailure} is a failure.
284
+ * @remarks
285
+ * Always true for {@link DetailedFailure} but can be used as type guard
286
+ * to discriminate {@link DetailedSuccess} from {@link DetailedFailure} in
287
+ * a {@link DetailedResult}.
288
+ * @returns `true`
289
+ */
145
290
  isFailure() {
146
291
  return true;
147
292
  }
293
+ /**
294
+ * Propagates the error message and detail from this result.
295
+ * @remarks
296
+ * Mutates the success type as the success callback would have, but does not
297
+ * call the success callback.
298
+ * @param _cb - {@link DetailedSuccessContinuation | Success callback} to be called
299
+ * on a {@link DetailedResult} in case of success (ignored).
300
+ * @returns A new {@link DetailedFailure | DetailedFailure<TN, TD>} which contains
301
+ * the error message and detail from this one.
302
+ */
148
303
  onSuccess(_cb) {
149
304
  return new DetailedFailure(this.message, this._detail);
150
305
  }
306
+ /**
307
+ * Invokes the supplied {@link DetailedFailureContinuation | failure callback} and propagates
308
+ * its returned {@link DetailedResult | DetailedResult<T, TD>}.
309
+ * @param cb - The {@link DetailedFailureContinuation | failure callback} to be invoked.
310
+ * @returns The {@link DetailedResult | DetailedResult<T, TD>} returned by the failure callback.
311
+ */
151
312
  onFailure(cb) {
152
313
  return cb(this.message, this._detail);
153
314
  }
154
315
  }
155
316
  exports.DetailedFailure = DetailedFailure;
317
+ /**
318
+ * Returns {@link DetailedSuccess | DetailedSuccess<T, TD>} with a supplied value and optional
319
+ * detail.
320
+ * @param value - The value of type `<T>` to be returned.
321
+ * @param detail - An optional detail of type `<TD>` to be returned.
322
+ * @returns A {@link DetailedSuccess | DetailedSuccess<T, TD>} with the supplied value
323
+ * and detail, if supplied.
324
+ * @public
325
+ */
156
326
  function succeedWithDetail(value, detail) {
157
327
  return new DetailedSuccess(value, detail);
158
328
  }
159
329
  exports.succeedWithDetail = succeedWithDetail;
330
+ /**
331
+ * Returns {@link DetailedFailure | DetailedFailure<T, TD>} with a supplied error message and detail.
332
+ * @param message - The error message to be returned.
333
+ * @param detail - The event detail to be returned.
334
+ * @returns An {@link DetailedFailure | DetailedFailure<T, TD>} with the supplied error
335
+ * message and detail.
336
+ * @public
337
+ */
160
338
  function failWithDetail(message, detail) {
161
339
  return new DetailedFailure(message, detail);
162
340
  }
163
341
  exports.failWithDetail = failWithDetail;
342
+ /**
343
+ * Propagates a {@link Success} or {@link Failure} {@link Result}, adding supplied
344
+ * event details as appropriate.
345
+ * @param result - The {@link Result} to be propagated.
346
+ * @param detail - The event detail (type `<TD>`) to be added to the {@link Result | result}.
347
+ * @param successDetail - An optional distinct event detail to be added to {@link Success} results. If `successDetail`
348
+ * is omitted or `undefined`, then `detail` will be applied to {@link Success} results.
349
+ * @returns A new {@link DetailedResult | DetailedResult<T, TD>} with the success value or error
350
+ * message from the original `result` but with the specified detail added.
351
+ * @public
352
+ */
164
353
  function propagateWithDetail(result, detail, successDetail) {
165
354
  return result.isSuccess()
166
355
  ? succeedWithDetail(result.value, successDetail !== null && successDetail !== void 0 ? successDetail : detail)
@@ -168,9 +357,13 @@ function propagateWithDetail(result, detail, successDetail) {
168
357
  }
169
358
  exports.propagateWithDetail = propagateWithDetail;
170
359
  /**
171
- * Wraps a function which returns a value of type <T> or throws
172
- * to produce Success<T> or Failure<T>
173
- * @param func The method to be captured
360
+ * Wraps a function which might throw to convert exception results
361
+ * to {@link Failure}.
362
+ * @param func - The function to be captured.
363
+ * @returns Returns {@link Success} with a value of type `<T>` on
364
+ * success , or {@link Failure} with the thrown error message if
365
+ * `func` throws an `Error`.
366
+ * @public
174
367
  */
175
368
  function captureResult(func) {
176
369
  try {
@@ -182,15 +375,17 @@ function captureResult(func) {
182
375
  }
183
376
  exports.captureResult = captureResult;
184
377
  /**
185
- * Maps an array of Result<T> to an array of <T>, if all results are
186
- * successful. If any results fail, returns failure with a concatenated
187
- * summary of all failure messages.
188
- * @param resultsIn The results to be mapped.
378
+ * Aggregates sucessful result values from a collection of {@link Result | Result<T>}.
379
+ * @param results - The collection of {@link Result | Result<T>} to be mapped.
380
+ * @returns If all {@link Result | results} are successful, returns {@link Success} with an
381
+ * array containing all returned values. If any {@link Result | results} failed, returns
382
+ * {@link Failure} with a concatenated summary of all error messages.
383
+ * @public
189
384
  */
190
- function mapResults(resultsIn) {
385
+ function mapResults(results) {
191
386
  const errors = [];
192
387
  const elements = [];
193
- for (const result of resultsIn) {
388
+ for (const result of results) {
194
389
  if (result.isSuccess()) {
195
390
  elements.push(result.value);
196
391
  }
@@ -205,16 +400,20 @@ function mapResults(resultsIn) {
205
400
  }
206
401
  exports.mapResults = mapResults;
207
402
  /**
208
- * Maps an array of DetailedResult<T, TD> to an array of <T>, if all results are
209
- * successful or yield ignorable errors. If any results fail with an error that
210
- * cannot be ignored, returns failure with a concatenated summary of all failure messages.
211
- * @param resultsIn The results to be mapped.
212
- * @param ignore Error detail values that should be ignored
403
+ * Aggregates sucessful results from a collection of {@link DetailedResult | DetailedResult<T, TD>},
404
+ * optionally ignoring certain error details.
405
+ * @param results - The collection of {@link DetailedResult | DetailedResult<T, TD>} to be mapped.
406
+ * @param ignore - An array of error detail values (of type `<TD>`) that should be ignored.
407
+ * @returns {@link Success} with an array containing all successful results if all results either
408
+ * suceeded or returned error details listed in `ignore`. If any results failed with details
409
+ * that cannot be ignored, returns {@link Failure} with an concatenated summary of all non-ignorable
410
+ * error mesasges.
411
+ * @public
213
412
  */
214
- function mapDetailedResults(resultsIn, ignore) {
413
+ function mapDetailedResults(results, ignore) {
215
414
  const errors = [];
216
415
  const elements = [];
217
- for (const result of resultsIn) {
416
+ for (const result of results) {
218
417
  if (result.isSuccess()) {
219
418
  elements.push(result.value);
220
419
  }
@@ -229,14 +428,18 @@ function mapDetailedResults(resultsIn, ignore) {
229
428
  }
230
429
  exports.mapDetailedResults = mapDetailedResults;
231
430
  /**
232
- * Maps an array of Result<T> to an array of <T>, omitting any error
233
- * results. If no results were successful, returns failure with a
234
- * concatenated summary of all failure messages.
431
+ * Aggregates successful results from a a collection of {@link Result | Result<T>}.
432
+ * @param results - An `Iterable` of {@link Result | Result<T>} from which success
433
+ * results are to be aggregated.
434
+ * @returns {@link Success} with an array of `<T>` if any results were successful. If
435
+ * all {@link Result | results} failed, returns {@link Failure} with a concatenated
436
+ * summary of all error messages.
437
+ * @public
235
438
  */
236
- function mapSuccess(resultsIn) {
439
+ function mapSuccess(results) {
237
440
  const errors = [];
238
441
  const elements = [];
239
- for (const result of resultsIn) {
442
+ for (const result of results) {
240
443
  if (result.isSuccess()) {
241
444
  elements.push(result.value);
242
445
  }
@@ -251,14 +454,17 @@ function mapSuccess(resultsIn) {
251
454
  }
252
455
  exports.mapSuccess = mapSuccess;
253
456
  /**
254
- * Maps an array of Result<T> to an array of strings consisting of all
255
- * error messages returned by results in the source array. Ignores
256
- * success results and returns an empty array if there were no errors.
257
- * @param resultsIn results to be reported
457
+ * Aggregates error messages from a collection of {@link Result | Result<T>}.
458
+ * @param results - An interable collection of {@link Result | Result<T>} for which
459
+ * error messages are aggregated.
460
+ * @returns An array of strings consisting of all error messages returned by
461
+ * {@link Result | results} in the source collection. Ignores {@link Success}
462
+ * results and returns an empty array if there were no errors.
463
+ * @public
258
464
  */
259
- function mapFailures(resultsIn) {
465
+ function mapFailures(results) {
260
466
  const errors = [];
261
- for (const result of resultsIn) {
467
+ for (const result of results) {
262
468
  if (result.isFailure()) {
263
469
  errors.push(result.message);
264
470
  }
@@ -267,9 +473,12 @@ function mapFailures(resultsIn) {
267
473
  }
268
474
  exports.mapFailures = mapFailures;
269
475
  /**
270
- * Returns success with true if all results are successful. If any are unsuccessful,
271
- * returns failure with a concatenated summary of all failure messages.
272
- * @param results The results to be tested.
476
+ * Determines if an iterable collection of {@link Result | Result<T>} were all successful.
477
+ * @param results - The collection of {@link Result | Result<T>} to be tested.
478
+ * @returns Returns {@link Success} with `true` if all {@link Result | results} are successful.
479
+ * If any are unsuccessful, returns {@link Failure} with a concatenated summary the error
480
+ * messages from all failed elements.
481
+ * @public
273
482
  */
274
483
  function allSucceed(results, successValue) {
275
484
  const errors = [];
@@ -288,11 +497,12 @@ function allSucceed(results, successValue) {
288
497
  }
289
498
  exports.allSucceed = allSucceed;
290
499
  /**
291
- * Populates an an object based on a prototype full of field initializers that return Result<T[key]>.
292
- * Returns success with the populated object if all initializers succeed, or failure with a
293
- * concatenated list of all failure messages.
294
- * @param initializers An object with the shape of the target but with initializer functions for
500
+ * Populates an an object based on a prototype full of field initializers that return {@link Result | Result<T[key]>}.
501
+ * Returns {@link Success} with the populated object if all initializers succeed, or {@link Failure} with a
502
+ * concatenated list of all error messages.
503
+ * @param initializers - An object with the shape of the target but with initializer functions for
295
504
  * each property.
505
+ * @public
296
506
  */
297
507
  function populateObject(initializers, order) {
298
508
  const state = {};
@@ -326,4 +536,4 @@ function populateObject(initializers, order) {
326
536
  return succeed(state);
327
537
  }
328
538
  exports.populateObject = populateObject;
329
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdWx0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3Jlc3VsdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHOzs7QUF1QkgsTUFBYSxPQUFPO0lBR2hCLFlBQVksS0FBUTtRQUNoQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDO0lBRU0sU0FBUztRQUNaLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFTSxTQUFTO1FBQ1osT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztJQUVELElBQVcsS0FBSztRQUNaLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUN2QixDQUFDO0lBRU0sZUFBZSxDQUFDLE9BQXVCO1FBQzFDLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUN2QixDQUFDO0lBRU0saUJBQWlCLENBQUMsSUFBUTs7UUFDN0IsT0FBTyxNQUFBLElBQUksQ0FBQyxNQUFNLG1DQUFJLElBQUksQ0FBQztJQUMvQixDQUFDO0lBRU0sU0FBUyxDQUFLLEVBQThCO1FBQy9DLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBRU0sU0FBUyxDQUFDLENBQXlCO1FBQ3RDLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFTSxpQkFBaUIsQ0FBSyxPQUFXO1FBQ3BDLE9BQU8saUJBQWlCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFTSxVQUFVLENBQUssTUFBVSxFQUFFLGFBQWtCO1FBQ2hELE9BQU8saUJBQWlCLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxhQUFhLGFBQWIsYUFBYSxjQUFiLGFBQWEsR0FBSSxNQUFNLENBQUMsQ0FBQztJQUNsRSxDQUFDO0NBQ0o7QUExQ0QsMEJBMENDO0FBRUQsTUFBYSxPQUFPO0lBR2hCLFlBQVksT0FBZTtRQUN2QixJQUFJLENB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RCxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQzthQUMvQjtTQUNKO2FBQ0k7WUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLHVCQUF1QixHQUFHLG9DQUFvQyxDQUFDLENBQUM7U0FDL0U7S0FDSjtJQUVELElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7UUFDbkIsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0tBQ2xDO0lBQ0QsT0FBTyxPQUFPLENBQUMsS0FBVSxDQUFDLENBQUM7QUFDL0IsQ0FBQztBQWpDRCx3Q0FpQ0MiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDIwIEVyaWsgRm9ydHVuZVxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbiAqIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbiAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGxcbiAqIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4gKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRVxuICogU09GVFdBUkUuXG4gKi9cblxuLyogZXNsaW50LWRpc2FibGUgbm8tdXNlLWJlZm9yZS1kZWZpbmUgKi9cbmV4cG9ydCB0eXBlIFJlc3VsdDxUPiA9IFN1Y2Nlc3M8VD4gfCBGYWlsdXJlPFQ+O1xuZXhwb3J0IHR5cGUgU3VjY2Vzc0NvbnRpbnVhdGlvbjxULCBUTj4gPSAodmFsdWU6IFQpID0+IFJlc3VsdDxUTj47XG5leHBvcnQgdHlwZSBGYWlsdXJlQ29udGludWF0aW9uPFQ+ID0gKG1lc3NhZ2U6IHN0cmluZykgPT4gUmVzdWx0PFQ+O1xuZXhwb3J0IHR5cGUgUmVzdWx0VmFsdWVUeXBlPFQ+ID0gVCBleHRlbmRzIFJlc3VsdDxpbmZlciBUVj4gPyBUViA6IG5ldmVyO1xuXG5leHBvcnQgaW50ZXJmYWNlIElSZXN1bHRMb2dnZXIge1xuICAgIGVycm9yKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVJlc3VsdDxUPiB7XG4gICAgaXNTdWNjZXNzKCk6IHRoaXMgaXMgU3VjY2VzczxUPjtcbiAgICBpc0ZhaWx1cmUoKTogdGhpcyBpcyBGYWlsdXJlPFQ+O1xuICAgIGdldFZhbHVlT3JUaHJvdyhsb2dnZXI/OiBJUmVzdWx0TG9nZ2VyKTogVDtcbiAgICBnZXRWYWx1ZU9yRGVmYXVsdChkZmx0PzogVCk6IFR8dW5kZWZpbmVkO1xuICAgIG9uU3VjY2VzczxUTj4oY2I6IFN1Y2Nlc3NDb250aW51YXRpb248VCwgVE4+KTogUmVzdWx0PFROPjtcbiAgICBvbkZhaWx1cmUoY2I6IEZhaWx1cmVDb250aW51YXRpb248VD4pOiBSZXN1bHQ8VD47XG4gICAgd2l0aEZhaWx1cmVEZXRhaWw8VEQ+KGRldGFpbDogVEQpOiBEZXRhaWxlZFJlc3VsdDxULCBURD47XG4gICAgd2l0aERldGFpbDxURD4oZGV0YWlsOiBURCwgc3VjY2Vzc0RldGFpbD86IFREKTogRGV0YWlsZWRSZXN1bHQ8VCwgVEQ+O1xufVxuXG5leHBvcnQgY2xhc3MgU3VjY2VzczxUPiBpbXBsZW1lbnRzIElSZXN1bHQ8VD4ge1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX3ZhbHVlOiBUO1xuXG4gICAgY29uc3RydWN0b3IodmFsdWU6IFQpIHtcbiAgICAgICAgdGhpcy5fdmFsdWUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNTdWNjZXNzKCk6IHRoaXMgaXMgU3VjY2VzczxUPiB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc0ZhaWx1cmUoKTogdGhpcyBpcyBGYWlsdXJlPFQ+IHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgdmFsdWUoKTogVCB7XG4gICAgICAgIHJldHVybiB0aGlzLl92YWx1ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0VmFsdWVPclRocm93KF9sb2dnZXI/OiBJUmVzdWx0TG9nZ2VyKTogVCB7XG4gICAgICAgIHJldHVybiB0aGlzLl92YWx1ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0VmFsdWVPckRlZmF1bHQoZGZsdD86IFQpOiBUfHVuZGVmaW5lZCB7XG4gICAgICAgIHJldHVybiB0aGlzLl92YWx1ZSA/PyBkZmx0O1xuICAgIH1cblxuICAgIHB1YmxpYyBvblN1Y2Nlc3M8VE4+KGNiOiBTdWNjZXNzQ29udGludWF0aW9uPFQsIFROPik6IFJlc3VsdDxUTj4ge1xuICAgICAgICByZXR1cm4gY2IodGhpcy52YWx1ZSk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uRmFpbHVyZShfOiBGYWlsdXJlQ29udGludWF0aW9uPFQ+KTogUmVzdWx0PFQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgcHVibGljIHdpdGhGYWlsdXJlRGV0YWlsPFREPihfZGV0YWlsOiBURCk6IERldGFpbGVkUmVzdWx0PFQsIFREPiB7XG4gICAgICAgIHJldHVybiBzdWNjZWVkV2l0aERldGFpbCh0aGlzLnZhbHVlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgd2l0aERldGFpbDxURD4oZGV0YWlsOiBURCwgc3VjY2Vzc0RldGFpbD86IFREKTogRGV0YWlsZWRSZXN1bHQ8VCwgVEQ+IHtcbiAgICAgICAgcmV0dXJuIHN1Y2NlZWRXaXRoRGV0YWlsKHRoaXMudmFsdWUsIHN1Y2Nlc3NEZXRhaWwgPz8gZGV0YWlsKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBGYWlsdXJlPFQ+IGltcGxlbWVudHMgSVJlc3VsdDxUPiB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfbWVzc2FnZTogc3RyaW5nO1xuXG4gICAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuX21lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc1N1Y2Nlc3MoKTogdGhpcyBpcyBTdWNjZXNzPFQ+IHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc0ZhaWx1cmUoKTogdGhpcyBpcyBGYWlsdXJlPFQ+IHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBtZXNzYWdlKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tZXNzYWdlO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRWYWx1ZU9yVGhyb3cobG9nZ2VyPzogSVJlc3VsdExvZ2dlcik6IG5ldmVyIHtcbiAgICAgICAgaWYgKGxvZ2dlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IodGhpcy5fbWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKHRoaXMuX21lc3NhZ2UpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRWYWx1ZU9yRGVmYXVsdChkZmx0PzogVCk6IFR8dW5kZWZpbmVkIHtcbiAgICAgICAgcmV0dXJuIGRmbHQ7XG4gICAgfVxuXG4gICAgcHVibGljIG9uU3VjY2VzczxUTj4oXzogU3VjY2Vzc0NvbnRpbnVhdGlvbjxULCBUTj4pOiBSZXN1bHQ8VE4+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBGYWlsdXJlKHRoaXMubWVzc2FnZSk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uRmFpbHVyZShjYjogRmFpbHVyZUNvbnRpbnVhdGlvbjxUPik6IFJlc3VsdDxUPiB7XG4gICAgICAgIHJldHVybiBjYih0aGlzLm1lc3NhZ2UpO1xuICAgIH1cblxuICAgIHB1YmxpYyB3aXRoRmFpbHVyZURldGFpbDxURD4oZGV0YWlsOiBURCk6IERldGFpbGVkUmVzdWx0PFQsIFREPiB7XG4gICAgICAgIHJldHVybiBmYWlsV2l0aERldGFpbCh0aGlzLm1lc3NhZ2UsIGRldGFpbCk7XG4gICAgfVxuXG4gICAgcHVibGljIHdpdGhEZXRhaWw8VEQ+KGRldGFpbDogVEQsIF9zdWNjZXNzRGV0YWlsPzogVEQpOiBEZXRhaWxlZFJlc3VsdDxULCBURD4ge1xuICAgICAgICByZXR1cm4gZmFpbFdpdGhEZXRhaWwodGhpcy5tZXNzYWdlLCBkZXRhaWwpO1xuICAgIH1cblxuICAgIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5tZXNzYWdlO1xuICAgIH1cbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gZm9yIHN1Y2Nlc3NmdWwgcmV0dXJuXG4gKiBAcGFyYW0gdmFsIFRoZSB2YWx1ZSB0byBiZSByZXR1cm5lZFxuICovXG5leHBvcnQgZnVuY3Rpb24gc3VjY2VlZDxUPih2YWw6IFQpOiBTdWNjZXNzPFQ+IHtcbiAgICByZXR1cm4gbmV3IFN1Y2Nlc3M8VD4odmFsKTtcbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gZm9yIGVycm9yIHJldHVyblxuICogQHBhcmFtIG1lc3NhZ2UgRXJyb3IgbWVzc2FnZSB0byBiZSByZXR1cm5lZFxuICovXG5leHBvcnQgZnVuY3Rpb24gZmFpbDxUPihtZXNzYWdlOiBzdHJpbmcpOiBGYWlsdXJlPFQ+IHtcbiAgICByZXR1cm4gbmV3IEZhaWx1cmU8VD4obWVzc2FnZSk7XG59XG5cbmV4cG9ydCB0eXBlIERldGFpbGVkU3VjY2Vzc0NvbnRpbnVhdGlvbjxULCBURCwgVE4+ID0gKHZhbHVlOiBULCBkZXRhaWw/OiBURCkgPT4gRGV0YWlsZWRSZXN1bHQ8VE4sIFREPjtcbmV4cG9ydCB0eXBlIERldGFpbGVkRmFpbHVyZUNvbnRpbnVhdGlvbjxULCBURD4gPSAobWVzc2FnZTogc3RyaW5nLCBkZXRhaWw6IFREKSA9PiBEZXRhaWxlZFJlc3VsdDxULCBURD47XG5cbmV4cG9ydCBjbGFzcyBEZXRhaWxlZFN1Y2Nlc3M8VCwgVEQ+IGV4dGVuZHMgU3VjY2VzczxUPiB7XG4gICAgcHJvdGVjdGVkIF9kZXRhaWw/OiBURDtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcih2YWx1ZTogVCwgZGV0YWlsPzogVEQpIHtcbiAgICAgICAgc3VwZXIodmFsdWUpO1xuICAgICAgICB0aGlzLl9kZXRhaWwgPSBkZXRhaWw7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBkZXRhaWwoKTogVER8dW5kZWZpbmVkIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RldGFpbDtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNTdWNjZXNzKCk6IHRoaXMgaXMgRGV0YWlsZWRTdWNjZXNzPFQsIFREPiB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHB1YmxpYyBvblN1Y2Nlc3M8VE4+KGNiOiBEZXRhaWxlZFN1Y2Nlc3NDb250aW51YXRpb248VCwgVEQsIFROPik6IERldGFpbGVkUmVzdWx0PFROLCBURD4ge1xuICAgICAgICByZXR1cm4gY2IodGhpcy52YWx1ZSwgdGhpcy5fZGV0YWlsKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25GYWlsdXJlKF9jYjogRGV0YWlsZWRGYWlsdXJlQ29udGludWF0aW9uPFQsIFREPik6IERldGFpbGVkUmVzdWx0PFQsIFREPiB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cblxuLyoqXG4gKiBBIERldGFpbGVkRmFpbHVyZSByZXBvcnRzIG9wdGlvbmFsIGZhaWx1cmUgZGV0YWlscyBpbiBhZGRpdGlvblxuICogdG8gdGhlIHN0YW5kYXJkIGZhaWx1cmUgbWVzc2FnZS5cbiAqL1xuZXhwb3J0IGNsYXNzIERldGFpbGVkRmFpbHVyZTxULCBURD4gZXh0ZW5kcyBGYWlsdXJlPFQ+IHtcbiAgICBwcm90ZWN0ZWQgX2RldGFpbDogVEQ7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nLCBkZXRhaWw6IFREKSB7XG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgICAgICB0aGlzLl9kZXRhaWwgPSBkZXRhaWw7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBkZXRhaWwoKTogVEQge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGV0YWlsO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc0ZhaWx1cmUoKTogdGhpcyBpcyBEZXRhaWxlZEZhaWx1cmU8VCwgVEQ+IHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcHVibGljIG9uU3VjY2VzczxUTj4oX2NiOiBEZXRhaWxlZFN1Y2Nlc3NDb250aW51YXRpb248VCwgVEQsIFROPik6IERldGFpbGVkUmVzdWx0PFROLCBURD4ge1xuICAgICAgICByZXR1cm4gbmV3IERldGFpbGVkRmFpbHVyZTxUTiwgVEQ+KHRoaXMubWVzc2FnZSwgdGhpcy5fZGV0YWlsKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25GYWlsdXJlKGNiOiBEZXRhaWxlZEZhaWx1cmVDb250aW51YXRpb248VCwgVEQ+KTogRGV0YWlsZWRSZXN1bHQ8VCwgVEQ+IHtcbiAgICAgICAgcmV0dXJuIGNiKHRoaXMubWVzc2FnZSwgdGhpcy5fZGV0YWlsKTtcbiAgICB9XG59XG5cbmV4cG9ydCB0eXBlIERldGFpbGVkUmVzdWx0PFQsIFREPiA9IERldGFpbGVkU3VjY2VzczxULCBURD58RGV0YWlsZWRGYWlsdXJlPFQsIFREPjtcbmV4cG9ydCB0eXBlIFJlc3VsdERldGFpbFR5cGU8VD4gPSBUIGV4dGVuZHMgRGV0YWlsZWRSZXN1bHQ8dW5rbm93biwgaW5mZXIgVEQ+ID8gVEQgOiBuZXZlcjtcblxuZXhwb3J0IGZ1bmN0aW9uIHN1Y2NlZWRXaXRoRGV0YWlsPFQsIFREPih2YWx1ZTogVCwgZGV0YWlsPzogVEQpOiBEZXRhaWxlZFN1Y2Nlc3M8VCwgVEQ+IHtcbiAgICByZXR1cm4gbmV3IERldGFpbGVkU3VjY2VzczxULCBURD4odmFsdWUsIGRldGFpbCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmYWlsV2l0aERldGFpbDxULCBURD4obWVzc2FnZTogc3RyaW5nLCBkZXRhaWw6IFREKTogRGV0YWlsZWRGYWlsdXJlPFQsIFREPiB7XG4gICAgcmV0dXJuIG5ldyBEZXRhaWxlZEZhaWx1cmU8VCwgVEQ+KG1lc3NhZ2UsIGRldGFpbCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwcm9wYWdhdGVXaXRoRGV0YWlsPFQsIFREPihyZXN1bHQ6IFJlc3VsdDxUPiwgZGV0YWlsOiBURCwgc3VjY2Vzc0RldGFpbD86IFREKTogRGV0YWlsZWRSZXN1bHQ8VCwgVEQ+IHtcbiAgICByZXR1cm4gcmVzdWx0LmlzU3VjY2VzcygpXG4gICAgICAgID8gc3VjY2VlZFdpdGhEZXRhaWwocmVzdWx0LnZhbHVlLCBzdWNjZXNzRGV0YWlsID8/IGRldGFpbClcbiAgICAgICAgOiBmYWlsV2l0aERldGFpbChyZXN1bHQubWVzc2FnZSwgZGV0YWlsKTtcbn1cblxuLyoqXG4gKiBXcmFwcyBhIGZ1bmN0aW9uIHdoaWNoIHJldHVybnMgYSB2YWx1ZSBvZiB0eXBlIDxUPiBvciB0aHJvd3NcbiAqIHRvIHByb2R1Y2UgU3VjY2VzczxUPiBvciBGYWlsdXJlPFQ+XG4gKiBAcGFyYW0gZnVuYyBUaGUgbWV0aG9kIHRvIGJlIGNhcHR1cmVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYXB0dXJlUmVzdWx0PFQ+KGZ1bmM6ICgpID0+IFQpOiBSZXN1bHQ8VD4ge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBzdWNjZWVkKGZ1bmMoKSk7XG4gICAgfVxuICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIGZhaWwoKGVyciBhcyBFcnJvcikubWVzc2FnZSk7XG4gICAgfVxufVxuXG4vKipcbiAqIE1hcHMgYW4gYXJyYXkgb2YgUmVzdWx0PFQ+IHRvIGFuIGFycmF5IG9mIDxUPiwgaWYgYWxsIHJlc3VsdHMgYXJlXG4gKiBzdWNjZXNzZnVsLiAgSWYgYW55IHJlc3VsdHMgZmFpbCwgcmV0dXJucyBmYWlsdXJlIHdpdGggYSBjb25jYXRlbmF0ZWRcbiAqIHN1bW1hcnkgb2YgYWxsIGZhaWx1cmUgbWVzc2FnZXMuXG4gKiBAcGFyYW0gcmVzdWx0c0luIFRoZSByZXN1bHRzIHRvIGJlIG1hcHBlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcFJlc3VsdHM8VD4ocmVzdWx0c0luOiBJdGVyYWJsZTxSZXN1bHQ8VD4+KTogUmVzdWx0PFRbXT4ge1xuICAgIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBlbGVtZW50czogVFtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IHJlc3VsdCBvZiByZXN1bHRzSW4pIHtcbiAgICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSkge1xuICAgICAgICAgICAgZWxlbWVudHMucHVzaChyZXN1bHQudmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZXJyb3JzLnB1c2gocmVzdWx0Lm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiBmYWlsKGVycm9ycy5qb2luKCdcXG4nKSk7XG4gICAgfVxuICAgIHJldHVybiBzdWNjZWVkKGVsZW1lbnRzKTtcbn1cblxuLyoqXG4gKiBNYXBzIGFuIGFycmF5IG9mIERldGFpbGVkUmVzdWx0PFQsIFREPiB0byBhbiBhcnJheSBvZiA8VD4sIGlmIGFsbCByZXN1bHRzIGFyZVxuICogc3VjY2Vzc2Z1bCBvciB5aWVsZCBpZ25vcmFibGUgZXJyb3JzLiAgSWYgYW55IHJlc3VsdHMgZmFpbCB3aXRoIGFuIGVycm9yIHRoYXRcbiAqIGNhbm5vdCBiZSBpZ25vcmVkLCByZXR1cm5zIGZhaWx1cmUgd2l0aCBhIGNvbmNhdGVuYXRlZCBzdW1tYXJ5IG9mIGFsbCBmYWlsdXJlIG1lc3NhZ2VzLlxuICogQHBhcmFtIHJlc3VsdHNJbiBUaGUgcmVzdWx0cyB0byBiZSBtYXBwZWQuXG4gKiBAcGFyYW0gaWdub3JlIEVycm9yIGRldGFpbCB2YWx1ZXMgdGhhdCBzaG91bGQgYmUgaWdub3JlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFwRGV0YWlsZWRSZXN1bHRzPFQsIFREPihyZXN1bHRzSW46IEl0ZXJhYmxlPERldGFpbGVkUmVzdWx0PFQsIFREPj4sIGlnbm9yZTogVERbXSk6IFJlc3VsdDxUW10+IHtcbiAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgZWxlbWVudHM6IFRbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCByZXN1bHQgb2YgcmVzdWx0c0luKSB7XG4gICAgICAgIGlmIChyZXN1bHQuaXNTdWNjZXNzKCkpIHtcbiAgICAgICAgICAgIGVsZW1lbnRzLnB1c2gocmVzdWx0LnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghaWdub3JlLmluY2x1ZGVzKHJlc3VsdC5kZXRhaWwpKSB7XG4gICAgICAgICAgICBlcnJvcnMucHVzaChyZXN1bHQubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGZhaWwoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9XG4gICAgcmV0dXJuIHN1Y2NlZWQoZWxlbWVudHMpO1xufVxuXG4vKipcbiAqIE1hcHMgYW4gYXJyYXkgb2YgUmVzdWx0PFQ+IHRvIGFuIGFycmF5IG9mIDxUPiwgb21pdHRpbmcgYW55IGVycm9yXG4gKiByZXN1bHRzLiAgSWYgbm8gcmVzdWx0cyB3ZXJlIHN1Y2Nlc3NmdWwsIHJldHVybnMgZmFpbHVyZSB3aXRoIGFcbiAqIGNvbmNhdGVuYXRlZCBzdW1tYXJ5IG9mIGFsbCBmYWlsdXJlIG1lc3NhZ2VzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFwU3VjY2VzczxUPihyZXN1bHRzSW46IEl0ZXJhYmxlPFJlc3VsdDxUPj4pOiBSZXN1bHQ8VFtdPiB7XG4gICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IGVsZW1lbnRzOiBUW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3VsdHNJbikge1xuICAgICAgICBpZiAocmVzdWx0LmlzU3VjY2VzcygpKSB7XG4gICAgICAgICAgICBlbGVtZW50cy5wdXNoKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBlcnJvcnMucHVzaChyZXN1bHQubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoKGVsZW1lbnRzLmxlbmd0aCA9PT0gMCkgJiYgKGVycm9ycy5sZW5ndGggPiAwKSkge1xuICAgICAgICByZXR1cm4gZmFpbChlcnJvcnMuam9pbignXFxuJykpO1xuICAgIH1cbiAgICByZXR1cm4gc3VjY2VlZChlbGVtZW50cyk7XG59XG5cbi8qKlxuICogTWFwcyBhbiBhcnJheSBvZiBSZXN1bHQ8VD4gdG8gYW4gYXJyYXkgb2Ygc3RyaW5ncyBjb25zaXN0aW5nIG9mIGFsbFxuICogZXJyb3IgbWVzc2FnZXMgcmV0dXJuZWQgYnkgcmVzdWx0cyBpbiB0aGUgc291cmNlIGFycmF5LiBJZ25vcmVzXG4gKiBzdWNjZXNzIHJlc3VsdHMgYW5kIHJldHVybnMgYW4gZW1wdHkgYXJyYXkgaWYgdGhlcmUgd2VyZSBubyBlcnJvcnMuXG4gKiBAcGFyYW0gcmVzdWx0c0luIHJlc3VsdHMgdG8gYmUgcmVwb3J0ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcEZhaWx1cmVzPFQ+KHJlc3VsdHNJbjogSXRlcmFibGU8UmVzdWx0PFQ+Pik6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG4gICAgZm9yIChjb25zdCByZXN1bHQgb2YgcmVzdWx0c0luKSB7XG4gICAgICAgIGlmIChyZXN1bHQuaXNGYWlsdXJlKCkpIHtcbiAgICAgICAgICAgIGVycm9ycy5wdXNoKHJlc3VsdC5tZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZXJyb3JzO1xufVxuXG4vKipcbiAqIFJldHVybnMgc3VjY2VzcyB3aXRoIHRydWUgaWYgYWxsIHJlc3VsdHMgYXJlIHN1Y2Nlc3NmdWwuICBJZiBhbnkgYXJlIHVuc3VjY2Vzc2Z1bCxcbiAqIHJldHVybnMgZmFpbHVyZSB3aXRoIGEgY29uY2F0ZW5hdGVkIHN1bW1hcnkgb2YgYWxsIGZhaWx1cmUgbWVzc2FnZXMuXG4gKiBAcGFyYW0gcmVzdWx0cyBUaGUgcmVzdWx0cyB0byBiZSB0ZXN0ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbGxTdWNjZWVkPFQ+KHJlc3VsdHM6IEl0ZXJhYmxlPFJlc3VsdDx1bmtub3duPj4sIHN1Y2Nlc3NWYWx1ZTogVCk6IFJlc3VsdDxUPiB7XG4gICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gaXN0YW5idWwgaWdub3JlIGVsc2VcbiAgICBpZiAocmVzdWx0cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3VsdHMpIHtcbiAgICAgICAgICAgIGlmIChyZXN1bHQuaXNGYWlsdXJlKCkpIHtcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChyZXN1bHQubWVzc2FnZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGZhaWwoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9XG4gICAgcmV0dXJuIHN1Y2NlZWQoc3VjY2Vzc1ZhbHVlKTtcbn1cblxuZXhwb3J0IHR5cGUgRmllbGRJbml0aWFsaXplcnM8VD4gPSB7IFsga2V5IGluIGtleW9mIFQgXTogKHN0YXRlOiBQYXJ0aWFsPFQ+KSA9PiBSZXN1bHQ8VFtrZXldPiB9O1xuXG4vKipcbiAqIFBvcHVsYXRlcyBhbiBhbiBvYmplY3QgYmFzZWQgb24gYSBwcm90b3R5cGUgZnVsbCBvZiBmaWVsZCBpbml0aWFsaXplcnMgdGhhdCByZXR1cm4gUmVzdWx0PFRba2V5XT4uXG4gKiBSZXR1cm5zIHN1Y2Nlc3Mgd2l0aCB0aGUgcG9wdWxhdGVkIG9iamVjdCBpZiBhbGwgaW5pdGlhbGl6ZXJzIHN1Y2NlZWQsIG9yIGZhaWx1cmUgd2l0aCBhXG4gKiBjb25jYXRlbmF0ZWQgbGlzdCBvZiBhbGwgZmFpbHVyZSBtZXNzYWdlcy5cbiAqIEBwYXJhbSBpbml0aWFsaXplcnMgQW4gb2JqZWN0IHdpdGggdGhlIHNoYXBlIG9mIHRoZSB0YXJnZXQgYnV0IHdpdGggaW5pdGlhbGl6ZXIgZnVuY3Rpb25zIGZvclxuICogZWFjaCBwcm9wZXJ0eS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvcHVsYXRlT2JqZWN0PFQ+KGluaXRpYWxpemVyczogRmllbGRJbml0aWFsaXplcnM8VD4sIG9yZGVyPzogKGtleW9mIFQpW10pOiBSZXN1bHQ8VD4ge1xuICAgIGNvbnN0IHN0YXRlID0ge30gYXMgeyBba2V5IGluIGtleW9mIFRdOiBUW2tleV0gfTtcbiAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3Qga2V5czogKGtleW9mIFQpW10gPSBBcnJheS5mcm9tKG9yZGVyID8/IFtdKTtcbiAgICBjb25zdCBmb3VuZEtleXMgPSBuZXcgU2V0PGtleW9mIFQ+KG9yZGVyKTtcblxuICAgIC8vIHN0YXJ0IHdpdGggdGhlIHN1cHBsaWVkIG9yZGVyIHRoZW4gYXBwZW5kIGFueXRoaW5nIGVsc2Ugd2UgZmluZFxuICAgIGZvciAoY29uc3Qga2V5IGluIGluaXRpYWxpemVycykge1xuICAgICAgICBpZiAoIWZvdW5kS2V5cy5oYXMoa2V5KSkge1xuICAgICAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICAgICAgICBmb3VuZEtleXMuYWRkKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgICAgIGlmIChpbml0aWFsaXplcnNba2V5XSkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gaW5pdGlhbGl6ZXJzW2tleV0oc3RhdGUpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSkge1xuICAgICAgICAgICAgICAgIHN0YXRlW2tleV0gPSByZXN1bHQudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChyZXN1bHQubWVzc2FnZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBlcnJvcnMucHVzaChgcG9wdWxhdGVPYmplY3Q6IEtleSAke2tleX0gaXMgcHJlc2VudCBidXQgaGFzIG5vIGluaXRpYWxpemVyYCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGZhaWwoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9XG4gICAgcmV0dXJuIHN1Y2NlZWQoc3RhdGUgYXMgVCk7XG59XG4iXX0=
539
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdWx0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3Jlc3VsdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHOzs7QUF3SUg7Ozs7R0FJRztBQUNILE1BQWEsT0FBTztJQVVoQjs7O09BR0c7SUFDSCxZQUFZLEtBQVE7UUFicEI7O1dBRUc7UUFDYSxZQUFPLEdBQUcsSUFBSSxDQUFDO1FBVzNCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO0lBQ3hCLENBQUM7SUFFRDs7T0FFRztJQUNILElBQVcsS0FBSztRQUNaLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUN2QixDQUFDO0lBRUQ7O09BRUc7SUFDSSxTQUFTO1FBQ1osT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVEOztPQUVHO0lBQ0ksU0FBUztRQUNaLE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7SUFFRDs7T0FFRztJQUNJLGVBQWUsQ0FBQyxPQUF1QjtRQUMxQyxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDdkIsQ0FBQztJQUVEOztPQUVHO0lBQ0ksaUJBQWlCLENBQUMsSUFBUTs7UUFDN0IsT0FBTyxNQUFBLElBQUksQ0FBQyxNQUFNLG1DQUFJLElBQUksQ0FBQztJQUMvQixDQUFDO0lBRUQ7O09BRUc7SUFDSSxTQUFTLENBQUssRUFBOEI7UUFDL0MsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzFCLENBQUM7SUFFRDs7T0FFRztJQUNJLFNBQVMsQ0FBQyxDQUF5QjtRQUN0QyxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBRUQ7O09BRUc7SUFDSSxpQkFBaUIsQ0FBSyxPQUFXO1FBQ3BDLE9BQU8saUJBQWlCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRDs7T0FFRztJQUNJLFVBQVUsQ0FBSyxNQUFVLEVBQUUsYUFBa0I7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Z2h0IChjKSAyMDIwIEVyaWsgRm9ydHVuZVxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbiAqIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbiAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGxcbiAqIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4gKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRVxuICogU09GVFdBUkUuXG4gKi9cblxuLyogZXNsaW50LWRpc2FibGUgbm8tdXNlLWJlZm9yZS1kZWZpbmUgKi9cbi8qKlxuICogUmVwcmVzZW50cyB0aGUge0BsaW5rIElSZXN1bHQgfCByZXN1bHR9IG9mIHNvbWUgb3BlcmF0aW9uIG9yIHNlcXVlbmNlIG9mIG9wZXJhdGlvbnMuXG4gKiBAcmVtYXJrc1xuICoge0BsaW5rIFN1Y2Nlc3MgfCBTdWNjZXNzPFQ+fSBhbmQge0BsaW5rIEZhaWx1cmUgfCBGYWlsdXJlPFQ+fSBzaGFyZSB0aGUgY29tbW9uXG4gKiBjb250cmFjdCB7QGxpbmsgSVJlc3VsdH0sIGVuYWJsaW5nIGNvbWluZ2xlZCBkaXNjcmltaW5hdGVkIHVzYWdlLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgdHlwZSBSZXN1bHQ8VD4gPSBTdWNjZXNzPFQ+IHwgRmFpbHVyZTxUPjtcbi8qKlxuICogQ29udGludWF0aW9uIGNhbGxiYWNrIHRvIGJlIGNhbGxlZCBpbiB0aGUgZXZlbnQgdGhhdCBhblxuICoge0BsaW5rIFJlc3VsdH0gaXMgc3VjY2Vzc2Z1bC5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IHR5cGUgU3VjY2Vzc0NvbnRpbnVhdGlvbjxULCBUTj4gPSAodmFsdWU6IFQpID0+IFJlc3VsdDxUTj47XG4vKipcbiAqIENvbnRpbnVhdGlvbiBjYWxsYmFjayB0byBiZSBjYWxsZWQgaW4gdGhlIGV2ZW50IHRoYXQgYW5cbiAqIHtAbGluayBSZXN1bHR9IGZhaWxzLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgdHlwZSBGYWlsdXJlQ29udGludWF0aW9uPFQ+ID0gKG1lc3NhZ2U6IHN0cmluZykgPT4gUmVzdWx0PFQ+O1xuLyoqXG4gKiBUeXBlIGluZmVyZW5jZSB0byBkZXRlcm1pbmUgdGhlIHJlc3VsdCB0eXBlIG9mIGFuIHtAbGluayBSZXN1bHR9LlxuICogQGJldGFcbiAqL1xuZXhwb3J0IHR5cGUgUmVzdWx0VmFsdWVUeXBlPFQ+ID0gVCBleHRlbmRzIFJlc3VsdDxpbmZlciBUVj4gPyBUViA6IG5ldmVyO1xuXG4vKipcbiAqIFNpbXBsZSBsb2dnZXIgaW50ZXJmYWNlIHVzZWQgYnkge0BsaW5rIElSZXN1bHQuZ2V0VmFsdWVPclRocm93fS5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJUmVzdWx0TG9nZ2VyIHtcbiAgICAvKipcbiAgICAgKiBMb2cgYW4gZXJyb3IgbWVzc2FnZS5cbiAgICAgKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC5cbiAgICAgKi9cbiAgICBlcnJvcihtZXNzYWdlOiBzdHJpbmcpOiB2b2lkO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiBzb21lIG9wZXJhdGlvbiBvZiBzZXF1ZW5jZSBvZiBvcGVyYXRpb25zLlxuICogQHJlbWFya3NcbiAqIFRoaXMgY29tbW9uIGNvbnRyYWN0IGVuYWJsZXMgY29taW5nbGVkIGRpc2NyaW1pbmF0ZWQgdXNhZ2Ugb2Yge0BsaW5rIFN1Y2Nlc3MgfCBTdWNjZXNzPFQ+fVxuICogYW5kIHtAbGluayBGYWlsdXJlIHwgRmFpbHVyZTxUPn0uXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSVJlc3VsdDxUPiB7XG4gICAgLyoqXG4gICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bC5cbiAgICAgKi9cbiAgICByZWFkb25seSBzdWNjZXNzOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBvcGVyYXRpb24gd2FzIHN1Y2Nlc3NmdWwuICBGdW5jdGlvbnNcbiAgICAgKiBhcyBhIHR5cGUgZ3VhcmQgZm9yIHtAbGluayBTdWNjZXNzIHwgU3VjY2VzczxUPn0uXG4gICAgICovXG4gICAgaXNTdWNjZXNzKCk6IHRoaXMgaXMgU3VjY2VzczxUPjtcblxuICAgIC8qKlxuICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgb3BlcmF0aW9uIGZhaWxlZC4gIEZ1bmN0aW9uc1xuICAgICAqIGFzIGEgdHlwZSBndWFyZCBmb3Ige0BsaW5rIEZhaWx1cmUgfCBGYWlsdXJlPFQ+fS5cbiAgICAgKi9cbiAgICBpc0ZhaWx1cmUoKTogdGhpcyBpcyBGYWlsdXJlPFQ+O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIGEgc3VjY2Vzc2Z1bCB7QGxpbmsgSVJlc3VsdCB8IHJlc3VsdH0sXG4gICAgICogb3IgdGhyb3dzIHRoZSBlcnJvciBtZXNzYWdlIGlmIHRoZSBjb3JyZXNwb25kaW5nIG9wZXJhdGlvbiBmYWlsZWQuXG4gICAgICogQHBhcmFtIGxvZ2dlciAtIEFuIG9wdGlvbmFsIHtAbGluayBJUmVzdWx0TG9nZ2VyIHwgbG9nZ2VyfSB0byB3aGljaCB0aGVcbiAgICAgKiBlcnJvciB3aWxsIGFsc28gYmUgcmVwb3J0ZWQuXG4gICAgICogQHJldHVybnMgVGhlIHJldHVybiB2YWx1ZSwgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bC5cbiAgICAgKiBAdGhyb3dzIFRoZSBlcnJvciBtZXNzYWdlIGlmIHRoZSBvcGVyYXRpb24gZmFpbGVkLlxuICAgICAqL1xuICAgIGdldFZhbHVlT3JUaHJvdyhsb2dnZXI/OiBJUmVzdWx0TG9nZ2VyKTogVDtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCBhIHN1Y2Nlc3NmdWwge0BsaW5rIElSZXN1bHQgfCByZXN1bHR9LFxuICAgICAqIG9yIGEgZGVmYXVsdCB2YWx1ZSBpZiB0aGUgY29ycmVzcG9uZGluZyBvcGVyYXRpb24gZmFpbGVkLlxuICAgICAqIEBwYXJhbSBkZmx0IC0gVGhlIHZhbHVlIHRvIGJlIHJldHVybmVkIGlmIHRoZSBvcGVyYXRpb24gZmFpbGVkIChkZWZhdWx0IGlzXG4gICAgICogYHVuZGVmaW5lZGApLlxuICAgICAqIEByZXR1cm5zIFRoZSByZXR1cm4gdmFsdWUsIGlmIHRoZSBvcGVyYXRpb24gd2FzIHN1Y2Nlc3NmdWwuICBSZXR1cm5zXG4gICAgICogdGhlIHN1cHBsaWVkIGRlZmF1bHQgdmFsdWUgb3IgYHVuZGVmaW5lZGAgaWYgbm8gZGVmYXVsdCBpcyBzdXBwbGllZC5cbiAgICAgKi9cbiAgICBnZXRWYWx1ZU9yRGVmYXVsdChkZmx0PzogVCk6IFR8dW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQ2FsbHMgYSBzdXBwbGllZCB7QGxpbmsgU3VjY2Vzc0NvbnRpbnVhdGlvbiB8IHN1Y2Nlc3MgY29udGludWF0aW9ufSBpZlxuICAgICAqIHRoZSBvcGVyYXRpb24gd2FzIGEgc3VjY2Vzcy5cbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIFRoZSB7QGxpbmsgU3VjY2Vzc0NvbnRpbnVhdGlvbiB8IHN1Y2Nlc3MgY29udGludWF0aW9ufSBtaWdodCByZXR1cm4gYVxuICAgICAqIGRpZmZlcmVudCByZXN1bHQgdHlwZSB0aGFuIHtAbGluayBJUmVzdWx0fSBvbiB3aGljaCBpdCBpcyBpbnZva2VkLiBUaGlzXG4gICAgICogZW5hYmxlcyBjaGFpbmluZyBvZiBvcGVyYXRpb25zIHdpdGggaGV0ZXJvZ2Vub3VzIHJldHVybiB0eXBlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBjYiAtIFRoZSB7QGxpbmsgU3VjY2Vzc0NvbnRpbnVhdGlvbiB8IHN1Y2Nlc3MgY29udGludWF0aW9ufSB0b1xuICAgICAqIGJlIGNhbGxlZCBpbiB0aGUgZXZlbnQgb2Ygc3VjY2Vzcy5cbiAgICAgKiBAcmV0dXJucyBJZiB0aGlzIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCwgcmV0dXJucyB0aGUgdmFsdWUgcmV0dXJuZWRcbiAgICAgKiBieSB0aGUge0BsaW5rIFN1Y2Nlc3NDb250aW51YXRpb24gfCBzdWNjZXNzIGNvbnRpbnVhdGlvbn0uICBJZiB0aGlzIHJlc3VsdFxuICAgICAqIGZhaWxlZCwgcHJvcGFnYXRlcyB0aGUgZXJyb3IgbWVzc2FnZSBmcm9tIHRoaXMgZmFpbHVyZS5cbiAgICAgKi9cbiAgICBvblN1Y2Nlc3M8VE4+KGNiOiBTdWNjZXNzQ29udGludWF0aW9uPFQsIFROPik6IFJlc3VsdDxUTj47XG5cbiAgICAvKipcbiAgICAgKiBDYWxscyBhIHN1cHBsaWVkIHtAbGluayBGYWlsdXJlQ29udGludWF0aW9uIHwgZmFpbGVkIGNvbnRpbnVhdGlvbn0gaWZcbiAgICAgKiB0aGUgb3BlcmF0aW9uIGZhaWxlZC5cbiAgICAgKiBAcGFyYW0gY2IgLSBUaGUge0BsaW5rIEZhaWx1cmVDb250aW51YXRpb24gfCBmYWlsdXJlIGNvbnRpbnVhdGlvbn0gdG9cbiAgICAgKiBiZSBjYWxsZWQgaW4gdGhlIGV2ZW50IG9mIGZhaWx1cmUuXG4gICAgICogQHJldHVybnMgSWYgdGhpcyBvcGVyYXRpb24gZmFpbGVkLCByZXR1cm5zIHRoZSB2YWx1ZSByZXR1cm5lZCBieSB0aGVcbiAgICAgKiB7QGxpbmsgRmFpbHVyZUNvbnRpbnVhdGlvbiB8IGZhaWx1cmUgY29udGludWF0aW9ufS4gIElmIHRoaXMgcmVzdWx0XG4gICAgICogd2FzIHN1Y2Nlc3NmdWwsIHByb3BhZ2F0ZXMgdGhlIHJlc3VsdCB2YWx1ZSBmcm9tIHRoZSBzdWNjZXNzZnVsIGV2ZW50LlxuICAgICAqL1xuICAgIG9uRmFpbHVyZShjYjogRmFpbHVyZUNvbnRpbnVhdGlvbjxUPik6IFJlc3VsdDxUPjtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGEge0BsaW5rIElSZXN1bHQgfCBJUmVzdWx0PFQ+fSB0byBhIHtAbGluayBEZXRhaWxlZFJlc3VsdCB8IERldGFpbGVkUmVzdWx0PFQsIFREPn0sXG4gICAgICogYWRkaW5nIGEgc3VwcGxpZWQgZGV0YWlsIGlmIHRoZSBvcGVyYXRpb24gZmFpbGVkLlxuICAgICAqIEBwYXJhbSBkZXRhaWwgLSBUaGUgZGV0YWlsIHRvIGJlIGFkZGVkIGlmIHRoaXMgb3BlcmF0aW9uIGZhaWxlZC5cbiAgICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgRGV0YWlsZWRSZXN1bHQgfCBEZXRhaWxlZFJlc3VsdDxULCBURD59IHdpdGggZWl0aGVyXG4gICAgICogdGhlIHN1Y2Nlc3MgcmVzdWx0IG9yIHRoZSBlcnJvciBtZXNzYWdlIGZyb20gdGhpcyB7QGxpbmsgSVJlc3VsdH0sIHdpdGhcbiAgICAgKiB0aGUgc3VwcGxpZWQgZGV0YWlsIChpZiB0aGlzIGV2ZW50IGZhaWxlZCkgb3IgZGV0YWlsIGB1bmRlZmluZWRgIChpZlxuICAgICAqIHRoaXMgcmVzdWx0IHN1Y2NlZWRlZCkuXG4gICAgICovXG4gICAgd2l0aEZhaWx1cmVEZXRhaWw8VEQ+KGRldGFpbDogVEQpOiBEZXRhaWxlZFJlc3VsdDxULCBURD47XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBhIHtAbGluayBJUmVzdWx0IHwgSVJlc3VsdDxUPn0gdG8gYSB7QGxpbmsgRGV0YWlsZWRSZXN1bHQgfCBEZXRhaWxlZFJlc3VsdDxULCBURD59LFxuICAgICAqIGFkZGluZyBzdXBwbGllZCBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSBkZXRhaWwgLSBUaGUgZGVmYXVsdCBkZXRhaWwgdG8gYmUgYWRkZWQgdG8gdGhlIG5ldyB7QGxpbmsgRGV0YWlsZWRSZXN1bHR9LlxuICAgICAqIEBwYXJhbSBzdWNjZXNzRGV0YWlsIC0gQW4gb3B0aW9uYWwgZGV0YWlsIHRvIGJlIGFkZGVkIGlmIHRoaXMgcmVzdWx0IHdhcyBzdWNjZXNzZnVsLlxuICAgICAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBEZXRhaWxlZFJlc3VsdCB8IERldGFpbGVkUmVzdWx0PFQsIFREPn0gd2l0aCBlaXRoZXJcbiAgICAgKiB0aGUgc3VjY2VzcyByZXN1bHQgb3IgdGhlIGVycm9yIG1lc3NhZ2UgZnJvbSB0aGlzIHtAbGluayBJUmVzdWx0fSBhbmQgdGhlXG4gICAgICogYXBwb3ByaWF0ZSBhZGRlZCBkZXRhaWwuXG4gICAgICovXG4gICAgd2l0aERldGFpbDxURD4oZGV0YWlsOiBURCwgc3VjY2Vzc0RldGFpbD86IFREKTogRGV0YWlsZWRSZXN1bHQ8VCwgVEQ+O1xufVxuXG4vKipcbiAqIFJlcG9ydHMgYSBzdWNjZXNzZnVsIHtAbGluayBJUmVzdWx0IHwgcmVzdWx0fSBmcm9tIHNvbWUgb3BlcmF0aW9uIGFuZCB0aGVcbiAqIGNvcnJlc3BvbmRpbmcgdmFsdWUuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjbGFzcyBTdWNjZXNzPFQ+IGltcGxlbWVudHMgSVJlc3VsdDxUPiB7XG4gICAgLyoqXG4gICAgICoge0Bpbmhlcml0ZG9jIElSZXN1bHQuc3VjY2Vzc31cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgc3VjY2VzcyA9IHRydWU7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBfdmFsdWU6IFQ7XG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEge0BsaW5rIFN1Y2Nlc3N9IHdpdGggdGhlIHN1cHBsaWVkIHZhbHVlLlxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBiZSByZXR1cm5lZC5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih2YWx1ZTogVCkge1xuICAgICAgICB0aGlzLl92YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSByZXN1bHQgdmFsdWUgcmV0dXJuZWQgYnkgdGhlIHN1Y2Nlc3NmdWwgb3BlcmF0aW9uLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgdmFsdWUoKTogVCB7XG4gICAgICAgIHJldHVybiB0aGlzLl92YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB7QGluaGVyaXRkb2MgSVJlc3VsdC5pc1N1Y2Nlc3N9XG4gICAgICovXG4gICAgcHVibGljIGlzU3VjY2VzcygpOiB0aGlzIGlzIFN1Y2Nlc3M8VD4ge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB7QGluaGVyaXRkb2MgSVJlc3VsdC5pc0ZhaWx1cmV9XG4gICAgICovXG4gICAgcHVibGljIGlzRmFpbHVyZSgpOiB0aGlzIGlzIEZhaWx1cmU8VD4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICoge0Bpbmhlcml0ZG9jIElSZXN1bHQuZ2V0VmFsdWVPclRocm93fVxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRWYWx1ZU9yVGhyb3coX2xvZ2dlcj86IElSZXN1bHRMb2dnZXIpOiBUIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHtAaW5oZXJpdGRvYyBJUmVzdWx0LmdldFZhbHVlT3JEZWZhdWx0fVxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRWYWx1ZU9yRGVmYXVsdChkZmx0PzogVCk6IFR8dW5kZWZpbmVkIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlID8/IGRmbHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICoge0Bpbmhlcml0ZG9jIElSZXN1bHQub25TdWNjZXNzfVxuICAgICAqL1xuICAgIHB1YmxpYyBvblN1Y2Nlc3M8VE4+KGNiOiBTdWNjZXNzQ29udGludWF0aW9uPFQsIFROPik6IFJlc3VsdDxUTj4ge1xuICAgICAgICByZXR1cm4gY2IodGhpcy52YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICoge0Bpbmhlcml0ZG9jIElSZXN1bHQub25GYWlsdXJlfVxuICAgICAqL1xuICAgIHB1YmxpYyBvbkZhaWx1cmUoXzogRmFpbHVyZUNvbnRpbnVhdGlvbjxUPik6IFJlc3VsdDxUPiB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHtAaW5oZXJpdGRvYyBJUmVzdWx0LndpdGhGYWlsdXJlRGV0YWlsfVxuICAgICAqL1xuICAgIHB1YmxpYyB3aXRoRmFpbHVyZURldGFpbDxURD4oX2RldGFpbDogVEQpOiBEZXRhaWxlZFJlc3VsdDxULCBURD4ge1xuICAgICAgICByZXR1cm4gc3VjY2VlZFdpdGhEZXRhaWwodGhpcy52YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICoge0Bpbmhlcml0ZG9jIElSZXN1bHQud2l0aERldGFpbH1cbiAgICAgKi9cbiAgICBwdWJsaWMgd2l0aERldGFpbDxURD4oZGV0YWlsOiBURCwgc3VjY2Vzc0RldGFpbD86IFREKTogRGV0YWlsZWRSZXN1bHQ8VCwgVEQ+IHtcbiAgICAgICAgcmV0dXJuIHN1Y2NlZWRXaXRoRGV0YWlsKHRoaXMudmFsdWUsIHN1Y2Nlc3NEZXRhaWwgPz8gZGV0YWlsKTtcbiAgICB9XG59XG5cbi8qKlxuICogUmVwb3J0cyBhIGZhaWxlZCB7QGxpbmsgSVJlc3VsdCB8IHJlc3VsdH0gZnJvbSBzb21lIG9wZXJhdGlvbiwgd2l0aCBhbiBlcnJvciBtZXNzYWdlLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY2xhc3MgRmFpbHVyZTxUPiBpbXBsZW1lbnRzIElSZXN1bHQ8VD4ge1xuICAgIC8qKlxuICAgICAqIHtAaW5oZXJpdGRvYyBJUmVzdWx0LnN1Y2Nlc3N9XG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHN1Y2Nlc3MgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX21lc3NhZ2U6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSB7QGxpbmsgRmFpbHVyZX0gd2l0aCB0aGUgc3VwcGxpZWQgbWVzc2FnZS5cbiAgICAgKiBAcGFyYW0gbWVzc2FnZSAtIEVycm9yIG1lc3NhZ2UgdG8gYmUgcmVwb3J0ZWQuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuX21lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGVycm9yIG1lc3NhZ2UgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZXJyb3IuXG4gICAgICovXG4gICAgcHVibGljIGdldCBtZXNzYWdlKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tZXNzYWdlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHtAaW5oZXJpdGRvYyBJUmVzdWx0LmlzU3VjY2Vzc31cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNTdWNjZXNzKCk6IHRoaXMgaXMgU3VjY2VzczxUPiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB7QGluaGVyaXRkb2MgSVJlc3VsdC5pc0ZhaWx1cmV9XG4gICAgICovXG4gICAgcHVibGljIGlzRmFpbHVyZSgpOiB0aGlzIGlzIEZhaWx1cmU8VD4ge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB7QGluaGVyaXRkb2MgSVJlc3VsdC5nZXRWYWx1ZU9yVGhyb3d9XG4gICAgICovXG4gICAgcHVibGljIGdldFZhbHVlT3JUaHJvdyhsb2dnZXI/OiBJUmVzdWx0TG9nZ2VyKTogbmV2ZXIge1xuICAgICAgICBpZiAobG9nZ2VyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcih0aGlzLl9tZXNzYWdlKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IodGhpcy5fbWVzc2FnZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICoge0Bpbmhlcml0ZG9jIElSZXN1bHQuZ2V0VmFsdWVPckRlZmF1bHR9XG4gICAgICovXG4gICAgcHVibGljIGdldFZhbHVlT3JEZWZhdWx0KGRmbHQ/OiBUKTogVHx1bmRlZmluZWQge1xuICAgICAgICByZXR1cm4gZGZsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB7QGluaGVyaXRkb2MgSVJlc3VsdC5vblN1Y2Nlc3N9XG4gICAgICovXG4gICAgcHVibGljIG9uU3VjY2VzczxUTj4oXzogU3VjY2Vzc0NvbnRpbnVhdGlvbjxULCBUTj4pOiBSZXN1bHQ8VE4+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBGYWlsdXJlKHRoaXMubWVzc2FnZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICoge0Bpbmhlcml0ZG9jIElSZXN1bHQub25GYWlsdXJlfVxuICAgICAqL1xuICAgIHB1YmxpYyBvbkZhaWx1cmUoY2I6IEZhaWx1cmVDb250aW51YXRpb248VD4pOiBSZXN1bHQ8VD4ge1xuICAgICAgICByZXR1cm4gY2IodGhpcy5tZXNzYWdlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB7QGluaGVyaXRkb2MgSVJlc3VsdC53aXRoRmFpbHVyZURldGFpbH1cbiAgICAgKi9cbiAgICBwdWJsaWMgd2l0aEZhaWx1cmVEZXRhaWw8VEQ+KGRldGFpbDogVEQpOiBEZXRhaWxlZFJlc3VsdDxULCBURD4ge1xuICAgICAgICByZXR1cm4gZmFpbFdpdGhEZXRhaWwodGhpcy5tZXNzYWdlLCBkZXRhaWwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHtAaW5oZXJpdGRvYyBJUmVzdWx0LndpdGhEZXRhaWx9XG4gICAgICovXG4gICAgcHVibGljIHdpdGhEZXRhaWw8VEQ+KGRldGFpbDogVEQsIF9zdWNjZXNzRGV0YWlsPzogVEQpOiBEZXRhaWxlZFJlc3VsdDxULCBURD4ge1xuICAgICAgICByZXR1cm4gZmFpbFdpdGhEZXRhaWwodGhpcy5tZXNzYWdlLCBkZXRhaWwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBhICdmcmllbmRseScgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgb2JqZWN0LlxuICAgICAqIEByZW1hcmtzXG4gICAgICogVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHtAbGluayBGYWlsdXJlfSB2YWx1ZSBpcyB0aGUgZXJyb3IgbWVzc2FnZS5cbiAgICAgKiBAcmV0dXJucyBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhpcyBvYmplY3QuXG4gICAgICovXG4gICAgcHVibGljIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLm1lc3NhZ2U7XG4gICAgfVxufVxuXG4vKipcbiAqIFJldHVybnMge0BsaW5rIFN1Y2Nlc3MgfCBTdWNjZXNzPFQ+fSB3aXRoIHRoZSBzdXBwbGllZCByZXN1bHQgdmFsdWUuXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgc3VjY2Vzc2Z1bCByZXN1bHQgdmFsdWUgdG8gYmUgcmV0dXJuZWRcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN1Y2NlZWQ8VD4odmFsdWU6IFQpOiBTdWNjZXNzPFQ+IHtcbiAgICByZXR1cm4gbmV3IFN1Y2Nlc3M8VD4odmFsdWUpO1xufVxuXG4vKipcbiAqIFJldHVybnMge0BsaW5rIEZhaWx1cmUgfCBGYWlsdXJlPFQ+fSB3aXRoIHRoZSBzdXBwbGllZCBlcnJvciBtZXNzYWdlLlxuICogQHBhcmFtIG1lc3NhZ2UgLSBFcnJvciBtZXNzYWdlIHRvIGJlIHJldHVybmVkLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gZmFpbDxUPihtZXNzYWdlOiBzdHJpbmcpOiBGYWlsdXJlPFQ+IHtcbiAgICByZXR1cm4gbmV3IEZhaWx1cmU8VD4obWVzc2FnZSk7XG59XG5cbi8qKlxuICogQ2FsbGJhY2sgdG8gYmUgY2FsbGVkIHdoZW4gYSB7QGxpbmsgRGV0YWlsZWRSZXN1bHR9IGVuY291bnRlcnMgc3VjY2Vzcy5cbiAqIEByZW1hcmtzXG4gKiBBIHN1Y2Nlc3MgY2FsbGJhY2sgY2FuIHJldHVybiBhIGRpZmZlcmVudCByZXN1bHQgdHlwZSB0aGFuIGl0IHJlY2VpdmVzLCBhbGxvd2luZ1xuICogc3VjY2VzcyByZXN1bHRzIHRvIGNoYWluIHRocm91Z2ggaW50ZXJtZWRpYXRlIHJlc3VsdCB0eXBlcy5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IHR5cGUgRGV0YWlsZWRTdWNjZXNzQ29udGludWF0aW9uPFQsIFRELCBUTj4gPSAodmFsdWU6IFQsIGRldGFpbD86IFREKSA9PiBEZXRhaWxlZFJlc3VsdDxUTiwgVEQ+O1xuXG4vKipcbiAqIENhbGxiYWNrIHRvIGJlIGNhbGxlZCB3aGVuIGEge0BsaW5rIERldGFpbGVkUmVzdWx0fSBlbmNvdW50ZXJzIGEgZmFpbHVyZS5cbiAqIEByZW1hcmtzXG4gKiBBIGZhaWx1cmUgY2FsbGJhY2sgY2FuIGNoYW5nZSB7QGxpbmsgRmFpbHVyZX0gdG8ge0BsaW5rIFN1Y2Nlc3N9IChlLmcuIGJ5IHJldHVybmluZyBhIGRlZmF1bHQgdmFsdWUpXG4gKiBvciBpdCBjYW4gY2hhbmdlIG9yIGVtYmVsbGlzaCB0aGUgZXJyb3IgbWVzc2FnZSwgYnV0IGl0IGNhbm5vdCBjaGFuZ2UgdGhlIHN1Y2Nlc3MgcmV0dXJuIHR5cGUuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCB0eXBlIERldGFpbGVkRmFpbHVyZUNvbnRpbnVhdGlvbjxULCBURD4gPSAobWVzc2FnZTogc3RyaW5nLCBkZXRhaWw6IFREKSA9PiBEZXRhaWxlZFJlc3VsdDxULCBURD47XG5cbi8qKlxuICogQSB7QGxpbmsgRGV0YWlsZWRTdWNjZXNzfSBleHRlbmRzIHtAbGluayBTdWNjZXNzfSB0byByZXBvcnQgb3B0aW9uYWwgc3VjY2VzcyBkZXRhaWxzIGluXG4gKiBhZGRpdGlvbiB0byB0aGUgZXJyb3IgbWVzc2FnZS5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNsYXNzIERldGFpbGVkU3VjY2VzczxULCBURD4gZXh0ZW5kcyBTdWNjZXNzPFQ+IHtcbiAgICAvKipcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgX2RldGFpbD86IFREO1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGxpbmsgRGV0YWlsZWRTdWNjZXNzIHwgRGV0YWlsZWRTdWNjZXNzPFQsIFREPn0gd2l0aCB0aGUgc3VwcGxpZWRcbiAgICAgKiB2YWx1ZSBhbmQgZGV0YWlsLlxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBiZSByZXR1cm5lZC5cbiAgICAgKiBAcGFyYW0gZGV0YWlsIC0gQW4gb3B0aW9uYWwgc3VjY2Vzc2Z1bCBkZXRhaWwgdG8gYmUgcmV0dXJuZWQuICBJZiBvbWl0dGVkLCBkZXRhaWxcbiAgICAgKiB3aWxsIGJlIGB1bmRlZmluZWRgLlxuICAgICAqL1xuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcih2YWx1ZTogVCwgZGV0YWlsPzogVEQpIHtcbiAgICAgICAgc3VwZXIodmFsdWUpO1xuICAgICAgICB0aGlzLl9kZXRhaWwgPSBkZXRhaWw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIHN1Y2Nlc3MgZGV0YWlsIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHtAbGluayBEZXRhaWxlZFN1Y2Nlc3N9LCBvciBgdW5kZWZpbmVkYCBpZlxuICAgICAqIG5vIGRldGFpbCB3YXMgc3VwcGxpZWQuXG4gICAgICovXG4gICAgcHVibGljIGdldCBkZXRhaWwoKTogVER8dW5kZWZpbmVkIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RldGFpbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXBvcnRzIHRoYXQgdGhpcyB7QGxpbmsgRGV0YWlsZWRTdWNjZXNzfSBpcyBhIHN1Y2Nlc3MuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBBbHdheXMgdHJ1ZSBmb3Ige0BsaW5rIERldGFpbGVkU3VjY2Vzc30gYnV0IGNhbiBiZSB1c2VkIGFzIHR5cGUgZ3VhcmRcbiAgICAgKiB0byBkaXNjcmltaW5hdGUge0BsaW5rIERldGFpbGVkU3VjY2Vzc30gZnJvbSB7QGxpbmsgRGV0YWlsZWRGYWlsdXJlfSBpblxuICAgICAqIGEge0BsaW5rIERldGFpbGVkUmVzdWx0fS5cbiAgICAgKiBAcmV0dXJucyBgdHJ1ZWBcbiAgICAgKi9cbiAgICBwdWJsaWMgaXNTdWNjZXNzKCk6IHRoaXMgaXMgRGV0YWlsZWRTdWNjZXNzPFQsIFREPiB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludm9rZXMgdGhlIHN1cHBsaWVkIHtAbGluayBEZXRhaWxlZFN1Y2Nlc3NDb250aW51YXRpb24gfCBzdWNjZXNzIGNhbGxiYWNrfSBhbmQgcHJvcGFnYXRlc1xuICAgICAqIGl0cyByZXR1cm5lZCB7QGxpbmsgRGV0YWlsZWRSZXN1bHQgfCBEZXRhaWxlZFJlc3VsdDxUTiwgVEQ+fS5cbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIFRoZSBzdWNjZXNzIGNhbGxiYWNrIG11dGF0ZXMgdGhlIHJldHVybiB0eXBlIGZyb20gYDxUPmAgdG8gYDxUTj5gLlxuICAgICAqIEBwYXJhbSBjYiAtIFRoZSB7QGxpbmsgRGV0YWlsZWRTdWNjZXNzQ29udGludWF0aW9uIHwgc3VjY2VzcyBjYWxsYmFja30gdG8gYmUgaW52b2tlZC5cbiAgICAgKiBAcmV0dXJucyBUaGUge0BsaW5rIERldGFpbGVkUmVzdWx0IHwgRGV0YWlsZWRSZXN1bHQ8VCwgVEQ+fSByZXR1cm5lZCBieSB0aGUgc3VjY2VzcyBjYWxsYmFjay5cbiAgICAgKi9cbiAgICBwdWJsaWMgb25TdWNjZXNzPFROPihjYjogRGV0YWlsZWRTdWNjZXNzQ29udGludWF0aW9uPFQsIFRELCBUTj4pOiBEZXRhaWxlZFJlc3VsdDxUTiwgVEQ+IHtcbiAgICAgICAgcmV0dXJuIGNiKHRoaXMudmFsdWUsIHRoaXMuX2RldGFpbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJvcGFnYXRlcyB0aGlzIHtAbGluayBEZXRhaWxlZFN1Y2Nlc3N9LlxuICAgICAqIEByZW1hcmtzXG4gICAgICogRmFpbHVyZSBkb2VzIG5vdCBtdXRhdGUgcmV0dXJuIHR5cGUgc28gd2UgY2FuIHJldHVybiB0aGlzIGV2ZW50IGRpcmVjdGx5LlxuICAgICAqIEBwYXJhbSBfY2IgLSB7QGxpbmsgRGV0YWlsZWRGYWlsdXJlQ29udGludWF0aW9uIHwgRmFpbHVyZSBjYWxsYmFja30gdG8gYmUgY2FsbGVkXG4gICAgICogb24gYSB7QGxpbmsgRGV0YWlsZWRSZXN1bHR9IGluIGNhc2Ugb2YgZmFpbHVyZSAoaWdub3JlZCkuXG4gICAgICogQHJldHVybnMgYHRoaXNgXG4gICAgICovXG4gICAgcHVibGljIG9uRmFpbHVyZShfY2I6IERldGFpbGVkRmFpbHVyZUNvbnRpbnVhdGlvbjxULCBURD4pOiBEZXRhaWxlZFJlc3VsdDxULCBURD4ge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5cbi8qKlxuICogQSB7QGxpbmsgRGV0YWlsZWRGYWlsdXJlfSBleHRlbmRzIHtAbGluayBGYWlsdXJlfSB0byByZXBvcnQgb3B0aW9uYWwgZmFpbHVyZSBkZXRhaWxzIGluXG4gKiBhZGRpdGlvbiB0byB0aGUgZXJyb3IgbWVzc2FnZS5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNsYXNzIERldGFpbGVkRmFpbHVyZTxULCBURD4gZXh0ZW5kcyBGYWlsdXJlPFQ+IHtcbiAgICAvKipcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgX2RldGFpbDogVEQ7XG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAbGluayBEZXRhaWxlZEZhaWx1cmUgfCBEZXRhaWxlZEZhaWx1cmU8VCwgVEQ+fSB3aXRoIHRoZSBzdXBwbGllZFxuICAgICAqIG1lc3NhZ2UgYW5kIGRldGFpbC5cbiAgICAgKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGJlIHJldHVybmVkLlxuICAgICAqIEBwYXJhbSBkZXRhaWwgLSBUaGUgZXJyb3IgZGV0YWlsIHRvIGJlIHJldHVybmVkLlxuICAgICAqL1xuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcsIGRldGFpbDogVEQpIHtcbiAgICAgICAgc3VwZXIobWVzc2FnZSk7XG4gICAgICAgIHRoaXMuX2RldGFpbCA9IGRldGFpbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZXJyb3IgZGV0YWlsIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHtAbGluayBEZXRhaWxlZEZhaWx1cmV9LlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgZGV0YWlsKCk6IFREIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RldGFpbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXBvcnRzIHRoYXQgdGhpcyB7QGxpbmsgRGV0YWlsZWRGYWlsdXJlfSBpcyBhIGZhaWx1cmUuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBBbHdheXMgdHJ1ZSBmb3Ige0BsaW5rIERldGFpbGVkRmFpbHVyZX0gYnV0IGNhbiBiZSB1c2VkIGFzIHR5cGUgZ3VhcmRcbiAgICAgKiB0byBkaXNjcmltaW5hdGUge0BsaW5rIERldGFpbGVkU3VjY2Vzc30gZnJvbSB7QGxpbmsgRGV0YWlsZWRGYWlsdXJlfSBpblxuICAgICAqIGEge0BsaW5rIERldGFpbGVkUmVzdWx0fS5cbiAgICAgKiBAcmV0dXJucyBgdHJ1ZWBcbiAgICAgKi9cbiAgICBwdWJsaWMgaXNGYWlsdXJlKCk6IHRoaXMgaXMgRGV0YWlsZWRGYWlsdXJlPFQsIFREPiB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByb3BhZ2F0ZXMgdGhlIGVycm9yIG1lc3NhZ2UgYW5kIGRldGFpbCBmcm9tIHRoaXMgcmVzdWx0LlxuICAgICAqIEByZW1hcmtzXG4gICAgICogTXV0YXRlcyB0aGUgc3VjY2VzcyB0eXBlIGFzIHRoZSBzdWNjZXNzIGNhbGxiYWNrIHdvdWxkIGhhdmUsIGJ1dCBkb2VzIG5vdFxuICAgICAqIGNhbGwgdGhlIHN1Y2Nlc3MgY2FsbGJhY2suXG4gICAgICogQHBhcmFtIF9jYiAtIHtAbGluayBEZXRhaWxlZFN1Y2Nlc3NDb250aW51YXRpb24gfCBTdWNjZXNzIGNhbGxiYWNrfSB0byBiZSBjYWxsZWRcbiAgICAgKiBvbiBhIHtAbGluayBEZXRhaWxlZFJlc3VsdH0gaW4gY2FzZSBvZiBzdWNjZXNzIChpZ25vcmVkKS5cbiAgICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgRGV0YWlsZWRGYWlsdXJlIHwgRGV0YWlsZWRGYWlsdXJlPFROLCBURD59IHdoaWNoIGNvbnRhaW5zXG4gICAgICogdGhlIGVycm9yIG1lc3NhZ2UgYW5kIGRldGFpbCBmcm9tIHRoaXMgb25lLlxuICAgICAqL1xuICAgIHB1YmxpYyBvblN1Y2Nlc3M8VE4+KF9jYjogRGV0YWlsZWRTdWNjZXNzQ29udGludWF0aW9uPFQsIFRELCBUTj4pOiBEZXRhaWxlZFJlc3VsdDxUTiwgVEQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBEZXRhaWxlZEZhaWx1cmU8VE4sIFREPih0aGlzLm1lc3NhZ2UsIHRoaXMuX2RldGFpbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW52b2tlcyB0aGUgc3VwcGxpZWQge0BsaW5rIERldGFpbGVkRmFpbHVyZUNvbnRpbnVhdGlvbiB8IGZhaWx1cmUgY2FsbGJhY2t9IGFuZCBwcm9wYWdhdGVzXG4gICAgICogaXRzIHJldHVybmVkIHtAbGluayBEZXRhaWxlZFJlc3VsdCB8IERldGFpbGVkUmVzdWx0PFQsIFREPn0uXG4gICAgICogQHBhcmFtIGNiIC0gVGhlIHtAbGluayBEZXRhaWxlZEZhaWx1cmVDb250aW51YXRpb24gfCBmYWlsdXJlIGNhbGxiYWNrfSB0byBiZSBpbnZva2VkLlxuICAgICAqIEByZXR1cm5zIFRoZSB7QGxpbmsgRGV0YWlsZWRSZXN1bHQgfCBEZXRhaWxlZFJlc3VsdDxULCBURD59IHJldHVybmVkIGJ5IHRoZSBmYWlsdXJlIGNhbGxiYWNrLlxuICAgICAqL1xuICAgIHB1YmxpYyBvbkZhaWx1cmUoY2I6IERldGFpbGVkRmFpbHVyZUNvbnRpbnVhdGlvbjxULCBURD4pOiBEZXRhaWxlZFJlc3VsdDxULCBURD4ge1xuICAgICAgICByZXR1cm4gY2IodGhpcy5tZXNzYWdlLCB0aGlzLl9kZXRhaWwpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBUeXBlIGluZmVyZW5jZSB0byBkZXRlcm1pbmUgdGhlIHJlc3VsdCB0eXBlIGBUYCBvZiBhIHtAbGluayBEZXRhaWxlZFJlc3VsdCB8IERldGFpbGVkUmVzdWx0PFQsIFREPn0uXG4gKiBAYmV0YVxuICovXG5leHBvcnQgdHlwZSBEZXRhaWxlZFJlc3VsdDxULCBURD4gPSBEZXRhaWxlZFN1Y2Nlc3M8VCwgVEQ+fERldGFpbGVkRmFpbHVyZTxULCBURD47XG5cbi8qKlxuICogVHlwZSBpbmZlcmVuY2UgdG8gZGV0ZXJtaW5lIHRoZSBkZXRhaWwgdHlwZSBgVERgIG9mIGEge0BsaW5rIERldGFpbGVkUmVzdWx0IHwgRGV0YWlsZWRSZXN1bHQ8VCwgVEQ+fS5cbiAqIEBiZXRhXG4gKi9cbmV4cG9ydCB0eXBlIFJlc3VsdERldGFpbFR5cGU8VD4gPSBUIGV4dGVuZHMgRGV0YWlsZWRSZXN1bHQ8dW5rbm93biwgaW5mZXIgVEQ+ID8gVEQgOiBuZXZlcjtcblxuLyoqXG4gKiBSZXR1cm5zIHtAbGluayBEZXRhaWxlZFN1Y2Nlc3MgfCBEZXRhaWxlZFN1Y2Nlc3M8VCwgVEQ+fSB3aXRoIGEgc3VwcGxpZWQgdmFsdWUgYW5kIG9wdGlvbmFsXG4gKiBkZXRhaWwuXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgb2YgdHlwZSBgPFQ+YCB0byBiZSByZXR1cm5lZC5cbiAqIEBwYXJhbSBkZXRhaWwgLSBBbiBvcHRpb25hbCBkZXRhaWwgb2YgdHlwZSBgPFREPmAgdG8gYmUgcmV0dXJuZWQuXG4gKiBAcmV0dXJucyBBIHtAbGluayBEZXRhaWxlZFN1Y2Nlc3MgfCBEZXRhaWxlZFN1Y2Nlc3M8VCwgVEQ+fSB3aXRoIHRoZSBzdXBwbGllZCB2YWx1ZVxuICogYW5kIGRldGFpbCwgaWYgc3VwcGxpZWQuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdWNjZWVkV2l0aERldGFpbDxULCBURD4odmFsdWU6IFQsIGRldGFpbD86IFREKTogRGV0YWlsZWRTdWNjZXNzPFQsIFREPiB7XG4gICAgcmV0dXJuIG5ldyBEZXRhaWxlZFN1Y2Nlc3M8VCwgVEQ+KHZhbHVlLCBkZXRhaWwpO1xufVxuXG4vKipcbiAqIFJldHVybnMge0BsaW5rIERldGFpbGVkRmFpbHVyZSB8IERldGFpbGVkRmFpbHVyZTxULCBURD59IHdpdGggYSBzdXBwbGllZCBlcnJvciBtZXNzYWdlIGFuZCBkZXRhaWwuXG4gKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBlcnJvciBtZXNzYWdlIHRvIGJlIHJldHVybmVkLlxuICogQHBhcmFtIGRldGFpbCAtIFRoZSBldmVudCBkZXRhaWwgdG8gYmUgcmV0dXJuZWQuXG4gKiBAcmV0dXJucyBBbiB7QGxpbmsgRGV0YWlsZWRGYWlsdXJlIHwgRGV0YWlsZWRGYWlsdXJlPFQsIFREPn0gd2l0aCB0aGUgc3VwcGxpZWQgZXJyb3JcbiAqIG1lc3NhZ2UgYW5kIGRldGFpbC5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZhaWxXaXRoRGV0YWlsPFQsIFREPihtZXNzYWdlOiBzdHJpbmcsIGRldGFpbDogVEQpOiBEZXRhaWxlZEZhaWx1cmU8VCwgVEQ+IHtcbiAgICByZXR1cm4gbmV3IERldGFpbGVkRmFpbHVyZTxULCBURD4obWVzc2FnZSwgZGV0YWlsKTtcbn1cblxuLyoqXG4gKiBQcm9wYWdhdGVzIGEge0BsaW5rIFN1Y2Nlc3N9IG9yIHtAbGluayBGYWlsdXJlfSB7QGxpbmsgUmVzdWx0fSwgYWRkaW5nIHN1cHBsaWVkXG4gKiBldmVudCBkZXRhaWxzIGFzIGFwcHJvcHJpYXRlLlxuICogQHBhcmFtIHJlc3VsdCAtIFRoZSB7QGxpbmsgUmVzdWx0fSB0byBiZSBwcm9wYWdhdGVkLlxuICogQHBhcmFtIGRldGFpbCAtIFRoZSBldmVudCBkZXRhaWwgKHR5cGUgYDxURD5gKSB0byBiZSBhZGRlZCB0byB0aGUge0BsaW5rIFJlc3VsdCB8IHJlc3VsdH0uXG4gKiBAcGFyYW0gc3VjY2Vzc0RldGFpbCAtIEFuIG9wdGlvbmFsIGRpc3RpbmN0IGV2ZW50IGRldGFpbCB0byBiZSBhZGRlZCB0byB7QGxpbmsgU3VjY2Vzc30gcmVzdWx0cy4gIElmIGBzdWNjZXNzRGV0YWlsYFxuICogaXMgb21pdHRlZCBvciBgdW5kZWZpbmVkYCwgdGhlbiBgZGV0YWlsYCB3aWxsIGJlIGFwcGxpZWQgdG8ge0BsaW5rIFN1Y2Nlc3N9IHJlc3VsdHMuXG4gKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgRGV0YWlsZWRSZXN1bHQgfCBEZXRhaWxlZFJlc3VsdDxULCBURD59IHdpdGggdGhlIHN1Y2Nlc3MgdmFsdWUgb3IgZXJyb3JcbiAqIG1lc3NhZ2UgZnJvbSB0aGUgb3JpZ2luYWwgYHJlc3VsdGAgYnV0IHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWwgYWRkZWQuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm9wYWdhdGVXaXRoRGV0YWlsPFQsIFREPihyZXN1bHQ6IFJlc3VsdDxUPiwgZGV0YWlsOiBURCwgc3VjY2Vzc0RldGFpbD86IFREKTogRGV0YWlsZWRSZXN1bHQ8VCwgVEQ+IHtcbiAgICByZXR1cm4gcmVzdWx0LmlzU3VjY2VzcygpXG4gICAgICAgID8gc3VjY2VlZFdpdGhEZXRhaWwocmVzdWx0LnZhbHVlLCBzdWNjZXNzRGV0YWlsID8/IGRldGFpbClcbiAgICAgICAgOiBmYWlsV2l0aERldGFpbChyZXN1bHQubWVzc2FnZSwgZGV0YWlsKTtcbn1cblxuLyoqXG4gKiBXcmFwcyBhIGZ1bmN0aW9uIHdoaWNoIG1pZ2h0IHRocm93IHRvIGNvbnZlcnQgZXhjZXB0aW9uIHJlc3VsdHNcbiAqIHRvIHtAbGluayBGYWlsdXJlfS5cbiAqIEBwYXJhbSBmdW5jIC0gVGhlIGZ1bmN0aW9uIHRvIGJlIGNhcHR1cmVkLlxuICogQHJldHVybnMgUmV0dXJucyB7QGxpbmsgU3VjY2Vzc30gd2l0aCBhIHZhbHVlIG9mIHR5cGUgYDxUPmAgb25cbiAqIHN1Y2Nlc3MgLCBvciB7QGxpbmsgRmFpbHVyZX0gd2l0aCB0aGUgdGhyb3duIGVycm9yIG1lc3NhZ2UgaWZcbiAqIGBmdW5jYCB0aHJvd3MgYW4gYEVycm9yYC5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhcHR1cmVSZXN1bHQ8VD4oZnVuYzogKCkgPT4gVCk6IFJlc3VsdDxUPiB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHN1Y2NlZWQoZnVuYygpKTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICByZXR1cm4gZmFpbCgoZXJyIGFzIEVycm9yKS5tZXNzYWdlKTtcbiAgICB9XG59XG5cbi8qKlxuICogQWdncmVnYXRlcyBzdWNlc3NmdWwgcmVzdWx0IHZhbHVlcyBmcm9tIGEgY29sbGVjdGlvbiBvZiB7QGxpbmsgUmVzdWx0IHwgUmVzdWx0PFQ+fS5cbiAqIEBwYXJhbSByZXN1bHRzIC0gVGhlIGNvbGxlY3Rpb24gb2Yge0BsaW5rIFJlc3VsdCB8IFJlc3VsdDxUPn0gdG8gYmUgbWFwcGVkLlxuICogQHJldHVybnMgIElmIGFsbCB7QGxpbmsgUmVzdWx0IHwgcmVzdWx0c30gYXJlIHN1Y2Nlc3NmdWwsIHJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggYW5cbiAqIGFycmF5IGNvbnRhaW5pbmcgYWxsIHJldHVybmVkIHZhbHVlcy4gIElmIGFueSB7QGxpbmsgUmVzdWx0IHwgcmVzdWx0c30gZmFpbGVkLCByZXR1cm5zXG4gKiB7QGxpbmsgRmFpbHVyZX0gd2l0aCBhIGNvbmNhdGVuYXRlZCBzdW1tYXJ5IG9mIGFsbCBlcnJvciBtZXNzYWdlcy5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcFJlc3VsdHM8VD4ocmVzdWx0czogSXRlcmFibGU8UmVzdWx0PFQ+Pik6IFJlc3VsdDxUW10+IHtcbiAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgZWxlbWVudHM6IFRbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCByZXN1bHQgb2YgcmVzdWx0cykge1xuICAgICAgICBpZiAocmVzdWx0LmlzU3VjY2VzcygpKSB7XG4gICAgICAgICAgICBlbGVtZW50cy5wdXNoKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBlcnJvcnMucHVzaChyZXN1bHQubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGZhaWwoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9XG4gICAgcmV0dXJuIHN1Y2NlZWQoZWxlbWVudHMpO1xufVxuXG4vKipcbiAqIEFnZ3JlZ2F0ZXMgc3VjZXNzZnVsIHJlc3VsdHMgZnJvbSBhIGNvbGxlY3Rpb24gb2Yge0BsaW5rIERldGFpbGVkUmVzdWx0IHwgRGV0YWlsZWRSZXN1bHQ8VCwgVEQ+fSxcbiAqIG9wdGlvbmFsbHkgaWdub3JpbmcgY2VydGFpbiBlcnJvciBkZXRhaWxzLlxuICogQHBhcmFtIHJlc3VsdHMgLSBUaGUgY29sbGVjdGlvbiBvZiB7QGxpbmsgRGV0YWlsZWRSZXN1bHQgfCBEZXRhaWxlZFJlc3VsdDxULCBURD59IHRvIGJlIG1hcHBlZC5cbiAqIEBwYXJhbSBpZ25vcmUgLSBBbiBhcnJheSBvZiBlcnJvciBkZXRhaWwgdmFsdWVzIChvZiB0eXBlIGA8VEQ+YCkgdGhhdCBzaG91bGQgYmUgaWdub3JlZC5cbiAqIEByZXR1cm5zIHtAbGluayBTdWNjZXNzfSB3aXRoIGFuIGFycmF5IGNvbnRhaW5pbmcgYWxsIHN1Y2Nlc3NmdWwgcmVzdWx0cyBpZiBhbGwgcmVzdWx0cyBlaXRoZXJcbiAqIHN1Y2VlZGVkIG9yIHJldHVybmVkIGVycm9yIGRldGFpbHMgbGlzdGVkIGluIGBpZ25vcmVgLiAgSWYgYW55IHJlc3VsdHMgZmFpbGVkIHdpdGggZGV0YWlsc1xuICogdGhhdCBjYW5ub3QgYmUgaWdub3JlZCwgcmV0dXJucyB7QGxpbmsgRmFpbHVyZX0gd2l0aCBhbiBjb25jYXRlbmF0ZWQgc3VtbWFyeSBvZiBhbGwgbm9uLWlnbm9yYWJsZVxuICogZXJyb3IgbWVzYXNnZXMuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXBEZXRhaWxlZFJlc3VsdHM8VCwgVEQ+KHJlc3VsdHM6IEl0ZXJhYmxlPERldGFpbGVkUmVzdWx0PFQsIFREPj4sIGlnbm9yZTogVERbXSk6IFJlc3VsdDxUW10+IHtcbiAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgZWxlbWVudHM6IFRbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCByZXN1bHQgb2YgcmVzdWx0cykge1xuICAgICAgICBpZiAocmVzdWx0LmlzU3VjY2VzcygpKSB7XG4gICAgICAgICAgICBlbGVtZW50cy5wdXNoKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIWlnbm9yZS5pbmNsdWRlcyhyZXN1bHQuZGV0YWlsKSkge1xuICAgICAgICAgICAgZXJyb3JzLnB1c2gocmVzdWx0Lm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiBmYWlsKGVycm9ycy5qb2luKCdcXG4nKSk7XG4gICAgfVxuICAgIHJldHVybiBzdWNjZWVkKGVsZW1lbnRzKTtcbn1cblxuLyoqXG4gKiBBZ2dyZWdhdGVzIHN1Y2Nlc3NmdWwgcmVzdWx0cyBmcm9tIGEgYSBjb2xsZWN0aW9uIG9mIHtAbGluayBSZXN1bHQgfCBSZXN1bHQ8VD59LlxuICogQHBhcmFtIHJlc3VsdHMgLSBBbiBgSXRlcmFibGVgIG9mIHtAbGluayBSZXN1bHQgfCBSZXN1bHQ8VD59IGZyb20gd2hpY2ggc3VjY2Vzc1xuICogcmVzdWx0cyBhcmUgdG8gYmUgYWdncmVnYXRlZC5cbiAqIEByZXR1cm5zIHtAbGluayBTdWNjZXNzfSB3aXRoIGFuIGFycmF5IG9mIGA8VD5gIGlmIGFueSByZXN1bHRzIHdlcmUgc3VjY2Vzc2Z1bC4gSWZcbiAqIGFsbCB7QGxpbmsgUmVzdWx0IHwgcmVzdWx0c30gZmFpbGVkLCByZXR1cm5zIHtAbGluayBGYWlsdXJlfSB3aXRoIGEgY29uY2F0ZW5hdGVkXG4gKiBzdW1tYXJ5IG9mIGFsbCBlcnJvciBtZXNzYWdlcy5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcFN1Y2Nlc3M8VD4ocmVzdWx0czogSXRlcmFibGU8UmVzdWx0PFQ+Pik6IFJlc3VsdDxUW10+IHtcbiAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgZWxlbWVudHM6IFRbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCByZXN1bHQgb2YgcmVzdWx0cykge1xuICAgICAgICBpZiAocmVzdWx0LmlzU3VjY2VzcygpKSB7XG4gICAgICAgICAgICBlbGVtZW50cy5wdXNoKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBlcnJvcnMucHVzaChyZXN1bHQubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoKGVsZW1lbnRzLmxlbmd0aCA9PT0gMCkgJiYgKGVycm9ycy5sZW5ndGggPiAwKSkge1xuICAgICAgICByZXR1cm4gZmFpbChlcnJvcnMuam9pbignXFxuJykpO1xuICAgIH1cbiAgICByZXR1cm4gc3VjY2VlZChlbGVtZW50cyk7XG59XG5cbi8qKlxuICogQWdncmVnYXRlcyBlcnJvciBtZXNzYWdlcyBmcm9tIGEgY29sbGVjdGlvbiBvZiB7QGxpbmsgUmVzdWx0IHwgUmVzdWx0PFQ+fS5cbiAqIEBwYXJhbSByZXN1bHRzIC0gQW4gaW50ZXJhYmxlIGNvbGxlY3Rpb24gb2Yge0BsaW5rIFJlc3VsdCB8IFJlc3VsdDxUPn0gZm9yIHdoaWNoXG4gKiBlcnJvciBtZXNzYWdlcyBhcmUgYWdncmVnYXRlZC5cbiAqIEByZXR1cm5zIEFuIGFycmF5IG9mIHN0cmluZ3MgY29uc2lzdGluZyBvZiBhbGwgZXJyb3IgbWVzc2FnZXMgcmV0dXJuZWQgYnlcbiAqIHtAbGluayBSZXN1bHQgfCByZXN1bHRzfSBpbiB0aGUgc291cmNlIGNvbGxlY3Rpb24uIElnbm9yZXMge0BsaW5rIFN1Y2Nlc3N9XG4gKiByZXN1bHRzIGFuZCByZXR1cm5zIGFuIGVtcHR5IGFycmF5IGlmIHRoZXJlIHdlcmUgbm8gZXJyb3JzLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWFwRmFpbHVyZXM8VD4ocmVzdWx0czogSXRlcmFibGU8UmVzdWx0PFQ+Pik6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG4gICAgZm9yIChjb25zdCByZXN1bHQgb2YgcmVzdWx0cykge1xuICAgICAgICBpZiAocmVzdWx0LmlzRmFpbHVyZSgpKSB7XG4gICAgICAgICAgICBlcnJvcnMucHVzaChyZXN1bHQubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGVycm9ycztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmVzIGlmIGFuIGl0ZXJhYmxlIGNvbGxlY3Rpb24gb2Yge0BsaW5rIFJlc3VsdCB8IFJlc3VsdDxUPn0gd2VyZSBhbGwgc3VjY2Vzc2Z1bC5cbiAqIEBwYXJhbSByZXN1bHRzIC0gVGhlIGNvbGxlY3Rpb24gb2Yge0BsaW5rIFJlc3VsdCB8IFJlc3VsdDxUPn0gdG8gYmUgdGVzdGVkLlxuICogQHJldHVybnMgUmV0dXJucyB7QGxpbmsgU3VjY2Vzc30gd2l0aCBgdHJ1ZWAgaWYgYWxsIHtAbGluayBSZXN1bHQgfCByZXN1bHRzfSBhcmUgc3VjY2Vzc2Z1bC5cbiAqIElmIGFueSBhcmUgdW5zdWNjZXNzZnVsLCByZXR1cm5zIHtAbGluayBGYWlsdXJlfSB3aXRoIGEgY29uY2F0ZW5hdGVkIHN1bW1hcnkgdGhlIGVycm9yXG4gKiBtZXNzYWdlcyBmcm9tIGFsbCBmYWlsZWQgZWxlbWVudHMuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbGxTdWNjZWVkPFQ+KHJlc3VsdHM6IEl0ZXJhYmxlPFJlc3VsdDx1bmtub3duPj4sIHN1Y2Nlc3NWYWx1ZTogVCk6IFJlc3VsdDxUPiB7XG4gICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gaXN0YW5idWwgaWdub3JlIGVsc2VcbiAgICBpZiAocmVzdWx0cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3VsdHMpIHtcbiAgICAgICAgICAgIGlmIChyZXN1bHQuaXNGYWlsdXJlKCkpIHtcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChyZXN1bHQubWVzc2FnZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGZhaWwoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9XG4gICAgcmV0dXJuIHN1Y2NlZWQoc3VjY2Vzc1ZhbHVlKTtcbn1cblxuLyoqXG4gKiBTdHJpbmcta2V5ZWQgcmVjb3JkIG9mIGluaXRpYWxpemF0aW9uIGZ1bmN0aW9ucyB0byBiZSBwYXNzZWQgdG8ge0BsaW5rIHBvcHVsYXRlT2JqZWN0fS5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IHR5cGUgRmllbGRJbml0aWFsaXplcnM8VD4gPSB7IFsga2V5IGluIGtleW9mIFQgXTogKHN0YXRlOiBQYXJ0aWFsPFQ+KSA9PiBSZXN1bHQ8VFtrZXldPiB9O1xuXG4vKipcbiAqIFBvcHVsYXRlcyBhbiBhbiBvYmplY3QgYmFzZWQgb24gYSBwcm90b3R5cGUgZnVsbCBvZiBmaWVsZCBpbml0aWFsaXplcnMgdGhhdCByZXR1cm4ge0BsaW5rIFJlc3VsdCB8IFJlc3VsdDxUW2tleV0+fS5cbiAqIFJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggdGhlIHBvcHVsYXRlZCBvYmplY3QgaWYgYWxsIGluaXRpYWxpemVycyBzdWNjZWVkLCBvciB7QGxpbmsgRmFpbHVyZX0gd2l0aCBhXG4gKiBjb25jYXRlbmF0ZWQgbGlzdCBvZiBhbGwgZXJyb3IgbWVzc2FnZXMuXG4gKiBAcGFyYW0gaW5pdGlhbGl6ZXJzIC0gQW4gb2JqZWN0IHdpdGggdGhlIHNoYXBlIG9mIHRoZSB0YXJnZXQgYnV0IHdpdGggaW5pdGlhbGl6ZXIgZnVuY3Rpb25zIGZvclxuICogZWFjaCBwcm9wZXJ0eS5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvcHVsYXRlT2JqZWN0PFQ+KGluaXRpYWxpemVyczogRmllbGRJbml0aWFsaXplcnM8VD4sIG9yZGVyPzogKGtleW9mIFQpW10pOiBSZXN1bHQ8VD4ge1xuICAgIGNvbnN0IHN0YXRlID0ge30gYXMgeyBba2V5IGluIGtleW9mIFRdOiBUW2tleV0gfTtcbiAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3Qga2V5czogKGtleW9mIFQpW10gPSBBcnJheS5mcm9tKG9yZGVyID8/IFtdKTtcbiAgICBjb25zdCBmb3VuZEtleXMgPSBuZXcgU2V0PGtleW9mIFQ+KG9yZGVyKTtcblxuICAgIC8vIHN0YXJ0IHdpdGggdGhlIHN1cHBsaWVkIG9yZGVyIHRoZW4gYXBwZW5kIGFueXRoaW5nIGVsc2Ugd2UgZmluZFxuICAgIGZvciAoY29uc3Qga2V5IGluIGluaXRpYWxpemVycykge1xuICAgICAgICBpZiAoIWZvdW5kS2V5cy5oYXMoa2V5KSkge1xuICAgICAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICAgICAgICBmb3VuZEtleXMuYWRkKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgICAgIGlmIChpbml0aWFsaXplcnNba2V5XSkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gaW5pdGlhbGl6ZXJzW2tleV0oc3RhdGUpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSkge1xuICAgICAgICAgICAgICAgIHN0YXRlW2tleV0gPSByZXN1bHQudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChyZXN1bHQubWVzc2FnZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBlcnJvcnMucHVzaChgcG9wdWxhdGVPYmplY3Q6IEtleSAke2tleX0gaXMgcHJlc2VudCBidXQgaGFzIG5vIGluaXRpYWxpemVyYCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGZhaWwoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9XG4gICAgcmV0dXJuIHN1Y2NlZWQoc3RhdGUgYXMgVCk7XG59XG4iXX0=