footprintjs 9.44.0 → 9.44.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CLAUDE.md +6 -5
  2. package/dist/esm/lib/capture/freeze.d.ts +51 -7
  3. package/dist/esm/lib/capture/freeze.js +289 -24
  4. package/dist/esm/lib/capture/valueKinds.d.ts +57 -0
  5. package/dist/esm/lib/capture/valueKinds.js +142 -0
  6. package/dist/esm/lib/memory/EventLog.d.ts +24 -6
  7. package/dist/esm/lib/memory/EventLog.js +30 -10
  8. package/dist/esm/lib/memory/admission.js +4 -3
  9. package/dist/esm/lib/memory/borrowedMutation.js +2 -2
  10. package/dist/esm/lib/memory/equality.d.ts +55 -19
  11. package/dist/esm/lib/memory/equality.js +154 -51
  12. package/dist/esm/lib/memory/logModel.js +11 -4
  13. package/dist/esm/lib/memory/redaction.d.ts +21 -0
  14. package/dist/esm/lib/memory/redaction.js +64 -7
  15. package/dist/esm/lib/runner/ExecutionRuntime.d.ts +4 -1
  16. package/dist/esm/lib/runner/ExecutionRuntime.js +15 -10
  17. package/dist/esm/lib/runner/snapshot.js +17 -3
  18. package/dist/esm/lib/slice/elementProvenance.js +2 -2
  19. package/dist/esm/lib/time-travel/chain.js +28 -26
  20. package/dist/lib/capture/freeze.js +292 -25
  21. package/dist/lib/capture/valueKinds.js +146 -0
  22. package/dist/lib/memory/EventLog.js +29 -9
  23. package/dist/lib/memory/admission.js +4 -3
  24. package/dist/lib/memory/borrowedMutation.js +2 -2
  25. package/dist/lib/memory/equality.js +154 -51
  26. package/dist/lib/memory/logModel.js +11 -4
  27. package/dist/lib/memory/redaction.js +66 -8
  28. package/dist/lib/runner/ExecutionRuntime.js +14 -9
  29. package/dist/lib/runner/snapshot.js +16 -2
  30. package/dist/lib/slice/elementProvenance.js +2 -2
  31. package/dist/lib/time-travel/chain.js +27 -25
  32. package/dist/types/lib/capture/freeze.d.ts +51 -7
  33. package/dist/types/lib/capture/valueKinds.d.ts +57 -0
  34. package/dist/types/lib/memory/EventLog.d.ts +24 -6
  35. package/dist/types/lib/memory/equality.d.ts +55 -19
  36. package/dist/types/lib/memory/redaction.d.ts +21 -0
  37. package/dist/types/lib/runner/ExecutionRuntime.d.ts +4 -1
  38. package/package.json +2 -1
@@ -1,38 +1,57 @@
1
1
  "use strict";
2
2
  /**
3
- * equality.ts — structural equality of committed-state values. A leaf (L0,
4
- * imports nothing): what `TransactionBuffer`'s net-change filter, the admitted
5
- * record's compare and the borrowed-mutation guard all ask. Re-exported from
6
- * `utils.ts`, so no importer moved.
3
+ * equality.ts — structural equality of committed-state values: THE owner of
4
+ * "what counts as a change". What `TransactionBuffer`'s net-change filter, the
5
+ * admitted record's compare, the read model's writer rule and the
6
+ * borrowed-mutation guard all ask. Its one import is the classifier of value
7
+ * kinds (`capture/valueKinds.ts`, a leaf); re-exported from `utils.ts`, so no
8
+ * importer moved.
7
9
  */
8
10
  Object.defineProperty(exports, "__esModule", { value: true });
9
11
  exports.deepEqual = void 0;
12
+ const valueKinds_js_1 = require("../capture/valueKinds.js");
10
13
  /**
11
14
  * Structural deep equality for committed-state values.
12
15
  *
13
16
  * Used by {@link TransactionBuffer} to decide whether a stage actually CHANGED
14
17
  * a path or merely re-wrote / reverted it to the value it already held (a
15
18
  * "no-op write"), and by `borrowedMutation.firstDifferingPath` to find where a
16
- * borrowed read moved. Committed state must survive `structuredClone`, and
17
- * `structuredClone` keeps `Date`, `Map` and `Set` — so those are legal state
18
- * values (a `$setValue` bypasses the proxy's JSON round-trip) and this must
19
- * tell two of them apart. Before 9.22.0 it compared them as plain objects, and
20
- * a `Date`/`Map`/`Set` has no own enumerable keys: every pair was "equal", so
21
- * `$setValue('k', new Date(1999))` over a 2020 date was dropped as a no-op —
22
- * no trace row, state unchanged — and a `setFullYear` in place slipped past
23
- * the dev-mode guard.
19
+ * borrowed read moved. Committed state must survive `structuredClone`, so the
20
+ * values it can hold are the kinds the clone keeps, and two values are equal
21
+ * when a record holds the same thing for both. Every kind has ONE arm below
22
+ * (`equalPairs`' switch over `ValueKind` — a kind added to the union does not
23
+ * compile until it is compared). Before 9.22.0 a Date, Map or Set was compared
24
+ * as an object with no own keys, and until 9.44.2 so were a RegExp, an Error,
25
+ * a boxed primitive, an ArrayBuffer, a DataView and a Blob: any two of a kind
26
+ * were "equal", so `$setValue('re', /y/g)` over `/x/g` committed no row and
27
+ * live state kept the OLD value.
24
28
  *
25
29
  * Semantics:
26
30
  * - reference / identical-primitive short-circuits first (cheap fast path)
27
31
  * - `NaN` equals `NaN` (primitive compare falls back to `Object.is`)
32
+ * - two values of different KINDS are never equal (a `Date` is never `{}`,
33
+ * an array never `{ 0: … }`)
28
34
  * - `Date`: same `getTime()` (two invalid dates are equal)
35
+ * - `RegExp`: same `source` and `flags` (the clone resets `lastIndex`)
36
+ * - `Error`: the same restored kind (one of the six built-in error names,
37
+ * else `Error`), own `message`, `stack` and own `cause` (deep) — what the
38
+ * clone keeps; any other own field is dropped by it, so it never counts
39
+ * (the admitted record's law)
40
+ * - a boxed primitive: the same wrapper type and the same primitive inside
41
+ * - an `ArrayBuffer`: length, resizability and bytes; a typed array or a
42
+ * `DataView`: its type and the bytes IT views — never the rest of its
43
+ * buffer (a Node `Buffer` views a slice of a shared pool, and the record
44
+ * keeps the view's bytes only: `capture/freeze.ts · freezeRecord`)
29
45
  * - `Map`: same size AND, per key of `a`, `b` holds a deep-equal value —
30
46
  * keys by `Map` identity (`SameValueZero`), values deep
31
47
  * - `Set`: same size AND every member of `a` is deep-equal to SOME member
32
48
  * of `b` (order-insensitive — a Set has no order to compare by)
33
- * - a typed value against a plain value, or two different typed kinds → not
34
- * equal (a `Date` is never `{}`)
35
- * - arrays: equal length AND deep-equal element-wise (order-sensitive)
49
+ * - an OPAQUE value (a Blob, a `DOMException` — content this library cannot
50
+ * read): by the caller's {@link OpaqueRule} — equal only to itself by
51
+ * default (replacing one is always a change), or, when both sides are
52
+ * copies of one record, equal to any other of its kind
53
+ * - arrays: equal length AND deep-equal element-wise (order-sensitive; an
54
+ * array's expando keys are out of contract and not compared)
36
55
  * - objects: identical set of keys that HOLD a value AND deep-equal per key.
37
56
  * An own key whose value is `undefined` counts as ABSENT: it is this
38
57
  * library's other spelling of a deleted key (`'full'` mode flattens
@@ -41,11 +60,13 @@ exports.deepEqual = void 0;
41
60
  * mirror — reads the two spellings as one state. So must the net-change
42
61
  * filter (9.19.1): `{}` and `{ k: undefined }` are not a change. Arrays
43
62
  * are untouched — a slot holding `undefined` is still a slot.
44
- * - mismatched kinds (array vs object, object vs null) → not equal
45
63
  *
46
64
  * Cost & safety:
47
- * - Allocates NOTHING but transient `Object.keys` arrays — no clones. It is
48
- * strictly cheaper than the `structuredClone` the commit already performs.
65
+ * - Allocates only transient `Object.keys` arrays, an error's property
66
+ * descriptors and a byte view per compared buffer — no clones (but one
67
+ * probe clone per class prototype, remembered: `capture/valueKinds.ts ·
68
+ * kindOf`). It is strictly cheaper than the `structuredClone` the commit
69
+ * already performs.
49
70
  * - Primitive comparisons (the bulk of state) are O(1) via the `===` /
50
71
  * `Object.is` fast paths; only nested objects/arrays incur a walk, bounded
51
72
  * by the value's own size.
@@ -57,11 +78,11 @@ exports.deepEqual = void 0;
57
78
  * change. Dev mode still warns about cycles at write time
58
79
  * (`ScopeFacade.setValue`) because they surprise narrative and JSON.
59
80
  */
