@decaf-ts/decoration 0.0.2 → 0.0.4

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.
@@ -31,10 +31,13 @@
31
31
  */
32
32
  exports.DecorationKeys = void 0;
33
33
  (function (DecorationKeys) {
34
+ DecorationKeys["LIBRARIES"] = "libraries";
34
35
  /** Storage key used on the constructor to mirror runtime metadata */
35
36
  DecorationKeys["REFLECT"] = "__decaf";
36
37
  /** Map of model property keys to their reflected design types */
37
38
  DecorationKeys["PROPERTIES"] = "properties";
39
+ /** Map of model method keys to their reflected design params and return types */
40
+ DecorationKeys["METHODS"] = "methods";
38
41
  /** Key under which the model's constructor is stored */
39
42
  DecorationKeys["CLASS"] = "class";
40
43
  /** Container of human-friendly descriptions per class and property */
@@ -65,6 +68,217 @@
65
68
  [exports.DecorationKeys.PROPERTIES]: [],
66
69
  };
67
70
 
71
+ /**
72
+ * @description Retrieves a nested value from an object given a path
73
+ * @summary Walks an object structure using a splitter-delimited path and returns the value at that location or undefined if any key is missing.
74
+ * @param {Record<string, any>} obj The object to traverse
75
+ * @param {string} path The path to the desired value (e.g., "a.b.c")
76
+ * @param {string} [splitter=ObjectKeySplitter] The delimiter used to split the path
77
+ * @return {*} The resolved value at the given path or undefined if not found
78
+ * @function getValueBySplitter
79
+ * @mermaid
80
+ * sequenceDiagram
81
+ * participant C as Caller
82
+ * participant F as getValueBySplitter
83
+ * participant O as Object
84
+ * C->>F: (obj, path, splitter)
85
+ * F->>F: split path into keys
86
+ * loop for each key
87
+ * F->>O: access current[key]
88
+ * alt missing or nullish
89
+ * F-->>C: return undefined
90
+ * end
91
+ * end
92
+ * F-->>C: return final value
93
+ * @memberOf module:decoration
94
+ */
95
+ function getValueBySplitter(obj, path, splitter = ObjectKeySplitter) {
96
+ const keys = path.split(splitter);
97
+ let current = obj;
98
+ for (const key of keys) {
99
+ if (current === null ||
100
+ current === undefined ||
101
+ !Object.prototype.hasOwnProperty.call(current, key))
102
+ return undefined;
103
+ current = current[key];
104
+ }
105
+ return current;
106
+ }
107
+ /**
108
+ * @description Sets a nested value on an object given a path
109
+ * @summary Traverses or creates intermediate objects following a splitter-delimited path and assigns the provided value at the destination key.
110
+ * @param {Record<string, any>} obj The object to mutate
111
+ * @param {string} path The destination path (e.g., "a.b.c")
112
+ * @param {*} value The value to set at the destination
113
+ * @param {string} [splitter=ObjectKeySplitter] The delimiter used to split the path
114
+ * @return {void}
115
+ * @function setValueBySplitter
116
+ * @mermaid
117
+ * sequenceDiagram
118
+ * participant C as Caller
119
+ * participant F as setValueBySplitter
120
+ * participant O as Object
121
+ * C->>F: (obj, path, value, splitter)
122
+ * F->>F: split path into keys
123
+ * loop for each key
124
+ * alt key missing
125
+ * F->>O: create intermediate object
126
+ * else key exists
127
+ * F->>O: descend into existing object
128
+ * end
129
+ * end
130
+ * F-->>C: void
131
+ * @memberOf module:decoration
132
+ */
133
+ function setValueBySplitter(obj, path, value, splitter = ObjectKeySplitter) {
134
+ const keys = path.split(splitter).filter((k) => k.length > 0);
135
+ if (keys.length === 0)
136
+ return;
137
+ let current = obj;
138
+ for (let i = 0; i < keys.length - 1; i++) {
139
+ const key = keys[i];
140
+ if (current[key] === undefined ||
141
+ current[key] === null ||
142
+ typeof current[key] !== "object") {
143
+ current[key] = {};
144
+ }
145
+ current = current[key];
146
+ }
147
+ const lastKey = keys[keys.length - 1];
148
+ current[lastKey] = value;
149
+ }
150
+ /**
151
+ * @description Centralized runtime metadata store bound to constructors
152
+ * @summary Provides utilities to read and write structured metadata for classes and their members, with optional mirroring onto the constructor via a well-known symbol key. Supports nested key paths using a configurable splitter and offers both instance and static APIs.
153
+ * @template M The model type the metadata belongs to
154
+ * @template META Extends BasicMetadata<M> representing the metadata structure
155
+ * @class
156
+ * @example
157
+ * // Define and read metadata for a class
158
+ * class User { name!: string }
159
+ * Metadata.set(User, "description.class", "A user model");
160
+ * Metadata.set(User, "properties.name", String);
161
+ * const desc = Metadata.get(User, "description.class"); // "A user model"
162
+ * const type = Metadata.type(User, "name"); // String
163
+ * @mermaid
164
+ * sequenceDiagram
165
+ * participant C as Constructor
166
+ * participant S as Metadata (static)
167
+ * C->>S: set(User, "properties.name", String)
168
+ * C->>S: get(User, "properties.name")
169
+ * S-->>C: String
170
+ */
171
+ class Metadata {
172
+ /**
173
+ * @description In-memory storage of metadata by constructor symbol
174
+ * @summary Maps a Symbol derived from the constructor to its metadata object, enabling efficient lookup.
175
+ */
176
+ static { this._metadata = {}; }
177
+ /**
178
+ * @description Path delimiter for nested metadata keys
179
+ * @summary Used by get/set operations to navigate nested structures, defaults to ObjectKeySplitter.
180
+ */
181
+ static { this.splitter = ObjectKeySplitter; }
182
+ /**
183
+ * @description Symbol key used to mirror metadata on the constructor
184
+ * @summary When mirroring is enabled, the metadata object is defined on the constructor under this non-enumerable key.
185
+ */
186
+ static { this.baseKey = exports.DecorationKeys.REFLECT; }
187
+ /**
188
+ * @description Controls whether metadata is mirrored onto the constructor
189
+ * @summary When true, the metadata object is defined on the constructor under the non-enumerable baseKey.
190
+ */
191
+ static { this.mirror = true; }
192
+ constructor() { }
193
+ /**
194
+ * @description Lists known property keys for a model
195
+ * @summary Reads the metadata entry and returns the names of properties that have recorded type information.
196
+ * @param {Constructor} model The target constructor
197
+ * @return {string[]|undefined} Array of property names or undefined if no metadata exists
198
+ */
199
+ static properties(model) {
200
+ const meta = this.get(model);
201
+ if (!meta)
202
+ return undefined;
203
+ return Object.keys(meta.properties);
204
+ }
205
+ /**
206
+ * @description Retrieves a human-readable description for a class or a property
207
+ * @summary Looks up the description stored under the metadata "description" map. If a property key is provided, returns the property's description; otherwise returns the class description.
208
+ * @template M
209
+ * @param {Constructor<M>} model The target constructor whose description is being retrieved
210
+ * @param {string} [prop] Optional property key for which to fetch the description
211
+ * @return {string|undefined} The description text if present, otherwise undefined
212
+ */
213
+ static description(model, prop) {
214
+ return this.get(model, [exports.DecorationKeys.DESCRIPTION, prop ? prop : exports.DecorationKeys.CLASS].join(ObjectKeySplitter));
215
+ }
216
+ /**
217
+ * @description Retrieves the recorded design type for a property
218
+ * @summary Reads the metadata entry under "properties.<prop>" to return the constructor recorded for the given property name.
219
+ * @param {Constructor} model The target constructor
220
+ * @param {string} prop The property name whose type should be returned
221
+ * @return {Constructor|undefined} The constructor reference of the property type or undefined if not available
222
+ */
223
+ static type(model, prop) {
224
+ return this.get(model, `${exports.DecorationKeys.PROPERTIES}.${prop}`);
225
+ }
226
+ /**
227
+ * @description Retrieves metadata for a model or a specific key within it
228
+ * @summary When called with a constructor only, returns the entire metadata object associated with the model. When a key path is provided, returns the value stored at that nested key.
229
+ * @template M
230
+ * @template META
231
+ * @param {Constructor<M> | string} model The target constructor used to locate the metadata record
232
+ * @param {string} [key] Optional nested key path to fetch a specific value
233
+ * @return {META|*|undefined} The metadata object, the value at the key path, or undefined if nothing exists
234
+ */
235
+ static get(model, key) {
236
+ const symbol = Symbol.for(model.toString());
237
+ return this.innerGet(symbol, key);
238
+ }
239
+ static innerGet(symbol, key) {
240
+ if (!this._metadata[symbol])
241
+ return undefined;
242
+ if (!key)
243
+ return this._metadata[symbol];
244
+ return getValueBySplitter(this._metadata[symbol], key, this.splitter);
245
+ }
246
+ static innerSet(symbol, key, value) {
247
+ if (!this._metadata[symbol])
248
+ this._metadata[symbol] = {};
249
+ setValueBySplitter(this._metadata[symbol], key, value, this.splitter);
250
+ }
251
+ /**
252
+ * @description Writes a metadata value at a given nested key path
253
+ * @summary Ensures the metadata record exists for the constructor, mirrors it on the constructor when enabled, and sets the provided value on the nested key path using the configured splitter.
254
+ * @template M
255
+ * @param {Constructor<M> | string} model The target constructor to which the metadata belongs
256
+ * @param {string} key The nested key path at which to store the value
257
+ * @param {*} value The value to store in the metadata
258
+ * @return {void}
259
+ */
260
+ static set(model, key, value) {
261
+ const symbol = Symbol.for(model.toString());
262
+ this.innerSet(symbol, key, value);
263
+ if (Metadata.mirror &&
264
+ !Object.prototype.hasOwnProperty.call(model, this.baseKey)) {
265
+ Object.defineProperty(model, this.baseKey, {
266
+ enumerable: false,
267
+ configurable: false,
268
+ writable: false,
269
+ value: this._metadata[symbol],
270
+ });
271
+ }
272
+ }
273
+ static registerLibrary(library, version) {
274
+ const symbol = Symbol.for(exports.DecorationKeys.LIBRARIES);
275
+ const lib = this.innerGet(symbol, library);
276
+ if (lib)
277
+ throw new Error(`Library already ${library} registered with version ${version}`);
278
+ this.innerSet(symbol, library, version);
279
+ }
280
+ }
281
+
68
282
  /**
69
283
  * @description Default resolver that returns the current default flavour
70
284
  * @summary Resolves the flavour for a given target by always returning the library's DefaultFlavour value.
@@ -172,6 +386,9 @@
172
386
  * @return Builder instance for finishing the chain
173
387
  */
174
388
  define(...decorators) {
389
+ if (decorators.find((d) => typeof d === "object") &&
390
+ decorators.length !== 1)
391
+ throw new Error(`When using an overridable decorator, only one is allowed`);
175
392
  return this.decorate(false, ...decorators);
176
393
  }
177
394
  /**
@@ -181,6 +398,9 @@
181
398
  * @return {DecorationBuilderBuild} Builder instance for building the decorator
182
399
  */
183
400
  extend(...decorators) {
401
+ if (decorators.find((d) => typeof d === "object") &&
402
+ decorators.length !== 1)
403
+ throw new Error(`When extending using an overridable decorator, only one is allowed`);
184
404
  return this.decorate(true, ...decorators);
185
405
  }
186
406
  /**
@@ -214,15 +434,6 @@
214
434
  const extras = cache[flavour]
215
435
  ? cache[flavour].extras
216
436
  : cache[DefaultFlavour].extras;
217
- const extraArgs = [
218
- ...(cache[DefaultFlavour].extras
219
- ? cache[DefaultFlavour].extras.values()
220
- : []),
221
- ].reduce((accum, e, i) => {
222
- if (e.args)
223
- accum[i] = e.args;
224
- return accum;
225
- }, {});
226
437
  if (cache &&
227
438
  cache[flavour] &&
228
439
  cache[flavour].decorators &&
@@ -243,15 +454,11 @@
243
454
  ...(decorators ? decorators.values() : []),
244
455
  ...(extras ? extras.values() : []),
245
456
  ];
246
- return toApply.reduce((_, d, i) => {
457
+ return toApply.reduce((_, d) => {
247
458
  switch (typeof d) {
248
459
  case "object": {
249
- const { decorator, args } = d;
250
- const argz = args || i < (decorators ? decorators.size : 0)
251
- ? decoratorArgs[i]
252
- : extraArgs[i - (decorators ? decorators.size : 0)] ||
253
- (decorators ? decoratorArgs[i - decorators.size] : []);
254
- return decorator(...(argz || []))(target, propertyKey, descriptor);
460
+ const { decorator } = d;
461
+ return decorator(...(Object.values(decoratorArgs)[0] || []))(target, propertyKey, descriptor);
255
462
  }
256
463
  case "function":
257
464
  return d(target, propertyKey, descriptor);
@@ -330,203 +537,6 @@
330
537
  }
331
538
  }
332
539
 
333
- /**
334
- * @description Retrieves a nested value from an object given a path
335
- * @summary Walks an object structure using a splitter-delimited path and returns the value at that location or undefined if any key is missing.
336
- * @param {Record<string, any>} obj The object to traverse
337
- * @param {string} path The path to the desired value (e.g., "a.b.c")
338
- * @param {string} [splitter=ObjectKeySplitter] The delimiter used to split the path
339
- * @return {*} The resolved value at the given path or undefined if not found
340
- * @function getValueBySplitter
341
- * @mermaid
342
- * sequenceDiagram
343
- * participant C as Caller
344
- * participant F as getValueBySplitter
345
- * participant O as Object
346
- * C->>F: (obj, path, splitter)
347
- * F->>F: split path into keys
348
- * loop for each key
349
- * F->>O: access current[key]
350
- * alt missing or nullish
351
- * F-->>C: return undefined
352
- * end
353
- * end
354
- * F-->>C: return final value
355
- * @memberOf module:decoration
356
- */
357
- function getValueBySplitter(obj, path, splitter = ObjectKeySplitter) {
358
- const keys = path.split(splitter);
359
- let current = obj;
360
- for (const key of keys) {
361
- if (current === null ||
362
- current === undefined ||
363
- !Object.prototype.hasOwnProperty.call(current, key))
364
- return undefined;
365
- current = current[key];
366
- }
367
- return current;
368
- }
369
- /**
370
- * @description Sets a nested value on an object given a path
371
- * @summary Traverses or creates intermediate objects following a splitter-delimited path and assigns the provided value at the destination key.
372
- * @param {Record<string, any>} obj The object to mutate
373
- * @param {string} path The destination path (e.g., "a.b.c")
374
- * @param {*} value The value to set at the destination
375
- * @param {string} [splitter=ObjectKeySplitter] The delimiter used to split the path
376
- * @return {void}
377
- * @function setValueBySplitter
378
- * @mermaid
379
- * sequenceDiagram
380
- * participant C as Caller
381
- * participant F as setValueBySplitter
382
- * participant O as Object
383
- * C->>F: (obj, path, value, splitter)
384
- * F->>F: split path into keys
385
- * loop for each key
386
- * alt key missing
387
- * F->>O: create intermediate object
388
- * else key exists
389
- * F->>O: descend into existing object
390
- * end
391
- * end
392
- * F-->>C: void
393
- * @memberOf module:decoration
394
- */
395
- function setValueBySplitter(obj, path, value, splitter = ObjectKeySplitter) {
396
- const keys = path.split(splitter).filter((k) => k.length > 0);
397
- if (keys.length === 0)
398
- return;
399
- let current = obj;
400
- for (let i = 0; i < keys.length - 1; i++) {
401
- const key = keys[i];
402
- if (current[key] === undefined ||
403
- current[key] === null ||
404
- typeof current[key] !== "object") {
405
- current[key] = {};
406
- }
407
- current = current[key];
408
- }
409
- const lastKey = keys[keys.length - 1];
410
- current[lastKey] = value;
411
- }
412
- /**
413
- * @description Centralized runtime metadata store bound to constructors
414
- * @summary Provides utilities to read and write structured metadata for classes and their members, with optional mirroring onto the constructor via a well-known symbol key. Supports nested key paths using a configurable splitter and offers both instance and static APIs.
415
- * @template M The model type the metadata belongs to
416
- * @template META Extends BasicMetadata<M> representing the metadata structure
417
- * @class
418
- * @example
419
- * // Define and read metadata for a class
420
- * class User { name!: string }
421
- * Metadata.set(User, "description.class", "A user model");
422
- * Metadata.set(User, "properties.name", String);
423
- * const desc = Metadata.get(User, "description.class"); // "A user model"
424
- * const type = Metadata.type(User, "name"); // String
425
- * @mermaid
426
- * sequenceDiagram
427
- * participant C as Constructor
428
- * participant S as Metadata (static)
429
- * C->>S: set(User, "properties.name", String)
430
- * C->>S: get(User, "properties.name")
431
- * S-->>C: String
432
- */
433
- class Metadata {
434
- /**
435
- * @description In-memory storage of metadata by constructor symbol
436
- * @summary Maps a Symbol derived from the constructor to its metadata object, enabling efficient lookup.
437
- */
438
- static { this._metadata = {}; }
439
- /**
440
- * @description Path delimiter for nested metadata keys
441
- * @summary Used by get/set operations to navigate nested structures, defaults to ObjectKeySplitter.
442
- */
443
- static { this.splitter = ObjectKeySplitter; }
444
- /**
445
- * @description Symbol key used to mirror metadata on the constructor
446
- * @summary When mirroring is enabled, the metadata object is defined on the constructor under this non-enumerable key.
447
- */
448
- static { this.baseKey = exports.DecorationKeys.REFLECT; }
449
- /**
450
- * @description Controls whether metadata is mirrored onto the constructor
451
- * @summary When true, the metadata object is defined on the constructor under the non-enumerable baseKey.
452
- */
453
- static { this.mirror = true; }
454
- constructor() { }
455
- /**
456
- * @description Lists known property keys for a model
457
- * @summary Reads the metadata entry and returns the names of properties that have recorded type information.
458
- * @param {Constructor} model The target constructor
459
- * @return {string[]|undefined} Array of property names or undefined if no metadata exists
460
- */
461
- static properties(model) {
462
- const meta = this.get(model);
463
- if (!meta)
464
- return undefined;
465
- return Object.keys(meta.properties);
466
- }
467
- /**
468
- * @description Retrieves a human-readable description for a class or a property
469
- * @summary Looks up the description stored under the metadata "description" map. If a property key is provided, returns the property's description; otherwise returns the class description.
470
- * @template M
471
- * @param {Constructor<M>} model The target constructor whose description is being retrieved
472
- * @param {string} [prop] Optional property key for which to fetch the description
473
- * @return {string|undefined} The description text if present, otherwise undefined
474
- */
475
- static description(model, prop) {
476
- return this.get(model, [exports.DecorationKeys.DESCRIPTION, prop ? prop : exports.DecorationKeys.CLASS].join(ObjectKeySplitter));
477
- }
478
- /**
479
- * @description Retrieves the recorded design type for a property
480
- * @summary Reads the metadata entry under "properties.<prop>" to return the constructor recorded for the given property name.
481
- * @param {Constructor} model The target constructor
482
- * @param {string} prop The property name whose type should be returned
483
- * @return {Constructor|undefined} The constructor reference of the property type or undefined if not available
484
- */
485
- static type(model, prop) {
486
- return this.get(model, `${exports.DecorationKeys.PROPERTIES}.${prop}`);
487
- }
488
- /**
489
- * @description Retrieves metadata for a model or a specific key within it
490
- * @summary When called with a constructor only, returns the entire metadata object associated with the model. When a key path is provided, returns the value stored at that nested key.
491
- * @template M
492
- * @template META
493
- * @param {Constructor<M>} model The target constructor used to locate the metadata record
494
- * @param {string} [key] Optional nested key path to fetch a specific value
495
- * @return {META|*|undefined} The metadata object, the value at the key path, or undefined if nothing exists
496
- */
497
- static get(model, key) {
498
- const symbol = Symbol.for(model.toString());
499
- if (!this._metadata[symbol])
500
- return undefined;
501
- if (!key)
502
- return this._metadata[symbol];
503
- return getValueBySplitter(this._metadata[symbol], key, this.splitter);
504
- }
505
- /**
506
- * @description Writes a metadata value at a given nested key path
507
- * @summary Ensures the metadata record exists for the constructor, mirrors it on the constructor when enabled, and sets the provided value on the nested key path using the configured splitter.
508
- * @param {Constructor} model The target constructor to which the metadata belongs
509
- * @param {string} key The nested key path at which to store the value
510
- * @param {*} value The value to store in the metadata
511
- * @return {void}
512
- */
513
- static set(model, key, value) {
514
- const symbol = Symbol.for(model.toString());
515
- if (!this._metadata[symbol])
516
- this._metadata[symbol] = {};
517
- if (Metadata.mirror &&
518
- !Object.prototype.hasOwnProperty.call(model, this.baseKey)) {
519
- Object.defineProperty(model, this.baseKey, {
520
- enumerable: false,
521
- configurable: false,
522
- writable: false,
523
- value: this._metadata[symbol],
524
- });
525
- }
526
- setValueBySplitter(this._metadata[symbol], key, value, this.splitter);
527
- }
528
- }
529
-
530
540
  /**
531
541
  * @description Assigns arbitrary metadata to a target using a string key
532
542
  * @summary Decorator factory that stores a key/value pair in the central Metadata store for the provided class or member.
@@ -556,6 +566,13 @@
556
566
  return metadata(`${exports.DecorationKeys.PROPERTIES}.${prop}`, designType)(model, prop);
557
567
  };
558
568
  }
569
+ function method() {
570
+ return function method(obj, prop, descriptor) {
571
+ const designParams = Reflect.getOwnMetadata(exports.DecorationKeys.DESIGN_PARAMS, obj, prop);
572
+ const designReturn = Reflect.getOwnMetadata(exports.DecorationKeys.DESIGN_RETURN, obj, prop);
573
+ return apply(metadata(`${exports.DecorationKeys.METHODS}.${prop}.${exports.DecorationKeys.DESIGN_PARAMS}`, designParams), metadata(`${exports.DecorationKeys.METHODS}.${prop}.${exports.DecorationKeys.DESIGN_RETURN}`, designReturn))(obj, prop, descriptor);
574
+ };
575
+ }
559
576
  /**
560
577
  * @description Decorator factory that applies multiple decorators to a single target
561
578
  * @summary Creates a composite decorator that applies multiple decorators in sequence, correctly handling class, method, and property decorators.
@@ -631,7 +648,8 @@
631
648
  * @const VERSION
632
649
  * @memberOf module:decoration
633
650
  */
634
- const VERSION = "0.0.2";
651
+ const VERSION = "0.0.4";
652
+ Metadata.registerLibrary("@decaf-ts/decoration", VERSION);
635
653
 
636
654
  exports.Decoration = Decoration;
637
655
  exports.DefaultFlavour = DefaultFlavour;
@@ -641,9 +659,12 @@
641
659
  exports.VERSION = VERSION;
642
660
  exports.apply = apply;
643
661
  exports.description = description;
662
+ exports.getValueBySplitter = getValueBySplitter;
644
663
  exports.metadata = metadata;
664
+ exports.method = method;
645
665
  exports.prop = prop;
646
666
  exports.propMetadata = propMetadata;
667
+ exports.setValueBySplitter = setValueBySplitter;
647
668
 
648
669
  }));
