@decaf-ts/logging 0.3.12 → 0.3.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/logging.cjs +542 -99
- package/dist/logging.esm.cjs +539 -100
- package/lib/LoggedClass.cjs +9 -12
- package/lib/LoggedClass.d.ts +6 -10
- package/lib/constants.cjs +40 -8
- package/lib/constants.d.ts +35 -7
- package/lib/decorators.cjs +114 -50
- package/lib/decorators.d.ts +58 -43
- package/lib/environment.cjs +73 -22
- package/lib/environment.d.ts +46 -29
- package/lib/esm/LoggedClass.d.ts +6 -10
- package/lib/esm/LoggedClass.js +9 -12
- package/lib/esm/constants.d.ts +35 -7
- package/lib/esm/constants.js +40 -8
- package/lib/esm/decorators.d.ts +58 -43
- package/lib/esm/decorators.js +113 -50
- package/lib/esm/environment.d.ts +46 -29
- package/lib/esm/environment.js +73 -22
- package/lib/esm/filters/LogFilter.d.ts +37 -0
- package/lib/esm/filters/LogFilter.js +30 -1
- package/lib/esm/filters/PatternFilter.d.ts +46 -0
- package/lib/esm/filters/PatternFilter.js +41 -1
- package/lib/esm/index.d.ts +7 -10
- package/lib/esm/index.js +8 -11
- package/lib/esm/logging.d.ts +14 -0
- package/lib/esm/logging.js +22 -1
- package/lib/esm/time.d.ts +149 -0
- package/lib/esm/time.js +212 -0
- package/lib/esm/types.d.ts +89 -51
- package/lib/esm/types.js +1 -1
- package/lib/filters/LogFilter.cjs +30 -1
- package/lib/filters/LogFilter.d.ts +37 -0
- package/lib/filters/PatternFilter.cjs +41 -1
- package/lib/filters/PatternFilter.d.ts +46 -0
- package/lib/index.cjs +8 -11
- package/lib/index.d.ts +7 -10
- package/lib/logging.cjs +22 -1
- package/lib/logging.d.ts +14 -0
- package/lib/time.cjs +217 -0
- package/lib/time.d.ts +149 -0
- package/lib/types.cjs +1 -1
- package/lib/types.d.ts +89 -51
- package/package.json +2 -2
package/dist/logging.cjs
CHANGED
|
@@ -4,12 +4,29 @@
|
|
|
4
4
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.logging = {}, global.styledStringBuilder, global.typedObjectAccumulator, global.tslib));
|
|
5
5
|
})(this, (function (exports, styledStringBuilder, typedObjectAccumulator, tslib) { 'use strict';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @description Global key used to store environment variables in browser contexts.
|
|
9
|
+
* @summary Enables the logging environment helpers to locate serialized environment configuration on `globalThis`.
|
|
10
|
+
* @const BrowserEnvKey
|
|
11
|
+
* @type {string}
|
|
12
|
+
* @memberOf module:Logging
|
|
13
|
+
*/
|
|
7
14
|
const BrowserEnvKey = "ENV";
|
|
8
15
|
/**
|
|
9
16
|
* @description Delimiter used for composing nested environment variable names.
|
|
10
17
|
* @summary Joins parent and child keys when mapping object paths to ENV strings.
|
|
18
|
+
* @const ENV_PATH_DELIMITER
|
|
19
|
+
* @type {string}
|
|
20
|
+
* @memberOf module:Logging
|
|
11
21
|
*/
|
|
12
22
|
const ENV_PATH_DELIMITER = "__";
|
|
23
|
+
/**
|
|
24
|
+
* @description Default prefix and suffix used for template placeholders.
|
|
25
|
+
* @summary Provides wrapper strings applied when interpolating messages with {@link patchPlaceholders}.
|
|
26
|
+
* @const DefaultPlaceholderWrappers
|
|
27
|
+
* @type {string[]}
|
|
28
|
+
* @memberOf module:Logging
|
|
29
|
+
*/
|
|
13
30
|
const DefaultPlaceholderWrappers = ["${", "}"];
|
|
14
31
|
/**
|
|
15
32
|
* @description Enum for log levels.
|
|
@@ -20,21 +37,24 @@
|
|
|
20
37
|
*/
|
|
21
38
|
exports.LogLevel = void 0;
|
|
22
39
|
(function (LogLevel) {
|
|
23
|
-
/**
|
|
40
|
+
/** @description Benchmark events that capture performance metrics. */
|
|
41
|
+
LogLevel["benchmark"] = "benchmark";
|
|
42
|
+
/** @description Error events that indicate failures requiring attention. */
|
|
24
43
|
LogLevel["error"] = "error";
|
|
25
|
-
/**
|
|
44
|
+
/** @description Informational events describing normal operation. */
|
|
26
45
|
LogLevel["info"] = "info";
|
|
27
|
-
/**
|
|
46
|
+
/** @description Verbose diagnostic information for detailed tracing. */
|
|
28
47
|
LogLevel["verbose"] = "verbose";
|
|
29
|
-
/** Debug or trace
|
|
48
|
+
/** @description Debug or trace details aimed at developers. */
|
|
30
49
|
LogLevel["debug"] = "debug";
|
|
31
|
-
/**
|
|
50
|
+
/** @description Extremely chatty or playful log entries. */
|
|
32
51
|
LogLevel["silly"] = "silly";
|
|
33
52
|
})(exports.LogLevel || (exports.LogLevel = {}));
|
|
34
53
|
/**
|
|
35
54
|
* @description Numeric values associated with log levels.
|
|
36
55
|
* @summary Provides a numeric representation of log levels for comparison and filtering.
|
|
37
|
-
* @
|
|
56
|
+
* @typedef {Object} NumericLogLevelsShape
|
|
57
|
+
* @property {number} benchmark - Numeric value for benchmark level (0).
|
|
38
58
|
* @property {number} error - Numeric value for error level (2).
|
|
39
59
|
* @property {number} info - Numeric value for info level (4).
|
|
40
60
|
* @property {number} verbose - Numeric value for verbose level (6).
|
|
@@ -42,7 +62,15 @@
|
|
|
42
62
|
* @property {number} silly - Numeric value for silly level (9).
|
|
43
63
|
* @memberOf module:Logging
|
|
44
64
|
*/
|
|
65
|
+
/**
|
|
66
|
+
* @description Numeric values associated with log levels.
|
|
67
|
+
* @summary Provides a numeric representation of log levels for comparison and filtering.
|
|
68
|
+
* @const NumericLogLevels
|
|
69
|
+
* @type {NumericLogLevelsShape}
|
|
70
|
+
* @memberOf module:Logging
|
|
71
|
+
*/
|
|
45
72
|
const NumericLogLevels = {
|
|
73
|
+
benchmark: 0,
|
|
46
74
|
error: 2,
|
|
47
75
|
info: 4,
|
|
48
76
|
verbose: 6,
|
|
@@ -65,7 +93,6 @@
|
|
|
65
93
|
/**
|
|
66
94
|
* @description Default theme for styling log output.
|
|
67
95
|
* @summary Defines the default color and style settings for various components of log messages.
|
|
68
|
-
* @const DefaultTheme
|
|
69
96
|
* @typedef {Theme} DefaultTheme
|
|
70
97
|
* @property {Object} class - Styling for class names.
|
|
71
98
|
* @property {number} class.fg - Foreground color code for class names (34).
|
|
@@ -85,6 +112,7 @@
|
|
|
85
112
|
* @property {Object} logLevel.verbose - Styling for verbose level logs (empty object).
|
|
86
113
|
* @property {Object} logLevel.debug - Styling for debug level logs.
|
|
87
114
|
* @property {number} logLevel.debug.fg - Foreground color code for debug level logs (33).
|
|
115
|
+
* @const DefaultTheme
|
|
88
116
|
* @memberOf module:Logging
|
|
89
117
|
*/
|
|
90
118
|
const DefaultTheme = {
|
|
@@ -105,6 +133,10 @@
|
|
|
105
133
|
},
|
|
106
134
|
method: {},
|
|
107
135
|
logLevel: {
|
|
136
|
+
benchmark: {
|
|
137
|
+
fg: 32,
|
|
138
|
+
style: ["bold"],
|
|
139
|
+
},
|
|
108
140
|
error: {
|
|
109
141
|
fg: 31,
|
|
110
142
|
style: ["bold"],
|
|
@@ -382,13 +414,33 @@
|
|
|
382
414
|
}
|
|
383
415
|
|
|
384
416
|
/**
|
|
385
|
-
* @
|
|
386
|
-
* @
|
|
417
|
+
* @description Environment accumulator that lazily reads from runtime sources.
|
|
418
|
+
* @summary Extends {@link ObjectAccumulator} to merge configuration objects while resolving values from Node or browser environment variables on demand.
|
|
387
419
|
* @template T
|
|
388
|
-
* @
|
|
389
|
-
* @
|
|
390
|
-
*
|
|
420
|
+
* @class Environment
|
|
421
|
+
* @example
|
|
422
|
+
* const Config = Environment.accumulate({ logging: { level: "info" } });
|
|
423
|
+
* console.log(Config.logging.level);
|
|
424
|
+
* console.log(String(Config.logging.level)); // => LOGGING__LEVEL key when serialized
|
|
425
|
+
* @mermaid
|
|
426
|
+
* sequenceDiagram
|
|
427
|
+
* participant Client
|
|
428
|
+
* participant Env as Environment
|
|
429
|
+
* participant Process as process.env
|
|
430
|
+
* participant Browser as globalThis.ENV
|
|
431
|
+
* Client->>Env: accumulate(partialConfig)
|
|
432
|
+
* Env->>Env: expand(values)
|
|
433
|
+
* Client->>Env: Config.logging.level
|
|
434
|
+
* alt Browser runtime
|
|
435
|
+
* Env->>Browser: lookup ENV key
|
|
436
|
+
* Browser-->>Env: resolved value
|
|
437
|
+
* else Node runtime
|
|
438
|
+
* Env->>Process: lookup ENV key
|
|
439
|
+
* Process-->>Env: resolved value
|
|
440
|
+
* end
|
|
441
|
+
* Env-->>Client: merged value
|
|
391
442
|
*/
|
|
443
|
+
const EmptyValue = Symbol("EnvironmentEmpty");
|
|
392
444
|
class Environment extends typedObjectAccumulator.ObjectAccumulator {
|
|
393
445
|
/**
|
|
394
446
|
* @static
|
|
@@ -402,10 +454,10 @@
|
|
|
402
454
|
super();
|
|
403
455
|
}
|
|
404
456
|
/**
|
|
405
|
-
* @description Retrieves a value from the environment
|
|
406
|
-
* @summary
|
|
407
|
-
* @param {string} k -
|
|
408
|
-
* @return {unknown}
|
|
457
|
+
* @description Retrieves a value from the runtime environment.
|
|
458
|
+
* @summary Handles browser and Node.js environments by normalizing keys and parsing values.
|
|
459
|
+
* @param {string} k - Key to resolve from the environment.
|
|
460
|
+
* @return {unknown} Value resolved from the environment or `undefined` when absent.
|
|
409
461
|
*/
|
|
410
462
|
fromEnv(k) {
|
|
411
463
|
let env;
|
|
@@ -419,6 +471,12 @@
|
|
|
419
471
|
}
|
|
420
472
|
return this.parseEnvValue(env[k]);
|
|
421
473
|
}
|
|
474
|
+
/**
|
|
475
|
+
* @description Converts stringified environment values into native types.
|
|
476
|
+
* @summary Interprets booleans and numbers while leaving other types unchanged.
|
|
477
|
+
* @param {unknown} val - Raw value retrieved from the environment.
|
|
478
|
+
* @return {unknown} Parsed value converted to boolean, number, or left as-is.
|
|
479
|
+
*/
|
|
422
480
|
parseEnvValue(val) {
|
|
423
481
|
if (typeof val !== "string")
|
|
424
482
|
return val;
|
|
@@ -432,10 +490,10 @@
|
|
|
432
490
|
return val;
|
|
433
491
|
}
|
|
434
492
|
/**
|
|
435
|
-
* @description Expands an object into the environment
|
|
436
|
-
* @summary Defines properties
|
|
437
|
-
* @template V - Type of the object being expanded
|
|
438
|
-
* @param {V} value -
|
|
493
|
+
* @description Expands an object into the environment.
|
|
494
|
+
* @summary Defines lazy properties that first consult runtime variables before falling back to seeded values.
|
|
495
|
+
* @template V - Type of the object being expanded.
|
|
496
|
+
* @param {V} value - Object to expose through environment getters and setters.
|
|
439
497
|
* @return {void}
|
|
440
498
|
*/
|
|
441
499
|
expand(value) {
|
|
@@ -448,9 +506,9 @@
|
|
|
448
506
|
if (v && typeof v === "object") {
|
|
449
507
|
return Environment.buildEnvProxy(v, [k]);
|
|
450
508
|
}
|
|
451
|
-
// If the model provides an empty string,
|
|
509
|
+
// If the model provides an empty string, mark with EmptyValue so instance proxy can return undefined without enabling key composition
|
|
452
510
|
if (v === "") {
|
|
453
|
-
return
|
|
511
|
+
return EmptyValue;
|
|
454
512
|
}
|
|
455
513
|
return v;
|
|
456
514
|
},
|
|
@@ -466,10 +524,10 @@
|
|
|
466
524
|
* @protected
|
|
467
525
|
* @static
|
|
468
526
|
* @description Retrieves or creates the singleton instance of the Environment class.
|
|
469
|
-
* @summary Ensures only one instance
|
|
527
|
+
* @summary Ensures only one {@link Environment} instance is created, wrapping it in a proxy to compose ENV keys on demand.
|
|
470
528
|
* @template E
|
|
471
|
-
* @param {...unknown[]} args - Arguments
|
|
472
|
-
* @return {E}
|
|
529
|
+
* @param {...unknown[]} args - Arguments forwarded to the factory when instantiating the singleton.
|
|
530
|
+
* @return {E} Singleton environment instance.
|
|
473
531
|
*/
|
|
474
532
|
static instance(...args) {
|
|
475
533
|
if (!Environment._instance) {
|
|
@@ -477,6 +535,8 @@
|
|
|
477
535
|
const proxied = new Proxy(base, {
|
|
478
536
|
get(target, prop, receiver) {
|
|
479
537
|
const value = Reflect.get(target, prop, receiver);
|
|
538
|
+
if (value === EmptyValue)
|
|
539
|
+
return undefined;
|
|
480
540
|
if (typeof value !== "undefined")
|
|
481
541
|
return value;
|
|
482
542
|
if (typeof prop === "string") {
|
|
@@ -495,10 +555,11 @@
|
|
|
495
555
|
/**
|
|
496
556
|
* @static
|
|
497
557
|
* @description Accumulates the given value into the environment.
|
|
498
|
-
* @summary Adds new properties
|
|
558
|
+
* @summary Adds new properties, hiding raw descriptors to avoid leaking enumeration semantics.
|
|
559
|
+
* @template T
|
|
499
560
|
* @template V
|
|
500
|
-
* @param {V} value -
|
|
501
|
-
* @return {
|
|
561
|
+
* @param {V} value - Object to merge into the environment.
|
|
562
|
+
* @return {Environment} Updated environment reference.
|
|
502
563
|
*/
|
|
503
564
|
static accumulate(value) {
|
|
504
565
|
const instance = Environment.instance();
|
|
@@ -513,9 +574,22 @@
|
|
|
513
574
|
});
|
|
514
575
|
return instance.accumulate(value);
|
|
515
576
|
}
|
|
577
|
+
/**
|
|
578
|
+
* @description Retrieves a value using a dot-path key from the accumulated environment.
|
|
579
|
+
* @summary Delegates to the singleton instance to access stored configuration.
|
|
580
|
+
* @param {string} key - Key to resolve from the environment store.
|
|
581
|
+
* @return {unknown} Stored value corresponding to the provided key.
|
|
582
|
+
*/
|
|
516
583
|
static get(key) {
|
|
517
584
|
return Environment._instance.get(key);
|
|
518
585
|
}
|
|
586
|
+
/**
|
|
587
|
+
* @description Builds a proxy that composes environment keys for nested properties.
|
|
588
|
+
* @summary Allows chained property access to emit uppercase ENV identifiers while honoring existing runtime overrides.
|
|
589
|
+
* @param {any} current - Seed model segment used when projecting nested structures.
|
|
590
|
+
* @param {string[]} path - Accumulated path segments leading to the proxy.
|
|
591
|
+
* @return {any} Proxy that resolves environment values or composes additional proxies for deeper paths.
|
|
592
|
+
*/
|
|
519
593
|
static buildEnvProxy(current, path) {
|
|
520
594
|
const buildKey = (p) => p.map((seg) => toENVFormat(seg)).join(ENV_PATH_DELIMITER);
|
|
521
595
|
// Helper to read from the active environment given a composed key
|
|
@@ -552,6 +626,9 @@
|
|
|
552
626
|
const isNextObject = nextModel && typeof nextModel === "object";
|
|
553
627
|
if (isNextObject)
|
|
554
628
|
return Environment.buildEnvProxy(nextModel, nextPath);
|
|
629
|
+
// If the model marks this leaf as an empty string, treat as undefined (no proxy)
|
|
630
|
+
if (nextModel === "")
|
|
631
|
+
return undefined;
|
|
555
632
|
// Always return a proxy for further path composition when no ENV value;
|
|
556
633
|
// do not surface primitive model defaults here (this API is for key composition).
|
|
557
634
|
return Environment.buildEnvProxy(undefined, nextPath);
|
|
@@ -584,6 +661,12 @@
|
|
|
584
661
|
.map((k) => (toEnv ? toENVFormat(k) : k));
|
|
585
662
|
}
|
|
586
663
|
}
|
|
664
|
+
/**
|
|
665
|
+
* @description Singleton environment instance seeded with default logging configuration.
|
|
666
|
+
* @summary Combines {@link DefaultLoggingConfig} with runtime environment variables to provide consistent logging defaults across platforms.
|
|
667
|
+
* @const LoggedEnvironment
|
|
668
|
+
* @memberOf module:Logging
|
|
669
|
+
*/
|
|
587
670
|
const LoggedEnvironment = Environment.accumulate(Object.assign({}, DefaultLoggingConfig, {
|
|
588
671
|
env: (isBrowser() && globalThis[BrowserEnvKey]
|
|
589
672
|
? globalThis[BrowserEnvKey]["NODE_ENV"]
|
|
@@ -758,6 +841,9 @@
|
|
|
758
841
|
return;
|
|
759
842
|
let method;
|
|
760
843
|
switch (level) {
|
|
844
|
+
case exports.LogLevel.benchmark:
|
|
845
|
+
method = console.log;
|
|
846
|
+
break;
|
|
761
847
|
case exports.LogLevel.info:
|
|
762
848
|
method = console.log;
|
|
763
849
|
break;
|
|
@@ -773,6 +859,15 @@
|
|
|
773
859
|
}
|
|
774
860
|
method(this.createLog(level, msg, error));
|
|
775
861
|
}
|
|
862
|
+
/**
|
|
863
|
+
* @description Logs a message at the benchmark level
|
|
864
|
+
* @summary Logs a message at the benchmark level if the current verbosity setting allows it
|
|
865
|
+
* @param {StringLike} msg - The message to be logged
|
|
866
|
+
* @return {void}
|
|
867
|
+
*/
|
|
868
|
+
benchmark(msg) {
|
|
869
|
+
this.log(exports.LogLevel.benchmark, msg);
|
|
870
|
+
}
|
|
776
871
|
/**
|
|
777
872
|
* @description Logs a message at the silly level
|
|
778
873
|
* @summary Logs a message at the silly level if the current verbosity setting allows it
|
|
@@ -974,6 +1069,15 @@
|
|
|
974
1069
|
static debug(msg) {
|
|
975
1070
|
return this.get().debug(msg);
|
|
976
1071
|
}
|
|
1072
|
+
/**
|
|
1073
|
+
* @description Logs a benchmark message.
|
|
1074
|
+
* @summary Delegates the benchmark logging to the global logger instance.
|
|
1075
|
+
*
|
|
1076
|
+
* @param msg - The message to be logged.
|
|
1077
|
+
*/
|
|
1078
|
+
static benchmark(msg) {
|
|
1079
|
+
return this.get().benchmark(msg);
|
|
1080
|
+
}
|
|
977
1081
|
/**
|
|
978
1082
|
* @description Logs a silly message.
|
|
979
1083
|
* @summary Delegates the debug logging to the global logger instance.
|
|
@@ -1129,12 +1233,8 @@
|
|
|
1129
1233
|
}
|
|
1130
1234
|
|
|
1131
1235
|
/**
|
|
1132
|
-
* @description Base class that provides a ready-to-use logger instance
|
|
1133
|
-
* @summary
|
|
1134
|
-
* into derived classes through a protected getter. Subclasses can directly access
|
|
1135
|
-
* this.log to emit messages without manually creating a logger. This promotes
|
|
1136
|
-
* consistent, context-aware logging across the codebase.
|
|
1137
|
-
* @param {void} [constructor] - No constructor arguments; subclasses may define their own
|
|
1236
|
+
* @description Base class that provides a ready-to-use logger instance.
|
|
1237
|
+
* @summary Supplies inheriting classes with a lazily created, context-aware {@link Logger} via the protected `log` getter, promoting consistent structured logging without manual wiring.
|
|
1138
1238
|
* @class LoggedClass
|
|
1139
1239
|
* @example
|
|
1140
1240
|
* class UserService extends LoggedClass {
|
|
@@ -1162,30 +1262,273 @@
|
|
|
1162
1262
|
*/
|
|
1163
1263
|
class LoggedClass {
|
|
1164
1264
|
/**
|
|
1165
|
-
* @description Lazily provides a context-aware logger for the current instance
|
|
1166
|
-
* @summary
|
|
1167
|
-
*
|
|
1168
|
-
* @return {Logger} A logger bound to the subclass context
|
|
1265
|
+
* @description Lazily provides a context-aware logger for the current instance.
|
|
1266
|
+
* @summary Calls {@link Logging.for} with the subclass instance to obtain a logger whose context matches the subclass name.
|
|
1267
|
+
* @return {Logger} Logger bound to the subclass context.
|
|
1169
1268
|
*/
|
|
1170
1269
|
get log() {
|
|
1171
|
-
|
|
1270
|
+
if (!this._log)
|
|
1271
|
+
this._log = Logging.for(this);
|
|
1272
|
+
return this._log;
|
|
1172
1273
|
}
|
|
1173
1274
|
constructor() { }
|
|
1174
1275
|
}
|
|
1175
1276
|
|
|
1277
|
+
/**
|
|
1278
|
+
* @description Base class for message filters that plug into the logging pipeline.
|
|
1279
|
+
* @summary Extends {@link LoggedClass} to supply a scoped logger and defines the contract required by {@link LoggingFilter} implementers that transform or drop log messages before emission.
|
|
1280
|
+
* @class LogFilter
|
|
1281
|
+
* @example
|
|
1282
|
+
* class RedactSecretsFilter extends LogFilter {
|
|
1283
|
+
* filter(config: LoggingConfig, message: string): string {
|
|
1284
|
+
* return message.replace(/secret/gi, "***");
|
|
1285
|
+
* }
|
|
1286
|
+
* }
|
|
1287
|
+
*
|
|
1288
|
+
* const filter = new RedactSecretsFilter();
|
|
1289
|
+
* filter.filter({ ...DefaultLoggingConfig, verbose: 0 }, "secret token");
|
|
1290
|
+
* @mermaid
|
|
1291
|
+
* sequenceDiagram
|
|
1292
|
+
* participant Logger
|
|
1293
|
+
* participant Filter as LogFilter
|
|
1294
|
+
* participant Impl as ConcreteFilter
|
|
1295
|
+
* participant Output
|
|
1296
|
+
* Logger->>Filter: filter(config, message, context)
|
|
1297
|
+
* Filter->>Impl: delegate to subclass implementation
|
|
1298
|
+
* Impl-->>Filter: transformed message
|
|
1299
|
+
* Filter-->>Output: return filtered message
|
|
1300
|
+
*/
|
|
1176
1301
|
class LogFilter extends LoggedClass {
|
|
1302
|
+
/**
|
|
1303
|
+
* @description Scoped logger that excludes other filters from the chain.
|
|
1304
|
+
* @summary Returns a child logger dedicated to the filter, preventing recursive filter invocation when emitting diagnostic messages.
|
|
1305
|
+
* @return {Logger} Context-aware logger for the filter instance.
|
|
1306
|
+
*/
|
|
1177
1307
|
get log() {
|
|
1178
1308
|
return super.log.for(this, { filters: [] });
|
|
1179
1309
|
}
|
|
1180
1310
|
}
|
|
1181
1311
|
|
|
1312
|
+
function safeNow() {
|
|
1313
|
+
// Prefer performance.now when available
|
|
1314
|
+
if (typeof globalThis !== "undefined" &&
|
|
1315
|
+
typeof globalThis.performance?.now === "function") {
|
|
1316
|
+
return () => globalThis.performance.now();
|
|
1317
|
+
}
|
|
1318
|
+
// Node: use process.hrtime.bigint for higher precision if available
|
|
1319
|
+
if (typeof process !== "undefined" &&
|
|
1320
|
+
typeof process.hrtime?.bigint === "function") {
|
|
1321
|
+
return () => {
|
|
1322
|
+
const ns = process.hrtime.bigint(); // nanoseconds
|
|
1323
|
+
return Number(ns) / 1_000_000; // to ms
|
|
1324
|
+
};
|
|
1325
|
+
}
|
|
1326
|
+
// Fallback
|
|
1327
|
+
return () => Date.now();
|
|
1328
|
+
}
|
|
1329
|
+
/**
|
|
1330
|
+
* @description High-resolution clock accessor returning milliseconds.
|
|
1331
|
+
* @summary Chooses the most precise timer available in the current runtime, preferring `performance.now` or `process.hrtime.bigint`.
|
|
1332
|
+
* @return {number} Milliseconds elapsed according to the best available clock.
|
|
1333
|
+
*/
|
|
1334
|
+
const now = safeNow();
|
|
1335
|
+
/**
|
|
1336
|
+
* @description High-resolution stopwatch with pause, resume, and lap tracking.
|
|
1337
|
+
* @summary Tracks elapsed time using the highest precision timer available, supports pausing, resuming, and recording labeled laps for diagnostics and benchmarking.
|
|
1338
|
+
* @param {boolean} [autoStart=false] - When true, the stopwatch starts immediately upon construction.
|
|
1339
|
+
* @class StopWatch
|
|
1340
|
+
* @example
|
|
1341
|
+
* const sw = new StopWatch(true);
|
|
1342
|
+
* // ... work ...
|
|
1343
|
+
* const lap = sw.lap("phase 1");
|
|
1344
|
+
* sw.pause();
|
|
1345
|
+
* console.log(`Elapsed: ${lap.totalMs}ms`);
|
|
1346
|
+
* @mermaid
|
|
1347
|
+
* sequenceDiagram
|
|
1348
|
+
* participant Client
|
|
1349
|
+
* participant StopWatch
|
|
1350
|
+
* participant Clock as now()
|
|
1351
|
+
* Client->>StopWatch: start()
|
|
1352
|
+
* StopWatch->>Clock: now()
|
|
1353
|
+
* Clock-->>StopWatch: timestamp
|
|
1354
|
+
* Client->>StopWatch: lap()
|
|
1355
|
+
* StopWatch->>Clock: now()
|
|
1356
|
+
* Clock-->>StopWatch: timestamp
|
|
1357
|
+
* StopWatch-->>Client: Lap
|
|
1358
|
+
* Client->>StopWatch: pause()
|
|
1359
|
+
* StopWatch->>Clock: now()
|
|
1360
|
+
* Clock-->>StopWatch: timestamp
|
|
1361
|
+
*/
|
|
1362
|
+
class StopWatch {
|
|
1363
|
+
constructor(autoStart = false) {
|
|
1364
|
+
this._startMs = null;
|
|
1365
|
+
this._elapsedMs = 0;
|
|
1366
|
+
this._running = false;
|
|
1367
|
+
this._laps = [];
|
|
1368
|
+
this._lastLapTotalMs = 0;
|
|
1369
|
+
if (autoStart)
|
|
1370
|
+
this.start();
|
|
1371
|
+
}
|
|
1372
|
+
/**
|
|
1373
|
+
* @description Indicates whether the stopwatch is actively running.
|
|
1374
|
+
* @summary Returns `true` when timing is in progress and `false` when paused or stopped.
|
|
1375
|
+
* @return {boolean} Current running state.
|
|
1376
|
+
*/
|
|
1377
|
+
get running() {
|
|
1378
|
+
return this._running;
|
|
1379
|
+
}
|
|
1380
|
+
/**
|
|
1381
|
+
* @description Elapsed time captured by the stopwatch.
|
|
1382
|
+
* @summary Computes the total elapsed time in milliseconds, including the current session if running.
|
|
1383
|
+
* @return {number} Milliseconds elapsed since the stopwatch started.
|
|
1384
|
+
*/
|
|
1385
|
+
get elapsedMs() {
|
|
1386
|
+
if (!this._running || this._startMs == null)
|
|
1387
|
+
return this._elapsedMs;
|
|
1388
|
+
return this._elapsedMs + (now() - this._startMs);
|
|
1389
|
+
}
|
|
1390
|
+
/**
|
|
1391
|
+
* @description Starts timing if the stopwatch is not already running.
|
|
1392
|
+
* @summary Records the current timestamp and transitions the stopwatch into the running state.
|
|
1393
|
+
* @return {this} Fluent reference to the stopwatch.
|
|
1394
|
+
*/
|
|
1395
|
+
start() {
|
|
1396
|
+
if (!this._running) {
|
|
1397
|
+
this._running = true;
|
|
1398
|
+
this._startMs = now();
|
|
1399
|
+
}
|
|
1400
|
+
return this;
|
|
1401
|
+
}
|
|
1402
|
+
/**
|
|
1403
|
+
* @description Pauses timing and accumulates elapsed milliseconds.
|
|
1404
|
+
* @summary Captures the partial duration, updates the accumulator, and keeps the stopwatch ready to resume later.
|
|
1405
|
+
* @return {this} Fluent reference to the stopwatch.
|
|
1406
|
+
*/
|
|
1407
|
+
pause() {
|
|
1408
|
+
if (this._running && this._startMs != null) {
|
|
1409
|
+
this._elapsedMs += now() - this._startMs;
|
|
1410
|
+
this._startMs = null;
|
|
1411
|
+
this._running = false;
|
|
1412
|
+
}
|
|
1413
|
+
return this;
|
|
1414
|
+
}
|
|
1415
|
+
/**
|
|
1416
|
+
* @description Resumes timing after a pause.
|
|
1417
|
+
* @summary Captures a fresh start timestamp while keeping previous elapsed time intact.
|
|
1418
|
+
* @return {this} Fluent reference to the stopwatch.
|
|
1419
|
+
*/
|
|
1420
|
+
resume() {
|
|
1421
|
+
if (!this._running) {
|
|
1422
|
+
this._running = true;
|
|
1423
|
+
this._startMs = now();
|
|
1424
|
+
}
|
|
1425
|
+
return this;
|
|
1426
|
+
}
|
|
1427
|
+
/**
|
|
1428
|
+
* @description Stops timing and returns the total elapsed milliseconds.
|
|
1429
|
+
* @summary Invokes {@link StopWatch.pause} to consolidate elapsed time, leaving the stopwatch in a non-running state.
|
|
1430
|
+
* @return {number} Milliseconds accumulated across all runs.
|
|
1431
|
+
*/
|
|
1432
|
+
stop() {
|
|
1433
|
+
this.pause();
|
|
1434
|
+
return this._elapsedMs;
|
|
1435
|
+
}
|
|
1436
|
+
/**
|
|
1437
|
+
* @description Resets the stopwatch state while optionally continuing to run.
|
|
1438
|
+
* @summary Clears elapsed time and lap history, preserving whether the stopwatch should continue ticking.
|
|
1439
|
+
* @return {this} Fluent reference to the stopwatch.
|
|
1440
|
+
*/
|
|
1441
|
+
reset() {
|
|
1442
|
+
const wasRunning = this._running;
|
|
1443
|
+
this._startMs = wasRunning ? now() : null;
|
|
1444
|
+
this._elapsedMs = 0;
|
|
1445
|
+
this._laps = [];
|
|
1446
|
+
this._lastLapTotalMs = 0;
|
|
1447
|
+
return this;
|
|
1448
|
+
}
|
|
1449
|
+
/**
|
|
1450
|
+
* @description Records a lap split since the stopwatch started or since the previous lap.
|
|
1451
|
+
* @summary Stores the lap metadata, updates cumulative tracking, and returns the newly created {@link Lap}.
|
|
1452
|
+
* @param {string} [label] - Optional label describing the lap.
|
|
1453
|
+
* @return {Lap} Lap snapshot capturing incremental and cumulative timings.
|
|
1454
|
+
*/
|
|
1455
|
+
lap(label) {
|
|
1456
|
+
const total = this.elapsedMs;
|
|
1457
|
+
const ms = total - this._lastLapTotalMs;
|
|
1458
|
+
const lap = {
|
|
1459
|
+
index: this._laps.length,
|
|
1460
|
+
label,
|
|
1461
|
+
ms,
|
|
1462
|
+
totalMs: total,
|
|
1463
|
+
};
|
|
1464
|
+
this._laps.push(lap);
|
|
1465
|
+
this._lastLapTotalMs = total;
|
|
1466
|
+
return lap;
|
|
1467
|
+
}
|
|
1468
|
+
/**
|
|
1469
|
+
* @description Retrieves the recorded lap history.
|
|
1470
|
+
* @summary Returns the internal lap array as a read-only view to prevent external mutation.
|
|
1471
|
+
* @return {Lap[]} Laps captured by the stopwatch.
|
|
1472
|
+
*/
|
|
1473
|
+
get laps() {
|
|
1474
|
+
return this._laps;
|
|
1475
|
+
}
|
|
1476
|
+
/**
|
|
1477
|
+
* @description Formats the elapsed time in a human-readable representation.
|
|
1478
|
+
* @summary Uses {@link formatMs} to produce an `hh:mm:ss.mmm` string for display and logging.
|
|
1479
|
+
* @return {string} Elapsed time formatted for presentation.
|
|
1480
|
+
*/
|
|
1481
|
+
toString() {
|
|
1482
|
+
return formatMs(this.elapsedMs);
|
|
1483
|
+
}
|
|
1484
|
+
/**
|
|
1485
|
+
* @description Serializes the stopwatch state.
|
|
1486
|
+
* @summary Provides a JSON-friendly snapshot including running state, elapsed time, and lap details.
|
|
1487
|
+
* @return {{running: boolean, elapsedMs: number, laps: Lap[]}} Serializable stopwatch representation.
|
|
1488
|
+
*/
|
|
1489
|
+
toJSON() {
|
|
1490
|
+
return {
|
|
1491
|
+
running: this._running,
|
|
1492
|
+
elapsedMs: this.elapsedMs,
|
|
1493
|
+
laps: this._laps.slice(),
|
|
1494
|
+
};
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
/**
|
|
1498
|
+
* @description Formats milliseconds into `hh:mm:ss.mmm`.
|
|
1499
|
+
* @summary Breaks the duration into hours, minutes, seconds, and milliseconds, returning a zero-padded string.
|
|
1500
|
+
* @param {number} ms - Milliseconds to format.
|
|
1501
|
+
* @return {string} Formatted duration string.
|
|
1502
|
+
* @function formatMs
|
|
1503
|
+
* @memberOf module:Logging
|
|
1504
|
+
* @mermaid
|
|
1505
|
+
* sequenceDiagram
|
|
1506
|
+
* participant Caller
|
|
1507
|
+
* participant Formatter as formatMs
|
|
1508
|
+
* Caller->>Formatter: formatMs(ms)
|
|
1509
|
+
* Formatter->>Formatter: derive hours/minutes/seconds
|
|
1510
|
+
* Formatter->>Formatter: pad segments
|
|
1511
|
+
* Formatter-->>Caller: hh:mm:ss.mmm
|
|
1512
|
+
*/
|
|
1513
|
+
function formatMs(ms) {
|
|
1514
|
+
const sign = ms < 0 ? "-" : "";
|
|
1515
|
+
const abs = Math.abs(ms);
|
|
1516
|
+
const hours = Math.floor(abs / 3_600_000);
|
|
1517
|
+
const minutes = Math.floor((abs % 3_600_000) / 60_000);
|
|
1518
|
+
const seconds = Math.floor((abs % 60_000) / 1000);
|
|
1519
|
+
const millis = Math.floor(abs % 1000);
|
|
1520
|
+
const pad = (n, w) => n.toString().padStart(w, "0");
|
|
1521
|
+
return `${sign}${pad(hours, 2)}:${pad(minutes, 2)}:${pad(seconds, 2)}.${pad(millis, 3)}`;
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1182
1524
|
/**
|
|
1183
|
-
* @description Method decorator for logging function calls
|
|
1184
|
-
* @summary
|
|
1185
|
-
* @param {LogLevel} level -
|
|
1186
|
-
* @param {
|
|
1187
|
-
* @param {
|
|
1188
|
-
* @
|
|
1525
|
+
* @description Method decorator for logging function calls.
|
|
1526
|
+
* @summary Wraps class methods to automatically log entry, exit, timing, and optional custom messages at a configurable {@link LogLevel}.
|
|
1527
|
+
* @param {LogLevel} level - Log level applied to the generated log statements (defaults to `LogLevel.info`).
|
|
1528
|
+
* @param {number} [verbosity=0] - Verbosity threshold required for the entry log to appear.
|
|
1529
|
+
* @param {ArgFormatFunction} [entryMessage] - Formatter invoked with the original method arguments to describe the invocation.
|
|
1530
|
+
* @param {ReturnFormatFunction} [exitMessage] - Optional formatter that describes the outcome or failure of the call.
|
|
1531
|
+
* @return {function(any, any, PropertyDescriptor): void} Method decorator proxy that injects logging behavior.
|
|
1189
1532
|
* @function log
|
|
1190
1533
|
* @mermaid
|
|
1191
1534
|
* sequenceDiagram
|
|
@@ -1210,93 +1553,153 @@
|
|
|
1210
1553
|
* end
|
|
1211
1554
|
* @category Method Decorators
|
|
1212
1555
|
*/
|
|
1213
|
-
function log(level = exports.LogLevel.info,
|
|
1214
|
-
return function (target, propertyKey, descriptor) {
|
|
1215
|
-
if (!descriptor)
|
|
1556
|
+
function log(level = exports.LogLevel.info, verbosity = 0, entryMessage = (...args) => `called with ${args}`, exitMessage) {
|
|
1557
|
+
return function log(target, propertyKey, descriptor) {
|
|
1558
|
+
if (!descriptor || typeof descriptor === "number")
|
|
1216
1559
|
throw new Error(`Logging decoration only applies to methods`);
|
|
1217
|
-
const logger =
|
|
1560
|
+
const logger = target instanceof LoggedClass
|
|
1561
|
+
? target["log"].for(target[propertyKey])
|
|
1562
|
+
: Logging.for(target).for(target[propertyKey]);
|
|
1218
1563
|
const method = logger[level].bind(logger);
|
|
1219
1564
|
const originalMethod = descriptor.value;
|
|
1220
1565
|
descriptor.value = new Proxy(originalMethod, {
|
|
1221
1566
|
apply(fn, thisArg, args) {
|
|
1222
|
-
method(
|
|
1223
|
-
|
|
1567
|
+
method(entryMessage(...args), verbosity);
|
|
1568
|
+
try {
|
|
1569
|
+
const result = Reflect.apply(fn, thisArg, args);
|
|
1570
|
+
if (result instanceof Promise) {
|
|
1571
|
+
return result
|
|
1572
|
+
.then((r) => {
|
|
1573
|
+
if (exitMessage)
|
|
1574
|
+
method(exitMessage(undefined, r));
|
|
1575
|
+
return r;
|
|
1576
|
+
})
|
|
1577
|
+
.catch((e) => {
|
|
1578
|
+
if (exitMessage)
|
|
1579
|
+
logger.error(exitMessage(e));
|
|
1580
|
+
throw e;
|
|
1581
|
+
});
|
|
1582
|
+
}
|
|
1583
|
+
if (exitMessage)
|
|
1584
|
+
method(exitMessage(undefined, result));
|
|
1585
|
+
return result;
|
|
1586
|
+
}
|
|
1587
|
+
catch (err) {
|
|
1588
|
+
if (exitMessage)
|
|
1589
|
+
logger.error(exitMessage(err));
|
|
1590
|
+
throw err;
|
|
1591
|
+
}
|
|
1592
|
+
},
|
|
1593
|
+
});
|
|
1594
|
+
return descriptor;
|
|
1595
|
+
};
|
|
1596
|
+
}
|
|
1597
|
+
/**
|
|
1598
|
+
* @description Method decorator that records execution time at the benchmark level.
|
|
1599
|
+
* @summary Wraps the target method to emit {@link Logger.benchmark} entries capturing completion time or failure latency.
|
|
1600
|
+
* @return {function(any, any, PropertyDescriptor): void} Method decorator proxy that benchmarks the original implementation.
|
|
1601
|
+
* @function benchmark
|
|
1602
|
+
* @mermaid
|
|
1603
|
+
* sequenceDiagram
|
|
1604
|
+
* participant Caller
|
|
1605
|
+
* participant Decorator as benchmark
|
|
1606
|
+
* participant Method as Original Method
|
|
1607
|
+
* Caller->>Decorator: invoke()
|
|
1608
|
+
* Decorator->>Method: Reflect.apply(...)
|
|
1609
|
+
* alt Promise result
|
|
1610
|
+
* Method-->>Decorator: Promise
|
|
1611
|
+
* Decorator->>Decorator: attach then()
|
|
1612
|
+
* Decorator->>Decorator: log completion duration
|
|
1613
|
+
* else Synchronous result
|
|
1614
|
+
* Method-->>Decorator: value
|
|
1615
|
+
* Decorator->>Decorator: log completion duration
|
|
1616
|
+
* end
|
|
1617
|
+
* Decorator-->>Caller: return result
|
|
1618
|
+
* @category Method Decorators
|
|
1619
|
+
*/
|
|
1620
|
+
function benchmark() {
|
|
1621
|
+
return function benchmark(target, propertyKey, descriptor) {
|
|
1622
|
+
if (!descriptor || typeof descriptor === "number")
|
|
1623
|
+
throw new Error(`benchmark decoration only applies to methods`);
|
|
1624
|
+
const logger = target instanceof LoggedClass
|
|
1625
|
+
? target["log"].for(target[propertyKey])
|
|
1626
|
+
: Logging.for(target).for(target[propertyKey]);
|
|
1627
|
+
const originalMethod = descriptor.value;
|
|
1628
|
+
descriptor.value = new Proxy(originalMethod, {
|
|
1629
|
+
apply(fn, thisArg, args) {
|
|
1630
|
+
const start = now();
|
|
1224
1631
|
try {
|
|
1225
1632
|
const result = Reflect.apply(fn, thisArg, args);
|
|
1226
1633
|
if (result instanceof Promise) {
|
|
1227
1634
|
return result.then((r) => {
|
|
1228
|
-
|
|
1229
|
-
method(`completed in ${Date.now() - start}ms`, verbosity);
|
|
1635
|
+
logger.benchmark(`completed in ${now() - start}ms`);
|
|
1230
1636
|
return r;
|
|
1231
1637
|
});
|
|
1232
1638
|
}
|
|
1233
|
-
|
|
1234
|
-
method(`completed in ${Date.now() - start}ms`, verbosity);
|
|
1639
|
+
logger.benchmark(`completed in ${now() - start}ms`);
|
|
1235
1640
|
return result;
|
|
1236
1641
|
}
|
|
1237
1642
|
catch (err) {
|
|
1238
|
-
|
|
1239
|
-
method(`failed in ${Date.now() - start}ms`, verbosity);
|
|
1643
|
+
logger.benchmark(`failed in ${now() - start}ms`);
|
|
1240
1644
|
throw err;
|
|
1241
1645
|
}
|
|
1242
1646
|
},
|
|
1243
1647
|
});
|
|
1648
|
+
return descriptor;
|
|
1244
1649
|
};
|
|
1245
1650
|
}
|
|
1246
1651
|
/**
|
|
1247
|
-
* @description Method decorator for logging function calls with debug level
|
|
1248
|
-
* @summary Convenience wrapper around
|
|
1249
|
-
* @
|
|
1250
|
-
* @return {Function} A method decorator that wraps the original method with debug logging
|
|
1652
|
+
* @description Method decorator for logging function calls with debug level.
|
|
1653
|
+
* @summary Convenience wrapper around {@link log} that logs using `LogLevel.debug`.
|
|
1654
|
+
* @return {function(any, any, PropertyDescriptor): void} Debug-level logging decorator.
|
|
1251
1655
|
* @function debug
|
|
1252
1656
|
* @category Method Decorators
|
|
1253
1657
|
*/
|
|
1254
|
-
function debug(
|
|
1255
|
-
return log(exports.LogLevel.debug,
|
|
1658
|
+
function debug() {
|
|
1659
|
+
return log(exports.LogLevel.debug, 0, (...args) => `called with ${args}`, (e, result) => e
|
|
1660
|
+
? `Failed with: ${e}`
|
|
1661
|
+
: result
|
|
1662
|
+
? `Completed with ${JSON.stringify(result)}`
|
|
1663
|
+
: "completed");
|
|
1256
1664
|
}
|
|
1257
1665
|
/**
|
|
1258
|
-
* @description Method decorator for logging function calls with info level
|
|
1259
|
-
* @summary Convenience wrapper around
|
|
1260
|
-
* @
|
|
1261
|
-
* @return {Function} A method decorator that wraps the original method with info logging
|
|
1666
|
+
* @description Method decorator for logging function calls with info level.
|
|
1667
|
+
* @summary Convenience wrapper around {@link log} that logs using `LogLevel.info`.
|
|
1668
|
+
* @return {function(any, any, PropertyDescriptor): void} Info-level logging decorator.
|
|
1262
1669
|
* @function info
|
|
1263
1670
|
* @category Method Decorators
|
|
1264
1671
|
*/
|
|
1265
|
-
function info(
|
|
1266
|
-
return log(exports.LogLevel.info
|
|
1672
|
+
function info() {
|
|
1673
|
+
return log(exports.LogLevel.info);
|
|
1267
1674
|
}
|
|
1268
1675
|
/**
|
|
1269
|
-
* @description Method decorator for logging function calls with silly level
|
|
1270
|
-
* @summary Convenience wrapper around
|
|
1271
|
-
* @
|
|
1272
|
-
* @return {Function} A method decorator that wraps the original method with silly logging
|
|
1676
|
+
* @description Method decorator for logging function calls with silly level.
|
|
1677
|
+
* @summary Convenience wrapper around {@link log} that logs using `LogLevel.silly`.
|
|
1678
|
+
* @return {function(any, any, PropertyDescriptor): void} Silly-level logging decorator.
|
|
1273
1679
|
* @function silly
|
|
1274
1680
|
* @category Method Decorators
|
|
1275
1681
|
*/
|
|
1276
|
-
function silly(
|
|
1277
|
-
return log(exports.LogLevel.silly
|
|
1682
|
+
function silly() {
|
|
1683
|
+
return log(exports.LogLevel.silly);
|
|
1278
1684
|
}
|
|
1279
1685
|
/**
|
|
1280
|
-
* @description Method decorator for logging function calls with verbose level
|
|
1281
|
-
* @summary Convenience wrapper around
|
|
1282
|
-
* @param {number} verbosity -
|
|
1283
|
-
* @
|
|
1284
|
-
* @return {Function} A method decorator that wraps the original method with verbose logging
|
|
1686
|
+
* @description Method decorator for logging function calls with verbose level.
|
|
1687
|
+
* @summary Convenience wrapper around {@link log} that logs using `LogLevel.verbose` with configurable verbosity and optional benchmarking.
|
|
1688
|
+
* @param {number|boolean} verbosity - Verbosity level for log filtering or flag to enable benchmarking.
|
|
1689
|
+
* @return {function(any, any,PropertyDescriptor): void} Verbose logging decorator.
|
|
1285
1690
|
* @function verbose
|
|
1286
1691
|
* @category Method Decorators
|
|
1287
1692
|
*/
|
|
1288
|
-
function verbose(verbosity = 0
|
|
1289
|
-
if (
|
|
1290
|
-
benchmark = verbosity;
|
|
1693
|
+
function verbose(verbosity = 0) {
|
|
1694
|
+
if (!verbosity) {
|
|
1291
1695
|
verbosity = 0;
|
|
1292
1696
|
}
|
|
1293
|
-
return log(exports.LogLevel.verbose,
|
|
1697
|
+
return log(exports.LogLevel.verbose, verbosity);
|
|
1294
1698
|
}
|
|
1295
1699
|
/**
|
|
1296
|
-
* @description Creates a decorator that makes a method non-configurable
|
|
1297
|
-
* @summary
|
|
1298
|
-
*
|
|
1299
|
-
* @return {Function} A decorator function that can be applied to methods
|
|
1700
|
+
* @description Creates a decorator that makes a method non-configurable.
|
|
1701
|
+
* @summary Prevents overriding by marking the method descriptor as non-configurable, throwing if applied to non-method targets.
|
|
1702
|
+
* @return {function(object, any, PropertyDescriptor): PropertyDescriptor|undefined} Decorator that hardens the method descriptor.
|
|
1300
1703
|
* @function final
|
|
1301
1704
|
* @category Method Decorators
|
|
1302
1705
|
*/
|
|
@@ -1311,17 +1714,57 @@
|
|
|
1311
1714
|
};
|
|
1312
1715
|
}
|
|
1313
1716
|
|
|
1717
|
+
/**
|
|
1718
|
+
* @description Filter that patches log messages using regular expressions.
|
|
1719
|
+
* @summary Applies a configured {@link RegExp} and replacement strategy to redact, mask, or restructure log payloads before they are emitted.
|
|
1720
|
+
* @param {RegExp} regexp - Expression used to detect sensitive or formatted text.
|
|
1721
|
+
* @param {string|ReplacementFunction} replacement - Replacement string or callback invoked for each match.
|
|
1722
|
+
* @class PatternFilter
|
|
1723
|
+
* @example
|
|
1724
|
+
* const filter = new PatternFilter(/token=[^&]+/g, "token=***");
|
|
1725
|
+
* const sanitized = filter.filter(config, "token=123&user=tom", []);
|
|
1726
|
+
* // sanitized === "token=***&user=tom"
|
|
1727
|
+
* @mermaid
|
|
1728
|
+
* sequenceDiagram
|
|
1729
|
+
* participant Logger
|
|
1730
|
+
* participant Filter as PatternFilter
|
|
1731
|
+
* participant RegExp
|
|
1732
|
+
* Logger->>Filter: filter(config, message, context)
|
|
1733
|
+
* Filter->>RegExp: execute match()
|
|
1734
|
+
* alt match found
|
|
1735
|
+
* RegExp-->>Filter: captures
|
|
1736
|
+
* Filter->>RegExp: replace(message, replacement)
|
|
1737
|
+
* RegExp-->>Filter: transformed message
|
|
1738
|
+
* else no match
|
|
1739
|
+
* RegExp-->>Filter: null
|
|
1740
|
+
* end
|
|
1741
|
+
* Filter-->>Logger: sanitized message
|
|
1742
|
+
*/
|
|
1314
1743
|
class PatternFilter extends LogFilter {
|
|
1315
1744
|
constructor(regexp, replacement) {
|
|
1316
1745
|
super();
|
|
1317
1746
|
this.regexp = regexp;
|
|
1318
1747
|
this.replacement = replacement;
|
|
1319
1748
|
}
|
|
1749
|
+
/**
|
|
1750
|
+
* @description Ensures deterministic RegExp matching.
|
|
1751
|
+
* @summary Runs the configured expression, then resets its state so repeated invocations behave consistently.
|
|
1752
|
+
* @param {string} message - Message to test for matches.
|
|
1753
|
+
* @return {RegExpExecArray|null} Match result or null when no match is found.
|
|
1754
|
+
*/
|
|
1320
1755
|
match(message) {
|
|
1321
1756
|
const match = this.regexp.exec(message);
|
|
1322
1757
|
this.regexp.lastIndex = 0;
|
|
1323
1758
|
return match;
|
|
1324
1759
|
}
|
|
1760
|
+
/**
|
|
1761
|
+
* @description Applies the replacement strategy to the incoming message.
|
|
1762
|
+
* @summary Executes {@link PatternFilter.match} and, when a match is found, replaces every occurrence using the configured replacement handler.
|
|
1763
|
+
* @param {LoggingConfig} config - Active logging configuration (unused but part of the filter contract).
|
|
1764
|
+
* @param {string} message - Message to be sanitized.
|
|
1765
|
+
* @param {string[]} context - Context entries associated with the log event.
|
|
1766
|
+
* @return {string} Sanitized log message.
|
|
1767
|
+
*/
|
|
1325
1768
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1326
1769
|
filter(config, message, context) {
|
|
1327
1770
|
const log = this.log.for(this.filter);
|
|
@@ -1345,22 +1788,18 @@
|
|
|
1345
1788
|
], PatternFilter.prototype, "match", null);
|
|
1346
1789
|
|
|
1347
1790
|
/**
|
|
1348
|
-
* @description
|
|
1349
|
-
* @summary
|
|
1350
|
-
* - Core classes like {@link Logging} and {@link MiniLogger}
|
|
1351
|
-
* - Decorators such as {@link log} for instrumenting methods
|
|
1352
|
-
* - Configuration and constants like {@link LogLevel} and {@link DefaultLoggingConfig}
|
|
1353
|
-
* - Type definitions including {@link Logger} and {@link LoggingConfig}
|
|
1354
|
-
* These exports enable consistent, context-aware, and optionally themed logging across projects.
|
|
1791
|
+
* @description Comprehensive logging toolkit for browser and Node environments.
|
|
1792
|
+
* @summary Exposes {@link Logging} and {@link MiniLogger} for runtime logging, decorators such as {@link log} for method instrumentation, and utilities like {@link PatternFilter}, {@link StopWatch}, and {@link LoggedEnvironment} to build configurable, theme-aware log pipelines.
|
|
1355
1793
|
* @module Logging
|
|
1356
1794
|
*/
|
|
1357
1795
|
/**
|
|
1358
|
-
* @description Current package version string
|
|
1359
|
-
* @summary Stores the
|
|
1796
|
+
* @description Current package version string.
|
|
1797
|
+
* @summary Stores the package version for diagnostics and compatibility checks.
|
|
1360
1798
|
* @const VERSION
|
|
1799
|
+
* @type {string}
|
|
1361
1800
|
* @memberOf module:Logging
|
|
1362
1801
|
*/
|
|
1363
|
-
const VERSION = "0.3.
|
|
1802
|
+
const VERSION = "0.3.13";
|
|
1364
1803
|
|
|
1365
1804
|
exports.BrowserEnvKey = BrowserEnvKey;
|
|
1366
1805
|
exports.DefaultLoggingConfig = DefaultLoggingConfig;
|
|
@@ -1375,13 +1814,17 @@
|
|
|
1375
1814
|
exports.MiniLogger = MiniLogger;
|
|
1376
1815
|
exports.NumericLogLevels = NumericLogLevels;
|
|
1377
1816
|
exports.PatternFilter = PatternFilter;
|
|
1817
|
+
exports.StopWatch = StopWatch;
|
|
1378
1818
|
exports.VERSION = VERSION;
|
|
1819
|
+
exports.benchmark = benchmark;
|
|
1379
1820
|
exports.debug = debug;
|
|
1380
1821
|
exports.escapeRegExp = escapeRegExp;
|
|
1381
1822
|
exports.final = final;
|
|
1823
|
+
exports.formatMs = formatMs;
|
|
1382
1824
|
exports.info = info;
|
|
1383
1825
|
exports.isBrowser = isBrowser;
|
|
1384
1826
|
exports.log = log;
|
|
1827
|
+
exports.now = now;
|
|
1385
1828
|
exports.padEnd = padEnd;
|
|
1386
1829
|
exports.patchPlaceholders = patchPlaceholders;
|
|
1387
1830
|
exports.patchString = patchString;
|
|
@@ -1396,4 +1839,4 @@
|
|
|
1396
1839
|
exports.verbose = verbose;
|
|
1397
1840
|
|
|
1398
1841
|
}));
|
|
1399
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2luZy5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvdGV4dC50cyIsIi4uL3NyYy93ZWIudHMiLCIuLi9zcmMvZW52aXJvbm1lbnQudHMiLCIuLi9zcmMvbG9nZ2luZy50cyIsIi4uL3NyYy9Mb2dnZWRDbGFzcy50cyIsIi4uL3NyYy9maWx0ZXJzL0xvZ0ZpbHRlci50cyIsIi4uL3NyYy9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL2ZpbHRlcnMvUGF0dGVybkZpbHRlci50cyIsIi4uL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMb2dnaW5nQ29uZmlnLCBUaGVtZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmV4cG9ydCBjb25zdCBCcm93c2VyRW52S2V5ID0gXCJFTlZcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVsaW1pdGVyIHVzZWQgZm9yIGNvbXBvc2luZyBuZXN0ZWQgZW52aXJvbm1lbnQgdmFyaWFibGUgbmFtZXMuXG4gKiBAc3VtbWFyeSBKb2lucyBwYXJlbnQgYW5kIGNoaWxkIGtleXMgd2hlbiBtYXBwaW5nIG9iamVjdCBwYXRocyB0byBFTlYgc3RyaW5ncy5cbiAqL1xuZXhwb3J0IGNvbnN0IEVOVl9QQVRIX0RFTElNSVRFUiA9IFwiX19cIjtcblxuZXhwb3J0IGNvbnN0IERlZmF1bHRQbGFjZWhvbGRlcldyYXBwZXJzID0gW1wiJHtcIiwgXCJ9XCJdO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFbnVtIGZvciBsb2cgbGV2ZWxzLlxuICogQHN1bW1hcnkgRGVmaW5lcyBkaWZmZXJlbnQgbGV2ZWxzIG9mIGxvZ2dpbmcgZm9yIHRoZSBhcHBsaWNhdGlvbi5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAcmVhZG9ubHlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZW51bSBMb2dMZXZlbCB7XG4gIC8qKiBFcnJvciBldmVudHMgdGhhdCBhcmUgbGlrZWx5IHRvIGNhdXNlIHByb2JsZW1zLiAqL1xuICBlcnJvciA9IFwiZXJyb3JcIixcbiAgLyoqIFJvdXRpbmUgaW5mb3JtYXRpb24sIHN1Y2ggYXMgb25nb2luZyBzdGF0dXMgb3IgcGVyZm9ybWFuY2UuICovXG4gIGluZm8gPSBcImluZm9cIixcbiAgLyoqIEFkZGl0aW9uYWwgcmVsZXZhbnQgaW5mb3JtYXRpb24uICovXG4gIHZlcmJvc2UgPSBcInZlcmJvc2VcIixcbiAgLyoqIERlYnVnIG9yIHRyYWNlIGluZm9ybWF0aW9uLiAqL1xuICBkZWJ1ZyA9IFwiZGVidWdcIixcbiAgLyoqIHdheSB0b28gdmVyYm9zZSBvciBzaWxseSBpbmZvcm1hdGlvbi4gKi9cbiAgc2lsbHkgPSBcInNpbGx5XCIsXG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE51bWVyaWMgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBsb2cgbGV2ZWxzLlxuICogQHN1bW1hcnkgUHJvdmlkZXMgYSBudW1lcmljIHJlcHJlc2VudGF0aW9uIG9mIGxvZyBsZXZlbHMgZm9yIGNvbXBhcmlzb24gYW5kIGZpbHRlcmluZy5cbiAqIEBjb25zdCBOdW1lcmljTG9nTGV2ZWxzXG4gKiBAcHJvcGVydHkge251bWJlcn0gZXJyb3IgLSBOdW1lcmljIHZhbHVlIGZvciBlcnJvciBsZXZlbCAoMikuXG4gKiBAcHJvcGVydHkge251bWJlcn0gaW5mbyAtIE51bWVyaWMgdmFsdWUgZm9yIGluZm8gbGV2ZWwgKDQpLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IHZlcmJvc2UgLSBOdW1lcmljIHZhbHVlIGZvciB2ZXJib3NlIGxldmVsICg2KS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBkZWJ1ZyAtIE51bWVyaWMgdmFsdWUgZm9yIGRlYnVnIGxldmVsICg3KS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBzaWxseSAtIE51bWVyaWMgdmFsdWUgZm9yIHNpbGx5IGxldmVsICg5KS5cbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3QgTnVtZXJpY0xvZ0xldmVscyA9IHtcbiAgZXJyb3I6IDIsXG4gIGluZm86IDQsXG4gIHZlcmJvc2U6IDYsXG4gIGRlYnVnOiA3LFxuICBzaWxseTogOSxcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVudW0gZm9yIGxvZ2dpbmcgb3V0cHV0IG1vZGVzLlxuICogQHN1bW1hcnkgRGVmaW5lcyBkaWZmZXJlbnQgb3V0cHV0IGZvcm1hdHMgZm9yIGxvZyBtZXNzYWdlcy5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGVudW0gTG9nZ2luZ01vZGUge1xuICAvKiogUmF3IHRleHQgZm9ybWF0IGZvciBodW1hbiByZWFkYWJpbGl0eSAqL1xuICBSQVcgPSBcInJhd1wiLFxuICAvKiogSlNPTiBmb3JtYXQgZm9yIG1hY2hpbmUgcGFyc2luZyAqL1xuICBKU09OID0gXCJqc29uXCIsXG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmF1bHQgdGhlbWUgZm9yIHN0eWxpbmcgbG9nIG91dHB1dC5cbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIGRlZmF1bHQgY29sb3IgYW5kIHN0eWxlIHNldHRpbmdzIGZvciB2YXJpb3VzIGNvbXBvbmVudHMgb2YgbG9nIG1lc3NhZ2VzLlxuICogQGNvbnN0IERlZmF1bHRUaGVtZVxuICogQHR5cGVkZWYge1RoZW1lfSBEZWZhdWx0VGhlbWVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBjbGFzcyAtIFN0eWxpbmcgZm9yIGNsYXNzIG5hbWVzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGNsYXNzLmZnIC0gRm9yZWdyb3VuZCBjb2xvciBjb2RlIGZvciBjbGFzcyBuYW1lcyAoMzQpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGlkIC0gU3R5bGluZyBmb3IgaWRlbnRpZmllcnMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gaWQuZmcgLSBGb3JlZ3JvdW5kIGNvbG9yIGNvZGUgZm9yIGlkZW50aWZpZXJzICgzNikuXG4gKiBAcHJvcGVydHkge09iamVjdH0gc3RhY2sgLSBTdHlsaW5nIGZvciBzdGFjayB0cmFjZXMgKGVtcHR5IG9iamVjdCkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gdGltZXN0YW1wIC0gU3R5bGluZyBmb3IgdGltZXN0YW1wcyAoZW1wdHkgb2JqZWN0KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBtZXNzYWdlIC0gU3R5bGluZyBmb3IgZGlmZmVyZW50IHR5cGVzIG9mIG1lc3NhZ2VzLlxuICogQHByb3BlcnR5IHtPYmplY3R9IG1lc3NhZ2UuZXJyb3IgLSBTdHlsaW5nIGZvciBlcnJvciBtZXNzYWdlcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtZXNzYWdlLmVycm9yLmZnIC0gRm9yZWdyb3VuZCBjb2xvciBjb2RlIGZvciBlcnJvciBtZXNzYWdlcyAoMzEpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IG1ldGhvZCAtIFN0eWxpbmcgZm9yIG1ldGhvZCBuYW1lcyAoZW1wdHkgb2JqZWN0KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2dMZXZlbCAtIFN0eWxpbmcgZm9yIGRpZmZlcmVudCBsb2cgbGV2ZWxzLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGxvZ0xldmVsLmVycm9yIC0gU3R5bGluZyBmb3IgZXJyb3IgbGV2ZWwgbG9ncy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsb2dMZXZlbC5lcnJvci5mZyAtIEZvcmVncm91bmQgY29sb3IgY29kZSBmb3IgZXJyb3IgbGV2ZWwgbG9ncyAoMzEpLlxuICogQHByb3BlcnR5IHtzdHJpbmdbXX0gbG9nTGV2ZWwuZXJyb3Iuc3R5bGUgLSBTdHlsZSBhdHRyaWJ1dGVzIGZvciBlcnJvciBsZXZlbCBsb2dzIChbXCJib2xkXCJdKS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2dMZXZlbC5pbmZvIC0gU3R5bGluZyBmb3IgaW5mbyBsZXZlbCBsb2dzIChlbXB0eSBvYmplY3QpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGxvZ0xldmVsLnZlcmJvc2UgLSBTdHlsaW5nIGZvciB2ZXJib3NlIGxldmVsIGxvZ3MgKGVtcHR5IG9iamVjdCkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nTGV2ZWwuZGVidWcgLSBTdHlsaW5nIGZvciBkZWJ1ZyBsZXZlbCBsb2dzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGxvZ0xldmVsLmRlYnVnLmZnIC0gRm9yZWdyb3VuZCBjb2xvciBjb2RlIGZvciBkZWJ1ZyBsZXZlbCBsb2dzICgzMykuXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGNvbnN0IERlZmF1bHRUaGVtZTogVGhlbWUgPSB7XG4gIGFwcDoge30sXG4gIHNlcGFyYXRvcjoge30sXG4gIGNsYXNzOiB7XG4gICAgZmc6IDM0LFxuICB9LFxuICBpZDoge1xuICAgIGZnOiAzNixcbiAgfSxcbiAgc3RhY2s6IHt9LFxuICB0aW1lc3RhbXA6IHt9LFxuICBtZXNzYWdlOiB7XG4gICAgZXJyb3I6IHtcbiAgICAgIGZnOiAzMSxcbiAgICB9LFxuICB9LFxuICBtZXRob2Q6IHt9LFxuICBsb2dMZXZlbDoge1xuICAgIGVycm9yOiB7XG4gICAgICBmZzogMzEsXG4gICAgICBzdHlsZTogW1wiYm9sZFwiXSxcbiAgICB9LFxuICAgIGluZm86IHtcbiAgICAgIGZnOiAzNCxcbiAgICAgIHN0eWxlOiBbXCJib2xkXCJdLFxuICAgIH0sXG4gICAgdmVyYm9zZToge1xuICAgICAgZmc6IDM0LFxuICAgICAgc3R5bGU6IFtcImJvbGRcIl0sXG4gICAgfSxcbiAgICBkZWJ1Zzoge1xuICAgICAgZmc6IDMzLFxuICAgICAgc3R5bGU6IFtcImJvbGRcIl0sXG4gICAgfSxcbiAgfSxcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmF1bHQgY29uZmlndXJhdGlvbiBmb3IgbG9nZ2luZy5cbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIGRlZmF1bHQgc2V0dGluZ3MgZm9yIHRoZSBsb2dnaW5nIHN5c3RlbSwgaW5jbHVkaW5nIHZlcmJvc2l0eSwgbG9nIGxldmVsLCBzdHlsaW5nLCBhbmQgdGltZXN0YW1wIGZvcm1hdC5cbiAqIEBjb25zdCBEZWZhdWx0TG9nZ2luZ0NvbmZpZ1xuICogQHR5cGVkZWYge0xvZ2dpbmdDb25maWd9IERlZmF1bHRMb2dnaW5nQ29uZmlnXG4gKiBAcHJvcGVydHkge251bWJlcn0gdmVyYm9zZSAtIFZlcmJvc2l0eSBsZXZlbCAoMCkuXG4gKiBAcHJvcGVydHkge0xvZ0xldmVsfSBsZXZlbCAtIERlZmF1bHQgbG9nIGxldmVsIChMb2dMZXZlbC5pbmZvKS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gbG9nTGV2ZWwgLSBXaGV0aGVyIHRvIGRpc3BsYXkgbG9nIGxldmVsIGluIG91dHB1dCAodHJ1ZSkuXG4gKiBAcHJvcGVydHkge0xvZ2dpbmdNb2RlfSBtb2RlIC0gT3V0cHV0IGZvcm1hdCBtb2RlIChMb2dnaW5nTW9kZS5SQVcpLlxuICogQHByb3BlcnR5IHtib29sZWFufSBzdHlsZSAtIFdoZXRoZXIgdG8gYXBwbHkgc3R5bGluZyB0byBsb2cgb3V0cHV0IChmYWxzZSkuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gc2VwYXJhdG9yIC0gU2VwYXJhdG9yIGJldHdlZW4gbG9nIGNvbXBvbmVudHMgKFwiIC0gXCIpLlxuICogQHByb3BlcnR5IHtib29sZWFufSB0aW1lc3RhbXAgLSBXaGV0aGVyIHRvIGluY2x1ZGUgdGltZXN0YW1wcyBpbiBsb2cgbWVzc2FnZXMgKHRydWUpLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHRpbWVzdGFtcEZvcm1hdCAtIEZvcm1hdCBmb3IgdGltZXN0YW1wcyAoXCJISDptbTpzcy5TU1NcIikuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGNvbnRleHQgLSBXaGV0aGVyIHRvIGluY2x1ZGUgY29udGV4dCBpbmZvcm1hdGlvbiBpbiBsb2cgbWVzc2FnZXMgKHRydWUpLlxuICogQHByb3BlcnR5IHtUaGVtZX0gdGhlbWUgLSBUaGUgdGhlbWUgdG8gdXNlIGZvciBzdHlsaW5nIGxvZyBtZXNzYWdlcyAoRGVmYXVsdFRoZW1lKS5cbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3QgRGVmYXVsdExvZ2dpbmdDb25maWc6IExvZ2dpbmdDb25maWcgPSB7XG4gIGVudjogXCJkZXZlbG9wbWVudFwiLFxuICB2ZXJib3NlOiAwLFxuICBsZXZlbDogTG9nTGV2ZWwuaW5mbyxcbiAgbG9nTGV2ZWw6IHRydWUsXG4gIHN0eWxlOiBmYWxzZSxcbiAgY29udGV4dFNlcGFyYXRvcjogXCIuXCIsXG4gIHNlcGFyYXRvcjogXCItXCIsXG4gIHRpbWVzdGFtcDogdHJ1ZSxcbiAgdGltZXN0YW1wRm9ybWF0OiBcIkhIOm1tOnNzLlNTU1wiLFxuICBjb250ZXh0OiB0cnVlLFxuICBmb3JtYXQ6IExvZ2dpbmdNb2RlLlJBVyxcbiAgcGF0dGVybjpcbiAgICBcIntsZXZlbH0gW3t0aW1lc3RhbXB9XSB7YXBwfSB7Y29udGV4dH0ge3NlcGFyYXRvcn0ge21lc3NhZ2V9IHtzdGFja31cIixcbiAgdGhlbWU6IERlZmF1bHRUaGVtZSxcbn07XG4iLCJpbXBvcnQgeyBEZWZhdWx0UGxhY2Vob2xkZXJXcmFwcGVycyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBQYWRzIHRoZSBlbmQgb2YgYSBzdHJpbmcgd2l0aCBhIHNwZWNpZmllZCBjaGFyYWN0ZXIuXG4gKiBAc3VtbWFyeSBFeHRlbmRzIHRoZSBpbnB1dCBzdHJpbmcgdG8gYSBzcGVjaWZpZWQgbGVuZ3RoIGJ5IGFkZGluZyBhIHBhZGRpbmcgY2hhcmFjdGVyIHRvIHRoZSBlbmQuXG4gKiBJZiB0aGUgaW5wdXQgc3RyaW5nIGlzIGFscmVhZHkgbG9uZ2VyIHRoYW4gdGhlIHNwZWNpZmllZCBsZW5ndGgsIGl0IGlzIHJldHVybmVkIHVuY2hhbmdlZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIC0gVGhlIGlucHV0IHN0cmluZyB0byBiZSBwYWRkZWQuXG4gKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIC0gVGhlIGRlc2lyZWQgdG90YWwgbGVuZ3RoIG9mIHRoZSByZXN1bHRpbmcgc3RyaW5nLlxuICogQHBhcmFtIHtzdHJpbmd9IFtjaGFyPVwiIFwiXSAtIFRoZSBjaGFyYWN0ZXIgdG8gdXNlIGZvciBwYWRkaW5nLiBEZWZhdWx0cyB0byBhIHNwYWNlLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgcGFkZGVkIHN0cmluZy5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGFkZGluZyBjaGFyYWN0ZXIgaXMgbm90IGV4YWN0bHkgb25lIGNoYXJhY3RlciBsb25nLlxuICpcbiAqIEBmdW5jdGlvbiBwYWRFbmRcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhZEVuZChcbiAgc3RyOiBzdHJpbmcsXG4gIGxlbmd0aDogbnVtYmVyLFxuICBjaGFyOiBzdHJpbmcgPSBcIiBcIlxuKTogc3RyaW5nIHtcbiAgaWYgKGNoYXIubGVuZ3RoICE9PSAxKVxuICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgY2hhcmFjdGVyIGxlbmd0aCBmb3IgcGFkZGluZy4gbXVzdCBiZSBvbmUhXCIpO1xuICByZXR1cm4gc3RyLnBhZEVuZChsZW5ndGgsIGNoYXIpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZXBsYWNlcyBwbGFjZWhvbGRlcnMgaW4gYSBzdHJpbmcgd2l0aCBwcm92aWRlZCB2YWx1ZXMuXG4gKiBAc3VtbWFyeSBJbnRlcnBvbGF0ZXMgYSBzdHJpbmcgYnkgcmVwbGFjaW5nIHBsYWNlaG9sZGVycyBvZiB0aGUgZm9ybSAke3ZhcmlhYmxlTmFtZX1cbiAqIHdpdGggY29ycmVzcG9uZGluZyB2YWx1ZXMgZnJvbSB0aGUgcHJvdmlkZWQgb2JqZWN0LiBJZiBhIHBsYWNlaG9sZGVyIGRvZXNuJ3QgaGF2ZVxuICogYSBjb3JyZXNwb25kaW5nIHZhbHVlLCBpdCBpcyBsZWZ0IHVuY2hhbmdlZCBpbiB0aGUgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dCAtIFRoZSBpbnB1dCBzdHJpbmcgY29udGFpbmluZyBwbGFjZWhvbGRlcnMgdG8gYmUgcmVwbGFjZWQuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz59IHZhbHVlcyAtIEFuIG9iamVjdCBjb250YWluaW5nIGtleS12YWx1ZSBwYWlycyBmb3IgcmVwbGFjZW1lbnQuXG4gKiBAcGFyYW0gcHJlZml4XG4gKiBAcGFyYW0gc3VmZml4XG4gKiBAcGFyYW0gZmxhZ3NcbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGludGVycG9sYXRlZCBzdHJpbmcgd2l0aCBwbGFjZWhvbGRlcnMgcmVwbGFjZWQgYnkgdGhlaXIgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gKlxuICogQGZ1bmN0aW9uIHBhdGNoUGxhY2Vob2xkZXJzXG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgcGF0Y2hTdHJpbmdcbiAqICAgcGFydGljaXBhbnQgU3RyaW5nLnJlcGxhY2VcbiAqICAgQ2FsbGVyLT4+cGF0Y2hTdHJpbmc6IENhbGwgd2l0aCBpbnB1dCBhbmQgdmFsdWVzXG4gKiAgIHBhdGNoU3RyaW5nLT4+U3RyaW5nLnJlcGxhY2U6IENhbGwgd2l0aCByZWdleCBhbmQgcmVwbGFjZW1lbnQgZnVuY3Rpb25cbiAqICAgU3RyaW5nLnJlcGxhY2UtPj5wYXRjaFN0cmluZzogUmV0dXJuIHJlcGxhY2VkIHN0cmluZ1xuICogICBwYXRjaFN0cmluZy0tPj5DYWxsZXI6IFJldHVybiBwYXRjaGVkIHN0cmluZ1xuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGF0Y2hQbGFjZWhvbGRlcnMoXG4gIGlucHV0OiBzdHJpbmcsXG4gIHZhbHVlczogUmVjb3JkPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPixcbiAgcHJlZml4OiBzdHJpbmcgPSBEZWZhdWx0UGxhY2Vob2xkZXJXcmFwcGVyc1swXSxcbiAgc3VmZml4OiBzdHJpbmcgPSBEZWZhdWx0UGxhY2Vob2xkZXJXcmFwcGVyc1sxXSxcbiAgZmxhZ3M6IHN0cmluZyA9IFwiZ1wiXG4pOiBzdHJpbmcge1xuICBjb25zdCBwbGFjZWhvbGRlcnMgPSBPYmplY3QuZW50cmllcyh2YWx1ZXMpLnJlZHVjZShcbiAgICAoYWNjOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBba2V5LCB2YWxdKSA9PiB7XG4gICAgICBhY2NbYCR7cHJlZml4fSR7a2V5fSR7c3VmZml4fWBdID0gdmFsO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LFxuICAgIHt9XG4gICk7XG4gIHJldHVybiBwYXRjaFN0cmluZyhpbnB1dCwgcGxhY2Vob2xkZXJzLCBmbGFncyk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFJlcGxhY2VzIG9jY3VycmVuY2VzIG9mIGtleXMgd2l0aCB0aGVpciBjb3JyZXNwb25kaW5nIHZhbHVlcyBpbiBhIHN0cmluZy5cbiAqIEBzdW1tYXJ5IEl0ZXJhdGVzIHRocm91Z2ggYSBzZXQgb2Yga2V5LXZhbHVlIHBhaXJzIGFuZCByZXBsYWNlcyBhbGwgb2NjdXJyZW5jZXMgb2YgZWFjaCBrZXlcbiAqIGluIHRoZSBpbnB1dCBzdHJpbmcgd2l0aCBpdHMgY29ycmVzcG9uZGluZyB2YWx1ZS4gU3VwcG9ydHMgcmVndWxhciBleHByZXNzaW9uIGZsYWdzIGZvciBjdXN0b21pemVkIHJlcGxhY2VtZW50LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dCAtIFRoZSBpbnB1dCBzdHJpbmcgaW4gd2hpY2ggcmVwbGFjZW1lbnRzIHdpbGwgYmUgbWFkZS5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPn0gdmFsdWVzIC0gQW4gb2JqZWN0IGNvbnRhaW5pbmcga2V5LXZhbHVlIHBhaXJzIGZvciByZXBsYWNlbWVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbZmxhZ3M9XCJnXCJdIC0gUmVndWxhciBleHByZXNzaW9uIGZsYWdzIHRvIGNvbnRyb2wgdGhlIHJlcGxhY2VtZW50IGJlaGF2aW9yLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgc3RyaW5nIHdpdGggYWxsIHNwZWNpZmllZCByZXBsYWNlbWVudHMgYXBwbGllZC5cbiAqXG4gKiBAZnVuY3Rpb24gcGF0Y2hTdHJpbmdcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhdGNoU3RyaW5nKFxuICBpbnB1dDogc3RyaW5nLFxuICB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz4sXG4gIGZsYWdzOiBzdHJpbmcgPSBcImdcIlxuKTogc3RyaW5nIHtcbiAgT2JqZWN0LmVudHJpZXModmFsdWVzKS5mb3JFYWNoKChba2V5LCB2YWxdKSA9PiB7XG4gICAgY29uc3QgcmVnZXhwID0gbmV3IFJlZ0V4cChlc2NhcGVSZWdFeHAoa2V5KSwgZmxhZ3MpO1xuICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZShyZWdleHAsIHZhbCBhcyBzdHJpbmcpO1xuICB9KTtcbiAgcmV0dXJuIGlucHV0O1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBhIHN0cmluZyB0byBjYW1lbENhc2UuXG4gKiBAc3VtbWFyeSBUcmFuc2Zvcm1zIHRoZSBpbnB1dCBzdHJpbmcgaW50byBjYW1lbENhc2UgZm9ybWF0LCB3aGVyZSB3b3JkcyBhcmUgam9pbmVkIHdpdGhvdXQgc3BhY2VzXG4gKiBhbmQgZWFjaCB3b3JkIGFmdGVyIHRoZSBmaXJzdCBzdGFydHMgd2l0aCBhIGNhcGl0YWwgbGV0dGVyLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGhlIGlucHV0IHN0cmluZyB0byBiZSBjb252ZXJ0ZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBpbnB1dCBzdHJpbmcgY29udmVydGVkIHRvIGNhbWVsQ2FzZS5cbiAqXG4gKiBAZnVuY3Rpb24gdG9DYW1lbENhc2VcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvQ2FtZWxDYXNlKHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB0ZXh0XG4gICAgLnJlcGxhY2UoLyg/Ol5cXHd8W0EtWl18XFxiXFx3KS9nLCAod29yZCwgaW5kZXgpID0+XG4gICAgICBpbmRleCA9PT0gMCA/IHdvcmQudG9Mb3dlckNhc2UoKSA6IHdvcmQudG9VcHBlckNhc2UoKVxuICAgIClcbiAgICAucmVwbGFjZSgvXFxzKy9nLCBcIlwiKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29udmVydHMgYSBzdHJpbmcgdG8gRU5WSVJPTk1FTlRfVkFSSUFCTEUgZm9ybWF0LlxuICogQHN1bW1hcnkgVHJhbnNmb3JtcyB0aGUgaW5wdXQgc3RyaW5nIGludG8gdXBwZXJjYXNlIHdpdGggd29yZHMgc2VwYXJhdGVkIGJ5IHVuZGVyc2NvcmVzLFxuICogdHlwaWNhbGx5IHVzZWQgZm9yIGVudmlyb25tZW50IHZhcmlhYmxlIG5hbWVzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGhlIGlucHV0IHN0cmluZyB0byBiZSBjb252ZXJ0ZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBpbnB1dCBzdHJpbmcgY29udmVydGVkIHRvIEVOVklST05NRU5UX1ZBUklBQkxFIGZvcm1hdC5cbiAqXG4gKiBAZnVuY3Rpb24gdG9FTlZGb3JtYXRcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvRU5WRm9ybWF0KHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB0b1NuYWtlQ2FzZSh0ZXh0KS50b1VwcGVyQ2FzZSgpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBhIHN0cmluZyB0byBzbmFrZV9jYXNlLlxuICogQHN1bW1hcnkgVHJhbnNmb3JtcyB0aGUgaW5wdXQgc3RyaW5nIGludG8gbG93ZXJjYXNlIHdpdGggd29yZHMgc2VwYXJhdGVkIGJ5IHVuZGVyc2NvcmVzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGhlIGlucHV0IHN0cmluZyB0byBiZSBjb252ZXJ0ZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBpbnB1dCBzdHJpbmcgY29udmVydGVkIHRvIHNuYWtlX2Nhc2UuXG4gKlxuICogQGZ1bmN0aW9uIHRvU25ha2VDYXNlXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b1NuYWtlQ2FzZSh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdGV4dFxuICAgIC5yZXBsYWNlKC8oW2Etel0pKFtBLVpdKS9nLCBcIiQxXyQyXCIpXG4gICAgLnJlcGxhY2UoL1tcXHMtXSsvZywgXCJfXCIpXG4gICAgLnRvTG93ZXJDYXNlKCk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvbnZlcnRzIGEgc3RyaW5nIHRvIGtlYmFiLWNhc2UuXG4gKiBAc3VtbWFyeSBUcmFuc2Zvcm1zIHRoZSBpbnB1dCBzdHJpbmcgaW50byBsb3dlcmNhc2Ugd2l0aCB3b3JkcyBzZXBhcmF0ZWQgYnkgaHlwaGVucy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSBpbnB1dCBzdHJpbmcgdG8gYmUgY29udmVydGVkLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgaW5wdXQgc3RyaW5nIGNvbnZlcnRlZCB0byBrZWJhYi1jYXNlLlxuICpcbiAqIEBmdW5jdGlvbiB0b0tlYmFiQ2FzZVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gdG9LZWJhYkNhc2UodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHRleHRcbiAgICAucmVwbGFjZSgvKFthLXpdKShbQS1aXSkvZywgXCIkMS0kMlwiKVxuICAgIC5yZXBsYWNlKC9bXFxzX10rL2csIFwiLVwiKVxuICAgIC50b0xvd2VyQ2FzZSgpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBhIHN0cmluZyB0byBQYXNjYWxDYXNlLlxuICogQHN1bW1hcnkgVHJhbnNmb3JtcyB0aGUgaW5wdXQgc3RyaW5nIGludG8gUGFzY2FsQ2FzZSBmb3JtYXQsIHdoZXJlIHdvcmRzIGFyZSBqb2luZWQgd2l0aG91dCBzcGFjZXNcbiAqIGFuZCBlYWNoIHdvcmQgc3RhcnRzIHdpdGggYSBjYXBpdGFsIGxldHRlci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSBpbnB1dCBzdHJpbmcgdG8gYmUgY29udmVydGVkLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgaW5wdXQgc3RyaW5nIGNvbnZlcnRlZCB0byBQYXNjYWxDYXNlLlxuICpcbiAqIEBmdW5jdGlvbiB0b1Bhc2NhbENhc2VcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvUGFzY2FsQ2FzZSh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdGV4dFxuICAgIC5yZXBsYWNlKC8oPzpeXFx3fFtBLVpdfFxcYlxcdykvZywgKHdvcmQpID0+IHdvcmQudG9VcHBlckNhc2UoKSlcbiAgICAucmVwbGFjZSgvXFxzKy9nLCBcIlwiKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRXNjYXBlcyBzcGVjaWFsIGNoYXJhY3RlcnMgaW4gYSBzdHJpbmcgZm9yIHVzZSBpbiBhIHJlZ3VsYXIgZXhwcmVzc2lvbi5cbiAqIEBzdW1tYXJ5IEFkZHMgYmFja3NsYXNoZXMgYmVmb3JlIGNoYXJhY3RlcnMgdGhhdCBoYXZlIHNwZWNpYWwgbWVhbmluZyBpbiByZWd1bGFyIGV4cHJlc3Npb25zLFxuICogYWxsb3dpbmcgdGhlIHN0cmluZyB0byBiZSB1c2VkIGFzIGEgbGl0ZXJhbCBtYXRjaCBpbiBhIFJlZ0V4cC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIC0gVGhlIHN0cmluZyB0byBlc2NhcGUgZm9yIHJlZ3VsYXIgZXhwcmVzc2lvbiB1c2UuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBlc2NhcGVkIHN0cmluZyBzYWZlIGZvciB1c2UgaW4gcmVndWxhciBleHByZXNzaW9ucy5cbiAqXG4gKiBAZnVuY3Rpb24gZXNjYXBlUmVnRXhwXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGVSZWdFeHAoc3RyaW5nOiBzdHJpbmcpIHtcbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC9bLiorP14ke30oKXxbXFxdXFxcXF0vZywgXCJcXFxcJCZcIik7IC8vICQmIG1lYW5zIHRoZSB3aG9sZSBtYXRjaGVkIHN0cmluZ1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFV0aWwgZnVuY3Rpb24gdG8gcHJvdmlkZSBzdHJpbmcgZm9ybWF0IGZ1bmN0aW9uYWxpdHkgc2ltaWxhciB0byBDIydzIHN0cmluZy5mb3JtYXRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZyB8IG51bWJlcj4gfCBSZWNvcmQ8c3RyaW5nLCBhbnk+fSBbYXJnc10gcmVwbGFjZW1lbnRzIG1hZGUgYnkgb3JkZXIgb2YgYXBwZWFyYW5jZSAocmVwbGFjZW1lbnQwIHdpbCByZXBsYWNlIHswfSBhbmQgc28gb24pXG4gKiBAcmV0dXJuIHtzdHJpbmd9IGZvcm1hdHRlZCBzdHJpbmdcbiAqXG4gKiBAZnVuY3Rpb24gc2ZcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gc2YoXG4gIHN0cmluZzogc3RyaW5nLFxuICAuLi5hcmdzOiAoc3RyaW5nIHwgbnVtYmVyIHwgUmVjb3JkPHN0cmluZywgYW55PilbXVxuKSB7XG4gIGlmIChhcmdzLmxlbmd0aCA+IDEpIHtcbiAgICBpZiAoXG4gICAgICAhYXJncy5ldmVyeSgoYXJnKSA9PiB0eXBlb2YgYXJnID09PSBcInN0cmluZ1wiIHx8IHR5cGVvZiBhcmcgPT09IFwibnVtYmVyXCIpXG4gICAgKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgT25seSBzdHJpbmcgYW5kIG51bWJlciBhcmd1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgbXVsdGlwbGUgcmVwbGFjZW1lbnRzLmBcbiAgICAgICk7XG4gIH1cblxuICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGFyZ3NbMF0gPT09IFwib2JqZWN0XCIpIHtcbiAgICBjb25zdCBvYmogPSBhcmdzWzBdIGFzIFJlY29yZDxzdHJpbmcsIGFueT47XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKG9iaikucmVkdWNlKChhY2MsIFtrZXksIHZhbF0pID0+IHtcbiAgICAgIHJldHVybiBhY2MucmVwbGFjZShuZXcgUmVnRXhwKGBcXFxceyR7a2V5fVxcXFx9YCwgXCJnXCIpLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgICB9KTtcbiAgICB9LCBzdHJpbmcpO1xuICB9XG5cbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC97KFxcZCspfS9nLCBmdW5jdGlvbiAobWF0Y2gsIG51bWJlcikge1xuICAgIHJldHVybiB0eXBlb2YgYXJnc1tudW1iZXJdICE9PSBcInVuZGVmaW5lZFwiXG4gICAgICA/IGFyZ3NbbnVtYmVyXS50b1N0cmluZygpXG4gICAgICA6IFwidW5kZWZpbmVkXCI7XG4gIH0pO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFV0aWwgZnVuY3Rpb24gdG8gcHJvdmlkZSBzdHJpbmcgZm9ybWF0IGZ1bmN0aW9uYWxpdHkgc2ltaWxhciB0byBDIydzIHN0cmluZy5mb3JtYXRcbiAqXG4gKiBAc2VlIHNmXG4gKlxuICogQGRlcHJlY2F0ZWRcbiAqIEBmdW5jdGlvbiBzdHJpbmdGb3JtYXRcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3Qgc3RyaW5nRm9ybWF0ID0gc2Y7XG4iLCIvKipcbiAqIEBkZXNjcmlwdGlvbiBEZXRlcm1pbmVzIGlmIHRoZSBjdXJyZW50IGVudmlyb25tZW50IGlzIGEgYnJvd3NlciBieSBjaGVja2luZyB0aGUgcHJvdG90eXBlIGNoYWluIG9mIHRoZSBnbG9iYWwgb2JqZWN0LlxuICogQHN1bW1hcnkgQ2hlY2tzIGlmIHRoZSBjb2RlIGlzIHJ1bm5pbmcgaW4gYSBicm93c2VyIGVudmlyb25tZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZW52aXJvbm1lbnQgaXMgYSBicm93c2VyLCBmYWxzZSBvdGhlcndpc2UuXG4gKiBAZnVuY3Rpb24gaXNCcm93c2VyXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQnJvd3NlcigpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBPYmplY3QuZ2V0UHJvdG90eXBlT2YoT2JqZWN0LmdldFByb3RvdHlwZU9mKGdsb2JhbFRoaXMpKSAhPT1cbiAgICBPYmplY3QucHJvdG90eXBlXG4gICk7XG59XG4iLCJpbXBvcnQgeyBPYmplY3RBY2N1bXVsYXRvciB9IGZyb20gXCJ0eXBlZC1vYmplY3QtYWNjdW11bGF0b3JcIjtcbmltcG9ydCB7IHRvRU5WRm9ybWF0IH0gZnJvbSBcIi4vdGV4dFwiO1xuaW1wb3J0IHsgaXNCcm93c2VyIH0gZnJvbSBcIi4vd2ViXCI7XG5pbXBvcnQge1xuICBCcm93c2VyRW52S2V5LFxuICBEZWZhdWx0TG9nZ2luZ0NvbmZpZyxcbiAgRU5WX1BBVEhfREVMSU1JVEVSLFxufSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRmFjdG9yeSB0eXBlIGZvciBjcmVhdGluZyBFbnZpcm9ubWVudCBpbnN0YW5jZXMuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgZnVuY3Rpb24gdHlwZSB0aGF0IGNyZWF0ZXMgYW5kIHJldHVybnMgRW52aXJvbm1lbnQgaW5zdGFuY2VzLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIC0gVGhlIHR5cGUgb2Ygb2JqZWN0IHRoZSBFbnZpcm9ubWVudCB3aWxsIGFjY3VtdWxhdGUuXG4gKiBAdGVtcGxhdGUgRSAtIFRoZSBzcGVjaWZpYyBFbnZpcm9ubWVudCB0eXBlIHRvIGJlIGNyZWF0ZWQsIGV4dGVuZGluZyBFbnZpcm9ubWVudDxUPi5cbiAqIEB0eXBlZGVmIHtmdW5jdGlvbiguLi51bmtub3duW10pOiBFfSBFbnZpcm9ubWVudEZhY3RvcnlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgdHlwZSBFbnZpcm9ubWVudEZhY3Rvcnk8VCBleHRlbmRzIG9iamVjdCwgRSBleHRlbmRzIEVudmlyb25tZW50PFQ+PiA9IChcbiAgLi4uYXJnczogdW5rbm93bltdXG4pID0+IEU7XG5cbi8qKlxuICogQGNsYXNzIEVudmlyb25tZW50XG4gKiBAZXh0ZW5kcyB7T2JqZWN0QWNjdW11bGF0b3I8VD59XG4gKiBAdGVtcGxhdGUgVFxuICogQGRlc2NyaXB0aW9uIEEgY2xhc3MgcmVwcmVzZW50aW5nIGFuIGVudmlyb25tZW50IHdpdGggYWNjdW11bGF0aW9uIGNhcGFiaWxpdGllcy5cbiAqIEBzdW1tYXJ5IE1hbmFnZXMgZW52aXJvbm1lbnQtcmVsYXRlZCBkYXRhIGFuZCBwcm92aWRlcyBtZXRob2RzIGZvciBhY2N1bXVsYXRpb24gYW5kIGtleSByZXRyaWV2YWwuXG4gKiBAcGFyYW0ge1R9IFtpbml0aWFsRGF0YV0gLSBUaGUgaW5pdGlhbCBkYXRhIHRvIHBvcHVsYXRlIHRoZSBlbnZpcm9ubWVudCB3aXRoLlxuICovXG5leHBvcnQgY2xhc3MgRW52aXJvbm1lbnQ8VCBleHRlbmRzIG9iamVjdD4gZXh0ZW5kcyBPYmplY3RBY2N1bXVsYXRvcjxUPiB7XG4gIC8qKlxuICAgKiBAc3RhdGljXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQGRlc2NyaXB0aW9uIEEgZmFjdG9yeSBmdW5jdGlvbiBmb3IgY3JlYXRpbmcgRW52aXJvbm1lbnQgaW5zdGFuY2VzLlxuICAgKiBAc3VtbWFyeSBEZWZpbmVzIGhvdyBuZXcgaW5zdGFuY2VzIG9mIHRoZSBFbnZpcm9ubWVudCBjbGFzcyBzaG91bGQgYmUgY3JlYXRlZC5cbiAgICogQHJldHVybiB7RW52aXJvbm1lbnQ8YW55Pn0gQSBuZXcgaW5zdGFuY2Ugb2YgdGhlIEVudmlyb25tZW50IGNsYXNzLlxuICAgKi9cbiAgcHJvdGVjdGVkIHN0YXRpYyBmYWN0b3J5OiBFbnZpcm9ubWVudEZhY3Rvcnk8YW55LCBhbnk+ID1cbiAgICAoKTogRW52aXJvbm1lbnQ8YW55PiA9PiBuZXcgRW52aXJvbm1lbnQoKTtcblxuICAvKipcbiAgICogQHN0YXRpY1xuICAgKiBAcHJpdmF0ZVxuICAgKiBAZGVzY3JpcHRpb24gVGhlIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiB0aGUgRW52aXJvbm1lbnQgY2xhc3MuXG4gICAqIEB0eXBlIHtFbnZpcm9ubWVudDxhbnk+fVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgX2luc3RhbmNlOiBFbnZpcm9ubWVudDxhbnk+O1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYSB2YWx1ZSBmcm9tIHRoZSBlbnZpcm9ubWVudFxuICAgKiBAc3VtbWFyeSBHZXRzIGEgdmFsdWUgZnJvbSB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGVzLCBoYW5kbGluZyBicm93c2VyIGFuZCBOb2RlLmpzIGVudmlyb25tZW50cyBkaWZmZXJlbnRseVxuICAgKiBAcGFyYW0ge3N0cmluZ30gayAtIFRoZSBrZXkgdG8gcmV0cmlldmUgZnJvbSB0aGUgZW52aXJvbm1lbnRcbiAgICogQHJldHVybiB7dW5rbm93bn0gVGhlIHZhbHVlIGZyb20gdGhlIGVudmlyb25tZW50LCBvciB1bmRlZmluZWQgaWYgbm90IGZvdW5kXG4gICAqL1xuICBwcm90ZWN0ZWQgZnJvbUVudihrOiBzdHJpbmcpIHtcbiAgICBsZXQgZW52OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICBpZiAoaXNCcm93c2VyKCkpIHtcbiAgICAgIGVudiA9XG4gICAgICAgIChcbiAgICAgICAgICBnbG9iYWxUaGlzIGFzIHR5cGVvZiBnbG9iYWxUaGlzICYge1xuICAgICAgICAgICAgW0Jyb3dzZXJFbnZLZXldOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgICAgICAgIH1cbiAgICAgICAgKVtCcm93c2VyRW52S2V5XSB8fCB7fTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW52ID0gZ2xvYmFsVGhpcy5wcm9jZXNzLmVudjtcbiAgICAgIGsgPSB0b0VOVkZvcm1hdChrKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucGFyc2VFbnZWYWx1ZShlbnZba10pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlRW52VmFsdWUodmFsOiB1bmtub3duKSB7XG4gICAgaWYgKHR5cGVvZiB2YWwgIT09IFwic3RyaW5nXCIpIHJldHVybiB2YWw7XG4gICAgaWYgKHZhbCA9PT0gXCJ0cnVlXCIpIHJldHVybiB0cnVlO1xuICAgIGlmICh2YWwgPT09IFwiZmFsc2VcIikgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IHJlc3VsdCA9IHBhcnNlRmxvYXQodmFsKTtcbiAgICBpZiAoIWlzTmFOKHJlc3VsdCkpIHJldHVybiByZXN1bHQ7XG4gICAgcmV0dXJuIHZhbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRXhwYW5kcyBhbiBvYmplY3QgaW50byB0aGUgZW52aXJvbm1lbnRcbiAgICogQHN1bW1hcnkgRGVmaW5lcyBwcm9wZXJ0aWVzIG9uIHRoZSBlbnZpcm9ubWVudCBvYmplY3QgdGhhdCBjYW4gYmUgYWNjZXNzZWQgYXMgZ2V0dGVycyBhbmQgc2V0dGVyc1xuICAgKiBAdGVtcGxhdGUgViAtIFR5cGUgb2YgdGhlIG9iamVjdCBiZWluZyBleHBhbmRlZFxuICAgKiBAcGFyYW0ge1Z9IHZhbHVlIC0gVGhlIG9iamVjdCB0byBleHBhbmQgaW50byB0aGUgZW52aXJvbm1lbnRcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHByb3RlY3RlZCBvdmVycmlkZSBleHBhbmQ8ViBleHRlbmRzIG9iamVjdD4odmFsdWU6IFYpOiB2b2lkIHtcbiAgICBPYmplY3QuZW50cmllcyh2YWx1ZSkuZm9yRWFjaCgoW2ssIHZdKSA9PiB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgaywge1xuICAgICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgICBjb25zdCBmcm9tRW52ID0gdGhpcy5mcm9tRW52KGspO1xuICAgICAgICAgIGlmICh0eXBlb2YgZnJvbUVudiAhPT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIGZyb21FbnY7XG4gICAgICAgICAgaWYgKHYgJiYgdHlwZW9mIHYgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIHJldHVybiBFbnZpcm9ubWVudC5idWlsZEVudlByb3h5KHYgYXMgYW55LCBba10pO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBJZiB0aGUgbW9kZWwgcHJvdmlkZXMgYW4gZW1wdHkgc3RyaW5nLCBleHBvc2UgYSBwcm94eSB0aGF0IGNvbXBvc2VzIEVOViBrZXlzXG4gICAgICAgICAgaWYgKHYgPT09IFwiXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBFbnZpcm9ubWVudC5idWlsZEVudlByb3h5KHVuZGVmaW5lZCwgW2tdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHY7XG4gICAgICAgIH0sXG4gICAgICAgIHNldDogKHZhbDogVltrZXlvZiBWXSkgPT4ge1xuICAgICAgICAgIHYgPSB2YWw7XG4gICAgICAgIH0sXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHN0YXRpY1xuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIG9yIGNyZWF0ZXMgdGhlIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiB0aGUgRW52aXJvbm1lbnQgY2xhc3MuXG4gICAqIEBzdW1tYXJ5IEVuc3VyZXMgb25seSBvbmUgaW5zdGFuY2Ugb2YgdGhlIEVudmlyb25tZW50IGNsYXNzIGV4aXN0cy5cbiAgICogQHRlbXBsYXRlIEVcbiAgICogQHBhcmFtIHsuLi51bmtub3duW119IGFyZ3MgLSBBcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgZmFjdG9yeSBmdW5jdGlvbiBpZiBhIG5ldyBpbnN0YW5jZSBpcyBjcmVhdGVkLlxuICAgKiBAcmV0dXJuIHtFfSBUaGUgc2luZ2xldG9uIGluc3RhbmNlIG9mIHRoZSBFbnZpcm9ubWVudCBjbGFzcy5cbiAgICovXG4gIHByb3RlY3RlZCBzdGF0aWMgaW5zdGFuY2U8RSBleHRlbmRzIEVudmlyb25tZW50PGFueT4+KC4uLmFyZ3M6IHVua25vd25bXSk6IEUge1xuICAgIGlmICghRW52aXJvbm1lbnQuX2luc3RhbmNlKSB7XG4gICAgICBjb25zdCBiYXNlID0gRW52aXJvbm1lbnQuZmFjdG9yeSguLi5hcmdzKSBhcyBFO1xuICAgICAgY29uc3QgcHJveGllZCA9IG5ldyBQcm94eShiYXNlIGFzIGFueSwge1xuICAgICAgICBnZXQodGFyZ2V0LCBwcm9wLCByZWNlaXZlcikge1xuICAgICAgICAgIGNvbnN0IHZhbHVlID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBwcm9wLCByZWNlaXZlcik7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgIGlmICh0eXBlb2YgcHJvcCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgLy8gQXZvaWQgaW50ZXJmZXJpbmcgd2l0aCBsb2dnaW5nIGNvbmZpZyBsb29rdXBzIGZvciBvcHRpb25hbCBmaWVsZHMgbGlrZSAnYXBwJ1xuICAgICAgICAgICAgaWYgKHByb3AgPT09IFwiYXBwXCIpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICByZXR1cm4gRW52aXJvbm1lbnQuYnVpbGRFbnZQcm94eSh1bmRlZmluZWQsIFtwcm9wXSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgRW52aXJvbm1lbnQuX2luc3RhbmNlID0gcHJveGllZCBhcyBhbnk7XG4gICAgfVxuICAgIHJldHVybiBFbnZpcm9ubWVudC5faW5zdGFuY2UgYXMgRTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3RhdGljXG4gICAqIEBkZXNjcmlwdGlvbiBBY2N1bXVsYXRlcyB0aGUgZ2l2ZW4gdmFsdWUgaW50byB0aGUgZW52aXJvbm1lbnQuXG4gICAqIEBzdW1tYXJ5IEFkZHMgbmV3IHByb3BlcnRpZXMgdG8gdGhlIGVudmlyb25tZW50IGZyb20gdGhlIHByb3ZpZGVkIG9iamVjdC5cbiAgICogQHRlbXBsYXRlIFZcbiAgICogQHBhcmFtIHtWfSB2YWx1ZSAtIFRoZSBvYmplY3QgdG8gYWNjdW11bGF0ZSBpbnRvIHRoZSBlbnZpcm9ubWVudC5cbiAgICogQHJldHVybiB7Vn0gVGhlIHVwZGF0ZWQgZW52aXJvbm1lbnQgaW5zdGFuY2UuXG4gICAqL1xuICBzdGF0aWMgYWNjdW11bGF0ZTxWIGV4dGVuZHMgb2JqZWN0PihcbiAgICB2YWx1ZTogVlxuICApOiB0eXBlb2YgRW52aXJvbm1lbnQuX2luc3RhbmNlICZcbiAgICBWICZcbiAgICBPYmplY3RBY2N1bXVsYXRvcjx0eXBlb2YgRW52aXJvbm1lbnQuX2luc3RhbmNlICYgVj4ge1xuICAgIGNvbnN0IGluc3RhbmNlID0gRW52aXJvbm1lbnQuaW5zdGFuY2UoKTtcbiAgICBPYmplY3Qua2V5cyhpbnN0YW5jZSBhcyBhbnkpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgY29uc3QgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoaW5zdGFuY2UgYXMgYW55LCBrZXkpO1xuICAgICAgaWYgKGRlc2MgJiYgZGVzYy5jb25maWd1cmFibGUgJiYgZGVzYy5lbnVtZXJhYmxlKSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShpbnN0YW5jZSBhcyBhbnksIGtleSwge1xuICAgICAgICAgIC4uLmRlc2MsXG4gICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBpbnN0YW5jZS5hY2N1bXVsYXRlKHZhbHVlKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQoa2V5OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gRW52aXJvbm1lbnQuX2luc3RhbmNlLmdldChrZXkpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgYnVpbGRFbnZQcm94eShjdXJyZW50OiBhbnksIHBhdGg6IHN0cmluZ1tdKTogYW55IHtcbiAgICBjb25zdCBidWlsZEtleSA9IChwOiBzdHJpbmdbXSkgPT5cbiAgICAgIHAubWFwKChzZWcpID0+IHRvRU5WRm9ybWF0KHNlZykpLmpvaW4oRU5WX1BBVEhfREVMSU1JVEVSKTtcblxuICAgIC8vIEhlbHBlciB0byByZWFkIGZyb20gdGhlIGFjdGl2ZSBlbnZpcm9ubWVudCBnaXZlbiBhIGNvbXBvc2VkIGtleVxuICAgIGNvbnN0IHJlYWRFbnYgPSAoa2V5OiBzdHJpbmcpOiB1bmtub3duID0+IHtcbiAgICAgIGlmIChpc0Jyb3dzZXIoKSkge1xuICAgICAgICBjb25zdCBlbnYgPSAoXG4gICAgICAgICAgZ2xvYmFsVGhpcyBhcyB0eXBlb2YgZ2xvYmFsVGhpcyAmIHtcbiAgICAgICAgICAgIFtCcm93c2VyRW52S2V5XT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgICAgIH1cbiAgICAgICAgKVtCcm93c2VyRW52S2V5XTtcbiAgICAgICAgcmV0dXJuIGVudiA/IGVudltrZXldIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIChnbG9iYWxUaGlzIGFzIGFueSk/LnByb2Nlc3M/LmVudj8uW2tleV07XG4gICAgfTtcblxuICAgIGNvbnN0IGhhbmRsZXI6IFByb3h5SGFuZGxlcjxhbnk+ID0ge1xuICAgICAgZ2V0KF90YXJnZXQsIHByb3A6IHN0cmluZyB8IHN5bWJvbCkge1xuICAgICAgICBpZiAocHJvcCA9PT0gU3ltYm9sLnRvUHJpbWl0aXZlKSB7XG4gICAgICAgICAgcmV0dXJuICgpID0+IGJ1aWxkS2V5KHBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wID09PSBcInRvU3RyaW5nXCIpIHtcbiAgICAgICAgICByZXR1cm4gKCkgPT4gYnVpbGRLZXkocGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3AgPT09IFwidmFsdWVPZlwiKSB7XG4gICAgICAgICAgcmV0dXJuICgpID0+IGJ1aWxkS2V5KHBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcHJvcCA9PT0gXCJzeW1ib2xcIikgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgICAgICBjb25zdCBuZXh0TW9kZWwgPVxuICAgICAgICAgIGN1cnJlbnQgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGN1cnJlbnQsIHByb3ApXG4gICAgICAgICAgICA/IChjdXJyZW50IGFzIGFueSlbcHJvcF1cbiAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBuZXh0UGF0aCA9IFsuLi5wYXRoLCBwcm9wXTtcbiAgICAgICAgY29uc3QgY29tcG9zZWRLZXkgPSBidWlsZEtleShuZXh0UGF0aCk7XG5cbiAgICAgICAgLy8gSWYgYW4gRU5WIHZhbHVlIGV4aXN0cyBmb3IgdGhpcyBwYXRoLCByZXR1cm4gaXQgZGlyZWN0bHlcbiAgICAgICAgY29uc3QgZW52VmFsdWUgPSByZWFkRW52KGNvbXBvc2VkS2V5KTtcbiAgICAgICAgaWYgKHR5cGVvZiBlbnZWYWx1ZSAhPT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIGVudlZhbHVlO1xuXG4gICAgICAgIC8vIE90aGVyd2lzZSwgaWYgdGhlIG1vZGVsIGhhcyBhbiBvYmplY3QgYXQgdGhpcyBwYXRoLCBrZWVwIGRyaWxsaW5nIHdpdGggYSBwcm94eVxuICAgICAgICBjb25zdCBpc05leHRPYmplY3QgPSBuZXh0TW9kZWwgJiYgdHlwZW9mIG5leHRNb2RlbCA9PT0gXCJvYmplY3RcIjtcbiAgICAgICAgaWYgKGlzTmV4dE9iamVjdCkgcmV0dXJuIEVudmlyb25tZW50LmJ1aWxkRW52UHJveHkobmV4dE1vZGVsLCBuZXh0UGF0aCk7XG5cbiAgICAgICAgLy8gQWx3YXlzIHJldHVybiBhIHByb3h5IGZvciBmdXJ0aGVyIHBhdGggY29tcG9zaXRpb24gd2hlbiBubyBFTlYgdmFsdWU7XG4gICAgICAgIC8vIGRvIG5vdCBzdXJmYWNlIHByaW1pdGl2ZSBtb2RlbCBkZWZhdWx0cyBoZXJlICh0aGlzIEFQSSBpcyBmb3Iga2V5IGNvbXBvc2l0aW9uKS5cbiAgICAgICAgcmV0dXJuIEVudmlyb25tZW50LmJ1aWxkRW52UHJveHkodW5kZWZpbmVkLCBuZXh0UGF0aCk7XG4gICAgICB9LFxuICAgICAgb3duS2V5cygpIHtcbiAgICAgICAgcmV0dXJuIGN1cnJlbnQgPyBSZWZsZWN0Lm93bktleXMoY3VycmVudCkgOiBbXTtcbiAgICAgIH0sXG4gICAgICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX3QsIHApIHtcbiAgICAgICAgaWYgKCFjdXJyZW50KSByZXR1cm4gdW5kZWZpbmVkIGFzIGFueTtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChjdXJyZW50LCBwKSkge1xuICAgICAgICAgIHJldHVybiB7IGVudW1lcmFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IGFzIFByb3BlcnR5RGVzY3JpcHRvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkIGFzIGFueTtcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIGNvbnN0IHRhcmdldCA9IHt9IGFzIGFueTtcbiAgICByZXR1cm4gbmV3IFByb3h5KHRhcmdldCwgaGFuZGxlcik7XG4gIH1cblxuICAvKipcbiAgICogQHN0YXRpY1xuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIHRoZSBrZXlzIG9mIHRoZSBlbnZpcm9ubWVudCwgb3B0aW9uYWxseSBjb252ZXJ0aW5nIHRoZW0gdG8gRU5WIGZvcm1hdC5cbiAgICogQHN1bW1hcnkgR2V0cyBhbGwga2V5cyBpbiB0aGUgZW52aXJvbm1lbnQsIHdpdGggYW4gb3B0aW9uIHRvIGZvcm1hdCB0aGVtIGZvciBlbnZpcm9ubWVudCB2YXJpYWJsZXMuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3RvRW52PXRydWVdIC0gV2hldGhlciB0byBjb252ZXJ0IHRoZSBrZXlzIHRvIEVOViBmb3JtYXQuXG4gICAqIEByZXR1cm4ge3N0cmluZ1tdfSBBbiBhcnJheSBvZiBrZXlzIGZyb20gdGhlIGVudmlyb25tZW50LlxuICAgKi9cbiAgc3RhdGljIGtleXModG9FbnY6IGJvb2xlYW4gPSB0cnVlKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBFbnZpcm9ubWVudC5pbnN0YW5jZSgpXG4gICAgICAua2V5cygpXG4gICAgICAubWFwKChrKSA9PiAodG9FbnYgPyB0b0VOVkZvcm1hdChrKSA6IGspKTtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgTG9nZ2VkRW52aXJvbm1lbnQgPSBFbnZpcm9ubWVudC5hY2N1bXVsYXRlKFxuICBPYmplY3QuYXNzaWduKHt9LCBEZWZhdWx0TG9nZ2luZ0NvbmZpZywge1xuICAgIGVudjpcbiAgICAgIChpc0Jyb3dzZXIoKSAmJiAoZ2xvYmFsVGhpcyBhcyBhbnkpW0Jyb3dzZXJFbnZLZXldXG4gICAgICAgID8gKGdsb2JhbFRoaXMgYXMgYW55KVtCcm93c2VyRW52S2V5XVtcIk5PREVfRU5WXCJdXG4gICAgICAgIDogKGdsb2JhbFRoaXMgYXMgYW55KS5wcm9jZXNzLmVudltcIk5PREVfRU5WXCJdKSB8fCBcImRldmVsb3BtZW50XCIsXG4gIH0pXG4pO1xuIiwiaW1wb3J0IHtcbiAgTG9nZ2VyRmFjdG9yeSxcbiAgTG9nZ2luZ0NvbmZpZyxcbiAgTG9nZ2luZ0NvbnRleHQsXG4gIFN0cmluZ0xpa2UsXG4gIFRoZW1lLFxuICBUaGVtZU9wdGlvbixcbiAgVGhlbWVPcHRpb25CeUxvZ0xldmVsLFxuICBMb2dnZXIsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBDb2xvcml6ZU9wdGlvbnMsIHN0eWxlLCBTdHlsZWRTdHJpbmcgfSBmcm9tIFwic3R5bGVkLXN0cmluZy1idWlsZGVyXCI7XG5pbXBvcnQgeyBEZWZhdWx0VGhlbWUsIExvZ0xldmVsLCBOdW1lcmljTG9nTGV2ZWxzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBzZiB9IGZyb20gXCIuL3RleHRcIjtcbmltcG9ydCB7IExvZ2dlZEVudmlyb25tZW50IH0gZnJvbSBcIi4vZW52aXJvbm1lbnRcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQSBtaW5pbWFsIGxvZ2dlciBpbXBsZW1lbnRhdGlvbi5cbiAqIEBzdW1tYXJ5IE1pbmlMb2dnZXIgaXMgYSBsaWdodHdlaWdodCBsb2dnaW5nIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGUgTG9nZ2VyIGludGVyZmFjZS5cbiAqIEl0IHByb3ZpZGVzIGJhc2ljIGxvZ2dpbmcgZnVuY3Rpb25hbGl0eSB3aXRoIHN1cHBvcnQgZm9yIGRpZmZlcmVudCBsb2cgbGV2ZWxzLCB2ZXJib3NpdHksXG4gKiBjb250ZXh0LWF3YXJlIGxvZ2dpbmcsIGFuZCBjdXN0b21pemFibGUgZm9ybWF0dGluZy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZXh0IC0gVGhlIGNvbnRleHQgKHR5cGljYWxseSBjbGFzcyBuYW1lKSB0aGlzIGxvZ2dlciBpcyBhc3NvY2lhdGVkIHdpdGhcbiAqIEBwYXJhbSB7UGFydGlhbDxMb2dnaW5nQ29uZmlnPn0gY29uZiAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gdG8gb3ZlcnJpZGUgZ2xvYmFsIHNldHRpbmdzXG4gKiBAY2xhc3MgTWluaUxvZ2dlclxuICogQGV4YW1wbGVcbiAqIC8vIENyZWF0ZSBhIG5ldyBsb2dnZXIgZm9yIGEgY2xhc3NcbiAqIGNvbnN0IGxvZ2dlciA9IG5ldyBNaW5pTG9nZ2VyKCdNeUNsYXNzJyk7XG4gKlxuICogLy8gTG9nIG1lc3NhZ2VzIGF0IGRpZmZlcmVudCBsZXZlbHNcbiAqIGxvZ2dlci5pbmZvKCdUaGlzIGlzIGFuIGluZm8gbWVzc2FnZScpO1xuICogbG9nZ2VyLmRlYnVnKCdUaGlzIGlzIGEgZGVidWcgbWVzc2FnZScpO1xuICogbG9nZ2VyLmVycm9yKCdTb21ldGhpbmcgd2VudCB3cm9uZycpO1xuICpcbiAqIC8vIENyZWF0ZSBhIGNoaWxkIGxvZ2dlciBmb3IgYSBzcGVjaWZpYyBtZXRob2RcbiAqIGNvbnN0IG1ldGhvZExvZ2dlciA9IGxvZ2dlci5mb3IoJ215TWV0aG9kJyk7XG4gKiBtZXRob2RMb2dnZXIudmVyYm9zZSgnRGV0YWlsZWQgaW5mb3JtYXRpb24nLCAyKTtcbiAqXG4gKiAvLyBMb2cgd2l0aCBjdXN0b20gY29uZmlndXJhdGlvblxuICogbG9nZ2VyLmZvcignc3BlY2lhbE1ldGhvZCcsIHsgc3R5bGU6IHRydWUgfSkuaW5mbygnU3R5bGVkIG1lc3NhZ2UnKTtcbiAqL1xuZXhwb3J0IGNsYXNzIE1pbmlMb2dnZXIgaW1wbGVtZW50cyBMb2dnZXIge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgY29udGV4dDogc3RyaW5nLFxuICAgIHByb3RlY3RlZCBjb25mPzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPlxuICApIHt9XG5cbiAgcHJvdGVjdGVkIGNvbmZpZyhcbiAgICBrZXk6IGtleW9mIExvZ2dpbmdDb25maWdcbiAgKTogTG9nZ2luZ0NvbmZpZ1trZXlvZiBMb2dnaW5nQ29uZmlnXSB7XG4gICAgaWYgKHRoaXMuY29uZiAmJiBrZXkgaW4gdGhpcy5jb25mKSByZXR1cm4gdGhpcy5jb25mW2tleV07XG4gICAgcmV0dXJuIExvZ2dpbmcuZ2V0Q29uZmlnKClba2V5XTtcbiAgfVxuXG4gIGZvcihtZXRob2Q6IHN0cmluZyB8ICgoLi4uYXJnczogYW55W10pID0+IGFueSkpOiBMb2dnZXI7XG4gIGZvcihjb25maWc6IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4pOiBMb2dnZXI7XG4gIGZvcihcbiAgICBtZXRob2Q6IHN0cmluZyB8ICgoLi4uYXJnczogYW55W10pID0+IGFueSkgfCBQYXJ0aWFsPExvZ2dpbmdDb25maWc+LFxuICAgIGNvbmZpZzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPixcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBMb2dnZXI7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGNoaWxkIGxvZ2dlciBmb3IgYSBzcGVjaWZpYyBtZXRob2Qgb3IgY29udGV4dFxuICAgKiBAc3VtbWFyeSBSZXR1cm5zIGEgbmV3IGxvZ2dlciBpbnN0YW5jZSB3aXRoIHRoZSBjdXJyZW50IGNvbnRleHQgZXh0ZW5kZWQgYnkgdGhlIHNwZWNpZmllZCBtZXRob2QgbmFtZVxuICAgKiBAcGFyYW0ge3N0cmluZyB8IEZ1bmN0aW9ufSBtZXRob2QgLSBUaGUgbWV0aG9kIG5hbWUgb3IgZnVuY3Rpb24gdG8gY3JlYXRlIGEgbG9nZ2VyIGZvclxuICAgKiBAcGFyYW0ge1BhcnRpYWw8TG9nZ2luZ0NvbmZpZz59IGNvbmZpZyAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gdG8gb3ZlcnJpZGUgc2V0dGluZ3NcbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGxvZ2dlciBmYWN0b3J5XG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gQSBuZXcgbG9nZ2VyIGluc3RhbmNlIGZvciB0aGUgc3BlY2lmaWVkIG1ldGhvZFxuICAgKi9cbiAgZm9yKFxuICAgIG1ldGhvZD86IHN0cmluZyB8ICgoLi4uYXJnczogYW55W10pID0+IGFueSkgfCBQYXJ0aWFsPExvZ2dpbmdDb25maWc+LFxuICAgIGNvbmZpZz86IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IExvZ2dlciB7XG4gICAgaWYgKCFjb25maWcgJiYgdHlwZW9mIG1ldGhvZCA9PT0gXCJvYmplY3RcIikge1xuICAgICAgY29uZmlnID0gbWV0aG9kO1xuICAgICAgbWV0aG9kID0gdW5kZWZpbmVkO1xuICAgIH0gZWxzZSB7XG4gICAgICBtZXRob2QgPSBtZXRob2RcbiAgICAgICAgPyB0eXBlb2YgbWV0aG9kID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgPyBtZXRob2RcbiAgICAgICAgICA6IChtZXRob2QgYXMgYW55KS5uYW1lXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHJveHkodGhpcywge1xuICAgICAgZ2V0OiAodGFyZ2V0OiB0eXBlb2YgdGhpcywgcDogc3RyaW5nIHwgc3ltYm9sLCByZWNlaXZlcjogYW55KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuZ2V0KHRhcmdldCwgcCwgcmVjZWl2ZXIpO1xuICAgICAgICBpZiAocCA9PT0gXCJjb25maWdcIikge1xuICAgICAgICAgIHJldHVybiBuZXcgUHJveHkodGhpcy5jb25maWcsIHtcbiAgICAgICAgICAgIGdldDogKHRhcmdldDogdHlwZW9mIHRoaXMuY29uZmlnLCBwOiBzdHJpbmcgfCBzeW1ib2wpID0+IHtcbiAgICAgICAgICAgICAgaWYgKGNvbmZpZyAmJiBwIGluIGNvbmZpZylcbiAgICAgICAgICAgICAgICByZXR1cm4gY29uZmlnW3AgYXMga2V5b2YgTG9nZ2luZ0NvbmZpZ107XG4gICAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LmdldCh0YXJnZXQsIHAsIHJlY2VpdmVyKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHAgPT09IFwiY29udGV4dFwiICYmIG1ldGhvZCkge1xuICAgICAgICAgIHJldHVybiBbcmVzdWx0LCBtZXRob2RdLmpvaW4oXCIuXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgZm9ybWF0dGVkIGxvZyBzdHJpbmdcbiAgICogQHN1bW1hcnkgR2VuZXJhdGVzIGEgbG9nIHN0cmluZyB3aXRoIHRpbWVzdGFtcCwgY29sb3JlZCBsb2cgbGV2ZWwsIGNvbnRleHQsIGFuZCBtZXNzYWdlXG4gICAqIEBwYXJhbSB7TG9nTGV2ZWx9IGxldmVsIC0gVGhlIGxvZyBsZXZlbCBmb3IgdGhpcyBtZXNzYWdlXG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZSB8IEVycm9yfSBtZXNzYWdlIC0gVGhlIG1lc3NhZ2UgdG8gbG9nIG9yIGFuIEVycm9yIG9iamVjdFxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2Vycm9yXSAtIE9wdGlvbmFsIGVycm9yIHRvIGV4dHJhY3Qgc3RhY2sgdHJhY2UgdG8gaW5jbHVkZSBpbiB0aGUgbG9nXG4gICAqIEByZXR1cm4ge3N0cmluZ30gQSBmb3JtYXR0ZWQgbG9nIHN0cmluZyB3aXRoIGFsbCBjb21wb25lbnRzXG4gICAqL1xuICBwcm90ZWN0ZWQgY3JlYXRlTG9nKFxuICAgIGxldmVsOiBMb2dMZXZlbCxcbiAgICBtZXNzYWdlOiBTdHJpbmdMaWtlIHwgRXJyb3IsXG4gICAgZXJyb3I/OiBFcnJvclxuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IGxvZzogUmVjb3JkPFxuICAgICAgfCBcInRpbWVzdGFtcFwiXG4gICAgICB8IFwibGV2ZWxcIlxuICAgICAgfCBcImNvbnRleHRcIlxuICAgICAgfCBcImNvcnJlbGF0aW9uSWRcIlxuICAgICAgfCBcIm1lc3NhZ2VcIlxuICAgICAgfCBcInNlcGFyYXRvclwiXG4gICAgICB8IFwic3RhY2tcIlxuICAgICAgfCBcImFwcFwiLFxuICAgICAgc3RyaW5nXG4gICAgPiA9IHt9IGFzIGFueTtcbiAgICBjb25zdCBzdHlsZSA9IHRoaXMuY29uZmlnKFwic3R5bGVcIik7XG4gICAgY29uc3Qgc2VwYXJhdG9yID0gdGhpcy5jb25maWcoXCJzZXBhcmF0b3JcIik7XG4gICAgY29uc3QgYXBwID0gdGhpcy5jb25maWcoXCJhcHBcIik7XG4gICAgaWYgKGFwcClcbiAgICAgIGxvZy5hcHAgPSBzdHlsZVxuICAgICAgICA/IExvZ2dpbmcudGhlbWUoYXBwIGFzIHN0cmluZywgXCJhcHBcIiwgbGV2ZWwpXG4gICAgICAgIDogKGFwcCBhcyBzdHJpbmcpO1xuXG4gICAgaWYgKHNlcGFyYXRvcilcbiAgICAgIGxvZy5zZXBhcmF0b3IgPSBzdHlsZVxuICAgICAgICA/IExvZ2dpbmcudGhlbWUoc2VwYXJhdG9yIGFzIHN0cmluZywgXCJzZXBhcmF0b3JcIiwgbGV2ZWwpXG4gICAgICAgIDogKHNlcGFyYXRvciBhcyBzdHJpbmcpO1xuXG4gICAgaWYgKHRoaXMuY29uZmlnKFwidGltZXN0YW1wXCIpKSB7XG4gICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuICAgICAgY29uc3QgdGltZXN0YW1wID0gc3R5bGUgPyBMb2dnaW5nLnRoZW1lKGRhdGUsIFwidGltZXN0YW1wXCIsIGxldmVsKSA6IGRhdGU7XG4gICAgICBsb2cudGltZXN0YW1wID0gdGltZXN0YW1wO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZyhcImxvZ0xldmVsXCIpKSB7XG4gICAgICBjb25zdCBsdmw6IHN0cmluZyA9IHN0eWxlXG4gICAgICAgID8gTG9nZ2luZy50aGVtZShsZXZlbCwgXCJsb2dMZXZlbFwiLCBsZXZlbClcbiAgICAgICAgOiBsZXZlbDtcbiAgICAgIGxvZy5sZXZlbCA9IGx2bC50b1VwcGVyQ2FzZSgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZyhcImNvbnRleHRcIikpIHtcbiAgICAgIGNvbnN0IGNvbnRleHQ6IHN0cmluZyA9IHN0eWxlXG4gICAgICAgID8gTG9nZ2luZy50aGVtZSh0aGlzLmNvbnRleHQsIFwiY2xhc3NcIiwgbGV2ZWwpXG4gICAgICAgIDogdGhpcy5jb250ZXh0O1xuICAgICAgbG9nLmNvbnRleHQgPSBjb250ZXh0O1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZyhcImNvcnJlbGF0aW9uSWRcIikpIHtcbiAgICAgIHtcbiAgICAgICAgY29uc3QgaWQ6IHN0cmluZyA9IHN0eWxlXG4gICAgICAgICAgPyBMb2dnaW5nLnRoZW1lKHRoaXMuY29uZmlnKFwiY29ycmVsYXRpb25JZFwiKSEudG9TdHJpbmcoKSwgXCJpZFwiLCBsZXZlbClcbiAgICAgICAgICA6IHRoaXMuY29uZmlnKFwiY29ycmVsYXRpb25JZFwiKSEudG9TdHJpbmcoKTtcbiAgICAgICAgbG9nLmNvcnJlbGF0aW9uSWQgPSBpZDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBtc2c6IHN0cmluZyA9IHN0eWxlXG4gICAgICA/IExvZ2dpbmcudGhlbWUoXG4gICAgICAgICAgdHlwZW9mIG1lc3NhZ2UgPT09IFwic3RyaW5nXCIgPyBtZXNzYWdlIDogKG1lc3NhZ2UgYXMgRXJyb3IpLm1lc3NhZ2UsXG4gICAgICAgICAgXCJtZXNzYWdlXCIsXG4gICAgICAgICAgbGV2ZWxcbiAgICAgICAgKVxuICAgICAgOiB0eXBlb2YgbWVzc2FnZSA9PT0gXCJzdHJpbmdcIlxuICAgICAgICA/IG1lc3NhZ2VcbiAgICAgICAgOiAobWVzc2FnZSBhcyBFcnJvcikubWVzc2FnZTtcbiAgICBsb2cubWVzc2FnZSA9IG1zZztcbiAgICBpZiAoZXJyb3IgfHwgbWVzc2FnZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBjb25zdCBzdGFjayA9IHN0eWxlXG4gICAgICAgID8gTG9nZ2luZy50aGVtZShcbiAgICAgICAgICAgIChlcnJvcj8uc3RhY2sgfHwgKG1lc3NhZ2UgYXMgRXJyb3IpLnN0YWNrKSBhcyBzdHJpbmcsXG4gICAgICAgICAgICBcInN0YWNrXCIsXG4gICAgICAgICAgICBsZXZlbFxuICAgICAgICAgIClcbiAgICAgICAgOiBlcnJvcj8uc3RhY2sgfHwgXCJcIjtcbiAgICAgIGxvZy5zdGFjayA9IGAgfCAkeyhlcnJvciB8fCAobWVzc2FnZSBhcyBFcnJvcikpLm1lc3NhZ2V9IC0gU3RhY2sgdHJhY2U6XFxuJHtzdGFja31gO1xuICAgIH1cblxuICAgIHN3aXRjaCAodGhpcy5jb25maWcoXCJmb3JtYXRcIikpIHtcbiAgICAgIGNhc2UgXCJqc29uXCI6XG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShsb2cpO1xuICAgICAgY2FzZSBcInJhd1wiOlxuICAgICAgICByZXR1cm4gKHRoaXMuY29uZmlnKFwicGF0dGVyblwiKSBhcyBzdHJpbmcpXG4gICAgICAgICAgLnNwbGl0KFwiIFwiKVxuICAgICAgICAgIC5tYXAoKHMpID0+IHtcbiAgICAgICAgICAgIGlmICghcy5tYXRjaCgvXFx7Lio/fS9nKSkgcmV0dXJuIHM7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWRTID0gc2YocywgbG9nKTtcbiAgICAgICAgICAgIGlmIChmb3JtYXR0ZWRTICE9PSBzKSByZXR1cm4gZm9ybWF0dGVkUztcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAuZmlsdGVyKChzKSA9PiBzKVxuICAgICAgICAgIC5qb2luKFwiIFwiKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgbG9nZ2luZyBmb3JtYXQ6ICR7dGhpcy5jb25maWcoXCJmb3JtYXRcIil9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGEgbWVzc2FnZSB3aXRoIHRoZSBzcGVjaWZpZWQgbG9nIGxldmVsXG4gICAqIEBzdW1tYXJ5IENoZWNrcyBpZiB0aGUgbWVzc2FnZSBzaG91bGQgYmUgbG9nZ2VkIGJhc2VkIG9uIHRoZSBjdXJyZW50IGxvZyBsZXZlbCxcbiAgICogdGhlbiB1c2VzIHRoZSBhcHByb3ByaWF0ZSBjb25zb2xlIG1ldGhvZCB0byBvdXRwdXQgdGhlIGZvcm1hdHRlZCBsb2dcbiAgICogQHBhcmFtIHtMb2dMZXZlbH0gbGV2ZWwgLSBUaGUgbG9nIGxldmVsIG9mIHRoZSBtZXNzYWdlXG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZSB8IEVycm9yfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQgb3IgYW4gRXJyb3Igb2JqZWN0XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZXJyb3JdIC0gT3B0aW9uYWwgc3RhY2sgdHJhY2UgdG8gaW5jbHVkZSBpbiB0aGUgbG9nXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBwcm90ZWN0ZWQgbG9nKGxldmVsOiBMb2dMZXZlbCwgbXNnOiBTdHJpbmdMaWtlIHwgRXJyb3IsIGVycm9yPzogRXJyb3IpOiB2b2lkIHtcbiAgICBjb25zdCBjb25mTHZsID0gdGhpcy5jb25maWcoXCJsZXZlbFwiKSBhcyBMb2dMZXZlbDtcbiAgICBpZiAoTnVtZXJpY0xvZ0xldmVsc1tjb25mTHZsXSA8IE51bWVyaWNMb2dMZXZlbHNbbGV2ZWxdKSByZXR1cm47XG4gICAgbGV0IG1ldGhvZDtcbiAgICBzd2l0Y2ggKGxldmVsKSB7XG4gICAgICBjYXNlIExvZ0xldmVsLmluZm86XG4gICAgICAgIG1ldGhvZCA9IGNvbnNvbGUubG9nO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTG9nTGV2ZWwudmVyYm9zZTpcbiAgICAgIGNhc2UgTG9nTGV2ZWwuZGVidWc6XG4gICAgICAgIG1ldGhvZCA9IGNvbnNvbGUuZGVidWc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBMb2dMZXZlbC5lcnJvcjpcbiAgICAgICAgbWV0aG9kID0gY29uc29sZS5lcnJvcjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGxvZyBsZXZlbFwiKTtcbiAgICB9XG4gICAgbWV0aG9kKHRoaXMuY3JlYXRlTG9nKGxldmVsLCBtc2csIGVycm9yKSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBzaWxseSBsZXZlbFxuICAgKiBAc3VtbWFyeSBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgc2lsbHkgbGV2ZWwgaWYgdGhlIGN1cnJlbnQgdmVyYm9zaXR5IHNldHRpbmcgYWxsb3dzIGl0XG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZX0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbdmVyYm9zaXR5PTBdIC0gVGhlIHZlcmJvc2l0eSBsZXZlbCBvZiB0aGUgbWVzc2FnZVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc2lsbHkobXNnOiBTdHJpbmdMaWtlLCB2ZXJib3NpdHk6IG51bWJlciA9IDApOiB2b2lkIHtcbiAgICBpZiAoKHRoaXMuY29uZmlnKFwidmVyYm9zZVwiKSBhcyBudW1iZXIpID49IHZlcmJvc2l0eSlcbiAgICAgIHRoaXMubG9nKExvZ0xldmVsLnZlcmJvc2UsIG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIGF0IHRoZSB2ZXJib3NlIGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSB2ZXJib3NlIGxldmVsIGlmIHRoZSBjdXJyZW50IHZlcmJvc2l0eSBzZXR0aW5nIGFsbG93cyBpdFxuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2V9IG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZFxuICAgKiBAcGFyYW0ge251bWJlcn0gW3ZlcmJvc2l0eT0wXSAtIFRoZSB2ZXJib3NpdHkgbGV2ZWwgb2YgdGhlIG1lc3NhZ2VcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHZlcmJvc2UobXNnOiBTdHJpbmdMaWtlLCB2ZXJib3NpdHk6IG51bWJlciA9IDApOiB2b2lkIHtcbiAgICBpZiAoKHRoaXMuY29uZmlnKFwidmVyYm9zZVwiKSBhcyBudW1iZXIpID49IHZlcmJvc2l0eSlcbiAgICAgIHRoaXMubG9nKExvZ0xldmVsLnZlcmJvc2UsIG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBpbmZvIGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBpbmZvIGxldmVsIGZvciBnZW5lcmFsIGFwcGxpY2F0aW9uIGluZm9ybWF0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZX0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBpbmZvKG1zZzogU3RyaW5nTGlrZSk6IHZvaWQge1xuICAgIHRoaXMubG9nKExvZ0xldmVsLmluZm8sIG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBkZWJ1ZyBsZXZlbFxuICAgKiBAc3VtbWFyeSBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgZGVidWcgbGV2ZWwgZm9yIGRldGFpbGVkIHRyb3VibGVzaG9vdGluZyBpbmZvcm1hdGlvblxuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2V9IG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZFxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgZGVidWcobXNnOiBTdHJpbmdMaWtlKTogdm9pZCB7XG4gICAgdGhpcy5sb2coTG9nTGV2ZWwuZGVidWcsIG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBlcnJvciBsZXZlbFxuICAgKiBAc3VtbWFyeSBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgZXJyb3IgbGV2ZWwgZm9yIGVycm9ycyBhbmQgZXhjZXB0aW9uc1xuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2UgfCBFcnJvcn0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkIG9yIGFuIEVycm9yIG9iamVjdFxuICAgKiBAcGFyYW0gZVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgZXJyb3IobXNnOiBTdHJpbmdMaWtlIHwgRXJyb3IsIGU/OiBFcnJvcik6IHZvaWQge1xuICAgIHRoaXMubG9nKExvZ0xldmVsLmVycm9yLCBtc2csIGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBVcGRhdGVzIHRoZSBsb2dnZXIgY29uZmlndXJhdGlvblxuICAgKiBAc3VtbWFyeSBNZXJnZXMgdGhlIHByb3ZpZGVkIGNvbmZpZ3VyYXRpb24gd2l0aCB0aGUgZXhpc3RpbmcgY29uZmlndXJhdGlvblxuICAgKiBAcGFyYW0ge1BhcnRpYWw8TG9nZ2luZ0NvbmZpZz59IGNvbmZpZyAtIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gYXBwbHlcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHNldENvbmZpZyhjb25maWc6IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4pOiB2b2lkIHtcbiAgICB0aGlzLmNvbmYgPSB7IC4uLih0aGlzLmNvbmYgfHwge30pLCAuLi5jb25maWcgfTtcbiAgfVxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBIHN0YXRpYyBjbGFzcyBmb3IgbWFuYWdpbmcgbG9nZ2luZyBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBUaGUgTG9nZ2luZyBjbGFzcyBwcm92aWRlcyBhIGNlbnRyYWxpemVkIGxvZ2dpbmcgbWVjaGFuaXNtIHdpdGggc3VwcG9ydCBmb3JcbiAqIGRpZmZlcmVudCBsb2cgbGV2ZWxzLCB2ZXJib3NpdHksIGFuZCBzdHlsaW5nLiBJdCB1c2VzIGEgc2luZ2xldG9uIHBhdHRlcm4gdG8gbWFpbnRhaW4gYSBnbG9iYWxcbiAqIGxvZ2dlciBpbnN0YW5jZSBhbmQgYWxsb3dzIGNyZWF0aW5nIHNwZWNpZmljIGxvZ2dlcnMgZm9yIGRpZmZlcmVudCBjbGFzc2VzIGFuZCBtZXRob2RzLlxuICogQGNsYXNzIExvZ2dpbmdcbiAqIEBleGFtcGxlXG4gKiAvLyBTZXQgZ2xvYmFsIGNvbmZpZ3VyYXRpb25cbiAqIExvZ2dpbmcuc2V0Q29uZmlnKHsgbGV2ZWw6IExvZ0xldmVsLmRlYnVnLCBzdHlsZTogdHJ1ZSB9KTtcbiAqXG4gKiAvLyBHZXQgYSBsb2dnZXIgZm9yIGEgc3BlY2lmaWMgY2xhc3NcbiAqIGNvbnN0IGxvZ2dlciA9IExvZ2dpbmcuZm9yKCdNeUNsYXNzJyk7XG4gKlxuICogLy8gTG9nIG1lc3NhZ2VzIGF0IGRpZmZlcmVudCBsZXZlbHNcbiAqIGxvZ2dlci5pbmZvKCdBcHBsaWNhdGlvbiBzdGFydGVkJyk7XG4gKiBsb2dnZXIuZGVidWcoJ1Byb2Nlc3NpbmcgZGF0YS4uLicpO1xuICpcbiAqIC8vIExvZyB3aXRoIGNvbnRleHRcbiAqIGNvbnN0IG1ldGhvZExvZ2dlciA9IExvZ2dpbmcuZm9yKCdNeUNsYXNzLm15TWV0aG9kJyk7XG4gKiBtZXRob2RMb2dnZXIudmVyYm9zZSgnRGV0YWlsZWQgb3BlcmF0aW9uIGluZm9ybWF0aW9uJywgMSk7XG4gKlxuICogLy8gTG9nIGVycm9yc1xuICogdHJ5IHtcbiAqICAgLy8gc29tZSBvcGVyYXRpb25cbiAqIH0gY2F0Y2ggKGVycm9yKSB7XG4gKiAgIGxvZ2dlci5lcnJvcihlcnJvcik7XG4gKiB9XG4gKiBAbWVybWFpZFxuICogY2xhc3NEaWFncmFtXG4gKiAgIGNsYXNzIExvZ2dlciB7XG4gKiAgICAgPDxpbnRlcmZhY2U+PlxuICogICAgICtmb3IobWV0aG9kLCBjb25maWcsIC4uLmFyZ3MpXG4gKiAgICAgK3NpbGx5KG1zZywgdmVyYm9zaXR5KVxuICogICAgICt2ZXJib3NlKG1zZywgdmVyYm9zaXR5KVxuICogICAgICtpbmZvKG1zZylcbiAqICAgICArZGVidWcobXNnKVxuICogICAgICtlcnJvcihtc2cpXG4gKiAgICAgK3NldENvbmZpZyhjb25maWcpXG4gKiAgIH1cbiAqXG4gKiAgIGNsYXNzIExvZ2dpbmcge1xuICogICAgIC1nbG9iYWw6IExvZ2dlclxuICogICAgIC1fZmFjdG9yeTogTG9nZ2VyRmFjdG9yeVxuICogICAgIC1fY29uZmlnOiBMb2dnaW5nQ29uZmlnXG4gKiAgICAgK3NldEZhY3RvcnkoZmFjdG9yeSlcbiAqICAgICArc2V0Q29uZmlnKGNvbmZpZylcbiAqICAgICArZ2V0Q29uZmlnKClcbiAqICAgICArZ2V0KClcbiAqICAgICArdmVyYm9zZShtc2csIHZlcmJvc2l0eSlcbiAqICAgICAraW5mbyhtc2cpXG4gKiAgICAgK2RlYnVnKG1zZylcbiAqICAgICArc2lsbHkobXNnKVxuICogICAgICtlcnJvcihtc2cpXG4gKiAgICAgK2ZvcihvYmplY3QsIGNvbmZpZywgLi4uYXJncylcbiAqICAgICArYmVjYXVzZShyZWFzb24sIGlkKVxuICogICAgICt0aGVtZSh0ZXh0LCB0eXBlLCBsb2dnZXJMZXZlbCwgdGVtcGxhdGUpXG4gKiAgIH1cbiAqXG4gKiAgIGNsYXNzIE1pbmlMb2dnZXIge1xuICogICAgICtjb25zdHJ1Y3Rvcihjb250ZXh0LCBjb25mPylcbiAqICAgfVxuICpcbiAqICAgTG9nZ2luZyAuLj4gTG9nZ2VyIDogY3JlYXRlc1xuICogICBMb2dnaW5nIC4uPiBNaW5pTG9nZ2VyIDogY3JlYXRlcyBieSBkZWZhdWx0XG4gKi9cbmV4cG9ydCBjbGFzcyBMb2dnaW5nIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZVxuICAgKiBAc3VtbWFyeSBBIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiBMb2dnZXIgdXNlZCBmb3IgZ2xvYmFsIGxvZ2dpbmdcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdsb2JhbD86IExvZ2dlcjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEZhY3RvcnkgZnVuY3Rpb24gZm9yIGNyZWF0aW5nIGxvZ2dlciBpbnN0YW5jZXNcbiAgICogQHN1bW1hcnkgQSBmdW5jdGlvbiB0aGF0IGNyZWF0ZXMgbmV3IExvZ2dlciBpbnN0YW5jZXMuIEJ5IGRlZmF1bHQsIGl0IGNyZWF0ZXMgYSBNaW5pTG9nZ2VyLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgX2ZhY3Rvcnk6IExvZ2dlckZhY3RvcnkgPSAoXG4gICAgb2JqZWN0OiBzdHJpbmcsXG4gICAgY29uZmlnPzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPlxuICApID0+IHtcbiAgICByZXR1cm4gbmV3IE1pbmlMb2dnZXIob2JqZWN0LCBjb25maWcpO1xuICB9O1xuXG4gIHByaXZhdGUgc3RhdGljIF9jb25maWc6IHR5cGVvZiBMb2dnZWRFbnZpcm9ubWVudCA9IExvZ2dlZEVudmlyb25tZW50O1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7fVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgZmFjdG9yeSBmdW5jdGlvbiBmb3IgY3JlYXRpbmcgbG9nZ2VyIGluc3RhbmNlc1xuICAgKiBAc3VtbWFyeSBBbGxvd3MgY3VzdG9taXppbmcgaG93IGxvZ2dlciBpbnN0YW5jZXMgYXJlIGNyZWF0ZWRcbiAgICogQHBhcmFtIHtMb2dnZXJGYWN0b3J5fSBmYWN0b3J5IC0gVGhlIGZhY3RvcnkgZnVuY3Rpb24gdG8gdXNlIGZvciBjcmVhdGluZyBsb2dnZXJzXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzdGF0aWMgc2V0RmFjdG9yeShmYWN0b3J5OiBMb2dnZXJGYWN0b3J5KSB7XG4gICAgTG9nZ2luZy5fZmFjdG9yeSA9IGZhY3Rvcnk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVwZGF0ZXMgdGhlIGdsb2JhbCBsb2dnaW5nIGNvbmZpZ3VyYXRpb25cbiAgICogQHN1bW1hcnkgQWxsb3dzIHVwZGF0aW5nIHRoZSBnbG9iYWwgbG9nZ2luZyBjb25maWd1cmF0aW9uIHdpdGggbmV3IHNldHRpbmdzXG4gICAqIEBwYXJhbSB7UGFydGlhbDxMb2dnaW5nQ29uZmlnPn0gY29uZmlnIC0gVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byBhcHBseVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc3RhdGljIHNldENvbmZpZyhjb25maWc6IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4pOiB2b2lkIHtcbiAgICBPYmplY3QuZW50cmllcyhjb25maWcpLmZvckVhY2goKFtrLCB2XSkgPT4ge1xuICAgICAgKHRoaXMuX2NvbmZpZyBhcyBhbnkpW2tdID0gdiBhcyBhbnk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgYSBjb3B5IG9mIHRoZSBjdXJyZW50IGdsb2JhbCBsb2dnaW5nIGNvbmZpZ3VyYXRpb25cbiAgICogQHN1bW1hcnkgUmV0dXJucyBhIGNvcHkgb2YgdGhlIGN1cnJlbnQgZ2xvYmFsIGxvZ2dpbmcgY29uZmlndXJhdGlvblxuICAgKiBAcmV0dXJuIHtMb2dnaW5nQ29uZmlnfSBBIGNvcHkgb2YgdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvblxuICAgKi9cbiAgc3RhdGljIGdldENvbmZpZygpOiB0eXBlb2YgTG9nZ2VkRW52aXJvbm1lbnQge1xuICAgIHJldHVybiB0aGlzLl9jb25maWc7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBvciBjcmVhdGVzIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKiBAc3VtbWFyeSBSZXR1cm5zIHRoZSBleGlzdGluZyBnbG9iYWwgbG9nZ2VyIG9yIGNyZWF0ZXMgYSBuZXcgb25lIGlmIGl0IGRvZXNuJ3QgZXhpc3QuXG4gICAqXG4gICAqIEByZXR1cm4gVGhlIGdsb2JhbCBWZXJib3NpdHlMb2dnZXIgaW5zdGFuY2UuXG4gICAqL1xuICBzdGF0aWMgZ2V0KCk6IExvZ2dlciB7XG4gICAgdGhpcy5nbG9iYWwgPSB0aGlzLmdsb2JhbCA/IHRoaXMuZ2xvYmFsIDogdGhpcy5fZmFjdG9yeShcIkxvZ2dpbmdcIik7XG4gICAgcmV0dXJuIHRoaXMuZ2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGEgdmVyYm9zZSBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdGhlIHZlcmJvc2UgbG9nZ2luZyB0byB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC5cbiAgICogQHBhcmFtIHZlcmJvc2l0eSAtIFRoZSB2ZXJib3NpdHkgbGV2ZWwgb2YgdGhlIG1lc3NhZ2UgKGRlZmF1bHQ6IDApLlxuICAgKi9cbiAgc3RhdGljIHZlcmJvc2UobXNnOiBTdHJpbmdMaWtlLCB2ZXJib3NpdHk6IG51bWJlciA9IDApOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS52ZXJib3NlKG1zZywgdmVyYm9zaXR5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhbiBpbmZvIG1lc3NhZ2UuXG4gICAqIEBzdW1tYXJ5IERlbGVnYXRlcyB0aGUgaW5mbyBsb2dnaW5nIHRvIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLlxuICAgKi9cbiAgc3RhdGljIGluZm8obXNnOiBTdHJpbmdMaWtlKTogdm9pZCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkuaW5mbyhtc2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGEgZGVidWcgbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRoZSBkZWJ1ZyBsb2dnaW5nIHRvIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLlxuICAgKi9cbiAgc3RhdGljIGRlYnVnKG1zZzogU3RyaW5nTGlrZSk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmdldCgpLmRlYnVnKG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBzaWxseSBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdGhlIGRlYnVnIGxvZ2dpbmcgdG8gdGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuXG4gICAqL1xuICBzdGF0aWMgc2lsbHkobXNnOiBTdHJpbmdMaWtlKTogdm9pZCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkuc2lsbHkobXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhbiBlcnJvciBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdGhlIGVycm9yIGxvZ2dpbmcgdG8gdGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuXG4gICAqIEBwYXJhbSBlXG4gICAqL1xuICBzdGF0aWMgZXJyb3IobXNnOiBTdHJpbmdMaWtlLCBlPzogRXJyb3IpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5lcnJvcihtc2csIGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbG9nZ2VyIGZvciBhIHNwZWNpZmljIG9iamVjdCBvciBjb250ZXh0XG4gICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBuZXcgbG9nZ2VyIGluc3RhbmNlIGZvciB0aGUgZ2l2ZW4gb2JqZWN0IG9yIGNvbnRleHQgdXNpbmcgdGhlIGZhY3RvcnkgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtMb2dnaW5nQ29udGV4dH0gb2JqZWN0IC0gVGhlIG9iamVjdCwgY2xhc3MsIG9yIGNvbnRleHQgdG8gY3JlYXRlIGEgbG9nZ2VyIGZvclxuICAgKiBAcGFyYW0ge1BhcnRpYWw8TG9nZ2luZ0NvbmZpZz59IFtjb25maWddIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvbiB0byBvdmVycmlkZSBnbG9iYWwgc2V0dGluZ3NcbiAgICogQHBhcmFtIHsuLi5hbnl9IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBsb2dnZXIgZmFjdG9yeVxuICAgKiBAcmV0dXJuIHtMb2dnZXJ9IEEgbmV3IGxvZ2dlciBpbnN0YW5jZSBmb3IgdGhlIHNwZWNpZmllZCBvYmplY3Qgb3IgY29udGV4dFxuICAgKi9cbiAgc3RhdGljIGZvcihcbiAgICBvYmplY3Q6IExvZ2dpbmdDb250ZXh0LFxuICAgIGNvbmZpZz86IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogTG9nZ2VyIHtcbiAgICBvYmplY3QgPVxuICAgICAgdHlwZW9mIG9iamVjdCA9PT0gXCJzdHJpbmdcIlxuICAgICAgICA/IG9iamVjdFxuICAgICAgICA6IG9iamVjdC5jb25zdHJ1Y3RvclxuICAgICAgICAgID8gb2JqZWN0LmNvbnN0cnVjdG9yLm5hbWVcbiAgICAgICAgICA6IG9iamVjdC5uYW1lO1xuICAgIHJldHVybiB0aGlzLl9mYWN0b3J5KG9iamVjdCwgY29uZmlnLCAuLi5hcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGxvZ2dlciBmb3IgYSBzcGVjaWZpYyByZWFzb24gb3IgY29ycmVsYXRpb24gY29udGV4dFxuICAgKiBAc3VtbWFyeSBVdGlsaXR5IHRvIHF1aWNrbHkgY3JlYXRlIGEgbG9nZ2VyIGxhYmVsZWQgd2l0aCBhIGZyZWUtZm9ybSByZWFzb24gYW5kIG9wdGlvbmFsIGlkZW50aWZpZXJcbiAgICogc28gdGhhdCBhZC1ob2Mgb3BlcmF0aW9ucyBjYW4gYmUgdHJhY2VkIHdpdGhvdXQgdHlpbmcgdGhlIGxvZ2dlciB0byBhIGNsYXNzIG9yIG1ldGhvZCBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmVhc29uIC0gQSB0ZXh0dWFsIHJlYXNvbiBvciBjb250ZXh0IGxhYmVsIGZvciB0aGlzIGxvZ2dlciBpbnN0YW5jZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2lkXSAtIE9wdGlvbmFsIGlkZW50aWZpZXIgdG8gaGVscCBjb3JyZWxhdGUgcmVsYXRlZCBsb2cgZW50cmllc1xuICAgKiBAcmV0dXJuIHtMb2dnZXJ9IEEgbmV3IGxvZ2dlciBpbnN0YW5jZSBsYWJlbGVkIHdpdGggdGhlIHByb3ZpZGVkIHJlYXNvbiBhbmQgaWRcbiAgICovXG4gIHN0YXRpYyBiZWNhdXNlKHJlYXNvbjogc3RyaW5nLCBpZD86IHN0cmluZyk6IExvZ2dlciB7XG4gICAgcmV0dXJuIHRoaXMuX2ZhY3RvcnkocmVhc29uLCB0aGlzLl9jb25maWcsIGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQXBwbGllcyB0aGVtZSBzdHlsaW5nIHRvIHRleHRcbiAgICogQHN1bW1hcnkgQXBwbGllcyBzdHlsaW5nIChjb2xvcnMsIGZvcm1hdHRpbmcpIHRvIHRleHQgYmFzZWQgb24gdGhlIHRoZW1lIGNvbmZpZ3VyYXRpb25cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUaGUgdGV4dCB0byBzdHlsZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSAtIFRoZSB0eXBlIG9mIGVsZW1lbnQgdG8gc3R5bGUgKGUuZy4sIFwiY2xhc3NcIiwgXCJtZXNzYWdlXCIsIFwibG9nTGV2ZWxcIilcbiAgICogQHBhcmFtIHtMb2dMZXZlbH0gbG9nZ2VyTGV2ZWwgLSBUaGUgbG9nIGxldmVsIHRvIHVzZSBmb3Igc3R5bGluZ1xuICAgKiBAcGFyYW0ge1RoZW1lfSBbdGVtcGxhdGU9RGVmYXVsdFRoZW1lXSAtIFRoZSB0aGVtZSB0byB1c2UgZm9yIHN0eWxpbmdcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgc3R5bGVkIHRleHRcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gICAqICAgcGFydGljaXBhbnQgVGhlbWUgYXMgTG9nZ2luZy50aGVtZVxuICAgKiAgIHBhcnRpY2lwYW50IEFwcGx5IGFzIGFwcGx5IGZ1bmN0aW9uXG4gICAqICAgcGFydGljaXBhbnQgU3R5bGUgYXMgc3R5bGVkLXN0cmluZy1idWlsZGVyXG4gICAqXG4gICAqICAgQ2FsbGVyLT4+VGhlbWU6IHRoZW1lKHRleHQsIHR5cGUsIGxvZ2dlckxldmVsKVxuICAgKiAgIFRoZW1lLT4+VGhlbWU6IENoZWNrIGlmIHN0eWxpbmcgaXMgZW5hYmxlZFxuICAgKiAgIGFsdCBzdHlsaW5nIGRpc2FibGVkXG4gICAqICAgICBUaGVtZS0tPj5DYWxsZXI6IHJldHVybiBvcmlnaW5hbCB0ZXh0XG4gICAqICAgZWxzZSBzdHlsaW5nIGVuYWJsZWRcbiAgICogICAgIFRoZW1lLT4+VGhlbWU6IEdldCB0aGVtZSBmb3IgdHlwZVxuICAgKiAgICAgYWx0IHRoZW1lIG5vdCBmb3VuZFxuICAgKiAgICAgICBUaGVtZS0tPj5DYWxsZXI6IHJldHVybiBvcmlnaW5hbCB0ZXh0XG4gICAqICAgICBlbHNlIHRoZW1lIGZvdW5kXG4gICAqICAgICAgIFRoZW1lLT4+VGhlbWU6IERldGVybWluZSBhY3R1YWwgdGhlbWUgYmFzZWQgb24gbG9nIGxldmVsXG4gICAqICAgICAgIFRoZW1lLT4+QXBwbHk6IEFwcGx5IGVhY2ggc3R5bGUgcHJvcGVydHlcbiAgICogICAgICAgQXBwbHktPj5TdHlsZTogQXBwbHkgY29sb3JzIGFuZCBmb3JtYXR0aW5nXG4gICAqICAgICAgIFN0eWxlLS0+PkFwcGx5OiBSZXR1cm4gc3R5bGVkIHRleHRcbiAgICogICAgICAgQXBwbHktLT4+VGhlbWU6IFJldHVybiBzdHlsZWQgdGV4dFxuICAgKiAgICAgICBUaGVtZS0tPj5DYWxsZXI6IFJldHVybiBmaW5hbCBzdHlsZWQgdGV4dFxuICAgKiAgICAgZW5kXG4gICAqICAgZW5kXG4gICAqL1xuICBzdGF0aWMgdGhlbWUoXG4gICAgdGV4dDogc3RyaW5nLFxuICAgIHR5cGU6IGtleW9mIFRoZW1lIHwga2V5b2YgTG9nTGV2ZWwsXG4gICAgbG9nZ2VyTGV2ZWw6IExvZ0xldmVsLFxuICAgIHRlbXBsYXRlOiBUaGVtZSA9IERlZmF1bHRUaGVtZVxuICApIHtcbiAgICBpZiAoIXRoaXMuX2NvbmZpZy5zdHlsZSkgcmV0dXJuIHRleHQ7XG4gICAgY29uc3QgbG9nZ2VyID0gTG9nZ2luZy5nZXQoKS5mb3IodGhpcy50aGVtZSk7XG5cbiAgICBmdW5jdGlvbiBhcHBseShcbiAgICAgIHR4dDogc3RyaW5nLFxuICAgICAgb3B0aW9uOiBrZXlvZiBUaGVtZU9wdGlvbixcbiAgICAgIHZhbHVlOiBudW1iZXIgfCBbbnVtYmVyXSB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSB8IG51bWJlcltdIHwgc3RyaW5nW11cbiAgICApOiBzdHJpbmcge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgdDogc3RyaW5nIHwgU3R5bGVkU3RyaW5nID0gdHh0O1xuICAgICAgICBsZXQgYyA9IHN0eWxlKHQpO1xuXG4gICAgICAgIGZ1bmN0aW9uIGFwcGx5Q29sb3IoXG4gICAgICAgICAgdmFsOiBudW1iZXIgfCBbbnVtYmVyXSB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICAgICAgICBpc0JnID0gZmFsc2VcbiAgICAgICAgKTogU3R5bGVkU3RyaW5nIHtcbiAgICAgICAgICBsZXQgZjpcbiAgICAgICAgICAgIHwgdHlwZW9mIGMuYmFja2dyb3VuZFxuICAgICAgICAgICAgfCB0eXBlb2YgYy5mb3JlZ3JvdW5kXG4gICAgICAgICAgICB8IHR5cGVvZiBjLnJnYlxuICAgICAgICAgICAgfCB0eXBlb2YgYy5jb2xvcjI1NiA9IGlzQmcgPyBjLmJhY2tncm91bmQgOiBjLmZvcmVncm91bmQ7XG4gICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbCkpIHtcbiAgICAgICAgICAgIHJldHVybiAoZiBhcyB0eXBlb2YgYy5iYWNrZ3JvdW5kIHwgdHlwZW9mIGMuZm9yZWdyb3VuZCkuY2FsbChcbiAgICAgICAgICAgICAgYyxcbiAgICAgICAgICAgICAgdmFsdWUgYXMgbnVtYmVyXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzd2l0Y2ggKHZhbC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgZiA9IGlzQmcgPyBjLmJnQ29sb3IyNTYgOiBjLmNvbG9yMjU2O1xuICAgICAgICAgICAgICByZXR1cm4gKGYgYXMgdHlwZW9mIGMuYmdDb2xvcjI1NiB8IHR5cGVvZiBjLmNvbG9yMjU2KSh2YWxbMF0pO1xuICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICBmID0gaXNCZyA/IGMuYmdSZ2IgOiBjLnJnYjtcbiAgICAgICAgICAgICAgcmV0dXJuIGMucmdiKHZhbFswXSwgdmFsWzFdLCB2YWxbMl0pO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBOb3QgYSB2YWxpZCBjb2xvciBvcHRpb246ICR7b3B0aW9ufWApO1xuICAgICAgICAgICAgICByZXR1cm4gc3R5bGUodCBhcyBzdHJpbmcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGFwcGx5U3R5bGUodjogbnVtYmVyIHwgc3RyaW5nKTogdm9pZCB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2ID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICBjID0gYy5zdHlsZSh2KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYyA9IGNbdiBhcyBrZXlvZiBDb2xvcml6ZU9wdGlvbnNdIGFzIFN0eWxlZFN0cmluZztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzd2l0Y2ggKG9wdGlvbikge1xuICAgICAgICAgIGNhc2UgXCJiZ1wiOlxuICAgICAgICAgIGNhc2UgXCJmZ1wiOlxuICAgICAgICAgICAgcmV0dXJuIGFwcGx5Q29sb3IodmFsdWUgYXMgbnVtYmVyKS50ZXh0O1xuICAgICAgICAgIGNhc2UgXCJzdHlsZVwiOlxuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgIHZhbHVlLmZvckVhY2goYXBwbHlTdHlsZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBhcHBseVN0eWxlKHZhbHVlIGFzIG51bWJlciB8IHN0cmluZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gYy50ZXh0O1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYE5vdCBhIHZhbGlkIHRoZW1lIG9wdGlvbjogJHtvcHRpb259YCk7XG4gICAgICAgICAgICByZXR1cm4gdDtcbiAgICAgICAgfVxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihgRXJyb3IgYXBwbHlpbmcgc3R5bGU6ICR7b3B0aW9ufSB3aXRoIHZhbHVlICR7dmFsdWV9YCk7XG4gICAgICAgIHJldHVybiB0eHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaW5kaXZpZHVhbFRoZW1lID0gdGVtcGxhdGVbdHlwZSBhcyBrZXlvZiBUaGVtZV07XG4gICAgaWYgKCFpbmRpdmlkdWFsVGhlbWUgfHwgIU9iamVjdC5rZXlzKGluZGl2aWR1YWxUaGVtZSkubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGV4dDtcbiAgICB9XG5cbiAgICBsZXQgYWN0dWFsVGhlbWU6IFRoZW1lT3B0aW9uID0gaW5kaXZpZHVhbFRoZW1lIGFzIFRoZW1lT3B0aW9uO1xuXG4gICAgY29uc3QgbG9nTGV2ZWxzID0gT2JqZWN0LmFzc2lnbih7fSwgTG9nTGV2ZWwpO1xuICAgIGlmIChPYmplY3Qua2V5cyhpbmRpdmlkdWFsVGhlbWUpWzBdIGluIGxvZ0xldmVscylcbiAgICAgIGFjdHVhbFRoZW1lID1cbiAgICAgICAgKGluZGl2aWR1YWxUaGVtZSBhcyBUaGVtZU9wdGlvbkJ5TG9nTGV2ZWwpW2xvZ2dlckxldmVsXSB8fCB7fTtcblxuICAgIHJldHVybiBPYmplY3Qua2V5cyhhY3R1YWxUaGVtZSkucmVkdWNlKChhY2M6IHN0cmluZywga2V5OiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IHZhbCA9IChhY3R1YWxUaGVtZSBhcyBUaGVtZU9wdGlvbilba2V5IGFzIGtleW9mIFRoZW1lT3B0aW9uXTtcbiAgICAgIGlmICh2YWwpXG4gICAgICAgIHJldHVybiBhcHBseShcbiAgICAgICAgICBhY2MsXG4gICAgICAgICAga2V5IGFzIGtleW9mIFRoZW1lT3B0aW9uLFxuICAgICAgICAgIHZhbCBhc1xuICAgICAgICAgICAgfCBudW1iZXJcbiAgICAgICAgICAgIHwgW251bWJlcl1cbiAgICAgICAgICAgIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdXG4gICAgICAgICAgICB8IG51bWJlcltdXG4gICAgICAgICAgICB8IHN0cmluZ1tdXG4gICAgICAgICk7XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHRleHQpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSBcIi4vbG9nZ2luZ1wiO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQmFzZSBjbGFzcyB0aGF0IHByb3ZpZGVzIGEgcmVhZHktdG8tdXNlIGxvZ2dlciBpbnN0YW5jZVxuICogQHN1bW1hcnkgTG9nZ2VkQ2xhc3MgaXMgYSBjb252ZW5pZW5jZSBhYnN0cmFjdCBjbGFzcyB0aGF0IGluamVjdHMgYSB0eXBlLXNhZmUgbG9nZ2VyXG4gKiBpbnRvIGRlcml2ZWQgY2xhc3NlcyB0aHJvdWdoIGEgcHJvdGVjdGVkIGdldHRlci4gU3ViY2xhc3NlcyBjYW4gZGlyZWN0bHkgYWNjZXNzXG4gKiB0aGlzLmxvZyB0byBlbWl0IG1lc3NhZ2VzIHdpdGhvdXQgbWFudWFsbHkgY3JlYXRpbmcgYSBsb2dnZXIuIFRoaXMgcHJvbW90ZXNcbiAqIGNvbnNpc3RlbnQsIGNvbnRleHQtYXdhcmUgbG9nZ2luZyBhY3Jvc3MgdGhlIGNvZGViYXNlLlxuICogQHBhcmFtIHt2b2lkfSBbY29uc3RydWN0b3JdIC0gTm8gY29uc3RydWN0b3IgYXJndW1lbnRzOyBzdWJjbGFzc2VzIG1heSBkZWZpbmUgdGhlaXIgb3duXG4gKiBAY2xhc3MgTG9nZ2VkQ2xhc3NcbiAqIEBleGFtcGxlXG4gKiBjbGFzcyBVc2VyU2VydmljZSBleHRlbmRzIExvZ2dlZENsYXNzIHtcbiAqICAgY3JlYXRlKHVzZXI6IFVzZXIpIHtcbiAqICAgICB0aGlzLmxvZy5pbmZvKGBDcmVhdGluZyB1c2VyICR7dXNlci5pZH1gKTtcbiAqICAgfVxuICogfVxuICpcbiAqIGNvbnN0IHN2YyA9IG5ldyBVc2VyU2VydmljZSgpO1xuICogc3ZjLmNyZWF0ZSh7IGlkOiBcIjQyXCIgfSk7XG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICogICBwYXJ0aWNpcGFudCBJbnN0YW5jZSBhcyBTdWJjbGFzcyBJbnN0YW5jZVxuICogICBwYXJ0aWNpcGFudCBHZXR0ZXIgYXMgTG9nZ2VkQ2xhc3MubG9nXG4gKiAgIHBhcnRpY2lwYW50IExvZ2dpbmcgYXMgTG9nZ2luZ1xuICogICBwYXJ0aWNpcGFudCBMb2dnZXIgYXMgTG9nZ2VyXG4gKlxuICogICBDbGllbnQtPj5JbnN0YW5jZTogY2FsbCBzb21lTWV0aG9kKClcbiAqICAgSW5zdGFuY2UtPj5HZXR0ZXI6IGFjY2VzcyB0aGlzLmxvZ1xuICogICBHZXR0ZXItPj5Mb2dnaW5nOiBMb2dnaW5nLmZvcih0aGlzKVxuICogICBMb2dnaW5nLS0+PkdldHRlcjogcmV0dXJuIExvZ2dlclxuICogICBHZXR0ZXItLT4+SW5zdGFuY2U6IHJldHVybiBMb2dnZXJcbiAqICAgSW5zdGFuY2UtPj5Mb2dnZXI6IGluZm8vZGVidWcvZXJyb3IoLi4uKVxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgTG9nZ2VkQ2xhc3Mge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExhemlseSBwcm92aWRlcyBhIGNvbnRleHQtYXdhcmUgbG9nZ2VyIGZvciB0aGUgY3VycmVudCBpbnN0YW5jZVxuICAgKiBAc3VtbWFyeSBVc2VzIExvZ2dpbmcuZm9yKHRoaXMpIHRvIGNyZWF0ZSBhIGxvZ2dlciB3aG9zZSBjb250ZXh0IGlzIHRoZVxuICAgKiBzdWJjbGFzcyBuYW1lLCBhbGxvd2luZyB1bmlmb3JtIGFuZCBzdHJ1Y3R1cmVkIGxvZ3MgZnJvbSBhbnkgaW5oZXJpdGluZyBjbGFzcy5cbiAgICogQHJldHVybiB7TG9nZ2VyfSBBIGxvZ2dlciBib3VuZCB0byB0aGUgc3ViY2xhc3MgY29udGV4dFxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBsb2coKTogTG9nZ2VyIHtcbiAgICByZXR1cm4gTG9nZ2luZy5mb3IodGhpcyBhcyBhbnkpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKCkge31cbn1cbiIsImltcG9ydCB7IExvZ2dlciwgTG9nZ2luZ0NvbmZpZywgTG9nZ2luZ0ZpbHRlciB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgTG9nZ2VkQ2xhc3MgfSBmcm9tIFwiLi4vTG9nZ2VkQ2xhc3NcIjtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIExvZ0ZpbHRlciBleHRlbmRzIExvZ2dlZENsYXNzIGltcGxlbWVudHMgTG9nZ2luZ0ZpbHRlciB7XG4gIG92ZXJyaWRlIGdldCBsb2coKTogTG9nZ2VyIHtcbiAgICByZXR1cm4gc3VwZXIubG9nLmZvcih0aGlzIGFzIGFueSwgeyBmaWx0ZXJzOiBbXSB9KTtcbiAgfVxuXG4gIGFic3RyYWN0IGZpbHRlcihcbiAgICBjb25maWc6IExvZ2dpbmdDb25maWcsXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICAgIGNvbnRleHQ6IHN0cmluZ1tdXG4gICk6IHN0cmluZztcbn1cbiIsImltcG9ydCB7IExvZ0xldmVsIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSBcIi4vbG9nZ2luZ1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzXG4gKiBAc3VtbWFyeSBDcmVhdGVzIGEgZGVjb3JhdG9yIHRoYXQgbG9ncyBtZXRob2QgY2FsbHMgd2l0aCBzcGVjaWZpZWQgbGV2ZWwsIGJlbmNobWFya2luZywgYW5kIHZlcmJvc2l0eVxuICogQHBhcmFtIHtMb2dMZXZlbH0gbGV2ZWwgLSBUaGUgbG9nIGxldmVsIHRvIHVzZSAoZGVmYXVsdDogTG9nTGV2ZWwuaW5mbylcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2JlbmNobWFyaz1mYWxzZV0gLSBXaGV0aGVyIHRvIGxvZyBleGVjdXRpb24gdGltZSAoZGVmYXVsdDogZmFsc2UpXG4gKiBAcGFyYW0ge251bWJlcn0gW3ZlcmJvc2l0eT0wXSAtIFRoZSB2ZXJib3NpdHkgbGV2ZWwgZm9yIHRoZSBsb2cgbWVzc2FnZXMgKGRlZmF1bHQ6IDApXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiBsb2dcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IERlY29yYXRvciBhcyBsb2cgZGVjb3JhdG9yXG4gKiAgIHBhcnRpY2lwYW50IE1ldGhvZCBhcyBPcmlnaW5hbCBNZXRob2RcbiAqICAgcGFydGljaXBhbnQgTG9nZ2VyIGFzIExvZ2dpbmcgaW5zdGFuY2VcbiAqXG4gKiAgIENsaWVudC0+PkRlY29yYXRvcjogY2FsbCBkZWNvcmF0ZWQgbWV0aG9kXG4gKiAgIERlY29yYXRvci0+PkxvZ2dlcjogbG9nIG1ldGhvZCBjYWxsXG4gKiAgIERlY29yYXRvci0+Pk1ldGhvZDogY2FsbCBvcmlnaW5hbCBtZXRob2RcbiAqICAgYWx0IHJlc3VsdCBpcyBQcm9taXNlXG4gKiAgICAgTWV0aG9kLS0+PkRlY29yYXRvcjogcmV0dXJuIFByb21pc2VcbiAqICAgICBEZWNvcmF0b3ItPj5EZWNvcmF0b3I6IGF0dGFjaCB0aGVuIGhhbmRsZXJcbiAqICAgICBOb3RlIG92ZXIgRGVjb3JhdG9yOiBQcm9taXNlIHJlc29sdmVzXG4gKiAgICAgRGVjb3JhdG9yLT4+TG9nZ2VyOiBsb2cgYmVuY2htYXJrIChpZiBlbmFibGVkKVxuICogICAgIERlY29yYXRvci0tPj5DbGllbnQ6IHJldHVybiByZXN1bHRcbiAqICAgZWxzZSByZXN1bHQgaXMgbm90IFByb21pc2VcbiAqICAgICBNZXRob2QtLT4+RGVjb3JhdG9yOiByZXR1cm4gcmVzdWx0XG4gKiAgICAgRGVjb3JhdG9yLT4+TG9nZ2VyOiBsb2cgYmVuY2htYXJrIChpZiBlbmFibGVkKVxuICogICAgIERlY29yYXRvci0tPj5DbGllbnQ6IHJldHVybiByZXN1bHRcbiAqICAgZW5kXG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvZyhcbiAgbGV2ZWw6IExvZ0xldmVsID0gTG9nTGV2ZWwuaW5mbyxcbiAgYmVuY2htYXJrOiBib29sZWFuID0gZmFsc2UsXG4gIHZlcmJvc2l0eSA9IDBcbikge1xuICByZXR1cm4gZnVuY3Rpb24gKFxuICAgIHRhcmdldDogYW55LFxuICAgIHByb3BlcnR5S2V5PzogYW55LFxuICAgIGRlc2NyaXB0b3I/OiBQcm9wZXJ0eURlc2NyaXB0b3JcbiAgKSB7XG4gICAgaWYgKCFkZXNjcmlwdG9yKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBMb2dnaW5nIGRlY29yYXRpb24gb25seSBhcHBsaWVzIHRvIG1ldGhvZHNgKTtcbiAgICBjb25zdCBsb2dnZXIgPSBMb2dnaW5nLmZvcih0YXJnZXQpLmZvcih0YXJnZXRbcHJvcGVydHlLZXldKTtcbiAgICBjb25zdCBtZXRob2QgPSBsb2dnZXJbbGV2ZWxdLmJpbmQobG9nZ2VyKSBhcyBhbnk7XG4gICAgY29uc3Qgb3JpZ2luYWxNZXRob2QgPSBkZXNjcmlwdG9yLnZhbHVlO1xuXG4gICAgZGVzY3JpcHRvci52YWx1ZSA9IG5ldyBQcm94eShvcmlnaW5hbE1ldGhvZCwge1xuICAgICAgYXBwbHkoZm4sIHRoaXNBcmcsIGFyZ3M6IGFueVtdKSB7XG4gICAgICAgIG1ldGhvZChgY2FsbGVkIHdpdGggJHthcmdzfWAsIHZlcmJvc2l0eSk7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBSZWZsZWN0LmFwcGx5KGZuLCB0aGlzQXJnLCBhcmdzKTtcbiAgICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50aGVuKChyOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgaWYgKGJlbmNobWFyaylcbiAgICAgICAgICAgICAgICBtZXRob2QoYGNvbXBsZXRlZCBpbiAke0RhdGUubm93KCkgLSBzdGFydH1tc2AsIHZlcmJvc2l0eSk7XG4gICAgICAgICAgICAgIHJldHVybiByO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChiZW5jaG1hcmspXG4gICAgICAgICAgICBtZXRob2QoYGNvbXBsZXRlZCBpbiAke0RhdGUubm93KCkgLSBzdGFydH1tc2AsIHZlcmJvc2l0eSk7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgaWYgKGJlbmNobWFyaykgbWV0aG9kKGBmYWlsZWQgaW4gJHtEYXRlLm5vdygpIC0gc3RhcnR9bXNgLCB2ZXJib3NpdHkpO1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcbiAgfTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIGRlYnVnIGxldmVsXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB0aGUgbG9nIGRlY29yYXRvciB0aGF0IHVzZXMgTG9nTGV2ZWwuZGVidWdcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2JlbmNobWFyaz1mYWxzZV0gLSBXaGV0aGVyIHRvIGxvZyBleGVjdXRpb24gdGltZSAoZGVmYXVsdDogZmFsc2UpXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIGRlYnVnIGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiBkZWJ1Z1xuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWJ1ZyhiZW5jaG1hcms6IGJvb2xlYW4gPSBmYWxzZSkge1xuICByZXR1cm4gbG9nKExvZ0xldmVsLmRlYnVnLCBiZW5jaG1hcmspO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggaW5mbyBsZXZlbFxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQgdGhlIGxvZyBkZWNvcmF0b3IgdGhhdCB1c2VzIExvZ0xldmVsLmluZm9cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2JlbmNobWFyaz1mYWxzZV0gLSBXaGV0aGVyIHRvIGxvZyBleGVjdXRpb24gdGltZSAoZGVmYXVsdDogZmFsc2UpXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIGluZm8gbG9nZ2luZ1xuICogQGZ1bmN0aW9uIGluZm9cbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gaW5mbyhiZW5jaG1hcms6IGJvb2xlYW4gPSBmYWxzZSkge1xuICByZXR1cm4gbG9nKExvZ0xldmVsLmluZm8sIGJlbmNobWFyayk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCBzaWxseSBsZXZlbFxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQgdGhlIGxvZyBkZWNvcmF0b3IgdGhhdCB1c2VzIExvZ0xldmVsLnNpbGx5XG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtiZW5jaG1hcms9ZmFsc2VdIC0gV2hldGhlciB0byBsb2cgZXhlY3V0aW9uIHRpbWUgKGRlZmF1bHQ6IGZhbHNlKVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbWV0aG9kIGRlY29yYXRvciB0aGF0IHdyYXBzIHRoZSBvcmlnaW5hbCBtZXRob2Qgd2l0aCBzaWxseSBsb2dnaW5nXG4gKiBAZnVuY3Rpb24gc2lsbHlcbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gc2lsbHkoYmVuY2htYXJrOiBib29sZWFuID0gZmFsc2UpIHtcbiAgcmV0dXJuIGxvZyhMb2dMZXZlbC5zaWxseSwgYmVuY2htYXJrKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIHZlcmJvc2UgbGV2ZWxcbiAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIHRoZSBsb2cgZGVjb3JhdG9yIHRoYXQgdXNlcyBMb2dMZXZlbC52ZXJib3NlIHdpdGggY29uZmlndXJhYmxlIHZlcmJvc2l0eVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbWV0aG9kIGRlY29yYXRvciB0aGF0IHdyYXBzIHRoZSBvcmlnaW5hbCBtZXRob2Qgd2l0aCB2ZXJib3NlIGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiB2ZXJib3NlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKCk6IChcbiAgdGFyZ2V0OiBhbnksXG4gIHByb3BlcnR5S2V5PzogYW55LFxuICBkZXNjcmlwdG9yPzogYW55XG4pID0+IHZvaWQ7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCB2ZXJib3NlIGxldmVsXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB0aGUgbG9nIGRlY29yYXRvciB0aGF0IHVzZXMgTG9nTGV2ZWwudmVyYm9zZSB3aXRoIGNvbmZpZ3VyYWJsZSB2ZXJib3NpdHlcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gYmVuY2htYXJrIC0gV2hldGhlciB0byBsb2cgZXhlY3V0aW9uIHRpbWVcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG1ldGhvZCBkZWNvcmF0b3IgdGhhdCB3cmFwcyB0aGUgb3JpZ2luYWwgbWV0aG9kIHdpdGggdmVyYm9zZSBsb2dnaW5nXG4gKiBAZnVuY3Rpb24gdmVyYm9zZVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyYm9zZShcbiAgYmVuY2htYXJrOiBib29sZWFuXG4pOiAodGFyZ2V0OiBhbnksIHByb3BlcnR5S2V5PzogYW55LCBkZXNjcmlwdG9yPzogYW55KSA9PiB2b2lkO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggdmVyYm9zZSBsZXZlbFxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQgdGhlIGxvZyBkZWNvcmF0b3IgdGhhdCB1c2VzIExvZ0xldmVsLnZlcmJvc2Ugd2l0aCBjb25maWd1cmFibGUgdmVyYm9zaXR5XG4gKiBAcGFyYW0ge251bWJlcn0gdmVyYm9zaXR5IC0gVGhlIHZlcmJvc2l0eSBsZXZlbCBmb3IgdGhlIGxvZyBtZXNzYWdlcyAoZGVmYXVsdDogMClcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG1ldGhvZCBkZWNvcmF0b3IgdGhhdCB3cmFwcyB0aGUgb3JpZ2luYWwgbWV0aG9kIHdpdGggdmVyYm9zZSBsb2dnaW5nXG4gKiBAZnVuY3Rpb24gdmVyYm9zZVxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKFxuICB2ZXJib3NpdHk6IG51bWJlciB8IGJvb2xlYW5cbik6ICh0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk/OiBhbnksIGRlc2NyaXB0b3I/OiBhbnkpID0+IHZvaWQ7XG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggdmVyYm9zZSBsZXZlbFxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQgdGhlIGxvZyBkZWNvcmF0b3IgdGhhdCB1c2VzIExvZ0xldmVsLnZlcmJvc2Ugd2l0aCBjb25maWd1cmFibGUgdmVyYm9zaXR5XG4gKiBAcGFyYW0ge251bWJlcn0gdmVyYm9zaXR5IC0gVGhlIHZlcmJvc2l0eSBsZXZlbCBmb3IgdGhlIGxvZyBtZXNzYWdlcyAoZGVmYXVsdDogMClcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2JlbmNobWFyaz1mYWxzZV0gLSBXaGV0aGVyIHRvIGxvZyBleGVjdXRpb24gdGltZSAoZGVmYXVsdDogZmFsc2UpXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIHZlcmJvc2UgbG9nZ2luZ1xuICogQGZ1bmN0aW9uIHZlcmJvc2VcbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyYm9zZSh2ZXJib3NpdHk6IG51bWJlciB8IGJvb2xlYW4gPSAwLCBiZW5jaG1hcms/OiBib29sZWFuKSB7XG4gIGlmICh0eXBlb2YgdmVyYm9zaXR5ID09PSBcImJvb2xlYW5cIikge1xuICAgIGJlbmNobWFyayA9IHZlcmJvc2l0eTtcbiAgICB2ZXJib3NpdHkgPSAwO1xuICB9XG4gIHJldHVybiBsb2coTG9nTGV2ZWwudmVyYm9zZSwgYmVuY2htYXJrLCB2ZXJib3NpdHkpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgZGVjb3JhdG9yIHRoYXQgbWFrZXMgYSBtZXRob2Qgbm9uLWNvbmZpZ3VyYWJsZVxuICogQHN1bW1hcnkgVGhpcyBkZWNvcmF0b3IgcHJldmVudHMgYSBtZXRob2QgZnJvbSBiZWluZyBvdmVycmlkZGVuIGJ5IG1ha2luZyBpdCBub24tY29uZmlndXJhYmxlLlxuICogSXQgdGhyb3dzIGFuIGVycm9yIGlmIHVzZWQgb24gYW55dGhpbmcgb3RoZXIgdGhhbiBhIG1ldGhvZC5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIGRlY29yYXRvciBmdW5jdGlvbiB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIG1ldGhvZHNcbiAqIEBmdW5jdGlvbiBmaW5hbFxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5hbCgpIHtcbiAgcmV0dXJuIChcbiAgICB0YXJnZXQ6IG9iamVjdCxcbiAgICBwcm9wZXJ0eUtleT86IGFueSxcbiAgICBkZXNjcmlwdG9yPzogUHJvcGVydHlEZXNjcmlwdG9yXG4gICkgPT4ge1xuICAgIGlmICghZGVzY3JpcHRvcilcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImZpbmFsIGRlY29yYXRvciBjYW4gb25seSBiZSB1c2VkIG9uIG1ldGhvZHNcIik7XG4gICAgaWYgKGRlc2NyaXB0b3I/LmNvbmZpZ3VyYWJsZSkge1xuICAgICAgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIGRlc2NyaXB0b3I7XG4gIH07XG59XG4iLCJpbXBvcnQgeyBMb2dGaWx0ZXIgfSBmcm9tIFwiLi9Mb2dGaWx0ZXJcIjtcbmltcG9ydCB7IExvZ2dpbmdDb25maWcgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IGZpbmFsIH0gZnJvbSBcIi4uL2RlY29yYXRvcnNcIjtcblxuZXhwb3J0IHR5cGUgUmVwbGFjZW1lbnRGdW5jdGlvbiA9IChzdWJzdHJpbmc6IHN0cmluZywgLi4uYXJnczogYW55W10pID0+IHN0cmluZztcblxuZXhwb3J0IGNsYXNzIFBhdHRlcm5GaWx0ZXIgZXh0ZW5kcyBMb2dGaWx0ZXIge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgcmVnZXhwOiBSZWdFeHAsXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IHJlcGxhY2VtZW50OiBzdHJpbmcgfCBSZXBsYWNlbWVudEZ1bmN0aW9uXG4gICkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBAZmluYWwoKVxuICBwcm90ZWN0ZWQgbWF0Y2gobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgY29uc3QgbWF0Y2ggPSB0aGlzLnJlZ2V4cC5leGVjKG1lc3NhZ2UpO1xuICAgIHRoaXMucmVnZXhwLmxhc3RJbmRleCA9IDA7XG4gICAgcmV0dXJuIG1hdGNoO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBmaWx0ZXIoY29uZmlnOiBMb2dnaW5nQ29uZmlnLCBtZXNzYWdlOiBzdHJpbmcsIGNvbnRleHQ6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5maWx0ZXIpO1xuICAgIGNvbnN0IG1hdGNoID0gdGhpcy5tYXRjaChtZXNzYWdlKTtcbiAgICBpZiAoIW1hdGNoKSByZXR1cm4gbWVzc2FnZTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIG1lc3NhZ2UucmVwbGFjZSh0aGlzLnJlZ2V4cCwgdGhpcy5yZXBsYWNlbWVudCBhcyBhbnkpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIGxvZy5lcnJvcihgUGF0dGVybkZpbHRlciByZXBsYWNlbWVudCBlcnJvcjogJHtlfWApO1xuICAgIH1cbiAgICByZXR1cm4gXCJcIjtcbiAgfVxufVxuIiwiZXhwb3J0ICogZnJvbSBcIi4vZmlsdGVyc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9lbnZpcm9ubWVudFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vTG9nZ2VkQ2xhc3NcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2xvZ2dpbmdcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3RleHRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGVzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi93ZWJcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQSBsb2dnaW5nIG1vZHVsZSBmb3IgVHlwZVNjcmlwdCBhcHBsaWNhdGlvbnNcbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIGEgY29tcHJlaGVuc2l2ZSwgZmxleGlibGUgbG9nZ2luZyBzb2x1dGlvbi4gVGhpcyBtb2R1bGUgZXhwb3NlczpcbiAqIC0gQ29yZSBjbGFzc2VzIGxpa2Uge0BsaW5rIExvZ2dpbmd9IGFuZCB7QGxpbmsgTWluaUxvZ2dlcn1cbiAqIC0gRGVjb3JhdG9ycyBzdWNoIGFzIHtAbGluayBsb2d9IGZvciBpbnN0cnVtZW50aW5nIG1ldGhvZHNcbiAqIC0gQ29uZmlndXJhdGlvbiBhbmQgY29uc3RhbnRzIGxpa2Uge0BsaW5rIExvZ0xldmVsfSBhbmQge0BsaW5rIERlZmF1bHRMb2dnaW5nQ29uZmlnfVxuICogLSBUeXBlIGRlZmluaXRpb25zIGluY2x1ZGluZyB7QGxpbmsgTG9nZ2VyfSBhbmQge0BsaW5rIExvZ2dpbmdDb25maWd9XG4gKiBUaGVzZSBleHBvcnRzIGVuYWJsZSBjb25zaXN0ZW50LCBjb250ZXh0LWF3YXJlLCBhbmQgb3B0aW9uYWxseSB0aGVtZWQgbG9nZ2luZyBhY3Jvc3MgcHJvamVjdHMuXG4gKiBAbW9kdWxlIExvZ2dpbmdcbiAqL1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDdXJyZW50IHBhY2thZ2UgdmVyc2lvbiBzdHJpbmdcbiAqIEBzdW1tYXJ5IFN0b3JlcyB0aGUgY3VycmVudCBwYWNrYWdlIHZlcnNpb24sIHVzZWQgZm9yIHZlcnNpb24gdHJhY2tpbmcgYW5kIGNvbXBhdGliaWxpdHkgY2hlY2tzXG4gKiBAY29uc3QgVkVSU0lPTlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gXCIjI1ZFUlNJT04jI1wiO1xuIl0sIm5hbWVzIjpbIkxvZ0xldmVsIiwiTG9nZ2luZ01vZGUiLCJPYmplY3RBY2N1bXVsYXRvciIsInN0eWxlIiwiX19kZWNvcmF0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBRU8sVUFBTSxhQUFhLEdBQUc7SUFFN0I7OztJQUdHO0FBQ0ksVUFBTSxrQkFBa0IsR0FBRztVQUVyQiwwQkFBMEIsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHO0lBRXBEOzs7Ozs7SUFNRztBQUNTQTtJQUFaLENBQUEsVUFBWSxRQUFRLEVBQUE7O0lBRWxCLElBQUEsUUFBQSxDQUFBLE9BQUEsQ0FBQSxHQUFBLE9BQWU7O0lBRWYsSUFBQSxRQUFBLENBQUEsTUFBQSxDQUFBLEdBQUEsTUFBYTs7SUFFYixJQUFBLFFBQUEsQ0FBQSxTQUFBLENBQUEsR0FBQSxTQUFtQjs7SUFFbkIsSUFBQSxRQUFBLENBQUEsT0FBQSxDQUFBLEdBQUEsT0FBZTs7SUFFZixJQUFBLFFBQUEsQ0FBQSxPQUFBLENBQUEsR0FBQSxPQUFlO0lBQ2pCLENBQUMsRUFYV0EsZ0JBQVEsS0FBUkEsZ0JBQVEsR0FXbkIsRUFBQSxDQUFBLENBQUE7SUFFRDs7Ozs7Ozs7OztJQVVHO0FBQ1UsVUFBQSxnQkFBZ0IsR0FBRztJQUM5QixJQUFBLEtBQUssRUFBRSxDQUFDO0lB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
|
|
1842
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2luZy5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvdGV4dC50cyIsIi4uL3NyYy93ZWIudHMiLCIuLi9zcmMvZW52aXJvbm1lbnQudHMiLCIuLi9zcmMvbG9nZ2luZy50cyIsIi4uL3NyYy9Mb2dnZWRDbGFzcy50cyIsIi4uL3NyYy9maWx0ZXJzL0xvZ0ZpbHRlci50cyIsIi4uL3NyYy90aW1lLnRzIiwiLi4vc3JjL2RlY29yYXRvcnMudHMiLCIuLi9zcmMvZmlsdGVycy9QYXR0ZXJuRmlsdGVyLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExvZ2dpbmdDb25maWcsIFRoZW1lIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gR2xvYmFsIGtleSB1c2VkIHRvIHN0b3JlIGVudmlyb25tZW50IHZhcmlhYmxlcyBpbiBicm93c2VyIGNvbnRleHRzLlxuICogQHN1bW1hcnkgRW5hYmxlcyB0aGUgbG9nZ2luZyBlbnZpcm9ubWVudCBoZWxwZXJzIHRvIGxvY2F0ZSBzZXJpYWxpemVkIGVudmlyb25tZW50IGNvbmZpZ3VyYXRpb24gb24gYGdsb2JhbFRoaXNgLlxuICogQGNvbnN0IEJyb3dzZXJFbnZLZXlcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGNvbnN0IEJyb3dzZXJFbnZLZXkgPSBcIkVOVlwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWxpbWl0ZXIgdXNlZCBmb3IgY29tcG9zaW5nIG5lc3RlZCBlbnZpcm9ubWVudCB2YXJpYWJsZSBuYW1lcy5cbiAqIEBzdW1tYXJ5IEpvaW5zIHBhcmVudCBhbmQgY2hpbGQga2V5cyB3aGVuIG1hcHBpbmcgb2JqZWN0IHBhdGhzIHRvIEVOViBzdHJpbmdzLlxuICogQGNvbnN0IEVOVl9QQVRIX0RFTElNSVRFUlxuICogQHR5cGUge3N0cmluZ31cbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3QgRU5WX1BBVEhfREVMSU1JVEVSID0gXCJfX1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IHByZWZpeCBhbmQgc3VmZml4IHVzZWQgZm9yIHRlbXBsYXRlIHBsYWNlaG9sZGVycy5cbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIHdyYXBwZXIgc3RyaW5ncyBhcHBsaWVkIHdoZW4gaW50ZXJwb2xhdGluZyBtZXNzYWdlcyB3aXRoIHtAbGluayBwYXRjaFBsYWNlaG9sZGVyc30uXG4gKiBAY29uc3QgRGVmYXVsdFBsYWNlaG9sZGVyV3JhcHBlcnNcbiAqIEB0eXBlIHtzdHJpbmdbXX1cbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3QgRGVmYXVsdFBsYWNlaG9sZGVyV3JhcHBlcnMgPSBbXCIke1wiLCBcIn1cIl07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVudW0gZm9yIGxvZyBsZXZlbHMuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGRpZmZlcmVudCBsZXZlbHMgb2YgbG9nZ2luZyBmb3IgdGhlIGFwcGxpY2F0aW9uLlxuICogQGVudW0ge3N0cmluZ31cbiAqIEByZWFkb25seVxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBlbnVtIExvZ0xldmVsIHtcbiAgLyoqIEBkZXNjcmlwdGlvbiBCZW5jaG1hcmsgZXZlbnRzIHRoYXQgY2FwdHVyZSBwZXJmb3JtYW5jZSBtZXRyaWNzLiAqL1xuICBiZW5jaG1hcmsgPSBcImJlbmNobWFya1wiLFxuICAvKiogQGRlc2NyaXB0aW9uIEVycm9yIGV2ZW50cyB0aGF0IGluZGljYXRlIGZhaWx1cmVzIHJlcXVpcmluZyBhdHRlbnRpb24uICovXG4gIGVycm9yID0gXCJlcnJvclwiLFxuICAvKiogQGRlc2NyaXB0aW9uIEluZm9ybWF0aW9uYWwgZXZlbnRzIGRlc2NyaWJpbmcgbm9ybWFsIG9wZXJhdGlvbi4gKi9cbiAgaW5mbyA9IFwiaW5mb1wiLFxuICAvKiogQGRlc2NyaXB0aW9uIFZlcmJvc2UgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiBmb3IgZGV0YWlsZWQgdHJhY2luZy4gKi9cbiAgdmVyYm9zZSA9IFwidmVyYm9zZVwiLFxuICAvKiogQGRlc2NyaXB0aW9uIERlYnVnIG9yIHRyYWNlIGRldGFpbHMgYWltZWQgYXQgZGV2ZWxvcGVycy4gKi9cbiAgZGVidWcgPSBcImRlYnVnXCIsXG4gIC8qKiBAZGVzY3JpcHRpb24gRXh0cmVtZWx5IGNoYXR0eSBvciBwbGF5ZnVsIGxvZyBlbnRyaWVzLiAqL1xuICBzaWxseSA9IFwic2lsbHlcIixcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTnVtZXJpYyB2YWx1ZXMgYXNzb2NpYXRlZCB3aXRoIGxvZyBsZXZlbHMuXG4gKiBAc3VtbWFyeSBQcm92aWRlcyBhIG51bWVyaWMgcmVwcmVzZW50YXRpb24gb2YgbG9nIGxldmVscyBmb3IgY29tcGFyaXNvbiBhbmQgZmlsdGVyaW5nLlxuICogQHR5cGVkZWYge09iamVjdH0gTnVtZXJpY0xvZ0xldmVsc1NoYXBlXG4gKiBAcHJvcGVydHkge251bWJlcn0gYmVuY2htYXJrIC0gTnVtZXJpYyB2YWx1ZSBmb3IgYmVuY2htYXJrIGxldmVsICgwKS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBlcnJvciAtIE51bWVyaWMgdmFsdWUgZm9yIGVycm9yIGxldmVsICgyKS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBpbmZvIC0gTnVtZXJpYyB2YWx1ZSBmb3IgaW5mbyBsZXZlbCAoNCkuXG4gKiBAcHJvcGVydHkge251bWJlcn0gdmVyYm9zZSAtIE51bWVyaWMgdmFsdWUgZm9yIHZlcmJvc2UgbGV2ZWwgKDYpLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGRlYnVnIC0gTnVtZXJpYyB2YWx1ZSBmb3IgZGVidWcgbGV2ZWwgKDcpLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IHNpbGx5IC0gTnVtZXJpYyB2YWx1ZSBmb3Igc2lsbHkgbGV2ZWwgKDkpLlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbi8qKlxuICogQGRlc2NyaXB0aW9uIE51bWVyaWMgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBsb2cgbGV2ZWxzLlxuICogQHN1bW1hcnkgUHJvdmlkZXMgYSBudW1lcmljIHJlcHJlc2VudGF0aW9uIG9mIGxvZyBsZXZlbHMgZm9yIGNvbXBhcmlzb24gYW5kIGZpbHRlcmluZy5cbiAqIEBjb25zdCBOdW1lcmljTG9nTGV2ZWxzXG4gKiBAdHlwZSB7TnVtZXJpY0xvZ0xldmVsc1NoYXBlfVxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBOdW1lcmljTG9nTGV2ZWxzID0ge1xuICBiZW5jaG1hcms6IDAsXG4gIGVycm9yOiAyLFxuICBpbmZvOiA0LFxuICB2ZXJib3NlOiA2LFxuICBkZWJ1ZzogNyxcbiAgc2lsbHk6IDksXG59O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFbnVtIGZvciBsb2dnaW5nIG91dHB1dCBtb2Rlcy5cbiAqIEBzdW1tYXJ5IERlZmluZXMgZGlmZmVyZW50IG91dHB1dCBmb3JtYXRzIGZvciBsb2cgbWVzc2FnZXMuXG4gKiBAZW51bSB7c3RyaW5nfVxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBlbnVtIExvZ2dpbmdNb2RlIHtcbiAgLyoqIFJhdyB0ZXh0IGZvcm1hdCBmb3IgaHVtYW4gcmVhZGFiaWxpdHkgKi9cbiAgUkFXID0gXCJyYXdcIixcbiAgLyoqIEpTT04gZm9ybWF0IGZvciBtYWNoaW5lIHBhcnNpbmcgKi9cbiAgSlNPTiA9IFwianNvblwiLFxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IHRoZW1lIGZvciBzdHlsaW5nIGxvZyBvdXRwdXQuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBkZWZhdWx0IGNvbG9yIGFuZCBzdHlsZSBzZXR0aW5ncyBmb3IgdmFyaW91cyBjb21wb25lbnRzIG9mIGxvZyBtZXNzYWdlcy5cbiAqIEB0eXBlZGVmIHtUaGVtZX0gRGVmYXVsdFRoZW1lXG4gKiBAcHJvcGVydHkge09iamVjdH0gY2xhc3MgLSBTdHlsaW5nIGZvciBjbGFzcyBuYW1lcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjbGFzcy5mZyAtIEZvcmVncm91bmQgY29sb3IgY29kZSBmb3IgY2xhc3MgbmFtZXMgKDM0KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBpZCAtIFN0eWxpbmcgZm9yIGlkZW50aWZpZXJzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGlkLmZnIC0gRm9yZWdyb3VuZCBjb2xvciBjb2RlIGZvciBpZGVudGlmaWVycyAoMzYpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IHN0YWNrIC0gU3R5bGluZyBmb3Igc3RhY2sgdHJhY2VzIChlbXB0eSBvYmplY3QpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IHRpbWVzdGFtcCAtIFN0eWxpbmcgZm9yIHRpbWVzdGFtcHMgKGVtcHR5IG9iamVjdCkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbWVzc2FnZSAtIFN0eWxpbmcgZm9yIGRpZmZlcmVudCB0eXBlcyBvZiBtZXNzYWdlcy5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBtZXNzYWdlLmVycm9yIC0gU3R5bGluZyBmb3IgZXJyb3IgbWVzc2FnZXMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gbWVzc2FnZS5lcnJvci5mZyAtIEZvcmVncm91bmQgY29sb3IgY29kZSBmb3IgZXJyb3IgbWVzc2FnZXMgKDMxKS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBtZXRob2QgLSBTdHlsaW5nIGZvciBtZXRob2QgbmFtZXMgKGVtcHR5IG9iamVjdCkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nTGV2ZWwgLSBTdHlsaW5nIGZvciBkaWZmZXJlbnQgbG9nIGxldmVscy5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2dMZXZlbC5lcnJvciAtIFN0eWxpbmcgZm9yIGVycm9yIGxldmVsIGxvZ3MuXG4gKiBAcHJvcGVydHkge251bWJlcn0gbG9nTGV2ZWwuZXJyb3IuZmcgLSBGb3JlZ3JvdW5kIGNvbG9yIGNvZGUgZm9yIGVycm9yIGxldmVsIGxvZ3MgKDMxKS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IGxvZ0xldmVsLmVycm9yLnN0eWxlIC0gU3R5bGUgYXR0cmlidXRlcyBmb3IgZXJyb3IgbGV2ZWwgbG9ncyAoW1wiYm9sZFwiXSkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nTGV2ZWwuaW5mbyAtIFN0eWxpbmcgZm9yIGluZm8gbGV2ZWwgbG9ncyAoZW1wdHkgb2JqZWN0KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2dMZXZlbC52ZXJib3NlIC0gU3R5bGluZyBmb3IgdmVyYm9zZSBsZXZlbCBsb2dzIChlbXB0eSBvYmplY3QpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGxvZ0xldmVsLmRlYnVnIC0gU3R5bGluZyBmb3IgZGVidWcgbGV2ZWwgbG9ncy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsb2dMZXZlbC5kZWJ1Zy5mZyAtIEZvcmVncm91bmQgY29sb3IgY29kZSBmb3IgZGVidWcgbGV2ZWwgbG9ncyAoMzMpLlxuICogQGNvbnN0IERlZmF1bHRUaGVtZVxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBEZWZhdWx0VGhlbWU6IFRoZW1lID0ge1xuICBhcHA6IHt9LFxuICBzZXBhcmF0b3I6IHt9LFxuICBjbGFzczoge1xuICAgIGZnOiAzNCxcbiAgfSxcbiAgaWQ6IHtcbiAgICBmZzogMzYsXG4gIH0sXG4gIHN0YWNrOiB7fSxcbiAgdGltZXN0YW1wOiB7fSxcbiAgbWVzc2FnZToge1xuICAgIGVycm9yOiB7XG4gICAgICBmZzogMzEsXG4gICAgfSxcbiAgfSxcbiAgbWV0aG9kOiB7fSxcbiAgbG9nTGV2ZWw6IHtcbiAgICBiZW5jaG1hcms6IHtcbiAgICAgIGZnOiAzMixcbiAgICAgIHN0eWxlOiBbXCJib2xkXCJdLFxuICAgIH0sXG4gICAgZXJyb3I6IHtcbiAgICAgIGZnOiAzMSxcbiAgICAgIHN0eWxlOiBbXCJib2xkXCJdLFxuICAgIH0sXG4gICAgaW5mbzoge1xuICAgICAgZmc6IDM0LFxuICAgICAgc3R5bGU6IFtcImJvbGRcIl0sXG4gICAgfSxcbiAgICB2ZXJib3NlOiB7XG4gICAgICBmZzogMzQsXG4gICAgICBzdHlsZTogW1wiYm9sZFwiXSxcbiAgICB9LFxuICAgIGRlYnVnOiB7XG4gICAgICBmZzogMzMsXG4gICAgICBzdHlsZTogW1wiYm9sZFwiXSxcbiAgICB9LFxuICB9LFxufTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVmYXVsdCBjb25maWd1cmF0aW9uIGZvciBsb2dnaW5nLlxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgZGVmYXVsdCBzZXR0aW5ncyBmb3IgdGhlIGxvZ2dpbmcgc3lzdGVtLCBpbmNsdWRpbmcgdmVyYm9zaXR5LCBsb2cgbGV2ZWwsIHN0eWxpbmcsIGFuZCB0aW1lc3RhbXAgZm9ybWF0LlxuICogQGNvbnN0IERlZmF1bHRMb2dnaW5nQ29uZmlnXG4gKiBAdHlwZWRlZiB7TG9nZ2luZ0NvbmZpZ30gRGVmYXVsdExvZ2dpbmdDb25maWdcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB2ZXJib3NlIC0gVmVyYm9zaXR5IGxldmVsICgwKS5cbiAqIEBwcm9wZXJ0eSB7TG9nTGV2ZWx9IGxldmVsIC0gRGVmYXVsdCBsb2cgbGV2ZWwgKExvZ0xldmVsLmluZm8pLlxuICogQHByb3BlcnR5IHtib29sZWFufSBsb2dMZXZlbCAtIFdoZXRoZXIgdG8gZGlzcGxheSBsb2cgbGV2ZWwgaW4gb3V0cHV0ICh0cnVlKS5cbiAqIEBwcm9wZXJ0eSB7TG9nZ2luZ01vZGV9IG1vZGUgLSBPdXRwdXQgZm9ybWF0IG1vZGUgKExvZ2dpbmdNb2RlLlJBVykuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHN0eWxlIC0gV2hldGhlciB0byBhcHBseSBzdHlsaW5nIHRvIGxvZyBvdXRwdXQgKGZhbHNlKS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzZXBhcmF0b3IgLSBTZXBhcmF0b3IgYmV0d2VlbiBsb2cgY29tcG9uZW50cyAoXCIgLSBcIikuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHRpbWVzdGFtcCAtIFdoZXRoZXIgdG8gaW5jbHVkZSB0aW1lc3RhbXBzIGluIGxvZyBtZXNzYWdlcyAodHJ1ZSkuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdGltZXN0YW1wRm9ybWF0IC0gRm9ybWF0IGZvciB0aW1lc3RhbXBzIChcIkhIOm1tOnNzLlNTU1wiKS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gY29udGV4dCAtIFdoZXRoZXIgdG8gaW5jbHVkZSBjb250ZXh0IGluZm9ybWF0aW9uIGluIGxvZyBtZXNzYWdlcyAodHJ1ZSkuXG4gKiBAcHJvcGVydHkge1RoZW1lfSB0aGVtZSAtIFRoZSB0aGVtZSB0byB1c2UgZm9yIHN0eWxpbmcgbG9nIG1lc3NhZ2VzIChEZWZhdWx0VGhlbWUpLlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBEZWZhdWx0TG9nZ2luZ0NvbmZpZzogTG9nZ2luZ0NvbmZpZyA9IHtcbiAgZW52OiBcImRldmVsb3BtZW50XCIsXG4gIHZlcmJvc2U6IDAsXG4gIGxldmVsOiBMb2dMZXZlbC5pbmZvLFxuICBsb2dMZXZlbDogdHJ1ZSxcbiAgc3R5bGU6IGZhbHNlLFxuICBjb250ZXh0U2VwYXJhdG9yOiBcIi5cIixcbiAgc2VwYXJhdG9yOiBcIi1cIixcbiAgdGltZXN0YW1wOiB0cnVlLFxuICB0aW1lc3RhbXBGb3JtYXQ6IFwiSEg6bW06c3MuU1NTXCIsXG4gIGNvbnRleHQ6IHRydWUsXG4gIGZvcm1hdDogTG9nZ2luZ01vZGUuUkFXLFxuICBwYXR0ZXJuOlxuICAgIFwie2xldmVsfSBbe3RpbWVzdGFtcH1dIHthcHB9IHtjb250ZXh0fSB7c2VwYXJhdG9yfSB7bWVzc2FnZX0ge3N0YWNrfVwiLFxuICB0aGVtZTogRGVmYXVsdFRoZW1lLFxufTtcbiIsImltcG9ydCB7IERlZmF1bHRQbGFjZWhvbGRlcldyYXBwZXJzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFBhZHMgdGhlIGVuZCBvZiBhIHN0cmluZyB3aXRoIGEgc3BlY2lmaWVkIGNoYXJhY3Rlci5cbiAqIEBzdW1tYXJ5IEV4dGVuZHMgdGhlIGlucHV0IHN0cmluZyB0byBhIHNwZWNpZmllZCBsZW5ndGggYnkgYWRkaW5nIGEgcGFkZGluZyBjaGFyYWN0ZXIgdG8gdGhlIGVuZC5cbiAqIElmIHRoZSBpbnB1dCBzdHJpbmcgaXMgYWxyZWFkeSBsb25nZXIgdGhhbiB0aGUgc3BlY2lmaWVkIGxlbmd0aCwgaXQgaXMgcmV0dXJuZWQgdW5jaGFuZ2VkLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBUaGUgaW5wdXQgc3RyaW5nIHRvIGJlIHBhZGRlZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggLSBUaGUgZGVzaXJlZCB0b3RhbCBsZW5ndGggb2YgdGhlIHJlc3VsdGluZyBzdHJpbmcuXG4gKiBAcGFyYW0ge3N0cmluZ30gW2NoYXI9XCIgXCJdIC0gVGhlIGNoYXJhY3RlciB0byB1c2UgZm9yIHBhZGRpbmcuIERlZmF1bHRzIHRvIGEgc3BhY2UuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBwYWRkZWQgc3RyaW5nLlxuICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYWRkaW5nIGNoYXJhY3RlciBpcyBub3QgZXhhY3RseSBvbmUgY2hhcmFjdGVyIGxvbmcuXG4gKlxuICogQGZ1bmN0aW9uIHBhZEVuZFxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGFkRW5kKFxuICBzdHI6IHN0cmluZyxcbiAgbGVuZ3RoOiBudW1iZXIsXG4gIGNoYXI6IHN0cmluZyA9IFwiIFwiXG4pOiBzdHJpbmcge1xuICBpZiAoY2hhci5sZW5ndGggIT09IDEpXG4gICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBjaGFyYWN0ZXIgbGVuZ3RoIGZvciBwYWRkaW5nLiBtdXN0IGJlIG9uZSFcIik7XG4gIHJldHVybiBzdHIucGFkRW5kKGxlbmd0aCwgY2hhcik7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFJlcGxhY2VzIHBsYWNlaG9sZGVycyBpbiBhIHN0cmluZyB3aXRoIHByb3ZpZGVkIHZhbHVlcy5cbiAqIEBzdW1tYXJ5IEludGVycG9sYXRlcyBhIHN0cmluZyBieSByZXBsYWNpbmcgcGxhY2Vob2xkZXJzIG9mIHRoZSBmb3JtICR7dmFyaWFibGVOYW1lfVxuICogd2l0aCBjb3JyZXNwb25kaW5nIHZhbHVlcyBmcm9tIHRoZSBwcm92aWRlZCBvYmplY3QuIElmIGEgcGxhY2Vob2xkZXIgZG9lc24ndCBoYXZlXG4gKiBhIGNvcnJlc3BvbmRpbmcgdmFsdWUsIGl0IGlzIGxlZnQgdW5jaGFuZ2VkIGluIHRoZSBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0IC0gVGhlIGlucHV0IHN0cmluZyBjb250YWluaW5nIHBsYWNlaG9sZGVycyB0byBiZSByZXBsYWNlZC5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPn0gdmFsdWVzIC0gQW4gb2JqZWN0IGNvbnRhaW5pbmcga2V5LXZhbHVlIHBhaXJzIGZvciByZXBsYWNlbWVudC5cbiAqIEBwYXJhbSBwcmVmaXhcbiAqIEBwYXJhbSBzdWZmaXhcbiAqIEBwYXJhbSBmbGFnc1xuICogQHJldHVybiB7c3RyaW5nfSBUaGUgaW50ZXJwb2xhdGVkIHN0cmluZyB3aXRoIHBsYWNlaG9sZGVycyByZXBsYWNlZCBieSB0aGVpciBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAqXG4gKiBAZnVuY3Rpb24gcGF0Y2hQbGFjZWhvbGRlcnNcbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICogICBwYXJ0aWNpcGFudCBwYXRjaFN0cmluZ1xuICogICBwYXJ0aWNpcGFudCBTdHJpbmcucmVwbGFjZVxuICogICBDYWxsZXItPj5wYXRjaFN0cmluZzogQ2FsbCB3aXRoIGlucHV0IGFuZCB2YWx1ZXNcbiAqICAgcGF0Y2hTdHJpbmctPj5TdHJpbmcucmVwbGFjZTogQ2FsbCB3aXRoIHJlZ2V4IGFuZCByZXBsYWNlbWVudCBmdW5jdGlvblxuICogICBTdHJpbmcucmVwbGFjZS0+PnBhdGNoU3RyaW5nOiBSZXR1cm4gcmVwbGFjZWQgc3RyaW5nXG4gKiAgIHBhdGNoU3RyaW5nLS0+PkNhbGxlcjogUmV0dXJuIHBhdGNoZWQgc3RyaW5nXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXRjaFBsYWNlaG9sZGVycyhcbiAgaW5wdXQ6IHN0cmluZyxcbiAgdmFsdWVzOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXIgfCBzdHJpbmc+LFxuICBwcmVmaXg6IHN0cmluZyA9IERlZmF1bHRQbGFjZWhvbGRlcldyYXBwZXJzWzBdLFxuICBzdWZmaXg6IHN0cmluZyA9IERlZmF1bHRQbGFjZWhvbGRlcldyYXBwZXJzWzFdLFxuICBmbGFnczogc3RyaW5nID0gXCJnXCJcbik6IHN0cmluZyB7XG4gIGNvbnN0IHBsYWNlaG9sZGVycyA9IE9iamVjdC5lbnRyaWVzKHZhbHVlcykucmVkdWNlKFxuICAgIChhY2M6IFJlY29yZDxzdHJpbmcsIGFueT4sIFtrZXksIHZhbF0pID0+IHtcbiAgICAgIGFjY1tgJHtwcmVmaXh9JHtrZXl9JHtzdWZmaXh9YF0gPSB2YWw7XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sXG4gICAge31cbiAgKTtcbiAgcmV0dXJuIHBhdGNoU3RyaW5nKGlucHV0LCBwbGFjZWhvbGRlcnMsIGZsYWdzKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmVwbGFjZXMgb2NjdXJyZW5jZXMgb2Yga2V5cyB3aXRoIHRoZWlyIGNvcnJlc3BvbmRpbmcgdmFsdWVzIGluIGEgc3RyaW5nLlxuICogQHN1bW1hcnkgSXRlcmF0ZXMgdGhyb3VnaCBhIHNldCBvZiBrZXktdmFsdWUgcGFpcnMgYW5kIHJlcGxhY2VzIGFsbCBvY2N1cnJlbmNlcyBvZiBlYWNoIGtleVxuICogaW4gdGhlIGlucHV0IHN0cmluZyB3aXRoIGl0cyBjb3JyZXNwb25kaW5nIHZhbHVlLiBTdXBwb3J0cyByZWd1bGFyIGV4cHJlc3Npb24gZmxhZ3MgZm9yIGN1c3RvbWl6ZWQgcmVwbGFjZW1lbnQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0IC0gVGhlIGlucHV0IHN0cmluZyBpbiB3aGljaCByZXBsYWNlbWVudHMgd2lsbCBiZSBtYWRlLlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBudW1iZXIgfCBzdHJpbmc+fSB2YWx1ZXMgLSBBbiBvYmplY3QgY29udGFpbmluZyBrZXktdmFsdWUgcGFpcnMgZm9yIHJlcGxhY2VtZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IFtmbGFncz1cImdcIl0gLSBSZWd1bGFyIGV4cHJlc3Npb24gZmxhZ3MgdG8gY29udHJvbCB0aGUgcmVwbGFjZW1lbnQgYmVoYXZpb3IuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBzdHJpbmcgd2l0aCBhbGwgc3BlY2lmaWVkIHJlcGxhY2VtZW50cyBhcHBsaWVkLlxuICpcbiAqIEBmdW5jdGlvbiBwYXRjaFN0cmluZ1xuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGF0Y2hTdHJpbmcoXG4gIGlucHV0OiBzdHJpbmcsXG4gIHZhbHVlczogUmVjb3JkPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPixcbiAgZmxhZ3M6IHN0cmluZyA9IFwiZ1wiXG4pOiBzdHJpbmcge1xuICBPYmplY3QuZW50cmllcyh2YWx1ZXMpLmZvckVhY2goKFtrZXksIHZhbF0pID0+IHtcbiAgICBjb25zdCByZWdleHAgPSBuZXcgUmVnRXhwKGVzY2FwZVJlZ0V4cChrZXkpLCBmbGFncyk7XG4gICAgaW5wdXQgPSBpbnB1dC5yZXBsYWNlKHJlZ2V4cCwgdmFsIGFzIHN0cmluZyk7XG4gIH0pO1xuICByZXR1cm4gaW5wdXQ7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvbnZlcnRzIGEgc3RyaW5nIHRvIGNhbWVsQ2FzZS5cbiAqIEBzdW1tYXJ5IFRyYW5zZm9ybXMgdGhlIGlucHV0IHN0cmluZyBpbnRvIGNhbWVsQ2FzZSBmb3JtYXQsIHdoZXJlIHdvcmRzIGFyZSBqb2luZWQgd2l0aG91dCBzcGFjZXNcbiAqIGFuZCBlYWNoIHdvcmQgYWZ0ZXIgdGhlIGZpcnN0IHN0YXJ0cyB3aXRoIGEgY2FwaXRhbCBsZXR0ZXIuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUaGUgaW5wdXQgc3RyaW5nIHRvIGJlIGNvbnZlcnRlZC5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGlucHV0IHN0cmluZyBjb252ZXJ0ZWQgdG8gY2FtZWxDYXNlLlxuICpcbiAqIEBmdW5jdGlvbiB0b0NhbWVsQ2FzZVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gdG9DYW1lbENhc2UodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHRleHRcbiAgICAucmVwbGFjZSgvKD86Xlxcd3xbQS1aXXxcXGJcXHcpL2csICh3b3JkLCBpbmRleCkgPT5cbiAgICAgIGluZGV4ID09PSAwID8gd29yZC50b0xvd2VyQ2FzZSgpIDogd29yZC50b1VwcGVyQ2FzZSgpXG4gICAgKVxuICAgIC5yZXBsYWNlKC9cXHMrL2csIFwiXCIpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBhIHN0cmluZyB0byBFTlZJUk9OTUVOVF9WQVJJQUJMRSBmb3JtYXQuXG4gKiBAc3VtbWFyeSBUcmFuc2Zvcm1zIHRoZSBpbnB1dCBzdHJpbmcgaW50byB1cHBlcmNhc2Ugd2l0aCB3b3JkcyBzZXBhcmF0ZWQgYnkgdW5kZXJzY29yZXMsXG4gKiB0eXBpY2FsbHkgdXNlZCBmb3IgZW52aXJvbm1lbnQgdmFyaWFibGUgbmFtZXMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUaGUgaW5wdXQgc3RyaW5nIHRvIGJlIGNvbnZlcnRlZC5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGlucHV0IHN0cmluZyBjb252ZXJ0ZWQgdG8gRU5WSVJPTk1FTlRfVkFSSUFCTEUgZm9ybWF0LlxuICpcbiAqIEBmdW5jdGlvbiB0b0VOVkZvcm1hdFxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gdG9FTlZGb3JtYXQodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHRvU25ha2VDYXNlKHRleHQpLnRvVXBwZXJDYXNlKCk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvbnZlcnRzIGEgc3RyaW5nIHRvIHNuYWtlX2Nhc2UuXG4gKiBAc3VtbWFyeSBUcmFuc2Zvcm1zIHRoZSBpbnB1dCBzdHJpbmcgaW50byBsb3dlcmNhc2Ugd2l0aCB3b3JkcyBzZXBhcmF0ZWQgYnkgdW5kZXJzY29yZXMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUaGUgaW5wdXQgc3RyaW5nIHRvIGJlIGNvbnZlcnRlZC5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGlucHV0IHN0cmluZyBjb252ZXJ0ZWQgdG8gc25ha2VfY2FzZS5cbiAqXG4gKiBAZnVuY3Rpb24gdG9TbmFrZUNhc2VcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvU25ha2VDYXNlKHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB0ZXh0XG4gICAgLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csIFwiJDFfJDJcIilcbiAgICAucmVwbGFjZSgvW1xccy1dKy9nLCBcIl9cIilcbiAgICAudG9Mb3dlckNhc2UoKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29udmVydHMgYSBzdHJpbmcgdG8ga2ViYWItY2FzZS5cbiAqIEBzdW1tYXJ5IFRyYW5zZm9ybXMgdGhlIGlucHV0IHN0cmluZyBpbnRvIGxvd2VyY2FzZSB3aXRoIHdvcmRzIHNlcGFyYXRlZCBieSBoeXBoZW5zLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGhlIGlucHV0IHN0cmluZyB0byBiZSBjb252ZXJ0ZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBpbnB1dCBzdHJpbmcgY29udmVydGVkIHRvIGtlYmFiLWNhc2UuXG4gKlxuICogQGZ1bmN0aW9uIHRvS2ViYWJDYXNlXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0tlYmFiQ2FzZSh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdGV4dFxuICAgIC5yZXBsYWNlKC8oW2Etel0pKFtBLVpdKS9nLCBcIiQxLSQyXCIpXG4gICAgLnJlcGxhY2UoL1tcXHNfXSsvZywgXCItXCIpXG4gICAgLnRvTG93ZXJDYXNlKCk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvbnZlcnRzIGEgc3RyaW5nIHRvIFBhc2NhbENhc2UuXG4gKiBAc3VtbWFyeSBUcmFuc2Zvcm1zIHRoZSBpbnB1dCBzdHJpbmcgaW50byBQYXNjYWxDYXNlIGZvcm1hdCwgd2hlcmUgd29yZHMgYXJlIGpvaW5lZCB3aXRob3V0IHNwYWNlc1xuICogYW5kIGVhY2ggd29yZCBzdGFydHMgd2l0aCBhIGNhcGl0YWwgbGV0dGVyLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGhlIGlucHV0IHN0cmluZyB0byBiZSBjb252ZXJ0ZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBpbnB1dCBzdHJpbmcgY29udmVydGVkIHRvIFBhc2NhbENhc2UuXG4gKlxuICogQGZ1bmN0aW9uIHRvUGFzY2FsQ2FzZVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gdG9QYXNjYWxDYXNlKHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB0ZXh0XG4gICAgLnJlcGxhY2UoLyg/Ol5cXHd8W0EtWl18XFxiXFx3KS9nLCAod29yZCkgPT4gd29yZC50b1VwcGVyQ2FzZSgpKVxuICAgIC5yZXBsYWNlKC9cXHMrL2csIFwiXCIpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFc2NhcGVzIHNwZWNpYWwgY2hhcmFjdGVycyBpbiBhIHN0cmluZyBmb3IgdXNlIGluIGEgcmVndWxhciBleHByZXNzaW9uLlxuICogQHN1bW1hcnkgQWRkcyBiYWNrc2xhc2hlcyBiZWZvcmUgY2hhcmFjdGVycyB0aGF0IGhhdmUgc3BlY2lhbCBtZWFuaW5nIGluIHJlZ3VsYXIgZXhwcmVzc2lvbnMsXG4gKiBhbGxvd2luZyB0aGUgc3RyaW5nIHRvIGJlIHVzZWQgYXMgYSBsaXRlcmFsIG1hdGNoIGluIGEgUmVnRXhwLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgLSBUaGUgc3RyaW5nIHRvIGVzY2FwZSBmb3IgcmVndWxhciBleHByZXNzaW9uIHVzZS5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGVzY2FwZWQgc3RyaW5nIHNhZmUgZm9yIHVzZSBpbiByZWd1bGFyIGV4cHJlc3Npb25zLlxuICpcbiAqIEBmdW5jdGlvbiBlc2NhcGVSZWdFeHBcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVzY2FwZVJlZ0V4cChzdHJpbmc6IHN0cmluZykge1xuICByZXR1cm4gc3RyaW5nLnJlcGxhY2UoL1suKis/XiR7fSgpfFtcXF1cXFxcXS9nLCBcIlxcXFwkJlwiKTsgLy8gJCYgbWVhbnMgdGhlIHdob2xlIG1hdGNoZWQgc3RyaW5nXG59XG5cbi8qKlxuICogQHN1bW1hcnkgVXRpbCBmdW5jdGlvbiB0byBwcm92aWRlIHN0cmluZyBmb3JtYXQgZnVuY3Rpb25hbGl0eSBzaW1pbGFyIHRvIEMjJ3Mgc3RyaW5nLmZvcm1hdFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmdcbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nIHwgbnVtYmVyPiB8IFJlY29yZDxzdHJpbmcsIGFueT59IFthcmdzXSByZXBsYWNlbWVudHMgbWFkZSBieSBvcmRlciBvZiBhcHBlYXJhbmNlIChyZXBsYWNlbWVudDAgd2lsIHJlcGxhY2UgezB9IGFuZCBzbyBvbilcbiAqIEByZXR1cm4ge3N0cmluZ30gZm9ybWF0dGVkIHN0cmluZ1xuICpcbiAqIEBmdW5jdGlvbiBzZlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZihcbiAgc3RyaW5nOiBzdHJpbmcsXG4gIC4uLmFyZ3M6IChzdHJpbmcgfCBudW1iZXIgfCBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtdXG4pIHtcbiAgaWYgKGFyZ3MubGVuZ3RoID4gMSkge1xuICAgIGlmIChcbiAgICAgICFhcmdzLmV2ZXJ5KChhcmcpID0+IHR5cGVvZiBhcmcgPT09IFwic3RyaW5nXCIgfHwgdHlwZW9mIGFyZyA9PT0gXCJudW1iZXJcIilcbiAgICApXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBPbmx5IHN0cmluZyBhbmQgbnVtYmVyIGFyZ3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBtdWx0aXBsZSByZXBsYWNlbWVudHMuYFxuICAgICAgKTtcbiAgfVxuXG4gIGlmIChhcmdzLmxlbmd0aCA9PT0gMSAmJiB0eXBlb2YgYXJnc1swXSA9PT0gXCJvYmplY3RcIikge1xuICAgIGNvbnN0IG9iaiA9IGFyZ3NbMF0gYXMgUmVjb3JkPHN0cmluZywgYW55PjtcbiAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMob2JqKS5yZWR1Y2UoKGFjYywgW2tleSwgdmFsXSkgPT4ge1xuICAgICAgcmV0dXJuIGFjYy5yZXBsYWNlKG5ldyBSZWdFeHAoYFxcXFx7JHtrZXl9XFxcXH1gLCBcImdcIiksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgIH0pO1xuICAgIH0sIHN0cmluZyk7XG4gIH1cblxuICByZXR1cm4gc3RyaW5nLnJlcGxhY2UoL3soXFxkKyl9L2csIGZ1bmN0aW9uIChtYXRjaCwgbnVtYmVyKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBhcmdzW251bWJlcl0gIT09IFwidW5kZWZpbmVkXCJcbiAgICAgID8gYXJnc1tudW1iZXJdLnRvU3RyaW5nKClcbiAgICAgIDogXCJ1bmRlZmluZWRcIjtcbiAgfSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgVXRpbCBmdW5jdGlvbiB0byBwcm92aWRlIHN0cmluZyBmb3JtYXQgZnVuY3Rpb25hbGl0eSBzaW1pbGFyIHRvIEMjJ3Mgc3RyaW5nLmZvcm1hdFxuICpcbiAqIEBzZWUgc2ZcbiAqXG4gKiBAZGVwcmVjYXRlZFxuICogQGZ1bmN0aW9uIHN0cmluZ0Zvcm1hdFxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBzdHJpbmdGb3JtYXQgPSBzZjtcbiIsIi8qKlxuICogQGRlc2NyaXB0aW9uIERldGVybWluZXMgaWYgdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQgaXMgYSBicm93c2VyIGJ5IGNoZWNraW5nIHRoZSBwcm90b3R5cGUgY2hhaW4gb2YgdGhlIGdsb2JhbCBvYmplY3QuXG4gKiBAc3VtbWFyeSBDaGVja3MgaWYgdGhlIGNvZGUgaXMgcnVubmluZyBpbiBhIGJyb3dzZXIgZW52aXJvbm1lbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBlbnZpcm9ubWVudCBpcyBhIGJyb3dzZXIsIGZhbHNlIG90aGVyd2lzZS5cbiAqIEBmdW5jdGlvbiBpc0Jyb3dzZXJcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gaXNCcm93c2VyKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIE9iamVjdC5nZXRQcm90b3R5cGVPZihPYmplY3QuZ2V0UHJvdG90eXBlT2YoZ2xvYmFsVGhpcykpICE9PVxuICAgIE9iamVjdC5wcm90b3R5cGVcbiAgKTtcbn1cbiIsImltcG9ydCB7IE9iamVjdEFjY3VtdWxhdG9yIH0gZnJvbSBcInR5cGVkLW9iamVjdC1hY2N1bXVsYXRvclwiO1xuaW1wb3J0IHsgdG9FTlZGb3JtYXQgfSBmcm9tIFwiLi90ZXh0XCI7XG5pbXBvcnQgeyBpc0Jyb3dzZXIgfSBmcm9tIFwiLi93ZWJcIjtcbmltcG9ydCB7XG4gIEJyb3dzZXJFbnZLZXksXG4gIERlZmF1bHRMb2dnaW5nQ29uZmlnLFxuICBFTlZfUEFUSF9ERUxJTUlURVIsXG59IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBGYWN0b3J5IHR5cGUgZm9yIGNyZWF0aW5nIEVudmlyb25tZW50IGluc3RhbmNlcy5cbiAqIEBzdW1tYXJ5IERlc2NyaWJlcyBmYWN0b3JpZXMgdGhhdCBjb25zdHJ1Y3Qge0BsaW5rIEVudmlyb25tZW50fSBkZXJpdmF0aXZlcyB3aXRoIGN1c3RvbSBpbml0aWFsaXphdGlvbi5cbiAqIEB0ZW1wbGF0ZSBUIC0gVGhlIHR5cGUgb2Ygb2JqZWN0IHRoZSBFbnZpcm9ubWVudCB3aWxsIGFjY3VtdWxhdGUuXG4gKiBAdGVtcGxhdGUgRSAtIFRoZSBzcGVjaWZpYyBFbnZpcm9ubWVudCB0eXBlIHRvIGJlIGNyZWF0ZWQsIGV4dGVuZGluZyBFbnZpcm9ubWVudDxUPi5cbiAqIEB0eXBlZGVmIHtmdW5jdGlvbih1bmtub3duW10pOiBFfSBFbnZpcm9ubWVudEZhY3RvcnlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgdHlwZSBFbnZpcm9ubWVudEZhY3Rvcnk8VCBleHRlbmRzIG9iamVjdCwgRSBleHRlbmRzIEVudmlyb25tZW50PFQ+PiA9IChcbiAgLi4uYXJnczogdW5rbm93bltdXG4pID0+IEU7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVudmlyb25tZW50IGFjY3VtdWxhdG9yIHRoYXQgbGF6aWx5IHJlYWRzIGZyb20gcnVudGltZSBzb3VyY2VzLlxuICogQHN1bW1hcnkgRXh0ZW5kcyB7QGxpbmsgT2JqZWN0QWNjdW11bGF0b3J9IHRvIG1lcmdlIGNvbmZpZ3VyYXRpb24gb2JqZWN0cyB3aGlsZSByZXNvbHZpbmcgdmFsdWVzIGZyb20gTm9kZSBvciBicm93c2VyIGVudmlyb25tZW50IHZhcmlhYmxlcyBvbiBkZW1hbmQuXG4gKiBAdGVtcGxhdGUgVFxuICogQGNsYXNzIEVudmlyb25tZW50XG4gKiBAZXhhbXBsZVxuICogY29uc3QgQ29uZmlnID0gRW52aXJvbm1lbnQuYWNjdW11bGF0ZSh7IGxvZ2dpbmc6IHsgbGV2ZWw6IFwiaW5mb1wiIH0gfSk7XG4gKiBjb25zb2xlLmxvZyhDb25maWcubG9nZ2luZy5sZXZlbCk7XG4gKiBjb25zb2xlLmxvZyhTdHJpbmcoQ29uZmlnLmxvZ2dpbmcubGV2ZWwpKTsgLy8gPT4gTE9HR0lOR19fTEVWRUwga2V5IHdoZW4gc2VyaWFsaXplZFxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgRW52IGFzIEVudmlyb25tZW50XG4gKiAgIHBhcnRpY2lwYW50IFByb2Nlc3MgYXMgcHJvY2Vzcy5lbnZcbiAqICAgcGFydGljaXBhbnQgQnJvd3NlciBhcyBnbG9iYWxUaGlzLkVOVlxuICogICBDbGllbnQtPj5FbnY6IGFjY3VtdWxhdGUocGFydGlhbENvbmZpZylcbiAqICAgRW52LT4+RW52OiBleHBhbmQodmFsdWVzKVxuICogICBDbGllbnQtPj5FbnY6IENvbmZpZy5sb2dnaW5nLmxldmVsXG4gKiAgIGFsdCBCcm93c2VyIHJ1bnRpbWVcbiAqICAgICBFbnYtPj5Ccm93c2VyOiBsb29rdXAgRU5WIGtleVxuICogICAgIEJyb3dzZXItLT4+RW52OiByZXNvbHZlZCB2YWx1ZVxuICogICBlbHNlIE5vZGUgcnVudGltZVxuICogICAgIEVudi0+PlByb2Nlc3M6IGxvb2t1cCBFTlYga2V5XG4gKiAgICAgUHJvY2Vzcy0tPj5FbnY6IHJlc29sdmVkIHZhbHVlXG4gKiAgIGVuZFxuICogICBFbnYtLT4+Q2xpZW50OiBtZXJnZWQgdmFsdWVcbiAqL1xuY29uc3QgRW1wdHlWYWx1ZSA9IFN5bWJvbChcIkVudmlyb25tZW50RW1wdHlcIik7XG5cbmV4cG9ydCBjbGFzcyBFbnZpcm9ubWVudDxUIGV4dGVuZHMgb2JqZWN0PiBleHRlbmRzIE9iamVjdEFjY3VtdWxhdG9yPFQ+IHtcbiAgLyoqXG4gICAqIEBzdGF0aWNcbiAgICogQHByb3RlY3RlZFxuICAgKiBAZGVzY3JpcHRpb24gQSBmYWN0b3J5IGZ1bmN0aW9uIGZvciBjcmVhdGluZyBFbnZpcm9ubWVudCBpbnN0YW5jZXMuXG4gICAqIEBzdW1tYXJ5IERlZmluZXMgaG93IG5ldyBpbnN0YW5jZXMgb2YgdGhlIEVudmlyb25tZW50IGNsYXNzIHNob3VsZCBiZSBjcmVhdGVkLlxuICAgKiBAcmV0dXJuIHtFbnZpcm9ubWVudDxhbnk+fSBBIG5ldyBpbnN0YW5jZSBvZiB0aGUgRW52aXJvbm1lbnQgY2xhc3MuXG4gICAqL1xuICBwcm90ZWN0ZWQgc3RhdGljIGZhY3Rvcnk6IEVudmlyb25tZW50RmFjdG9yeTxhbnksIGFueT4gPVxuICAgICgpOiBFbnZpcm9ubWVudDxhbnk+ID0+IG5ldyBFbnZpcm9ubWVudCgpO1xuXG4gIC8qKlxuICAgKiBAc3RhdGljXG4gICAqIEBwcml2YXRlXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgc2luZ2xldG9uIGluc3RhbmNlIG9mIHRoZSBFbnZpcm9ubWVudCBjbGFzcy5cbiAgICogQHR5cGUge0Vudmlyb25tZW50PGFueT59XG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBfaW5zdGFuY2U6IEVudmlyb25tZW50PGFueT47XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBhIHZhbHVlIGZyb20gdGhlIHJ1bnRpbWUgZW52aXJvbm1lbnQuXG4gICAqIEBzdW1tYXJ5IEhhbmRsZXMgYnJvd3NlciBhbmQgTm9kZS5qcyBlbnZpcm9ubWVudHMgYnkgbm9ybWFsaXppbmcga2V5cyBhbmQgcGFyc2luZyB2YWx1ZXMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrIC0gS2V5IHRvIHJlc29sdmUgZnJvbSB0aGUgZW52aXJvbm1lbnQuXG4gICAqIEByZXR1cm4ge3Vua25vd259IFZhbHVlIHJlc29sdmVkIGZyb20gdGhlIGVudmlyb25tZW50IG9yIGB1bmRlZmluZWRgIHdoZW4gYWJzZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIGZyb21FbnYoazogc3RyaW5nKSB7XG4gICAgbGV0IGVudjogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgaWYgKGlzQnJvd3NlcigpKSB7XG4gICAgICBlbnYgPVxuICAgICAgICAoXG4gICAgICAgICAgZ2xvYmFsVGhpcyBhcyB0eXBlb2YgZ2xvYmFsVGhpcyAmIHtcbiAgICAgICAgICAgIFtCcm93c2VyRW52S2V5XTogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgICAgICAgICB9XG4gICAgICAgIClbQnJvd3NlckVudktleV0gfHwge307XG4gICAgfSBlbHNlIHtcbiAgICAgIGVudiA9IGdsb2JhbFRoaXMucHJvY2Vzcy5lbnY7XG4gICAgICBrID0gdG9FTlZGb3JtYXQoayk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnBhcnNlRW52VmFsdWUoZW52W2tdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ29udmVydHMgc3RyaW5naWZpZWQgZW52aXJvbm1lbnQgdmFsdWVzIGludG8gbmF0aXZlIHR5cGVzLlxuICAgKiBAc3VtbWFyeSBJbnRlcnByZXRzIGJvb2xlYW5zIGFuZCBudW1iZXJzIHdoaWxlIGxlYXZpbmcgb3RoZXIgdHlwZXMgdW5jaGFuZ2VkLlxuICAgKiBAcGFyYW0ge3Vua25vd259IHZhbCAtIFJhdyB2YWx1ZSByZXRyaWV2ZWQgZnJvbSB0aGUgZW52aXJvbm1lbnQuXG4gICAqIEByZXR1cm4ge3Vua25vd259IFBhcnNlZCB2YWx1ZSBjb252ZXJ0ZWQgdG8gYm9vbGVhbiwgbnVtYmVyLCBvciBsZWZ0IGFzLWlzLlxuICAgKi9cbiAgcHJvdGVjdGVkIHBhcnNlRW52VmFsdWUodmFsOiB1bmtub3duKSB7XG4gICAgaWYgKHR5cGVvZiB2YWwgIT09IFwic3RyaW5nXCIpIHJldHVybiB2YWw7XG4gICAgaWYgKHZhbCA9PT0gXCJ0cnVlXCIpIHJldHVybiB0cnVlO1xuICAgIGlmICh2YWwgPT09IFwiZmFsc2VcIikgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IHJlc3VsdCA9IHBhcnNlRmxvYXQodmFsKTtcbiAgICBpZiAoIWlzTmFOKHJlc3VsdCkpIHJldHVybiByZXN1bHQ7XG4gICAgcmV0dXJuIHZhbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRXhwYW5kcyBhbiBvYmplY3QgaW50byB0aGUgZW52aXJvbm1lbnQuXG4gICAqIEBzdW1tYXJ5IERlZmluZXMgbGF6eSBwcm9wZXJ0aWVzIHRoYXQgZmlyc3QgY29uc3VsdCBydW50aW1lIHZhcmlhYmxlcyBiZWZvcmUgZmFsbGluZyBiYWNrIHRvIHNlZWRlZCB2YWx1ZXMuXG4gICAqIEB0ZW1wbGF0ZSBWIC0gVHlwZSBvZiB0aGUgb2JqZWN0IGJlaW5nIGV4cGFuZGVkLlxuICAgKiBAcGFyYW0ge1Z9IHZhbHVlIC0gT2JqZWN0IHRvIGV4cG9zZSB0aHJvdWdoIGVudmlyb25tZW50IGdldHRlcnMgYW5kIHNldHRlcnMuXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgZXhwYW5kPFYgZXh0ZW5kcyBvYmplY3Q+KHZhbHVlOiBWKTogdm9pZCB7XG4gICAgT2JqZWN0LmVudHJpZXModmFsdWUpLmZvckVhY2goKFtrLCB2XSkgPT4ge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIGssIHtcbiAgICAgICAgZ2V0OiAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZnJvbUVudiA9IHRoaXMuZnJvbUVudihrKTtcbiAgICAgICAgICBpZiAodHlwZW9mIGZyb21FbnYgIT09IFwidW5kZWZpbmVkXCIpIHJldHVybiBmcm9tRW52O1xuICAgICAgICAgIGlmICh2ICYmIHR5cGVvZiB2ID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gRW52aXJvbm1lbnQuYnVpbGRFbnZQcm94eSh2IGFzIGFueSwgW2tdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gSWYgdGhlIG1vZGVsIHByb3ZpZGVzIGFuIGVtcHR5IHN0cmluZywgbWFyayB3aXRoIEVtcHR5VmFsdWUgc28gaW5zdGFuY2UgcHJveHkgY2FuIHJldHVybiB1bmRlZmluZWQgd2l0aG91dCBlbmFibGluZyBrZXkgY29tcG9zaXRpb25cbiAgICAgICAgICBpZiAodiA9PT0gXCJcIikge1xuICAgICAgICAgICAgcmV0dXJuIEVtcHR5VmFsdWUgYXMgdW5rbm93biBhcyBWW2tleW9mIFZdO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdjtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiAodmFsOiBWW2tleW9mIFZdKSA9PiB7XG4gICAgICAgICAgdiA9IHZhbDtcbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKiBAc3RhdGljXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgb3IgY3JlYXRlcyB0aGUgc2luZ2xldG9uIGluc3RhbmNlIG9mIHRoZSBFbnZpcm9ubWVudCBjbGFzcy5cbiAgICogQHN1bW1hcnkgRW5zdXJlcyBvbmx5IG9uZSB7QGxpbmsgRW52aXJvbm1lbnR9IGluc3RhbmNlIGlzIGNyZWF0ZWQsIHdyYXBwaW5nIGl0IGluIGEgcHJveHkgdG8gY29tcG9zZSBFTlYga2V5cyBvbiBkZW1hbmQuXG4gICAqIEB0ZW1wbGF0ZSBFXG4gICAqIEBwYXJhbSB7Li4udW5rbm93bltdfSBhcmdzIC0gQXJndW1lbnRzIGZvcndhcmRlZCB0byB0aGUgZmFjdG9yeSB3aGVuIGluc3RhbnRpYXRpbmcgdGhlIHNpbmdsZXRvbi5cbiAgICogQHJldHVybiB7RX0gU2luZ2xldG9uIGVudmlyb25tZW50IGluc3RhbmNlLlxuICAgKi9cbiAgcHJvdGVjdGVkIHN0YXRpYyBpbnN0YW5jZTxFIGV4dGVuZHMgRW52aXJvbm1lbnQ8YW55Pj4oLi4uYXJnczogdW5rbm93bltdKTogRSB7XG4gICAgaWYgKCFFbnZpcm9ubWVudC5faW5zdGFuY2UpIHtcbiAgICAgIGNvbnN0IGJhc2UgPSBFbnZpcm9ubWVudC5mYWN0b3J5KC4uLmFyZ3MpIGFzIEU7XG4gICAgICBjb25zdCBwcm94aWVkID0gbmV3IFByb3h5KGJhc2UgYXMgYW55LCB7XG4gICAgICAgIGdldCh0YXJnZXQsIHByb3AsIHJlY2VpdmVyKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBSZWZsZWN0LmdldCh0YXJnZXQsIHByb3AsIHJlY2VpdmVyKTtcbiAgICAgICAgICBpZiAodmFsdWUgPT09IEVtcHR5VmFsdWUpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgIGlmICh0eXBlb2YgcHJvcCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgLy8gQXZvaWQgaW50ZXJmZXJpbmcgd2l0aCBsb2dnaW5nIGNvbmZpZyBsb29rdXBzIGZvciBvcHRpb25hbCBmaWVsZHMgbGlrZSAnYXBwJ1xuICAgICAgICAgICAgaWYgKHByb3AgPT09IFwiYXBwXCIpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICByZXR1cm4gRW52aXJvbm1lbnQuYnVpbGRFbnZQcm94eSh1bmRlZmluZWQsIFtwcm9wXSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgRW52aXJvbm1lbnQuX2luc3RhbmNlID0gcHJveGllZCBhcyBhbnk7XG4gICAgfVxuICAgIHJldHVybiBFbnZpcm9ubWVudC5faW5zdGFuY2UgYXMgRTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3RhdGljXG4gICAqIEBkZXNjcmlwdGlvbiBBY2N1bXVsYXRlcyB0aGUgZ2l2ZW4gdmFsdWUgaW50byB0aGUgZW52aXJvbm1lbnQuXG4gICAqIEBzdW1tYXJ5IEFkZHMgbmV3IHByb3BlcnRpZXMsIGhpZGluZyByYXcgZGVzY3JpcHRvcnMgdG8gYXZvaWQgbGVha2luZyBlbnVtZXJhdGlvbiBzZW1hbnRpY3MuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEB0ZW1wbGF0ZSBWXG4gICAqIEBwYXJhbSB7Vn0gdmFsdWUgLSBPYmplY3QgdG8gbWVyZ2UgaW50byB0aGUgZW52aXJvbm1lbnQuXG4gICAqIEByZXR1cm4ge0Vudmlyb25tZW50fSBVcGRhdGVkIGVudmlyb25tZW50IHJlZmVyZW5jZS5cbiAgICovXG4gIHN0YXRpYyBhY2N1bXVsYXRlPFYgZXh0ZW5kcyBvYmplY3QsIFRCYXNlIGV4dGVuZHMgb2JqZWN0ID0gb2JqZWN0PihcbiAgICB2YWx1ZTogVlxuICApOiBFbnZpcm9ubWVudDxUQmFzZSAmIFY+ICYgVEJhc2UgJiBWIHtcbiAgICBjb25zdCBpbnN0YW5jZSA9IEVudmlyb25tZW50Lmluc3RhbmNlPEVudmlyb25tZW50PFRCYXNlICYgVj4+KCk7XG4gICAgT2JqZWN0LmtleXMoaW5zdGFuY2UgYXMgYW55KS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgIGNvbnN0IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGluc3RhbmNlIGFzIGFueSwga2V5KTtcbiAgICAgIGlmIChkZXNjICYmIGRlc2MuY29uZmlndXJhYmxlICYmIGRlc2MuZW51bWVyYWJsZSkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoaW5zdGFuY2UgYXMgYW55LCBrZXksIHtcbiAgICAgICAgICAuLi5kZXNjLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gaW5zdGFuY2UuYWNjdW11bGF0ZSh2YWx1ZSkgYXMgdW5rbm93biBhcyBFbnZpcm9ubWVudDxUQmFzZSAmIFY+ICZcbiAgICAgIFRCYXNlICZcbiAgICAgIFY7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBhIHZhbHVlIHVzaW5nIGEgZG90LXBhdGgga2V5IGZyb20gdGhlIGFjY3VtdWxhdGVkIGVudmlyb25tZW50LlxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdG8gdGhlIHNpbmdsZXRvbiBpbnN0YW5jZSB0byBhY2Nlc3Mgc3RvcmVkIGNvbmZpZ3VyYXRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBLZXkgdG8gcmVzb2x2ZSBmcm9tIHRoZSBlbnZpcm9ubWVudCBzdG9yZS5cbiAgICogQHJldHVybiB7dW5rbm93bn0gU3RvcmVkIHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHByb3ZpZGVkIGtleS5cbiAgICovXG4gIHN0YXRpYyBnZXQoa2V5OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gRW52aXJvbm1lbnQuX2luc3RhbmNlLmdldChrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBCdWlsZHMgYSBwcm94eSB0aGF0IGNvbXBvc2VzIGVudmlyb25tZW50IGtleXMgZm9yIG5lc3RlZCBwcm9wZXJ0aWVzLlxuICAgKiBAc3VtbWFyeSBBbGxvd3MgY2hhaW5lZCBwcm9wZXJ0eSBhY2Nlc3MgdG8gZW1pdCB1cHBlcmNhc2UgRU5WIGlkZW50aWZpZXJzIHdoaWxlIGhvbm9yaW5nIGV4aXN0aW5nIHJ1bnRpbWUgb3ZlcnJpZGVzLlxuICAgKiBAcGFyYW0ge2FueX0gY3VycmVudCAtIFNlZWQgbW9kZWwgc2VnbWVudCB1c2VkIHdoZW4gcHJvamVjdGluZyBuZXN0ZWQgc3RydWN0dXJlcy5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gcGF0aCAtIEFjY3VtdWxhdGVkIHBhdGggc2VnbWVudHMgbGVhZGluZyB0byB0aGUgcHJveHkuXG4gICAqIEByZXR1cm4ge2FueX0gUHJveHkgdGhhdCByZXNvbHZlcyBlbnZpcm9ubWVudCB2YWx1ZXMgb3IgY29tcG9zZXMgYWRkaXRpb25hbCBwcm94aWVzIGZvciBkZWVwZXIgcGF0aHMuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBidWlsZEVudlByb3h5KGN1cnJlbnQ6IGFueSwgcGF0aDogc3RyaW5nW10pOiBhbnkge1xuICAgIGNvbnN0IGJ1aWxkS2V5ID0gKHA6IHN0cmluZ1tdKSA9PlxuICAgICAgcC5tYXAoKHNlZykgPT4gdG9FTlZGb3JtYXQoc2VnKSkuam9pbihFTlZfUEFUSF9ERUxJTUlURVIpO1xuXG4gICAgLy8gSGVscGVyIHRvIHJlYWQgZnJvbSB0aGUgYWN0aXZlIGVudmlyb25tZW50IGdpdmVuIGEgY29tcG9zZWQga2V5XG4gICAgY29uc3QgcmVhZEVudiA9IChrZXk6IHN0cmluZyk6IHVua25vd24gPT4ge1xuICAgICAgaWYgKGlzQnJvd3NlcigpKSB7XG4gICAgICAgIGNvbnN0IGVudiA9IChcbiAgICAgICAgICBnbG9iYWxUaGlzIGFzIHR5cGVvZiBnbG9iYWxUaGlzICYge1xuICAgICAgICAgICAgW0Jyb3dzZXJFbnZLZXldPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICAgICAgfVxuICAgICAgICApW0Jyb3dzZXJFbnZLZXldO1xuICAgICAgICByZXR1cm4gZW52ID8gZW52W2tleV0gOiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gKGdsb2JhbFRoaXMgYXMgYW55KT8ucHJvY2Vzcz8uZW52Py5ba2V5XTtcbiAgICB9O1xuXG4gICAgY29uc3QgaGFuZGxlcjogUHJveHlIYW5kbGVyPGFueT4gPSB7XG4gICAgICBnZXQoX3RhcmdldCwgcHJvcDogc3RyaW5nIHwgc3ltYm9sKSB7XG4gICAgICAgIGlmIChwcm9wID09PSBTeW1ib2wudG9QcmltaXRpdmUpIHtcbiAgICAgICAgICByZXR1cm4gKCkgPT4gYnVpbGRLZXkocGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3AgPT09IFwidG9TdHJpbmdcIikge1xuICAgICAgICAgIHJldHVybiAoKSA9PiBidWlsZEtleShwYXRoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcCA9PT0gXCJ2YWx1ZU9mXCIpIHtcbiAgICAgICAgICByZXR1cm4gKCkgPT4gYnVpbGRLZXkocGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwcm9wID09PSBcInN5bWJvbFwiKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgICAgIGNvbnN0IG5leHRNb2RlbCA9XG4gICAgICAgICAgY3VycmVudCAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoY3VycmVudCwgcHJvcClcbiAgICAgICAgICAgID8gKGN1cnJlbnQgYXMgYW55KVtwcm9wXVxuICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICAgIGNvbnN0IG5leHRQYXRoID0gWy4uLnBhdGgsIHByb3BdO1xuICAgICAgICBjb25zdCBjb21wb3NlZEtleSA9IGJ1aWxkS2V5KG5leHRQYXRoKTtcblxuICAgICAgICAvLyBJZiBhbiBFTlYgdmFsdWUgZXhpc3RzIGZvciB0aGlzIHBhdGgsIHJldHVybiBpdCBkaXJlY3RseVxuICAgICAgICBjb25zdCBlbnZWYWx1ZSA9IHJlYWRFbnYoY29tcG9zZWRLZXkpO1xuICAgICAgICBpZiAodHlwZW9mIGVudlZhbHVlICE9PSBcInVuZGVmaW5lZFwiKSByZXR1cm4gZW52VmFsdWU7XG5cbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBpZiB0aGUgbW9kZWwgaGFzIGFuIG9iamVjdCBhdCB0aGlzIHBhdGgsIGtlZXAgZHJpbGxpbmcgd2l0aCBhIHByb3h5XG4gICAgICAgIGNvbnN0IGlzTmV4dE9iamVjdCA9IG5leHRNb2RlbCAmJiB0eXBlb2YgbmV4dE1vZGVsID09PSBcIm9iamVjdFwiO1xuICAgICAgICBpZiAoaXNOZXh0T2JqZWN0KSByZXR1cm4gRW52aXJvbm1lbnQuYnVpbGRFbnZQcm94eShuZXh0TW9kZWwsIG5leHRQYXRoKTtcblxuICAgICAgICAvLyBJZiB0aGUgbW9kZWwgbWFya3MgdGhpcyBsZWFmIGFzIGFuIGVtcHR5IHN0cmluZywgdHJlYXQgYXMgdW5kZWZpbmVkIChubyBwcm94eSlcbiAgICAgICAgaWYgKG5leHRNb2RlbCA9PT0gXCJcIikgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgICAgICAvLyBBbHdheXMgcmV0dXJuIGEgcHJveHkgZm9yIGZ1cnRoZXIgcGF0aCBjb21wb3NpdGlvbiB3aGVuIG5vIEVOViB2YWx1ZTtcbiAgICAgICAgLy8gZG8gbm90IHN1cmZhY2UgcHJpbWl0aXZlIG1vZGVsIGRlZmF1bHRzIGhlcmUgKHRoaXMgQVBJIGlzIGZvciBrZXkgY29tcG9zaXRpb24pLlxuICAgICAgICByZXR1cm4gRW52aXJvbm1lbnQuYnVpbGRFbnZQcm94eSh1bmRlZmluZWQsIG5leHRQYXRoKTtcbiAgICAgIH0sXG4gICAgICBvd25LZXlzKCkge1xuICAgICAgICByZXR1cm4gY3VycmVudCA/IFJlZmxlY3Qub3duS2V5cyhjdXJyZW50KSA6IFtdO1xuICAgICAgfSxcbiAgICAgIGdldE93blByb3BlcnR5RGVzY3JpcHRvcihfdCwgcCkge1xuICAgICAgICBpZiAoIWN1cnJlbnQpIHJldHVybiB1bmRlZmluZWQgYXMgYW55O1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGN1cnJlbnQsIHApKSB7XG4gICAgICAgICAgcmV0dXJuIHsgZW51bWVyYWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gYXMgUHJvcGVydHlEZXNjcmlwdG9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQgYXMgYW55O1xuICAgICAgfSxcbiAgICB9O1xuXG4gICAgY29uc3QgdGFyZ2V0ID0ge30gYXMgYW55O1xuICAgIHJldHVybiBuZXcgUHJveHkodGFyZ2V0LCBoYW5kbGVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3RhdGljXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgdGhlIGtleXMgb2YgdGhlIGVudmlyb25tZW50LCBvcHRpb25hbGx5IGNvbnZlcnRpbmcgdGhlbSB0byBFTlYgZm9ybWF0LlxuICAgKiBAc3VtbWFyeSBHZXRzIGFsbCBrZXlzIGluIHRoZSBlbnZpcm9ubWVudCwgd2l0aCBhbiBvcHRpb24gdG8gZm9ybWF0IHRoZW0gZm9yIGVudmlyb25tZW50IHZhcmlhYmxlcy5cbiAgICogQHBhcmFtIHtib29sZWFufSBbdG9FbnY9dHJ1ZV0gLSBXaGV0aGVyIHRvIGNvbnZlcnQgdGhlIGtleXMgdG8gRU5WIGZvcm1hdC5cbiAgICogQHJldHVybiB7c3RyaW5nW119IEFuIGFycmF5IG9mIGtleXMgZnJvbSB0aGUgZW52aXJvbm1lbnQuXG4gICAqL1xuICBzdGF0aWMga2V5cyh0b0VudjogYm9vbGVhbiA9IHRydWUpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIEVudmlyb25tZW50Lmluc3RhbmNlKClcbiAgICAgIC5rZXlzKClcbiAgICAgIC5tYXAoKGspID0+ICh0b0VudiA/IHRvRU5WRm9ybWF0KGspIDogaykpO1xuICB9XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFNpbmdsZXRvbiBlbnZpcm9ubWVudCBpbnN0YW5jZSBzZWVkZWQgd2l0aCBkZWZhdWx0IGxvZ2dpbmcgY29uZmlndXJhdGlvbi5cbiAqIEBzdW1tYXJ5IENvbWJpbmVzIHtAbGluayBEZWZhdWx0TG9nZ2luZ0NvbmZpZ30gd2l0aCBydW50aW1lIGVudmlyb25tZW50IHZhcmlhYmxlcyB0byBwcm92aWRlIGNvbnNpc3RlbnQgbG9nZ2luZyBkZWZhdWx0cyBhY3Jvc3MgcGxhdGZvcm1zLlxuICogQGNvbnN0IExvZ2dlZEVudmlyb25tZW50XG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGNvbnN0IExvZ2dlZEVudmlyb25tZW50ID0gRW52aXJvbm1lbnQuYWNjdW11bGF0ZShcbiAgT2JqZWN0LmFzc2lnbih7fSwgRGVmYXVsdExvZ2dpbmdDb25maWcsIHtcbiAgICBlbnY6XG4gICAgICAoaXNCcm93c2VyKCkgJiYgKGdsb2JhbFRoaXMgYXMgYW55KVtCcm93c2VyRW52S2V5XVxuICAgICAgICA/IChnbG9iYWxUaGlzIGFzIGFueSlbQnJvd3NlckVudktleV1bXCJOT0RFX0VOVlwiXVxuICAgICAgICA6IChnbG9iYWxUaGlzIGFzIGFueSkucHJvY2Vzcy5lbnZbXCJOT0RFX0VOVlwiXSkgfHwgXCJkZXZlbG9wbWVudFwiLFxuICB9KVxuKTtcbiIsImltcG9ydCB7XG4gIExvZ2dlckZhY3RvcnksXG4gIExvZ2dpbmdDb25maWcsXG4gIExvZ2dpbmdDb250ZXh0LFxuICBTdHJpbmdMaWtlLFxuICBUaGVtZSxcbiAgVGhlbWVPcHRpb24sXG4gIFRoZW1lT3B0aW9uQnlMb2dMZXZlbCxcbiAgTG9nZ2VyLFxufSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgQ29sb3JpemVPcHRpb25zLCBzdHlsZSwgU3R5bGVkU3RyaW5nIH0gZnJvbSBcInN0eWxlZC1zdHJpbmctYnVpbGRlclwiO1xuaW1wb3J0IHsgRGVmYXVsdFRoZW1lLCBMb2dMZXZlbCwgTnVtZXJpY0xvZ0xldmVscyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgc2YgfSBmcm9tIFwiLi90ZXh0XCI7XG5pbXBvcnQgeyBMb2dnZWRFbnZpcm9ubWVudCB9IGZyb20gXCIuL2Vudmlyb25tZW50XCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgbWluaW1hbCBsb2dnZXIgaW1wbGVtZW50YXRpb24uXG4gKiBAc3VtbWFyeSBNaW5pTG9nZ2VyIGlzIGEgbGlnaHR3ZWlnaHQgbG9nZ2luZyBjbGFzcyB0aGF0IGltcGxlbWVudHMgdGhlIExvZ2dlciBpbnRlcmZhY2UuXG4gKiBJdCBwcm92aWRlcyBiYXNpYyBsb2dnaW5nIGZ1bmN0aW9uYWxpdHkgd2l0aCBzdXBwb3J0IGZvciBkaWZmZXJlbnQgbG9nIGxldmVscywgdmVyYm9zaXR5LFxuICogY29udGV4dC1hd2FyZSBsb2dnaW5nLCBhbmQgY3VzdG9taXphYmxlIGZvcm1hdHRpbmcuXG4gKiBAcGFyYW0ge3N0cmluZ30gY29udGV4dCAtIFRoZSBjb250ZXh0ICh0eXBpY2FsbHkgY2xhc3MgbmFtZSkgdGhpcyBsb2dnZXIgaXMgYXNzb2NpYXRlZCB3aXRoXG4gKiBAcGFyYW0ge1BhcnRpYWw8TG9nZ2luZ0NvbmZpZz59IGNvbmYgLSBPcHRpb25hbCBjb25maWd1cmF0aW9uIHRvIG92ZXJyaWRlIGdsb2JhbCBzZXR0aW5nc1xuICogQGNsYXNzIE1pbmlMb2dnZXJcbiAqIEBleGFtcGxlXG4gKiAvLyBDcmVhdGUgYSBuZXcgbG9nZ2VyIGZvciBhIGNsYXNzXG4gKiBjb25zdCBsb2dnZXIgPSBuZXcgTWluaUxvZ2dlcignTXlDbGFzcycpO1xuICpcbiAqIC8vIExvZyBtZXNzYWdlcyBhdCBkaWZmZXJlbnQgbGV2ZWxzXG4gKiBsb2dnZXIuaW5mbygnVGhpcyBpcyBhbiBpbmZvIG1lc3NhZ2UnKTtcbiAqIGxvZ2dlci5kZWJ1ZygnVGhpcyBpcyBhIGRlYnVnIG1lc3NhZ2UnKTtcbiAqIGxvZ2dlci5lcnJvcignU29tZXRoaW5nIHdlbnQgd3JvbmcnKTtcbiAqXG4gKiAvLyBDcmVhdGUgYSBjaGlsZCBsb2dnZXIgZm9yIGEgc3BlY2lmaWMgbWV0aG9kXG4gKiBjb25zdCBtZXRob2RMb2dnZXIgPSBsb2dnZXIuZm9yKCdteU1ldGhvZCcpO1xuICogbWV0aG9kTG9nZ2VyLnZlcmJvc2UoJ0RldGFpbGVkIGluZm9ybWF0aW9uJywgMik7XG4gKlxuICogLy8gTG9nIHdpdGggY3VzdG9tIGNvbmZpZ3VyYXRpb25cbiAqIGxvZ2dlci5mb3IoJ3NwZWNpYWxNZXRob2QnLCB7IHN0eWxlOiB0cnVlIH0pLmluZm8oJ1N0eWxlZCBtZXNzYWdlJyk7XG4gKi9cbmV4cG9ydCBjbGFzcyBNaW5pTG9nZ2VyIGltcGxlbWVudHMgTG9nZ2VyIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIGNvbnRleHQ6IHN0cmluZyxcbiAgICBwcm90ZWN0ZWQgY29uZj86IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz5cbiAgKSB7fVxuXG4gIHByb3RlY3RlZCBjb25maWcoXG4gICAga2V5OiBrZXlvZiBMb2dnaW5nQ29uZmlnXG4gICk6IExvZ2dpbmdDb25maWdba2V5b2YgTG9nZ2luZ0NvbmZpZ10ge1xuICAgIGlmICh0aGlzLmNvbmYgJiYga2V5IGluIHRoaXMuY29uZikgcmV0dXJuIHRoaXMuY29uZltrZXldO1xuICAgIHJldHVybiBMb2dnaW5nLmdldENvbmZpZygpW2tleV07XG4gIH1cblxuICBmb3IobWV0aG9kOiBzdHJpbmcgfCAoKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnkpKTogTG9nZ2VyO1xuICBmb3IoY29uZmlnOiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+KTogTG9nZ2VyO1xuICBmb3IoXG4gICAgbWV0aG9kOiBzdHJpbmcgfCAoKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnkpIHwgUGFydGlhbDxMb2dnaW5nQ29uZmlnPixcbiAgICBjb25maWc6IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogTG9nZ2VyO1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBjaGlsZCBsb2dnZXIgZm9yIGEgc3BlY2lmaWMgbWV0aG9kIG9yIGNvbnRleHRcbiAgICogQHN1bW1hcnkgUmV0dXJucyBhIG5ldyBsb2dnZXIgaW5zdGFuY2Ugd2l0aCB0aGUgY3VycmVudCBjb250ZXh0IGV4dGVuZGVkIGJ5IHRoZSBzcGVjaWZpZWQgbWV0aG9kIG5hbWVcbiAgICogQHBhcmFtIHtzdHJpbmcgfCBGdW5jdGlvbn0gbWV0aG9kIC0gVGhlIG1ldGhvZCBuYW1lIG9yIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIGxvZ2dlciBmb3JcbiAgICogQHBhcmFtIHtQYXJ0aWFsPExvZ2dpbmdDb25maWc+fSBjb25maWcgLSBPcHRpb25hbCBjb25maWd1cmF0aW9uIHRvIG92ZXJyaWRlIHNldHRpbmdzXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBsb2dnZXIgZmFjdG9yeVxuICAgKiBAcmV0dXJuIHtMb2dnZXJ9IEEgbmV3IGxvZ2dlciBpbnN0YW5jZSBmb3IgdGhlIHNwZWNpZmllZCBtZXRob2RcbiAgICovXG4gIGZvcihcbiAgICBtZXRob2Q/OiBzdHJpbmcgfCAoKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnkpIHwgUGFydGlhbDxMb2dnaW5nQ29uZmlnPixcbiAgICBjb25maWc/OiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+LFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBMb2dnZXIge1xuICAgIGlmICghY29uZmlnICYmIHR5cGVvZiBtZXRob2QgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIGNvbmZpZyA9IG1ldGhvZDtcbiAgICAgIG1ldGhvZCA9IHVuZGVmaW5lZDtcbiAgICB9IGVsc2Uge1xuICAgICAgbWV0aG9kID0gbWV0aG9kXG4gICAgICAgID8gdHlwZW9mIG1ldGhvZCA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgID8gbWV0aG9kXG4gICAgICAgICAgOiAobWV0aG9kIGFzIGFueSkubmFtZVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb3h5KHRoaXMsIHtcbiAgICAgIGdldDogKHRhcmdldDogdHlwZW9mIHRoaXMsIHA6IHN0cmluZyB8IHN5bWJvbCwgcmVjZWl2ZXI6IGFueSkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBSZWZsZWN0LmdldCh0YXJnZXQsIHAsIHJlY2VpdmVyKTtcbiAgICAgICAgaWYgKHAgPT09IFwiY29uZmlnXCIpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFByb3h5KHRoaXMuY29uZmlnLCB7XG4gICAgICAgICAgICBnZXQ6ICh0YXJnZXQ6IHR5cGVvZiB0aGlzLmNvbmZpZywgcDogc3RyaW5nIHwgc3ltYm9sKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChjb25maWcgJiYgcCBpbiBjb25maWcpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbmZpZ1twIGFzIGtleW9mIExvZ2dpbmdDb25maWddO1xuICAgICAgICAgICAgICByZXR1cm4gUmVmbGVjdC5nZXQodGFyZ2V0LCBwLCByZWNlaXZlcik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwID09PSBcImNvbnRleHRcIiAmJiBtZXRob2QpIHtcbiAgICAgICAgICByZXR1cm4gW3Jlc3VsdCwgbWV0aG9kXS5qb2luKFwiLlwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGZvcm1hdHRlZCBsb2cgc3RyaW5nXG4gICAqIEBzdW1tYXJ5IEdlbmVyYXRlcyBhIGxvZyBzdHJpbmcgd2l0aCB0aW1lc3RhbXAsIGNvbG9yZWQgbG9nIGxldmVsLCBjb250ZXh0LCBhbmQgbWVzc2FnZVxuICAgKiBAcGFyYW0ge0xvZ0xldmVsfSBsZXZlbCAtIFRoZSBsb2cgbGV2ZWwgZm9yIHRoaXMgbWVzc2FnZVxuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2UgfCBFcnJvcn0gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGxvZyBvciBhbiBFcnJvciBvYmplY3RcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtlcnJvcl0gLSBPcHRpb25hbCBlcnJvciB0byBleHRyYWN0IHN0YWNrIHRyYWNlIHRvIGluY2x1ZGUgaW4gdGhlIGxvZ1xuICAgKiBAcmV0dXJuIHtzdHJpbmd9IEEgZm9ybWF0dGVkIGxvZyBzdHJpbmcgd2l0aCBhbGwgY29tcG9uZW50c1xuICAgKi9cbiAgcHJvdGVjdGVkIGNyZWF0ZUxvZyhcbiAgICBsZXZlbDogTG9nTGV2ZWwsXG4gICAgbWVzc2FnZTogU3RyaW5nTGlrZSB8IEVycm9yLFxuICAgIGVycm9yPzogRXJyb3JcbiAgKTogc3RyaW5nIHtcbiAgICBjb25zdCBsb2c6IFJlY29yZDxcbiAgICAgIHwgXCJ0aW1lc3RhbXBcIlxuICAgICAgfCBcImxldmVsXCJcbiAgICAgIHwgXCJjb250ZXh0XCJcbiAgICAgIHwgXCJjb3JyZWxhdGlvbklkXCJcbiAgICAgIHwgXCJtZXNzYWdlXCJcbiAgICAgIHwgXCJzZXBhcmF0b3JcIlxuICAgICAgfCBcInN0YWNrXCJcbiAgICAgIHwgXCJhcHBcIixcbiAgICAgIHN0cmluZ1xuICAgID4gPSB7fSBhcyBhbnk7XG4gICAgY29uc3Qgc3R5bGUgPSB0aGlzLmNvbmZpZyhcInN0eWxlXCIpO1xuICAgIGNvbnN0IHNlcGFyYXRvciA9IHRoaXMuY29uZmlnKFwic2VwYXJhdG9yXCIpO1xuICAgIGNvbnN0IGFwcCA9IHRoaXMuY29uZmlnKFwiYXBwXCIpO1xuICAgIGlmIChhcHApXG4gICAgICBsb2cuYXBwID0gc3R5bGVcbiAgICAgICAgPyBMb2dnaW5nLnRoZW1lKGFwcCBhcyBzdHJpbmcsIFwiYXBwXCIsIGxldmVsKVxuICAgICAgICA6IChhcHAgYXMgc3RyaW5nKTtcblxuICAgIGlmIChzZXBhcmF0b3IpXG4gICAgICBsb2cuc2VwYXJhdG9yID0gc3R5bGVcbiAgICAgICAgPyBMb2dnaW5nLnRoZW1lKHNlcGFyYXRvciBhcyBzdHJpbmcsIFwic2VwYXJhdG9yXCIsIGxldmVsKVxuICAgICAgICA6IChzZXBhcmF0b3IgYXMgc3RyaW5nKTtcblxuICAgIGlmICh0aGlzLmNvbmZpZyhcInRpbWVzdGFtcFwiKSkge1xuICAgICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcbiAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IHN0eWxlID8gTG9nZ2luZy50aGVtZShkYXRlLCBcInRpbWVzdGFtcFwiLCBsZXZlbCkgOiBkYXRlO1xuICAgICAgbG9nLnRpbWVzdGFtcCA9IHRpbWVzdGFtcDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWcoXCJsb2dMZXZlbFwiKSkge1xuICAgICAgY29uc3QgbHZsOiBzdHJpbmcgPSBzdHlsZVxuICAgICAgICA/IExvZ2dpbmcudGhlbWUobGV2ZWwsIFwibG9nTGV2ZWxcIiwgbGV2ZWwpXG4gICAgICAgIDogbGV2ZWw7XG4gICAgICBsb2cubGV2ZWwgPSBsdmwudG9VcHBlckNhc2UoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWcoXCJjb250ZXh0XCIpKSB7XG4gICAgICBjb25zdCBjb250ZXh0OiBzdHJpbmcgPSBzdHlsZVxuICAgICAgICA/IExvZ2dpbmcudGhlbWUodGhpcy5jb250ZXh0LCBcImNsYXNzXCIsIGxldmVsKVxuICAgICAgICA6IHRoaXMuY29udGV4dDtcbiAgICAgIGxvZy5jb250ZXh0ID0gY29udGV4dDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWcoXCJjb3JyZWxhdGlvbklkXCIpKSB7XG4gICAgICB7XG4gICAgICAgIGNvbnN0IGlkOiBzdHJpbmcgPSBzdHlsZVxuICAgICAgICAgID8gTG9nZ2luZy50aGVtZSh0aGlzLmNvbmZpZyhcImNvcnJlbGF0aW9uSWRcIikhLnRvU3RyaW5nKCksIFwiaWRcIiwgbGV2ZWwpXG4gICAgICAgICAgOiB0aGlzLmNvbmZpZyhcImNvcnJlbGF0aW9uSWRcIikhLnRvU3RyaW5nKCk7XG4gICAgICAgIGxvZy5jb3JyZWxhdGlvbklkID0gaWQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgbXNnOiBzdHJpbmcgPSBzdHlsZVxuICAgICAgPyBMb2dnaW5nLnRoZW1lKFxuICAgICAgICAgIHR5cGVvZiBtZXNzYWdlID09PSBcInN0cmluZ1wiID8gbWVzc2FnZSA6IChtZXNzYWdlIGFzIEVycm9yKS5tZXNzYWdlLFxuICAgICAgICAgIFwibWVzc2FnZVwiLFxuICAgICAgICAgIGxldmVsXG4gICAgICAgIClcbiAgICAgIDogdHlwZW9mIG1lc3NhZ2UgPT09IFwic3RyaW5nXCJcbiAgICAgICAgPyBtZXNzYWdlXG4gICAgICAgIDogKG1lc3NhZ2UgYXMgRXJyb3IpLm1lc3NhZ2U7XG4gICAgbG9nLm1lc3NhZ2UgPSBtc2c7XG4gICAgaWYgKGVycm9yIHx8IG1lc3NhZ2UgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgY29uc3Qgc3RhY2sgPSBzdHlsZVxuICAgICAgICA/IExvZ2dpbmcudGhlbWUoXG4gICAgICAgICAgICAoZXJyb3I/LnN0YWNrIHx8IChtZXNzYWdlIGFzIEVycm9yKS5zdGFjaykgYXMgc3RyaW5nLFxuICAgICAgICAgICAgXCJzdGFja1wiLFxuICAgICAgICAgICAgbGV2ZWxcbiAgICAgICAgICApXG4gICAgICAgIDogZXJyb3I/LnN0YWNrIHx8IFwiXCI7XG4gICAgICBsb2cuc3RhY2sgPSBgIHwgJHsoZXJyb3IgfHwgKG1lc3NhZ2UgYXMgRXJyb3IpKS5tZXNzYWdlfSAtIFN0YWNrIHRyYWNlOlxcbiR7c3RhY2t9YDtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHRoaXMuY29uZmlnKFwiZm9ybWF0XCIpKSB7XG4gICAgICBjYXNlIFwianNvblwiOlxuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkobG9nKTtcbiAgICAgIGNhc2UgXCJyYXdcIjpcbiAgICAgICAgcmV0dXJuICh0aGlzLmNvbmZpZyhcInBhdHRlcm5cIikgYXMgc3RyaW5nKVxuICAgICAgICAgIC5zcGxpdChcIiBcIilcbiAgICAgICAgICAubWFwKChzKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXMubWF0Y2goL1xcey4qP30vZykpIHJldHVybiBzO1xuICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVkUyA9IHNmKHMsIGxvZyk7XG4gICAgICAgICAgICBpZiAoZm9ybWF0dGVkUyAhPT0gcykgcmV0dXJuIGZvcm1hdHRlZFM7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLmZpbHRlcigocykgPT4gcylcbiAgICAgICAgICAuam9pbihcIiBcIik7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGxvZ2dpbmcgZm9ybWF0OiAke3RoaXMuY29uZmlnKFwiZm9ybWF0XCIpfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGxvZyBsZXZlbFxuICAgKiBAc3VtbWFyeSBDaGVja3MgaWYgdGhlIG1lc3NhZ2Ugc2hvdWxkIGJlIGxvZ2dlZCBiYXNlZCBvbiB0aGUgY3VycmVudCBsb2cgbGV2ZWwsXG4gICAqIHRoZW4gdXNlcyB0aGUgYXBwcm9wcmlhdGUgY29uc29sZSBtZXRob2QgdG8gb3V0cHV0IHRoZSBmb3JtYXR0ZWQgbG9nXG4gICAqIEBwYXJhbSB7TG9nTGV2ZWx9IGxldmVsIC0gVGhlIGxvZyBsZXZlbCBvZiB0aGUgbWVzc2FnZVxuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2UgfCBFcnJvcn0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkIG9yIGFuIEVycm9yIG9iamVjdFxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2Vycm9yXSAtIE9wdGlvbmFsIHN0YWNrIHRyYWNlIHRvIGluY2x1ZGUgaW4gdGhlIGxvZ1xuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgcHJvdGVjdGVkIGxvZyhsZXZlbDogTG9nTGV2ZWwsIG1zZzogU3RyaW5nTGlrZSB8IEVycm9yLCBlcnJvcj86IEVycm9yKTogdm9pZCB7XG4gICAgY29uc3QgY29uZkx2bCA9IHRoaXMuY29uZmlnKFwibGV2ZWxcIikgYXMgTG9nTGV2ZWw7XG4gICAgaWYgKE51bWVyaWNMb2dMZXZlbHNbY29uZkx2bF0gPCBOdW1lcmljTG9nTGV2ZWxzW2xldmVsXSkgcmV0dXJuO1xuICAgIGxldCBtZXRob2Q7XG4gICAgc3dpdGNoIChsZXZlbCkge1xuICAgICAgY2FzZSBMb2dMZXZlbC5iZW5jaG1hcms6XG4gICAgICAgIG1ldGhvZCA9IGNvbnNvbGUubG9nO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTG9nTGV2ZWwuaW5mbzpcbiAgICAgICAgbWV0aG9kID0gY29uc29sZS5sb2c7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBMb2dMZXZlbC52ZXJib3NlOlxuICAgICAgY2FzZSBMb2dMZXZlbC5kZWJ1ZzpcbiAgICAgICAgbWV0aG9kID0gY29uc29sZS5kZWJ1ZztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIExvZ0xldmVsLmVycm9yOlxuICAgICAgICBtZXRob2QgPSBjb25zb2xlLmVycm9yO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgbG9nIGxldmVsXCIpO1xuICAgIH1cbiAgICBtZXRob2QodGhpcy5jcmVhdGVMb2cobGV2ZWwsIG1zZywgZXJyb3IpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGJlbmNobWFyayBsZXZlbFxuICAgKiBAc3VtbWFyeSBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgYmVuY2htYXJrIGxldmVsIGlmIHRoZSBjdXJyZW50IHZlcmJvc2l0eSBzZXR0aW5nIGFsbG93cyBpdFxuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2V9IG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZFxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgYmVuY2htYXJrKG1zZzogU3RyaW5nTGlrZSk6IHZvaWQge1xuICAgIHRoaXMubG9nKExvZ0xldmVsLmJlbmNobWFyaywgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIHNpbGx5IGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBzaWxseSBsZXZlbCBpZiB0aGUgY3VycmVudCB2ZXJib3NpdHkgc2V0dGluZyBhbGxvd3MgaXRcbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWRcbiAgICogQHBhcmFtIHtudW1iZXJ9IFt2ZXJib3NpdHk9MF0gLSBUaGUgdmVyYm9zaXR5IGxldmVsIG9mIHRoZSBtZXNzYWdlXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzaWxseShtc2c6IFN0cmluZ0xpa2UsIHZlcmJvc2l0eTogbnVtYmVyID0gMCk6IHZvaWQge1xuICAgIGlmICgodGhpcy5jb25maWcoXCJ2ZXJib3NlXCIpIGFzIG51bWJlcikgPj0gdmVyYm9zaXR5KVxuICAgICAgdGhpcy5sb2coTG9nTGV2ZWwudmVyYm9zZSwgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIHZlcmJvc2UgbGV2ZWxcbiAgICogQHN1bW1hcnkgTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIHZlcmJvc2UgbGV2ZWwgaWYgdGhlIGN1cnJlbnQgdmVyYm9zaXR5IHNldHRpbmcgYWxsb3dzIGl0XG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZX0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbdmVyYm9zaXR5PTBdIC0gVGhlIHZlcmJvc2l0eSBsZXZlbCBvZiB0aGUgbWVzc2FnZVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgdmVyYm9zZShtc2c6IFN0cmluZ0xpa2UsIHZlcmJvc2l0eTogbnVtYmVyID0gMCk6IHZvaWQge1xuICAgIGlmICgodGhpcy5jb25maWcoXCJ2ZXJib3NlXCIpIGFzIG51bWJlcikgPj0gdmVyYm9zaXR5KVxuICAgICAgdGhpcy5sb2coTG9nTGV2ZWwudmVyYm9zZSwgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGluZm8gbGV2ZWxcbiAgICogQHN1bW1hcnkgTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGluZm8gbGV2ZWwgZm9yIGdlbmVyYWwgYXBwbGljYXRpb24gaW5mb3JtYXRpb25cbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWRcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIGluZm8obXNnOiBTdHJpbmdMaWtlKTogdm9pZCB7XG4gICAgdGhpcy5sb2coTG9nTGV2ZWwuaW5mbywgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGRlYnVnIGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBkZWJ1ZyBsZXZlbCBmb3IgZGV0YWlsZWQgdHJvdWJsZXNob290aW5nIGluZm9ybWF0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZX0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBkZWJ1Zyhtc2c6IFN0cmluZ0xpa2UpOiB2b2lkIHtcbiAgICB0aGlzLmxvZyhMb2dMZXZlbC5kZWJ1ZywgbXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGVycm9yIGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBlcnJvciBsZXZlbCBmb3IgZXJyb3JzIGFuZCBleGNlcHRpb25zXG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZSB8IEVycm9yfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQgb3IgYW4gRXJyb3Igb2JqZWN0XG4gICAqIEBwYXJhbSBlXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBlcnJvcihtc2c6IFN0cmluZ0xpa2UgfCBFcnJvciwgZT86IEVycm9yKTogdm9pZCB7XG4gICAgdGhpcy5sb2coTG9nTGV2ZWwuZXJyb3IsIG1zZywgZSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVwZGF0ZXMgdGhlIGxvZ2dlciBjb25maWd1cmF0aW9uXG4gICAqIEBzdW1tYXJ5IE1lcmdlcyB0aGUgcHJvdmlkZWQgY29uZmlndXJhdGlvbiB3aXRoIHRoZSBleGlzdGluZyBjb25maWd1cmF0aW9uXG4gICAqIEBwYXJhbSB7UGFydGlhbDxMb2dnaW5nQ29uZmlnPn0gY29uZmlnIC0gVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byBhcHBseVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc2V0Q29uZmlnKGNvbmZpZzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPik6IHZvaWQge1xuICAgIHRoaXMuY29uZiA9IHsgLi4uKHRoaXMuY29uZiB8fCB7fSksIC4uLmNvbmZpZyB9O1xuICB9XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgc3RhdGljIGNsYXNzIGZvciBtYW5hZ2luZyBsb2dnaW5nIG9wZXJhdGlvbnNcbiAqIEBzdW1tYXJ5IFRoZSBMb2dnaW5nIGNsYXNzIHByb3ZpZGVzIGEgY2VudHJhbGl6ZWQgbG9nZ2luZyBtZWNoYW5pc20gd2l0aCBzdXBwb3J0IGZvclxuICogZGlmZmVyZW50IGxvZyBsZXZlbHMsIHZlcmJvc2l0eSwgYW5kIHN0eWxpbmcuIEl0IHVzZXMgYSBzaW5nbGV0b24gcGF0dGVybiB0byBtYWludGFpbiBhIGdsb2JhbFxuICogbG9nZ2VyIGluc3RhbmNlIGFuZCBhbGxvd3MgY3JlYXRpbmcgc3BlY2lmaWMgbG9nZ2VycyBmb3IgZGlmZmVyZW50IGNsYXNzZXMgYW5kIG1ldGhvZHMuXG4gKiBAY2xhc3MgTG9nZ2luZ1xuICogQGV4YW1wbGVcbiAqIC8vIFNldCBnbG9iYWwgY29uZmlndXJhdGlvblxuICogTG9nZ2luZy5zZXRDb25maWcoeyBsZXZlbDogTG9nTGV2ZWwuZGVidWcsIHN0eWxlOiB0cnVlIH0pO1xuICpcbiAqIC8vIEdldCBhIGxvZ2dlciBmb3IgYSBzcGVjaWZpYyBjbGFzc1xuICogY29uc3QgbG9nZ2VyID0gTG9nZ2luZy5mb3IoJ015Q2xhc3MnKTtcbiAqXG4gKiAvLyBMb2cgbWVzc2FnZXMgYXQgZGlmZmVyZW50IGxldmVsc1xuICogbG9nZ2VyLmluZm8oJ0FwcGxpY2F0aW9uIHN0YXJ0ZWQnKTtcbiAqIGxvZ2dlci5kZWJ1ZygnUHJvY2Vzc2luZyBkYXRhLi4uJyk7XG4gKlxuICogLy8gTG9nIHdpdGggY29udGV4dFxuICogY29uc3QgbWV0aG9kTG9nZ2VyID0gTG9nZ2luZy5mb3IoJ015Q2xhc3MubXlNZXRob2QnKTtcbiAqIG1ldGhvZExvZ2dlci52ZXJib3NlKCdEZXRhaWxlZCBvcGVyYXRpb24gaW5mb3JtYXRpb24nLCAxKTtcbiAqXG4gKiAvLyBMb2cgZXJyb3JzXG4gKiB0cnkge1xuICogICAvLyBzb21lIG9wZXJhdGlvblxuICogfSBjYXRjaCAoZXJyb3IpIHtcbiAqICAgbG9nZ2VyLmVycm9yKGVycm9yKTtcbiAqIH1cbiAqIEBtZXJtYWlkXG4gKiBjbGFzc0RpYWdyYW1cbiAqICAgY2xhc3MgTG9nZ2VyIHtcbiAqICAgICA8PGludGVyZmFjZT4+XG4gKiAgICAgK2ZvcihtZXRob2QsIGNvbmZpZywgLi4uYXJncylcbiAqICAgICArc2lsbHkobXNnLCB2ZXJib3NpdHkpXG4gKiAgICAgK3ZlcmJvc2UobXNnLCB2ZXJib3NpdHkpXG4gKiAgICAgK2luZm8obXNnKVxuICogICAgICtkZWJ1Zyhtc2cpXG4gKiAgICAgK2Vycm9yKG1zZylcbiAqICAgICArc2V0Q29uZmlnKGNvbmZpZylcbiAqICAgfVxuICpcbiAqICAgY2xhc3MgTG9nZ2luZyB7XG4gKiAgICAgLWdsb2JhbDogTG9nZ2VyXG4gKiAgICAgLV9mYWN0b3J5OiBMb2dnZXJGYWN0b3J5XG4gKiAgICAgLV9jb25maWc6IExvZ2dpbmdDb25maWdcbiAqICAgICArc2V0RmFjdG9yeShmYWN0b3J5KVxuICogICAgICtzZXRDb25maWcoY29uZmlnKVxuICogICAgICtnZXRDb25maWcoKVxuICogICAgICtnZXQoKVxuICogICAgICt2ZXJib3NlKG1zZywgdmVyYm9zaXR5KVxuICogICAgICtpbmZvKG1zZylcbiAqICAgICArZGVidWcobXNnKVxuICogICAgICtzaWxseShtc2cpXG4gKiAgICAgK2Vycm9yKG1zZylcbiAqICAgICArZm9yKG9iamVjdCwgY29uZmlnLCAuLi5hcmdzKVxuICogICAgICtiZWNhdXNlKHJlYXNvbiwgaWQpXG4gKiAgICAgK3RoZW1lKHRleHQsIHR5cGUsIGxvZ2dlckxldmVsLCB0ZW1wbGF0ZSlcbiAqICAgfVxuICpcbiAqICAgY2xhc3MgTWluaUxvZ2dlciB7XG4gKiAgICAgK2NvbnN0cnVjdG9yKGNvbnRleHQsIGNvbmY/KVxuICogICB9XG4gKlxuICogICBMb2dnaW5nIC4uPiBMb2dnZXIgOiBjcmVhdGVzXG4gKiAgIExvZ2dpbmcgLi4+IE1pbmlMb2dnZXIgOiBjcmVhdGVzIGJ5IGRlZmF1bHRcbiAqL1xuZXhwb3J0IGNsYXNzIExvZ2dpbmcge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlXG4gICAqIEBzdW1tYXJ5IEEgc2luZ2xldG9uIGluc3RhbmNlIG9mIExvZ2dlciB1c2VkIGZvciBnbG9iYWwgbG9nZ2luZ1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZ2xvYmFsPzogTG9nZ2VyO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRmFjdG9yeSBmdW5jdGlvbiBmb3IgY3JlYXRpbmcgbG9nZ2VyIGluc3RhbmNlc1xuICAgKiBAc3VtbWFyeSBBIGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBuZXcgTG9nZ2VyIGluc3RhbmNlcy4gQnkgZGVmYXVsdCwgaXQgY3JlYXRlcyBhIE1pbmlMb2dnZXIuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBfZmFjdG9yeTogTG9nZ2VyRmFjdG9yeSA9IChcbiAgICBvYmplY3Q6IHN0cmluZyxcbiAgICBjb25maWc/OiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+XG4gICkgPT4ge1xuICAgIHJldHVybiBuZXcgTWluaUxvZ2dlcihvYmplY3QsIGNvbmZpZyk7XG4gIH07XG5cbiAgcHJpdmF0ZSBzdGF0aWMgX2NvbmZpZzogdHlwZW9mIExvZ2dlZEVudmlyb25tZW50ID0gTG9nZ2VkRW52aXJvbm1lbnQ7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBmYWN0b3J5IGZ1bmN0aW9uIGZvciBjcmVhdGluZyBsb2dnZXIgaW5zdGFuY2VzXG4gICAqIEBzdW1tYXJ5IEFsbG93cyBjdXN0b21pemluZyBob3cgbG9nZ2VyIGluc3RhbmNlcyBhcmUgY3JlYXRlZFxuICAgKiBAcGFyYW0ge0xvZ2dlckZhY3Rvcnl9IGZhY3RvcnkgLSBUaGUgZmFjdG9yeSBmdW5jdGlvbiB0byB1c2UgZm9yIGNyZWF0aW5nIGxvZ2dlcnNcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHN0YXRpYyBzZXRGYWN0b3J5KGZhY3Rvcnk6IExvZ2dlckZhY3RvcnkpIHtcbiAgICBMb2dnaW5nLl9mYWN0b3J5ID0gZmFjdG9yeTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVXBkYXRlcyB0aGUgZ2xvYmFsIGxvZ2dpbmcgY29uZmlndXJhdGlvblxuICAgKiBAc3VtbWFyeSBBbGxvd3MgdXBkYXRpbmcgdGhlIGdsb2JhbCBsb2dnaW5nIGNvbmZpZ3VyYXRpb24gd2l0aCBuZXcgc2V0dGluZ3NcbiAgICogQHBhcmFtIHtQYXJ0aWFsPExvZ2dpbmdDb25maWc+fSBjb25maWcgLSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIGFwcGx5XG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzdGF0aWMgc2V0Q29uZmlnKGNvbmZpZzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPik6IHZvaWQge1xuICAgIE9iamVjdC5lbnRyaWVzKGNvbmZpZykuZm9yRWFjaCgoW2ssIHZdKSA9PiB7XG4gICAgICAodGhpcy5fY29uZmlnIGFzIGFueSlba10gPSB2IGFzIGFueTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyBhIGNvcHkgb2YgdGhlIGN1cnJlbnQgZ2xvYmFsIGxvZ2dpbmcgY29uZmlndXJhdGlvblxuICAgKiBAc3VtbWFyeSBSZXR1cm5zIGEgY29weSBvZiB0aGUgY3VycmVudCBnbG9iYWwgbG9nZ2luZyBjb25maWd1cmF0aW9uXG4gICAqIEByZXR1cm4ge0xvZ2dpbmdDb25maWd9IEEgY29weSBvZiB0aGUgY3VycmVudCBjb25maWd1cmF0aW9uXG4gICAqL1xuICBzdGF0aWMgZ2V0Q29uZmlnKCk6IHR5cGVvZiBMb2dnZWRFbnZpcm9ubWVudCB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbmZpZztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIG9yIGNyZWF0ZXMgdGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIGV4aXN0aW5nIGdsb2JhbCBsb2dnZXIgb3IgY3JlYXRlcyBhIG5ldyBvbmUgaWYgaXQgZG9lc24ndCBleGlzdC5cbiAgICpcbiAgICogQHJldHVybiBUaGUgZ2xvYmFsIFZlcmJvc2l0eUxvZ2dlciBpbnN0YW5jZS5cbiAgICovXG4gIHN0YXRpYyBnZXQoKTogTG9nZ2VyIHtcbiAgICB0aGlzLmdsb2JhbCA9IHRoaXMuZ2xvYmFsID8gdGhpcy5nbG9iYWwgOiB0aGlzLl9mYWN0b3J5KFwiTG9nZ2luZ1wiKTtcbiAgICByZXR1cm4gdGhpcy5nbG9iYWw7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSB2ZXJib3NlIG1lc3NhZ2UuXG4gICAqIEBzdW1tYXJ5IERlbGVnYXRlcyB0aGUgdmVyYm9zZSBsb2dnaW5nIHRvIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLlxuICAgKiBAcGFyYW0gdmVyYm9zaXR5IC0gVGhlIHZlcmJvc2l0eSBsZXZlbCBvZiB0aGUgbWVzc2FnZSAoZGVmYXVsdDogMCkuXG4gICAqL1xuICBzdGF0aWMgdmVyYm9zZShtc2c6IFN0cmluZ0xpa2UsIHZlcmJvc2l0eTogbnVtYmVyID0gMCk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmdldCgpLnZlcmJvc2UobXNnLCB2ZXJib3NpdHkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGFuIGluZm8gbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRoZSBpbmZvIGxvZ2dpbmcgdG8gdGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuXG4gICAqL1xuICBzdGF0aWMgaW5mbyhtc2c6IFN0cmluZ0xpa2UpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5pbmZvKG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBkZWJ1ZyBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdGhlIGRlYnVnIGxvZ2dpbmcgdG8gdGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuXG4gICAqL1xuICBzdGF0aWMgZGVidWcobXNnOiBTdHJpbmdMaWtlKTogdm9pZCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkuZGVidWcobXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIGJlbmNobWFyayBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdGhlIGJlbmNobWFyayBsb2dnaW5nIHRvIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLlxuICAgKi9cbiAgc3RhdGljIGJlbmNobWFyayhtc2c6IFN0cmluZ0xpa2UpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5iZW5jaG1hcmsobXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhIHNpbGx5IG1lc3NhZ2UuXG4gICAqIEBzdW1tYXJ5IERlbGVnYXRlcyB0aGUgZGVidWcgbG9nZ2luZyB0byB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC5cbiAgICovXG4gIHN0YXRpYyBzaWxseShtc2c6IFN0cmluZ0xpa2UpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5zaWxseShtc2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGFuIGVycm9yIG1lc3NhZ2UuXG4gICAqIEBzdW1tYXJ5IERlbGVnYXRlcyB0aGUgZXJyb3IgbG9nZ2luZyB0byB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC5cbiAgICogQHBhcmFtIGVcbiAgICovXG4gIHN0YXRpYyBlcnJvcihtc2c6IFN0cmluZ0xpa2UsIGU/OiBFcnJvcik6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmdldCgpLmVycm9yKG1zZywgZSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBsb2dnZXIgZm9yIGEgc3BlY2lmaWMgb2JqZWN0IG9yIGNvbnRleHRcbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIG5ldyBsb2dnZXIgaW5zdGFuY2UgZm9yIHRoZSBnaXZlbiBvYmplY3Qgb3IgY29udGV4dCB1c2luZyB0aGUgZmFjdG9yeSBmdW5jdGlvblxuICAgKiBAcGFyYW0ge0xvZ2dpbmdDb250ZXh0fSBvYmplY3QgLSBUaGUgb2JqZWN0LCBjbGFzcywgb3IgY29udGV4dCB0byBjcmVhdGUgYSBsb2dnZXIgZm9yXG4gICAqIEBwYXJhbSB7UGFydGlhbDxMb2dnaW5nQ29uZmlnPn0gW2NvbmZpZ10gLSBPcHRpb25hbCBjb25maWd1cmF0aW9uIHRvIG92ZXJyaWRlIGdsb2JhbCBzZXR0aW5nc1xuICAgKiBAcGFyYW0gey4uLmFueX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGxvZ2dlciBmYWN0b3J5XG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gQSBuZXcgbG9nZ2VyIGluc3RhbmNlIGZvciB0aGUgc3BlY2lmaWVkIG9iamVjdCBvciBjb250ZXh0XG4gICAqL1xuICBzdGF0aWMgZm9yKFxuICAgIG9iamVjdDogTG9nZ2luZ0NvbnRleHQsXG4gICAgY29uZmlnPzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPixcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBMb2dnZXIge1xuICAgIG9iamVjdCA9XG4gICAgICB0eXBlb2Ygb2JqZWN0ID09PSBcInN0cmluZ1wiXG4gICAgICAgID8gb2JqZWN0XG4gICAgICAgIDogb2JqZWN0LmNvbnN0cnVjdG9yXG4gICAgICAgICAgPyBvYmplY3QuY29uc3RydWN0b3IubmFtZVxuICAgICAgICAgIDogb2JqZWN0Lm5hbWU7XG4gICAgcmV0dXJuIHRoaXMuX2ZhY3Rvcnkob2JqZWN0LCBjb25maWcsIC4uLmFyZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbG9nZ2VyIGZvciBhIHNwZWNpZmljIHJlYXNvbiBvciBjb3JyZWxhdGlvbiBjb250ZXh0XG4gICAqIEBzdW1tYXJ5IFV0aWxpdHkgdG8gcXVpY2tseSBjcmVhdGUgYSBsb2dnZXIgbGFiZWxlZCB3aXRoIGEgZnJlZS1mb3JtIHJlYXNvbiBhbmQgb3B0aW9uYWwgaWRlbnRpZmllclxuICAgKiBzbyB0aGF0IGFkLWhvYyBvcGVyYXRpb25zIGNhbiBiZSB0cmFjZWQgd2l0aG91dCB0eWluZyB0aGUgbG9nZ2VyIHRvIGEgY2xhc3Mgb3IgbWV0aG9kIG5hbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZWFzb24gLSBBIHRleHR1YWwgcmVhc29uIG9yIGNvbnRleHQgbGFiZWwgZm9yIHRoaXMgbG9nZ2VyIGluc3RhbmNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbaWRdIC0gT3B0aW9uYWwgaWRlbnRpZmllciB0byBoZWxwIGNvcnJlbGF0ZSByZWxhdGVkIGxvZyBlbnRyaWVzXG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gQSBuZXcgbG9nZ2VyIGluc3RhbmNlIGxhYmVsZWQgd2l0aCB0aGUgcHJvdmlkZWQgcmVhc29uIGFuZCBpZFxuICAgKi9cbiAgc3RhdGljIGJlY2F1c2UocmVhc29uOiBzdHJpbmcsIGlkPzogc3RyaW5nKTogTG9nZ2VyIHtcbiAgICByZXR1cm4gdGhpcy5fZmFjdG9yeShyZWFzb24sIHRoaXMuX2NvbmZpZywgaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBcHBsaWVzIHRoZW1lIHN0eWxpbmcgdG8gdGV4dFxuICAgKiBAc3VtbWFyeSBBcHBsaWVzIHN0eWxpbmcgKGNvbG9ycywgZm9ybWF0dGluZykgdG8gdGV4dCBiYXNlZCBvbiB0aGUgdGhlbWUgY29uZmlndXJhdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSB0ZXh0IHRvIHN0eWxlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIC0gVGhlIHR5cGUgb2YgZWxlbWVudCB0byBzdHlsZSAoZS5nLiwgXCJjbGFzc1wiLCBcIm1lc3NhZ2VcIiwgXCJsb2dMZXZlbFwiKVxuICAgKiBAcGFyYW0ge0xvZ0xldmVsfSBsb2dnZXJMZXZlbCAtIFRoZSBsb2cgbGV2ZWwgdG8gdXNlIGZvciBzdHlsaW5nXG4gICAqIEBwYXJhbSB7VGhlbWV9IFt0ZW1wbGF0ZT1EZWZhdWx0VGhlbWVdIC0gVGhlIHRoZW1lIHRvIHVzZSBmb3Igc3R5bGluZ1xuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBzdHlsZWQgdGV4dFxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAgICogICBwYXJ0aWNpcGFudCBUaGVtZSBhcyBMb2dnaW5nLnRoZW1lXG4gICAqICAgcGFydGljaXBhbnQgQXBwbHkgYXMgYXBwbHkgZnVuY3Rpb25cbiAgICogICBwYXJ0aWNpcGFudCBTdHlsZSBhcyBzdHlsZWQtc3RyaW5nLWJ1aWxkZXJcbiAgICpcbiAgICogICBDYWxsZXItPj5UaGVtZTogdGhlbWUodGV4dCwgdHlwZSwgbG9nZ2VyTGV2ZWwpXG4gICAqICAgVGhlbWUtPj5UaGVtZTogQ2hlY2sgaWYgc3R5bGluZyBpcyBlbmFibGVkXG4gICAqICAgYWx0IHN0eWxpbmcgZGlzYWJsZWRcbiAgICogICAgIFRoZW1lLS0+PkNhbGxlcjogcmV0dXJuIG9yaWdpbmFsIHRleHRcbiAgICogICBlbHNlIHN0eWxpbmcgZW5hYmxlZFxuICAgKiAgICAgVGhlbWUtPj5UaGVtZTogR2V0IHRoZW1lIGZvciB0eXBlXG4gICAqICAgICBhbHQgdGhlbWUgbm90IGZvdW5kXG4gICAqICAgICAgIFRoZW1lLS0+PkNhbGxlcjogcmV0dXJuIG9yaWdpbmFsIHRleHRcbiAgICogICAgIGVsc2UgdGhlbWUgZm91bmRcbiAgICogICAgICAgVGhlbWUtPj5UaGVtZTogRGV0ZXJtaW5lIGFjdHVhbCB0aGVtZSBiYXNlZCBvbiBsb2cgbGV2ZWxcbiAgICogICAgICAgVGhlbWUtPj5BcHBseTogQXBwbHkgZWFjaCBzdHlsZSBwcm9wZXJ0eVxuICAgKiAgICAgICBBcHBseS0+PlN0eWxlOiBBcHBseSBjb2xvcnMgYW5kIGZvcm1hdHRpbmdcbiAgICogICAgICAgU3R5bGUtLT4+QXBwbHk6IFJldHVybiBzdHlsZWQgdGV4dFxuICAgKiAgICAgICBBcHBseS0tPj5UaGVtZTogUmV0dXJuIHN0eWxlZCB0ZXh0XG4gICAqICAgICAgIFRoZW1lLS0+PkNhbGxlcjogUmV0dXJuIGZpbmFsIHN0eWxlZCB0ZXh0XG4gICAqICAgICBlbmRcbiAgICogICBlbmRcbiAgICovXG4gIHN0YXRpYyB0aGVtZShcbiAgICB0ZXh0OiBzdHJpbmcsXG4gICAgdHlwZToga2V5b2YgVGhlbWUgfCBrZXlvZiBMb2dMZXZlbCxcbiAgICBsb2dnZXJMZXZlbDogTG9nTGV2ZWwsXG4gICAgdGVtcGxhdGU6IFRoZW1lID0gRGVmYXVsdFRoZW1lXG4gICkge1xuICAgIGlmICghdGhpcy5fY29uZmlnLnN0eWxlKSByZXR1cm4gdGV4dDtcbiAgICBjb25zdCBsb2dnZXIgPSBMb2dnaW5nLmdldCgpLmZvcih0aGlzLnRoZW1lKTtcblxuICAgIGZ1bmN0aW9uIGFwcGx5KFxuICAgICAgdHh0OiBzdHJpbmcsXG4gICAgICBvcHRpb246IGtleW9mIFRoZW1lT3B0aW9uLFxuICAgICAgdmFsdWU6IG51bWJlciB8IFtudW1iZXJdIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHwgbnVtYmVyW10gfCBzdHJpbmdbXVxuICAgICk6IHN0cmluZyB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB0OiBzdHJpbmcgfCBTdHlsZWRTdHJpbmcgPSB0eHQ7XG4gICAgICAgIGxldCBjID0gc3R5bGUodCk7XG5cbiAgICAgICAgZnVuY3Rpb24gYXBwbHlDb2xvcihcbiAgICAgICAgICB2YWw6IG51bWJlciB8IFtudW1iZXJdIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgIGlzQmcgPSBmYWxzZVxuICAgICAgICApOiBTdHlsZWRTdHJpbmcge1xuICAgICAgICAgIGxldCBmOlxuICAgICAgICAgICAgfCB0eXBlb2YgYy5iYWNrZ3JvdW5kXG4gICAgICAgICAgICB8IHR5cGVvZiBjLmZvcmVncm91bmRcbiAgICAgICAgICAgIHwgdHlwZW9mIGMucmdiXG4gICAgICAgICAgICB8IHR5cGVvZiBjLmNvbG9yMjU2ID0gaXNCZyA/IGMuYmFja2dyb3VuZCA6IGMuZm9yZWdyb3VuZDtcbiAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsKSkge1xuICAgICAgICAgICAgcmV0dXJuIChmIGFzIHR5cGVvZiBjLmJhY2tncm91bmQgfCB0eXBlb2YgYy5mb3JlZ3JvdW5kKS5jYWxsKFxuICAgICAgICAgICAgICBjLFxuICAgICAgICAgICAgICB2YWx1ZSBhcyBudW1iZXJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHN3aXRjaCAodmFsLmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICBmID0gaXNCZyA/IGMuYmdDb2xvcjI1NiA6IGMuY29sb3IyNTY7XG4gICAgICAgICAgICAgIHJldHVybiAoZiBhcyB0eXBlb2YgYy5iZ0NvbG9yMjU2IHwgdHlwZW9mIGMuY29sb3IyNTYpKHZhbFswXSk7XG4gICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgIGYgPSBpc0JnID8gYy5iZ1JnYiA6IGMucmdiO1xuICAgICAgICAgICAgICByZXR1cm4gYy5yZ2IodmFsWzBdLCB2YWxbMV0sIHZhbFsyXSk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYE5vdCBhIHZhbGlkIGNvbG9yIG9wdGlvbjogJHtvcHRpb259YCk7XG4gICAgICAgICAgICAgIHJldHVybiBzdHlsZSh0IGFzIHN0cmluZyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gYXBwbHlTdHlsZSh2OiBudW1iZXIgfCBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgICBpZiAodHlwZW9mIHYgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIGMgPSBjLnN0eWxlKHYpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjID0gY1t2IGFzIGtleW9mIENvbG9yaXplT3B0aW9uc10gYXMgU3R5bGVkU3RyaW5nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAob3B0aW9uKSB7XG4gICAgICAgICAgY2FzZSBcImJnXCI6XG4gICAgICAgICAgY2FzZSBcImZnXCI6XG4gICAgICAgICAgICByZXR1cm4gYXBwbHlDb2xvcih2YWx1ZSBhcyBudW1iZXIpLnRleHQ7XG4gICAgICAgICAgY2FzZSBcInN0eWxlXCI6XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgdmFsdWUuZm9yRWFjaChhcHBseVN0eWxlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGFwcGx5U3R5bGUodmFsdWUgYXMgbnVtYmVyIHwgc3RyaW5nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjLnRleHQ7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgTm90IGEgdmFsaWQgdGhlbWUgb3B0aW9uOiAke29wdGlvbn1gKTtcbiAgICAgICAgICAgIHJldHVybiB0O1xuICAgICAgICB9XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKGBFcnJvciBhcHBseWluZyBzdHlsZTogJHtvcHRpb259IHdpdGggdmFsdWUgJHt2YWx1ZX1gKTtcbiAgICAgICAgcmV0dXJuIHR4dDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBpbmRpdmlkdWFsVGhlbWUgPSB0ZW1wbGF0ZVt0eXBlIGFzIGtleW9mIFRoZW1lXTtcbiAgICBpZiAoIWluZGl2aWR1YWxUaGVtZSB8fCAhT2JqZWN0LmtleXMoaW5kaXZpZHVhbFRoZW1lKS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0ZXh0O1xuICAgIH1cblxuICAgIGxldCBhY3R1YWxUaGVtZTogVGhlbWVPcHRpb24gPSBpbmRpdmlkdWFsVGhlbWUgYXMgVGhlbWVPcHRpb247XG5cbiAgICBjb25zdCBsb2dMZXZlbHMgPSBPYmplY3QuYXNzaWduKHt9LCBMb2dMZXZlbCk7XG4gICAgaWYgKE9iamVjdC5rZXlzKGluZGl2aWR1YWxUaGVtZSlbMF0gaW4gbG9nTGV2ZWxzKVxuICAgICAgYWN0dWFsVGhlbWUgPVxuICAgICAgICAoaW5kaXZpZHVhbFRoZW1lIGFzIFRoZW1lT3B0aW9uQnlMb2dMZXZlbClbbG9nZ2VyTGV2ZWxdIHx8IHt9O1xuXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGFjdHVhbFRoZW1lKS5yZWR1Y2UoKGFjYzogc3RyaW5nLCBrZXk6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgdmFsID0gKGFjdHVhbFRoZW1lIGFzIFRoZW1lT3B0aW9uKVtrZXkgYXMga2V5b2YgVGhlbWVPcHRpb25dO1xuICAgICAgaWYgKHZhbClcbiAgICAgICAgcmV0dXJuIGFwcGx5KFxuICAgICAgICAgIGFjYyxcbiAgICAgICAgICBrZXkgYXMga2V5b2YgVGhlbWVPcHRpb24sXG4gICAgICAgICAgdmFsIGFzXG4gICAgICAgICAgICB8IG51bWJlclxuICAgICAgICAgICAgfCBbbnVtYmVyXVxuICAgICAgICAgICAgfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl1cbiAgICAgICAgICAgIHwgbnVtYmVyW11cbiAgICAgICAgICAgIHwgc3RyaW5nW11cbiAgICAgICAgKTtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgdGV4dCk7XG4gIH1cbn1cbiIsImltcG9ydCB7IExvZ2dpbmcgfSBmcm9tIFwiLi9sb2dnaW5nXCI7XG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBCYXNlIGNsYXNzIHRoYXQgcHJvdmlkZXMgYSByZWFkeS10by11c2UgbG9nZ2VyIGluc3RhbmNlLlxuICogQHN1bW1hcnkgU3VwcGxpZXMgaW5oZXJpdGluZyBjbGFzc2VzIHdpdGggYSBsYXppbHkgY3JlYXRlZCwgY29udGV4dC1hd2FyZSB7QGxpbmsgTG9nZ2VyfSB2aWEgdGhlIHByb3RlY3RlZCBgbG9nYCBnZXR0ZXIsIHByb21vdGluZyBjb25zaXN0ZW50IHN0cnVjdHVyZWQgbG9nZ2luZyB3aXRob3V0IG1hbnVhbCB3aXJpbmcuXG4gKiBAY2xhc3MgTG9nZ2VkQ2xhc3NcbiAqIEBleGFtcGxlXG4gKiBjbGFzcyBVc2VyU2VydmljZSBleHRlbmRzIExvZ2dlZENsYXNzIHtcbiAqICAgY3JlYXRlKHVzZXI6IFVzZXIpIHtcbiAqICAgICB0aGlzLmxvZy5pbmZvKGBDcmVhdGluZyB1c2VyICR7dXNlci5pZH1gKTtcbiAqICAgfVxuICogfVxuICpcbiAqIGNvbnN0IHN2YyA9IG5ldyBVc2VyU2VydmljZSgpO1xuICogc3ZjLmNyZWF0ZSh7IGlkOiBcIjQyXCIgfSk7XG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICogICBwYXJ0aWNpcGFudCBJbnN0YW5jZSBhcyBTdWJjbGFzcyBJbnN0YW5jZVxuICogICBwYXJ0aWNpcGFudCBHZXR0ZXIgYXMgTG9nZ2VkQ2xhc3MubG9nXG4gKiAgIHBhcnRpY2lwYW50IExvZ2dpbmcgYXMgTG9nZ2luZ1xuICogICBwYXJ0aWNpcGFudCBMb2dnZXIgYXMgTG9nZ2VyXG4gKlxuICogICBDbGllbnQtPj5JbnN0YW5jZTogY2FsbCBzb21lTWV0aG9kKClcbiAqICAgSW5zdGFuY2UtPj5HZXR0ZXI6IGFjY2VzcyB0aGlzLmxvZ1xuICogICBHZXR0ZXItPj5Mb2dnaW5nOiBMb2dnaW5nLmZvcih0aGlzKVxuICogICBMb2dnaW5nLS0+PkdldHRlcjogcmV0dXJuIExvZ2dlclxuICogICBHZXR0ZXItLT4+SW5zdGFuY2U6IHJldHVybiBMb2dnZXJcbiAqICAgSW5zdGFuY2UtPj5Mb2dnZXI6IGluZm8vZGVidWcvZXJyb3IoLi4uKVxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgTG9nZ2VkQ2xhc3Mge1xuICBwcml2YXRlIF9sb2c/OiBMb2dnZXI7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMYXppbHkgcHJvdmlkZXMgYSBjb250ZXh0LWF3YXJlIGxvZ2dlciBmb3IgdGhlIGN1cnJlbnQgaW5zdGFuY2UuXG4gICAqIEBzdW1tYXJ5IENhbGxzIHtAbGluayBMb2dnaW5nLmZvcn0gd2l0aCB0aGUgc3ViY2xhc3MgaW5zdGFuY2UgdG8gb2J0YWluIGEgbG9nZ2VyIHdob3NlIGNvbnRleHQgbWF0Y2hlcyB0aGUgc3ViY2xhc3MgbmFtZS5cbiAgICogQHJldHVybiB7TG9nZ2VyfSBMb2dnZXIgYm91bmQgdG8gdGhlIHN1YmNsYXNzIGNvbnRleHQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IGxvZygpOiBMb2dnZXIge1xuICAgIGlmICghdGhpcy5fbG9nKSB0aGlzLl9sb2cgPSBMb2dnaW5nLmZvcih0aGlzIGFzIGFueSk7XG4gICAgcmV0dXJuIHRoaXMuX2xvZztcbiAgfVxuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcigpIHt9XG59XG4iLCJpbXBvcnQgeyBMb2dnZXIsIExvZ2dpbmdDb25maWcsIExvZ2dpbmdGaWx0ZXIgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IExvZ2dlZENsYXNzIH0gZnJvbSBcIi4uL0xvZ2dlZENsYXNzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEJhc2UgY2xhc3MgZm9yIG1lc3NhZ2UgZmlsdGVycyB0aGF0IHBsdWcgaW50byB0aGUgbG9nZ2luZyBwaXBlbGluZS5cbiAqIEBzdW1tYXJ5IEV4dGVuZHMge0BsaW5rIExvZ2dlZENsYXNzfSB0byBzdXBwbHkgYSBzY29wZWQgbG9nZ2VyIGFuZCBkZWZpbmVzIHRoZSBjb250cmFjdCByZXF1aXJlZCBieSB7QGxpbmsgTG9nZ2luZ0ZpbHRlcn0gaW1wbGVtZW50ZXJzIHRoYXQgdHJhbnNmb3JtIG9yIGRyb3AgbG9nIG1lc3NhZ2VzIGJlZm9yZSBlbWlzc2lvbi5cbiAqIEBjbGFzcyBMb2dGaWx0ZXJcbiAqIEBleGFtcGxlXG4gKiBjbGFzcyBSZWRhY3RTZWNyZXRzRmlsdGVyIGV4dGVuZHMgTG9nRmlsdGVyIHtcbiAqICAgZmlsdGVyKGNvbmZpZzogTG9nZ2luZ0NvbmZpZywgbWVzc2FnZTogc3RyaW5nKTogc3RyaW5nIHtcbiAqICAgICByZXR1cm4gbWVzc2FnZS5yZXBsYWNlKC9zZWNyZXQvZ2ksIFwiKioqXCIpO1xuICogICB9XG4gKiB9XG4gKlxuICogY29uc3QgZmlsdGVyID0gbmV3IFJlZGFjdFNlY3JldHNGaWx0ZXIoKTtcbiAqIGZpbHRlci5maWx0ZXIoeyAuLi5EZWZhdWx0TG9nZ2luZ0NvbmZpZywgdmVyYm9zZTogMCB9LCBcInNlY3JldCB0b2tlblwiKTtcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgTG9nZ2VyXG4gKiAgIHBhcnRpY2lwYW50IEZpbHRlciBhcyBMb2dGaWx0ZXJcbiAqICAgcGFydGljaXBhbnQgSW1wbCBhcyBDb25jcmV0ZUZpbHRlclxuICogICBwYXJ0aWNpcGFudCBPdXRwdXRcbiAqICAgTG9nZ2VyLT4+RmlsdGVyOiBmaWx0ZXIoY29uZmlnLCBtZXNzYWdlLCBjb250ZXh0KVxuICogICBGaWx0ZXItPj5JbXBsOiBkZWxlZ2F0ZSB0byBzdWJjbGFzcyBpbXBsZW1lbnRhdGlvblxuICogICBJbXBsLS0+PkZpbHRlcjogdHJhbnNmb3JtZWQgbWVzc2FnZVxuICogICBGaWx0ZXItLT4+T3V0cHV0OiByZXR1cm4gZmlsdGVyZWQgbWVzc2FnZVxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgTG9nRmlsdGVyIGV4dGVuZHMgTG9nZ2VkQ2xhc3MgaW1wbGVtZW50cyBMb2dnaW5nRmlsdGVyIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTY29wZWQgbG9nZ2VyIHRoYXQgZXhjbHVkZXMgb3RoZXIgZmlsdGVycyBmcm9tIHRoZSBjaGFpbi5cbiAgICogQHN1bW1hcnkgUmV0dXJucyBhIGNoaWxkIGxvZ2dlciBkZWRpY2F0ZWQgdG8gdGhlIGZpbHRlciwgcHJldmVudGluZyByZWN1cnNpdmUgZmlsdGVyIGludm9jYXRpb24gd2hlbiBlbWl0dGluZyBkaWFnbm9zdGljIG1lc3NhZ2VzLlxuICAgKiBAcmV0dXJuIHtMb2dnZXJ9IENvbnRleHQtYXdhcmUgbG9nZ2VyIGZvciB0aGUgZmlsdGVyIGluc3RhbmNlLlxuICAgKi9cbiAgb3ZlcnJpZGUgZ2V0IGxvZygpOiBMb2dnZXIge1xuICAgIHJldHVybiBzdXBlci5sb2cuZm9yKHRoaXMgYXMgYW55LCB7IGZpbHRlcnM6IFtdIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUcmFuc2Zvcm0gb3Igc3VwcHJlc3MgYSBsb2cgbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgSW5zcGVjdCB0aGUgcHJvdmlkZWQgbWVzc2FnZSBhbmQgY29udGV4dCB0byBwcm9kdWNlIHRoZSB2YWx1ZSB0aGF0IHdpbGwgYmUgZm9yd2FyZGVkIHRvIHN1YnNlcXVlbnQgZmlsdGVycyBvciBlbWl0dGVycy5cbiAgICogQHBhcmFtIHtMb2dnaW5nQ29uZmlnfSBjb25maWcgLSBBY3RpdmUgbG9nZ2luZyBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIE9yaWdpbmFsIGxvZyBtZXNzYWdlIHBheWxvYWQuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGNvbnRleHQgLSBDb250ZXh0IHZhbHVlcyBhdHRhY2hlZCB0byB0aGUgbWVzc2FnZS5cbiAgICogQHJldHVybiB7c3RyaW5nfSBGaWx0ZXJlZCBtZXNzYWdlIHRvIHBhc3MgdG8gZG93bnN0cmVhbSBwcm9jZXNzaW5nLlxuICAgKi9cbiAgYWJzdHJhY3QgZmlsdGVyKFxuICAgIGNvbmZpZzogTG9nZ2luZ0NvbmZpZyxcbiAgICBtZXNzYWdlOiBzdHJpbmcsXG4gICAgY29udGV4dDogc3RyaW5nW11cbiAgKTogc3RyaW5nO1xufVxuIiwiLyoqXG4gKiBAZGVzY3JpcHRpb24gU25hcHNob3Qgb2YgYSByZWNvcmRlZCBsYXAgaW50ZXJ2YWwuXG4gKiBAc3VtbWFyeSBDYXB0dXJlcyB0aGUgbGFwIGluZGV4LCBvcHRpb25hbCBsYWJlbCwgZWxhcHNlZCBtaWxsaXNlY29uZHMgZm9yIHRoZSBsYXAsIGFuZCBjdW11bGF0aXZlIGVsYXBzZWQgdGltZSBzaW5jZSB0aGUgc3RvcHdhdGNoIHN0YXJ0ZWQuXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBMYXBcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBpbmRleCAtIFplcm8tYmFzZWQgbGFwIG9yZGVyLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtsYWJlbF0gLSBPcHRpb25hbCBsYWJlbCBkZXNjcmliaW5nIHRoZSBsYXAuXG4gKiBAcHJvcGVydHkge251bWJlcn0gbXMgLSBEdXJhdGlvbiBvZiB0aGUgbGFwIGluIG1pbGxpc2Vjb25kcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB0b3RhbE1zIC0gVG90YWwgZWxhcHNlZCB0aW1lIHdoZW4gdGhlIGxhcCB3YXMgcmVjb3JkZWQuXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IHR5cGUgTGFwID0ge1xuICBpbmRleDogbnVtYmVyO1xuICBsYWJlbD86IHN0cmluZztcbiAgLyoqIER1cmF0aW9uIG9mIHRoaXMgbGFwIGluIG1pbGxpc2Vjb25kcyAqL1xuICBtczogbnVtYmVyO1xuICAvKiogQ3VtdWxhdGl2ZSB0aW1lIHVwIHRvIHRoaXMgbGFwIGluIG1pbGxpc2Vjb25kcyAqL1xuICB0b3RhbE1zOiBudW1iZXI7XG59O1xuXG50eXBlIE5vd0ZuID0gKCkgPT4gbnVtYmVyOyAvLyBtaWxsaXNlY29uZHNcblxuZnVuY3Rpb24gc2FmZU5vdygpOiBOb3dGbiB7XG4gIC8vIFByZWZlciBwZXJmb3JtYW5jZS5ub3cgd2hlbiBhdmFpbGFibGVcbiAgaWYgKFxuICAgIHR5cGVvZiBnbG9iYWxUaGlzICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgdHlwZW9mIGdsb2JhbFRoaXMucGVyZm9ybWFuY2U/Lm5vdyA9PT0gXCJmdW5jdGlvblwiXG4gICkge1xuICAgIHJldHVybiAoKSA9PiBnbG9iYWxUaGlzLnBlcmZvcm1hbmNlLm5vdygpO1xuICB9XG4gIC8vIE5vZGU6IHVzZSBwcm9jZXNzLmhydGltZS5iaWdpbnQgZm9yIGhpZ2hlciBwcmVjaXNpb24gaWYgYXZhaWxhYmxlXG4gIGlmIChcbiAgICB0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgIHR5cGVvZiAocHJvY2VzcyBhcyBhbnkpLmhydGltZT8uYmlnaW50ID09PSBcImZ1bmN0aW9uXCJcbiAgKSB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGNvbnN0IG5zID0gKHByb2Nlc3MgYXMgYW55KS5ocnRpbWUuYmlnaW50KCkgYXMgYmlnaW50OyAvLyBuYW5vc2Vjb25kc1xuICAgICAgcmV0dXJuIE51bWJlcihucykgLyAxXzAwMF8wMDA7IC8vIHRvIG1zXG4gICAgfTtcbiAgfVxuICAvLyBGYWxsYmFja1xuICByZXR1cm4gKCkgPT4gRGF0ZS5ub3coKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gSGlnaC1yZXNvbHV0aW9uIGNsb2NrIGFjY2Vzc29yIHJldHVybmluZyBtaWxsaXNlY29uZHMuXG4gKiBAc3VtbWFyeSBDaG9vc2VzIHRoZSBtb3N0IHByZWNpc2UgdGltZXIgYXZhaWxhYmxlIGluIHRoZSBjdXJyZW50IHJ1bnRpbWUsIHByZWZlcnJpbmcgYHBlcmZvcm1hbmNlLm5vd2Agb3IgYHByb2Nlc3MuaHJ0aW1lLmJpZ2ludGAuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IE1pbGxpc2Vjb25kcyBlbGFwc2VkIGFjY29yZGluZyB0byB0aGUgYmVzdCBhdmFpbGFibGUgY2xvY2suXG4gKi9cbmV4cG9ydCBjb25zdCBub3cgPSBzYWZlTm93KCk7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEhpZ2gtcmVzb2x1dGlvbiBzdG9wd2F0Y2ggd2l0aCBwYXVzZSwgcmVzdW1lLCBhbmQgbGFwIHRyYWNraW5nLlxuICogQHN1bW1hcnkgVHJhY2tzIGVsYXBzZWQgdGltZSB1c2luZyB0aGUgaGlnaGVzdCBwcmVjaXNpb24gdGltZXIgYXZhaWxhYmxlLCBzdXBwb3J0cyBwYXVzaW5nLCByZXN1bWluZywgYW5kIHJlY29yZGluZyBsYWJlbGVkIGxhcHMgZm9yIGRpYWdub3N0aWNzIGFuZCBiZW5jaG1hcmtpbmcuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFthdXRvU3RhcnQ9ZmFsc2VdIC0gV2hlbiB0cnVlLCB0aGUgc3RvcHdhdGNoIHN0YXJ0cyBpbW1lZGlhdGVseSB1cG9uIGNvbnN0cnVjdGlvbi5cbiAqIEBjbGFzcyBTdG9wV2F0Y2hcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzdyA9IG5ldyBTdG9wV2F0Y2godHJ1ZSk7XG4gKiAvLyAuLi4gd29yayAuLi5cbiAqIGNvbnN0IGxhcCA9IHN3LmxhcChcInBoYXNlIDFcIik7XG4gKiBzdy5wYXVzZSgpO1xuICogY29uc29sZS5sb2coYEVsYXBzZWQ6ICR7bGFwLnRvdGFsTXN9bXNgKTtcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IFN0b3BXYXRjaFxuICogICBwYXJ0aWNpcGFudCBDbG9jayBhcyBub3coKVxuICogICBDbGllbnQtPj5TdG9wV2F0Y2g6IHN0YXJ0KClcbiAqICAgU3RvcFdhdGNoLT4+Q2xvY2s6IG5vdygpXG4gKiAgIENsb2NrLS0+PlN0b3BXYXRjaDogdGltZXN0YW1wXG4gKiAgIENsaWVudC0+PlN0b3BXYXRjaDogbGFwKClcbiAqICAgU3RvcFdhdGNoLT4+Q2xvY2s6IG5vdygpXG4gKiAgIENsb2NrLS0+PlN0b3BXYXRjaDogdGltZXN0YW1wXG4gKiAgIFN0b3BXYXRjaC0tPj5DbGllbnQ6IExhcFxuICogICBDbGllbnQtPj5TdG9wV2F0Y2g6IHBhdXNlKClcbiAqICAgU3RvcFdhdGNoLT4+Q2xvY2s6IG5vdygpXG4gKiAgIENsb2NrLS0+PlN0b3BXYXRjaDogdGltZXN0YW1wXG4gKi9cbmV4cG9ydCBjbGFzcyBTdG9wV2F0Y2gge1xuICBwcml2YXRlIF9zdGFydE1zOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfZWxhcHNlZE1zID0gMDtcbiAgcHJpdmF0ZSBfcnVubmluZyA9IGZhbHNlO1xuICBwcml2YXRlIF9sYXBzOiBMYXBbXSA9IFtdO1xuICBwcml2YXRlIF9sYXN0TGFwVG90YWxNcyA9IDA7XG5cbiAgY29uc3RydWN0b3IoYXV0b1N0YXJ0ID0gZmFsc2UpIHtcbiAgICBpZiAoYXV0b1N0YXJ0KSB0aGlzLnN0YXJ0KCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzdG9wd2F0Y2ggaXMgYWN0aXZlbHkgcnVubmluZy5cbiAgICogQHN1bW1hcnkgUmV0dXJucyBgdHJ1ZWAgd2hlbiB0aW1pbmcgaXMgaW4gcHJvZ3Jlc3MgYW5kIGBmYWxzZWAgd2hlbiBwYXVzZWQgb3Igc3RvcHBlZC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gQ3VycmVudCBydW5uaW5nIHN0YXRlLlxuICAgKi9cbiAgZ2V0IHJ1bm5pbmcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3J1bm5pbmc7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEVsYXBzZWQgdGltZSBjYXB0dXJlZCBieSB0aGUgc3RvcHdhdGNoLlxuICAgKiBAc3VtbWFyeSBDb21wdXRlcyB0aGUgdG90YWwgZWxhcHNlZCB0aW1lIGluIG1pbGxpc2Vjb25kcywgaW5jbHVkaW5nIHRoZSBjdXJyZW50IHNlc3Npb24gaWYgcnVubmluZy5cbiAgICogQHJldHVybiB7bnVtYmVyfSBNaWxsaXNlY29uZHMgZWxhcHNlZCBzaW5jZSB0aGUgc3RvcHdhdGNoIHN0YXJ0ZWQuXG4gICAqL1xuICBnZXQgZWxhcHNlZE1zKCk6IG51bWJlciB7XG4gICAgaWYgKCF0aGlzLl9ydW5uaW5nIHx8IHRoaXMuX3N0YXJ0TXMgPT0gbnVsbCkgcmV0dXJuIHRoaXMuX2VsYXBzZWRNcztcbiAgICByZXR1cm4gdGhpcy5fZWxhcHNlZE1zICsgKG5vdygpIC0gdGhpcy5fc3RhcnRNcyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFN0YXJ0cyB0aW1pbmcgaWYgdGhlIHN0b3B3YXRjaCBpcyBub3QgYWxyZWFkeSBydW5uaW5nLlxuICAgKiBAc3VtbWFyeSBSZWNvcmRzIHRoZSBjdXJyZW50IHRpbWVzdGFtcCBhbmQgdHJhbnNpdGlvbnMgdGhlIHN0b3B3YXRjaCBpbnRvIHRoZSBydW5uaW5nIHN0YXRlLlxuICAgKiBAcmV0dXJuIHt0aGlzfSBGbHVlbnQgcmVmZXJlbmNlIHRvIHRoZSBzdG9wd2F0Y2guXG4gICAqL1xuICBzdGFydCgpOiB0aGlzIHtcbiAgICBpZiAoIXRoaXMuX3J1bm5pbmcpIHtcbiAgICAgIHRoaXMuX3J1bm5pbmcgPSB0cnVlO1xuICAgICAgdGhpcy5fc3RhcnRNcyA9IG5vdygpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUGF1c2VzIHRpbWluZyBhbmQgYWNjdW11bGF0ZXMgZWxhcHNlZCBtaWxsaXNlY29uZHMuXG4gICAqIEBzdW1tYXJ5IENhcHR1cmVzIHRoZSBwYXJ0aWFsIGR1cmF0aW9uLCB1cGRhdGVzIHRoZSBhY2N1bXVsYXRvciwgYW5kIGtlZXBzIHRoZSBzdG9wd2F0Y2ggcmVhZHkgdG8gcmVzdW1lIGxhdGVyLlxuICAgKiBAcmV0dXJuIHt0aGlzfSBGbHVlbnQgcmVmZXJlbmNlIHRvIHRoZSBzdG9wd2F0Y2guXG4gICAqL1xuICBwYXVzZSgpOiB0aGlzIHtcbiAgICBpZiAodGhpcy5fcnVubmluZyAmJiB0aGlzLl9zdGFydE1zICE9IG51bGwpIHtcbiAgICAgIHRoaXMuX2VsYXBzZWRNcyArPSBub3coKSAtIHRoaXMuX3N0YXJ0TXM7XG4gICAgICB0aGlzLl9zdGFydE1zID0gbnVsbDtcbiAgICAgIHRoaXMuX3J1bm5pbmcgPSBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlc3VtZXMgdGltaW5nIGFmdGVyIGEgcGF1c2UuXG4gICAqIEBzdW1tYXJ5IENhcHR1cmVzIGEgZnJlc2ggc3RhcnQgdGltZXN0YW1wIHdoaWxlIGtlZXBpbmcgcHJldmlvdXMgZWxhcHNlZCB0aW1lIGludGFjdC5cbiAgICogQHJldHVybiB7dGhpc30gRmx1ZW50IHJlZmVyZW5jZSB0byB0aGUgc3RvcHdhdGNoLlxuICAgKi9cbiAgcmVzdW1lKCk6IHRoaXMge1xuICAgIGlmICghdGhpcy5fcnVubmluZykge1xuICAgICAgdGhpcy5fcnVubmluZyA9IHRydWU7XG4gICAgICB0aGlzLl9zdGFydE1zID0gbm93KCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTdG9wcyB0aW1pbmcgYW5kIHJldHVybnMgdGhlIHRvdGFsIGVsYXBzZWQgbWlsbGlzZWNvbmRzLlxuICAgKiBAc3VtbWFyeSBJbnZva2VzIHtAbGluayBTdG9wV2F0Y2gucGF1c2V9IHRvIGNvbnNvbGlkYXRlIGVsYXBzZWQgdGltZSwgbGVhdmluZyB0aGUgc3RvcHdhdGNoIGluIGEgbm9uLXJ1bm5pbmcgc3RhdGUuXG4gICAqIEByZXR1cm4ge251bWJlcn0gTWlsbGlzZWNvbmRzIGFjY3VtdWxhdGVkIGFjcm9zcyBhbGwgcnVucy5cbiAgICovXG4gIHN0b3AoKTogbnVtYmVyIHtcbiAgICB0aGlzLnBhdXNlKCk7XG4gICAgcmV0dXJuIHRoaXMuX2VsYXBzZWRNcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVzZXRzIHRoZSBzdG9wd2F0Y2ggc3RhdGUgd2hpbGUgb3B0aW9uYWxseSBjb250aW51aW5nIHRvIHJ1bi5cbiAgICogQHN1bW1hcnkgQ2xlYXJzIGVsYXBzZWQgdGltZSBhbmQgbGFwIGhpc3RvcnksIHByZXNlcnZpbmcgd2hldGhlciB0aGUgc3RvcHdhdGNoIHNob3VsZCBjb250aW51ZSB0aWNraW5nLlxuICAgKiBAcmV0dXJuIHt0aGlzfSBGbHVlbnQgcmVmZXJlbmNlIHRvIHRoZSBzdG9wd2F0Y2guXG4gICAqL1xuICByZXNldCgpOiB0aGlzIHtcbiAgICBjb25zdCB3YXNSdW5uaW5nID0gdGhpcy5fcnVubmluZztcbiAgICB0aGlzLl9zdGFydE1zID0gd2FzUnVubmluZyA/IG5vdygpIDogbnVsbDtcbiAgICB0aGlzLl9lbGFwc2VkTXMgPSAwO1xuICAgIHRoaXMuX2xhcHMgPSBbXTtcbiAgICB0aGlzLl9sYXN0TGFwVG90YWxNcyA9IDA7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlY29yZHMgYSBsYXAgc3BsaXQgc2luY2UgdGhlIHN0b3B3YXRjaCBzdGFydGVkIG9yIHNpbmNlIHRoZSBwcmV2aW91cyBsYXAuXG4gICAqIEBzdW1tYXJ5IFN0b3JlcyB0aGUgbGFwIG1ldGFkYXRhLCB1cGRhdGVzIGN1bXVsYXRpdmUgdHJhY2tpbmcsIGFuZCByZXR1cm5zIHRoZSBuZXdseSBjcmVhdGVkIHtAbGluayBMYXB9LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhYmVsXSAtIE9wdGlvbmFsIGxhYmVsIGRlc2NyaWJpbmcgdGhlIGxhcC5cbiAgICogQHJldHVybiB7TGFwfSBMYXAgc25hcHNob3QgY2FwdHVyaW5nIGluY3JlbWVudGFsIGFuZCBjdW11bGF0aXZlIHRpbWluZ3MuXG4gICAqL1xuICBsYXAobGFiZWw/OiBzdHJpbmcpOiBMYXAge1xuICAgIGNvbnN0IHRvdGFsID0gdGhpcy5lbGFwc2VkTXM7XG4gICAgY29uc3QgbXMgPSB0b3RhbCAtIHRoaXMuX2xhc3RMYXBUb3RhbE1zO1xuICAgIGNvbnN0IGxhcDogTGFwID0ge1xuICAgICAgaW5kZXg6IHRoaXMuX2xhcHMubGVuZ3RoLFxuICAgICAgbGFiZWwsXG4gICAgICBtcyxcbiAgICAgIHRvdGFsTXM6IHRvdGFsLFxuICAgIH07XG4gICAgdGhpcy5fbGFwcy5wdXNoKGxhcCk7XG4gICAgdGhpcy5fbGFzdExhcFRvdGFsTXMgPSB0b3RhbDtcbiAgICByZXR1cm4gbGFwO1xuICB9XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIHRoZSByZWNvcmRlZCBsYXAgaGlzdG9yeS5cbiAgICogQHN1bW1hcnkgUmV0dXJucyB0aGUgaW50ZXJuYWwgbGFwIGFycmF5IGFzIGEgcmVhZC1vbmx5IHZpZXcgdG8gcHJldmVudCBleHRlcm5hbCBtdXRhdGlvbi5cbiAgICogQHJldHVybiB7TGFwW119IExhcHMgY2FwdHVyZWQgYnkgdGhlIHN0b3B3YXRjaC5cbiAgICovXG4gIGdldCBsYXBzKCk6IHJlYWRvbmx5IExhcFtdIHtcbiAgICByZXR1cm4gdGhpcy5fbGFwcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRm9ybWF0cyB0aGUgZWxhcHNlZCB0aW1lIGluIGEgaHVtYW4tcmVhZGFibGUgcmVwcmVzZW50YXRpb24uXG4gICAqIEBzdW1tYXJ5IFVzZXMge0BsaW5rIGZvcm1hdE1zfSB0byBwcm9kdWNlIGFuIGBoaDptbTpzcy5tbW1gIHN0cmluZyBmb3IgZGlzcGxheSBhbmQgbG9nZ2luZy5cbiAgICogQHJldHVybiB7c3RyaW5nfSBFbGFwc2VkIHRpbWUgZm9ybWF0dGVkIGZvciBwcmVzZW50YXRpb24uXG4gICAqL1xuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBmb3JtYXRNcyh0aGlzLmVsYXBzZWRNcyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNlcmlhbGl6ZXMgdGhlIHN0b3B3YXRjaCBzdGF0ZS5cbiAgICogQHN1bW1hcnkgUHJvdmlkZXMgYSBKU09OLWZyaWVuZGx5IHNuYXBzaG90IGluY2x1ZGluZyBydW5uaW5nIHN0YXRlLCBlbGFwc2VkIHRpbWUsIGFuZCBsYXAgZGV0YWlscy5cbiAgICogQHJldHVybiB7e3J1bm5pbmc6IGJvb2xlYW4sIGVsYXBzZWRNczogbnVtYmVyLCBsYXBzOiBMYXBbXX19IFNlcmlhbGl6YWJsZSBzdG9wd2F0Y2ggcmVwcmVzZW50YXRpb24uXG4gICAqL1xuICB0b0pTT04oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHJ1bm5pbmc6IHRoaXMuX3J1bm5pbmcsXG4gICAgICBlbGFwc2VkTXM6IHRoaXMuZWxhcHNlZE1zLFxuICAgICAgbGFwczogdGhpcy5fbGFwcy5zbGljZSgpLFxuICAgIH07XG4gIH1cbn1cbi8qKlxuICogQGRlc2NyaXB0aW9uIEZvcm1hdHMgbWlsbGlzZWNvbmRzIGludG8gYGhoOm1tOnNzLm1tbWAuXG4gKiBAc3VtbWFyeSBCcmVha3MgdGhlIGR1cmF0aW9uIGludG8gaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMsIGFuZCBtaWxsaXNlY29uZHMsIHJldHVybmluZyBhIHplcm8tcGFkZGVkIHN0cmluZy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtcyAtIE1pbGxpc2Vjb25kcyB0byBmb3JtYXQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IEZvcm1hdHRlZCBkdXJhdGlvbiBzdHJpbmcuXG4gKiBAZnVuY3Rpb24gZm9ybWF0TXNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgRm9ybWF0dGVyIGFzIGZvcm1hdE1zXG4gKiAgIENhbGxlci0+PkZvcm1hdHRlcjogZm9ybWF0TXMobXMpXG4gKiAgIEZvcm1hdHRlci0+PkZvcm1hdHRlcjogZGVyaXZlIGhvdXJzL21pbnV0ZXMvc2Vjb25kc1xuICogICBGb3JtYXR0ZXItPj5Gb3JtYXR0ZXI6IHBhZCBzZWdtZW50c1xuICogICBGb3JtYXR0ZXItLT4+Q2FsbGVyOiBoaDptbTpzcy5tbW1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdE1zKG1zOiBudW1iZXIpOiBzdHJpbmcge1xuICBjb25zdCBzaWduID0gbXMgPCAwID8gXCItXCIgOiBcIlwiO1xuICBjb25zdCBhYnMgPSBNYXRoLmFicyhtcyk7XG4gIGNvbnN0IGhvdXJzID0gTWF0aC5mbG9vcihhYnMgLyAzXzYwMF8wMDApO1xuICBjb25zdCBtaW51dGVzID0gTWF0aC5mbG9vcigoYWJzICUgM182MDBfMDAwKSAvIDYwXzAwMCk7XG4gIGNvbnN0IHNlY29uZHMgPSBNYXRoLmZsb29yKChhYnMgJSA2MF8wMDApIC8gMTAwMCk7XG4gIGNvbnN0IG1pbGxpcyA9IE1hdGguZmxvb3IoYWJzICUgMTAwMCk7XG4gIGNvbnN0IHBhZCA9IChuOiBudW1iZXIsIHc6IG51bWJlcikgPT4gbi50b1N0cmluZygpLnBhZFN0YXJ0KHcsIFwiMFwiKTtcbiAgcmV0dXJuIGAke3NpZ259JHtwYWQoaG91cnMsIDIpfToke3BhZChtaW51dGVzLCAyKX06JHtwYWQoc2Vjb25kcywgMil9LiR7cGFkKG1pbGxpcywgMyl9YDtcbn1cbiIsImltcG9ydCB7IExvZ0xldmVsIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSBcIi4vbG9nZ2luZ1wiO1xuaW1wb3J0IHsgbm93IH0gZnJvbSBcIi4vdGltZVwiO1xuaW1wb3J0IHsgTG9nZ2VkQ2xhc3MgfSBmcm9tIFwiLi9Mb2dnZWRDbGFzc1wiO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuZXhwb3J0IHR5cGUgQXJnRm9ybWF0RnVuY3Rpb24gPSAoLi4uYXJnczogYW55W10pID0+IHN0cmluZztcbmV4cG9ydCB0eXBlIFJldHVybkZvcm1hdEZ1bmN0aW9uID0gKGU/OiBFcnJvciwgcmVzdWx0PzogYW55KSA9PiBzdHJpbmc7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMuXG4gKiBAc3VtbWFyeSBXcmFwcyBjbGFzcyBtZXRob2RzIHRvIGF1dG9tYXRpY2FsbHkgbG9nIGVudHJ5LCBleGl0LCB0aW1pbmcsIGFuZCBvcHRpb25hbCBjdXN0b20gbWVzc2FnZXMgYXQgYSBjb25maWd1cmFibGUge0BsaW5rIExvZ0xldmVsfS5cbiAqIEBwYXJhbSB7TG9nTGV2ZWx9IGxldmVsIC0gTG9nIGxldmVsIGFwcGxpZWQgdG8gdGhlIGdlbmVyYXRlZCBsb2cgc3RhdGVtZW50cyAoZGVmYXVsdHMgdG8gYExvZ0xldmVsLmluZm9gKS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbdmVyYm9zaXR5PTBdIC0gVmVyYm9zaXR5IHRocmVzaG9sZCByZXF1aXJlZCBmb3IgdGhlIGVudHJ5IGxvZyB0byBhcHBlYXIuXG4gKiBAcGFyYW0ge0FyZ0Zvcm1hdEZ1bmN0aW9ufSBbZW50cnlNZXNzYWdlXSAtIEZvcm1hdHRlciBpbnZva2VkIHdpdGggdGhlIG9yaWdpbmFsIG1ldGhvZCBhcmd1bWVudHMgdG8gZGVzY3JpYmUgdGhlIGludm9jYXRpb24uXG4gKiBAcGFyYW0ge1JldHVybkZvcm1hdEZ1bmN0aW9ufSBbZXhpdE1lc3NhZ2VdIC0gT3B0aW9uYWwgZm9ybWF0dGVyIHRoYXQgZGVzY3JpYmVzIHRoZSBvdXRjb21lIG9yIGZhaWx1cmUgb2YgdGhlIGNhbGwuXG4gKiBAcmV0dXJuIHtmdW5jdGlvbihhbnksIGFueSwgUHJvcGVydHlEZXNjcmlwdG9yKTogdm9pZH0gTWV0aG9kIGRlY29yYXRvciBwcm94eSB0aGF0IGluamVjdHMgbG9nZ2luZyBiZWhhdmlvci5cbiAqIEBmdW5jdGlvbiBsb2dcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IERlY29yYXRvciBhcyBsb2cgZGVjb3JhdG9yXG4gKiAgIHBhcnRpY2lwYW50IE1ldGhvZCBhcyBPcmlnaW5hbCBNZXRob2RcbiAqICAgcGFydGljaXBhbnQgTG9nZ2VyIGFzIExvZ2dpbmcgaW5zdGFuY2VcbiAqXG4gKiAgIENsaWVudC0+PkRlY29yYXRvcjogY2FsbCBkZWNvcmF0ZWQgbWV0aG9kXG4gKiAgIERlY29yYXRvci0+PkxvZ2dlcjogbG9nIG1ldGhvZCBjYWxsXG4gKiAgIERlY29yYXRvci0+Pk1ldGhvZDogY2FsbCBvcmlnaW5hbCBtZXRob2RcbiAqICAgYWx0IHJlc3VsdCBpcyBQcm9taXNlXG4gKiAgICAgTWV0aG9kLS0+PkRlY29yYXRvcjogcmV0dXJuIFByb21pc2VcbiAqICAgICBEZWNvcmF0b3ItPj5EZWNvcmF0b3I6IGF0dGFjaCB0aGVuIGhhbmRsZXJcbiAqICAgICBOb3RlIG92ZXIgRGVjb3JhdG9yOiBQcm9taXNlIHJlc29sdmVzXG4gKiAgICAgRGVjb3JhdG9yLT4+TG9nZ2VyOiBsb2cgYmVuY2htYXJrIChpZiBlbmFibGVkKVxuICogICAgIERlY29yYXRvci0tPj5DbGllbnQ6IHJldHVybiByZXN1bHRcbiAqICAgZWxzZSByZXN1bHQgaXMgbm90IFByb21pc2VcbiAqICAgICBNZXRob2QtLT4+RGVjb3JhdG9yOiByZXR1cm4gcmVzdWx0XG4gKiAgICAgRGVjb3JhdG9yLT4+TG9nZ2VyOiBsb2cgYmVuY2htYXJrIChpZiBlbmFibGVkKVxuICogICAgIERlY29yYXRvci0tPj5DbGllbnQ6IHJldHVybiByZXN1bHRcbiAqICAgZW5kXG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvZyhcbiAgbGV2ZWw6IExvZ0xldmVsID0gTG9nTGV2ZWwuaW5mbyxcbiAgdmVyYm9zaXR5ID0gMCxcbiAgZW50cnlNZXNzYWdlOiBBcmdGb3JtYXRGdW5jdGlvbiA9ICguLi5hcmdzOiBhbnlbXSkgPT4gYGNhbGxlZCB3aXRoICR7YXJnc31gLFxuICBleGl0TWVzc2FnZT86IFJldHVybkZvcm1hdEZ1bmN0aW9uXG4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGxvZyh0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk/OiBhbnksIGRlc2NyaXB0b3I/OiBhbnkpIHtcbiAgICBpZiAoIWRlc2NyaXB0b3IgfHwgdHlwZW9mIGRlc2NyaXB0b3IgPT09IFwibnVtYmVyXCIpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYExvZ2dpbmcgZGVjb3JhdGlvbiBvbmx5IGFwcGxpZXMgdG8gbWV0aG9kc2ApO1xuICAgIGNvbnN0IGxvZ2dlcjogTG9nZ2VyID1cbiAgICAgIHRhcmdldCBpbnN0YW5jZW9mIExvZ2dlZENsYXNzXG4gICAgICAgID8gdGFyZ2V0W1wibG9nXCJdLmZvcih0YXJnZXRbcHJvcGVydHlLZXkgYXMga2V5b2YgdHlwZW9mIHRhcmdldF0pXG4gICAgICAgIDogTG9nZ2luZy5mb3IodGFyZ2V0KS5mb3IodGFyZ2V0W3Byb3BlcnR5S2V5XSk7XG4gICAgY29uc3QgbWV0aG9kID0gbG9nZ2VyW2xldmVsXS5iaW5kKGxvZ2dlcikgYXMgYW55O1xuICAgIGNvbnN0IG9yaWdpbmFsTWV0aG9kID0gZGVzY3JpcHRvci52YWx1ZTtcblxuICAgIGRlc2NyaXB0b3IudmFsdWUgPSBuZXcgUHJveHkob3JpZ2luYWxNZXRob2QsIHtcbiAgICAgIGFwcGx5KGZuLCB0aGlzQXJnLCBhcmdzOiBhbnlbXSkge1xuICAgICAgICBtZXRob2QoZW50cnlNZXNzYWdlKC4uLmFyZ3MpLCB2ZXJib3NpdHkpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuYXBwbHkoZm4sIHRoaXNBcmcsIGFyZ3MpO1xuICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgICAgICAgICAgIC50aGVuKChyOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXhpdE1lc3NhZ2UpIG1ldGhvZChleGl0TWVzc2FnZSh1bmRlZmluZWQsIHIpKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcjtcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGV4aXRNZXNzYWdlKSBsb2dnZXIuZXJyb3IoZXhpdE1lc3NhZ2UoZSBhcyBFcnJvcikpO1xuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZXhpdE1lc3NhZ2UpIG1ldGhvZChleGl0TWVzc2FnZSh1bmRlZmluZWQsIHJlc3VsdCkpO1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0gY2F0Y2ggKGVycjogdW5rbm93bikge1xuICAgICAgICAgIGlmIChleGl0TWVzc2FnZSkgbG9nZ2VyLmVycm9yKGV4aXRNZXNzYWdlKGVyciBhcyBFcnJvcikpO1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcbiAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgfTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciB0aGF0IHJlY29yZHMgZXhlY3V0aW9uIHRpbWUgYXQgdGhlIGJlbmNobWFyayBsZXZlbC5cbiAqIEBzdW1tYXJ5IFdyYXBzIHRoZSB0YXJnZXQgbWV0aG9kIHRvIGVtaXQge0BsaW5rIExvZ2dlci5iZW5jaG1hcmt9IGVudHJpZXMgY2FwdHVyaW5nIGNvbXBsZXRpb24gdGltZSBvciBmYWlsdXJlIGxhdGVuY3kuXG4gKiBAcmV0dXJuIHtmdW5jdGlvbihhbnksIGFueSwgIFByb3BlcnR5RGVzY3JpcHRvcik6IHZvaWR9IE1ldGhvZCBkZWNvcmF0b3IgcHJveHkgdGhhdCBiZW5jaG1hcmtzIHRoZSBvcmlnaW5hbCBpbXBsZW1lbnRhdGlvbi5cbiAqIEBmdW5jdGlvbiBiZW5jaG1hcmtcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IERlY29yYXRvciBhcyBiZW5jaG1hcmtcbiAqICAgcGFydGljaXBhbnQgTWV0aG9kIGFzIE9yaWdpbmFsIE1ldGhvZFxuICogICBDYWxsZXItPj5EZWNvcmF0b3I6IGludm9rZSgpXG4gKiAgIERlY29yYXRvci0+Pk1ldGhvZDogUmVmbGVjdC5hcHBseSguLi4pXG4gKiAgIGFsdCBQcm9taXNlIHJlc3VsdFxuICogICAgIE1ldGhvZC0tPj5EZWNvcmF0b3I6IFByb21pc2VcbiAqICAgICBEZWNvcmF0b3ItPj5EZWNvcmF0b3I6IGF0dGFjaCB0aGVuKClcbiAqICAgICBEZWNvcmF0b3ItPj5EZWNvcmF0b3I6IGxvZyBjb21wbGV0aW9uIGR1cmF0aW9uXG4gKiAgIGVsc2UgU3luY2hyb25vdXMgcmVzdWx0XG4gKiAgICAgTWV0aG9kLS0+PkRlY29yYXRvcjogdmFsdWVcbiAqICAgICBEZWNvcmF0b3ItPj5EZWNvcmF0b3I6IGxvZyBjb21wbGV0aW9uIGR1cmF0aW9uXG4gKiAgIGVuZFxuICogICBEZWNvcmF0b3ItLT4+Q2FsbGVyOiByZXR1cm4gcmVzdWx0XG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJlbmNobWFyaygpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGJlbmNobWFyayh0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk/OiBhbnksIGRlc2NyaXB0b3I/OiBhbnkpIHtcbiAgICBpZiAoIWRlc2NyaXB0b3IgfHwgdHlwZW9mIGRlc2NyaXB0b3IgPT09IFwibnVtYmVyXCIpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGJlbmNobWFyayBkZWNvcmF0aW9uIG9ubHkgYXBwbGllcyB0byBtZXRob2RzYCk7XG4gICAgY29uc3QgbG9nZ2VyOiBMb2dnZXIgPVxuICAgICAgdGFyZ2V0IGluc3RhbmNlb2YgTG9nZ2VkQ2xhc3NcbiAgICAgICAgPyB0YXJnZXRbXCJsb2dcIl0uZm9yKHRhcmdldFtwcm9wZXJ0eUtleSBhcyBrZXlvZiB0eXBlb2YgdGFyZ2V0XSlcbiAgICAgICAgOiBMb2dnaW5nLmZvcih0YXJnZXQpLmZvcih0YXJnZXRbcHJvcGVydHlLZXldKTtcbiAgICBjb25zdCBvcmlnaW5hbE1ldGhvZCA9IGRlc2NyaXB0b3IudmFsdWU7XG5cbiAgICBkZXNjcmlwdG9yLnZhbHVlID0gbmV3IFByb3h5KG9yaWdpbmFsTWV0aG9kLCB7XG4gICAgICBhcHBseShmbiwgdGhpc0FyZywgYXJnczogYW55W10pIHtcbiAgICAgICAgY29uc3Qgc3RhcnQgPSBub3coKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBSZWZsZWN0LmFwcGx5KGZuLCB0aGlzQXJnLCBhcmdzKTtcbiAgICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50aGVuKChyOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgbG9nZ2VyLmJlbmNobWFyayhgY29tcGxldGVkIGluICR7bm93KCkgLSBzdGFydH1tc2ApO1xuICAgICAgICAgICAgICByZXR1cm4gcjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBsb2dnZXIuYmVuY2htYXJrKGBjb21wbGV0ZWQgaW4gJHtub3coKSAtIHN0YXJ0fW1zYCk7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICAgICAgbG9nZ2VyLmJlbmNobWFyayhgZmFpbGVkIGluICR7bm93KCkgLSBzdGFydH1tc2ApO1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHJldHVybiBkZXNjcmlwdG9yO1xuICB9O1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggZGVidWcgbGV2ZWwuXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB7QGxpbmsgbG9nfSB0aGF0IGxvZ3MgdXNpbmcgYExvZ0xldmVsLmRlYnVnYC5cbiAqIEByZXR1cm4ge2Z1bmN0aW9uKGFueSwgYW55LCBQcm9wZXJ0eURlc2NyaXB0b3IpOiB2b2lkfSBEZWJ1Zy1sZXZlbCBsb2dnaW5nIGRlY29yYXRvci5cbiAqIEBmdW5jdGlvbiBkZWJ1Z1xuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWJ1ZygpIHtcbiAgcmV0dXJuIGxvZyhcbiAgICBMb2dMZXZlbC5kZWJ1ZyxcbiAgICAwLFxuICAgICguLi5hcmdzOiBhbnlbXSkgPT4gYGNhbGxlZCB3aXRoICR7YXJnc31gLFxuICAgIChlPzogRXJyb3IsIHJlc3VsdD86IGFueSkgPT5cbiAgICAgIGVcbiAgICAgICAgPyBgRmFpbGVkIHdpdGg6ICR7ZX1gXG4gICAgICAgIDogcmVzdWx0XG4gICAgICAgICAgPyBgQ29tcGxldGVkIHdpdGggJHtKU09OLnN0cmluZ2lmeShyZXN1bHQpfWBcbiAgICAgICAgICA6IFwiY29tcGxldGVkXCJcbiAgKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIGluZm8gbGV2ZWwuXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB7QGxpbmsgbG9nfSB0aGF0IGxvZ3MgdXNpbmcgYExvZ0xldmVsLmluZm9gLlxuICogQHJldHVybiB7ZnVuY3Rpb24oYW55LCBhbnksIFByb3BlcnR5RGVzY3JpcHRvcik6IHZvaWR9IEluZm8tbGV2ZWwgbG9nZ2luZyBkZWNvcmF0b3IuXG4gKiBAZnVuY3Rpb24gaW5mb1xuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmZvKCkge1xuICByZXR1cm4gbG9nKExvZ0xldmVsLmluZm8pO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggc2lsbHkgbGV2ZWwuXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB7QGxpbmsgbG9nfSB0aGF0IGxvZ3MgdXNpbmcgYExvZ0xldmVsLnNpbGx5YC5cbiAqIEByZXR1cm4ge2Z1bmN0aW9uKGFueSwgYW55LCBQcm9wZXJ0eURlc2NyaXB0b3IpOiB2b2lkfSBTaWxseS1sZXZlbCBsb2dnaW5nIGRlY29yYXRvci5cbiAqIEBmdW5jdGlvbiBzaWxseVxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzaWxseSgpIHtcbiAgcmV0dXJuIGxvZyhMb2dMZXZlbC5zaWxseSk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCB2ZXJib3NlIGxldmVsLlxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQge0BsaW5rIGxvZ30gdGhhdCBsb2dzIHVzaW5nIGBMb2dMZXZlbC52ZXJib3NlYCB3aXRoIGNvbmZpZ3VyYWJsZSB2ZXJib3NpdHkuXG4gKiBAcmV0dXJuIHtmdW5jdGlvbihhbnksIGFueSwgUHJvcGVydHlEZXNjcmlwdG9yKTogdm9pZH0gVmVyYm9zZSBsb2dnaW5nIGRlY29yYXRvci5cbiAqIEBmdW5jdGlvbiB2ZXJib3NlXG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcmJvc2UoKTogKFxuICB0YXJnZXQ6IGFueSxcbiAgcHJvcGVydHlLZXk/OiBhbnksXG4gIGRlc2NyaXB0b3I/OiBhbnlcbikgPT4gdm9pZDtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIHZlcmJvc2UgbGV2ZWwuXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB7QGxpbmsgbG9nfSB0aGF0IGxvZ3MgdXNpbmcgYExvZ0xldmVsLnZlcmJvc2VgIHdoaWxlIHRvZ2dsaW5nIGJlbmNobWFya2luZy5cbiAqIEByZXR1cm4ge2Z1bmN0aW9uKGFueSwgUHJvcGVydHlEZXNjcmlwdG9yKTogdm9pZH0gVmVyYm9zZSBsb2dnaW5nIGRlY29yYXRvci5cbiAqIEBmdW5jdGlvbiB2ZXJib3NlXG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcmJvc2UoKTogKFxuICB0YXJnZXQ6IGFueSxcbiAgcHJvcGVydHlLZXk/OiBhbnksXG4gIGRlc2NyaXB0b3I/OiBhbnlcbikgPT4gdm9pZDtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIHZlcmJvc2UgbGV2ZWwuXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB7QGxpbmsgbG9nfSB0aGF0IGxvZ3MgdXNpbmcgYExvZ0xldmVsLnZlcmJvc2VgIHdpdGggY29uZmlndXJhYmxlIHZlcmJvc2l0eSBhbmQgb3B0aW9uYWwgYmVuY2htYXJraW5nLlxuICogQHBhcmFtIHtudW1iZXJ8Ym9vbGVhbn0gdmVyYm9zaXR5IC0gVmVyYm9zaXR5IGxldmVsIGZvciBsb2cgZmlsdGVyaW5nIG9yIGZsYWcgdG8gZW5hYmxlIGJlbmNobWFya2luZy5cbiAqIEByZXR1cm4ge2Z1bmN0aW9uKGFueSwgYW55LFByb3BlcnR5RGVzY3JpcHRvcik6IHZvaWR9IFZlcmJvc2UgbG9nZ2luZyBkZWNvcmF0b3IuXG4gKiBAZnVuY3Rpb24gdmVyYm9zZVxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKHZlcmJvc2l0eTogbnVtYmVyIHwgYm9vbGVhbiA9IDApIHtcbiAgaWYgKCF2ZXJib3NpdHkpIHtcbiAgICB2ZXJib3NpdHkgPSAwO1xuICB9XG4gIHJldHVybiBsb2coTG9nTGV2ZWwudmVyYm9zZSwgdmVyYm9zaXR5IGFzIG51bWJlcik7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBkZWNvcmF0b3IgdGhhdCBtYWtlcyBhIG1ldGhvZCBub24tY29uZmlndXJhYmxlLlxuICogQHN1bW1hcnkgUHJldmVudHMgb3ZlcnJpZGluZyBieSBtYXJraW5nIHRoZSBtZXRob2QgZGVzY3JpcHRvciBhcyBub24tY29uZmlndXJhYmxlLCB0aHJvd2luZyBpZiBhcHBsaWVkIHRvIG5vbi1tZXRob2QgdGFyZ2V0cy5cbiAqIEByZXR1cm4ge2Z1bmN0aW9uKG9iamVjdCwgYW55LCBQcm9wZXJ0eURlc2NyaXB0b3IpOiBQcm9wZXJ0eURlc2NyaXB0b3J8dW5kZWZpbmVkfSBEZWNvcmF0b3IgdGhhdCBoYXJkZW5zIHRoZSBtZXRob2QgZGVzY3JpcHRvci5cbiAqIEBmdW5jdGlvbiBmaW5hbFxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5hbCgpIHtcbiAgcmV0dXJuICh0YXJnZXQ6IG9iamVjdCwgcHJvcGVydHlLZXk/OiBhbnksIGRlc2NyaXB0b3I/OiBhbnkpID0+IHtcbiAgICBpZiAoIWRlc2NyaXB0b3IpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJmaW5hbCBkZWNvcmF0b3IgY2FuIG9ubHkgYmUgdXNlZCBvbiBtZXRob2RzXCIpO1xuICAgIGlmIChkZXNjcmlwdG9yPy5jb25maWd1cmFibGUpIHtcbiAgICAgIGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBkZXNjcmlwdG9yO1xuICB9O1xufVxuIiwiaW1wb3J0IHsgTG9nRmlsdGVyIH0gZnJvbSBcIi4vTG9nRmlsdGVyXCI7XG5pbXBvcnQgeyBMb2dnaW5nQ29uZmlnIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBmaW5hbCB9IGZyb20gXCIuLi9kZWNvcmF0b3JzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFJlcGxhY2VtZW50IGNhbGxiYWNrIHVzZWQgdG8gdHJhbnNmb3JtIFJlZ0V4cCBtYXRjaGVzLlxuICogQHN1bW1hcnkgUmVjZWl2ZXMgdGhlIG1hdGNoZWQgc3Vic3RyaW5nIGFuZCBhZGRpdGlvbmFsIGNhcHR1cmUgYXJndW1lbnRzLCByZXR1cm5pbmcgdGhlIHJlcGxhY2VtZW50IHRleHQgdGhhdCB3aWxsIGJlIGluamVjdGVkIGludG8gdGhlIGxvZyBtZXNzYWdlLlxuICogQHR5cGVkZWYge2Z1bmN0aW9uKHN0cmluZywgYW55W10pOiBzdHJpbmd9IFJlcGxhY2VtZW50RnVuY3Rpb25cbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgdHlwZSBSZXBsYWNlbWVudEZ1bmN0aW9uID0gKHN1YnN0cmluZzogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkgPT4gc3RyaW5nO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBGaWx0ZXIgdGhhdCBwYXRjaGVzIGxvZyBtZXNzYWdlcyB1c2luZyByZWd1bGFyIGV4cHJlc3Npb25zLlxuICogQHN1bW1hcnkgQXBwbGllcyBhIGNvbmZpZ3VyZWQge0BsaW5rIFJlZ0V4cH0gYW5kIHJlcGxhY2VtZW50IHN0cmF0ZWd5IHRvIHJlZGFjdCwgbWFzaywgb3IgcmVzdHJ1Y3R1cmUgbG9nIHBheWxvYWRzIGJlZm9yZSB0aGV5IGFyZSBlbWl0dGVkLlxuICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cCAtIEV4cHJlc3Npb24gdXNlZCB0byBkZXRlY3Qgc2Vuc2l0aXZlIG9yIGZvcm1hdHRlZCB0ZXh0LlxuICogQHBhcmFtIHtzdHJpbmd8UmVwbGFjZW1lbnRGdW5jdGlvbn0gcmVwbGFjZW1lbnQgLSBSZXBsYWNlbWVudCBzdHJpbmcgb3IgY2FsbGJhY2sgaW52b2tlZCBmb3IgZWFjaCBtYXRjaC5cbiAqIEBjbGFzcyBQYXR0ZXJuRmlsdGVyXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZmlsdGVyID0gbmV3IFBhdHRlcm5GaWx0ZXIoL3Rva2VuPVteJl0rL2csIFwidG9rZW49KioqXCIpO1xuICogY29uc3Qgc2FuaXRpemVkID0gZmlsdGVyLmZpbHRlcihjb25maWcsIFwidG9rZW49MTIzJnVzZXI9dG9tXCIsIFtdKTtcbiAqIC8vIHNhbml0aXplZCA9PT0gXCJ0b2tlbj0qKiomdXNlcj10b21cIlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBMb2dnZXJcbiAqICAgcGFydGljaXBhbnQgRmlsdGVyIGFzIFBhdHRlcm5GaWx0ZXJcbiAqICAgcGFydGljaXBhbnQgUmVnRXhwXG4gKiAgIExvZ2dlci0+PkZpbHRlcjogZmlsdGVyKGNvbmZpZywgbWVzc2FnZSwgY29udGV4dClcbiAqICAgRmlsdGVyLT4+UmVnRXhwOiBleGVjdXRlIG1hdGNoKClcbiAqICAgYWx0IG1hdGNoIGZvdW5kXG4gKiAgICAgUmVnRXhwLS0+PkZpbHRlcjogY2FwdHVyZXNcbiAqICAgICBGaWx0ZXItPj5SZWdFeHA6IHJlcGxhY2UobWVzc2FnZSwgcmVwbGFjZW1lbnQpXG4gKiAgICAgUmVnRXhwLS0+PkZpbHRlcjogdHJhbnNmb3JtZWQgbWVzc2FnZVxuICogICBlbHNlIG5vIG1hdGNoXG4gKiAgICAgUmVnRXhwLS0+PkZpbHRlcjogbnVsbFxuICogICBlbmRcbiAqICAgRmlsdGVyLS0+PkxvZ2dlcjogc2FuaXRpemVkIG1lc3NhZ2VcbiAqL1xuZXhwb3J0IGNsYXNzIFBhdHRlcm5GaWx0ZXIgZXh0ZW5kcyBMb2dGaWx0ZXIge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgcmVnZXhwOiBSZWdFeHAsXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IHJlcGxhY2VtZW50OiBzdHJpbmcgfCBSZXBsYWNlbWVudEZ1bmN0aW9uXG4gICkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEVuc3VyZXMgZGV0ZXJtaW5pc3RpYyBSZWdFeHAgbWF0Y2hpbmcuXG4gICAqIEBzdW1tYXJ5IFJ1bnMgdGhlIGNvbmZpZ3VyZWQgZXhwcmVzc2lvbiwgdGhlbiByZXNldHMgaXRzIHN0YXRlIHNvIHJlcGVhdGVkIGludm9jYXRpb25zIGJlaGF2ZSBjb25zaXN0ZW50bHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gTWVzc2FnZSB0byB0ZXN0IGZvciBtYXRjaGVzLlxuICAgKiBAcmV0dXJuIHtSZWdFeHBFeGVjQXJyYXl8bnVsbH0gTWF0Y2ggcmVzdWx0IG9yIG51bGwgd2hlbiBubyBtYXRjaCBpcyBmb3VuZC5cbiAgICovXG4gIEBmaW5hbCgpXG4gIHByb3RlY3RlZCBtYXRjaChtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICBjb25zdCBtYXRjaCA9IHRoaXMucmVnZXhwLmV4ZWMobWVzc2FnZSk7XG4gICAgdGhpcy5yZWdleHAubGFzdEluZGV4ID0gMDtcbiAgICByZXR1cm4gbWF0Y2g7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFwcGxpZXMgdGhlIHJlcGxhY2VtZW50IHN0cmF0ZWd5IHRvIHRoZSBpbmNvbWluZyBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBFeGVjdXRlcyB7QGxpbmsgUGF0dGVybkZpbHRlci5tYXRjaH0gYW5kLCB3aGVuIGEgbWF0Y2ggaXMgZm91bmQsIHJlcGxhY2VzIGV2ZXJ5IG9jY3VycmVuY2UgdXNpbmcgdGhlIGNvbmZpZ3VyZWQgcmVwbGFjZW1lbnQgaGFuZGxlci5cbiAgICogQHBhcmFtIHtMb2dnaW5nQ29uZmlnfSBjb25maWcgLSBBY3RpdmUgbG9nZ2luZyBjb25maWd1cmF0aW9uICh1bnVzZWQgYnV0IHBhcnQgb2YgdGhlIGZpbHRlciBjb250cmFjdCkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gTWVzc2FnZSB0byBiZSBzYW5pdGl6ZWQuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGNvbnRleHQgLSBDb250ZXh0IGVudHJpZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBsb2cgZXZlbnQuXG4gICAqIEByZXR1cm4ge3N0cmluZ30gU2FuaXRpemVkIGxvZyBtZXNzYWdlLlxuICAgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBmaWx0ZXIoY29uZmlnOiBMb2dnaW5nQ29uZmlnLCBtZXNzYWdlOiBzdHJpbmcsIGNvbnRleHQ6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5maWx0ZXIpO1xuICAgIGNvbnN0IG1hdGNoID0gdGhpcy5tYXRjaChtZXNzYWdlKTtcbiAgICBpZiAoIW1hdGNoKSByZXR1cm4gbWVzc2FnZTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIG1lc3NhZ2UucmVwbGFjZSh0aGlzLnJlZ2V4cCwgdGhpcy5yZXBsYWNlbWVudCBhcyBhbnkpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIGxvZy5lcnJvcihgUGF0dGVybkZpbHRlciByZXBsYWNlbWVudCBlcnJvcjogJHtlfWApO1xuICAgIH1cbiAgICByZXR1cm4gXCJcIjtcbiAgfVxufVxuIiwiZXhwb3J0ICogZnJvbSBcIi4vZmlsdGVyc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9lbnZpcm9ubWVudFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vTG9nZ2VkQ2xhc3NcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2xvZ2dpbmdcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3RleHRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3RpbWVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGVzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi93ZWJcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29tcHJlaGVuc2l2ZSBsb2dnaW5nIHRvb2xraXQgZm9yIGJyb3dzZXIgYW5kIE5vZGUgZW52aXJvbm1lbnRzLlxuICogQHN1bW1hcnkgRXhwb3NlcyB7QGxpbmsgTG9nZ2luZ30gYW5kIHtAbGluayBNaW5pTG9nZ2VyfSBmb3IgcnVudGltZSBsb2dnaW5nLCBkZWNvcmF0b3JzIHN1Y2ggYXMge0BsaW5rIGxvZ30gZm9yIG1ldGhvZCBpbnN0cnVtZW50YXRpb24sIGFuZCB1dGlsaXRpZXMgbGlrZSB7QGxpbmsgUGF0dGVybkZpbHRlcn0sIHtAbGluayBTdG9wV2F0Y2h9LCBhbmQge0BsaW5rIExvZ2dlZEVudmlyb25tZW50fSB0byBidWlsZCBjb25maWd1cmFibGUsIHRoZW1lLWF3YXJlIGxvZyBwaXBlbGluZXMuXG4gKiBAbW9kdWxlIExvZ2dpbmdcbiAqL1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDdXJyZW50IHBhY2thZ2UgdmVyc2lvbiBzdHJpbmcuXG4gKiBAc3VtbWFyeSBTdG9yZXMgdGhlIHBhY2thZ2UgdmVyc2lvbiBmb3IgZGlhZ25vc3RpY3MgYW5kIGNvbXBhdGliaWxpdHkgY2hlY2tzLlxuICogQGNvbnN0IFZFUlNJT05cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG4iXSwibmFtZXMiOlsiTG9nTGV2ZWwiLCJMb2dnaW5nTW9kZSIsIk9iamVjdEFjY3VtdWxhdG9yIiwic3R5bGUiLCJfX2RlY29yYXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7SUFFQTs7Ozs7O0lBTUc7QUFDSSxVQUFNLGFBQWEsR0FBRztJQUU3Qjs7Ozs7O0lBTUc7QUFDSSxVQUFNLGtCQUFrQixHQUFHO0lBRWxDOzs7Ozs7SUFNRztVQUNVLDBCQUEwQixHQUFHLENBQUMsSUFBSSxFQUFFLEdBQUc7SUFFcEQ7Ozs7OztJQU1HO0FBQ1NBO0lBQVosQ0FBQSxVQUFZLFFBQVEsRUFBQTs7SUFFbEIsSUFBQSxRQUFBLENBQUEsV0FBQSxDQUFBLEdBQUEsV0FBdUI7O0lBRXZCLElBQUEsUUFBQSxDQUFBLE9BQUEsQ0FBQSxHQUFBLE9BQWU7O0lBRWYsSUFBQSxRQUFBLENBQUEsTUFBQSxDQUFBLEdBQUEsTUFBYTs7SUFFYixJQUFBLFFBQUEsQ0FBQSxTQUFBLENBQUEsR0FBQSxTQUFtQjs7SUFFbkIs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
|