@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.
- package/LICENSE +0 -0
- package/README.md +4 -0
- package/brand.d.ts +8 -0
- package/brand.d.ts.map +1 -0
- package/brand.js +24 -0
- package/converter.d.ts +149 -105
- package/converter.d.ts.map +1 -0
- package/converter.js +59 -72
- package/converters.d.ts +432 -194
- package/converters.d.ts.map +1 -0
- package/converters.js +335 -224
- package/csvHelpers.d.ts +7 -0
- package/csvHelpers.d.ts.map +1 -0
- package/csvHelpers.js +14 -4
- package/extendedArray.d.ts +46 -0
- package/extendedArray.d.ts.map +1 -0
- package/extendedArray.js +53 -8
- package/formatter.d.ts +53 -0
- package/formatter.d.ts.map +1 -0
- package/formatter.js +27 -4
- package/hash.d.ts +51 -0
- package/hash.d.ts.map +1 -0
- package/hash.js +168 -0
- package/index.d.ts +7 -2
- package/index.d.ts.map +1 -0
- package/index.js +16 -5
- package/logger.d.ts +3 -2
- package/logger.d.ts.map +1 -0
- package/logger.js +12 -12
- package/package.json +24 -20
- package/rangeOf.d.ts +96 -0
- package/rangeOf.d.ts.map +1 -0
- package/rangeOf.js +81 -2
- package/result.d.ts +393 -39
- package/result.d.ts.map +1 -0
- package/result.js +259 -49
- package/ts-utils.d.ts +2475 -0
- package/tsdoc-metadata.json +11 -0
- package/utils.d.ts +71 -27
- package/utils.d.ts.map +1 -0
- package/utils.js +82 -37
- package/validation/boolean.d.ts +27 -0
- package/validation/boolean.d.ts.map +1 -0
- package/validation/boolean.js +59 -0
- package/validation/classes.d.ts +5 -0
- package/validation/classes.d.ts.map +1 -0
- package/validation/classes.js +34 -0
- package/validation/field.d.ts +43 -0
- package/validation/field.d.ts.map +1 -0
- package/validation/field.js +72 -0
- package/validation/genericValidator.d.ts +84 -0
- package/validation/genericValidator.d.ts.map +1 -0
- package/validation/genericValidator.js +138 -0
- package/validation/index.d.ts +7 -0
- package/validation/index.d.ts.map +1 -0
- package/validation/index.js +59 -0
- package/validation/number.d.ts +27 -0
- package/validation/number.d.ts.map +1 -0
- package/validation/number.js +57 -0
- package/validation/object.d.ts +115 -0
- package/validation/object.d.ts.map +1 -0
- package/validation/object.js +143 -0
- package/validation/string.d.ts +27 -0
- package/validation/string.d.ts.map +1 -0
- package/validation/string.js +57 -0
- package/validation/traits.d.ts +68 -0
- package/validation/traits.d.ts.map +1 -0
- package/validation/traits.js +58 -0
- package/validation/validator.d.ts +82 -0
- package/validation/validator.d.ts.map +1 -0
- package/validation/validator.js +24 -0
- package/validation/validatorBase.d.ts +25 -0
- package/validation/validatorBase.d.ts.map +1 -0
- package/validation/validatorBase.js +44 -0
- package/validation/validators.d.ts +32 -0
- package/validation/validators.d.ts.map +1 -0
- package/validation/validators.js +59 -0
package/converters.js
CHANGED
|
@@ -33,36 +33,50 @@ const extendedArray_1 = require("./extendedArray");
|
|
|
33
33
|
const mustache_1 = __importDefault(require("mustache"));
|
|
34
34
|
const utils_1 = require("./utils");
|
|
35
35
|
/**
|
|
36
|
-
* The @
|
|
37
|
-
*
|
|
36
|
+
* The {@link Converters.StringConverter | StringConverter} class extends {@link BaseConverter}
|
|
37
|
+
* to provide string-specific helper methods.
|
|
38
|
+
* @public
|
|
38
39
|
*/
|
|
39
40
|
class StringConverter extends converter_1.BaseConverter {
|
|
40
41
|
/**
|
|
41
|
-
* Construct a new @
|
|
42
|
-
* @param defaultContext Optional context used by the conversion
|
|
43
|
-
* @param traits Optional traits to be applied to the conversion
|
|
44
|
-
* @param converter Optional
|
|
42
|
+
* Construct a new {@link Converters.StringConverter | StringConverter}.
|
|
43
|
+
* @param defaultContext - Optional context used by the conversion.
|
|
44
|
+
* @param traits - Optional traits to be applied to the conversion.
|
|
45
|
+
* @param converter - Optional conversion function to be used for the conversion.
|
|
45
46
|
*/
|
|
46
47
|
constructor(defaultContext, traits, converter = StringConverter._convert) {
|
|
47
48
|
super(converter, defaultContext, traits);
|
|
48
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* @internal
|
|
52
|
+
*/
|
|
49
53
|
static _convert(from) {
|
|
50
54
|
return typeof from === 'string'
|
|
51
|
-
? result_1.succeed(from)
|
|
52
|
-
: result_1.fail(`Not a string: ${JSON.stringify(from)}`);
|
|
55
|
+
? (0, result_1.succeed)(from)
|
|
56
|
+
: (0, result_1.fail)(`Not a string: ${JSON.stringify(from)}`);
|
|
53
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* @internal
|
|
60
|
+
*/
|
|
54
61
|
static _wrap(wrapped, converter, traits) {
|
|
55
62
|
return new StringConverter(undefined, undefined, (from) => {
|
|
56
63
|
return wrapped.convert(from).onSuccess(converter);
|
|
57
64
|
})._with(wrapped._traits(traits));
|
|
58
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Concrete implementation of {@link Converters.StringConverter.(matching#string) | StringConverter.matching(string)},
|
|
68
|
+
* {@link Converters.StringConverter.(matching#array) | StringConverter.matching(string[])},
|
|
69
|
+
* {@link Converters.StringConverter.(matching#set) | StringConverter.matching(Set<string>)}, and
|
|
70
|
+
* {@link Converters.StringConverter.(matching#regexp) | StringConverter.matching(RegExp)}.
|
|
71
|
+
* @internal
|
|
72
|
+
*/
|
|
59
73
|
matching(match, options) {
|
|
60
74
|
const message = options === null || options === void 0 ? void 0 : options.message;
|
|
61
75
|
if (typeof match === 'string') {
|
|
62
76
|
return StringConverter._wrap(this, (from) => {
|
|
63
77
|
return (match === from)
|
|
64
|
-
? result_1.succeed(from)
|
|
65
|
-
: result_1.fail(message
|
|
78
|
+
? (0, result_1.succeed)(from)
|
|
79
|
+
: (0, result_1.fail)(message
|
|
66
80
|
? `"${from}": ${message}`
|
|
67
81
|
: `"${from}": does not match "${match}"`);
|
|
68
82
|
});
|
|
@@ -70,8 +84,8 @@ class StringConverter extends converter_1.BaseConverter {
|
|
|
70
84
|
else if (match instanceof RegExp) {
|
|
71
85
|
return StringConverter._wrap(this, (from) => {
|
|
72
86
|
return (match.test(from))
|
|
73
|
-
? result_1.succeed(from)
|
|
74
|
-
: result_1.fail(message
|
|
87
|
+
? (0, result_1.succeed)(from)
|
|
88
|
+
: (0, result_1.fail)(message
|
|
75
89
|
? `"${from}": ${message}`
|
|
76
90
|
: `"${from}": does not match "${match}"`);
|
|
77
91
|
});
|
|
@@ -79,8 +93,8 @@ class StringConverter extends converter_1.BaseConverter {
|
|
|
79
93
|
else if (match instanceof Set) {
|
|
80
94
|
return StringConverter._wrap(this, (from) => {
|
|
81
95
|
return (match.has(from))
|
|
82
|
-
? result_1.succeed(from)
|
|
83
|
-
: result_1.fail(message
|
|
96
|
+
? (0, result_1.succeed)(from)
|
|
97
|
+
: (0, result_1.fail)(message
|
|
84
98
|
? `"${from}": ${message}`
|
|
85
99
|
: `"${from}": not found in set`);
|
|
86
100
|
});
|
|
@@ -88,8 +102,8 @@ class StringConverter extends converter_1.BaseConverter {
|
|
|
88
102
|
else {
|
|
89
103
|
return StringConverter._wrap(this, (from) => {
|
|
90
104
|
return (match.includes(from))
|
|
91
|
-
? result_1.succeed(from)
|
|
92
|
-
: result_1.fail(message
|
|
105
|
+
? (0, result_1.succeed)(from)
|
|
106
|
+
: (0, result_1.fail)(message
|
|
93
107
|
? `"${from}": ${message}`
|
|
94
108
|
: `"${from}": not found in [${match.join(',')}]`);
|
|
95
109
|
});
|
|
@@ -100,113 +114,138 @@ exports.StringConverter = StringConverter;
|
|
|
100
114
|
/**
|
|
101
115
|
* A converter to convert unknown to string. Values of type
|
|
102
116
|
* string succeed. Anything else fails.
|
|
117
|
+
* @public
|
|
103
118
|
*/
|
|
104
119
|
exports.string = new StringConverter();
|
|
105
120
|
/**
|
|
106
|
-
* Helper function to create a
|
|
107
|
-
* template conversions supplied at construction time or at
|
|
108
|
-
*
|
|
121
|
+
* Helper function to create a {@link Converters.StringConverter | StringConverter} which converts
|
|
122
|
+
* `unknown` to `string`, applying template conversions supplied at construction time or at
|
|
123
|
+
* runtime as context.
|
|
124
|
+
* @remarks
|
|
125
|
+
* Template conversions are applied using `mustache` syntax.
|
|
126
|
+
* @param defaultContext - Optional default context to use for template values.
|
|
127
|
+
* @returns A new {@link Converter} returning `string`.
|
|
128
|
+
* @public
|
|
109
129
|
*/
|
|
110
130
|
function templateString(defaultContext) {
|
|
111
131
|
return new StringConverter(defaultContext, undefined, (from, _self, context) => {
|
|
112
132
|
if (typeof from !== 'string') {
|
|
113
|
-
return result_1.fail(`Not a string: ${JSON.stringify(from)}`);
|
|
133
|
+
return (0, result_1.fail)(`Not a string: ${JSON.stringify(from)}`);
|
|
114
134
|
}
|
|
115
|
-
return result_1.captureResult(() => mustache_1.default.render(from, context));
|
|
135
|
+
return (0, result_1.captureResult)(() => mustache_1.default.render(from, context));
|
|
116
136
|
});
|
|
117
137
|
}
|
|
118
138
|
exports.templateString = templateString;
|
|
119
139
|
/**
|
|
120
|
-
*
|
|
140
|
+
* Helper function to create a {@link Converter} which converts `unknown` to one of a set of supplied
|
|
141
|
+
* enumerated values. Anything else fails.
|
|
142
|
+
*
|
|
143
|
+
* @remarks
|
|
121
144
|
* Allowed enumerated values can also be supplied as context at conversion time.
|
|
122
|
-
* @param values Array of allowed values
|
|
145
|
+
* @param values - Array of allowed values.
|
|
146
|
+
* @returns A new {@link Converter} returning `<T>`.
|
|
147
|
+
* @public
|
|
123
148
|
*/
|
|
124
149
|
function enumeratedValue(values) {
|
|
125
150
|
return new converter_1.BaseConverter((from, _self, context) => {
|
|
126
151
|
const v = context !== null && context !== void 0 ? context : values;
|
|
127
152
|
const index = v.indexOf(from);
|
|
128
|
-
return (index >= 0 ? result_1.succeed(v[index]) : result_1.fail(`Invalid enumerated value ${JSON.stringify(from)}`));
|
|
153
|
+
return (index >= 0 ? (0, result_1.succeed)(v[index]) : (0, result_1.fail)(`Invalid enumerated value ${JSON.stringify(from)}`));
|
|
129
154
|
});
|
|
130
155
|
}
|
|
131
156
|
exports.enumeratedValue = enumeratedValue;
|
|
132
157
|
/**
|
|
133
|
-
*
|
|
134
|
-
* values
|
|
135
|
-
*
|
|
136
|
-
*
|
|
158
|
+
* Helper function to create a {@link Converter} which converts `unknown` to one of a set of supplied enumerated
|
|
159
|
+
* values, mapping any of multiple supplied values to the enumeration.
|
|
160
|
+
* @remarks
|
|
161
|
+
* Enables mapping of multiple input values to a consistent internal representation (so e.g. `'y'`, `'yes'`,
|
|
162
|
+
* `'true'`, `1` and `true` can all map to boolean `true`)
|
|
163
|
+
* @param map - An array of tuples describing the mapping. The first element of each tuple is the result
|
|
137
164
|
* value, the second is the set of values that map to the result. Tuples are evaluated in the order
|
|
138
165
|
* supplied and are not checked for duplicates.
|
|
139
|
-
* @param message
|
|
140
|
-
* @returns
|
|
166
|
+
* @param message - An optional error message.
|
|
167
|
+
* @returns A {@link Converter} which applies the mapping and yields `<T>` on success.
|
|
168
|
+
* @public
|
|
141
169
|
*/
|
|
142
170
|
function mappedEnumeratedValue(map, message) {
|
|
143
171
|
return new converter_1.BaseConverter((from, _self, _context) => {
|
|
144
172
|
for (const item of map) {
|
|
145
173
|
if (item[1].includes(from)) {
|
|
146
|
-
return result_1.succeed(item[0]);
|
|
174
|
+
return (0, result_1.succeed)(item[0]);
|
|
147
175
|
}
|
|
148
176
|
}
|
|
149
|
-
return result_1.fail(message ? `${JSON.stringify(from)}: ${message}` : `Cannot map '${JSON.stringify(from)}' to a supported value`);
|
|
177
|
+
return (0, result_1.fail)(message ? `${JSON.stringify(from)}: ${message}` : `Cannot map '${JSON.stringify(from)}' to a supported value`);
|
|
150
178
|
});
|
|
151
179
|
}
|
|
152
180
|
exports.mappedEnumeratedValue = mappedEnumeratedValue;
|
|
153
181
|
/**
|
|
154
|
-
*
|
|
155
|
-
* comparison succeeds, fails otherwise.
|
|
156
|
-
* @param value The value to be compared
|
|
182
|
+
* Helper function to create a {@link Converter} which converts `unknown` to some supplied literal value. Succeeds with
|
|
183
|
+
* the supplied value if an identity comparison succeeds, fails otherwise.
|
|
184
|
+
* @param value - The value to be compared.
|
|
185
|
+
* @returns A {@link Converter} which returns the supplied value on success.
|
|
186
|
+
* @public
|
|
157
187
|
*/
|
|
158
188
|
function literal(value) {
|
|
159
189
|
return new converter_1.BaseConverter((from, _self, _context) => {
|
|
160
|
-
return (from === value) ? result_1.succeed(value) : result_1.fail(`${JSON.stringify(from)}: does not match ${JSON.stringify(value)}`);
|
|
190
|
+
return (from === value) ? (0, result_1.succeed)(value) : (0, result_1.fail)(`${JSON.stringify(from)}: does not match ${JSON.stringify(value)}`);
|
|
161
191
|
});
|
|
162
192
|
}
|
|
163
193
|
exports.literal = literal;
|
|
164
194
|
/**
|
|
165
195
|
* Deprecated alias for @see literal
|
|
166
|
-
* @param value The value to be compared
|
|
167
|
-
* @deprecated
|
|
196
|
+
* @param value - The value to be compared.
|
|
197
|
+
* @deprecated Use {@link Converters.literal} instead.
|
|
198
|
+
* @internal
|
|
168
199
|
*/
|
|
169
200
|
exports.value = literal;
|
|
170
201
|
/**
|
|
171
|
-
* A
|
|
172
|
-
*
|
|
202
|
+
* A {@link Converter} which converts `unknown` to a `number`.
|
|
203
|
+
* @remarks
|
|
204
|
+
* Numbers and strings with a numeric format succeed. Anything else fails.
|
|
205
|
+
* @public
|
|
173
206
|
*/
|
|
174
207
|
exports.number = new converter_1.BaseConverter((from) => {
|
|
175
208
|
if (typeof from !== 'number') {
|
|
176
209
|
const num = (typeof from === 'string' ? Number(from) : NaN);
|
|
177
210
|
return isNaN(num)
|
|
178
|
-
? result_1.fail(`Not a number: ${JSON.stringify(from)}`)
|
|
179
|
-
: result_1.succeed(num);
|
|
211
|
+
? (0, result_1.fail)(`Not a number: ${JSON.stringify(from)}`)
|
|
212
|
+
: (0, result_1.succeed)(num);
|
|
180
213
|
}
|
|
181
|
-
return result_1.succeed(from);
|
|
214
|
+
return (0, result_1.succeed)(from);
|
|
182
215
|
});
|
|
183
216
|
/**
|
|
184
|
-
* A
|
|
185
|
-
*
|
|
186
|
-
*
|
|
217
|
+
* A {@link Converter} which converts `unknown` to `boolean`.
|
|
218
|
+
* @remarks
|
|
219
|
+
* Boolean values or the case-insensitive strings `'true'` and `'false'` succeed.
|
|
220
|
+
* Anything else fails.
|
|
221
|
+
* @public
|
|
187
222
|
*/
|
|
188
223
|
exports.boolean = new converter_1.BaseConverter((from) => {
|
|
189
224
|
if (typeof from === 'boolean') {
|
|
190
|
-
return result_1.succeed(from);
|
|
225
|
+
return (0, result_1.succeed)(from);
|
|
191
226
|
}
|
|
192
227
|
else if (typeof from === 'string') {
|
|
193
228
|
switch (from.toLowerCase()) {
|
|
194
|
-
case 'true': return result_1.succeed(true);
|
|
195
|
-
case 'false': return result_1.succeed(false);
|
|
229
|
+
case 'true': return (0, result_1.succeed)(true);
|
|
230
|
+
case 'false': return (0, result_1.succeed)(false);
|
|
196
231
|
}
|
|
197
232
|
}
|
|
198
|
-
return result_1.fail(`Not a boolean: ${JSON.stringify(from)}`);
|
|
233
|
+
return (0, result_1.fail)(`Not a boolean: ${JSON.stringify(from)}`);
|
|
199
234
|
});
|
|
200
235
|
/**
|
|
201
|
-
* A
|
|
202
|
-
* are returned. Anything else returns
|
|
236
|
+
* A {@link Converter} which converts an optional `string` value. Values of type
|
|
237
|
+
* `string` are returned. Anything else returns {@link Success} with value `undefined`.
|
|
238
|
+
* @public
|
|
203
239
|
*/
|
|
204
240
|
exports.optionalString = exports.string.optional();
|
|
205
241
|
/**
|
|
206
|
-
*
|
|
207
|
-
* by separating at a supplied delimiter.
|
|
208
|
-
*
|
|
209
|
-
*
|
|
242
|
+
* Helper function to create a {@link Converter} which converts any `string` into an
|
|
243
|
+
* array of `string`, by separating at a supplied delimiter.
|
|
244
|
+
* @remarks
|
|
245
|
+
* Delimeter may also be supplied as context at conversion time.
|
|
246
|
+
* @param delimiter - The delimiter at which to split.
|
|
247
|
+
* @returns A new {@link Converter} returning `string[]`.
|
|
248
|
+
* @public
|
|
210
249
|
*/
|
|
211
250
|
function delimitedString(delimiter, options = 'filtered') {
|
|
212
251
|
return new converter_1.BaseConverter((from, _self, context) => {
|
|
@@ -216,55 +255,65 @@ function delimitedString(delimiter, options = 'filtered') {
|
|
|
216
255
|
if (options !== 'all') {
|
|
217
256
|
strings = strings.filter((s) => (s.trim().length > 0));
|
|
218
257
|
}
|
|
219
|
-
return result_1.succeed(strings);
|
|
258
|
+
return (0, result_1.succeed)(strings);
|
|
220
259
|
}
|
|
221
|
-
return result_1.fail(result.message);
|
|
260
|
+
return (0, result_1.fail)(result.message);
|
|
222
261
|
});
|
|
223
262
|
}
|
|
224
263
|
exports.delimitedString = delimitedString;
|
|
225
264
|
/**
|
|
226
|
-
* A
|
|
265
|
+
* A {@link Converter} which converts an iso formatted string, a number or a `Date` object to
|
|
266
|
+
* a `Date` object.
|
|
267
|
+
* @public
|
|
227
268
|
*/
|
|
228
269
|
exports.isoDate = new converter_1.BaseConverter((from) => {
|
|
229
270
|
if (typeof from === 'string') {
|
|
230
271
|
const dt = luxon_1.DateTime.fromISO(from);
|
|
231
272
|
if (dt.isValid) {
|
|
232
|
-
return result_1.succeed(dt.toJSDate());
|
|
273
|
+
return (0, result_1.succeed)(dt.toJSDate());
|
|
233
274
|
}
|
|
234
|
-
return result_1.fail(`Invalid date: ${dt.invalidExplanation}`);
|
|
275
|
+
return (0, result_1.fail)(`Invalid date: ${dt.invalidExplanation}`);
|
|
235
276
|
}
|
|
236
277
|
else if (typeof from === 'number') {
|
|
237
|
-
return result_1.succeed(new Date(from));
|
|
278
|
+
return (0, result_1.succeed)(new Date(from));
|
|
238
279
|
}
|
|
239
280
|
else if (from instanceof Date) {
|
|
240
|
-
return result_1.succeed(from);
|
|
281
|
+
return (0, result_1.succeed)(from);
|
|
241
282
|
}
|
|
242
|
-
return result_1.fail(`Cannot convert ${JSON.stringify(from)} to Date`);
|
|
283
|
+
return (0, result_1.fail)(`Cannot convert ${JSON.stringify(from)} to Date`);
|
|
243
284
|
});
|
|
244
285
|
/**
|
|
245
|
-
* A
|
|
246
|
-
*
|
|
247
|
-
*
|
|
286
|
+
* A {@link Converter} which converts an optional `number` value.
|
|
287
|
+
* @remarks
|
|
288
|
+
* Values of type `number` or numeric strings are converted and returned.
|
|
289
|
+
* Anything else returns {@link Success} with value `undefined`.
|
|
290
|
+
* @public
|
|
248
291
|
*/
|
|
249
292
|
exports.optionalNumber = exports.number.optional();
|
|
250
293
|
/**
|
|
251
|
-
* A
|
|
252
|
-
*
|
|
253
|
-
*
|
|
294
|
+
* A {@link Converter} to convert an optional `boolean` value.
|
|
295
|
+
* @remarks
|
|
296
|
+
* Values of type `boolean` or strings that match (case-insensitive) `'true'`
|
|
297
|
+
* or `'false'` are converted and returned. Anything else returns {@link Success}
|
|
298
|
+
* with value `undefined`.
|
|
299
|
+
* @public
|
|
254
300
|
*/
|
|
255
301
|
exports.optionalBoolean = exports.boolean.optional();
|
|
256
302
|
/**
|
|
257
|
-
* A helper
|
|
258
|
-
* in sequence, returning the first successful
|
|
259
|
-
* if none of the supplied converters can convert the value.
|
|
260
|
-
*
|
|
261
|
-
* If onError is
|
|
303
|
+
* A helper function to create a {@link Converter} for polymorphic values. Returns a
|
|
304
|
+
* converter which Invokes the wrapped converters in sequence, returning the first successful
|
|
305
|
+
* result. Returns an error if none of the supplied converters can convert the value.
|
|
306
|
+
* @remarks
|
|
307
|
+
* If `onError` is `ignoreErrors` (default), then errors from any of the
|
|
262
308
|
* converters are ignored provided that some converter succeeds. If
|
|
263
|
-
* onError is
|
|
309
|
+
* onError is `failOnError`, then an error from any converter fails the entire
|
|
264
310
|
* conversion.
|
|
265
311
|
*
|
|
266
|
-
* @param converters An ordered list of converters to be considered
|
|
267
|
-
* @param onError Specifies treatment of unconvertable elements
|
|
312
|
+
* @param converters - An ordered list of {@link Converter | converters} to be considered.
|
|
313
|
+
* @param onError - Specifies treatment of unconvertable elements.
|
|
314
|
+
* @returns A new {@link Converter} which yields a value from the union of the types returned
|
|
315
|
+
* by the wrapped converters.
|
|
316
|
+
* @public
|
|
268
317
|
*/
|
|
269
318
|
function oneOf(converters, onError = 'ignoreErrors') {
|
|
270
319
|
return new converter_1.BaseConverter((from, _self, context) => {
|
|
@@ -281,21 +330,24 @@ function oneOf(converters, onError = 'ignoreErrors') {
|
|
|
281
330
|
errors.push(result.message);
|
|
282
331
|
}
|
|
283
332
|
}
|
|
284
|
-
return result_1.fail(`No matching converter for ${JSON.stringify(from)}: ${errors.join('\n')}`);
|
|
333
|
+
return (0, result_1.fail)(`No matching converter for ${JSON.stringify(from)}: ${errors.join('\n')}`);
|
|
285
334
|
});
|
|
286
335
|
}
|
|
287
336
|
exports.oneOf = oneOf;
|
|
288
337
|
/**
|
|
289
|
-
* A helper
|
|
290
|
-
*
|
|
291
|
-
* is '
|
|
292
|
-
*
|
|
293
|
-
* @param
|
|
338
|
+
* A helper function to create a {@link Converter} which converts `unknown` to an array of `<T>`.
|
|
339
|
+
* @remarks
|
|
340
|
+
* If `onError` is `'failOnError'` (default), then the entire conversion fails if any element cannot
|
|
341
|
+
* be converted. If `onError` is `'ignoreErrors'`, then failing elements are silently ignored.
|
|
342
|
+
* @param converter - {@link Converter} used to convert each item in the array.
|
|
343
|
+
* @param ignoreErrors - Specifies treatment of unconvertable elements.
|
|
344
|
+
* @returns A {@link Converter} which returns an array of `<T>`.
|
|
345
|
+
* @public
|
|
294
346
|
*/
|
|
295
347
|
function arrayOf(converter, onError = 'failOnError') {
|
|
296
348
|
return new converter_1.BaseConverter((from, _self, context) => {
|
|
297
349
|
if (!Array.isArray(from)) {
|
|
298
|
-
return result_1.fail(`Not an array: ${JSON.stringify(from)}`);
|
|
350
|
+
return (0, result_1.fail)(`Not an array: ${JSON.stringify(from)}`);
|
|
299
351
|
}
|
|
300
352
|
const successes = [];
|
|
301
353
|
const errors = [];
|
|
@@ -309,190 +361,228 @@ function arrayOf(converter, onError = 'failOnError') {
|
|
|
309
361
|
}
|
|
310
362
|
}
|
|
311
363
|
return (errors.length === 0) || (onError === 'ignoreErrors')
|
|
312
|
-
? result_1.succeed(successes)
|
|
313
|
-
: result_1.fail(errors.join('\n'));
|
|
364
|
+
? (0, result_1.succeed)(successes)
|
|
365
|
+
: (0, result_1.fail)(errors.join('\n'));
|
|
314
366
|
});
|
|
315
367
|
}
|
|
316
368
|
exports.arrayOf = arrayOf;
|
|
317
369
|
/**
|
|
318
|
-
* A helper
|
|
319
|
-
*
|
|
320
|
-
* is '
|
|
321
|
-
*
|
|
322
|
-
* @param
|
|
370
|
+
* A helper function to create a {@link Converter} which converts `unknown` to {@link ExtendedArray | ExtendedArray<T>}.
|
|
371
|
+
* @remarks
|
|
372
|
+
* If `onError` is `'failOnError'` (default), then the entire conversion fails if any element cannot
|
|
373
|
+
* be converted. If `onError` is `'ignoreErrors'`, then failing elements are silently ignored.
|
|
374
|
+
* @param converter - {@link Converter} used to convert each item in the array
|
|
375
|
+
* @param ignoreErrors - Specifies treatment of unconvertable elements
|
|
376
|
+
* @beta
|
|
323
377
|
*/
|
|
324
378
|
function extendedArrayOf(label, converter, onError = 'failOnError') {
|
|
325
379
|
return arrayOf(converter, onError).map((items) => {
|
|
326
|
-
return result_1.captureResult(() => new extendedArray_1.ExtendedArray(label, ...items));
|
|
380
|
+
return (0, result_1.captureResult)(() => new extendedArray_1.ExtendedArray(label, ...items));
|
|
327
381
|
});
|
|
328
382
|
}
|
|
329
383
|
exports.extendedArrayOf = extendedArrayOf;
|
|
330
384
|
/**
|
|
331
|
-
* Converter to convert an unknown to an array of
|
|
332
|
-
*
|
|
385
|
+
* {@link Converter} to convert an `unknown` to an array of `string`.
|
|
386
|
+
* @remarks
|
|
387
|
+
* Returns {@link Success} with the the supplied value if it as an array
|
|
388
|
+
* of strings, returns {@link Failure} with an error message otherwise.
|
|
389
|
+
* @public
|
|
333
390
|
*/
|
|
334
391
|
exports.stringArray = arrayOf(exports.string);
|
|
335
392
|
/**
|
|
336
|
-
* Converter to convert an unknown to an array of
|
|
337
|
-
*
|
|
393
|
+
* {@link Converter} to convert an `unknown` to an array of `number`.
|
|
394
|
+
* @remarks
|
|
395
|
+
* Returns {@link Success} with the the supplied value if it as an array
|
|
396
|
+
* of numbers, returns {@link Failure} with an error message otherwise.
|
|
397
|
+
* @public
|
|
338
398
|
*/
|
|
339
399
|
exports.numberArray = arrayOf(exports.number);
|
|
400
|
+
/**
|
|
401
|
+
* Concrete implementation of {@link Converters.(recordOf:default) | Converters.recordOf(Converter<T>)},
|
|
402
|
+
* {@link Converters.(recordOf:withOnError) | Converters.recordOf(Converter<T>, 'fail'|'ignore')}, and
|
|
403
|
+
* {@link Converters.(recordOf:withOptions) | Converters.recordOf(Converter<T>, KeyedConverterOptions)}.
|
|
404
|
+
* @internal
|
|
405
|
+
*/
|
|
340
406
|
function recordOf(converter, option = 'fail') {
|
|
341
407
|
const options = (typeof option === 'string') ? { onError: option } : { onError: 'fail', ...option };
|
|
342
408
|
return new converter_1.BaseConverter((from, _self, context) => {
|
|
343
409
|
var _a, _b;
|
|
344
410
|
if ((typeof from !== 'object') || (from === null) || Array.isArray(from)) {
|
|
345
|
-
return result_1.fail(`Not a string-keyed object: ${JSON.stringify(from)}`);
|
|
411
|
+
return (0, result_1.fail)(`Not a string-keyed object: ${JSON.stringify(from)}`);
|
|
346
412
|
}
|
|
347
413
|
const record = {};
|
|
348
414
|
const errors = [];
|
|
349
415
|
for (const key in from) {
|
|
350
|
-
if (utils_1.isKeyOf(key, from)) {
|
|
351
|
-
const writeKeyResult = (_b = (_a = options.keyConverter) === null || _a === void 0 ? void 0 : _a.convert(key, context)) !== null && _b !== void 0 ? _b : result_1.succeed(key);
|
|
416
|
+
if ((0, utils_1.isKeyOf)(key, from)) {
|
|
417
|
+
const writeKeyResult = (_b = (_a = options.keyConverter) === null || _a === void 0 ? void 0 : _a.convert(key, context)) !== null && _b !== void 0 ? _b : (0, result_1.succeed)(key);
|
|
352
418
|
writeKeyResult.onSuccess((writeKey) => {
|
|
353
419
|
return converter.convert(from[key], context).onSuccess((value) => {
|
|
354
420
|
record[writeKey] = value;
|
|
355
|
-
return result_1.succeed(true);
|
|
421
|
+
return (0, result_1.succeed)(true);
|
|
356
422
|
});
|
|
357
423
|
}).onFailure((message) => {
|
|
358
424
|
errors.push(message);
|
|
359
|
-
return result_1.fail(message);
|
|
425
|
+
return (0, result_1.fail)(message);
|
|
360
426
|
});
|
|
361
427
|
}
|
|
362
428
|
}
|
|
363
429
|
return (errors.length === 0) || (options.onError === 'ignore')
|
|
364
|
-
? result_1.succeed(record)
|
|
365
|
-
: result_1.fail(errors.join('\n'));
|
|
430
|
+
? (0, result_1.succeed)(record)
|
|
431
|
+
: (0, result_1.fail)(errors.join('\n'));
|
|
366
432
|
});
|
|
367
433
|
}
|
|
368
434
|
exports.recordOf = recordOf;
|
|
435
|
+
/**
|
|
436
|
+
* Concrete implementation of {@link Converters.(mapOf:default) | Converters.mapOf(Converter<T>)},
|
|
437
|
+
* {@link Converters.(mapOf:withOnError) | Converters.mapOf(Converter<T>, 'fail'|'ignore')}, and
|
|
438
|
+
* {@link Converters.(mapOf:withOptions) | Converters.mapOf(Converter<T>, KeyedConverterOptions)}.
|
|
439
|
+
* @internal
|
|
440
|
+
*/
|
|
369
441
|
function mapOf(converter, option = 'fail') {
|
|
370
442
|
const options = (typeof option === 'string') ? { onError: option } : { onError: 'fail', ...option };
|
|
371
443
|
return new converter_1.BaseConverter((from, _self, context) => {
|
|
372
444
|
var _a, _b;
|
|
373
445
|
if ((typeof from !== 'object') || (from === null) || Array.isArray(from)) {
|
|
374
|
-
return result_1.fail(`Not a string-keyed object: ${JSON.stringify(from)}`);
|
|
446
|
+
return (0, result_1.fail)(`Not a string-keyed object: ${JSON.stringify(from)}`);
|
|
375
447
|
}
|
|
376
448
|
const map = new Map();
|
|
377
449
|
const errors = [];
|
|
378
450
|
for (const key in from) {
|
|
379
|
-
if (utils_1.isKeyOf(key, from)) {
|
|
380
|
-
const writeKeyResult = (_b = (_a = options.keyConverter) === null || _a === void 0 ? void 0 : _a.convert(key, context)) !== null && _b !== void 0 ? _b : result_1.succeed(key);
|
|
451
|
+
if ((0, utils_1.isKeyOf)(key, from)) {
|
|
452
|
+
const writeKeyResult = (_b = (_a = options.keyConverter) === null || _a === void 0 ? void 0 : _a.convert(key, context)) !== null && _b !== void 0 ? _b : (0, result_1.succeed)(key);
|
|
381
453
|
writeKeyResult.onSuccess((writeKey) => {
|
|
382
454
|
return converter.convert(from[key], context).onSuccess((value) => {
|
|
383
455
|
map.set(writeKey, value);
|
|
384
|
-
return result_1.succeed(true);
|
|
456
|
+
return (0, result_1.succeed)(true);
|
|
385
457
|
});
|
|
386
458
|
}).onFailure((message) => {
|
|
387
459
|
errors.push(message);
|
|
388
|
-
return result_1.fail(message);
|
|
460
|
+
return (0, result_1.fail)(message);
|
|
389
461
|
});
|
|
390
462
|
}
|
|
391
463
|
}
|
|
392
464
|
return (errors.length === 0) || (options.onError === 'ignore')
|
|
393
|
-
? result_1.succeed(map)
|
|
394
|
-
: result_1.fail(errors.join('\n'));
|
|
465
|
+
? (0, result_1.succeed)(map)
|
|
466
|
+
: (0, result_1.fail)(errors.join('\n'));
|
|
395
467
|
});
|
|
396
468
|
}
|
|
397
469
|
exports.mapOf = mapOf;
|
|
398
470
|
/**
|
|
399
|
-
*
|
|
400
|
-
* a supplied validator and returns it.
|
|
401
|
-
* @
|
|
402
|
-
*
|
|
403
|
-
*
|
|
404
|
-
*
|
|
471
|
+
* Helper function to create a {@link Converter} which validates that a supplied value is
|
|
472
|
+
* of a type validated by a supplied validator function and returns it.
|
|
473
|
+
* @remarks
|
|
474
|
+
* If `validator` succeeds, this {@link Converter} returns {@link Success} with the supplied
|
|
475
|
+
* value of `from` coerced to type `<T>`. Returns a {@link Failure} with additional
|
|
476
|
+
* information otherwise.
|
|
477
|
+
* @param validator - A validator function to determine if the converted value is valid.
|
|
478
|
+
* @param description - A description of the validated type for use in error messages.
|
|
479
|
+
* @returns A new {@link Converter | Converter<T>} which applies the supplied validation.
|
|
480
|
+
* @public
|
|
405
481
|
*/
|
|
406
482
|
function validateWith(validator, description) {
|
|
407
483
|
return new converter_1.BaseConverter((from, _self, _context) => {
|
|
408
484
|
if (validator(from)) {
|
|
409
|
-
return result_1.succeed(from);
|
|
485
|
+
return (0, result_1.succeed)(from);
|
|
410
486
|
}
|
|
411
|
-
return result_1.fail(`${JSON.stringify(from)}: invalid ${description !== null && description !== void 0 ? description : 'value'}`);
|
|
487
|
+
return (0, result_1.fail)(`${JSON.stringify(from)}: invalid ${description !== null && description !== void 0 ? description : 'value'}`);
|
|
412
488
|
});
|
|
413
489
|
}
|
|
414
490
|
exports.validateWith = validateWith;
|
|
415
491
|
/**
|
|
416
|
-
* A helper function to
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
-
* @param
|
|
492
|
+
* A helper function to create a {@link Converter} which extracts and converts an element from an array.
|
|
493
|
+
* @remarks
|
|
494
|
+
* The returned {@link Converter} returns {@link Success} with the converted value if the element exists
|
|
495
|
+
* in the supplied array and can be converted. Returns {@link Failure} with an error message otherwise.
|
|
496
|
+
* @param index - The index of the element to be extracted.
|
|
497
|
+
* @param converter - A {@link Converter} used to convert the extracted element.
|
|
498
|
+
* @returns A {@link Converter | Converter<T>} which extracts the specified element from an array.
|
|
499
|
+
* @public
|
|
421
500
|
*/
|
|
422
501
|
function element(index, converter) {
|
|
423
502
|
return new converter_1.BaseConverter((from, _self, context) => {
|
|
424
503
|
if (index < 0) {
|
|
425
|
-
return result_1.fail(`${index}: cannot convert for a negative element index`);
|
|
504
|
+
return (0, result_1.fail)(`${index}: cannot convert for a negative element index`);
|
|
426
505
|
}
|
|
427
506
|
else if (!Array.isArray(from)) {
|
|
428
|
-
return result_1.fail('element converter: source is not an array');
|
|
507
|
+
return (0, result_1.fail)('element converter: source is not an array');
|
|
429
508
|
}
|
|
430
509
|
else if (index >= from.length) {
|
|
431
|
-
return result_1.fail(`${index}: element converter index out of range (0..${from.length - 1})`);
|
|
510
|
+
return (0, result_1.fail)(`${index}: element converter index out of range (0..${from.length - 1})`);
|
|
432
511
|
}
|
|
433
512
|
return converter.convert(from[index], context);
|
|
434
513
|
});
|
|
435
514
|
}
|
|
436
515
|
exports.element = element;
|
|
437
516
|
/**
|
|
438
|
-
* A helper function to
|
|
439
|
-
*
|
|
440
|
-
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
*
|
|
444
|
-
* @param
|
|
517
|
+
* A helper function to create a {@link Converter} which extracts and converts an optional element from an array.
|
|
518
|
+
* @remarks
|
|
519
|
+
* The resulting {@link Converter} returns {@link Success} with the converted value if the element exsist
|
|
520
|
+
* in the supplied array and can be converted. Returns {@link Success} with value `undefined` if the parameter
|
|
521
|
+
* is an array but the index is out of range. Returns {@link Failure} with a message if the supplied parameter
|
|
522
|
+
* is not an array, if the requested index is negative, or if the element cannot be converted.
|
|
523
|
+
* @param index - The index of the element to be extracted.
|
|
524
|
+
* @param converter - A {@link Converter} used to convert the extracted element.
|
|
525
|
+
* @returns A {@link Converter | Converter<T>} which extracts the specified element from an array.
|
|
526
|
+
* @public
|
|
445
527
|
*/
|
|
446
528
|
function optionalElement(index, converter) {
|
|
447
529
|
return new converter_1.BaseConverter((from, _self, context) => {
|
|
448
530
|
if (index < 0) {
|
|
449
|
-
return result_1.fail(`${index}: cannot convert for a negative element index`);
|
|
531
|
+
return (0, result_1.fail)(`${index}: cannot convert for a negative element index`);
|
|
450
532
|
}
|
|
451
533
|
else if (!Array.isArray(from)) {
|
|
452
|
-
return result_1.fail('element converter: source is not an array');
|
|
534
|
+
return (0, result_1.fail)('element converter: source is not an array');
|
|
453
535
|
}
|
|
454
536
|
else if (index >= from.length) {
|
|
455
|
-
return result_1.succeed(undefined);
|
|
537
|
+
return (0, result_1.succeed)(undefined);
|
|
456
538
|
}
|
|
457
539
|
return converter.convert(from[index], context);
|
|
458
540
|
});
|
|
459
541
|
}
|
|
460
542
|
exports.optionalElement = optionalElement;
|
|
461
543
|
/**
|
|
462
|
-
* A helper function to
|
|
463
|
-
*
|
|
464
|
-
*
|
|
465
|
-
* @
|
|
466
|
-
*
|
|
544
|
+
* A helper function to create a {@link Converter} which extracts and convert a property specified
|
|
545
|
+
* by name from an object.
|
|
546
|
+
* @remarks
|
|
547
|
+
* The resulting {@link Converter} returns {@link Success} with the converted value of the correpsonding
|
|
548
|
+
* object property if the field exists and can be converted. Returns {@link Failure} with an error message
|
|
549
|
+
* otherwise.
|
|
550
|
+
* @param name - The name of the field to be extracted.
|
|
551
|
+
* @param converter - {@link Converter} used to convert the extracted field.
|
|
552
|
+
* @public
|
|
467
553
|
*/
|
|
468
554
|
function field(name, converter) {
|
|
469
555
|
return new converter_1.BaseConverter((from, _self, context) => {
|
|
470
556
|
if (typeof from === 'object' && (!Array.isArray(from)) && from !== null) {
|
|
471
|
-
if (utils_1.isKeyOf(name, from)) {
|
|
557
|
+
if ((0, utils_1.isKeyOf)(name, from)) {
|
|
472
558
|
return converter.convert(from[name], context).onFailure((message) => {
|
|
473
|
-
return result_1.fail(`Field ${name}: ${message}`);
|
|
559
|
+
return (0, result_1.fail)(`Field ${name}: ${message}`);
|
|
474
560
|
});
|
|
475
561
|
}
|
|
476
|
-
return result_1.fail(`Field ${name} not found in: ${JSON.stringify(from)}`);
|
|
562
|
+
return (0, result_1.fail)(`Field ${name} not found in: ${JSON.stringify(from)}`);
|
|
477
563
|
}
|
|
478
|
-
return result_1.fail(`Cannot convert field "${name}" from non-object ${JSON.stringify(from)}`);
|
|
564
|
+
return (0, result_1.fail)(`Cannot convert field "${name}" from non-object ${JSON.stringify(from)}`);
|
|
479
565
|
});
|
|
480
566
|
}
|
|
481
567
|
exports.field = field;
|
|
482
568
|
/**
|
|
483
|
-
* A helper function to
|
|
484
|
-
*
|
|
485
|
-
*
|
|
486
|
-
*
|
|
487
|
-
*
|
|
488
|
-
*
|
|
569
|
+
* A helper function to create a {@link Converter} which extracts and convert a property specified
|
|
570
|
+
* by name from an object.
|
|
571
|
+
* @remarks
|
|
572
|
+
* The resulting {@link Converter} returns {@link Success} with the converted value of the correpsonding
|
|
573
|
+
* object property if the field exists and can be converted. Returns {@link Success} with value `undefined`
|
|
574
|
+
* if the supplied parametr is an object but the named field is not present. Returns {@link Failure} with
|
|
575
|
+
* an error message otherwise.
|
|
576
|
+
* @param name - The name of the field to be extracted.
|
|
577
|
+
* @param converter - {@link Converter} used to convert the extracted field.
|
|
578
|
+
* @public
|
|
489
579
|
*/
|
|
490
580
|
function optionalField(name, converter) {
|
|
491
581
|
return new converter_1.BaseConverter((from, _self, context) => {
|
|
492
582
|
if (typeof from === 'object' && (!Array.isArray(from)) && from !== null) {
|
|
493
|
-
if (utils_1.isKeyOf(name, from)) {
|
|
583
|
+
if ((0, utils_1.isKeyOf)(name, from)) {
|
|
494
584
|
const result = converter.convert(from[name], context).onFailure((message) => {
|
|
495
|
-
return result_1.fail(`${name}: ${message}`);
|
|
585
|
+
return (0, result_1.fail)(`${name}: ${message}`);
|
|
496
586
|
});
|
|
497
587
|
// if conversion was successful or input was undefined we
|
|
498
588
|
// succeed with 'undefined', but we propagate actual
|
|
@@ -501,19 +591,28 @@ function optionalField(name, converter) {
|
|
|
501
591
|
return result;
|
|
502
592
|
}
|
|
503
593
|
}
|
|
504
|
-
return result_1.succeed(undefined);
|
|
594
|
+
return (0, result_1.succeed)(undefined);
|
|
505
595
|
}
|
|
506
|
-
return result_1.fail(`Cannot convert field "${name}" from non-object ${JSON.stringify(from)}`);
|
|
596
|
+
return (0, result_1.fail)(`Cannot convert field "${name}" from non-object ${JSON.stringify(from)}`);
|
|
507
597
|
}, undefined, { isOptional: true });
|
|
508
598
|
}
|
|
509
599
|
exports.optionalField = optionalField;
|
|
510
600
|
/**
|
|
511
|
-
* Converter
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
* the
|
|
601
|
+
* A {@link Converter} which converts an object of type `<T>` without changing shape, given
|
|
602
|
+
* a {@link Converters.FieldConverters | FieldConverters<T>} for the fields in the object.
|
|
603
|
+
* @remarks
|
|
604
|
+
* By default, if all of the required fields exist and can be converted, returns a new object with
|
|
605
|
+
* the converted values under the original key names. If any required fields do not exist or cannot
|
|
606
|
+
* be converted, the entire conversion fails. See {@link Converters.ObjectConverterOptions | ObjectConverterOptions}
|
|
607
|
+
* for other conversion options.
|
|
608
|
+
* @public
|
|
515
609
|
*/
|
|
516
610
|
class ObjectConverter extends converter_1.BaseConverter {
|
|
611
|
+
/**
|
|
612
|
+
* Concrete implementation of {@link Converters.ObjectConverter.(constructor:withOptions)}
|
|
613
|
+
* and {@link Converters.ObjectConverter.(constructor:withKeys)}.
|
|
614
|
+
* @internal
|
|
615
|
+
*/
|
|
517
616
|
constructor(fields, opt) {
|
|
518
617
|
super((from, _self, context) => {
|
|
519
618
|
var _a, _b;
|
|
@@ -538,7 +637,7 @@ class ObjectConverter extends converter_1.BaseConverter {
|
|
|
538
637
|
if (this.options.strict === true) {
|
|
539
638
|
if ((typeof from === 'object') && (!Array.isArray(from))) {
|
|
540
639
|
for (const key in from) {
|
|
541
|
-
if (from.hasOwnProperty(key) && (!utils_1.isKeyOf(key, fields) || (fields[key] === undefined))) {
|
|
640
|
+
if (from.hasOwnProperty(key) && (!(0, utils_1.isKeyOf)(key, fields) || (fields[key] === undefined))) {
|
|
542
641
|
errors.push(`${key}: unexpected property in source object`);
|
|
543
642
|
}
|
|
544
643
|
}
|
|
@@ -547,7 +646,7 @@ class ObjectConverter extends converter_1.BaseConverter {
|
|
|
547
646
|
errors.push('source is not an object');
|
|
548
647
|
}
|
|
549
648
|
}
|
|
550
|
-
return (errors.length === 0) ? result_1.succeed(converted) : result_1.fail(errors.join('\n'));
|
|
649
|
+
return (errors.length === 0) ? (0, result_1.succeed)(converted) : (0, result_1.fail)(errors.join('\n'));
|
|
551
650
|
});
|
|
552
651
|
this.fields = fields;
|
|
553
652
|
if (Array.isArray(opt)) {
|
|
@@ -557,106 +656,110 @@ class ObjectConverter extends converter_1.BaseConverter {
|
|
|
557
656
|
this.options = opt !== null && opt !== void 0 ? opt : {};
|
|
558
657
|
}
|
|
559
658
|
}
|
|
659
|
+
/**
|
|
660
|
+
* Concrete implementation of
|
|
661
|
+
* {@link Converters.ObjectConverter.(partial:withOptions) | ObjectConverter.partial(ObjectConverterOptions)} and
|
|
662
|
+
* {@link Converters.ObjectConverter.(partial:withKeys) | ObjectConverter.partial((keyof T)[]}.
|
|
663
|
+
* @internal
|
|
664
|
+
*/
|
|
560
665
|
partial(opt) {
|
|
561
666
|
return new ObjectConverter(this.fields, opt)._with(this._traits());
|
|
562
667
|
}
|
|
563
|
-
|
|
668
|
+
/**
|
|
669
|
+
* Creates a new {@link Converters.ObjectConverter | ObjectConverter} derived from this one but with
|
|
670
|
+
* new optional properties as specified by a supplied array of `keyof T`.
|
|
671
|
+
* @param addOptionalProperties - The keys to be made optional.
|
|
672
|
+
* @returns A new {@link Converters.ObjectConverter | ObjectConverter} with the additional optional source
|
|
673
|
+
* properties.
|
|
674
|
+
*/
|
|
675
|
+
addPartial(addOptionalProperties) {
|
|
564
676
|
var _a;
|
|
565
|
-
return this.partial([...(_a = this.options.optionalFields) !== null && _a !== void 0 ? _a : [], ...
|
|
677
|
+
return this.partial([...(_a = this.options.optionalFields) !== null && _a !== void 0 ? _a : [], ...addOptionalProperties])._with(this._traits());
|
|
566
678
|
}
|
|
567
679
|
}
|
|
568
680
|
exports.ObjectConverter = ObjectConverter;
|
|
569
681
|
/**
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
*
|
|
573
|
-
* new object with the converted values under the original key names. If any fields do not exist
|
|
574
|
-
* or cannot be converted, the entire conversion fails.
|
|
575
|
-
*
|
|
576
|
-
* Fields that succeed but convert to undefined are omitted from the result object but do not
|
|
577
|
-
* fail the conversion.
|
|
578
|
-
* @param fields An object containing defining the shape and converters to be applied.
|
|
579
|
-
* @param opt An @see ObjectConverterOptions<T> containing options for the object converter, or
|
|
580
|
-
* an array of (keyof T) containing optional keys.
|
|
682
|
+
* Concrete implementation of {@link Converters.(object:withOptions) | Converters.object(fields, options)}
|
|
683
|
+
* and {@link Converters.(object:withKeys) | Converters.objects(fields, optionalKeys)}.
|
|
684
|
+
* @internal
|
|
581
685
|
*/
|
|
582
|
-
function object(
|
|
583
|
-
return new ObjectConverter(
|
|
686
|
+
function object(properties, options) {
|
|
687
|
+
return new ObjectConverter(properties, options);
|
|
584
688
|
}
|
|
585
689
|
exports.object = object;
|
|
586
690
|
/**
|
|
587
|
-
*
|
|
588
|
-
*
|
|
589
|
-
*
|
|
590
|
-
* new object with the converted values under the original key names. If any fields do not exist
|
|
591
|
-
* or cannot be converted, the entire conversion fails.
|
|
592
|
-
*
|
|
593
|
-
* Fields that succeed but convert to undefined are omitted from the result object but do not
|
|
594
|
-
* fail the conversion.
|
|
595
|
-
*
|
|
596
|
-
* The conversion fails if any unexpected fields are encountered.
|
|
597
|
-
*
|
|
598
|
-
* @param fields An object containing defining the shape and converters to be applied.
|
|
599
|
-
* @param opt - An @see ObjectConverterOptions<T> containing options for the object converter, or
|
|
600
|
-
* an array of (keyof T) containing optional keys.
|
|
691
|
+
* Concrete implementation for {@link Converters.(strictObject:withOptions) | Converters.strictObject(fields, options)}
|
|
692
|
+
* and {@link Converters.(strictObject:withKeys) | Converters.strictObject(fields, optional)}.
|
|
693
|
+
* @internal
|
|
601
694
|
*/
|
|
602
|
-
function strictObject(
|
|
695
|
+
function strictObject(properties, opt) {
|
|
603
696
|
const options = (opt && Array.isArray(opt))
|
|
604
697
|
? { strict: true, optionalFields: opt }
|
|
605
698
|
: { ...(opt !== null && opt !== void 0 ? opt : {}), strict: true };
|
|
606
|
-
return new ObjectConverter(
|
|
699
|
+
return new ObjectConverter(properties, options);
|
|
607
700
|
}
|
|
608
701
|
exports.strictObject = strictObject;
|
|
609
702
|
/**
|
|
610
|
-
* Helper to
|
|
611
|
-
*
|
|
612
|
-
*
|
|
613
|
-
*
|
|
614
|
-
*
|
|
615
|
-
*
|
|
616
|
-
*
|
|
617
|
-
* discriminator property
|
|
703
|
+
* Helper to create a {@link Converter} whhich converts a discriminated object without changing shape.
|
|
704
|
+
* @remarks
|
|
705
|
+
* Takes the name of the discriminator property and a
|
|
706
|
+
* {@link Converters.DiscriminatedObjectConverters | string-keyed Record of converters}. During conversion,
|
|
707
|
+
* the resulting {@link Converter} invokes the converter from `converters` that corresponds to the value of
|
|
708
|
+
* the discriminator property in the source object.
|
|
709
|
+
*
|
|
710
|
+
* If the source is not an object, the discriminator property is missing, or the discriminator has
|
|
711
|
+
* a value not present in the converters, conversion fails and returns {@link Failure} with more information.
|
|
712
|
+
* @param discriminatorProp - Name of the property used to discriminate types.
|
|
713
|
+
* @param converters - {@link Converters.DiscriminatedObjectConverters | String-keyed record of converters} to
|
|
714
|
+
* invoke, where each key corresponds to a value of the discriminator property.
|
|
715
|
+
* @returns A {@link Converter} which converts the corresponding discriminated object.
|
|
716
|
+
* @public
|
|
618
717
|
*/
|
|
619
718
|
function discriminatedObject(discriminatorProp, converters) {
|
|
620
719
|
return new converter_1.BaseConverter((from) => {
|
|
621
720
|
if ((typeof from !== 'object') || Array.isArray(from) || from === null) {
|
|
622
|
-
return result_1.fail(`Not a discriminated object: "${JSON.stringify(from)}"`);
|
|
721
|
+
return (0, result_1.fail)(`Not a discriminated object: "${JSON.stringify(from)}"`);
|
|
623
722
|
}
|
|
624
|
-
if ((!utils_1.isKeyOf(discriminatorProp, from)) || (!from[discriminatorProp])) {
|
|
625
|
-
return result_1.fail(`Discriminator property ${discriminatorProp} not present in "${JSON.stringify(from)}"`);
|
|
723
|
+
if ((!(0, utils_1.isKeyOf)(discriminatorProp, from)) || (!from[discriminatorProp])) {
|
|
724
|
+
return (0, result_1.fail)(`Discriminator property ${discriminatorProp} not present in "${JSON.stringify(from)}"`);
|
|
626
725
|
}
|
|
627
726
|
const discriminatorValue = from[discriminatorProp];
|
|
628
727
|
const converter = converters[discriminatorValue];
|
|
629
728
|
if (converter === undefined) {
|
|
630
|
-
return result_1.fail(`No converter for discriminator ${discriminatorProp}="${discriminatorValue}"`);
|
|
729
|
+
return (0, result_1.fail)(`No converter for discriminator ${discriminatorProp}="${discriminatorValue}"`);
|
|
631
730
|
}
|
|
632
731
|
return converter.convert(from);
|
|
633
732
|
});
|
|
634
733
|
}
|
|
635
734
|
exports.discriminatedObject = discriminatedObject;
|
|
636
735
|
/**
|
|
637
|
-
* Helper to
|
|
638
|
-
*
|
|
639
|
-
* converter that will extract and convert a single field from the source object.
|
|
736
|
+
* Helper to create a {@link Converter} which converts a source object to a new object with a
|
|
737
|
+
* different shape.
|
|
640
738
|
*
|
|
641
|
-
*
|
|
642
|
-
*
|
|
643
|
-
*
|
|
739
|
+
* @remarks
|
|
740
|
+
* On successful conversion, the resulting {@link Converter} returns {@link Success} with a new
|
|
741
|
+
* object, which contains the converted values under the key names specified at initialization time.
|
|
742
|
+
* It returns {@link Failure} with an error message if any fields to be extracted do not exist
|
|
743
|
+
* or cannot be converted.
|
|
644
744
|
*
|
|
645
745
|
* Fields that succeed but convert to undefined are omitted from the result object but do not
|
|
646
746
|
* fail the conversion.
|
|
647
747
|
*
|
|
648
|
-
* @param
|
|
649
|
-
*
|
|
748
|
+
* @param properties - An object with key names that correspond to the target object and an
|
|
749
|
+
* appropriate {@link Converters.FieldConverters | FieldConverter} which extracts and converts
|
|
750
|
+
* a single filed from the source object.
|
|
751
|
+
* @returns A {@link Converter} with the specified conversion behavior.
|
|
752
|
+
* @public
|
|
650
753
|
*/
|
|
651
|
-
function transform(
|
|
754
|
+
function transform(properties) {
|
|
652
755
|
return new converter_1.BaseConverter((from, _self, context) => {
|
|
653
756
|
// eslint bug thinks key is used before defined
|
|
654
757
|
// eslint-disable-next-line no-use-before-define
|
|
655
758
|
const converted = {};
|
|
656
759
|
const errors = [];
|
|
657
|
-
for (const key in
|
|
658
|
-
if (
|
|
659
|
-
const result =
|
|
760
|
+
for (const key in properties) {
|
|
761
|
+
if (properties[key]) {
|
|
762
|
+
const result = properties[key].convert(from, context);
|
|
660
763
|
if (result.isSuccess() && (result.value !== undefined)) {
|
|
661
764
|
converted[key] = result.value;
|
|
662
765
|
}
|
|
@@ -665,30 +768,38 @@ function transform(fields) {
|
|
|
665
768
|
}
|
|
666
769
|
}
|
|
667
770
|
}
|
|
668
|
-
return (errors.length === 0) ? result_1.succeed(converted) : result_1.fail(errors.join('\n'));
|
|
771
|
+
return (errors.length === 0) ? (0, result_1.succeed)(converted) : (0, result_1.fail)(errors.join('\n'));
|
|
669
772
|
});
|
|
670
773
|
}
|
|
671
774
|
exports.transform = transform;
|
|
672
775
|
/**
|
|
673
|
-
* A helper wrapper to
|
|
674
|
-
*
|
|
675
|
-
* @param
|
|
776
|
+
* A helper wrapper to construct a {@link Converter} which converts to an arbitrary strongly-typed
|
|
777
|
+
* range of some comparable type.
|
|
778
|
+
* @param converter - {@link Converter} used to convert `min` and `max` extent of the range.
|
|
779
|
+
* @param constructor - Static constructor to instantiate the object.
|
|
780
|
+
* @public
|
|
676
781
|
*/
|
|
677
782
|
function rangeTypeOf(converter, constructor) {
|
|
678
783
|
return new converter_1.BaseConverter((from, _self, context) => {
|
|
679
784
|
const result = object({
|
|
680
785
|
min: converter,
|
|
681
786
|
max: converter,
|
|
682
|
-
}, ['min', 'max']).convert(from, context);
|
|
787
|
+
}, { optionalFields: ['min', 'max'] }).convert(from, context);
|
|
683
788
|
if (result.isSuccess()) {
|
|
684
789
|
return constructor({ min: result.value.min, max: result.value.max });
|
|
685
790
|
}
|
|
686
|
-
return result_1.fail(result.message);
|
|
791
|
+
return (0, result_1.fail)(result.message);
|
|
687
792
|
});
|
|
688
793
|
}
|
|
689
794
|
exports.rangeTypeOf = rangeTypeOf;
|
|
795
|
+
/**
|
|
796
|
+
* A helper wrapper to construct a {@link Converter} which converts to {@link RangeOf | RangeOf<T>}
|
|
797
|
+
* where `<T>` is some comparable type.
|
|
798
|
+
* @param converter - {@link Converter} used to convert `min` and `max` extent of the range.
|
|
799
|
+
* @public
|
|
800
|
+
*/
|
|
690
801
|
function rangeOf(converter) {
|
|
691
802
|
return rangeTypeOf(converter, rangeOf_1.RangeOf.createRange);
|
|
692
803
|
}
|
|
693
804
|
exports.rangeOf = rangeOf;
|
|
694
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVydGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb252ZXJ0ZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUNILDJDQUF3RTtBQUN4RSx1Q0FBdUQ7QUFDdkQscUNBQWdFO0FBRWhFLGlDQUFpQztBQUNqQyxtREFBZ0Q7QUFDaEQsd0RBQWdDO0FBQ2hDLG1DQUFrQztBQWVsQzs7O0dBR0c7QUFDSCxNQUFhLGVBQXlELFNBQVEseUJBQW9CO0lBQzlGOzs7OztPQUtHO0lBQ0gsWUFDSSxjQUFtQixFQUNuQixNQUF3QixFQUN4QixZQUFnRixlQUFlLENBQUMsUUFBUTtRQUV4RyxLQUFLLENBQUMsU0FBUyxFQUFFLGNBQWMsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRVMsTUFBTSxDQUFDLFFBQVEsQ0FBbUIsSUFBYTtRQUNyRCxPQUFPLE9BQU8sSUFBSSxLQUFLLFFBQVE7WUFDM0IsQ0FBQyxDQUFDLGdCQUFPLENBQUMsSUFBUyxDQUFDO1lBQ3BCLENBQUMsQ0FBQyxhQUFJLENBQUMsaUJBQWlCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFUyxNQUFNLENBQUMsS0FBSyxDQUNsQixPQUErQixFQUMvQixTQUFpQyxFQUNqQyxNQUF3QjtRQUV4QixPQUFPLElBQUksZUFBZSxDQUFRLFNBQVMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxJQUFhLEVBQUUsRUFBRTtZQUN0RSxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3RELENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQXlDTSxRQUFRLENBQUMsS0FBMEMsRUFBRSxP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Z0IsV0FBVyxDQUF1QyxTQUEyQixFQUFFLFdBQXVEO0lBQ2xKLE9BQU8sSUFBSSx5QkFBYSxDQUFDLENBQUMsSUFBYSxFQUFFLEtBQUssRUFBRSxPQUFZLEVBQUUsRUFBRTtRQUM1RCxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUM7WUFDbEIsR0FBRyxFQUFFLFNBQVM7WUFDZCxHQUFHLEVBQUUsU0FBUztTQUNqQixFQUFFLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMxQyxJQUFJLE1BQU0sQ0FBQyxTQUFTLEVBQUUsRUFBRTtZQUNwQixPQUFPLFdBQVcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1NBQ3hFO1FBQ0QsT0FBTyxhQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2hDLENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQztBQVhELGtDQVdDO0FBRUQsU0FBZ0IsT0FBTyxDQUFnQixTQUEyQjtJQUM5RCxPQUFPLFdBQVcsQ0FBb0IsU0FBUyxFQUFFLGlCQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUUsQ0FBQztBQUZELDBCQUVDIiwic291cmNlc0NvbnRlbnQiOlsiXG4vKlxuICogQ29weXJpZ2h0IChjKSAyMDIwIEVyaWsgRm9ydHVuZVxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbiAqIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbiAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGxcbiAqIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4gKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRVxuICogU09GVFdBUkUuXG4gKi9cbmltcG9ydCB7IEJhc2VDb252ZXJ0ZXIsIENvbnZlcnRlciwgQ29udmVydGVyVHJhaXRzIH0gZnJvbSAnLi9jb252ZXJ0ZXInO1xuaW1wb3J0IHsgUmFuZ2VPZiwgUmFuZ2VPZlByb3BlcnRpZXMgfSBmcm9tICcuL3JhbmdlT2YnO1xuaW1wb3J0IHsgUmVzdWx0LCBjYXB0dXJlUmVzdWx0LCBmYWlsLCBzdWNjZWVkIH0gZnJvbSAnLi9yZXN1bHQnO1xuXG5pbXBvcnQgeyBEYXRlVGltZSB9IGZyb20gJ2x1eG9uJztcbmltcG9ydCB7IEV4dGVuZGVkQXJyYXkgfSBmcm9tICcuL2V4dGVuZGVkQXJyYXknO1xuaW1wb3J0IE11c3RhY2hlIGZyb20gJ211c3RhY2hlJztcbmltcG9ydCB7IGlzS2V5T2YgfSBmcm9tICcuL3V0aWxzJztcblxudHlwZSBPbkVycm9yID0gJ2ZhaWxPbkVycm9yJyB8ICdpZ25vcmVFcnJvcnMnO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIEBzZWUgU3RyaW5nQ29udmVydGVyIG1hY2hpbmcgbWV0aG9kXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RyaW5nTWF0Y2hPcHRpb25zIHtcbiAgICAvKipcbiAgICAgKiBBbiBvcHRpb25hbCBtZXNzYWdlIHRvIGJlIGRpc3BsYXllZCBpZiBhIG5vbi1tYXRjaGluZyBzdHJpbmdcbiAgICAgKiBpcyBlbmNvdW50ZXJlZC5cbiAgICAgKi9cbiAgICBtZXNzYWdlPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFRoZSBAc2VlIFN0cmluZ0NvbnZlcnRlciBjbGFzcyBleHRlbmRzIEBzZWUgQmFzZUNvbnZlcnRlciB0byBwcm92aWRlIHN0cmluZy1zcGVjaWZpYyBoZWxwZXJcbiAqIGZ1bmN0aW9ucy5cbiAqL1xuZXhwb3J0IGNsYXNzIFN0cmluZ0NvbnZlcnRlcjxUIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nLCBUQyA9IHVua25vd24+IGV4dGVuZHMgQmFzZUNvbnZlcnRlcjxULCBUQz4ge1xuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdCBhIG5ldyBAc2VlIFN0cmluZ0NvbnZlcnRlclxuICAgICAqIEBwYXJhbSBkZWZhdWx0Q29udGV4dCBPcHRpb25hbCBjb250ZXh0IHVzZWQgYnkgdGhlIGNvbnZlcnNpb25cbiAgICAgKiBAcGFyYW0gdHJhaXRzIE9wdGlvbmFsIHRyYWl0cyB0byBiZSBhcHBsaWVkIHRvIHRoZSBjb252ZXJzaW9uXG4gICAgICogQHBhcmFtIGNvbnZlcnRlciBPcHRpb25hbCBjb252ZXJ0ZXIgdG8gYmUgdXNlZCBmb3IgdGhlIGNvbnZlcnNpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgICAgIGRlZmF1bHRDb250ZXh0PzogVEMsXG4gICAgICAgIHRyYWl0cz86IENvbnZlcnRlclRyYWl0cyxcbiAgICAgICAgY29udmVydGVyOiAoZnJvbTogdW5rbm93biwgc2VsZjogQ29udmVydGVyPFQsIFRDPiwgY29udGV4dD86IFRDKSA9PiBSZXN1bHQ8VD4gPSBTdHJpbmdDb252ZXJ0ZXIuX2NvbnZlcnQsXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKGNvbnZlcnRlciwgZGVmYXVsdENvbnRleHQsIHRyYWl0cyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHN0YXRpYyBfY29udmVydDxUIGV4dGVuZHMgc3RyaW5nPihmcm9tOiB1bmtub3duKTogUmVzdWx0PFQ+IHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBmcm9tID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgPyBzdWNjZWVkKGZyb20gYXMgVClcbiAgICAgICAgICAgIDogZmFpbChgTm90IGEgc3RyaW5nOiAke0pTT04uc3RyaW5naWZ5KGZyb20pfWApO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBzdGF0aWMgX3dyYXA8VCBleHRlbmRzIHN0cmluZywgVEM+KFxuICAgICAgICB3cmFwcGVkOiBTdHJpbmdDb252ZXJ0ZXI8VCwgVEM+LFxuICAgICAgICBjb252ZXJ0ZXI6IChmcm9tOiBUKSA9PiBSZXN1bHQ8VD4sXG4gICAgICAgIHRyYWl0cz86IENvbnZlcnRlclRyYWl0c1xuICAgICk6IFN0cmluZ0NvbnZlcnRlcjxULCBUQz4ge1xuICAgICAgICByZXR1cm4gbmV3IFN0cmluZ0NvbnZlcnRlcjxULCBUQz4odW5kZWZpbmVkLCB1bmRlZmluZWQsIChmcm9tOiB1bmtub3duKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gd3JhcHBlZC5jb252ZXJ0KGZyb20pLm9uU3VjY2Vzcyhjb252ZXJ0ZXIpO1xuICAgICAgICB9KS5fd2l0aCh3cmFwcGVkLl90cmFpdHModHJhaXRzKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIEBzZWUgU3RyaW5nQ29udmVydGVyIHdoaWNoIGNvbnN0cmFpbnMgdGhlIHJlc3VsdCB0byBtYXRjaCBhIHN1cHBsaWVkXG4gICAgICogc3RyaW5nLlxuICAgICAqIEBwYXJhbSBtYXRjaCBUaGUgc3RyaW5nIHRvIGJlIG1hdGNoZWRcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25hbCBAc2VlIFN0cmluZ01hdGNoT3B0aW9ucyBmb3IgdGhpcyBjb252ZXJzaW9uXG4gICAgICogQHJldHVybnMgQHNlZSBTdWNjZXNzIHdpdGggYSBtYXRjaGluZyBzdHJpbmcgb3IgQHNlZSBGYWlsdXJlIHdpdGggYW4gaW5mb3JtYXRpdmVcbiAgICAgKiBlcnJvciBpZiB0aGUgc3RyaW5nIGRvZXMgbm90IG1hdGNoLlxuICAgICAqL1xuICAgIHB1YmxpYyBtYXRjaGluZyhtYXRjaDogc3RyaW5nLCBvcHRpb25zPzogUGFydGlhbDxTdHJpbmdNYXRjaE9wdGlvbnM+KTogU3RyaW5nQ29udmVydGVyPFQsIFRDPjtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBAc2VlIFN0cmluZ0NvbnZlcnRlciB3aGljaCBjb25zdHJhaW5zIHRoZSByZXN1bHQgdG8gbWF0Y2ggb25lIG9mIGEgc3VwcGxpZWRcbiAgICAgKiBhcnJheSBvZiBzdHJpbmdzLlxuICAgICAqIEBwYXJhbSBtYXRjaCBUaGUgYXJyYXkgdG8gYmUgc2VhcmNoZWRcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25hbCBAc2VlIFN0cmluZ01hdGNoT3B0aW9ucyBmb3IgdGhpcyBjb252ZXJzaW9uXG4gICAgICogQHJldHVybnMgQHNlZSBTdWNjZXNzIHdpdGggYSBtYXRjaGluZyBzdHJpbmcgb3IgQHNlZSBGYWlsdXJlIHdpdGggYW4gaW5mb3JtYXRpdmVcbiAgICAgKiBlcnJvciBpZiB0aGUgc3RyaW5nIGRvZXMgbm90IG1hdGNoLlxuICAgICAqL1xuICAgIHB1YmxpYyBtYXRjaGluZyhtYXRjaDogc3RyaW5nW10sIG9wdGlvbnM/OiBQYXJ0aWFsPFN0cmluZ01hdGNoT3B0aW9ucz4pOiBTdHJpbmdDb252ZXJ0ZXI8VCwgVEM+O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIEBzZWUgU3RyaW5nQ29udmVydGVyIHdoaWNoIGNvbnN0cmFpbnMgdGhlIHJlc3VsdCB0byBtYXRjaCBvbmUgb2YgYSBzdXBwbGllZFxuICAgICAqIFNldCBvZiBzdHJpbmdzLlxuICAgICAqIEBwYXJhbSBtYXRjaCBUaGUgU2V0IHRvIGJlIHRlc3RlZFxuICAgICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbmFsIEBzZWUgU3RyaW5nTWF0Y2hPcHRpb25zIGZvciB0aGlzIGNvbnZlcnNpb25cbiAgICAgKiBAcmV0dXJucyBAc2VlIFN1Y2Nlc3Mgd2l0aCBhIG1hdGNoaW5nIHN0cmluZyBvciBAc2VlIEZhaWx1cmUgd2l0aCBhbiBpbmZvcm1hdGl2ZVxuICAgICAqIGVycm9yIGlmIHRoZSBzdHJpbmcgZG9lcyBub3QgbWF0Y2guXG4gICAgICovXG4gICAgcHVibGljIG1hdGNoaW5nKG1hdGNoOiBTZXQ8VD4sIG9wdGlvbnM/OiBQYXJ0aWFsPFN0cmluZ01hdGNoT3B0aW9ucz4pOiBTdHJpbmdDb252ZXJ0ZXI8VCwgVEM+O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIEBzZWUgU3RyaW5nQ29udmVydGVyIHdoaWNoIGNvbnN0cmFpbnMgdGhlIHJlc3VsdCB0byBtYXRjaCBhIHN1cHBsaWVkIHJlZ3VsYXJcbiAgICAgKiBleHByZXNzaW9uLlxuICAgICAqIEBwYXJhbSBtYXRjaCBUaGUgQHNlZSBSZWdFeHAgdG8gYmUgdGVzdGVkXG4gICAgICogQHBhcmFtIG9wdGlvbnMgT3B0aW9uYWwgQHNlZSBTdHJpbmdNYXRjaE9wdGlvbnMgZm9yIHRoaXMgY29udmVyc2lvblxuICAgICAqIEByZXR1cm5zIEBzZWUgU3VjY2VzcyB3aXRoIGEgbWF0Y2hpbmcgc3RyaW5nIG9yIEBzZWUgRmFpbHVyZSB3aXRoIGFuIGluZm9ybWF0aXZlXG4gICAgICogZXJyb3IgaWYgdGhlIHN0cmluZyBkb2VzIG5vdCBtYXRjaC5cbiAgICAgKi9cbiAgICBwdWJsaWMgbWF0Y2hpbmcobWF0Y2g6IFJlZ0V4cCwgb3B0aW9ucz86IFBhcnRpYWw8U3RyaW5nTWF0Y2hPcHRpb25zPik6IFN0cmluZ0NvbnZlcnRlcjxULCBUQz47XG4gICAgcHVibGljIG1hdGNoaW5nKG1hdGNoOiBzdHJpbmcgfCBzdHJpbmdbXSB8IFNldDxUPiB8IFJlZ0V4cCwgb3B0aW9ucz86IFBhcnRpYWw8U3RyaW5nTWF0Y2hPcHRpb25zPik6IFN0cmluZ0NvbnZlcnRlcjxULCBUQz4ge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gb3B0aW9ucz8ubWVzc2FnZTtcbiAgICAgICAgaWYgKHR5cGVvZiBtYXRjaCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBTdHJpbmdDb252ZXJ0ZXIuX3dyYXA8VCwgVEM+KHRoaXMsIChmcm9tOiBUKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChtYXRjaCA9PT0gZnJvbSlcbiAgICAgICAgICAgICAgICAgICAgPyBzdWNjZWVkKGZyb20gYXMgVClcbiAgICAgICAgICAgICAgICAgICAgOiBmYWlsKG1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgID8gYFwiJHtmcm9tfVwiOiAke21lc3NhZ2V9YFxuICAgICAgICAgICAgICAgICAgICAgICAgOiBgXCIke2Zyb219XCI6IGRvZXMgbm90IG1hdGNoIFwiJHttYXRjaH1cImApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobWF0Y2ggaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJldHVybiBTdHJpbmdDb252ZXJ0ZXIuX3dyYXA8VCwgVEM+KHRoaXMsIChmcm9tOiBUKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChtYXRjaC50ZXN0KGZyb20pKVxuICAgICAgICAgICAgICAgICAgICA/IHN1Y2NlZWQoZnJvbSBhcyBUKVxuICAgICAgICAgICAgICAgICAgICA6IGZhaWwobWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBgXCIke2Zyb219XCI6ICR7bWVzc2FnZX1gXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGBcIiR7ZnJvbX1cIjogZG9lcyBub3QgbWF0Y2ggXCIke21hdGNofVwiYCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChtYXRjaCBpbnN0YW5jZW9mIFNldCkge1xuICAgICAgICAgICAgcmV0dXJuIFN0cmluZ0NvbnZlcnRlci5fd3JhcDxULCBUQz4odGhpcywgKGZyb206IFQpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gKG1hdGNoLmhhcyhmcm9tKSlcbiAgICAgICAgICAgICAgICAgICAgPyBzdWNjZWVkKGZyb20gYXMgVClcbiAgICAgICAgICAgICAgICAgICAgOiBmYWlsKG1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgID8gYFwiJHtmcm9tfVwiOiAke21lc3NhZ2V9YFxuICAgICAgICAgICAgICAgICAgICAgICAgOiBgXCIke2Zyb219XCI6IG5vdCBmb3VuZCBpbiBzZXRgKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFN0cmluZ0NvbnZlcnRlci5fd3JhcDxULCBUQz4odGhpcywgKGZyb206IFQpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gKG1hdGNoLmluY2x1ZGVzKGZyb20pKVxuICAgICAgICAgICAgICAgICAgICA/IHN1Y2NlZWQoZnJvbSBhcyBUKVxuICAgICAgICAgICAgICAgICAgICA6IGZhaWwobWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBgXCIke2Zyb219XCI6ICR7bWVzc2FnZX1gXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGBcIiR7ZnJvbX1cIjogbm90IGZvdW5kIGluIFske21hdGNoLmpvaW4oJywnKX1dYCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBBIGNvbnZlcnRlciB0byBjb252ZXJ0IHVua25vd24gdG8gc3RyaW5nLiBWYWx1ZXMgb2YgdHlwZVxuICogc3RyaW5nIHN1Y2NlZWQuICBBbnl0aGluZyBlbHNlIGZhaWxzLlxuICovXG5leHBvcnQgY29uc3Qgc3RyaW5nID0gbmV3IFN0cmluZ0NvbnZlcnRlcigpO1xuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYSBjb252ZXJ0ZXIgd2hpY2ggY29udmVydHMgdW5rbm93biB0byBzdHJpbmcsIGFwcGx5aW5nXG4gKiB0ZW1wbGF0ZSBjb252ZXJzaW9ucyBzdXBwbGllZCBhdCBjb25zdHJ1Y3Rpb24gdGltZSBvciBhdCBydW50aW1lIGFzIGNvbnRleHQuXG4gKiBAcGFyYW0gZGVmYXVsdENvbnRleHQgb3B0aW9uYWwgZGVmYXVsdCBjb250ZXh0IHRvIHVzZSBmb3IgdGVtcGxhdGUgdmFsdWVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0ZW1wbGF0ZVN0cmluZyhkZWZhdWx0Q29udGV4dD86IHVua25vd24pOiBTdHJpbmdDb252ZXJ0ZXI8c3RyaW5nLCB1bmtub3duPiB7XG4gICAgcmV0dXJuIG5ldyBTdHJpbmdDb252ZXJ0ZXI8c3RyaW5nLCB1bmtub3duPihkZWZhdWx0Q29udGV4dCwgdW5kZWZpbmVkLCAoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxzdHJpbmcsIHVua25vd24+LCBjb250ZXh0PzogdW5rbm93bikgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIGZyb20gIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFpbChgTm90IGEgc3RyaW5nOiAke0pTT04uc3RyaW5naWZ5KGZyb20pfWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYXB0dXJlUmVzdWx0KCgpID0+IE11c3RhY2hlLnJlbmRlcihmcm9tLCBjb250ZXh0KSk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBjb252ZXJ0ZXIgdG8gY29udmVydCB1bmtub3duIHRvIG9uZSBvZiBhIHNldCBvZiBzdXBwbGllZCBlbnVtZXJhdGVkIHZhbHVlcy4gQW55dGhpbmcgZWxzZSBmYWlscy5cbiAqIEFsbG93ZWQgZW51bWVyYXRlZCB2YWx1ZXMgY2FuIGFsc28gYmUgc3VwcGxpZWQgYXMgY29udGV4dCBhdCBjb252ZXJzaW9uIHRpbWUuXG4gKiBAcGFyYW0gdmFsdWVzIEFycmF5IG9mIGFsbG93ZWQgdmFsdWVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbnVtZXJhdGVkVmFsdWU8VD4odmFsdWVzOiBUW10pOiBDb252ZXJ0ZXI8VCwgVFtdPiB7XG4gICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyKChmcm9tOiB1bmtub3duLCBfc2VsZjogQ29udmVydGVyPFQsIFRbXT4sIGNvbnRleHQ/OiBUW10pOiBSZXN1bHQ8VD4gPT4ge1xuICAgICAgICBjb25zdCB2ID0gY29udGV4dCA/PyB2YWx1ZXM7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdi5pbmRleE9mKGZyb20gYXMgVCk7XG4gICAgICAgIHJldHVybiAoaW5kZXggPj0gMCA/IHN1Y2NlZWQodltpbmRleF0pIDogZmFpbChgSW52YWxpZCBlbnVtZXJhdGVkIHZhbHVlICR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9YCkpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHVua25vd24gdG8gb25lIG9mIGEgc2V0IG9mIHN1cHBsaWVkIGVudW1lcmF0ZWQgdmFsdWVzLCBtYXBwaW5nIGFueSBvZiBtdWx0aXBsZSBzdXBwbGllZFxuICogdmFsdWVzIHRvIHRoZSBlbnVtZXJhdGlvbi4gRW5hYmxlcyBtYXBwaW5nIG9mIG11bHRpcGxlIGlucHV0IHZhbHVlcyB0byBhIGNvbnNpc3RlbnQgaW50ZXJuYWxcbiAqIHJlcHJlc2VudGF0aW9uIChzbyBlLmcuICd5JywgJ3llcycsICd0cnVlJyBhbmQgdHJ1ZSBjYW4gYWxsIG1hcCB0byBib29sZWFuIHRydWUpXG4gKiBAcGFyYW0gbWFwIEFuIGFycmF5IG9mIHR1cGxlcyBkZXNjcmliaW5nIHRoZSBtYXBwaW5nLiBUaGUgZmlyc3QgZWxlbWVudCBvZiBlYWNoIHR1cGxlIGlzIHRoZSByZXN1bHRcbiAqIHZhbHVlLCB0aGUgc2Vjb25kIGlzIHRoZSBzZXQgb2YgdmFsdWVzIHRoYXQgbWFwIHRvIHRoZSByZXN1bHQuICBUdXBsZXMgYXJlIGV2YWx1YXRlZCBpbiB0aGUgb3JkZXJcbiAqIHN1cHBsaWVkIGFuZCBhcmUgbm90IGNoZWNrZWQgZm9yIGR1cGxpY2F0ZXMuXG4gKiBAcGFyYW0gbWVzc2FnZSBhbiBvcHRpb25hbCBlcnJvciBtZXNzYWdlXG4gKiBAcmV0dXJucyBUaGUgbWFwcGVkIHZhbHVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXBwZWRFbnVtZXJhdGVkVmFsdWU8VD4obWFwOiBbVCwgdW5rbm93bltdXVtdLCBtZXNzYWdlPzogc3RyaW5nKTogQ29udmVydGVyPFQsIHVuZGVmaW5lZD4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxULCB1bmRlZmluZWQ+LCBfY29udGV4dD86IHVua25vd24pID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIG1hcCkge1xuICAgICAgICAgICAgaWYgKGl0ZW1bMV0uaW5jbHVkZXMoZnJvbSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3VjY2VlZChpdGVtWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFpbChtZXNzYWdlID8gYCR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9OiAke21lc3NhZ2V9YCA6IGBDYW5ub3QgbWFwICcke0pTT04uc3RyaW5naWZ5KGZyb20pfScgdG8gYSBzdXBwb3J0ZWQgdmFsdWVgKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBIGNvbnZlcnRlciB0byBjb252ZXJ0IHVua25vd24gdG8gc29tZSB2YWx1ZS4gU3VjY2VlZHMgd2l0aCB0aGUgc3VwcGxpZWQgdmFsdWUgaWYgYW4gaWRlbnRpdHlcbiAqIGNvbXBhcmlzb24gc3VjY2VlZHMsIGZhaWxzIG90aGVyd2lzZS5cbiAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gYmUgY29tcGFyZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpdGVyYWw8VD4odmFsdWU6IFQpOiBDb252ZXJ0ZXI8VCwgdW5rbm93bj4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcjxULCB1bmtub3duPigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxULCB1bmtub3duPiwgX2NvbnRleHQ/OiB1bmtub3duKTogUmVzdWx0PFQ+ID0+IHtcbiAgICAgICAgcmV0dXJuIChmcm9tID09PSB2YWx1ZSkgPyBzdWNjZWVkKHZhbHVlKSA6IGZhaWwoYCR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9OiBkb2VzIG5vdCBtYXRjaCAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX1gKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBEZXByZWNhdGVkIGFsaWFzIGZvciBAc2VlIGxpdGVyYWxcbiAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gYmUgY29tcGFyZWRcbiAqIEBkZXByZWNhdGVkIHVzZSBsaXRlcmFsIGluc3RlYWRcbiAqL1xuZXhwb3J0IGNvbnN0IHZhbHVlID0gbGl0ZXJhbDtcblxuLyoqXG4gKiBBIGNvbnZlcnRlciB0byBjb252ZXJ0IHVua25vd24gdG8gYSBudW1iZXIuICBOdW1iZXJzIGFuZCBzdHJpbmdzXG4gKiB3aXRoIGEgbnVtZXJpYyBmb3JtYXQgc3VjY2VlZC4gIEFueXRoaW5nIGVsc2UgZmFpbHMuXG4gKi9cbmV4cG9ydCBjb25zdCBudW1iZXIgPSBuZXcgQmFzZUNvbnZlcnRlcjxudW1iZXI+KChmcm9tOiB1bmtub3duKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBmcm9tICE9PSAnbnVtYmVyJykge1xuICAgICAgICBjb25zdCBudW06IG51bWJlciA9ICh0eXBlb2YgZnJvbSA9PT0gJ3N0cmluZycgPyBOdW1iZXIoZnJvbSkgOiBOYU4pO1xuICAgICAgICByZXR1cm4gaXNOYU4obnVtKVxuICAgICAgICAgICAgPyBmYWlsKGBOb3QgYSBudW1iZXI6ICR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9YClcbiAgICAgICAgICAgIDogc3VjY2VlZChudW0pO1xuICAgIH1cbiAgICByZXR1cm4gc3VjY2VlZChmcm9tKTtcbn0pO1xuXG4vKipcbiAqIEEgY29udmVydGVyIHRvIGNvbnZlcnQgdW5rbm93biB0byBib29sZWFuLiBCb29sZWFuIHZhbHVlcyBvciB0aGVcbiAqIGNhc2UtaW5zZW5zaXRpdmUgc3RyaW5ncyAndHJ1ZScgYW5kICdmYWxzZScgc3VjY2VlZC4gIEFueXRoaW5nXG4gKiBlbHNlIGZhaWxzLlxuICovXG5leHBvcnQgY29uc3QgYm9vbGVhbiA9IG5ldyBCYXNlQ29udmVydGVyPGJvb2xlYW4+KChmcm9tOiB1bmtub3duKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBmcm9tID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgcmV0dXJuIHN1Y2NlZWQoZnJvbSBhcyBib29sZWFuKTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIGZyb20gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHN3aXRjaCAoZnJvbS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlICd0cnVlJzogcmV0dXJuIHN1Y2NlZWQodHJ1ZSk7XG4gICAgICAgICAgICBjYXNlICdmYWxzZSc6IHJldHVybiBzdWNjZWVkKGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFpbChgTm90IGEgYm9vbGVhbjogJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKTtcbn0pO1xuXG4vKipcbiAqIEEgY29udmVydGVyIHRvIGNvbnZlcnQgYW4gb3B0aW9uYWwgc3RyaW5nIHZhbHVlLiBWYWx1ZXMgb2YgdHlwZSBzdHJpbmdcbiAqIGFyZSByZXR1cm5lZC4gIEFueXRoaW5nIGVsc2UgcmV0dXJucyBzdWNjZXNzIHdpdGggYW4gdW5kZWZpbmVkIHZhbHVlLlxuICovXG5leHBvcnQgY29uc3Qgb3B0aW9uYWxTdHJpbmcgPSBzdHJpbmcub3B0aW9uYWwoKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY29udmVydGVyIHdoaWNoIGNvbnZlcnRzIGFueSBzdHJpbmcgaW50byBhbiBhcnJheSBvZiBzdHJpbmdzXG4gKiBieSBzZXBhcmF0aW5nIGF0IGEgc3VwcGxpZWQgZGVsaW1pdGVyLiBEZWxpbWV0ZXIgbWF5IGFsc28gYmUgc3VwcGxpZWRcbiAqIGFzIGNvbnRleHQgYXQgY29udmVyc2lvbiB0aW1lLlxuICogQHBhcmFtIGRlbGltaXRlciBUaGUgZGVsaW1pdGVyIGF0IHdoaWNoIHRvIHNwbGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVsaW1pdGVkU3RyaW5nKGRlbGltaXRlcjogc3RyaW5nLCBvcHRpb25zOiAnZmlsdGVyZWQnfCdhbGwnID0gJ2ZpbHRlcmVkJyk6IENvbnZlcnRlcjxzdHJpbmdbXSwgc3RyaW5nPiB7XG4gICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyPHN0cmluZ1tdLCBzdHJpbmc+KChmcm9tOiB1bmtub3duLCBfc2VsZjogQ29udmVydGVyPHN0cmluZ1tdLCBzdHJpbmc+LCBjb250ZXh0Pzogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHN0cmluZy5jb252ZXJ0KGZyb20pO1xuICAgICAgICBpZiAocmVzdWx0LmlzU3VjY2VzcygpKSB7XG4gICAgICAgICAgICBsZXQgc3RyaW5ncyA9IHJlc3VsdC52YWx1ZS5zcGxpdChjb250ZXh0ID8/IGRlbGltaXRlcik7XG4gICAgICAgICAgICBpZiAob3B0aW9ucyAhPT0gJ2FsbCcpIHtcbiAgICAgICAgICAgICAgICBzdHJpbmdzID0gc3RyaW5ncy5maWx0ZXIoKHMpID0+IChzLnRyaW0oKS5sZW5ndGggPiAwKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc3VjY2VlZChzdHJpbmdzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFpbChyZXN1bHQubWVzc2FnZSk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBjb252ZXJ0ZXIgdG8gY29udmVydCBhbiBpc28gZm9ybWF0dGVkIHN0cmluZywgYSBudW1iZXIgb3IgYSBEYXRlIG9iamVjdCB0byBhIERhdGUgb2JqZWN0XG4gKi9cbmV4cG9ydCBjb25zdCBpc29EYXRlID0gbmV3IEJhc2VDb252ZXJ0ZXI8RGF0ZT4oKGZyb206IHVua25vd24pID0+IHtcbiAgICBpZiAodHlwZW9mIGZyb20gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGNvbnN0IGR0ID0gRGF0ZVRpbWUuZnJvbUlTTyhmcm9tKTtcbiAgICAgICAgaWYgKGR0LmlzVmFsaWQpIHtcbiAgICAgICAgICAgIHJldHVybiBzdWNjZWVkKGR0LnRvSlNEYXRlKCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWlsKGBJbnZhbGlkIGRhdGU6ICR7ZHQuaW52YWxpZEV4cGxhbmF0aW9ufWApO1xuICAgIH1cbiAgICBlbHNlIGlmICh0eXBlb2YgZnJvbSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIHN1Y2NlZWQobmV3IERhdGUoZnJvbSkpO1xuICAgIH1cbiAgICBlbHNlIGlmIChmcm9tIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICByZXR1cm4gc3VjY2VlZChmcm9tKTtcbiAgICB9XG4gICAgcmV0dXJuIGZhaWwoYENhbm5vdCBjb252ZXJ0ICR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9IHRvIERhdGVgKTtcbn0pO1xuXG4vKipcbiAqIEEgY29udmVydGVyIHRvIGNvbnZlcnQgYW4gb3B0aW9uYWwgbnVtYmVyIHZhbHVlLiBWYWx1ZXMgb2YgdHlwZSBudW1iZXJcbiAqIG9yIG51bWVyaWMgc3RyaW5ncyBhcmUgY29udmVydGVkIGFuZCByZXR1cm5lZC4gQW55dGhpbmcgZWxzZSByZXR1cm5zXG4gKiBzdWNjZXNzIHdpdGggYW4gdW5kZWZpbmVkIHZhbHVlLlxuICovXG5leHBvcnQgY29uc3Qgb3B0aW9uYWxOdW1iZXIgPSBudW1iZXIub3B0aW9uYWwoKTtcblxuLyoqXG4gKiBBIGNvbnZlcnRlciB0byBjb252ZXJ0IGFuIG9wdGlvbmFsIGJvb2xlYW4gdmFsdWUuIFZhbHVlcyBvZiB0eXBlIGJvb2xlYW5cbiAqIG9yIHN0cmluZ3MgdGhhdCBtYXRjaCAoY2FzZS1pbnNlbnNpdGl2ZSkgJ3RydWUnIG9yICdmYWxzZScgYXJlIGNvbnZlcnRlZFxuICogYW5kIHJldHVybmVkLiAgQW55dGhpbmcgZWxzZSByZXR1cm5zIHN1Y2Nlc3Mgd2l0aCBhbiB1bmRlZmluZWQgdmFsdWUuXG4gKi9cbmV4cG9ydCBjb25zdCBvcHRpb25hbEJvb2xlYW4gPSBib29sZWFuLm9wdGlvbmFsKCk7XG5cbi8qKlxuICogQSBoZWxwZXIgd3JhcHBlciBmb3IgcG9seW1vcnBoaWMgZmllbGRzLiBJbnZva2VzIHRoZSB3cmFwcGVkIGNvbnZlcnRlcnNcbiAqIGluIHNlcXVlbmNlLCByZXR1cm5pbmcgdGhlIGZpcnN0IHN1Y2Nlc3NmdWwgcmVzdWx0LiAgUmV0dXJucyBhbiBlcnJvclxuICogaWYgbm9uZSBvZiB0aGUgc3VwcGxpZWQgY29udmVydGVycyBjYW4gY29udmVydCB0aGUgdmFsdWUuXG4gKlxuICogSWYgb25FcnJvciBpcyAnaWdub3JlRXJyb3JzJyAoZGVmYXVsdCksIHRoZW4gZXJyb3JzIGZyb20gYW55IG9mIHRoZVxuICogY29udmVydGVycyBhcmUgaWdub3JlZCBwcm92aWRlZCB0aGF0IHNvbWUgY29udmVydGVyIHN1Y2NlZWRzLiAgSWZcbiAqIG9uRXJyb3IgaXMgJ2ZhaWxPbkVycm9yJywgdGhlbiBhbiBlcnJvciBmcm9tIGFueSBjb252ZXJ0ZXIgZmFpbHMgdGhlIGVudGlyZVxuICogY29udmVyc2lvbi5cbiAqXG4gKiBAcGFyYW0gY29udmVydGVycyBBbiBvcmRlcmVkIGxpc3Qgb2YgY29udmVydGVycyB0byBiZSBjb25zaWRlcmVkXG4gKiBAcGFyYW0gb25FcnJvciBTcGVjaWZpZXMgdHJlYXRtZW50IG9mIHVuY29udmVydGFibGUgZWxlbWVudHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uZU9mPFQsIFRDPXVua25vd24+KGNvbnZlcnRlcnM6IEFycmF5PENvbnZlcnRlcjxULCBUQz4+LCBvbkVycm9yOiBPbkVycm9yID0gJ2lnbm9yZUVycm9ycycpOiBDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmLCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGNvbnZlcnRlciBvZiBjb252ZXJ0ZXJzKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBjb252ZXJ0ZXIuY29udmVydChmcm9tLCBjb250ZXh0KTtcbiAgICAgICAgICAgIGlmIChyZXN1bHQuaXNTdWNjZXNzKCkgJiYgKHJlc3VsdC52YWx1ZSAhPT0gdW5kZWZpbmVkKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChyZXN1bHQuaXNGYWlsdXJlKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAob25FcnJvciA9PT0gJ2ZhaWxPbkVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChyZXN1bHQubWVzc2FnZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhaWwoYE5vIG1hdGNoaW5nIGNvbnZlcnRlciBmb3IgJHtKU09OLnN0cmluZ2lmeShmcm9tKX06ICR7ZXJyb3JzLmpvaW4oJ1xcbicpfWApO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEEgaGVscGVyIHdyYXBwZXIgZm9yIGNvbnZlcnRpbmcgYW4gYXJyYXkgb2YgPFQ+LiAgSWYgb25FcnJvciBpcyAnZmFpbE9uRXJyb3InIChkZWZhdWx0KSxcbiAqIHRoZW4gdGhlIGVudGlyZSBjb252ZXJzaW9uIGZhaWxzIGlmIGFueSBlbGVtZW50IGNhbm5vdCBiZSBjb252ZXJ0ZWQuICBJZiBvbkVycm9yXG4gKiBpcyAnaWdub3JlRXJyb3JzJywgZmFpbGluZyBlbGVtZW50cyBhcmUgc2lsZW50bHkgaWdub3JlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgQ29udmVydGVyIHVzZWQgdG8gY29udmVydCBlYWNoIGl0ZW0gaW4gdGhlIGFycmF5XG4gKiBAcGFyYW0gaWdub3JlRXJyb3JzIFNwZWNpZmllcyB0cmVhdG1lbnQgb2YgdW5jb252ZXJ0YWJsZSBlbGVtZW50c1xuICovXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlPZjxULCBUQz11bmRlZmluZWQ+KGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPiwgb25FcnJvcjogT25FcnJvciA9ICdmYWlsT25FcnJvcicpOiBDb252ZXJ0ZXI8VFtdLCBUQz4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxUW10sIFRDPiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShmcm9tKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYE5vdCBhbiBhcnJheTogJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN1Y2Nlc3NlczogVFtdID0gW107XG4gICAgICAgIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGZyb20pIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnZlcnRlci5jb252ZXJ0KGl0ZW0sIGNvbnRleHQpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSAmJiByZXN1bHQudmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3Nlcy5wdXNoKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChyZXN1bHQuaXNGYWlsdXJlKCkpIHtcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChyZXN1bHQubWVzc2FnZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gKGVycm9ycy5sZW5ndGggPT09IDApIHx8IChvbkVycm9yID09PSAnaWdub3JlRXJyb3JzJylcbiAgICAgICAgICAgID8gc3VjY2VlZChzdWNjZXNzZXMpXG4gICAgICAgICAgICA6IGZhaWwoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBIGhlbHBlciB3cmFwcGVyIGZvciBjb252ZXJ0aW5nIHRvIEl0ZW1ycmF5PFQ+LiAgSWYgb25FcnJvciBpcyAnZmFpbE9uRXJyb3InIChkZWZhdWx0KSxcbiAqIHRoZW4gdGhlIGVudGlyZSBjb252ZXJzaW9uIGZhaWxzIGlmIGFueSBlbGVtZW50IGNhbm5vdCBiZSBjb252ZXJ0ZWQuICBJZiBvbkVycm9yXG4gKiBpcyAnaWdub3JlRXJyb3JzJywgZmFpbGluZyBlbGVtZW50cyBhcmUgc2lsZW50bHkgaWdub3JlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgQ29udmVydGVyIHVzZWQgdG8gY29udmVydCBlYWNoIGl0ZW0gaW4gdGhlIGFycmF5XG4gKiBAcGFyYW0gaWdub3JlRXJyb3JzIFNwZWNpZmllcyB0cmVhdG1lbnQgb2YgdW5jb252ZXJ0YWJsZSBlbGVtZW50c1xuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0ZW5kZWRBcnJheU9mPFQsIFRDPXVuZGVmaW5lZD4obGFiZWw6IHN0cmluZywgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+LCBvbkVycm9yOiBPbkVycm9yID0gJ2ZhaWxPbkVycm9yJyk6IENvbnZlcnRlcjxFeHRlbmRlZEFycmF5PFQ+LCBUQz4ge1xuICAgIHJldHVybiBhcnJheU9mKGNvbnZlcnRlciwgb25FcnJvcikubWFwKChpdGVtczogVFtdKSA9PiB7XG4gICAgICAgIHJldHVybiBjYXB0dXJlUmVzdWx0KCgpID0+IG5ldyBFeHRlbmRlZEFycmF5KGxhYmVsLCAuLi5pdGVtcykpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnRlciB0byBjb252ZXJ0IGFuIHVua25vd24gdG8gYW4gYXJyYXkgb2Ygc3RyaW5ncy4gQ29udmVyc2lvbiBzdWNjZWVkc1xuICogYW5kIHJldHVybnMgdGhlIHN1cHBsaWVkIHZhbHVlIGlmIGl0IGFzIGFuIGFycmF5IG9mIHN0cmluZ3MsIGZhaWxzIG90aGVyd2lzZS5cbiAqL1xuZXhwb3J0IGNvbnN0IHN0cmluZ0FycmF5ID0gYXJyYXlPZihzdHJpbmcpO1xuXG4vKipcbiAqIENvbnZlcnRlciB0byBjb252ZXJ0IGFuIHVua25vd24gdG8gYW4gYXJyYXkgb2YgbnVtYmVycy4gQ29udmVyc2lvbiBzdWNjZWVkc1xuICogYW5kIHJldHVybnMgdGhlIHN1cHBsaWVkIHZhbHVlIGlmIGl0IGFzIGFuIGFycmF5IG9mIG51bWJlcnMsIGZhaWxzIG90aGVyd2lzZS5cbiAqL1xuZXhwb3J0IGNvbnN0IG51bWJlckFycmF5ID0gYXJyYXlPZihudW1iZXIpO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yICdyZWNvcmRPZicgYW5kICdtYXBPZicgY29udmVydGVyc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEtleWVkQ29udmVydGVyT3B0aW9uczxUIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nLCBUQz11bmRlZmluZWQ+IHtcbiAgICBvbkVycm9yPzogJ2ZhaWwnfCdpZ25vcmUnO1xuICAgIGtleUNvbnZlcnRlcj86IENvbnZlcnRlcjxULCBUQz47XG59XG5cbi8qKlxuICogQSBoZWxwZXIgd3JhcHBlciB0byBjb252ZXJ0IHRoZSBzdHJpbmcta2V5ZWQgcHJvcGVydGllcyBvZiBhbiBvYmplY3QgdG8gYSBSZWNvcmQgb2YgVC5cbiAqIENvbnZlcnNpb24gZmFpbHMgaWYgYW55IGVsZW1lbnQgY2Fubm90IGJlIGNvbnZlcnRlZC4gIElmIG9uRXJyb3IgaXMgJ2lnbm9yZScgZmFpbGluZ1xuICogZWxlbWVudHMgYXJlIHNpbGVudGx5IGlnbm9yZWQuXG4gKiBAcGFyYW0gY29udmVydGVyIENvbnZlcnRlciB1c2VkIHRvIGNvbnZlcnQgZWFjaCBpdGVtIGluIHRoZSByZWNvcmRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlY29yZE9mPFQsIFRDPXVuZGVmaW5lZCwgVEsgZXh0ZW5kcyBzdHJpbmc9c3RyaW5nPihjb252ZXJ0ZXI6IENvbnZlcnRlcjxULCBUQz4pOiBDb252ZXJ0ZXI8UmVjb3JkPFRLLCBUPiwgVEM+O1xuXG4vKipcbiAqIEEgaGVscGVyIHdyYXBwZXIgdG8gY29udmVydCB0aGUgc3RyaW5nLWtleWVkIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0IHRvIGEgUmVjb3JkIG9mIFQuXG4gKiBJZiBvbkVycm9yIGlzICdmYWlsJyAoZGVmYXVsdCksICB0aGVuIHRoZSBlbnRpcmUgY29udmVyc2lvbiBmYWlscyBpZiBhbnkgZWxlbWVudFxuICogY2Fubm90IGJlIGNvbnZlcnRlZC4gIElmIG9uRXJyb3IgaXMgJ2lnbm9yZScgZmFpbGluZyBlbGVtZW50cyBhcmUgc2lsZW50bHkgaWdub3JlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgQ29udmVydGVyIHVzZWQgdG8gY29udmVydCBlYWNoIGl0ZW0gaW4gdGhlIHJlY29yZFxuICogQHBhcmFtIG9uRXJyb3IgU3BlY2lmaWVzIHRyZWF0bWVudCBvZiB1bmNvbnZlcnRhYmxlIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRPZjxULCBUQz11bmRlZmluZWQsIFRLIGV4dGVuZHMgc3RyaW5nPXN0cmluZz4oXG4gICAgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+LFxuICAgIG9uRXJyb3I6ICdmYWlsJ3wnaWdub3JlJ1xuKTogQ29udmVydGVyPFJlY29yZDxUSywgVD4sIFRDPjtcblxuLyoqXG4gKiBBIGhlbHBlciB3cmFwcGVyIHRvIGNvbnZlcnQgdGhlIHN0cmluZy1rZXllZCBwcm9wZXJ0aWVzIG9mIGFuIG9iamVjdCB0byBhIFJlY29yZCBvZiBULlxuICogSWYgb3B0aW9ucyBzcGVjaWZ5IGEga2V5IGNvbnZlcnRlciBpdCB3aWxsIGJlIGFwcGxpZWQgdG8gZWFjaCBrZXkuXG4gKiBJZiBvbkVycm9yIGlzICdmYWlsJyAoZGVmYXVsdCksICB0aGVuIHRoZSBlbnRpcmUgY29udmVyc2lvbiBmYWlscyBpZiBhbnkga2V5IG9yIGVsZW1lbnRcbiAqIGNhbm5vdCBiZSBjb252ZXJ0ZWQuICBJZiBvbkVycm9yIGlzICdpZ25vcmUnIGZhaWxpbmcgZWxlbWVudHMgYXJlIHNpbGVudGx5IGlnbm9yZWQuXG4gKiBAcGFyYW0gY29udmVydGVyIENvbnZlcnRlciB1c2VkIHRvIGNvbnZlcnQgZWFjaCBpdGVtIGluIHRoZSByZWNvcmRcbiAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbmFsIEBzZWUgS2V5ZWRDb252ZXJ0ZXJPcHRpb25zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRPZjxULCBUQz11bmRlZmluZWQsIFRLIGV4dGVuZHMgc3RyaW5nPXN0cmluZz4oXG4gICAgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+LFxuICAgIG9wdGlvbnM6IEtleWVkQ29udmVydGVyT3B0aW9uczxUSywgVEM+XG4pOiBDb252ZXJ0ZXI8UmVjb3JkPFRLLCBUPiwgVEM+O1xuXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkT2Y8VCwgVEM9dW5kZWZpbmVkLCBUSyBleHRlbmRzIHN0cmluZz1zdHJpbmc+KFxuICAgIGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPixcbiAgICBvcHRpb246ICdmYWlsJ3wnaWdub3JlJ3xLZXllZENvbnZlcnRlck9wdGlvbnM8VEssIFRDPiA9ICdmYWlsJ1xuKTogQ29udmVydGVyPFJlY29yZDxUSywgVD4sIFRDPiB7XG4gICAgY29uc3Qgb3B0aW9uczogS2V5ZWRDb252ZXJ0ZXJPcHRpb25zPFRLLCBUQz4gPSAodHlwZW9mIG9wdGlvbiA9PT0gJ3N0cmluZycpID8geyBvbkVycm9yOiBvcHRpb24gfSA6IHsgb25FcnJvcjogJ2ZhaWwnLCAuLi5vcHRpb24gfTtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8UmVjb3JkPFRLLCBUPiwgVEM+LCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgaWYgKCh0eXBlb2YgZnJvbSAhPT0gJ29iamVjdCcpIHx8IChmcm9tID09PSBudWxsKSB8fCBBcnJheS5pc0FycmF5KGZyb20pKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFpbChgTm90IGEgc3RyaW5nLWtleWVkIG9iamVjdDogJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlY29yZDogUmVjb3JkPHN0cmluZywgVD4gPSB7fTtcbiAgICAgICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGZyb20pIHtcbiAgICAgICAgICAgIGlmIChpc0tleU9mKGtleSwgZnJvbSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB3cml0ZUtleVJlc3VsdCA9IG9wdGlvbnMua2V5Q29udmVydGVyPy5jb252ZXJ0KGtleSwgY29udGV4dCkgPz8gc3VjY2VlZChrZXkpO1xuXG4gICAgICAgICAgICAgICAgd3JpdGVLZXlSZXN1bHQub25TdWNjZXNzKCh3cml0ZUtleSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udmVydGVyLmNvbnZlcnQoZnJvbVtrZXldIGFzIHVua25vd24sIGNvbnRleHQpLm9uU3VjY2VzcygodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlY29yZFt3cml0ZUtleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWNjZWVkKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KS5vbkZhaWx1cmUoKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JzLnB1c2gobWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWlsKG1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChlcnJvcnMubGVuZ3RoID09PSAwKSB8fCAob3B0aW9ucy5vbkVycm9yID09PSAnaWdub3JlJylcbiAgICAgICAgICAgID8gc3VjY2VlZChyZWNvcmQpXG4gICAgICAgICAgICA6IGZhaWwoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBIGhlbHBlciB3cmFwcGVyIHRvIGNvbnZlcnQgdGhlIHN0cmluZy1rZXllZCBwcm9wZXJ0aWVzIG9mIGFuIG9iamVjdCB0byBhIE1hcCBvZiBULlxuICogQ29udmVyc2lvbiBmYWlscyBpZiBhbnkgZWxlbWVudCBjYW5ub3QgYmUgY29udmVydGVkLlxuICogQHBhcmFtIGNvbnZlcnRlciBDb252ZXJ0ZXIgdXNlZCB0byBjb252ZXJ0IGVhY2ggaXRlbSBpbiB0aGUgbWFwXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXBPZjxULCBUQyA9IHVuZGVmaW5lZCwgVEsgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+KGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPik6IENvbnZlcnRlcjxNYXA8VEssIFQ+LCBUQz47XG5cbi8qKlxuICogQSBoZWxwZXIgd3JhcHBlciB0byBjb252ZXJ0IHRoZSBzdHJpbmcta2V5ZWQgcHJvcGVydGllcyBvZiBhbiBvYmplY3QgdG8gYSBNYXAgb2YgVC5cbiAqIElmIG9uRXJyb3IgaXMgJ2ZhaWwnIChkZWZhdWx0KSwgIHRoZW4gdGhlIGVudGlyZSBjb252ZXJzaW9uIGZhaWxzIGlmIGFueSBlbGVtZW50XG4gKiBjYW5ub3QgYmUgY29udmVydGVkLiAgSWYgb25FcnJvciBpcyAnaWdub3JlJyBmYWlsaW5nIGVsZW1lbnRzIGFyZSBzaWxlbnRseSBpZ25vcmVkLlxuICogQHBhcmFtIGNvbnZlcnRlciBDb252ZXJ0ZXIgdXNlZCB0byBjb252ZXJ0IGVhY2ggaXRlbSBpbiB0aGUgbWFwXG4gKiBAcGFyYW0gb25FcnJvciBTcGVjaWZpZXMgdHJlYXRtZW50IG9mIHVuY29udmVydGFibGUgZWxlbWVudHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcE9mPFQsIFRDID0gdW5kZWZpbmVkLCBUSyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4oXG4gICAgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+LFxuICAgIG9uRXJyb3I6ICdmYWlsJyB8ICdpZ25vcmUnXG4pOiBDb252ZXJ0ZXI8TWFwPFRLLCBUPiwgVEM+O1xuXG4vKipcbiAqIEEgaGVscGVyIHdyYXBwZXIgdG8gY29udmVydCB0aGUgc3RyaW5nLWtleWVkIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0IHRvIGEgTWFwIG9mIFQuXG4gKiBJZiBvcHRpb25zIHNwZWNpZnkgYSBrZXkgY29udmVydGVyIGl0IHdpbGwgYmUgYXBwbGllZCB0byBlYWNoIGtleS5cbiAqIElmIG9uRXJyb3IgaXMgJ2ZhaWwnIChkZWZhdWx0KSwgIHRoZW4gdGhlIGVudGlyZSBjb252ZXJzaW9uIGZhaWxzIGlmIGFueSBrZXkgb3IgZWxlbWVudFxuICogY2Fubm90IGJlIGNvbnZlcnRlZC4gIElmIG9uRXJyb3IgaXMgJ2lnbm9yZScgZmFpbGluZyBlbGVtZW50cyBhcmUgc2lsZW50bHkgaWdub3JlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgQ29udmVydGVyIHVzZWQgdG8gY29udmVydCBlYWNoIGl0ZW0gaW4gdGhlIG1hcFxuICogQHBhcmFtIG9wdGlvbnMgT3B0aW9uYWwgQHNlZSBLZXllZENvbnZlcnRlck9wdGlvbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcE9mPFQsIFRDID0gdW5kZWZpbmVkLCBUSyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4oXG4gICAgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+LFxuICAgIG9wdGlvbnM6IEtleWVkQ29udmVydGVyT3B0aW9uczxUSywgVEM+XG4pOiBDb252ZXJ0ZXI8TWFwPFRLLCBUPiwgVEM+O1xuXG5leHBvcnQgZnVuY3Rpb24gbWFwT2Y8VCwgVEMgPSB1bmRlZmluZWQsIFRLIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPihcbiAgICBjb252ZXJ0ZXI6IENvbnZlcnRlcjxULCBUQz4sXG4gICAgb3B0aW9uOiAnZmFpbCcgfCAnaWdub3JlJyB8IEtleWVkQ29udmVydGVyT3B0aW9uczxUSywgVEM+ID0gJ2ZhaWwnXG4pOiBDb252ZXJ0ZXI8TWFwPFRLLCBUPiwgVEM+IHtcbiAgICBjb25zdCBvcHRpb25zID0gKHR5cGVvZiBvcHRpb24gPT09ICdzdHJpbmcnKSA/IHsgb25FcnJvcjogb3B0aW9uIH0gOiB7IG9uRXJyb3I6ICdmYWlsJywgLi4ub3B0aW9uIH07XG4gICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyKChmcm9tOiB1bmtub3duLCBfc2VsZjogQ29udmVydGVyPE1hcDxUSywgVD4sIFRDPiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgIGlmICgodHlwZW9mIGZyb20gIT09ICdvYmplY3QnKSB8fCAoZnJvbSA9PT0gbnVsbCkgfHwgQXJyYXkuaXNBcnJheShmcm9tKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYE5vdCBhIHN0cmluZy1rZXllZCBvYmplY3Q6ICR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBtYXAgPSBuZXcgTWFwPFRLLCBUPigpO1xuICAgICAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG5cbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZnJvbSkge1xuICAgICAgICAgICAgaWYgKGlzS2V5T2Yoa2V5LCBmcm9tKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHdyaXRlS2V5UmVzdWx0ID0gb3B0aW9ucy5rZXlDb252ZXJ0ZXI/LmNvbnZlcnQoa2V5LCBjb250ZXh0KSA/PyBzdWNjZWVkKGtleSk7XG5cbiAgICAgICAgICAgICAgICB3cml0ZUtleVJlc3VsdC5vblN1Y2Nlc3MoKHdyaXRlS2V5KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb252ZXJ0ZXIuY29udmVydChmcm9tW2tleV0gYXMgdW5rbm93biwgY29udGV4dCkub25TdWNjZXNzKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWFwLnNldCh3cml0ZUtleSwgdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1Y2NlZWQodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pLm9uRmFpbHVyZSgobWVzc2FnZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChtZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhaWwobWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gKGVycm9ycy5sZW5ndGggPT09IDApIHx8IChvcHRpb25zLm9uRXJyb3IgPT09ICdpZ25vcmUnKVxuICAgICAgICAgICAgPyBzdWNjZWVkKG1hcClcbiAgICAgICAgICAgIDogZmFpbChlcnJvcnMuam9pbignXFxuJykpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEdldHMgYSBjb252ZXJ0ZXIgd2hpY2ggdmFsaWRhdGVzIHRoYXQgYSBzdXBwbGllZCB2YWx1ZSBpcyBvZiBhIHR5cGUgdmFsaWRhdGVkIGJ5XG4gKiBhIHN1cHBsaWVkIHZhbGlkYXRvciBhbmQgcmV0dXJucyBpdC5cbiAqIEBwYXJhbSB2YWxpZGF0b3IgQSB2YWxpZGF0b3IgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGlmIHRoZSBjb252ZXJ0ZWQgdmFsdWUgaXMgdmFsaWRcbiAqIEBwYXJhbSBkZXNjcmlwdGlvbiBBIGRlc2NyaXB0aW9uIG9mIHRoZSB2YWxpZGF0ZSB0eXBlIGZvciB1c2UgaW4gZXJyb3IgbWVzc2FnZXNcbiAqIEByZXR1cm5zIElmIHZhbGlkYXRvciByZXR1cm5zIHRydWUsIHN1Y2VlZHMgd2l0aCBmcm9tIGNvZXJjZWQgdG8gVC4gIEZhaWxzIHdpdGggYW4gZXJyb3JcbiAqIG1lc3NhZ2Ugb3RoZXJ3aXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVXaXRoPFQsIFRDPXVuZGVmaW5lZD4odmFsaWRhdG9yOiAoZnJvbTogdW5rbm93bikgPT4gZnJvbSBpcyBULCBkZXNjcmlwdGlvbj86IHN0cmluZyk6IENvbnZlcnRlcjxULCBUQz4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxULCBUQz4sIF9jb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgaWYgKHZhbGlkYXRvcihmcm9tKSkge1xuICAgICAgICAgICAgcmV0dXJuIHN1Y2NlZWQoZnJvbSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhaWwoYCR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9OiBpbnZhbGlkICR7ZGVzY3JpcHRpb24gPz8gJ3ZhbHVlJ31gKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBIGhlbHBlciBmdW5jdGlvbiB0byBleHRyYWN0IGFuZCBjb252ZXJ0IGFuIGVsZW1lbnQgZnJvbSBhbiBhcnJheS4gU3VjY2VlZHMgYW5kIHJldHVybnNcbiAqIHRoZSBjb252ZXJ0ZWQgdmFsdWUgaWYgdGhlIGVsZW1lbnQgZXhpc3RzIGluIHRoZSBzdXBwbGllZCBwYXJhbWV0ZXIgYW5kIGNhbiBiZSBjb252ZXJ0ZWQuXG4gKiBGYWlscyBvdGhlcndpc2UuXG4gKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBmaWVsZCB0byBiZSBleHRyYWN0ZWQuXG4gKiBAcGFyYW0gY29udmVydGVyIENvbnZlcnRlciB1c2VkIHRvIGNvbnZlcnQgdGhlIGV4dHJhY3RlZCBlbGVtZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZWxlbWVudDxULCBUQz11bmRlZmluZWQ+KGluZGV4OiBudW1iZXIsIGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPik6IENvbnZlcnRlcjxULCBUQz4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxULCBUQz4sIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFpbChgJHtpbmRleH06IGNhbm5vdCBjb252ZXJ0IGZvciBhIG5lZ2F0aXZlIGVsZW1lbnQgaW5kZXhgKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghQXJyYXkuaXNBcnJheShmcm9tKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoJ2VsZW1lbnQgY29udmVydGVyOiBzb3VyY2UgaXMgbm90IGFuIGFycmF5Jyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaW5kZXggPj0gZnJvbS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKGAke2luZGV4fTogZWxlbWVudCBjb252ZXJ0ZXIgaW5kZXggb3V0IG9mIHJhbmdlICgwLi4ke2Zyb20ubGVuZ3RoIC0gMX0pYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbnZlcnRlci5jb252ZXJ0KGZyb21baW5kZXhdLCBjb250ZXh0KTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBIGhlbHBlciBmdW5jdGlvbiB0byBleHRyYWN0IGFuZCBjb252ZXJ0IGFuIG9wdGlvbmFsIGVsZW1lbnQgZnJvbSBhbiBhcnJheS4gU3VjY2VlZHNcbiAqIGFuZCByZXR1cm5zIHRoZSBjb252ZXJ0ZWQgdmFsdWUgaWYgdGhlIGVsZW1lbnQgZXhpc3RzIGluIHRoZSBzdXBwbGllZCBwYXJhbWV0ZXIgYW5kIGNhblxuICogYmUgY29udmVydGVkLiBTdWNjZWVkcyB3aXRoIHVuZGVmaW5lZCBpZiB0aGUgcGFyYW1ldGVyIGlzIGFuIGFycmF5IGJ1dCB0aGUgaW5kZXggaXMgdG9vXG4gKiBsYXJnZS4gRmFpbHMgaWYgdGhlIHN1cHBsaWVkIHBhcmFtZXRlciBpcyBub3QgYW4gYXJyYXksIGlmIHRoZSByZXF1ZXN0ZWQgaW5kZXggaXMgbmVnYXRpdmUsXG4gKiBvciBpZiB0aGUgZWxlbWVudCBjYW5ub3QgYmUgY29udmVydGVkLlxuICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGJlIGV4dHJhY3RlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgQ29udmVydGVyIHVzZWQgdG8gY29udmVydCB0aGUgZXh0cmFjdGVkIGZpZWxkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gb3B0aW9uYWxFbGVtZW50PFQsIFRDPXVuZGVmaW5lZD4oaW5kZXg6IG51bWJlciwgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+KTogQ29udmVydGVyPFR8dW5kZWZpbmVkLCBUQz4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxUfHVuZGVmaW5lZCwgVEM+LCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYCR7aW5kZXh9OiBjYW5ub3QgY29udmVydCBmb3IgYSBuZWdhdGl2ZSBlbGVtZW50IGluZGV4YCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIUFycmF5LmlzQXJyYXkoZnJvbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKCdlbGVtZW50IGNvbnZlcnRlcjogc291cmNlIGlzIG5vdCBhbiBhcnJheScpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGluZGV4ID49IGZyb20ubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gc3VjY2VlZCh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb252ZXJ0ZXIuY29udmVydChmcm9tW2luZGV4XSwgY29udGV4dCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gZXh0cmFjdCBhbmQgY29udmVydCBhIGZpZWxkIGZyb20gYW4gb2JqZWN0LiBTdWNjZWVkcyBhbmQgcmV0dXJuc1xuICogdGhlIGNvbnZlcnRlZCB2YWx1ZSBpZiB0aGUgZmllbGQgZXhpc3RzIGluIHRoZSBzdXBwbGllZCBwYXJhbWV0ZXIgYW5kIGNhbiBiZSBjb252ZXJ0ZWQuXG4gKiBGYWlscyBvdGhlcndpc2UuXG4gKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZmllbGQgdG8gYmUgZXh0cmFjdGVkLlxuICogQHBhcmFtIGNvbnZlcnRlciBDb252ZXJ0ZXIgdXNlZCB0byBjb252ZXJ0IHRoZSBleHRyYWN0ZWQgZmllbGQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaWVsZDxULCBUQz11bmRlZmluZWQ+KG5hbWU6IHN0cmluZywgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+KTogQ29udmVydGVyPFQsIFRDPiB7XG4gICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyKChmcm9tOiB1bmtub3duLCBfc2VsZjogQ29udmVydGVyPFQsIFRDPiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgZnJvbSA9PT0gJ29iamVjdCcgJiYgKCFBcnJheS5pc0FycmF5KGZyb20pKSAmJiBmcm9tICE9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoaXNLZXlPZihuYW1lLCBmcm9tKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb252ZXJ0ZXIuY29udmVydChmcm9tW25hbWVdLCBjb250ZXh0KS5vbkZhaWx1cmUoKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhaWwoYEZpZWxkICR7bmFtZX06ICR7bWVzc2FnZX1gKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWlsKGBGaWVsZCAke25hbWV9IG5vdCBmb3VuZCBpbjogJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFpbChgQ2Fubm90IGNvbnZlcnQgZmllbGQgXCIke25hbWV9XCIgZnJvbSBub24tb2JqZWN0ICR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9YCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gZXh0cmFjdCBhbmQgY29udmVydCBhbiBvcHRpb25hbCBmaWVsZCBmcm9tIGFuIG9iamVjdC4gU3VjY2VlZHNcbiAqIGFuZCByZXR1cm5zIHRoZSBjb252ZXJ0ZWQgdmFsdWUgaWYgdGhlIGZpZWxkIGV4aXN0cyBpbiB0aGUgc3VwcGxpZWQgcGFyYW1ldGVyIGFuZCBjYW5cbiAqIGJlIGNvbnZlcnRlZC4gU3VjY2VlZHMgd2l0aCB1bmRlZmluZWQgaWYgdGhlIHBhcmFtZXRlciBpcyBhbiBvYmplY3QgYnV0IHRoZSBuYW1lZCBmaWVsZFxuICogaXMgbm90IHByZXNlbnQuIEZhaWxzIGlmIHRoZSBzdXBwbGllZCBwYXJhbWV0ZXIgaXMgbm90IGFuIG9iamVjdC5cbiAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBiZSBleHRyYWN0ZWQuXG4gKiBAcGFyYW0gY29udmVydGVyIENvbnZlcnRlciB1c2VkIHRvIGNvbnZlcnQgdGhlIGV4dHJhY3RlZCBmaWVsZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9wdGlvbmFsRmllbGQ8VCwgVEM9dW5kZWZpbmVkPihuYW1lOiBzdHJpbmcsIGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPik6IENvbnZlcnRlcjxUfHVuZGVmaW5lZCwgVEM+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VHx1bmRlZmluZWQsIFRDPiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgZnJvbSA9PT0gJ29iamVjdCcgJiYgKCFBcnJheS5pc0FycmF5KGZyb20pKSAmJiBmcm9tICE9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoaXNLZXlPZihuYW1lLCBmcm9tKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnZlcnRlci5jb252ZXJ0KGZyb21bbmFtZV0sIGNvbnRleHQpLm9uRmFpbHVyZSgobWVzc2FnZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFpbChgJHtuYW1lfTogJHttZXNzYWdlfWApO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgLy8gaWYgY29udmVyc2lvbiB3YXMgc3VjY2Vzc2Z1bCBvciBpbnB1dCB3YXMgdW5kZWZpbmVkIHdlXG4gICAgICAgICAgICAgICAgLy8gc3VjY2VlZCB3aXRoICd1bmRlZmluZWQnLCBidXQgd2UgcHJvcGFnYXRlIGFjdHVhbFxuICAgICAgICAgICAgICAgIC8vIGZhaWx1cmVzLlxuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuaXNTdWNjZXNzKCkgfHwgKGZyb21bbmFtZV0gIT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc3VjY2VlZCh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWlsKGBDYW5ub3QgY29udmVydCBmaWVsZCBcIiR7bmFtZX1cIiBmcm9tIG5vbi1vYmplY3QgJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKTtcbiAgICB9LCB1bmRlZmluZWQsIHsgaXNPcHRpb25hbDogdHJ1ZSB9KTtcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBhbiBAc2VlIE9iamVjdENvbnZlcnRlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+IHtcbiAgICAvKipcbiAgICAgKiBJZiBwcmVzZW50LCBsaXN0cyBvcHRpb25hbCBmaWVsZHMuIE1pc3Npbmcgbm9uLW9wdGlvbmFsIGZpZWxkcyBjYXVzZSBhbiBlcnJvci5cbiAgICAgKi9cbiAgICBvcHRpb25hbEZpZWxkcz86IChrZXlvZiBUKVtdO1xuICAgIC8qKlxuICAgICAqIElmIHRydWUsIHVucmVjb2duaXplZCBmaWVsZHMgeWllbGQgYW4gZXJyb3IuICBJZiBmYWxzZSBvciB1bmRlZmluZWQgKGRlZmF1bHQpLFxuICAgICAqIHVucmVjb2duaXplZCBmaWVsZHMgYXJlIGlnbm9yZWQuXG4gICAgICovXG4gICAgc3RyaWN0PzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBQZXItcHJvcGVydHkgY29udmVydGVycyBmb3IgZWFjaCBvZiB0aGUgcHJvcGVydGllcyBpbiB0eXBlIFQuXG4gKi9cbmV4cG9ydCB0eXBlIEZpZWxkQ29udmVydGVyczxULCBUQz11bmtub3duPiA9IHsgWyBrZXkgaW4ga2V5b2YgVCBdOiBDb252ZXJ0ZXI8VFtrZXldLCBUQz4gfTtcblxuLyoqXG4gKiBDb252ZXJ0ZXIgdG8gY29udmVydCBhbiBvYmplY3Qgb2YgdHlwZSBUIHdpdGhvdXQgY2hhbmdpbmcgc2hhcGUsIGdpdmVuIGEgQHNlZSBGaWVsZENvbnZlcnRlcnM8VD4uXG4gKiBJZiBhbGwgb2YgdGhlIHJlcXVpcmVkIGZpZWxkcyBleGlzdCBhbmQgY2FuIGJlIGNvbnZlcnRlZCwgcmV0dXJucyBhIG5ldyBvYmplY3Qgd2l0aCB0aGUgY29udmVydGVkXG4gKiB2YWx1ZXMgdW5kZXIgdGhlIG9yaWdpbmFsIGtleSBuYW1lcy4gIElmIGFueSByZXF1aXJlZCBmaWVsZHMgZG8gbm90IGV4aXN0IG9yIGNhbm5vdCBiZSBjb252ZXJ0ZWQsXG4gKiB0aGUgZW50aXJlIGNvbnZlcnNpb24gZmFpbHMuICBTZWUgQHNlZSBPYmplY3RDb252ZXJ0ZXJPcHRpb25zIGZvciBvdGhlciBjb252ZXJzaW9uIG9wdGlvbnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBPYmplY3RDb252ZXJ0ZXI8VCwgVEM9dW5rbm93bj4gZXh0ZW5kcyBCYXNlQ29udmVydGVyPFQsIFRDPiB7XG4gICAgcHVibGljIHJlYWRvbmx5IGZpZWxkczogRmllbGRDb252ZXJ0ZXJzPFQ+O1xuICAgIHB1YmxpYyByZWFkb25seSBvcHRpb25zOiBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+O1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBAc2VlIE9iamVjdENvbnZlcnRlcjxUPiB1c2luZyBvcHRpb25zIHN1cHBsaWVkIGluIGFuXG4gICAgICogb3B0aW9uYWwgQHNlZSBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+LlxuICAgICAqIEBwYXJhbSBmaWVsZHMgQSBAc2VlIEZpZWxkQ29udmVydGVyczxUPiBjb250YWluaW5nIGNvbnZlcnRlcnMgZm9yIGVhY2ggZmllbGRcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBBbiBvcHRpb25hbCBAc2VlIE9iamVjdENvbnZlcnRlck9wdGlvbnMgdG8gY29uZmlndXJlIHRoZSBjb252ZXJzaW9uXG4gICAgICovXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKGZpZWxkczogRmllbGRDb252ZXJ0ZXJzPFQsIFRDPiwgb3B0aW9ucz86IE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD4pXG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IEBzZWUgT2JqZWN0Q29udmVydGVyPFQ+IHVzaW5nIG9wdGlvbmFsIGZpZWxkcyBzdXBwbGllZCBpbiBhblxuICAgICAqIG9wdGlvbmFsIGFycmF5IG9mIGtleW9mIFQuXG4gICAgICogQHBhcmFtIGZpZWxkcyBBIEBzZWUgRmllbGRDb252ZXJ0ZXJzPFQ+IGNvbnRhaW5pbmcgY29udmVydGVycyBmb3IgZWFjaCBmaWVsZFxuICAgICAqIEBwYXJhbSBvcHRpb25hbCBBbiBvcHRpb25hbCBhcnJheSBvZiBrZXlvZiBUIGxpc3RpbmcgZmllbGRzIHRoYXQgYXJlIG5vdCByZXF1aXJlZC5cbiAgICAgKi9cbiAgICBwdWJsaWMgY29uc3RydWN0b3IoZmllbGRzOiBGaWVsZENvbnZlcnRlcnM8VCwgVEM+LCBvcHRpb25hbD86IChrZXlvZiBUKVtdKTtcbiAgICBwdWJsaWMgY29uc3RydWN0b3IoZmllbGRzOiBGaWVsZENvbnZlcnRlcnM8VCwgVEM+LCBvcHQ/OiBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+fChrZXlvZiBUKVtdKSB7XG4gICAgICAgIHN1cGVyKChmcm9tOiB1bmtub3duLCBfc2VsZiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgICAgICAvLyBlc2xpbnQgYnVnIHRoaW5rcyBrZXkgaXMgdXNlZCBiZWZvcmUgZGVmaW5lZFxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZS1iZWZvcmUtZGVmaW5lXG4gICAgICAgICAgICBjb25zdCBjb252ZXJ0ZWQgPSB7fSBhcyB7IFtrZXkgaW4ga2V5b2YgVF06IFRba2V5XSB9O1xuICAgICAgICAgICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZmllbGRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZpZWxkc1trZXldKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlzT3B0aW9uYWwgPSAoZmllbGRzW2tleV0uaXNPcHRpb25hbCB8fCB0aGlzLm9wdGlvbnMub3B0aW9uYWxGaWVsZHM/LmluY2x1ZGVzKGtleSkpID8/IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBpc09wdGlvbmFsXG4gICAgICAgICAgICAgICAgICAgICAgICA/IG9wdGlvbmFsRmllbGQoa2V5LCBmaWVsZHNba2V5XSkuY29udmVydChmcm9tLCBjb250ZXh0KVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBmaWVsZChrZXksIGZpZWxkc1trZXldKS5jb252ZXJ0KGZyb20sIGNvbnRleHQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmlzU3VjY2VzcygpICYmIChyZXN1bHQudmFsdWUgIT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnRlZFtrZXldID0gcmVzdWx0LnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJlc3VsdC5pc0ZhaWx1cmUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JzLnB1c2gocmVzdWx0Lm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnN0cmljdCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIGlmICgodHlwZW9mIGZyb20gPT09ICdvYmplY3QnKSAmJiAoIUFycmF5LmlzQXJyYXkoZnJvbSkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIGZyb20pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmcm9tLmhhc093blByb3BlcnR5KGtleSkgJiYgKCFpc0tleU9mKGtleSwgZmllbGRzKSB8fCAoZmllbGRzW2tleV0gPT09IHVuZGVmaW5lZCkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JzLnB1c2goYCR7a2V5fTogdW5leHBlY3RlZCBwcm9wZXJ0eSBpbiBzb3VyY2Ugb2JqZWN0YCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9ycy5wdXNoKCdzb3VyY2UgaXMgbm90IGFuIG9iamVjdCcpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAoZXJyb3JzLmxlbmd0aCA9PT0gMCkgPyBzdWNjZWVkKGNvbnZlcnRlZCkgOiBmYWlsKGVycm9ycy5qb2luKCdcXG4nKSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuZmllbGRzID0gZmllbGRzO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShvcHQpKSB7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMgPSB7IG9wdGlvbmFsRmllbGRzOiBvcHQgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdCA/PyB7fTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBwYXJ0aWFsKG9wdGlvbnM6IE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD4pOiBPYmplY3RDb252ZXJ0ZXI8UGFydGlhbDxUPiwgVEM+O1xuICAgIHB1YmxpYyBwYXJ0aWFsKG9wdGlvbmFsPzogKGtleW9mIFQpW10pOiBPYmplY3RDb252ZXJ0ZXI8UGFydGlhbDxUPiwgVEM+O1xuICAgIHB1YmxpYyBwYXJ0aWFsKG9wdD86IE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD58KGtleW9mIFQpW10pOiBPYmplY3RDb252ZXJ0ZXI8UGFydGlhbDxUPiwgVEM+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RDb252ZXJ0ZXI8UGFydGlhbDxUPiwgVEM+KHRoaXMuZmllbGRzIGFzIEZpZWxkQ29udmVydGVyczxQYXJ0aWFsPFQ+LCBUQz4sIG9wdCBhcyBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFBhcnRpYWw8VD4+KS5fd2l0aCh0aGlzLl90cmFpdHMoKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFkZFBhcnRpYWwoYWRkT3B0aW9uYWxGaWVsZHM6IChrZXlvZiBUKVtdKTogT2JqZWN0Q29udmVydGVyPFBhcnRpYWw8VD4sIFRDPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcnRpYWwoWy4uLnRoaXMub3B0aW9ucy5vcHRpb25hbEZpZWxkcyA/PyBbXSwgLi4uYWRkT3B0aW9uYWxGaWVsZHNdKS5fd2l0aCh0aGlzLl90cmFpdHMoKSk7XG4gICAgfVxufVxuXG4vKipcbiAqIEhlbHBlciB0byBjb252ZXJ0IGFuIG9iamVjdCB3aXRob3V0IGNoYW5naW5nIHNoYXBlLiBUaGUgc291cmNlIHBhcmFtZXRlciBpcyBhbiBvYmplY3Qgd2l0aFxuICoga2V5IG5hbWVzIHRoYXQgY29ycmVzcG9uZCB0byB0aGUgdGFyZ2V0IG9iamVjdCBhbmQgdGhlIGFwcHJvcHJpYXRlIGNvcnJlc3BvbmRpbmcgY29udmVydGVyXG4gKiBhcyB0aGUgcHJvcGVydHkgdmFsdWUuIElmIGFsbCBvZiB0aGUgcmVxdWVzdGVkIGZpZWxkcyBleGlzdCBhbmQgY2FuIGJlIGNvbnZlcnRlZCwgcmV0dXJucyBhXG4gKiBuZXcgb2JqZWN0IHdpdGggdGhlIGNvbnZlcnRlZCB2YWx1ZXMgdW5kZXIgdGhlIG9yaWdpbmFsIGtleSBuYW1lcy4gIElmIGFueSBmaWVsZHMgZG8gbm90IGV4aXN0XG4gKiBvciBjYW5ub3QgYmUgY29udmVydGVkLCB0aGUgZW50aXJlIGNvbnZlcnNpb24gZmFpbHMuXG4gKlxuICogRmllbGRzIHRoYXQgc3VjY2VlZCBidXQgY29udmVydCB0byB1bmRlZmluZWQgYXJlIG9taXR0ZWQgZnJvbSB0aGUgcmVzdWx0IG9iamVjdCBidXQgZG8gbm90XG4gKiBmYWlsIHRoZSBjb252ZXJzaW9uLlxuICogQHBhcmFtIGZpZWxkcyBBbiBvYmplY3QgY29udGFpbmluZyBkZWZpbmluZyB0aGUgc2hhcGUgYW5kIGNvbnZlcnRlcnMgdG8gYmUgYXBwbGllZC5cbiAqIEBwYXJhbSBvcHQgQW4gQHNlZSBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+IGNvbnRhaW5pbmcgb3B0aW9ucyBmb3IgdGhlIG9iamVjdCBjb252ZXJ0ZXIsIG9yXG4gKiBhbiBhcnJheSBvZiAoa2V5b2YgVCkgY29udGFpbmluZyBvcHRpb25hbCBrZXlzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gb2JqZWN0PFQ+KGZpZWxkczogRmllbGRDb252ZXJ0ZXJzPFQ+LCBvcHQ/OiAoa2V5b2YgVClbXXxPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+KTogT2JqZWN0Q29udmVydGVyPFQ+IHtcbiAgICByZXR1cm4gbmV3IE9iamVjdENvbnZlcnRlcihmaWVsZHMsIG9wdCBhcyBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+KTtcbn1cblxuLyoqXG4gKiBIZWxwZXIgdG8gY29udmVydCBhbiBvYmplY3Qgd2l0aG91dCBjaGFuZ2luZyBzaGFwZS4gVGhlIHNvdXJjZSBwYXJhbWV0ZXIgaXMgYW4gb2JqZWN0IHdpdGhcbiAqIGtleSBuYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdGhlIHRhcmdldCBvYmplY3QgYW5kIHRoZSBhcHByb3ByaWF0ZSBjb3JyZXNwb25kaW5nIGNvbnZlcnRlclxuICogYXMgdGhlIHByb3BlcnR5IHZhbHVlLiBJZiBhbGwgb2YgdGhlIHJlcXVlc3RlZCBmaWVsZHMgZXhpc3QgYW5kIGNhbiBiZSBjb252ZXJ0ZWQsIHJldHVybnMgYVxuICogbmV3IG9iamVjdCB3aXRoIHRoZSBjb252ZXJ0ZWQgdmFsdWVzIHVuZGVyIHRoZSBvcmlnaW5hbCBrZXkgbmFtZXMuICBJZiBhbnkgZmllbGRzIGRvIG5vdCBleGlzdFxuICogb3IgY2Fubm90IGJlIGNvbnZlcnRlZCwgdGhlIGVudGlyZSBjb252ZXJzaW9uIGZhaWxzLlxuICpcbiAqIEZpZWxkcyB0aGF0IHN1Y2NlZWQgYnV0IGNvbnZlcnQgdG8gdW5kZWZpbmVkIGFyZSBvbWl0dGVkIGZyb20gdGhlIHJlc3VsdCBvYmplY3QgYnV0IGRvIG5vdFxuICogZmFpbCB0aGUgY29udmVyc2lvbi5cbiAqXG4gKiBUaGUgY29udmVyc2lvbiBmYWlscyBpZiBhbnkgdW5leHBlY3RlZCBmaWVsZHMgYXJlIGVuY291bnRlcmVkLlxuICpcbiAqIEBwYXJhbSBmaWVsZHMgQW4gb2JqZWN0IGNvbnRhaW5pbmcgZGVmaW5pbmcgdGhlIHNoYXBlIGFuZCBjb252ZXJ0ZXJzIHRvIGJlIGFwcGxpZWQuXG4gKiBAcGFyYW0gb3B0IC0gQW4gQHNlZSBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+IGNvbnRhaW5pbmcgb3B0aW9ucyBmb3IgdGhlIG9iamVjdCBjb252ZXJ0ZXIsIG9yXG4gKiBhbiBhcnJheSBvZiAoa2V5b2YgVCkgY29udGFpbmluZyBvcHRpb25hbCBrZXlzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RyaWN0T2JqZWN0PFQ+KFxuICAgIGZpZWxkczogRmllbGRDb252ZXJ0ZXJzPFQ+LFxuICAgIG9wdD86IChrZXlvZiBUKVtdfE9taXQ8T2JqZWN0Q29udmVydGVyT3B0aW9uczxUPiwgJ3N0cmljdCc+LFxuKTogT2JqZWN0Q29udmVydGVyPFQ+IHtcbiAgICBjb25zdCBvcHRpb25zOiBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+ID0gKG9wdCAmJiBBcnJheS5pc0FycmF5KG9wdCkpXG4gICAgICAgID8geyBzdHJpY3Q6IHRydWUsIG9wdGlvbmFsRmllbGRzOiBvcHQgfVxuICAgICAgICA6IHsgLi4uKG9wdCA/PyB7fSksIHN0cmljdDogdHJ1ZSB9O1xuICAgIHJldHVybiBuZXcgT2JqZWN0Q29udmVydGVyKGZpZWxkcywgb3B0aW9ucyk7XG59XG5cbmV4cG9ydCB0eXBlIERpc2NyaW1pbmF0ZWRPYmplY3RDb252ZXJ0ZXJzPFQsIFREIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nLCBUQz11bmtub3duPiA9IFJlY29yZDxURCwgQ29udmVydGVyPFQsIFRDPj47XG5cbi8qKlxuICogSGVscGVyIHRvIGNvbnZlcnQgYSBkaXNjcmltaW5hdGVkIHByb3BlcnR5IHdpdGhvdXQgY2hhbmdpbmcgc2hhcGUuICBUYWtlcyB0aGUgbmFtZSBvZiB0aGVcbiAqIGRpc2NyaW1pbmF0b3IgcHJvcGVydHkgYW5kIGEgc3RyaW5nLWtleWVkIHJlY29yZCBvZiBvYmplY3QgY29udmVydGVycywgYW5kIGludm9rZXMgdGhlXG4gKiBjb252ZXJ0ZXIgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgdmFsdWUgb2YgdGhlIGRpc2NyaW1pbmF0b3IgcHJvcGVydHkgaW4gdGhlIHNvdXJjZSBvYmplY3QuXG4gKiBGYWlscyBpZiB0aGUgc291cmNlIGlzIG5vdCBhbiBvYmplY3Qgb3IgaWYgdGhlIGRpc2NyaW1pbmF0b3IgcHJvcGVydHkgaXMgbWlzc2luZyBvciBoYXNcbiAqIGEgdmFsdWUgbm90IHByZXNlbnQgaW4gdGhlIGNvbnZlcnRlcnMuXG4gKiBAcGFyYW0gZGlzY3JpbWluYXRvclByb3AgTmFtZSBvZiB0aGUgcHJvcGVydHkgdXNlZCB0byBkaXNjcmltaW5hdGUgdHlwZXNcbiAqIEBwYXJhbSBjb252ZXJ0ZXJzIFN0cmluZy1rZXllZCByZWNvcmQgb2YgY29udmVydGVycyB0byBpbnZva2UsIHdoZXJlIGtleSBjb3JyZXNwb25kcyB0byBhIHZhbHVlIG9mIHRoZVxuICogZGlzY3JpbWluYXRvciBwcm9wZXJ0eS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpc2NyaW1pbmF0ZWRPYmplY3Q8VCwgVEQgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmcsIFRDPXVua25vd24+KGRpc2NyaW1pbmF0b3JQcm9wOiBzdHJpbmcsIGNvbnZlcnRlcnM6IERpc2NyaW1pbmF0ZWRPYmplY3RDb252ZXJ0ZXJzPFQsIFREPik6IENvbnZlcnRlcjxULCBUQz4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93bikgPT4ge1xuICAgICAgICBpZiAoKHR5cGVvZiBmcm9tICE9PSAnb2JqZWN0JykgfHwgQXJyYXkuaXNBcnJheShmcm9tKSB8fCBmcm9tID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFpbChgTm90IGEgZGlzY3JpbWluYXRlZCBvYmplY3Q6IFwiJHtKU09OLnN0cmluZ2lmeShmcm9tKX1cImApO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoIWlzS2V5T2YoZGlzY3JpbWluYXRvclByb3AsIGZyb20pKSB8fCAoIWZyb21bZGlzY3JpbWluYXRvclByb3BdKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYERpc2NyaW1pbmF0b3IgcHJvcGVydHkgJHtkaXNjcmltaW5hdG9yUHJvcH0gbm90IHByZXNlbnQgaW4gXCIke0pTT04uc3RyaW5naWZ5KGZyb20pfVwiYCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkaXNjcmltaW5hdG9yVmFsdWUgPSBmcm9tW2Rpc2NyaW1pbmF0b3JQcm9wXSBhcyBURDtcbiAgICAgICAgY29uc3QgY29udmVydGVyID0gY29udmVydGVyc1tkaXNjcmltaW5hdG9yVmFsdWVdO1xuICAgICAgICBpZiAoY29udmVydGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKGBObyBjb252ZXJ0ZXIgZm9yIGRpc2NyaW1pbmF0b3IgJHtkaXNjcmltaW5hdG9yUHJvcH09XCIke2Rpc2NyaW1pbmF0b3JWYWx1ZX1cImApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb252ZXJ0ZXIuY29udmVydChmcm9tKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBIZWxwZXIgdG8gY29udmVydCBhbiBvYmplY3QgdG8gYSBuZXcgb2JqZWN0IHdpdGggYSBkaWZmZXJlbnQgc2hhcGUuIFRoZSBzb3VyY2UgcGFyYW1ldGVyIGlzXG4gKiBhbiBvYmplY3Qgd2l0aCBrZXkgbmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHRoZSB0YXJnZXQgb2JqZWN0LCBhbmQgYW4gYXBwcm9yaWF0ZSBfZmllbGRfXG4gKiBjb252ZXJ0ZXIgdGhhdCB3aWxsIGV4dHJhY3QgYW5kIGNvbnZlcnQgYSBzaW5nbGUgZmllbGQgZnJvbSB0aGUgc291cmNlIG9iamVjdC5cbiAqXG4gKiBJZiBhbGwgb2YgdGhlIGV4dHJhY3RlZCBmaWVsZHMgZXhpc3QgYW5kIGNhbiBiZSBjb252ZXJ0ZWQsIHJldHVybnMgYSBuZXcgb2JqZWN0IHdpdGggdGhlXG4gKiBjb252ZXJ0ZWQgdmFsdWVzIHVuZGVyIHRoZSBvcmlnaW5hbCBrZXkgbmFtZXMuICBJZiBhbnkgZmllbGRzIHRvIGJlIGV4dHJhY3RlZCBkbyBub3QgZXhpc3RcbiAqIG9yIGNhbm5vdCBiZSBjb252ZXJ0ZWQsIHRoZSBlbnRpcmUgY29udmVyc2lvbiBmYWlscy5cbiAqXG4gKiBGaWVsZHMgdGhhdCBzdWNjZWVkIGJ1dCBjb252ZXJ0IHRvIHVuZGVmaW5lZCBhcmUgb21pdHRlZCBmcm9tIHRoZSByZXN1bHQgb2JqZWN0IGJ1dCBkbyBub3RcbiAqIGZhaWwgdGhlIGNvbnZlcnNpb24uXG4gKlxuICogQHBhcmFtIGZpZWxkcyBBbiBvYmplY3QgZGVmaW5pbmcgdGhlIHNoYXBlIG9mIHRoZSB0YXJnZXQgb2JqZWN0IGFuZCB0aGUgZmllbGQgY29udmVydGVyc1xuICogdG8gYmUgdXNlZCB0byBjb25zdHJ1Y3QgaXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm08VCwgVEM9dW5rbm93bj4oZmllbGRzOiBGaWVsZENvbnZlcnRlcnM8VCwgVEM+KTogQ29udmVydGVyPFQsIFRDPiB7XG4gICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyKChmcm9tOiB1bmtub3duLCBfc2VsZiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgIC8vIGVzbGludCBidWcgdGhpbmtzIGtleSBpcyB1c2VkIGJlZm9yZSBkZWZpbmVkXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11c2UtYmVmb3JlLWRlZmluZVxuICAgICAgICBjb25zdCBjb252ZXJ0ZWQgPSB7fSBhcyB7IFsga2V5IGluIGtleW9mIFRdOiBUW2tleV0gfTtcbiAgICAgICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGZpZWxkcykge1xuICAgICAgICAgICAgaWYgKGZpZWxkc1trZXldKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gZmllbGRzW2tleV0uY29udmVydChmcm9tLCBjb250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmlzU3VjY2VzcygpICYmIChyZXN1bHQudmFsdWUgIT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udmVydGVkW2tleV0gPSByZXN1bHQudmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJlc3VsdC5pc0ZhaWx1cmUoKSkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChyZXN1bHQubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChlcnJvcnMubGVuZ3RoID09PSAwKSA/IHN1Y2NlZWQoY29udmVydGVkKSA6IGZhaWwoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBIGhlbHBlciB3cmFwcGVyIHRvIGNvbnZlcnQgYSByYW5nZSBvZiBzb21lIG90aGVyIGNvbXBhcmFibGUgdHlwZVxuICogQHBhcmFtIGNvbnZlcnRlciBDb252ZXJ0ZXIgdXNlZCB0byBjb252ZXJ0IG1pbiBhbmQgbWF4IGV4dGVudCBvZiB0aGUgcmFpZFxuICogQHBhcmFtIGNvbnN0cnVjdG9yIE9wdGlvbmFsIHN0YXRpYyBjb25zdHJ1Y3RvciB0byBpbnN0YW50aWF0ZSB0aGUgb2JqZWN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByYW5nZVR5cGVPZjxULCBSVCBleHRlbmRzIFJhbmdlT2Y8VD4sIFRDPXVua25vd24+KGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPiwgY29uc3RydWN0b3I6IChpbml0OiBSYW5nZU9mUHJvcGVydGllczxUPikgPT4gUmVzdWx0PFJUPik6IENvbnZlcnRlcjxSVCwgVEM+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmLCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gb2JqZWN0KHtcbiAgICAgICAgICAgIG1pbjogY29udmVydGVyLFxuICAgICAgICAgICAgbWF4OiBjb252ZXJ0ZXIsXG4gICAgICAgIH0sIFsnbWluJywgJ21heCddKS5jb252ZXJ0KGZyb20sIGNvbnRleHQpO1xuICAgICAgICBpZiAocmVzdWx0LmlzU3VjY2VzcygpKSB7XG4gICAgICAgICAgICByZXR1cm4gY29uc3RydWN0b3IoeyBtaW46IHJlc3VsdC52YWx1ZS5taW4sIG1heDogcmVzdWx0LnZhbHVlLm1heCB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFpbChyZXN1bHQubWVzc2FnZSk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByYW5nZU9mPFQsIFRDPXVua25vd24+KGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPik6IENvbnZlcnRlcjxSYW5nZU9mPFQ+LCBUQz4ge1xuICAgIHJldHVybiByYW5nZVR5cGVPZjxULCBSYW5nZU9mPFQ+LCBUQz4oY29udmVydGVyLCBSYW5nZU9mLmNyZWF0ZVJhbmdlKTtcbn1cbiJdfQ==
|
|
805
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVydGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb252ZXJ0ZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUNILDJDQUF3RTtBQUN4RSx1Q0FBdUQ7QUFDdkQscUNBQWdFO0FBRWhFLGlDQUFpQztBQUNqQyxtREFBZ0Q7QUFDaEQsd0RBQWdDO0FBQ2hDLG1DQUFrQztBQWlCbEM7Ozs7R0FJRztBQUNILE1BQWEsZUFBeUQsU0FBUSx5QkFBb0I7SUFDOUY7Ozs7O09BS0c7SUFDSCxZQUNJLGNBQW1CLEVBQ25CLE1BQXdCLEVBQ3hCLFlBQWdGLGVBQWUsQ0FBQyxRQUFRO1FBRXhHLEtBQUssQ0FBQyxTQUFTLEVBQUUsY0FBYyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRDs7T0FFRztJQUNPLE1BQU0sQ0FBQyxRQUFRLENBQW1CLElBQWE7UUFDckQsT0FBTyxPQUFPLElBQUksS0FBSyxRQUFRO1lBQzNCLENBQUMsQ0FBQyxJQUFBLGdCQUFPLEVBQUMsSUFBUyxDQUFDO1lBQ3BCLENBQUMsQ0FBQyxJQUFBLGFBQUksRUFBQyxpQkFBaUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVEOztPQUVHO0lBQ08sTUFBTSxDQUFDLEtBQUssQ0FDbEIsT0FBK0IsRUFDL0IsU0FBaUMsRUFDakMsTUFBd0I7UUFFeEIsT0FBTyxJQUFJLGVBQWUsQ0FBUSxTQUFTLEVBQUUsU0FBUyxFQUFFLENBQUMsSUFBYSxFQUFFLEVBQUU7WUFDdEUsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN0RCxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3RD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QU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7U0FDeEU7UUFDRCxPQUFPLElBQUEsYUFBSSxFQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNoQyxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFYRCxrQ0FXQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBZ0IsT0FBTyxDQUFnQixTQUEyQjtJQUM5RCxPQUFPLFdBQVcsQ0FBb0IsU0FBUyxFQUFFLGlCQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUUsQ0FBQztBQUZELDBCQUVDIiwic291cmNlc0NvbnRlbnQiOlsiXG4vKlxuICogQ29weXJpZ2h0IChjKSAyMDIwIEVyaWsgRm9ydHVuZVxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbiAqIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbiAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGxcbiAqIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4gKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRVxuICogU09GVFdBUkUuXG4gKi9cbmltcG9ydCB7IEJhc2VDb252ZXJ0ZXIsIENvbnZlcnRlciwgQ29udmVydGVyVHJhaXRzIH0gZnJvbSAnLi9jb252ZXJ0ZXInO1xuaW1wb3J0IHsgUmFuZ2VPZiwgUmFuZ2VPZlByb3BlcnRpZXMgfSBmcm9tICcuL3JhbmdlT2YnO1xuaW1wb3J0IHsgUmVzdWx0LCBjYXB0dXJlUmVzdWx0LCBmYWlsLCBzdWNjZWVkIH0gZnJvbSAnLi9yZXN1bHQnO1xuXG5pbXBvcnQgeyBEYXRlVGltZSB9IGZyb20gJ2x1eG9uJztcbmltcG9ydCB7IEV4dGVuZGVkQXJyYXkgfSBmcm9tICcuL2V4dGVuZGVkQXJyYXknO1xuaW1wb3J0IE11c3RhY2hlIGZyb20gJ211c3RhY2hlJztcbmltcG9ydCB7IGlzS2V5T2YgfSBmcm9tICcuL3V0aWxzJztcblxudHlwZSBPbkVycm9yID0gJ2ZhaWxPbkVycm9yJyB8ICdpZ25vcmVFcnJvcnMnO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBDb252ZXJ0ZXJzLlN0cmluZ0NvbnZlcnRlciB8IFN0cmluZ0NvbnZlcnRlcn1cbiAqIG1hdGNoaW5nIG1ldGhvZFxuICogQHB1YmxpY1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0cmluZ01hdGNoT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICogQW4gb3B0aW9uYWwgbWVzc2FnZSB0byBiZSBkaXNwbGF5ZWQgaWYgYSBub24tbWF0Y2hpbmcgc3RyaW5nXG4gICAgICogaXMgZW5jb3VudGVyZWQuXG4gICAgICovXG4gICAgbWVzc2FnZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nQ29udmVydGVyIHwgU3RyaW5nQ29udmVydGVyfSBjbGFzcyBleHRlbmRzIHtAbGluayBCYXNlQ29udmVydGVyfVxuICogdG8gcHJvdmlkZSBzdHJpbmctc3BlY2lmaWMgaGVscGVyIG1ldGhvZHMuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJpbmdDb252ZXJ0ZXI8VCBleHRlbmRzIHN0cmluZyA9IHN0cmluZywgVEMgPSB1bmtub3duPiBleHRlbmRzIEJhc2VDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3QgYSBuZXcge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nQ29udmVydGVyIHwgU3RyaW5nQ29udmVydGVyfS5cbiAgICAgKiBAcGFyYW0gZGVmYXVsdENvbnRleHQgLSBPcHRpb25hbCBjb250ZXh0IHVzZWQgYnkgdGhlIGNvbnZlcnNpb24uXG4gICAgICogQHBhcmFtIHRyYWl0cyAtIE9wdGlvbmFsIHRyYWl0cyB0byBiZSBhcHBsaWVkIHRvIHRoZSBjb252ZXJzaW9uLlxuICAgICAqIEBwYXJhbSBjb252ZXJ0ZXIgLSBPcHRpb25hbCBjb252ZXJzaW9uIGZ1bmN0aW9uIHRvIGJlIHVzZWQgZm9yIHRoZSBjb252ZXJzaW9uLlxuICAgICAqL1xuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICAgICAgZGVmYXVsdENvbnRleHQ/OiBUQyxcbiAgICAgICAgdHJhaXRzPzogQ29udmVydGVyVHJhaXRzLFxuICAgICAgICBjb252ZXJ0ZXI6IChmcm9tOiB1bmtub3duLCBzZWxmOiBDb252ZXJ0ZXI8VCwgVEM+LCBjb250ZXh0PzogVEMpID0+IFJlc3VsdDxUPiA9IFN0cmluZ0NvbnZlcnRlci5fY29udmVydCxcbiAgICApIHtcbiAgICAgICAgc3VwZXIoY29udmVydGVyLCBkZWZhdWx0Q29udGV4dCwgdHJhaXRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgc3RhdGljIF9jb252ZXJ0PFQgZXh0ZW5kcyBzdHJpbmc+KGZyb206IHVua25vd24pOiBSZXN1bHQ8VD4ge1xuICAgICAgICByZXR1cm4gdHlwZW9mIGZyb20gPT09ICdzdHJpbmcnXG4gICAgICAgICAgICA/IHN1Y2NlZWQoZnJvbSBhcyBUKVxuICAgICAgICAgICAgOiBmYWlsKGBOb3QgYSBzdHJpbmc6ICR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9YCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHN0YXRpYyBfd3JhcDxUIGV4dGVuZHMgc3RyaW5nLCBUQz4oXG4gICAgICAgIHdyYXBwZWQ6IFN0cmluZ0NvbnZlcnRlcjxULCBUQz4sXG4gICAgICAgIGNvbnZlcnRlcjogKGZyb206IFQpID0+IFJlc3VsdDxUPixcbiAgICAgICAgdHJhaXRzPzogQ29udmVydGVyVHJhaXRzXG4gICAgKTogU3RyaW5nQ29udmVydGVyPFQsIFRDPiB7XG4gICAgICAgIHJldHVybiBuZXcgU3RyaW5nQ29udmVydGVyPFQsIFRDPih1bmRlZmluZWQsIHVuZGVmaW5lZCwgKGZyb206IHVua25vd24pID0+IHtcbiAgICAgICAgICAgIHJldHVybiB3cmFwcGVkLmNvbnZlcnQoZnJvbSkub25TdWNjZXNzKGNvbnZlcnRlcik7XG4gICAgICAgIH0pLl93aXRoKHdyYXBwZWQuX3RyYWl0cyh0cmFpdHMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nQ29udmVydGVyIHwgU3RyaW5nQ29udmVydGVyfSB3aGljaCBjb25zdHJhaW5zIHRoZSByZXN1bHQgdG8gbWF0Y2hcbiAgICAgKiBhIHN1cHBsaWVkIHN0cmluZy5cbiAgICAgKiBAcGFyYW0gbWF0Y2ggLSBUaGUgc3RyaW5nIHRvIGJlIG1hdGNoZWRcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIHtAbGluayBDb252ZXJ0ZXJzLlN0cmluZ01hdGNoT3B0aW9uc30gZm9yIHRoaXMgY29udmVyc2lvbi5cbiAgICAgKiBAcmV0dXJucyB7QGxpbmsgU3VjY2Vzc30gd2l0aCBhIG1hdGNoaW5nIHN0cmluZyBvciB7QGxpbmsgRmFpbHVyZX0gd2l0aCBhbiBpbmZvcm1hdGl2ZVxuICAgICAqIGVycm9yIGlmIHRoZSBzdHJpbmcgZG9lcyBub3QgbWF0Y2guXG4gICAgICoge0BsYWJlbCBzdHJpbmd9XG4gICAgICovXG4gICAgcHVibGljIG1hdGNoaW5nKG1hdGNoOiBzdHJpbmcsIG9wdGlvbnM/OiBQYXJ0aWFsPFN0cmluZ01hdGNoT3B0aW9ucz4pOiBTdHJpbmdDb252ZXJ0ZXI8VCwgVEM+O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHtAbGluayBDb252ZXJ0ZXJzLlN0cmluZ0NvbnZlcnRlciB8IFN0cmluZ0NvbnZlcnRlcn0gd2hpY2ggY29uc3RyYWlucyB0aGUgcmVzdWx0IHRvIG1hdGNoXG4gICAgICogb25lIG9mIGEgc3VwcGxpZWQgYXJyYXkgb2Ygc3RyaW5ncy5cbiAgICAgKiBAcGFyYW0gbWF0Y2ggLSBUaGUgYXJyYXkgb2YgYWxsb3dlZCBzdHJpbmdzLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nTWF0Y2hPcHRpb25zfSBmb3IgdGhpcyBjb252ZXJzaW9uLlxuICAgICAqIEByZXR1cm5zIHtAbGluayBTdWNjZXNzfSB3aXRoIGEgbWF0Y2hpbmcgc3RyaW5nIG9yIHtAbGluayBGYWlsdXJlfSB3aXRoIGFuIGluZm9ybWF0aXZlXG4gICAgICogZXJyb3IgaWYgdGhlIHN0cmluZyBkb2VzIG5vdCBtYXRjaC5cbiAgICAgKiB7QGxhYmVsIGFycmF5fVxuICAgICAqL1xuICAgIHB1YmxpYyBtYXRjaGluZyhtYXRjaDogc3RyaW5nW10sIG9wdGlvbnM/OiBQYXJ0aWFsPFN0cmluZ01hdGNoT3B0aW9ucz4pOiBTdHJpbmdDb252ZXJ0ZXI8VCwgVEM+O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHtAbGluayBDb252ZXJ0ZXJzLlN0cmluZ0NvbnZlcnRlciB8IFN0cmluZ0NvbnZlcnRlcn0gd2hpY2ggY29uc3RyYWlucyB0aGUgcmVzdWx0IHRvIG1hdGNoXG4gICAgICogb25lIG9mIGEgc3VwcGxpZWQgYFNldGAgb2Ygc3RyaW5ncy5cbiAgICAgKiBAcGFyYW0gbWF0Y2ggLSBUaGUgYFNldGAgb2YgYWxsb3dlZCBzdHJpbmdzLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nTWF0Y2hPcHRpb25zfSBmb3IgdGhpcyBjb252ZXJzaW9uLlxuICAgICAqIEByZXR1cm5zIHtAbGluayBTdWNjZXNzfSB3aXRoIGEgbWF0Y2hpbmcgc3RyaW5nIG9yIHtAbGluayBGYWlsdXJlfSB3aXRoIGFuIGluZm9ybWF0aXZlXG4gICAgICogZXJyb3IgaWYgdGhlIHN0cmluZyBkb2VzIG5vdCBtYXRjaC5cbiAgICAgKiB7QGxhYmVsIHNldH1cbiAgICAgKi9cbiAgICBwdWJsaWMgbWF0Y2hpbmcobWF0Y2g6IFNldDxUPiwgb3B0aW9ucz86IFBhcnRpYWw8U3RyaW5nTWF0Y2hPcHRpb25zPik6IFN0cmluZ0NvbnZlcnRlcjxULCBUQz47XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nQ29udmVydGVyIHwgU3RyaW5nQ29udmVydGVyfSB3aGljaCBjb25zdHJhaW5zIHRoZSByZXN1bHQgdG8gbWF0Y2hcbiAgICAgKiBhIHN1cHBsaWVkIHJlZ3VsYXIgZXhwcmVzc2lvbi5cbiAgICAgKiBAcGFyYW0gbWF0Y2ggLSBUaGUgcmVndWxhciBleHByZXNzaW9uIHRvIGJlIHVzZWQgYXMgYSBjb25zdHJhaW50LlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nTWF0Y2hPcHRpb25zfSBmb3IgdGhpcyBjb252ZXJzaW9uXG4gICAgICogQHJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggYSBtYXRjaGluZyBzdHJpbmcgb3Ige0BsaW5rIEZhaWx1cmV9IHdpdGggYW4gaW5mb3JtYXRpdmVcbiAgICAgKiBlcnJvciBpZiB0aGUgc3RyaW5nIGRvZXMgbm90IG1hdGNoLlxuICAgICAqIHtAbGFiZWwgcmVnZXhwfVxuICAgICAqL1xuICAgIHB1YmxpYyBtYXRjaGluZyhtYXRjaDogUmVnRXhwLCBvcHRpb25zPzogUGFydGlhbDxTdHJpbmdNYXRjaE9wdGlvbnM+KTogU3RyaW5nQ29udmVydGVyPFQsIFRDPjtcbiAgICAvKipcbiAgICAgKiBDb25jcmV0ZSBpbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgQ29udmVydGVycy5TdHJpbmdDb252ZXJ0ZXIuKG1hdGNoaW5nI3N0cmluZykgfCBTdHJpbmdDb252ZXJ0ZXIubWF0Y2hpbmcoc3RyaW5nKX0sXG4gICAgICoge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nQ29udmVydGVyLihtYXRjaGluZyNhcnJheSkgfCBTdHJpbmdDb252ZXJ0ZXIubWF0Y2hpbmcoc3RyaW5nW10pfSxcbiAgICAgKiB7QGxpbmsgQ29udmVydGVycy5TdHJpbmdDb252ZXJ0ZXIuKG1hdGNoaW5nI3NldCkgfCBTdHJpbmdDb252ZXJ0ZXIubWF0Y2hpbmcoU2V0PHN0cmluZz4pfSwgYW5kXG4gICAgICoge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nQ29udmVydGVyLihtYXRjaGluZyNyZWdleHApIHwgU3RyaW5nQ29udmVydGVyLm1hdGNoaW5nKFJlZ0V4cCl9LlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBtYXRjaGluZyhtYXRjaDogc3RyaW5nIHwgc3RyaW5nW10gfCBTZXQ8VD4gfCBSZWdFeHAsIG9wdGlvbnM/OiBQYXJ0aWFsPFN0cmluZ01hdGNoT3B0aW9ucz4pOiBTdHJpbmdDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IG9wdGlvbnM/Lm1lc3NhZ2U7XG4gICAgICAgIGlmICh0eXBlb2YgbWF0Y2ggPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gU3RyaW5nQ29udmVydGVyLl93cmFwPFQsIFRDPih0aGlzLCAoZnJvbTogVCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiAobWF0Y2ggPT09IGZyb20pXG4gICAgICAgICAgICAgICAgICAgID8gc3VjY2VlZChmcm9tIGFzIFQpXG4gICAgICAgICAgICAgICAgICAgIDogZmFpbChtZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgICAgICA/IGBcIiR7ZnJvbX1cIjogJHttZXNzYWdlfWBcbiAgICAgICAgICAgICAgICAgICAgICAgIDogYFwiJHtmcm9tfVwiOiBkb2VzIG5vdCBtYXRjaCBcIiR7bWF0Y2h9XCJgKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG1hdGNoIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXR1cm4gU3RyaW5nQ29udmVydGVyLl93cmFwPFQsIFRDPih0aGlzLCAoZnJvbTogVCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiAobWF0Y2gudGVzdChmcm9tKSlcbiAgICAgICAgICAgICAgICAgICAgPyBzdWNjZWVkKGZyb20gYXMgVClcbiAgICAgICAgICAgICAgICAgICAgOiBmYWlsKG1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgID8gYFwiJHtmcm9tfVwiOiAke21lc3NhZ2V9YFxuICAgICAgICAgICAgICAgICAgICAgICAgOiBgXCIke2Zyb219XCI6IGRvZXMgbm90IG1hdGNoIFwiJHttYXRjaH1cImApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobWF0Y2ggaW5zdGFuY2VvZiBTZXQpIHtcbiAgICAgICAgICAgIHJldHVybiBTdHJpbmdDb252ZXJ0ZXIuX3dyYXA8VCwgVEM+KHRoaXMsIChmcm9tOiBUKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChtYXRjaC5oYXMoZnJvbSkpXG4gICAgICAgICAgICAgICAgICAgID8gc3VjY2VlZChmcm9tIGFzIFQpXG4gICAgICAgICAgICAgICAgICAgIDogZmFpbChtZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgICAgICA/IGBcIiR7ZnJvbX1cIjogJHttZXNzYWdlfWBcbiAgICAgICAgICAgICAgICAgICAgICAgIDogYFwiJHtmcm9tfVwiOiBub3QgZm91bmQgaW4gc2V0YCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBTdHJpbmdDb252ZXJ0ZXIuX3dyYXA8VCwgVEM+KHRoaXMsIChmcm9tOiBUKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChtYXRjaC5pbmNsdWRlcyhmcm9tKSlcbiAgICAgICAgICAgICAgICAgICAgPyBzdWNjZWVkKGZyb20gYXMgVClcbiAgICAgICAgICAgICAgICAgICAgOiBmYWlsKG1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgID8gYFwiJHtmcm9tfVwiOiAke21lc3NhZ2V9YFxuICAgICAgICAgICAgICAgICAgICAgICAgOiBgXCIke2Zyb219XCI6IG5vdCBmb3VuZCBpbiBbJHttYXRjaC5qb2luKCcsJyl9XWApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogQSBjb252ZXJ0ZXIgdG8gY29udmVydCB1bmtub3duIHRvIHN0cmluZy4gVmFsdWVzIG9mIHR5cGVcbiAqIHN0cmluZyBzdWNjZWVkLiAgQW55dGhpbmcgZWxzZSBmYWlscy5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IHN0cmluZyA9IG5ldyBTdHJpbmdDb252ZXJ0ZXIoKTtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcnMuU3RyaW5nQ29udmVydGVyIHwgU3RyaW5nQ29udmVydGVyfSB3aGljaCBjb252ZXJ0c1xuICogYHVua25vd25gIHRvIGBzdHJpbmdgLCBhcHBseWluZyB0ZW1wbGF0ZSBjb252ZXJzaW9ucyBzdXBwbGllZCBhdCBjb25zdHJ1Y3Rpb24gdGltZSBvciBhdFxuICogcnVudGltZSBhcyBjb250ZXh0LlxuICogQHJlbWFya3NcbiAqIFRlbXBsYXRlIGNvbnZlcnNpb25zIGFyZSBhcHBsaWVkIHVzaW5nIGBtdXN0YWNoZWAgc3ludGF4LlxuICogQHBhcmFtIGRlZmF1bHRDb250ZXh0IC0gT3B0aW9uYWwgZGVmYXVsdCBjb250ZXh0IHRvIHVzZSBmb3IgdGVtcGxhdGUgdmFsdWVzLlxuICogQHJldHVybnMgQSBuZXcge0BsaW5rIENvbnZlcnRlcn0gcmV0dXJuaW5nIGBzdHJpbmdgLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gdGVtcGxhdGVTdHJpbmcoZGVmYXVsdENvbnRleHQ/OiB1bmtub3duKTogU3RyaW5nQ29udmVydGVyPHN0cmluZywgdW5rbm93bj4ge1xuICAgIHJldHVybiBuZXcgU3RyaW5nQ29udmVydGVyPHN0cmluZywgdW5rbm93bj4oZGVmYXVsdENvbnRleHQsIHVuZGVmaW5lZCwgKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8c3RyaW5nLCB1bmtub3duPiwgY29udGV4dD86IHVua25vd24pID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBmcm9tICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYE5vdCBhIHN0cmluZzogJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FwdHVyZVJlc3VsdCgoKSA9PiBNdXN0YWNoZS5yZW5kZXIoZnJvbSwgY29udGV4dCkpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBjb252ZXJ0cyBgdW5rbm93bmAgdG8gb25lIG9mIGEgc2V0IG9mIHN1cHBsaWVkXG4gKiBlbnVtZXJhdGVkIHZhbHVlcy4gQW55dGhpbmcgZWxzZSBmYWlscy5cbiAqXG4gKiBAcmVtYXJrc1xuICogQWxsb3dlZCBlbnVtZXJhdGVkIHZhbHVlcyBjYW4gYWxzbyBiZSBzdXBwbGllZCBhcyBjb250ZXh0IGF0IGNvbnZlcnNpb24gdGltZS5cbiAqIEBwYXJhbSB2YWx1ZXMgLSBBcnJheSBvZiBhbGxvd2VkIHZhbHVlcy5cbiAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBDb252ZXJ0ZXJ9IHJldHVybmluZyBgPFQ+YC5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVudW1lcmF0ZWRWYWx1ZTxUPih2YWx1ZXM6IFRbXSk6IENvbnZlcnRlcjxULCBUW10+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VCwgVFtdPiwgY29udGV4dD86IFRbXSk6IFJlc3VsdDxUPiA9PiB7XG4gICAgICAgIGNvbnN0IHYgPSBjb250ZXh0ID8/IHZhbHVlcztcbiAgICAgICAgY29uc3QgaW5kZXggPSB2LmluZGV4T2YoZnJvbSBhcyBUKTtcbiAgICAgICAgcmV0dXJuIChpbmRleCA+PSAwID8gc3VjY2VlZCh2W2luZGV4XSkgOiBmYWlsKGBJbnZhbGlkIGVudW1lcmF0ZWQgdmFsdWUgJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKSk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIGB1bmtub3duYCB0byBvbmUgb2YgYSBzZXQgb2Ygc3VwcGxpZWQgZW51bWVyYXRlZFxuICogdmFsdWVzLCBtYXBwaW5nIGFueSBvZiBtdWx0aXBsZSBzdXBwbGllZCB2YWx1ZXMgdG8gdGhlIGVudW1lcmF0aW9uLlxuICogQHJlbWFya3NcbiAqIEVuYWJsZXMgbWFwcGluZyBvZiBtdWx0aXBsZSBpbnB1dCB2YWx1ZXMgdG8gYSBjb25zaXN0ZW50IGludGVybmFsIHJlcHJlc2VudGF0aW9uIChzbyBlLmcuIGAneSdgLCBgJ3llcydgLFxuICogYCd0cnVlJ2AsIGAxYCBhbmQgYHRydWVgIGNhbiBhbGwgbWFwIHRvIGJvb2xlYW4gYHRydWVgKVxuICogQHBhcmFtIG1hcCAtIEFuIGFycmF5IG9mIHR1cGxlcyBkZXNjcmliaW5nIHRoZSBtYXBwaW5nLiBUaGUgZmlyc3QgZWxlbWVudCBvZiBlYWNoIHR1cGxlIGlzIHRoZSByZXN1bHRcbiAqIHZhbHVlLCB0aGUgc2Vjb25kIGlzIHRoZSBzZXQgb2YgdmFsdWVzIHRoYXQgbWFwIHRvIHRoZSByZXN1bHQuICBUdXBsZXMgYXJlIGV2YWx1YXRlZCBpbiB0aGUgb3JkZXJcbiAqIHN1cHBsaWVkIGFuZCBhcmUgbm90IGNoZWNrZWQgZm9yIGR1cGxpY2F0ZXMuXG4gKiBAcGFyYW0gbWVzc2FnZSAtIEFuIG9wdGlvbmFsIGVycm9yIG1lc3NhZ2UuXG4gKiBAcmV0dXJucyBBIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGFwcGxpZXMgdGhlIG1hcHBpbmcgYW5kIHlpZWxkcyBgPFQ+YCBvbiBzdWNjZXNzLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWFwcGVkRW51bWVyYXRlZFZhbHVlPFQ+KG1hcDogW1QsIHVua25vd25bXV1bXSwgbWVzc2FnZT86IHN0cmluZyk6IENvbnZlcnRlcjxULCB1bmRlZmluZWQ+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VCwgdW5kZWZpbmVkPiwgX2NvbnRleHQ/OiB1bmtub3duKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBtYXApIHtcbiAgICAgICAgICAgIGlmIChpdGVtWzFdLmluY2x1ZGVzKGZyb20pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1Y2NlZWQoaXRlbVswXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhaWwobWVzc2FnZSA/IGAke0pTT04uc3RyaW5naWZ5KGZyb20pfTogJHttZXNzYWdlfWAgOiBgQ2Fubm90IG1hcCAnJHtKU09OLnN0cmluZ2lmeShmcm9tKX0nIHRvIGEgc3VwcG9ydGVkIHZhbHVlYCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIGB1bmtub3duYCB0byBzb21lIHN1cHBsaWVkIGxpdGVyYWwgdmFsdWUuIFN1Y2NlZWRzIHdpdGhcbiAqIHRoZSBzdXBwbGllZCB2YWx1ZSBpZiBhbiBpZGVudGl0eSBjb21wYXJpc29uIHN1Y2NlZWRzLCBmYWlscyBvdGhlcndpc2UuXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gYmUgY29tcGFyZWQuXG4gKiBAcmV0dXJucyBBIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIHJldHVybnMgdGhlIHN1cHBsaWVkIHZhbHVlIG9uIHN1Y2Nlc3MuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaXRlcmFsPFQ+KHZhbHVlOiBUKTogQ29udmVydGVyPFQsIHVua25vd24+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXI8VCwgdW5rbm93bj4oKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VCwgdW5rbm93bj4sIF9jb250ZXh0PzogdW5rbm93bik6IFJlc3VsdDxUPiA9PiB7XG4gICAgICAgIHJldHVybiAoZnJvbSA9PT0gdmFsdWUpID8gc3VjY2VlZCh2YWx1ZSkgOiBmYWlsKGAke0pTT04uc3RyaW5naWZ5KGZyb20pfTogZG9lcyBub3QgbWF0Y2ggJHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9YCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogRGVwcmVjYXRlZCBhbGlhcyBmb3IgQHNlZSBsaXRlcmFsXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gYmUgY29tcGFyZWQuXG4gKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rIENvbnZlcnRlcnMubGl0ZXJhbH0gaW5zdGVhZC5cbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgdmFsdWUgPSBsaXRlcmFsO1xuXG4vKipcbiAqIEEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggY29udmVydHMgYHVua25vd25gIHRvIGEgYG51bWJlcmAuXG4gKiBAcmVtYXJrc1xuICogTnVtYmVycyBhbmQgc3RyaW5ncyB3aXRoIGEgbnVtZXJpYyBmb3JtYXQgc3VjY2VlZC4gQW55dGhpbmcgZWxzZSBmYWlscy5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IG51bWJlciA9IG5ldyBCYXNlQ29udmVydGVyPG51bWJlcj4oKGZyb206IHVua25vd24pID0+IHtcbiAgICBpZiAodHlwZW9mIGZyb20gIT09ICdudW1iZXInKSB7XG4gICAgICAgIGNvbnN0IG51bTogbnVtYmVyID0gKHR5cGVvZiBmcm9tID09PSAnc3RyaW5nJyA/IE51bWJlcihmcm9tKSA6IE5hTik7XG4gICAgICAgIHJldHVybiBpc05hTihudW0pXG4gICAgICAgICAgICA/IGZhaWwoYE5vdCBhIG51bWJlcjogJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKVxuICAgICAgICAgICAgOiBzdWNjZWVkKG51bSk7XG4gICAgfVxuICAgIHJldHVybiBzdWNjZWVkKGZyb20pO1xufSk7XG5cbi8qKlxuICogQSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBjb252ZXJ0cyBgdW5rbm93bmAgdG8gYGJvb2xlYW5gLlxuICogQHJlbWFya3NcbiAqIEJvb2xlYW4gdmFsdWVzIG9yIHRoZSBjYXNlLWluc2Vuc2l0aXZlIHN0cmluZ3MgYCd0cnVlJ2AgYW5kIGAnZmFsc2UnYCBzdWNjZWVkLlxuICogQW55dGhpbmcgZWxzZSBmYWlscy5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IGJvb2xlYW4gPSBuZXcgQmFzZUNvbnZlcnRlcjxib29sZWFuPigoZnJvbTogdW5rbm93bikgPT4ge1xuICAgIGlmICh0eXBlb2YgZnJvbSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHJldHVybiBzdWNjZWVkKGZyb20gYXMgYm9vbGVhbik7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBmcm9tID09PSAnc3RyaW5nJykge1xuICAgICAgICBzd2l0Y2ggKGZyb20udG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSAndHJ1ZSc6IHJldHVybiBzdWNjZWVkKHRydWUpO1xuICAgICAgICAgICAgY2FzZSAnZmFsc2UnOiByZXR1cm4gc3VjY2VlZChmYWxzZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhaWwoYE5vdCBhIGJvb2xlYW46ICR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9YCk7XG59KTtcblxuLyoqXG4gKiBBIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIGFuIG9wdGlvbmFsIGBzdHJpbmdgIHZhbHVlLiBWYWx1ZXMgb2YgdHlwZVxuICogYHN0cmluZ2AgYXJlIHJldHVybmVkLiAgQW55dGhpbmcgZWxzZSByZXR1cm5zIHtAbGluayBTdWNjZXNzfSB3aXRoIHZhbHVlIGB1bmRlZmluZWRgLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3Qgb3B0aW9uYWxTdHJpbmcgPSBzdHJpbmcub3B0aW9uYWwoKTtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggY29udmVydHMgYW55IGBzdHJpbmdgIGludG8gYW5cbiAqIGFycmF5IG9mIGBzdHJpbmdgLCBieSBzZXBhcmF0aW5nIGF0IGEgc3VwcGxpZWQgZGVsaW1pdGVyLlxuICogQHJlbWFya3NcbiAqIERlbGltZXRlciBtYXkgYWxzbyBiZSBzdXBwbGllZCBhcyBjb250ZXh0IGF0IGNvbnZlcnNpb24gdGltZS5cbiAqIEBwYXJhbSBkZWxpbWl0ZXIgLSBUaGUgZGVsaW1pdGVyIGF0IHdoaWNoIHRvIHNwbGl0LlxuICogQHJldHVybnMgQSBuZXcge0BsaW5rIENvbnZlcnRlcn0gcmV0dXJuaW5nIGBzdHJpbmdbXWAuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWxpbWl0ZWRTdHJpbmcoZGVsaW1pdGVyOiBzdHJpbmcsIG9wdGlvbnM6ICdmaWx0ZXJlZCd8J2FsbCcgPSAnZmlsdGVyZWQnKTogQ29udmVydGVyPHN0cmluZ1tdLCBzdHJpbmc+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXI8c3RyaW5nW10sIHN0cmluZz4oKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8c3RyaW5nW10sIHN0cmluZz4sIGNvbnRleHQ/OiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gc3RyaW5nLmNvbnZlcnQoZnJvbSk7XG4gICAgICAgIGlmIChyZXN1bHQuaXNTdWNjZXNzKCkpIHtcbiAgICAgICAgICAgIGxldCBzdHJpbmdzID0gcmVzdWx0LnZhbHVlLnNwbGl0KGNvbnRleHQgPz8gZGVsaW1pdGVyKTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zICE9PSAnYWxsJykge1xuICAgICAgICAgICAgICAgIHN0cmluZ3MgPSBzdHJpbmdzLmZpbHRlcigocykgPT4gKHMudHJpbSgpLmxlbmd0aCA+IDApKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdWNjZWVkKHN0cmluZ3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWlsKHJlc3VsdC5tZXNzYWdlKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIGFuIGlzbyBmb3JtYXR0ZWQgc3RyaW5nLCBhIG51bWJlciBvciBhIGBEYXRlYCBvYmplY3QgdG9cbiAqIGEgYERhdGVgIG9iamVjdC5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IGlzb0RhdGUgPSBuZXcgQmFzZUNvbnZlcnRlcjxEYXRlPigoZnJvbTogdW5rbm93bikgPT4ge1xuICAgIGlmICh0eXBlb2YgZnJvbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc3QgZHQgPSBEYXRlVGltZS5mcm9tSVNPKGZyb20pO1xuICAgICAgICBpZiAoZHQuaXNWYWxpZCkge1xuICAgICAgICAgICAgcmV0dXJuIHN1Y2NlZWQoZHQudG9KU0RhdGUoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhaWwoYEludmFsaWQgZGF0ZTogJHtkdC5pbnZhbGlkRXhwbGFuYXRpb259YCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBmcm9tID09PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gc3VjY2VlZChuZXcgRGF0ZShmcm9tKSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGZyb20gaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgIHJldHVybiBzdWNjZWVkKGZyb20pO1xuICAgIH1cbiAgICByZXR1cm4gZmFpbChgQ2Fubm90IGNvbnZlcnQgJHtKU09OLnN0cmluZ2lmeShmcm9tKX0gdG8gRGF0ZWApO1xufSk7XG5cbi8qKlxuICogQSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBjb252ZXJ0cyBhbiBvcHRpb25hbCBgbnVtYmVyYCB2YWx1ZS5cbiAqIEByZW1hcmtzXG4gKiBWYWx1ZXMgb2YgdHlwZSBgbnVtYmVyYCBvciBudW1lcmljIHN0cmluZ3MgYXJlIGNvbnZlcnRlZCBhbmQgcmV0dXJuZWQuXG4gKiBBbnl0aGluZyBlbHNlIHJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggdmFsdWUgYHVuZGVmaW5lZGAuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBvcHRpb25hbE51bWJlciA9IG51bWJlci5vcHRpb25hbCgpO1xuXG4vKipcbiAqIEEge0BsaW5rIENvbnZlcnRlcn0gdG8gY29udmVydCBhbiBvcHRpb25hbCBgYm9vbGVhbmAgdmFsdWUuXG4gKiBAcmVtYXJrc1xuICogVmFsdWVzIG9mIHR5cGUgYGJvb2xlYW5gIG9yIHN0cmluZ3MgdGhhdCBtYXRjaCAoY2FzZS1pbnNlbnNpdGl2ZSkgYCd0cnVlJ2BcbiAqIG9yIGAnZmFsc2UnYCBhcmUgY29udmVydGVkIGFuZCByZXR1cm5lZC4gIEFueXRoaW5nIGVsc2UgcmV0dXJucyB7QGxpbmsgU3VjY2Vzc31cbiAqIHdpdGggdmFsdWUgYHVuZGVmaW5lZGAuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBvcHRpb25hbEJvb2xlYW4gPSBib29sZWFuLm9wdGlvbmFsKCk7XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcn0gZm9yIHBvbHltb3JwaGljIHZhbHVlcy4gIFJldHVybnMgYVxuICogY29udmVydGVyIHdoaWNoIEludm9rZXMgdGhlIHdyYXBwZWQgY29udmVydGVycyBpbiBzZXF1ZW5jZSwgcmV0dXJuaW5nIHRoZSBmaXJzdCBzdWNjZXNzZnVsXG4gKiByZXN1bHQuICBSZXR1cm5zIGFuIGVycm9yIGlmIG5vbmUgb2YgdGhlIHN1cHBsaWVkIGNvbnZlcnRlcnMgY2FuIGNvbnZlcnQgdGhlIHZhbHVlLlxuICogQHJlbWFya3NcbiAqIElmIGBvbkVycm9yYCBpcyBgaWdub3JlRXJyb3JzYCAoZGVmYXVsdCksIHRoZW4gZXJyb3JzIGZyb20gYW55IG9mIHRoZVxuICogY29udmVydGVycyBhcmUgaWdub3JlZCBwcm92aWRlZCB0aGF0IHNvbWUgY29udmVydGVyIHN1Y2NlZWRzLiAgSWZcbiAqIG9uRXJyb3IgaXMgYGZhaWxPbkVycm9yYCwgdGhlbiBhbiBlcnJvciBmcm9tIGFueSBjb252ZXJ0ZXIgZmFpbHMgdGhlIGVudGlyZVxuICogY29udmVyc2lvbi5cbiAqXG4gKiBAcGFyYW0gY29udmVydGVycyAtIEFuIG9yZGVyZWQgbGlzdCBvZiB7QGxpbmsgQ29udmVydGVyIHwgY29udmVydGVyc30gdG8gYmUgY29uc2lkZXJlZC5cbiAqIEBwYXJhbSBvbkVycm9yIC0gU3BlY2lmaWVzIHRyZWF0bWVudCBvZiB1bmNvbnZlcnRhYmxlIGVsZW1lbnRzLlxuICogQHJldHVybnMgQSBuZXcge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggeWllbGRzIGEgdmFsdWUgZnJvbSB0aGUgdW5pb24gb2YgdGhlIHR5cGVzIHJldHVybmVkXG4gKiBieSB0aGUgd3JhcHBlZCBjb252ZXJ0ZXJzLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gb25lT2Y8VCwgVEM9dW5rbm93bj4oY29udmVydGVyczogQXJyYXk8Q29udmVydGVyPFQsIFRDPj4sIG9uRXJyb3I6IE9uRXJyb3IgPSAnaWdub3JlRXJyb3JzJyk6IENvbnZlcnRlcjxULCBUQz4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGYsIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG4gICAgICAgIGZvciAoY29uc3QgY29udmVydGVyIG9mIGNvbnZlcnRlcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnZlcnRlci5jb252ZXJ0KGZyb20sIGNvbnRleHQpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSAmJiAocmVzdWx0LnZhbHVlICE9PSB1bmRlZmluZWQpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJlc3VsdC5pc0ZhaWx1cmUoKSkge1xuICAgICAgICAgICAgICAgIGlmIChvbkVycm9yID09PSAnZmFpbE9uRXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVycm9ycy5wdXNoKHJlc3VsdC5tZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFpbChgTm8gbWF0Y2hpbmcgY29udmVydGVyIGZvciAke0pTT04uc3RyaW5naWZ5KGZyb20pfTogJHtlcnJvcnMuam9pbignXFxuJyl9YCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggY29udmVydHMgYHVua25vd25gIHRvIGFuIGFycmF5IG9mIGA8VD5gLlxuICogQHJlbWFya3NcbiAqIElmIGBvbkVycm9yYCBpcyBgJ2ZhaWxPbkVycm9yJ2AgKGRlZmF1bHQpLCB0aGVuIHRoZSBlbnRpcmUgY29udmVyc2lvbiBmYWlscyBpZiBhbnkgZWxlbWVudCBjYW5ub3RcbiAqIGJlIGNvbnZlcnRlZC4gIElmIGBvbkVycm9yYCBpcyBgJ2lnbm9yZUVycm9ycydgLCB0aGVuIGZhaWxpbmcgZWxlbWVudHMgYXJlIHNpbGVudGx5IGlnbm9yZWQuXG4gKiBAcGFyYW0gY29udmVydGVyIC0ge0BsaW5rIENvbnZlcnRlcn0gdXNlZCB0byBjb252ZXJ0IGVhY2ggaXRlbSBpbiB0aGUgYXJyYXkuXG4gKiBAcGFyYW0gaWdub3JlRXJyb3JzIC0gU3BlY2lmaWVzIHRyZWF0bWVudCBvZiB1bmNvbnZlcnRhYmxlIGVsZW1lbnRzLlxuICogQHJldHVybnMgQSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCByZXR1cm5zIGFuIGFycmF5IG9mIGA8VD5gLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlPZjxULCBUQz11bmRlZmluZWQ+KGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPiwgb25FcnJvcjogT25FcnJvciA9ICdmYWlsT25FcnJvcicpOiBDb252ZXJ0ZXI8VFtdLCBUQz4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxUW10sIFRDPiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShmcm9tKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYE5vdCBhbiBhcnJheTogJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN1Y2Nlc3NlczogVFtdID0gW107XG4gICAgICAgIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGZyb20pIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnZlcnRlci5jb252ZXJ0KGl0ZW0sIGNvbnRleHQpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSAmJiByZXN1bHQudmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3Nlcy5wdXNoKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChyZXN1bHQuaXNGYWlsdXJlKCkpIHtcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChyZXN1bHQubWVzc2FnZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gKGVycm9ycy5sZW5ndGggPT09IDApIHx8IChvbkVycm9yID09PSAnaWdub3JlRXJyb3JzJylcbiAgICAgICAgICAgID8gc3VjY2VlZChzdWNjZXNzZXMpXG4gICAgICAgICAgICA6IGZhaWwoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBIGhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBjb252ZXJ0cyBgdW5rbm93bmAgdG8ge0BsaW5rIEV4dGVuZGVkQXJyYXkgfCBFeHRlbmRlZEFycmF5PFQ+fS5cbiAqIEByZW1hcmtzXG4gKiBJZiBgb25FcnJvcmAgaXMgYCdmYWlsT25FcnJvcidgIChkZWZhdWx0KSwgdGhlbiB0aGUgZW50aXJlIGNvbnZlcnNpb24gZmFpbHMgaWYgYW55IGVsZW1lbnQgY2Fubm90XG4gKiBiZSBjb252ZXJ0ZWQuICBJZiBgb25FcnJvcmAgaXMgYCdpZ25vcmVFcnJvcnMnYCwgdGhlbiBmYWlsaW5nIGVsZW1lbnRzIGFyZSBzaWxlbnRseSBpZ25vcmVkLlxuICogQHBhcmFtIGNvbnZlcnRlciAtIHtAbGluayBDb252ZXJ0ZXJ9IHVzZWQgdG8gY29udmVydCBlYWNoIGl0ZW0gaW4gdGhlIGFycmF5XG4gKiBAcGFyYW0gaWdub3JlRXJyb3JzIC0gU3BlY2lmaWVzIHRyZWF0bWVudCBvZiB1bmNvbnZlcnRhYmxlIGVsZW1lbnRzXG4gKiBAYmV0YVxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0ZW5kZWRBcnJheU9mPFQsIFRDPXVuZGVmaW5lZD4obGFiZWw6IHN0cmluZywgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+LCBvbkVycm9yOiBPbkVycm9yID0gJ2ZhaWxPbkVycm9yJyk6IENvbnZlcnRlcjxFeHRlbmRlZEFycmF5PFQ+LCBUQz4ge1xuICAgIHJldHVybiBhcnJheU9mKGNvbnZlcnRlciwgb25FcnJvcikubWFwKChpdGVtczogVFtdKSA9PiB7XG4gICAgICAgIHJldHVybiBjYXB0dXJlUmVzdWx0KCgpID0+IG5ldyBFeHRlbmRlZEFycmF5KGxhYmVsLCAuLi5pdGVtcykpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIHtAbGluayBDb252ZXJ0ZXJ9IHRvIGNvbnZlcnQgYW4gYHVua25vd25gIHRvIGFuIGFycmF5IG9mIGBzdHJpbmdgLlxuICogQHJlbWFya3NcbiAqIFJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggdGhlIHRoZSBzdXBwbGllZCB2YWx1ZSBpZiBpdCBhcyBhbiBhcnJheVxuICogb2Ygc3RyaW5ncywgcmV0dXJucyB7QGxpbmsgRmFpbHVyZX0gd2l0aCBhbiBlcnJvciBtZXNzYWdlIG90aGVyd2lzZS5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IHN0cmluZ0FycmF5ID0gYXJyYXlPZihzdHJpbmcpO1xuXG4vKipcbiAqIHtAbGluayBDb252ZXJ0ZXJ9IHRvIGNvbnZlcnQgYW4gYHVua25vd25gIHRvIGFuIGFycmF5IG9mIGBudW1iZXJgLlxuICogQHJlbWFya3NcbiAqIFJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggdGhlIHRoZSBzdXBwbGllZCB2YWx1ZSBpZiBpdCBhcyBhbiBhcnJheVxuICogb2YgbnVtYmVycywgcmV0dXJucyB7QGxpbmsgRmFpbHVyZX0gd2l0aCBhbiBlcnJvciBtZXNzYWdlIG90aGVyd2lzZS5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IG51bWJlckFycmF5ID0gYXJyYXlPZihudW1iZXIpO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBDb252ZXJ0ZXJzLihyZWNvcmRPZjp3aXRoT3B0aW9ucyl9IGFuZCB7QGxpbmsgQ29udmVydGVycy4obWFwT2Y6d2l0aE9wdGlvbnMpfVxuICogaGVscGVyIGZ1bmN0aW9ucy5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBLZXllZENvbnZlcnRlck9wdGlvbnM8VCBleHRlbmRzIHN0cmluZyA9IHN0cmluZywgVEM9dW5kZWZpbmVkPiB7XG4gICAgLyoqXG4gICAgICogaWYgYG9uRXJyb3JgIGlzIGAnZmFpbCdgIChkZWZhdWx0KSwgdGhlbiB0aGUgZW50aXJlIGNvbnZlcnNpb24gZmFpbHMgaWYgYW55IGtleSBvciBlbGVtZW50XG4gICAgICogY2Fubm90IGJlIGNvbnZlcnRlZC4gIElmIGBvbkVycm9yYCBpcyBgJ2lnbm9yZSdgLCBmYWlsaW5nIGVsZW1lbnRzIGFyZSBzaWxlbnRseSBpZ25vcmVkLlxuICAgICAqL1xuICAgIG9uRXJyb3I/OiAnZmFpbCd8J2lnbm9yZSc7XG4gICAgLyoqXG4gICAgICogSWYgcHJlc2VudCwgYGtleUNvbnZlcnRlcmAgaXMgdXNlZCB0byBjb252ZXJ0IHRoZSBzb3VyY2Ugb2JqZWN0IHByb3BlcnR5IG5hbWVzIHRvXG4gICAgICoga2V5cyBpbiB0aGUgcmVzdWx0aW5nIG1hcCBvciByZWNvcmQuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBDYW4gYmUgdXNlZCB0byBjb2VyY2Uga2V5IG5hbWVzIHRvIHN1cHBvcnRlZCB2YWx1ZXMgYW5kL29yIHN0cm9uZyB0eXBlcy5cbiAgICAgKi9cbiAgICBrZXlDb252ZXJ0ZXI/OiBDb252ZXJ0ZXI8VCwgVEM+O1xufVxuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIHRoZSBgc3RyaW5nYC1rZXllZCBwcm9wZXJ0aWVzXG4gKiB1c2luZyBhIHN1cHBsaWVkIHtAbGluayBDb252ZXJ0ZXIgfCBDb252ZXJ0ZXI8VD59IHRvIHByb2R1Y2UgYSBgUmVjb3JkPHN0cmluZywgVD5gLlxuICogQHJlbWFya3NcbiAqIFRoZSByZXN1bHRpbmcgY29udmVydGVyIGZhaWxzIGNvbnZlcnNpb24gaWYgYW55IGVsZW1lbnQgY2Fubm90IGJlIGNvbnZlcnRlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgLSB7QGxpbmsgQ29udmVydGVyfSB1c2VkIHRvIGNvbnZlcnQgZWFjaCBpdGVtIGluIHRoZSBzb3VyY2Ugb2JqZWN0LlxuICogQHJldHVybnMgQSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCByZXR1cm5zIGBSZWNvcmQ8c3RyaW5nLCBUPmAuXG4gKiB7QGxhYmVsIGRlZmF1bHR9XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRPZjxULCBUQz11bmRlZmluZWQsIFRLIGV4dGVuZHMgc3RyaW5nPXN0cmluZz4oY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+KTogQ29udmVydGVyPFJlY29yZDxUSywgVD4sIFRDPjtcblxuLyoqXG4gKiBBIGhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBjb252ZXJ0cyB0aGUgYHN0cmluZ2Ata2V5ZWQgcHJvcGVydGllc1xuICogdXNpbmcgYSBzdXBwbGllZCB7QGxpbmsgQ29udmVydGVyIHwgQ29udmVydGVyPFQ+fSB0byBwcm9kdWNlIGEgYFJlY29yZDxzdHJpbmcsIFQ+YCBhbmQgb3B0aW9uYWxseVxuICogc3BlY2lmaWVkIGhhbmRsaW5nIG9mIGVsZW1lbnRzIHRoYXQgY2Fubm90IGJlIGNvbnZlcnRlZC5cbiAqIEByZW1hcmtzXG4gKiBpZiBgb25FcnJvcmAgaXMgYCdmYWlsJ2AgKGRlZmF1bHQpLCB0aGVuIHRoZSBlbnRpcmUgY29udmVyc2lvbiBmYWlscyBpZiBhbnkga2V5IG9yIGVsZW1lbnRcbiAqIGNhbm5vdCBiZSBjb252ZXJ0ZWQuICBJZiBgb25FcnJvcmAgaXMgYCdpZ25vcmUnYCwgZmFpbGluZyBlbGVtZW50cyBhcmUgc2lsZW50bHkgaWdub3JlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgLSB7QGxpbmsgQ29udmVydGVyfSB1c2VkIHRvIGNvbnZlcnQgZWFjaCBpdGVtIGluIHRoZSBzb3VyY2Ugb2JqZWN0LlxuICogQHJldHVybnMgQSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCByZXR1cm5zIGBSZWNvcmQ8c3RyaW5nLCBUPmAuXG4gKiB7QGxhYmVsIHdpdGhPbkVycm9yfVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkT2Y8VCwgVEM9dW5kZWZpbmVkLCBUSyBleHRlbmRzIHN0cmluZz1zdHJpbmc+KFxuICAgIGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPixcbiAgICBvbkVycm9yOiAnZmFpbCd8J2lnbm9yZSdcbik6IENvbnZlcnRlcjxSZWNvcmQ8VEssIFQ+LCBUQz47XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggY29udmVydHMgdGhlIGBzdHJpbmdgLWtleWVkIHByb3BlcnRpZXNcbiAqIHVzaW5nIGEgc3VwcGxpZWQge0BsaW5rIENvbnZlcnRlciB8IENvbnZlcnRlcjxUPn0gdG8gcHJvZHVjZSBhIGBSZWNvcmQ8VEssIFQ+YC5cbiAqIEByZW1hcmtzXG4gKiBJZiBwcmVzZW50LCB0aGUgc3VwcGxpZWQge0BsaW5rIENvbnZlcnRlcnMuS2V5ZWRDb252ZXJ0ZXJPcHRpb25zIHwgb3B0aW9uc30gY2FuIHByb3ZpZGUgYSBzdHJvbmdseS10eXBlZFxuICogY29udmVydGVyIGZvciBrZXlzIGFuZC9vciBjb250cm9sIHRoZSBoYW5kbGluZyBvZiBlbGVtZW50cyB0aGF0IGZhaWwgY29udmVyc2lvbi5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgLSB7QGxpbmsgQ29udmVydGVyfSB1c2VkIHRvIGNvbnZlcnQgZWFjaCBpdGVtIGluIHRoZSBzb3VyY2Ugb2JqZWN0LlxuICogQHBhcmFtIG9wdGlvbnMgLSBPcHRpb25hbCB7QGxpbmsgQ29udmVydGVycy5LZXllZENvbnZlcnRlck9wdGlvbnMgfCBLZXllZENvbnZlcnRlck9wdGlvbnM8VEssIFRDPn0gd2hpY2hcbiAqIHN1cHBsaWVzIGEga2V5IGNvbnZlcnRlciBhbmQvb3IgZXJyb3ItaGFuZGxpbmcgb3B0aW9ucy5cbiAqIEByZXR1cm5zIEEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggcmV0dXJucyBgUmVjb3JkPFRLLCBUPmAuXG4gKiB7QGxhYmVsIHdpdGhPcHRpb25zfVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkT2Y8VCwgVEM9dW5kZWZpbmVkLCBUSyBleHRlbmRzIHN0cmluZz1zdHJpbmc+KFxuICAgIGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPixcbiAgICBvcHRpb25zOiBLZXllZENvbnZlcnRlck9wdGlvbnM8VEssIFRDPlxuKTogQ29udmVydGVyPFJlY29yZDxUSywgVD4sIFRDPjtcblxuLyoqXG4gKiBDb25jcmV0ZSBpbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgQ29udmVydGVycy4ocmVjb3JkT2Y6ZGVmYXVsdCkgfCBDb252ZXJ0ZXJzLnJlY29yZE9mKENvbnZlcnRlcjxUPil9LFxuICoge0BsaW5rIENvbnZlcnRlcnMuKHJlY29yZE9mOndpdGhPbkVycm9yKSB8IENvbnZlcnRlcnMucmVjb3JkT2YoQ29udmVydGVyPFQ+LCAnZmFpbCd8J2lnbm9yZScpfSwgYW5kXG4gKiB7QGxpbmsgQ29udmVydGVycy4ocmVjb3JkT2Y6d2l0aE9wdGlvbnMpIHwgQ29udmVydGVycy5yZWNvcmRPZihDb252ZXJ0ZXI8VD4sIEtleWVkQ29udmVydGVyT3B0aW9ucyl9LlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRPZjxULCBUQz11bmRlZmluZWQsIFRLIGV4dGVuZHMgc3RyaW5nPXN0cmluZz4oXG4gICAgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+LFxuICAgIG9wdGlvbjogJ2ZhaWwnfCdpZ25vcmUnfEtleWVkQ29udmVydGVyT3B0aW9uczxUSywgVEM+ID0gJ2ZhaWwnXG4pOiBDb252ZXJ0ZXI8UmVjb3JkPFRLLCBUPiwgVEM+IHtcbiAgICBjb25zdCBvcHRpb25zOiBLZXllZENvbnZlcnRlck9wdGlvbnM8VEssIFRDPiA9ICh0eXBlb2Ygb3B0aW9uID09PSAnc3RyaW5nJykgPyB7IG9uRXJyb3I6IG9wdGlvbiB9IDogeyBvbkVycm9yOiAnZmFpbCcsIC4uLm9wdGlvbiB9O1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxSZWNvcmQ8VEssIFQ+LCBUQz4sIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICBpZiAoKHR5cGVvZiBmcm9tICE9PSAnb2JqZWN0JykgfHwgKGZyb20gPT09IG51bGwpIHx8IEFycmF5LmlzQXJyYXkoZnJvbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKGBOb3QgYSBzdHJpbmcta2V5ZWQgb2JqZWN0OiAke0pTT04uc3RyaW5naWZ5KGZyb20pfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVjb3JkOiBSZWNvcmQ8c3RyaW5nLCBUPiA9IHt9O1xuICAgICAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG5cbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZnJvbSkge1xuICAgICAgICAgICAgaWYgKGlzS2V5T2Yoa2V5LCBmcm9tKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHdyaXRlS2V5UmVzdWx0ID0gb3B0aW9ucy5rZXlDb252ZXJ0ZXI/LmNvbnZlcnQoa2V5LCBjb250ZXh0KSA/PyBzdWNjZWVkKGtleSk7XG5cbiAgICAgICAgICAgICAgICB3cml0ZUtleVJlc3VsdC5vblN1Y2Nlc3MoKHdyaXRlS2V5KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb252ZXJ0ZXIuY29udmVydChmcm9tW2tleV0gYXMgdW5rbm93biwgY29udGV4dCkub25TdWNjZXNzKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkW3dyaXRlS2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1Y2NlZWQodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pLm9uRmFpbHVyZSgobWVzc2FnZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChtZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhaWwobWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gKGVycm9ycy5sZW5ndGggPT09IDApIHx8IChvcHRpb25zLm9uRXJyb3IgPT09ICdpZ25vcmUnKVxuICAgICAgICAgICAgPyBzdWNjZWVkKHJlY29yZClcbiAgICAgICAgICAgIDogZmFpbChlcnJvcnMuam9pbignXFxuJykpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIHRoZSBgc3RyaW5nYC1rZXllZCBwcm9wZXJ0aWVzXG4gKiB1c2luZyBhIHN1cHBsaWVkIHtAbGluayBDb252ZXJ0ZXIgfCBDb252ZXJ0ZXI8VD59IHRvIHByb2R1Y2UgYSBgTWFwPHN0cmluZywgVD5gLlxuICogQHJlbWFya3NcbiAqIFRoZSByZXN1bHRpbmcgY29udmVydGVyIGZhaWxzIGNvbnZlcnNpb24gaWYgYW55IGVsZW1lbnQgY2Fubm90IGJlIGNvbnZlcnRlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgLSB7QGxpbmsgQ29udmVydGVyfSB1c2VkIHRvIGNvbnZlcnQgZWFjaCBpdGVtIGluIHRoZSBzb3VyY2Ugb2JqZWN0LlxuICogQHJldHVybnMgQSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCByZXR1cm5zIGBNYXA8c3RyaW5nLCBUPmAuXG4gKiB7QGxhYmVsIGRlZmF1bHR9XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXBPZjxULCBUQyA9IHVuZGVmaW5lZCwgVEsgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+KGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPik6IENvbnZlcnRlcjxNYXA8VEssIFQ+LCBUQz47XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggY29udmVydHMgdGhlIGBzdHJpbmdgLWtleWVkIHByb3BlcnRpZXNcbiAqIHVzaW5nIGEgc3VwcGxpZWQge0BsaW5rIENvbnZlcnRlciB8IENvbnZlcnRlcjxUPn0gdG8gcHJvZHVjZSBhIGBNYXA8c3RyaW5nLCBUPmAgYW5kIG9wdGlvbmFsbHlcbiAqIHNwZWNpZmllZCBoYW5kbGluZyBvZiBlbGVtZW50cyB0aGF0IGNhbm5vdCBiZSBjb252ZXJ0ZWQuXG4gKiBAcmVtYXJrc1xuICogaWYgYG9uRXJyb3JgIGlzIGAnZmFpbCdgIChkZWZhdWx0KSwgdGhlbiB0aGUgZW50aXJlIGNvbnZlcnNpb24gZmFpbHMgaWYgYW55IGtleSBvciBlbGVtZW50XG4gKiBjYW5ub3QgYmUgY29udmVydGVkLiAgSWYgYG9uRXJyb3JgIGlzIGAnaWdub3JlJ2AsIGZhaWxpbmcgZWxlbWVudHMgYXJlIHNpbGVudGx5IGlnbm9yZWQuXG4gKiBAcGFyYW0gY29udmVydGVyIC0ge0BsaW5rIENvbnZlcnRlcn0gdXNlZCB0byBjb252ZXJ0IGVhY2ggaXRlbSBpbiB0aGUgc291cmNlIG9iamVjdC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggcmV0dXJucyBgTWFwPHN0cmluZywgVD5gLlxuICoge0BsYWJlbCB3aXRoT25FcnJvcn1cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcE9mPFQsIFRDID0gdW5kZWZpbmVkLCBUSyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4oXG4gICAgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+LFxuICAgIG9uRXJyb3I6ICdmYWlsJyB8ICdpZ25vcmUnXG4pOiBDb252ZXJ0ZXI8TWFwPFRLLCBUPiwgVEM+O1xuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIHRoZSBgc3RyaW5nYC1rZXllZCBwcm9wZXJ0aWVzXG4gKiB1c2luZyBhIHN1cHBsaWVkIHtAbGluayBDb252ZXJ0ZXIgfCBDb252ZXJ0ZXI8VD59IHRvIHByb2R1Y2UgYSBgTWFwPFRLLCBUPmAuXG4gKiBAcmVtYXJrc1xuICogSWYgcHJlc2VudCwgdGhlIHN1cHBsaWVkIHtAbGluayBDb252ZXJ0ZXJzLktleWVkQ29udmVydGVyT3B0aW9ucyB8IG9wdGlvbnN9IGNhbiBwcm92aWRlIGEgc3Ryb25nbHktdHlwZWRcbiAqIGNvbnZlcnRlciBmb3Iga2V5cyBhbmQvb3IgY29udHJvbCB0aGUgaGFuZGxpbmcgb2YgZWxlbWVudHMgdGhhdCBmYWlsIGNvbnZlcnNpb24uXG4gKiBAcGFyYW0gY29udmVydGVyIC0ge0BsaW5rIENvbnZlcnRlcn0gdXNlZCB0byBjb252ZXJ0IGVhY2ggaXRlbSBpbiB0aGUgc291cmNlIG9iamVjdC5cbiAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwge0BsaW5rIENvbnZlcnRlcnMuS2V5ZWRDb252ZXJ0ZXJPcHRpb25zIHwgS2V5ZWRDb252ZXJ0ZXJPcHRpb25zPFRLLCBUQz59IHdoaWNoXG4gKiBzdXBwbGllcyBhIGtleSBjb252ZXJ0ZXIgYW5kL29yIGVycm9yLWhhbmRsaW5nIG9wdGlvbnMuXG4gKiBAcmV0dXJucyBBIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIHJldHVybnMgYE1hcDxUSywgVD5gLlxuICoge0BsYWJlbCB3aXRoT3B0aW9uc31cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcE9mPFQsIFRDID0gdW5kZWZpbmVkLCBUSyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4oXG4gICAgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+LFxuICAgIG9wdGlvbnM6IEtleWVkQ29udmVydGVyT3B0aW9uczxUSywgVEM+XG4pOiBDb252ZXJ0ZXI8TWFwPFRLLCBUPiwgVEM+O1xuXG4vKipcbiAqIENvbmNyZXRlIGltcGxlbWVudGF0aW9uIG9mIHtAbGluayBDb252ZXJ0ZXJzLihtYXBPZjpkZWZhdWx0KSB8IENvbnZlcnRlcnMubWFwT2YoQ29udmVydGVyPFQ+KX0sXG4gKiB7QGxpbmsgQ29udmVydGVycy4obWFwT2Y6d2l0aE9uRXJyb3IpIHwgQ29udmVydGVycy5tYXBPZihDb252ZXJ0ZXI8VD4sICdmYWlsJ3wnaWdub3JlJyl9LCBhbmRcbiAqIHtAbGluayBDb252ZXJ0ZXJzLihtYXBPZjp3aXRoT3B0aW9ucykgfCBDb252ZXJ0ZXJzLm1hcE9mKENvbnZlcnRlcjxUPiwgS2V5ZWRDb252ZXJ0ZXJPcHRpb25zKX0uXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcE9mPFQsIFRDID0gdW5kZWZpbmVkLCBUSyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4oXG4gICAgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+LFxuICAgIG9wdGlvbjogJ2ZhaWwnIHwgJ2lnbm9yZScgfCBLZXllZENvbnZlcnRlck9wdGlvbnM8VEssIFRDPiA9ICdmYWlsJ1xuKTogQ29udmVydGVyPE1hcDxUSywgVD4sIFRDPiB7XG4gICAgY29uc3Qgb3B0aW9ucyA9ICh0eXBlb2Ygb3B0aW9uID09PSAnc3RyaW5nJykgPyB7IG9uRXJyb3I6IG9wdGlvbiB9IDogeyBvbkVycm9yOiAnZmFpbCcsIC4uLm9wdGlvbiB9O1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxNYXA8VEssIFQ+LCBUQz4sIGNvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICBpZiAoKHR5cGVvZiBmcm9tICE9PSAnb2JqZWN0JykgfHwgKGZyb20gPT09IG51bGwpIHx8IEFycmF5LmlzQXJyYXkoZnJvbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKGBOb3QgYSBzdHJpbmcta2V5ZWQgb2JqZWN0OiAke0pTT04uc3RyaW5naWZ5KGZyb20pfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbWFwID0gbmV3IE1hcDxUSywgVD4oKTtcbiAgICAgICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGZyb20pIHtcbiAgICAgICAgICAgIGlmIChpc0tleU9mKGtleSwgZnJvbSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB3cml0ZUtleVJlc3VsdCA9IG9wdGlvbnMua2V5Q29udmVydGVyPy5jb252ZXJ0KGtleSwgY29udGV4dCkgPz8gc3VjY2VlZChrZXkpO1xuXG4gICAgICAgICAgICAgICAgd3JpdGVLZXlSZXN1bHQub25TdWNjZXNzKCh3cml0ZUtleSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udmVydGVyLmNvbnZlcnQoZnJvbVtrZXldIGFzIHVua25vd24sIGNvbnRleHQpLm9uU3VjY2VzcygodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcC5zZXQod3JpdGVLZXksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWNjZWVkKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KS5vbkZhaWx1cmUoKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JzLnB1c2gobWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWlsKG1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChlcnJvcnMubGVuZ3RoID09PSAwKSB8fCAob3B0aW9ucy5vbkVycm9yID09PSAnaWdub3JlJylcbiAgICAgICAgICAgID8gc3VjY2VlZChtYXApXG4gICAgICAgICAgICA6IGZhaWwoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlICBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIHZhbGlkYXRlcyB0aGF0IGEgc3VwcGxpZWQgdmFsdWUgaXNcbiAqIG9mIGEgdHlwZSB2YWxpZGF0ZWQgYnkgYSBzdXBwbGllZCB2YWxpZGF0b3IgZnVuY3Rpb24gYW5kIHJldHVybnMgaXQuXG4gKiBAcmVtYXJrc1xuICogSWYgYHZhbGlkYXRvcmAgc3VjY2VlZHMsIHRoaXMge0BsaW5rIENvbnZlcnRlcn0gcmV0dXJucyB7QGxpbmsgU3VjY2Vzc30gd2l0aCB0aGUgc3VwcGxpZWRcbiAqIHZhbHVlIG9mIGBmcm9tYCBjb2VyY2VkIHRvIHR5cGUgYDxUPmAuICBSZXR1cm5zIGEge0BsaW5rIEZhaWx1cmV9IHdpdGggYWRkaXRpb25hbFxuICogaW5mb3JtYXRpb24gb3RoZXJ3aXNlLlxuICogQHBhcmFtIHZhbGlkYXRvciAtIEEgdmFsaWRhdG9yIGZ1bmN0aW9uIHRvIGRldGVybWluZSBpZiB0aGUgY29udmVydGVkIHZhbHVlIGlzIHZhbGlkLlxuICogQHBhcmFtIGRlc2NyaXB0aW9uIC0gQSBkZXNjcmlwdGlvbiBvZiB0aGUgdmFsaWRhdGVkIHR5cGUgZm9yIHVzZSBpbiBlcnJvciBtZXNzYWdlcy5cbiAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBDb252ZXJ0ZXIgfCBDb252ZXJ0ZXI8VD59IHdoaWNoIGFwcGxpZXMgdGhlIHN1cHBsaWVkIHZhbGlkYXRpb24uXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVdpdGg8VCwgVEM9dW5kZWZpbmVkPih2YWxpZGF0b3I6IChmcm9tOiB1bmtub3duKSA9PiBmcm9tIGlzIFQsIGRlc2NyaXB0aW9uPzogc3RyaW5nKTogQ29udmVydGVyPFQsIFRDPiB7XG4gICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyKChmcm9tOiB1bmtub3duLCBfc2VsZjogQ29udmVydGVyPFQsIFRDPiwgX2NvbnRleHQ/OiBUQykgPT4ge1xuICAgICAgICBpZiAodmFsaWRhdG9yKGZyb20pKSB7XG4gICAgICAgICAgICByZXR1cm4gc3VjY2VlZChmcm9tKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFpbChgJHtKU09OLnN0cmluZ2lmeShmcm9tKX06IGludmFsaWQgJHtkZXNjcmlwdGlvbiA/PyAndmFsdWUnfWApO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGV4dHJhY3RzIGFuZCBjb252ZXJ0cyBhbiBlbGVtZW50IGZyb20gYW4gYXJyYXkuXG4gKiBAcmVtYXJrc1xuICogVGhlIHJldHVybmVkIHtAbGluayBDb252ZXJ0ZXJ9IHJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggdGhlIGNvbnZlcnRlZCB2YWx1ZSBpZiB0aGUgZWxlbWVudCBleGlzdHNcbiAqIGluIHRoZSBzdXBwbGllZCBhcnJheSBhbmQgY2FuIGJlIGNvbnZlcnRlZC4gUmV0dXJucyB7QGxpbmsgRmFpbHVyZX0gd2l0aCBhbiBlcnJvciBtZXNzYWdlIG90aGVyd2lzZS5cbiAqIEBwYXJhbSBpbmRleCAtIFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byBiZSBleHRyYWN0ZWQuXG4gKiBAcGFyYW0gY29udmVydGVyIC0gQSB7QGxpbmsgQ29udmVydGVyfSB1c2VkIHRvIGNvbnZlcnQgdGhlIGV4dHJhY3RlZCBlbGVtZW50LlxuICogQHJldHVybnMgQSB7QGxpbmsgQ29udmVydGVyIHwgQ29udmVydGVyPFQ+fSB3aGljaCBleHRyYWN0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgZnJvbSBhbiBhcnJheS5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVsZW1lbnQ8VCwgVEM9dW5kZWZpbmVkPihpbmRleDogbnVtYmVyLCBjb252ZXJ0ZXI6IENvbnZlcnRlcjxULCBUQz4pOiBDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VCwgVEM+LCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYCR7aW5kZXh9OiBjYW5ub3QgY29udmVydCBmb3IgYSBuZWdhdGl2ZSBlbGVtZW50IGluZGV4YCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIUFycmF5LmlzQXJyYXkoZnJvbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKCdlbGVtZW50IGNvbnZlcnRlcjogc291cmNlIGlzIG5vdCBhbiBhcnJheScpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGluZGV4ID49IGZyb20ubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFpbChgJHtpbmRleH06IGVsZW1lbnQgY29udmVydGVyIGluZGV4IG91dCBvZiByYW5nZSAoMC4uJHtmcm9tLmxlbmd0aCAtIDF9KWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb252ZXJ0ZXIuY29udmVydChmcm9tW2luZGV4XSwgY29udGV4dCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggZXh0cmFjdHMgYW5kIGNvbnZlcnRzIGFuIG9wdGlvbmFsIGVsZW1lbnQgZnJvbSBhbiBhcnJheS5cbiAqIEByZW1hcmtzXG4gKiBUaGUgcmVzdWx0aW5nIHtAbGluayBDb252ZXJ0ZXJ9IHJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggdGhlIGNvbnZlcnRlZCB2YWx1ZSBpZiB0aGUgZWxlbWVudCBleHNpc3RcbiAqIGluIHRoZSBzdXBwbGllZCBhcnJheSBhbmQgY2FuIGJlIGNvbnZlcnRlZC4gUmV0dXJucyB7QGxpbmsgU3VjY2Vzc30gd2l0aCB2YWx1ZSBgdW5kZWZpbmVkYCBpZiB0aGUgcGFyYW1ldGVyXG4gKiBpcyBhbiBhcnJheSBidXQgdGhlIGluZGV4IGlzIG91dCBvZiByYW5nZS4gUmV0dXJucyB7QGxpbmsgRmFpbHVyZX0gd2l0aCBhIG1lc3NhZ2UgaWYgdGhlIHN1cHBsaWVkIHBhcmFtZXRlclxuICogaXMgbm90IGFuIGFycmF5LCBpZiB0aGUgcmVxdWVzdGVkIGluZGV4IGlzIG5lZ2F0aXZlLCBvciBpZiB0aGUgZWxlbWVudCBjYW5ub3QgYmUgY29udmVydGVkLlxuICogQHBhcmFtIGluZGV4IC0gVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIGJlIGV4dHJhY3RlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgLSBBIHtAbGluayBDb252ZXJ0ZXJ9IHVzZWQgdG8gY29udmVydCB0aGUgZXh0cmFjdGVkIGVsZW1lbnQuXG4gKiBAcmV0dXJucyBBIHtAbGluayBDb252ZXJ0ZXIgfCBDb252ZXJ0ZXI8VD59IHdoaWNoIGV4dHJhY3RzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBmcm9tIGFuIGFycmF5LlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gb3B0aW9uYWxFbGVtZW50PFQsIFRDPXVuZGVmaW5lZD4oaW5kZXg6IG51bWJlciwgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+KTogQ29udmVydGVyPFR8dW5kZWZpbmVkLCBUQz4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxUfHVuZGVmaW5lZCwgVEM+LCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYCR7aW5kZXh9OiBjYW5ub3QgY29udmVydCBmb3IgYSBuZWdhdGl2ZSBlbGVtZW50IGluZGV4YCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIUFycmF5LmlzQXJyYXkoZnJvbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKCdlbGVtZW50IGNvbnZlcnRlcjogc291cmNlIGlzIG5vdCBhbiBhcnJheScpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGluZGV4ID49IGZyb20ubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gc3VjY2VlZCh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb252ZXJ0ZXIuY29udmVydChmcm9tW2luZGV4XSwgY29udGV4dCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggZXh0cmFjdHMgYW5kIGNvbnZlcnQgYSBwcm9wZXJ0eSBzcGVjaWZpZWRcbiAqIGJ5IG5hbWUgZnJvbSBhbiBvYmplY3QuXG4gKiBAcmVtYXJrc1xuICogVGhlIHJlc3VsdGluZyB7QGxpbmsgQ29udmVydGVyfSByZXR1cm5zIHtAbGluayBTdWNjZXNzfSB3aXRoIHRoZSBjb252ZXJ0ZWQgdmFsdWUgb2YgdGhlIGNvcnJlcHNvbmRpbmdcbiAqIG9iamVjdCBwcm9wZXJ0eSBpZiB0aGUgZmllbGQgZXhpc3RzIGFuZCBjYW4gYmUgY29udmVydGVkLiBSZXR1cm5zIHtAbGluayBGYWlsdXJlfSB3aXRoIGFuIGVycm9yIG1lc3NhZ2VcbiAqIG90aGVyd2lzZS5cbiAqIEBwYXJhbSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGJlIGV4dHJhY3RlZC5cbiAqIEBwYXJhbSBjb252ZXJ0ZXIgLSB7QGxpbmsgQ29udmVydGVyfSB1c2VkIHRvIGNvbnZlcnQgdGhlIGV4dHJhY3RlZCBmaWVsZC5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpZWxkPFQsIFRDPXVuZGVmaW5lZD4obmFtZTogc3RyaW5nLCBjb252ZXJ0ZXI6IENvbnZlcnRlcjxULCBUQz4pOiBDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmOiBDb252ZXJ0ZXI8VCwgVEM+LCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBmcm9tID09PSAnb2JqZWN0JyAmJiAoIUFycmF5LmlzQXJyYXkoZnJvbSkpICYmIGZyb20gIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChpc0tleU9mKG5hbWUsIGZyb20pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnZlcnRlci5jb252ZXJ0KGZyb21bbmFtZV0sIGNvbnRleHQpLm9uRmFpbHVyZSgobWVzc2FnZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFpbChgRmllbGQgJHtuYW1lfTogJHttZXNzYWdlfWApO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYEZpZWxkICR7bmFtZX0gbm90IGZvdW5kIGluOiAke0pTT04uc3RyaW5naWZ5KGZyb20pfWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWlsKGBDYW5ub3QgY29udmVydCBmaWVsZCBcIiR7bmFtZX1cIiBmcm9tIG5vbi1vYmplY3QgJHtKU09OLnN0cmluZ2lmeShmcm9tKX1gKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBIGhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBleHRyYWN0cyBhbmQgY29udmVydCBhIHByb3BlcnR5IHNwZWNpZmllZFxuICogYnkgbmFtZSBmcm9tIGFuIG9iamVjdC5cbiAqIEByZW1hcmtzXG4gKiBUaGUgcmVzdWx0aW5nIHtAbGluayBDb252ZXJ0ZXJ9IHJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggdGhlIGNvbnZlcnRlZCB2YWx1ZSBvZiB0aGUgY29ycmVwc29uZGluZ1xuICogb2JqZWN0IHByb3BlcnR5IGlmIHRoZSBmaWVsZCBleGlzdHMgYW5kIGNhbiBiZSBjb252ZXJ0ZWQuIFJldHVybnMge0BsaW5rIFN1Y2Nlc3N9IHdpdGggdmFsdWUgYHVuZGVmaW5lZGBcbiAqIGlmIHRoZSBzdXBwbGllZCBwYXJhbWV0ciBpcyBhbiBvYmplY3QgYnV0IHRoZSBuYW1lZCBmaWVsZCBpcyBub3QgcHJlc2VudC4gIFJldHVybnMge0BsaW5rIEZhaWx1cmV9IHdpdGhcbiAqIGFuIGVycm9yIG1lc3NhZ2Ugb3RoZXJ3aXNlLlxuICogQHBhcmFtIG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgZmllbGQgdG8gYmUgZXh0cmFjdGVkLlxuICogQHBhcmFtIGNvbnZlcnRlciAtIHtAbGluayBDb252ZXJ0ZXJ9IHVzZWQgdG8gY29udmVydCB0aGUgZXh0cmFjdGVkIGZpZWxkLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gb3B0aW9uYWxGaWVsZDxULCBUQz11bmRlZmluZWQ+KG5hbWU6IHN0cmluZywgY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+KTogQ29udmVydGVyPFR8dW5kZWZpbmVkLCBUQz4ge1xuICAgIHJldHVybiBuZXcgQmFzZUNvbnZlcnRlcigoZnJvbTogdW5rbm93biwgX3NlbGY6IENvbnZlcnRlcjxUfHVuZGVmaW5lZCwgVEM+LCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBmcm9tID09PSAnb2JqZWN0JyAmJiAoIUFycmF5LmlzQXJyYXkoZnJvbSkpICYmIGZyb20gIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChpc0tleU9mKG5hbWUsIGZyb20pKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gY29udmVydGVyLmNvbnZlcnQoZnJvbVtuYW1lXSwgY29udGV4dCkub25GYWlsdXJlKChtZXNzYWdlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWlsKGAke25hbWV9OiAke21lc3NhZ2V9YCk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAvLyBpZiBjb252ZXJzaW9uIHdhcyBzdWNjZXNzZnVsIG9yIGlucHV0IHdhcyB1bmRlZmluZWQgd2VcbiAgICAgICAgICAgICAgICAvLyBzdWNjZWVkIHdpdGggJ3VuZGVmaW5lZCcsIGJ1dCB3ZSBwcm9wYWdhdGUgYWN0dWFsXG4gICAgICAgICAgICAgICAgLy8gZmFpbHVyZXMuXG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSB8fCAoZnJvbVtuYW1lXSAhPT0gdW5kZWZpbmVkKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdWNjZWVkKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhaWwoYENhbm5vdCBjb252ZXJ0IGZpZWxkIFwiJHtuYW1lfVwiIGZyb20gbm9uLW9iamVjdCAke0pTT04uc3RyaW5naWZ5KGZyb20pfWApO1xuICAgIH0sIHVuZGVmaW5lZCwgeyBpc09wdGlvbmFsOiB0cnVlIH0pO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGFuIHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlciB8IE9iamVjdENvbnZlcnRlcn0uXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT2JqZWN0Q29udmVydGVyT3B0aW9uczxUPiB7XG4gICAgLyoqXG4gICAgICogSWYgcHJlc2VudCwgbGlzdHMgb3B0aW9uYWwgZmllbGRzLiBNaXNzaW5nIG5vbi1vcHRpb25hbCBmaWVsZHMgY2F1c2UgYW4gZXJyb3IuXG4gICAgICovXG4gICAgb3B0aW9uYWxGaWVsZHM/OiAoa2V5b2YgVClbXTtcbiAgICAvKipcbiAgICAgKiBJZiB0cnVlLCB1bnJlY29nbml6ZWQgZmllbGRzIHlpZWxkIGFuIGVycm9yLiAgSWYgZmFsc2Ugb3IgdW5kZWZpbmVkIChkZWZhdWx0KSxcbiAgICAgKiB1bnJlY29nbml6ZWQgZmllbGRzIGFyZSBpZ25vcmVkLlxuICAgICAqL1xuICAgIHN0cmljdD86IGJvb2xlYW47XG59XG5cbi8qKlxuICogUGVyLXByb3BlcnR5IGNvbnZlcnRlcnMgZm9yIGVhY2ggb2YgdGhlIHByb3BlcnRpZXMgaW4gdHlwZSBULlxuICogQHJlbWFya3NcbiAqIFVzZWQgdG8gY29uc3RydWN0IGEge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyIHwgT2JqZWN0Q29udmVydGVyfVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgdHlwZSBGaWVsZENvbnZlcnRlcnM8VCwgVEM9dW5rbm93bj4gPSB7IFsga2V5IGluIGtleW9mIFQgXTogQ29udmVydGVyPFRba2V5XSwgVEM+IH07XG5cbi8qKlxuICogQSB7QGxpbmsgQ29udmVydGVyfSB3aGljaCBjb252ZXJ0cyBhbiBvYmplY3Qgb2YgdHlwZSBgPFQ+YCB3aXRob3V0IGNoYW5naW5nIHNoYXBlLCBnaXZlblxuICogYSB7QGxpbmsgQ29udmVydGVycy5GaWVsZENvbnZlcnRlcnMgfCBGaWVsZENvbnZlcnRlcnM8VD59IGZvciB0aGUgZmllbGRzIGluIHRoZSBvYmplY3QuXG4gKiBAcmVtYXJrc1xuICogQnkgZGVmYXVsdCwgaWYgYWxsIG9mIHRoZSByZXF1aXJlZCBmaWVsZHMgZXhpc3QgYW5kIGNhbiBiZSBjb252ZXJ0ZWQsIHJldHVybnMgYSBuZXcgb2JqZWN0IHdpdGhcbiAqIHRoZSBjb252ZXJ0ZWQgdmFsdWVzIHVuZGVyIHRoZSBvcmlnaW5hbCBrZXkgbmFtZXMuICBJZiBhbnkgcmVxdWlyZWQgZmllbGRzIGRvIG5vdCBleGlzdCBvciBjYW5ub3RcbiAqIGJlIGNvbnZlcnRlZCwgdGhlIGVudGlyZSBjb252ZXJzaW9uIGZhaWxzLiBTZWUge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyT3B0aW9ucyB8IE9iamVjdENvbnZlcnRlck9wdGlvbnN9XG4gKiBmb3Igb3RoZXIgY29udmVyc2lvbiBvcHRpb25zLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY2xhc3MgT2JqZWN0Q29udmVydGVyPFQsIFRDPXVua25vd24+IGV4dGVuZHMgQmFzZUNvbnZlcnRlcjxULCBUQz4ge1xuICAgIC8qKlxuICAgICAqIEZpZWxkcyBjb252ZXJ0ZWQgYnkgdGhpcyB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIgfCBPYmplY3RDb252ZXJ0ZXJ9LlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBmaWVsZHM6IEZpZWxkQ29udmVydGVyczxUPjtcbiAgICAvKipcbiAgICAgKiBPcHRpb25zIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlciB8IE9iamVjdENvbnZlcnRlcn0uXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IG9wdGlvbnM6IE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD47XG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlciB8IE9iamVjdENvbnZlcnRlcjxUPn0gdXNpbmcgb3B0aW9uc1xuICAgICAqIHN1cHBsaWVkIGluIGEge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyT3B0aW9ucyB8IE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD59LlxuICAgICAqIEBwYXJhbSBmaWVsZHMgLSBBIHtAbGluayBDb252ZXJ0ZXJzLkZpZWxkQ29udmVydGVycyB8IEZpZWxkQ29udmVydGVyczxUPn0gY29udGFpbmluZ1xuICAgICAqIGEge0BsaW5rIENvbnZlcnRlcn0gZm9yIGVhY2ggZmllbGRcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIEBzZWUgT2JqZWN0Q29udmVydGVyT3B0aW9ucyB0byBjb25maWd1cmUgdGhlIGNvbnZlcnNpb25cbiAgICAgKiB7QGxhYmVsIHdpdGhPcHRpb25zfVxuICAgICAqL1xuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihmaWVsZHM6IEZpZWxkQ29udmVydGVyczxULCBUQz4sIG9wdGlvbnM/OiBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+KVxuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIgfCBPYmplY3RDb252ZXJ0ZXI8VD59IHdpdGggb3B0aW9uYWxcbiAgICAgKiBwcm9wZXJ0aWVzIHNwZWNpZmllZCBhcyBhbiBhcnJheSBvZiBga2V5b2YgVGAuXG4gICAgICogQHBhcmFtIGZpZWxkcyAtIEEge0BsaW5rIENvbnZlcnRlcnMuRmllbGRDb252ZXJ0ZXJzIHwgRmllbGRDb252ZXJ0ZXJzPFQ+fSBjb250YWluaW5nXG4gICAgICogYSB7QGxpbmsgQ29udmVydGVyfSBmb3IgZWFjaCBmaWVsZC5cbiAgICAgKiBAcGFyYW0gb3B0aW9uYWwgLSBBbiBhcnJheSBvZiBga2V5b2YgVGAgbGlzdGluZyBmaWVsZHMgdGhhdCBhcmUgbm90IHJlcXVpcmVkLlxuICAgICAqIHtAbGFiZWwgd2l0aEtleXN9XG4gICAgICovXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKGZpZWxkczogRmllbGRDb252ZXJ0ZXJzPFQsIFRDPiwgb3B0aW9uYWw/OiAoa2V5b2YgVClbXSk7XG4gICAgLyoqXG4gICAgICogQ29uY3JldGUgaW1wbGVtZW50YXRpb24gb2Yge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyLihjb25zdHJ1Y3Rvcjp3aXRoT3B0aW9ucyl9XG4gICAgICogYW5kIHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlci4oY29uc3RydWN0b3I6d2l0aEtleXMpfS5cbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgY29uc3RydWN0b3IoZmllbGRzOiBGaWVsZENvbnZlcnRlcnM8VCwgVEM+LCBvcHQ/OiBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+fChrZXlvZiBUKVtdKSB7XG4gICAgICAgIHN1cGVyKChmcm9tOiB1bmtub3duLCBfc2VsZiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgICAgICAvLyBlc2xpbnQgYnVnIHRoaW5rcyBrZXkgaXMgdXNlZCBiZWZvcmUgZGVmaW5lZFxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZS1iZWZvcmUtZGVmaW5lXG4gICAgICAgICAgICBjb25zdCBjb252ZXJ0ZWQgPSB7fSBhcyB7IFtrZXkgaW4ga2V5b2YgVF06IFRba2V5XSB9O1xuICAgICAgICAgICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZmllbGRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZpZWxkc1trZXldKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlzT3B0aW9uYWwgPSAoZmllbGRzW2tleV0uaXNPcHRpb25hbCB8fCB0aGlzLm9wdGlvbnMub3B0aW9uYWxGaWVsZHM/LmluY2x1ZGVzKGtleSkpID8/IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBpc09wdGlvbmFsXG4gICAgICAgICAgICAgICAgICAgICAgICA/IG9wdGlvbmFsRmllbGQoa2V5LCBmaWVsZHNba2V5XSkuY29udmVydChmcm9tLCBjb250ZXh0KVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBmaWVsZChrZXksIGZpZWxkc1trZXldKS5jb252ZXJ0KGZyb20sIGNvbnRleHQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmlzU3VjY2VzcygpICYmIChyZXN1bHQudmFsdWUgIT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnRlZFtrZXldID0gcmVzdWx0LnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJlc3VsdC5pc0ZhaWx1cmUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JzLnB1c2gocmVzdWx0Lm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnN0cmljdCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIGlmICgodHlwZW9mIGZyb20gPT09ICdvYmplY3QnKSAmJiAoIUFycmF5LmlzQXJyYXkoZnJvbSkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIGZyb20pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmcm9tLmhhc093blByb3BlcnR5KGtleSkgJiYgKCFpc0tleU9mKGtleSwgZmllbGRzKSB8fCAoZmllbGRzW2tleV0gPT09IHVuZGVmaW5lZCkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JzLnB1c2goYCR7a2V5fTogdW5leHBlY3RlZCBwcm9wZXJ0eSBpbiBzb3VyY2Ugb2JqZWN0YCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9ycy5wdXNoKCdzb3VyY2UgaXMgbm90IGFuIG9iamVjdCcpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAoZXJyb3JzLmxlbmd0aCA9PT0gMCkgPyBzdWNjZWVkKGNvbnZlcnRlZCkgOiBmYWlsKGVycm9ycy5qb2luKCdcXG4nKSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuZmllbGRzID0gZmllbGRzO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShvcHQpKSB7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMgPSB7IG9wdGlvbmFsRmllbGRzOiBvcHQgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdCA/PyB7fTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyIHwgT2JqZWN0Q29udmVydGVyfSBkZXJpdmVkIGZyb20gdGhpcyBvbmUgYnV0IHdpdGhcbiAgICAgKiBuZXcgb3B0aW9uYWwgcHJvcGVydGllcyBhcyBzcGVjaWZpZWQgYnkgYSBzdXBwbGllZCB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXJPcHRpb25zIHwgT2JqZWN0Q29udmVydGVyT3B0aW9uczxUPn0uXG4gICAgICogQHBhcmFtIG9wdGlvbnMgLSBUaGUge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyT3B0aW9ucyB8IG9wdGlvbnN9IHRvIGJlIGFwcGxpZWQgdG8gdGhlIG5ld1xuICAgICAqIGNvbnZlcnRlci5cbiAgICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIgfCBPYmplY3RDb252ZXJ0ZXJ9IHdpdGggdGhlIGFkZGl0aW9uYWwgb3B0aW9uYWwgc291cmNlIHByb3BlcnRpZXMuXG4gICAgICoge0BsYWJlbCB3aXRoT3B0aW9uc31cbiAgICAgKi9cbiAgICBwdWJsaWMgcGFydGlhbChvcHRpb25zOiBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+KTogT2JqZWN0Q29udmVydGVyPFBhcnRpYWw8VD4sIFRDPjtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyIHwgT2JqZWN0Q29udmVydGVyfSBkZXJpdmVkIGZyb20gdGhpcyBvbmUgYnV0IHdpdGhcbiAgICAgKiBuZXcgb3B0aW9uYWwgcHJvcGVydGllcyBhcyBzcGVjaWZpZWQgYnkgYSBzdXBwbGllZCBhcnJheSBvZiBga2V5b2YgVGAuXG4gICAgICogQHBhcmFtIG9wdGlvbmFsIC0gVGhlIGtleXMgb2YgdGhlIHNvdXJjZSBvYmplY3QgcHJvcGVydGllcyB0byBiZSBtYWRlIG9wdGlvbmFsLlxuICAgICAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlciB8IE9iamVjdENvbnZlcnRlcn0gd2l0aCB0aGUgYWRkaXRpb25hbCBvcHRpb25hbCBzb3VyY2VcbiAgICAgKiBwcm9wZXJ0aWVzLlxuICAgICAqIHtAbGFiZWwgd2l0aEtleXN9XG4gICAgICovXG4gICAgcHVibGljIHBhcnRpYWwob3B0aW9uYWw/OiAoa2V5b2YgVClbXSk6IE9iamVjdENvbnZlcnRlcjxQYXJ0aWFsPFQ+LCBUQz47XG4gICAgLyoqXG4gICAgICogQ29uY3JldGUgaW1wbGVtZW50YXRpb24gb2ZcbiAgICAgKiB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIuKHBhcnRpYWw6d2l0aE9wdGlvbnMpIHwgT2JqZWN0Q29udmVydGVyLnBhcnRpYWwoT2JqZWN0Q29udmVydGVyT3B0aW9ucyl9IGFuZFxuICAgICAqIHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlci4ocGFydGlhbDp3aXRoS2V5cykgfCBPYmplY3RDb252ZXJ0ZXIucGFydGlhbCgoa2V5b2YgVClbXX0uXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHBhcnRpYWwob3B0PzogT2JqZWN0Q29udmVydGVyT3B0aW9uczxUPnwoa2V5b2YgVClbXSk6IE9iamVjdENvbnZlcnRlcjxQYXJ0aWFsPFQ+LCBUQz4ge1xuICAgICAgICByZXR1cm4gbmV3IE9iamVjdENvbnZlcnRlcjxQYXJ0aWFsPFQ+LCBUQz4odGhpcy5maWVsZHMgYXMgRmllbGRDb252ZXJ0ZXJzPFBhcnRpYWw8VD4sIFRDPiwgb3B0IGFzIE9iamVjdENvbnZlcnRlck9wdGlvbnM8UGFydGlhbDxUPj4pLl93aXRoKHRoaXMuX3RyYWl0cygpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlciB8IE9iamVjdENvbnZlcnRlcn0gZGVyaXZlZCBmcm9tIHRoaXMgb25lIGJ1dCB3aXRoXG4gICAgICogbmV3IG9wdGlvbmFsIHByb3BlcnRpZXMgYXMgc3BlY2lmaWVkIGJ5IGEgc3VwcGxpZWQgYXJyYXkgb2YgYGtleW9mIFRgLlxuICAgICAqIEBwYXJhbSBhZGRPcHRpb25hbFByb3BlcnRpZXMgLSBUaGUga2V5cyB0byBiZSBtYWRlIG9wdGlvbmFsLlxuICAgICAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlciB8IE9iamVjdENvbnZlcnRlcn0gd2l0aCB0aGUgYWRkaXRpb25hbCBvcHRpb25hbCBzb3VyY2VcbiAgICAgKiBwcm9wZXJ0aWVzLlxuICAgICAqL1xuICAgIHB1YmxpYyBhZGRQYXJ0aWFsKGFkZE9wdGlvbmFsUHJvcGVydGllczogKGtleW9mIFQpW10pOiBPYmplY3RDb252ZXJ0ZXI8UGFydGlhbDxUPiwgVEM+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFydGlhbChbLi4udGhpcy5vcHRpb25zLm9wdGlvbmFsRmllbGRzID8/IFtdLCAuLi5hZGRPcHRpb25hbFByb3BlcnRpZXNdKS5fd2l0aCh0aGlzLl90cmFpdHMoKSk7XG4gICAgfVxufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYSB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIgfCBPYmplY3RDb252ZXJ0ZXI8VD59IHdoaWNoIGNvbnZlcnRzIGFuIG9iamVjdFxuICogd2l0aG91dCBjaGFuZ2luZyBzaGFwZSwgZ2l2ZW4gYSB7QGxpbmsgQ29udmVydGVycy5GaWVsZENvbnZlcnRlcnMgfCBGaWVsZENvbnZlcnRlcnM8VD59IGFuZCBhbiBvcHRpb25hbFxuICoge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyT3B0aW9ucyB8IE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD59IHRvIGZ1cnRoZXIgcmVmaW5lIGNvbnZlcnNpb24gYmVhdmlvci5cbiAqIEByZW1hcmtzXG4gKiBCeSBkZWZhdWx0LCBpZiBhbGwgb2YgdGhlIHJlcXVlc3RlZCBmaWVsZHMgZXhpc3QgYW5kIGNhbiBiZSBjb252ZXJ0ZWQsIHJldHVybnMge0BsaW5rIFN1Y2Nlc3N9XG4gKiB3aXRoIGEgbmV3IG9iamVjdCB0aGF0IGNvbnRhaW5zIHRoZSBjb252ZXJ0ZWQgdmFsdWVzIHVuZGVyIHRoZSBvcmlnaW5hbCBrZXkgbmFtZXMuICBJZiBhbnkgcmVxdXJpZWQgcHJvcGVydGllc1xuICogZG8gbm90IGV4aXN0IG9yIGNhbm5vdCBiZSBjb252ZXJ0ZWQsIHRoZSBlbnRpcmUgY29udmVyc2lvbiBmYWlscywgcmV0dXJuaW5nIHtAbGluayBGYWlsdXJlfSB3aXRoIGFkZGl0aW9uYWxcbiAqIGVycm9yIGluZm9ybWF0aW9uLlxuICpcbiAqIEZpZWxkcyB0aGF0IHN1Y2NlZWQgYnV0IGNvbnZlcnQgdG8gdW5kZWZpbmVkIGFyZSBvbWl0dGVkIGZyb20gdGhlIHJlc3VsdCBvYmplY3QgYnV0IGRvIG5vdFxuICogZmFpbCB0aGUgY29udmVyc2lvbi5cbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gQW4ge0BsaW5rIENvbnZlcnRlcnMuRmllbGRDb252ZXJ0ZXJzIHwgRmllbGRDb252ZXJ0ZXJzPFQ+fSBkZWZpbmluZyB0aGUgc2hhcGUgb2YgdGhlXG4gKiBzb3VyY2Ugb2JqZWN0IGFuZCB7QGxpbmsgQ29udmVydGVyIHwgY29udmVydGVyc30gdG8gYmUgYXBwbGllZCB0byBlYWNoIHByb3BlcnRpZXMuXG4gKiBAcGFyYW0gb3B0aW9ucyAtIEFuIHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlck9wdGlvbnMgfCBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+fSBjb250YWluaW5nIG9wdGlvbnNcbiAqIGZvciB0aGUgb2JqZWN0IGNvbnZlcnRlci5cbiAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlciB8IE9iamVjdENvbnZlcnRlcn0gd2hpY2ggYXBwbGllcyB0aGUgc3BlY2lmaWVkIGNvbnZlcnNpb25zLlxuICoge0BsYWJlbCB3aXRoT3B0aW9uc31cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9iamVjdDxUPihwcm9wZXJ0aWVzOiBGaWVsZENvbnZlcnRlcnM8VD4sIG9wdGlvbnM/OiBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+KTogT2JqZWN0Q29udmVydGVyPFQ+O1xuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYSB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIgfCBPYmplY3RDb252ZXJ0ZXI8VD59IHdoaWNoIGNvbnZlcnRzIGFuIG9iamVjdFxuICogd2l0aG91dCBjaGFuZ2luZyBzaGFwZSwgZ2l2ZW4gYSB7QGxpbmsgQ29udmVydGVycy5GaWVsZENvbnZlcnRlcnMgfCBGaWVsZENvbnZlcnRlcnM8VD59IGFuZCBhIHNldCBvZlxuICogb3B0aW9uYWwgcHJvcGVydGllcy5cbiAqIEByZW1hcmtzXG4gKiBCeSBkZWZhdWx0LCBpZiBhbGwgb2YgdGhlIHJlcXVlc3RlZCBmaWVsZHMgZXhpc3QgYW5kIGNhbiBiZSBjb252ZXJ0ZWQsIHJldHVybnMge0BsaW5rIFN1Y2Nlc3N9XG4gKiB3aXRoIGEgbmV3IG9iamVjdCB0aGF0IGNvbnRhaW5zIHRoZSBjb252ZXJ0ZWQgdmFsdWVzIHVuZGVyIHRoZSBvcmlnaW5hbCBrZXkgbmFtZXMuICBJZiBhbnkgcmVxdXJpZWQgcHJvcGVydGllc1xuICogZG8gbm90IGV4aXN0IG9yIGNhbm5vdCBiZSBjb252ZXJ0ZWQsIHRoZSBlbnRpcmUgY29udmVyc2lvbiBmYWlscywgcmV0dXJuaW5nIHtAbGluayBGYWlsdXJlfSB3aXRoIGFkZGl0aW9uYWxcbiAqIGVycm9yIGluZm9ybWF0aW9uLlxuICpcbiAqIEZpZWxkcyB0aGF0IHN1Y2NlZWQgYnV0IGNvbnZlcnQgdG8gdW5kZWZpbmVkIGFyZSBvbWl0dGVkIGZyb20gdGhlIHJlc3VsdCBvYmplY3QgYnV0IGRvIG5vdFxuICogZmFpbCB0aGUgY29udmVyc2lvbi5cbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gQW4ge0BsaW5rIENvbnZlcnRlcnMuRmllbGRDb252ZXJ0ZXJzIHwgRmllbGRDb252ZXJ0ZXJzPFQ+fSBkZWZpbmluZyB0aGUgc2hhcGUgb2YgdGhlXG4gKiBzb3VyY2Ugb2JqZWN0IGFuZCB7QGxpbmsgQ29udmVydGVyIHwgY29udmVydGVyc30gdG8gYmUgYXBwbGllZCB0byBlYWNoIHByb3BlcnRpZXMuXG4gKiBAcGFyYW0gb3B0aW9uYWwgLSBBbiBhcnJheSBvZiBgKGtleW9mIFQpYCBsaXN0aW5nIHRoZSBrZXlzIHRvIGJlIGNvbnNpZGVyZWQgb3B0aW9uYWwuXG4gKiB7QGxhYmVsIHdpdGhLZXlzfVxuICogQHJldHVybnMgQSBuZXcge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyIHwgT2JqZWN0Q29udmVydGVyfSB3aGljaCBhcHBsaWVzIHRoZSBzcGVjaWZpZWQgY29udmVyc2lvbnMuXG4gKiBAcHVibGljXG4gKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rIENvbnZlcnRlcnMuKG9iamVjdDp3aXRoT3B0aW9ucykgfCBDb252ZXJ0ZXJzLm9iamVjdChmaWVsZHMsIG9wdGlvbnMpfSBpbnN0ZWFkLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBvYmplY3Q8VD4ocHJvcGVydGllczogRmllbGRDb252ZXJ0ZXJzPFQ+LCBvcHRpb25hbDogKGtleW9mIFQpW10pOiBPYmplY3RDb252ZXJ0ZXI8VD47XG4vKipcbiAqIENvbmNyZXRlIGltcGxlbWVudGF0aW9uIG9mIHtAbGluayBDb252ZXJ0ZXJzLihvYmplY3Q6d2l0aE9wdGlvbnMpIHwgQ29udmVydGVycy5vYmplY3QoZmllbGRzLCBvcHRpb25zKX1cbiAqIGFuZCB7QGxpbmsgQ29udmVydGVycy4ob2JqZWN0OndpdGhLZXlzKSB8IENvbnZlcnRlcnMub2JqZWN0cyhmaWVsZHMsIG9wdGlvbmFsS2V5cyl9LlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvYmplY3Q8VD4ocHJvcGVydGllczogRmllbGRDb252ZXJ0ZXJzPFQ+LCBvcHRpb25zPzogKGtleW9mIFQpW118T2JqZWN0Q29udmVydGVyT3B0aW9uczxUPik6IE9iamVjdENvbnZlcnRlcjxUPiB7XG4gICAgcmV0dXJuIG5ldyBPYmplY3RDb252ZXJ0ZXIocHJvcGVydGllcywgb3B0aW9ucyBhcyBPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+KTtcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciB0aGUge0BsaW5rIENvbnZlcnRlcnMuKHN0cmljdE9iamVjdDp3aXRoT3B0aW9ucyl9IGhlbHBlciBmdW5jdGlvbi5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IHR5cGUgU3RyaWN0T2JqZWN0Q29udmVydGVyT3B0aW9uczxUPiA9IE9taXQ8T2JqZWN0Q29udmVydGVyT3B0aW9uczxUPiwgJ3N0cmljdCc+O1xuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYSB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIgfCBPYmplY3RDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIGFuIG9iamVjdFxuICogd2l0aG91dCBjaGFuZ2luZyBzaGFwZSwgYSB7QGxpbmsgQ29udmVydGVycy5GaWVsZENvbnZlcnRlcnMgfCBGaWVsZENvbnZlcnRlcnM8VD59IGFuZCBhbiBvcHRpb25hbFxuICoge0BsaW5rIENvbnZlcnRlcnMuU3RyaWN0T2JqZWN0Q29udmVydGVyT3B0aW9ucyB8IFN0cmljdE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD59IHRvIGZ1cnRoZXIgcmVmaW5lXG4gKiBjb252ZXJzaW9uIGJlaGF2aW9yLlxuICpcbiAqIEByZW1hcmtzXG4gKiBGaWVsZHMgdGhhdCBzdWNjZWVkIGJ1dCBjb252ZXJ0IHRvIHVuZGVmaW5lZCBhcmUgb21pdHRlZCBmcm9tIHRoZSByZXN1bHQgb2JqZWN0IGJ1dCBkbyBub3RcbiAqIGZhaWwgdGhlIGNvbnZlcnNpb24uXG4gKlxuICogVGhlIGNvbnZlcnNpb24gZmFpbHMgaWYgYW55IHVuZXhwZWN0ZWQgZmllbGRzIGFyZSBlbmNvdW50ZXJlZC5cbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIEFuIG9iamVjdCBjb250YWluaW5nIGRlZmluaW5nIHRoZSBzaGFwZSBhbmQgY29udmVydGVycyB0byBiZSBhcHBsaWVkLlxuICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBAc2VlIFN0cmljdE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD4gY29udGFpbmluZyBvcHRpb25zIGZvciB0aGUgb2JqZWN0IGNvbnZlcnRlci5cbiAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBDb252ZXJ0ZXJzLk9iamVjdENvbnZlcnRlciB8IE9iamVjdENvbnZlcnRlcn0gd2hpY2ggYXBwbGllcyB0aGUgc3BlY2lmaWVkIGNvbnZlcnNpb25zLlxuICoge0BsYWJlbCB3aXRoT3B0aW9uc31cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0cmljdE9iamVjdDxUPihwcm9wZXJ0aWVzOiBGaWVsZENvbnZlcnRlcnM8VD4sIG9wdGlvbnM/OiBTdHJpY3RPYmplY3RDb252ZXJ0ZXJPcHRpb25zPFQ+KTogT2JqZWN0Q29udmVydGVyPFQ+O1xuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYSB7QGxpbmsgQ29udmVydGVycy5PYmplY3RDb252ZXJ0ZXIgfCBPYmplY3RDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIGFuIG9iamVjdFxuICogd2l0aG91dCBjaGFuZ2luZyBzaGFwZSwgYSB7QGxpbmsgQ29udmVydGVycy5GaWVsZENvbnZlcnRlcnMgfCBGaWVsZENvbnZlcnRlcnM8VD59IGFuZCBhbiBvcHRpb25hbFxuICoge0BsaW5rIENvbnZlcnRlcnMuU3RyaWN0T2JqZWN0Q29udmVydGVyT3B0aW9ucyB8IFN0cmljdE9iamVjdENvbnZlcnRlck9wdGlvbnM8VD59IHRvIGZ1cnRoZXIgcmVmaW5lXG4gKiBjb252ZXJzaW9uIGJlaGF2aW9yLlxuICpcbiAqIEByZW1hcmtzXG4gKiBGaWVsZHMgdGhhdCBzdWNjZWVkIGJ1dCBjb252ZXJ0IHRvIHVuZGVmaW5lZCBhcmUgb21pdHRlZCBmcm9tIHRoZSByZXN1bHQgb2JqZWN0IGJ1dCBkbyBub3RcbiAqIGZhaWwgdGhlIGNvbnZlcnNpb24uXG4gKlxuICogVGhlIGNvbnZlcnNpb24gZmFpbHMgaWYgYW55IHVuZXhwZWN0ZWQgZmllbGRzIGFyZSBlbmNvdW50ZXJlZC5cbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIEFuIG9iamVjdCBjb250YWluaW5nIGRlZmluaW5nIHRoZSBzaGFwZSBhbmQgY29udmVydGVycyB0byBiZSBhcHBsaWVkLlxuICogQHBhcmFtIG9wdGlvbmFsIC0gQW4gYXJyYXkgb2YgYGtleW9mIFRgIGNvbnRhaW5pbmcga2V5cyB0byBiZSBjb25zaWRlcmVkIG9wdGlvbmFsLlxuICogQHJldHVybnMgQSBuZXcge0BsaW5rIENvbnZlcnRlcnMuT2JqZWN0Q29udmVydGVyIHwgT2JqZWN0Q29udmVydGVyfSB3aGljaCBhcHBsaWVzIHRoZSBzcGVjaWZpZWQgY29udmVyc2lvbnMuXG4gKiB7QGxhYmVsIHdpdGhLZXlzfVxuICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayBDb252ZXJ0ZXJzLihzdHJpY3RPYmplY3Q6d2l0aE9wdGlvbnMpIHwgQ29udmVydGVycy5zdHJpY3RPYmplY3Qob3B0aW9ucyl9IGluc3RlYWQuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdHJpY3RPYmplY3Q8VD4ocHJvcGVydGllczogRmllbGRDb252ZXJ0ZXJzPFQ+LCBvcHRpb25hbDogKGtleW9mIFQpW10pOiBPYmplY3RDb252ZXJ0ZXI8VD47XG4vKipcbiAqIENvbmNyZXRlIGltcGxlbWVudGF0aW9uIGZvciB7QGxpbmsgQ29udmVydGVycy4oc3RyaWN0T2JqZWN0OndpdGhPcHRpb25zKSB8IENvbnZlcnRlcnMuc3RyaWN0T2JqZWN0KGZpZWxkcywgb3B0aW9ucyl9XG4gKiBhbmQge0BsaW5rIENvbnZlcnRlcnMuKHN0cmljdE9iamVjdDp3aXRoS2V5cykgfCBDb252ZXJ0ZXJzLnN0cmljdE9iamVjdChmaWVsZHMsIG9wdGlvbmFsKX0uXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0cmljdE9iamVjdDxUPihcbiAgICBwcm9wZXJ0aWVzOiBGaWVsZENvbnZlcnRlcnM8VD4sXG4gICAgb3B0PzogKGtleW9mIFQpW118U3RyaWN0T2JqZWN0Q29udmVydGVyT3B0aW9uczxUPixcbik6IE9iamVjdENvbnZlcnRlcjxUPiB7XG4gICAgY29uc3Qgb3B0aW9uczogT2JqZWN0Q29udmVydGVyT3B0aW9uczxUPiA9IChvcHQgJiYgQXJyYXkuaXNBcnJheShvcHQpKVxuICAgICAgICA/IHsgc3RyaWN0OiB0cnVlLCBvcHRpb25hbEZpZWxkczogb3B0IH1cbiAgICAgICAgOiB7IC4uLihvcHQgPz8ge30pLCBzdHJpY3Q6IHRydWUgfTtcbiAgICByZXR1cm4gbmV3IE9iamVjdENvbnZlcnRlcihwcm9wZXJ0aWVzLCBvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBBIHN0cmluZy1rZXllZCBgUmVjb3JkPHN0cmluZywgQ29udmVydGVyPmAgd2hpY2ggbWFwcyBzcGVjaWZpYyB7QGxpbmsgQ29udmVydGVyIHwgY29udmVydGVyc30gdG8gdGhlXG4gKiB2YWx1ZSBvZiBhIGRpc2NyaW1pbmF0b3IgcHJvcGVydHkuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCB0eXBlIERpc2NyaW1pbmF0ZWRPYmplY3RDb252ZXJ0ZXJzPFQsIFREIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nLCBUQz11bmtub3duPiA9IFJlY29yZDxURCwgQ29udmVydGVyPFQsIFRDPj47XG5cbi8qKlxuICogSGVscGVyIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaGljaCBjb252ZXJ0cyBhIGRpc2NyaW1pbmF0ZWQgb2JqZWN0IHdpdGhvdXQgY2hhbmdpbmcgc2hhcGUuXG4gKiBAcmVtYXJrc1xuICogVGFrZXMgdGhlIG5hbWUgb2YgdGhlIGRpc2NyaW1pbmF0b3IgcHJvcGVydHkgYW5kIGFcbiAqIHtAbGluayBDb252ZXJ0ZXJzLkRpc2NyaW1pbmF0ZWRPYmplY3RDb252ZXJ0ZXJzIHwgc3RyaW5nLWtleWVkIFJlY29yZCBvZiBjb252ZXJ0ZXJzfS4gRHVyaW5nIGNvbnZlcnNpb24sXG4gKiB0aGUgcmVzdWx0aW5nIHtAbGluayBDb252ZXJ0ZXJ9IGludm9rZXMgdGhlIGNvbnZlcnRlciBmcm9tIGBjb252ZXJ0ZXJzYCB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZSB2YWx1ZSBvZlxuICogdGhlIGRpc2NyaW1pbmF0b3IgcHJvcGVydHkgaW4gdGhlIHNvdXJjZSBvYmplY3QuXG4gKlxuICogSWYgdGhlIHNvdXJjZSBpcyBub3QgYW4gb2JqZWN0LCB0aGUgZGlzY3JpbWluYXRvciBwcm9wZXJ0eSBpcyBtaXNzaW5nLCBvciB0aGUgZGlzY3JpbWluYXRvciBoYXNcbiAqIGEgdmFsdWUgbm90IHByZXNlbnQgaW4gdGhlIGNvbnZlcnRlcnMsIGNvbnZlcnNpb24gZmFpbHMgYW5kIHJldHVybnMge0BsaW5rIEZhaWx1cmV9IHdpdGggbW9yZSBpbmZvcm1hdGlvbi5cbiAqIEBwYXJhbSBkaXNjcmltaW5hdG9yUHJvcCAtIE5hbWUgb2YgdGhlIHByb3BlcnR5IHVzZWQgdG8gZGlzY3JpbWluYXRlIHR5cGVzLlxuICogQHBhcmFtIGNvbnZlcnRlcnMgLSB7QGxpbmsgQ29udmVydGVycy5EaXNjcmltaW5hdGVkT2JqZWN0Q29udmVydGVycyB8IFN0cmluZy1rZXllZCByZWNvcmQgb2YgY29udmVydGVyc30gdG9cbiAqIGludm9rZSwgd2hlcmUgZWFjaCBrZXkgY29ycmVzcG9uZHMgdG8gYSB2YWx1ZSBvZiB0aGUgZGlzY3JpbWluYXRvciBwcm9wZXJ0eS5cbiAqIEByZXR1cm5zIEEge0BsaW5rIENvbnZlcnRlcn0gd2hpY2ggY29udmVydHMgdGhlIGNvcnJlc3BvbmRpbmcgZGlzY3JpbWluYXRlZCBvYmplY3QuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXNjcmltaW5hdGVkT2JqZWN0PFQsIFREIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nLCBUQz11bmtub3duPihkaXNjcmltaW5hdG9yUHJvcDogc3RyaW5nLCBjb252ZXJ0ZXJzOiBEaXNjcmltaW5hdGVkT2JqZWN0Q29udmVydGVyczxULCBURD4pOiBDb252ZXJ0ZXI8VCwgVEM+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24pID0+IHtcbiAgICAgICAgaWYgKCh0eXBlb2YgZnJvbSAhPT0gJ29iamVjdCcpIHx8IEFycmF5LmlzQXJyYXkoZnJvbSkgfHwgZnJvbSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhaWwoYE5vdCBhIGRpc2NyaW1pbmF0ZWQgb2JqZWN0OiBcIiR7SlNPTi5zdHJpbmdpZnkoZnJvbSl9XCJgKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoKCFpc0tleU9mKGRpc2NyaW1pbmF0b3JQcm9wLCBmcm9tKSkgfHwgKCFmcm9tW2Rpc2NyaW1pbmF0b3JQcm9wXSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWlsKGBEaXNjcmltaW5hdG9yIHByb3BlcnR5ICR7ZGlzY3JpbWluYXRvclByb3B9IG5vdCBwcmVzZW50IGluIFwiJHtKU09OLnN0cmluZ2lmeShmcm9tKX1cImApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZGlzY3JpbWluYXRvclZhbHVlID0gZnJvbVtkaXNjcmltaW5hdG9yUHJvcF0gYXMgVEQ7XG4gICAgICAgIGNvbnN0IGNvbnZlcnRlciA9IGNvbnZlcnRlcnNbZGlzY3JpbWluYXRvclZhbHVlXTtcbiAgICAgICAgaWYgKGNvbnZlcnRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFpbChgTm8gY29udmVydGVyIGZvciBkaXNjcmltaW5hdG9yICR7ZGlzY3JpbWluYXRvclByb3B9PVwiJHtkaXNjcmltaW5hdG9yVmFsdWV9XCJgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29udmVydGVyLmNvbnZlcnQoZnJvbSk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogSGVscGVyIHRvIGNyZWF0ZSBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIGEgc291cmNlIG9iamVjdCB0byBhIG5ldyBvYmplY3Qgd2l0aCBhXG4gKiBkaWZmZXJlbnQgc2hhcGUuXG4gKlxuICogQHJlbWFya3NcbiAqIE9uIHN1Y2Nlc3NmdWwgY29udmVyc2lvbiwgdGhlIHJlc3VsdGluZyB7QGxpbmsgQ29udmVydGVyfSByZXR1cm5zIHtAbGluayBTdWNjZXNzfSB3aXRoIGEgbmV3XG4gKiBvYmplY3QsIHdoaWNoIGNvbnRhaW5zIHRoZSBjb252ZXJ0ZWQgdmFsdWVzIHVuZGVyIHRoZSBrZXkgbmFtZXMgc3BlY2lmaWVkIGF0IGluaXRpYWxpemF0aW9uIHRpbWUuXG4gKiBJdCByZXR1cm5zIHtAbGluayBGYWlsdXJlfSB3aXRoIGFuIGVycm9yIG1lc3NhZ2UgaWYgYW55IGZpZWxkcyB0byBiZSBleHRyYWN0ZWQgZG8gbm90IGV4aXN0XG4gKiBvciBjYW5ub3QgYmUgY29udmVydGVkLlxuICpcbiAqIEZpZWxkcyB0aGF0IHN1Y2NlZWQgYnV0IGNvbnZlcnQgdG8gdW5kZWZpbmVkIGFyZSBvbWl0dGVkIGZyb20gdGhlIHJlc3VsdCBvYmplY3QgYnV0IGRvIG5vdFxuICogZmFpbCB0aGUgY29udmVyc2lvbi5cbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIEFuIG9iamVjdCB3aXRoIGtleSBuYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdGhlIHRhcmdldCBvYmplY3QgYW5kIGFuXG4gKiBhcHByb3ByaWF0ZSB7QGxpbmsgQ29udmVydGVycy5GaWVsZENvbnZlcnRlcnMgfCBGaWVsZENvbnZlcnRlcn0gd2hpY2ggZXh0cmFjdHMgYW5kIGNvbnZlcnRzXG4gKiBhIHNpbmdsZSBmaWxlZCBmcm9tIHRoZSBzb3VyY2Ugb2JqZWN0LlxuICogQHJldHVybnMgQSB7QGxpbmsgQ29udmVydGVyfSB3aXRoIHRoZSBzcGVjaWZpZWQgY29udmVyc2lvbiBiZWhhdmlvci5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybTxULCBUQz11bmtub3duPihwcm9wZXJ0aWVzOiBGaWVsZENvbnZlcnRlcnM8VCwgVEM+KTogQ29udmVydGVyPFQsIFRDPiB7XG4gICAgcmV0dXJuIG5ldyBCYXNlQ29udmVydGVyKChmcm9tOiB1bmtub3duLCBfc2VsZiwgY29udGV4dD86IFRDKSA9PiB7XG4gICAgICAgIC8vIGVzbGludCBidWcgdGhpbmtzIGtleSBpcyB1c2VkIGJlZm9yZSBkZWZpbmVkXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11c2UtYmVmb3JlLWRlZmluZVxuICAgICAgICBjb25zdCBjb252ZXJ0ZWQgPSB7fSBhcyB7IFsga2V5IGluIGtleW9mIFRdOiBUW2tleV0gfTtcbiAgICAgICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleV0pIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBwcm9wZXJ0aWVzW2tleV0uY29udmVydChmcm9tLCBjb250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmlzU3VjY2VzcygpICYmIChyZXN1bHQudmFsdWUgIT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udmVydGVkW2tleV0gPSByZXN1bHQudmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJlc3VsdC5pc0ZhaWx1cmUoKSkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChyZXN1bHQubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChlcnJvcnMubGVuZ3RoID09PSAwKSA/IHN1Y2NlZWQoY29udmVydGVkKSA6IGZhaWwoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBIGhlbHBlciB3cmFwcGVyIHRvIGNvbnN0cnVjdCBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIHRvIGFuIGFyYml0cmFyeSBzdHJvbmdseS10eXBlZFxuICogcmFuZ2Ugb2Ygc29tZSBjb21wYXJhYmxlIHR5cGUuXG4gKiBAcGFyYW0gY29udmVydGVyIC0ge0BsaW5rIENvbnZlcnRlcn0gdXNlZCB0byBjb252ZXJ0IGBtaW5gIGFuZCBgbWF4YCBleHRlbnQgb2YgdGhlIHJhbmdlLlxuICogQHBhcmFtIGNvbnN0cnVjdG9yIC0gU3RhdGljIGNvbnN0cnVjdG9yIHRvIGluc3RhbnRpYXRlIHRoZSBvYmplY3QuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByYW5nZVR5cGVPZjxULCBSVCBleHRlbmRzIFJhbmdlT2Y8VD4sIFRDPXVua25vd24+KGNvbnZlcnRlcjogQ29udmVydGVyPFQsIFRDPiwgY29uc3RydWN0b3I6IChpbml0OiBSYW5nZU9mUHJvcGVydGllczxUPikgPT4gUmVzdWx0PFJUPik6IENvbnZlcnRlcjxSVCwgVEM+IHtcbiAgICByZXR1cm4gbmV3IEJhc2VDb252ZXJ0ZXIoKGZyb206IHVua25vd24sIF9zZWxmLCBjb250ZXh0PzogVEMpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gb2JqZWN0KHtcbiAgICAgICAgICAgIG1pbjogY29udmVydGVyLFxuICAgICAgICAgICAgbWF4OiBjb252ZXJ0ZXIsXG4gICAgICAgIH0sIHsgb3B0aW9uYWxGaWVsZHM6IFsnbWluJywgJ21heCddIH0pLmNvbnZlcnQoZnJvbSwgY29udGV4dCk7XG4gICAgICAgIGlmIChyZXN1bHQuaXNTdWNjZXNzKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBjb25zdHJ1Y3Rvcih7IG1pbjogcmVzdWx0LnZhbHVlLm1pbiwgbWF4OiByZXN1bHQudmFsdWUubWF4IH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWlsKHJlc3VsdC5tZXNzYWdlKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBIGhlbHBlciB3cmFwcGVyIHRvIGNvbnN0cnVjdCBhIHtAbGluayBDb252ZXJ0ZXJ9IHdoaWNoIGNvbnZlcnRzIHRvIHtAbGluayBSYW5nZU9mIHwgUmFuZ2VPZjxUPn1cbiAqIHdoZXJlIGA8VD5gIGlzIHNvbWUgY29tcGFyYWJsZSB0eXBlLlxuICogQHBhcmFtIGNvbnZlcnRlciAtIHtAbGluayBDb252ZXJ0ZXJ9IHVzZWQgdG8gY29udmVydCBgbWluYCBhbmQgYG1heGAgZXh0ZW50IG9mIHRoZSByYW5nZS5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJhbmdlT2Y8VCwgVEM9dW5rbm93bj4oY29udmVydGVyOiBDb252ZXJ0ZXI8VCwgVEM+KTogQ29udmVydGVyPFJhbmdlT2Y8VD4sIFRDPiB7XG4gICAgcmV0dXJuIHJhbmdlVHlwZU9mPFQsIFJhbmdlT2Y8VD4sIFRDPihjb252ZXJ0ZXIsIFJhbmdlT2YuY3JlYXRlUmFuZ2UpO1xufVxuIl19
|