@decaf-ts/logging 0.3.8 → 0.3.10
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.md +3 -2
- package/dist/logging.cjs +588 -105
- package/dist/logging.esm.cjs +568 -102
- package/lib/constants.cjs +15 -6
- package/lib/constants.d.ts +7 -0
- package/lib/decorators.cjs +44 -27
- package/lib/decorators.d.ts +9 -0
- package/lib/environment.cjs +204 -0
- package/lib/environment.d.ts +86 -0
- package/lib/esm/constants.d.ts +7 -0
- package/lib/esm/constants.js +14 -5
- package/lib/esm/decorators.d.ts +9 -0
- package/lib/esm/decorators.js +43 -27
- package/lib/esm/environment.d.ts +86 -0
- package/lib/esm/environment.js +200 -0
- package/lib/esm/filters/LogFilter.d.ts +6 -0
- package/lib/esm/filters/LogFilter.js +7 -0
- package/lib/esm/filters/PatternFilter.d.ts +10 -0
- package/lib/esm/filters/PatternFilter.js +44 -0
- package/lib/esm/filters/index.d.ts +2 -0
- package/lib/esm/filters/index.js +3 -0
- package/lib/esm/index.d.ts +5 -2
- package/lib/esm/index.js +6 -3
- package/lib/esm/logging.d.ts +10 -11
- package/lib/esm/logging.js +38 -27
- package/lib/esm/text.d.ts +156 -0
- package/lib/esm/text.js +214 -0
- package/lib/esm/types.d.ts +31 -5
- package/lib/esm/types.js +1 -1
- package/lib/esm/web.d.ts +8 -0
- package/lib/esm/web.js +12 -0
- package/lib/esm/winston/winston.d.ts +2 -2
- package/lib/esm/winston/winston.js +4 -4
- package/lib/filters/LogFilter.cjs +11 -0
- package/lib/filters/LogFilter.d.ts +6 -0
- package/lib/filters/PatternFilter.cjs +48 -0
- package/lib/filters/PatternFilter.d.ts +10 -0
- package/lib/filters/index.cjs +19 -0
- package/lib/filters/index.d.ts +2 -0
- package/lib/index.cjs +6 -3
- package/lib/index.d.ts +5 -2
- package/lib/logging.cjs +37 -26
- package/lib/logging.d.ts +10 -11
- package/lib/text.cjs +227 -0
- package/lib/text.d.ts +156 -0
- package/lib/types.cjs +1 -1
- package/lib/types.d.ts +31 -5
- package/lib/web.cjs +15 -0
- package/lib/web.d.ts +8 -0
- package/lib/winston/winston.cjs +4 -4
- package/lib/winston/winston.d.ts +2 -2
- package/package.json +13 -4
- package/lib/esm/utils.d.ts +0 -12
- package/lib/esm/utils.js +0 -31
- package/lib/utils.cjs +0 -34
- package/lib/utils.d.ts +0 -12
package/dist/logging.cjs
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('styled-string-builder')) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'styled-string-builder'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.logging = {}, global.styledStringBuilder));
|
|
5
|
-
})(this, (function (exports, styledStringBuilder) { 'use strict';
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('styled-string-builder'), require('typed-object-accumulator'), require('tslib')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'styled-string-builder', 'typed-object-accumulator', 'tslib'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.logging = {}, global.styledStringBuilder, global.typedObjectAccumulator, global.tslib));
|
|
5
|
+
})(this, (function (exports, styledStringBuilder, typedObjectAccumulator, tslib) { 'use strict';
|
|
6
6
|
|
|
7
|
+
const BrowserEnvKey = "ENV";
|
|
8
|
+
/**
|
|
9
|
+
* @description Delimiter used for composing nested environment variable names.
|
|
10
|
+
* @summary Joins parent and child keys when mapping object paths to ENV strings.
|
|
11
|
+
*/
|
|
12
|
+
const ENV_PATH_DELIMITER = "__";
|
|
13
|
+
const DefaultPlaceholderWrappers = ["${", "}"];
|
|
7
14
|
/**
|
|
8
15
|
* @description Enum for log levels.
|
|
9
16
|
* @summary Defines different levels of logging for the application.
|
|
@@ -81,6 +88,8 @@
|
|
|
81
88
|
* @memberOf module:Logging
|
|
82
89
|
*/
|
|
83
90
|
const DefaultTheme = {
|
|
91
|
+
app: {},
|
|
92
|
+
separator: {},
|
|
84
93
|
class: {
|
|
85
94
|
fg: 34,
|
|
86
95
|
},
|
|
@@ -132,21 +141,194 @@
|
|
|
132
141
|
* @memberOf module:Logging
|
|
133
142
|
*/
|
|
134
143
|
const DefaultLoggingConfig = {
|
|
144
|
+
env: "development",
|
|
135
145
|
verbose: 0,
|
|
136
146
|
level: exports.LogLevel.info,
|
|
137
147
|
logLevel: true,
|
|
138
|
-
mode: exports.LoggingMode.RAW,
|
|
139
148
|
style: false,
|
|
140
149
|
contextSeparator: ".",
|
|
141
|
-
separator: "
|
|
150
|
+
separator: "-",
|
|
142
151
|
timestamp: true,
|
|
143
152
|
timestampFormat: "HH:mm:ss.SSS",
|
|
144
153
|
context: true,
|
|
145
|
-
format:
|
|
146
|
-
pattern: "{level} [{timestamp}] {context}
|
|
154
|
+
format: exports.LoggingMode.RAW,
|
|
155
|
+
pattern: "{level} [{timestamp}] {app} {context} {separator} {message} {stack}",
|
|
147
156
|
theme: DefaultTheme,
|
|
148
157
|
};
|
|
149
158
|
|
|
159
|
+
/**
|
|
160
|
+
* @description Pads the end of a string with a specified character.
|
|
161
|
+
* @summary Extends the input string to a specified length by adding a padding character to the end.
|
|
162
|
+
* If the input string is already longer than the specified length, it is returned unchanged.
|
|
163
|
+
*
|
|
164
|
+
* @param {string} str - The input string to be padded.
|
|
165
|
+
* @param {number} length - The desired total length of the resulting string.
|
|
166
|
+
* @param {string} [char=" "] - The character to use for padding. Defaults to a space.
|
|
167
|
+
* @return {string} The padded string.
|
|
168
|
+
* @throws {Error} If the padding character is not exactly one character long.
|
|
169
|
+
*
|
|
170
|
+
* @function padEnd
|
|
171
|
+
*
|
|
172
|
+
* @memberOf module:Logging
|
|
173
|
+
*/
|
|
174
|
+
function padEnd(str, length, char = " ") {
|
|
175
|
+
if (char.length !== 1)
|
|
176
|
+
throw new Error("Invalid character length for padding. must be one!");
|
|
177
|
+
return str.padEnd(length, char);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* @description Replaces placeholders in a string with provided values.
|
|
181
|
+
* @summary Interpolates a string by replacing placeholders of the form ${variableName}
|
|
182
|
+
* with corresponding values from the provided object. If a placeholder doesn't have
|
|
183
|
+
* a corresponding value, it is left unchanged in the string.
|
|
184
|
+
*
|
|
185
|
+
* @param {string} input - The input string containing placeholders to be replaced.
|
|
186
|
+
* @param {Record<string, number | string>} values - An object containing key-value pairs for replacement.
|
|
187
|
+
* @param prefix
|
|
188
|
+
* @param suffix
|
|
189
|
+
* @param flags
|
|
190
|
+
* @return {string} The interpolated string with placeholders replaced by their corresponding values.
|
|
191
|
+
*
|
|
192
|
+
* @function patchPlaceholders
|
|
193
|
+
*
|
|
194
|
+
* @mermaid
|
|
195
|
+
* sequenceDiagram
|
|
196
|
+
* participant Caller
|
|
197
|
+
* participant patchString
|
|
198
|
+
* participant String.replace
|
|
199
|
+
* Caller->>patchString: Call with input and values
|
|
200
|
+
* patchString->>String.replace: Call with regex and replacement function
|
|
201
|
+
* String.replace->>patchString: Return replaced string
|
|
202
|
+
* patchString-->>Caller: Return patched string
|
|
203
|
+
*
|
|
204
|
+
* @memberOf module:Logging
|
|
205
|
+
*/
|
|
206
|
+
function patchPlaceholders(input, values, prefix = DefaultPlaceholderWrappers[0], suffix = DefaultPlaceholderWrappers[1], flags = "g") {
|
|
207
|
+
const placeholders = Object.entries(values).reduce((acc, [key, val]) => {
|
|
208
|
+
acc[`${prefix}${key}${suffix}`] = val;
|
|
209
|
+
return acc;
|
|
210
|
+
}, {});
|
|
211
|
+
return patchString(input, placeholders, flags);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* @description Replaces occurrences of keys with their corresponding values in a string.
|
|
215
|
+
* @summary Iterates through a set of key-value pairs and replaces all occurrences of each key
|
|
216
|
+
* in the input string with its corresponding value. Supports regular expression flags for customized replacement.
|
|
217
|
+
*
|
|
218
|
+
* @param {string} input - The input string in which replacements will be made.
|
|
219
|
+
* @param {Record<string, number | string>} values - An object containing key-value pairs for replacement.
|
|
220
|
+
* @param {string} [flags="g"] - Regular expression flags to control the replacement behavior.
|
|
221
|
+
* @return {string} The string with all specified replacements applied.
|
|
222
|
+
*
|
|
223
|
+
* @function patchString
|
|
224
|
+
*
|
|
225
|
+
* @memberOf module:Logging
|
|
226
|
+
*/
|
|
227
|
+
function patchString(input, values, flags = "g") {
|
|
228
|
+
Object.entries(values).forEach(([key, val]) => {
|
|
229
|
+
const regexp = new RegExp(escapeRegExp(key), flags);
|
|
230
|
+
input = input.replace(regexp, val);
|
|
231
|
+
});
|
|
232
|
+
return input;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* @description Converts a string to camelCase.
|
|
236
|
+
* @summary Transforms the input string into camelCase format, where words are joined without spaces
|
|
237
|
+
* and each word after the first starts with a capital letter.
|
|
238
|
+
*
|
|
239
|
+
* @param {string} text - The input string to be converted.
|
|
240
|
+
* @return {string} The input string converted to camelCase.
|
|
241
|
+
*
|
|
242
|
+
* @function toCamelCase
|
|
243
|
+
*
|
|
244
|
+
* @memberOf module:Logging
|
|
245
|
+
*/
|
|
246
|
+
function toCamelCase(text) {
|
|
247
|
+
return text
|
|
248
|
+
.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => index === 0 ? word.toLowerCase() : word.toUpperCase())
|
|
249
|
+
.replace(/\s+/g, "");
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* @description Converts a string to ENVIRONMENT_VARIABLE format.
|
|
253
|
+
* @summary Transforms the input string into uppercase with words separated by underscores,
|
|
254
|
+
* typically used for environment variable names.
|
|
255
|
+
*
|
|
256
|
+
* @param {string} text - The input string to be converted.
|
|
257
|
+
* @return {string} The input string converted to ENVIRONMENT_VARIABLE format.
|
|
258
|
+
*
|
|
259
|
+
* @function toENVFormat
|
|
260
|
+
*
|
|
261
|
+
* @memberOf module:Logging
|
|
262
|
+
*/
|
|
263
|
+
function toENVFormat(text) {
|
|
264
|
+
return toSnakeCase(text).toUpperCase();
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* @description Converts a string to snake_case.
|
|
268
|
+
* @summary Transforms the input string into lowercase with words separated by underscores.
|
|
269
|
+
*
|
|
270
|
+
* @param {string} text - The input string to be converted.
|
|
271
|
+
* @return {string} The input string converted to snake_case.
|
|
272
|
+
*
|
|
273
|
+
* @function toSnakeCase
|
|
274
|
+
*
|
|
275
|
+
* @memberOf module:Logging
|
|
276
|
+
*/
|
|
277
|
+
function toSnakeCase(text) {
|
|
278
|
+
return text
|
|
279
|
+
.replace(/([a-z])([A-Z])/g, "$1_$2")
|
|
280
|
+
.replace(/[\s-]+/g, "_")
|
|
281
|
+
.toLowerCase();
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* @description Converts a string to kebab-case.
|
|
285
|
+
* @summary Transforms the input string into lowercase with words separated by hyphens.
|
|
286
|
+
*
|
|
287
|
+
* @param {string} text - The input string to be converted.
|
|
288
|
+
* @return {string} The input string converted to kebab-case.
|
|
289
|
+
*
|
|
290
|
+
* @function toKebabCase
|
|
291
|
+
*
|
|
292
|
+
* @memberOf module:Logging
|
|
293
|
+
*/
|
|
294
|
+
function toKebabCase(text) {
|
|
295
|
+
return text
|
|
296
|
+
.replace(/([a-z])([A-Z])/g, "$1-$2")
|
|
297
|
+
.replace(/[\s_]+/g, "-")
|
|
298
|
+
.toLowerCase();
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* @description Converts a string to PascalCase.
|
|
302
|
+
* @summary Transforms the input string into PascalCase format, where words are joined without spaces
|
|
303
|
+
* and each word starts with a capital letter.
|
|
304
|
+
*
|
|
305
|
+
* @param {string} text - The input string to be converted.
|
|
306
|
+
* @return {string} The input string converted to PascalCase.
|
|
307
|
+
*
|
|
308
|
+
* @function toPascalCase
|
|
309
|
+
*
|
|
310
|
+
* @memberOf module:Logging
|
|
311
|
+
*/
|
|
312
|
+
function toPascalCase(text) {
|
|
313
|
+
return text
|
|
314
|
+
.replace(/(?:^\w|[A-Z]|\b\w)/g, (word) => word.toUpperCase())
|
|
315
|
+
.replace(/\s+/g, "");
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* @description Escapes special characters in a string for use in a regular expression.
|
|
319
|
+
* @summary Adds backslashes before characters that have special meaning in regular expressions,
|
|
320
|
+
* allowing the string to be used as a literal match in a RegExp.
|
|
321
|
+
*
|
|
322
|
+
* @param {string} string - The string to escape for regular expression use.
|
|
323
|
+
* @return {string} The escaped string safe for use in regular expressions.
|
|
324
|
+
*
|
|
325
|
+
* @function escapeRegExp
|
|
326
|
+
*
|
|
327
|
+
* @memberOf module:Logging
|
|
328
|
+
*/
|
|
329
|
+
function escapeRegExp(string) {
|
|
330
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
|
|
331
|
+
}
|
|
150
332
|
/**
|
|
151
333
|
* @summary Util function to provide string format functionality similar to C#'s string.format
|
|
152
334
|
*
|
|
@@ -154,11 +336,10 @@
|
|
|
154
336
|
* @param {Array<string | number> | Record<string, any>} [args] replacements made by order of appearance (replacement0 wil replace {0} and so on)
|
|
155
337
|
* @return {string} formatted string
|
|
156
338
|
*
|
|
157
|
-
* @function
|
|
158
|
-
* @memberOf module:
|
|
159
|
-
* @category Model
|
|
339
|
+
* @function sf
|
|
340
|
+
* @memberOf module:Logging
|
|
160
341
|
*/
|
|
161
|
-
function
|
|
342
|
+
function sf(string, ...args) {
|
|
162
343
|
if (args.length > 1) {
|
|
163
344
|
if (!args.every((arg) => typeof arg === "string" || typeof arg === "number"))
|
|
164
345
|
throw new Error(`Only string and number arguments are supported for multiple replacements.`);
|
|
@@ -177,6 +358,224 @@
|
|
|
177
358
|
: "undefined";
|
|
178
359
|
});
|
|
179
360
|
}
|
|
361
|
+
/**
|
|
362
|
+
* @summary Util function to provide string format functionality similar to C#'s string.format
|
|
363
|
+
*
|
|
364
|
+
* @see sf
|
|
365
|
+
*
|
|
366
|
+
* @deprecated
|
|
367
|
+
* @function stringFormat
|
|
368
|
+
* @memberOf module:Logging
|
|
369
|
+
*/
|
|
370
|
+
const stringFormat = sf;
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* @description Determines if the current environment is a browser by checking the prototype chain of the global object.
|
|
374
|
+
* @summary Checks if the code is running in a browser environment.
|
|
375
|
+
* @return {boolean} True if the environment is a browser, false otherwise.
|
|
376
|
+
* @function isBrowser
|
|
377
|
+
* @memberOf module:Logging
|
|
378
|
+
*/
|
|
379
|
+
function isBrowser() {
|
|
380
|
+
return (Object.getPrototypeOf(Object.getPrototypeOf(globalThis)) !==
|
|
381
|
+
Object.prototype);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* @class Environment
|
|
386
|
+
* @extends {ObjectAccumulator<T>}
|
|
387
|
+
* @template T
|
|
388
|
+
* @description A class representing an environment with accumulation capabilities.
|
|
389
|
+
* @summary Manages environment-related data and provides methods for accumulation and key retrieval.
|
|
390
|
+
* @param {T} [initialData] - The initial data to populate the environment with.
|
|
391
|
+
*/
|
|
392
|
+
class Environment extends typedObjectAccumulator.ObjectAccumulator {
|
|
393
|
+
/**
|
|
394
|
+
* @static
|
|
395
|
+
* @protected
|
|
396
|
+
* @description A factory function for creating Environment instances.
|
|
397
|
+
* @summary Defines how new instances of the Environment class should be created.
|
|
398
|
+
* @return {Environment<any>} A new instance of the Environment class.
|
|
399
|
+
*/
|
|
400
|
+
static { this.factory = () => new Environment(); }
|
|
401
|
+
constructor() {
|
|
402
|
+
super();
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* @description Retrieves a value from the environment
|
|
406
|
+
* @summary Gets a value from the environment variables, handling browser and Node.js environments differently
|
|
407
|
+
* @param {string} k - The key to retrieve from the environment
|
|
408
|
+
* @return {unknown} The value from the environment, or undefined if not found
|
|
409
|
+
*/
|
|
410
|
+
fromEnv(k) {
|
|
411
|
+
let env;
|
|
412
|
+
if (isBrowser()) {
|
|
413
|
+
env = globalThis[BrowserEnvKey];
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
env = globalThis.process.env;
|
|
417
|
+
k = toENVFormat(k);
|
|
418
|
+
}
|
|
419
|
+
return env[k];
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* @description Expands an object into the environment
|
|
423
|
+
* @summary Defines properties on the environment object that can be accessed as getters and setters
|
|
424
|
+
* @template V - Type of the object being expanded
|
|
425
|
+
* @param {V} value - The object to expand into the environment
|
|
426
|
+
* @return {void}
|
|
427
|
+
*/
|
|
428
|
+
expand(value) {
|
|
429
|
+
Object.entries(value).forEach(([k, v]) => {
|
|
430
|
+
Object.defineProperty(this, k, {
|
|
431
|
+
get: () => {
|
|
432
|
+
const fromEnv = this.fromEnv(k);
|
|
433
|
+
if (typeof fromEnv !== "undefined")
|
|
434
|
+
return fromEnv;
|
|
435
|
+
if (v && typeof v === "object") {
|
|
436
|
+
return Environment.buildEnvProxy(v, [k]);
|
|
437
|
+
}
|
|
438
|
+
// If the model provides an empty string, expose a proxy that composes ENV keys
|
|
439
|
+
if (v === "") {
|
|
440
|
+
return Environment.buildEnvProxy(undefined, [k]);
|
|
441
|
+
}
|
|
442
|
+
return v;
|
|
443
|
+
},
|
|
444
|
+
set: (val) => {
|
|
445
|
+
v = val;
|
|
446
|
+
},
|
|
447
|
+
configurable: true,
|
|
448
|
+
enumerable: true,
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* @protected
|
|
454
|
+
* @static
|
|
455
|
+
* @description Retrieves or creates the singleton instance of the Environment class.
|
|
456
|
+
* @summary Ensures only one instance of the Environment class exists.
|
|
457
|
+
* @template E
|
|
458
|
+
* @param {...unknown[]} args - Arguments to pass to the factory function if a new instance is created.
|
|
459
|
+
* @return {E} The singleton instance of the Environment class.
|
|
460
|
+
*/
|
|
461
|
+
static instance(...args) {
|
|
462
|
+
if (!Environment._instance) {
|
|
463
|
+
const base = Environment.factory(...args);
|
|
464
|
+
const proxied = new Proxy(base, {
|
|
465
|
+
get(target, prop, receiver) {
|
|
466
|
+
const value = Reflect.get(target, prop, receiver);
|
|
467
|
+
if (typeof value !== "undefined")
|
|
468
|
+
return value;
|
|
469
|
+
if (typeof prop === "string") {
|
|
470
|
+
// Avoid interfering with logging config lookups for optional fields like 'app'
|
|
471
|
+
if (prop === "app")
|
|
472
|
+
return undefined;
|
|
473
|
+
return Environment.buildEnvProxy(undefined, [prop]);
|
|
474
|
+
}
|
|
475
|
+
return value;
|
|
476
|
+
},
|
|
477
|
+
});
|
|
478
|
+
Environment._instance = proxied;
|
|
479
|
+
}
|
|
480
|
+
return Environment._instance;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* @static
|
|
484
|
+
* @description Accumulates the given value into the environment.
|
|
485
|
+
* @summary Adds new properties to the environment from the provided object.
|
|
486
|
+
* @template V
|
|
487
|
+
* @param {V} value - The object to accumulate into the environment.
|
|
488
|
+
* @return {V} The updated environment instance.
|
|
489
|
+
*/
|
|
490
|
+
static accumulate(value) {
|
|
491
|
+
const instance = Environment.instance();
|
|
492
|
+
Object.keys(instance).forEach((key) => {
|
|
493
|
+
const desc = Object.getOwnPropertyDescriptor(instance, key);
|
|
494
|
+
if (desc && desc.configurable && desc.enumerable) {
|
|
495
|
+
Object.defineProperty(instance, key, {
|
|
496
|
+
...desc,
|
|
497
|
+
enumerable: false,
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
return instance.accumulate(value);
|
|
502
|
+
}
|
|
503
|
+
static get(key) {
|
|
504
|
+
return Environment._instance.get(key);
|
|
505
|
+
}
|
|
506
|
+
static buildEnvProxy(current, path) {
|
|
507
|
+
const buildKey = (p) => p.map((seg) => toENVFormat(seg)).join(ENV_PATH_DELIMITER);
|
|
508
|
+
// Helper to read from the active environment given a composed key
|
|
509
|
+
const readEnv = (key) => {
|
|
510
|
+
if (isBrowser()) {
|
|
511
|
+
const env = globalThis[BrowserEnvKey];
|
|
512
|
+
return env ? env[key] : undefined;
|
|
513
|
+
}
|
|
514
|
+
return globalThis?.process?.env?.[key];
|
|
515
|
+
};
|
|
516
|
+
const handler = {
|
|
517
|
+
get(_target, prop) {
|
|
518
|
+
if (prop === Symbol.toPrimitive) {
|
|
519
|
+
return () => buildKey(path);
|
|
520
|
+
}
|
|
521
|
+
if (prop === "toString") {
|
|
522
|
+
return () => buildKey(path);
|
|
523
|
+
}
|
|
524
|
+
if (prop === "valueOf") {
|
|
525
|
+
return () => buildKey(path);
|
|
526
|
+
}
|
|
527
|
+
if (typeof prop === "symbol")
|
|
528
|
+
return undefined;
|
|
529
|
+
const nextModel = current && Object.prototype.hasOwnProperty.call(current, prop)
|
|
530
|
+
? current[prop]
|
|
531
|
+
: undefined;
|
|
532
|
+
const nextPath = [...path, prop];
|
|
533
|
+
const composedKey = buildKey(nextPath);
|
|
534
|
+
// If an ENV value exists for this path, return it directly
|
|
535
|
+
const envValue = readEnv(composedKey);
|
|
536
|
+
if (typeof envValue !== "undefined")
|
|
537
|
+
return envValue;
|
|
538
|
+
// Otherwise, if the model has an object at this path, keep drilling with a proxy
|
|
539
|
+
const isNextObject = nextModel && typeof nextModel === "object";
|
|
540
|
+
if (isNextObject)
|
|
541
|
+
return Environment.buildEnvProxy(nextModel, nextPath);
|
|
542
|
+
// Always return a proxy for further path composition when no ENV value;
|
|
543
|
+
// do not surface primitive model defaults here (this API is for key composition).
|
|
544
|
+
return Environment.buildEnvProxy(undefined, nextPath);
|
|
545
|
+
},
|
|
546
|
+
ownKeys() {
|
|
547
|
+
return current ? Reflect.ownKeys(current) : [];
|
|
548
|
+
},
|
|
549
|
+
getOwnPropertyDescriptor(_t, p) {
|
|
550
|
+
if (!current)
|
|
551
|
+
return undefined;
|
|
552
|
+
if (Object.prototype.hasOwnProperty.call(current, p)) {
|
|
553
|
+
return { enumerable: true, configurable: true };
|
|
554
|
+
}
|
|
555
|
+
return undefined;
|
|
556
|
+
},
|
|
557
|
+
};
|
|
558
|
+
const target = {};
|
|
559
|
+
return new Proxy(target, handler);
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* @static
|
|
563
|
+
* @description Retrieves the keys of the environment, optionally converting them to ENV format.
|
|
564
|
+
* @summary Gets all keys in the environment, with an option to format them for environment variables.
|
|
565
|
+
* @param {boolean} [toEnv=true] - Whether to convert the keys to ENV format.
|
|
566
|
+
* @return {string[]} An array of keys from the environment.
|
|
567
|
+
*/
|
|
568
|
+
static keys(toEnv = true) {
|
|
569
|
+
return Environment.instance()
|
|
570
|
+
.keys()
|
|
571
|
+
.map((k) => (toEnv ? toENVFormat(k) : k));
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
const LoggedEnvironment = Environment.accumulate(Object.assign({}, DefaultLoggingConfig, {
|
|
575
|
+
env: (isBrowser() && globalThis[BrowserEnvKey]
|
|
576
|
+
? globalThis[BrowserEnvKey]["NODE_ENV"]
|
|
577
|
+
: globalThis.process.env["NODE_ENV"]) || "development",
|
|
578
|
+
}));
|
|
180
579
|
|
|
181
580
|
/**
|
|
182
581
|
* @description A minimal logger implementation.
|
|
@@ -258,12 +657,22 @@
|
|
|
258
657
|
* @summary Generates a log string with timestamp, colored log level, context, and message
|
|
259
658
|
* @param {LogLevel} level - The log level for this message
|
|
260
659
|
* @param {StringLike | Error} message - The message to log or an Error object
|
|
261
|
-
* @param {string} [
|
|
660
|
+
* @param {string} [error] - Optional error to extract stack trace to include in the log
|
|
262
661
|
* @return {string} A formatted log string with all components
|
|
263
662
|
*/
|
|
264
|
-
createLog(level, message,
|
|
663
|
+
createLog(level, message, error) {
|
|
265
664
|
const log = {};
|
|
266
665
|
const style = this.config("style");
|
|
666
|
+
const separator = this.config("separator");
|
|
667
|
+
const app = this.config("app");
|
|
668
|
+
if (app)
|
|
669
|
+
log.app = style
|
|
670
|
+
? Logging.theme(app, "app", level)
|
|
671
|
+
: app;
|
|
672
|
+
if (separator)
|
|
673
|
+
log.separator = style
|
|
674
|
+
? Logging.theme(separator, "separator", level)
|
|
675
|
+
: separator;
|
|
267
676
|
if (this.config("timestamp")) {
|
|
268
677
|
const date = new Date().toISOString();
|
|
269
678
|
const timestamp = style ? Logging.theme(date, "timestamp", level) : date;
|
|
@@ -295,11 +704,11 @@
|
|
|
295
704
|
? message
|
|
296
705
|
: message.message;
|
|
297
706
|
log.message = msg;
|
|
298
|
-
if (
|
|
299
|
-
stack = style
|
|
300
|
-
? Logging.theme((stack || message.stack), "stack", level)
|
|
301
|
-
: stack;
|
|
302
|
-
log.stack =
|
|
707
|
+
if (error || message instanceof Error) {
|
|
708
|
+
const stack = style
|
|
709
|
+
? Logging.theme((error?.stack || message.stack), "stack", level)
|
|
710
|
+
: error?.stack || "";
|
|
711
|
+
log.stack = ` | ${(error || message).message} - Stack trace:\n${stack}`;
|
|
303
712
|
}
|
|
304
713
|
switch (this.config("format")) {
|
|
305
714
|
case "json":
|
|
@@ -310,7 +719,7 @@
|
|
|
310
719
|
.map((s) => {
|
|
311
720
|
if (!s.match(/\{.*?}/g))
|
|
312
721
|
return s;
|
|
313
|
-
const formattedS =
|
|
722
|
+
const formattedS = sf(s, log);
|
|
314
723
|
if (formattedS !== s)
|
|
315
724
|
return formattedS;
|
|
316
725
|
return undefined;
|
|
@@ -327,12 +736,12 @@
|
|
|
327
736
|
* then uses the appropriate console method to output the formatted log
|
|
328
737
|
* @param {LogLevel} level - The log level of the message
|
|
329
738
|
* @param {StringLike | Error} msg - The message to be logged or an Error object
|
|
330
|
-
* @param {string} [
|
|
739
|
+
* @param {string} [error] - Optional stack trace to include in the log
|
|
331
740
|
* @return {void}
|
|
332
741
|
*/
|
|
333
|
-
log(level, msg,
|
|
334
|
-
|
|
335
|
-
|
|
742
|
+
log(level, msg, error) {
|
|
743
|
+
const confLvl = this.config("level");
|
|
744
|
+
if (NumericLogLevels[confLvl] < NumericLogLevels[level])
|
|
336
745
|
return;
|
|
337
746
|
let method;
|
|
338
747
|
switch (level) {
|
|
@@ -349,7 +758,7 @@
|
|
|
349
758
|
default:
|
|
350
759
|
throw new Error("Invalid log level");
|
|
351
760
|
}
|
|
352
|
-
method(this.createLog(level, msg,
|
|
761
|
+
method(this.createLog(level, msg, error));
|
|
353
762
|
}
|
|
354
763
|
/**
|
|
355
764
|
* @description Logs a message at the silly level
|
|
@@ -395,10 +804,11 @@
|
|
|
395
804
|
* @description Logs a message at the error level
|
|
396
805
|
* @summary Logs a message at the error level for errors and exceptions
|
|
397
806
|
* @param {StringLike | Error} msg - The message to be logged or an Error object
|
|
807
|
+
* @param e
|
|
398
808
|
* @return {void}
|
|
399
809
|
*/
|
|
400
|
-
error(msg) {
|
|
401
|
-
this.log(exports.LogLevel.error, msg);
|
|
810
|
+
error(msg, e) {
|
|
811
|
+
this.log(exports.LogLevel.error, msg, e);
|
|
402
812
|
}
|
|
403
813
|
/**
|
|
404
814
|
* @description Updates the logger configuration
|
|
@@ -483,11 +893,7 @@
|
|
|
483
893
|
static { this._factory = (object, config) => {
|
|
484
894
|
return new MiniLogger(object, config);
|
|
485
895
|
}; }
|
|
486
|
-
|
|
487
|
-
* @description Configuration for the logging system
|
|
488
|
-
* @summary Stores the global logging configuration including verbosity, log level, styling, and formatting settings
|
|
489
|
-
*/
|
|
490
|
-
static { this._config = DefaultLoggingConfig; }
|
|
896
|
+
static { this._config = LoggedEnvironment; }
|
|
491
897
|
constructor() { }
|
|
492
898
|
/**
|
|
493
899
|
* @description Sets the factory function for creating logger instances
|
|
@@ -505,7 +911,9 @@
|
|
|
505
911
|
* @return {void}
|
|
506
912
|
*/
|
|
507
913
|
static setConfig(config) {
|
|
508
|
-
Object.
|
|
914
|
+
Object.entries(config).forEach(([k, v]) => {
|
|
915
|
+
this._config[k] = v;
|
|
916
|
+
});
|
|
509
917
|
}
|
|
510
918
|
/**
|
|
511
919
|
* @description Gets a copy of the current global logging configuration
|
|
@@ -513,7 +921,7 @@
|
|
|
513
921
|
* @return {LoggingConfig} A copy of the current configuration
|
|
514
922
|
*/
|
|
515
923
|
static getConfig() {
|
|
516
|
-
return
|
|
924
|
+
return this._config;
|
|
517
925
|
}
|
|
518
926
|
/**
|
|
519
927
|
* @description Retrieves or creates the global logger instance.
|
|
@@ -567,9 +975,10 @@
|
|
|
567
975
|
* @summary Delegates the error logging to the global logger instance.
|
|
568
976
|
*
|
|
569
977
|
* @param msg - The message to be logged.
|
|
978
|
+
* @param e
|
|
570
979
|
*/
|
|
571
|
-
static error(msg) {
|
|
572
|
-
return this.get().error(msg);
|
|
980
|
+
static error(msg, e) {
|
|
981
|
+
return this.get().error(msg, e);
|
|
573
982
|
}
|
|
574
983
|
/**
|
|
575
984
|
* @description Creates a logger for a specific object or context
|
|
@@ -706,6 +1115,57 @@
|
|
|
706
1115
|
}
|
|
707
1116
|
}
|
|
708
1117
|
|
|
1118
|
+
/**
|
|
1119
|
+
* @description Base class that provides a ready-to-use logger instance
|
|
1120
|
+
* @summary LoggedClass is a convenience abstract class that injects a type-safe logger
|
|
1121
|
+
* into derived classes through a protected getter. Subclasses can directly access
|
|
1122
|
+
* this.log to emit messages without manually creating a logger. This promotes
|
|
1123
|
+
* consistent, context-aware logging across the codebase.
|
|
1124
|
+
* @param {void} [constructor] - No constructor arguments; subclasses may define their own
|
|
1125
|
+
* @class LoggedClass
|
|
1126
|
+
* @example
|
|
1127
|
+
* class UserService extends LoggedClass {
|
|
1128
|
+
* create(user: User) {
|
|
1129
|
+
* this.log.info(`Creating user ${user.id}`);
|
|
1130
|
+
* }
|
|
1131
|
+
* }
|
|
1132
|
+
*
|
|
1133
|
+
* const svc = new UserService();
|
|
1134
|
+
* svc.create({ id: "42" });
|
|
1135
|
+
* @mermaid
|
|
1136
|
+
* sequenceDiagram
|
|
1137
|
+
* participant Client
|
|
1138
|
+
* participant Instance as Subclass Instance
|
|
1139
|
+
* participant Getter as LoggedClass.log
|
|
1140
|
+
* participant Logging as Logging
|
|
1141
|
+
* participant Logger as Logger
|
|
1142
|
+
*
|
|
1143
|
+
* Client->>Instance: call someMethod()
|
|
1144
|
+
* Instance->>Getter: access this.log
|
|
1145
|
+
* Getter->>Logging: Logging.for(this)
|
|
1146
|
+
* Logging-->>Getter: return Logger
|
|
1147
|
+
* Getter-->>Instance: return Logger
|
|
1148
|
+
* Instance->>Logger: info/debug/error(...)
|
|
1149
|
+
*/
|
|
1150
|
+
class LoggedClass {
|
|
1151
|
+
/**
|
|
1152
|
+
* @description Lazily provides a context-aware logger for the current instance
|
|
1153
|
+
* @summary Uses Logging.for(this) to create a logger whose context is the
|
|
1154
|
+
* subclass name, allowing uniform and structured logs from any inheriting class.
|
|
1155
|
+
* @return {Logger} A logger bound to the subclass context
|
|
1156
|
+
*/
|
|
1157
|
+
get log() {
|
|
1158
|
+
return Logging.for(this);
|
|
1159
|
+
}
|
|
1160
|
+
constructor() { }
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
class LogFilter extends LoggedClass {
|
|
1164
|
+
get log() {
|
|
1165
|
+
return super.log.for(this, { filters: [] });
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
|
|
709
1169
|
/**
|
|
710
1170
|
* @description Method decorator for logging function calls
|
|
711
1171
|
* @summary Creates a decorator that logs method calls with specified level, benchmarking, and verbosity
|
|
@@ -741,35 +1201,33 @@
|
|
|
741
1201
|
return function (target, propertyKey, descriptor) {
|
|
742
1202
|
if (!descriptor)
|
|
743
1203
|
throw new Error(`Logging decoration only applies to methods`);
|
|
744
|
-
const
|
|
745
|
-
const method =
|
|
1204
|
+
const logger = Logging.for(target).for(target[propertyKey]);
|
|
1205
|
+
const method = logger[level].bind(logger);
|
|
746
1206
|
const originalMethod = descriptor.value;
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
1207
|
+
descriptor.value = new Proxy(originalMethod, {
|
|
1208
|
+
apply(fn, thisArg, args) {
|
|
1209
|
+
method(`called with ${args}`, verbosity);
|
|
1210
|
+
const start = Date.now();
|
|
1211
|
+
try {
|
|
1212
|
+
const result = Reflect.apply(fn, thisArg, args);
|
|
1213
|
+
if (result instanceof Promise) {
|
|
1214
|
+
return result.then((r) => {
|
|
1215
|
+
if (benchmark)
|
|
1216
|
+
method(`completed in ${Date.now() - start}ms`, verbosity);
|
|
1217
|
+
return r;
|
|
1218
|
+
});
|
|
758
1219
|
}
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
Object.assign(func, "name", {
|
|
770
|
-
value: descriptor.value.name,
|
|
1220
|
+
if (benchmark)
|
|
1221
|
+
method(`completed in ${Date.now() - start}ms`, verbosity);
|
|
1222
|
+
return result;
|
|
1223
|
+
}
|
|
1224
|
+
catch (err) {
|
|
1225
|
+
if (benchmark)
|
|
1226
|
+
method(`failed in ${Date.now() - start}ms`, verbosity);
|
|
1227
|
+
throw err;
|
|
1228
|
+
}
|
|
1229
|
+
},
|
|
771
1230
|
});
|
|
772
|
-
descriptor.value = func;
|
|
773
1231
|
};
|
|
774
1232
|
}
|
|
775
1233
|
/**
|
|
@@ -821,51 +1279,57 @@
|
|
|
821
1279
|
}
|
|
822
1280
|
return log(exports.LogLevel.verbose, benchmark, verbosity);
|
|
823
1281
|
}
|
|
824
|
-
|
|
825
1282
|
/**
|
|
826
|
-
* @description
|
|
827
|
-
* @summary
|
|
828
|
-
*
|
|
829
|
-
*
|
|
830
|
-
*
|
|
831
|
-
* @
|
|
832
|
-
* @class LoggedClass
|
|
833
|
-
* @example
|
|
834
|
-
* class UserService extends LoggedClass {
|
|
835
|
-
* create(user: User) {
|
|
836
|
-
* this.log.info(`Creating user ${user.id}`);
|
|
837
|
-
* }
|
|
838
|
-
* }
|
|
839
|
-
*
|
|
840
|
-
* const svc = new UserService();
|
|
841
|
-
* svc.create({ id: "42" });
|
|
842
|
-
* @mermaid
|
|
843
|
-
* sequenceDiagram
|
|
844
|
-
* participant Client
|
|
845
|
-
* participant Instance as Subclass Instance
|
|
846
|
-
* participant Getter as LoggedClass.log
|
|
847
|
-
* participant Logging as Logging
|
|
848
|
-
* participant Logger as Logger
|
|
849
|
-
*
|
|
850
|
-
* Client->>Instance: call someMethod()
|
|
851
|
-
* Instance->>Getter: access this.log
|
|
852
|
-
* Getter->>Logging: Logging.for(this)
|
|
853
|
-
* Logging-->>Getter: return Logger
|
|
854
|
-
* Getter-->>Instance: return Logger
|
|
855
|
-
* Instance->>Logger: info/debug/error(...)
|
|
1283
|
+
* @description Creates a decorator that makes a method non-configurable
|
|
1284
|
+
* @summary This decorator prevents a method from being overridden by making it non-configurable.
|
|
1285
|
+
* It throws an error if used on anything other than a method.
|
|
1286
|
+
* @return {Function} A decorator function that can be applied to methods
|
|
1287
|
+
* @function final
|
|
1288
|
+
* @category Method Decorators
|
|
856
1289
|
*/
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
1290
|
+
function final() {
|
|
1291
|
+
return (target, propertyKey, descriptor) => {
|
|
1292
|
+
if (!descriptor)
|
|
1293
|
+
throw new Error("final decorator can only be used on methods");
|
|
1294
|
+
if (descriptor?.configurable) {
|
|
1295
|
+
descriptor.configurable = false;
|
|
1296
|
+
}
|
|
1297
|
+
return descriptor;
|
|
1298
|
+
};
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
class PatternFilter extends LogFilter {
|
|
1302
|
+
constructor(regexp, replacement) {
|
|
1303
|
+
super();
|
|
1304
|
+
this.regexp = regexp;
|
|
1305
|
+
this.replacement = replacement;
|
|
1306
|
+
}
|
|
1307
|
+
match(message) {
|
|
1308
|
+
const match = this.regexp.exec(message);
|
|
1309
|
+
this.regexp.lastIndex = 0;
|
|
1310
|
+
return match;
|
|
1311
|
+
}
|
|
1312
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1313
|
+
filter(config, message, context) {
|
|
1314
|
+
const log = this.log.for(this.filter);
|
|
1315
|
+
const match = this.match(message);
|
|
1316
|
+
if (!match)
|
|
1317
|
+
return message;
|
|
1318
|
+
try {
|
|
1319
|
+
return message.replace(this.regexp, this.replacement);
|
|
1320
|
+
}
|
|
1321
|
+
catch (e) {
|
|
1322
|
+
log.error(`PatternFilter replacement error: ${e}`);
|
|
1323
|
+
}
|
|
1324
|
+
return "";
|
|
866
1325
|
}
|
|
867
|
-
constructor() { }
|
|
868
1326
|
}
|
|
1327
|
+
tslib.__decorate([
|
|
1328
|
+
final(),
|
|
1329
|
+
tslib.__metadata("design:type", Function),
|
|
1330
|
+
tslib.__metadata("design:paramtypes", [String]),
|
|
1331
|
+
tslib.__metadata("design:returntype", void 0)
|
|
1332
|
+
], PatternFilter.prototype, "match", null);
|
|
869
1333
|
|
|
870
1334
|
/**
|
|
871
1335
|
* @description A logging module for TypeScript applications
|
|
@@ -883,21 +1347,40 @@
|
|
|
883
1347
|
* @const VERSION
|
|
884
1348
|
* @memberOf module:Logging
|
|
885
1349
|
*/
|
|
886
|
-
const VERSION = "0.3.
|
|
1350
|
+
const VERSION = "0.3.9";
|
|
887
1351
|
|
|
1352
|
+
exports.BrowserEnvKey = BrowserEnvKey;
|
|
888
1353
|
exports.DefaultLoggingConfig = DefaultLoggingConfig;
|
|
1354
|
+
exports.DefaultPlaceholderWrappers = DefaultPlaceholderWrappers;
|
|
889
1355
|
exports.DefaultTheme = DefaultTheme;
|
|
1356
|
+
exports.ENV_PATH_DELIMITER = ENV_PATH_DELIMITER;
|
|
1357
|
+
exports.Environment = Environment;
|
|
1358
|
+
exports.LogFilter = LogFilter;
|
|
890
1359
|
exports.LoggedClass = LoggedClass;
|
|
1360
|
+
exports.LoggedEnvironment = LoggedEnvironment;
|
|
891
1361
|
exports.Logging = Logging;
|
|
892
1362
|
exports.MiniLogger = MiniLogger;
|
|
893
1363
|
exports.NumericLogLevels = NumericLogLevels;
|
|
1364
|
+
exports.PatternFilter = PatternFilter;
|
|
894
1365
|
exports.VERSION = VERSION;
|
|
895
1366
|
exports.debug = debug;
|
|
1367
|
+
exports.escapeRegExp = escapeRegExp;
|
|
1368
|
+
exports.final = final;
|
|
896
1369
|
exports.info = info;
|
|
1370
|
+
exports.isBrowser = isBrowser;
|
|
897
1371
|
exports.log = log;
|
|
1372
|
+
exports.padEnd = padEnd;
|
|
1373
|
+
exports.patchPlaceholders = patchPlaceholders;
|
|
1374
|
+
exports.patchString = patchString;
|
|
1375
|
+
exports.sf = sf;
|
|
898
1376
|
exports.silly = silly;
|
|
899
1377
|
exports.stringFormat = stringFormat;
|
|
1378
|
+
exports.toCamelCase = toCamelCase;
|
|
1379
|
+
exports.toENVFormat = toENVFormat;
|
|
1380
|
+
exports.toKebabCase = toKebabCase;
|
|
1381
|
+
exports.toPascalCase = toPascalCase;
|
|
1382
|
+
exports.toSnakeCase = toSnakeCase;
|
|
900
1383
|
exports.verbose = verbose;
|
|
901
1384
|
|
|
902
1385
|
}));
|
|
903
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2luZy5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvdXRpbHMudHMiLCIuLi9zcmMvbG9nZ2luZy50cyIsIi4uL3NyYy9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL0xvZ2dlZENsYXNzLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExvZ2dpbmdDb25maWcsIFRoZW1lIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRW51bSBmb3IgbG9nIGxldmVscy5cbiAqIEBzdW1tYXJ5IERlZmluZXMgZGlmZmVyZW50IGxldmVscyBvZiBsb2dnaW5nIGZvciB0aGUgYXBwbGljYXRpb24uXG4gKiBAZW51bSB7c3RyaW5nfVxuICogQHJlYWRvbmx5XG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGVudW0gTG9nTGV2ZWwge1xuICAvKiogRXJyb3IgZXZlbnRzIHRoYXQgYXJlIGxpa2VseSB0byBjYXVzZSBwcm9ibGVtcy4gKi9cbiAgZXJyb3IgPSBcImVycm9yXCIsXG4gIC8qKiBSb3V0aW5lIGluZm9ybWF0aW9uLCBzdWNoIGFzIG9uZ29pbmcgc3RhdHVzIG9yIHBlcmZvcm1hbmNlLiAqL1xuICBpbmZvID0gXCJpbmZvXCIsXG4gIC8qKiBBZGRpdGlvbmFsIHJlbGV2YW50IGluZm9ybWF0aW9uLiAqL1xuICB2ZXJib3NlID0gXCJ2ZXJib3NlXCIsXG4gIC8qKiBEZWJ1ZyBvciB0cmFjZSBpbmZvcm1hdGlvbi4gKi9cbiAgZGVidWcgPSBcImRlYnVnXCIsXG4gIC8qKiB3YXkgdG9vIHZlcmJvc2Ugb3Igc2lsbHkgaW5mb3JtYXRpb24uICovXG4gIHNpbGx5ID0gXCJzaWxseVwiLFxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBOdW1lcmljIHZhbHVlcyBhc3NvY2lhdGVkIHdpdGggbG9nIGxldmVscy5cbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIGEgbnVtZXJpYyByZXByZXNlbnRhdGlvbiBvZiBsb2cgbGV2ZWxzIGZvciBjb21wYXJpc29uIGFuZCBmaWx0ZXJpbmcuXG4gKiBAY29uc3QgTnVtZXJpY0xvZ0xldmVsc1xuICogQHByb3BlcnR5IHtudW1iZXJ9IGVycm9yIC0gTnVtZXJpYyB2YWx1ZSBmb3IgZXJyb3IgbGV2ZWwgKDIpLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGluZm8gLSBOdW1lcmljIHZhbHVlIGZvciBpbmZvIGxldmVsICg0KS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB2ZXJib3NlIC0gTnVtZXJpYyB2YWx1ZSBmb3IgdmVyYm9zZSBsZXZlbCAoNikuXG4gKiBAcHJvcGVydHkge251bWJlcn0gZGVidWcgLSBOdW1lcmljIHZhbHVlIGZvciBkZWJ1ZyBsZXZlbCAoNykuXG4gKiBAcHJvcGVydHkge251bWJlcn0gc2lsbHkgLSBOdW1lcmljIHZhbHVlIGZvciBzaWxseSBsZXZlbCAoOSkuXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGNvbnN0IE51bWVyaWNMb2dMZXZlbHMgPSB7XG4gIGVycm9yOiAyLFxuICBpbmZvOiA0LFxuICB2ZXJib3NlOiA2LFxuICBkZWJ1ZzogNyxcbiAgc2lsbHk6IDksXG59O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFbnVtIGZvciBsb2dnaW5nIG91dHB1dCBtb2Rlcy5cbiAqIEBzdW1tYXJ5IERlZmluZXMgZGlmZmVyZW50IG91dHB1dCBmb3JtYXRzIGZvciBsb2cgbWVzc2FnZXMuXG4gKiBAZW51bSB7c3RyaW5nfVxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBlbnVtIExvZ2dpbmdNb2RlIHtcbiAgLyoqIFJhdyB0ZXh0IGZvcm1hdCBmb3IgaHVtYW4gcmVhZGFiaWxpdHkgKi9cbiAgUkFXID0gXCJyYXdcIixcbiAgLyoqIEpTT04gZm9ybWF0IGZvciBtYWNoaW5lIHBhcnNpbmcgKi9cbiAgSlNPTiA9IFwianNvblwiLFxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IHRoZW1lIGZvciBzdHlsaW5nIGxvZyBvdXRwdXQuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBkZWZhdWx0IGNvbG9yIGFuZCBzdHlsZSBzZXR0aW5ncyBmb3IgdmFyaW91cyBjb21wb25lbnRzIG9mIGxvZyBtZXNzYWdlcy5cbiAqIEBjb25zdCBEZWZhdWx0VGhlbWVcbiAqIEB0eXBlZGVmIHtUaGVtZX0gRGVmYXVsdFRoZW1lXG4gKiBAcHJvcGVydHkge09iamVjdH0gY2xhc3MgLSBTdHlsaW5nIGZvciBjbGFzcyBuYW1lcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjbGFzcy5mZyAtIEZvcmVncm91bmQgY29sb3IgY29kZSBmb3IgY2xhc3MgbmFtZXMgKDM0KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBpZCAtIFN0eWxpbmcgZm9yIGlkZW50aWZpZXJzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGlkLmZnIC0gRm9yZWdyb3VuZCBjb2xvciBjb2RlIGZvciBpZGVudGlmaWVycyAoMzYpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IHN0YWNrIC0gU3R5bGluZyBmb3Igc3RhY2sgdHJhY2VzIChlbXB0eSBvYmplY3QpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IHRpbWVzdGFtcCAtIFN0eWxpbmcgZm9yIHRpbWVzdGFtcHMgKGVtcHR5IG9iamVjdCkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbWVzc2FnZSAtIFN0eWxpbmcgZm9yIGRpZmZlcmVudCB0eXBlcyBvZiBtZXNzYWdlcy5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBtZXNzYWdlLmVycm9yIC0gU3R5bGluZyBmb3IgZXJyb3IgbWVzc2FnZXMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gbWVzc2FnZS5lcnJvci5mZyAtIEZvcmVncm91bmQgY29sb3IgY29kZSBmb3IgZXJyb3IgbWVzc2FnZXMgKDMxKS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBtZXRob2QgLSBTdHlsaW5nIGZvciBtZXRob2QgbmFtZXMgKGVtcHR5IG9iamVjdCkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nTGV2ZWwgLSBTdHlsaW5nIGZvciBkaWZmZXJlbnQgbG9nIGxldmVscy5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2dMZXZlbC5lcnJvciAtIFN0eWxpbmcgZm9yIGVycm9yIGxldmVsIGxvZ3MuXG4gKiBAcHJvcGVydHkge251bWJlcn0gbG9nTGV2ZWwuZXJyb3IuZmcgLSBGb3JlZ3JvdW5kIGNvbG9yIGNvZGUgZm9yIGVycm9yIGxldmVsIGxvZ3MgKDMxKS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IGxvZ0xldmVsLmVycm9yLnN0eWxlIC0gU3R5bGUgYXR0cmlidXRlcyBmb3IgZXJyb3IgbGV2ZWwgbG9ncyAoW1wiYm9sZFwiXSkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nTGV2ZWwuaW5mbyAtIFN0eWxpbmcgZm9yIGluZm8gbGV2ZWwgbG9ncyAoZW1wdHkgb2JqZWN0KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2dMZXZlbC52ZXJib3NlIC0gU3R5bGluZyBmb3IgdmVyYm9zZSBsZXZlbCBsb2dzIChlbXB0eSBvYmplY3QpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGxvZ0xldmVsLmRlYnVnIC0gU3R5bGluZyBmb3IgZGVidWcgbGV2ZWwgbG9ncy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsb2dMZXZlbC5kZWJ1Zy5mZyAtIEZvcmVncm91bmQgY29sb3IgY29kZSBmb3IgZGVidWcgbGV2ZWwgbG9ncyAoMzMpLlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBEZWZhdWx0VGhlbWU6IFRoZW1lID0ge1xuICBjbGFzczoge1xuICAgIGZnOiAzNCxcbiAgfSxcbiAgaWQ6IHtcbiAgICBmZzogMzYsXG4gIH0sXG4gIHN0YWNrOiB7fSxcbiAgdGltZXN0YW1wOiB7fSxcbiAgbWVzc2FnZToge1xuICAgIGVycm9yOiB7XG4gICAgICBmZzogMzEsXG4gICAgfSxcbiAgfSxcbiAgbWV0aG9kOiB7fSxcbiAgbG9nTGV2ZWw6IHtcbiAgICBlcnJvcjoge1xuICAgICAgZmc6IDMxLFxuICAgICAgc3R5bGU6IFtcImJvbGRcIl0sXG4gICAgfSxcbiAgICBpbmZvOiB7XG4gICAgICBmZzogMzQsXG4gICAgICBzdHlsZTogW1wiYm9sZFwiXSxcbiAgICB9LFxuICAgIHZlcmJvc2U6IHtcbiAgICAgIGZnOiAzNCxcbiAgICAgIHN0eWxlOiBbXCJib2xkXCJdLFxuICAgIH0sXG4gICAgZGVidWc6IHtcbiAgICAgIGZnOiAzMyxcbiAgICAgIHN0eWxlOiBbXCJib2xkXCJdLFxuICAgIH0sXG4gIH0sXG59O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IGNvbmZpZ3VyYXRpb24gZm9yIGxvZ2dpbmcuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBkZWZhdWx0IHNldHRpbmdzIGZvciB0aGUgbG9nZ2luZyBzeXN0ZW0sIGluY2x1ZGluZyB2ZXJib3NpdHksIGxvZyBsZXZlbCwgc3R5bGluZywgYW5kIHRpbWVzdGFtcCBmb3JtYXQuXG4gKiBAY29uc3QgRGVmYXVsdExvZ2dpbmdDb25maWdcbiAqIEB0eXBlZGVmIHtMb2dnaW5nQ29uZmlnfSBEZWZhdWx0TG9nZ2luZ0NvbmZpZ1xuICogQHByb3BlcnR5IHtudW1iZXJ9IHZlcmJvc2UgLSBWZXJib3NpdHkgbGV2ZWwgKDApLlxuICogQHByb3BlcnR5IHtMb2dMZXZlbH0gbGV2ZWwgLSBEZWZhdWx0IGxvZyBsZXZlbCAoTG9nTGV2ZWwuaW5mbykuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGxvZ0xldmVsIC0gV2hldGhlciB0byBkaXNwbGF5IGxvZyBsZXZlbCBpbiBvdXRwdXQgKHRydWUpLlxuICogQHByb3BlcnR5IHtMb2dnaW5nTW9kZX0gbW9kZSAtIE91dHB1dCBmb3JtYXQgbW9kZSAoTG9nZ2luZ01vZGUuUkFXKS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gc3R5bGUgLSBXaGV0aGVyIHRvIGFwcGx5IHN0eWxpbmcgdG8gbG9nIG91dHB1dCAoZmFsc2UpLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHNlcGFyYXRvciAtIFNlcGFyYXRvciBiZXR3ZWVuIGxvZyBjb21wb25lbnRzIChcIiAtIFwiKS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gdGltZXN0YW1wIC0gV2hldGhlciB0byBpbmNsdWRlIHRpbWVzdGFtcHMgaW4gbG9nIG1lc3NhZ2VzICh0cnVlKS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB0aW1lc3RhbXBGb3JtYXQgLSBGb3JtYXQgZm9yIHRpbWVzdGFtcHMgKFwiSEg6bW06c3MuU1NTXCIpLlxuICogQHByb3BlcnR5IHtib29sZWFufSBjb250ZXh0IC0gV2hldGhlciB0byBpbmNsdWRlIGNvbnRleHQgaW5mb3JtYXRpb24gaW4gbG9nIG1lc3NhZ2VzICh0cnVlKS5cbiAqIEBwcm9wZXJ0eSB7VGhlbWV9IHRoZW1lIC0gVGhlIHRoZW1lIHRvIHVzZSBmb3Igc3R5bGluZyBsb2cgbWVzc2FnZXMgKERlZmF1bHRUaGVtZSkuXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGNvbnN0IERlZmF1bHRMb2dnaW5nQ29uZmlnOiBMb2dnaW5nQ29uZmlnID0ge1xuICB2ZXJib3NlOiAwLFxuICBsZXZlbDogTG9nTGV2ZWwuaW5mbyxcbiAgbG9nTGV2ZWw6IHRydWUsXG4gIG1vZGU6IExvZ2dpbmdNb2RlLlJBVyxcbiAgc3R5bGU6IGZhbHNlLFxuICBjb250ZXh0U2VwYXJhdG9yOiBcIi5cIixcbiAgc2VwYXJhdG9yOiBcIiAtIFwiLFxuICB0aW1lc3RhbXA6IHRydWUsXG4gIHRpbWVzdGFtcEZvcm1hdDogXCJISDptbTpzcy5TU1NcIixcbiAgY29udGV4dDogdHJ1ZSxcbiAgZm9ybWF0OiBcInJhd1wiLFxuICBwYXR0ZXJuOiBcIntsZXZlbH0gW3t0aW1lc3RhbXB9XSB7Y29udGV4dH0gLSB7bWVzc2FnZX0ge3N0YWNrfVwiLFxuICB0aGVtZTogRGVmYXVsdFRoZW1lLFxufTtcbiIsIi8qKlxuICogQHN1bW1hcnkgVXRpbCBmdW5jdGlvbiB0byBwcm92aWRlIHN0cmluZyBmb3JtYXQgZnVuY3Rpb25hbGl0eSBzaW1pbGFyIHRvIEMjJ3Mgc3RyaW5nLmZvcm1hdFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmdcbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nIHwgbnVtYmVyPiB8IFJlY29yZDxzdHJpbmcsIGFueT59IFthcmdzXSByZXBsYWNlbWVudHMgbWFkZSBieSBvcmRlciBvZiBhcHBlYXJhbmNlIChyZXBsYWNlbWVudDAgd2lsIHJlcGxhY2UgezB9IGFuZCBzbyBvbilcbiAqIEByZXR1cm4ge3N0cmluZ30gZm9ybWF0dGVkIHN0cmluZ1xuICpcbiAqIEBmdW5jdGlvbiBzdHJpbmdGb3JtYXRcbiAqIEBtZW1iZXJPZiBtb2R1bGU6bG9nZ2luZ1xuICogQGNhdGVnb3J5IE1vZGVsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdHJpbmdGb3JtYXQoXG4gIHN0cmluZzogc3RyaW5nLFxuICAuLi5hcmdzOiAoc3RyaW5nIHwgbnVtYmVyIHwgUmVjb3JkPHN0cmluZywgYW55PilbXVxuKSB7XG4gIGlmIChhcmdzLmxlbmd0aCA+IDEpIHtcbiAgICBpZiAoXG4gICAgICAhYXJncy5ldmVyeSgoYXJnKSA9PiB0eXBlb2YgYXJnID09PSBcInN0cmluZ1wiIHx8IHR5cGVvZiBhcmcgPT09IFwibnVtYmVyXCIpXG4gICAgKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgT25seSBzdHJpbmcgYW5kIG51bWJlciBhcmd1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgbXVsdGlwbGUgcmVwbGFjZW1lbnRzLmBcbiAgICAgICk7XG4gIH1cblxuICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGFyZ3NbMF0gPT09IFwib2JqZWN0XCIpIHtcbiAgICBjb25zdCBvYmogPSBhcmdzWzBdIGFzIFJlY29yZDxzdHJpbmcsIGFueT47XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKG9iaikucmVkdWNlKChhY2MsIFtrZXksIHZhbF0pID0+IHtcbiAgICAgIHJldHVybiBhY2MucmVwbGFjZShuZXcgUmVnRXhwKGBcXFxceyR7a2V5fVxcXFx9YCwgXCJnXCIpLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgICB9KTtcbiAgICB9LCBzdHJpbmcpO1xuICB9XG5cbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC97KFxcZCspfS9nLCBmdW5jdGlvbiAobWF0Y2gsIG51bWJlcikge1xuICAgIHJldHVybiB0eXBlb2YgYXJnc1tudW1iZXJdICE9PSBcInVuZGVmaW5lZFwiXG4gICAgICA/IGFyZ3NbbnVtYmVyXS50b1N0cmluZygpXG4gICAgICA6IFwidW5kZWZpbmVkXCI7XG4gIH0pO1xufVxuIiwiaW1wb3J0IHtcbiAgTG9nZ2VyRmFjdG9yeSxcbiAgTG9nZ2luZ0NvbmZpZyxcbiAgTG9nZ2luZ0NvbnRleHQsXG4gIFN0cmluZ0xpa2UsXG4gIFRoZW1lLFxuICBUaGVtZU9wdGlvbixcbiAgVGhlbWVPcHRpb25CeUxvZ0xldmVsLFxuICBMb2dnZXIsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBDb2xvcml6ZU9wdGlvbnMsIHN0eWxlLCBTdHlsZWRTdHJpbmcgfSBmcm9tIFwic3R5bGVkLXN0cmluZy1idWlsZGVyXCI7XG5pbXBvcnQge1xuICBEZWZhdWx0TG9nZ2luZ0NvbmZpZyxcbiAgRGVmYXVsdFRoZW1lLFxuICBMb2dMZXZlbCxcbiAgTnVtZXJpY0xvZ0xldmVscyxcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBzdHJpbmdGb3JtYXQgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBIG1pbmltYWwgbG9nZ2VyIGltcGxlbWVudGF0aW9uLlxuICogQHN1bW1hcnkgTWluaUxvZ2dlciBpcyBhIGxpZ2h0d2VpZ2h0IGxvZ2dpbmcgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoZSBMb2dnZXIgaW50ZXJmYWNlLlxuICogSXQgcHJvdmlkZXMgYmFzaWMgbG9nZ2luZyBmdW5jdGlvbmFsaXR5IHdpdGggc3VwcG9ydCBmb3IgZGlmZmVyZW50IGxvZyBsZXZlbHMsIHZlcmJvc2l0eSxcbiAqIGNvbnRleHQtYXdhcmUgbG9nZ2luZywgYW5kIGN1c3RvbWl6YWJsZSBmb3JtYXR0aW5nLlxuICogQHBhcmFtIHtzdHJpbmd9IGNvbnRleHQgLSBUaGUgY29udGV4dCAodHlwaWNhbGx5IGNsYXNzIG5hbWUpIHRoaXMgbG9nZ2VyIGlzIGFzc29jaWF0ZWQgd2l0aFxuICogQHBhcmFtIHtQYXJ0aWFsPExvZ2dpbmdDb25maWc+fSBjb25mIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvbiB0byBvdmVycmlkZSBnbG9iYWwgc2V0dGluZ3NcbiAqIEBjbGFzcyBNaW5pTG9nZ2VyXG4gKiBAZXhhbXBsZVxuICogLy8gQ3JlYXRlIGEgbmV3IGxvZ2dlciBmb3IgYSBjbGFzc1xuICogY29uc3QgbG9nZ2VyID0gbmV3IE1pbmlMb2dnZXIoJ015Q2xhc3MnKTtcbiAqXG4gKiAvLyBMb2cgbWVzc2FnZXMgYXQgZGlmZmVyZW50IGxldmVsc1xuICogbG9nZ2VyLmluZm8oJ1RoaXMgaXMgYW4gaW5mbyBtZXNzYWdlJyk7XG4gKiBsb2dnZXIuZGVidWcoJ1RoaXMgaXMgYSBkZWJ1ZyBtZXNzYWdlJyk7XG4gKiBsb2dnZXIuZXJyb3IoJ1NvbWV0aGluZyB3ZW50IHdyb25nJyk7XG4gKlxuICogLy8gQ3JlYXRlIGEgY2hpbGQgbG9nZ2VyIGZvciBhIHNwZWNpZmljIG1ldGhvZFxuICogY29uc3QgbWV0aG9kTG9nZ2VyID0gbG9nZ2VyLmZvcignbXlNZXRob2QnKTtcbiAqIG1ldGhvZExvZ2dlci52ZXJib3NlKCdEZXRhaWxlZCBpbmZvcm1hdGlvbicsIDIpO1xuICpcbiAqIC8vIExvZyB3aXRoIGN1c3RvbSBjb25maWd1cmF0aW9uXG4gKiBsb2dnZXIuZm9yKCdzcGVjaWFsTWV0aG9kJywgeyBzdHlsZTogdHJ1ZSB9KS5pbmZvKCdTdHlsZWQgbWVzc2FnZScpO1xuICovXG5leHBvcnQgY2xhc3MgTWluaUxvZ2dlciBpbXBsZW1lbnRzIExvZ2dlciB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBjb250ZXh0OiBzdHJpbmcsXG4gICAgcHJvdGVjdGVkIGNvbmY/OiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+XG4gICkge31cblxuICBwcm90ZWN0ZWQgY29uZmlnKFxuICAgIGtleToga2V5b2YgTG9nZ2luZ0NvbmZpZ1xuICApOiBMb2dnaW5nQ29uZmlnW2tleW9mIExvZ2dpbmdDb25maWddIHtcbiAgICBpZiAodGhpcy5jb25mICYmIGtleSBpbiB0aGlzLmNvbmYpIHJldHVybiB0aGlzLmNvbmZba2V5XTtcbiAgICByZXR1cm4gTG9nZ2luZy5nZXRDb25maWcoKVtrZXldO1xuICB9XG5cbiAgZm9yKG1ldGhvZDogc3RyaW5nIHwgKCguLi5hcmdzOiBhbnlbXSkgPT4gYW55KSk6IExvZ2dlcjtcbiAgZm9yKGNvbmZpZzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPik6IExvZ2dlcjtcbiAgZm9yKFxuICAgIG1ldGhvZDogc3RyaW5nIHwgKCguLi5hcmdzOiBhbnlbXSkgPT4gYW55KSB8IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4sXG4gICAgY29uZmlnOiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+LFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IExvZ2dlcjtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgY2hpbGQgbG9nZ2VyIGZvciBhIHNwZWNpZmljIG1ldGhvZCBvciBjb250ZXh0XG4gICAqIEBzdW1tYXJ5IFJldHVybnMgYSBuZXcgbG9nZ2VyIGluc3RhbmNlIHdpdGggdGhlIGN1cnJlbnQgY29udGV4dCBleHRlbmRlZCBieSB0aGUgc3BlY2lmaWVkIG1ldGhvZCBuYW1lXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgRnVuY3Rpb259IG1ldGhvZCAtIFRoZSBtZXRob2QgbmFtZSBvciBmdW5jdGlvbiB0byBjcmVhdGUgYSBsb2dnZXIgZm9yXG4gICAqIEBwYXJhbSB7UGFydGlhbDxMb2dnaW5nQ29uZmlnPn0gY29uZmlnIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvbiB0byBvdmVycmlkZSBzZXR0aW5nc1xuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgbG9nZ2VyIGZhY3RvcnlcbiAgICogQHJldHVybiB7TG9nZ2VyfSBBIG5ldyBsb2dnZXIgaW5zdGFuY2UgZm9yIHRoZSBzcGVjaWZpZWQgbWV0aG9kXG4gICAqL1xuICBmb3IoXG4gICAgbWV0aG9kPzogc3RyaW5nIHwgKCguLi5hcmdzOiBhbnlbXSkgPT4gYW55KSB8IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4sXG4gICAgY29uZmlnPzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPixcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogTG9nZ2VyIHtcbiAgICBpZiAoIWNvbmZpZyAmJiB0eXBlb2YgbWV0aG9kID09PSBcIm9iamVjdFwiKSB7XG4gICAgICBjb25maWcgPSBtZXRob2Q7XG4gICAgICBtZXRob2QgPSB1bmRlZmluZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1ldGhvZCA9IG1ldGhvZFxuICAgICAgICA/IHR5cGVvZiBtZXRob2QgPT09IFwic3RyaW5nXCJcbiAgICAgICAgICA/IG1ldGhvZFxuICAgICAgICAgIDogKG1ldGhvZCBhcyBhbnkpLm5hbWVcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQcm94eSh0aGlzLCB7XG4gICAgICBnZXQ6ICh0YXJnZXQ6IHR5cGVvZiB0aGlzLCBwOiBzdHJpbmcgfCBzeW1ib2wsIHJlY2VpdmVyOiBhbnkpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBwLCByZWNlaXZlcik7XG4gICAgICAgIGlmIChwID09PSBcImNvbmZpZ1wiKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBQcm94eSh0aGlzLmNvbmZpZywge1xuICAgICAgICAgICAgZ2V0OiAodGFyZ2V0OiB0eXBlb2YgdGhpcy5jb25maWcsIHA6IHN0cmluZyB8IHN5bWJvbCkgPT4ge1xuICAgICAgICAgICAgICBpZiAoY29uZmlnICYmIHAgaW4gY29uZmlnKVxuICAgICAgICAgICAgICAgIHJldHVybiBjb25maWdbcCBhcyBrZXlvZiBMb2dnaW5nQ29uZmlnXTtcbiAgICAgICAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KHRhcmdldCwgcCwgcmVjZWl2ZXIpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocCA9PT0gXCJjb250ZXh0XCIgJiYgbWV0aG9kKSB7XG4gICAgICAgICAgcmV0dXJuIFtyZXN1bHQsIG1ldGhvZF0uam9pbihcIi5cIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBmb3JtYXR0ZWQgbG9nIHN0cmluZ1xuICAgKiBAc3VtbWFyeSBHZW5lcmF0ZXMgYSBsb2cgc3RyaW5nIHdpdGggdGltZXN0YW1wLCBjb2xvcmVkIGxvZyBsZXZlbCwgY29udGV4dCwgYW5kIG1lc3NhZ2VcbiAgICogQHBhcmFtIHtMb2dMZXZlbH0gbGV2ZWwgLSBUaGUgbG9nIGxldmVsIGZvciB0aGlzIG1lc3NhZ2VcbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlIHwgRXJyb3J9IG1lc3NhZ2UgLSBUaGUgbWVzc2FnZSB0byBsb2cgb3IgYW4gRXJyb3Igb2JqZWN0XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RhY2tdIC0gT3B0aW9uYWwgc3RhY2sgdHJhY2UgdG8gaW5jbHVkZSBpbiB0aGUgbG9nXG4gICAqIEByZXR1cm4ge3N0cmluZ30gQSBmb3JtYXR0ZWQgbG9nIHN0cmluZyB3aXRoIGFsbCBjb21wb25lbnRzXG4gICAqL1xuICBwcm90ZWN0ZWQgY3JlYXRlTG9nKFxuICAgIGxldmVsOiBMb2dMZXZlbCxcbiAgICBtZXNzYWdlOiBTdHJpbmdMaWtlIHwgRXJyb3IsXG4gICAgc3RhY2s/OiBzdHJpbmdcbiAgKTogc3RyaW5nIHtcbiAgICBjb25zdCBsb2c6IFJlY29yZDxcbiAgICAgIFwidGltZXN0YW1wXCIgfCBcImxldmVsXCIgfCBcImNvbnRleHRcIiB8IFwiY29ycmVsYXRpb25JZFwiIHwgXCJtZXNzYWdlXCIgfCBcInN0YWNrXCIsXG4gICAgICBzdHJpbmdcbiAgICA+ID0ge30gYXMgYW55O1xuICAgIGNvbnN0IHN0eWxlID0gdGhpcy5jb25maWcoXCJzdHlsZVwiKTtcbiAgICBpZiAodGhpcy5jb25maWcoXCJ0aW1lc3RhbXBcIikpIHtcbiAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gICAgICBjb25zdCB0aW1lc3RhbXAgPSBzdHlsZSA/IExvZ2dpbmcudGhlbWUoZGF0ZSwgXCJ0aW1lc3RhbXBcIiwgbGV2ZWwpIDogZGF0ZTtcbiAgICAgIGxvZy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnKFwibG9nTGV2ZWxcIikpIHtcbiAgICAgIGNvbnN0IGx2bDogc3RyaW5nID0gc3R5bGVcbiAgICAgICAgPyBMb2dnaW5nLnRoZW1lKGxldmVsLCBcImxvZ0xldmVsXCIsIGxldmVsKVxuICAgICAgICA6IGxldmVsO1xuICAgICAgbG9nLmxldmVsID0gbHZsLnRvVXBwZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnKFwiY29udGV4dFwiKSkge1xuICAgICAgY29uc3QgY29udGV4dDogc3RyaW5nID0gc3R5bGVcbiAgICAgICAgPyBMb2dnaW5nLnRoZW1lKHRoaXMuY29udGV4dCwgXCJjbGFzc1wiLCBsZXZlbClcbiAgICAgICAgOiB0aGlzLmNvbnRleHQ7XG4gICAgICBsb2cuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnKFwiY29ycmVsYXRpb25JZFwiKSkge1xuICAgICAge1xuICAgICAgICBjb25zdCBpZDogc3RyaW5nID0gc3R5bGVcbiAgICAgICAgICA/IExvZ2dpbmcudGhlbWUodGhpcy5jb25maWcoXCJjb3JyZWxhdGlvbklkXCIpIS50b1N0cmluZygpLCBcImlkXCIsIGxldmVsKVxuICAgICAgICAgIDogdGhpcy5jb25maWcoXCJjb3JyZWxhdGlvbklkXCIpIS50b1N0cmluZygpO1xuICAgICAgICBsb2cuY29ycmVsYXRpb25JZCA9IGlkO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IG1zZzogc3RyaW5nID0gc3R5bGVcbiAgICAgID8gTG9nZ2luZy50aGVtZShcbiAgICAgICAgICB0eXBlb2YgbWVzc2FnZSA9PT0gXCJzdHJpbmdcIiA/IG1lc3NhZ2UgOiAobWVzc2FnZSBhcyBFcnJvcikubWVzc2FnZSxcbiAgICAgICAgICBcIm1lc3NhZ2VcIixcbiAgICAgICAgICBsZXZlbFxuICAgICAgICApXG4gICAgICA6IHR5cGVvZiBtZXNzYWdlID09PSBcInN0cmluZ1wiXG4gICAgICAgID8gbWVzc2FnZVxuICAgICAgICA6IChtZXNzYWdlIGFzIEVycm9yKS5tZXNzYWdlO1xuICAgIGxvZy5tZXNzYWdlID0gbXNnO1xuICAgIGlmIChzdGFjayB8fCBtZXNzYWdlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHN0YWNrID0gc3R5bGVcbiAgICAgICAgPyBMb2dnaW5nLnRoZW1lKFxuICAgICAgICAgICAgKHN0YWNrIHx8IChtZXNzYWdlIGFzIEVycm9yKS5zdGFjaykgYXMgc3RyaW5nLFxuICAgICAgICAgICAgXCJzdGFja1wiLFxuICAgICAgICAgICAgbGV2ZWxcbiAgICAgICAgICApXG4gICAgICAgIDogc3RhY2s7XG4gICAgICBsb2cuc3RhY2sgPSBgXFxuU3RhY2sgdHJhY2U6XFxuJHtzdGFja31gO1xuICAgIH1cblxuICAgIHN3aXRjaCAodGhpcy5jb25maWcoXCJmb3JtYXRcIikpIHtcbiAgICAgIGNhc2UgXCJqc29uXCI6XG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShsb2cpO1xuICAgICAgY2FzZSBcInJhd1wiOlxuICAgICAgICByZXR1cm4gKHRoaXMuY29uZmlnKFwicGF0dGVyblwiKSBhcyBzdHJpbmcpXG4gICAgICAgICAgLnNwbGl0KFwiIFwiKVxuICAgICAgICAgIC5tYXAoKHMpID0+IHtcbiAgICAgICAgICAgIGlmICghcy5tYXRjaCgvXFx7Lio/fS9nKSkgcmV0dXJuIHM7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWRTID0gc3RyaW5nRm9ybWF0KHMsIGxvZyk7XG4gICAgICAgICAgICBpZiAoZm9ybWF0dGVkUyAhPT0gcykgcmV0dXJuIGZvcm1hdHRlZFM7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLmZpbHRlcigocykgPT4gcylcbiAgICAgICAgICAuam9pbihcIiBcIik7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGxvZ2dpbmcgZm9ybWF0OiAke3RoaXMuY29uZmlnKFwiZm9ybWF0XCIpfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGxvZyBsZXZlbFxuICAgKiBAc3VtbWFyeSBDaGVja3MgaWYgdGhlIG1lc3NhZ2Ugc2hvdWxkIGJlIGxvZ2dlZCBiYXNlZCBvbiB0aGUgY3VycmVudCBsb2cgbGV2ZWwsXG4gICAqIHRoZW4gdXNlcyB0aGUgYXBwcm9wcmlhdGUgY29uc29sZSBtZXRob2QgdG8gb3V0cHV0IHRoZSBmb3JtYXR0ZWQgbG9nXG4gICAqIEBwYXJhbSB7TG9nTGV2ZWx9IGxldmVsIC0gVGhlIGxvZyBsZXZlbCBvZiB0aGUgbWVzc2FnZVxuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2UgfCBFcnJvcn0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkIG9yIGFuIEVycm9yIG9iamVjdFxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0YWNrXSAtIE9wdGlvbmFsIHN0YWNrIHRyYWNlIHRvIGluY2x1ZGUgaW4gdGhlIGxvZ1xuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgcHJvdGVjdGVkIGxvZyhcbiAgICBsZXZlbDogTG9nTGV2ZWwsXG4gICAgbXNnOiBTdHJpbmdMaWtlIHwgRXJyb3IsXG4gICAgc3RhY2s/OiBzdHJpbmdcbiAgKTogdm9pZCB7XG4gICAgaWYgKFxuICAgICAgTnVtZXJpY0xvZ0xldmVsc1t0aGlzLmNvbmZpZyhcImxldmVsXCIpIGFzIExvZ0xldmVsXSA8XG4gICAgICBOdW1lcmljTG9nTGV2ZWxzW2xldmVsXVxuICAgIClcbiAgICAgIHJldHVybjtcbiAgICBsZXQgbWV0aG9kO1xuICAgIHN3aXRjaCAobGV2ZWwpIHtcbiAgICAgIGNhc2UgTG9nTGV2ZWwuaW5mbzpcbiAgICAgICAgbWV0aG9kID0gY29uc29sZS5sb2c7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBMb2dMZXZlbC52ZXJib3NlOlxuICAgICAgY2FzZSBMb2dMZXZlbC5kZWJ1ZzpcbiAgICAgICAgbWV0aG9kID0gY29uc29sZS5kZWJ1ZztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIExvZ0xldmVsLmVycm9yOlxuICAgICAgICBtZXRob2QgPSBjb25zb2xlLmVycm9yO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgbG9nIGxldmVsXCIpO1xuICAgIH1cbiAgICBtZXRob2QodGhpcy5jcmVhdGVMb2cobGV2ZWwsIG1zZywgc3RhY2spKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIHNpbGx5IGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBzaWxseSBsZXZlbCBpZiB0aGUgY3VycmVudCB2ZXJib3NpdHkgc2V0dGluZyBhbGxvd3MgaXRcbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWRcbiAgICogQHBhcmFtIHtudW1iZXJ9IFt2ZXJib3NpdHk9MF0gLSBUaGUgdmVyYm9zaXR5IGxldmVsIG9mIHRoZSBtZXNzYWdlXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzaWxseShtc2c6IFN0cmluZ0xpa2UsIHZlcmJvc2l0eTogbnVtYmVyID0gMCk6IHZvaWQge1xuICAgIGlmICgodGhpcy5jb25maWcoXCJ2ZXJib3NlXCIpIGFzIG51bWJlcikgPj0gdmVyYm9zaXR5KVxuICAgICAgdGhpcy5sb2coTG9nTGV2ZWwudmVyYm9zZSwgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIHZlcmJvc2UgbGV2ZWxcbiAgICogQHN1bW1hcnkgTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIHZlcmJvc2UgbGV2ZWwgaWYgdGhlIGN1cnJlbnQgdmVyYm9zaXR5IHNldHRpbmcgYWxsb3dzIGl0XG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZX0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbdmVyYm9zaXR5PTBdIC0gVGhlIHZlcmJvc2l0eSBsZXZlbCBvZiB0aGUgbWVzc2FnZVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgdmVyYm9zZShtc2c6IFN0cmluZ0xpa2UsIHZlcmJvc2l0eTogbnVtYmVyID0gMCk6IHZvaWQge1xuICAgIGlmICgodGhpcy5jb25maWcoXCJ2ZXJib3NlXCIpIGFzIG51bWJlcikgPj0gdmVyYm9zaXR5KVxuICAgICAgdGhpcy5sb2coTG9nTGV2ZWwudmVyYm9zZSwgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGluZm8gbGV2ZWxcbiAgICogQHN1bW1hcnkgTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGluZm8gbGV2ZWwgZm9yIGdlbmVyYWwgYXBwbGljYXRpb24gaW5mb3JtYXRpb25cbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWRcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIGluZm8obXNnOiBTdHJpbmdMaWtlKTogdm9pZCB7XG4gICAgdGhpcy5sb2coTG9nTGV2ZWwuaW5mbywgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGRlYnVnIGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBkZWJ1ZyBsZXZlbCBmb3IgZGV0YWlsZWQgdHJvdWJsZXNob290aW5nIGluZm9ybWF0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZX0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBkZWJ1Zyhtc2c6IFN0cmluZ0xpa2UpOiB2b2lkIHtcbiAgICB0aGlzLmxvZyhMb2dMZXZlbC5kZWJ1ZywgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGVycm9yIGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBlcnJvciBsZXZlbCBmb3IgZXJyb3JzIGFuZCBleGNlcHRpb25zXG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZSB8IEVycm9yfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQgb3IgYW4gRXJyb3Igb2JqZWN0XG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBlcnJvcihtc2c6IFN0cmluZ0xpa2UgfCBFcnJvcik6IHZvaWQge1xuICAgIHRoaXMubG9nKExvZ0xldmVsLmVycm9yLCBtc2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBVcGRhdGVzIHRoZSBsb2dnZXIgY29uZmlndXJhdGlvblxuICAgKiBAc3VtbWFyeSBNZXJnZXMgdGhlIHByb3ZpZGVkIGNvbmZpZ3VyYXRpb24gd2l0aCB0aGUgZXhpc3RpbmcgY29uZmlndXJhdGlvblxuICAgKiBAcGFyYW0ge1BhcnRpYWw8TG9nZ2luZ0NvbmZpZz59IGNvbmZpZyAtIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gYXBwbHlcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHNldENvbmZpZyhjb25maWc6IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4pOiB2b2lkIHtcbiAgICB0aGlzLmNvbmYgPSB7IC4uLih0aGlzLmNvbmYgfHwge30pLCAuLi5jb25maWcgfTtcbiAgfVxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBIHN0YXRpYyBjbGFzcyBmb3IgbWFuYWdpbmcgbG9nZ2luZyBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBUaGUgTG9nZ2luZyBjbGFzcyBwcm92aWRlcyBhIGNlbnRyYWxpemVkIGxvZ2dpbmcgbWVjaGFuaXNtIHdpdGggc3VwcG9ydCBmb3JcbiAqIGRpZmZlcmVudCBsb2cgbGV2ZWxzLCB2ZXJib3NpdHksIGFuZCBzdHlsaW5nLiBJdCB1c2VzIGEgc2luZ2xldG9uIHBhdHRlcm4gdG8gbWFpbnRhaW4gYSBnbG9iYWxcbiAqIGxvZ2dlciBpbnN0YW5jZSBhbmQgYWxsb3dzIGNyZWF0aW5nIHNwZWNpZmljIGxvZ2dlcnMgZm9yIGRpZmZlcmVudCBjbGFzc2VzIGFuZCBtZXRob2RzLlxuICogQGNsYXNzIExvZ2dpbmdcbiAqIEBleGFtcGxlXG4gKiAvLyBTZXQgZ2xvYmFsIGNvbmZpZ3VyYXRpb25cbiAqIExvZ2dpbmcuc2V0Q29uZmlnKHsgbGV2ZWw6IExvZ0xldmVsLmRlYnVnLCBzdHlsZTogdHJ1ZSB9KTtcbiAqXG4gKiAvLyBHZXQgYSBsb2dnZXIgZm9yIGEgc3BlY2lmaWMgY2xhc3NcbiAqIGNvbnN0IGxvZ2dlciA9IExvZ2dpbmcuZm9yKCdNeUNsYXNzJyk7XG4gKlxuICogLy8gTG9nIG1lc3NhZ2VzIGF0IGRpZmZlcmVudCBsZXZlbHNcbiAqIGxvZ2dlci5pbmZvKCdBcHBsaWNhdGlvbiBzdGFydGVkJyk7XG4gKiBsb2dnZXIuZGVidWcoJ1Byb2Nlc3NpbmcgZGF0YS4uLicpO1xuICpcbiAqIC8vIExvZyB3aXRoIGNvbnRleHRcbiAqIGNvbnN0IG1ldGhvZExvZ2dlciA9IExvZ2dpbmcuZm9yKCdNeUNsYXNzLm15TWV0aG9kJyk7XG4gKiBtZXRob2RMb2dnZXIudmVyYm9zZSgnRGV0YWlsZWQgb3BlcmF0aW9uIGluZm9ybWF0aW9uJywgMSk7XG4gKlxuICogLy8gTG9nIGVycm9yc1xuICogdHJ5IHtcbiAqICAgLy8gc29tZSBvcGVyYXRpb25cbiAqIH0gY2F0Y2ggKGVycm9yKSB7XG4gKiAgIGxvZ2dlci5lcnJvcihlcnJvcik7XG4gKiB9XG4gKiBAbWVybWFpZFxuICogY2xhc3NEaWFncmFtXG4gKiAgIGNsYXNzIExvZ2dlciB7XG4gKiAgICAgPDxpbnRlcmZhY2U+PlxuICogICAgICtmb3IobWV0aG9kLCBjb25maWcsIC4uLmFyZ3MpXG4gKiAgICAgK3NpbGx5KG1zZywgdmVyYm9zaXR5KVxuICogICAgICt2ZXJib3NlKG1zZywgdmVyYm9zaXR5KVxuICogICAgICtpbmZvKG1zZylcbiAqICAgICArZGVidWcobXNnKVxuICogICAgICtlcnJvcihtc2cpXG4gKiAgICAgK3NldENvbmZpZyhjb25maWcpXG4gKiAgIH1cbiAqXG4gKiAgIGNsYXNzIExvZ2dpbmcge1xuICogICAgIC1nbG9iYWw6IExvZ2dlclxuICogICAgIC1fZmFjdG9yeTogTG9nZ2VyRmFjdG9yeVxuICogICAgIC1fY29uZmlnOiBMb2dnaW5nQ29uZmlnXG4gKiAgICAgK3NldEZhY3RvcnkoZmFjdG9yeSlcbiAqICAgICArc2V0Q29uZmlnKGNvbmZpZylcbiAqICAgICArZ2V0Q29uZmlnKClcbiAqICAgICArZ2V0KClcbiAqICAgICArdmVyYm9zZShtc2csIHZlcmJvc2l0eSlcbiAqICAgICAraW5mbyhtc2cpXG4gKiAgICAgK2RlYnVnKG1zZylcbiAqICAgICArc2lsbHkobXNnKVxuICogICAgICtlcnJvcihtc2cpXG4gKiAgICAgK2ZvcihvYmplY3QsIGNvbmZpZywgLi4uYXJncylcbiAqICAgICArYmVjYXVzZShyZWFzb24sIGlkKVxuICogICAgICt0aGVtZSh0ZXh0LCB0eXBlLCBsb2dnZXJMZXZlbCwgdGVtcGxhdGUpXG4gKiAgIH1cbiAqXG4gKiAgIGNsYXNzIE1pbmlMb2dnZXIge1xuICogICAgICtjb25zdHJ1Y3Rvcihjb250ZXh0LCBjb25mPylcbiAqICAgfVxuICpcbiAqICAgTG9nZ2luZyAuLj4gTG9nZ2VyIDogY3JlYXRlc1xuICogICBMb2dnaW5nIC4uPiBNaW5pTG9nZ2VyIDogY3JlYXRlcyBieSBkZWZhdWx0XG4gKi9cbmV4cG9ydCBjbGFzcyBMb2dnaW5nIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZVxuICAgKiBAc3VtbWFyeSBBIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiBMb2dnZXIgdXNlZCBmb3IgZ2xvYmFsIGxvZ2dpbmdcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdsb2JhbD86IExvZ2dlcjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEZhY3RvcnkgZnVuY3Rpb24gZm9yIGNyZWF0aW5nIGxvZ2dlciBpbnN0YW5jZXNcbiAgICogQHN1bW1hcnkgQSBmdW5jdGlvbiB0aGF0IGNyZWF0ZXMgbmV3IExvZ2dlciBpbnN0YW5jZXMuIEJ5IGRlZmF1bHQsIGl0IGNyZWF0ZXMgYSBNaW5pTG9nZ2VyLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgX2ZhY3Rvcnk6IExvZ2dlckZhY3RvcnkgPSAoXG4gICAgb2JqZWN0OiBzdHJpbmcsXG4gICAgY29uZmlnPzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPlxuICApID0+IHtcbiAgICByZXR1cm4gbmV3IE1pbmlMb2dnZXIob2JqZWN0LCBjb25maWcpO1xuICB9O1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBsb2dnaW5nIHN5c3RlbVxuICAgKiBAc3VtbWFyeSBTdG9yZXMgdGhlIGdsb2JhbCBsb2dnaW5nIGNvbmZpZ3VyYXRpb24gaW5jbHVkaW5nIHZlcmJvc2l0eSwgbG9nIGxldmVsLCBzdHlsaW5nLCBhbmQgZm9ybWF0dGluZyBzZXR0aW5nc1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgX2NvbmZpZzogTG9nZ2luZ0NvbmZpZyA9IERlZmF1bHRMb2dnaW5nQ29uZmlnO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7fVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgZmFjdG9yeSBmdW5jdGlvbiBmb3IgY3JlYXRpbmcgbG9nZ2VyIGluc3RhbmNlc1xuICAgKiBAc3VtbWFyeSBBbGxvd3MgY3VzdG9taXppbmcgaG93IGxvZ2dlciBpbnN0YW5jZXMgYXJlIGNyZWF0ZWRcbiAgICogQHBhcmFtIHtMb2dnZXJGYWN0b3J5fSBmYWN0b3J5IC0gVGhlIGZhY3RvcnkgZnVuY3Rpb24gdG8gdXNlIGZvciBjcmVhdGluZyBsb2dnZXJzXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzdGF0aWMgc2V0RmFjdG9yeShmYWN0b3J5OiBMb2dnZXJGYWN0b3J5KSB7XG4gICAgTG9nZ2luZy5fZmFjdG9yeSA9IGZhY3Rvcnk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVwZGF0ZXMgdGhlIGdsb2JhbCBsb2dnaW5nIGNvbmZpZ3VyYXRpb25cbiAgICogQHN1bW1hcnkgQWxsb3dzIHVwZGF0aW5nIHRoZSBnbG9iYWwgbG9nZ2luZyBjb25maWd1cmF0aW9uIHdpdGggbmV3IHNldHRpbmdzXG4gICAqIEBwYXJhbSB7UGFydGlhbDxMb2dnaW5nQ29uZmlnPn0gY29uZmlnIC0gVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byBhcHBseVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc3RhdGljIHNldENvbmZpZyhjb25maWc6IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4pIHtcbiAgICBPYmplY3QuYXNzaWduKHRoaXMuX2NvbmZpZywgY29uZmlnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyBhIGNvcHkgb2YgdGhlIGN1cnJlbnQgZ2xvYmFsIGxvZ2dpbmcgY29uZmlndXJhdGlvblxuICAgKiBAc3VtbWFyeSBSZXR1cm5zIGEgY29weSBvZiB0aGUgY3VycmVudCBnbG9iYWwgbG9nZ2luZyBjb25maWd1cmF0aW9uXG4gICAqIEByZXR1cm4ge0xvZ2dpbmdDb25maWd9IEEgY29weSBvZiB0aGUgY3VycmVudCBjb25maWd1cmF0aW9uXG4gICAqL1xuICBzdGF0aWMgZ2V0Q29uZmlnKCk6IExvZ2dpbmdDb25maWcge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCB0aGlzLl9jb25maWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgb3IgY3JlYXRlcyB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICogQHN1bW1hcnkgUmV0dXJucyB0aGUgZXhpc3RpbmcgZ2xvYmFsIGxvZ2dlciBvciBjcmVhdGVzIGEgbmV3IG9uZSBpZiBpdCBkb2Vzbid0IGV4aXN0LlxuICAgKlxuICAgKiBAcmV0dXJuIFRoZSBnbG9iYWwgVmVyYm9zaXR5TG9nZ2VyIGluc3RhbmNlLlxuICAgKi9cbiAgc3RhdGljIGdldCgpOiBMb2dnZXIge1xuICAgIHRoaXMuZ2xvYmFsID0gdGhpcy5nbG9iYWwgPyB0aGlzLmdsb2JhbCA6IHRoaXMuX2ZhY3RvcnkoXCJMb2dnaW5nXCIpO1xuICAgIHJldHVybiB0aGlzLmdsb2JhbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIHZlcmJvc2UgbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRoZSB2ZXJib3NlIGxvZ2dpbmcgdG8gdGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuXG4gICAqIEBwYXJhbSB2ZXJib3NpdHkgLSBUaGUgdmVyYm9zaXR5IGxldmVsIG9mIHRoZSBtZXNzYWdlIChkZWZhdWx0OiAwKS5cbiAgICovXG4gIHN0YXRpYyB2ZXJib3NlKG1zZzogU3RyaW5nTGlrZSwgdmVyYm9zaXR5OiBudW1iZXIgPSAwKTogdm9pZCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkudmVyYm9zZShtc2csIHZlcmJvc2l0eSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYW4gaW5mbyBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdGhlIGluZm8gbG9nZ2luZyB0byB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC5cbiAgICovXG4gIHN0YXRpYyBpbmZvKG1zZzogU3RyaW5nTGlrZSk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmdldCgpLmluZm8obXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIGRlYnVnIG1lc3NhZ2UuXG4gICAqIEBzdW1tYXJ5IERlbGVnYXRlcyB0aGUgZGVidWcgbG9nZ2luZyB0byB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC5cbiAgICovXG4gIHN0YXRpYyBkZWJ1Zyhtc2c6IFN0cmluZ0xpa2UpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5kZWJ1Zyhtc2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGEgc2lsbHkgbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRoZSBkZWJ1ZyBsb2dnaW5nIHRvIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLlxuICAgKi9cbiAgc3RhdGljIHNpbGx5KG1zZzogU3RyaW5nTGlrZSk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmdldCgpLnNpbGx5KG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYW4gZXJyb3IgbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRoZSBlcnJvciBsb2dnaW5nIHRvIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLlxuICAgKi9cbiAgc3RhdGljIGVycm9yKG1zZzogU3RyaW5nTGlrZSk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmdldCgpLmVycm9yKG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBsb2dnZXIgZm9yIGEgc3BlY2lmaWMgb2JqZWN0IG9yIGNvbnRleHRcbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIG5ldyBsb2dnZXIgaW5zdGFuY2UgZm9yIHRoZSBnaXZlbiBvYmplY3Qgb3IgY29udGV4dCB1c2luZyB0aGUgZmFjdG9yeSBmdW5jdGlvblxuICAgKiBAcGFyYW0ge0xvZ2dpbmdDb250ZXh0fSBvYmplY3QgLSBUaGUgb2JqZWN0LCBjbGFzcywgb3IgY29udGV4dCB0byBjcmVhdGUgYSBsb2dnZXIgZm9yXG4gICAqIEBwYXJhbSB7UGFydGlhbDxMb2dnaW5nQ29uZmlnPn0gW2NvbmZpZ10gLSBPcHRpb25hbCBjb25maWd1cmF0aW9uIHRvIG92ZXJyaWRlIGdsb2JhbCBzZXR0aW5nc1xuICAgKiBAcGFyYW0gey4uLmFueX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGxvZ2dlciBmYWN0b3J5XG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gQSBuZXcgbG9nZ2VyIGluc3RhbmNlIGZvciB0aGUgc3BlY2lmaWVkIG9iamVjdCBvciBjb250ZXh0XG4gICAqL1xuICBzdGF0aWMgZm9yKFxuICAgIG9iamVjdDogTG9nZ2luZ0NvbnRleHQsXG4gICAgY29uZmlnPzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPixcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBMb2dnZXIge1xuICAgIG9iamVjdCA9XG4gICAgICB0eXBlb2Ygb2JqZWN0ID09PSBcInN0cmluZ1wiXG4gICAgICAgID8gb2JqZWN0XG4gICAgICAgIDogb2JqZWN0LmNvbnN0cnVjdG9yXG4gICAgICAgICAgPyBvYmplY3QuY29uc3RydWN0b3IubmFtZVxuICAgICAgICAgIDogb2JqZWN0Lm5hbWU7XG4gICAgcmV0dXJuIHRoaXMuX2ZhY3Rvcnkob2JqZWN0LCBjb25maWcsIC4uLmFyZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbG9nZ2VyIGZvciBhIHNwZWNpZmljIHJlYXNvbiBvciBjb3JyZWxhdGlvbiBjb250ZXh0XG4gICAqIEBzdW1tYXJ5IFV0aWxpdHkgdG8gcXVpY2tseSBjcmVhdGUgYSBsb2dnZXIgbGFiZWxlZCB3aXRoIGEgZnJlZS1mb3JtIHJlYXNvbiBhbmQgb3B0aW9uYWwgaWRlbnRpZmllclxuICAgKiBzbyB0aGF0IGFkLWhvYyBvcGVyYXRpb25zIGNhbiBiZSB0cmFjZWQgd2l0aG91dCB0eWluZyB0aGUgbG9nZ2VyIHRvIGEgY2xhc3Mgb3IgbWV0aG9kIG5hbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZWFzb24gLSBBIHRleHR1YWwgcmVhc29uIG9yIGNvbnRleHQgbGFiZWwgZm9yIHRoaXMgbG9nZ2VyIGluc3RhbmNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbaWRdIC0gT3B0aW9uYWwgaWRlbnRpZmllciB0byBoZWxwIGNvcnJlbGF0ZSByZWxhdGVkIGxvZyBlbnRyaWVzXG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gQSBuZXcgbG9nZ2VyIGluc3RhbmNlIGxhYmVsZWQgd2l0aCB0aGUgcHJvdmlkZWQgcmVhc29uIGFuZCBpZFxuICAgKi9cbiAgc3RhdGljIGJlY2F1c2UocmVhc29uOiBzdHJpbmcsIGlkPzogc3RyaW5nKTogTG9nZ2VyIHtcbiAgICByZXR1cm4gdGhpcy5fZmFjdG9yeShyZWFzb24sIHRoaXMuX2NvbmZpZywgaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBcHBsaWVzIHRoZW1lIHN0eWxpbmcgdG8gdGV4dFxuICAgKiBAc3VtbWFyeSBBcHBsaWVzIHN0eWxpbmcgKGNvbG9ycywgZm9ybWF0dGluZykgdG8gdGV4dCBiYXNlZCBvbiB0aGUgdGhlbWUgY29uZmlndXJhdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSB0ZXh0IHRvIHN0eWxlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIC0gVGhlIHR5cGUgb2YgZWxlbWVudCB0byBzdHlsZSAoZS5nLiwgXCJjbGFzc1wiLCBcIm1lc3NhZ2VcIiwgXCJsb2dMZXZlbFwiKVxuICAgKiBAcGFyYW0ge0xvZ0xldmVsfSBsb2dnZXJMZXZlbCAtIFRoZSBsb2cgbGV2ZWwgdG8gdXNlIGZvciBzdHlsaW5nXG4gICAqIEBwYXJhbSB7VGhlbWV9IFt0ZW1wbGF0ZT1EZWZhdWx0VGhlbWVdIC0gVGhlIHRoZW1lIHRvIHVzZSBmb3Igc3R5bGluZ1xuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBzdHlsZWQgdGV4dFxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAgICogICBwYXJ0aWNpcGFudCBUaGVtZSBhcyBMb2dnaW5nLnRoZW1lXG4gICAqICAgcGFydGljaXBhbnQgQXBwbHkgYXMgYXBwbHkgZnVuY3Rpb25cbiAgICogICBwYXJ0aWNpcGFudCBTdHlsZSBhcyBzdHlsZWQtc3RyaW5nLWJ1aWxkZXJcbiAgICpcbiAgICogICBDYWxsZXItPj5UaGVtZTogdGhlbWUodGV4dCwgdHlwZSwgbG9nZ2VyTGV2ZWwpXG4gICAqICAgVGhlbWUtPj5UaGVtZTogQ2hlY2sgaWYgc3R5bGluZyBpcyBlbmFibGVkXG4gICAqICAgYWx0IHN0eWxpbmcgZGlzYWJsZWRcbiAgICogICAgIFRoZW1lLS0+PkNhbGxlcjogcmV0dXJuIG9yaWdpbmFsIHRleHRcbiAgICogICBlbHNlIHN0eWxpbmcgZW5hYmxlZFxuICAgKiAgICAgVGhlbWUtPj5UaGVtZTogR2V0IHRoZW1lIGZvciB0eXBlXG4gICAqICAgICBhbHQgdGhlbWUgbm90IGZvdW5kXG4gICAqICAgICAgIFRoZW1lLS0+PkNhbGxlcjogcmV0dXJuIG9yaWdpbmFsIHRleHRcbiAgICogICAgIGVsc2UgdGhlbWUgZm91bmRcbiAgICogICAgICAgVGhlbWUtPj5UaGVtZTogRGV0ZXJtaW5lIGFjdHVhbCB0aGVtZSBiYXNlZCBvbiBsb2cgbGV2ZWxcbiAgICogICAgICAgVGhlbWUtPj5BcHBseTogQXBwbHkgZWFjaCBzdHlsZSBwcm9wZXJ0eVxuICAgKiAgICAgICBBcHBseS0+PlN0eWxlOiBBcHBseSBjb2xvcnMgYW5kIGZvcm1hdHRpbmdcbiAgICogICAgICAgU3R5bGUtLT4+QXBwbHk6IFJldHVybiBzdHlsZWQgdGV4dFxuICAgKiAgICAgICBBcHBseS0tPj5UaGVtZTogUmV0dXJuIHN0eWxlZCB0ZXh0XG4gICAqICAgICAgIFRoZW1lLS0+PkNhbGxlcjogUmV0dXJuIGZpbmFsIHN0eWxlZCB0ZXh0XG4gICAqICAgICBlbmRcbiAgICogICBlbmRcbiAgICovXG4gIHN0YXRpYyB0aGVtZShcbiAgICB0ZXh0OiBzdHJpbmcsXG4gICAgdHlwZToga2V5b2YgVGhlbWUgfCBrZXlvZiBMb2dMZXZlbCxcbiAgICBsb2dnZXJMZXZlbDogTG9nTGV2ZWwsXG4gICAgdGVtcGxhdGU6IFRoZW1lID0gRGVmYXVsdFRoZW1lXG4gICkge1xuICAgIGlmICghdGhpcy5fY29uZmlnLnN0eWxlKSByZXR1cm4gdGV4dDtcbiAgICBjb25zdCBsb2dnZXIgPSBMb2dnaW5nLmdldCgpLmZvcih0aGlzLnRoZW1lKTtcblxuICAgIGZ1bmN0aW9uIGFwcGx5KFxuICAgICAgdHh0OiBzdHJpbmcsXG4gICAgICBvcHRpb246IGtleW9mIFRoZW1lT3B0aW9uLFxuICAgICAgdmFsdWU6IG51bWJlciB8IFtudW1iZXJdIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHwgbnVtYmVyW10gfCBzdHJpbmdbXVxuICAgICk6IHN0cmluZyB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB0OiBzdHJpbmcgfCBTdHlsZWRTdHJpbmcgPSB0eHQ7XG4gICAgICAgIGxldCBjID0gc3R5bGUodCk7XG5cbiAgICAgICAgZnVuY3Rpb24gYXBwbHlDb2xvcihcbiAgICAgICAgICB2YWw6IG51bWJlciB8IFtudW1iZXJdIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgIGlzQmcgPSBmYWxzZVxuICAgICAgICApOiBTdHlsZWRTdHJpbmcge1xuICAgICAgICAgIGxldCBmOlxuICAgICAgICAgICAgfCB0eXBlb2YgYy5iYWNrZ3JvdW5kXG4gICAgICAgICAgICB8IHR5cGVvZiBjLmZvcmVncm91bmRcbiAgICAgICAgICAgIHwgdHlwZW9mIGMucmdiXG4gICAgICAgICAgICB8IHR5cGVvZiBjLmNvbG9yMjU2ID0gaXNCZyA/IGMuYmFja2dyb3VuZCA6IGMuZm9yZWdyb3VuZDtcbiAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsKSkge1xuICAgICAgICAgICAgcmV0dXJuIChmIGFzIHR5cGVvZiBjLmJhY2tncm91bmQgfCB0eXBlb2YgYy5mb3JlZ3JvdW5kKS5jYWxsKFxuICAgICAgICAgICAgICBjLFxuICAgICAgICAgICAgICB2YWx1ZSBhcyBudW1iZXJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHN3aXRjaCAodmFsLmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICBmID0gaXNCZyA/IGMuYmdDb2xvcjI1NiA6IGMuY29sb3IyNTY7XG4gICAgICAgICAgICAgIHJldHVybiAoZiBhcyB0eXBlb2YgYy5iZ0NvbG9yMjU2IHwgdHlwZW9mIGMuY29sb3IyNTYpKHZhbFswXSk7XG4gICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgIGYgPSBpc0JnID8gYy5iZ1JnYiA6IGMucmdiO1xuICAgICAgICAgICAgICByZXR1cm4gYy5yZ2IodmFsWzBdLCB2YWxbMV0sIHZhbFsyXSk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYE5vdCBhIHZhbGlkIGNvbG9yIG9wdGlvbjogJHtvcHRpb259YCk7XG4gICAgICAgICAgICAgIHJldHVybiBzdHlsZSh0IGFzIHN0cmluZyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gYXBwbHlTdHlsZSh2OiBudW1iZXIgfCBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgICBpZiAodHlwZW9mIHYgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIGMgPSBjLnN0eWxlKHYpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjID0gY1t2IGFzIGtleW9mIENvbG9yaXplT3B0aW9uc10gYXMgU3R5bGVkU3RyaW5nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAob3B0aW9uKSB7XG4gICAgICAgICAgY2FzZSBcImJnXCI6XG4gICAgICAgICAgY2FzZSBcImZnXCI6XG4gICAgICAgICAgICByZXR1cm4gYXBwbHlDb2xvcih2YWx1ZSBhcyBudW1iZXIpLnRleHQ7XG4gICAgICAgICAgY2FzZSBcInN0eWxlXCI6XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgdmFsdWUuZm9yRWFjaChhcHBseVN0eWxlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGFwcGx5U3R5bGUodmFsdWUgYXMgbnVtYmVyIHwgc3RyaW5nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjLnRleHQ7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgTm90IGEgdmFsaWQgdGhlbWUgb3B0aW9uOiAke29wdGlvbn1gKTtcbiAgICAgICAgICAgIHJldHVybiB0O1xuICAgICAgICB9XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKGBFcnJvciBhcHBseWluZyBzdHlsZTogJHtvcHRpb259IHdpdGggdmFsdWUgJHt2YWx1ZX1gKTtcbiAgICAgICAgcmV0dXJuIHR4dDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBpbmRpdmlkdWFsVGhlbWUgPSB0ZW1wbGF0ZVt0eXBlIGFzIGtleW9mIFRoZW1lXTtcbiAgICBpZiAoIWluZGl2aWR1YWxUaGVtZSB8fCAhT2JqZWN0LmtleXMoaW5kaXZpZHVhbFRoZW1lKS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0ZXh0O1xuICAgIH1cblxuICAgIGxldCBhY3R1YWxUaGVtZTogVGhlbWVPcHRpb24gPSBpbmRpdmlkdWFsVGhlbWUgYXMgVGhlbWVPcHRpb247XG5cbiAgICBjb25zdCBsb2dMZXZlbHMgPSBPYmplY3QuYXNzaWduKHt9LCBMb2dMZXZlbCk7XG4gICAgaWYgKE9iamVjdC5rZXlzKGluZGl2aWR1YWxUaGVtZSlbMF0gaW4gbG9nTGV2ZWxzKVxuICAgICAgYWN0dWFsVGhlbWUgPVxuICAgICAgICAoaW5kaXZpZHVhbFRoZW1lIGFzIFRoZW1lT3B0aW9uQnlMb2dMZXZlbClbbG9nZ2VyTGV2ZWxdIHx8IHt9O1xuXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGFjdHVhbFRoZW1lKS5yZWR1Y2UoKGFjYzogc3RyaW5nLCBrZXk6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgdmFsID0gKGFjdHVhbFRoZW1lIGFzIFRoZW1lT3B0aW9uKVtrZXkgYXMga2V5b2YgVGhlbWVPcHRpb25dO1xuICAgICAgaWYgKHZhbClcbiAgICAgICAgcmV0dXJuIGFwcGx5KFxuICAgICAgICAgIGFjYyxcbiAgICAgICAgICBrZXkgYXMga2V5b2YgVGhlbWVPcHRpb24sXG4gICAgICAgICAgdmFsIGFzXG4gICAgICAgICAgICB8IG51bWJlclxuICAgICAgICAgICAgfCBbbnVtYmVyXVxuICAgICAgICAgICAgfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl1cbiAgICAgICAgICAgIHwgbnVtYmVyW11cbiAgICAgICAgICAgIHwgc3RyaW5nW11cbiAgICAgICAgKTtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgdGV4dCk7XG4gIH1cbn1cbiIsImltcG9ydCB7IExvZ0xldmVsIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSBcIi4vbG9nZ2luZ1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzXG4gKiBAc3VtbWFyeSBDcmVhdGVzIGEgZGVjb3JhdG9yIHRoYXQgbG9ncyBtZXRob2QgY2FsbHMgd2l0aCBzcGVjaWZpZWQgbGV2ZWwsIGJlbmNobWFya2luZywgYW5kIHZlcmJvc2l0eVxuICogQHBhcmFtIHtMb2dMZXZlbH0gbGV2ZWwgLSBUaGUgbG9nIGxldmVsIHRvIHVzZSAoZGVmYXVsdDogTG9nTGV2ZWwuaW5mbylcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2JlbmNobWFyaz1mYWxzZV0gLSBXaGV0aGVyIHRvIGxvZyBleGVjdXRpb24gdGltZSAoZGVmYXVsdDogZmFsc2UpXG4gKiBAcGFyYW0ge251bWJlcn0gW3ZlcmJvc2l0eT0wXSAtIFRoZSB2ZXJib3NpdHkgbGV2ZWwgZm9yIHRoZSBsb2cgbWVzc2FnZXMgKGRlZmF1bHQ6IDApXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiBsb2dcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IERlY29yYXRvciBhcyBsb2cgZGVjb3JhdG9yXG4gKiAgIHBhcnRpY2lwYW50IE1ldGhvZCBhcyBPcmlnaW5hbCBNZXRob2RcbiAqICAgcGFydGljaXBhbnQgTG9nZ2VyIGFzIExvZ2dpbmcgaW5zdGFuY2VcbiAqXG4gKiAgIENsaWVudC0+PkRlY29yYXRvcjogY2FsbCBkZWNvcmF0ZWQgbWV0aG9kXG4gKiAgIERlY29yYXRvci0+PkxvZ2dlcjogbG9nIG1ldGhvZCBjYWxsXG4gKiAgIERlY29yYXRvci0+Pk1ldGhvZDogY2FsbCBvcmlnaW5hbCBtZXRob2RcbiAqICAgYWx0IHJlc3VsdCBpcyBQcm9taXNlXG4gKiAgICAgTWV0aG9kLS0+PkRlY29yYXRvcjogcmV0dXJuIFByb21pc2VcbiAqICAgICBEZWNvcmF0b3ItPj5EZWNvcmF0b3I6IGF0dGFjaCB0aGVuIGhhbmRsZXJcbiAqICAgICBOb3RlIG92ZXIgRGVjb3JhdG9yOiBQcm9taXNlIHJlc29sdmVzXG4gKiAgICAgRGVjb3JhdG9yLT4+TG9nZ2VyOiBsb2cgYmVuY2htYXJrIChpZiBlbmFibGVkKVxuICogICAgIERlY29yYXRvci0tPj5DbGllbnQ6IHJldHVybiByZXN1bHRcbiAqICAgZWxzZSByZXN1bHQgaXMgbm90IFByb21pc2VcbiAqICAgICBNZXRob2QtLT4+RGVjb3JhdG9yOiByZXR1cm4gcmVzdWx0XG4gKiAgICAgRGVjb3JhdG9yLT4+TG9nZ2VyOiBsb2cgYmVuY2htYXJrIChpZiBlbmFibGVkKVxuICogICAgIERlY29yYXRvci0tPj5DbGllbnQ6IHJldHVybiByZXN1bHRcbiAqICAgZW5kXG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvZyhcbiAgbGV2ZWw6IExvZ0xldmVsID0gTG9nTGV2ZWwuaW5mbyxcbiAgYmVuY2htYXJrOiBib29sZWFuID0gZmFsc2UsXG4gIHZlcmJvc2l0eSA9IDBcbikge1xuICByZXR1cm4gZnVuY3Rpb24gKFxuICAgIHRhcmdldDogYW55LFxuICAgIHByb3BlcnR5S2V5PzogYW55LFxuICAgIGRlc2NyaXB0b3I/OiBQcm9wZXJ0eURlc2NyaXB0b3JcbiAgKSB7XG4gICAgaWYgKCFkZXNjcmlwdG9yKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBMb2dnaW5nIGRlY29yYXRpb24gb25seSBhcHBsaWVzIHRvIG1ldGhvZHNgKTtcbiAgICBjb25zdCBsb2cgPSBMb2dnaW5nLmZvcih0YXJnZXQpLmZvcih0YXJnZXRbcHJvcGVydHlLZXldKTtcbiAgICBjb25zdCBtZXRob2QgPSBsb2dbbGV2ZWxdLmJpbmQobG9nKTtcbiAgICBjb25zdCBvcmlnaW5hbE1ldGhvZCA9IGRlc2NyaXB0b3IudmFsdWU7XG5cbiAgICBjb25zdCBmdW5jID0gZnVuY3Rpb24gKHRoaXM6IHR5cGVvZiB0YXJnZXQsIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgICBtZXRob2QoYGNhbGxlZCB3aXRoICR7YXJnc31gLCB2ZXJib3NpdHkpO1xuICAgICAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgbGV0IGVuZDogbnVtYmVyO1xuICAgICAgY29uc3QgcmVzdWx0OiBhbnkgPSBvcmlnaW5hbE1ldGhvZC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQudGhlbigocikgPT4ge1xuICAgICAgICAgIGlmIChiZW5jaG1hcmspIHtcbiAgICAgICAgICAgIGVuZCA9IERhdGUubm93KCk7XG4gICAgICAgICAgICBpZiAoYmVuY2htYXJrKSBtZXRob2QoYGNvbXBsZXRlZCBpbiAke2VuZCAtIHN0YXJ0fW1zYCwgdmVyYm9zaXR5KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHI7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGJlbmNobWFyaykge1xuICAgICAgICBlbmQgPSBEYXRlLm5vdygpO1xuICAgICAgICBpZiAoYmVuY2htYXJrKSBtZXRob2QoYGNvbXBsZXRlZCBpbiAke2VuZCAtIHN0YXJ0fW1zYCwgdmVyYm9zaXR5KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LmJpbmQodGFyZ2V0KSBhcyBhbnk7XG5cbiAgICBPYmplY3QuYXNzaWduKGZ1bmMsIFwibmFtZVwiLCB7XG4gICAgICB2YWx1ZTogZGVzY3JpcHRvci52YWx1ZS5uYW1lLFxuICAgIH0pO1xuXG4gICAgZGVzY3JpcHRvci52YWx1ZSA9IGZ1bmM7XG4gIH07XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCBkZWJ1ZyBsZXZlbFxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQgdGhlIGxvZyBkZWNvcmF0b3IgdGhhdCB1c2VzIExvZ0xldmVsLmRlYnVnXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtiZW5jaG1hcms9ZmFsc2VdIC0gV2hldGhlciB0byBsb2cgZXhlY3V0aW9uIHRpbWUgKGRlZmF1bHQ6IGZhbHNlKVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbWV0aG9kIGRlY29yYXRvciB0aGF0IHdyYXBzIHRoZSBvcmlnaW5hbCBtZXRob2Qgd2l0aCBkZWJ1ZyBsb2dnaW5nXG4gKiBAZnVuY3Rpb24gZGVidWdcbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZGVidWcoYmVuY2htYXJrOiBib29sZWFuID0gZmFsc2UpIHtcbiAgcmV0dXJuIGxvZyhMb2dMZXZlbC5kZWJ1ZywgYmVuY2htYXJrKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIGluZm8gbGV2ZWxcbiAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIHRoZSBsb2cgZGVjb3JhdG9yIHRoYXQgdXNlcyBMb2dMZXZlbC5pbmZvXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtiZW5jaG1hcms9ZmFsc2VdIC0gV2hldGhlciB0byBsb2cgZXhlY3V0aW9uIHRpbWUgKGRlZmF1bHQ6IGZhbHNlKVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbWV0aG9kIGRlY29yYXRvciB0aGF0IHdyYXBzIHRoZSBvcmlnaW5hbCBtZXRob2Qgd2l0aCBpbmZvIGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiBpbmZvXG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluZm8oYmVuY2htYXJrOiBib29sZWFuID0gZmFsc2UpIHtcbiAgcmV0dXJuIGxvZyhMb2dMZXZlbC5pbmZvLCBiZW5jaG1hcmspO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggc2lsbHkgbGV2ZWxcbiAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIHRoZSBsb2cgZGVjb3JhdG9yIHRoYXQgdXNlcyBMb2dMZXZlbC5zaWxseVxuICogQHBhcmFtIHtib29sZWFufSBbYmVuY2htYXJrPWZhbHNlXSAtIFdoZXRoZXIgdG8gbG9nIGV4ZWN1dGlvbiB0aW1lIChkZWZhdWx0OiBmYWxzZSlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG1ldGhvZCBkZWNvcmF0b3IgdGhhdCB3cmFwcyB0aGUgb3JpZ2luYWwgbWV0aG9kIHdpdGggc2lsbHkgbG9nZ2luZ1xuICogQGZ1bmN0aW9uIHNpbGx5XG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNpbGx5KGJlbmNobWFyazogYm9vbGVhbiA9IGZhbHNlKSB7XG4gIHJldHVybiBsb2coTG9nTGV2ZWwuc2lsbHksIGJlbmNobWFyayk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCB2ZXJib3NlIGxldmVsXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB0aGUgbG9nIGRlY29yYXRvciB0aGF0IHVzZXMgTG9nTGV2ZWwudmVyYm9zZSB3aXRoIGNvbmZpZ3VyYWJsZSB2ZXJib3NpdHlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG1ldGhvZCBkZWNvcmF0b3IgdGhhdCB3cmFwcyB0aGUgb3JpZ2luYWwgbWV0aG9kIHdpdGggdmVyYm9zZSBsb2dnaW5nXG4gKiBAZnVuY3Rpb24gdmVyYm9zZVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyYm9zZSgpOiAoXG4gIHRhcmdldDogYW55LFxuICBwcm9wZXJ0eUtleT86IGFueSxcbiAgZGVzY3JpcHRvcj86IGFueVxuKSA9PiB2b2lkO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggdmVyYm9zZSBsZXZlbFxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQgdGhlIGxvZyBkZWNvcmF0b3IgdGhhdCB1c2VzIExvZ0xldmVsLnZlcmJvc2Ugd2l0aCBjb25maWd1cmFibGUgdmVyYm9zaXR5XG4gKiBAcGFyYW0ge2Jvb2xlYW59IGJlbmNobWFyayAtIFdoZXRoZXIgdG8gbG9nIGV4ZWN1dGlvbiB0aW1lXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIHZlcmJvc2UgbG9nZ2luZ1xuICogQGZ1bmN0aW9uIHZlcmJvc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcmJvc2UoXG4gIGJlbmNobWFyazogYm9vbGVhblxuKTogKHRhcmdldDogYW55LCBwcm9wZXJ0eUtleT86IGFueSwgZGVzY3JpcHRvcj86IGFueSkgPT4gdm9pZDtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIHZlcmJvc2UgbGV2ZWxcbiAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIHRoZSBsb2cgZGVjb3JhdG9yIHRoYXQgdXNlcyBMb2dMZXZlbC52ZXJib3NlIHdpdGggY29uZmlndXJhYmxlIHZlcmJvc2l0eVxuICogQHBhcmFtIHtudW1iZXJ9IHZlcmJvc2l0eSAtIFRoZSB2ZXJib3NpdHkgbGV2ZWwgZm9yIHRoZSBsb2cgbWVzc2FnZXMgKGRlZmF1bHQ6IDApXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIHZlcmJvc2UgbG9nZ2luZ1xuICogQGZ1bmN0aW9uIHZlcmJvc2VcbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyYm9zZShcbiAgdmVyYm9zaXR5OiBudW1iZXIgfCBib29sZWFuXG4pOiAodGFyZ2V0OiBhbnksIHByb3BlcnR5S2V5PzogYW55LCBkZXNjcmlwdG9yPzogYW55KSA9PiB2b2lkO1xuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIHZlcmJvc2UgbGV2ZWxcbiAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIHRoZSBsb2cgZGVjb3JhdG9yIHRoYXQgdXNlcyBMb2dMZXZlbC52ZXJib3NlIHdpdGggY29uZmlndXJhYmxlIHZlcmJvc2l0eVxuICogQHBhcmFtIHtudW1iZXJ9IHZlcmJvc2l0eSAtIFRoZSB2ZXJib3NpdHkgbGV2ZWwgZm9yIHRoZSBsb2cgbWVzc2FnZXMgKGRlZmF1bHQ6IDApXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtiZW5jaG1hcms9ZmFsc2VdIC0gV2hldGhlciB0byBsb2cgZXhlY3V0aW9uIHRpbWUgKGRlZmF1bHQ6IGZhbHNlKVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbWV0aG9kIGRlY29yYXRvciB0aGF0IHdyYXBzIHRoZSBvcmlnaW5hbCBtZXRob2Qgd2l0aCB2ZXJib3NlIGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiB2ZXJib3NlXG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcmJvc2UodmVyYm9zaXR5OiBudW1iZXIgfCBib29sZWFuID0gMCwgYmVuY2htYXJrPzogYm9vbGVhbikge1xuICBpZiAodHlwZW9mIHZlcmJvc2l0eSA9PT0gXCJib29sZWFuXCIpIHtcbiAgICBiZW5jaG1hcmsgPSB2ZXJib3NpdHk7XG4gICAgdmVyYm9zaXR5ID0gMDtcbiAgfVxuICByZXR1cm4gbG9nKExvZ0xldmVsLnZlcmJvc2UsIGJlbmNobWFyaywgdmVyYm9zaXR5KTtcbn1cbiIsImltcG9ydCB7IExvZ2dpbmcgfSBmcm9tIFwiLi9sb2dnaW5nXCI7XG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBCYXNlIGNsYXNzIHRoYXQgcHJvdmlkZXMgYSByZWFkeS10by11c2UgbG9nZ2VyIGluc3RhbmNlXG4gKiBAc3VtbWFyeSBMb2dnZWRDbGFzcyBpcyBhIGNvbnZlbmllbmNlIGFic3RyYWN0IGNsYXNzIHRoYXQgaW5qZWN0cyBhIHR5cGUtc2FmZSBsb2dnZXJcbiAqIGludG8gZGVyaXZlZCBjbGFzc2VzIHRocm91Z2ggYSBwcm90ZWN0ZWQgZ2V0dGVyLiBTdWJjbGFzc2VzIGNhbiBkaXJlY3RseSBhY2Nlc3NcbiAqIHRoaXMubG9nIHRvIGVtaXQgbWVzc2FnZXMgd2l0aG91dCBtYW51YWxseSBjcmVhdGluZyBhIGxvZ2dlci4gVGhpcyBwcm9tb3Rlc1xuICogY29uc2lzdGVudCwgY29udGV4dC1hd2FyZSBsb2dnaW5nIGFjcm9zcyB0aGUgY29kZWJhc2UuXG4gKiBAcGFyYW0ge3ZvaWR9IFtjb25zdHJ1Y3Rvcl0gLSBObyBjb25zdHJ1Y3RvciBhcmd1bWVudHM7IHN1YmNsYXNzZXMgbWF5IGRlZmluZSB0aGVpciBvd25cbiAqIEBjbGFzcyBMb2dnZWRDbGFzc1xuICogQGV4YW1wbGVcbiAqIGNsYXNzIFVzZXJTZXJ2aWNlIGV4dGVuZHMgTG9nZ2VkQ2xhc3Mge1xuICogICBjcmVhdGUodXNlcjogVXNlcikge1xuICogICAgIHRoaXMubG9nLmluZm8oYENyZWF0aW5nIHVzZXIgJHt1c2VyLmlkfWApO1xuICogICB9XG4gKiB9XG4gKlxuICogY29uc3Qgc3ZjID0gbmV3IFVzZXJTZXJ2aWNlKCk7XG4gKiBzdmMuY3JlYXRlKHsgaWQ6IFwiNDJcIiB9KTtcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IEluc3RhbmNlIGFzIFN1YmNsYXNzIEluc3RhbmNlXG4gKiAgIHBhcnRpY2lwYW50IEdldHRlciBhcyBMb2dnZWRDbGFzcy5sb2dcbiAqICAgcGFydGljaXBhbnQgTG9nZ2luZyBhcyBMb2dnaW5nXG4gKiAgIHBhcnRpY2lwYW50IExvZ2dlciBhcyBMb2dnZXJcbiAqXG4gKiAgIENsaWVudC0+Pkluc3RhbmNlOiBjYWxsIHNvbWVNZXRob2QoKVxuICogICBJbnN0YW5jZS0+PkdldHRlcjogYWNjZXNzIHRoaXMubG9nXG4gKiAgIEdldHRlci0+PkxvZ2dpbmc6IExvZ2dpbmcuZm9yKHRoaXMpXG4gKiAgIExvZ2dpbmctLT4+R2V0dGVyOiByZXR1cm4gTG9nZ2VyXG4gKiAgIEdldHRlci0tPj5JbnN0YW5jZTogcmV0dXJuIExvZ2dlclxuICogICBJbnN0YW5jZS0+PkxvZ2dlcjogaW5mby9kZWJ1Zy9lcnJvciguLi4pXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBMb2dnZWRDbGFzcyB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTGF6aWx5IHByb3ZpZGVzIGEgY29udGV4dC1hd2FyZSBsb2dnZXIgZm9yIHRoZSBjdXJyZW50IGluc3RhbmNlXG4gICAqIEBzdW1tYXJ5IFVzZXMgTG9nZ2luZy5mb3IodGhpcykgdG8gY3JlYXRlIGEgbG9nZ2VyIHdob3NlIGNvbnRleHQgaXMgdGhlXG4gICAqIHN1YmNsYXNzIG5hbWUsIGFsbG93aW5nIHVuaWZvcm0gYW5kIHN0cnVjdHVyZWQgbG9ncyBmcm9tIGFueSBpbmhlcml0aW5nIGNsYXNzLlxuICAgKiBAcmV0dXJuIHtMb2dnZXJ9IEEgbG9nZ2VyIGJvdW5kIHRvIHRoZSBzdWJjbGFzcyBjb250ZXh0XG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IGxvZygpOiBMb2dnZXIge1xuICAgIHJldHVybiBMb2dnaW5nLmZvcih0aGlzIGFzIGFueSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoKSB7fVxufVxuIiwiZXhwb3J0ICogZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9Mb2dnZWRDbGFzc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vbG9nZ2luZ1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZXNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgbG9nZ2luZyBtb2R1bGUgZm9yIFR5cGVTY3JpcHQgYXBwbGljYXRpb25zXG4gKiBAc3VtbWFyeSBQcm92aWRlcyBhIGNvbXByZWhlbnNpdmUsIGZsZXhpYmxlIGxvZ2dpbmcgc29sdXRpb24uIFRoaXMgbW9kdWxlIGV4cG9zZXM6XG4gKiAtIENvcmUgY2xhc3NlcyBsaWtlIHtAbGluayBMb2dnaW5nfSBhbmQge0BsaW5rIE1pbmlMb2dnZXJ9XG4gKiAtIERlY29yYXRvcnMgc3VjaCBhcyB7QGxpbmsgbG9nfSBmb3IgaW5zdHJ1bWVudGluZyBtZXRob2RzXG4gKiAtIENvbmZpZ3VyYXRpb24gYW5kIGNvbnN0YW50cyBsaWtlIHtAbGluayBMb2dMZXZlbH0gYW5kIHtAbGluayBEZWZhdWx0TG9nZ2luZ0NvbmZpZ31cbiAqIC0gVHlwZSBkZWZpbml0aW9ucyBpbmNsdWRpbmcge0BsaW5rIExvZ2dlcn0gYW5kIHtAbGluayBMb2dnaW5nQ29uZmlnfVxuICogVGhlc2UgZXhwb3J0cyBlbmFibGUgY29uc2lzdGVudCwgY29udGV4dC1hd2FyZSwgYW5kIG9wdGlvbmFsbHkgdGhlbWVkIGxvZ2dpbmcgYWNyb3NzIHByb2plY3RzLlxuICogQG1vZHVsZSBMb2dnaW5nXG4gKi9cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ3VycmVudCBwYWNrYWdlIHZlcnNpb24gc3RyaW5nXG4gKiBAc3VtbWFyeSBTdG9yZXMgdGhlIGN1cnJlbnQgcGFja2FnZSB2ZXJzaW9uLCB1c2VkIGZvciB2ZXJzaW9uIHRyYWNraW5nIGFuZCBjb21wYXRpYmlsaXR5IGNoZWNrc1xuICogQGNvbnN0IFZFUlNJT05cbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbiJdLCJuYW1lcyI6WyJMb2dMZXZlbCIsIkxvZ2dpbmdNb2RlIiwic3R5bGUiXSwibWFwcGluZ3MiOiI7Ozs7OztJQUVBOzs7Ozs7SUFNRztBQUNTQTtJQUFaLENBQUEsVUFBWSxRQUFRLEVBQUE7O0lBRWxCLElBQUEsUUFBQSxDQUFBLE9BQUEsQ0FBQSxHQUFBLE9BQWU7O0lBRWYsSUFBQSxRQUFBLENBQUEsTUFBQSxDQUFBLEdBQUEsTUFBYTs7SUFFYixJQUFBLFFBQUEsQ0FBQSxTQUFBLENBQUEsR0FBQSxTQUFtQjs7SUFFbkIsSUFBQSxRQUFBLENBQUEsT0FBQSxDQUFBLEdBQUEsT0FBZTs7SUFFZixJQUFBLFFBQUEsQ0FBQSxPQUFBLENBQUEsR0FBQSxPQUFlO0lBQ2pCLENBQUMsRUFYV0EsZ0JBQVEsS0FBUkEsZ0JBQVEsR0FXbkIsRUFBQSxDQUFBLENBQUE7SUFFRDs7Ozs7Ozs7OztJQVVHO0FBQ1UsVUFBQSxnQkFBZ0IsR0FBRztJQUM5QixJQUFBLEtBQUssRUFBRSxDQUFDO0lBQ1IsSUFBQSxJQUFJLEVBQUUsQ0FBQztJQUNQLElBQUEsT0FBTyxFQUFFLENBQUM7SUFDVixJQUFBLEtBQUssRUFBRSxDQUFDO0lBQ1IsSUFBQSxLQUFLLEVBQUUsQ0FBQzs7SUFHVjs7Ozs7SUFLRztBQUNTQztJQUFaLENBQUEsVUFBWSxXQUFXLEVBQUE7O0lBRXJCLElBQUEsV0FBQSxDQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQVc7O0lBRVgsSUFBQSxXQUFBLENBQUEsTUFBQSxDQUFBLEdBQUEsTUFBYTtJQUNmLENBQUMsRUFMV0EsbUJBQVcsS0FBWEEsbUJBQVcsR0FLdEIsRUFBQSxDQUFBLENBQUE7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBd0JHO0FBQ1UsVUFBQSxZQUFZLEdBQVU7SUFDakMsSUFBQSxLQUFLLEVBQUU7SUFDTCxRQUFBLEVBQUUsRUFBRSxFQUFFO0lBQ1AsS0FBQTtJQUNELElBQUEsRUFBRSxFQUFFO0lBQ0YsUUFBQSxFQUFFLEVBQUUsRUFBRTtJQUNQLEtBQUE7SUFDRCxJQUFBLEtBQUssRUFBRSxFQUFFO0lBQ1QsSUFBQSxTQUFTLEVBQUUsRUFBRTtJQUNiLElBQUEsT0FBTyxFQUFFO0lBQ1AsUUFBQSxLQUFLLEVBQUU7SUFDTCxZQUFBLEVBQUUsRUFBRSxFQUFFO0lBQ1AsU0FBQTtJQUNGLEtBQUE7SUFDRCxJQUFBLE1BQU0sRUFBRSxFQUFFO0lBQ1YsSUFBQSxRQUFRLEVBQUU7SUFDUixRQUFBLEtBQUssRUFBRTtJQUNMLFlBQUEsRUFBRSxFQUFFLEVBQUU7Z0JBQ04sS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDO0lBQ2hCLFNBQUE7SUFDRCxRQUFBLElBQUksRUFBRTtJQUNKLFlBQUEsRUFBRSxFQUFFLEVBQUU7Z0JBQ04sS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDO0lBQ2hCLFNBQUE7SUFDRCxRQUFBLE9BQU8sRUFBRTtJQUNQLFlBQUEsRUFBRSxFQUFFLEVBQUU7Z0JBQ04sS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDO0lBQ2hCLFNBQUE7SUFDRCxRQUFBLEtBQUssRUFBRTtJQUNMLFlBQUEsRUFBRSxFQUFFLEVBQUU7Z0JBQ04sS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDO0lBQ2hCLFNBQUE7SUFDRixLQUFBOztJQUdIOzs7Ozs7Ozs7Ozs7Ozs7O0lBZ0JHO0FBQ1UsVUFBQSxvQkFBb0IsR0FBa0I7SUFDakQsSUFBQSxPQUFPLEVBQUUsQ0FBQztRQUNWLEtBQUssRUFBRUQsZ0JBQVEsQ0FBQyxJQUFJO0lBQ3BCLElBQUEsUUFBUSxFQUFFLElBQUk7UUFDZCxJQUFJLEVBQUVDLG1CQUFXLENBQUMsR0FBRztJQUNyQixJQUFBLEtBQUssRUFBRSxLQUFLO0lBQ1osSUFBQSxnQkFBZ0IsRUFBRSxHQUFHO0lBQ3JCLElBQUEsU0FBUyxFQUFFLEtBQUs7SUFDaEIsSUFBQSxTQUFTLEVBQUUsSUFBSTtJQUNmLElBQUEsZUFBZSxFQUFFLGNBQWM7SUFDL0IsSUFBQSxPQUFPLEVBQUUsSUFBSTtJQUNiLElBQUEsTUFBTSxFQUFFLEtBQUs7SUFDYixJQUFBLE9BQU8sRUFBRSxxREFBcUQ7SUFDOUQsSUFBQSxLQUFLLEVBQUUsWUFBWTs7O0lDaEpyQjs7Ozs7Ozs7OztJQVVHO2FBQ2EsWUFBWSxDQUMxQixNQUFjLEVBQ2QsR0FBRyxJQUErQyxFQUFBO0lBRWxELElBQUEsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtJQUNuQixRQUFBLElBQ0UsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxLQUFLLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLENBQUM7SUFFeEUsWUFBQSxNQUFNLElBQUksS0FBSyxDQUNiLENBQUEseUVBQUEsQ0FBMkUsQ0FDNUU7O0lBR0wsSUFBQSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLFFBQVEsRUFBRTtJQUNwRCxRQUFBLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQXdCO0lBQzFDLFFBQUEsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsS0FBSTtJQUNwRCxZQUFBLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxDQUFBLEdBQUEsRUFBTSxHQUFHLENBQUEsR0FBQSxDQUFLLEVBQUUsR0FBRyxDQUFDLEVBQUUsWUFBQTtJQUNsRCxnQkFBQSxPQUFPLEdBQUc7SUFDWixhQUFDLENBQUM7YUFDSCxFQUFFLE1BQU0sQ0FBQzs7UUFHWixPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLFVBQVUsS0FBSyxFQUFFLE1BQU0sRUFBQTtJQUN2RCxRQUFBLE9BQU8sT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUs7SUFDN0IsY0FBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsUUFBUTtrQkFDckIsV0FBVztJQUNqQixLQUFDLENBQUM7SUFDSjs7SUNuQkE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBdUJHO1VBQ1UsVUFBVSxDQUFBO1FBQ3JCLFdBQ1ksQ0FBQSxPQUFlLEVBQ2YsSUFBNkIsRUFBQTtZQUQ3QixJQUFPLENBQUEsT0FBQSxHQUFQLE9BQU87WUFDUCxJQUFJLENBQUEsSUFBQSxHQUFKLElBQUk7O0lBR04sSUFBQSxNQUFNLENBQ2QsR0FBd0IsRUFBQTtZQUV4QixJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJO0lBQUUsWUFBQSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO0lBQ3hELFFBQUEsT0FBTyxPQUFPLENBQUMsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDOztJQVVqQzs7Ozs7OztJQU9HO1FBQ0gsR0FBRyxDQUNELE1BQW9FLEVBQ3BFLE1BQStCOztJQUUvQixJQUFBLEdBQUcsSUFBVyxFQUFBO1lBRWQsSUFBSSxDQUFDLE1BQU0sSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRLEVBQUU7Z0JBQ3pDLE1BQU0sR0FBRyxNQUFNO2dCQUNmLE1BQU0sR0FBRyxTQUFTOztpQkFDYjtJQUNMLFlBQUEsTUFBTSxHQUFHO0lBQ1Asa0JBQUUsT0FBTyxNQUFNLEtBQUs7SUFDbEIsc0JBQUU7MEJBQ0MsTUFBYyxDQUFDO3NCQUNsQixTQUFTOztJQUdmLFFBQUEsT0FBTyxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUU7Z0JBQ3JCLEdBQUcsRUFBRSxDQUFDLE1BQW1CLEVBQUUsQ0FBa0IsRUFBRSxRQUFhLEtBQUk7SUFDOUQsZ0JBQUEsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLFFBQVEsQ0FBQztJQUMvQyxnQkFBQSxJQUFJLENBQUMsS0FBSyxRQUFRLEVBQUU7SUFDbEIsb0JBQUEsT0FBTyxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO0lBQzVCLHdCQUFBLEdBQUcsRUFBRSxDQUFDLE1BQTBCLEVBQUUsQ0FBa0IsS0FBSTtJQUN0RCw0QkFBQSxJQUFJLE1BQU0sSUFBSSxDQUFDLElBQUksTUFBTTtJQUN2QixnQ0FBQSxPQUFPLE1BQU0sQ0FBQyxDQUF3QixDQUFDO2dDQUN6QyxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxRQUFRLENBQUM7NkJBQ3hDO0lBQ0YscUJBQUEsQ0FBQzs7SUFFSixnQkFBQSxJQUFJLENBQUMsS0FBSyxTQUFTLElBQUksTUFBTSxFQUFFO3dCQUM3QixPQUFPLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7O0lBRW5DLGdCQUFBLE9BQU8sTUFBTTtpQkFDZDtJQUNGLFNBQUEsQ0FBQzs7SUFHSjs7Ozs7OztJQU9HO0lBQ08sSUFBQSxTQUFTLENBQ2pCLEtBQWUsRUFDZixPQUEyQixFQUMzQixLQUFjLEVBQUE7WUFFZCxNQUFNLEdBQUcsR0FHTCxFQUFTO1lBQ2IsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUM7SUFDbEMsUUFBQSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQUU7Z0JBQzVCLE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFO2dCQUNyQyxNQUFNLFNBQVMsR0FBRyxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFLEtBQUssQ0FBQyxHQUFHLElBQUk7SUFDeEUsWUFBQSxHQUFHLENBQUMsU0FBUyxHQUFHLFNBQVM7O0lBRzNCLFFBQUEsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxFQUFFO2dCQUMzQixNQUFNLEdBQUcsR0FBVztzQkFDaEIsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsVUFBVSxFQUFFLEtBQUs7c0JBQ3RDLEtBQUs7SUFDVCxZQUFBLEdBQUcsQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLFdBQVcsRUFBRTs7SUFHL0IsUUFBQSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEVBQUU7Z0JBQzFCLE1BQU0sT0FBTyxHQUFXO0lBQ3RCLGtCQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSztJQUM1QyxrQkFBRSxJQUFJLENBQUMsT0FBTztJQUNoQixZQUFBLEdBQUcsQ0FBQyxPQUFPLEdBQUcsT0FBTzs7SUFHdkIsUUFBQSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLEVBQUU7Z0JBQ2hDO29CQUNFLE1BQU0sRUFBRSxHQUFXO0lBQ2pCLHNCQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUUsQ0FBQyxRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSzswQkFDbkUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDNUMsZ0JBQUEsR0FBRyxDQUFDLGFBQWEsR0FBRyxFQUFFOzs7WUFJMUIsTUFBTSxHQUFHLEdBQVc7a0JBQ2hCLE9BQU8sQ0FBQyxLQUFLLENBQ1gsT0FBTyxPQUFPLEtBQUssUUFBUSxHQUFHLE9BQU8sR0FBSSxPQUFpQixDQUFDLE9BQU8sRUFDbEUsU0FBUyxFQUNULEtBQUs7SUFFVCxjQUFFLE9BQU8sT0FBTyxLQUFLO0lBQ25CLGtCQUFFO0lBQ0Ysa0JBQUcsT0FBaUIsQ0FBQyxPQUFPO0lBQ2hDLFFBQUEsR0FBRyxDQUFDLE9BQU8sR0FBRyxHQUFHO0lBQ2pCLFFBQUEsSUFBSSxLQUFLLElBQUksT0FBTyxZQUFZLEtBQUssRUFBRTtJQUNyQyxZQUFBLEtBQUssR0FBRztJQUNOLGtCQUFFLE9BQU8sQ0FBQyxLQUFLLEVBQ1YsS0FBSyxJQUFLLE9BQWlCLENBQUMsS0FBSyxHQUNsQyxPQUFPLEVBQ1AsS0FBSztzQkFFUCxLQUFLO0lBQ1QsWUFBQSxHQUFHLENBQUMsS0FBSyxHQUFHLENBQW1CLGdCQUFBLEVBQUEsS0FBSyxFQUFFOztJQUd4QyxRQUFBLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7SUFDM0IsWUFBQSxLQUFLLE1BQU07SUFDVCxnQkFBQSxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDO0lBQzVCLFlBQUEsS0FBSyxLQUFLO0lBQ1IsZ0JBQUEsT0FBUSxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVM7eUJBQzFCLEtBQUssQ0FBQyxHQUFHO0lBQ1QscUJBQUEsR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFJO0lBQ1Qsb0JBQUEsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO0lBQUUsd0JBQUEsT0FBTyxDQUFDO3dCQUNqQyxNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQzt3QkFDdkMsSUFBSSxVQUFVLEtBQUssQ0FBQztJQUFFLHdCQUFBLE9BQU8sVUFBVTtJQUN2QyxvQkFBQSxPQUFPLFNBQVM7SUFDbEIsaUJBQUM7SUFDQSxxQkFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQzt5QkFDZixJQUFJLENBQUMsR0FBRyxDQUFDO0lBQ2QsWUFBQTtJQUNFLGdCQUFBLE1BQU0sSUFBSSxLQUFLLENBQUMsQ0FBQSw0QkFBQSxFQUErQixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFFLENBQUEsQ0FBQzs7O0lBSTdFOzs7Ozs7OztJQVFHO0lBQ08sSUFBQSxHQUFHLENBQ1gsS0FBZSxFQUNmLEdBQXVCLEVBQ3ZCLEtBQWMsRUFBQTtZQUVkLElBQ0UsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQWEsQ0FBQztnQkFDbEQsZ0JBQWdCLENBQUMsS0FBSyxDQUFDO2dCQUV2QjtJQUNGLFFBQUEsSUFBSSxNQUFNO1lBQ1YsUUFBUSxLQUFLO2dCQUNYLEtBQUtELGdCQUFRLENBQUMsSUFBSTtJQUNoQixnQkFBQSxNQUFNLEdBQUcsT0FBTyxDQUFDLEdBQUc7b0JBQ3BCO2dCQUNGLEtBQUtBLGdCQUFRLENBQUMsT0FBTztnQkFDckIsS0FBS0EsZ0JBQVEsQ0FBQyxLQUFLO0lBQ2pCLGdCQUFBLE1BQU0sR0FBRyxPQUFPLENBQUMsS0FBSztvQkFDdEI7Z0JBQ0YsS0FBS0EsZ0JBQVEsQ0FBQyxLQUFLO0lBQ2pCLGdCQUFBLE1BQU0sR0FBRyxPQUFPLENBQUMsS0FBSztvQkFDdEI7SUFDRixZQUFBO0lBQ0UsZ0JBQUEsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQzs7SUFFeEMsUUFBQSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDOztJQUczQzs7Ozs7O0lBTUc7SUFDSCxJQUFBLEtBQUssQ0FBQyxHQUFlLEVBQUUsU0FBQSxHQUFvQixDQUFDLEVBQUE7SUFDMUMsUUFBQSxJQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFZLElBQUksU0FBUztnQkFDakQsSUFBSSxDQUFDLEdBQUcsQ0FBQ0EsZ0JBQVEsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDOztJQUduQzs7Ozs7O0lBTUc7SUFDSCxJQUFBLE9BQU8sQ0FBQyxHQUFlLEVBQUUsU0FBQSxHQUFvQixDQUFDLEVBQUE7SUFDNUMsUUFBQSxJQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFZLElBQUksU0FBUztnQkFDakQsSUFBSSxDQUFDLEdBQUcsQ0FBQ0EsZ0JBQVEsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDOztJQUduQzs7Ozs7SUFLRztJQUNILElBQUEsSUFBSSxDQUFDLEdBQWUsRUFBQTtZQUNsQixJQUFJLENBQUMsR0FBRyxDQUFDQSxnQkFBUSxDQUFDLElBQUksRUFBRSxHQUFHLENBQUM7O0lBRzlCOzs7OztJQUtHO0lBQ0gsSUFBQSxLQUFLLENBQUMsR0FBZSxFQUFBO1lBQ25CLElBQUksQ0FBQyxHQUFHLENBQUNBLGdCQUFRLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQzs7SUFHL0I7Ozs7O0lBS0c7SUFDSCxJQUFBLEtBQUssQ0FBQyxHQUF1QixFQUFBO1lBQzNCLElBQUksQ0FBQyxHQUFHLENBQUNBLGdCQUFRLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQzs7SUFHL0I7Ozs7O0lBS0c7SUFDSCxJQUFBLFNBQVMsQ0FBQyxNQUE4QixFQUFBO0lBQ3RDLFFBQUEsSUFBSSxDQUFDLElBQUksR0FBRyxFQUFFLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRTs7SUFFbEQ7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQWdFRztVQUNVLE9BQU8sQ0FBQTtJQU9sQjs7O0lBR0c7SUFDWSxJQUFBLFNBQUEsSUFBQSxDQUFBLFFBQVEsR0FBa0IsQ0FDdkMsTUFBYyxFQUNkLE1BQStCLEtBQzdCO0lBQ0YsUUFBQSxPQUFPLElBQUksVUFBVSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUM7SUFDdkMsS0FBQyxDQUFDO0lBQ0Y7OztJQUdHO2lCQUNZLElBQU8sQ0FBQSxPQUFBLEdBQWtCLG9CQUFvQixDQUFDO0lBRTdELElBQUEsV0FBQSxHQUFBO0lBRUE7Ozs7O0lBS0c7UUFDSCxPQUFPLFVBQVUsQ0FBQyxPQUFzQixFQUFBO0lBQ3RDLFFBQUEsT0FBTyxDQUFDLFFBQVEsR0FBRyxPQUFPOztJQUc1Qjs7Ozs7SUFLRztRQUNILE9BQU8sU0FBUyxDQUFDLE1BQThCLEVBQUE7WUFDN0MsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQzs7SUFHckM7Ozs7SUFJRztJQUNILElBQUEsT0FBTyxTQUFTLEdBQUE7WUFDZCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUM7O0lBR3hDOzs7OztJQUtHO0lBQ0gsSUFBQSxPQUFPLEdBQUcsR0FBQTtZQUNSLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDO1lBQ2xFLE9BQU8sSUFBSSxDQUFDLE1BQU07O0lBR3BCOzs7Ozs7SUFNRztJQUNILElBQUEsT0FBTyxPQUFPLENBQUMsR0FBZSxFQUFFLFlBQW9CLENBQUMsRUFBQTtZQUNuRCxPQUFPLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQzs7SUFHM0M7Ozs7O0lBS0c7UUFDSCxPQUFPLElBQUksQ0FBQyxHQUFlLEVBQUE7WUFDekIsT0FBTyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQzs7SUFHN0I7Ozs7O0lBS0c7UUFDSCxPQUFPLEtBQUssQ0FBQyxHQUFlLEVBQUE7WUFDMUIsT0FBTyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQzs7SUFHOUI7Ozs7O0lBS0c7UUFDSCxPQUFPLEtBQUssQ0FBQyxHQUFlLEVBQUE7WUFDMUIsT0FBTyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQzs7SUFHOUI7Ozs7O0lBS0c7UUFDSCxPQUFPLEtBQUssQ0FBQyxHQUFlLEVBQUE7WUFDMUIsT0FBTyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQzs7SUFHOUI7Ozs7Ozs7SUFPRztRQUNILE9BQU8sR0FBRyxDQUNSLE1BQXNCLEVBQ3RCLE1BQStCLEVBQy9CLEdBQUcsSUFBVyxFQUFBO1lBRWQsTUFBTTtnQkFDSixPQUFPLE1BQU0sS0FBSztJQUNoQixrQkFBRTtzQkFDQSxNQUFNLENBQUM7SUFDUCxzQkFBRSxNQUFNLENBQUMsV0FBVyxDQUFDO0lBQ3JCLHNCQUFFLE1BQU0sQ0FBQyxJQUFJO1lBQ25CLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDOztJQUcvQzs7Ozs7OztJQU9HO0lBQ0gsSUFBQSxPQUFPLE9BQU8sQ0FBQyxNQUFjLEVBQUUsRUFBVyxFQUFBO0lBQ3hDLFFBQUEsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQzs7SUFHaEQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBZ0NHO1FBQ0gsT0FBTyxLQUFLLENBQ1YsSUFBWSxFQUNaLElBQWtDLEVBQ2xDLFdBQXFCLEVBQ3JCLFFBQUEsR0FBa0IsWUFBWSxFQUFBO0lBRTlCLFFBQUEsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSztJQUFFLFlBQUEsT0FBTyxJQUFJO0lBQ3BDLFFBQUEsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBRTVDLFFBQUEsU0FBUyxLQUFLLENBQ1osR0FBVyxFQUNYLE1BQXlCLEVBQ3pCLEtBQXlFLEVBQUE7SUFFekUsWUFBQSxJQUFJO29CQUNGLE1BQU0sQ0FBQyxHQUEwQixHQUFHO0lBQ3BDLGdCQUFBLElBQUksQ0FBQyxHQUFHRSx5QkFBSyxDQUFDLENBQUMsQ0FBQztJQUVoQixnQkFBQSxTQUFTLFVBQVUsQ0FDakIsR0FBaUQsRUFDakQsSUFBSSxHQUFHLEtBQUssRUFBQTtJQUVaLG9CQUFBLElBQUksQ0FBQyxHQUltQixJQUFJLEdBQUcsQ0FBQyxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUMsVUFBVTt3QkFDMUQsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUU7NEJBQ3ZCLE9BQVEsQ0FBK0MsQ0FBQyxJQUFJLENBQzFELENBQUMsRUFDRCxLQUFlLENBQ2hCOztJQUVILG9CQUFBLFFBQVEsR0FBRyxDQUFDLE1BQU07SUFDaEIsd0JBQUEsS0FBSyxDQUFDO0lBQ0osNEJBQUEsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQyxRQUFRO0lBQ3BDLDRCQUFBLE9BQVEsQ0FBNkMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDL0Qsd0JBQUEsS0FBSyxDQUFDO0lBQ0osNEJBQUEsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHO0lBQzFCLDRCQUFBLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0Qyx3QkFBQTtJQUNFLDRCQUFBLE1BQU0sQ0FBQyxLQUFLLENBQUMsNkJBQTZCLE1BQU0sQ0FBQSxDQUFFLENBQUM7SUFDbkQsNEJBQUEsT0FBT0EseUJBQUssQ0FBQyxDQUFXLENBQUM7OztvQkFJL0IsU0FBUyxVQUFVLENBQUMsQ0FBa0IsRUFBQTtJQUNwQyxvQkFBQSxJQUFJLE9BQU8sQ0FBQyxLQUFLLFFBQVEsRUFBRTtJQUN6Qix3QkFBQSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7OzZCQUNUO0lBQ0wsd0JBQUEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUEwQixDQUFpQjs7O29CQUlyRCxRQUFRLE1BQU07SUFDWixvQkFBQSxLQUFLLElBQUk7SUFDVCxvQkFBQSxLQUFLLElBQUk7SUFDUCx3QkFBQSxPQUFPLFVBQVUsQ0FBQyxLQUFlLENBQUMsQ0FBQyxJQUFJO0lBQ3pDLG9CQUFBLEtBQUssT0FBTztJQUNWLHdCQUFBLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtJQUN4Qiw0QkFBQSxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQzs7aUNBQ3BCO2dDQUNMLFVBQVUsQ0FBQyxLQUF3QixDQUFDOzs0QkFFdEMsT0FBTyxDQUFDLENBQUMsSUFBSTtJQUNmLG9CQUFBO0lBQ0Usd0JBQUEsTUFBTSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsTUFBTSxDQUFBLENBQUUsQ0FBQztJQUNuRCx3QkFBQSxPQUFPLENBQUM7Ozs7Z0JBR1osT0FBTyxDQUFVLEVBQUU7b0JBQ25CLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQSxzQkFBQSxFQUF5QixNQUFNLENBQWUsWUFBQSxFQUFBLEtBQUssQ0FBRSxDQUFBLENBQUM7SUFDbkUsZ0JBQUEsT0FBTyxHQUFHOzs7SUFJZCxRQUFBLE1BQU0sZUFBZSxHQUFHLFFBQVEsQ0FBQyxJQUFtQixDQUFDO0lBQ3JELFFBQUEsSUFBSSxDQUFDLGVBQWUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsTUFBTSxFQUFFO0lBQzVELFlBQUEsT0FBTyxJQUFJOztZQUdiLElBQUksV0FBVyxHQUFnQixlQUE4QjtZQUU3RCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRUYsZ0JBQVEsQ0FBQztZQUM3QyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksU0FBUztnQkFDOUMsV0FBVztJQUNSLGdCQUFBLGVBQXlDLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRTtJQUVqRSxRQUFBLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFXLEVBQUUsR0FBVyxLQUFJO0lBQ2xFLFlBQUEsTUFBTSxHQUFHLEdBQUksV0FBMkIsQ0FBQyxHQUF3QixDQUFDO0lBQ2xFLFlBQUEsSUFBSSxHQUFHO29CQUNMLE9BQU8sS0FBSyxDQUNWLEdBQUcsRUFDSCxHQUF3QixFQUN4QixHQUtZLENBQ2I7SUFDSCxZQUFBLE9BQU8sR0FBRzthQUNYLEVBQUUsSUFBSSxDQUFDOzs7O0lDcG9CWjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBOEJHO0lBQ2EsU0FBQSxHQUFHLENBQ2pCLEtBQUEsR0FBa0JBLGdCQUFRLENBQUMsSUFBSSxFQUMvQixTQUFxQixHQUFBLEtBQUssRUFDMUIsU0FBUyxHQUFHLENBQUMsRUFBQTtJQUViLElBQUEsT0FBTyxVQUNMLE1BQVcsRUFDWCxXQUFpQixFQUNqQixVQUErQixFQUFBO0lBRS9CLFFBQUEsSUFBSSxDQUFDLFVBQVU7SUFDYixZQUFBLE1BQU0sSUFBSSxLQUFLLENBQUMsQ0FBQSwwQ0FBQSxDQUE0QyxDQUFDO0lBQy9ELFFBQUEsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ3hELE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO0lBQ25DLFFBQUEsTUFBTSxjQUFjLEdBQUcsVUFBVSxDQUFDLEtBQUs7SUFFdkMsUUFBQSxNQUFNLElBQUksR0FBRyxVQUErQixHQUFHLElBQVcsRUFBQTtJQUN4RCxZQUFBLE1BQU0sQ0FBQyxDQUFlLFlBQUEsRUFBQSxJQUFJLEVBQUUsRUFBRSxTQUFTLENBQUM7SUFDeEMsWUFBQSxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFO0lBQ3hCLFlBQUEsSUFBSSxHQUFXO2dCQUNmLE1BQU0sTUFBTSxHQUFRLGNBQWMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQztJQUNwRCxZQUFBLElBQUksTUFBTSxZQUFZLE9BQU8sRUFBRTtJQUM3QixnQkFBQSxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUk7d0JBQ3ZCLElBQUksU0FBUyxFQUFFO0lBQ2Isd0JBQUEsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUU7SUFDaEIsd0JBQUEsSUFBSSxTQUFTO2dDQUFFLE1BQU0sQ0FBQyxnQkFBZ0IsR0FBRyxHQUFHLEtBQUssQ0FBSSxFQUFBLENBQUEsRUFBRSxTQUFTLENBQUM7O0lBRW5FLG9CQUFBLE9BQU8sQ0FBQztJQUNWLGlCQUFDLENBQUM7O2dCQUVKLElBQUksU0FBUyxFQUFFO0lBQ2IsZ0JBQUEsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUU7SUFDaEIsZ0JBQUEsSUFBSSxTQUFTO3dCQUFFLE1BQU0sQ0FBQyxnQkFBZ0IsR0FBRyxHQUFHLEtBQUssQ0FBSSxFQUFBLENBQUEsRUFBRSxTQUFTLENBQUM7O0lBR25FLFlBQUEsT0FBTyxNQUFNO0lBQ2YsU0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQVE7SUFFckIsUUFBQSxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUU7SUFDMUIsWUFBQSxLQUFLLEVBQUUsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJO0lBQzdCLFNBQUEsQ0FBQztJQUVGLFFBQUEsVUFBVSxDQUFDLEtBQUssR0FBRyxJQUFJO0lBQ3pCLEtBQUM7SUFDSDtJQUVBOzs7Ozs7O0lBT0c7SUFDYSxTQUFBLEtBQUssQ0FBQyxTQUFBLEdBQXFCLEtBQUssRUFBQTtRQUM5QyxPQUFPLEdBQUcsQ0FBQ0EsZ0JBQVEsQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDO0lBQ3ZDO0lBRUE7Ozs7Ozs7SUFPRztJQUNhLFNBQUEsSUFBSSxDQUFDLFNBQUEsR0FBcUIsS0FBSyxFQUFBO1FBQzdDLE9BQU8sR0FBRyxDQUFDQSxnQkFBUSxDQUFDLElBQUksRUFBRSxTQUFTLENBQUM7SUFDdEM7SUFFQTs7Ozs7OztJQU9HO0lBQ2EsU0FBQSxLQUFLLENBQUMsU0FBQSxHQUFxQixLQUFLLEVBQUE7UUFDOUMsT0FBTyxHQUFHLENBQUNBLGdCQUFRLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQztJQUN2QztJQW9DQTs7Ozs7Ozs7SUFRRzthQUNhLE9BQU8sQ0FBQyxTQUE4QixHQUFBLENBQUMsRUFBRSxTQUFtQixFQUFBO0lBQzFFLElBQUEsSUFBSSxPQUFPLFNBQVMsS0FBSyxTQUFTLEVBQUU7WUFDbEMsU0FBUyxHQUFHLFNBQVM7WUFDckIsU0FBUyxHQUFHLENBQUM7O1FBRWYsT0FBTyxHQUFHLENBQUNBLGdCQUFRLENBQUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUM7SUFDcEQ7O0lDbEtBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBK0JHO1VBQ21CLFdBQVcsQ0FBQTtJQUMvQjs7Ozs7SUFLRztJQUNILElBQUEsSUFBYyxHQUFHLEdBQUE7SUFDZixRQUFBLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFXLENBQUM7O0lBR2pDLElBQUEsV0FBQSxHQUFBO0lBQ0Q7O0lDeENEOzs7Ozs7Ozs7SUFTRztJQUVIOzs7OztJQUtHO0FBQ0ksVUFBTSxPQUFPLEdBQUc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OyJ9
|
|
1386
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2luZy5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvdGV4dC50cyIsIi4uL3NyYy93ZWIudHMiLCIuLi9zcmMvZW52aXJvbm1lbnQudHMiLCIuLi9zcmMvbG9nZ2luZy50cyIsIi4uL3NyYy9Mb2dnZWRDbGFzcy50cyIsIi4uL3NyYy9maWx0ZXJzL0xvZ0ZpbHRlci50cyIsIi4uL3NyYy9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL2ZpbHRlcnMvUGF0dGVybkZpbHRlci50cyIsIi4uL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMb2dnaW5nQ29uZmlnLCBUaGVtZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmV4cG9ydCBjb25zdCBCcm93c2VyRW52S2V5ID0gXCJFTlZcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVsaW1pdGVyIHVzZWQgZm9yIGNvbXBvc2luZyBuZXN0ZWQgZW52aXJvbm1lbnQgdmFyaWFibGUgbmFtZXMuXG4gKiBAc3VtbWFyeSBKb2lucyBwYXJlbnQgYW5kIGNoaWxkIGtleXMgd2hlbiBtYXBwaW5nIG9iamVjdCBwYXRocyB0byBFTlYgc3RyaW5ncy5cbiAqL1xuZXhwb3J0IGNvbnN0IEVOVl9QQVRIX0RFTElNSVRFUiA9IFwiX19cIjtcblxuZXhwb3J0IGNvbnN0IERlZmF1bHRQbGFjZWhvbGRlcldyYXBwZXJzID0gW1wiJHtcIiwgXCJ9XCJdO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFbnVtIGZvciBsb2cgbGV2ZWxzLlxuICogQHN1bW1hcnkgRGVmaW5lcyBkaWZmZXJlbnQgbGV2ZWxzIG9mIGxvZ2dpbmcgZm9yIHRoZSBhcHBsaWNhdGlvbi5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAcmVhZG9ubHlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZW51bSBMb2dMZXZlbCB7XG4gIC8qKiBFcnJvciBldmVudHMgdGhhdCBhcmUgbGlrZWx5IHRvIGNhdXNlIHByb2JsZW1zLiAqL1xuICBlcnJvciA9IFwiZXJyb3JcIixcbiAgLyoqIFJvdXRpbmUgaW5mb3JtYXRpb24sIHN1Y2ggYXMgb25nb2luZyBzdGF0dXMgb3IgcGVyZm9ybWFuY2UuICovXG4gIGluZm8gPSBcImluZm9cIixcbiAgLyoqIEFkZGl0aW9uYWwgcmVsZXZhbnQgaW5mb3JtYXRpb24uICovXG4gIHZlcmJvc2UgPSBcInZlcmJvc2VcIixcbiAgLyoqIERlYnVnIG9yIHRyYWNlIGluZm9ybWF0aW9uLiAqL1xuICBkZWJ1ZyA9IFwiZGVidWdcIixcbiAgLyoqIHdheSB0b28gdmVyYm9zZSBvciBzaWxseSBpbmZvcm1hdGlvbi4gKi9cbiAgc2lsbHkgPSBcInNpbGx5XCIsXG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE51bWVyaWMgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBsb2cgbGV2ZWxzLlxuICogQHN1bW1hcnkgUHJvdmlkZXMgYSBudW1lcmljIHJlcHJlc2VudGF0aW9uIG9mIGxvZyBsZXZlbHMgZm9yIGNvbXBhcmlzb24gYW5kIGZpbHRlcmluZy5cbiAqIEBjb25zdCBOdW1lcmljTG9nTGV2ZWxzXG4gKiBAcHJvcGVydHkge251bWJlcn0gZXJyb3IgLSBOdW1lcmljIHZhbHVlIGZvciBlcnJvciBsZXZlbCAoMikuXG4gKiBAcHJvcGVydHkge251bWJlcn0gaW5mbyAtIE51bWVyaWMgdmFsdWUgZm9yIGluZm8gbGV2ZWwgKDQpLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IHZlcmJvc2UgLSBOdW1lcmljIHZhbHVlIGZvciB2ZXJib3NlIGxldmVsICg2KS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBkZWJ1ZyAtIE51bWVyaWMgdmFsdWUgZm9yIGRlYnVnIGxldmVsICg3KS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBzaWxseSAtIE51bWVyaWMgdmFsdWUgZm9yIHNpbGx5IGxldmVsICg5KS5cbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3QgTnVtZXJpY0xvZ0xldmVscyA9IHtcbiAgZXJyb3I6IDIsXG4gIGluZm86IDQsXG4gIHZlcmJvc2U6IDYsXG4gIGRlYnVnOiA3LFxuICBzaWxseTogOSxcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVudW0gZm9yIGxvZ2dpbmcgb3V0cHV0IG1vZGVzLlxuICogQHN1bW1hcnkgRGVmaW5lcyBkaWZmZXJlbnQgb3V0cHV0IGZvcm1hdHMgZm9yIGxvZyBtZXNzYWdlcy5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGVudW0gTG9nZ2luZ01vZGUge1xuICAvKiogUmF3IHRleHQgZm9ybWF0IGZvciBodW1hbiByZWFkYWJpbGl0eSAqL1xuICBSQVcgPSBcInJhd1wiLFxuICAvKiogSlNPTiBmb3JtYXQgZm9yIG1hY2hpbmUgcGFyc2luZyAqL1xuICBKU09OID0gXCJqc29uXCIsXG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmF1bHQgdGhlbWUgZm9yIHN0eWxpbmcgbG9nIG91dHB1dC5cbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIGRlZmF1bHQgY29sb3IgYW5kIHN0eWxlIHNldHRpbmdzIGZvciB2YXJpb3VzIGNvbXBvbmVudHMgb2YgbG9nIG1lc3NhZ2VzLlxuICogQGNvbnN0IERlZmF1bHRUaGVtZVxuICogQHR5cGVkZWYge1RoZW1lfSBEZWZhdWx0VGhlbWVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBjbGFzcyAtIFN0eWxpbmcgZm9yIGNsYXNzIG5hbWVzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGNsYXNzLmZnIC0gRm9yZWdyb3VuZCBjb2xvciBjb2RlIGZvciBjbGFzcyBuYW1lcyAoMzQpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGlkIC0gU3R5bGluZyBmb3IgaWRlbnRpZmllcnMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gaWQuZmcgLSBGb3JlZ3JvdW5kIGNvbG9yIGNvZGUgZm9yIGlkZW50aWZpZXJzICgzNikuXG4gKiBAcHJvcGVydHkge09iamVjdH0gc3RhY2sgLSBTdHlsaW5nIGZvciBzdGFjayB0cmFjZXMgKGVtcHR5IG9iamVjdCkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gdGltZXN0YW1wIC0gU3R5bGluZyBmb3IgdGltZXN0YW1wcyAoZW1wdHkgb2JqZWN0KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBtZXNzYWdlIC0gU3R5bGluZyBmb3IgZGlmZmVyZW50IHR5cGVzIG9mIG1lc3NhZ2VzLlxuICogQHByb3BlcnR5IHtPYmplY3R9IG1lc3NhZ2UuZXJyb3IgLSBTdHlsaW5nIGZvciBlcnJvciBtZXNzYWdlcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtZXNzYWdlLmVycm9yLmZnIC0gRm9yZWdyb3VuZCBjb2xvciBjb2RlIGZvciBlcnJvciBtZXNzYWdlcyAoMzEpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IG1ldGhvZCAtIFN0eWxpbmcgZm9yIG1ldGhvZCBuYW1lcyAoZW1wdHkgb2JqZWN0KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2dMZXZlbCAtIFN0eWxpbmcgZm9yIGRpZmZlcmVudCBsb2cgbGV2ZWxzLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGxvZ0xldmVsLmVycm9yIC0gU3R5bGluZyBmb3IgZXJyb3IgbGV2ZWwgbG9ncy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsb2dMZXZlbC5lcnJvci5mZyAtIEZvcmVncm91bmQgY29sb3IgY29kZSBmb3IgZXJyb3IgbGV2ZWwgbG9ncyAoMzEpLlxuICogQHByb3BlcnR5IHtzdHJpbmdbXX0gbG9nTGV2ZWwuZXJyb3Iuc3R5bGUgLSBTdHlsZSBhdHRyaWJ1dGVzIGZvciBlcnJvciBsZXZlbCBsb2dzIChbXCJib2xkXCJdKS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2dMZXZlbC5pbmZvIC0gU3R5bGluZyBmb3IgaW5mbyBsZXZlbCBsb2dzIChlbXB0eSBvYmplY3QpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGxvZ0xldmVsLnZlcmJvc2UgLSBTdHlsaW5nIGZvciB2ZXJib3NlIGxldmVsIGxvZ3MgKGVtcHR5IG9iamVjdCkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nTGV2ZWwuZGVidWcgLSBTdHlsaW5nIGZvciBkZWJ1ZyBsZXZlbCBsb2dzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGxvZ0xldmVsLmRlYnVnLmZnIC0gRm9yZWdyb3VuZCBjb2xvciBjb2RlIGZvciBkZWJ1ZyBsZXZlbCBsb2dzICgzMykuXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGNvbnN0IERlZmF1bHRUaGVtZTogVGhlbWUgPSB7XG4gIGFwcDoge30sXG4gIHNlcGFyYXRvcjoge30sXG4gIGNsYXNzOiB7XG4gICAgZmc6IDM0LFxuICB9LFxuICBpZDoge1xuICAgIGZnOiAzNixcbiAgfSxcbiAgc3RhY2s6IHt9LFxuICB0aW1lc3RhbXA6IHt9LFxuICBtZXNzYWdlOiB7XG4gICAgZXJyb3I6IHtcbiAgICAgIGZnOiAzMSxcbiAgICB9LFxuICB9LFxuICBtZXRob2Q6IHt9LFxuICBsb2dMZXZlbDoge1xuICAgIGVycm9yOiB7XG4gICAgICBmZzogMzEsXG4gICAgICBzdHlsZTogW1wiYm9sZFwiXSxcbiAgICB9LFxuICAgIGluZm86IHtcbiAgICAgIGZnOiAzNCxcbiAgICAgIHN0eWxlOiBbXCJib2xkXCJdLFxuICAgIH0sXG4gICAgdmVyYm9zZToge1xuICAgICAgZmc6IDM0LFxuICAgICAgc3R5bGU6IFtcImJvbGRcIl0sXG4gICAgfSxcbiAgICBkZWJ1Zzoge1xuICAgICAgZmc6IDMzLFxuICAgICAgc3R5bGU6IFtcImJvbGRcIl0sXG4gICAgfSxcbiAgfSxcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmF1bHQgY29uZmlndXJhdGlvbiBmb3IgbG9nZ2luZy5cbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIGRlZmF1bHQgc2V0dGluZ3MgZm9yIHRoZSBsb2dnaW5nIHN5c3RlbSwgaW5jbHVkaW5nIHZlcmJvc2l0eSwgbG9nIGxldmVsLCBzdHlsaW5nLCBhbmQgdGltZXN0YW1wIGZvcm1hdC5cbiAqIEBjb25zdCBEZWZhdWx0TG9nZ2luZ0NvbmZpZ1xuICogQHR5cGVkZWYge0xvZ2dpbmdDb25maWd9IERlZmF1bHRMb2dnaW5nQ29uZmlnXG4gKiBAcHJvcGVydHkge251bWJlcn0gdmVyYm9zZSAtIFZlcmJvc2l0eSBsZXZlbCAoMCkuXG4gKiBAcHJvcGVydHkge0xvZ0xldmVsfSBsZXZlbCAtIERlZmF1bHQgbG9nIGxldmVsIChMb2dMZXZlbC5pbmZvKS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gbG9nTGV2ZWwgLSBXaGV0aGVyIHRvIGRpc3BsYXkgbG9nIGxldmVsIGluIG91dHB1dCAodHJ1ZSkuXG4gKiBAcHJvcGVydHkge0xvZ2dpbmdNb2RlfSBtb2RlIC0gT3V0cHV0IGZvcm1hdCBtb2RlIChMb2dnaW5nTW9kZS5SQVcpLlxuICogQHByb3BlcnR5IHtib29sZWFufSBzdHlsZSAtIFdoZXRoZXIgdG8gYXBwbHkgc3R5bGluZyB0byBsb2cgb3V0cHV0IChmYWxzZSkuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gc2VwYXJhdG9yIC0gU2VwYXJhdG9yIGJldHdlZW4gbG9nIGNvbXBvbmVudHMgKFwiIC0gXCIpLlxuICogQHByb3BlcnR5IHtib29sZWFufSB0aW1lc3RhbXAgLSBXaGV0aGVyIHRvIGluY2x1ZGUgdGltZXN0YW1wcyBpbiBsb2cgbWVzc2FnZXMgKHRydWUpLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHRpbWVzdGFtcEZvcm1hdCAtIEZvcm1hdCBmb3IgdGltZXN0YW1wcyAoXCJISDptbTpzcy5TU1NcIikuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGNvbnRleHQgLSBXaGV0aGVyIHRvIGluY2x1ZGUgY29udGV4dCBpbmZvcm1hdGlvbiBpbiBsb2cgbWVzc2FnZXMgKHRydWUpLlxuICogQHByb3BlcnR5IHtUaGVtZX0gdGhlbWUgLSBUaGUgdGhlbWUgdG8gdXNlIGZvciBzdHlsaW5nIGxvZyBtZXNzYWdlcyAoRGVmYXVsdFRoZW1lKS5cbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3QgRGVmYXVsdExvZ2dpbmdDb25maWc6IExvZ2dpbmdDb25maWcgPSB7XG4gIGVudjogXCJkZXZlbG9wbWVudFwiLFxuICB2ZXJib3NlOiAwLFxuICBsZXZlbDogTG9nTGV2ZWwuaW5mbyxcbiAgbG9nTGV2ZWw6IHRydWUsXG4gIHN0eWxlOiBmYWxzZSxcbiAgY29udGV4dFNlcGFyYXRvcjogXCIuXCIsXG4gIHNlcGFyYXRvcjogXCItXCIsXG4gIHRpbWVzdGFtcDogdHJ1ZSxcbiAgdGltZXN0YW1wRm9ybWF0OiBcIkhIOm1tOnNzLlNTU1wiLFxuICBjb250ZXh0OiB0cnVlLFxuICBmb3JtYXQ6IExvZ2dpbmdNb2RlLlJBVyxcbiAgcGF0dGVybjpcbiAgICBcIntsZXZlbH0gW3t0aW1lc3RhbXB9XSB7YXBwfSB7Y29udGV4dH0ge3NlcGFyYXRvcn0ge21lc3NhZ2V9IHtzdGFja31cIixcbiAgdGhlbWU6IERlZmF1bHRUaGVtZSxcbn07XG4iLCJpbXBvcnQgeyBEZWZhdWx0UGxhY2Vob2xkZXJXcmFwcGVycyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBQYWRzIHRoZSBlbmQgb2YgYSBzdHJpbmcgd2l0aCBhIHNwZWNpZmllZCBjaGFyYWN0ZXIuXG4gKiBAc3VtbWFyeSBFeHRlbmRzIHRoZSBpbnB1dCBzdHJpbmcgdG8gYSBzcGVjaWZpZWQgbGVuZ3RoIGJ5IGFkZGluZyBhIHBhZGRpbmcgY2hhcmFjdGVyIHRvIHRoZSBlbmQuXG4gKiBJZiB0aGUgaW5wdXQgc3RyaW5nIGlzIGFscmVhZHkgbG9uZ2VyIHRoYW4gdGhlIHNwZWNpZmllZCBsZW5ndGgsIGl0IGlzIHJldHVybmVkIHVuY2hhbmdlZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIC0gVGhlIGlucHV0IHN0cmluZyB0byBiZSBwYWRkZWQuXG4gKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIC0gVGhlIGRlc2lyZWQgdG90YWwgbGVuZ3RoIG9mIHRoZSByZXN1bHRpbmcgc3RyaW5nLlxuICogQHBhcmFtIHtzdHJpbmd9IFtjaGFyPVwiIFwiXSAtIFRoZSBjaGFyYWN0ZXIgdG8gdXNlIGZvciBwYWRkaW5nLiBEZWZhdWx0cyB0byBhIHNwYWNlLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgcGFkZGVkIHN0cmluZy5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGFkZGluZyBjaGFyYWN0ZXIgaXMgbm90IGV4YWN0bHkgb25lIGNoYXJhY3RlciBsb25nLlxuICpcbiAqIEBmdW5jdGlvbiBwYWRFbmRcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhZEVuZChcbiAgc3RyOiBzdHJpbmcsXG4gIGxlbmd0aDogbnVtYmVyLFxuICBjaGFyOiBzdHJpbmcgPSBcIiBcIlxuKTogc3RyaW5nIHtcbiAgaWYgKGNoYXIubGVuZ3RoICE9PSAxKVxuICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgY2hhcmFjdGVyIGxlbmd0aCBmb3IgcGFkZGluZy4gbXVzdCBiZSBvbmUhXCIpO1xuICByZXR1cm4gc3RyLnBhZEVuZChsZW5ndGgsIGNoYXIpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZXBsYWNlcyBwbGFjZWhvbGRlcnMgaW4gYSBzdHJpbmcgd2l0aCBwcm92aWRlZCB2YWx1ZXMuXG4gKiBAc3VtbWFyeSBJbnRlcnBvbGF0ZXMgYSBzdHJpbmcgYnkgcmVwbGFjaW5nIHBsYWNlaG9sZGVycyBvZiB0aGUgZm9ybSAke3ZhcmlhYmxlTmFtZX1cbiAqIHdpdGggY29ycmVzcG9uZGluZyB2YWx1ZXMgZnJvbSB0aGUgcHJvdmlkZWQgb2JqZWN0LiBJZiBhIHBsYWNlaG9sZGVyIGRvZXNuJ3QgaGF2ZVxuICogYSBjb3JyZXNwb25kaW5nIHZhbHVlLCBpdCBpcyBsZWZ0IHVuY2hhbmdlZCBpbiB0aGUgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dCAtIFRoZSBpbnB1dCBzdHJpbmcgY29udGFpbmluZyBwbGFjZWhvbGRlcnMgdG8gYmUgcmVwbGFjZWQuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz59IHZhbHVlcyAtIEFuIG9iamVjdCBjb250YWluaW5nIGtleS12YWx1ZSBwYWlycyBmb3IgcmVwbGFjZW1lbnQuXG4gKiBAcGFyYW0gcHJlZml4XG4gKiBAcGFyYW0gc3VmZml4XG4gKiBAcGFyYW0gZmxhZ3NcbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGludGVycG9sYXRlZCBzdHJpbmcgd2l0aCBwbGFjZWhvbGRlcnMgcmVwbGFjZWQgYnkgdGhlaXIgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gKlxuICogQGZ1bmN0aW9uIHBhdGNoUGxhY2Vob2xkZXJzXG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgcGF0Y2hTdHJpbmdcbiAqICAgcGFydGljaXBhbnQgU3RyaW5nLnJlcGxhY2VcbiAqICAgQ2FsbGVyLT4+cGF0Y2hTdHJpbmc6IENhbGwgd2l0aCBpbnB1dCBhbmQgdmFsdWVzXG4gKiAgIHBhdGNoU3RyaW5nLT4+U3RyaW5nLnJlcGxhY2U6IENhbGwgd2l0aCByZWdleCBhbmQgcmVwbGFjZW1lbnQgZnVuY3Rpb25cbiAqICAgU3RyaW5nLnJlcGxhY2UtPj5wYXRjaFN0cmluZzogUmV0dXJuIHJlcGxhY2VkIHN0cmluZ1xuICogICBwYXRjaFN0cmluZy0tPj5DYWxsZXI6IFJldHVybiBwYXRjaGVkIHN0cmluZ1xuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGF0Y2hQbGFjZWhvbGRlcnMoXG4gIGlucHV0OiBzdHJpbmcsXG4gIHZhbHVlczogUmVjb3JkPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPixcbiAgcHJlZml4OiBzdHJpbmcgPSBEZWZhdWx0UGxhY2Vob2xkZXJXcmFwcGVyc1swXSxcbiAgc3VmZml4OiBzdHJpbmcgPSBEZWZhdWx0UGxhY2Vob2xkZXJXcmFwcGVyc1sxXSxcbiAgZmxhZ3M6IHN0cmluZyA9IFwiZ1wiXG4pOiBzdHJpbmcge1xuICBjb25zdCBwbGFjZWhvbGRlcnMgPSBPYmplY3QuZW50cmllcyh2YWx1ZXMpLnJlZHVjZShcbiAgICAoYWNjOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBba2V5LCB2YWxdKSA9PiB7XG4gICAgICBhY2NbYCR7cHJlZml4fSR7a2V5fSR7c3VmZml4fWBdID0gdmFsO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LFxuICAgIHt9XG4gICk7XG4gIHJldHVybiBwYXRjaFN0cmluZyhpbnB1dCwgcGxhY2Vob2xkZXJzLCBmbGFncyk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFJlcGxhY2VzIG9jY3VycmVuY2VzIG9mIGtleXMgd2l0aCB0aGVpciBjb3JyZXNwb25kaW5nIHZhbHVlcyBpbiBhIHN0cmluZy5cbiAqIEBzdW1tYXJ5IEl0ZXJhdGVzIHRocm91Z2ggYSBzZXQgb2Yga2V5LXZhbHVlIHBhaXJzIGFuZCByZXBsYWNlcyBhbGwgb2NjdXJyZW5jZXMgb2YgZWFjaCBrZXlcbiAqIGluIHRoZSBpbnB1dCBzdHJpbmcgd2l0aCBpdHMgY29ycmVzcG9uZGluZyB2YWx1ZS4gU3VwcG9ydHMgcmVndWxhciBleHByZXNzaW9uIGZsYWdzIGZvciBjdXN0b21pemVkIHJlcGxhY2VtZW50LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dCAtIFRoZSBpbnB1dCBzdHJpbmcgaW4gd2hpY2ggcmVwbGFjZW1lbnRzIHdpbGwgYmUgbWFkZS5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPn0gdmFsdWVzIC0gQW4gb2JqZWN0IGNvbnRhaW5pbmcga2V5LXZhbHVlIHBhaXJzIGZvciByZXBsYWNlbWVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbZmxhZ3M9XCJnXCJdIC0gUmVndWxhciBleHByZXNzaW9uIGZsYWdzIHRvIGNvbnRyb2wgdGhlIHJlcGxhY2VtZW50IGJlaGF2aW9yLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgc3RyaW5nIHdpdGggYWxsIHNwZWNpZmllZCByZXBsYWNlbWVudHMgYXBwbGllZC5cbiAqXG4gKiBAZnVuY3Rpb24gcGF0Y2hTdHJpbmdcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhdGNoU3RyaW5nKFxuICBpbnB1dDogc3RyaW5nLFxuICB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz4sXG4gIGZsYWdzOiBzdHJpbmcgPSBcImdcIlxuKTogc3RyaW5nIHtcbiAgT2JqZWN0LmVudHJpZXModmFsdWVzKS5mb3JFYWNoKChba2V5LCB2YWxdKSA9PiB7XG4gICAgY29uc3QgcmVnZXhwID0gbmV3IFJlZ0V4cChlc2NhcGVSZWdFeHAoa2V5KSwgZmxhZ3MpO1xuICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZShyZWdleHAsIHZhbCBhcyBzdHJpbmcpO1xuICB9KTtcbiAgcmV0dXJuIGlucHV0O1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBhIHN0cmluZyB0byBjYW1lbENhc2UuXG4gKiBAc3VtbWFyeSBUcmFuc2Zvcm1zIHRoZSBpbnB1dCBzdHJpbmcgaW50byBjYW1lbENhc2UgZm9ybWF0LCB3aGVyZSB3b3JkcyBhcmUgam9pbmVkIHdpdGhvdXQgc3BhY2VzXG4gKiBhbmQgZWFjaCB3b3JkIGFmdGVyIHRoZSBmaXJzdCBzdGFydHMgd2l0aCBhIGNhcGl0YWwgbGV0dGVyLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGhlIGlucHV0IHN0cmluZyB0byBiZSBjb252ZXJ0ZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBpbnB1dCBzdHJpbmcgY29udmVydGVkIHRvIGNhbWVsQ2FzZS5cbiAqXG4gKiBAZnVuY3Rpb24gdG9DYW1lbENhc2VcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvQ2FtZWxDYXNlKHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB0ZXh0XG4gICAgLnJlcGxhY2UoLyg/Ol5cXHd8W0EtWl18XFxiXFx3KS9nLCAod29yZCwgaW5kZXgpID0+XG4gICAgICBpbmRleCA9PT0gMCA/IHdvcmQudG9Mb3dlckNhc2UoKSA6IHdvcmQudG9VcHBlckNhc2UoKVxuICAgIClcbiAgICAucmVwbGFjZSgvXFxzKy9nLCBcIlwiKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29udmVydHMgYSBzdHJpbmcgdG8gRU5WSVJPTk1FTlRfVkFSSUFCTEUgZm9ybWF0LlxuICogQHN1bW1hcnkgVHJhbnNmb3JtcyB0aGUgaW5wdXQgc3RyaW5nIGludG8gdXBwZXJjYXNlIHdpdGggd29yZHMgc2VwYXJhdGVkIGJ5IHVuZGVyc2NvcmVzLFxuICogdHlwaWNhbGx5IHVzZWQgZm9yIGVudmlyb25tZW50IHZhcmlhYmxlIG5hbWVzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGhlIGlucHV0IHN0cmluZyB0byBiZSBjb252ZXJ0ZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBpbnB1dCBzdHJpbmcgY29udmVydGVkIHRvIEVOVklST05NRU5UX1ZBUklBQkxFIGZvcm1hdC5cbiAqXG4gKiBAZnVuY3Rpb24gdG9FTlZGb3JtYXRcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvRU5WRm9ybWF0KHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB0b1NuYWtlQ2FzZSh0ZXh0KS50b1VwcGVyQ2FzZSgpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBhIHN0cmluZyB0byBzbmFrZV9jYXNlLlxuICogQHN1bW1hcnkgVHJhbnNmb3JtcyB0aGUgaW5wdXQgc3RyaW5nIGludG8gbG93ZXJjYXNlIHdpdGggd29yZHMgc2VwYXJhdGVkIGJ5IHVuZGVyc2NvcmVzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGhlIGlucHV0IHN0cmluZyB0byBiZSBjb252ZXJ0ZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBpbnB1dCBzdHJpbmcgY29udmVydGVkIHRvIHNuYWtlX2Nhc2UuXG4gKlxuICogQGZ1bmN0aW9uIHRvU25ha2VDYXNlXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b1NuYWtlQ2FzZSh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdGV4dFxuICAgIC5yZXBsYWNlKC8oW2Etel0pKFtBLVpdKS9nLCBcIiQxXyQyXCIpXG4gICAgLnJlcGxhY2UoL1tcXHMtXSsvZywgXCJfXCIpXG4gICAgLnRvTG93ZXJDYXNlKCk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvbnZlcnRzIGEgc3RyaW5nIHRvIGtlYmFiLWNhc2UuXG4gKiBAc3VtbWFyeSBUcmFuc2Zvcm1zIHRoZSBpbnB1dCBzdHJpbmcgaW50byBsb3dlcmNhc2Ugd2l0aCB3b3JkcyBzZXBhcmF0ZWQgYnkgaHlwaGVucy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSBpbnB1dCBzdHJpbmcgdG8gYmUgY29udmVydGVkLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgaW5wdXQgc3RyaW5nIGNvbnZlcnRlZCB0byBrZWJhYi1jYXNlLlxuICpcbiAqIEBmdW5jdGlvbiB0b0tlYmFiQ2FzZVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gdG9LZWJhYkNhc2UodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHRleHRcbiAgICAucmVwbGFjZSgvKFthLXpdKShbQS1aXSkvZywgXCIkMS0kMlwiKVxuICAgIC5yZXBsYWNlKC9bXFxzX10rL2csIFwiLVwiKVxuICAgIC50b0xvd2VyQ2FzZSgpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBhIHN0cmluZyB0byBQYXNjYWxDYXNlLlxuICogQHN1bW1hcnkgVHJhbnNmb3JtcyB0aGUgaW5wdXQgc3RyaW5nIGludG8gUGFzY2FsQ2FzZSBmb3JtYXQsIHdoZXJlIHdvcmRzIGFyZSBqb2luZWQgd2l0aG91dCBzcGFjZXNcbiAqIGFuZCBlYWNoIHdvcmQgc3RhcnRzIHdpdGggYSBjYXBpdGFsIGxldHRlci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSBpbnB1dCBzdHJpbmcgdG8gYmUgY29udmVydGVkLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgaW5wdXQgc3RyaW5nIGNvbnZlcnRlZCB0byBQYXNjYWxDYXNlLlxuICpcbiAqIEBmdW5jdGlvbiB0b1Bhc2NhbENhc2VcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvUGFzY2FsQ2FzZSh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdGV4dFxuICAgIC5yZXBsYWNlKC8oPzpeXFx3fFtBLVpdfFxcYlxcdykvZywgKHdvcmQpID0+IHdvcmQudG9VcHBlckNhc2UoKSlcbiAgICAucmVwbGFjZSgvXFxzKy9nLCBcIlwiKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRXNjYXBlcyBzcGVjaWFsIGNoYXJhY3RlcnMgaW4gYSBzdHJpbmcgZm9yIHVzZSBpbiBhIHJlZ3VsYXIgZXhwcmVzc2lvbi5cbiAqIEBzdW1tYXJ5IEFkZHMgYmFja3NsYXNoZXMgYmVmb3JlIGNoYXJhY3RlcnMgdGhhdCBoYXZlIHNwZWNpYWwgbWVhbmluZyBpbiByZWd1bGFyIGV4cHJlc3Npb25zLFxuICogYWxsb3dpbmcgdGhlIHN0cmluZyB0byBiZSB1c2VkIGFzIGEgbGl0ZXJhbCBtYXRjaCBpbiBhIFJlZ0V4cC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIC0gVGhlIHN0cmluZyB0byBlc2NhcGUgZm9yIHJlZ3VsYXIgZXhwcmVzc2lvbiB1c2UuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBlc2NhcGVkIHN0cmluZyBzYWZlIGZvciB1c2UgaW4gcmVndWxhciBleHByZXNzaW9ucy5cbiAqXG4gKiBAZnVuY3Rpb24gZXNjYXBlUmVnRXhwXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGVSZWdFeHAoc3RyaW5nOiBzdHJpbmcpIHtcbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC9bLiorP14ke30oKXxbXFxdXFxcXF0vZywgXCJcXFxcJCZcIik7IC8vICQmIG1lYW5zIHRoZSB3aG9sZSBtYXRjaGVkIHN0cmluZ1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFV0aWwgZnVuY3Rpb24gdG8gcHJvdmlkZSBzdHJpbmcgZm9ybWF0IGZ1bmN0aW9uYWxpdHkgc2ltaWxhciB0byBDIydzIHN0cmluZy5mb3JtYXRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZyB8IG51bWJlcj4gfCBSZWNvcmQ8c3RyaW5nLCBhbnk+fSBbYXJnc10gcmVwbGFjZW1lbnRzIG1hZGUgYnkgb3JkZXIgb2YgYXBwZWFyYW5jZSAocmVwbGFjZW1lbnQwIHdpbCByZXBsYWNlIHswfSBhbmQgc28gb24pXG4gKiBAcmV0dXJuIHtzdHJpbmd9IGZvcm1hdHRlZCBzdHJpbmdcbiAqXG4gKiBAZnVuY3Rpb24gc2ZcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gc2YoXG4gIHN0cmluZzogc3RyaW5nLFxuICAuLi5hcmdzOiAoc3RyaW5nIHwgbnVtYmVyIHwgUmVjb3JkPHN0cmluZywgYW55PilbXVxuKSB7XG4gIGlmIChhcmdzLmxlbmd0aCA+IDEpIHtcbiAgICBpZiAoXG4gICAgICAhYXJncy5ldmVyeSgoYXJnKSA9PiB0eXBlb2YgYXJnID09PSBcInN0cmluZ1wiIHx8IHR5cGVvZiBhcmcgPT09IFwibnVtYmVyXCIpXG4gICAgKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgT25seSBzdHJpbmcgYW5kIG51bWJlciBhcmd1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgbXVsdGlwbGUgcmVwbGFjZW1lbnRzLmBcbiAgICAgICk7XG4gIH1cblxuICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGFyZ3NbMF0gPT09IFwib2JqZWN0XCIpIHtcbiAgICBjb25zdCBvYmogPSBhcmdzWzBdIGFzIFJlY29yZDxzdHJpbmcsIGFueT47XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKG9iaikucmVkdWNlKChhY2MsIFtrZXksIHZhbF0pID0+IHtcbiAgICAgIHJldHVybiBhY2MucmVwbGFjZShuZXcgUmVnRXhwKGBcXFxceyR7a2V5fVxcXFx9YCwgXCJnXCIpLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgICB9KTtcbiAgICB9LCBzdHJpbmcpO1xuICB9XG5cbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC97KFxcZCspfS9nLCBmdW5jdGlvbiAobWF0Y2gsIG51bWJlcikge1xuICAgIHJldHVybiB0eXBlb2YgYXJnc1tudW1iZXJdICE9PSBcInVuZGVmaW5lZFwiXG4gICAgICA/IGFyZ3NbbnVtYmVyXS50b1N0cmluZygpXG4gICAgICA6IFwidW5kZWZpbmVkXCI7XG4gIH0pO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFV0aWwgZnVuY3Rpb24gdG8gcHJvdmlkZSBzdHJpbmcgZm9ybWF0IGZ1bmN0aW9uYWxpdHkgc2ltaWxhciB0byBDIydzIHN0cmluZy5mb3JtYXRcbiAqXG4gKiBAc2VlIHNmXG4gKlxuICogQGRlcHJlY2F0ZWRcbiAqIEBmdW5jdGlvbiBzdHJpbmdGb3JtYXRcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3Qgc3RyaW5nRm9ybWF0ID0gc2Y7XG4iLCIvKipcbiAqIEBkZXNjcmlwdGlvbiBEZXRlcm1pbmVzIGlmIHRoZSBjdXJyZW50IGVudmlyb25tZW50IGlzIGEgYnJvd3NlciBieSBjaGVja2luZyB0aGUgcHJvdG90eXBlIGNoYWluIG9mIHRoZSBnbG9iYWwgb2JqZWN0LlxuICogQHN1bW1hcnkgQ2hlY2tzIGlmIHRoZSBjb2RlIGlzIHJ1bm5pbmcgaW4gYSBicm93c2VyIGVudmlyb25tZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZW52aXJvbm1lbnQgaXMgYSBicm93c2VyLCBmYWxzZSBvdGhlcndpc2UuXG4gKiBAZnVuY3Rpb24gaXNCcm93c2VyXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQnJvd3NlcigpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBPYmplY3QuZ2V0UHJvdG90eXBlT2YoT2JqZWN0LmdldFByb3RvdHlwZU9mKGdsb2JhbFRoaXMpKSAhPT1cbiAgICBPYmplY3QucHJvdG90eXBlXG4gICk7XG59XG4iLCJpbXBvcnQgeyBPYmplY3RBY2N1bXVsYXRvciB9IGZyb20gXCJ0eXBlZC1vYmplY3QtYWNjdW11bGF0b3JcIjtcbmltcG9ydCB7IHRvRU5WRm9ybWF0IH0gZnJvbSBcIi4vdGV4dFwiO1xuaW1wb3J0IHsgaXNCcm93c2VyIH0gZnJvbSBcIi4vd2ViXCI7XG5pbXBvcnQge1xuICBCcm93c2VyRW52S2V5LFxuICBEZWZhdWx0TG9nZ2luZ0NvbmZpZyxcbiAgRU5WX1BBVEhfREVMSU1JVEVSLFxufSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRmFjdG9yeSB0eXBlIGZvciBjcmVhdGluZyBFbnZpcm9ubWVudCBpbnN0YW5jZXMuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgZnVuY3Rpb24gdHlwZSB0aGF0IGNyZWF0ZXMgYW5kIHJldHVybnMgRW52aXJvbm1lbnQgaW5zdGFuY2VzLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIC0gVGhlIHR5cGUgb2Ygb2JqZWN0IHRoZSBFbnZpcm9ubWVudCB3aWxsIGFjY3VtdWxhdGUuXG4gKiBAdGVtcGxhdGUgRSAtIFRoZSBzcGVjaWZpYyBFbnZpcm9ubWVudCB0eXBlIHRvIGJlIGNyZWF0ZWQsIGV4dGVuZGluZyBFbnZpcm9ubWVudDxUPi5cbiAqIEB0eXBlZGVmIHtmdW5jdGlvbiguLi51bmtub3duW10pOiBFfSBFbnZpcm9ubWVudEZhY3RvcnlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgdHlwZSBFbnZpcm9ubWVudEZhY3Rvcnk8VCBleHRlbmRzIG9iamVjdCwgRSBleHRlbmRzIEVudmlyb25tZW50PFQ+PiA9IChcbiAgLi4uYXJnczogdW5rbm93bltdXG4pID0+IEU7XG5cbi8qKlxuICogQGNsYXNzIEVudmlyb25tZW50XG4gKiBAZXh0ZW5kcyB7T2JqZWN0QWNjdW11bGF0b3I8VD59XG4gKiBAdGVtcGxhdGUgVFxuICogQGRlc2NyaXB0aW9uIEEgY2xhc3MgcmVwcmVzZW50aW5nIGFuIGVudmlyb25tZW50IHdpdGggYWNjdW11bGF0aW9uIGNhcGFiaWxpdGllcy5cbiAqIEBzdW1tYXJ5IE1hbmFnZXMgZW52aXJvbm1lbnQtcmVsYXRlZCBkYXRhIGFuZCBwcm92aWRlcyBtZXRob2RzIGZvciBhY2N1bXVsYXRpb24gYW5kIGtleSByZXRyaWV2YWwuXG4gKiBAcGFyYW0ge1R9IFtpbml0aWFsRGF0YV0gLSBUaGUgaW5pdGlhbCBkYXRhIHRvIHBvcHVsYXRlIHRoZSBlbnZpcm9ubWVudCB3aXRoLlxuICovXG5leHBvcnQgY2xhc3MgRW52aXJvbm1lbnQ8VCBleHRlbmRzIG9iamVjdD4gZXh0ZW5kcyBPYmplY3RBY2N1bXVsYXRvcjxUPiB7XG4gIC8qKlxuICAgKiBAc3RhdGljXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQGRlc2NyaXB0aW9uIEEgZmFjdG9yeSBmdW5jdGlvbiBmb3IgY3JlYXRpbmcgRW52aXJvbm1lbnQgaW5zdGFuY2VzLlxuICAgKiBAc3VtbWFyeSBEZWZpbmVzIGhvdyBuZXcgaW5zdGFuY2VzIG9mIHRoZSBFbnZpcm9ubWVudCBjbGFzcyBzaG91bGQgYmUgY3JlYXRlZC5cbiAgICogQHJldHVybiB7RW52aXJvbm1lbnQ8YW55Pn0gQSBuZXcgaW5zdGFuY2Ugb2YgdGhlIEVudmlyb25tZW50IGNsYXNzLlxuICAgKi9cbiAgcHJvdGVjdGVkIHN0YXRpYyBmYWN0b3J5OiBFbnZpcm9ubWVudEZhY3Rvcnk8YW55LCBhbnk+ID1cbiAgICAoKTogRW52aXJvbm1lbnQ8YW55PiA9PiBuZXcgRW52aXJvbm1lbnQoKTtcblxuICAvKipcbiAgICogQHN0YXRpY1xuICAgKiBAcHJpdmF0ZVxuICAgKiBAZGVzY3JpcHRpb24gVGhlIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiB0aGUgRW52aXJvbm1lbnQgY2xhc3MuXG4gICAqIEB0eXBlIHtFbnZpcm9ubWVudDxhbnk+fVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgX2luc3RhbmNlOiBFbnZpcm9ubWVudDxhbnk+O1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYSB2YWx1ZSBmcm9tIHRoZSBlbnZpcm9ubWVudFxuICAgKiBAc3VtbWFyeSBHZXRzIGEgdmFsdWUgZnJvbSB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGVzLCBoYW5kbGluZyBicm93c2VyIGFuZCBOb2RlLmpzIGVudmlyb25tZW50cyBkaWZmZXJlbnRseVxuICAgKiBAcGFyYW0ge3N0cmluZ30gayAtIFRoZSBrZXkgdG8gcmV0cmlldmUgZnJvbSB0aGUgZW52aXJvbm1lbnRcbiAgICogQHJldHVybiB7dW5rbm93bn0gVGhlIHZhbHVlIGZyb20gdGhlIGVudmlyb25tZW50LCBvciB1bmRlZmluZWQgaWYgbm90IGZvdW5kXG4gICAqL1xuICBwcm90ZWN0ZWQgZnJvbUVudihrOiBzdHJpbmcpIHtcbiAgICBsZXQgZW52OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICBpZiAoaXNCcm93c2VyKCkpIHtcbiAgICAgIGVudiA9IChcbiAgICAgICAgZ2xvYmFsVGhpcyBhcyB0eXBlb2YgZ2xvYmFsVGhpcyAmIHtcbiAgICAgICAgICBbQnJvd3NlckVudktleV06IFJlY29yZDxzdHJpbmcsIGFueT47XG4gICAgICAgIH1cbiAgICAgIClbQnJvd3NlckVudktleV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGVudiA9IGdsb2JhbFRoaXMucHJvY2Vzcy5lbnY7XG4gICAgICBrID0gdG9FTlZGb3JtYXQoayk7XG4gICAgfVxuICAgIHJldHVybiBlbnZba107XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEV4cGFuZHMgYW4gb2JqZWN0IGludG8gdGhlIGVudmlyb25tZW50XG4gICAqIEBzdW1tYXJ5IERlZmluZXMgcHJvcGVydGllcyBvbiB0aGUgZW52aXJvbm1lbnQgb2JqZWN0IHRoYXQgY2FuIGJlIGFjY2Vzc2VkIGFzIGdldHRlcnMgYW5kIHNldHRlcnNcbiAgICogQHRlbXBsYXRlIFYgLSBUeXBlIG9mIHRoZSBvYmplY3QgYmVpbmcgZXhwYW5kZWRcbiAgICogQHBhcmFtIHtWfSB2YWx1ZSAtIFRoZSBvYmplY3QgdG8gZXhwYW5kIGludG8gdGhlIGVudmlyb25tZW50XG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgZXhwYW5kPFYgZXh0ZW5kcyBvYmplY3Q+KHZhbHVlOiBWKTogdm9pZCB7XG4gICAgT2JqZWN0LmVudHJpZXModmFsdWUpLmZvckVhY2goKFtrLCB2XSkgPT4ge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIGssIHtcbiAgICAgICAgZ2V0OiAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZnJvbUVudiA9IHRoaXMuZnJvbUVudihrKTtcbiAgICAgICAgICBpZiAodHlwZW9mIGZyb21FbnYgIT09IFwidW5kZWZpbmVkXCIpIHJldHVybiBmcm9tRW52O1xuICAgICAgICAgIGlmICh2ICYmIHR5cGVvZiB2ID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gRW52aXJvbm1lbnQuYnVpbGRFbnZQcm94eSh2IGFzIGFueSwgW2tdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gSWYgdGhlIG1vZGVsIHByb3ZpZGVzIGFuIGVtcHR5IHN0cmluZywgZXhwb3NlIGEgcHJveHkgdGhhdCBjb21wb3NlcyBFTlYga2V5c1xuICAgICAgICAgIGlmICh2ID09PSBcIlwiKSB7XG4gICAgICAgICAgICByZXR1cm4gRW52aXJvbm1lbnQuYnVpbGRFbnZQcm94eSh1bmRlZmluZWQsIFtrXSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB2O1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6ICh2YWw6IFZba2V5b2YgVl0pID0+IHtcbiAgICAgICAgICB2ID0gdmFsO1xuICAgICAgICB9LFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEBzdGF0aWNcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBvciBjcmVhdGVzIHRoZSBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgdGhlIEVudmlyb25tZW50IGNsYXNzLlxuICAgKiBAc3VtbWFyeSBFbnN1cmVzIG9ubHkgb25lIGluc3RhbmNlIG9mIHRoZSBFbnZpcm9ubWVudCBjbGFzcyBleGlzdHMuXG4gICAqIEB0ZW1wbGF0ZSBFXG4gICAqIEBwYXJhbSB7Li4udW5rbm93bltdfSBhcmdzIC0gQXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGZhY3RvcnkgZnVuY3Rpb24gaWYgYSBuZXcgaW5zdGFuY2UgaXMgY3JlYXRlZC5cbiAgICogQHJldHVybiB7RX0gVGhlIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiB0aGUgRW52aXJvbm1lbnQgY2xhc3MuXG4gICAqL1xuICBwcm90ZWN0ZWQgc3RhdGljIGluc3RhbmNlPEUgZXh0ZW5kcyBFbnZpcm9ubWVudDxhbnk+PiguLi5hcmdzOiB1bmtub3duW10pOiBFIHtcbiAgICBpZiAoIUVudmlyb25tZW50Ll9pbnN0YW5jZSkge1xuICAgICAgY29uc3QgYmFzZSA9IEVudmlyb25tZW50LmZhY3RvcnkoLi4uYXJncykgYXMgRTtcbiAgICAgIGNvbnN0IHByb3hpZWQgPSBuZXcgUHJveHkoYmFzZSBhcyBhbnksIHtcbiAgICAgICAgZ2V0KHRhcmdldCwgcHJvcCwgcmVjZWl2ZXIpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IFJlZmxlY3QuZ2V0KHRhcmdldCwgcHJvcCwgcmVjZWl2ZXIpO1xuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09IFwidW5kZWZpbmVkXCIpIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICBpZiAodHlwZW9mIHByb3AgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIC8vIEF2b2lkIGludGVyZmVyaW5nIHdpdGggbG9nZ2luZyBjb25maWcgbG9va3VwcyBmb3Igb3B0aW9uYWwgZmllbGRzIGxpa2UgJ2FwcCdcbiAgICAgICAgICAgIGlmIChwcm9wID09PSBcImFwcFwiKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgcmV0dXJuIEVudmlyb25tZW50LmJ1aWxkRW52UHJveHkodW5kZWZpbmVkLCBbcHJvcF0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIEVudmlyb25tZW50Ll9pbnN0YW5jZSA9IHByb3hpZWQgYXMgYW55O1xuICAgIH1cbiAgICByZXR1cm4gRW52aXJvbm1lbnQuX2luc3RhbmNlIGFzIEU7XG4gIH1cblxuICAvKipcbiAgICogQHN0YXRpY1xuICAgKiBAZGVzY3JpcHRpb24gQWNjdW11bGF0ZXMgdGhlIGdpdmVuIHZhbHVlIGludG8gdGhlIGVudmlyb25tZW50LlxuICAgKiBAc3VtbWFyeSBBZGRzIG5ldyBwcm9wZXJ0aWVzIHRvIHRoZSBlbnZpcm9ubWVudCBmcm9tIHRoZSBwcm92aWRlZCBvYmplY3QuXG4gICAqIEB0ZW1wbGF0ZSBWXG4gICAqIEBwYXJhbSB7Vn0gdmFsdWUgLSBUaGUgb2JqZWN0IHRvIGFjY3VtdWxhdGUgaW50byB0aGUgZW52aXJvbm1lbnQuXG4gICAqIEByZXR1cm4ge1Z9IFRoZSB1cGRhdGVkIGVudmlyb25tZW50IGluc3RhbmNlLlxuICAgKi9cbiAgc3RhdGljIGFjY3VtdWxhdGU8ViBleHRlbmRzIG9iamVjdD4oXG4gICAgdmFsdWU6IFZcbiAgKTogdHlwZW9mIEVudmlyb25tZW50Ll9pbnN0YW5jZSAmXG4gICAgViAmXG4gICAgT2JqZWN0QWNjdW11bGF0b3I8dHlwZW9mIEVudmlyb25tZW50Ll9pbnN0YW5jZSAmIFY+IHtcbiAgICBjb25zdCBpbnN0YW5jZSA9IEVudmlyb25tZW50Lmluc3RhbmNlKCk7XG4gICAgT2JqZWN0LmtleXMoaW5zdGFuY2UgYXMgYW55KS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgIGNvbnN0IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGluc3RhbmNlIGFzIGFueSwga2V5KTtcbiAgICAgIGlmIChkZXNjICYmIGRlc2MuY29uZmlndXJhYmxlICYmIGRlc2MuZW51bWVyYWJsZSkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoaW5zdGFuY2UgYXMgYW55LCBrZXksIHtcbiAgICAgICAgICAuLi5kZXNjLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gaW5zdGFuY2UuYWNjdW11bGF0ZSh2YWx1ZSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0KGtleTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIEVudmlyb25tZW50Ll9pbnN0YW5jZS5nZXQoa2V5KTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGJ1aWxkRW52UHJveHkoY3VycmVudDogYW55LCBwYXRoOiBzdHJpbmdbXSk6IGFueSB7XG4gICAgY29uc3QgYnVpbGRLZXkgPSAocDogc3RyaW5nW10pID0+XG4gICAgICBwLm1hcCgoc2VnKSA9PiB0b0VOVkZvcm1hdChzZWcpKS5qb2luKEVOVl9QQVRIX0RFTElNSVRFUik7XG5cbiAgICAvLyBIZWxwZXIgdG8gcmVhZCBmcm9tIHRoZSBhY3RpdmUgZW52aXJvbm1lbnQgZ2l2ZW4gYSBjb21wb3NlZCBrZXlcbiAgICBjb25zdCByZWFkRW52ID0gKGtleTogc3RyaW5nKTogdW5rbm93biA9PiB7XG4gICAgICBpZiAoaXNCcm93c2VyKCkpIHtcbiAgICAgICAgY29uc3QgZW52ID0gKFxuICAgICAgICAgIGdsb2JhbFRoaXMgYXMgdHlwZW9mIGdsb2JhbFRoaXMgJiB7XG4gICAgICAgICAgICBbQnJvd3NlckVudktleV0/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgICB9XG4gICAgICAgIClbQnJvd3NlckVudktleV07XG4gICAgICAgIHJldHVybiBlbnYgPyBlbnZba2V5XSA6IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiAoZ2xvYmFsVGhpcyBhcyBhbnkpPy5wcm9jZXNzPy5lbnY/LltrZXldO1xuICAgIH07XG5cbiAgICBjb25zdCBoYW5kbGVyOiBQcm94eUhhbmRsZXI8YW55PiA9IHtcbiAgICAgIGdldChfdGFyZ2V0LCBwcm9wOiBzdHJpbmcgfCBzeW1ib2wpIHtcbiAgICAgICAgaWYgKHByb3AgPT09IFN5bWJvbC50b1ByaW1pdGl2ZSkge1xuICAgICAgICAgIHJldHVybiAoKSA9PiBidWlsZEtleShwYXRoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcCA9PT0gXCJ0b1N0cmluZ1wiKSB7XG4gICAgICAgICAgcmV0dXJuICgpID0+IGJ1aWxkS2V5KHBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wID09PSBcInZhbHVlT2ZcIikge1xuICAgICAgICAgIHJldHVybiAoKSA9PiBidWlsZEtleShwYXRoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHByb3AgPT09IFwic3ltYm9sXCIpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgICAgY29uc3QgbmV4dE1vZGVsID1cbiAgICAgICAgICBjdXJyZW50ICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChjdXJyZW50LCBwcm9wKVxuICAgICAgICAgICAgPyAoY3VycmVudCBhcyBhbnkpW3Byb3BdXG4gICAgICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3QgbmV4dFBhdGggPSBbLi4ucGF0aCwgcHJvcF07XG4gICAgICAgIGNvbnN0IGNvbXBvc2VkS2V5ID0gYnVpbGRLZXkobmV4dFBhdGgpO1xuXG4gICAgICAgIC8vIElmIGFuIEVOViB2YWx1ZSBleGlzdHMgZm9yIHRoaXMgcGF0aCwgcmV0dXJuIGl0IGRpcmVjdGx5XG4gICAgICAgIGNvbnN0IGVudlZhbHVlID0gcmVhZEVudihjb21wb3NlZEtleSk7XG4gICAgICAgIGlmICh0eXBlb2YgZW52VmFsdWUgIT09IFwidW5kZWZpbmVkXCIpIHJldHVybiBlbnZWYWx1ZTtcblxuICAgICAgICAvLyBPdGhlcndpc2UsIGlmIHRoZSBtb2RlbCBoYXMgYW4gb2JqZWN0IGF0IHRoaXMgcGF0aCwga2VlcCBkcmlsbGluZyB3aXRoIGEgcHJveHlcbiAgICAgICAgY29uc3QgaXNOZXh0T2JqZWN0ID0gbmV4dE1vZGVsICYmIHR5cGVvZiBuZXh0TW9kZWwgPT09IFwib2JqZWN0XCI7XG4gICAgICAgIGlmIChpc05leHRPYmplY3QpIHJldHVybiBFbnZpcm9ubWVudC5idWlsZEVudlByb3h5KG5leHRNb2RlbCwgbmV4dFBhdGgpO1xuXG4gICAgICAgIC8vIEFsd2F5cyByZXR1cm4gYSBwcm94eSBmb3IgZnVydGhlciBwYXRoIGNvbXBvc2l0aW9uIHdoZW4gbm8gRU5WIHZhbHVlO1xuICAgICAgICAvLyBkbyBub3Qgc3VyZmFjZSBwcmltaXRpdmUgbW9kZWwgZGVmYXVsdHMgaGVyZSAodGhpcyBBUEkgaXMgZm9yIGtleSBjb21wb3NpdGlvbikuXG4gICAgICAgIHJldHVybiBFbnZpcm9ubWVudC5idWlsZEVudlByb3h5KHVuZGVmaW5lZCwgbmV4dFBhdGgpO1xuICAgICAgfSxcbiAgICAgIG93bktleXMoKSB7XG4gICAgICAgIHJldHVybiBjdXJyZW50ID8gUmVmbGVjdC5vd25LZXlzKGN1cnJlbnQpIDogW107XG4gICAgICB9LFxuICAgICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF90LCBwKSB7XG4gICAgICAgIGlmICghY3VycmVudCkgcmV0dXJuIHVuZGVmaW5lZCBhcyBhbnk7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoY3VycmVudCwgcCkpIHtcbiAgICAgICAgICByZXR1cm4geyBlbnVtZXJhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSBhcyBQcm9wZXJ0eURlc2NyaXB0b3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZCBhcyBhbnk7XG4gICAgICB9LFxuICAgIH07XG5cbiAgICBjb25zdCB0YXJnZXQgPSB7fSBhcyBhbnk7XG4gICAgcmV0dXJuIG5ldyBQcm94eSh0YXJnZXQsIGhhbmRsZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdGF0aWNcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyB0aGUga2V5cyBvZiB0aGUgZW52aXJvbm1lbnQsIG9wdGlvbmFsbHkgY29udmVydGluZyB0aGVtIHRvIEVOViBmb3JtYXQuXG4gICAqIEBzdW1tYXJ5IEdldHMgYWxsIGtleXMgaW4gdGhlIGVudmlyb25tZW50LCB3aXRoIGFuIG9wdGlvbiB0byBmb3JtYXQgdGhlbSBmb3IgZW52aXJvbm1lbnQgdmFyaWFibGVzLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFt0b0Vudj10cnVlXSAtIFdoZXRoZXIgdG8gY29udmVydCB0aGUga2V5cyB0byBFTlYgZm9ybWF0LlxuICAgKiBAcmV0dXJuIHtzdHJpbmdbXX0gQW4gYXJyYXkgb2Yga2V5cyBmcm9tIHRoZSBlbnZpcm9ubWVudC5cbiAgICovXG4gIHN0YXRpYyBrZXlzKHRvRW52OiBib29sZWFuID0gdHJ1ZSk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gRW52aXJvbm1lbnQuaW5zdGFuY2UoKVxuICAgICAgLmtleXMoKVxuICAgICAgLm1hcCgoaykgPT4gKHRvRW52ID8gdG9FTlZGb3JtYXQoaykgOiBrKSk7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IExvZ2dlZEVudmlyb25tZW50ID0gRW52aXJvbm1lbnQuYWNjdW11bGF0ZShcbiAgT2JqZWN0LmFzc2lnbih7fSwgRGVmYXVsdExvZ2dpbmdDb25maWcsIHtcbiAgICBlbnY6XG4gICAgICAoaXNCcm93c2VyKCkgJiYgKGdsb2JhbFRoaXMgYXMgYW55KVtCcm93c2VyRW52S2V5XVxuICAgICAgICA/IChnbG9iYWxUaGlzIGFzIGFueSlbQnJvd3NlckVudktleV1bXCJOT0RFX0VOVlwiXVxuICAgICAgICA6IChnbG9iYWxUaGlzIGFzIGFueSkucHJvY2Vzcy5lbnZbXCJOT0RFX0VOVlwiXSkgfHwgXCJkZXZlbG9wbWVudFwiLFxuICB9KVxuKTtcbiIsImltcG9ydCB7XG4gIExvZ2dlckZhY3RvcnksXG4gIExvZ2dpbmdDb25maWcsXG4gIExvZ2dpbmdDb250ZXh0LFxuICBTdHJpbmdMaWtlLFxuICBUaGVtZSxcbiAgVGhlbWVPcHRpb24sXG4gIFRoZW1lT3B0aW9uQnlMb2dMZXZlbCxcbiAgTG9nZ2VyLFxufSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgQ29sb3JpemVPcHRpb25zLCBzdHlsZSwgU3R5bGVkU3RyaW5nIH0gZnJvbSBcInN0eWxlZC1zdHJpbmctYnVpbGRlclwiO1xuaW1wb3J0IHsgRGVmYXVsdFRoZW1lLCBMb2dMZXZlbCwgTnVtZXJpY0xvZ0xldmVscyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgc2YgfSBmcm9tIFwiLi90ZXh0XCI7XG5pbXBvcnQgeyBMb2dnZWRFbnZpcm9ubWVudCB9IGZyb20gXCIuL2Vudmlyb25tZW50XCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgbWluaW1hbCBsb2dnZXIgaW1wbGVtZW50YXRpb24uXG4gKiBAc3VtbWFyeSBNaW5pTG9nZ2VyIGlzIGEgbGlnaHR3ZWlnaHQgbG9nZ2luZyBjbGFzcyB0aGF0IGltcGxlbWVudHMgdGhlIExvZ2dlciBpbnRlcmZhY2UuXG4gKiBJdCBwcm92aWRlcyBiYXNpYyBsb2dnaW5nIGZ1bmN0aW9uYWxpdHkgd2l0aCBzdXBwb3J0IGZvciBkaWZmZXJlbnQgbG9nIGxldmVscywgdmVyYm9zaXR5LFxuICogY29udGV4dC1hd2FyZSBsb2dnaW5nLCBhbmQgY3VzdG9taXphYmxlIGZvcm1hdHRpbmcuXG4gKiBAcGFyYW0ge3N0cmluZ30gY29udGV4dCAtIFRoZSBjb250ZXh0ICh0eXBpY2FsbHkgY2xhc3MgbmFtZSkgdGhpcyBsb2dnZXIgaXMgYXNzb2NpYXRlZCB3aXRoXG4gKiBAcGFyYW0ge1BhcnRpYWw8TG9nZ2luZ0NvbmZpZz59IGNvbmYgLSBPcHRpb25hbCBjb25maWd1cmF0aW9uIHRvIG92ZXJyaWRlIGdsb2JhbCBzZXR0aW5nc1xuICogQGNsYXNzIE1pbmlMb2dnZXJcbiAqIEBleGFtcGxlXG4gKiAvLyBDcmVhdGUgYSBuZXcgbG9nZ2VyIGZvciBhIGNsYXNzXG4gKiBjb25zdCBsb2dnZXIgPSBuZXcgTWluaUxvZ2dlcignTXlDbGFzcycpO1xuICpcbiAqIC8vIExvZyBtZXNzYWdlcyBhdCBkaWZmZXJlbnQgbGV2ZWxzXG4gKiBsb2dnZXIuaW5mbygnVGhpcyBpcyBhbiBpbmZvIG1lc3NhZ2UnKTtcbiAqIGxvZ2dlci5kZWJ1ZygnVGhpcyBpcyBhIGRlYnVnIG1lc3NhZ2UnKTtcbiAqIGxvZ2dlci5lcnJvcignU29tZXRoaW5nIHdlbnQgd3JvbmcnKTtcbiAqXG4gKiAvLyBDcmVhdGUgYSBjaGlsZCBsb2dnZXIgZm9yIGEgc3BlY2lmaWMgbWV0aG9kXG4gKiBjb25zdCBtZXRob2RMb2dnZXIgPSBsb2dnZXIuZm9yKCdteU1ldGhvZCcpO1xuICogbWV0aG9kTG9nZ2VyLnZlcmJvc2UoJ0RldGFpbGVkIGluZm9ybWF0aW9uJywgMik7XG4gKlxuICogLy8gTG9nIHdpdGggY3VzdG9tIGNvbmZpZ3VyYXRpb25cbiAqIGxvZ2dlci5mb3IoJ3NwZWNpYWxNZXRob2QnLCB7IHN0eWxlOiB0cnVlIH0pLmluZm8oJ1N0eWxlZCBtZXNzYWdlJyk7XG4gKi9cbmV4cG9ydCBjbGFzcyBNaW5pTG9nZ2VyIGltcGxlbWVudHMgTG9nZ2VyIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIGNvbnRleHQ6IHN0cmluZyxcbiAgICBwcm90ZWN0ZWQgY29uZj86IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz5cbiAgKSB7fVxuXG4gIHByb3RlY3RlZCBjb25maWcoXG4gICAga2V5OiBrZXlvZiBMb2dnaW5nQ29uZmlnXG4gICk6IExvZ2dpbmdDb25maWdba2V5b2YgTG9nZ2luZ0NvbmZpZ10ge1xuICAgIGlmICh0aGlzLmNvbmYgJiYga2V5IGluIHRoaXMuY29uZikgcmV0dXJuIHRoaXMuY29uZltrZXldO1xuICAgIHJldHVybiBMb2dnaW5nLmdldENvbmZpZygpW2tleV07XG4gIH1cblxuICBmb3IobWV0aG9kOiBzdHJpbmcgfCAoKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnkpKTogTG9nZ2VyO1xuICBmb3IoY29uZmlnOiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+KTogTG9nZ2VyO1xuICBmb3IoXG4gICAgbWV0aG9kOiBzdHJpbmcgfCAoKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnkpIHwgUGFydGlhbDxMb2dnaW5nQ29uZmlnPixcbiAgICBjb25maWc6IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogTG9nZ2VyO1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBjaGlsZCBsb2dnZXIgZm9yIGEgc3BlY2lmaWMgbWV0aG9kIG9yIGNvbnRleHRcbiAgICogQHN1bW1hcnkgUmV0dXJucyBhIG5ldyBsb2dnZXIgaW5zdGFuY2Ugd2l0aCB0aGUgY3VycmVudCBjb250ZXh0IGV4dGVuZGVkIGJ5IHRoZSBzcGVjaWZpZWQgbWV0aG9kIG5hbWVcbiAgICogQHBhcmFtIHtzdHJpbmcgfCBGdW5jdGlvbn0gbWV0aG9kIC0gVGhlIG1ldGhvZCBuYW1lIG9yIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIGxvZ2dlciBmb3JcbiAgICogQHBhcmFtIHtQYXJ0aWFsPExvZ2dpbmdDb25maWc+fSBjb25maWcgLSBPcHRpb25hbCBjb25maWd1cmF0aW9uIHRvIG92ZXJyaWRlIHNldHRpbmdzXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBsb2dnZXIgZmFjdG9yeVxuICAgKiBAcmV0dXJuIHtMb2dnZXJ9IEEgbmV3IGxvZ2dlciBpbnN0YW5jZSBmb3IgdGhlIHNwZWNpZmllZCBtZXRob2RcbiAgICovXG4gIGZvcihcbiAgICBtZXRob2Q/OiBzdHJpbmcgfCAoKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnkpIHwgUGFydGlhbDxMb2dnaW5nQ29uZmlnPixcbiAgICBjb25maWc/OiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+LFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBMb2dnZXIge1xuICAgIGlmICghY29uZmlnICYmIHR5cGVvZiBtZXRob2QgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIGNvbmZpZyA9IG1ldGhvZDtcbiAgICAgIG1ldGhvZCA9IHVuZGVmaW5lZDtcbiAgICB9IGVsc2Uge1xuICAgICAgbWV0aG9kID0gbWV0aG9kXG4gICAgICAgID8gdHlwZW9mIG1ldGhvZCA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgID8gbWV0aG9kXG4gICAgICAgICAgOiAobWV0aG9kIGFzIGFueSkubmFtZVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb3h5KHRoaXMsIHtcbiAgICAgIGdldDogKHRhcmdldDogdHlwZW9mIHRoaXMsIHA6IHN0cmluZyB8IHN5bWJvbCwgcmVjZWl2ZXI6IGFueSkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBSZWZsZWN0LmdldCh0YXJnZXQsIHAsIHJlY2VpdmVyKTtcbiAgICAgICAgaWYgKHAgPT09IFwiY29uZmlnXCIpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFByb3h5KHRoaXMuY29uZmlnLCB7XG4gICAgICAgICAgICBnZXQ6ICh0YXJnZXQ6IHR5cGVvZiB0aGlzLmNvbmZpZywgcDogc3RyaW5nIHwgc3ltYm9sKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChjb25maWcgJiYgcCBpbiBjb25maWcpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbmZpZ1twIGFzIGtleW9mIExvZ2dpbmdDb25maWddO1xuICAgICAgICAgICAgICByZXR1cm4gUmVmbGVjdC5nZXQodGFyZ2V0LCBwLCByZWNlaXZlcik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwID09PSBcImNvbnRleHRcIiAmJiBtZXRob2QpIHtcbiAgICAgICAgICByZXR1cm4gW3Jlc3VsdCwgbWV0aG9kXS5qb2luKFwiLlwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGZvcm1hdHRlZCBsb2cgc3RyaW5nXG4gICAqIEBzdW1tYXJ5IEdlbmVyYXRlcyBhIGxvZyBzdHJpbmcgd2l0aCB0aW1lc3RhbXAsIGNvbG9yZWQgbG9nIGxldmVsLCBjb250ZXh0LCBhbmQgbWVzc2FnZVxuICAgKiBAcGFyYW0ge0xvZ0xldmVsfSBsZXZlbCAtIFRoZSBsb2cgbGV2ZWwgZm9yIHRoaXMgbWVzc2FnZVxuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2UgfCBFcnJvcn0gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGxvZyBvciBhbiBFcnJvciBvYmplY3RcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtlcnJvcl0gLSBPcHRpb25hbCBlcnJvciB0byBleHRyYWN0IHN0YWNrIHRyYWNlIHRvIGluY2x1ZGUgaW4gdGhlIGxvZ1xuICAgKiBAcmV0dXJuIHtzdHJpbmd9IEEgZm9ybWF0dGVkIGxvZyBzdHJpbmcgd2l0aCBhbGwgY29tcG9uZW50c1xuICAgKi9cbiAgcHJvdGVjdGVkIGNyZWF0ZUxvZyhcbiAgICBsZXZlbDogTG9nTGV2ZWwsXG4gICAgbWVzc2FnZTogU3RyaW5nTGlrZSB8IEVycm9yLFxuICAgIGVycm9yPzogRXJyb3JcbiAgKTogc3RyaW5nIHtcbiAgICBjb25zdCBsb2c6IFJlY29yZDxcbiAgICAgIHwgXCJ0aW1lc3RhbXBcIlxuICAgICAgfCBcImxldmVsXCJcbiAgICAgIHwgXCJjb250ZXh0XCJcbiAgICAgIHwgXCJjb3JyZWxhdGlvbklkXCJcbiAgICAgIHwgXCJtZXNzYWdlXCJcbiAgICAgIHwgXCJzZXBhcmF0b3JcIlxuICAgICAgfCBcInN0YWNrXCJcbiAgICAgIHwgXCJhcHBcIixcbiAgICAgIHN0cmluZ1xuICAgID4gPSB7fSBhcyBhbnk7XG4gICAgY29uc3Qgc3R5bGUgPSB0aGlzLmNvbmZpZyhcInN0eWxlXCIpO1xuICAgIGNvbnN0IHNlcGFyYXRvciA9IHRoaXMuY29uZmlnKFwic2VwYXJhdG9yXCIpO1xuICAgIGNvbnN0IGFwcCA9IHRoaXMuY29uZmlnKFwiYXBwXCIpO1xuICAgIGlmIChhcHApXG4gICAgICBsb2cuYXBwID0gc3R5bGVcbiAgICAgICAgPyBMb2dnaW5nLnRoZW1lKGFwcCBhcyBzdHJpbmcsIFwiYXBwXCIsIGxldmVsKVxuICAgICAgICA6IChhcHAgYXMgc3RyaW5nKTtcblxuICAgIGlmIChzZXBhcmF0b3IpXG4gICAgICBsb2cuc2VwYXJhdG9yID0gc3R5bGVcbiAgICAgICAgPyBMb2dnaW5nLnRoZW1lKHNlcGFyYXRvciBhcyBzdHJpbmcsIFwic2VwYXJhdG9yXCIsIGxldmVsKVxuICAgICAgICA6IChzZXBhcmF0b3IgYXMgc3RyaW5nKTtcblxuICAgIGlmICh0aGlzLmNvbmZpZyhcInRpbWVzdGFtcFwiKSkge1xuICAgICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcbiAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IHN0eWxlID8gTG9nZ2luZy50aGVtZShkYXRlLCBcInRpbWVzdGFtcFwiLCBsZXZlbCkgOiBkYXRlO1xuICAgICAgbG9nLnRpbWVzdGFtcCA9IHRpbWVzdGFtcDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWcoXCJsb2dMZXZlbFwiKSkge1xuICAgICAgY29uc3QgbHZsOiBzdHJpbmcgPSBzdHlsZVxuICAgICAgICA/IExvZ2dpbmcudGhlbWUobGV2ZWwsIFwibG9nTGV2ZWxcIiwgbGV2ZWwpXG4gICAgICAgIDogbGV2ZWw7XG4gICAgICBsb2cubGV2ZWwgPSBsdmwudG9VcHBlckNhc2UoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWcoXCJjb250ZXh0XCIpKSB7XG4gICAgICBjb25zdCBjb250ZXh0OiBzdHJpbmcgPSBzdHlsZVxuICAgICAgICA/IExvZ2dpbmcudGhlbWUodGhpcy5jb250ZXh0LCBcImNsYXNzXCIsIGxldmVsKVxuICAgICAgICA6IHRoaXMuY29udGV4dDtcbiAgICAgIGxvZy5jb250ZXh0ID0gY29udGV4dDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWcoXCJjb3JyZWxhdGlvbklkXCIpKSB7XG4gICAgICB7XG4gICAgICAgIGNvbnN0IGlkOiBzdHJpbmcgPSBzdHlsZVxuICAgICAgICAgID8gTG9nZ2luZy50aGVtZSh0aGlzLmNvbmZpZyhcImNvcnJlbGF0aW9uSWRcIikhLnRvU3RyaW5nKCksIFwiaWRcIiwgbGV2ZWwpXG4gICAgICAgICAgOiB0aGlzLmNvbmZpZyhcImNvcnJlbGF0aW9uSWRcIikhLnRvU3RyaW5nKCk7XG4gICAgICAgIGxvZy5jb3JyZWxhdGlvbklkID0gaWQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgbXNnOiBzdHJpbmcgPSBzdHlsZVxuICAgICAgPyBMb2dnaW5nLnRoZW1lKFxuICAgICAgICAgIHR5cGVvZiBtZXNzYWdlID09PSBcInN0cmluZ1wiID8gbWVzc2FnZSA6IChtZXNzYWdlIGFzIEVycm9yKS5tZXNzYWdlLFxuICAgICAgICAgIFwibWVzc2FnZVwiLFxuICAgICAgICAgIGxldmVsXG4gICAgICAgIClcbiAgICAgIDogdHlwZW9mIG1lc3NhZ2UgPT09IFwic3RyaW5nXCJcbiAgICAgICAgPyBtZXNzYWdlXG4gICAgICAgIDogKG1lc3NhZ2UgYXMgRXJyb3IpLm1lc3NhZ2U7XG4gICAgbG9nLm1lc3NhZ2UgPSBtc2c7XG4gICAgaWYgKGVycm9yIHx8IG1lc3NhZ2UgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgY29uc3Qgc3RhY2sgPSBzdHlsZVxuICAgICAgICA/IExvZ2dpbmcudGhlbWUoXG4gICAgICAgICAgICAoZXJyb3I/LnN0YWNrIHx8IChtZXNzYWdlIGFzIEVycm9yKS5zdGFjaykgYXMgc3RyaW5nLFxuICAgICAgICAgICAgXCJzdGFja1wiLFxuICAgICAgICAgICAgbGV2ZWxcbiAgICAgICAgICApXG4gICAgICAgIDogZXJyb3I/LnN0YWNrIHx8IFwiXCI7XG4gICAgICBsb2cuc3RhY2sgPSBgIHwgJHsoZXJyb3IgfHwgKG1lc3NhZ2UgYXMgRXJyb3IpKS5tZXNzYWdlfSAtIFN0YWNrIHRyYWNlOlxcbiR7c3RhY2t9YDtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHRoaXMuY29uZmlnKFwiZm9ybWF0XCIpKSB7XG4gICAgICBjYXNlIFwianNvblwiOlxuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkobG9nKTtcbiAgICAgIGNhc2UgXCJyYXdcIjpcbiAgICAgICAgcmV0dXJuICh0aGlzLmNvbmZpZyhcInBhdHRlcm5cIikgYXMgc3RyaW5nKVxuICAgICAgICAgIC5zcGxpdChcIiBcIilcbiAgICAgICAgICAubWFwKChzKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXMubWF0Y2goL1xcey4qP30vZykpIHJldHVybiBzO1xuICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVkUyA9IHNmKHMsIGxvZyk7XG4gICAgICAgICAgICBpZiAoZm9ybWF0dGVkUyAhPT0gcykgcmV0dXJuIGZvcm1hdHRlZFM7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLmZpbHRlcigocykgPT4gcylcbiAgICAgICAgICAuam9pbihcIiBcIik7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGxvZ2dpbmcgZm9ybWF0OiAke3RoaXMuY29uZmlnKFwiZm9ybWF0XCIpfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGxvZyBsZXZlbFxuICAgKiBAc3VtbWFyeSBDaGVja3MgaWYgdGhlIG1lc3NhZ2Ugc2hvdWxkIGJlIGxvZ2dlZCBiYXNlZCBvbiB0aGUgY3VycmVudCBsb2cgbGV2ZWwsXG4gICAqIHRoZW4gdXNlcyB0aGUgYXBwcm9wcmlhdGUgY29uc29sZSBtZXRob2QgdG8gb3V0cHV0IHRoZSBmb3JtYXR0ZWQgbG9nXG4gICAqIEBwYXJhbSB7TG9nTGV2ZWx9IGxldmVsIC0gVGhlIGxvZyBsZXZlbCBvZiB0aGUgbWVzc2FnZVxuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2UgfCBFcnJvcn0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkIG9yIGFuIEVycm9yIG9iamVjdFxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2Vycm9yXSAtIE9wdGlvbmFsIHN0YWNrIHRyYWNlIHRvIGluY2x1ZGUgaW4gdGhlIGxvZ1xuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgcHJvdGVjdGVkIGxvZyhsZXZlbDogTG9nTGV2ZWwsIG1zZzogU3RyaW5nTGlrZSB8IEVycm9yLCBlcnJvcj86IEVycm9yKTogdm9pZCB7XG4gICAgY29uc3QgY29uZkx2bCA9IHRoaXMuY29uZmlnKFwibGV2ZWxcIikgYXMgTG9nTGV2ZWw7XG4gICAgaWYgKE51bWVyaWNMb2dMZXZlbHNbY29uZkx2bF0gPCBOdW1lcmljTG9nTGV2ZWxzW2xldmVsXSkgcmV0dXJuO1xuICAgIGxldCBtZXRob2Q7XG4gICAgc3dpdGNoIChsZXZlbCkge1xuICAgICAgY2FzZSBMb2dMZXZlbC5pbmZvOlxuICAgICAgICBtZXRob2QgPSBjb25zb2xlLmxvZztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIExvZ0xldmVsLnZlcmJvc2U6XG4gICAgICBjYXNlIExvZ0xldmVsLmRlYnVnOlxuICAgICAgICBtZXRob2QgPSBjb25zb2xlLmRlYnVnO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTG9nTGV2ZWwuZXJyb3I6XG4gICAgICAgIG1ldGhvZCA9IGNvbnNvbGUuZXJyb3I7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBsb2cgbGV2ZWxcIik7XG4gICAgfVxuICAgIG1ldGhvZCh0aGlzLmNyZWF0ZUxvZyhsZXZlbCwgbXNnLCBlcnJvcikpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgc2lsbHkgbGV2ZWxcbiAgICogQHN1bW1hcnkgTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIHNpbGx5IGxldmVsIGlmIHRoZSBjdXJyZW50IHZlcmJvc2l0eSBzZXR0aW5nIGFsbG93cyBpdFxuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2V9IG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZFxuICAgKiBAcGFyYW0ge251bWJlcn0gW3ZlcmJvc2l0eT0wXSAtIFRoZSB2ZXJib3NpdHkgbGV2ZWwgb2YgdGhlIG1lc3NhZ2VcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHNpbGx5KG1zZzogU3RyaW5nTGlrZSwgdmVyYm9zaXR5OiBudW1iZXIgPSAwKTogdm9pZCB7XG4gICAgaWYgKCh0aGlzLmNvbmZpZyhcInZlcmJvc2VcIikgYXMgbnVtYmVyKSA+PSB2ZXJib3NpdHkpXG4gICAgICB0aGlzLmxvZyhMb2dMZXZlbC52ZXJib3NlLCBtc2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgdmVyYm9zZSBsZXZlbFxuICAgKiBAc3VtbWFyeSBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgdmVyYm9zZSBsZXZlbCBpZiB0aGUgY3VycmVudCB2ZXJib3NpdHkgc2V0dGluZyBhbGxvd3MgaXRcbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWRcbiAgICogQHBhcmFtIHtudW1iZXJ9IFt2ZXJib3NpdHk9MF0gLSBUaGUgdmVyYm9zaXR5IGxldmVsIG9mIHRoZSBtZXNzYWdlXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICB2ZXJib3NlKG1zZzogU3RyaW5nTGlrZSwgdmVyYm9zaXR5OiBudW1iZXIgPSAwKTogdm9pZCB7XG4gICAgaWYgKCh0aGlzLmNvbmZpZyhcInZlcmJvc2VcIikgYXMgbnVtYmVyKSA+PSB2ZXJib3NpdHkpXG4gICAgICB0aGlzLmxvZyhMb2dMZXZlbC52ZXJib3NlLCBtc2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgaW5mbyBsZXZlbFxuICAgKiBAc3VtbWFyeSBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgaW5mbyBsZXZlbCBmb3IgZ2VuZXJhbCBhcHBsaWNhdGlvbiBpbmZvcm1hdGlvblxuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2V9IG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZFxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgaW5mbyhtc2c6IFN0cmluZ0xpa2UpOiB2b2lkIHtcbiAgICB0aGlzLmxvZyhMb2dMZXZlbC5pbmZvLCBtc2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgZGVidWcgbGV2ZWxcbiAgICogQHN1bW1hcnkgTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGRlYnVnIGxldmVsIGZvciBkZXRhaWxlZCB0cm91Ymxlc2hvb3RpbmcgaW5mb3JtYXRpb25cbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWRcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIGRlYnVnKG1zZzogU3RyaW5nTGlrZSk6IHZvaWQge1xuICAgIHRoaXMubG9nKExvZ0xldmVsLmRlYnVnLCBtc2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgZXJyb3IgbGV2ZWxcbiAgICogQHN1bW1hcnkgTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGVycm9yIGxldmVsIGZvciBlcnJvcnMgYW5kIGV4Y2VwdGlvbnNcbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlIHwgRXJyb3J9IG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZCBvciBhbiBFcnJvciBvYmplY3RcbiAgICogQHBhcmFtIGVcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIGVycm9yKG1zZzogU3RyaW5nTGlrZSB8IEVycm9yLCBlPzogRXJyb3IpOiB2b2lkIHtcbiAgICB0aGlzLmxvZyhMb2dMZXZlbC5lcnJvciwgbXNnLCBlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVXBkYXRlcyB0aGUgbG9nZ2VyIGNvbmZpZ3VyYXRpb25cbiAgICogQHN1bW1hcnkgTWVyZ2VzIHRoZSBwcm92aWRlZCBjb25maWd1cmF0aW9uIHdpdGggdGhlIGV4aXN0aW5nIGNvbmZpZ3VyYXRpb25cbiAgICogQHBhcmFtIHtQYXJ0aWFsPExvZ2dpbmdDb25maWc+fSBjb25maWcgLSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIGFwcGx5XG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzZXRDb25maWcoY29uZmlnOiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+KTogdm9pZCB7XG4gICAgdGhpcy5jb25mID0geyAuLi4odGhpcy5jb25mIHx8IHt9KSwgLi4uY29uZmlnIH07XG4gIH1cbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQSBzdGF0aWMgY2xhc3MgZm9yIG1hbmFnaW5nIGxvZ2dpbmcgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgVGhlIExvZ2dpbmcgY2xhc3MgcHJvdmlkZXMgYSBjZW50cmFsaXplZCBsb2dnaW5nIG1lY2hhbmlzbSB3aXRoIHN1cHBvcnQgZm9yXG4gKiBkaWZmZXJlbnQgbG9nIGxldmVscywgdmVyYm9zaXR5LCBhbmQgc3R5bGluZy4gSXQgdXNlcyBhIHNpbmdsZXRvbiBwYXR0ZXJuIHRvIG1haW50YWluIGEgZ2xvYmFsXG4gKiBsb2dnZXIgaW5zdGFuY2UgYW5kIGFsbG93cyBjcmVhdGluZyBzcGVjaWZpYyBsb2dnZXJzIGZvciBkaWZmZXJlbnQgY2xhc3NlcyBhbmQgbWV0aG9kcy5cbiAqIEBjbGFzcyBMb2dnaW5nXG4gKiBAZXhhbXBsZVxuICogLy8gU2V0IGdsb2JhbCBjb25maWd1cmF0aW9uXG4gKiBMb2dnaW5nLnNldENvbmZpZyh7IGxldmVsOiBMb2dMZXZlbC5kZWJ1Zywgc3R5bGU6IHRydWUgfSk7XG4gKlxuICogLy8gR2V0IGEgbG9nZ2VyIGZvciBhIHNwZWNpZmljIGNsYXNzXG4gKiBjb25zdCBsb2dnZXIgPSBMb2dnaW5nLmZvcignTXlDbGFzcycpO1xuICpcbiAqIC8vIExvZyBtZXNzYWdlcyBhdCBkaWZmZXJlbnQgbGV2ZWxzXG4gKiBsb2dnZXIuaW5mbygnQXBwbGljYXRpb24gc3RhcnRlZCcpO1xuICogbG9nZ2VyLmRlYnVnKCdQcm9jZXNzaW5nIGRhdGEuLi4nKTtcbiAqXG4gKiAvLyBMb2cgd2l0aCBjb250ZXh0XG4gKiBjb25zdCBtZXRob2RMb2dnZXIgPSBMb2dnaW5nLmZvcignTXlDbGFzcy5teU1ldGhvZCcpO1xuICogbWV0aG9kTG9nZ2VyLnZlcmJvc2UoJ0RldGFpbGVkIG9wZXJhdGlvbiBpbmZvcm1hdGlvbicsIDEpO1xuICpcbiAqIC8vIExvZyBlcnJvcnNcbiAqIHRyeSB7XG4gKiAgIC8vIHNvbWUgb3BlcmF0aW9uXG4gKiB9IGNhdGNoIChlcnJvcikge1xuICogICBsb2dnZXIuZXJyb3IoZXJyb3IpO1xuICogfVxuICogQG1lcm1haWRcbiAqIGNsYXNzRGlhZ3JhbVxuICogICBjbGFzcyBMb2dnZXIge1xuICogICAgIDw8aW50ZXJmYWNlPj5cbiAqICAgICArZm9yKG1ldGhvZCwgY29uZmlnLCAuLi5hcmdzKVxuICogICAgICtzaWxseShtc2csIHZlcmJvc2l0eSlcbiAqICAgICArdmVyYm9zZShtc2csIHZlcmJvc2l0eSlcbiAqICAgICAraW5mbyhtc2cpXG4gKiAgICAgK2RlYnVnKG1zZylcbiAqICAgICArZXJyb3IobXNnKVxuICogICAgICtzZXRDb25maWcoY29uZmlnKVxuICogICB9XG4gKlxuICogICBjbGFzcyBMb2dnaW5nIHtcbiAqICAgICAtZ2xvYmFsOiBMb2dnZXJcbiAqICAgICAtX2ZhY3Rvcnk6IExvZ2dlckZhY3RvcnlcbiAqICAgICAtX2NvbmZpZzogTG9nZ2luZ0NvbmZpZ1xuICogICAgICtzZXRGYWN0b3J5KGZhY3RvcnkpXG4gKiAgICAgK3NldENvbmZpZyhjb25maWcpXG4gKiAgICAgK2dldENvbmZpZygpXG4gKiAgICAgK2dldCgpXG4gKiAgICAgK3ZlcmJvc2UobXNnLCB2ZXJib3NpdHkpXG4gKiAgICAgK2luZm8obXNnKVxuICogICAgICtkZWJ1Zyhtc2cpXG4gKiAgICAgK3NpbGx5KG1zZylcbiAqICAgICArZXJyb3IobXNnKVxuICogICAgICtmb3Iob2JqZWN0LCBjb25maWcsIC4uLmFyZ3MpXG4gKiAgICAgK2JlY2F1c2UocmVhc29uLCBpZClcbiAqICAgICArdGhlbWUodGV4dCwgdHlwZSwgbG9nZ2VyTGV2ZWwsIHRlbXBsYXRlKVxuICogICB9XG4gKlxuICogICBjbGFzcyBNaW5pTG9nZ2VyIHtcbiAqICAgICArY29uc3RydWN0b3IoY29udGV4dCwgY29uZj8pXG4gKiAgIH1cbiAqXG4gKiAgIExvZ2dpbmcgLi4+IExvZ2dlciA6IGNyZWF0ZXNcbiAqICAgTG9nZ2luZyAuLj4gTWluaUxvZ2dlciA6IGNyZWF0ZXMgYnkgZGVmYXVsdFxuICovXG5leHBvcnQgY2xhc3MgTG9nZ2luZyB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2VcbiAgICogQHN1bW1hcnkgQSBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgTG9nZ2VyIHVzZWQgZm9yIGdsb2JhbCBsb2dnaW5nXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBnbG9iYWw/OiBMb2dnZXI7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBGYWN0b3J5IGZ1bmN0aW9uIGZvciBjcmVhdGluZyBsb2dnZXIgaW5zdGFuY2VzXG4gICAqIEBzdW1tYXJ5IEEgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIG5ldyBMb2dnZXIgaW5zdGFuY2VzLiBCeSBkZWZhdWx0LCBpdCBjcmVhdGVzIGEgTWluaUxvZ2dlci5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIF9mYWN0b3J5OiBMb2dnZXJGYWN0b3J5ID0gKFxuICAgIG9iamVjdDogc3RyaW5nLFxuICAgIGNvbmZpZz86IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz5cbiAgKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBNaW5pTG9nZ2VyKG9iamVjdCwgY29uZmlnKTtcbiAgfTtcblxuICBwcml2YXRlIHN0YXRpYyBfY29uZmlnOiB0eXBlb2YgTG9nZ2VkRW52aXJvbm1lbnQgPSBMb2dnZWRFbnZpcm9ubWVudDtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIGZhY3RvcnkgZnVuY3Rpb24gZm9yIGNyZWF0aW5nIGxvZ2dlciBpbnN0YW5jZXNcbiAgICogQHN1bW1hcnkgQWxsb3dzIGN1c3RvbWl6aW5nIGhvdyBsb2dnZXIgaW5zdGFuY2VzIGFyZSBjcmVhdGVkXG4gICAqIEBwYXJhbSB7TG9nZ2VyRmFjdG9yeX0gZmFjdG9yeSAtIFRoZSBmYWN0b3J5IGZ1bmN0aW9uIHRvIHVzZSBmb3IgY3JlYXRpbmcgbG9nZ2Vyc1xuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc3RhdGljIHNldEZhY3RvcnkoZmFjdG9yeTogTG9nZ2VyRmFjdG9yeSkge1xuICAgIExvZ2dpbmcuX2ZhY3RvcnkgPSBmYWN0b3J5O1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBVcGRhdGVzIHRoZSBnbG9iYWwgbG9nZ2luZyBjb25maWd1cmF0aW9uXG4gICAqIEBzdW1tYXJ5IEFsbG93cyB1cGRhdGluZyB0aGUgZ2xvYmFsIGxvZ2dpbmcgY29uZmlndXJhdGlvbiB3aXRoIG5ldyBzZXR0aW5nc1xuICAgKiBAcGFyYW0ge1BhcnRpYWw8TG9nZ2luZ0NvbmZpZz59IGNvbmZpZyAtIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gYXBwbHlcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHN0YXRpYyBzZXRDb25maWcoY29uZmlnOiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+KTogdm9pZCB7XG4gICAgT2JqZWN0LmVudHJpZXMoY29uZmlnKS5mb3JFYWNoKChbaywgdl0pID0+IHtcbiAgICAgICh0aGlzLl9jb25maWcgYXMgYW55KVtrXSA9IHYgYXMgYW55O1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIGEgY29weSBvZiB0aGUgY3VycmVudCBnbG9iYWwgbG9nZ2luZyBjb25maWd1cmF0aW9uXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgYSBjb3B5IG9mIHRoZSBjdXJyZW50IGdsb2JhbCBsb2dnaW5nIGNvbmZpZ3VyYXRpb25cbiAgICogQHJldHVybiB7TG9nZ2luZ0NvbmZpZ30gQSBjb3B5IG9mIHRoZSBjdXJyZW50IGNvbmZpZ3VyYXRpb25cbiAgICovXG4gIHN0YXRpYyBnZXRDb25maWcoKTogdHlwZW9mIExvZ2dlZEVudmlyb25tZW50IHtcbiAgICByZXR1cm4gdGhpcy5fY29uZmlnO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgb3IgY3JlYXRlcyB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICogQHN1bW1hcnkgUmV0dXJucyB0aGUgZXhpc3RpbmcgZ2xvYmFsIGxvZ2dlciBvciBjcmVhdGVzIGEgbmV3IG9uZSBpZiBpdCBkb2Vzbid0IGV4aXN0LlxuICAgKlxuICAgKiBAcmV0dXJuIFRoZSBnbG9iYWwgVmVyYm9zaXR5TG9nZ2VyIGluc3RhbmNlLlxuICAgKi9cbiAgc3RhdGljIGdldCgpOiBMb2dnZXIge1xuICAgIHRoaXMuZ2xvYmFsID0gdGhpcy5nbG9iYWwgPyB0aGlzLmdsb2JhbCA6IHRoaXMuX2ZhY3RvcnkoXCJMb2dnaW5nXCIpO1xuICAgIHJldHVybiB0aGlzLmdsb2JhbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIHZlcmJvc2UgbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRoZSB2ZXJib3NlIGxvZ2dpbmcgdG8gdGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuXG4gICAqIEBwYXJhbSB2ZXJib3NpdHkgLSBUaGUgdmVyYm9zaXR5IGxldmVsIG9mIHRoZSBtZXNzYWdlIChkZWZhdWx0OiAwKS5cbiAgICovXG4gIHN0YXRpYyB2ZXJib3NlKG1zZzogU3RyaW5nTGlrZSwgdmVyYm9zaXR5OiBudW1iZXIgPSAwKTogdm9pZCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkudmVyYm9zZShtc2csIHZlcmJvc2l0eSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYW4gaW5mbyBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdGhlIGluZm8gbG9nZ2luZyB0byB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC5cbiAgICovXG4gIHN0YXRpYyBpbmZvKG1zZzogU3RyaW5nTGlrZSk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmdldCgpLmluZm8obXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIGRlYnVnIG1lc3NhZ2UuXG4gICAqIEBzdW1tYXJ5IERlbGVnYXRlcyB0aGUgZGVidWcgbG9nZ2luZyB0byB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC5cbiAgICovXG4gIHN0YXRpYyBkZWJ1Zyhtc2c6IFN0cmluZ0xpa2UpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5kZWJ1Zyhtc2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGEgc2lsbHkgbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRoZSBkZWJ1ZyBsb2dnaW5nIHRvIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLlxuICAgKi9cbiAgc3RhdGljIHNpbGx5KG1zZzogU3RyaW5nTGlrZSk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmdldCgpLnNpbGx5KG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYW4gZXJyb3IgbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRoZSBlcnJvciBsb2dnaW5nIHRvIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLlxuICAgKiBAcGFyYW0gZVxuICAgKi9cbiAgc3RhdGljIGVycm9yKG1zZzogU3RyaW5nTGlrZSwgZT86IEVycm9yKTogdm9pZCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkuZXJyb3IobXNnLCBlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGxvZ2dlciBmb3IgYSBzcGVjaWZpYyBvYmplY3Qgb3IgY29udGV4dFxuICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgbmV3IGxvZ2dlciBpbnN0YW5jZSBmb3IgdGhlIGdpdmVuIG9iamVjdCBvciBjb250ZXh0IHVzaW5nIHRoZSBmYWN0b3J5IGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7TG9nZ2luZ0NvbnRleHR9IG9iamVjdCAtIFRoZSBvYmplY3QsIGNsYXNzLCBvciBjb250ZXh0IHRvIGNyZWF0ZSBhIGxvZ2dlciBmb3JcbiAgICogQHBhcmFtIHtQYXJ0aWFsPExvZ2dpbmdDb25maWc+fSBbY29uZmlnXSAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gdG8gb3ZlcnJpZGUgZ2xvYmFsIHNldHRpbmdzXG4gICAqIEBwYXJhbSB7Li4uYW55fSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgbG9nZ2VyIGZhY3RvcnlcbiAgICogQHJldHVybiB7TG9nZ2VyfSBBIG5ldyBsb2dnZXIgaW5zdGFuY2UgZm9yIHRoZSBzcGVjaWZpZWQgb2JqZWN0IG9yIGNvbnRleHRcbiAgICovXG4gIHN0YXRpYyBmb3IoXG4gICAgb2JqZWN0OiBMb2dnaW5nQ29udGV4dCxcbiAgICBjb25maWc/OiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+LFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IExvZ2dlciB7XG4gICAgb2JqZWN0ID1cbiAgICAgIHR5cGVvZiBvYmplY3QgPT09IFwic3RyaW5nXCJcbiAgICAgICAgPyBvYmplY3RcbiAgICAgICAgOiBvYmplY3QuY29uc3RydWN0b3JcbiAgICAgICAgICA/IG9iamVjdC5jb25zdHJ1Y3Rvci5uYW1lXG4gICAgICAgICAgOiBvYmplY3QubmFtZTtcbiAgICByZXR1cm4gdGhpcy5fZmFjdG9yeShvYmplY3QsIGNvbmZpZywgLi4uYXJncyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBsb2dnZXIgZm9yIGEgc3BlY2lmaWMgcmVhc29uIG9yIGNvcnJlbGF0aW9uIGNvbnRleHRcbiAgICogQHN1bW1hcnkgVXRpbGl0eSB0byBxdWlja2x5IGNyZWF0ZSBhIGxvZ2dlciBsYWJlbGVkIHdpdGggYSBmcmVlLWZvcm0gcmVhc29uIGFuZCBvcHRpb25hbCBpZGVudGlmaWVyXG4gICAqIHNvIHRoYXQgYWQtaG9jIG9wZXJhdGlvbnMgY2FuIGJlIHRyYWNlZCB3aXRob3V0IHR5aW5nIHRoZSBsb2dnZXIgdG8gYSBjbGFzcyBvciBtZXRob2QgbmFtZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHJlYXNvbiAtIEEgdGV4dHVhbCByZWFzb24gb3IgY29udGV4dCBsYWJlbCBmb3IgdGhpcyBsb2dnZXIgaW5zdGFuY2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtpZF0gLSBPcHRpb25hbCBpZGVudGlmaWVyIHRvIGhlbHAgY29ycmVsYXRlIHJlbGF0ZWQgbG9nIGVudHJpZXNcbiAgICogQHJldHVybiB7TG9nZ2VyfSBBIG5ldyBsb2dnZXIgaW5zdGFuY2UgbGFiZWxlZCB3aXRoIHRoZSBwcm92aWRlZCByZWFzb24gYW5kIGlkXG4gICAqL1xuICBzdGF0aWMgYmVjYXVzZShyZWFzb246IHN0cmluZywgaWQ/OiBzdHJpbmcpOiBMb2dnZXIge1xuICAgIHJldHVybiB0aGlzLl9mYWN0b3J5KHJlYXNvbiwgdGhpcy5fY29uZmlnLCBpZCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFwcGxpZXMgdGhlbWUgc3R5bGluZyB0byB0ZXh0XG4gICAqIEBzdW1tYXJ5IEFwcGxpZXMgc3R5bGluZyAoY29sb3JzLCBmb3JtYXR0aW5nKSB0byB0ZXh0IGJhc2VkIG9uIHRoZSB0aGVtZSBjb25maWd1cmF0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGhlIHRleHQgdG8gc3R5bGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgLSBUaGUgdHlwZSBvZiBlbGVtZW50IHRvIHN0eWxlIChlLmcuLCBcImNsYXNzXCIsIFwibWVzc2FnZVwiLCBcImxvZ0xldmVsXCIpXG4gICAqIEBwYXJhbSB7TG9nTGV2ZWx9IGxvZ2dlckxldmVsIC0gVGhlIGxvZyBsZXZlbCB0byB1c2UgZm9yIHN0eWxpbmdcbiAgICogQHBhcmFtIHtUaGVtZX0gW3RlbXBsYXRlPURlZmF1bHRUaGVtZV0gLSBUaGUgdGhlbWUgdG8gdXNlIGZvciBzdHlsaW5nXG4gICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHN0eWxlZCB0ZXh0XG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICAgKiAgIHBhcnRpY2lwYW50IFRoZW1lIGFzIExvZ2dpbmcudGhlbWVcbiAgICogICBwYXJ0aWNpcGFudCBBcHBseSBhcyBhcHBseSBmdW5jdGlvblxuICAgKiAgIHBhcnRpY2lwYW50IFN0eWxlIGFzIHN0eWxlZC1zdHJpbmctYnVpbGRlclxuICAgKlxuICAgKiAgIENhbGxlci0+PlRoZW1lOiB0aGVtZSh0ZXh0LCB0eXBlLCBsb2dnZXJMZXZlbClcbiAgICogICBUaGVtZS0+PlRoZW1lOiBDaGVjayBpZiBzdHlsaW5nIGlzIGVuYWJsZWRcbiAgICogICBhbHQgc3R5bGluZyBkaXNhYmxlZFxuICAgKiAgICAgVGhlbWUtLT4+Q2FsbGVyOiByZXR1cm4gb3JpZ2luYWwgdGV4dFxuICAgKiAgIGVsc2Ugc3R5bGluZyBlbmFibGVkXG4gICAqICAgICBUaGVtZS0+PlRoZW1lOiBHZXQgdGhlbWUgZm9yIHR5cGVcbiAgICogICAgIGFsdCB0aGVtZSBub3QgZm91bmRcbiAgICogICAgICAgVGhlbWUtLT4+Q2FsbGVyOiByZXR1cm4gb3JpZ2luYWwgdGV4dFxuICAgKiAgICAgZWxzZSB0aGVtZSBmb3VuZFxuICAgKiAgICAgICBUaGVtZS0+PlRoZW1lOiBEZXRlcm1pbmUgYWN0dWFsIHRoZW1lIGJhc2VkIG9uIGxvZyBsZXZlbFxuICAgKiAgICAgICBUaGVtZS0+PkFwcGx5OiBBcHBseSBlYWNoIHN0eWxlIHByb3BlcnR5XG4gICAqICAgICAgIEFwcGx5LT4+U3R5bGU6IEFwcGx5IGNvbG9ycyBhbmQgZm9ybWF0dGluZ1xuICAgKiAgICAgICBTdHlsZS0tPj5BcHBseTogUmV0dXJuIHN0eWxlZCB0ZXh0XG4gICAqICAgICAgIEFwcGx5LS0+PlRoZW1lOiBSZXR1cm4gc3R5bGVkIHRleHRcbiAgICogICAgICAgVGhlbWUtLT4+Q2FsbGVyOiBSZXR1cm4gZmluYWwgc3R5bGVkIHRleHRcbiAgICogICAgIGVuZFxuICAgKiAgIGVuZFxuICAgKi9cbiAgc3RhdGljIHRoZW1lKFxuICAgIHRleHQ6IHN0cmluZyxcbiAgICB0eXBlOiBrZXlvZiBUaGVtZSB8IGtleW9mIExvZ0xldmVsLFxuICAgIGxvZ2dlckxldmVsOiBMb2dMZXZlbCxcbiAgICB0ZW1wbGF0ZTogVGhlbWUgPSBEZWZhdWx0VGhlbWVcbiAgKSB7XG4gICAgaWYgKCF0aGlzLl9jb25maWcuc3R5bGUpIHJldHVybiB0ZXh0O1xuICAgIGNvbnN0IGxvZ2dlciA9IExvZ2dpbmcuZ2V0KCkuZm9yKHRoaXMudGhlbWUpO1xuXG4gICAgZnVuY3Rpb24gYXBwbHkoXG4gICAgICB0eHQ6IHN0cmluZyxcbiAgICAgIG9wdGlvbjoga2V5b2YgVGhlbWVPcHRpb24sXG4gICAgICB2YWx1ZTogbnVtYmVyIHwgW251bWJlcl0gfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gfCBudW1iZXJbXSB8IHN0cmluZ1tdXG4gICAgKTogc3RyaW5nIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHQ6IHN0cmluZyB8IFN0eWxlZFN0cmluZyA9IHR4dDtcbiAgICAgICAgbGV0IGMgPSBzdHlsZSh0KTtcblxuICAgICAgICBmdW5jdGlvbiBhcHBseUNvbG9yKFxuICAgICAgICAgIHZhbDogbnVtYmVyIHwgW251bWJlcl0gfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICAgaXNCZyA9IGZhbHNlXG4gICAgICAgICk6IFN0eWxlZFN0cmluZyB7XG4gICAgICAgICAgbGV0IGY6XG4gICAgICAgICAgICB8IHR5cGVvZiBjLmJhY2tncm91bmRcbiAgICAgICAgICAgIHwgdHlwZW9mIGMuZm9yZWdyb3VuZFxuICAgICAgICAgICAgfCB0eXBlb2YgYy5yZ2JcbiAgICAgICAgICAgIHwgdHlwZW9mIGMuY29sb3IyNTYgPSBpc0JnID8gYy5iYWNrZ3JvdW5kIDogYy5mb3JlZ3JvdW5kO1xuICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgICAgICAgICByZXR1cm4gKGYgYXMgdHlwZW9mIGMuYmFja2dyb3VuZCB8IHR5cGVvZiBjLmZvcmVncm91bmQpLmNhbGwoXG4gICAgICAgICAgICAgIGMsXG4gICAgICAgICAgICAgIHZhbHVlIGFzIG51bWJlclxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc3dpdGNoICh2YWwubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgIGYgPSBpc0JnID8gYy5iZ0NvbG9yMjU2IDogYy5jb2xvcjI1NjtcbiAgICAgICAgICAgICAgcmV0dXJuIChmIGFzIHR5cGVvZiBjLmJnQ29sb3IyNTYgfCB0eXBlb2YgYy5jb2xvcjI1NikodmFsWzBdKTtcbiAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgZiA9IGlzQmcgPyBjLmJnUmdiIDogYy5yZ2I7XG4gICAgICAgICAgICAgIHJldHVybiBjLnJnYih2YWxbMF0sIHZhbFsxXSwgdmFsWzJdKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgTm90IGEgdmFsaWQgY29sb3Igb3B0aW9uOiAke29wdGlvbn1gKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHN0eWxlKHQgYXMgc3RyaW5nKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBhcHBseVN0eWxlKHY6IG51bWJlciB8IHN0cmluZyk6IHZvaWQge1xuICAgICAgICAgIGlmICh0eXBlb2YgdiA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgYyA9IGMuc3R5bGUodik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGMgPSBjW3YgYXMga2V5b2YgQ29sb3JpemVPcHRpb25zXSBhcyBTdHlsZWRTdHJpbmc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgc3dpdGNoIChvcHRpb24pIHtcbiAgICAgICAgICBjYXNlIFwiYmdcIjpcbiAgICAgICAgICBjYXNlIFwiZmdcIjpcbiAgICAgICAgICAgIHJldHVybiBhcHBseUNvbG9yKHZhbHVlIGFzIG51bWJlcikudGV4dDtcbiAgICAgICAgICBjYXNlIFwic3R5bGVcIjpcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICB2YWx1ZS5mb3JFYWNoKGFwcGx5U3R5bGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgYXBwbHlTdHlsZSh2YWx1ZSBhcyBudW1iZXIgfCBzdHJpbmcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGMudGV4dDtcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBOb3QgYSB2YWxpZCB0aGVtZSBvcHRpb246ICR7b3B0aW9ufWApO1xuICAgICAgICAgICAgcmV0dXJuIHQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYEVycm9yIGFwcGx5aW5nIHN0eWxlOiAke29wdGlvbn0gd2l0aCB2YWx1ZSAke3ZhbHVlfWApO1xuICAgICAgICByZXR1cm4gdHh0O1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGluZGl2aWR1YWxUaGVtZSA9IHRlbXBsYXRlW3R5cGUgYXMga2V5b2YgVGhlbWVdO1xuICAgIGlmICghaW5kaXZpZHVhbFRoZW1lIHx8ICFPYmplY3Qua2V5cyhpbmRpdmlkdWFsVGhlbWUpLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHRleHQ7XG4gICAgfVxuXG4gICAgbGV0IGFjdHVhbFRoZW1lOiBUaGVtZU9wdGlvbiA9IGluZGl2aWR1YWxUaGVtZSBhcyBUaGVtZU9wdGlvbjtcblxuICAgIGNvbnN0IGxvZ0xldmVscyA9IE9iamVjdC5hc3NpZ24oe30sIExvZ0xldmVsKTtcbiAgICBpZiAoT2JqZWN0LmtleXMoaW5kaXZpZHVhbFRoZW1lKVswXSBpbiBsb2dMZXZlbHMpXG4gICAgICBhY3R1YWxUaGVtZSA9XG4gICAgICAgIChpbmRpdmlkdWFsVGhlbWUgYXMgVGhlbWVPcHRpb25CeUxvZ0xldmVsKVtsb2dnZXJMZXZlbF0gfHwge307XG5cbiAgICByZXR1cm4gT2JqZWN0LmtleXMoYWN0dWFsVGhlbWUpLnJlZHVjZSgoYWNjOiBzdHJpbmcsIGtleTogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCB2YWwgPSAoYWN0dWFsVGhlbWUgYXMgVGhlbWVPcHRpb24pW2tleSBhcyBrZXlvZiBUaGVtZU9wdGlvbl07XG4gICAgICBpZiAodmFsKVxuICAgICAgICByZXR1cm4gYXBwbHkoXG4gICAgICAgICAgYWNjLFxuICAgICAgICAgIGtleSBhcyBrZXlvZiBUaGVtZU9wdGlvbixcbiAgICAgICAgICB2YWwgYXNcbiAgICAgICAgICAgIHwgbnVtYmVyXG4gICAgICAgICAgICB8IFtudW1iZXJdXG4gICAgICAgICAgICB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXVxuICAgICAgICAgICAgfCBudW1iZXJbXVxuICAgICAgICAgICAgfCBzdHJpbmdbXVxuICAgICAgICApO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB0ZXh0KTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgTG9nZ2luZyB9IGZyb20gXCIuL2xvZ2dpbmdcIjtcbmltcG9ydCB7IExvZ2dlciB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEJhc2UgY2xhc3MgdGhhdCBwcm92aWRlcyBhIHJlYWR5LXRvLXVzZSBsb2dnZXIgaW5zdGFuY2VcbiAqIEBzdW1tYXJ5IExvZ2dlZENsYXNzIGlzIGEgY29udmVuaWVuY2UgYWJzdHJhY3QgY2xhc3MgdGhhdCBpbmplY3RzIGEgdHlwZS1zYWZlIGxvZ2dlclxuICogaW50byBkZXJpdmVkIGNsYXNzZXMgdGhyb3VnaCBhIHByb3RlY3RlZCBnZXR0ZXIuIFN1YmNsYXNzZXMgY2FuIGRpcmVjdGx5IGFjY2Vzc1xuICogdGhpcy5sb2cgdG8gZW1pdCBtZXNzYWdlcyB3aXRob3V0IG1hbnVhbGx5IGNyZWF0aW5nIGEgbG9nZ2VyLiBUaGlzIHByb21vdGVzXG4gKiBjb25zaXN0ZW50LCBjb250ZXh0LWF3YXJlIGxvZ2dpbmcgYWNyb3NzIHRoZSBjb2RlYmFzZS5cbiAqIEBwYXJhbSB7dm9pZH0gW2NvbnN0cnVjdG9yXSAtIE5vIGNvbnN0cnVjdG9yIGFyZ3VtZW50czsgc3ViY2xhc3NlcyBtYXkgZGVmaW5lIHRoZWlyIG93blxuICogQGNsYXNzIExvZ2dlZENsYXNzXG4gKiBAZXhhbXBsZVxuICogY2xhc3MgVXNlclNlcnZpY2UgZXh0ZW5kcyBMb2dnZWRDbGFzcyB7XG4gKiAgIGNyZWF0ZSh1c2VyOiBVc2VyKSB7XG4gKiAgICAgdGhpcy5sb2cuaW5mbyhgQ3JlYXRpbmcgdXNlciAke3VzZXIuaWR9YCk7XG4gKiAgIH1cbiAqIH1cbiAqXG4gKiBjb25zdCBzdmMgPSBuZXcgVXNlclNlcnZpY2UoKTtcbiAqIHN2Yy5jcmVhdGUoeyBpZDogXCI0MlwiIH0pO1xuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgSW5zdGFuY2UgYXMgU3ViY2xhc3MgSW5zdGFuY2VcbiAqICAgcGFydGljaXBhbnQgR2V0dGVyIGFzIExvZ2dlZENsYXNzLmxvZ1xuICogICBwYXJ0aWNpcGFudCBMb2dnaW5nIGFzIExvZ2dpbmdcbiAqICAgcGFydGljaXBhbnQgTG9nZ2VyIGFzIExvZ2dlclxuICpcbiAqICAgQ2xpZW50LT4+SW5zdGFuY2U6IGNhbGwgc29tZU1ldGhvZCgpXG4gKiAgIEluc3RhbmNlLT4+R2V0dGVyOiBhY2Nlc3MgdGhpcy5sb2dcbiAqICAgR2V0dGVyLT4+TG9nZ2luZzogTG9nZ2luZy5mb3IodGhpcylcbiAqICAgTG9nZ2luZy0tPj5HZXR0ZXI6IHJldHVybiBMb2dnZXJcbiAqICAgR2V0dGVyLS0+Pkluc3RhbmNlOiByZXR1cm4gTG9nZ2VyXG4gKiAgIEluc3RhbmNlLT4+TG9nZ2VyOiBpbmZvL2RlYnVnL2Vycm9yKC4uLilcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIExvZ2dlZENsYXNzIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMYXppbHkgcHJvdmlkZXMgYSBjb250ZXh0LWF3YXJlIGxvZ2dlciBmb3IgdGhlIGN1cnJlbnQgaW5zdGFuY2VcbiAgICogQHN1bW1hcnkgVXNlcyBMb2dnaW5nLmZvcih0aGlzKSB0byBjcmVhdGUgYSBsb2dnZXIgd2hvc2UgY29udGV4dCBpcyB0aGVcbiAgICogc3ViY2xhc3MgbmFtZSwgYWxsb3dpbmcgdW5pZm9ybSBhbmQgc3RydWN0dXJlZCBsb2dzIGZyb20gYW55IGluaGVyaXRpbmcgY2xhc3MuXG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gQSBsb2dnZXIgYm91bmQgdG8gdGhlIHN1YmNsYXNzIGNvbnRleHRcbiAgICovXG4gIHByb3RlY3RlZCBnZXQgbG9nKCk6IExvZ2dlciB7XG4gICAgcmV0dXJuIExvZ2dpbmcuZm9yKHRoaXMgYXMgYW55KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcigpIHt9XG59XG4iLCJpbXBvcnQgeyBMb2dnZXIsIExvZ2dpbmdDb25maWcsIExvZ2dpbmdGaWx0ZXIgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IExvZ2dlZENsYXNzIH0gZnJvbSBcIi4uL0xvZ2dlZENsYXNzXCI7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBMb2dGaWx0ZXIgZXh0ZW5kcyBMb2dnZWRDbGFzcyBpbXBsZW1lbnRzIExvZ2dpbmdGaWx0ZXIge1xuICBvdmVycmlkZSBnZXQgbG9nKCk6IExvZ2dlciB7XG4gICAgcmV0dXJuIHN1cGVyLmxvZy5mb3IodGhpcyBhcyBhbnksIHsgZmlsdGVyczogW10gfSk7XG4gIH1cblxuICBhYnN0cmFjdCBmaWx0ZXIoXG4gICAgY29uZmlnOiBMb2dnaW5nQ29uZmlnLFxuICAgIG1lc3NhZ2U6IHN0cmluZyxcbiAgICBjb250ZXh0OiBzdHJpbmdbXVxuICApOiBzdHJpbmc7XG59XG4iLCJpbXBvcnQgeyBMb2dMZXZlbCB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgTG9nZ2luZyB9IGZyb20gXCIuL2xvZ2dpbmdcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxsc1xuICogQHN1bW1hcnkgQ3JlYXRlcyBhIGRlY29yYXRvciB0aGF0IGxvZ3MgbWV0aG9kIGNhbGxzIHdpdGggc3BlY2lmaWVkIGxldmVsLCBiZW5jaG1hcmtpbmcsIGFuZCB2ZXJib3NpdHlcbiAqIEBwYXJhbSB7TG9nTGV2ZWx9IGxldmVsIC0gVGhlIGxvZyBsZXZlbCB0byB1c2UgKGRlZmF1bHQ6IExvZ0xldmVsLmluZm8pXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtiZW5jaG1hcms9ZmFsc2VdIC0gV2hldGhlciB0byBsb2cgZXhlY3V0aW9uIHRpbWUgKGRlZmF1bHQ6IGZhbHNlKVxuICogQHBhcmFtIHtudW1iZXJ9IFt2ZXJib3NpdHk9MF0gLSBUaGUgdmVyYm9zaXR5IGxldmVsIGZvciB0aGUgbG9nIG1lc3NhZ2VzIChkZWZhdWx0OiAwKVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbWV0aG9kIGRlY29yYXRvciB0aGF0IHdyYXBzIHRoZSBvcmlnaW5hbCBtZXRob2Qgd2l0aCBsb2dnaW5nXG4gKiBAZnVuY3Rpb24gbG9nXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICogICBwYXJ0aWNpcGFudCBEZWNvcmF0b3IgYXMgbG9nIGRlY29yYXRvclxuICogICBwYXJ0aWNpcGFudCBNZXRob2QgYXMgT3JpZ2luYWwgTWV0aG9kXG4gKiAgIHBhcnRpY2lwYW50IExvZ2dlciBhcyBMb2dnaW5nIGluc3RhbmNlXG4gKlxuICogICBDbGllbnQtPj5EZWNvcmF0b3I6IGNhbGwgZGVjb3JhdGVkIG1ldGhvZFxuICogICBEZWNvcmF0b3ItPj5Mb2dnZXI6IGxvZyBtZXRob2QgY2FsbFxuICogICBEZWNvcmF0b3ItPj5NZXRob2Q6IGNhbGwgb3JpZ2luYWwgbWV0aG9kXG4gKiAgIGFsdCByZXN1bHQgaXMgUHJvbWlzZVxuICogICAgIE1ldGhvZC0tPj5EZWNvcmF0b3I6IHJldHVybiBQcm9taXNlXG4gKiAgICAgRGVjb3JhdG9yLT4+RGVjb3JhdG9yOiBhdHRhY2ggdGhlbiBoYW5kbGVyXG4gKiAgICAgTm90ZSBvdmVyIERlY29yYXRvcjogUHJvbWlzZSByZXNvbHZlc1xuICogICAgIERlY29yYXRvci0+PkxvZ2dlcjogbG9nIGJlbmNobWFyayAoaWYgZW5hYmxlZClcbiAqICAgICBEZWNvcmF0b3ItLT4+Q2xpZW50OiByZXR1cm4gcmVzdWx0XG4gKiAgIGVsc2UgcmVzdWx0IGlzIG5vdCBQcm9taXNlXG4gKiAgICAgTWV0aG9kLS0+PkRlY29yYXRvcjogcmV0dXJuIHJlc3VsdFxuICogICAgIERlY29yYXRvci0+PkxvZ2dlcjogbG9nIGJlbmNobWFyayAoaWYgZW5hYmxlZClcbiAqICAgICBEZWNvcmF0b3ItLT4+Q2xpZW50OiByZXR1cm4gcmVzdWx0XG4gKiAgIGVuZFxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2coXG4gIGxldmVsOiBMb2dMZXZlbCA9IExvZ0xldmVsLmluZm8sXG4gIGJlbmNobWFyazogYm9vbGVhbiA9IGZhbHNlLFxuICB2ZXJib3NpdHkgPSAwXG4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChcbiAgICB0YXJnZXQ6IGFueSxcbiAgICBwcm9wZXJ0eUtleT86IGFueSxcbiAgICBkZXNjcmlwdG9yPzogUHJvcGVydHlEZXNjcmlwdG9yXG4gICkge1xuICAgIGlmICghZGVzY3JpcHRvcilcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTG9nZ2luZyBkZWNvcmF0aW9uIG9ubHkgYXBwbGllcyB0byBtZXRob2RzYCk7XG4gICAgY29uc3QgbG9nZ2VyID0gTG9nZ2luZy5mb3IodGFyZ2V0KS5mb3IodGFyZ2V0W3Byb3BlcnR5S2V5XSk7XG4gICAgY29uc3QgbWV0aG9kID0gbG9nZ2VyW2xldmVsXS5iaW5kKGxvZ2dlcikgYXMgYW55O1xuICAgIGNvbnN0IG9yaWdpbmFsTWV0aG9kID0gZGVzY3JpcHRvci52YWx1ZTtcblxuICAgIGRlc2NyaXB0b3IudmFsdWUgPSBuZXcgUHJveHkob3JpZ2luYWxNZXRob2QsIHtcbiAgICAgIGFwcGx5KGZuLCB0aGlzQXJnLCBhcmdzOiBhbnlbXSkge1xuICAgICAgICBtZXRob2QoYGNhbGxlZCB3aXRoICR7YXJnc31gLCB2ZXJib3NpdHkpO1xuICAgICAgICBjb25zdCBzdGFydCA9IERhdGUubm93KCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5hcHBseShmbiwgdGhpc0FyZywgYXJncyk7XG4gICAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQudGhlbigocjogYW55KSA9PiB7XG4gICAgICAgICAgICAgIGlmIChiZW5jaG1hcmspXG4gICAgICAgICAgICAgICAgbWV0aG9kKGBjb21wbGV0ZWQgaW4gJHtEYXRlLm5vdygpIC0gc3RhcnR9bXNgLCB2ZXJib3NpdHkpO1xuICAgICAgICAgICAgICByZXR1cm4gcjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoYmVuY2htYXJrKVxuICAgICAgICAgICAgbWV0aG9kKGBjb21wbGV0ZWQgaW4gJHtEYXRlLm5vdygpIC0gc3RhcnR9bXNgLCB2ZXJib3NpdHkpO1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIGlmIChiZW5jaG1hcmspIG1ldGhvZChgZmFpbGVkIGluICR7RGF0ZS5ub3coKSAtIHN0YXJ0fW1zYCwgdmVyYm9zaXR5KTtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG4gIH07XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCBkZWJ1ZyBsZXZlbFxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQgdGhlIGxvZyBkZWNvcmF0b3IgdGhhdCB1c2VzIExvZ0xldmVsLmRlYnVnXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtiZW5jaG1hcms9ZmFsc2VdIC0gV2hldGhlciB0byBsb2cgZXhlY3V0aW9uIHRpbWUgKGRlZmF1bHQ6IGZhbHNlKVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbWV0aG9kIGRlY29yYXRvciB0aGF0IHdyYXBzIHRoZSBvcmlnaW5hbCBtZXRob2Qgd2l0aCBkZWJ1ZyBsb2dnaW5nXG4gKiBAZnVuY3Rpb24gZGVidWdcbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZGVidWcoYmVuY2htYXJrOiBib29sZWFuID0gZmFsc2UpIHtcbiAgcmV0dXJuIGxvZyhMb2dMZXZlbC5kZWJ1ZywgYmVuY2htYXJrKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIGluZm8gbGV2ZWxcbiAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIHRoZSBsb2cgZGVjb3JhdG9yIHRoYXQgdXNlcyBMb2dMZXZlbC5pbmZvXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtiZW5jaG1hcms9ZmFsc2VdIC0gV2hldGhlciB0byBsb2cgZXhlY3V0aW9uIHRpbWUgKGRlZmF1bHQ6IGZhbHNlKVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbWV0aG9kIGRlY29yYXRvciB0aGF0IHdyYXBzIHRoZSBvcmlnaW5hbCBtZXRob2Qgd2l0aCBpbmZvIGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiBpbmZvXG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluZm8oYmVuY2htYXJrOiBib29sZWFuID0gZmFsc2UpIHtcbiAgcmV0dXJuIGxvZyhMb2dMZXZlbC5pbmZvLCBiZW5jaG1hcmspO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggc2lsbHkgbGV2ZWxcbiAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIHRoZSBsb2cgZGVjb3JhdG9yIHRoYXQgdXNlcyBMb2dMZXZlbC5zaWxseVxuICogQHBhcmFtIHtib29sZWFufSBbYmVuY2htYXJrPWZhbHNlXSAtIFdoZXRoZXIgdG8gbG9nIGV4ZWN1dGlvbiB0aW1lIChkZWZhdWx0OiBmYWxzZSlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG1ldGhvZCBkZWNvcmF0b3IgdGhhdCB3cmFwcyB0aGUgb3JpZ2luYWwgbWV0aG9kIHdpdGggc2lsbHkgbG9nZ2luZ1xuICogQGZ1bmN0aW9uIHNpbGx5XG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNpbGx5KGJlbmNobWFyazogYm9vbGVhbiA9IGZhbHNlKSB7XG4gIHJldHVybiBsb2coTG9nTGV2ZWwuc2lsbHksIGJlbmNobWFyayk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCB2ZXJib3NlIGxldmVsXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB0aGUgbG9nIGRlY29yYXRvciB0aGF0IHVzZXMgTG9nTGV2ZWwudmVyYm9zZSB3aXRoIGNvbmZpZ3VyYWJsZSB2ZXJib3NpdHlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG1ldGhvZCBkZWNvcmF0b3IgdGhhdCB3cmFwcyB0aGUgb3JpZ2luYWwgbWV0aG9kIHdpdGggdmVyYm9zZSBsb2dnaW5nXG4gKiBAZnVuY3Rpb24gdmVyYm9zZVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyYm9zZSgpOiAoXG4gIHRhcmdldDogYW55LFxuICBwcm9wZXJ0eUtleT86IGFueSxcbiAgZGVzY3JpcHRvcj86IGFueVxuKSA9PiB2b2lkO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggdmVyYm9zZSBsZXZlbFxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQgdGhlIGxvZyBkZWNvcmF0b3IgdGhhdCB1c2VzIExvZ0xldmVsLnZlcmJvc2Ugd2l0aCBjb25maWd1cmFibGUgdmVyYm9zaXR5XG4gKiBAcGFyYW0ge2Jvb2xlYW59IGJlbmNobWFyayAtIFdoZXRoZXIgdG8gbG9nIGV4ZWN1dGlvbiB0aW1lXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIHZlcmJvc2UgbG9nZ2luZ1xuICogQGZ1bmN0aW9uIHZlcmJvc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcmJvc2UoXG4gIGJlbmNobWFyazogYm9vbGVhblxuKTogKHRhcmdldDogYW55LCBwcm9wZXJ0eUtleT86IGFueSwgZGVzY3JpcHRvcj86IGFueSkgPT4gdm9pZDtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIHZlcmJvc2UgbGV2ZWxcbiAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIHRoZSBsb2cgZGVjb3JhdG9yIHRoYXQgdXNlcyBMb2dMZXZlbC52ZXJib3NlIHdpdGggY29uZmlndXJhYmxlIHZlcmJvc2l0eVxuICogQHBhcmFtIHtudW1iZXJ9IHZlcmJvc2l0eSAtIFRoZSB2ZXJib3NpdHkgbGV2ZWwgZm9yIHRoZSBsb2cgbWVzc2FnZXMgKGRlZmF1bHQ6IDApXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIHZlcmJvc2UgbG9nZ2luZ1xuICogQGZ1bmN0aW9uIHZlcmJvc2VcbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyYm9zZShcbiAgdmVyYm9zaXR5OiBudW1iZXIgfCBib29sZWFuXG4pOiAodGFyZ2V0OiBhbnksIHByb3BlcnR5S2V5PzogYW55LCBkZXNjcmlwdG9yPzogYW55KSA9PiB2b2lkO1xuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIHZlcmJvc2UgbGV2ZWxcbiAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIHRoZSBsb2cgZGVjb3JhdG9yIHRoYXQgdXNlcyBMb2dMZXZlbC52ZXJib3NlIHdpdGggY29uZmlndXJhYmxlIHZlcmJvc2l0eVxuICogQHBhcmFtIHtudW1iZXJ9IHZlcmJvc2l0eSAtIFRoZSB2ZXJib3NpdHkgbGV2ZWwgZm9yIHRoZSBsb2cgbWVzc2FnZXMgKGRlZmF1bHQ6IDApXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtiZW5jaG1hcms9ZmFsc2VdIC0gV2hldGhlciB0byBsb2cgZXhlY3V0aW9uIHRpbWUgKGRlZmF1bHQ6IGZhbHNlKVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbWV0aG9kIGRlY29yYXRvciB0aGF0IHdyYXBzIHRoZSBvcmlnaW5hbCBtZXRob2Qgd2l0aCB2ZXJib3NlIGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiB2ZXJib3NlXG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcmJvc2UodmVyYm9zaXR5OiBudW1iZXIgfCBib29sZWFuID0gMCwgYmVuY2htYXJrPzogYm9vbGVhbikge1xuICBpZiAodHlwZW9mIHZlcmJvc2l0eSA9PT0gXCJib29sZWFuXCIpIHtcbiAgICBiZW5jaG1hcmsgPSB2ZXJib3NpdHk7XG4gICAgdmVyYm9zaXR5ID0gMDtcbiAgfVxuICByZXR1cm4gbG9nKExvZ0xldmVsLnZlcmJvc2UsIGJlbmNobWFyaywgdmVyYm9zaXR5KTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGRlY29yYXRvciB0aGF0IG1ha2VzIGEgbWV0aG9kIG5vbi1jb25maWd1cmFibGVcbiAqIEBzdW1tYXJ5IFRoaXMgZGVjb3JhdG9yIHByZXZlbnRzIGEgbWV0aG9kIGZyb20gYmVpbmcgb3ZlcnJpZGRlbiBieSBtYWtpbmcgaXQgbm9uLWNvbmZpZ3VyYWJsZS5cbiAqIEl0IHRocm93cyBhbiBlcnJvciBpZiB1c2VkIG9uIGFueXRoaW5nIG90aGVyIHRoYW4gYSBtZXRob2QuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBkZWNvcmF0b3IgZnVuY3Rpb24gdGhhdCBjYW4gYmUgYXBwbGllZCB0byBtZXRob2RzXG4gKiBAZnVuY3Rpb24gZmluYWxcbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZmluYWwoKSB7XG4gIHJldHVybiAoXG4gICAgdGFyZ2V0OiBvYmplY3QsXG4gICAgcHJvcGVydHlLZXk/OiBhbnksXG4gICAgZGVzY3JpcHRvcj86IFByb3BlcnR5RGVzY3JpcHRvclxuICApID0+IHtcbiAgICBpZiAoIWRlc2NyaXB0b3IpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJmaW5hbCBkZWNvcmF0b3IgY2FuIG9ubHkgYmUgdXNlZCBvbiBtZXRob2RzXCIpO1xuICAgIGlmIChkZXNjcmlwdG9yPy5jb25maWd1cmFibGUpIHtcbiAgICAgIGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBkZXNjcmlwdG9yO1xuICB9O1xufVxuIiwiaW1wb3J0IHsgTG9nRmlsdGVyIH0gZnJvbSBcIi4vTG9nRmlsdGVyXCI7XG5pbXBvcnQgeyBMb2dnaW5nQ29uZmlnIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBmaW5hbCB9IGZyb20gXCIuLi9kZWNvcmF0b3JzXCI7XG5cbmV4cG9ydCB0eXBlIFJlcGxhY2VtZW50RnVuY3Rpb24gPSAoc3Vic3RyaW5nOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKSA9PiBzdHJpbmc7XG5cbmV4cG9ydCBjbGFzcyBQYXR0ZXJuRmlsdGVyIGV4dGVuZHMgTG9nRmlsdGVyIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IHJlZ2V4cDogUmVnRXhwLFxuICAgIHByb3RlY3RlZCByZWFkb25seSByZXBsYWNlbWVudDogc3RyaW5nIHwgUmVwbGFjZW1lbnRGdW5jdGlvblxuICApIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgQGZpbmFsKClcbiAgcHJvdGVjdGVkIG1hdGNoKG1lc3NhZ2U6IHN0cmluZykge1xuICAgIGNvbnN0IG1hdGNoID0gdGhpcy5yZWdleHAuZXhlYyhtZXNzYWdlKTtcbiAgICB0aGlzLnJlZ2V4cC5sYXN0SW5kZXggPSAwO1xuICAgIHJldHVybiBtYXRjaDtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgZmlsdGVyKGNvbmZpZzogTG9nZ2luZ0NvbmZpZywgbWVzc2FnZTogc3RyaW5nLCBjb250ZXh0OiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMuZmlsdGVyKTtcbiAgICBjb25zdCBtYXRjaCA9IHRoaXMubWF0Y2gobWVzc2FnZSk7XG4gICAgaWYgKCFtYXRjaCkgcmV0dXJuIG1lc3NhZ2U7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBtZXNzYWdlLnJlcGxhY2UodGhpcy5yZWdleHAsIHRoaXMucmVwbGFjZW1lbnQgYXMgYW55KTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICBsb2cuZXJyb3IoYFBhdHRlcm5GaWx0ZXIgcmVwbGFjZW1lbnQgZXJyb3I6ICR7ZX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIFwiXCI7XG4gIH1cbn1cbiIsImV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlcnNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnN0YW50c1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZW52aXJvbm1lbnRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0xvZ2dlZENsYXNzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9sb2dnaW5nXCI7XG5leHBvcnQgKiBmcm9tIFwiLi90ZXh0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi90eXBlc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vd2ViXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgbG9nZ2luZyBtb2R1bGUgZm9yIFR5cGVTY3JpcHQgYXBwbGljYXRpb25zXG4gKiBAc3VtbWFyeSBQcm92aWRlcyBhIGNvbXByZWhlbnNpdmUsIGZsZXhpYmxlIGxvZ2dpbmcgc29sdXRpb24uIFRoaXMgbW9kdWxlIGV4cG9zZXM6XG4gKiAtIENvcmUgY2xhc3NlcyBsaWtlIHtAbGluayBMb2dnaW5nfSBhbmQge0BsaW5rIE1pbmlMb2dnZXJ9XG4gKiAtIERlY29yYXRvcnMgc3VjaCBhcyB7QGxpbmsgbG9nfSBmb3IgaW5zdHJ1bWVudGluZyBtZXRob2RzXG4gKiAtIENvbmZpZ3VyYXRpb24gYW5kIGNvbnN0YW50cyBsaWtlIHtAbGluayBMb2dMZXZlbH0gYW5kIHtAbGluayBEZWZhdWx0TG9nZ2luZ0NvbmZpZ31cbiAqIC0gVHlwZSBkZWZpbml0aW9ucyBpbmNsdWRpbmcge0BsaW5rIExvZ2dlcn0gYW5kIHtAbGluayBMb2dnaW5nQ29uZmlnfVxuICogVGhlc2UgZXhwb3J0cyBlbmFibGUgY29uc2lzdGVudCwgY29udGV4dC1hd2FyZSwgYW5kIG9wdGlvbmFsbHkgdGhlbWVkIGxvZ2dpbmcgYWNyb3NzIHByb2plY3RzLlxuICogQG1vZHVsZSBMb2dnaW5nXG4gKi9cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ3VycmVudCBwYWNrYWdlIHZlcnNpb24gc3RyaW5nXG4gKiBAc3VtbWFyeSBTdG9yZXMgdGhlIGN1cnJlbnQgcGFja2FnZSB2ZXJzaW9uLCB1c2VkIGZvciB2ZXJzaW9uIHRyYWNraW5nIGFuZCBjb21wYXRpYmlsaXR5IGNoZWNrc1xuICogQGNvbnN0IFZFUlNJT05cbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbiJdLCJuYW1lcyI6WyJMb2dMZXZlbCIsIkxvZ2dpbmdNb2RlIiwiT2JqZWN0QWNjdW11bGF0b3IiLCJzdHlsZSIsIl9fZGVjb3JhdGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUVPLFVBQU0sYUFBYSxHQUFHO0lBRTdCOzs7SUFHRztBQUNJLFVBQU0sa0JBQWtCLEdBQUc7VUFFckIsMEJBQTBCLEdBQUcsQ0FBQyxJQUFJLEVBQUUsR0FBRztJQUVwRDs7Ozs7O0lBTUc7QUFDU0E7SUFBWixDQUFBLFVBQVksUUFBUSxFQUFBOztJQUVsQixJQUFBLFFBQUEsQ0FBQSxPQUFBLENBQUEsR0FBQSxPQUFlOztJQUVmLElBQUEsUUFBQSxDQUFBLE1BQUEsQ0FBQSxHQUFBLE1BQWE7O0lBRWIsSUFBQSxRQUFBLENBQUEsU0FBQSxDQUFBLEdBQUEsU0FBbUI7O0lBRW5CLElBQUEsUUFBQSxDQUFBLE9BQUEsQ0FBQSxHQUFBLE9BQWU7O0lBRWYsSUFBQSxRQUFBLENBQUEsT0FBQSxDQUFBLEdBQUEsT0FBZTtJQUNqQixDQUFDLEVBWFdBLGdCQUFRLEtBQVJBLGdCQUFRLEdBV25CLEVBQUEsQ0FBQSxDQUFBO0lBRUQ7Ozs7Ozs7Ozs7SUFVRztBQUNVLFVBQUEsZ0JBQWdCLEdBQUc7SUFDOUIsSUFBQSxLQUFLLEVBQUUsQ0FBQztJQUNSLElBQUEsSUFBSSxFQUFFLENBQUM7SUFDUCxJQUFBLE9BQU8sRUFBRSxDQUFDO0lBQ1YsSUFBQSxLQUFLLEVBQUUsQ0FBQztJQUNSLElBQUEsS0FBSyxFQUFFLENBQUM7O0lBR1Y7Ozs7O0lBS0c7QUFDU0M7SUFBWixDQUFBLFVBQVksV0FBVyxFQUFBOztJQUVyQixJQUFBLFdBQUEsQ0FBQSxLQUFBLENBQUEsR0FBQSxLQUFXOztJQUVYLElBQUEsV0FBQSxDQUFBLE1BQUEsQ0FBQSxHQUFBLE1BQWE7SUFDZixDQUFDLEVBTFdBLG1CQUFXLEtBQVhBLG1CQUFXLEdBS3RCLEVBQUEsQ0FBQSxDQUFBO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQXdCRztB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
|