@fgv/ts-utils 1.2.0-alpha.2 → 1.3.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 (77) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +4 -0
  3. package/brand.d.ts +2 -0
  4. package/brand.d.ts.map +1 -0
  5. package/brand.js +1 -1
  6. package/converter.d.ts +185 -73
  7. package/converter.d.ts.map +1 -0
  8. package/converter.js +104 -51
  9. package/converters.d.ts +440 -182
  10. package/converters.d.ts.map +1 -0
  11. package/converters.js +358 -209
  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 +6 -2
  25. package/index.d.ts.map +1 -0
  26. package/index.js +15 -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 +391 -39
  35. package/result.d.ts.map +1 -0
  36. package/result.js +257 -49
  37. package/ts-utils.d.ts +2451 -0
  38. package/tsdoc-metadata.json +11 -0
  39. package/utils.d.ts +49 -27
  40. package/utils.d.ts.map +1 -0
  41. package/utils.js +53 -36
  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 -1
  46. package/validation/classes.d.ts.map +1 -0
  47. package/validation/classes.js +9 -2
  48. package/validation/field.d.ts +30 -0
  49. package/validation/field.d.ts.map +1 -0
  50. package/validation/field.js +23 -5
  51. package/validation/genericValidator.d.ts +41 -22
  52. package/validation/genericValidator.d.ts.map +1 -0
  53. package/validation/genericValidator.js +25 -26
  54. package/validation/index.d.ts +5 -3
  55. package/validation/index.d.ts.map +1 -0
  56. package/validation/index.js +15 -8
  57. package/validation/number.d.ts +20 -0
  58. package/validation/number.d.ts.map +1 -0
  59. package/validation/number.js +17 -2
  60. package/validation/object.d.ts +76 -11
  61. package/validation/object.d.ts.map +1 -0
  62. package/validation/object.js +52 -14
  63. package/validation/string.d.ts +20 -0
  64. package/validation/string.d.ts.map +1 -0
  65. package/validation/string.js +17 -2
  66. package/validation/traits.d.ts +50 -1
  67. package/validation/traits.d.ts.map +1 -0
  68. package/validation/traits.js +15 -2
  69. package/validation/validator.d.ts +44 -23
  70. package/validation/validator.d.ts.map +1 -0
  71. package/validation/validator.js +1 -1
  72. package/validation/validatorBase.d.ts +16 -1
  73. package/validation/validatorBase.d.ts.map +1 -0
  74. package/validation/validatorBase.js +7 -1
  75. package/validation/validators.d.ts +26 -2
  76. package/validation/validators.d.ts.map +1 -0
  77. package/validation/validators.js +26 -8
package/converter.js CHANGED
@@ -24,10 +24,21 @@ exports.BaseConverter = void 0;
24
24
  */
25
25
  const result_1 = require("./result");
26
26
  /**
27
- * Simple templated converter wrapper to simplify typed conversion from unknown.
27
+ * Base templated wrapper to simplify creation of new {@link Converter}s.
28
+ * @public
28
29
  */
