@decaf-ts/logging 0.3.7 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/logging.cjs +651 -104
  2. package/dist/logging.esm.cjs +630 -101
  3. package/lib/constants.cjs +24 -6
  4. package/lib/constants.d.ts +7 -0
  5. package/lib/decorators.cjs +47 -24
  6. package/lib/decorators.d.ts +24 -6
  7. package/lib/environment.cjs +204 -0
  8. package/lib/environment.d.ts +86 -0
  9. package/lib/esm/constants.d.ts +7 -0
  10. package/lib/esm/constants.js +23 -5
  11. package/lib/esm/decorators.d.ts +24 -6
  12. package/lib/esm/decorators.js +46 -24
  13. package/lib/esm/environment.d.ts +86 -0
  14. package/lib/esm/environment.js +200 -0
  15. package/lib/esm/filters/LogFilter.d.ts +6 -0
  16. package/lib/esm/filters/LogFilter.js +7 -0
  17. package/lib/esm/filters/PatternFilter.d.ts +10 -0
  18. package/lib/esm/filters/PatternFilter.js +43 -0
  19. package/lib/esm/filters/index.d.ts +2 -0
  20. package/lib/esm/filters/index.js +3 -0
  21. package/lib/esm/index.d.ts +5 -1
  22. package/lib/esm/index.js +6 -2
  23. package/lib/esm/logging.d.ts +11 -11
  24. package/lib/esm/logging.js +62 -32
  25. package/lib/esm/text.d.ts +156 -0
  26. package/lib/esm/text.js +214 -0
  27. package/lib/esm/types.d.ts +32 -4
  28. package/lib/esm/types.js +1 -1
  29. package/lib/esm/web.d.ts +8 -0
  30. package/lib/esm/web.js +12 -0
  31. package/lib/esm/winston/winston.d.ts +2 -2
  32. package/lib/esm/winston/winston.js +4 -4
  33. package/lib/filters/LogFilter.cjs +11 -0
  34. package/lib/filters/LogFilter.d.ts +6 -0
  35. package/lib/filters/PatternFilter.cjs +47 -0
  36. package/lib/filters/PatternFilter.d.ts +10 -0
  37. package/lib/filters/index.cjs +19 -0
  38. package/lib/filters/index.d.ts +2 -0
  39. package/lib/index.cjs +6 -2
  40. package/lib/index.d.ts +5 -1
  41. package/lib/logging.cjs +61 -31
  42. package/lib/logging.d.ts +11 -11
  43. package/lib/text.cjs +227 -0
  44. package/lib/text.d.ts +156 -0
  45. package/lib/types.cjs +1 -1
  46. package/lib/types.d.ts +32 -4
  47. package/lib/web.cjs +15 -0
  48. package/lib/web.d.ts +8 -0
  49. package/lib/winston/winston.cjs +4 -4
  50. package/lib/winston/winston.d.ts +2 -2
  51. package/package.json +12 -3
@@ -1,5 +1,14 @@
1
1
  import { style } from 'styled-string-builder';
2
+ import { ObjectAccumulator } from 'typed-object-accumulator';
3
+ import { __decorate, __metadata } from 'tslib';
2
4
 
5
+ const BrowserEnvKey = "ENV";
6
+ /**
7
+ * @description Delimiter used for composing nested environment variable names.
8
+ * @summary Joins parent and child keys when mapping object paths to ENV strings.
9
+ */
10
+ const ENV_PATH_DELIMITER = "__";
11
+ const DefaultPlaceholderWrappers = ["${", "}"];
3
12
  /**
4
13
  * @description Enum for log levels.
5
14
  * @summary Defines different levels of logging for the application.
@@ -77,6 +86,8 @@ var LoggingMode;
77
86
  * @memberOf module:Logging
78
87
  */
79
88
  const DefaultTheme = {
89
+ app: {},
90
+ separator: {},
80
91
  class: {
81
92
  fg: 34,
82
93
  },
@@ -96,10 +107,17 @@ const DefaultTheme = {
96
107
  fg: 31,
97
108
  style: ["bold"],
98
109
  },
99
- info: {},
100
- verbose: {},
110
+ info: {
111
+ fg: 34,
112
+ style: ["bold"],
113
+ },
114
+ verbose: {
115
+ fg: 34,
116
+ style: ["bold"],
117
+ },
101
118
  debug: {
102
119
  fg: 33,
120
+ style: ["bold"],
103
121
  },
104
122
  },
105
123
  };
@@ -121,19 +139,442 @@ const DefaultTheme = {
121
139
  * @memberOf module:Logging
122
140
  */
123
141
  const DefaultLoggingConfig = {
142
+ env: "development",
124
143
  verbose: 0,
125
144
  level: LogLevel.info,
126
145
  logLevel: true,
127
- mode: LoggingMode.RAW,
128
146
  style: false,
129
147
  contextSeparator: ".",
130
- separator: " - ",
148
+ separator: "-",
131
149
  timestamp: true,
132
150
  timestampFormat: "HH:mm:ss.SSS",
133
151
  context: true,
152
+ format: LoggingMode.RAW,
153
+ pattern: "{level} [{timestamp}] {app} {context} {separator} {message} {stack}",
134
154
  theme: DefaultTheme,
135
155
  };
136
156
 
157
+ /**
158
+ * @description Pads the end of a string with a specified character.
159
+ * @summary Extends the input string to a specified length by adding a padding character to the end.
160
+ * If the input string is already longer than the specified length, it is returned unchanged.
161
+ *
162
+ * @param {string} str - The input string to be padded.
163
+ * @param {number} length - The desired total length of the resulting string.
164
+ * @param {string} [char=" "] - The character to use for padding. Defaults to a space.
165
+ * @return {string} The padded string.
166
+ * @throws {Error} If the padding character is not exactly one character long.
167
+ *
168
+ * @function padEnd
169
+ *
170
+ * @memberOf module:Logging
171
+ */
172
+ function padEnd(str, length, char = " ") {
173
+ if (char.length !== 1)
174
+ throw new Error("Invalid character length for padding. must be one!");
175
+ return str.padEnd(length, char);
176
+ }
177
+ /**
178
+ * @description Replaces placeholders in a string with provided values.
179
+ * @summary Interpolates a string by replacing placeholders of the form ${variableName}
180
+ * with corresponding values from the provided object. If a placeholder doesn't have
181
+ * a corresponding value, it is left unchanged in the string.
182
+ *
183
+ * @param {string} input - The input string containing placeholders to be replaced.
184
+ * @param {Record<string, number | string>} values - An object containing key-value pairs for replacement.
185
+ * @param prefix
186
+ * @param suffix
187
+ * @param flags
188
+ * @return {string} The interpolated string with placeholders replaced by their corresponding values.
189
+ *
190
+ * @function patchPlaceholders
191
+ *
192
+ * @mermaid
193
+ * sequenceDiagram
194
+ * participant Caller
195
+ * participant patchString
196
+ * participant String.replace
197
+ * Caller->>patchString: Call with input and values
198
+ * patchString->>String.replace: Call with regex and replacement function
199
+ * String.replace->>patchString: Return replaced string
200
+ * patchString-->>Caller: Return patched string
201
+ *
202
+ * @memberOf module:Logging
203
+ */
204
+ function patchPlaceholders(input, values, prefix = DefaultPlaceholderWrappers[0], suffix = DefaultPlaceholderWrappers[1], flags = "g") {
205
+ const placeholders = Object.entries(values).reduce((acc, [key, val]) => {
206
+ acc[`${prefix}${key}${suffix}`] = val;
207
+ return acc;
208
+ }, {});
209
+ return patchString(input, placeholders, flags);
210
+ }
211
+ /**
212
+ * @description Replaces occurrences of keys with their corresponding values in a string.
213
+ * @summary Iterates through a set of key-value pairs and replaces all occurrences of each key
214
+ * in the input string with its corresponding value. Supports regular expression flags for customized replacement.
215
+ *
216
+ * @param {string} input - The input string in which replacements will be made.
217
+ * @param {Record<string, number | string>} values - An object containing key-value pairs for replacement.
218
+ * @param {string} [flags="g"] - Regular expression flags to control the replacement behavior.
219
+ * @return {string} The string with all specified replacements applied.
220
+ *
221
+ * @function patchString
222
+ *
223
+ * @memberOf module:Logging
224
+ */
225
+ function patchString(input, values, flags = "g") {
226
+ Object.entries(values).forEach(([key, val]) => {
227
+ const regexp = new RegExp(escapeRegExp(key), flags);
228
+ input = input.replace(regexp, val);
229
+ });
230
+ return input;
231
+ }
232
+ /**
233
+ * @description Converts a string to camelCase.
234
+ * @summary Transforms the input string into camelCase format, where words are joined without spaces
235
+ * and each word after the first starts with a capital letter.
236
+ *
237
+ * @param {string} text - The input string to be converted.
238
+ * @return {string} The input string converted to camelCase.
239
+ *
240
+ * @function toCamelCase
241
+ *
242
+ * @memberOf module:Logging
243
+ */
244
+ function toCamelCase(text) {
245
+ return text
246
+ .replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => index === 0 ? word.toLowerCase() : word.toUpperCase())
247
+ .replace(/\s+/g, "");
248
+ }
249
+ /**
250
+ * @description Converts a string to ENVIRONMENT_VARIABLE format.
251
+ * @summary Transforms the input string into uppercase with words separated by underscores,
252
+ * typically used for environment variable names.
253
+ *
254
+ * @param {string} text - The input string to be converted.
255
+ * @return {string} The input string converted to ENVIRONMENT_VARIABLE format.
256
+ *
257
+ * @function toENVFormat
258
+ *
259
+ * @memberOf module:Logging
260
+ */
261
+ function toENVFormat(text) {
262
+ return toSnakeCase(text).toUpperCase();
263
+ }
264
+ /**
265
+ * @description Converts a string to snake_case.
266
+ * @summary Transforms the input string into lowercase with words separated by underscores.
267
+ *
268
+ * @param {string} text - The input string to be converted.
269
+ * @return {string} The input string converted to snake_case.
270
+ *
271
+ * @function toSnakeCase
272
+ *
273
+ * @memberOf module:Logging
274
+ */
275
+ function toSnakeCase(text) {
276
+ return text
277
+ .replace(/([a-z])([A-Z])/g, "$1_$2")
278
+ .replace(/[\s-]+/g, "_")
279
+ .toLowerCase();
280
+ }
281
+ /**
282
+ * @description Converts a string to kebab-case.
283
+ * @summary Transforms the input string into lowercase with words separated by hyphens.
284
+ *
285
+ * @param {string} text - The input string to be converted.
286
+ * @return {string} The input string converted to kebab-case.
287
+ *
288
+ * @function toKebabCase
289
+ *
290
+ * @memberOf module:Logging
291
+ */
292
+ function toKebabCase(text) {
293
+ return text
294
+ .replace(/([a-z])([A-Z])/g, "$1-$2")
295
+ .replace(/[\s_]+/g, "-")
296
+ .toLowerCase();
297
+ }
298
+ /**
299
+ * @description Converts a string to PascalCase.
300
+ * @summary Transforms the input string into PascalCase format, where words are joined without spaces
301
+ * and each word starts with a capital letter.
302
+ *
303
+ * @param {string} text - The input string to be converted.
304
+ * @return {string} The input string converted to PascalCase.
305
+ *
306
+ * @function toPascalCase
307
+ *
308
+ * @memberOf module:Logging
309
+ */
310
+ function toPascalCase(text) {
311
+ return text
312
+ .replace(/(?:^\w|[A-Z]|\b\w)/g, (word) => word.toUpperCase())
313
+ .replace(/\s+/g, "");
314
+ }
315
+ /**
316
+ * @description Escapes special characters in a string for use in a regular expression.
317
+ * @summary Adds backslashes before characters that have special meaning in regular expressions,
318
+ * allowing the string to be used as a literal match in a RegExp.
319
+ *
320
+ * @param {string} string - The string to escape for regular expression use.
321
+ * @return {string} The escaped string safe for use in regular expressions.
322
+ *
323
+ * @function escapeRegExp
324
+ *
325
+ * @memberOf module:Logging
326
+ */
327
+ function escapeRegExp(string) {
328
+ return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
329
+ }
330
+ /**
331
+ * @summary Util function to provide string format functionality similar to C#'s string.format
332
+ *
333
+ * @param {string} string
334
+ * @param {Array<string | number> | Record<string, any>} [args] replacements made by order of appearance (replacement0 wil replace {0} and so on)
335
+ * @return {string} formatted string
336
+ *
337
+ * @function sf
338
+ * @memberOf module:Logging
339
+ */
340
+ function sf(string, ...args) {
341
+ if (args.length > 1) {
342
+ if (!args.every((arg) => typeof arg === "string" || typeof arg === "number"))
343
+ throw new Error(`Only string and number arguments are supported for multiple replacements.`);
344
+ }
345
+ if (args.length === 1 && typeof args[0] === "object") {
346
+ const obj = args[0];
347
+ return Object.entries(obj).reduce((acc, [key, val]) => {
348
+ return acc.replace(new RegExp(`\\{${key}\\}`, "g"), function () {
349
+ return val;
350
+ });
351
+ }, string);
352
+ }
353
+ return string.replace(/{(\d+)}/g, function (match, number) {
354
+ return typeof args[number] !== "undefined"
355
+ ? args[number].toString()
356
+ : "undefined";
357
+ });
358
+ }
359
+ /**
360
+ * @summary Util function to provide string format functionality similar to C#'s string.format
361
+ *
362
+ * @see sf
363
+ *
364
+ * @deprecated
365
+ * @function stringFormat
366
+ * @memberOf module:Logging
367
+ */
368
+ const stringFormat = sf;
369
+
370
+ /**
371
+ * @description Determines if the current environment is a browser by checking the prototype chain of the global object.
372
+ * @summary Checks if the code is running in a browser environment.
373
+ * @return {boolean} True if the environment is a browser, false otherwise.
374
+ * @function isBrowser
375
+ * @memberOf module:Logging
376
+ */
377
+ function isBrowser() {
378
+ return (Object.getPrototypeOf(Object.getPrototypeOf(globalThis)) !==
379
+ Object.prototype);
380
+ }
381
+
382
+ /**
383
+ * @class Environment
384
+ * @extends {ObjectAccumulator<T>}
385
+ * @template T
386
+ * @description A class representing an environment with accumulation capabilities.
387
+ * @summary Manages environment-related data and provides methods for accumulation and key retrieval.
388
+ * @param {T} [initialData] - The initial data to populate the environment with.
389
+ */
390
+ class Environment extends ObjectAccumulator {
391
+ /**
392
+ * @static
393
+ * @protected
394
+ * @description A factory function for creating Environment instances.
395
+ * @summary Defines how new instances of the Environment class should be created.
396
+ * @return {Environment<any>} A new instance of the Environment class.
397
+ */
398
+ static { this.factory = () => new Environment(); }
399
+ constructor() {
400
+ super();
401
+ }
402
+ /**
403
+ * @description Retrieves a value from the environment
404
+ * @summary Gets a value from the environment variables, handling browser and Node.js environments differently
405
+ * @param {string} k - The key to retrieve from the environment
406
+ * @return {unknown} The value from the environment, or undefined if not found
407
+ */
408
+ fromEnv(k) {
409
+ let env;
410
+ if (isBrowser()) {
411
+ env = globalThis[BrowserEnvKey];
412
+ }
413
+ else {
414
+ env = globalThis.process.env;
415
+ k = toENVFormat(k);
416
+ }
417
+ return env[k];
418
+ }
419
+ /**
420
+ * @description Expands an object into the environment
421
+ * @summary Defines properties on the environment object that can be accessed as getters and setters
422
+ * @template V - Type of the object being expanded
423
+ * @param {V} value - The object to expand into the environment
424
+ * @return {void}
425
+ */
426
+ expand(value) {
427
+ Object.entries(value).forEach(([k, v]) => {
428
+ Object.defineProperty(this, k, {
429
+ get: () => {
430
+ const fromEnv = this.fromEnv(k);
431
+ if (typeof fromEnv !== "undefined")
432
+ return fromEnv;
433
+ if (v && typeof v === "object") {
434
+ return Environment.buildEnvProxy(v, [k]);
435
+ }
436
+ // If the model provides an empty string, expose a proxy that composes ENV keys
437
+ if (v === "") {
438
+ return Environment.buildEnvProxy(undefined, [k]);
439
+ }
440
+ return v;
441
+ },
442
+ set: (val) => {
443
+ v = val;
444
+ },
445
+ configurable: true,
446
+ enumerable: true,
447
+ });
448
+ });
449
+ }
450
+ /**
451
+ * @protected
452
+ * @static
453
+ * @description Retrieves or creates the singleton instance of the Environment class.
454
+ * @summary Ensures only one instance of the Environment class exists.
455
+ * @template E
456
+ * @param {...unknown[]} args - Arguments to pass to the factory function if a new instance is created.
457
+ * @return {E} The singleton instance of the Environment class.
458
+ */
459
+ static instance(...args) {
460
+ if (!Environment._instance) {
461
+ const base = Environment.factory(...args);
462
+ const proxied = new Proxy(base, {
463
+ get(target, prop, receiver) {
464
+ const value = Reflect.get(target, prop, receiver);
465
+ if (typeof value !== "undefined")
466
+ return value;
467
+ if (typeof prop === "string") {
468
+ // Avoid interfering with logging config lookups for optional fields like 'app'
469
+ if (prop === "app")
470
+ return undefined;
471
+ return Environment.buildEnvProxy(undefined, [prop]);
472
+ }
473
+ return value;
474
+ },
475
+ });
476
+ Environment._instance = proxied;
477
+ }
478
+ return Environment._instance;
479
+ }
480
+ /**
481
+ * @static
482
+ * @description Accumulates the given value into the environment.
483
+ * @summary Adds new properties to the environment from the provided object.
484
+ * @template V
485
+ * @param {V} value - The object to accumulate into the environment.
486
+ * @return {V} The updated environment instance.
487
+ */
488
+ static accumulate(value) {
489
+ const instance = Environment.instance();
490
+ Object.keys(instance).forEach((key) => {
491
+ const desc = Object.getOwnPropertyDescriptor(instance, key);
492
+ if (desc && desc.configurable && desc.enumerable) {
493
+ Object.defineProperty(instance, key, {
494
+ ...desc,
495
+ enumerable: false,
496
+ });
497
+ }
498
+ });
499
+ return instance.accumulate(value);
500
+ }
501
+ static get(key) {
502
+ return Environment._instance.get(key);
503
+ }
504
+ static buildEnvProxy(current, path) {
505
+ const buildKey = (p) => p.map((seg) => toENVFormat(seg)).join(ENV_PATH_DELIMITER);
506
+ // Helper to read from the active environment given a composed key
507
+ const readEnv = (key) => {
508
+ if (isBrowser()) {
509
+ const env = globalThis[BrowserEnvKey];
510
+ return env ? env[key] : undefined;
511
+ }
512
+ return globalThis?.process?.env?.[key];
513
+ };
514
+ const handler = {
515
+ get(_target, prop) {
516
+ if (prop === Symbol.toPrimitive) {
517
+ return () => buildKey(path);
518
+ }
519
+ if (prop === "toString") {
520
+ return () => buildKey(path);
521
+ }
522
+ if (prop === "valueOf") {
523
+ return () => buildKey(path);
524
+ }
525
+ if (typeof prop === "symbol")
526
+ return undefined;
527
+ const nextModel = current && Object.prototype.hasOwnProperty.call(current, prop)
528
+ ? current[prop]
529
+ : undefined;
530
+ const nextPath = [...path, prop];
531
+ const composedKey = buildKey(nextPath);
532
+ // If an ENV value exists for this path, return it directly
533
+ const envValue = readEnv(composedKey);
534
+ if (typeof envValue !== "undefined")
535
+ return envValue;
536
+ // Otherwise, if the model has an object at this path, keep drilling with a proxy
537
+ const isNextObject = nextModel && typeof nextModel === "object";
538
+ if (isNextObject)
539
+ return Environment.buildEnvProxy(nextModel, nextPath);
540
+ // Always return a proxy for further path composition when no ENV value;
541
+ // do not surface primitive model defaults here (this API is for key composition).
542
+ return Environment.buildEnvProxy(undefined, nextPath);
543
+ },
544
+ ownKeys() {
545
+ return current ? Reflect.ownKeys(current) : [];
546
+ },
547
+ getOwnPropertyDescriptor(_t, p) {
548
+ if (!current)
549
+ return undefined;
550
+ if (Object.prototype.hasOwnProperty.call(current, p)) {
551
+ return { enumerable: true, configurable: true };
552
+ }
553
+ return undefined;
554
+ },
555
+ };
556
+ const target = {};
557
+ return new Proxy(target, handler);
558
+ }
559
+ /**
560
+ * @static
561
+ * @description Retrieves the keys of the environment, optionally converting them to ENV format.
562
+ * @summary Gets all keys in the environment, with an option to format them for environment variables.
563
+ * @param {boolean} [toEnv=true] - Whether to convert the keys to ENV format.
564
+ * @return {string[]} An array of keys from the environment.
565
+ */
566
+ static keys(toEnv = true) {
567
+ return Environment.instance()
568
+ .keys()
569
+ .map((k) => (toEnv ? toENVFormat(k) : k));
570
+ }
571
+ }
572
+ const LoggedEnvironment = Environment.accumulate(Object.assign({}, DefaultLoggingConfig, {
573
+ env: (isBrowser() && globalThis[BrowserEnvKey]
574
+ ? globalThis[BrowserEnvKey]["NODE_ENV"]
575
+ : globalThis.process.env["NODE_ENV"]) || "development",
576
+ }));
577
+
137
578
  /**
138
579
  * @description A minimal logger implementation.
139
580
  * @summary MiniLogger is a lightweight logging class that implements the Logger interface.
@@ -214,35 +655,45 @@ class MiniLogger {
214
655
  * @summary Generates a log string with timestamp, colored log level, context, and message
215
656
  * @param {LogLevel} level - The log level for this message
216
657
  * @param {StringLike | Error} message - The message to log or an Error object
217
- * @param {string} [stack] - Optional stack trace to include in the log
658
+ * @param {string} [error] - Optional error to extract stack trace to include in the log
218
659
  * @return {string} A formatted log string with all components
219
660
  */
