velocious 1.0.175 → 1.0.177

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 (32) hide show
  1. package/build/src/database/drivers/base.d.ts +3 -2
  2. package/build/src/database/drivers/base.d.ts.map +1 -1
  3. package/build/src/database/drivers/base.js +2 -2
  4. package/build/src/database/query/index.d.ts +6 -1
  5. package/build/src/database/query/index.d.ts.map +1 -1
  6. package/build/src/database/query/index.js +21 -1
  7. package/build/src/database/query/join-object.d.ts +6 -0
  8. package/build/src/database/query/join-object.d.ts.map +1 -1
  9. package/build/src/database/query/join-object.js +26 -12
  10. package/build/src/database/query/model-class-query.d.ts +5 -0
  11. package/build/src/database/query/model-class-query.d.ts.map +1 -1
  12. package/build/src/database/query/model-class-query.js +32 -1
  13. package/build/src/database/query/where-not.d.ts +9 -0
  14. package/build/src/database/query/where-not.d.ts.map +1 -0
  15. package/build/src/database/query/where-not.js +19 -0
  16. package/build/src/testing/base-expect.d.ts +13 -0
  17. package/build/src/testing/base-expect.d.ts.map +1 -0
  18. package/build/src/testing/base-expect.js +14 -0
  19. package/build/src/testing/expect-to-change.d.ts +27 -0
  20. package/build/src/testing/expect-to-change.d.ts.map +1 -0
  21. package/build/src/testing/expect-to-change.js +43 -0
  22. package/build/src/testing/expect-utils.d.ts +45 -0
  23. package/build/src/testing/expect-utils.d.ts.map +1 -0
  24. package/build/src/testing/expect-utils.js +190 -0
  25. package/build/src/testing/expect.d.ts +137 -0
  26. package/build/src/testing/expect.d.ts.map +1 -0
  27. package/build/src/testing/expect.js +619 -0
  28. package/build/src/testing/test.d.ts +4 -152
  29. package/build/src/testing/test.d.ts.map +1 -1
  30. package/build/src/testing/test.js +3 -655
  31. package/build/tsconfig.tsbuildinfo +1 -1
  32. package/package.json +3 -3