649
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVjb3JhdGlvbi5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvZGVjb3JhdGlvbi9EZWNvcmF0aW9uLnRzIiwiLi4vc3JjL21ldGFkYXRhL01ldGFkYXRhLnRzIiwiLi4vc3JjL2RlY29yYXRvcnMudHMiLCIuLi9zcmMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQmFzaWNNZXRhZGF0YSB9IGZyb20gXCIuL21ldGFkYXRhL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmF1bHQgZmxhdm91ciBpZGVudGlmaWVyIGZvciB0aGUgZGVjb3JhdG9yIHN5c3RlbVxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgZGVmYXVsdCBmbGF2b3VyIHVzZWQgYnkgdGhlIERlY29yYXRpb24gY2xhc3Mgd2hlbiBubyBzcGVjaWZpYyBmbGF2b3VyIGlzIHByb3ZpZGVkLlxuICogVGhpcyBjb25zdGFudCBpcyB1c2VkIHRocm91Z2hvdXQgdGhlIGxpYnJhcnkgYXMgdGhlIGZhbGxiYWNrIGZsYXZvdXIgZm9yIGRlY29yYXRvcnMuXG4gKiBAY29uc3QgRGVmYXVsdEZsYXZvdXJcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdGlvblxuICovXG5leHBvcnQgY29uc3QgRGVmYXVsdEZsYXZvdXIgPSBcImRlY2FmXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENoYXJhY3RlciB1c2VkIHRvIHNwbGl0IG5lc3RlZCBtZXRhZGF0YSBrZXlzXG4gKiBAc3VtbWFyeSBUaGUgZGVsaW1pdGVyIHVzZWQgYnkgdGhlIG1ldGFkYXRhIHN0b3JlIHRvIHRyYXZlcnNlIG5lc3RlZCBvYmplY3QgcGF0aHMgd2hlbiByZWFkaW5nL3dyaXRpbmcgdmFsdWVzLlxuICogQGNvbnN0IE9iamVjdEtleVNwbGl0dGVyXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRpb25cbiAqL1xuZXhwb3J0IGNvbnN0IE9iamVjdEtleVNwbGl0dGVyID0gXCIuXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVudW0gY29udGFpbmluZyBtZXRhZGF0YSBrZXlzIHVzZWQgZm9yIHJlZmxlY3Rpb24gaW4gdGhlIG1vZGVsIHN5c3RlbVxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgdmFyaW91cyBNb2RlbCBrZXlzIHVzZWQgZm9yIHJlZmxlY3Rpb24gYW5kIG1ldGFkYXRhIHN0b3JhZ2UuXG4gKiBUaGVzZSBrZXlzIGFyZSB1c2VkIHRocm91Z2hvdXQgdGhlIGxpYnJhcnkgdG8gc3RvcmUgYW5kIHJldHJpZXZlIG1ldGFkYXRhIGFib3V0IG1vZGVscyxcbiAqIHRoZWlyIHByb3BlcnRpZXMsIGFuZCB0aGVpciBiZWhhdmlvci5cbiAqIEByZWFkb25seVxuICogQGVudW0ge3N0cmluZ31cbiAqIEByZWFkb25seVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0aW9uXG4gKi9cbmV4cG9ydCBlbnVtIERlY29yYXRpb25LZXlzIHtcbiAgLyoqIFN0b3JhZ2Uga2V5IHVzZWQgb24gdGhlIGNvbnN0cnVjdG9yIHRvIG1pcnJvciBydW50aW1lIG1ldGFkYXRhICovXG4gIFJFRkxFQ1QgPSBgX18ke0RlZmF1bHRGbGF2b3VyfWAsXG4gIC8qKiBNYXAgb2YgbW9kZWwgcHJvcGVydHkga2V5cyB0byB0aGVpciByZWZsZWN0ZWQgZGVzaWduIHR5cGVzICovXG4gIFBST1BFUlRJRVMgPSBcInByb3BlcnRpZXNcIixcbiAgLyoqIEtleSB1bmRlciB3aGljaCB0aGUgbW9kZWwncyBjb25zdHJ1Y3RvciBpcyBzdG9yZWQgKi9cbiAgQ0xBU1MgPSBcImNsYXNzXCIsXG4gIC8qKiBDb250YWluZXIgb2YgaHVtYW4tZnJpZW5kbHkgZGVzY3JpcHRpb25zIHBlciBjbGFzcyBhbmQgcHJvcGVydHkgKi9cbiAgREVTQ1JJUFRJT04gPSBcImRlc2NyaXB0aW9uXCIsXG4gIC8qKiBSZWZsZWN0IG1ldGFkYXRhIGtleSBmb3IgZGVzaWduIHRpbWUgdHlwZSBvZiBhIHByb3BlcnR5ICovXG4gIERFU0lHTl9UWVBFID0gXCJkZXNpZ246dHlwZVwiLFxuICAvKiogUmVmbGVjdCBtZXRhZGF0YSBrZXkgZm9yIGNvbnN0cnVjdG9yIHBhcmFtZXRlciB0eXBlcyAqL1xuICBERVNJR05fUEFSQU1TID0gXCJkZXNpZ246cGFyYW10eXBlc1wiLFxuICAvKiogUmVmbGVjdCBtZXRhZGF0YSBrZXkgZm9yIG1ldGhvZCByZXR1cm4gdHlwZSAqL1xuICBERVNJR05fUkVUVVJOID0gXCJkZXNpZ246cmV0dXJudHlwZVwiLFxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBUeXBlZGVmIGZvciB0aGUgZGVmYXVsdCBtZXRhZGF0YSBvYmplY3Qgc2hhcGVcbiAqIEBzdW1tYXJ5IERlc2NyaWJlcyB0aGUgbWluaW1hbCBzdHJ1Y3R1cmUgcGVyc2lzdGVkIGZvciBhIG1vZGVsIGJlZm9yZSBhbnkgbWV0YWRhdGEgaXMgcmVjb3JkZWQuXG4gKiBAdGVtcGxhdGUgTVxuICogQHR5cGVkZWYge29iamVjdH0gRGVmYXVsdE1ldGFkYXRhVHlwZTxNPlxuICogQHByb3BlcnR5IHtSZWNvcmQ8c3RyaW5nLCBDb25zdHJ1Y3RvciB8IHVuZGVmaW5lZD59IHByb3BlcnRpZXMgLSBNYXBwaW5nIG9mIHByb3BlcnR5IG5hbWVzIHRvIHRoZWlyIGRlc2lnbiB0eXBlc1xuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0aW9uXG4gKi9cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVmYXVsdCBtZXRhZGF0YSBpbnN0YW5jZVxuICogQHN1bW1hcnkgQ29uY3JldGUgZGVmYXVsdCBtZXRhZGF0YSBvYmplY3QgdXNlZCB3aGVuIGluaXRpYWxpemluZyBtZXRhZGF0YSBmb3IgYSBtb2RlbFxuICogQHR5cGUge0RlZmF1bHRNZXRhZGF0YVR5cGU8YW55Pn1cbiAqIEBjb25zdCBEZWZhdWx0TWV0YWRhdGFcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdGlvblxuICovXG5leHBvcnQgY29uc3QgRGVmYXVsdE1ldGFkYXRhOiBCYXNpY01ldGFkYXRhPGFueT4gPSB7XG4gIFtEZWNvcmF0aW9uS2V5cy5QUk9QRVJUSUVTXTogW10sXG59IGFzIHVua25vd24gYXMgQmFzaWNNZXRhZGF0YTxhbnk+O1xuIiwiaW1wb3J0IHtcbiAgRGVjb3JhdGlvbkJ1aWxkZXJCdWlsZCxcbiAgRGVjb3JhdGlvbkJ1aWxkZXJFbmQsXG4gIERlY29yYXRpb25CdWlsZGVyTWlkLFxuICBEZWNvcmF0aW9uQnVpbGRlclN0YXJ0LFxuICBGbGF2b3VyUmVzb2x2ZXIsXG4gIElEZWNvcmF0aW9uQnVpbGRlcixcbn0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IERlZmF1bHRGbGF2b3VyIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IHJlc29sdmVyIHRoYXQgcmV0dXJucyB0aGUgY3VycmVudCBkZWZhdWx0IGZsYXZvdXJcbiAqIEBzdW1tYXJ5IFJlc29sdmVzIHRoZSBmbGF2b3VyIGZvciBhIGdpdmVuIHRhcmdldCBieSBhbHdheXMgcmV0dXJuaW5nIHRoZSBsaWJyYXJ5J3MgRGVmYXVsdEZsYXZvdXIgdmFsdWUuXG4gKiBAcGFyYW0ge29iamVjdH0gdGFyZ2V0IFRoZSB0YXJnZXQgb2JqZWN0IGJlaW5nIGRlY29yYXRlZFxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgcmVzb2x2ZWQgZmxhdm91ciBpZGVudGlmaWVyXG4gKiBAZnVuY3Rpb24gZGVmYXVsdEZsYXZvdXJSZXNvbHZlclxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0aW9uXG4gKi9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbmZ1bmN0aW9uIGRlZmF1bHRGbGF2b3VyUmVzb2x2ZXIodGFyZ2V0OiBvYmplY3QpIHtcbiAgcmV0dXJuIERlZmF1bHRGbGF2b3VyO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBVbmlvbiB0eXBlIGNvdmVyaW5nIHN1cHBvcnRlZCBkZWNvcmF0b3Iga2luZHNcbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgYW55IG9mIHRoZSBzdGFuZGFyZCBUeXBlU2NyaXB0IGRlY29yYXRvciBzaWduYXR1cmVzIChjbGFzcywgcHJvcGVydHksIG9yIG1ldGhvZCksIGVuYWJsaW5nIGZsZXhpYmxlIHJlZ2lzdHJhdGlvbiBhbmQgYXBwbGljYXRpb24gd2l0aGluIHRoZSBEZWNvcmF0aW9uIHN5c3RlbS5cbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAdHlwZURlZiBEZWNvcmF0b3JUeXBlc1xuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0aW9uXG4gKi9cbmV4cG9ydCB0eXBlIERlY29yYXRvclR5cGVzID1cbiAgfCBDbGFzc0RlY29yYXRvclxuICB8IFByb3BlcnR5RGVjb3JhdG9yXG4gIHwgTWV0aG9kRGVjb3JhdG9yO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBUeXBlIGRlZmluaXRpb24gZm9yIGEgZGVjb3JhdG9yIGZhY3RvcnkgZnVuY3Rpb25cbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgYSBmdW5jdGlvbiB0aGF0IGFjY2VwdHMgYXJiaXRyYXJ5IGFyZ3VtZW50cyBhbmQgcmV0dXJucyBhIGNvbmNyZXRlIGRlY29yYXRvciBmdW5jdGlvbiB0byBiZSBhcHBsaWVkIHRvIGEgdGFyZ2V0LlxuICogQHRlbXBsYXRlIEFcbiAqIEB0eXBlRGVmIERlY29yYXRvckZhY3RvcnlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdGlvblxuICovXG5leHBvcnQgdHlwZSBEZWNvcmF0b3JGYWN0b3J5ID0gKC4uLmFyZ3M6IGFueVtdKSA9PiBEZWNvcmF0b3JUeXBlcztcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQXJndW1lbnQgYnVuZGxlIGZvciBhIGRlY29yYXRvciBmYWN0b3J5XG4gKiBAc3VtbWFyeSBPYmplY3QgZm9ybSB1c2VkIHRvIGRlZmVyIGRlY29yYXRvciBjcmVhdGlvbiwgY2FycnlpbmcgYm90aCB0aGUgZmFjdG9yeSBmdW5jdGlvbiBhbmQgaXRzIGFyZ3VtZW50IGxpc3QgdG8gYmUgaW52b2tlZCBsYXRlciBkdXJpbmcgYXBwbGljYXRpb24uXG4gKiBAdHlwZURlZiBEZWNvcmF0b3JGYWN0b3J5QXJnc1xuICogQHByb3BlcnR5IHtEZWNvcmF0b3JGYWN0b3J5fSBkZWNvcmF0b3IgVGhlIGZhY3RvcnkgZnVuY3Rpb24gdGhhdCBwcm9kdWNlcyBhIGRlY29yYXRvciB3aGVuIGludm9rZWRcbiAqIEBwcm9wZXJ0eSB7YW55W119IFthcmdzXSBPcHRpb25hbCBsaXN0IG9mIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBkZWNvcmF0b3IgZmFjdG9yeVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0aW9uXG4gKi9cbmV4cG9ydCB0eXBlIERlY29yYXRvckZhY3RvcnlBcmdzID0ge1xuICBkZWNvcmF0b3I6IERlY29yYXRvckZhY3Rvcnk7XG4gIGFyZ3M/OiBhbnlbXTtcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFVuaW9uIHRoYXQgcmVwcmVzZW50cyBlaXRoZXIgYSByZWFkeS10by1hcHBseSBkZWNvcmF0b3Igb3IgYSBmYWN0b3J5IHdpdGggYXJndW1lbnRzXG4gKiBAc3VtbWFyeSBBbGxvd3MgcmVnaXN0ZXJpbmcgZGVjb3JhdG9ycyBpbiB0d28gZm9ybXM6IGFzIGRpcmVjdCBkZWNvcmF0b3IgZnVuY3Rpb25zIG9yIGFzIGRlZmVycmVkIGZhY3RvcmllcyBwYWlyZWQgd2l0aCB0aGVpciBhcmd1bWVudCBsaXN0cyBmb3IgbGF0ZXIgaW5zdGFudGlhdGlvbi5cbiAqIEB0eXBlRGVmIERlY29yYXRvckRhdGFcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdGlvblxuICovXG5leHBvcnQgdHlwZSBEZWNvcmF0b3JEYXRhID0gRGVjb3JhdG9yVHlwZXMgfCBEZWNvcmF0b3JGYWN0b3J5QXJncztcbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgZGVjb3JhdG9yIG1hbmFnZW1lbnQgY2xhc3MgdGhhdCBoYW5kbGVzIGZsYXZvdXJlZCBkZWNvcmF0b3JzXG4gKiBAc3VtbWFyeSBUaGUgRGVjb3JhdGlvbiBjbGFzcyBwcm92aWRlcyBhIGJ1aWxkZXIgcGF0dGVybiBmb3IgY3JlYXRpbmcgYW5kIG1hbmFnaW5nIGRlY29yYXRvcnMgd2l0aCBkaWZmZXJlbnQgZmxhdm91cnMuXG4gKiBJdCBzdXBwb3J0cyByZWdpc3RlcmluZywgZXh0ZW5kaW5nLCBhbmQgYXBwbHlpbmcgZGVjb3JhdG9ycyB3aXRoIGNvbnRleHQtYXdhcmUgZmxhdm91ciByZXNvbHV0aW9uLlxuICogVGhlIGNsYXNzIGltcGxlbWVudHMgYSBmbHVlbnQgaW50ZXJmYWNlIGZvciBkZWZpbmluZywgZXh0ZW5kaW5nLCBhbmQgYXBwbHlpbmcgZGVjb3JhdG9ycyB3aXRoIGRpZmZlcmVudCBmbGF2b3VycyxcbiAqIGFsbG93aW5nIGZvciBmcmFtZXdvcmstc3BlY2lmaWMgZGVjb3JhdG9yIGltcGxlbWVudGF0aW9ucyB3aGlsZSBtYWludGFpbmluZyBhIGNvbnNpc3RlbnQgQVBJLlxuICogQHRlbXBsYXRlIFQgVHlwZSBvZiB0aGUgZGVjb3JhdG9yIChDbGFzc0RlY29yYXRvciB8IFByb3BlcnR5RGVjb3JhdG9yIHwgTWV0aG9kRGVjb3JhdG9yKVxuICogQHBhcmFtIHtzdHJpbmd9IFtmbGF2b3VyXSBPcHRpb25hbCBmbGF2b3VyIHBhcmFtZXRlciBmb3IgdGhlIGRlY29yYXRvciBjb250ZXh0XG4gKiBAY2xhc3NcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBDcmVhdGUgYSBuZXcgZGVjb3JhdGlvbiBmb3IgJ2NvbXBvbmVudCcgd2l0aCBkZWZhdWx0IGZsYXZvdXJcbiAqIGNvbnN0IGNvbXBvbmVudERlY29yYXRvciA9IG5ldyBEZWNvcmF0aW9uKClcbiAqICAgLmZvcignY29tcG9uZW50JylcbiAqICAgLmRlZmluZShjdXN0b21Db21wb25lbnREZWNvcmF0b3IpO1xuICpcbiAqIC8vIENyZWF0ZSBhIGZsYXZvdXJlZCBkZWNvcmF0aW9uXG4gKiBjb25zdCB2dWVDb21wb25lbnQgPSBuZXcgRGVjb3JhdGlvbigndnVlJylcbiAqICAgLmZvcignY29tcG9uZW50JylcbiAqICAgLmRlZmluZSh2dWVDb21wb25lbnREZWNvcmF0b3IpO1xuICpcbiAqIC8vIEFwcGx5IHRoZSBkZWNvcmF0aW9uXG4gKiBAY29tcG9uZW50RGVjb3JhdG9yXG4gKiBjbGFzcyBNeUNvbXBvbmVudCB7fVxuICogYGBgXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IEQgYXMgRGVjb3JhdGlvblxuICogICBwYXJ0aWNpcGFudCBSIGFzIEZsYXZvdXJSZXNvbHZlclxuICogICBwYXJ0aWNpcGFudCBGIGFzIERlY29yYXRvckZhY3RvcnlcbiAqXG4gKiAgIEMtPj5EOiBuZXcgRGVjb3JhdGlvbihmbGF2b3VyKVxuICogICBDLT4+RDogZm9yKGtleSlcbiAqICAgQy0+PkQ6IGRlZmluZShkZWNvcmF0b3JzKVxuICogICBELT4+RDogcmVnaXN0ZXIoa2V5LCBmbGF2b3VyLCBkZWNvcmF0b3JzKVxuICogICBELT4+RjogZGVjb3JhdG9yRmFjdG9yeShrZXksIGZsYXZvdXIpXG4gKiAgIEYtPj5SOiByZXNvbHZlKHRhcmdldClcbiAqICAgUi0tPj5GOiByZXNvbHZlZCBmbGF2b3VyXG4gKiAgIEYtPj5GOiBhcHBseSBkZWNvcmF0b3JzXG4gKiAgIEYtLT4+QzogZGVjb3JhdGVkIHRhcmdldFxuICovXG5leHBvcnQgY2xhc3MgRGVjb3JhdGlvbiBpbXBsZW1lbnRzIElEZWNvcmF0aW9uQnVpbGRlciB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU3RhdGljIG1hcCBvZiByZWdpc3RlcmVkIGRlY29yYXRvcnNcbiAgICogQHN1bW1hcnkgU3RvcmVzIGFsbCByZWdpc3RlcmVkIGRlY29yYXRvcnMgb3JnYW5pemVkIGJ5IGtleSBhbmQgZmxhdm91clxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZGVjb3JhdG9yczogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICBSZWNvcmQ8XG4gICAgICBzdHJpbmcsXG4gICAgICB7XG4gICAgICAgIGRlY29yYXRvcnM/OiBTZXQ8RGVjb3JhdG9yRGF0YT47XG4gICAgICAgIGV4dHJhcz86IFNldDxEZWNvcmF0b3JEYXRhPjtcbiAgICAgIH1cbiAgICA+XG4gID4gPSB7fTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEZ1bmN0aW9uIHRvIHJlc29sdmUgZmxhdm91ciBmcm9tIGEgdGFyZ2V0XG4gICAqIEBzdW1tYXJ5IFJlc29sdmVyIGZ1bmN0aW9uIHRoYXQgZGV0ZXJtaW5lcyB0aGUgYXBwcm9wcmlhdGUgZmxhdm91ciBmb3IgYSBnaXZlbiB0YXJnZXRcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGZsYXZvdXJSZXNvbHZlcjogRmxhdm91clJlc29sdmVyID0gZGVmYXVsdEZsYXZvdXJSZXNvbHZlcjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldCBvZiBkZWNvcmF0b3JzIGZvciB0aGUgY3VycmVudCBjb250ZXh0XG4gICAqL1xuICBwcml2YXRlIGRlY29yYXRvcnM/OiBTZXQ8RGVjb3JhdG9yRGF0YT47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXQgb2YgYWRkaXRpb25hbCBkZWNvcmF0b3JzXG4gICAqL1xuICBwcml2YXRlIGV4dHJhcz86IFNldDxEZWNvcmF0b3JEYXRhPjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEN1cnJlbnQgZGVjb3JhdG9yIGtleVxuICAgKi9cbiAgcHJpdmF0ZSBrZXk/OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBmbGF2b3VyOiBzdHJpbmcgPSBEZWZhdWx0Rmxhdm91cikge31cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIGtleSBmb3IgdGhlIGRlY29yYXRpb24gYnVpbGRlclxuICAgKiBAc3VtbWFyeSBJbml0aWFsaXplcyBhIG5ldyBkZWNvcmF0aW9uIGNoYWluIHdpdGggdGhlIHNwZWNpZmllZCBrZXlcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUgaWRlbnRpZmllciBmb3IgdGhlIGRlY29yYXRvclxuICAgKiBAcmV0dXJuIHtEZWNvcmF0aW9uQnVpbGRlck1pZH0gQnVpbGRlciBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nXG4gICAqL1xuICBmb3Ioa2V5OiBzdHJpbmcpOiBEZWNvcmF0aW9uQnVpbGRlck1pZCB7XG4gICAgdGhpcy5rZXkgPSBrZXk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFkZHMgZGVjb3JhdG9ycyB0byB0aGUgY3VycmVudCBjb250ZXh0XG4gICAqIEBzdW1tYXJ5IEludGVybmFsIG1ldGhvZCB0byBhZGQgZGVjb3JhdG9ycyB3aXRoIGFkZG9uIHN1cHBvcnRcbiAgICogQHBhcmFtIHtib29sZWFufSBbYWRkb249ZmFsc2VdIFdoZXRoZXIgdGhlIGRlY29yYXRvcnMgYXJlIGFkZG9uc1xuICAgKiBAcGFyYW0gZGVjb3JhdG9ycyBBcnJheSBvZiBkZWNvcmF0b3JzXG4gICAqIEByZXR1cm4ge3RoaXN9IEN1cnJlbnQgaW5zdGFuY2UgZm9yIGNoYWluaW5nXG4gICAqL1xuICBwcml2YXRlIGRlY29yYXRlKFxuICAgIGFkZG9uOiBib29sZWFuID0gZmFsc2UsXG4gICAgLi4uZGVjb3JhdG9yczogRGVjb3JhdG9yRGF0YVtdXG4gICk6IHRoaXMge1xuICAgIGlmICghdGhpcy5rZXkpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJrZXkgbXVzdCBiZSBwcm92aWRlZCBiZWZvcmUgZGVjb3JhdG9ycyBjYW4gYmUgYWRkZWRcIik7XG4gICAgaWYgKFxuICAgICAgKCFkZWNvcmF0b3JzIHx8ICFkZWNvcmF0b3JzLmxlbmd0aCkgJiZcbiAgICAgICFhZGRvbiAmJlxuICAgICAgdGhpcy5mbGF2b3VyICE9PSBEZWZhdWx0Rmxhdm91clxuICAgIClcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJNdXN0IHByb3ZpZGUgb3ZlcnJpZGVzIG9yIGFkZG9ucyB0byBvdmVycmlkZSBvciBleHRlbmQgZGVjYWYncyBkZWNvcmF0b3JzXCJcbiAgICAgICk7XG4gICAgaWYgKHRoaXMuZmxhdm91ciA9PT0gRGVmYXVsdEZsYXZvdXIgJiYgYWRkb24pXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEZWZhdWx0IGZsYXZvdXIgY2Fubm90IGJlIGV4dGVuZGVkXCIpO1xuXG4gICAgdGhpc1thZGRvbiA/IFwiZXh0cmFzXCIgOiBcImRlY29yYXRvcnNcIl0gPSBuZXcgU2V0KFtcbiAgICAgIC4uLih0aGlzW2FkZG9uID8gXCJleHRyYXNcIiA6IFwiZGVjb3JhdG9yc1wiXSB8fCBuZXcgU2V0KCkpLnZhbHVlcygpLFxuICAgICAgLi4uZGVjb3JhdG9ycyxcbiAgICBdKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBEZWZpbmVzIHRoZSBiYXNlIGRlY29yYXRvcnNcbiAgICogQHN1bW1hcnkgU2V0cyB0aGUgcHJpbWFyeSBkZWNvcmF0b3JzIGZvciB0aGUgY3VycmVudCBjb250ZXh0XG4gICAqIEBwYXJhbSBkZWNvcmF0b3JzIERlY29yYXRvcnMgdG8gZGVmaW5lXG4gICAqIEByZXR1cm4gQnVpbGRlciBpbnN0YW5jZSBmb3IgZmluaXNoaW5nIHRoZSBjaGFpblxuICAgKi9cbiAgZGVmaW5lKFxuICAgIC4uLmRlY29yYXRvcnM6IERlY29yYXRvckRhdGFbXVxuICApOiBEZWNvcmF0aW9uQnVpbGRlckVuZCAmIERlY29yYXRpb25CdWlsZGVyQnVpbGQge1xuICAgIHJldHVybiB0aGlzLmRlY29yYXRlKGZhbHNlLCAuLi5kZWNvcmF0b3JzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRXh0ZW5kcyBleGlzdGluZyBkZWNvcmF0b3JzXG4gICAqIEBzdW1tYXJ5IEFkZHMgYWRkaXRpb25hbCBkZWNvcmF0b3JzIHRvIHRoZSBjdXJyZW50IGNvbnRleHRcbiAgICogQHBhcmFtIGRlY29yYXRvcnMgQWRkaXRpb25hbCBkZWNvcmF0b3JzXG4gICAqIEByZXR1cm4ge0RlY29yYXRpb25CdWlsZGVyQnVpbGR9IEJ1aWxkZXIgaW5zdGFuY2UgZm9yIGJ1aWxkaW5nIHRoZSBkZWNvcmF0b3JcbiAgICovXG4gIGV4dGVuZCguLi5kZWNvcmF0b3JzOiBEZWNvcmF0b3JEYXRhW10pOiBEZWNvcmF0aW9uQnVpbGRlckJ1aWxkIHtcbiAgICByZXR1cm4gdGhpcy5kZWNvcmF0ZSh0cnVlLCAuLi5kZWNvcmF0b3JzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRmFjdG9yeSB0aGF0IGNyZWF0ZXMgYSBjb250ZXh0LWF3YXJlIGRlY29yYXRvciBmb3IgYSBrZXkvZmxhdm91clxuICAgKiBAc3VtbWFyeSBQcm9kdWNlcyBhIGRlY29yYXRvciBmdW5jdGlvbiBib3VuZCB0byB0aGUgcHJvdmlkZWQga2V5IGFuZCBmbGF2b3VyLiBUaGUgcmVzdWx0aW5nIGRlY29yYXRvciByZXNvbHZlcyB0aGUgYWN0dWFsXG4gICAqIGRlY29yYXRvcnMgdG8gYXBwbHkgYXQgaW52b2NhdGlvbiB0aW1lIGJhc2VkIG9uIHRoZSB0YXJnZXQncyByZXNvbHZlZCBmbGF2b3VyIGFuZCB0aGUgcmVnaXN0ZXJlZCBiYXNlIGFuZCBleHRyYSBkZWNvcmF0b3JzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBkZWNvcmF0aW9uIGtleSB1c2VkIHRvIGxvb2sgdXAgcmVnaXN0ZXJlZCBkZWNvcmF0b3JzXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZj1EZWZhdWx0Rmxhdm91cl0gT3B0aW9uYWwgZXhwbGljaXQgZmxhdm91ciB0byBiaW5kIHRoZSBmYWN0b3J5IHRvXG4gICAqIEByZXR1cm4ge2Z1bmN0aW9uKG9iamVjdCwgYW55LCBUeXBlZFByb3BlcnR5RGVzY3JpcHRvcjxhbnk+KTogYW55fSBBIGRlY29yYXRvciBmdW5jdGlvbiB0aGF0IGFwcGxpZXMgdGhlIHJlc29sdmVkIGRlY29yYXRvcnNcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgVSBhcyBVc2VyIENvZGVcbiAgICogICBwYXJ0aWNpcGFudCBCIGFzIERlY29yYXRpb24gKGJ1aWxkZXIpXG4gICAqICAgcGFydGljaXBhbnQgRiBhcyBkZWNvcmF0b3JGYWN0b3J5KGtleSwgZilcbiAgICogICBwYXJ0aWNpcGFudCBSIGFzIGZsYXZvdXJSZXNvbHZlclxuICAgKiAgIHBhcnRpY2lwYW50IEEgYXMgQXBwbGllZCBEZWNvcmF0b3JzXG4gICAqICAgVS0+PkI6IGRlZmluZSgpL2V4dGVuZCgpIGFuZCBhcHBseSgpXG4gICAqICAgQi0+PkY6IGNyZWF0ZSBjb250ZXh0IGRlY29yYXRvclxuICAgKiAgIEYtPj5SOiByZXNvbHZlKHRhcmdldClcbiAgICogICBSLS0+PkY6IGZsYXZvdXJcbiAgICogICBGLT4+QTogY29sbGVjdCBiYXNlICsgZXh0cmFzXG4gICAqICAgbG9vcCBlYWNoIGRlY29yYXRvclxuICAgKiAgICAgQS0+PlU6IGludm9rZSBkZWNvcmF0b3IodGFyZ2V0LCBrZXk/LCBkZXNjPylcbiAgICogICBlbmRcbiAgICovXG4gIHByb3RlY3RlZCBkZWNvcmF0b3JGYWN0b3J5KGtleTogc3RyaW5nLCBmOiBzdHJpbmcgPSBEZWZhdWx0Rmxhdm91cikge1xuICAgIGZ1bmN0aW9uIGNvbnRleHREZWNvcmF0b3IoXG4gICAgICB0YXJnZXQ6IG9iamVjdCxcbiAgICAgIHByb3BlcnR5S2V5PzogYW55LFxuICAgICAgZGVzY3JpcHRvcj86IFR5cGVkUHJvcGVydHlEZXNjcmlwdG9yPGFueT5cbiAgICApIHtcbiAgICAgIGNvbnN0IGZsYXZvdXIgPSBEZWNvcmF0aW9uLmZsYXZvdXJSZXNvbHZlcih0YXJnZXQpO1xuICAgICAgY29uc3QgY2FjaGUgPSBEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XTtcbiAgICAgIGxldCBkZWNvcmF0b3JzO1xuICAgICAgY29uc3QgZXh0cmFzID0gY2FjaGVbZmxhdm91cl1cbiAgICAgICAgPyBjYWNoZVtmbGF2b3VyXS5leHRyYXNcbiAgICAgICAgOiBjYWNoZVtEZWZhdWx0Rmxhdm91cl0uZXh0cmFzO1xuICAgICAgY29uc3QgZXh0cmFBcmdzID0gW1xuICAgICAgICAuLi4oKGNhY2hlW0RlZmF1bHRGbGF2b3VyXSBhcyBhbnkpLmV4dHJhc1xuICAgICAgICAgID8gKGNhY2hlW0RlZmF1bHRGbGF2b3VyXSBhcyBhbnkpLmV4dHJhcy52YWx1ZXMoKVxuICAgICAgICAgIDogW10pLFxuICAgICAgXS5yZWR1Y2UoKGFjY3VtOiBSZWNvcmQ8bnVtYmVyLCBhbnk+LCBlLCBpKSA9PiB7XG4gICAgICAgIGlmIChlLmFyZ3MpIGFjY3VtW2ldID0gZS5hcmdzO1xuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LCB7fSk7XG5cbiAgICAgIGlmIChcbiAgICAgICAgY2FjaGUgJiZcbiAgICAgICAgY2FjaGVbZmxhdm91cl0gJiZcbiAgICAgICAgY2FjaGVbZmxhdm91cl0uZGVjb3JhdG9ycyAmJlxuICAgICAgICBjYWNoZVtmbGF2b3VyXS5kZWNvcmF0b3JzLnNpemVcbiAgICAgICkge1xuICAgICAgICBkZWNvcmF0b3JzID0gY2FjaGVbZmxhdm91cl0uZGVjb3JhdG9ycztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlY29yYXRvcnMgPSBjYWNoZVtEZWZhdWx0Rmxhdm91cl0uZGVjb3JhdG9ycztcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGVjb3JhdG9yQXJncyA9IFtcbiAgICAgICAgLi4uKGNhY2hlW0RlZmF1bHRGbGF2b3VyXSBhcyBhbnkpLmRlY29yYXRvcnMudmFsdWVzKCksXG4gICAgICBdLnJlZHVjZSgoYWNjdW06IFJlY29yZDxudW1iZXIsIGFueT4sIGUsIGkpID0+IHtcbiAgICAgICAgaWYgKGUuYXJncykgYWNjdW1baV0gPSBlLmFyZ3M7XG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgIH0sIHt9KTtcblxuICAgICAgY29uc3QgdG9BcHBseSA9IFtcbiAgICAgICAgLi4uKGRlY29yYXRvcnMgPyBkZWNvcmF0b3JzLnZhbHVlcygpIDogW10pLFxuICAgICAgICAuLi4oZXh0cmFzID8gZXh0cmFzLnZhbHVlcygpIDogW10pLFxuICAgICAgXTtcblxuICAgICAgcmV0dXJuIHRvQXBwbHkucmVkdWNlKFxuICAgICAgICAoXywgZCwgaSkgPT4ge1xuICAgICAgICAgIHN3aXRjaCAodHlwZW9mIGQpIHtcbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjoge1xuICAgICAgICAgICAgICBjb25zdCB7IGRlY29yYXRvciwgYXJncyB9ID0gZCBhcyBEZWNvcmF0b3JGYWN0b3J5QXJncztcbiAgICAgICAgICAgICAgY29uc3QgYXJneiA9XG4gICAgICAgICAgICAgICAgYXJncyB8fCBpIDwgKGRlY29yYXRvcnMgPyBkZWNvcmF0b3JzLnNpemUgOiAwKVxuICAgICAgICAgICAgICAgICAgPyBkZWNvcmF0b3JBcmdzW2ldXG4gICAgICAgICAgICAgICAgICA6IGV4dHJhQXJnc1tpIC0gKGRlY29yYXRvcnMgPyBkZWNvcmF0b3JzLnNpemUgOiAwKV0gfHxcbiAgICAgICAgICAgICAgICAgICAgKGRlY29yYXRvcnMgPyBkZWNvcmF0b3JBcmdzW2kgLSBkZWNvcmF0b3JzLnNpemVdIDogW10pO1xuXG4gICAgICAgICAgICAgIHJldHVybiAoZGVjb3JhdG9yKC4uLihhcmd6IHx8IFtdKSkgYXMgYW55KShcbiAgICAgICAgICAgICAgICB0YXJnZXQsXG4gICAgICAgICAgICAgICAgcHJvcGVydHlLZXksXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRvclxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImZ1bmN0aW9uXCI6XG4gICAgICAgICAgICAgIHJldHVybiAoZCBhcyBhbnkpKHRhcmdldCwgcHJvcGVydHlLZXksIGRlc2NyaXB0b3IpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmV4cGVjdGVkIGRlY29yYXRvciB0eXBlOiAke3R5cGVvZiBkfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgeyB0YXJnZXQsIHByb3BlcnR5S2V5LCBkZXNjcmlwdG9yIH1cbiAgICAgICk7XG4gICAgfVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb250ZXh0RGVjb3JhdG9yLCBcIm5hbWVcIiwge1xuICAgICAgdmFsdWU6IFtmLCBrZXldLmpvaW4oXCJfZGVjb3JhdG9yX2Zvcl9cIiksXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgfSk7XG4gICAgcmV0dXJuIGNvbnRleHREZWNvcmF0b3I7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgdGhlIGZpbmFsIGRlY29yYXRvciBmdW5jdGlvblxuICAgKiBAc3VtbWFyeSBCdWlsZHMgYW5kIHJldHVybnMgdGhlIGRlY29yYXRvciBmYWN0b3J5IGZ1bmN0aW9uXG4gICAqIEByZXR1cm4ge2Z1bmN0aW9uKGFueSwgYW55PywgVHlwZWRQcm9wZXJ0eURlc2NyaXB0b3I/KTogYW55fSBUaGUgZ2VuZXJhdGVkIGRlY29yYXRvciBmdW5jdGlvblxuICAgKi9cbiAgYXBwbHkoKTogKFxuICAgIHRhcmdldDogYW55LFxuICAgIHByb3BlcnR5S2V5PzogYW55LFxuICAgIGRlc2NyaXB0b3I/OiBUeXBlZFByb3BlcnR5RGVzY3JpcHRvcjxhbnk+XG4gICkgPT4gYW55IHtcbiAgICBpZiAoIXRoaXMua2V5KVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8ga2V5IHByb3ZpZGVkIGZvciB0aGUgZGVjb3JhdGlvbiBidWlsZGVyXCIpO1xuICAgIERlY29yYXRpb24ucmVnaXN0ZXIoXG4gICAgICB0aGlzLmtleSxcbiAgICAgIHRoaXMuZmxhdm91cixcbiAgICAgIHRoaXMuZGVjb3JhdG9ycyB8fCBuZXcgU2V0KCksXG4gICAgICB0aGlzLmV4dHJhc1xuICAgICk7XG4gICAgcmV0dXJuIHRoaXMuZGVjb3JhdG9yRmFjdG9yeSh0aGlzLmtleSwgdGhpcy5mbGF2b3VyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVnaXN0ZXJzIGRlY29yYXRvcnMgZm9yIGEgc3BlY2lmaWMga2V5IGFuZCBmbGF2b3VyXG4gICAqIEBzdW1tYXJ5IEludGVybmFsIG1ldGhvZCB0byBzdG9yZSBkZWNvcmF0b3JzIGluIHRoZSBzdGF0aWMgcmVnaXN0cnlcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBEZWNvcmF0b3Iga2V5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmbGF2b3VyIERlY29yYXRvciBmbGF2b3VyXG4gICAqIEBwYXJhbSBbZGVjb3JhdG9yc10gUHJpbWFyeSBkZWNvcmF0b3JzXG4gICAqIEBwYXJhbSBbZXh0cmFzXSBBZGRpdGlvbmFsIGRlY29yYXRvcnNcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHJlZ2lzdGVyKFxuICAgIGtleTogc3RyaW5nLFxuICAgIGZsYXZvdXI6IHN0cmluZyxcbiAgICBkZWNvcmF0b3JzPzogU2V0PERlY29yYXRvckRhdGE+LFxuICAgIGV4dHJhcz86IFNldDxEZWNvcmF0b3JEYXRhPlxuICApIHtcbiAgICBpZiAoIWtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8ga2V5IHByb3ZpZGVkIGZvciB0aGUgZGVjb3JhdGlvbiBidWlsZGVyXCIpO1xuICAgIH1cbiAgICBpZiAoIWRlY29yYXRvcnMpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBkZWNvcmF0b3JzIHByb3ZpZGVkIGZvciB0aGUgZGVjb3JhdGlvbiBidWlsZGVyXCIpO1xuICAgIGlmICghZmxhdm91cilcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGZsYXZvdXIgcHJvdmlkZWQgZm9yIHRoZSBkZWNvcmF0aW9uIGJ1aWxkZXJcIik7XG5cbiAgICBpZiAoIURlY29yYXRpb24uZGVjb3JhdG9yc1trZXldKSBEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XSA9IHt9O1xuICAgIGlmICghRGVjb3JhdGlvbi5kZWNvcmF0b3JzW2tleV1bZmxhdm91cl0pXG4gICAgICBEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XVtmbGF2b3VyXSA9IHt9O1xuICAgIGlmIChkZWNvcmF0b3JzKSBEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XVtmbGF2b3VyXS5kZWNvcmF0b3JzID0gZGVjb3JhdG9ycztcbiAgICBpZiAoZXh0cmFzKSBEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XVtmbGF2b3VyXS5leHRyYXMgPSBleHRyYXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIGdsb2JhbCBmbGF2b3VyIHJlc29sdmVyXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgdGhlIGZ1bmN0aW9uIHVzZWQgdG8gZGV0ZXJtaW5lIGRlY29yYXRvciBmbGF2b3Vyc1xuICAgKiBAcGFyYW0ge0ZsYXZvdXJSZXNvbHZlcn0gcmVzb2x2ZXIgRnVuY3Rpb24gdG8gcmVzb2x2ZSBmbGF2b3Vyc1xuICAgKi9cbiAgc3RhdGljIHNldEZsYXZvdXJSZXNvbHZlcihyZXNvbHZlcjogRmxhdm91clJlc29sdmVyKSB7XG4gICAgRGVjb3JhdGlvbi5mbGF2b3VyUmVzb2x2ZXIgPSByZXNvbHZlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ29udmVuaWVuY2Ugc3RhdGljIGVudHJ5IHRvIHN0YXJ0IGEgZGVjb3JhdGlvbiBidWlsZGVyXG4gICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBuZXcgRGVjb3JhdGlvbiBpbnN0YW5jZSBhbmQgaW5pdGlhdGVzIHRoZSBidWlsZGVyIGNoYWluIHdpdGggdGhlIHByb3ZpZGVkIGtleS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUgZGVjb3JhdGlvbiBrZXkgdG8gY29uZmlndXJlXG4gICAqIEByZXR1cm4ge0RlY29yYXRpb25CdWlsZGVyTWlkfSBBIGJ1aWxkZXIgaW5zdGFuY2UgZm9yIGNoYWluaW5nIGRlZmluaXRpb25zXG4gICAqL1xuICBzdGF0aWMgZm9yKGtleTogc3RyaW5nKTogRGVjb3JhdGlvbkJ1aWxkZXJNaWQge1xuICAgIHJldHVybiBuZXcgRGVjb3JhdGlvbigpLmZvcihrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTdGFydHMgYSBidWlsZGVyIGZvciBhIHNwZWNpZmljIGZsYXZvdXJcbiAgICogQHN1bW1hcnkgQ29udmVuaWVuY2UgbWV0aG9kIHRvIGJlZ2luIGEgRGVjb3JhdGlvbiBidWlsZGVyIGNoYWluIGJvdW5kIHRvIHRoZSBnaXZlbiBmbGF2b3VyIGlkZW50aWZpZXIsIGFsbG93aW5nIHJlZ2lzdHJhdGlvbiBvZiBmbGF2b3VyLXNwZWNpZmljIGRlY29yYXRvcnMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmbGF2b3VyIFRoZSBmbGF2b3VyIG5hbWUgdG8gYmluZCB0byB0aGUgYnVpbGRlclxuICAgKiBAcmV0dXJuIHtEZWNvcmF0aW9uQnVpbGRlclN0YXJ0fSBBIGJ1aWxkZXIgc3RhcnQgaW50ZXJmYWNlIHRvIGNvbnRpbnVlIGNvbmZpZ3VyYXRpb25cbiAgICovXG4gIHN0YXRpYyBmbGF2b3VyZWRBcyhmbGF2b3VyOiBzdHJpbmcpOiBEZWNvcmF0aW9uQnVpbGRlclN0YXJ0IHtcbiAgICByZXR1cm4gbmV3IERlY29yYXRpb24oZmxhdm91cik7XG4gIH1cbn1cbiIsImltcG9ydCB7IEJhc2ljTWV0YWRhdGEsIENvbnN0cnVjdG9yIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IERlY29yYXRpb25LZXlzLCBPYmplY3RLZXlTcGxpdHRlciB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCBcInJlZmxlY3QtbWV0YWRhdGFcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgbmVzdGVkIHZhbHVlIGZyb20gYW4gb2JqZWN0IGdpdmVuIGEgcGF0aFxuICogQHN1bW1hcnkgV2Fsa3MgYW4gb2JqZWN0IHN0cnVjdHVyZSB1c2luZyBhIHNwbGl0dGVyLWRlbGltaXRlZCBwYXRoIGFuZCByZXR1cm5zIHRoZSB2YWx1ZSBhdCB0aGF0IGxvY2F0aW9uIG9yIHVuZGVmaW5lZCBpZiBhbnkga2V5IGlzIG1pc3NpbmcuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IG9iaiBUaGUgb2JqZWN0IHRvIHRyYXZlcnNlXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgcGF0aCB0byB0aGUgZGVzaXJlZCB2YWx1ZSAoZS5nLiwgXCJhLmIuY1wiKVxuICogQHBhcmFtIHtzdHJpbmd9IFtzcGxpdHRlcj1PYmplY3RLZXlTcGxpdHRlcl0gVGhlIGRlbGltaXRlciB1c2VkIHRvIHNwbGl0IHRoZSBwYXRoXG4gKiBAcmV0dXJuIHsqfSBUaGUgcmVzb2x2ZWQgdmFsdWUgYXQgdGhlIGdpdmVuIHBhdGggb3IgdW5kZWZpbmVkIGlmIG5vdCBmb3VuZFxuICogQGZ1bmN0aW9uIGdldFZhbHVlQnlTcGxpdHRlclxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENhbGxlclxuICogICBwYXJ0aWNpcGFudCBGIGFzIGdldFZhbHVlQnlTcGxpdHRlclxuICogICBwYXJ0aWNpcGFudCBPIGFzIE9iamVjdFxuICogICBDLT4+RjogKG9iaiwgcGF0aCwgc3BsaXR0ZXIpXG4gKiAgIEYtPj5GOiBzcGxpdCBwYXRoIGludG8ga2V5c1xuICogICBsb29wIGZvciBlYWNoIGtleVxuICogICAgIEYtPj5POiBhY2Nlc3MgY3VycmVudFtrZXldXG4gKiAgICAgYWx0IG1pc3Npbmcgb3IgbnVsbGlzaFxuICogICAgICAgRi0tPj5DOiByZXR1cm4gdW5kZWZpbmVkXG4gKiAgICAgZW5kXG4gKiAgIGVuZFxuICogICBGLS0+PkM6IHJldHVybiBmaW5hbCB2YWx1ZVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0aW9uXG4gKi9cbmZ1bmN0aW9uIGdldFZhbHVlQnlTcGxpdHRlcihcbiAgb2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICBwYXRoOiBzdHJpbmcsXG4gIHNwbGl0dGVyOiBzdHJpbmcgPSBPYmplY3RLZXlTcGxpdHRlclxuKTogYW55IHtcbiAgY29uc3Qga2V5cyA9IHBhdGguc3BsaXQoc3BsaXR0ZXIpO1xuICBsZXQgY3VycmVudCA9IG9iajtcblxuICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgaWYgKFxuICAgICAgY3VycmVudCA9PT0gbnVsbCB8fFxuICAgICAgY3VycmVudCA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGN1cnJlbnQsIGtleSlcbiAgICApXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGN1cnJlbnQgPSBjdXJyZW50W2tleV07XG4gIH1cblxuICByZXR1cm4gY3VycmVudDtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gU2V0cyBhIG5lc3RlZCB2YWx1ZSBvbiBhbiBvYmplY3QgZ2l2ZW4gYSBwYXRoXG4gKiBAc3VtbWFyeSBUcmF2ZXJzZXMgb3IgY3JlYXRlcyBpbnRlcm1lZGlhdGUgb2JqZWN0cyBmb2xsb3dpbmcgYSBzcGxpdHRlci1kZWxpbWl0ZWQgcGF0aCBhbmQgYXNzaWducyB0aGUgcHJvdmlkZWQgdmFsdWUgYXQgdGhlIGRlc3RpbmF0aW9uIGtleS5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gb2JqIFRoZSBvYmplY3QgdG8gbXV0YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgZGVzdGluYXRpb24gcGF0aCAoZS5nLiwgXCJhLmIuY1wiKVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0IGF0IHRoZSBkZXN0aW5hdGlvblxuICogQHBhcmFtIHtzdHJpbmd9IFtzcGxpdHRlcj1PYmplY3RLZXlTcGxpdHRlcl0gVGhlIGRlbGltaXRlciB1c2VkIHRvIHNwbGl0IHRoZSBwYXRoXG4gKiBAcmV0dXJuIHt2b2lkfVxuICogQGZ1bmN0aW9uIHNldFZhbHVlQnlTcGxpdHRlclxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENhbGxlclxuICogICBwYXJ0aWNpcGFudCBGIGFzIHNldFZhbHVlQnlTcGxpdHRlclxuICogICBwYXJ0aWNpcGFudCBPIGFzIE9iamVjdFxuICogICBDLT4+RjogKG9iaiwgcGF0aCwgdmFsdWUsIHNwbGl0dGVyKVxuICogICBGLT4+Rjogc3BsaXQgcGF0aCBpbnRvIGtleXNcbiAqICAgbG9vcCBmb3IgZWFjaCBrZXlcbiAqICAgICBhbHQga2V5IG1pc3NpbmdcbiAqICAgICAgIEYtPj5POiBjcmVhdGUgaW50ZXJtZWRpYXRlIG9iamVjdFxuICogICAgIGVsc2Uga2V5IGV4aXN0c1xuICogICAgICAgRi0+Pk86IGRlc2NlbmQgaW50byBleGlzdGluZyBvYmplY3RcbiAqICAgICBlbmRcbiAqICAgZW5kXG4gKiAgIEYtLT4+Qzogdm9pZFxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0aW9uXG4gKi9cbmZ1bmN0aW9uIHNldFZhbHVlQnlTcGxpdHRlcihcbiAgb2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICBwYXRoOiBzdHJpbmcsXG4gIHZhbHVlOiBhbnksXG4gIHNwbGl0dGVyID0gT2JqZWN0S2V5U3BsaXR0ZXJcbik6IHZvaWQge1xuICBjb25zdCBrZXlzID0gcGF0aC5zcGxpdChzcGxpdHRlcikuZmlsdGVyKChrKSA9PiBrLmxlbmd0aCA+IDApO1xuICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHJldHVybjtcblxuICBsZXQgY3VycmVudDogUmVjb3JkPGFueSwgYW55PiA9IG9iajtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgY29uc3Qga2V5ID0ga2V5c1tpXTtcbiAgICBpZiAoXG4gICAgICBjdXJyZW50W2tleV0gPT09IHVuZGVmaW5lZCB8fFxuICAgICAgY3VycmVudFtrZXldID09PSBudWxsIHx8XG4gICAgICB0eXBlb2YgY3VycmVudFtrZXldICE9PSBcIm9iamVjdFwiXG4gICAgKSB7XG4gICAgICBjdXJyZW50W2tleV0gPSB7fTtcbiAgICB9XG4gICAgY3VycmVudCA9IGN1cnJlbnRba2V5XTtcbiAgfVxuXG4gIGNvbnN0IGxhc3RLZXkgPSBrZXlzW2tleXMubGVuZ3RoIC0gMV07XG4gIGN1cnJlbnRbbGFzdEtleV0gPSB2YWx1ZTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ2VudHJhbGl6ZWQgcnVudGltZSBtZXRhZGF0YSBzdG9yZSBib3VuZCB0byBjb25zdHJ1Y3RvcnNcbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIHV0aWxpdGllcyB0byByZWFkIGFuZCB3cml0ZSBzdHJ1Y3R1cmVkIG1ldGFkYXRhIGZvciBjbGFzc2VzIGFuZCB0aGVpciBtZW1iZXJzLCB3aXRoIG9wdGlvbmFsIG1pcnJvcmluZyBvbnRvIHRoZSBjb25zdHJ1Y3RvciB2aWEgYSB3ZWxsLWtub3duIHN5bWJvbCBrZXkuIFN1cHBvcnRzIG5lc3RlZCBrZXkgcGF0aHMgdXNpbmcgYSBjb25maWd1cmFibGUgc3BsaXR0ZXIgYW5kIG9mZmVycyBib3RoIGluc3RhbmNlIGFuZCBzdGF0aWMgQVBJcy5cbiAqIEB0ZW1wbGF0ZSBNIFRoZSBtb2RlbCB0eXBlIHRoZSBtZXRhZGF0YSBiZWxvbmdzIHRvXG4gKiBAdGVtcGxhdGUgTUVUQSBFeHRlbmRzIEJhc2ljTWV0YWRhdGE8TT4gcmVwcmVzZW50aW5nIHRoZSBtZXRhZGF0YSBzdHJ1Y3R1cmVcbiAqIEBjbGFzc1xuICogQGV4YW1wbGVcbiAqIC8vIERlZmluZSBhbmQgcmVhZCBtZXRhZGF0YSBmb3IgYSBjbGFzc1xuICogY2xhc3MgVXNlciB7IG5hbWUhOiBzdHJpbmcgfVxuICogTWV0YWRhdGEuc2V0KFVzZXIsIFwiZGVzY3JpcHRpb24uY2xhc3NcIiwgXCJBIHVzZXIgbW9kZWxcIik7XG4gKiBNZXRhZGF0YS5zZXQoVXNlciwgXCJwcm9wZXJ0aWVzLm5hbWVcIiwgU3RyaW5nKTtcbiAqIGNvbnN0IGRlc2MgPSBNZXRhZGF0YS5nZXQoVXNlciwgXCJkZXNjcmlwdGlvbi5jbGFzc1wiKTsgLy8gXCJBIHVzZXIgbW9kZWxcIlxuICogY29uc3QgdHlwZSA9IE1ldGFkYXRhLnR5cGUoVXNlciwgXCJuYW1lXCIpOyAvLyBTdHJpbmdcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQyBhcyBDb25zdHJ1Y3RvclxuICogICBwYXJ0aWNpcGFudCBTIGFzIE1ldGFkYXRhIChzdGF0aWMpXG4gKiAgIEMtPj5TOiBzZXQoVXNlciwgXCJwcm9wZXJ0aWVzLm5hbWVcIiwgU3RyaW5nKVxuICogICBDLT4+UzogZ2V0KFVzZXIsIFwicHJvcGVydGllcy5uYW1lXCIpXG4gKiAgIFMtLT4+QzogU3RyaW5nXG4gKi9cbmV4cG9ydCBjbGFzcyBNZXRhZGF0YSB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gSW4tbWVtb3J5IHN0b3JhZ2Ugb2YgbWV0YWRhdGEgYnkgY29uc3RydWN0b3Igc3ltYm9sXG4gICAqIEBzdW1tYXJ5IE1hcHMgYSBTeW1ib2wgZGVyaXZlZCBmcm9tIHRoZSBjb25zdHJ1Y3RvciB0byBpdHMgbWV0YWRhdGEgb2JqZWN0LCBlbmFibGluZyBlZmZpY2llbnQgbG9va3VwLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgX21ldGFkYXRhOiBSZWNvcmQ8c3ltYm9sLCBhbnk+ID0ge307XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQYXRoIGRlbGltaXRlciBmb3IgbmVzdGVkIG1ldGFkYXRhIGtleXNcbiAgICogQHN1bW1hcnkgVXNlZCBieSBnZXQvc2V0IG9wZXJhdGlvbnMgdG8gbmF2aWdhdGUgbmVzdGVkIHN0cnVjdHVyZXMsIGRlZmF1bHRzIHRvIE9iamVjdEtleVNwbGl0dGVyLlxuICAgKi9cbiAgc3RhdGljIHNwbGl0dGVyID0gT2JqZWN0S2V5U3BsaXR0ZXI7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU3ltYm9sIGtleSB1c2VkIHRvIG1pcnJvciBtZXRhZGF0YSBvbiB0aGUgY29uc3RydWN0b3JcbiAgICogQHN1bW1hcnkgV2hlbiBtaXJyb3JpbmcgaXMgZW5hYmxlZCwgdGhlIG1ldGFkYXRhIG9iamVjdCBpcyBkZWZpbmVkIG9uIHRoZSBjb25zdHJ1Y3RvciB1bmRlciB0aGlzIG5vbi1lbnVtZXJhYmxlIGtleS5cbiAgICovXG4gIHN0YXRpYyBiYXNlS2V5ID0gRGVjb3JhdGlvbktleXMuUkVGTEVDVDtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDb250cm9scyB3aGV0aGVyIG1ldGFkYXRhIGlzIG1pcnJvcmVkIG9udG8gdGhlIGNvbnN0cnVjdG9yXG4gICAqIEBzdW1tYXJ5IFdoZW4gdHJ1ZSwgdGhlIG1ldGFkYXRhIG9iamVjdCBpcyBkZWZpbmVkIG9uIHRoZSBjb25zdHJ1Y3RvciB1bmRlciB0aGUgbm9uLWVudW1lcmFibGUgYmFzZUtleS5cbiAgICovXG4gIHN0YXRpYyBtaXJyb3I6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7fVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTGlzdHMga25vd24gcHJvcGVydHkga2V5cyBmb3IgYSBtb2RlbFxuICAgKiBAc3VtbWFyeSBSZWFkcyB0aGUgbWV0YWRhdGEgZW50cnkgYW5kIHJldHVybnMgdGhlIG5hbWVzIG9mIHByb3BlcnRpZXMgdGhhdCBoYXZlIHJlY29yZGVkIHR5cGUgaW5mb3JtYXRpb24uXG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3J9IG1vZGVsIFRoZSB0YXJnZXQgY29uc3RydWN0b3JcbiAgICogQHJldHVybiB7c3RyaW5nW118dW5kZWZpbmVkfSBBcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyBvciB1bmRlZmluZWQgaWYgbm8gbWV0YWRhdGEgZXhpc3RzXG4gICAqL1xuICBzdGF0aWMgcHJvcGVydGllcyhtb2RlbDogQ29uc3RydWN0b3IpOiBzdHJpbmdbXSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuZ2V0KG1vZGVsKTtcbiAgICBpZiAoIW1ldGEpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKG1ldGEucHJvcGVydGllcyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBhIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIGZvciBhIGNsYXNzIG9yIGEgcHJvcGVydHlcbiAgICogQHN1bW1hcnkgTG9va3MgdXAgdGhlIGRlc2NyaXB0aW9uIHN0b3JlZCB1bmRlciB0aGUgbWV0YWRhdGEgXCJkZXNjcmlwdGlvblwiIG1hcC4gSWYgYSBwcm9wZXJ0eSBrZXkgaXMgcHJvdmlkZWQsIHJldHVybnMgdGhlIHByb3BlcnR5J3MgZGVzY3JpcHRpb247IG90aGVyd2lzZSByZXR1cm5zIHRoZSBjbGFzcyBkZXNjcmlwdGlvbi5cbiAgICogQHRlbXBsYXRlIE1cbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gbW9kZWwgVGhlIHRhcmdldCBjb25zdHJ1Y3RvciB3aG9zZSBkZXNjcmlwdGlvbiBpcyBiZWluZyByZXRyaWV2ZWRcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtwcm9wXSBPcHRpb25hbCBwcm9wZXJ0eSBrZXkgZm9yIHdoaWNoIHRvIGZldGNoIHRoZSBkZXNjcmlwdGlvblxuICAgKiBAcmV0dXJuIHtzdHJpbmd8dW5kZWZpbmVkfSBUaGUgZGVzY3JpcHRpb24gdGV4dCBpZiBwcmVzZW50LCBvdGhlcndpc2UgdW5kZWZpbmVkXG4gICAqL1xuICBzdGF0aWMgZGVzY3JpcHRpb248TT4obW9kZWw6IENvbnN0cnVjdG9yPE0+LCBwcm9wPzoga2V5b2YgTSkge1xuICAgIHJldHVybiB0aGlzLmdldChcbiAgICAgIG1vZGVsLFxuICAgICAgW0RlY29yYXRpb25LZXlzLkRFU0NSSVBUSU9OLCBwcm9wID8gcHJvcCA6IERlY29yYXRpb25LZXlzLkNMQVNTXS5qb2luKFxuICAgICAgICBPYmplY3RLZXlTcGxpdHRlclxuICAgICAgKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyB0aGUgcmVjb3JkZWQgZGVzaWduIHR5cGUgZm9yIGEgcHJvcGVydHlcbiAgICogQHN1bW1hcnkgUmVhZHMgdGhlIG1ldGFkYXRhIGVudHJ5IHVuZGVyIFwicHJvcGVydGllcy48cHJvcD5cIiB0byByZXR1cm4gdGhlIGNvbnN0cnVjdG9yIHJlY29yZGVkIGZvciB0aGUgZ2l2ZW4gcHJvcGVydHkgbmFtZS5cbiAgICogQHBhcmFtIHtDb25zdHJ1Y3Rvcn0gbW9kZWwgVGhlIHRhcmdldCBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge3N0cmluZ30gcHJvcCBUaGUgcHJvcGVydHkgbmFtZSB3aG9zZSB0eXBlIHNob3VsZCBiZSByZXR1cm5lZFxuICAgKiBAcmV0dXJuIHtDb25zdHJ1Y3Rvcnx1bmRlZmluZWR9IFRoZSBjb25zdHJ1Y3RvciByZWZlcmVuY2Ugb2YgdGhlIHByb3BlcnR5IHR5cGUgb3IgdW5kZWZpbmVkIGlmIG5vdCBhdmFpbGFibGVcbiAgICovXG4gIHN0YXRpYyB0eXBlKG1vZGVsOiBDb25zdHJ1Y3RvciwgcHJvcDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KG1vZGVsLCBgJHtEZWNvcmF0aW9uS2V5cy5QUk9QRVJUSUVTfS4ke3Byb3B9YCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBtZXRhZGF0YSBmb3IgYSBtb2RlbCBvciBhIHNwZWNpZmljIGtleSB3aXRoaW4gaXRcbiAgICogQHN1bW1hcnkgV2hlbiBjYWxsZWQgd2l0aCBhIGNvbnN0cnVjdG9yIG9ubHksIHJldHVybnMgdGhlIGVudGlyZSBtZXRhZGF0YSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBtb2RlbC4gV2hlbiBhIGtleSBwYXRoIGlzIHByb3ZpZGVkLCByZXR1cm5zIHRoZSB2YWx1ZSBzdG9yZWQgYXQgdGhhdCBuZXN0ZWQga2V5LlxuICAgKiBAdGVtcGxhdGUgTVxuICAgKiBAdGVtcGxhdGUgTUVUQVxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBtb2RlbCBUaGUgdGFyZ2V0IGNvbnN0cnVjdG9yIHVzZWQgdG8gbG9jYXRlIHRoZSBtZXRhZGF0YSByZWNvcmRcbiAgICogQHJldHVybiB7TUVUQXx1bmRlZmluZWR9IFRoZSBtZXRhZGF0YSBvYmplY3QsIHRoZSB2YWx1ZSBhdCB0aGUga2V5IHBhdGgsIG9yIHVuZGVmaW5lZCBpZiBub3RoaW5nIGV4aXN0c1xuICAgKi9cbiAgc3RhdGljIGdldDxNLCBNRVRBIGV4dGVuZHMgQmFzaWNNZXRhZGF0YTxNPiA9IEJhc2ljTWV0YWRhdGE8TT4+KFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPlxuICApOiBNRVRBIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBtZXRhZGF0YSBmb3IgYSBtb2RlbCBvciBhIHNwZWNpZmljIGtleSB3aXRoaW4gaXRcbiAgICogQHN1bW1hcnkgV2hlbiBjYWxsZWQgd2l0aCBhIGNvbnN0cnVjdG9yIG9ubHksIHJldHVybnMgdGhlIGVudGlyZSBtZXRhZGF0YSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBtb2RlbC4gV2hlbiBhIGtleSBwYXRoIGlzIHByb3ZpZGVkLCByZXR1cm5zIHRoZSB2YWx1ZSBzdG9yZWQgYXQgdGhhdCBuZXN0ZWQga2V5LlxuICAgKiBAdGVtcGxhdGUgTVxuICAgKiBAdGVtcGxhdGUgTUVUQVxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBtb2RlbCBUaGUgdGFyZ2V0IGNvbnN0cnVjdG9yIHVzZWQgdG8gbG9jYXRlIHRoZSBtZXRhZGF0YSByZWNvcmRcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBuZXN0ZWQga2V5IHBhdGggdG8gZmV0Y2ggYSBzcGVjaWZpYyB2YWx1ZVxuICAgKiBAcmV0dXJuIHtNRVRBfCp8dW5kZWZpbmVkfSBUaGUgbWV0YWRhdGEgb2JqZWN0LCB0aGUgdmFsdWUgYXQgdGhlIGtleSBwYXRoLCBvciB1bmRlZmluZWQgaWYgbm90aGluZyBleGlzdHNcbiAgICovXG4gIHN0YXRpYyBnZXQobW9kZWw6IENvbnN0cnVjdG9yLCBrZXk6IHN0cmluZyk6IGFueTtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgbWV0YWRhdGEgZm9yIGEgbW9kZWwgb3IgYSBzcGVjaWZpYyBrZXkgd2l0aGluIGl0XG4gICAqIEBzdW1tYXJ5IFdoZW4gY2FsbGVkIHdpdGggYSBjb25zdHJ1Y3RvciBvbmx5LCByZXR1cm5zIHRoZSBlbnRpcmUgbWV0YWRhdGEgb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGUgbW9kZWwuIFdoZW4gYSBrZXkgcGF0aCBpcyBwcm92aWRlZCwgcmV0dXJucyB0aGUgdmFsdWUgc3RvcmVkIGF0IHRoYXQgbmVzdGVkIGtleS5cbiAgICogQHRlbXBsYXRlIE1cbiAgICogQHRlbXBsYXRlIE1FVEFcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gbW9kZWwgVGhlIHRhcmdldCBjb25zdHJ1Y3RvciB1c2VkIHRvIGxvY2F0ZSB0aGUgbWV0YWRhdGEgcmVjb3JkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBba2V5XSBPcHRpb25hbCBuZXN0ZWQga2V5IHBhdGggdG8gZmV0Y2ggYSBzcGVjaWZpYyB2YWx1ZVxuICAgKiBAcmV0dXJuIHtNRVRBfCp8dW5kZWZpbmVkfSBUaGUgbWV0YWRhdGEgb2JqZWN0LCB0aGUgdmFsdWUgYXQgdGhlIGtleSBwYXRoLCBvciB1bmRlZmluZWQgaWYgbm90aGluZyBleGlzdHNcbiAgICovXG4gIHN0YXRpYyBnZXQobW9kZWw6IENvbnN0cnVjdG9yLCBrZXk/OiBzdHJpbmcpIHtcbiAgICBjb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1vZGVsLnRvU3RyaW5nKCkpO1xuICAgIGlmICghdGhpcy5fbWV0YWRhdGFbc3ltYm9sXSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBpZiAoIWtleSkgcmV0dXJuIHRoaXMuX21ldGFkYXRhW3N5bWJvbF07XG4gICAgcmV0dXJuIGdldFZhbHVlQnlTcGxpdHRlcih0aGlzLl9tZXRhZGF0YVtzeW1ib2xdLCBrZXksIHRoaXMuc3BsaXR0ZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBXcml0ZXMgYSBtZXRhZGF0YSB2YWx1ZSBhdCBhIGdpdmVuIG5lc3RlZCBrZXkgcGF0aFxuICAgKiBAc3VtbWFyeSBFbnN1cmVzIHRoZSBtZXRhZGF0YSByZWNvcmQgZXhpc3RzIGZvciB0aGUgY29uc3RydWN0b3IsIG1pcnJvcnMgaXQgb24gdGhlIGNvbnN0cnVjdG9yIHdoZW4gZW5hYmxlZCwgYW5kIHNldHMgdGhlIHByb3ZpZGVkIHZhbHVlIG9uIHRoZSBuZXN0ZWQga2V5IHBhdGggdXNpbmcgdGhlIGNvbmZpZ3VyZWQgc3BsaXR0ZXIuXG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3J9IG1vZGVsIFRoZSB0YXJnZXQgY29uc3RydWN0b3IgdG8gd2hpY2ggdGhlIG1ldGFkYXRhIGJlbG9uZ3NcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUgbmVzdGVkIGtleSBwYXRoIGF0IHdoaWNoIHRvIHN0b3JlIHRoZSB2YWx1ZVxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzdG9yZSBpbiB0aGUgbWV0YWRhdGFcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHN0YXRpYyBzZXQobW9kZWw6IENvbnN0cnVjdG9yLCBrZXk6IHN0cmluZywgdmFsdWU6IGFueSkge1xuICAgIGNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobW9kZWwudG9TdHJpbmcoKSk7XG4gICAgaWYgKCF0aGlzLl9tZXRhZGF0YVtzeW1ib2xdKSB0aGlzLl9tZXRhZGF0YVtzeW1ib2xdID0ge30gYXMgYW55O1xuICAgIGlmIChcbiAgICAgIE1ldGFkYXRhLm1pcnJvciAmJlxuICAgICAgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2RlbCwgdGhpcy5iYXNlS2V5KVxuICAgICkge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZGVsLCB0aGlzLmJhc2VLZXksIHtcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgdmFsdWU6IHRoaXMuX21ldGFkYXRhW3N5bWJvbF0sXG4gICAgICB9KTtcbiAgICB9XG4gICAgc2V0VmFsdWVCeVNwbGl0dGVyKHRoaXMuX21ldGFkYXRhW3N5bWJvbF0sIGtleSwgdmFsdWUsIHRoaXMuc3BsaXR0ZXIpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBNZXRhZGF0YSB9IGZyb20gXCIuL21ldGFkYXRhL01ldGFkYXRhXCI7XG5pbXBvcnQgeyBEZWNvcmF0aW9uS2V5cywgT2JqZWN0S2V5U3BsaXR0ZXIgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQXNzaWducyBhcmJpdHJhcnkgbWV0YWRhdGEgdG8gYSB0YXJnZXQgdXNpbmcgYSBzdHJpbmcga2V5XG4gKiBAc3VtbWFyeSBEZWNvcmF0b3IgZmFjdG9yeSB0aGF0IHN0b3JlcyBhIGtleS92YWx1ZSBwYWlyIGluIHRoZSBjZW50cmFsIE1ldGFkYXRhIHN0b3JlIGZvciB0aGUgcHJvdmlkZWQgY2xhc3Mgb3IgbWVtYmVyLlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUgbWV0YWRhdGEga2V5IHRvIGFzc29jaWF0ZSB3aXRoIHRoZSB0YXJnZXRcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIG1ldGFkYXRhIHZhbHVlIHRvIHN0b3JlIHVuZGVyIHRoZSBnaXZlbiBrZXlcbiAqIEByZXR1cm4gQSBkZWNvcmF0b3IgdGhhdCB3cml0ZXMgdGhlIG1ldGFkYXRhIHdoZW4gYXBwbGllZFxuICogQGZ1bmN0aW9uIG1ldGFkYXRhXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWV0YWRhdGEoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIG1ldGFkYXRhKFxuICAgIG1vZGVsOiBhbnksXG5cbiAgICBwcm9wPzogYW55LFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBkZXNjcmlwdG9yPzogUHJvcGVydHlEZXNjcmlwdG9yXG4gICkge1xuICAgIE1ldGFkYXRhLnNldChwcm9wID8gbW9kZWwuY29uc3RydWN0b3IgOiBtb2RlbCwga2V5LCB2YWx1ZSk7XG4gIH07XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENhcHR1cmVzIGFuZCBzdG9yZXMgYSBwcm9wZXJ0eSdzIGRlc2lnbiB0eXBlXG4gKiBAc3VtbWFyeSBEZWNvcmF0b3IgZmFjdG9yeSB0aGF0IHJlYWRzIHRoZSByZWZsZWN0ZWQgZGVzaWduOnR5cGUgZm9yIGEgcHJvcGVydHkgYW5kIHJlZ2lzdGVycyBpdCBpbiB0aGUgTWV0YWRhdGEgc3RvcmUgdW5kZXIgdGhlIHByb3BlcnRpZXMgbWFwLlxuICogQHJldHVybiBBIGRlY29yYXRvciB0aGF0IHJlY29yZHMgdGhlIHByb3BlcnR5J3MgdHlwZSBtZXRhZGF0YSB3aGVuIGFwcGxpZWRcbiAqIEBmdW5jdGlvbiBwcm9wXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvcCgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHByb3AobW9kZWw6IG9iamVjdCwgcHJvcDogYW55KSB7XG4gICAgY29uc3QgZGVzaWduVHlwZSA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGEoXG4gICAgICBEZWNvcmF0aW9uS2V5cy5ERVNJR05fVFlQRSxcbiAgICAgIG1vZGVsLFxuICAgICAgcHJvcFxuICAgICk7XG4gICAgcmV0dXJuIG1ldGFkYXRhKGAke0RlY29yYXRpb25LZXlzLlBST1BFUlRJRVN9LiR7cHJvcH1gLCBkZXNpZ25UeXBlKShcbiAgICAgIG1vZGVsLFxuICAgICAgcHJvcFxuICAgICk7XG4gIH07XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlY29yYXRvciBmYWN0b3J5IHRoYXQgYXBwbGllcyBtdWx0aXBsZSBkZWNvcmF0b3JzIHRvIGEgc2luZ2xlIHRhcmdldFxuICogQHN1bW1hcnkgQ3JlYXRlcyBhIGNvbXBvc2l0ZSBkZWNvcmF0b3IgdGhhdCBhcHBsaWVzIG11bHRpcGxlIGRlY29yYXRvcnMgaW4gc2VxdWVuY2UsIGNvcnJlY3RseSBoYW5kbGluZyBjbGFzcywgbWV0aG9kLCBhbmQgcHJvcGVydHkgZGVjb3JhdG9ycy5cbiAqIEBwYXJhbSB7QXJyYXk8Q2xhc3NEZWNvcmF0b3IgfCBNZXRob2REZWNvcmF0b3IgfCBQcm9wZXJ0eURlY29yYXRvcj59IGRlY29yYXRvcnMgLSBBcnJheSBvZiBkZWNvcmF0b3JzIHRvIGFwcGx5XG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBkZWNvcmF0b3IgZnVuY3Rpb24gdGhhdCBhcHBsaWVzIGFsbCBwcm92aWRlZCBkZWNvcmF0b3JzIHRvIHRoZSB0YXJnZXRcbiAqIEBmdW5jdGlvbiBhcHBseVxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBVIGFzIFVzZXIgQ29kZVxuICogICBwYXJ0aWNpcGFudCBBIGFzIGFwcGx5KC4uLmRlY29yYXRvcnMpXG4gKiAgIHBhcnRpY2lwYW50IEQgYXMgRGVjb3JhdG9yXG4gKiAgIFUtPj5BOiBnZXQgZGVjb3JhdG9yKC4uLmRlY29yYXRvcnMpXG4gKiAgIEEtPj5VOiByZXR1cm5zICh0YXJnZXQsIGtleT8sIGRlc2M/KSA9PiB2b2lkXG4gKiAgIFUtPj5BOiBpbnZva2Ugb24gdGFyZ2V0XG4gKiAgIGxvb3AgZm9yIGVhY2ggZGVjb3JhdG9yXG4gKiAgICAgQS0+PkQ6IGludm9rZSBhcHByb3ByaWF0ZSBkZWNvcmF0b3IgdHlwZVxuICogICBlbmRcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseShcbiAgLi4uZGVjb3JhdG9yczogQXJyYXk8Q2xhc3NEZWNvcmF0b3IgfCBNZXRob2REZWNvcmF0b3IgfCBQcm9wZXJ0eURlY29yYXRvcj5cbikge1xuICByZXR1cm4gKFxuICAgIHRhcmdldDogb2JqZWN0LFxuICAgIHByb3BlcnR5S2V5Pzogc3RyaW5nIHwgc3ltYm9sIHwgdW5rbm93bixcbiAgICBkZXNjcmlwdG9yPzogUHJvcGVydHlEZXNjcmlwdG9yXG4gICkgPT4ge1xuICAgIGZvciAoY29uc3QgZGVjb3JhdG9yIG9mIGRlY29yYXRvcnMpIHtcbiAgICAgIGlmICh0YXJnZXQgaW5zdGFuY2VvZiBGdW5jdGlvbiAmJiAhZGVzY3JpcHRvcikge1xuICAgICAgICAoZGVjb3JhdG9yIGFzIENsYXNzRGVjb3JhdG9yKSh0YXJnZXQpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIChkZWNvcmF0b3IgYXMgTWV0aG9kRGVjb3JhdG9yIHwgUHJvcGVydHlEZWNvcmF0b3IpKFxuICAgICAgICB0YXJnZXQsXG4gICAgICAgIHByb3BlcnR5S2V5IGFzIHN0cmluZyB8IHN5bWJvbCxcbiAgICAgICAgZGVzY3JpcHRvciBhcyBUeXBlZFByb3BlcnR5RGVzY3JpcHRvcjx1bmtub3duPlxuICAgICAgKTtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBwcm9wZXJ0eSBtZXRhZGF0YSBkZWNvcmF0b3JcbiAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIGZhY3RvcnkgdGhhdCBjb21iaW5lcyBtZXRhZGF0YShrZXksIHZhbHVlKSBhbmQgcHJvcCgpIHRvIGJvdGggc2V0IGFuIGFyYml0cmFyeSBtZXRhZGF0YSBrZXkgYW5kIHJlY29yZCB0aGUgcHJvcGVydHkncyBkZXNpZ24gdHlwZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIG1ldGFkYXRhIGtleSB0byBzZXQgZm9yIHRoZSBwcm9wZXJ0eVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgbWV0YWRhdGEgdmFsdWUgdG8gYXNzb2NpYXRlIHdpdGggdGhlIGtleVxuICogQHJldHVybiBBIGRlY29yYXRvciB0aGF0IHNldHMgdGhlIG1ldGFkYXRhIGFuZCBjYXB0dXJlcyB0aGUgcHJvcGVydHkncyB0eXBlXG4gKiBAZnVuY3Rpb24gcHJvcE1ldGFkYXRhXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvcE1ldGFkYXRhKGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSB7XG4gIHJldHVybiBhcHBseShtZXRhZGF0YShrZXksIHZhbHVlKSwgcHJvcCgpKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQXR0YWNoZXMgYSBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiB0byBhIGNsYXNzIG9yIG1lbWJlclxuICogQHN1bW1hcnkgRGVjb3JhdG9yIGZhY3RvcnkgdGhhdCBzdG9yZXMgYSB0ZXh0dWFsIGRlc2NyaXB0aW9uIGluIHRoZSBNZXRhZGF0YSBzdG9yZSB1bmRlciB0aGUgYXBwcm9wcmlhdGUgZGVzY3JpcHRpb24ga2V5IGZvciBhIGNsYXNzIG9yIGl0cyBwcm9wZXJ0eS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBkZXNjIFRoZSBkZXNjcmlwdGl2ZSB0ZXh0IHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBjbGFzcyBvciBwcm9wZXJ0eVxuICogQHJldHVybiBBIGRlY29yYXRvciB0aGF0IHJlY29yZHMgdGhlIGRlc2NyaXB0aW9uIHdoZW4gYXBwbGllZFxuICogQGZ1bmN0aW9uIGRlc2NyaXB0aW9uXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZGVzY3JpcHRpb24oZGVzYzogc3RyaW5nKSB7XG4gIHJldHVybiBmdW5jdGlvbiBkZXNjcmlwdGlvbihvcmlnaW5hbDogYW55LCBwcm9wOiBhbnksIGRlc2NyaXB0b3I/OiBhbnkpIHtcbiAgICByZXR1cm4gbWV0YWRhdGEoXG4gICAgICBbXG4gICAgICAgIERlY29yYXRpb25LZXlzLkRFU0NSSVBUSU9OLFxuICAgICAgICBwcm9wID8gcHJvcC50b1N0cmluZygpIDogRGVjb3JhdGlvbktleXMuQ0xBU1MsXG4gICAgICBdLmpvaW4oT2JqZWN0S2V5U3BsaXR0ZXIpLFxuICAgICAgZGVzY1xuICAgICkob3JpZ2luYWwsIHByb3AsIGRlc2NyaXB0b3IpO1xuICB9O1xufVxuIiwiLyoqXG4gKiBAZGVzY3JpcHRpb24gUm9vdCBlbnRyeSBwb2ludCBmb3IgdGhlIGRlY29yYXRpb24gbW9kdWxlXG4gKiBAc3VtbWFyeSBBZ2dyZWdhdGVzIGFuZCByZS1leHBvcnRzIHRoZSBwdWJsaWMgQVBJIG9mIHRoZSBkZWNvcmF0aW9uIGxpYnJhcnksIGluY2x1ZGluZyBjb3JlIGNsYXNzZXMgbGlrZSB7QGxpbmsgRGVjb3JhdGlvbn0sIHV0aWxpdHkgZGVjb3JhdG9ycywgbWV0YWRhdGEgaGVscGVycywgYW5kIGNvbnN0YW50cy4gVGhpcyBtb2R1bGUgaXMgdGhlIHByaW1hcnkgaW1wb3J0IHN1cmZhY2UgZm9yIGNvbnN1bWVycyBhbmQgZXhwb3NlczpcbiAqIC0gQ29yZSBidWlsZGVyOiB7QGxpbmsgRGVjb3JhdGlvbn1cbiAqIC0gRGVjb3JhdG9yIHV0aWxpdGllczoge0BsaW5rIG1vZHVsZTpkZWNvcmF0aW9uIHwgZGVjb3JhdG9ycyBpbiAuL2RlY29yYXRvcnN9XG4gKiAtIE1ldGFkYXRhIHV0aWxpdGllczoge0BsaW5rIE1ldGFkYXRhfVxuICogLSBDb25zdGFudHMgYW5kIGVudW1zOiB7QGxpbmsgRGVjb3JhdGlvbktleXN9LCB7QGxpbmsgRGVmYXVsdEZsYXZvdXJ9XG4gKlxuICogQG1vZHVsZSBkZWNvcmF0aW9uXG4gKi9cblxuZXhwb3J0ICogZnJvbSBcIi4vZGVjb3JhdGlvblwiO1xuZXhwb3J0ICogZnJvbSBcIi4vbWV0YWRhdGFcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnN0YW50c1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDdXJyZW50IHZlcnNpb24gb2YgdGhlIHJlZmxlY3Rpb24gcGFja2FnZVxuICogQHN1bW1hcnkgU3RvcmVzIHRoZSBzZW1hbnRpYyB2ZXJzaW9uIG51bWJlciBvZiB0aGUgcGFja2FnZVxuICogQGNvbnN0IFZFUlNJT05cbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdGlvblxuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbiJdLCJuYW1lcyI6WyJEZWNvcmF0aW9uS2V5cyJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0lBRUE7Ozs7OztJQU1HO0FBQ0ksVUFBTSxjQUFjLEdBQUc7SUFFOUI7Ozs7O0lBS0c7QUFDSSxVQUFNLGlCQUFpQixHQUFHO0lBRWpDOzs7Ozs7Ozs7SUFTRztBQUNTQTtJQUFaLENBQUEsVUFBWSxjQUFjLEVBQUE7O0lBRXhCLElBQUEsY0FBQSxDQUFBLFNBQUEsQ0FBQSxHQUFBLFNBQStCOztJQUUvQixJQUFBLGNBQUEsQ0FBQSxZQUFBLENBQUEsR0FBQSxZQUF5Qjs7SUFFekIsSUFBQSxjQUFBLENBQUEsT0FBQSxDQUFBLEdBQUEsT0FBZTs7SUFFZixJQUFBLGNBQUEsQ0FBQSxhQUFBLENBQUEsR0FBQSxhQUEyQjs7SUFFM0IsSUFBQSxjQUFBLENBQUEsYUFBQSxDQUFBLEdBQUEsYUFBMkI7O0lBRTNCLElBQUEsY0FBQSxDQUFBLGVBQUEsQ0FBQSxHQUFBLG1CQUFtQzs7SUFFbkMsSUFBQSxjQUFBLENBQUEsZUFBQSxDQUFBLEdBQUEsbUJBQW1DO0lBQ3JDLENBQUMsRUFmV0Esc0JBQWMsS0FBZEEsc0JBQWMsR0FlekIsRUFBQSxDQUFBLENBQUE7SUFFRDs7Ozs7OztJQU9HO0lBRUg7Ozs7OztJQU1HO0FBQ1UsVUFBQSxlQUFlLEdBQXVCO0lBQ2pELElBQUEsQ0FBQ0Esc0JBQWMsQ0FBQyxVQUFVLEdBQUcsRUFBRTs7O0lDckRqQzs7Ozs7OztJQU9HO0lBQ0g7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
670
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVjb3JhdGlvbi5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvbWV0YWRhdGEvTWV0YWRhdGEudHMiLCIuLi9zcmMvZGVjb3JhdGlvbi9EZWNvcmF0aW9uLnRzIiwiLi4vc3JjL2RlY29yYXRvcnMudHMiLCIuLi9zcmMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQmFzaWNNZXRhZGF0YSB9IGZyb20gXCIuL21ldGFkYXRhL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmF1bHQgZmxhdm91ciBpZGVudGlmaWVyIGZvciB0aGUgZGVjb3JhdG9yIHN5c3RlbVxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgZGVmYXVsdCBmbGF2b3VyIHVzZWQgYnkgdGhlIERlY29yYXRpb24gY2xhc3Mgd2hlbiBubyBzcGVjaWZpYyBmbGF2b3VyIGlzIHByb3ZpZGVkLlxuICogVGhpcyBjb25zdGFudCBpcyB1c2VkIHRocm91Z2hvdXQgdGhlIGxpYnJhcnkgYXMgdGhlIGZhbGxiYWNrIGZsYXZvdXIgZm9yIGRlY29yYXRvcnMuXG4gKiBAY29uc3QgRGVmYXVsdEZsYXZvdXJcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdGlvblxuICovXG5leHBvcnQgY29uc3QgRGVmYXVsdEZsYXZvdXIgPSBcImRlY2FmXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENoYXJhY3RlciB1c2VkIHRvIHNwbGl0IG5lc3RlZCBtZXRhZGF0YSBrZXlzXG4gKiBAc3VtbWFyeSBUaGUgZGVsaW1pdGVyIHVzZWQgYnkgdGhlIG1ldGFkYXRhIHN0b3JlIHRvIHRyYXZlcnNlIG5lc3RlZCBvYmplY3QgcGF0aHMgd2hlbiByZWFkaW5nL3dyaXRpbmcgdmFsdWVzLlxuICogQGNvbnN0IE9iamVjdEtleVNwbGl0dGVyXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRpb25cbiAqL1xuZXhwb3J0IGNvbnN0IE9iamVjdEtleVNwbGl0dGVyID0gXCIuXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVudW0gY29udGFpbmluZyBtZXRhZGF0YSBrZXlzIHVzZWQgZm9yIHJlZmxlY3Rpb24gaW4gdGhlIG1vZGVsIHN5c3RlbVxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgdmFyaW91cyBNb2RlbCBrZXlzIHVzZWQgZm9yIHJlZmxlY3Rpb24gYW5kIG1ldGFkYXRhIHN0b3JhZ2UuXG4gKiBUaGVzZSBrZXlzIGFyZSB1c2VkIHRocm91Z2hvdXQgdGhlIGxpYnJhcnkgdG8gc3RvcmUgYW5kIHJldHJpZXZlIG1ldGFkYXRhIGFib3V0IG1vZGVscyxcbiAqIHRoZWlyIHByb3BlcnRpZXMsIGFuZCB0aGVpciBiZWhhdmlvci5cbiAqIEByZWFkb25seVxuICogQGVudW0ge3N0cmluZ31cbiAqIEByZWFkb25seVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0aW9uXG4gKi9cbmV4cG9ydCBlbnVtIERlY29yYXRpb25LZXlzIHtcbiAgTElCUkFSSUVTID0gXCJsaWJyYXJpZXNcIixcbiAgLyoqIFN0b3JhZ2Uga2V5IHVzZWQgb24gdGhlIGNvbnN0cnVjdG9yIHRvIG1pcnJvciBydW50aW1lIG1ldGFkYXRhICovXG4gIFJFRkxFQ1QgPSBgX18ke0RlZmF1bHRGbGF2b3VyfWAsXG4gIC8qKiBNYXAgb2YgbW9kZWwgcHJvcGVydHkga2V5cyB0byB0aGVpciByZWZsZWN0ZWQgZGVzaWduIHR5cGVzICovXG4gIFBST1BFUlRJRVMgPSBcInByb3BlcnRpZXNcIixcbiAgLyoqIE1hcCBvZiBtb2RlbCBtZXRob2Qga2V5cyB0byB0aGVpciByZWZsZWN0ZWQgZGVzaWduIHBhcmFtcyBhbmQgcmV0dXJuIHR5cGVzICovXG4gIE1FVEhPRFMgPSBcIm1ldGhvZHNcIixcbiAgLyoqIEtleSB1bmRlciB3aGljaCB0aGUgbW9kZWwncyBjb25zdHJ1Y3RvciBpcyBzdG9yZWQgKi9cbiAgQ0xBU1MgPSBcImNsYXNzXCIsXG4gIC8qKiBDb250YWluZXIgb2YgaHVtYW4tZnJpZW5kbHkgZGVzY3JpcHRpb25zIHBlciBjbGFzcyBhbmQgcHJvcGVydHkgKi9cbiAgREVTQ1JJUFRJT04gPSBcImRlc2NyaXB0aW9uXCIsXG4gIC8qKiBSZWZsZWN0IG1ldGFkYXRhIGtleSBmb3IgZGVzaWduIHRpbWUgdHlwZSBvZiBhIHByb3BlcnR5ICovXG4gIERFU0lHTl9UWVBFID0gXCJkZXNpZ246dHlwZVwiLFxuICAvKiogUmVmbGVjdCBtZXRhZGF0YSBrZXkgZm9yIGNvbnN0cnVjdG9yIHBhcmFtZXRlciB0eXBlcyAqL1xuICBERVNJR05fUEFSQU1TID0gXCJkZXNpZ246cGFyYW10eXBlc1wiLFxuICAvKiogUmVmbGVjdCBtZXRhZGF0YSBrZXkgZm9yIG1ldGhvZCByZXR1cm4gdHlwZSAqL1xuICBERVNJR05fUkVUVVJOID0gXCJkZXNpZ246cmV0dXJudHlwZVwiLFxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBUeXBlZGVmIGZvciB0aGUgZGVmYXVsdCBtZXRhZGF0YSBvYmplY3Qgc2hhcGVcbiAqIEBzdW1tYXJ5IERlc2NyaWJlcyB0aGUgbWluaW1hbCBzdHJ1Y3R1cmUgcGVyc2lzdGVkIGZvciBhIG1vZGVsIGJlZm9yZSBhbnkgbWV0YWRhdGEgaXMgcmVjb3JkZWQuXG4gKiBAdGVtcGxhdGUgTVxuICogQHR5cGVkZWYge29iamVjdH0gRGVmYXVsdE1ldGFkYXRhVHlwZTxNPlxuICogQHByb3BlcnR5IHtSZWNvcmQ8c3RyaW5nLCBDb25zdHJ1Y3RvciB8IHVuZGVmaW5lZD59IHByb3BlcnRpZXMgLSBNYXBwaW5nIG9mIHByb3BlcnR5IG5hbWVzIHRvIHRoZWlyIGRlc2lnbiB0eXBlc1xuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0aW9uXG4gKi9cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVmYXVsdCBtZXRhZGF0YSBpbnN0YW5jZVxuICogQHN1bW1hcnkgQ29uY3JldGUgZGVmYXVsdCBtZXRhZGF0YSBvYmplY3QgdXNlZCB3aGVuIGluaXRpYWxpemluZyBtZXRhZGF0YSBmb3IgYSBtb2RlbFxuICogQHR5cGUge0RlZmF1bHRNZXRhZGF0YVR5cGU8YW55Pn1cbiAqIEBjb25zdCBEZWZhdWx0TWV0YWRhdGFcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdGlvblxuICovXG5leHBvcnQgY29uc3QgRGVmYXVsdE1ldGFkYXRhOiBCYXNpY01ldGFkYXRhPGFueT4gPSB7XG4gIFtEZWNvcmF0aW9uS2V5cy5QUk9QRVJUSUVTXTogW10sXG59IGFzIHVua25vd24gYXMgQmFzaWNNZXRhZGF0YTxhbnk+O1xuIiwiaW1wb3J0IHsgQmFzaWNNZXRhZGF0YSwgQ29uc3RydWN0b3IgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgRGVjb3JhdGlvbktleXMsIE9iamVjdEtleVNwbGl0dGVyIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IFwicmVmbGVjdC1tZXRhZGF0YVwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYSBuZXN0ZWQgdmFsdWUgZnJvbSBhbiBvYmplY3QgZ2l2ZW4gYSBwYXRoXG4gKiBAc3VtbWFyeSBXYWxrcyBhbiBvYmplY3Qgc3RydWN0dXJlIHVzaW5nIGEgc3BsaXR0ZXItZGVsaW1pdGVkIHBhdGggYW5kIHJldHVybnMgdGhlIHZhbHVlIGF0IHRoYXQgbG9jYXRpb24gb3IgdW5kZWZpbmVkIGlmIGFueSBrZXkgaXMgbWlzc2luZy5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gb2JqIFRoZSBvYmplY3QgdG8gdHJhdmVyc2VcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIFRoZSBwYXRoIHRvIHRoZSBkZXNpcmVkIHZhbHVlIChlLmcuLCBcImEuYi5jXCIpXG4gKiBAcGFyYW0ge3N0cmluZ30gW3NwbGl0dGVyPU9iamVjdEtleVNwbGl0dGVyXSBUaGUgZGVsaW1pdGVyIHVzZWQgdG8gc3BsaXQgdGhlIHBhdGhcbiAqIEByZXR1cm4geyp9IFRoZSByZXNvbHZlZCB2YWx1ZSBhdCB0aGUgZ2l2ZW4gcGF0aCBvciB1bmRlZmluZWQgaWYgbm90IGZvdW5kXG4gKiBAZnVuY3Rpb24gZ2V0VmFsdWVCeVNwbGl0dGVyXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IEYgYXMgZ2V0VmFsdWVCeVNwbGl0dGVyXG4gKiAgIHBhcnRpY2lwYW50IE8gYXMgT2JqZWN0XG4gKiAgIEMtPj5GOiAob2JqLCBwYXRoLCBzcGxpdHRlcilcbiAqICAgRi0+PkY6IHNwbGl0IHBhdGggaW50byBrZXlzXG4gKiAgIGxvb3AgZm9yIGVhY2gga2V5XG4gKiAgICAgRi0+Pk86IGFjY2VzcyBjdXJyZW50W2tleV1cbiAqICAgICBhbHQgbWlzc2luZyBvciBudWxsaXNoXG4gKiAgICAgICBGLS0+PkM6IHJldHVybiB1bmRlZmluZWRcbiAqICAgICBlbmRcbiAqICAgZW5kXG4gKiAgIEYtLT4+QzogcmV0dXJuIGZpbmFsIHZhbHVlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFZhbHVlQnlTcGxpdHRlcihcbiAgb2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICBwYXRoOiBzdHJpbmcsXG4gIHNwbGl0dGVyOiBzdHJpbmcgPSBPYmplY3RLZXlTcGxpdHRlclxuKTogYW55IHtcbiAgY29uc3Qga2V5cyA9IHBhdGguc3BsaXQoc3BsaXR0ZXIpO1xuICBsZXQgY3VycmVudCA9IG9iajtcblxuICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgaWYgKFxuICAgICAgY3VycmVudCA9PT0gbnVsbCB8fFxuICAgICAgY3VycmVudCA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGN1cnJlbnQsIGtleSlcbiAgICApXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGN1cnJlbnQgPSBjdXJyZW50W2tleV07XG4gIH1cblxuICByZXR1cm4gY3VycmVudDtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gU2V0cyBhIG5lc3RlZCB2YWx1ZSBvbiBhbiBvYmplY3QgZ2l2ZW4gYSBwYXRoXG4gKiBAc3VtbWFyeSBUcmF2ZXJzZXMgb3IgY3JlYXRlcyBpbnRlcm1lZGlhdGUgb2JqZWN0cyBmb2xsb3dpbmcgYSBzcGxpdHRlci1kZWxpbWl0ZWQgcGF0aCBhbmQgYXNzaWducyB0aGUgcHJvdmlkZWQgdmFsdWUgYXQgdGhlIGRlc3RpbmF0aW9uIGtleS5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gb2JqIFRoZSBvYmplY3QgdG8gbXV0YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgZGVzdGluYXRpb24gcGF0aCAoZS5nLiwgXCJhLmIuY1wiKVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0IGF0IHRoZSBkZXN0aW5hdGlvblxuICogQHBhcmFtIHtzdHJpbmd9IFtzcGxpdHRlcj1PYmplY3RLZXlTcGxpdHRlcl0gVGhlIGRlbGltaXRlciB1c2VkIHRvIHNwbGl0IHRoZSBwYXRoXG4gKiBAcmV0dXJuIHt2b2lkfVxuICogQGZ1bmN0aW9uIHNldFZhbHVlQnlTcGxpdHRlclxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENhbGxlclxuICogICBwYXJ0aWNpcGFudCBGIGFzIHNldFZhbHVlQnlTcGxpdHRlclxuICogICBwYXJ0aWNpcGFudCBPIGFzIE9iamVjdFxuICogICBDLT4+RjogKG9iaiwgcGF0aCwgdmFsdWUsIHNwbGl0dGVyKVxuICogICBGLT4+Rjogc3BsaXQgcGF0aCBpbnRvIGtleXNcbiAqICAgbG9vcCBmb3IgZWFjaCBrZXlcbiAqICAgICBhbHQga2V5IG1pc3NpbmdcbiAqICAgICAgIEYtPj5POiBjcmVhdGUgaW50ZXJtZWRpYXRlIG9iamVjdFxuICogICAgIGVsc2Uga2V5IGV4aXN0c1xuICogICAgICAgRi0+Pk86IGRlc2NlbmQgaW50byBleGlzdGluZyBvYmplY3RcbiAqICAgICBlbmRcbiAqICAgZW5kXG4gKiAgIEYtLT4+Qzogdm9pZFxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRWYWx1ZUJ5U3BsaXR0ZXIoXG4gIG9iajogUmVjb3JkPHN0cmluZywgYW55PixcbiAgcGF0aDogc3RyaW5nLFxuICB2YWx1ZTogYW55LFxuICBzcGxpdHRlciA9IE9iamVjdEtleVNwbGl0dGVyXG4pOiB2b2lkIHtcbiAgY29uc3Qga2V5cyA9IHBhdGguc3BsaXQoc3BsaXR0ZXIpLmZpbHRlcigoaykgPT4gay5sZW5ndGggPiAwKTtcbiAgaWYgKGtleXMubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgbGV0IGN1cnJlbnQ6IFJlY29yZDxhbnksIGFueT4gPSBvYmo7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgIGNvbnN0IGtleSA9IGtleXNbaV07XG4gICAgaWYgKFxuICAgICAgY3VycmVudFtrZXldID09PSB1bmRlZmluZWQgfHxcbiAgICAgIGN1cnJlbnRba2V5XSA9PT0gbnVsbCB8fFxuICAgICAgdHlwZW9mIGN1cnJlbnRba2V5XSAhPT0gXCJvYmplY3RcIlxuICAgICkge1xuICAgICAgY3VycmVudFtrZXldID0ge307XG4gICAgfVxuICAgIGN1cnJlbnQgPSBjdXJyZW50W2tleV07XG4gIH1cblxuICBjb25zdCBsYXN0S2V5ID0ga2V5c1trZXlzLmxlbmd0aCAtIDFdO1xuICBjdXJyZW50W2xhc3RLZXldID0gdmFsdWU7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENlbnRyYWxpemVkIHJ1bnRpbWUgbWV0YWRhdGEgc3RvcmUgYm91bmQgdG8gY29uc3RydWN0b3JzXG4gKiBAc3VtbWFyeSBQcm92aWRlcyB1dGlsaXRpZXMgdG8gcmVhZCBhbmQgd3JpdGUgc3RydWN0dXJlZCBtZXRhZGF0YSBmb3IgY2xhc3NlcyBhbmQgdGhlaXIgbWVtYmVycywgd2l0aCBvcHRpb25hbCBtaXJyb3Jpbmcgb250byB0aGUgY29uc3RydWN0b3IgdmlhIGEgd2VsbC1rbm93biBzeW1ib2wga2V5LiBTdXBwb3J0cyBuZXN0ZWQga2V5IHBhdGhzIHVzaW5nIGEgY29uZmlndXJhYmxlIHNwbGl0dGVyIGFuZCBvZmZlcnMgYm90aCBpbnN0YW5jZSBhbmQgc3RhdGljIEFQSXMuXG4gKiBAdGVtcGxhdGUgTSBUaGUgbW9kZWwgdHlwZSB0aGUgbWV0YWRhdGEgYmVsb25ncyB0b1xuICogQHRlbXBsYXRlIE1FVEEgRXh0ZW5kcyBCYXNpY01ldGFkYXRhPE0+IHJlcHJlc2VudGluZyB0aGUgbWV0YWRhdGEgc3RydWN0dXJlXG4gKiBAY2xhc3NcbiAqIEBleGFtcGxlXG4gKiAvLyBEZWZpbmUgYW5kIHJlYWQgbWV0YWRhdGEgZm9yIGEgY2xhc3NcbiAqIGNsYXNzIFVzZXIgeyBuYW1lITogc3RyaW5nIH1cbiAqIE1ldGFkYXRhLnNldChVc2VyLCBcImRlc2NyaXB0aW9uLmNsYXNzXCIsIFwiQSB1c2VyIG1vZGVsXCIpO1xuICogTWV0YWRhdGEuc2V0KFVzZXIsIFwicHJvcGVydGllcy5uYW1lXCIsIFN0cmluZyk7XG4gKiBjb25zdCBkZXNjID0gTWV0YWRhdGEuZ2V0KFVzZXIsIFwiZGVzY3JpcHRpb24uY2xhc3NcIik7IC8vIFwiQSB1c2VyIG1vZGVsXCJcbiAqIGNvbnN0IHR5cGUgPSBNZXRhZGF0YS50eXBlKFVzZXIsIFwibmFtZVwiKTsgLy8gU3RyaW5nXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ29uc3RydWN0b3JcbiAqICAgcGFydGljaXBhbnQgUyBhcyBNZXRhZGF0YSAoc3RhdGljKVxuICogICBDLT4+Uzogc2V0KFVzZXIsIFwicHJvcGVydGllcy5uYW1lXCIsIFN0cmluZylcbiAqICAgQy0+PlM6IGdldChVc2VyLCBcInByb3BlcnRpZXMubmFtZVwiKVxuICogICBTLS0+PkM6IFN0cmluZ1xuICovXG5leHBvcnQgY2xhc3MgTWV0YWRhdGEge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEluLW1lbW9yeSBzdG9yYWdlIG9mIG1ldGFkYXRhIGJ5IGNvbnN0cnVjdG9yIHN5bWJvbFxuICAgKiBAc3VtbWFyeSBNYXBzIGEgU3ltYm9sIGRlcml2ZWQgZnJvbSB0aGUgY29uc3RydWN0b3IgdG8gaXRzIG1ldGFkYXRhIG9iamVjdCwgZW5hYmxpbmcgZWZmaWNpZW50IGxvb2t1cC5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIF9tZXRhZGF0YTogUmVjb3JkPHN5bWJvbCwgYW55PiA9IHt9O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUGF0aCBkZWxpbWl0ZXIgZm9yIG5lc3RlZCBtZXRhZGF0YSBrZXlzXG4gICAqIEBzdW1tYXJ5IFVzZWQgYnkgZ2V0L3NldCBvcGVyYXRpb25zIHRvIG5hdmlnYXRlIG5lc3RlZCBzdHJ1Y3R1cmVzLCBkZWZhdWx0cyB0byBPYmplY3RLZXlTcGxpdHRlci5cbiAgICovXG4gIHN0YXRpYyBzcGxpdHRlciA9IE9iamVjdEtleVNwbGl0dGVyO1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFN5bWJvbCBrZXkgdXNlZCB0byBtaXJyb3IgbWV0YWRhdGEgb24gdGhlIGNvbnN0cnVjdG9yXG4gICAqIEBzdW1tYXJ5IFdoZW4gbWlycm9yaW5nIGlzIGVuYWJsZWQsIHRoZSBtZXRhZGF0YSBvYmplY3QgaXMgZGVmaW5lZCBvbiB0aGUgY29uc3RydWN0b3IgdW5kZXIgdGhpcyBub24tZW51bWVyYWJsZSBrZXkuXG4gICAqL1xuICBzdGF0aWMgYmFzZUtleSA9IERlY29yYXRpb25LZXlzLlJFRkxFQ1Q7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ29udHJvbHMgd2hldGhlciBtZXRhZGF0YSBpcyBtaXJyb3JlZCBvbnRvIHRoZSBjb25zdHJ1Y3RvclxuICAgKiBAc3VtbWFyeSBXaGVuIHRydWUsIHRoZSBtZXRhZGF0YSBvYmplY3QgaXMgZGVmaW5lZCBvbiB0aGUgY29uc3RydWN0b3IgdW5kZXIgdGhlIG5vbi1lbnVtZXJhYmxlIGJhc2VLZXkuXG4gICAqL1xuICBzdGF0aWMgbWlycm9yOiBib29sZWFuID0gdHJ1ZTtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExpc3RzIGtub3duIHByb3BlcnR5IGtleXMgZm9yIGEgbW9kZWxcbiAgICogQHN1bW1hcnkgUmVhZHMgdGhlIG1ldGFkYXRhIGVudHJ5IGFuZCByZXR1cm5zIHRoZSBuYW1lcyBvZiBwcm9wZXJ0aWVzIHRoYXQgaGF2ZSByZWNvcmRlZCB0eXBlIGluZm9ybWF0aW9uLlxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yfSBtb2RlbCBUaGUgdGFyZ2V0IGNvbnN0cnVjdG9yXG4gICAqIEByZXR1cm4ge3N0cmluZ1tdfHVuZGVmaW5lZH0gQXJyYXkgb2YgcHJvcGVydHkgbmFtZXMgb3IgdW5kZWZpbmVkIGlmIG5vIG1ldGFkYXRhIGV4aXN0c1xuICAgKi9cbiAgc3RhdGljIHByb3BlcnRpZXMobW9kZWw6IENvbnN0cnVjdG9yKTogc3RyaW5nW10gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLmdldChtb2RlbCk7XG4gICAgaWYgKCFtZXRhKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhtZXRhLnByb3BlcnRpZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYSBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBmb3IgYSBjbGFzcyBvciBhIHByb3BlcnR5XG4gICAqIEBzdW1tYXJ5IExvb2tzIHVwIHRoZSBkZXNjcmlwdGlvbiBzdG9yZWQgdW5kZXIgdGhlIG1ldGFkYXRhIFwiZGVzY3JpcHRpb25cIiBtYXAuIElmIGEgcHJvcGVydHkga2V5IGlzIHByb3ZpZGVkLCByZXR1cm5zIHRoZSBwcm9wZXJ0eSdzIGRlc2NyaXB0aW9uOyBvdGhlcndpc2UgcmV0dXJucyB0aGUgY2xhc3MgZGVzY3JpcHRpb24uXG4gICAqIEB0ZW1wbGF0ZSBNXG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3I8TT59IG1vZGVsIFRoZSB0YXJnZXQgY29uc3RydWN0b3Igd2hvc2UgZGVzY3JpcHRpb24gaXMgYmVpbmcgcmV0cmlldmVkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcHJvcF0gT3B0aW9uYWwgcHJvcGVydHkga2V5IGZvciB3aGljaCB0byBmZXRjaCB0aGUgZGVzY3JpcHRpb25cbiAgICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH0gVGhlIGRlc2NyaXB0aW9uIHRleHQgaWYgcHJlc2VudCwgb3RoZXJ3aXNlIHVuZGVmaW5lZFxuICAgKi9cbiAgc3RhdGljIGRlc2NyaXB0aW9uPE0+KFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPixcbiAgICBwcm9wPzoga2V5b2YgTVxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmdldChcbiAgICAgIG1vZGVsLFxuICAgICAgW0RlY29yYXRpb25LZXlzLkRFU0NSSVBUSU9OLCBwcm9wID8gcHJvcCA6IERlY29yYXRpb25LZXlzLkNMQVNTXS5qb2luKFxuICAgICAgICBPYmplY3RLZXlTcGxpdHRlclxuICAgICAgKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyB0aGUgcmVjb3JkZWQgZGVzaWduIHR5cGUgZm9yIGEgcHJvcGVydHlcbiAgICogQHN1bW1hcnkgUmVhZHMgdGhlIG1ldGFkYXRhIGVudHJ5IHVuZGVyIFwicHJvcGVydGllcy48cHJvcD5cIiB0byByZXR1cm4gdGhlIGNvbnN0cnVjdG9yIHJlY29yZGVkIGZvciB0aGUgZ2l2ZW4gcHJvcGVydHkgbmFtZS5cbiAgICogQHBhcmFtIHtDb25zdHJ1Y3Rvcn0gbW9kZWwgVGhlIHRhcmdldCBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge3N0cmluZ30gcHJvcCBUaGUgcHJvcGVydHkgbmFtZSB3aG9zZSB0eXBlIHNob3VsZCBiZSByZXR1cm5lZFxuICAgKiBAcmV0dXJuIHtDb25zdHJ1Y3Rvcnx1bmRlZmluZWR9IFRoZSBjb25zdHJ1Y3RvciByZWZlcmVuY2Ugb2YgdGhlIHByb3BlcnR5IHR5cGUgb3IgdW5kZWZpbmVkIGlmIG5vdCBhdmFpbGFibGVcbiAgICovXG4gIHN0YXRpYyB0eXBlKG1vZGVsOiBDb25zdHJ1Y3RvciwgcHJvcDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KG1vZGVsLCBgJHtEZWNvcmF0aW9uS2V5cy5QUk9QRVJUSUVTfS4ke3Byb3B9YCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBtZXRhZGF0YSBmb3IgYSBtb2RlbCBvciBhIHNwZWNpZmljIGtleSB3aXRoaW4gaXRcbiAgICogQHN1bW1hcnkgV2hlbiBjYWxsZWQgd2l0aCBhIGNvbnN0cnVjdG9yIG9ubHksIHJldHVybnMgdGhlIGVudGlyZSBtZXRhZGF0YSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBtb2RlbC4gV2hlbiBhIGtleSBwYXRoIGlzIHByb3ZpZGVkLCByZXR1cm5zIHRoZSB2YWx1ZSBzdG9yZWQgYXQgdGhhdCBuZXN0ZWQga2V5LlxuICAgKiBAdGVtcGxhdGUgTVxuICAgKiBAdGVtcGxhdGUgTUVUQVxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBtb2RlbCBUaGUgdGFyZ2V0IGNvbnN0cnVjdG9yIHVzZWQgdG8gbG9jYXRlIHRoZSBtZXRhZGF0YSByZWNvcmRcbiAgICogQHJldHVybiB7TUVUQXx1bmRlZmluZWR9IFRoZSBtZXRhZGF0YSBvYmplY3QsIHRoZSB2YWx1ZSBhdCB0aGUga2V5IHBhdGgsIG9yIHVuZGVmaW5lZCBpZiBub3RoaW5nIGV4aXN0c1xuICAgKi9cbiAgc3RhdGljIGdldDxNLCBNRVRBIGV4dGVuZHMgQmFzaWNNZXRhZGF0YTxNPiA9IEJhc2ljTWV0YWRhdGE8TT4+KFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPlxuICApOiBNRVRBIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBtZXRhZGF0YSBmb3IgYSBtb2RlbCBvciBhIHNwZWNpZmljIGtleSB3aXRoaW4gaXRcbiAgICogQHN1bW1hcnkgV2hlbiBjYWxsZWQgd2l0aCBhIGNvbnN0cnVjdG9yIG9ubHksIHJldHVybnMgdGhlIGVudGlyZSBtZXRhZGF0YSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBtb2RlbC4gV2hlbiBhIGtleSBwYXRoIGlzIHByb3ZpZGVkLCByZXR1cm5zIHRoZSB2YWx1ZSBzdG9yZWQgYXQgdGhhdCBuZXN0ZWQga2V5LlxuICAgKiBAdGVtcGxhdGUgTVxuICAgKiBAdGVtcGxhdGUgTUVUQVxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBtb2RlbCBUaGUgdGFyZ2V0IGNvbnN0cnVjdG9yIHVzZWQgdG8gbG9jYXRlIHRoZSBtZXRhZGF0YSByZWNvcmRcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBuZXN0ZWQga2V5IHBhdGggdG8gZmV0Y2ggYSBzcGVjaWZpYyB2YWx1ZVxuICAgKiBAcmV0dXJuIHtNRVRBfCp8dW5kZWZpbmVkfSBUaGUgbWV0YWRhdGEgb2JqZWN0LCB0aGUgdmFsdWUgYXQgdGhlIGtleSBwYXRoLCBvciB1bmRlZmluZWQgaWYgbm90aGluZyBleGlzdHNcbiAgICovXG4gIHN0YXRpYyBnZXQobW9kZWw6IENvbnN0cnVjdG9yLCBrZXk6IHN0cmluZyk6IGFueTtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgbWV0YWRhdGEgZm9yIGEgbW9kZWwgb3IgYSBzcGVjaWZpYyBrZXkgd2l0aGluIGl0XG4gICAqIEBzdW1tYXJ5IFdoZW4gY2FsbGVkIHdpdGggYSBjb25zdHJ1Y3RvciBvbmx5LCByZXR1cm5zIHRoZSBlbnRpcmUgbWV0YWRhdGEgb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGUgbW9kZWwuIFdoZW4gYSBrZXkgcGF0aCBpcyBwcm92aWRlZCwgcmV0dXJucyB0aGUgdmFsdWUgc3RvcmVkIGF0IHRoYXQgbmVzdGVkIGtleS5cbiAgICogQHRlbXBsYXRlIE1cbiAgICogQHRlbXBsYXRlIE1FVEFcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPiB8IHN0cmluZ30gbW9kZWwgVGhlIHRhcmdldCBjb25zdHJ1Y3RvciB1c2VkIHRvIGxvY2F0ZSB0aGUgbWV0YWRhdGEgcmVjb3JkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBba2V5XSBPcHRpb25hbCBuZXN0ZWQga2V5IHBhdGggdG8gZmV0Y2ggYSBzcGVjaWZpYyB2YWx1ZVxuICAgKiBAcmV0dXJuIHtNRVRBfCp8dW5kZWZpbmVkfSBUaGUgbWV0YWRhdGEgb2JqZWN0LCB0aGUgdmFsdWUgYXQgdGhlIGtleSBwYXRoLCBvciB1bmRlZmluZWQgaWYgbm90aGluZyBleGlzdHNcbiAgICovXG4gIHN0YXRpYyBnZXQobW9kZWw6IENvbnN0cnVjdG9yLCBrZXk/OiBzdHJpbmcpIHtcbiAgICBjb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1vZGVsLnRvU3RyaW5nKCkpO1xuICAgIHJldHVybiB0aGlzLmlubmVyR2V0KHN5bWJvbCwga2V5KTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGlubmVyR2V0KHN5bWJvbDogc3ltYm9sLCBrZXk/OiBzdHJpbmcpIHtcbiAgICBpZiAoIXRoaXMuX21ldGFkYXRhW3N5bWJvbF0pIHJldHVybiB1bmRlZmluZWQ7XG4gICAgaWYgKCFrZXkpIHJldHVybiB0aGlzLl9tZXRhZGF0YVtzeW1ib2xdO1xuICAgIHJldHVybiBnZXRWYWx1ZUJ5U3BsaXR0ZXIodGhpcy5fbWV0YWRhdGFbc3ltYm9sXSwga2V5LCB0aGlzLnNwbGl0dGVyKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGlubmVyU2V0KHN5bWJvbDogc3ltYm9sLCBrZXk6IHN0cmluZywgdmFsdWU6IGFueSkge1xuICAgIGlmICghdGhpcy5fbWV0YWRhdGFbc3ltYm9sXSkgdGhpcy5fbWV0YWRhdGFbc3ltYm9sXSA9IHt9IGFzIGFueTtcbiAgICBzZXRWYWx1ZUJ5U3BsaXR0ZXIodGhpcy5fbWV0YWRhdGFbc3ltYm9sXSwga2V5LCB2YWx1ZSwgdGhpcy5zcGxpdHRlcik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFdyaXRlcyBhIG1ldGFkYXRhIHZhbHVlIGF0IGEgZ2l2ZW4gbmVzdGVkIGtleSBwYXRoXG4gICAqIEBzdW1tYXJ5IEVuc3VyZXMgdGhlIG1ldGFkYXRhIHJlY29yZCBleGlzdHMgZm9yIHRoZSBjb25zdHJ1Y3RvciwgbWlycm9ycyBpdCBvbiB0aGUgY29uc3RydWN0b3Igd2hlbiBlbmFibGVkLCBhbmQgc2V0cyB0aGUgcHJvdmlkZWQgdmFsdWUgb24gdGhlIG5lc3RlZCBrZXkgcGF0aCB1c2luZyB0aGUgY29uZmlndXJlZCBzcGxpdHRlci5cbiAgICogQHRlbXBsYXRlIE1cbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPiB8IHN0cmluZ30gbW9kZWwgVGhlIHRhcmdldCBjb25zdHJ1Y3RvciB0byB3aGljaCB0aGUgbWV0YWRhdGEgYmVsb25nc1xuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBuZXN0ZWQga2V5IHBhdGggYXQgd2hpY2ggdG8gc3RvcmUgdGhlIHZhbHVlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHN0b3JlIGluIHRoZSBtZXRhZGF0YVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc3RhdGljIHNldChtb2RlbDogQ29uc3RydWN0b3IgfCBzdHJpbmcsIGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSB7XG4gICAgY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtb2RlbC50b1N0cmluZygpKTtcbiAgICB0aGlzLmlubmVyU2V0KHN5bWJvbCwga2V5LCB2YWx1ZSk7XG4gICAgaWYgKFxuICAgICAgTWV0YWRhdGEubWlycm9yICYmXG4gICAgICAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZGVsLCB0aGlzLmJhc2VLZXkpXG4gICAgKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kZWwsIHRoaXMuYmFzZUtleSwge1xuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICB2YWx1ZTogdGhpcy5fbWV0YWRhdGFbc3ltYm9sXSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyByZWdpc3RlckxpYnJhcnkobGlicmFyeTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcpIHtcbiAgICBjb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKERlY29yYXRpb25LZXlzLkxJQlJBUklFUyk7XG4gICAgY29uc3QgbGliID0gdGhpcy5pbm5lckdldChzeW1ib2wsIGxpYnJhcnkpO1xuICAgIGlmIChsaWIpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBMaWJyYXJ5IGFscmVhZHkgJHtsaWJyYXJ5fSByZWdpc3RlcmVkIHdpdGggdmVyc2lvbiAke3ZlcnNpb259YFxuICAgICAgKTtcbiAgICB0aGlzLmlubmVyU2V0KHN5bWJvbCwgbGlicmFyeSwgdmVyc2lvbik7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIERlY29yYXRpb25CdWlsZGVyQnVpbGQsXG4gIERlY29yYXRpb25CdWlsZGVyRW5kLFxuICBEZWNvcmF0aW9uQnVpbGRlck1pZCxcbiAgRGVjb3JhdGlvbkJ1aWxkZXJTdGFydCxcbiAgRmxhdm91clJlc29sdmVyLFxuICBJRGVjb3JhdGlvbkJ1aWxkZXIsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBEZWZhdWx0Rmxhdm91ciB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVmYXVsdCByZXNvbHZlciB0aGF0IHJldHVybnMgdGhlIGN1cnJlbnQgZGVmYXVsdCBmbGF2b3VyXG4gKiBAc3VtbWFyeSBSZXNvbHZlcyB0aGUgZmxhdm91ciBmb3IgYSBnaXZlbiB0YXJnZXQgYnkgYWx3YXlzIHJldHVybmluZyB0aGUgbGlicmFyeSdzIERlZmF1bHRGbGF2b3VyIHZhbHVlLlxuICogQHBhcmFtIHtvYmplY3R9IHRhcmdldCBUaGUgdGFyZ2V0IG9iamVjdCBiZWluZyBkZWNvcmF0ZWRcbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHJlc29sdmVkIGZsYXZvdXIgaWRlbnRpZmllclxuICogQGZ1bmN0aW9uIGRlZmF1bHRGbGF2b3VyUmVzb2x2ZXJcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdGlvblxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG5mdW5jdGlvbiBkZWZhdWx0Rmxhdm91clJlc29sdmVyKHRhcmdldDogb2JqZWN0KSB7XG4gIHJldHVybiBEZWZhdWx0Rmxhdm91cjtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gVW5pb24gdHlwZSBjb3ZlcmluZyBzdXBwb3J0ZWQgZGVjb3JhdG9yIGtpbmRzXG4gKiBAc3VtbWFyeSBSZXByZXNlbnRzIGFueSBvZiB0aGUgc3RhbmRhcmQgVHlwZVNjcmlwdCBkZWNvcmF0b3Igc2lnbmF0dXJlcyAoY2xhc3MsIHByb3BlcnR5LCBvciBtZXRob2QpLCBlbmFibGluZyBmbGV4aWJsZSByZWdpc3RyYXRpb24gYW5kIGFwcGxpY2F0aW9uIHdpdGhpbiB0aGUgRGVjb3JhdGlvbiBzeXN0ZW0uXG4gKiBAdGVtcGxhdGUgVFxuICogQHR5cGVEZWYgRGVjb3JhdG9yVHlwZXNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdGlvblxuICovXG5leHBvcnQgdHlwZSBEZWNvcmF0b3JUeXBlcyA9XG4gIHwgQ2xhc3NEZWNvcmF0b3JcbiAgfCBQcm9wZXJ0eURlY29yYXRvclxuICB8IE1ldGhvZERlY29yYXRvcjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gVHlwZSBkZWZpbml0aW9uIGZvciBhIGRlY29yYXRvciBmYWN0b3J5IGZ1bmN0aW9uXG4gKiBAc3VtbWFyeSBSZXByZXNlbnRzIGEgZnVuY3Rpb24gdGhhdCBhY2NlcHRzIGFyYml0cmFyeSBhcmd1bWVudHMgYW5kIHJldHVybnMgYSBjb25jcmV0ZSBkZWNvcmF0b3IgZnVuY3Rpb24gdG8gYmUgYXBwbGllZCB0byBhIHRhcmdldC5cbiAqIEB0ZW1wbGF0ZSBBXG4gKiBAdHlwZURlZiBEZWNvcmF0b3JGYWN0b3J5XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRpb25cbiAqL1xuZXhwb3J0IHR5cGUgRGVjb3JhdG9yRmFjdG9yeSA9ICguLi5hcmdzOiBhbnlbXSkgPT4gRGVjb3JhdG9yVHlwZXM7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEFyZ3VtZW50IGJ1bmRsZSBmb3IgYSBkZWNvcmF0b3IgZmFjdG9yeVxuICogQHN1bW1hcnkgT2JqZWN0IGZvcm0gdXNlZCB0byBkZWZlciBkZWNvcmF0b3IgY3JlYXRpb24sIGNhcnJ5aW5nIGJvdGggdGhlIGZhY3RvcnkgZnVuY3Rpb24gYW5kIGl0cyBhcmd1bWVudCBsaXN0IHRvIGJlIGludm9rZWQgbGF0ZXIgZHVyaW5nIGFwcGxpY2F0aW9uLlxuICogQHR5cGVEZWYgRGVjb3JhdG9yRmFjdG9yeUFyZ3NcbiAqIEBwcm9wZXJ0eSB7RGVjb3JhdG9yRmFjdG9yeX0gZGVjb3JhdG9yIFRoZSBmYWN0b3J5IGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgYSBkZWNvcmF0b3Igd2hlbiBpbnZva2VkXG4gKiBAcHJvcGVydHkge2FueVtdfSBhcmdzIGxpc3Qgb2YgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGRlY29yYXRvciBmYWN0b3J5XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRpb25cbiAqL1xuZXhwb3J0IHR5cGUgRGVjb3JhdG9yRmFjdG9yeUFyZ3MgPSB7XG4gIGRlY29yYXRvcjogRGVjb3JhdG9yRmFjdG9yeTtcbiAgYXJnczogYW55W107XG59O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBVbmlvbiB0aGF0IHJlcHJlc2VudHMgZWl0aGVyIGEgcmVhZHktdG8tYXBwbHkgZGVjb3JhdG9yIG9yIGEgZmFjdG9yeSB3aXRoIGFyZ3VtZW50c1xuICogQHN1bW1hcnkgQWxsb3dzIHJlZ2lzdGVyaW5nIGRlY29yYXRvcnMgaW4gdHdvIGZvcm1zOiBhcyBkaXJlY3QgZGVjb3JhdG9yIGZ1bmN0aW9ucyBvciBhcyBkZWZlcnJlZCBmYWN0b3JpZXMgcGFpcmVkIHdpdGggdGhlaXIgYXJndW1lbnQgbGlzdHMgZm9yIGxhdGVyIGluc3RhbnRpYXRpb24uXG4gKiBAdHlwZURlZiBEZWNvcmF0b3JEYXRhXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRpb25cbiAqL1xuZXhwb3J0IHR5cGUgRGVjb3JhdG9yRGF0YSA9IERlY29yYXRvclR5cGVzIHwgRGVjb3JhdG9yRmFjdG9yeUFyZ3M7XG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBIGRlY29yYXRvciBtYW5hZ2VtZW50IGNsYXNzIHRoYXQgaGFuZGxlcyBmbGF2b3VyZWQgZGVjb3JhdG9yc1xuICogQHN1bW1hcnkgVGhlIERlY29yYXRpb24gY2xhc3MgcHJvdmlkZXMgYSBidWlsZGVyIHBhdHRlcm4gZm9yIGNyZWF0aW5nIGFuZCBtYW5hZ2luZyBkZWNvcmF0b3JzIHdpdGggZGlmZmVyZW50IGZsYXZvdXJzLlxuICogSXQgc3VwcG9ydHMgcmVnaXN0ZXJpbmcsIGV4dGVuZGluZywgYW5kIGFwcGx5aW5nIGRlY29yYXRvcnMgd2l0aCBjb250ZXh0LWF3YXJlIGZsYXZvdXIgcmVzb2x1dGlvbi5cbiAqIFRoZSBjbGFzcyBpbXBsZW1lbnRzIGEgZmx1ZW50IGludGVyZmFjZSBmb3IgZGVmaW5pbmcsIGV4dGVuZGluZywgYW5kIGFwcGx5aW5nIGRlY29yYXRvcnMgd2l0aCBkaWZmZXJlbnQgZmxhdm91cnMsXG4gKiBhbGxvd2luZyBmb3IgZnJhbWV3b3JrLXNwZWNpZmljIGRlY29yYXRvciBpbXBsZW1lbnRhdGlvbnMgd2hpbGUgbWFpbnRhaW5pbmcgYSBjb25zaXN0ZW50IEFQSS5cbiAqIEB0ZW1wbGF0ZSBUIFR5cGUgb2YgdGhlIGRlY29yYXRvciAoQ2xhc3NEZWNvcmF0b3IgfCBQcm9wZXJ0eURlY29yYXRvciB8IE1ldGhvZERlY29yYXRvcilcbiAqIEBwYXJhbSB7c3RyaW5nfSBbZmxhdm91cl0gT3B0aW9uYWwgZmxhdm91ciBwYXJhbWV0ZXIgZm9yIHRoZSBkZWNvcmF0b3IgY29udGV4dFxuICogQGNsYXNzXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gQ3JlYXRlIGEgbmV3IGRlY29yYXRpb24gZm9yICdjb21wb25lbnQnIHdpdGggZGVmYXVsdCBmbGF2b3VyXG4gKiBjb25zdCBjb21wb25lbnREZWNvcmF0b3IgPSBuZXcgRGVjb3JhdGlvbigpXG4gKiAgIC5mb3IoJ2NvbXBvbmVudCcpXG4gKiAgIC5kZWZpbmUoY3VzdG9tQ29tcG9uZW50RGVjb3JhdG9yKTtcbiAqXG4gKiAvLyBDcmVhdGUgYSBmbGF2b3VyZWQgZGVjb3JhdGlvblxuICogY29uc3QgdnVlQ29tcG9uZW50ID0gbmV3IERlY29yYXRpb24oJ3Z1ZScpXG4gKiAgIC5mb3IoJ2NvbXBvbmVudCcpXG4gKiAgIC5kZWZpbmUodnVlQ29tcG9uZW50RGVjb3JhdG9yKTtcbiAqXG4gKiAvLyBBcHBseSB0aGUgZGVjb3JhdGlvblxuICogQGNvbXBvbmVudERlY29yYXRvclxuICogY2xhc3MgTXlDb21wb25lbnQge31cbiAqIGBgYFxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENsaWVudFxuICogICBwYXJ0aWNpcGFudCBEIGFzIERlY29yYXRpb25cbiAqICAgcGFydGljaXBhbnQgUiBhcyBGbGF2b3VyUmVzb2x2ZXJcbiAqICAgcGFydGljaXBhbnQgRiBhcyBEZWNvcmF0b3JGYWN0b3J5XG4gKlxuICogICBDLT4+RDogbmV3IERlY29yYXRpb24oZmxhdm91cilcbiAqICAgQy0+PkQ6IGZvcihrZXkpXG4gKiAgIEMtPj5EOiBkZWZpbmUoZGVjb3JhdG9ycylcbiAqICAgRC0+PkQ6IHJlZ2lzdGVyKGtleSwgZmxhdm91ciwgZGVjb3JhdG9ycylcbiAqICAgRC0+PkY6IGRlY29yYXRvckZhY3Rvcnkoa2V5LCBmbGF2b3VyKVxuICogICBGLT4+UjogcmVzb2x2ZSh0YXJnZXQpXG4gKiAgIFItLT4+RjogcmVzb2x2ZWQgZmxhdm91clxuICogICBGLT4+RjogYXBwbHkgZGVjb3JhdG9yc1xuICogICBGLS0+PkM6IGRlY29yYXRlZCB0YXJnZXRcbiAqL1xuZXhwb3J0IGNsYXNzIERlY29yYXRpb24gaW1wbGVtZW50cyBJRGVjb3JhdGlvbkJ1aWxkZXIge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFN0YXRpYyBtYXAgb2YgcmVnaXN0ZXJlZCBkZWNvcmF0b3JzXG4gICAqIEBzdW1tYXJ5IFN0b3JlcyBhbGwgcmVnaXN0ZXJlZCBkZWNvcmF0b3JzIG9yZ2FuaXplZCBieSBrZXkgYW5kIGZsYXZvdXJcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGRlY29yYXRvcnM6IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgUmVjb3JkPFxuICAgICAgc3RyaW5nLFxuICAgICAge1xuICAgICAgICBkZWNvcmF0b3JzPzogU2V0PERlY29yYXRvckRhdGE+O1xuICAgICAgICBleHRyYXM/OiBTZXQ8RGVjb3JhdG9yRGF0YT47XG4gICAgICB9XG4gICAgPlxuICA+ID0ge307XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBGdW5jdGlvbiB0byByZXNvbHZlIGZsYXZvdXIgZnJvbSBhIHRhcmdldFxuICAgKiBAc3VtbWFyeSBSZXNvbHZlciBmdW5jdGlvbiB0aGF0IGRldGVybWluZXMgdGhlIGFwcHJvcHJpYXRlIGZsYXZvdXIgZm9yIGEgZ2l2ZW4gdGFyZ2V0XG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBmbGF2b3VyUmVzb2x2ZXI6IEZsYXZvdXJSZXNvbHZlciA9IGRlZmF1bHRGbGF2b3VyUmVzb2x2ZXI7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXQgb2YgZGVjb3JhdG9ycyBmb3IgdGhlIGN1cnJlbnQgY29udGV4dFxuICAgKi9cbiAgcHJpdmF0ZSBkZWNvcmF0b3JzPzogU2V0PERlY29yYXRvckRhdGE+O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0IG9mIGFkZGl0aW9uYWwgZGVjb3JhdG9yc1xuICAgKi9cbiAgcHJpdmF0ZSBleHRyYXM/OiBTZXQ8RGVjb3JhdG9yRGF0YT47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDdXJyZW50IGRlY29yYXRvciBrZXlcbiAgICovXG4gIHByaXZhdGUga2V5Pzogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZmxhdm91cjogc3RyaW5nID0gRGVmYXVsdEZsYXZvdXIpIHt9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBrZXkgZm9yIHRoZSBkZWNvcmF0aW9uIGJ1aWxkZXJcbiAgICogQHN1bW1hcnkgSW5pdGlhbGl6ZXMgYSBuZXcgZGVjb3JhdGlvbiBjaGFpbiB3aXRoIHRoZSBzcGVjaWZpZWQga2V5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGlkZW50aWZpZXIgZm9yIHRoZSBkZWNvcmF0b3JcbiAgICogQHJldHVybiB7RGVjb3JhdGlvbkJ1aWxkZXJNaWR9IEJ1aWxkZXIgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZ1xuICAgKi9cbiAgZm9yKGtleTogc3RyaW5nKTogRGVjb3JhdGlvbkJ1aWxkZXJNaWQge1xuICAgIHRoaXMua2V5ID0ga2V5O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBZGRzIGRlY29yYXRvcnMgdG8gdGhlIGN1cnJlbnQgY29udGV4dFxuICAgKiBAc3VtbWFyeSBJbnRlcm5hbCBtZXRob2QgdG8gYWRkIGRlY29yYXRvcnMgd2l0aCBhZGRvbiBzdXBwb3J0XG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2FkZG9uPWZhbHNlXSBXaGV0aGVyIHRoZSBkZWNvcmF0b3JzIGFyZSBhZGRvbnNcbiAgICogQHBhcmFtIGRlY29yYXRvcnMgQXJyYXkgb2YgZGVjb3JhdG9yc1xuICAgKiBAcmV0dXJuIHt0aGlzfSBDdXJyZW50IGluc3RhbmNlIGZvciBjaGFpbmluZ1xuICAgKi9cbiAgcHJpdmF0ZSBkZWNvcmF0ZShcbiAgICBhZGRvbjogYm9vbGVhbiA9IGZhbHNlLFxuICAgIC4uLmRlY29yYXRvcnM6IERlY29yYXRvckRhdGFbXVxuICApOiB0aGlzIHtcbiAgICBpZiAoIXRoaXMua2V5KVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwia2V5IG11c3QgYmUgcHJvdmlkZWQgYmVmb3JlIGRlY29yYXRvcnMgY2FuIGJlIGFkZGVkXCIpO1xuICAgIGlmIChcbiAgICAgICghZGVjb3JhdG9ycyB8fCAhZGVjb3JhdG9ycy5sZW5ndGgpICYmXG4gICAgICAhYWRkb24gJiZcbiAgICAgIHRoaXMuZmxhdm91ciAhPT0gRGVmYXVsdEZsYXZvdXJcbiAgICApXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiTXVzdCBwcm92aWRlIG92ZXJyaWRlcyBvciBhZGRvbnMgdG8gb3ZlcnJpZGUgb3IgZXh0ZW5kIGRlY2FmJ3MgZGVjb3JhdG9yc1wiXG4gICAgICApO1xuICAgIGlmICh0aGlzLmZsYXZvdXIgPT09IERlZmF1bHRGbGF2b3VyICYmIGFkZG9uKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRGVmYXVsdCBmbGF2b3VyIGNhbm5vdCBiZSBleHRlbmRlZFwiKTtcblxuICAgIHRoaXNbYWRkb24gPyBcImV4dHJhc1wiIDogXCJkZWNvcmF0b3JzXCJdID0gbmV3IFNldChbXG4gICAgICAuLi4odGhpc1thZGRvbiA/IFwiZXh0cmFzXCIgOiBcImRlY29yYXRvcnNcIl0gfHwgbmV3IFNldCgpKS52YWx1ZXMoKSxcbiAgICAgIC4uLmRlY29yYXRvcnMsXG4gICAgXSk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRGVmaW5lcyB0aGUgYmFzZSBkZWNvcmF0b3JzXG4gICAqIEBzdW1tYXJ5IFNldHMgdGhlIHByaW1hcnkgZGVjb3JhdG9ycyBmb3IgdGhlIGN1cnJlbnQgY29udGV4dFxuICAgKiBAcGFyYW0gZGVjb3JhdG9ycyBEZWNvcmF0b3JzIHRvIGRlZmluZVxuICAgKiBAcmV0dXJuIEJ1aWxkZXIgaW5zdGFuY2UgZm9yIGZpbmlzaGluZyB0aGUgY2hhaW5cbiAgICovXG4gIGRlZmluZShcbiAgICAuLi5kZWNvcmF0b3JzOiBEZWNvcmF0b3JEYXRhW11cbiAgKTogRGVjb3JhdGlvbkJ1aWxkZXJFbmQgJiBEZWNvcmF0aW9uQnVpbGRlckJ1aWxkIHtcbiAgICBpZiAoXG4gICAgICBkZWNvcmF0b3JzLmZpbmQoKGQpID0+IHR5cGVvZiBkID09PSBcIm9iamVjdFwiKSAmJlxuICAgICAgZGVjb3JhdG9ycy5sZW5ndGggIT09IDFcbiAgICApXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBXaGVuIHVzaW5nIGFuIG92ZXJyaWRhYmxlIGRlY29yYXRvciwgb25seSBvbmUgaXMgYWxsb3dlZGBcbiAgICAgICk7XG4gICAgcmV0dXJuIHRoaXMuZGVjb3JhdGUoZmFsc2UsIC4uLmRlY29yYXRvcnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFeHRlbmRzIGV4aXN0aW5nIGRlY29yYXRvcnNcbiAgICogQHN1bW1hcnkgQWRkcyBhZGRpdGlvbmFsIGRlY29yYXRvcnMgdG8gdGhlIGN1cnJlbnQgY29udGV4dFxuICAgKiBAcGFyYW0gZGVjb3JhdG9ycyBBZGRpdGlvbmFsIGRlY29yYXRvcnNcbiAgICogQHJldHVybiB7RGVjb3JhdGlvbkJ1aWxkZXJCdWlsZH0gQnVpbGRlciBpbnN0YW5jZSBmb3IgYnVpbGRpbmcgdGhlIGRlY29yYXRvclxuICAgKi9cbiAgZXh0ZW5kKC4uLmRlY29yYXRvcnM6IERlY29yYXRvckRhdGFbXSk6IERlY29yYXRpb25CdWlsZGVyQnVpbGQge1xuICAgIGlmIChcbiAgICAgIGRlY29yYXRvcnMuZmluZCgoZCkgPT4gdHlwZW9mIGQgPT09IFwib2JqZWN0XCIpICYmXG4gICAgICBkZWNvcmF0b3JzLmxlbmd0aCAhPT0gMVxuICAgIClcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFdoZW4gZXh0ZW5kaW5nIHVzaW5nIGFuIG92ZXJyaWRhYmxlIGRlY29yYXRvciwgb25seSBvbmUgaXMgYWxsb3dlZGBcbiAgICAgICk7XG4gICAgcmV0dXJuIHRoaXMuZGVjb3JhdGUodHJ1ZSwgLi4uZGVjb3JhdG9ycyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEZhY3RvcnkgdGhhdCBjcmVhdGVzIGEgY29udGV4dC1hd2FyZSBkZWNvcmF0b3IgZm9yIGEga2V5L2ZsYXZvdXJcbiAgICogQHN1bW1hcnkgUHJvZHVjZXMgYSBkZWNvcmF0b3IgZnVuY3Rpb24gYm91bmQgdG8gdGhlIHByb3ZpZGVkIGtleSBhbmQgZmxhdm91ci4gVGhlIHJlc3VsdGluZyBkZWNvcmF0b3IgcmVzb2x2ZXMgdGhlIGFjdHVhbFxuICAgKiBkZWNvcmF0b3JzIHRvIGFwcGx5IGF0IGludm9jYXRpb24gdGltZSBiYXNlZCBvbiB0aGUgdGFyZ2V0J3MgcmVzb2x2ZWQgZmxhdm91ciBhbmQgdGhlIHJlZ2lzdGVyZWQgYmFzZSBhbmQgZXh0cmEgZGVjb3JhdG9ycy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUgZGVjb3JhdGlvbiBrZXkgdXNlZCB0byBsb29rIHVwIHJlZ2lzdGVyZWQgZGVjb3JhdG9yc1xuICAgKiBAcGFyYW0ge3N0cmluZ30gW2Y9RGVmYXVsdEZsYXZvdXJdIE9wdGlvbmFsIGV4cGxpY2l0IGZsYXZvdXIgdG8gYmluZCB0aGUgZmFjdG9yeSB0b1xuICAgKiBAcmV0dXJuIHtmdW5jdGlvbihvYmplY3QsIGFueSwgVHlwZWRQcm9wZXJ0eURlc2NyaXB0b3I8YW55Pik6IGFueX0gQSBkZWNvcmF0b3IgZnVuY3Rpb24gdGhhdCBhcHBsaWVzIHRoZSByZXNvbHZlZCBkZWNvcmF0b3JzXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IFUgYXMgVXNlciBDb2RlXG4gICAqICAgcGFydGljaXBhbnQgQiBhcyBEZWNvcmF0aW9uIChidWlsZGVyKVxuICAgKiAgIHBhcnRpY2lwYW50IEYgYXMgZGVjb3JhdG9yRmFjdG9yeShrZXksIGYpXG4gICAqICAgcGFydGljaXBhbnQgUiBhcyBmbGF2b3VyUmVzb2x2ZXJcbiAgICogICBwYXJ0aWNpcGFudCBBIGFzIEFwcGxpZWQgRGVjb3JhdG9yc1xuICAgKiAgIFUtPj5COiBkZWZpbmUoKS9leHRlbmQoKSBhbmQgYXBwbHkoKVxuICAgKiAgIEItPj5GOiBjcmVhdGUgY29udGV4dCBkZWNvcmF0b3JcbiAgICogICBGLT4+UjogcmVzb2x2ZSh0YXJnZXQpXG4gICAqICAgUi0tPj5GOiBmbGF2b3VyXG4gICAqICAgRi0+PkE6IGNvbGxlY3QgYmFzZSArIGV4dHJhc1xuICAgKiAgIGxvb3AgZWFjaCBkZWNvcmF0b3JcbiAgICogICAgIEEtPj5VOiBpbnZva2UgZGVjb3JhdG9yKHRhcmdldCwga2V5PywgZGVzYz8pXG4gICAqICAgZW5kXG4gICAqL1xuICBwcm90ZWN0ZWQgZGVjb3JhdG9yRmFjdG9yeShrZXk6IHN0cmluZywgZjogc3RyaW5nID0gRGVmYXVsdEZsYXZvdXIpIHtcbiAgICBmdW5jdGlvbiBjb250ZXh0RGVjb3JhdG9yKFxuICAgICAgdGFyZ2V0OiBvYmplY3QsXG4gICAgICBwcm9wZXJ0eUtleT86IGFueSxcbiAgICAgIGRlc2NyaXB0b3I/OiBUeXBlZFByb3BlcnR5RGVzY3JpcHRvcjxhbnk+XG4gICAgKSB7XG4gICAgICBjb25zdCBmbGF2b3VyID0gRGVjb3JhdGlvbi5mbGF2b3VyUmVzb2x2ZXIodGFyZ2V0KTtcbiAgICAgIGNvbnN0IGNhY2hlID0gRGVjb3JhdGlvbi5kZWNvcmF0b3JzW2tleV07XG4gICAgICBsZXQgZGVjb3JhdG9ycztcbiAgICAgIGNvbnN0IGV4dHJhcyA9IGNhY2hlW2ZsYXZvdXJdXG4gICAgICAgID8gY2FjaGVbZmxhdm91cl0uZXh0cmFzXG4gICAgICAgIDogY2FjaGVbRGVmYXVsdEZsYXZvdXJdLmV4dHJhcztcblxuICAgICAgaWYgKFxuICAgICAgICBjYWNoZSAmJlxuICAgICAgICBjYWNoZVtmbGF2b3VyXSAmJlxuICAgICAgICBjYWNoZVtmbGF2b3VyXS5kZWNvcmF0b3JzICYmXG4gICAgICAgIGNhY2hlW2ZsYXZvdXJdLmRlY29yYXRvcnMuc2l6ZVxuICAgICAgKSB7XG4gICAgICAgIGRlY29yYXRvcnMgPSBjYWNoZVtmbGF2b3VyXS5kZWNvcmF0b3JzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVjb3JhdG9ycyA9IGNhY2hlW0RlZmF1bHRGbGF2b3VyXS5kZWNvcmF0b3JzO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBkZWNvcmF0b3JBcmdzID0gW1xuICAgICAgICAuLi4oY2FjaGVbRGVmYXVsdEZsYXZvdXJdIGFzIGFueSkuZGVjb3JhdG9ycy52YWx1ZXMoKSxcbiAgICAgIF0ucmVkdWNlKChhY2N1bTogUmVjb3JkPG51bWJlciwgYW55PiwgZSwgaSkgPT4ge1xuICAgICAgICBpZiAoZS5hcmdzKSBhY2N1bVtpXSA9IGUuYXJncztcbiAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgfSwge30pO1xuXG4gICAgICBjb25zdCB0b0FwcGx5ID0gW1xuICAgICAgICAuLi4oZGVjb3JhdG9ycyA/IGRlY29yYXRvcnMudmFsdWVzKCkgOiBbXSksXG4gICAgICAgIC4uLihleHRyYXMgPyBleHRyYXMudmFsdWVzKCkgOiBbXSksXG4gICAgICBdO1xuXG4gICAgICByZXR1cm4gdG9BcHBseS5yZWR1Y2UoXG4gICAgICAgIChfLCBkKSA9PiB7XG4gICAgICAgICAgc3dpdGNoICh0eXBlb2YgZCkge1xuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOiB7XG4gICAgICAgICAgICAgIGNvbnN0IHsgZGVjb3JhdG9yIH0gPSBkIGFzIERlY29yYXRvckZhY3RvcnlBcmdzO1xuXG4gICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgZGVjb3JhdG9yKC4uLihPYmplY3QudmFsdWVzKGRlY29yYXRvckFyZ3MpWzBdIHx8IFtdKSkgYXMgYW55XG4gICAgICAgICAgICAgICkodGFyZ2V0LCBwcm9wZXJ0eUtleSwgZGVzY3JpcHRvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiZnVuY3Rpb25cIjpcbiAgICAgICAgICAgICAgcmV0dXJuIChkIGFzIGFueSkodGFyZ2V0LCBwcm9wZXJ0eUtleSwgZGVzY3JpcHRvcik7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgZGVjb3JhdG9yIHR5cGU6ICR7dHlwZW9mIGR9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7IHRhcmdldCwgcHJvcGVydHlLZXksIGRlc2NyaXB0b3IgfVxuICAgICAgKTtcbiAgICB9XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvbnRleHREZWNvcmF0b3IsIFwibmFtZVwiLCB7XG4gICAgICB2YWx1ZTogW2YsIGtleV0uam9pbihcIl9kZWNvcmF0b3JfZm9yX1wiKSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICB9KTtcbiAgICByZXR1cm4gY29udGV4dERlY29yYXRvcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyB0aGUgZmluYWwgZGVjb3JhdG9yIGZ1bmN0aW9uXG4gICAqIEBzdW1tYXJ5IEJ1aWxkcyBhbmQgcmV0dXJucyB0aGUgZGVjb3JhdG9yIGZhY3RvcnkgZnVuY3Rpb25cbiAgICogQHJldHVybiB7ZnVuY3Rpb24oYW55LCBhbnk/LCBUeXBlZFByb3BlcnR5RGVzY3JpcHRvcj8pOiBhbnl9IFRoZSBnZW5lcmF0ZWQgZGVjb3JhdG9yIGZ1bmN0aW9uXG4gICAqL1xuICBhcHBseSgpOiAoXG4gICAgdGFyZ2V0OiBhbnksXG4gICAgcHJvcGVydHlLZXk/OiBhbnksXG4gICAgZGVzY3JpcHRvcj86IFR5cGVkUHJvcGVydHlEZXNjcmlwdG9yPGFueT5cbiAgKSA9PiBhbnkge1xuICAgIGlmICghdGhpcy5rZXkpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBrZXkgcHJvdmlkZWQgZm9yIHRoZSBkZWNvcmF0aW9uIGJ1aWxkZXJcIik7XG4gICAgRGVjb3JhdGlvbi5yZWdpc3RlcihcbiAgICAgIHRoaXMua2V5LFxuICAgICAgdGhpcy5mbGF2b3VyLFxuICAgICAgdGhpcy5kZWNvcmF0b3JzIHx8IG5ldyBTZXQoKSxcbiAgICAgIHRoaXMuZXh0cmFzXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5kZWNvcmF0b3JGYWN0b3J5KHRoaXMua2V5LCB0aGlzLmZsYXZvdXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWdpc3RlcnMgZGVjb3JhdG9ycyBmb3IgYSBzcGVjaWZpYyBrZXkgYW5kIGZsYXZvdXJcbiAgICogQHN1bW1hcnkgSW50ZXJuYWwgbWV0aG9kIHRvIHN0b3JlIGRlY29yYXRvcnMgaW4gdGhlIHN0YXRpYyByZWdpc3RyeVxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IERlY29yYXRvciBrZXlcbiAgICogQHBhcmFtIHtzdHJpbmd9IGZsYXZvdXIgRGVjb3JhdG9yIGZsYXZvdXJcbiAgICogQHBhcmFtIFtkZWNvcmF0b3JzXSBQcmltYXJ5IGRlY29yYXRvcnNcbiAgICogQHBhcmFtIFtleHRyYXNdIEFkZGl0aW9uYWwgZGVjb3JhdG9yc1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgcmVnaXN0ZXIoXG4gICAga2V5OiBzdHJpbmcsXG4gICAgZmxhdm91cjogc3RyaW5nLFxuICAgIGRlY29yYXRvcnM/OiBTZXQ8RGVjb3JhdG9yRGF0YT4sXG4gICAgZXh0cmFzPzogU2V0PERlY29yYXRvckRhdGE+XG4gICkge1xuICAgIGlmICgha2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBrZXkgcHJvdmlkZWQgZm9yIHRoZSBkZWNvcmF0aW9uIGJ1aWxkZXJcIik7XG4gICAgfVxuICAgIGlmICghZGVjb3JhdG9ycylcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGRlY29yYXRvcnMgcHJvdmlkZWQgZm9yIHRoZSBkZWNvcmF0aW9uIGJ1aWxkZXJcIik7XG4gICAgaWYgKCFmbGF2b3VyKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gZmxhdm91ciBwcm92aWRlZCBmb3IgdGhlIGRlY29yYXRpb24gYnVpbGRlclwiKTtcblxuICAgIGlmICghRGVjb3JhdGlvbi5kZWNvcmF0b3JzW2tleV0pIERlY29yYXRpb24uZGVjb3JhdG9yc1trZXldID0ge307XG4gICAgaWYgKCFEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XVtmbGF2b3VyXSlcbiAgICAgIERlY29yYXRpb24uZGVjb3JhdG9yc1trZXldW2ZsYXZvdXJdID0ge307XG4gICAgaWYgKGRlY29yYXRvcnMpIERlY29yYXRpb24uZGVjb3JhdG9yc1trZXldW2ZsYXZvdXJdLmRlY29yYXRvcnMgPSBkZWNvcmF0b3JzO1xuICAgIGlmIChleHRyYXMpIERlY29yYXRpb24uZGVjb3JhdG9yc1trZXldW2ZsYXZvdXJdLmV4dHJhcyA9IGV4dHJhcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgZ2xvYmFsIGZsYXZvdXIgcmVzb2x2ZXJcbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgZnVuY3Rpb24gdXNlZCB0byBkZXRlcm1pbmUgZGVjb3JhdG9yIGZsYXZvdXJzXG4gICAqIEBwYXJhbSB7Rmxhdm91clJlc29sdmVyfSByZXNvbHZlciBGdW5jdGlvbiB0byByZXNvbHZlIGZsYXZvdXJzXG4gICAqL1xuICBzdGF0aWMgc2V0Rmxhdm91clJlc29sdmVyKHJlc29sdmVyOiBGbGF2b3VyUmVzb2x2ZXIpIHtcbiAgICBEZWNvcmF0aW9uLmZsYXZvdXJSZXNvbHZlciA9IHJlc29sdmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDb252ZW5pZW5jZSBzdGF0aWMgZW50cnkgdG8gc3RhcnQgYSBkZWNvcmF0aW9uIGJ1aWxkZXJcbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIG5ldyBEZWNvcmF0aW9uIGluc3RhbmNlIGFuZCBpbml0aWF0ZXMgdGhlIGJ1aWxkZXIgY2hhaW4gd2l0aCB0aGUgcHJvdmlkZWQga2V5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBkZWNvcmF0aW9uIGtleSB0byBjb25maWd1cmVcbiAgICogQHJldHVybiB7RGVjb3JhdGlvbkJ1aWxkZXJNaWR9IEEgYnVpbGRlciBpbnN0YW5jZSBmb3IgY2hhaW5pbmcgZGVmaW5pdGlvbnNcbiAgICovXG4gIHN0YXRpYyBmb3Ioa2V5OiBzdHJpbmcpOiBEZWNvcmF0aW9uQnVpbGRlck1pZCB7XG4gICAgcmV0dXJuIG5ldyBEZWNvcmF0aW9uKCkuZm9yKGtleSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFN0YXJ0cyBhIGJ1aWxkZXIgZm9yIGEgc3BlY2lmaWMgZmxhdm91clxuICAgKiBAc3VtbWFyeSBDb252ZW5pZW5jZSBtZXRob2QgdG8gYmVnaW4gYSBEZWNvcmF0aW9uIGJ1aWxkZXIgY2hhaW4gYm91bmQgdG8gdGhlIGdpdmVuIGZsYXZvdXIgaWRlbnRpZmllciwgYWxsb3dpbmcgcmVnaXN0cmF0aW9uIG9mIGZsYXZvdXItc3BlY2lmaWMgZGVjb3JhdG9ycy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZsYXZvdXIgVGhlIGZsYXZvdXIgbmFtZSB0byBiaW5kIHRvIHRoZSBidWlsZGVyXG4gICAqIEByZXR1cm4ge0RlY29yYXRpb25CdWlsZGVyU3RhcnR9IEEgYnVpbGRlciBzdGFydCBpbnRlcmZhY2UgdG8gY29udGludWUgY29uZmlndXJhdGlvblxuICAgKi9cbiAgc3RhdGljIGZsYXZvdXJlZEFzKGZsYXZvdXI6IHN0cmluZyk6IERlY29yYXRpb25CdWlsZGVyU3RhcnQge1xuICAgIHJldHVybiBuZXcgRGVjb3JhdGlvbihmbGF2b3VyKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgTWV0YWRhdGEgfSBmcm9tIFwiLi9tZXRhZGF0YS9NZXRhZGF0YVwiO1xuaW1wb3J0IHsgRGVjb3JhdGlvbktleXMsIE9iamVjdEtleVNwbGl0dGVyIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEFzc2lnbnMgYXJiaXRyYXJ5IG1ldGFkYXRhIHRvIGEgdGFyZ2V0IHVzaW5nIGEgc3RyaW5nIGtleVxuICogQHN1bW1hcnkgRGVjb3JhdG9yIGZhY3RvcnkgdGhhdCBzdG9yZXMgYSBrZXkvdmFsdWUgcGFpciBpbiB0aGUgY2VudHJhbCBNZXRhZGF0YSBzdG9yZSBmb3IgdGhlIHByb3ZpZGVkIGNsYXNzIG9yIG1lbWJlci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIG1ldGFkYXRhIGtleSB0byBhc3NvY2lhdGUgd2l0aCB0aGUgdGFyZ2V0XG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBtZXRhZGF0YSB2YWx1ZSB0byBzdG9yZSB1bmRlciB0aGUgZ2l2ZW4ga2V5XG4gKiBAcmV0dXJuIEEgZGVjb3JhdG9yIHRoYXQgd3JpdGVzIHRoZSBtZXRhZGF0YSB3aGVuIGFwcGxpZWRcbiAqIEBmdW5jdGlvbiBtZXRhZGF0YVxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ldGFkYXRhKGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSB7XG4gIHJldHVybiBmdW5jdGlvbiBtZXRhZGF0YShcbiAgICBtb2RlbDogYW55LFxuXG4gICAgcHJvcD86IGFueSxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgZGVzY3JpcHRvcj86IFByb3BlcnR5RGVzY3JpcHRvclxuICApIHtcbiAgICBNZXRhZGF0YS5zZXQocHJvcCA/IG1vZGVsLmNvbnN0cnVjdG9yIDogbW9kZWwsIGtleSwgdmFsdWUpO1xuICB9O1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDYXB0dXJlcyBhbmQgc3RvcmVzIGEgcHJvcGVydHkncyBkZXNpZ24gdHlwZVxuICogQHN1bW1hcnkgRGVjb3JhdG9yIGZhY3RvcnkgdGhhdCByZWFkcyB0aGUgcmVmbGVjdGVkIGRlc2lnbjp0eXBlIGZvciBhIHByb3BlcnR5IGFuZCByZWdpc3RlcnMgaXQgaW4gdGhlIE1ldGFkYXRhIHN0b3JlIHVuZGVyIHRoZSBwcm9wZXJ0aWVzIG1hcC5cbiAqIEByZXR1cm4gQSBkZWNvcmF0b3IgdGhhdCByZWNvcmRzIHRoZSBwcm9wZXJ0eSdzIHR5cGUgbWV0YWRhdGEgd2hlbiBhcHBsaWVkXG4gKiBAZnVuY3Rpb24gcHJvcFxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByb3AoKSB7XG4gIHJldHVybiBmdW5jdGlvbiBwcm9wKG1vZGVsOiBvYmplY3QsIHByb3A6IGFueSkge1xuICAgIGNvbnN0IGRlc2lnblR5cGUgPSBSZWZsZWN0LmdldE93bk1ldGFkYXRhKFxuICAgICAgRGVjb3JhdGlvbktleXMuREVTSUdOX1RZUEUsXG4gICAgICBtb2RlbCxcbiAgICAgIHByb3BcbiAgICApO1xuICAgIHJldHVybiBtZXRhZGF0YShgJHtEZWNvcmF0aW9uS2V5cy5QUk9QRVJUSUVTfS4ke3Byb3B9YCwgZGVzaWduVHlwZSkoXG4gICAgICBtb2RlbCxcbiAgICAgIHByb3BcbiAgICApO1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWV0aG9kKCkge1xuICByZXR1cm4gZnVuY3Rpb24gbWV0aG9kKG9iajogYW55LCBwcm9wOiBhbnksIGRlc2NyaXB0b3I6IGFueSkge1xuICAgIGNvbnN0IGRlc2lnblBhcmFtcyA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGEoXG4gICAgICBEZWNvcmF0aW9uS2V5cy5ERVNJR05fUEFSQU1TLFxuICAgICAgb2JqLFxuICAgICAgcHJvcFxuICAgICk7XG4gICAgY29uc3QgZGVzaWduUmV0dXJuID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YShcbiAgICAgIERlY29yYXRpb25LZXlzLkRFU0lHTl9SRVRVUk4sXG4gICAgICBvYmosXG4gICAgICBwcm9wXG4gICAgKTtcbiAgICByZXR1cm4gYXBwbHkoXG4gICAgICBtZXRhZGF0YShcbiAgICAgICAgYCR7RGVjb3JhdGlvbktleXMuTUVUSE9EU30uJHtwcm9wfS4ke0RlY29yYXRpb25LZXlzLkRFU0lHTl9QQVJBTVN9YCxcbiAgICAgICAgZGVzaWduUGFyYW1zXG4gICAgICApLFxuICAgICAgbWV0YWRhdGEoXG4gICAgICAgIGAke0RlY29yYXRpb25LZXlzLk1FVEhPRFN9LiR7cHJvcH0uJHtEZWNvcmF0aW9uS2V5cy5ERVNJR05fUkVUVVJOfWAsXG4gICAgICAgIGRlc2lnblJldHVyblxuICAgICAgKVxuICAgICkob2JqLCBwcm9wLCBkZXNjcmlwdG9yKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVjb3JhdG9yIGZhY3RvcnkgdGhhdCBhcHBsaWVzIG11bHRpcGxlIGRlY29yYXRvcnMgdG8gYSBzaW5nbGUgdGFyZ2V0XG4gKiBAc3VtbWFyeSBDcmVhdGVzIGEgY29tcG9zaXRlIGRlY29yYXRvciB0aGF0IGFwcGxpZXMgbXVsdGlwbGUgZGVjb3JhdG9ycyBpbiBzZXF1ZW5jZSwgY29ycmVjdGx5IGhhbmRsaW5nIGNsYXNzLCBtZXRob2QsIGFuZCBwcm9wZXJ0eSBkZWNvcmF0b3JzLlxuICogQHBhcmFtIHtBcnJheTxDbGFzc0RlY29yYXRvciB8IE1ldGhvZERlY29yYXRvciB8IFByb3BlcnR5RGVjb3JhdG9yPn0gZGVjb3JhdG9ycyAtIEFycmF5IG9mIGRlY29yYXRvcnMgdG8gYXBwbHlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIGRlY29yYXRvciBmdW5jdGlvbiB0aGF0IGFwcGxpZXMgYWxsIHByb3ZpZGVkIGRlY29yYXRvcnMgdG8gdGhlIHRhcmdldFxuICogQGZ1bmN0aW9uIGFwcGx5XG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IFUgYXMgVXNlciBDb2RlXG4gKiAgIHBhcnRpY2lwYW50IEEgYXMgYXBwbHkoLi4uZGVjb3JhdG9ycylcbiAqICAgcGFydGljaXBhbnQgRCBhcyBEZWNvcmF0b3JcbiAqICAgVS0+PkE6IGdldCBkZWNvcmF0b3IoLi4uZGVjb3JhdG9ycylcbiAqICAgQS0+PlU6IHJldHVybnMgKHRhcmdldCwga2V5PywgZGVzYz8pID0+IHZvaWRcbiAqICAgVS0+PkE6IGludm9rZSBvbiB0YXJnZXRcbiAqICAgbG9vcCBmb3IgZWFjaCBkZWNvcmF0b3JcbiAqICAgICBBLT4+RDogaW52b2tlIGFwcHJvcHJpYXRlIGRlY29yYXRvciB0eXBlXG4gKiAgIGVuZFxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5KFxuICAuLi5kZWNvcmF0b3JzOiBBcnJheTxDbGFzc0RlY29yYXRvciB8IE1ldGhvZERlY29yYXRvciB8IFByb3BlcnR5RGVjb3JhdG9yPlxuKSB7XG4gIHJldHVybiAoXG4gICAgdGFyZ2V0OiBvYmplY3QsXG4gICAgcHJvcGVydHlLZXk/OiBzdHJpbmcgfCBzeW1ib2wgfCB1bmtub3duLFxuICAgIGRlc2NyaXB0b3I/OiBQcm9wZXJ0eURlc2NyaXB0b3JcbiAgKSA9PiB7XG4gICAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgZGVjb3JhdG9ycykge1xuICAgICAgaWYgKHRhcmdldCBpbnN0YW5jZW9mIEZ1bmN0aW9uICYmICFkZXNjcmlwdG9yKSB7XG4gICAgICAgIChkZWNvcmF0b3IgYXMgQ2xhc3NEZWNvcmF0b3IpKHRhcmdldCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgKGRlY29yYXRvciBhcyBNZXRob2REZWNvcmF0b3IgfCBQcm9wZXJ0eURlY29yYXRvcikoXG4gICAgICAgIHRhcmdldCxcbiAgICAgICAgcHJvcGVydHlLZXkgYXMgc3RyaW5nIHwgc3ltYm9sLFxuICAgICAgICBkZXNjcmlwdG9yIGFzIFR5cGVkUHJvcGVydHlEZXNjcmlwdG9yPHVua25vd24+XG4gICAgICApO1xuICAgIH1cbiAgfTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIHByb3BlcnR5IG1ldGFkYXRhIGRlY29yYXRvclxuICogQHN1bW1hcnkgQ29udmVuaWVuY2UgZmFjdG9yeSB0aGF0IGNvbWJpbmVzIG1ldGFkYXRhKGtleSwgdmFsdWUpIGFuZCBwcm9wKCkgdG8gYm90aCBzZXQgYW4gYXJiaXRyYXJ5IG1ldGFkYXRhIGtleSBhbmQgcmVjb3JkIHRoZSBwcm9wZXJ0eSdzIGRlc2lnbiB0eXBlLlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUgbWV0YWRhdGEga2V5IHRvIHNldCBmb3IgdGhlIHByb3BlcnR5XG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBtZXRhZGF0YSB2YWx1ZSB0byBhc3NvY2lhdGUgd2l0aCB0aGUga2V5XG4gKiBAcmV0dXJuIEEgZGVjb3JhdG9yIHRoYXQgc2V0cyB0aGUgbWV0YWRhdGEgYW5kIGNhcHR1cmVzIHRoZSBwcm9wZXJ0eSdzIHR5cGVcbiAqIEBmdW5jdGlvbiBwcm9wTWV0YWRhdGFcbiAqIEBjYXRlZ29yeSBQcm9wZXJ0eSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm9wTWV0YWRhdGEoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpIHtcbiAgcmV0dXJuIGFwcGx5KG1ldGFkYXRhKGtleSwgdmFsdWUpLCBwcm9wKCkpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBdHRhY2hlcyBhIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIHRvIGEgY2xhc3Mgb3IgbWVtYmVyXG4gKiBAc3VtbWFyeSBEZWNvcmF0b3IgZmFjdG9yeSB0aGF0IHN0b3JlcyBhIHRleHR1YWwgZGVzY3JpcHRpb24gaW4gdGhlIE1ldGFkYXRhIHN0b3JlIHVuZGVyIHRoZSBhcHByb3ByaWF0ZSBkZXNjcmlwdGlvbiBrZXkgZm9yIGEgY2xhc3Mgb3IgaXRzIHByb3BlcnR5LlxuICogQHBhcmFtIHtzdHJpbmd9IGRlc2MgVGhlIGRlc2NyaXB0aXZlIHRleHQgdG8gYXNzb2NpYXRlIHdpdGggdGhlIGNsYXNzIG9yIHByb3BlcnR5XG4gKiBAcmV0dXJuIEEgZGVjb3JhdG9yIHRoYXQgcmVjb3JkcyB0aGUgZGVzY3JpcHRpb24gd2hlbiBhcHBsaWVkXG4gKiBAZnVuY3Rpb24gZGVzY3JpcHRpb25cbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXNjcmlwdGlvbihkZXNjOiBzdHJpbmcpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGRlc2NyaXB0aW9uKG9yaWdpbmFsOiBhbnksIHByb3A6IGFueSwgZGVzY3JpcHRvcj86IGFueSkge1xuICAgIHJldHVybiBtZXRhZGF0YShcbiAgICAgIFtcbiAgICAgICAgRGVjb3JhdGlvbktleXMuREVTQ1JJUFRJT04sXG4gICAgICAgIHByb3AgPyBwcm9wLnRvU3RyaW5nKCkgOiBEZWNvcmF0aW9uS2V5cy5DTEFTUyxcbiAgICAgIF0uam9pbihPYmplY3RLZXlTcGxpdHRlciksXG4gICAgICBkZXNjXG4gICAgKShvcmlnaW5hbCwgcHJvcCwgZGVzY3JpcHRvcik7XG4gIH07XG59XG4iLCIvKipcbiAqIEBkZXNjcmlwdGlvbiBSb290IGVudHJ5IHBvaW50IGZvciB0aGUgZGVjb3JhdGlvbiBtb2R1bGVcbiAqIEBzdW1tYXJ5IEFnZ3JlZ2F0ZXMgYW5kIHJlLWV4cG9ydHMgdGhlIHB1YmxpYyBBUEkgb2YgdGhlIGRlY29yYXRpb24gbGlicmFyeSwgaW5jbHVkaW5nIGNvcmUgY2xhc3NlcyBsaWtlIHtAbGluayBEZWNvcmF0aW9ufSwgdXRpbGl0eSBkZWNvcmF0b3JzLCBtZXRhZGF0YSBoZWxwZXJzLCBhbmQgY29uc3RhbnRzLiBUaGlzIG1vZHVsZSBpcyB0aGUgcHJpbWFyeSBpbXBvcnQgc3VyZmFjZSBmb3IgY29uc3VtZXJzIGFuZCBleHBvc2VzOlxuICogLSBDb3JlIGJ1aWxkZXI6IHtAbGluayBEZWNvcmF0aW9ufVxuICogLSBEZWNvcmF0b3IgdXRpbGl0aWVzOiB7QGxpbmsgbW9kdWxlOmRlY29yYXRpb24gfCBkZWNvcmF0b3JzIGluIC4vZGVjb3JhdG9yc31cbiAqIC0gTWV0YWRhdGEgdXRpbGl0aWVzOiB7QGxpbmsgTWV0YWRhdGF9XG4gKiAtIENvbnN0YW50cyBhbmQgZW51bXM6IHtAbGluayBEZWNvcmF0aW9uS2V5c30sIHtAbGluayBEZWZhdWx0Rmxhdm91cn1cbiAqXG4gKiBAbW9kdWxlIGRlY29yYXRpb25cbiAqL1xuXG5pbXBvcnQgeyBNZXRhZGF0YSB9IGZyb20gXCIuL21ldGFkYXRhL2luZGV4XCI7XG5cbmV4cG9ydCAqIGZyb20gXCIuL2RlY29yYXRpb25cIjtcbmV4cG9ydCAqIGZyb20gXCIuL21ldGFkYXRhXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2RlY29yYXRvcnNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ3VycmVudCB2ZXJzaW9uIG9mIHRoZSByZWZsZWN0aW9uIHBhY2thZ2VcbiAqIEBzdW1tYXJ5IFN0b3JlcyB0aGUgc2VtYW50aWMgdmVyc2lvbiBudW1iZXIgb2YgdGhlIHBhY2thZ2VcbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRpb25cbiAqL1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG5cbk1ldGFkYXRhLnJlZ2lzdGVyTGlicmFyeShcIkBkZWNhZi10cy9kZWNvcmF0aW9uXCIsIFZFUlNJT04pO1xuIl0sIm5hbWVzIjpbIkRlY29yYXRpb25LZXlzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7SUFFQTs7Ozs7O0lBTUc7QUFDSSxVQUFNLGNBQWMsR0FBRztJQUU5Qjs7Ozs7SUFLRztBQUNJLFVBQU0saUJBQWlCLEdBQUc7SUFFakM7Ozs7Ozs7OztJQVNHO0FBQ1NBO0lBQVosQ0FBQSxV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