220
- createLog(level, message, stack) {
221
- const log = [];
661
+ createLog(level, message, error) {
662
+ const log = {};
222
663
  const style = this.config("style");
664
+ const separator = this.config("separator");
665
+ const app = this.config("app");
666
+ if (app)
667
+ log.app = style
668
+ ? Logging.theme(app, "app", level)
669
+ : app;
670
+ if (separator)
671
+ log.separator = style
672
+ ? Logging.theme(separator, "separator", level)
673
+ : separator;
223
674
  if (this.config("timestamp")) {
224
675
  const date = new Date().toISOString();
225
676
  const timestamp = style ? Logging.theme(date, "timestamp", level) : date;
226
- log.push(timestamp);
677
+ log.timestamp = timestamp;
227
678
  }
228
679
  if (this.config("logLevel")) {
229
680
  const lvl = style
230
681
  ? Logging.theme(level, "logLevel", level)
231
682
  : level;
232
- log.push(lvl);
683
+ log.level = lvl.toUpperCase();
233
684
  }
234
685
  if (this.config("context")) {
235
686
  const context = style
236
687
  ? Logging.theme(this.context, "class", level)
237
688
  : this.context;
238
- log.push(context);
689
+ log.context = context;
239
690
  }
240
691
  if (this.config("correlationId")) {
241
692
  {
242
693
  const id = style
243
694
  ? Logging.theme(this.config("correlationId").toString(), "id", level)
244
695
  : this.config("correlationId").toString();
245
- log.push(id);
696
+ log.correlationId = id;
246
697
  }
247
698
  }
248
699
  const msg = style
@@ -250,14 +701,32 @@ class MiniLogger {
250
701
  : typeof message === "string"
251
702
  ? message
252
703
  : message.message;
253
- log.push(msg);
254
- if (stack || message instanceof Error) {
255
- stack = style
256
- ? Logging.theme((stack || message.stack), "stack", level)
257
- : stack;
258
- log.push(`\nStack trace:\n${stack}`);
704
+ log.message = msg;
705
+ if (error || message instanceof Error) {
706
+ const stack = style
707
+ ? Logging.theme((error?.stack || message.stack), "stack", level)
708
+ : error?.stack || "";
709
+ log.stack = ` | ${(error || message).message} - Stack trace:\n${stack}`;
710
+ }
711
+ switch (this.config("format")) {
712
+ case "json":
713
+ return JSON.stringify(log);
714
+ case "raw":
715
+ return this.config("pattern")
716
+ .split(" ")
717
+ .map((s) => {
718
+ if (!s.match(/\{.*?}/g))
719
+ return s;
720
+ const formattedS = sf(s, log);
721
+ if (formattedS !== s)
722
+ return formattedS;
723
+ return undefined;
724
+ })
725
+ .filter((s) => s)
726
+ .join(" ");
727
+ default:
728
+ throw new Error(`Unsupported logging format: ${this.config("format")}`);
259
729
  }
260
- return log.join(this.config("separator"));
261
730
  }
262
731
  /**
263
732
  * @description Logs a message with the specified log level
@@ -265,12 +734,12 @@ class MiniLogger {
265
734
  * then uses the appropriate console method to output the formatted log
266
735
  * @param {LogLevel} level - The log level of the message
267
736
  * @param {StringLike | Error} msg - The message to be logged or an Error object
268
- * @param {string} [stack] - Optional stack trace to include in the log
737
+ * @param {string} [error] - Optional stack trace to include in the log
269
738
  * @return {void}
270
739
  */
271
- log(level, msg, stack) {
272
- if (NumericLogLevels[this.config("level")] <
273
- NumericLogLevels[level])
740
+ log(level, msg, error) {
741
+ const confLvl = this.config("level");
742
+ if (NumericLogLevels[confLvl] < NumericLogLevels[level])
274
743
  return;
275
744
  let method;
276
745
  switch (level) {
@@ -287,7 +756,7 @@ class MiniLogger {
287
756
  default:
288
757
  throw new Error("Invalid log level");
289
758
  }
290
- method(this.createLog(level, msg, stack));
759
+ method(this.createLog(level, msg, error));
291
760
  }
292
761
  /**
293
762
  * @description Logs a message at the silly level
@@ -333,10 +802,11 @@ class MiniLogger {
333
802
  * @description Logs a message at the error level
334
803
  * @summary Logs a message at the error level for errors and exceptions
335
804
  * @param {StringLike | Error} msg - The message to be logged or an Error object
805
+ * @param e
336
806
  * @return {void}
337
807
  */
338
- error(msg) {
339
- this.log(LogLevel.error, msg);
808
+ error(msg, e) {
809
+ this.log(LogLevel.error, msg, e);
340
810
  }
341
811
  /**
342
812
  * @description Updates the logger configuration
@@ -421,11 +891,7 @@ class Logging {
421
891
  static { this._factory = (object, config) => {
422
892
  return new MiniLogger(object, config);
423
893
  }; }
424
- /**
425
- * @description Configuration for the logging system
426
- * @summary Stores the global logging configuration including verbosity, log level, styling, and formatting settings
427
- */
428
- static { this._config = DefaultLoggingConfig; }
894
+ static { this._config = LoggedEnvironment; }
429
895
  constructor() { }
430
896
  /**
431
897
  * @description Sets the factory function for creating logger instances
@@ -443,7 +909,9 @@ class Logging {
443
909
  * @return {void}
444
910
  */
445
911
  static setConfig(config) {
446
- Object.assign(this._config, config);
912
+ Object.entries(config).forEach(([k, v]) => {
913
+ this._config[k] = v;
914
+ });
447
915
  }
448
916
  /**
449
917
  * @description Gets a copy of the current global logging configuration
@@ -451,7 +919,7 @@ class Logging {
451
919
  * @return {LoggingConfig} A copy of the current configuration
452
920
  */
453
921
  static getConfig() {
454
- return Object.assign({}, this._config);
922
+ return this._config;
455
923
  }
456
924
  /**
457
925
  * @description Retrieves or creates the global logger instance.
@@ -505,9 +973,10 @@ class Logging {
505
973
  * @summary Delegates the error logging to the global logger instance.
506
974
  *
507
975
  * @param msg - The message to be logged.
976
+ * @param e
508
977
  */
509
- static error(msg) {
510
- return this.get().error(msg);
978
+ static error(msg, e) {
979
+ return this.get().error(msg, e);
511
980
  }
512
981
  /**
513
982
  * @description Creates a logger for a specific object or context
@@ -644,6 +1113,57 @@ class Logging {
644
1113
  }
645
1114
  }
646
1115
 
1116
+ /**
1117
+ * @description Base class that provides a ready-to-use logger instance
1118
+ * @summary LoggedClass is a convenience abstract class that injects a type-safe logger
1119
+ * into derived classes through a protected getter. Subclasses can directly access
1120
+ * this.log to emit messages without manually creating a logger. This promotes
1121
+ * consistent, context-aware logging across the codebase.
1122
+ * @param {void} [constructor] - No constructor arguments; subclasses may define their own
1123
+ * @class LoggedClass
1124
+ * @example
1125
+ * class UserService extends LoggedClass {
1126
+ * create(user: User) {
1127
+ * this.log.info(`Creating user ${user.id}`);
1128
+ * }
1129
+ * }
1130
+ *
1131
+ * const svc = new UserService();
1132
+ * svc.create({ id: "42" });
1133
+ * @mermaid
1134
+ * sequenceDiagram
1135
+ * participant Client
1136
+ * participant Instance as Subclass Instance
1137
+ * participant Getter as LoggedClass.log
1138
+ * participant Logging as Logging
1139
+ * participant Logger as Logger
1140
+ *
1141
+ * Client->>Instance: call someMethod()
1142
+ * Instance->>Getter: access this.log
1143
+ * Getter->>Logging: Logging.for(this)
1144
+ * Logging-->>Getter: return Logger
1145
+ * Getter-->>Instance: return Logger
1146
+ * Instance->>Logger: info/debug/error(...)
1147
+ */
1148
+ class LoggedClass {
1149
+ /**
1150
+ * @description Lazily provides a context-aware logger for the current instance
1151
+ * @summary Uses Logging.for(this) to create a logger whose context is the
1152
+ * subclass name, allowing uniform and structured logs from any inheriting class.
1153
+ * @return {Logger} A logger bound to the subclass context
1154
+ */
1155
+ get log() {
1156
+ return Logging.for(this);
1157
+ }
1158
+ constructor() { }
1159
+ }
1160
+
1161
+ class LogFilter extends LoggedClass {
1162
+ get log() {
1163
+ return super.log.for(this, { filters: [] });
1164
+ }
1165
+ }
1166
+
647
1167
  /**
648
1168
  * @description Method decorator for logging function calls
649
1169
  * @summary Creates a decorator that logs method calls with specified level, benchmarking, and verbosity
@@ -677,31 +1197,35 @@ class Logging {
677
1197
  */
678
1198
  function log(level = LogLevel.info, benchmark = false, verbosity = 0) {
679
1199
  return function (target, propertyKey, descriptor) {
680
- const log = Logging.for(target).for(target[propertyKey]);
681
- const method = log[level].bind(log);
1200
+ if (!descriptor)
1201
+ throw new Error(`Logging decoration only applies to methods`);
1202
+ const logger = Logging.for(target).for(target[propertyKey]);
1203
+ const method = logger[level].bind(logger);
682
1204
  const originalMethod = descriptor.value;
683
- descriptor.value = function (...args) {
684
- method(`called with ${args}`, verbosity);
685
- const start = Date.now();
686
- let end;
687
- const result = originalMethod.apply(this, args);
688
- if (result instanceof Promise) {
689
- return result.then((r) => {
690
- if (benchmark) {
691
- end = Date.now();
692
- if (benchmark)
693
- method(`completed in ${end - start}ms`, verbosity);
1205
+ descriptor.value = new Proxy(originalMethod, {
1206
+ apply(fn, thisArg, args) {
1207
+ method(`called with ${args}`, verbosity);
1208
+ const start = Date.now();
1209
+ try {
1210
+ const result = Reflect.apply(fn, thisArg, args);
1211
+ if (result instanceof Promise) {
1212
+ return result.then((r) => {
1213
+ if (benchmark)
1214
+ method(`completed in ${Date.now() - start}ms`, verbosity);
1215
+ return r;
1216
+ });
694
1217
  }
695
- return r;
696
- });
697
- }
698
- if (benchmark) {
699
- end = Date.now();
700
- if (benchmark)
701
- method(`completed in ${end - start}ms`, verbosity);
702
- }
703
- return result;
704
- };
1218
+ if (benchmark)
1219
+ method(`completed in ${Date.now() - start}ms`, verbosity);
1220
+ return result;
1221
+ }
1222
+ catch (err) {
1223
+ if (benchmark)
1224
+ method(`failed in ${Date.now() - start}ms`, verbosity);
1225
+ throw err;
1226
+ }
1227
+ },
1228
+ });
705
1229
  };
706
1230
  }
707
1231
  /**
@@ -753,51 +1277,56 @@ function verbose(verbosity = 0, benchmark) {
753
1277
  }
754
1278
  return log(LogLevel.verbose, benchmark, verbosity);
755
1279
  }
756
-
757
1280
  /**
758
- * @description Base class that provides a ready-to-use logger instance
759
- * @summary LoggedClass is a convenience abstract class that injects a type-safe logger
760
- * into derived classes through a protected getter. Subclasses can directly access
761
- * this.log to emit messages without manually creating a logger. This promotes
762
- * consistent, context-aware logging across the codebase.
763
- * @param {void} [constructor] - No constructor arguments; subclasses may define their own
764
- * @class LoggedClass
765
- * @example
766
- * class UserService extends LoggedClass {
767
- * create(user: User) {
768
- * this.log.info(`Creating user ${user.id}`);
769
- * }
770
- * }
771
- *
772
- * const svc = new UserService();
773
- * svc.create({ id: "42" });
774
- * @mermaid
775
- * sequenceDiagram
776
- * participant Client
777
- * participant Instance as Subclass Instance
778
- * participant Getter as LoggedClass.log
779
- * participant Logging as Logging
780
- * participant Logger as Logger
781
- *
782
- * Client->>Instance: call someMethod()
783
- * Instance->>Getter: access this.log
784
- * Getter->>Logging: Logging.for(this)
785
- * Logging-->>Getter: return Logger
786
- * Getter-->>Instance: return Logger
787
- * Instance->>Logger: info/debug/error(...)
1281
+ * @description Creates a decorator that makes a method non-configurable
1282
+ * @summary This decorator prevents a method from being overridden by making it non-configurable.
1283
+ * It throws an error if used on anything other than a method.
1284
+ * @return {Function} A decorator function that can be applied to methods
1285
+ * @function final
1286
+ * @category Method Decorators
788
1287
  */
789
- class LoggedClass {
790
- /**
791
- * @description Lazily provides a context-aware logger for the current instance
792
- * @summary Uses Logging.for(this) to create a logger whose context is the
793
- * subclass name, allowing uniform and structured logs from any inheriting class.
794
- * @return {Logger} A logger bound to the subclass context
795
- */
796
- get log() {
797
- return Logging.for(this);
1288
+ function final() {
1289
+ return (target, propertyKey, descriptor) => {
1290
+ if (!descriptor)
1291
+ throw new Error("final decorator can only be used on methods");
1292
+ if (descriptor?.configurable) {
1293
+ descriptor.configurable = false;
1294
+ }
1295
+ return descriptor;
1296
+ };
1297
+ }
1298
+
1299
+ class PatternFilter extends LogFilter {
1300
+ constructor(regexp, replacement) {
1301
+ super();
1302
+ this.regexp = regexp;
1303
+ this.replacement = replacement;
1304
+ }
1305
+ match(message) {
1306
+ const match = this.regexp.exec(message);
1307
+ this.regexp.lastIndex = 0;
1308
+ return match;
1309
+ }
1310
+ filter(config, message, context) {
1311
+ const log = this.log.for(this.filter);
1312
+ const match = this.match(message);
1313
+ if (!match)
1314
+ return message;
1315
+ try {
1316
+ return message.replace(this.regexp, this.replacement);
1317
+ }
1318
+ catch (e) {
1319
+ log.error(`PatternFilter replacement error: ${e}`);
1320
+ }
1321
+ return "";
798
1322
  }
799
- constructor() { }
800
1323
  }
1324
+ __decorate([
1325
+ final(),
1326
+ __metadata("design:type", Function),
1327
+ __metadata("design:paramtypes", [String]),
1328
+ __metadata("design:returntype", void 0)
1329
+ ], PatternFilter.prototype, "match", null);
801
1330
 
802
1331
  /**
803
1332
  * @description A logging module for TypeScript applications
@@ -815,7 +1344,7 @@ class LoggedClass {
815
1344
  * @const VERSION
816
1345
  * @memberOf module:Logging
817
1346
  */
818
- const VERSION = "0.3.7";
1347
+ const VERSION = "0.3.9";
819
1348
 
820
- export { DefaultLoggingConfig, DefaultTheme, LogLevel, LoggedClass, Logging, LoggingMode, MiniLogger, NumericLogLevels, VERSION, debug, info, log, silly, verbose };
821
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2luZy5lc20uY2pzIiwic291cmNlcyI6WyIuLi9zcmMvY29uc3RhbnRzLnRzIiwiLi4vc3JjL2xvZ2dpbmcudHMiLCIuLi9zcmMvZGVjb3JhdG9ycy50cyIsIi4uL3NyYy9Mb2dnZWRDbGFzcy50cyIsIi4uL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMb2dnaW5nQ29uZmlnLCBUaGVtZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVudW0gZm9yIGxvZyBsZXZlbHMuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGRpZmZlcmVudCBsZXZlbHMgb2YgbG9nZ2luZyBmb3IgdGhlIGFwcGxpY2F0aW9uLlxuICogQGVudW0ge3N0cmluZ31cbiAqIEByZWFkb25seVxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBlbnVtIExvZ0xldmVsIHtcbiAgLyoqIEVycm9yIGV2ZW50cyB0aGF0IGFyZSBsaWtlbHkgdG8gY2F1c2UgcHJvYmxlbXMuICovXG4gIGVycm9yID0gXCJlcnJvclwiLFxuICAvKiogUm91dGluZSBpbmZvcm1hdGlvbiwgc3VjaCBhcyBvbmdvaW5nIHN0YXR1cyBvciBwZXJmb3JtYW5jZS4gKi9cbiAgaW5mbyA9IFwiaW5mb1wiLFxuICAvKiogQWRkaXRpb25hbCByZWxldmFudCBpbmZvcm1hdGlvbi4gKi9cbiAgdmVyYm9zZSA9IFwidmVyYm9zZVwiLFxuICAvKiogRGVidWcgb3IgdHJhY2UgaW5mb3JtYXRpb24uICovXG4gIGRlYnVnID0gXCJkZWJ1Z1wiLFxuICAvKiogd2F5IHRvbyB2ZXJib3NlIG9yIHNpbGx5IGluZm9ybWF0aW9uLiAqL1xuICBzaWxseSA9IFwic2lsbHlcIixcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTnVtZXJpYyB2YWx1ZXMgYXNzb2NpYXRlZCB3aXRoIGxvZyBsZXZlbHMuXG4gKiBAc3VtbWFyeSBQcm92aWRlcyBhIG51bWVyaWMgcmVwcmVzZW50YXRpb24gb2YgbG9nIGxldmVscyBmb3IgY29tcGFyaXNvbiBhbmQgZmlsdGVyaW5nLlxuICogQGNvbnN0IE51bWVyaWNMb2dMZXZlbHNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBlcnJvciAtIE51bWVyaWMgdmFsdWUgZm9yIGVycm9yIGxldmVsICgyKS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBpbmZvIC0gTnVtZXJpYyB2YWx1ZSBmb3IgaW5mbyBsZXZlbCAoNCkuXG4gKiBAcHJvcGVydHkge251bWJlcn0gdmVyYm9zZSAtIE51bWVyaWMgdmFsdWUgZm9yIHZlcmJvc2UgbGV2ZWwgKDYpLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGRlYnVnIC0gTnVtZXJpYyB2YWx1ZSBmb3IgZGVidWcgbGV2ZWwgKDcpLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IHNpbGx5IC0gTnVtZXJpYyB2YWx1ZSBmb3Igc2lsbHkgbGV2ZWwgKDkpLlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBOdW1lcmljTG9nTGV2ZWxzID0ge1xuICBlcnJvcjogMixcbiAgaW5mbzogNCxcbiAgdmVyYm9zZTogNixcbiAgZGVidWc6IDcsXG4gIHNpbGx5OiA5LFxufTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRW51bSBmb3IgbG9nZ2luZyBvdXRwdXQgbW9kZXMuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGRpZmZlcmVudCBvdXRwdXQgZm9ybWF0cyBmb3IgbG9nIG1lc3NhZ2VzLlxuICogQGVudW0ge3N0cmluZ31cbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZW51bSBMb2dnaW5nTW9kZSB7XG4gIC8qKiBSYXcgdGV4dCBmb3JtYXQgZm9yIGh1bWFuIHJlYWRhYmlsaXR5ICovXG4gIFJBVyA9IFwicmF3XCIsXG4gIC8qKiBKU09OIGZvcm1hdCBmb3IgbWFjaGluZSBwYXJzaW5nICovXG4gIEpTT04gPSBcImpzb25cIixcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVmYXVsdCB0aGVtZSBmb3Igc3R5bGluZyBsb2cgb3V0cHV0LlxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgZGVmYXVsdCBjb2xvciBhbmQgc3R5bGUgc2V0dGluZ3MgZm9yIHZhcmlvdXMgY29tcG9uZW50cyBvZiBsb2cgbWVzc2FnZXMuXG4gKiBAY29uc3QgRGVmYXVsdFRoZW1lXG4gKiBAdHlwZWRlZiB7VGhlbWV9IERlZmF1bHRUaGVtZVxuICogQHByb3BlcnR5IHtPYmplY3R9IGNsYXNzIC0gU3R5bGluZyBmb3IgY2xhc3MgbmFtZXMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gY2xhc3MuZmcgLSBGb3JlZ3JvdW5kIGNvbG9yIGNvZGUgZm9yIGNsYXNzIG5hbWVzICgzNCkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gaWQgLSBTdHlsaW5nIGZvciBpZGVudGlmaWVycy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBpZC5mZyAtIEZvcmVncm91bmQgY29sb3IgY29kZSBmb3IgaWRlbnRpZmllcnMgKDM2KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBzdGFjayAtIFN0eWxpbmcgZm9yIHN0YWNrIHRyYWNlcyAoZW1wdHkgb2JqZWN0KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB0aW1lc3RhbXAgLSBTdHlsaW5nIGZvciB0aW1lc3RhbXBzIChlbXB0eSBvYmplY3QpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IG1lc3NhZ2UgLSBTdHlsaW5nIGZvciBkaWZmZXJlbnQgdHlwZXMgb2YgbWVzc2FnZXMuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbWVzc2FnZS5lcnJvciAtIFN0eWxpbmcgZm9yIGVycm9yIG1lc3NhZ2VzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IG1lc3NhZ2UuZXJyb3IuZmcgLSBGb3JlZ3JvdW5kIGNvbG9yIGNvZGUgZm9yIGVycm9yIG1lc3NhZ2VzICgzMSkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbWV0aG9kIC0gU3R5bGluZyBmb3IgbWV0aG9kIG5hbWVzIChlbXB0eSBvYmplY3QpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGxvZ0xldmVsIC0gU3R5bGluZyBmb3IgZGlmZmVyZW50IGxvZyBsZXZlbHMuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nTGV2ZWwuZXJyb3IgLSBTdHlsaW5nIGZvciBlcnJvciBsZXZlbCBsb2dzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGxvZ0xldmVsLmVycm9yLmZnIC0gRm9yZWdyb3VuZCBjb2xvciBjb2RlIGZvciBlcnJvciBsZXZlbCBsb2dzICgzMSkuXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBsb2dMZXZlbC5lcnJvci5zdHlsZSAtIFN0eWxlIGF0dHJpYnV0ZXMgZm9yIGVycm9yIGxldmVsIGxvZ3MgKFtcImJvbGRcIl0pLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGxvZ0xldmVsLmluZm8gLSBTdHlsaW5nIGZvciBpbmZvIGxldmVsIGxvZ3MgKGVtcHR5IG9iamVjdCkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nTGV2ZWwudmVyYm9zZSAtIFN0eWxpbmcgZm9yIHZlcmJvc2UgbGV2ZWwgbG9ncyAoZW1wdHkgb2JqZWN0KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2dMZXZlbC5kZWJ1ZyAtIFN0eWxpbmcgZm9yIGRlYnVnIGxldmVsIGxvZ3MuXG4gKiBAcHJvcGVydHkge251bWJlcn0gbG9nTGV2ZWwuZGVidWcuZmcgLSBGb3JlZ3JvdW5kIGNvbG9yIGNvZGUgZm9yIGRlYnVnIGxldmVsIGxvZ3MgKDMzKS5cbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3QgRGVmYXVsdFRoZW1lOiBUaGVtZSA9IHtcbiAgY2xhc3M6IHtcbiAgICBmZzogMzQsXG4gIH0sXG4gIGlkOiB7XG4gICAgZmc6IDM2LFxuICB9LFxuICBzdGFjazoge30sXG4gIHRpbWVzdGFtcDoge30sXG4gIG1lc3NhZ2U6IHtcbiAgICBlcnJvcjoge1xuICAgICAgZmc6IDMxLFxuICAgIH0sXG4gIH0sXG4gIG1ldGhvZDoge30sXG4gIGxvZ0xldmVsOiB7XG4gICAgZXJyb3I6IHtcbiAgICAgIGZnOiAzMSxcbiAgICAgIHN0eWxlOiBbXCJib2xkXCJdLFxuICAgIH0sXG4gICAgaW5mbzoge30sXG4gICAgdmVyYm9zZToge30sXG4gICAgZGVidWc6IHtcbiAgICAgIGZnOiAzMyxcbiAgICB9LFxuICB9LFxufTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVmYXVsdCBjb25maWd1cmF0aW9uIGZvciBsb2dnaW5nLlxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgZGVmYXVsdCBzZXR0aW5ncyBmb3IgdGhlIGxvZ2dpbmcgc3lzdGVtLCBpbmNsdWRpbmcgdmVyYm9zaXR5LCBsb2cgbGV2ZWwsIHN0eWxpbmcsIGFuZCB0aW1lc3RhbXAgZm9ybWF0LlxuICogQGNvbnN0IERlZmF1bHRMb2dnaW5nQ29uZmlnXG4gKiBAdHlwZWRlZiB7TG9nZ2luZ0NvbmZpZ30gRGVmYXVsdExvZ2dpbmdDb25maWdcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB2ZXJib3NlIC0gVmVyYm9zaXR5IGxldmVsICgwKS5cbiAqIEBwcm9wZXJ0eSB7TG9nTGV2ZWx9IGxldmVsIC0gRGVmYXVsdCBsb2cgbGV2ZWwgKExvZ0xldmVsLmluZm8pLlxuICogQHByb3BlcnR5IHtib29sZWFufSBsb2dMZXZlbCAtIFdoZXRoZXIgdG8gZGlzcGxheSBsb2cgbGV2ZWwgaW4gb3V0cHV0ICh0cnVlKS5cbiAqIEBwcm9wZXJ0eSB7TG9nZ2luZ01vZGV9IG1vZGUgLSBPdXRwdXQgZm9ybWF0IG1vZGUgKExvZ2dpbmdNb2RlLlJBVykuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHN0eWxlIC0gV2hldGhlciB0byBhcHBseSBzdHlsaW5nIHRvIGxvZyBvdXRwdXQgKGZhbHNlKS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzZXBhcmF0b3IgLSBTZXBhcmF0b3IgYmV0d2VlbiBsb2cgY29tcG9uZW50cyAoXCIgLSBcIikuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHRpbWVzdGFtcCAtIFdoZXRoZXIgdG8gaW5jbHVkZSB0aW1lc3RhbXBzIGluIGxvZyBtZXNzYWdlcyAodHJ1ZSkuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdGltZXN0YW1wRm9ybWF0IC0gRm9ybWF0IGZvciB0aW1lc3RhbXBzIChcIkhIOm1tOnNzLlNTU1wiKS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gY29udGV4dCAtIFdoZXRoZXIgdG8gaW5jbHVkZSBjb250ZXh0IGluZm9ybWF0aW9uIGluIGxvZyBtZXNzYWdlcyAodHJ1ZSkuXG4gKiBAcHJvcGVydHkge1RoZW1lfSB0aGVtZSAtIFRoZSB0aGVtZSB0byB1c2UgZm9yIHN0eWxpbmcgbG9nIG1lc3NhZ2VzIChEZWZhdWx0VGhlbWUpLlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBEZWZhdWx0TG9nZ2luZ0NvbmZpZzogTG9nZ2luZ0NvbmZpZyA9IHtcbiAgdmVyYm9zZTogMCxcbiAgbGV2ZWw6IExvZ0xldmVsLmluZm8sXG4gIGxvZ0xldmVsOiB0cnVlLFxuICBtb2RlOiBMb2dnaW5nTW9kZS5SQVcsXG4gIHN0eWxlOiBmYWxzZSxcbiAgY29udGV4dFNlcGFyYXRvcjogXCIuXCIsXG4gIHNlcGFyYXRvcjogXCIgLSBcIixcbiAgdGltZXN0YW1wOiB0cnVlLFxuICB0aW1lc3RhbXBGb3JtYXQ6IFwiSEg6bW06c3MuU1NTXCIsXG4gIGNvbnRleHQ6IHRydWUsXG4gIHRoZW1lOiBEZWZhdWx0VGhlbWUsXG59O1xuIiwiaW1wb3J0IHtcbiAgTG9nZ2VyRmFjdG9yeSxcbiAgTG9nZ2luZ0NvbmZpZyxcbiAgTG9nZ2luZ0NvbnRleHQsXG4gIFN0cmluZ0xpa2UsXG4gIFRoZW1lLFxuICBUaGVtZU9wdGlvbixcbiAgVGhlbWVPcHRpb25CeUxvZ0xldmVsLFxuICBMb2dnZXIsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBDb2xvcml6ZU9wdGlvbnMsIHN0eWxlLCBTdHlsZWRTdHJpbmcgfSBmcm9tIFwic3R5bGVkLXN0cmluZy1idWlsZGVyXCI7XG5pbXBvcnQge1xuICBEZWZhdWx0TG9nZ2luZ0NvbmZpZyxcbiAgRGVmYXVsdFRoZW1lLFxuICBMb2dMZXZlbCxcbiAgTnVtZXJpY0xvZ0xldmVscyxcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgbWluaW1hbCBsb2dnZXIgaW1wbGVtZW50YXRpb24uXG4gKiBAc3VtbWFyeSBNaW5pTG9nZ2VyIGlzIGEgbGlnaHR3ZWlnaHQgbG9nZ2luZyBjbGFzcyB0aGF0IGltcGxlbWVudHMgdGhlIExvZ2dlciBpbnRlcmZhY2UuXG4gKiBJdCBwcm92aWRlcyBiYXNpYyBsb2dnaW5nIGZ1bmN0aW9uYWxpdHkgd2l0aCBzdXBwb3J0IGZvciBkaWZmZXJlbnQgbG9nIGxldmVscywgdmVyYm9zaXR5LFxuICogY29udGV4dC1hd2FyZSBsb2dnaW5nLCBhbmQgY3VzdG9taXphYmxlIGZvcm1hdHRpbmcuXG4gKiBAcGFyYW0ge3N0cmluZ30gY29udGV4dCAtIFRoZSBjb250ZXh0ICh0eXBpY2FsbHkgY2xhc3MgbmFtZSkgdGhpcyBsb2dnZXIgaXMgYXNzb2NpYXRlZCB3aXRoXG4gKiBAcGFyYW0ge1BhcnRpYWw8TG9nZ2luZ0NvbmZpZz59IGNvbmYgLSBPcHRpb25hbCBjb25maWd1cmF0aW9uIHRvIG92ZXJyaWRlIGdsb2JhbCBzZXR0aW5nc1xuICogQGNsYXNzIE1pbmlMb2dnZXJcbiAqIEBleGFtcGxlXG4gKiAvLyBDcmVhdGUgYSBuZXcgbG9nZ2VyIGZvciBhIGNsYXNzXG4gKiBjb25zdCBsb2dnZXIgPSBuZXcgTWluaUxvZ2dlcignTXlDbGFzcycpO1xuICpcbiAqIC8vIExvZyBtZXNzYWdlcyBhdCBkaWZmZXJlbnQgbGV2ZWxzXG4gKiBsb2dnZXIuaW5mbygnVGhpcyBpcyBhbiBpbmZvIG1lc3NhZ2UnKTtcbiAqIGxvZ2dlci5kZWJ1ZygnVGhpcyBpcyBhIGRlYnVnIG1lc3NhZ2UnKTtcbiAqIGxvZ2dlci5lcnJvcignU29tZXRoaW5nIHdlbnQgd3JvbmcnKTtcbiAqXG4gKiAvLyBDcmVhdGUgYSBjaGlsZCBsb2dnZXIgZm9yIGEgc3BlY2lmaWMgbWV0aG9kXG4gKiBjb25zdCBtZXRob2RMb2dnZXIgPSBsb2dnZXIuZm9yKCdteU1ldGhvZCcpO1xuICogbWV0aG9kTG9nZ2VyLnZlcmJvc2UoJ0RldGFpbGVkIGluZm9ybWF0aW9uJywgMik7XG4gKlxuICogLy8gTG9nIHdpdGggY3VzdG9tIGNvbmZpZ3VyYXRpb25cbiAqIGxvZ2dlci5mb3IoJ3NwZWNpYWxNZXRob2QnLCB7IHN0eWxlOiB0cnVlIH0pLmluZm8oJ1N0eWxlZCBtZXNzYWdlJyk7XG4gKi9cbmV4cG9ydCBjbGFzcyBNaW5pTG9nZ2VyIGltcGxlbWVudHMgTG9nZ2VyIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIGNvbnRleHQ6IHN0cmluZyxcbiAgICBwcm90ZWN0ZWQgY29uZj86IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz5cbiAgKSB7fVxuXG4gIHByb3RlY3RlZCBjb25maWcoXG4gICAga2V5OiBrZXlvZiBMb2dnaW5nQ29uZmlnXG4gICk6IExvZ2dpbmdDb25maWdba2V5b2YgTG9nZ2luZ0NvbmZpZ10ge1xuICAgIGlmICh0aGlzLmNvbmYgJiYga2V5IGluIHRoaXMuY29uZikgcmV0dXJuIHRoaXMuY29uZltrZXldO1xuICAgIHJldHVybiBMb2dnaW5nLmdldENvbmZpZygpW2tleV07XG4gIH1cblxuICBmb3IobWV0aG9kOiBzdHJpbmcgfCAoKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnkpKTogTG9nZ2VyO1xuICBmb3IoY29uZmlnOiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+KTogTG9nZ2VyO1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBjaGlsZCBsb2dnZXIgZm9yIGEgc3BlY2lmaWMgbWV0aG9kIG9yIGNvbnRleHRcbiAgICogQHN1bW1hcnkgUmV0dXJucyBhIG5ldyBsb2dnZXIgaW5zdGFuY2Ugd2l0aCB0aGUgY3VycmVudCBjb250ZXh0IGV4dGVuZGVkIGJ5IHRoZSBzcGVjaWZpZWQgbWV0aG9kIG5hbWVcbiAgICogQHBhcmFtIHtzdHJpbmcgfCBGdW5jdGlvbn0gbWV0aG9kIC0gVGhlIG1ldGhvZCBuYW1lIG9yIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIGxvZ2dlciBmb3JcbiAgICogQHBhcmFtIHtQYXJ0aWFsPExvZ2dpbmdDb25maWc+fSBjb25maWcgLSBPcHRpb25hbCBjb25maWd1cmF0aW9uIHRvIG92ZXJyaWRlIHNldHRpbmdzXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBsb2dnZXIgZmFjdG9yeVxuICAgKiBAcmV0dXJuIHtMb2dnZXJ9IEEgbmV3IGxvZ2dlciBpbnN0YW5jZSBmb3IgdGhlIHNwZWNpZmllZCBtZXRob2RcbiAgICovXG4gIGZvcihcbiAgICBtZXRob2Q/OiBzdHJpbmcgfCAoKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnkpIHwgUGFydGlhbDxMb2dnaW5nQ29uZmlnPixcbiAgICBjb25maWc/OiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+LFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBMb2dnZXIge1xuICAgIGlmICghY29uZmlnICYmIHR5cGVvZiBtZXRob2QgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIGNvbmZpZyA9IG1ldGhvZDtcbiAgICAgIG1ldGhvZCA9IHVuZGVmaW5lZDtcbiAgICB9IGVsc2Uge1xuICAgICAgbWV0aG9kID0gbWV0aG9kXG4gICAgICAgID8gdHlwZW9mIG1ldGhvZCA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgID8gbWV0aG9kXG4gICAgICAgICAgOiAobWV0aG9kIGFzIGFueSkubmFtZVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb3h5KHRoaXMsIHtcbiAgICAgIGdldDogKHRhcmdldDogdHlwZW9mIHRoaXMsIHA6IHN0cmluZyB8IHN5bWJvbCwgcmVjZWl2ZXI6IGFueSkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBSZWZsZWN0LmdldCh0YXJnZXQsIHAsIHJlY2VpdmVyKTtcbiAgICAgICAgaWYgKHAgPT09IFwiY29uZmlnXCIpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFByb3h5KHRoaXMuY29uZmlnLCB7XG4gICAgICAgICAgICBnZXQ6ICh0YXJnZXQ6IHR5cGVvZiB0aGlzLmNvbmZpZywgcDogc3RyaW5nIHwgc3ltYm9sKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChjb25maWcgJiYgcCBpbiBjb25maWcpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbmZpZ1twIGFzIGtleW9mIExvZ2dpbmdDb25maWddO1xuICAgICAgICAgICAgICByZXR1cm4gUmVmbGVjdC5nZXQodGFyZ2V0LCBwLCByZWNlaXZlcik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwID09PSBcImNvbnRleHRcIiAmJiBtZXRob2QpIHtcbiAgICAgICAgICByZXR1cm4gW3Jlc3VsdCwgbWV0aG9kXS5qb2luKFwiLlwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGZvcm1hdHRlZCBsb2cgc3RyaW5nXG4gICAqIEBzdW1tYXJ5IEdlbmVyYXRlcyBhIGxvZyBzdHJpbmcgd2l0aCB0aW1lc3RhbXAsIGNvbG9yZWQgbG9nIGxldmVsLCBjb250ZXh0LCBhbmQgbWVzc2FnZVxuICAgKiBAcGFyYW0ge0xvZ0xldmVsfSBsZXZlbCAtIFRoZSBsb2cgbGV2ZWwgZm9yIHRoaXMgbWVzc2FnZVxuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2UgfCBFcnJvcn0gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGxvZyBvciBhbiBFcnJvciBvYmplY3RcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtzdGFja10gLSBPcHRpb25hbCBzdGFjayB0cmFjZSB0byBpbmNsdWRlIGluIHRoZSBsb2dcbiAgICogQHJldHVybiB7c3RyaW5nfSBBIGZvcm1hdHRlZCBsb2cgc3RyaW5nIHdpdGggYWxsIGNvbXBvbmVudHNcbiAgICovXG4gIHByb3RlY3RlZCBjcmVhdGVMb2coXG4gICAgbGV2ZWw6IExvZ0xldmVsLFxuICAgIG1lc3NhZ2U6IFN0cmluZ0xpa2UgfCBFcnJvcixcbiAgICBzdGFjaz86IHN0cmluZ1xuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IGxvZzogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBzdHlsZSA9IHRoaXMuY29uZmlnKFwic3R5bGVcIik7XG4gICAgaWYgKHRoaXMuY29uZmlnKFwidGltZXN0YW1wXCIpKSB7XG4gICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuICAgICAgY29uc3QgdGltZXN0YW1wID0gc3R5bGUgPyBMb2dnaW5nLnRoZW1lKGRhdGUsIFwidGltZXN0YW1wXCIsIGxldmVsKSA6IGRhdGU7XG4gICAgICBsb2cucHVzaCh0aW1lc3RhbXApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZyhcImxvZ0xldmVsXCIpKSB7XG4gICAgICBjb25zdCBsdmw6IHN0cmluZyA9IHN0eWxlXG4gICAgICAgID8gTG9nZ2luZy50aGVtZShsZXZlbCwgXCJsb2dMZXZlbFwiLCBsZXZlbClcbiAgICAgICAgOiBsZXZlbDtcbiAgICAgIGxvZy5wdXNoKGx2bCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnKFwiY29udGV4dFwiKSkge1xuICAgICAgY29uc3QgY29udGV4dDogc3RyaW5nID0gc3R5bGVcbiAgICAgICAgPyBMb2dnaW5nLnRoZW1lKHRoaXMuY29udGV4dCwgXCJjbGFzc1wiLCBsZXZlbClcbiAgICAgICAgOiB0aGlzLmNvbnRleHQ7XG4gICAgICBsb2cucHVzaChjb250ZXh0KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWcoXCJjb3JyZWxhdGlvbklkXCIpKSB7XG4gICAgICB7XG4gICAgICAgIGNvbnN0IGlkOiBzdHJpbmcgPSBzdHlsZVxuICAgICAgICAgID8gTG9nZ2luZy50aGVtZSh0aGlzLmNvbmZpZyhcImNvcnJlbGF0aW9uSWRcIikhLnRvU3RyaW5nKCksIFwiaWRcIiwgbGV2ZWwpXG4gICAgICAgICAgOiB0aGlzLmNvbmZpZyhcImNvcnJlbGF0aW9uSWRcIikhLnRvU3RyaW5nKCk7XG4gICAgICAgIGxvZy5wdXNoKGlkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBtc2c6IHN0cmluZyA9IHN0eWxlXG4gICAgICA/IExvZ2dpbmcudGhlbWUoXG4gICAgICAgICAgdHlwZW9mIG1lc3NhZ2UgPT09IFwic3RyaW5nXCIgPyBtZXNzYWdlIDogKG1lc3NhZ2UgYXMgRXJyb3IpLm1lc3NhZ2UsXG4gICAgICAgICAgXCJtZXNzYWdlXCIsXG4gICAgICAgICAgbGV2ZWxcbiAgICAgICAgKVxuICAgICAgOiB0eXBlb2YgbWVzc2FnZSA9PT0gXCJzdHJpbmdcIlxuICAgICAgICA/IG1lc3NhZ2VcbiAgICAgICAgOiAobWVzc2FnZSBhcyBFcnJvcikubWVzc2FnZTtcbiAgICBsb2cucHVzaChtc2cpO1xuICAgIGlmIChzdGFjayB8fCBtZXNzYWdlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHN0YWNrID0gc3R5bGVcbiAgICAgICAgPyBMb2dnaW5nLnRoZW1lKFxuICAgICAgICAgICAgKHN0YWNrIHx8IChtZXNzYWdlIGFzIEVycm9yKS5zdGFjaykgYXMgc3RyaW5nLFxuICAgICAgICAgICAgXCJzdGFja1wiLFxuICAgICAgICAgICAgbGV2ZWxcbiAgICAgICAgICApXG4gICAgICAgIDogc3RhY2s7XG4gICAgICBsb2cucHVzaChgXFxuU3RhY2sgdHJhY2U6XFxuJHtzdGFja31gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbG9nLmpvaW4odGhpcy5jb25maWcoXCJzZXBhcmF0b3JcIikgYXMgc3RyaW5nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGxvZyBsZXZlbFxuICAgKiBAc3VtbWFyeSBDaGVja3MgaWYgdGhlIG1lc3NhZ2Ugc2hvdWxkIGJlIGxvZ2dlZCBiYXNlZCBvbiB0aGUgY3VycmVudCBsb2cgbGV2ZWwsXG4gICAqIHRoZW4gdXNlcyB0aGUgYXBwcm9wcmlhdGUgY29uc29sZSBtZXRob2QgdG8gb3V0cHV0IHRoZSBmb3JtYXR0ZWQgbG9nXG4gICAqIEBwYXJhbSB7TG9nTGV2ZWx9IGxldmVsIC0gVGhlIGxvZyBsZXZlbCBvZiB0aGUgbWVzc2FnZVxuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2UgfCBFcnJvcn0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkIG9yIGFuIEVycm9yIG9iamVjdFxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0YWNrXSAtIE9wdGlvbmFsIHN0YWNrIHRyYWNlIHRvIGluY2x1ZGUgaW4gdGhlIGxvZ1xuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgcHJvdGVjdGVkIGxvZyhcbiAgICBsZXZlbDogTG9nTGV2ZWwsXG4gICAgbXNnOiBTdHJpbmdMaWtlIHwgRXJyb3IsXG4gICAgc3RhY2s/OiBzdHJpbmdcbiAgKTogdm9pZCB7XG4gICAgaWYgKFxuICAgICAgTnVtZXJpY0xvZ0xldmVsc1t0aGlzLmNvbmZpZyhcImxldmVsXCIpIGFzIExvZ0xldmVsXSA8XG4gICAgICBOdW1lcmljTG9nTGV2ZWxzW2xldmVsXVxuICAgIClcbiAgICAgIHJldHVybjtcbiAgICBsZXQgbWV0aG9kO1xuICAgIHN3aXRjaCAobGV2ZWwpIHtcbiAgICAgIGNhc2UgTG9nTGV2ZWwuaW5mbzpcbiAgICAgICAgbWV0aG9kID0gY29uc29sZS5sb2c7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBMb2dMZXZlbC52ZXJib3NlOlxuICAgICAgY2FzZSBMb2dMZXZlbC5kZWJ1ZzpcbiAgICAgICAgbWV0aG9kID0gY29uc29sZS5kZWJ1ZztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIExvZ0xldmVsLmVycm9yOlxuICAgICAgICBtZXRob2QgPSBjb25zb2xlLmVycm9yO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgbG9nIGxldmVsXCIpO1xuICAgIH1cbiAgICBtZXRob2QodGhpcy5jcmVhdGVMb2cobGV2ZWwsIG1zZywgc3RhY2spKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIHNpbGx5IGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBzaWxseSBsZXZlbCBpZiB0aGUgY3VycmVudCB2ZXJib3NpdHkgc2V0dGluZyBhbGxvd3MgaXRcbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWRcbiAgICogQHBhcmFtIHtudW1iZXJ9IFt2ZXJib3NpdHk9MF0gLSBUaGUgdmVyYm9zaXR5IGxldmVsIG9mIHRoZSBtZXNzYWdlXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzaWxseShtc2c6IFN0cmluZ0xpa2UsIHZlcmJvc2l0eTogbnVtYmVyID0gMCk6IHZvaWQge1xuICAgIGlmICgodGhpcy5jb25maWcoXCJ2ZXJib3NlXCIpIGFzIG51bWJlcikgPj0gdmVyYm9zaXR5KVxuICAgICAgdGhpcy5sb2coTG9nTGV2ZWwudmVyYm9zZSwgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIHZlcmJvc2UgbGV2ZWxcbiAgICogQHN1bW1hcnkgTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIHZlcmJvc2UgbGV2ZWwgaWYgdGhlIGN1cnJlbnQgdmVyYm9zaXR5IHNldHRpbmcgYWxsb3dzIGl0XG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZX0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbdmVyYm9zaXR5PTBdIC0gVGhlIHZlcmJvc2l0eSBsZXZlbCBvZiB0aGUgbWVzc2FnZVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgdmVyYm9zZShtc2c6IFN0cmluZ0xpa2UsIHZlcmJvc2l0eTogbnVtYmVyID0gMCk6IHZvaWQge1xuICAgIGlmICgodGhpcy5jb25maWcoXCJ2ZXJib3NlXCIpIGFzIG51bWJlcikgPj0gdmVyYm9zaXR5KVxuICAgICAgdGhpcy5sb2coTG9nTGV2ZWwudmVyYm9zZSwgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGluZm8gbGV2ZWxcbiAgICogQHN1bW1hcnkgTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGluZm8gbGV2ZWwgZm9yIGdlbmVyYWwgYXBwbGljYXRpb24gaW5mb3JtYXRpb25cbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWRcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIGluZm8obXNnOiBTdHJpbmdMaWtlKTogdm9pZCB7XG4gICAgdGhpcy5sb2coTG9nTGV2ZWwuaW5mbywgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGRlYnVnIGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBkZWJ1ZyBsZXZlbCBmb3IgZGV0YWlsZWQgdHJvdWJsZXNob290aW5nIGluZm9ybWF0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZX0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBkZWJ1Zyhtc2c6IFN0cmluZ0xpa2UpOiB2b2lkIHtcbiAgICB0aGlzLmxvZyhMb2dMZXZlbC5kZWJ1ZywgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGVycm9yIGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBlcnJvciBsZXZlbCBmb3IgZXJyb3JzIGFuZCBleGNlcHRpb25zXG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZSB8IEVycm9yfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQgb3IgYW4gRXJyb3Igb2JqZWN0XG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBlcnJvcihtc2c6IFN0cmluZ0xpa2UgfCBFcnJvcik6IHZvaWQge1xuICAgIHRoaXMubG9nKExvZ0xldmVsLmVycm9yLCBtc2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBVcGRhdGVzIHRoZSBsb2dnZXIgY29uZmlndXJhdGlvblxuICAgKiBAc3VtbWFyeSBNZXJnZXMgdGhlIHByb3ZpZGVkIGNvbmZpZ3VyYXRpb24gd2l0aCB0aGUgZXhpc3RpbmcgY29uZmlndXJhdGlvblxuICAgKiBAcGFyYW0ge1BhcnRpYWw8TG9nZ2luZ0NvbmZpZz59IGNvbmZpZyAtIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gYXBwbHlcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHNldENvbmZpZyhjb25maWc6IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4pOiB2b2lkIHtcbiAgICB0aGlzLmNvbmYgPSB7IC4uLih0aGlzLmNvbmYgfHwge30pLCAuLi5jb25maWcgfTtcbiAgfVxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBIHN0YXRpYyBjbGFzcyBmb3IgbWFuYWdpbmcgbG9nZ2luZyBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBUaGUgTG9nZ2luZyBjbGFzcyBwcm92aWRlcyBhIGNlbnRyYWxpemVkIGxvZ2dpbmcgbWVjaGFuaXNtIHdpdGggc3VwcG9ydCBmb3JcbiAqIGRpZmZlcmVudCBsb2cgbGV2ZWxzLCB2ZXJib3NpdHksIGFuZCBzdHlsaW5nLiBJdCB1c2VzIGEgc2luZ2xldG9uIHBhdHRlcm4gdG8gbWFpbnRhaW4gYSBnbG9iYWxcbiAqIGxvZ2dlciBpbnN0YW5jZSBhbmQgYWxsb3dzIGNyZWF0aW5nIHNwZWNpZmljIGxvZ2dlcnMgZm9yIGRpZmZlcmVudCBjbGFzc2VzIGFuZCBtZXRob2RzLlxuICogQGNsYXNzIExvZ2dpbmdcbiAqIEBleGFtcGxlXG4gKiAvLyBTZXQgZ2xvYmFsIGNvbmZpZ3VyYXRpb25cbiAqIExvZ2dpbmcuc2V0Q29uZmlnKHsgbGV2ZWw6IExvZ0xldmVsLmRlYnVnLCBzdHlsZTogdHJ1ZSB9KTtcbiAqXG4gKiAvLyBHZXQgYSBsb2dnZXIgZm9yIGEgc3BlY2lmaWMgY2xhc3NcbiAqIGNvbnN0IGxvZ2dlciA9IExvZ2dpbmcuZm9yKCdNeUNsYXNzJyk7XG4gKlxuICogLy8gTG9nIG1lc3NhZ2VzIGF0IGRpZmZlcmVudCBsZXZlbHNcbiAqIGxvZ2dlci5pbmZvKCdBcHBsaWNhdGlvbiBzdGFydGVkJyk7XG4gKiBsb2dnZXIuZGVidWcoJ1Byb2Nlc3NpbmcgZGF0YS4uLicpO1xuICpcbiAqIC8vIExvZyB3aXRoIGNvbnRleHRcbiAqIGNvbnN0IG1ldGhvZExvZ2dlciA9IExvZ2dpbmcuZm9yKCdNeUNsYXNzLm15TWV0aG9kJyk7XG4gKiBtZXRob2RMb2dnZXIudmVyYm9zZSgnRGV0YWlsZWQgb3BlcmF0aW9uIGluZm9ybWF0aW9uJywgMSk7XG4gKlxuICogLy8gTG9nIGVycm9yc1xuICogdHJ5IHtcbiAqICAgLy8gc29tZSBvcGVyYXRpb25cbiAqIH0gY2F0Y2ggKGVycm9yKSB7XG4gKiAgIGxvZ2dlci5lcnJvcihlcnJvcik7XG4gKiB9XG4gKiBAbWVybWFpZFxuICogY2xhc3NEaWFncmFtXG4gKiAgIGNsYXNzIExvZ2dlciB7XG4gKiAgICAgPDxpbnRlcmZhY2U+PlxuICogICAgICtmb3IobWV0aG9kLCBjb25maWcsIC4uLmFyZ3MpXG4gKiAgICAgK3NpbGx5KG1zZywgdmVyYm9zaXR5KVxuICogICAgICt2ZXJib3NlKG1zZywgdmVyYm9zaXR5KVxuICogICAgICtpbmZvKG1zZylcbiAqICAgICArZGVidWcobXNnKVxuICogICAgICtlcnJvcihtc2cpXG4gKiAgICAgK3NldENvbmZpZyhjb25maWcpXG4gKiAgIH1cbiAqXG4gKiAgIGNsYXNzIExvZ2dpbmcge1xuICogICAgIC1nbG9iYWw6IExvZ2dlclxuICogICAgIC1fZmFjdG9yeTogTG9nZ2VyRmFjdG9yeVxuICogICAgIC1fY29uZmlnOiBMb2dnaW5nQ29uZmlnXG4gKiAgICAgK3NldEZhY3RvcnkoZmFjdG9yeSlcbiAqICAgICArc2V0Q29uZmlnKGNvbmZpZylcbiAqICAgICArZ2V0Q29uZmlnKClcbiAqICAgICArZ2V0KClcbiAqICAgICArdmVyYm9zZShtc2csIHZlcmJvc2l0eSlcbiAqICAgICAraW5mbyhtc2cpXG4gKiAgICAgK2RlYnVnKG1zZylcbiAqICAgICArc2lsbHkobXNnKVxuICogICAgICtlcnJvcihtc2cpXG4gKiAgICAgK2ZvcihvYmplY3QsIGNvbmZpZywgLi4uYXJncylcbiAqICAgICArYmVjYXVzZShyZWFzb24sIGlkKVxuICogICAgICt0aGVtZSh0ZXh0LCB0eXBlLCBsb2dnZXJMZXZlbCwgdGVtcGxhdGUpXG4gKiAgIH1cbiAqXG4gKiAgIGNsYXNzIE1pbmlMb2dnZXIge1xuICogICAgICtjb25zdHJ1Y3Rvcihjb250ZXh0LCBjb25mPylcbiAqICAgfVxuICpcbiAqICAgTG9nZ2luZyAuLj4gTG9nZ2VyIDogY3JlYXRlc1xuICogICBMb2dnaW5nIC4uPiBNaW5pTG9nZ2VyIDogY3JlYXRlcyBieSBkZWZhdWx0XG4gKi9cbmV4cG9ydCBjbGFzcyBMb2dnaW5nIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZVxuICAgKiBAc3VtbWFyeSBBIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiBMb2dnZXIgdXNlZCBmb3IgZ2xvYmFsIGxvZ2dpbmdcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdsb2JhbD86IExvZ2dlcjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEZhY3RvcnkgZnVuY3Rpb24gZm9yIGNyZWF0aW5nIGxvZ2dlciBpbnN0YW5jZXNcbiAgICogQHN1bW1hcnkgQSBmdW5jdGlvbiB0aGF0IGNyZWF0ZXMgbmV3IExvZ2dlciBpbnN0YW5jZXMuIEJ5IGRlZmF1bHQsIGl0IGNyZWF0ZXMgYSBNaW5pTG9nZ2VyLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgX2ZhY3Rvcnk6IExvZ2dlckZhY3RvcnkgPSAoXG4gICAgb2JqZWN0OiBzdHJpbmcsXG4gICAgY29uZmlnPzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPlxuICApID0+IHtcbiAgICByZXR1cm4gbmV3IE1pbmlMb2dnZXIob2JqZWN0LCBjb25maWcpO1xuICB9O1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBsb2dnaW5nIHN5c3RlbVxuICAgKiBAc3VtbWFyeSBTdG9yZXMgdGhlIGdsb2JhbCBsb2dnaW5nIGNvbmZpZ3VyYXRpb24gaW5jbHVkaW5nIHZlcmJvc2l0eSwgbG9nIGxldmVsLCBzdHlsaW5nLCBhbmQgZm9ybWF0dGluZyBzZXR0aW5nc1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgX2NvbmZpZzogTG9nZ2luZ0NvbmZpZyA9IERlZmF1bHRMb2dnaW5nQ29uZmlnO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7fVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgZmFjdG9yeSBmdW5jdGlvbiBmb3IgY3JlYXRpbmcgbG9nZ2VyIGluc3RhbmNlc1xuICAgKiBAc3VtbWFyeSBBbGxvd3MgY3VzdG9taXppbmcgaG93IGxvZ2dlciBpbnN0YW5jZXMgYXJlIGNyZWF0ZWRcbiAgICogQHBhcmFtIHtMb2dnZXJGYWN0b3J5fSBmYWN0b3J5IC0gVGhlIGZhY3RvcnkgZnVuY3Rpb24gdG8gdXNlIGZvciBjcmVhdGluZyBsb2dnZXJzXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzdGF0aWMgc2V0RmFjdG9yeShmYWN0b3J5OiBMb2dnZXJGYWN0b3J5KSB7XG4gICAgTG9nZ2luZy5fZmFjdG9yeSA9IGZhY3Rvcnk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVwZGF0ZXMgdGhlIGdsb2JhbCBsb2dnaW5nIGNvbmZpZ3VyYXRpb25cbiAgICogQHN1bW1hcnkgQWxsb3dzIHVwZGF0aW5nIHRoZSBnbG9iYWwgbG9nZ2luZyBjb25maWd1cmF0aW9uIHdpdGggbmV3IHNldHRpbmdzXG4gICAqIEBwYXJhbSB7UGFydGlhbDxMb2dnaW5nQ29uZmlnPn0gY29uZmlnIC0gVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byBhcHBseVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc3RhdGljIHNldENvbmZpZyhjb25maWc6IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4pIHtcbiAgICBPYmplY3QuYXNzaWduKHRoaXMuX2NvbmZpZywgY29uZmlnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyBhIGNvcHkgb2YgdGhlIGN1cnJlbnQgZ2xvYmFsIGxvZ2dpbmcgY29uZmlndXJhdGlvblxuICAgKiBAc3VtbWFyeSBSZXR1cm5zIGEgY29weSBvZiB0aGUgY3VycmVudCBnbG9iYWwgbG9nZ2luZyBjb25maWd1cmF0aW9uXG4gICAqIEByZXR1cm4ge0xvZ2dpbmdDb25maWd9IEEgY29weSBvZiB0aGUgY3VycmVudCBjb25maWd1cmF0aW9uXG4gICAqL1xuICBzdGF0aWMgZ2V0Q29uZmlnKCk6IExvZ2dpbmdDb25maWcge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCB0aGlzLl9jb25maWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgb3IgY3JlYXRlcyB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICogQHN1bW1hcnkgUmV0dXJucyB0aGUgZXhpc3RpbmcgZ2xvYmFsIGxvZ2dlciBvciBjcmVhdGVzIGEgbmV3IG9uZSBpZiBpdCBkb2Vzbid0IGV4aXN0LlxuICAgKlxuICAgKiBAcmV0dXJuIFRoZSBnbG9iYWwgVmVyYm9zaXR5TG9nZ2VyIGluc3RhbmNlLlxuICAgKi9cbiAgc3RhdGljIGdldCgpOiBMb2dnZXIge1xuICAgIHRoaXMuZ2xvYmFsID0gdGhpcy5nbG9iYWwgPyB0aGlzLmdsb2JhbCA6IHRoaXMuX2ZhY3RvcnkoXCJMb2dnaW5nXCIpO1xuICAgIHJldHVybiB0aGlzLmdsb2JhbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIHZlcmJvc2UgbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRoZSB2ZXJib3NlIGxvZ2dpbmcgdG8gdGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuXG4gICAqIEBwYXJhbSB2ZXJib3NpdHkgLSBUaGUgdmVyYm9zaXR5IGxldmVsIG9mIHRoZSBtZXNzYWdlIChkZWZhdWx0OiAwKS5cbiAgICovXG4gIHN0YXRpYyB2ZXJib3NlKG1zZzogU3RyaW5nTGlrZSwgdmVyYm9zaXR5OiBudW1iZXIgPSAwKTogdm9pZCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkudmVyYm9zZShtc2csIHZlcmJvc2l0eSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYW4gaW5mbyBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdGhlIGluZm8gbG9nZ2luZyB0byB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC5cbiAgICovXG4gIHN0YXRpYyBpbmZvKG1zZzogU3RyaW5nTGlrZSk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmdldCgpLmluZm8obXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIGRlYnVnIG1lc3NhZ2UuXG4gICAqIEBzdW1tYXJ5IERlbGVnYXRlcyB0aGUgZGVidWcgbG9nZ2luZyB0byB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC5cbiAgICovXG4gIHN0YXRpYyBkZWJ1Zyhtc2c6IFN0cmluZ0xpa2UpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5kZWJ1Zyhtc2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGEgc2lsbHkgbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRoZSBkZWJ1ZyBsb2dnaW5nIHRvIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLlxuICAgKi9cbiAgc3RhdGljIHNpbGx5KG1zZzogU3RyaW5nTGlrZSk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmdldCgpLnNpbGx5KG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYW4gZXJyb3IgbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRoZSBlcnJvciBsb2dnaW5nIHRvIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLlxuICAgKi9cbiAgc3RhdGljIGVycm9yKG1zZzogU3RyaW5nTGlrZSk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmdldCgpLmVycm9yKG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBsb2dnZXIgZm9yIGEgc3BlY2lmaWMgb2JqZWN0IG9yIGNvbnRleHRcbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIG5ldyBsb2dnZXIgaW5zdGFuY2UgZm9yIHRoZSBnaXZlbiBvYmplY3Qgb3IgY29udGV4dCB1c2luZyB0aGUgZmFjdG9yeSBmdW5jdGlvblxuICAgKiBAcGFyYW0ge0xvZ2dpbmdDb250ZXh0fSBvYmplY3QgLSBUaGUgb2JqZWN0LCBjbGFzcywgb3IgY29udGV4dCB0byBjcmVhdGUgYSBsb2dnZXIgZm9yXG4gICAqIEBwYXJhbSB7UGFydGlhbDxMb2dnaW5nQ29uZmlnPn0gW2NvbmZpZ10gLSBPcHRpb25hbCBjb25maWd1cmF0aW9uIHRvIG92ZXJyaWRlIGdsb2JhbCBzZXR0aW5nc1xuICAgKiBAcGFyYW0gey4uLmFueX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGxvZ2dlciBmYWN0b3J5XG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gQSBuZXcgbG9nZ2VyIGluc3RhbmNlIGZvciB0aGUgc3BlY2lmaWVkIG9iamVjdCBvciBjb250ZXh0XG4gICAqL1xuICBzdGF0aWMgZm9yKFxuICAgIG9iamVjdDogTG9nZ2luZ0NvbnRleHQsXG4gICAgY29uZmlnPzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPixcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBMb2dnZXIge1xuICAgIG9iamVjdCA9XG4gICAgICB0eXBlb2Ygb2JqZWN0ID09PSBcInN0cmluZ1wiXG4gICAgICAgID8gb2JqZWN0XG4gICAgICAgIDogb2JqZWN0LmNvbnN0cnVjdG9yXG4gICAgICAgICAgPyBvYmplY3QuY29uc3RydWN0b3IubmFtZVxuICAgICAgICAgIDogb2JqZWN0Lm5hbWU7XG4gICAgcmV0dXJuIHRoaXMuX2ZhY3Rvcnkob2JqZWN0LCBjb25maWcsIC4uLmFyZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbG9nZ2VyIGZvciBhIHNwZWNpZmljIHJlYXNvbiBvciBjb3JyZWxhdGlvbiBjb250ZXh0XG4gICAqIEBzdW1tYXJ5IFV0aWxpdHkgdG8gcXVpY2tseSBjcmVhdGUgYSBsb2dnZXIgbGFiZWxlZCB3aXRoIGEgZnJlZS1mb3JtIHJlYXNvbiBhbmQgb3B0aW9uYWwgaWRlbnRpZmllclxuICAgKiBzbyB0aGF0IGFkLWhvYyBvcGVyYXRpb25zIGNhbiBiZSB0cmFjZWQgd2l0aG91dCB0eWluZyB0aGUgbG9nZ2VyIHRvIGEgY2xhc3Mgb3IgbWV0aG9kIG5hbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZWFzb24gLSBBIHRleHR1YWwgcmVhc29uIG9yIGNvbnRleHQgbGFiZWwgZm9yIHRoaXMgbG9nZ2VyIGluc3RhbmNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbaWRdIC0gT3B0aW9uYWwgaWRlbnRpZmllciB0byBoZWxwIGNvcnJlbGF0ZSByZWxhdGVkIGxvZyBlbnRyaWVzXG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gQSBuZXcgbG9nZ2VyIGluc3RhbmNlIGxhYmVsZWQgd2l0aCB0aGUgcHJvdmlkZWQgcmVhc29uIGFuZCBpZFxuICAgKi9cbiAgc3RhdGljIGJlY2F1c2UocmVhc29uOiBzdHJpbmcsIGlkPzogc3RyaW5nKTogTG9nZ2VyIHtcbiAgICByZXR1cm4gdGhpcy5fZmFjdG9yeShyZWFzb24sIHRoaXMuX2NvbmZpZywgaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBcHBsaWVzIHRoZW1lIHN0eWxpbmcgdG8gdGV4dFxuICAgKiBAc3VtbWFyeSBBcHBsaWVzIHN0eWxpbmcgKGNvbG9ycywgZm9ybWF0dGluZykgdG8gdGV4dCBiYXNlZCBvbiB0aGUgdGhlbWUgY29uZmlndXJhdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSB0ZXh0IHRvIHN0eWxlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIC0gVGhlIHR5cGUgb2YgZWxlbWVudCB0byBzdHlsZSAoZS5nLiwgXCJjbGFzc1wiLCBcIm1lc3NhZ2VcIiwgXCJsb2dMZXZlbFwiKVxuICAgKiBAcGFyYW0ge0xvZ0xldmVsfSBsb2dnZXJMZXZlbCAtIFRoZSBsb2cgbGV2ZWwgdG8gdXNlIGZvciBzdHlsaW5nXG4gICAqIEBwYXJhbSB7VGhlbWV9IFt0ZW1wbGF0ZT1EZWZhdWx0VGhlbWVdIC0gVGhlIHRoZW1lIHRvIHVzZSBmb3Igc3R5bGluZ1xuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBzdHlsZWQgdGV4dFxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAgICogICBwYXJ0aWNpcGFudCBUaGVtZSBhcyBMb2dnaW5nLnRoZW1lXG4gICAqICAgcGFydGljaXBhbnQgQXBwbHkgYXMgYXBwbHkgZnVuY3Rpb25cbiAgICogICBwYXJ0aWNpcGFudCBTdHlsZSBhcyBzdHlsZWQtc3RyaW5nLWJ1aWxkZXJcbiAgICpcbiAgICogICBDYWxsZXItPj5UaGVtZTogdGhlbWUodGV4dCwgdHlwZSwgbG9nZ2VyTGV2ZWwpXG4gICAqICAgVGhlbWUtPj5UaGVtZTogQ2hlY2sgaWYgc3R5bGluZyBpcyBlbmFibGVkXG4gICAqICAgYWx0IHN0eWxpbmcgZGlzYWJsZWRcbiAgICogICAgIFRoZW1lLS0+PkNhbGxlcjogcmV0dXJuIG9yaWdpbmFsIHRleHRcbiAgICogICBlbHNlIHN0eWxpbmcgZW5hYmxlZFxuICAgKiAgICAgVGhlbWUtPj5UaGVtZTogR2V0IHRoZW1lIGZvciB0eXBlXG4gICAqICAgICBhbHQgdGhlbWUgbm90IGZvdW5kXG4gICAqICAgICAgIFRoZW1lLS0+PkNhbGxlcjogcmV0dXJuIG9yaWdpbmFsIHRleHRcbiAgICogICAgIGVsc2UgdGhlbWUgZm91bmRcbiAgICogICAgICAgVGhlbWUtPj5UaGVtZTogRGV0ZXJtaW5lIGFjdHVhbCB0aGVtZSBiYXNlZCBvbiBsb2cgbGV2ZWxcbiAgICogICAgICAgVGhlbWUtPj5BcHBseTogQXBwbHkgZWFjaCBzdHlsZSBwcm9wZXJ0eVxuICAgKiAgICAgICBBcHBseS0+PlN0eWxlOiBBcHBseSBjb2xvcnMgYW5kIGZvcm1hdHRpbmdcbiAgICogICAgICAgU3R5bGUtLT4+QXBwbHk6IFJldHVybiBzdHlsZWQgdGV4dFxuICAgKiAgICAgICBBcHBseS0tPj5UaGVtZTogUmV0dXJuIHN0eWxlZCB0ZXh0XG4gICAqICAgICAgIFRoZW1lLS0+PkNhbGxlcjogUmV0dXJuIGZpbmFsIHN0eWxlZCB0ZXh0XG4gICAqICAgICBlbmRcbiAgICogICBlbmRcbiAgICovXG4gIHN0YXRpYyB0aGVtZShcbiAgICB0ZXh0OiBzdHJpbmcsXG4gICAgdHlwZToga2V5b2YgVGhlbWUgfCBrZXlvZiBMb2dMZXZlbCxcbiAgICBsb2dnZXJMZXZlbDogTG9nTGV2ZWwsXG4gICAgdGVtcGxhdGU6IFRoZW1lID0gRGVmYXVsdFRoZW1lXG4gICkge1xuICAgIGlmICghdGhpcy5fY29uZmlnLnN0eWxlKSByZXR1cm4gdGV4dDtcbiAgICBjb25zdCBsb2dnZXIgPSBMb2dnaW5nLmdldCgpLmZvcih0aGlzLnRoZW1lKTtcblxuICAgIGZ1bmN0aW9uIGFwcGx5KFxuICAgICAgdHh0OiBzdHJpbmcsXG4gICAgICBvcHRpb246IGtleW9mIFRoZW1lT3B0aW9uLFxuICAgICAgdmFsdWU6IG51bWJlciB8IFtudW1iZXJdIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHwgbnVtYmVyW10gfCBzdHJpbmdbXVxuICAgICk6IHN0cmluZyB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB0OiBzdHJpbmcgfCBTdHlsZWRTdHJpbmcgPSB0eHQ7XG4gICAgICAgIGxldCBjID0gc3R5bGUodCk7XG5cbiAgICAgICAgZnVuY3Rpb24gYXBwbHlDb2xvcihcbiAgICAgICAgICB2YWw6IG51bWJlciB8IFtudW1iZXJdIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgIGlzQmcgPSBmYWxzZVxuICAgICAgICApOiBTdHlsZWRTdHJpbmcge1xuICAgICAgICAgIGxldCBmOlxuICAgICAgICAgICAgfCB0eXBlb2YgYy5iYWNrZ3JvdW5kXG4gICAgICAgICAgICB8IHR5cGVvZiBjLmZvcmVncm91bmRcbiAgICAgICAgICAgIHwgdHlwZW9mIGMucmdiXG4gICAgICAgICAgICB8IHR5cGVvZiBjLmNvbG9yMjU2ID0gaXNCZyA/IGMuYmFja2dyb3VuZCA6IGMuZm9yZWdyb3VuZDtcbiAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsKSkge1xuICAgICAgICAgICAgcmV0dXJuIChmIGFzIHR5cGVvZiBjLmJhY2tncm91bmQgfCB0eXBlb2YgYy5mb3JlZ3JvdW5kKS5jYWxsKFxuICAgICAgICAgICAgICBjLFxuICAgICAgICAgICAgICB2YWx1ZSBhcyBudW1iZXJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHN3aXRjaCAodmFsLmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICBmID0gaXNCZyA/IGMuYmdDb2xvcjI1NiA6IGMuY29sb3IyNTY7XG4gICAgICAgICAgICAgIHJldHVybiAoZiBhcyB0eXBlb2YgYy5iZ0NvbG9yMjU2IHwgdHlwZW9mIGMuY29sb3IyNTYpKHZhbFswXSk7XG4gICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgIGYgPSBpc0JnID8gYy5iZ1JnYiA6IGMucmdiO1xuICAgICAgICAgICAgICByZXR1cm4gYy5yZ2IodmFsWzBdLCB2YWxbMV0sIHZhbFsyXSk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYE5vdCBhIHZhbGlkIGNvbG9yIG9wdGlvbjogJHtvcHRpb259YCk7XG4gICAgICAgICAgICAgIHJldHVybiBzdHlsZSh0IGFzIHN0cmluZyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gYXBwbHlTdHlsZSh2OiBudW1iZXIgfCBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgICBpZiAodHlwZW9mIHYgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIGMgPSBjLnN0eWxlKHYpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjID0gY1t2IGFzIGtleW9mIENvbG9yaXplT3B0aW9uc10gYXMgU3R5bGVkU3RyaW5nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAob3B0aW9uKSB7XG4gICAgICAgICAgY2FzZSBcImJnXCI6XG4gICAgICAgICAgY2FzZSBcImZnXCI6XG4gICAgICAgICAgICByZXR1cm4gYXBwbHlDb2xvcih2YWx1ZSBhcyBudW1iZXIpLnRleHQ7XG4gICAgICAgICAgY2FzZSBcInN0eWxlXCI6XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgdmFsdWUuZm9yRWFjaChhcHBseVN0eWxlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGFwcGx5U3R5bGUodmFsdWUgYXMgbnVtYmVyIHwgc3RyaW5nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjLnRleHQ7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgTm90IGEgdmFsaWQgdGhlbWUgb3B0aW9uOiAke29wdGlvbn1gKTtcbiAgICAgICAgICAgIHJldHVybiB0O1xuICAgICAgICB9XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKGBFcnJvciBhcHBseWluZyBzdHlsZTogJHtvcHRpb259IHdpdGggdmFsdWUgJHt2YWx1ZX1gKTtcbiAgICAgICAgcmV0dXJuIHR4dDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBpbmRpdmlkdWFsVGhlbWUgPSB0ZW1wbGF0ZVt0eXBlIGFzIGtleW9mIFRoZW1lXTtcbiAgICBpZiAoIWluZGl2aWR1YWxUaGVtZSB8fCAhT2JqZWN0LmtleXMoaW5kaXZpZHVhbFRoZW1lKS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0ZXh0O1xuICAgIH1cblxuICAgIGxldCBhY3R1YWxUaGVtZTogVGhlbWVPcHRpb24gPSBpbmRpdmlkdWFsVGhlbWUgYXMgVGhlbWVPcHRpb247XG5cbiAgICBjb25zdCBsb2dMZXZlbHMgPSBPYmplY3QuYXNzaWduKHt9LCBMb2dMZXZlbCk7XG4gICAgaWYgKE9iamVjdC5rZXlzKGluZGl2aWR1YWxUaGVtZSlbMF0gaW4gbG9nTGV2ZWxzKVxuICAgICAgYWN0dWFsVGhlbWUgPVxuICAgICAgICAoaW5kaXZpZHVhbFRoZW1lIGFzIFRoZW1lT3B0aW9uQnlMb2dMZXZlbClbbG9nZ2VyTGV2ZWxdIHx8IHt9O1xuXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGFjdHVhbFRoZW1lKS5yZWR1Y2UoKGFjYzogc3RyaW5nLCBrZXk6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgdmFsID0gKGFjdHVhbFRoZW1lIGFzIFRoZW1lT3B0aW9uKVtrZXkgYXMga2V5b2YgVGhlbWVPcHRpb25dO1xuICAgICAgaWYgKHZhbClcbiAgICAgICAgcmV0dXJuIGFwcGx5KFxuICAgICAgICAgIGFjYyxcbiAgICAgICAgICBrZXkgYXMga2V5b2YgVGhlbWVPcHRpb24sXG4gICAgICAgICAgdmFsIGFzXG4gICAgICAgICAgICB8IG51bWJlclxuICAgICAgICAgICAgfCBbbnVtYmVyXVxuICAgICAgICAgICAgfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl1cbiAgICAgICAgICAgIHwgbnVtYmVyW11cbiAgICAgICAgICAgIHwgc3RyaW5nW11cbiAgICAgICAgKTtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgdGV4dCk7XG4gIH1cbn1cbiIsImltcG9ydCB7IExvZ0xldmVsIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSBcIi4vbG9nZ2luZ1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzXG4gKiBAc3VtbWFyeSBDcmVhdGVzIGEgZGVjb3JhdG9yIHRoYXQgbG9ncyBtZXRob2QgY2FsbHMgd2l0aCBzcGVjaWZpZWQgbGV2ZWwsIGJlbmNobWFya2luZywgYW5kIHZlcmJvc2l0eVxuICogQHBhcmFtIHtMb2dMZXZlbH0gbGV2ZWwgLSBUaGUgbG9nIGxldmVsIHRvIHVzZSAoZGVmYXVsdDogTG9nTGV2ZWwuaW5mbylcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2JlbmNobWFyaz1mYWxzZV0gLSBXaGV0aGVyIHRvIGxvZyBleGVjdXRpb24gdGltZSAoZGVmYXVsdDogZmFsc2UpXG4gKiBAcGFyYW0ge251bWJlcn0gW3ZlcmJvc2l0eT0wXSAtIFRoZSB2ZXJib3NpdHkgbGV2ZWwgZm9yIHRoZSBsb2cgbWVzc2FnZXMgKGRlZmF1bHQ6IDApXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiBsb2dcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IERlY29yYXRvciBhcyBsb2cgZGVjb3JhdG9yXG4gKiAgIHBhcnRpY2lwYW50IE1ldGhvZCBhcyBPcmlnaW5hbCBNZXRob2RcbiAqICAgcGFydGljaXBhbnQgTG9nZ2VyIGFzIExvZ2dpbmcgaW5zdGFuY2VcbiAqXG4gKiAgIENsaWVudC0+PkRlY29yYXRvcjogY2FsbCBkZWNvcmF0ZWQgbWV0aG9kXG4gKiAgIERlY29yYXRvci0+PkxvZ2dlcjogbG9nIG1ldGhvZCBjYWxsXG4gKiAgIERlY29yYXRvci0+Pk1ldGhvZDogY2FsbCBvcmlnaW5hbCBtZXRob2RcbiAqICAgYWx0IHJlc3VsdCBpcyBQcm9taXNlXG4gKiAgICAgTWV0aG9kLS0+PkRlY29yYXRvcjogcmV0dXJuIFByb21pc2VcbiAqICAgICBEZWNvcmF0b3ItPj5EZWNvcmF0b3I6IGF0dGFjaCB0aGVuIGhhbmRsZXJcbiAqICAgICBOb3RlIG92ZXIgRGVjb3JhdG9yOiBQcm9taXNlIHJlc29sdmVzXG4gKiAgICAgRGVjb3JhdG9yLT4+TG9nZ2VyOiBsb2cgYmVuY2htYXJrIChpZiBlbmFibGVkKVxuICogICAgIERlY29yYXRvci0tPj5DbGllbnQ6IHJldHVybiByZXN1bHRcbiAqICAgZWxzZSByZXN1bHQgaXMgbm90IFByb21pc2VcbiAqICAgICBNZXRob2QtLT4+RGVjb3JhdG9yOiByZXR1cm4gcmVzdWx0XG4gKiAgICAgRGVjb3JhdG9yLT4+TG9nZ2VyOiBsb2cgYmVuY2htYXJrIChpZiBlbmFibGVkKVxuICogICAgIERlY29yYXRvci0tPj5DbGllbnQ6IHJldHVybiByZXN1bHRcbiAqICAgZW5kXG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvZyhcbiAgbGV2ZWw6IExvZ0xldmVsID0gTG9nTGV2ZWwuaW5mbyxcbiAgYmVuY2htYXJrOiBib29sZWFuID0gZmFsc2UsXG4gIHZlcmJvc2l0eSA9IDBcbikge1xuICByZXR1cm4gZnVuY3Rpb24gKFxuICAgIHRhcmdldDogYW55LFxuICAgIHByb3BlcnR5S2V5OiBzdHJpbmcsXG4gICAgZGVzY3JpcHRvcjogUHJvcGVydHlEZXNjcmlwdG9yXG4gICkge1xuICAgIGNvbnN0IGxvZyA9IExvZ2dpbmcuZm9yKHRhcmdldCkuZm9yKHRhcmdldFtwcm9wZXJ0eUtleV0pO1xuICAgIGNvbnN0IG1ldGhvZCA9IGxvZ1tsZXZlbF0uYmluZChsb2cpO1xuICAgIGNvbnN0IG9yaWdpbmFsTWV0aG9kID0gZGVzY3JpcHRvci52YWx1ZTtcbiAgICBkZXNjcmlwdG9yLnZhbHVlID0gZnVuY3Rpb24gKC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgICBtZXRob2QoYGNhbGxlZCB3aXRoICR7YXJnc31gLCB2ZXJib3NpdHkpO1xuICAgICAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgbGV0IGVuZDogbnVtYmVyO1xuICAgICAgY29uc3QgcmVzdWx0OiBhbnkgPSBvcmlnaW5hbE1ldGhvZC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQudGhlbigocikgPT4ge1xuICAgICAgICAgIGlmIChiZW5jaG1hcmspIHtcbiAgICAgICAgICAgIGVuZCA9IERhdGUubm93KCk7XG4gICAgICAgICAgICBpZiAoYmVuY2htYXJrKSBtZXRob2QoYGNvbXBsZXRlZCBpbiAke2VuZCAtIHN0YXJ0fW1zYCwgdmVyYm9zaXR5KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHI7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGJlbmNobWFyaykge1xuICAgICAgICBlbmQgPSBEYXRlLm5vdygpO1xuICAgICAgICBpZiAoYmVuY2htYXJrKSBtZXRob2QoYGNvbXBsZXRlZCBpbiAke2VuZCAtIHN0YXJ0fW1zYCwgdmVyYm9zaXR5KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICB9O1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggZGVidWcgbGV2ZWxcbiAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIHRoZSBsb2cgZGVjb3JhdG9yIHRoYXQgdXNlcyBMb2dMZXZlbC5kZWJ1Z1xuICogQHBhcmFtIHtib29sZWFufSBbYmVuY2htYXJrPWZhbHNlXSAtIFdoZXRoZXIgdG8gbG9nIGV4ZWN1dGlvbiB0aW1lIChkZWZhdWx0OiBmYWxzZSlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG1ldGhvZCBkZWNvcmF0b3IgdGhhdCB3cmFwcyB0aGUgb3JpZ2luYWwgbWV0aG9kIHdpdGggZGVidWcgbG9nZ2luZ1xuICogQGZ1bmN0aW9uIGRlYnVnXG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlYnVnKGJlbmNobWFyazogYm9vbGVhbiA9IGZhbHNlKSB7XG4gIHJldHVybiBsb2coTG9nTGV2ZWwuZGVidWcsIGJlbmNobWFyayk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCBpbmZvIGxldmVsXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB0aGUgbG9nIGRlY29yYXRvciB0aGF0IHVzZXMgTG9nTGV2ZWwuaW5mb1xuICogQHBhcmFtIHtib29sZWFufSBbYmVuY2htYXJrPWZhbHNlXSAtIFdoZXRoZXIgdG8gbG9nIGV4ZWN1dGlvbiB0aW1lIChkZWZhdWx0OiBmYWxzZSlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG1ldGhvZCBkZWNvcmF0b3IgdGhhdCB3cmFwcyB0aGUgb3JpZ2luYWwgbWV0aG9kIHdpdGggaW5mbyBsb2dnaW5nXG4gKiBAZnVuY3Rpb24gaW5mb1xuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmZvKGJlbmNobWFyazogYm9vbGVhbiA9IGZhbHNlKSB7XG4gIHJldHVybiBsb2coTG9nTGV2ZWwuaW5mbywgYmVuY2htYXJrKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIHNpbGx5IGxldmVsXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB0aGUgbG9nIGRlY29yYXRvciB0aGF0IHVzZXMgTG9nTGV2ZWwuc2lsbHlcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2JlbmNobWFyaz1mYWxzZV0gLSBXaGV0aGVyIHRvIGxvZyBleGVjdXRpb24gdGltZSAoZGVmYXVsdDogZmFsc2UpXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIHNpbGx5IGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiBzaWxseVxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzaWxseShiZW5jaG1hcms6IGJvb2xlYW4gPSBmYWxzZSkge1xuICByZXR1cm4gbG9nKExvZ0xldmVsLnNpbGx5LCBiZW5jaG1hcmspO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggdmVyYm9zZSBsZXZlbFxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQgdGhlIGxvZyBkZWNvcmF0b3IgdGhhdCB1c2VzIExvZ0xldmVsLnZlcmJvc2Ugd2l0aCBjb25maWd1cmFibGUgdmVyYm9zaXR5XG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIHZlcmJvc2UgbG9nZ2luZ1xuICogQGZ1bmN0aW9uIHZlcmJvc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcmJvc2UoKTogdm9pZDtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIHZlcmJvc2UgbGV2ZWxcbiAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIHRoZSBsb2cgZGVjb3JhdG9yIHRoYXQgdXNlcyBMb2dMZXZlbC52ZXJib3NlIHdpdGggY29uZmlndXJhYmxlIHZlcmJvc2l0eVxuICogQHBhcmFtIHtib29sZWFufSBiZW5jaG1hcmsgLSBXaGV0aGVyIHRvIGxvZyBleGVjdXRpb24gdGltZVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbWV0aG9kIGRlY29yYXRvciB0aGF0IHdyYXBzIHRoZSBvcmlnaW5hbCBtZXRob2Qgd2l0aCB2ZXJib3NlIGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiB2ZXJib3NlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKGJlbmNobWFyazogYm9vbGVhbik6IHZvaWQ7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCB2ZXJib3NlIGxldmVsXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB0aGUgbG9nIGRlY29yYXRvciB0aGF0IHVzZXMgTG9nTGV2ZWwudmVyYm9zZSB3aXRoIGNvbmZpZ3VyYWJsZSB2ZXJib3NpdHlcbiAqIEBwYXJhbSB7bnVtYmVyfSB2ZXJib3NpdHkgLSBUaGUgdmVyYm9zaXR5IGxldmVsIGZvciB0aGUgbG9nIG1lc3NhZ2VzIChkZWZhdWx0OiAwKVxuICogQHBhcmFtIHtib29sZWFufSBbYmVuY2htYXJrPWZhbHNlXSAtIFdoZXRoZXIgdG8gbG9nIGV4ZWN1dGlvbiB0aW1lIChkZWZhdWx0OiBmYWxzZSlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG1ldGhvZCBkZWNvcmF0b3IgdGhhdCB3cmFwcyB0aGUgb3JpZ2luYWwgbWV0aG9kIHdpdGggdmVyYm9zZSBsb2dnaW5nXG4gKiBAZnVuY3Rpb24gdmVyYm9zZVxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKHZlcmJvc2l0eTogbnVtYmVyIHwgYm9vbGVhbiA9IDAsIGJlbmNobWFyaz86IGJvb2xlYW4pIHtcbiAgaWYgKHR5cGVvZiB2ZXJib3NpdHkgPT09IFwiYm9vbGVhblwiKSB7XG4gICAgYmVuY2htYXJrID0gdmVyYm9zaXR5O1xuICAgIHZlcmJvc2l0eSA9IDA7XG4gIH1cbiAgcmV0dXJuIGxvZyhMb2dMZXZlbC52ZXJib3NlLCBiZW5jaG1hcmssIHZlcmJvc2l0eSk7XG59XG4iLCJpbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSBcIi4vbG9nZ2luZ1wiO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQmFzZSBjbGFzcyB0aGF0IHByb3ZpZGVzIGEgcmVhZHktdG8tdXNlIGxvZ2dlciBpbnN0YW5jZVxuICogQHN1bW1hcnkgTG9nZ2VkQ2xhc3MgaXMgYSBjb252ZW5pZW5jZSBhYnN0cmFjdCBjbGFzcyB0aGF0IGluamVjdHMgYSB0eXBlLXNhZmUgbG9nZ2VyXG4gKiBpbnRvIGRlcml2ZWQgY2xhc3NlcyB0aHJvdWdoIGEgcHJvdGVjdGVkIGdldHRlci4gU3ViY2xhc3NlcyBjYW4gZGlyZWN0bHkgYWNjZXNzXG4gKiB0aGlzLmxvZyB0byBlbWl0IG1lc3NhZ2VzIHdpdGhvdXQgbWFudWFsbHkgY3JlYXRpbmcgYSBsb2dnZXIuIFRoaXMgcHJvbW90ZXNcbiAqIGNvbnNpc3RlbnQsIGNvbnRleHQtYXdhcmUgbG9nZ2luZyBhY3Jvc3MgdGhlIGNvZGViYXNlLlxuICogQHBhcmFtIHt2b2lkfSBbY29uc3RydWN0b3JdIC0gTm8gY29uc3RydWN0b3IgYXJndW1lbnRzOyBzdWJjbGFzc2VzIG1heSBkZWZpbmUgdGhlaXIgb3duXG4gKiBAY2xhc3MgTG9nZ2VkQ2xhc3NcbiAqIEBleGFtcGxlXG4gKiBjbGFzcyBVc2VyU2VydmljZSBleHRlbmRzIExvZ2dlZENsYXNzIHtcbiAqICAgY3JlYXRlKHVzZXI6IFVzZXIpIHtcbiAqICAgICB0aGlzLmxvZy5pbmZvKGBDcmVhdGluZyB1c2VyICR7dXNlci5pZH1gKTtcbiAqICAgfVxuICogfVxuICpcbiAqIGNvbnN0IHN2YyA9IG5ldyBVc2VyU2VydmljZSgpO1xuICogc3ZjLmNyZWF0ZSh7IGlkOiBcIjQyXCIgfSk7XG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICogICBwYXJ0aWNpcGFudCBJbnN0YW5jZSBhcyBTdWJjbGFzcyBJbnN0YW5jZVxuICogICBwYXJ0aWNpcGFudCBHZXR0ZXIgYXMgTG9nZ2VkQ2xhc3MubG9nXG4gKiAgIHBhcnRpY2lwYW50IExvZ2dpbmcgYXMgTG9nZ2luZ1xuICogICBwYXJ0aWNpcGFudCBMb2dnZXIgYXMgTG9nZ2VyXG4gKlxuICogICBDbGllbnQtPj5JbnN0YW5jZTogY2FsbCBzb21lTWV0aG9kKClcbiAqICAgSW5zdGFuY2UtPj5HZXR0ZXI6IGFjY2VzcyB0aGlzLmxvZ1xuICogICBHZXR0ZXItPj5Mb2dnaW5nOiBMb2dnaW5nLmZvcih0aGlzKVxuICogICBMb2dnaW5nLS0+PkdldHRlcjogcmV0dXJuIExvZ2dlclxuICogICBHZXR0ZXItLT4+SW5zdGFuY2U6IHJldHVybiBMb2dnZXJcbiAqICAgSW5zdGFuY2UtPj5Mb2dnZXI6IGluZm8vZGVidWcvZXJyb3IoLi4uKVxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgTG9nZ2VkQ2xhc3Mge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExhemlseSBwcm92aWRlcyBhIGNvbnRleHQtYXdhcmUgbG9nZ2VyIGZvciB0aGUgY3VycmVudCBpbnN0YW5jZVxuICAgKiBAc3VtbWFyeSBVc2VzIExvZ2dpbmcuZm9yKHRoaXMpIHRvIGNyZWF0ZSBhIGxvZ2dlciB3aG9zZSBjb250ZXh0IGlzIHRoZVxuICAgKiBzdWJjbGFzcyBuYW1lLCBhbGxvd2luZyB1bmlmb3JtIGFuZCBzdHJ1Y3R1cmVkIGxvZ3MgZnJvbSBhbnkgaW5oZXJpdGluZyBjbGFzcy5cbiAgICogQHJldHVybiB7TG9nZ2VyfSBBIGxvZ2dlciBib3VuZCB0byB0aGUgc3ViY2xhc3MgY29udGV4dFxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBsb2coKTogTG9nZ2VyIHtcbiAgICByZXR1cm4gTG9nZ2luZy5mb3IodGhpcyBhcyBhbnkpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKCkge31cbn1cbiIsImV4cG9ydCAqIGZyb20gXCIuL2NvbnN0YW50c1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vTG9nZ2VkQ2xhc3NcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2xvZ2dpbmdcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgbG9nZ2luZyBtb2R1bGUgZm9yIFR5cGVTY3JpcHQgYXBwbGljYXRpb25zXG4gKiBAc3VtbWFyeSBQcm92aWRlcyBhIGNvbXByZWhlbnNpdmUsIGZsZXhpYmxlIGxvZ2dpbmcgc29sdXRpb24uIFRoaXMgbW9kdWxlIGV4cG9zZXM6XG4gKiAtIENvcmUgY2xhc3NlcyBsaWtlIHtAbGluayBMb2dnaW5nfSBhbmQge0BsaW5rIE1pbmlMb2dnZXJ9XG4gKiAtIERlY29yYXRvcnMgc3VjaCBhcyB7QGxpbmsgbG9nfSBmb3IgaW5zdHJ1bWVudGluZyBtZXRob2RzXG4gKiAtIENvbmZpZ3VyYXRpb24gYW5kIGNvbnN0YW50cyBsaWtlIHtAbGluayBMb2dMZXZlbH0gYW5kIHtAbGluayBEZWZhdWx0TG9nZ2luZ0NvbmZpZ31cbiAqIC0gVHlwZSBkZWZpbml0aW9ucyBpbmNsdWRpbmcge0BsaW5rIExvZ2dlcn0gYW5kIHtAbGluayBMb2dnaW5nQ29uZmlnfVxuICogVGhlc2UgZXhwb3J0cyBlbmFibGUgY29uc2lzdGVudCwgY29udGV4dC1hd2FyZSwgYW5kIG9wdGlvbmFsbHkgdGhlbWVkIGxvZ2dpbmcgYWNyb3NzIHByb2plY3RzLlxuICogQG1vZHVsZSBMb2dnaW5nXG4gKi9cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ3VycmVudCBwYWNrYWdlIHZlcnNpb24gc3RyaW5nXG4gKiBAc3VtbWFyeSBTdG9yZXMgdGhlIGN1cnJlbnQgcGFja2FnZSB2ZXJzaW9uLCB1c2VkIGZvciB2ZXJzaW9uIHRyYWNraW5nIGFuZCBjb21wYXRpYmlsaXR5IGNoZWNrc1xuICogQGNvbnN0IFZFUlNJT05cbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBOzs7Ozs7QUFNRztJQUNTO0FBQVosQ0FBQSxVQUFZLFFBQVEsRUFBQTs7QUFFbEIsSUFBQSxRQUFBLENBQUEsT0FBQSxDQUFBLEdBQUEsT0FBZTs7QUFFZixJQUFBLFFBQUEsQ0FBQSxNQUFBLENBQUEsR0FBQSxNQUFhOztBQUViLElBQUEsUUFBQSxDQUFBLFNBQUEsQ0FBQSxHQUFBLFNBQW1COztBQUVuQixJQUFBLFFBQUEsQ0FBQSxPQUFBLENBQUEsR0FBQSxPQUFlOztBQUVmLElBQUEsUUFBQSxDQUFBLE9BQUEsQ0FBQSxHQUFBLE9BQWU7QUFDakIsQ0FBQyxFQVhXLFFBQVEsS0FBUixRQUFRLEdBV25CLEVBQUEsQ0FBQSxDQUFBO0FBRUQ7Ozs7Ozs7Ozs7QUFVRztBQUNVLE1BQUEsZ0JBQWdCLEdBQUc7QUFDOUIsSUFBQSxLQUFLLEVBQUUsQ0FBQztBQUNSLElBQUEsSUFBSSxFQUFFLENBQUM7QUFDUCxJQUFBLE9BQU8sRUFBRSxDQUFDO0FBQ1YsSUFBQSxLQUFLLEVBQUUsQ0FBQztBQUNSLElBQUEsS0FBSyxFQUFFLENBQUM7O0FBR1Y7Ozs7O0FBS0c7SUFDUztBQUFaLENBQUEsVUFBWSxXQUFXLEVBQUE7O0FBRXJCLElBQUEsV0FBQSxDQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQVc7O0FBRVgsSUFBQSxXQUFBLENBQUEsTUFBQSxDQUFBLEdBQUEsTUFBYTtBQUNmLENBQUMsRUFMVyxXQUFXLEtBQVgsV0FBVyxHQUt0QixFQUFBLENBQUEsQ0FBQTtBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF3Qkc7QUFDVSxNQUFBLFlBQVksR0FBVTtBQUNqQyxJQUFBLEtBQUssRUFBRTtBQUNMLFFBQUEsRUFBRSxFQUFFLEVBQUU7QUFDUCxLQUFBO0FBQ0QsSUFBQSxFQUFFLEVBQUU7QUFD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
1349
+ export { BrowserEnvKey, DefaultLoggingConfig, DefaultPlaceholderWrappers, DefaultTheme, ENV_PATH_DELIMITER, Environment, LogFilter, LogLevel, LoggedClass, LoggedEnvironment, Logging, LoggingMode, MiniLogger, NumericLogLevels, PatternFilter, VERSION, debug, escapeRegExp, final, info, isBrowser, log, padEnd, patchPlaceholders, patchString, sf, silly, stringFormat, toCamelCase, toENVFormat, toKebabCase, toPascalCase, toSnakeCase, verbose };
1350
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2luZy5lc20uY2pzIiwic291cmNlcyI6WyIuLi9zcmMvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3RleHQudHMiLCIuLi9zcmMvd2ViLnRzIiwiLi4vc3JjL2Vudmlyb25tZW50LnRzIiwiLi4vc3JjL2xvZ2dpbmcudHMiLCIuLi9zcmMvTG9nZ2VkQ2xhc3MudHMiLCIuLi9zcmMvZmlsdGVycy9Mb2dGaWx0ZXIudHMiLCIuLi9zcmMvZGVjb3JhdG9ycy50cyIsIi4uL3NyYy9maWx0ZXJzL1BhdHRlcm5GaWx0ZXIudHMiLCIuLi9zcmMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTG9nZ2luZ0NvbmZpZywgVGhlbWUgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG5leHBvcnQgY29uc3QgQnJvd3NlckVudktleSA9IFwiRU5WXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlbGltaXRlciB1c2VkIGZvciBjb21wb3NpbmcgbmVzdGVkIGVudmlyb25tZW50IHZhcmlhYmxlIG5hbWVzLlxuICogQHN1bW1hcnkgSm9pbnMgcGFyZW50IGFuZCBjaGlsZCBrZXlzIHdoZW4gbWFwcGluZyBvYmplY3QgcGF0aHMgdG8gRU5WIHN0cmluZ3MuXG4gKi9cbmV4cG9ydCBjb25zdCBFTlZfUEFUSF9ERUxJTUlURVIgPSBcIl9fXCI7XG5cbmV4cG9ydCBjb25zdCBEZWZhdWx0UGxhY2Vob2xkZXJXcmFwcGVycyA9IFtcIiR7XCIsIFwifVwiXTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRW51bSBmb3IgbG9nIGxldmVscy5cbiAqIEBzdW1tYXJ5IERlZmluZXMgZGlmZmVyZW50IGxldmVscyBvZiBsb2dnaW5nIGZvciB0aGUgYXBwbGljYXRpb24uXG4gKiBAZW51bSB7c3RyaW5nfVxuICogQHJlYWRvbmx5XG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGVudW0gTG9nTGV2ZWwge1xuICAvKiogRXJyb3IgZXZlbnRzIHRoYXQgYXJlIGxpa2VseSB0byBjYXVzZSBwcm9ibGVtcy4gKi9cbiAgZXJyb3IgPSBcImVycm9yXCIsXG4gIC8qKiBSb3V0aW5lIGluZm9ybWF0aW9uLCBzdWNoIGFzIG9uZ29pbmcgc3RhdHVzIG9yIHBlcmZvcm1hbmNlLiAqL1xuICBpbmZvID0gXCJpbmZvXCIsXG4gIC8qKiBBZGRpdGlvbmFsIHJlbGV2YW50IGluZm9ybWF0aW9uLiAqL1xuICB2ZXJib3NlID0gXCJ2ZXJib3NlXCIsXG4gIC8qKiBEZWJ1ZyBvciB0cmFjZSBpbmZvcm1hdGlvbi4gKi9cbiAgZGVidWcgPSBcImRlYnVnXCIsXG4gIC8qKiB3YXkgdG9vIHZlcmJvc2Ugb3Igc2lsbHkgaW5mb3JtYXRpb24uICovXG4gIHNpbGx5ID0gXCJzaWxseVwiLFxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBOdW1lcmljIHZhbHVlcyBhc3NvY2lhdGVkIHdpdGggbG9nIGxldmVscy5cbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIGEgbnVtZXJpYyByZXByZXNlbnRhdGlvbiBvZiBsb2cgbGV2ZWxzIGZvciBjb21wYXJpc29uIGFuZCBmaWx0ZXJpbmcuXG4gKiBAY29uc3QgTnVtZXJpY0xvZ0xldmVsc1xuICogQHByb3BlcnR5IHtudW1iZXJ9IGVycm9yIC0gTnVtZXJpYyB2YWx1ZSBmb3IgZXJyb3IgbGV2ZWwgKDIpLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGluZm8gLSBOdW1lcmljIHZhbHVlIGZvciBpbmZvIGxldmVsICg0KS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB2ZXJib3NlIC0gTnVtZXJpYyB2YWx1ZSBmb3IgdmVyYm9zZSBsZXZlbCAoNikuXG4gKiBAcHJvcGVydHkge251bWJlcn0gZGVidWcgLSBOdW1lcmljIHZhbHVlIGZvciBkZWJ1ZyBsZXZlbCAoNykuXG4gKiBAcHJvcGVydHkge251bWJlcn0gc2lsbHkgLSBOdW1lcmljIHZhbHVlIGZvciBzaWxseSBsZXZlbCAoOSkuXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGNvbnN0IE51bWVyaWNMb2dMZXZlbHMgPSB7XG4gIGVycm9yOiAyLFxuICBpbmZvOiA0LFxuICB2ZXJib3NlOiA2LFxuICBkZWJ1ZzogNyxcbiAgc2lsbHk6IDksXG59O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFbnVtIGZvciBsb2dnaW5nIG91dHB1dCBtb2Rlcy5cbiAqIEBzdW1tYXJ5IERlZmluZXMgZGlmZmVyZW50IG91dHB1dCBmb3JtYXRzIGZvciBsb2cgbWVzc2FnZXMuXG4gKiBAZW51bSB7c3RyaW5nfVxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBlbnVtIExvZ2dpbmdNb2RlIHtcbiAgLyoqIFJhdyB0ZXh0IGZvcm1hdCBmb3IgaHVtYW4gcmVhZGFiaWxpdHkgKi9cbiAgUkFXID0gXCJyYXdcIixcbiAgLyoqIEpTT04gZm9ybWF0IGZvciBtYWNoaW5lIHBhcnNpbmcgKi9cbiAgSlNPTiA9IFwianNvblwiLFxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IHRoZW1lIGZvciBzdHlsaW5nIGxvZyBvdXRwdXQuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBkZWZhdWx0IGNvbG9yIGFuZCBzdHlsZSBzZXR0aW5ncyBmb3IgdmFyaW91cyBjb21wb25lbnRzIG9mIGxvZyBtZXNzYWdlcy5cbiAqIEBjb25zdCBEZWZhdWx0VGhlbWVcbiAqIEB0eXBlZGVmIHtUaGVtZX0gRGVmYXVsdFRoZW1lXG4gKiBAcHJvcGVydHkge09iamVjdH0gY2xhc3MgLSBTdHlsaW5nIGZvciBjbGFzcyBuYW1lcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjbGFzcy5mZyAtIEZvcmVncm91bmQgY29sb3IgY29kZSBmb3IgY2xhc3MgbmFtZXMgKDM0KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBpZCAtIFN0eWxpbmcgZm9yIGlkZW50aWZpZXJzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGlkLmZnIC0gRm9yZWdyb3VuZCBjb2xvciBjb2RlIGZvciBpZGVudGlmaWVycyAoMzYpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IHN0YWNrIC0gU3R5bGluZyBmb3Igc3RhY2sgdHJhY2VzIChlbXB0eSBvYmplY3QpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IHRpbWVzdGFtcCAtIFN0eWxpbmcgZm9yIHRpbWVzdGFtcHMgKGVtcHR5IG9iamVjdCkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbWVzc2FnZSAtIFN0eWxpbmcgZm9yIGRpZmZlcmVudCB0eXBlcyBvZiBtZXNzYWdlcy5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBtZXNzYWdlLmVycm9yIC0gU3R5bGluZyBmb3IgZXJyb3IgbWVzc2FnZXMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gbWVzc2FnZS5lcnJvci5mZyAtIEZvcmVncm91bmQgY29sb3IgY29kZSBmb3IgZXJyb3IgbWVzc2FnZXMgKDMxKS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBtZXRob2QgLSBTdHlsaW5nIGZvciBtZXRob2QgbmFtZXMgKGVtcHR5IG9iamVjdCkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nTGV2ZWwgLSBTdHlsaW5nIGZvciBkaWZmZXJlbnQgbG9nIGxldmVscy5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2dMZXZlbC5lcnJvciAtIFN0eWxpbmcgZm9yIGVycm9yIGxldmVsIGxvZ3MuXG4gKiBAcHJvcGVydHkge251bWJlcn0gbG9nTGV2ZWwuZXJyb3IuZmcgLSBGb3JlZ3JvdW5kIGNvbG9yIGNvZGUgZm9yIGVycm9yIGxldmVsIGxvZ3MgKDMxKS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IGxvZ0xldmVsLmVycm9yLnN0eWxlIC0gU3R5bGUgYXR0cmlidXRlcyBmb3IgZXJyb3IgbGV2ZWwgbG9ncyAoW1wiYm9sZFwiXSkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nTGV2ZWwuaW5mbyAtIFN0eWxpbmcgZm9yIGluZm8gbGV2ZWwgbG9ncyAoZW1wdHkgb2JqZWN0KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2dMZXZlbC52ZXJib3NlIC0gU3R5bGluZyBmb3IgdmVyYm9zZSBsZXZlbCBsb2dzIChlbXB0eSBvYmplY3QpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGxvZ0xldmVsLmRlYnVnIC0gU3R5bGluZyBmb3IgZGVidWcgbGV2ZWwgbG9ncy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsb2dMZXZlbC5kZWJ1Zy5mZyAtIEZvcmVncm91bmQgY29sb3IgY29kZSBmb3IgZGVidWcgbGV2ZWwgbG9ncyAoMzMpLlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBEZWZhdWx0VGhlbWU6IFRoZW1lID0ge1xuICBhcHA6IHt9LFxuICBzZXBhcmF0b3I6IHt9LFxuICBjbGFzczoge1xuICAgIGZnOiAzNCxcbiAgfSxcbiAgaWQ6IHtcbiAgICBmZzogMzYsXG4gIH0sXG4gIHN0YWNrOiB7fSxcbiAgdGltZXN0YW1wOiB7fSxcbiAgbWVzc2FnZToge1xuICAgIGVycm9yOiB7XG4gICAgICBmZzogMzEsXG4gICAgfSxcbiAgfSxcbiAgbWV0aG9kOiB7fSxcbiAgbG9nTGV2ZWw6IHtcbiAgICBlcnJvcjoge1xuICAgICAgZmc6IDMxLFxuICAgICAgc3R5bGU6IFtcImJvbGRcIl0sXG4gICAgfSxcbiAgICBpbmZvOiB7XG4gICAgICBmZzogMzQsXG4gICAgICBzdHlsZTogW1wiYm9sZFwiXSxcbiAgICB9LFxuICAgIHZlcmJvc2U6IHtcbiAgICAgIGZnOiAzNCxcbiAgICAgIHN0eWxlOiBbXCJib2xkXCJdLFxuICAgIH0sXG4gICAgZGVidWc6IHtcbiAgICAgIGZnOiAzMyxcbiAgICAgIHN0eWxlOiBbXCJib2xkXCJdLFxuICAgIH0sXG4gIH0sXG59O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IGNvbmZpZ3VyYXRpb24gZm9yIGxvZ2dpbmcuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBkZWZhdWx0IHNldHRpbmdzIGZvciB0aGUgbG9nZ2luZyBzeXN0ZW0sIGluY2x1ZGluZyB2ZXJib3NpdHksIGxvZyBsZXZlbCwgc3R5bGluZywgYW5kIHRpbWVzdGFtcCBmb3JtYXQuXG4gKiBAY29uc3QgRGVmYXVsdExvZ2dpbmdDb25maWdcbiAqIEB0eXBlZGVmIHtMb2dnaW5nQ29uZmlnfSBEZWZhdWx0TG9nZ2luZ0NvbmZpZ1xuICogQHByb3BlcnR5IHtudW1iZXJ9IHZlcmJvc2UgLSBWZXJib3NpdHkgbGV2ZWwgKDApLlxuICogQHByb3BlcnR5IHtMb2dMZXZlbH0gbGV2ZWwgLSBEZWZhdWx0IGxvZyBsZXZlbCAoTG9nTGV2ZWwuaW5mbykuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGxvZ0xldmVsIC0gV2hldGhlciB0byBkaXNwbGF5IGxvZyBsZXZlbCBpbiBvdXRwdXQgKHRydWUpLlxuICogQHByb3BlcnR5IHtMb2dnaW5nTW9kZX0gbW9kZSAtIE91dHB1dCBmb3JtYXQgbW9kZSAoTG9nZ2luZ01vZGUuUkFXKS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gc3R5bGUgLSBXaGV0aGVyIHRvIGFwcGx5IHN0eWxpbmcgdG8gbG9nIG91dHB1dCAoZmFsc2UpLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHNlcGFyYXRvciAtIFNlcGFyYXRvciBiZXR3ZWVuIGxvZyBjb21wb25lbnRzIChcIiAtIFwiKS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gdGltZXN0YW1wIC0gV2hldGhlciB0byBpbmNsdWRlIHRpbWVzdGFtcHMgaW4gbG9nIG1lc3NhZ2VzICh0cnVlKS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB0aW1lc3RhbXBGb3JtYXQgLSBGb3JtYXQgZm9yIHRpbWVzdGFtcHMgKFwiSEg6bW06c3MuU1NTXCIpLlxuICogQHByb3BlcnR5IHtib29sZWFufSBjb250ZXh0IC0gV2hldGhlciB0byBpbmNsdWRlIGNvbnRleHQgaW5mb3JtYXRpb24gaW4gbG9nIG1lc3NhZ2VzICh0cnVlKS5cbiAqIEBwcm9wZXJ0eSB7VGhlbWV9IHRoZW1lIC0gVGhlIHRoZW1lIHRvIHVzZSBmb3Igc3R5bGluZyBsb2cgbWVzc2FnZXMgKERlZmF1bHRUaGVtZSkuXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGNvbnN0IERlZmF1bHRMb2dnaW5nQ29uZmlnOiBMb2dnaW5nQ29uZmlnID0ge1xuICBlbnY6IFwiZGV2ZWxvcG1lbnRcIixcbiAgdmVyYm9zZTogMCxcbiAgbGV2ZWw6IExvZ0xldmVsLmluZm8sXG4gIGxvZ0xldmVsOiB0cnVlLFxuICBzdHlsZTogZmFsc2UsXG4gIGNvbnRleHRTZXBhcmF0b3I6IFwiLlwiLFxuICBzZXBhcmF0b3I6IFwiLVwiLFxuICB0aW1lc3RhbXA6IHRydWUsXG4gIHRpbWVzdGFtcEZvcm1hdDogXCJISDptbTpzcy5TU1NcIixcbiAgY29udGV4dDogdHJ1ZSxcbiAgZm9ybWF0OiBMb2dnaW5nTW9kZS5SQVcsXG4gIHBhdHRlcm46XG4gICAgXCJ7bGV2ZWx9IFt7dGltZXN0YW1wfV0ge2FwcH0ge2NvbnRleHR9IHtzZXBhcmF0b3J9IHttZXNzYWdlfSB7c3RhY2t9XCIsXG4gIHRoZW1lOiBEZWZhdWx0VGhlbWUsXG59O1xuIiwiaW1wb3J0IHsgRGVmYXVsdFBsYWNlaG9sZGVyV3JhcHBlcnMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUGFkcyB0aGUgZW5kIG9mIGEgc3RyaW5nIHdpdGggYSBzcGVjaWZpZWQgY2hhcmFjdGVyLlxuICogQHN1bW1hcnkgRXh0ZW5kcyB0aGUgaW5wdXQgc3RyaW5nIHRvIGEgc3BlY2lmaWVkIGxlbmd0aCBieSBhZGRpbmcgYSBwYWRkaW5nIGNoYXJhY3RlciB0byB0aGUgZW5kLlxuICogSWYgdGhlIGlucHV0IHN0cmluZyBpcyBhbHJlYWR5IGxvbmdlciB0aGFuIHRoZSBzcGVjaWZpZWQgbGVuZ3RoLCBpdCBpcyByZXR1cm5lZCB1bmNoYW5nZWQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIFRoZSBpbnB1dCBzdHJpbmcgdG8gYmUgcGFkZGVkLlxuICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCAtIFRoZSBkZXNpcmVkIHRvdGFsIGxlbmd0aCBvZiB0aGUgcmVzdWx0aW5nIHN0cmluZy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbY2hhcj1cIiBcIl0gLSBUaGUgY2hhcmFjdGVyIHRvIHVzZSBmb3IgcGFkZGluZy4gRGVmYXVsdHMgdG8gYSBzcGFjZS5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHBhZGRlZCBzdHJpbmcuXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBhZGRpbmcgY2hhcmFjdGVyIGlzIG5vdCBleGFjdGx5IG9uZSBjaGFyYWN0ZXIgbG9uZy5cbiAqXG4gKiBAZnVuY3Rpb24gcGFkRW5kXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYWRFbmQoXG4gIHN0cjogc3RyaW5nLFxuICBsZW5ndGg6IG51bWJlcixcbiAgY2hhcjogc3RyaW5nID0gXCIgXCJcbik6IHN0cmluZyB7XG4gIGlmIChjaGFyLmxlbmd0aCAhPT0gMSlcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGNoYXJhY3RlciBsZW5ndGggZm9yIHBhZGRpbmcuIG11c3QgYmUgb25lIVwiKTtcbiAgcmV0dXJuIHN0ci5wYWRFbmQobGVuZ3RoLCBjaGFyKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmVwbGFjZXMgcGxhY2Vob2xkZXJzIGluIGEgc3RyaW5nIHdpdGggcHJvdmlkZWQgdmFsdWVzLlxuICogQHN1bW1hcnkgSW50ZXJwb2xhdGVzIGEgc3RyaW5nIGJ5IHJlcGxhY2luZyBwbGFjZWhvbGRlcnMgb2YgdGhlIGZvcm0gJHt2YXJpYWJsZU5hbWV9XG4gKiB3aXRoIGNvcnJlc3BvbmRpbmcgdmFsdWVzIGZyb20gdGhlIHByb3ZpZGVkIG9iamVjdC4gSWYgYSBwbGFjZWhvbGRlciBkb2Vzbid0IGhhdmVcbiAqIGEgY29ycmVzcG9uZGluZyB2YWx1ZSwgaXQgaXMgbGVmdCB1bmNoYW5nZWQgaW4gdGhlIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgLSBUaGUgaW5wdXQgc3RyaW5nIGNvbnRhaW5pbmcgcGxhY2Vob2xkZXJzIHRvIGJlIHJlcGxhY2VkLlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBudW1iZXIgfCBzdHJpbmc+fSB2YWx1ZXMgLSBBbiBvYmplY3QgY29udGFpbmluZyBrZXktdmFsdWUgcGFpcnMgZm9yIHJlcGxhY2VtZW50LlxuICogQHBhcmFtIHByZWZpeFxuICogQHBhcmFtIHN1ZmZpeFxuICogQHBhcmFtIGZsYWdzXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBpbnRlcnBvbGF0ZWQgc3RyaW5nIHdpdGggcGxhY2Vob2xkZXJzIHJlcGxhY2VkIGJ5IHRoZWlyIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICpcbiAqIEBmdW5jdGlvbiBwYXRjaFBsYWNlaG9sZGVyc1xuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IHBhdGNoU3RyaW5nXG4gKiAgIHBhcnRpY2lwYW50IFN0cmluZy5yZXBsYWNlXG4gKiAgIENhbGxlci0+PnBhdGNoU3RyaW5nOiBDYWxsIHdpdGggaW5wdXQgYW5kIHZhbHVlc1xuICogICBwYXRjaFN0cmluZy0+PlN0cmluZy5yZXBsYWNlOiBDYWxsIHdpdGggcmVnZXggYW5kIHJlcGxhY2VtZW50IGZ1bmN0aW9uXG4gKiAgIFN0cmluZy5yZXBsYWNlLT4+cGF0Y2hTdHJpbmc6IFJldHVybiByZXBsYWNlZCBzdHJpbmdcbiAqICAgcGF0Y2hTdHJpbmctLT4+Q2FsbGVyOiBSZXR1cm4gcGF0Y2hlZCBzdHJpbmdcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhdGNoUGxhY2Vob2xkZXJzKFxuICBpbnB1dDogc3RyaW5nLFxuICB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz4sXG4gIHByZWZpeDogc3RyaW5nID0gRGVmYXVsdFBsYWNlaG9sZGVyV3JhcHBlcnNbMF0sXG4gIHN1ZmZpeDogc3RyaW5nID0gRGVmYXVsdFBsYWNlaG9sZGVyV3JhcHBlcnNbMV0sXG4gIGZsYWdzOiBzdHJpbmcgPSBcImdcIlxuKTogc3RyaW5nIHtcbiAgY29uc3QgcGxhY2Vob2xkZXJzID0gT2JqZWN0LmVudHJpZXModmFsdWVzKS5yZWR1Y2UoXG4gICAgKGFjYzogUmVjb3JkPHN0cmluZywgYW55PiwgW2tleSwgdmFsXSkgPT4ge1xuICAgICAgYWNjW2Ake3ByZWZpeH0ke2tleX0ke3N1ZmZpeH1gXSA9IHZhbDtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSxcbiAgICB7fVxuICApO1xuICByZXR1cm4gcGF0Y2hTdHJpbmcoaW5wdXQsIHBsYWNlaG9sZGVycywgZmxhZ3MpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZXBsYWNlcyBvY2N1cnJlbmNlcyBvZiBrZXlzIHdpdGggdGhlaXIgY29ycmVzcG9uZGluZyB2YWx1ZXMgaW4gYSBzdHJpbmcuXG4gKiBAc3VtbWFyeSBJdGVyYXRlcyB0aHJvdWdoIGEgc2V0IG9mIGtleS12YWx1ZSBwYWlycyBhbmQgcmVwbGFjZXMgYWxsIG9jY3VycmVuY2VzIG9mIGVhY2gga2V5XG4gKiBpbiB0aGUgaW5wdXQgc3RyaW5nIHdpdGggaXRzIGNvcnJlc3BvbmRpbmcgdmFsdWUuIFN1cHBvcnRzIHJlZ3VsYXIgZXhwcmVzc2lvbiBmbGFncyBmb3IgY3VzdG9taXplZCByZXBsYWNlbWVudC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgLSBUaGUgaW5wdXQgc3RyaW5nIGluIHdoaWNoIHJlcGxhY2VtZW50cyB3aWxsIGJlIG1hZGUuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz59IHZhbHVlcyAtIEFuIG9iamVjdCBjb250YWluaW5nIGtleS12YWx1ZSBwYWlycyBmb3IgcmVwbGFjZW1lbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gW2ZsYWdzPVwiZ1wiXSAtIFJlZ3VsYXIgZXhwcmVzc2lvbiBmbGFncyB0byBjb250cm9sIHRoZSByZXBsYWNlbWVudCBiZWhhdmlvci5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHN0cmluZyB3aXRoIGFsbCBzcGVjaWZpZWQgcmVwbGFjZW1lbnRzIGFwcGxpZWQuXG4gKlxuICogQGZ1bmN0aW9uIHBhdGNoU3RyaW5nXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXRjaFN0cmluZyhcbiAgaW5wdXQ6IHN0cmluZyxcbiAgdmFsdWVzOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXIgfCBzdHJpbmc+LFxuICBmbGFnczogc3RyaW5nID0gXCJnXCJcbik6IHN0cmluZyB7XG4gIE9iamVjdC5lbnRyaWVzKHZhbHVlcykuZm9yRWFjaCgoW2tleSwgdmFsXSkgPT4ge1xuICAgIGNvbnN0IHJlZ2V4cCA9IG5ldyBSZWdFeHAoZXNjYXBlUmVnRXhwKGtleSksIGZsYWdzKTtcbiAgICBpbnB1dCA9IGlucHV0LnJlcGxhY2UocmVnZXhwLCB2YWwgYXMgc3RyaW5nKTtcbiAgfSk7XG4gIHJldHVybiBpbnB1dDtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29udmVydHMgYSBzdHJpbmcgdG8gY2FtZWxDYXNlLlxuICogQHN1bW1hcnkgVHJhbnNmb3JtcyB0aGUgaW5wdXQgc3RyaW5nIGludG8gY2FtZWxDYXNlIGZvcm1hdCwgd2hlcmUgd29yZHMgYXJlIGpvaW5lZCB3aXRob3V0IHNwYWNlc1xuICogYW5kIGVhY2ggd29yZCBhZnRlciB0aGUgZmlyc3Qgc3RhcnRzIHdpdGggYSBjYXBpdGFsIGxldHRlci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSBpbnB1dCBzdHJpbmcgdG8gYmUgY29udmVydGVkLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgaW5wdXQgc3RyaW5nIGNvbnZlcnRlZCB0byBjYW1lbENhc2UuXG4gKlxuICogQGZ1bmN0aW9uIHRvQ2FtZWxDYXNlXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0NhbWVsQ2FzZSh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdGV4dFxuICAgIC5yZXBsYWNlKC8oPzpeXFx3fFtBLVpdfFxcYlxcdykvZywgKHdvcmQsIGluZGV4KSA9PlxuICAgICAgaW5kZXggPT09IDAgPyB3b3JkLnRvTG93ZXJDYXNlKCkgOiB3b3JkLnRvVXBwZXJDYXNlKClcbiAgICApXG4gICAgLnJlcGxhY2UoL1xccysvZywgXCJcIik7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvbnZlcnRzIGEgc3RyaW5nIHRvIEVOVklST05NRU5UX1ZBUklBQkxFIGZvcm1hdC5cbiAqIEBzdW1tYXJ5IFRyYW5zZm9ybXMgdGhlIGlucHV0IHN0cmluZyBpbnRvIHVwcGVyY2FzZSB3aXRoIHdvcmRzIHNlcGFyYXRlZCBieSB1bmRlcnNjb3JlcyxcbiAqIHR5cGljYWxseSB1c2VkIGZvciBlbnZpcm9ubWVudCB2YXJpYWJsZSBuYW1lcy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSBpbnB1dCBzdHJpbmcgdG8gYmUgY29udmVydGVkLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgaW5wdXQgc3RyaW5nIGNvbnZlcnRlZCB0byBFTlZJUk9OTUVOVF9WQVJJQUJMRSBmb3JtYXQuXG4gKlxuICogQGZ1bmN0aW9uIHRvRU5WRm9ybWF0XG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0VOVkZvcm1hdCh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdG9TbmFrZUNhc2UodGV4dCkudG9VcHBlckNhc2UoKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29udmVydHMgYSBzdHJpbmcgdG8gc25ha2VfY2FzZS5cbiAqIEBzdW1tYXJ5IFRyYW5zZm9ybXMgdGhlIGlucHV0IHN0cmluZyBpbnRvIGxvd2VyY2FzZSB3aXRoIHdvcmRzIHNlcGFyYXRlZCBieSB1bmRlcnNjb3Jlcy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSBpbnB1dCBzdHJpbmcgdG8gYmUgY29udmVydGVkLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgaW5wdXQgc3RyaW5nIGNvbnZlcnRlZCB0byBzbmFrZV9jYXNlLlxuICpcbiAqIEBmdW5jdGlvbiB0b1NuYWtlQ2FzZVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gdG9TbmFrZUNhc2UodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHRleHRcbiAgICAucmVwbGFjZSgvKFthLXpdKShbQS1aXSkvZywgXCIkMV8kMlwiKVxuICAgIC5yZXBsYWNlKC9bXFxzLV0rL2csIFwiX1wiKVxuICAgIC50b0xvd2VyQ2FzZSgpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBhIHN0cmluZyB0byBrZWJhYi1jYXNlLlxuICogQHN1bW1hcnkgVHJhbnNmb3JtcyB0aGUgaW5wdXQgc3RyaW5nIGludG8gbG93ZXJjYXNlIHdpdGggd29yZHMgc2VwYXJhdGVkIGJ5IGh5cGhlbnMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUaGUgaW5wdXQgc3RyaW5nIHRvIGJlIGNvbnZlcnRlZC5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGlucHV0IHN0cmluZyBjb252ZXJ0ZWQgdG8ga2ViYWItY2FzZS5cbiAqXG4gKiBAZnVuY3Rpb24gdG9LZWJhYkNhc2VcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvS2ViYWJDYXNlKHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB0ZXh0XG4gICAgLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csIFwiJDEtJDJcIilcbiAgICAucmVwbGFjZSgvW1xcc19dKy9nLCBcIi1cIilcbiAgICAudG9Mb3dlckNhc2UoKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29udmVydHMgYSBzdHJpbmcgdG8gUGFzY2FsQ2FzZS5cbiAqIEBzdW1tYXJ5IFRyYW5zZm9ybXMgdGhlIGlucHV0IHN0cmluZyBpbnRvIFBhc2NhbENhc2UgZm9ybWF0LCB3aGVyZSB3b3JkcyBhcmUgam9pbmVkIHdpdGhvdXQgc3BhY2VzXG4gKiBhbmQgZWFjaCB3b3JkIHN0YXJ0cyB3aXRoIGEgY2FwaXRhbCBsZXR0ZXIuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUaGUgaW5wdXQgc3RyaW5nIHRvIGJlIGNvbnZlcnRlZC5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGlucHV0IHN0cmluZyBjb252ZXJ0ZWQgdG8gUGFzY2FsQ2FzZS5cbiAqXG4gKiBAZnVuY3Rpb24gdG9QYXNjYWxDYXNlXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b1Bhc2NhbENhc2UodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHRleHRcbiAgICAucmVwbGFjZSgvKD86Xlxcd3xbQS1aXXxcXGJcXHcpL2csICh3b3JkKSA9PiB3b3JkLnRvVXBwZXJDYXNlKCkpXG4gICAgLnJlcGxhY2UoL1xccysvZywgXCJcIik7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVzY2FwZXMgc3BlY2lhbCBjaGFyYWN0ZXJzIGluIGEgc3RyaW5nIGZvciB1c2UgaW4gYSByZWd1bGFyIGV4cHJlc3Npb24uXG4gKiBAc3VtbWFyeSBBZGRzIGJhY2tzbGFzaGVzIGJlZm9yZSBjaGFyYWN0ZXJzIHRoYXQgaGF2ZSBzcGVjaWFsIG1lYW5pbmcgaW4gcmVndWxhciBleHByZXNzaW9ucyxcbiAqIGFsbG93aW5nIHRoZSBzdHJpbmcgdG8gYmUgdXNlZCBhcyBhIGxpdGVyYWwgbWF0Y2ggaW4gYSBSZWdFeHAuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyAtIFRoZSBzdHJpbmcgdG8gZXNjYXBlIGZvciByZWd1bGFyIGV4cHJlc3Npb24gdXNlLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgZXNjYXBlZCBzdHJpbmcgc2FmZSBmb3IgdXNlIGluIHJlZ3VsYXIgZXhwcmVzc2lvbnMuXG4gKlxuICogQGZ1bmN0aW9uIGVzY2FwZVJlZ0V4cFxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gZXNjYXBlUmVnRXhwKHN0cmluZzogc3RyaW5nKSB7XG4gIHJldHVybiBzdHJpbmcucmVwbGFjZSgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2csIFwiXFxcXCQmXCIpOyAvLyAkJiBtZWFucyB0aGUgd2hvbGUgbWF0Y2hlZCBzdHJpbmdcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBVdGlsIGZ1bmN0aW9uIHRvIHByb3ZpZGUgc3RyaW5nIGZvcm1hdCBmdW5jdGlvbmFsaXR5IHNpbWlsYXIgdG8gQyMncyBzdHJpbmcuZm9ybWF0XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZ1xuICogQHBhcmFtIHtBcnJheTxzdHJpbmcgfCBudW1iZXI+IHwgUmVjb3JkPHN0cmluZywgYW55Pn0gW2FyZ3NdIHJlcGxhY2VtZW50cyBtYWRlIGJ5IG9yZGVyIG9mIGFwcGVhcmFuY2UgKHJlcGxhY2VtZW50MCB3aWwgcmVwbGFjZSB7MH0gYW5kIHNvIG9uKVxuICogQHJldHVybiB7c3RyaW5nfSBmb3JtYXR0ZWQgc3RyaW5nXG4gKlxuICogQGZ1bmN0aW9uIHNmXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNmKFxuICBzdHJpbmc6IHN0cmluZyxcbiAgLi4uYXJnczogKHN0cmluZyB8IG51bWJlciB8IFJlY29yZDxzdHJpbmcsIGFueT4pW11cbikge1xuICBpZiAoYXJncy5sZW5ndGggPiAxKSB7XG4gICAgaWYgKFxuICAgICAgIWFyZ3MuZXZlcnkoKGFyZykgPT4gdHlwZW9mIGFyZyA9PT0gXCJzdHJpbmdcIiB8fCB0eXBlb2YgYXJnID09PSBcIm51bWJlclwiKVxuICAgIClcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYE9ubHkgc3RyaW5nIGFuZCBudW1iZXIgYXJndW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIG11bHRpcGxlIHJlcGxhY2VtZW50cy5gXG4gICAgICApO1xuICB9XG5cbiAgaWYgKGFyZ3MubGVuZ3RoID09PSAxICYmIHR5cGVvZiBhcmdzWzBdID09PSBcIm9iamVjdFwiKSB7XG4gICAgY29uc3Qgb2JqID0gYXJnc1swXSBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhvYmopLnJlZHVjZSgoYWNjLCBba2V5LCB2YWxdKSA9PiB7XG4gICAgICByZXR1cm4gYWNjLnJlcGxhY2UobmV3IFJlZ0V4cChgXFxcXHske2tleX1cXFxcfWAsIFwiZ1wiKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgfSk7XG4gICAgfSwgc3RyaW5nKTtcbiAgfVxuXG4gIHJldHVybiBzdHJpbmcucmVwbGFjZSgveyhcXGQrKX0vZywgZnVuY3Rpb24gKG1hdGNoLCBudW1iZXIpIHtcbiAgICByZXR1cm4gdHlwZW9mIGFyZ3NbbnVtYmVyXSAhPT0gXCJ1bmRlZmluZWRcIlxuICAgICAgPyBhcmdzW251bWJlcl0udG9TdHJpbmcoKVxuICAgICAgOiBcInVuZGVmaW5lZFwiO1xuICB9KTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBVdGlsIGZ1bmN0aW9uIHRvIHByb3ZpZGUgc3RyaW5nIGZvcm1hdCBmdW5jdGlvbmFsaXR5IHNpbWlsYXIgdG8gQyMncyBzdHJpbmcuZm9ybWF0XG4gKlxuICogQHNlZSBzZlxuICpcbiAqIEBkZXByZWNhdGVkXG4gKiBAZnVuY3Rpb24gc3RyaW5nRm9ybWF0XG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGNvbnN0IHN0cmluZ0Zvcm1hdCA9IHNmO1xuIiwiLyoqXG4gKiBAZGVzY3JpcHRpb24gRGV0ZXJtaW5lcyBpZiB0aGUgY3VycmVudCBlbnZpcm9ubWVudCBpcyBhIGJyb3dzZXIgYnkgY2hlY2tpbmcgdGhlIHByb3RvdHlwZSBjaGFpbiBvZiB0aGUgZ2xvYmFsIG9iamVjdC5cbiAqIEBzdW1tYXJ5IENoZWNrcyBpZiB0aGUgY29kZSBpcyBydW5uaW5nIGluIGEgYnJvd3NlciBlbnZpcm9ubWVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIGVudmlyb25tZW50IGlzIGEgYnJvd3NlciwgZmFsc2Ugb3RoZXJ3aXNlLlxuICogQGZ1bmN0aW9uIGlzQnJvd3NlclxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Jyb3dzZXIoKTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgT2JqZWN0LmdldFByb3RvdHlwZU9mKE9iamVjdC5nZXRQcm90b3R5cGVPZihnbG9iYWxUaGlzKSkgIT09XG4gICAgT2JqZWN0LnByb3RvdHlwZVxuICApO1xufVxuIiwiaW1wb3J0IHsgT2JqZWN0QWNjdW11bGF0b3IgfSBmcm9tIFwidHlwZWQtb2JqZWN0LWFjY3VtdWxhdG9yXCI7XG5pbXBvcnQgeyB0b0VOVkZvcm1hdCB9IGZyb20gXCIuL3RleHRcIjtcbmltcG9ydCB7IGlzQnJvd3NlciB9IGZyb20gXCIuL3dlYlwiO1xuaW1wb3J0IHtcbiAgQnJvd3NlckVudktleSxcbiAgRGVmYXVsdExvZ2dpbmdDb25maWcsXG4gIEVOVl9QQVRIX0RFTElNSVRFUixcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEZhY3RvcnkgdHlwZSBmb3IgY3JlYXRpbmcgRW52aXJvbm1lbnQgaW5zdGFuY2VzLlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGZ1bmN0aW9uIHR5cGUgdGhhdCBjcmVhdGVzIGFuZCByZXR1cm5zIEVudmlyb25tZW50IGluc3RhbmNlcy5cbiAqXG4gKiBAdGVtcGxhdGUgVCAtIFRoZSB0eXBlIG9mIG9iamVjdCB0aGUgRW52aXJvbm1lbnQgd2lsbCBhY2N1bXVsYXRlLlxuICogQHRlbXBsYXRlIEUgLSBUaGUgc3BlY2lmaWMgRW52aXJvbm1lbnQgdHlwZSB0byBiZSBjcmVhdGVkLCBleHRlbmRpbmcgRW52aXJvbm1lbnQ8VD4uXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oLi4udW5rbm93bltdKTogRX0gRW52aXJvbm1lbnRGYWN0b3J5XG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IHR5cGUgRW52aXJvbm1lbnRGYWN0b3J5PFQgZXh0ZW5kcyBvYmplY3QsIEUgZXh0ZW5kcyBFbnZpcm9ubWVudDxUPj4gPSAoXG4gIC4uLmFyZ3M6IHVua25vd25bXVxuKSA9PiBFO1xuXG4vKipcbiAqIEBjbGFzcyBFbnZpcm9ubWVudFxuICogQGV4dGVuZHMge09iamVjdEFjY3VtdWxhdG9yPFQ+fVxuICogQHRlbXBsYXRlIFRcbiAqIEBkZXNjcmlwdGlvbiBBIGNsYXNzIHJlcHJlc2VudGluZyBhbiBlbnZpcm9ubWVudCB3aXRoIGFjY3VtdWxhdGlvbiBjYXBhYmlsaXRpZXMuXG4gKiBAc3VtbWFyeSBNYW5hZ2VzIGVudmlyb25tZW50LXJlbGF0ZWQgZGF0YSBhbmQgcHJvdmlkZXMgbWV0aG9kcyBmb3IgYWNjdW11bGF0aW9uIGFuZCBrZXkgcmV0cmlldmFsLlxuICogQHBhcmFtIHtUfSBbaW5pdGlhbERhdGFdIC0gVGhlIGluaXRpYWwgZGF0YSB0byBwb3B1bGF0ZSB0aGUgZW52aXJvbm1lbnQgd2l0aC5cbiAqL1xuZXhwb3J0IGNsYXNzIEVudmlyb25tZW50PFQgZXh0ZW5kcyBvYmplY3Q+IGV4dGVuZHMgT2JqZWN0QWNjdW11bGF0b3I8VD4ge1xuICAvKipcbiAgICogQHN0YXRpY1xuICAgKiBAcHJvdGVjdGVkXG4gICAqIEBkZXNjcmlwdGlvbiBBIGZhY3RvcnkgZnVuY3Rpb24gZm9yIGNyZWF0aW5nIEVudmlyb25tZW50IGluc3RhbmNlcy5cbiAgICogQHN1bW1hcnkgRGVmaW5lcyBob3cgbmV3IGluc3RhbmNlcyBvZiB0aGUgRW52aXJvbm1lbnQgY2xhc3Mgc2hvdWxkIGJlIGNyZWF0ZWQuXG4gICAqIEByZXR1cm4ge0Vudmlyb25tZW50PGFueT59IEEgbmV3IGluc3RhbmNlIG9mIHRoZSBFbnZpcm9ubWVudCBjbGFzcy5cbiAgICovXG4gIHByb3RlY3RlZCBzdGF0aWMgZmFjdG9yeTogRW52aXJvbm1lbnRGYWN0b3J5PGFueSwgYW55PiA9XG4gICAgKCk6IEVudmlyb25tZW50PGFueT4gPT4gbmV3IEVudmlyb25tZW50KCk7XG5cbiAgLyoqXG4gICAqIEBzdGF0aWNcbiAgICogQHByaXZhdGVcbiAgICogQGRlc2NyaXB0aW9uIFRoZSBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgdGhlIEVudmlyb25tZW50IGNsYXNzLlxuICAgKiBAdHlwZSB7RW52aXJvbm1lbnQ8YW55Pn1cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIF9pbnN0YW5jZTogRW52aXJvbm1lbnQ8YW55PjtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgdmFsdWUgZnJvbSB0aGUgZW52aXJvbm1lbnRcbiAgICogQHN1bW1hcnkgR2V0cyBhIHZhbHVlIGZyb20gdGhlIGVudmlyb25tZW50IHZhcmlhYmxlcywgaGFuZGxpbmcgYnJvd3NlciBhbmQgTm9kZS5qcyBlbnZpcm9ubWVudHMgZGlmZmVyZW50bHlcbiAgICogQHBhcmFtIHtzdHJpbmd9IGsgLSBUaGUga2V5IHRvIHJldHJpZXZlIGZyb20gdGhlIGVudmlyb25tZW50XG4gICAqIEByZXR1cm4ge3Vua25vd259IFRoZSB2YWx1ZSBmcm9tIHRoZSBlbnZpcm9ubWVudCwgb3IgdW5kZWZpbmVkIGlmIG5vdCBmb3VuZFxuICAgKi9cbiAgcHJvdGVjdGVkIGZyb21FbnYoazogc3RyaW5nKSB7XG4gICAgbGV0IGVudjogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgaWYgKGlzQnJvd3NlcigpKSB7XG4gICAgICBlbnYgPSAoXG4gICAgICAgIGdsb2JhbFRoaXMgYXMgdHlwZW9mIGdsb2JhbFRoaXMgJiB7XG4gICAgICAgICAgW0Jyb3dzZXJFbnZLZXldOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgICAgICB9XG4gICAgICApW0Jyb3dzZXJFbnZLZXldO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbnYgPSBnbG9iYWxUaGlzLnByb2Nlc3MuZW52O1xuICAgICAgayA9IHRvRU5WRm9ybWF0KGspO1xuICAgIH1cbiAgICByZXR1cm4gZW52W2tdO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFeHBhbmRzIGFuIG9iamVjdCBpbnRvIHRoZSBlbnZpcm9ubWVudFxuICAgKiBAc3VtbWFyeSBEZWZpbmVzIHByb3BlcnRpZXMgb24gdGhlIGVudmlyb25tZW50IG9iamVjdCB0aGF0IGNhbiBiZSBhY2Nlc3NlZCBhcyBnZXR0ZXJzIGFuZCBzZXR0ZXJzXG4gICAqIEB0ZW1wbGF0ZSBWIC0gVHlwZSBvZiB0aGUgb2JqZWN0IGJlaW5nIGV4cGFuZGVkXG4gICAqIEBwYXJhbSB7Vn0gdmFsdWUgLSBUaGUgb2JqZWN0IHRvIGV4cGFuZCBpbnRvIHRoZSBlbnZpcm9ubWVudFxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGV4cGFuZDxWIGV4dGVuZHMgb2JqZWN0Pih2YWx1ZTogVik6IHZvaWQge1xuICAgIE9iamVjdC5lbnRyaWVzKHZhbHVlKS5mb3JFYWNoKChbaywgdl0pID0+IHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBrLCB7XG4gICAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGZyb21FbnYgPSB0aGlzLmZyb21FbnYoayk7XG4gICAgICAgICAgaWYgKHR5cGVvZiBmcm9tRW52ICE9PSBcInVuZGVmaW5lZFwiKSByZXR1cm4gZnJvbUVudjtcbiAgICAgICAgICBpZiAodiAmJiB0eXBlb2YgdiA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgcmV0dXJuIEVudmlyb25tZW50LmJ1aWxkRW52UHJveHkodiBhcyBhbnksIFtrXSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIElmIHRoZSBtb2RlbCBwcm92aWRlcyBhbiBlbXB0eSBzdHJpbmcsIGV4cG9zZSBhIHByb3h5IHRoYXQgY29tcG9zZXMgRU5WIGtleXNcbiAgICAgICAgICBpZiAodiA9PT0gXCJcIikge1xuICAgICAgICAgICAgcmV0dXJuIEVudmlyb25tZW50LmJ1aWxkRW52UHJveHkodW5kZWZpbmVkLCBba10pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdjtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiAodmFsOiBWW2tleW9mIFZdKSA9PiB7XG4gICAgICAgICAgdiA9IHZhbDtcbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKiBAc3RhdGljXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgb3IgY3JlYXRlcyB0aGUgc2luZ2xldG9uIGluc3RhbmNlIG9mIHRoZSBFbnZpcm9ubWVudCBjbGFzcy5cbiAgICogQHN1bW1hcnkgRW5zdXJlcyBvbmx5IG9uZSBpbnN0YW5jZSBvZiB0aGUgRW52aXJvbm1lbnQgY2xhc3MgZXhpc3RzLlxuICAgKiBAdGVtcGxhdGUgRVxuICAgKiBAcGFyYW0gey4uLnVua25vd25bXX0gYXJncyAtIEFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBmYWN0b3J5IGZ1bmN0aW9uIGlmIGEgbmV3IGluc3RhbmNlIGlzIGNyZWF0ZWQuXG4gICAqIEByZXR1cm4ge0V9IFRoZSBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgdGhlIEVudmlyb25tZW50IGNsYXNzLlxuICAgKi9cbiAgcHJvdGVjdGVkIHN0YXRpYyBpbnN0YW5jZTxFIGV4dGVuZHMgRW52aXJvbm1lbnQ8YW55Pj4oLi4uYXJnczogdW5rbm93bltdKTogRSB7XG4gICAgaWYgKCFFbnZpcm9ubWVudC5faW5zdGFuY2UpIHtcbiAgICAgIGNvbnN0IGJhc2UgPSBFbnZpcm9ubWVudC5mYWN0b3J5KC4uLmFyZ3MpIGFzIEU7XG4gICAgICBjb25zdCBwcm94aWVkID0gbmV3IFByb3h5KGJhc2UgYXMgYW55LCB7XG4gICAgICAgIGdldCh0YXJnZXQsIHByb3AsIHJlY2VpdmVyKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBSZWZsZWN0LmdldCh0YXJnZXQsIHByb3AsIHJlY2VpdmVyKTtcbiAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcInVuZGVmaW5lZFwiKSByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgaWYgKHR5cGVvZiBwcm9wID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAvLyBBdm9pZCBpbnRlcmZlcmluZyB3aXRoIGxvZ2dpbmcgY29uZmlnIGxvb2t1cHMgZm9yIG9wdGlvbmFsIGZpZWxkcyBsaWtlICdhcHAnXG4gICAgICAgICAgICBpZiAocHJvcCA9PT0gXCJhcHBcIikgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHJldHVybiBFbnZpcm9ubWVudC5idWlsZEVudlByb3h5KHVuZGVmaW5lZCwgW3Byb3BdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBFbnZpcm9ubWVudC5faW5zdGFuY2UgPSBwcm94aWVkIGFzIGFueTtcbiAgICB9XG4gICAgcmV0dXJuIEVudmlyb25tZW50Ll9pbnN0YW5jZSBhcyBFO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdGF0aWNcbiAgICogQGRlc2NyaXB0aW9uIEFjY3VtdWxhdGVzIHRoZSBnaXZlbiB2YWx1ZSBpbnRvIHRoZSBlbnZpcm9ubWVudC5cbiAgICogQHN1bW1hcnkgQWRkcyBuZXcgcHJvcGVydGllcyB0byB0aGUgZW52aXJvbm1lbnQgZnJvbSB0aGUgcHJvdmlkZWQgb2JqZWN0LlxuICAgKiBAdGVtcGxhdGUgVlxuICAgKiBAcGFyYW0ge1Z9IHZhbHVlIC0gVGhlIG9iamVjdCB0byBhY2N1bXVsYXRlIGludG8gdGhlIGVudmlyb25tZW50LlxuICAgKiBAcmV0dXJuIHtWfSBUaGUgdXBkYXRlZCBlbnZpcm9ubWVudCBpbnN0YW5jZS5cbiAgICovXG4gIHN0YXRpYyBhY2N1bXVsYXRlPFYgZXh0ZW5kcyBvYmplY3Q+KFxuICAgIHZhbHVlOiBWXG4gICk6IHR5cGVvZiBFbnZpcm9ubWVudC5faW5zdGFuY2UgJlxuICAgIFYgJlxuICAgIE9iamVjdEFjY3VtdWxhdG9yPHR5cGVvZiBFbnZpcm9ubWVudC5faW5zdGFuY2UgJiBWPiB7XG4gICAgY29uc3QgaW5zdGFuY2UgPSBFbnZpcm9ubWVudC5pbnN0YW5jZSgpO1xuICAgIE9iamVjdC5rZXlzKGluc3RhbmNlIGFzIGFueSkuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICBjb25zdCBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihpbnN0YW5jZSBhcyBhbnksIGtleSk7XG4gICAgICBpZiAoZGVzYyAmJiBkZXNjLmNvbmZpZ3VyYWJsZSAmJiBkZXNjLmVudW1lcmFibGUpIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGluc3RhbmNlIGFzIGFueSwga2V5LCB7XG4gICAgICAgICAgLi4uZGVzYyxcbiAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGluc3RhbmNlLmFjY3VtdWxhdGUodmFsdWUpO1xuICB9XG5cbiAgc3RhdGljIGdldChrZXk6IHN0cmluZykge1xuICAgIHJldHVybiBFbnZpcm9ubWVudC5faW5zdGFuY2UuZ2V0KGtleSk7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBidWlsZEVudlByb3h5KGN1cnJlbnQ6IGFueSwgcGF0aDogc3RyaW5nW10pOiBhbnkge1xuICAgIGNvbnN0IGJ1aWxkS2V5ID0gKHA6IHN0cmluZ1tdKSA9PlxuICAgICAgcC5tYXAoKHNlZykgPT4gdG9FTlZGb3JtYXQoc2VnKSkuam9pbihFTlZfUEFUSF9ERUxJTUlURVIpO1xuXG4gICAgLy8gSGVscGVyIHRvIHJlYWQgZnJvbSB0aGUgYWN0aXZlIGVudmlyb25tZW50IGdpdmVuIGEgY29tcG9zZWQga2V5XG4gICAgY29uc3QgcmVhZEVudiA9IChrZXk6IHN0cmluZyk6IHVua25vd24gPT4ge1xuICAgICAgaWYgKGlzQnJvd3NlcigpKSB7XG4gICAgICAgIGNvbnN0IGVudiA9IChcbiAgICAgICAgICBnbG9iYWxUaGlzIGFzIHR5cGVvZiBnbG9iYWxUaGlzICYge1xuICAgICAgICAgICAgW0Jyb3dzZXJFbnZLZXldPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICAgICAgfVxuICAgICAgICApW0Jyb3dzZXJFbnZLZXldO1xuICAgICAgICByZXR1cm4gZW52ID8gZW52W2tleV0gOiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gKGdsb2JhbFRoaXMgYXMgYW55KT8ucHJvY2Vzcz8uZW52Py5ba2V5XTtcbiAgICB9O1xuXG4gICAgY29uc3QgaGFuZGxlcjogUHJveHlIYW5kbGVyPGFueT4gPSB7XG4gICAgICBnZXQoX3RhcmdldCwgcHJvcDogc3RyaW5nIHwgc3ltYm9sKSB7XG4gICAgICAgIGlmIChwcm9wID09PSBTeW1ib2wudG9QcmltaXRpdmUpIHtcbiAgICAgICAgICByZXR1cm4gKCkgPT4gYnVpbGRLZXkocGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3AgPT09IFwidG9TdHJpbmdcIikge1xuICAgICAgICAgIHJldHVybiAoKSA9PiBidWlsZEtleShwYXRoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcCA9PT0gXCJ2YWx1ZU9mXCIpIHtcbiAgICAgICAgICByZXR1cm4gKCkgPT4gYnVpbGRLZXkocGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwcm9wID09PSBcInN5bWJvbFwiKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgICAgIGNvbnN0IG5leHRNb2RlbCA9XG4gICAgICAgICAgY3VycmVudCAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoY3VycmVudCwgcHJvcClcbiAgICAgICAgICAgID8gKGN1cnJlbnQgYXMgYW55KVtwcm9wXVxuICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICAgIGNvbnN0IG5leHRQYXRoID0gWy4uLnBhdGgsIHByb3BdO1xuICAgICAgICBjb25zdCBjb21wb3NlZEtleSA9IGJ1aWxkS2V5KG5leHRQYXRoKTtcblxuICAgICAgICAvLyBJZiBhbiBFTlYgdmFsdWUgZXhpc3RzIGZvciB0aGlzIHBhdGgsIHJldHVybiBpdCBkaXJlY3RseVxuICAgICAgICBjb25zdCBlbnZWYWx1ZSA9IHJlYWRFbnYoY29tcG9zZWRLZXkpO1xuICAgICAgICBpZiAodHlwZW9mIGVudlZhbHVlICE9PSBcInVuZGVmaW5lZFwiKSByZXR1cm4gZW52VmFsdWU7XG5cbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBpZiB0aGUgbW9kZWwgaGFzIGFuIG9iamVjdCBhdCB0aGlzIHBhdGgsIGtlZXAgZHJpbGxpbmcgd2l0aCBhIHByb3h5XG4gICAgICAgIGNvbnN0IGlzTmV4dE9iamVjdCA9IG5leHRNb2RlbCAmJiB0eXBlb2YgbmV4dE1vZGVsID09PSBcIm9iamVjdFwiO1xuICAgICAgICBpZiAoaXNOZXh0T2JqZWN0KSByZXR1cm4gRW52aXJvbm1lbnQuYnVpbGRFbnZQcm94eShuZXh0TW9kZWwsIG5leHRQYXRoKTtcblxuICAgICAgICAvLyBBbHdheXMgcmV0dXJuIGEgcHJveHkgZm9yIGZ1cnRoZXIgcGF0aCBjb21wb3NpdGlvbiB3aGVuIG5vIEVOViB2YWx1ZTtcbiAgICAgICAgLy8gZG8gbm90IHN1cmZhY2UgcHJpbWl0aXZlIG1vZGVsIGRlZmF1bHRzIGhlcmUgKHRoaXMgQVBJIGlzIGZvciBrZXkgY29tcG9zaXRpb24pLlxuICAgICAgICByZXR1cm4gRW52aXJvbm1lbnQuYnVpbGRFbnZQcm94eSh1bmRlZmluZWQsIG5leHRQYXRoKTtcbiAgICAgIH0sXG4gICAgICBvd25LZXlzKCkge1xuICAgICAgICByZXR1cm4gY3VycmVudCA/IFJlZmxlY3Qub3duS2V5cyhjdXJyZW50KSA6IFtdO1xuICAgICAgfSxcbiAgICAgIGdldE93blByb3BlcnR5RGVzY3JpcHRvcihfdCwgcCkge1xuICAgICAgICBpZiAoIWN1cnJlbnQpIHJldHVybiB1bmRlZmluZWQgYXMgYW55O1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGN1cnJlbnQsIHApKSB7XG4gICAgICAgICAgcmV0dXJuIHsgZW51bWVyYWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gYXMgUHJvcGVydHlEZXNjcmlwdG9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQgYXMgYW55O1xuICAgICAgfSxcbiAgICB9O1xuXG4gICAgY29uc3QgdGFyZ2V0ID0ge30gYXMgYW55O1xuICAgIHJldHVybiBuZXcgUHJveHkodGFyZ2V0LCBoYW5kbGVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3RhdGljXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgdGhlIGtleXMgb2YgdGhlIGVudmlyb25tZW50LCBvcHRpb25hbGx5IGNvbnZlcnRpbmcgdGhlbSB0byBFTlYgZm9ybWF0LlxuICAgKiBAc3VtbWFyeSBHZXRzIGFsbCBrZXlzIGluIHRoZSBlbnZpcm9ubWVudCwgd2l0aCBhbiBvcHRpb24gdG8gZm9ybWF0IHRoZW0gZm9yIGVudmlyb25tZW50IHZhcmlhYmxlcy5cbiAgICogQHBhcmFtIHtib29sZWFufSBbdG9FbnY9dHJ1ZV0gLSBXaGV0aGVyIHRvIGNvbnZlcnQgdGhlIGtleXMgdG8gRU5WIGZvcm1hdC5cbiAgICogQHJldHVybiB7c3RyaW5nW119IEFuIGFycmF5IG9mIGtleXMgZnJvbSB0aGUgZW52aXJvbm1lbnQuXG4gICAqL1xuICBzdGF0aWMga2V5cyh0b0VudjogYm9vbGVhbiA9IHRydWUpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIEVudmlyb25tZW50Lmluc3RhbmNlKClcbiAgICAgIC5rZXlzKClcbiAgICAgIC5tYXAoKGspID0+ICh0b0VudiA/IHRvRU5WRm9ybWF0KGspIDogaykpO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBMb2dnZWRFbnZpcm9ubWVudCA9IEVudmlyb25tZW50LmFjY3VtdWxhdGUoXG4gIE9iamVjdC5hc3NpZ24oe30sIERlZmF1bHRMb2dnaW5nQ29uZmlnLCB7XG4gICAgZW52OlxuICAgICAgKGlzQnJvd3NlcigpICYmIChnbG9iYWxUaGlzIGFzIGFueSlbQnJvd3NlckVudktleV1cbiAgICAgICAgPyAoZ2xvYmFsVGhpcyBhcyBhbnkpW0Jyb3dzZXJFbnZLZXldW1wiTk9ERV9FTlZcIl1cbiAgICAgICAgOiAoZ2xvYmFsVGhpcyBhcyBhbnkpLnByb2Nlc3MuZW52W1wiTk9ERV9FTlZcIl0pIHx8IFwiZGV2ZWxvcG1lbnRcIixcbiAgfSlcbik7XG4iLCJpbXBvcnQge1xuICBMb2dnZXJGYWN0b3J5LFxuICBMb2dnaW5nQ29uZmlnLFxuICBMb2dnaW5nQ29udGV4dCxcbiAgU3RyaW5nTGlrZSxcbiAgVGhlbWUsXG4gIFRoZW1lT3B0aW9uLFxuICBUaGVtZU9wdGlvbkJ5TG9nTGV2ZWwsXG4gIExvZ2dlcixcbn0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IENvbG9yaXplT3B0aW9ucywgc3R5bGUsIFN0eWxlZFN0cmluZyB9IGZyb20gXCJzdHlsZWQtc3RyaW5nLWJ1aWxkZXJcIjtcbmltcG9ydCB7IERlZmF1bHRUaGVtZSwgTG9nTGV2ZWwsIE51bWVyaWNMb2dMZXZlbHMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHNmIH0gZnJvbSBcIi4vdGV4dFwiO1xuaW1wb3J0IHsgTG9nZ2VkRW52aXJvbm1lbnQgfSBmcm9tIFwiLi9lbnZpcm9ubWVudFwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBIG1pbmltYWwgbG9nZ2VyIGltcGxlbWVudGF0aW9uLlxuICogQHN1bW1hcnkgTWluaUxvZ2dlciBpcyBhIGxpZ2h0d2VpZ2h0IGxvZ2dpbmcgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoZSBMb2dnZXIgaW50ZXJmYWNlLlxuICogSXQgcHJvdmlkZXMgYmFzaWMgbG9nZ2luZyBmdW5jdGlvbmFsaXR5IHdpdGggc3VwcG9ydCBmb3IgZGlmZmVyZW50IGxvZyBsZXZlbHMsIHZlcmJvc2l0eSxcbiAqIGNvbnRleHQtYXdhcmUgbG9nZ2luZywgYW5kIGN1c3RvbWl6YWJsZSBmb3JtYXR0aW5nLlxuICogQHBhcmFtIHtzdHJpbmd9IGNvbnRleHQgLSBUaGUgY29udGV4dCAodHlwaWNhbGx5IGNsYXNzIG5hbWUpIHRoaXMgbG9nZ2VyIGlzIGFzc29jaWF0ZWQgd2l0aFxuICogQHBhcmFtIHtQYXJ0aWFsPExvZ2dpbmdDb25maWc+fSBjb25mIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvbiB0byBvdmVycmlkZSBnbG9iYWwgc2V0dGluZ3NcbiAqIEBjbGFzcyBNaW5pTG9nZ2VyXG4gKiBAZXhhbXBsZVxuICogLy8gQ3JlYXRlIGEgbmV3IGxvZ2dlciBmb3IgYSBjbGFzc1xuICogY29uc3QgbG9nZ2VyID0gbmV3IE1pbmlMb2dnZXIoJ015Q2xhc3MnKTtcbiAqXG4gKiAvLyBMb2cgbWVzc2FnZXMgYXQgZGlmZmVyZW50IGxldmVsc1xuICogbG9nZ2VyLmluZm8oJ1RoaXMgaXMgYW4gaW5mbyBtZXNzYWdlJyk7XG4gKiBsb2dnZXIuZGVidWcoJ1RoaXMgaXMgYSBkZWJ1ZyBtZXNzYWdlJyk7XG4gKiBsb2dnZXIuZXJyb3IoJ1NvbWV0aGluZyB3ZW50IHdyb25nJyk7XG4gKlxuICogLy8gQ3JlYXRlIGEgY2hpbGQgbG9nZ2VyIGZvciBhIHNwZWNpZmljIG1ldGhvZFxuICogY29uc3QgbWV0aG9kTG9nZ2VyID0gbG9nZ2VyLmZvcignbXlNZXRob2QnKTtcbiAqIG1ldGhvZExvZ2dlci52ZXJib3NlKCdEZXRhaWxlZCBpbmZvcm1hdGlvbicsIDIpO1xuICpcbiAqIC8vIExvZyB3aXRoIGN1c3RvbSBjb25maWd1cmF0aW9uXG4gKiBsb2dnZXIuZm9yKCdzcGVjaWFsTWV0aG9kJywgeyBzdHlsZTogdHJ1ZSB9KS5pbmZvKCdTdHlsZWQgbWVzc2FnZScpO1xuICovXG5leHBvcnQgY2xhc3MgTWluaUxvZ2dlciBpbXBsZW1lbnRzIExvZ2dlciB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBjb250ZXh0OiBzdHJpbmcsXG4gICAgcHJvdGVjdGVkIGNvbmY/OiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+XG4gICkge31cblxuICBwcm90ZWN0ZWQgY29uZmlnKFxuICAgIGtleToga2V5b2YgTG9nZ2luZ0NvbmZpZ1xuICApOiBMb2dnaW5nQ29uZmlnW2tleW9mIExvZ2dpbmdDb25maWddIHtcbiAgICBpZiAodGhpcy5jb25mICYmIGtleSBpbiB0aGlzLmNvbmYpIHJldHVybiB0aGlzLmNvbmZba2V5XTtcbiAgICByZXR1cm4gTG9nZ2luZy5nZXRDb25maWcoKVtrZXldO1xuICB9XG5cbiAgZm9yKG1ldGhvZDogc3RyaW5nIHwgKCguLi5hcmdzOiBhbnlbXSkgPT4gYW55KSk6IExvZ2dlcjtcbiAgZm9yKGNvbmZpZzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPik6IExvZ2dlcjtcbiAgZm9yKFxuICAgIG1ldGhvZDogc3RyaW5nIHwgKCguLi5hcmdzOiBhbnlbXSkgPT4gYW55KSB8IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4sXG4gICAgY29uZmlnOiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+LFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IExvZ2dlcjtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgY2hpbGQgbG9nZ2VyIGZvciBhIHNwZWNpZmljIG1ldGhvZCBvciBjb250ZXh0XG4gICAqIEBzdW1tYXJ5IFJldHVybnMgYSBuZXcgbG9nZ2VyIGluc3RhbmNlIHdpdGggdGhlIGN1cnJlbnQgY29udGV4dCBleHRlbmRlZCBieSB0aGUgc3BlY2lmaWVkIG1ldGhvZCBuYW1lXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgRnVuY3Rpb259IG1ldGhvZCAtIFRoZSBtZXRob2QgbmFtZSBvciBmdW5jdGlvbiB0byBjcmVhdGUgYSBsb2dnZXIgZm9yXG4gICAqIEBwYXJhbSB7UGFydGlhbDxMb2dnaW5nQ29uZmlnPn0gY29uZmlnIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvbiB0byBvdmVycmlkZSBzZXR0aW5nc1xuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgbG9nZ2VyIGZhY3RvcnlcbiAgICogQHJldHVybiB7TG9nZ2VyfSBBIG5ldyBsb2dnZXIgaW5zdGFuY2UgZm9yIHRoZSBzcGVjaWZpZWQgbWV0aG9kXG4gICAqL1xuICBmb3IoXG4gICAgbWV0aG9kPzogc3RyaW5nIHwgKCguLi5hcmdzOiBhbnlbXSkgPT4gYW55KSB8IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4sXG4gICAgY29uZmlnPzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPixcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogTG9nZ2VyIHtcbiAgICBpZiAoIWNvbmZpZyAmJiB0eXBlb2YgbWV0aG9kID09PSBcIm9iamVjdFwiKSB7XG4gICAgICBjb25maWcgPSBtZXRob2Q7XG4gICAgICBtZXRob2QgPSB1bmRlZmluZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1ldGhvZCA9IG1ldGhvZFxuICAgICAgICA/IHR5cGVvZiBtZXRob2QgPT09IFwic3RyaW5nXCJcbiAgICAgICAgICA/IG1ldGhvZFxuICAgICAgICAgIDogKG1ldGhvZCBhcyBhbnkpLm5hbWVcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQcm94eSh0aGlzLCB7XG4gICAgICBnZXQ6ICh0YXJnZXQ6IHR5cGVvZiB0aGlzLCBwOiBzdHJpbmcgfCBzeW1ib2wsIHJlY2VpdmVyOiBhbnkpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBwLCByZWNlaXZlcik7XG4gICAgICAgIGlmIChwID09PSBcImNvbmZpZ1wiKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBQcm94eSh0aGlzLmNvbmZpZywge1xuICAgICAgICAgICAgZ2V0OiAodGFyZ2V0OiB0eXBlb2YgdGhpcy5jb25maWcsIHA6IHN0cmluZyB8IHN5bWJvbCkgPT4ge1xuICAgICAgICAgICAgICBpZiAoY29uZmlnICYmIHAgaW4gY29uZmlnKVxuICAgICAgICAgICAgICAgIHJldHVybiBjb25maWdbcCBhcyBrZXlvZiBMb2dnaW5nQ29uZmlnXTtcbiAgICAgICAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KHRhcmdldCwgcCwgcmVjZWl2ZXIpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocCA9PT0gXCJjb250ZXh0XCIgJiYgbWV0aG9kKSB7XG4gICAgICAgICAgcmV0dXJuIFtyZXN1bHQsIG1ldGhvZF0uam9pbihcIi5cIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBmb3JtYXR0ZWQgbG9nIHN0cmluZ1xuICAgKiBAc3VtbWFyeSBHZW5lcmF0ZXMgYSBsb2cgc3RyaW5nIHdpdGggdGltZXN0YW1wLCBjb2xvcmVkIGxvZyBsZXZlbCwgY29udGV4dCwgYW5kIG1lc3NhZ2VcbiAgICogQHBhcmFtIHtMb2dMZXZlbH0gbGV2ZWwgLSBUaGUgbG9nIGxldmVsIGZvciB0aGlzIG1lc3NhZ2VcbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlIHwgRXJyb3J9IG1lc3NhZ2UgLSBUaGUgbWVzc2FnZSB0byBsb2cgb3IgYW4gRXJyb3Igb2JqZWN0XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZXJyb3JdIC0gT3B0aW9uYWwgZXJyb3IgdG8gZXh0cmFjdCBzdGFjayB0cmFjZSB0byBpbmNsdWRlIGluIHRoZSBsb2dcbiAgICogQHJldHVybiB7c3RyaW5nfSBBIGZvcm1hdHRlZCBsb2cgc3RyaW5nIHdpdGggYWxsIGNvbXBvbmVudHNcbiAgICovXG4gIHByb3RlY3RlZCBjcmVhdGVMb2coXG4gICAgbGV2ZWw6IExvZ0xldmVsLFxuICAgIG1lc3NhZ2U6IFN0cmluZ0xpa2UgfCBFcnJvcixcbiAgICBlcnJvcj86IEVycm9yXG4gICk6IHN0cmluZyB7XG4gICAgY29uc3QgbG9nOiBSZWNvcmQ8XG4gICAgICB8IFwidGltZXN0YW1wXCJcbiAgICAgIHwgXCJsZXZlbFwiXG4gICAgICB8IFwiY29udGV4dFwiXG4gICAgICB8IFwiY29ycmVsYXRpb25JZFwiXG4gICAgICB8IFwibWVzc2FnZVwiXG4gICAgICB8IFwic2VwYXJhdG9yXCJcbiAgICAgIHwgXCJzdGFja1wiXG4gICAgICB8IFwiYXBwXCIsXG4gICAgICBzdHJpbmdcbiAgICA+ID0ge30gYXMgYW55O1xuICAgIGNvbnN0IHN0eWxlID0gdGhpcy5jb25maWcoXCJzdHlsZVwiKTtcbiAgICBjb25zdCBzZXBhcmF0b3IgPSB0aGlzLmNvbmZpZyhcInNlcGFyYXRvclwiKTtcbiAgICBjb25zdCBhcHAgPSB0aGlzLmNvbmZpZyhcImFwcFwiKTtcbiAgICBpZiAoYXBwKVxuICAgICAgbG9nLmFwcCA9IHN0eWxlXG4gICAgICAgID8gTG9nZ2luZy50aGVtZShhcHAgYXMgc3RyaW5nLCBcImFwcFwiLCBsZXZlbClcbiAgICAgICAgOiAoYXBwIGFzIHN0cmluZyk7XG5cbiAgICBpZiAoc2VwYXJhdG9yKVxuICAgICAgbG9nLnNlcGFyYXRvciA9IHN0eWxlXG4gICAgICAgID8gTG9nZ2luZy50aGVtZShzZXBhcmF0b3IgYXMgc3RyaW5nLCBcInNlcGFyYXRvclwiLCBsZXZlbClcbiAgICAgICAgOiAoc2VwYXJhdG9yIGFzIHN0cmluZyk7XG5cbiAgICBpZiAodGhpcy5jb25maWcoXCJ0aW1lc3RhbXBcIikpIHtcbiAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gICAgICBjb25zdCB0aW1lc3RhbXAgPSBzdHlsZSA/IExvZ2dpbmcudGhlbWUoZGF0ZSwgXCJ0aW1lc3RhbXBcIiwgbGV2ZWwpIDogZGF0ZTtcbiAgICAgIGxvZy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnKFwibG9nTGV2ZWxcIikpIHtcbiAgICAgIGNvbnN0IGx2bDogc3RyaW5nID0gc3R5bGVcbiAgICAgICAgPyBMb2dnaW5nLnRoZW1lKGxldmVsLCBcImxvZ0xldmVsXCIsIGxldmVsKVxuICAgICAgICA6IGxldmVsO1xuICAgICAgbG9nLmxldmVsID0gbHZsLnRvVXBwZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnKFwiY29udGV4dFwiKSkge1xuICAgICAgY29uc3QgY29udGV4dDogc3RyaW5nID0gc3R5bGVcbiAgICAgICAgPyBMb2dnaW5nLnRoZW1lKHRoaXMuY29udGV4dCwgXCJjbGFzc1wiLCBsZXZlbClcbiAgICAgICAgOiB0aGlzLmNvbnRleHQ7XG4gICAgICBsb2cuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnKFwiY29ycmVsYXRpb25JZFwiKSkge1xuICAgICAge1xuICAgICAgICBjb25zdCBpZDogc3RyaW5nID0gc3R5bGVcbiAgICAgICAgICA/IExvZ2dpbmcudGhlbWUodGhpcy5jb25maWcoXCJjb3JyZWxhdGlvbklkXCIpIS50b1N0cmluZygpLCBcImlkXCIsIGxldmVsKVxuICAgICAgICAgIDogdGhpcy5jb25maWcoXCJjb3JyZWxhdGlvbklkXCIpIS50b1N0cmluZygpO1xuICAgICAgICBsb2cuY29ycmVsYXRpb25JZCA9IGlkO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IG1zZzogc3RyaW5nID0gc3R5bGVcbiAgICAgID8gTG9nZ2luZy50aGVtZShcbiAgICAgICAgICB0eXBlb2YgbWVzc2FnZSA9PT0gXCJzdHJpbmdcIiA/IG1lc3NhZ2UgOiAobWVzc2FnZSBhcyBFcnJvcikubWVzc2FnZSxcbiAgICAgICAgICBcIm1lc3NhZ2VcIixcbiAgICAgICAgICBsZXZlbFxuICAgICAgICApXG4gICAgICA6IHR5cGVvZiBtZXNzYWdlID09PSBcInN0cmluZ1wiXG4gICAgICAgID8gbWVzc2FnZVxuICAgICAgICA6IChtZXNzYWdlIGFzIEVycm9yKS5tZXNzYWdlO1xuICAgIGxvZy5tZXNzYWdlID0gbXNnO1xuICAgIGlmIChlcnJvciB8fCBtZXNzYWdlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIGNvbnN0IHN0YWNrID0gc3R5bGVcbiAgICAgICAgPyBMb2dnaW5nLnRoZW1lKFxuICAgICAgICAgICAgKGVycm9yPy5zdGFjayB8fCAobWVzc2FnZSBhcyBFcnJvcikuc3RhY2spIGFzIHN0cmluZyxcbiAgICAgICAgICAgIFwic3RhY2tcIixcbiAgICAgICAgICAgIGxldmVsXG4gICAgICAgICAgKVxuICAgICAgICA6IGVycm9yPy5zdGFjayB8fCBcIlwiO1xuICAgICAgbG9nLnN0YWNrID0gYCB8ICR7KGVycm9yIHx8IChtZXNzYWdlIGFzIEVycm9yKSkubWVzc2FnZX0gLSBTdGFjayB0cmFjZTpcXG4ke3N0YWNrfWA7XG4gICAgfVxuXG4gICAgc3dpdGNoICh0aGlzLmNvbmZpZyhcImZvcm1hdFwiKSkge1xuICAgICAgY2FzZSBcImpzb25cIjpcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGxvZyk7XG4gICAgICBjYXNlIFwicmF3XCI6XG4gICAgICAgIHJldHVybiAodGhpcy5jb25maWcoXCJwYXR0ZXJuXCIpIGFzIHN0cmluZylcbiAgICAgICAgICAuc3BsaXQoXCIgXCIpXG4gICAgICAgICAgLm1hcCgocykgPT4ge1xuICAgICAgICAgICAgaWYgKCFzLm1hdGNoKC9cXHsuKj99L2cpKSByZXR1cm4gcztcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZFMgPSBzZihzLCBsb2cpO1xuICAgICAgICAgICAgaWYgKGZvcm1hdHRlZFMgIT09IHMpIHJldHVybiBmb3JtYXR0ZWRTO1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5maWx0ZXIoKHMpID0+IHMpXG4gICAgICAgICAgLmpvaW4oXCIgXCIpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBsb2dnaW5nIGZvcm1hdDogJHt0aGlzLmNvbmZpZyhcImZvcm1hdFwiKX1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIHdpdGggdGhlIHNwZWNpZmllZCBsb2cgbGV2ZWxcbiAgICogQHN1bW1hcnkgQ2hlY2tzIGlmIHRoZSBtZXNzYWdlIHNob3VsZCBiZSBsb2dnZWQgYmFzZWQgb24gdGhlIGN1cnJlbnQgbG9nIGxldmVsLFxuICAgKiB0aGVuIHVzZXMgdGhlIGFwcHJvcHJpYXRlIGNvbnNvbGUgbWV0aG9kIHRvIG91dHB1dCB0aGUgZm9ybWF0dGVkIGxvZ1xuICAgKiBAcGFyYW0ge0xvZ0xldmVsfSBsZXZlbCAtIFRoZSBsb2cgbGV2ZWwgb2YgdGhlIG1lc3NhZ2VcbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlIHwgRXJyb3J9IG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZCBvciBhbiBFcnJvciBvYmplY3RcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtlcnJvcl0gLSBPcHRpb25hbCBzdGFjayB0cmFjZSB0byBpbmNsdWRlIGluIHRoZSBsb2dcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHByb3RlY3RlZCBsb2cobGV2ZWw6IExvZ0xldmVsLCBtc2c6IFN0cmluZ0xpa2UgfCBFcnJvciwgZXJyb3I/OiBFcnJvcik6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZMdmwgPSB0aGlzLmNvbmZpZyhcImxldmVsXCIpIGFzIExvZ0xldmVsO1xuICAgIGlmIChOdW1lcmljTG9nTGV2ZWxzW2NvbmZMdmxdIDwgTnVtZXJpY0xvZ0xldmVsc1tsZXZlbF0pIHJldHVybjtcbiAgICBsZXQgbWV0aG9kO1xuICAgIHN3aXRjaCAobGV2ZWwpIHtcbiAgICAgIGNhc2UgTG9nTGV2ZWwuaW5mbzpcbiAgICAgICAgbWV0aG9kID0gY29uc29sZS5sb2c7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBMb2dMZXZlbC52ZXJib3NlOlxuICAgICAgY2FzZSBMb2dMZXZlbC5kZWJ1ZzpcbiAgICAgICAgbWV0aG9kID0gY29uc29sZS5kZWJ1ZztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIExvZ0xldmVsLmVycm9yOlxuICAgICAgICBtZXRob2QgPSBjb25zb2xlLmVycm9yO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgbG9nIGxldmVsXCIpO1xuICAgIH1cbiAgICBtZXRob2QodGhpcy5jcmVhdGVMb2cobGV2ZWwsIG1zZywgZXJyb3IpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIHNpbGx5IGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBzaWxseSBsZXZlbCBpZiB0aGUgY3VycmVudCB2ZXJib3NpdHkgc2V0dGluZyBhbGxvd3MgaXRcbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWRcbiAgICogQHBhcmFtIHtudW1iZXJ9IFt2ZXJib3NpdHk9MF0gLSBUaGUgdmVyYm9zaXR5IGxldmVsIG9mIHRoZSBtZXNzYWdlXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzaWxseShtc2c6IFN0cmluZ0xpa2UsIHZlcmJvc2l0eTogbnVtYmVyID0gMCk6IHZvaWQge1xuICAgIGlmICgodGhpcy5jb25maWcoXCJ2ZXJib3NlXCIpIGFzIG51bWJlcikgPj0gdmVyYm9zaXR5KVxuICAgICAgdGhpcy5sb2coTG9nTGV2ZWwudmVyYm9zZSwgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIHZlcmJvc2UgbGV2ZWxcbiAgICogQHN1bW1hcnkgTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIHZlcmJvc2UgbGV2ZWwgaWYgdGhlIGN1cnJlbnQgdmVyYm9zaXR5IHNldHRpbmcgYWxsb3dzIGl0XG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZX0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbdmVyYm9zaXR5PTBdIC0gVGhlIHZlcmJvc2l0eSBsZXZlbCBvZiB0aGUgbWVzc2FnZVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgdmVyYm9zZShtc2c6IFN0cmluZ0xpa2UsIHZlcmJvc2l0eTogbnVtYmVyID0gMCk6IHZvaWQge1xuICAgIGlmICgodGhpcy5jb25maWcoXCJ2ZXJib3NlXCIpIGFzIG51bWJlcikgPj0gdmVyYm9zaXR5KVxuICAgICAgdGhpcy5sb2coTG9nTGV2ZWwudmVyYm9zZSwgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGluZm8gbGV2ZWxcbiAgICogQHN1bW1hcnkgTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGluZm8gbGV2ZWwgZm9yIGdlbmVyYWwgYXBwbGljYXRpb24gaW5mb3JtYXRpb25cbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWRcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIGluZm8obXNnOiBTdHJpbmdMaWtlKTogdm9pZCB7XG4gICAgdGhpcy5sb2coTG9nTGV2ZWwuaW5mbywgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGRlYnVnIGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBkZWJ1ZyBsZXZlbCBmb3IgZGV0YWlsZWQgdHJvdWJsZXNob290aW5nIGluZm9ybWF0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZX0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBkZWJ1Zyhtc2c6IFN0cmluZ0xpa2UpOiB2b2lkIHtcbiAgICB0aGlzLmxvZyhMb2dMZXZlbC5kZWJ1ZywgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGVycm9yIGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBlcnJvciBsZXZlbCBmb3IgZXJyb3JzIGFuZCBleGNlcHRpb25zXG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZSB8IEVycm9yfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQgb3IgYW4gRXJyb3Igb2JqZWN0XG4gICAqIEBwYXJhbSBlXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBlcnJvcihtc2c6IFN0cmluZ0xpa2UgfCBFcnJvciwgZT86IEVycm9yKTogdm9pZCB7XG4gICAgdGhpcy5sb2coTG9nTGV2ZWwuZXJyb3IsIG1zZywgZSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVwZGF0ZXMgdGhlIGxvZ2dlciBjb25maWd1cmF0aW9uXG4gICAqIEBzdW1tYXJ5IE1lcmdlcyB0aGUgcHJvdmlkZWQgY29uZmlndXJhdGlvbiB3aXRoIHRoZSBleGlzdGluZyBjb25maWd1cmF0aW9uXG4gICAqIEBwYXJhbSB7UGFydGlhbDxMb2dnaW5nQ29uZmlnPn0gY29uZmlnIC0gVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byBhcHBseVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc2V0Q29uZmlnKGNvbmZpZzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPik6IHZvaWQge1xuICAgIHRoaXMuY29uZiA9IHsgLi4uKHRoaXMuY29uZiB8fCB7fSksIC4uLmNvbmZpZyB9O1xuICB9XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgc3RhdGljIGNsYXNzIGZvciBtYW5hZ2luZyBsb2dnaW5nIG9wZXJhdGlvbnNcbiAqIEBzdW1tYXJ5IFRoZSBMb2dnaW5nIGNsYXNzIHByb3ZpZGVzIGEgY2VudHJhbGl6ZWQgbG9nZ2luZyBtZWNoYW5pc20gd2l0aCBzdXBwb3J0IGZvclxuICogZGlmZmVyZW50IGxvZyBsZXZlbHMsIHZlcmJvc2l0eSwgYW5kIHN0eWxpbmcuIEl0IHVzZXMgYSBzaW5nbGV0b24gcGF0dGVybiB0byBtYWludGFpbiBhIGdsb2JhbFxuICogbG9nZ2VyIGluc3RhbmNlIGFuZCBhbGxvd3MgY3JlYXRpbmcgc3BlY2lmaWMgbG9nZ2VycyBmb3IgZGlmZmVyZW50IGNsYXNzZXMgYW5kIG1ldGhvZHMuXG4gKiBAY2xhc3MgTG9nZ2luZ1xuICogQGV4YW1wbGVcbiAqIC8vIFNldCBnbG9iYWwgY29uZmlndXJhdGlvblxuICogTG9nZ2luZy5zZXRDb25maWcoeyBsZXZlbDogTG9nTGV2ZWwuZGVidWcsIHN0eWxlOiB0cnVlIH0pO1xuICpcbiAqIC8vIEdldCBhIGxvZ2dlciBmb3IgYSBzcGVjaWZpYyBjbGFzc1xuICogY29uc3QgbG9nZ2VyID0gTG9nZ2luZy5mb3IoJ015Q2xhc3MnKTtcbiAqXG4gKiAvLyBMb2cgbWVzc2FnZXMgYXQgZGlmZmVyZW50IGxldmVsc1xuICogbG9nZ2VyLmluZm8oJ0FwcGxpY2F0aW9uIHN0YXJ0ZWQnKTtcbiAqIGxvZ2dlci5kZWJ1ZygnUHJvY2Vzc2luZyBkYXRhLi4uJyk7XG4gKlxuICogLy8gTG9nIHdpdGggY29udGV4dFxuICogY29uc3QgbWV0aG9kTG9nZ2VyID0gTG9nZ2luZy5mb3IoJ015Q2xhc3MubXlNZXRob2QnKTtcbiAqIG1ldGhvZExvZ2dlci52ZXJib3NlKCdEZXRhaWxlZCBvcGVyYXRpb24gaW5mb3JtYXRpb24nLCAxKTtcbiAqXG4gKiAvLyBMb2cgZXJyb3JzXG4gKiB0cnkge1xuICogICAvLyBzb21lIG9wZXJhdGlvblxuICogfSBjYXRjaCAoZXJyb3IpIHtcbiAqICAgbG9nZ2VyLmVycm9yKGVycm9yKTtcbiAqIH1cbiAqIEBtZXJtYWlkXG4gKiBjbGFzc0RpYWdyYW1cbiAqICAgY2xhc3MgTG9nZ2VyIHtcbiAqICAgICA8PGludGVyZmFjZT4+XG4gKiAgICAgK2ZvcihtZXRob2QsIGNvbmZpZywgLi4uYXJncylcbiAqICAgICArc2lsbHkobXNnLCB2ZXJib3NpdHkpXG4gKiAgICAgK3ZlcmJvc2UobXNnLCB2ZXJib3NpdHkpXG4gKiAgICAgK2luZm8obXNnKVxuICogICAgICtkZWJ1Zyhtc2cpXG4gKiAgICAgK2Vycm9yKG1zZylcbiAqICAgICArc2V0Q29uZmlnKGNvbmZpZylcbiAqICAgfVxuICpcbiAqICAgY2xhc3MgTG9nZ2luZyB7XG4gKiAgICAgLWdsb2JhbDogTG9nZ2VyXG4gKiAgICAgLV9mYWN0b3J5OiBMb2dnZXJGYWN0b3J5XG4gKiAgICAgLV9jb25maWc6IExvZ2dpbmdDb25maWdcbiAqICAgICArc2V0RmFjdG9yeShmYWN0b3J5KVxuICogICAgICtzZXRDb25maWcoY29uZmlnKVxuICogICAgICtnZXRDb25maWcoKVxuICogICAgICtnZXQoKVxuICogICAgICt2ZXJib3NlKG1zZywgdmVyYm9zaXR5KVxuICogICAgICtpbmZvKG1zZylcbiAqICAgICArZGVidWcobXNnKVxuICogICAgICtzaWxseShtc2cpXG4gKiAgICAgK2Vycm9yKG1zZylcbiAqICAgICArZm9yKG9iamVjdCwgY29uZmlnLCAuLi5hcmdzKVxuICogICAgICtiZWNhdXNlKHJlYXNvbiwgaWQpXG4gKiAgICAgK3RoZW1lKHRleHQsIHR5cGUsIGxvZ2dlckxldmVsLCB0ZW1wbGF0ZSlcbiAqICAgfVxuICpcbiAqICAgY2xhc3MgTWluaUxvZ2dlciB7XG4gKiAgICAgK2NvbnN0cnVjdG9yKGNvbnRleHQsIGNvbmY/KVxuICogICB9XG4gKlxuICogICBMb2dnaW5nIC4uPiBMb2dnZXIgOiBjcmVhdGVzXG4gKiAgIExvZ2dpbmcgLi4+IE1pbmlMb2dnZXIgOiBjcmVhdGVzIGJ5IGRlZmF1bHRcbiAqL1xuZXhwb3J0IGNsYXNzIExvZ2dpbmcge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlXG4gICAqIEBzdW1tYXJ5IEEgc2luZ2xldG9uIGluc3RhbmNlIG9mIExvZ2dlciB1c2VkIGZvciBnbG9iYWwgbG9nZ2luZ1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZ2xvYmFsPzogTG9nZ2VyO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRmFjdG9yeSBmdW5jdGlvbiBmb3IgY3JlYXRpbmcgbG9nZ2VyIGluc3RhbmNlc1xuICAgKiBAc3VtbWFyeSBBIGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBuZXcgTG9nZ2VyIGluc3RhbmNlcy4gQnkgZGVmYXVsdCwgaXQgY3JlYXRlcyBhIE1pbmlMb2dnZXIuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBfZmFjdG9yeTogTG9nZ2VyRmFjdG9yeSA9IChcbiAgICBvYmplY3Q6IHN0cmluZyxcbiAgICBjb25maWc/OiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+XG4gICkgPT4ge1xuICAgIHJldHVybiBuZXcgTWluaUxvZ2dlcihvYmplY3QsIGNvbmZpZyk7XG4gIH07XG5cbiAgcHJpdmF0ZSBzdGF0aWMgX2NvbmZpZzogdHlwZW9mIExvZ2dlZEVudmlyb25tZW50ID0gTG9nZ2VkRW52aXJvbm1lbnQ7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBmYWN0b3J5IGZ1bmN0aW9uIGZvciBjcmVhdGluZyBsb2dnZXIgaW5zdGFuY2VzXG4gICAqIEBzdW1tYXJ5IEFsbG93cyBjdXN0b21pemluZyBob3cgbG9nZ2VyIGluc3RhbmNlcyBhcmUgY3JlYXRlZFxuICAgKiBAcGFyYW0ge0xvZ2dlckZhY3Rvcnl9IGZhY3RvcnkgLSBUaGUgZmFjdG9yeSBmdW5jdGlvbiB0byB1c2UgZm9yIGNyZWF0aW5nIGxvZ2dlcnNcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHN0YXRpYyBzZXRGYWN0b3J5KGZhY3Rvcnk6IExvZ2dlckZhY3RvcnkpIHtcbiAgICBMb2dnaW5nLl9mYWN0b3J5ID0gZmFjdG9yeTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVXBkYXRlcyB0aGUgZ2xvYmFsIGxvZ2dpbmcgY29uZmlndXJhdGlvblxuICAgKiBAc3VtbWFyeSBBbGxvd3MgdXBkYXRpbmcgdGhlIGdsb2JhbCBsb2dnaW5nIGNvbmZpZ3VyYXRpb24gd2l0aCBuZXcgc2V0dGluZ3NcbiAgICogQHBhcmFtIHtQYXJ0aWFsPExvZ2dpbmdDb25maWc+fSBjb25maWcgLSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIGFwcGx5XG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzdGF0aWMgc2V0Q29uZmlnKGNvbmZpZzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPik6IHZvaWQge1xuICAgIE9iamVjdC5lbnRyaWVzKGNvbmZpZykuZm9yRWFjaCgoW2ssIHZdKSA9PiB7XG4gICAgICAodGhpcy5fY29uZmlnIGFzIGFueSlba10gPSB2IGFzIGFueTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyBhIGNvcHkgb2YgdGhlIGN1cnJlbnQgZ2xvYmFsIGxvZ2dpbmcgY29uZmlndXJhdGlvblxuICAgKiBAc3VtbWFyeSBSZXR1cm5zIGEgY29weSBvZiB0aGUgY3VycmVudCBnbG9iYWwgbG9nZ2luZyBjb25maWd1cmF0aW9uXG4gICAqIEByZXR1cm4ge0xvZ2dpbmdDb25maWd9IEEgY29weSBvZiB0aGUgY3VycmVudCBjb25maWd1cmF0aW9uXG4gICAqL1xuICBzdGF0aWMgZ2V0Q29uZmlnKCk6IHR5cGVvZiBMb2dnZWRFbnZpcm9ubWVudCB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbmZpZztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIG9yIGNyZWF0ZXMgdGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIGV4aXN0aW5nIGdsb2JhbCBsb2dnZXIgb3IgY3JlYXRlcyBhIG5ldyBvbmUgaWYgaXQgZG9lc24ndCBleGlzdC5cbiAgICpcbiAgICogQHJldHVybiBUaGUgZ2xvYmFsIFZlcmJvc2l0eUxvZ2dlciBpbnN0YW5jZS5cbiAgICovXG4gIHN0YXRpYyBnZXQoKTogTG9nZ2VyIHtcbiAgICB0aGlzLmdsb2JhbCA9IHRoaXMuZ2xvYmFsID8gdGhpcy5nbG9iYWwgOiB0aGlzLl9mYWN0b3J5KFwiTG9nZ2luZ1wiKTtcbiAgICByZXR1cm4gdGhpcy5nbG9iYWw7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSB2ZXJib3NlIG1lc3NhZ2UuXG4gICAqIEBzdW1tYXJ5IERlbGVnYXRlcyB0aGUgdmVyYm9zZSBsb2dnaW5nIHRvIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLlxuICAgKiBAcGFyYW0gdmVyYm9zaXR5IC0gVGhlIHZlcmJvc2l0eSBsZXZlbCBvZiB0aGUgbWVzc2FnZSAoZGVmYXVsdDogMCkuXG4gICAqL1xuICBzdGF0aWMgdmVyYm9zZShtc2c6IFN0cmluZ0xpa2UsIHZlcmJvc2l0eTogbnVtYmVyID0gMCk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmdldCgpLnZlcmJvc2UobXNnLCB2ZXJib3NpdHkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGFuIGluZm8gbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRoZSBpbmZvIGxvZ2dpbmcgdG8gdGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuXG4gICAqL1xuICBzdGF0aWMgaW5mbyhtc2c6IFN0cmluZ0xpa2UpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5pbmZvKG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBkZWJ1ZyBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdGhlIGRlYnVnIGxvZ2dpbmcgdG8gdGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuXG4gICAqL1xuICBzdGF0aWMgZGVidWcobXNnOiBTdHJpbmdMaWtlKTogdm9pZCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkuZGVidWcobXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIHNpbGx5IG1lc3NhZ2UuXG4gICAqIEBzdW1tYXJ5IERlbGVnYXRlcyB0aGUgZGVidWcgbG9nZ2luZyB0byB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC5cbiAgICovXG4gIHN0YXRpYyBzaWxseShtc2c6IFN0cmluZ0xpa2UpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5zaWxseShtc2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGFuIGVycm9yIG1lc3NhZ2UuXG4gICAqIEBzdW1tYXJ5IERlbGVnYXRlcyB0aGUgZXJyb3IgbG9nZ2luZyB0byB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC5cbiAgICogQHBhcmFtIGVcbiAgICovXG4gIHN0YXRpYyBlcnJvcihtc2c6IFN0cmluZ0xpa2UsIGU/OiBFcnJvcik6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmdldCgpLmVycm9yKG1zZywgZSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBsb2dnZXIgZm9yIGEgc3BlY2lmaWMgb2JqZWN0IG9yIGNvbnRleHRcbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIG5ldyBsb2dnZXIgaW5zdGFuY2UgZm9yIHRoZSBnaXZlbiBvYmplY3Qgb3IgY29udGV4dCB1c2luZyB0aGUgZmFjdG9yeSBmdW5jdGlvblxuICAgKiBAcGFyYW0ge0xvZ2dpbmdDb250ZXh0fSBvYmplY3QgLSBUaGUgb2JqZWN0LCBjbGFzcywgb3IgY29udGV4dCB0byBjcmVhdGUgYSBsb2dnZXIgZm9yXG4gICAqIEBwYXJhbSB7UGFydGlhbDxMb2dnaW5nQ29uZmlnPn0gW2NvbmZpZ10gLSBPcHRpb25hbCBjb25maWd1cmF0aW9uIHRvIG92ZXJyaWRlIGdsb2JhbCBzZXR0aW5nc1xuICAgKiBAcGFyYW0gey4uLmFueX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGxvZ2dlciBmYWN0b3J5XG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gQSBuZXcgbG9nZ2VyIGluc3RhbmNlIGZvciB0aGUgc3BlY2lmaWVkIG9iamVjdCBvciBjb250ZXh0XG4gICAqL1xuICBzdGF0aWMgZm9yKFxuICAgIG9iamVjdDogTG9nZ2luZ0NvbnRleHQsXG4gICAgY29uZmlnPzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPixcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBMb2dnZXIge1xuICAgIG9iamVjdCA9XG4gICAgICB0eXBlb2Ygb2JqZWN0ID09PSBcInN0cmluZ1wiXG4gICAgICAgID8gb2JqZWN0XG4gICAgICAgIDogb2JqZWN0LmNvbnN0cnVjdG9yXG4gICAgICAgICAgPyBvYmplY3QuY29uc3RydWN0b3IubmFtZVxuICAgICAgICAgIDogb2JqZWN0Lm5hbWU7XG4gICAgcmV0dXJuIHRoaXMuX2ZhY3Rvcnkob2JqZWN0LCBjb25maWcsIC4uLmFyZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbG9nZ2VyIGZvciBhIHNwZWNpZmljIHJlYXNvbiBvciBjb3JyZWxhdGlvbiBjb250ZXh0XG4gICAqIEBzdW1tYXJ5IFV0aWxpdHkgdG8gcXVpY2tseSBjcmVhdGUgYSBsb2dnZXIgbGFiZWxlZCB3aXRoIGEgZnJlZS1mb3JtIHJlYXNvbiBhbmQgb3B0aW9uYWwgaWRlbnRpZmllclxuICAgKiBzbyB0aGF0IGFkLWhvYyBvcGVyYXRpb25zIGNhbiBiZSB0cmFjZWQgd2l0aG91dCB0eWluZyB0aGUgbG9nZ2VyIHRvIGEgY2xhc3Mgb3IgbWV0aG9kIG5hbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZWFzb24gLSBBIHRleHR1YWwgcmVhc29uIG9yIGNvbnRleHQgbGFiZWwgZm9yIHRoaXMgbG9nZ2VyIGluc3RhbmNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbaWRdIC0gT3B0aW9uYWwgaWRlbnRpZmllciB0byBoZWxwIGNvcnJlbGF0ZSByZWxhdGVkIGxvZyBlbnRyaWVzXG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gQSBuZXcgbG9nZ2VyIGluc3RhbmNlIGxhYmVsZWQgd2l0aCB0aGUgcHJvdmlkZWQgcmVhc29uIGFuZCBpZFxuICAgKi9cbiAgc3RhdGljIGJlY2F1c2UocmVhc29uOiBzdHJpbmcsIGlkPzogc3RyaW5nKTogTG9nZ2VyIHtcbiAgICByZXR1cm4gdGhpcy5fZmFjdG9yeShyZWFzb24sIHRoaXMuX2NvbmZpZywgaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBcHBsaWVzIHRoZW1lIHN0eWxpbmcgdG8gdGV4dFxuICAgKiBAc3VtbWFyeSBBcHBsaWVzIHN0eWxpbmcgKGNvbG9ycywgZm9ybWF0dGluZykgdG8gdGV4dCBiYXNlZCBvbiB0aGUgdGhlbWUgY29uZmlndXJhdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSB0ZXh0IHRvIHN0eWxlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIC0gVGhlIHR5cGUgb2YgZWxlbWVudCB0byBzdHlsZSAoZS5nLiwgXCJjbGFzc1wiLCBcIm1lc3NhZ2VcIiwgXCJsb2dMZXZlbFwiKVxuICAgKiBAcGFyYW0ge0xvZ0xldmVsfSBsb2dnZXJMZXZlbCAtIFRoZSBsb2cgbGV2ZWwgdG8gdXNlIGZvciBzdHlsaW5nXG4gICAqIEBwYXJhbSB7VGhlbWV9IFt0ZW1wbGF0ZT1EZWZhdWx0VGhlbWVdIC0gVGhlIHRoZW1lIHRvIHVzZSBmb3Igc3R5bGluZ1xuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBzdHlsZWQgdGV4dFxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAgICogICBwYXJ0aWNpcGFudCBUaGVtZSBhcyBMb2dnaW5nLnRoZW1lXG4gICAqICAgcGFydGljaXBhbnQgQXBwbHkgYXMgYXBwbHkgZnVuY3Rpb25cbiAgICogICBwYXJ0aWNpcGFudCBTdHlsZSBhcyBzdHlsZWQtc3RyaW5nLWJ1aWxkZXJcbiAgICpcbiAgICogICBDYWxsZXItPj5UaGVtZTogdGhlbWUodGV4dCwgdHlwZSwgbG9nZ2VyTGV2ZWwpXG4gICAqICAgVGhlbWUtPj5UaGVtZTogQ2hlY2sgaWYgc3R5bGluZyBpcyBlbmFibGVkXG4gICAqICAgYWx0IHN0eWxpbmcgZGlzYWJsZWRcbiAgICogICAgIFRoZW1lLS0+PkNhbGxlcjogcmV0dXJuIG9yaWdpbmFsIHRleHRcbiAgICogICBlbHNlIHN0eWxpbmcgZW5hYmxlZFxuICAgKiAgICAgVGhlbWUtPj5UaGVtZTogR2V0IHRoZW1lIGZvciB0eXBlXG4gICAqICAgICBhbHQgdGhlbWUgbm90IGZvdW5kXG4gICAqICAgICAgIFRoZW1lLS0+PkNhbGxlcjogcmV0dXJuIG9yaWdpbmFsIHRleHRcbiAgICogICAgIGVsc2UgdGhlbWUgZm91bmRcbiAgICogICAgICAgVGhlbWUtPj5UaGVtZTogRGV0ZXJtaW5lIGFjdHVhbCB0aGVtZSBiYXNlZCBvbiBsb2cgbGV2ZWxcbiAgICogICAgICAgVGhlbWUtPj5BcHBseTogQXBwbHkgZWFjaCBzdHlsZSBwcm9wZXJ0eVxuICAgKiAgICAgICBBcHBseS0+PlN0eWxlOiBBcHBseSBjb2xvcnMgYW5kIGZvcm1hdHRpbmdcbiAgICogICAgICAgU3R5bGUtLT4+QXBwbHk6IFJldHVybiBzdHlsZWQgdGV4dFxuICAgKiAgICAgICBBcHBseS0tPj5UaGVtZTogUmV0dXJuIHN0eWxlZCB0ZXh0XG4gICAqICAgICAgIFRoZW1lLS0+PkNhbGxlcjogUmV0dXJuIGZpbmFsIHN0eWxlZCB0ZXh0XG4gICAqICAgICBlbmRcbiAgICogICBlbmRcbiAgICovXG4gIHN0YXRpYyB0aGVtZShcbiAgICB0ZXh0OiBzdHJpbmcsXG4gICAgdHlwZToga2V5b2YgVGhlbWUgfCBrZXlvZiBMb2dMZXZlbCxcbiAgICBsb2dnZXJMZXZlbDogTG9nTGV2ZWwsXG4gICAgdGVtcGxhdGU6IFRoZW1lID0gRGVmYXVsdFRoZW1lXG4gICkge1xuICAgIGlmICghdGhpcy5fY29uZmlnLnN0eWxlKSByZXR1cm4gdGV4dDtcbiAgICBjb25zdCBsb2dnZXIgPSBMb2dnaW5nLmdldCgpLmZvcih0aGlzLnRoZW1lKTtcblxuICAgIGZ1bmN0aW9uIGFwcGx5KFxuICAgICAgdHh0OiBzdHJpbmcsXG4gICAgICBvcHRpb246IGtleW9mIFRoZW1lT3B0aW9uLFxuICAgICAgdmFsdWU6IG51bWJlciB8IFtudW1iZXJdIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHwgbnVtYmVyW10gfCBzdHJpbmdbXVxuICAgICk6IHN0cmluZyB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB0OiBzdHJpbmcgfCBTdHlsZWRTdHJpbmcgPSB0eHQ7XG4gICAgICAgIGxldCBjID0gc3R5bGUodCk7XG5cbiAgICAgICAgZnVuY3Rpb24gYXBwbHlDb2xvcihcbiAgICAgICAgICB2YWw6IG51bWJlciB8IFtudW1iZXJdIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgIGlzQmcgPSBmYWxzZVxuICAgICAgICApOiBTdHlsZWRTdHJpbmcge1xuICAgICAgICAgIGxldCBmOlxuICAgICAgICAgICAgfCB0eXBlb2YgYy5iYWNrZ3JvdW5kXG4gICAgICAgICAgICB8IHR5cGVvZiBjLmZvcmVncm91bmRcbiAgICAgICAgICAgIHwgdHlwZW9mIGMucmdiXG4gICAgICAgICAgICB8IHR5cGVvZiBjLmNvbG9yMjU2ID0gaXNCZyA/IGMuYmFja2dyb3VuZCA6IGMuZm9yZWdyb3VuZDtcbiAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsKSkge1xuICAgICAgICAgICAgcmV0dXJuIChmIGFzIHR5cGVvZiBjLmJhY2tncm91bmQgfCB0eXBlb2YgYy5mb3JlZ3JvdW5kKS5jYWxsKFxuICAgICAgICAgICAgICBjLFxuICAgICAgICAgICAgICB2YWx1ZSBhcyBudW1iZXJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHN3aXRjaCAodmFsLmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICBmID0gaXNCZyA/IGMuYmdDb2xvcjI1NiA6IGMuY29sb3IyNTY7XG4gICAgICAgICAgICAgIHJldHVybiAoZiBhcyB0eXBlb2YgYy5iZ0NvbG9yMjU2IHwgdHlwZW9mIGMuY29sb3IyNTYpKHZhbFswXSk7XG4gICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgIGYgPSBpc0JnID8gYy5iZ1JnYiA6IGMucmdiO1xuICAgICAgICAgICAgICByZXR1cm4gYy5yZ2IodmFsWzBdLCB2YWxbMV0sIHZhbFsyXSk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYE5vdCBhIHZhbGlkIGNvbG9yIG9wdGlvbjogJHtvcHRpb259YCk7XG4gICAgICAgICAgICAgIHJldHVybiBzdHlsZSh0IGFzIHN0cmluZyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gYXBwbHlTdHlsZSh2OiBudW1iZXIgfCBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgICBpZiAodHlwZW9mIHYgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIGMgPSBjLnN0eWxlKHYpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjID0gY1t2IGFzIGtleW9mIENvbG9yaXplT3B0aW9uc10gYXMgU3R5bGVkU3RyaW5nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAob3B0aW9uKSB7XG4gICAgICAgICAgY2FzZSBcImJnXCI6XG4gICAgICAgICAgY2FzZSBcImZnXCI6XG4gICAgICAgICAgICByZXR1cm4gYXBwbHlDb2xvcih2YWx1ZSBhcyBudW1iZXIpLnRleHQ7XG4gICAgICAgICAgY2FzZSBcInN0eWxlXCI6XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgdmFsdWUuZm9yRWFjaChhcHBseVN0eWxlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGFwcGx5U3R5bGUodmFsdWUgYXMgbnVtYmVyIHwgc3RyaW5nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjLnRleHQ7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgTm90IGEgdmFsaWQgdGhlbWUgb3B0aW9uOiAke29wdGlvbn1gKTtcbiAgICAgICAgICAgIHJldHVybiB0O1xuICAgICAgICB9XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKGBFcnJvciBhcHBseWluZyBzdHlsZTogJHtvcHRpb259IHdpdGggdmFsdWUgJHt2YWx1ZX1gKTtcbiAgICAgICAgcmV0dXJuIHR4dDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBpbmRpdmlkdWFsVGhlbWUgPSB0ZW1wbGF0ZVt0eXBlIGFzIGtleW9mIFRoZW1lXTtcbiAgICBpZiAoIWluZGl2aWR1YWxUaGVtZSB8fCAhT2JqZWN0LmtleXMoaW5kaXZpZHVhbFRoZW1lKS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0ZXh0O1xuICAgIH1cblxuICAgIGxldCBhY3R1YWxUaGVtZTogVGhlbWVPcHRpb24gPSBpbmRpdmlkdWFsVGhlbWUgYXMgVGhlbWVPcHRpb247XG5cbiAgICBjb25zdCBsb2dMZXZlbHMgPSBPYmplY3QuYXNzaWduKHt9LCBMb2dMZXZlbCk7XG4gICAgaWYgKE9iamVjdC5rZXlzKGluZGl2aWR1YWxUaGVtZSlbMF0gaW4gbG9nTGV2ZWxzKVxuICAgICAgYWN0dWFsVGhlbWUgPVxuICAgICAgICAoaW5kaXZpZHVhbFRoZW1lIGFzIFRoZW1lT3B0aW9uQnlMb2dMZXZlbClbbG9nZ2VyTGV2ZWxdIHx8IHt9O1xuXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGFjdHVhbFRoZW1lKS5yZWR1Y2UoKGFjYzogc3RyaW5nLCBrZXk6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgdmFsID0gKGFjdHVhbFRoZW1lIGFzIFRoZW1lT3B0aW9uKVtrZXkgYXMga2V5b2YgVGhlbWVPcHRpb25dO1xuICAgICAgaWYgKHZhbClcbiAgICAgICAgcmV0dXJuIGFwcGx5KFxuICAgICAgICAgIGFjYyxcbiAgICAgICAgICBrZXkgYXMga2V5b2YgVGhlbWVPcHRpb24sXG4gICAgICAgICAgdmFsIGFzXG4gICAgICAgICAgICB8IG51bWJlclxuICAgICAgICAgICAgfCBbbnVtYmVyXVxuICAgICAgICAgICAgfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl1cbiAgICAgICAgICAgIHwgbnVtYmVyW11cbiAgICAgICAgICAgIHwgc3RyaW5nW11cbiAgICAgICAgKTtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgdGV4dCk7XG4gIH1cbn1cbiIsImltcG9ydCB7IExvZ2dpbmcgfSBmcm9tIFwiLi9sb2dnaW5nXCI7XG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBCYXNlIGNsYXNzIHRoYXQgcHJvdmlkZXMgYSByZWFkeS10by11c2UgbG9nZ2VyIGluc3RhbmNlXG4gKiBAc3VtbWFyeSBMb2dnZWRDbGFzcyBpcyBhIGNvbnZlbmllbmNlIGFic3RyYWN0IGNsYXNzIHRoYXQgaW5qZWN0cyBhIHR5cGUtc2FmZSBsb2dnZXJcbiAqIGludG8gZGVyaXZlZCBjbGFzc2VzIHRocm91Z2ggYSBwcm90ZWN0ZWQgZ2V0dGVyLiBTdWJjbGFzc2VzIGNhbiBkaXJlY3RseSBhY2Nlc3NcbiAqIHRoaXMubG9nIHRvIGVtaXQgbWVzc2FnZXMgd2l0aG91dCBtYW51YWxseSBjcmVhdGluZyBhIGxvZ2dlci4gVGhpcyBwcm9tb3Rlc1xuICogY29uc2lzdGVudCwgY29udGV4dC1hd2FyZSBsb2dnaW5nIGFjcm9zcyB0aGUgY29kZWJhc2UuXG4gKiBAcGFyYW0ge3ZvaWR9IFtjb25zdHJ1Y3Rvcl0gLSBObyBjb25zdHJ1Y3RvciBhcmd1bWVudHM7IHN1YmNsYXNzZXMgbWF5IGRlZmluZSB0aGVpciBvd25cbiAqIEBjbGFzcyBMb2dnZWRDbGFzc1xuICogQGV4YW1wbGVcbiAqIGNsYXNzIFVzZXJTZXJ2aWNlIGV4dGVuZHMgTG9nZ2VkQ2xhc3Mge1xuICogICBjcmVhdGUodXNlcjogVXNlcikge1xuICogICAgIHRoaXMubG9nLmluZm8oYENyZWF0aW5nIHVzZXIgJHt1c2VyLmlkfWApO1xuICogICB9XG4gKiB9XG4gKlxuICogY29uc3Qgc3ZjID0gbmV3IFVzZXJTZXJ2aWNlKCk7XG4gKiBzdmMuY3JlYXRlKHsgaWQ6IFwiNDJcIiB9KTtcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IEluc3RhbmNlIGFzIFN1YmNsYXNzIEluc3RhbmNlXG4gKiAgIHBhcnRpY2lwYW50IEdldHRlciBhcyBMb2dnZWRDbGFzcy5sb2dcbiAqICAgcGFydGljaXBhbnQgTG9nZ2luZyBhcyBMb2dnaW5nXG4gKiAgIHBhcnRpY2lwYW50IExvZ2dlciBhcyBMb2dnZXJcbiAqXG4gKiAgIENsaWVudC0+Pkluc3RhbmNlOiBjYWxsIHNvbWVNZXRob2QoKVxuICogICBJbnN0YW5jZS0+PkdldHRlcjogYWNjZXNzIHRoaXMubG9nXG4gKiAgIEdldHRlci0+PkxvZ2dpbmc6IExvZ2dpbmcuZm9yKHRoaXMpXG4gKiAgIExvZ2dpbmctLT4+R2V0dGVyOiByZXR1cm4gTG9nZ2VyXG4gKiAgIEdldHRlci0tPj5JbnN0YW5jZTogcmV0dXJuIExvZ2dlclxuICogICBJbnN0YW5jZS0+PkxvZ2dlcjogaW5mby9kZWJ1Zy9lcnJvciguLi4pXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBMb2dnZWRDbGFzcyB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTGF6aWx5IHByb3ZpZGVzIGEgY29udGV4dC1hd2FyZSBsb2dnZXIgZm9yIHRoZSBjdXJyZW50IGluc3RhbmNlXG4gICAqIEBzdW1tYXJ5IFVzZXMgTG9nZ2luZy5mb3IodGhpcykgdG8gY3JlYXRlIGEgbG9nZ2VyIHdob3NlIGNvbnRleHQgaXMgdGhlXG4gICAqIHN1YmNsYXNzIG5hbWUsIGFsbG93aW5nIHVuaWZvcm0gYW5kIHN0cnVjdHVyZWQgbG9ncyBmcm9tIGFueSBpbmhlcml0aW5nIGNsYXNzLlxuICAgKiBAcmV0dXJuIHtMb2dnZXJ9IEEgbG9nZ2VyIGJvdW5kIHRvIHRoZSBzdWJjbGFzcyBjb250ZXh0XG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IGxvZygpOiBMb2dnZXIge1xuICAgIHJldHVybiBMb2dnaW5nLmZvcih0aGlzIGFzIGFueSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoKSB7fVxufVxuIiwiaW1wb3J0IHsgTG9nZ2VyLCBMb2dnaW5nQ29uZmlnLCBMb2dnaW5nRmlsdGVyIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBMb2dnZWRDbGFzcyB9IGZyb20gXCIuLi9Mb2dnZWRDbGFzc1wiO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgTG9nRmlsdGVyIGV4dGVuZHMgTG9nZ2VkQ2xhc3MgaW1wbGVtZW50cyBMb2dnaW5nRmlsdGVyIHtcbiAgb3ZlcnJpZGUgZ2V0IGxvZygpOiBMb2dnZXIge1xuICAgIHJldHVybiBzdXBlci5sb2cuZm9yKHRoaXMgYXMgYW55LCB7IGZpbHRlcnM6IFtdIH0pO1xuICB9XG5cbiAgYWJzdHJhY3QgZmlsdGVyKFxuICAgIGNvbmZpZzogTG9nZ2luZ0NvbmZpZyxcbiAgICBtZXNzYWdlOiBzdHJpbmcsXG4gICAgY29udGV4dDogc3RyaW5nW11cbiAgKTogc3RyaW5nO1xufVxuIiwiaW1wb3J0IHsgTG9nTGV2ZWwgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IExvZ2dpbmcgfSBmcm9tIFwiLi9sb2dnaW5nXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHNcbiAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBkZWNvcmF0b3IgdGhhdCBsb2dzIG1ldGhvZCBjYWxscyB3aXRoIHNwZWNpZmllZCBsZXZlbCwgYmVuY2htYXJraW5nLCBhbmQgdmVyYm9zaXR5XG4gKiBAcGFyYW0ge0xvZ0xldmVsfSBsZXZlbCAtIFRoZSBsb2cgbGV2ZWwgdG8gdXNlIChkZWZhdWx0OiBMb2dMZXZlbC5pbmZvKVxuICogQHBhcmFtIHtib29sZWFufSBbYmVuY2htYXJrPWZhbHNlXSAtIFdoZXRoZXIgdG8gbG9nIGV4ZWN1dGlvbiB0aW1lIChkZWZhdWx0OiBmYWxzZSlcbiAqIEBwYXJhbSB7bnVtYmVyfSBbdmVyYm9zaXR5PTBdIC0gVGhlIHZlcmJvc2l0eSBsZXZlbCBmb3IgdGhlIGxvZyBtZXNzYWdlcyAoZGVmYXVsdDogMClcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG1ldGhvZCBkZWNvcmF0b3IgdGhhdCB3cmFwcyB0aGUgb3JpZ2luYWwgbWV0aG9kIHdpdGggbG9nZ2luZ1xuICogQGZ1bmN0aW9uIGxvZ1xuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgRGVjb3JhdG9yIGFzIGxvZyBkZWNvcmF0b3JcbiAqICAgcGFydGljaXBhbnQgTWV0aG9kIGFzIE9yaWdpbmFsIE1ldGhvZFxuICogICBwYXJ0aWNpcGFudCBMb2dnZXIgYXMgTG9nZ2luZyBpbnN0YW5jZVxuICpcbiAqICAgQ2xpZW50LT4+RGVjb3JhdG9yOiBjYWxsIGRlY29yYXRlZCBtZXRob2RcbiAqICAgRGVjb3JhdG9yLT4+TG9nZ2VyOiBsb2cgbWV0aG9kIGNhbGxcbiAqICAgRGVjb3JhdG9yLT4+TWV0aG9kOiBjYWxsIG9yaWdpbmFsIG1ldGhvZFxuICogICBhbHQgcmVzdWx0IGlzIFByb21pc2VcbiAqICAgICBNZXRob2QtLT4+RGVjb3JhdG9yOiByZXR1cm4gUHJvbWlzZVxuICogICAgIERlY29yYXRvci0+PkRlY29yYXRvcjogYXR0YWNoIHRoZW4gaGFuZGxlclxuICogICAgIE5vdGUgb3ZlciBEZWNvcmF0b3I6IFByb21pc2UgcmVzb2x2ZXNcbiAqICAgICBEZWNvcmF0b3ItPj5Mb2dnZXI6IGxvZyBiZW5jaG1hcmsgKGlmIGVuYWJsZWQpXG4gKiAgICAgRGVjb3JhdG9yLS0+PkNsaWVudDogcmV0dXJuIHJlc3VsdFxuICogICBlbHNlIHJlc3VsdCBpcyBub3QgUHJvbWlzZVxuICogICAgIE1ldGhvZC0tPj5EZWNvcmF0b3I6IHJldHVybiByZXN1bHRcbiAqICAgICBEZWNvcmF0b3ItPj5Mb2dnZXI6IGxvZyBiZW5jaG1hcmsgKGlmIGVuYWJsZWQpXG4gKiAgICAgRGVjb3JhdG9yLS0+PkNsaWVudDogcmV0dXJuIHJlc3VsdFxuICogICBlbmRcbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbG9nKFxuICBsZXZlbDogTG9nTGV2ZWwgPSBMb2dMZXZlbC5pbmZvLFxuICBiZW5jaG1hcms6IGJvb2xlYW4gPSBmYWxzZSxcbiAgdmVyYm9zaXR5ID0gMFxuKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoXG4gICAgdGFyZ2V0OiBhbnksXG4gICAgcHJvcGVydHlLZXk/OiBhbnksXG4gICAgZGVzY3JpcHRvcj86IFByb3BlcnR5RGVzY3JpcHRvclxuICApIHtcbiAgICBpZiAoIWRlc2NyaXB0b3IpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYExvZ2dpbmcgZGVjb3JhdGlvbiBvbmx5IGFwcGxpZXMgdG8gbWV0aG9kc2ApO1xuICAgIGNvbnN0IGxvZ2dlciA9IExvZ2dpbmcuZm9yKHRhcmdldCkuZm9yKHRhcmdldFtwcm9wZXJ0eUtleV0pO1xuICAgIGNvbnN0IG1ldGhvZCA9IGxvZ2dlcltsZXZlbF0uYmluZChsb2dnZXIpIGFzIGFueTtcbiAgICBjb25zdCBvcmlnaW5hbE1ldGhvZCA9IGRlc2NyaXB0b3IudmFsdWU7XG5cbiAgICBkZXNjcmlwdG9yLnZhbHVlID0gbmV3IFByb3h5KG9yaWdpbmFsTWV0aG9kLCB7XG4gICAgICBhcHBseShmbiwgdGhpc0FyZywgYXJnczogYW55W10pIHtcbiAgICAgICAgbWV0aG9kKGBjYWxsZWQgd2l0aCAke2FyZ3N9YCwgdmVyYm9zaXR5KTtcbiAgICAgICAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuYXBwbHkoZm4sIHRoaXNBcmcsIGFyZ3MpO1xuICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0LnRoZW4oKHI6IGFueSkgPT4ge1xuICAgICAgICAgICAgICBpZiAoYmVuY2htYXJrKVxuICAgICAgICAgICAgICAgIG1ldGhvZChgY29tcGxldGVkIGluICR7RGF0ZS5ub3coKSAtIHN0YXJ0fW1zYCwgdmVyYm9zaXR5KTtcbiAgICAgICAgICAgICAgcmV0dXJuIHI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGJlbmNobWFyaylcbiAgICAgICAgICAgIG1ldGhvZChgY29tcGxldGVkIGluICR7RGF0ZS5ub3coKSAtIHN0YXJ0fW1zYCwgdmVyYm9zaXR5KTtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBpZiAoYmVuY2htYXJrKSBtZXRob2QoYGZhaWxlZCBpbiAke0RhdGUubm93KCkgLSBzdGFydH1tc2AsIHZlcmJvc2l0eSk7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuICB9O1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggZGVidWcgbGV2ZWxcbiAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIHRoZSBsb2cgZGVjb3JhdG9yIHRoYXQgdXNlcyBMb2dMZXZlbC5kZWJ1Z1xuICogQHBhcmFtIHtib29sZWFufSBbYmVuY2htYXJrPWZhbHNlXSAtIFdoZXRoZXIgdG8gbG9nIGV4ZWN1dGlvbiB0aW1lIChkZWZhdWx0OiBmYWxzZSlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG1ldGhvZCBkZWNvcmF0b3IgdGhhdCB3cmFwcyB0aGUgb3JpZ2luYWwgbWV0aG9kIHdpdGggZGVidWcgbG9nZ2luZ1xuICogQGZ1bmN0aW9uIGRlYnVnXG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlYnVnKGJlbmNobWFyazogYm9vbGVhbiA9IGZhbHNlKSB7XG4gIHJldHVybiBsb2coTG9nTGV2ZWwuZGVidWcsIGJlbmNobWFyayk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCBpbmZvIGxldmVsXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB0aGUgbG9nIGRlY29yYXRvciB0aGF0IHVzZXMgTG9nTGV2ZWwuaW5mb1xuICogQHBhcmFtIHtib29sZWFufSBbYmVuY2htYXJrPWZhbHNlXSAtIFdoZXRoZXIgdG8gbG9nIGV4ZWN1dGlvbiB0aW1lIChkZWZhdWx0OiBmYWxzZSlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG1ldGhvZCBkZWNvcmF0b3IgdGhhdCB3cmFwcyB0aGUgb3JpZ2luYWwgbWV0aG9kIHdpdGggaW5mbyBsb2dnaW5nXG4gKiBAZnVuY3Rpb24gaW5mb1xuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmZvKGJlbmNobWFyazogYm9vbGVhbiA9IGZhbHNlKSB7XG4gIHJldHVybiBsb2coTG9nTGV2ZWwuaW5mbywgYmVuY2htYXJrKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIHNpbGx5IGxldmVsXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB0aGUgbG9nIGRlY29yYXRvciB0aGF0IHVzZXMgTG9nTGV2ZWwuc2lsbHlcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2JlbmNobWFyaz1mYWxzZV0gLSBXaGV0aGVyIHRvIGxvZyBleGVjdXRpb24gdGltZSAoZGVmYXVsdDogZmFsc2UpXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIHNpbGx5IGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiBzaWxseVxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzaWxseShiZW5jaG1hcms6IGJvb2xlYW4gPSBmYWxzZSkge1xuICByZXR1cm4gbG9nKExvZ0xldmVsLnNpbGx5LCBiZW5jaG1hcmspO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggdmVyYm9zZSBsZXZlbFxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQgdGhlIGxvZyBkZWNvcmF0b3IgdGhhdCB1c2VzIExvZ0xldmVsLnZlcmJvc2Ugd2l0aCBjb25maWd1cmFibGUgdmVyYm9zaXR5XG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIHZlcmJvc2UgbG9nZ2luZ1xuICogQGZ1bmN0aW9uIHZlcmJvc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcmJvc2UoKTogKFxuICB0YXJnZXQ6IGFueSxcbiAgcHJvcGVydHlLZXk/OiBhbnksXG4gIGRlc2NyaXB0b3I/OiBhbnlcbikgPT4gdm9pZDtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIHZlcmJvc2UgbGV2ZWxcbiAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIHRoZSBsb2cgZGVjb3JhdG9yIHRoYXQgdXNlcyBMb2dMZXZlbC52ZXJib3NlIHdpdGggY29uZmlndXJhYmxlIHZlcmJvc2l0eVxuICogQHBhcmFtIHtib29sZWFufSBiZW5jaG1hcmsgLSBXaGV0aGVyIHRvIGxvZyBleGVjdXRpb24gdGltZVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbWV0aG9kIGRlY29yYXRvciB0aGF0IHdyYXBzIHRoZSBvcmlnaW5hbCBtZXRob2Qgd2l0aCB2ZXJib3NlIGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiB2ZXJib3NlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKFxuICBiZW5jaG1hcms6IGJvb2xlYW5cbik6ICh0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk/OiBhbnksIGRlc2NyaXB0b3I/OiBhbnkpID0+IHZvaWQ7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCB2ZXJib3NlIGxldmVsXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB0aGUgbG9nIGRlY29yYXRvciB0aGF0IHVzZXMgTG9nTGV2ZWwudmVyYm9zZSB3aXRoIGNvbmZpZ3VyYWJsZSB2ZXJib3NpdHlcbiAqIEBwYXJhbSB7bnVtYmVyfSB2ZXJib3NpdHkgLSBUaGUgdmVyYm9zaXR5IGxldmVsIGZvciB0aGUgbG9nIG1lc3NhZ2VzIChkZWZhdWx0OiAwKVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbWV0aG9kIGRlY29yYXRvciB0aGF0IHdyYXBzIHRoZSBvcmlnaW5hbCBtZXRob2Qgd2l0aCB2ZXJib3NlIGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiB2ZXJib3NlXG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcmJvc2UoXG4gIHZlcmJvc2l0eTogbnVtYmVyIHwgYm9vbGVhblxuKTogKHRhcmdldDogYW55LCBwcm9wZXJ0eUtleT86IGFueSwgZGVzY3JpcHRvcj86IGFueSkgPT4gdm9pZDtcbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCB2ZXJib3NlIGxldmVsXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB0aGUgbG9nIGRlY29yYXRvciB0aGF0IHVzZXMgTG9nTGV2ZWwudmVyYm9zZSB3aXRoIGNvbmZpZ3VyYWJsZSB2ZXJib3NpdHlcbiAqIEBwYXJhbSB7bnVtYmVyfSB2ZXJib3NpdHkgLSBUaGUgdmVyYm9zaXR5IGxldmVsIGZvciB0aGUgbG9nIG1lc3NhZ2VzIChkZWZhdWx0OiAwKVxuICogQHBhcmFtIHtib29sZWFufSBbYmVuY2htYXJrPWZhbHNlXSAtIFdoZXRoZXIgdG8gbG9nIGV4ZWN1dGlvbiB0aW1lIChkZWZhdWx0OiBmYWxzZSlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG1ldGhvZCBkZWNvcmF0b3IgdGhhdCB3cmFwcyB0aGUgb3JpZ2luYWwgbWV0aG9kIHdpdGggdmVyYm9zZSBsb2dnaW5nXG4gKiBAZnVuY3Rpb24gdmVyYm9zZVxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKHZlcmJvc2l0eTogbnVtYmVyIHwgYm9vbGVhbiA9IDAsIGJlbmNobWFyaz86IGJvb2xlYW4pIHtcbiAgaWYgKHR5cGVvZiB2ZXJib3NpdHkgPT09IFwiYm9vbGVhblwiKSB7XG4gICAgYmVuY2htYXJrID0gdmVyYm9zaXR5O1xuICAgIHZlcmJvc2l0eSA9IDA7XG4gIH1cbiAgcmV0dXJuIGxvZyhMb2dMZXZlbC52ZXJib3NlLCBiZW5jaG1hcmssIHZlcmJvc2l0eSk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBkZWNvcmF0b3IgdGhhdCBtYWtlcyBhIG1ldGhvZCBub24tY29uZmlndXJhYmxlXG4gKiBAc3VtbWFyeSBUaGlzIGRlY29yYXRvciBwcmV2ZW50cyBhIG1ldGhvZCBmcm9tIGJlaW5nIG92ZXJyaWRkZW4gYnkgbWFraW5nIGl0IG5vbi1jb25maWd1cmFibGUuXG4gKiBJdCB0aHJvd3MgYW4gZXJyb3IgaWYgdXNlZCBvbiBhbnl0aGluZyBvdGhlciB0aGFuIGEgbWV0aG9kLlxuICogQHJldHVybiB7RnVuY3Rpb259IEEgZGVjb3JhdG9yIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gbWV0aG9kc1xuICogQGZ1bmN0aW9uIGZpbmFsXG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmFsKCkge1xuICByZXR1cm4gKFxuICAgIHRhcmdldDogb2JqZWN0LFxuICAgIHByb3BlcnR5S2V5PzogYW55LFxuICAgIGRlc2NyaXB0b3I/OiBQcm9wZXJ0eURlc2NyaXB0b3JcbiAgKSA9PiB7XG4gICAgaWYgKCFkZXNjcmlwdG9yKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZmluYWwgZGVjb3JhdG9yIGNhbiBvbmx5IGJlIHVzZWQgb24gbWV0aG9kc1wiKTtcbiAgICBpZiAoZGVzY3JpcHRvcj8uY29uZmlndXJhYmxlKSB7XG4gICAgICBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgfTtcbn1cbiIsImltcG9ydCB7IExvZ0ZpbHRlciB9IGZyb20gXCIuL0xvZ0ZpbHRlclwiO1xuaW1wb3J0IHsgTG9nZ2luZ0NvbmZpZyB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgZmluYWwgfSBmcm9tIFwiLi4vZGVjb3JhdG9yc1wiO1xuXG5leHBvcnQgdHlwZSBSZXBsYWNlbWVudEZ1bmN0aW9uID0gKHN1YnN0cmluZzogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkgPT4gc3RyaW5nO1xuXG5leHBvcnQgY2xhc3MgUGF0dGVybkZpbHRlciBleHRlbmRzIExvZ0ZpbHRlciB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCByZWFkb25seSByZWdleHA6IFJlZ0V4cCxcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgcmVwbGFjZW1lbnQ6IHN0cmluZyB8IFJlcGxhY2VtZW50RnVuY3Rpb25cbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIEBmaW5hbCgpXG4gIHByb3RlY3RlZCBtYXRjaChtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICBjb25zdCBtYXRjaCA9IHRoaXMucmVnZXhwLmV4ZWMobWVzc2FnZSk7XG4gICAgdGhpcy5yZWdleHAubGFzdEluZGV4ID0gMDtcbiAgICByZXR1cm4gbWF0Y2g7XG4gIH1cblxuICBmaWx0ZXIoY29uZmlnOiBMb2dnaW5nQ29uZmlnLCBtZXNzYWdlOiBzdHJpbmcsIGNvbnRleHQ6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5maWx0ZXIpO1xuICAgIGNvbnN0IG1hdGNoID0gdGhpcy5tYXRjaChtZXNzYWdlKTtcbiAgICBpZiAoIW1hdGNoKSByZXR1cm4gbWVzc2FnZTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIG1lc3NhZ2UucmVwbGFjZSh0aGlzLnJlZ2V4cCwgdGhpcy5yZXBsYWNlbWVudCBhcyBhbnkpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIGxvZy5lcnJvcihgUGF0dGVybkZpbHRlciByZXBsYWNlbWVudCBlcnJvcjogJHtlfWApO1xuICAgIH1cbiAgICByZXR1cm4gXCJcIjtcbiAgfVxufVxuIiwiZXhwb3J0ICogZnJvbSBcIi4vZmlsdGVyc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9lbnZpcm9ubWVudFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vTG9nZ2VkQ2xhc3NcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2xvZ2dpbmdcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3RleHRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGVzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi93ZWJcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQSBsb2dnaW5nIG1vZHVsZSBmb3IgVHlwZVNjcmlwdCBhcHBsaWNhdGlvbnNcbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIGEgY29tcHJlaGVuc2l2ZSwgZmxleGlibGUgbG9nZ2luZyBzb2x1dGlvbi4gVGhpcyBtb2R1bGUgZXhwb3NlczpcbiAqIC0gQ29yZSBjbGFzc2VzIGxpa2Uge0BsaW5rIExvZ2dpbmd9IGFuZCB7QGxpbmsgTWluaUxvZ2dlcn1cbiAqIC0gRGVjb3JhdG9ycyBzdWNoIGFzIHtAbGluayBsb2d9IGZvciBpbnN0cnVtZW50aW5nIG1ldGhvZHNcbiAqIC0gQ29uZmlndXJhdGlvbiBhbmQgY29uc3RhbnRzIGxpa2Uge0BsaW5rIExvZ0xldmVsfSBhbmQge0BsaW5rIERlZmF1bHRMb2dnaW5nQ29uZmlnfVxuICogLSBUeXBlIGRlZmluaXRpb25zIGluY2x1ZGluZyB7QGxpbmsgTG9nZ2VyfSBhbmQge0BsaW5rIExvZ2dpbmdDb25maWd9XG4gKiBUaGVzZSBleHBvcnRzIGVuYWJsZSBjb25zaXN0ZW50LCBjb250ZXh0LWF3YXJlLCBhbmQgb3B0aW9uYWxseSB0aGVtZWQgbG9nZ2luZyBhY3Jvc3MgcHJvamVjdHMuXG4gKiBAbW9kdWxlIExvZ2dpbmdcbiAqL1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDdXJyZW50IHBhY2thZ2UgdmVyc2lvbiBzdHJpbmdcbiAqIEBzdW1tYXJ5IFN0b3JlcyB0aGUgY3VycmVudCBwYWNrYWdlIHZlcnNpb24sIHVzZWQgZm9yIHZlcnNpb24gdHJhY2tpbmcgYW5kIGNvbXBhdGliaWxpdHkgY2hlY2tzXG4gKiBAY29uc3QgVkVSU0lPTlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gXCIjI1ZFUlNJT04jI1wiO1xuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFFTyxNQUFNLGFBQWEsR0FB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