60
- function deepEqual(a, b) {
61
- return equalPairs(a, b, undefined);
81
+ function deepEqual(a, b, opaque = 'identity') {
82
+ return equalPairs(a, b, undefined, opaque);
62
83
  }
63
84
  exports.deepEqual = deepEqual;
64
- function equalPairs(a, b, seen) {
85
+ function equalPairs(a, b, seen, opaque) {
65
86
  if (a === b)
66
87
  return true; // same reference or identical primitive
67
88
  if (typeof a !== typeof b)
@@ -70,16 +91,35 @@ function equalPairs(a, b, seen) {
70
91
  return a === b; // one is null, the other isn't
71
92
  if (typeof a !== 'object')
72
93
  return Object.is(a, b); // NaN-safe primitive compare
73
- // Typed arms first — a Date/Map/Set has no own enumerable keys, so the
74
- // plain-object walk below would call any two of them equal.
75
- const aKind = typedKind(a);
76
- if (aKind !== typedKind(b))
94
+ const kind = (0, valueKinds_js_1.kindOf)(a);
95
+ if (kind !== (0, valueKinds_js_1.kindOf)(b))
77
96
  return false;
78
- if (aKind === 'date')
79
- return Object.is(a.getTime(), b.getTime());
80
- const aIsArray = Array.isArray(a);
81
- if (aIsArray !== Array.isArray(b))
82
- return false; // array vs plain object
97
+ switch (kind) {
98
+ // Atoms: their content is a slot, not their keys.
99
+ case 'date':
100
+ return Object.is(Date.prototype.getTime.call(a), Date.prototype.getTime.call(b));
101
+ case 'regexp':
102
+ return a.source === b.source && a.flags === b.flags;
103
+ case 'boxed':
104
+ return tagOf(a) === tagOf(b) && equalPairs(a.valueOf(), b.valueOf(), seen, opaque);
105
+ case 'buffer':
106
+ return equalBuffers(a, b);
107
+ case 'view':
108
+ return equalViews(a, b);
109
+ case 'opaque':
110
+ return opaque === 'copies' && tagOf(a) === tagOf(b); // `a === b` was answered above
111
+ case 'plain':
112
+ case 'array':
113
+ case 'map':
114
+ case 'set':
115
+ case 'error':
116
+ return equalContainers(a, b, kind, seen, opaque);
117
+ default:
118
+ return unknownKind(kind);
119
+ }
120
+ }
121
+ /** The kinds whose content is other values: compared part by part, under the cycle guard. */
122
+ function equalContainers(a, b, kind, seen, opaque) {
83
123
  // Cycle guard — a pair we are already inside is equal by assumption.
84
124
  seen ??= new WeakMap();
85
125
  let partners = seen.get(a);
@@ -88,15 +128,17 @@ function equalPairs(a, b, seen) {
88
128
  if (!partners)
89
129
  seen.set(a, (partners = new WeakSet()));
90
130
  partners.add(b);
91
- if (aKind === 'map')
92
- return equalMaps(a, b, seen);
93
- if (aKind === 'set')
94
- return equalSets(a, b, seen);
95
- if (aIsArray) {
131
+ if (kind === 'map')
132
+ return equalMaps(a, b, seen, opaque);
133
+ if (kind === 'set')
134
+ return equalSets(a, b, seen, opaque);
135
+ if (kind === 'error')
136
+ return equalErrors(a, b, seen, opaque);
137
+ if (kind === 'array') {
96
138
  if (a.length !== b.length)
97
139
  return false;
98
140
  for (let i = 0; i < a.length; i++) {
99
- if (!equalPairs(a[i], b[i], seen))
141
+ if (!equalPairs(a[i], b[i], seen, opaque))
100
142
  return false;
101
143
  }
102
144
  return true;
@@ -110,7 +152,7 @@ function equalPairs(a, b, seen) {
110
152
  aHeld++;
111
153
  if (!Object.prototype.hasOwnProperty.call(b, key))
112
154
  return false;
113
- if (!equalPairs(a[key], b[key], seen))
155
+ if (!equalPairs(a[key], b[key], seen, opaque))
114
156
  return false;
115
157
  }
116
158
  let bHeld = 0;
@@ -119,23 +161,84 @@ function equalPairs(a, b, seen) {
119
161
  bHeld++;
120
162
  return aHeld === bHeld;
121
163
  }
122
- /** The typed state values `structuredClone` keeps and a key walk cannot see. */
123
- function typedKind(value) {
124
- if (value instanceof Date)
125
- return 'date';
126
- if (value instanceof Map)
127
- return 'map';
128
- if (value instanceof Set)
129
- return 'set';
130
- return undefined;
164
+ function unknownKind(kind) {
165
+ throw new TypeError(`deepEqual: no comparison for the value kind '${String(kind)}'`);
166
+ }
167
+ /** `[object Number]`, `[object Uint8Array]` … — the built-in type a boxed value or a view carries. */
168
+ function tagOf(value) {
169
+ return Object.prototype.toString.call(value);
170
+ }
171
+ /** The same view type over the same bytes — the bytes the view sees, wherever they sit in its buffer. */
172
+ function equalViews(a, b) {
173
+ if (tagOf(a) !== tagOf(b) || a.byteLength !== b.byteLength)
174
+ return false;
175
+ if (a.buffer === b.buffer && a.byteOffset === b.byteOffset)
176
+ return true;
177
+ const p = new Uint8Array(a.buffer, a.byteOffset, a.byteLength);
178
+ const q = new Uint8Array(b.buffer, b.byteOffset, b.byteLength);
179
+ for (let i = 0; i < p.length; i++)
180
+ if (p[i] !== q[i])
181
+ return false;
182
+ return true;
183
+ }
184
+ /** The same length, resizability and bytes. */
185
+ function equalBuffers(a, b) {
186
+ if (a === b)
187
+ return true;
188
+ const x = a;
189
+ const y = b;
190
+ if (x.byteLength !== y.byteLength || x.resizable !== y.resizable || x.maxByteLength !== y.maxByteLength) {
191
+ return false;
192
+ }
193
+ const p = new Uint8Array(a);
194
+ const q = new Uint8Array(b);
195
+ for (let i = 0; i < p.length; i++)
196
+ if (p[i] !== q[i])
197
+ return false;
198
+ return true;
199
+ }
200
+ /** The six error names `structuredClone` restores; any other name comes back an `Error`. */
201
+ const ERROR_NAMES = new Set(['EvalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError']);
202
+ /**
203
+ * Two errors as the clone keeps them: the restored kind, the own `message`,
204
+ * the `stack` and the own `cause` (deep). Any other own field is dropped by
205
+ * the clone, so it never counts.
206
+ */
207
+ function equalErrors(a, b, seen, opaque) {
208
+ if (errorKindOf(a) !== errorKindOf(b) || stackOf(a) !== stackOf(b))
209
+ return false;
210
+ const aMessage = ownData(a, 'message');
211
+ const bMessage = ownData(b, 'message');
212
+ if (String(aMessage?.value) !== String(bMessage?.value) || !aMessage !== !bMessage)
213
+ return false;
214
+ const aCause = ownData(a, 'cause');
215
+ const bCause = ownData(b, 'cause');
216
+ if (!aCause || !bCause)
217
+ return !aCause === !bCause;
218
+ return equalPairs(aCause.value, bCause.value, seen, opaque);
219
+ }
220
+ function errorKindOf(error) {
221
+ const name = String(error.name);
222
+ return ERROR_NAMES.has(name) ? name : 'Error';
223
+ }
224
+ function stackOf(error) {
225
+ const stack = error.stack;
226
+ return typeof stack === 'string' ? stack : undefined;
227
+ }
228
+ /** An own DATA property, boxed — how the clone reads an error's `message` and `cause`. */
229
+ function ownData(value, key) {
230
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
231
+ return descriptor !== undefined && Object.prototype.hasOwnProperty.call(descriptor, 'value')
232
+ ? { value: descriptor.value }
233
+ : undefined;
131
234
  }
132
- function equalMaps(a, b, seen) {
235
+ function equalMaps(a, b, seen, opaque) {
133
236
  if (a.size !== b.size)
134
237
  return false;
135
238
  for (const [key, value] of a) {
136
239
  if (!b.has(key))
137
240
  return false;
138
- if (!equalPairs(value, b.get(key), seen))
241
+ if (!equalPairs(value, b.get(key), seen, opaque))
139
242
  return false;
140
243
  }
141
244
  return true;
@@ -144,7 +247,7 @@ function equalMaps(a, b, seen) {
144
247
  * Order-insensitive, deep per member. Quadratic in the worst case for sets of
145
248
  * objects — a set of primitives (the common shape) is one `has` per member.
146
249
  */
147
- function equalSets(a, b, seen) {
250
+ function equalSets(a, b, seen, opaque) {
148
251
  if (a.size !== b.size)
149
252
  return false;
150
253
  const unmatched = [...b];
@@ -153,11 +256,11 @@ function equalSets(a, b, seen) {
153
256
  // Each match retires its slot so two structurally-equal members of `a`
154
257
  // cannot both claim the same member of `b`.
155
258
  const at = unmatched.indexOf(member);
156
- const found = at >= 0 ? at : unmatched.findIndex((candidate) => equalPairs(member, candidate, seen));
259
+ const found = at >= 0 ? at : unmatched.findIndex((candidate) => equalPairs(member, candidate, seen, opaque));
157
260
  if (found < 0)
158
261
  return false;
159
262
  unmatched.splice(found, 1);
160
263
  }
161
264
  return true;
162
265
  }
163
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXF1YWxpdHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL21lbW9yeS9lcXVhbGl0eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7O0dBS0c7OztBQUVIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaURHO0FBQ0gsU0FBZ0IsU0FBUyxDQUFDLENBQU0sRUFBRSxDQUFNO0lBQ3RDLE9BQU8sVUFBVSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFDckMsQ0FBQztBQUZELDhCQUVDO0FBV0QsU0FBUyxVQUFVLENBQUMsQ0FBTSxFQUFFLENBQU0sRUFBRSxJQUEyQjtJQUM3RCxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUMsQ0FBQyx3Q0FBd0M7SUFDbEUsSUFBSSxPQUFPLENBQUMsS0FBSyxPQUFPLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUN4QyxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUk7UUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQywrQkFBK0I7SUFDN0UsSUFBSSxPQUFPLENBQUMsS0FBSyxRQUFRO1FBQUUsT0FBTyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLDZCQUE2QjtJQUVoRix1RUFBdUU7SUFDdkUsNERBQTREO0lBQzVELE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMzQixJQUFJLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDekMsSUFBSSxLQUFLLEtBQUssTUFBTTtRQUFFLE9BQU8sTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENB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Q0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBlcXVhbGl0eS50cyDigJQgc3RydWN0dXJhbCBlcXVhbGl0eSBvZiBjb21taXR0ZWQtc3RhdGUgdmFsdWVzLiBBIGxlYWYgKEwwLFxuICogaW1wb3J0cyBub3RoaW5nKTogd2hhdCBgVHJhbnNhY3Rpb25CdWZmZXJgJ3MgbmV0LWNoYW5nZSBmaWx0ZXIsIHRoZSBhZG1pdHRlZFxuICogcmVjb3JkJ3MgY29tcGFyZSBhbmQgdGhlIGJvcnJvd2VkLW11dGF0aW9uIGd1YXJkIGFsbCBhc2suIFJlLWV4cG9ydGVkIGZyb21cbiAqIGB1dGlscy50c2AsIHNvIG5vIGltcG9ydGVyIG1vdmVkLlxuICovXG5cbi8qKlxuICogU3RydWN0dXJhbCBkZWVwIGVxdWFsaXR5IGZvciBjb21taXR0ZWQtc3RhdGUgdmFsdWVzLlxuICpcbiAqIFVzZWQgYnkge0BsaW5rIFRyYW5zYWN0aW9uQnVmZmVyfSB0byBkZWNpZGUgd2hldGhlciBhIHN0YWdlIGFjdHVhbGx5IENIQU5HRURcbiAqIGEgcGF0aCBvciBtZXJlbHkgcmUtd3JvdGUgLyByZXZlcnRlZCBpdCB0byB0aGUgdmFsdWUgaXQgYWxyZWFkeSBoZWxkIChhXG4gKiBcIm5vLW9wIHdyaXRlXCIpLCBhbmQgYnkgYGJvcnJvd2VkTXV0YXRpb24uZmlyc3REaWZmZXJpbmdQYXRoYCB0byBmaW5kIHdoZXJlIGFcbiAqIGJvcnJvd2VkIHJlYWQgbW92ZWQuIENvbW1pdHRlZCBzdGF0ZSBtdXN0IHN1cnZpdmUgYHN0cnVjdHVyZWRDbG9uZWAsIGFuZFxuICogYHN0cnVjdHVyZWRDbG9uZWAga2VlcHMgYERhdGVgLCBgTWFwYCBhbmQgYFNldGAg4oCUIHNvIHRob3NlIGFyZSBsZWdhbCBzdGF0ZVxuICogdmFsdWVzIChhIGAkc2V0VmFsdWVgIGJ5cGFzc2VzIHRoZSBwcm94eSdzIEpTT04gcm91bmQtdHJpcCkgYW5kIHRoaXMgbXVzdFxuICogdGVsbCB0d28gb2YgdGhlbSBhcGFydC4gQmVmb3JlIDkuMjIuMCBpdCBjb21wYXJlZCB0aGVtIGFzIHBsYWluIG9iamVjdHMsIGFuZFxuICogYSBgRGF0ZWAvYE1hcGAvYFNldGAgaGFzIG5vIG93biBlbnVtZXJhYmxlIGtleXM6IGV2ZXJ5IHBhaXIgd2FzIFwiZXF1YWxcIiwgc29cbiAqIGAkc2V0VmFsdWUoJ2snLCBuZXcgRGF0ZSgxOTk5KSlgIG92ZXIgYSAyMDIwIGRhdGUgd2FzIGRyb3BwZWQgYXMgYSBuby1vcCDigJRcbiAqIG5vIHRyYWNlIHJvdywgc3RhdGUgdW5jaGFuZ2VkIOKAlCBhbmQgYSBgc2V0RnVsbFllYXJgIGluIHBsYWNlIHNsaXBwZWQgcGFzdFxuICogdGhlIGRldi1tb2RlIGd1YXJkLlxuICpcbiAqIFNlbWFudGljczpcbiAqICAgLSByZWZlcmVuY2UgLyBpZGVudGljYWwtcHJpbWl0aXZlIHNob3J0LWNpcmN1aXRzIGZpcnN0IChjaGVhcCBmYXN0IHBhdGgpXG4gKiAgIC0gYE5hTmAgZXF1YWxzIGBOYU5gIChwcmltaXRpdmUgY29tcGFyZSBmYWxscyBiYWNrIHRvIGBPYmplY3QuaXNgKVxuICogICAtIGBEYXRlYDogc2FtZSBgZ2V0VGltZSgpYCAodHdvIGludmFsaWQgZGF0ZXMgYXJlIGVxdWFsKVxuICogICAtIGBNYXBgOiBzYW1lIHNpemUgQU5ELCBwZXIga2V5IG9mIGBhYCwgYGJgIGhvbGRzIGEgZGVlcC1lcXVhbCB2YWx1ZSDigJRcbiAqICAgICBrZXlzIGJ5IGBNYXBgIGlkZW50aXR5IChgU2FtZVZhbHVlWmVyb2ApLCB2YWx1ZXMgZGVlcFxuICogICAtIGBTZXRgOiBzYW1lIHNpemUgQU5EIGV2ZXJ5IG1lbWJlciBvZiBgYWAgaXMgZGVlcC1lcXVhbCB0byBTT01FIG1lbWJlclxuICogICAgIG9mIGBiYCAob3JkZXItaW5zZW5zaXRpdmUg4oCUIGEgU2V0IGhhcyBubyBvcmRlciB0byBjb21wYXJlIGJ5KVxuICogICAtIGEgdHlwZWQgdmFsdWUgYWdhaW5zdCBhIHBsYWluIHZhbHVlLCBvciB0d28gZGlmZmVyZW50IHR5cGVkIGtpbmRzIOKGkiBub3RcbiAqICAgICBlcXVhbCAoYSBgRGF0ZWAgaXMgbmV2ZXIgYHt9YClcbiAqICAgLSBhcnJheXM6IGVxdWFsIGxlbmd0aCBBTkQgZGVlcC1lcXVhbCBlbGVtZW50LXdpc2UgKG9yZGVyLXNlbnNpdGl2ZSlcbiAqICAgLSBvYmplY3RzOiBpZGVudGljYWwgc2V0IG9mIGtleXMgdGhhdCBIT0xEIGEgdmFsdWUgQU5EIGRlZXAtZXF1YWwgcGVyIGtleS5cbiAqICAgICBBbiBvd24ga2V5IHdob3NlIHZhbHVlIGlzIGB1bmRlZmluZWRgIGNvdW50cyBhcyBBQlNFTlQ6IGl0IGlzIHRoaXNcbiAqICAgICBsaWJyYXJ5J3Mgb3RoZXIgc3BlbGxpbmcgb2YgYSBkZWxldGVkIGtleSAoYCdmdWxsJ2AgbW9kZSBmbGF0dGVuc1xuICogICAgIGBkZWxldGVgIGludG8gYGtleTogdW5kZWZpbmVkYDsgYCdkZWx0YSdgIG1vZGUncyBgZGVsZXRlYCB2ZXJiIHJlbW92ZXNcbiAqICAgICB0aGUga2V5KSwgYW5kIGV2ZXJ5IGNvbnN1bWVyIOKAlCBKU09OLCB0aGUgZm9sZCwgYGNvbW1pdFZhbHVlQXRgLCB0aGVcbiAqICAgICBtaXJyb3Ig4oCUIHJlYWRzIHRoZSB0d28gc3BlbGxpbmdzIGFzIG9uZSBzdGF0ZS4gU28gbXVzdCB0aGUgbmV0LWNoYW5nZVxuICogICAgIGZpbHRlciAoOS4xOS4xKTogYHt9YCBhbmQgYHsgazogdW5kZWZpbmVkIH1gIGFyZSBub3QgYSBjaGFuZ2UuIEFycmF5c1xuICogICAgIGFyZSB1bnRvdWNoZWQg4oCUIGEgc2xvdCBob2xkaW5nIGB1bmRlZmluZWRgIGlzIHN0aWxsIGEgc2xvdC5cbiAqICAgLSBtaXNtYXRjaGVkIGtpbmRzIChhcnJheSB2cyBvYmplY3QsIG9iamVjdCB2cyBudWxsKSDihpIgbm90IGVxdWFsXG4gKlxuICogQ29zdCAmIHNhZmV0eTpcbiAqICAgLSBBbGxvY2F0ZXMgTk9USElORyBidXQgdHJhbnNpZW50IGBPYmplY3Qua2V5c2AgYXJyYXlzIOKAlCBubyBjbG9uZXMuIEl0IGlzXG4gKiAgICAgc3RyaWN0bHkgY2hlYXBlciB0aGFuIHRoZSBgc3RydWN0dXJlZENsb25lYCB0aGUgY29tbWl0IGFscmVhZHkgcGVyZm9ybXMuXG4gKiAgIC0gUHJpbWl0aXZlIGNvbXBhcmlzb25zICh0aGUgYnVsayBvZiBzdGF0ZSkgYXJlIE8oMSkgdmlhIHRoZSBgPT09YCAvXG4gKiAgICAgYE9iamVjdC5pc2AgZmFzdCBwYXRoczsgb25seSBuZXN0ZWQgb2JqZWN0cy9hcnJheXMgaW5jdXIgYSB3YWxrLCBib3VuZGVkXG4gKiAgICAgYnkgdGhlIHZhbHVlJ3Mgb3duIHNpemUuXG4gKiAgIC0gVGVybWluYXRlcyBvbiBDWUNMSUMgdmFsdWVzICg5LjE4LjEpOiBhIHN0YXRlIHZhbHVlIG11c3Qgc3Vydml2ZVxuICogICAgIGBzdHJ1Y3R1cmVkQ2xvbmVgLCBhbmQgYHN0cnVjdHVyZWRDbG9uZWAgcHJlc2VydmVzIGN5Y2xlcyDigJQgc28gYVxuICogICAgIHNlbGYtcmVmZXJlbmNpbmcgdmFsdWUgaXMgYSBsZWdhbCB2YWx1ZSwgbm90IGFuIG91dC1vZi1jb250cmFjdCBvbmUuIEFcbiAqICAgICBwYWlyIG9mIG9iamVjdHMgYWxyZWFkeSB1bmRlciBjb21wYXJpc29uIGlzIHRyZWF0ZWQgYXMgZXF1YWwgKHRoZVxuICogICAgIHN0cnVjdHVyYWwgYW5zd2VyLCBsb2Rhc2ggYGlzRXF1YWxgIHNlbWFudGljcyk7IGFjeWNsaWMgaW5wdXRzIHNlZSBub1xuICogICAgIGNoYW5nZS4gRGV2IG1vZGUgc3RpbGwgd2FybnMgYWJvdXQgY3ljbGVzIGF0IHdyaXRlIHRpbWVcbiAqICAgICAoYFNjb3BlRmFjYWRlLnNldFZhbHVlYCkgYmVjYXVzZSB0aGV5IHN1cnByaXNlIG5hcnJhdGl2ZSBhbmQgSlNPTi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZXBFcXVhbChhOiBhbnksIGI6IGFueSk6IGJvb2xlYW4ge1xuICByZXR1cm4gZXF1YWxQYWlycyhhLCBiLCB1bmRlZmluZWQpO1xufVxuXG4vKipcbiAqIE9iamVjdCBwYWlycyBtZXQgc28gZmFyLCBrZXllZCBgYSDihpIgdGhlIGIncyBpdCBoYXMgYmVlbiBwYWlyZWQgd2l0aGAuIENyZWF0ZWRcbiAqIGxhemlseSBieSB0aGUgZmlyc3Qgb2JqZWN0IHBhaXIsIHNvIHByaW1pdGl2ZSBjb21wYXJlcyBhbGxvY2F0ZSBub3RoaW5nLlxuICogTmV2ZXIgcHJ1bmVkOiBldmVyeSBgZmFsc2VgIHJldHVybnMgc3RyYWlnaHQgdXAgdG8gdGhlIGNhbGxlciAoZWFjaCByZWN1cnNpdmVcbiAqIGNhbGwgc2hvcnQtY2lyY3VpdHMgb24gaXQpLCBzbyBub3RoaW5nIGlzIGxvb2tlZCB1cCBhZnRlciBhIG1pc21hdGNoIOKAlCBhXG4gKiBzdG9yZWQgcGFpciBpcyBlaXRoZXIgc3RpbGwgdW5kZXIgY29tcGFyaXNvbiBvciBhbHJlYWR5IGtub3duIGVxdWFsLlxuICovXG50eXBlIFNlZW5QYWlycyA9IFdlYWtNYXA8b2JqZWN0LCBXZWFrU2V0PG9iamVjdD4+O1xuXG5mdW5jdGlvbiBlcXVhbFBhaXJzKGE6IGFueSwgYjogYW55LCBzZWVuOiBTZWVuUGFpcnMgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgaWYgKGEgPT09IGIpIHJldHVybiB0cnVlOyAvLyBzYW1lIHJlZmVyZW5jZSBvciBpZGVudGljYWwgcHJpbWl0aXZlXG4gIGlmICh0eXBlb2YgYSAhPT0gdHlwZW9mIGIpIHJldHVybiBmYWxzZTtcbiAgaWYgKGEgPT09IG51bGwgfHwgYiA9PT0gbnVsbCkgcmV0dXJuIGEgPT09IGI7IC8vIG9uZSBpcyBudWxsLCB0aGUgb3RoZXIgaXNuJ3RcbiAgaWYgKHR5cGVvZiBhICE9PSAnb2JqZWN0JykgcmV0dXJuIE9iamVjdC5pcyhhLCBiKTsgLy8gTmFOLXNhZmUgcHJpbWl0aXZlIGNvbXBhcmVcblxuICAvLyBUeXBlZCBhcm1zIGZpcnN0IOKAlCBhIERhdGUvTWFwL1NldCBoYXMgbm8gb3duIGVudW1lcmFibGUga2V5cywgc28gdGhlXG4gIC8vIHBsYWluLW9iamVjdCB3YWxrIGJlbG93IHdvdWxkIGNhbGwgYW55IHR3byBvZiB0aGVtIGVxdWFsLlxuICBjb25zdCBhS2luZCA9IHR5cGVkS2luZChhKTtcbiAgaWYgKGFLaW5kICE9PSB0eXBlZEtpbmQoYikpIHJldHVybiBmYWxzZTtcbiAgaWYgKGFLaW5kID09PSAnZGF0ZScpIHJldHVybiBPYmplY3QuaXMoYS5nZXRUaW1lKCksIGIuZ2V0VGltZSgpKTtcblxuICBjb25zdCBhSXNBcnJheSA9IEFycmF5LmlzQXJyYXkoYSk7XG4gIGlmIChhSXNBcnJheSAhPT0gQXJyYXkuaXNBcnJheShiKSkgcmV0dXJuIGZhbHNlOyAvLyBhcnJheSB2cyBwbGFpbiBvYmplY3RcblxuICAvLyBDeWNsZSBndWFyZCDigJQgYSBwYWlyIHdlIGFyZSBhbHJlYWR5IGluc2lkZSBpcyBlcXVhbCBieSBhc3N1bXB0aW9uLlxuICBzZWVuID8/PSBuZXcgV2Vha01hcCgpO1xuICBsZXQgcGFydG5lcnMgPSBzZWVuLmdldChhKTtcbiAgaWYgKHBhcnRuZXJzPy5oYXMoYikpIHJldHVybiB0cnVlO1xuICBpZiAoIXBhcnRuZXJzKSBzZWVuLnNldChhLCAocGFydG5lcnMgPSBuZXcgV2Vha1NldCgpKSk7XG4gIHBhcnRuZXJzLmFkZChiKTtcblxuICBpZiAoYUtpbmQgPT09ICdtYXAnKSByZXR1cm4gZXF1YWxNYXBzKGEsIGIsIHNlZW4pO1xuICBpZiAoYUtpbmQgPT09ICdzZXQnKSByZXR1cm4gZXF1YWxTZXRzKGEsIGIsIHNlZW4pO1xuXG4gIGlmIChhSXNBcnJheSkge1xuICAgIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICghZXF1YWxQYWlycyhhW2ldLCBiW2ldLCBzZWVuKSkgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8vIE9iamVjdHM6IG9ubHkga2V5cyB0aGF0IEhPTEQgYSB2YWx1ZSB0YWtlIHBhcnQg4oCUIGFuIG93biBgdW5kZWZpbmVkYCBpcyBhXG4gIC8vIGRlbGV0ZWQga2V5LCB0aGUgc2FtZSBzdGF0ZSBhcyBhbiBhYnNlbnQgb25lIChzZWUgdGhlIGNvbnRyYWN0IGFib3ZlKS5cbiAgbGV0IGFIZWxkID0gMDtcbiAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoYSkpIHtcbiAgICBpZiAoYVtrZXldID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgIGFIZWxkKys7XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwga2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICghZXF1YWxQYWlycyhhW2tleV0sIGJba2V5XSwgc2VlbikpIHJldHVybiBmYWxzZTtcbiAgfVxuICBsZXQgYkhlbGQgPSAwO1xuICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhiKSkgaWYgKGJba2V5XSAhPT0gdW5kZWZpbmVkKSBiSGVsZCsrO1xuICByZXR1cm4gYUhlbGQgPT09IGJIZWxkO1xufVxuXG4vKiogVGhlIHR5cGVkIHN0YXRlIHZhbHVlcyBgc3RydWN0dXJlZENsb25lYCBrZWVwcyBhbmQgYSBrZXkgd2FsayBjYW5ub3Qgc2VlLiAqL1xuZnVuY3Rpb24gdHlwZWRLaW5kKHZhbHVlOiBvYmplY3QpOiAnZGF0ZScgfCAnbWFwJyB8ICdzZXQnIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkgcmV0dXJuICdkYXRlJztcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTWFwKSByZXR1cm4gJ21hcCc7XG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFNldCkgcmV0dXJuICdzZXQnO1xuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBlcXVhbE1hcHMoYTogTWFwPHVua25vd24sIHVua25vd24+LCBiOiBNYXA8dW5rbm93biwgdW5rbm93bj4sIHNlZW46IFNlZW5QYWlycyk6IGJvb2xlYW4ge1xuICBpZiAoYS5zaXplICE9PSBiLnNpemUpIHJldHVybiBmYWxzZTtcbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgYSkge1xuICAgIGlmICghYi5oYXMoa2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICghZXF1YWxQYWlycyh2YWx1ZSwgYi5nZXQoa2V5KSwgc2VlbikpIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBPcmRlci1pbnNlbnNpdGl2ZSwgZGVlcCBwZXIgbWVtYmVyLiBRdWFkcmF0aWMgaW4gdGhlIHdvcnN0IGNhc2UgZm9yIHNldHMgb2ZcbiAqIG9iamVjdHMg4oCUIGEgc2V0IG9mIHByaW1pdGl2ZXMgKHRoZSBjb21tb24gc2hhcGUpIGlzIG9uZSBgaGFzYCBwZXIgbWVtYmVyLlxuICovXG5mdW5jdGlvbiBlcXVhbFNldHMoYTogU2V0PHVua25vd24+LCBiOiBTZXQ8dW5rbm93bj4sIHNlZW46IFNlZW5QYWlycyk6IGJvb2xlYW4ge1xuICBpZiAoYS5zaXplICE9PSBiLnNpemUpIHJldHVybiBmYWxzZTtcbiAgY29uc3QgdW5tYXRjaGVkID0gWy4uLmJdO1xuICBmb3IgKGNvbnN0IG1lbWJlciBvZiBhKSB7XG4gICAgLy8gU2FtZVZhbHVlWmVybyBmaXJzdCDigJQgcHJpbWl0aXZlcyBhbmQgc2hhcmVkIHJlZmVyZW5jZXMsIG9uZSBgaGFzYC5cbiAgICAvLyBFYWNoIG1hdGNoIHJldGlyZXMgaXRzIHNsb3Qgc28gdHdvIHN0cnVjdHVyYWxseS1lcXVhbCBtZW1iZXJzIG9mIGBhYFxuICAgIC8vIGNhbm5vdCBib3RoIGNsYWltIHRoZSBzYW1lIG1lbWJlciBvZiBgYmAuXG4gICAgY29uc3QgYXQgPSB1bm1hdGNoZWQuaW5kZXhPZihtZW1iZXIpO1xuICAgIGNvbnN0IGZvdW5kID0gYXQgPj0gMCA/IGF0IDogdW5tYXRjaGVkLmZpbmRJbmRleCgoY2FuZGlkYXRlKSA9PiBlcXVhbFBhaXJzKG1lbWJlciwgY2FuZGlkYXRlLCBzZWVuKSk7XG4gICAgaWYgKGZvdW5kIDwgMCkgcmV0dXJuIGZhbHNlO1xuICAgIHVubWF0Y2hlZC5zcGxpY2UoZm91bmQsIDEpO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuIl19
266
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXF1YWxpdHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL21lbW9yeS9lcXVhbGl0eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7R0FPRzs7O0FBRUgsNERBQWtFO0FBRWxFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUVHO0FBQ0gsU0FBZ0IsU0FBUyxDQUFDLENBQU0sRUFBRSxDQUFNLEVBQUUsU0FBcUIsVUFBVTtJQUN2RSxPQUFPLFVBQVUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztBQUM3QyxDQUFDO0FBRkQsOEJBRUM7QUE0QkQsU0FBUyxVQUFVLENBQUMsQ0FBTSxFQUFFLENBQU0sRUFBRSxJQUEyQixFQUFFLE1BQWtCO0lBQ2pGLElBQUksQ0FBQyxLQUFLLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQyxDQUFDLHdDQUF3QztJQUNsRSxJQUFJLE9BQU8sQ0FBQyxLQUFLLE9BQU8sQ0FBQztRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3hDLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssSUFBSTtRQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLCtCQUErQjtJQUM3RSxJQUFJLE9BQU8sQ0FBQyxLQUFLLFFBQVE7UUFBRSxPQUFPLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsNkJBQTZCO0lBRWhGLE1BQU0sSUFBSSxHQUFHLElBQUEsc0JBQU0sRUFBQyxDQUFDLENBQUMsQ0FBQztJQUN2QixJQUFJLElBQUksS0FBSyxJQUFBLHNCQUFNLEVBQUMsQ0FBQyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDckMsUUFBUSxJQUFJLEVBQUUsQ0FBQztRQUNiLGtEQUFrRDtRQUNsRCxLQUFLLE1B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LEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDN0csSUFBSSxLQUFLLEdBQUcsQ0FBQztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQzVCLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGVxdWFsaXR5LnRzIOKAlCBzdHJ1Y3R1cmFsIGVxdWFsaXR5IG9mIGNvbW1pdHRlZC1zdGF0ZSB2YWx1ZXM6IFRIRSBvd25lciBvZlxuICogXCJ3aGF0IGNvdW50cyBhcyBhIGNoYW5nZVwiLiBXaGF0IGBUcmFuc2FjdGlvbkJ1ZmZlcmAncyBuZXQtY2hhbmdlIGZpbHRlciwgdGhlXG4gKiBhZG1pdHRlZCByZWNvcmQncyBjb21wYXJlLCB0aGUgcmVhZCBtb2RlbCdzIHdyaXRlciBydWxlIGFuZCB0aGVcbiAqIGJvcnJvd2VkLW11dGF0aW9uIGd1YXJkIGFsbCBhc2suIEl0cyBvbmUgaW1wb3J0IGlzIHRoZSBjbGFzc2lmaWVyIG9mIHZhbHVlXG4gKiBraW5kcyAoYGNhcHR1cmUvdmFsdWVLaW5kcy50c2AsIGEgbGVhZik7IHJlLWV4cG9ydGVkIGZyb20gYHV0aWxzLnRzYCwgc28gbm9cbiAqIGltcG9ydGVyIG1vdmVkLlxuICovXG5cbmltcG9ydCB7IHR5cGUgVmFsdWVLaW5kLCBraW5kT2YgfSBmcm9tICcuLi9jYXB0dXJlL3ZhbHVlS2luZHMuanMnO1xuXG4vKipcbiAqIFN0cnVjdHVyYWwgZGVlcCBlcXVhbGl0eSBmb3IgY29tbWl0dGVkLXN0YXRlIHZhbHVlcy5cbiAqXG4gKiBVc2VkIGJ5IHtAbGluayBUcmFuc2FjdGlvbkJ1ZmZlcn0gdG8gZGVjaWRlIHdoZXRoZXIgYSBzdGFnZSBhY3R1YWxseSBDSEFOR0VEXG4gKiBhIHBhdGggb3IgbWVyZWx5IHJlLXdyb3RlIC8gcmV2ZXJ0ZWQgaXQgdG8gdGhlIHZhbHVlIGl0IGFscmVhZHkgaGVsZCAoYVxuICogXCJuby1vcCB3cml0ZVwiKSwgYW5kIGJ5IGBib3Jyb3dlZE11dGF0aW9uLmZpcnN0RGlmZmVyaW5nUGF0aGAgdG8gZmluZCB3aGVyZSBhXG4gKiBib3Jyb3dlZCByZWFkIG1vdmVkLiBDb21taXR0ZWQgc3RhdGUgbXVzdCBzdXJ2aXZlIGBzdHJ1Y3R1cmVkQ2xvbmVgLCBzbyB0aGVcbiAqIHZhbHVlcyBpdCBjYW4gaG9sZCBhcmUgdGhlIGtpbmRzIHRoZSBjbG9uZSBrZWVwcywgYW5kIHR3byB2YWx1ZXMgYXJlIGVxdWFsXG4gKiB3aGVuIGEgcmVjb3JkIGhvbGRzIHRoZSBzYW1lIHRoaW5nIGZvciBib3RoLiBFdmVyeSBraW5kIGhhcyBPTkUgYXJtIGJlbG93XG4gKiAoYGVxdWFsUGFpcnNgJyBzd2l0Y2ggb3ZlciBgVmFsdWVLaW5kYCDigJQgYSBraW5kIGFkZGVkIHRvIHRoZSB1bmlvbiBkb2VzIG5vdFxuICogY29tcGlsZSB1bnRpbCBpdCBpcyBjb21wYXJlZCkuIEJlZm9yZSA5LjIyLjAgYSBEYXRlLCBNYXAgb3IgU2V0IHdhcyBjb21wYXJlZFxuICogYXMgYW4gb2JqZWN0IHdpdGggbm8gb3duIGtleXMsIGFuZCB1bnRpbCA5LjQ0LjIgc28gd2VyZSBhIFJlZ0V4cCwgYW4gRXJyb3IsXG4gKiBhIGJveGVkIHByaW1pdGl2ZSwgYW4gQXJyYXlCdWZmZXIsIGEgRGF0YVZpZXcgYW5kIGEgQmxvYjogYW55IHR3byBvZiBhIGtpbmRcbiAqIHdlcmUgXCJlcXVhbFwiLCBzbyBgJHNldFZhbHVlKCdyZScsIC95L2cpYCBvdmVyIGAveC9nYCBjb21taXR0ZWQgbm8gcm93IGFuZFxuICogbGl2ZSBzdGF0ZSBrZXB0IHRoZSBPTEQgdmFsdWUuXG4gKlxuICogU2VtYW50aWNzOlxuICogICAtIHJlZmVyZW5jZSAvIGlkZW50aWNhbC1wcmltaXRpdmUgc2hvcnQtY2lyY3VpdHMgZmlyc3QgKGNoZWFwIGZhc3QgcGF0aClcbiAqICAgLSBgTmFOYCBlcXVhbHMgYE5hTmAgKHByaW1pdGl2ZSBjb21wYXJlIGZhbGxzIGJhY2sgdG8gYE9iamVjdC5pc2ApXG4gKiAgIC0gdHdvIHZhbHVlcyBvZiBkaWZmZXJlbnQgS0lORFMgYXJlIG5ldmVyIGVxdWFsIChhIGBEYXRlYCBpcyBuZXZlciBge31gLFxuICogICAgIGFuIGFycmF5IG5ldmVyIGB7IDA6IOKApiB9YClcbiAqICAgLSBgRGF0ZWA6IHNhbWUgYGdldFRpbWUoKWAgKHR3byBpbnZhbGlkIGRhdGVzIGFyZSBlcXVhbClcbiAqICAgLSBgUmVnRXhwYDogc2FtZSBgc291cmNlYCBhbmQgYGZsYWdzYCAodGhlIGNsb25lIHJlc2V0cyBgbGFzdEluZGV4YClcbiAqICAgLSBgRXJyb3JgOiB0aGUgc2FtZSByZXN0b3JlZCBraW5kIChvbmUgb2YgdGhlIHNpeCBidWlsdC1pbiBlcnJvciBuYW1lcyxcbiAqICAgICBlbHNlIGBFcnJvcmApLCBvd24gYG1lc3NhZ2VgLCBgc3RhY2tgIGFuZCBvd24gYGNhdXNlYCAoZGVlcCkg4oCUIHdoYXQgdGhlXG4gKiAgICAgY2xvbmUga2VlcHM7IGFueSBvdGhlciBvd24gZmllbGQgaXMgZHJvcHBlZCBieSBpdCwgc28gaXQgbmV2ZXIgY291bnRzXG4gKiAgICAgKHRoZSBhZG1pdHRlZCByZWNvcmQncyBsYXcpXG4gKiAgIC0gYSBib3hlZCBwcmltaXRpdmU6IHRoZSBzYW1lIHdyYXBwZXIgdHlwZSBhbmQgdGhlIHNhbWUgcHJpbWl0aXZlIGluc2lkZVxuICogICAtIGFuIGBBcnJheUJ1ZmZlcmA6IGxlbmd0aCwgcmVzaXphYmlsaXR5IGFuZCBieXRlczsgYSB0eXBlZCBhcnJheSBvciBhXG4gKiAgICAgYERhdGFWaWV3YDogaXRzIHR5cGUgYW5kIHRoZSBieXRlcyBJVCB2aWV3cyDigJQgbmV2ZXIgdGhlIHJlc3Qgb2YgaXRzXG4gKiAgICAgYnVmZmVyIChhIE5vZGUgYEJ1ZmZlcmAgdmlld3MgYSBzbGljZSBvZiBhIHNoYXJlZCBwb29sLCBhbmQgdGhlIHJlY29yZFxuICogICAgIGtlZXBzIHRoZSB2aWV3J3MgYnl0ZXMgb25seTogYGNhcHR1cmUvZnJlZXplLnRzIMK3IGZyZWV6ZVJlY29yZGApXG4gKiAgIC0gYE1hcGA6IHNhbWUgc2l6ZSBBTkQsIHBlciBrZXkgb2YgYGFgLCBgYmAgaG9sZHMgYSBkZWVwLWVxdWFsIHZhbHVlIOKAlFxuICogICAgIGtleXMgYnkgYE1hcGAgaWRlbnRpdHkgKGBTYW1lVmFsdWVaZXJvYCksIHZhbHVlcyBkZWVwXG4gKiAgIC0gYFNldGA6IHNhbWUgc2l6ZSBBTkQgZXZlcnkgbWVtYmVyIG9mIGBhYCBpcyBkZWVwLWVxdWFsIHRvIFNPTUUgbWVtYmVyXG4gKiAgICAgb2YgYGJgIChvcmRlci1pbnNlbnNpdGl2ZSDigJQgYSBTZXQgaGFzIG5vIG9yZGVyIHRvIGNvbXBhcmUgYnkpXG4gKiAgIC0gYW4gT1BBUVVFIHZhbHVlIChhIEJsb2IsIGEgYERPTUV4Y2VwdGlvbmAg4oCUIGNvbnRlbnQgdGhpcyBsaWJyYXJ5IGNhbm5vdFxuICogICAgIHJlYWQpOiBieSB0aGUgY2FsbGVyJ3Mge0BsaW5rIE9wYXF1ZVJ1bGV9IOKAlCBlcXVhbCBvbmx5IHRvIGl0c2VsZiBieVxuICogICAgIGRlZmF1bHQgKHJlcGxhY2luZyBvbmUgaXMgYWx3YXlzIGEgY2hhbmdlKSwgb3IsIHdoZW4gYm90aCBzaWRlcyBhcmVcbiAqICAgICBjb3BpZXMgb2Ygb25lIHJlY29yZCwgZXF1YWwgdG8gYW55IG90aGVyIG9mIGl0cyBraW5kXG4gKiAgIC0gYXJyYXlzOiBlcXVhbCBsZW5ndGggQU5EIGRlZXAtZXF1YWwgZWxlbWVudC13aXNlIChvcmRlci1zZW5zaXRpdmU7IGFuXG4gKiAgICAgYXJyYXkncyBleHBhbmRvIGtleXMgYXJlIG91dCBvZiBjb250cmFjdCBhbmQgbm90IGNvbXBhcmVkKVxuICogICAtIG9iamVjdHM6IGlkZW50aWNhbCBzZXQgb2Yga2V5cyB0aGF0IEhPTEQgYSB2YWx1ZSBBTkQgZGVlcC1lcXVhbCBwZXIga2V5LlxuICogICAgIEFuIG93biBrZXkgd2hvc2UgdmFsdWUgaXMgYHVuZGVmaW5lZGAgY291bnRzIGFzIEFCU0VOVDogaXQgaXMgdGhpc1xuICogICAgIGxpYnJhcnkncyBvdGhlciBzcGVsbGluZyBvZiBhIGRlbGV0ZWQga2V5IChgJ2Z1bGwnYCBtb2RlIGZsYXR0ZW5zXG4gKiAgICAgYGRlbGV0ZWAgaW50byBga2V5OiB1bmRlZmluZWRgOyBgJ2RlbHRhJ2AgbW9kZSdzIGBkZWxldGVgIHZlcmIgcmVtb3Zlc1xuICogICAgIHRoZSBrZXkpLCBhbmQgZXZlcnkgY29uc3VtZXIg4oCUIEpTT04sIHRoZSBmb2xkLCBgY29tbWl0VmFsdWVBdGAsIHRoZVxuICogICAgIG1pcnJvciDigJQgcmVhZHMgdGhlIHR3byBzcGVsbGluZ3MgYXMgb25lIHN0YXRlLiBTbyBtdXN0IHRoZSBuZXQtY2hhbmdlXG4gKiAgICAgZmlsdGVyICg5LjE5LjEpOiBge31gIGFuZCBgeyBrOiB1bmRlZmluZWQgfWAgYXJlIG5vdCBhIGNoYW5nZS4gQXJyYXlzXG4gKiAgICAgYXJlIHVudG91Y2hlZCDigJQgYSBzbG90IGhvbGRpbmcgYHVuZGVmaW5lZGAgaXMgc3RpbGwgYSBzbG90LlxuICpcbiAqIENvc3QgJiBzYWZldHk6XG4gKiAgIC0gQWxsb2NhdGVzIG9ubHkgdHJhbnNpZW50IGBPYmplY3Qua2V5c2AgYXJyYXlzLCBhbiBlcnJvcidzIHByb3BlcnR5XG4gKiAgICAgZGVzY3JpcHRvcnMgYW5kIGEgYnl0ZSB2aWV3IHBlciBjb21wYXJlZCBidWZmZXIg4oCUIG5vIGNsb25lcyAoYnV0IG9uZVxuICogICAgIHByb2JlIGNsb25lIHBlciBjbGFzcyBwcm90b3R5cGUsIHJlbWVtYmVyZWQ6IGBjYXB0dXJlL3ZhbHVlS2luZHMudHMgwrdcbiAqICAgICBraW5kT2ZgKS4gSXQgaXMgc3RyaWN0bHkgY2hlYXBlciB0aGFuIHRoZSBgc3RydWN0dXJlZENsb25lYCB0aGUgY29tbWl0XG4gKiAgICAgYWxyZWFkeSBwZXJmb3Jtcy5cbiAqICAgLSBQcmltaXRpdmUgY29tcGFyaXNvbnMgKHRoZSBidWxrIG9mIHN0YXRlKSBhcmUgTygxKSB2aWEgdGhlIGA9PT1gIC9cbiAqICAgICBgT2JqZWN0LmlzYCBmYXN0IHBhdGhzOyBvbmx5IG5lc3RlZCBvYmplY3RzL2FycmF5cyBpbmN1ciBhIHdhbGssIGJvdW5kZWRcbiAqICAgICBieSB0aGUgdmFsdWUncyBvd24gc2l6ZS5cbiAqICAgLSBUZXJtaW5hdGVzIG9uIENZQ0xJQyB2YWx1ZXMgKDkuMTguMSk6IGEgc3RhdGUgdmFsdWUgbXVzdCBzdXJ2aXZlXG4gKiAgICAgYHN0cnVjdHVyZWRDbG9uZWAsIGFuZCBgc3RydWN0dXJlZENsb25lYCBwcmVzZXJ2ZXMgY3ljbGVzIOKAlCBzbyBhXG4gKiAgICAgc2VsZi1yZWZlcmVuY2luZyB2YWx1ZSBpcyBhIGxlZ2FsIHZhbHVlLCBub3QgYW4gb3V0LW9mLWNvbnRyYWN0IG9uZS4gQVxuICogICAgIHBhaXIgb2Ygb2JqZWN0cyBhbHJlYWR5IHVuZGVyIGNvbXBhcmlzb24gaXMgdHJlYXRlZCBhcyBlcXVhbCAodGhlXG4gKiAgICAgc3RydWN0dXJhbCBhbnN3ZXIsIGxvZGFzaCBgaXNFcXVhbGAgc2VtYW50aWNzKTsgYWN5Y2xpYyBpbnB1dHMgc2VlIG5vXG4gKiAgICAgY2hhbmdlLiBEZXYgbW9kZSBzdGlsbCB3YXJucyBhYm91dCBjeWNsZXMgYXQgd3JpdGUgdGltZVxuICogICAgIChgU2NvcGVGYWNhZGUuc2V0VmFsdWVgKSBiZWNhdXNlIHRoZXkgc3VycHJpc2UgbmFycmF0aXZlIGFuZCBKU09OLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVlcEVxdWFsKGE6IGFueSwgYjogYW55LCBvcGFxdWU6IE9wYXF1ZVJ1bGUgPSAnaWRlbnRpdHknKTogYm9vbGVhbiB7XG4gIHJldHVybiBlcXVhbFBhaXJzKGEsIGIsIHVuZGVmaW5lZCwgb3BhcXVlKTtcbn1cblxuLyoqXG4gKiBIb3cge0BsaW5rIGRlZXBFcXVhbH0gY29tcGFyZXMgdHdvIE9QQVFVRSB2YWx1ZXMgKGEgQmxvYiwgYSBgRE9NRXhjZXB0aW9uYCDigJRcbiAqIGNvbnRlbnQgdGhpcyBsaWJyYXJ5IGNhbm5vdCByZWFkKTpcbiAqXG4gKiAgIC0gYCdpZGVudGl0eSdgICh0aGUgZGVmYXVsdCkg4oCUIGVxdWFsIG9ubHkgdG8gaXRzZWxmLiBUaGUgYW5zd2VyIHdoZW4gb25lXG4gKiAgICAgc2lkZSBpcyBhIHZhbHVlIGEgc3RhZ2UgaGFuZGVkIGluOiB0aGUgbmV0LWNoYW5nZSBmaWx0ZXJcbiAqICAgICAoYFRyYW5zYWN0aW9uQnVmZmVyYCksIHRoZSBhcHBlbmQgY2hlY2sgKGBkZWx0YUVuY29kaW5nYCkuIEEgbmV3IG9iamVjdFxuICogICAgIGlzIGEgY2hhbmdlLCBiZWNhdXNlIG5vdGhpbmcgY2FuIHNheSBpdCBpcyBub3QuXG4gKiAgIC0gYCdjb3BpZXMnYCDigJQgZXF1YWwgdG8gYW55IG90aGVyIG9mIGl0cyBraW5kLiBUaGUgYW5zd2VyIHdoZW4gQk9USCBzaWRlc1xuICogICAgIGFyZSBjb3BpZXMgb2Ygb25lIHJlY29yZGVkIHZhbHVlIOKAlCBhIGZvbGQncyBnZW5lcmF0aW9ucyAoYGxvZ01vZGVsYCxcbiAqICAgICBgZWxlbWVudFByb3ZlbmFuY2VgKSwgYSByZXRhaW5lZCByZWFkIGFnYWluc3QgbGl2ZSBzdGF0ZVxuICogICAgIChgYm9ycm93ZWRNdXRhdGlvbmApLCB0aGUgcmVjb3JkIHJlcGxheWVkIGFnYWluc3QgdGhlIHJlYWQtYmFja1xuICogICAgIChgYWRtaXNzaW9uYCk6IGNvcGllcyBuZXZlciBzaGFyZSBpZGVudGl0eSwgc28gaWRlbnRpdHkgd291bGQgY2FsbCBldmVyeVxuICogICAgIG9wYXF1ZSB2YWx1ZSBjaGFuZ2VkLlxuICovXG5leHBvcnQgdHlwZSBPcGFxdWVSdWxlID0gJ2lkZW50aXR5JyB8ICdjb3BpZXMnO1xuXG4vKipcbiAqIE9iamVjdCBwYWlycyBtZXQgc28gZmFyLCBrZXllZCBgYSDihpIgdGhlIGIncyBpdCBoYXMgYmVlbiBwYWlyZWQgd2l0aGAuIENyZWF0ZWRcbiAqIGxhemlseSBieSB0aGUgZmlyc3Qgb2JqZWN0IHBhaXIsIHNvIHByaW1pdGl2ZSBjb21wYXJlcyBhbGxvY2F0ZSBub3RoaW5nLlxuICogTmV2ZXIgcHJ1bmVkOiBldmVyeSBgZmFsc2VgIHJldHVybnMgc3RyYWlnaHQgdXAgdG8gdGhlIGNhbGxlciAoZWFjaCByZWN1cnNpdmVcbiAqIGNhbGwgc2hvcnQtY2lyY3VpdHMgb24gaXQpLCBzbyBub3RoaW5nIGlzIGxvb2tlZCB1cCBhZnRlciBhIG1pc21hdGNoIOKAlCBhXG4gKiBzdG9yZWQgcGFpciBpcyBlaXRoZXIgc3RpbGwgdW5kZXIgY29tcGFyaXNvbiBvciBhbHJlYWR5IGtub3duIGVxdWFsLlxuICovXG50eXBlIFNlZW5QYWlycyA9IFdlYWtNYXA8b2JqZWN0LCBXZWFrU2V0PG9iamVjdD4+O1xuXG5mdW5jdGlvbiBlcXVhbFBhaXJzKGE6IGFueSwgYjogYW55LCBzZWVuOiBTZWVuUGFpcnMgfCB1bmRlZmluZWQsIG9wYXF1ZTogT3BhcXVlUnVsZSk6IGJvb2xlYW4ge1xuICBpZiAoYSA9PT0gYikgcmV0dXJuIHRydWU7IC8vIHNhbWUgcmVmZXJlbmNlIG9yIGlkZW50aWNhbCBwcmltaXRpdmVcbiAgaWYgKHR5cGVvZiBhICE9PSB0eXBlb2YgYikgcmV0dXJuIGZhbHNlO1xuICBpZiAoYSA9PT0gbnVsbCB8fCBiID09PSBudWxsKSByZXR1cm4gYSA9PT0gYjsgLy8gb25lIGlzIG51bGwsIHRoZSBvdGhlciBpc24ndFxuICBpZiAodHlwZW9mIGEgIT09ICdvYmplY3QnKSByZXR1cm4gT2JqZWN0LmlzKGEsIGIpOyAvLyBOYU4tc2FmZSBwcmltaXRpdmUgY29tcGFyZVxuXG4gIGNvbnN0IGtpbmQgPSBraW5kT2YoYSk7XG4gIGlmIChraW5kICE9PSBraW5kT2YoYikpIHJldHVybiBmYWxzZTtcbiAgc3dpdGNoIChraW5kKSB7XG4gICAgLy8gQXRvbXM6IHRoZWlyIGNvbnRlbnQgaXMgYSBzbG90LCBub3QgdGhlaXIga2V5cy5cbiAgICBjYXNlICdkYXRlJzpcbiAgICAgIHJldHVybiBPYmplY3QuaXMoRGF0ZS5wcm90b3R5cGUuZ2V0VGltZS5jYWxsKGEpLCBEYXRlLnByb3RvdHlwZS5nZXRUaW1lLmNhbGwoYikpO1xuICAgIGNhc2UgJ3JlZ2V4cCc6XG4gICAgICByZXR1cm4gYS5zb3VyY2UgPT09IGIuc291cmNlICYmIGEuZmxhZ3MgPT09IGIuZmxhZ3M7XG4gICAgY2FzZSAnYm94ZWQnOlxuICAgICAgcmV0dXJuIHRhZ09mKGEpID09PSB0YWdPZihiKSAmJiBlcXVhbFBhaXJzKGEudmFsdWVPZigpLCBiLnZhbHVlT2YoKSwgc2Vlbiwgb3BhcXVlKTtcbiAgICBjYXNlICdidWZmZXInOlxuICAgICAgcmV0dXJuIGVxdWFsQnVmZmVycyhhLCBiKTtcbiAgICBjYXNlICd2aWV3JzpcbiAgICAgIHJldHVybiBlcXVhbFZpZXdzKGEsIGIpO1xuICAgIGNhc2UgJ29wYXF1ZSc6XG4gICAgICByZXR1cm4gb3BhcXVlID09PSAnY29waWVzJyAmJiB0YWdPZihhKSA9PT0gdGFnT2YoYik7IC8vIGBhID09PSBiYCB3YXMgYW5zd2VyZWQgYWJvdmVcbiAgICBjYXNlICdwbGFpbic6XG4gICAgY2FzZSAnYXJyYXknOlxuICAgIGNhc2UgJ21hcCc6XG4gICAgY2FzZSAnc2V0JzpcbiAgICBjYXNlICdlcnJvcic6XG4gICAgICByZXR1cm4gZXF1YWxDb250YWluZXJzKGEsIGIsIGtpbmQsIHNlZW4sIG9wYXF1ZSk7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB1bmtub3duS2luZChraW5kKTtcbiAgfVxufVxuXG4vKiogVGhlIGtpbmRzIHdob3NlIGNvbnRlbnQgaXMgb3RoZXIgdmFsdWVzOiBjb21wYXJlZCBwYXJ0IGJ5IHBhcnQsIHVuZGVyIHRoZSBjeWNsZSBndWFyZC4gKi9cbmZ1bmN0aW9uIGVxdWFsQ29udGFpbmVycyhhOiBhbnksIGI6IGFueSwga2luZDogVmFsdWVLaW5kLCBzZWVuOiBTZWVuUGFpcnMgfCB1bmRlZmluZWQsIG9wYXF1ZTogT3BhcXVlUnVsZSk6IGJvb2xlYW4ge1xuICAvLyBDeWNsZSBndWFyZCDigJQgYSBwYWlyIHdlIGFyZSBhbHJlYWR5IGluc2lkZSBpcyBlcXVhbCBieSBhc3N1bXB0aW9uLlxuICBzZWVuID8/PSBuZXcgV2Vha01hcCgpO1xuICBsZXQgcGFydG5lcnMgPSBzZWVuLmdldChhKTtcbiAgaWYgKHBhcnRuZXJzPy5oYXMoYikpIHJldHVybiB0cnVlO1xuICBpZiAoIXBhcnRuZXJzKSBzZWVuLnNldChhLCAocGFydG5lcnMgPSBuZXcgV2Vha1NldCgpKSk7XG4gIHBhcnRuZXJzLmFkZChiKTtcblxuICBpZiAoa2luZCA9PT0gJ21hcCcpIHJldHVybiBlcXVhbE1hcHMoYSwgYiwgc2Vlbiwgb3BhcXVlKTtcbiAgaWYgKGtpbmQgPT09ICdzZXQnKSByZXR1cm4gZXF1YWxTZXRzKGEsIGIsIHNlZW4sIG9wYXF1ZSk7XG4gIGlmIChraW5kID09PSAnZXJyb3InKSByZXR1cm4gZXF1YWxFcnJvcnMoYSwgYiwgc2Vlbiwgb3BhcXVlKTtcbiAgaWYgKGtpbmQgPT09ICdhcnJheScpIHtcbiAgICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIWVxdWFsUGFpcnMoYVtpXSwgYltpXSwgc2Vlbiwgb3BhcXVlKSkgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8vIE9iamVjdHM6IG9ubHkga2V5cyB0aGF0IEhPTEQgYSB2YWx1ZSB0YWtlIHBhcnQg4oCUIGFuIG93biBgdW5kZWZpbmVkYCBpcyBhXG4gIC8vIGRlbGV0ZWQga2V5LCB0aGUgc2FtZSBzdGF0ZSBhcyBhbiBhYnNlbnQgb25lIChzZWUgdGhlIGNvbnRyYWN0IGFib3ZlKS5cbiAgbGV0IGFIZWxkID0gMDtcbiAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoYSkpIHtcbiAgICBpZiAoYVtrZXldID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgIGFIZWxkKys7XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwga2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICghZXF1YWxQYWlycyhhW2tleV0sIGJba2V5XSwgc2Vlbiwgb3BhcXVlKSkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGxldCBiSGVsZCA9IDA7XG4gIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGIpKSBpZiAoYltrZXldICE9PSB1bmRlZmluZWQpIGJIZWxkKys7XG4gIHJldHVybiBhSGVsZCA9PT0gYkhlbGQ7XG59XG5cbmZ1bmN0aW9uIHVua25vd25LaW5kKGtpbmQ6IG5ldmVyKTogbmV2ZXIge1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKGBkZWVwRXF1YWw6IG5vIGNvbXBhcmlzb24gZm9yIHRoZSB2YWx1ZSBraW5kICcke1N0cmluZyhraW5kKX0nYCk7XG59XG5cbi8qKiBgW29iamVjdCBOdW1iZXJdYCwgYFtvYmplY3QgVWludDhBcnJheV1gIOKApiDigJQgdGhlIGJ1aWx0LWluIHR5cGUgYSBib3hlZCB2YWx1ZSBvciBhIHZpZXcgY2Fycmllcy4gKi9cbmZ1bmN0aW9uIHRhZ09mKHZhbHVlOiBvYmplY3QpOiBzdHJpbmcge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKTtcbn1cblxuLyoqIFRoZSBzYW1lIHZpZXcgdHlwZSBvdmVyIHRoZSBzYW1lIGJ5dGVzIOKAlCB0aGUgYnl0ZXMgdGhlIHZpZXcgc2Vlcywgd2hlcmV2ZXIgdGhleSBzaXQgaW4gaXRzIGJ1ZmZlci4gKi9cbmZ1bmN0aW9uIGVxdWFsVmlld3MoYTogQXJyYXlCdWZmZXJWaWV3LCBiOiBBcnJheUJ1ZmZlclZpZXcpOiBib29sZWFuIHtcbiAgaWYgKHRhZ09mKGEpICE9PSB0YWdPZihiKSB8fCBhLmJ5dGVMZW5ndGggIT09IGIuYnl0ZUxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoYS5idWZmZXIgPT09IGIuYnVmZmVyICYmIGEuYnl0ZU9mZnNldCA9PT0gYi5ieXRlT2Zmc2V0KSByZXR1cm4gdHJ1ZTtcbiAgY29uc3QgcCA9IG5ldyBVaW50OEFycmF5KGEuYnVmZmVyLCBhLmJ5dGVPZmZzZXQsIGEuYnl0ZUxlbmd0aCk7XG4gIGNvbnN0IHEgPSBuZXcgVWludDhBcnJheShiLmJ1ZmZlciwgYi5ieXRlT2Zmc2V0LCBiLmJ5dGVMZW5ndGgpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHAubGVuZ3RoOyBpKyspIGlmIChwW2ldICE9PSBxW2ldKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiogVGhlIHNhbWUgbGVuZ3RoLCByZXNpemFiaWxpdHkgYW5kIGJ5dGVzLiAqL1xuZnVuY3Rpb24gZXF1YWxCdWZmZXJzKGE6IEFycmF5QnVmZmVyTGlrZSwgYjogQXJyYXlCdWZmZXJMaWtlKTogYm9vbGVhbiB7XG4gIGlmIChhID09PSBiKSByZXR1cm4gdHJ1ZTtcbiAgY29uc3QgeCA9IGEgYXMgQXJyYXlCdWZmZXJMaWtlICYgeyByZXNpemFibGU/OiBib29sZWFuOyBtYXhCeXRlTGVuZ3RoPzogbnVtYmVyIH07XG4gIGNvbnN0IHkgPSBiIGFzIHR5cGVvZiB4O1xuICBpZiAoeC5ieXRlTGVuZ3RoICE9PSB5LmJ5dGVMZW5ndGggfHwgeC5yZXNpemFibGUgIT09IHkucmVzaXphYmxlIHx8IHgubWF4Qnl0ZUxlbmd0aCAhPT0geS5tYXhCeXRlTGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGNvbnN0IHAgPSBuZXcgVWludDhBcnJheShhKTtcbiAgY29uc3QgcSA9IG5ldyBVaW50OEFycmF5KGIpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHAubGVuZ3RoOyBpKyspIGlmIChwW2ldICE9PSBxW2ldKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiogVGhlIHNpeCBlcnJvciBuYW1lcyBgc3RydWN0dXJlZENsb25lYCByZXN0b3JlczsgYW55IG90aGVyIG5hbWUgY29tZXMgYmFjayBhbiBgRXJyb3JgLiAqL1xuY29uc3QgRVJST1JfTkFNRVMgPSBuZXcgU2V0KFsnRXZhbEVycm9yJywgJ1JhbmdlRXJyb3InLCAnUmVmZXJlbmNlRXJyb3InLCAnU3ludGF4RXJyb3InLCAnVHlwZUVycm9yJywgJ1VSSUVycm9yJ10pO1xuXG4vKipcbiAqIFR3byBlcnJvcnMgYXMgdGhlIGNsb25lIGtlZXBzIHRoZW06IHRoZSByZXN0b3JlZCBraW5kLCB0aGUgb3duIGBtZXNzYWdlYCxcbiAqIHRoZSBgc3RhY2tgIGFuZCB0aGUgb3duIGBjYXVzZWAgKGRlZXApLiBBbnkgb3RoZXIgb3duIGZpZWxkIGlzIGRyb3BwZWQgYnlcbiAqIHRoZSBjbG9uZSwgc28gaXQgbmV2ZXIgY291bnRzLlxuICovXG5mdW5jdGlvbiBlcXVhbEVycm9ycyhhOiBFcnJvciwgYjogRXJyb3IsIHNlZW46IFNlZW5QYWlycywgb3BhcXVlOiBPcGFxdWVSdWxlKTogYm9vbGVhbiB7XG4gIGlmIChlcnJvcktpbmRPZihhKSAhPT0gZXJyb3JLaW5kT2YoYikgfHwgc3RhY2tPZihhKSAhPT0gc3RhY2tPZihiKSkgcmV0dXJuIGZhbHNlO1xuICBjb25zdCBhTWVzc2FnZSA9IG93bkRhdGEoYSwgJ21lc3NhZ2UnKTtcbiAgY29uc3QgYk1lc3NhZ2UgPSBvd25EYXRhKGIsICdtZXNzYWdlJyk7XG4gIGlmIChTdHJpbmcoYU1lc3NhZ2U/LnZhbHVlKSAhPT0gU3RyaW5nKGJNZXNzYWdlPy52YWx1ZSkgfHwgIWFNZXNzYWdlICE9PSAhYk1lc3NhZ2UpIHJldHVybiBmYWxzZTtcbiAgY29uc3QgYUNhdXNlID0gb3duRGF0YShhLCAnY2F1c2UnKTtcbiAgY29uc3QgYkNhdXNlID0gb3duRGF0YShiLCAnY2F1c2UnKTtcbiAgaWYgKCFhQ2F1c2UgfHwgIWJDYXVzZSkgcmV0dXJuICFhQ2F1c2UgPT09ICFiQ2F1c2U7XG4gIHJldHVybiBlcXVhbFBhaXJzKGFDYXVzZS52YWx1ZSwgYkNhdXNlLnZhbHVlLCBzZWVuLCBvcGFxdWUpO1xufVxuXG5mdW5jdGlvbiBlcnJvcktpbmRPZihlcnJvcjogRXJyb3IpOiBzdHJpbmcge1xuICBjb25zdCBuYW1lID0gU3RyaW5nKGVycm9yLm5hbWUpO1xuICByZXR1cm4gRVJST1JfTkFNRVMuaGFzKG5hbWUpID8gbmFtZSA6ICdFcnJvcic7XG59XG5cbmZ1bmN0aW9uIHN0YWNrT2YoZXJyb3I6IEVycm9yKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgc3RhY2sgPSBlcnJvci5zdGFjaztcbiAgcmV0dXJuIHR5cGVvZiBzdGFjayA9PT0gJ3N0cmluZycgPyBzdGFjayA6IHVuZGVmaW5lZDtcbn1cblxuLyoqIEFuIG93biBEQVRBIHByb3BlcnR5LCBib3hlZCDigJQgaG93IHRoZSBjbG9uZSByZWFkcyBhbiBlcnJvcidzIGBtZXNzYWdlYCBhbmQgYGNhdXNlYC4gKi9cbmZ1bmN0aW9uIG93bkRhdGEodmFsdWU6IG9iamVjdCwga2V5OiBzdHJpbmcpOiB7IHZhbHVlOiB1bmtub3duIH0gfCB1bmRlZmluZWQge1xuICBjb25zdCBkZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih2YWx1ZSwga2V5KTtcbiAgcmV0dXJuIGRlc2NyaXB0b3IgIT09IHVuZGVmaW5lZCAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZGVzY3JpcHRvciwgJ3ZhbHVlJylcbiAgICA/IHsgdmFsdWU6IGRlc2NyaXB0b3IudmFsdWUgfVxuICAgIDogdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBlcXVhbE1hcHMoYTogTWFwPHVua25vd24sIHVua25vd24+LCBiOiBNYXA8dW5rbm93biwgdW5rbm93bj4sIHNlZW46IFNlZW5QYWlycywgb3BhcXVlOiBPcGFxdWVSdWxlKTogYm9vbGVhbiB7XG4gIGlmIChhLnNpemUgIT09IGIuc2l6ZSkgcmV0dXJuIGZhbHNlO1xuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBhKSB7XG4gICAgaWYgKCFiLmhhcyhrZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKCFlcXVhbFBhaXJzKHZhbHVlLCBiLmdldChrZXkpLCBzZWVuLCBvcGFxdWUpKSByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogT3JkZXItaW5zZW5zaXRpdmUsIGRlZXAgcGVyIG1lbWJlci4gUXVhZHJhdGljIGluIHRoZSB3b3JzdCBjYXNlIGZvciBzZXRzIG9mXG4gKiBvYmplY3RzIOKAlCBhIHNldCBvZiBwcmltaXRpdmVzICh0aGUgY29tbW9uIHNoYXBlKSBpcyBvbmUgYGhhc2AgcGVyIG1lbWJlci5cbiAqL1xuZnVuY3Rpb24gZXF1YWxTZXRzKGE6IFNldDx1bmtub3duPiwgYjogU2V0PHVua25vd24+LCBzZWVuOiBTZWVuUGFpcnMsIG9wYXF1ZTogT3BhcXVlUnVsZSk6IGJvb2xlYW4ge1xuICBpZiAoYS5zaXplICE9PSBiLnNpemUpIHJldHVybiBmYWxzZTtcbiAgY29uc3QgdW5tYXRjaGVkID0gWy4uLmJdO1xuICBmb3IgKGNvbnN0IG1lbWJlciBvZiBhKSB7XG4gICAgLy8gU2FtZVZhbHVlWmVybyBmaXJzdCDigJQgcHJpbWl0aXZlcyBhbmQgc2hhcmVkIHJlZmVyZW5jZXMsIG9uZSBgaGFzYC5cbiAgICAvLyBFYWNoIG1hdGNoIHJldGlyZXMgaXRzIHNsb3Qgc28gdHdvIHN0cnVjdHVyYWxseS1lcXVhbCBtZW1iZXJzIG9mIGBhYFxuICAgIC8vIGNhbm5vdCBib3RoIGNsYWltIHRoZSBzYW1lIG1lbWJlciBvZiBgYmAuXG4gICAgY29uc3QgYXQgPSB1bm1hdGNoZWQuaW5kZXhPZihtZW1iZXIpO1xuICAgIGNvbnN0IGZvdW5kID0gYXQgPj0gMCA/IGF0IDogdW5tYXRjaGVkLmZpbmRJbmRleCgoY2FuZGlkYXRlKSA9PiBlcXVhbFBhaXJzKG1lbWJlciwgY2FuZGlkYXRlLCBzZWVuLCBvcGFxdWUpKTtcbiAgICBpZiAoZm91bmQgPCAwKSByZXR1cm4gZmFsc2U7XG4gICAgdW5tYXRjaGVkLnNwbGljZShmb3VuZCwgMSk7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG4iXX0=