29
30
  class BaseConverter {
31
+ /**
32
+ * Constructs a new {@link Converter} which uses the supplied function to perform the conversion.
33
+ * @param converter - The conversion function to be applied.
34
+ * @param defaultContext - Optional conversion context to be used by default.
35
+ * @param traits - Optional {@link ConverterTraits | traits} to be assigned to the resulting
36
+ * converter.
37
+ */
30
38
  constructor(converter, defaultContext, traits) {
39
+ /**
40
+ * @internal
41
+ */
31
42
  this._isOptional = false;
32
43
  this._converter = converter;
33
44
  this._defaultContext = defaultContext;
@@ -35,41 +46,37 @@ class BaseConverter {
35
46
  this._brand = (traits === null || traits === void 0 ? void 0 : traits.brand);
36
47
  }
37
48
  /**
38
- * Converts from unknown to <T>
39
- * @param from The unknown to be converted
40
- * @returns An @see Result with a value or an error message
49
+ * {@inheritdoc Converter.isOptional}
50
+ */
51
+ get isOptional() {
52
+ return this._isOptional;
53
+ }
54
+ /**
55
+ * {@inheritdoc Converter.brand}
56
+ */
57
+ get brand() {
58
+ return this._brand;
59
+ }
60
+ /**
61
+ * {@inheritdoc Converter.convert}
41
62
  */
42
63
  convert(from, context) {
43
64
  return this._converter(from, this, context !== null && context !== void 0 ? context : this._defaultContext);
44
65
  }
45
66
  /**
46
- * Converts from unknown to <T> or undefined, as appropriate.
47
- * If 'onError' is 'failOnError', the converter succeeds for
48
- * 'undefined' or any convertible value, but reports an error
49
- * if it encounters a value that cannot be converted. If 'onError'
50
- * is 'ignoreErrors' (default) then values that cannot be converted
51
- * result in a successful return of 'undefined'.
52
- * @param from The unknown to be converted
53
- * @param onError Specifies handling of values that cannot be converted, default 'ignoreErrors'
67
+ * {@inheritdoc Converter.convertOptional}
54
68
  */
55
69
  convertOptional(from, context, onError) {
56
70
  const result = this._converter(from, this, this._context(context));
57
71
  if (result.isFailure()) {
58
72
  onError = onError !== null && onError !== void 0 ? onError : 'ignoreErrors';
59
- return ((from === undefined) || onError === 'ignoreErrors') ? result_1.succeed(undefined) : result;
73
+ return ((from === undefined) || onError === 'ignoreErrors') ? (0, result_1.succeed)(undefined) : result;
60
74
  }
61
75
  return result;
62
76
  }
63
77
  /**
64
- * Creates a converter for an optional value. If 'onError'
65
- * is 'failOnError', the converter accepts 'undefined' or a
66
- * convertible value, but reports an error if it encounters
67
- * a value that cannot be converted. If 'onError' is 'ignoreErrors'
68
- * then values that cannot be converted result in a
69
- * successful return of 'undefined'.
70
- *
71
- * @param onError Specifies handling of values that cannot be converted, default 'ignoreErrors'
72
- * */
78
+ * {@inheritdoc Converter.optional}
79
+ */
73
80
  optional(onError) {
74
81
  return new BaseConverter((from, _self, context) => {
75
82
  onError = onError !== null && onError !== void 0 ? onError : 'failOnError';
@@ -77,20 +84,7 @@ class BaseConverter {
77
84
  })._with(this._traits({ isOptional: true }));
78
85
  }
79
86
  /**
80
- * Reports whether this value is explicitly optional
81
- */
82
- get isOptional() {
83
- return this._isOptional;
84
- }
85
- /**
86
- * Reports the brand of a branded type.
87
- */
88
- get brand() {
89
- return this._brand;
90
- }
91
- /**
92
- * Applies a (possibly) mapping conversion to the converted value.
93
- * @param mapper A function which maps from the converted type to some other type.
87
+ * {@inheritdoc Converter.map}
94
88
  */
95
89
  map(mapper) {
96
90
  return new BaseConverter((from, _self, context) => {
@@ -98,12 +92,11 @@ class BaseConverter {
98
92
  if (innerResult.isSuccess()) {
99
93
  return mapper(innerResult.value);
100
94
  }
101
- return result_1.fail(innerResult.message);
95
+ return (0, result_1.fail)(innerResult.message);
102
96
  })._with(this._traits());
103
97
  }
104
98
  /**
105
- * Applies an additional converter to the converted value.
106
- * @param mapConverter The converter to be applied to the converted value
99
+ * {@inheritdoc Converter.mapConvert}
107
100
  */
108
101
  mapConvert(mapConverter) {
109
102
  return new BaseConverter((from, _self, context) => {
@@ -111,25 +104,76 @@ class BaseConverter {
111
104
  if (innerResult.isSuccess()) {
112
105
  return mapConverter.convert(innerResult.value);
113
106
  }
114
- return result_1.fail(innerResult.message);
107
+ return (0, result_1.fail)(innerResult.message);
115
108
  // eslint-disable-next-line no-return-assign
116
109
  })._with(this._traits());
117
110
  }
118
111
  /**
119
- * Creates a converter with an optional constraint. If the base converter
120
- * succeeds, calls a supplied constraint evaluation function with the
121
- * value and fails the conversion if the function returns either false
122
- * or Failure<T>.
123
- *
124
- * @param constraint Constraint evaluation function
112
+ * {@inheritdoc Converter.mapItems}
113
+ */
114
+ mapItems(mapper) {
115
+ return new BaseConverter((from, _self, context) => {
116
+ return this._converter(from, this, this._context(context)).onSuccess((items) => {
117
+ if (Array.isArray(items)) {
118
+ return (0, result_1.mapResults)(items.map((i) => mapper(i)));
119
+ }
120
+ return (0, result_1.fail)('Cannot map items - not an array');
121
+ });
122
+ });
123
+ }
124
+ /**
125
+ * {@inheritdoc Converter.mapConvertItems}
126
+ */
127
+ mapConvertItems(mapConverter) {
128
+ return new BaseConverter((from, _self, context) => {
129
+ return this._converter(from, this, this._context(context)).onSuccess((items) => {
130
+ if (Array.isArray(items)) {
131
+ return (0, result_1.mapResults)(items.map((i) => mapConverter.convert(i)));
132
+ }
133
+ return (0, result_1.fail)('Cannot map items - not an array');
134
+ });
135
+ });
136
+ }
137
+ /**
138
+ * {@inheritdoc Converter.withTypeGuard}
139
+ */
140
+ withTypeGuard(guard, message) {
141
+ return new BaseConverter((from, _self, context) => {
142
+ return this._converter(from, this, this._context(context)).onSuccess((inner) => {
143
+ message = message !== null && message !== void 0 ? message : 'invalid type';
144
+ return guard(inner) ? (0, result_1.succeed)(inner) : (0, result_1.fail)(`${message}: ${JSON.stringify(from)}`);
145
+ });
146
+ });
147
+ }
148
+ /**
149
+ * {@inheritdoc Converter.withItemTypeGuard}
150
+ */
151
+ withItemTypeGuard(guard, message) {
152
+ return new BaseConverter((from, _self, context) => {
153
+ return this._converter(from, this, this._context(context)).onSuccess((items) => {
154
+ if (Array.isArray(items)) {
155
+ return (0, result_1.mapResults)(items.map((i) => {
156
+ message = message !== null && message !== void 0 ? message : 'invalid type';
157
+ return guard(i) ? (0, result_1.succeed)(i) : (0, result_1.fail)(`${message}: ${JSON.stringify(from)}`);
158
+ }));
159
+ }
160
+ return (0, result_1.fail)('Cannot guard item type - not an array');
161
+ });
162
+ });
163
+ }
164
+ /**
165
+ * {@inheritdoc Converter.withConstraint}
125
166
  */
126
- withConstraint(constraint) {
167
+ withConstraint(constraint, options) {
127
168
  return new BaseConverter((from, _self, context) => {
169
+ var _a;
128
170
  const result = this._converter(from, this, this._context(context));
129
171
  if (result.isSuccess()) {
130
172
  const constraintResult = constraint(result.value);
131
173
  if (typeof constraintResult === 'boolean') {
132
- return constraintResult ? result : result_1.fail(`Value ${JSON.stringify(result.value)} does not meet constraint.`);
174
+ return constraintResult
175
+ ? result
176
+ : (0, result_1.fail)(`"${JSON.stringify(result.value)}": ${(_a = options === null || options === void 0 ? void 0 : options.description) !== null && _a !== void 0 ? _a : 'does not meet constraint'}`);
133
177
  }
134
178
  return constraintResult;
135
179
  }
@@ -137,7 +181,7 @@ class BaseConverter {
137
181
  })._with(this._traits());
138
182
  }
139
183
  /**
140
- * Adds a brand to the type to prevent mismatched usage of simple types
184
+ * {@inheritdoc Converter.withBrand}
141
185
  */
142
186
  withBrand(brand) {
143
187
  if (this._brand) {
@@ -145,13 +189,19 @@ class BaseConverter {
145
189
  }
146
190
  return new BaseConverter((from, _self, context) => {
147
191
  return this._converter(from, this, this._context(context)).onSuccess((v) => {
148
- return result_1.succeed(v);
192
+ return (0, result_1.succeed)(v);
149
193
  });
150
194
  })._with(this._traits({ brand }));
151
195
  }
196
+ /**
197
+ * @internal
198
+ */
152
199
  _context(supplied) {
153
200
  return supplied !== null && supplied !== void 0 ? supplied : this._defaultContext;
154
201
  }
202
+ /**
203
+ * @internal
204
+ */
155
205
  _traits(traits) {
156
206
  return {
157
207
  isOptional: this.isOptional,
@@ -159,6 +209,9 @@ class BaseConverter {
159
209
  ...(traits !== null && traits !== void 0 ? traits : {}),
160
210
  };
161
211
  }
212
+ /**
213
+ * @internal
214
+ */
162
215
  _with(traits) {
163
216
  this._isOptional = (traits.isOptional === true);
164
217
  this._brand = (traits.brand);
@@ -166,4 +219,4 @@ class BaseConverter {
166
219
  }
167
220
  }
168
221
  exports.BaseConverter = BaseConverter;
169
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVydGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbnZlcnRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7QUFDSCxxQ0FBaUQ7QUF1R2pEOztHQUVHO0FBQ0gsTUFBYSxhQUFhO0lBT3RCLFlBQ0ksU0FBNkUsRUFDN0UsY0FBbUIsRUFDbkIsTUFBd0I7UUFSbEIsZ0JBQVcsR0FBRyxLQUFLLENBQUM7UUFVMUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDNUIsSUFBSSxDQUFDLGVBQWUsR0FBRyxjQUFjLENBQUM7UUFDdEMsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUEsTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLFVBQVUsTUFBSyxJQUFJLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksT0FBTyxDQUFDLElBQWEsRUFBRSxPQUFZO1FBQ3RDLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLE9BQU8sYUFBUCxPQUFPLGNBQVAsT0FBTyxHQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ksZUFBZSxDQUFDLElBQWEsRUFBRSxPQUFZLEVBQUUsT0FBaUI7UUFDakUsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNuRSxJQUFJLE1BQU0sQ0FBQyxTQUFTLEVBQUUsRUFBRTtZQUNwQixPQUFPLEdBQUcsT0FBTyxhQUFQLE9BQU8sY0FBUCxPQUFPLEdB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O1lBQ0gsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQzNCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztZQUNqQixHQUFHLENBQUMsTUFBTSxhQUFOLE1BQU0sY0FBTixNQUFNLEdBQUksRUFBRSxDQUFDO1NBQ3BCLENBQUM7SUFDTixDQUFDO0lBRVMsS0FBSyxDQUFDLE1BQWdDO1FBQzVDLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxNQUFNLENBQUMsVUFBVSxLQUFLLElBQUksQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0IsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztDQUNKO0FBaEtELHNDQWdLQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjAgRXJpayBGb3J0dW5lXG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuICogdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuICogY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbFxuICogY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFXG4gKiBTT0ZUV0FSRS5cbiAqL1xuaW1wb3J0IHsgUmVzdWx0LCBmYWlsLCBzdWNjZWVkIH0gZnJvbSAnLi9yZXN1bHQnO1xuaW1wb3J0IHsgQnJhbmQgfSBmcm9tICcuL2JyYW5kJztcblxudHlwZSBPbkVycm9yID0gJ2ZhaWxPbkVycm9yJyB8ICdpZ25vcmVFcnJvcnMnO1xuXG4vKipcbiAqIENvbnZlcnRlciB0cmFpdHMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29udmVydGVyVHJhaXRzIHtcbiAgICByZWFkb25seSBpc09wdGlvbmFsOiBib29sZWFuO1xuICAgIHJlYWRvbmx5IGJyYW5kPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbnZlcnRlcjxULCBUQz11bmRlZmluZWQ+IGV4dGVuZHMgQ29udmVydGVyVHJhaXRzIHtcbiAgICAvKipcbiAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIGVsZW1lbnQgaXMgZXhwbGljaXRseSBvcHRpb25hbFxuICAgICAqL1xuICAgICByZWFkb25seSBpc09wdGlvbmFsOiBib29sZWFuO1xuXG4gICAgIC8qKlxuICAgICAgKiBSZXR1cm5zIHRoZSBicmFuZCBmb3IgYSBicmFuZGVkIHR5cGVcbiAgICAgICovXG4gICAgIHJlYWRvbmx5IGJyYW5kPzogc3RyaW5nO1xuXG4gICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGZyb20gdW5rbm93biB0byA8VD5cbiAgICAgKiBAcGFyYW0gZnJvbSBUaGUgdW5rbm93biB0byBiZSBjb252ZXJ0ZWRcbiAgICAgKiBAcGFyYW0gY29udGV4dCBBbiBvcHRpb25hbCBjb250ZXh0IGFwcGxpZWQgdG8gdGhlIGNvbnZlcnNpb25cbiAgICAgKiBAcmV0dXJucyBBbiBAc2VlIFJlc3VsdCB3aXRoIGEgdmFsdWUgb3IgYW4gZXJyb3IgbWVzc2FnZVxuICAgICAqL1xuICAgIGNvbnZlcnQoZnJvbTogdW5rbm93biwgY29udGV4dD86IFRDKTogUmVzdWx0PFQ+O1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgZnJvbSB1bmtub3duIHRvIDxUPiBvciB1bmRlZmluZWQsIGFzIGFwcHJvcHJpYXRlLlxuICAgICAqIElmICdvbkVycm9yJyBpcyAnZmFpbE9uRXJyb3InLCB0aGUgY29udmVydGVyIHN1Y2NlZWRzIGZvclxuICAgICAqICd1bmRlZmluZWQnIG9yIGFueSBjb252ZXJ0aWJsZSB2YWx1ZSwgYnV0IHJlcG9ydHMgYW4gZXJyb3JcbiAgICAgKiBpZiBpdCBlbmNvdW50ZXJzIGEgdmFsdWUgdGhhdCBjYW5ub3QgYmUgY29udmVydGVkLiAgSWYgJ29uRXJyb3InXG4gICAgICogaXMgJ2lnbm9yZUVycm9ycycgKGRlZmF1bHQpIHRoZW4gdmFsdWVzIHRoYXQgY2Fubm90IGJlIGNvbnZlcnRlZFxuICAgICAqIHJlc3VsdCBpbiBhIHN1Y2Nlc3NmdWwgcmV0dXJuIG9mICd1bmRlZmluZWQnLlxuICAgICAqIEBwYXJhbSBmcm9tIFRoZSB1bmtub3duIHRvIGJlIGNvbnZlcnRlZFxuICAgICAqIEBwYXJhbSBjb250ZXh0IE9wdGlvbmFsIGNvbnRleHQgZm9yIHVzZSBieSB0aGUgY29udmVydGVyXG4gICAgICogQHBhcmFtIG9uRXJyb3IgU3BlY2lmaWVzIGhhbmRsaW5nIG9mIHZhbHVlcyB0aGF0IGNhbm5vdCBiZSBjb252ZXJ0ZWQsIGRlZmF1bHQgJ2lnbm9yZUVycm9ycydcbiAgICAgKi9cbiAgICBjb252ZXJ0T3B0aW9uYWwoZnJvbTogdW5rbm93biwgY29udGV4dD86IFRDLCBvbkVycm9yPzogT25FcnJvcik6IFJlc3VsdDxUfHVuZGVmaW5lZD47XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY29udmVydGVyIGZvciBhbiBvcHRpb25hbCB2YWx1ZS4gSWYgJ29uRXJyb3InXG4gICAgICogaXMgJ2ZhaWxPbkVycm9yJywgdGhlIGNvbnZlcnRlciBhY2NlcHRzICd1bmRlZmluZWQnIG9yIGFcbiAgICAgKiBjb252ZXJ0aWJsZSB2YWx1ZSwgYnV0IHJlcG9ydHMgYW4gZXJyb3IgaWYgaXQgZW5jb3VudGVyc1xuICAgICAqIGEgdmFsdWUgdGhhdCBjYW5ub3QgYmUgY29udmVydGVkLiAgSWYgJ29uRXJyb3InIGlzICdpZ25vcmVFcnJvcnMnXG4gICAgICogKGRlZmF1bHQpIHRoZW4gdmFsdWVzIHRoYXQgY2Fubm90IGJlIGNvbnZlcnRlZCByZXN1bHQgaW4gYVxuICAgICAqIHN1Y2Nlc3NmdWwgcmV0dXJuIG9mICd1bmRlZmluZWQnLlxuICAgICAqXG4gICAgICogQHBhcmFtIG9uRXJyb3IgU3BlY2lmaWVzIGhhbmRsaW5nIG9mIHZhbHVlcyB0aGF0IGNhbm5vdCBiZSBjb252ZXJ0ZWQsIGRlZmF1bHQgJ2lnbm9yZUVycm9ycydcbiAgICAgKiAqL1xuICAgIG9wdGlvbmFsKG9uRXJyb3I/OiBPbkVycm9yKTogQ29udmVydGVyPFR8dW5kZWZpbmVkLCBUQz47XG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGEgKHBvc3NpYmx5KSBtYXBwaW5nIGNvbnZlcnNpb24gdG8gdGhlIGNvbnZlcnRlZCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0gbWFwcGVyIEEgZnVuY3Rpb24gd2hpY2ggbWFwcyBmcm9tIHRoZSBjb252ZXJ0ZWQgdHlwZSB0byBzb21lIG90aGVyIHR5cGUuXG4gICAgICovXG4gICAgbWFwPFQyPihtYXBwZXI6IChmcm9tOiBUKSA9PiBSZXN1bHQ8VDI+KTogQ29udmVydGVyPFQyLCBUQz47XG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGFuIGFkZGl0aW9uYWwgY29udmVydGVyIHRvIHRoZSBjb252ZXJ0ZWQgdmFsdWUuXG4gICAgICogQHBhcmFtIG1hcENvbnZlcnRlciBUaGUgY29udmVydGVyIHRvIGJlIGFwcGxpZWQgdG8gdGhlIGNvbnZlcnRlZCB2YWx1ZVxuICAgICAqL1xuICAgIG1hcENvbnZlcnQ8VDI+KG1hcENvbnZlcnRlcjogQ29udmVydGVyPFQyPik6IENvbnZlcnRlcjxUMiwgVEM+O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNvbnZlcnRlciB3aXRoIGFuIG9wdGlvbmFsIGNvbnN0cmFpbnQuICBJZiB0aGUgYmFzZSBjb252ZXJ0ZXJcbiAgICAgKiBzdWNjZWVkcywgY2FsbHMgYSBzdXBwbGllZCBjb25zdHJhaW50IGV2YWx1YXRpb24gZnVuY3Rpb24gd2l0aCB0aGVcbiAgICAgKiB2YWx1ZSBhbmQgZmFpbHMgdGhlIGNvbnZlcnNpb24gaWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgZWl0aGVyIGZhbHNlXG4gICAgICogb3IgRmFpbHVyZTxUPi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBjb25zdHJhaW50IENvbnN0cmFpbnQgZXZhbHVhdGlvbiBmdW5jdGlvblxuICAgICAqL1xuICAgIHdpdGhDb25zdHJhaW50KGNvbnN0cmFpbnQ6ICh2YWw6IFQpID0+IGJvb2xlYW58UmVzdWx0PFQ+KTogQ29udmVydGVyPFQsIFRDPjtcblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBicmFuZCB0byB0aGUgdHlwZSB0byBwcmV2ZW50IG1pc21hdGNoZWQgdXNhZ2Ugb2Ygc2ltcGxlIHR5cGVzXG4gICAgICovXG4gICAgd2l0aEJyYW5kPEIgZXh0ZW5kcyBzdHJpbmc+KGJyYW5kOiBCKTogQ29udmVydGVyPEJyYW5kPFQsIEI+LCBUQz47XG59XG5cbnR5cGUgSW5uZXJJbmZlcnJlZFR5cGU8VENPTlY+ID1cbiAgICBUQ09OViBleHRlbmRzIENvbnZlcnRlcjxpbmZlciBUVE8+XG4gICAgICAgID8gKFRUTyBleHRlbmRzIEFycmF5PGluZmVyIFRUT0VMRU0+ID8gSW5uZXJJbmZlcnJlZFR5cGU8VFRPRUxFTT5bXSA6IFRUTylcbiAgICAgICAgOiAoVENPTlYgZXh0ZW5kcyBBcnJheTxpbmZlciBURUxFTT4gPyBJbm5lckluZmVycmVkVHlwZTxURUxFTT5bXSA6IFRDT05WKTtcblxuLyoqXG4gKiBJbmZlcnMgdGhlIHR5cGUgdGhhdCB3aWxsIGJlIHJldHVybmVkIGJ5IGFuIGludHN0YW50aWF0ZWQgY29udmVydGVyLiAgV29ya3NcbiAqIGZvciBjb21wbGV4IGFzIHdlbGwgYXMgc2ltcGxlIHR5cGVzLlxuICogQGV4YW1wbGUgSW5mZXI8dHlwZW9mIENvbnZlcnRlcnMubWFwT2YoQ29udmVydGVycy5zdHJpbmdBcnJheSk+IGlzIE1hcDxzdHJpbmcsIHN0cmluZ1tdPlxuICovXG5leHBvcnQgdHlwZSBJbmZlcjxUQ09OVj4gPSBUQ09OViBleHRlbmRzIENvbnZlcnRlcjxpbmZlciBUVE8+ID8gSW5uZXJJbmZlcnJlZFR5cGU8VFRPPiA6IG5ldmVyO1xuXG4vKipcbiAqIERlcHJlY2F0ZWQgbmFtZSBmb3IgSW5mZXI8VD4gcmV0YWluZWQgZm9yIGNvbXBhdGliaWxpdHlcbiAqIEBkZXByZWNhdGVkIHVzZSBAc2VlIEluZmVyIGluc3RlYWRcbiAqL1xuZXhwb3J0IHR5cGUgQ29udmVydGVkVG9UeXBlPFRDT05WPiA9IEluZmVyPFRDT05WPjtcblxuLyoqXG4gKiBTaW1wbGUgdGVtcGxhdGVkIGNvbnZlcnRlciB3cmFwcGVyIHRvIHNpbXBsaWZ5IHR5cGVkIGNvbnZlcnNpb24gZnJvbSB1bmtub3duLlxuICovXG5leHBvcnQgY2xhc3MgQmFzZUNvbnZlcnRlcjxULCBUQz11bmRlZmluZWQ+IGltcGxlbWVudHMgQ29udmVydGVyPFQsIFRDPiB7XG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IF9kZWZhdWx0Q29udGV4dD86IFRDO1xuICAgIHByb3RlY3RlZCBfaXNPcHRpb25hbCA9IGZhbHNlO1xuICAgIHByb3RlY3RlZCBfYnJhbmQ/OiBzdHJpbmc7XG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9jb252ZXJ0ZXI6IChmcm9tOiB1bmtub3duLCBzZWxmOiBDb252ZXJ0ZXI8VCwgVEM+LCBjb250ZXh0PzogVEMpID0+IFJlc3VsdDxUPjtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICAgICAgY29udmVydGVyOiAoZnJvbTogdW5rbm93biwgc2VsZjogQ29udmVydGVyPFQsIFRDPiwgY29udGV4dD86IFRDKSA9PiBSZXN1bHQ8VD4sXG4gICAgICAgIGRlZmF1bHRDb250ZXh0PzogVEMsXG4gICAgICAgIHRyYWl0cz86IENvbnZlcnRlclRyYWl0cyxcbiAgICApIHtcbiAgICAgICAgdGhpcy5fY29udmVydGVyID0gY29udmVydGVyO1xuICAgICAgICB0aGlzLl9kZWZhdWx0Q29udGV4dCA9IGRlZmF1bHRDb250ZXh0O1xuICAgICAgICB0aGlzLl9pc09wdGlvbmFsID0gKHRyYWl0cz8uaXNPcHRpb25hbCA9PT0gdHJ1ZSk7XG4gICAgICAgIHRoaXMuX2JyYW5kID0gKHRyYWl0cz8uYnJhbmQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGZyb20gdW5rbm93biB0byA8VD5cbiAgICAgKiBAcGFyYW0gZnJvbSBUaGUgdW5rbm93biB0byBiZSBjb252ZXJ0ZWRcbiAgICAgKiBAcmV0dXJucyBBbiBAc2VlIFJlc3VsdCB3aXRoIGEgdmFsdWUgb3IgYW4gZXJyb3IgbWVzc2FnZVxuICAgICAqL1xuICAgIHB1YmxpYyBjb252ZXJ0KGZyb206IHVua25vd24sIGNvbnRleHQ/OiBUQyk6IFJlc3VsdDxUPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb252ZXJ0ZXIoZnJvbSwgdGhpcywgY29udGV4dCA/PyB0aGlzLl9kZWZhdWx0Q29udGV4dCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgZnJvbSB1bmtub3duIHRvIDxUPiBvciB1bmRlZmluZWQsIGFzIGFwcHJvcHJpYXRlLlxuICAgICAqIElmICdvbkVycm9yJyBpcyAnZmFpbE9uRXJyb3InLCB0aGUgY29udmVydGVyIHN1Y2NlZWRzIGZvclxuICAgICAqICd1bmRlZmluZWQnIG9yIGFueSBjb252ZXJ0aWJsZSB2YWx1ZSwgYnV0IHJlcG9ydHMgYW4gZXJyb3JcbiAgICAgKiBpZiBpdCBlbmNvdW50ZXJzIGEgdmFsdWUgdGhhdCBjYW5ub3QgYmUgY29udmVydGVkLiAgSWYgJ29uRXJyb3InXG4gICAgICogaXMgJ2lnbm9yZUVycm9ycycgKGRlZmF1bHQpIHRoZW4gdmFsdWVzIHRoYXQgY2Fubm90IGJlIGNvbnZlcnRlZFxuICAgICAqIHJlc3VsdCBpbiBhIHN1Y2Nlc3NmdWwgcmV0dXJuIG9mICd1bmRlZmluZWQnLlxuICAgICAqIEBwYXJhbSBmcm9tIFRoZSB1bmtub3duIHRvIGJlIGNvbnZlcnRlZFxuICAgICAqIEBwYXJhbSBvbkVycm9yIFNwZWNpZmllcyBoYW5kbGluZyBvZiB2YWx1ZXMgdGhhdCBjYW5ub3QgYmUgY29udmVydGVkLCBkZWZhdWx0ICdpZ25vcmVFcnJvcnMnXG4gICAgICovXG4gICAgcHVibGljIGNvbnZlcnRPcHRpb25hbChmcm9tOiB1bmtub3duLCBjb250ZXh0PzogVEMsIG9uRXJyb3I/OiBPbkVycm9yKTogUmVzdWx0PFR8dW5kZWZpbmVkPiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX2NvbnZlcnRlcihmcm9tLCB0aGlzLCB0aGlzLl9jb250ZXh0KGNvbnRleHQpKTtcbiAgICAgICAgaWYgKHJlc3VsdC5pc0ZhaWx1cmUoKSkge1xuICAgICAgICAgICAgb25FcnJvciA9IG9uRXJyb3IgPz8gJ2lnbm9yZUVycm9ycyc7XG4gICAgICAgICAgICByZXR1cm4gKChmcm9tID09PSB1bmRlZmluZWQpIHx8IG9uRXJyb3IgPT09ICdpZ25vcmVFcnJvcnMnKSA/IHN1Y2NlZWQodW5kZWZpbmVkKSA6IHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjb252ZXJ0ZXIgZm9yIGFuIG9wdGlvbmFsIHZhbHVlLiBJZiAnb25FcnJvcidcbiAgICAgKiBpcyAnZmFpbE9uRXJyb3InLCB0aGUgY29udmVydGVyIGFjY2VwdHMgJ3VuZGVmaW5lZCcgb3IgYVxuICAgICAqIGNvbnZlcnRpYmxlIHZhbHVlLCBidXQgcmVwb3J0cyBhbiBlcnJvciBpZiBpdCBlbmNvdW50ZXJzXG4gICAgICogYSB2YWx1ZSB0aGF0IGNhbm5vdCBiZSBjb252ZXJ0ZWQuICBJZiAnb25FcnJvcicgaXMgJ2lnbm9yZUVycm9ycydcbiAgICAgKiB0aGVuIHZhbHVlcyB0aGF0IGNhbm5vdCBiZSBjb252ZXJ0ZWQgcmVzdWx0IGluIGFcbiAgICAgKiBzdWNjZXNzZnVsIHJldHVybiBvZiAndW5kZWZpbmVkJy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBvbkVycm9yIFNwZWNpZmllcyBoYW5kbGluZyBvZiB2YWx1ZXMgdGhhdCBjYW5ub3QgYmUgY29udmVydGVkLCBkZWZhdWx0ICdpZ25vcmVFcnJvcnMnXG4gICAgICogKi9cbiAgICBwdWJsaWMgb3B0aW9uYWwob25FcnJvcj86IE9uRXJyb3IpOiBDb252ZXJ0ZXI8VHx1bmRlZmluZWQsIFRDPiB7XG4gICAgICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxUfHVuZGVmaW5lZCwgVEM+LCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgICAgIG9uRXJyb3IgPSBvbkVycm9yID8/ICdmYWlsT25FcnJvcic7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb252ZXJ0T3B0aW9uYWwoZnJvbSwgdGhpcy5fY29udGV4dChjb250ZXh0KSwgb25FcnJvcik7XG4gICAgICAgIH0pLl93aXRoKHRoaXMuX3RyYWl0cyh7IGlzT3B0aW9uYWw6IHRydWUgfSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlcG9ydHMgd2hldGhlciB0aGlzIHZhbHVlIGlzIGV4cGxpY2l0bHkgb3B0aW9uYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGlzT3B0aW9uYWwoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc09wdGlvbmFsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlcG9ydHMgdGhlIGJyYW5kIG9mIGEgYnJhbmRlZCB0eXBlLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgYnJhbmQoKTogc3RyaW5nfHVuZGVmaW5lZCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9icmFuZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGEgKHBvc3NpYmx5KSBtYXBwaW5nIGNvbnZlcnNpb24gdG8gdGhlIGNvbnZlcnRlZCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0gbWFwcGVyIEEgZnVuY3Rpb24gd2hpY2ggbWFwcyBmcm9tIHRoZSBjb252ZXJ0ZWQgdHlwZSB0byBzb21lIG90aGVyIHR5cGUuXG4gICAgICovXG4gICAgcHVibGljIG1hcDxUMj4obWFwcGVyOiAoZnJvbTogVCkgPT4gUmVzdWx0PFQyPik6IENvbnZlcnRlcjxUMiwgVEM+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyPFQyLCBUQz4oKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VDIsIFRDPiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpbm5lclJlc3VsdCA9IHRoaXMuX2NvbnZlcnRlcihmcm9tLCB0aGlzLCB0aGlzLl9jb250ZXh0KGNvbnRleHQpKTtcbiAgICAgICAgICAgIGlmIChpbm5lclJlc3VsdC5pc1N1Y2Nlc3MoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXBwZXIoaW5uZXJSZXN1bHQudmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhaWwoaW5uZXJSZXN1bHQubWVzc2FnZSk7XG4gICAgICAgIH0pLl93aXRoKHRoaXMuX3RyYWl0cygpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGFuIGFkZGl0aW9uYWwgY29udmVydGVyIHRvIHRoZSBjb252ZXJ0ZWQgdmFsdWUuXG4gICAgICogQHBhcmFtIG1hcENvbnZlcnRlciBUaGUgY29udmVydGVyIHRvIGJlIGFwcGxpZWQgdG8gdGhlIGNvbnZlcnRlZCB2YWx1ZVxuICAgICAqL1xuICAgIHB1YmxpYyBtYXBDb252ZXJ0PFQyPihtYXBDb252ZXJ0ZXI6IENvbnZlcnRlcjxUMj4pOiBDb252ZXJ0ZXI8VDIsIFRDPiB7XG4gICAgICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcjxUMiwgVEM+KChmcm9tOiB1bmtub3duLCBfc2VsZjogQ29udmVydGVyPFQyLCBUQz4sIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW5uZXJSZXN1bHQgPSB0aGlzLl9jb252ZXJ0ZXIoZnJvbSwgdGhpcywgdGhpcy5fY29udGV4dChjb250ZXh0KSk7XG4gICAgICAgICAgICBpZiAoaW5uZXJSZXN1bHQuaXNTdWNjZXNzKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWFwQ29udmVydGVyLmNvbnZlcnQoaW5uZXJSZXN1bHQudmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhaWwoaW5uZXJSZXN1bHQubWVzc2FnZSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1yZXR1cm4tYXNzaWduXG4gICAgICAgIH0pLl93aXRoKHRoaXMuX3RyYWl0cygpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY29udmVydGVyIHdpdGggYW4gb3B0aW9uYWwgY29uc3RyYWludC4gIElmIHRoZSBiYXNlIGNvbnZlcnRlclxuICAgICAqIHN1Y2NlZWRzLCBjYWxscyBhIHN1cHBsaWVkIGNvbnN0cmFpbnQgZXZhbHVhdGlvbiBmdW5jdGlvbiB3aXRoIHRoZVxuICAgICAqIHZhbHVlIGFuZCBmYWlscyB0aGUgY29udmVyc2lvbiBpZiB0aGUgZnVuY3Rpb24gcmV0dXJucyBlaXRoZXIgZmFsc2VcbiAgICAgKiBvciBGYWlsdXJlPFQ+LlxuICAgICAqXG4gICAgICogQHBhcmFtIGNvbnN0cmFpbnQgQ29uc3RyYWludCBldmFsdWF0aW9uIGZ1bmN0aW9uXG4gICAgICovXG4gICAgcHVibGljIHdpdGhDb25zdHJhaW50KGNvbnN0cmFpbnQ6ICh2YWw6IFQpID0+IGJvb2xlYW58UmVzdWx0PFQ+KTogQ29udmVydGVyPFQsIFRDPiB7XG4gICAgICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcjxULCBUQz4oKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VCwgVEM+LCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX2NvbnZlcnRlcihmcm9tLCB0aGlzLCB0aGlzLl9jb250ZXh0KGNvbnRleHQpKTtcbiAgICAgICAgICAgIGlmIChyZXN1bHQuaXNTdWNjZXNzKCkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25zdHJhaW50UmVzdWx0ID0gY29uc3RyYWludChyZXN1bHQudmFsdWUpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29uc3RyYWludFJlc3VsdCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb25zdHJhaW50UmVzdWx0ID8gcmVzdWx0IDogZmFpbChgVmFsdWUgJHtKU09OLnN0cmluZ2lmeShyZXN1bHQudmFsdWUpfSBkb2VzIG5vdCBtZWV0IGNvbnN0cmFpbnQuYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjb25zdHJhaW50UmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfSkuX3dpdGgodGhpcy5fdHJhaXRzKCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBicmFuZCB0byB0aGUgdHlwZSB0byBwcmV2ZW50IG1pc21hdGNoZWQgdXNhZ2Ugb2Ygc2ltcGxlIHR5cGVzXG4gICAgICovXG4gICAgcHVibGljIHdpdGhCcmFuZDxCIGV4dGVuZHMgc3RyaW5nPihicmFuZDogQik6IENvbnZlcnRlcjxCcmFuZDxULCBCPiwgVEM+IHtcbiAgICAgICAgaWYgKHRoaXMuX2JyYW5kKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCByZXBsYWNlIGV4aXN0aW5nIGJyYW5kIFwiJHt0aGlzLl9icmFuZH1cIiB3aXRoIFwiJHticmFuZH1cIi5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcjxCcmFuZDxULCBCPiwgVEM+KChmcm9tOiB1bmtub3duLCBfc2VsZjogQ29udmVydGVyPFQsIFRDPiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY29udmVydGVyKGZyb20sIHRoaXMsIHRoaXMuX2NvbnRleHQoY29udGV4dCkpLm9uU3VjY2VzcygodikgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBzdWNjZWVkKHYgYXMgQnJhbmQ8VCwgQj4pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pLl93aXRoKHRoaXMuX3RyYWl0cyh7IGJyYW5kIH0pKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgX2NvbnRleHQoc3VwcGxpZWQ/OiBUQyk6IFRDfHVuZGVmaW5lZCB7XG4gICAgICAgIHJldHVybiBzdXBwbGllZCA/PyB0aGlzLl9kZWZhdWx0Q29udGV4dDtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgX3RyYWl0cyh0cmFpdHM/OiBQYXJ0aWFsPENvbnZlcnRlclRyYWl0cz4pOiBDb252ZXJ0ZXJUcmFpdHMge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaXNPcHRpb25hbDogdGhpcy5pc09wdGlvbmFsLFxuICAgICAgICAgICAgYnJhbmQ6IHRoaXMuYnJhbmQsXG4gICAgICAgICAgICAuLi4odHJhaXRzID8/IHt9KSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgX3dpdGgodHJhaXRzOiBQYXJ0aWFsPENvbnZlcnRlclRyYWl0cz4pOiB0aGlzIHtcbiAgICAgICAgdGhpcy5faXNPcHRpb25hbCA9ICh0cmFpdHMuaXNPcHRpb25hbCA9PT0gdHJ1ZSk7XG4gICAgICAgIHRoaXMuX2JyYW5kID0gKHRyYWl0cy5icmFuZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbiJdfQ==
222
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVydGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbnZlcnRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7QUFDSCxxQ0FBNkQ7QUEyTTdEOzs7R0FHRztBQUNILE1BQWEsYUFBYTtJQWdCdEI7Ozs7OztPQU1HO0lBQ0gsWUFDSSxTQUE2RSxFQUM3RSxjQUFtQixFQUNuQixNQUF3QjtRQXJCNUI7O1dBRUc7UUFDTyxnQkFBVyxHQUFHLEtBQUssQ0FBQztRQW9CMUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDNUIsSUFBSSxDQUFDLGVBQWUsR0FBRyxjQUFjLENBQUM7UUFDdEMsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUEsTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLFVBQVUsTUFBSyxJQUFJLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7T0FFRztJQUNILElBQVcsVUFBVTtRQUNqQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7SUFDNUIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBVyxLQUFLO1FBQ1osT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3ZCLENBQUM7SUFFRDs7T0FFRztJQUNJLE9BQU8sQ0FBQyxJQUFhLEVBQUUsT0FBWTtRQUN0QyxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLGFBQVAsT0FBTyxjQUFQLE9BQU8sR0FBSSxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDeEUsQ0FBQztJQUVEOztPQUVHO0lBQ0ksZUFBZSxDQUFDLElBQWEsRUFBRSxPQUFZLEVBQUUsT0FBaUI7UUFDakUsTUFBTSxNQUFNLEdBQUcsSUFB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RUQsT0FBTyxJQUFJLGFBQWEsQ0FBa0IsQ0FBQyxJQUFhLEVBQUUsS0FBdUIsRUFBRSxPQUFZLEVBQUUsRUFBRTtZQUMvRixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7Z0JBQ3ZFLE9BQU8sSUFBQSxnQkFBTyxFQUFDLENBQWdCLENBQUMsQ0FBQztZQUNyQyxDQUFDLENBQUMsQ0FBQztRQUNQLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRDs7T0FFRztJQUNPLFFBQVEsQ0FBQyxRQUFhO1FBQzVCLE9BQU8sUUFBUSxhQUFSLFFBQVEsY0FBUixRQUFRLEdBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQztJQUM1QyxDQUFDO0lBRUQ7O09BRUc7SUFDTyxPQUFPLENBQUMsTUFBaUM7UUFDL0MsT0FBTztZQUNILFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVTtZQUMzQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7WUFDakIsR0FBRyxDQUFDLE1BQU0sYUFBTixNQUFNLGNBQU4sTUFBTSxHQUFJLEVBQUUsQ0FBQztTQUNwQixDQUFDO0lBQ04sQ0FBQztJQUVEOztPQUVHO0lBQ08sS0FBSyxDQUFDLE1BQWdDO1FBQzVDLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxNQUFNLENBQUMsVUFBVSxLQUFLLElBQUksQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0IsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztDQUNKO0FBbE9ELHNDQWtPQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjAgRXJpayBGb3J0dW5lXG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuICogdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuICogY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbFxuICogY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFXG4gKiBTT0ZUV0FSRS5cbiAqL1xuaW1wb3J0IHsgUmVzdWx0LCBmYWlsLCBtYXBSZXN1bHRzLCBzdWNjZWVkIH0gZnJvbSAnLi9yZXN1bHQnO1xuaW1wb3J0IHsgQnJhbmQgfSBmcm9tICcuL2JyYW5kJztcblxudHlwZSBPbkVycm9yID0gJ2ZhaWxPbkVycm9yJyB8ICdpZ25vcmVFcnJvcnMnO1xuXG4vKipcbiAqIENvbnZlcnRlciB0cmFpdHMuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29udmVydGVyVHJhaXRzIHtcbiAgICByZWFkb25seSBpc09wdGlvbmFsOiBib29sZWFuO1xuICAgIHJlYWRvbmx5IGJyYW5kPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBDb252ZXJ0ZXIud2l0aENvbnN0cmFpbnR9LlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbnN0cmFpbnRPcHRpb25zIHtcbiAgICAvKipcbiAgICAgKiBPcHRpb25hbCBkZXNjcmlwdGlvbiBmb3IgZXJyb3IgbWVzc2FnZXMgd2hlbiBjb25zdHJhaW50XG4gICAgICogZnVuY3Rpb24gcmV0dXJucyBmYWxzZS5cbiAgICAgKi9cbiAgICByZWFkb25seSBkZXNjcmlwdGlvbjogc3RyaW5nO1xufVxuXG4vKipcbiAqIEdlbmVyaWMgY29udmVydGVyIHRvIGNvbnZlcnQgdW5rbm93biB0byBhIHRlbXBsYXRlZCB0eXBlIGA8VD5gLCB1c2luZ1xuICogaW50cmluc2ljIHJ1bGVzIG9yIGFzIG1vZGlmaWVkIGJ5IGFuIG9wdGlvbmFsIGNvbnZlcnNpb24gY29udGV4dFxuICogb2Ygb3B0aW9uYWwgdGVtcGxhdGVkIHR5cGUgYDxUQz5gIChkZWZhdWx0IGB1bmRlZmluZWRgKS5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb252ZXJ0ZXI8VCwgVEM9dW5kZWZpbmVkPiBleHRlbmRzIENvbnZlcnRlclRyYWl0cyB7XG4gICAgLyoqXG4gICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBlbGVtZW50IGlzIGV4cGxpY2l0bHkgb3B0aW9uYWwuXG4gICAgICovXG4gICAgIHJlYWRvbmx5IGlzT3B0aW9uYWw6IGJvb2xlYW47XG5cbiAgICAgLyoqXG4gICAgICAqIFJldHVybnMgdGhlIGJyYW5kIGZvciBhIGJyYW5kZWQgdHlwZS5cbiAgICAgICovXG4gICAgIHJlYWRvbmx5IGJyYW5kPzogc3RyaW5nO1xuXG4gICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGZyb20gYHVua25vd25gIHRvIGA8VD5gLlxuICAgICAqIEBwYXJhbSBmcm9tIC0gVGhlIGB1bmtub3duYCB0byBiZSBjb252ZXJ0ZWRcbiAgICAgKiBAcGFyYW0gY29udGV4dCAtIEFuIG9wdGlvbmFsIGNvbnZlcnNpb24gY29udGV4dCBvZiB0eXBlIGA8VEM+YCB0byBiZSB1c2VkIGluXG4gICAgICogdGhlIGNvbnZlcnNpb24uXG4gICAgICogQHJldHVybnMgQSB7QGxpbmsgUmVzdWx0fSB3aXRoIGEge0BsaW5rIFN1Y2Nlc3N9IGFuZCBhIHZhbHVlIG9uIHN1Y2Nlc3Mgb3IgYW5cbiAgICAgKiB7QGxpbmsgRmFpbHVyZX0gd2l0aCBhIGEgbWVzc2FnZSBvbiBmYWlsdXJlLlxuICAgICAqL1xuICAgIGNvbnZlcnQoZnJvbTogdW5rbm93biwgY29udGV4dD86IFRDKTogUmVzdWx0PFQ+O1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgZnJvbSBgdW5rbm93bmAgdG8gYDxUPmAgb3IgYHVuZGVmaW5lZGAsIGFzIGFwcHJvcHJpYXRlLlxuICAgICAqXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBJZiBgb25FcnJvcmAgaXMgYGZhaWxPbkVycm9yYCwgdGhlIGNvbnZlcnRlciBzdWNjZWVkcyBmb3JcbiAgICAgKiBgdW5kZWZpbmVkYCBvciBhbnkgY29udmVydGlibGUgdmFsdWUsIGJ1dCByZXBvcnRzIGFuIGVycm9yXG4gICAgICogaWYgaXQgZW5jb3VudGVycyBhIHZhbHVlIHRoYXQgY2Fubm90IGJlIGNvbnZlcnRlZC5cbiAgICAgKlxuICAgICAqIElmIGBvbkVycm9yYCBpcyBgaWdub3JlRXJyb3JzYCAoZGVmYXVsdCkgdGhlbiB2YWx1ZXMgdGhhdFxuICAgICAqIGNhbm5vdCBiZSBjb252ZXJ0ZWQgcmVzdWx0IGluIGEgc3VjY2Vzc2Z1bCByZXR1cm4gb2YgYHVuZGVmaW5lZGAuXG4gICAgICogQHBhcmFtIGZyb20gLSBUaGUgYHVua25vd25gIHRvIGJlIGNvbnZlcnRlZFxuICAgICAqIEBwYXJhbSBjb250ZXh0IC0gQW4gb3B0aW9uYWwgY29udmVyc2lvbiBjb250ZXh0IG9mIHR5cGUgYDxUQz5gIHRvIGJlIHVzZWQgaW5cbiAgICAgKiB0aGUgY29udmVyc2lvbi5cbiAgICAgKiBAcGFyYW0gb25FcnJvciAtIFNwZWNpZmllcyBoYW5kbGluZyBvZiB2YWx1ZXMgdGhhdCBjYW5ub3QgYmUgY29udmVydGVkIChkZWZhdWx0IGBpZ25vcmVFcnJvcnNgKS5cbiAgICAgKiBAcmV0dXJucyBBIHtAbGluayBSZXN1bHR9IHdpdGggYSB7QGxpbmsgU3VjY2Vzc30gYW5kIGEgdmFsdWUgb24gc3VjY2VzcyBvciBhblxuICAgICAqIHtAbGluayBGYWlsdXJlfSB3aXRoIGEgYSBtZXNzYWdlIG9uIGZhaWx1cmUuXG4gICAgICovXG4gICAgY29udmVydE9wdGlvbmFsKGZyb206IHVua25vd24sIGNvbnRleHQ/OiBUQywgb25FcnJvcj86IE9uRXJyb3IpOiBSZXN1bHQ8VHx1bmRlZmluZWQ+O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHtAbGluayBDb252ZXJ0ZXJ9IGZvciBhbiBvcHRpb25hbCB2YWx1ZS5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzXG4gICAgICogSWYgYG9uRXJyb3JgIGlzIGBmYWlsT25FcnJvcmAsIHRoZSByZXN1bHRpbmcgY29udmVydGVyIHdpbGwgYWNjZXB0IGB1bmRlZmluZWRgXG4gICAgICogb3IgYSBjb252ZXJ0aWJsZSB2YWx1ZSwgYnV0IHJlcG9ydCBhbiBlcnJvciBpZiBpdCBlbmNvdW50ZXJzIGEgdmFsdWUgdGhhdCBjYW5ub3QgYmVcbiAgICAgKiBjb252ZXJ0ZWQuXG4gICAgICpcbiAgICAgKiBJZiBgb25FcnJvcmAgaXMgYGlnbm9yZUVycm9yc2AgKGRlZmF1bHQpIHRoZW4gdmFsdWVzIHRoYXQgY2Fubm90IGJlIGNvbnZlcnRlZCB3aWxsXG4gICAgICogcmVzdWx0IGluIGEgc3VjY2Vzc2Z1bCByZXR1cm4gb2YgYHVuZGVmaW5lZGAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb25FcnJvciAtIFNwZWNpZmllcyBoYW5kbGluZyBvZiB2YWx1ZXMgdGhhdCBjYW5ub3QgYmUgY29udmVydGVkIChkZWZhdWx0IGBpZ25vcmVFcnJvcnNgKS5cbiAgICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgQ29udmVydGVyfSByZXR1cm5pbmcgYDxUfHVuZGVmaW5lZD5gLlxuICAgICAqICovXG4gICAgb3B0aW9uYWwob25FcnJvcj86IE9uRXJyb3IpOiBDb252ZXJ0ZXI8VHx1bmRlZmluZWQsIFRDPjtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBhcHBsaWVzIGEgKHBvc3NpYmx5KSBtYXBwaW5nIGNvbnZlcnNpb24gdG9cbiAgICAgKiB0aGUgY29udmVydGVkIHZhbHVlIG9mIHRoaXMge0BsaW5rIENvbnZlcnRlcn0uXG4gICAgICogQHBhcmFtIG1hcHBlciAtIEEgZnVuY3Rpb24gd2hpY2ggbWFwcyBmcm9tIHRoZSB0aGUgcmVzdWx0IHR5cGUgYDxUPmAgb2YgdGhpc1xuICAgICAqIGNvbnZlcnRlciB0byBhIG5ldyByZXN1bHQgdHlwZSBgPFQyPmAuXG4gICAgICogQHJldHVybnMgQSBuZXcge0BsaW5rIENvbnZlcnRlcn0gcmV0dXJuaW5nIGA8VDI+YC5cbiAgICAgKi9cbiAgICBtYXA8VDI+KG1hcHBlcjogKGZyb206IFQpID0+IFJlc3VsdDxUMj4pOiBDb252ZXJ0ZXI8VDIsIFRDPjtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBhcHBsaWVzIGFuIGFkZGl0aW9uYWwgc3VwcGxpZWRcbiAgICAgKiBjb252ZXJ0ZXIgdG8gdGhlIHJlc3VsdCBvZiB0aGlzIGNvbnZlcnRlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBtYXBDb252ZXJ0ZXIgLSBUaGUge0BsaW5rIENvbnZlcnRlcn0gdG8gYmUgYXBwbGllZCB0byB0aGVcbiAgICAgKiBjb252ZXJ0ZWQgcmVzdWx0IGZyb20gdGhpcyB7QGxpbmsgQ29udmVydGVyfS5cbiAgICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgQ29udmVydGVyfSByZXR1cm5pbmcgYDxUMj5gLlxuICAgICAqL1xuICAgIG1hcENvbnZlcnQ8VDI+KG1hcENvbnZlcnRlcjogQ29udmVydGVyPFQyPik6IENvbnZlcnRlcjxUMiwgVEM+O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIG1hcHMgdGhlIGluZGl2aWR1YWwgaXRlbXMgb2YgYSBjb2xsZWN0aW9uXG4gICAgICogcmVzdWx0aW5nIGZyb20gdGhpcyB7QGxpbmsgQ29udmVydGVyfSB1c2luZyB0aGUgc3VwcGxpZWQgbWFwIGZ1Y3Rpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIEZhaWxzIGlmIGBmcm9tYCBpcyBub3QgYW4gYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbWFwcGVyIC0gVGhlIG1hcCBmdW5jdGlvbiB0byBiZSBhcHBsaWVkIHRvIGVhY2ggZWxlbWVudCBvZiB0aGVcbiAgICAgKiByZXN1bHQgb2YgdGhpcyB7QGxpbmsgQ29udmVydGVyfS5cbiAgICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgQ29udmVydGVyfSByZXR1cm5pbmcgYDxUSVtdPmAuXG4gICAgICovXG4gICAgbWFwSXRlbXM8VEk+KG1hcHBlcjogKGZyb206IHVua25vd24pID0+IFJlc3VsdDxUST4pOiBDb252ZXJ0ZXI8VElbXSwgVEM+O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIG1hcHMgdGhlIGluZGl2aWR1YWwgaXRlbXMgb2YgYSBjb2xsZWN0aW9uXG4gICAgICogcmVzdWx0aW5nIGZyb20gdGhpcyB7QGxpbmsgQ29udmVydGVyfSB1c2luZyB0aGUgc3VwcGxpZWQge0BsaW5rIENvbnZlcnRlcn0uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIEZhaWxzIGlmIGBmcm9tYCBpcyBub3QgYW4gYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbWFwQ29udmVydGVyIC0gVGhlIHtAbGluayBDb252ZXJ0ZXJ9IHRvIGJlIGFwcGxpZWQgdG8gZWFjaCBlbGVtZW50IG9mIHRoZVxuICAgICAqIHJlc3VsdCBvZiB0aGlzIHtAbGluayBDb252ZXJ0ZXJ9LlxuICAgICAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBDb252ZXJ0ZXJ9IHJldHVybmluZyBgPFRJW10+YC5cbiAgICAgKi9cbiAgICAgbWFwQ29udmVydEl0ZW1zPFRJPihtYXBDb252ZXJ0ZXI6IENvbnZlcnRlcjxUSSwgdW5rbm93bj4pOiBDb252ZXJ0ZXI8VElbXSwgVEM+O1xuXG4gICAgIC8qKlxuICAgICAgKiBDcmVhdGVzIGEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggYXBwbGllcyBhIHN1cHBsaWVkIHR5cGUgZ3VhcmQgdG8gdGhlIGNvbnZlcnNpb25cbiAgICAgICogcmVzdWx0LlxuICAgICAgKiBAcGFyYW0gZ3VhcmQgLSBUaGUgdHlwZSBndWFyZCBmdW5jdGlvbiB0byBhcHBseS5cbiAgICAgICogQHBhcmFtIG1lc3NhZ2UgLSBPcHRpb25hbCBtZXNzYWdlIHRvIGJlIHJlcG9ydGVkIGlmIHRoZSB0eXBlIGd1YXJkIGZhaWxzLlxuICAgICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgQ29udmVydGVyfSByZXR1cm5pbmcgYDxUST5gLlxuICAgICAgKi9cbiAgICB3aXRoVHlwZUd1YXJkPFRJPihndWFyZDogKGZyb206IHVua25vd24pID0+IGZyb20gaXMgVEksIG1lc3NhZ2U/OiBzdHJpbmcpOiBDb252ZXJ0ZXI8VEksIFRDPjtcblxuICAgICAvKipcbiAgICAgICogQ3JlYXRlcyBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGFwcGxpZXMgYSBzdXBwbGllZCB0eXBlIGd1YXJkIHRvIGVhY2ggbWVtYmVyIG9mXG4gICAgICAqIHRoZSBjb252ZXJzaW9uIHJlc3VsdCBmcm9tIHRoaXMgY29udmVydGVyLlxuICAgICAgKlxuICAgICAgKiBAcmVtYXJrc1xuICAgICAgKiBGYWlscyBpZiB0aGUgY29udmVyc2lvbiByZXN1bHQgaXMgbm90IGFuIGFycmF5IG9yIGlmIGFueSBtZW1iZXIgZmFpbHMgdGhlXG4gICAgICAqIHR5cGUgZ3VhcmQuXG4gICAgICAqIEBwYXJhbSBndWFyZCAtIFRoZSB0eXBlIGd1YXJkIGZ1bmN0aW9uIHRvIGFwcGx5IHRvIGVhY2ggZWxlbWVudC5cbiAgICAgICogQHBhcmFtIG1lc3NhZ2UgLSBPcHRpb25hbCBtZXNzYWdlIHRvIGJlIHJlcG9ydGVkIGlmIHRoZSB0eXBlIGd1YXJkIGZhaWxzLlxuICAgICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgQ29udmVydGVyfSByZXR1cm5pbmcgYDxUST5gLlxuICAgICAgKi9cbiAgICAgIHdpdGhJdGVtVHlwZUd1YXJkPFRJPihndWFyZDogKGZyb206IHVua25vd24pID0+IGZyb20gaXMgVEksIG1lc3NhZ2U/OiBzdHJpbmcpOiBDb252ZXJ0ZXI8VElbXSwgVEM+O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGFwcGxpZXMgYW4gb3B0aW9uYWwgY29uc3RyYWludCB0byB0aGUgcmVzdWx0XG4gICAgICogb2YgdGhpcyBjb252ZXJzaW9uLiAgSWYgdGhpcyB7QGxpbmsgQ29udmVydGVyfSAodGhlIGJhc2UgY29udmVydGVyKSBzdWNjZWVkcywgdGhlIG5ld1xuICAgICAqIGNvbnZlcnRlciBjYWxscyBhIHN1cHBsaWVkIGNvbnN0cmFpbnQgZXZhbHVhdGlvbiBmdW5jdGlvbiB3aXRoIHRoZSBjb252ZXJzaW9uLCB3aGljaFxuICAgICAqIGZhaWxzIHRoZSBlbnRpcmUgY29udmVyc2lvbiBpZiB0aGUgY29uc3RyYWludCBmdW5jdGlvbiByZXR1cm5zIGVpdGhlciBgZmFsc2VgIG9yXG4gICAgICoge0BsaW5rIEZhaWx1cmUgfCBGYWlsdXJlPFQ+fS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBjb25zdHJhaW50IC0gQ29uc3RyYWludCBldmFsdWF0aW9uIGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0ge0BsaW5rIENvbnN0cmFpbnRPcHRpb25zIHwgT3B0aW9uc30gZm9yIGNvbnN0cmFpbnQgZXZhbHVhdGlvbi5cbiAgICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgQ29udmVydGVyfSByZXR1cm5pbmcgYDxUPmAuXG4gICAgICovXG4gICAgd2l0aENvbnN0cmFpbnQoXG4gICAgICAgIGNvbnN0cmFpbnQ6ICh2YWw6IFQpID0+IGJvb2xlYW58UmVzdWx0PFQ+LFxuICAgICAgICBvcHRpb25zPzogQ29uc3RyYWludE9wdGlvbnMsXG4gICAgKTogQ29udmVydGVyPFQsIFRDPjtcblxuICAgIC8qKlxuICAgICAqIHJldHVybnMgYSBjb252ZXJ0ZXIgd2hpY2ggYWRkcyBhIGJyYW5kIHRvIHRoZSB0eXBlIHRvIHByZXZlbnQgbWlzbWF0Y2hlZCB1c2FnZVxuICAgICAqIG9mIHNpbXBsZSB0eXBlcy5cbiAgICAgKiBAcGFyYW0gYnJhbmQgLSBUaGUgYnJhbmQgdG8gYmUgYXBwbGllZCB0byB0aGUgcmVzdWx0IHZhbHVlLlxuICAgICAqIEByZXR1cm5zIEEge0BsaW5rIENvbnZlcnRlcn0gcmV0dXJuaW5nIGBCcmFuZDxULCBCPmAuXG4gICAgICovXG4gICAgd2l0aEJyYW5kPEIgZXh0ZW5kcyBzdHJpbmc+KGJyYW5kOiBCKTogQ29udmVydGVyPEJyYW5kPFQsIEI+LCBUQz47XG59XG5cbi8qKlxuICogaW50ZXJuYWxcbiAqL1xudHlwZSBJbm5lckluZmVycmVkVHlwZTxUQ09OVj4gPVxuICAgIFRDT05WIGV4dGVuZHMgQ29udmVydGVyPGluZmVyIFRUTz5cbiAgICAgICAgPyAoVFRPIGV4dGVuZHMgQXJyYXk8aW5mZXIgVFRPRUxFTT4gPyBJbm5lckluZmVycmVkVHlwZTxUVE9FTEVNPltdIDogVFRPKVxuICAgICAgICA6IChUQ09OViBleHRlbmRzIEFycmF5PGluZmVyIFRFTEVNPiA/IElubmVySW5mZXJyZWRUeXBlPFRFTEVNPltdIDogVENPTlYpO1xuXG4vKipcbiAqIEluZmVycyB0aGUgdHlwZSB0aGF0IHdpbGwgYmUgcmV0dXJuZWQgYnkgYW4gaW50c3RhbnRpYXRlZCBjb252ZXJ0ZXIuICBXb3Jrc1xuICogZm9yIGNvbXBsZXggYXMgd2VsbCBhcyBzaW1wbGUgdHlwZXMuXG4gKiBAZXhhbXBsZSBgSW5mZXI8dHlwZW9mIENvbnZlcnRlcnMubWFwT2YoQ29udmVydGVycy5zdHJpbmdBcnJheSk+YCBpcyBgTWFwPHN0cmluZywgc3RyaW5nW10+YFxuICogQGJldGFcbiAqL1xuZXhwb3J0IHR5cGUgSW5mZXI8VENPTlY+ID0gVENPTlYgZXh0ZW5kcyBDb252ZXJ0ZXI8aW5mZXIgVFRPPiA/IElubmVySW5mZXJyZWRUeXBlPFRUTz4gOiBuZXZlcjtcblxuLyoqXG4gKiBEZXByZWNhdGVkIG5hbWUgZm9yIEluZmVyPFQ+IHJldGFpbmVkIGZvciBjb21wYXRpYmlsaXR5XG4gKiBAZGVwcmVjYXRlZCB1c2UgQHNlZSBJbmZlciBpbnN0ZWFkXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IHR5cGUgQ29udmVydGVkVG9UeXBlPFRDT05WPiA9IEluZmVyPFRDT05WPjtcblxuLyoqXG4gKiBCYXNlIHRlbXBsYXRlZCB3cmFwcGVyIHRvIHNpbXBsaWZ5IGNyZWF0aW9uIG9mIG5ldyB7QGxpbmsgQ29udmVydGVyfXMuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjbGFzcyBCYXNlQ29udmVydGVyPFQsIFRDPXVuZGVmaW5lZD4gaW1wbGVtZW50cyBDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICAvKipcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgX2RlZmF1bHRDb250ZXh0PzogVEM7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHJvdGVjdGVkIF9pc09wdGlvbmFsID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHJvdGVjdGVkIF9icmFuZD86IHN0cmluZztcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NvbnZlcnRlcjogKGZyb206IHVua25vd24sIHNlbGY6IENvbnZlcnRlcjxULCBUQz4sIGNvbnRleHQ/OiBUQykgPT4gUmVzdWx0PFQ+O1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGxpbmsgQ29udmVydGVyfSB3aGljaCB1c2VzIHRoZSBzdXBwbGllZCBmdW5jdGlvbiB0byBwZXJmb3JtIHRoZSBjb252ZXJzaW9uLlxuICAgICAqIEBwYXJhbSBjb252ZXJ0ZXIgLSBUaGUgY29udmVyc2lvbiBmdW5jdGlvbiB0byBiZSBhcHBsaWVkLlxuICAgICAqIEBwYXJhbSBkZWZhdWx0Q29udGV4dCAtIE9wdGlvbmFsIGNvbnZlcnNpb24gY29udGV4dCB0byBiZSB1c2VkIGJ5IGRlZmF1bHQuXG4gICAgICogQHBhcmFtIHRyYWl0cyAtIE9wdGlvbmFsIHtAbGluayBDb252ZXJ0ZXJUcmFpdHMgfCB0cmFpdHN9IHRvIGJlIGFzc2lnbmVkIHRvIHRoZSByZXN1bHRpbmdcbiAgICAgKiBjb252ZXJ0ZXIuXG4gICAgICovXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKFxuICAgICAgICBjb252ZXJ0ZXI6IChmcm9tOiB1bmtub3duLCBzZWxmOiBDb252ZXJ0ZXI8VCwgVEM+LCBjb250ZXh0PzogVEMpID0+IFJlc3VsdDxUPixcbiAgICAgICAgZGVmYXVsdENvbnRleHQ/OiBUQyxcbiAgICAgICAgdHJhaXRzPzogQ29udmVydGVyVHJhaXRzLFxuICAgICkge1xuICAgICAgICB0aGlzLl9jb252ZXJ0ZXIgPSBjb252ZXJ0ZXI7XG4gICAgICAgIHRoaXMuX2RlZmF1bHRDb250ZXh0ID0gZGVmYXVsdENvbnRleHQ7XG4gICAgICAgIHRoaXMuX2lzT3B0aW9uYWwgPSAodHJhaXRzPy5pc09wdGlvbmFsID09PSB0cnVlKTtcbiAgICAgICAgdGhpcy5fYnJhbmQgPSAodHJhaXRzPy5icmFuZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICoge0Bpbmhlcml0ZG9jIENvbnZlcnRlci5pc09wdGlvbmFsfVxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgaXNPcHRpb25hbCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzT3B0aW9uYWw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICoge0Bpbmhlcml0ZG9jIENvbnZlcnRlci5icmFuZH1cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGJyYW5kKCk6IHN0cmluZ3x1bmRlZmluZWQge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnJhbmQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICoge0Bpbmhlcml0ZG9jIENvbnZlcnRlci5jb252ZXJ0fVxuICAgICAqL1xuICAgIHB1YmxpYyBjb252ZXJ0KGZyb206IHVua25vd24sIGNvbnRleHQ/OiBUQyk6IFJlc3VsdDxUPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb252ZXJ0ZXIoZnJvbSwgdGhpcywgY29udGV4dCA/PyB0aGlzLl9kZWZhdWx0Q29udGV4dCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICoge0Bpbmhlcml0ZG9jIENvbnZlcnRlci5jb252ZXJ0T3B0aW9uYWx9XG4gICAgICovXG4gICAgcHVibGljIGNvbnZlcnRPcHRpb25hbChmcm9tOiB1bmtub3duLCBjb250ZXh0PzogVEMsIG9uRXJyb3I/OiBPbkVycm9yKTogUmVzdWx0PFR8dW5kZWZpbmVkPiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX2NvbnZlcnRlcihmcm9tLCB0aGlzLCB0aGlzLl9jb250ZXh0KGNvbnRleHQpKTtcbiAgICAgICAgaWYgKHJlc3VsdC5pc0ZhaWx1cmUoKSkge1xuICAgICAgICAgICAgb25FcnJvciA9IG9uRXJyb3IgPz8gJ2lnbm9yZUVycm9ycyc7XG4gICAgICAgICAgICByZXR1cm4gKChmcm9tID09PSB1bmRlZmluZWQpIHx8IG9uRXJyb3IgPT09ICdpZ25vcmVFcnJvcnMnKSA/IHN1Y2NlZWQodW5kZWZpbmVkKSA6IHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHtAaW5oZXJpdGRvYyBDb252ZXJ0ZXIub3B0aW9uYWx9XG4gICAgICovXG4gICAgcHVibGljIG9wdGlvbmFsKG9uRXJyb3I/OiBPbkVycm9yKTogQ29udmVydGVyPFR8dW5kZWZpbmVkLCBUQz4ge1xuICAgICAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VHx1bmRlZmluZWQsIFRDPiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgICAgICBvbkVycm9yID0gb25FcnJvciA/PyAnZmFpbE9uRXJyb3InO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29udmVydE9wdGlvbmFsKGZyb20sIHRoaXMuX2NvbnRleHQoY29udGV4dCksIG9uRXJyb3IpO1xuICAgICAgICB9KS5fd2l0aCh0aGlzLl90cmFpdHMoeyBpc09wdGlvbmFsOiB0cnVlIH0pKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB7QGluaGVyaXRkb2MgQ29udmVydGVyLm1hcH1cbiAgICAgKi9cbiAgICBwdWJsaWMgbWFwPFQyPihtYXBwZXI6IChmcm9tOiBUKSA9PiBSZXN1bHQ8VDI+KTogQ29udmVydGVyPFQyLCBUQz4ge1xuICAgICAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXI8VDIsIFRDPigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxUMiwgVEM+LCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGlubmVyUmVzdWx0ID0gdGhpcy5fY29udmVydGVyKGZyb20sIHRoaXMsIHRoaXMuX2NvbnRleHQoY29udGV4dCkpO1xuICAgICAgICAgICAgaWYgKGlubmVyUmVzdWx0LmlzU3VjY2VzcygpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hcHBlcihpbm5lclJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFpbChpbm5lclJlc3VsdC5tZXNzYWdlKTtcbiAgICAgICAgfSkuX3dpdGgodGhpcy5fdHJhaXRzKCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHtAaW5oZXJpdGRvYyBDb252ZXJ0ZXIubWFwQ29udmVydH1cbiAgICAgKi9cbiAgICBwdWJsaWMgbWFwQ29udmVydDxUMj4obWFwQ29udmVydGVyOiBDb252ZXJ0ZXI8VDI+KTogQ29udmVydGVyPFQyLCBUQz4ge1xuICAgICAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXI8VDIsIFRDPigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxUMiwgVEM+LCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGlubmVyUmVzdWx0ID0gdGhpcy5fY29udmVydGVyKGZyb20sIHRoaXMsIHRoaXMuX2NvbnRleHQoY29udGV4dCkpO1xuICAgICAgICAgICAgaWYgKGlubmVyUmVzdWx0LmlzU3VjY2VzcygpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hcENvbnZlcnRlci5jb252ZXJ0KGlubmVyUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWlsKGlubmVyUmVzdWx0Lm1lc3NhZ2UpO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmV0dXJuLWFzc2lnblxuICAgICAgICB9KS5fd2l0aCh0aGlzLl90cmFpdHMoKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICoge0Bpbmhlcml0ZG9jIENvbnZlcnRlci5tYXBJdGVtc31cbiAgICAgKi9cbiAgICBwdWJsaWMgbWFwSXRlbXM8VEk+KG1hcHBlcjogKGZyb206IHVua25vd24pID0+IFJlc3VsdDxUST4pOiBDb252ZXJ0ZXI8VElbXSwgVEM+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyPFRJW10sIFRDPigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxUSVtdLCBUQz4sIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnZlcnRlcihmcm9tLCB0aGlzLCB0aGlzLl9jb250ZXh0KGNvbnRleHQpKS5vblN1Y2Nlc3MoKGl0ZW1zKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoaXRlbXMpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtYXBSZXN1bHRzKGl0ZW1zLm1hcCgoaSkgPT4gbWFwcGVyKGkpKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWlsKCdDYW5ub3QgbWFwIGl0ZW1zIC0gbm90IGFuIGFycmF5Jyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICoge0Bpbmhlcml0ZG9jIENvbnZlcnRlci5tYXBDb252ZXJ0SXRlbXN9XG4gICAgICovXG4gICAgcHVibGljIG1hcENvbnZlcnRJdGVtczxUST4obWFwQ29udmVydGVyOiBDb252ZXJ0ZXI8VEksIHVua25vd24+KTogQ29udmVydGVyPFRJW10sIFRDPiB7XG4gICAgICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcjxUSVtdLCBUQz4oKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VElbXSwgVEM+LCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jb252ZXJ0ZXIoZnJvbSwgdGhpcywgdGhpcy5fY29udGV4dChjb250ZXh0KSkub25TdWNjZXNzKChpdGVtcykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGl0ZW1zKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWFwUmVzdWx0cyhpdGVtcy5tYXAoKGkpID0+IG1hcENvbnZlcnRlci5jb252ZXJ0KGkpKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWlsKCdDYW5ub3QgbWFwIGl0ZW1zIC0gbm90IGFuIGFycmF5Jyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICoge0Bpbmhlcml0ZG9jIENvbnZlcnRlci53aXRoVHlwZUd1YXJkfVxuICAgICAqL1xuICAgIHB1YmxpYyB3aXRoVHlwZUd1YXJkPFRJPihndWFyZDogKGZyb206IHVua25vd24pID0+IGZyb20gaXMgVEksIG1lc3NhZ2U/OiBzdHJpbmcpOiBDb252ZXJ0ZXI8VEksIFRDPiB7XG4gICAgICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcjxUSSwgVEM+KChmcm9tOiB1bmtub3duLCBfc2VsZjogQ29udmVydGVyPFRJLCBUQz4sIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnZlcnRlcihmcm9tLCB0aGlzLCB0aGlzLl9jb250ZXh0KGNvbnRleHQpKS5vblN1Y2Nlc3MoKGlubmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IG1lc3NhZ2UgPz8gJ2ludmFsaWQgdHlwZSc7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGd1YXJkKGlubmVyKSA/IHN1Y2NlZWQoaW5uZXIpIDogZmFpbChgJHttZXNzYWdlfTogJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB7QGluaGVyaXRkb2MgQ29udmVydGVyLndpdGhJdGVtVHlwZUd1YXJkfVxuICAgICAqL1xuICAgIHB1YmxpYyB3aXRoSXRlbVR5cGVHdWFyZDxUST4oZ3VhcmQ6IChmcm9tOiB1bmtub3duKSA9PiBmcm9tIGlzIFRJLCBtZXNzYWdlPzogc3RyaW5nKTogQ29udmVydGVyPFRJW10sIFRDPiB7XG4gICAgICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcjxUSVtdLCBUQz4oKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VElbXSwgVEM+LCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jb252ZXJ0ZXIoZnJvbSwgdGhpcywgdGhpcy5fY29udGV4dChjb250ZXh0KSkub25TdWNjZXNzKChpdGVtcykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGl0ZW1zKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWFwUmVzdWx0cyhpdGVtcy5tYXAoKGkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBtZXNzYWdlID8/ICdpbnZhbGlkIHR5cGUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGd1YXJkKGkpID8gc3VjY2VlZChpKSA6IGZhaWwoYCR7bWVzc2FnZX06ICR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9YCk7XG4gICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhaWwoJ0Nhbm5vdCBndWFyZCBpdGVtIHR5cGUgLSBub3QgYW4gYXJyYXknKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB7QGluaGVyaXRkb2MgQ29udmVydGVyLndpdGhDb25zdHJhaW50fVxuICAgICAqL1xuICAgIHB1YmxpYyB3aXRoQ29uc3RyYWludChcbiAgICAgICAgY29uc3RyYWludDogKHZhbDogVCkgPT4gYm9vbGVhbnxSZXN1bHQ8VD4sXG4gICAgICAgIG9wdGlvbnM/OiBDb25zdHJhaW50T3B0aW9ucyxcbiAgICApOiBDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyPFQsIFRDPigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxULCBUQz4sIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fY29udmVydGVyKGZyb20sIHRoaXMsIHRoaXMuX2NvbnRleHQoY29udGV4dCkpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0cmFpbnRSZXN1bHQgPSBjb25zdHJhaW50KHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjb25zdHJhaW50UmVzdWx0ID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRSZXN1bHRcbiAgICAgICAgICAgICAgICAgICAgICAgID8gcmVzdWx0XG4gICAgICAgICAgICAgICAgICAgICAgICA6IGZhaWwoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYFwiJHtKU09OLnN0cmluZ2lmeShyZXN1bHQudmFsdWUpfVwiOiAke29wdGlvbnM/LmRlc2NyaXB0aW9uID8/ICdkb2VzIG5vdCBtZWV0IGNvbnN0cmFpbnQnfWBcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjb25zdHJhaW50UmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfSkuX3dpdGgodGhpcy5fdHJhaXRzKCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHtAaW5oZXJpdGRvYyBDb252ZXJ0ZXIud2l0aEJyYW5kfVxuICAgICAqL1xuICAgIHB1YmxpYyB3aXRoQnJhbmQ8QiBleHRlbmRzIHN0cmluZz4oYnJhbmQ6IEIpOiBDb252ZXJ0ZXI8QnJhbmQ8VCwgQj4sIFRDPiB7XG4gICAgICAgIGlmICh0aGlzLl9icmFuZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgcmVwbGFjZSBleGlzdGluZyBicmFuZCBcIiR7dGhpcy5fYnJhbmR9XCIgd2l0aCBcIiR7YnJhbmR9XCIuYCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXI8QnJhbmQ8VCwgQj4sIFRDPigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxULCBUQz4sIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnZlcnRlcihmcm9tLCB0aGlzLCB0aGlzLl9jb250ZXh0KGNvbnRleHQpKS5vblN1Y2Nlc3MoKHYpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3VjY2VlZCh2IGFzIEJyYW5kPFQsIEI+KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KS5fd2l0aCh0aGlzLl90cmFpdHMoeyBicmFuZCB9KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHJvdGVjdGVkIF9jb250ZXh0KHN1cHBsaWVkPzogVEMpOiBUQ3x1bmRlZmluZWQge1xuICAgICAgICByZXR1cm4gc3VwcGxpZWQgPz8gdGhpcy5fZGVmYXVsdENvbnRleHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHJvdGVjdGVkIF90cmFpdHModHJhaXRzPzogUGFydGlhbDxDb252ZXJ0ZXJUcmFpdHM+KTogQ29udmVydGVyVHJhaXRzIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGlzT3B0aW9uYWw6IHRoaXMuaXNPcHRpb25hbCxcbiAgICAgICAgICAgIGJyYW5kOiB0aGlzLmJyYW5kLFxuICAgICAgICAgICAgLi4uKHRyYWl0cyA/PyB7fSksXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHJvdGVjdGVkIF93aXRoKHRyYWl0czogUGFydGlhbDxDb252ZXJ0ZXJUcmFpdHM+KTogdGhpcyB7XG4gICAgICAgIHRoaXMuX2lzT3B0aW9uYWwgPSAodHJhaXRzLmlzT3B0aW9uYWwgPT09IHRydWUpO1xuICAgICAgICB0aGlzLl9icmFuZCA9ICh0cmFpdHMuYnJhbmQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4iXX0=