jderobot-ide-interface 0.3.17 → 0.3.19

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 (50) hide show
  1. package/dist/a5a14e7d119e89dea736.wasm +0 -0
  2. package/dist/components/Button/Button.styles.d.ts +3 -1
  3. package/dist/components/ButtonsContainer/ButtonsContainer.styles.d.ts +6 -2
  4. package/dist/components/Dropdown/Dropdown.styles.d.ts +3 -1
  5. package/dist/components/Explorer/Explorer.styles.d.ts +9 -3
  6. package/dist/components/Explorer/file_explorer/FileExplorer.styles.d.ts +3 -1
  7. package/dist/components/Explorer/file_explorer/MoreActionsMenu.styles.d.ts +12 -4
  8. package/dist/components/Explorer/file_explorer/TreeNode.styles.d.ts +18 -6
  9. package/dist/components/FileEditor/FileEditor.d.ts +2 -1
  10. package/dist/components/FileEditor/FileEditor.styles.d.ts +9 -3
  11. package/dist/components/FileEditor/IdeInterface.stories.d.ts +5 -0
  12. package/dist/components/FileEditor/TextEditor.d.ts +2 -1
  13. package/dist/components/FileEditor/lsp-client.d.ts +1 -0
  14. package/dist/components/IdeInterface/IdeInterface.d.ts +2 -1
  15. package/dist/components/IdeInterface/IdeInterface.stories.d.ts +1 -1
  16. package/dist/components/IdeInterface/IdeInterface.styles.d.ts +67 -1228
  17. package/dist/components/IdeInterface/TheoryInterface.styles.d.ts +21 -7
  18. package/dist/components/Modals/EditorKeybindModal.styles.d.ts +3 -1
  19. package/dist/components/Modals/ErrorModal.styles.d.ts +9 -3
  20. package/dist/components/Modals/Modal.styles.d.ts +68 -25
  21. package/dist/components/ProgressBar/ProgressBar.style.d.ts +3 -1
  22. package/dist/components/StatusBar/StatusBar.style.d.ts +9 -3
  23. package/dist/components/Theory/Canvas.styles.d.ts +3 -1
  24. package/dist/components/Theory/CarouselDisplay.styles.d.ts +39 -13
  25. package/dist/components/Theory/Code.styles.d.ts +3 -1
  26. package/dist/components/Theory/FormulaSection.styles.d.ts +3 -1
  27. package/dist/components/Theory/HighlightedSection.styles.d.ts +3 -1
  28. package/dist/components/Theory/Image.styles.d.ts +3 -1
  29. package/dist/components/Theory/ImageRow.styles.d.ts +3 -1
  30. package/dist/components/Theory/Link.styles.d.ts +3 -1
  31. package/dist/components/Theory/List.styles.d.ts +3 -1
  32. package/dist/components/Theory/LocalVideo.styles.d.ts +3 -1
  33. package/dist/components/Theory/NumberedList.styles.d.ts +3 -1
  34. package/dist/components/Theory/Section.styles.d.ts +6 -2
  35. package/dist/components/Theory/Subsection.styles.d.ts +6 -2
  36. package/dist/components/Theory/Subsubsection.styles.d.ts +6 -2
  37. package/dist/components/Theory/Timeline.styles.d.ts +24 -8
  38. package/dist/components/Theory/TimelineComparison.styles.d.ts +15 -5
  39. package/dist/components/Theory/YoutubeVideo.styles.d.ts +1 -1
  40. package/dist/components/VncViewer/VncViewer.styles.d.ts +12 -4
  41. package/dist/d94e0a7c7ed2cbcaeba4.html +123 -0
  42. package/dist/main.js +4071 -1890
  43. package/dist/node_fs_promises.main.js +13 -0
  44. package/dist/node_modules_vscode_diff_dist_worker_js_esm.main.js +397 -0
  45. package/dist/package.json +1 -1
  46. package/dist/vendors-node_modules_jschardet_index_js.main.js +8224 -0
  47. package/dist/vendors-node_modules_vscode_diff_dist_index_js.main.js +626 -0
  48. package/dist/vendors-node_modules_vscode_diff_dist_wire_js.main.js +2233 -0
  49. package/dist/vendors-node_modules_vscode_iconv-lite-umd_lib_iconv-lite-umd_js.main.js +18 -0
  50. package/package.json +1 -1
@@ -0,0 +1,2233 @@
1
+ "use strict";
2
+ (this["webpackChunkjderobot_ide_interface"] = this["webpackChunkjderobot_ide_interface"] || []).push([["vendors-node_modules_vscode_diff_dist_wire_js"],{
3
+
4
+ /***/ "./node_modules/@vscode/diff/dist/diff_wasm_bg-c6YkaZRL.wasm"
5
+ /*!*******************************************************************!*\
6
+ !*** ./node_modules/@vscode/diff/dist/diff_wasm_bg-c6YkaZRL.wasm ***!
7
+ \*******************************************************************/
8
+ (module, __unused_webpack_exports, __webpack_require__) {
9
+
10
+ module.exports = __webpack_require__.p + "a5a14e7d119e89dea736.wasm";
11
+
12
+ /***/ },
13
+
14
+ /***/ "./node_modules/@vscode/diff/dist/wire.js"
15
+ /*!************************************************!*\
16
+ !*** ./node_modules/@vscode/diff/dist/wire.js ***!
17
+ \************************************************/
18
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
19
+
20
+ __webpack_require__.r(__webpack_exports__);
21
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
22
+ /* harmony export */ D: () => (/* binding */ DefaultLinesDiffComputer),
23
+ /* harmony export */ L: () => (/* binding */ LineRange),
24
+ /* harmony export */ O: () => (/* binding */ OffsetRange),
25
+ /* harmony export */ R: () => (/* binding */ RangeMapping),
26
+ /* harmony export */ a: () => (/* binding */ Range),
27
+ /* harmony export */ b: () => (/* binding */ DetailedLineRangeMapping),
28
+ /* harmony export */ c: () => (/* binding */ LinesDiff),
29
+ /* harmony export */ d: () => (/* binding */ LineRangeMapping),
30
+ /* harmony export */ g: () => (/* binding */ getWasm),
31
+ /* harmony export */ i: () => (/* binding */ initWasm),
32
+ /* harmony export */ l: () => (/* binding */ linesDiffToWire),
33
+ /* harmony export */ w: () => (/* binding */ wireToLinesDiff)
34
+ /* harmony export */ });
35
+ /*---------------------------------------------------------------------------------------------
36
+ * Copyright (c) Microsoft Corporation. All rights reserved.
37
+ * Licensed under the MIT License. See License.txt in the project root for license information.
38
+ *--------------------------------------------------------------------------------------------*/
39
+ /**
40
+ * A range of offsets (0-based).
41
+ */
42
+ class OffsetRange {
43
+ start;
44
+ endExclusive;
45
+ static ofLength(length) {
46
+ return new OffsetRange(0, length);
47
+ }
48
+ static ofStartAndLength(start, length) {
49
+ return new OffsetRange(start, start + length);
50
+ }
51
+ constructor(start, endExclusive) {
52
+ this.start = start;
53
+ this.endExclusive = endExclusive;
54
+ if (start > endExclusive) {
55
+ throw new Error(`Invalid range: [${start}, ${endExclusive})`);
56
+ }
57
+ }
58
+ get isEmpty() {
59
+ return this.start === this.endExclusive;
60
+ }
61
+ get length() {
62
+ return this.endExclusive - this.start;
63
+ }
64
+ delta(offset) {
65
+ return new OffsetRange(this.start + offset, this.endExclusive + offset);
66
+ }
67
+ deltaStart(offset) {
68
+ return new OffsetRange(this.start + offset, this.endExclusive);
69
+ }
70
+ deltaEnd(offset) {
71
+ return new OffsetRange(this.start, this.endExclusive + offset);
72
+ }
73
+ equals(other) {
74
+ return this.start === other.start && this.endExclusive === other.endExclusive;
75
+ }
76
+ containsRange(other) {
77
+ return this.start <= other.start && other.endExclusive <= this.endExclusive;
78
+ }
79
+ contains(offset) {
80
+ return this.start <= offset && offset < this.endExclusive;
81
+ }
82
+ join(other) {
83
+ return new OffsetRange(Math.min(this.start, other.start), Math.max(this.endExclusive, other.endExclusive));
84
+ }
85
+ intersect(other) {
86
+ const start = Math.max(this.start, other.start);
87
+ const end = Math.min(this.endExclusive, other.endExclusive);
88
+ if (start <= end) {
89
+ return new OffsetRange(start, end);
90
+ }
91
+ return undefined;
92
+ }
93
+ intersects(other) {
94
+ const start = Math.max(this.start, other.start);
95
+ const end = Math.min(this.endExclusive, other.endExclusive);
96
+ return start < end;
97
+ }
98
+ intersectsOrTouches(other) {
99
+ const start = Math.max(this.start, other.start);
100
+ const end = Math.min(this.endExclusive, other.endExclusive);
101
+ return start <= end;
102
+ }
103
+ slice(arr) {
104
+ return arr.slice(this.start, this.endExclusive);
105
+ }
106
+ toString() {
107
+ return `[${this.start}, ${this.endExclusive})`;
108
+ }
109
+ }
110
+
111
+ class InfiniteTimeout {
112
+ static instance = new InfiniteTimeout();
113
+ isValid() {
114
+ return true;
115
+ }
116
+ }
117
+ class DateTimeout {
118
+ timeout;
119
+ startTime = Date.now();
120
+ valid = true;
121
+ constructor(timeout) {
122
+ this.timeout = timeout;
123
+ if (timeout <= 0) {
124
+ throw new Error('timeout must be positive');
125
+ }
126
+ }
127
+ isValid() {
128
+ const valid = Date.now() - this.startTime < this.timeout;
129
+ if (!valid && this.valid) {
130
+ this.valid = false;
131
+ }
132
+ return this.valid;
133
+ }
134
+ }
135
+ /**
136
+ * Represents an offset pair for two sequences.
137
+ */
138
+ class OffsetPair {
139
+ offset1;
140
+ offset2;
141
+ static zero = new OffsetPair(0, 0);
142
+ static max = new OffsetPair(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
143
+ constructor(offset1, offset2) {
144
+ this.offset1 = offset1;
145
+ this.offset2 = offset2;
146
+ }
147
+ toString() {
148
+ return `${this.offset1} <-> ${this.offset2}`;
149
+ }
150
+ delta(offset) {
151
+ if (offset === 0) {
152
+ return this;
153
+ }
154
+ return new OffsetPair(this.offset1 + offset, this.offset2 + offset);
155
+ }
156
+ equals(other) {
157
+ return this.offset1 === other.offset1 && this.offset2 === other.offset2;
158
+ }
159
+ }
160
+ /**
161
+ * Represents a diff between two sequences.
162
+ */
163
+ class SequenceDiff {
164
+ seq1Range;
165
+ seq2Range;
166
+ static invert(sequenceDiffs, doc1Length) {
167
+ const result = [];
168
+ forEachAdjacent(sequenceDiffs, (a, b) => {
169
+ result.push(SequenceDiff.fromOffsetPairs(a ? a.getEndExclusives() : OffsetPair.zero, b ? b.getStarts() : new OffsetPair(doc1Length, (a ? a.seq2Range.endExclusive - a.seq1Range.endExclusive : 0) + doc1Length)));
170
+ });
171
+ return result;
172
+ }
173
+ static fromOffsetPairs(start, endExclusive) {
174
+ return new SequenceDiff(new OffsetRange(start.offset1, endExclusive.offset1), new OffsetRange(start.offset2, endExclusive.offset2));
175
+ }
176
+ static assertSorted(sequenceDiffs) {
177
+ let last = undefined;
178
+ for (const cur of sequenceDiffs) {
179
+ if (last) {
180
+ if (!(last.seq1Range.endExclusive <= cur.seq1Range.start && last.seq2Range.endExclusive <= cur.seq2Range.start)) {
181
+ throw new Error('Sequence diffs must be sorted');
182
+ }
183
+ }
184
+ last = cur;
185
+ }
186
+ }
187
+ constructor(seq1Range, seq2Range) {
188
+ this.seq1Range = seq1Range;
189
+ this.seq2Range = seq2Range;
190
+ }
191
+ swap() {
192
+ return new SequenceDiff(this.seq2Range, this.seq1Range);
193
+ }
194
+ toString() {
195
+ return `${this.seq1Range} <-> ${this.seq2Range}`;
196
+ }
197
+ join(other) {
198
+ return new SequenceDiff(this.seq1Range.join(other.seq1Range), this.seq2Range.join(other.seq2Range));
199
+ }
200
+ delta(offset) {
201
+ if (offset === 0) {
202
+ return this;
203
+ }
204
+ return new SequenceDiff(this.seq1Range.delta(offset), this.seq2Range.delta(offset));
205
+ }
206
+ deltaStart(offset) {
207
+ if (offset === 0) {
208
+ return this;
209
+ }
210
+ return new SequenceDiff(this.seq1Range.deltaStart(offset), this.seq2Range.deltaStart(offset));
211
+ }
212
+ deltaEnd(offset) {
213
+ if (offset === 0) {
214
+ return this;
215
+ }
216
+ return new SequenceDiff(this.seq1Range.deltaEnd(offset), this.seq2Range.deltaEnd(offset));
217
+ }
218
+ intersectsOrTouches(other) {
219
+ return this.seq1Range.intersectsOrTouches(other.seq1Range) || this.seq2Range.intersectsOrTouches(other.seq2Range);
220
+ }
221
+ intersect(other) {
222
+ const i1 = this.seq1Range.intersect(other.seq1Range);
223
+ const i2 = this.seq2Range.intersect(other.seq2Range);
224
+ if (!i1 || !i2) {
225
+ return undefined;
226
+ }
227
+ return new SequenceDiff(i1, i2);
228
+ }
229
+ getStarts() {
230
+ return new OffsetPair(this.seq1Range.start, this.seq2Range.start);
231
+ }
232
+ getEndExclusives() {
233
+ return new OffsetPair(this.seq1Range.endExclusive, this.seq2Range.endExclusive);
234
+ }
235
+ }
236
+ /**
237
+ * Result of a diff algorithm computation.
238
+ */
239
+ class DiffAlgorithmResult {
240
+ diffs;
241
+ hitTimeout;
242
+ static trivial(seq1, seq2) {
243
+ return new DiffAlgorithmResult([new SequenceDiff(OffsetRange.ofLength(seq1.length), OffsetRange.ofLength(seq2.length))], false);
244
+ }
245
+ static trivialTimedOut(seq1, seq2) {
246
+ return new DiffAlgorithmResult([new SequenceDiff(OffsetRange.ofLength(seq1.length), OffsetRange.ofLength(seq2.length))], true);
247
+ }
248
+ constructor(diffs, hitTimeout) {
249
+ this.diffs = diffs;
250
+ this.hitTimeout = hitTimeout;
251
+ }
252
+ }
253
+ // Helper function for iterating with neighbors
254
+ function forEachAdjacent(items, callback) {
255
+ let prev = undefined;
256
+ for (const item of items) {
257
+ callback(prev, item);
258
+ prev = item;
259
+ }
260
+ callback(prev, undefined);
261
+ }
262
+
263
+ /**
264
+ * A 2D array implementation.
265
+ */
266
+ class Array2D {
267
+ width;
268
+ height;
269
+ array = [];
270
+ constructor(width, height) {
271
+ this.width = width;
272
+ this.height = height;
273
+ this.array = new Array(width * height);
274
+ }
275
+ get(x, y) {
276
+ return this.array[x + y * this.width];
277
+ }
278
+ set(x, y, value) {
279
+ this.array[x + y * this.width] = value;
280
+ }
281
+ }
282
+ /**
283
+ * A O(MN) diffing algorithm that supports a score function.
284
+ * The algorithm can be improved by processing the 2d array diagonally.
285
+ */
286
+ class DynamicProgrammingDiffing {
287
+ compute(sequence1, sequence2, timeout = InfiniteTimeout.instance, equalityScore) {
288
+ if (sequence1.length === 0 || sequence2.length === 0) {
289
+ return DiffAlgorithmResult.trivial(sequence1, sequence2);
290
+ }
291
+ /**
292
+ * lcsLengths.get(i, j): Length of the longest common subsequence of
293
+ * sequence1.substring(0, i + 1) and sequence2.substring(0, j + 1).
294
+ */
295
+ const lcsLengths = new Array2D(sequence1.length, sequence2.length);
296
+ const directions = new Array2D(sequence1.length, sequence2.length);
297
+ const lengths = new Array2D(sequence1.length, sequence2.length);
298
+ // Initialize lcsLengths
299
+ for (let s1 = 0; s1 < sequence1.length; s1++) {
300
+ for (let s2 = 0; s2 < sequence2.length; s2++) {
301
+ if (!timeout.isValid()) {
302
+ return DiffAlgorithmResult.trivialTimedOut(sequence1, sequence2);
303
+ }
304
+ const horizontalLen = s1 === 0 ? 0 : lcsLengths.get(s1 - 1, s2);
305
+ const verticalLen = s2 === 0 ? 0 : lcsLengths.get(s1, s2 - 1);
306
+ let extendedSeqScore;
307
+ if (sequence1.getElement(s1) === sequence2.getElement(s2)) {
308
+ if (s1 === 0 || s2 === 0) {
309
+ extendedSeqScore = 0;
310
+ }
311
+ else {
312
+ extendedSeqScore = lcsLengths.get(s1 - 1, s2 - 1);
313
+ }
314
+ if (s1 > 0 && s2 > 0 && directions.get(s1 - 1, s2 - 1) === 3) {
315
+ // Prefer consecutive diagonals
316
+ extendedSeqScore += lengths.get(s1 - 1, s2 - 1);
317
+ }
318
+ extendedSeqScore += (equalityScore ? equalityScore(s1, s2) : 1);
319
+ }
320
+ else {
321
+ extendedSeqScore = -1;
322
+ }
323
+ const newValue = Math.max(horizontalLen, verticalLen, extendedSeqScore);
324
+ if (newValue === extendedSeqScore) {
325
+ // Prefer diagonals
326
+ const prevLen = s1 > 0 && s2 > 0 ? lengths.get(s1 - 1, s2 - 1) : 0;
327
+ lengths.set(s1, s2, prevLen + 1);
328
+ directions.set(s1, s2, 3);
329
+ }
330
+ else if (newValue === horizontalLen) {
331
+ lengths.set(s1, s2, 0);
332
+ directions.set(s1, s2, 1);
333
+ }
334
+ else if (newValue === verticalLen) {
335
+ lengths.set(s1, s2, 0);
336
+ directions.set(s1, s2, 2);
337
+ }
338
+ lcsLengths.set(s1, s2, newValue);
339
+ }
340
+ }
341
+ // Backtracking
342
+ const result = [];
343
+ let lastAligningPosS1 = sequence1.length;
344
+ let lastAligningPosS2 = sequence2.length;
345
+ function reportDecreasingAligningPositions(s1, s2) {
346
+ if (s1 + 1 !== lastAligningPosS1 || s2 + 1 !== lastAligningPosS2) {
347
+ result.push(new SequenceDiff(new OffsetRange(s1 + 1, lastAligningPosS1), new OffsetRange(s2 + 1, lastAligningPosS2)));
348
+ }
349
+ lastAligningPosS1 = s1;
350
+ lastAligningPosS2 = s2;
351
+ }
352
+ let s1 = sequence1.length - 1;
353
+ let s2 = sequence2.length - 1;
354
+ while (s1 >= 0 && s2 >= 0) {
355
+ if (directions.get(s1, s2) === 3) {
356
+ reportDecreasingAligningPositions(s1, s2);
357
+ s1--;
358
+ s2--;
359
+ }
360
+ else {
361
+ if (directions.get(s1, s2) === 1) {
362
+ s1--;
363
+ }
364
+ else {
365
+ s2--;
366
+ }
367
+ }
368
+ }
369
+ reportDecreasingAligningPositions(-1, -1);
370
+ result.reverse();
371
+ return new DiffAlgorithmResult(result, false);
372
+ }
373
+ }
374
+
375
+ /**
376
+ * An O(ND) diff algorithm that has a quadratic space worst-case complexity.
377
+ */
378
+ class MyersDiffAlgorithm {
379
+ compute(seq1, seq2, timeout = InfiniteTimeout.instance) {
380
+ // Common special cases - early return improves performance dramatically
381
+ if (seq1.length === 0 || seq2.length === 0) {
382
+ return DiffAlgorithmResult.trivial(seq1, seq2);
383
+ }
384
+ const seqX = seq1; // Text on the x axis
385
+ const seqY = seq2; // Text on the y axis
386
+ function getXAfterSnake(x, y) {
387
+ while (x < seqX.length && y < seqY.length && seqX.getElement(x) === seqY.getElement(y)) {
388
+ x++;
389
+ y++;
390
+ }
391
+ return x;
392
+ }
393
+ let d = 0;
394
+ // V[k]: X value of longest d-line that ends in diagonal k.
395
+ // d-line: path from (0,0) to (x,y) that uses exactly d non-diagonals.
396
+ // diagonal k: Set of points (x,y) with x-y = k.
397
+ const V = new FastInt32Array();
398
+ V.set(0, getXAfterSnake(0, 0));
399
+ const paths = new FastArrayNegativeIndices();
400
+ paths.set(0, V.get(0) === 0 ? null : new SnakePath(null, 0, 0, V.get(0)));
401
+ let k = 0;
402
+ loop: while (true) {
403
+ d++;
404
+ if (!timeout.isValid()) {
405
+ return DiffAlgorithmResult.trivialTimedOut(seqX, seqY);
406
+ }
407
+ // The paper has `for (k = -d; k <= d; k += 2)`, but we can ignore diagonals that cannot influence the result.
408
+ const lowerBound = -Math.min(d, seqY.length + (d % 2));
409
+ const upperBound = Math.min(d, seqX.length + (d % 2));
410
+ for (k = lowerBound; k <= upperBound; k += 2) {
411
+ // We can use the X values of (d-1)-lines to compute X value of the longest d-lines.
412
+ const maxXofDLineTop = k === upperBound ? -1 : V.get(k + 1); // Vertical non-diagonal (add symbol in seqX)
413
+ const maxXofDLineLeft = k === lowerBound ? -1 : V.get(k - 1) + 1; // Horizontal non-diagonal (delete symbol in seqX)
414
+ const x = Math.min(Math.max(maxXofDLineTop, maxXofDLineLeft), seqX.length);
415
+ const y = x - k;
416
+ if (x > seqX.length || y > seqY.length) {
417
+ continue;
418
+ }
419
+ const newMaxX = getXAfterSnake(x, y);
420
+ V.set(k, newMaxX);
421
+ const lastPath = x === maxXofDLineTop ? paths.get(k + 1) : paths.get(k - 1);
422
+ paths.set(k, newMaxX !== x ? new SnakePath(lastPath, x, y, newMaxX - x) : lastPath);
423
+ if (V.get(k) === seqX.length && V.get(k) - k === seqY.length) {
424
+ break loop;
425
+ }
426
+ }
427
+ }
428
+ let path = paths.get(k);
429
+ const result = [];
430
+ let lastAligningPosS1 = seqX.length;
431
+ let lastAligningPosS2 = seqY.length;
432
+ while (true) {
433
+ const endX = path ? path.x + path.length : 0;
434
+ const endY = path ? path.y + path.length : 0;
435
+ if (endX !== lastAligningPosS1 || endY !== lastAligningPosS2) {
436
+ result.push(new SequenceDiff(new OffsetRange(endX, lastAligningPosS1), new OffsetRange(endY, lastAligningPosS2)));
437
+ }
438
+ if (!path) {
439
+ break;
440
+ }
441
+ lastAligningPosS1 = path.x;
442
+ lastAligningPosS2 = path.y;
443
+ path = path.prev;
444
+ }
445
+ result.reverse();
446
+ return new DiffAlgorithmResult(result, false);
447
+ }
448
+ }
449
+ class SnakePath {
450
+ prev;
451
+ x;
452
+ y;
453
+ length;
454
+ constructor(prev, x, y, length) {
455
+ this.prev = prev;
456
+ this.x = x;
457
+ this.y = y;
458
+ this.length = length;
459
+ }
460
+ }
461
+ /**
462
+ * An array that supports fast negative indices.
463
+ */
464
+ class FastInt32Array {
465
+ positiveArr = new Int32Array(10);
466
+ negativeArr = new Int32Array(10);
467
+ get(idx) {
468
+ if (idx < 0) {
469
+ idx = -idx - 1;
470
+ return this.negativeArr[idx];
471
+ }
472
+ else {
473
+ return this.positiveArr[idx];
474
+ }
475
+ }
476
+ set(idx, value) {
477
+ if (idx < 0) {
478
+ idx = -idx - 1;
479
+ if (idx >= this.negativeArr.length) {
480
+ const arr = this.negativeArr;
481
+ this.negativeArr = new Int32Array(arr.length * 2);
482
+ this.negativeArr.set(arr);
483
+ }
484
+ this.negativeArr[idx] = value;
485
+ }
486
+ else {
487
+ if (idx >= this.positiveArr.length) {
488
+ const arr = this.positiveArr;
489
+ this.positiveArr = new Int32Array(arr.length * 2);
490
+ this.positiveArr.set(arr);
491
+ }
492
+ this.positiveArr[idx] = value;
493
+ }
494
+ }
495
+ }
496
+ /**
497
+ * An array that supports fast negative indices for objects.
498
+ */
499
+ class FastArrayNegativeIndices {
500
+ positiveArr = [];
501
+ negativeArr = [];
502
+ get(idx) {
503
+ if (idx < 0) {
504
+ idx = -idx - 1;
505
+ return this.negativeArr[idx];
506
+ }
507
+ else {
508
+ return this.positiveArr[idx];
509
+ }
510
+ }
511
+ set(idx, value) {
512
+ if (idx < 0) {
513
+ idx = -idx - 1;
514
+ this.negativeArr[idx] = value;
515
+ }
516
+ else {
517
+ this.positiveArr[idx] = value;
518
+ }
519
+ }
520
+ }
521
+
522
+ function optimizeSequenceDiffs(sequence1, sequence2, sequenceDiffs) {
523
+ let result = sequenceDiffs;
524
+ result = joinSequenceDiffsByShifting(sequence1, sequence2, result);
525
+ // Sometimes, calling this function twice improves the result.
526
+ result = joinSequenceDiffsByShifting(sequence1, sequence2, result);
527
+ result = shiftSequenceDiffs(sequence1, sequence2, result);
528
+ return result;
529
+ }
530
+ /**
531
+ * This function fixes issues like this:
532
+ * ```
533
+ * import { Baz, Bar } from "foo";
534
+ * ```
535
+ * <->
536
+ * ```
537
+ * import { Baz, Bar, Foo } from "foo";
538
+ * ```
539
+ * Computed diff: [ {Add "," after Bar}, {Add "Foo " after space} }
540
+ * Improved diff: [{Add ", Foo" after Bar}]
541
+ */
542
+ function joinSequenceDiffsByShifting(sequence1, sequence2, sequenceDiffs) {
543
+ if (sequenceDiffs.length === 0) {
544
+ return sequenceDiffs;
545
+ }
546
+ const result = [];
547
+ result.push(sequenceDiffs[0]);
548
+ // First move them all to the left as much as possible and join them if possible
549
+ for (let i = 1; i < sequenceDiffs.length; i++) {
550
+ const prevResult = result[result.length - 1];
551
+ let cur = sequenceDiffs[i];
552
+ if (cur.seq1Range.isEmpty || cur.seq2Range.isEmpty) {
553
+ const length = cur.seq1Range.start - prevResult.seq1Range.endExclusive;
554
+ let d;
555
+ for (d = 1; d <= length; d++) {
556
+ if (sequence1.getElement(cur.seq1Range.start - d) !== sequence1.getElement(cur.seq1Range.endExclusive - d) ||
557
+ sequence2.getElement(cur.seq2Range.start - d) !== sequence2.getElement(cur.seq2Range.endExclusive - d)) {
558
+ break;
559
+ }
560
+ }
561
+ d--;
562
+ if (d === length) {
563
+ // Merge previous and current diff
564
+ result[result.length - 1] = new SequenceDiff(new OffsetRange(prevResult.seq1Range.start, cur.seq1Range.endExclusive - length), new OffsetRange(prevResult.seq2Range.start, cur.seq2Range.endExclusive - length));
565
+ continue;
566
+ }
567
+ cur = cur.delta(-d);
568
+ }
569
+ result.push(cur);
570
+ }
571
+ const result2 = [];
572
+ // Then move them all to the right and join them again if possible
573
+ for (let i = 0; i < result.length - 1; i++) {
574
+ const nextResult = result[i + 1];
575
+ let cur = result[i];
576
+ if (cur.seq1Range.isEmpty || cur.seq2Range.isEmpty) {
577
+ const length = nextResult.seq1Range.start - cur.seq1Range.endExclusive;
578
+ let d;
579
+ for (d = 0; d < length; d++) {
580
+ if (!sequence1.isStronglyEqual(cur.seq1Range.start + d, cur.seq1Range.endExclusive + d) ||
581
+ !sequence2.isStronglyEqual(cur.seq2Range.start + d, cur.seq2Range.endExclusive + d)) {
582
+ break;
583
+ }
584
+ }
585
+ if (d === length) {
586
+ // Merge previous and current diff
587
+ result[i + 1] = new SequenceDiff(new OffsetRange(cur.seq1Range.start + length, nextResult.seq1Range.endExclusive), new OffsetRange(cur.seq2Range.start + length, nextResult.seq2Range.endExclusive));
588
+ continue;
589
+ }
590
+ if (d > 0) {
591
+ cur = cur.delta(d);
592
+ }
593
+ }
594
+ result2.push(cur);
595
+ }
596
+ if (result.length > 0) {
597
+ result2.push(result[result.length - 1]);
598
+ }
599
+ return result2;
600
+ }
601
+ function shiftSequenceDiffs(sequence1, sequence2, sequenceDiffs) {
602
+ if (!sequence1.getBoundaryScore || !sequence2.getBoundaryScore) {
603
+ return sequenceDiffs;
604
+ }
605
+ for (let i = 0; i < sequenceDiffs.length; i++) {
606
+ const prevDiff = (i > 0 ? sequenceDiffs[i - 1] : undefined);
607
+ const diff = sequenceDiffs[i];
608
+ const nextDiff = (i + 1 < sequenceDiffs.length ? sequenceDiffs[i + 1] : undefined);
609
+ const seq1ValidRange = new OffsetRange(prevDiff ? prevDiff.seq1Range.endExclusive + 1 : 0, nextDiff ? nextDiff.seq1Range.start - 1 : sequence1.length);
610
+ const seq2ValidRange = new OffsetRange(prevDiff ? prevDiff.seq2Range.endExclusive + 1 : 0, nextDiff ? nextDiff.seq2Range.start - 1 : sequence2.length);
611
+ if (diff.seq1Range.isEmpty) {
612
+ sequenceDiffs[i] = shiftDiffToBetterPosition(diff, sequence1, sequence2, seq1ValidRange, seq2ValidRange);
613
+ }
614
+ else if (diff.seq2Range.isEmpty) {
615
+ sequenceDiffs[i] = shiftDiffToBetterPosition(diff.swap(), sequence2, sequence1, seq2ValidRange, seq1ValidRange).swap();
616
+ }
617
+ }
618
+ return sequenceDiffs;
619
+ }
620
+ function shiftDiffToBetterPosition(diff, sequence1, sequence2, seq1ValidRange, seq2ValidRange) {
621
+ const maxShiftLimit = 100; // To prevent performance issues
622
+ let deltaBefore = 1;
623
+ while (diff.seq1Range.start - deltaBefore >= seq1ValidRange.start &&
624
+ diff.seq2Range.start - deltaBefore >= seq2ValidRange.start &&
625
+ sequence2.isStronglyEqual(diff.seq2Range.start - deltaBefore, diff.seq2Range.endExclusive - deltaBefore) && deltaBefore < maxShiftLimit) {
626
+ deltaBefore++;
627
+ }
628
+ deltaBefore--;
629
+ let deltaAfter = 0;
630
+ while (diff.seq1Range.start + deltaAfter < seq1ValidRange.endExclusive &&
631
+ diff.seq2Range.endExclusive + deltaAfter < seq2ValidRange.endExclusive &&
632
+ sequence2.isStronglyEqual(diff.seq2Range.start + deltaAfter, diff.seq2Range.endExclusive + deltaAfter) && deltaAfter < maxShiftLimit) {
633
+ deltaAfter++;
634
+ }
635
+ if (deltaBefore === 0 && deltaAfter === 0) {
636
+ return diff;
637
+ }
638
+ let bestDelta = 0;
639
+ let bestScore = -1;
640
+ // Find best scored delta
641
+ for (let delta = -deltaBefore; delta <= deltaAfter; delta++) {
642
+ const seq2OffsetStart = diff.seq2Range.start + delta;
643
+ const seq2OffsetEndExclusive = diff.seq2Range.endExclusive + delta;
644
+ const seq1Offset = diff.seq1Range.start + delta;
645
+ const score = sequence1.getBoundaryScore(seq1Offset) + sequence2.getBoundaryScore(seq2OffsetStart) + sequence2.getBoundaryScore(seq2OffsetEndExclusive);
646
+ if (score > bestScore) {
647
+ bestScore = score;
648
+ bestDelta = delta;
649
+ }
650
+ }
651
+ return diff.delta(bestDelta);
652
+ }
653
+ function removeShortMatches(sequence1, sequence2, sequenceDiffs) {
654
+ const result = [];
655
+ for (const s of sequenceDiffs) {
656
+ const last = result[result.length - 1];
657
+ if (!last) {
658
+ result.push(s);
659
+ continue;
660
+ }
661
+ if (s.seq1Range.start - last.seq1Range.endExclusive <= 2 || s.seq2Range.start - last.seq2Range.endExclusive <= 2) {
662
+ result[result.length - 1] = new SequenceDiff(last.seq1Range.join(s.seq1Range), last.seq2Range.join(s.seq2Range));
663
+ }
664
+ else {
665
+ result.push(s);
666
+ }
667
+ }
668
+ return result;
669
+ }
670
+ function extendDiffsToEntireWordIfAppropriate(sequence1, sequence2, sequenceDiffs, findParent, force = false) {
671
+ const equalMappings = SequenceDiff.invert(sequenceDiffs, sequence1.length);
672
+ const additional = [];
673
+ let lastPoint = new OffsetPair(0, 0);
674
+ function scanWord(pair, equalMapping) {
675
+ if (pair.offset1 < lastPoint.offset1 || pair.offset2 < lastPoint.offset2) {
676
+ return;
677
+ }
678
+ const w1 = findParent(sequence1, pair.offset1);
679
+ const w2 = findParent(sequence2, pair.offset2);
680
+ if (!w1 || !w2) {
681
+ return;
682
+ }
683
+ let w = new SequenceDiff(w1, w2);
684
+ const equalPart = w.intersect(equalMapping);
685
+ let equalChars1 = equalPart.seq1Range.length;
686
+ let equalChars2 = equalPart.seq2Range.length;
687
+ while (equalMappings.length > 0) {
688
+ const next = equalMappings[0];
689
+ const intersects = next.seq1Range.intersects(w.seq1Range) || next.seq2Range.intersects(w.seq2Range);
690
+ if (!intersects) {
691
+ break;
692
+ }
693
+ const v1 = findParent(sequence1, next.seq1Range.start);
694
+ const v2 = findParent(sequence2, next.seq2Range.start);
695
+ const v = new SequenceDiff(v1, v2);
696
+ const equalPartV = v.intersect(next);
697
+ equalChars1 += equalPartV.seq1Range.length;
698
+ equalChars2 += equalPartV.seq2Range.length;
699
+ w = w.join(v);
700
+ if (w.seq1Range.endExclusive >= next.seq1Range.endExclusive) {
701
+ equalMappings.shift();
702
+ }
703
+ else {
704
+ break;
705
+ }
706
+ }
707
+ if ((force && equalChars1 + equalChars2 < w.seq1Range.length + w.seq2Range.length) || equalChars1 + equalChars2 < (w.seq1Range.length + w.seq2Range.length) * 2 / 3) {
708
+ additional.push(w);
709
+ }
710
+ lastPoint = w.getEndExclusives();
711
+ }
712
+ while (equalMappings.length > 0) {
713
+ const next = equalMappings.shift();
714
+ if (next.seq1Range.isEmpty) {
715
+ continue;
716
+ }
717
+ scanWord(next.getStarts(), next);
718
+ scanWord(next.getEndExclusives().delta(-1), next);
719
+ }
720
+ const merged = mergeSequenceDiffs(sequenceDiffs, additional);
721
+ return merged;
722
+ }
723
+ function mergeSequenceDiffs(sequenceDiffs1, sequenceDiffs2) {
724
+ const result = [];
725
+ while (sequenceDiffs1.length > 0 || sequenceDiffs2.length > 0) {
726
+ const sd1 = sequenceDiffs1[0];
727
+ const sd2 = sequenceDiffs2[0];
728
+ let next;
729
+ if (sd1 && (!sd2 || sd1.seq1Range.start < sd2.seq1Range.start)) {
730
+ next = sequenceDiffs1.shift();
731
+ }
732
+ else {
733
+ next = sequenceDiffs2.shift();
734
+ }
735
+ if (result.length > 0 && result[result.length - 1].seq1Range.endExclusive >= next.seq1Range.start) {
736
+ result[result.length - 1] = result[result.length - 1].join(next);
737
+ }
738
+ else {
739
+ result.push(next);
740
+ }
741
+ }
742
+ return result;
743
+ }
744
+ function removeVeryShortMatchingLinesBetweenDiffs(sequence1, _sequence2, sequenceDiffs) {
745
+ let diffs = sequenceDiffs;
746
+ if (diffs.length === 0) {
747
+ return diffs;
748
+ }
749
+ let counter = 0;
750
+ let shouldRepeat;
751
+ do {
752
+ shouldRepeat = false;
753
+ const result = [diffs[0]];
754
+ for (let i = 1; i < diffs.length; i++) {
755
+ const cur = diffs[i];
756
+ const lastResult = result[result.length - 1];
757
+ function shouldJoinDiffs(before, after) {
758
+ const unchangedRange = new OffsetRange(lastResult.seq1Range.endExclusive, cur.seq1Range.start);
759
+ const unchangedText = sequence1.getText(unchangedRange);
760
+ const unchangedTextWithoutWs = unchangedText.replace(/\s/g, '');
761
+ if (unchangedTextWithoutWs.length <= 4
762
+ && (before.seq1Range.length + before.seq2Range.length > 5 || after.seq1Range.length + after.seq2Range.length > 5)) {
763
+ return true;
764
+ }
765
+ return false;
766
+ }
767
+ const shouldJoin = shouldJoinDiffs(lastResult, cur);
768
+ if (shouldJoin) {
769
+ shouldRepeat = true;
770
+ result[result.length - 1] = result[result.length - 1].join(cur);
771
+ }
772
+ else {
773
+ result.push(cur);
774
+ }
775
+ }
776
+ diffs = result;
777
+ } while (counter++ < 10 && shouldRepeat);
778
+ return diffs;
779
+ }
780
+ function removeVeryShortMatchingTextBetweenLongDiffs(sequence1, sequence2, sequenceDiffs) {
781
+ let diffs = sequenceDiffs;
782
+ if (diffs.length === 0) {
783
+ return diffs;
784
+ }
785
+ let counter = 0;
786
+ let shouldRepeat;
787
+ do {
788
+ shouldRepeat = false;
789
+ const result = [diffs[0]];
790
+ for (let i = 1; i < diffs.length; i++) {
791
+ const cur = diffs[i];
792
+ const lastResult = result[result.length - 1];
793
+ function shouldJoinDiffs(before, after) {
794
+ const unchangedRange = new OffsetRange(lastResult.seq1Range.endExclusive, cur.seq1Range.start);
795
+ const unchangedLineCount = sequence1.countLinesIn(unchangedRange);
796
+ if (unchangedLineCount > 5 || unchangedRange.length > 500) {
797
+ return false;
798
+ }
799
+ const unchangedText = sequence1.getText(unchangedRange).trim();
800
+ if (unchangedText.length > 20 || unchangedText.split(/\r\n|\r|\n/).length > 1) {
801
+ return false;
802
+ }
803
+ const beforeLineCount1 = sequence1.countLinesIn(before.seq1Range);
804
+ const beforeSeq1Length = before.seq1Range.length;
805
+ const beforeLineCount2 = sequence2.countLinesIn(before.seq2Range);
806
+ const beforeSeq2Length = before.seq2Range.length;
807
+ const afterLineCount1 = sequence1.countLinesIn(after.seq1Range);
808
+ const afterSeq1Length = after.seq1Range.length;
809
+ const afterLineCount2 = sequence2.countLinesIn(after.seq2Range);
810
+ const afterSeq2Length = after.seq2Range.length;
811
+ const max = 2 * 40 + 50;
812
+ function cap(v) {
813
+ return Math.min(v, max);
814
+ }
815
+ if (Math.pow(Math.pow(cap(beforeLineCount1 * 40 + beforeSeq1Length), 1.5) + Math.pow(cap(beforeLineCount2 * 40 + beforeSeq2Length), 1.5), 1.5)
816
+ + Math.pow(Math.pow(cap(afterLineCount1 * 40 + afterSeq1Length), 1.5) + Math.pow(cap(afterLineCount2 * 40 + afterSeq2Length), 1.5), 1.5) > ((max ** 1.5) ** 1.5) * 1.3) {
817
+ return true;
818
+ }
819
+ return false;
820
+ }
821
+ const shouldJoin = shouldJoinDiffs(lastResult, cur);
822
+ if (shouldJoin) {
823
+ shouldRepeat = true;
824
+ result[result.length - 1] = result[result.length - 1].join(cur);
825
+ }
826
+ else {
827
+ result.push(cur);
828
+ }
829
+ }
830
+ diffs = result;
831
+ } while (counter++ < 10 && shouldRepeat);
832
+ const newDiffs = [];
833
+ // Remove short suffixes/prefixes
834
+ forEachWithNeighbors(diffs, (prev, cur, next) => {
835
+ let newDiff = cur;
836
+ function shouldMarkAsChanged(text) {
837
+ return text.length > 0 && text.trim().length <= 3 && cur.seq1Range.length + cur.seq2Range.length > 100;
838
+ }
839
+ const fullRange1 = sequence1.extendToFullLines(cur.seq1Range);
840
+ const prefix = sequence1.getText(new OffsetRange(fullRange1.start, cur.seq1Range.start));
841
+ if (shouldMarkAsChanged(prefix)) {
842
+ newDiff = newDiff.deltaStart(-prefix.length);
843
+ }
844
+ const suffix = sequence1.getText(new OffsetRange(cur.seq1Range.endExclusive, fullRange1.endExclusive));
845
+ if (shouldMarkAsChanged(suffix)) {
846
+ newDiff = newDiff.deltaEnd(suffix.length);
847
+ }
848
+ const availableSpace = SequenceDiff.fromOffsetPairs(prev ? prev.getEndExclusives() : OffsetPair.zero, next ? next.getStarts() : OffsetPair.max);
849
+ const intersected = newDiff.intersect(availableSpace);
850
+ if (newDiffs.length > 0 && intersected.getStarts().equals(newDiffs[newDiffs.length - 1].getEndExclusives())) {
851
+ newDiffs[newDiffs.length - 1] = newDiffs[newDiffs.length - 1].join(intersected);
852
+ }
853
+ else {
854
+ newDiffs.push(intersected);
855
+ }
856
+ });
857
+ return newDiffs;
858
+ }
859
+ function forEachWithNeighbors(items, callback) {
860
+ for (let i = 0; i < items.length; i++) {
861
+ callback(items[i - 1], items[i], items[i + 1]);
862
+ }
863
+ }
864
+
865
+ const CharCode$1 = {
866
+ Space: 32,
867
+ Tab: 9,
868
+ };
869
+ class LineSequence {
870
+ trimmedHash;
871
+ lines;
872
+ constructor(trimmedHash, lines) {
873
+ this.trimmedHash = trimmedHash;
874
+ this.lines = lines;
875
+ }
876
+ getElement(offset) {
877
+ return this.trimmedHash[offset];
878
+ }
879
+ get length() {
880
+ return this.trimmedHash.length;
881
+ }
882
+ getBoundaryScore(length) {
883
+ const indentationBefore = length === 0 ? 0 : getIndentation(this.lines[length - 1]);
884
+ const indentationAfter = length === this.lines.length ? 0 : getIndentation(this.lines[length]);
885
+ return 1000 - (indentationBefore + indentationAfter);
886
+ }
887
+ getText(range) {
888
+ return this.lines.slice(range.start, range.endExclusive).join('\n');
889
+ }
890
+ isStronglyEqual(offset1, offset2) {
891
+ return this.lines[offset1] === this.lines[offset2];
892
+ }
893
+ }
894
+ function getIndentation(str) {
895
+ let i = 0;
896
+ while (i < str.length && (str.charCodeAt(i) === CharCode$1.Space || str.charCodeAt(i) === CharCode$1.Tab)) {
897
+ i++;
898
+ }
899
+ return i;
900
+ }
901
+
902
+ const CharCode = {
903
+ LineFeed: 10,
904
+ CarriageReturn: 13,
905
+ Space: 32,
906
+ Tab: 9,
907
+ a: 97,
908
+ z: 122,
909
+ A: 65,
910
+ Z: 90,
911
+ Digit0: 48,
912
+ Digit9: 57,
913
+ Comma: 44,
914
+ Semicolon: 59,
915
+ };
916
+ function isSpace(charCode) {
917
+ return charCode === CharCode.Space || charCode === CharCode.Tab;
918
+ }
919
+ class Range {
920
+ startLineNumber;
921
+ startColumn;
922
+ endLineNumber;
923
+ endColumn;
924
+ constructor(startLineNumber, startColumn, endLineNumber, endColumn) {
925
+ this.startLineNumber = startLineNumber;
926
+ this.startColumn = startColumn;
927
+ this.endLineNumber = endLineNumber;
928
+ this.endColumn = endColumn;
929
+ }
930
+ static fromPositions(start, end) {
931
+ return new Range(start.lineNumber, start.column, end.lineNumber, end.column);
932
+ }
933
+ }
934
+ class Position {
935
+ lineNumber;
936
+ column;
937
+ constructor(lineNumber, column) {
938
+ this.lineNumber = lineNumber;
939
+ this.column = column;
940
+ }
941
+ isBefore(other) {
942
+ if (this.lineNumber < other.lineNumber) {
943
+ return true;
944
+ }
945
+ if (other.lineNumber < this.lineNumber) {
946
+ return false;
947
+ }
948
+ return this.column < other.column;
949
+ }
950
+ }
951
+ class LinesSliceCharSequence {
952
+ lines;
953
+ considerWhitespaceChanges;
954
+ elements = [];
955
+ firstElementOffsetByLineIdx = [];
956
+ lineStartOffsets = [];
957
+ trimmedWsLengthsByLineIdx = [];
958
+ _range;
959
+ constructor(lines, range, considerWhitespaceChanges) {
960
+ this.lines = lines;
961
+ this.considerWhitespaceChanges = considerWhitespaceChanges;
962
+ this._range = range;
963
+ this.firstElementOffsetByLineIdx.push(0);
964
+ for (let lineNumber = this._range.startLineNumber; lineNumber <= this._range.endLineNumber; lineNumber++) {
965
+ let line = lines[lineNumber - 1];
966
+ let lineStartOffset = 0;
967
+ if (lineNumber === this._range.startLineNumber && this._range.startColumn > 1) {
968
+ lineStartOffset = this._range.startColumn - 1;
969
+ line = line.substring(lineStartOffset);
970
+ }
971
+ this.lineStartOffsets.push(lineStartOffset);
972
+ let trimmedWsLength = 0;
973
+ if (!considerWhitespaceChanges) {
974
+ const trimmedStartLine = line.trimStart();
975
+ trimmedWsLength = line.length - trimmedStartLine.length;
976
+ line = trimmedStartLine.trimEnd();
977
+ }
978
+ this.trimmedWsLengthsByLineIdx.push(trimmedWsLength);
979
+ const lineLength = lineNumber === this._range.endLineNumber ? Math.min(this._range.endColumn - 1 - lineStartOffset - trimmedWsLength, line.length) : line.length;
980
+ for (let i = 0; i < lineLength; i++) {
981
+ this.elements.push(line.charCodeAt(i));
982
+ }
983
+ if (lineNumber < this._range.endLineNumber) {
984
+ this.elements.push('\n'.charCodeAt(0));
985
+ this.firstElementOffsetByLineIdx.push(this.elements.length);
986
+ }
987
+ }
988
+ }
989
+ toString() {
990
+ return `Slice: "${this.text}"`;
991
+ }
992
+ get text() {
993
+ return this.getText(new OffsetRange(0, this.length));
994
+ }
995
+ getText(range) {
996
+ return this.elements.slice(range.start, range.endExclusive).map(e => String.fromCharCode(e)).join('');
997
+ }
998
+ getElement(offset) {
999
+ return this.elements[offset];
1000
+ }
1001
+ get length() {
1002
+ return this.elements.length;
1003
+ }
1004
+ getBoundaryScore(length) {
1005
+ const prevCategory = getCategory(length > 0 ? this.elements[length - 1] : -1);
1006
+ const nextCategory = getCategory(length < this.elements.length ? this.elements[length] : -1);
1007
+ if (prevCategory === 7 /* CharBoundaryCategory.LineBreakCR */ && nextCategory === 8 /* CharBoundaryCategory.LineBreakLF */) {
1008
+ // don't break between \r and \n
1009
+ return 0;
1010
+ }
1011
+ if (prevCategory === 8 /* CharBoundaryCategory.LineBreakLF */) {
1012
+ // prefer the linebreak before the change
1013
+ return 150;
1014
+ }
1015
+ let score = 0;
1016
+ if (prevCategory !== nextCategory) {
1017
+ score += 10;
1018
+ if (prevCategory === 0 /* CharBoundaryCategory.WordLower */ && nextCategory === 1 /* CharBoundaryCategory.WordUpper */) {
1019
+ score += 1;
1020
+ }
1021
+ }
1022
+ score += getCategoryBoundaryScore(prevCategory);
1023
+ score += getCategoryBoundaryScore(nextCategory);
1024
+ return score;
1025
+ }
1026
+ translateOffset(offset, preference = 'right') {
1027
+ const i = findLastIdxMonotonous(this.firstElementOffsetByLineIdx, (value) => value <= offset);
1028
+ const lineOffset = offset - this.firstElementOffsetByLineIdx[i];
1029
+ return new Position(this._range.startLineNumber + i, 1 + this.lineStartOffsets[i] + lineOffset + ((lineOffset === 0 && preference === 'left') ? 0 : this.trimmedWsLengthsByLineIdx[i]));
1030
+ }
1031
+ translateRange(range) {
1032
+ const pos1 = this.translateOffset(range.start, 'right');
1033
+ const pos2 = this.translateOffset(range.endExclusive, 'left');
1034
+ if (pos2.isBefore(pos1)) {
1035
+ return Range.fromPositions(pos2, pos2);
1036
+ }
1037
+ return Range.fromPositions(pos1, pos2);
1038
+ }
1039
+ /**
1040
+ * Finds the word that contains the character at the given offset
1041
+ */
1042
+ findWordContaining(offset) {
1043
+ if (offset < 0 || offset >= this.elements.length) {
1044
+ return undefined;
1045
+ }
1046
+ if (!isWordChar(this.elements[offset])) {
1047
+ return undefined;
1048
+ }
1049
+ // find start
1050
+ let start = offset;
1051
+ while (start > 0 && isWordChar(this.elements[start - 1])) {
1052
+ start--;
1053
+ }
1054
+ // find end
1055
+ let end = offset;
1056
+ while (end < this.elements.length && isWordChar(this.elements[end])) {
1057
+ end++;
1058
+ }
1059
+ return new OffsetRange(start, end);
1060
+ }
1061
+ /** fooBar has the two sub-words foo and bar */
1062
+ findSubWordContaining(offset) {
1063
+ if (offset < 0 || offset >= this.elements.length) {
1064
+ return undefined;
1065
+ }
1066
+ if (!isWordChar(this.elements[offset])) {
1067
+ return undefined;
1068
+ }
1069
+ // find start
1070
+ let start = offset;
1071
+ while (start > 0 && isWordChar(this.elements[start - 1]) && !isUpperCase(this.elements[start])) {
1072
+ start--;
1073
+ }
1074
+ // find end
1075
+ let end = offset;
1076
+ while (end < this.elements.length && isWordChar(this.elements[end]) && !isUpperCase(this.elements[end])) {
1077
+ end++;
1078
+ }
1079
+ return new OffsetRange(start, end);
1080
+ }
1081
+ countLinesIn(range) {
1082
+ return this.translateOffset(range.endExclusive).lineNumber - this.translateOffset(range.start).lineNumber;
1083
+ }
1084
+ isStronglyEqual(offset1, offset2) {
1085
+ return this.elements[offset1] === this.elements[offset2];
1086
+ }
1087
+ extendToFullLines(range) {
1088
+ const start = findLastMonotonous(this.firstElementOffsetByLineIdx, x => x <= range.start) ?? 0;
1089
+ const end = findFirstMonotonous(this.firstElementOffsetByLineIdx, x => range.endExclusive <= x) ?? this.elements.length;
1090
+ return new OffsetRange(start, end);
1091
+ }
1092
+ }
1093
+ function isWordChar(charCode) {
1094
+ return charCode >= CharCode.a && charCode <= CharCode.z
1095
+ || charCode >= CharCode.A && charCode <= CharCode.Z
1096
+ || charCode >= CharCode.Digit0 && charCode <= CharCode.Digit9;
1097
+ }
1098
+ function isUpperCase(charCode) {
1099
+ return charCode >= CharCode.A && charCode <= CharCode.Z;
1100
+ }
1101
+ const categoryScore = {
1102
+ [0 /* CharBoundaryCategory.WordLower */]: 0,
1103
+ [1 /* CharBoundaryCategory.WordUpper */]: 0,
1104
+ [2 /* CharBoundaryCategory.WordNumber */]: 0,
1105
+ [3 /* CharBoundaryCategory.End */]: 10,
1106
+ [4 /* CharBoundaryCategory.Other */]: 2,
1107
+ [5 /* CharBoundaryCategory.Separator */]: 30,
1108
+ [6 /* CharBoundaryCategory.Space */]: 3,
1109
+ [7 /* CharBoundaryCategory.LineBreakCR */]: 10,
1110
+ [8 /* CharBoundaryCategory.LineBreakLF */]: 10,
1111
+ };
1112
+ function getCategoryBoundaryScore(category) {
1113
+ return categoryScore[category];
1114
+ }
1115
+ function getCategory(charCode) {
1116
+ if (charCode === CharCode.LineFeed) {
1117
+ return 8 /* CharBoundaryCategory.LineBreakLF */;
1118
+ }
1119
+ else if (charCode === CharCode.CarriageReturn) {
1120
+ return 7 /* CharBoundaryCategory.LineBreakCR */;
1121
+ }
1122
+ else if (isSpace(charCode)) {
1123
+ return 6 /* CharBoundaryCategory.Space */;
1124
+ }
1125
+ else if (charCode >= CharCode.a && charCode <= CharCode.z) {
1126
+ return 0 /* CharBoundaryCategory.WordLower */;
1127
+ }
1128
+ else if (charCode >= CharCode.A && charCode <= CharCode.Z) {
1129
+ return 1 /* CharBoundaryCategory.WordUpper */;
1130
+ }
1131
+ else if (charCode >= CharCode.Digit0 && charCode <= CharCode.Digit9) {
1132
+ return 2 /* CharBoundaryCategory.WordNumber */;
1133
+ }
1134
+ else if (charCode === -1) {
1135
+ return 3 /* CharBoundaryCategory.End */;
1136
+ }
1137
+ else if (charCode === CharCode.Comma || charCode === CharCode.Semicolon) {
1138
+ return 5 /* CharBoundaryCategory.Separator */;
1139
+ }
1140
+ else {
1141
+ return 4 /* CharBoundaryCategory.Other */;
1142
+ }
1143
+ }
1144
+ // Binary search helpers
1145
+ function findLastIdxMonotonous(array, predicate) {
1146
+ let low = 0;
1147
+ let high = array.length - 1;
1148
+ while (low <= high) {
1149
+ const mid = Math.floor((low + high) / 2);
1150
+ if (predicate(array[mid])) {
1151
+ low = mid + 1;
1152
+ }
1153
+ else {
1154
+ high = mid - 1;
1155
+ }
1156
+ }
1157
+ return high;
1158
+ }
1159
+ function findLastMonotonous(array, predicate) {
1160
+ const idx = findLastIdxMonotonous(array, predicate);
1161
+ return idx >= 0 ? array[idx] : undefined;
1162
+ }
1163
+ function findFirstMonotonous(array, predicate) {
1164
+ let low = 0;
1165
+ let high = array.length - 1;
1166
+ while (low <= high) {
1167
+ const mid = Math.floor((low + high) / 2);
1168
+ if (predicate(array[mid])) {
1169
+ high = mid - 1;
1170
+ }
1171
+ else {
1172
+ low = mid + 1;
1173
+ }
1174
+ }
1175
+ return low < array.length ? array[low] : undefined;
1176
+ }
1177
+
1178
+ /**
1179
+ * A range of lines (1-based, end is exclusive).
1180
+ */
1181
+ class LineRange {
1182
+ startLineNumber;
1183
+ endLineNumberExclusive;
1184
+ constructor(startLineNumber, endLineNumberExclusive) {
1185
+ this.startLineNumber = startLineNumber;
1186
+ this.endLineNumberExclusive = endLineNumberExclusive;
1187
+ if (startLineNumber > endLineNumberExclusive) {
1188
+ throw new Error(`Invalid range: ${startLineNumber} > ${endLineNumberExclusive}`);
1189
+ }
1190
+ }
1191
+ get isEmpty() {
1192
+ return this.startLineNumber === this.endLineNumberExclusive;
1193
+ }
1194
+ get length() {
1195
+ return this.endLineNumberExclusive - this.startLineNumber;
1196
+ }
1197
+ join(other) {
1198
+ return new LineRange(Math.min(this.startLineNumber, other.startLineNumber), Math.max(this.endLineNumberExclusive, other.endLineNumberExclusive));
1199
+ }
1200
+ intersectsOrTouches(other) {
1201
+ return this.startLineNumber <= other.endLineNumberExclusive
1202
+ && other.startLineNumber <= this.endLineNumberExclusive;
1203
+ }
1204
+ toOffsetRange() {
1205
+ return new OffsetRange(this.startLineNumber - 1, this.endLineNumberExclusive - 1);
1206
+ }
1207
+ toString() {
1208
+ return `[${this.startLineNumber}, ${this.endLineNumberExclusive})`;
1209
+ }
1210
+ }
1211
+ /**
1212
+ * A mapping between two ranges.
1213
+ */
1214
+ class RangeMapping {
1215
+ originalRange;
1216
+ modifiedRange;
1217
+ constructor(originalRange, modifiedRange) {
1218
+ this.originalRange = originalRange;
1219
+ this.modifiedRange = modifiedRange;
1220
+ }
1221
+ toString() {
1222
+ return `${rangeToString(this.originalRange)} <-> ${rangeToString(this.modifiedRange)}`;
1223
+ }
1224
+ static assertSorted(rangeMappings) {
1225
+ for (let i = 1; i < rangeMappings.length; i++) {
1226
+ const prev = rangeMappings[i - 1];
1227
+ const cur = rangeMappings[i];
1228
+ if (!(prev.originalRange.endLineNumber <= cur.originalRange.startLineNumber ||
1229
+ (prev.originalRange.endLineNumber === cur.originalRange.startLineNumber && prev.originalRange.endColumn <= cur.originalRange.startColumn))) {
1230
+ throw new Error('RangeMappings must be sorted');
1231
+ }
1232
+ }
1233
+ }
1234
+ }
1235
+ function rangeToString(range) {
1236
+ return `(${range.startLineNumber}:${range.startColumn})-(${range.endLineNumber}:${range.endColumn})`;
1237
+ }
1238
+ /**
1239
+ * A mapping between two line ranges.
1240
+ */
1241
+ class LineRangeMapping {
1242
+ original;
1243
+ modified;
1244
+ constructor(original, modified) {
1245
+ this.original = original;
1246
+ this.modified = modified;
1247
+ }
1248
+ toString() {
1249
+ return `${this.original} <-> ${this.modified}`;
1250
+ }
1251
+ /**
1252
+ * This method assumes that the LineRangeMapping describes a valid diff!
1253
+ * I.e. if one range is empty, the other range cannot be the entire document.
1254
+ * It avoids various problems when the line range points to non-existing line-numbers.
1255
+ */
1256
+ toRangeMapping2(originalLines, modifiedLines) {
1257
+ const isValidLineNumber = (lineNumber, lines) => {
1258
+ return lineNumber >= 1 && lineNumber <= lines.length;
1259
+ };
1260
+ const normalizePosition = (lineNumber, column, lines) => {
1261
+ if (lineNumber < 1) {
1262
+ return new Position(1, 1);
1263
+ }
1264
+ if (lineNumber > lines.length) {
1265
+ return new Position(lines.length, lines[lines.length - 1].length + 1);
1266
+ }
1267
+ const line = lines[lineNumber - 1];
1268
+ if (column > line.length + 1) {
1269
+ return new Position(lineNumber, line.length + 1);
1270
+ }
1271
+ return new Position(lineNumber, column);
1272
+ };
1273
+ if (isValidLineNumber(this.original.endLineNumberExclusive, originalLines)
1274
+ && isValidLineNumber(this.modified.endLineNumberExclusive, modifiedLines)) {
1275
+ return new RangeMapping(new Range(this.original.startLineNumber, 1, this.original.endLineNumberExclusive, 1), new Range(this.modified.startLineNumber, 1, this.modified.endLineNumberExclusive, 1));
1276
+ }
1277
+ if (!this.original.isEmpty && !this.modified.isEmpty) {
1278
+ return new RangeMapping(Range.fromPositions(new Position(this.original.startLineNumber, 1), normalizePosition(this.original.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER, originalLines)), Range.fromPositions(new Position(this.modified.startLineNumber, 1), normalizePosition(this.modified.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER, modifiedLines)));
1279
+ }
1280
+ if (this.original.startLineNumber > 1 && this.modified.startLineNumber > 1) {
1281
+ return new RangeMapping(Range.fromPositions(normalizePosition(this.original.startLineNumber - 1, Number.MAX_SAFE_INTEGER, originalLines), normalizePosition(this.original.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER, originalLines)), Range.fromPositions(normalizePosition(this.modified.startLineNumber - 1, Number.MAX_SAFE_INTEGER, modifiedLines), normalizePosition(this.modified.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER, modifiedLines)));
1282
+ }
1283
+ // Situation now: one range is empty and one range touches the last line and one range starts at line 1.
1284
+ // This shouldn't happen for valid diffs.
1285
+ throw new Error('Invalid diff: cannot convert to range mapping');
1286
+ }
1287
+ }
1288
+ /**
1289
+ * A detailed mapping between two line ranges, including inner changes.
1290
+ */
1291
+ class DetailedLineRangeMapping extends LineRangeMapping {
1292
+ innerChanges;
1293
+ constructor(original, modified, innerChanges) {
1294
+ super(original, modified);
1295
+ this.innerChanges = innerChanges;
1296
+ }
1297
+ }
1298
+ /**
1299
+ * Result of a lines diff computation.
1300
+ */
1301
+ class LinesDiff {
1302
+ changes;
1303
+ moves;
1304
+ hitTimeout;
1305
+ constructor(changes, moves, hitTimeout) {
1306
+ this.changes = changes;
1307
+ this.moves = moves;
1308
+ this.hitTimeout = hitTimeout;
1309
+ }
1310
+ }
1311
+ /**
1312
+ * Represents text that was moved from one location to another.
1313
+ */
1314
+ class MovedText {
1315
+ lineRangeMapping;
1316
+ changes;
1317
+ constructor(lineRangeMapping, changes) {
1318
+ this.lineRangeMapping = lineRangeMapping;
1319
+ this.changes = changes;
1320
+ }
1321
+ }
1322
+ /**
1323
+ * Helper to convert from range mappings to line range mappings.
1324
+ */
1325
+ function lineRangeMappingFromRangeMappings(alignments, originalLines, modifiedLines, dontAssertStartLine = false) {
1326
+ const changes = [];
1327
+ for (const g of groupAdjacentBy(alignments.map(a => getLineRangeMapping(a, originalLines, modifiedLines)), (a1, a2) => a1.original.intersectsOrTouches(a2.original)
1328
+ || a1.modified.intersectsOrTouches(a2.modified))) {
1329
+ const first = g[0];
1330
+ const last = g[g.length - 1];
1331
+ changes.push(new DetailedLineRangeMapping(first.original.join(last.original), first.modified.join(last.modified), g.map(a => a.innerChanges[0])));
1332
+ }
1333
+ if (!dontAssertStartLine) {
1334
+ // Assert that the changes are sorted and non-overlapping (but don't throw - just log in debug)
1335
+ for (let i = 1; i < changes.length; i++) {
1336
+ const prev = changes[i - 1];
1337
+ const cur = changes[i];
1338
+ if (prev.original.endLineNumberExclusive > cur.original.startLineNumber ||
1339
+ prev.modified.endLineNumberExclusive > cur.modified.startLineNumber) {
1340
+ // Silently skip validation issue - may be expected in some edge cases
1341
+ break;
1342
+ }
1343
+ }
1344
+ }
1345
+ return changes;
1346
+ }
1347
+ function getLineRangeMapping(rangeMapping, originalLines, modifiedLines) {
1348
+ let lineStartDelta = 0;
1349
+ let lineEndDelta = 0;
1350
+ // rangeMapping describes the edit that replaces `rangeMapping.originalRange` with `newText := getText(modifiedLines, rangeMapping.modifiedRange)`.
1351
+ // original: ]xxx \n <- this line is not modified
1352
+ // modified: ]xx \n
1353
+ if (rangeMapping.modifiedRange.endColumn === 1 && rangeMapping.originalRange.endColumn === 1
1354
+ && rangeMapping.originalRange.startLineNumber + lineStartDelta <= rangeMapping.originalRange.endLineNumber
1355
+ && rangeMapping.modifiedRange.startLineNumber + lineStartDelta <= rangeMapping.modifiedRange.endLineNumber) {
1356
+ // We can only do this if the range is not empty yet
1357
+ lineEndDelta = -1;
1358
+ }
1359
+ // original: xxx[ \n <- this line is not modified
1360
+ // modified: xxx[ \n
1361
+ if (rangeMapping.modifiedRange.startColumn - 1 >= (modifiedLines[rangeMapping.modifiedRange.startLineNumber - 1]?.length ?? 0)
1362
+ && rangeMapping.originalRange.startColumn - 1 >= (originalLines[rangeMapping.originalRange.startLineNumber - 1]?.length ?? 0)
1363
+ && rangeMapping.originalRange.startLineNumber <= rangeMapping.originalRange.endLineNumber + lineEndDelta
1364
+ && rangeMapping.modifiedRange.startLineNumber <= rangeMapping.modifiedRange.endLineNumber + lineEndDelta) {
1365
+ // We can only do this if the range is not empty yet
1366
+ lineStartDelta = 1;
1367
+ }
1368
+ const originalLineRange = new LineRange(rangeMapping.originalRange.startLineNumber + lineStartDelta, rangeMapping.originalRange.endLineNumber + 1 + lineEndDelta);
1369
+ const modifiedLineRange = new LineRange(rangeMapping.modifiedRange.startLineNumber + lineStartDelta, rangeMapping.modifiedRange.endLineNumber + 1 + lineEndDelta);
1370
+ return new DetailedLineRangeMapping(originalLineRange, modifiedLineRange, [rangeMapping]);
1371
+ }
1372
+ function* groupAdjacentBy(items, shouldBeGrouped) {
1373
+ let currentGroup;
1374
+ let last;
1375
+ for (const item of items) {
1376
+ if (last !== undefined && shouldBeGrouped(last, item)) {
1377
+ currentGroup.push(item);
1378
+ }
1379
+ else {
1380
+ if (currentGroup) {
1381
+ yield currentGroup;
1382
+ }
1383
+ currentGroup = [item];
1384
+ }
1385
+ last = item;
1386
+ }
1387
+ if (currentGroup) {
1388
+ yield currentGroup;
1389
+ }
1390
+ }
1391
+ class ArrayText {
1392
+ lines;
1393
+ constructor(lines) {
1394
+ this.lines = lines;
1395
+ }
1396
+ get lineCount() {
1397
+ return this.lines.length;
1398
+ }
1399
+ getLineContent(lineNumber) {
1400
+ return this.lines[lineNumber - 1];
1401
+ }
1402
+ }
1403
+
1404
+ /**
1405
+ * The main diff computer that computes detailed line diffs.
1406
+ */
1407
+ class DefaultLinesDiffComputer {
1408
+ _dynamicProgrammingDiffing = new DynamicProgrammingDiffing();
1409
+ _myersDiffingAlgorithm = new MyersDiffAlgorithm();
1410
+ computeDiff(originalLines, modifiedLines, options) {
1411
+ // Handle identical single line
1412
+ if (originalLines.length <= 1 && arraysEqual(originalLines, modifiedLines)) {
1413
+ return new LinesDiff([], [], false);
1414
+ }
1415
+ // Handle empty single line - treat as full replacement
1416
+ if (originalLines.length === 1 && originalLines[0].length === 0 || modifiedLines.length === 1 && modifiedLines[0].length === 0) {
1417
+ return new LinesDiff([
1418
+ new DetailedLineRangeMapping(new LineRange(1, originalLines.length + 1), new LineRange(1, modifiedLines.length + 1), [
1419
+ new RangeMapping(new Range(1, 1, originalLines.length, originalLines[originalLines.length - 1].length + 1), new Range(1, 1, modifiedLines.length, modifiedLines[modifiedLines.length - 1].length + 1))
1420
+ ])
1421
+ ], [], false);
1422
+ }
1423
+ const timeout = options.maxComputationTimeMs === 0 ? InfiniteTimeout.instance : new DateTimeout(options.maxComputationTimeMs);
1424
+ const considerWhitespaceChanges = !options.ignoreTrimWhitespace;
1425
+ // Create perfect hash for lines (trimmed)
1426
+ const perfectHashes = new Map();
1427
+ function getOrCreateHash(text) {
1428
+ let hash = perfectHashes.get(text);
1429
+ if (hash === undefined) {
1430
+ hash = perfectHashes.size;
1431
+ perfectHashes.set(text, hash);
1432
+ }
1433
+ return hash;
1434
+ }
1435
+ const originalLinesHashes = originalLines.map((l) => getOrCreateHash(l.trim()));
1436
+ const modifiedLinesHashes = modifiedLines.map((l) => getOrCreateHash(l.trim()));
1437
+ const sequence1 = new LineSequence(originalLinesHashes, originalLines);
1438
+ const sequence2 = new LineSequence(modifiedLinesHashes, modifiedLines);
1439
+ // Choose algorithm based on size
1440
+ const lineAlignmentResult = (() => {
1441
+ if (sequence1.length + sequence2.length < 1700) {
1442
+ // Use the improved algorithm for small files
1443
+ return this._dynamicProgrammingDiffing.compute(sequence1, sequence2, timeout, (offset1, offset2) => originalLines[offset1] === modifiedLines[offset2]
1444
+ ? modifiedLines[offset2].length === 0
1445
+ ? 0.1
1446
+ : 1 + Math.log(1 + modifiedLines[offset2].length)
1447
+ : 0.99);
1448
+ }
1449
+ return this._myersDiffingAlgorithm.compute(sequence1, sequence2, timeout);
1450
+ })();
1451
+ let lineAlignments = lineAlignmentResult.diffs;
1452
+ let hitTimeout = lineAlignmentResult.hitTimeout;
1453
+ // Apply heuristics
1454
+ lineAlignments = optimizeSequenceDiffs(sequence1, sequence2, lineAlignments);
1455
+ lineAlignments = removeVeryShortMatchingLinesBetweenDiffs(sequence1, sequence2, lineAlignments);
1456
+ const alignments = [];
1457
+ const scanForWhitespaceChanges = (equalLinesCount) => {
1458
+ if (!considerWhitespaceChanges) {
1459
+ return;
1460
+ }
1461
+ for (let i = 0; i < equalLinesCount; i++) {
1462
+ const seq1Offset = seq1LastStart + i;
1463
+ const seq2Offset = seq2LastStart + i;
1464
+ if (originalLines[seq1Offset] !== modifiedLines[seq2Offset]) {
1465
+ // This is because of whitespace changes, diff these lines
1466
+ const characterDiffs = this._refineDiff(originalLines, modifiedLines, new SequenceDiff(new OffsetRange(seq1Offset, seq1Offset + 1), new OffsetRange(seq2Offset, seq2Offset + 1)), timeout, considerWhitespaceChanges, options);
1467
+ for (const a of characterDiffs.mappings) {
1468
+ alignments.push(a);
1469
+ }
1470
+ if (characterDiffs.hitTimeout) {
1471
+ hitTimeout = true;
1472
+ }
1473
+ }
1474
+ }
1475
+ };
1476
+ let seq1LastStart = 0;
1477
+ let seq2LastStart = 0;
1478
+ for (const diff of lineAlignments) {
1479
+ const equalLinesCount = diff.seq1Range.start - seq1LastStart;
1480
+ scanForWhitespaceChanges(equalLinesCount);
1481
+ seq1LastStart = diff.seq1Range.endExclusive;
1482
+ seq2LastStart = diff.seq2Range.endExclusive;
1483
+ const characterDiffs = this._refineDiff(originalLines, modifiedLines, diff, timeout, considerWhitespaceChanges, options);
1484
+ if (characterDiffs.hitTimeout) {
1485
+ hitTimeout = true;
1486
+ }
1487
+ for (const a of characterDiffs.mappings) {
1488
+ alignments.push(a);
1489
+ }
1490
+ }
1491
+ scanForWhitespaceChanges(originalLines.length - seq1LastStart);
1492
+ const original = new ArrayText(originalLines);
1493
+ const modified = new ArrayText(modifiedLines);
1494
+ const changes = lineRangeMappingFromRangeMappings(alignments, original.lines, modified.lines);
1495
+ // TODO: Compute moves if options.computeMoves is true
1496
+ const moves = [];
1497
+ return new LinesDiff(changes, moves, hitTimeout);
1498
+ }
1499
+ _refineDiff(originalLines, modifiedLines, diff, timeout, considerWhitespaceChanges, options) {
1500
+ const lineRangeMapping = toLineRangeMapping(diff);
1501
+ const rangeMapping = lineRangeMapping.toRangeMapping2(originalLines, modifiedLines);
1502
+ const slice1 = new LinesSliceCharSequence(originalLines, rangeMapping.originalRange, considerWhitespaceChanges);
1503
+ const slice2 = new LinesSliceCharSequence(modifiedLines, rangeMapping.modifiedRange, considerWhitespaceChanges);
1504
+ const diffResult = slice1.length + slice2.length < 500
1505
+ ? this._dynamicProgrammingDiffing.compute(slice1, slice2, timeout)
1506
+ : this._myersDiffingAlgorithm.compute(slice1, slice2, timeout);
1507
+ let diffs = diffResult.diffs;
1508
+ diffs = optimizeSequenceDiffs(slice1, slice2, diffs);
1509
+ diffs = extendDiffsToEntireWordIfAppropriate(slice1, slice2, diffs, (seq, idx) => seq.findWordContaining(idx));
1510
+ if (options.extendToSubwords) {
1511
+ diffs = extendDiffsToEntireWordIfAppropriate(slice1, slice2, diffs, (seq, idx) => seq.findSubWordContaining(idx), true);
1512
+ }
1513
+ diffs = removeShortMatches(slice1, slice2, diffs);
1514
+ diffs = removeVeryShortMatchingTextBetweenLongDiffs(slice1, slice2, diffs);
1515
+ const result = diffs.map((d) => new RangeMapping(slice1.translateRange(d.seq1Range), slice2.translateRange(d.seq2Range)));
1516
+ return {
1517
+ mappings: result,
1518
+ hitTimeout: diffResult.hitTimeout,
1519
+ };
1520
+ }
1521
+ }
1522
+ function toLineRangeMapping(sequenceDiff) {
1523
+ return new LineRangeMapping(new LineRange(sequenceDiff.seq1Range.start + 1, sequenceDiff.seq1Range.endExclusive + 1), new LineRange(sequenceDiff.seq2Range.start + 1, sequenceDiff.seq2Range.endExclusive + 1));
1524
+ }
1525
+ function arraysEqual(a, b) {
1526
+ if (a.length !== b.length) {
1527
+ return false;
1528
+ }
1529
+ for (let i = 0; i < a.length; i++) {
1530
+ if (a[i] !== b[i]) {
1531
+ return false;
1532
+ }
1533
+ }
1534
+ return true;
1535
+ }
1536
+
1537
+ /* @ts-self-types="./diff_wasm.d.ts" */
1538
+
1539
+ /**
1540
+ * Compute a diff between two texts.
1541
+ *
1542
+ * # Arguments
1543
+ * * `original` - The original text (lines separated by newlines)
1544
+ * * `modified` - The modified text (lines separated by newlines)
1545
+ * * `options` - Optional diff options (as a JavaScript object)
1546
+ *
1547
+ * # Returns
1548
+ * A `WasmLinesDiff` object containing the changes.
1549
+ * @param {string} original
1550
+ * @param {string} modified
1551
+ * @param {any} options
1552
+ * @returns {any}
1553
+ */
1554
+ function computeDiff(original, modified, options) {
1555
+ const ptr0 = passStringToWasm0(original, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1556
+ const len0 = WASM_VECTOR_LEN;
1557
+ const ptr1 = passStringToWasm0(modified, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1558
+ const len1 = WASM_VECTOR_LEN;
1559
+ const ret = wasm.computeDiff(ptr0, len0, ptr1, len1, options);
1560
+ if (ret[2]) {
1561
+ throw takeFromExternrefTable0(ret[1]);
1562
+ }
1563
+ return takeFromExternrefTable0(ret[0]);
1564
+ }
1565
+
1566
+ /**
1567
+ * Compute a diff between two arrays of lines.
1568
+ *
1569
+ * # Arguments
1570
+ * * `original_lines` - The original lines (as a JavaScript array of strings)
1571
+ * * `modified_lines` - The modified lines (as a JavaScript array of strings)
1572
+ * * `options` - Optional diff options (as a JavaScript object)
1573
+ *
1574
+ * # Returns
1575
+ * A `WasmLinesDiff` object containing the changes.
1576
+ * @param {any} original_lines
1577
+ * @param {any} modified_lines
1578
+ * @param {any} options
1579
+ * @returns {any}
1580
+ */
1581
+ function computeDiffLines(original_lines, modified_lines, options) {
1582
+ const ret = wasm.computeDiffLines(original_lines, modified_lines, options);
1583
+ if (ret[2]) {
1584
+ throw takeFromExternrefTable0(ret[1]);
1585
+ }
1586
+ return takeFromExternrefTable0(ret[0]);
1587
+ }
1588
+
1589
+ /**
1590
+ * Initialize panic hook for better error messages in the browser console.
1591
+ */
1592
+ function init() {
1593
+ wasm.init();
1594
+ }
1595
+ function __wbg_get_imports() {
1596
+ const import0 = {
1597
+ __proto__: null,
1598
+ __wbg_Error_ef53bc310eb298a0: function(arg0, arg1) {
1599
+ const ret = Error(getStringFromWasm0(arg0, arg1));
1600
+ return ret;
1601
+ },
1602
+ __wbg_Number_6b506e6536831eaa: function(arg0) {
1603
+ const ret = Number(arg0);
1604
+ return ret;
1605
+ },
1606
+ __wbg_String_8564e559799eccda: function(arg0, arg1) {
1607
+ const ret = String(arg1);
1608
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1609
+ const len1 = WASM_VECTOR_LEN;
1610
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
1611
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
1612
+ },
1613
+ __wbg___wbindgen_bigint_get_as_i64_38130e98eecd467d: function(arg0, arg1) {
1614
+ const v = arg1;
1615
+ const ret = typeof(v) === 'bigint' ? v : undefined;
1616
+ getDataViewMemory0().setBigInt64(arg0 + 8 * 1, isLikeNone(ret) ? BigInt(0) : ret, true);
1617
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
1618
+ },
1619
+ __wbg___wbindgen_boolean_get_1a45e2c38d4d41b9: function(arg0) {
1620
+ const v = arg0;
1621
+ const ret = typeof(v) === 'boolean' ? v : undefined;
1622
+ return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
1623
+ },
1624
+ __wbg___wbindgen_debug_string_0accd80f45e5faa2: function(arg0, arg1) {
1625
+ const ret = debugString(arg1);
1626
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1627
+ const len1 = WASM_VECTOR_LEN;
1628
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
1629
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
1630
+ },
1631
+ __wbg___wbindgen_in_70a403a56e771704: function(arg0, arg1) {
1632
+ const ret = arg0 in arg1;
1633
+ return ret;
1634
+ },
1635
+ __wbg___wbindgen_is_bigint_6ffd6468a9bc44b9: function(arg0) {
1636
+ const ret = typeof(arg0) === 'bigint';
1637
+ return ret;
1638
+ },
1639
+ __wbg___wbindgen_is_function_754e9f305ff6029e: function(arg0) {
1640
+ const ret = typeof(arg0) === 'function';
1641
+ return ret;
1642
+ },
1643
+ __wbg___wbindgen_is_null_87c3bfe968c6a5ad: function(arg0) {
1644
+ const ret = arg0 === null;
1645
+ return ret;
1646
+ },
1647
+ __wbg___wbindgen_is_object_56732c2bc353f41d: function(arg0) {
1648
+ const val = arg0;
1649
+ const ret = typeof(val) === 'object' && val !== null;
1650
+ return ret;
1651
+ },
1652
+ __wbg___wbindgen_is_undefined_67b456be8673d3d7: function(arg0) {
1653
+ const ret = arg0 === undefined;
1654
+ return ret;
1655
+ },
1656
+ __wbg___wbindgen_jsval_eq_1068e624fa87f6ab: function(arg0, arg1) {
1657
+ const ret = arg0 === arg1;
1658
+ return ret;
1659
+ },
1660
+ __wbg___wbindgen_jsval_loose_eq_2c56564c75129511: function(arg0, arg1) {
1661
+ const ret = arg0 == arg1;
1662
+ return ret;
1663
+ },
1664
+ __wbg___wbindgen_number_get_9bb1761122181af2: function(arg0, arg1) {
1665
+ const obj = arg1;
1666
+ const ret = typeof(obj) === 'number' ? obj : undefined;
1667
+ getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true);
1668
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
1669
+ },
1670
+ __wbg___wbindgen_string_get_72bdf95d3ae505b1: function(arg0, arg1) {
1671
+ const obj = arg1;
1672
+ const ret = typeof(obj) === 'string' ? obj : undefined;
1673
+ var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1674
+ var len1 = WASM_VECTOR_LEN;
1675
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
1676
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
1677
+ },
1678
+ __wbg___wbindgen_throw_1506f2235d1bdba0: function(arg0, arg1) {
1679
+ throw new Error(getStringFromWasm0(arg0, arg1));
1680
+ },
1681
+ __wbg_call_8a89609d89f6608a: function() { return handleError(function (arg0, arg1) {
1682
+ const ret = arg0.call(arg1);
1683
+ return ret;
1684
+ }, arguments); },
1685
+ __wbg_done_60cf307fcc680536: function(arg0) {
1686
+ const ret = arg0.done;
1687
+ return ret;
1688
+ },
1689
+ __wbg_error_a6fa202b58aa1cd3: function(arg0, arg1) {
1690
+ let deferred0_0;
1691
+ let deferred0_1;
1692
+ try {
1693
+ deferred0_0 = arg0;
1694
+ deferred0_1 = arg1;
1695
+ console.error(getStringFromWasm0(arg0, arg1));
1696
+ } finally {
1697
+ wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
1698
+ }
1699
+ },
1700
+ __wbg_get_1f8f054ddbaa7db2: function() { return handleError(function (arg0, arg1) {
1701
+ const ret = Reflect.get(arg0, arg1);
1702
+ return ret;
1703
+ }, arguments); },
1704
+ __wbg_get_unchecked_33f6e5c9e2f2d6b2: function(arg0, arg1) {
1705
+ const ret = arg0[arg1 >>> 0];
1706
+ return ret;
1707
+ },
1708
+ __wbg_get_with_ref_key_6412cf3094599694: function(arg0, arg1) {
1709
+ const ret = arg0[arg1];
1710
+ return ret;
1711
+ },
1712
+ __wbg_instanceof_ArrayBuffer_8f49811467741499: function(arg0) {
1713
+ let result;
1714
+ try {
1715
+ result = arg0 instanceof ArrayBuffer;
1716
+ } catch (_) {
1717
+ result = false;
1718
+ }
1719
+ const ret = result;
1720
+ return ret;
1721
+ },
1722
+ __wbg_instanceof_Uint8Array_86f30649f63ef9c2: function(arg0) {
1723
+ let result;
1724
+ try {
1725
+ result = arg0 instanceof Uint8Array;
1726
+ } catch (_) {
1727
+ result = false;
1728
+ }
1729
+ const ret = result;
1730
+ return ret;
1731
+ },
1732
+ __wbg_isArray_67c2c9c4313f4448: function(arg0) {
1733
+ const ret = Array.isArray(arg0);
1734
+ return ret;
1735
+ },
1736
+ __wbg_isSafeInteger_66acec27e09e99a7: function(arg0) {
1737
+ const ret = Number.isSafeInteger(arg0);
1738
+ return ret;
1739
+ },
1740
+ __wbg_iterator_8732428d309e270e: function() {
1741
+ const ret = Symbol.iterator;
1742
+ return ret;
1743
+ },
1744
+ __wbg_length_4a591ecaa01354d9: function(arg0) {
1745
+ const ret = arg0.length;
1746
+ return ret;
1747
+ },
1748
+ __wbg_length_66f1a4b2e9026940: function(arg0) {
1749
+ const ret = arg0.length;
1750
+ return ret;
1751
+ },
1752
+ __wbg_new_227d7c05414eb861: function() {
1753
+ const ret = new Error();
1754
+ return ret;
1755
+ },
1756
+ __wbg_new_578aeef4b6b94378: function(arg0) {
1757
+ const ret = new Uint8Array(arg0);
1758
+ return ret;
1759
+ },
1760
+ __wbg_new_ce1ab61c1c2b300d: function() {
1761
+ const ret = new Object();
1762
+ return ret;
1763
+ },
1764
+ __wbg_new_d90091b82fdf5b91: function() {
1765
+ const ret = new Array();
1766
+ return ret;
1767
+ },
1768
+ __wbg_next_9e03acdf51c4960d: function(arg0) {
1769
+ const ret = arg0.next;
1770
+ return ret;
1771
+ },
1772
+ __wbg_next_eb8ca7351fa27906: function() { return handleError(function (arg0) {
1773
+ const ret = arg0.next();
1774
+ return ret;
1775
+ }, arguments); },
1776
+ __wbg_prototypesetcall_3249fc62a0fafa30: function(arg0, arg1, arg2) {
1777
+ Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);
1778
+ },
1779
+ __wbg_set_6be42768c690e380: function(arg0, arg1, arg2) {
1780
+ arg0[arg1] = arg2;
1781
+ },
1782
+ __wbg_set_dca99999bba88a9a: function(arg0, arg1, arg2) {
1783
+ arg0[arg1 >>> 0] = arg2;
1784
+ },
1785
+ __wbg_stack_3b0d974bbf31e44f: function(arg0, arg1) {
1786
+ const ret = arg1.stack;
1787
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1788
+ const len1 = WASM_VECTOR_LEN;
1789
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
1790
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
1791
+ },
1792
+ __wbg_value_f3625092ee4b37f4: function(arg0) {
1793
+ const ret = arg0.value;
1794
+ return ret;
1795
+ },
1796
+ __wbindgen_cast_0000000000000001: function(arg0) {
1797
+ // Cast intrinsic for `F64 -> Externref`.
1798
+ const ret = arg0;
1799
+ return ret;
1800
+ },
1801
+ __wbindgen_cast_0000000000000002: function(arg0, arg1) {
1802
+ // Cast intrinsic for `Ref(String) -> Externref`.
1803
+ const ret = getStringFromWasm0(arg0, arg1);
1804
+ return ret;
1805
+ },
1806
+ __wbindgen_cast_0000000000000003: function(arg0) {
1807
+ // Cast intrinsic for `U64 -> Externref`.
1808
+ const ret = BigInt.asUintN(64, arg0);
1809
+ return ret;
1810
+ },
1811
+ __wbindgen_init_externref_table: function() {
1812
+ const table = wasm.__wbindgen_externrefs;
1813
+ const offset = table.grow(4);
1814
+ table.set(0, undefined);
1815
+ table.set(offset + 0, undefined);
1816
+ table.set(offset + 1, null);
1817
+ table.set(offset + 2, true);
1818
+ table.set(offset + 3, false);
1819
+ },
1820
+ };
1821
+ return {
1822
+ __proto__: null,
1823
+ "./diff_wasm_bg.js": import0,
1824
+ };
1825
+ }
1826
+
1827
+ function addToExternrefTable0(obj) {
1828
+ const idx = wasm.__externref_table_alloc();
1829
+ wasm.__wbindgen_externrefs.set(idx, obj);
1830
+ return idx;
1831
+ }
1832
+
1833
+ function debugString(val) {
1834
+ // primitive types
1835
+ const type = typeof val;
1836
+ if (type == 'number' || type == 'boolean' || val == null) {
1837
+ return `${val}`;
1838
+ }
1839
+ if (type == 'string') {
1840
+ return `"${val}"`;
1841
+ }
1842
+ if (type == 'symbol') {
1843
+ const description = val.description;
1844
+ if (description == null) {
1845
+ return 'Symbol';
1846
+ } else {
1847
+ return `Symbol(${description})`;
1848
+ }
1849
+ }
1850
+ if (type == 'function') {
1851
+ const name = val.name;
1852
+ if (typeof name == 'string' && name.length > 0) {
1853
+ return `Function(${name})`;
1854
+ } else {
1855
+ return 'Function';
1856
+ }
1857
+ }
1858
+ // objects
1859
+ if (Array.isArray(val)) {
1860
+ const length = val.length;
1861
+ let debug = '[';
1862
+ if (length > 0) {
1863
+ debug += debugString(val[0]);
1864
+ }
1865
+ for(let i = 1; i < length; i++) {
1866
+ debug += ', ' + debugString(val[i]);
1867
+ }
1868
+ debug += ']';
1869
+ return debug;
1870
+ }
1871
+ // Test for built-in
1872
+ const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
1873
+ let className;
1874
+ if (builtInMatches && builtInMatches.length > 1) {
1875
+ className = builtInMatches[1];
1876
+ } else {
1877
+ // Failed to match the standard '[object ClassName]'
1878
+ return toString.call(val);
1879
+ }
1880
+ if (className == 'Object') {
1881
+ // we're a user defined class or Object
1882
+ // JSON.stringify avoids problems with cycles, and is generally much
1883
+ // easier than looping through ownProperties of `val`.
1884
+ try {
1885
+ return 'Object(' + JSON.stringify(val) + ')';
1886
+ } catch (_) {
1887
+ return 'Object';
1888
+ }
1889
+ }
1890
+ // errors
1891
+ if (val instanceof Error) {
1892
+ return `${val.name}: ${val.message}\n${val.stack}`;
1893
+ }
1894
+ // TODO we could test for more things here, like `Set`s and `Map`s.
1895
+ return className;
1896
+ }
1897
+
1898
+ function getArrayU8FromWasm0(ptr, len) {
1899
+ ptr = ptr >>> 0;
1900
+ return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
1901
+ }
1902
+
1903
+ let cachedDataViewMemory0 = null;
1904
+ function getDataViewMemory0() {
1905
+ if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
1906
+ cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
1907
+ }
1908
+ return cachedDataViewMemory0;
1909
+ }
1910
+
1911
+ function getStringFromWasm0(ptr, len) {
1912
+ return decodeText(ptr >>> 0, len);
1913
+ }
1914
+
1915
+ let cachedUint8ArrayMemory0 = null;
1916
+ function getUint8ArrayMemory0() {
1917
+ if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
1918
+ cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
1919
+ }
1920
+ return cachedUint8ArrayMemory0;
1921
+ }
1922
+
1923
+ function handleError(f, args) {
1924
+ try {
1925
+ return f.apply(this, args);
1926
+ } catch (e) {
1927
+ const idx = addToExternrefTable0(e);
1928
+ wasm.__wbindgen_exn_store(idx);
1929
+ }
1930
+ }
1931
+
1932
+ function isLikeNone(x) {
1933
+ return x === undefined || x === null;
1934
+ }
1935
+
1936
+ function passStringToWasm0(arg, malloc, realloc) {
1937
+ if (realloc === undefined) {
1938
+ const buf = cachedTextEncoder.encode(arg);
1939
+ const ptr = malloc(buf.length, 1) >>> 0;
1940
+ getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
1941
+ WASM_VECTOR_LEN = buf.length;
1942
+ return ptr;
1943
+ }
1944
+
1945
+ let len = arg.length;
1946
+ let ptr = malloc(len, 1) >>> 0;
1947
+
1948
+ const mem = getUint8ArrayMemory0();
1949
+
1950
+ let offset = 0;
1951
+
1952
+ for (; offset < len; offset++) {
1953
+ const code = arg.charCodeAt(offset);
1954
+ if (code > 0x7F) break;
1955
+ mem[ptr + offset] = code;
1956
+ }
1957
+ if (offset !== len) {
1958
+ if (offset !== 0) {
1959
+ arg = arg.slice(offset);
1960
+ }
1961
+ ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
1962
+ const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
1963
+ const ret = cachedTextEncoder.encodeInto(arg, view);
1964
+
1965
+ offset += ret.written;
1966
+ ptr = realloc(ptr, len, offset, 1) >>> 0;
1967
+ }
1968
+
1969
+ WASM_VECTOR_LEN = offset;
1970
+ return ptr;
1971
+ }
1972
+
1973
+ function takeFromExternrefTable0(idx) {
1974
+ const value = wasm.__wbindgen_externrefs.get(idx);
1975
+ wasm.__externref_table_dealloc(idx);
1976
+ return value;
1977
+ }
1978
+
1979
+ let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
1980
+ cachedTextDecoder.decode();
1981
+ const MAX_SAFARI_DECODE_BYTES = 2146435072;
1982
+ let numBytesDecoded = 0;
1983
+ function decodeText(ptr, len) {
1984
+ numBytesDecoded += len;
1985
+ if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
1986
+ cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
1987
+ cachedTextDecoder.decode();
1988
+ numBytesDecoded = len;
1989
+ }
1990
+ return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
1991
+ }
1992
+
1993
+ const cachedTextEncoder = new TextEncoder();
1994
+
1995
+ if (!('encodeInto' in cachedTextEncoder)) {
1996
+ cachedTextEncoder.encodeInto = function (arg, view) {
1997
+ const buf = cachedTextEncoder.encode(arg);
1998
+ view.set(buf);
1999
+ return {
2000
+ read: arg.length,
2001
+ written: buf.length
2002
+ };
2003
+ };
2004
+ }
2005
+
2006
+ let WASM_VECTOR_LEN = 0;
2007
+
2008
+ let wasm;
2009
+ function __wbg_finalize_init(instance, module) {
2010
+ wasm = instance.exports;
2011
+ cachedDataViewMemory0 = null;
2012
+ cachedUint8ArrayMemory0 = null;
2013
+ wasm.__wbindgen_start();
2014
+ return wasm;
2015
+ }
2016
+
2017
+ async function __wbg_load(module, imports) {
2018
+ if (typeof Response === 'function' && module instanceof Response) {
2019
+ if (typeof WebAssembly.instantiateStreaming === 'function') {
2020
+ try {
2021
+ return await WebAssembly.instantiateStreaming(module, imports);
2022
+ } catch (e) {
2023
+ const validResponse = module.ok && expectedResponseType(module.type);
2024
+
2025
+ if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {
2026
+ console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
2027
+
2028
+ } else { throw e; }
2029
+ }
2030
+ }
2031
+
2032
+ const bytes = await module.arrayBuffer();
2033
+ return await WebAssembly.instantiate(bytes, imports);
2034
+ } else {
2035
+ const instance = await WebAssembly.instantiate(module, imports);
2036
+
2037
+ if (instance instanceof WebAssembly.Instance) {
2038
+ return { instance, module };
2039
+ } else {
2040
+ return instance;
2041
+ }
2042
+ }
2043
+
2044
+ function expectedResponseType(type) {
2045
+ switch (type) {
2046
+ case 'basic': case 'cors': case 'default': return true;
2047
+ }
2048
+ return false;
2049
+ }
2050
+ }
2051
+
2052
+ function initSync(module) {
2053
+ if (wasm !== undefined) return wasm;
2054
+
2055
+
2056
+ if (module !== undefined) {
2057
+ if (Object.getPrototypeOf(module) === Object.prototype) {
2058
+ ({module} = module);
2059
+ } else {
2060
+ console.warn('using deprecated parameters for `initSync()`; pass a single object instead');
2061
+ }
2062
+ }
2063
+
2064
+ const imports = __wbg_get_imports();
2065
+ if (!(module instanceof WebAssembly.Module)) {
2066
+ module = new WebAssembly.Module(module);
2067
+ }
2068
+ const instance = new WebAssembly.Instance(module, imports);
2069
+ return __wbg_finalize_init(instance);
2070
+ }
2071
+
2072
+ async function __wbg_init(module_or_path) {
2073
+ if (wasm !== undefined) return wasm;
2074
+
2075
+
2076
+ if (module_or_path !== undefined) {
2077
+ if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
2078
+ ({module_or_path} = module_or_path);
2079
+ } else {
2080
+ console.warn('using deprecated parameters for the initialization function; pass a single object instead');
2081
+ }
2082
+ }
2083
+
2084
+ if (module_or_path === undefined) {
2085
+ module_or_path = new URL(new URL(/* asset import */ __webpack_require__(/*! diff_wasm_bg-c6YkaZRL.wasm */ "./node_modules/@vscode/diff/dist/diff_wasm_bg-c6YkaZRL.wasm"), __webpack_require__.b).href);
2086
+ }
2087
+ const imports = __wbg_get_imports();
2088
+
2089
+ if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {
2090
+ module_or_path = fetch(module_or_path);
2091
+ }
2092
+
2093
+ const { instance, module } = await __wbg_load(await module_or_path, imports);
2094
+
2095
+ return __wbg_finalize_init(instance);
2096
+ }
2097
+
2098
+ var wasm$1 = /*#__PURE__*/Object.freeze({
2099
+ __proto__: null,
2100
+ computeDiff: computeDiff,
2101
+ computeDiffLines: computeDiffLines,
2102
+ default: __wbg_init,
2103
+ init: init,
2104
+ initSync: initSync
2105
+ });
2106
+
2107
+ /**
2108
+ * WASM module loader.
2109
+ *
2110
+ * Handles async initialization of the WASM module.
2111
+ */
2112
+ // @ts-ignore -- generated at build time by `npm run build:wasm` (wasm-pack --target web).
2113
+ let wasmModule = null;
2114
+ let initPromise = null;
2115
+ /**
2116
+ * Initialize the WASM module.
2117
+ *
2118
+ * This must be called before using any WASM-based diff functions.
2119
+ * It's safe to call multiple times — subsequent calls are no-ops.
2120
+ *
2121
+ * @returns Promise that resolves when WASM is ready
2122
+ */
2123
+ async function initWasm() {
2124
+ if (wasmModule) {
2125
+ return wasmModule;
2126
+ }
2127
+ if (initPromise) {
2128
+ return initPromise;
2129
+ }
2130
+ initPromise = (async () => {
2131
+ const wasmUrl = new URL(new URL(/* asset import */ __webpack_require__(/*! diff_wasm_bg-c6YkaZRL.wasm */ "./node_modules/@vscode/diff/dist/diff_wasm_bg-c6YkaZRL.wasm"), __webpack_require__.b).href);
2132
+ // Node's undici fetch does not support file:// URLs, so read bytes ourselves.
2133
+ let source = wasmUrl;
2134
+ if (typeof process !== 'undefined' && process.versions?.node) {
2135
+ const { readFile } = await __webpack_require__.e(/*! import() */ "node_fs_promises").then(__webpack_require__.t.bind(__webpack_require__, /*! node:fs/promises */ "node:fs/promises", 19));
2136
+ source = await readFile(wasmUrl);
2137
+ }
2138
+ await __wbg_init({ module_or_path: source });
2139
+ init();
2140
+ wasmModule = wasm$1;
2141
+ return wasmModule;
2142
+ })();
2143
+ return initPromise;
2144
+ }
2145
+ /**
2146
+ * Get the WASM module synchronously.
2147
+ *
2148
+ * @throws Error if WASM hasn't been initialized yet
2149
+ * @returns The WASM module
2150
+ */
2151
+ function getWasm() {
2152
+ if (!wasmModule) {
2153
+ throw new Error('WASM not initialized. Call initWasm() first and await it.');
2154
+ }
2155
+ return wasmModule;
2156
+ }
2157
+
2158
+ /**
2159
+ * Conversions between `LinesDiff` (in-memory class instances) and
2160
+ * `WireLinesDiff` (plain JSON-friendly shape used on the worker boundary).
2161
+ */
2162
+ function linesDiffToWire(diff) {
2163
+ return {
2164
+ changes: diff.changes.map(detailedToWire),
2165
+ moves: diff.moves.map(moveToWire),
2166
+ hitTimeout: diff.hitTimeout,
2167
+ };
2168
+ }
2169
+ function wireToLinesDiff(wire) {
2170
+ const changes = wire.changes.map(wireToDetailed);
2171
+ const moves = wire.moves.map(wireToMove);
2172
+ return new LinesDiff(changes, moves, wire.hitTimeout);
2173
+ }
2174
+ function detailedToWire(m) {
2175
+ return {
2176
+ original: {
2177
+ startLineNumber: m.original.startLineNumber,
2178
+ endLineNumberExclusive: m.original.endLineNumberExclusive,
2179
+ },
2180
+ modified: {
2181
+ startLineNumber: m.modified.startLineNumber,
2182
+ endLineNumberExclusive: m.modified.endLineNumberExclusive,
2183
+ },
2184
+ innerChanges: m.innerChanges ? m.innerChanges.map(rangeMappingToWire) : null,
2185
+ };
2186
+ }
2187
+ function wireToDetailed(m) {
2188
+ const inner = m.innerChanges?.map(wireToRangeMapping);
2189
+ return new DetailedLineRangeMapping(new LineRange(m.original.startLineNumber, m.original.endLineNumberExclusive), new LineRange(m.modified.startLineNumber, m.modified.endLineNumberExclusive), inner);
2190
+ }
2191
+ function rangeMappingToWire(rm) {
2192
+ return {
2193
+ originalStartLine: rm.originalRange.startLineNumber,
2194
+ originalStartColumn: rm.originalRange.startColumn,
2195
+ originalEndLine: rm.originalRange.endLineNumber,
2196
+ originalEndColumn: rm.originalRange.endColumn,
2197
+ modifiedStartLine: rm.modifiedRange.startLineNumber,
2198
+ modifiedStartColumn: rm.modifiedRange.startColumn,
2199
+ modifiedEndLine: rm.modifiedRange.endLineNumber,
2200
+ modifiedEndColumn: rm.modifiedRange.endColumn,
2201
+ };
2202
+ }
2203
+ function wireToRangeMapping(rm) {
2204
+ return new RangeMapping(new Range(rm.originalStartLine, rm.originalStartColumn, rm.originalEndLine, rm.originalEndColumn), new Range(rm.modifiedStartLine, rm.modifiedStartColumn, rm.modifiedEndLine, rm.modifiedEndColumn));
2205
+ }
2206
+ function moveToWire(m) {
2207
+ return {
2208
+ lineRangeMapping: {
2209
+ original: {
2210
+ startLineNumber: m.lineRangeMapping.original.startLineNumber,
2211
+ endLineNumberExclusive: m.lineRangeMapping.original.endLineNumberExclusive,
2212
+ },
2213
+ modified: {
2214
+ startLineNumber: m.lineRangeMapping.modified.startLineNumber,
2215
+ endLineNumberExclusive: m.lineRangeMapping.modified.endLineNumberExclusive,
2216
+ },
2217
+ },
2218
+ changes: m.changes.map(detailedToWire),
2219
+ };
2220
+ }
2221
+ function wireToMove(m) {
2222
+ const lrm = new LineRangeMapping(new LineRange(m.lineRangeMapping.original.startLineNumber, m.lineRangeMapping.original.endLineNumberExclusive), new LineRange(m.lineRangeMapping.modified.startLineNumber, m.lineRangeMapping.modified.endLineNumberExclusive));
2223
+ return new MovedText(lrm, m.changes.map(wireToDetailed));
2224
+ }
2225
+
2226
+
2227
+ //# sourceMappingURL=wire.js.map
2228
+
2229
+
2230
+ /***/ }
2231
+
2232
+ }]);
2233
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVuZG9ycy1ub2RlX21vZHVsZXNfdnNjb2RlX2RpZmZfZGlzdF93aXJlX2pzLm1haW4uanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQ0FBK0MsTUFBTSxJQUFJLGFBQWE7QUFDdEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLFdBQVcsSUFBSSxrQkFBa0I7QUFDcEQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixjQUFjLE1BQU0sYUFBYTtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLGdCQUFnQixNQUFNLGVBQWU7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5Qix1QkFBdUI7QUFDaEQsNkJBQTZCLHVCQUF1QjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkI7QUFDM0IsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQyxRQUFRO0FBQ25EO0FBQ0E7QUFDQSxpQ0FBaUMsaUJBQWlCO0FBQ2xEO0FBQ0EsNkVBQTZFO0FBQzdFLGtGQUFrRjtBQUNsRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLFdBQVc7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsWUFBWSxnQkFBZ0I7QUFDNUI7QUFDQSxxQkFBcUIsa0JBQWtCLEdBQUc7QUFDMUMsb0JBQW9CLHNCQUFzQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLDBCQUEwQjtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLGFBQWE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQix1QkFBdUI7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixZQUFZO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLDBCQUEwQjtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMscUJBQXFCO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLGtCQUFrQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0Isa0JBQWtCO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxvQkFBb0Isa0JBQWtCO0FBQ3RDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRCx5Q0FBeUM7QUFDcEc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLGdCQUFnQjtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsVUFBVTtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4Q0FBOEMsaUJBQWlCLElBQUksdUJBQXVCO0FBQzFGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHFCQUFxQixJQUFJLDRCQUE0QjtBQUN4RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixtQ0FBbUMsTUFBTSxrQ0FBa0M7QUFDN0Y7QUFDQTtBQUNBLHdCQUF3QiwwQkFBMEI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLHNCQUFzQixHQUFHLGtCQUFrQixLQUFLLG9CQUFvQixHQUFHLGdCQUFnQjtBQUN0RztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsZUFBZSxNQUFNLGNBQWM7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0Isb0JBQW9CO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLHFCQUFxQjtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixjQUFjO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixXQUFXLFFBQVE7QUFDbkIsV0FBVyxLQUFLO0FBQ2hCLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEtBQUs7QUFDaEIsV0FBVyxLQUFLO0FBQ2hCLFdBQVcsS0FBSztBQUNoQixhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNULGtEQUFrRDtBQUNsRDtBQUNBO0FBQ0EsU0FBUyxlQUFlO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0EsU0FBUztBQUNULGlEQUFpRDtBQUNqRDtBQUNBO0FBQ0EsU0FBUyxlQUFlO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULGtEQUFrRDtBQUNsRDtBQUNBO0FBQ0EsU0FBUyxlQUFlO0FBQ3hCO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixJQUFJO0FBQ3ZCO0FBQ0E7QUFDQSxtQkFBbUIsSUFBSTtBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWLDZCQUE2QixZQUFZO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0IsS0FBSztBQUNwQyxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsWUFBWTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixTQUFTLElBQUksWUFBWSxJQUFJLFVBQVU7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLFdBQVcsY0FBYztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtREFBbUQsOEJBQThCO0FBQ2pGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVEQUF1RCw4QkFBOEI7QUFDckY7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7O0FBRUE7QUFDQTs7QUFFQSxrQkFBa0IsT0FBTztBQUN6QjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxNQUFNO0FBQ047O0FBRUE7QUFDQSxxQkFBcUI7QUFDckIsVUFBVTtBQUNWO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0EsY0FBYyxRQUFRO0FBQ3RCLFVBQVU7QUFDVix3RUFBd0U7QUFDeEU7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0EsY0FBYyxnQkFBZ0I7QUFDOUIsVUFBVTtBQUNWLHVGQUF1RjtBQUN2RjtBQUNBOztBQUVBO0FBQ0EseUNBQXlDLDhKQUE2QztBQUN0RjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxZQUFZLG1CQUFtQjs7QUFFL0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDLDhKQUE2QztBQUNyRjtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsV0FBVyxRQUFRLCtKQUEwQjtBQUNqRTtBQUNBO0FBQ0EsMkJBQTJCLHdCQUF3QjtBQUNuRDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRXlQO0FBQ3pQIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vamRlcm9ib3QtaWRlLWludGVyZmFjZS8uL25vZGVfbW9kdWxlcy9AdnNjb2RlL2RpZmYvZGlzdC93aXJlLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiAgQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiAgTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cbiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuLyoqXG4gKiBBIHJhbmdlIG9mIG9mZnNldHMgKDAtYmFzZWQpLlxuICovXG5jbGFzcyBPZmZzZXRSYW5nZSB7XG4gICAgc3RhcnQ7XG4gICAgZW5kRXhjbHVzaXZlO1xuICAgIHN0YXRpYyBvZkxlbmd0aChsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBPZmZzZXRSYW5nZSgwLCBsZW5ndGgpO1xuICAgIH1cbiAgICBzdGF0aWMgb2ZTdGFydEFuZExlbmd0aChzdGFydCwgbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBuZXcgT2Zmc2V0UmFuZ2Uoc3RhcnQsIHN0YXJ0ICsgbGVuZ3RoKTtcbiAgICB9XG4gICAgY29uc3RydWN0b3Ioc3RhcnQsIGVuZEV4Y2x1c2l2ZSkge1xuICAgICAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7XG4gICAgICAgIHRoaXMuZW5kRXhjbHVzaXZlID0gZW5kRXhjbHVzaXZlO1xuICAgICAgICBpZiAoc3RhcnQgPiBlbmRFeGNsdXNpdmUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCByYW5nZTogWyR7c3RhcnR9LCAke2VuZEV4Y2x1c2l2ZX0pYCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IGlzRW1wdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXJ0ID09PSB0aGlzLmVuZEV4Y2x1c2l2ZTtcbiAgICB9XG4gICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5kRXhjbHVzaXZlIC0gdGhpcy5zdGFydDtcbiAgICB9XG4gICAgZGVsdGEob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBuZXcgT2Zmc2V0UmFuZ2UodGhpcy5zdGFydCArIG9mZnNldCwgdGhpcy5lbmRFeGNsdXNpdmUgKyBvZmZzZXQpO1xuICAgIH1cbiAgICBkZWx0YVN0YXJ0KG9mZnNldCkge1xuICAgICAgICByZXR1cm4gbmV3IE9mZnNldFJhbmdlKHRoaXMuc3RhcnQgKyBvZmZzZXQsIHRoaXMuZW5kRXhjbHVzaXZlKTtcbiAgICB9XG4gICAgZGVsdGFFbmQob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBuZXcgT2Zmc2V0UmFuZ2UodGhpcy5zdGFydCwgdGhpcy5lbmRFeGNsdXNpdmUgKyBvZmZzZXQpO1xuICAgIH1cbiAgICBlcXVhbHMob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhcnQgPT09IG90aGVyLnN0YXJ0ICYmIHRoaXMuZW5kRXhjbHVzaXZlID09PSBvdGhlci5lbmRFeGNsdXNpdmU7XG4gICAgfVxuICAgIGNvbnRhaW5zUmFuZ2Uob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhcnQgPD0gb3RoZXIuc3RhcnQgJiYgb3RoZXIuZW5kRXhjbHVzaXZlIDw9IHRoaXMuZW5kRXhjbHVzaXZlO1xuICAgIH1cbiAgICBjb250YWlucyhvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhcnQgPD0gb2Zmc2V0ICYmIG9mZnNldCA8IHRoaXMuZW5kRXhjbHVzaXZlO1xuICAgIH1cbiAgICBqb2luKG90aGVyKSB7XG4gICAgICAgIHJldHVybiBuZXcgT2Zmc2V0UmFuZ2UoTWF0aC5taW4odGhpcy5zdGFydCwgb3RoZXIuc3RhcnQpLCBNYXRoLm1heCh0aGlzLmVuZEV4Y2x1c2l2ZSwgb3RoZXIuZW5kRXhjbHVzaXZlKSk7XG4gICAgfVxuICAgIGludGVyc2VjdChvdGhlcikge1xuICAgICAgICBjb25zdCBzdGFydCA9IE1hdGgubWF4KHRoaXMuc3RhcnQsIG90aGVyLnN0YXJ0KTtcbiAgICAgICAgY29uc3QgZW5kID0gTWF0aC5taW4odGhpcy5lbmRFeGNsdXNpdmUsIG90aGVyLmVuZEV4Y2x1c2l2ZSk7XG4gICAgICAgIGlmIChzdGFydCA8PSBlbmQpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgT2Zmc2V0UmFuZ2Uoc3RhcnQsIGVuZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgaW50ZXJzZWN0cyhvdGhlcikge1xuICAgICAgICBjb25zdCBzdGFydCA9IE1hdGgubWF4KHRoaXMuc3RhcnQsIG90aGVyLnN0YXJ0KTtcbiAgICAgICAgY29uc3QgZW5kID0gTWF0aC5taW4odGhpcy5lbmRFeGNsdXNpdmUsIG90aGVyLmVuZEV4Y2x1c2l2ZSk7XG4gICAgICAgIHJldHVybiBzdGFydCA8IGVuZDtcbiAgICB9XG4gICAgaW50ZXJzZWN0c09yVG91Y2hlcyhvdGhlcikge1xuICAgICAgICBjb25zdCBzdGFydCA9IE1hdGgubWF4KHRoaXMuc3RhcnQsIG90aGVyLnN0YXJ0KTtcbiAgICAgICAgY29uc3QgZW5kID0gTWF0aC5taW4odGhpcy5lbmRFeGNsdXNpdmUsIG90aGVyLmVuZEV4Y2x1c2l2ZSk7XG4gICAgICAgIHJldHVybiBzdGFydCA8PSBlbmQ7XG4gICAgfVxuICAgIHNsaWNlKGFycikge1xuICAgICAgICByZXR1cm4gYXJyLnNsaWNlKHRoaXMuc3RhcnQsIHRoaXMuZW5kRXhjbHVzaXZlKTtcbiAgICB9XG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiBgWyR7dGhpcy5zdGFydH0sICR7dGhpcy5lbmRFeGNsdXNpdmV9KWA7XG4gICAgfVxufVxuXG5jbGFzcyBJbmZpbml0ZVRpbWVvdXQge1xuICAgIHN0YXRpYyBpbnN0YW5jZSA9IG5ldyBJbmZpbml0ZVRpbWVvdXQoKTtcbiAgICBpc1ZhbGlkKCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG59XG5jbGFzcyBEYXRlVGltZW91dCB7XG4gICAgdGltZW91dDtcbiAgICBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHZhbGlkID0gdHJ1ZTtcbiAgICBjb25zdHJ1Y3Rvcih0aW1lb3V0KSB7XG4gICAgICAgIHRoaXMudGltZW91dCA9IHRpbWVvdXQ7XG4gICAgICAgIGlmICh0aW1lb3V0IDw9IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigndGltZW91dCBtdXN0IGJlIHBvc2l0aXZlJyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaXNWYWxpZCgpIHtcbiAgICAgICAgY29uc3QgdmFsaWQgPSBEYXRlLm5vdygpIC0gdGhpcy5zdGFydFRpbWUgPCB0aGlzLnRpbWVvdXQ7XG4gICAgICAgIGlmICghdmFsaWQgJiYgdGhpcy52YWxpZCkge1xuICAgICAgICAgICAgdGhpcy52YWxpZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZhbGlkO1xuICAgIH1cbn1cbi8qKlxuICogUmVwcmVzZW50cyBhbiBvZmZzZXQgcGFpciBmb3IgdHdvIHNlcXVlbmNlcy5cbiAqL1xuY2xhc3MgT2Zmc2V0UGFpciB7XG4gICAgb2Zmc2V0MTtcbiAgICBvZmZzZXQyO1xuICAgIHN0YXRpYyB6ZXJvID0gbmV3IE9mZnNldFBhaXIoMCwgMCk7XG4gICAgc3RhdGljIG1heCA9IG5ldyBPZmZzZXRQYWlyKE51bWJlci5NQVhfU0FGRV9JTlRFR0VSLCBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUik7XG4gICAgY29uc3RydWN0b3Iob2Zmc2V0MSwgb2Zmc2V0Mikge1xuICAgICAgICB0aGlzLm9mZnNldDEgPSBvZmZzZXQxO1xuICAgICAgICB0aGlzLm9mZnNldDIgPSBvZmZzZXQyO1xuICAgIH1cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIGAke3RoaXMub2Zmc2V0MX0gPC0+ICR7dGhpcy5vZmZzZXQyfWA7XG4gICAgfVxuICAgIGRlbHRhKG9mZnNldCkge1xuICAgICAgICBpZiAob2Zmc2V0ID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IE9mZnNldFBhaXIodGhpcy5vZmZzZXQxICsgb2Zmc2V0LCB0aGlzLm9mZnNldDIgKyBvZmZzZXQpO1xuICAgIH1cbiAgICBlcXVhbHMob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub2Zmc2V0MSA9PT0gb3RoZXIub2Zmc2V0MSAmJiB0aGlzLm9mZnNldDIgPT09IG90aGVyLm9mZnNldDI7XG4gICAgfVxufVxuLyoqXG4gKiBSZXByZXNlbnRzIGEgZGlmZiBiZXR3ZWVuIHR3byBzZXF1ZW5jZXMuXG4gKi9cbmNsYXNzIFNlcXVlbmNlRGlmZiB7XG4gICAgc2VxMVJhbmdlO1xuICAgIHNlcTJSYW5nZTtcbiAgICBzdGF0aWMgaW52ZXJ0KHNlcXVlbmNlRGlmZnMsIGRvYzFMZW5ndGgpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgICAgIGZvckVhY2hBZGphY2VudChzZXF1ZW5jZURpZmZzLCAoYSwgYikgPT4ge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2goU2VxdWVuY2VEaWZmLmZyb21PZmZzZXRQYWlycyhhID8gYS5nZXRFbmRFeGNsdXNpdmVzKCkgOiBPZmZzZXRQYWlyLnplcm8sIGIgPyBiLmdldFN0YXJ0cygpIDogbmV3IE9mZnNldFBhaXIoZG9jMUxlbmd0aCwgKGEgPyBhLnNlcTJSYW5nZS5lbmRFeGNsdXNpdmUgLSBhLnNlcTFSYW5nZS5lbmRFeGNsdXNpdmUgOiAwKSArIGRvYzFMZW5ndGgpKSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICBzdGF0aWMgZnJvbU9mZnNldFBhaXJzKHN0YXJ0LCBlbmRFeGNsdXNpdmUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTZXF1ZW5jZURpZmYobmV3IE9mZnNldFJhbmdlKHN0YXJ0Lm9mZnNldDEsIGVuZEV4Y2x1c2l2ZS5vZmZzZXQxKSwgbmV3IE9mZnNldFJhbmdlKHN0YXJ0Lm9mZnNldDIsIGVuZEV4Y2x1c2l2ZS5vZmZzZXQyKSk7XG4gICAgfVxuICAgIHN0YXRpYyBhc3NlcnRTb3J0ZWQoc2VxdWVuY2VEaWZmcykge1xuICAgICAgICBsZXQgbGFzdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgZm9yIChjb25zdCBjdXIgb2Ygc2VxdWVuY2VEaWZmcykge1xuICAgICAgICAgICAgaWYgKGxhc3QpIHtcbiAgICAgICAgICAgICAgICBpZiAoIShsYXN0LnNlcTFSYW5nZS5lbmRFeGNsdXNpdmUgPD0gY3VyLnNlcTFSYW5nZS5zdGFydCAmJiBsYXN0LnNlcTJSYW5nZS5lbmRFeGNsdXNpdmUgPD0gY3VyLnNlcTJSYW5nZS5zdGFydCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTZXF1ZW5jZSBkaWZmcyBtdXN0IGJlIHNvcnRlZCcpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxhc3QgPSBjdXI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc3RydWN0b3Ioc2VxMVJhbmdlLCBzZXEyUmFuZ2UpIHtcbiAgICAgICAgdGhpcy5zZXExUmFuZ2UgPSBzZXExUmFuZ2U7XG4gICAgICAgIHRoaXMuc2VxMlJhbmdlID0gc2VxMlJhbmdlO1xuICAgIH1cbiAgICBzd2FwKCkge1xuICAgICAgICByZXR1cm4gbmV3IFNlcXVlbmNlRGlmZih0aGlzLnNlcTJSYW5nZSwgdGhpcy5zZXExUmFuZ2UpO1xuICAgIH1cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIGAke3RoaXMuc2VxMVJhbmdlfSA8LT4gJHt0aGlzLnNlcTJSYW5nZX1gO1xuICAgIH1cbiAgICBqb2luKG90aGVyKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2VxdWVuY2VEaWZmKHRoaXMuc2VxMVJhbmdlLmpvaW4ob3RoZXIuc2VxMVJhbmdlKSwgdGhpcy5zZXEyUmFuZ2Uuam9pbihvdGhlci5zZXEyUmFuZ2UpKTtcbiAgICB9XG4gICAgZGVsdGEob2Zmc2V0KSB7XG4gICAgICAgIGlmIChvZmZzZXQgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgU2VxdWVuY2VEaWZmKHRoaXMuc2VxMVJhbmdlLmRlbHRhKG9mZnNldCksIHRoaXMuc2VxMlJhbmdlLmRlbHRhKG9mZnNldCkpO1xuICAgIH1cbiAgICBkZWx0YVN0YXJ0KG9mZnNldCkge1xuICAgICAgICBpZiAob2Zmc2V0ID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFNlcXVlbmNlRGlmZih0aGlzLnNlcTFSYW5nZS5kZWx0YVN0YXJ0KG9mZnNldCksIHRoaXMuc2VxMlJhbmdlLmRlbHRhU3RhcnQob2Zmc2V0KSk7XG4gICAgfVxuICAgIGRlbHRhRW5kKG9mZnNldCkge1xuICAgICAgICBpZiAob2Zmc2V0ID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFNlcXVlbmNlRGlmZih0aGlzLnNlcTFSYW5nZS5kZWx0YUVuZChvZmZzZXQpLCB0aGlzLnNlcTJSYW5nZS5kZWx0YUVuZChvZmZzZXQpKTtcbiAgICB9XG4gICAgaW50ZXJzZWN0c09yVG91Y2hlcyhvdGhlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXExUmFuZ2UuaW50ZXJzZWN0c09yVG91Y2hlcyhvdGhlci5zZXExUmFuZ2UpIHx8IHRoaXMuc2VxMlJhbmdlLmludGVyc2VjdHNPclRvdWNoZXMob3RoZXIuc2VxMlJhbmdlKTtcbiAgICB9XG4gICAgaW50ZXJzZWN0KG90aGVyKSB7XG4gICAgICAgIGNvbnN0IGkxID0gdGhpcy5zZXExUmFuZ2UuaW50ZXJzZWN0KG90aGVyLnNlcTFSYW5nZSk7XG4gICAgICAgIGNvbnN0IGkyID0gdGhpcy5zZXEyUmFuZ2UuaW50ZXJzZWN0KG90aGVyLnNlcTJSYW5nZSk7XG4gICAgICAgIGlmICghaTEgfHwgIWkyKSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgU2VxdWVuY2VEaWZmKGkxLCBpMik7XG4gICAgfVxuICAgIGdldFN0YXJ0cygpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBPZmZzZXRQYWlyKHRoaXMuc2VxMVJhbmdlLnN0YXJ0LCB0aGlzLnNlcTJSYW5nZS5zdGFydCk7XG4gICAgfVxuICAgIGdldEVuZEV4Y2x1c2l2ZXMoKSB7XG4gICAgICAgIHJldHVybiBuZXcgT2Zmc2V0UGFpcih0aGlzLnNlcTFSYW5nZS5lbmRFeGNsdXNpdmUsIHRoaXMuc2VxMlJhbmdlLmVuZEV4Y2x1c2l2ZSk7XG4gICAgfVxufVxuLyoqXG4gKiBSZXN1bHQgb2YgYSBkaWZmIGFsZ29yaXRobSBjb21wdXRhdGlvbi5cbiAqL1xuY2xhc3MgRGlmZkFsZ29yaXRobVJlc3VsdCB7XG4gICAgZGlmZnM7XG4gICAgaGl0VGltZW91dDtcbiAgICBzdGF0aWMgdHJpdmlhbChzZXExLCBzZXEyKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGlmZkFsZ29yaXRobVJlc3VsdChbbmV3IFNlcXVlbmNlRGlmZihPZmZzZXRSYW5nZS5vZkxlbmd0aChzZXExLmxlbmd0aCksIE9mZnNldFJhbmdlLm9mTGVuZ3RoKHNlcTIubGVuZ3RoKSldLCBmYWxzZSk7XG4gICAgfVxuICAgIHN0YXRpYyB0cml2aWFsVGltZWRPdXQoc2VxMSwgc2VxMikge1xuICAgICAgICByZXR1cm4gbmV3IERpZmZBbGdvcml0aG1SZXN1bHQoW25ldyBTZXF1ZW5jZURpZmYoT2Zmc2V0UmFuZ2Uub2ZMZW5ndGgoc2VxMS5sZW5ndGgpLCBPZmZzZXRSYW5nZS5vZkxlbmd0aChzZXEyLmxlbmd0aCkpXSwgdHJ1ZSk7XG4gICAgfVxuICAgIGNvbnN0cnVjdG9yKGRpZmZzLCBoaXRUaW1lb3V0KSB7XG4gICAgICAgIHRoaXMuZGlmZnMgPSBkaWZmcztcbiAgICAgICAgdGhpcy5oaXRUaW1lb3V0ID0gaGl0VGltZW91dDtcbiAgICB9XG59XG4vLyBIZWxwZXIgZnVuY3Rpb24gZm9yIGl0ZXJhdGluZyB3aXRoIG5laWdoYm9yc1xuZnVuY3Rpb24gZm9yRWFjaEFkamFjZW50KGl0ZW1zLCBjYWxsYmFjaykge1xuICAgIGxldCBwcmV2ID0gdW5kZWZpbmVkO1xuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgICBjYWxsYmFjayhwcmV2LCBpdGVtKTtcbiAgICAgICAgcHJldiA9IGl0ZW07XG4gICAgfVxuICAgIGNhbGxiYWNrKHByZXYsIHVuZGVmaW5lZCk7XG59XG5cbi8qKlxuICogQSAyRCBhcnJheSBpbXBsZW1lbnRhdGlvbi5cbiAqL1xuY2xhc3MgQXJyYXkyRCB7XG4gICAgd2lkdGg7XG4gICAgaGVpZ2h0O1xuICAgIGFycmF5ID0gW107XG4gICAgY29uc3RydWN0b3Iod2lkdGgsIGhlaWdodCkge1xuICAgICAgICB0aGlzLndpZHRoID0gd2lkdGg7XG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgICB0aGlzLmFycmF5ID0gbmV3IEFycmF5KHdpZHRoICogaGVpZ2h0KTtcbiAgICB9XG4gICAgZ2V0KHgsIHkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXJyYXlbeCArIHkgKiB0aGlzLndpZHRoXTtcbiAgICB9XG4gICAgc2V0KHgsIHksIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYXJyYXlbeCArIHkgKiB0aGlzLndpZHRoXSA9IHZhbHVlO1xuICAgIH1cbn1cbi8qKlxuICogQSBPKE1OKSBkaWZmaW5nIGFsZ29yaXRobSB0aGF0IHN1cHBvcnRzIGEgc2NvcmUgZnVuY3Rpb24uXG4gKiBUaGUgYWxnb3JpdGhtIGNhbiBiZSBpbXByb3ZlZCBieSBwcm9jZXNzaW5nIHRoZSAyZCBhcnJheSBkaWFnb25hbGx5LlxuICovXG5jbGFzcyBEeW5hbWljUHJvZ3JhbW1pbmdEaWZmaW5nIHtcbiAgICBjb21wdXRlKHNlcXVlbmNlMSwgc2VxdWVuY2UyLCB0aW1lb3V0ID0gSW5maW5pdGVUaW1lb3V0Lmluc3RhbmNlLCBlcXVhbGl0eVNjb3JlKSB7XG4gICAgICAgIGlmIChzZXF1ZW5jZTEubGVuZ3RoID09PSAwIHx8IHNlcXVlbmNlMi5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBEaWZmQWxnb3JpdGhtUmVzdWx0LnRyaXZpYWwoc2VxdWVuY2UxLCBzZXF1ZW5jZTIpO1xuICAgICAgICB9XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBsY3NMZW5ndGhzLmdldChpLCBqKTogTGVuZ3RoIG9mIHRoZSBsb25nZXN0IGNvbW1vbiBzdWJzZXF1ZW5jZSBvZlxuICAgICAgICAgKiBzZXF1ZW5jZTEuc3Vic3RyaW5nKDAsIGkgKyAxKSBhbmQgc2VxdWVuY2UyLnN1YnN0cmluZygwLCBqICsgMSkuXG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBsY3NMZW5ndGhzID0gbmV3IEFycmF5MkQoc2VxdWVuY2UxLmxlbmd0aCwgc2VxdWVuY2UyLmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IGRpcmVjdGlvbnMgPSBuZXcgQXJyYXkyRChzZXF1ZW5jZTEubGVuZ3RoLCBzZXF1ZW5jZTIubGVuZ3RoKTtcbiAgICAgICAgY29uc3QgbGVuZ3RocyA9IG5ldyBBcnJheTJEKHNlcXVlbmNlMS5sZW5ndGgsIHNlcXVlbmNlMi5sZW5ndGgpO1xuICAgICAgICAvLyBJbml0aWFsaXplIGxjc0xlbmd0aHNcbiAgICAgICAgZm9yIChsZXQgczEgPSAwOyBzMSA8IHNlcXVlbmNlMS5sZW5ndGg7IHMxKyspIHtcbiAgICAgICAgICAgIGZvciAobGV0IHMyID0gMDsgczIgPCBzZXF1ZW5jZTIubGVuZ3RoOyBzMisrKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aW1lb3V0LmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRGlmZkFsZ29yaXRobVJlc3VsdC50cml2aWFsVGltZWRPdXQoc2VxdWVuY2UxLCBzZXF1ZW5jZTIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBob3Jpem9udGFsTGVuID0gczEgPT09IDAgPyAwIDogbGNzTGVuZ3Rocy5nZXQoczEgLSAxLCBzMik7XG4gICAgICAgICAgICAgICAgY29uc3QgdmVydGljYWxMZW4gPSBzMiA9PT0gMCA/IDAgOiBsY3NMZW5ndGhzLmdldChzMSwgczIgLSAxKTtcbiAgICAgICAgICAgICAgICBsZXQgZXh0ZW5kZWRTZXFTY29yZTtcbiAgICAgICAgICAgICAgICBpZiAoc2VxdWVuY2UxLmdldEVsZW1lbnQoczEpID09PSBzZXF1ZW5jZTIuZ2V0RWxlbWVudChzMikpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHMxID09PSAwIHx8IHMyID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHRlbmRlZFNlcVNjb3JlID0gMDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuZGVkU2VxU2NvcmUgPSBsY3NMZW5ndGhzLmdldChzMSAtIDEsIHMyIC0gMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHMxID4gMCAmJiBzMiA+IDAgJiYgZGlyZWN0aW9ucy5nZXQoczEgLSAxLCBzMiAtIDEpID09PSAzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBQcmVmZXIgY29uc2VjdXRpdmUgZGlhZ29uYWxzXG4gICAgICAgICAgICAgICAgICAgICAgICBleHRlbmRlZFNlcVNjb3JlICs9IGxlbmd0aHMuZ2V0KHMxIC0gMSwgczIgLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBleHRlbmRlZFNlcVNjb3JlICs9IChlcXVhbGl0eVNjb3JlID8gZXF1YWxpdHlTY29yZShzMSwgczIpIDogMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBleHRlbmRlZFNlcVNjb3JlID0gLTE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1ZhbHVlID0gTWF0aC5tYXgoaG9yaXpvbnRhbExlbiwgdmVydGljYWxMZW4sIGV4dGVuZGVkU2VxU2NvcmUpO1xuICAgICAgICAgICAgICAgIGlmIChuZXdWYWx1ZSA9PT0gZXh0ZW5kZWRTZXFTY29yZSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBQcmVmZXIgZGlhZ29uYWxzXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHByZXZMZW4gPSBzMSA+IDAgJiYgczIgPiAwID8gbGVuZ3Rocy5nZXQoczEgLSAxLCBzMiAtIDEpIDogMDtcbiAgICAgICAgICAgICAgICAgICAgbGVuZ3Rocy5zZXQoczEsIHMyLCBwcmV2TGVuICsgMSk7XG4gICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbnMuc2V0KHMxLCBzMiwgMyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5ld1ZhbHVlID09PSBob3Jpem9udGFsTGVuKSB7XG4gICAgICAgICAgICAgICAgICAgIGxlbmd0aHMuc2V0KHMxLCBzMiwgMCk7XG4gICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbnMuc2V0KHMxLCBzMiwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5ld1ZhbHVlID09PSB2ZXJ0aWNhbExlbikge1xuICAgICAgICAgICAgICAgICAgICBsZW5ndGhzLnNldChzMSwgczIsIDApO1xuICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb25zLnNldChzMSwgczIsIDIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsY3NMZW5ndGhzLnNldChzMSwgczIsIG5ld1ZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBCYWNrdHJhY2tpbmdcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgICAgIGxldCBsYXN0QWxpZ25pbmdQb3NTMSA9IHNlcXVlbmNlMS5sZW5ndGg7XG4gICAgICAgIGxldCBsYXN0QWxpZ25pbmdQb3NTMiA9IHNlcXVlbmNlMi5sZW5ndGg7XG4gICAgICAgIGZ1bmN0aW9uIHJlcG9ydERlY3JlYXNpbmdBbGlnbmluZ1Bvc2l0aW9ucyhzMSwgczIpIHtcbiAgICAgICAgICAgIGlmIChzMSArIDEgIT09IGxhc3RBbGlnbmluZ1Bvc1MxIHx8IHMyICsgMSAhPT0gbGFzdEFsaWduaW5nUG9zUzIpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChuZXcgU2VxdWVuY2VEaWZmKG5ldyBPZmZzZXRSYW5nZShzMSArIDEsIGxhc3RBbGlnbmluZ1Bvc1MxKSwgbmV3IE9mZnNldFJhbmdlKHMyICsgMSwgbGFzdEFsaWduaW5nUG9zUzIpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsYXN0QWxpZ25pbmdQb3NTMSA9IHMxO1xuICAgICAgICAgICAgbGFzdEFsaWduaW5nUG9zUzIgPSBzMjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgczEgPSBzZXF1ZW5jZTEubGVuZ3RoIC0gMTtcbiAgICAgICAgbGV0IHMyID0gc2VxdWVuY2UyLmxlbmd0aCAtIDE7XG4gICAgICAgIHdoaWxlIChzMSA+PSAwICYmIHMyID49IDApIHtcbiAgICAgICAgICAgIGlmIChkaXJlY3Rpb25zLmdldChzMSwgczIpID09PSAzKSB7XG4gICAgICAgICAgICAgICAgcmVwb3J0RGVjcmVhc2luZ0FsaWduaW5nUG9zaXRpb25zKHMxLCBzMik7XG4gICAgICAgICAgICAgICAgczEtLTtcbiAgICAgICAgICAgICAgICBzMi0tO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGRpcmVjdGlvbnMuZ2V0KHMxLCBzMikgPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgczEtLTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHMyLS07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJlcG9ydERlY3JlYXNpbmdBbGlnbmluZ1Bvc2l0aW9ucygtMSwgLTEpO1xuICAgICAgICByZXN1bHQucmV2ZXJzZSgpO1xuICAgICAgICByZXR1cm4gbmV3IERpZmZBbGdvcml0aG1SZXN1bHQocmVzdWx0LCBmYWxzZSk7XG4gICAgfVxufVxuXG4vKipcbiAqIEFuIE8oTkQpIGRpZmYgYWxnb3JpdGhtIHRoYXQgaGFzIGEgcXVhZHJhdGljIHNwYWNlIHdvcnN0LWNhc2UgY29tcGxleGl0eS5cbiAqL1xuY2xhc3MgTXllcnNEaWZmQWxnb3JpdGhtIHtcbiAgICBjb21wdXRlKHNlcTEsIHNlcTIsIHRpbWVvdXQgPSBJbmZpbml0ZVRpbWVvdXQuaW5zdGFuY2UpIHtcbiAgICAgICAgLy8gQ29tbW9uIHNwZWNpYWwgY2FzZXMgLSBlYXJseSByZXR1cm4gaW1wcm92ZXMgcGVyZm9ybWFuY2UgZHJhbWF0aWNhbGx5XG4gICAgICAgIGlmIChzZXExLmxlbmd0aCA9PT0gMCB8fCBzZXEyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIERpZmZBbGdvcml0aG1SZXN1bHQudHJpdmlhbChzZXExLCBzZXEyKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzZXFYID0gc2VxMTsgLy8gVGV4dCBvbiB0aGUgeCBheGlzXG4gICAgICAgIGNvbnN0IHNlcVkgPSBzZXEyOyAvLyBUZXh0IG9uIHRoZSB5IGF4aXNcbiAgICAgICAgZnVuY3Rpb24gZ2V0WEFmdGVyU25ha2UoeCwgeSkge1xuICAgICAgICAgICAgd2hpbGUgKHggPCBzZXFYLmxlbmd0aCAmJiB5IDwgc2VxWS5sZW5ndGggJiYgc2VxWC5nZXRFbGVtZW50KHgpID09PSBzZXFZLmdldEVsZW1lbnQoeSkpIHtcbiAgICAgICAgICAgICAgICB4Kys7XG4gICAgICAgICAgICAgICAgeSsrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHg7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGQgPSAwO1xuICAgICAgICAvLyBWW2tdOiBYIHZhbHVlIG9mIGxvbmdlc3QgZC1saW5lIHRoYXQgZW5kcyBpbiBkaWFnb25hbCBrLlxuICAgICAgICAvLyBkLWxpbmU6IHBhdGggZnJvbSAoMCwwKSB0byAoeCx5KSB0aGF0IHVzZXMgZXhhY3RseSBkIG5vbi1kaWFnb25hbHMuXG4gICAgICAgIC8vIGRpYWdvbmFsIGs6IFNldCBvZiBwb2ludHMgKHgseSkgd2l0aCB4LXkgPSBrLlxuICAgICAgICBjb25zdCBWID0gbmV3IEZhc3RJbnQzMkFycmF5KCk7XG4gICAgICAgIFYuc2V0KDAsIGdldFhBZnRlclNuYWtlKDAsIDApKTtcbiAgICAgICAgY29uc3QgcGF0aHMgPSBuZXcgRmFzdEFycmF5TmVnYXRpdmVJbmRpY2VzKCk7XG4gICAgICAgIHBhdGhzLnNldCgwLCBWLmdldCgwKSA9PT0gMCA/IG51bGwgOiBuZXcgU25ha2VQYXRoKG51bGwsIDAsIDAsIFYuZ2V0KDApKSk7XG4gICAgICAgIGxldCBrID0gMDtcbiAgICAgICAgbG9vcDogd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIGQrKztcbiAgICAgICAgICAgIGlmICghdGltZW91dC5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gRGlmZkFsZ29yaXRobVJlc3VsdC50cml2aWFsVGltZWRPdXQoc2VxWCwgc2VxWSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBUaGUgcGFwZXIgaGFzIGBmb3IgKGsgPSAtZDsgayA8PSBkOyBrICs9IDIpYCwgYnV0IHdlIGNhbiBpZ25vcmUgZGlhZ29uYWxzIHRoYXQgY2Fubm90IGluZmx1ZW5jZSB0aGUgcmVzdWx0LlxuICAgICAgICAgICAgY29uc3QgbG93ZXJCb3VuZCA9IC1NYXRoLm1pbihkLCBzZXFZLmxlbmd0aCArIChkICUgMikpO1xuICAgICAgICAgICAgY29uc3QgdXBwZXJCb3VuZCA9IE1hdGgubWluKGQsIHNlcVgubGVuZ3RoICsgKGQgJSAyKSk7XG4gICAgICAgICAgICBmb3IgKGsgPSBsb3dlckJvdW5kOyBrIDw9IHVwcGVyQm91bmQ7IGsgKz0gMikge1xuICAgICAgICAgICAgICAgIC8vIFdlIGNhbiB1c2UgdGhlIFggdmFsdWVzIG9mIChkLTEpLWxpbmVzIHRvIGNvbXB1dGUgWCB2YWx1ZSBvZiB0aGUgbG9uZ2VzdCBkLWxpbmVzLlxuICAgICAgICAgICAgICAgIGNvbnN0IG1heFhvZkRMaW5lVG9wID0gayA9PT0gdXBwZXJCb3VuZCA/IC0xIDogVi5nZXQoayArIDEpOyAvLyBWZXJ0aWNhbCBub24tZGlhZ29uYWwgKGFkZCBzeW1ib2wgaW4gc2VxWClcbiAgICAgICAgICAgICAgICBjb25zdCBtYXhYb2ZETGluZUxlZnQgPSBrID09PSBsb3dlckJvdW5kID8gLTEgOiBWLmdldChrIC0gMSkgKyAxOyAvLyBIb3Jpem9udGFsIG5vbi1kaWFnb25hbCAoZGVsZXRlIHN5bWJvbCBpbiBzZXFYKVxuICAgICAgICAgICAgICAgIGNvbnN0IHggPSBNYXRoLm1pbihNYXRoLm1heChtYXhYb2ZETGluZVRvcCwgbWF4WG9mRExpbmVMZWZ0KSwgc2VxWC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHkgPSB4IC0gaztcbiAgICAgICAgICAgICAgICBpZiAoeCA+IHNlcVgubGVuZ3RoIHx8IHkgPiBzZXFZLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3TWF4WCA9IGdldFhBZnRlclNuYWtlKHgsIHkpO1xuICAgICAgICAgICAgICAgIFYuc2V0KGssIG5ld01heFgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGxhc3RQYXRoID0geCA9PT0gbWF4WG9mRExpbmVUb3AgPyBwYXRocy5nZXQoayArIDEpIDogcGF0aHMuZ2V0KGsgLSAxKTtcbiAgICAgICAgICAgICAgICBwYXRocy5zZXQoaywgbmV3TWF4WCAhPT0geCA/IG5ldyBTbmFrZVBhdGgobGFzdFBhdGgsIHgsIHksIG5ld01heFggLSB4KSA6IGxhc3RQYXRoKTtcbiAgICAgICAgICAgICAgICBpZiAoVi5nZXQoaykgPT09IHNlcVgubGVuZ3RoICYmIFYuZ2V0KGspIC0gayA9PT0gc2VxWS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWsgbG9vcDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHBhdGggPSBwYXRocy5nZXQoayk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgICAgICBsZXQgbGFzdEFsaWduaW5nUG9zUzEgPSBzZXFYLmxlbmd0aDtcbiAgICAgICAgbGV0IGxhc3RBbGlnbmluZ1Bvc1MyID0gc2VxWS5sZW5ndGg7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICBjb25zdCBlbmRYID0gcGF0aCA/IHBhdGgueCArIHBhdGgubGVuZ3RoIDogMDtcbiAgICAgICAgICAgIGNvbnN0IGVuZFkgPSBwYXRoID8gcGF0aC55ICsgcGF0aC5sZW5ndGggOiAwO1xuICAgICAgICAgICAgaWYgKGVuZFggIT09IGxhc3RBbGlnbmluZ1Bvc1MxIHx8IGVuZFkgIT09IGxhc3RBbGlnbmluZ1Bvc1MyKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2gobmV3IFNlcXVlbmNlRGlmZihuZXcgT2Zmc2V0UmFuZ2UoZW5kWCwgbGFzdEFsaWduaW5nUG9zUzEpLCBuZXcgT2Zmc2V0UmFuZ2UoZW5kWSwgbGFzdEFsaWduaW5nUG9zUzIpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXBhdGgpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxhc3RBbGlnbmluZ1Bvc1MxID0gcGF0aC54O1xuICAgICAgICAgICAgbGFzdEFsaWduaW5nUG9zUzIgPSBwYXRoLnk7XG4gICAgICAgICAgICBwYXRoID0gcGF0aC5wcmV2O1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdC5yZXZlcnNlKCk7XG4gICAgICAgIHJldHVybiBuZXcgRGlmZkFsZ29yaXRobVJlc3VsdChyZXN1bHQsIGZhbHNlKTtcbiAgICB9XG59XG5jbGFzcyBTbmFrZVBhdGgge1xuICAgIHByZXY7XG4gICAgeDtcbiAgICB5O1xuICAgIGxlbmd0aDtcbiAgICBjb25zdHJ1Y3RvcihwcmV2LCB4LCB5LCBsZW5ndGgpIHtcbiAgICAgICAgdGhpcy5wcmV2ID0gcHJldjtcbiAgICAgICAgdGhpcy54ID0geDtcbiAgICAgICAgdGhpcy55ID0geTtcbiAgICAgICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7XG4gICAgfVxufVxuLyoqXG4gKiBBbiBhcnJheSB0aGF0IHN1cHBvcnRzIGZhc3QgbmVnYXRpdmUgaW5kaWNlcy5cbiAqL1xuY2xhc3MgRmFzdEludDMyQXJyYXkge1xuICAgIHBvc2l0aXZlQXJyID0gbmV3IEludDMyQXJyYXkoMTApO1xuICAgIG5lZ2F0aXZlQXJyID0gbmV3IEludDMyQXJyYXkoMTApO1xuICAgIGdldChpZHgpIHtcbiAgICAgICAgaWYgKGlkeCA8IDApIHtcbiAgICAgICAgICAgIGlkeCA9IC1pZHggLSAxO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubmVnYXRpdmVBcnJbaWR4XTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnBvc2l0aXZlQXJyW2lkeF07XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0KGlkeCwgdmFsdWUpIHtcbiAgICAgICAgaWYgKGlkeCA8IDApIHtcbiAgICAgICAgICAgIGlkeCA9IC1pZHggLSAxO1xuICAgICAgICAgICAgaWYgKGlkeCA+PSB0aGlzLm5lZ2F0aXZlQXJyLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFyciA9IHRoaXMubmVnYXRpdmVBcnI7XG4gICAgICAgICAgICAgICAgdGhpcy5uZWdhdGl2ZUFyciA9IG5ldyBJbnQzMkFycmF5KGFyci5sZW5ndGggKiAyKTtcbiAgICAgICAgICAgICAgICB0aGlzLm5lZ2F0aXZlQXJyLnNldChhcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5uZWdhdGl2ZUFycltpZHhdID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAoaWR4ID49IHRoaXMucG9zaXRpdmVBcnIubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYXJyID0gdGhpcy5wb3NpdGl2ZUFycjtcbiAgICAgICAgICAgICAgICB0aGlzLnBvc2l0aXZlQXJyID0gbmV3IEludDMyQXJyYXkoYXJyLmxlbmd0aCAqIDIpO1xuICAgICAgICAgICAgICAgIHRoaXMucG9zaXRpdmVBcnIuc2V0KGFycik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnBvc2l0aXZlQXJyW2lkeF0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi8qKlxuICogQW4gYXJyYXkgdGhhdCBzdXBwb3J0cyBmYXN0IG5lZ2F0aXZlIGluZGljZXMgZm9yIG9iamVjdHMuXG4gKi9cbmNsYXNzIEZhc3RBcnJheU5lZ2F0aXZlSW5kaWNlcyB7XG4gICAgcG9zaXRpdmVBcnIgPSBbXTtcbiAgICBuZWdhdGl2ZUFyciA9IFtdO1xuICAgIGdldChpZHgpIHtcbiAgICAgICAgaWYgKGlkeCA8IDApIHtcbiAgICAgICAgICAgIGlkeCA9IC1pZHggLSAxO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubmVnYXRpdmVBcnJbaWR4XTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnBvc2l0aXZlQXJyW2lkeF07XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0KGlkeCwgdmFsdWUpIHtcbiAgICAgICAgaWYgKGlkeCA8IDApIHtcbiAgICAgICAgICAgIGlkeCA9IC1pZHggLSAxO1xuICAgICAgICAgICAgdGhpcy5uZWdhdGl2ZUFycltpZHhdID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnBvc2l0aXZlQXJyW2lkeF0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gb3B0aW1pemVTZXF1ZW5jZURpZmZzKHNlcXVlbmNlMSwgc2VxdWVuY2UyLCBzZXF1ZW5jZURpZmZzKSB7XG4gICAgbGV0IHJlc3VsdCA9IHNlcXVlbmNlRGlmZnM7XG4gICAgcmVzdWx0ID0gam9pblNlcXVlbmNlRGlmZnNCeVNoaWZ0aW5nKHNlcXVlbmNlMSwgc2VxdWVuY2UyLCByZXN1bHQpO1xuICAgIC8vIFNvbWV0aW1lcywgY2FsbGluZyB0aGlzIGZ1bmN0aW9uIHR3aWNlIGltcHJvdmVzIHRoZSByZXN1bHQuXG4gICAgcmVzdWx0ID0gam9pblNlcXVlbmNlRGlmZnNCeVNoaWZ0aW5nKHNlcXVlbmNlMSwgc2VxdWVuY2UyLCByZXN1bHQpO1xuICAgIHJlc3VsdCA9IHNoaWZ0U2VxdWVuY2VEaWZmcyhzZXF1ZW5jZTEsIHNlcXVlbmNlMiwgcmVzdWx0KTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGZpeGVzIGlzc3VlcyBsaWtlIHRoaXM6XG4gKiBgYGBcbiAqIGltcG9ydCB7IEJheiwgQmFyIH0gZnJvbSBcImZvb1wiO1xuICogYGBgXG4gKiA8LT5cbiAqIGBgYFxuICogaW1wb3J0IHsgQmF6LCBCYXIsIEZvbyB9IGZyb20gXCJmb29cIjtcbiAqIGBgYFxuICogQ29tcHV0ZWQgZGlmZjogWyB7QWRkIFwiLFwiIGFmdGVyIEJhcn0sIHtBZGQgXCJGb28gXCIgYWZ0ZXIgc3BhY2V9IH1cbiAqIEltcHJvdmVkIGRpZmY6IFt7QWRkIFwiLCBGb29cIiBhZnRlciBCYXJ9XVxuICovXG5mdW5jdGlvbiBqb2luU2VxdWVuY2VEaWZmc0J5U2hpZnRpbmcoc2VxdWVuY2UxLCBzZXF1ZW5jZTIsIHNlcXVlbmNlRGlmZnMpIHtcbiAgICBpZiAoc2VxdWVuY2VEaWZmcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHNlcXVlbmNlRGlmZnM7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgIHJlc3VsdC5wdXNoKHNlcXVlbmNlRGlmZnNbMF0pO1xuICAgIC8vIEZpcnN0IG1vdmUgdGhlbSBhbGwgdG8gdGhlIGxlZnQgYXMgbXVjaCBhcyBwb3NzaWJsZSBhbmQgam9pbiB0aGVtIGlmIHBvc3NpYmxlXG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBzZXF1ZW5jZURpZmZzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHByZXZSZXN1bHQgPSByZXN1bHRbcmVzdWx0Lmxlbmd0aCAtIDFdO1xuICAgICAgICBsZXQgY3VyID0gc2VxdWVuY2VEaWZmc1tpXTtcbiAgICAgICAgaWYgKGN1ci5zZXExUmFuZ2UuaXNFbXB0eSB8fCBjdXIuc2VxMlJhbmdlLmlzRW1wdHkpIHtcbiAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IGN1ci5zZXExUmFuZ2Uuc3RhcnQgLSBwcmV2UmVzdWx0LnNlcTFSYW5nZS5lbmRFeGNsdXNpdmU7XG4gICAgICAgICAgICBsZXQgZDtcbiAgICAgICAgICAgIGZvciAoZCA9IDE7IGQgPD0gbGVuZ3RoOyBkKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoc2VxdWVuY2UxLmdldEVsZW1lbnQoY3VyLnNlcTFSYW5nZS5zdGFydCAtIGQpICE9PSBzZXF1ZW5jZTEuZ2V0RWxlbWVudChjdXIuc2VxMVJhbmdlLmVuZEV4Y2x1c2l2ZSAtIGQpIHx8XG4gICAgICAgICAgICAgICAgICAgIHNlcXVlbmNlMi5nZXRFbGVtZW50KGN1ci5zZXEyUmFuZ2Uuc3RhcnQgLSBkKSAhPT0gc2VxdWVuY2UyLmdldEVsZW1lbnQoY3VyLnNlcTJSYW5nZS5lbmRFeGNsdXNpdmUgLSBkKSkge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkLS07XG4gICAgICAgICAgICBpZiAoZCA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgLy8gTWVyZ2UgcHJldmlvdXMgYW5kIGN1cnJlbnQgZGlmZlxuICAgICAgICAgICAgICAgIHJlc3VsdFtyZXN1bHQubGVuZ3RoIC0gMV0gPSBuZXcgU2VxdWVuY2VEaWZmKG5ldyBPZmZzZXRSYW5nZShwcmV2UmVzdWx0LnNlcTFSYW5nZS5zdGFydCwgY3VyLnNlcTFSYW5nZS5lbmRFeGNsdXNpdmUgLSBsZW5ndGgpLCBuZXcgT2Zmc2V0UmFuZ2UocHJldlJlc3VsdC5zZXEyUmFuZ2Uuc3RhcnQsIGN1ci5zZXEyUmFuZ2UuZW5kRXhjbHVzaXZlIC0gbGVuZ3RoKSk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXIgPSBjdXIuZGVsdGEoLWQpO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdC5wdXNoKGN1cik7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdDIgPSBbXTtcbiAgICAvLyBUaGVuIG1vdmUgdGhlbSBhbGwgdG8gdGhlIHJpZ2h0IGFuZCBqb2luIHRoZW0gYWdhaW4gaWYgcG9zc2libGVcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlc3VsdC5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgY29uc3QgbmV4dFJlc3VsdCA9IHJlc3VsdFtpICsgMV07XG4gICAgICAgIGxldCBjdXIgPSByZXN1bHRbaV07XG4gICAgICAgIGlmIChjdXIuc2VxMVJhbmdlLmlzRW1wdHkgfHwgY3VyLnNlcTJSYW5nZS5pc0VtcHR5KSB7XG4gICAgICAgICAgICBjb25zdCBsZW5ndGggPSBuZXh0UmVzdWx0LnNlcTFSYW5nZS5zdGFydCAtIGN1ci5zZXExUmFuZ2UuZW5kRXhjbHVzaXZlO1xuICAgICAgICAgICAgbGV0IGQ7XG4gICAgICAgICAgICBmb3IgKGQgPSAwOyBkIDwgbGVuZ3RoOyBkKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoIXNlcXVlbmNlMS5pc1N0cm9uZ2x5RXF1YWwoY3VyLnNlcTFSYW5nZS5zdGFydCArIGQsIGN1ci5zZXExUmFuZ2UuZW5kRXhjbHVzaXZlICsgZCkgfHxcbiAgICAgICAgICAgICAgICAgICAgIXNlcXVlbmNlMi5pc1N0cm9uZ2x5RXF1YWwoY3VyLnNlcTJSYW5nZS5zdGFydCArIGQsIGN1ci5zZXEyUmFuZ2UuZW5kRXhjbHVzaXZlICsgZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGQgPT09IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgIC8vIE1lcmdlIHByZXZpb3VzIGFuZCBjdXJyZW50IGRpZmZcbiAgICAgICAgICAgICAgICByZXN1bHRbaSArIDFdID0gbmV3IFNlcXVlbmNlRGlmZihuZXcgT2Zmc2V0UmFuZ2UoY3VyLnNlcTFSYW5nZS5zdGFydCArIGxlbmd0aCwgbmV4dFJlc3VsdC5zZXExUmFuZ2UuZW5kRXhjbHVzaXZlKSwgbmV3IE9mZnNldFJhbmdlKGN1ci5zZXEyUmFuZ2Uuc3RhcnQgKyBsZW5ndGgsIG5leHRSZXN1bHQuc2VxMlJhbmdlLmVuZEV4Y2x1c2l2ZSkpO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGQgPiAwKSB7XG4gICAgICAgICAgICAgICAgY3VyID0gY3VyLmRlbHRhKGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJlc3VsdDIucHVzaChjdXIpO1xuICAgIH1cbiAgICBpZiAocmVzdWx0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmVzdWx0Mi5wdXNoKHJlc3VsdFtyZXN1bHQubGVuZ3RoIC0gMV0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0Mjtcbn1cbmZ1bmN0aW9uIHNoaWZ0U2VxdWVuY2VEaWZmcyhzZXF1ZW5jZTEsIHNlcXVlbmNlMiwgc2VxdWVuY2VEaWZmcykge1xuICAgIGlmICghc2VxdWVuY2UxLmdldEJvdW5kYXJ5U2NvcmUgfHwgIXNlcXVlbmNlMi5nZXRCb3VuZGFyeVNjb3JlKSB7XG4gICAgICAgIHJldHVybiBzZXF1ZW5jZURpZmZzO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlcXVlbmNlRGlmZnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgcHJldkRpZmYgPSAoaSA+IDAgPyBzZXF1ZW5jZURpZmZzW2kgLSAxXSA6IHVuZGVmaW5lZCk7XG4gICAgICAgIGNvbnN0IGRpZmYgPSBzZXF1ZW5jZURpZmZzW2ldO1xuICAgICAgICBjb25zdCBuZXh0RGlmZiA9IChpICsgMSA8IHNlcXVlbmNlRGlmZnMubGVuZ3RoID8gc2VxdWVuY2VEaWZmc1tpICsgMV0gOiB1bmRlZmluZWQpO1xuICAgICAgICBjb25zdCBzZXExVmFsaWRSYW5nZSA9IG5ldyBPZmZzZXRSYW5nZShwcmV2RGlmZiA/IHByZXZEaWZmLnNlcTFSYW5nZS5lbmRFeGNsdXNpdmUgKyAxIDogMCwgbmV4dERpZmYgPyBuZXh0RGlmZi5zZXExUmFuZ2Uuc3RhcnQgLSAxIDogc2VxdWVuY2UxLmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IHNlcTJWYWxpZFJhbmdlID0gbmV3IE9mZnNldFJhbmdlKHByZXZEaWZmID8gcHJldkRpZmYuc2VxMlJhbmdlLmVuZEV4Y2x1c2l2ZSArIDEgOiAwLCBuZXh0RGlmZiA/IG5leHREaWZmLnNlcTJSYW5nZS5zdGFydCAtIDEgOiBzZXF1ZW5jZTIubGVuZ3RoKTtcbiAgICAgICAgaWYgKGRpZmYuc2VxMVJhbmdlLmlzRW1wdHkpIHtcbiAgICAgICAgICAgIHNlcXVlbmNlRGlmZnNbaV0gPSBzaGlmdERpZmZUb0JldHRlclBvc2l0aW9uKGRpZmYsIHNlcXVlbmNlMSwgc2VxdWVuY2UyLCBzZXExVmFsaWRSYW5nZSwgc2VxMlZhbGlkUmFuZ2UpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGRpZmYuc2VxMlJhbmdlLmlzRW1wdHkpIHtcbiAgICAgICAgICAgIHNlcXVlbmNlRGlmZnNbaV0gPSBzaGlmdERpZmZUb0JldHRlclBvc2l0aW9uKGRpZmYuc3dhcCgpLCBzZXF1ZW5jZTIsIHNlcXVlbmNlMSwgc2VxMlZhbGlkUmFuZ2UsIHNlcTFWYWxpZFJhbmdlKS5zd2FwKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNlcXVlbmNlRGlmZnM7XG59XG5mdW5jdGlvbiBzaGlmdERpZmZUb0JldHRlclBvc2l0aW9uKGRpZmYsIHNlcXVlbmNlMSwgc2VxdWVuY2UyLCBzZXExVmFsaWRSYW5nZSwgc2VxMlZhbGlkUmFuZ2UpIHtcbiAgICBjb25zdCBtYXhTaGlmdExpbWl0ID0gMTAwOyAvLyBUbyBwcmV2ZW50IHBlcmZvcm1hbmNlIGlzc3Vlc1xuICAgIGxldCBkZWx0YUJlZm9yZSA9IDE7XG4gICAgd2hpbGUgKGRpZmYuc2VxMVJhbmdlLnN0YXJ0IC0gZGVsdGFCZWZvcmUgPj0gc2VxMVZhbGlkUmFuZ2Uuc3RhcnQgJiZcbiAgICAgICAgZGlmZi5zZXEyUmFuZ2Uuc3RhcnQgLSBkZWx0YUJlZm9yZSA+PSBzZXEyVmFsaWRSYW5nZS5zdGFydCAmJlxuICAgICAgICBzZXF1ZW5jZTIuaXNTdHJvbmdseUVxdWFsKGRpZmYuc2VxMlJhbmdlLnN0YXJ0IC0gZGVsdGFCZWZvcmUsIGRpZmYuc2VxMlJhbmdlLmVuZEV4Y2x1c2l2ZSAtIGRlbHRhQmVmb3JlKSAmJiBkZWx0YUJlZm9yZSA8IG1heFNoaWZ0TGltaXQpIHtcbiAgICAgICAgZGVsdGFCZWZvcmUrKztcbiAgICB9XG4gICAgZGVsdGFCZWZvcmUtLTtcbiAgICBsZXQgZGVsdGFBZnRlciA9IDA7XG4gICAgd2hpbGUgKGRpZmYuc2VxMVJhbmdlLnN0YXJ0ICsgZGVsdGFBZnRlciA8IHNlcTFWYWxpZFJhbmdlLmVuZEV4Y2x1c2l2ZSAmJlxuICAgICAgICBkaWZmLnNlcTJSYW5nZS5lbmRFeGNsdXNpdmUgKyBkZWx0YUFmdGVyIDwgc2VxMlZhbGlkUmFuZ2UuZW5kRXhjbHVzaXZlICYmXG4gICAgICAgIHNlcXVlbmNlMi5pc1N0cm9uZ2x5RXF1YWwoZGlmZi5zZXEyUmFuZ2Uuc3RhcnQgKyBkZWx0YUFmdGVyLCBkaWZmLnNlcTJSYW5nZS5lbmRFeGNsdXNpdmUgKyBkZWx0YUFmdGVyKSAmJiBkZWx0YUFmdGVyIDwgbWF4U2hpZnRMaW1pdCkge1xuICAgICAgICBkZWx0YUFmdGVyKys7XG4gICAgfVxuICAgIGlmIChkZWx0YUJlZm9yZSA9PT0gMCAmJiBkZWx0YUFmdGVyID09PSAwKSB7XG4gICAgICAgIHJldHVybiBkaWZmO1xuICAgIH1cbiAgICBsZXQgYmVzdERlbHRhID0gMDtcbiAgICBsZXQgYmVzdFNjb3JlID0gLTE7XG4gICAgLy8gRmluZCBiZXN0IHNjb3JlZCBkZWx0YVxuICAgIGZvciAobGV0IGRlbHRhID0gLWRlbHRhQmVmb3JlOyBkZWx0YSA8PSBkZWx0YUFmdGVyOyBkZWx0YSsrKSB7XG4gICAgICAgIGNvbnN0IHNlcTJPZmZzZXRTdGFydCA9IGRpZmYuc2VxMlJhbmdlLnN0YXJ0ICsgZGVsdGE7XG4gICAgICAgIGNvbnN0IHNlcTJPZmZzZXRFbmRFeGNsdXNpdmUgPSBkaWZmLnNlcTJSYW5nZS5lbmRFeGNsdXNpdmUgKyBkZWx0YTtcbiAgICAgICAgY29uc3Qgc2VxMU9mZnNldCA9IGRpZmYuc2VxMVJhbmdlLnN0YXJ0ICsgZGVsdGE7XG4gICAgICAgIGNvbnN0IHNjb3JlID0gc2VxdWVuY2UxLmdldEJvdW5kYXJ5U2NvcmUoc2VxMU9mZnNldCkgKyBzZXF1ZW5jZTIuZ2V0Qm91bmRhcnlTY29yZShzZXEyT2Zmc2V0U3RhcnQpICsgc2VxdWVuY2UyLmdldEJvdW5kYXJ5U2NvcmUoc2VxMk9mZnNldEVuZEV4Y2x1c2l2ZSk7XG4gICAgICAgIGlmIChzY29yZSA+IGJlc3RTY29yZSkge1xuICAgICAgICAgICAgYmVzdFNjb3JlID0gc2NvcmU7XG4gICAgICAgICAgICBiZXN0RGVsdGEgPSBkZWx0YTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGlmZi5kZWx0YShiZXN0RGVsdGEpO1xufVxuZnVuY3Rpb24gcmVtb3ZlU2hvcnRNYXRjaGVzKHNlcXVlbmNlMSwgc2VxdWVuY2UyLCBzZXF1ZW5jZURpZmZzKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgZm9yIChjb25zdCBzIG9mIHNlcXVlbmNlRGlmZnMpIHtcbiAgICAgICAgY29uc3QgbGFzdCA9IHJlc3VsdFtyZXN1bHQubGVuZ3RoIC0gMV07XG4gICAgICAgIGlmICghbGFzdCkge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2gocyk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocy5zZXExUmFuZ2Uuc3RhcnQgLSBsYXN0LnNlcTFSYW5nZS5lbmRFeGNsdXNpdmUgPD0gMiB8fCBzLnNlcTJSYW5nZS5zdGFydCAtIGxhc3Quc2VxMlJhbmdlLmVuZEV4Y2x1c2l2ZSA8PSAyKSB7XG4gICAgICAgICAgICByZXN1bHRbcmVzdWx0Lmxlbmd0aCAtIDFdID0gbmV3IFNlcXVlbmNlRGlmZihsYXN0LnNlcTFSYW5nZS5qb2luKHMuc2VxMVJhbmdlKSwgbGFzdC5zZXEyUmFuZ2Uuam9pbihzLnNlcTJSYW5nZSkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2gocyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIGV4dGVuZERpZmZzVG9FbnRpcmVXb3JkSWZBcHByb3ByaWF0ZShzZXF1ZW5jZTEsIHNlcXVlbmNlMiwgc2VxdWVuY2VEaWZmcywgZmluZFBhcmVudCwgZm9yY2UgPSBmYWxzZSkge1xuICAgIGNvbnN0IGVxdWFsTWFwcGluZ3MgPSBTZXF1ZW5jZURpZmYuaW52ZXJ0KHNlcXVlbmNlRGlmZnMsIHNlcXVlbmNlMS5sZW5ndGgpO1xuICAgIGNvbnN0IGFkZGl0aW9uYWwgPSBbXTtcbiAgICBsZXQgbGFzdFBvaW50ID0gbmV3IE9mZnNldFBhaXIoMCwgMCk7XG4gICAgZnVuY3Rpb24gc2NhbldvcmQocGFpciwgZXF1YWxNYXBwaW5nKSB7XG4gICAgICAgIGlmIChwYWlyLm9mZnNldDEgPCBsYXN0UG9pbnQub2Zmc2V0MSB8fCBwYWlyLm9mZnNldDIgPCBsYXN0UG9pbnQub2Zmc2V0Mikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHcxID0gZmluZFBhcmVudChzZXF1ZW5jZTEsIHBhaXIub2Zmc2V0MSk7XG4gICAgICAgIGNvbnN0IHcyID0gZmluZFBhcmVudChzZXF1ZW5jZTIsIHBhaXIub2Zmc2V0Mik7XG4gICAgICAgIGlmICghdzEgfHwgIXcyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHcgPSBuZXcgU2VxdWVuY2VEaWZmKHcxLCB3Mik7XG4gICAgICAgIGNvbnN0IGVxdWFsUGFydCA9IHcuaW50ZXJzZWN0KGVxdWFsTWFwcGluZyk7XG4gICAgICAgIGxldCBlcXVhbENoYXJzMSA9IGVxdWFsUGFydC5zZXExUmFuZ2UubGVuZ3RoO1xuICAgICAgICBsZXQgZXF1YWxDaGFyczIgPSBlcXVhbFBhcnQuc2VxMlJhbmdlLmxlbmd0aDtcbiAgICAgICAgd2hpbGUgKGVxdWFsTWFwcGluZ3MubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgbmV4dCA9IGVxdWFsTWFwcGluZ3NbMF07XG4gICAgICAgICAgICBjb25zdCBpbnRlcnNlY3RzID0gbmV4dC5zZXExUmFuZ2UuaW50ZXJzZWN0cyh3LnNlcTFSYW5nZSkgfHwgbmV4dC5zZXEyUmFuZ2UuaW50ZXJzZWN0cyh3LnNlcTJSYW5nZSk7XG4gICAgICAgICAgICBpZiAoIWludGVyc2VjdHMpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHYxID0gZmluZFBhcmVudChzZXF1ZW5jZTEsIG5leHQuc2VxMVJhbmdlLnN0YXJ0KTtcbiAgICAgICAgICAgIGNvbnN0IHYyID0gZmluZFBhcmVudChzZXF1ZW5jZTIsIG5leHQuc2VxMlJhbmdlLnN0YXJ0KTtcbiAgICAgICAgICAgIGNvbnN0IHYgPSBuZXcgU2VxdWVuY2VEaWZmKHYxLCB2Mik7XG4gICAgICAgICAgICBjb25zdCBlcXVhbFBhcnRWID0gdi5pbnRlcnNlY3QobmV4dCk7XG4gICAgICAgICAgICBlcXVhbENoYXJzMSArPSBlcXVhbFBhcnRWLnNlcTFSYW5nZS5sZW5ndGg7XG4gICAgICAgICAgICBlcXVhbENoYXJzMiArPSBlcXVhbFBhcnRWLnNlcTJSYW5nZS5sZW5ndGg7XG4gICAgICAgICAgICB3ID0gdy5qb2luKHYpO1xuICAgICAgICAgICAgaWYgKHcuc2VxMVJhbmdlLmVuZEV4Y2x1c2l2ZSA+PSBuZXh0LnNlcTFSYW5nZS5lbmRFeGNsdXNpdmUpIHtcbiAgICAgICAgICAgICAgICBlcXVhbE1hcHBpbmdzLnNoaWZ0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoKGZvcmNlICYmIGVxdWFsQ2hhcnMxICsgZXF1YWxDaGFyczIgPCB3LnNlcTFSYW5nZS5sZW5ndGggKyB3LnNlcTJSYW5nZS5sZW5ndGgpIHx8IGVxdWFsQ2hhcnMxICsgZXF1YWxDaGFyczIgPCAody5zZXExUmFuZ2UubGVuZ3RoICsgdy5zZXEyUmFuZ2UubGVuZ3RoKSAqIDIgLyAzKSB7XG4gICAgICAgICAgICBhZGRpdGlvbmFsLnB1c2godyk7XG4gICAgICAgIH1cbiAgICAgICAgbGFzdFBvaW50ID0gdy5nZXRFbmRFeGNsdXNpdmVzKCk7XG4gICAgfVxuICAgIHdoaWxlIChlcXVhbE1hcHBpbmdzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgbmV4dCA9IGVxdWFsTWFwcGluZ3Muc2hpZnQoKTtcbiAgICAgICAgaWYgKG5leHQuc2VxMVJhbmdlLmlzRW1wdHkpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHNjYW5Xb3JkKG5leHQuZ2V0U3RhcnRzKCksIG5leHQpO1xuICAgICAgICBzY2FuV29yZChuZXh0LmdldEVuZEV4Y2x1c2l2ZXMoKS5kZWx0YSgtMSksIG5leHQpO1xuICAgIH1cbiAgICBjb25zdCBtZXJnZWQgPSBtZXJnZVNlcXVlbmNlRGlmZnMoc2VxdWVuY2VEaWZmcywgYWRkaXRpb25hbCk7XG4gICAgcmV0dXJuIG1lcmdlZDtcbn1cbmZ1bmN0aW9uIG1lcmdlU2VxdWVuY2VEaWZmcyhzZXF1ZW5jZURpZmZzMSwgc2VxdWVuY2VEaWZmczIpIHtcbiAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAgICB3aGlsZSAoc2VxdWVuY2VEaWZmczEubGVuZ3RoID4gMCB8fCBzZXF1ZW5jZURpZmZzMi5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IHNkMSA9IHNlcXVlbmNlRGlmZnMxWzBdO1xuICAgICAgICBjb25zdCBzZDIgPSBzZXF1ZW5jZURpZmZzMlswXTtcbiAgICAgICAgbGV0IG5leHQ7XG4gICAgICAgIGlmIChzZDEgJiYgKCFzZDIgfHwgc2QxLnNlcTFSYW5nZS5zdGFydCA8IHNkMi5zZXExUmFuZ2Uuc3RhcnQpKSB7XG4gICAgICAgICAgICBuZXh0ID0gc2VxdWVuY2VEaWZmczEuc2hpZnQoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG5leHQgPSBzZXF1ZW5jZURpZmZzMi5zaGlmdCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXN1bHQubGVuZ3RoID4gMCAmJiByZXN1bHRbcmVzdWx0Lmxlbmd0aCAtIDFdLnNlcTFSYW5nZS5lbmRFeGNsdXNpdmUgPj0gbmV4dC5zZXExUmFuZ2Uuc3RhcnQpIHtcbiAgICAgICAgICAgIHJlc3VsdFtyZXN1bHQubGVuZ3RoIC0gMV0gPSByZXN1bHRbcmVzdWx0Lmxlbmd0aCAtIDFdLmpvaW4obmV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaChuZXh0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gcmVtb3ZlVmVyeVNob3J0TWF0Y2hpbmdMaW5lc0JldHdlZW5EaWZmcyhzZXF1ZW5jZTEsIF9zZXF1ZW5jZTIsIHNlcXVlbmNlRGlmZnMpIHtcbiAgICBsZXQgZGlmZnMgPSBzZXF1ZW5jZURpZmZzO1xuICAgIGlmIChkaWZmcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIGRpZmZzO1xuICAgIH1cbiAgICBsZXQgY291bnRlciA9IDA7XG4gICAgbGV0IHNob3VsZFJlcGVhdDtcbiAgICBkbyB7XG4gICAgICAgIHNob3VsZFJlcGVhdCA9IGZhbHNlO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBbZGlmZnNbMF1dO1xuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGRpZmZzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBjdXIgPSBkaWZmc1tpXTtcbiAgICAgICAgICAgIGNvbnN0IGxhc3RSZXN1bHQgPSByZXN1bHRbcmVzdWx0Lmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgZnVuY3Rpb24gc2hvdWxkSm9pbkRpZmZzKGJlZm9yZSwgYWZ0ZXIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB1bmNoYW5nZWRSYW5nZSA9IG5ldyBPZmZzZXRSYW5nZShsYXN0UmVzdWx0LnNlcTFSYW5nZS5lbmRFeGNsdXNpdmUsIGN1ci5zZXExUmFuZ2Uuc3RhcnQpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHVuY2hhbmdlZFRleHQgPSBzZXF1ZW5jZTEuZ2V0VGV4dCh1bmNoYW5nZWRSYW5nZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgdW5jaGFuZ2VkVGV4dFdpdGhvdXRXcyA9IHVuY2hhbmdlZFRleHQucmVwbGFjZSgvXFxzL2csICcnKTtcbiAgICAgICAgICAgICAgICBpZiAodW5jaGFuZ2VkVGV4dFdpdGhvdXRXcy5sZW5ndGggPD0gNFxuICAgICAgICAgICAgICAgICAgICAmJiAoYmVmb3JlLnNlcTFSYW5nZS5sZW5ndGggKyBiZWZvcmUuc2VxMlJhbmdlLmxlbmd0aCA+IDUgfHwgYWZ0ZXIuc2VxMVJhbmdlLmxlbmd0aCArIGFmdGVyLnNlcTJSYW5nZS5sZW5ndGggPiA1KSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgc2hvdWxkSm9pbiA9IHNob3VsZEpvaW5EaWZmcyhsYXN0UmVzdWx0LCBjdXIpO1xuICAgICAgICAgICAgaWYgKHNob3VsZEpvaW4pIHtcbiAgICAgICAgICAgICAgICBzaG91bGRSZXBlYXQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJlc3VsdFtyZXN1bHQubGVuZ3RoIC0gMV0gPSByZXN1bHRbcmVzdWx0Lmxlbmd0aCAtIDFdLmpvaW4oY3VyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGN1cik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZGlmZnMgPSByZXN1bHQ7XG4gICAgfSB3aGlsZSAoY291bnRlcisrIDwgMTAgJiYgc2hvdWxkUmVwZWF0KTtcbiAgICByZXR1cm4gZGlmZnM7XG59XG5mdW5jdGlvbiByZW1vdmVWZXJ5U2hvcnRNYXRjaGluZ1RleHRCZXR3ZWVuTG9uZ0RpZmZzKHNlcXVlbmNlMSwgc2VxdWVuY2UyLCBzZXF1ZW5jZURpZmZzKSB7XG4gICAgbGV0IGRpZmZzID0gc2VxdWVuY2VEaWZmcztcbiAgICBpZiAoZGlmZnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBkaWZmcztcbiAgICB9XG4gICAgbGV0IGNvdW50ZXIgPSAwO1xuICAgIGxldCBzaG91bGRSZXBlYXQ7XG4gICAgZG8ge1xuICAgICAgICBzaG91bGRSZXBlYXQgPSBmYWxzZTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gW2RpZmZzWzBdXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBkaWZmcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgY3VyID0gZGlmZnNbaV07XG4gICAgICAgICAgICBjb25zdCBsYXN0UmVzdWx0ID0gcmVzdWx0W3Jlc3VsdC5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgIGZ1bmN0aW9uIHNob3VsZEpvaW5EaWZmcyhiZWZvcmUsIGFmdGVyKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdW5jaGFuZ2VkUmFuZ2UgPSBuZXcgT2Zmc2V0UmFuZ2UobGFzdFJlc3VsdC5zZXExUmFuZ2UuZW5kRXhjbHVzaXZlLCBjdXIuc2VxMVJhbmdlLnN0YXJ0KTtcbiAgICAgICAgICAgICAgICBjb25zdCB1bmNoYW5nZWRMaW5lQ291bnQgPSBzZXF1ZW5jZTEuY291bnRMaW5lc0luKHVuY2hhbmdlZFJhbmdlKTtcbiAgICAgICAgICAgICAgICBpZiAodW5jaGFuZ2VkTGluZUNvdW50ID4gNSB8fCB1bmNoYW5nZWRSYW5nZS5sZW5ndGggPiA1MDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCB1bmNoYW5nZWRUZXh0ID0gc2VxdWVuY2UxLmdldFRleHQodW5jaGFuZ2VkUmFuZ2UpLnRyaW0oKTtcbiAgICAgICAgICAgICAgICBpZiAodW5jaGFuZ2VkVGV4dC5sZW5ndGggPiAyMCB8fCB1bmNoYW5nZWRUZXh0LnNwbGl0KC9cXHJcXG58XFxyfFxcbi8pLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBiZWZvcmVMaW5lQ291bnQxID0gc2VxdWVuY2UxLmNvdW50TGluZXNJbihiZWZvcmUuc2VxMVJhbmdlKTtcbiAgICAgICAgICAgICAgICBjb25zdCBiZWZvcmVTZXExTGVuZ3RoID0gYmVmb3JlLnNlcTFSYW5nZS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgY29uc3QgYmVmb3JlTGluZUNvdW50MiA9IHNlcXVlbmNlMi5jb3VudExpbmVzSW4oYmVmb3JlLnNlcTJSYW5nZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgYmVmb3JlU2VxMkxlbmd0aCA9IGJlZm9yZS5zZXEyUmFuZ2UubGVuZ3RoO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFmdGVyTGluZUNvdW50MSA9IHNlcXVlbmNlMS5jb3VudExpbmVzSW4oYWZ0ZXIuc2VxMVJhbmdlKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhZnRlclNlcTFMZW5ndGggPSBhZnRlci5zZXExUmFuZ2UubGVuZ3RoO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFmdGVyTGluZUNvdW50MiA9IHNlcXVlbmNlMi5jb3VudExpbmVzSW4oYWZ0ZXIuc2VxMlJhbmdlKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhZnRlclNlcTJMZW5ndGggPSBhZnRlci5zZXEyUmFuZ2UubGVuZ3RoO1xuICAgICAgICAgICAgICAgIGNvbnN0IG1heCA9IDIgKiA0MCArIDUwO1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGNhcCh2KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBNYXRoLm1pbih2LCBtYXgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoTWF0aC5wb3coTWF0aC5wb3coY2FwKGJlZm9yZUxpbmVDb3VudDEgKiA0MCArIGJlZm9yZVNlcTFMZW5ndGgpLCAxLjUpICsgTWF0aC5wb3coY2FwKGJlZm9yZUxpbmVDb3VudDIgKiA0MCArIGJlZm9yZVNlcTJMZW5ndGgpLCAxLjUpLCAxLjUpXG4gICAgICAgICAgICAgICAgICAgICsgTWF0aC5wb3coTWF0aC5wb3coY2FwKGFmdGVyTGluZUNvdW50MSAqIDQwICsgYWZ0ZXJTZXExTGVuZ3RoKSwgMS41KSArIE1hdGgucG93KGNhcChhZnRlckxpbmVDb3VudDIgKiA0MCArIGFmdGVyU2VxMkxlbmd0aCksIDEuNSksIDEuNSkgPiAoKG1heCAqKiAxLjUpICoqIDEuNSkgKiAxLjMpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHNob3VsZEpvaW4gPSBzaG91bGRKb2luRGlmZnMobGFzdFJlc3VsdCwgY3VyKTtcbiAgICAgICAgICAgIGlmIChzaG91bGRKb2luKSB7XG4gICAgICAgICAgICAgICAgc2hvdWxkUmVwZWF0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICByZXN1bHRbcmVzdWx0Lmxlbmd0aCAtIDFdID0gcmVzdWx0W3Jlc3VsdC5sZW5ndGggLSAxXS5qb2luKGN1cik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChjdXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGRpZmZzID0gcmVzdWx0O1xuICAgIH0gd2hpbGUgKGNvdW50ZXIrKyA8IDEwICYmIHNob3VsZFJlcGVhdCk7XG4gICAgY29uc3QgbmV3RGlmZnMgPSBbXTtcbiAgICAvLyBSZW1vdmUgc2hvcnQgc3VmZml4ZXMvcHJlZml4ZXNcbiAgICBmb3JFYWNoV2l0aE5laWdoYm9ycyhkaWZmcywgKHByZXYsIGN1ciwgbmV4dCkgPT4ge1xuICAgICAgICBsZXQgbmV3RGlmZiA9IGN1cjtcbiAgICAgICAgZnVuY3Rpb24gc2hvdWxkTWFya0FzQ2hhbmdlZCh0ZXh0KSB7XG4gICAgICAgICAgICByZXR1cm4gdGV4dC5sZW5ndGggPiAwICYmIHRleHQudHJpbSgpLmxlbmd0aCA8PSAzICYmIGN1ci5zZXExUmFuZ2UubGVuZ3RoICsgY3VyLnNlcTJSYW5nZS5sZW5ndGggPiAxMDA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZnVsbFJhbmdlMSA9IHNlcXVlbmNlMS5leHRlbmRUb0Z1bGxMaW5lcyhjdXIuc2VxMVJhbmdlKTtcbiAgICAgICAgY29uc3QgcHJlZml4ID0gc2VxdWVuY2UxLmdldFRleHQobmV3IE9mZnNldFJhbmdlKGZ1bGxSYW5nZTEuc3RhcnQsIGN1ci5zZXExUmFuZ2Uuc3RhcnQpKTtcbiAgICAgICAgaWYgKHNob3VsZE1hcmtBc0NoYW5nZWQocHJlZml4KSkge1xuICAgICAgICAgICAgbmV3RGlmZiA9IG5ld0RpZmYuZGVsdGFTdGFydCgtcHJlZml4Lmxlbmd0aCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3VmZml4ID0gc2VxdWVuY2UxLmdldFRleHQobmV3IE9mZnNldFJhbmdlKGN1ci5zZXExUmFuZ2UuZW5kRXhjbHVzaXZlLCBmdWxsUmFuZ2UxLmVuZEV4Y2x1c2l2ZSkpO1xuICAgICAgICBpZiAoc2hvdWxkTWFya0FzQ2hhbmdlZChzdWZmaXgpKSB7XG4gICAgICAgICAgICBuZXdEaWZmID0gbmV3RGlmZi5kZWx0YUVuZChzdWZmaXgubGVuZ3RoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhdmFpbGFibGVTcGFjZSA9IFNlcXVlbmNlRGlmZi5mcm9tT2Zmc2V0UGFpcnMocHJldiA/IHByZXYuZ2V0RW5kRXhjbHVzaXZlcygpIDogT2Zmc2V0UGFpci56ZXJvLCBuZXh0ID8gbmV4dC5nZXRTdGFydHMoKSA6IE9mZnNldFBhaXIubWF4KTtcbiAgICAgICAgY29uc3QgaW50ZXJzZWN0ZWQgPSBuZXdEaWZmLmludGVyc2VjdChhdmFpbGFibGVTcGFjZSk7XG4gICAgICAgIGlmIChuZXdEaWZmcy5sZW5ndGggPiAwICYmIGludGVyc2VjdGVkLmdldFN0YXJ0cygpLmVxdWFscyhuZXdEaWZmc1tuZXdEaWZmcy5sZW5ndGggLSAxXS5nZXRFbmRFeGNsdXNpdmVzKCkpKSB7XG4gICAgICAgICAgICBuZXdEaWZmc1tuZXdEaWZmcy5sZW5ndGggLSAxXSA9IG5ld0RpZmZzW25ld0RpZmZzLmxlbmd0aCAtIDFdLmpvaW4oaW50ZXJzZWN0ZWQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbmV3RGlmZnMucHVzaChpbnRlcnNlY3RlZCk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gbmV3RGlmZnM7XG59XG5mdW5jdGlvbiBmb3JFYWNoV2l0aE5laWdoYm9ycyhpdGVtcywgY2FsbGJhY2spIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNhbGxiYWNrKGl0ZW1zW2kgLSAxXSwgaXRlbXNbaV0sIGl0ZW1zW2kgKyAxXSk7XG4gICAgfVxufVxuXG5jb25zdCBDaGFyQ29kZSQxID0ge1xuICAgIFNwYWNlOiAzMixcbiAgICBUYWI6IDksXG59O1xuY2xhc3MgTGluZVNlcXVlbmNlIHtcbiAgICB0cmltbWVkSGFzaDtcbiAgICBsaW5lcztcbiAgICBjb25zdHJ1Y3Rvcih0cmltbWVkSGFzaCwgbGluZXMpIHtcbiAgICAgICAgdGhpcy50cmltbWVkSGFzaCA9IHRyaW1tZWRIYXNoO1xuICAgICAgICB0aGlzLmxpbmVzID0gbGluZXM7XG4gICAgfVxuICAgIGdldEVsZW1lbnQob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRyaW1tZWRIYXNoW29mZnNldF07XG4gICAgfVxuICAgIGdldCBsZW5ndGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRyaW1tZWRIYXNoLmxlbmd0aDtcbiAgICB9XG4gICAgZ2V0Qm91bmRhcnlTY29yZShsZW5ndGgpIHtcbiAgICAgICAgY29uc3QgaW5kZW50YXRpb25CZWZvcmUgPSBsZW5ndGggPT09IDAgPyAwIDogZ2V0SW5kZW50YXRpb24odGhpcy5saW5lc1tsZW5ndGggLSAxXSk7XG4gICAgICAgIGNvbnN0IGluZGVudGF0aW9uQWZ0ZXIgPSBsZW5ndGggPT09IHRoaXMubGluZXMubGVuZ3RoID8gMCA6IGdldEluZGVudGF0aW9uKHRoaXMubGluZXNbbGVuZ3RoXSk7XG4gICAgICAgIHJldHVybiAxMDAwIC0gKGluZGVudGF0aW9uQmVmb3JlICsgaW5kZW50YXRpb25BZnRlcik7XG4gICAgfVxuICAgIGdldFRleHQocmFuZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubGluZXMuc2xpY2UocmFuZ2Uuc3RhcnQsIHJhbmdlLmVuZEV4Y2x1c2l2ZSkuam9pbignXFxuJyk7XG4gICAgfVxuICAgIGlzU3Ryb25nbHlFcXVhbChvZmZzZXQxLCBvZmZzZXQyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxpbmVzW29mZnNldDFdID09PSB0aGlzLmxpbmVzW29mZnNldDJdO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGdldEluZGVudGF0aW9uKHN0cikge1xuICAgIGxldCBpID0gMDtcbiAgICB3aGlsZSAoaSA8IHN0ci5sZW5ndGggJiYgKHN0ci5jaGFyQ29kZUF0KGkpID09PSBDaGFyQ29kZSQxLlNwYWNlIHx8IHN0ci5jaGFyQ29kZUF0KGkpID09PSBDaGFyQ29kZSQxLlRhYikpIHtcbiAgICAgICAgaSsrO1xuICAgIH1cbiAgICByZXR1cm4gaTtcbn1cblxuY29uc3QgQ2hhckNvZGUgPSB7XG4gICAgTGluZUZlZWQ6IDEwLFxuICAgIENhcnJpYWdlUmV0dXJuOiAxMyxcbiAgICBTcGFjZTogMzIsXG4gICAgVGFiOiA5LFxuICAgIGE6IDk3LFxuICAgIHo6IDEyMixcbiAgICBBOiA2NSxcbiAgICBaOiA5MCxcbiAgICBEaWdpdDA6IDQ4LFxuICAgIERpZ2l0OTogNTcsXG4gICAgQ29tbWE6IDQ0LFxuICAgIFNlbWljb2xvbjogNTksXG59O1xuZnVuY3Rpb24gaXNTcGFjZShjaGFyQ29kZSkge1xuICAgIHJldHVybiBjaGFyQ29kZSA9PT0gQ2hhckNvZGUuU3BhY2UgfHwgY2hhckNvZGUgPT09IENoYXJDb2RlLlRhYjtcbn1cbmNsYXNzIFJhbmdlIHtcbiAgICBzdGFydExpbmVOdW1iZXI7XG4gICAgc3RhcnRDb2x1bW47XG4gICAgZW5kTGluZU51bWJlcjtcbiAgICBlbmRDb2x1bW47XG4gICAgY29uc3RydWN0b3Ioc3RhcnRMaW5lTnVtYmVyLCBzdGFydENvbHVtbiwgZW5kTGluZU51bWJlciwgZW5kQ29sdW1uKSB7XG4gICAgICAgIHRoaXMuc3RhcnRMaW5lTnVtYmVyID0gc3RhcnRMaW5lTnVtYmVyO1xuICAgICAgICB0aGlzLnN0YXJ0Q29sdW1uID0gc3RhcnRDb2x1bW47XG4gICAgICAgIHRoaXMuZW5kTGluZU51bWJlciA9IGVuZExpbmVOdW1iZXI7XG4gICAgICAgIHRoaXMuZW5kQ29sdW1uID0gZW5kQ29sdW1uO1xuICAgIH1cbiAgICBzdGF0aWMgZnJvbVBvc2l0aW9ucyhzdGFydCwgZW5kKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmFuZ2Uoc3RhcnQubGluZU51bWJlciwgc3RhcnQuY29sdW1uLCBlbmQubGluZU51bWJlciwgZW5kLmNvbHVtbik7XG4gICAgfVxufVxuY2xhc3MgUG9zaXRpb24ge1xuICAgIGxpbmVOdW1iZXI7XG4gICAgY29sdW1uO1xuICAgIGNvbnN0cnVjdG9yKGxpbmVOdW1iZXIsIGNvbHVtbikge1xuICAgICAgICB0aGlzLmxpbmVOdW1iZXIgPSBsaW5lTnVtYmVyO1xuICAgICAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjtcbiAgICB9XG4gICAgaXNCZWZvcmUob3RoZXIpIHtcbiAgICAgICAgaWYgKHRoaXMubGluZU51bWJlciA8IG90aGVyLmxpbmVOdW1iZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvdGhlci5saW5lTnVtYmVyIDwgdGhpcy5saW5lTnVtYmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuY29sdW1uIDwgb3RoZXIuY29sdW1uO1xuICAgIH1cbn1cbmNsYXNzIExpbmVzU2xpY2VDaGFyU2VxdWVuY2Uge1xuICAgIGxpbmVzO1xuICAgIGNvbnNpZGVyV2hpdGVzcGFjZUNoYW5nZXM7XG4gICAgZWxlbWVudHMgPSBbXTtcbiAgICBmaXJzdEVsZW1lbnRPZmZzZXRCeUxpbmVJZHggPSBbXTtcbiAgICBsaW5lU3RhcnRPZmZzZXRzID0gW107XG4gICAgdHJpbW1lZFdzTGVuZ3Roc0J5TGluZUlkeCA9IFtdO1xuICAgIF9yYW5nZTtcbiAgICBjb25zdHJ1Y3RvcihsaW5lcywgcmFuZ2UsIGNvbnNpZGVyV2hpdGVzcGFjZUNoYW5nZXMpIHtcbiAgICAgICAgdGhpcy5saW5lcyA9IGxpbmVzO1xuICAgICAgICB0aGlzLmNvbnNpZGVyV2hpdGVzcGFjZUNoYW5nZXMgPSBjb25zaWRlcldoaXRlc3BhY2VDaGFuZ2VzO1xuICAgICAgICB0aGlzLl9yYW5nZSA9IHJhbmdlO1xuICAgICAgICB0aGlzLmZpcnN0RWxlbWVudE9mZnNldEJ5TGluZUlkeC5wdXNoKDApO1xuICAgICAgICBmb3IgKGxldCBsaW5lTnVtYmVyID0gdGhpcy5fcmFuZ2Uuc3RhcnRMaW5lTnVtYmVyOyBsaW5lTnVtYmVyIDw9IHRoaXMuX3JhbmdlLmVuZExpbmVOdW1iZXI7IGxpbmVOdW1iZXIrKykge1xuICAgICAgICAgICAgbGV0IGxpbmUgPSBsaW5lc1tsaW5lTnVtYmVyIC0gMV07XG4gICAgICAgICAgICBsZXQgbGluZVN0YXJ0T2Zmc2V0ID0gMDtcbiAgICAgICAgICAgIGlmIChsaW5lTnVtYmVyID09PSB0aGlzLl9yYW5nZS5zdGFydExpbmVOdW1iZXIgJiYgdGhpcy5fcmFuZ2Uuc3RhcnRDb2x1bW4gPiAxKSB7XG4gICAgICAgICAgICAgICAgbGluZVN0YXJ0T2Zmc2V0ID0gdGhpcy5fcmFuZ2Uuc3RhcnRDb2x1bW4gLSAxO1xuICAgICAgICAgICAgICAgIGxpbmUgPSBsaW5lLnN1YnN0cmluZyhsaW5lU3RhcnRPZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5saW5lU3RhcnRPZmZzZXRzLnB1c2gobGluZVN0YXJ0T2Zmc2V0KTtcbiAgICAgICAgICAgIGxldCB0cmltbWVkV3NMZW5ndGggPSAwO1xuICAgICAgICAgICAgaWYgKCFjb25zaWRlcldoaXRlc3BhY2VDaGFuZ2VzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdHJpbW1lZFN0YXJ0TGluZSA9IGxpbmUudHJpbVN0YXJ0KCk7XG4gICAgICAgICAgICAgICAgdHJpbW1lZFdzTGVuZ3RoID0gbGluZS5sZW5ndGggLSB0cmltbWVkU3RhcnRMaW5lLmxlbmd0aDtcbiAgICAgICAgICAgICAgICBsaW5lID0gdHJpbW1lZFN0YXJ0TGluZS50cmltRW5kKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnRyaW1tZWRXc0xlbmd0aHNCeUxpbmVJZHgucHVzaCh0cmltbWVkV3NMZW5ndGgpO1xuICAgICAgICAgICAgY29uc3QgbGluZUxlbmd0aCA9IGxpbmVOdW1iZXIgPT09IHRoaXMuX3JhbmdlLmVuZExpbmVOdW1iZXIgPyBNYXRoLm1pbih0aGlzLl9yYW5nZS5lbmRDb2x1bW4gLSAxIC0gbGluZVN0YXJ0T2Zmc2V0IC0gdHJpbW1lZFdzTGVuZ3RoLCBsaW5lLmxlbmd0aCkgOiBsaW5lLmxlbmd0aDtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZUxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50cy5wdXNoKGxpbmUuY2hhckNvZGVBdChpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobGluZU51bWJlciA8IHRoaXMuX3JhbmdlLmVuZExpbmVOdW1iZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnRzLnB1c2goJ1xcbicuY2hhckNvZGVBdCgwKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5maXJzdEVsZW1lbnRPZmZzZXRCeUxpbmVJZHgucHVzaCh0aGlzLmVsZW1lbnRzLmxlbmd0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiBgU2xpY2U6IFwiJHt0aGlzLnRleHR9XCJgO1xuICAgIH1cbiAgICBnZXQgdGV4dCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VGV4dChuZXcgT2Zmc2V0UmFuZ2UoMCwgdGhpcy5sZW5ndGgpKTtcbiAgICB9XG4gICAgZ2V0VGV4dChyYW5nZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50cy5zbGljZShyYW5nZS5zdGFydCwgcmFuZ2UuZW5kRXhjbHVzaXZlKS5tYXAoZSA9PiBTdHJpbmcuZnJvbUNoYXJDb2RlKGUpKS5qb2luKCcnKTtcbiAgICB9XG4gICAgZ2V0RWxlbWVudChvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudHNbb2Zmc2V0XTtcbiAgICB9XG4gICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudHMubGVuZ3RoO1xuICAgIH1cbiAgICBnZXRCb3VuZGFyeVNjb3JlKGxlbmd0aCkge1xuICAgICAgICBjb25zdCBwcmV2Q2F0ZWdvcnkgPSBnZXRDYXRlZ29yeShsZW5ndGggPiAwID8gdGhpcy5lbGVtZW50c1tsZW5ndGggLSAxXSA6IC0xKTtcbiAgICAgICAgY29uc3QgbmV4dENhdGVnb3J5ID0gZ2V0Q2F0ZWdvcnkobGVuZ3RoIDwgdGhpcy5lbGVtZW50cy5sZW5ndGggPyB0aGlzLmVsZW1lbnRzW2xlbmd0aF0gOiAtMSk7XG4gICAgICAgIGlmIChwcmV2Q2F0ZWdvcnkgPT09IDcgLyogQ2hhckJvdW5kYXJ5Q2F0ZWdvcnkuTGluZUJyZWFrQ1IgKi8gJiYgbmV4dENhdGVnb3J5ID09PSA4IC8qIENoYXJCb3VuZGFyeUNhdGVnb3J5LkxpbmVCcmVha0xGICovKSB7XG4gICAgICAgICAgICAvLyBkb24ndCBicmVhayBiZXR3ZWVuIFxcciBhbmQgXFxuXG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJldkNhdGVnb3J5ID09PSA4IC8qIENoYXJCb3VuZGFyeUNhdGVnb3J5LkxpbmVCcmVha0xGICovKSB7XG4gICAgICAgICAgICAvLyBwcmVmZXIgdGhlIGxpbmVicmVhayBiZWZvcmUgdGhlIGNoYW5nZVxuICAgICAgICAgICAgcmV0dXJuIDE1MDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgc2NvcmUgPSAwO1xuICAgICAgICBpZiAocHJldkNhdGVnb3J5ICE9PSBuZXh0Q2F0ZWdvcnkpIHtcbiAgICAgICAgICAgIHNjb3JlICs9IDEwO1xuICAgICAgICAgICAgaWYgKHByZXZDYXRlZ29yeSA9PT0gMCAvKiBDaGFyQm91bmRhcnlDYXRlZ29yeS5Xb3JkTG93ZXIgKi8gJiYgbmV4dENhdGVnb3J5ID09PSAxIC8qIENoYXJCb3VuZGFyeUNhdGVnb3J5LldvcmRVcHBlciAqLykge1xuICAgICAgICAgICAgICAgIHNjb3JlICs9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc2NvcmUgKz0gZ2V0Q2F0ZWdvcnlCb3VuZGFyeVNjb3JlKHByZXZDYXRlZ29yeSk7XG4gICAgICAgIHNjb3JlICs9IGdldENhdGVnb3J5Qm91bmRhcnlTY29yZShuZXh0Q2F0ZWdvcnkpO1xuICAgICAgICByZXR1cm4gc2NvcmU7XG4gICAgfVxuICAgIHRyYW5zbGF0ZU9mZnNldChvZmZzZXQsIHByZWZlcmVuY2UgPSAncmlnaHQnKSB7XG4gICAgICAgIGNvbnN0IGkgPSBmaW5kTGFzdElkeE1vbm90b25vdXModGhpcy5maXJzdEVsZW1lbnRPZmZzZXRCeUxpbmVJZHgsICh2YWx1ZSkgPT4gdmFsdWUgPD0gb2Zmc2V0KTtcbiAgICAgICAgY29uc3QgbGluZU9mZnNldCA9IG9mZnNldCAtIHRoaXMuZmlyc3RFbGVtZW50T2Zmc2V0QnlMaW5lSWR4W2ldO1xuICAgICAgICByZXR1cm4gbmV3IFBvc2l0aW9uKHRoaXMuX3JhbmdlLnN0YXJ0TGluZU51bWJlciArIGksIDEgKyB0aGlzLmxpbmVTdGFydE9mZnNldHNbaV0gKyBsaW5lT2Zmc2V0ICsgKChsaW5lT2Zmc2V0ID09PSAwICYmIHByZWZlcmVuY2UgPT09ICdsZWZ0JykgPyAwIDogdGhpcy50cmltbWVkV3NMZW5ndGhzQnlMaW5lSWR4W2ldKSk7XG4gICAgfVxuICAgIHRyYW5zbGF0ZVJhbmdlKHJhbmdlKSB7XG4gICAgICAgIGNvbnN0IHBvczEgPSB0aGlzLnRyYW5zbGF0ZU9mZnNldChyYW5nZS5zdGFydCwgJ3JpZ2h0Jyk7XG4gICAgICAgIGNvbnN0IHBvczIgPSB0aGlzLnRyYW5zbGF0ZU9mZnNldChyYW5nZS5lbmRFeGNsdXNpdmUsICdsZWZ0Jyk7XG4gICAgICAgIGlmIChwb3MyLmlzQmVmb3JlKHBvczEpKSB7XG4gICAgICAgICAgICByZXR1cm4gUmFuZ2UuZnJvbVBvc2l0aW9ucyhwb3MyLCBwb3MyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmFuZ2UuZnJvbVBvc2l0aW9ucyhwb3MxLCBwb3MyKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRmluZHMgdGhlIHdvcmQgdGhhdCBjb250YWlucyB0aGUgY2hhcmFjdGVyIGF0IHRoZSBnaXZlbiBvZmZzZXRcbiAgICAgKi9cbiAgICBmaW5kV29yZENvbnRhaW5pbmcob2Zmc2V0KSB7XG4gICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCA+PSB0aGlzLmVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzV29yZENoYXIodGhpcy5lbGVtZW50c1tvZmZzZXRdKSkge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBmaW5kIHN0YXJ0XG4gICAgICAgIGxldCBzdGFydCA9IG9mZnNldDtcbiAgICAgICAgd2hpbGUgKHN0YXJ0ID4gMCAmJiBpc1dvcmRDaGFyKHRoaXMuZWxlbWVudHNbc3RhcnQgLSAxXSkpIHtcbiAgICAgICAgICAgIHN0YXJ0LS07XG4gICAgICAgIH1cbiAgICAgICAgLy8gZmluZCBlbmRcbiAgICAgICAgbGV0IGVuZCA9IG9mZnNldDtcbiAgICAgICAgd2hpbGUgKGVuZCA8IHRoaXMuZWxlbWVudHMubGVuZ3RoICYmIGlzV29yZENoYXIodGhpcy5lbGVtZW50c1tlbmRdKSkge1xuICAgICAgICAgICAgZW5kKys7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBPZmZzZXRSYW5nZShzdGFydCwgZW5kKTtcbiAgICB9XG4gICAgLyoqIGZvb0JhciBoYXMgdGhlIHR3byBzdWItd29yZHMgZm9vIGFuZCBiYXIgKi9cbiAgICBmaW5kU3ViV29yZENvbnRhaW5pbmcob2Zmc2V0KSB7XG4gICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCA+PSB0aGlzLmVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzV29yZENoYXIodGhpcy5lbGVtZW50c1tvZmZzZXRdKSkge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBmaW5kIHN0YXJ0XG4gICAgICAgIGxldCBzdGFydCA9IG9mZnNldDtcbiAgICAgICAgd2hpbGUgKHN0YXJ0ID4gMCAmJiBpc1dvcmRDaGFyKHRoaXMuZWxlbWVudHNbc3RhcnQgLSAxXSkgJiYgIWlzVXBwZXJDYXNlKHRoaXMuZWxlbWVudHNbc3RhcnRdKSkge1xuICAgICAgICAgICAgc3RhcnQtLTtcbiAgICAgICAgfVxuICAgICAgICAvLyBmaW5kIGVuZFxuICAgICAgICBsZXQgZW5kID0gb2Zmc2V0O1xuICAgICAgICB3aGlsZSAoZW5kIDwgdGhpcy5lbGVtZW50cy5sZW5ndGggJiYgaXNXb3JkQ2hhcih0aGlzLmVsZW1lbnRzW2VuZF0pICYmICFpc1VwcGVyQ2FzZSh0aGlzLmVsZW1lbnRzW2VuZF0pKSB7XG4gICAgICAgICAgICBlbmQrKztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IE9mZnNldFJhbmdlKHN0YXJ0LCBlbmQpO1xuICAgIH1cbiAgICBjb3VudExpbmVzSW4ocmFuZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNsYXRlT2Zmc2V0KHJhbmdlLmVuZEV4Y2x1c2l2ZSkubGluZU51bWJlciAtIHRoaXMudHJhbnNsYXRlT2Zmc2V0KHJhbmdlLnN0YXJ0KS5saW5lTnVtYmVyO1xuICAgIH1cbiAgICBpc1N0cm9uZ2x5RXF1YWwob2Zmc2V0MSwgb2Zmc2V0Mikge1xuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50c1tvZmZzZXQxXSA9PT0gdGhpcy5lbGVtZW50c1tvZmZzZXQyXTtcbiAgICB9XG4gICAgZXh0ZW5kVG9GdWxsTGluZXMocmFuZ2UpIHtcbiAgICAgICAgY29uc3Qgc3RhcnQgPSBmaW5kTGFzdE1vbm90b25vdXModGhpcy5maXJzdEVsZW1lbnRPZmZzZXRCeUxpbmVJZHgsIHggPT4geCA8PSByYW5nZS5zdGFydCkgPz8gMDtcbiAgICAgICAgY29uc3QgZW5kID0gZmluZEZpcnN0TW9ub3Rvbm91cyh0aGlzLmZpcnN0RWxlbWVudE9mZnNldEJ5TGluZUlkeCwgeCA9PiByYW5nZS5lbmRFeGNsdXNpdmUgPD0geCkgPz8gdGhpcy5lbGVtZW50cy5sZW5ndGg7XG4gICAgICAgIHJldHVybiBuZXcgT2Zmc2V0UmFuZ2Uoc3RhcnQsIGVuZCk7XG4gICAgfVxufVxuZnVuY3Rpb24gaXNXb3JkQ2hhcihjaGFyQ29kZSkge1xuICAgIHJldHVybiBjaGFyQ29kZSA+PSBDaGFyQ29kZS5hICYmIGNoYXJDb2RlIDw9IENoYXJDb2RlLnpcbiAgICAgICAgfHwgY2hhckNvZGUgPj0gQ2hhckNvZGUuQSAmJiBjaGFyQ29kZSA8PSBDaGFyQ29kZS5aXG4gICAgICAgIHx8IGNoYXJDb2RlID49IENoYXJDb2RlLkRpZ2l0MCAmJiBjaGFyQ29kZSA8PSBDaGFyQ29kZS5EaWdpdDk7XG59XG5mdW5jdGlvbiBpc1VwcGVyQ2FzZShjaGFyQ29kZSkge1xuICAgIHJldHVybiBjaGFyQ29kZSA+PSBDaGFyQ29kZS5BICYmIGNoYXJDb2RlIDw9IENoYXJDb2RlLlo7XG59XG5jb25zdCBjYXRlZ29yeVNjb3JlID0ge1xuICAgIFswIC8qIENoYXJCb3VuZGFyeUNhdGVnb3J5LldvcmRMb3dlciAqL106IDAsXG4gICAgWzEgLyogQ2hhckJvdW5kYXJ5Q2F0ZWdvcnkuV29yZFVwcGVyICovXTogMCxcbiAgICBbMiAvKiBDaGFyQm91bmRhcnlDYXRlZ29yeS5Xb3JkTnVtYmVyICovXTogMCxcbiAgICBbMyAvKiBDaGFyQm91bmRhcnlDYXRlZ29yeS5FbmQgKi9dOiAxMCxcbiAgICBbNCAvKiBDaGFyQm91bmRhcnlDYXRlZ29yeS5PdGhlciAqL106IDIsXG4gICAgWzUgLyogQ2hhckJvdW5kYXJ5Q2F0ZWdvcnkuU2VwYXJhdG9yICovXTogMzAsXG4gICAgWzYgLyogQ2hhckJvdW5kYXJ5Q2F0ZWdvcnkuU3BhY2UgKi9dOiAzLFxuICAgIFs3IC8qIENoYXJCb3VuZGFyeUNhdGVnb3J5LkxpbmVCcmVha0NSICovXTogMTAsXG4gICAgWzggLyogQ2hhckJvdW5kYXJ5Q2F0ZWdvcnkuTGluZUJyZWFrTEYgKi9dOiAxMCxcbn07XG5mdW5jdGlvbiBnZXRDYXRlZ29yeUJvdW5kYXJ5U2NvcmUoY2F0ZWdvcnkpIHtcbiAgICByZXR1cm4gY2F0ZWdvcnlTY29yZVtjYXRlZ29yeV07XG59XG5mdW5jdGlvbiBnZXRDYXRlZ29yeShjaGFyQ29kZSkge1xuICAgIGlmIChjaGFyQ29kZSA9PT0gQ2hhckNvZGUuTGluZUZlZWQpIHtcbiAgICAgICAgcmV0dXJuIDggLyogQ2hhckJvdW5kYXJ5Q2F0ZWdvcnkuTGluZUJyZWFrTEYgKi87XG4gICAgfVxuICAgIGVsc2UgaWYgKGNoYXJDb2RlID09PSBDaGFyQ29kZS5DYXJyaWFnZVJldHVybikge1xuICAgICAgICByZXR1cm4gNyAvKiBDaGFyQm91bmRhcnlDYXRlZ29yeS5MaW5lQnJlYWtDUiAqLztcbiAgICB9XG4gICAgZWxzZSBpZiAoaXNTcGFjZShjaGFyQ29kZSkpIHtcbiAgICAgICAgcmV0dXJuIDYgLyogQ2hhckJvdW5kYXJ5Q2F0ZWdvcnkuU3BhY2UgKi87XG4gICAgfVxuICAgIGVsc2UgaWYgKGNoYXJDb2RlID49IENoYXJDb2RlLmEgJiYgY2hhckNvZGUgPD0gQ2hhckNvZGUueikge1xuICAgICAgICByZXR1cm4gMCAvKiBDaGFyQm91bmRhcnlDYXRlZ29yeS5Xb3JkTG93ZXIgKi87XG4gICAgfVxuICAgIGVsc2UgaWYgKGNoYXJDb2RlID49IENoYXJDb2RlLkEgJiYgY2hhckNvZGUgPD0gQ2hhckNvZGUuWikge1xuICAgICAgICByZXR1cm4gMSAvKiBDaGFyQm91bmRhcnlDYXRlZ29yeS5Xb3JkVXBwZXIgKi87XG4gICAgfVxuICAgIGVsc2UgaWYgKGNoYXJDb2RlID49IENoYXJDb2RlLkRpZ2l0MCAmJiBjaGFyQ29kZSA8PSBDaGFyQ29kZS5EaWdpdDkpIHtcbiAgICAgICAgcmV0dXJuIDIgLyogQ2hhckJvdW5kYXJ5Q2F0ZWdvcnkuV29yZE51bWJlciAqLztcbiAgICB9XG4gICAgZWxzZSBpZiAoY2hhckNvZGUgPT09IC0xKSB7XG4gICAgICAgIHJldHVybiAzIC8qIENoYXJCb3VuZGFyeUNhdGVnb3J5LkVuZCAqLztcbiAgICB9XG4gICAgZWxzZSBpZiAoY2hhckNvZGUgPT09IENoYXJDb2RlLkNvbW1hIHx8IGNoYXJDb2RlID09PSBDaGFyQ29kZS5TZW1pY29sb24pIHtcbiAgICAgICAgcmV0dXJuIDUgLyogQ2hhckJvdW5kYXJ5Q2F0ZWdvcnkuU2VwYXJhdG9yICovO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIDQgLyogQ2hhckJvdW5kYXJ5Q2F0ZWdvcnkuT3RoZXIgKi87XG4gICAgfVxufVxuLy8gQmluYXJ5IHNlYXJjaCBoZWxwZXJzXG5mdW5jdGlvbiBmaW5kTGFzdElkeE1vbm90b25vdXMoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgIGxldCBsb3cgPSAwO1xuICAgIGxldCBoaWdoID0gYXJyYXkubGVuZ3RoIC0gMTtcbiAgICB3aGlsZSAobG93IDw9IGhpZ2gpIHtcbiAgICAgICAgY29uc3QgbWlkID0gTWF0aC5mbG9vcigobG93ICsgaGlnaCkgLyAyKTtcbiAgICAgICAgaWYgKHByZWRpY2F0ZShhcnJheVttaWRdKSkge1xuICAgICAgICAgICAgbG93ID0gbWlkICsgMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGhpZ2ggPSBtaWQgLSAxO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBoaWdoO1xufVxuZnVuY3Rpb24gZmluZExhc3RNb25vdG9ub3VzKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgICBjb25zdCBpZHggPSBmaW5kTGFzdElkeE1vbm90b25vdXMoYXJyYXksIHByZWRpY2F0ZSk7XG4gICAgcmV0dXJuIGlkeCA+PSAwID8gYXJyYXlbaWR4XSA6IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIGZpbmRGaXJzdE1vbm90b25vdXMoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgIGxldCBsb3cgPSAwO1xuICAgIGxldCBoaWdoID0gYXJyYXkubGVuZ3RoIC0gMTtcbiAgICB3aGlsZSAobG93IDw9IGhpZ2gpIHtcbiAgICAgICAgY29uc3QgbWlkID0gTWF0aC5mbG9vcigobG93ICsgaGlnaCkgLyAyKTtcbiAgICAgICAgaWYgKHByZWRpY2F0ZShhcnJheVttaWRdKSkge1xuICAgICAgICAgICAgaGlnaCA9IG1pZCAtIDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsb3cgPSBtaWQgKyAxO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBsb3cgPCBhcnJheS5sZW5ndGggPyBhcnJheVtsb3ddIDogdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEEgcmFuZ2Ugb2YgbGluZXMgKDEtYmFzZWQsIGVuZCBpcyBleGNsdXNpdmUpLlxuICovXG5jbGFzcyBMaW5lUmFuZ2Uge1xuICAgIHN0YXJ0TGluZU51bWJlcjtcbiAgICBlbmRMaW5lTnVtYmVyRXhjbHVzaXZlO1xuICAgIGNvbnN0cnVjdG9yKHN0YXJ0TGluZU51bWJlciwgZW5kTGluZU51bWJlckV4Y2x1c2l2ZSkge1xuICAgICAgICB0aGlzLnN0YXJ0TGluZU51bWJlciA9IHN0YXJ0TGluZU51bWJlcjtcbiAgICAgICAgdGhpcy5lbmRMaW5lTnVtYmVyRXhjbHVzaXZlID0gZW5kTGluZU51bWJlckV4Y2x1c2l2ZTtcbiAgICAgICAgaWYgKHN0YXJ0TGluZU51bWJlciA+IGVuZExpbmVOdW1iZXJFeGNsdXNpdmUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCByYW5nZTogJHtzdGFydExpbmVOdW1iZXJ9ID4gJHtlbmRMaW5lTnVtYmVyRXhjbHVzaXZlfWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBpc0VtcHR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zdGFydExpbmVOdW1iZXIgPT09IHRoaXMuZW5kTGluZU51bWJlckV4Y2x1c2l2ZTtcbiAgICB9XG4gICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5kTGluZU51bWJlckV4Y2x1c2l2ZSAtIHRoaXMuc3RhcnRMaW5lTnVtYmVyO1xuICAgIH1cbiAgICBqb2luKG90aGVyKSB7XG4gICAgICAgIHJldHVybiBuZXcgTGluZVJhbmdlKE1hdGgubWluKHRoaXMuc3RhcnRMaW5lTnVtYmVyLCBvdGhlci5zdGFydExpbmVOdW1iZXIpLCBNYXRoLm1heCh0aGlzLmVuZExpbmVOdW1iZXJFeGNsdXNpdmUsIG90aGVyLmVuZExpbmVOdW1iZXJFeGNsdXNpdmUpKTtcbiAgICB9XG4gICAgaW50ZXJzZWN0c09yVG91Y2hlcyhvdGhlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5zdGFydExpbmVOdW1iZXIgPD0gb3RoZXIuZW5kTGluZU51bWJlckV4Y2x1c2l2ZVxuICAgICAgICAgICAgJiYgb3RoZXIuc3RhcnRMaW5lTnVtYmVyIDw9IHRoaXMuZW5kTGluZU51bWJlckV4Y2x1c2l2ZTtcbiAgICB9XG4gICAgdG9PZmZzZXRSYW5nZSgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBPZmZzZXRSYW5nZSh0aGlzLnN0YXJ0TGluZU51bWJlciAtIDEsIHRoaXMuZW5kTGluZU51bWJlckV4Y2x1c2l2ZSAtIDEpO1xuICAgIH1cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIGBbJHt0aGlzLnN0YXJ0TGluZU51bWJlcn0sICR7dGhpcy5lbmRMaW5lTnVtYmVyRXhjbHVzaXZlfSlgO1xuICAgIH1cbn1cbi8qKlxuICogQSBtYXBwaW5nIGJldHdlZW4gdHdvIHJhbmdlcy5cbiAqL1xuY2xhc3MgUmFuZ2VNYXBwaW5nIHtcbiAgICBvcmlnaW5hbFJhbmdlO1xuICAgIG1vZGlmaWVkUmFuZ2U7XG4gICAgY29uc3RydWN0b3Iob3JpZ2luYWxSYW5nZSwgbW9kaWZpZWRSYW5nZSkge1xuICAgICAgICB0aGlzLm9yaWdpbmFsUmFuZ2UgPSBvcmlnaW5hbFJhbmdlO1xuICAgICAgICB0aGlzLm1vZGlmaWVkUmFuZ2UgPSBtb2RpZmllZFJhbmdlO1xuICAgIH1cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIGAke3JhbmdlVG9TdHJpbmcodGhpcy5vcmlnaW5hbFJhbmdlKX0gPC0+ICR7cmFuZ2VUb1N0cmluZyh0aGlzLm1vZGlmaWVkUmFuZ2UpfWA7XG4gICAgfVxuICAgIHN0YXRpYyBhc3NlcnRTb3J0ZWQocmFuZ2VNYXBwaW5ncykge1xuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHJhbmdlTWFwcGluZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXYgPSByYW5nZU1hcHBpbmdzW2kgLSAxXTtcbiAgICAgICAgICAgIGNvbnN0IGN1ciA9IHJhbmdlTWFwcGluZ3NbaV07XG4gICAgICAgICAgICBpZiAoIShwcmV2Lm9yaWdpbmFsUmFuZ2UuZW5kTGluZU51bWJlciA8PSBjdXIub3JpZ2luYWxSYW5nZS5zdGFydExpbmVOdW1iZXIgfHxcbiAgICAgICAgICAgICAgICAocHJldi5vcmlnaW5hbFJhbmdlLmVuZExpbmVOdW1iZXIgPT09IGN1ci5vcmlnaW5hbFJhbmdlLnN0YXJ0TGluZU51bWJlciAmJiBwcmV2Lm9yaWdpbmFsUmFuZ2UuZW5kQ29sdW1uIDw9IGN1ci5vcmlnaW5hbFJhbmdlLnN0YXJ0Q29sdW1uKSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JhbmdlTWFwcGluZ3MgbXVzdCBiZSBzb3J0ZWQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIHJhbmdlVG9TdHJpbmcocmFuZ2UpIHtcbiAgICByZXR1cm4gYCgke3JhbmdlLnN0YXJ0TGluZU51bWJlcn06JHtyYW5nZS5zdGFydENvbHVtbn0pLSgke3JhbmdlLmVuZExpbmVOdW1iZXJ9OiR7cmFuZ2UuZW5kQ29sdW1ufSlgO1xufVxuLyoqXG4gKiBBIG1hcHBpbmcgYmV0d2VlbiB0d28gbGluZSByYW5nZXMuXG4gKi9cbmNsYXNzIExpbmVSYW5nZU1hcHBpbmcge1xuICAgIG9yaWdpbmFsO1xuICAgIG1vZGlmaWVkO1xuICAgIGNvbnN0cnVjdG9yKG9yaWdpbmFsLCBtb2RpZmllZCkge1xuICAgICAgICB0aGlzLm9yaWdpbmFsID0gb3JpZ2luYWw7XG4gICAgICAgIHRoaXMubW9kaWZpZWQgPSBtb2RpZmllZDtcbiAgICB9XG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiBgJHt0aGlzLm9yaWdpbmFsfSA8LT4gJHt0aGlzLm1vZGlmaWVkfWA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGFzc3VtZXMgdGhhdCB0aGUgTGluZVJhbmdlTWFwcGluZyBkZXNjcmliZXMgYSB2YWxpZCBkaWZmIVxuICAgICAqIEkuZS4gaWYgb25lIHJhbmdlIGlzIGVtcHR5LCB0aGUgb3RoZXIgcmFuZ2UgY2Fubm90IGJlIHRoZSBlbnRpcmUgZG9jdW1lbnQuXG4gICAgICogSXQgYXZvaWRzIHZhcmlvdXMgcHJvYmxlbXMgd2hlbiB0aGUgbGluZSByYW5nZSBwb2ludHMgdG8gbm9uLWV4aXN0aW5nIGxpbmUtbnVtYmVycy5cbiAgICAqL1xuICAgIHRvUmFuZ2VNYXBwaW5nMihvcmlnaW5hbExpbmVzLCBtb2RpZmllZExpbmVzKSB7XG4gICAgICAgIGNvbnN0IGlzVmFsaWRMaW5lTnVtYmVyID0gKGxpbmVOdW1iZXIsIGxpbmVzKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbGluZU51bWJlciA+PSAxICYmIGxpbmVOdW1iZXIgPD0gbGluZXMubGVuZ3RoO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBub3JtYWxpemVQb3NpdGlvbiA9IChsaW5lTnVtYmVyLCBjb2x1bW4sIGxpbmVzKSA9PiB7XG4gICAgICAgICAgICBpZiAobGluZU51bWJlciA8IDEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFBvc2l0aW9uKDEsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGxpbmVOdW1iZXIgPiBsaW5lcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFBvc2l0aW9uKGxpbmVzLmxlbmd0aCwgbGluZXNbbGluZXMubGVuZ3RoIC0gMV0ubGVuZ3RoICsgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBsaW5lID0gbGluZXNbbGluZU51bWJlciAtIDFdO1xuICAgICAgICAgICAgaWYgKGNvbHVtbiA+IGxpbmUubGVuZ3RoICsgMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUG9zaXRpb24obGluZU51bWJlciwgbGluZS5sZW5ndGggKyAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuZXcgUG9zaXRpb24obGluZU51bWJlciwgY29sdW1uKTtcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGlzVmFsaWRMaW5lTnVtYmVyKHRoaXMub3JpZ2luYWwuZW5kTGluZU51bWJlckV4Y2x1c2l2ZSwgb3JpZ2luYWxMaW5lcylcbiAgICAgICAgICAgICYmIGlzVmFsaWRMaW5lTnVtYmVyKHRoaXMubW9kaWZpZWQuZW5kTGluZU51bWJlckV4Y2x1c2l2ZSwgbW9kaWZpZWRMaW5lcykpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmFuZ2VNYXBwaW5nKG5ldyBSYW5nZSh0aGlzLm9yaWdpbmFsLnN0YXJ0TGluZU51bWJlciwgMSwgdGhpcy5vcmlnaW5hbC5lbmRMaW5lTnVtYmVyRXhjbHVzaXZlLCAxKSwgbmV3IFJhbmdlKHRoaXMubW9kaWZpZWQuc3RhcnRMaW5lTnVtYmVyLCAxLCB0aGlzLm1vZGlmaWVkLmVuZExpbmVOdW1iZXJFeGNsdXNpdmUsIDEpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMub3JpZ2luYWwuaXNFbXB0eSAmJiAhdGhpcy5tb2RpZmllZC5pc0VtcHR5KSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFJhbmdlTWFwcGluZyhSYW5nZS5mcm9tUG9zaXRpb25zKG5ldyBQb3NpdGlvbih0aGlzLm9yaWdpbmFsLnN0YXJ0TGluZU51bWJlciwgMSksIG5vcm1hbGl6ZVBvc2l0aW9uKHRoaXMub3JpZ2luYWwuZW5kTGluZU51bWJlckV4Y2x1c2l2ZSAtIDEsIE51bWJlci5NQVhfU0FGRV9JTlRFR0VSLCBvcmlnaW5hbExpbmVzKSksIFJhbmdlLmZyb21Qb3NpdGlvbnMobmV3IFBvc2l0aW9uKHRoaXMubW9kaWZpZWQuc3RhcnRMaW5lTnVtYmVyLCAxKSwgbm9ybWFsaXplUG9zaXRpb24odGhpcy5tb2RpZmllZC5lbmRMaW5lTnVtYmVyRXhjbHVzaXZlIC0gMSwgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIsIG1vZGlmaWVkTGluZXMpKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMub3JpZ2luYWwuc3RhcnRMaW5lTnVtYmVyID4gMSAmJiB0aGlzLm1vZGlmaWVkLnN0YXJ0TGluZU51bWJlciA+IDEpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmFuZ2VNYXBwaW5nKFJhbmdlLmZyb21Qb3NpdGlvbnMobm9ybWFsaXplUG9zaXRpb24odGhpcy5vcmlnaW5hbC5zdGFydExpbmVOdW1iZXIgLSAxLCBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiwgb3JpZ2luYWxMaW5lcyksIG5vcm1hbGl6ZVBvc2l0aW9uKHRoaXMub3JpZ2luYWwuZW5kTGluZU51bWJlckV4Y2x1c2l2ZSAtIDEsIE51bWJlci5NQVhfU0FGRV9JTlRFR0VSLCBvcmlnaW5hbExpbmVzKSksIFJhbmdlLmZyb21Qb3NpdGlvbnMobm9ybWFsaXplUG9zaXRpb24odGhpcy5tb2RpZmllZC5zdGFydExpbmVOdW1iZXIgLSAxLCBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiwgbW9kaWZpZWRMaW5lcyksIG5vcm1hbGl6ZVBvc2l0aW9uKHRoaXMubW9kaWZpZWQuZW5kTGluZU51bWJlckV4Y2x1c2l2ZSAtIDEsIE51bWJlci5NQVhfU0FGRV9JTlRFR0VSLCBtb2RpZmllZExpbmVzKSkpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNpdHVhdGlvbiBub3c6IG9uZSByYW5nZSBpcyBlbXB0eSBhbmQgb25lIHJhbmdlIHRvdWNoZXMgdGhlIGxhc3QgbGluZSBhbmQgb25lIHJhbmdlIHN0YXJ0cyBhdCBsaW5lIDEuXG4gICAgICAgIC8vIFRoaXMgc2hvdWxkbid0IGhhcHBlbiBmb3IgdmFsaWQgZGlmZnMuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBkaWZmOiBjYW5ub3QgY29udmVydCB0byByYW5nZSBtYXBwaW5nJyk7XG4gICAgfVxufVxuLyoqXG4gKiBBIGRldGFpbGVkIG1hcHBpbmcgYmV0d2VlbiB0d28gbGluZSByYW5nZXMsIGluY2x1ZGluZyBpbm5lciBjaGFuZ2VzLlxuICovXG5jbGFzcyBEZXRhaWxlZExpbmVSYW5nZU1hcHBpbmcgZXh0ZW5kcyBMaW5lUmFuZ2VNYXBwaW5nIHtcbiAgICBpbm5lckNoYW5nZXM7XG4gICAgY29uc3RydWN0b3Iob3JpZ2luYWwsIG1vZGlmaWVkLCBpbm5lckNoYW5nZXMpIHtcbiAgICAgICAgc3VwZXIob3JpZ2luYWwsIG1vZGlmaWVkKTtcbiAgICAgICAgdGhpcy5pbm5lckNoYW5nZXMgPSBpbm5lckNoYW5nZXM7XG4gICAgfVxufVxuLyoqXG4gKiBSZXN1bHQgb2YgYSBsaW5lcyBkaWZmIGNvbXB1dGF0aW9uLlxuICovXG5jbGFzcyBMaW5lc0RpZmYge1xuICAgIGNoYW5nZXM7XG4gICAgbW92ZXM7XG4gICAgaGl0VGltZW91dDtcbiAgICBjb25zdHJ1Y3RvcihjaGFuZ2VzLCBtb3ZlcywgaGl0VGltZW91dCkge1xuICAgICAgICB0aGlzLmNoYW5nZXMgPSBjaGFuZ2VzO1xuICAgICAgICB0aGlzLm1vdmVzID0gbW92ZXM7XG4gICAgICAgIHRoaXMuaGl0VGltZW91dCA9IGhpdFRpbWVvdXQ7XG4gICAgfVxufVxuLyoqXG4gKiBSZXByZXNlbnRzIHRleHQgdGhhdCB3YXMgbW92ZWQgZnJvbSBvbmUgbG9jYXRpb24gdG8gYW5vdGhlci5cbiAqL1xuY2xhc3MgTW92ZWRUZXh0IHtcbiAgICBsaW5lUmFuZ2VNYXBwaW5nO1xuICAgIGNoYW5nZXM7XG4gICAgY29uc3RydWN0b3IobGluZVJhbmdlTWFwcGluZywgY2hhbmdlcykge1xuICAgICAgICB0aGlzLmxpbmVSYW5nZU1hcHBpbmcgPSBsaW5lUmFuZ2VNYXBwaW5nO1xuICAgICAgICB0aGlzLmNoYW5nZXMgPSBjaGFuZ2VzO1xuICAgIH1cbn1cbi8qKlxuICogSGVscGVyIHRvIGNvbnZlcnQgZnJvbSByYW5nZSBtYXBwaW5ncyB0byBsaW5lIHJhbmdlIG1hcHBpbmdzLlxuICovXG5mdW5jdGlvbiBsaW5lUmFuZ2VNYXBwaW5nRnJvbVJhbmdlTWFwcGluZ3MoYWxpZ25tZW50cywgb3JpZ2luYWxMaW5lcywgbW9kaWZpZWRMaW5lcywgZG9udEFzc2VydFN0YXJ0TGluZSA9IGZhbHNlKSB7XG4gICAgY29uc3QgY2hhbmdlcyA9IFtdO1xuICAgIGZvciAoY29uc3QgZyBvZiBncm91cEFkamFjZW50QnkoYWxpZ25tZW50cy5tYXAoYSA9PiBnZXRMaW5lUmFuZ2VNYXBwaW5nKGEsIG9yaWdpbmFsTGluZXMsIG1vZGlmaWVkTGluZXMpKSwgKGExLCBhMikgPT4gYTEub3JpZ2luYWwuaW50ZXJzZWN0c09yVG91Y2hlcyhhMi5vcmlnaW5hbClcbiAgICAgICAgfHwgYTEubW9kaWZpZWQuaW50ZXJzZWN0c09yVG91Y2hlcyhhMi5tb2RpZmllZCkpKSB7XG4gICAgICAgIGNvbnN0IGZpcnN0ID0gZ1swXTtcbiAgICAgICAgY29uc3QgbGFzdCA9IGdbZy5sZW5ndGggLSAxXTtcbiAgICAgICAgY2hhbmdlcy5wdXNoKG5ldyBEZXRhaWxlZExpbmVSYW5nZU1hcHBpbmcoZmlyc3Qub3JpZ2luYWwuam9pbihsYXN0Lm9yaWdpbmFsKSwgZmlyc3QubW9kaWZpZWQuam9pbihsYXN0Lm1vZGlmaWVkKSwgZy5tYXAoYSA9PiBhLmlubmVyQ2hhbmdlc1swXSkpKTtcbiAgICB9XG4gICAgaWYgKCFkb250QXNzZXJ0U3RhcnRMaW5lKSB7XG4gICAgICAgIC8vIEFzc2VydCB0aGF0IHRoZSBjaGFuZ2VzIGFyZSBzb3J0ZWQgYW5kIG5vbi1vdmVybGFwcGluZyAoYnV0IGRvbid0IHRocm93IC0ganVzdCBsb2cgaW4gZGVidWcpXG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgY2hhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgcHJldiA9IGNoYW5nZXNbaSAtIDFdO1xuICAgICAgICAgICAgY29uc3QgY3VyID0gY2hhbmdlc1tpXTtcbiAgICAgICAgICAgIGlmIChwcmV2Lm9yaWdpbmFsLmVuZExpbmVOdW1iZXJFeGNsdXNpdmUgPiBjdXIub3JpZ2luYWwuc3RhcnRMaW5lTnVtYmVyIHx8XG4gICAgICAgICAgICAgICAgcHJldi5tb2RpZmllZC5lbmRMaW5lTnVtYmVyRXhjbHVzaXZlID4gY3VyLm1vZGlmaWVkLnN0YXJ0TGluZU51bWJlcikge1xuICAgICAgICAgICAgICAgIC8vIFNpbGVudGx5IHNraXAgdmFsaWRhdGlvbiBpc3N1ZSAtIG1heSBiZSBleHBlY3RlZCBpbiBzb21lIGVkZ2UgY2FzZXNcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY2hhbmdlcztcbn1cbmZ1bmN0aW9uIGdldExpbmVSYW5nZU1hcHBpbmcocmFuZ2VNYXBwaW5nLCBvcmlnaW5hbExpbmVzLCBtb2RpZmllZExpbmVzKSB7XG4gICAgbGV0IGxpbmVTdGFydERlbHRhID0gMDtcbiAgICBsZXQgbGluZUVuZERlbHRhID0gMDtcbiAgICAvLyByYW5nZU1hcHBpbmcgZGVzY3JpYmVzIHRoZSBlZGl0IHRoYXQgcmVwbGFjZXMgYHJhbmdlTWFwcGluZy5vcmlnaW5hbFJhbmdlYCB3aXRoIGBuZXdUZXh0IDo9IGdldFRleHQobW9kaWZpZWRMaW5lcywgcmFuZ2VNYXBwaW5nLm1vZGlmaWVkUmFuZ2UpYC5cbiAgICAvLyBvcmlnaW5hbDogXXh4eCBcXG4gPC0gdGhpcyBsaW5lIGlzIG5vdCBtb2RpZmllZFxuICAgIC8vIG1vZGlmaWVkOiBdeHggIFxcblxuICAgIGlmIChyYW5nZU1hcHBpbmcubW9kaWZpZWRSYW5nZS5lbmRDb2x1bW4gPT09IDEgJiYgcmFuZ2VNYXBwaW5nLm9yaWdpbmFsUmFuZ2UuZW5kQ29sdW1uID09PSAxXG4gICAgICAgICYmIHJhbmdlTWFwcGluZy5vcmlnaW5hbFJhbmdlLnN0YXJ0TGluZU51bWJlciArIGxpbmVTdGFydERlbHRhIDw9IHJhbmdlTWFwcGluZy5vcmlnaW5hbFJhbmdlLmVuZExpbmVOdW1iZXJcbiAgICAgICAgJiYgcmFuZ2VNYXBwaW5nLm1vZGlmaWVkUmFuZ2Uuc3RhcnRMaW5lTnVtYmVyICsgbGluZVN0YXJ0RGVsdGEgPD0gcmFuZ2VNYXBwaW5nLm1vZGlmaWVkUmFuZ2UuZW5kTGluZU51bWJlcikge1xuICAgICAgICAvLyBXZSBjYW4gb25seSBkbyB0aGlzIGlmIHRoZSByYW5nZSBpcyBub3QgZW1wdHkgeWV0XG4gICAgICAgIGxpbmVFbmREZWx0YSA9IC0xO1xuICAgIH1cbiAgICAvLyBvcmlnaW5hbDogeHh4WyBcXG4gPC0gdGhpcyBsaW5lIGlzIG5vdCBtb2RpZmllZFxuICAgIC8vIG1vZGlmaWVkOiB4eHhbIFxcblxuICAgIGlmIChyYW5nZU1hcHBpbmcubW9kaWZpZWRSYW5nZS5zdGFydENvbHVtbiAtIDEgPj0gKG1vZGlmaWVkTGluZXNbcmFuZ2VNYXBwaW5nLm1vZGlmaWVkUmFuZ2Uuc3RhcnRMaW5lTnVtYmVyIC0gMV0/Lmxlbmd0aCA/PyAwKVxuICAgICAgICAmJiByYW5nZU1hcHBpbmcub3JpZ2luYWxSYW5nZS5zdGFydENvbHVtbiAtIDEgPj0gKG9yaWdpbmFsTGluZXNbcmFuZ2VNYXBwaW5nLm9yaWdpbmFsUmFuZ2Uuc3RhcnRMaW5lTnVtYmVyIC0gMV0/Lmxlbmd0aCA/PyAwKVxuICAgICAgICAmJiByYW5nZU1hcHBpbmcub3JpZ2luYWxSYW5nZS5zdGFydExpbmVOdW1iZXIgPD0gcmFuZ2VNYXBwaW5nLm9yaWdpbmFsUmFuZ2UuZW5kTGluZU51bWJlciArIGxpbmVFbmREZWx0YVxuICAgICAgICAmJiByYW5nZU1hcHBpbmcubW9kaWZpZWRSYW5nZS5zdGFydExpbmVOdW1iZXIgPD0gcmFuZ2VNYXBwaW5nLm1vZGlmaWVkUmFuZ2UuZW5kTGluZU51bWJlciArIGxpbmVFbmREZWx0YSkge1xuICAgICAgICAvLyBXZSBjYW4gb25seSBkbyB0aGlzIGlmIHRoZSByYW5nZSBpcyBub3QgZW1wdHkgeWV0XG4gICAgICAgIGxpbmVTdGFydERlbHRhID0gMTtcbiAgICB9XG4gICAgY29uc3Qgb3JpZ2luYWxMaW5lUmFuZ2UgPSBuZXcgTGluZVJhbmdlKHJhbmdlTWFwcGluZy5vcmlnaW5hbFJhbmdlLnN0YXJ0TGluZU51bWJlciArIGxpbmVTdGFydERlbHRhLCByYW5nZU1hcHBpbmcub3JpZ2luYWxSYW5nZS5lbmRMaW5lTnVtYmVyICsgMSArIGxpbmVFbmREZWx0YSk7XG4gICAgY29uc3QgbW9kaWZpZWRMaW5lUmFuZ2UgPSBuZXcgTGluZVJhbmdlKHJhbmdlTWFwcGluZy5tb2RpZmllZFJhbmdlLnN0YXJ0TGluZU51bWJlciArIGxpbmVTdGFydERlbHRhLCByYW5nZU1hcHBpbmcubW9kaWZpZWRSYW5nZS5lbmRMaW5lTnVtYmVyICsgMSArIGxpbmVFbmREZWx0YSk7XG4gICAgcmV0dXJuIG5ldyBEZXRhaWxlZExpbmVSYW5nZU1hcHBpbmcob3JpZ2luYWxMaW5lUmFuZ2UsIG1vZGlmaWVkTGluZVJhbmdlLCBbcmFuZ2VNYXBwaW5nXSk7XG59XG5mdW5jdGlvbiogZ3JvdXBBZGphY2VudEJ5KGl0ZW1zLCBzaG91bGRCZUdyb3VwZWQpIHtcbiAgICBsZXQgY3VycmVudEdyb3VwO1xuICAgIGxldCBsYXN0O1xuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgICBpZiAobGFzdCAhPT0gdW5kZWZpbmVkICYmIHNob3VsZEJlR3JvdXBlZChsYXN0LCBpdGVtKSkge1xuICAgICAgICAgICAgY3VycmVudEdyb3VwLnB1c2goaXRlbSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudEdyb3VwKSB7XG4gICAgICAgICAgICAgICAgeWllbGQgY3VycmVudEdyb3VwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3VycmVudEdyb3VwID0gW2l0ZW1dO1xuICAgICAgICB9XG4gICAgICAgIGxhc3QgPSBpdGVtO1xuICAgIH1cbiAgICBpZiAoY3VycmVudEdyb3VwKSB7XG4gICAgICAgIHlpZWxkIGN1cnJlbnRHcm91cDtcbiAgICB9XG59XG5jbGFzcyBBcnJheVRleHQge1xuICAgIGxpbmVzO1xuICAgIGNvbnN0cnVjdG9yKGxpbmVzKSB7XG4gICAgICAgIHRoaXMubGluZXMgPSBsaW5lcztcbiAgICB9XG4gICAgZ2V0IGxpbmVDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubGluZXMubGVuZ3RoO1xuICAgIH1cbiAgICBnZXRMaW5lQ29udGVudChsaW5lTnVtYmVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxpbmVzW2xpbmVOdW1iZXIgLSAxXTtcbiAgICB9XG59XG5cbi8qKlxuICogVGhlIG1haW4gZGlmZiBjb21wdXRlciB0aGF0IGNvbXB1dGVzIGRldGFpbGVkIGxpbmUgZGlmZnMuXG4gKi9cbmNsYXNzIERlZmF1bHRMaW5lc0RpZmZDb21wdXRlciB7XG4gICAgX2R5bmFtaWNQcm9ncmFtbWluZ0RpZmZpbmcgPSBuZXcgRHluYW1pY1Byb2dyYW1taW5nRGlmZmluZygpO1xuICAgIF9teWVyc0RpZmZpbmdBbGdvcml0aG0gPSBuZXcgTXllcnNEaWZmQWxnb3JpdGhtKCk7XG4gICAgY29tcHV0ZURpZmYob3JpZ2luYWxMaW5lcywgbW9kaWZpZWRMaW5lcywgb3B0aW9ucykge1xuICAgICAgICAvLyBIYW5kbGUgaWRlbnRpY2FsIHNpbmdsZSBsaW5lXG4gICAgICAgIGlmIChvcmlnaW5hbExpbmVzLmxlbmd0aCA8PSAxICYmIGFycmF5c0VxdWFsKG9yaWdpbmFsTGluZXMsIG1vZGlmaWVkTGluZXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IExpbmVzRGlmZihbXSwgW10sIGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBIYW5kbGUgZW1wdHkgc2luZ2xlIGxpbmUgLSB0cmVhdCBhcyBmdWxsIHJlcGxhY2VtZW50XG4gICAgICAgIGlmIChvcmlnaW5hbExpbmVzLmxlbmd0aCA9PT0gMSAmJiBvcmlnaW5hbExpbmVzWzBdLmxlbmd0aCA9PT0gMCB8fCBtb2RpZmllZExpbmVzLmxlbmd0aCA9PT0gMSAmJiBtb2RpZmllZExpbmVzWzBdLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBMaW5lc0RpZmYoW1xuICAgICAgICAgICAgICAgIG5ldyBEZXRhaWxlZExpbmVSYW5nZU1hcHBpbmcobmV3IExpbmVSYW5nZSgxLCBvcmlnaW5hbExpbmVzLmxlbmd0aCArIDEpLCBuZXcgTGluZVJhbmdlKDEsIG1vZGlmaWVkTGluZXMubGVuZ3RoICsgMSksIFtcbiAgICAgICAgICAgICAgICAgICAgbmV3IFJhbmdlTWFwcGluZyhuZXcgUmFuZ2UoMSwgMSwgb3JpZ2luYWxMaW5lcy5sZW5ndGgsIG9yaWdpbmFsTGluZXNbb3JpZ2luYWxMaW5lcy5sZW5ndGggLSAxXS5sZW5ndGggKyAxKSwgbmV3IFJhbmdlKDEsIDEsIG1vZGlmaWVkTGluZXMubGVuZ3RoLCBtb2RpZmllZExpbmVzW21vZGlmaWVkTGluZXMubGVuZ3RoIC0gMV0ubGVuZ3RoICsgMSkpXG4gICAgICAgICAgICAgICAgXSlcbiAgICAgICAgICAgIF0sIFtdLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGltZW91dCA9IG9wdGlvbnMubWF4Q29tcHV0YXRpb25UaW1lTXMgPT09IDAgPyBJbmZpbml0ZVRpbWVvdXQuaW5zdGFuY2UgOiBuZXcgRGF0ZVRpbWVvdXQob3B0aW9ucy5tYXhDb21wdXRhdGlvblRpbWVNcyk7XG4gICAgICAgIGNvbnN0IGNvbnNpZGVyV2hpdGVzcGFjZUNoYW5nZXMgPSAhb3B0aW9ucy5pZ25vcmVUcmltV2hpdGVzcGFjZTtcbiAgICAgICAgLy8gQ3JlYXRlIHBlcmZlY3QgaGFzaCBmb3IgbGluZXMgKHRyaW1tZWQpXG4gICAgICAgIGNvbnN0IHBlcmZlY3RIYXNoZXMgPSBuZXcgTWFwKCk7XG4gICAgICAgIGZ1bmN0aW9uIGdldE9yQ3JlYXRlSGFzaCh0ZXh0KSB7XG4gICAgICAgICAgICBsZXQgaGFzaCA9IHBlcmZlY3RIYXNoZXMuZ2V0KHRleHQpO1xuICAgICAgICAgICAgaWYgKGhhc2ggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGhhc2ggPSBwZXJmZWN0SGFzaGVzLnNpemU7XG4gICAgICAgICAgICAgICAgcGVyZmVjdEhhc2hlcy5zZXQodGV4dCwgaGFzaCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaGFzaDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcmlnaW5hbExpbmVzSGFzaGVzID0gb3JpZ2luYWxMaW5lcy5tYXAoKGwpID0+IGdldE9yQ3JlYXRlSGFzaChsLnRyaW0oKSkpO1xuICAgICAgICBjb25zdCBtb2RpZmllZExpbmVzSGFzaGVzID0gbW9kaWZpZWRMaW5lcy5tYXAoKGwpID0+IGdldE9yQ3JlYXRlSGFzaChsLnRyaW0oKSkpO1xuICAgICAgICBjb25zdCBzZXF1ZW5jZTEgPSBuZXcgTGluZVNlcXVlbmNlKG9yaWdpbmFsTGluZXNIYXNoZXMsIG9yaWdpbmFsTGluZXMpO1xuICAgICAgICBjb25zdCBzZXF1ZW5jZTIgPSBuZXcgTGluZVNlcXVlbmNlKG1vZGlmaWVkTGluZXNIYXNoZXMsIG1vZGlmaWVkTGluZXMpO1xuICAgICAgICAvLyBDaG9vc2UgYWxnb3JpdGhtIGJhc2VkIG9uIHNpemVcbiAgICAgICAgY29uc3QgbGluZUFsaWdubWVudFJlc3VsdCA9ICgoKSA9PiB7XG4gICAgICAgICAgICBpZiAoc2VxdWVuY2UxLmxlbmd0aCArIHNlcXVlbmNlMi5sZW5ndGggPCAxNzAwKSB7XG4gICAgICAgICAgICAgICAgLy8gVXNlIHRoZSBpbXByb3ZlZCBhbGdvcml0aG0gZm9yIHNtYWxsIGZpbGVzXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2R5bmFtaWNQcm9ncmFtbWluZ0RpZmZpbmcuY29tcHV0ZShzZXF1ZW5jZTEsIHNlcXVlbmNlMiwgdGltZW91dCwgKG9mZnNldDEsIG9mZnNldDIpID0+IG9yaWdpbmFsTGluZXNbb2Zmc2V0MV0gPT09IG1vZGlmaWVkTGluZXNbb2Zmc2V0Ml1cbiAgICAgICAgICAgICAgICAgICAgPyBtb2RpZmllZExpbmVzW29mZnNldDJdLmxlbmd0aCA9PT0gMFxuICAgICAgICAgICAgICAgICAgICAgICAgPyAwLjFcbiAgICAgICAgICAgICAgICAgICAgICAgIDogMSArIE1hdGgubG9nKDEgKyBtb2RpZmllZExpbmVzW29mZnNldDJdLmxlbmd0aClcbiAgICAgICAgICAgICAgICAgICAgOiAwLjk5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9teWVyc0RpZmZpbmdBbGdvcml0aG0uY29tcHV0ZShzZXF1ZW5jZTEsIHNlcXVlbmNlMiwgdGltZW91dCk7XG4gICAgICAgIH0pKCk7XG4gICAgICAgIGxldCBsaW5lQWxpZ25tZW50cyA9IGxpbmVBbGlnbm1lbnRSZXN1bHQuZGlmZnM7XG4gICAgICAgIGxldCBoaXRUaW1lb3V0ID0gbGluZUFsaWdubWVudFJlc3VsdC5oaXRUaW1lb3V0O1xuICAgICAgICAvLyBBcHBseSBoZXVyaXN0aWNzXG4gICAgICAgIGxpbmVBbGlnbm1lbnRzID0gb3B0aW1pemVTZXF1ZW5jZURpZmZzKHNlcXVlbmNlMSwgc2VxdWVuY2UyLCBsaW5lQWxpZ25tZW50cyk7XG4gICAgICAgIGxpbmVBbGlnbm1lbnRzID0gcmVtb3ZlVmVyeVNob3J0TWF0Y2hpbmdMaW5lc0JldHdlZW5EaWZmcyhzZXF1ZW5jZTEsIHNlcXVlbmNlMiwgbGluZUFsaWdubWVudHMpO1xuICAgICAgICBjb25zdCBhbGlnbm1lbnRzID0gW107XG4gICAgICAgIGNvbnN0IHNjYW5Gb3JXaGl0ZXNwYWNlQ2hhbmdlcyA9IChlcXVhbExpbmVzQ291bnQpID0+IHtcbiAgICAgICAgICAgIGlmICghY29uc2lkZXJXaGl0ZXNwYWNlQ2hhbmdlcykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXF1YWxMaW5lc0NvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzZXExT2Zmc2V0ID0gc2VxMUxhc3RTdGFydCArIGk7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2VxMk9mZnNldCA9IHNlcTJMYXN0U3RhcnQgKyBpO1xuICAgICAgICAgICAgICAgIGlmIChvcmlnaW5hbExpbmVzW3NlcTFPZmZzZXRdICE9PSBtb2RpZmllZExpbmVzW3NlcTJPZmZzZXRdKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYmVjYXVzZSBvZiB3aGl0ZXNwYWNlIGNoYW5nZXMsIGRpZmYgdGhlc2UgbGluZXNcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhcmFjdGVyRGlmZnMgPSB0aGlzLl9yZWZpbmVEaWZmKG9yaWdpbmFsTGluZXMsIG1vZGlmaWVkTGluZXMsIG5ldyBTZXF1ZW5jZURpZmYobmV3IE9mZnNldFJhbmdlKHNlcTFPZmZzZXQsIHNlcTFPZmZzZXQgKyAxKSwgbmV3IE9mZnNldFJhbmdlKHNlcTJPZmZzZXQsIHNlcTJPZmZzZXQgKyAxKSksIHRpbWVvdXQsIGNvbnNpZGVyV2hpdGVzcGFjZUNoYW5nZXMsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGEgb2YgY2hhcmFjdGVyRGlmZnMubWFwcGluZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsaWdubWVudHMucHVzaChhKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoY2hhcmFjdGVyRGlmZnMuaGl0VGltZW91dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaGl0VGltZW91dCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGxldCBzZXExTGFzdFN0YXJ0ID0gMDtcbiAgICAgICAgbGV0IHNlcTJMYXN0U3RhcnQgPSAwO1xuICAgICAgICBmb3IgKGNvbnN0IGRpZmYgb2YgbGluZUFsaWdubWVudHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGVxdWFsTGluZXNDb3VudCA9IGRpZmYuc2VxMVJhbmdlLnN0YXJ0IC0gc2VxMUxhc3RTdGFydDtcbiAgICAgICAgICAgIHNjYW5Gb3JXaGl0ZXNwYWNlQ2hhbmdlcyhlcXVhbExpbmVzQ291bnQpO1xuICAgICAgICAgICAgc2VxMUxhc3RTdGFydCA9IGRpZmYuc2VxMVJhbmdlLmVuZEV4Y2x1c2l2ZTtcbiAgICAgICAgICAgIHNlcTJMYXN0U3RhcnQgPSBkaWZmLnNlcTJSYW5nZS5lbmRFeGNsdXNpdmU7XG4gICAgICAgICAgICBjb25zdCBjaGFyYWN0ZXJEaWZmcyA9IHRoaXMuX3JlZmluZURpZmYob3JpZ2luYWxMaW5lcywgbW9kaWZpZWRMaW5lcywgZGlmZiwgdGltZW91dCwgY29uc2lkZXJXaGl0ZXNwYWNlQ2hhbmdlcywgb3B0aW9ucyk7XG4gICAgICAgICAgICBpZiAoY2hhcmFjdGVyRGlmZnMuaGl0VGltZW91dCkge1xuICAgICAgICAgICAgICAgIGhpdFRpbWVvdXQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChjb25zdCBhIG9mIGNoYXJhY3RlckRpZmZzLm1hcHBpbmdzKSB7XG4gICAgICAgICAgICAgICAgYWxpZ25tZW50cy5wdXNoKGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHNjYW5Gb3JXaGl0ZXNwYWNlQ2hhbmdlcyhvcmlnaW5hbExpbmVzLmxlbmd0aCAtIHNlcTFMYXN0U3RhcnQpO1xuICAgICAgICBjb25zdCBvcmlnaW5hbCA9IG5ldyBBcnJheVRleHQob3JpZ2luYWxMaW5lcyk7XG4gICAgICAgIGNvbnN0IG1vZGlmaWVkID0gbmV3IEFycmF5VGV4dChtb2RpZmllZExpbmVzKTtcbiAgICAgICAgY29uc3QgY2hhbmdlcyA9IGxpbmVSYW5nZU1hcHBpbmdGcm9tUmFuZ2VNYXBwaW5ncyhhbGlnbm1lbnRzLCBvcmlnaW5hbC5saW5lcywgbW9kaWZpZWQubGluZXMpO1xuICAgICAgICAvLyBUT0RPOiBDb21wdXRlIG1vdmVzIGlmIG9wdGlvbnMuY29tcHV0ZU1vdmVzIGlzIHRydWVcbiAgICAgICAgY29uc3QgbW92ZXMgPSBbXTtcbiAgICAgICAgcmV0dXJuIG5ldyBMaW5lc0RpZmYoY2hhbmdlcywgbW92ZXMsIGhpdFRpbWVvdXQpO1xuICAgIH1cbiAgICBfcmVmaW5lRGlmZihvcmlnaW5hbExpbmVzLCBtb2RpZmllZExpbmVzLCBkaWZmLCB0aW1lb3V0LCBjb25zaWRlcldoaXRlc3BhY2VDaGFuZ2VzLCBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGxpbmVSYW5nZU1hcHBpbmcgPSB0b0xpbmVSYW5nZU1hcHBpbmcoZGlmZik7XG4gICAgICAgIGNvbnN0IHJhbmdlTWFwcGluZyA9IGxpbmVSYW5nZU1hcHBpbmcudG9SYW5nZU1hcHBpbmcyKG9yaWdpbmFsTGluZXMsIG1vZGlmaWVkTGluZXMpO1xuICAgICAgICBjb25zdCBzbGljZTEgPSBuZXcgTGluZXNTbGljZUNoYXJTZXF1ZW5jZShvcmlnaW5hbExpbmVzLCByYW5nZU1hcHBpbmcub3JpZ2luYWxSYW5nZSwgY29uc2lkZXJXaGl0ZXNwYWNlQ2hhbmdlcyk7XG4gICAgICAgIGNvbnN0IHNsaWNlMiA9IG5ldyBMaW5lc1NsaWNlQ2hhclNlcXVlbmNlKG1vZGlmaWVkTGluZXMsIHJhbmdlTWFwcGluZy5tb2RpZmllZFJhbmdlLCBjb25zaWRlcldoaXRlc3BhY2VDaGFuZ2VzKTtcbiAgICAgICAgY29uc3QgZGlmZlJlc3VsdCA9IHNsaWNlMS5sZW5ndGggKyBzbGljZTIubGVuZ3RoIDwgNTAwXG4gICAgICAgICAgICA/IHRoaXMuX2R5bmFtaWNQcm9ncmFtbWluZ0RpZmZpbmcuY29tcHV0ZShzbGljZTEsIHNsaWNlMiwgdGltZW91dClcbiAgICAgICAgICAgIDogdGhpcy5fbXllcnNEaWZmaW5nQWxnb3JpdGhtLmNvbXB1dGUoc2xpY2UxLCBzbGljZTIsIHRpbWVvdXQpO1xuICAgICAgICBsZXQgZGlmZnMgPSBkaWZmUmVzdWx0LmRpZmZzO1xuICAgICAgICBkaWZmcyA9IG9wdGltaXplU2VxdWVuY2VEaWZmcyhzbGljZTEsIHNsaWNlMiwgZGlmZnMpO1xuICAgICAgICBkaWZmcyA9IGV4dGVuZERpZmZzVG9FbnRpcmVXb3JkSWZBcHByb3ByaWF0ZShzbGljZTEsIHNsaWNlMiwgZGlmZnMsIChzZXEsIGlkeCkgPT4gc2VxLmZpbmRXb3JkQ29udGFpbmluZyhpZHgpKTtcbiAgICAgICAgaWYgKG9wdGlvbnMuZXh0ZW5kVG9TdWJ3b3Jkcykge1xuICAgICAgICAgICAgZGlmZnMgPSBleHRlbmREaWZmc1RvRW50aXJlV29yZElmQXBwcm9wcmlhdGUoc2xpY2UxLCBzbGljZTIsIGRpZmZzLCAoc2VxLCBpZHgpID0+IHNlcS5maW5kU3ViV29yZENvbnRhaW5pbmcoaWR4KSwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZGlmZnMgPSByZW1vdmVTaG9ydE1hdGNoZXMoc2xpY2UxLCBzbGljZTIsIGRpZmZzKTtcbiAgICAgICAgZGlmZnMgPSByZW1vdmVWZXJ5U2hvcnRNYXRjaGluZ1RleHRCZXR3ZWVuTG9uZ0RpZmZzKHNsaWNlMSwgc2xpY2UyLCBkaWZmcyk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGRpZmZzLm1hcCgoZCkgPT4gbmV3IFJhbmdlTWFwcGluZyhzbGljZTEudHJhbnNsYXRlUmFuZ2UoZC5zZXExUmFuZ2UpLCBzbGljZTIudHJhbnNsYXRlUmFuZ2UoZC5zZXEyUmFuZ2UpKSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBtYXBwaW5nczogcmVzdWx0LFxuICAgICAgICAgICAgaGl0VGltZW91dDogZGlmZlJlc3VsdC5oaXRUaW1lb3V0LFxuICAgICAgICB9O1xuICAgIH1cbn1cbmZ1bmN0aW9uIHRvTGluZVJhbmdlTWFwcGluZyhzZXF1ZW5jZURpZmYpIHtcbiAgICByZXR1cm4gbmV3IExpbmVSYW5nZU1hcHBpbmcobmV3IExpbmVSYW5nZShzZXF1ZW5jZURpZmYuc2VxMVJhbmdlLnN0YXJ0ICsgMSwgc2VxdWVuY2VEaWZmLnNlcTFSYW5nZS5lbmRFeGNsdXNpdmUgKyAxKSwgbmV3IExpbmVSYW5nZShzZXF1ZW5jZURpZmYuc2VxMlJhbmdlLnN0YXJ0ICsgMSwgc2VxdWVuY2VEaWZmLnNlcTJSYW5nZS5lbmRFeGNsdXNpdmUgKyAxKSk7XG59XG5mdW5jdGlvbiBhcnJheXNFcXVhbChhLCBiKSB7XG4gICAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoYVtpXSAhPT0gYltpXSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuXG4vKiBAdHMtc2VsZi10eXBlcz1cIi4vZGlmZl93YXNtLmQudHNcIiAqL1xuXG4vKipcbiAqIENvbXB1dGUgYSBkaWZmIGJldHdlZW4gdHdvIHRleHRzLlxuICpcbiAqICMgQXJndW1lbnRzXG4gKiAqIGBvcmlnaW5hbGAgLSBUaGUgb3JpZ2luYWwgdGV4dCAobGluZXMgc2VwYXJhdGVkIGJ5IG5ld2xpbmVzKVxuICogKiBgbW9kaWZpZWRgIC0gVGhlIG1vZGlmaWVkIHRleHQgKGxpbmVzIHNlcGFyYXRlZCBieSBuZXdsaW5lcylcbiAqICogYG9wdGlvbnNgIC0gT3B0aW9uYWwgZGlmZiBvcHRpb25zIChhcyBhIEphdmFTY3JpcHQgb2JqZWN0KVxuICpcbiAqICMgUmV0dXJuc1xuICogQSBgV2FzbUxpbmVzRGlmZmAgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGNoYW5nZXMuXG4gKiBAcGFyYW0ge3N0cmluZ30gb3JpZ2luYWxcbiAqIEBwYXJhbSB7c3RyaW5nfSBtb2RpZmllZFxuICogQHBhcmFtIHthbnl9IG9wdGlvbnNcbiAqIEByZXR1cm5zIHthbnl9XG4gKi9cbmZ1bmN0aW9uIGNvbXB1dGVEaWZmKG9yaWdpbmFsLCBtb2RpZmllZCwgb3B0aW9ucykge1xuICAgIGNvbnN0IHB0cjAgPSBwYXNzU3RyaW5nVG9XYXNtMChvcmlnaW5hbCwgd2FzbS5fX3diaW5kZ2VuX21hbGxvYywgd2FzbS5fX3diaW5kZ2VuX3JlYWxsb2MpO1xuICAgIGNvbnN0IGxlbjAgPSBXQVNNX1ZFQ1RPUl9MRU47XG4gICAgY29uc3QgcHRyMSA9IHBhc3NTdHJpbmdUb1dhc20wKG1vZGlmaWVkLCB3YXNtLl9fd2JpbmRnZW5fbWFsbG9jLCB3YXNtLl9fd2JpbmRnZW5fcmVhbGxvYyk7XG4gICAgY29uc3QgbGVuMSA9IFdBU01fVkVDVE9SX0xFTjtcbiAgICBjb25zdCByZXQgPSB3YXNtLmNvbXB1dGVEaWZmKHB0cjAsIGxlbjAsIHB0cjEsIGxlbjEsIG9wdGlvbnMpO1xuICAgIGlmIChyZXRbMl0pIHtcbiAgICAgICAgdGhyb3cgdGFrZUZyb21FeHRlcm5yZWZUYWJsZTAocmV0WzFdKTtcbiAgICB9XG4gICAgcmV0dXJuIHRha2VGcm9tRXh0ZXJucmVmVGFibGUwKHJldFswXSk7XG59XG5cbi8qKlxuICogQ29tcHV0ZSBhIGRpZmYgYmV0d2VlbiB0d28gYXJyYXlzIG9mIGxpbmVzLlxuICpcbiAqICMgQXJndW1lbnRzXG4gKiAqIGBvcmlnaW5hbF9saW5lc2AgLSBUaGUgb3JpZ2luYWwgbGluZXMgKGFzIGEgSmF2YVNjcmlwdCBhcnJheSBvZiBzdHJpbmdzKVxuICogKiBgbW9kaWZpZWRfbGluZXNgIC0gVGhlIG1vZGlmaWVkIGxpbmVzIChhcyBhIEphdmFTY3JpcHQgYXJyYXkgb2Ygc3RyaW5ncylcbiAqICogYG9wdGlvbnNgIC0gT3B0aW9uYWwgZGlmZiBvcHRpb25zIChhcyBhIEphdmFTY3JpcHQgb2JqZWN0KVxuICpcbiAqICMgUmV0dXJuc1xuICogQSBgV2FzbUxpbmVzRGlmZmAgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGNoYW5nZXMuXG4gKiBAcGFyYW0ge2FueX0gb3JpZ2luYWxfbGluZXNcbiAqIEBwYXJhbSB7YW55fSBtb2RpZmllZF9saW5lc1xuICogQHBhcmFtIHthbnl9IG9wdGlvbnNcbiAqIEByZXR1cm5zIHthbnl9XG4gKi9cbmZ1bmN0aW9uIGNvbXB1dGVEaWZmTGluZXMob3JpZ2luYWxfbGluZXMsIG1vZGlmaWVkX2xpbmVzLCBvcHRpb25zKSB7XG4gICAgY29uc3QgcmV0ID0gd2FzbS5jb21wdXRlRGlmZkxpbmVzKG9yaWdpbmFsX2xpbmVzLCBtb2RpZmllZF9saW5lcywgb3B0aW9ucyk7XG4gICAgaWYgKHJldFsyXSkge1xuICAgICAgICB0aHJvdyB0YWtlRnJvbUV4dGVybnJlZlRhYmxlMChyZXRbMV0pO1xuICAgIH1cbiAgICByZXR1cm4gdGFrZUZyb21FeHRlcm5yZWZUYWJsZTAocmV0WzBdKTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIHBhbmljIGhvb2sgZm9yIGJldHRlciBlcnJvciBtZXNzYWdlcyBpbiB0aGUgYnJvd3NlciBjb25zb2xlLlxuICovXG5mdW5jdGlvbiBpbml0KCkge1xuICAgIHdhc20uaW5pdCgpO1xufVxuZnVuY3Rpb24gX193YmdfZ2V0X2ltcG9ydHMoKSB7XG4gICAgY29uc3QgaW1wb3J0MCA9IHtcbiAgICAgICAgX19wcm90b19fOiBudWxsLFxuICAgICAgICBfX3diZ19FcnJvcl9lZjUzYmMzMTBlYjI5OGEwOiBmdW5jdGlvbihhcmcwLCBhcmcxKSB7XG4gICAgICAgICAgICBjb25zdCByZXQgPSBFcnJvcihnZXRTdHJpbmdGcm9tV2FzbTAoYXJnMCwgYXJnMSkpO1xuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmdfTnVtYmVyXzZiNTA2ZTY1MzY4MzFlYWE6IGZ1bmN0aW9uKGFyZzApIHtcbiAgICAgICAgICAgIGNvbnN0IHJldCA9IE51bWJlcihhcmcwKTtcbiAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH0sXG4gICAgICAgIF9fd2JnX1N0cmluZ184NTY0ZTU1OTc5OWVjY2RhOiBmdW5jdGlvbihhcmcwLCBhcmcxKSB7XG4gICAgICAgICAgICBjb25zdCByZXQgPSBTdHJpbmcoYXJnMSk7XG4gICAgICAgICAgICBjb25zdCBwdHIxID0gcGFzc1N0cmluZ1RvV2FzbTAocmV0LCB3YXNtLl9fd2JpbmRnZW5fbWFsbG9jLCB3YXNtLl9fd2JpbmRnZW5fcmVhbGxvYyk7XG4gICAgICAgICAgICBjb25zdCBsZW4xID0gV0FTTV9WRUNUT1JfTEVOO1xuICAgICAgICAgICAgZ2V0RGF0YVZpZXdNZW1vcnkwKCkuc2V0SW50MzIoYXJnMCArIDQgKiAxLCBsZW4xLCB0cnVlKTtcbiAgICAgICAgICAgIGdldERhdGFWaWV3TWVtb3J5MCgpLnNldEludDMyKGFyZzAgKyA0ICogMCwgcHRyMSwgdHJ1ZSk7XG4gICAgICAgIH0sXG4gICAgICAgIF9fd2JnX19fd2JpbmRnZW5fYmlnaW50X2dldF9hc19pNjRfMzgxMzBlOThlZWNkNDY3ZDogZnVuY3Rpb24oYXJnMCwgYXJnMSkge1xuICAgICAgICAgICAgY29uc3QgdiA9IGFyZzE7XG4gICAgICAgICAgICBjb25zdCByZXQgPSB0eXBlb2YodikgPT09ICdiaWdpbnQnID8gdiA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGdldERhdGFWaWV3TWVtb3J5MCgpLnNldEJpZ0ludDY0KGFyZzAgKyA4ICogMSwgaXNMaWtlTm9uZShyZXQpID8gQmlnSW50KDApIDogcmV0LCB0cnVlKTtcbiAgICAgICAgICAgIGdldERhdGFWaWV3TWVtb3J5MCgpLnNldEludDMyKGFyZzAgKyA0ICogMCwgIWlzTGlrZU5vbmUocmV0KSwgdHJ1ZSk7XG4gICAgICAgIH0sXG4gICAgICAgIF9fd2JnX19fd2JpbmRnZW5fYm9vbGVhbl9nZXRfMWE0NWUyYzM4ZDRkNDFiOTogZnVuY3Rpb24oYXJnMCkge1xuICAgICAgICAgICAgY29uc3QgdiA9IGFyZzA7XG4gICAgICAgICAgICBjb25zdCByZXQgPSB0eXBlb2YodikgPT09ICdib29sZWFuJyA/IHYgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICByZXR1cm4gaXNMaWtlTm9uZShyZXQpID8gMHhGRkZGRkYgOiByZXQgPyAxIDogMDtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmdfX193YmluZGdlbl9kZWJ1Z19zdHJpbmdfMGFjY2Q4MGY0NWU1ZmFhMjogZnVuY3Rpb24oYXJnMCwgYXJnMSkge1xuICAgICAgICAgICAgY29uc3QgcmV0ID0gZGVidWdTdHJpbmcoYXJnMSk7XG4gICAgICAgICAgICBjb25zdCBwdHIxID0gcGFzc1N0cmluZ1RvV2FzbTAocmV0LCB3YXNtLl9fd2JpbmRnZW5fbWFsbG9jLCB3YXNtLl9fd2JpbmRnZW5fcmVhbGxvYyk7XG4gICAgICAgICAgICBjb25zdCBsZW4xID0gV0FTTV9WRUNUT1JfTEVOO1xuICAgICAgICAgICAgZ2V0RGF0YVZpZXdNZW1vcnkwKCkuc2V0SW50MzIoYXJnMCArIDQgKiAxLCBsZW4xLCB0cnVlKTtcbiAgICAgICAgICAgIGdldERhdGFWaWV3TWVtb3J5MCgpLnNldEludDMyKGFyZzAgKyA0ICogMCwgcHRyMSwgdHJ1ZSk7XG4gICAgICAgIH0sXG4gICAgICAgIF9fd2JnX19fd2JpbmRnZW5faW5fNzBhNDAzYTU2ZTc3MTcwNDogZnVuY3Rpb24oYXJnMCwgYXJnMSkge1xuICAgICAgICAgICAgY29uc3QgcmV0ID0gYXJnMCBpbiBhcmcxO1xuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmdfX193YmluZGdlbl9pc19iaWdpbnRfNmZmZDY0NjhhOWJjNDRiOTogZnVuY3Rpb24oYXJnMCkge1xuICAgICAgICAgICAgY29uc3QgcmV0ID0gdHlwZW9mKGFyZzApID09PSAnYmlnaW50JztcbiAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH0sXG4gICAgICAgIF9fd2JnX19fd2JpbmRnZW5faXNfZnVuY3Rpb25fNzU0ZTlmMzA1ZmY2MDI5ZTogZnVuY3Rpb24oYXJnMCkge1xuICAgICAgICAgICAgY29uc3QgcmV0ID0gdHlwZW9mKGFyZzApID09PSAnZnVuY3Rpb24nO1xuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmdfX193YmluZGdlbl9pc19udWxsXzg3YzNiZmU5NjhjNmE1YWQ6IGZ1bmN0aW9uKGFyZzApIHtcbiAgICAgICAgICAgIGNvbnN0IHJldCA9IGFyZzAgPT09IG51bGw7XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9LFxuICAgICAgICBfX3diZ19fX3diaW5kZ2VuX2lzX29iamVjdF81NjczMmMyYmMzNTNmNDFkOiBmdW5jdGlvbihhcmcwKSB7XG4gICAgICAgICAgICBjb25zdCB2YWwgPSBhcmcwO1xuICAgICAgICAgICAgY29uc3QgcmV0ID0gdHlwZW9mKHZhbCkgPT09ICdvYmplY3QnICYmIHZhbCAhPT0gbnVsbDtcbiAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH0sXG4gICAgICAgIF9fd2JnX19fd2JpbmRnZW5faXNfdW5kZWZpbmVkXzY3YjQ1NmJlODY3M2QzZDc6IGZ1bmN0aW9uKGFyZzApIHtcbiAgICAgICAgICAgIGNvbnN0IHJldCA9IGFyZzAgPT09IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH0sXG4gICAgICAgIF9fd2JnX19fd2JpbmRnZW5fanN2YWxfZXFfMTA2OGU2MjRmYTg3ZjZhYjogZnVuY3Rpb24oYXJnMCwgYXJnMSkge1xuICAgICAgICAgICAgY29uc3QgcmV0ID0gYXJnMCA9PT0gYXJnMTtcbiAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH0sXG4gICAgICAgIF9fd2JnX19fd2JpbmRnZW5fanN2YWxfbG9vc2VfZXFfMmM1NjU2NGM3NTEyOTUxMTogZnVuY3Rpb24oYXJnMCwgYXJnMSkge1xuICAgICAgICAgICAgY29uc3QgcmV0ID0gYXJnMCA9PSBhcmcxO1xuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmdfX193YmluZGdlbl9udW1iZXJfZ2V0XzliYjE3NjExMjIxODFhZjI6IGZ1bmN0aW9uKGFyZzAsIGFyZzEpIHtcbiAgICAgICAgICAgIGNvbnN0IG9iaiA9IGFyZzE7XG4gICAgICAgICAgICBjb25zdCByZXQgPSB0eXBlb2Yob2JqKSA9PT0gJ251bWJlcicgPyBvYmogOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICBnZXREYXRhVmlld01lbW9yeTAoKS5zZXRGbG9hdDY0KGFyZzAgKyA4ICogMSwgaXNMaWtlTm9uZShyZXQpID8gMCA6IHJldCwgdHJ1ZSk7XG4gICAgICAgICAgICBnZXREYXRhVmlld01lbW9yeTAoKS5zZXRJbnQzMihhcmcwICsgNCAqIDAsICFpc0xpa2VOb25lKHJldCksIHRydWUpO1xuICAgICAgICB9LFxuICAgICAgICBfX3diZ19fX3diaW5kZ2VuX3N0cmluZ19nZXRfNzJiZGY5NWQzYWU1MDViMTogZnVuY3Rpb24oYXJnMCwgYXJnMSkge1xuICAgICAgICAgICAgY29uc3Qgb2JqID0gYXJnMTtcbiAgICAgICAgICAgIGNvbnN0IHJldCA9IHR5cGVvZihvYmopID09PSAnc3RyaW5nJyA/IG9iaiA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHZhciBwdHIxID0gaXNMaWtlTm9uZShyZXQpID8gMCA6IHBhc3NTdHJpbmdUb1dhc20wKHJldCwgd2FzbS5fX3diaW5kZ2VuX21hbGxvYywgd2FzbS5fX3diaW5kZ2VuX3JlYWxsb2MpO1xuICAgICAgICAgICAgdmFyIGxlbjEgPSBXQVNNX1ZFQ1RPUl9MRU47XG4gICAgICAgICAgICBnZXREYXRhVmlld01lbW9yeTAoKS5zZXRJbnQzMihhcmcwICsgNCAqIDEsIGxlbjEsIHRydWUpO1xuICAgICAgICAgICAgZ2V0RGF0YVZpZXdNZW1vcnkwKCkuc2V0SW50MzIoYXJnMCArIDQgKiAwLCBwdHIxLCB0cnVlKTtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmdfX193YmluZGdlbl90aHJvd18xNTA2ZjIyMzVkMWJkYmEwOiBmdW5jdGlvbihhcmcwLCBhcmcxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZ2V0U3RyaW5nRnJvbVdhc20wKGFyZzAsIGFyZzEpKTtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmdfY2FsbF84YTg5NjA5ZDg5ZjY2MDhhOiBmdW5jdGlvbigpIHsgcmV0dXJuIGhhbmRsZUVycm9yKGZ1bmN0aW9uIChhcmcwLCBhcmcxKSB7XG4gICAgICAgICAgICBjb25zdCByZXQgPSBhcmcwLmNhbGwoYXJnMSk7XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9LCBhcmd1bWVudHMpOyB9LFxuICAgICAgICBfX3diZ19kb25lXzYwY2YzMDdmY2M2ODA1MzY6IGZ1bmN0aW9uKGFyZzApIHtcbiAgICAgICAgICAgIGNvbnN0IHJldCA9IGFyZzAuZG9uZTtcbiAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH0sXG4gICAgICAgIF9fd2JnX2Vycm9yX2E2ZmEyMDJiNThhYTFjZDM6IGZ1bmN0aW9uKGFyZzAsIGFyZzEpIHtcbiAgICAgICAgICAgIGxldCBkZWZlcnJlZDBfMDtcbiAgICAgICAgICAgIGxldCBkZWZlcnJlZDBfMTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgZGVmZXJyZWQwXzAgPSBhcmcwO1xuICAgICAgICAgICAgICAgIGRlZmVycmVkMF8xID0gYXJnMTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGdldFN0cmluZ0Zyb21XYXNtMChhcmcwLCBhcmcxKSk7XG4gICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHdhc20uX193YmluZGdlbl9mcmVlKGRlZmVycmVkMF8wLCBkZWZlcnJlZDBfMSwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIF9fd2JnX2dldF8xZjhmMDU0ZGRiYWE3ZGIyOiBmdW5jdGlvbigpIHsgcmV0dXJuIGhhbmRsZUVycm9yKGZ1bmN0aW9uIChhcmcwLCBhcmcxKSB7XG4gICAgICAgICAgICBjb25zdCByZXQgPSBSZWZsZWN0LmdldChhcmcwLCBhcmcxKTtcbiAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH0sIGFyZ3VtZW50cyk7IH0sXG4gICAgICAgIF9fd2JnX2dldF91bmNoZWNrZWRfMzNmNmU1YzllMmYyZDZiMjogZnVuY3Rpb24oYXJnMCwgYXJnMSkge1xuICAgICAgICAgICAgY29uc3QgcmV0ID0gYXJnMFthcmcxID4+PiAwXTtcbiAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH0sXG4gICAgICAgIF9fd2JnX2dldF93aXRoX3JlZl9rZXlfNjQxMmNmMzA5NDU5OTY5NDogZnVuY3Rpb24oYXJnMCwgYXJnMSkge1xuICAgICAgICAgICAgY29uc3QgcmV0ID0gYXJnMFthcmcxXTtcbiAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH0sXG4gICAgICAgIF9fd2JnX2luc3RhbmNlb2ZfQXJyYXlCdWZmZXJfOGY0OTgxMTQ2Nzc0MTQ5OTogZnVuY3Rpb24oYXJnMCkge1xuICAgICAgICAgICAgbGV0IHJlc3VsdDtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gYXJnMCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyO1xuICAgICAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcmV0ID0gcmVzdWx0O1xuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmdfaW5zdGFuY2VvZl9VaW50OEFycmF5Xzg2ZjMwNjQ5ZjYzZWY5YzI6IGZ1bmN0aW9uKGFyZzApIHtcbiAgICAgICAgICAgIGxldCByZXN1bHQ7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGFyZzAgaW5zdGFuY2VvZiBVaW50OEFycmF5O1xuICAgICAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcmV0ID0gcmVzdWx0O1xuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmdfaXNBcnJheV82N2MyYzljNDMxM2Y0NDQ4OiBmdW5jdGlvbihhcmcwKSB7XG4gICAgICAgICAgICBjb25zdCByZXQgPSBBcnJheS5pc0FycmF5KGFyZzApO1xuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmdfaXNTYWZlSW50ZWdlcl82NmFjZWMyN2UwOWU5OWE3OiBmdW5jdGlvbihhcmcwKSB7XG4gICAgICAgICAgICBjb25zdCByZXQgPSBOdW1iZXIuaXNTYWZlSW50ZWdlcihhcmcwKTtcbiAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH0sXG4gICAgICAgIF9fd2JnX2l0ZXJhdG9yXzg3MzI0MjhkMzA5ZTI3MGU6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgcmV0ID0gU3ltYm9sLml0ZXJhdG9yO1xuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmdfbGVuZ3RoXzRhNTkxZWNhYTAxMzU0ZDk6IGZ1bmN0aW9uKGFyZzApIHtcbiAgICAgICAgICAgIGNvbnN0IHJldCA9IGFyZzAubGVuZ3RoO1xuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmdfbGVuZ3RoXzY2ZjFhNGIyZTkwMjY5NDA6IGZ1bmN0aW9uKGFyZzApIHtcbiAgICAgICAgICAgIGNvbnN0IHJldCA9IGFyZzAubGVuZ3RoO1xuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmdfbmV3XzIyN2Q3YzA1NDE0ZWI4NjE6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgcmV0ID0gbmV3IEVycm9yKCk7XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9LFxuICAgICAgICBfX3diZ19uZXdfNTc4YWVlZjRiNmI5NDM3ODogZnVuY3Rpb24oYXJnMCkge1xuICAgICAgICAgICAgY29uc3QgcmV0ID0gbmV3IFVpbnQ4QXJyYXkoYXJnMCk7XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9LFxuICAgICAgICBfX3diZ19uZXdfY2UxYWI2MWMxYzJiMzAwZDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCByZXQgPSBuZXcgT2JqZWN0KCk7XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9LFxuICAgICAgICBfX3diZ19uZXdfZDkwMDkxYjgyZmRmNWI5MTogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCByZXQgPSBuZXcgQXJyYXkoKTtcbiAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH0sXG4gICAgICAgIF9fd2JnX25leHRfOWUwM2FjZGY1MWM0OTYwZDogZnVuY3Rpb24oYXJnMCkge1xuICAgICAgICAgICAgY29uc3QgcmV0ID0gYXJnMC5uZXh0O1xuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmdfbmV4dF9lYjhjYTczNTFmYTI3OTA2OiBmdW5jdGlvbigpIHsgcmV0dXJuIGhhbmRsZUVycm9yKGZ1bmN0aW9uIChhcmcwKSB7XG4gICAgICAgICAgICBjb25zdCByZXQgPSBhcmcwLm5leHQoKTtcbiAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH0sIGFyZ3VtZW50cyk7IH0sXG4gICAgICAgIF9fd2JnX3Byb3RvdHlwZXNldGNhbGxfMzI0OWZjNjJhMGZhZmEzMDogZnVuY3Rpb24oYXJnMCwgYXJnMSwgYXJnMikge1xuICAgICAgICAgICAgVWludDhBcnJheS5wcm90b3R5cGUuc2V0LmNhbGwoZ2V0QXJyYXlVOEZyb21XYXNtMChhcmcwLCBhcmcxKSwgYXJnMik7XG4gICAgICAgIH0sXG4gICAgICAgIF9fd2JnX3NldF82YmU0Mjc2OGM2OTBlMzgwOiBmdW5jdGlvbihhcmcwLCBhcmcxLCBhcmcyKSB7XG4gICAgICAgICAgICBhcmcwW2FyZzFdID0gYXJnMjtcbiAgICAgICAgfSxcbiAgICAgICAgX193Ymdfc2V0X2RjYTk5OTk5YmJhODhhOWE6IGZ1bmN0aW9uKGFyZzAsIGFyZzEsIGFyZzIpIHtcbiAgICAgICAgICAgIGFyZzBbYXJnMSA+Pj4gMF0gPSBhcmcyO1xuICAgICAgICB9LFxuICAgICAgICBfX3diZ19zdGFja18zYjBkOTc0YmJmMzFlNDRmOiBmdW5jdGlvbihhcmcwLCBhcmcxKSB7XG4gICAgICAgICAgICBjb25zdCByZXQgPSBhcmcxLnN0YWNrO1xuICAgICAgICAgICAgY29uc3QgcHRyMSA9IHBhc3NTdHJpbmdUb1dhc20wKHJldCwgd2FzbS5fX3diaW5kZ2VuX21hbGxvYywgd2FzbS5fX3diaW5kZ2VuX3JlYWxsb2MpO1xuICAgICAgICAgICAgY29uc3QgbGVuMSA9IFdBU01fVkVDVE9SX0xFTjtcbiAgICAgICAgICAgIGdldERhdGFWaWV3TWVtb3J5MCgpLnNldEludDMyKGFyZzAgKyA0ICogMSwgbGVuMSwgdHJ1ZSk7XG4gICAgICAgICAgICBnZXREYXRhVmlld01lbW9yeTAoKS5zZXRJbnQzMihhcmcwICsgNCAqIDAsIHB0cjEsIHRydWUpO1xuICAgICAgICB9LFxuICAgICAgICBfX3diZ192YWx1ZV9mMzYyNTA5MmVlNGIzN2Y0OiBmdW5jdGlvbihhcmcwKSB7XG4gICAgICAgICAgICBjb25zdCByZXQgPSBhcmcwLnZhbHVlO1xuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmluZGdlbl9jYXN0XzAwMDAwMDAwMDAwMDAwMDE6IGZ1bmN0aW9uKGFyZzApIHtcbiAgICAgICAgICAgIC8vIENhc3QgaW50cmluc2ljIGZvciBgRjY0IC0+IEV4dGVybnJlZmAuXG4gICAgICAgICAgICBjb25zdCByZXQgPSBhcmcwO1xuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmluZGdlbl9jYXN0XzAwMDAwMDAwMDAwMDAwMDI6IGZ1bmN0aW9uKGFyZzAsIGFyZzEpIHtcbiAgICAgICAgICAgIC8vIENhc3QgaW50cmluc2ljIGZvciBgUmVmKFN0cmluZykgLT4gRXh0ZXJucmVmYC5cbiAgICAgICAgICAgIGNvbnN0IHJldCA9IGdldFN0cmluZ0Zyb21XYXNtMChhcmcwLCBhcmcxKTtcbiAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH0sXG4gICAgICAgIF9fd2JpbmRnZW5fY2FzdF8wMDAwMDAwMDAwMDAwMDAzOiBmdW5jdGlvbihhcmcwKSB7XG4gICAgICAgICAgICAvLyBDYXN0IGludHJpbnNpYyBmb3IgYFU2NCAtPiBFeHRlcm5yZWZgLlxuICAgICAgICAgICAgY29uc3QgcmV0ID0gQmlnSW50LmFzVWludE4oNjQsIGFyZzApO1xuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfSxcbiAgICAgICAgX193YmluZGdlbl9pbml0X2V4dGVybnJlZl90YWJsZTogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCB0YWJsZSA9IHdhc20uX193YmluZGdlbl9leHRlcm5yZWZzO1xuICAgICAgICAgICAgY29uc3Qgb2Zmc2V0ID0gdGFibGUuZ3Jvdyg0KTtcbiAgICAgICAgICAgIHRhYmxlLnNldCgwLCB1bmRlZmluZWQpO1xuICAgICAgICAgICAgdGFibGUuc2V0KG9mZnNldCArIDAsIHVuZGVmaW5lZCk7XG4gICAgICAgICAgICB0YWJsZS5zZXQob2Zmc2V0ICsgMSwgbnVsbCk7XG4gICAgICAgICAgICB0YWJsZS5zZXQob2Zmc2V0ICsgMiwgdHJ1ZSk7XG4gICAgICAgICAgICB0YWJsZS5zZXQob2Zmc2V0ICsgMywgZmFsc2UpO1xuICAgICAgICB9LFxuICAgIH07XG4gICAgcmV0dXJuIHtcbiAgICAgICAgX19wcm90b19fOiBudWxsLFxuICAgICAgICBcIi4vZGlmZl93YXNtX2JnLmpzXCI6IGltcG9ydDAsXG4gICAgfTtcbn1cblxuZnVuY3Rpb24gYWRkVG9FeHRlcm5yZWZUYWJsZTAob2JqKSB7XG4gICAgY29uc3QgaWR4ID0gd2FzbS5fX2V4dGVybnJlZl90YWJsZV9hbGxvYygpO1xuICAgIHdhc20uX193YmluZGdlbl9leHRlcm5yZWZzLnNldChpZHgsIG9iaik7XG4gICAgcmV0dXJuIGlkeDtcbn1cblxuZnVuY3Rpb24gZGVidWdTdHJpbmcodmFsKSB7XG4gICAgLy8gcHJpbWl0aXZlIHR5cGVzXG4gICAgY29uc3QgdHlwZSA9IHR5cGVvZiB2YWw7XG4gICAgaWYgKHR5cGUgPT0gJ251bWJlcicgfHwgdHlwZSA9PSAnYm9vbGVhbicgfHwgdmFsID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuICBgJHt2YWx9YDtcbiAgICB9XG4gICAgaWYgKHR5cGUgPT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIGBcIiR7dmFsfVwiYDtcbiAgICB9XG4gICAgaWYgKHR5cGUgPT0gJ3N5bWJvbCcpIHtcbiAgICAgICAgY29uc3QgZGVzY3JpcHRpb24gPSB2YWwuZGVzY3JpcHRpb247XG4gICAgICAgIGlmIChkZXNjcmlwdGlvbiA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gJ1N5bWJvbCc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gYFN5bWJvbCgke2Rlc2NyaXB0aW9ufSlgO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgY29uc3QgbmFtZSA9IHZhbC5uYW1lO1xuICAgICAgICBpZiAodHlwZW9mIG5hbWUgPT0gJ3N0cmluZycgJiYgbmFtZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICByZXR1cm4gYEZ1bmN0aW9uKCR7bmFtZX0pYDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAnRnVuY3Rpb24nO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIG9iamVjdHNcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IHZhbC5sZW5ndGg7XG4gICAgICAgIGxldCBkZWJ1ZyA9ICdbJztcbiAgICAgICAgaWYgKGxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGRlYnVnICs9IGRlYnVnU3RyaW5nKHZhbFswXSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yKGxldCBpID0gMTsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBkZWJ1ZyArPSAnLCAnICsgZGVidWdTdHJpbmcodmFsW2ldKTtcbiAgICAgICAgfVxuICAgICAgICBkZWJ1ZyArPSAnXSc7XG4gICAgICAgIHJldHVybiBkZWJ1ZztcbiAgICB9XG4gICAgLy8gVGVzdCBmb3IgYnVpbHQtaW5cbiAgICBjb25zdCBidWlsdEluTWF0Y2hlcyA9IC9cXFtvYmplY3QgKFteXFxdXSspXFxdLy5leGVjKHRvU3RyaW5nLmNhbGwodmFsKSk7XG4gICAgbGV0IGNsYXNzTmFtZTtcbiAgICBpZiAoYnVpbHRJbk1hdGNoZXMgJiYgYnVpbHRJbk1hdGNoZXMubGVuZ3RoID4gMSkge1xuICAgICAgICBjbGFzc05hbWUgPSBidWlsdEluTWF0Y2hlc1sxXTtcbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBGYWlsZWQgdG8gbWF0Y2ggdGhlIHN0YW5kYXJkICdbb2JqZWN0IENsYXNzTmFtZV0nXG4gICAgICAgIHJldHVybiB0b1N0cmluZy5jYWxsKHZhbCk7XG4gICAgfVxuICAgIGlmIChjbGFzc05hbWUgPT0gJ09iamVjdCcpIHtcbiAgICAgICAgLy8gd2UncmUgYSB1c2VyIGRlZmluZWQgY2xhc3Mgb3IgT2JqZWN0XG4gICAgICAgIC8vIEpTT04uc3RyaW5naWZ5IGF2b2lkcyBwcm9ibGVtcyB3aXRoIGN5Y2xlcywgYW5kIGlzIGdlbmVyYWxseSBtdWNoXG4gICAgICAgIC8vIGVhc2llciB0aGFuIGxvb3BpbmcgdGhyb3VnaCBvd25Qcm9wZXJ0aWVzIG9mIGB2YWxgLlxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuICdPYmplY3QoJyArIEpTT04uc3RyaW5naWZ5KHZhbCkgKyAnKSc7XG4gICAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgICAgIHJldHVybiAnT2JqZWN0JztcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBlcnJvcnNcbiAgICBpZiAodmFsIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIGAke3ZhbC5uYW1lfTogJHt2YWwubWVzc2FnZX1cXG4ke3ZhbC5zdGFja31gO1xuICAgIH1cbiAgICAvLyBUT0RPIHdlIGNvdWxkIHRlc3QgZm9yIG1vcmUgdGhpbmdzIGhlcmUsIGxpa2UgYFNldGBzIGFuZCBgTWFwYHMuXG4gICAgcmV0dXJuIGNsYXNzTmFtZTtcbn1cblxuZnVuY3Rpb24gZ2V0QXJyYXlVOEZyb21XYXNtMChwdHIsIGxlbikge1xuICAgIHB0ciA9IHB0ciA+Pj4gMDtcbiAgICByZXR1cm4gZ2V0VWludDhBcnJheU1lbW9yeTAoKS5zdWJhcnJheShwdHIgLyAxLCBwdHIgLyAxICsgbGVuKTtcbn1cblxubGV0IGNhY2hlZERhdGFWaWV3TWVtb3J5MCA9IG51bGw7XG5mdW5jdGlvbiBnZXREYXRhVmlld01lbW9yeTAoKSB7XG4gICAgaWYgKGNhY2hlZERhdGFWaWV3TWVtb3J5MCA9PT0gbnVsbCB8fCBjYWNoZWREYXRhVmlld01lbW9yeTAuYnVmZmVyLmRldGFjaGVkID09PSB0cnVlIHx8IChjYWNoZWREYXRhVmlld01lbW9yeTAuYnVmZmVyLmRldGFjaGVkID09PSB1bmRlZmluZWQgJiYgY2FjaGVkRGF0YVZpZXdNZW1vcnkwLmJ1ZmZlciAhPT0gd2FzbS5tZW1vcnkuYnVmZmVyKSkge1xuICAgICAgICBjYWNoZWREYXRhVmlld01lbW9yeTAgPSBuZXcgRGF0YVZpZXcod2FzbS5tZW1vcnkuYnVmZmVyKTtcbiAgICB9XG4gICAgcmV0dXJuIGNhY2hlZERhdGFWaWV3TWVtb3J5MDtcbn1cblxuZnVuY3Rpb24gZ2V0U3RyaW5nRnJvbVdhc20wKHB0ciwgbGVuKSB7XG4gICAgcmV0dXJuIGRlY29kZVRleHQocHRyID4+PiAwLCBsZW4pO1xufVxuXG5sZXQgY2FjaGVkVWludDhBcnJheU1lbW9yeTAgPSBudWxsO1xuZnVuY3Rpb24gZ2V0VWludDhBcnJheU1lbW9yeTAoKSB7XG4gICAgaWYgKGNhY2hlZFVpbnQ4QXJyYXlNZW1vcnkwID09PSBudWxsIHx8IGNhY2hlZFVpbnQ4QXJyYXlNZW1vcnkwLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgY2FjaGVkVWludDhBcnJheU1lbW9yeTAgPSBuZXcgVWludDhBcnJheSh3YXNtLm1lbW9yeS5idWZmZXIpO1xuICAgIH1cbiAgICByZXR1cm4gY2FjaGVkVWludDhBcnJheU1lbW9yeTA7XG59XG5cbmZ1bmN0aW9uIGhhbmRsZUVycm9yKGYsIGFyZ3MpIHtcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gZi5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnN0IGlkeCA9IGFkZFRvRXh0ZXJucmVmVGFibGUwKGUpO1xuICAgICAgICB3YXNtLl9fd2JpbmRnZW5fZXhuX3N0b3JlKGlkeCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc0xpa2VOb25lKHgpIHtcbiAgICByZXR1cm4geCA9PT0gdW5kZWZpbmVkIHx8IHggPT09IG51bGw7XG59XG5cbmZ1bmN0aW9uIHBhc3NTdHJpbmdUb1dhc20wKGFyZywgbWFsbG9jLCByZWFsbG9jKSB7XG4gICAgaWYgKHJlYWxsb2MgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCBidWYgPSBjYWNoZWRUZXh0RW5jb2Rlci5lbmNvZGUoYXJnKTtcbiAgICAgICAgY29uc3QgcHRyID0gbWFsbG9jKGJ1Zi5sZW5ndGgsIDEpID4+PiAwO1xuICAgICAgICBnZXRVaW50OEFycmF5TWVtb3J5MCgpLnN1YmFycmF5KHB0ciwgcHRyICsgYnVmLmxlbmd0aCkuc2V0KGJ1Zik7XG4gICAgICAgIFdBU01fVkVDVE9SX0xFTiA9IGJ1Zi5sZW5ndGg7XG4gICAgICAgIHJldHVybiBwdHI7XG4gICAgfVxuXG4gICAgbGV0IGxlbiA9IGFyZy5sZW5ndGg7XG4gICAgbGV0IHB0ciA9IG1hbGxvYyhsZW4sIDEpID4+PiAwO1xuXG4gICAgY29uc3QgbWVtID0gZ2V0VWludDhBcnJheU1lbW9yeTAoKTtcblxuICAgIGxldCBvZmZzZXQgPSAwO1xuXG4gICAgZm9yICg7IG9mZnNldCA8IGxlbjsgb2Zmc2V0KyspIHtcbiAgICAgICAgY29uc3QgY29kZSA9IGFyZy5jaGFyQ29kZUF0KG9mZnNldCk7XG4gICAgICAgIGlmIChjb2RlID4gMHg3RikgYnJlYWs7XG4gICAgICAgIG1lbVtwdHIgKyBvZmZzZXRdID0gY29kZTtcbiAgICB9XG4gICAgaWYgKG9mZnNldCAhPT0gbGVuKSB7XG4gICAgICAgIGlmIChvZmZzZXQgIT09IDApIHtcbiAgICAgICAgICAgIGFyZyA9IGFyZy5zbGljZShvZmZzZXQpO1xuICAgICAgICB9XG4gICAgICAgIHB0ciA9IHJlYWxsb2MocHRyLCBsZW4sIGxlbiA9IG9mZnNldCArIGFyZy5sZW5ndGggKiAzLCAxKSA+Pj4gMDtcbiAgICAgICAgY29uc3QgdmlldyA9IGdldFVpbnQ4QXJyYXlNZW1vcnkwKCkuc3ViYXJyYXkocHRyICsgb2Zmc2V0LCBwdHIgKyBsZW4pO1xuICAgICAgICBjb25zdCByZXQgPSBjYWNoZWRUZXh0RW5jb2Rlci5lbmNvZGVJbnRvKGFyZywgdmlldyk7XG5cbiAgICAgICAgb2Zmc2V0ICs9IHJldC53cml0dGVuO1xuICAgICAgICBwdHIgPSByZWFsbG9jKHB0ciwgbGVuLCBvZmZzZXQsIDEpID4+PiAwO1xuICAgIH1cblxuICAgIFdBU01fVkVDVE9SX0xFTiA9IG9mZnNldDtcbiAgICByZXR1cm4gcHRyO1xufVxuXG5mdW5jdGlvbiB0YWtlRnJvbUV4dGVybnJlZlRhYmxlMChpZHgpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHdhc20uX193YmluZGdlbl9leHRlcm5yZWZzLmdldChpZHgpO1xuICAgIHdhc20uX19leHRlcm5yZWZfdGFibGVfZGVhbGxvYyhpZHgpO1xuICAgIHJldHVybiB2YWx1ZTtcbn1cblxubGV0IGNhY2hlZFRleHREZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKCd1dGYtOCcsIHsgaWdub3JlQk9NOiB0cnVlLCBmYXRhbDogdHJ1ZSB9KTtcbmNhY2hlZFRleHREZWNvZGVyLmRlY29kZSgpO1xuY29uc3QgTUFYX1NBRkFSSV9ERUNPREVfQllURVMgPSAyMTQ2NDM1MDcyO1xubGV0IG51bUJ5dGVzRGVjb2RlZCA9IDA7XG5mdW5jdGlvbiBkZWNvZGVUZXh0KHB0ciwgbGVuKSB7XG4gICAgbnVtQnl0ZXNEZWNvZGVkICs9IGxlbjtcbiAgICBpZiAobnVtQnl0ZXNEZWNvZGVkID49IE1BWF9TQUZBUklfREVDT0RFX0JZVEVTKSB7XG4gICAgICAgIGNhY2hlZFRleHREZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKCd1dGYtOCcsIHsgaWdub3JlQk9NOiB0cnVlLCBmYXRhbDogdHJ1ZSB9KTtcbiAgICAgICAgY2FjaGVkVGV4dERlY29kZXIuZGVjb2RlKCk7XG4gICAgICAgIG51bUJ5dGVzRGVjb2RlZCA9IGxlbjtcbiAgICB9XG4gICAgcmV0dXJuIGNhY2hlZFRleHREZWNvZGVyLmRlY29kZShnZXRVaW50OEFycmF5TWVtb3J5MCgpLnN1YmFycmF5KHB0ciwgcHRyICsgbGVuKSk7XG59XG5cbmNvbnN0IGNhY2hlZFRleHRFbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7XG5cbmlmICghKCdlbmNvZGVJbnRvJyBpbiBjYWNoZWRUZXh0RW5jb2RlcikpIHtcbiAgICBjYWNoZWRUZXh0RW5jb2Rlci5lbmNvZGVJbnRvID0gZnVuY3Rpb24gKGFyZywgdmlldykge1xuICAgICAgICBjb25zdCBidWYgPSBjYWNoZWRUZXh0RW5jb2Rlci5lbmNvZGUoYXJnKTtcbiAgICAgICAgdmlldy5zZXQoYnVmKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlYWQ6IGFyZy5sZW5ndGgsXG4gICAgICAgICAgICB3cml0dGVuOiBidWYubGVuZ3RoXG4gICAgICAgIH07XG4gICAgfTtcbn1cblxubGV0IFdBU01fVkVDVE9SX0xFTiA9IDA7XG5cbmxldCB3YXNtO1xuZnVuY3Rpb24gX193YmdfZmluYWxpemVfaW5pdChpbnN0YW5jZSwgbW9kdWxlKSB7XG4gICAgd2FzbSA9IGluc3RhbmNlLmV4cG9ydHM7XG4gICAgY2FjaGVkRGF0YVZpZXdNZW1vcnkwID0gbnVsbDtcbiAgICBjYWNoZWRVaW50OEFycmF5TWVtb3J5MCA9IG51bGw7XG4gICAgd2FzbS5fX3diaW5kZ2VuX3N0YXJ0KCk7XG4gICAgcmV0dXJuIHdhc207XG59XG5cbmFzeW5jIGZ1bmN0aW9uIF9fd2JnX2xvYWQobW9kdWxlLCBpbXBvcnRzKSB7XG4gICAgaWYgKHR5cGVvZiBSZXNwb25zZSA9PT0gJ2Z1bmN0aW9uJyAmJiBtb2R1bGUgaW5zdGFuY2VvZiBSZXNwb25zZSkge1xuICAgICAgICBpZiAodHlwZW9mIFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlU3RyZWFtaW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhd2FpdCBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZVN0cmVhbWluZyhtb2R1bGUsIGltcG9ydHMpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbGlkUmVzcG9uc2UgPSBtb2R1bGUub2sgJiYgZXhwZWN0ZWRSZXNwb25zZVR5cGUobW9kdWxlLnR5cGUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHZhbGlkUmVzcG9uc2UgJiYgbW9kdWxlLmhlYWRlcnMuZ2V0KCdDb250ZW50LVR5cGUnKSAhPT0gJ2FwcGxpY2F0aW9uL3dhc20nKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcImBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZVN0cmVhbWluZ2AgZmFpbGVkIGJlY2F1c2UgeW91ciBzZXJ2ZXIgZG9lcyBub3Qgc2VydmUgV2FzbSB3aXRoIGBhcHBsaWNhdGlvbi93YXNtYCBNSU1FIHR5cGUuIEZhbGxpbmcgYmFjayB0byBgV2ViQXNzZW1ibHkuaW5zdGFudGlhdGVgIHdoaWNoIGlzIHNsb3dlci4gT3JpZ2luYWwgZXJyb3I6XFxuXCIsIGUpO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHsgdGhyb3cgZTsgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYnl0ZXMgPSBhd2FpdCBtb2R1bGUuYXJyYXlCdWZmZXIoKTtcbiAgICAgICAgcmV0dXJuIGF3YWl0IFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKGJ5dGVzLCBpbXBvcnRzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKG1vZHVsZSwgaW1wb3J0cyk7XG5cbiAgICAgICAgaWYgKGluc3RhbmNlIGluc3RhbmNlb2YgV2ViQXNzZW1ibHkuSW5zdGFuY2UpIHtcbiAgICAgICAgICAgIHJldHVybiB7IGluc3RhbmNlLCBtb2R1bGUgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGV4cGVjdGVkUmVzcG9uc2VUeXBlKHR5cGUpIHtcbiAgICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgICAgICBjYXNlICdiYXNpYyc6IGNhc2UgJ2NvcnMnOiBjYXNlICdkZWZhdWx0JzogcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gaW5pdFN5bmMobW9kdWxlKSB7XG4gICAgaWYgKHdhc20gIT09IHVuZGVmaW5lZCkgcmV0dXJuIHdhc207XG5cblxuICAgIGlmIChtb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKG1vZHVsZSkgPT09IE9iamVjdC5wcm90b3R5cGUpIHtcbiAgICAgICAgICAgICh7bW9kdWxlfSA9IG1vZHVsZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ3VzaW5nIGRlcHJlY2F0ZWQgcGFyYW1ldGVycyBmb3IgYGluaXRTeW5jKClgOyBwYXNzIGEgc2luZ2xlIG9iamVjdCBpbnN0ZWFkJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBpbXBvcnRzID0gX193YmdfZ2V0X2ltcG9ydHMoKTtcbiAgICBpZiAoIShtb2R1bGUgaW5zdGFuY2VvZiBXZWJBc3NlbWJseS5Nb2R1bGUpKSB7XG4gICAgICAgIG1vZHVsZSA9IG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUobW9kdWxlKTtcbiAgICB9XG4gICAgY29uc3QgaW5zdGFuY2UgPSBuZXcgV2ViQXNzZW1ibHkuSW5zdGFuY2UobW9kdWxlLCBpbXBvcnRzKTtcbiAgICByZXR1cm4gX193YmdfZmluYWxpemVfaW5pdChpbnN0YW5jZSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIF9fd2JnX2luaXQobW9kdWxlX29yX3BhdGgpIHtcbiAgICBpZiAod2FzbSAhPT0gdW5kZWZpbmVkKSByZXR1cm4gd2FzbTtcblxuXG4gICAgaWYgKG1vZHVsZV9vcl9wYXRoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihtb2R1bGVfb3JfcGF0aCkgPT09IE9iamVjdC5wcm90b3R5cGUpIHtcbiAgICAgICAgICAgICh7bW9kdWxlX29yX3BhdGh9ID0gbW9kdWxlX29yX3BhdGgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCd1c2luZyBkZXByZWNhdGVkIHBhcmFtZXRlcnMgZm9yIHRoZSBpbml0aWFsaXphdGlvbiBmdW5jdGlvbjsgcGFzcyBhIHNpbmdsZSBvYmplY3QgaW5zdGVhZCcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1vZHVsZV9vcl9wYXRoID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbW9kdWxlX29yX3BhdGggPSBuZXcgVVJMKG5ldyBVUkwoJ2RpZmZfd2FzbV9iZy1jNllrYVpSTC53YXNtJywgaW1wb3J0Lm1ldGEudXJsKS5ocmVmKTtcbiAgICB9XG4gICAgY29uc3QgaW1wb3J0cyA9IF9fd2JnX2dldF9pbXBvcnRzKCk7XG5cbiAgICBpZiAodHlwZW9mIG1vZHVsZV9vcl9wYXRoID09PSAnc3RyaW5nJyB8fCAodHlwZW9mIFJlcXVlc3QgPT09ICdmdW5jdGlvbicgJiYgbW9kdWxlX29yX3BhdGggaW5zdGFuY2VvZiBSZXF1ZXN0KSB8fCAodHlwZW9mIFVSTCA9PT0gJ2Z1bmN0aW9uJyAmJiBtb2R1bGVfb3JfcGF0aCBpbnN0YW5jZW9mIFVSTCkpIHtcbiAgICAgICAgbW9kdWxlX29yX3BhdGggPSBmZXRjaChtb2R1bGVfb3JfcGF0aCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBpbnN0YW5jZSwgbW9kdWxlIH0gPSBhd2FpdCBfX3diZ19sb2FkKGF3YWl0IG1vZHVsZV9vcl9wYXRoLCBpbXBvcnRzKTtcblxuICAgIHJldHVybiBfX3diZ19maW5hbGl6ZV9pbml0KGluc3RhbmNlKTtcbn1cblxudmFyIHdhc20kMSA9IC8qI19fUFVSRV9fKi9PYmplY3QuZnJlZXplKHtcbiAgICBfX3Byb3RvX186IG51bGwsXG4gICAgY29tcHV0ZURpZmY6IGNvbXB1dGVEaWZmLFxuICAgIGNvbXB1dGVEaWZmTGluZXM6IGNvbXB1dGVEaWZmTGluZXMsXG4gICAgZGVmYXVsdDogX193YmdfaW5pdCxcbiAgICBpbml0OiBpbml0LFxuICAgIGluaXRTeW5jOiBpbml0U3luY1xufSk7XG5cbi8qKlxuICogV0FTTSBtb2R1bGUgbG9hZGVyLlxuICpcbiAqIEhhbmRsZXMgYXN5bmMgaW5pdGlhbGl6YXRpb24gb2YgdGhlIFdBU00gbW9kdWxlLlxuICovXG4vLyBAdHMtaWdub3JlIC0tIGdlbmVyYXRlZCBhdCBidWlsZCB0aW1lIGJ5IGBucG0gcnVuIGJ1aWxkOndhc21gICh3YXNtLXBhY2sgLS10YXJnZXQgd2ViKS5cbmxldCB3YXNtTW9kdWxlID0gbnVsbDtcbmxldCBpbml0UHJvbWlzZSA9IG51bGw7XG4vKipcbiAqIEluaXRpYWxpemUgdGhlIFdBU00gbW9kdWxlLlxuICpcbiAqIFRoaXMgbXVzdCBiZSBjYWxsZWQgYmVmb3JlIHVzaW5nIGFueSBXQVNNLWJhc2VkIGRpZmYgZnVuY3Rpb25zLlxuICogSXQncyBzYWZlIHRvIGNhbGwgbXVsdGlwbGUgdGltZXMg4oCUIHN1YnNlcXVlbnQgY2FsbHMgYXJlIG5vLW9wcy5cbiAqXG4gKiBAcmV0dXJucyBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBXQVNNIGlzIHJlYWR5XG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGluaXRXYXNtKCkge1xuICAgIGlmICh3YXNtTW9kdWxlKSB7XG4gICAgICAgIHJldHVybiB3YXNtTW9kdWxlO1xuICAgIH1cbiAgICBpZiAoaW5pdFByb21pc2UpIHtcbiAgICAgICAgcmV0dXJuIGluaXRQcm9taXNlO1xuICAgIH1cbiAgICBpbml0UHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHdhc21VcmwgPSBuZXcgVVJMKG5ldyBVUkwoJ2RpZmZfd2FzbV9iZy1jNllrYVpSTC53YXNtJywgaW1wb3J0Lm1ldGEudXJsKS5ocmVmKTtcbiAgICAgICAgLy8gTm9kZSdzIHVuZGljaSBmZXRjaCBkb2VzIG5vdCBzdXBwb3J0IGZpbGU6Ly8gVVJMcywgc28gcmVhZCBieXRlcyBvdXJzZWx2ZXMuXG4gICAgICAgIGxldCBzb3VyY2UgPSB3YXNtVXJsO1xuICAgICAgICBpZiAodHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmIHByb2Nlc3MudmVyc2lvbnM/Lm5vZGUpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgcmVhZEZpbGUgfSA9IGF3YWl0IGltcG9ydCgnbm9kZTpmcy9wcm9taXNlcycpO1xuICAgICAgICAgICAgc291cmNlID0gYXdhaXQgcmVhZEZpbGUod2FzbVVybCk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgX193YmdfaW5pdCh7IG1vZHVsZV9vcl9wYXRoOiBzb3VyY2UgfSk7XG4gICAgICAgIGluaXQoKTtcbiAgICAgICAgd2FzbU1vZHVsZSA9IHdhc20kMTtcbiAgICAgICAgcmV0dXJuIHdhc21Nb2R1bGU7XG4gICAgfSkoKTtcbiAgICByZXR1cm4gaW5pdFByb21pc2U7XG59XG4vKipcbiAqIEdldCB0aGUgV0FTTSBtb2R1bGUgc3luY2hyb25vdXNseS5cbiAqXG4gKiBAdGhyb3dzIEVycm9yIGlmIFdBU00gaGFzbid0IGJlZW4gaW5pdGlhbGl6ZWQgeWV0XG4gKiBAcmV0dXJucyBUaGUgV0FTTSBtb2R1bGVcbiAqL1xuZnVuY3Rpb24gZ2V0V2FzbSgpIHtcbiAgICBpZiAoIXdhc21Nb2R1bGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdXQVNNIG5vdCBpbml0aWFsaXplZC4gQ2FsbCBpbml0V2FzbSgpIGZpcnN0IGFuZCBhd2FpdCBpdC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHdhc21Nb2R1bGU7XG59XG5cbi8qKlxuICogQ29udmVyc2lvbnMgYmV0d2VlbiBgTGluZXNEaWZmYCAoaW4tbWVtb3J5IGNsYXNzIGluc3RhbmNlcykgYW5kXG4gKiBgV2lyZUxpbmVzRGlmZmAgKHBsYWluIEpTT04tZnJpZW5kbHkgc2hhcGUgdXNlZCBvbiB0aGUgd29ya2VyIGJvdW5kYXJ5KS5cbiAqL1xuZnVuY3Rpb24gbGluZXNEaWZmVG9XaXJlKGRpZmYpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBjaGFuZ2VzOiBkaWZmLmNoYW5nZXMubWFwKGRldGFpbGVkVG9XaXJlKSxcbiAgICAgICAgbW92ZXM6IGRpZmYubW92ZXMubWFwKG1vdmVUb1dpcmUpLFxuICAgICAgICBoaXRUaW1lb3V0OiBkaWZmLmhpdFRpbWVvdXQsXG4gICAgfTtcbn1cbmZ1bmN0aW9uIHdpcmVUb0xpbmVzRGlmZih3aXJlKSB7XG4gICAgY29uc3QgY2hhbmdlcyA9IHdpcmUuY2hhbmdlcy5tYXAod2lyZVRvRGV0YWlsZWQpO1xuICAgIGNvbnN0IG1vdmVzID0gd2lyZS5tb3Zlcy5tYXAod2lyZVRvTW92ZSk7XG4gICAgcmV0dXJuIG5ldyBMaW5lc0RpZmYoY2hhbmdlcywgbW92ZXMsIHdpcmUuaGl0VGltZW91dCk7XG59XG5mdW5jdGlvbiBkZXRhaWxlZFRvV2lyZShtKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgb3JpZ2luYWw6IHtcbiAgICAgICAgICAgIHN0YXJ0TGluZU51bWJlcjogbS5vcmlnaW5hbC5zdGFydExpbmVOdW1iZXIsXG4gICAgICAgICAgICBlbmRMaW5lTnVtYmVyRXhjbHVzaXZlOiBtLm9yaWdpbmFsLmVuZExpbmVOdW1iZXJFeGNsdXNpdmUsXG4gICAgICAgIH0sXG4gICAgICAgIG1vZGlmaWVkOiB7XG4gICAgICAgICAgICBzdGFydExpbmVOdW1iZXI6IG0ubW9kaWZpZWQuc3RhcnRMaW5lTnVtYmVyLFxuICAgICAgICAgICAgZW5kTGluZU51bWJlckV4Y2x1c2l2ZTogbS5tb2RpZmllZC5lbmRMaW5lTnVtYmVyRXhjbHVzaXZlLFxuICAgICAgICB9LFxuICAgICAgICBpbm5lckNoYW5nZXM6IG0uaW5uZXJDaGFuZ2VzID8gbS5pbm5lckNoYW5nZXMubWFwKHJhbmdlTWFwcGluZ1RvV2lyZSkgOiBudWxsLFxuICAgIH07XG59XG5mdW5jdGlvbiB3aXJlVG9EZXRhaWxlZChtKSB7XG4gICAgY29uc3QgaW5uZXIgPSBtLmlubmVyQ2hhbmdlcz8ubWFwKHdpcmVUb1JhbmdlTWFwcGluZyk7XG4gICAgcmV0dXJuIG5ldyBEZXRhaWxlZExpbmVSYW5nZU1hcHBpbmcobmV3IExpbmVSYW5nZShtLm9yaWdpbmFsLnN0YXJ0TGluZU51bWJlciwgbS5vcmlnaW5hbC5lbmRMaW5lTnVtYmVyRXhjbHVzaXZlKSwgbmV3IExpbmVSYW5nZShtLm1vZGlmaWVkLnN0YXJ0TGluZU51bWJlciwgbS5tb2RpZmllZC5lbmRMaW5lTnVtYmVyRXhjbHVzaXZlKSwgaW5uZXIpO1xufVxuZnVuY3Rpb24gcmFuZ2VNYXBwaW5nVG9XaXJlKHJtKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgb3JpZ2luYWxTdGFydExpbmU6IHJtLm9yaWdpbmFsUmFuZ2Uuc3RhcnRMaW5lTnVtYmVyLFxuICAgICAgICBvcmlnaW5hbFN0YXJ0Q29sdW1uOiBybS5vcmlnaW5hbFJhbmdlLnN0YXJ0Q29sdW1uLFxuICAgICAgICBvcmlnaW5hbEVuZExpbmU6IHJtLm9yaWdpbmFsUmFuZ2UuZW5kTGluZU51bWJlcixcbiAgICAgICAgb3JpZ2luYWxFbmRDb2x1bW46IHJtLm9yaWdpbmFsUmFuZ2UuZW5kQ29sdW1uLFxuICAgICAgICBtb2RpZmllZFN0YXJ0TGluZTogcm0ubW9kaWZpZWRSYW5nZS5zdGFydExpbmVOdW1iZXIsXG4gICAgICAgIG1vZGlmaWVkU3RhcnRDb2x1bW46IHJtLm1vZGlmaWVkUmFuZ2Uuc3RhcnRDb2x1bW4sXG4gICAgICAgIG1vZGlmaWVkRW5kTGluZTogcm0ubW9kaWZpZWRSYW5nZS5lbmRMaW5lTnVtYmVyLFxuICAgICAgICBtb2RpZmllZEVuZENvbHVtbjogcm0ubW9kaWZpZWRSYW5nZS5lbmRDb2x1bW4sXG4gICAgfTtcbn1cbmZ1bmN0aW9uIHdpcmVUb1JhbmdlTWFwcGluZyhybSkge1xuICAgIHJldHVybiBuZXcgUmFuZ2VNYXBwaW5nKG5ldyBSYW5nZShybS5vcmlnaW5hbFN0YXJ0TGluZSwgcm0ub3JpZ2luYWxTdGFydENvbHVtbiwgcm0ub3JpZ2luYWxFbmRMaW5lLCBybS5vcmlnaW5hbEVuZENvbHVtbiksIG5ldyBSYW5nZShybS5tb2RpZmllZFN0YXJ0TGluZSwgcm0ubW9kaWZpZWRTdGFydENvbHVtbiwgcm0ubW9kaWZpZWRFbmRMaW5lLCBybS5tb2RpZmllZEVuZENvbHVtbikpO1xufVxuZnVuY3Rpb24gbW92ZVRvV2lyZShtKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbGluZVJhbmdlTWFwcGluZzoge1xuICAgICAgICAgICAgb3JpZ2luYWw6IHtcbiAgICAgICAgICAgICAgICBzdGFydExpbmVOdW1iZXI6IG0ubGluZVJhbmdlTWFwcGluZy5vcmlnaW5hbC5zdGFydExpbmVOdW1iZXIsXG4gICAgICAgICAgICAgICAgZW5kTGluZU51bWJlckV4Y2x1c2l2ZTogbS5saW5lUmFuZ2VNYXBwaW5nLm9yaWdpbmFsLmVuZExpbmVOdW1iZXJFeGNsdXNpdmUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbW9kaWZpZWQ6IHtcbiAgICAgICAgICAgICAgICBzdGFydExpbmVOdW1iZXI6IG0ubGluZVJhbmdlTWFwcGluZy5tb2RpZmllZC5zdGFydExpbmVOdW1iZXIsXG4gICAgICAgICAgICAgICAgZW5kTGluZU51bWJlckV4Y2x1c2l2ZTogbS5saW5lUmFuZ2VNYXBwaW5nLm1vZGlmaWVkLmVuZExpbmVOdW1iZXJFeGNsdXNpdmUsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBjaGFuZ2VzOiBtLmNoYW5nZXMubWFwKGRldGFpbGVkVG9XaXJlKSxcbiAgICB9O1xufVxuZnVuY3Rpb24gd2lyZVRvTW92ZShtKSB7XG4gICAgY29uc3QgbHJtID0gbmV3IExpbmVSYW5nZU1hcHBpbmcobmV3IExpbmVSYW5nZShtLmxpbmVSYW5nZU1hcHBpbmcub3JpZ2luYWwuc3RhcnRMaW5lTnVtYmVyLCBtLmxpbmVSYW5nZU1hcHBpbmcub3JpZ2luYWwuZW5kTGluZU51bWJlckV4Y2x1c2l2ZSksIG5ldyBMaW5lUmFuZ2UobS5saW5lUmFuZ2VNYXBwaW5nLm1vZGlmaWVkLnN0YXJ0TGluZU51bWJlciwgbS5saW5lUmFuZ2VNYXBwaW5nLm1vZGlmaWVkLmVuZExpbmVOdW1iZXJFeGNsdXNpdmUpKTtcbiAgICByZXR1cm4gbmV3IE1vdmVkVGV4dChscm0sIG0uY2hhbmdlcy5tYXAod2lyZVRvRGV0YWlsZWQpKTtcbn1cblxuZXhwb3J0IHsgRGVmYXVsdExpbmVzRGlmZkNvbXB1dGVyIGFzIEQsIExpbmVSYW5nZSBhcyBMLCBPZmZzZXRSYW5nZSBhcyBPLCBSYW5nZU1hcHBpbmcgYXMgUiwgUmFuZ2UgYXMgYSwgRGV0YWlsZWRMaW5lUmFuZ2VNYXBwaW5nIGFzIGIsIExpbmVzRGlmZiBhcyBjLCBMaW5lUmFuZ2VNYXBwaW5nIGFzIGQsIGdldFdhc20gYXMgZywgaW5pdFdhc20gYXMgaSwgbGluZXNEaWZmVG9XaXJlIGFzIGwsIHdpcmVUb0xpbmVzRGlmZiBhcyB3IH07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13aXJlLmpzLm1hcFxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9