@cartanova/qgrid-cli 0.1.1 → 1.0.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.
Files changed (91) hide show
  1. package/bundle/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorate.js +9 -0
  2. package/bundle/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorateMetadata.js +6 -0
  3. package/bundle/dist/_virtual/_rolldown/runtime.js +15 -0
  4. package/bundle/dist/application/qgrid/oauth.js +140 -0
  5. package/bundle/dist/application/qgrid/pool.js +100 -0
  6. package/bundle/dist/application/qgrid/qgrid.frame.js +280 -0
  7. package/bundle/dist/application/qgrid/qgrid.types.js +79 -0
  8. package/bundle/dist/application/qgrid/worker.js +183 -0
  9. package/bundle/dist/application/queries.generated.js +31 -0
  10. package/bundle/dist/application/request-log/request-log.model.js +113 -0
  11. package/bundle/dist/application/request-log/request-log.types.js +13 -0
  12. package/bundle/dist/application/sonamu.generated.js +99 -0
  13. package/bundle/dist/application/sonamu.generated.sso.js +34 -0
  14. package/bundle/dist/application/token/token.model.js +157 -0
  15. package/bundle/dist/application/token/token.types.js +22 -0
  16. package/bundle/dist/i18n/en.js +63 -0
  17. package/bundle/dist/i18n/ko.js +62 -0
  18. package/bundle/dist/i18n/sd.generated.js +272 -0
  19. package/bundle/dist/index.js +11 -0
  20. package/bundle/dist/migrations/20260410171405_create__request_logs.js +26 -0
  21. package/bundle/dist/migrations/20260410171406_create__tokens.js +24 -0
  22. package/bundle/dist/migrations/20260411120624_alter_tokens_alter2.js +16 -0
  23. package/bundle/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +155 -0
  24. package/bundle/dist/node_modules/.pnpm/@vitest_expect@4.1.2/node_modules/@vitest/expect/dist/index.js +1484 -0
  25. package/bundle/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.2/node_modules/@vitest/pretty-format/dist/index.js +887 -0
  26. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/chunk-artifact.js +2746 -0
  27. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/index.js +8 -0
  28. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/utils.js +8 -0
  29. package/bundle/dist/node_modules/.pnpm/@vitest_snapshot@4.1.2/node_modules/@vitest/snapshot/dist/index.js +662 -0
  30. package/bundle/dist/node_modules/.pnpm/@vitest_spy@4.1.2/node_modules/@vitest/spy/dist/index.js +386 -0
  31. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +82 -0
  32. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/constants.js +48 -0
  33. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/diff.js +1307 -0
  34. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/display.js +558 -0
  35. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/error.js +33 -0
  36. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/helpers.js +226 -0
  37. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/offset.js +27 -0
  38. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/serialize.js +77 -0
  39. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/source-map.js +374 -0
  40. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/timers.js +37 -0
  41. package/bundle/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +2886 -0
  42. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +10 -0
  43. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +109 -0
  44. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +10 -0
  45. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +10 -0
  46. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +10 -0
  47. package/bundle/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +1127 -0
  48. package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +21 -0
  49. package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +432 -0
  50. package/bundle/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +506 -0
  51. package/bundle/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +86 -0
  52. package/bundle/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 +426 -0
  53. package/bundle/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 +6 -0
  54. package/bundle/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 +41 -0
  55. package/bundle/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 +19 -0
  56. package/bundle/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 +202 -0
  57. package/bundle/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 +16 -0
  58. package/bundle/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 +59 -0
  59. package/bundle/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 +2910 -0
  60. package/bundle/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 +44 -0
  61. package/bundle/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 +28 -0
  62. package/bundle/dist/sonamu.config.js +196 -0
  63. package/bundle/dist/testing/fixture.js +8 -0
  64. package/bundle/dist/testing/global.js +9 -0
  65. package/bundle/dist/testing/setup-mocks.js +17 -0
  66. package/bundle/dist/utils/subset-loaders.js +12 -0
  67. package/bundle/src/application/request-log/request-log.entity.json +75 -0
  68. package/bundle/src/application/token/token.entity.json +37 -0
  69. package/bundle/src/migrations/20260410171405_create__request_logs.ts +23 -0
  70. package/bundle/src/migrations/20260410171406_create__tokens.ts +21 -0
  71. package/bundle/src/migrations/20260411120624_alter_tokens_alter2.ts +15 -0
  72. package/bundle/web-dist/client/assets/index-DlPchHBY.js +116 -0
  73. package/bundle/web-dist/client/assets/index-vZsvyuFn.css +1 -0
  74. package/bundle/web-dist/client/assets/rolldown-runtime-Dw2cE7zH.js +1 -0
  75. package/bundle/web-dist/client/assets/routes-CagDz23B.js +1 -0
  76. package/bundle/web-dist/client/assets/sd.generated-BrQoQXvv.js +47 -0
  77. package/bundle/web-dist/client/assets/services.generated-BspO2L0j.js +1 -0
  78. package/bundle/web-dist/client/assets/show-aXUGa0gm.js +29 -0
  79. package/bundle/web-dist/client/assets/tokens-DRkXtZ3Q.js +1 -0
  80. package/bundle/web-dist/client/assets/vendor-react-DH4kUfK2.js +9 -0
  81. package/bundle/web-dist/client/assets/vendor-tanstack-CUxlo6YN.js +1 -0
  82. package/bundle/web-dist/client/index.html +18 -0
  83. package/bundle/web-dist/server/assets/react-dom-CGIzOSuj.js +335 -0
  84. package/bundle/web-dist/server/assets/routes-ClzReRep.js +490 -0
  85. package/bundle/web-dist/server/assets/sd.generated-BnonqqKr.js +21694 -0
  86. package/bundle/web-dist/server/assets/services.generated-D5ABD5fr.js +836 -0
  87. package/bundle/web-dist/server/assets/show-C9pcdSxc.js +23364 -0
  88. package/bundle/web-dist/server/assets/tokens-JH6FsnWZ.js +860 -0
  89. package/bundle/web-dist/server/entry-server.generated.js +44646 -0
  90. package/dist/cli.js +38 -89
  91. package/package.json +40 -12