@@ -0,0 +1,619 @@
1
+ // @ts-check
2
+ import { formatValue, minifiedStringify } from "./format-value.js";
3
+ import { anythingDifferent } from "set-state-compare/build/diff-utils.js";
4
+ import BaseExpect from "./base-expect.js";
5
+ import ExpectToChange from "./expect-to-change.js";
6
+ import { isArrayContaining, isObjectContaining, matchArrayContaining, matchObject } from "./expect-utils.js";
7
+ export default class Expect extends BaseExpect {
8
+ /**
9
+ * @param {any} object - Object.
10
+ */
11
+ constructor(object) {
12
+ super();
13
+ this._object = object;
14
+ /** @type {Array<Expect | ExpectToChange>} */
15
+ this.expectations = [];
16
+ }
17
+ /**
18
+ * @param {function(): Promise<number>} changeCallback - Change callback.
19
+ * @returns {ExpectToChange} - The and change.
20
+ */
21
+ andChange(changeCallback) {
22
+ return this.toChange(changeCallback);
23
+ }
24
+ /**
25
+ * @returns {this} - A value.
26
+ */
27
+ get not() {
28
+ this._not = true;
29
+ return this;
30
+ }
31
+ /**
32
+ * @param {any} result - Result.
33
+ * @returns {void} - No return value.
34
+ */
35
+ toBe(result) {
36
+ if (this._not) {
37
+ if (this._object === result) {
38
+ const objectPrint = formatValue(this._object);
39
+ const resultPrint = formatValue(result);
40
+ throw new Error(`${objectPrint} was unexpected not to be ${resultPrint}`);
41
+ }
42
+ }
43
+ else {
44
+ if (this._object !== result) {
45
+ const objectPrint = formatValue(this._object);
46
+ const resultPrint = formatValue(result);
47
+ throw new Error(`${objectPrint} wasn't expected be ${resultPrint}`);
48
+ }
49
+ }
50
+ }
51
+ /**
52
+ * @param {number} result - Result.
53
+ * @returns {void} - No return value.
54
+ */
55
+ toBeLessThan(result) {
56
+ if (typeof this._object !== "number" || typeof result !== "number") {
57
+ throw new Error(`Expected numbers but got ${typeof this._object} and ${typeof result}`);
58
+ }
59
+ if (this._not) {
60
+ if (this._object < result) {
61
+ const objectPrint = formatValue(this._object);
62
+ const resultPrint = formatValue(result);
63
+ throw new Error(`${objectPrint} was unexpected to be less than ${resultPrint}`);
64
+ }
65
+ }
66
+ else {
67
+ if (this._object >= result) {
68
+ const objectPrint = formatValue(this._object);
69
+ const resultPrint = formatValue(result);
70
+ throw new Error(`${objectPrint} wasn't expected to be greater than or equal to ${resultPrint}`);
71
+ }
72
+ }
73
+ }
74
+ /**
75
+ * @param {number} result - Result.
76
+ * @returns {void} - No return value.
77
+ */
78
+ toBeLessThanOrEqual(result) {
79
+ if (typeof this._object !== "number" || typeof result !== "number") {
80
+ throw new Error(`Expected numbers but got ${typeof this._object} and ${typeof result}`);
81
+ }
82
+ if (this._not) {
83
+ if (this._object <= result) {
84
+ const objectPrint = formatValue(this._object);
85
+ const resultPrint = formatValue(result);
86
+ throw new Error(`${objectPrint} was unexpected to be less than or equal to ${resultPrint}`);
87
+ }
88
+ }
89
+ else {
90
+ if (this._object > result) {
91
+ const objectPrint = formatValue(this._object);
92
+ const resultPrint = formatValue(result);
93
+ throw new Error(`${objectPrint} wasn't expected to be greater than ${resultPrint}`);
94
+ }
95
+ }
96
+ }
97
+ /**
98
+ * @param {number} result - Result.
99
+ * @returns {void} - No return value.
100
+ */
101
+ toBeGreaterThan(result) {
102
+ if (typeof this._object !== "number" || typeof result !== "number") {
103
+ throw new Error(`Expected numbers but got ${typeof this._object} and ${typeof result}`);
104
+ }
105
+ if (this._not) {
106
+ if (this._object > result) {
107
+ const objectPrint = formatValue(this._object);
108
+ const resultPrint = formatValue(result);
109
+ throw new Error(`${objectPrint} was unexpected to be greater than ${resultPrint}`);
110
+ }
111
+ }
112
+ else {
113
+ if (this._object <= result) {
114
+ const objectPrint = formatValue(this._object);
115
+ const resultPrint = formatValue(result);
116
+ throw new Error(`${objectPrint} wasn't expected to be less than or equal to ${resultPrint}`);
117
+ }
118
+ }
119
+ }
120
+ /**
121
+ * @param {number} result - Result.
122
+ * @returns {void} - No return value.
123
+ */
124
+ toBeGreaterThanOrEqual(result) {
125
+ if (typeof this._object !== "number" || typeof result !== "number") {
126
+ throw new Error(`Expected numbers but got ${typeof this._object} and ${typeof result}`);
127
+ }
128
+ if (this._not) {
129
+ if (this._object >= result) {
130
+ const objectPrint = formatValue(this._object);
131
+ const resultPrint = formatValue(result);
132
+ throw new Error(`${objectPrint} was unexpected to be greater than or equal to ${resultPrint}`);
133
+ }
134
+ }
135
+ else {
136
+ if (this._object < result) {
137
+ const objectPrint = formatValue(this._object);
138
+ const resultPrint = formatValue(result);
139
+ throw new Error(`${objectPrint} wasn't expected to be less than ${resultPrint}`);
140
+ }
141
+ }
142
+ }
143
+ /**
144
+ * @param {number} result - Result.
145
+ * @param {number} [precision] - Decimal precision.
146
+ * @returns {void} - No return value.
147
+ */
148
+ toBeCloseTo(result, precision = 2) {
149
+ if (typeof this._object !== "number" || typeof result !== "number") {
150
+ throw new Error(`Expected numbers but got ${typeof this._object} and ${typeof result}`);
151
+ }
152
+ if (typeof precision !== "number" || !Number.isFinite(precision)) {
153
+ throw new Error(`Expected precision to be a number but got ${typeof precision}`);
154
+ }
155
+ const tolerance = 0.5 * Math.pow(10, -precision);
156
+ const diff = Math.abs(this._object - result);
157
+ const isClose = diff <= tolerance;
158
+ if (this._not) {
159
+ if (isClose) {
160
+ const objectPrint = formatValue(this._object);
161
+ const resultPrint = formatValue(result);
162
+ throw new Error(`${objectPrint} was unexpected to be close to ${resultPrint}`);
163
+ }
164
+ }
165
+ else {
166
+ if (!isClose) {
167
+ const objectPrint = formatValue(this._object);
168
+ const resultPrint = formatValue(result);
169
+ throw new Error(`${objectPrint} wasn't expected to be close to ${resultPrint}`);
170
+ }
171
+ }
172
+ }
173
+ /**
174
+ * @param {number} result - Expected length.
175
+ * @returns {void} - No return value.
176
+ */
177
+ toHaveLength(result) {
178
+ if (typeof result !== "number") {
179
+ throw new Error(`Expected length number but got ${typeof result}`);
180
+ }
181
+ if (this._object === null || this._object === undefined || typeof this._object.length !== "number") {
182
+ throw new Error(`Expected value with length but got ${typeof this._object}`);
183
+ }
184
+ const objectPrint = formatValue(this._object);
185
+ const resultPrint = formatValue(result);
186
+ const lengthValue = this._object.length;
187
+ if (this._not) {
188
+ if (lengthValue === result) {
189
+ throw new Error(`${objectPrint} was unexpected to have length ${resultPrint}`);
190
+ }
191
+ }
192
+ else if (lengthValue !== result) {
193
+ throw new Error(`${objectPrint} wasn't expected to have length ${resultPrint}`);
194
+ }
195
+ }
196
+ /**
197
+ * @returns {void} - No return value.
198
+ */
199
+ toBeDefined() {
200
+ if (this._not) {
201
+ if (this._object !== undefined) {
202
+ const objectPrint = formatValue(this._object);
203
+ throw new Error(`${objectPrint} wasn´t expected to be defined`);
204
+ }
205
+ }
206
+ else {
207
+ if (this._object === undefined) {
208
+ const objectPrint = formatValue(this._object);
209
+ throw new Error(`${objectPrint} wasn't expected be undefined`);
210
+ }
211
+ }
212
+ }
213
+ /**
214
+ * @param {new (...args: unknown[]) => unknown} klass - Class constructor to check against.
215
+ * @returns {void} - No return value.
216
+ */
217
+ toBeInstanceOf(klass) {
218
+ if (!(this._object instanceof klass)) {
219
+ const objectPrint = formatValue(this._object);
220
+ throw new Error(`Expected ${objectPrint} to be a ${klass.name} but it wasn't`);
221
+ }
222
+ }
223
+ /**
224
+ * @returns {void} - No return value.
225
+ */
226
+ toBeFalse() {
227
+ this.toBe(false);
228
+ }
229
+ /**
230
+ * @returns {void} - No return value.
231
+ */
232
+ toBeNull() {
233
+ this.toBe(null);
234
+ }
235
+ /**
236
+ * @returns {void} - No return value.
237
+ */
238
+ toBeUndefined() {
239
+ this.toBe(undefined);
240
+ }
241
+ /**
242
+ * @returns {void} - No return value.
243
+ */
244
+ toBeTrue() {
245
+ this.toBe(true);
246
+ }
247
+ /**
248
+ * @returns {void} - No return value.
249
+ */
250
+ toBeTruthy() {
251
+ const objectPrint = formatValue(this._object);
252
+ if (this._not) {
253
+ if (this._object) {
254
+ throw new Error(`${objectPrint} was unexpected to be truthy`);
255
+ }
256
+ }
257
+ else {
258
+ if (!this._object) {
259
+ throw new Error(`${objectPrint} wasn't expected to be truthy`);
260
+ }
261
+ }
262
+ }
263
+ /**
264
+ * @param {function(): Promise<number>} changeCallback - Change callback.
265
+ * @returns {ExpectToChange} - The change.
266
+ */
267
+ toChange(changeCallback) {
268
+ if (this._not)
269
+ throw new Error("not stub");
270
+ const expectToChange = new ExpectToChange({ changeCallback, expect: this });
271
+ this.expectations.push(expectToChange);
272
+ return expectToChange;
273
+ }
274
+ /**
275
+ * @param {any} valueToContain - Value to contain.
276
+ * @returns {void} - No return value.
277
+ */
278
+ toContain(valueToContain) {
279
+ if (this._not)
280
+ throw new Error("not stub");
281
+ if (typeof this._object == "string") {
282
+ if (!this._object.includes(String(valueToContain))) {
283
+ const objectPrint = minifiedStringify(this._object);
284
+ const valuePrint = typeof valueToContain == "string"
285
+ ? minifiedStringify(valueToContain)
286
+ : formatValue(valueToContain);
287
+ throw new Error(`${objectPrint} doesn't contain ${valuePrint}`);
288
+ }
289
+ return;
290
+ }
291
+ if (!Array.isArray(this._object)) {
292
+ throw new Error(`Expected array or string but got ${typeof this._object}`);
293
+ }
294
+ if (!this._object.includes(valueToContain)) {
295
+ const objectPrint = formatValue(this._object);
296
+ const valuePrint = typeof valueToContain == "string"
297
+ ? minifiedStringify(valueToContain)
298
+ : formatValue(valueToContain);
299
+ throw new Error(`${objectPrint} doesn't contain ${valuePrint}`);
300
+ }
301
+ }
302
+ /**
303
+ * @param {any} valueToContain - Value to contain.
304
+ * @returns {void} - No return value.
305
+ */
306
+ toContainEqual(valueToContain) {
307
+ if (!Array.isArray(this._object)) {
308
+ throw new Error(`Expected array but got ${typeof this._object}`);
309
+ }
310
+ const matches = this._object.some((item) => !anythingDifferent(item, valueToContain));
311
+ const objectPrint = formatValue(this._object);
312
+ const valuePrint = typeof valueToContain == "string"
313
+ ? minifiedStringify(valueToContain)
314
+ : formatValue(valueToContain);
315
+ if (this._not) {
316
+ if (matches) {
317
+ throw new Error(`${objectPrint} was unexpected to contain ${valuePrint}`);
318
+ }
319
+ }
320
+ else if (!matches) {
321
+ throw new Error(`${objectPrint} doesn't contain ${valuePrint}`);
322
+ }
323
+ }
324
+ /**
325
+ * @param {any} result - Result.
326
+ * @returns {void} - No return value.
327
+ */
328
+ toEqual(result) {
329
+ if (this._object instanceof Set && result instanceof Set) {
330
+ const objectPrint = formatValue(this._object);
331
+ const resultPrint = formatValue(result);
332
+ const actualItems = Array.from(this._object);
333
+ const expectedItems = Array.from(result);
334
+ const missingItems = expectedItems.filter((expectedItem) => {
335
+ return !actualItems.some((actualItem) => !anythingDifferent(actualItem, expectedItem));
336
+ });
337
+ const unexpectedItems = actualItems.filter((actualItem) => {
338
+ return !expectedItems.some((expectedItem) => !anythingDifferent(actualItem, expectedItem));
339
+ });
340
+ const isEqual = missingItems.length === 0 && unexpectedItems.length === 0;
341
+ if (this._not) {
342
+ if (isEqual) {
343
+ throw new Error(`${objectPrint} was unexpected equal to ${resultPrint}`);
344
+ }
345
+ }
346
+ else if (!isEqual) {
347
+ const missingStrings = missingItems.map((item) => minifiedStringify(item));
348
+ const unexpectedStrings = unexpectedItems.map((item) => minifiedStringify(item));
349
+ const diffParts = [];
350
+ if (missingStrings.length > 0)
351
+ diffParts.push(`missing ${missingStrings.join(", ")}`);
352
+ if (unexpectedStrings.length > 0)
353
+ diffParts.push(`unexpected ${unexpectedStrings.join(", ")}`);
354
+ const diffMessage = diffParts.length > 0 ? ` (diff: ${diffParts.join("; ")})` : "";
355
+ throw new Error(`${objectPrint} wasn't equal to ${resultPrint}${diffMessage}`);
356
+ }
357
+ return;
358
+ }
359
+ if (isObjectContaining(result)) {
360
+ const expectedValue = /** @type {any} */ (result).value;
361
+ const { matches, differences } = matchObject(this._object, expectedValue);
362
+ const objectPrint = formatValue(this._object);
363
+ const expectedPrint = formatValue(expectedValue);
364
+ if (this._not) {
365
+ if (matches) {
366
+ throw new Error(`Expected ${objectPrint} not to match ${expectedPrint}`);
367
+ }
368
+ }
369
+ else if (!matches) {
370
+ const diffPrint = Object.keys(differences).length > 0 ? ` (diff: ${minifiedStringify(differences)})` : "";
371
+ throw new Error(`Expected ${objectPrint} to match ${expectedPrint}${diffPrint}`);
372
+ }
373
+ return;
374
+ }
375
+ if (isArrayContaining(result)) {
376
+ const expectedValue = /** @type {any[]} */ ( /** @type {any} */(result).value);
377
+ const { matches, differences } = matchArrayContaining(this._object, expectedValue);
378
+ const objectPrint = formatValue(this._object);
379
+ const expectedPrint = formatValue(expectedValue);
380
+ if (this._not) {
381
+ if (matches) {
382
+ throw new Error(`Expected ${objectPrint} not to match ${expectedPrint}`);
383
+ }
384
+ }
385
+ else if (!matches) {
386
+ const diffPrint = Object.keys(differences).length > 0 ? ` (diff: ${minifiedStringify(differences)})` : "";
387
+ throw new Error(`Expected ${objectPrint} to match ${expectedPrint}${diffPrint}`);
388
+ }
389
+ return;
390
+ }
391
+ if (this._not) {
392
+ if (typeof this._object == "object" && typeof result == "object") {
393
+ if (!anythingDifferent(this._object, result)) {
394
+ const objectPrint = formatValue(this._object);
395
+ const resultPrint = formatValue(result);
396
+ throw new Error(`${objectPrint} was unexpected equal to ${resultPrint}`);
397
+ }
398
+ }
399
+ else {
400
+ if (this._object == result) {
401
+ const objectPrint = formatValue(this._object);
402
+ const resultPrint = formatValue(result);
403
+ throw new Error(`${objectPrint} was unexpected equal to ${resultPrint}`);
404
+ }
405
+ }
406
+ }
407
+ else {
408
+ if (typeof this._object == "object" && typeof result == "object") {
409
+ if (anythingDifferent(this._object, result)) {
410
+ const objectPrint = formatValue(this._object);
411
+ const resultPrint = formatValue(result);
412
+ if (Array.isArray(this._object) && Array.isArray(result)) {
413
+ const actualStrings = this._object.map((item) => minifiedStringify(item));
414
+ const expectedStrings = result.map((item) => minifiedStringify(item));
415
+ const missingItems = expectedStrings.filter((item) => !actualStrings.includes(item));
416
+ const unexpectedItems = actualStrings.filter((item) => !expectedStrings.includes(item));
417
+ const diffParts = [];
418
+ if (missingItems.length > 0)
419
+ diffParts.push(`missing ${missingItems.join(", ")}`);
420
+ if (unexpectedItems.length > 0)
421
+ diffParts.push(`unexpected ${unexpectedItems.join(", ")}`);
422
+ const diffMessage = diffParts.length > 0 ? ` (diff: ${diffParts.join("; ")})` : "";
423
+ throw new Error(`${objectPrint} wasn't equal to ${resultPrint}${diffMessage}`);
424
+ }
425
+ throw new Error(`${objectPrint} wasn't equal to ${resultPrint}`);
426
+ }
427
+ }
428
+ else {
429
+ if (this._object != result) {
430
+ const objectPrint = formatValue(this._object);
431
+ const resultPrint = formatValue(result);
432
+ throw new Error(`${objectPrint} wasn't equal to ${resultPrint}`);
433
+ }
434
+ }
435
+ }
436
+ }
437
+ /**
438
+ * @param {RegExp} regex - Regex.
439
+ * @returns {void} - No return value.
440
+ */
441
+ toMatch(regex) {
442
+ if (typeof this._object !== "string") {
443
+ throw new Error(`Expected string but got ${typeof this._object}`);
444
+ }
445
+ const match = this._object.match(regex);
446
+ const objectPrint = minifiedStringify(this._object);
447
+ if (this._not) {
448
+ if (match) {
449
+ throw new Error(`${objectPrint} shouldn't match ${regex}`);
450
+ }
451
+ }
452
+ else {
453
+ if (!match) {
454
+ throw new Error(`${objectPrint} didn't match ${regex}`);
455
+ }
456
+ }
457
+ }
458
+ /**
459
+ * @param {Record<string, any> | any[]} expected - Expected partial object.
460
+ * @returns {void} - No return value.
461
+ */
462
+ toMatchObject(expected) {
463
+ if (expected === null || typeof expected !== "object") {
464
+ throw new Error(`Expected object but got ${typeof expected}`);
465
+ }
466
+ const { matches, differences } = matchObject(this._object, expected);
467
+ const objectPrint = formatValue(this._object);
468
+ const expectedPrint = formatValue(expected);
469
+ if (this._not) {
470
+ if (matches) {
471
+ throw new Error(`Expected ${objectPrint} not to match ${expectedPrint}`);
472
+ }
473
+ }
474
+ else if (!matches) {
475
+ const diffPrint = Object.keys(differences).length > 0 ? ` (diff: ${minifiedStringify(differences)})` : "";
476
+ throw new Error(`Expected ${objectPrint} to match ${expectedPrint}${diffPrint}`);
477
+ }
478
+ }
479
+ /**
480
+ * @template T extends Error
481
+ * @param {string|T} expectedError - Expected error.
482
+ * @returns {Promise<void>} - Resolves when complete.
483
+ */
484
+ async toThrowError(expectedError) {
485
+ if (this._not)
486
+ throw new Error("not stub");
487
+ let failedError;
488
+ try {
489
+ if (typeof this._object !== "function") {
490
+ throw new Error(`Expected function but got ${typeof this._object}`);
491
+ }
492
+ await this._object();
493
+ }
494
+ catch (error) {
495
+ failedError = error;
496
+ }
497
+ if (!failedError)
498
+ throw new Error("Expected to fail but didn't");
499
+ let expectedErrorMessage, failedErrorMessage;
500
+ if (typeof failedError == "string") {
501
+ failedErrorMessage = failedError;
502
+ }
503
+ else if (failedError instanceof Error) {
504
+ failedErrorMessage = failedError.message;
505
+ }
506
+ else {
507
+ failedErrorMessage = String(failedError);
508
+ }
509
+ if (typeof expectedError == "string") {
510
+ expectedErrorMessage = expectedError;
511
+ }
512
+ else if (expectedError instanceof Error) {
513
+ expectedErrorMessage = expectedError.message;
514
+ }
515
+ else {
516
+ expectedErrorMessage = String(expectedError);
517
+ }
518
+ if (failedErrorMessage != expectedErrorMessage) {
519
+ throw new Error(`Expected to fail with '${expectedErrorMessage}' but failed with '${failedErrorMessage}'`);
520
+ }
521
+ }
522
+ /**
523
+ * @param {string|RegExp|Error|((new (...args: unknown[]) => Error))} [expected] - Expected error.
524
+ * @returns {Promise<void>} - Resolves when complete.
525
+ */
526
+ async toThrow(expected) {
527
+ if (typeof this._object !== "function") {
528
+ throw new Error(`Expected function but got ${typeof this._object}`);
529
+ }
530
+ let failedError;
531
+ try {
532
+ await this._object();
533
+ }
534
+ catch (error) {
535
+ failedError = error;
536
+ }
537
+ const objectPrint = formatValue(this._object);
538
+ if (this._not) {
539
+ if (failedError) {
540
+ throw new Error(`${objectPrint} was unexpected to throw`);
541
+ }
542
+ return;
543
+ }
544
+ if (!failedError)
545
+ throw new Error("Expected to fail but didn't");
546
+ if (expected === undefined)
547
+ return;
548
+ const failedErrorMessage = failedError instanceof Error ? failedError.message : String(failedError);
549
+ const failedErrorName = failedError instanceof Error ? failedError.name : typeof failedError;
550
+ if (expected instanceof RegExp) {
551
+ if (!expected.test(failedErrorMessage)) {
552
+ throw new Error(`Expected to fail with message matching ${expected} but failed with '${failedErrorMessage}'`);
553
+ }
554
+ return;
555
+ }
556
+ if (typeof expected === "function" && (expected.prototype instanceof Error || expected === Error)) {
557
+ if (!(failedError instanceof expected)) {
558
+ throw new Error(`Expected to throw ${expected.name} but threw ${failedErrorName}`);
559
+ }
560
+ return;
561
+ }
562
+ let expectedMessage;
563
+ if (typeof expected === "string") {
564
+ expectedMessage = expected;
565
+ }
566
+ else if (expected instanceof Error) {
567
+ expectedMessage = expected.message;
568
+ }
569
+ else {
570
+ expectedMessage = String(expected);
571
+ }
572
+ if (failedErrorMessage != expectedMessage) {
573
+ throw new Error(`Expected to fail with '${expectedMessage}' but failed with '${failedErrorMessage}'`);
574
+ }
575
+ }
576
+ /**
577
+ * @returns {Promise<any>} - Resolves with the execute.
578
+ */
579
+ async execute() {
580
+ for (const expectation of this.expectations) {
581
+ await expectation.runBefore();
582
+ }
583
+ if (typeof this._object !== "function") {
584
+ throw new Error(`Expected function but got ${typeof this._object}`);
585
+ }
586
+ const result = await this._object();
587
+ for (const expectation of this.expectations) {
588
+ await expectation.runAfter();
589
+ }
590
+ for (const expectation of this.expectations) {
591
+ await expectation.execute();
592
+ }
593
+ return result;
594
+ }
595
+ /**
596
+ * @param {Record<string, any>} result - Result.
597
+ * @returns {void} - No return value.
598
+ */
599
+ toHaveAttributes(result) {
600
+ if (this._not)
601
+ throw new Error("not stub");
602
+ /** @type {Record<string, any[]>} */
603
+ const differences = {};
604
+ const objectAsRecord = /** @type {Record<string, unknown>} */ (this._object);
605
+ for (const key in result) {
606
+ const value = result[key];
607
+ if (!(key in objectAsRecord))
608
+ throw new Error(`${this._object.constructor.name} doesn't respond to ${key}`);
609
+ const objectValue = /** @type {() => unknown} */ (objectAsRecord[key])();
610
+ if (value != objectValue) {
611
+ differences[key] = [value, objectValue];
612
+ }
613
+ }
614
+ if (Object.keys(differences).length > 0) {
615
+ throw new Error(`Object had differet values: ${minifiedStringify(differences)}`);
616
+ }
617
+ }
618
+ }
619
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3Rlc3RpbmcvZXhwZWN0LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsV0FBVyxFQUFFLGlCQUFpQixFQUFDLE1BQU0sbUJBQW1CLENBQUE7QUFDaEUsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sdUNBQXVDLENBQUE7QUFDdkUsT0FBTyxVQUFVLE1BQU0sa0JBQWtCLENBQUE7QUFDekMsT0FBTyxjQUFjLE1BQU0sdUJBQXVCLENBQUE7QUFDbEQsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixrQkFBa0IsRUFDbEIsb0JBQW9CLEVBQ3BCLFdBQVcsRUFDWixNQUFNLG1CQUFtQixDQUFBO0FBRTFCLE1BQU0sQ0FBQyxPQUFPLE9BQU8sTUFBTyxTQUFRLFVBQVU7SUFDNUM7O09BRUc7SUFDSCxZQUFZLE1BQU07UUFDaEIsS0FBSyxFQUFFLENBQUE7UUFDUCxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQTtRQUVyQiw2Q0FBNkM7UUFDN0MsSUFBSSxDQUFDLFlBQVksR0FBRyxFQUFFLENBQUE7SUFDeEIsQ0FBQztJQUVEOzs7T0FHRztJQUNILFNBQVMsQ0FBQyxjQUFjO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsQ0FBQTtJQUN0QyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLEdBQUc7UUFDTCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQTtRQUVoQixPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUFJLENBQUMsTUFBTTtRQUNULElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2QsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLE1BQU0sRUFBRSxDQUFDO2dCQUM1QixNQUFNLFdBQVcsR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FB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QUN6QyxDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDeEMsTUFBTSxJQUFJLEtBQUssQ0FBQywrQkFBK0IsaUJBQWlCLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQ2xGLENBQUM7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtmb3JtYXRWYWx1ZSwgbWluaWZpZWRTdHJpbmdpZnl9IGZyb20gXCIuL2Zvcm1hdC12YWx1ZS5qc1wiXG5pbXBvcnQge2FueXRoaW5nRGlmZmVyZW50fSBmcm9tIFwic2V0LXN0YXRlLWNvbXBhcmUvYnVpbGQvZGlmZi11dGlscy5qc1wiXG5pbXBvcnQgQmFzZUV4cGVjdCBmcm9tIFwiLi9iYXNlLWV4cGVjdC5qc1wiXG5pbXBvcnQgRXhwZWN0VG9DaGFuZ2UgZnJvbSBcIi4vZXhwZWN0LXRvLWNoYW5nZS5qc1wiXG5pbXBvcnQge1xuICBpc0FycmF5Q29udGFpbmluZyxcbiAgaXNPYmplY3RDb250YWluaW5nLFxuICBtYXRjaEFycmF5Q29udGFpbmluZyxcbiAgbWF0Y2hPYmplY3Rcbn0gZnJvbSBcIi4vZXhwZWN0LXV0aWxzLmpzXCJcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXhwZWN0IGV4dGVuZHMgQmFzZUV4cGVjdCB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2FueX0gb2JqZWN0IC0gT2JqZWN0LlxuICAgKi9cbiAgY29uc3RydWN0b3Iob2JqZWN0KSB7XG4gICAgc3VwZXIoKVxuICAgIHRoaXMuX29iamVjdCA9IG9iamVjdFxuXG4gICAgLyoqIEB0eXBlIHtBcnJheTxFeHBlY3QgfCBFeHBlY3RUb0NoYW5nZT59ICovXG4gICAgdGhpcy5leHBlY3RhdGlvbnMgPSBbXVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oKTogUHJvbWlzZTxudW1iZXI+fSBjaGFuZ2VDYWxsYmFjayAtIENoYW5nZSBjYWxsYmFjay5cbiAgICogQHJldHVybnMge0V4cGVjdFRvQ2hhbmdlfSAtIFRoZSBhbmQgY2hhbmdlLlxuICAgKi9cbiAgYW5kQ2hhbmdlKGNoYW5nZUNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHRoaXMudG9DaGFuZ2UoY2hhbmdlQ2FsbGJhY2spXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge3RoaXN9IC0gQSB2YWx1ZS5cbiAgICovXG4gIGdldCBub3QoKSB7XG4gICAgdGhpcy5fbm90ID0gdHJ1ZVxuXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2FueX0gcmVzdWx0IC0gUmVzdWx0LlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICB0b0JlKHJlc3VsdCkge1xuICAgIGlmICh0aGlzLl9ub3QpIHtcbiAgICAgIGlmICh0aGlzLl9vYmplY3QgPT09IHJlc3VsdCkge1xuICAgICAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcbiAgICAgICAgY29uc3QgcmVzdWx0UHJpbnQgPSBmb3JtYXRWYWx1ZShyZXN1bHQpXG5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXMgdW5leHBlY3RlZCBub3QgdG8gYmUgJHtyZXN1bHRQcmludH1gKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5fb2JqZWN0ICE9PSByZXN1bHQpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2Fzbid0IGV4cGVjdGVkIGJlICR7cmVzdWx0UHJpbnR9YClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc3VsdCAtIFJlc3VsdC5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9CZUxlc3NUaGFuKHJlc3VsdCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fb2JqZWN0ICE9PSBcIm51bWJlclwiIHx8IHR5cGVvZiByZXN1bHQgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgbnVtYmVycyBidXQgZ290ICR7dHlwZW9mIHRoaXMuX29iamVjdH0gYW5kICR7dHlwZW9mIHJlc3VsdH1gKVxuICAgIH1cblxuICAgIGlmICh0aGlzLl9ub3QpIHtcbiAgICAgIGlmICh0aGlzLl9vYmplY3QgPCByZXN1bHQpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2FzIHVuZXhwZWN0ZWQgdG8gYmUgbGVzcyB0aGFuICR7cmVzdWx0UHJpbnR9YClcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuX29iamVjdCA+PSByZXN1bHQpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2Fzbid0IGV4cGVjdGVkIHRvIGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAke3Jlc3VsdFByaW50fWApXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByZXN1bHQgLSBSZXN1bHQuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHRvQmVMZXNzVGhhbk9yRXF1YWwocmVzdWx0KSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl9vYmplY3QgIT09IFwibnVtYmVyXCIgfHwgdHlwZW9mIHJlc3VsdCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBudW1iZXJzIGJ1dCBnb3QgJHt0eXBlb2YgdGhpcy5fb2JqZWN0fSBhbmQgJHt0eXBlb2YgcmVzdWx0fWApXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX25vdCkge1xuICAgICAgaWYgKHRoaXMuX29iamVjdCA8PSByZXN1bHQpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2FzIHVuZXhwZWN0ZWQgdG8gYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICR7cmVzdWx0UHJpbnR9YClcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuX29iamVjdCA+IHJlc3VsdCkge1xuICAgICAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcbiAgICAgICAgY29uc3QgcmVzdWx0UHJpbnQgPSBmb3JtYXRWYWx1ZShyZXN1bHQpXG5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXNuJ3QgZXhwZWN0ZWQgdG8gYmUgZ3JlYXRlciB0aGFuICR7cmVzdWx0UHJpbnR9YClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc3VsdCAtIFJlc3VsdC5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9CZUdyZWF0ZXJUaGFuKHJlc3VsdCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fb2JqZWN0ICE9PSBcIm51bWJlclwiIHx8IHR5cGVvZiByZXN1bHQgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgbnVtYmVycyBidXQgZ290ICR7dHlwZW9mIHRoaXMuX29iamVjdH0gYW5kICR7dHlwZW9mIHJlc3VsdH1gKVxuICAgIH1cblxuICAgIGlmICh0aGlzLl9ub3QpIHtcbiAgICAgIGlmICh0aGlzLl9vYmplY3QgPiByZXN1bHQpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2FzIHVuZXhwZWN0ZWQgdG8gYmUgZ3JlYXRlciB0aGFuICR7cmVzdWx0UHJpbnR9YClcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuX29iamVjdCA8PSByZXN1bHQpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2Fzbid0IGV4cGVjdGVkIHRvIGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAke3Jlc3VsdFByaW50fWApXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByZXN1bHQgLSBSZXN1bHQuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHRvQmVHcmVhdGVyVGhhbk9yRXF1YWwocmVzdWx0KSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl9vYmplY3QgIT09IFwibnVtYmVyXCIgfHwgdHlwZW9mIHJlc3VsdCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBudW1iZXJzIGJ1dCBnb3QgJHt0eXBlb2YgdGhpcy5fb2JqZWN0fSBhbmQgJHt0eXBlb2YgcmVzdWx0fWApXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX25vdCkge1xuICAgICAgaWYgKHRoaXMuX29iamVjdCA+PSByZXN1bHQpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2FzIHVuZXhwZWN0ZWQgdG8gYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICR7cmVzdWx0UHJpbnR9YClcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuX29iamVjdCA8IHJlc3VsdCkge1xuICAgICAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcbiAgICAgICAgY29uc3QgcmVzdWx0UHJpbnQgPSBmb3JtYXRWYWx1ZShyZXN1bHQpXG5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXNuJ3QgZXhwZWN0ZWQgdG8gYmUgbGVzcyB0aGFuICR7cmVzdWx0UHJpbnR9YClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc3VsdCAtIFJlc3VsdC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtwcmVjaXNpb25dIC0gRGVjaW1hbCBwcmVjaXNpb24uXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHRvQmVDbG9zZVRvKHJlc3VsdCwgcHJlY2lzaW9uID0gMikge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fb2JqZWN0ICE9PSBcIm51bWJlclwiIHx8IHR5cGVvZiByZXN1bHQgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgbnVtYmVycyBidXQgZ290ICR7dHlwZW9mIHRoaXMuX29iamVjdH0gYW5kICR7dHlwZW9mIHJlc3VsdH1gKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgcHJlY2lzaW9uICE9PSBcIm51bWJlclwiIHx8ICFOdW1iZXIuaXNGaW5pdGUocHJlY2lzaW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBwcmVjaXNpb24gdG8gYmUgYSBudW1iZXIgYnV0IGdvdCAke3R5cGVvZiBwcmVjaXNpb259YClcbiAgICB9XG5cbiAgICBjb25zdCB0b2xlcmFuY2UgPSAwLjUgKiBNYXRoLnBvdygxMCwgLXByZWNpc2lvbilcbiAgICBjb25zdCBkaWZmID0gTWF0aC5hYnModGhpcy5fb2JqZWN0IC0gcmVzdWx0KVxuICAgIGNvbnN0IGlzQ2xvc2UgPSBkaWZmIDw9IHRvbGVyYW5jZVxuXG4gICAgaWYgKHRoaXMuX25vdCkge1xuICAgICAgaWYgKGlzQ2xvc2UpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2FzIHVuZXhwZWN0ZWQgdG8gYmUgY2xvc2UgdG8gJHtyZXN1bHRQcmludH1gKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIWlzQ2xvc2UpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2Fzbid0IGV4cGVjdGVkIHRvIGJlIGNsb3NlIHRvICR7cmVzdWx0UHJpbnR9YClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc3VsdCAtIEV4cGVjdGVkIGxlbmd0aC5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9IYXZlTGVuZ3RoKHJlc3VsdCkge1xuICAgIGlmICh0eXBlb2YgcmVzdWx0ICE9PSBcIm51bWJlclwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGxlbmd0aCBudW1iZXIgYnV0IGdvdCAke3R5cGVvZiByZXN1bHR9YClcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fb2JqZWN0ID09PSBudWxsIHx8IHRoaXMuX29iamVjdCA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiB0aGlzLl9vYmplY3QubGVuZ3RoICE9PSBcIm51bWJlclwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIHZhbHVlIHdpdGggbGVuZ3RoIGJ1dCBnb3QgJHt0eXBlb2YgdGhpcy5fb2JqZWN0fWApXG4gICAgfVxuXG4gICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgY29uc3QgcmVzdWx0UHJpbnQgPSBmb3JtYXRWYWx1ZShyZXN1bHQpXG4gICAgY29uc3QgbGVuZ3RoVmFsdWUgPSB0aGlzLl9vYmplY3QubGVuZ3RoXG5cbiAgICBpZiAodGhpcy5fbm90KSB7XG4gICAgICBpZiAobGVuZ3RoVmFsdWUgPT09IHJlc3VsdCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7b2JqZWN0UHJpbnR9IHdhcyB1bmV4cGVjdGVkIHRvIGhhdmUgbGVuZ3RoICR7cmVzdWx0UHJpbnR9YClcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGxlbmd0aFZhbHVlICE9PSByZXN1bHQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2Fzbid0IGV4cGVjdGVkIHRvIGhhdmUgbGVuZ3RoICR7cmVzdWx0UHJpbnR9YClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9CZURlZmluZWQoKSB7XG4gICAgaWYgKHRoaXMuX25vdCkge1xuICAgICAgaWYgKHRoaXMuX29iamVjdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IG9iamVjdFByaW50ID0gZm9ybWF0VmFsdWUodGhpcy5fb2JqZWN0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2FzbsK0dCBleHBlY3RlZCB0byBiZSBkZWZpbmVkYClcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuX29iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IG9iamVjdFByaW50ID0gZm9ybWF0VmFsdWUodGhpcy5fb2JqZWN0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2Fzbid0IGV4cGVjdGVkIGJlIHVuZGVmaW5lZGApXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7bmV3ICguLi5hcmdzOiB1bmtub3duW10pID0+IHVua25vd259IGtsYXNzIC0gQ2xhc3MgY29uc3RydWN0b3IgdG8gY2hlY2sgYWdhaW5zdC5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9CZUluc3RhbmNlT2Yoa2xhc3MpIHtcbiAgICBpZiAoISh0aGlzLl9vYmplY3QgaW5zdGFuY2VvZiBrbGFzcykpIHtcbiAgICAgIGNvbnN0IG9iamVjdFByaW50ID0gZm9ybWF0VmFsdWUodGhpcy5fb2JqZWN0KVxuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkICR7b2JqZWN0UHJpbnR9IHRvIGJlIGEgJHtrbGFzcy5uYW1lfSBidXQgaXQgd2Fzbid0YClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9CZUZhbHNlKCkge1xuICAgIHRoaXMudG9CZShmYWxzZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICB0b0JlTnVsbCgpIHtcbiAgICB0aGlzLnRvQmUobnVsbClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICB0b0JlVW5kZWZpbmVkKCkge1xuICAgIHRoaXMudG9CZSh1bmRlZmluZWQpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9CZVRydWUoKSB7XG4gICAgdGhpcy50b0JlKHRydWUpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9CZVRydXRoeSgpIHtcbiAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcblxuICAgIGlmICh0aGlzLl9ub3QpIHtcbiAgICAgIGlmICh0aGlzLl9vYmplY3QpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXMgdW5leHBlY3RlZCB0byBiZSB0cnV0aHlgKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIXRoaXMuX29iamVjdCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7b2JqZWN0UHJpbnR9IHdhc24ndCBleHBlY3RlZCB0byBiZSB0cnV0aHlgKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKCk6IFByb21pc2U8bnVtYmVyPn0gY2hhbmdlQ2FsbGJhY2sgLSBDaGFuZ2UgY2FsbGJhY2suXG4gICAqIEByZXR1cm5zIHtFeHBlY3RUb0NoYW5nZX0gLSBUaGUgY2hhbmdlLlxuICAgKi9cbiAgdG9DaGFuZ2UoY2hhbmdlQ2FsbGJhY2spIHtcbiAgICBpZiAodGhpcy5fbm90KSB0aHJvdyBuZXcgRXJyb3IoXCJub3Qgc3R1YlwiKVxuXG4gICAgY29uc3QgZXhwZWN0VG9DaGFuZ2UgPSBuZXcgRXhwZWN0VG9DaGFuZ2Uoe2NoYW5nZUNhbGxiYWNrLCBleHBlY3Q6IHRoaXN9KVxuXG4gICAgdGhpcy5leHBlY3RhdGlvbnMucHVzaChleHBlY3RUb0NoYW5nZSlcblxuICAgIHJldHVybiBleHBlY3RUb0NoYW5nZVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7YW55fSB2YWx1ZVRvQ29udGFpbiAtIFZhbHVlIHRvIGNvbnRhaW4uXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHRvQ29udGFpbih2YWx1ZVRvQ29udGFpbikge1xuICAgIGlmICh0aGlzLl9ub3QpIHRocm93IG5ldyBFcnJvcihcIm5vdCBzdHViXCIpXG5cbiAgICBpZiAodHlwZW9mIHRoaXMuX29iamVjdCA9PSBcInN0cmluZ1wiKSB7XG4gICAgICBpZiAoIXRoaXMuX29iamVjdC5pbmNsdWRlcyhTdHJpbmcodmFsdWVUb0NvbnRhaW4pKSkge1xuICAgICAgICBjb25zdCBvYmplY3RQcmludCA9IG1pbmlmaWVkU3RyaW5naWZ5KHRoaXMuX29iamVjdClcbiAgICAgICAgY29uc3QgdmFsdWVQcmludCA9IHR5cGVvZiB2YWx1ZVRvQ29udGFpbiA9PSBcInN0cmluZ1wiXG4gICAgICAgICAgPyBtaW5pZmllZFN0cmluZ2lmeSh2YWx1ZVRvQ29udGFpbilcbiAgICAgICAgICA6IGZvcm1hdFZhbHVlKHZhbHVlVG9Db250YWluKVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gZG9lc24ndCBjb250YWluICR7dmFsdWVQcmludH1gKVxuICAgICAgfVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHRoaXMuX29iamVjdCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgYXJyYXkgb3Igc3RyaW5nIGJ1dCBnb3QgJHt0eXBlb2YgdGhpcy5fb2JqZWN0fWApXG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLl9vYmplY3QuaW5jbHVkZXModmFsdWVUb0NvbnRhaW4pKSB7XG4gICAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcbiAgICAgIGNvbnN0IHZhbHVlUHJpbnQgPSB0eXBlb2YgdmFsdWVUb0NvbnRhaW4gPT0gXCJzdHJpbmdcIlxuICAgICAgICA/IG1pbmlmaWVkU3RyaW5naWZ5KHZhbHVlVG9Db250YWluKVxuICAgICAgICA6IGZvcm1hdFZhbHVlKHZhbHVlVG9Db250YWluKVxuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7b2JqZWN0UHJpbnR9IGRvZXNuJ3QgY29udGFpbiAke3ZhbHVlUHJpbnR9YClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHthbnl9IHZhbHVlVG9Db250YWluIC0gVmFsdWUgdG8gY29udGFpbi5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9Db250YWluRXF1YWwodmFsdWVUb0NvbnRhaW4pIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkodGhpcy5fb2JqZWN0KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBhcnJheSBidXQgZ290ICR7dHlwZW9mIHRoaXMuX29iamVjdH1gKVxuICAgIH1cblxuICAgIGNvbnN0IG1hdGNoZXMgPSB0aGlzLl9vYmplY3Quc29tZSgoaXRlbSkgPT4gIWFueXRoaW5nRGlmZmVyZW50KGl0ZW0sIHZhbHVlVG9Db250YWluKSlcbiAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcbiAgICBjb25zdCB2YWx1ZVByaW50ID0gdHlwZW9mIHZhbHVlVG9Db250YWluID09IFwic3RyaW5nXCJcbiAgICAgID8gbWluaWZpZWRTdHJpbmdpZnkodmFsdWVUb0NvbnRhaW4pXG4gICAgICA6IGZvcm1hdFZhbHVlKHZhbHVlVG9Db250YWluKVxuXG4gICAgaWYgKHRoaXMuX25vdCkge1xuICAgICAgaWYgKG1hdGNoZXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXMgdW5leHBlY3RlZCB0byBjb250YWluICR7dmFsdWVQcmludH1gKVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIW1hdGNoZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gZG9lc24ndCBjb250YWluICR7dmFsdWVQcmludH1gKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2FueX0gcmVzdWx0IC0gUmVzdWx0LlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICB0b0VxdWFsKHJlc3VsdCkge1xuICAgIGlmICh0aGlzLl9vYmplY3QgaW5zdGFuY2VvZiBTZXQgJiYgcmVzdWx0IGluc3RhbmNlb2YgU2V0KSB7XG4gICAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcbiAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuICAgICAgY29uc3QgYWN0dWFsSXRlbXMgPSBBcnJheS5mcm9tKHRoaXMuX29iamVjdClcbiAgICAgIGNvbnN0IGV4cGVjdGVkSXRlbXMgPSBBcnJheS5mcm9tKHJlc3VsdClcbiAgICAgIGNvbnN0IG1pc3NpbmdJdGVtcyA9IGV4cGVjdGVkSXRlbXMuZmlsdGVyKChleHBlY3RlZEl0ZW0pID0+IHtcbiAgICAgICAgcmV0dXJuICFhY3R1YWxJdGVtcy5zb21lKChhY3R1YWxJdGVtKSA9PiAhYW55dGhpbmdEaWZmZXJlbnQoYWN0dWFsSXRlbSwgZXhwZWN0ZWRJdGVtKSlcbiAgICAgIH0pXG4gICAgICBjb25zdCB1bmV4cGVjdGVkSXRlbXMgPSBhY3R1YWxJdGVtcy5maWx0ZXIoKGFjdHVhbEl0ZW0pID0+IHtcbiAgICAgICAgcmV0dXJuICFleHBlY3RlZEl0ZW1zLnNvbWUoKGV4cGVjdGVkSXRlbSkgPT4gIWFueXRoaW5nRGlmZmVyZW50KGFjdHVhbEl0ZW0sIGV4cGVjdGVkSXRlbSkpXG4gICAgICB9KVxuICAgICAgY29uc3QgaXNFcXVhbCA9IG1pc3NpbmdJdGVtcy5sZW5ndGggPT09IDAgJiYgdW5leHBlY3RlZEl0ZW1zLmxlbmd0aCA9PT0gMFxuXG4gICAgICBpZiAodGhpcy5fbm90KSB7XG4gICAgICAgIGlmIChpc0VxdWFsKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXMgdW5leHBlY3RlZCBlcXVhbCB0byAke3Jlc3VsdFByaW50fWApXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIWlzRXF1YWwpIHtcbiAgICAgICAgY29uc3QgbWlzc2luZ1N0cmluZ3MgPSBtaXNzaW5nSXRlbXMubWFwKChpdGVtKSA9PiBtaW5pZmllZFN0cmluZ2lmeShpdGVtKSlcbiAgICAgICAgY29uc3QgdW5leHBlY3RlZFN0cmluZ3MgPSB1bmV4cGVjdGVkSXRlbXMubWFwKChpdGVtKSA9PiBtaW5pZmllZFN0cmluZ2lmeShpdGVtKSlcbiAgICAgICAgY29uc3QgZGlmZlBhcnRzID0gW11cblxuICAgICAgICBpZiAobWlzc2luZ1N0cmluZ3MubGVuZ3RoID4gMCkgZGlmZlBhcnRzLnB1c2goYG1pc3NpbmcgJHttaXNzaW5nU3RyaW5ncy5qb2luKFwiLCBcIil9YClcbiAgICAgICAgaWYgKHVuZXhwZWN0ZWRTdHJpbmdzLmxlbmd0aCA+IDApIGRpZmZQYXJ0cy5wdXNoKGB1bmV4cGVjdGVkICR7dW5leHBlY3RlZFN0cmluZ3Muam9pbihcIiwgXCIpfWApXG5cbiAgICAgICAgY29uc3QgZGlmZk1lc3NhZ2UgPSBkaWZmUGFydHMubGVuZ3RoID4gMCA/IGAgKGRpZmY6ICR7ZGlmZlBhcnRzLmpvaW4oXCI7IFwiKX0pYCA6IFwiXCJcblxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7b2JqZWN0UHJpbnR9IHdhc24ndCBlcXVhbCB0byAke3Jlc3VsdFByaW50fSR7ZGlmZk1lc3NhZ2V9YClcbiAgICAgIH1cblxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKGlzT2JqZWN0Q29udGFpbmluZyhyZXN1bHQpKSB7XG4gICAgICBjb25zdCBleHBlY3RlZFZhbHVlID0gLyoqIEB0eXBlIHthbnl9ICovIChyZXN1bHQpLnZhbHVlXG4gICAgICBjb25zdCB7bWF0Y2hlcywgZGlmZmVyZW5jZXN9ID0gbWF0Y2hPYmplY3QodGhpcy5fb2JqZWN0LCBleHBlY3RlZFZhbHVlKVxuICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICBjb25zdCBleHBlY3RlZFByaW50ID0gZm9ybWF0VmFsdWUoZXhwZWN0ZWRWYWx1ZSlcblxuICAgICAgaWYgKHRoaXMuX25vdCkge1xuICAgICAgICBpZiAobWF0Y2hlcykge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtvYmplY3RQcmludH0gbm90IHRvIG1hdGNoICR7ZXhwZWN0ZWRQcmludH1gKVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKCFtYXRjaGVzKSB7XG4gICAgICAgIGNvbnN0IGRpZmZQcmludCA9IE9iamVjdC5rZXlzKGRpZmZlcmVuY2VzKS5sZW5ndGggPiAwID8gYCAoZGlmZjogJHttaW5pZmllZFN0cmluZ2lmeShkaWZmZXJlbmNlcyl9KWAgOiBcIlwiXG5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke29iamVjdFByaW50fSB0byBtYXRjaCAke2V4cGVjdGVkUHJpbnR9JHtkaWZmUHJpbnR9YClcbiAgICAgIH1cblxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKGlzQXJyYXlDb250YWluaW5nKHJlc3VsdCkpIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkVmFsdWUgPSAvKiogQHR5cGUge2FueVtdfSAqLyAoLyoqIEB0eXBlIHthbnl9ICovIChyZXN1bHQpLnZhbHVlKVxuICAgICAgY29uc3Qge21hdGNoZXMsIGRpZmZlcmVuY2VzfSA9IG1hdGNoQXJyYXlDb250YWluaW5nKHRoaXMuX29iamVjdCwgZXhwZWN0ZWRWYWx1ZSlcbiAgICAgIGNvbnN0IG9iamVjdFByaW50ID0gZm9ybWF0VmFsdWUodGhpcy5fb2JqZWN0KVxuICAgICAgY29uc3QgZXhwZWN0ZWRQcmludCA9IGZvcm1hdFZhbHVlKGV4cGVjdGVkVmFsdWUpXG5cbiAgICAgIGlmICh0aGlzLl9ub3QpIHtcbiAgICAgICAgaWYgKG1hdGNoZXMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkICR7b2JqZWN0UHJpbnR9IG5vdCB0byBtYXRjaCAke2V4cGVjdGVkUHJpbnR9YClcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICghbWF0Y2hlcykge1xuICAgICAgICBjb25zdCBkaWZmUHJpbnQgPSBPYmplY3Qua2V5cyhkaWZmZXJlbmNlcykubGVuZ3RoID4gMCA/IGAgKGRpZmY6ICR7bWluaWZpZWRTdHJpbmdpZnkoZGlmZmVyZW5jZXMpfSlgIDogXCJcIlxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtvYmplY3RQcmludH0gdG8gbWF0Y2ggJHtleHBlY3RlZFByaW50fSR7ZGlmZlByaW50fWApXG4gICAgICB9XG5cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICh0aGlzLl9ub3QpIHtcbiAgICAgIGlmICh0eXBlb2YgdGhpcy5fb2JqZWN0ID09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlc3VsdCA9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIGlmICghYW55dGhpbmdEaWZmZXJlbnQodGhpcy5fb2JqZWN0LCByZXN1bHQpKSB7XG4gICAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICAgICAgY29uc3QgcmVzdWx0UHJpbnQgPSBmb3JtYXRWYWx1ZShyZXN1bHQpXG5cbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7b2JqZWN0UHJpbnR9IHdhcyB1bmV4cGVjdGVkIGVxdWFsIHRvICR7cmVzdWx0UHJpbnR9YClcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMuX29iamVjdCA9PSByZXN1bHQpIHtcbiAgICAgICAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcbiAgICAgICAgICBjb25zdCByZXN1bHRQcmludCA9IGZvcm1hdFZhbHVlKHJlc3VsdClcblxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2FzIHVuZXhwZWN0ZWQgZXF1YWwgdG8gJHtyZXN1bHRQcmludH1gKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlb2YgdGhpcy5fb2JqZWN0ID09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlc3VsdCA9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIGlmIChhbnl0aGluZ0RpZmZlcmVudCh0aGlzLl9vYmplY3QsIHJlc3VsdCkpIHtcbiAgICAgICAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcbiAgICAgICAgICBjb25zdCByZXN1bHRQcmludCA9IGZvcm1hdFZhbHVlKHJlc3VsdClcblxuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMuX29iamVjdCkgJiYgQXJyYXkuaXNBcnJheShyZXN1bHQpKSB7XG4gICAgICAgICAgICBjb25zdCBhY3R1YWxTdHJpbmdzID0gdGhpcy5fb2JqZWN0Lm1hcCgoaXRlbSkgPT4gbWluaWZpZWRTdHJpbmdpZnkoaXRlbSkpXG4gICAgICAgICAgICBjb25zdCBleHBlY3RlZFN0cmluZ3MgPSByZXN1bHQubWFwKChpdGVtKSA9PiBtaW5pZmllZFN0cmluZ2lmeShpdGVtKSlcblxuICAgICAgICAgICAgY29uc3QgbWlzc2luZ0l0ZW1zID0gZXhwZWN0ZWRTdHJpbmdzLmZpbHRlcigoaXRlbSkgPT4gIWFjdHVhbFN0cmluZ3MuaW5jbHVkZXMoaXRlbSkpXG4gICAgICAgICAgICBjb25zdCB1bmV4cGVjdGVkSXRlbXMgPSBhY3R1YWxTdHJpbmdzLmZpbHRlcigoaXRlbSkgPT4gIWV4cGVjdGVkU3RyaW5ncy5pbmNsdWRlcyhpdGVtKSlcblxuICAgICAgICAgICAgY29uc3QgZGlmZlBhcnRzID0gW11cblxuICAgICAgICAgICAgaWYgKG1pc3NpbmdJdGVtcy5sZW5ndGggPiAwKSBkaWZmUGFydHMucHVzaChgbWlzc2luZyAke21pc3NpbmdJdGVtcy5qb2luKFwiLCBcIil9YClcbiAgICAgICAgICAgIGlmICh1bmV4cGVjdGVkSXRlbXMubGVuZ3RoID4gMCkgZGlmZlBhcnRzLnB1c2goYHVuZXhwZWN0ZWQgJHt1bmV4cGVjdGVkSXRlbXMuam9pbihcIiwgXCIpfWApXG5cbiAgICAgICAgICAgIGNvbnN0IGRpZmZNZXNzYWdlID0gZGlmZlBhcnRzLmxlbmd0aCA+IDAgPyBgIChkaWZmOiAke2RpZmZQYXJ0cy5qb2luKFwiOyBcIil9KWAgOiBcIlwiXG5cbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2Fzbid0IGVxdWFsIHRvICR7cmVzdWx0UHJpbnR9JHtkaWZmTWVzc2FnZX1gKVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2Fzbid0IGVxdWFsIHRvICR7cmVzdWx0UHJpbnR9YClcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMuX29iamVjdCAhPSByZXN1bHQpIHtcbiAgICAgICAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcbiAgICAgICAgICBjb25zdCByZXN1bHRQcmludCA9IGZvcm1hdFZhbHVlKHJlc3VsdClcblxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2Fzbid0IGVxdWFsIHRvICR7cmVzdWx0UHJpbnR9YClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1JlZ0V4cH0gcmVnZXggLSBSZWdleC5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9NYXRjaChyZWdleCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fb2JqZWN0ICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIHN0cmluZyBidXQgZ290ICR7dHlwZW9mIHRoaXMuX29iamVjdH1gKVxuICAgIH1cblxuICAgIGNvbnN0IG1hdGNoID0gdGhpcy5fb2JqZWN0Lm1hdGNoKHJlZ2V4KVxuICAgIGNvbnN0IG9iamVjdFByaW50ID0gbWluaWZpZWRTdHJpbmdpZnkodGhpcy5fb2JqZWN0KVxuXG4gICAgaWYgKHRoaXMuX25vdCkge1xuICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gc2hvdWxkbid0IG1hdGNoICR7cmVnZXh9YClcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFtYXRjaCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7b2JqZWN0UHJpbnR9IGRpZG4ndCBtYXRjaCAke3JlZ2V4fWApXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55PiB8IGFueVtdfSBleHBlY3RlZCAtIEV4cGVjdGVkIHBhcnRpYWwgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICB0b01hdGNoT2JqZWN0KGV4cGVjdGVkKSB7XG4gICAgaWYgKGV4cGVjdGVkID09PSBudWxsIHx8IHR5cGVvZiBleHBlY3RlZCAhPT0gXCJvYmplY3RcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBvYmplY3QgYnV0IGdvdCAke3R5cGVvZiBleHBlY3RlZH1gKVxuICAgIH1cblxuICAgIGNvbnN0IHttYXRjaGVzLCBkaWZmZXJlbmNlc30gPSBtYXRjaE9iamVjdCh0aGlzLl9vYmplY3QsIGV4cGVjdGVkKVxuICAgIGNvbnN0IG9iamVjdFByaW50ID0gZm9ybWF0VmFsdWUodGhpcy5fb2JqZWN0KVxuICAgIGNvbnN0IGV4cGVjdGVkUHJpbnQgPSBmb3JtYXRWYWx1ZShleHBlY3RlZClcblxuICAgIGlmICh0aGlzLl9ub3QpIHtcbiAgICAgIGlmIChtYXRjaGVzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtvYmplY3RQcmludH0gbm90IHRvIG1hdGNoICR7ZXhwZWN0ZWRQcmludH1gKVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIW1hdGNoZXMpIHtcbiAgICAgIGNvbnN0IGRpZmZQcmludCA9IE9iamVjdC5rZXlzKGRpZmZlcmVuY2VzKS5sZW5ndGggPiAwID8gYCAoZGlmZjogJHttaW5pZmllZFN0cmluZ2lmeShkaWZmZXJlbmNlcyl9KWAgOiBcIlwiXG5cbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtvYmplY3RQcmludH0gdG8gbWF0Y2ggJHtleHBlY3RlZFByaW50fSR7ZGlmZlByaW50fWApXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEB0ZW1wbGF0ZSBUIGV4dGVuZHMgRXJyb3JcbiAgICogQHBhcmFtIHtzdHJpbmd8VH0gZXhwZWN0ZWRFcnJvciAtIEV4cGVjdGVkIGVycm9yLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgdG9UaHJvd0Vycm9yKGV4cGVjdGVkRXJyb3IpIHtcbiAgICBpZiAodGhpcy5fbm90KSB0aHJvdyBuZXcgRXJyb3IoXCJub3Qgc3R1YlwiKVxuXG4gICAgbGV0IGZhaWxlZEVycm9yXG5cbiAgICB0cnkge1xuICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vYmplY3QgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGZ1bmN0aW9uIGJ1dCBnb3QgJHt0eXBlb2YgdGhpcy5fb2JqZWN0fWApXG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHRoaXMuX29iamVjdCgpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGZhaWxlZEVycm9yID0gZXJyb3JcbiAgICB9XG5cbiAgICBpZiAoIWZhaWxlZEVycm9yKSB0aHJvdyBuZXcgRXJyb3IoXCJFeHBlY3RlZCB0byBmYWlsIGJ1dCBkaWRuJ3RcIilcblxuICAgIGxldCBleHBlY3RlZEVycm9yTWVzc2FnZSwgZmFpbGVkRXJyb3JNZXNzYWdlXG5cbiAgICBpZiAodHlwZW9mIGZhaWxlZEVycm9yID09IFwic3RyaW5nXCIpIHtcbiAgICAgIGZhaWxlZEVycm9yTWVzc2FnZSA9IGZhaWxlZEVycm9yXG4gICAgfSBlbHNlIGlmIChmYWlsZWRFcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBmYWlsZWRFcnJvck1lc3NhZ2UgPSBmYWlsZWRFcnJvci5tZXNzYWdlXG4gICAgfSBlbHNlIHtcbiAgICAgIGZhaWxlZEVycm9yTWVzc2FnZSA9IFN0cmluZyhmYWlsZWRFcnJvcilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGV4cGVjdGVkRXJyb3IgPT0gXCJzdHJpbmdcIikge1xuICAgICAgZXhwZWN0ZWRFcnJvck1lc3NhZ2UgPSBleHBlY3RlZEVycm9yXG4gICAgfSBlbHNlIGlmIChleHBlY3RlZEVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIGV4cGVjdGVkRXJyb3JNZXNzYWdlID0gZXhwZWN0ZWRFcnJvci5tZXNzYWdlXG4gICAgfSBlbHNlIHtcbiAgICAgIGV4cGVjdGVkRXJyb3JNZXNzYWdlID0gU3RyaW5nKGV4cGVjdGVkRXJyb3IpXG4gICAgfVxuXG4gICAgaWYgKGZhaWxlZEVycm9yTWVzc2FnZSAhPSBleHBlY3RlZEVycm9yTWVzc2FnZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCB0byBmYWlsIHdpdGggJyR7ZXhwZWN0ZWRFcnJvck1lc3NhZ2V9JyBidXQgZmFpbGVkIHdpdGggJyR7ZmFpbGVkRXJyb3JNZXNzYWdlfSdgKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ3xSZWdFeHB8RXJyb3J8KChuZXcgKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gRXJyb3IpKX0gW2V4cGVjdGVkXSAtIEV4cGVjdGVkIGVycm9yLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgdG9UaHJvdyhleHBlY3RlZCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fb2JqZWN0ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgZnVuY3Rpb24gYnV0IGdvdCAke3R5cGVvZiB0aGlzLl9vYmplY3R9YClcbiAgICB9XG5cbiAgICBsZXQgZmFpbGVkRXJyb3JcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLl9vYmplY3QoKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBmYWlsZWRFcnJvciA9IGVycm9yXG4gICAgfVxuXG4gICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG5cbiAgICBpZiAodGhpcy5fbm90KSB7XG4gICAgICBpZiAoZmFpbGVkRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXMgdW5leHBlY3RlZCB0byB0aHJvd2ApXG4gICAgICB9XG5cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICghZmFpbGVkRXJyb3IpIHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGVkIHRvIGZhaWwgYnV0IGRpZG4ndFwiKVxuICAgIGlmIChleHBlY3RlZCA9PT0gdW5kZWZpbmVkKSByZXR1cm5cblxuICAgIGNvbnN0IGZhaWxlZEVycm9yTWVzc2FnZSA9IGZhaWxlZEVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBmYWlsZWRFcnJvci5tZXNzYWdlIDogU3RyaW5nKGZhaWxlZEVycm9yKVxuICAgIGNvbnN0IGZhaWxlZEVycm9yTmFtZSA9IGZhaWxlZEVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBmYWlsZWRFcnJvci5uYW1lIDogdHlwZW9mIGZhaWxlZEVycm9yXG5cbiAgICBpZiAoZXhwZWN0ZWQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgIGlmICghZXhwZWN0ZWQudGVzdChmYWlsZWRFcnJvck1lc3NhZ2UpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgdG8gZmFpbCB3aXRoIG1lc3NhZ2UgbWF0Y2hpbmcgJHtleHBlY3RlZH0gYnV0IGZhaWxlZCB3aXRoICcke2ZhaWxlZEVycm9yTWVzc2FnZX0nYClcbiAgICAgIH1cblxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBleHBlY3RlZCA9PT0gXCJmdW5jdGlvblwiICYmIChleHBlY3RlZC5wcm90b3R5cGUgaW5zdGFuY2VvZiBFcnJvciB8fCBleHBlY3RlZCA9PT0gRXJyb3IpKSB7XG4gICAgICBpZiAoIShmYWlsZWRFcnJvciBpbnN0YW5jZW9mIGV4cGVjdGVkKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIHRvIHRocm93ICR7ZXhwZWN0ZWQubmFtZX0gYnV0IHRocmV3ICR7ZmFpbGVkRXJyb3JOYW1lfWApXG4gICAgICB9XG5cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGxldCBleHBlY3RlZE1lc3NhZ2VcblxuICAgIGlmICh0eXBlb2YgZXhwZWN0ZWQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGV4cGVjdGVkTWVzc2FnZSA9IGV4cGVjdGVkXG4gICAgfSBlbHNlIGlmIChleHBlY3RlZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBleHBlY3RlZE1lc3NhZ2UgPSBleHBlY3RlZC5tZXNzYWdlXG4gICAgfSBlbHNlIHtcbiAgICAgIGV4cGVjdGVkTWVzc2FnZSA9IFN0cmluZyhleHBlY3RlZClcbiAgICB9XG5cbiAgICBpZiAoZmFpbGVkRXJyb3JNZXNzYWdlICE9IGV4cGVjdGVkTWVzc2FnZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCB0byBmYWlsIHdpdGggJyR7ZXhwZWN0ZWRNZXNzYWdlfScgYnV0IGZhaWxlZCB3aXRoICcke2ZhaWxlZEVycm9yTWVzc2FnZX0nYClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge1Byb21pc2U8YW55Pn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBleGVjdXRlLlxuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZSgpIHtcbiAgICBmb3IgKGNvbnN0IGV4cGVjdGF0aW9uIG9mIHRoaXMuZXhwZWN0YXRpb25zKSB7XG4gICAgICBhd2FpdCBleHBlY3RhdGlvbi5ydW5CZWZvcmUoKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGhpcy5fb2JqZWN0ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgZnVuY3Rpb24gYnV0IGdvdCAke3R5cGVvZiB0aGlzLl9vYmplY3R9YClcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLl9vYmplY3QoKVxuXG4gICAgZm9yIChjb25zdCBleHBlY3RhdGlvbiBvZiB0aGlzLmV4cGVjdGF0aW9ucykge1xuICAgICAgYXdhaXQgZXhwZWN0YXRpb24ucnVuQWZ0ZXIoKVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZXhwZWN0YXRpb24gb2YgdGhpcy5leHBlY3RhdGlvbnMpIHtcbiAgICAgIGF3YWl0IGV4cGVjdGF0aW9uLmV4ZWN1dGUoKVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHRcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IHJlc3VsdCAtIFJlc3VsdC5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9IYXZlQXR0cmlidXRlcyhyZXN1bHQpIHtcbiAgICBpZiAodGhpcy5fbm90KSB0aHJvdyBuZXcgRXJyb3IoXCJub3Qgc3R1YlwiKVxuXG4gICAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBhbnlbXT59ICovXG4gICAgY29uc3QgZGlmZmVyZW5jZXMgPSB7fVxuICAgIGNvbnN0IG9iamVjdEFzUmVjb3JkID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gKi8gKHRoaXMuX29iamVjdClcblxuICAgIGZvciAoY29uc3Qga2V5IGluIHJlc3VsdCkge1xuICAgICAgY29uc3QgdmFsdWUgPSByZXN1bHRba2V5XVxuXG4gICAgICBpZiAoIShrZXkgaW4gb2JqZWN0QXNSZWNvcmQpKSB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5fb2JqZWN0LmNvbnN0cnVjdG9yLm5hbWV9IGRvZXNuJ3QgcmVzcG9uZCB0byAke2tleX1gKVxuXG4gICAgICBjb25zdCBvYmplY3RWYWx1ZSA9IC8qKiBAdHlwZSB7KCkgPT4gdW5rbm93bn0gKi8gKG9iamVjdEFzUmVjb3JkW2tleV0pKClcblxuICAgICAgaWYgKHZhbHVlICE9IG9iamVjdFZhbHVlKSB7XG4gICAgICAgIGRpZmZlcmVuY2VzW2tleV0gPSBbdmFsdWUsIG9iamVjdFZhbHVlXVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChPYmplY3Qua2V5cyhkaWZmZXJlbmNlcykubGVuZ3RoID4gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBPYmplY3QgaGFkIGRpZmZlcmV0IHZhbHVlczogJHttaW5pZmllZFN0cmluZ2lmeShkaWZmZXJlbmNlcyl9YClcbiAgICB9XG4gIH1cbn1cbiJdfQ==