@cartanova/qgrid-cli 1.0.4 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/dist/application/qgrid/pool.js +15 -6
- package/bundle/dist/application/qgrid/qgrid.frame.js +17 -22
- package/bundle/dist/application/qgrid/qgrid.types.js +5 -2
- package/bundle/dist/application/request-log/request-log.model.js +2 -2
- package/bundle/dist/sonamu.config.js +5 -2
- package/bundle/src/application/qgrid/pool.ts +17 -7
- package/bundle/src/application/qgrid/qgrid.frame.ts +18 -25
- package/bundle/src/application/qgrid/qgrid.types.ts +1 -1
- package/bundle/src/application/request-log/request-log.model.ts +2 -2
- package/bundle/src/sonamu.config.ts +1 -1
- package/bundle/web-dist/{web-dist/client/assets/index-DlPchHBY.js → client/assets/index-C0m8rRjO.js} +2 -2
- package/bundle/web-dist/client/assets/{routes-CagDz23B.js → routes-B1eOXnpo.js} +1 -1
- package/bundle/web-dist/client/assets/{show-aXUGa0gm.js → show-BztN6MXO.js} +1 -1
- package/bundle/web-dist/client/assets/tokens-rR2_-Pte.js +1 -0
- package/bundle/web-dist/client/index.html +1 -1
- package/bundle/web-dist/server/assets/{tokens-JH6FsnWZ.js → tokens-ARL5AOAh.js} +4 -1
- package/bundle/web-dist/server/entry-server.generated.js +1 -1
- package/dist/cli.js +38 -24
- package/package.json +10 -10
- package/bundle/dist/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorate.js +0 -9
- package/bundle/dist/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorateMetadata.js +0 -6
- package/bundle/dist/dist/_virtual/_rolldown/runtime.js +0 -15
- package/bundle/dist/dist/application/qgrid/oauth.js +0 -140
- package/bundle/dist/dist/application/qgrid/pool.js +0 -100
- package/bundle/dist/dist/application/qgrid/qgrid.frame.js +0 -280
- package/bundle/dist/dist/application/qgrid/qgrid.types.js +0 -79
- package/bundle/dist/dist/application/qgrid/worker.js +0 -183
- package/bundle/dist/dist/application/queries.generated.js +0 -31
- package/bundle/dist/dist/application/request-log/request-log.model.js +0 -113
- package/bundle/dist/dist/application/request-log/request-log.types.js +0 -13
- package/bundle/dist/dist/application/sonamu.generated.js +0 -99
- package/bundle/dist/dist/application/sonamu.generated.sso.js +0 -34
- package/bundle/dist/dist/application/token/token.model.js +0 -157
- package/bundle/dist/dist/application/token/token.types.js +0 -22
- package/bundle/dist/dist/i18n/en.js +0 -63
- package/bundle/dist/dist/i18n/ko.js +0 -62
- package/bundle/dist/dist/i18n/sd.generated.js +0 -272
- package/bundle/dist/dist/index.js +0 -11
- package/bundle/dist/dist/migrations/20260410171405_create__request_logs.js +0 -26
- package/bundle/dist/dist/migrations/20260410171406_create__tokens.js +0 -24
- package/bundle/dist/dist/migrations/20260411120624_alter_tokens_alter2.js +0 -16
- package/bundle/dist/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +0 -155
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_expect@4.1.2/node_modules/@vitest/expect/dist/index.js +0 -1484
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.2/node_modules/@vitest/pretty-format/dist/index.js +0 -887
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/chunk-artifact.js +0 -2746
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/index.js +0 -8
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/utils.js +0 -8
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_snapshot@4.1.2/node_modules/@vitest/snapshot/dist/index.js +0 -662
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_spy@4.1.2/node_modules/@vitest/spy/dist/index.js +0 -386
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +0 -82
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/constants.js +0 -48
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/diff.js +0 -1307
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/display.js +0 -558
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/error.js +0 -33
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/helpers.js +0 -226
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/offset.js +0 -27
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/serialize.js +0 -77
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/source-map.js +0 -374
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/timers.js +0 -37
- package/bundle/dist/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +0 -2886
- package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +0 -10
- package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +0 -109
- package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +0 -10
- package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +0 -10
- package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +0 -10
- package/bundle/dist/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +0 -1127
- package/bundle/dist/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +0 -21
- package/bundle/dist/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +0 -432
- package/bundle/dist/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +0 -506
- package/bundle/dist/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +0 -86
- package/bundle/dist/dist/node_modules/.pnpm/vite@8.0.3_@emnapi_core@1.9.2_@emnapi_runtime@1.9.2_@types_node@25.0.7_esbuild@0.27.4_jiti@2.6.1_sass@1.98.0_tsx@4.21.0/node_modules/vite/dist/node/module-runner.js +0 -426
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +0 -6
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/benchmark.CX_oY03V.js +0 -41
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/evaluatedModules.Dg1zASAC.js +0 -19
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/index.Chj8NDwU.js +0 -202
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/index.DOa3dzoN.js +0 -16
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +0 -59
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/test.p_J6dB8a.js +0 -2910
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +0 -44
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/index.js +0 -28
- package/bundle/dist/dist/sonamu.config.js +0 -196
- package/bundle/dist/dist/testing/fixture.js +0 -8
- package/bundle/dist/dist/testing/global.js +0 -9
- package/bundle/dist/dist/testing/setup-mocks.js +0 -17
- package/bundle/dist/dist/utils/subset-loaders.js +0 -12
- package/bundle/src/src/application/qgrid/oauth.ts +0 -181
- package/bundle/src/src/application/qgrid/pool.ts +0 -132
- package/bundle/src/src/application/qgrid/qgrid.frame.ts +0 -275
- package/bundle/src/src/application/qgrid/qgrid.types.ts +0 -117
- package/bundle/src/src/application/qgrid/worker.ts +0 -234
- package/bundle/src/src/application/queries.generated.ts +0 -59
- package/bundle/src/src/application/request-log/request-log.entity.json +0 -75
- package/bundle/src/src/application/request-log/request-log.model.ts +0 -155
- package/bundle/src/src/application/request-log/request-log.types.ts +0 -15
- package/bundle/src/src/application/sonamu.generated.http +0 -187
- package/bundle/src/src/application/sonamu.generated.sso.ts +0 -66
- package/bundle/src/src/application/sonamu.generated.ts +0 -135
- package/bundle/src/src/application/token/token.entity.json +0 -37
- package/bundle/src/src/application/token/token.model.ts +0 -160
- package/bundle/src/src/application/token/token.types.ts +0 -26
- package/bundle/src/src/i18n/en.ts +0 -59
- package/bundle/src/src/i18n/ko.ts +0 -59
- package/bundle/src/src/i18n/sd.generated.ts +0 -384
- package/bundle/src/src/index.ts +0 -6
- package/bundle/src/src/migrations/20260410171405_create__request_logs.ts +0 -23
- package/bundle/src/src/migrations/20260410171406_create__tokens.ts +0 -21
- package/bundle/src/src/migrations/20260411120624_alter_tokens_alter2.ts +0 -15
- package/bundle/src/src/sonamu.config.ts +0 -248
- package/bundle/src/src/testing/fixture.ts +0 -6
- package/bundle/src/src/testing/global.ts +0 -6
- package/bundle/src/src/testing/setup-mocks.ts +0 -44
- package/bundle/src/src/typings/fastify.d.ts +0 -8
- package/bundle/src/src/typings/sonamu.d.ts +0 -17
- package/bundle/src/src/utils/subset-loaders.ts +0 -11
- package/bundle/web-dist/client/assets/index-DlPchHBY.js +0 -116
- package/bundle/web-dist/client/assets/tokens-DRkXtZ3Q.js +0 -1
- package/bundle/web-dist/web-dist/client/assets/index-vZsvyuFn.css +0 -1
- package/bundle/web-dist/web-dist/client/assets/rolldown-runtime-Dw2cE7zH.js +0 -1
- package/bundle/web-dist/web-dist/client/assets/routes-CagDz23B.js +0 -1
- package/bundle/web-dist/web-dist/client/assets/sd.generated-BrQoQXvv.js +0 -47
- package/bundle/web-dist/web-dist/client/assets/services.generated-BspO2L0j.js +0 -1
- package/bundle/web-dist/web-dist/client/assets/show-aXUGa0gm.js +0 -29
- package/bundle/web-dist/web-dist/client/assets/tokens-DRkXtZ3Q.js +0 -1
- package/bundle/web-dist/web-dist/client/assets/vendor-react-DH4kUfK2.js +0 -9
- package/bundle/web-dist/web-dist/client/assets/vendor-tanstack-CUxlo6YN.js +0 -1
- package/bundle/web-dist/web-dist/client/index.html +0 -18
- package/bundle/web-dist/web-dist/server/assets/react-dom-CGIzOSuj.js +0 -335
- package/bundle/web-dist/web-dist/server/assets/routes-ClzReRep.js +0 -490
- package/bundle/web-dist/web-dist/server/assets/sd.generated-BnonqqKr.js +0 -21694
- package/bundle/web-dist/web-dist/server/assets/services.generated-D5ABD5fr.js +0 -836
- package/bundle/web-dist/web-dist/server/assets/show-C9pcdSxc.js +0 -23364
- package/bundle/web-dist/web-dist/server/assets/tokens-JH6FsnWZ.js +0 -860
- package/bundle/web-dist/web-dist/server/entry-server.generated.js +0 -44646
|
@@ -1,1307 +0,0 @@
|
|
|
1
|
-
import { y } from "../../../../../tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js";
|
|
2
|
-
import { format, plugins } from "../../../../../@vitest_pretty-format@4.1.2/node_modules/@vitest/pretty-format/dist/index.js";
|
|
3
|
-
import { stringify } from "./display.js";
|
|
4
|
-
import "./constants.js";
|
|
5
|
-
import { deepClone, getOwnProperties, getType as getType$1 } from "./helpers.js";
|
|
6
|
-
/**
|
|
7
|
-
* Class representing one diff tuple.
|
|
8
|
-
* Attempts to look like a two-element array (which is what this used to be).
|
|
9
|
-
* @param {number} op Operation, one of: DIFF_DELETE, DIFF_INSERT, DIFF_EQUAL.
|
|
10
|
-
* @param {string} text Text to be deleted, inserted, or retained.
|
|
11
|
-
* @constructor
|
|
12
|
-
*/
|
|
13
|
-
var Diff = class {
|
|
14
|
-
0;
|
|
15
|
-
1;
|
|
16
|
-
constructor(op, text) {
|
|
17
|
-
this[0] = op;
|
|
18
|
-
this[1] = text;
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* Determine the common prefix of two strings.
|
|
23
|
-
* @param {string} text1 First string.
|
|
24
|
-
* @param {string} text2 Second string.
|
|
25
|
-
* @return {number} The number of characters common to the start of each
|
|
26
|
-
* string.
|
|
27
|
-
*/
|
|
28
|
-
function diff_commonPrefix(text1, text2) {
|
|
29
|
-
if (!text1 || !text2 || text1.charAt(0) !== text2.charAt(0)) return 0;
|
|
30
|
-
let pointermin = 0;
|
|
31
|
-
let pointermax = Math.min(text1.length, text2.length);
|
|
32
|
-
let pointermid = pointermax;
|
|
33
|
-
let pointerstart = 0;
|
|
34
|
-
while (pointermin < pointermid) {
|
|
35
|
-
if (text1.substring(pointerstart, pointermid) === text2.substring(pointerstart, pointermid)) {
|
|
36
|
-
pointermin = pointermid;
|
|
37
|
-
pointerstart = pointermin;
|
|
38
|
-
} else pointermax = pointermid;
|
|
39
|
-
pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
|
|
40
|
-
}
|
|
41
|
-
return pointermid;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Determine the common suffix of two strings.
|
|
45
|
-
* @param {string} text1 First string.
|
|
46
|
-
* @param {string} text2 Second string.
|
|
47
|
-
* @return {number} The number of characters common to the end of each string.
|
|
48
|
-
*/
|
|
49
|
-
function diff_commonSuffix(text1, text2) {
|
|
50
|
-
if (!text1 || !text2 || text1.charAt(text1.length - 1) !== text2.charAt(text2.length - 1)) return 0;
|
|
51
|
-
let pointermin = 0;
|
|
52
|
-
let pointermax = Math.min(text1.length, text2.length);
|
|
53
|
-
let pointermid = pointermax;
|
|
54
|
-
let pointerend = 0;
|
|
55
|
-
while (pointermin < pointermid) {
|
|
56
|
-
if (text1.substring(text1.length - pointermid, text1.length - pointerend) === text2.substring(text2.length - pointermid, text2.length - pointerend)) {
|
|
57
|
-
pointermin = pointermid;
|
|
58
|
-
pointerend = pointermin;
|
|
59
|
-
} else pointermax = pointermid;
|
|
60
|
-
pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
|
|
61
|
-
}
|
|
62
|
-
return pointermid;
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Determine if the suffix of one string is the prefix of another.
|
|
66
|
-
* @param {string} text1 First string.
|
|
67
|
-
* @param {string} text2 Second string.
|
|
68
|
-
* @return {number} The number of characters common to the end of the first
|
|
69
|
-
* string and the start of the second string.
|
|
70
|
-
* @private
|
|
71
|
-
*/
|
|
72
|
-
function diff_commonOverlap_(text1, text2) {
|
|
73
|
-
const text1_length = text1.length;
|
|
74
|
-
const text2_length = text2.length;
|
|
75
|
-
if (text1_length === 0 || text2_length === 0) return 0;
|
|
76
|
-
if (text1_length > text2_length) text1 = text1.substring(text1_length - text2_length);
|
|
77
|
-
else if (text1_length < text2_length) text2 = text2.substring(0, text1_length);
|
|
78
|
-
const text_length = Math.min(text1_length, text2_length);
|
|
79
|
-
if (text1 === text2) return text_length;
|
|
80
|
-
let best = 0;
|
|
81
|
-
let length = 1;
|
|
82
|
-
while (true) {
|
|
83
|
-
const pattern = text1.substring(text_length - length);
|
|
84
|
-
const found = text2.indexOf(pattern);
|
|
85
|
-
if (found === -1) return best;
|
|
86
|
-
length += found;
|
|
87
|
-
if (found === 0 || text1.substring(text_length - length) === text2.substring(0, length)) {
|
|
88
|
-
best = length;
|
|
89
|
-
length++;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Reduce the number of edits by eliminating semantically trivial equalities.
|
|
95
|
-
* @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
|
|
96
|
-
*/
|
|
97
|
-
function diff_cleanupSemantic(diffs) {
|
|
98
|
-
let changes = false;
|
|
99
|
-
const equalities = [];
|
|
100
|
-
let equalitiesLength = 0;
|
|
101
|
-
/** @type {?string} */
|
|
102
|
-
let lastEquality = null;
|
|
103
|
-
let pointer = 0;
|
|
104
|
-
let length_insertions1 = 0;
|
|
105
|
-
let length_deletions1 = 0;
|
|
106
|
-
let length_insertions2 = 0;
|
|
107
|
-
let length_deletions2 = 0;
|
|
108
|
-
while (pointer < diffs.length) {
|
|
109
|
-
if (diffs[pointer][0] === 0) {
|
|
110
|
-
equalities[equalitiesLength++] = pointer;
|
|
111
|
-
length_insertions1 = length_insertions2;
|
|
112
|
-
length_deletions1 = length_deletions2;
|
|
113
|
-
length_insertions2 = 0;
|
|
114
|
-
length_deletions2 = 0;
|
|
115
|
-
lastEquality = diffs[pointer][1];
|
|
116
|
-
} else {
|
|
117
|
-
if (diffs[pointer][0] === 1) length_insertions2 += diffs[pointer][1].length;
|
|
118
|
-
else length_deletions2 += diffs[pointer][1].length;
|
|
119
|
-
if (lastEquality && lastEquality.length <= Math.max(length_insertions1, length_deletions1) && lastEquality.length <= Math.max(length_insertions2, length_deletions2)) {
|
|
120
|
-
diffs.splice(equalities[equalitiesLength - 1], 0, new Diff(-1, lastEquality));
|
|
121
|
-
diffs[equalities[equalitiesLength - 1] + 1][0] = 1;
|
|
122
|
-
equalitiesLength--;
|
|
123
|
-
equalitiesLength--;
|
|
124
|
-
pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1;
|
|
125
|
-
length_insertions1 = 0;
|
|
126
|
-
length_deletions1 = 0;
|
|
127
|
-
length_insertions2 = 0;
|
|
128
|
-
length_deletions2 = 0;
|
|
129
|
-
lastEquality = null;
|
|
130
|
-
changes = true;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
pointer++;
|
|
134
|
-
}
|
|
135
|
-
if (changes) diff_cleanupMerge(diffs);
|
|
136
|
-
diff_cleanupSemanticLossless(diffs);
|
|
137
|
-
pointer = 1;
|
|
138
|
-
while (pointer < diffs.length) {
|
|
139
|
-
if (diffs[pointer - 1][0] === -1 && diffs[pointer][0] === 1) {
|
|
140
|
-
const deletion = diffs[pointer - 1][1];
|
|
141
|
-
const insertion = diffs[pointer][1];
|
|
142
|
-
const overlap_length1 = diff_commonOverlap_(deletion, insertion);
|
|
143
|
-
const overlap_length2 = diff_commonOverlap_(insertion, deletion);
|
|
144
|
-
if (overlap_length1 >= overlap_length2) {
|
|
145
|
-
if (overlap_length1 >= deletion.length / 2 || overlap_length1 >= insertion.length / 2) {
|
|
146
|
-
diffs.splice(pointer, 0, new Diff(0, insertion.substring(0, overlap_length1)));
|
|
147
|
-
diffs[pointer - 1][1] = deletion.substring(0, deletion.length - overlap_length1);
|
|
148
|
-
diffs[pointer + 1][1] = insertion.substring(overlap_length1);
|
|
149
|
-
pointer++;
|
|
150
|
-
}
|
|
151
|
-
} else if (overlap_length2 >= deletion.length / 2 || overlap_length2 >= insertion.length / 2) {
|
|
152
|
-
diffs.splice(pointer, 0, new Diff(0, deletion.substring(0, overlap_length2)));
|
|
153
|
-
diffs[pointer - 1][0] = 1;
|
|
154
|
-
diffs[pointer - 1][1] = insertion.substring(0, insertion.length - overlap_length2);
|
|
155
|
-
diffs[pointer + 1][0] = -1;
|
|
156
|
-
diffs[pointer + 1][1] = deletion.substring(overlap_length2);
|
|
157
|
-
pointer++;
|
|
158
|
-
}
|
|
159
|
-
pointer++;
|
|
160
|
-
}
|
|
161
|
-
pointer++;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
const nonAlphaNumericRegex_ = /[^a-z0-9]/i;
|
|
165
|
-
const whitespaceRegex_ = /\s/;
|
|
166
|
-
const linebreakRegex_ = /[\r\n]/;
|
|
167
|
-
const blanklineEndRegex_ = /\n\r?\n$/;
|
|
168
|
-
const blanklineStartRegex_ = /^\r?\n\r?\n/;
|
|
169
|
-
/**
|
|
170
|
-
* Look for single edits surrounded on both sides by equalities
|
|
171
|
-
* which can be shifted sideways to align the edit to a word boundary.
|
|
172
|
-
* e.g: The c<ins>at c</ins>ame. -> The <ins>cat </ins>came.
|
|
173
|
-
* @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
|
|
174
|
-
*/
|
|
175
|
-
function diff_cleanupSemanticLossless(diffs) {
|
|
176
|
-
let pointer = 1;
|
|
177
|
-
while (pointer < diffs.length - 1) {
|
|
178
|
-
if (diffs[pointer - 1][0] === 0 && diffs[pointer + 1][0] === 0) {
|
|
179
|
-
let equality1 = diffs[pointer - 1][1];
|
|
180
|
-
let edit = diffs[pointer][1];
|
|
181
|
-
let equality2 = diffs[pointer + 1][1];
|
|
182
|
-
const commonOffset = diff_commonSuffix(equality1, edit);
|
|
183
|
-
if (commonOffset) {
|
|
184
|
-
const commonString = edit.substring(edit.length - commonOffset);
|
|
185
|
-
equality1 = equality1.substring(0, equality1.length - commonOffset);
|
|
186
|
-
edit = commonString + edit.substring(0, edit.length - commonOffset);
|
|
187
|
-
equality2 = commonString + equality2;
|
|
188
|
-
}
|
|
189
|
-
let bestEquality1 = equality1;
|
|
190
|
-
let bestEdit = edit;
|
|
191
|
-
let bestEquality2 = equality2;
|
|
192
|
-
let bestScore = diff_cleanupSemanticScore_(equality1, edit) + diff_cleanupSemanticScore_(edit, equality2);
|
|
193
|
-
while (edit.charAt(0) === equality2.charAt(0)) {
|
|
194
|
-
equality1 += edit.charAt(0);
|
|
195
|
-
edit = edit.substring(1) + equality2.charAt(0);
|
|
196
|
-
equality2 = equality2.substring(1);
|
|
197
|
-
const score = diff_cleanupSemanticScore_(equality1, edit) + diff_cleanupSemanticScore_(edit, equality2);
|
|
198
|
-
if (score >= bestScore) {
|
|
199
|
-
bestScore = score;
|
|
200
|
-
bestEquality1 = equality1;
|
|
201
|
-
bestEdit = edit;
|
|
202
|
-
bestEquality2 = equality2;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
if (diffs[pointer - 1][1] !== bestEquality1) {
|
|
206
|
-
if (bestEquality1) diffs[pointer - 1][1] = bestEquality1;
|
|
207
|
-
else {
|
|
208
|
-
diffs.splice(pointer - 1, 1);
|
|
209
|
-
pointer--;
|
|
210
|
-
}
|
|
211
|
-
diffs[pointer][1] = bestEdit;
|
|
212
|
-
if (bestEquality2) diffs[pointer + 1][1] = bestEquality2;
|
|
213
|
-
else {
|
|
214
|
-
diffs.splice(pointer + 1, 1);
|
|
215
|
-
pointer--;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
pointer++;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Reorder and merge like edit sections. Merge equalities.
|
|
224
|
-
* Any edit section can move as long as it doesn't cross an equality.
|
|
225
|
-
* @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
|
|
226
|
-
*/
|
|
227
|
-
function diff_cleanupMerge(diffs) {
|
|
228
|
-
diffs.push(new Diff(0, ""));
|
|
229
|
-
let pointer = 0;
|
|
230
|
-
let count_delete = 0;
|
|
231
|
-
let count_insert = 0;
|
|
232
|
-
let text_delete = "";
|
|
233
|
-
let text_insert = "";
|
|
234
|
-
let commonlength;
|
|
235
|
-
while (pointer < diffs.length) switch (diffs[pointer][0]) {
|
|
236
|
-
case 1:
|
|
237
|
-
count_insert++;
|
|
238
|
-
text_insert += diffs[pointer][1];
|
|
239
|
-
pointer++;
|
|
240
|
-
break;
|
|
241
|
-
case -1:
|
|
242
|
-
count_delete++;
|
|
243
|
-
text_delete += diffs[pointer][1];
|
|
244
|
-
pointer++;
|
|
245
|
-
break;
|
|
246
|
-
case 0:
|
|
247
|
-
if (count_delete + count_insert > 1) {
|
|
248
|
-
if (count_delete !== 0 && count_insert !== 0) {
|
|
249
|
-
commonlength = diff_commonPrefix(text_insert, text_delete);
|
|
250
|
-
if (commonlength !== 0) {
|
|
251
|
-
if (pointer - count_delete - count_insert > 0 && diffs[pointer - count_delete - count_insert - 1][0] === 0) diffs[pointer - count_delete - count_insert - 1][1] += text_insert.substring(0, commonlength);
|
|
252
|
-
else {
|
|
253
|
-
diffs.splice(0, 0, new Diff(0, text_insert.substring(0, commonlength)));
|
|
254
|
-
pointer++;
|
|
255
|
-
}
|
|
256
|
-
text_insert = text_insert.substring(commonlength);
|
|
257
|
-
text_delete = text_delete.substring(commonlength);
|
|
258
|
-
}
|
|
259
|
-
commonlength = diff_commonSuffix(text_insert, text_delete);
|
|
260
|
-
if (commonlength !== 0) {
|
|
261
|
-
diffs[pointer][1] = text_insert.substring(text_insert.length - commonlength) + diffs[pointer][1];
|
|
262
|
-
text_insert = text_insert.substring(0, text_insert.length - commonlength);
|
|
263
|
-
text_delete = text_delete.substring(0, text_delete.length - commonlength);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
pointer -= count_delete + count_insert;
|
|
267
|
-
diffs.splice(pointer, count_delete + count_insert);
|
|
268
|
-
if (text_delete.length) {
|
|
269
|
-
diffs.splice(pointer, 0, new Diff(-1, text_delete));
|
|
270
|
-
pointer++;
|
|
271
|
-
}
|
|
272
|
-
if (text_insert.length) {
|
|
273
|
-
diffs.splice(pointer, 0, new Diff(1, text_insert));
|
|
274
|
-
pointer++;
|
|
275
|
-
}
|
|
276
|
-
pointer++;
|
|
277
|
-
} else if (pointer !== 0 && diffs[pointer - 1][0] === 0) {
|
|
278
|
-
diffs[pointer - 1][1] += diffs[pointer][1];
|
|
279
|
-
diffs.splice(pointer, 1);
|
|
280
|
-
} else pointer++;
|
|
281
|
-
count_insert = 0;
|
|
282
|
-
count_delete = 0;
|
|
283
|
-
text_delete = "";
|
|
284
|
-
text_insert = "";
|
|
285
|
-
break;
|
|
286
|
-
}
|
|
287
|
-
if (diffs.at(-1)?.[1] === "") diffs.pop();
|
|
288
|
-
let changes = false;
|
|
289
|
-
pointer = 1;
|
|
290
|
-
while (pointer < diffs.length - 1) {
|
|
291
|
-
if (diffs[pointer - 1][0] === 0 && diffs[pointer + 1][0] === 0) {
|
|
292
|
-
if (diffs[pointer][1].substring(diffs[pointer][1].length - diffs[pointer - 1][1].length) === diffs[pointer - 1][1]) {
|
|
293
|
-
diffs[pointer][1] = diffs[pointer - 1][1] + diffs[pointer][1].substring(0, diffs[pointer][1].length - diffs[pointer - 1][1].length);
|
|
294
|
-
diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1];
|
|
295
|
-
diffs.splice(pointer - 1, 1);
|
|
296
|
-
changes = true;
|
|
297
|
-
} else if (diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) === diffs[pointer + 1][1]) {
|
|
298
|
-
diffs[pointer - 1][1] += diffs[pointer + 1][1];
|
|
299
|
-
diffs[pointer][1] = diffs[pointer][1].substring(diffs[pointer + 1][1].length) + diffs[pointer + 1][1];
|
|
300
|
-
diffs.splice(pointer + 1, 1);
|
|
301
|
-
changes = true;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
pointer++;
|
|
305
|
-
}
|
|
306
|
-
if (changes) diff_cleanupMerge(diffs);
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* Given two strings, compute a score representing whether the internal
|
|
310
|
-
* boundary falls on logical boundaries.
|
|
311
|
-
* Scores range from 6 (best) to 0 (worst).
|
|
312
|
-
* Closure, but does not reference any external variables.
|
|
313
|
-
* @param {string} one First string.
|
|
314
|
-
* @param {string} two Second string.
|
|
315
|
-
* @return {number} The score.
|
|
316
|
-
* @private
|
|
317
|
-
*/
|
|
318
|
-
function diff_cleanupSemanticScore_(one, two) {
|
|
319
|
-
if (!one || !two) return 6;
|
|
320
|
-
const char1 = one.charAt(one.length - 1);
|
|
321
|
-
const char2 = two.charAt(0);
|
|
322
|
-
const nonAlphaNumeric1 = char1.match(nonAlphaNumericRegex_);
|
|
323
|
-
const nonAlphaNumeric2 = char2.match(nonAlphaNumericRegex_);
|
|
324
|
-
const whitespace1 = nonAlphaNumeric1 && char1.match(whitespaceRegex_);
|
|
325
|
-
const whitespace2 = nonAlphaNumeric2 && char2.match(whitespaceRegex_);
|
|
326
|
-
const lineBreak1 = whitespace1 && char1.match(linebreakRegex_);
|
|
327
|
-
const lineBreak2 = whitespace2 && char2.match(linebreakRegex_);
|
|
328
|
-
const blankLine1 = lineBreak1 && one.match(blanklineEndRegex_);
|
|
329
|
-
const blankLine2 = lineBreak2 && two.match(blanklineStartRegex_);
|
|
330
|
-
if (blankLine1 || blankLine2) return 5;
|
|
331
|
-
else if (lineBreak1 || lineBreak2) return 4;
|
|
332
|
-
else if (nonAlphaNumeric1 && !whitespace1 && whitespace2) return 3;
|
|
333
|
-
else if (whitespace1 || whitespace2) return 2;
|
|
334
|
-
else if (nonAlphaNumeric1 || nonAlphaNumeric2) return 1;
|
|
335
|
-
return 0;
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
339
|
-
*
|
|
340
|
-
* This source code is licensed under the MIT license found in the
|
|
341
|
-
* LICENSE file in the root directory of this source tree.
|
|
342
|
-
*/
|
|
343
|
-
const NO_DIFF_MESSAGE = "Compared values have no visual difference.";
|
|
344
|
-
const SIMILAR_MESSAGE = "Compared values serialize to the same structure.\nPrinting internal object structure without calling `toJSON` instead.";
|
|
345
|
-
function getDefaultExportFromCjs(x) {
|
|
346
|
-
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
347
|
-
}
|
|
348
|
-
var build = {};
|
|
349
|
-
var hasRequiredBuild;
|
|
350
|
-
function requireBuild() {
|
|
351
|
-
if (hasRequiredBuild) return build;
|
|
352
|
-
hasRequiredBuild = 1;
|
|
353
|
-
Object.defineProperty(build, "__esModule", { value: true });
|
|
354
|
-
build.default = diffSequence;
|
|
355
|
-
/**
|
|
356
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
357
|
-
*
|
|
358
|
-
* This source code is licensed under the MIT license found in the
|
|
359
|
-
* LICENSE file in the root directory of this source tree.
|
|
360
|
-
*
|
|
361
|
-
*/
|
|
362
|
-
const pkg = "diff-sequences";
|
|
363
|
-
const NOT_YET_SET = 0;
|
|
364
|
-
const countCommonItemsF = (aIndex, aEnd, bIndex, bEnd, isCommon) => {
|
|
365
|
-
let nCommon = 0;
|
|
366
|
-
while (aIndex < aEnd && bIndex < bEnd && isCommon(aIndex, bIndex)) {
|
|
367
|
-
aIndex += 1;
|
|
368
|
-
bIndex += 1;
|
|
369
|
-
nCommon += 1;
|
|
370
|
-
}
|
|
371
|
-
return nCommon;
|
|
372
|
-
};
|
|
373
|
-
const countCommonItemsR = (aStart, aIndex, bStart, bIndex, isCommon) => {
|
|
374
|
-
let nCommon = 0;
|
|
375
|
-
while (aStart <= aIndex && bStart <= bIndex && isCommon(aIndex, bIndex)) {
|
|
376
|
-
aIndex -= 1;
|
|
377
|
-
bIndex -= 1;
|
|
378
|
-
nCommon += 1;
|
|
379
|
-
}
|
|
380
|
-
return nCommon;
|
|
381
|
-
};
|
|
382
|
-
const extendPathsF = (d, aEnd, bEnd, bF, isCommon, aIndexesF, iMaxF) => {
|
|
383
|
-
let iF = 0;
|
|
384
|
-
let kF = -d;
|
|
385
|
-
let aFirst = aIndexesF[iF];
|
|
386
|
-
let aIndexPrev1 = aFirst;
|
|
387
|
-
aIndexesF[iF] += countCommonItemsF(aFirst + 1, aEnd, bF + aFirst - kF + 1, bEnd, isCommon);
|
|
388
|
-
const nF = d < iMaxF ? d : iMaxF;
|
|
389
|
-
for (iF += 1, kF += 2; iF <= nF; iF += 1, kF += 2) {
|
|
390
|
-
if (iF !== d && aIndexPrev1 < aIndexesF[iF]) aFirst = aIndexesF[iF];
|
|
391
|
-
else {
|
|
392
|
-
aFirst = aIndexPrev1 + 1;
|
|
393
|
-
if (aEnd <= aFirst) return iF - 1;
|
|
394
|
-
}
|
|
395
|
-
aIndexPrev1 = aIndexesF[iF];
|
|
396
|
-
aIndexesF[iF] = aFirst + countCommonItemsF(aFirst + 1, aEnd, bF + aFirst - kF + 1, bEnd, isCommon);
|
|
397
|
-
}
|
|
398
|
-
return iMaxF;
|
|
399
|
-
};
|
|
400
|
-
const extendPathsR = (d, aStart, bStart, bR, isCommon, aIndexesR, iMaxR) => {
|
|
401
|
-
let iR = 0;
|
|
402
|
-
let kR = d;
|
|
403
|
-
let aFirst = aIndexesR[iR];
|
|
404
|
-
let aIndexPrev1 = aFirst;
|
|
405
|
-
aIndexesR[iR] -= countCommonItemsR(aStart, aFirst - 1, bStart, bR + aFirst - kR - 1, isCommon);
|
|
406
|
-
const nR = d < iMaxR ? d : iMaxR;
|
|
407
|
-
for (iR += 1, kR -= 2; iR <= nR; iR += 1, kR -= 2) {
|
|
408
|
-
if (iR !== d && aIndexesR[iR] < aIndexPrev1) aFirst = aIndexesR[iR];
|
|
409
|
-
else {
|
|
410
|
-
aFirst = aIndexPrev1 - 1;
|
|
411
|
-
if (aFirst < aStart) return iR - 1;
|
|
412
|
-
}
|
|
413
|
-
aIndexPrev1 = aIndexesR[iR];
|
|
414
|
-
aIndexesR[iR] = aFirst - countCommonItemsR(aStart, aFirst - 1, bStart, bR + aFirst - kR - 1, isCommon);
|
|
415
|
-
}
|
|
416
|
-
return iMaxR;
|
|
417
|
-
};
|
|
418
|
-
const extendOverlappablePathsF = (d, aStart, aEnd, bStart, bEnd, isCommon, aIndexesF, iMaxF, aIndexesR, iMaxR, division) => {
|
|
419
|
-
const bF = bStart - aStart;
|
|
420
|
-
const aLength = aEnd - aStart;
|
|
421
|
-
const baDeltaLength = bEnd - bStart - aLength;
|
|
422
|
-
const kMinOverlapF = -baDeltaLength - (d - 1);
|
|
423
|
-
const kMaxOverlapF = -baDeltaLength + (d - 1);
|
|
424
|
-
let aIndexPrev1 = NOT_YET_SET;
|
|
425
|
-
const nF = d < iMaxF ? d : iMaxF;
|
|
426
|
-
for (let iF = 0, kF = -d; iF <= nF; iF += 1, kF += 2) {
|
|
427
|
-
const insert = iF === 0 || iF !== d && aIndexPrev1 < aIndexesF[iF];
|
|
428
|
-
const aLastPrev = insert ? aIndexesF[iF] : aIndexPrev1;
|
|
429
|
-
const aFirst = insert ? aLastPrev : aLastPrev + 1;
|
|
430
|
-
const bFirst = bF + aFirst - kF;
|
|
431
|
-
const nCommonF = countCommonItemsF(aFirst + 1, aEnd, bFirst + 1, bEnd, isCommon);
|
|
432
|
-
const aLast = aFirst + nCommonF;
|
|
433
|
-
aIndexPrev1 = aIndexesF[iF];
|
|
434
|
-
aIndexesF[iF] = aLast;
|
|
435
|
-
if (kMinOverlapF <= kF && kF <= kMaxOverlapF) {
|
|
436
|
-
const iR = (d - 1 - (kF + baDeltaLength)) / 2;
|
|
437
|
-
if (iR <= iMaxR && aIndexesR[iR] - 1 <= aLast) {
|
|
438
|
-
const bLastPrev = bF + aLastPrev - (insert ? kF + 1 : kF - 1);
|
|
439
|
-
const nCommonR = countCommonItemsR(aStart, aLastPrev, bStart, bLastPrev, isCommon);
|
|
440
|
-
const aIndexPrevFirst = aLastPrev - nCommonR;
|
|
441
|
-
const bIndexPrevFirst = bLastPrev - nCommonR;
|
|
442
|
-
const aEndPreceding = aIndexPrevFirst + 1;
|
|
443
|
-
const bEndPreceding = bIndexPrevFirst + 1;
|
|
444
|
-
division.nChangePreceding = d - 1;
|
|
445
|
-
if (d - 1 === aEndPreceding + bEndPreceding - aStart - bStart) {
|
|
446
|
-
division.aEndPreceding = aStart;
|
|
447
|
-
division.bEndPreceding = bStart;
|
|
448
|
-
} else {
|
|
449
|
-
division.aEndPreceding = aEndPreceding;
|
|
450
|
-
division.bEndPreceding = bEndPreceding;
|
|
451
|
-
}
|
|
452
|
-
division.nCommonPreceding = nCommonR;
|
|
453
|
-
if (nCommonR !== 0) {
|
|
454
|
-
division.aCommonPreceding = aEndPreceding;
|
|
455
|
-
division.bCommonPreceding = bEndPreceding;
|
|
456
|
-
}
|
|
457
|
-
division.nCommonFollowing = nCommonF;
|
|
458
|
-
if (nCommonF !== 0) {
|
|
459
|
-
division.aCommonFollowing = aFirst + 1;
|
|
460
|
-
division.bCommonFollowing = bFirst + 1;
|
|
461
|
-
}
|
|
462
|
-
const aStartFollowing = aLast + 1;
|
|
463
|
-
const bStartFollowing = bFirst + nCommonF + 1;
|
|
464
|
-
division.nChangeFollowing = d - 1;
|
|
465
|
-
if (d - 1 === aEnd + bEnd - aStartFollowing - bStartFollowing) {
|
|
466
|
-
division.aStartFollowing = aEnd;
|
|
467
|
-
division.bStartFollowing = bEnd;
|
|
468
|
-
} else {
|
|
469
|
-
division.aStartFollowing = aStartFollowing;
|
|
470
|
-
division.bStartFollowing = bStartFollowing;
|
|
471
|
-
}
|
|
472
|
-
return true;
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
return false;
|
|
477
|
-
};
|
|
478
|
-
const extendOverlappablePathsR = (d, aStart, aEnd, bStart, bEnd, isCommon, aIndexesF, iMaxF, aIndexesR, iMaxR, division) => {
|
|
479
|
-
const bR = bEnd - aEnd;
|
|
480
|
-
const aLength = aEnd - aStart;
|
|
481
|
-
const baDeltaLength = bEnd - bStart - aLength;
|
|
482
|
-
const kMinOverlapR = baDeltaLength - d;
|
|
483
|
-
const kMaxOverlapR = baDeltaLength + d;
|
|
484
|
-
let aIndexPrev1 = NOT_YET_SET;
|
|
485
|
-
const nR = d < iMaxR ? d : iMaxR;
|
|
486
|
-
for (let iR = 0, kR = d; iR <= nR; iR += 1, kR -= 2) {
|
|
487
|
-
const insert = iR === 0 || iR !== d && aIndexesR[iR] < aIndexPrev1;
|
|
488
|
-
const aLastPrev = insert ? aIndexesR[iR] : aIndexPrev1;
|
|
489
|
-
const aFirst = insert ? aLastPrev : aLastPrev - 1;
|
|
490
|
-
const bFirst = bR + aFirst - kR;
|
|
491
|
-
const nCommonR = countCommonItemsR(aStart, aFirst - 1, bStart, bFirst - 1, isCommon);
|
|
492
|
-
const aLast = aFirst - nCommonR;
|
|
493
|
-
aIndexPrev1 = aIndexesR[iR];
|
|
494
|
-
aIndexesR[iR] = aLast;
|
|
495
|
-
if (kMinOverlapR <= kR && kR <= kMaxOverlapR) {
|
|
496
|
-
const iF = (d + (kR - baDeltaLength)) / 2;
|
|
497
|
-
if (iF <= iMaxF && aLast - 1 <= aIndexesF[iF]) {
|
|
498
|
-
const bLast = bFirst - nCommonR;
|
|
499
|
-
division.nChangePreceding = d;
|
|
500
|
-
if (d === aLast + bLast - aStart - bStart) {
|
|
501
|
-
division.aEndPreceding = aStart;
|
|
502
|
-
division.bEndPreceding = bStart;
|
|
503
|
-
} else {
|
|
504
|
-
division.aEndPreceding = aLast;
|
|
505
|
-
division.bEndPreceding = bLast;
|
|
506
|
-
}
|
|
507
|
-
division.nCommonPreceding = nCommonR;
|
|
508
|
-
if (nCommonR !== 0) {
|
|
509
|
-
division.aCommonPreceding = aLast;
|
|
510
|
-
division.bCommonPreceding = bLast;
|
|
511
|
-
}
|
|
512
|
-
division.nChangeFollowing = d - 1;
|
|
513
|
-
if (d === 1) {
|
|
514
|
-
division.nCommonFollowing = 0;
|
|
515
|
-
division.aStartFollowing = aEnd;
|
|
516
|
-
division.bStartFollowing = bEnd;
|
|
517
|
-
} else {
|
|
518
|
-
const bLastPrev = bR + aLastPrev - (insert ? kR - 1 : kR + 1);
|
|
519
|
-
const nCommonF = countCommonItemsF(aLastPrev, aEnd, bLastPrev, bEnd, isCommon);
|
|
520
|
-
division.nCommonFollowing = nCommonF;
|
|
521
|
-
if (nCommonF !== 0) {
|
|
522
|
-
division.aCommonFollowing = aLastPrev;
|
|
523
|
-
division.bCommonFollowing = bLastPrev;
|
|
524
|
-
}
|
|
525
|
-
const aStartFollowing = aLastPrev + nCommonF;
|
|
526
|
-
const bStartFollowing = bLastPrev + nCommonF;
|
|
527
|
-
if (d - 1 === aEnd + bEnd - aStartFollowing - bStartFollowing) {
|
|
528
|
-
division.aStartFollowing = aEnd;
|
|
529
|
-
division.bStartFollowing = bEnd;
|
|
530
|
-
} else {
|
|
531
|
-
division.aStartFollowing = aStartFollowing;
|
|
532
|
-
division.bStartFollowing = bStartFollowing;
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
return true;
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
return false;
|
|
540
|
-
};
|
|
541
|
-
const divide = (nChange, aStart, aEnd, bStart, bEnd, isCommon, aIndexesF, aIndexesR, division) => {
|
|
542
|
-
const bF = bStart - aStart;
|
|
543
|
-
const bR = bEnd - aEnd;
|
|
544
|
-
const aLength = aEnd - aStart;
|
|
545
|
-
const bLength = bEnd - bStart;
|
|
546
|
-
const baDeltaLength = bLength - aLength;
|
|
547
|
-
let iMaxF = aLength;
|
|
548
|
-
let iMaxR = aLength;
|
|
549
|
-
aIndexesF[0] = aStart - 1;
|
|
550
|
-
aIndexesR[0] = aEnd;
|
|
551
|
-
if (baDeltaLength % 2 === 0) {
|
|
552
|
-
const dMin = (nChange || baDeltaLength) / 2;
|
|
553
|
-
const dMax = (aLength + bLength) / 2;
|
|
554
|
-
for (let d = 1; d <= dMax; d += 1) {
|
|
555
|
-
iMaxF = extendPathsF(d, aEnd, bEnd, bF, isCommon, aIndexesF, iMaxF);
|
|
556
|
-
if (d < dMin) iMaxR = extendPathsR(d, aStart, bStart, bR, isCommon, aIndexesR, iMaxR);
|
|
557
|
-
else if (extendOverlappablePathsR(d, aStart, aEnd, bStart, bEnd, isCommon, aIndexesF, iMaxF, aIndexesR, iMaxR, division)) return;
|
|
558
|
-
}
|
|
559
|
-
} else {
|
|
560
|
-
const dMin = ((nChange || baDeltaLength) + 1) / 2;
|
|
561
|
-
const dMax = (aLength + bLength + 1) / 2;
|
|
562
|
-
let d = 1;
|
|
563
|
-
iMaxF = extendPathsF(d, aEnd, bEnd, bF, isCommon, aIndexesF, iMaxF);
|
|
564
|
-
for (d += 1; d <= dMax; d += 1) {
|
|
565
|
-
iMaxR = extendPathsR(d - 1, aStart, bStart, bR, isCommon, aIndexesR, iMaxR);
|
|
566
|
-
if (d < dMin) iMaxF = extendPathsF(d, aEnd, bEnd, bF, isCommon, aIndexesF, iMaxF);
|
|
567
|
-
else if (extendOverlappablePathsF(d, aStart, aEnd, bStart, bEnd, isCommon, aIndexesF, iMaxF, aIndexesR, iMaxR, division)) return;
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
/* istanbul ignore next */
|
|
571
|
-
throw new Error(`${pkg}: no overlap aStart=${aStart} aEnd=${aEnd} bStart=${bStart} bEnd=${bEnd}`);
|
|
572
|
-
};
|
|
573
|
-
const findSubsequences = (nChange, aStart, aEnd, bStart, bEnd, transposed, callbacks, aIndexesF, aIndexesR, division) => {
|
|
574
|
-
if (bEnd - bStart < aEnd - aStart) {
|
|
575
|
-
transposed = !transposed;
|
|
576
|
-
if (transposed && callbacks.length === 1) {
|
|
577
|
-
const { foundSubsequence, isCommon } = callbacks[0];
|
|
578
|
-
callbacks[1] = {
|
|
579
|
-
foundSubsequence: (nCommon, bCommon, aCommon) => {
|
|
580
|
-
foundSubsequence(nCommon, aCommon, bCommon);
|
|
581
|
-
},
|
|
582
|
-
isCommon: (bIndex, aIndex) => isCommon(aIndex, bIndex)
|
|
583
|
-
};
|
|
584
|
-
}
|
|
585
|
-
const tStart = aStart;
|
|
586
|
-
const tEnd = aEnd;
|
|
587
|
-
aStart = bStart;
|
|
588
|
-
aEnd = bEnd;
|
|
589
|
-
bStart = tStart;
|
|
590
|
-
bEnd = tEnd;
|
|
591
|
-
}
|
|
592
|
-
const { foundSubsequence, isCommon } = callbacks[transposed ? 1 : 0];
|
|
593
|
-
divide(nChange, aStart, aEnd, bStart, bEnd, isCommon, aIndexesF, aIndexesR, division);
|
|
594
|
-
const { nChangePreceding, aEndPreceding, bEndPreceding, nCommonPreceding, aCommonPreceding, bCommonPreceding, nCommonFollowing, aCommonFollowing, bCommonFollowing, nChangeFollowing, aStartFollowing, bStartFollowing } = division;
|
|
595
|
-
if (aStart < aEndPreceding && bStart < bEndPreceding) findSubsequences(nChangePreceding, aStart, aEndPreceding, bStart, bEndPreceding, transposed, callbacks, aIndexesF, aIndexesR, division);
|
|
596
|
-
if (nCommonPreceding !== 0) foundSubsequence(nCommonPreceding, aCommonPreceding, bCommonPreceding);
|
|
597
|
-
if (nCommonFollowing !== 0) foundSubsequence(nCommonFollowing, aCommonFollowing, bCommonFollowing);
|
|
598
|
-
if (aStartFollowing < aEnd && bStartFollowing < bEnd) findSubsequences(nChangeFollowing, aStartFollowing, aEnd, bStartFollowing, bEnd, transposed, callbacks, aIndexesF, aIndexesR, division);
|
|
599
|
-
};
|
|
600
|
-
const validateLength = (name, arg) => {
|
|
601
|
-
if (typeof arg !== "number") throw new TypeError(`${pkg}: ${name} typeof ${typeof arg} is not a number`);
|
|
602
|
-
if (!Number.isSafeInteger(arg)) throw new RangeError(`${pkg}: ${name} value ${arg} is not a safe integer`);
|
|
603
|
-
if (arg < 0) throw new RangeError(`${pkg}: ${name} value ${arg} is a negative integer`);
|
|
604
|
-
};
|
|
605
|
-
const validateCallback = (name, arg) => {
|
|
606
|
-
const type = typeof arg;
|
|
607
|
-
if (type !== "function") throw new TypeError(`${pkg}: ${name} typeof ${type} is not a function`);
|
|
608
|
-
};
|
|
609
|
-
function diffSequence(aLength, bLength, isCommon, foundSubsequence) {
|
|
610
|
-
validateLength("aLength", aLength);
|
|
611
|
-
validateLength("bLength", bLength);
|
|
612
|
-
validateCallback("isCommon", isCommon);
|
|
613
|
-
validateCallback("foundSubsequence", foundSubsequence);
|
|
614
|
-
const nCommonF = countCommonItemsF(0, aLength, 0, bLength, isCommon);
|
|
615
|
-
if (nCommonF !== 0) foundSubsequence(nCommonF, 0, 0);
|
|
616
|
-
if (aLength !== nCommonF || bLength !== nCommonF) {
|
|
617
|
-
const aStart = nCommonF;
|
|
618
|
-
const bStart = nCommonF;
|
|
619
|
-
const nCommonR = countCommonItemsR(aStart, aLength - 1, bStart, bLength - 1, isCommon);
|
|
620
|
-
const aEnd = aLength - nCommonR;
|
|
621
|
-
const bEnd = bLength - nCommonR;
|
|
622
|
-
const nCommonFR = nCommonF + nCommonR;
|
|
623
|
-
if (aLength !== nCommonFR && bLength !== nCommonFR) findSubsequences(0, aStart, aEnd, bStart, bEnd, false, [{
|
|
624
|
-
foundSubsequence,
|
|
625
|
-
isCommon
|
|
626
|
-
}], [NOT_YET_SET], [NOT_YET_SET], {
|
|
627
|
-
aCommonFollowing: NOT_YET_SET,
|
|
628
|
-
aCommonPreceding: NOT_YET_SET,
|
|
629
|
-
aEndPreceding: NOT_YET_SET,
|
|
630
|
-
aStartFollowing: NOT_YET_SET,
|
|
631
|
-
bCommonFollowing: NOT_YET_SET,
|
|
632
|
-
bCommonPreceding: NOT_YET_SET,
|
|
633
|
-
bEndPreceding: NOT_YET_SET,
|
|
634
|
-
bStartFollowing: NOT_YET_SET,
|
|
635
|
-
nChangeFollowing: NOT_YET_SET,
|
|
636
|
-
nChangePreceding: NOT_YET_SET,
|
|
637
|
-
nCommonFollowing: NOT_YET_SET,
|
|
638
|
-
nCommonPreceding: NOT_YET_SET
|
|
639
|
-
});
|
|
640
|
-
if (nCommonR !== 0) foundSubsequence(nCommonR, aEnd, bEnd);
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
return build;
|
|
644
|
-
}
|
|
645
|
-
var diffSequences = /* @__PURE__ */ getDefaultExportFromCjs(/* @__PURE__ */ requireBuild());
|
|
646
|
-
function formatTrailingSpaces(line, trailingSpaceFormatter) {
|
|
647
|
-
return line.replace(/\s+$/, (match) => trailingSpaceFormatter(match));
|
|
648
|
-
}
|
|
649
|
-
function printDiffLine(line, isFirstOrLast, color, indicator, trailingSpaceFormatter, emptyFirstOrLastLinePlaceholder) {
|
|
650
|
-
return line.length !== 0 ? color(`${indicator} ${formatTrailingSpaces(line, trailingSpaceFormatter)}`) : indicator !== " " ? color(indicator) : isFirstOrLast && emptyFirstOrLastLinePlaceholder.length !== 0 ? color(`${indicator} ${emptyFirstOrLastLinePlaceholder}`) : "";
|
|
651
|
-
}
|
|
652
|
-
function printDeleteLine(line, isFirstOrLast, { aColor, aIndicator, changeLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder }) {
|
|
653
|
-
return printDiffLine(line, isFirstOrLast, aColor, aIndicator, changeLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder);
|
|
654
|
-
}
|
|
655
|
-
function printInsertLine(line, isFirstOrLast, { bColor, bIndicator, changeLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder }) {
|
|
656
|
-
return printDiffLine(line, isFirstOrLast, bColor, bIndicator, changeLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder);
|
|
657
|
-
}
|
|
658
|
-
function printCommonLine(line, isFirstOrLast, { commonColor, commonIndicator, commonLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder }) {
|
|
659
|
-
return printDiffLine(line, isFirstOrLast, commonColor, commonIndicator, commonLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder);
|
|
660
|
-
}
|
|
661
|
-
function createPatchMark(aStart, aEnd, bStart, bEnd, { patchColor }) {
|
|
662
|
-
return patchColor(`@@ -${aStart + 1},${aEnd - aStart} +${bStart + 1},${bEnd - bStart} @@`);
|
|
663
|
-
}
|
|
664
|
-
function joinAlignedDiffsNoExpand(diffs, options) {
|
|
665
|
-
const iLength = diffs.length;
|
|
666
|
-
const nContextLines = options.contextLines;
|
|
667
|
-
const nContextLines2 = nContextLines + nContextLines;
|
|
668
|
-
let jLength = iLength;
|
|
669
|
-
let hasExcessAtStartOrEnd = false;
|
|
670
|
-
let nExcessesBetweenChanges = 0;
|
|
671
|
-
let i = 0;
|
|
672
|
-
while (i !== iLength) {
|
|
673
|
-
const iStart = i;
|
|
674
|
-
while (i !== iLength && diffs[i][0] === 0) i += 1;
|
|
675
|
-
if (iStart !== i) if (iStart === 0) {
|
|
676
|
-
if (i > nContextLines) {
|
|
677
|
-
jLength -= i - nContextLines;
|
|
678
|
-
hasExcessAtStartOrEnd = true;
|
|
679
|
-
}
|
|
680
|
-
} else if (i === iLength) {
|
|
681
|
-
const n = i - iStart;
|
|
682
|
-
if (n > nContextLines) {
|
|
683
|
-
jLength -= n - nContextLines;
|
|
684
|
-
hasExcessAtStartOrEnd = true;
|
|
685
|
-
}
|
|
686
|
-
} else {
|
|
687
|
-
const n = i - iStart;
|
|
688
|
-
if (n > nContextLines2) {
|
|
689
|
-
jLength -= n - nContextLines2;
|
|
690
|
-
nExcessesBetweenChanges += 1;
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
while (i !== iLength && diffs[i][0] !== 0) i += 1;
|
|
694
|
-
}
|
|
695
|
-
const hasPatch = nExcessesBetweenChanges !== 0 || hasExcessAtStartOrEnd;
|
|
696
|
-
if (nExcessesBetweenChanges !== 0) jLength += nExcessesBetweenChanges + 1;
|
|
697
|
-
else if (hasExcessAtStartOrEnd) jLength += 1;
|
|
698
|
-
const jLast = jLength - 1;
|
|
699
|
-
const lines = [];
|
|
700
|
-
let jPatchMark = 0;
|
|
701
|
-
if (hasPatch) lines.push("");
|
|
702
|
-
let aStart = 0;
|
|
703
|
-
let bStart = 0;
|
|
704
|
-
let aEnd = 0;
|
|
705
|
-
let bEnd = 0;
|
|
706
|
-
const pushCommonLine = (line) => {
|
|
707
|
-
const j = lines.length;
|
|
708
|
-
lines.push(printCommonLine(line, j === 0 || j === jLast, options));
|
|
709
|
-
aEnd += 1;
|
|
710
|
-
bEnd += 1;
|
|
711
|
-
};
|
|
712
|
-
const pushDeleteLine = (line) => {
|
|
713
|
-
const j = lines.length;
|
|
714
|
-
lines.push(printDeleteLine(line, j === 0 || j === jLast, options));
|
|
715
|
-
aEnd += 1;
|
|
716
|
-
};
|
|
717
|
-
const pushInsertLine = (line) => {
|
|
718
|
-
const j = lines.length;
|
|
719
|
-
lines.push(printInsertLine(line, j === 0 || j === jLast, options));
|
|
720
|
-
bEnd += 1;
|
|
721
|
-
};
|
|
722
|
-
i = 0;
|
|
723
|
-
while (i !== iLength) {
|
|
724
|
-
let iStart = i;
|
|
725
|
-
while (i !== iLength && diffs[i][0] === 0) i += 1;
|
|
726
|
-
if (iStart !== i) if (iStart === 0) {
|
|
727
|
-
if (i > nContextLines) {
|
|
728
|
-
iStart = i - nContextLines;
|
|
729
|
-
aStart = iStart;
|
|
730
|
-
bStart = iStart;
|
|
731
|
-
aEnd = aStart;
|
|
732
|
-
bEnd = bStart;
|
|
733
|
-
}
|
|
734
|
-
for (let iCommon = iStart; iCommon !== i; iCommon += 1) pushCommonLine(diffs[iCommon][1]);
|
|
735
|
-
} else if (i === iLength) {
|
|
736
|
-
const iEnd = i - iStart > nContextLines ? iStart + nContextLines : i;
|
|
737
|
-
for (let iCommon = iStart; iCommon !== iEnd; iCommon += 1) pushCommonLine(diffs[iCommon][1]);
|
|
738
|
-
} else {
|
|
739
|
-
const nCommon = i - iStart;
|
|
740
|
-
if (nCommon > nContextLines2) {
|
|
741
|
-
const iEnd = iStart + nContextLines;
|
|
742
|
-
for (let iCommon = iStart; iCommon !== iEnd; iCommon += 1) pushCommonLine(diffs[iCommon][1]);
|
|
743
|
-
lines[jPatchMark] = createPatchMark(aStart, aEnd, bStart, bEnd, options);
|
|
744
|
-
jPatchMark = lines.length;
|
|
745
|
-
lines.push("");
|
|
746
|
-
const nOmit = nCommon - nContextLines2;
|
|
747
|
-
aStart = aEnd + nOmit;
|
|
748
|
-
bStart = bEnd + nOmit;
|
|
749
|
-
aEnd = aStart;
|
|
750
|
-
bEnd = bStart;
|
|
751
|
-
for (let iCommon = i - nContextLines; iCommon !== i; iCommon += 1) pushCommonLine(diffs[iCommon][1]);
|
|
752
|
-
} else for (let iCommon = iStart; iCommon !== i; iCommon += 1) pushCommonLine(diffs[iCommon][1]);
|
|
753
|
-
}
|
|
754
|
-
while (i !== iLength && diffs[i][0] === -1) {
|
|
755
|
-
pushDeleteLine(diffs[i][1]);
|
|
756
|
-
i += 1;
|
|
757
|
-
}
|
|
758
|
-
while (i !== iLength && diffs[i][0] === 1) {
|
|
759
|
-
pushInsertLine(diffs[i][1]);
|
|
760
|
-
i += 1;
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
if (hasPatch) lines[jPatchMark] = createPatchMark(aStart, aEnd, bStart, bEnd, options);
|
|
764
|
-
return lines.join("\n");
|
|
765
|
-
}
|
|
766
|
-
function joinAlignedDiffsExpand(diffs, options) {
|
|
767
|
-
return diffs.map((diff, i, diffs) => {
|
|
768
|
-
const line = diff[1];
|
|
769
|
-
const isFirstOrLast = i === 0 || i === diffs.length - 1;
|
|
770
|
-
switch (diff[0]) {
|
|
771
|
-
case -1: return printDeleteLine(line, isFirstOrLast, options);
|
|
772
|
-
case 1: return printInsertLine(line, isFirstOrLast, options);
|
|
773
|
-
default: return printCommonLine(line, isFirstOrLast, options);
|
|
774
|
-
}
|
|
775
|
-
}).join("\n");
|
|
776
|
-
}
|
|
777
|
-
const noColor = (string) => string;
|
|
778
|
-
const DIFF_CONTEXT_DEFAULT = 5;
|
|
779
|
-
const DIFF_TRUNCATE_THRESHOLD_DEFAULT = 0;
|
|
780
|
-
function getDefaultOptions() {
|
|
781
|
-
return {
|
|
782
|
-
aAnnotation: "Expected",
|
|
783
|
-
aColor: y.green,
|
|
784
|
-
aIndicator: "-",
|
|
785
|
-
bAnnotation: "Received",
|
|
786
|
-
bColor: y.red,
|
|
787
|
-
bIndicator: "+",
|
|
788
|
-
changeColor: y.inverse,
|
|
789
|
-
changeLineTrailingSpaceColor: noColor,
|
|
790
|
-
commonColor: y.dim,
|
|
791
|
-
commonIndicator: " ",
|
|
792
|
-
commonLineTrailingSpaceColor: noColor,
|
|
793
|
-
compareKeys: void 0,
|
|
794
|
-
contextLines: DIFF_CONTEXT_DEFAULT,
|
|
795
|
-
emptyFirstOrLastLinePlaceholder: "",
|
|
796
|
-
expand: false,
|
|
797
|
-
includeChangeCounts: false,
|
|
798
|
-
omitAnnotationLines: false,
|
|
799
|
-
patchColor: y.yellow,
|
|
800
|
-
printBasicPrototype: false,
|
|
801
|
-
truncateThreshold: DIFF_TRUNCATE_THRESHOLD_DEFAULT,
|
|
802
|
-
truncateAnnotation: "... Diff result is truncated",
|
|
803
|
-
truncateAnnotationColor: noColor
|
|
804
|
-
};
|
|
805
|
-
}
|
|
806
|
-
function getCompareKeys(compareKeys) {
|
|
807
|
-
return compareKeys && typeof compareKeys === "function" ? compareKeys : void 0;
|
|
808
|
-
}
|
|
809
|
-
function getContextLines(contextLines) {
|
|
810
|
-
return typeof contextLines === "number" && Number.isSafeInteger(contextLines) && contextLines >= 0 ? contextLines : DIFF_CONTEXT_DEFAULT;
|
|
811
|
-
}
|
|
812
|
-
function normalizeDiffOptions(options = {}) {
|
|
813
|
-
return {
|
|
814
|
-
...getDefaultOptions(),
|
|
815
|
-
...options,
|
|
816
|
-
compareKeys: getCompareKeys(options.compareKeys),
|
|
817
|
-
contextLines: getContextLines(options.contextLines)
|
|
818
|
-
};
|
|
819
|
-
}
|
|
820
|
-
function isEmptyString(lines) {
|
|
821
|
-
return lines.length === 1 && lines[0].length === 0;
|
|
822
|
-
}
|
|
823
|
-
function countChanges(diffs) {
|
|
824
|
-
let a = 0;
|
|
825
|
-
let b = 0;
|
|
826
|
-
diffs.forEach((diff) => {
|
|
827
|
-
switch (diff[0]) {
|
|
828
|
-
case -1:
|
|
829
|
-
a += 1;
|
|
830
|
-
break;
|
|
831
|
-
case 1:
|
|
832
|
-
b += 1;
|
|
833
|
-
break;
|
|
834
|
-
}
|
|
835
|
-
});
|
|
836
|
-
return {
|
|
837
|
-
a,
|
|
838
|
-
b
|
|
839
|
-
};
|
|
840
|
-
}
|
|
841
|
-
function printAnnotation({ aAnnotation, aColor, aIndicator, bAnnotation, bColor, bIndicator, includeChangeCounts, omitAnnotationLines }, changeCounts) {
|
|
842
|
-
if (omitAnnotationLines) return "";
|
|
843
|
-
let aRest = "";
|
|
844
|
-
let bRest = "";
|
|
845
|
-
if (includeChangeCounts) {
|
|
846
|
-
const aCount = String(changeCounts.a);
|
|
847
|
-
const bCount = String(changeCounts.b);
|
|
848
|
-
const baAnnotationLengthDiff = bAnnotation.length - aAnnotation.length;
|
|
849
|
-
const aAnnotationPadding = " ".repeat(Math.max(0, baAnnotationLengthDiff));
|
|
850
|
-
const bAnnotationPadding = " ".repeat(Math.max(0, -baAnnotationLengthDiff));
|
|
851
|
-
const baCountLengthDiff = bCount.length - aCount.length;
|
|
852
|
-
const aCountPadding = " ".repeat(Math.max(0, baCountLengthDiff));
|
|
853
|
-
const bCountPadding = " ".repeat(Math.max(0, -baCountLengthDiff));
|
|
854
|
-
aRest = `${aAnnotationPadding} ${aIndicator} ${aCountPadding}${aCount}`;
|
|
855
|
-
bRest = `${bAnnotationPadding} ${bIndicator} ${bCountPadding}${bCount}`;
|
|
856
|
-
}
|
|
857
|
-
const a = `${aIndicator} ${aAnnotation}${aRest}`;
|
|
858
|
-
const b = `${bIndicator} ${bAnnotation}${bRest}`;
|
|
859
|
-
return `${aColor(a)}\n${bColor(b)}\n\n`;
|
|
860
|
-
}
|
|
861
|
-
function printDiffLines(diffs, truncated, options) {
|
|
862
|
-
return printAnnotation(options, countChanges(diffs)) + (options.expand ? joinAlignedDiffsExpand(diffs, options) : joinAlignedDiffsNoExpand(diffs, options)) + (truncated ? options.truncateAnnotationColor(`\n${options.truncateAnnotation}`) : "");
|
|
863
|
-
}
|
|
864
|
-
function diffLinesUnified(aLines, bLines, options) {
|
|
865
|
-
const normalizedOptions = normalizeDiffOptions(options);
|
|
866
|
-
const [diffs, truncated] = diffLinesRaw(isEmptyString(aLines) ? [] : aLines, isEmptyString(bLines) ? [] : bLines, normalizedOptions);
|
|
867
|
-
return printDiffLines(diffs, truncated, normalizedOptions);
|
|
868
|
-
}
|
|
869
|
-
function diffLinesUnified2(aLinesDisplay, bLinesDisplay, aLinesCompare, bLinesCompare, options) {
|
|
870
|
-
if (isEmptyString(aLinesDisplay) && isEmptyString(aLinesCompare)) {
|
|
871
|
-
aLinesDisplay = [];
|
|
872
|
-
aLinesCompare = [];
|
|
873
|
-
}
|
|
874
|
-
if (isEmptyString(bLinesDisplay) && isEmptyString(bLinesCompare)) {
|
|
875
|
-
bLinesDisplay = [];
|
|
876
|
-
bLinesCompare = [];
|
|
877
|
-
}
|
|
878
|
-
if (aLinesDisplay.length !== aLinesCompare.length || bLinesDisplay.length !== bLinesCompare.length) return diffLinesUnified(aLinesDisplay, bLinesDisplay, options);
|
|
879
|
-
const [diffs, truncated] = diffLinesRaw(aLinesCompare, bLinesCompare, options);
|
|
880
|
-
let aIndex = 0;
|
|
881
|
-
let bIndex = 0;
|
|
882
|
-
diffs.forEach((diff) => {
|
|
883
|
-
switch (diff[0]) {
|
|
884
|
-
case -1:
|
|
885
|
-
diff[1] = aLinesDisplay[aIndex];
|
|
886
|
-
aIndex += 1;
|
|
887
|
-
break;
|
|
888
|
-
case 1:
|
|
889
|
-
diff[1] = bLinesDisplay[bIndex];
|
|
890
|
-
bIndex += 1;
|
|
891
|
-
break;
|
|
892
|
-
default:
|
|
893
|
-
diff[1] = bLinesDisplay[bIndex];
|
|
894
|
-
aIndex += 1;
|
|
895
|
-
bIndex += 1;
|
|
896
|
-
}
|
|
897
|
-
});
|
|
898
|
-
return printDiffLines(diffs, truncated, normalizeDiffOptions(options));
|
|
899
|
-
}
|
|
900
|
-
function diffLinesRaw(aLines, bLines, options) {
|
|
901
|
-
const truncate = options?.truncateThreshold ?? false;
|
|
902
|
-
const truncateThreshold = Math.max(Math.floor(options?.truncateThreshold ?? 0), 0);
|
|
903
|
-
const aLength = truncate ? Math.min(aLines.length, truncateThreshold) : aLines.length;
|
|
904
|
-
const bLength = truncate ? Math.min(bLines.length, truncateThreshold) : bLines.length;
|
|
905
|
-
const truncated = aLength !== aLines.length || bLength !== bLines.length;
|
|
906
|
-
const isCommon = (aIndex, bIndex) => aLines[aIndex] === bLines[bIndex];
|
|
907
|
-
const diffs = [];
|
|
908
|
-
let aIndex = 0;
|
|
909
|
-
let bIndex = 0;
|
|
910
|
-
const foundSubsequence = (nCommon, aCommon, bCommon) => {
|
|
911
|
-
for (; aIndex !== aCommon; aIndex += 1) diffs.push(new Diff(-1, aLines[aIndex]));
|
|
912
|
-
for (; bIndex !== bCommon; bIndex += 1) diffs.push(new Diff(1, bLines[bIndex]));
|
|
913
|
-
for (; nCommon !== 0; nCommon -= 1, aIndex += 1, bIndex += 1) diffs.push(new Diff(0, bLines[bIndex]));
|
|
914
|
-
};
|
|
915
|
-
diffSequences(aLength, bLength, isCommon, foundSubsequence);
|
|
916
|
-
for (; aIndex !== aLength; aIndex += 1) diffs.push(new Diff(-1, aLines[aIndex]));
|
|
917
|
-
for (; bIndex !== bLength; bIndex += 1) diffs.push(new Diff(1, bLines[bIndex]));
|
|
918
|
-
return [diffs, truncated];
|
|
919
|
-
}
|
|
920
|
-
function getType(value) {
|
|
921
|
-
if (value === void 0) return "undefined";
|
|
922
|
-
else if (value === null) return "null";
|
|
923
|
-
else if (Array.isArray(value)) return "array";
|
|
924
|
-
else if (typeof value === "boolean") return "boolean";
|
|
925
|
-
else if (typeof value === "function") return "function";
|
|
926
|
-
else if (typeof value === "number") return "number";
|
|
927
|
-
else if (typeof value === "string") return "string";
|
|
928
|
-
else if (typeof value === "bigint") return "bigint";
|
|
929
|
-
else if (typeof value === "object") {
|
|
930
|
-
if (value != null) {
|
|
931
|
-
if (value.constructor === RegExp) return "regexp";
|
|
932
|
-
else if (value.constructor === Map) return "map";
|
|
933
|
-
else if (value.constructor === Set) return "set";
|
|
934
|
-
else if (value.constructor === Date) return "date";
|
|
935
|
-
}
|
|
936
|
-
return "object";
|
|
937
|
-
} else if (typeof value === "symbol") return "symbol";
|
|
938
|
-
throw new Error(`value of unknown type: ${value}`);
|
|
939
|
-
}
|
|
940
|
-
function getNewLineSymbol(string) {
|
|
941
|
-
return string.includes("\r\n") ? "\r\n" : "\n";
|
|
942
|
-
}
|
|
943
|
-
function diffStrings(a, b, options) {
|
|
944
|
-
const truncate = options?.truncateThreshold ?? false;
|
|
945
|
-
const truncateThreshold = Math.max(Math.floor(options?.truncateThreshold ?? 0), 0);
|
|
946
|
-
let aLength = a.length;
|
|
947
|
-
let bLength = b.length;
|
|
948
|
-
if (truncate) {
|
|
949
|
-
const aMultipleLines = a.includes("\n");
|
|
950
|
-
const bMultipleLines = b.includes("\n");
|
|
951
|
-
const aNewLineSymbol = getNewLineSymbol(a);
|
|
952
|
-
const bNewLineSymbol = getNewLineSymbol(b);
|
|
953
|
-
const _a = aMultipleLines ? `${a.split(aNewLineSymbol, truncateThreshold).join(aNewLineSymbol)}\n` : a;
|
|
954
|
-
const _b = bMultipleLines ? `${b.split(bNewLineSymbol, truncateThreshold).join(bNewLineSymbol)}\n` : b;
|
|
955
|
-
aLength = _a.length;
|
|
956
|
-
bLength = _b.length;
|
|
957
|
-
}
|
|
958
|
-
const truncated = aLength !== a.length || bLength !== b.length;
|
|
959
|
-
const isCommon = (aIndex, bIndex) => a[aIndex] === b[bIndex];
|
|
960
|
-
let aIndex = 0;
|
|
961
|
-
let bIndex = 0;
|
|
962
|
-
const diffs = [];
|
|
963
|
-
const foundSubsequence = (nCommon, aCommon, bCommon) => {
|
|
964
|
-
if (aIndex !== aCommon) diffs.push(new Diff(-1, a.slice(aIndex, aCommon)));
|
|
965
|
-
if (bIndex !== bCommon) diffs.push(new Diff(1, b.slice(bIndex, bCommon)));
|
|
966
|
-
aIndex = aCommon + nCommon;
|
|
967
|
-
bIndex = bCommon + nCommon;
|
|
968
|
-
diffs.push(new Diff(0, b.slice(bCommon, bIndex)));
|
|
969
|
-
};
|
|
970
|
-
diffSequences(aLength, bLength, isCommon, foundSubsequence);
|
|
971
|
-
if (aIndex !== aLength) diffs.push(new Diff(-1, a.slice(aIndex)));
|
|
972
|
-
if (bIndex !== bLength) diffs.push(new Diff(1, b.slice(bIndex)));
|
|
973
|
-
return [diffs, truncated];
|
|
974
|
-
}
|
|
975
|
-
function concatenateRelevantDiffs(op, diffs, changeColor) {
|
|
976
|
-
return diffs.reduce((reduced, diff) => reduced + (diff[0] === 0 ? diff[1] : diff[0] === op && diff[1].length !== 0 ? changeColor(diff[1]) : ""), "");
|
|
977
|
-
}
|
|
978
|
-
var ChangeBuffer = class {
|
|
979
|
-
op;
|
|
980
|
-
line;
|
|
981
|
-
lines;
|
|
982
|
-
changeColor;
|
|
983
|
-
constructor(op, changeColor) {
|
|
984
|
-
this.op = op;
|
|
985
|
-
this.line = [];
|
|
986
|
-
this.lines = [];
|
|
987
|
-
this.changeColor = changeColor;
|
|
988
|
-
}
|
|
989
|
-
pushSubstring(substring) {
|
|
990
|
-
this.pushDiff(new Diff(this.op, substring));
|
|
991
|
-
}
|
|
992
|
-
pushLine() {
|
|
993
|
-
this.lines.push(this.line.length !== 1 ? new Diff(this.op, concatenateRelevantDiffs(this.op, this.line, this.changeColor)) : this.line[0][0] === this.op ? this.line[0] : new Diff(this.op, this.line[0][1]));
|
|
994
|
-
this.line.length = 0;
|
|
995
|
-
}
|
|
996
|
-
isLineEmpty() {
|
|
997
|
-
return this.line.length === 0;
|
|
998
|
-
}
|
|
999
|
-
pushDiff(diff) {
|
|
1000
|
-
this.line.push(diff);
|
|
1001
|
-
}
|
|
1002
|
-
align(diff) {
|
|
1003
|
-
const string = diff[1];
|
|
1004
|
-
if (string.includes("\n")) {
|
|
1005
|
-
const substrings = string.split("\n");
|
|
1006
|
-
const iLast = substrings.length - 1;
|
|
1007
|
-
substrings.forEach((substring, i) => {
|
|
1008
|
-
if (i < iLast) {
|
|
1009
|
-
this.pushSubstring(substring);
|
|
1010
|
-
this.pushLine();
|
|
1011
|
-
} else if (substring.length !== 0) this.pushSubstring(substring);
|
|
1012
|
-
});
|
|
1013
|
-
} else this.pushDiff(diff);
|
|
1014
|
-
}
|
|
1015
|
-
moveLinesTo(lines) {
|
|
1016
|
-
if (!this.isLineEmpty()) this.pushLine();
|
|
1017
|
-
lines.push(...this.lines);
|
|
1018
|
-
this.lines.length = 0;
|
|
1019
|
-
}
|
|
1020
|
-
};
|
|
1021
|
-
var CommonBuffer = class {
|
|
1022
|
-
deleteBuffer;
|
|
1023
|
-
insertBuffer;
|
|
1024
|
-
lines;
|
|
1025
|
-
constructor(deleteBuffer, insertBuffer) {
|
|
1026
|
-
this.deleteBuffer = deleteBuffer;
|
|
1027
|
-
this.insertBuffer = insertBuffer;
|
|
1028
|
-
this.lines = [];
|
|
1029
|
-
}
|
|
1030
|
-
pushDiffCommonLine(diff) {
|
|
1031
|
-
this.lines.push(diff);
|
|
1032
|
-
}
|
|
1033
|
-
pushDiffChangeLines(diff) {
|
|
1034
|
-
const isDiffEmpty = diff[1].length === 0;
|
|
1035
|
-
if (!isDiffEmpty || this.deleteBuffer.isLineEmpty()) this.deleteBuffer.pushDiff(diff);
|
|
1036
|
-
if (!isDiffEmpty || this.insertBuffer.isLineEmpty()) this.insertBuffer.pushDiff(diff);
|
|
1037
|
-
}
|
|
1038
|
-
flushChangeLines() {
|
|
1039
|
-
this.deleteBuffer.moveLinesTo(this.lines);
|
|
1040
|
-
this.insertBuffer.moveLinesTo(this.lines);
|
|
1041
|
-
}
|
|
1042
|
-
align(diff) {
|
|
1043
|
-
const op = diff[0];
|
|
1044
|
-
const string = diff[1];
|
|
1045
|
-
if (string.includes("\n")) {
|
|
1046
|
-
const substrings = string.split("\n");
|
|
1047
|
-
const iLast = substrings.length - 1;
|
|
1048
|
-
substrings.forEach((substring, i) => {
|
|
1049
|
-
if (i === 0) {
|
|
1050
|
-
const subdiff = new Diff(op, substring);
|
|
1051
|
-
if (this.deleteBuffer.isLineEmpty() && this.insertBuffer.isLineEmpty()) {
|
|
1052
|
-
this.flushChangeLines();
|
|
1053
|
-
this.pushDiffCommonLine(subdiff);
|
|
1054
|
-
} else {
|
|
1055
|
-
this.pushDiffChangeLines(subdiff);
|
|
1056
|
-
this.flushChangeLines();
|
|
1057
|
-
}
|
|
1058
|
-
} else if (i < iLast) this.pushDiffCommonLine(new Diff(op, substring));
|
|
1059
|
-
else if (substring.length !== 0) this.pushDiffChangeLines(new Diff(op, substring));
|
|
1060
|
-
});
|
|
1061
|
-
} else this.pushDiffChangeLines(diff);
|
|
1062
|
-
}
|
|
1063
|
-
getLines() {
|
|
1064
|
-
this.flushChangeLines();
|
|
1065
|
-
return this.lines;
|
|
1066
|
-
}
|
|
1067
|
-
};
|
|
1068
|
-
function getAlignedDiffs(diffs, changeColor) {
|
|
1069
|
-
const deleteBuffer = new ChangeBuffer(-1, changeColor);
|
|
1070
|
-
const insertBuffer = new ChangeBuffer(1, changeColor);
|
|
1071
|
-
const commonBuffer = new CommonBuffer(deleteBuffer, insertBuffer);
|
|
1072
|
-
diffs.forEach((diff) => {
|
|
1073
|
-
switch (diff[0]) {
|
|
1074
|
-
case -1:
|
|
1075
|
-
deleteBuffer.align(diff);
|
|
1076
|
-
break;
|
|
1077
|
-
case 1:
|
|
1078
|
-
insertBuffer.align(diff);
|
|
1079
|
-
break;
|
|
1080
|
-
default: commonBuffer.align(diff);
|
|
1081
|
-
}
|
|
1082
|
-
});
|
|
1083
|
-
return commonBuffer.getLines();
|
|
1084
|
-
}
|
|
1085
|
-
function hasCommonDiff(diffs, isMultiline) {
|
|
1086
|
-
if (isMultiline) {
|
|
1087
|
-
const iLast = diffs.length - 1;
|
|
1088
|
-
return diffs.some((diff, i) => diff[0] === 0 && (i !== iLast || diff[1] !== "\n"));
|
|
1089
|
-
}
|
|
1090
|
-
return diffs.some((diff) => diff[0] === 0);
|
|
1091
|
-
}
|
|
1092
|
-
function diffStringsUnified(a, b, options) {
|
|
1093
|
-
if (a !== b && a.length !== 0 && b.length !== 0) {
|
|
1094
|
-
const isMultiline = a.includes("\n") || b.includes("\n");
|
|
1095
|
-
const [diffs, truncated] = diffStringsRaw(isMultiline ? `${a}\n` : a, isMultiline ? `${b}\n` : b, true, options);
|
|
1096
|
-
if (hasCommonDiff(diffs, isMultiline)) {
|
|
1097
|
-
const optionsNormalized = normalizeDiffOptions(options);
|
|
1098
|
-
return printDiffLines(getAlignedDiffs(diffs, optionsNormalized.changeColor), truncated, optionsNormalized);
|
|
1099
|
-
}
|
|
1100
|
-
}
|
|
1101
|
-
return diffLinesUnified(a.split("\n"), b.split("\n"), options);
|
|
1102
|
-
}
|
|
1103
|
-
function diffStringsRaw(a, b, cleanup, options) {
|
|
1104
|
-
const [diffs, truncated] = diffStrings(a, b, options);
|
|
1105
|
-
if (cleanup) diff_cleanupSemantic(diffs);
|
|
1106
|
-
return [diffs, truncated];
|
|
1107
|
-
}
|
|
1108
|
-
function getCommonMessage(message, options) {
|
|
1109
|
-
const { commonColor } = normalizeDiffOptions(options);
|
|
1110
|
-
return commonColor(message);
|
|
1111
|
-
}
|
|
1112
|
-
const { AsymmetricMatcher, DOMCollection, DOMElement, Immutable, ReactElement, ReactTestComponent } = plugins;
|
|
1113
|
-
const PLUGINS = [
|
|
1114
|
-
ReactTestComponent,
|
|
1115
|
-
ReactElement,
|
|
1116
|
-
DOMElement,
|
|
1117
|
-
DOMCollection,
|
|
1118
|
-
Immutable,
|
|
1119
|
-
AsymmetricMatcher,
|
|
1120
|
-
plugins.Error
|
|
1121
|
-
];
|
|
1122
|
-
const FORMAT_OPTIONS = {
|
|
1123
|
-
maxDepth: 20,
|
|
1124
|
-
plugins: PLUGINS
|
|
1125
|
-
};
|
|
1126
|
-
const FALLBACK_FORMAT_OPTIONS = {
|
|
1127
|
-
callToJSON: false,
|
|
1128
|
-
maxDepth: 8,
|
|
1129
|
-
plugins: PLUGINS
|
|
1130
|
-
};
|
|
1131
|
-
/**
|
|
1132
|
-
* @param a Expected value
|
|
1133
|
-
* @param b Received value
|
|
1134
|
-
* @param options Diff options
|
|
1135
|
-
* @returns {string | null} a string diff
|
|
1136
|
-
*/
|
|
1137
|
-
function diff(a, b, options) {
|
|
1138
|
-
if (Object.is(a, b)) return "";
|
|
1139
|
-
const aType = getType(a);
|
|
1140
|
-
let expectedType = aType;
|
|
1141
|
-
let omitDifference = false;
|
|
1142
|
-
if (aType === "object" && typeof a.asymmetricMatch === "function") {
|
|
1143
|
-
if (a.$$typeof !== Symbol.for("jest.asymmetricMatcher")) return;
|
|
1144
|
-
if (typeof a.getExpectedType !== "function") return;
|
|
1145
|
-
expectedType = a.getExpectedType();
|
|
1146
|
-
omitDifference = expectedType === "string";
|
|
1147
|
-
}
|
|
1148
|
-
if (expectedType !== getType(b)) {
|
|
1149
|
-
const { aAnnotation, aColor, aIndicator, bAnnotation, bColor, bIndicator } = normalizeDiffOptions(options);
|
|
1150
|
-
const formatOptions = getFormatOptions(FALLBACK_FORMAT_OPTIONS, options);
|
|
1151
|
-
let aDisplay = format(a, formatOptions);
|
|
1152
|
-
let bDisplay = format(b, formatOptions);
|
|
1153
|
-
const MAX_LENGTH = 1e5;
|
|
1154
|
-
function truncate(s) {
|
|
1155
|
-
return s.length <= MAX_LENGTH ? s : `${s.slice(0, MAX_LENGTH)}...`;
|
|
1156
|
-
}
|
|
1157
|
-
aDisplay = truncate(aDisplay);
|
|
1158
|
-
bDisplay = truncate(bDisplay);
|
|
1159
|
-
return `${`${aColor(`${aIndicator} ${aAnnotation}:`)}\n${aDisplay}`}\n\n${`${bColor(`${bIndicator} ${bAnnotation}:`)}\n${bDisplay}`}`;
|
|
1160
|
-
}
|
|
1161
|
-
if (omitDifference) return;
|
|
1162
|
-
switch (aType) {
|
|
1163
|
-
case "string": return diffLinesUnified(a.split("\n"), b.split("\n"), options);
|
|
1164
|
-
case "boolean":
|
|
1165
|
-
case "number": return comparePrimitive(a, b, options);
|
|
1166
|
-
case "map": return compareObjects(sortMap(a), sortMap(b), options);
|
|
1167
|
-
case "set": return compareObjects(sortSet(a), sortSet(b), options);
|
|
1168
|
-
default: return compareObjects(a, b, options);
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
function comparePrimitive(a, b, options) {
|
|
1172
|
-
const aFormat = format(a, FORMAT_OPTIONS);
|
|
1173
|
-
const bFormat = format(b, FORMAT_OPTIONS);
|
|
1174
|
-
return aFormat === bFormat ? "" : diffLinesUnified(aFormat.split("\n"), bFormat.split("\n"), options);
|
|
1175
|
-
}
|
|
1176
|
-
function sortMap(map) {
|
|
1177
|
-
return new Map(Array.from(map.entries()).sort());
|
|
1178
|
-
}
|
|
1179
|
-
function sortSet(set) {
|
|
1180
|
-
return new Set(Array.from(set.values()).sort());
|
|
1181
|
-
}
|
|
1182
|
-
function compareObjects(a, b, options) {
|
|
1183
|
-
let difference;
|
|
1184
|
-
let hasThrown = false;
|
|
1185
|
-
try {
|
|
1186
|
-
difference = getObjectsDifference(a, b, getFormatOptions(FORMAT_OPTIONS, options), options);
|
|
1187
|
-
} catch {
|
|
1188
|
-
hasThrown = true;
|
|
1189
|
-
}
|
|
1190
|
-
const noDiffMessage = getCommonMessage(NO_DIFF_MESSAGE, options);
|
|
1191
|
-
if (difference === void 0 || difference === noDiffMessage) {
|
|
1192
|
-
difference = getObjectsDifference(a, b, getFormatOptions(FALLBACK_FORMAT_OPTIONS, options), options);
|
|
1193
|
-
if (difference !== noDiffMessage && !hasThrown) difference = `${getCommonMessage(SIMILAR_MESSAGE, options)}\n\n${difference}`;
|
|
1194
|
-
}
|
|
1195
|
-
return difference;
|
|
1196
|
-
}
|
|
1197
|
-
function getFormatOptions(formatOptions, options) {
|
|
1198
|
-
const { compareKeys, printBasicPrototype, maxDepth } = normalizeDiffOptions(options);
|
|
1199
|
-
return {
|
|
1200
|
-
...formatOptions,
|
|
1201
|
-
compareKeys,
|
|
1202
|
-
printBasicPrototype,
|
|
1203
|
-
maxDepth: maxDepth ?? formatOptions.maxDepth
|
|
1204
|
-
};
|
|
1205
|
-
}
|
|
1206
|
-
function getObjectsDifference(a, b, formatOptions, options) {
|
|
1207
|
-
const formatOptionsZeroIndent = {
|
|
1208
|
-
...formatOptions,
|
|
1209
|
-
indent: 0
|
|
1210
|
-
};
|
|
1211
|
-
const aCompare = format(a, formatOptionsZeroIndent);
|
|
1212
|
-
const bCompare = format(b, formatOptionsZeroIndent);
|
|
1213
|
-
if (aCompare === bCompare) return getCommonMessage(NO_DIFF_MESSAGE, options);
|
|
1214
|
-
else {
|
|
1215
|
-
const aDisplay = format(a, formatOptions);
|
|
1216
|
-
const bDisplay = format(b, formatOptions);
|
|
1217
|
-
return diffLinesUnified2(aDisplay.split("\n"), bDisplay.split("\n"), aCompare.split("\n"), bCompare.split("\n"), options);
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
const MAX_DIFF_STRING_LENGTH = 2e4;
|
|
1221
|
-
function isAsymmetricMatcher(data) {
|
|
1222
|
-
return getType$1(data) === "Object" && typeof data.asymmetricMatch === "function";
|
|
1223
|
-
}
|
|
1224
|
-
function isReplaceable(obj1, obj2) {
|
|
1225
|
-
const obj1Type = getType$1(obj1);
|
|
1226
|
-
return obj1Type === getType$1(obj2) && (obj1Type === "Object" || obj1Type === "Array");
|
|
1227
|
-
}
|
|
1228
|
-
function printDiffOrStringify(received, expected, options) {
|
|
1229
|
-
const { aAnnotation, bAnnotation } = normalizeDiffOptions(options);
|
|
1230
|
-
if (typeof expected === "string" && typeof received === "string" && expected.length > 0 && received.length > 0 && expected.length <= MAX_DIFF_STRING_LENGTH && received.length <= MAX_DIFF_STRING_LENGTH && expected !== received) {
|
|
1231
|
-
if (expected.includes("\n") || received.includes("\n")) return diffStringsUnified(expected, received, options);
|
|
1232
|
-
const [diffs] = diffStringsRaw(expected, received, true);
|
|
1233
|
-
const hasCommonDiff = diffs.some((diff) => diff[0] === 0);
|
|
1234
|
-
const printLabel = getLabelPrinter(aAnnotation, bAnnotation);
|
|
1235
|
-
return `${printLabel(aAnnotation) + printExpected(getCommonAndChangedSubstrings(diffs, -1, hasCommonDiff))}\n${printLabel(bAnnotation) + printReceived(getCommonAndChangedSubstrings(diffs, 1, hasCommonDiff))}`;
|
|
1236
|
-
}
|
|
1237
|
-
const clonedExpected = deepClone(expected, { forceWritable: true });
|
|
1238
|
-
const { replacedExpected, replacedActual } = replaceAsymmetricMatcher(deepClone(received, { forceWritable: true }), clonedExpected);
|
|
1239
|
-
return diff(replacedExpected, replacedActual, options);
|
|
1240
|
-
}
|
|
1241
|
-
function replaceAsymmetricMatcher(actual, expected, actualReplaced = /* @__PURE__ */ new WeakSet(), expectedReplaced = /* @__PURE__ */ new WeakSet()) {
|
|
1242
|
-
if (actual instanceof Error && expected instanceof Error && typeof actual.cause !== "undefined" && typeof expected.cause === "undefined") {
|
|
1243
|
-
delete actual.cause;
|
|
1244
|
-
return {
|
|
1245
|
-
replacedActual: actual,
|
|
1246
|
-
replacedExpected: expected
|
|
1247
|
-
};
|
|
1248
|
-
}
|
|
1249
|
-
if (!isReplaceable(actual, expected)) return {
|
|
1250
|
-
replacedActual: actual,
|
|
1251
|
-
replacedExpected: expected
|
|
1252
|
-
};
|
|
1253
|
-
if (actualReplaced.has(actual) || expectedReplaced.has(expected)) return {
|
|
1254
|
-
replacedActual: actual,
|
|
1255
|
-
replacedExpected: expected
|
|
1256
|
-
};
|
|
1257
|
-
actualReplaced.add(actual);
|
|
1258
|
-
expectedReplaced.add(expected);
|
|
1259
|
-
getOwnProperties(expected).forEach((key) => {
|
|
1260
|
-
const expectedValue = expected[key];
|
|
1261
|
-
const actualValue = actual[key];
|
|
1262
|
-
if (isAsymmetricMatcher(expectedValue)) {
|
|
1263
|
-
if (expectedValue.asymmetricMatch(actualValue)) expected[key] = actualValue;
|
|
1264
|
-
else if ("sample" in expectedValue && expectedValue.sample !== void 0 && isReplaceable(actualValue, expectedValue.sample)) {
|
|
1265
|
-
const replaced = replaceAsymmetricMatcher(actualValue, expectedValue.sample, actualReplaced, expectedReplaced);
|
|
1266
|
-
actual[key] = replaced.replacedActual;
|
|
1267
|
-
expected[key] = replaced.replacedExpected;
|
|
1268
|
-
}
|
|
1269
|
-
} else if (isAsymmetricMatcher(actualValue)) {
|
|
1270
|
-
if (actualValue.asymmetricMatch(expectedValue)) actual[key] = expectedValue;
|
|
1271
|
-
else if ("sample" in actualValue && actualValue.sample !== void 0 && isReplaceable(actualValue.sample, expectedValue)) {
|
|
1272
|
-
const replaced = replaceAsymmetricMatcher(actualValue.sample, expectedValue, actualReplaced, expectedReplaced);
|
|
1273
|
-
actual[key] = replaced.replacedActual;
|
|
1274
|
-
expected[key] = replaced.replacedExpected;
|
|
1275
|
-
}
|
|
1276
|
-
} else if (isReplaceable(actualValue, expectedValue)) {
|
|
1277
|
-
const replaced = replaceAsymmetricMatcher(actualValue, expectedValue, actualReplaced, expectedReplaced);
|
|
1278
|
-
actual[key] = replaced.replacedActual;
|
|
1279
|
-
expected[key] = replaced.replacedExpected;
|
|
1280
|
-
}
|
|
1281
|
-
});
|
|
1282
|
-
return {
|
|
1283
|
-
replacedActual: actual,
|
|
1284
|
-
replacedExpected: expected
|
|
1285
|
-
};
|
|
1286
|
-
}
|
|
1287
|
-
function getLabelPrinter(...strings) {
|
|
1288
|
-
const maxLength = strings.reduce((max, string) => string.length > max ? string.length : max, 0);
|
|
1289
|
-
return (string) => `${string}: ${" ".repeat(maxLength - string.length)}`;
|
|
1290
|
-
}
|
|
1291
|
-
const SPACE_SYMBOL = "·";
|
|
1292
|
-
function replaceTrailingSpaces(text) {
|
|
1293
|
-
return text.replace(/\s+$/gm, (spaces) => SPACE_SYMBOL.repeat(spaces.length));
|
|
1294
|
-
}
|
|
1295
|
-
function printReceived(object) {
|
|
1296
|
-
return y.red(replaceTrailingSpaces(stringify(object)));
|
|
1297
|
-
}
|
|
1298
|
-
function printExpected(value) {
|
|
1299
|
-
return y.green(replaceTrailingSpaces(stringify(value)));
|
|
1300
|
-
}
|
|
1301
|
-
function getCommonAndChangedSubstrings(diffs, op, hasCommonDiff) {
|
|
1302
|
-
return diffs.reduce((reduced, diff) => reduced + (diff[0] === 0 ? diff[1] : diff[0] === op ? hasCommonDiff ? y.inverse(diff[1]) : diff[1] : ""), "");
|
|
1303
|
-
}
|
|
1304
|
-
//#endregion
|
|
1305
|
-
export { diff, printDiffOrStringify };
|
|
1306
|
-
|
|
1307
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlmZi5qcyIsIm5hbWVzIjpbImMiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHZpdGVzdCt1dGlsc0A0LjEuMi9ub2RlX21vZHVsZXMvQHZpdGVzdC91dGlscy9kaXN0L2RpZmYuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcGx1Z2lucywgZm9ybWF0IH0gZnJvbSAnQHZpdGVzdC9wcmV0dHktZm9ybWF0JztcbmltcG9ydCBjIGZyb20gJ3RpbnlyYWluYm93JztcbmltcG9ydCB7IHN0cmluZ2lmeSB9IGZyb20gJy4vZGlzcGxheS5qcyc7XG5pbXBvcnQgeyBkZWVwQ2xvbmUsIGdldE93blByb3BlcnRpZXMsIGdldFR5cGUgYXMgZ2V0VHlwZSQxIH0gZnJvbSAnLi9oZWxwZXJzLmpzJztcbmltcG9ydCAnLi9jb25zdGFudHMuanMnO1xuXG4vKipcbiogRGlmZiBNYXRjaCBhbmQgUGF0Y2hcbiogQ29weXJpZ2h0IDIwMTggVGhlIGRpZmYtbWF0Y2gtcGF0Y2ggQXV0aG9ycy5cbiogaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9kaWZmLW1hdGNoLXBhdGNoXG4qXG4qIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4qIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4qXG4qICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4qXG4qIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG4vKipcbiogQGZpbGVvdmVydmlldyBDb21wdXRlcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHR3byB0ZXh0cyB0byBjcmVhdGUgYSBwYXRjaC5cbiogQXBwbGllcyB0aGUgcGF0Y2ggb250byBhbm90aGVyIHRleHQsIGFsbG93aW5nIGZvciBlcnJvcnMuXG4qIEBhdXRob3IgZnJhc2VyQGdvb2dsZS5jb20gKE5laWwgRnJhc2VyKVxuKi9cbi8qKlxuKiBDSEFOR0VTIGJ5IHBlZHJvdHRpbWFyayB0byBkaWZmX21hdGNoX3BhdGNoX3VuY29tcHJlc3NlZC50cyBmaWxlOlxuKlxuKiAxLiBEZWxldGUgYW55dGhpbmcgbm90IG5lZWRlZCB0byB1c2UgZGlmZl9jbGVhbnVwU2VtYW50aWMgbWV0aG9kXG4qIDIuIENvbnZlcnQgZnJvbSBwcm90b3R5cGUgcHJvcGVydGllcyB0byB2YXIgZGVjbGFyYXRpb25zXG4qIDMuIENvbnZlcnQgRGlmZiB0byBjbGFzcyBmcm9tIGNvbnN0cnVjdG9yIGFuZCBwcm90b3R5cGVcbiogNC4gQWRkIHR5cGUgYW5ub3RhdGlvbnMgZm9yIGFyZ3VtZW50cyBhbmQgcmV0dXJuIHZhbHVlc1xuKiA1LiBBZGQgZXhwb3J0c1xuKi9cbi8qKlxuKiBUaGUgZGF0YSBzdHJ1Y3R1cmUgcmVwcmVzZW50aW5nIGEgZGlmZiBpcyBhbiBhcnJheSBvZiB0dXBsZXM6XG4qIFtbRElGRl9ERUxFVEUsICdIZWxsbyddLCBbRElGRl9JTlNFUlQsICdHb29kYnllJ10sIFtESUZGX0VRVUFMLCAnIHdvcmxkLiddXVxuKiB3aGljaCBtZWFuczogZGVsZXRlICdIZWxsbycsIGFkZCAnR29vZGJ5ZScgYW5kIGtlZXAgJyB3b3JsZC4nXG4qL1xuY29uc3QgRElGRl9ERUxFVEUgPSAtMTtcbmNvbnN0IERJRkZfSU5TRVJUID0gMTtcbmNvbnN0IERJRkZfRVFVQUwgPSAwO1xuLyoqXG4qIENsYXNzIHJlcHJlc2VudGluZyBvbmUgZGlmZiB0dXBsZS5cbiogQXR0ZW1wdHMgdG8gbG9vayBsaWtlIGEgdHdvLWVsZW1lbnQgYXJyYXkgKHdoaWNoIGlzIHdoYXQgdGhpcyB1c2VkIHRvIGJlKS5cbiogQHBhcmFtIHtudW1iZXJ9IG9wIE9wZXJhdGlvbiwgb25lIG9mOiBESUZGX0RFTEVURSwgRElGRl9JTlNFUlQsIERJRkZfRVFVQUwuXG4qIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IFRleHQgdG8gYmUgZGVsZXRlZCwgaW5zZXJ0ZWQsIG9yIHJldGFpbmVkLlxuKiBAY29uc3RydWN0b3JcbiovXG5jbGFzcyBEaWZmIHtcblx0MDtcblx0MTtcblx0Y29uc3RydWN0b3Iob3AsIHRleHQpIHtcblx0XHR0aGlzWzBdID0gb3A7XG5cdFx0dGhpc1sxXSA9IHRleHQ7XG5cdH1cbn1cbi8qKlxuKiBEZXRlcm1pbmUgdGhlIGNvbW1vbiBwcmVmaXggb2YgdHdvIHN0cmluZ3MuXG4qIEBwYXJhbSB7c3RyaW5nfSB0ZXh0MSBGaXJzdCBzdHJpbmcuXG4qIEBwYXJhbSB7c3RyaW5nfSB0ZXh0MiBTZWNvbmQgc3RyaW5nLlxuKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBjb21tb24gdG8gdGhlIHN0YXJ0IG9mIGVhY2hcbiogICAgIHN0cmluZy5cbiovXG5mdW5jdGlvbiBkaWZmX2NvbW1vblByZWZpeCh0ZXh0MSwgdGV4dDIpIHtcblx0Ly8gUXVpY2sgY2hlY2sgZm9yIGNvbW1vbiBudWxsIGNhc2VzLlxuXHRpZiAoIXRleHQxIHx8ICF0ZXh0MiB8fCB0ZXh0MS5jaGFyQXQoMCkgIT09IHRleHQyLmNoYXJBdCgwKSkge1xuXHRcdHJldHVybiAwO1xuXHR9XG5cdC8vIEJpbmFyeSBzZWFyY2guXG5cdC8vIFBlcmZvcm1hbmNlIGFuYWx5c2lzOiBodHRwczovL25laWwuZnJhc2VyLm5hbWUvbmV3cy8yMDA3LzEwLzA5L1xuXHRsZXQgcG9pbnRlcm1pbiA9IDA7XG5cdGxldCBwb2ludGVybWF4ID0gTWF0aC5taW4odGV4dDEubGVuZ3RoLCB0ZXh0Mi5sZW5ndGgpO1xuXHRsZXQgcG9pbnRlcm1pZCA9IHBvaW50ZXJtYXg7XG5cdGxldCBwb2ludGVyc3RhcnQgPSAwO1xuXHR3aGlsZSAocG9pbnRlcm1pbiA8IHBvaW50ZXJtaWQpIHtcblx0XHRpZiAodGV4dDEuc3Vic3RyaW5nKHBvaW50ZXJzdGFydCwgcG9pbnRlcm1pZCkgPT09IHRleHQyLnN1YnN0cmluZyhwb2ludGVyc3RhcnQsIHBvaW50ZXJtaWQpKSB7XG5cdFx0XHRwb2ludGVybWluID0gcG9pbnRlcm1pZDtcblx0XHRcdHBvaW50ZXJzdGFydCA9IHBvaW50ZXJtaW47XG5cdFx0fSBlbHNlIHtcblx0XHRcdHBvaW50ZXJtYXggPSBwb2ludGVybWlkO1xuXHRcdH1cblx0XHRwb2ludGVybWlkID0gTWF0aC5mbG9vcigocG9pbnRlcm1heCAtIHBvaW50ZXJtaW4pIC8gMiArIHBvaW50ZXJtaW4pO1xuXHR9XG5cdHJldHVybiBwb2ludGVybWlkO1xufVxuLyoqXG4qIERldGVybWluZSB0aGUgY29tbW9uIHN1ZmZpeCBvZiB0d28gc3RyaW5ncy5cbiogQHBhcmFtIHtzdHJpbmd9IHRleHQxIEZpcnN0IHN0cmluZy5cbiogQHBhcmFtIHtzdHJpbmd9IHRleHQyIFNlY29uZCBzdHJpbmcuXG4qIEByZXR1cm4ge251bWJlcn0gVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGNvbW1vbiB0byB0aGUgZW5kIG9mIGVhY2ggc3RyaW5nLlxuKi9cbmZ1bmN0aW9uIGRpZmZfY29tbW9uU3VmZml4KHRleHQxLCB0ZXh0Mikge1xuXHQvLyBRdWljayBjaGVjayBmb3IgY29tbW9uIG51bGwgY2FzZXMuXG5cdGlmICghdGV4dDEgfHwgIXRleHQyIHx8IHRleHQxLmNoYXJBdCh0ZXh0MS5sZW5ndGggLSAxKSAhPT0gdGV4dDIuY2hhckF0KHRleHQyLmxlbmd0aCAtIDEpKSB7XG5cdFx0cmV0dXJuIDA7XG5cdH1cblx0Ly8gQmluYXJ5IHNlYXJjaC5cblx0Ly8gUGVyZm9ybWFuY2UgYW5hbHlzaXM6IGh0dHBzOi8vbmVpbC5mcmFzZXIubmFtZS9uZXdzLzIwMDcvMTAvMDkvXG5cdGxldCBwb2ludGVybWluID0gMDtcblx0bGV0IHBvaW50ZXJtYXggPSBNYXRoLm1pbih0ZXh0MS5sZW5ndGgsIHRleHQyLmxlbmd0aCk7XG5cdGxldCBwb2ludGVybWlkID0gcG9pbnRlcm1heDtcblx0bGV0IHBvaW50ZXJlbmQgPSAwO1xuXHR3aGlsZSAocG9pbnRlcm1pbiA8IHBvaW50ZXJtaWQpIHtcblx0XHRpZiAodGV4dDEuc3Vic3RyaW5nKHRleHQxLmxlbmd0aCAtIHBvaW50ZXJtaWQsIHRleHQxLmxlbmd0aCAtIHBvaW50ZXJlbmQpID09PSB0ZXh0Mi5zdWJzdHJpbmcodGV4dDIubGVuZ3RoIC0gcG9pbnRlcm1pZCwgdGV4dDIubGVuZ3RoIC0gcG9pbnRlcmVuZCkpIHtcblx0XHRcdHBvaW50ZXJtaW4gPSBwb2ludGVybWlkO1xuXHRcdFx0cG9pbnRlcmVuZCA9IHBvaW50ZXJtaW47XG5cdFx0fSBlbHNlIHtcblx0XHRcdHBvaW50ZXJtYXggPSBwb2ludGVybWlkO1xuXHRcdH1cblx0XHRwb2ludGVybWlkID0gTWF0aC5mbG9vcigocG9pbnRlcm1heCAtIHBvaW50ZXJtaW4pIC8gMiArIHBvaW50ZXJtaW4pO1xuXHR9XG5cdHJldHVybiBwb2ludGVybWlkO1xufVxuLyoqXG4qIERldGVybWluZSBpZiB0aGUgc3VmZml4IG9mIG9uZSBzdHJpbmcgaXMgdGhlIHByZWZpeCBvZiBhbm90aGVyLlxuKiBAcGFyYW0ge3N0cmluZ30gdGV4dDEgRmlyc3Qgc3RyaW5nLlxuKiBAcGFyYW0ge3N0cmluZ30gdGV4dDIgU2Vjb25kIHN0cmluZy5cbiogQHJldHVybiB7bnVtYmVyfSBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgY29tbW9uIHRvIHRoZSBlbmQgb2YgdGhlIGZpcnN0XG4qICAgICBzdHJpbmcgYW5kIHRoZSBzdGFydCBvZiB0aGUgc2Vjb25kIHN0cmluZy5cbiogQHByaXZhdGVcbiovXG5mdW5jdGlvbiBkaWZmX2NvbW1vbk92ZXJsYXBfKHRleHQxLCB0ZXh0Mikge1xuXHQvLyBDYWNoZSB0aGUgdGV4dCBsZW5ndGhzIHRvIHByZXZlbnQgbXVsdGlwbGUgY2FsbHMuXG5cdGNvbnN0IHRleHQxX2xlbmd0aCA9IHRleHQxLmxlbmd0aDtcblx0Y29uc3QgdGV4dDJfbGVuZ3RoID0gdGV4dDIubGVuZ3RoO1xuXHQvLyBFbGltaW5hdGUgdGhlIG51bGwgY2FzZS5cblx0aWYgKHRleHQxX2xlbmd0aCA9PT0gMCB8fCB0ZXh0Ml9sZW5ndGggPT09IDApIHtcblx0XHRyZXR1cm4gMDtcblx0fVxuXHQvLyBUcnVuY2F0ZSB0aGUgbG9uZ2VyIHN0cmluZy5cblx0aWYgKHRleHQxX2xlbmd0aCA+IHRleHQyX2xlbmd0aCkge1xuXHRcdHRleHQxID0gdGV4dDEuc3Vic3RyaW5nKHRleHQxX2xlbmd0aCAtIHRleHQyX2xlbmd0aCk7XG5cdH0gZWxzZSBpZiAodGV4dDFfbGVuZ3RoIDwgdGV4dDJfbGVuZ3RoKSB7XG5cdFx0dGV4dDIgPSB0ZXh0Mi5zdWJzdHJpbmcoMCwgdGV4dDFfbGVuZ3RoKTtcblx0fVxuXHRjb25zdCB0ZXh0X2xlbmd0aCA9IE1hdGgubWluKHRleHQxX2xlbmd0aCwgdGV4dDJfbGVuZ3RoKTtcblx0Ly8gUXVpY2sgY2hlY2sgZm9yIHRoZSB3b3JzdCBjYXNlLlxuXHRpZiAodGV4dDEgPT09IHRleHQyKSB7XG5cdFx0cmV0dXJuIHRleHRfbGVuZ3RoO1xuXHR9XG5cdC8vIFN0YXJ0IGJ5IGxvb2tpbmcgZm9yIGEgc2luZ2xlIGNoYXJhY3RlciBtYXRjaFxuXHQvLyBhbmQgaW5jcmVhc2UgbGVuZ3RoIHVudGlsIG5vIG1hdGNoIGlzIGZvdW5kLlxuXHQvLyBQZXJmb3JtYW5jZSBhbmFseXNpczogaHR0cHM6Ly9uZWlsLmZyYXNlci5uYW1lL25ld3MvMjAxMC8xMS8wNC9cblx0bGV0IGJlc3QgPSAwO1xuXHRsZXQgbGVuZ3RoID0gMTtcblx0d2hpbGUgKHRydWUpIHtcblx0XHRjb25zdCBwYXR0ZXJuID0gdGV4dDEuc3Vic3RyaW5nKHRleHRfbGVuZ3RoIC0gbGVuZ3RoKTtcblx0XHRjb25zdCBmb3VuZCA9IHRleHQyLmluZGV4T2YocGF0dGVybik7XG5cdFx0aWYgKGZvdW5kID09PSAtMSkge1xuXHRcdFx0cmV0dXJuIGJlc3Q7XG5cdFx0fVxuXHRcdGxlbmd0aCArPSBmb3VuZDtcblx0XHRpZiAoZm91bmQgPT09IDAgfHwgdGV4dDEuc3Vic3RyaW5nKHRleHRfbGVuZ3RoIC0gbGVuZ3RoKSA9PT0gdGV4dDIuc3Vic3RyaW5nKDAsIGxlbmd0aCkpIHtcblx0XHRcdGJlc3QgPSBsZW5ndGg7XG5cdFx0XHRsZW5ndGgrKztcblx0XHR9XG5cdH1cbn1cbi8qKlxuKiBSZWR1Y2UgdGhlIG51bWJlciBvZiBlZGl0cyBieSBlbGltaW5hdGluZyBzZW1hbnRpY2FsbHkgdHJpdmlhbCBlcXVhbGl0aWVzLlxuKiBAcGFyYW0geyFBcnJheS48IWRpZmZfbWF0Y2hfcGF0Y2guRGlmZj59IGRpZmZzIEFycmF5IG9mIGRpZmYgdHVwbGVzLlxuKi9cbmZ1bmN0aW9uIGRpZmZfY2xlYW51cFNlbWFudGljKGRpZmZzKSB7XG5cdGxldCBjaGFuZ2VzID0gZmFsc2U7XG5cdGNvbnN0IGVxdWFsaXRpZXMgPSBbXTtcblx0bGV0IGVxdWFsaXRpZXNMZW5ndGggPSAwO1xuXHQvKiogQHR5cGUgez9zdHJpbmd9ICovXG5cdGxldCBsYXN0RXF1YWxpdHkgPSBudWxsO1xuXHQvLyBBbHdheXMgZXF1YWwgdG8gZGlmZnNbZXF1YWxpdGllc1tlcXVhbGl0aWVzTGVuZ3RoIC0gMV1dWzFdXG5cdGxldCBwb2ludGVyID0gMDtcblx0Ly8gTnVtYmVyIG9mIGNoYXJhY3RlcnMgdGhhdCBjaGFuZ2VkIHByaW9yIHRvIHRoZSBlcXVhbGl0eS5cblx0bGV0IGxlbmd0aF9pbnNlcnRpb25zMSA9IDA7XG5cdGxldCBsZW5ndGhfZGVsZXRpb25zMSA9IDA7XG5cdC8vIE51bWJlciBvZiBjaGFyYWN0ZXJzIHRoYXQgY2hhbmdlZCBhZnRlciB0aGUgZXF1YWxpdHkuXG5cdGxldCBsZW5ndGhfaW5zZXJ0aW9uczIgPSAwO1xuXHRsZXQgbGVuZ3RoX2RlbGV0aW9uczIgPSAwO1xuXHR3aGlsZSAocG9pbnRlciA8IGRpZmZzLmxlbmd0aCkge1xuXHRcdGlmIChkaWZmc1twb2ludGVyXVswXSA9PT0gRElGRl9FUVVBTCkge1xuXHRcdFx0Ly8gRXF1YWxpdHkgZm91bmQuXG5cdFx0XHRlcXVhbGl0aWVzW2VxdWFsaXRpZXNMZW5ndGgrK10gPSBwb2ludGVyO1xuXHRcdFx0bGVuZ3RoX2luc2VydGlvbnMxID0gbGVuZ3RoX2luc2VydGlvbnMyO1xuXHRcdFx0bGVuZ3RoX2RlbGV0aW9uczEgPSBsZW5ndGhfZGVsZXRpb25zMjtcblx0XHRcdGxlbmd0aF9pbnNlcnRpb25zMiA9IDA7XG5cdFx0XHRsZW5ndGhfZGVsZXRpb25zMiA9IDA7XG5cdFx0XHRsYXN0RXF1YWxpdHkgPSBkaWZmc1twb2ludGVyXVsxXTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gQW4gaW5zZXJ0aW9uIG9yIGRlbGV0aW9uLlxuXHRcdFx0aWYgKGRpZmZzW3BvaW50ZXJdWzBdID09PSBESUZGX0lOU0VSVCkge1xuXHRcdFx0XHRsZW5ndGhfaW5zZXJ0aW9uczIgKz0gZGlmZnNbcG9pbnRlcl1bMV0ubGVuZ3RoO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bGVuZ3RoX2RlbGV0aW9uczIgKz0gZGlmZnNbcG9pbnRlcl1bMV0ubGVuZ3RoO1xuXHRcdFx0fVxuXHRcdFx0Ly8gRWxpbWluYXRlIGFuIGVxdWFsaXR5IHRoYXQgaXMgc21hbGxlciBvciBlcXVhbCB0byB0aGUgZWRpdHMgb24gYm90aFxuXHRcdFx0Ly8gc2lkZXMgb2YgaXQuXG5cdFx0XHRpZiAobGFzdEVxdWFsaXR5ICYmIGxhc3RFcXVhbGl0eS5sZW5ndGggPD0gTWF0aC5tYXgobGVuZ3RoX2luc2VydGlvbnMxLCBsZW5ndGhfZGVsZXRpb25zMSkgJiYgbGFzdEVxdWFsaXR5Lmxlbmd0aCA8PSBNYXRoLm1heChsZW5ndGhfaW5zZXJ0aW9uczIsIGxlbmd0aF9kZWxldGlvbnMyKSkge1xuXHRcdFx0XHQvLyBEdXBsaWNhdGUgcmVjb3JkLlxuXHRcdFx0XHRkaWZmcy5zcGxpY2UoZXF1YWxpdGllc1tlcXVhbGl0aWVzTGVuZ3RoIC0gMV0sIDAsIG5ldyBEaWZmKERJRkZfREVMRVRFLCBsYXN0RXF1YWxpdHkpKTtcblx0XHRcdFx0Ly8gQ2hhbmdlIHNlY29uZCBjb3B5IHRvIGluc2VydC5cblx0XHRcdFx0ZGlmZnNbZXF1YWxpdGllc1tlcXVhbGl0aWVzTGVuZ3RoIC0gMV0gKyAxXVswXSA9IERJRkZfSU5TRVJUO1xuXHRcdFx0XHQvLyBUaHJvdyBhd2F5IHRoZSBlcXVhbGl0eSB3ZSBqdXN0IGRlbGV0ZWQuXG5cdFx0XHRcdGVxdWFsaXRpZXNMZW5ndGgtLTtcblx0XHRcdFx0Ly8gVGhyb3cgYXdheSB0aGUgcHJldmlvdXMgZXF1YWxpdHkgKGl0IG5lZWRzIHRvIGJlIHJlZXZhbHVhdGVkKS5cblx0XHRcdFx0ZXF1YWxpdGllc0xlbmd0aC0tO1xuXHRcdFx0XHRwb2ludGVyID0gZXF1YWxpdGllc0xlbmd0aCA+IDAgPyBlcXVhbGl0aWVzW2VxdWFsaXRpZXNMZW5ndGggLSAxXSA6IC0xO1xuXHRcdFx0XHRsZW5ndGhfaW5zZXJ0aW9uczEgPSAwO1xuXHRcdFx0XHRsZW5ndGhfZGVsZXRpb25zMSA9IDA7XG5cdFx0XHRcdGxlbmd0aF9pbnNlcnRpb25zMiA9IDA7XG5cdFx0XHRcdGxlbmd0aF9kZWxldGlvbnMyID0gMDtcblx0XHRcdFx0bGFzdEVxdWFsaXR5ID0gbnVsbDtcblx0XHRcdFx0Y2hhbmdlcyA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHBvaW50ZXIrKztcblx0fVxuXHQvLyBOb3JtYWxpemUgdGhlIGRpZmYuXG5cdGlmIChjaGFuZ2VzKSB7XG5cdFx0ZGlmZl9jbGVhbnVwTWVyZ2UoZGlmZnMpO1xuXHR9XG5cdGRpZmZfY2xlYW51cFNlbWFudGljTG9zc2xlc3MoZGlmZnMpO1xuXHQvLyBGaW5kIGFueSBvdmVybGFwcyBiZXR3ZWVuIGRlbGV0aW9ucyBhbmQgaW5zZXJ0aW9ucy5cblx0Ly8gZS5nOiA8ZGVsPmFiY3h4eDwvZGVsPjxpbnM+eHh4ZGVmPC9pbnM+XG5cdC8vICAgLT4gPGRlbD5hYmM8L2RlbD54eHg8aW5zPmRlZjwvaW5zPlxuXHQvLyBlLmc6IDxkZWw+eHh4YWJjPC9kZWw+PGlucz5kZWZ4eHg8L2lucz5cblx0Ly8gICAtPiA8aW5zPmRlZjwvaW5zPnh4eDxkZWw+YWJjPC9kZWw+XG5cdC8vIE9ubHkgZXh0cmFjdCBhbiBvdmVybGFwIGlmIGl0IGlzIGFzIGJpZyBhcyB0aGUgZWRpdCBhaGVhZCBvciBiZWhpbmQgaXQuXG5cdHBvaW50ZXIgPSAxO1xuXHR3aGlsZSAocG9pbnRlciA8IGRpZmZzLmxlbmd0aCkge1xuXHRcdGlmIChkaWZmc1twb2ludGVyIC0gMV1bMF0gPT09IERJRkZfREVMRVRFICYmIGRpZmZzW3BvaW50ZXJdWzBdID09PSBESUZGX0lOU0VSVCkge1xuXHRcdFx0Y29uc3QgZGVsZXRpb24gPSBkaWZmc1twb2ludGVyIC0gMV1bMV07XG5cdFx0XHRjb25zdCBpbnNlcnRpb24gPSBkaWZmc1twb2ludGVyXVsxXTtcblx0XHRcdGNvbnN0IG92ZXJsYXBfbGVuZ3RoMSA9IGRpZmZfY29tbW9uT3ZlcmxhcF8oZGVsZXRpb24sIGluc2VydGlvbik7XG5cdFx0XHRjb25zdCBvdmVybGFwX2xlbmd0aDIgPSBkaWZmX2NvbW1vbk92ZXJsYXBfKGluc2VydGlvbiwgZGVsZXRpb24pO1xuXHRcdFx0aWYgKG92ZXJsYXBfbGVuZ3RoMSA+PSBvdmVybGFwX2xlbmd0aDIpIHtcblx0XHRcdFx0aWYgKG92ZXJsYXBfbGVuZ3RoMSA+PSBkZWxldGlvbi5sZW5ndGggLyAyIHx8IG92ZXJsYXBfbGVuZ3RoMSA+PSBpbnNlcnRpb24ubGVuZ3RoIC8gMikge1xuXHRcdFx0XHRcdC8vIE92ZXJsYXAgZm91bmQuICBJbnNlcnQgYW4gZXF1YWxpdHkgYW5kIHRyaW0gdGhlIHN1cnJvdW5kaW5nIGVkaXRzLlxuXHRcdFx0XHRcdGRpZmZzLnNwbGljZShwb2ludGVyLCAwLCBuZXcgRGlmZihESUZGX0VRVUFMLCBpbnNlcnRpb24uc3Vic3RyaW5nKDAsIG92ZXJsYXBfbGVuZ3RoMSkpKTtcblx0XHRcdFx0XHRkaWZmc1twb2ludGVyIC0gMV1bMV0gPSBkZWxldGlvbi5zdWJzdHJpbmcoMCwgZGVsZXRpb24ubGVuZ3RoIC0gb3ZlcmxhcF9sZW5ndGgxKTtcblx0XHRcdFx0XHRkaWZmc1twb2ludGVyICsgMV1bMV0gPSBpbnNlcnRpb24uc3Vic3RyaW5nKG92ZXJsYXBfbGVuZ3RoMSk7XG5cdFx0XHRcdFx0cG9pbnRlcisrO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpZiAob3ZlcmxhcF9sZW5ndGgyID49IGRlbGV0aW9uLmxlbmd0aCAvIDIgfHwgb3ZlcmxhcF9sZW5ndGgyID49IGluc2VydGlvbi5sZW5ndGggLyAyKSB7XG5cdFx0XHRcdFx0Ly8gUmV2ZXJzZSBvdmVybGFwIGZvdW5kLlxuXHRcdFx0XHRcdC8vIEluc2VydCBhbiBlcXVhbGl0eSBhbmQgc3dhcCBhbmQgdHJpbSB0aGUgc3Vycm91bmRpbmcgZWRpdHMuXG5cdFx0XHRcdFx0ZGlmZnMuc3BsaWNlKHBvaW50ZXIsIDAsIG5ldyBEaWZmKERJRkZfRVFVQUwsIGRlbGV0aW9uLnN1YnN0cmluZygwLCBvdmVybGFwX2xlbmd0aDIpKSk7XG5cdFx0XHRcdFx0ZGlmZnNbcG9pbnRlciAtIDFdWzBdID0gRElGRl9JTlNFUlQ7XG5cdFx0XHRcdFx0ZGlmZnNbcG9pbnRlciAtIDFdWzFdID0gaW5zZXJ0aW9uLnN1YnN0cmluZygwLCBpbnNlcnRpb24ubGVuZ3RoIC0gb3ZlcmxhcF9sZW5ndGgyKTtcblx0XHRcdFx0XHRkaWZmc1twb2ludGVyICsgMV1bMF0gPSBESUZGX0RFTEVURTtcblx0XHRcdFx0XHRkaWZmc1twb2ludGVyICsgMV1bMV0gPSBkZWxldGlvbi5zdWJzdHJpbmcob3ZlcmxhcF9sZW5ndGgyKTtcblx0XHRcdFx0XHRwb2ludGVyKys7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHBvaW50ZXIrKztcblx0XHR9XG5cdFx0cG9pbnRlcisrO1xuXHR9XG59XG4vLyBEZWZpbmUgc29tZSByZWdleCBwYXR0ZXJucyBmb3IgbWF0Y2hpbmcgYm91bmRhcmllcy5cbmNvbnN0IG5vbkFscGhhTnVtZXJpY1JlZ2V4XyA9IC9bXmEtejAtOV0vaTtcbmNvbnN0IHdoaXRlc3BhY2VSZWdleF8gPSAvXFxzLztcbmNvbnN0IGxpbmVicmVha1JlZ2V4XyA9IC9bXFxyXFxuXS87XG5jb25zdCBibGFua2xpbmVFbmRSZWdleF8gPSAvXFxuXFxyP1xcbiQvO1xuY29uc3QgYmxhbmtsaW5lU3RhcnRSZWdleF8gPSAvXlxccj9cXG5cXHI/XFxuLztcbi8qKlxuKiBMb29rIGZvciBzaW5nbGUgZWRpdHMgc3Vycm91bmRlZCBvbiBib3RoIHNpZGVzIGJ5IGVxdWFsaXRpZXNcbiogd2hpY2ggY2FuIGJlIHNoaWZ0ZWQgc2lkZXdheXMgdG8gYWxpZ24gdGhlIGVkaXQgdG8gYSB3b3JkIGJvdW5kYXJ5LlxuKiBlLmc6IFRoZSBjPGlucz5hdCBjPC9pbnM+YW1lLiAtPiBUaGUgPGlucz5jYXQgPC9pbnM+Y2FtZS5cbiogQHBhcmFtIHshQXJyYXkuPCFkaWZmX21hdGNoX3BhdGNoLkRpZmY+fSBkaWZmcyBBcnJheSBvZiBkaWZmIHR1cGxlcy5cbiovXG5mdW5jdGlvbiBkaWZmX2NsZWFudXBTZW1hbnRpY0xvc3NsZXNzKGRpZmZzKSB7XG5cdGxldCBwb2ludGVyID0gMTtcblx0Ly8gSW50ZW50aW9uYWxseSBpZ25vcmUgdGhlIGZpcnN0IGFuZCBsYXN0IGVsZW1lbnQgKGRvbid0IG5lZWQgY2hlY2tpbmcpLlxuXHR3aGlsZSAocG9pbnRlciA8IGRpZmZzLmxlbmd0aCAtIDEpIHtcblx0XHRpZiAoZGlmZnNbcG9pbnRlciAtIDFdWzBdID09PSBESUZGX0VRVUFMICYmIGRpZmZzW3BvaW50ZXIgKyAxXVswXSA9PT0gRElGRl9FUVVBTCkge1xuXHRcdFx0Ly8gVGhpcyBpcyBhIHNpbmdsZSBlZGl0IHN1cnJvdW5kZWQgYnkgZXF1YWxpdGllcy5cblx0XHRcdGxldCBlcXVhbGl0eTEgPSBkaWZmc1twb2ludGVyIC0gMV1bMV07XG5cdFx0XHRsZXQgZWRpdCA9IGRpZmZzW3BvaW50ZXJdWzFdO1xuXHRcdFx0bGV0IGVxdWFsaXR5MiA9IGRpZmZzW3BvaW50ZXIgKyAxXVsxXTtcblx0XHRcdC8vIEZpcnN0LCBzaGlmdCB0aGUgZWRpdCBhcyBmYXIgbGVmdCBhcyBwb3NzaWJsZS5cblx0XHRcdGNvbnN0IGNvbW1vbk9mZnNldCA9IGRpZmZfY29tbW9uU3VmZml4KGVxdWFsaXR5MSwgZWRpdCk7XG5cdFx0XHRpZiAoY29tbW9uT2Zmc2V0KSB7XG5cdFx0XHRcdGNvbnN0IGNvbW1vblN0cmluZyA9IGVkaXQuc3Vic3RyaW5nKGVkaXQubGVuZ3RoIC0gY29tbW9uT2Zmc2V0KTtcblx0XHRcdFx0ZXF1YWxpdHkxID0gZXF1YWxpdHkxLnN1YnN0cmluZygwLCBlcXVhbGl0eTEubGVuZ3RoIC0gY29tbW9uT2Zmc2V0KTtcblx0XHRcdFx0ZWRpdCA9IGNvbW1vblN0cmluZyArIGVkaXQuc3Vic3RyaW5nKDAsIGVkaXQubGVuZ3RoIC0gY29tbW9uT2Zmc2V0KTtcblx0XHRcdFx0ZXF1YWxpdHkyID0gY29tbW9uU3RyaW5nICsgZXF1YWxpdHkyO1xuXHRcdFx0fVxuXHRcdFx0Ly8gU2Vjb25kLCBzdGVwIGNoYXJhY3RlciBieSBjaGFyYWN0ZXIgcmlnaHQsIGxvb2tpbmcgZm9yIHRoZSBiZXN0IGZpdC5cblx0XHRcdGxldCBiZXN0RXF1YWxpdHkxID0gZXF1YWxpdHkxO1xuXHRcdFx0bGV0IGJlc3RFZGl0ID0gZWRpdDtcblx0XHRcdGxldCBiZXN0RXF1YWxpdHkyID0gZXF1YWxpdHkyO1xuXHRcdFx0bGV0IGJlc3RTY29yZSA9IGRpZmZfY2xlYW51cFNlbWFudGljU2NvcmVfKGVxdWFsaXR5MSwgZWRpdCkgKyBkaWZmX2NsZWFudXBTZW1hbnRpY1Njb3JlXyhlZGl0LCBlcXVhbGl0eTIpO1xuXHRcdFx0d2hpbGUgKGVkaXQuY2hhckF0KDApID09PSBlcXVhbGl0eTIuY2hhckF0KDApKSB7XG5cdFx0XHRcdGVxdWFsaXR5MSArPSBlZGl0LmNoYXJBdCgwKTtcblx0XHRcdFx0ZWRpdCA9IGVkaXQuc3Vic3RyaW5nKDEpICsgZXF1YWxpdHkyLmNoYXJBdCgwKTtcblx0XHRcdFx0ZXF1YWxpdHkyID0gZXF1YWxpdHkyLnN1YnN0cmluZygxKTtcblx0XHRcdFx0Y29uc3Qgc2NvcmUgPSBkaWZmX2NsZWFudXBTZW1hbnRpY1Njb3JlXyhlcXVhbGl0eTEsIGVkaXQpICsgZGlmZl9jbGVhbnVwU2VtYW50aWNTY29yZV8oZWRpdCwgZXF1YWxpdHkyKTtcblx0XHRcdFx0Ly8gVGhlID49IGVuY291cmFnZXMgdHJhaWxpbmcgcmF0aGVyIHRoYW4gbGVhZGluZyB3aGl0ZXNwYWNlIG9uIGVkaXRzLlxuXHRcdFx0XHRpZiAoc2NvcmUgPj0gYmVzdFNjb3JlKSB7XG5cdFx0XHRcdFx0YmVzdFNjb3JlID0gc2NvcmU7XG5cdFx0XHRcdFx0YmVzdEVxdWFsaXR5MSA9IGVxdWFsaXR5MTtcblx0XHRcdFx0XHRiZXN0RWRpdCA9IGVkaXQ7XG5cdFx0XHRcdFx0YmVzdEVxdWFsaXR5MiA9IGVxdWFsaXR5Mjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKGRpZmZzW3BvaW50ZXIgLSAxXVsxXSAhPT0gYmVzdEVxdWFsaXR5MSkge1xuXHRcdFx0XHQvLyBXZSBoYXZlIGFuIGltcHJvdmVtZW50LCBzYXZlIGl0IGJhY2sgdG8gdGhlIGRpZmYuXG5cdFx0XHRcdGlmIChiZXN0RXF1YWxpdHkxKSB7XG5cdFx0XHRcdFx0ZGlmZnNbcG9pbnRlciAtIDFdWzFdID0gYmVzdEVxdWFsaXR5MTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRkaWZmcy5zcGxpY2UocG9pbnRlciAtIDEsIDEpO1xuXHRcdFx0XHRcdHBvaW50ZXItLTtcblx0XHRcdFx0fVxuXHRcdFx0XHRkaWZmc1twb2ludGVyXVsxXSA9IGJlc3RFZGl0O1xuXHRcdFx0XHRpZiAoYmVzdEVxdWFsaXR5Mikge1xuXHRcdFx0XHRcdGRpZmZzW3BvaW50ZXIgKyAxXVsxXSA9IGJlc3RFcXVhbGl0eTI7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZGlmZnMuc3BsaWNlKHBvaW50ZXIgKyAxLCAxKTtcblx0XHRcdFx0XHRwb2ludGVyLS07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cG9pbnRlcisrO1xuXHR9XG59XG4vKipcbiogUmVvcmRlciBhbmQgbWVyZ2UgbGlrZSBlZGl0IHNlY3Rpb25zLiAgTWVyZ2UgZXF1YWxpdGllcy5cbiogQW55IGVkaXQgc2VjdGlvbiBjYW4gbW92ZSBhcyBsb25nIGFzIGl0IGRvZXNuJ3QgY3Jvc3MgYW4gZXF1YWxpdHkuXG4qIEBwYXJhbSB7IUFycmF5LjwhZGlmZl9tYXRjaF9wYXRjaC5EaWZmPn0gZGlmZnMgQXJyYXkgb2YgZGlmZiB0dXBsZXMuXG4qL1xuZnVuY3Rpb24gZGlmZl9jbGVhbnVwTWVyZ2UoZGlmZnMpIHtcblx0Ly8gQWRkIGEgZHVtbXkgZW50cnkgYXQgdGhlIGVuZC5cblx0ZGlmZnMucHVzaChuZXcgRGlmZihESUZGX0VRVUFMLCBcIlwiKSk7XG5cdGxldCBwb2ludGVyID0gMDtcblx0bGV0IGNvdW50X2RlbGV0ZSA9IDA7XG5cdGxldCBjb3VudF9pbnNlcnQgPSAwO1xuXHRsZXQgdGV4dF9kZWxldGUgPSBcIlwiO1xuXHRsZXQgdGV4dF9pbnNlcnQgPSBcIlwiO1xuXHRsZXQgY29tbW9ubGVuZ3RoO1xuXHR3aGlsZSAocG9pbnRlciA8IGRpZmZzLmxlbmd0aCkge1xuXHRcdHN3aXRjaCAoZGlmZnNbcG9pbnRlcl1bMF0pIHtcblx0XHRcdGNhc2UgRElGRl9JTlNFUlQ6XG5cdFx0XHRcdGNvdW50X2luc2VydCsrO1xuXHRcdFx0XHR0ZXh0X2luc2VydCArPSBkaWZmc1twb2ludGVyXVsxXTtcblx0XHRcdFx0cG9pbnRlcisrO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgRElGRl9ERUxFVEU6XG5cdFx0XHRcdGNvdW50X2RlbGV0ZSsrO1xuXHRcdFx0XHR0ZXh0X2RlbGV0ZSArPSBkaWZmc1twb2ludGVyXVsxXTtcblx0XHRcdFx0cG9pbnRlcisrO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgRElGRl9FUVVBTDpcblx0XHRcdFx0Ly8gVXBvbiByZWFjaGluZyBhbiBlcXVhbGl0eSwgY2hlY2sgZm9yIHByaW9yIHJlZHVuZGFuY2llcy5cblx0XHRcdFx0aWYgKGNvdW50X2RlbGV0ZSArIGNvdW50X2luc2VydCA+IDEpIHtcblx0XHRcdFx0XHRpZiAoY291bnRfZGVsZXRlICE9PSAwICYmIGNvdW50X2luc2VydCAhPT0gMCkge1xuXHRcdFx0XHRcdFx0Ly8gRmFjdG9yIG91dCBhbnkgY29tbW9uIHByZWZpeGVzLlxuXHRcdFx0XHRcdFx0Y29tbW9ubGVuZ3RoID0gZGlmZl9jb21tb25QcmVmaXgodGV4dF9pbnNlcnQsIHRleHRfZGVsZXRlKTtcblx0XHRcdFx0XHRcdGlmIChjb21tb25sZW5ndGggIT09IDApIHtcblx0XHRcdFx0XHRcdFx0aWYgKHBvaW50ZXIgLSBjb3VudF9kZWxldGUgLSBjb3VudF9pbnNlcnQgPiAwICYmIGRpZmZzW3BvaW50ZXIgLSBjb3VudF9kZWxldGUgLSBjb3VudF9pbnNlcnQgLSAxXVswXSA9PT0gRElGRl9FUVVBTCkge1xuXHRcdFx0XHRcdFx0XHRcdGRpZmZzW3BvaW50ZXIgLSBjb3VudF9kZWxldGUgLSBjb3VudF9pbnNlcnQgLSAxXVsxXSArPSB0ZXh0X2luc2VydC5zdWJzdHJpbmcoMCwgY29tbW9ubGVuZ3RoKTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRkaWZmcy5zcGxpY2UoMCwgMCwgbmV3IERpZmYoRElGRl9FUVVBTCwgdGV4dF9pbnNlcnQuc3Vic3RyaW5nKDAsIGNvbW1vbmxlbmd0aCkpKTtcblx0XHRcdFx0XHRcdFx0XHRwb2ludGVyKys7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0dGV4dF9pbnNlcnQgPSB0ZXh0X2luc2VydC5zdWJzdHJpbmcoY29tbW9ubGVuZ3RoKTtcblx0XHRcdFx0XHRcdFx0dGV4dF9kZWxldGUgPSB0ZXh0X2RlbGV0ZS5zdWJzdHJpbmcoY29tbW9ubGVuZ3RoKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdC8vIEZhY3RvciBvdXQgYW55IGNvbW1vbiBzdWZmaXhlcy5cblx0XHRcdFx0XHRcdGNvbW1vbmxlbmd0aCA9IGRpZmZfY29tbW9uU3VmZml4KHRleHRfaW5zZXJ0LCB0ZXh0X2RlbGV0ZSk7XG5cdFx0XHRcdFx0XHRpZiAoY29tbW9ubGVuZ3RoICE9PSAwKSB7XG5cdFx0XHRcdFx0XHRcdGRpZmZzW3BvaW50ZXJdWzFdID0gdGV4dF9pbnNlcnQuc3Vic3RyaW5nKHRleHRfaW5zZXJ0Lmxlbmd0aCAtIGNvbW1vbmxlbmd0aCkgKyBkaWZmc1twb2ludGVyXVsxXTtcblx0XHRcdFx0XHRcdFx0dGV4dF9pbnNlcnQgPSB0ZXh0X2luc2VydC5zdWJzdHJpbmcoMCwgdGV4dF9pbnNlcnQubGVuZ3RoIC0gY29tbW9ubGVuZ3RoKTtcblx0XHRcdFx0XHRcdFx0dGV4dF9kZWxldGUgPSB0ZXh0X2RlbGV0ZS5zdWJzdHJpbmcoMCwgdGV4dF9kZWxldGUubGVuZ3RoIC0gY29tbW9ubGVuZ3RoKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Ly8gRGVsZXRlIHRoZSBvZmZlbmRpbmcgcmVjb3JkcyBhbmQgYWRkIHRoZSBtZXJnZWQgb25lcy5cblx0XHRcdFx0XHRwb2ludGVyIC09IGNvdW50X2RlbGV0ZSArIGNvdW50X2luc2VydDtcblx0XHRcdFx0XHRkaWZmcy5zcGxpY2UocG9pbnRlciwgY291bnRfZGVsZXRlICsgY291bnRfaW5zZXJ0KTtcblx0XHRcdFx0XHRpZiAodGV4dF9kZWxldGUubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRkaWZmcy5zcGxpY2UocG9pbnRlciwgMCwgbmV3IERpZmYoRElGRl9ERUxFVEUsIHRleHRfZGVsZXRlKSk7XG5cdFx0XHRcdFx0XHRwb2ludGVyKys7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICh0ZXh0X2luc2VydC5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdGRpZmZzLnNwbGljZShwb2ludGVyLCAwLCBuZXcgRGlmZihESUZGX0lOU0VSVCwgdGV4dF9pbnNlcnQpKTtcblx0XHRcdFx0XHRcdHBvaW50ZXIrKztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cG9pbnRlcisrO1xuXHRcdFx0XHR9IGVsc2UgaWYgKHBvaW50ZXIgIT09IDAgJiYgZGlmZnNbcG9pbnRlciAtIDFdWzBdID09PSBESUZGX0VRVUFMKSB7XG5cdFx0XHRcdFx0Ly8gTWVyZ2UgdGhpcyBlcXVhbGl0eSB3aXRoIHRoZSBwcmV2aW91cyBvbmUuXG5cdFx0XHRcdFx0ZGlmZnNbcG9pbnRlciAtIDFdWzFdICs9IGRpZmZzW3BvaW50ZXJdWzFdO1xuXHRcdFx0XHRcdGRpZmZzLnNwbGljZShwb2ludGVyLCAxKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRwb2ludGVyKys7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y291bnRfaW5zZXJ0ID0gMDtcblx0XHRcdFx0Y291bnRfZGVsZXRlID0gMDtcblx0XHRcdFx0dGV4dF9kZWxldGUgPSBcIlwiO1xuXHRcdFx0XHR0ZXh0X2luc2VydCA9IFwiXCI7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblx0fVxuXHRpZiAoZGlmZnMuYXQoLTEpPy5bMV0gPT09IFwiXCIpIHtcblx0XHRkaWZmcy5wb3AoKTtcblx0fVxuXHQvLyBTZWNvbmQgcGFzczogbG9vayBmb3Igc2luZ2xlIGVkaXRzIHN1cnJvdW5kZWQgb24gYm90aCBzaWRlcyBieSBlcXVhbGl0aWVzXG5cdC8vIHdoaWNoIGNhbiBiZSBzaGlmdGVkIHNpZGV3YXlzIHRvIGVsaW1pbmF0ZSBhbiBlcXVhbGl0eS5cblx0Ly8gZS5nOiBBPGlucz5CQTwvaW5zPkMgLT4gPGlucz5BQjwvaW5zPkFDXG5cdGxldCBjaGFuZ2VzID0gZmFsc2U7XG5cdHBvaW50ZXIgPSAxO1xuXHQvLyBJbnRlbnRpb25hbGx5IGlnbm9yZSB0aGUgZmlyc3QgYW5kIGxhc3QgZWxlbWVudCAoZG9uJ3QgbmVlZCBjaGVja2luZykuXG5cdHdoaWxlIChwb2ludGVyIDwgZGlmZnMubGVuZ3RoIC0gMSkge1xuXHRcdGlmIChkaWZmc1twb2ludGVyIC0gMV1bMF0gPT09IERJRkZfRVFVQUwgJiYgZGlmZnNbcG9pbnRlciArIDFdWzBdID09PSBESUZGX0VRVUFMKSB7XG5cdFx0XHQvLyBUaGlzIGlzIGEgc2luZ2xlIGVkaXQgc3Vycm91bmRlZCBieSBlcXVhbGl0aWVzLlxuXHRcdFx0aWYgKGRpZmZzW3BvaW50ZXJdWzFdLnN1YnN0cmluZyhkaWZmc1twb2ludGVyXVsxXS5sZW5ndGggLSBkaWZmc1twb2ludGVyIC0gMV1bMV0ubGVuZ3RoKSA9PT0gZGlmZnNbcG9pbnRlciAtIDFdWzFdKSB7XG5cdFx0XHRcdC8vIFNoaWZ0IHRoZSBlZGl0IG92ZXIgdGhlIHByZXZpb3VzIGVxdWFsaXR5LlxuXHRcdFx0XHRkaWZmc1twb2ludGVyXVsxXSA9IGRpZmZzW3BvaW50ZXIgLSAxXVsxXSArIGRpZmZzW3BvaW50ZXJdWzFdLnN1YnN0cmluZygwLCBkaWZmc1twb2ludGVyXVsxXS5sZW5ndGggLSBkaWZmc1twb2ludGVyIC0gMV1bMV0ubGVuZ3RoKTtcblx0XHRcdFx0ZGlmZnNbcG9pbnRlciArIDFdWzFdID0gZGlmZnNbcG9pbnRlciAtIDFdWzFdICsgZGlmZnNbcG9pbnRlciArIDFdWzFdO1xuXHRcdFx0XHRkaWZmcy5zcGxpY2UocG9pbnRlciAtIDEsIDEpO1xuXHRcdFx0XHRjaGFuZ2VzID0gdHJ1ZTtcblx0XHRcdH0gZWxzZSBpZiAoZGlmZnNbcG9pbnRlcl1bMV0uc3Vic3RyaW5nKDAsIGRpZmZzW3BvaW50ZXIgKyAxXVsxXS5sZW5ndGgpID09PSBkaWZmc1twb2ludGVyICsgMV1bMV0pIHtcblx0XHRcdFx0Ly8gU2hpZnQgdGhlIGVkaXQgb3ZlciB0aGUgbmV4dCBlcXVhbGl0eS5cblx0XHRcdFx0ZGlmZnNbcG9pbnRlciAtIDFdWzFdICs9IGRpZmZzW3BvaW50ZXIgKyAxXVsxXTtcblx0XHRcdFx0ZGlmZnNbcG9pbnRlcl1bMV0gPSBkaWZmc1twb2ludGVyXVsxXS5zdWJzdHJpbmcoZGlmZnNbcG9pbnRlciArIDFdWzFdLmxlbmd0aCkgKyBkaWZmc1twb2ludGVyICsgMV1bMV07XG5cdFx0XHRcdGRpZmZzLnNwbGljZShwb2ludGVyICsgMSwgMSk7XG5cdFx0XHRcdGNoYW5nZXMgPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRwb2ludGVyKys7XG5cdH1cblx0Ly8gSWYgc2hpZnRzIHdlcmUgbWFkZSwgdGhlIGRpZmYgbmVlZHMgcmVvcmRlcmluZyBhbmQgYW5vdGhlciBzaGlmdCBzd2VlcC5cblx0aWYgKGNoYW5nZXMpIHtcblx0XHRkaWZmX2NsZWFudXBNZXJnZShkaWZmcyk7XG5cdH1cbn1cbi8qKlxuKiBHaXZlbiB0d28gc3RyaW5ncywgY29tcHV0ZSBhIHNjb3JlIHJlcHJlc2VudGluZyB3aGV0aGVyIHRoZSBpbnRlcm5hbFxuKiBib3VuZGFyeSBmYWxscyBvbiBsb2dpY2FsIGJvdW5kYXJpZXMuXG4qIFNjb3JlcyByYW5nZSBmcm9tIDYgKGJlc3QpIHRvIDAgKHdvcnN0KS5cbiogQ2xvc3VyZSwgYnV0IGRvZXMgbm90IHJlZmVyZW5jZSBhbnkgZXh0ZXJuYWwgdmFyaWFibGVzLlxuKiBAcGFyYW0ge3N0cmluZ30gb25lIEZpcnN0IHN0cmluZy5cbiogQHBhcmFtIHtzdHJpbmd9IHR3byBTZWNvbmQgc3RyaW5nLlxuKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBzY29yZS5cbiogQHByaXZhdGVcbiovXG5mdW5jdGlvbiBkaWZmX2NsZWFudXBTZW1hbnRpY1Njb3JlXyhvbmUsIHR3bykge1xuXHRpZiAoIW9uZSB8fCAhdHdvKSB7XG5cdFx0Ly8gRWRnZXMgYXJlIHRoZSBiZXN0LlxuXHRcdHJldHVybiA2O1xuXHR9XG5cdC8vIEVhY2ggcG9ydCBvZiB0aGlzIGZ1bmN0aW9uIGJlaGF2ZXMgc2xpZ2h0bHkgZGlmZmVyZW50bHkgZHVlIHRvXG5cdC8vIHN1YnRsZSBkaWZmZXJlbmNlcyBpbiBlYWNoIGxhbmd1YWdlJ3MgZGVmaW5pdGlvbiBvZiB0aGluZ3MgbGlrZVxuXHQvLyAnd2hpdGVzcGFjZScuICBTaW5jZSB0aGlzIGZ1bmN0aW9uJ3MgcHVycG9zZSBpcyBsYXJnZWx5IGNvc21ldGljLFxuXHQvLyB0aGUgY2hvaWNlIGhhcyBiZWVuIG1hZGUgdG8gdXNlIGVhY2ggbGFuZ3VhZ2UncyBuYXRpdmUgZmVhdHVyZXNcblx0Ly8gcmF0aGVyIHRoYW4gZm9yY2UgdG90YWwgY29uZm9ybWl0eS5cblx0Y29uc3QgY2hhcjEgPSBvbmUuY2hhckF0KG9uZS5sZW5ndGggLSAxKTtcblx0Y29uc3QgY2hhcjIgPSB0d28uY2hhckF0KDApO1xuXHRjb25zdCBub25BbHBoYU51bWVyaWMxID0gY2hhcjEubWF0Y2gobm9uQWxwaGFOdW1lcmljUmVnZXhfKTtcblx0Y29uc3Qgbm9uQWxwaGFOdW1lcmljMiA9IGNoYXIyLm1hdGNoKG5vbkFscGhhTnVtZXJpY1JlZ2V4Xyk7XG5cdGNvbnN0IHdoaXRlc3BhY2UxID0gbm9uQWxwaGFOdW1lcmljMSAmJiBjaGFyMS5tYXRjaCh3aGl0ZXNwYWNlUmVnZXhfKTtcblx0Y29uc3Qgd2hpdGVzcGFjZTIgPSBub25BbHBoYU51bWVyaWMyICYmIGNoYXIyLm1hdGNoKHdoaXRlc3BhY2VSZWdleF8pO1xuXHRjb25zdCBsaW5lQnJlYWsxID0gd2hpdGVzcGFjZTEgJiYgY2hhcjEubWF0Y2gobGluZWJyZWFrUmVnZXhfKTtcblx0Y29uc3QgbGluZUJyZWFrMiA9IHdoaXRlc3BhY2UyICYmIGNoYXIyLm1hdGNoKGxpbmVicmVha1JlZ2V4Xyk7XG5cdGNvbnN0IGJsYW5rTGluZTEgPSBsaW5lQnJlYWsxICYmIG9uZS5tYXRjaChibGFua2xpbmVFbmRSZWdleF8pO1xuXHRjb25zdCBibGFua0xpbmUyID0gbGluZUJyZWFrMiAmJiB0d28ubWF0Y2goYmxhbmtsaW5lU3RhcnRSZWdleF8pO1xuXHRpZiAoYmxhbmtMaW5lMSB8fCBibGFua0xpbmUyKSB7XG5cdFx0Ly8gRml2ZSBwb2ludHMgZm9yIGJsYW5rIGxpbmVzLlxuXHRcdHJldHVybiA1O1xuXHR9IGVsc2UgaWYgKGxpbmVCcmVhazEgfHwgbGluZUJyZWFrMikge1xuXHRcdC8vIEZvdXIgcG9pbnRzIGZvciBsaW5lIGJyZWFrcy5cblx0XHRyZXR1cm4gNDtcblx0fSBlbHNlIGlmIChub25BbHBoYU51bWVyaWMxICYmICF3aGl0ZXNwYWNlMSAmJiB3aGl0ZXNwYWNlMikge1xuXHRcdC8vIFRocmVlIHBvaW50cyBmb3IgZW5kIG9mIHNlbnRlbmNlcy5cblx0XHRyZXR1cm4gMztcblx0fSBlbHNlIGlmICh3aGl0ZXNwYWNlMSB8fCB3aGl0ZXNwYWNlMikge1xuXHRcdC8vIFR3byBwb2ludHMgZm9yIHdoaXRlc3BhY2UuXG5cdFx0cmV0dXJuIDI7XG5cdH0gZWxzZSBpZiAobm9uQWxwaGFOdW1lcmljMSB8fCBub25BbHBoYU51bWVyaWMyKSB7XG5cdFx0Ly8gT25lIHBvaW50IGZvciBub24tYWxwaGFudW1lcmljLlxuXHRcdHJldHVybiAxO1xuXHR9XG5cdHJldHVybiAwO1xufVxuXG4vKipcbiogQ29weXJpZ2h0IChjKSBNZXRhIFBsYXRmb3JtcywgSW5jLiBhbmQgYWZmaWxpYXRlcy5cbipcbiogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4qIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiovXG5jb25zdCBOT19ESUZGX01FU1NBR0UgPSBcIkNvbXBhcmVkIHZhbHVlcyBoYXZlIG5vIHZpc3VhbCBkaWZmZXJlbmNlLlwiO1xuY29uc3QgU0lNSUxBUl9NRVNTQUdFID0gXCJDb21wYXJlZCB2YWx1ZXMgc2VyaWFsaXplIHRvIHRoZSBzYW1lIHN0cnVjdHVyZS5cXG5cIiArIFwiUHJpbnRpbmcgaW50ZXJuYWwgb2JqZWN0IHN0cnVjdHVyZSB3aXRob3V0IGNhbGxpbmcgYHRvSlNPTmAgaW5zdGVhZC5cIjtcblxuZnVuY3Rpb24gZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMoeCkge1xuXHRyZXR1cm4geCAmJiB4Ll9fZXNNb2R1bGUgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsIFwiZGVmYXVsdFwiKSA/IHhbXCJkZWZhdWx0XCJdIDogeDtcbn1cblxudmFyIGJ1aWxkID0ge307XG5cbnZhciBoYXNSZXF1aXJlZEJ1aWxkO1xuXG5mdW5jdGlvbiByZXF1aXJlQnVpbGQgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRCdWlsZCkgcmV0dXJuIGJ1aWxkO1xuXHRoYXNSZXF1aXJlZEJ1aWxkID0gMTtcblxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoYnVpbGQsICdfX2VzTW9kdWxlJywge1xuXHQgIHZhbHVlOiB0cnVlXG5cdH0pO1xuXHRidWlsZC5kZWZhdWx0ID0gZGlmZlNlcXVlbmNlO1xuXHQvKipcblx0ICogQ29weXJpZ2h0IChjKSBNZXRhIFBsYXRmb3JtcywgSW5jLiBhbmQgYWZmaWxpYXRlcy5cblx0ICpcblx0ICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG5cdCAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cblx0ICpcblx0ICovXG5cblx0Ly8gVGhpcyBkaWZmLXNlcXVlbmNlcyBwYWNrYWdlIGltcGxlbWVudHMgdGhlIGxpbmVhciBzcGFjZSB2YXJpYXRpb24gaW5cblx0Ly8gQW4gTyhORCkgRGlmZmVyZW5jZSBBbGdvcml0aG0gYW5kIEl0cyBWYXJpYXRpb25zIGJ5IEV1Z2VuZSBXLiBNeWVyc1xuXG5cdC8vIFJlbGF0aW9uc2hpcCBpbiBub3RhdGlvbiBiZXR3ZWVuIE15ZXJzIHBhcGVyIGFuZCB0aGlzIHBhY2thZ2U6XG5cdC8vIEEgaXMgYVxuXHQvLyBOIGlzIGFMZW5ndGgsIGFFbmQgLSBhU3RhcnQsIGFuZCBzbyBvblxuXHQvLyB4IGlzIGFJbmRleCwgYUZpcnN0LCBhTGFzdCwgYW5kIHNvIG9uXG5cdC8vIEIgaXMgYlxuXHQvLyBNIGlzIGJMZW5ndGgsIGJFbmQgLSBiU3RhcnQsIGFuZCBzbyBvblxuXHQvLyB5IGlzIGJJbmRleCwgYkZpcnN0LCBiTGFzdCwgYW5kIHNvIG9uXG5cdC8vIM6UID0gTiAtIE0gaXMgbmVnYXRpdmUgb2YgYmFEZWx0YUxlbmd0aCA9IGJMZW5ndGggLSBhTGVuZ3RoXG5cdC8vIEQgaXMgZFxuXHQvLyBrIGlzIGtGXG5cdC8vIGsgKyDOlCBpcyBrRiA9IGtSIC0gYmFEZWx0YUxlbmd0aFxuXHQvLyBWIGlzIGFJbmRleGVzRiBvciBhSW5kZXhlc1IgKHNlZSBjb21tZW50IGJlbG93IGFib3V0IEluZGV4ZXMgdHlwZSlcblx0Ly8gaW5kZXggaW50ZXJ2YWxzIFsxLCBOXSBhbmQgWzEsIE1dIGFyZSBbMCwgYUxlbmd0aCkgYW5kIFswLCBiTGVuZ3RoKVxuXHQvLyBzdGFydGluZyBwb2ludCBpbiBmb3J3YXJkIGRpcmVjdGlvbiAoMCwgMCkgaXMgKC0xLCAtMSlcblx0Ly8gc3RhcnRpbmcgcG9pbnQgaW4gcmV2ZXJzZSBkaXJlY3Rpb24gKE4gKyAxLCBNICsgMSkgaXMgKGFMZW5ndGgsIGJMZW5ndGgpXG5cblx0Ly8gVGhlIOKAnGVkaXQgZ3JhcGjigJ0gZm9yIHNlcXVlbmNlcyBhIGFuZCBiIGNvcnJlc3BvbmRzIHRvIGl0ZW1zOlxuXHQvLyBpbiBhIG9uIHRoZSBob3Jpem9udGFsIGF4aXNcblx0Ly8gaW4gYiBvbiB0aGUgdmVydGljYWwgYXhpc1xuXHQvL1xuXHQvLyBHaXZlbiBhLWNvb3JkaW5hdGUgb2YgYSBwb2ludCBpbiBhIGRpYWdvbmFsLCB5b3UgY2FuIGNvbXB1dGUgYi1jb29yZGluYXRlLlxuXHQvL1xuXHQvLyBGb3J3YXJkIGRpYWdvbmFscyBrRjpcblx0Ly8gemVybyBkaWFnb25hbCBpbnRlcnNlY3RzIHRvcCBsZWZ0IGNvcm5lclxuXHQvLyBwb3NpdGl2ZSBkaWFnb25hbHMgaW50ZXJzZWN0IHRvcCBlZGdlXG5cdC8vIG5lZ2F0aXZlIGRpYWdvbmFscyBpbnNlcnNlY3QgbGVmdCBlZGdlXG5cdC8vXG5cdC8vIFJldmVyc2UgZGlhZ29uYWxzIGtSOlxuXHQvLyB6ZXJvIGRpYWdvbmFsIGludGVyc2VjdHMgYm90dG9tIHJpZ2h0IGNvcm5lclxuXHQvLyBwb3NpdGl2ZSBkaWFnb25hbHMgaW50ZXJzZWN0IHJpZ2h0IGVkZ2Vcblx0Ly8gbmVnYXRpdmUgZGlhZ29uYWxzIGludGVyc2VjdCBib3R0b20gZWRnZVxuXG5cdC8vIFRoZSBncmFwaCBjb250YWlucyBhIGRpcmVjdGVkIGFjeWNsaWMgZ3JhcGggb2YgZWRnZXM6XG5cdC8vIGhvcml6b250YWw6IGRlbGV0ZSBhbiBpdGVtIGZyb20gYVxuXHQvLyB2ZXJ0aWNhbDogaW5zZXJ0IGFuIGl0ZW0gZnJvbSBiXG5cdC8vIGRpYWdvbmFsOiBjb21tb24gaXRlbSBpbiBhIGFuZCBiXG5cdC8vXG5cdC8vIFRoZSBhbGdvcml0aG0gc29sdmVzIGR1YWwgcHJvYmxlbXMgaW4gdGhlIGdyYXBoIGFuYWxvZ3k6XG5cdC8vIEZpbmQgbG9uZ2VzdCBjb21tb24gc3Vic2VxdWVuY2U6IHBhdGggd2l0aCBtYXhpbXVtIG51bWJlciBvZiBkaWFnb25hbCBlZGdlc1xuXHQvLyBGaW5kIHNob3J0ZXN0IGVkaXQgc2NyaXB0OiBwYXRoIHdpdGggbWluaW11bSBudW1iZXIgb2Ygbm9uLWRpYWdvbmFsIGVkZ2VzXG5cblx0Ly8gSW5wdXQgY2FsbGJhY2sgZnVuY3Rpb24gY29tcGFyZXMgaXRlbXMgYXQgaW5kZXhlcyBpbiB0aGUgc2VxdWVuY2VzLlxuXG5cdC8vIE91dHB1dCBjYWxsYmFjayBmdW5jdGlvbiByZWNlaXZlcyB0aGUgbnVtYmVyIG9mIGFkamFjZW50IGl0ZW1zXG5cdC8vIGFuZCBzdGFydGluZyBpbmRleGVzIG9mIGVhY2ggY29tbW9uIHN1YnNlcXVlbmNlLlxuXHQvLyBFaXRoZXIgb3JpZ2luYWwgZnVuY3Rpb25zIG9yIHdyYXBwZWQgdG8gc3dhcCBpbmRleGVzIGlmIGdyYXBoIGlzIHRyYW5zcG9zZWQuXG5cdC8vIEluZGV4ZXMgaW4gc2VxdWVuY2UgYSBvZiBsYXN0IHBvaW50IG9mIGZvcndhcmQgb3IgcmV2ZXJzZSBwYXRocyBpbiBncmFwaC5cblx0Ly8gTXllcnMgYWxnb3JpdGhtIGluZGV4ZXMgYnkgZGlhZ29uYWwgayB3aGljaCBmb3IgbmVnYXRpdmUgaXMgYmFkIGRlb3B0IGluIFY4LlxuXHQvLyBUaGlzIHBhY2thZ2UgaW5kZXhlcyBieSBpRiBhbmQgaVIgd2hpY2ggYXJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB6ZXJvLlxuXHQvLyBhbmQgYWxzbyB1cGRhdGVzIHRoZSBpbmRleCBhcnJheXMgaW4gcGxhY2UgdG8gY3V0IG1lbW9yeSBpbiBoYWxmLlxuXHQvLyBrRiA9IDIgKiBpRiAtIGRcblx0Ly8ga1IgPSBkIC0gMiAqIGlSXG5cdC8vIERpdmlzaW9uIG9mIGluZGV4IGludGVydmFscyBpbiBzZXF1ZW5jZXMgYSBhbmQgYiBhdCB0aGUgbWlkZGxlIGNoYW5nZS5cblx0Ly8gSW52YXJpYW50OiBpbnRlcnZhbHMgZG8gbm90IGhhdmUgY29tbW9uIGl0ZW1zIGF0IHRoZSBzdGFydCBvciBlbmQuXG5cdGNvbnN0IHBrZyA9ICdkaWZmLXNlcXVlbmNlcyc7IC8vIGZvciBlcnJvciBtZXNzYWdlc1xuXHRjb25zdCBOT1RfWUVUX1NFVCA9IDA7IC8vIHNtYWxsIGludCBpbnN0ZWFkIG9mIHVuZGVmaW5lZCB0byBhdm9pZCBkZW9wdCBpbiBWOFxuXG5cdC8vIFJldHVybiB0aGUgbnVtYmVyIG9mIGNvbW1vbiBpdGVtcyB0aGF0IGZvbGxvdyBpbiBmb3J3YXJkIGRpcmVjdGlvbi5cblx0Ly8gVGhlIGxlbmd0aCBvZiB3aGF0IE15ZXJzIHBhcGVyIGNhbGxzIGEg4oCcc25ha2XigJ0gaW4gYSBmb3J3YXJkIHBhdGguXG5cdGNvbnN0IGNvdW50Q29tbW9uSXRlbXNGID0gKGFJbmRleCwgYUVuZCwgYkluZGV4LCBiRW5kLCBpc0NvbW1vbikgPT4ge1xuXHQgIGxldCBuQ29tbW9uID0gMDtcblx0ICB3aGlsZSAoYUluZGV4IDwgYUVuZCAmJiBiSW5kZXggPCBiRW5kICYmIGlzQ29tbW9uKGFJbmRleCwgYkluZGV4KSkge1xuXHQgICAgYUluZGV4ICs9IDE7XG5cdCAgICBiSW5kZXggKz0gMTtcblx0ICAgIG5Db21tb24gKz0gMTtcblx0ICB9XG5cdCAgcmV0dXJuIG5Db21tb247XG5cdH07XG5cblx0Ly8gUmV0dXJuIHRoZSBudW1iZXIgb2YgY29tbW9uIGl0ZW1zIHRoYXQgcHJlY2VkZSBpbiByZXZlcnNlIGRpcmVjdGlvbi5cblx0Ly8gVGhlIGxlbmd0aCBvZiB3aGF0IE15ZXJzIHBhcGVyIGNhbGxzIGEg4oCcc25ha2XigJ0gaW4gYSByZXZlcnNlIHBhdGguXG5cdGNvbnN0IGNvdW50Q29tbW9uSXRlbXNSID0gKGFTdGFydCwgYUluZGV4LCBiU3RhcnQsIGJJbmRleCwgaXNDb21tb24pID0+IHtcblx0ICBsZXQgbkNvbW1vbiA9IDA7XG5cdCAgd2hpbGUgKGFTdGFydCA8PSBhSW5kZXggJiYgYlN0YXJ0IDw9IGJJbmRleCAmJiBpc0NvbW1vbihhSW5kZXgsIGJJbmRleCkpIHtcblx0ICAgIGFJbmRleCAtPSAxO1xuXHQgICAgYkluZGV4IC09IDE7XG5cdCAgICBuQ29tbW9uICs9IDE7XG5cdCAgfVxuXHQgIHJldHVybiBuQ29tbW9uO1xuXHR9O1xuXG5cdC8vIEEgc2ltcGxlIGZ1bmN0aW9uIHRvIGV4dGVuZCBmb3J3YXJkIHBhdGhzIGZyb20gKGQgLSAxKSB0byBkIGNoYW5nZXNcblx0Ly8gd2hlbiBmb3J3YXJkIGFuZCByZXZlcnNlIHBhdGhzIGNhbm5vdCB5ZXQgb3ZlcmxhcC5cblx0Y29uc3QgZXh0ZW5kUGF0aHNGID0gKFxuXHQgIGQsXG5cdCAgYUVuZCxcblx0ICBiRW5kLFxuXHQgIGJGLFxuXHQgIGlzQ29tbW9uLFxuXHQgIGFJbmRleGVzRixcblx0ICBpTWF4RiAvLyByZXR1cm4gdGhlIHZhbHVlIGJlY2F1c2Ugb3B0aW1pemF0aW9uIG1pZ2h0IGRlY3JlYXNlIGl0XG5cdCkgPT4ge1xuXHQgIC8vIFVucm9sbCB0aGUgZmlyc3QgaXRlcmF0aW9uLlxuXHQgIGxldCBpRiA9IDA7XG5cdCAgbGV0IGtGID0gLWQ7IC8vIGtGID0gMiAqIGlGIC0gZFxuXHQgIGxldCBhRmlyc3QgPSBhSW5kZXhlc0ZbaUZdOyAvLyBpbiBmaXJzdCBpdGVyYXRpb24gYWx3YXlzIGluc2VydFxuXHQgIGxldCBhSW5kZXhQcmV2MSA9IGFGaXJzdDsgLy8gcHJldiB2YWx1ZSBvZiBbaUYgLSAxXSBpbiBuZXh0IGl0ZXJhdGlvblxuXHQgIGFJbmRleGVzRltpRl0gKz0gY291bnRDb21tb25JdGVtc0YoXG5cdCAgICBhRmlyc3QgKyAxLFxuXHQgICAgYUVuZCxcblx0ICAgIGJGICsgYUZpcnN0IC0ga0YgKyAxLFxuXHQgICAgYkVuZCxcblx0ICAgIGlzQ29tbW9uXG5cdCAgKTtcblxuXHQgIC8vIE9wdGltaXphdGlvbjogc2tpcCBkaWFnb25hbHMgaW4gd2hpY2ggcGF0aHMgY2Fubm90IGV2ZXIgb3ZlcmxhcC5cblx0ICBjb25zdCBuRiA9IGQgPCBpTWF4RiA/IGQgOiBpTWF4RjtcblxuXHQgIC8vIFRoZSBkaWFnb25hbHMga0YgYXJlIG9kZCB3aGVuIGQgaXMgb2RkIGFuZCBldmVuIHdoZW4gZCBpcyBldmVuLlxuXHQgIGZvciAoaUYgKz0gMSwga0YgKz0gMjsgaUYgPD0gbkY7IGlGICs9IDEsIGtGICs9IDIpIHtcblx0ICAgIC8vIFRvIGdldCBmaXJzdCBwb2ludCBvZiBwYXRoIHNlZ21lbnQsIG1vdmUgb25lIGNoYW5nZSBpbiBmb3J3YXJkIGRpcmVjdGlvblxuXHQgICAgLy8gZnJvbSBsYXN0IHBvaW50IG9mIHByZXZpb3VzIHBhdGggc2VnbWVudCBpbiBhbiBhZGphY2VudCBkaWFnb25hbC5cblx0ICAgIC8vIEluIGxhc3QgcG9zc2libGUgaXRlcmF0aW9uIHdoZW4gaUYgPT09IGQgYW5kIGtGID09PSBkIGFsd2F5cyBkZWxldGUuXG5cdCAgICBpZiAoaUYgIT09IGQgJiYgYUluZGV4UHJldjEgPCBhSW5kZXhlc0ZbaUZdKSB7XG5cdCAgICAgIGFGaXJzdCA9IGFJbmRleGVzRltpRl07IC8vIHZlcnRpY2FsIHRvIGluc2VydCBmcm9tIGJcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIGFGaXJzdCA9IGFJbmRleFByZXYxICsgMTsgLy8gaG9yaXpvbnRhbCB0byBkZWxldGUgZnJvbSBhXG5cblx0ICAgICAgaWYgKGFFbmQgPD0gYUZpcnN0KSB7XG5cdCAgICAgICAgLy8gT3B0aW1pemF0aW9uOiBkZWxldGUgbW92ZWQgcGFzdCByaWdodCBvZiBncmFwaC5cblx0ICAgICAgICByZXR1cm4gaUYgLSAxO1xuXHQgICAgICB9XG5cdCAgICB9XG5cblx0ICAgIC8vIFRvIGdldCBsYXN0IHBvaW50IG9mIHBhdGggc2VnbWVudCwgbW92ZSBhbG9uZyBkaWFnb25hbCBvZiBjb21tb24gaXRlbXMuXG5cdCAgICBhSW5kZXhQcmV2MSA9IGFJbmRleGVzRltpRl07XG5cdCAgICBhSW5kZXhlc0ZbaUZdID1cblx0ICAgICAgYUZpcnN0ICtcblx0ICAgICAgY291bnRDb21tb25JdGVtc0YoYUZpcnN0ICsgMSwgYUVuZCwgYkYgKyBhRmlyc3QgLSBrRiArIDEsIGJFbmQsIGlzQ29tbW9uKTtcblx0ICB9XG5cdCAgcmV0dXJuIGlNYXhGO1xuXHR9O1xuXG5cdC8vIEEgc2ltcGxlIGZ1bmN0aW9uIHRvIGV4dGVuZCByZXZlcnNlIHBhdGhzIGZyb20gKGQgLSAxKSB0byBkIGNoYW5nZXNcblx0Ly8gd2hlbiByZXZlcnNlIGFuZCBmb3J3YXJkIHBhdGhzIGNhbm5vdCB5ZXQgb3ZlcmxhcC5cblx0Y29uc3QgZXh0ZW5kUGF0aHNSID0gKFxuXHQgIGQsXG5cdCAgYVN0YXJ0LFxuXHQgIGJTdGFydCxcblx0ICBiUixcblx0ICBpc0NvbW1vbixcblx0ICBhSW5kZXhlc1IsXG5cdCAgaU1heFIgLy8gcmV0dXJuIHRoZSB2YWx1ZSBiZWNhdXNlIG9wdGltaXphdGlvbiBtaWdodCBkZWNyZWFzZSBpdFxuXHQpID0+IHtcblx0ICAvLyBVbnJvbGwgdGhlIGZpcnN0IGl0ZXJhdGlvbi5cblx0ICBsZXQgaVIgPSAwO1xuXHQgIGxldCBrUiA9IGQ7IC8vIGtSID0gZCAtIDIgKiBpUlxuXHQgIGxldCBhRmlyc3QgPSBhSW5kZXhlc1JbaVJdOyAvLyBpbiBmaXJzdCBpdGVyYXRpb24gYWx3YXlzIGluc2VydFxuXHQgIGxldCBhSW5kZXhQcmV2MSA9IGFGaXJzdDsgLy8gcHJldiB2YWx1ZSBvZiBbaVIgLSAxXSBpbiBuZXh0IGl0ZXJhdGlvblxuXHQgIGFJbmRleGVzUltpUl0gLT0gY291bnRDb21tb25JdGVtc1IoXG5cdCAgICBhU3RhcnQsXG5cdCAgICBhRmlyc3QgLSAxLFxuXHQgICAgYlN0YXJ0LFxuXHQgICAgYlIgKyBhRmlyc3QgLSBrUiAtIDEsXG5cdCAgICBpc0NvbW1vblxuXHQgICk7XG5cblx0ICAvLyBPcHRpbWl6YXRpb246IHNraXAgZGlhZ29uYWxzIGluIHdoaWNoIHBhdGhzIGNhbm5vdCBldmVyIG92ZXJsYXAuXG5cdCAgY29uc3QgblIgPSBkIDwgaU1heFIgPyBkIDogaU1heFI7XG5cblx0ICAvLyBUaGUgZGlhZ29uYWxzIGtSIGFyZSBvZGQgd2hlbiBkIGlzIG9kZCBhbmQgZXZlbiB3aGVuIGQgaXMgZXZlbi5cblx0ICBmb3IgKGlSICs9IDEsIGtSIC09IDI7IGlSIDw9IG5SOyBpUiArPSAxLCBrUiAtPSAyKSB7XG5cdCAgICAvLyBUbyBnZXQgZmlyc3QgcG9pbnQgb2YgcGF0aCBzZWdtZW50LCBtb3ZlIG9uZSBjaGFuZ2UgaW4gcmV2ZXJzZSBkaXJlY3Rpb25cblx0ICAgIC8vIGZyb20gbGFzdCBwb2ludCBvZiBwcmV2aW91cyBwYXRoIHNlZ21lbnQgaW4gYW4gYWRqYWNlbnQgZGlhZ29uYWwuXG5cdCAgICAvLyBJbiBsYXN0IHBvc3NpYmxlIGl0ZXJhdGlvbiB3aGVuIGlSID09PSBkIGFuZCBrUiA9PT0gLWQgYWx3YXlzIGRlbGV0ZS5cblx0ICAgIGlmIChpUiAhPT0gZCAmJiBhSW5kZXhlc1JbaVJdIDwgYUluZGV4UHJldjEpIHtcblx0ICAgICAgYUZpcnN0ID0gYUluZGV4ZXNSW2lSXTsgLy8gdmVydGljYWwgdG8gaW5zZXJ0IGZyb20gYlxuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgYUZpcnN0ID0gYUluZGV4UHJldjEgLSAxOyAvLyBob3Jpem9udGFsIHRvIGRlbGV0ZSBmcm9tIGFcblxuXHQgICAgICBpZiAoYUZpcnN0IDwgYVN0YXJ0KSB7XG5cdCAgICAgICAgLy8gT3B0aW1pemF0aW9uOiBkZWxldGUgbW92ZWQgcGFzdCBsZWZ0IG9mIGdyYXBoLlxuXHQgICAgICAgIHJldHVybiBpUiAtIDE7XG5cdCAgICAgIH1cblx0ICAgIH1cblxuXHQgICAgLy8gVG8gZ2V0IGxhc3QgcG9pbnQgb2YgcGF0aCBzZWdtZW50LCBtb3ZlIGFsb25nIGRpYWdvbmFsIG9mIGNvbW1vbiBpdGVtcy5cblx0ICAgIGFJbmRleFByZXYxID0gYUluZGV4ZXNSW2lSXTtcblx0ICAgIGFJbmRleGVzUltpUl0gPVxuXHQgICAgICBhRmlyc3QgLVxuXHQgICAgICBjb3VudENvbW1vbkl0ZW1zUihcblx0ICAgICAgICBhU3RhcnQsXG5cdCAgICAgICAgYUZpcnN0IC0gMSxcblx0ICAgICAgICBiU3RhcnQsXG5cdCAgICAgICAgYlIgKyBhRmlyc3QgLSBrUiAtIDEsXG5cdCAgICAgICAgaXNDb21tb25cblx0ICAgICAgKTtcblx0ICB9XG5cdCAgcmV0dXJuIGlNYXhSO1xuXHR9O1xuXG5cdC8vIEEgY29tcGxldGUgZnVuY3Rpb24gdG8gZXh0ZW5kIGZvcndhcmQgcGF0aHMgZnJvbSAoZCAtIDEpIHRvIGQgY2hhbmdlcy5cblx0Ly8gUmV0dXJuIHRydWUgaWYgYSBwYXRoIG92ZXJsYXBzIHJldmVyc2UgcGF0aCBvZiAoZCAtIDEpIGNoYW5nZXMgaW4gaXRzIGRpYWdvbmFsLlxuXHRjb25zdCBleHRlbmRPdmVybGFwcGFibGVQYXRoc0YgPSAoXG5cdCAgZCxcblx0ICBhU3RhcnQsXG5cdCAgYUVuZCxcblx0ICBiU3RhcnQsXG5cdCAgYkVuZCxcblx0ICBpc0NvbW1vbixcblx0ICBhSW5kZXhlc0YsXG5cdCAgaU1heEYsXG5cdCAgYUluZGV4ZXNSLFxuXHQgIGlNYXhSLFxuXHQgIGRpdmlzaW9uIC8vIHVwZGF0ZSBwcm9wIHZhbHVlcyBpZiByZXR1cm4gdHJ1ZVxuXHQpID0+IHtcblx0ICBjb25zdCBiRiA9IGJTdGFydCAtIGFTdGFydDsgLy8gYkluZGV4ID0gYkYgKyBhSW5kZXggLSBrRlxuXHQgIGNvbnN0IGFMZW5ndGggPSBhRW5kIC0gYVN0YXJ0O1xuXHQgIGNvbnN0IGJMZW5ndGggPSBiRW5kIC0gYlN0YXJ0O1xuXHQgIGNvbnN0IGJhRGVsdGFMZW5ndGggPSBiTGVuZ3RoIC0gYUxlbmd0aDsgLy8ga0YgPSBrUiAtIGJhRGVsdGFMZW5ndGhcblxuXHQgIC8vIFJhbmdlIG9mIGRpYWdvbmFscyBpbiB3aGljaCBmb3J3YXJkIGFuZCByZXZlcnNlIHBhdGhzIG1pZ2h0IG92ZXJsYXAuXG5cdCAgY29uc3Qga01pbk92ZXJsYXBGID0gLWJhRGVsdGFMZW5ndGggLSAoZCAtIDEpOyAvLyAtKGQgLSAxKSA8PSBrUlxuXHQgIGNvbnN0IGtNYXhPdmVybGFwRiA9IC1iYURlbHRhTGVuZ3RoICsgKGQgLSAxKTsgLy8ga1IgPD0gKGQgLSAxKVxuXG5cdCAgbGV0IGFJbmRleFByZXYxID0gTk9UX1lFVF9TRVQ7IC8vIHByZXYgdmFsdWUgb2YgW2lGIC0gMV0gaW4gbmV4dCBpdGVyYXRpb25cblxuXHQgIC8vIE9wdGltaXphdGlvbjogc2tpcCBkaWFnb25hbHMgaW4gd2hpY2ggcGF0aHMgY2Fubm90IGV2ZXIgb3ZlcmxhcC5cblx0ICBjb25zdCBuRiA9IGQgPCBpTWF4RiA/IGQgOiBpTWF4RjtcblxuXHQgIC8vIFRoZSBkaWFnb25hbHMga0YgPSAyICogaUYgLSBkIGFyZSBvZGQgd2hlbiBkIGlzIG9kZCBhbmQgZXZlbiB3aGVuIGQgaXMgZXZlbi5cblx0ICBmb3IgKGxldCBpRiA9IDAsIGtGID0gLWQ7IGlGIDw9IG5GOyBpRiArPSAxLCBrRiArPSAyKSB7XG5cdCAgICAvLyBUbyBnZXQgZmlyc3QgcG9pbnQgb2YgcGF0aCBzZWdtZW50LCBtb3ZlIG9uZSBjaGFuZ2UgaW4gZm9yd2FyZCBkaXJlY3Rpb25cblx0ICAgIC8vIGZyb20gbGFzdCBwb2ludCBvZiBwcmV2aW91cyBwYXRoIHNlZ21lbnQgaW4gYW4gYWRqYWNlbnQgZGlhZ29uYWwuXG5cdCAgICAvLyBJbiBmaXJzdCBpdGVyYXRpb24gd2hlbiBpRiA9PT0gMCBhbmQga0YgPT09IC1kIGFsd2F5cyBpbnNlcnQuXG5cdCAgICAvLyBJbiBsYXN0IHBvc3NpYmxlIGl0ZXJhdGlvbiB3aGVuIGlGID09PSBkIGFuZCBrRiA9PT0gZCBhbHdheXMgZGVsZXRlLlxuXHQgICAgY29uc3QgaW5zZXJ0ID0gaUYgPT09IDAgfHwgKGlGICE9PSBkICYmIGFJbmRleFByZXYxIDwgYUluZGV4ZXNGW2lGXSk7XG5cdCAgICBjb25zdCBhTGFzdFByZXYgPSBpbnNlcnQgPyBhSW5kZXhlc0ZbaUZdIDogYUluZGV4UHJldjE7XG5cdCAgICBjb25zdCBhRmlyc3QgPSBpbnNlcnRcblx0ICAgICAgPyBhTGFzdFByZXYgLy8gdmVydGljYWwgdG8gaW5zZXJ0IGZyb20gYlxuXHQgICAgICA6IGFMYXN0UHJldiArIDE7IC8vIGhvcml6b250YWwgdG8gZGVsZXRlIGZyb20gYVxuXG5cdCAgICAvLyBUbyBnZXQgbGFzdCBwb2ludCBvZiBwYXRoIHNlZ21lbnQsIG1vdmUgYWxvbmcgZGlhZ29uYWwgb2YgY29tbW9uIGl0ZW1zLlxuXHQgICAgY29uc3QgYkZpcnN0ID0gYkYgKyBhRmlyc3QgLSBrRjtcblx0ICAgIGNvbnN0IG5Db21tb25GID0gY291bnRDb21tb25JdGVtc0YoXG5cdCAgICAgIGFGaXJzdCArIDEsXG5cdCAgICAgIGFFbmQsXG5cdCAgICAgIGJGaXJzdCArIDEsXG5cdCAgICAgIGJFbmQsXG5cdCAgICAgIGlzQ29tbW9uXG5cdCAgICApO1xuXHQgICAgY29uc3QgYUxhc3QgPSBhRmlyc3QgKyBuQ29tbW9uRjtcblx0ICAgIGFJbmRleFByZXYxID0gYUluZGV4ZXNGW2lGXTtcblx0ICAgIGFJbmRleGVzRltpRl0gPSBhTGFzdDtcblx0ICAgIGlmIChrTWluT3ZlcmxhcEYgPD0ga0YgJiYga0YgPD0ga01heE92ZXJsYXBGKSB7XG5cdCAgICAgIC8vIFNvbHZlIGZvciBpUiBvZiByZXZlcnNlIHBhdGggd2l0aCAoZCAtIDEpIGNoYW5nZXMgaW4gZGlhZ29uYWwga0Y6XG5cdCAgICAgIC8vIGtSID0ga0YgKyBiYURlbHRhTGVuZ3RoXG5cdCAgICAgIC8vIGtSID0gKGQgLSAxKSAtIDIgKiBpUlxuXHQgICAgICBjb25zdCBpUiA9IChkIC0gMSAtIChrRiArIGJhRGVsdGFMZW5ndGgpKSAvIDI7XG5cblx0ICAgICAgLy8gSWYgdGhpcyBmb3J3YXJkIHBhdGggb3ZlcmxhcHMgdGhlIHJldmVyc2UgcGF0aCBpbiB0aGlzIGRpYWdvbmFsLFxuXHQgICAgICAvLyB0aGVuIHRoaXMgaXMgdGhlIG1pZGRsZSBjaGFuZ2Ugb2YgdGhlIGluZGV4IGludGVydmFscy5cblx0ICAgICAgaWYgKGlSIDw9IGlNYXhSICYmIGFJbmRleGVzUltpUl0gLSAxIDw9IGFMYXN0KSB7XG5cdCAgICAgICAgLy8gVW5saWtlIHRoZSBNeWVycyBhbGdvcml0aG0gd2hpY2ggZmluZHMgb25seSB0aGUgbWlkZGxlIOKAnHNuYWtl4oCdXG5cdCAgICAgICAgLy8gdGhpcyBwYWNrYWdlIGNhbiBmaW5kIHR3byBjb21tb24gc3Vic2VxdWVuY2VzIHBlciBkaXZpc2lvbi5cblx0ICAgICAgICAvLyBMYXN0IHBvaW50IG9mIHByZXZpb3VzIHBhdGggc2VnbWVudCBpcyBvbiBhbiBhZGphY2VudCBkaWFnb25hbC5cblx0ICAgICAgICBjb25zdCBiTGFzdFByZXYgPSBiRiArIGFMYXN0UHJldiAtIChpbnNlcnQgPyBrRiArIDEgOiBrRiAtIDEpO1xuXG5cdCAgICAgICAgLy8gQmVjYXVzZSBvZiBpbnZhcmlhbnQgdGhhdCBpbnRlcnZhbHMgcHJlY2VkaW5nIHRoZSBtaWRkbGUgY2hhbmdlXG5cdCAgICAgICAgLy8gY2Fubm90IGhhdmUgY29tbW9uIGl0ZW1zIGF0IHRoZSBlbmQsXG5cdCAgICAgICAgLy8gbW92ZSBpbiByZXZlcnNlIGRpcmVjdGlvbiBhbG9uZyBhIGRpYWdvbmFsIG9mIGNvbW1vbiBpdGVtcy5cblx0ICAgICAgICBjb25zdCBuQ29tbW9uUiA9IGNvdW50Q29tbW9uSXRlbXNSKFxuXHQgICAgICAgICAgYVN0YXJ0LFxuXHQgICAgICAgICAgYUxhc3RQcmV2LFxuXHQgICAgICAgICAgYlN0YXJ0LFxuXHQgICAgICAgICAgYkxhc3RQcmV2LFxuXHQgICAgICAgICAgaXNDb21tb25cblx0ICAgICAgICApO1xuXHQgICAgICAgIGNvbnN0IGFJbmRleFByZXZGaXJzdCA9IGFMYXN0UHJldiAtIG5Db21tb25SO1xuXHQgICAgICAgIGNvbnN0IGJJbmRleFByZXZGaXJzdCA9IGJMYXN0UHJldiAtIG5Db21tb25SO1xuXHQgICAgICAgIGNvbnN0IGFFbmRQcmVjZWRpbmcgPSBhSW5kZXhQcmV2Rmlyc3QgKyAxO1xuXHQgICAgICAgIGNvbnN0IGJFbmRQcmVjZWRpbmcgPSBiSW5kZXhQcmV2Rmlyc3QgKyAxO1xuXHQgICAgICAgIGRpdmlzaW9uLm5DaGFuZ2VQcmVjZWRpbmcgPSBkIC0gMTtcblx0ICAgICAgICBpZiAoZCAtIDEgPT09IGFFbmRQcmVjZWRpbmcgKyBiRW5kUHJlY2VkaW5nIC0gYVN0YXJ0IC0gYlN0YXJ0KSB7XG5cdCAgICAgICAgICAvLyBPcHRpbWl6YXRpb246IG51bWJlciBvZiBwcmVjZWRpbmcgY2hhbmdlcyBpbiBmb3J3YXJkIGRpcmVjdGlvblxuXHQgICAgICAgICAgLy8gaXMgZXF1YWwgdG8gbnVtYmVyIG9mIGl0ZW1zIGluIHByZWNlZGluZyBpbnRlcnZhbCxcblx0ICAgICAgICAgIC8vIHRoZXJlZm9yZSBpdCBjYW5ub3QgY29udGFpbiBhbnkgY29tbW9uIGl0ZW1zLlxuXHQgICAgICAgICAgZGl2aXNpb24uYUVuZFByZWNlZGluZyA9IGFTdGFydDtcblx0ICAgICAgICAgIGRpdmlzaW9uLmJFbmRQcmVjZWRpbmcgPSBiU3RhcnQ7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIGRpdmlzaW9uLmFFbmRQcmVjZWRpbmcgPSBhRW5kUHJlY2VkaW5nO1xuXHQgICAgICAgICAgZGl2aXNpb24uYkVuZFByZWNlZGluZyA9IGJFbmRQcmVjZWRpbmc7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGRpdmlzaW9uLm5Db21tb25QcmVjZWRpbmcgPSBuQ29tbW9uUjtcblx0ICAgICAgICBpZiAobkNvbW1vblIgIT09IDApIHtcblx0ICAgICAgICAgIGRpdmlzaW9uLmFDb21tb25QcmVjZWRpbmcgPSBhRW5kUHJlY2VkaW5nO1xuXHQgICAgICAgICAgZGl2aXNpb24uYkNvbW1vblByZWNlZGluZyA9IGJFbmRQcmVjZWRpbmc7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGRpdmlzaW9uLm5Db21tb25Gb2xsb3dpbmcgPSBuQ29tbW9uRjtcblx0ICAgICAgICBpZiAobkNvbW1vbkYgIT09IDApIHtcblx0ICAgICAgICAgIGRpdmlzaW9uLmFDb21tb25Gb2xsb3dpbmcgPSBhRmlyc3QgKyAxO1xuXHQgICAgICAgICAgZGl2aXNpb24uYkNvbW1vbkZvbGxvd2luZyA9IGJGaXJzdCArIDE7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNvbnN0IGFTdGFydEZvbGxvd2luZyA9IGFMYXN0ICsgMTtcblx0ICAgICAgICBjb25zdCBiU3RhcnRGb2xsb3dpbmcgPSBiRmlyc3QgKyBuQ29tbW9uRiArIDE7XG5cdCAgICAgICAgZGl2aXNpb24ubkNoYW5nZUZvbGxvd2luZyA9IGQgLSAxO1xuXHQgICAgICAgIGlmIChkIC0gMSA9PT0gYUVuZCArIGJFbmQgLSBhU3RhcnRGb2xsb3dpbmcgLSBiU3RhcnRGb2xsb3dpbmcpIHtcblx0ICAgICAgICAgIC8vIE9wdGltaXphdGlvbjogbnVtYmVyIG9mIGNoYW5nZXMgaW4gcmV2ZXJzZSBkaXJlY3Rpb25cblx0ICAgICAgICAgIC8vIGlzIGVxdWFsIHRvIG51bWJlciBvZiBpdGVtcyBpbiBmb2xsb3dpbmcgaW50ZXJ2YWwsXG5cdCAgICAgICAgICAvLyB0aGVyZWZvcmUgaXQgY2Fubm90IGNvbnRhaW4gYW55IGNvbW1vbiBpdGVtcy5cblx0ICAgICAgICAgIGRpdmlzaW9uLmFTdGFydEZvbGxvd2luZyA9IGFFbmQ7XG5cdCAgICAgICAgICBkaXZpc2lvbi5iU3RhcnRGb2xsb3dpbmcgPSBiRW5kO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICBkaXZpc2lvbi5hU3RhcnRGb2xsb3dpbmcgPSBhU3RhcnRGb2xsb3dpbmc7XG5cdCAgICAgICAgICBkaXZpc2lvbi5iU3RhcnRGb2xsb3dpbmcgPSBiU3RhcnRGb2xsb3dpbmc7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0cnVlO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfVxuXHQgIHJldHVybiBmYWxzZTtcblx0fTtcblxuXHQvLyBBIGNvbXBsZXRlIGZ1bmN0aW9uIHRvIGV4dGVuZCByZXZlcnNlIHBhdGhzIGZyb20gKGQgLSAxKSB0byBkIGNoYW5nZXMuXG5cdC8vIFJldHVybiB0cnVlIGlmIGEgcGF0aCBvdmVybGFwcyBmb3J3YXJkIHBhdGggb2YgZCBjaGFuZ2VzIGluIGl0cyBkaWFnb25hbC5cblx0Y29uc3QgZXh0ZW5kT3ZlcmxhcHBhYmxlUGF0aHNSID0gKFxuXHQgIGQsXG5cdCAgYVN0YXJ0LFxuXHQgIGFFbmQsXG5cdCAgYlN0YXJ0LFxuXHQgIGJFbmQsXG5cdCAgaXNDb21tb24sXG5cdCAgYUluZGV4ZXNGLFxuXHQgIGlNYXhGLFxuXHQgIGFJbmRleGVzUixcblx0ICBpTWF4Uixcblx0ICBkaXZpc2lvbiAvLyB1cGRhdGUgcHJvcCB2YWx1ZXMgaWYgcmV0dXJuIHRydWVcblx0KSA9PiB7XG5cdCAgY29uc3QgYlIgPSBiRW5kIC0gYUVuZDsgLy8gYkluZGV4ID0gYlIgKyBhSW5kZXggLSBrUlxuXHQgIGNvbnN0IGFMZW5ndGggPSBhRW5kIC0gYVN0YXJ0O1xuXHQgIGNvbnN0IGJMZW5ndGggPSBiRW5kIC0gYlN0YXJ0O1xuXHQgIGNvbnN0IGJhRGVsdGFMZW5ndGggPSBiTGVuZ3RoIC0gYUxlbmd0aDsgLy8ga1IgPSBrRiArIGJhRGVsdGFMZW5ndGhcblxuXHQgIC8vIFJhbmdlIG9mIGRpYWdvbmFscyBpbiB3aGljaCBmb3J3YXJkIGFuZCByZXZlcnNlIHBhdGhzIG1pZ2h0IG92ZXJsYXAuXG5cdCAgY29uc3Qga01pbk92ZXJsYXBSID0gYmFEZWx0YUxlbmd0aCAtIGQ7IC8vIC1kIDw9IGtGXG5cdCAgY29uc3Qga01heE92ZXJsYXBSID0gYmFEZWx0YUxlbmd0aCArIGQ7IC8vIGtGIDw9IGRcblxuXHQgIGxldCBhSW5kZXhQcmV2MSA9IE5PVF9ZRVRfU0VUOyAvLyBwcmV2IHZhbHVlIG9mIFtpUiAtIDFdIGluIG5leHQgaXRlcmF0aW9uXG5cblx0ICAvLyBPcHRpbWl6YXRpb246IHNraXAgZGlhZ29uYWxzIGluIHdoaWNoIHBhdGhzIGNhbm5vdCBldmVyIG92ZXJsYXAuXG5cdCAgY29uc3QgblIgPSBkIDwgaU1heFIgPyBkIDogaU1heFI7XG5cblx0ICAvLyBUaGUgZGlhZ29uYWxzIGtSID0gZCAtIDIgKiBpUiBhcmUgb2RkIHdoZW4gZCBpcyBvZGQgYW5kIGV2ZW4gd2hlbiBkIGlzIGV2ZW4uXG5cdCAgZm9yIChsZXQgaVIgPSAwLCBrUiA9IGQ7IGlSIDw9IG5SOyBpUiArPSAxLCBrUiAtPSAyKSB7XG5cdCAgICAvLyBUbyBnZXQgZmlyc3QgcG9pbnQgb2YgcGF0aCBzZWdtZW50LCBtb3ZlIG9uZSBjaGFuZ2UgaW4gcmV2ZXJzZSBkaXJlY3Rpb25cblx0ICAgIC8vIGZyb20gbGFzdCBwb2ludCBvZiBwcmV2aW91cyBwYXRoIHNlZ21lbnQgaW4gYW4gYWRqYWNlbnQgZGlhZ29uYWwuXG5cdCAgICAvLyBJbiBmaXJzdCBpdGVyYXRpb24gd2hlbiBpUiA9PT0gMCBhbmQga1IgPT09IGQgYWx3YXlzIGluc2VydC5cblx0ICAgIC8vIEluIGxhc3QgcG9zc2libGUgaXRlcmF0aW9uIHdoZW4gaVIgPT09IGQgYW5kIGtSID09PSAtZCBhbHdheXMgZGVsZXRlLlxuXHQgICAgY29uc3QgaW5zZXJ0ID0gaVIgPT09IDAgfHwgKGlSICE9PSBkICYmIGFJbmRleGVzUltpUl0gPCBhSW5kZXhQcmV2MSk7XG5cdCAgICBjb25zdCBhTGFzdFByZXYgPSBpbnNlcnQgPyBhSW5kZXhlc1JbaVJdIDogYUluZGV4UHJldjE7XG5cdCAgICBjb25zdCBhRmlyc3QgPSBpbnNlcnRcblx0ICAgICAgPyBhTGFzdFByZXYgLy8gdmVydGljYWwgdG8gaW5zZXJ0IGZyb20gYlxuXHQgICAgICA6IGFMYXN0UHJldiAtIDE7IC8vIGhvcml6b250YWwgdG8gZGVsZXRlIGZyb20gYVxuXG5cdCAgICAvLyBUbyBnZXQgbGFzdCBwb2ludCBvZiBwYXRoIHNlZ21lbnQsIG1vdmUgYWxvbmcgZGlhZ29uYWwgb2YgY29tbW9uIGl0ZW1zLlxuXHQgICAgY29uc3QgYkZpcnN0ID0gYlIgKyBhRmlyc3QgLSBrUjtcblx0ICAgIGNvbnN0IG5Db21tb25SID0gY291bnRDb21tb25JdGVtc1IoXG5cdCAgICAgIGFTdGFydCxcblx0ICAgICAgYUZpcnN0IC0gMSxcblx0ICAgICAgYlN0YXJ0LFxuXHQgICAgICBiRmlyc3QgLSAxLFxuXHQgICAgICBpc0NvbW1vblxuXHQgICAgKTtcblx0ICAgIGNvbnN0IGFMYXN0ID0gYUZpcnN0IC0gbkNvbW1vblI7XG5cdCAgICBhSW5kZXhQcmV2MSA9IGFJbmRleGVzUltpUl07XG5cdCAgICBhSW5kZXhlc1JbaVJdID0gYUxhc3Q7XG5cdCAgICBpZiAoa01pbk92ZXJsYXBSIDw9IGtSICYmIGtSIDw9IGtNYXhPdmVybGFwUikge1xuXHQgICAgICAvLyBTb2x2ZSBmb3IgaUYgb2YgZm9yd2FyZCBwYXRoIHdpdGggZCBjaGFuZ2VzIGluIGRpYWdvbmFsIGtSOlxuXHQgICAgICAvLyBrRiA9IGtSIC0gYmFEZWx0YUxlbmd0aFxuXHQgICAgICAvLyBrRiA9IDIgKiBpRiAtIGRcblx0ICAgICAgY29uc3QgaUYgPSAoZCArIChrUiAtIGJhRGVsdGFMZW5ndGgpKSAvIDI7XG5cblx0ICAgICAgLy8gSWYgdGhpcyByZXZlcnNlIHBhdGggb3ZlcmxhcHMgdGhlIGZvcndhcmQgcGF0aCBpbiB0aGlzIGRpYWdvbmFsLFxuXHQgICAgICAvLyB0aGVuIHRoaXMgaXMgYSBtaWRkbGUgY2hhbmdlIG9mIHRoZSBpbmRleCBpbnRlcnZhbHMuXG5cdCAgICAgIGlmIChpRiA8PSBpTWF4RiAmJiBhTGFzdCAtIDEgPD0gYUluZGV4ZXNGW2lGXSkge1xuXHQgICAgICAgIGNvbnN0IGJMYXN0ID0gYkZpcnN0IC0gbkNvbW1vblI7XG5cdCAgICAgICAgZGl2aXNpb24ubkNoYW5nZVByZWNlZGluZyA9IGQ7XG5cdCAgICAgICAgaWYgKGQgPT09IGFMYXN0ICsgYkxhc3QgLSBhU3RhcnQgLSBiU3RhcnQpIHtcblx0ICAgICAgICAgIC8vIE9wdGltaXphdGlvbjogbnVtYmVyIG9mIGNoYW5nZXMgaW4gcmV2ZXJzZSBkaXJlY3Rpb25cblx0ICAgICAgICAgIC8vIGlzIGVxdWFsIHRvIG51bWJlciBvZiBpdGVtcyBpbiBwcmVjZWRpbmcgaW50ZXJ2YWwsXG5cdCAgICAgICAgICAvLyB0aGVyZWZvcmUgaXQgY2Fubm90IGNvbnRhaW4gYW55IGNvbW1vbiBpdGVtcy5cblx0ICAgICAgICAgIGRpdmlzaW9uLmFFbmRQcmVjZWRpbmcgPSBhU3RhcnQ7XG5cdCAgICAgICAgICBkaXZpc2lvbi5iRW5kUHJlY2VkaW5nID0gYlN0YXJ0O1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICBkaXZpc2lvbi5hRW5kUHJlY2VkaW5nID0gYUxhc3Q7XG5cdCAgICAgICAgICBkaXZpc2lvbi5iRW5kUHJlY2VkaW5nID0gYkxhc3Q7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGRpdmlzaW9uLm5Db21tb25QcmVjZWRpbmcgPSBuQ29tbW9uUjtcblx0ICAgICAgICBpZiAobkNvbW1vblIgIT09IDApIHtcblx0ICAgICAgICAgIC8vIFRoZSBsYXN0IHBvaW50IG9mIHJldmVyc2UgcGF0aCBzZWdtZW50IGlzIHN0YXJ0IG9mIGNvbW1vbiBzdWJzZXF1ZW5jZS5cblx0ICAgICAgICAgIGRpdmlzaW9uLmFDb21tb25QcmVjZWRpbmcgPSBhTGFzdDtcblx0ICAgICAgICAgIGRpdmlzaW9uLmJDb21tb25QcmVjZWRpbmcgPSBiTGFzdDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZGl2aXNpb24ubkNoYW5nZUZvbGxvd2luZyA9IGQgLSAxO1xuXHQgICAgICAgIGlmIChkID09PSAxKSB7XG5cdCAgICAgICAgICAvLyBUaGVyZSBpcyBubyBwcmV2aW91cyBwYXRoIHNlZ21lbnQuXG5cdCAgICAgICAgICBkaXZpc2lvbi5uQ29tbW9uRm9sbG93aW5nID0gMDtcblx0ICAgICAgICAgIGRpdmlzaW9uLmFTdGFydEZvbGxvd2luZyA9IGFFbmQ7XG5cdCAgICAgICAgICBkaXZpc2lvbi5iU3RhcnRGb2xsb3dpbmcgPSBiRW5kO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAvLyBVbmxpa2UgdGhlIE15ZXJzIGFsZ29yaXRobSB3aGljaCBmaW5kcyBvbmx5IHRoZSBtaWRkbGUg4oCcc25ha2XigJ1cblx0ICAgICAgICAgIC8vIHRoaXMgcGFja2FnZSBjYW4gZmluZCB0d28gY29tbW9uIHN1YnNlcXVlbmNlcyBwZXIgZGl2aXNpb24uXG5cdCAgICAgICAgICAvLyBMYXN0IHBvaW50IG9mIHByZXZpb3VzIHBhdGggc2VnbWVudCBpcyBvbiBhbiBhZGphY2VudCBkaWFnb25hbC5cblx0ICAgICAgICAgIGNvbnN0IGJMYXN0UHJldiA9IGJSICsgYUxhc3RQcmV2IC0gKGluc2VydCA/IGtSIC0gMSA6IGtSICsgMSk7XG5cblx0ICAgICAgICAgIC8vIEJlY2F1c2Ugb2YgaW52YXJpYW50IHRoYXQgaW50ZXJ2YWxzIGZvbGxvd2luZyB0aGUgbWlkZGxlIGNoYW5nZVxuXHQgICAgICAgICAgLy8gY2Fubm90IGhhdmUgY29tbW9uIGl0ZW1zIGF0IHRoZSBzdGFydCxcblx0ICAgICAgICAgIC8vIG1vdmUgaW4gZm9yd2FyZCBkaXJlY3Rpb24gYWxvbmcgYSBkaWFnb25hbCBvZiBjb21tb24gaXRlbXMuXG5cdCAgICAgICAgICBjb25zdCBuQ29tbW9uRiA9IGNvdW50Q29tbW9uSXRlbXNGKFxuXHQgICAgICAgICAgICBhTGFzdFByZXYsXG5cdCAgICAgICAgICAgIGFFbmQsXG5cdCAgICAgICAgICAgIGJMYXN0UHJldixcblx0ICAgICAgICAgICAgYkVuZCxcblx0ICAgICAgICAgICAgaXNDb21tb25cblx0ICAgICAgICAgICk7XG5cdCAgICAgICAgICBkaXZpc2lvbi5uQ29tbW9uRm9sbG93aW5nID0gbkNvbW1vbkY7XG5cdCAgICAgICAgICBpZiAobkNvbW1vbkYgIT09IDApIHtcblx0ICAgICAgICAgICAgLy8gVGhlIGxhc3QgcG9pbnQgb2YgcmV2ZXJzZSBwYXRoIHNlZ21lbnQgaXMgc3RhcnQgb2YgY29tbW9uIHN1YnNlcXVlbmNlLlxuXHQgICAgICAgICAgICBkaXZpc2lvbi5hQ29tbW9uRm9sbG93aW5nID0gYUxhc3RQcmV2O1xuXHQgICAgICAgICAgICBkaXZpc2lvbi5iQ29tbW9uRm9sbG93aW5nID0gYkxhc3RQcmV2O1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgICAgY29uc3QgYVN0YXJ0Rm9sbG93aW5nID0gYUxhc3RQcmV2ICsgbkNvbW1vbkY7IC8vIGFGaXJzdFByZXZcblx0ICAgICAgICAgIGNvbnN0IGJTdGFydEZvbGxvd2luZyA9IGJMYXN0UHJldiArIG5Db21tb25GOyAvLyBiRmlyc3RQcmV2XG5cblx0ICAgICAgICAgIGlmIChkIC0gMSA9PT0gYUVuZCArIGJFbmQgLSBhU3RhcnRGb2xsb3dpbmcgLSBiU3RhcnRGb2xsb3dpbmcpIHtcblx0ICAgICAgICAgICAgLy8gT3B0aW1pemF0aW9uOiBudW1iZXIgb2YgY2hhbmdlcyBpbiBmb3J3YXJkIGRpcmVjdGlvblxuXHQgICAgICAgICAgICAvLyBpcyBlcXVhbCB0byBudW1iZXIgb2YgaXRlbXMgaW4gZm9sbG93aW5nIGludGVydmFsLFxuXHQgICAgICAgICAgICAvLyB0aGVyZWZvcmUgaXQgY2Fubm90IGNvbnRhaW4gYW55IGNvbW1vbiBpdGVtcy5cblx0ICAgICAgICAgICAgZGl2aXNpb24uYVN0YXJ0Rm9sbG93aW5nID0gYUVuZDtcblx0ICAgICAgICAgICAgZGl2aXNpb24uYlN0YXJ0Rm9sbG93aW5nID0gYkVuZDtcblx0ICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIGRpdmlzaW9uLmFTdGFydEZvbGxvd2luZyA9IGFTdGFydEZvbGxvd2luZztcblx0ICAgICAgICAgICAgZGl2aXNpb24uYlN0YXJ0Rm9sbG93aW5nID0gYlN0YXJ0Rm9sbG93aW5nO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdHJ1ZTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH1cblx0ICByZXR1cm4gZmFsc2U7XG5cdH07XG5cblx0Ly8gR2l2ZW4gaW5kZXggaW50ZXJ2YWxzIGFuZCBpbnB1dCBmdW5jdGlvbiB0byBjb21wYXJlIGl0ZW1zIGF0IGluZGV4ZXMsXG5cdC8vIGRpdmlkZSBhdCB0aGUgbWlkZGxlIGNoYW5nZS5cblx0Ly9cblx0Ly8gRE8gTk9UIENBTEwgaWYgc3RhcnQgPT09IGVuZCwgYmVjYXVzZSBpbnRlcnZhbCBjYW5ub3QgY29udGFpbiBjb21tb24gaXRlbXNcblx0Ly8gYW5kIGJlY2F1c2UgdGhpcyBmdW5jdGlvbiB3aWxsIHRocm93IHRoZSDigJxubyBvdmVybGFw4oCdIGVycm9yLlxuXHRjb25zdCBkaXZpZGUgPSAoXG5cdCAgbkNoYW5nZSxcblx0ICBhU3RhcnQsXG5cdCAgYUVuZCxcblx0ICBiU3RhcnQsXG5cdCAgYkVuZCxcblx0ICBpc0NvbW1vbixcblx0ICBhSW5kZXhlc0YsXG5cdCAgYUluZGV4ZXNSLFxuXHQgIGRpdmlzaW9uIC8vIG91dHB1dFxuXHQpID0+IHtcblx0ICBjb25zdCBiRiA9IGJTdGFydCAtIGFTdGFydDsgLy8gYkluZGV4ID0gYkYgKyBhSW5kZXggLSBrRlxuXHQgIGNvbnN0IGJSID0gYkVuZCAtIGFFbmQ7IC8vIGJJbmRleCA9IGJSICsgYUluZGV4IC0ga1Jcblx0ICBjb25zdCBhTGVuZ3RoID0gYUVuZCAtIGFTdGFydDtcblx0ICBjb25zdCBiTGVuZ3RoID0gYkVuZCAtIGJTdGFydDtcblxuXHQgIC8vIEJlY2F1c2UgZ3JhcGggaGFzIHNxdWFyZSBvciBwb3J0cmFpdCBvcmllbnRhdGlvbixcblx0ICAvLyBsZW5ndGggZGlmZmVyZW5jZSBpcyBtaW5pbXVtIG51bWJlciBvZiBpdGVtcyB0byBpbnNlcnQgZnJvbSBiLlxuXHQgIC8vIENvcnJlc3BvbmRpbmcgZm9yd2FyZCBhbmQgcmV2ZXJzZSBkaWFnb25hbHMgaW4gZ3JhcGhcblx0ICAvLyBkZXBlbmQgb24gbGVuZ3RoIGRpZmZlcmVuY2Ugb2YgdGhlIHNlcXVlbmNlczpcblx0ICAvLyBrRiA9IGtSIC0gYmFEZWx0YUxlbmd0aFxuXHQgIC8vIGtSID0ga0YgKyBiYURlbHRhTGVuZ3RoXG5cdCAgY29uc3QgYmFEZWx0YUxlbmd0aCA9IGJMZW5ndGggLSBhTGVuZ3RoO1xuXG5cdCAgLy8gT3B0aW1pemF0aW9uOiBtYXggZGlhZ29uYWwgaW4gZ3JhcGggaW50ZXJzZWN0cyBjb3JuZXIgb2Ygc2hvcnRlciBzaWRlLlxuXHQgIGxldCBpTWF4RiA9IGFMZW5ndGg7XG5cdCAgbGV0IGlNYXhSID0gYUxlbmd0aDtcblxuXHQgIC8vIEluaXRpYWxpemUgbm8gY2hhbmdlcyB5ZXQgaW4gZm9yd2FyZCBvciByZXZlcnNlIGRpcmVjdGlvbjpcblx0ICBhSW5kZXhlc0ZbMF0gPSBhU3RhcnQgLSAxOyAvLyBhdCBvcGVuIHN0YXJ0IG9mIGludGVydmFsLCBvdXRzaWRlIGNsb3NlZCBzdGFydFxuXHQgIGFJbmRleGVzUlswXSA9IGFFbmQ7IC8vIGF0IG9wZW4gZW5kIG9mIGludGVydmFsXG5cblx0ICBpZiAoYmFEZWx0YUxlbmd0aCAlIDIgPT09IDApIHtcblx0ICAgIC8vIFRoZSBudW1iZXIgb2YgY2hhbmdlcyBpbiBwYXRocyBpcyAyICogZCBpZiBsZW5ndGggZGlmZmVyZW5jZSBpcyBldmVuLlxuXHQgICAgY29uc3QgZE1pbiA9IChuQ2hhbmdlIHx8IGJhRGVsdGFMZW5ndGgpIC8gMjtcblx0ICAgIGNvbnN0IGRNYXggPSAoYUxlbmd0aCArIGJMZW5ndGgpIC8gMjtcblx0ICAgIGZvciAobGV0IGQgPSAxOyBkIDw9IGRNYXg7IGQgKz0gMSkge1xuXHQgICAgICBpTWF4RiA9IGV4dGVuZFBhdGhzRihkLCBhRW5kLCBiRW5kLCBiRiwgaXNDb21tb24sIGFJbmRleGVzRiwgaU1heEYpO1xuXHQgICAgICBpZiAoZCA8IGRNaW4pIHtcblx0ICAgICAgICBpTWF4UiA9IGV4dGVuZFBhdGhzUihkLCBhU3RhcnQsIGJTdGFydCwgYlIsIGlzQ29tbW9uLCBhSW5kZXhlc1IsIGlNYXhSKTtcblx0ICAgICAgfSBlbHNlIGlmIChcblx0ICAgICAgICAvLyBJZiBhIHJldmVyc2UgcGF0aCBvdmVybGFwcyBhIGZvcndhcmQgcGF0aCBpbiB0aGUgc2FtZSBkaWFnb25hbCxcblx0ICAgICAgICAvLyByZXR1cm4gYSBkaXZpc2lvbiBvZiB0aGUgaW5kZXggaW50ZXJ2YWxzIGF0IHRoZSBtaWRkbGUgY2hhbmdlLlxuXHQgICAgICAgIGV4dGVuZE92ZXJsYXBwYWJsZVBhdGhzUihcblx0ICAgICAgICAgIGQsXG5cdCAgICAgICAgICBhU3RhcnQsXG5cdCAgICAgICAgICBhRW5kLFxuXHQgICAgICAgICAgYlN0YXJ0LFxuXHQgICAgICAgICAgYkVuZCxcblx0ICAgICAgICAgIGlzQ29tbW9uLFxuXHQgICAgICAgICAgYUluZGV4ZXNGLFxuXHQgICAgICAgICAgaU1heEYsXG5cdCAgICAgICAgICBhSW5kZXhlc1IsXG5cdCAgICAgICAgICBpTWF4Uixcblx0ICAgICAgICAgIGRpdmlzaW9uXG5cdCAgICAgICAgKVxuXHQgICAgICApIHtcblx0ICAgICAgICByZXR1cm47XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9IGVsc2Uge1xuXHQgICAgLy8gVGhlIG51bWJlciBvZiBjaGFuZ2VzIGluIHBhdGhzIGlzIDIgKiBkIC0gMSBpZiBsZW5ndGggZGlmZmVyZW5jZSBpcyBvZGQuXG5cdCAgICBjb25zdCBkTWluID0gKChuQ2hhbmdlIHx8IGJhRGVsdGFMZW5ndGgpICsgMSkgLyAyO1xuXHQgICAgY29uc3QgZE1heCA9IChhTGVuZ3RoICsgYkxlbmd0aCArIDEpIC8gMjtcblxuXHQgICAgLy8gVW5yb2xsIGZpcnN0IGhhbGYgaXRlcmF0aW9uIHNvIGxvb3AgZXh0ZW5kcyB0aGUgcmVsZXZhbnQgcGFpcnMgb2YgcGF0aHMuXG5cdCAgICAvLyBCZWNhdXNlIG9mIGludmFyaWFudCB0aGF0IGludGVydmFscyBoYXZlIG5vIGNvbW1vbiBpdGVtcyBhdCBzdGFydCBvciBlbmQsXG5cdCAgICAvLyBhbmQgbGltaXRhdGlvbiBub3QgdG8gY2FsbCBkaXZpZGUgd2l0aCBlbXB0eSBpbnRlcnZhbHMsXG5cdCAgICAvLyB0aGVyZWZvcmUgaXQgY2Fubm90IGJlIGNhbGxlZCBpZiBhIGZvcndhcmQgcGF0aCB3aXRoIG9uZSBjaGFuZ2Vcblx0ICAgIC8vIHdvdWxkIG92ZXJsYXAgYSByZXZlcnNlIHBhdGggd2l0aCBubyBjaGFuZ2VzLCBldmVuIGlmIGRNaW4gPT09IDEuXG5cdCAgICBsZXQgZCA9IDE7XG5cdCAgICBpTWF4RiA9IGV4dGVuZFBhdGhzRihkLCBhRW5kLCBiRW5kLCBiRiwgaXNDb21tb24sIGFJbmRleGVzRiwgaU1heEYpO1xuXHQgICAgZm9yIChkICs9IDE7IGQgPD0gZE1heDsgZCArPSAxKSB7XG5cdCAgICAgIGlNYXhSID0gZXh0ZW5kUGF0aHNSKFxuXHQgICAgICAgIGQgLSAxLFxuXHQgICAgICAgIGFTdGFydCxcblx0ICAgICAgICBiU3RhcnQsXG5cdCAgICAgICAgYlIsXG5cdCAgICAgICAgaXNDb21tb24sXG5cdCAgICAgICAgYUluZGV4ZXNSLFxuXHQgICAgICAgIGlNYXhSXG5cdCAgICAgICk7XG5cdCAgICAgIGlmIChkIDwgZE1pbikge1xuXHQgICAgICAgIGlNYXhGID0gZXh0ZW5kUGF0aHNGKGQsIGFFbmQsIGJFbmQsIGJGLCBpc0NvbW1vbiwgYUluZGV4ZXNGLCBpTWF4Rik7XG5cdCAgICAgIH0gZWxzZSBpZiAoXG5cdCAgICAgICAgLy8gSWYgYSBmb3J3YXJkIHBhdGggb3ZlcmxhcHMgYSByZXZlcnNlIHBhdGggaW4gdGhlIHNhbWUgZGlhZ29uYWwsXG5cdCAgICAgICAgLy8gcmV0dXJuIGEgZGl2aXNpb24gb2YgdGhlIGluZGV4IGludGVydmFscyBhdCB0aGUgbWlkZGxlIGNoYW5nZS5cblx0ICAgICAgICBleHRlbmRPdmVybGFwcGFibGVQYXRoc0YoXG5cdCAgICAgICAgICBkLFxuXHQgICAgICAgICAgYVN0YXJ0LFxuXHQgICAgICAgICAgYUVuZCxcblx0ICAgICAgICAgIGJTdGFydCxcblx0ICAgICAgICAgIGJFbmQsXG5cdCAgICAgICAgICBpc0NvbW1vbixcblx0ICAgICAgICAgIGFJbmRleGVzRixcblx0ICAgICAgICAgIGlNYXhGLFxuXHQgICAgICAgICAgYUluZGV4ZXNSLFxuXHQgICAgICAgICAgaU1heFIsXG5cdCAgICAgICAgICBkaXZpc2lvblxuXHQgICAgICAgIClcblx0ICAgICAgKSB7XG5cdCAgICAgICAgcmV0dXJuO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfVxuXG5cdCAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0ICB0aHJvdyBuZXcgRXJyb3IoXG5cdCAgICBgJHtwa2d9OiBubyBvdmVybGFwIGFTdGFydD0ke2FTdGFydH0gYUVuZD0ke2FFbmR9IGJTdGFydD0ke2JTdGFydH0gYkVuZD0ke2JFbmR9YFxuXHQgICk7XG5cdH07XG5cblx0Ly8gR2l2ZW4gaW5kZXggaW50ZXJ2YWxzIGFuZCBpbnB1dCBmdW5jdGlvbiB0byBjb21wYXJlIGl0ZW1zIGF0IGluZGV4ZXMsXG5cdC8vIHJldHVybiBieSBvdXRwdXQgZnVuY3Rpb24gdGhlIG51bWJlciBvZiBhZGphY2VudCBpdGVtcyBhbmQgc3RhcnRpbmcgaW5kZXhlc1xuXHQvLyBvZiBlYWNoIGNvbW1vbiBzdWJzZXF1ZW5jZS4gRGl2aWRlIGFuZCBjb25xdWVyIHdpdGggb25seSBsaW5lYXIgc3BhY2UuXG5cdC8vXG5cdC8vIFRoZSBpbmRleCBpbnRlcnZhbHMgYXJlIGhhbGYgb3BlbiBbc3RhcnQsIGVuZCkgbGlrZSBhcnJheSBzbGljZSBtZXRob2QuXG5cdC8vIERPIE5PVCBDQUxMIGlmIHN0YXJ0ID09PSBlbmQsIGJlY2F1c2UgaW50ZXJ2YWwgY2Fubm90IGNvbnRhaW4gY29tbW9uIGl0ZW1zXG5cdC8vIGFuZCBiZWNhdXNlIGRpdmlkZSBmdW5jdGlvbiB3aWxsIHRocm93IHRoZSDigJxubyBvdmVybGFw4oCdIGVycm9yLlxuXHRjb25zdCBmaW5kU3Vic2VxdWVuY2VzID0gKFxuXHQgIG5DaGFuZ2UsXG5cdCAgYVN0YXJ0LFxuXHQgIGFFbmQsXG5cdCAgYlN0YXJ0LFxuXHQgIGJFbmQsXG5cdCAgdHJhbnNwb3NlZCxcblx0ICBjYWxsYmFja3MsXG5cdCAgYUluZGV4ZXNGLFxuXHQgIGFJbmRleGVzUixcblx0ICBkaXZpc2lvbiAvLyB0ZW1wb3JhcnkgbWVtb3J5LCBub3QgaW5wdXQgbm9yIG91dHB1dFxuXHQpID0+IHtcblx0ICBpZiAoYkVuZCAtIGJTdGFydCA8IGFFbmQgLSBhU3RhcnQpIHtcblx0ICAgIC8vIFRyYW5zcG9zZSBncmFwaCBzbyBpdCBoYXMgcG9ydHJhaXQgaW5zdGVhZCBvZiBsYW5kc2NhcGUgb3JpZW50YXRpb24uXG5cdCAgICAvLyBBbHdheXMgY29tcGFyZSBzaG9ydGVyIHRvIGxvbmdlciBzZXF1ZW5jZSBmb3IgY29uc2lzdGVuY3kgYW5kIG9wdGltaXphdGlvbi5cblx0ICAgIHRyYW5zcG9zZWQgPSAhdHJhbnNwb3NlZDtcblx0ICAgIGlmICh0cmFuc3Bvc2VkICYmIGNhbGxiYWNrcy5sZW5ndGggPT09IDEpIHtcblx0ICAgICAgLy8gTGF6aWx5IHdyYXAgY2FsbGJhY2sgZnVuY3Rpb25zIHRvIHN3YXAgYXJncyBpZiBncmFwaCBpcyB0cmFuc3Bvc2VkLlxuXHQgICAgICBjb25zdCB7Zm91bmRTdWJzZXF1ZW5jZSwgaXNDb21tb259ID0gY2FsbGJhY2tzWzBdO1xuXHQgICAgICBjYWxsYmFja3NbMV0gPSB7XG5cdCAgICAgICAgZm91bmRTdWJzZXF1ZW5jZTogKG5Db21tb24sIGJDb21tb24sIGFDb21tb24pID0+IHtcblx0ICAgICAgICAgIGZvdW5kU3Vic2VxdWVuY2UobkNvbW1vbiwgYUNvbW1vbiwgYkNvbW1vbik7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBpc0NvbW1vbjogKGJJbmRleCwgYUluZGV4KSA9PiBpc0NvbW1vbihhSW5kZXgsIGJJbmRleClcblx0ICAgICAgfTtcblx0ICAgIH1cblx0ICAgIGNvbnN0IHRTdGFydCA9IGFTdGFydDtcblx0ICAgIGNvbnN0IHRFbmQgPSBhRW5kO1xuXHQgICAgYVN0YXJ0ID0gYlN0YXJ0O1xuXHQgICAgYUVuZCA9IGJFbmQ7XG5cdCAgICBiU3RhcnQgPSB0U3RhcnQ7XG5cdCAgICBiRW5kID0gdEVuZDtcblx0ICB9XG5cdCAgY29uc3Qge2ZvdW5kU3Vic2VxdWVuY2UsIGlzQ29tbW9ufSA9IGNhbGxiYWNrc1t0cmFuc3Bvc2VkID8gMSA6IDBdO1xuXG5cdCAgLy8gRGl2aWRlIHRoZSBpbmRleCBpbnRlcnZhbHMgYXQgdGhlIG1pZGRsZSBjaGFuZ2UuXG5cdCAgZGl2aWRlKFxuXHQgICAgbkNoYW5nZSxcblx0ICAgIGFTdGFydCxcblx0ICAgIGFFbmQsXG5cdCAgICBiU3RhcnQsXG5cdCAgICBiRW5kLFxuXHQgICAgaXNDb21tb24sXG5cdCAgICBhSW5kZXhlc0YsXG5cdCAgICBhSW5kZXhlc1IsXG5cdCAgICBkaXZpc2lvblxuXHQgICk7XG5cdCAgY29uc3Qge1xuXHQgICAgbkNoYW5nZVByZWNlZGluZyxcblx0ICAgIGFFbmRQcmVjZWRpbmcsXG5cdCAgICBiRW5kUHJlY2VkaW5nLFxuXHQgICAgbkNvbW1vblByZWNlZGluZyxcblx0ICAgIGFDb21tb25QcmVjZWRpbmcsXG5cdCAgICBiQ29tbW9uUHJlY2VkaW5nLFxuXHQgICAgbkNvbW1vbkZvbGxvd2luZyxcblx0ICAgIGFDb21tb25Gb2xsb3dpbmcsXG5cdCAgICBiQ29tbW9uRm9sbG93aW5nLFxuXHQgICAgbkNoYW5nZUZvbGxvd2luZyxcblx0ICAgIGFTdGFydEZvbGxvd2luZyxcblx0ICAgIGJTdGFydEZvbGxvd2luZ1xuXHQgIH0gPSBkaXZpc2lvbjtcblxuXHQgIC8vIFVubGVzcyBlaXRoZXIgaW5kZXggaW50ZXJ2YWwgaXMgZW1wdHksIHRoZXkgbWlnaHQgY29udGFpbiBjb21tb24gaXRlbXMuXG5cdCAgaWYgKGFTdGFydCA8IGFFbmRQcmVjZWRpbmcgJiYgYlN0YXJ0IDwgYkVuZFByZWNlZGluZykge1xuXHQgICAgLy8gUmVjdXJzZWx5IGZpbmQgYW5kIHJldHVybiBjb21tb24gc3Vic2VxdWVuY2VzIHByZWNlZGluZyB0aGUgZGl2aXNpb24uXG5cdCAgICBmaW5kU3Vic2VxdWVuY2VzKFxuXHQgICAgICBuQ2hhbmdlUHJlY2VkaW5nLFxuXHQgICAgICBhU3RhcnQsXG5cdCAgICAgIGFFbmRQcmVjZWRpbmcsXG5cdCAgICAgIGJTdGFydCxcblx0ICAgICAgYkVuZFByZWNlZGluZyxcblx0ICAgICAgdHJhbnNwb3NlZCxcblx0ICAgICAgY2FsbGJhY2tzLFxuXHQgICAgICBhSW5kZXhlc0YsXG5cdCAgICAgIGFJbmRleGVzUixcblx0ICAgICAgZGl2aXNpb25cblx0ICAgICk7XG5cdCAgfVxuXG5cdCAgLy8gUmV0dXJuIGNvbW1vbiBzdWJzZXF1ZW5jZXMgdGhhdCBhcmUgYWRqYWNlbnQgdG8gdGhlIG1pZGRsZSBjaGFuZ2UuXG5cdCAgaWYgKG5Db21tb25QcmVjZWRpbmcgIT09IDApIHtcblx0ICAgIGZvdW5kU3Vic2VxdWVuY2UobkNvbW1vblByZWNlZGluZywgYUNvbW1vblByZWNlZGluZywgYkNvbW1vblByZWNlZGluZyk7XG5cdCAgfVxuXHQgIGlmIChuQ29tbW9uRm9sbG93aW5nICE9PSAwKSB7XG5cdCAgICBmb3VuZFN1YnNlcXVlbmNlKG5Db21tb25Gb2xsb3dpbmcsIGFDb21tb25Gb2xsb3dpbmcsIGJDb21tb25Gb2xsb3dpbmcpO1xuXHQgIH1cblxuXHQgIC8vIFVubGVzcyBlaXRoZXIgaW5kZXggaW50ZXJ2YWwgaXMgZW1wdHksIHRoZXkgbWlnaHQgY29udGFpbiBjb21tb24gaXRlbXMuXG5cdCAgaWYgKGFTdGFydEZvbGxvd2luZyA8IGFFbmQgJiYgYlN0YXJ0Rm9sbG93aW5nIDwgYkVuZCkge1xuXHQgICAgLy8gUmVjdXJzZWx5IGZpbmQgYW5kIHJldHVybiBjb21tb24gc3Vic2VxdWVuY2VzIGZvbGxvd2luZyB0aGUgZGl2aXNpb24uXG5cdCAgICBmaW5kU3Vic2VxdWVuY2VzKFxuXHQgICAgICBuQ2hhbmdlRm9sbG93aW5nLFxuXHQgICAgICBhU3RhcnRGb2xsb3dpbmcsXG5cdCAgICAgIGFFbmQsXG5cdCAgICAgIGJTdGFydEZvbGxvd2luZyxcblx0ICAgICAgYkVuZCxcblx0ICAgICAgdHJhbnNwb3NlZCxcblx0ICAgICAgY2FsbGJhY2tzLFxuXHQgICAgICBhSW5kZXhlc0YsXG5cdCAgICAgIGFJbmRleGVzUixcblx0ICAgICAgZGl2aXNpb25cblx0ICAgICk7XG5cdCAgfVxuXHR9O1xuXHRjb25zdCB2YWxpZGF0ZUxlbmd0aCA9IChuYW1lLCBhcmcpID0+IHtcblx0ICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicpIHtcblx0ICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7cGtnfTogJHtuYW1lfSB0eXBlb2YgJHt0eXBlb2YgYXJnfSBpcyBub3QgYSBudW1iZXJgKTtcblx0ICB9XG5cdCAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihhcmcpKSB7XG5cdCAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgJHtwa2d9OiAke25hbWV9IHZhbHVlICR7YXJnfSBpcyBub3QgYSBzYWZlIGludGVnZXJgKTtcblx0ICB9XG5cdCAgaWYgKGFyZyA8IDApIHtcblx0ICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGAke3BrZ306ICR7bmFtZX0gdmFsdWUgJHthcmd9IGlzIGEgbmVnYXRpdmUgaW50ZWdlcmApO1xuXHQgIH1cblx0fTtcblx0Y29uc3QgdmFsaWRhdGVDYWxsYmFjayA9IChuYW1lLCBhcmcpID0+IHtcblx0ICBjb25zdCB0eXBlID0gdHlwZW9mIGFyZztcblx0ICBpZiAodHlwZSAhPT0gJ2Z1bmN0aW9uJykge1xuXHQgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtwa2d9OiAke25hbWV9IHR5cGVvZiAke3R5cGV9IGlzIG5vdCBhIGZ1bmN0aW9uYCk7XG5cdCAgfVxuXHR9O1xuXG5cdC8vIENvbXBhcmUgaXRlbXMgaW4gdHdvIHNlcXVlbmNlcyB0byBmaW5kIGEgbG9uZ2VzdCBjb21tb24gc3Vic2VxdWVuY2UuXG5cdC8vIEdpdmVuIGxlbmd0aHMgb2Ygc2VxdWVuY2VzIGFuZCBpbnB1dCBmdW5jdGlvbiB0byBjb21wYXJlIGl0ZW1zIGF0IGluZGV4ZXMsXG5cdC8vIHJldHVybiBieSBvdXRwdXQgZnVuY3Rpb24gdGhlIG51bWJlciBvZiBhZGphY2VudCBpdGVtcyBhbmQgc3RhcnRpbmcgaW5kZXhlc1xuXHQvLyBvZiBlYWNoIGNvbW1vbiBzdWJzZXF1ZW5jZS5cblx0ZnVuY3Rpb24gZGlmZlNlcXVlbmNlKGFMZW5ndGgsIGJMZW5ndGgsIGlzQ29tbW9uLCBmb3VuZFN1YnNlcXVlbmNlKSB7XG5cdCAgdmFsaWRhdGVMZW5ndGgoJ2FMZW5ndGgnLCBhTGVuZ3RoKTtcblx0ICB2YWxpZGF0ZUxlbmd0aCgnYkxlbmd0aCcsIGJMZW5ndGgpO1xuXHQgIHZhbGlkYXRlQ2FsbGJhY2soJ2lzQ29tbW9uJywgaXNDb21tb24pO1xuXHQgIHZhbGlkYXRlQ2FsbGJhY2soJ2ZvdW5kU3Vic2VxdWVuY2UnLCBmb3VuZFN1YnNlcXVlbmNlKTtcblxuXHQgIC8vIENvdW50IGNvbW1vbiBpdGVtcyBmcm9tIHRoZSBzdGFydCBpbiB0aGUgZm9yd2FyZCBkaXJlY3Rpb24uXG5cdCAgY29uc3QgbkNvbW1vbkYgPSBjb3VudENvbW1vbkl0ZW1zRigwLCBhTGVuZ3RoLCAwLCBiTGVuZ3RoLCBpc0NvbW1vbik7XG5cdCAgaWYgKG5Db21tb25GICE9PSAwKSB7XG5cdCAgICBmb3VuZFN1YnNlcXVlbmNlKG5Db21tb25GLCAwLCAwKTtcblx0ICB9XG5cblx0ICAvLyBVbmxlc3MgYm90aCBzZXF1ZW5jZXMgY29uc2lzdCBvZiBjb21tb24gaXRlbXMgb25seSxcblx0ICAvLyBmaW5kIGNvbW1vbiBpdGVtcyBpbiB0aGUgaGFsZi10cmltbWVkIGluZGV4IGludGVydmFscy5cblx0ICBpZiAoYUxlbmd0aCAhPT0gbkNvbW1vbkYgfHwgYkxlbmd0aCAhPT0gbkNvbW1vbkYpIHtcblx0ICAgIC8vIEludmFyaWFudDogaW50ZXJ2YWxzIGRvIG5vdCBoYXZlIGNvbW1vbiBpdGVtcyBhdCB0aGUgc3RhcnQuXG5cdCAgICAvLyBUaGUgc3RhcnQgb2YgYW4gaW5kZXggaW50ZXJ2YWwgaXMgY2xvc2VkIGxpa2UgYXJyYXkgc2xpY2UgbWV0aG9kLlxuXHQgICAgY29uc3QgYVN0YXJ0ID0gbkNvbW1vbkY7XG5cdCAgICBjb25zdCBiU3RhcnQgPSBuQ29tbW9uRjtcblxuXHQgICAgLy8gQ291bnQgY29tbW9uIGl0ZW1zIGZyb20gdGhlIGVuZCBpbiB0aGUgcmV2ZXJzZSBkaXJlY3Rpb24uXG5cdCAgICBjb25zdCBuQ29tbW9uUiA9IGNvdW50Q29tbW9uSXRlbXNSKFxuXHQgICAgICBhU3RhcnQsXG5cdCAgICAgIGFMZW5ndGggLSAxLFxuXHQgICAgICBiU3RhcnQsXG5cdCAgICAgIGJMZW5ndGggLSAxLFxuXHQgICAgICBpc0NvbW1vblxuXHQgICAgKTtcblxuXHQgICAgLy8gSW52YXJpYW50OiBpbnRlcnZhbHMgZG8gbm90IGhhdmUgY29tbW9uIGl0ZW1zIGF0IHRoZSBlbmQuXG5cdCAgICAvLyBUaGUgZW5kIG9mIGFuIGluZGV4IGludGVydmFsIGlzIG9wZW4gbGlrZSBhcnJheSBzbGljZSBtZXRob2QuXG5cdCAgICBjb25zdCBhRW5kID0gYUxlbmd0aCAtIG5Db21tb25SO1xuXHQgICAgY29uc3QgYkVuZCA9IGJMZW5ndGggLSBuQ29tbW9uUjtcblxuXHQgICAgLy8gVW5sZXNzIG9uZSBzZXF1ZW5jZSBjb25zaXN0cyBvZiBjb21tb24gaXRlbXMgb25seSxcblx0ICAgIC8vIHRoZXJlZm9yZSB0aGUgb3RoZXIgdHJpbW1lZCBpbmRleCBpbnRlcnZhbCBjb25zaXN0cyBvZiBjaGFuZ2VzIG9ubHksXG5cdCAgICAvLyBmaW5kIGNvbW1vbiBpdGVtcyBpbiB0aGUgdHJpbW1lZCBpbmRleCBpbnRlcnZhbHMuXG5cdCAgICBjb25zdCBuQ29tbW9uRlIgPSBuQ29tbW9uRiArIG5Db21tb25SO1xuXHQgICAgaWYgKGFMZW5ndGggIT09IG5Db21tb25GUiAmJiBiTGVuZ3RoICE9PSBuQ29tbW9uRlIpIHtcblx0ICAgICAgY29uc3QgbkNoYW5nZSA9IDA7IC8vIG51bWJlciBvZiBjaGFuZ2UgaXRlbXMgaXMgbm90IHlldCBrbm93blxuXHQgICAgICBjb25zdCB0cmFuc3Bvc2VkID0gZmFsc2U7IC8vIGNhbGwgdGhlIG9yaWdpbmFsIHVud3JhcHBlZCBmdW5jdGlvbnNcblx0ICAgICAgY29uc3QgY2FsbGJhY2tzID0gW1xuXHQgICAgICAgIHtcblx0ICAgICAgICAgIGZvdW5kU3Vic2VxdWVuY2UsXG5cdCAgICAgICAgICBpc0NvbW1vblxuXHQgICAgICAgIH1cblx0ICAgICAgXTtcblxuXHQgICAgICAvLyBJbmRleGVzIGluIHNlcXVlbmNlIGEgb2YgbGFzdCBwb2ludHMgaW4gZnVydGhlc3QgcmVhY2hpbmcgcGF0aHNcblx0ICAgICAgLy8gZnJvbSBvdXRzaWRlIHRoZSBzdGFydCBhdCB0b3AgbGVmdCBpbiB0aGUgZm9yd2FyZCBkaXJlY3Rpb246XG5cdCAgICAgIGNvbnN0IGFJbmRleGVzRiA9IFtOT1RfWUVUX1NFVF07XG5cdCAgICAgIC8vIGZyb20gdGhlIGVuZCBhdCBib3R0b20gcmlnaHQgaW4gdGhlIHJldmVyc2UgZGlyZWN0aW9uOlxuXHQgICAgICBjb25zdCBhSW5kZXhlc1IgPSBbTk9UX1lFVF9TRVRdO1xuXG5cdCAgICAgIC8vIEluaXRpYWxpemUgb25lIG9iamVjdCBhcyBvdXRwdXQgb2YgYWxsIGNhbGxzIHRvIGRpdmlkZSBmdW5jdGlvbi5cblx0ICAgICAgY29uc3QgZGl2aXNpb24gPSB7XG5cdCAgICAgICAgYUNvbW1vbkZvbGxvd2luZzogTk9UX1lFVF9TRVQsXG5cdCAgICAgICAgYUNvbW1vblByZWNlZGluZzogTk9UX1lFVF9TRVQsXG5cdCAgICAgICAgYUVuZFByZWNlZGluZzogTk9UX1lFVF9TRVQsXG5cdCAgICAgICAgYVN0YXJ0Rm9sbG93aW5nOiBOT1RfWUVUX1NFVCxcblx0ICAgICAgICBiQ29tbW9uRm9sbG93aW5nOiBOT1RfWUVUX1NFVCxcblx0ICAgICAgICBiQ29tbW9uUHJlY2VkaW5nOiBOT1RfWUVUX1NFVCxcblx0ICAgICAgICBiRW5kUHJlY2VkaW5nOiBOT1RfWUVUX1NFVCxcblx0ICAgICAgICBiU3RhcnRGb2xsb3dpbmc6IE5PVF9ZRVRfU0VULFxuXHQgICAgICAgIG5DaGFuZ2VGb2xsb3dpbmc6IE5PVF9ZRVRfU0VULFxuXHQgICAgICAgIG5DaGFuZ2VQcmVjZWRpbmc6IE5PVF9ZRVRfU0VULFxuXHQgICAgICAgIG5Db21tb25Gb2xsb3dpbmc6IE5PVF9ZRVRfU0VULFxuXHQgICAgICAgIG5Db21tb25QcmVjZWRpbmc6IE5PVF9ZRVRfU0VUXG5cdCAgICAgIH07XG5cblx0ICAgICAgLy8gRmluZCBhbmQgcmV0dXJuIGNvbW1vbiBzdWJzZXF1ZW5jZXMgaW4gdGhlIHRyaW1tZWQgaW5kZXggaW50ZXJ2YWxzLlxuXHQgICAgICBmaW5kU3Vic2VxdWVuY2VzKFxuXHQgICAgICAgIG5DaGFuZ2UsXG5cdCAgICAgICAgYVN0YXJ0LFxuXHQgICAgICAgIGFFbmQsXG5cdCAgICAgICAgYlN0YXJ0LFxuXHQgICAgICAgIGJFbmQsXG5cdCAgICAgICAgdHJhbnNwb3NlZCxcblx0ICAgICAgICBjYWxsYmFja3MsXG5cdCAgICAgICAgYUluZGV4ZXNGLFxuXHQgICAgICAgIGFJbmRleGVzUixcblx0ICAgICAgICBkaXZpc2lvblxuXHQgICAgICApO1xuXHQgICAgfVxuXHQgICAgaWYgKG5Db21tb25SICE9PSAwKSB7XG5cdCAgICAgIGZvdW5kU3Vic2VxdWVuY2UobkNvbW1vblIsIGFFbmQsIGJFbmQpO1xuXHQgICAgfVxuXHQgIH1cblx0fVxuXHRyZXR1cm4gYnVpbGQ7XG59XG5cbnZhciBidWlsZEV4cG9ydHMgPSAvKkBfX1BVUkVfXyovIHJlcXVpcmVCdWlsZCgpO1xudmFyIGRpZmZTZXF1ZW5jZXMgPSAvKkBfX1BVUkVfXyovZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMoYnVpbGRFeHBvcnRzKTtcblxuZnVuY3Rpb24gZm9ybWF0VHJhaWxpbmdTcGFjZXMobGluZSwgdHJhaWxpbmdTcGFjZUZvcm1hdHRlcikge1xuXHRyZXR1cm4gbGluZS5yZXBsYWNlKC9cXHMrJC8sIChtYXRjaCkgPT4gdHJhaWxpbmdTcGFjZUZvcm1hdHRlcihtYXRjaCkpO1xufVxuZnVuY3Rpb24gcHJpbnREaWZmTGluZShsaW5lLCBpc0ZpcnN0T3JMYXN0LCBjb2xvciwgaW5kaWNhdG9yLCB0cmFpbGluZ1NwYWNlRm9ybWF0dGVyLCBlbXB0eUZpcnN0T3JMYXN0TGluZVBsYWNlaG9sZGVyKSB7XG5cdHJldHVybiBsaW5lLmxlbmd0aCAhPT0gMCA/IGNvbG9yKGAke2luZGljYXRvcn0gJHtmb3JtYXRUcmFpbGluZ1NwYWNlcyhsaW5lLCB0cmFpbGluZ1NwYWNlRm9ybWF0dGVyKX1gKSA6IGluZGljYXRvciAhPT0gXCIgXCIgPyBjb2xvcihpbmRpY2F0b3IpIDogaXNGaXJzdE9yTGFzdCAmJiBlbXB0eUZpcnN0T3JMYXN0TGluZVBsYWNlaG9sZGVyLmxlbmd0aCAhPT0gMCA/IGNvbG9yKGAke2luZGljYXRvcn0gJHtlbXB0eUZpcnN0T3JMYXN0TGluZVBsYWNlaG9sZGVyfWApIDogXCJcIjtcbn1cbmZ1bmN0aW9uIHByaW50RGVsZXRlTGluZShsaW5lLCBpc0ZpcnN0T3JMYXN0LCB7IGFDb2xvciwgYUluZGljYXRvciwgY2hhbmdlTGluZVRyYWlsaW5nU3BhY2VDb2xvciwgZW1wdHlGaXJzdE9yTGFzdExpbmVQbGFjZWhvbGRlciB9KSB7XG5cdHJldHVybiBwcmludERpZmZMaW5lKGxpbmUsIGlzRmlyc3RPckxhc3QsIGFDb2xvciwgYUluZGljYXRvciwgY2hhbmdlTGluZVRyYWlsaW5nU3BhY2VDb2xvciwgZW1wdHlGaXJzdE9yTGFzdExpbmVQbGFjZWhvbGRlcik7XG59XG5mdW5jdGlvbiBwcmludEluc2VydExpbmUobGluZSwgaXNGaXJzdE9yTGFzdCwgeyBiQ29sb3IsIGJJbmRpY2F0b3IsIGNoYW5nZUxpbmVUcmFpbGluZ1NwYWNlQ29sb3IsIGVtcHR5Rmlyc3RPckxhc3RMaW5lUGxhY2Vob2xkZXIgfSkge1xuXHRyZXR1cm4gcHJpbnREaWZmTGluZShsaW5lLCBpc0ZpcnN0T3JMYXN0LCBiQ29sb3IsIGJJbmRpY2F0b3IsIGNoYW5nZUxpbmVUcmFpbGluZ1NwYWNlQ29sb3IsIGVtcHR5Rmlyc3RPckxhc3RMaW5lUGxhY2Vob2xkZXIpO1xufVxuZnVuY3Rpb24gcHJpbnRDb21tb25MaW5lKGxpbmUsIGlzRmlyc3RPckxhc3QsIHsgY29tbW9uQ29sb3IsIGNvbW1vbkluZGljYXRvciwgY29tbW9uTGluZVRyYWlsaW5nU3BhY2VDb2xvciwgZW1wdHlGaXJzdE9yTGFzdExpbmVQbGFjZWhvbGRlciB9KSB7XG5cdHJldHVybiBwcmludERpZmZMaW5lKGxpbmUsIGlzRmlyc3RPckxhc3QsIGNvbW1vbkNvbG9yLCBjb21tb25JbmRpY2F0b3IsIGNvbW1vbkxpbmVUcmFpbGluZ1NwYWNlQ29sb3IsIGVtcHR5Rmlyc3RPckxhc3RMaW5lUGxhY2Vob2xkZXIpO1xufVxuLy8gSW4gR05VIGRpZmYgZm9ybWF0LCBpbmRleGVzIGFyZSBvbmUtYmFzZWQgaW5zdGVhZCBvZiB6ZXJvLWJhc2VkLlxuZnVuY3Rpb24gY3JlYXRlUGF0Y2hNYXJrKGFTdGFydCwgYUVuZCwgYlN0YXJ0LCBiRW5kLCB7IHBhdGNoQ29sb3IgfSkge1xuXHRyZXR1cm4gcGF0Y2hDb2xvcihgQEAgLSR7YVN0YXJ0ICsgMX0sJHthRW5kIC0gYVN0YXJ0fSArJHtiU3RhcnQgKyAxfSwke2JFbmQgLSBiU3RhcnR9IEBAYCk7XG59XG4vLyBqZXN0IC0tbm8tZXhwYW5kXG4vL1xuLy8gR2l2ZW4gYXJyYXkgb2YgYWxpZ25lZCBzdHJpbmdzIHdpdGggaW52ZXJzZSBoaWdobGlnaHQgZm9ybWF0dGluZyxcbi8vIHJldHVybiBqb2luZWQgbGluZXMgd2l0aCBkaWZmIGZvcm1hdHRpbmcgKGFuZCBwYXRjaCBtYXJrcywgaWYgbmVlZGVkKS5cbmZ1bmN0aW9uIGpvaW5BbGlnbmVkRGlmZnNOb0V4cGFuZChkaWZmcywgb3B0aW9ucykge1xuXHRjb25zdCBpTGVuZ3RoID0gZGlmZnMubGVuZ3RoO1xuXHRjb25zdCBuQ29udGV4dExpbmVzID0gb3B0aW9ucy5jb250ZXh0TGluZXM7XG5cdGNvbnN0IG5Db250ZXh0TGluZXMyID0gbkNvbnRleHRMaW5lcyArIG5Db250ZXh0TGluZXM7XG5cdC8vIEZpcnN0IHBhc3M6IGNvdW50IG91dHB1dCBsaW5lcyBhbmQgc2VlIGlmIGl0IGhhcyBwYXRjaGVzLlxuXHRsZXQgakxlbmd0aCA9IGlMZW5ndGg7XG5cdGxldCBoYXNFeGNlc3NBdFN0YXJ0T3JFbmQgPSBmYWxzZTtcblx0bGV0IG5FeGNlc3Nlc0JldHdlZW5DaGFuZ2VzID0gMDtcblx0bGV0IGkgPSAwO1xuXHR3aGlsZSAoaSAhPT0gaUxlbmd0aCkge1xuXHRcdGNvbnN0IGlTdGFydCA9IGk7XG5cdFx0d2hpbGUgKGkgIT09IGlMZW5ndGggJiYgZGlmZnNbaV1bMF0gPT09IERJRkZfRVFVQUwpIHtcblx0XHRcdGkgKz0gMTtcblx0XHR9XG5cdFx0aWYgKGlTdGFydCAhPT0gaSkge1xuXHRcdFx0aWYgKGlTdGFydCA9PT0gMCkge1xuXHRcdFx0XHQvLyBhdCBzdGFydFxuXHRcdFx0XHRpZiAoaSA+IG5Db250ZXh0TGluZXMpIHtcblx0XHRcdFx0XHRqTGVuZ3RoIC09IGkgLSBuQ29udGV4dExpbmVzO1xuXHRcdFx0XHRcdGhhc0V4Y2Vzc0F0U3RhcnRPckVuZCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoaSA9PT0gaUxlbmd0aCkge1xuXHRcdFx0XHQvLyBhdCBlbmRcblx0XHRcdFx0Y29uc3QgbiA9IGkgLSBpU3RhcnQ7XG5cdFx0XHRcdGlmIChuID4gbkNvbnRleHRMaW5lcykge1xuXHRcdFx0XHRcdGpMZW5ndGggLT0gbiAtIG5Db250ZXh0TGluZXM7XG5cdFx0XHRcdFx0aGFzRXhjZXNzQXRTdGFydE9yRW5kID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gYmV0d2VlbiBjaGFuZ2VzXG5cdFx0XHRcdGNvbnN0IG4gPSBpIC0gaVN0YXJ0O1xuXHRcdFx0XHRpZiAobiA+IG5Db250ZXh0TGluZXMyKSB7XG5cdFx0XHRcdFx0akxlbmd0aCAtPSBuIC0gbkNvbnRleHRMaW5lczI7XG5cdFx0XHRcdFx0bkV4Y2Vzc2VzQmV0d2VlbkNoYW5nZXMgKz0gMTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHR3aGlsZSAoaSAhPT0gaUxlbmd0aCAmJiBkaWZmc1tpXVswXSAhPT0gRElGRl9FUVVBTCkge1xuXHRcdFx0aSArPSAxO1xuXHRcdH1cblx0fVxuXHRjb25zdCBoYXNQYXRjaCA9IG5FeGNlc3Nlc0JldHdlZW5DaGFuZ2VzICE9PSAwIHx8IGhhc0V4Y2Vzc0F0U3RhcnRPckVuZDtcblx0aWYgKG5FeGNlc3Nlc0JldHdlZW5DaGFuZ2VzICE9PSAwKSB7XG5cdFx0akxlbmd0aCArPSBuRXhjZXNzZXNCZXR3ZWVuQ2hhbmdlcyArIDE7XG5cdH0gZWxzZSBpZiAoaGFzRXhjZXNzQXRTdGFydE9yRW5kKSB7XG5cdFx0akxlbmd0aCArPSAxO1xuXHR9XG5cdGNvbnN0IGpMYXN0ID0gakxlbmd0aCAtIDE7XG5cdGNvbnN0IGxpbmVzID0gW107XG5cdGxldCBqUGF0Y2hNYXJrID0gMDtcblx0aWYgKGhhc1BhdGNoKSB7XG5cdFx0bGluZXMucHVzaChcIlwiKTtcblx0fVxuXHQvLyBJbmRleGVzIG9mIGV4cGVjdGVkIG9yIHJlY2VpdmVkIGxpbmVzIGluIGN1cnJlbnQgcGF0Y2g6XG5cdGxldCBhU3RhcnQgPSAwO1xuXHRsZXQgYlN0YXJ0ID0gMDtcblx0bGV0IGFFbmQgPSAwO1xuXHRsZXQgYkVuZCA9IDA7XG5cdGNvbnN0IHB1c2hDb21tb25MaW5lID0gKGxpbmUpID0+IHtcblx0XHRjb25zdCBqID0gbGluZXMubGVuZ3RoO1xuXHRcdGxpbmVzLnB1c2gocHJpbnRDb21tb25MaW5lKGxpbmUsIGogPT09IDAgfHwgaiA9PT0gakxhc3QsIG9wdGlvbnMpKTtcblx0XHRhRW5kICs9IDE7XG5cdFx0YkVuZCArPSAxO1xuXHR9O1xuXHRjb25zdCBwdXNoRGVsZXRlTGluZSA9IChsaW5lKSA9PiB7XG5cdFx0Y29uc3QgaiA9IGxpbmVzLmxlbmd0aDtcblx0XHRsaW5lcy5wdXNoKHByaW50RGVsZXRlTGluZShsaW5lLCBqID09PSAwIHx8IGogPT09IGpMYXN0LCBvcHRpb25zKSk7XG5cdFx0YUVuZCArPSAxO1xuXHR9O1xuXHRjb25zdCBwdXNoSW5zZXJ0TGluZSA9IChsaW5lKSA9PiB7XG5cdFx0Y29uc3QgaiA9IGxpbmVzLmxlbmd0aDtcblx0XHRsaW5lcy5wdXNoKHByaW50SW5zZXJ0TGluZShsaW5lLCBqID09PSAwIHx8IGogPT09IGpMYXN0LCBvcHRpb25zKSk7XG5cdFx0YkVuZCArPSAxO1xuXHR9O1xuXHQvLyBTZWNvbmQgcGFzczogcHVzaCBsaW5lcyB3aXRoIGRpZmYgZm9ybWF0dGluZyAoYW5kIHBhdGNoIG1hcmtzLCBpZiBuZWVkZWQpLlxuXHRpID0gMDtcblx0d2hpbGUgKGkgIT09IGlMZW5ndGgpIHtcblx0XHRsZXQgaVN0YXJ0ID0gaTtcblx0XHR3aGlsZSAoaSAhPT0gaUxlbmd0aCAmJiBkaWZmc1tpXVswXSA9PT0gRElGRl9FUVVBTCkge1xuXHRcdFx0aSArPSAxO1xuXHRcdH1cblx0XHRpZiAoaVN0YXJ0ICE9PSBpKSB7XG5cdFx0XHRpZiAoaVN0YXJ0ID09PSAwKSB7XG5cdFx0XHRcdC8vIGF0IGJlZ2lubmluZ1xuXHRcdFx0XHRpZiAoaSA+IG5Db250ZXh0TGluZXMpIHtcblx0XHRcdFx0XHRpU3RhcnQgPSBpIC0gbkNvbnRleHRMaW5lcztcblx0XHRcdFx0XHRhU3RhcnQgPSBpU3RhcnQ7XG5cdFx0XHRcdFx0YlN0YXJ0ID0gaVN0YXJ0O1xuXHRcdFx0XHRcdGFFbmQgPSBhU3RhcnQ7XG5cdFx0XHRcdFx0YkVuZCA9IGJTdGFydDtcblx0XHRcdFx0fVxuXHRcdFx0XHRmb3IgKGxldCBpQ29tbW9uID0gaVN0YXJ0OyBpQ29tbW9uICE9PSBpOyBpQ29tbW9uICs9IDEpIHtcblx0XHRcdFx0XHRwdXNoQ29tbW9uTGluZShkaWZmc1tpQ29tbW9uXVsxXSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoaSA9PT0gaUxlbmd0aCkge1xuXHRcdFx0XHQvLyBhdCBlbmRcblx0XHRcdFx0Y29uc3QgaUVuZCA9IGkgLSBpU3RhcnQgPiBuQ29udGV4dExpbmVzID8gaVN0YXJ0ICsgbkNvbnRleHRMaW5lcyA6IGk7XG5cdFx0XHRcdGZvciAobGV0IGlDb21tb24gPSBpU3RhcnQ7IGlDb21tb24gIT09IGlFbmQ7IGlDb21tb24gKz0gMSkge1xuXHRcdFx0XHRcdHB1c2hDb21tb25MaW5lKGRpZmZzW2lDb21tb25dWzFdKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gYmV0d2VlbiBjaGFuZ2VzXG5cdFx0XHRcdGNvbnN0IG5Db21tb24gPSBpIC0gaVN0YXJ0O1xuXHRcdFx0XHRpZiAobkNvbW1vbiA+IG5Db250ZXh0TGluZXMyKSB7XG5cdFx0XHRcdFx0Y29uc3QgaUVuZCA9IGlTdGFydCArIG5Db250ZXh0TGluZXM7XG5cdFx0XHRcdFx0Zm9yIChsZXQgaUNvbW1vbiA9IGlTdGFydDsgaUNvbW1vbiAhPT0gaUVuZDsgaUNvbW1vbiArPSAxKSB7XG5cdFx0XHRcdFx0XHRwdXNoQ29tbW9uTGluZShkaWZmc1tpQ29tbW9uXVsxXSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGxpbmVzW2pQYXRjaE1hcmtdID0gY3JlYXRlUGF0Y2hNYXJrKGFTdGFydCwgYUVuZCwgYlN0YXJ0LCBiRW5kLCBvcHRpb25zKTtcblx0XHRcdFx0XHRqUGF0Y2hNYXJrID0gbGluZXMubGVuZ3RoO1xuXHRcdFx0XHRcdGxpbmVzLnB1c2goXCJcIik7XG5cdFx0XHRcdFx0Y29uc3Qgbk9taXQgPSBuQ29tbW9uIC0gbkNvbnRleHRMaW5lczI7XG5cdFx0XHRcdFx0YVN0YXJ0ID0gYUVuZCArIG5PbWl0O1xuXHRcdFx0XHRcdGJTdGFydCA9IGJFbmQgKyBuT21pdDtcblx0XHRcdFx0XHRhRW5kID0gYVN0YXJ0O1xuXHRcdFx0XHRcdGJFbmQgPSBiU3RhcnQ7XG5cdFx0XHRcdFx0Zm9yIChsZXQgaUNvbW1vbiA9IGkgLSBuQ29udGV4dExpbmVzOyBpQ29tbW9uICE9PSBpOyBpQ29tbW9uICs9IDEpIHtcblx0XHRcdFx0XHRcdHB1c2hDb21tb25MaW5lKGRpZmZzW2lDb21tb25dWzFdKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Zm9yIChsZXQgaUNvbW1vbiA9IGlTdGFydDsgaUNvbW1vbiAhPT0gaTsgaUNvbW1vbiArPSAxKSB7XG5cdFx0XHRcdFx0XHRwdXNoQ29tbW9uTGluZShkaWZmc1tpQ29tbW9uXVsxXSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHdoaWxlIChpICE9PSBpTGVuZ3RoICYmIGRpZmZzW2ldWzBdID09PSBESUZGX0RFTEVURSkge1xuXHRcdFx0cHVzaERlbGV0ZUxpbmUoZGlmZnNbaV1bMV0pO1xuXHRcdFx0aSArPSAxO1xuXHRcdH1cblx0XHR3aGlsZSAoaSAhPT0gaUxlbmd0aCAmJiBkaWZmc1tpXVswXSA9PT0gRElGRl9JTlNFUlQpIHtcblx0XHRcdHB1c2hJbnNlcnRMaW5lKGRpZmZzW2ldWzFdKTtcblx0XHRcdGkgKz0gMTtcblx0XHR9XG5cdH1cblx0aWYgKGhhc1BhdGNoKSB7XG5cdFx0bGluZXNbalBhdGNoTWFya10gPSBjcmVhdGVQYXRjaE1hcmsoYVN0YXJ0LCBhRW5kLCBiU3RhcnQsIGJFbmQsIG9wdGlvbnMpO1xuXHR9XG5cdHJldHVybiBsaW5lcy5qb2luKFwiXFxuXCIpO1xufVxuLy8gamVzdCAtLWV4cGFuZFxuLy9cbi8vIEdpdmVuIGFycmF5IG9mIGFsaWduZWQgc3RyaW5ncyB3aXRoIGludmVyc2UgaGlnaGxpZ2h0IGZvcm1hdHRpbmcsXG4vLyByZXR1cm4gam9pbmVkIGxpbmVzIHdpdGggZGlmZiBmb3JtYXR0aW5nLlxuZnVuY3Rpb24gam9pbkFsaWduZWREaWZmc0V4cGFuZChkaWZmcywgb3B0aW9ucykge1xuXHRyZXR1cm4gZGlmZnMubWFwKChkaWZmLCBpLCBkaWZmcykgPT4ge1xuXHRcdGNvbnN0IGxpbmUgPSBkaWZmWzFdO1xuXHRcdGNvbnN0IGlzRmlyc3RPckxhc3QgPSBpID09PSAwIHx8IGkgPT09IGRpZmZzLmxlbmd0aCAtIDE7XG5cdFx0c3dpdGNoIChkaWZmWzBdKSB7XG5cdFx0XHRjYXNlIERJRkZfREVMRVRFOiByZXR1cm4gcHJpbnREZWxldGVMaW5lKGxpbmUsIGlzRmlyc3RPckxhc3QsIG9wdGlvbnMpO1xuXHRcdFx0Y2FzZSBESUZGX0lOU0VSVDogcmV0dXJuIHByaW50SW5zZXJ0TGluZShsaW5lLCBpc0ZpcnN0T3JMYXN0LCBvcHRpb25zKTtcblx0XHRcdGRlZmF1bHQ6IHJldHVybiBwcmludENvbW1vbkxpbmUobGluZSwgaXNGaXJzdE9yTGFzdCwgb3B0aW9ucyk7XG5cdFx0fVxuXHR9KS5qb2luKFwiXFxuXCIpO1xufVxuXG5jb25zdCBub0NvbG9yID0gKHN0cmluZykgPT4gc3RyaW5nO1xuY29uc3QgRElGRl9DT05URVhUX0RFRkFVTFQgPSA1O1xuY29uc3QgRElGRl9UUlVOQ0FURV9USFJFU0hPTERfREVGQVVMVCA9IDA7XG5mdW5jdGlvbiBnZXREZWZhdWx0T3B0aW9ucygpIHtcblx0cmV0dXJuIHtcblx0XHRhQW5ub3RhdGlvbjogXCJFeHBlY3RlZFwiLFxuXHRcdGFDb2xvcjogYy5ncmVlbixcblx0XHRhSW5kaWNhdG9yOiBcIi1cIixcblx0XHRiQW5ub3RhdGlvbjogXCJSZWNlaXZlZFwiLFxuXHRcdGJDb2xvcjogYy5yZWQsXG5cdFx0YkluZGljYXRvcjogXCIrXCIsXG5cdFx0Y2hhbmdlQ29sb3I6IGMuaW52ZXJzZSxcblx0XHRjaGFuZ2VMaW5lVHJhaWxpbmdTcGFjZUNvbG9yOiBub0NvbG9yLFxuXHRcdGNvbW1vbkNvbG9yOiBjLmRpbSxcblx0XHRjb21tb25JbmRpY2F0b3I6IFwiIFwiLFxuXHRcdGNvbW1vbkxpbmVUcmFpbGluZ1NwYWNlQ29sb3I6IG5vQ29sb3IsXG5cdFx0Y29tcGFyZUtleXM6IHVuZGVmaW5lZCxcblx0XHRjb250ZXh0TGluZXM6IERJRkZfQ09OVEVYVF9ERUZBVUxULFxuXHRcdGVtcHR5Rmlyc3RPckxhc3RMaW5lUGxhY2Vob2xkZXI6IFwiXCIsXG5cdFx0ZXhwYW5kOiBmYWxzZSxcblx0XHRpbmNsdWRlQ2hhbmdlQ291bnRzOiBmYWxzZSxcblx0XHRvbWl0QW5ub3RhdGlvbkxpbmVzOiBmYWxzZSxcblx0XHRwYXRjaENvbG9yOiBjLnllbGxvdyxcblx0XHRwcmludEJhc2ljUHJvdG90eXBlOiBmYWxzZSxcblx0XHR0cnVuY2F0ZVRocmVzaG9sZDogRElGRl9UUlVOQ0FURV9USFJFU0hPTERfREVGQVVMVCxcblx0XHR0cnVuY2F0ZUFubm90YXRpb246IFwiLi4uIERpZmYgcmVzdWx0IGlzIHRydW5jYXRlZFwiLFxuXHRcdHRydW5jYXRlQW5ub3RhdGlvbkNvbG9yOiBub0NvbG9yXG5cdH07XG59XG5mdW5jdGlvbiBnZXRDb21wYXJlS2V5cyhjb21wYXJlS2V5cykge1xuXHRyZXR1cm4gY29tcGFyZUtleXMgJiYgdHlwZW9mIGNvbXBhcmVLZXlzID09PSBcImZ1bmN0aW9uXCIgPyBjb21wYXJlS2V5cyA6IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIGdldENvbnRleHRMaW5lcyhjb250ZXh0TGluZXMpIHtcblx0cmV0dXJuIHR5cGVvZiBjb250ZXh0TGluZXMgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzU2FmZUludGVnZXIoY29udGV4dExpbmVzKSAmJiBjb250ZXh0TGluZXMgPj0gMCA/IGNvbnRleHRMaW5lcyA6IERJRkZfQ09OVEVYVF9ERUZBVUxUO1xufVxuLy8gUHVyZSBmdW5jdGlvbiByZXR1cm5zIG9wdGlvbnMgd2l0aCBhbGwgcHJvcGVydGllcy5cbmZ1bmN0aW9uIG5vcm1hbGl6ZURpZmZPcHRpb25zKG9wdGlvbnMgPSB7fSkge1xuXHRyZXR1cm4ge1xuXHRcdC4uLmdldERlZmF1bHRPcHRpb25zKCksXG5cdFx0Li4ub3B0aW9ucyxcblx0XHRjb21wYXJlS2V5czogZ2V0Q29tcGFyZUtleXMob3B0aW9ucy5jb21wYXJlS2V5cyksXG5cdFx0Y29udGV4dExpbmVzOiBnZXRDb250ZXh0TGluZXMob3B0aW9ucy5jb250ZXh0TGluZXMpXG5cdH07XG59XG5cbmZ1bmN0aW9uIGlzRW1wdHlTdHJpbmcobGluZXMpIHtcblx0cmV0dXJuIGxpbmVzLmxlbmd0aCA9PT0gMSAmJiBsaW5lc1swXS5sZW5ndGggPT09IDA7XG59XG5mdW5jdGlvbiBjb3VudENoYW5nZXMoZGlmZnMpIHtcblx0bGV0IGEgPSAwO1xuXHRsZXQgYiA9IDA7XG5cdGRpZmZzLmZvckVhY2goKGRpZmYpID0+IHtcblx0XHRzd2l0Y2ggKGRpZmZbMF0pIHtcblx0XHRcdGNhc2UgRElGRl9ERUxFVEU6XG5cdFx0XHRcdGEgKz0gMTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIERJRkZfSU5TRVJUOlxuXHRcdFx0XHRiICs9IDE7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblx0fSk7XG5cdHJldHVybiB7XG5cdFx0YSxcblx0XHRiXG5cdH07XG59XG5mdW5jdGlvbiBwcmludEFubm90YXRpb24oeyBhQW5ub3RhdGlvbiwgYUNvbG9yLCBhSW5kaWNhdG9yLCBiQW5ub3RhdGlvbiwgYkNvbG9yLCBiSW5kaWNhdG9yLCBpbmNsdWRlQ2hhbmdlQ291bnRzLCBvbWl0QW5ub3RhdGlvbkxpbmVzIH0sIGNoYW5nZUNvdW50cykge1xuXHRpZiAob21pdEFubm90YXRpb25MaW5lcykge1xuXHRcdHJldHVybiBcIlwiO1xuXHR9XG5cdGxldCBhUmVzdCA9IFwiXCI7XG5cdGxldCBiUmVzdCA9IFwiXCI7XG5cdGlmIChpbmNsdWRlQ2hhbmdlQ291bnRzKSB7XG5cdFx0Y29uc3QgYUNvdW50ID0gU3RyaW5nKGNoYW5nZUNvdW50cy5hKTtcblx0XHRjb25zdCBiQ291bnQgPSBTdHJpbmcoY2hhbmdlQ291bnRzLmIpO1xuXHRcdC8vIFBhZGRpbmcgcmlnaHQgYWxpZ25zIHRoZSBlbmRzIG9mIHRoZSBhbm5vdGF0aW9ucy5cblx0XHRjb25zdCBiYUFubm90YXRpb25MZW5ndGhEaWZmID0gYkFubm90YXRpb24ubGVuZ3RoIC0gYUFubm90YXRpb24ubGVuZ3RoO1xuXHRcdGNvbnN0IGFBbm5vdGF0aW9uUGFkZGluZyA9IFwiIFwiLnJlcGVhdChNYXRoLm1heCgwLCBiYUFubm90YXRpb25MZW5ndGhEaWZmKSk7XG5cdFx0Y29uc3QgYkFubm90YXRpb25QYWRkaW5nID0gXCIgXCIucmVwZWF0KE1hdGgubWF4KDAsIC1iYUFubm90YXRpb25MZW5ndGhEaWZmKSk7XG5cdFx0Ly8gUGFkZGluZyBsZWZ0IGFsaWducyB0aGUgZW5kcyBvZiB0aGUgY291bnRzLlxuXHRcdGNvbnN0IGJhQ291bnRMZW5ndGhEaWZmID0gYkNvdW50Lmxlbmd0aCAtIGFDb3VudC5sZW5ndGg7XG5cdFx0Y29uc3QgYUNvdW50UGFkZGluZyA9IFwiIFwiLnJlcGVhdChNYXRoLm1heCgwLCBiYUNvdW50TGVuZ3RoRGlmZikpO1xuXHRcdGNvbnN0IGJDb3VudFBhZGRpbmcgPSBcIiBcIi5yZXBlYXQoTWF0aC5tYXgoMCwgLWJhQ291bnRMZW5ndGhEaWZmKSk7XG5cdFx0YVJlc3QgPSBgJHthQW5ub3RhdGlvblBhZGRpbmd9ICAke2FJbmRpY2F0b3J9ICR7YUNvdW50UGFkZGluZ30ke2FDb3VudH1gO1xuXHRcdGJSZXN0ID0gYCR7YkFubm90YXRpb25QYWRkaW5nfSAgJHtiSW5kaWNhdG9yfSAke2JDb3VudFBhZGRpbmd9JHtiQ291bnR9YDtcblx0fVxuXHRjb25zdCBhID0gYCR7YUluZGljYXRvcn0gJHthQW5ub3RhdGlvbn0ke2FSZXN0fWA7XG5cdGNvbnN0IGIgPSBgJHtiSW5kaWNhdG9yfSAke2JBbm5vdGF0aW9ufSR7YlJlc3R9YDtcblx0cmV0dXJuIGAke2FDb2xvcihhKX1cXG4ke2JDb2xvcihiKX1cXG5cXG5gO1xufVxuZnVuY3Rpb24gcHJpbnREaWZmTGluZXMoZGlmZnMsIHRydW5jYXRlZCwgb3B0aW9ucykge1xuXHRyZXR1cm4gcHJpbnRBbm5vdGF0aW9uKG9wdGlvbnMsIGNvdW50Q2hhbmdlcyhkaWZmcykpICsgKG9wdGlvbnMuZXhwYW5kID8gam9pbkFsaWduZWREaWZmc0V4cGFuZChkaWZmcywgb3B0aW9ucykgOiBqb2luQWxpZ25lZERpZmZzTm9FeHBhbmQoZGlmZnMsIG9wdGlvbnMpKSArICh0cnVuY2F0ZWQgPyBvcHRpb25zLnRydW5jYXRlQW5ub3RhdGlvbkNvbG9yKGBcXG4ke29wdGlvbnMudHJ1bmNhdGVBbm5vdGF0aW9ufWApIDogXCJcIik7XG59XG4vLyBDb21wYXJlIHR3byBhcnJheXMgb2Ygc3RyaW5ncyBsaW5lLWJ5LWxpbmUuIEZvcm1hdCBhcyBjb21wYXJpc29uIGxpbmVzLlxuZnVuY3Rpb24gZGlmZkxpbmVzVW5pZmllZChhTGluZXMsIGJMaW5lcywgb3B0aW9ucykge1xuXHRjb25zdCBub3JtYWxpemVkT3B0aW9ucyA9IG5vcm1hbGl6ZURpZmZPcHRpb25zKG9wdGlvbnMpO1xuXHRjb25zdCBbZGlmZnMsIHRydW5jYXRlZF0gPSBkaWZmTGluZXNSYXcoaXNFbXB0eVN0cmluZyhhTGluZXMpID8gW10gOiBhTGluZXMsIGlzRW1wdHlTdHJpbmcoYkxpbmVzKSA/IFtdIDogYkxpbmVzLCBub3JtYWxpemVkT3B0aW9ucyk7XG5cdHJldHVybiBwcmludERpZmZMaW5lcyhkaWZmcywgdHJ1bmNhdGVkLCBub3JtYWxpemVkT3B0aW9ucyk7XG59XG4vLyBHaXZlbiB0d28gcGFpcnMgb2YgYXJyYXlzIG9mIHN0cmluZ3M6XG4vLyBDb21wYXJlIHRoZSBwYWlyIG9mIGNvbXBhcmlzb24gYXJyYXlzIGxpbmUtYnktbGluZS5cbi8vIEZvcm1hdCB0aGUgY29ycmVzcG9uZGluZyBsaW5lcyBpbiB0aGUgcGFpciBvZiBkaXNwbGF5YWJsZSBhcnJheXMuXG5mdW5jdGlvbiBkaWZmTGluZXNVbmlmaWVkMihhTGluZXNEaXNwbGF5LCBiTGluZXNEaXNwbGF5LCBhTGluZXNDb21wYXJlLCBiTGluZXNDb21wYXJlLCBvcHRpb25zKSB7XG5cdGlmIChpc0VtcHR5U3RyaW5nKGFMaW5lc0Rpc3BsYXkpICYmIGlzRW1wdHlTdHJpbmcoYUxpbmVzQ29tcGFyZSkpIHtcblx0XHRhTGluZXNEaXNwbGF5ID0gW107XG5cdFx0YUxpbmVzQ29tcGFyZSA9IFtdO1xuXHR9XG5cdGlmIChpc0VtcHR5U3RyaW5nKGJMaW5lc0Rpc3BsYXkpICYmIGlzRW1wdHlTdHJpbmcoYkxpbmVzQ29tcGFyZSkpIHtcblx0XHRiTGluZXNEaXNwbGF5ID0gW107XG5cdFx0YkxpbmVzQ29tcGFyZSA9IFtdO1xuXHR9XG5cdGlmIChhTGluZXNEaXNwbGF5Lmxlbmd0aCAhPT0gYUxpbmVzQ29tcGFyZS5sZW5ndGggfHwgYkxpbmVzRGlzcGxheS5sZW5ndGggIT09IGJMaW5lc0NvbXBhcmUubGVuZ3RoKSB7XG5cdFx0Ly8gRmFsbCBiYWNrIHRvIGRpZmYgb2YgZGlzcGxheSBsaW5lcy5cblx0XHRyZXR1cm4gZGlmZkxpbmVzVW5pZmllZChhTGluZXNEaXNwbGF5LCBiTGluZXNEaXNwbGF5LCBvcHRpb25zKTtcblx0fVxuXHRjb25zdCBbZGlmZnMsIHRydW5jYXRlZF0gPSBkaWZmTGluZXNSYXcoYUxpbmVzQ29tcGFyZSwgYkxpbmVzQ29tcGFyZSwgb3B0aW9ucyk7XG5cdC8vIFJlcGxhY2UgY29tcGFyaXNvbiBsaW5lcyB3aXRoIGRpc3BsYXlhYmxlIGxpbmVzLlxuXHRsZXQgYUluZGV4ID0gMDtcblx0bGV0IGJJbmRleCA9IDA7XG5cdGRpZmZzLmZvckVhY2goKGRpZmYpID0+IHtcblx0XHRzd2l0Y2ggKGRpZmZbMF0pIHtcblx0XHRcdGNhc2UgRElGRl9ERUxFVEU6XG5cdFx0XHRcdGRpZmZbMV0gPSBhTGluZXNEaXNwbGF5W2FJbmRleF07XG5cdFx0XHRcdGFJbmRleCArPSAxO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgRElGRl9JTlNFUlQ6XG5cdFx0XHRcdGRpZmZbMV0gPSBiTGluZXNEaXNwbGF5W2JJbmRleF07XG5cdFx0XHRcdGJJbmRleCArPSAxO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdGRpZmZbMV0gPSBiTGluZXNEaXNwbGF5W2JJbmRleF07XG5cdFx0XHRcdGFJbmRleCArPSAxO1xuXHRcdFx0XHRiSW5kZXggKz0gMTtcblx0XHR9XG5cdH0pO1xuXHRyZXR1cm4gcHJpbnREaWZmTGluZXMoZGlmZnMsIHRydW5jYXRlZCwgbm9ybWFsaXplRGlmZk9wdGlvbnMob3B0aW9ucykpO1xufVxuLy8gQ29tcGFyZSB0d28gYXJyYXlzIG9mIHN0cmluZ3MgbGluZS1ieS1saW5lLlxuZnVuY3Rpb24gZGlmZkxpbmVzUmF3KGFMaW5lcywgYkxpbmVzLCBvcHRpb25zKSB7XG5cdGNvbnN0IHRydW5jYXRlID0gb3B0aW9ucz8udHJ1bmNhdGVUaHJlc2hvbGQgPz8gZmFsc2U7XG5cdGNvbnN0IHRydW5jYXRlVGhyZXNob2xkID0gTWF0aC5tYXgoTWF0aC5mbG9vcihvcHRpb25zPy50cnVuY2F0ZVRocmVzaG9sZCA/PyAwKSwgMCk7XG5cdGNvbnN0IGFMZW5ndGggPSB0cnVuY2F0ZSA/IE1hdGgubWluKGFMaW5lcy5sZW5ndGgsIHRydW5jYXRlVGhyZXNob2xkKSA6IGFMaW5lcy5sZW5ndGg7XG5cdGNvbnN0IGJMZW5ndGggPSB0cnVuY2F0ZSA/IE1hdGgubWluKGJMaW5lcy5sZW5ndGgsIHRydW5jYXRlVGhyZXNob2xkKSA6IGJMaW5lcy5sZW5ndGg7XG5cdGNvbnN0IHRydW5jYXRlZCA9IGFMZW5ndGggIT09IGFMaW5lcy5sZW5ndGggfHwgYkxlbmd0aCAhPT0gYkxpbmVzLmxlbmd0aDtcblx0Y29uc3QgaXNDb21tb24gPSAoYUluZGV4LCBiSW5kZXgpID0+IGFMaW5lc1thSW5kZXhdID09PSBiTGluZXNbYkluZGV4XTtcblx0Y29uc3QgZGlmZnMgPSBbXTtcblx0bGV0IGFJbmRleCA9IDA7XG5cdGxldCBiSW5kZXggPSAwO1xuXHRjb25zdCBmb3VuZFN1YnNlcXVlbmNlID0gKG5Db21tb24sIGFDb21tb24sIGJDb21tb24pID0+IHtcblx0XHRmb3IgKDsgYUluZGV4ICE9PSBhQ29tbW9uOyBhSW5kZXggKz0gMSkge1xuXHRcdFx0ZGlmZnMucHVzaChuZXcgRGlmZihESUZGX0RFTEVURSwgYUxpbmVzW2FJbmRleF0pKTtcblx0XHR9XG5cdFx0Zm9yICg7IGJJbmRleCAhPT0gYkNvbW1vbjsgYkluZGV4ICs9IDEpIHtcblx0XHRcdGRpZmZzLnB1c2gobmV3IERpZmYoRElGRl9JTlNFUlQsIGJMaW5lc1tiSW5kZXhdKSk7XG5cdFx0fVxuXHRcdGZvciAoOyBuQ29tbW9uICE9PSAwOyBuQ29tbW9uIC09IDEsIGFJbmRleCArPSAxLCBiSW5kZXggKz0gMSkge1xuXHRcdFx0ZGlmZnMucHVzaChuZXcgRGlmZihESUZGX0VRVUFMLCBiTGluZXNbYkluZGV4XSkpO1xuXHRcdH1cblx0fTtcblx0ZGlmZlNlcXVlbmNlcyhhTGVuZ3RoLCBiTGVuZ3RoLCBpc0NvbW1vbiwgZm91bmRTdWJzZXF1ZW5jZSk7XG5cdC8vIEFmdGVyIHRoZSBsYXN0IGNvbW1vbiBzdWJzZXF1ZW5jZSwgcHVzaCByZW1haW5pbmcgY2hhbmdlIGl0ZW1zLlxuXHRmb3IgKDsgYUluZGV4ICE9PSBhTGVuZ3RoOyBhSW5kZXggKz0gMSkge1xuXHRcdGRpZmZzLnB1c2gobmV3IERpZmYoRElGRl9ERUxFVEUsIGFMaW5lc1thSW5kZXhdKSk7XG5cdH1cblx0Zm9yICg7IGJJbmRleCAhPT0gYkxlbmd0aDsgYkluZGV4ICs9IDEpIHtcblx0XHRkaWZmcy5wdXNoKG5ldyBEaWZmKERJRkZfSU5TRVJULCBiTGluZXNbYkluZGV4XSkpO1xuXHR9XG5cdHJldHVybiBbZGlmZnMsIHRydW5jYXRlZF07XG59XG5cbi8vIGdldCB0aGUgdHlwZSBvZiBhIHZhbHVlIHdpdGggaGFuZGxpbmcgdGhlIGVkZ2UgY2FzZXMgbGlrZSBgdHlwZW9mIFtdYFxuLy8gYW5kIGB0eXBlb2YgbnVsbGBcbmZ1bmN0aW9uIGdldFR5cGUodmFsdWUpIHtcblx0aWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gXCJ1bmRlZmluZWRcIjtcblx0fSBlbHNlIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuXHRcdHJldHVybiBcIm51bGxcIjtcblx0fSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuXHRcdHJldHVybiBcImFycmF5XCI7XG5cdH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcImJvb2xlYW5cIikge1xuXHRcdHJldHVybiBcImJvb2xlYW5cIjtcblx0fSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIikge1xuXHRcdHJldHVybiBcImZ1bmN0aW9uXCI7XG5cdH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiKSB7XG5cdFx0cmV0dXJuIFwibnVtYmVyXCI7XG5cdH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB7XG5cdFx0cmV0dXJuIFwic3RyaW5nXCI7XG5cdH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcImJpZ2ludFwiKSB7XG5cdFx0cmV0dXJuIFwiYmlnaW50XCI7XG5cdH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiKSB7XG5cdFx0aWYgKHZhbHVlICE9IG51bGwpIHtcblx0XHRcdGlmICh2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gUmVnRXhwKSB7XG5cdFx0XHRcdHJldHVybiBcInJlZ2V4cFwiO1xuXHRcdFx0fSBlbHNlIGlmICh2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gTWFwKSB7XG5cdFx0XHRcdHJldHVybiBcIm1hcFwiO1xuXHRcdFx0fSBlbHNlIGlmICh2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gU2V0KSB7XG5cdFx0XHRcdHJldHVybiBcInNldFwiO1xuXHRcdFx0fSBlbHNlIGlmICh2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gRGF0ZSkge1xuXHRcdFx0XHRyZXR1cm4gXCJkYXRlXCI7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBcIm9iamVjdFwiO1xuXHR9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzeW1ib2xcIikge1xuXHRcdHJldHVybiBcInN5bWJvbFwiO1xuXHR9XG5cdHRocm93IG5ldyBFcnJvcihgdmFsdWUgb2YgdW5rbm93biB0eXBlOiAke3ZhbHVlfWApO1xufVxuXG4vLyBwbGF0Zm9ybXMgY29tcGF0aWJsZVxuZnVuY3Rpb24gZ2V0TmV3TGluZVN5bWJvbChzdHJpbmcpIHtcblx0cmV0dXJuIHN0cmluZy5pbmNsdWRlcyhcIlxcclxcblwiKSA/IFwiXFxyXFxuXCIgOiBcIlxcblwiO1xufVxuZnVuY3Rpb24gZGlmZlN0cmluZ3MoYSwgYiwgb3B0aW9ucykge1xuXHRjb25zdCB0cnVuY2F0ZSA9IG9wdGlvbnM/LnRydW5jYXRlVGhyZXNob2xkID8/IGZhbHNlO1xuXHRjb25zdCB0cnVuY2F0ZVRocmVzaG9sZCA9IE1hdGgubWF4KE1hdGguZmxvb3Iob3B0aW9ucz8udHJ1bmNhdGVUaHJlc2hvbGQgPz8gMCksIDApO1xuXHRsZXQgYUxlbmd0aCA9IGEubGVuZ3RoO1xuXHRsZXQgYkxlbmd0aCA9IGIubGVuZ3RoO1xuXHRpZiAodHJ1bmNhdGUpIHtcblx0XHRjb25zdCBhTXVsdGlwbGVMaW5lcyA9IGEuaW5jbHVkZXMoXCJcXG5cIik7XG5cdFx0Y29uc3QgYk11bHRpcGxlTGluZXMgPSBiLmluY2x1ZGVzKFwiXFxuXCIpO1xuXHRcdGNvbnN0IGFOZXdMaW5lU3ltYm9sID0gZ2V0TmV3TGluZVN5bWJvbChhKTtcblx0XHRjb25zdCBiTmV3TGluZVN5bWJvbCA9IGdldE5ld0xpbmVTeW1ib2woYik7XG5cdFx0Ly8gbXVsdGlwbGUtbGluZXMgc3RyaW5nIGV4cGVjdHMgYSBuZXdsaW5lIHRvIGJlIGFwcGVuZGVkIGF0IHRoZSBlbmRcblx0XHRjb25zdCBfYSA9IGFNdWx0aXBsZUxpbmVzID8gYCR7YS5zcGxpdChhTmV3TGluZVN5bWJvbCwgdHJ1bmNhdGVUaHJlc2hvbGQpLmpvaW4oYU5ld0xpbmVTeW1ib2wpfVxcbmAgOiBhO1xuXHRcdGNvbnN0IF9iID0gYk11bHRpcGxlTGluZXMgPyBgJHtiLnNwbGl0KGJOZXdMaW5lU3ltYm9sLCB0cnVuY2F0ZVRocmVzaG9sZCkuam9pbihiTmV3TGluZVN5bWJvbCl9XFxuYCA6IGI7XG5cdFx0YUxlbmd0aCA9IF9hLmxlbmd0aDtcblx0XHRiTGVuZ3RoID0gX2IubGVuZ3RoO1xuXHR9XG5cdGNvbnN0IHRydW5jYXRlZCA9IGFMZW5ndGggIT09IGEubGVuZ3RoIHx8IGJMZW5ndGggIT09IGIubGVuZ3RoO1xuXHRjb25zdCBpc0NvbW1vbiA9IChhSW5kZXgsIGJJbmRleCkgPT4gYVthSW5kZXhdID09PSBiW2JJbmRleF07XG5cdGxldCBhSW5kZXggPSAwO1xuXHRsZXQgYkluZGV4ID0gMDtcblx0Y29uc3QgZGlmZnMgPSBbXTtcblx0Y29uc3QgZm91bmRTdWJzZXF1ZW5jZSA9IChuQ29tbW9uLCBhQ29tbW9uLCBiQ29tbW9uKSA9PiB7XG5cdFx0aWYgKGFJbmRleCAhPT0gYUNvbW1vbikge1xuXHRcdFx0ZGlmZnMucHVzaChuZXcgRGlmZihESUZGX0RFTEVURSwgYS5zbGljZShhSW5kZXgsIGFDb21tb24pKSk7XG5cdFx0fVxuXHRcdGlmIChiSW5kZXggIT09IGJDb21tb24pIHtcblx0XHRcdGRpZmZzLnB1c2gobmV3IERpZmYoRElGRl9JTlNFUlQsIGIuc2xpY2UoYkluZGV4LCBiQ29tbW9uKSkpO1xuXHRcdH1cblx0XHRhSW5kZXggPSBhQ29tbW9uICsgbkNvbW1vbjtcblx0XHRiSW5kZXggPSBiQ29tbW9uICsgbkNvbW1vbjtcblx0XHRkaWZmcy5wdXNoKG5ldyBEaWZmKERJRkZfRVFVQUwsIGIuc2xpY2UoYkNvbW1vbiwgYkluZGV4KSkpO1xuXHR9O1xuXHRkaWZmU2VxdWVuY2VzKGFMZW5ndGgsIGJMZW5ndGgsIGlzQ29tbW9uLCBmb3VuZFN1YnNlcXVlbmNlKTtcblx0Ly8gQWZ0ZXIgdGhlIGxhc3QgY29tbW9uIHN1YnNlcXVlbmNlLCBwdXNoIHJlbWFpbmluZyBjaGFuZ2UgaXRlbXMuXG5cdGlmIChhSW5kZXggIT09IGFMZW5ndGgpIHtcblx0XHRkaWZmcy5wdXNoKG5ldyBEaWZmKERJRkZfREVMRVRFLCBhLnNsaWNlKGFJbmRleCkpKTtcblx0fVxuXHRpZiAoYkluZGV4ICE9PSBiTGVuZ3RoKSB7XG5cdFx0ZGlmZnMucHVzaChuZXcgRGlmZihESUZGX0lOU0VSVCwgYi5zbGljZShiSW5kZXgpKSk7XG5cdH1cblx0cmV0dXJuIFtkaWZmcywgdHJ1bmNhdGVkXTtcbn1cblxuLy8gR2l2ZW4gY2hhbmdlIG9wIGFuZCBhcnJheSBvZiBkaWZmcywgcmV0dXJuIGNvbmNhdGVuYXRlZCBzdHJpbmc6XG4vLyAqIGluY2x1ZGUgY29tbW9uIHN0cmluZ3Ncbi8vICogaW5jbHVkZSBjaGFuZ2Ugc3RyaW5ncyB3aGljaCBoYXZlIGFyZ3VtZW50IG9wIHdpdGggY2hhbmdlQ29sb3Jcbi8vICogZXhjbHVkZSBjaGFuZ2Ugc3RyaW5ncyB3aGljaCBoYXZlIG9wcG9zaXRlIG9wXG5mdW5jdGlvbiBjb25jYXRlbmF0ZVJlbGV2YW50RGlmZnMob3AsIGRpZmZzLCBjaGFuZ2VDb2xvcikge1xuXHRyZXR1cm4gZGlmZnMucmVkdWNlKChyZWR1Y2VkLCBkaWZmKSA9PiByZWR1Y2VkICsgKGRpZmZbMF0gPT09IERJRkZfRVFVQUwgPyBkaWZmWzFdIDogZGlmZlswXSA9PT0gb3AgJiYgZGlmZlsxXS5sZW5ndGggIT09IDAgPyBjaGFuZ2VDb2xvcihkaWZmWzFdKSA6IFwiXCIpLCBcIlwiKTtcbn1cbi8vIEVuY2Fwc3VsYXRlIGNoYW5nZSBsaW5lcyB1bnRpbCBlaXRoZXIgYSBjb21tb24gbmV3bGluZSBvciB0aGUgZW5kLlxuY2xhc3MgQ2hhbmdlQnVmZmVyIHtcblx0b3A7XG5cdGxpbmU7XG5cdGxpbmVzO1xuXHRjaGFuZ2VDb2xvcjtcblx0Y29uc3RydWN0b3Iob3AsIGNoYW5nZUNvbG9yKSB7XG5cdFx0dGhpcy5vcCA9IG9wO1xuXHRcdHRoaXMubGluZSA9IFtdO1xuXHRcdHRoaXMubGluZXMgPSBbXTtcblx0XHR0aGlzLmNoYW5nZUNvbG9yID0gY2hhbmdlQ29sb3I7XG5cdH1cblx0cHVzaFN1YnN0cmluZyhzdWJzdHJpbmcpIHtcblx0XHR0aGlzLnB1c2hEaWZmKG5ldyBEaWZmKHRoaXMub3AsIHN1YnN0cmluZykpO1xuXHR9XG5cdHB1c2hMaW5lKCkge1xuXHRcdC8vIEFzc3VtZSBjYWxsIG9ubHkgaWYgbGluZSBoYXMgYXQgbGVhc3Qgb25lIGRpZmYsXG5cdFx0Ly8gdGhlcmVmb3JlIGFuIGVtcHR5IGxpbmUgbXVzdCBoYXZlIGEgZGlmZiB3aGljaCBoYXMgYW4gZW1wdHkgc3RyaW5nLlxuXHRcdC8vIElmIGxpbmUgaGFzIG11bHRpcGxlIGRpZmZzLCB0aGVuIGFzc3VtZSBpdCBoYXMgYSBjb21tb24gZGlmZixcblx0XHQvLyB0aGVyZWZvcmUgY2hhbmdlIGRpZmZzIGhhdmUgY2hhbmdlIGNvbG9yO1xuXHRcdC8vIG90aGVyd2lzZSB0aGVuIGl0IGhhcyBsaW5lIGNvbG9yIG9ubHkuXG5cdFx0dGhpcy5saW5lcy5wdXNoKHRoaXMubGluZS5sZW5ndGggIT09IDEgPyBuZXcgRGlmZih0aGlzLm9wLCBjb25jYXRlbmF0ZVJlbGV2YW50RGlmZnModGhpcy5vcCwgdGhpcy5saW5lLCB0aGlzLmNoYW5nZUNvbG9yKSkgOiB0aGlzLmxpbmVbMF1bMF0gPT09IHRoaXMub3AgPyB0aGlzLmxpbmVbMF0gOiBuZXcgRGlmZih0aGlzLm9wLCB0aGlzLmxpbmVbMF1bMV0pKTtcblx0XHR0aGlzLmxpbmUubGVuZ3RoID0gMDtcblx0fVxuXHRpc0xpbmVFbXB0eSgpIHtcblx0XHRyZXR1cm4gdGhpcy5saW5lLmxlbmd0aCA9PT0gMDtcblx0fVxuXHQvLyBNaW5vciBpbnB1dCB0byBidWZmZXIuXG5cdHB1c2hEaWZmKGRpZmYpIHtcblx0XHR0aGlzLmxpbmUucHVzaChkaWZmKTtcblx0fVxuXHQvLyBNYWluIGlucHV0IHRvIGJ1ZmZlci5cblx0YWxpZ24oZGlmZikge1xuXHRcdGNvbnN0IHN0cmluZyA9IGRpZmZbMV07XG5cdFx0aWYgKHN0cmluZy5pbmNsdWRlcyhcIlxcblwiKSkge1xuXHRcdFx0Y29uc3Qgc3Vic3RyaW5ncyA9IHN0cmluZy5zcGxpdChcIlxcblwiKTtcblx0XHRcdGNvbnN0IGlMYXN0ID0gc3Vic3RyaW5ncy5sZW5ndGggLSAxO1xuXHRcdFx0c3Vic3RyaW5ncy5mb3JFYWNoKChzdWJzdHJpbmcsIGkpID0+IHtcblx0XHRcdFx0aWYgKGkgPCBpTGFzdCkge1xuXHRcdFx0XHRcdC8vIFRoZSBmaXJzdCBzdWJzdHJpbmcgY29tcGxldGVzIHRoZSBjdXJyZW50IGNoYW5nZSBsaW5lLlxuXHRcdFx0XHRcdC8vIEEgbWlkZGxlIHN1YnN0cmluZyBpcyBhIGNoYW5nZSBsaW5lLlxuXHRcdFx0XHRcdHRoaXMucHVzaFN1YnN0cmluZyhzdWJzdHJpbmcpO1xuXHRcdFx0XHRcdHRoaXMucHVzaExpbmUoKTtcblx0XHRcdFx0fSBlbHNlIGlmIChzdWJzdHJpbmcubGVuZ3RoICE9PSAwKSB7XG5cdFx0XHRcdFx0Ly8gVGhlIGxhc3Qgc3Vic3RyaW5nIHN0YXJ0cyBhIGNoYW5nZSBsaW5lLCBpZiBpdCBpcyBub3QgZW1wdHkuXG5cdFx0XHRcdFx0Ly8gSW1wb3J0YW50OiBUaGlzIG5vbi1lbXB0eSBjb25kaXRpb24gYWxzbyBhdXRvbWF0aWNhbGx5IG9taXRzXG5cdFx0XHRcdFx0Ly8gdGhlIG5ld2xpbmUgYXBwZW5kZWQgdG8gdGhlIGVuZCBvZiBleHBlY3RlZCBhbmQgcmVjZWl2ZWQgc3RyaW5ncy5cblx0XHRcdFx0XHR0aGlzLnB1c2hTdWJzdHJpbmcoc3Vic3RyaW5nKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIEFwcGVuZCBub24tbXVsdGlsaW5lIHN0cmluZyB0byBjdXJyZW50IGNoYW5nZSBsaW5lLlxuXHRcdFx0dGhpcy5wdXNoRGlmZihkaWZmKTtcblx0XHR9XG5cdH1cblx0Ly8gT3V0cHV0IGZyb20gYnVmZmVyLlxuXHRtb3ZlTGluZXNUbyhsaW5lcykge1xuXHRcdGlmICghdGhpcy5pc0xpbmVFbXB0eSgpKSB7XG5cdFx0XHR0aGlzLnB1c2hMaW5lKCk7XG5cdFx0fVxuXHRcdGxpbmVzLnB1c2goLi4udGhpcy5saW5lcyk7XG5cdFx0dGhpcy5saW5lcy5sZW5ndGggPSAwO1xuXHR9XG59XG4vLyBFbmNhcHN1bGF0ZSBjb21tb24gYW5kIGNoYW5nZSBsaW5lcy5cbmNsYXNzIENvbW1vbkJ1ZmZlciB7XG5cdGRlbGV0ZUJ1ZmZlcjtcblx0aW5zZXJ0QnVmZmVyO1xuXHRsaW5lcztcblx0Y29uc3RydWN0b3IoZGVsZXRlQnVmZmVyLCBpbnNlcnRCdWZmZXIpIHtcblx0XHR0aGlzLmRlbGV0ZUJ1ZmZlciA9IGRlbGV0ZUJ1ZmZlcjtcblx0XHR0aGlzLmluc2VydEJ1ZmZlciA9IGluc2VydEJ1ZmZlcjtcblx0XHR0aGlzLmxpbmVzID0gW107XG5cdH1cblx0cHVzaERpZmZDb21tb25MaW5lKGRpZmYpIHtcblx0XHR0aGlzLmxpbmVzLnB1c2goZGlmZik7XG5cdH1cblx0cHVzaERpZmZDaGFuZ2VMaW5lcyhkaWZmKSB7XG5cdFx0Y29uc3QgaXNEaWZmRW1wdHkgPSBkaWZmWzFdLmxlbmd0aCA9PT0gMDtcblx0XHQvLyBBbiBlbXB0eSBkaWZmIHN0cmluZyBpcyByZWR1bmRhbnQsIHVubGVzcyBhIGNoYW5nZSBsaW5lIGlzIGVtcHR5LlxuXHRcdGlmICghaXNEaWZmRW1wdHkgfHwgdGhpcy5kZWxldGVCdWZmZXIuaXNMaW5lRW1wdHkoKSkge1xuXHRcdFx0dGhpcy5kZWxldGVCdWZmZXIucHVzaERpZmYoZGlmZik7XG5cdFx0fVxuXHRcdGlmICghaXNEaWZmRW1wdHkgfHwgdGhpcy5pbnNlcnRCdWZmZXIuaXNMaW5lRW1wdHkoKSkge1xuXHRcdFx0dGhpcy5pbnNlcnRCdWZmZXIucHVzaERpZmYoZGlmZik7XG5cdFx0fVxuXHR9XG5cdGZsdXNoQ2hhbmdlTGluZXMoKSB7XG5cdFx0dGhpcy5kZWxldGVCdWZmZXIubW92ZUxpbmVzVG8odGhpcy5saW5lcyk7XG5cdFx0dGhpcy5pbnNlcnRCdWZmZXIubW92ZUxpbmVzVG8odGhpcy5saW5lcyk7XG5cdH1cblx0Ly8gSW5wdXQgdG8gYnVmZmVyLlxuXHRhbGlnbihkaWZmKSB7XG5cdFx0Y29uc3Qgb3AgPSBkaWZmWzBdO1xuXHRcdGNvbnN0IHN0cmluZyA9IGRpZmZbMV07XG5cdFx0aWYgKHN0cmluZy5pbmNsdWRlcyhcIlxcblwiKSkge1xuXHRcdFx0Y29uc3Qgc3Vic3RyaW5ncyA9IHN0cmluZy5zcGxpdChcIlxcblwiKTtcblx0XHRcdGNvbnN0IGlMYXN0ID0gc3Vic3RyaW5ncy5sZW5ndGggLSAxO1xuXHRcdFx0c3Vic3RyaW5ncy5mb3JFYWNoKChzdWJzdHJpbmcsIGkpID0+IHtcblx0XHRcdFx0aWYgKGkgPT09IDApIHtcblx0XHRcdFx0XHRjb25zdCBzdWJkaWZmID0gbmV3IERpZmYob3AsIHN1YnN0cmluZyk7XG5cdFx0XHRcdFx0aWYgKHRoaXMuZGVsZXRlQnVmZmVyLmlzTGluZUVtcHR5KCkgJiYgdGhpcy5pbnNlcnRCdWZmZXIuaXNMaW5lRW1wdHkoKSkge1xuXHRcdFx0XHRcdFx0Ly8gSWYgYm90aCBjdXJyZW50IGNoYW5nZSBsaW5lcyBhcmUgZW1wdHksXG5cdFx0XHRcdFx0XHQvLyB0aGVuIHRoZSBmaXJzdCBzdWJzdHJpbmcgaXMgYSBjb21tb24gbGluZS5cblx0XHRcdFx0XHRcdHRoaXMuZmx1c2hDaGFuZ2VMaW5lcygpO1xuXHRcdFx0XHRcdFx0dGhpcy5wdXNoRGlmZkNvbW1vbkxpbmUoc3ViZGlmZik7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdC8vIElmIGVpdGhlciBjdXJyZW50IGNoYW5nZSBsaW5lIGlzIG5vbi1lbXB0eSxcblx0XHRcdFx0XHRcdC8vIHRoZW4gdGhlIGZpcnN0IHN1YnN0cmluZyBjb21wbGV0ZXMgdGhlIGNoYW5nZSBsaW5lcy5cblx0XHRcdFx0XHRcdHRoaXMucHVzaERpZmZDaGFuZ2VMaW5lcyhzdWJkaWZmKTtcblx0XHRcdFx0XHRcdHRoaXMuZmx1c2hDaGFuZ2VMaW5lcygpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIGlmIChpIDwgaUxhc3QpIHtcblx0XHRcdFx0XHQvLyBBIG1pZGRsZSBzdWJzdHJpbmcgaXMgYSBjb21tb24gbGluZS5cblx0XHRcdFx0XHR0aGlzLnB1c2hEaWZmQ29tbW9uTGluZShuZXcgRGlmZihvcCwgc3Vic3RyaW5nKSk7XG5cdFx0XHRcdH0gZWxzZSBpZiAoc3Vic3RyaW5nLmxlbmd0aCAhPT0gMCkge1xuXHRcdFx0XHRcdC8vIFRoZSBsYXN0IHN1YnN0cmluZyBzdGFydHMgYSBjaGFuZ2UgbGluZSwgaWYgaXQgaXMgbm90IGVtcHR5LlxuXHRcdFx0XHRcdC8vIEltcG9ydGFudDogVGhpcyBub24tZW1wdHkgY29uZGl0aW9uIGFsc28gYXV0b21hdGljYWxseSBvbWl0c1xuXHRcdFx0XHRcdC8vIHRoZSBuZXdsaW5lIGFwcGVuZGVkIHRvIHRoZSBlbmQgb2YgZXhwZWN0ZWQgYW5kIHJlY2VpdmVkIHN0cmluZ3MuXG5cdFx0XHRcdFx0dGhpcy5wdXNoRGlmZkNoYW5nZUxpbmVzKG5ldyBEaWZmKG9wLCBzdWJzdHJpbmcpKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIEFwcGVuZCBub24tbXVsdGlsaW5lIHN0cmluZyB0byBjdXJyZW50IGNoYW5nZSBsaW5lcy5cblx0XHRcdC8vIEltcG9ydGFudDogSXQgY2Fubm90IGJlIGF0IHRoZSBlbmQgZm9sbG93aW5nIGVtcHR5IGNoYW5nZSBsaW5lcyxcblx0XHRcdC8vIGJlY2F1c2UgbmV3bGluZSBhcHBlbmRlZCB0byB0aGUgZW5kIG9mIGV4cGVjdGVkIGFuZCByZWNlaXZlZCBzdHJpbmdzLlxuXHRcdFx0dGhpcy5wdXNoRGlmZkNoYW5nZUxpbmVzKGRpZmYpO1xuXHRcdH1cblx0fVxuXHQvLyBPdXRwdXQgZnJvbSBidWZmZXIuXG5cdGdldExpbmVzKCkge1xuXHRcdHRoaXMuZmx1c2hDaGFuZ2VMaW5lcygpO1xuXHRcdHJldHVybiB0aGlzLmxpbmVzO1xuXHR9XG59XG4vLyBHaXZlbiBkaWZmcyBmcm9tIGV4cGVjdGVkIGFuZCByZWNlaXZlZCBzdHJpbmdzLFxuLy8gcmV0dXJuIG5ldyBhcnJheSBvZiBkaWZmcyBzcGxpdCBvciBqb2luZWQgaW50byBsaW5lcy5cbi8vXG4vLyBUbyBjb3JyZWN0bHkgYWxpZ24gYSBjaGFuZ2UgbGluZSBhdCB0aGUgZW5kLCB0aGUgYWxnb3JpdGhtOlxuLy8gKiBhc3N1bWVzIHRoYXQgYSBuZXdsaW5lIHdhcyBhcHBlbmRlZCB0byB0aGUgc3RyaW5nc1xuLy8gKiBvbWl0cyB0aGUgbGFzdCBuZXdsaW5lIGZyb20gdGhlIG91dHB1dCBhcnJheVxuLy9cbi8vIEFzc3VtZSB0aGUgZnVuY3Rpb24gaXMgbm90IGNhbGxlZDpcbi8vICogaWYgZWl0aGVyIGV4cGVjdGVkIG9yIHJlY2VpdmVkIGlzIGVtcHR5IHN0cmluZ1xuLy8gKiBpZiBuZWl0aGVyIGV4cGVjdGVkIG5vciByZWNlaXZlZCBpcyBtdWx0aWxpbmUgc3RyaW5nXG5mdW5jdGlvbiBnZXRBbGlnbmVkRGlmZnMoZGlmZnMsIGNoYW5nZUNvbG9yKSB7XG5cdGNvbnN0IGRlbGV0ZUJ1ZmZlciA9IG5ldyBDaGFuZ2VCdWZmZXIoRElGRl9ERUxFVEUsIGNoYW5nZUNvbG9yKTtcblx0Y29uc3QgaW5zZXJ0QnVmZmVyID0gbmV3IENoYW5nZUJ1ZmZlcihESUZGX0lOU0VSVCwgY2hhbmdlQ29sb3IpO1xuXHRjb25zdCBjb21tb25CdWZmZXIgPSBuZXcgQ29tbW9uQnVmZmVyKGRlbGV0ZUJ1ZmZlciwgaW5zZXJ0QnVmZmVyKTtcblx0ZGlmZnMuZm9yRWFjaCgoZGlmZikgPT4ge1xuXHRcdHN3aXRjaCAoZGlmZlswXSkge1xuXHRcdFx0Y2FzZSBESUZGX0RFTEVURTpcblx0XHRcdFx0ZGVsZXRlQnVmZmVyLmFsaWduKGRpZmYpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgRElGRl9JTlNFUlQ6XG5cdFx0XHRcdGluc2VydEJ1ZmZlci5hbGlnbihkaWZmKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRkZWZhdWx0OiBjb21tb25CdWZmZXIuYWxpZ24oZGlmZik7XG5cdFx0fVxuXHR9KTtcblx0cmV0dXJuIGNvbW1vbkJ1ZmZlci5nZXRMaW5lcygpO1xufVxuXG5mdW5jdGlvbiBoYXNDb21tb25EaWZmKGRpZmZzLCBpc011bHRpbGluZSkge1xuXHRpZiAoaXNNdWx0aWxpbmUpIHtcblx0XHQvLyBJbXBvcnRhbnQ6IElnbm9yZSBjb21tb24gbmV3bGluZSB0aGF0IHdhcyBhcHBlbmRlZCB0byBtdWx0aWxpbmUgc3RyaW5ncyFcblx0XHRjb25zdCBpTGFzdCA9IGRpZmZzLmxlbmd0aCAtIDE7XG5cdFx0cmV0dXJuIGRpZmZzLnNvbWUoKGRpZmYsIGkpID0+IGRpZmZbMF0gPT09IERJRkZfRVFVQUwgJiYgKGkgIT09IGlMYXN0IHx8IGRpZmZbMV0gIT09IFwiXFxuXCIpKTtcblx0fVxuXHRyZXR1cm4gZGlmZnMuc29tZSgoZGlmZikgPT4gZGlmZlswXSA9PT0gRElGRl9FUVVBTCk7XG59XG4vLyBDb21wYXJlIHR3byBzdHJpbmdzIGNoYXJhY3Rlci1ieS1jaGFyYWN0ZXIuXG4vLyBGb3JtYXQgYXMgY29tcGFyaXNvbiBsaW5lcyBpbiB3aGljaCBjaGFuZ2VkIHN1YnN0cmluZ3MgaGF2ZSBpbnZlcnNlIGNvbG9ycy5cbmZ1bmN0aW9uIGRpZmZTdHJpbmdzVW5pZmllZChhLCBiLCBvcHRpb25zKSB7XG5cdGlmIChhICE9PSBiICYmIGEubGVuZ3RoICE9PSAwICYmIGIubGVuZ3RoICE9PSAwKSB7XG5cdFx0Y29uc3QgaXNNdWx0aWxpbmUgPSBhLmluY2x1ZGVzKFwiXFxuXCIpIHx8IGIuaW5jbHVkZXMoXCJcXG5cIik7XG5cdFx0Ly8gZ2V0QWxpZ25lZERpZmZzIGFzc3VtZXMgdGhhdCBhIG5ld2xpbmUgd2FzIGFwcGVuZGVkIHRvIHRoZSBzdHJpbmdzLlxuXHRcdGNvbnN0IFtkaWZmcywgdHJ1bmNhdGVkXSA9IGRpZmZTdHJpbmdzUmF3KGlzTXVsdGlsaW5lID8gYCR7YX1cXG5gIDogYSwgaXNNdWx0aWxpbmUgPyBgJHtifVxcbmAgOiBiLCB0cnVlLCBvcHRpb25zKTtcblx0XHRpZiAoaGFzQ29tbW9uRGlmZihkaWZmcywgaXNNdWx0aWxpbmUpKSB7XG5cdFx0XHRjb25zdCBvcHRpb25zTm9ybWFsaXplZCA9IG5vcm1hbGl6ZURpZmZPcHRpb25zKG9wdGlvbnMpO1xuXHRcdFx0Y29uc3QgbGluZXMgPSBnZXRBbGlnbmVkRGlmZnMoZGlmZnMsIG9wdGlvbnNOb3JtYWxpemVkLmNoYW5nZUNvbG9yKTtcblx0XHRcdHJldHVybiBwcmludERpZmZMaW5lcyhsaW5lcywgdHJ1bmNhdGVkLCBvcHRpb25zTm9ybWFsaXplZCk7XG5cdFx0fVxuXHR9XG5cdC8vIEZhbGwgYmFjayB0byBsaW5lLWJ5LWxpbmUgZGlmZi5cblx0cmV0dXJuIGRpZmZMaW5lc1VuaWZpZWQoYS5zcGxpdChcIlxcblwiKSwgYi5zcGxpdChcIlxcblwiKSwgb3B0aW9ucyk7XG59XG4vLyBDb21wYXJlIHR3byBzdHJpbmdzIGNoYXJhY3Rlci1ieS1jaGFyYWN0ZXIuXG4vLyBPcHRpb25hbGx5IGNsZWFuIHVwIHNtYWxsIGNvbW1vbiBzdWJzdHJpbmdzLCBhbHNvIGtub3duIGFzIGNoYWZmLlxuZnVuY3Rpb24gZGlmZlN0cmluZ3NSYXcoYSwgYiwgY2xlYW51cCwgb3B0aW9ucykge1xuXHRjb25zdCBbZGlmZnMsIHRydW5jYXRlZF0gPSBkaWZmU3RyaW5ncyhhLCBiLCBvcHRpb25zKTtcblx0aWYgKGNsZWFudXApIHtcblx0XHRkaWZmX2NsZWFudXBTZW1hbnRpYyhkaWZmcyk7XG5cdH1cblx0cmV0dXJuIFtkaWZmcywgdHJ1bmNhdGVkXTtcbn1cblxuZnVuY3Rpb24gZ2V0Q29tbW9uTWVzc2FnZShtZXNzYWdlLCBvcHRpb25zKSB7XG5cdGNvbnN0IHsgY29tbW9uQ29sb3IgfSA9IG5vcm1hbGl6ZURpZmZPcHRpb25zKG9wdGlvbnMpO1xuXHRyZXR1cm4gY29tbW9uQ29sb3IobWVzc2FnZSk7XG59XG5jb25zdCB7IEFzeW1tZXRyaWNNYXRjaGVyLCBET01Db2xsZWN0aW9uLCBET01FbGVtZW50LCBJbW11dGFibGUsIFJlYWN0RWxlbWVudCwgUmVhY3RUZXN0Q29tcG9uZW50IH0gPSBwbHVnaW5zO1xuY29uc3QgUExVR0lOUyA9IFtcblx0UmVhY3RUZXN0Q29tcG9uZW50LFxuXHRSZWFjdEVsZW1lbnQsXG5cdERPTUVsZW1lbnQsXG5cdERPTUNvbGxlY3Rpb24sXG5cdEltbXV0YWJsZSxcblx0QXN5bW1ldHJpY01hdGNoZXIsXG5cdHBsdWdpbnMuRXJyb3Jcbl07XG5jb25zdCBGT1JNQVRfT1BUSU9OUyA9IHtcblx0bWF4RGVwdGg6IDIwLFxuXHRwbHVnaW5zOiBQTFVHSU5TXG59O1xuY29uc3QgRkFMTEJBQ0tfRk9STUFUX09QVElPTlMgPSB7XG5cdGNhbGxUb0pTT046IGZhbHNlLFxuXHRtYXhEZXB0aDogOCxcblx0cGx1Z2luczogUExVR0lOU1xufTtcbi8vIEdlbmVyYXRlIGEgc3RyaW5nIHRoYXQgd2lsbCBoaWdobGlnaHQgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0d28gdmFsdWVzXG4vLyB3aXRoIGdyZWVuIGFuZCByZWQuIChzaW1pbGFyIHRvIGhvdyBnaXRodWIgZG9lcyBjb2RlIGRpZmZpbmcpXG4vKipcbiogQHBhcmFtIGEgRXhwZWN0ZWQgdmFsdWVcbiogQHBhcmFtIGIgUmVjZWl2ZWQgdmFsdWVcbiogQHBhcmFtIG9wdGlvbnMgRGlmZiBvcHRpb25zXG4qIEByZXR1cm5zIHtzdHJpbmcgfCBudWxsfSBhIHN0cmluZyBkaWZmXG4qL1xuZnVuY3Rpb24gZGlmZihhLCBiLCBvcHRpb25zKSB7XG5cdGlmIChPYmplY3QuaXMoYSwgYikpIHtcblx0XHRyZXR1cm4gXCJcIjtcblx0fVxuXHRjb25zdCBhVHlwZSA9IGdldFR5cGUoYSk7XG5cdGxldCBleHBlY3RlZFR5cGUgPSBhVHlwZTtcblx0bGV0IG9taXREaWZmZXJlbmNlID0gZmFsc2U7XG5cdGlmIChhVHlwZSA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgYS5hc3ltbWV0cmljTWF0Y2ggPT09IFwiZnVuY3Rpb25cIikge1xuXHRcdGlmIChhLiQkdHlwZW9mICE9PSBTeW1ib2wuZm9yKFwiamVzdC5hc3ltbWV0cmljTWF0Y2hlclwiKSkge1xuXHRcdFx0Ly8gRG8gbm90IGtub3cgZXhwZWN0ZWQgdHlwZSBvZiB1c2VyLWRlZmluZWQgYXN5bW1ldHJpYyBtYXRjaGVyLlxuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBhLmdldEV4cGVjdGVkVHlwZSAhPT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHQvLyBGb3IgZXhhbXBsZSwgZXhwZWN0LmFueXRoaW5nKCkgbWF0Y2hlcyBlaXRoZXIgbnVsbCBvciB1bmRlZmluZWRcblx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdGV4cGVjdGVkVHlwZSA9IGEuZ2V0RXhwZWN0ZWRUeXBlKCk7XG5cdFx0Ly8gUHJpbWl0aXZlIHR5cGVzIGJvb2xlYW4gYW5kIG51bWJlciBvbWl0IGRpZmZlcmVuY2UgYmVsb3cuXG5cdFx0Ly8gRm9yIGV4YW1wbGUsIG9taXQgZGlmZmVyZW5jZSBmb3IgZXhwZWN0LnN0cmluZ01hdGNoaW5nKHJlZ2V4cClcblx0XHRvbWl0RGlmZmVyZW5jZSA9IGV4cGVjdGVkVHlwZSA9PT0gXCJzdHJpbmdcIjtcblx0fVxuXHRpZiAoZXhwZWN0ZWRUeXBlICE9PSBnZXRUeXBlKGIpKSB7XG5cdFx0Y29uc3QgeyBhQW5ub3RhdGlvbiwgYUNvbG9yLCBhSW5kaWNhdG9yLCBiQW5ub3RhdGlvbiwgYkNvbG9yLCBiSW5kaWNhdG9yIH0gPSBub3JtYWxpemVEaWZmT3B0aW9ucyhvcHRpb25zKTtcblx0XHRjb25zdCBmb3JtYXRPcHRpb25zID0gZ2V0Rm9ybWF0T3B0aW9ucyhGQUxMQkFDS19GT1JNQVRfT1BUSU9OUywgb3B0aW9ucyk7XG5cdFx0bGV0IGFEaXNwbGF5ID0gZm9ybWF0KGEsIGZvcm1hdE9wdGlvbnMpO1xuXHRcdGxldCBiRGlzcGxheSA9IGZvcm1hdChiLCBmb3JtYXRPcHRpb25zKTtcblx0XHQvLyBldmVuIGlmIHByZXR0eUZvcm1hdCBwcmludHMgc3VjY2Vzc2Z1bGx5IGJpZyBvYmplY3RzLFxuXHRcdC8vIGxhcmdlIHN0cmluZyBjYW4gY2hva2UgbGF0ZXIgb24gKGNvbmNhdGVuYXRpb24/IFJQQz8pLFxuXHRcdC8vIHNvIHRydW5jYXRlIGl0IHRvIGEgcmVhc29uYWJsZSBsZW5ndGggaGVyZS5cblx0XHQvLyAoRm9yIGV4YW1wbGUsIHBsYXl3cmlnaHQncyBFbGVtZW50SGFuZGxlIGNhbiBiZWNvbWUgYWJvdXQgMjAwXzAwMF8wMDAgbGVuZ3RoIHN0cmluZylcblx0XHRjb25zdCBNQVhfTEVOR1RIID0gMWU1O1xuXHRcdGZ1bmN0aW9uIHRydW5jYXRlKHMpIHtcblx0XHRcdHJldHVybiBzLmxlbmd0aCA8PSBNQVhfTEVOR1RIID8gcyA6IGAke3Muc2xpY2UoMCwgTUFYX0xFTkdUSCl9Li4uYDtcblx0XHR9XG5cdFx0YURpc3BsYXkgPSB0cnVuY2F0ZShhRGlzcGxheSk7XG5cdFx0YkRpc3BsYXkgPSB0cnVuY2F0ZShiRGlzcGxheSk7XG5cdFx0Y29uc3QgYURpZmYgPSBgJHthQ29sb3IoYCR7YUluZGljYXRvcn0gJHthQW5ub3RhdGlvbn06YCl9XFxuJHthRGlzcGxheX1gO1xuXHRcdGNvbnN0IGJEaWZmID0gYCR7YkNvbG9yKGAke2JJbmRpY2F0b3J9ICR7YkFubm90YXRpb259OmApfVxcbiR7YkRpc3BsYXl9YDtcblx0XHRyZXR1cm4gYCR7YURpZmZ9XFxuXFxuJHtiRGlmZn1gO1xuXHR9XG5cdGlmIChvbWl0RGlmZmVyZW5jZSkge1xuXHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdH1cblx0c3dpdGNoIChhVHlwZSkge1xuXHRcdGNhc2UgXCJzdHJpbmdcIjogcmV0dXJuIGRpZmZMaW5lc1VuaWZpZWQoYS5zcGxpdChcIlxcblwiKSwgYi5zcGxpdChcIlxcblwiKSwgb3B0aW9ucyk7XG5cdFx0Y2FzZSBcImJvb2xlYW5cIjpcblx0XHRjYXNlIFwibnVtYmVyXCI6IHJldHVybiBjb21wYXJlUHJpbWl0aXZlKGEsIGIsIG9wdGlvbnMpO1xuXHRcdGNhc2UgXCJtYXBcIjogcmV0dXJuIGNvbXBhcmVPYmplY3RzKHNvcnRNYXAoYSksIHNvcnRNYXAoYiksIG9wdGlvbnMpO1xuXHRcdGNhc2UgXCJzZXRcIjogcmV0dXJuIGNvbXBhcmVPYmplY3RzKHNvcnRTZXQoYSksIHNvcnRTZXQoYiksIG9wdGlvbnMpO1xuXHRcdGRlZmF1bHQ6IHJldHVybiBjb21wYXJlT2JqZWN0cyhhLCBiLCBvcHRpb25zKTtcblx0fVxufVxuZnVuY3Rpb24gY29tcGFyZVByaW1pdGl2ZShhLCBiLCBvcHRpb25zKSB7XG5cdGNvbnN0IGFGb3JtYXQgPSBmb3JtYXQoYSwgRk9STUFUX09QVElPTlMpO1xuXHRjb25zdCBiRm9ybWF0ID0gZm9ybWF0KGIsIEZPUk1BVF9PUFRJT05TKTtcblx0cmV0dXJuIGFGb3JtYXQgPT09IGJGb3JtYXQgPyBcIlwiIDogZGlmZkxpbmVzVW5pZmllZChhRm9ybWF0LnNwbGl0KFwiXFxuXCIpLCBiRm9ybWF0LnNwbGl0KFwiXFxuXCIpLCBvcHRpb25zKTtcbn1cbmZ1bmN0aW9uIHNvcnRNYXAobWFwKSB7XG5cdHJldHVybiBuZXcgTWFwKEFycmF5LmZyb20obWFwLmVudHJpZXMoKSkuc29ydCgpKTtcbn1cbmZ1bmN0aW9uIHNvcnRTZXQoc2V0KSB7XG5cdHJldHVybiBuZXcgU2V0KEFycmF5LmZyb20oc2V0LnZhbHVlcygpKS5zb3J0KCkpO1xufVxuZnVuY3Rpb24gY29tcGFyZU9iamVjdHMoYSwgYiwgb3B0aW9ucykge1xuXHRsZXQgZGlmZmVyZW5jZTtcblx0bGV0IGhhc1Rocm93biA9IGZhbHNlO1xuXHR0cnkge1xuXHRcdGNvbnN0IGZvcm1hdE9wdGlvbnMgPSBnZXRGb3JtYXRPcHRpb25zKEZPUk1BVF9PUFRJT05TLCBvcHRpb25zKTtcblx0XHRkaWZmZXJlbmNlID0gZ2V0T2JqZWN0c0RpZmZlcmVuY2UoYSwgYiwgZm9ybWF0T3B0aW9ucywgb3B0aW9ucyk7XG5cdH0gY2F0Y2gge1xuXHRcdGhhc1Rocm93biA9IHRydWU7XG5cdH1cblx0Y29uc3Qgbm9EaWZmTWVzc2FnZSA9IGdldENvbW1vbk1lc3NhZ2UoTk9fRElGRl9NRVNTQUdFLCBvcHRpb25zKTtcblx0Ly8gSWYgdGhlIGNvbXBhcmlzb24geWllbGRzIG5vIHJlc3VsdHMsIGNvbXBhcmUgYWdhaW4gYnV0IHRoaXMgdGltZVxuXHQvLyB3aXRob3V0IGNhbGxpbmcgYHRvSlNPTmAuIEl0J3MgYWxzbyBwb3NzaWJsZSB0aGF0IHRvSlNPTiBtaWdodCB0aHJvdy5cblx0aWYgKGRpZmZlcmVuY2UgPT09IHVuZGVmaW5lZCB8fCBkaWZmZXJlbmNlID09PSBub0RpZmZNZXNzYWdlKSB7XG5cdFx0Y29uc3QgZm9ybWF0T3B0aW9ucyA9IGdldEZvcm1hdE9wdGlvbnMoRkFMTEJBQ0tfRk9STUFUX09QVElPTlMsIG9wdGlvbnMpO1xuXHRcdGRpZmZlcmVuY2UgPSBnZXRPYmplY3RzRGlmZmVyZW5jZShhLCBiLCBmb3JtYXRPcHRpb25zLCBvcHRpb25zKTtcblx0XHRpZiAoZGlmZmVyZW5jZSAhPT0gbm9EaWZmTWVzc2FnZSAmJiAhaGFzVGhyb3duKSB7XG5cdFx0XHRkaWZmZXJlbmNlID0gYCR7Z2V0Q29tbW9uTWVzc2FnZShTSU1JTEFSX01FU1NBR0UsIG9wdGlvbnMpfVxcblxcbiR7ZGlmZmVyZW5jZX1gO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gZGlmZmVyZW5jZTtcbn1cbmZ1bmN0aW9uIGdldEZvcm1hdE9wdGlvbnMoZm9ybWF0T3B0aW9ucywgb3B0aW9ucykge1xuXHRjb25zdCB7IGNvbXBhcmVLZXlzLCBwcmludEJhc2ljUHJvdG90eXBlLCBtYXhEZXB0aCB9ID0gbm9ybWFsaXplRGlmZk9wdGlvbnMob3B0aW9ucyk7XG5cdHJldHVybiB7XG5cdFx0Li4uZm9ybWF0T3B0aW9ucyxcblx0XHRjb21wYXJlS2V5cyxcblx0XHRwcmludEJhc2ljUHJvdG90eXBlLFxuXHRcdG1heERlcHRoOiBtYXhEZXB0aCA/PyBmb3JtYXRPcHRpb25zLm1heERlcHRoXG5cdH07XG59XG5mdW5jdGlvbiBnZXRPYmplY3RzRGlmZmVyZW5jZShhLCBiLCBmb3JtYXRPcHRpb25zLCBvcHRpb25zKSB7XG5cdGNvbnN0IGZvcm1hdE9wdGlvbnNaZXJvSW5kZW50ID0ge1xuXHRcdC4uLmZvcm1hdE9wdGlvbnMsXG5cdFx0aW5kZW50OiAwXG5cdH07XG5cdGNvbnN0IGFDb21wYXJlID0gZm9ybWF0KGEsIGZvcm1hdE9wdGlvbnNaZXJvSW5kZW50KTtcblx0Y29uc3QgYkNvbXBhcmUgPSBmb3JtYXQoYiwgZm9ybWF0T3B0aW9uc1plcm9JbmRlbnQpO1xuXHRpZiAoYUNvbXBhcmUgPT09IGJDb21wYXJlKSB7XG5cdFx0cmV0dXJuIGdldENvbW1vbk1lc3NhZ2UoTk9fRElGRl9NRVNTQUdFLCBvcHRpb25zKTtcblx0fSBlbHNlIHtcblx0XHRjb25zdCBhRGlzcGxheSA9IGZvcm1hdChhLCBmb3JtYXRPcHRpb25zKTtcblx0XHRjb25zdCBiRGlzcGxheSA9IGZvcm1hdChiLCBmb3JtYXRPcHRpb25zKTtcblx0XHRyZXR1cm4gZGlmZkxpbmVzVW5pZmllZDIoYURpc3BsYXkuc3BsaXQoXCJcXG5cIiksIGJEaXNwbGF5LnNwbGl0KFwiXFxuXCIpLCBhQ29tcGFyZS5zcGxpdChcIlxcblwiKSwgYkNvbXBhcmUuc3BsaXQoXCJcXG5cIiksIG9wdGlvbnMpO1xuXHR9XG59XG5jb25zdCBNQVhfRElGRl9TVFJJTkdfTEVOR1RIID0gMmU0O1xuZnVuY3Rpb24gaXNBc3ltbWV0cmljTWF0Y2hlcihkYXRhKSB7XG5cdGNvbnN0IHR5cGUgPSBnZXRUeXBlJDEoZGF0YSk7XG5cdHJldHVybiB0eXBlID09PSBcIk9iamVjdFwiICYmIHR5cGVvZiBkYXRhLmFzeW1tZXRyaWNNYXRjaCA9PT0gXCJmdW5jdGlvblwiO1xufVxuZnVuY3Rpb24gaXNSZXBsYWNlYWJsZShvYmoxLCBvYmoyKSB7XG5cdGNvbnN0IG9iajFUeXBlID0gZ2V0VHlwZSQxKG9iajEpO1xuXHRjb25zdCBvYmoyVHlwZSA9IGdldFR5cGUkMShvYmoyKTtcblx0cmV0dXJuIG9iajFUeXBlID09PSBvYmoyVHlwZSAmJiAob2JqMVR5cGUgPT09IFwiT2JqZWN0XCIgfHwgb2JqMVR5cGUgPT09IFwiQXJyYXlcIik7XG59XG5mdW5jdGlvbiBwcmludERpZmZPclN0cmluZ2lmeShyZWNlaXZlZCwgZXhwZWN0ZWQsIG9wdGlvbnMpIHtcblx0Y29uc3QgeyBhQW5ub3RhdGlvbiwgYkFubm90YXRpb24gfSA9IG5vcm1hbGl6ZURpZmZPcHRpb25zKG9wdGlvbnMpO1xuXHRpZiAodHlwZW9mIGV4cGVjdGVkID09PSBcInN0cmluZ1wiICYmIHR5cGVvZiByZWNlaXZlZCA9PT0gXCJzdHJpbmdcIiAmJiBleHBlY3RlZC5sZW5ndGggPiAwICYmIHJlY2VpdmVkLmxlbmd0aCA+IDAgJiYgZXhwZWN0ZWQubGVuZ3RoIDw9IE1BWF9ESUZGX1NUUklOR19MRU5HVEggJiYgcmVjZWl2ZWQubGVuZ3RoIDw9IE1BWF9ESUZGX1NUUklOR19MRU5HVEggJiYgZXhwZWN0ZWQgIT09IHJlY2VpdmVkKSB7XG5cdFx0aWYgKGV4cGVjdGVkLmluY2x1ZGVzKFwiXFxuXCIpIHx8IHJlY2VpdmVkLmluY2x1ZGVzKFwiXFxuXCIpKSB7XG5cdFx0XHRyZXR1cm4gZGlmZlN0cmluZ3NVbmlmaWVkKGV4cGVjdGVkLCByZWNlaXZlZCwgb3B0aW9ucyk7XG5cdFx0fVxuXHRcdGNvbnN0IFtkaWZmc10gPSBkaWZmU3RyaW5nc1JhdyhleHBlY3RlZCwgcmVjZWl2ZWQsIHRydWUpO1xuXHRcdGNvbnN0IGhhc0NvbW1vbkRpZmYgPSBkaWZmcy5zb21lKChkaWZmKSA9PiBkaWZmWzBdID09PSBESUZGX0VRVUFMKTtcblx0XHRjb25zdCBwcmludExhYmVsID0gZ2V0TGFiZWxQcmludGVyKGFBbm5vdGF0aW9uLCBiQW5ub3RhdGlvbik7XG5cdFx0Y29uc3QgZXhwZWN0ZWRMaW5lID0gcHJpbnRMYWJlbChhQW5ub3RhdGlvbikgKyBwcmludEV4cGVjdGVkKGdldENvbW1vbkFuZENoYW5nZWRTdWJzdHJpbmdzKGRpZmZzLCBESUZGX0RFTEVURSwgaGFzQ29tbW9uRGlmZikpO1xuXHRcdGNvbnN0IHJlY2VpdmVkTGluZSA9IHByaW50TGFiZWwoYkFubm90YXRpb24pICsgcHJpbnRSZWNlaXZlZChnZXRDb21tb25BbmRDaGFuZ2VkU3Vic3RyaW5ncyhkaWZmcywgRElGRl9JTlNFUlQsIGhhc0NvbW1vbkRpZmYpKTtcblx0XHRyZXR1cm4gYCR7ZXhwZWN0ZWRMaW5lfVxcbiR7cmVjZWl2ZWRMaW5lfWA7XG5cdH1cblx0Ly8gaWYgKGlzTGluZURpZmZhYmxlKGV4cGVjdGVkLCByZWNlaXZlZCkpIHtcblx0Y29uc3QgY2xvbmVkRXhwZWN0ZWQgPSBkZWVwQ2xvbmUoZXhwZWN0ZWQsIHsgZm9yY2VXcml0YWJsZTogdHJ1ZSB9KTtcblx0Y29uc3QgY2xvbmVkUmVjZWl2ZWQgPSBkZWVwQ2xvbmUocmVjZWl2ZWQsIHsgZm9yY2VXcml0YWJsZTogdHJ1ZSB9KTtcblx0Y29uc3QgeyByZXBsYWNlZEV4cGVjdGVkLCByZXBsYWNlZEFjdHVhbCB9ID0gcmVwbGFjZUFzeW1tZXRyaWNNYXRjaGVyKGNsb25lZFJlY2VpdmVkLCBjbG9uZWRFeHBlY3RlZCk7XG5cdGNvbnN0IGRpZmZlcmVuY2UgPSBkaWZmKHJlcGxhY2VkRXhwZWN0ZWQsIHJlcGxhY2VkQWN0dWFsLCBvcHRpb25zKTtcblx0cmV0dXJuIGRpZmZlcmVuY2U7XG5cdC8vIH1cblx0Ly8gY29uc3QgcHJpbnRMYWJlbCA9IGdldExhYmVsUHJpbnRlcihhQW5ub3RhdGlvbiwgYkFubm90YXRpb24pXG5cdC8vIGNvbnN0IGV4cGVjdGVkTGluZSA9IHByaW50TGFiZWwoYUFubm90YXRpb24pICsgcHJpbnRFeHBlY3RlZChleHBlY3RlZClcblx0Ly8gY29uc3QgcmVjZWl2ZWRMaW5lXG5cdC8vICAgPSBwcmludExhYmVsKGJBbm5vdGF0aW9uKVxuXHQvLyAgICsgKHN0cmluZ2lmeShleHBlY3RlZCkgPT09IHN0cmluZ2lmeShyZWNlaXZlZClcblx0Ly8gICAgID8gJ3NlcmlhbGl6ZXMgdG8gdGhlIHNhbWUgc3RyaW5nJ1xuXHQvLyAgICAgOiBwcmludFJlY2VpdmVkKHJlY2VpdmVkKSlcblx0Ly8gcmV0dXJuIGAke2V4cGVjdGVkTGluZX1cXG4ke3JlY2VpdmVkTGluZX1gXG59XG5mdW5jdGlvbiByZXBsYWNlQXN5bW1ldHJpY01hdGNoZXIoYWN0dWFsLCBleHBlY3RlZCwgYWN0dWFsUmVwbGFjZWQgPSBuZXcgV2Vha1NldCgpLCBleHBlY3RlZFJlcGxhY2VkID0gbmV3IFdlYWtTZXQoKSkge1xuXHQvLyBoYW5kbGUgYXN5bW1ldHJpYyBFcnJvci5jYXVzZSBkaWZmXG5cdGlmIChhY3R1YWwgaW5zdGFuY2VvZiBFcnJvciAmJiBleHBlY3RlZCBpbnN0YW5jZW9mIEVycm9yICYmIHR5cGVvZiBhY3R1YWwuY2F1c2UgIT09IFwidW5kZWZpbmVkXCIgJiYgdHlwZW9mIGV4cGVjdGVkLmNhdXNlID09PSBcInVuZGVmaW5lZFwiKSB7XG5cdFx0ZGVsZXRlIGFjdHVhbC5jYXVzZTtcblx0XHRyZXR1cm4ge1xuXHRcdFx0cmVwbGFjZWRBY3R1YWw6IGFjdHVhbCxcblx0XHRcdHJlcGxhY2VkRXhwZWN0ZWQ6IGV4cGVjdGVkXG5cdFx0fTtcblx0fVxuXHRpZiAoIWlzUmVwbGFjZWFibGUoYWN0dWFsLCBleHBlY3RlZCkpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0cmVwbGFjZWRBY3R1YWw6IGFjdHVhbCxcblx0XHRcdHJlcGxhY2VkRXhwZWN0ZWQ6IGV4cGVjdGVkXG5cdFx0fTtcblx0fVxuXHRpZiAoYWN0dWFsUmVwbGFjZWQuaGFzKGFjdHVhbCkgfHwgZXhwZWN0ZWRSZXBsYWNlZC5oYXMoZXhwZWN0ZWQpKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHJlcGxhY2VkQWN0dWFsOiBhY3R1YWwsXG5cdFx0XHRyZXBsYWNlZEV4cGVjdGVkOiBleHBlY3RlZFxuXHRcdH07XG5cdH1cblx0YWN0dWFsUmVwbGFjZWQuYWRkKGFjdHVhbCk7XG5cdGV4cGVjdGVkUmVwbGFjZWQuYWRkKGV4cGVjdGVkKTtcblx0Z2V0T3duUHJvcGVydGllcyhleHBlY3RlZCkuZm9yRWFjaCgoa2V5KSA9PiB7XG5cdFx0Y29uc3QgZXhwZWN0ZWRWYWx1ZSA9IGV4cGVjdGVkW2tleV07XG5cdFx0Y29uc3QgYWN0dWFsVmFsdWUgPSBhY3R1YWxba2V5XTtcblx0XHRpZiAoaXNBc3ltbWV0cmljTWF0Y2hlcihleHBlY3RlZFZhbHVlKSkge1xuXHRcdFx0aWYgKGV4cGVjdGVkVmFsdWUuYXN5bW1ldHJpY01hdGNoKGFjdHVhbFZhbHVlKSkge1xuXHRcdFx0XHQvLyBXaGVuIG1hdGNoZXIgbWF0Y2hlcywgcmVwbGFjZSBleHBlY3RlZCB3aXRoIGFjdHVhbCB2YWx1ZVxuXHRcdFx0XHQvLyBzbyB0aGV5IGFwcGVhciB0aGUgc2FtZSBpbiB0aGUgZGlmZlxuXHRcdFx0XHRleHBlY3RlZFtrZXldID0gYWN0dWFsVmFsdWU7XG5cdFx0XHR9IGVsc2UgaWYgKFwic2FtcGxlXCIgaW4gZXhwZWN0ZWRWYWx1ZSAmJiBleHBlY3RlZFZhbHVlLnNhbXBsZSAhPT0gdW5kZWZpbmVkICYmIGlzUmVwbGFjZWFibGUoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUuc2FtcGxlKSkge1xuXHRcdFx0XHQvLyBGb3IgY29udGFpbmVyIG1hdGNoZXJzIChBcnJheUNvbnRhaW5pbmcsIE9iamVjdENvbnRhaW5pbmcpLCB1bndyYXAgYW5kIHJlY3Vyc2l2ZWx5IHByb2Nlc3Ncblx0XHRcdFx0Ly8gTWF0Y2hlciBkb2Vzbid0IG1hdGNoOiB1bndyYXAgYnV0IGtlZXAgc3RydWN0dXJlIHRvIHNob3cgbWlzbWF0Y2hcblx0XHRcdFx0Y29uc3QgcmVwbGFjZWQgPSByZXBsYWNlQXN5bW1ldHJpY01hdGNoZXIoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUuc2FtcGxlLCBhY3R1YWxSZXBsYWNlZCwgZXhwZWN0ZWRSZXBsYWNlZCk7XG5cdFx0XHRcdGFjdHVhbFtrZXldID0gcmVwbGFjZWQucmVwbGFjZWRBY3R1YWw7XG5cdFx0XHRcdGV4cGVjdGVkW2tleV0gPSByZXBsYWNlZC5yZXBsYWNlZEV4cGVjdGVkO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSBpZiAoaXNBc3ltbWV0cmljTWF0Y2hlcihhY3R1YWxWYWx1ZSkpIHtcblx0XHRcdGlmIChhY3R1YWxWYWx1ZS5hc3ltbWV0cmljTWF0Y2goZXhwZWN0ZWRWYWx1ZSkpIHtcblx0XHRcdFx0YWN0dWFsW2tleV0gPSBleHBlY3RlZFZhbHVlO1xuXHRcdFx0fSBlbHNlIGlmIChcInNhbXBsZVwiIGluIGFjdHVhbFZhbHVlICYmIGFjdHVhbFZhbHVlLnNhbXBsZSAhPT0gdW5kZWZpbmVkICYmIGlzUmVwbGFjZWFibGUoYWN0dWFsVmFsdWUuc2FtcGxlLCBleHBlY3RlZFZhbHVlKSkge1xuXHRcdFx0XHRjb25zdCByZXBsYWNlZCA9IHJlcGxhY2VBc3ltbWV0cmljTWF0Y2hlcihhY3R1YWxWYWx1ZS5zYW1wbGUsIGV4cGVjdGVkVmFsdWUsIGFjdHVhbFJlcGxhY2VkLCBleHBlY3RlZFJlcGxhY2VkKTtcblx0XHRcdFx0YWN0dWFsW2tleV0gPSByZXBsYWNlZC5yZXBsYWNlZEFjdHVhbDtcblx0XHRcdFx0ZXhwZWN0ZWRba2V5XSA9IHJlcGxhY2VkLnJlcGxhY2VkRXhwZWN0ZWQ7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmIChpc1JlcGxhY2VhYmxlKGFjdHVhbFZhbHVlLCBleHBlY3RlZFZhbHVlKSkge1xuXHRcdFx0Y29uc3QgcmVwbGFjZWQgPSByZXBsYWNlQXN5bW1ldHJpY01hdGNoZXIoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUsIGFjdHVhbFJlcGxhY2VkLCBleHBlY3RlZFJlcGxhY2VkKTtcblx0XHRcdGFjdHVhbFtrZXldID0gcmVwbGFjZWQucmVwbGFjZWRBY3R1YWw7XG5cdFx0XHRleHBlY3RlZFtrZXldID0gcmVwbGFjZWQucmVwbGFjZWRFeHBlY3RlZDtcblx0XHR9XG5cdH0pO1xuXHRyZXR1cm4ge1xuXHRcdHJlcGxhY2VkQWN0dWFsOiBhY3R1YWwsXG5cdFx0cmVwbGFjZWRFeHBlY3RlZDogZXhwZWN0ZWRcblx0fTtcbn1cbmZ1bmN0aW9uIGdldExhYmVsUHJpbnRlciguLi5zdHJpbmdzKSB7XG5cdGNvbnN0IG1heExlbmd0aCA9IHN0cmluZ3MucmVkdWNlKChtYXgsIHN0cmluZykgPT4gc3RyaW5nLmxlbmd0aCA+IG1heCA/IHN0cmluZy5sZW5ndGggOiBtYXgsIDApO1xuXHRyZXR1cm4gKHN0cmluZykgPT4gYCR7c3RyaW5nfTogJHtcIiBcIi5yZXBlYXQobWF4TGVuZ3RoIC0gc3RyaW5nLmxlbmd0aCl9YDtcbn1cbmNvbnN0IFNQQUNFX1NZTUJPTCA9IFwiwrdcIjtcbmZ1bmN0aW9uIHJlcGxhY2VUcmFpbGluZ1NwYWNlcyh0ZXh0KSB7XG5cdHJldHVybiB0ZXh0LnJlcGxhY2UoL1xccyskL2dtLCAoc3BhY2VzKSA9PiBTUEFDRV9TWU1CT0wucmVwZWF0KHNwYWNlcy5sZW5ndGgpKTtcbn1cbmZ1bmN0aW9uIHByaW50UmVjZWl2ZWQob2JqZWN0KSB7XG5cdHJldHVybiBjLnJlZChyZXBsYWNlVHJhaWxpbmdTcGFjZXMoc3RyaW5naWZ5KG9iamVjdCkpKTtcbn1cbmZ1bmN0aW9uIHByaW50RXhwZWN0ZWQodmFsdWUpIHtcblx0cmV0dXJuIGMuZ3JlZW4ocmVwbGFjZVRyYWlsaW5nU3BhY2VzKHN0cmluZ2lmeSh2YWx1ZSkpKTtcbn1cbmZ1bmN0aW9uIGdldENvbW1vbkFuZENoYW5nZWRTdWJzdHJpbmdzKGRpZmZzLCBvcCwgaGFzQ29tbW9uRGlmZikge1xuXHRyZXR1cm4gZGlmZnMucmVkdWNlKChyZWR1Y2VkLCBkaWZmKSA9PiByZWR1Y2VkICsgKGRpZmZbMF0gPT09IERJRkZfRVFVQUwgPyBkaWZmWzFdIDogZGlmZlswXSA9PT0gb3AgPyBoYXNDb21tb25EaWZmID8gYy5pbnZlcnNlKGRpZmZbMV0pIDogZGlmZlsxXSA6IFwiXCIpLCBcIlwiKTtcbn1cblxuZXhwb3J0IHsgRElGRl9ERUxFVEUsIERJRkZfRVFVQUwsIERJRkZfSU5TRVJULCBEaWZmLCBkaWZmLCBkaWZmTGluZXNSYXcsIGRpZmZMaW5lc1VuaWZpZWQsIGRpZmZMaW5lc1VuaWZpZWQyLCBkaWZmU3RyaW5nc1JhdywgZGlmZlN0cmluZ3NVbmlmaWVkLCBnZXRMYWJlbFByaW50ZXIsIHByaW50RGlmZk9yU3RyaW5naWZ5LCBy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
|