@@ -0,0 +1,1484 @@
1
+ import { y } from "../../../../../tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js";
2
+ import { stringify } from "../../../../../@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/display.js";
3
+ import { assertTypes, getType, isObject, noop, ordinal } from "../../../../../@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/helpers.js";
4
+ import { diff, printDiffOrStringify } from "../../../../../@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/diff.js";
5
+ import { processError } from "../../../../../@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/error.js";
6
+ import { isMockFunction } from "../../../../../@vitest_spy@4.1.2/node_modules/@vitest/spy/dist/index.js";
7
+ import { use, utils_exports } from "../../../../../chai@6.2.2/node_modules/chai/index.js";
8
+ //#region ../../node_modules/.pnpm/@vitest+expect@4.1.2/node_modules/@vitest/expect/dist/index.js
9
+ const ChaiStyleAssertions = (chai, utils) => {
10
+ function defProperty(name, delegateTo) {
11
+ utils.addProperty(chai.Assertion.prototype, name, function() {
12
+ const jestMethod = chai.Assertion.prototype[delegateTo];
13
+ if (!jestMethod) throw new Error(`Cannot delegate to ${String(delegateTo)}: method not found. Ensure JestChaiExpect plugin is loaded first.`);
14
+ return jestMethod.call(this);
15
+ });
16
+ }
17
+ function defPropertyWithArgs(name, delegateTo, ...args) {
18
+ utils.addProperty(chai.Assertion.prototype, name, function() {
19
+ const jestMethod = chai.Assertion.prototype[delegateTo];
20
+ if (!jestMethod) throw new Error(`Cannot delegate to ${String(delegateTo)}: method not found. Ensure JestChaiExpect plugin is loaded first.`);
21
+ return jestMethod.call(this, ...args);
22
+ });
23
+ }
24
+ function defMethod(name, delegateTo) {
25
+ utils.addMethod(chai.Assertion.prototype, name, function(...args) {
26
+ const jestMethod = chai.Assertion.prototype[delegateTo];
27
+ if (!jestMethod) throw new Error(`Cannot delegate to ${String(delegateTo)}: method not found. Ensure JestChaiExpect plugin is loaded first.`);
28
+ return jestMethod.call(this, ...args);
29
+ });
30
+ }
31
+ defProperty("called", "toHaveBeenCalled");
32
+ defProperty("calledOnce", "toHaveBeenCalledOnce");
33
+ defPropertyWithArgs("calledTwice", "toHaveBeenCalledTimes", 2);
34
+ defPropertyWithArgs("calledThrice", "toHaveBeenCalledTimes", 3);
35
+ defMethod("callCount", "toHaveBeenCalledTimes");
36
+ defMethod("calledWith", "toHaveBeenCalledWith");
37
+ defMethod("calledOnceWith", "toHaveBeenCalledExactlyOnceWith");
38
+ defMethod("lastCalledWith", "toHaveBeenLastCalledWith");
39
+ defMethod("nthCalledWith", "toHaveBeenNthCalledWith");
40
+ defMethod("returned", "toHaveReturned");
41
+ defMethod("returnedWith", "toHaveReturnedWith");
42
+ defMethod("returnedTimes", "toHaveReturnedTimes");
43
+ defMethod("lastReturnedWith", "toHaveLastReturnedWith");
44
+ defMethod("nthReturnedWith", "toHaveNthReturnedWith");
45
+ defMethod("calledBefore", "toHaveBeenCalledBefore");
46
+ defMethod("calledAfter", "toHaveBeenCalledAfter");
47
+ };
48
+ const MATCHERS_OBJECT = Symbol.for("matchers-object");
49
+ const JEST_MATCHERS_OBJECT = Symbol.for("$$jest-matchers-object");
50
+ const GLOBAL_EXPECT = Symbol.for("expect-global");
51
+ const ASYMMETRIC_MATCHERS_OBJECT = Symbol.for("asymmetric-matchers-object");
52
+ const customMatchers = {
53
+ toSatisfy(actual, expected, message) {
54
+ const { printReceived, printExpected, matcherHint } = this.utils;
55
+ const pass = expected(actual);
56
+ return {
57
+ pass,
58
+ message: () => pass ? `\
59
+ ${matcherHint(".not.toSatisfy", "received", "")}
60
+
61
+ Expected value to not satisfy:
62
+ ${message || printExpected(expected)}
63
+ Received:
64
+ ${printReceived(actual)}` : `\
65
+ ${matcherHint(".toSatisfy", "received", "")}
66
+
67
+ Expected value to satisfy:
68
+ ${message || printExpected(expected)}
69
+
70
+ Received:
71
+ ${printReceived(actual)}`
72
+ };
73
+ },
74
+ toBeOneOf(actual, expected) {
75
+ const { equals, customTesters } = this;
76
+ const { printReceived, printExpected, matcherHint } = this.utils;
77
+ let pass;
78
+ if (Array.isArray(expected)) pass = expected.length === 0 || expected.some((item) => equals(item, actual, customTesters));
79
+ else if (expected instanceof Set) pass = expected.size === 0 || expected.has(actual) || [...expected].some((item) => equals(item, actual, customTesters));
80
+ else throw new TypeError(`You must provide an array or set to ${matcherHint(".toBeOneOf")}, not '${typeof expected}'.`);
81
+ return {
82
+ pass,
83
+ message: () => pass ? `\
84
+ ${matcherHint(".not.toBeOneOf", "received", "")}
85
+
86
+ Expected value to not be one of:
87
+ ${printExpected(expected)}
88
+ Received:
89
+ ${printReceived(actual)}` : `\
90
+ ${matcherHint(".toBeOneOf", "received", "")}
91
+
92
+ Expected value to be one of:
93
+ ${printExpected(expected)}
94
+
95
+ Received:
96
+ ${printReceived(actual)}`
97
+ };
98
+ }
99
+ };
100
+ const EXPECTED_COLOR = y.green;
101
+ const RECEIVED_COLOR = y.red;
102
+ const INVERTED_COLOR = y.inverse;
103
+ const BOLD_WEIGHT = y.bold;
104
+ const DIM_COLOR = y.dim;
105
+ function matcherHint(matcherName, received = "received", expected = "expected", options = {}) {
106
+ const { comment = "", isDirectExpectCall = false, isNot = false, promise = "", secondArgument = "", expectedColor = EXPECTED_COLOR, receivedColor = RECEIVED_COLOR, secondArgumentColor = EXPECTED_COLOR } = options;
107
+ let hint = "";
108
+ let dimString = "expect";
109
+ if (!isDirectExpectCall && received !== "") {
110
+ hint += DIM_COLOR(`${dimString}(`) + receivedColor(received);
111
+ dimString = ")";
112
+ }
113
+ if (promise !== "") {
114
+ hint += DIM_COLOR(`${dimString}.`) + promise;
115
+ dimString = "";
116
+ }
117
+ if (isNot) {
118
+ hint += `${DIM_COLOR(`${dimString}.`)}not`;
119
+ dimString = "";
120
+ }
121
+ if (matcherName.includes(".")) dimString += matcherName;
122
+ else {
123
+ hint += DIM_COLOR(`${dimString}.`) + matcherName;
124
+ dimString = "";
125
+ }
126
+ if (expected === "") dimString += "()";
127
+ else {
128
+ hint += DIM_COLOR(`${dimString}(`) + expectedColor(expected);
129
+ if (secondArgument) hint += DIM_COLOR(", ") + secondArgumentColor(secondArgument);
130
+ dimString = ")";
131
+ }
132
+ if (comment !== "") dimString += ` // ${comment}`;
133
+ if (dimString !== "") hint += DIM_COLOR(dimString);
134
+ return hint;
135
+ }
136
+ const SPACE_SYMBOL = "·";
137
+ function replaceTrailingSpaces(text) {
138
+ return text.replace(/\s+$/gm, (spaces) => SPACE_SYMBOL.repeat(spaces.length));
139
+ }
140
+ function printReceived(object) {
141
+ return RECEIVED_COLOR(replaceTrailingSpaces(stringify(object)));
142
+ }
143
+ function printExpected(value) {
144
+ return EXPECTED_COLOR(replaceTrailingSpaces(stringify(value)));
145
+ }
146
+ function getMatcherUtils() {
147
+ return {
148
+ EXPECTED_COLOR,
149
+ RECEIVED_COLOR,
150
+ INVERTED_COLOR,
151
+ BOLD_WEIGHT,
152
+ DIM_COLOR,
153
+ diff,
154
+ matcherHint,
155
+ printReceived,
156
+ printExpected,
157
+ printDiffOrStringify,
158
+ printWithType
159
+ };
160
+ }
161
+ function printWithType(name, value, print) {
162
+ const type = getType(value);
163
+ return (type !== "null" && type !== "undefined" ? `${name} has type: ${type}\n` : "") + `${name} has value: ${print(value)}`;
164
+ }
165
+ function addCustomEqualityTesters(newTesters) {
166
+ if (!Array.isArray(newTesters)) throw new TypeError(`expect.customEqualityTesters: Must be set to an array of Testers. Was given "${getType(newTesters)}"`);
167
+ globalThis[JEST_MATCHERS_OBJECT].customEqualityTesters.push(...newTesters);
168
+ }
169
+ function getCustomEqualityTesters() {
170
+ return globalThis[JEST_MATCHERS_OBJECT].customEqualityTesters;
171
+ }
172
+ function equals(a, b, customTesters, strictCheck) {
173
+ customTesters = customTesters || [];
174
+ return eq(a, b, [], [], customTesters, strictCheck ? hasKey : hasDefinedKey);
175
+ }
176
+ Function.prototype.toString;
177
+ function isAsymmetric(obj) {
178
+ return !!obj && typeof obj === "object" && "asymmetricMatch" in obj && isA("Function", obj.asymmetricMatch);
179
+ }
180
+ function hasAsymmetric(obj, seen = /* @__PURE__ */ new Set()) {
181
+ if (seen.has(obj)) return false;
182
+ seen.add(obj);
183
+ if (isAsymmetric(obj)) return true;
184
+ if (Array.isArray(obj)) return obj.some((i) => hasAsymmetric(i, seen));
185
+ if (obj instanceof Set) return Array.from(obj).some((i) => hasAsymmetric(i, seen));
186
+ if (isObject(obj)) return Object.values(obj).some((v) => hasAsymmetric(v, seen));
187
+ return false;
188
+ }
189
+ function asymmetricMatch(a, b, customTesters) {
190
+ const asymmetricA = isAsymmetric(a);
191
+ const asymmetricB = isAsymmetric(b);
192
+ if (asymmetricA && asymmetricB) return;
193
+ if (asymmetricA) return a.asymmetricMatch(b, customTesters);
194
+ if (asymmetricB) return b.asymmetricMatch(a, customTesters);
195
+ }
196
+ function isError(value) {
197
+ if (typeof Error.isError === "function") return Error.isError(value);
198
+ switch (Object.prototype.toString.call(value)) {
199
+ case "[object Error]":
200
+ case "[object Exception]":
201
+ case "[object DOMException]": return true;
202
+ default: return value instanceof Error;
203
+ }
204
+ }
205
+ function eq(a, b, aStack, bStack, customTesters, hasKey) {
206
+ let result = true;
207
+ const asymmetricResult = asymmetricMatch(a, b, customTesters);
208
+ if (asymmetricResult !== void 0) return asymmetricResult;
209
+ const testerContext = { equals };
210
+ for (let i = 0; i < customTesters.length; i++) {
211
+ const customTesterResult = customTesters[i].call(testerContext, a, b, customTesters);
212
+ if (customTesterResult !== void 0) return customTesterResult;
213
+ }
214
+ if (typeof URL === "function" && a instanceof URL && b instanceof URL) return a.href === b.href;
215
+ if (Object.is(a, b)) return true;
216
+ if (a === null || b === null) return a === b;
217
+ const className = Object.prototype.toString.call(a);
218
+ if (className !== Object.prototype.toString.call(b)) return false;
219
+ switch (className) {
220
+ case "[object Boolean]":
221
+ case "[object String]":
222
+ case "[object Number]": if (typeof a !== typeof b) return false;
223
+ else if (typeof a !== "object" && typeof b !== "object") return Object.is(a, b);
224
+ else return Object.is(a.valueOf(), b.valueOf());
225
+ case "[object Date]": {
226
+ const numA = +a;
227
+ const numB = +b;
228
+ return numA === numB || Number.isNaN(numA) && Number.isNaN(numB);
229
+ }
230
+ case "[object RegExp]": return a.source === b.source && a.flags === b.flags;
231
+ case "[object Temporal.Instant]":
232
+ case "[object Temporal.ZonedDateTime]":
233
+ case "[object Temporal.PlainDateTime]":
234
+ case "[object Temporal.PlainDate]":
235
+ case "[object Temporal.PlainTime]":
236
+ case "[object Temporal.PlainYearMonth]":
237
+ case "[object Temporal.PlainMonthDay]": return a.equals(b);
238
+ case "[object Temporal.Duration]": return a.toString() === b.toString();
239
+ }
240
+ if (typeof a !== "object" || typeof b !== "object") return false;
241
+ if (isDomNode(a) && isDomNode(b)) return a.isEqualNode(b);
242
+ let length = aStack.length;
243
+ while (length--) if (aStack[length] === a) return bStack[length] === b;
244
+ else if (bStack[length] === b) return false;
245
+ aStack.push(a);
246
+ bStack.push(b);
247
+ if (className === "[object Array]" && a.length !== b.length) return false;
248
+ if (isError(a) && isError(b)) try {
249
+ return isErrorEqual(a, b, aStack, bStack, customTesters, hasKey);
250
+ } finally {
251
+ aStack.pop();
252
+ bStack.pop();
253
+ }
254
+ const aKeys = keys(a, hasKey);
255
+ let key;
256
+ let size = aKeys.length;
257
+ if (keys(b, hasKey).length !== size) return false;
258
+ while (size--) {
259
+ key = aKeys[size];
260
+ result = hasKey(b, key) && eq(a[key], b[key], aStack, bStack, customTesters, hasKey);
261
+ if (!result) return false;
262
+ }
263
+ aStack.pop();
264
+ bStack.pop();
265
+ return result;
266
+ }
267
+ function isErrorEqual(a, b, aStack, bStack, customTesters, hasKey) {
268
+ let result = Object.prototype.toString.call(a) === Object.prototype.toString.call(b) && a.name === b.name && a.message === b.message;
269
+ if (typeof b.cause !== "undefined") result &&= eq(a.cause, b.cause, aStack, bStack, customTesters, hasKey);
270
+ if (a instanceof AggregateError && b instanceof AggregateError) result &&= eq(a.errors, b.errors, aStack, bStack, customTesters, hasKey);
271
+ result &&= eq({ ...a }, { ...b }, aStack, bStack, customTesters, hasKey);
272
+ return result;
273
+ }
274
+ function keys(obj, hasKey) {
275
+ const keys = [];
276
+ for (const key in obj) if (hasKey(obj, key)) keys.push(key);
277
+ return keys.concat(Object.getOwnPropertySymbols(obj).filter((symbol) => Object.getOwnPropertyDescriptor(obj, symbol).enumerable));
278
+ }
279
+ function hasDefinedKey(obj, key) {
280
+ return hasKey(obj, key) && obj[key] !== void 0;
281
+ }
282
+ function hasKey(obj, key) {
283
+ return Object.hasOwn(obj, key);
284
+ }
285
+ function isA(typeName, value) {
286
+ return Object.prototype.toString.apply(value) === `[object ${typeName}]`;
287
+ }
288
+ function isDomNode(obj) {
289
+ return obj !== null && typeof obj === "object" && "nodeType" in obj && typeof obj.nodeType === "number" && "nodeName" in obj && typeof obj.nodeName === "string" && "isEqualNode" in obj && typeof obj.isEqualNode === "function";
290
+ }
291
+ function getPrototype(obj) {
292
+ if (Object.getPrototypeOf) return Object.getPrototypeOf(obj);
293
+ if (obj.constructor.prototype === obj) return null;
294
+ return obj.constructor.prototype;
295
+ }
296
+ function hasProperty(obj, property) {
297
+ if (!obj) return false;
298
+ if (Object.hasOwn(obj, property)) return true;
299
+ return hasProperty(getPrototype(obj), property);
300
+ }
301
+ const IS_KEYED_SENTINEL = "@@__IMMUTABLE_KEYED__@@";
302
+ const IS_SET_SENTINEL = "@@__IMMUTABLE_SET__@@";
303
+ const IS_LIST_SENTINEL = "@@__IMMUTABLE_LIST__@@";
304
+ const IS_ORDERED_SENTINEL = "@@__IMMUTABLE_ORDERED__@@";
305
+ const IS_RECORD_SYMBOL = "@@__IMMUTABLE_RECORD__@@";
306
+ function isImmutableUnorderedKeyed(maybeKeyed) {
307
+ return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL] && !maybeKeyed[IS_ORDERED_SENTINEL]);
308
+ }
309
+ function isImmutableUnorderedSet(maybeSet) {
310
+ return !!(maybeSet && maybeSet[IS_SET_SENTINEL] && !maybeSet[IS_ORDERED_SENTINEL]);
311
+ }
312
+ function isObjectLiteral(source) {
313
+ return source != null && typeof source === "object" && !Array.isArray(source);
314
+ }
315
+ function isImmutableList(source) {
316
+ return Boolean(source && isObjectLiteral(source) && source[IS_LIST_SENTINEL]);
317
+ }
318
+ function isImmutableOrderedKeyed(source) {
319
+ return Boolean(source && isObjectLiteral(source) && source[IS_KEYED_SENTINEL] && source[IS_ORDERED_SENTINEL]);
320
+ }
321
+ function isImmutableOrderedSet(source) {
322
+ return Boolean(source && isObjectLiteral(source) && source[IS_SET_SENTINEL] && source[IS_ORDERED_SENTINEL]);
323
+ }
324
+ function isImmutableRecord(source) {
325
+ return Boolean(source && isObjectLiteral(source) && source[IS_RECORD_SYMBOL]);
326
+ }
327
+ /**
328
+ * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
329
+ *
330
+ * This source code is licensed under the MIT license found in the
331
+ * LICENSE file in the root directory of this source tree.
332
+ *
333
+ */
334
+ const IteratorSymbol = Symbol.iterator;
335
+ function hasIterator(object) {
336
+ return !!(object != null && object[IteratorSymbol]);
337
+ }
338
+ function iterableEquality(a, b, customTesters = [], aStack = [], bStack = []) {
339
+ if (typeof a !== "object" || typeof b !== "object" || Array.isArray(a) || Array.isArray(b) || !hasIterator(a) || !hasIterator(b)) return;
340
+ if (a.constructor !== b.constructor) return false;
341
+ let length = aStack.length;
342
+ while (length--) if (aStack[length] === a) return bStack[length] === b;
343
+ aStack.push(a);
344
+ bStack.push(b);
345
+ const filteredCustomTesters = [...customTesters.filter((t) => t !== iterableEquality), iterableEqualityWithStack];
346
+ function iterableEqualityWithStack(a, b) {
347
+ return iterableEquality(a, b, [...customTesters], [...aStack], [...bStack]);
348
+ }
349
+ if (a.size !== void 0) {
350
+ if (a.size !== b.size) return false;
351
+ else if (isA("Set", a) || isImmutableUnorderedSet(a)) {
352
+ let allFound = true;
353
+ for (const aValue of a) if (!b.has(aValue)) {
354
+ let has = false;
355
+ for (const bValue of b) if (equals(aValue, bValue, filteredCustomTesters) === true) has = true;
356
+ if (has === false) {
357
+ allFound = false;
358
+ break;
359
+ }
360
+ }
361
+ aStack.pop();
362
+ bStack.pop();
363
+ return allFound;
364
+ } else if (isA("Map", a) || isImmutableUnorderedKeyed(a)) {
365
+ let allFound = true;
366
+ for (const aEntry of a) if (!b.has(aEntry[0]) || !equals(aEntry[1], b.get(aEntry[0]), filteredCustomTesters)) {
367
+ let has = false;
368
+ for (const bEntry of b) {
369
+ const matchedKey = equals(aEntry[0], bEntry[0], filteredCustomTesters);
370
+ let matchedValue = false;
371
+ if (matchedKey === true) matchedValue = equals(aEntry[1], bEntry[1], filteredCustomTesters);
372
+ if (matchedValue === true) has = true;
373
+ }
374
+ if (has === false) {
375
+ allFound = false;
376
+ break;
377
+ }
378
+ }
379
+ aStack.pop();
380
+ bStack.pop();
381
+ return allFound;
382
+ }
383
+ }
384
+ const bIterator = b[IteratorSymbol]();
385
+ for (const aValue of a) {
386
+ const nextB = bIterator.next();
387
+ if (nextB.done || !equals(aValue, nextB.value, filteredCustomTesters)) return false;
388
+ }
389
+ if (!bIterator.next().done) return false;
390
+ if (!isImmutableList(a) && !isImmutableOrderedKeyed(a) && !isImmutableOrderedSet(a) && !isImmutableRecord(a)) {
391
+ if (!equals(Object.entries(a), Object.entries(b), filteredCustomTesters)) return false;
392
+ }
393
+ aStack.pop();
394
+ bStack.pop();
395
+ return true;
396
+ }
397
+ /**
398
+ * Checks if `hasOwnProperty(object, key)` up the prototype chain, stopping at `Object.prototype`.
399
+ */
400
+ function hasPropertyInObject(object, key) {
401
+ if (!object || typeof object !== "object" || object === Object.prototype) return false;
402
+ return Object.hasOwn(object, key) || hasPropertyInObject(Object.getPrototypeOf(object), key);
403
+ }
404
+ function isObjectWithKeys(a) {
405
+ return isObject(a) && !isError(a) && !Array.isArray(a) && !(a instanceof Date) && !(a instanceof Set) && !(a instanceof Map);
406
+ }
407
+ function subsetEquality(object, subset, customTesters = []) {
408
+ const filteredCustomTesters = customTesters.filter((t) => t !== subsetEquality);
409
+ const subsetEqualityWithContext = (seenReferences = /* @__PURE__ */ new WeakMap()) => (object, subset) => {
410
+ if (!isObjectWithKeys(subset)) return;
411
+ return Object.keys(subset).every((key) => {
412
+ if (subset[key] != null && typeof subset[key] === "object") {
413
+ if (seenReferences.has(subset[key])) return equals(object[key], subset[key], filteredCustomTesters);
414
+ seenReferences.set(subset[key], true);
415
+ }
416
+ const result = object != null && hasPropertyInObject(object, key) && equals(object[key], subset[key], [...filteredCustomTesters, subsetEqualityWithContext(seenReferences)]);
417
+ seenReferences.delete(subset[key]);
418
+ return result;
419
+ });
420
+ };
421
+ return subsetEqualityWithContext()(object, subset);
422
+ }
423
+ function typeEquality(a, b) {
424
+ if (a == null || b == null || a.constructor === b.constructor) return;
425
+ return false;
426
+ }
427
+ function arrayBufferEquality(a, b) {
428
+ let dataViewA = a;
429
+ let dataViewB = b;
430
+ if (!(a instanceof DataView && b instanceof DataView)) {
431
+ if (!(a instanceof ArrayBuffer) || !(b instanceof ArrayBuffer)) return;
432
+ try {
433
+ dataViewA = new DataView(a);
434
+ dataViewB = new DataView(b);
435
+ } catch {
436
+ return;
437
+ }
438
+ }
439
+ if (dataViewA.byteLength !== dataViewB.byteLength) return false;
440
+ for (let i = 0; i < dataViewA.byteLength; i++) if (dataViewA.getUint8(i) !== dataViewB.getUint8(i)) return false;
441
+ return true;
442
+ }
443
+ function sparseArrayEquality(a, b, customTesters = []) {
444
+ if (!Array.isArray(a) || !Array.isArray(b)) return;
445
+ const aKeys = Object.keys(a);
446
+ const bKeys = Object.keys(b);
447
+ return equals(a, b, customTesters.filter((t) => t !== sparseArrayEquality), true) && equals(aKeys, bKeys);
448
+ }
449
+ function generateToBeMessage(deepEqualityName, expected = "#{this}", actual = "#{exp}") {
450
+ const toBeMessage = `expected ${expected} to be ${actual} // Object.is equality`;
451
+ if (["toStrictEqual", "toEqual"].includes(deepEqualityName)) return `${toBeMessage}\n\nIf it should pass with deep equality, replace "toBe" with "${deepEqualityName}"\n\nExpected: ${expected}\nReceived: serializes to the same string\n`;
452
+ return toBeMessage;
453
+ }
454
+ function pluralize(word, count) {
455
+ return `${count} ${word}${count === 1 ? "" : "s"}`;
456
+ }
457
+ function getObjectKeys(object) {
458
+ return [...Object.keys(object), ...Object.getOwnPropertySymbols(object).filter((s) => Object.getOwnPropertyDescriptor(object, s)?.enumerable)];
459
+ }
460
+ function getObjectSubset(object, subset, customTesters) {
461
+ let stripped = 0;
462
+ const getObjectSubsetWithContext = (seenReferences = /* @__PURE__ */ new WeakMap()) => (object, subset) => {
463
+ if (Array.isArray(object)) {
464
+ if (Array.isArray(subset) && subset.length === object.length) return subset.map((sub, i) => getObjectSubsetWithContext(seenReferences)(object[i], sub));
465
+ } else if (object instanceof Date) return object;
466
+ else if (isObject(object) && isObject(subset)) {
467
+ if (equals(object, subset, [
468
+ ...customTesters,
469
+ iterableEquality,
470
+ subsetEquality
471
+ ])) return subset;
472
+ const trimmed = {};
473
+ seenReferences.set(object, trimmed);
474
+ if (typeof object.constructor === "function" && typeof object.constructor.name === "string") Object.defineProperty(trimmed, "constructor", {
475
+ enumerable: false,
476
+ value: object.constructor
477
+ });
478
+ for (const key of getObjectKeys(object)) if (hasPropertyInObject(subset, key)) trimmed[key] = seenReferences.has(object[key]) ? seenReferences.get(object[key]) : getObjectSubsetWithContext(seenReferences)(object[key], subset[key]);
479
+ else if (!seenReferences.has(object[key])) {
480
+ stripped += 1;
481
+ if (isObject(object[key])) stripped += getObjectKeys(object[key]).length;
482
+ getObjectSubsetWithContext(seenReferences)(object[key], subset[key]);
483
+ }
484
+ if (getObjectKeys(trimmed).length > 0) return trimmed;
485
+ }
486
+ return object;
487
+ };
488
+ return {
489
+ subset: getObjectSubsetWithContext()(object, subset),
490
+ stripped
491
+ };
492
+ }
493
+ /**
494
+ * Detects if an object is a Standard Schema V1 compatible schema
495
+ */
496
+ function isStandardSchema(obj) {
497
+ return !!obj && (typeof obj === "object" || typeof obj === "function") && obj["~standard"] && typeof obj["~standard"].validate === "function";
498
+ }
499
+ if (!Object.hasOwn(globalThis, MATCHERS_OBJECT)) {
500
+ const globalState = /* @__PURE__ */ new WeakMap();
501
+ const matchers = Object.create(null);
502
+ const customEqualityTesters = [];
503
+ const asymmetricMatchers = Object.create(null);
504
+ Object.defineProperty(globalThis, MATCHERS_OBJECT, { get: () => globalState });
505
+ Object.defineProperty(globalThis, JEST_MATCHERS_OBJECT, {
506
+ configurable: true,
507
+ get: () => ({
508
+ state: globalState.get(globalThis[GLOBAL_EXPECT]),
509
+ matchers,
510
+ customEqualityTesters
511
+ })
512
+ });
513
+ Object.defineProperty(globalThis, ASYMMETRIC_MATCHERS_OBJECT, { get: () => asymmetricMatchers });
514
+ }
515
+ function getState(expect) {
516
+ return globalThis[MATCHERS_OBJECT].get(expect);
517
+ }
518
+ function setState(state, expect) {
519
+ const map = globalThis[MATCHERS_OBJECT];
520
+ const current = map.get(expect) || {};
521
+ const results = Object.defineProperties(current, {
522
+ ...Object.getOwnPropertyDescriptors(current),
523
+ ...Object.getOwnPropertyDescriptors(state)
524
+ });
525
+ map.set(expect, results);
526
+ }
527
+ var AsymmetricMatcher = class {
528
+ $$typeof = Symbol.for("jest.asymmetricMatcher");
529
+ constructor(sample, inverse = false) {
530
+ this.sample = sample;
531
+ this.inverse = inverse;
532
+ }
533
+ getMatcherContext(expect) {
534
+ return {
535
+ ...getState(expect || globalThis[GLOBAL_EXPECT]),
536
+ equals,
537
+ isNot: this.inverse,
538
+ customTesters: getCustomEqualityTesters(),
539
+ utils: {
540
+ ...getMatcherUtils(),
541
+ diff,
542
+ stringify,
543
+ iterableEquality,
544
+ subsetEquality
545
+ }
546
+ };
547
+ }
548
+ };
549
+ AsymmetricMatcher.prototype[Symbol.for("chai/inspect")] = function(options) {
550
+ const result = stringify(this, options.depth, { min: true });
551
+ if (result.length <= options.truncate) return result;
552
+ return `${this.toString()}{…}`;
553
+ };
554
+ var StringContaining = class extends AsymmetricMatcher {
555
+ constructor(sample, inverse = false) {
556
+ if (!isA("String", sample)) throw new Error("Expected is not a string");
557
+ super(sample, inverse);
558
+ }
559
+ asymmetricMatch(other) {
560
+ const result = isA("String", other) && other.includes(this.sample);
561
+ return this.inverse ? !result : result;
562
+ }
563
+ toString() {
564
+ return `String${this.inverse ? "Not" : ""}Containing`;
565
+ }
566
+ getExpectedType() {
567
+ return "string";
568
+ }
569
+ };
570
+ var Anything = class extends AsymmetricMatcher {
571
+ asymmetricMatch(other) {
572
+ return other != null;
573
+ }
574
+ toString() {
575
+ return "Anything";
576
+ }
577
+ toAsymmetricMatcher() {
578
+ return "Anything";
579
+ }
580
+ };
581
+ var ObjectContaining = class extends AsymmetricMatcher {
582
+ constructor(sample, inverse = false) {
583
+ super(sample, inverse);
584
+ }
585
+ getPrototype(obj) {
586
+ if (Object.getPrototypeOf) return Object.getPrototypeOf(obj);
587
+ if (obj.constructor.prototype === obj) return null;
588
+ return obj.constructor.prototype;
589
+ }
590
+ hasProperty(obj, property) {
591
+ if (!obj) return false;
592
+ if (Object.hasOwn(obj, property)) return true;
593
+ return this.hasProperty(this.getPrototype(obj), property);
594
+ }
595
+ getProperties(obj) {
596
+ return [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj).filter((s) => Object.getOwnPropertyDescriptor(obj, s)?.enumerable)];
597
+ }
598
+ asymmetricMatch(other, customTesters) {
599
+ if (typeof this.sample !== "object") throw new TypeError(`You must provide an object to ${this.toString()}, not '${typeof this.sample}'.`);
600
+ let result = true;
601
+ const properties = this.getProperties(this.sample);
602
+ for (const property of properties) {
603
+ if (!this.hasProperty(other, property)) {
604
+ result = false;
605
+ break;
606
+ }
607
+ const value = this.sample[property];
608
+ const otherValue = other[property];
609
+ if (!equals(value, otherValue, customTesters)) {
610
+ result = false;
611
+ break;
612
+ }
613
+ }
614
+ return this.inverse ? !result : result;
615
+ }
616
+ toString() {
617
+ return `Object${this.inverse ? "Not" : ""}Containing`;
618
+ }
619
+ getExpectedType() {
620
+ return "object";
621
+ }
622
+ };
623
+ var ArrayContaining = class extends AsymmetricMatcher {
624
+ constructor(sample, inverse = false) {
625
+ super(sample, inverse);
626
+ }
627
+ asymmetricMatch(other, customTesters) {
628
+ if (!Array.isArray(this.sample)) throw new TypeError(`You must provide an array to ${this.toString()}, not '${typeof this.sample}'.`);
629
+ const result = this.sample.length === 0 || Array.isArray(other) && this.sample.every((item) => other.some((another) => equals(item, another, customTesters)));
630
+ return this.inverse ? !result : result;
631
+ }
632
+ toString() {
633
+ return `Array${this.inverse ? "Not" : ""}Containing`;
634
+ }
635
+ getExpectedType() {
636
+ return "array";
637
+ }
638
+ };
639
+ var Any = class extends AsymmetricMatcher {
640
+ constructor(sample) {
641
+ if (typeof sample === "undefined") throw new TypeError("any() expects to be passed a constructor function. Please pass one or use anything() to match any object.");
642
+ super(sample);
643
+ }
644
+ fnNameFor(func) {
645
+ if (func.name) return func.name;
646
+ const matches = Function.prototype.toString.call(func).match(/^(?:async)?\s*function\s*(?:\*\s*)?([\w$]+)\s*\(/);
647
+ return matches ? matches[1] : "<anonymous>";
648
+ }
649
+ asymmetricMatch(other) {
650
+ if (this.sample === String) return typeof other == "string" || other instanceof String;
651
+ if (this.sample === Number) return typeof other == "number" || other instanceof Number;
652
+ if (this.sample === Function) return typeof other == "function" || typeof other === "function";
653
+ if (this.sample === Boolean) return typeof other == "boolean" || other instanceof Boolean;
654
+ if (this.sample === BigInt) return typeof other == "bigint" || other instanceof BigInt;
655
+ if (this.sample === Symbol) return typeof other == "symbol" || other instanceof Symbol;
656
+ if (this.sample === Object) return typeof other == "object";
657
+ return other instanceof this.sample;
658
+ }
659
+ toString() {
660
+ return "Any";
661
+ }
662
+ getExpectedType() {
663
+ if (this.sample === String) return "string";
664
+ if (this.sample === Number) return "number";
665
+ if (this.sample === Function) return "function";
666
+ if (this.sample === Object) return "object";
667
+ if (this.sample === Boolean) return "boolean";
668
+ return this.fnNameFor(this.sample);
669
+ }
670
+ toAsymmetricMatcher() {
671
+ return `Any<${this.fnNameFor(this.sample)}>`;
672
+ }
673
+ };
674
+ var StringMatching = class extends AsymmetricMatcher {
675
+ constructor(sample, inverse = false) {
676
+ if (!isA("String", sample) && !isA("RegExp", sample)) throw new Error("Expected is not a String or a RegExp");
677
+ super(new RegExp(sample), inverse);
678
+ }
679
+ asymmetricMatch(other) {
680
+ const result = isA("String", other) && this.sample.test(other);
681
+ return this.inverse ? !result : result;
682
+ }
683
+ toString() {
684
+ return `String${this.inverse ? "Not" : ""}Matching`;
685
+ }
686
+ getExpectedType() {
687
+ return "string";
688
+ }
689
+ };
690
+ var CloseTo = class extends AsymmetricMatcher {
691
+ precision;
692
+ constructor(sample, precision = 2, inverse = false) {
693
+ if (!isA("Number", sample)) throw new Error("Expected is not a Number");
694
+ if (!isA("Number", precision)) throw new Error("Precision is not a Number");
695
+ super(sample);
696
+ this.inverse = inverse;
697
+ this.precision = precision;
698
+ }
699
+ asymmetricMatch(other) {
700
+ if (!isA("Number", other)) return false;
701
+ let result = false;
702
+ if (other === Number.POSITIVE_INFINITY && this.sample === Number.POSITIVE_INFINITY) result = true;
703
+ else if (other === Number.NEGATIVE_INFINITY && this.sample === Number.NEGATIVE_INFINITY) result = true;
704
+ else result = Math.abs(this.sample - other) < 10 ** -this.precision / 2;
705
+ return this.inverse ? !result : result;
706
+ }
707
+ toString() {
708
+ return `Number${this.inverse ? "Not" : ""}CloseTo`;
709
+ }
710
+ getExpectedType() {
711
+ return "number";
712
+ }
713
+ toAsymmetricMatcher() {
714
+ return [
715
+ this.toString(),
716
+ this.sample,
717
+ `(${pluralize("digit", this.precision)})`
718
+ ].join(" ");
719
+ }
720
+ };
721
+ var SchemaMatching = class extends AsymmetricMatcher {
722
+ result;
723
+ constructor(sample, inverse = false) {
724
+ if (!isStandardSchema(sample)) throw new TypeError("SchemaMatching expected to receive a Standard Schema.");
725
+ super(sample, inverse);
726
+ }
727
+ asymmetricMatch(other) {
728
+ const result = this.sample["~standard"].validate(other);
729
+ if (result instanceof Promise) throw new TypeError("Async schema validation is not supported in asymmetric matchers.");
730
+ this.result = result;
731
+ const pass = !this.result.issues || this.result.issues.length === 0;
732
+ return this.inverse ? !pass : pass;
733
+ }
734
+ toString() {
735
+ return `Schema${this.inverse ? "Not" : ""}Matching`;
736
+ }
737
+ getExpectedType() {
738
+ return "object";
739
+ }
740
+ toAsymmetricMatcher() {
741
+ const { utils } = this.getMatcherContext();
742
+ if ((this.result?.issues || []).length > 0) return `${this.toString()} ${utils.stringify(this.result, void 0, { printBasicPrototype: false })}`;
743
+ return this.toString();
744
+ }
745
+ };
746
+ const JestAsymmetricMatchers = (chai, utils) => {
747
+ utils.addMethod(chai.expect, "anything", () => new Anything());
748
+ utils.addMethod(chai.expect, "any", (expected) => new Any(expected));
749
+ utils.addMethod(chai.expect, "stringContaining", (expected) => new StringContaining(expected));
750
+ utils.addMethod(chai.expect, "objectContaining", (expected) => new ObjectContaining(expected));
751
+ utils.addMethod(chai.expect, "arrayContaining", (expected) => new ArrayContaining(expected));
752
+ utils.addMethod(chai.expect, "stringMatching", (expected) => new StringMatching(expected));
753
+ utils.addMethod(chai.expect, "closeTo", (expected, precision) => new CloseTo(expected, precision));
754
+ utils.addMethod(chai.expect, "schemaMatching", (expected) => new SchemaMatching(expected));
755
+ chai.expect.not = {
756
+ stringContaining: (expected) => new StringContaining(expected, true),
757
+ objectContaining: (expected) => new ObjectContaining(expected, true),
758
+ arrayContaining: (expected) => new ArrayContaining(expected, true),
759
+ stringMatching: (expected) => new StringMatching(expected, true),
760
+ closeTo: (expected, precision) => new CloseTo(expected, precision, true),
761
+ schemaMatching: (expected) => new SchemaMatching(expected, true)
762
+ };
763
+ };
764
+ function createAssertionMessage(util, assertion, hasArgs) {
765
+ const soft = util.flag(assertion, "soft") ? ".soft" : "";
766
+ const not = util.flag(assertion, "negate") ? "not." : "";
767
+ const name = `${util.flag(assertion, "_name")}(${hasArgs ? "expected" : ""})`;
768
+ const promiseName = util.flag(assertion, "promise");
769
+ return `expect${soft}(actual)${promiseName ? `.${promiseName}` : ""}.${not}${name}`;
770
+ }
771
+ function recordAsyncExpect(_test, promise, assertion, error, isSoft) {
772
+ const test = _test;
773
+ if (test && promise instanceof Promise) {
774
+ promise = promise.finally(() => {
775
+ if (!test.promises) return;
776
+ const index = test.promises.indexOf(promise);
777
+ if (index !== -1) test.promises.splice(index, 1);
778
+ });
779
+ if (!test.promises) test.promises = [];
780
+ if (isSoft) promise = promise.then(noop, (err) => {
781
+ handleTestError(test, err);
782
+ });
783
+ test.promises.push(promise);
784
+ let resolved = false;
785
+ test.onFinished ??= [];
786
+ test.onFinished.push(() => {
787
+ if (!resolved) {
788
+ const stack = (globalThis.__vitest_worker__?.onFilterStackTrace || ((s) => s || ""))(error.stack);
789
+ console.warn([
790
+ `Promise returned by \`${assertion}\` was not awaited. `,
791
+ "Vitest currently auto-awaits hanging assertions at the end of the test, but this will cause the test to fail in the next Vitest major. ",
792
+ "Please remember to await the assertion.\n",
793
+ stack
794
+ ].join(""));
795
+ }
796
+ });
797
+ return {
798
+ then(onFulfilled, onRejected) {
799
+ resolved = true;
800
+ return promise.then(onFulfilled, onRejected);
801
+ },
802
+ catch(onRejected) {
803
+ resolved = true;
804
+ return promise.catch(onRejected);
805
+ },
806
+ finally(onFinally) {
807
+ resolved = true;
808
+ return promise.finally(onFinally);
809
+ },
810
+ [Symbol.toStringTag]: "Promise"
811
+ };
812
+ }
813
+ return promise;
814
+ }
815
+ function handleTestError(test, err) {
816
+ test.result ||= { state: "fail" };
817
+ test.result.state = "fail";
818
+ test.result.errors ||= [];
819
+ test.result.errors.push(processError(err));
820
+ }
821
+ function wrapAssertion(utils, name, fn) {
822
+ return function(...args) {
823
+ if (name !== "withTest") utils.flag(this, "_name", name);
824
+ if (!utils.flag(this, "soft")) try {
825
+ return fn.apply(this, args);
826
+ } finally {}
827
+ const test = utils.flag(this, "vitest-test");
828
+ if (!test) throw new Error("expect.soft() can only be used inside a test");
829
+ try {
830
+ const result = fn.apply(this, args);
831
+ if (result && typeof result === "object" && typeof result.then === "function") return result.then(noop, (err) => {
832
+ handleTestError(test, err);
833
+ });
834
+ return result;
835
+ } catch (err) {
836
+ handleTestError(test, err);
837
+ }
838
+ };
839
+ }
840
+ const JestChaiExpect = (chai, utils) => {
841
+ const { AssertionError } = chai;
842
+ const customTesters = getCustomEqualityTesters();
843
+ function def(name, fn) {
844
+ const addMethod = (n) => {
845
+ const softWrapper = wrapAssertion(utils, n, fn);
846
+ utils.addMethod(chai.Assertion.prototype, n, softWrapper);
847
+ utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, n, softWrapper);
848
+ };
849
+ if (Array.isArray(name)) name.forEach((n) => addMethod(n));
850
+ else addMethod(name);
851
+ }
852
+ [
853
+ "throw",
854
+ "throws",
855
+ "Throw"
856
+ ].forEach((m) => {
857
+ utils.overwriteMethod(chai.Assertion.prototype, m, (_super) => {
858
+ return function(...args) {
859
+ const promise = utils.flag(this, "promise");
860
+ const object = utils.flag(this, "object");
861
+ const isNot = utils.flag(this, "negate");
862
+ if (promise === "rejects") utils.flag(this, "object", () => {
863
+ throw object;
864
+ });
865
+ else if (promise === "resolves" && typeof object !== "function") if (!isNot) throw new AssertionError(utils.flag(this, "message") || "expected promise to throw an error, but it didn't", { showDiff: false }, utils.flag(this, "ssfi"));
866
+ else return;
867
+ _super.apply(this, args);
868
+ };
869
+ });
870
+ });
871
+ def("withTest", function(test) {
872
+ utils.flag(this, "vitest-test", test);
873
+ return this;
874
+ });
875
+ def("toEqual", function(expected) {
876
+ const actual = utils.flag(this, "object");
877
+ const equal = equals(actual, expected, [...customTesters, iterableEquality]);
878
+ return this.assert(equal, "expected #{this} to deeply equal #{exp}", "expected #{this} to not deeply equal #{exp}", expected, actual);
879
+ });
880
+ def("toStrictEqual", function(expected) {
881
+ const obj = utils.flag(this, "object");
882
+ const equal = equals(obj, expected, [
883
+ ...customTesters,
884
+ iterableEquality,
885
+ typeEquality,
886
+ sparseArrayEquality,
887
+ arrayBufferEquality
888
+ ], true);
889
+ return this.assert(equal, "expected #{this} to strictly equal #{exp}", "expected #{this} to not strictly equal #{exp}", expected, obj);
890
+ });
891
+ def("toBe", function(expected) {
892
+ const actual = this._obj;
893
+ const pass = Object.is(actual, expected);
894
+ let deepEqualityName = "";
895
+ if (!pass) {
896
+ if (equals(actual, expected, [
897
+ ...customTesters,
898
+ iterableEquality,
899
+ typeEquality,
900
+ sparseArrayEquality,
901
+ arrayBufferEquality
902
+ ], true)) deepEqualityName = "toStrictEqual";
903
+ else if (equals(actual, expected, [...customTesters, iterableEquality])) deepEqualityName = "toEqual";
904
+ }
905
+ return this.assert(pass, generateToBeMessage(deepEqualityName), "expected #{this} not to be #{exp} // Object.is equality", expected, actual);
906
+ });
907
+ def("toMatchObject", function(expected) {
908
+ const actual = this._obj;
909
+ const pass = equals(actual, expected, [
910
+ ...customTesters,
911
+ iterableEquality,
912
+ subsetEquality
913
+ ]);
914
+ const isNot = utils.flag(this, "negate");
915
+ const { subset: actualSubset, stripped } = getObjectSubset(actual, expected, customTesters);
916
+ if (pass && isNot || !pass && !isNot) {
917
+ const msg = utils.getMessage(this, [
918
+ pass,
919
+ "expected #{this} to match object #{exp}",
920
+ "expected #{this} to not match object #{exp}",
921
+ expected,
922
+ actualSubset,
923
+ false
924
+ ]);
925
+ throw new AssertionError(stripped === 0 ? msg : `${msg}\n(${stripped} matching ${stripped === 1 ? "property" : "properties"} omitted from actual)`, {
926
+ showDiff: true,
927
+ expected,
928
+ actual: actualSubset
929
+ });
930
+ }
931
+ });
932
+ def("toMatch", function(expected) {
933
+ const actual = this._obj;
934
+ if (typeof actual !== "string") throw new TypeError(`.toMatch() expects to receive a string, but got ${typeof actual}`);
935
+ return this.assert(typeof expected === "string" ? actual.includes(expected) : actual.match(expected), `expected #{this} to match #{exp}`, `expected #{this} not to match #{exp}`, expected, actual);
936
+ });
937
+ def("toContain", function(item) {
938
+ const actual = this._obj;
939
+ if (typeof Node !== "undefined" && actual instanceof Node) {
940
+ if (!(item instanceof Node)) throw new TypeError(`toContain() expected a DOM node as the argument, but got ${typeof item}`);
941
+ return this.assert(actual.contains(item), "expected #{this} to contain element #{exp}", "expected #{this} not to contain element #{exp}", item, actual);
942
+ }
943
+ if (typeof DOMTokenList !== "undefined" && actual instanceof DOMTokenList) {
944
+ assertTypes(item, "class name", ["string"]);
945
+ const expectedClassList = utils.flag(this, "negate") ? actual.value.replace(item, "").trim() : `${actual.value} ${item}`;
946
+ return this.assert(actual.contains(item), `expected "${actual.value}" to contain "${item}"`, `expected "${actual.value}" not to contain "${item}"`, expectedClassList, actual.value);
947
+ }
948
+ if (typeof actual === "string" && typeof item === "string") return this.assert(actual.includes(item), `expected #{this} to contain #{exp}`, `expected #{this} not to contain #{exp}`, item, actual);
949
+ if (actual != null && typeof actual !== "string") utils.flag(this, "object", Array.from(actual));
950
+ return this.contain(item);
951
+ });
952
+ def("toContainEqual", function(expected) {
953
+ const obj = utils.flag(this, "object");
954
+ const index = Array.from(obj).findIndex((item) => {
955
+ return equals(item, expected, customTesters);
956
+ });
957
+ this.assert(index !== -1, "expected #{this} to deep equally contain #{exp}", "expected #{this} to not deep equally contain #{exp}", expected);
958
+ });
959
+ def("toBeTruthy", function() {
960
+ const obj = utils.flag(this, "object");
961
+ this.assert(Boolean(obj), "expected #{this} to be truthy", "expected #{this} to not be truthy", true, obj);
962
+ });
963
+ def("toBeFalsy", function() {
964
+ const obj = utils.flag(this, "object");
965
+ this.assert(!obj, "expected #{this} to be falsy", "expected #{this} to not be falsy", false, obj);
966
+ });
967
+ def("toBeGreaterThan", function(expected) {
968
+ const actual = this._obj;
969
+ assertTypes(actual, "actual", ["number", "bigint"]);
970
+ assertTypes(expected, "expected", ["number", "bigint"]);
971
+ return this.assert(actual > expected, `expected ${actual} to be greater than ${expected}`, `expected ${actual} to be not greater than ${expected}`, expected, actual, false);
972
+ });
973
+ def("toBeGreaterThanOrEqual", function(expected) {
974
+ const actual = this._obj;
975
+ assertTypes(actual, "actual", ["number", "bigint"]);
976
+ assertTypes(expected, "expected", ["number", "bigint"]);
977
+ return this.assert(actual >= expected, `expected ${actual} to be greater than or equal to ${expected}`, `expected ${actual} to be not greater than or equal to ${expected}`, expected, actual, false);
978
+ });
979
+ def("toBeLessThan", function(expected) {
980
+ const actual = this._obj;
981
+ assertTypes(actual, "actual", ["number", "bigint"]);
982
+ assertTypes(expected, "expected", ["number", "bigint"]);
983
+ return this.assert(actual < expected, `expected ${actual} to be less than ${expected}`, `expected ${actual} to be not less than ${expected}`, expected, actual, false);
984
+ });
985
+ def("toBeLessThanOrEqual", function(expected) {
986
+ const actual = this._obj;
987
+ assertTypes(actual, "actual", ["number", "bigint"]);
988
+ assertTypes(expected, "expected", ["number", "bigint"]);
989
+ return this.assert(actual <= expected, `expected ${actual} to be less than or equal to ${expected}`, `expected ${actual} to be not less than or equal to ${expected}`, expected, actual, false);
990
+ });
991
+ def("toBeNaN", function() {
992
+ const obj = utils.flag(this, "object");
993
+ this.assert(Number.isNaN(obj), "expected #{this} to be NaN", "expected #{this} not to be NaN", NaN, obj);
994
+ });
995
+ def("toBeUndefined", function() {
996
+ const obj = utils.flag(this, "object");
997
+ this.assert(void 0 === obj, "expected #{this} to be undefined", "expected #{this} not to be undefined", void 0, obj);
998
+ });
999
+ def("toBeNull", function() {
1000
+ const obj = utils.flag(this, "object");
1001
+ this.assert(obj === null, "expected #{this} to be null", "expected #{this} not to be null", null, obj);
1002
+ });
1003
+ def("toBeNullable", function() {
1004
+ const obj = utils.flag(this, "object");
1005
+ this.assert(obj == null, "expected #{this} to be nullish", "expected #{this} not to be nullish", null, obj);
1006
+ });
1007
+ def("toBeDefined", function() {
1008
+ const obj = utils.flag(this, "object");
1009
+ this.assert(typeof obj !== "undefined", "expected #{this} to be defined", "expected #{this} to be undefined", obj);
1010
+ });
1011
+ def("toBeTypeOf", function(expected) {
1012
+ const actual = typeof this._obj;
1013
+ const equal = expected === actual;
1014
+ return this.assert(equal, "expected #{this} to be type of #{exp}", "expected #{this} not to be type of #{exp}", expected, actual);
1015
+ });
1016
+ def("toBeInstanceOf", function(obj) {
1017
+ return this.instanceOf(obj);
1018
+ });
1019
+ def("toHaveLength", function(length) {
1020
+ return this.have.length(length);
1021
+ });
1022
+ def("toHaveProperty", function(...args) {
1023
+ if (Array.isArray(args[0])) args[0] = args[0].map((key) => String(key).replace(/([.[\]])/g, "\\$1")).join(".");
1024
+ const actual = this._obj;
1025
+ const [propertyName, expected] = args;
1026
+ const getValue = () => {
1027
+ if (Object.hasOwn(actual, propertyName)) return {
1028
+ value: actual[propertyName],
1029
+ exists: true
1030
+ };
1031
+ return utils.getPathInfo(actual, propertyName);
1032
+ };
1033
+ const { value, exists } = getValue();
1034
+ const pass = exists && (args.length === 1 || equals(expected, value, customTesters));
1035
+ const valueString = args.length === 1 ? "" : ` with value ${utils.objDisplay(expected)}`;
1036
+ return this.assert(pass, `expected #{this} to have property "${propertyName}"${valueString}`, `expected #{this} to not have property "${propertyName}"${valueString}`, expected, exists ? value : void 0);
1037
+ });
1038
+ def("toBeCloseTo", function(received, precision = 2) {
1039
+ const expected = this._obj;
1040
+ let pass = false;
1041
+ let expectedDiff = 0;
1042
+ let receivedDiff = 0;
1043
+ if (received === Number.POSITIVE_INFINITY && expected === Number.POSITIVE_INFINITY) pass = true;
1044
+ else if (received === Number.NEGATIVE_INFINITY && expected === Number.NEGATIVE_INFINITY) pass = true;
1045
+ else {
1046
+ expectedDiff = 10 ** -precision / 2;
1047
+ receivedDiff = Math.abs(expected - received);
1048
+ pass = receivedDiff < expectedDiff;
1049
+ }
1050
+ return this.assert(pass, `expected #{this} to be close to #{exp}, received difference is ${receivedDiff}, but expected ${expectedDiff}`, `expected #{this} to not be close to #{exp}, received difference is ${receivedDiff}, but expected ${expectedDiff}`, received, expected, false);
1051
+ });
1052
+ function assertIsMock(assertion) {
1053
+ if (!isMockFunction(assertion._obj)) throw new TypeError(`${utils.inspect(assertion._obj)} is not a spy or a call to a spy!`);
1054
+ }
1055
+ function getSpy(assertion) {
1056
+ assertIsMock(assertion);
1057
+ return assertion._obj;
1058
+ }
1059
+ def(["toHaveBeenCalledTimes", "toBeCalledTimes"], function(number) {
1060
+ const spy = getSpy(this);
1061
+ const spyName = spy.getMockName();
1062
+ const callCount = spy.mock.calls.length;
1063
+ return this.assert(callCount === number, `expected "${spyName}" to be called #{exp} times, but got ${callCount} times`, `expected "${spyName}" to not be called #{exp} times`, number, callCount, false);
1064
+ });
1065
+ def("toHaveBeenCalledOnce", function() {
1066
+ const spy = getSpy(this);
1067
+ const spyName = spy.getMockName();
1068
+ const callCount = spy.mock.calls.length;
1069
+ return this.assert(callCount === 1, `expected "${spyName}" to be called once, but got ${callCount} times`, `expected "${spyName}" to not be called once`, 1, callCount, false);
1070
+ });
1071
+ def(["toHaveBeenCalled", "toBeCalled"], function() {
1072
+ const spy = getSpy(this);
1073
+ const spyName = spy.getMockName();
1074
+ const callCount = spy.mock.calls.length;
1075
+ const called = callCount > 0;
1076
+ const isNot = utils.flag(this, "negate");
1077
+ let msg = utils.getMessage(this, [
1078
+ called,
1079
+ `expected "${spyName}" to be called at least once`,
1080
+ `expected "${spyName}" to not be called at all, but actually been called ${callCount} times`,
1081
+ true,
1082
+ called
1083
+ ]);
1084
+ if (called && isNot) msg = formatCalls(spy, msg);
1085
+ if (called && isNot || !called && !isNot) throw new AssertionError(msg);
1086
+ });
1087
+ function equalsArgumentArray(a, b) {
1088
+ return a.length === b.length && a.every((aItem, i) => equals(aItem, b[i], [...customTesters, iterableEquality]));
1089
+ }
1090
+ def(["toHaveBeenCalledWith", "toBeCalledWith"], function(...args) {
1091
+ const spy = getSpy(this);
1092
+ const spyName = spy.getMockName();
1093
+ const pass = spy.mock.calls.some((callArg) => equalsArgumentArray(callArg, args));
1094
+ const isNot = utils.flag(this, "negate");
1095
+ const msg = utils.getMessage(this, [
1096
+ pass,
1097
+ `expected "${spyName}" to be called with arguments: #{exp}`,
1098
+ `expected "${spyName}" to not be called with arguments: #{exp}`,
1099
+ args
1100
+ ]);
1101
+ if (pass && isNot || !pass && !isNot) throw new AssertionError(formatCalls(spy, msg, args));
1102
+ });
1103
+ def("toHaveBeenCalledExactlyOnceWith", function(...args) {
1104
+ const spy = getSpy(this);
1105
+ const spyName = spy.getMockName();
1106
+ const callCount = spy.mock.calls.length;
1107
+ const pass = spy.mock.calls.some((callArg) => equalsArgumentArray(callArg, args)) && callCount === 1;
1108
+ const isNot = utils.flag(this, "negate");
1109
+ const msg = utils.getMessage(this, [
1110
+ pass,
1111
+ `expected "${spyName}" to be called once with arguments: #{exp}`,
1112
+ `expected "${spyName}" to not be called once with arguments: #{exp}`,
1113
+ args
1114
+ ]);
1115
+ if (pass && isNot || !pass && !isNot) throw new AssertionError(formatCalls(spy, msg, args));
1116
+ });
1117
+ def("toHaveBeenNthCalledWith", function(times, ...args) {
1118
+ const spy = getSpy(this);
1119
+ const spyName = spy.getMockName();
1120
+ const nthCall = spy.mock.calls[times - 1];
1121
+ const callCount = spy.mock.calls.length;
1122
+ const isCalled = times <= callCount;
1123
+ this.assert(nthCall && equalsArgumentArray(nthCall, args), `expected ${ordinal(times)} "${spyName}" call to have been called with #{exp}${isCalled ? `` : `, but called only ${callCount} times`}`, `expected ${ordinal(times)} "${spyName}" call to not have been called with #{exp}`, args, nthCall, isCalled);
1124
+ });
1125
+ def("toHaveBeenLastCalledWith", function(...args) {
1126
+ const spy = getSpy(this);
1127
+ const spyName = spy.getMockName();
1128
+ const lastCall = spy.mock.calls.at(-1);
1129
+ this.assert(lastCall && equalsArgumentArray(lastCall, args), `expected last "${spyName}" call to have been called with #{exp}`, `expected last "${spyName}" call to not have been called with #{exp}`, args, lastCall);
1130
+ });
1131
+ /**
1132
+ * Used for `toHaveBeenCalledBefore` and `toHaveBeenCalledAfter` to determine if the expected spy was called before the result spy.
1133
+ */
1134
+ function isSpyCalledBeforeAnotherSpy(beforeSpy, afterSpy, failIfNoFirstInvocation) {
1135
+ const beforeInvocationCallOrder = beforeSpy.mock.invocationCallOrder;
1136
+ const afterInvocationCallOrder = afterSpy.mock.invocationCallOrder;
1137
+ if (beforeInvocationCallOrder.length === 0) return !failIfNoFirstInvocation;
1138
+ if (afterInvocationCallOrder.length === 0) return false;
1139
+ return beforeInvocationCallOrder[0] < afterInvocationCallOrder[0];
1140
+ }
1141
+ def(["toHaveBeenCalledBefore"], function(resultSpy, failIfNoFirstInvocation = true) {
1142
+ const expectSpy = getSpy(this);
1143
+ if (!isMockFunction(resultSpy)) throw new TypeError(`${utils.inspect(resultSpy)} is not a spy or a call to a spy`);
1144
+ this.assert(isSpyCalledBeforeAnotherSpy(expectSpy, resultSpy, failIfNoFirstInvocation), `expected "${expectSpy.getMockName()}" to have been called before "${resultSpy.getMockName()}"`, `expected "${expectSpy.getMockName()}" to not have been called before "${resultSpy.getMockName()}"`, resultSpy, expectSpy);
1145
+ });
1146
+ def(["toHaveBeenCalledAfter"], function(resultSpy, failIfNoFirstInvocation = true) {
1147
+ const expectSpy = getSpy(this);
1148
+ if (!isMockFunction(resultSpy)) throw new TypeError(`${utils.inspect(resultSpy)} is not a spy or a call to a spy`);
1149
+ this.assert(isSpyCalledBeforeAnotherSpy(resultSpy, expectSpy, failIfNoFirstInvocation), `expected "${expectSpy.getMockName()}" to have been called after "${resultSpy.getMockName()}"`, `expected "${expectSpy.getMockName()}" to not have been called after "${resultSpy.getMockName()}"`, resultSpy, expectSpy);
1150
+ });
1151
+ def(["toThrow", "toThrowError"], function(expected) {
1152
+ if (typeof expected === "string" || typeof expected === "undefined" || expected instanceof RegExp) return this.throws(expected === "" ? /^$/ : expected);
1153
+ const obj = this._obj;
1154
+ const promise = utils.flag(this, "promise");
1155
+ const isNot = utils.flag(this, "negate");
1156
+ let thrown = null;
1157
+ if (promise === "rejects") thrown = obj;
1158
+ else if (promise === "resolves" && typeof obj !== "function") if (!isNot) throw new AssertionError(utils.flag(this, "message") || "expected promise to throw an error, but it didn't", { showDiff: false }, utils.flag(this, "ssfi"));
1159
+ else return;
1160
+ else {
1161
+ let isThrow = false;
1162
+ try {
1163
+ obj();
1164
+ } catch (err) {
1165
+ isThrow = true;
1166
+ thrown = err;
1167
+ }
1168
+ if (!isThrow && !isNot) throw new AssertionError(utils.flag(this, "message") || "expected function to throw an error, but it didn't", { showDiff: false }, utils.flag(this, "ssfi"));
1169
+ }
1170
+ if (typeof expected === "function") {
1171
+ const name = expected.name || expected.prototype.constructor.name;
1172
+ return this.assert(thrown && thrown instanceof expected, `expected error to be instance of ${name}`, `expected error not to be instance of ${name}`, expected, thrown);
1173
+ }
1174
+ if (isError(expected)) {
1175
+ const equal = equals(thrown, expected, [...customTesters, iterableEquality]);
1176
+ return this.assert(equal, "expected a thrown error to be #{exp}", "expected a thrown error not to be #{exp}", expected, thrown);
1177
+ }
1178
+ if (typeof expected === "object" && "asymmetricMatch" in expected && typeof expected.asymmetricMatch === "function") {
1179
+ const matcher = expected;
1180
+ return this.assert(thrown && matcher.asymmetricMatch(thrown), "expected error to match asymmetric matcher", "expected error not to match asymmetric matcher", matcher, thrown);
1181
+ }
1182
+ const equal = equals(thrown, expected, [...customTesters, iterableEquality]);
1183
+ return this.assert(equal, "expected a thrown value to equal #{exp}", "expected a thrown value not to equal #{exp}", expected, thrown);
1184
+ });
1185
+ [{
1186
+ name: "toHaveResolved",
1187
+ condition: (spy) => spy.mock.settledResults.length > 0 && spy.mock.settledResults.some(({ type }) => type === "fulfilled"),
1188
+ action: "resolved"
1189
+ }, {
1190
+ name: ["toHaveReturned", "toReturn"],
1191
+ condition: (spy) => spy.mock.calls.length > 0 && spy.mock.results.some(({ type }) => type !== "throw"),
1192
+ action: "called"
1193
+ }].forEach(({ name, condition, action }) => {
1194
+ def(name, function() {
1195
+ const spy = getSpy(this);
1196
+ const spyName = spy.getMockName();
1197
+ const pass = condition(spy);
1198
+ this.assert(pass, `expected "${spyName}" to be successfully ${action} at least once`, `expected "${spyName}" to not be successfully ${action}`, pass, !pass, false);
1199
+ });
1200
+ });
1201
+ [{
1202
+ name: "toHaveResolvedTimes",
1203
+ condition: (spy, times) => spy.mock.settledResults.reduce((s, { type }) => type === "fulfilled" ? ++s : s, 0) === times,
1204
+ action: "resolved"
1205
+ }, {
1206
+ name: ["toHaveReturnedTimes", "toReturnTimes"],
1207
+ condition: (spy, times) => spy.mock.results.reduce((s, { type }) => type === "throw" ? s : ++s, 0) === times,
1208
+ action: "called"
1209
+ }].forEach(({ name, condition, action }) => {
1210
+ def(name, function(times) {
1211
+ const spy = getSpy(this);
1212
+ const spyName = spy.getMockName();
1213
+ const pass = condition(spy, times);
1214
+ this.assert(pass, `expected "${spyName}" to be successfully ${action} ${times} times`, `expected "${spyName}" to not be successfully ${action} ${times} times`, `expected resolved times: ${times}`, `received resolved times: ${pass}`, false);
1215
+ });
1216
+ });
1217
+ [{
1218
+ name: "toHaveResolvedWith",
1219
+ condition: (spy, value) => spy.mock.settledResults.some(({ type, value: result }) => type === "fulfilled" && equals(value, result)),
1220
+ action: "resolve"
1221
+ }, {
1222
+ name: ["toHaveReturnedWith", "toReturnWith"],
1223
+ condition: (spy, value) => spy.mock.results.some(({ type, value: result }) => type === "return" && equals(value, result)),
1224
+ action: "return"
1225
+ }].forEach(({ name, condition, action }) => {
1226
+ def(name, function(value) {
1227
+ const spy = getSpy(this);
1228
+ const pass = condition(spy, value);
1229
+ const isNot = utils.flag(this, "negate");
1230
+ if (pass && isNot || !pass && !isNot) {
1231
+ const spyName = spy.getMockName();
1232
+ const msg = utils.getMessage(this, [
1233
+ pass,
1234
+ `expected "${spyName}" to ${action} with: #{exp} at least once`,
1235
+ `expected "${spyName}" to not ${action} with: #{exp}`,
1236
+ value
1237
+ ]);
1238
+ throw new AssertionError(formatReturns(spy, action === "return" ? spy.mock.results : spy.mock.settledResults, msg, value));
1239
+ }
1240
+ });
1241
+ });
1242
+ [{
1243
+ name: "toHaveLastResolvedWith",
1244
+ condition: (spy, value) => {
1245
+ const result = spy.mock.settledResults.at(-1);
1246
+ return Boolean(result && result.type === "fulfilled" && equals(result.value, value));
1247
+ },
1248
+ action: "resolve"
1249
+ }, {
1250
+ name: "toHaveLastReturnedWith",
1251
+ condition: (spy, value) => {
1252
+ const result = spy.mock.results.at(-1);
1253
+ return Boolean(result && result.type === "return" && equals(result.value, value));
1254
+ },
1255
+ action: "return"
1256
+ }].forEach(({ name, condition, action }) => {
1257
+ def(name, function(value) {
1258
+ const spy = getSpy(this);
1259
+ const result = (action === "return" ? spy.mock.results : spy.mock.settledResults).at(-1);
1260
+ const spyName = spy.getMockName();
1261
+ this.assert(condition(spy, value), `expected last "${spyName}" call to ${action} #{exp}`, `expected last "${spyName}" call to not ${action} #{exp}`, value, result?.value);
1262
+ });
1263
+ });
1264
+ [{
1265
+ name: "toHaveNthResolvedWith",
1266
+ condition: (spy, index, value) => {
1267
+ const result = spy.mock.settledResults[index - 1];
1268
+ return result && result.type === "fulfilled" && equals(result.value, value);
1269
+ },
1270
+ action: "resolve"
1271
+ }, {
1272
+ name: "toHaveNthReturnedWith",
1273
+ condition: (spy, index, value) => {
1274
+ const result = spy.mock.results[index - 1];
1275
+ return result && result.type === "return" && equals(result.value, value);
1276
+ },
1277
+ action: "return"
1278
+ }].forEach(({ name, condition, action }) => {
1279
+ def(name, function(nthCall, value) {
1280
+ const spy = getSpy(this);
1281
+ const spyName = spy.getMockName();
1282
+ const result = (action === "return" ? spy.mock.results : spy.mock.settledResults)[nthCall - 1];
1283
+ const ordinalCall = `${ordinal(nthCall)} call`;
1284
+ this.assert(condition(spy, nthCall, value), `expected ${ordinalCall} "${spyName}" call to ${action} #{exp}`, `expected ${ordinalCall} "${spyName}" call to not ${action} #{exp}`, value, result?.value);
1285
+ });
1286
+ });
1287
+ def("withContext", function(context) {
1288
+ for (const key in context) utils.flag(this, key, context[key]);
1289
+ return this;
1290
+ });
1291
+ utils.addProperty(chai.Assertion.prototype, "resolves", function __VITEST_RESOLVES__() {
1292
+ const error = /* @__PURE__ */ new Error("resolves");
1293
+ utils.flag(this, "promise", "resolves");
1294
+ utils.flag(this, "error", error);
1295
+ const test = utils.flag(this, "vitest-test");
1296
+ const obj = utils.flag(this, "object");
1297
+ if (utils.flag(this, "poll")) throw new SyntaxError(`expect.poll() is not supported in combination with .resolves`);
1298
+ if (typeof obj?.then !== "function") throw new TypeError(`You must provide a Promise to expect() when using .resolves, not '${typeof obj}'.`);
1299
+ const proxy = new Proxy(this, { get: (target, key, receiver) => {
1300
+ const result = Reflect.get(target, key, receiver);
1301
+ if (typeof result !== "function") return result instanceof chai.Assertion ? proxy : result;
1302
+ return (...args) => {
1303
+ utils.flag(this, "_name", key);
1304
+ return recordAsyncExpect(test, Promise.resolve(obj).then((value) => {
1305
+ utils.flag(this, "object", value);
1306
+ return result.call(this, ...args);
1307
+ }, (err) => {
1308
+ const _error = new AssertionError(`promise rejected "${utils.inspect(err)}" instead of resolving`, { showDiff: false });
1309
+ _error.cause = err;
1310
+ throw _error;
1311
+ }).catch((err) => {
1312
+ if (isError(err) && error.stack) err.stack = error.stack.replace(error.message, err.message);
1313
+ throw err;
1314
+ }), createAssertionMessage(utils, this, !!args.length), error, utils.flag(this, "soft"));
1315
+ };
1316
+ } });
1317
+ return proxy;
1318
+ });
1319
+ utils.addProperty(chai.Assertion.prototype, "rejects", function __VITEST_REJECTS__() {
1320
+ const error = /* @__PURE__ */ new Error("rejects");
1321
+ utils.flag(this, "promise", "rejects");
1322
+ utils.flag(this, "error", error);
1323
+ const test = utils.flag(this, "vitest-test");
1324
+ const obj = utils.flag(this, "object");
1325
+ const wrapper = typeof obj === "function" ? obj() : obj;
1326
+ if (utils.flag(this, "poll")) throw new SyntaxError(`expect.poll() is not supported in combination with .rejects`);
1327
+ if (typeof wrapper?.then !== "function") throw new TypeError(`You must provide a Promise to expect() when using .rejects, not '${typeof wrapper}'.`);
1328
+ const proxy = new Proxy(this, { get: (target, key, receiver) => {
1329
+ const result = Reflect.get(target, key, receiver);
1330
+ if (typeof result !== "function") return result instanceof chai.Assertion ? proxy : result;
1331
+ return (...args) => {
1332
+ utils.flag(this, "_name", key);
1333
+ return recordAsyncExpect(test, Promise.resolve(wrapper).then((value) => {
1334
+ throw new AssertionError(`promise resolved "${utils.inspect(value)}" instead of rejecting`, {
1335
+ showDiff: true,
1336
+ expected: /* @__PURE__ */ new Error("rejected promise"),
1337
+ actual: value
1338
+ });
1339
+ }, (err) => {
1340
+ utils.flag(this, "object", err);
1341
+ return result.call(this, ...args);
1342
+ }).catch((err) => {
1343
+ if (isError(err) && error.stack) err.stack = error.stack.replace(error.message, err.message);
1344
+ throw err;
1345
+ }), createAssertionMessage(utils, this, !!args.length), error, utils.flag(this, "soft"));
1346
+ };
1347
+ } });
1348
+ return proxy;
1349
+ });
1350
+ };
1351
+ function formatCalls(spy, msg, showActualCall) {
1352
+ if (spy.mock.calls.length) msg += y.gray(`\n\nReceived:\n\n${spy.mock.calls.map((callArg, i) => {
1353
+ let methodCall = y.bold(` ${ordinal(i + 1)} ${spy.getMockName()} call:\n\n`);
1354
+ if (showActualCall) methodCall += diff(showActualCall, callArg, { omitAnnotationLines: true });
1355
+ else methodCall += stringify(callArg).split("\n").map((line) => ` ${line}`).join("\n");
1356
+ methodCall += "\n";
1357
+ return methodCall;
1358
+ }).join("\n")}`);
1359
+ msg += y.gray(`\n\nNumber of calls: ${y.bold(spy.mock.calls.length)}\n`);
1360
+ return msg;
1361
+ }
1362
+ function formatReturns(spy, results, msg, showActualReturn) {
1363
+ if (results.length) msg += y.gray(`\n\nReceived:\n\n${results.map((callReturn, i) => {
1364
+ let methodCall = y.bold(` ${ordinal(i + 1)} ${spy.getMockName()} call return:\n\n`);
1365
+ if (showActualReturn) methodCall += diff(showActualReturn, callReturn.value, { omitAnnotationLines: true });
1366
+ else methodCall += stringify(callReturn).split("\n").map((line) => ` ${line}`).join("\n");
1367
+ methodCall += "\n";
1368
+ return methodCall;
1369
+ }).join("\n")}`);
1370
+ msg += y.gray(`\n\nNumber of calls: ${y.bold(spy.mock.calls.length)}\n`);
1371
+ return msg;
1372
+ }
1373
+ function getMatcherState(assertion, expect) {
1374
+ const obj = assertion._obj;
1375
+ const isNot = utils_exports.flag(assertion, "negate");
1376
+ const promise = utils_exports.flag(assertion, "promise") || "";
1377
+ const customMessage = utils_exports.flag(assertion, "message");
1378
+ const jestUtils = {
1379
+ ...getMatcherUtils(),
1380
+ diff,
1381
+ stringify,
1382
+ iterableEquality,
1383
+ subsetEquality
1384
+ };
1385
+ let task = utils_exports.flag(assertion, "vitest-test");
1386
+ const currentTestName = task?.fullTestName ?? "";
1387
+ if (task?.type !== "test") task = void 0;
1388
+ return {
1389
+ state: {
1390
+ ...getState(expect),
1391
+ task,
1392
+ currentTestName,
1393
+ customTesters: getCustomEqualityTesters(),
1394
+ isNot,
1395
+ utils: jestUtils,
1396
+ promise,
1397
+ equals,
1398
+ suppressedErrors: [],
1399
+ soft: utils_exports.flag(assertion, "soft"),
1400
+ poll: utils_exports.flag(assertion, "poll")
1401
+ },
1402
+ isNot,
1403
+ obj,
1404
+ customMessage
1405
+ };
1406
+ }
1407
+ var JestExtendError = class extends Error {
1408
+ constructor(message, actual, expected, context) {
1409
+ super(message);
1410
+ this.actual = actual;
1411
+ this.expected = expected;
1412
+ this.context = context;
1413
+ }
1414
+ };
1415
+ function JestExtendPlugin(c, expect, matchers) {
1416
+ return (_, utils) => {
1417
+ Object.entries(matchers).forEach(([expectAssertionName, expectAssertion]) => {
1418
+ function expectWrapper(...args) {
1419
+ const { state, isNot, obj, customMessage } = getMatcherState(this, expect);
1420
+ const result = expectAssertion.call(state, obj, ...args);
1421
+ if (result && typeof result === "object" && typeof result.then === "function") return result.then(({ pass, message, actual, expected, meta }) => {
1422
+ if (pass && isNot || !pass && !isNot) throw new JestExtendError(customMessage != null ? customMessage : message(), actual, expected, {
1423
+ assertionName: expectAssertionName,
1424
+ meta
1425
+ });
1426
+ });
1427
+ const { pass, message, actual, expected, meta } = result;
1428
+ if (pass && isNot || !pass && !isNot) throw new JestExtendError(customMessage != null ? customMessage : message(), actual, expected, {
1429
+ assertionName: expectAssertionName,
1430
+ meta
1431
+ });
1432
+ }
1433
+ const softWrapper = wrapAssertion(utils, expectAssertionName, expectWrapper);
1434
+ utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, expectAssertionName, softWrapper);
1435
+ utils.addMethod(c.Assertion.prototype, expectAssertionName, softWrapper);
1436
+ class CustomMatcher extends AsymmetricMatcher {
1437
+ constructor(inverse = false, ...sample) {
1438
+ super(sample, inverse);
1439
+ }
1440
+ asymmetricMatch(other) {
1441
+ const { pass } = expectAssertion.call(this.getMatcherContext(expect), other, ...this.sample);
1442
+ return this.inverse ? !pass : pass;
1443
+ }
1444
+ toString() {
1445
+ return `${this.inverse ? "not." : ""}${expectAssertionName}`;
1446
+ }
1447
+ getExpectedType() {
1448
+ return "any";
1449
+ }
1450
+ toAsymmetricMatcher() {
1451
+ return `${this.toString()}<${this.sample.map((item) => stringify(item)).join(", ")}>`;
1452
+ }
1453
+ }
1454
+ const customMatcher = (...sample) => new CustomMatcher(false, ...sample);
1455
+ Object.defineProperty(expect, expectAssertionName, {
1456
+ configurable: true,
1457
+ enumerable: true,
1458
+ value: customMatcher,
1459
+ writable: true
1460
+ });
1461
+ Object.defineProperty(expect.not, expectAssertionName, {
1462
+ configurable: true,
1463
+ enumerable: true,
1464
+ value: (...sample) => new CustomMatcher(true, ...sample),
1465
+ writable: true
1466
+ });
1467
+ Object.defineProperty(globalThis[ASYMMETRIC_MATCHERS_OBJECT], expectAssertionName, {
1468
+ configurable: true,
1469
+ enumerable: true,
1470
+ value: customMatcher,
1471
+ writable: true
1472
+ });
1473
+ });
1474
+ };
1475
+ }
1476
+ const JestExtend = (chai, utils) => {
1477
+ utils.addMethod(chai.expect, "extend", (expect, expects) => {
1478
+ use(JestExtendPlugin(chai, expect, expects));
1479
+ });
1480
+ };
1481
+ //#endregion
1482
+ export { ASYMMETRIC_MATCHERS_OBJECT, ChaiStyleAssertions, GLOBAL_EXPECT, JestAsymmetricMatchers, JestChaiExpect, JestExtend, addCustomEqualityTesters, createAssertionMessage, customMatchers, equals, getState, iterableEquality, recordAsyncExpect, setState, subsetEquality, wrapAssertion };
1483
+
1484
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJuYW1lcyI6WyJjIiwidXRpbCJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Adml0ZXN0K2V4cGVjdEA0LjEuMi9ub2RlX21vZHVsZXMvQHZpdGVzdC9leHBlY3QvZGlzdC9pbmRleC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBwcmludERpZmZPclN0cmluZ2lmeSwgZGlmZiB9IGZyb20gJ0B2aXRlc3QvdXRpbHMvZGlmZic7XG5pbXBvcnQgeyBzdHJpbmdpZnkgfSBmcm9tICdAdml0ZXN0L3V0aWxzL2Rpc3BsYXknO1xuaW1wb3J0IHsgZ2V0VHlwZSwgaXNPYmplY3QsIG5vb3AsIGFzc2VydFR5cGVzLCBvcmRpbmFsIH0gZnJvbSAnQHZpdGVzdC91dGlscy9oZWxwZXJzJztcbmltcG9ydCBjIGZyb20gJ3RpbnlyYWluYm93JztcbmltcG9ydCB7IGlzTW9ja0Z1bmN0aW9uIH0gZnJvbSAnQHZpdGVzdC9zcHknO1xuaW1wb3J0IHsgcHJvY2Vzc0Vycm9yIH0gZnJvbSAnQHZpdGVzdC91dGlscy9lcnJvcic7XG5pbXBvcnQgeyB1c2UsIHV0aWwgfSBmcm9tICdjaGFpJztcbmltcG9ydCAqIGFzIGNoYWkgZnJvbSAnY2hhaSc7XG5leHBvcnQgeyBjaGFpIH07XG5cbmNvbnN0IENoYWlTdHlsZUFzc2VydGlvbnMgPSAoY2hhaSwgdXRpbHMpID0+IHtcblx0ZnVuY3Rpb24gZGVmUHJvcGVydHkobmFtZSwgZGVsZWdhdGVUbykge1xuXHRcdHV0aWxzLmFkZFByb3BlcnR5KGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgbmFtZSwgZnVuY3Rpb24oKSB7XG5cdFx0XHRjb25zdCBqZXN0TWV0aG9kID0gY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlW2RlbGVnYXRlVG9dO1xuXHRcdFx0aWYgKCFqZXN0TWV0aG9kKSB7XG5cdFx0XHRcdHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGRlbGVnYXRlIHRvICR7U3RyaW5nKGRlbGVnYXRlVG8pfTogbWV0aG9kIG5vdCBmb3VuZC4gRW5zdXJlIEplc3RDaGFpRXhwZWN0IHBsdWdpbiBpcyBsb2FkZWQgZmlyc3QuYCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gamVzdE1ldGhvZC5jYWxsKHRoaXMpO1xuXHRcdH0pO1xuXHR9XG5cdGZ1bmN0aW9uIGRlZlByb3BlcnR5V2l0aEFyZ3MobmFtZSwgZGVsZWdhdGVUbywgLi4uYXJncykge1xuXHRcdHV0aWxzLmFkZFByb3BlcnR5KGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgbmFtZSwgZnVuY3Rpb24oKSB7XG5cdFx0XHRjb25zdCBqZXN0TWV0aG9kID0gY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlW2RlbGVnYXRlVG9dO1xuXHRcdFx0aWYgKCFqZXN0TWV0aG9kKSB7XG5cdFx0XHRcdHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGRlbGVnYXRlIHRvICR7U3RyaW5nKGRlbGVnYXRlVG8pfTogbWV0aG9kIG5vdCBmb3VuZC4gRW5zdXJlIEplc3RDaGFpRXhwZWN0IHBsdWdpbiBpcyBsb2FkZWQgZmlyc3QuYCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gamVzdE1ldGhvZC5jYWxsKHRoaXMsIC4uLmFyZ3MpO1xuXHRcdH0pO1xuXHR9XG5cdGZ1bmN0aW9uIGRlZk1ldGhvZChuYW1lLCBkZWxlZ2F0ZVRvKSB7XG5cdFx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgbmFtZSwgZnVuY3Rpb24oLi4uYXJncykge1xuXHRcdFx0Y29uc3QgamVzdE1ldGhvZCA9IGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZVtkZWxlZ2F0ZVRvXTtcblx0XHRcdGlmICghamVzdE1ldGhvZCkge1xuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBkZWxlZ2F0ZSB0byAke1N0cmluZyhkZWxlZ2F0ZVRvKX06IG1ldGhvZCBub3QgZm91bmQuIEVuc3VyZSBKZXN0Q2hhaUV4cGVjdCBwbHVnaW4gaXMgbG9hZGVkIGZpcnN0LmApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGplc3RNZXRob2QuY2FsbCh0aGlzLCAuLi5hcmdzKTtcblx0XHR9KTtcblx0fVxuXHQvLyBBUEkgdG8gKHNvbWV3aGF0KSBtaXJyb3Igc2lub24tY2hhaVxuXHQvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhaWpzL3Npbm9uLWNoYWlcblx0ZGVmUHJvcGVydHkoXCJjYWxsZWRcIiwgXCJ0b0hhdmVCZWVuQ2FsbGVkXCIpO1xuXHRkZWZQcm9wZXJ0eShcImNhbGxlZE9uY2VcIiwgXCJ0b0hhdmVCZWVuQ2FsbGVkT25jZVwiKTtcblx0ZGVmUHJvcGVydHlXaXRoQXJncyhcImNhbGxlZFR3aWNlXCIsIFwidG9IYXZlQmVlbkNhbGxlZFRpbWVzXCIsIDIpO1xuXHRkZWZQcm9wZXJ0eVdpdGhBcmdzKFwiY2FsbGVkVGhyaWNlXCIsIFwidG9IYXZlQmVlbkNhbGxlZFRpbWVzXCIsIDMpO1xuXHRkZWZNZXRob2QoXCJjYWxsQ291bnRcIiwgXCJ0b0hhdmVCZWVuQ2FsbGVkVGltZXNcIik7XG5cdGRlZk1ldGhvZChcImNhbGxlZFdpdGhcIiwgXCJ0b0hhdmVCZWVuQ2FsbGVkV2l0aFwiKTtcblx0ZGVmTWV0aG9kKFwiY2FsbGVkT25jZVdpdGhcIiwgXCJ0b0hhdmVCZWVuQ2FsbGVkRXhhY3RseU9uY2VXaXRoXCIpO1xuXHRkZWZNZXRob2QoXCJsYXN0Q2FsbGVkV2l0aFwiLCBcInRvSGF2ZUJlZW5MYXN0Q2FsbGVkV2l0aFwiKTtcblx0ZGVmTWV0aG9kKFwibnRoQ2FsbGVkV2l0aFwiLCBcInRvSGF2ZUJlZW5OdGhDYWxsZWRXaXRoXCIpO1xuXHRkZWZNZXRob2QoXCJyZXR1cm5lZFwiLCBcInRvSGF2ZVJldHVybmVkXCIpO1xuXHRkZWZNZXRob2QoXCJyZXR1cm5lZFdpdGhcIiwgXCJ0b0hhdmVSZXR1cm5lZFdpdGhcIik7XG5cdGRlZk1ldGhvZChcInJldHVybmVkVGltZXNcIiwgXCJ0b0hhdmVSZXR1cm5lZFRpbWVzXCIpO1xuXHRkZWZNZXRob2QoXCJsYXN0UmV0dXJuZWRXaXRoXCIsIFwidG9IYXZlTGFzdFJldHVybmVkV2l0aFwiKTtcblx0ZGVmTWV0aG9kKFwibnRoUmV0dXJuZWRXaXRoXCIsIFwidG9IYXZlTnRoUmV0dXJuZWRXaXRoXCIpO1xuXHRkZWZNZXRob2QoXCJjYWxsZWRCZWZvcmVcIiwgXCJ0b0hhdmVCZWVuQ2FsbGVkQmVmb3JlXCIpO1xuXHRkZWZNZXRob2QoXCJjYWxsZWRBZnRlclwiLCBcInRvSGF2ZUJlZW5DYWxsZWRBZnRlclwiKTtcblx0Ly8gVE9ETzogaW1wbGVtZW50XG5cdC8vIGRlZk1ldGhvZCgndGhyb3duJywgJ3RvSGF2ZVRocm93bicpXG59O1xuXG5jb25zdCBNQVRDSEVSU19PQkpFQ1QgPSBTeW1ib2wuZm9yKFwibWF0Y2hlcnMtb2JqZWN0XCIpO1xuY29uc3QgSkVTVF9NQVRDSEVSU19PQkpFQ1QgPSBTeW1ib2wuZm9yKFwiJCRqZXN0LW1hdGNoZXJzLW9iamVjdFwiKTtcbmNvbnN0IEdMT0JBTF9FWFBFQ1QgPSBTeW1ib2wuZm9yKFwiZXhwZWN0LWdsb2JhbFwiKTtcbmNvbnN0IEFTWU1NRVRSSUNfTUFUQ0hFUlNfT0JKRUNUID0gU3ltYm9sLmZvcihcImFzeW1tZXRyaWMtbWF0Y2hlcnMtb2JqZWN0XCIpO1xuXG4vLyBzZWxlY3RpdmVseSBwb3J0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vamVzdC1jb21tdW5pdHkvamVzdC1leHRlbmRlZFxuY29uc3QgY3VzdG9tTWF0Y2hlcnMgPSB7XG5cdHRvU2F0aXNmeShhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG5cdFx0Y29uc3QgeyBwcmludFJlY2VpdmVkLCBwcmludEV4cGVjdGVkLCBtYXRjaGVySGludCB9ID0gdGhpcy51dGlscztcblx0XHRjb25zdCBwYXNzID0gZXhwZWN0ZWQoYWN0dWFsKTtcblx0XHRyZXR1cm4ge1xuXHRcdFx0cGFzcyxcblx0XHRcdG1lc3NhZ2U6ICgpID0+IHBhc3MgPyBgXFxcbiR7bWF0Y2hlckhpbnQoXCIubm90LnRvU2F0aXNmeVwiLCBcInJlY2VpdmVkXCIsIFwiXCIpfVxuXG5FeHBlY3RlZCB2YWx1ZSB0byBub3Qgc2F0aXNmeTpcbiR7bWVzc2FnZSB8fCBwcmludEV4cGVjdGVkKGV4cGVjdGVkKX1cblJlY2VpdmVkOlxuJHtwcmludFJlY2VpdmVkKGFjdHVhbCl9YCA6IGBcXFxuJHttYXRjaGVySGludChcIi50b1NhdGlzZnlcIiwgXCJyZWNlaXZlZFwiLCBcIlwiKX1cblxuRXhwZWN0ZWQgdmFsdWUgdG8gc2F0aXNmeTpcbiR7bWVzc2FnZSB8fCBwcmludEV4cGVjdGVkKGV4cGVjdGVkKX1cblxuUmVjZWl2ZWQ6XG4ke3ByaW50UmVjZWl2ZWQoYWN0dWFsKX1gXG5cdFx0fTtcblx0fSxcblx0dG9CZU9uZU9mKGFjdHVhbCwgZXhwZWN0ZWQpIHtcblx0XHRjb25zdCB7IGVxdWFscywgY3VzdG9tVGVzdGVycyB9ID0gdGhpcztcblx0XHRjb25zdCB7IHByaW50UmVjZWl2ZWQsIHByaW50RXhwZWN0ZWQsIG1hdGNoZXJIaW50IH0gPSB0aGlzLnV0aWxzO1xuXHRcdGxldCBwYXNzO1xuXHRcdGlmIChBcnJheS5pc0FycmF5KGV4cGVjdGVkKSkge1xuXHRcdFx0cGFzcyA9IGV4cGVjdGVkLmxlbmd0aCA9PT0gMCB8fCBleHBlY3RlZC5zb21lKChpdGVtKSA9PiBlcXVhbHMoaXRlbSwgYWN0dWFsLCBjdXN0b21UZXN0ZXJzKSk7XG5cdFx0fSBlbHNlIGlmIChleHBlY3RlZCBpbnN0YW5jZW9mIFNldCkge1xuXHRcdFx0cGFzcyA9IGV4cGVjdGVkLnNpemUgPT09IDAgfHwgZXhwZWN0ZWQuaGFzKGFjdHVhbCkgfHwgWy4uLmV4cGVjdGVkXS5zb21lKChpdGVtKSA9PiBlcXVhbHMoaXRlbSwgYWN0dWFsLCBjdXN0b21UZXN0ZXJzKSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYFlvdSBtdXN0IHByb3ZpZGUgYW4gYXJyYXkgb3Igc2V0IHRvICR7bWF0Y2hlckhpbnQoXCIudG9CZU9uZU9mXCIpfSwgbm90ICcke3R5cGVvZiBleHBlY3RlZH0nLmApO1xuXHRcdH1cblx0XHRyZXR1cm4ge1xuXHRcdFx0cGFzcyxcblx0XHRcdG1lc3NhZ2U6ICgpID0+IHBhc3MgPyBgXFxcbiR7bWF0Y2hlckhpbnQoXCIubm90LnRvQmVPbmVPZlwiLCBcInJlY2VpdmVkXCIsIFwiXCIpfVxuXG5FeHBlY3RlZCB2YWx1ZSB0byBub3QgYmUgb25lIG9mOlxuJHtwcmludEV4cGVjdGVkKGV4cGVjdGVkKX1cblJlY2VpdmVkOlxuJHtwcmludFJlY2VpdmVkKGFjdHVhbCl9YCA6IGBcXFxuJHttYXRjaGVySGludChcIi50b0JlT25lT2ZcIiwgXCJyZWNlaXZlZFwiLCBcIlwiKX1cblxuRXhwZWN0ZWQgdmFsdWUgdG8gYmUgb25lIG9mOlxuJHtwcmludEV4cGVjdGVkKGV4cGVjdGVkKX1cblxuUmVjZWl2ZWQ6XG4ke3ByaW50UmVjZWl2ZWQoYWN0dWFsKX1gXG5cdFx0fTtcblx0fVxufTtcblxuY29uc3QgRVhQRUNURURfQ09MT1IgPSBjLmdyZWVuO1xuY29uc3QgUkVDRUlWRURfQ09MT1IgPSBjLnJlZDtcbmNvbnN0IElOVkVSVEVEX0NPTE9SID0gYy5pbnZlcnNlO1xuY29uc3QgQk9MRF9XRUlHSFQgPSBjLmJvbGQ7XG5jb25zdCBESU1fQ09MT1IgPSBjLmRpbTtcbmZ1bmN0aW9uIG1hdGNoZXJIaW50KG1hdGNoZXJOYW1lLCByZWNlaXZlZCA9IFwicmVjZWl2ZWRcIiwgZXhwZWN0ZWQgPSBcImV4cGVjdGVkXCIsIG9wdGlvbnMgPSB7fSkge1xuXHRjb25zdCB7IGNvbW1lbnQgPSBcIlwiLCBpc0RpcmVjdEV4cGVjdENhbGwgPSBmYWxzZSwgaXNOb3QgPSBmYWxzZSwgcHJvbWlzZSA9IFwiXCIsIHNlY29uZEFyZ3VtZW50ID0gXCJcIiwgZXhwZWN0ZWRDb2xvciA9IEVYUEVDVEVEX0NPTE9SLCByZWNlaXZlZENvbG9yID0gUkVDRUlWRURfQ09MT1IsIHNlY29uZEFyZ3VtZW50Q29sb3IgPSBFWFBFQ1RFRF9DT0xPUiB9ID0gb3B0aW9ucztcblx0bGV0IGhpbnQgPSBcIlwiO1xuXHRsZXQgZGltU3RyaW5nID0gXCJleHBlY3RcIjtcblx0aWYgKCFpc0RpcmVjdEV4cGVjdENhbGwgJiYgcmVjZWl2ZWQgIT09IFwiXCIpIHtcblx0XHRoaW50ICs9IERJTV9DT0xPUihgJHtkaW1TdHJpbmd9KGApICsgcmVjZWl2ZWRDb2xvcihyZWNlaXZlZCk7XG5cdFx0ZGltU3RyaW5nID0gXCIpXCI7XG5cdH1cblx0aWYgKHByb21pc2UgIT09IFwiXCIpIHtcblx0XHRoaW50ICs9IERJTV9DT0xPUihgJHtkaW1TdHJpbmd9LmApICsgcHJvbWlzZTtcblx0XHRkaW1TdHJpbmcgPSBcIlwiO1xuXHR9XG5cdGlmIChpc05vdCkge1xuXHRcdGhpbnQgKz0gYCR7RElNX0NPTE9SKGAke2RpbVN0cmluZ30uYCl9bm90YDtcblx0XHRkaW1TdHJpbmcgPSBcIlwiO1xuXHR9XG5cdGlmIChtYXRjaGVyTmFtZS5pbmNsdWRlcyhcIi5cIikpIHtcblx0XHQvLyBPbGQgZm9ybWF0OiBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSxcblx0XHQvLyBlc3BlY2lhbGx5IHdpdGhvdXQgcHJvbWlzZSBvciBpc05vdCBvcHRpb25zXG5cdFx0ZGltU3RyaW5nICs9IG1hdGNoZXJOYW1lO1xuXHR9IGVsc2Uge1xuXHRcdC8vIE5ldyBmb3JtYXQ6IG9taXQgcGVyaW9kIGZyb20gbWF0Y2hlck5hbWUgYXJnXG5cdFx0aGludCArPSBESU1fQ09MT1IoYCR7ZGltU3RyaW5nfS5gKSArIG1hdGNoZXJOYW1lO1xuXHRcdGRpbVN0cmluZyA9IFwiXCI7XG5cdH1cblx0aWYgKGV4cGVjdGVkID09PSBcIlwiKSB7XG5cdFx0ZGltU3RyaW5nICs9IFwiKClcIjtcblx0fSBlbHNlIHtcblx0XHRoaW50ICs9IERJTV9DT0xPUihgJHtkaW1TdHJpbmd9KGApICsgZXhwZWN0ZWRDb2xvcihleHBlY3RlZCk7XG5cdFx0aWYgKHNlY29uZEFyZ3VtZW50KSB7XG5cdFx0XHRoaW50ICs9IERJTV9DT0xPUihcIiwgXCIpICsgc2Vjb25kQXJndW1lbnRDb2xvcihzZWNvbmRBcmd1bWVudCk7XG5cdFx0fVxuXHRcdGRpbVN0cmluZyA9IFwiKVwiO1xuXHR9XG5cdGlmIChjb21tZW50ICE9PSBcIlwiKSB7XG5cdFx0ZGltU3RyaW5nICs9IGAgLy8gJHtjb21tZW50fWA7XG5cdH1cblx0aWYgKGRpbVN0cmluZyAhPT0gXCJcIikge1xuXHRcdGhpbnQgKz0gRElNX0NPTE9SKGRpbVN0cmluZyk7XG5cdH1cblx0cmV0dXJuIGhpbnQ7XG59XG5jb25zdCBTUEFDRV9TWU1CT0wgPSBcIsK3XCI7XG4vLyBJbnN0ZWFkIG9mIGludmVyc2UgaGlnaGxpZ2h0IHdoaWNoIG5vdyBpbXBsaWVzIGEgY2hhbmdlLFxuLy8gcmVwbGFjZSBjb21tb24gc3BhY2VzIHdpdGggbWlkZGxlIGRvdCBhdCB0aGUgZW5kIG9mIGFueSBsaW5lLlxuZnVuY3Rpb24gcmVwbGFjZVRyYWlsaW5nU3BhY2VzKHRleHQpIHtcblx0cmV0dXJuIHRleHQucmVwbGFjZSgvXFxzKyQvZ20sIChzcGFjZXMpID0+IFNQQUNFX1NZTUJPTC5yZXBlYXQoc3BhY2VzLmxlbmd0aCkpO1xufVxuZnVuY3Rpb24gcHJpbnRSZWNlaXZlZChvYmplY3QpIHtcblx0cmV0dXJuIFJFQ0VJVkVEX0NPTE9SKHJlcGxhY2VUcmFpbGluZ1NwYWNlcyhzdHJpbmdpZnkob2JqZWN0KSkpO1xufVxuZnVuY3Rpb24gcHJpbnRFeHBlY3RlZCh2YWx1ZSkge1xuXHRyZXR1cm4gRVhQRUNURURfQ09MT1IocmVwbGFjZVRyYWlsaW5nU3BhY2VzKHN0cmluZ2lmeSh2YWx1ZSkpKTtcbn1cbmZ1bmN0aW9uIGdldE1hdGNoZXJVdGlscygpIHtcblx0cmV0dXJuIHtcblx0XHRFWFBFQ1RFRF9DT0xPUixcblx0XHRSRUNFSVZFRF9DT0xPUixcblx0XHRJTlZFUlRFRF9DT0xPUixcblx0XHRCT0xEX1dFSUdIVCxcblx0XHRESU1fQ09MT1IsXG5cdFx0ZGlmZixcblx0XHRtYXRjaGVySGludCxcblx0XHRwcmludFJlY2VpdmVkLFxuXHRcdHByaW50RXhwZWN0ZWQsXG5cdFx0cHJpbnREaWZmT3JTdHJpbmdpZnksXG5cdFx0cHJpbnRXaXRoVHlwZVxuXHR9O1xufVxuZnVuY3Rpb24gcHJpbnRXaXRoVHlwZShuYW1lLCB2YWx1ZSwgcHJpbnQpIHtcblx0Y29uc3QgdHlwZSA9IGdldFR5cGUodmFsdWUpO1xuXHRjb25zdCBoYXNUeXBlID0gdHlwZSAhPT0gXCJudWxsXCIgJiYgdHlwZSAhPT0gXCJ1bmRlZmluZWRcIiA/IGAke25hbWV9IGhhcyB0eXBlOiAgJHt0eXBlfVxcbmAgOiBcIlwiO1xuXHRjb25zdCBoYXNWYWx1ZSA9IGAke25hbWV9IGhhcyB2YWx1ZTogJHtwcmludCh2YWx1ZSl9YDtcblx0cmV0dXJuIGhhc1R5cGUgKyBoYXNWYWx1ZTtcbn1cbmZ1bmN0aW9uIGFkZEN1c3RvbUVxdWFsaXR5VGVzdGVycyhuZXdUZXN0ZXJzKSB7XG5cdGlmICghQXJyYXkuaXNBcnJheShuZXdUZXN0ZXJzKSkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYGV4cGVjdC5jdXN0b21FcXVhbGl0eVRlc3RlcnM6IE11c3QgYmUgc2V0IHRvIGFuIGFycmF5IG9mIFRlc3RlcnMuIFdhcyBnaXZlbiBcIiR7Z2V0VHlwZShuZXdUZXN0ZXJzKX1cImApO1xuXHR9XG5cdGdsb2JhbFRoaXNbSkVTVF9NQVRDSEVSU19PQkpFQ1RdLmN1c3RvbUVxdWFsaXR5VGVzdGVycy5wdXNoKC4uLm5ld1Rlc3RlcnMpO1xufVxuZnVuY3Rpb24gZ2V0Q3VzdG9tRXF1YWxpdHlUZXN0ZXJzKCkge1xuXHRyZXR1cm4gZ2xvYmFsVGhpc1tKRVNUX01BVENIRVJTX09CSkVDVF0uY3VzdG9tRXF1YWxpdHlUZXN0ZXJzO1xufVxuXG4vLyBFeHRyYWN0ZWQgb3V0IG9mIGphc21pbmUgMi41LjJcbmZ1bmN0aW9uIGVxdWFscyhhLCBiLCBjdXN0b21UZXN0ZXJzLCBzdHJpY3RDaGVjaykge1xuXHRjdXN0b21UZXN0ZXJzID0gY3VzdG9tVGVzdGVycyB8fCBbXTtcblx0cmV0dXJuIGVxKGEsIGIsIFtdLCBbXSwgY3VzdG9tVGVzdGVycywgc3RyaWN0Q2hlY2sgPyBoYXNLZXkgOiBoYXNEZWZpbmVkS2V5KTtcbn1cbmNvbnN0IGZ1bmN0aW9uVG9TdHJpbmcgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG5mdW5jdGlvbiBpc0FzeW1tZXRyaWMob2JqKSB7XG5cdHJldHVybiAhIW9iaiAmJiB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiICYmIFwiYXN5bW1ldHJpY01hdGNoXCIgaW4gb2JqICYmIGlzQShcIkZ1bmN0aW9uXCIsIG9iai5hc3ltbWV0cmljTWF0Y2gpO1xufVxuZnVuY3Rpb24gaGFzQXN5bW1ldHJpYyhvYmosIHNlZW4gPSBuZXcgU2V0KCkpIHtcblx0aWYgKHNlZW4uaGFzKG9iaikpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0c2Vlbi5hZGQob2JqKTtcblx0aWYgKGlzQXN5bW1ldHJpYyhvYmopKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblx0aWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuXHRcdHJldHVybiBvYmouc29tZSgoaSkgPT4gaGFzQXN5bW1ldHJpYyhpLCBzZWVuKSk7XG5cdH1cblx0aWYgKG9iaiBpbnN0YW5jZW9mIFNldCkge1xuXHRcdHJldHVybiBBcnJheS5mcm9tKG9iaikuc29tZSgoaSkgPT4gaGFzQXN5bW1ldHJpYyhpLCBzZWVuKSk7XG5cdH1cblx0aWYgKGlzT2JqZWN0KG9iaikpIHtcblx0XHRyZXR1cm4gT2JqZWN0LnZhbHVlcyhvYmopLnNvbWUoKHYpID0+IGhhc0FzeW1tZXRyaWModiwgc2VlbikpO1xuXHR9XG5cdHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIGFzeW1tZXRyaWNNYXRjaChhLCBiLCBjdXN0b21UZXN0ZXJzKSB7XG5cdGNvbnN0IGFzeW1tZXRyaWNBID0gaXNBc3ltbWV0cmljKGEpO1xuXHRjb25zdCBhc3ltbWV0cmljQiA9IGlzQXN5bW1ldHJpYyhiKTtcblx0aWYgKGFzeW1tZXRyaWNBICYmIGFzeW1tZXRyaWNCKSB7XG5cdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0fVxuXHRpZiAoYXN5bW1ldHJpY0EpIHtcblx0XHRyZXR1cm4gYS5hc3ltbWV0cmljTWF0Y2goYiwgY3VzdG9tVGVzdGVycyk7XG5cdH1cblx0aWYgKGFzeW1tZXRyaWNCKSB7XG5cdFx0cmV0dXJuIGIuYXN5bW1ldHJpY01hdGNoKGEsIGN1c3RvbVRlc3RlcnMpO1xuXHR9XG59XG4vLyBodHRwczovL2dpdGh1Yi5jb20vamVzdGpzL2plc3QvYmxvYi85MDViY2JjZWQzZDQwY2RmN2FhZGM0Y2RmNmZiNzMxYzRiYjNkYmUzL3BhY2thZ2VzL2V4cGVjdC11dGlscy9zcmMvdXRpbHMudHMjTDUwOVxuZnVuY3Rpb24gaXNFcnJvcih2YWx1ZSkge1xuXHRpZiAodHlwZW9mIEVycm9yLmlzRXJyb3IgPT09IFwiZnVuY3Rpb25cIikge1xuXHRcdHJldHVybiBFcnJvci5pc0Vycm9yKHZhbHVlKTtcblx0fVxuXHRzd2l0Y2ggKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkpIHtcblx0XHRjYXNlIFwiW29iamVjdCBFcnJvcl1cIjpcblx0XHRjYXNlIFwiW29iamVjdCBFeGNlcHRpb25dXCI6XG5cdFx0Y2FzZSBcIltvYmplY3QgRE9NRXhjZXB0aW9uXVwiOiByZXR1cm4gdHJ1ZTtcblx0XHRkZWZhdWx0OiByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBFcnJvcjtcblx0fVxufVxuLy8gRXF1YWxpdHkgZnVuY3Rpb24gbG92aW5nbHkgYWRhcHRlZCBmcm9tIGlzRXF1YWwgaW5cbi8vICAgW1VuZGVyc2NvcmVdKGh0dHA6Ly91bmRlcnNjb3JlanMub3JnKVxuZnVuY3Rpb24gZXEoYSwgYiwgYVN0YWNrLCBiU3RhY2ssIGN1c3RvbVRlc3RlcnMsIGhhc0tleSkge1xuXHRsZXQgcmVzdWx0ID0gdHJ1ZTtcblx0Y29uc3QgYXN5bW1ldHJpY1Jlc3VsdCA9IGFzeW1tZXRyaWNNYXRjaChhLCBiLCBjdXN0b21UZXN0ZXJzKTtcblx0aWYgKGFzeW1tZXRyaWNSZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBhc3ltbWV0cmljUmVzdWx0O1xuXHR9XG5cdGNvbnN0IHRlc3RlckNvbnRleHQgPSB7IGVxdWFscyB9O1xuXHRmb3IgKGxldCBpID0gMDsgaSA8IGN1c3RvbVRlc3RlcnMubGVuZ3RoOyBpKyspIHtcblx0XHRjb25zdCBjdXN0b21UZXN0ZXJSZXN1bHQgPSBjdXN0b21UZXN0ZXJzW2ldLmNhbGwodGVzdGVyQ29udGV4dCwgYSwgYiwgY3VzdG9tVGVzdGVycyk7XG5cdFx0aWYgKGN1c3RvbVRlc3RlclJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRyZXR1cm4gY3VzdG9tVGVzdGVyUmVzdWx0O1xuXHRcdH1cblx0fVxuXHRpZiAodHlwZW9mIFVSTCA9PT0gXCJmdW5jdGlvblwiICYmIGEgaW5zdGFuY2VvZiBVUkwgJiYgYiBpbnN0YW5jZW9mIFVSTCkge1xuXHRcdHJldHVybiBhLmhyZWYgPT09IGIuaHJlZjtcblx0fVxuXHRpZiAoT2JqZWN0LmlzKGEsIGIpKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblx0Ly8gQSBzdHJpY3QgY29tcGFyaXNvbiBpcyBuZWNlc3NhcnkgYmVjYXVzZSBgbnVsbCA9PSB1bmRlZmluZWRgLlxuXHRpZiAoYSA9PT0gbnVsbCB8fCBiID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIGEgPT09IGI7XG5cdH1cblx0Y29uc3QgY2xhc3NOYW1lID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGEpO1xuXHRpZiAoY2xhc3NOYW1lICE9PSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYikpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0c3dpdGNoIChjbGFzc05hbWUpIHtcblx0XHRjYXNlIFwiW29iamVjdCBCb29sZWFuXVwiOlxuXHRcdGNhc2UgXCJbb2JqZWN0IFN0cmluZ11cIjpcblx0XHRjYXNlIFwiW29iamVjdCBOdW1iZXJdXCI6IGlmICh0eXBlb2YgYSAhPT0gdHlwZW9mIGIpIHtcblx0XHRcdC8vIE9uZSBpcyBhIHByaW1pdGl2ZSwgb25lIGEgYG5ldyBQcmltaXRpdmUoKWBcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9IGVsc2UgaWYgKHR5cGVvZiBhICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiBiICE9PSBcIm9iamVjdFwiKSB7XG5cdFx0XHQvLyBib3RoIGFyZSBwcm9wZXIgcHJpbWl0aXZlc1xuXHRcdFx0cmV0dXJuIE9iamVjdC5pcyhhLCBiKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gYm90aCBhcmUgYG5ldyBQcmltaXRpdmUoKWBzXG5cdFx0XHRyZXR1cm4gT2JqZWN0LmlzKGEudmFsdWVPZigpLCBiLnZhbHVlT2YoKSk7XG5cdFx0fVxuXHRcdGNhc2UgXCJbb2JqZWN0IERhdGVdXCI6IHtcblx0XHRcdGNvbnN0IG51bUEgPSArYTtcblx0XHRcdGNvbnN0IG51bUIgPSArYjtcblx0XHRcdC8vIENvZXJjZSBkYXRlcyB0byBudW1lcmljIHByaW1pdGl2ZSB2YWx1ZXMuIERhdGVzIGFyZSBjb21wYXJlZCBieSB0aGVpclxuXHRcdFx0Ly8gbWlsbGlzZWNvbmQgcmVwcmVzZW50YXRpb25zLiBOb3RlIHRoYXQgaW52YWxpZCBkYXRlcyB3aXRoIG1pbGxpc2Vjb25kIHJlcHJlc2VudGF0aW9uc1xuXHRcdFx0Ly8gb2YgYE5hTmAgYXJlIGVxdWl2YWxlbnQuXG5cdFx0XHRyZXR1cm4gbnVtQSA9PT0gbnVtQiB8fCBOdW1iZXIuaXNOYU4obnVtQSkgJiYgTnVtYmVyLmlzTmFOKG51bUIpO1xuXHRcdH1cblx0XHRjYXNlIFwiW29iamVjdCBSZWdFeHBdXCI6IHJldHVybiBhLnNvdXJjZSA9PT0gYi5zb3VyY2UgJiYgYS5mbGFncyA9PT0gYi5mbGFncztcblx0XHRjYXNlIFwiW29iamVjdCBUZW1wb3JhbC5JbnN0YW50XVwiOlxuXHRcdGNhc2UgXCJbb2JqZWN0IFRlbXBvcmFsLlpvbmVkRGF0ZVRpbWVdXCI6XG5cdFx0Y2FzZSBcIltvYmplY3QgVGVtcG9yYWwuUGxhaW5EYXRlVGltZV1cIjpcblx0XHRjYXNlIFwiW29iamVjdCBUZW1wb3JhbC5QbGFpbkRhdGVdXCI6XG5cdFx0Y2FzZSBcIltvYmplY3QgVGVtcG9yYWwuUGxhaW5UaW1lXVwiOlxuXHRcdGNhc2UgXCJbb2JqZWN0IFRlbXBvcmFsLlBsYWluWWVhck1vbnRoXVwiOlxuXHRcdGNhc2UgXCJbb2JqZWN0IFRlbXBvcmFsLlBsYWluTW9udGhEYXldXCI6IHJldHVybiBhLmVxdWFscyhiKTtcblx0XHRjYXNlIFwiW29iamVjdCBUZW1wb3JhbC5EdXJhdGlvbl1cIjogcmV0dXJuIGEudG9TdHJpbmcoKSA9PT0gYi50b1N0cmluZygpO1xuXHR9XG5cdGlmICh0eXBlb2YgYSAhPT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgYiAhPT0gXCJvYmplY3RcIikge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHQvLyBVc2UgRE9NMyBtZXRob2QgaXNFcXVhbE5vZGUgKElFPj05KVxuXHRpZiAoaXNEb21Ob2RlKGEpICYmIGlzRG9tTm9kZShiKSkge1xuXHRcdHJldHVybiBhLmlzRXF1YWxOb2RlKGIpO1xuXHR9XG5cdC8vIFVzZWQgdG8gZGV0ZWN0IGNpcmN1bGFyIHJlZmVyZW5jZXMuXG5cdGxldCBsZW5ndGggPSBhU3RhY2subGVuZ3RoO1xuXHR3aGlsZSAobGVuZ3RoLS0pIHtcblx0XHQvLyBMaW5lYXIgc2VhcmNoLiBQZXJmb3JtYW5jZSBpcyBpbnZlcnNlbHkgcHJvcG9ydGlvbmFsIHRvIHRoZSBudW1iZXIgb2Zcblx0XHQvLyB1bmlxdWUgbmVzdGVkIHN0cnVjdHVyZXMuXG5cdFx0Ly8gY2lyY3VsYXIgcmVmZXJlbmNlcyBhdCBzYW1lIGRlcHRoIGFyZSBlcXVhbFxuXHRcdC8vIGNpcmN1bGFyIHJlZmVyZW5jZSBpcyBub3QgZXF1YWwgdG8gbm9uLWNpcmN1bGFyIG9uZVxuXHRcdGlmIChhU3RhY2tbbGVuZ3RoXSA9PT0gYSkge1xuXHRcdFx0cmV0dXJuIGJTdGFja1tsZW5ndGhdID09PSBiO1xuXHRcdH0gZWxzZSBpZiAoYlN0YWNrW2xlbmd0aF0gPT09IGIpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdH1cblx0Ly8gQWRkIHRoZSBmaXJzdCBvYmplY3QgdG8gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzLlxuXHRhU3RhY2sucHVzaChhKTtcblx0YlN0YWNrLnB1c2goYik7XG5cdC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgb2JqZWN0cyBhbmQgYXJyYXlzLlxuXHQvLyBDb21wYXJlIGFycmF5IGxlbmd0aHMgdG8gZGV0ZXJtaW5lIGlmIGEgZGVlcCBjb21wYXJpc29uIGlzIG5lY2Vzc2FyeS5cblx0aWYgKGNsYXNzTmFtZSA9PT0gXCJbb2JqZWN0IEFycmF5XVwiICYmIGEubGVuZ3RoICE9PSBiLmxlbmd0aCkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHRpZiAoaXNFcnJvcihhKSAmJiBpc0Vycm9yKGIpKSB7XG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiBpc0Vycm9yRXF1YWwoYSwgYiwgYVN0YWNrLCBiU3RhY2ssIGN1c3RvbVRlc3RlcnMsIGhhc0tleSk7XG5cdFx0fSBmaW5hbGx5IHtcblx0XHRcdGFTdGFjay5wb3AoKTtcblx0XHRcdGJTdGFjay5wb3AoKTtcblx0XHR9XG5cdH1cblx0Ly8gRGVlcCBjb21wYXJlIG9iamVjdHMuXG5cdGNvbnN0IGFLZXlzID0ga2V5cyhhLCBoYXNLZXkpO1xuXHRsZXQga2V5O1xuXHRsZXQgc2l6ZSA9IGFLZXlzLmxlbmd0aDtcblx0Ly8gRW5zdXJlIHRoYXQgYm90aCBvYmplY3RzIGNvbnRhaW4gdGhlIHNhbWUgbnVtYmVyIG9mIHByb3BlcnRpZXMgYmVmb3JlIGNvbXBhcmluZyBkZWVwIGVxdWFsaXR5LlxuXHRpZiAoa2V5cyhiLCBoYXNLZXkpLmxlbmd0aCAhPT0gc2l6ZSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR3aGlsZSAoc2l6ZS0tKSB7XG5cdFx0a2V5ID0gYUtleXNbc2l6ZV07XG5cdFx0Ly8gRGVlcCBjb21wYXJlIGVhY2ggbWVtYmVyXG5cdFx0cmVzdWx0ID0gaGFzS2V5KGIsIGtleSkgJiYgZXEoYVtrZXldLCBiW2tleV0sIGFTdGFjaywgYlN0YWNrLCBjdXN0b21UZXN0ZXJzLCBoYXNLZXkpO1xuXHRcdGlmICghcmVzdWx0KSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cdC8vIFJlbW92ZSB0aGUgZmlyc3Qgb2JqZWN0IGZyb20gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzLlxuXHRhU3RhY2sucG9wKCk7XG5cdGJTdGFjay5wb3AoKTtcblx0cmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIGlzRXJyb3JFcXVhbChhLCBiLCBhU3RhY2ssIGJTdGFjaywgY3VzdG9tVGVzdGVycywgaGFzS2V5KSB7XG5cdC8vIGh0dHBzOi8vbm9kZWpzLm9yZy9kb2NzL2xhdGVzdC12MjIueC9hcGkvYXNzZXJ0Lmh0bWwjY29tcGFyaXNvbi1kZXRhaWxzXG5cdC8vIC0gW1tQcm90b3R5cGVdXSBvZiBvYmplY3RzIGFyZSBjb21wYXJlZCB1c2luZyB0aGUgPT09IG9wZXJhdG9yLlxuXHQvLyAtIE9ubHkgZW51bWVyYWJsZSBcIm93blwiIHByb3BlcnRpZXMgYXJlIGNvbnNpZGVyZWQuXG5cdC8vIC0gRXJyb3IgbmFtZXMsIG1lc3NhZ2VzLCBjYXVzZXMsIGFuZCBlcnJvcnMgYXJlIGFsd2F5cyBjb21wYXJlZCwgZXZlbiBpZiB0aGVzZSBhcmUgbm90IGVudW1lcmFibGUgcHJvcGVydGllcy4gZXJyb3JzIGlzIGFsc28gY29tcGFyZWQuXG5cdGxldCByZXN1bHQgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYSkgPT09IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChiKSAmJiBhLm5hbWUgPT09IGIubmFtZSAmJiBhLm1lc3NhZ2UgPT09IGIubWVzc2FnZTtcblx0Ly8gY2hlY2sgRXJyb3IuY2F1c2UgYXN5bW1ldHJpY2FsbHlcblx0aWYgKHR5cGVvZiBiLmNhdXNlICE9PSBcInVuZGVmaW5lZFwiKSB7XG5cdFx0cmVzdWx0ICYmPSBlcShhLmNhdXNlLCBiLmNhdXNlLCBhU3RhY2ssIGJTdGFjaywgY3VzdG9tVGVzdGVycywgaGFzS2V5KTtcblx0fVxuXHQvLyBBZ2dyZWdhdGVFcnJvci5lcnJvcnNcblx0aWYgKGEgaW5zdGFuY2VvZiBBZ2dyZWdhdGVFcnJvciAmJiBiIGluc3RhbmNlb2YgQWdncmVnYXRlRXJyb3IpIHtcblx0XHRyZXN1bHQgJiY9IGVxKGEuZXJyb3JzLCBiLmVycm9ycywgYVN0YWNrLCBiU3RhY2ssIGN1c3RvbVRlc3RlcnMsIGhhc0tleSk7XG5cdH1cblx0Ly8gc3ByZWFkIHRvIGNvbXBhcmUgZW51bWVyYWJsZSBwcm9wZXJ0aWVzXG5cdHJlc3VsdCAmJj0gZXEoeyAuLi5hIH0sIHsgLi4uYiB9LCBhU3RhY2ssIGJTdGFjaywgY3VzdG9tVGVzdGVycywgaGFzS2V5KTtcblx0cmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIGtleXMob2JqLCBoYXNLZXkpIHtcblx0Y29uc3Qga2V5cyA9IFtdO1xuXHRmb3IgKGNvbnN0IGtleSBpbiBvYmopIHtcblx0XHRpZiAoaGFzS2V5KG9iaiwga2V5KSkge1xuXHRcdFx0a2V5cy5wdXNoKGtleSk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBrZXlzLmNvbmNhdChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKG9iaikuZmlsdGVyKChzeW1ib2wpID0+IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBzeW1ib2wpLmVudW1lcmFibGUpKTtcbn1cbmZ1bmN0aW9uIGhhc0RlZmluZWRLZXkob2JqLCBrZXkpIHtcblx0cmV0dXJuIGhhc0tleShvYmosIGtleSkgJiYgb2JqW2tleV0gIT09IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIGhhc0tleShvYmosIGtleSkge1xuXHRyZXR1cm4gT2JqZWN0Lmhhc093bihvYmosIGtleSk7XG59XG5mdW5jdGlvbiBpc0EodHlwZU5hbWUsIHZhbHVlKSB7XG5cdHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmFwcGx5KHZhbHVlKSA9PT0gYFtvYmplY3QgJHt0eXBlTmFtZX1dYDtcbn1cbmZ1bmN0aW9uIGlzRG9tTm9kZShvYmopIHtcblx0cmV0dXJuIG9iaiAhPT0gbnVsbCAmJiB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiICYmIFwibm9kZVR5cGVcIiBpbiBvYmogJiYgdHlwZW9mIG9iai5ub2RlVHlwZSA9PT0gXCJudW1iZXJcIiAmJiBcIm5vZGVOYW1lXCIgaW4gb2JqICYmIHR5cGVvZiBvYmoubm9kZU5hbWUgPT09IFwic3RyaW5nXCIgJiYgXCJpc0VxdWFsTm9kZVwiIGluIG9iaiAmJiB0eXBlb2Ygb2JqLmlzRXF1YWxOb2RlID09PSBcImZ1bmN0aW9uXCI7XG59XG5mdW5jdGlvbiBmbk5hbWVGb3IoZnVuYykge1xuXHRpZiAoZnVuYy5uYW1lKSB7XG5cdFx0cmV0dXJuIGZ1bmMubmFtZTtcblx0fVxuXHRjb25zdCBtYXRjaGVzID0gZnVuY3Rpb25Ub1N0cmluZy5jYWxsKGZ1bmMpLm1hdGNoKC9eKD86YXN5bmMpP1xccypmdW5jdGlvblxccyooPzpcXCpcXHMqKT8oW1xcdyRdKylcXHMqXFwoLyk7XG5cdHJldHVybiBtYXRjaGVzID8gbWF0Y2hlc1sxXSA6IFwiPGFub255bW91cz5cIjtcbn1cbmZ1bmN0aW9uIGdldFByb3RvdHlwZShvYmopIHtcblx0aWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZikge1xuXHRcdHJldHVybiBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKTtcblx0fVxuXHRpZiAob2JqLmNvbnN0cnVjdG9yLnByb3RvdHlwZSA9PT0gb2JqKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblx0cmV0dXJuIG9iai5jb25zdHJ1Y3Rvci5wcm90b3R5cGU7XG59XG5mdW5jdGlvbiBoYXNQcm9wZXJ0eShvYmosIHByb3BlcnR5KSB7XG5cdGlmICghb2JqKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdGlmIChPYmplY3QuaGFzT3duKG9iaiwgcHJvcGVydHkpKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblx0cmV0dXJuIGhhc1Byb3BlcnR5KGdldFByb3RvdHlwZShvYmopLCBwcm9wZXJ0eSk7XG59XG4vLyBTRU5USU5FTCBjb25zdGFudHMgYXJlIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL2ltbXV0YWJsZS1qc1xuY29uc3QgSVNfS0VZRURfU0VOVElORUwgPSBcIkBAX19JTU1VVEFCTEVfS0VZRURfX0BAXCI7XG5jb25zdCBJU19TRVRfU0VOVElORUwgPSBcIkBAX19JTU1VVEFCTEVfU0VUX19AQFwiO1xuY29uc3QgSVNfTElTVF9TRU5USU5FTCA9IFwiQEBfX0lNTVVUQUJMRV9MSVNUX19AQFwiO1xuY29uc3QgSVNfT1JERVJFRF9TRU5USU5FTCA9IFwiQEBfX0lNTVVUQUJMRV9PUkRFUkVEX19AQFwiO1xuY29uc3QgSVNfUkVDT1JEX1NZTUJPTCA9IFwiQEBfX0lNTVVUQUJMRV9SRUNPUkRfX0BAXCI7XG5mdW5jdGlvbiBpc0ltbXV0YWJsZVVub3JkZXJlZEtleWVkKG1heWJlS2V5ZWQpIHtcblx0cmV0dXJuICEhKG1heWJlS2V5ZWQgJiYgbWF5YmVLZXllZFtJU19LRVlFRF9TRU5USU5FTF0gJiYgIW1heWJlS2V5ZWRbSVNfT1JERVJFRF9TRU5USU5FTF0pO1xufVxuZnVuY3Rpb24gaXNJbW11dGFibGVVbm9yZGVyZWRTZXQobWF5YmVTZXQpIHtcblx0cmV0dXJuICEhKG1heWJlU2V0ICYmIG1heWJlU2V0W0lTX1NFVF9TRU5USU5FTF0gJiYgIW1heWJlU2V0W0lTX09SREVSRURfU0VOVElORUxdKTtcbn1cbmZ1bmN0aW9uIGlzT2JqZWN0TGl0ZXJhbChzb3VyY2UpIHtcblx0cmV0dXJuIHNvdXJjZSAhPSBudWxsICYmIHR5cGVvZiBzb3VyY2UgPT09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkoc291cmNlKTtcbn1cbmZ1bmN0aW9uIGlzSW1tdXRhYmxlTGlzdChzb3VyY2UpIHtcblx0cmV0dXJuIEJvb2xlYW4oc291cmNlICYmIGlzT2JqZWN0TGl0ZXJhbChzb3VyY2UpICYmIHNvdXJjZVtJU19MSVNUX1NFTlRJTkVMXSk7XG59XG5mdW5jdGlvbiBpc0ltbXV0YWJsZU9yZGVyZWRLZXllZChzb3VyY2UpIHtcblx0cmV0dXJuIEJvb2xlYW4oc291cmNlICYmIGlzT2JqZWN0TGl0ZXJhbChzb3VyY2UpICYmIHNvdXJjZVtJU19LRVlFRF9TRU5USU5FTF0gJiYgc291cmNlW0lTX09SREVSRURfU0VOVElORUxdKTtcbn1cbmZ1bmN0aW9uIGlzSW1tdXRhYmxlT3JkZXJlZFNldChzb3VyY2UpIHtcblx0cmV0dXJuIEJvb2xlYW4oc291cmNlICYmIGlzT2JqZWN0TGl0ZXJhbChzb3VyY2UpICYmIHNvdXJjZVtJU19TRVRfU0VOVElORUxdICYmIHNvdXJjZVtJU19PUkRFUkVEX1NFTlRJTkVMXSk7XG59XG5mdW5jdGlvbiBpc0ltbXV0YWJsZVJlY29yZChzb3VyY2UpIHtcblx0cmV0dXJuIEJvb2xlYW4oc291cmNlICYmIGlzT2JqZWN0TGl0ZXJhbChzb3VyY2UpICYmIHNvdXJjZVtJU19SRUNPUkRfU1lNQk9MXSk7XG59XG4vKipcbiogQ29weXJpZ2h0IChjKSBGYWNlYm9vaywgSW5jLiBhbmQgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4qXG4qIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuXG4qXG4qL1xuY29uc3QgSXRlcmF0b3JTeW1ib2wgPSBTeW1ib2wuaXRlcmF0b3I7XG5mdW5jdGlvbiBoYXNJdGVyYXRvcihvYmplY3QpIHtcblx0cmV0dXJuICEhKG9iamVjdCAhPSBudWxsICYmIG9iamVjdFtJdGVyYXRvclN5bWJvbF0pO1xufVxuZnVuY3Rpb24gaXRlcmFibGVFcXVhbGl0eShhLCBiLCBjdXN0b21UZXN0ZXJzID0gW10sIGFTdGFjayA9IFtdLCBiU3RhY2sgPSBbXSkge1xuXHRpZiAodHlwZW9mIGEgIT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIGIgIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShhKSB8fCBBcnJheS5pc0FycmF5KGIpIHx8ICFoYXNJdGVyYXRvcihhKSB8fCAhaGFzSXRlcmF0b3IoYikpIHtcblx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHR9XG5cdGlmIChhLmNvbnN0cnVjdG9yICE9PSBiLmNvbnN0cnVjdG9yKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdGxldCBsZW5ndGggPSBhU3RhY2subGVuZ3RoO1xuXHR3aGlsZSAobGVuZ3RoLS0pIHtcblx0XHQvLyBMaW5lYXIgc2VhcmNoLiBQZXJmb3JtYW5jZSBpcyBpbnZlcnNlbHkgcHJvcG9ydGlvbmFsIHRvIHRoZSBudW1iZXIgb2Zcblx0XHQvLyB1bmlxdWUgbmVzdGVkIHN0cnVjdHVyZXMuXG5cdFx0Ly8gY2lyY3VsYXIgcmVmZXJlbmNlcyBhdCBzYW1lIGRlcHRoIGFyZSBlcXVhbFxuXHRcdC8vIGNpcmN1bGFyIHJlZmVyZW5jZSBpcyBub3QgZXF1YWwgdG8gbm9uLWNpcmN1bGFyIG9uZVxuXHRcdGlmIChhU3RhY2tbbGVuZ3RoXSA9PT0gYSkge1xuXHRcdFx0cmV0dXJuIGJTdGFja1tsZW5ndGhdID09PSBiO1xuXHRcdH1cblx0fVxuXHRhU3RhY2sucHVzaChhKTtcblx0YlN0YWNrLnB1c2goYik7XG5cdGNvbnN0IGZpbHRlcmVkQ3VzdG9tVGVzdGVycyA9IFsuLi5jdXN0b21UZXN0ZXJzLmZpbHRlcigodCkgPT4gdCAhPT0gaXRlcmFibGVFcXVhbGl0eSksIGl0ZXJhYmxlRXF1YWxpdHlXaXRoU3RhY2tdO1xuXHRmdW5jdGlvbiBpdGVyYWJsZUVxdWFsaXR5V2l0aFN0YWNrKGEsIGIpIHtcblx0XHRyZXR1cm4gaXRlcmFibGVFcXVhbGl0eShhLCBiLCBbLi4uY3VzdG9tVGVzdGVyc10sIFsuLi5hU3RhY2tdLCBbLi4uYlN0YWNrXSk7XG5cdH1cblx0aWYgKGEuc2l6ZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0aWYgKGEuc2l6ZSAhPT0gYi5zaXplKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fSBlbHNlIGlmIChpc0EoXCJTZXRcIiwgYSkgfHwgaXNJbW11dGFibGVVbm9yZGVyZWRTZXQoYSkpIHtcblx0XHRcdGxldCBhbGxGb3VuZCA9IHRydWU7XG5cdFx0XHRmb3IgKGNvbnN0IGFWYWx1ZSBvZiBhKSB7XG5cdFx0XHRcdGlmICghYi5oYXMoYVZhbHVlKSkge1xuXHRcdFx0XHRcdGxldCBoYXMgPSBmYWxzZTtcblx0XHRcdFx0XHRmb3IgKGNvbnN0IGJWYWx1ZSBvZiBiKSB7XG5cdFx0XHRcdFx0XHRjb25zdCBpc0VxdWFsID0gZXF1YWxzKGFWYWx1ZSwgYlZhbHVlLCBmaWx0ZXJlZEN1c3RvbVRlc3RlcnMpO1xuXHRcdFx0XHRcdFx0aWYgKGlzRXF1YWwgPT09IHRydWUpIHtcblx0XHRcdFx0XHRcdFx0aGFzID0gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKGhhcyA9PT0gZmFsc2UpIHtcblx0XHRcdFx0XHRcdGFsbEZvdW5kID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdC8vIFJlbW92ZSB0aGUgZmlyc3QgdmFsdWUgZnJvbSB0aGUgc3RhY2sgb2YgdHJhdmVyc2VkIHZhbHVlcy5cblx0XHRcdGFTdGFjay5wb3AoKTtcblx0XHRcdGJTdGFjay5wb3AoKTtcblx0XHRcdHJldHVybiBhbGxGb3VuZDtcblx0XHR9IGVsc2UgaWYgKGlzQShcIk1hcFwiLCBhKSB8fCBpc0ltbXV0YWJsZVVub3JkZXJlZEtleWVkKGEpKSB7XG5cdFx0XHRsZXQgYWxsRm91bmQgPSB0cnVlO1xuXHRcdFx0Zm9yIChjb25zdCBhRW50cnkgb2YgYSkge1xuXHRcdFx0XHRpZiAoIWIuaGFzKGFFbnRyeVswXSkgfHwgIWVxdWFscyhhRW50cnlbMV0sIGIuZ2V0KGFFbnRyeVswXSksIGZpbHRlcmVkQ3VzdG9tVGVzdGVycykpIHtcblx0XHRcdFx0XHRsZXQgaGFzID0gZmFsc2U7XG5cdFx0XHRcdFx0Zm9yIChjb25zdCBiRW50cnkgb2YgYikge1xuXHRcdFx0XHRcdFx0Y29uc3QgbWF0Y2hlZEtleSA9IGVxdWFscyhhRW50cnlbMF0sIGJFbnRyeVswXSwgZmlsdGVyZWRDdXN0b21UZXN0ZXJzKTtcblx0XHRcdFx0XHRcdGxldCBtYXRjaGVkVmFsdWUgPSBmYWxzZTtcblx0XHRcdFx0XHRcdGlmIChtYXRjaGVkS2V5ID09PSB0cnVlKSB7XG5cdFx0XHRcdFx0XHRcdG1hdGNoZWRWYWx1ZSA9IGVxdWFscyhhRW50cnlbMV0sIGJFbnRyeVsxXSwgZmlsdGVyZWRDdXN0b21UZXN0ZXJzKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGlmIChtYXRjaGVkVmFsdWUgPT09IHRydWUpIHtcblx0XHRcdFx0XHRcdFx0aGFzID0gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKGhhcyA9PT0gZmFsc2UpIHtcblx0XHRcdFx0XHRcdGFsbEZvdW5kID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdC8vIFJlbW92ZSB0aGUgZmlyc3QgdmFsdWUgZnJvbSB0aGUgc3RhY2sgb2YgdHJhdmVyc2VkIHZhbHVlcy5cblx0XHRcdGFTdGFjay5wb3AoKTtcblx0XHRcdGJTdGFjay5wb3AoKTtcblx0XHRcdHJldHVybiBhbGxGb3VuZDtcblx0XHR9XG5cdH1cblx0Y29uc3QgYkl0ZXJhdG9yID0gYltJdGVyYXRvclN5bWJvbF0oKTtcblx0Zm9yIChjb25zdCBhVmFsdWUgb2YgYSkge1xuXHRcdGNvbnN0IG5leHRCID0gYkl0ZXJhdG9yLm5leHQoKTtcblx0XHRpZiAobmV4dEIuZG9uZSB8fCAhZXF1YWxzKGFWYWx1ZSwgbmV4dEIudmFsdWUsIGZpbHRlcmVkQ3VzdG9tVGVzdGVycykpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdH1cblx0aWYgKCFiSXRlcmF0b3IubmV4dCgpLmRvbmUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0aWYgKCFpc0ltbXV0YWJsZUxpc3QoYSkgJiYgIWlzSW1tdXRhYmxlT3JkZXJlZEtleWVkKGEpICYmICFpc0ltbXV0YWJsZU9yZGVyZWRTZXQoYSkgJiYgIWlzSW1tdXRhYmxlUmVjb3JkKGEpKSB7XG5cdFx0Y29uc3QgYUVudHJpZXMgPSBPYmplY3QuZW50cmllcyhhKTtcblx0XHRjb25zdCBiRW50cmllcyA9IE9iamVjdC5lbnRyaWVzKGIpO1xuXHRcdGlmICghZXF1YWxzKGFFbnRyaWVzLCBiRW50cmllcywgZmlsdGVyZWRDdXN0b21UZXN0ZXJzKSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fVxuXHQvLyBSZW1vdmUgdGhlIGZpcnN0IHZhbHVlIGZyb20gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCB2YWx1ZXMuXG5cdGFTdGFjay5wb3AoKTtcblx0YlN0YWNrLnBvcCgpO1xuXHRyZXR1cm4gdHJ1ZTtcbn1cbi8qKlxuKiBDaGVja3MgaWYgYGhhc093blByb3BlcnR5KG9iamVjdCwga2V5KWAgdXAgdGhlIHByb3RvdHlwZSBjaGFpbiwgc3RvcHBpbmcgYXQgYE9iamVjdC5wcm90b3R5cGVgLlxuKi9cbmZ1bmN0aW9uIGhhc1Byb3BlcnR5SW5PYmplY3Qob2JqZWN0LCBrZXkpIHtcblx0Y29uc3Qgc2hvdWxkVGVybWluYXRlID0gIW9iamVjdCB8fCB0eXBlb2Ygb2JqZWN0ICE9PSBcIm9iamVjdFwiIHx8IG9iamVjdCA9PT0gT2JqZWN0LnByb3RvdHlwZTtcblx0aWYgKHNob3VsZFRlcm1pbmF0ZSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHRyZXR1cm4gT2JqZWN0Lmhhc093bihvYmplY3QsIGtleSkgfHwgaGFzUHJvcGVydHlJbk9iamVjdChPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KSwga2V5KTtcbn1cbmZ1bmN0aW9uIGlzT2JqZWN0V2l0aEtleXMoYSkge1xuXHRyZXR1cm4gaXNPYmplY3QoYSkgJiYgIWlzRXJyb3IoYSkgJiYgIUFycmF5LmlzQXJyYXkoYSkgJiYgIShhIGluc3RhbmNlb2YgRGF0ZSkgJiYgIShhIGluc3RhbmNlb2YgU2V0KSAmJiAhKGEgaW5zdGFuY2VvZiBNYXApO1xufVxuZnVuY3Rpb24gc3Vic2V0RXF1YWxpdHkob2JqZWN0LCBzdWJzZXQsIGN1c3RvbVRlc3RlcnMgPSBbXSkge1xuXHRjb25zdCBmaWx0ZXJlZEN1c3RvbVRlc3RlcnMgPSBjdXN0b21UZXN0ZXJzLmZpbHRlcigodCkgPT4gdCAhPT0gc3Vic2V0RXF1YWxpdHkpO1xuXHQvLyBzdWJzZXRFcXVhbGl0eSBuZWVkcyB0byBrZWVwIHRyYWNrIG9mIHRoZSByZWZlcmVuY2VzXG5cdC8vIGl0IGhhcyBhbHJlYWR5IHZpc2l0ZWQgdG8gYXZvaWQgaW5maW5pdGUgbG9vcHMgaW4gY2FzZVxuXHQvLyB0aGVyZSBhcmUgY2lyY3VsYXIgcmVmZXJlbmNlcyBpbiB0aGUgc3Vic2V0IHBhc3NlZCB0byBpdC5cblx0Y29uc3Qgc3Vic2V0RXF1YWxpdHlXaXRoQ29udGV4dCA9IChzZWVuUmVmZXJlbmNlcyA9IG5ldyBXZWFrTWFwKCkpID0+IChvYmplY3QsIHN1YnNldCkgPT4ge1xuXHRcdGlmICghaXNPYmplY3RXaXRoS2V5cyhzdWJzZXQpKSB7XG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRyZXR1cm4gT2JqZWN0LmtleXMoc3Vic2V0KS5ldmVyeSgoa2V5KSA9PiB7XG5cdFx0XHRpZiAoc3Vic2V0W2tleV0gIT0gbnVsbCAmJiB0eXBlb2Ygc3Vic2V0W2tleV0gPT09IFwib2JqZWN0XCIpIHtcblx0XHRcdFx0aWYgKHNlZW5SZWZlcmVuY2VzLmhhcyhzdWJzZXRba2V5XSkpIHtcblx0XHRcdFx0XHRyZXR1cm4gZXF1YWxzKG9iamVjdFtrZXldLCBzdWJzZXRba2V5XSwgZmlsdGVyZWRDdXN0b21UZXN0ZXJzKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRzZWVuUmVmZXJlbmNlcy5zZXQoc3Vic2V0W2tleV0sIHRydWUpO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgcmVzdWx0ID0gb2JqZWN0ICE9IG51bGwgJiYgaGFzUHJvcGVydHlJbk9iamVjdChvYmplY3QsIGtleSkgJiYgZXF1YWxzKG9iamVjdFtrZXldLCBzdWJzZXRba2V5XSwgWy4uLmZpbHRlcmVkQ3VzdG9tVGVzdGVycywgc3Vic2V0RXF1YWxpdHlXaXRoQ29udGV4dChzZWVuUmVmZXJlbmNlcyldKTtcblx0XHRcdC8vIFRoZSBtYWluIGdvYWwgb2YgdXNpbmcgc2VlblJlZmVyZW5jZSBpcyB0byBhdm9pZCBjaXJjdWxhciBub2RlIG9uIHRyZWUuXG5cdFx0XHQvLyBJdCB3aWxsIG9ubHkgaGFwcGVuIHdpdGhpbiBhIHBhcmVudCBhbmQgaXRzIGNoaWxkLCBub3QgYSBub2RlIGFuZCBub2RlcyBuZXh0IHRvIGl0IChzYW1lIGxldmVsKVxuXHRcdFx0Ly8gV2Ugc2hvdWxkIGtlZXAgdGhlIHJlZmVyZW5jZSBmb3IgYSBwYXJlbnQgYW5kIGl0cyBjaGlsZCBvbmx5XG5cdFx0XHQvLyBUaHVzIHdlIHNob3VsZCBkZWxldGUgdGhlIHJlZmVyZW5jZSBpbW1lZGlhdGVseSBzbyB0aGF0IGl0IGRvZXNuJ3QgaW50ZXJmZXJlXG5cdFx0XHQvLyBvdGhlciBub2RlcyB3aXRoaW4gdGhlIHNhbWUgbGV2ZWwgb24gdHJlZS5cblx0XHRcdHNlZW5SZWZlcmVuY2VzLmRlbGV0ZShzdWJzZXRba2V5XSk7XG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdH0pO1xuXHR9O1xuXHRyZXR1cm4gc3Vic2V0RXF1YWxpdHlXaXRoQ29udGV4dCgpKG9iamVjdCwgc3Vic2V0KTtcbn1cbmZ1bmN0aW9uIHR5cGVFcXVhbGl0eShhLCBiKSB7XG5cdGlmIChhID09IG51bGwgfHwgYiA9PSBudWxsIHx8IGEuY29uc3RydWN0b3IgPT09IGIuY29uc3RydWN0b3IpIHtcblx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHR9XG5cdHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIGFycmF5QnVmZmVyRXF1YWxpdHkoYSwgYikge1xuXHRsZXQgZGF0YVZpZXdBID0gYTtcblx0bGV0IGRhdGFWaWV3QiA9IGI7XG5cdGlmICghKGEgaW5zdGFuY2VvZiBEYXRhVmlldyAmJiBiIGluc3RhbmNlb2YgRGF0YVZpZXcpKSB7XG5cdFx0aWYgKCEoYSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB8fCAhKGIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikpIHtcblx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdHRyeSB7XG5cdFx0XHRkYXRhVmlld0EgPSBuZXcgRGF0YVZpZXcoYSk7XG5cdFx0XHRkYXRhVmlld0IgPSBuZXcgRGF0YVZpZXcoYik7XG5cdFx0fSBjYXRjaCB7XG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdH1cblx0fVxuXHQvLyBCdWZmZXJzIGFyZSBub3QgZXF1YWwgd2hlbiB0aGV5IGRvIG5vdCBoYXZlIHRoZSBzYW1lIGJ5dGUgbGVuZ3RoXG5cdGlmIChkYXRhVmlld0EuYnl0ZUxlbmd0aCAhPT0gZGF0YVZpZXdCLmJ5dGVMZW5ndGgpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0Ly8gQ2hlY2sgaWYgZXZlcnkgYnl0ZSB2YWx1ZSBpcyBlcXVhbCB0byBlYWNoIG90aGVyXG5cdGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YVZpZXdBLmJ5dGVMZW5ndGg7IGkrKykge1xuXHRcdGlmIChkYXRhVmlld0EuZ2V0VWludDgoaSkgIT09IGRhdGFWaWV3Qi5nZXRVaW50OChpKSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIHNwYXJzZUFycmF5RXF1YWxpdHkoYSwgYiwgY3VzdG9tVGVzdGVycyA9IFtdKSB7XG5cdGlmICghQXJyYXkuaXNBcnJheShhKSB8fCAhQXJyYXkuaXNBcnJheShiKSkge1xuXHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdH1cblx0Ly8gQSBzcGFyc2UgYXJyYXkgWywgLCAxXSB3aWxsIGhhdmUga2V5cyBbXCIyXCJdIHdoZXJlYXMgW3VuZGVmaW5lZCwgdW5kZWZpbmVkLCAxXSB3aWxsIGhhdmUga2V5cyBbXCIwXCIsIFwiMVwiLCBcIjJcIl1cblx0Y29uc3QgYUtleXMgPSBPYmplY3Qua2V5cyhhKTtcblx0Y29uc3QgYktleXMgPSBPYmplY3Qua2V5cyhiKTtcblx0Y29uc3QgZmlsdGVyZWRDdXN0b21UZXN0ZXJzID0gY3VzdG9tVGVzdGVycy5maWx0ZXIoKHQpID0+IHQgIT09IHNwYXJzZUFycmF5RXF1YWxpdHkpO1xuXHRyZXR1cm4gZXF1YWxzKGEsIGIsIGZpbHRlcmVkQ3VzdG9tVGVzdGVycywgdHJ1ZSkgJiYgZXF1YWxzKGFLZXlzLCBiS2V5cyk7XG59XG5mdW5jdGlvbiBnZW5lcmF0ZVRvQmVNZXNzYWdlKGRlZXBFcXVhbGl0eU5hbWUsIGV4cGVjdGVkID0gXCIje3RoaXN9XCIsIGFjdHVhbCA9IFwiI3tleHB9XCIpIHtcblx0Y29uc3QgdG9CZU1lc3NhZ2UgPSBgZXhwZWN0ZWQgJHtleHBlY3RlZH0gdG8gYmUgJHthY3R1YWx9IC8vIE9iamVjdC5pcyBlcXVhbGl0eWA7XG5cdGlmIChbXCJ0b1N0cmljdEVxdWFsXCIsIFwidG9FcXVhbFwiXS5pbmNsdWRlcyhkZWVwRXF1YWxpdHlOYW1lKSkge1xuXHRcdHJldHVybiBgJHt0b0JlTWVzc2FnZX1cXG5cXG5JZiBpdCBzaG91bGQgcGFzcyB3aXRoIGRlZXAgZXF1YWxpdHksIHJlcGxhY2UgXCJ0b0JlXCIgd2l0aCBcIiR7ZGVlcEVxdWFsaXR5TmFtZX1cIlxcblxcbkV4cGVjdGVkOiAke2V4cGVjdGVkfVxcblJlY2VpdmVkOiBzZXJpYWxpemVzIHRvIHRoZSBzYW1lIHN0cmluZ1xcbmA7XG5cdH1cblx0cmV0dXJuIHRvQmVNZXNzYWdlO1xufVxuZnVuY3Rpb24gcGx1cmFsaXplKHdvcmQsIGNvdW50KSB7XG5cdHJldHVybiBgJHtjb3VudH0gJHt3b3JkfSR7Y291bnQgPT09IDEgPyBcIlwiIDogXCJzXCJ9YDtcbn1cbmZ1bmN0aW9uIGdldE9iamVjdEtleXMob2JqZWN0KSB7XG5cdHJldHVybiBbLi4uT2JqZWN0LmtleXMob2JqZWN0KSwgLi4uT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmplY3QpLmZpbHRlcigocykgPT4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIHMpPy5lbnVtZXJhYmxlKV07XG59XG5mdW5jdGlvbiBnZXRPYmplY3RTdWJzZXQob2JqZWN0LCBzdWJzZXQsIGN1c3RvbVRlc3RlcnMpIHtcblx0bGV0IHN0cmlwcGVkID0gMDtcblx0Y29uc3QgZ2V0T2JqZWN0U3Vic2V0V2l0aENvbnRleHQgPSAoc2VlblJlZmVyZW5jZXMgPSBuZXcgV2Vha01hcCgpKSA9PiAob2JqZWN0LCBzdWJzZXQpID0+IHtcblx0XHRpZiAoQXJyYXkuaXNBcnJheShvYmplY3QpKSB7XG5cdFx0XHRpZiAoQXJyYXkuaXNBcnJheShzdWJzZXQpICYmIHN1YnNldC5sZW5ndGggPT09IG9iamVjdC5sZW5ndGgpIHtcblx0XHRcdFx0Ly8gVGhlIG1hcCBtZXRob2QgcmV0dXJucyBjb3JyZWN0IHN1YmNsYXNzIG9mIHN1YnNldC5cblx0XHRcdFx0cmV0dXJuIHN1YnNldC5tYXAoKHN1YiwgaSkgPT4gZ2V0T2JqZWN0U3Vic2V0V2l0aENvbnRleHQoc2VlblJlZmVyZW5jZXMpKG9iamVjdFtpXSwgc3ViKSk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmIChvYmplY3QgaW5zdGFuY2VvZiBEYXRlKSB7XG5cdFx0XHRyZXR1cm4gb2JqZWN0O1xuXHRcdH0gZWxzZSBpZiAoaXNPYmplY3Qob2JqZWN0KSAmJiBpc09iamVjdChzdWJzZXQpKSB7XG5cdFx0XHRpZiAoZXF1YWxzKG9iamVjdCwgc3Vic2V0LCBbXG5cdFx0XHRcdC4uLmN1c3RvbVRlc3RlcnMsXG5cdFx0XHRcdGl0ZXJhYmxlRXF1YWxpdHksXG5cdFx0XHRcdHN1YnNldEVxdWFsaXR5XG5cdFx0XHRdKSkge1xuXHRcdFx0XHQvLyByZXR1cm4gXCJleHBlY3RlZFwiIHN1YnNldCB0byBhdm9pZCBzaG93aW5nIGlycmVsZXZhbnQgdG9NYXRjaE9iamVjdCBkaWZmXG5cdFx0XHRcdHJldHVybiBzdWJzZXQ7XG5cdFx0XHR9XG5cdFx0XHRjb25zdCB0cmltbWVkID0ge307XG5cdFx0XHRzZWVuUmVmZXJlbmNlcy5zZXQob2JqZWN0LCB0cmltbWVkKTtcblx0XHRcdC8vIHByZXNlcnZlIGNvbnN0cnVjdG9yIGZvciB0b01hdGNoT2JqZWN0IGRpZmZcblx0XHRcdGlmICh0eXBlb2Ygb2JqZWN0LmNvbnN0cnVjdG9yID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIG9iamVjdC5jb25zdHJ1Y3Rvci5uYW1lID09PSBcInN0cmluZ1wiKSB7XG5cdFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0cmltbWVkLCBcImNvbnN0cnVjdG9yXCIsIHtcblx0XHRcdFx0XHRlbnVtZXJhYmxlOiBmYWxzZSxcblx0XHRcdFx0XHR2YWx1ZTogb2JqZWN0LmNvbnN0cnVjdG9yXG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdFx0Zm9yIChjb25zdCBrZXkgb2YgZ2V0T2JqZWN0S2V5cyhvYmplY3QpKSB7XG5cdFx0XHRcdGlmIChoYXNQcm9wZXJ0eUluT2JqZWN0KHN1YnNldCwga2V5KSkge1xuXHRcdFx0XHRcdHRyaW1tZWRba2V5XSA9IHNlZW5SZWZlcmVuY2VzLmhhcyhvYmplY3Rba2V5XSkgPyBzZWVuUmVmZXJlbmNlcy5nZXQob2JqZWN0W2tleV0pIDogZ2V0T2JqZWN0U3Vic2V0V2l0aENvbnRleHQoc2VlblJlZmVyZW5jZXMpKG9iamVjdFtrZXldLCBzdWJzZXRba2V5XSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0aWYgKCFzZWVuUmVmZXJlbmNlcy5oYXMob2JqZWN0W2tleV0pKSB7XG5cdFx0XHRcdFx0XHRzdHJpcHBlZCArPSAxO1xuXHRcdFx0XHRcdFx0aWYgKGlzT2JqZWN0KG9iamVjdFtrZXldKSkge1xuXHRcdFx0XHRcdFx0XHRzdHJpcHBlZCArPSBnZXRPYmplY3RLZXlzKG9iamVjdFtrZXldKS5sZW5ndGg7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRnZXRPYmplY3RTdWJzZXRXaXRoQ29udGV4dChzZWVuUmVmZXJlbmNlcykob2JqZWN0W2tleV0sIHN1YnNldFtrZXldKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmIChnZXRPYmplY3RLZXlzKHRyaW1tZWQpLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0cmV0dXJuIHRyaW1tZWQ7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBvYmplY3Q7XG5cdH07XG5cdHJldHVybiB7XG5cdFx0c3Vic2V0OiBnZXRPYmplY3RTdWJzZXRXaXRoQ29udGV4dCgpKG9iamVjdCwgc3Vic2V0KSxcblx0XHRzdHJpcHBlZFxuXHR9O1xufVxuLyoqXG4qIERldGVjdHMgaWYgYW4gb2JqZWN0IGlzIGEgU3RhbmRhcmQgU2NoZW1hIFYxIGNvbXBhdGlibGUgc2NoZW1hXG4qL1xuZnVuY3Rpb24gaXNTdGFuZGFyZFNjaGVtYShvYmopIHtcblx0cmV0dXJuICEhb2JqICYmICh0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiBvYmogPT09IFwiZnVuY3Rpb25cIikgJiYgb2JqW1wifnN0YW5kYXJkXCJdICYmIHR5cGVvZiBvYmpbXCJ+c3RhbmRhcmRcIl0udmFsaWRhdGUgPT09IFwiZnVuY3Rpb25cIjtcbn1cblxuaWYgKCFPYmplY3QuaGFzT3duKGdsb2JhbFRoaXMsIE1BVENIRVJTX09CSkVDVCkpIHtcblx0Y29uc3QgZ2xvYmFsU3RhdGUgPSBuZXcgV2Vha01hcCgpO1xuXHRjb25zdCBtYXRjaGVycyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cdGNvbnN0IGN1c3RvbUVxdWFsaXR5VGVzdGVycyA9IFtdO1xuXHRjb25zdCBhc3ltbWV0cmljTWF0Y2hlcnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsVGhpcywgTUFUQ0hFUlNfT0JKRUNULCB7IGdldDogKCkgPT4gZ2xvYmFsU3RhdGUgfSk7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxUaGlzLCBKRVNUX01BVENIRVJTX09CSkVDVCwge1xuXHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRnZXQ6ICgpID0+ICh7XG5cdFx0XHRzdGF0ZTogZ2xvYmFsU3RhdGUuZ2V0KGdsb2JhbFRoaXNbR0xPQkFMX0VYUEVDVF0pLFxuXHRcdFx0bWF0Y2hlcnMsXG5cdFx0XHRjdXN0b21FcXVhbGl0eVRlc3RlcnNcblx0XHR9KVxuXHR9KTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGdsb2JhbFRoaXMsIEFTWU1NRVRSSUNfTUFUQ0hFUlNfT0JKRUNULCB7IGdldDogKCkgPT4gYXN5bW1ldHJpY01hdGNoZXJzIH0pO1xufVxuZnVuY3Rpb24gZ2V0U3RhdGUoZXhwZWN0KSB7XG5cdHJldHVybiBnbG9iYWxUaGlzW01BVENIRVJTX09CSkVDVF0uZ2V0KGV4cGVjdCk7XG59XG5mdW5jdGlvbiBzZXRTdGF0ZShzdGF0ZSwgZXhwZWN0KSB7XG5cdGNvbnN0IG1hcCA9IGdsb2JhbFRoaXNbTUFUQ0hFUlNfT0JKRUNUXTtcblx0Y29uc3QgY3VycmVudCA9IG1hcC5nZXQoZXhwZWN0KSB8fCB7fTtcblx0Ly8gc28gaXQga2VlcHMgZ2V0dGVycyBmcm9tIGB0ZXN0UGF0aGBcblx0Y29uc3QgcmVzdWx0cyA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKGN1cnJlbnQsIHtcblx0XHQuLi5PYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhjdXJyZW50KSxcblx0XHQuLi5PYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhzdGF0ZSlcblx0fSk7XG5cdG1hcC5zZXQoZXhwZWN0LCByZXN1bHRzKTtcbn1cblxuY2xhc3MgQXN5bW1ldHJpY01hdGNoZXIge1xuXHQvLyBzaG91bGQgaGF2ZSBcImplc3RcIiB0byBiZSBjb21wYXRpYmxlIHdpdGggaXRzIGVjb3N5c3RlbVxuXHQkJHR5cGVvZiA9IFN5bWJvbC5mb3IoXCJqZXN0LmFzeW1tZXRyaWNNYXRjaGVyXCIpO1xuXHRjb25zdHJ1Y3RvcihzYW1wbGUsIGludmVyc2UgPSBmYWxzZSkge1xuXHRcdHRoaXMuc2FtcGxlID0gc2FtcGxlO1xuXHRcdHRoaXMuaW52ZXJzZSA9IGludmVyc2U7XG5cdH1cblx0Z2V0TWF0Y2hlckNvbnRleHQoZXhwZWN0KSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdC4uLmdldFN0YXRlKGV4cGVjdCB8fCBnbG9iYWxUaGlzW0dMT0JBTF9FWFBFQ1RdKSxcblx0XHRcdGVxdWFscyxcblx0XHRcdGlzTm90OiB0aGlzLmludmVyc2UsXG5cdFx0XHRjdXN0b21UZXN0ZXJzOiBnZXRDdXN0b21FcXVhbGl0eVRlc3RlcnMoKSxcblx0XHRcdHV0aWxzOiB7XG5cdFx0XHRcdC4uLmdldE1hdGNoZXJVdGlscygpLFxuXHRcdFx0XHRkaWZmLFxuXHRcdFx0XHRzdHJpbmdpZnksXG5cdFx0XHRcdGl0ZXJhYmxlRXF1YWxpdHksXG5cdFx0XHRcdHN1YnNldEVxdWFsaXR5XG5cdFx0XHR9XG5cdFx0fTtcblx0fVxufVxuLy8gaW1wbGVtZW50IGN1c3RvbSBjaGFpL2xvdXBlIGluc3BlY3QgZm9yIGJldHRlciBBc3NlcnRpb25FcnJvci5tZXNzYWdlIGZvcm1hdHRpbmdcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFpanMvbG91cGUvYmxvYi85YjhhNmRlYWJjZDUwYWRjMDU2YTY0ZmI3MDU4OTYxOTQ3MTBjNWM2L3NyYy9pbmRleC50cyNMMjlcbi8vIEB0cy1leHBlY3QtZXJyb3IgY29tcHV0ZWQgcHJvcGVydGllcyBpcyBub3Qgc3VwcG9ydGVkIHdoZW4gaXNvbGF0ZWREZWNsYXJhdGlvbnMgaXMgZW5hYmxlZFxuLy8gRklYTUU6IGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvVHlwZVNjcmlwdC9pc3N1ZXMvNjEwNjhcbkFzeW1tZXRyaWNNYXRjaGVyLnByb3RvdHlwZVtTeW1ib2wuZm9yKFwiY2hhaS9pbnNwZWN0XCIpXSA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcblx0Ly8gbWluaW1hbCBwcmV0dHktZm9ybWF0IHdpdGggc2ltcGxlIG1hbnVhbCB0cnVuY2F0aW9uXG5cdGNvbnN0IHJlc3VsdCA9IHN0cmluZ2lmeSh0aGlzLCBvcHRpb25zLmRlcHRoLCB7IG1pbjogdHJ1ZSB9KTtcblx0aWYgKHJlc3VsdC5sZW5ndGggPD0gb3B0aW9ucy50cnVuY2F0ZSkge1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblx0cmV0dXJuIGAke3RoaXMudG9TdHJpbmcoKX174oCmfWA7XG59O1xuY2xhc3MgU3RyaW5nQ29udGFpbmluZyBleHRlbmRzIEFzeW1tZXRyaWNNYXRjaGVyIHtcblx0Y29uc3RydWN0b3Ioc2FtcGxlLCBpbnZlcnNlID0gZmFsc2UpIHtcblx0XHRpZiAoIWlzQShcIlN0cmluZ1wiLCBzYW1wbGUpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJFeHBlY3RlZCBpcyBub3QgYSBzdHJpbmdcIik7XG5cdFx0fVxuXHRcdHN1cGVyKHNhbXBsZSwgaW52ZXJzZSk7XG5cdH1cblx0YXN5bW1ldHJpY01hdGNoKG90aGVyKSB7XG5cdFx0Y29uc3QgcmVzdWx0ID0gaXNBKFwiU3RyaW5nXCIsIG90aGVyKSAmJiBvdGhlci5pbmNsdWRlcyh0aGlzLnNhbXBsZSk7XG5cdFx0cmV0dXJuIHRoaXMuaW52ZXJzZSA/ICFyZXN1bHQgOiByZXN1bHQ7XG5cdH1cblx0dG9TdHJpbmcoKSB7XG5cdFx0cmV0dXJuIGBTdHJpbmcke3RoaXMuaW52ZXJzZSA/IFwiTm90XCIgOiBcIlwifUNvbnRhaW5pbmdgO1xuXHR9XG5cdGdldEV4cGVjdGVkVHlwZSgpIHtcblx0XHRyZXR1cm4gXCJzdHJpbmdcIjtcblx0fVxufVxuY2xhc3MgQW55dGhpbmcgZXh0ZW5kcyBBc3ltbWV0cmljTWF0Y2hlciB7XG5cdGFzeW1tZXRyaWNNYXRjaChvdGhlcikge1xuXHRcdHJldHVybiBvdGhlciAhPSBudWxsO1xuXHR9XG5cdHRvU3RyaW5nKCkge1xuXHRcdHJldHVybiBcIkFueXRoaW5nXCI7XG5cdH1cblx0dG9Bc3ltbWV0cmljTWF0Y2hlcigpIHtcblx0XHRyZXR1cm4gXCJBbnl0aGluZ1wiO1xuXHR9XG59XG5jbGFzcyBPYmplY3RDb250YWluaW5nIGV4dGVuZHMgQXN5bW1ldHJpY01hdGNoZXIge1xuXHRjb25zdHJ1Y3RvcihzYW1wbGUsIGludmVyc2UgPSBmYWxzZSkge1xuXHRcdHN1cGVyKHNhbXBsZSwgaW52ZXJzZSk7XG5cdH1cblx0Z2V0UHJvdG90eXBlKG9iaikge1xuXHRcdGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YpIHtcblx0XHRcdHJldHVybiBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKTtcblx0XHR9XG5cdFx0aWYgKG9iai5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgPT09IG9iaikge1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXHRcdHJldHVybiBvYmouY29uc3RydWN0b3IucHJvdG90eXBlO1xuXHR9XG5cdGhhc1Byb3BlcnR5KG9iaiwgcHJvcGVydHkpIHtcblx0XHRpZiAoIW9iaikge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRpZiAoT2JqZWN0Lmhhc093bihvYmosIHByb3BlcnR5KSkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmhhc1Byb3BlcnR5KHRoaXMuZ2V0UHJvdG90eXBlKG9iaiksIHByb3BlcnR5KTtcblx0fVxuXHRnZXRQcm9wZXJ0aWVzKG9iaikge1xuXHRcdHJldHVybiBbLi4uT2JqZWN0LmtleXMob2JqKSwgLi4uT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmopLmZpbHRlcigocykgPT4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmosIHMpPy5lbnVtZXJhYmxlKV07XG5cdH1cblx0YXN5bW1ldHJpY01hdGNoKG90aGVyLCBjdXN0b21UZXN0ZXJzKSB7XG5cdFx0aWYgKHR5cGVvZiB0aGlzLnNhbXBsZSAhPT0gXCJvYmplY3RcIikge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihgWW91IG11c3QgcHJvdmlkZSBhbiBvYmplY3QgdG8gJHt0aGlzLnRvU3RyaW5nKCl9LCBub3QgJyR7dHlwZW9mIHRoaXMuc2FtcGxlfScuYCk7XG5cdFx0fVxuXHRcdGxldCByZXN1bHQgPSB0cnVlO1xuXHRcdGNvbnN0IHByb3BlcnRpZXMgPSB0aGlzLmdldFByb3BlcnRpZXModGhpcy5zYW1wbGUpO1xuXHRcdGZvciAoY29uc3QgcHJvcGVydHkgb2YgcHJvcGVydGllcykge1xuXHRcdFx0aWYgKCF0aGlzLmhhc1Byb3BlcnR5KG90aGVyLCBwcm9wZXJ0eSkpIHtcblx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgdmFsdWUgPSB0aGlzLnNhbXBsZVtwcm9wZXJ0eV07XG5cdFx0XHRjb25zdCBvdGhlclZhbHVlID0gb3RoZXJbcHJvcGVydHldO1xuXHRcdFx0aWYgKCFlcXVhbHModmFsdWUsIG90aGVyVmFsdWUsIGN1c3RvbVRlc3RlcnMpKSB7XG5cdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuaW52ZXJzZSA/ICFyZXN1bHQgOiByZXN1bHQ7XG5cdH1cblx0dG9TdHJpbmcoKSB7XG5cdFx0cmV0dXJuIGBPYmplY3Qke3RoaXMuaW52ZXJzZSA/IFwiTm90XCIgOiBcIlwifUNvbnRhaW5pbmdgO1xuXHR9XG5cdGdldEV4cGVjdGVkVHlwZSgpIHtcblx0XHRyZXR1cm4gXCJvYmplY3RcIjtcblx0fVxufVxuY2xhc3MgQXJyYXlDb250YWluaW5nIGV4dGVuZHMgQXN5bW1ldHJpY01hdGNoZXIge1xuXHRjb25zdHJ1Y3RvcihzYW1wbGUsIGludmVyc2UgPSBmYWxzZSkge1xuXHRcdHN1cGVyKHNhbXBsZSwgaW52ZXJzZSk7XG5cdH1cblx0YXN5bW1ldHJpY01hdGNoKG90aGVyLCBjdXN0b21UZXN0ZXJzKSB7XG5cdFx0aWYgKCFBcnJheS5pc0FycmF5KHRoaXMuc2FtcGxlKSkge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihgWW91IG11c3QgcHJvdmlkZSBhbiBhcnJheSB0byAke3RoaXMudG9TdHJpbmcoKX0sIG5vdCAnJHt0eXBlb2YgdGhpcy5zYW1wbGV9Jy5gKTtcblx0XHR9XG5cdFx0Y29uc3QgcmVzdWx0ID0gdGhpcy5zYW1wbGUubGVuZ3RoID09PSAwIHx8IEFycmF5LmlzQXJyYXkob3RoZXIpICYmIHRoaXMuc2FtcGxlLmV2ZXJ5KChpdGVtKSA9PiBvdGhlci5zb21lKChhbm90aGVyKSA9PiBlcXVhbHMoaXRlbSwgYW5vdGhlciwgY3VzdG9tVGVzdGVycykpKTtcblx0XHRyZXR1cm4gdGhpcy5pbnZlcnNlID8gIXJlc3VsdCA6IHJlc3VsdDtcblx0fVxuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gYEFycmF5JHt0aGlzLmludmVyc2UgPyBcIk5vdFwiIDogXCJcIn1Db250YWluaW5nYDtcblx0fVxuXHRnZXRFeHBlY3RlZFR5cGUoKSB7XG5cdFx0cmV0dXJuIFwiYXJyYXlcIjtcblx0fVxufVxuY2xhc3MgQW55IGV4dGVuZHMgQXN5bW1ldHJpY01hdGNoZXIge1xuXHRjb25zdHJ1Y3RvcihzYW1wbGUpIHtcblx0XHRpZiAodHlwZW9mIHNhbXBsZSA9PT0gXCJ1bmRlZmluZWRcIikge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihcImFueSgpIGV4cGVjdHMgdG8gYmUgcGFzc2VkIGEgY29uc3RydWN0b3IgZnVuY3Rpb24uIFwiICsgXCJQbGVhc2UgcGFzcyBvbmUgb3IgdXNlIGFueXRoaW5nKCkgdG8gbWF0Y2ggYW55IG9iamVjdC5cIik7XG5cdFx0fVxuXHRcdHN1cGVyKHNhbXBsZSk7XG5cdH1cblx0Zm5OYW1lRm9yKGZ1bmMpIHtcblx0XHRpZiAoZnVuYy5uYW1lKSB7XG5cdFx0XHRyZXR1cm4gZnVuYy5uYW1lO1xuXHRcdH1cblx0XHRjb25zdCBmdW5jdGlvblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xuXHRcdGNvbnN0IG1hdGNoZXMgPSBmdW5jdGlvblRvU3RyaW5nLmNhbGwoZnVuYykubWF0Y2goL14oPzphc3luYyk/XFxzKmZ1bmN0aW9uXFxzKig/OlxcKlxccyopPyhbXFx3JF0rKVxccypcXCgvKTtcblx0XHRyZXR1cm4gbWF0Y2hlcyA/IG1hdGNoZXNbMV0gOiBcIjxhbm9ueW1vdXM+XCI7XG5cdH1cblx0YXN5bW1ldHJpY01hdGNoKG90aGVyKSB7XG5cdFx0aWYgKHRoaXMuc2FtcGxlID09PSBTdHJpbmcpIHtcblx0XHRcdHJldHVybiB0eXBlb2Ygb3RoZXIgPT0gXCJzdHJpbmdcIiB8fCBvdGhlciBpbnN0YW5jZW9mIFN0cmluZztcblx0XHR9XG5cdFx0aWYgKHRoaXMuc2FtcGxlID09PSBOdW1iZXIpIHtcblx0XHRcdHJldHVybiB0eXBlb2Ygb3RoZXIgPT0gXCJudW1iZXJcIiB8fCBvdGhlciBpbnN0YW5jZW9mIE51bWJlcjtcblx0XHR9XG5cdFx0aWYgKHRoaXMuc2FtcGxlID09PSBGdW5jdGlvbikge1xuXHRcdFx0cmV0dXJuIHR5cGVvZiBvdGhlciA9PSBcImZ1bmN0aW9uXCIgfHwgdHlwZW9mIG90aGVyID09PSBcImZ1bmN0aW9uXCI7XG5cdFx0fVxuXHRcdGlmICh0aGlzLnNhbXBsZSA9PT0gQm9vbGVhbikge1xuXHRcdFx0cmV0dXJuIHR5cGVvZiBvdGhlciA9PSBcImJvb2xlYW5cIiB8fCBvdGhlciBpbnN0YW5jZW9mIEJvb2xlYW47XG5cdFx0fVxuXHRcdGlmICh0aGlzLnNhbXBsZSA9PT0gQmlnSW50KSB7XG5cdFx0XHRyZXR1cm4gdHlwZW9mIG90aGVyID09IFwiYmlnaW50XCIgfHwgb3RoZXIgaW5zdGFuY2VvZiBCaWdJbnQ7XG5cdFx0fVxuXHRcdGlmICh0aGlzLnNhbXBsZSA9PT0gU3ltYm9sKSB7XG5cdFx0XHRyZXR1cm4gdHlwZW9mIG90aGVyID09IFwic3ltYm9sXCIgfHwgb3RoZXIgaW5zdGFuY2VvZiBTeW1ib2w7XG5cdFx0fVxuXHRcdGlmICh0aGlzLnNhbXBsZSA9PT0gT2JqZWN0KSB7XG5cdFx0XHRyZXR1cm4gdHlwZW9mIG90aGVyID09IFwib2JqZWN0XCI7XG5cdFx0fVxuXHRcdHJldHVybiBvdGhlciBpbnN0YW5jZW9mIHRoaXMuc2FtcGxlO1xuXHR9XG5cdHRvU3RyaW5nKCkge1xuXHRcdHJldHVybiBcIkFueVwiO1xuXHR9XG5cdGdldEV4cGVjdGVkVHlwZSgpIHtcblx0XHRpZiAodGhpcy5zYW1wbGUgPT09IFN0cmluZykge1xuXHRcdFx0cmV0dXJuIFwic3RyaW5nXCI7XG5cdFx0fVxuXHRcdGlmICh0aGlzLnNhbXBsZSA9PT0gTnVtYmVyKSB7XG5cdFx0XHRyZXR1cm4gXCJudW1iZXJcIjtcblx0XHR9XG5cdFx0aWYgKHRoaXMuc2FtcGxlID09PSBGdW5jdGlvbikge1xuXHRcdFx0cmV0dXJuIFwiZnVuY3Rpb25cIjtcblx0XHR9XG5cdFx0aWYgKHRoaXMuc2FtcGxlID09PSBPYmplY3QpIHtcblx0XHRcdHJldHVybiBcIm9iamVjdFwiO1xuXHRcdH1cblx0XHRpZiAodGhpcy5zYW1wbGUgPT09IEJvb2xlYW4pIHtcblx0XHRcdHJldHVybiBcImJvb2xlYW5cIjtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuZm5OYW1lRm9yKHRoaXMuc2FtcGxlKTtcblx0fVxuXHR0b0FzeW1tZXRyaWNNYXRjaGVyKCkge1xuXHRcdHJldHVybiBgQW55PCR7dGhpcy5mbk5hbWVGb3IodGhpcy5zYW1wbGUpfT5gO1xuXHR9XG59XG5jbGFzcyBTdHJpbmdNYXRjaGluZyBleHRlbmRzIEFzeW1tZXRyaWNNYXRjaGVyIHtcblx0Y29uc3RydWN0b3Ioc2FtcGxlLCBpbnZlcnNlID0gZmFsc2UpIHtcblx0XHRpZiAoIWlzQShcIlN0cmluZ1wiLCBzYW1wbGUpICYmICFpc0EoXCJSZWdFeHBcIiwgc2FtcGxlKSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgaXMgbm90IGEgU3RyaW5nIG9yIGEgUmVnRXhwXCIpO1xuXHRcdH1cblx0XHRzdXBlcihuZXcgUmVnRXhwKHNhbXBsZSksIGludmVyc2UpO1xuXHR9XG5cdGFzeW1tZXRyaWNNYXRjaChvdGhlcikge1xuXHRcdGNvbnN0IHJlc3VsdCA9IGlzQShcIlN0cmluZ1wiLCBvdGhlcikgJiYgdGhpcy5zYW1wbGUudGVzdChvdGhlcik7XG5cdFx0cmV0dXJuIHRoaXMuaW52ZXJzZSA/ICFyZXN1bHQgOiByZXN1bHQ7XG5cdH1cblx0dG9TdHJpbmcoKSB7XG5cdFx0cmV0dXJuIGBTdHJpbmcke3RoaXMuaW52ZXJzZSA/IFwiTm90XCIgOiBcIlwifU1hdGNoaW5nYDtcblx0fVxuXHRnZXRFeHBlY3RlZFR5cGUoKSB7XG5cdFx0cmV0dXJuIFwic3RyaW5nXCI7XG5cdH1cbn1cbmNsYXNzIENsb3NlVG8gZXh0ZW5kcyBBc3ltbWV0cmljTWF0Y2hlciB7XG5cdHByZWNpc2lvbjtcblx0Y29uc3RydWN0b3Ioc2FtcGxlLCBwcmVjaXNpb24gPSAyLCBpbnZlcnNlID0gZmFsc2UpIHtcblx0XHRpZiAoIWlzQShcIk51bWJlclwiLCBzYW1wbGUpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJFeHBlY3RlZCBpcyBub3QgYSBOdW1iZXJcIik7XG5cdFx0fVxuXHRcdGlmICghaXNBKFwiTnVtYmVyXCIsIHByZWNpc2lvbikpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIlByZWNpc2lvbiBpcyBub3QgYSBOdW1iZXJcIik7XG5cdFx0fVxuXHRcdHN1cGVyKHNhbXBsZSk7XG5cdFx0dGhpcy5pbnZlcnNlID0gaW52ZXJzZTtcblx0XHR0aGlzLnByZWNpc2lvbiA9IHByZWNpc2lvbjtcblx0fVxuXHRhc3ltbWV0cmljTWF0Y2gob3RoZXIpIHtcblx0XHRpZiAoIWlzQShcIk51bWJlclwiLCBvdGhlcikpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0bGV0IHJlc3VsdCA9IGZhbHNlO1xuXHRcdGlmIChvdGhlciA9PT0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZICYmIHRoaXMuc2FtcGxlID09PSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpIHtcblx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0fSBlbHNlIGlmIChvdGhlciA9PT0gTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZICYmIHRoaXMuc2FtcGxlID09PSBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkpIHtcblx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJlc3VsdCA9IE1hdGguYWJzKHRoaXMuc2FtcGxlIC0gb3RoZXIpIDwgMTAgKiogLXRoaXMucHJlY2lzaW9uIC8gMjtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuaW52ZXJzZSA/ICFyZXN1bHQgOiByZXN1bHQ7XG5cdH1cblx0dG9TdHJpbmcoKSB7XG5cdFx0cmV0dXJuIGBOdW1iZXIke3RoaXMuaW52ZXJzZSA/IFwiTm90XCIgOiBcIlwifUNsb3NlVG9gO1xuXHR9XG5cdGdldEV4cGVjdGVkVHlwZSgpIHtcblx0XHRyZXR1cm4gXCJudW1iZXJcIjtcblx0fVxuXHR0b0FzeW1tZXRyaWNNYXRjaGVyKCkge1xuXHRcdHJldHVybiBbXG5cdFx0XHR0aGlzLnRvU3RyaW5nKCksXG5cdFx0XHR0aGlzLnNhbXBsZSxcblx0XHRcdGAoJHtwbHVyYWxpemUoXCJkaWdpdFwiLCB0aGlzLnByZWNpc2lvbil9KWBcblx0XHRdLmpvaW4oXCIgXCIpO1xuXHR9XG59XG5jbGFzcyBTY2hlbWFNYXRjaGluZyBleHRlbmRzIEFzeW1tZXRyaWNNYXRjaGVyIHtcblx0cmVzdWx0O1xuXHRjb25zdHJ1Y3RvcihzYW1wbGUsIGludmVyc2UgPSBmYWxzZSkge1xuXHRcdGlmICghaXNTdGFuZGFyZFNjaGVtYShzYW1wbGUpKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKFwiU2NoZW1hTWF0Y2hpbmcgZXhwZWN0ZWQgdG8gcmVjZWl2ZSBhIFN0YW5kYXJkIFNjaGVtYS5cIik7XG5cdFx0fVxuXHRcdHN1cGVyKHNhbXBsZSwgaW52ZXJzZSk7XG5cdH1cblx0YXN5bW1ldHJpY01hdGNoKG90aGVyKSB7XG5cdFx0Y29uc3QgcmVzdWx0ID0gdGhpcy5zYW1wbGVbXCJ+c3RhbmRhcmRcIl0udmFsaWRhdGUob3RoZXIpO1xuXHRcdC8vIENoZWNrIGlmIHRoZSByZXN1bHQgaXMgYSBQcm9taXNlIChhc3luYyB2YWxpZGF0aW9uKVxuXHRcdGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKFwiQXN5bmMgc2NoZW1hIHZhbGlkYXRpb24gaXMgbm90IHN1cHBvcnRlZCBpbiBhc3ltbWV0cmljIG1hdGNoZXJzLlwiKTtcblx0XHR9XG5cdFx0dGhpcy5yZXN1bHQgPSByZXN1bHQ7XG5cdFx0Y29uc3QgcGFzcyA9ICF0aGlzLnJlc3VsdC5pc3N1ZXMgfHwgdGhpcy5yZXN1bHQuaXNzdWVzLmxlbmd0aCA9PT0gMDtcblx0XHRyZXR1cm4gdGhpcy5pbnZlcnNlID8gIXBhc3MgOiBwYXNzO1xuXHR9XG5cdHRvU3RyaW5nKCkge1xuXHRcdHJldHVybiBgU2NoZW1hJHt0aGlzLmludmVyc2UgPyBcIk5vdFwiIDogXCJcIn1NYXRjaGluZ2A7XG5cdH1cblx0Z2V0RXhwZWN0ZWRUeXBlKCkge1xuXHRcdHJldHVybiBcIm9iamVjdFwiO1xuXHR9XG5cdHRvQXN5bW1ldHJpY01hdGNoZXIoKSB7XG5cdFx0Y29uc3QgeyB1dGlscyB9ID0gdGhpcy5nZXRNYXRjaGVyQ29udGV4dCgpO1xuXHRcdGNvbnN0IGlzc3VlcyA9IHRoaXMucmVzdWx0Py5pc3N1ZXMgfHwgW107XG5cdFx0aWYgKGlzc3Vlcy5sZW5ndGggPiAwKSB7XG5cdFx0XHRyZXR1cm4gYCR7dGhpcy50b1N0cmluZygpfSAke3V0aWxzLnN0cmluZ2lmeSh0aGlzLnJlc3VsdCwgdW5kZWZpbmVkLCB7IHByaW50QmFzaWNQcm90b3R5cGU6IGZhbHNlIH0pfWA7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLnRvU3RyaW5nKCk7XG5cdH1cbn1cbmNvbnN0IEplc3RBc3ltbWV0cmljTWF0Y2hlcnMgPSAoY2hhaSwgdXRpbHMpID0+IHtcblx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuZXhwZWN0LCBcImFueXRoaW5nXCIsICgpID0+IG5ldyBBbnl0aGluZygpKTtcblx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuZXhwZWN0LCBcImFueVwiLCAoZXhwZWN0ZWQpID0+IG5ldyBBbnkoZXhwZWN0ZWQpKTtcblx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuZXhwZWN0LCBcInN0cmluZ0NvbnRhaW5pbmdcIiwgKGV4cGVjdGVkKSA9PiBuZXcgU3RyaW5nQ29udGFpbmluZyhleHBlY3RlZCkpO1xuXHR1dGlscy5hZGRNZXRob2QoY2hhaS5leHBlY3QsIFwib2JqZWN0Q29udGFpbmluZ1wiLCAoZXhwZWN0ZWQpID0+IG5ldyBPYmplY3RDb250YWluaW5nKGV4cGVjdGVkKSk7XG5cdHV0aWxzLmFkZE1ldGhvZChjaGFpLmV4cGVjdCwgXCJhcnJheUNvbnRhaW5pbmdcIiwgKGV4cGVjdGVkKSA9PiBuZXcgQXJyYXlDb250YWluaW5nKGV4cGVjdGVkKSk7XG5cdHV0aWxzLmFkZE1ldGhvZChjaGFpLmV4cGVjdCwgXCJzdHJpbmdNYXRjaGluZ1wiLCAoZXhwZWN0ZWQpID0+IG5ldyBTdHJpbmdNYXRjaGluZyhleHBlY3RlZCkpO1xuXHR1dGlscy5hZGRNZXRob2QoY2hhaS5leHBlY3QsIFwiY2xvc2VUb1wiLCAoZXhwZWN0ZWQsIHByZWNpc2lvbikgPT4gbmV3IENsb3NlVG8oZXhwZWN0ZWQsIHByZWNpc2lvbikpO1xuXHR1dGlscy5hZGRNZXRob2QoY2hhaS5leHBlY3QsIFwic2NoZW1hTWF0Y2hpbmdcIiwgKGV4cGVjdGVkKSA9PiBuZXcgU2NoZW1hTWF0Y2hpbmcoZXhwZWN0ZWQpKTtcblx0Ly8gZGVmaW5lUHJvcGVydHkgZG9lcyBub3Qgd29ya1xuXHRjaGFpLmV4cGVjdC5ub3QgPSB7XG5cdFx0c3RyaW5nQ29udGFpbmluZzogKGV4cGVjdGVkKSA9PiBuZXcgU3RyaW5nQ29udGFpbmluZyhleHBlY3RlZCwgdHJ1ZSksXG5cdFx0b2JqZWN0Q29udGFpbmluZzogKGV4cGVjdGVkKSA9PiBuZXcgT2JqZWN0Q29udGFpbmluZyhleHBlY3RlZCwgdHJ1ZSksXG5cdFx0YXJyYXlDb250YWluaW5nOiAoZXhwZWN0ZWQpID0+IG5ldyBBcnJheUNvbnRhaW5pbmcoZXhwZWN0ZWQsIHRydWUpLFxuXHRcdHN0cmluZ01hdGNoaW5nOiAoZXhwZWN0ZWQpID0+IG5ldyBTdHJpbmdNYXRjaGluZyhleHBlY3RlZCwgdHJ1ZSksXG5cdFx0Y2xvc2VUbzogKGV4cGVjdGVkLCBwcmVjaXNpb24pID0+IG5ldyBDbG9zZVRvKGV4cGVjdGVkLCBwcmVjaXNpb24sIHRydWUpLFxuXHRcdHNjaGVtYU1hdGNoaW5nOiAoZXhwZWN0ZWQpID0+IG5ldyBTY2hlbWFNYXRjaGluZyhleHBlY3RlZCwgdHJ1ZSlcblx0fTtcbn07XG5cbmZ1bmN0aW9uIGNyZWF0ZUFzc2VydGlvbk1lc3NhZ2UodXRpbCwgYXNzZXJ0aW9uLCBoYXNBcmdzKSB7XG5cdGNvbnN0IHNvZnQgPSB1dGlsLmZsYWcoYXNzZXJ0aW9uLCBcInNvZnRcIikgPyBcIi5zb2Z0XCIgOiBcIlwiO1xuXHRjb25zdCBub3QgPSB1dGlsLmZsYWcoYXNzZXJ0aW9uLCBcIm5lZ2F0ZVwiKSA/IFwibm90LlwiIDogXCJcIjtcblx0Y29uc3QgbmFtZSA9IGAke3V0aWwuZmxhZyhhc3NlcnRpb24sIFwiX25hbWVcIil9KCR7aGFzQXJncyA/IFwiZXhwZWN0ZWRcIiA6IFwiXCJ9KWA7XG5cdGNvbnN0IHByb21pc2VOYW1lID0gdXRpbC5mbGFnKGFzc2VydGlvbiwgXCJwcm9taXNlXCIpO1xuXHRjb25zdCBwcm9taXNlID0gcHJvbWlzZU5hbWUgPyBgLiR7cHJvbWlzZU5hbWV9YCA6IFwiXCI7XG5cdHJldHVybiBgZXhwZWN0JHtzb2Z0fShhY3R1YWwpJHtwcm9taXNlfS4ke25vdH0ke25hbWV9YDtcbn1cbmZ1bmN0aW9uIHJlY29yZEFzeW5jRXhwZWN0KF90ZXN0LCBwcm9taXNlLCBhc3NlcnRpb24sIGVycm9yLCBpc1NvZnQpIHtcblx0Y29uc3QgdGVzdCA9IF90ZXN0O1xuXHQvLyByZWNvcmQgcHJvbWlzZSBmb3IgdGVzdCwgdGhhdCByZXNvbHZlcyBiZWZvcmUgdGVzdCBlbmRzXG5cdGlmICh0ZXN0ICYmIHByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG5cdFx0Ly8gaWYgcHJvbWlzZSBpcyBleHBsaWNpdGx5IGF3YWl0ZWQsIHJlbW92ZSBpdCBmcm9tIHRoZSBsaXN0XG5cdFx0cHJvbWlzZSA9IHByb21pc2UuZmluYWxseSgoKSA9PiB7XG5cdFx0XHRpZiAoIXRlc3QucHJvbWlzZXMpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgaW5kZXggPSB0ZXN0LnByb21pc2VzLmluZGV4T2YocHJvbWlzZSk7XG5cdFx0XHRpZiAoaW5kZXggIT09IC0xKSB7XG5cdFx0XHRcdHRlc3QucHJvbWlzZXMuc3BsaWNlKGluZGV4LCAxKTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHQvLyByZWNvcmQgcHJvbWlzZVxuXHRcdGlmICghdGVzdC5wcm9taXNlcykge1xuXHRcdFx0dGVzdC5wcm9taXNlcyA9IFtdO1xuXHRcdH1cblx0XHQvLyBzZXR1cCBgZXhwZWN0LnNvZnRgIGhhbmRsZXIgaGVyZSBpbnN0ZWFkIG9mIGB3cmFwQXNzZXJ0aW9uYFxuXHRcdC8vIHRvIGF2b2lkIGRvdWJsZSBlcnJvciB0cmFja2luZyB3aGlsZSBrZWVwaW5nIG5vbi1hd2FpdCBwcm9taXNlIGRldGVjdGlvbi5cblx0XHRpZiAoaXNTb2Z0KSB7XG5cdFx0XHRwcm9taXNlID0gcHJvbWlzZS50aGVuKG5vb3AsIChlcnIpID0+IHtcblx0XHRcdFx0aGFuZGxlVGVzdEVycm9yKHRlc3QsIGVycik7XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0dGVzdC5wcm9taXNlcy5wdXNoKHByb21pc2UpO1xuXHRcdGxldCByZXNvbHZlZCA9IGZhbHNlO1xuXHRcdHRlc3Qub25GaW5pc2hlZCA/Pz0gW107XG5cdFx0dGVzdC5vbkZpbmlzaGVkLnB1c2goKCkgPT4ge1xuXHRcdFx0aWYgKCFyZXNvbHZlZCkge1xuXHRcdFx0XHRjb25zdCBwcm9jZXNzb3IgPSBnbG9iYWxUaGlzLl9fdml0ZXN0X3dvcmtlcl9fPy5vbkZpbHRlclN0YWNrVHJhY2UgfHwgKChzKSA9PiBzIHx8IFwiXCIpO1xuXHRcdFx0XHRjb25zdCBzdGFjayA9IHByb2Nlc3NvcihlcnJvci5zdGFjayk7XG5cdFx0XHRcdGNvbnNvbGUud2FybihbXG5cdFx0XHRcdFx0YFByb21pc2UgcmV0dXJuZWQgYnkgXFxgJHthc3NlcnRpb259XFxgIHdhcyBub3QgYXdhaXRlZC4gYCxcblx0XHRcdFx0XHRcIlZpdGVzdCBjdXJyZW50bHkgYXV0by1hd2FpdHMgaGFuZ2luZyBhc3NlcnRpb25zIGF0IHRoZSBlbmQgb2YgdGhlIHRlc3QsIGJ1dCB0aGlzIHdpbGwgY2F1c2UgdGhlIHRlc3QgdG8gZmFpbCBpbiB0aGUgbmV4dCBWaXRlc3QgbWFqb3IuIFwiLFxuXHRcdFx0XHRcdFwiUGxlYXNlIHJlbWVtYmVyIHRvIGF3YWl0IHRoZSBhc3NlcnRpb24uXFxuXCIsXG5cdFx0XHRcdFx0c3RhY2tcblx0XHRcdFx0XS5qb2luKFwiXCIpKTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRyZXR1cm4ge1xuXHRcdFx0dGhlbihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkge1xuXHRcdFx0XHRyZXNvbHZlZCA9IHRydWU7XG5cdFx0XHRcdHJldHVybiBwcm9taXNlLnRoZW4ob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpO1xuXHRcdFx0fSxcblx0XHRcdGNhdGNoKG9uUmVqZWN0ZWQpIHtcblx0XHRcdFx0cmVzb2x2ZWQgPSB0cnVlO1xuXHRcdFx0XHRyZXR1cm4gcHJvbWlzZS5jYXRjaChvblJlamVjdGVkKTtcblx0XHRcdH0sXG5cdFx0XHRmaW5hbGx5KG9uRmluYWxseSkge1xuXHRcdFx0XHRyZXNvbHZlZCA9IHRydWU7XG5cdFx0XHRcdHJldHVybiBwcm9taXNlLmZpbmFsbHkob25GaW5hbGx5KTtcblx0XHRcdH0sXG5cdFx0XHRbU3ltYm9sLnRvU3RyaW5nVGFnXTogXCJQcm9taXNlXCJcblx0XHR9O1xuXHR9XG5cdHJldHVybiBwcm9taXNlO1xufVxuZnVuY3Rpb24gaGFuZGxlVGVzdEVycm9yKHRlc3QsIGVycikge1xuXHR0ZXN0LnJlc3VsdCB8fD0geyBzdGF0ZTogXCJmYWlsXCIgfTtcblx0dGVzdC5yZXN1bHQuc3RhdGUgPSBcImZhaWxcIjtcblx0dGVzdC5yZXN1bHQuZXJyb3JzIHx8PSBbXTtcblx0dGVzdC5yZXN1bHQuZXJyb3JzLnB1c2gocHJvY2Vzc0Vycm9yKGVycikpO1xufVxuZnVuY3Rpb24gd3JhcEFzc2VydGlvbih1dGlscywgbmFtZSwgZm4pIHtcblx0cmV0dXJuIGZ1bmN0aW9uKC4uLmFyZ3MpIHtcblx0XHQvLyBwcml2YXRlXG5cdFx0aWYgKG5hbWUgIT09IFwid2l0aFRlc3RcIikge1xuXHRcdFx0dXRpbHMuZmxhZyh0aGlzLCBcIl9uYW1lXCIsIG5hbWUpO1xuXHRcdH1cblx0XHRpZiAoIXV0aWxzLmZsYWcodGhpcywgXCJzb2Z0XCIpKSB7XG5cdFx0XHQvLyBhdm9pZCBXZWJLaXQncyBwcm9wZXIgdGFpbCBjYWxsIHRvIHByZXNlcnZlIHN0YWNrdHJhY2Ugb2Zmc2V0IGZvciBpbmxpbmUgc25hcHNob3Rcblx0XHRcdC8vIGh0dHBzOi8vd2Via2l0Lm9yZy9ibG9nLzYyNDAvZWNtYXNjcmlwdC02LXByb3Blci10YWlsLWNhbGxzLWluLXdlYmtpdFxuXHRcdFx0dHJ5IHtcblx0XHRcdFx0cmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXHRcdFx0fSBmaW5hbGx5IHt9XG5cdFx0fVxuXHRcdGNvbnN0IHRlc3QgPSB1dGlscy5mbGFnKHRoaXMsIFwidml0ZXN0LXRlc3RcIik7XG5cdFx0aWYgKCF0ZXN0KSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJleHBlY3Quc29mdCgpIGNhbiBvbmx5IGJlIHVzZWQgaW5zaWRlIGEgdGVzdFwiKTtcblx0XHR9XG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IHJlc3VsdCA9IGZuLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXHRcdFx0aWYgKHJlc3VsdCAmJiB0eXBlb2YgcmVzdWx0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiByZXN1bHQudGhlbiA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHRcdHJldHVybiByZXN1bHQudGhlbihub29wLCAoZXJyKSA9PiB7XG5cdFx0XHRcdFx0aGFuZGxlVGVzdEVycm9yKHRlc3QsIGVycik7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdGhhbmRsZVRlc3RFcnJvcih0ZXN0LCBlcnIpO1xuXHRcdH1cblx0fTtcbn1cblxuLy8gSmVzdCBFeHBlY3QgQ29tcGFjdFxuY29uc3QgSmVzdENoYWlFeHBlY3QgPSAoY2hhaSwgdXRpbHMpID0+IHtcblx0Y29uc3QgeyBBc3NlcnRpb25FcnJvciB9ID0gY2hhaTtcblx0Y29uc3QgY3VzdG9tVGVzdGVycyA9IGdldEN1c3RvbUVxdWFsaXR5VGVzdGVycygpO1xuXHRmdW5jdGlvbiBkZWYobmFtZSwgZm4pIHtcblx0XHRjb25zdCBhZGRNZXRob2QgPSAobikgPT4ge1xuXHRcdFx0Y29uc3Qgc29mdFdyYXBwZXIgPSB3cmFwQXNzZXJ0aW9uKHV0aWxzLCBuLCBmbik7XG5cdFx0XHR1dGlscy5hZGRNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCBuLCBzb2Z0V3JhcHBlcik7XG5cdFx0XHR1dGlscy5hZGRNZXRob2QoZ2xvYmFsVGhpc1tKRVNUX01BVENIRVJTX09CSkVDVF0ubWF0Y2hlcnMsIG4sIHNvZnRXcmFwcGVyKTtcblx0XHR9O1xuXHRcdGlmIChBcnJheS5pc0FycmF5KG5hbWUpKSB7XG5cdFx0XHRuYW1lLmZvckVhY2goKG4pID0+IGFkZE1ldGhvZChuKSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGFkZE1ldGhvZChuYW1lKTtcblx0XHR9XG5cdH1cblx0W1xuXHRcdFwidGhyb3dcIixcblx0XHRcInRocm93c1wiLFxuXHRcdFwiVGhyb3dcIlxuXHRdLmZvckVhY2goKG0pID0+IHtcblx0XHR1dGlscy5vdmVyd3JpdGVNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCBtLCAoX3N1cGVyKSA9PiB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oLi4uYXJncykge1xuXHRcdFx0XHRjb25zdCBwcm9taXNlID0gdXRpbHMuZmxhZyh0aGlzLCBcInByb21pc2VcIik7XG5cdFx0XHRcdGNvbnN0IG9iamVjdCA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0XHRcdGNvbnN0IGlzTm90ID0gdXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKTtcblx0XHRcdFx0aWYgKHByb21pc2UgPT09IFwicmVqZWN0c1wiKSB7XG5cdFx0XHRcdFx0dXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiLCAoKSA9PiB7XG5cdFx0XHRcdFx0XHR0aHJvdyBvYmplY3Q7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH0gZWxzZSBpZiAocHJvbWlzZSA9PT0gXCJyZXNvbHZlc1wiICYmIHR5cGVvZiBvYmplY3QgIT09IFwiZnVuY3Rpb25cIikge1xuXHRcdFx0XHRcdGlmICghaXNOb3QpIHtcblx0XHRcdFx0XHRcdGNvbnN0IG1lc3NhZ2UgPSB1dGlscy5mbGFnKHRoaXMsIFwibWVzc2FnZVwiKSB8fCBcImV4cGVjdGVkIHByb21pc2UgdG8gdGhyb3cgYW4gZXJyb3IsIGJ1dCBpdCBkaWRuJ3RcIjtcblx0XHRcdFx0XHRcdGNvbnN0IGVycm9yID0geyBzaG93RGlmZjogZmFsc2UgfTtcblx0XHRcdFx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtZXNzYWdlLCBlcnJvciwgdXRpbHMuZmxhZyh0aGlzLCBcInNzZmlcIikpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdF9zdXBlci5hcHBseSh0aGlzLCBhcmdzKTtcblx0XHRcdH07XG5cdFx0fSk7XG5cdH0pO1xuXHQvLyBAdHMtZXhwZWN0LWVycm9yIEBpbnRlcm5hbFxuXHRkZWYoXCJ3aXRoVGVzdFwiLCBmdW5jdGlvbih0ZXN0KSB7XG5cdFx0dXRpbHMuZmxhZyh0aGlzLCBcInZpdGVzdC10ZXN0XCIsIHRlc3QpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9KTtcblx0ZGVmKFwidG9FcXVhbFwiLCBmdW5jdGlvbihleHBlY3RlZCkge1xuXHRcdGNvbnN0IGFjdHVhbCA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0Y29uc3QgZXF1YWwgPSBlcXVhbHMoYWN0dWFsLCBleHBlY3RlZCwgWy4uLmN1c3RvbVRlc3RlcnMsIGl0ZXJhYmxlRXF1YWxpdHldKTtcblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQoZXF1YWwsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBkZWVwbHkgZXF1YWwgI3tleHB9XCIsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgZGVlcGx5IGVxdWFsICN7ZXhwfVwiLCBleHBlY3RlZCwgYWN0dWFsKTtcblx0fSk7XG5cdGRlZihcInRvU3RyaWN0RXF1YWxcIiwgZnVuY3Rpb24oZXhwZWN0ZWQpIHtcblx0XHRjb25zdCBvYmogPSB1dGlscy5mbGFnKHRoaXMsIFwib2JqZWN0XCIpO1xuXHRcdGNvbnN0IGVxdWFsID0gZXF1YWxzKG9iaiwgZXhwZWN0ZWQsIFtcblx0XHRcdC4uLmN1c3RvbVRlc3RlcnMsXG5cdFx0XHRpdGVyYWJsZUVxdWFsaXR5LFxuXHRcdFx0dHlwZUVxdWFsaXR5LFxuXHRcdFx0c3BhcnNlQXJyYXlFcXVhbGl0eSxcblx0XHRcdGFycmF5QnVmZmVyRXF1YWxpdHlcblx0XHRdLCB0cnVlKTtcblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQoZXF1YWwsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBzdHJpY3RseSBlcXVhbCAje2V4cH1cIiwgXCJleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBzdHJpY3RseSBlcXVhbCAje2V4cH1cIiwgZXhwZWN0ZWQsIG9iaik7XG5cdH0pO1xuXHRkZWYoXCJ0b0JlXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdGhpcy5fb2JqO1xuXHRcdGNvbnN0IHBhc3MgPSBPYmplY3QuaXMoYWN0dWFsLCBleHBlY3RlZCk7XG5cdFx0bGV0IGRlZXBFcXVhbGl0eU5hbWUgPSBcIlwiO1xuXHRcdGlmICghcGFzcykge1xuXHRcdFx0Y29uc3QgdG9TdHJpY3RFcXVhbFBhc3MgPSBlcXVhbHMoYWN0dWFsLCBleHBlY3RlZCwgW1xuXHRcdFx0XHQuLi5jdXN0b21UZXN0ZXJzLFxuXHRcdFx0XHRpdGVyYWJsZUVxdWFsaXR5LFxuXHRcdFx0XHR0eXBlRXF1YWxpdHksXG5cdFx0XHRcdHNwYXJzZUFycmF5RXF1YWxpdHksXG5cdFx0XHRcdGFycmF5QnVmZmVyRXF1YWxpdHlcblx0XHRcdF0sIHRydWUpO1xuXHRcdFx0aWYgKHRvU3RyaWN0RXF1YWxQYXNzKSB7XG5cdFx0XHRcdGRlZXBFcXVhbGl0eU5hbWUgPSBcInRvU3RyaWN0RXF1YWxcIjtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNvbnN0IHRvRXF1YWxQYXNzID0gZXF1YWxzKGFjdHVhbCwgZXhwZWN0ZWQsIFsuLi5jdXN0b21UZXN0ZXJzLCBpdGVyYWJsZUVxdWFsaXR5XSk7XG5cdFx0XHRcdGlmICh0b0VxdWFsUGFzcykge1xuXHRcdFx0XHRcdGRlZXBFcXVhbGl0eU5hbWUgPSBcInRvRXF1YWxcIjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQocGFzcywgZ2VuZXJhdGVUb0JlTWVzc2FnZShkZWVwRXF1YWxpdHlOYW1lKSwgXCJleHBlY3RlZCAje3RoaXN9IG5vdCB0byBiZSAje2V4cH0gLy8gT2JqZWN0LmlzIGVxdWFsaXR5XCIsIGV4cGVjdGVkLCBhY3R1YWwpO1xuXHR9KTtcblx0ZGVmKFwidG9NYXRjaE9iamVjdFwiLCBmdW5jdGlvbihleHBlY3RlZCkge1xuXHRcdGNvbnN0IGFjdHVhbCA9IHRoaXMuX29iajtcblx0XHRjb25zdCBwYXNzID0gZXF1YWxzKGFjdHVhbCwgZXhwZWN0ZWQsIFtcblx0XHRcdC4uLmN1c3RvbVRlc3RlcnMsXG5cdFx0XHRpdGVyYWJsZUVxdWFsaXR5LFxuXHRcdFx0c3Vic2V0RXF1YWxpdHlcblx0XHRdKTtcblx0XHRjb25zdCBpc05vdCA9IHV0aWxzLmZsYWcodGhpcywgXCJuZWdhdGVcIik7XG5cdFx0Y29uc3QgeyBzdWJzZXQ6IGFjdHVhbFN1YnNldCwgc3RyaXBwZWQgfSA9IGdldE9iamVjdFN1YnNldChhY3R1YWwsIGV4cGVjdGVkLCBjdXN0b21UZXN0ZXJzKTtcblx0XHRpZiAocGFzcyAmJiBpc05vdCB8fCAhcGFzcyAmJiAhaXNOb3QpIHtcblx0XHRcdGNvbnN0IG1zZyA9IHV0aWxzLmdldE1lc3NhZ2UodGhpcywgW1xuXHRcdFx0XHRwYXNzLFxuXHRcdFx0XHRcImV4cGVjdGVkICN7dGhpc30gdG8gbWF0Y2ggb2JqZWN0ICN7ZXhwfVwiLFxuXHRcdFx0XHRcImV4cGVjdGVkICN7dGhpc30gdG8gbm90IG1hdGNoIG9iamVjdCAje2V4cH1cIixcblx0XHRcdFx0ZXhwZWN0ZWQsXG5cdFx0XHRcdGFjdHVhbFN1YnNldCxcblx0XHRcdFx0ZmFsc2Vcblx0XHRcdF0pO1xuXHRcdFx0Y29uc3QgbWVzc2FnZSA9IHN0cmlwcGVkID09PSAwID8gbXNnIDogYCR7bXNnfVxcbigke3N0cmlwcGVkfSBtYXRjaGluZyAke3N0cmlwcGVkID09PSAxID8gXCJwcm9wZXJ0eVwiIDogXCJwcm9wZXJ0aWVzXCJ9IG9taXR0ZWQgZnJvbSBhY3R1YWwpYDtcblx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtZXNzYWdlLCB7XG5cdFx0XHRcdHNob3dEaWZmOiB0cnVlLFxuXHRcdFx0XHRleHBlY3RlZCxcblx0XHRcdFx0YWN0dWFsOiBhY3R1YWxTdWJzZXRcblx0XHRcdH0pO1xuXHRcdH1cblx0fSk7XG5cdGRlZihcInRvTWF0Y2hcIiwgZnVuY3Rpb24oZXhwZWN0ZWQpIHtcblx0XHRjb25zdCBhY3R1YWwgPSB0aGlzLl9vYmo7XG5cdFx0aWYgKHR5cGVvZiBhY3R1YWwgIT09IFwic3RyaW5nXCIpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYC50b01hdGNoKCkgZXhwZWN0cyB0byByZWNlaXZlIGEgc3RyaW5nLCBidXQgZ290ICR7dHlwZW9mIGFjdHVhbH1gKTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuYXNzZXJ0KHR5cGVvZiBleHBlY3RlZCA9PT0gXCJzdHJpbmdcIiA/IGFjdHVhbC5pbmNsdWRlcyhleHBlY3RlZCkgOiBhY3R1YWwubWF0Y2goZXhwZWN0ZWQpLCBgZXhwZWN0ZWQgI3t0aGlzfSB0byBtYXRjaCAje2V4cH1gLCBgZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gbWF0Y2ggI3tleHB9YCwgZXhwZWN0ZWQsIGFjdHVhbCk7XG5cdH0pO1xuXHRkZWYoXCJ0b0NvbnRhaW5cIiwgZnVuY3Rpb24oaXRlbSkge1xuXHRcdGNvbnN0IGFjdHVhbCA9IHRoaXMuX29iajtcblx0XHRpZiAodHlwZW9mIE5vZGUgIT09IFwidW5kZWZpbmVkXCIgJiYgYWN0dWFsIGluc3RhbmNlb2YgTm9kZSkge1xuXHRcdFx0aWYgKCEoaXRlbSBpbnN0YW5jZW9mIE5vZGUpKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYHRvQ29udGFpbigpIGV4cGVjdGVkIGEgRE9NIG5vZGUgYXMgdGhlIGFyZ3VtZW50LCBidXQgZ290ICR7dHlwZW9mIGl0ZW19YCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdGhpcy5hc3NlcnQoYWN0dWFsLmNvbnRhaW5zKGl0ZW0pLCBcImV4cGVjdGVkICN7dGhpc30gdG8gY29udGFpbiBlbGVtZW50ICN7ZXhwfVwiLCBcImV4cGVjdGVkICN7dGhpc30gbm90IHRvIGNvbnRhaW4gZWxlbWVudCAje2V4cH1cIiwgaXRlbSwgYWN0dWFsKTtcblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBET01Ub2tlbkxpc3QgIT09IFwidW5kZWZpbmVkXCIgJiYgYWN0dWFsIGluc3RhbmNlb2YgRE9NVG9rZW5MaXN0KSB7XG5cdFx0XHRhc3NlcnRUeXBlcyhpdGVtLCBcImNsYXNzIG5hbWVcIiwgW1wic3RyaW5nXCJdKTtcblx0XHRcdGNvbnN0IGlzTm90ID0gdXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKTtcblx0XHRcdGNvbnN0IGV4cGVjdGVkQ2xhc3NMaXN0ID0gaXNOb3QgPyBhY3R1YWwudmFsdWUucmVwbGFjZShpdGVtLCBcIlwiKS50cmltKCkgOiBgJHthY3R1YWwudmFsdWV9ICR7aXRlbX1gO1xuXHRcdFx0cmV0dXJuIHRoaXMuYXNzZXJ0KGFjdHVhbC5jb250YWlucyhpdGVtKSwgYGV4cGVjdGVkIFwiJHthY3R1YWwudmFsdWV9XCIgdG8gY29udGFpbiBcIiR7aXRlbX1cImAsIGBleHBlY3RlZCBcIiR7YWN0dWFsLnZhbHVlfVwiIG5vdCB0byBjb250YWluIFwiJHtpdGVtfVwiYCwgZXhwZWN0ZWRDbGFzc0xpc3QsIGFjdHVhbC52YWx1ZSk7XG5cdFx0fVxuXHRcdC8vIGhhbmRsZSBzaW1wbGUgY2FzZSBvbiBvdXIgb3duIHVzaW5nIGB0aGlzLmFzc2VydGAgdG8gaW5jbHVkZSBkaWZmIGluIGVycm9yIG1lc3NhZ2Vcblx0XHRpZiAodHlwZW9mIGFjdHVhbCA9PT0gXCJzdHJpbmdcIiAmJiB0eXBlb2YgaXRlbSA9PT0gXCJzdHJpbmdcIikge1xuXHRcdFx0cmV0dXJuIHRoaXMuYXNzZXJ0KGFjdHVhbC5pbmNsdWRlcyhpdGVtKSwgYGV4cGVjdGVkICN7dGhpc30gdG8gY29udGFpbiAje2V4cH1gLCBgZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gY29udGFpbiAje2V4cH1gLCBpdGVtLCBhY3R1YWwpO1xuXHRcdH1cblx0XHQvLyBtYWtlIFwiYWN0dWFsXCIgaW5kZXhhYmxlIHRvIGhhdmUgY29tcGF0aWJpbGl0eSB3aXRoIGplc3Rcblx0XHRpZiAoYWN0dWFsICE9IG51bGwgJiYgdHlwZW9mIGFjdHVhbCAhPT0gXCJzdHJpbmdcIikge1xuXHRcdFx0dXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiLCBBcnJheS5mcm9tKGFjdHVhbCkpO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5jb250YWluKGl0ZW0pO1xuXHR9KTtcblx0ZGVmKFwidG9Db250YWluRXF1YWxcIiwgZnVuY3Rpb24oZXhwZWN0ZWQpIHtcblx0XHRjb25zdCBvYmogPSB1dGlscy5mbGFnKHRoaXMsIFwib2JqZWN0XCIpO1xuXHRcdGNvbnN0IGluZGV4ID0gQXJyYXkuZnJvbShvYmopLmZpbmRJbmRleCgoaXRlbSkgPT4ge1xuXHRcdFx0cmV0dXJuIGVxdWFscyhpdGVtLCBleHBlY3RlZCwgY3VzdG9tVGVzdGVycyk7XG5cdFx0fSk7XG5cdFx0dGhpcy5hc3NlcnQoaW5kZXggIT09IC0xLCBcImV4cGVjdGVkICN7dGhpc30gdG8gZGVlcCBlcXVhbGx5IGNvbnRhaW4gI3tleHB9XCIsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgZGVlcCBlcXVhbGx5IGNvbnRhaW4gI3tleHB9XCIsIGV4cGVjdGVkKTtcblx0fSk7XG5cdGRlZihcInRvQmVUcnV0aHlcIiwgZnVuY3Rpb24oKSB7XG5cdFx0Y29uc3Qgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKTtcblx0XHR0aGlzLmFzc2VydChCb29sZWFuKG9iaiksIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSB0cnV0aHlcIiwgXCJleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBiZSB0cnV0aHlcIiwgdHJ1ZSwgb2JqKTtcblx0fSk7XG5cdGRlZihcInRvQmVGYWxzeVwiLCBmdW5jdGlvbigpIHtcblx0XHRjb25zdCBvYmogPSB1dGlscy5mbGFnKHRoaXMsIFwib2JqZWN0XCIpO1xuXHRcdHRoaXMuYXNzZXJ0KCFvYmosIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBmYWxzeVwiLCBcImV4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIGZhbHN5XCIsIGZhbHNlLCBvYmopO1xuXHR9KTtcblx0ZGVmKFwidG9CZUdyZWF0ZXJUaGFuXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdGhpcy5fb2JqO1xuXHRcdGFzc2VydFR5cGVzKGFjdHVhbCwgXCJhY3R1YWxcIiwgW1wibnVtYmVyXCIsIFwiYmlnaW50XCJdKTtcblx0XHRhc3NlcnRUeXBlcyhleHBlY3RlZCwgXCJleHBlY3RlZFwiLCBbXCJudW1iZXJcIiwgXCJiaWdpbnRcIl0pO1xuXHRcdHJldHVybiB0aGlzLmFzc2VydChhY3R1YWwgPiBleHBlY3RlZCwgYGV4cGVjdGVkICR7YWN0dWFsfSB0byBiZSBncmVhdGVyIHRoYW4gJHtleHBlY3RlZH1gLCBgZXhwZWN0ZWQgJHthY3R1YWx9IHRvIGJlIG5vdCBncmVhdGVyIHRoYW4gJHtleHBlY3RlZH1gLCBleHBlY3RlZCwgYWN0dWFsLCBmYWxzZSk7XG5cdH0pO1xuXHRkZWYoXCJ0b0JlR3JlYXRlclRoYW5PckVxdWFsXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdGhpcy5fb2JqO1xuXHRcdGFzc2VydFR5cGVzKGFjdHVhbCwgXCJhY3R1YWxcIiwgW1wibnVtYmVyXCIsIFwiYmlnaW50XCJdKTtcblx0XHRhc3NlcnRUeXBlcyhleHBlY3RlZCwgXCJleHBlY3RlZFwiLCBbXCJudW1iZXJcIiwgXCJiaWdpbnRcIl0pO1xuXHRcdHJldHVybiB0aGlzLmFzc2VydChhY3R1YWwgPj0gZXhwZWN0ZWQsIGBleHBlY3RlZCAke2FjdHVhbH0gdG8gYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICR7ZXhwZWN0ZWR9YCwgYGV4cGVjdGVkICR7YWN0dWFsfSB0byBiZSBub3QgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICR7ZXhwZWN0ZWR9YCwgZXhwZWN0ZWQsIGFjdHVhbCwgZmFsc2UpO1xuXHR9KTtcblx0ZGVmKFwidG9CZUxlc3NUaGFuXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdGhpcy5fb2JqO1xuXHRcdGFzc2VydFR5cGVzKGFjdHVhbCwgXCJhY3R1YWxcIiwgW1wibnVtYmVyXCIsIFwiYmlnaW50XCJdKTtcblx0XHRhc3NlcnRUeXBlcyhleHBlY3RlZCwgXCJleHBlY3RlZFwiLCBbXCJudW1iZXJcIiwgXCJiaWdpbnRcIl0pO1xuXHRcdHJldHVybiB0aGlzLmFzc2VydChhY3R1YWwgPCBleHBlY3RlZCwgYGV4cGVjdGVkICR7YWN0dWFsfSB0byBiZSBsZXNzIHRoYW4gJHtleHBlY3RlZH1gLCBgZXhwZWN0ZWQgJHthY3R1YWx9IHRvIGJlIG5vdCBsZXNzIHRoYW4gJHtleHBlY3RlZH1gLCBleHBlY3RlZCwgYWN0dWFsLCBmYWxzZSk7XG5cdH0pO1xuXHRkZWYoXCJ0b0JlTGVzc1RoYW5PckVxdWFsXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdGhpcy5fb2JqO1xuXHRcdGFzc2VydFR5cGVzKGFjdHVhbCwgXCJhY3R1YWxcIiwgW1wibnVtYmVyXCIsIFwiYmlnaW50XCJdKTtcblx0XHRhc3NlcnRUeXBlcyhleHBlY3RlZCwgXCJleHBlY3RlZFwiLCBbXCJudW1iZXJcIiwgXCJiaWdpbnRcIl0pO1xuXHRcdHJldHVybiB0aGlzLmFzc2VydChhY3R1YWwgPD0gZXhwZWN0ZWQsIGBleHBlY3RlZCAke2FjdHVhbH0gdG8gYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICR7ZXhwZWN0ZWR9YCwgYGV4cGVjdGVkICR7YWN0dWFsfSB0byBiZSBub3QgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICR7ZXhwZWN0ZWR9YCwgZXhwZWN0ZWQsIGFjdHVhbCwgZmFsc2UpO1xuXHR9KTtcblx0ZGVmKFwidG9CZU5hTlwiLCBmdW5jdGlvbigpIHtcblx0XHRjb25zdCBvYmogPSB1dGlscy5mbGFnKHRoaXMsIFwib2JqZWN0XCIpO1xuXHRcdHRoaXMuYXNzZXJ0KE51bWJlci5pc05hTihvYmopLCBcImV4cGVjdGVkICN7dGhpc30gdG8gYmUgTmFOXCIsIFwiZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgTmFOXCIsIE51bWJlci5OYU4sIG9iaik7XG5cdH0pO1xuXHRkZWYoXCJ0b0JlVW5kZWZpbmVkXCIsIGZ1bmN0aW9uKCkge1xuXHRcdGNvbnN0IG9iaiA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0dGhpcy5hc3NlcnQodW5kZWZpbmVkID09PSBvYmosIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSB1bmRlZmluZWRcIiwgXCJleHBlY3RlZCAje3RoaXN9IG5vdCB0byBiZSB1bmRlZmluZWRcIiwgdW5kZWZpbmVkLCBvYmopO1xuXHR9KTtcblx0ZGVmKFwidG9CZU51bGxcIiwgZnVuY3Rpb24oKSB7XG5cdFx0Y29uc3Qgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKTtcblx0XHR0aGlzLmFzc2VydChvYmogPT09IG51bGwsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBudWxsXCIsIFwiZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgbnVsbFwiLCBudWxsLCBvYmopO1xuXHR9KTtcblx0ZGVmKFwidG9CZU51bGxhYmxlXCIsIGZ1bmN0aW9uKCkge1xuXHRcdGNvbnN0IG9iaiA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0dGhpcy5hc3NlcnQob2JqID09IG51bGwsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBudWxsaXNoXCIsIFwiZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgbnVsbGlzaFwiLCBudWxsLCBvYmopO1xuXHR9KTtcblx0ZGVmKFwidG9CZURlZmluZWRcIiwgZnVuY3Rpb24oKSB7XG5cdFx0Y29uc3Qgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKTtcblx0XHR0aGlzLmFzc2VydCh0eXBlb2Ygb2JqICE9PSBcInVuZGVmaW5lZFwiLCBcImV4cGVjdGVkICN7dGhpc30gdG8gYmUgZGVmaW5lZFwiLCBcImV4cGVjdGVkICN7dGhpc30gdG8gYmUgdW5kZWZpbmVkXCIsIG9iaik7XG5cdH0pO1xuXHRkZWYoXCJ0b0JlVHlwZU9mXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdHlwZW9mIHRoaXMuX29iajtcblx0XHRjb25zdCBlcXVhbCA9IGV4cGVjdGVkID09PSBhY3R1YWw7XG5cdFx0cmV0dXJuIHRoaXMuYXNzZXJ0KGVxdWFsLCBcImV4cGVjdGVkICN7dGhpc30gdG8gYmUgdHlwZSBvZiAje2V4cH1cIiwgXCJleHBlY3RlZCAje3RoaXN9IG5vdCB0byBiZSB0eXBlIG9mICN7ZXhwfVwiLCBleHBlY3RlZCwgYWN0dWFsKTtcblx0fSk7XG5cdGRlZihcInRvQmVJbnN0YW5jZU9mXCIsIGZ1bmN0aW9uKG9iaikge1xuXHRcdHJldHVybiB0aGlzLmluc3RhbmNlT2Yob2JqKTtcblx0fSk7XG5cdGRlZihcInRvSGF2ZUxlbmd0aFwiLCBmdW5jdGlvbihsZW5ndGgpIHtcblx0XHRyZXR1cm4gdGhpcy5oYXZlLmxlbmd0aChsZW5ndGgpO1xuXHR9KTtcblx0Ly8gZGVzdHJ1Y3R1cmluZywgYmVjYXVzZSBpdCBjaGVja3MgYGFyZ3VtZW50c2AgaW5zaWRlLCBhbmQgdmFsdWUgaXMgcGFzc2luZyBhcyBgdW5kZWZpbmVkYFxuXHRkZWYoXCJ0b0hhdmVQcm9wZXJ0eVwiLCBmdW5jdGlvbiguLi5hcmdzKSB7XG5cdFx0aWYgKEFycmF5LmlzQXJyYXkoYXJnc1swXSkpIHtcblx0XHRcdGFyZ3NbMF0gPSBhcmdzWzBdLm1hcCgoa2V5KSA9PiBTdHJpbmcoa2V5KS5yZXBsYWNlKC8oWy5bXFxdXSkvZywgXCJcXFxcJDFcIikpLmpvaW4oXCIuXCIpO1xuXHRcdH1cblx0XHRjb25zdCBhY3R1YWwgPSB0aGlzLl9vYmo7XG5cdFx0Y29uc3QgW3Byb3BlcnR5TmFtZSwgZXhwZWN0ZWRdID0gYXJncztcblx0XHRjb25zdCBnZXRWYWx1ZSA9ICgpID0+IHtcblx0XHRcdGNvbnN0IGhhc093biA9IE9iamVjdC5oYXNPd24oYWN0dWFsLCBwcm9wZXJ0eU5hbWUpO1xuXHRcdFx0aWYgKGhhc093bikge1xuXHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdHZhbHVlOiBhY3R1YWxbcHJvcGVydHlOYW1lXSxcblx0XHRcdFx0XHRleGlzdHM6IHRydWVcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB1dGlscy5nZXRQYXRoSW5mbyhhY3R1YWwsIHByb3BlcnR5TmFtZSk7XG5cdFx0fTtcblx0XHRjb25zdCB7IHZhbHVlLCBleGlzdHMgfSA9IGdldFZhbHVlKCk7XG5cdFx0Y29uc3QgcGFzcyA9IGV4aXN0cyAmJiAoYXJncy5sZW5ndGggPT09IDEgfHwgZXF1YWxzKGV4cGVjdGVkLCB2YWx1ZSwgY3VzdG9tVGVzdGVycykpO1xuXHRcdGNvbnN0IHZhbHVlU3RyaW5nID0gYXJncy5sZW5ndGggPT09IDEgPyBcIlwiIDogYCB3aXRoIHZhbHVlICR7dXRpbHMub2JqRGlzcGxheShleHBlY3RlZCl9YDtcblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQocGFzcywgYGV4cGVjdGVkICN7dGhpc30gdG8gaGF2ZSBwcm9wZXJ0eSBcIiR7cHJvcGVydHlOYW1lfVwiJHt2YWx1ZVN0cmluZ31gLCBgZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgaGF2ZSBwcm9wZXJ0eSBcIiR7cHJvcGVydHlOYW1lfVwiJHt2YWx1ZVN0cmluZ31gLCBleHBlY3RlZCwgZXhpc3RzID8gdmFsdWUgOiB1bmRlZmluZWQpO1xuXHR9KTtcblx0ZGVmKFwidG9CZUNsb3NlVG9cIiwgZnVuY3Rpb24ocmVjZWl2ZWQsIHByZWNpc2lvbiA9IDIpIHtcblx0XHRjb25zdCBleHBlY3RlZCA9IHRoaXMuX29iajtcblx0XHRsZXQgcGFzcyA9IGZhbHNlO1xuXHRcdGxldCBleHBlY3RlZERpZmYgPSAwO1xuXHRcdGxldCByZWNlaXZlZERpZmYgPSAwO1xuXHRcdGlmIChyZWNlaXZlZCA9PT0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZICYmIGV4cGVjdGVkID09PSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpIHtcblx0XHRcdHBhc3MgPSB0cnVlO1xuXHRcdH0gZWxzZSBpZiAocmVjZWl2ZWQgPT09IE51bWJlci5ORUdBVElWRV9JTkZJTklUWSAmJiBleHBlY3RlZCA9PT0gTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZKSB7XG5cdFx0XHRwYXNzID0gdHJ1ZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZXhwZWN0ZWREaWZmID0gMTAgKiogLXByZWNpc2lvbiAvIDI7XG5cdFx0XHRyZWNlaXZlZERpZmYgPSBNYXRoLmFicyhleHBlY3RlZCAtIHJlY2VpdmVkKTtcblx0XHRcdHBhc3MgPSByZWNlaXZlZERpZmYgPCBleHBlY3RlZERpZmY7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmFzc2VydChwYXNzLCBgZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBjbG9zZSB0byAje2V4cH0sIHJlY2VpdmVkIGRpZmZlcmVuY2UgaXMgJHtyZWNlaXZlZERpZmZ9LCBidXQgZXhwZWN0ZWQgJHtleHBlY3RlZERpZmZ9YCwgYGV4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIGNsb3NlIHRvICN7ZXhwfSwgcmVjZWl2ZWQgZGlmZmVyZW5jZSBpcyAke3JlY2VpdmVkRGlmZn0sIGJ1dCBleHBlY3RlZCAke2V4cGVjdGVkRGlmZn1gLCByZWNlaXZlZCwgZXhwZWN0ZWQsIGZhbHNlKTtcblx0fSk7XG5cdGZ1bmN0aW9uIGFzc2VydElzTW9jayhhc3NlcnRpb24pIHtcblx0XHRpZiAoIWlzTW9ja0Z1bmN0aW9uKGFzc2VydGlvbi5fb2JqKSkge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihgJHt1dGlscy5pbnNwZWN0KGFzc2VydGlvbi5fb2JqKX0gaXMgbm90IGEgc3B5IG9yIGEgY2FsbCB0byBhIHNweSFgKTtcblx0XHR9XG5cdH1cblx0ZnVuY3Rpb24gZ2V0U3B5KGFzc2VydGlvbikge1xuXHRcdGFzc2VydElzTW9jayhhc3NlcnRpb24pO1xuXHRcdHJldHVybiBhc3NlcnRpb24uX29iajtcblx0fVxuXHRkZWYoW1widG9IYXZlQmVlbkNhbGxlZFRpbWVzXCIsIFwidG9CZUNhbGxlZFRpbWVzXCJdLCBmdW5jdGlvbihudW1iZXIpIHtcblx0XHRjb25zdCBzcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdGNvbnN0IGNhbGxDb3VudCA9IHNweS5tb2NrLmNhbGxzLmxlbmd0aDtcblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQoY2FsbENvdW50ID09PSBudW1iZXIsIGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byBiZSBjYWxsZWQgI3tleHB9IHRpbWVzLCBidXQgZ290ICR7Y2FsbENvdW50fSB0aW1lc2AsIGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byBub3QgYmUgY2FsbGVkICN7ZXhwfSB0aW1lc2AsIG51bWJlciwgY2FsbENvdW50LCBmYWxzZSk7XG5cdH0pO1xuXHRkZWYoXCJ0b0hhdmVCZWVuQ2FsbGVkT25jZVwiLCBmdW5jdGlvbigpIHtcblx0XHRjb25zdCBzcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdGNvbnN0IGNhbGxDb3VudCA9IHNweS5tb2NrLmNhbGxzLmxlbmd0aDtcblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQoY2FsbENvdW50ID09PSAxLCBgZXhwZWN0ZWQgXCIke3NweU5hbWV9XCIgdG8gYmUgY2FsbGVkIG9uY2UsIGJ1dCBnb3QgJHtjYWxsQ291bnR9IHRpbWVzYCwgYGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIG5vdCBiZSBjYWxsZWQgb25jZWAsIDEsIGNhbGxDb3VudCwgZmFsc2UpO1xuXHR9KTtcblx0ZGVmKFtcInRvSGF2ZUJlZW5DYWxsZWRcIiwgXCJ0b0JlQ2FsbGVkXCJdLCBmdW5jdGlvbigpIHtcblx0XHRjb25zdCBzcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdGNvbnN0IGNhbGxDb3VudCA9IHNweS5tb2NrLmNhbGxzLmxlbmd0aDtcblx0XHRjb25zdCBjYWxsZWQgPSBjYWxsQ291bnQgPiAwO1xuXHRcdGNvbnN0IGlzTm90ID0gdXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKTtcblx0XHRsZXQgbXNnID0gdXRpbHMuZ2V0TWVzc2FnZSh0aGlzLCBbXG5cdFx0XHRjYWxsZWQsXG5cdFx0XHRgZXhwZWN0ZWQgXCIke3NweU5hbWV9XCIgdG8gYmUgY2FsbGVkIGF0IGxlYXN0IG9uY2VgLFxuXHRcdFx0YGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIG5vdCBiZSBjYWxsZWQgYXQgYWxsLCBidXQgYWN0dWFsbHkgYmVlbiBjYWxsZWQgJHtjYWxsQ291bnR9IHRpbWVzYCxcblx0XHRcdHRydWUsXG5cdFx0XHRjYWxsZWRcblx0XHRdKTtcblx0XHRpZiAoY2FsbGVkICYmIGlzTm90KSB7XG5cdFx0XHRtc2cgPSBmb3JtYXRDYWxscyhzcHksIG1zZyk7XG5cdFx0fVxuXHRcdGlmIChjYWxsZWQgJiYgaXNOb3QgfHwgIWNhbGxlZCAmJiAhaXNOb3QpIHtcblx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtc2cpO1xuXHRcdH1cblx0fSk7XG5cdC8vIG1hbnVhbGx5IGNvbXBhcmUgYXJyYXkgZWxlbWVudHMgc2luY2UgYGplc3RFcXVhbHNgIGNhbm5vdFxuXHQvLyBhcHBseSBhc3ltbWV0cmljIG1hdGNoZXIgdG8gYHVuZGVmaW5lZGAgYXJyYXkgZWxlbWVudC5cblx0ZnVuY3Rpb24gZXF1YWxzQXJndW1lbnRBcnJheShhLCBiKSB7XG5cdFx0cmV0dXJuIGEubGVuZ3RoID09PSBiLmxlbmd0aCAmJiBhLmV2ZXJ5KChhSXRlbSwgaSkgPT4gZXF1YWxzKGFJdGVtLCBiW2ldLCBbLi4uY3VzdG9tVGVzdGVycywgaXRlcmFibGVFcXVhbGl0eV0pKTtcblx0fVxuXHRkZWYoW1widG9IYXZlQmVlbkNhbGxlZFdpdGhcIiwgXCJ0b0JlQ2FsbGVkV2l0aFwiXSwgZnVuY3Rpb24oLi4uYXJncykge1xuXHRcdGNvbnN0IHNweSA9IGdldFNweSh0aGlzKTtcblx0XHRjb25zdCBzcHlOYW1lID0gc3B5LmdldE1vY2tOYW1lKCk7XG5cdFx0Y29uc3QgcGFzcyA9IHNweS5tb2NrLmNhbGxzLnNvbWUoKGNhbGxBcmcpID0+IGVxdWFsc0FyZ3VtZW50QXJyYXkoY2FsbEFyZywgYXJncykpO1xuXHRcdGNvbnN0IGlzTm90ID0gdXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKTtcblx0XHRjb25zdCBtc2cgPSB1dGlscy5nZXRNZXNzYWdlKHRoaXMsIFtcblx0XHRcdHBhc3MsXG5cdFx0XHRgZXhwZWN0ZWQgXCIke3NweU5hbWV9XCIgdG8gYmUgY2FsbGVkIHdpdGggYXJndW1lbnRzOiAje2V4cH1gLFxuXHRcdFx0YGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIG5vdCBiZSBjYWxsZWQgd2l0aCBhcmd1bWVudHM6ICN7ZXhwfWAsXG5cdFx0XHRhcmdzXG5cdFx0XSk7XG5cdFx0aWYgKHBhc3MgJiYgaXNOb3QgfHwgIXBhc3MgJiYgIWlzTm90KSB7XG5cdFx0XHR0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZm9ybWF0Q2FsbHMoc3B5LCBtc2csIGFyZ3MpKTtcblx0XHR9XG5cdH0pO1xuXHRkZWYoXCJ0b0hhdmVCZWVuQ2FsbGVkRXhhY3RseU9uY2VXaXRoXCIsIGZ1bmN0aW9uKC4uLmFyZ3MpIHtcblx0XHRjb25zdCBzcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdGNvbnN0IGNhbGxDb3VudCA9IHNweS5tb2NrLmNhbGxzLmxlbmd0aDtcblx0XHRjb25zdCBoYXNDYWxsV2l0aEFyZ3MgPSBzcHkubW9jay5jYWxscy5zb21lKChjYWxsQXJnKSA9PiBlcXVhbHNBcmd1bWVudEFycmF5KGNhbGxBcmcsIGFyZ3MpKTtcblx0XHRjb25zdCBwYXNzID0gaGFzQ2FsbFdpdGhBcmdzICYmIGNhbGxDb3VudCA9PT0gMTtcblx0XHRjb25zdCBpc05vdCA9IHV0aWxzLmZsYWcodGhpcywgXCJuZWdhdGVcIik7XG5cdFx0Y29uc3QgbXNnID0gdXRpbHMuZ2V0TWVzc2FnZSh0aGlzLCBbXG5cdFx0XHRwYXNzLFxuXHRcdFx0YGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIGJlIGNhbGxlZCBvbmNlIHdpdGggYXJndW1lbnRzOiAje2V4cH1gLFxuXHRcdFx0YGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIG5vdCBiZSBjYWxsZWQgb25jZSB3aXRoIGFyZ3VtZW50czogI3tleHB9YCxcblx0XHRcdGFyZ3Ncblx0XHRdKTtcblx0XHRpZiAocGFzcyAmJiBpc05vdCB8fCAhcGFzcyAmJiAhaXNOb3QpIHtcblx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihmb3JtYXRDYWxscyhzcHksIG1zZywgYXJncykpO1xuXHRcdH1cblx0fSk7XG5cdGRlZihcInRvSGF2ZUJlZW5OdGhDYWxsZWRXaXRoXCIsIGZ1bmN0aW9uKHRpbWVzLCAuLi5hcmdzKSB7XG5cdFx0Y29uc3Qgc3B5ID0gZ2V0U3B5KHRoaXMpO1xuXHRcdGNvbnN0IHNweU5hbWUgPSBzcHkuZ2V0TW9ja05hbWUoKTtcblx0XHRjb25zdCBudGhDYWxsID0gc3B5Lm1vY2suY2FsbHNbdGltZXMgLSAxXTtcblx0XHRjb25zdCBjYWxsQ291bnQgPSBzcHkubW9jay5jYWxscy5sZW5ndGg7XG5cdFx0Y29uc3QgaXNDYWxsZWQgPSB0aW1lcyA8PSBjYWxsQ291bnQ7XG5cdFx0dGhpcy5hc3NlcnQobnRoQ2FsbCAmJiBlcXVhbHNBcmd1bWVudEFycmF5KG50aENhbGwsIGFyZ3MpLCBgZXhwZWN0ZWQgJHtvcmRpbmFsKHRpbWVzKX0gXCIke3NweU5hbWV9XCIgY2FsbCB0byBoYXZlIGJlZW4gY2FsbGVkIHdpdGggI3tleHB9JHtpc0NhbGxlZCA/IGBgIDogYCwgYnV0IGNhbGxlZCBvbmx5ICR7Y2FsbENvdW50fSB0aW1lc2B9YCwgYGV4cGVjdGVkICR7b3JkaW5hbCh0aW1lcyl9IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gbm90IGhhdmUgYmVlbiBjYWxsZWQgd2l0aCAje2V4cH1gLCBhcmdzLCBudGhDYWxsLCBpc0NhbGxlZCk7XG5cdH0pO1xuXHRkZWYoXCJ0b0hhdmVCZWVuTGFzdENhbGxlZFdpdGhcIiwgZnVuY3Rpb24oLi4uYXJncykge1xuXHRcdGNvbnN0IHNweSA9IGdldFNweSh0aGlzKTtcblx0XHRjb25zdCBzcHlOYW1lID0gc3B5LmdldE1vY2tOYW1lKCk7XG5cdFx0Y29uc3QgbGFzdENhbGwgPSBzcHkubW9jay5jYWxscy5hdCgtMSk7XG5cdFx0dGhpcy5hc3NlcnQobGFzdENhbGwgJiYgZXF1YWxzQXJndW1lbnRBcnJheShsYXN0Q2FsbCwgYXJncyksIGBleHBlY3RlZCBsYXN0IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gaGF2ZSBiZWVuIGNhbGxlZCB3aXRoICN7ZXhwfWAsIGBleHBlY3RlZCBsYXN0IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gbm90IGhhdmUgYmVlbiBjYWxsZWQgd2l0aCAje2V4cH1gLCBhcmdzLCBsYXN0Q2FsbCk7XG5cdH0pO1xuXHQvKipcblx0KiBVc2VkIGZvciBgdG9IYXZlQmVlbkNhbGxlZEJlZm9yZWAgYW5kIGB0b0hhdmVCZWVuQ2FsbGVkQWZ0ZXJgIHRvIGRldGVybWluZSBpZiB0aGUgZXhwZWN0ZWQgc3B5IHdhcyBjYWxsZWQgYmVmb3JlIHRoZSByZXN1bHQgc3B5LlxuXHQqL1xuXHRmdW5jdGlvbiBpc1NweUNhbGxlZEJlZm9yZUFub3RoZXJTcHkoYmVmb3JlU3B5LCBhZnRlclNweSwgZmFpbElmTm9GaXJzdEludm9jYXRpb24pIHtcblx0XHRjb25zdCBiZWZvcmVJbnZvY2F0aW9uQ2FsbE9yZGVyID0gYmVmb3JlU3B5Lm1vY2suaW52b2NhdGlvbkNhbGxPcmRlcjtcblx0XHRjb25zdCBhZnRlckludm9jYXRpb25DYWxsT3JkZXIgPSBhZnRlclNweS5tb2NrLmludm9jYXRpb25DYWxsT3JkZXI7XG5cdFx0aWYgKGJlZm9yZUludm9jYXRpb25DYWxsT3JkZXIubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRyZXR1cm4gIWZhaWxJZk5vRmlyc3RJbnZvY2F0aW9uO1xuXHRcdH1cblx0XHRpZiAoYWZ0ZXJJbnZvY2F0aW9uQ2FsbE9yZGVyLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRyZXR1cm4gYmVmb3JlSW52b2NhdGlvbkNhbGxPcmRlclswXSA8IGFmdGVySW52b2NhdGlvbkNhbGxPcmRlclswXTtcblx0fVxuXHRkZWYoW1widG9IYXZlQmVlbkNhbGxlZEJlZm9yZVwiXSwgZnVuY3Rpb24ocmVzdWx0U3B5LCBmYWlsSWZOb0ZpcnN0SW52b2NhdGlvbiA9IHRydWUpIHtcblx0XHRjb25zdCBleHBlY3RTcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0aWYgKCFpc01vY2tGdW5jdGlvbihyZXN1bHRTcHkpKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKGAke3V0aWxzLmluc3BlY3QocmVzdWx0U3B5KX0gaXMgbm90IGEgc3B5IG9yIGEgY2FsbCB0byBhIHNweWApO1xuXHRcdH1cblx0XHR0aGlzLmFzc2VydChpc1NweUNhbGxlZEJlZm9yZUFub3RoZXJTcHkoZXhwZWN0U3B5LCByZXN1bHRTcHksIGZhaWxJZk5vRmlyc3RJbnZvY2F0aW9uKSwgYGV4cGVjdGVkIFwiJHtleHBlY3RTcHkuZ2V0TW9ja05hbWUoKX1cIiB0byBoYXZlIGJlZW4gY2FsbGVkIGJlZm9yZSBcIiR7cmVzdWx0U3B5LmdldE1vY2tOYW1lKCl9XCJgLCBgZXhwZWN0ZWQgXCIke2V4cGVjdFNweS5nZXRNb2NrTmFtZSgpfVwiIHRvIG5vdCBoYXZlIGJlZW4gY2FsbGVkIGJlZm9yZSBcIiR7cmVzdWx0U3B5LmdldE1vY2tOYW1lKCl9XCJgLCByZXN1bHRTcHksIGV4cGVjdFNweSk7XG5cdH0pO1xuXHRkZWYoW1widG9IYXZlQmVlbkNhbGxlZEFmdGVyXCJdLCBmdW5jdGlvbihyZXN1bHRTcHksIGZhaWxJZk5vRmlyc3RJbnZvY2F0aW9uID0gdHJ1ZSkge1xuXHRcdGNvbnN0IGV4cGVjdFNweSA9IGdldFNweSh0aGlzKTtcblx0XHRpZiAoIWlzTW9ja0Z1bmN0aW9uKHJlc3VsdFNweSkpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYCR7dXRpbHMuaW5zcGVjdChyZXN1bHRTcHkpfSBpcyBub3QgYSBzcHkgb3IgYSBjYWxsIHRvIGEgc3B5YCk7XG5cdFx0fVxuXHRcdHRoaXMuYXNzZXJ0KGlzU3B5Q2FsbGVkQmVmb3JlQW5vdGhlclNweShyZXN1bHRTcHksIGV4cGVjdFNweSwgZmFpbElmTm9GaXJzdEludm9jYXRpb24pLCBgZXhwZWN0ZWQgXCIke2V4cGVjdFNweS5nZXRNb2NrTmFtZSgpfVwiIHRvIGhhdmUgYmVlbiBjYWxsZWQgYWZ0ZXIgXCIke3Jlc3VsdFNweS5nZXRNb2NrTmFtZSgpfVwiYCwgYGV4cGVjdGVkIFwiJHtleHBlY3RTcHkuZ2V0TW9ja05hbWUoKX1cIiB0byBub3QgaGF2ZSBiZWVuIGNhbGxlZCBhZnRlciBcIiR7cmVzdWx0U3B5LmdldE1vY2tOYW1lKCl9XCJgLCByZXN1bHRTcHksIGV4cGVjdFNweSk7XG5cdH0pO1xuXHRkZWYoW1widG9UaHJvd1wiLCBcInRvVGhyb3dFcnJvclwiXSwgZnVuY3Rpb24oZXhwZWN0ZWQpIHtcblx0XHRpZiAodHlwZW9mIGV4cGVjdGVkID09PSBcInN0cmluZ1wiIHx8IHR5cGVvZiBleHBlY3RlZCA9PT0gXCJ1bmRlZmluZWRcIiB8fCBleHBlY3RlZCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuXHRcdFx0Ly8gRml4ZXMgdGhlIGlzc3VlIHJlbGF0ZWQgdG8gYGNoYWlgIDxodHRwczovL2dpdGh1Yi5jb20vdml0ZXN0LWRldi92aXRlc3QvaXNzdWVzLzY2MTg+XG5cdFx0XHRyZXR1cm4gdGhpcy50aHJvd3MoZXhwZWN0ZWQgPT09IFwiXCIgPyAvXiQvIDogZXhwZWN0ZWQpO1xuXHRcdH1cblx0XHRjb25zdCBvYmogPSB0aGlzLl9vYmo7XG5cdFx0Y29uc3QgcHJvbWlzZSA9IHV0aWxzLmZsYWcodGhpcywgXCJwcm9taXNlXCIpO1xuXHRcdGNvbnN0IGlzTm90ID0gdXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKTtcblx0XHRsZXQgdGhyb3duID0gbnVsbDtcblx0XHRpZiAocHJvbWlzZSA9PT0gXCJyZWplY3RzXCIpIHtcblx0XHRcdHRocm93biA9IG9iajtcblx0XHR9IGVsc2UgaWYgKHByb21pc2UgPT09IFwicmVzb2x2ZXNcIiAmJiB0eXBlb2Ygb2JqICE9PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdGlmICghaXNOb3QpIHtcblx0XHRcdFx0Y29uc3QgbWVzc2FnZSA9IHV0aWxzLmZsYWcodGhpcywgXCJtZXNzYWdlXCIpIHx8IFwiZXhwZWN0ZWQgcHJvbWlzZSB0byB0aHJvdyBhbiBlcnJvciwgYnV0IGl0IGRpZG4ndFwiO1xuXHRcdFx0XHRjb25zdCBlcnJvciA9IHsgc2hvd0RpZmY6IGZhbHNlIH07XG5cdFx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtZXNzYWdlLCBlcnJvciwgdXRpbHMuZmxhZyh0aGlzLCBcInNzZmlcIikpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRsZXQgaXNUaHJvdyA9IGZhbHNlO1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0b2JqKCk7XG5cdFx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdFx0aXNUaHJvdyA9IHRydWU7XG5cdFx0XHRcdHRocm93biA9IGVycjtcblx0XHRcdH1cblx0XHRcdGlmICghaXNUaHJvdyAmJiAhaXNOb3QpIHtcblx0XHRcdFx0Y29uc3QgbWVzc2FnZSA9IHV0aWxzLmZsYWcodGhpcywgXCJtZXNzYWdlXCIpIHx8IFwiZXhwZWN0ZWQgZnVuY3Rpb24gdG8gdGhyb3cgYW4gZXJyb3IsIGJ1dCBpdCBkaWRuJ3RcIjtcblx0XHRcdFx0Y29uc3QgZXJyb3IgPSB7IHNob3dEaWZmOiBmYWxzZSB9O1xuXHRcdFx0XHR0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobWVzc2FnZSwgZXJyb3IsIHV0aWxzLmZsYWcodGhpcywgXCJzc2ZpXCIpKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBleHBlY3RlZCA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHRjb25zdCBuYW1lID0gZXhwZWN0ZWQubmFtZSB8fCBleHBlY3RlZC5wcm90b3R5cGUuY29uc3RydWN0b3IubmFtZTtcblx0XHRcdHJldHVybiB0aGlzLmFzc2VydCh0aHJvd24gJiYgdGhyb3duIGluc3RhbmNlb2YgZXhwZWN0ZWQsIGBleHBlY3RlZCBlcnJvciB0byBiZSBpbnN0YW5jZSBvZiAke25hbWV9YCwgYGV4cGVjdGVkIGVycm9yIG5vdCB0byBiZSBpbnN0YW5jZSBvZiAke25hbWV9YCwgZXhwZWN0ZWQsIHRocm93bik7XG5cdFx0fVxuXHRcdGlmIChpc0Vycm9yKGV4cGVjdGVkKSkge1xuXHRcdFx0Y29uc3QgZXF1YWwgPSBlcXVhbHModGhyb3duLCBleHBlY3RlZCwgWy4uLmN1c3RvbVRlc3RlcnMsIGl0ZXJhYmxlRXF1YWxpdHldKTtcblx0XHRcdHJldHVybiB0aGlzLmFzc2VydChlcXVhbCwgXCJleHBlY3RlZCBhIHRocm93biBlcnJvciB0byBiZSAje2V4cH1cIiwgXCJleHBlY3RlZCBhIHRocm93biBlcnJvciBub3QgdG8gYmUgI3tleHB9XCIsIGV4cGVjdGVkLCB0aHJvd24pO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIGV4cGVjdGVkID09PSBcIm9iamVjdFwiICYmIFwiYXN5bW1ldHJpY01hdGNoXCIgaW4gZXhwZWN0ZWQgJiYgdHlwZW9mIGV4cGVjdGVkLmFzeW1tZXRyaWNNYXRjaCA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHRjb25zdCBtYXRjaGVyID0gZXhwZWN0ZWQ7XG5cdFx0XHRyZXR1cm4gdGhpcy5hc3NlcnQodGhyb3duICYmIG1hdGNoZXIuYXN5bW1ldHJpY01hdGNoKHRocm93biksIFwiZXhwZWN0ZWQgZXJyb3IgdG8gbWF0Y2ggYXN5bW1ldHJpYyBtYXRjaGVyXCIsIFwiZXhwZWN0ZWQgZXJyb3Igbm90IHRvIG1hdGNoIGFzeW1tZXRyaWMgbWF0Y2hlclwiLCBtYXRjaGVyLCB0aHJvd24pO1xuXHRcdH1cblx0XHRjb25zdCBlcXVhbCA9IGVxdWFscyh0aHJvd24sIGV4cGVjdGVkLCBbLi4uY3VzdG9tVGVzdGVycywgaXRlcmFibGVFcXVhbGl0eV0pO1xuXHRcdHJldHVybiB0aGlzLmFzc2VydChlcXVhbCwgXCJleHBlY3RlZCBhIHRocm93biB2YWx1ZSB0byBlcXVhbCAje2V4cH1cIiwgXCJleHBlY3RlZCBhIHRocm93biB2YWx1ZSBub3QgdG8gZXF1YWwgI3tleHB9XCIsIGV4cGVjdGVkLCB0aHJvd24pO1xuXHR9KTtcblx0W3tcblx0XHRuYW1lOiBcInRvSGF2ZVJlc29sdmVkXCIsXG5cdFx0Y29uZGl0aW9uOiAoc3B5KSA9PiBzcHkubW9jay5zZXR0bGVkUmVzdWx0cy5sZW5ndGggPiAwICYmIHNweS5tb2NrLnNldHRsZWRSZXN1bHRzLnNvbWUoKHsgdHlwZSB9KSA9PiB0eXBlID09PSBcImZ1bGZpbGxlZFwiKSxcblx0XHRhY3Rpb246IFwicmVzb2x2ZWRcIlxuXHR9LCB7XG5cdFx0bmFtZTogW1widG9IYXZlUmV0dXJuZWRcIiwgXCJ0b1JldHVyblwiXSxcblx0XHRjb25kaXRpb246IChzcHkpID0+IHNweS5tb2NrLmNhbGxzLmxlbmd0aCA+IDAgJiYgc3B5Lm1vY2sucmVzdWx0cy5zb21lKCh7IHR5cGUgfSkgPT4gdHlwZSAhPT0gXCJ0aHJvd1wiKSxcblx0XHRhY3Rpb246IFwiY2FsbGVkXCJcblx0fV0uZm9yRWFjaCgoeyBuYW1lLCBjb25kaXRpb24sIGFjdGlvbiB9KSA9PiB7XG5cdFx0ZGVmKG5hbWUsIGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29uc3Qgc3B5ID0gZ2V0U3B5KHRoaXMpO1xuXHRcdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdFx0Y29uc3QgcGFzcyA9IGNvbmRpdGlvbihzcHkpO1xuXHRcdFx0dGhpcy5hc3NlcnQocGFzcywgYGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIGJlIHN1Y2Nlc3NmdWxseSAke2FjdGlvbn0gYXQgbGVhc3Qgb25jZWAsIGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byBub3QgYmUgc3VjY2Vzc2Z1bGx5ICR7YWN0aW9ufWAsIHBhc3MsICFwYXNzLCBmYWxzZSk7XG5cdFx0fSk7XG5cdH0pO1xuXHRbe1xuXHRcdG5hbWU6IFwidG9IYXZlUmVzb2x2ZWRUaW1lc1wiLFxuXHRcdGNvbmRpdGlvbjogKHNweSwgdGltZXMpID0+IHNweS5tb2NrLnNldHRsZWRSZXN1bHRzLnJlZHVjZSgocywgeyB0eXBlIH0pID0+IHR5cGUgPT09IFwiZnVsZmlsbGVkXCIgPyArK3MgOiBzLCAwKSA9PT0gdGltZXMsXG5cdFx0YWN0aW9uOiBcInJlc29sdmVkXCJcblx0fSwge1xuXHRcdG5hbWU6IFtcInRvSGF2ZVJldHVybmVkVGltZXNcIiwgXCJ0b1JldHVyblRpbWVzXCJdLFxuXHRcdGNvbmRpdGlvbjogKHNweSwgdGltZXMpID0+IHNweS5tb2NrLnJlc3VsdHMucmVkdWNlKChzLCB7IHR5cGUgfSkgPT4gdHlwZSA9PT0gXCJ0aHJvd1wiID8gcyA6ICsrcywgMCkgPT09IHRpbWVzLFxuXHRcdGFjdGlvbjogXCJjYWxsZWRcIlxuXHR9XS5mb3JFYWNoKCh7IG5hbWUsIGNvbmRpdGlvbiwgYWN0aW9uIH0pID0+IHtcblx0XHRkZWYobmFtZSwgZnVuY3Rpb24odGltZXMpIHtcblx0XHRcdGNvbnN0IHNweSA9IGdldFNweSh0aGlzKTtcblx0XHRcdGNvbnN0IHNweU5hbWUgPSBzcHkuZ2V0TW9ja05hbWUoKTtcblx0XHRcdGNvbnN0IHBhc3MgPSBjb25kaXRpb24oc3B5LCB0aW1lcyk7XG5cdFx0XHR0aGlzLmFzc2VydChwYXNzLCBgZXhwZWN0ZWQgXCIke3NweU5hbWV9XCIgdG8gYmUgc3VjY2Vzc2Z1bGx5ICR7YWN0aW9ufSAke3RpbWVzfSB0aW1lc2AsIGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byBub3QgYmUgc3VjY2Vzc2Z1bGx5ICR7YWN0aW9ufSAke3RpbWVzfSB0aW1lc2AsIGBleHBlY3RlZCByZXNvbHZlZCB0aW1lczogJHt0aW1lc31gLCBgcmVjZWl2ZWQgcmVzb2x2ZWQgdGltZXM6ICR7cGFzc31gLCBmYWxzZSk7XG5cdFx0fSk7XG5cdH0pO1xuXHRbe1xuXHRcdG5hbWU6IFwidG9IYXZlUmVzb2x2ZWRXaXRoXCIsXG5cdFx0Y29uZGl0aW9uOiAoc3B5LCB2YWx1ZSkgPT4gc3B5Lm1vY2suc2V0dGxlZFJlc3VsdHMuc29tZSgoeyB0eXBlLCB2YWx1ZTogcmVzdWx0IH0pID0+IHR5cGUgPT09IFwiZnVsZmlsbGVkXCIgJiYgZXF1YWxzKHZhbHVlLCByZXN1bHQpKSxcblx0XHRhY3Rpb246IFwicmVzb2x2ZVwiXG5cdH0sIHtcblx0XHRuYW1lOiBbXCJ0b0hhdmVSZXR1cm5lZFdpdGhcIiwgXCJ0b1JldHVybldpdGhcIl0sXG5cdFx0Y29uZGl0aW9uOiAoc3B5LCB2YWx1ZSkgPT4gc3B5Lm1vY2sucmVzdWx0cy5zb21lKCh7IHR5cGUsIHZhbHVlOiByZXN1bHQgfSkgPT4gdHlwZSA9PT0gXCJyZXR1cm5cIiAmJiBlcXVhbHModmFsdWUsIHJlc3VsdCkpLFxuXHRcdGFjdGlvbjogXCJyZXR1cm5cIlxuXHR9XS5mb3JFYWNoKCh7IG5hbWUsIGNvbmRpdGlvbiwgYWN0aW9uIH0pID0+IHtcblx0XHRkZWYobmFtZSwgZnVuY3Rpb24odmFsdWUpIHtcblx0XHRcdGNvbnN0IHNweSA9IGdldFNweSh0aGlzKTtcblx0XHRcdGNvbnN0IHBhc3MgPSBjb25kaXRpb24oc3B5LCB2YWx1ZSk7XG5cdFx0XHRjb25zdCBpc05vdCA9IHV0aWxzLmZsYWcodGhpcywgXCJuZWdhdGVcIik7XG5cdFx0XHRpZiAocGFzcyAmJiBpc05vdCB8fCAhcGFzcyAmJiAhaXNOb3QpIHtcblx0XHRcdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdFx0XHRjb25zdCBtc2cgPSB1dGlscy5nZXRNZXNzYWdlKHRoaXMsIFtcblx0XHRcdFx0XHRwYXNzLFxuXHRcdFx0XHRcdGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byAke2FjdGlvbn0gd2l0aDogI3tleHB9IGF0IGxlYXN0IG9uY2VgLFxuXHRcdFx0XHRcdGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byBub3QgJHthY3Rpb259IHdpdGg6ICN7ZXhwfWAsXG5cdFx0XHRcdFx0dmFsdWVcblx0XHRcdFx0XSk7XG5cdFx0XHRcdGNvbnN0IHJlc3VsdHMgPSBhY3Rpb24gPT09IFwicmV0dXJuXCIgPyBzcHkubW9jay5yZXN1bHRzIDogc3B5Lm1vY2suc2V0dGxlZFJlc3VsdHM7XG5cdFx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihmb3JtYXRSZXR1cm5zKHNweSwgcmVzdWx0cywgbXNnLCB2YWx1ZSkpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9KTtcblx0W3tcblx0XHRuYW1lOiBcInRvSGF2ZUxhc3RSZXNvbHZlZFdpdGhcIixcblx0XHRjb25kaXRpb246IChzcHksIHZhbHVlKSA9PiB7XG5cdFx0XHRjb25zdCByZXN1bHQgPSBzcHkubW9jay5zZXR0bGVkUmVzdWx0cy5hdCgtMSk7XG5cdFx0XHRyZXR1cm4gQm9vbGVhbihyZXN1bHQgJiYgcmVzdWx0LnR5cGUgPT09IFwiZnVsZmlsbGVkXCIgJiYgZXF1YWxzKHJlc3VsdC52YWx1ZSwgdmFsdWUpKTtcblx0XHR9LFxuXHRcdGFjdGlvbjogXCJyZXNvbHZlXCJcblx0fSwge1xuXHRcdG5hbWU6IFwidG9IYXZlTGFzdFJldHVybmVkV2l0aFwiLFxuXHRcdGNvbmRpdGlvbjogKHNweSwgdmFsdWUpID0+IHtcblx0XHRcdGNvbnN0IHJlc3VsdCA9IHNweS5tb2NrLnJlc3VsdHMuYXQoLTEpO1xuXHRcdFx0cmV0dXJuIEJvb2xlYW4ocmVzdWx0ICYmIHJlc3VsdC50eXBlID09PSBcInJldHVyblwiICYmIGVxdWFscyhyZXN1bHQudmFsdWUsIHZhbHVlKSk7XG5cdFx0fSxcblx0XHRhY3Rpb246IFwicmV0dXJuXCJcblx0fV0uZm9yRWFjaCgoeyBuYW1lLCBjb25kaXRpb24sIGFjdGlvbiB9KSA9PiB7XG5cdFx0ZGVmKG5hbWUsIGZ1bmN0aW9uKHZhbHVlKSB7XG5cdFx0XHRjb25zdCBzcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0XHRjb25zdCByZXN1bHRzID0gYWN0aW9uID09PSBcInJldHVyblwiID8gc3B5Lm1vY2sucmVzdWx0cyA6IHNweS5tb2NrLnNldHRsZWRSZXN1bHRzO1xuXHRcdFx0Y29uc3QgcmVzdWx0ID0gcmVzdWx0cy5hdCgtMSk7XG5cdFx0XHRjb25zdCBzcHlOYW1lID0gc3B5LmdldE1vY2tOYW1lKCk7XG5cdFx0XHR0aGlzLmFzc2VydChjb25kaXRpb24oc3B5LCB2YWx1ZSksIGBleHBlY3RlZCBsYXN0IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gJHthY3Rpb259ICN7ZXhwfWAsIGBleHBlY3RlZCBsYXN0IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gbm90ICR7YWN0aW9ufSAje2V4cH1gLCB2YWx1ZSwgcmVzdWx0Py52YWx1ZSk7XG5cdFx0fSk7XG5cdH0pO1xuXHRbe1xuXHRcdG5hbWU6IFwidG9IYXZlTnRoUmVzb2x2ZWRXaXRoXCIsXG5cdFx0Y29uZGl0aW9uOiAoc3B5LCBpbmRleCwgdmFsdWUpID0+IHtcblx0XHRcdGNvbnN0IHJlc3VsdCA9IHNweS5tb2NrLnNldHRsZWRSZXN1bHRzW2luZGV4IC0gMV07XG5cdFx0XHRyZXR1cm4gcmVzdWx0ICYmIHJlc3VsdC50eXBlID09PSBcImZ1bGZpbGxlZFwiICYmIGVxdWFscyhyZXN1bHQudmFsdWUsIHZhbHVlKTtcblx0XHR9LFxuXHRcdGFjdGlvbjogXCJyZXNvbHZlXCJcblx0fSwge1xuXHRcdG5hbWU6IFwidG9IYXZlTnRoUmV0dXJuZWRXaXRoXCIsXG5cdFx0Y29uZGl0aW9uOiAoc3B5LCBpbmRleCwgdmFsdWUpID0+IHtcblx0XHRcdGNvbnN0IHJlc3VsdCA9IHNweS5tb2NrLnJlc3VsdHNbaW5kZXggLSAxXTtcblx0XHRcdHJldHVybiByZXN1bHQgJiYgcmVzdWx0LnR5cGUgPT09IFwicmV0dXJuXCIgJiYgZXF1YWxzKHJlc3VsdC52YWx1ZSwgdmFsdWUpO1xuXHRcdH0sXG5cdFx0YWN0aW9uOiBcInJldHVyblwiXG5cdH1dLmZvckVhY2goKHsgbmFtZSwgY29uZGl0aW9uLCBhY3Rpb24gfSkgPT4ge1xuXHRcdGRlZihuYW1lLCBmdW5jdGlvbihudGhDYWxsLCB2YWx1ZSkge1xuXHRcdFx0Y29uc3Qgc3B5ID0gZ2V0U3B5KHRoaXMpO1xuXHRcdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdFx0Y29uc3QgcmVzdWx0cyA9IGFjdGlvbiA9PT0gXCJyZXR1cm5cIiA/IHNweS5tb2NrLnJlc3VsdHMgOiBzcHkubW9jay5zZXR0bGVkUmVzdWx0cztcblx0XHRcdGNvbnN0IHJlc3VsdCA9IHJlc3VsdHNbbnRoQ2FsbCAtIDFdO1xuXHRcdFx0Y29uc3Qgb3JkaW5hbENhbGwgPSBgJHtvcmRpbmFsKG50aENhbGwpfSBjYWxsYDtcblx0XHRcdHRoaXMuYXNzZXJ0KGNvbmRpdGlvbihzcHksIG50aENhbGwsIHZhbHVlKSwgYGV4cGVjdGVkICR7b3JkaW5hbENhbGx9IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gJHthY3Rpb259ICN7ZXhwfWAsIGBleHBlY3RlZCAke29yZGluYWxDYWxsfSBcIiR7c3B5TmFtZX1cIiBjYWxsIHRvIG5vdCAke2FjdGlvbn0gI3tleHB9YCwgdmFsdWUsIHJlc3VsdD8udmFsdWUpO1xuXHRcdH0pO1xuXHR9KTtcblx0Ly8gQHRzLWV4cGVjdC1lcnJvciBAaW50ZXJuYWxcblx0ZGVmKFwid2l0aENvbnRleHRcIiwgZnVuY3Rpb24oY29udGV4dCkge1xuXHRcdGZvciAoY29uc3Qga2V5IGluIGNvbnRleHQpIHtcblx0XHRcdHV0aWxzLmZsYWcodGhpcywga2V5LCBjb250ZXh0W2tleV0pO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fSk7XG5cdHV0aWxzLmFkZFByb3BlcnR5KGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgXCJyZXNvbHZlc1wiLCBmdW5jdGlvbiBfX1ZJVEVTVF9SRVNPTFZFU19fKCkge1xuXHRcdGNvbnN0IGVycm9yID0gbmV3IEVycm9yKFwicmVzb2x2ZXNcIik7XG5cdFx0dXRpbHMuZmxhZyh0aGlzLCBcInByb21pc2VcIiwgXCJyZXNvbHZlc1wiKTtcblx0XHR1dGlscy5mbGFnKHRoaXMsIFwiZXJyb3JcIiwgZXJyb3IpO1xuXHRcdGNvbnN0IHRlc3QgPSB1dGlscy5mbGFnKHRoaXMsIFwidml0ZXN0LXRlc3RcIik7XG5cdFx0Y29uc3Qgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKTtcblx0XHRpZiAodXRpbHMuZmxhZyh0aGlzLCBcInBvbGxcIikpIHtcblx0XHRcdHRocm93IG5ldyBTeW50YXhFcnJvcihgZXhwZWN0LnBvbGwoKSBpcyBub3Qgc3VwcG9ydGVkIGluIGNvbWJpbmF0aW9uIHdpdGggLnJlc29sdmVzYCk7XG5cdFx0fVxuXHRcdGlmICh0eXBlb2Ygb2JqPy50aGVuICE9PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYFlvdSBtdXN0IHByb3ZpZGUgYSBQcm9taXNlIHRvIGV4cGVjdCgpIHdoZW4gdXNpbmcgLnJlc29sdmVzLCBub3QgJyR7dHlwZW9mIG9ian0nLmApO1xuXHRcdH1cblx0XHRjb25zdCBwcm94eSA9IG5ldyBQcm94eSh0aGlzLCB7IGdldDogKHRhcmdldCwga2V5LCByZWNlaXZlcikgPT4ge1xuXHRcdFx0Y29uc3QgcmVzdWx0ID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBrZXksIHJlY2VpdmVyKTtcblx0XHRcdGlmICh0eXBlb2YgcmVzdWx0ICE9PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdFx0cmV0dXJuIHJlc3VsdCBpbnN0YW5jZW9mIGNoYWkuQXNzZXJ0aW9uID8gcHJveHkgOiByZXN1bHQ7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gKC4uLmFyZ3MpID0+IHtcblx0XHRcdFx0dXRpbHMuZmxhZyh0aGlzLCBcIl9uYW1lXCIsIGtleSk7XG5cdFx0XHRcdGNvbnN0IHByb21pc2UgPSBQcm9taXNlLnJlc29sdmUob2JqKS50aGVuKCh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIiwgdmFsdWUpO1xuXHRcdFx0XHRcdHJldHVybiByZXN1bHQuY2FsbCh0aGlzLCAuLi5hcmdzKTtcblx0XHRcdFx0fSwgKGVycikgPT4ge1xuXHRcdFx0XHRcdGNvbnN0IF9lcnJvciA9IG5ldyBBc3NlcnRpb25FcnJvcihgcHJvbWlzZSByZWplY3RlZCBcIiR7dXRpbHMuaW5zcGVjdChlcnIpfVwiIGluc3RlYWQgb2YgcmVzb2x2aW5nYCwgeyBzaG93RGlmZjogZmFsc2UgfSk7XG5cdFx0XHRcdFx0X2Vycm9yLmNhdXNlID0gZXJyO1xuXHRcdFx0XHRcdHRocm93IF9lcnJvcjtcblx0XHRcdFx0fSkuY2F0Y2goKGVycikgPT4ge1xuXHRcdFx0XHRcdGlmIChpc0Vycm9yKGVycikgJiYgZXJyb3Iuc3RhY2spIHtcblx0XHRcdFx0XHRcdGVyci5zdGFjayA9IGVycm9yLnN0YWNrLnJlcGxhY2UoZXJyb3IubWVzc2FnZSwgZXJyLm1lc3NhZ2UpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR0aHJvdyBlcnI7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRyZXR1cm4gcmVjb3JkQXN5bmNFeHBlY3QodGVzdCwgcHJvbWlzZSwgY3JlYXRlQXNzZXJ0aW9uTWVzc2FnZSh1dGlscywgdGhpcywgISFhcmdzLmxlbmd0aCksIGVycm9yLCB1dGlscy5mbGFnKHRoaXMsIFwic29mdFwiKSk7XG5cdFx0XHR9O1xuXHRcdH0gfSk7XG5cdFx0cmV0dXJuIHByb3h5O1xuXHR9KTtcblx0dXRpbHMuYWRkUHJvcGVydHkoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCBcInJlamVjdHNcIiwgZnVuY3Rpb24gX19WSVRFU1RfUkVKRUNUU19fKCkge1xuXHRcdGNvbnN0IGVycm9yID0gbmV3IEVycm9yKFwicmVqZWN0c1wiKTtcblx0XHR1dGlscy5mbGFnKHRoaXMsIFwicHJvbWlzZVwiLCBcInJlamVjdHNcIik7XG5cdFx0dXRpbHMuZmxhZyh0aGlzLCBcImVycm9yXCIsIGVycm9yKTtcblx0XHRjb25zdCB0ZXN0ID0gdXRpbHMuZmxhZyh0aGlzLCBcInZpdGVzdC10ZXN0XCIpO1xuXHRcdGNvbnN0IG9iaiA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0Y29uc3Qgd3JhcHBlciA9IHR5cGVvZiBvYmogPT09IFwiZnVuY3Rpb25cIiA/IG9iaigpIDogb2JqO1xuXHRcdGlmICh1dGlscy5mbGFnKHRoaXMsIFwicG9sbFwiKSkge1xuXHRcdFx0dGhyb3cgbmV3IFN5bnRheEVycm9yKGBleHBlY3QucG9sbCgpIGlzIG5vdCBzdXBwb3J0ZWQgaW4gY29tYmluYXRpb24gd2l0aCAucmVqZWN0c2ApO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHdyYXBwZXI/LnRoZW4gIT09IFwiZnVuY3Rpb25cIikge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihgWW91IG11c3QgcHJvdmlkZSBhIFByb21pc2UgdG8gZXhwZWN0KCkgd2hlbiB1c2luZyAucmVqZWN0cywgbm90ICcke3R5cGVvZiB3cmFwcGVyfScuYCk7XG5cdFx0fVxuXHRcdGNvbnN0IHByb3h5ID0gbmV3IFByb3h5KHRoaXMsIHsgZ2V0OiAodGFyZ2V0LCBrZXksIHJlY2VpdmVyKSA9PiB7XG5cdFx0XHRjb25zdCByZXN1bHQgPSBSZWZsZWN0LmdldCh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpO1xuXHRcdFx0aWYgKHR5cGVvZiByZXN1bHQgIT09IFwiZnVuY3Rpb25cIikge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0IGluc3RhbmNlb2YgY2hhaS5Bc3NlcnRpb24gPyBwcm94eSA6IHJlc3VsdDtcblx0XHRcdH1cblx0XHRcdHJldHVybiAoLi4uYXJncykgPT4ge1xuXHRcdFx0XHR1dGlscy5mbGFnKHRoaXMsIFwiX25hbWVcIiwga2V5KTtcblx0XHRcdFx0Y29uc3QgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSh3cmFwcGVyKS50aGVuKCh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdGNvbnN0IF9lcnJvciA9IG5ldyBBc3NlcnRpb25FcnJvcihgcHJvbWlzZSByZXNvbHZlZCBcIiR7dXRpbHMuaW5zcGVjdCh2YWx1ZSl9XCIgaW5zdGVhZCBvZiByZWplY3RpbmdgLCB7XG5cdFx0XHRcdFx0XHRzaG93RGlmZjogdHJ1ZSxcblx0XHRcdFx0XHRcdGV4cGVjdGVkOiBuZXcgRXJyb3IoXCJyZWplY3RlZCBwcm9taXNlXCIpLFxuXHRcdFx0XHRcdFx0YWN0dWFsOiB2YWx1ZVxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdHRocm93IF9lcnJvcjtcblx0XHRcdFx0fSwgKGVycikgPT4ge1xuXHRcdFx0XHRcdHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIiwgZXJyKTtcblx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0LmNhbGwodGhpcywgLi4uYXJncyk7XG5cdFx0XHRcdH0pLmNhdGNoKChlcnIpID0+IHtcblx0XHRcdFx0XHRpZiAoaXNFcnJvcihlcnIpICYmIGVycm9yLnN0YWNrKSB7XG5cdFx0XHRcdFx0XHRlcnIuc3RhY2sgPSBlcnJvci5zdGFjay5yZXBsYWNlKGVycm9yLm1lc3NhZ2UsIGVyci5tZXNzYWdlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0dGhyb3cgZXJyO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0cmV0dXJuIHJlY29yZEFzeW5jRXhwZWN0KHRlc3QsIHByb21pc2UsIGNyZWF0ZUFzc2VydGlvbk1lc3NhZ2UodXRpbHMsIHRoaXMsICEhYXJncy5sZW5ndGgpLCBlcnJvciwgdXRpbHMuZmxhZyh0aGlzLCBcInNvZnRcIikpO1xuXHRcdFx0fTtcblx0XHR9IH0pO1xuXHRcdHJldHVybiBwcm94eTtcblx0fSk7XG59O1xuZnVuY3Rpb24gZm9ybWF0Q2FsbHMoc3B5LCBtc2csIHNob3dBY3R1YWxDYWxsKSB7XG5cdGlmIChzcHkubW9jay5jYWxscy5sZW5ndGgpIHtcblx0XHRtc2cgKz0gYy5ncmF5KGBcXG5cXG5SZWNlaXZlZDpcXG5cXG4ke3NweS5tb2NrLmNhbGxzLm1hcCgoY2FsbEFyZywgaSkgPT4ge1xuXHRcdFx0bGV0IG1ldGhvZENhbGwgPSBjLmJvbGQoYCAgJHtvcmRpbmFsKGkgKyAxKX0gJHtzcHkuZ2V0TW9ja05hbWUoKX0gY2FsbDpcXG5cXG5gKTtcblx0XHRcdGlmIChzaG93QWN0dWFsQ2FsbCkge1xuXHRcdFx0XHRtZXRob2RDYWxsICs9IGRpZmYoc2hvd0FjdHVhbENhbGwsIGNhbGxBcmcsIHsgb21pdEFubm90YXRpb25MaW5lczogdHJ1ZSB9KTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG1ldGhvZENhbGwgKz0gc3RyaW5naWZ5KGNhbGxBcmcpLnNwbGl0KFwiXFxuXCIpLm1hcCgobGluZSkgPT4gYCAgICAke2xpbmV9YCkuam9pbihcIlxcblwiKTtcblx0XHRcdH1cblx0XHRcdG1ldGhvZENhbGwgKz0gXCJcXG5cIjtcblx0XHRcdHJldHVybiBtZXRob2RDYWxsO1xuXHRcdH0pLmpvaW4oXCJcXG5cIil9YCk7XG5cdH1cblx0bXNnICs9IGMuZ3JheShgXFxuXFxuTnVtYmVyIG9mIGNhbGxzOiAke2MuYm9sZChzcHkubW9jay5jYWxscy5sZW5ndGgpfVxcbmApO1xuXHRyZXR1cm4gbXNnO1xufVxuZnVuY3Rpb24gZm9ybWF0UmV0dXJucyhzcHksIHJlc3VsdHMsIG1zZywgc2hvd0FjdHVhbFJldHVybikge1xuXHRpZiAocmVzdWx0cy5sZW5ndGgpIHtcblx0XHRtc2cgKz0gYy5ncmF5KGBcXG5cXG5SZWNlaXZlZDpcXG5cXG4ke3Jlc3VsdHMubWFwKChjYWxsUmV0dXJuLCBpKSA9PiB7XG5cdFx0XHRsZXQgbWV0aG9kQ2FsbCA9IGMuYm9sZChgICAke29yZGluYWwoaSArIDEpfSAke3NweS5nZXRNb2NrTmFtZSgpfSBjYWxsIHJldHVybjpcXG5cXG5gKTtcblx0XHRcdGlmIChzaG93QWN0dWFsUmV0dXJuKSB7XG5cdFx0XHRcdG1ldGhvZENhbGwgKz0gZGlmZihzaG93QWN0dWFsUmV0dXJuLCBjYWxsUmV0dXJuLnZhbHVlLCB7IG9taXRBbm5vdGF0aW9uTGluZXM6IHRydWUgfSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRtZXRob2RDYWxsICs9IHN0cmluZ2lmeShjYWxsUmV0dXJuKS5zcGxpdChcIlxcblwiKS5tYXAoKGxpbmUpID0+IGAgICAgJHtsaW5lfWApLmpvaW4oXCJcXG5cIik7XG5cdFx0XHR9XG5cdFx0XHRtZXRob2RDYWxsICs9IFwiXFxuXCI7XG5cdFx0XHRyZXR1cm4gbWV0aG9kQ2FsbDtcblx0XHR9KS5qb2luKFwiXFxuXCIpfWApO1xuXHR9XG5cdG1zZyArPSBjLmdyYXkoYFxcblxcbk51bWJlciBvZiBjYWxsczogJHtjLmJvbGQoc3B5Lm1vY2suY2FsbHMubGVuZ3RoKX1cXG5gKTtcblx0cmV0dXJuIG1zZztcbn1cblxuZnVuY3Rpb24gZ2V0TWF0Y2hlclN0YXRlKGFzc2VydGlvbiwgZXhwZWN0KSB7XG5cdGNvbnN0IG9iaiA9IGFzc2VydGlvbi5fb2JqO1xuXHRjb25zdCBpc05vdCA9IHV0aWwuZmxhZyhhc3NlcnRpb24sIFwibmVnYXRlXCIpO1xuXHRjb25zdCBwcm9taXNlID0gdXRpbC5mbGFnKGFzc2VydGlvbiwgXCJwcm9taXNlXCIpIHx8IFwiXCI7XG5cdGNvbnN0IGN1c3RvbU1lc3NhZ2UgPSB1dGlsLmZsYWcoYXNzZXJ0aW9uLCBcIm1lc3NhZ2VcIik7XG5cdGNvbnN0IGplc3RVdGlscyA9IHtcblx0XHQuLi5nZXRNYXRjaGVyVXRpbHMoKSxcblx0XHRkaWZmLFxuXHRcdHN0cmluZ2lmeSxcblx0XHRpdGVyYWJsZUVxdWFsaXR5LFxuXHRcdHN1YnNldEVxdWFsaXR5XG5cdH07XG5cdGxldCB0YXNrID0gdXRpbC5mbGFnKGFzc2VydGlvbiwgXCJ2aXRlc3QtdGVzdFwiKTtcblx0Y29uc3QgY3VycmVudFRlc3ROYW1lID0gdGFzaz8uZnVsbFRlc3ROYW1lID8/IFwiXCI7XG5cdGlmICh0YXNrPy50eXBlICE9PSBcInRlc3RcIikge1xuXHRcdHRhc2sgPSB1bmRlZmluZWQ7XG5cdH1cblx0Y29uc3QgbWF0Y2hlclN0YXRlID0ge1xuXHRcdC4uLmdldFN0YXRlKGV4cGVjdCksXG5cdFx0dGFzayxcblx0XHRjdXJyZW50VGVzdE5hbWUsXG5cdFx0Y3VzdG9tVGVzdGVyczogZ2V0Q3VzdG9tRXF1YWxpdHlUZXN0ZXJzKCksXG5cdFx0aXNOb3QsXG5cdFx0dXRpbHM6IGplc3RVdGlscyxcblx0XHRwcm9taXNlLFxuXHRcdGVxdWFscyxcblx0XHRzdXBwcmVzc2VkRXJyb3JzOiBbXSxcblx0XHRzb2Z0OiB1dGlsLmZsYWcoYXNzZXJ0aW9uLCBcInNvZnRcIiksXG5cdFx0cG9sbDogdXRpbC5mbGFnKGFzc2VydGlvbiwgXCJwb2xsXCIpXG5cdH07XG5cdHJldHVybiB7XG5cdFx0c3RhdGU6IG1hdGNoZXJTdGF0ZSxcblx0XHRpc05vdCxcblx0XHRvYmosXG5cdFx0Y3VzdG9tTWVzc2FnZVxuXHR9O1xufVxuY2xhc3MgSmVzdEV4dGVuZEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuXHRjb25zdHJ1Y3RvcihtZXNzYWdlLCBhY3R1YWwsIGV4cGVjdGVkLCBjb250ZXh0KSB7XG5cdFx0c3VwZXIobWVzc2FnZSk7XG5cdFx0dGhpcy5hY3R1YWwgPSBhY3R1YWw7XG5cdFx0dGhpcy5leHBlY3RlZCA9IGV4cGVjdGVkO1xuXHRcdHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG5cdH1cbn1cbmZ1bmN0aW9uIEplc3RFeHRlbmRQbHVnaW4oYywgZXhwZWN0LCBtYXRjaGVycykge1xuXHRyZXR1cm4gKF8sIHV0aWxzKSA9PiB7XG5cdFx0T2JqZWN0LmVudHJpZXMobWF0Y2hlcnMpLmZvckVhY2goKFtleHBlY3RBc3NlcnRpb25OYW1lLCBleHBlY3RBc3NlcnRpb25dKSA9PiB7XG5cdFx0XHRmdW5jdGlvbiBleHBlY3RXcmFwcGVyKC4uLmFyZ3MpIHtcblx0XHRcdFx0Y29uc3QgeyBzdGF0ZSwgaXNOb3QsIG9iaiwgY3VzdG9tTWVzc2FnZSB9ID0gZ2V0TWF0Y2hlclN0YXRlKHRoaXMsIGV4cGVjdCk7XG5cdFx0XHRcdGNvbnN0IHJlc3VsdCA9IGV4cGVjdEFzc2VydGlvbi5jYWxsKHN0YXRlLCBvYmosIC4uLmFyZ3MpO1xuXHRcdFx0XHRpZiAocmVzdWx0ICYmIHR5cGVvZiByZXN1bHQgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlc3VsdC50aGVuID09PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdFx0XHRjb25zdCB0aGVuYWJsZSA9IHJlc3VsdDtcblx0XHRcdFx0XHRyZXR1cm4gdGhlbmFibGUudGhlbigoeyBwYXNzLCBtZXNzYWdlLCBhY3R1YWwsIGV4cGVjdGVkLCBtZXRhIH0pID0+IHtcblx0XHRcdFx0XHRcdGlmIChwYXNzICYmIGlzTm90IHx8ICFwYXNzICYmICFpc05vdCkge1xuXHRcdFx0XHRcdFx0XHRjb25zdCBlcnJvck1lc3NhZ2UgPSBjdXN0b21NZXNzYWdlICE9IG51bGwgPyBjdXN0b21NZXNzYWdlIDogbWVzc2FnZSgpO1xuXHRcdFx0XHRcdFx0XHR0aHJvdyBuZXcgSmVzdEV4dGVuZEVycm9yKGVycm9yTWVzc2FnZSwgYWN0dWFsLCBleHBlY3RlZCwge1xuXHRcdFx0XHRcdFx0XHRcdGFzc2VydGlvbk5hbWU6IGV4cGVjdEFzc2VydGlvbk5hbWUsXG5cdFx0XHRcdFx0XHRcdFx0bWV0YVxuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRjb25zdCB7IHBhc3MsIG1lc3NhZ2UsIGFjdHVhbCwgZXhwZWN0ZWQsIG1ldGEgfSA9IHJlc3VsdDtcblx0XHRcdFx0aWYgKHBhc3MgJiYgaXNOb3QgfHwgIXBhc3MgJiYgIWlzTm90KSB7XG5cdFx0XHRcdFx0Y29uc3QgZXJyb3JNZXNzYWdlID0gY3VzdG9tTWVzc2FnZSAhPSBudWxsID8gY3VzdG9tTWVzc2FnZSA6IG1lc3NhZ2UoKTtcblx0XHRcdFx0XHR0aHJvdyBuZXcgSmVzdEV4dGVuZEVycm9yKGVycm9yTWVzc2FnZSwgYWN0dWFsLCBleHBlY3RlZCwge1xuXHRcdFx0XHRcdFx0YXNzZXJ0aW9uTmFtZTogZXhwZWN0QXNzZXJ0aW9uTmFtZSxcblx0XHRcdFx0XHRcdG1ldGFcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Y29uc3Qgc29mdFdyYXBwZXIgPSB3cmFwQXNzZXJ0aW9uKHV0aWxzLCBleHBlY3RBc3NlcnRpb25OYW1lLCBleHBlY3RXcmFwcGVyKTtcblx0XHRcdHV0aWxzLmFkZE1ldGhvZChnbG9iYWxUaGlzW0pFU1RfTUFUQ0hFUlNfT0JKRUNUXS5tYXRjaGVycywgZXhwZWN0QXNzZXJ0aW9uTmFtZSwgc29mdFdyYXBwZXIpO1xuXHRcdFx0dXRpbHMuYWRkTWV0aG9kKGMuQXNzZXJ0aW9uLnByb3RvdHlwZSwgZXhwZWN0QXNzZXJ0aW9uTmFtZSwgc29mdFdyYXBwZXIpO1xuXHRcdFx0Y2xhc3MgQ3VzdG9tTWF0Y2hlciBleHRlbmRzIEFzeW1tZXRyaWNNYXRjaGVyIHtcblx0XHRcdFx0Y29uc3RydWN0b3IoaW52ZXJzZSA9IGZhbHNlLCAuLi5zYW1wbGUpIHtcblx0XHRcdFx0XHRzdXBlcihzYW1wbGUsIGludmVyc2UpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGFzeW1tZXRyaWNNYXRjaChvdGhlcikge1xuXHRcdFx0XHRcdGNvbnN0IHsgcGFzcyB9ID0gZXhwZWN0QXNzZXJ0aW9uLmNhbGwodGhpcy5nZXRNYXRjaGVyQ29udGV4dChleHBlY3QpLCBvdGhlciwgLi4udGhpcy5zYW1wbGUpO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLmludmVyc2UgPyAhcGFzcyA6IHBhc3M7XG5cdFx0XHRcdH1cblx0XHRcdFx0dG9TdHJpbmcoKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGAke3RoaXMuaW52ZXJzZSA/IFwibm90LlwiIDogXCJcIn0ke2V4cGVjdEFzc2VydGlvbk5hbWV9YDtcblx0XHRcdFx0fVxuXHRcdFx0XHRnZXRFeHBlY3RlZFR5cGUoKSB7XG5cdFx0XHRcdFx0cmV0dXJuIFwiYW55XCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0dG9Bc3ltbWV0cmljTWF0Y2hlcigpIHtcblx0XHRcdFx0XHRyZXR1cm4gYCR7dGhpcy50b1N0cmluZygpfTwke3RoaXMuc2FtcGxlLm1hcCgoaXRlbSkgPT4gc3RyaW5naWZ5KGl0ZW0pKS5qb2luKFwiLCBcIil9PmA7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGNvbnN0IGN1c3RvbU1hdGNoZXIgPSAoLi4uc2FtcGxlKSA9PiBuZXcgQ3VzdG9tTWF0Y2hlcihmYWxzZSwgLi4uc2FtcGxlKTtcblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBlY3QsIGV4cGVjdEFzc2VydGlvbk5hbWUsIHtcblx0XHRcdFx0Y29uZmlndXJhYmxlOiB0cnVlLFxuXHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuXHRcdFx0XHR2YWx1ZTogY3VzdG9tTWF0Y2hlcixcblx0XHRcdFx0d3JpdGFibGU6IHRydWVcblx0XHRcdH0pO1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cGVjdC5ub3QsIGV4cGVjdEFzc2VydGlvbk5hbWUsIHtcblx0XHRcdFx0Y29uZmlndXJhYmxlOiB0cnVlLFxuXHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuXHRcdFx0XHR2YWx1ZTogKC4uLnNhbXBsZSkgPT4gbmV3IEN1c3RvbU1hdGNoZXIodHJ1ZSwgLi4uc2FtcGxlKSxcblx0XHRcdFx0d3JpdGFibGU6IHRydWVcblx0XHRcdH0pO1xuXHRcdFx0Ly8ga2VlcCB0cmFjayBvZiBhc3ltbWV0cmljIG1hdGNoZXJzIG9uIGdsb2JhbCBzbyB0aGF0IGl0IGNhbiBiZSBjb3BpZWQgb3ZlciB0byBsb2NhbCBjb250ZXh0J3MgYGV4cGVjdGAuXG5cdFx0XHQvLyBub3RlIHRoYXQgdGhlIG5lZ2F0ZWQgdmFyaWFudCBpcyBhdXRvbWF0aWNhbGx5IHNoYXJlZCBzaW5jZSBpdCdzIGFzc2lnbmVkIG9uIHRoZSBzaW5nbGUgYGV4cGVjdC5ub3RgIG9iamVjdC5cblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxUaGlzW0FTWU1NRVRSSUNfTUFUQ0hFUlNfT0JKRUNUXSwgZXhwZWN0QXNzZXJ0aW9uTmFtZSwge1xuXHRcdFx0XHRjb25maWd1cmFibGU6IHRydWUsXG5cdFx0XHRcdGVudW1lcmFibGU6IHRydWUsXG5cdFx0XHRcdHZhbHVlOiBjdXN0b21NYXRjaGVyLFxuXHRcdFx0XHR3cml0YWJsZTogdHJ1ZVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH07XG59XG5jb25zdCBKZXN0RXh0ZW5kID0gKGNoYWksIHV0aWxzKSA9PiB7XG5cdHV0aWxzLmFkZE1ldGhvZChjaGFpLmV4cGVjdCwgXCJleHRlbmRcIiwgKGV4cGVjdCwgZXhwZWN0cykgPT4ge1xuXHRcdHVzZShKZXN0RXh0ZW5kUGx1Z2luKGNoYWksIGV4cGVjdCwgZXhwZWN0cykpO1xuXHR9KTtcbn07XG5cbmV4cG9ydCB7IEFTWU1NRVRSSUNfTUFUQ0hFUlNfT0JKRUNULCBBbnksIEFueXRoaW5nLCBBcnJheUNvbnRhaW5pbmcsIEFzeW1tZXRyaWNNYXRjaGVyLCBDaGFpU3R5bGVBc3NlcnRpb25zLCBHTE9CQUxfRVhQRUNULCBKRVNUX01BVENIRVJTX09CSkVDVCwgSmVzdEFzeW1tZXRyaWNNYXRjaGVycywgSmVzdENoYWlFeHBlY3QsIEplc3RFeHRlbmQsIE1BVENIRVJTX09CSkVDVCwgT2JqZWN0Q29udGFpbmluZywgU2NoZW1hTWF0Y2hpbmcsIFN0cmluZ0NvbnRhaW5pbmcsIFN0cmluZ01hdGNoaW5nLCBhZGRDdXN0b21FcXVhbGl0eVRlc3RlcnMsIGFycmF5QnVmZmVyRXF1YWxpdHksIGNyZWF0ZUFzc2VydGlvbk1lc3NhZ2UsIGN1c3RvbU1hdGNoZXJzLCBlcXVhbHMsIGZuTmFtZUZvciwgZ2VuZXJhdGVUb0JlTWVzc2FnZSwgZ2V0T2JqZWN0S2V5cywgZ2V0T2JqZWN0U3Vic2V0LCBnZXRTdGF0ZSwgaGFzQXN5bW1ldHJpYywgaGFzUHJvcGVydHksIGlzQSwgaXNBc3ltbWV0cmljLCBpc0Vycm9yLCBpc0ltbXV0YWJsZVVub3JkZXJlZEtleWVkLCBpc0ltbXV0YWJsZVVub3JkZXJlZFNldCwgaXNTdGFuZGFyZFNjaGVtYSwgaXRlcmFibGVFcXVhbGl0eSwgcGx1cmFsaXplLCByZWNvcmRBc3luY0V4cGVjdCwgc2V0U3RhdGUsIHNwYXJzZUFycmF5RXF1YWxpdHksIHN1YnNldEVxdWFsaXR5LCB0eXBlRXF1YWxpdHksIHdyYXBBc3NlcnRpb24gfTtcbiJdLCJ4X2dvb2dsZV9pZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQVVBLE1BQU0sdUJBQXVCLE1BQU0sVUFBVTtDQUM1QyxTQUFTLFlBQVksTUFBTSxZQUFZO0FBQ3RDLFFBQU0sWUFBWSxLQUFLLFVBQVUsV0FBVyxNQUFNLFdBQVc7R0FDNUQsTUFBTSxhQUFhLEtBQUssVUFBVSxVQUFVO0FBQzVDLE9BQUksQ0FBQyxXQUNKLE9BQU0sSUFBSSxNQUFNLHNCQUFzQixPQUFPLFdBQVcsQ0FBQyxtRUFBbUU7QUFFN0gsVUFBTyxXQUFXLEtBQUssS0FBSztJQUMzQjs7Q0FFSCxTQUFTLG9CQUFvQixNQUFNLFlBQVksR0FBRyxNQUFNO0FBQ3ZELFFBQU0sWUFBWSxLQUFLLFVBQVUsV0FBVyxNQUFNLFdBQVc7R0FDNUQsTUFBTSxhQUFhLEtBQUssVUFBVSxVQUFVO0FBQzVDLE9BQUksQ0FBQyxXQUNKLE9BQU0sSUFBSSxNQUFNLHNCQUFzQixPQUFPLFdB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