@cartanova/qgrid-cli 1.0.4 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/bundle/dist/application/qgrid/pool.js +15 -6
  2. package/bundle/dist/application/qgrid/qgrid.frame.js +17 -22
  3. package/bundle/dist/application/qgrid/qgrid.types.js +5 -2
  4. package/bundle/dist/application/request-log/request-log.model.js +2 -2
  5. package/bundle/dist/sonamu.config.js +5 -2
  6. package/bundle/src/application/qgrid/pool.ts +17 -7
  7. package/bundle/src/application/qgrid/qgrid.frame.ts +18 -25
  8. package/bundle/src/application/qgrid/qgrid.types.ts +1 -1
  9. package/bundle/src/application/request-log/request-log.model.ts +2 -2
  10. package/bundle/src/sonamu.config.ts +1 -1
  11. package/bundle/web-dist/{web-dist/client/assets/index-DlPchHBY.js → client/assets/index-C0m8rRjO.js} +2 -2
  12. package/bundle/web-dist/client/assets/{routes-CagDz23B.js → routes-B1eOXnpo.js} +1 -1
  13. package/bundle/web-dist/client/assets/{show-aXUGa0gm.js → show-BztN6MXO.js} +1 -1
  14. package/bundle/web-dist/client/assets/tokens-rR2_-Pte.js +1 -0
  15. package/bundle/web-dist/client/index.html +1 -1
  16. package/bundle/web-dist/server/assets/{tokens-JH6FsnWZ.js → tokens-ARL5AOAh.js} +4 -1
  17. package/bundle/web-dist/server/entry-server.generated.js +1 -1
  18. package/dist/cli.js +38 -24
  19. package/package.json +10 -10
  20. package/bundle/dist/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorate.js +0 -9
  21. package/bundle/dist/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorateMetadata.js +0 -6
  22. package/bundle/dist/dist/_virtual/_rolldown/runtime.js +0 -15
  23. package/bundle/dist/dist/application/qgrid/oauth.js +0 -140
  24. package/bundle/dist/dist/application/qgrid/pool.js +0 -100
  25. package/bundle/dist/dist/application/qgrid/qgrid.frame.js +0 -280
  26. package/bundle/dist/dist/application/qgrid/qgrid.types.js +0 -79
  27. package/bundle/dist/dist/application/qgrid/worker.js +0 -183
  28. package/bundle/dist/dist/application/queries.generated.js +0 -31
  29. package/bundle/dist/dist/application/request-log/request-log.model.js +0 -113
  30. package/bundle/dist/dist/application/request-log/request-log.types.js +0 -13
  31. package/bundle/dist/dist/application/sonamu.generated.js +0 -99
  32. package/bundle/dist/dist/application/sonamu.generated.sso.js +0 -34
  33. package/bundle/dist/dist/application/token/token.model.js +0 -157
  34. package/bundle/dist/dist/application/token/token.types.js +0 -22
  35. package/bundle/dist/dist/i18n/en.js +0 -63
  36. package/bundle/dist/dist/i18n/ko.js +0 -62
  37. package/bundle/dist/dist/i18n/sd.generated.js +0 -272
  38. package/bundle/dist/dist/index.js +0 -11
  39. package/bundle/dist/dist/migrations/20260410171405_create__request_logs.js +0 -26
  40. package/bundle/dist/dist/migrations/20260410171406_create__tokens.js +0 -24
  41. package/bundle/dist/dist/migrations/20260411120624_alter_tokens_alter2.js +0 -16
  42. package/bundle/dist/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +0 -155
  43. package/bundle/dist/dist/node_modules/.pnpm/@vitest_expect@4.1.2/node_modules/@vitest/expect/dist/index.js +0 -1484
  44. package/bundle/dist/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.2/node_modules/@vitest/pretty-format/dist/index.js +0 -887
  45. package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/chunk-artifact.js +0 -2746
  46. package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/index.js +0 -8
  47. package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/utils.js +0 -8
  48. package/bundle/dist/dist/node_modules/.pnpm/@vitest_snapshot@4.1.2/node_modules/@vitest/snapshot/dist/index.js +0 -662
  49. package/bundle/dist/dist/node_modules/.pnpm/@vitest_spy@4.1.2/node_modules/@vitest/spy/dist/index.js +0 -386
  50. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +0 -82
  51. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/constants.js +0 -48
  52. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/diff.js +0 -1307
  53. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/display.js +0 -558
  54. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/error.js +0 -33
  55. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/helpers.js +0 -226
  56. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/offset.js +0 -27
  57. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/serialize.js +0 -77
  58. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/source-map.js +0 -374
  59. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/timers.js +0 -37
  60. package/bundle/dist/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +0 -2886
  61. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +0 -10
  62. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +0 -109
  63. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +0 -10
  64. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +0 -10
  65. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +0 -10
  66. package/bundle/dist/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +0 -1127
  67. package/bundle/dist/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +0 -21
  68. package/bundle/dist/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +0 -432
  69. package/bundle/dist/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +0 -506
  70. package/bundle/dist/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +0 -86
  71. package/bundle/dist/dist/node_modules/.pnpm/vite@8.0.3_@emnapi_core@1.9.2_@emnapi_runtime@1.9.2_@types_node@25.0.7_esbuild@0.27.4_jiti@2.6.1_sass@1.98.0_tsx@4.21.0/node_modules/vite/dist/node/module-runner.js +0 -426
  72. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +0 -6
  73. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/benchmark.CX_oY03V.js +0 -41
  74. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/evaluatedModules.Dg1zASAC.js +0 -19
  75. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/index.Chj8NDwU.js +0 -202
  76. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/index.DOa3dzoN.js +0 -16
  77. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +0 -59
  78. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/test.p_J6dB8a.js +0 -2910
  79. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +0 -44
  80. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/index.js +0 -28
  81. package/bundle/dist/dist/sonamu.config.js +0 -196
  82. package/bundle/dist/dist/testing/fixture.js +0 -8
  83. package/bundle/dist/dist/testing/global.js +0 -9
  84. package/bundle/dist/dist/testing/setup-mocks.js +0 -17
  85. package/bundle/dist/dist/utils/subset-loaders.js +0 -12
  86. package/bundle/src/src/application/qgrid/oauth.ts +0 -181
  87. package/bundle/src/src/application/qgrid/pool.ts +0 -132
  88. package/bundle/src/src/application/qgrid/qgrid.frame.ts +0 -275
  89. package/bundle/src/src/application/qgrid/qgrid.types.ts +0 -117
  90. package/bundle/src/src/application/qgrid/worker.ts +0 -234
  91. package/bundle/src/src/application/queries.generated.ts +0 -59
  92. package/bundle/src/src/application/request-log/request-log.entity.json +0 -75
  93. package/bundle/src/src/application/request-log/request-log.model.ts +0 -155
  94. package/bundle/src/src/application/request-log/request-log.types.ts +0 -15
  95. package/bundle/src/src/application/sonamu.generated.http +0 -187
  96. package/bundle/src/src/application/sonamu.generated.sso.ts +0 -66
  97. package/bundle/src/src/application/sonamu.generated.ts +0 -135
  98. package/bundle/src/src/application/token/token.entity.json +0 -37
  99. package/bundle/src/src/application/token/token.model.ts +0 -160
  100. package/bundle/src/src/application/token/token.types.ts +0 -26
  101. package/bundle/src/src/i18n/en.ts +0 -59
  102. package/bundle/src/src/i18n/ko.ts +0 -59
  103. package/bundle/src/src/i18n/sd.generated.ts +0 -384
  104. package/bundle/src/src/index.ts +0 -6
  105. package/bundle/src/src/migrations/20260410171405_create__request_logs.ts +0 -23
  106. package/bundle/src/src/migrations/20260410171406_create__tokens.ts +0 -21
  107. package/bundle/src/src/migrations/20260411120624_alter_tokens_alter2.ts +0 -15
  108. package/bundle/src/src/sonamu.config.ts +0 -248
  109. package/bundle/src/src/testing/fixture.ts +0 -6
  110. package/bundle/src/src/testing/global.ts +0 -6
  111. package/bundle/src/src/testing/setup-mocks.ts +0 -44
  112. package/bundle/src/src/typings/fastify.d.ts +0 -8
  113. package/bundle/src/src/typings/sonamu.d.ts +0 -17
  114. package/bundle/src/src/utils/subset-loaders.ts +0 -11
  115. package/bundle/web-dist/client/assets/index-DlPchHBY.js +0 -116
  116. package/bundle/web-dist/client/assets/tokens-DRkXtZ3Q.js +0 -1
  117. package/bundle/web-dist/web-dist/client/assets/index-vZsvyuFn.css +0 -1
  118. package/bundle/web-dist/web-dist/client/assets/rolldown-runtime-Dw2cE7zH.js +0 -1
  119. package/bundle/web-dist/web-dist/client/assets/routes-CagDz23B.js +0 -1
  120. package/bundle/web-dist/web-dist/client/assets/sd.generated-BrQoQXvv.js +0 -47
  121. package/bundle/web-dist/web-dist/client/assets/services.generated-BspO2L0j.js +0 -1
  122. package/bundle/web-dist/web-dist/client/assets/show-aXUGa0gm.js +0 -29
  123. package/bundle/web-dist/web-dist/client/assets/tokens-DRkXtZ3Q.js +0 -1
  124. package/bundle/web-dist/web-dist/client/assets/vendor-react-DH4kUfK2.js +0 -9
  125. package/bundle/web-dist/web-dist/client/assets/vendor-tanstack-CUxlo6YN.js +0 -1
  126. package/bundle/web-dist/web-dist/client/index.html +0 -18
  127. package/bundle/web-dist/web-dist/server/assets/react-dom-CGIzOSuj.js +0 -335
  128. package/bundle/web-dist/web-dist/server/assets/routes-ClzReRep.js +0 -490
  129. package/bundle/web-dist/web-dist/server/assets/sd.generated-BnonqqKr.js +0 -21694
  130. package/bundle/web-dist/web-dist/server/assets/services.generated-D5ABD5fr.js +0 -836
  131. package/bundle/web-dist/web-dist/server/assets/show-C9pcdSxc.js +0 -23364
  132. package/bundle/web-dist/web-dist/server/assets/tokens-JH6FsnWZ.js +0 -860
  133. package/bundle/web-dist/web-dist/server/entry-server.generated.js +0 -44646
@@ -1,2910 +0,0 @@
1
- import { assertTypes, createDefer, createSimpleStackTrace } from "../../../../../@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/helpers.js";
2
- import { processError } from "../../../../../@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/error.js";
3
- import { delay, getSafeTimers } from "../../../../../@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/timers.js";
4
- import { parseSingleStack } from "../../../../../@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/source-map.js";
5
- import { normalize } from "../../../../../pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js";
6
- import "../../../../../pathe@2.0.3/node_modules/pathe/dist/index.js";
7
- import { createChainable, createTaskCollector, getCurrentSuite, getCurrentTest, getFn, getHooks, getNames, getTestName, getTests, matchesTags, updateTask } from "../../../../../@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/chunk-artifact.js";
8
- import "../../../../../@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/index.js";
9
- import "../../../../../@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/utils.js";
10
- import { getWorkerState, isChildProcess, resetModules, waitForImportsToResolve } from "./utils.BX5Fg8C4.js";
11
- import { getBenchFn, getBenchOptions } from "./benchmark.CX_oY03V.js";
12
- import { clearAllMocks, fn, isMockFunction, resetAllMocks, restoreAllMocks, spyOn } from "../../../../../@vitest_spy@4.1.2/node_modules/@vitest/spy/dist/index.js";
13
- import { Assertion, assert as assert$1, expect, should as should$1, use, utils_exports } from "../../../../../chai@6.2.2/node_modules/chai/index.js";
14
- import { ASYMMETRIC_MATCHERS_OBJECT, ChaiStyleAssertions, GLOBAL_EXPECT, JestAsymmetricMatchers, JestChaiExpect, JestExtend, addCustomEqualityTesters, createAssertionMessage, customMatchers, equals, getState, iterableEquality, recordAsyncExpect, setState, subsetEquality, wrapAssertion } from "../../../../../@vitest_expect@4.1.2/node_modules/@vitest/expect/dist/index.js";
15
- import "../../../../../@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/offset.js";
16
- import { SnapshotClient, addSerializer, stripSnapshotIndentation } from "../../../../../@vitest_snapshot@4.1.2/node_modules/@vitest/snapshot/dist/index.js";
17
- import { commonjsGlobal } from "./_commonjsHelpers.D26ty3Ew.js";
18
- import { RealDate, mockDate, resetDate, rpc } from "./rpc.MzXet3jl.js";
19
- //#region ../../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
20
- const unsupported = [
21
- "matchSnapshot",
22
- "toMatchSnapshot",
23
- "toMatchInlineSnapshot",
24
- "toThrowErrorMatchingSnapshot",
25
- "toThrowErrorMatchingInlineSnapshot",
26
- "throws",
27
- "Throw",
28
- "throw",
29
- "toThrow",
30
- "toThrowError"
31
- ];
32
- /**
33
- * Attaches a `cause` property to the error if missing, copies the stack trace from the source, and throws.
34
- *
35
- * @param error - The error to throw
36
- * @param source - Error to copy the stack trace from
37
- *
38
- * @throws Always throws the provided error with an amended stack trace
39
- */
40
- function throwWithCause(error, source) {
41
- if (error.cause == null) error.cause = /* @__PURE__ */ new Error("Matcher did not succeed in time.");
42
- throw copyStackTrace$1(error, source);
43
- }
44
- function createExpectPoll(expect) {
45
- return function poll(fn, options = {}) {
46
- const defaults = getWorkerState().config.expect?.poll ?? {};
47
- const { interval = defaults.interval ?? 50, timeout = defaults.timeout ?? 1e3, message } = options;
48
- const assertion = expect(null, message).withContext({ poll: true });
49
- fn = fn.bind(assertion);
50
- const test = utils_exports.flag(assertion, "vitest-test");
51
- if (!test) throw new Error("expect.poll() must be called inside a test");
52
- const proxy = new Proxy(assertion, { get(target, key, receiver) {
53
- const assertionFunction = Reflect.get(target, key, receiver);
54
- if (typeof assertionFunction !== "function") return assertionFunction instanceof Assertion ? proxy : assertionFunction;
55
- if (key === "assert") return assertionFunction;
56
- if (typeof key === "string" && unsupported.includes(key)) throw new SyntaxError(`expect.poll() is not supported in combination with .${key}(). Use vi.waitFor() if your assertion condition is unstable.`);
57
- return function(...args) {
58
- const STACK_TRACE_ERROR = /* @__PURE__ */ new Error("STACK_TRACE_ERROR");
59
- const promise = async () => {
60
- const { setTimeout, clearTimeout } = getSafeTimers();
61
- let executionPhase = "fn";
62
- let hasTimedOut = false;
63
- const timerId = setTimeout(() => {
64
- hasTimedOut = true;
65
- }, timeout);
66
- utils_exports.flag(assertion, "_name", key);
67
- const onSettled = utils_exports.flag(assertion, "_poll.onSettled");
68
- try {
69
- while (true) {
70
- const isLastAttempt = hasTimedOut;
71
- if (isLastAttempt) utils_exports.flag(assertion, "_isLastPollAttempt", true);
72
- try {
73
- executionPhase = "fn";
74
- const obj = await fn();
75
- utils_exports.flag(assertion, "object", obj);
76
- executionPhase = "assertion";
77
- const output = await assertionFunction.call(assertion, ...args);
78
- await onSettled?.({
79
- assertion,
80
- status: "pass"
81
- });
82
- return output;
83
- } catch (err) {
84
- if (isLastAttempt || executionPhase === "assertion" && utils_exports.flag(assertion, "_poll.assert_once")) {
85
- await onSettled?.({
86
- assertion,
87
- status: "fail"
88
- });
89
- throwWithCause(err, STACK_TRACE_ERROR);
90
- }
91
- await delay(interval, setTimeout);
92
- }
93
- }
94
- } finally {
95
- clearTimeout(timerId);
96
- }
97
- };
98
- let awaited = false;
99
- test.onFinished ??= [];
100
- test.onFinished.push(() => {
101
- if (!awaited) {
102
- const negated = utils_exports.flag(assertion, "negate") ? "not." : "";
103
- const assertionString = `expect.${utils_exports.flag(assertion, "_poll.element") ? "element(locator)" : "poll(assertion)"}.${negated}${String(key)}()`;
104
- throw copyStackTrace$1(/* @__PURE__ */ new Error(`${assertionString} was not awaited. This assertion is asynchronous and must be awaited; otherwise, it is not executed to avoid unhandled rejections:\n\nawait ${assertionString}\n`), STACK_TRACE_ERROR);
105
- }
106
- });
107
- let resultPromise;
108
- return {
109
- then(onFulfilled, onRejected) {
110
- awaited = true;
111
- return (resultPromise ||= promise()).then(onFulfilled, onRejected);
112
- },
113
- catch(onRejected) {
114
- awaited = true;
115
- return (resultPromise ||= promise()).catch(onRejected);
116
- },
117
- finally(onFinally) {
118
- awaited = true;
119
- return (resultPromise ||= promise()).finally(onFinally);
120
- },
121
- [Symbol.toStringTag]: "Promise"
122
- };
123
- };
124
- } });
125
- return proxy;
126
- };
127
- }
128
- function copyStackTrace$1(target, source) {
129
- if (source.stack !== void 0) target.stack = source.stack.replace(source.message, target.message);
130
- return target;
131
- }
132
- let _client;
133
- function getSnapshotClient() {
134
- if (!_client) _client = new SnapshotClient({ isEqual: (received, expected) => {
135
- return equals(received, expected, [iterableEquality, subsetEquality]);
136
- } });
137
- return _client;
138
- }
139
- function getError(expected, promise) {
140
- if (typeof expected !== "function") {
141
- if (!promise) throw new Error(`expected must be a function, received ${typeof expected}`);
142
- return expected;
143
- }
144
- try {
145
- expected();
146
- } catch (e) {
147
- return e;
148
- }
149
- throw new Error("snapshot function didn't throw");
150
- }
151
- function getTestNames(test) {
152
- return {
153
- filepath: test.file.filepath,
154
- name: getNames(test).slice(1).join(" > "),
155
- testId: test.id
156
- };
157
- }
158
- const SnapshotPlugin = (chai, utils) => {
159
- function getTest(assertionName, obj) {
160
- const test = utils.flag(obj, "vitest-test");
161
- if (!test) throw new Error(`'${assertionName}' cannot be used without test context`);
162
- return test;
163
- }
164
- for (const key of ["matchSnapshot", "toMatchSnapshot"]) utils.addMethod(chai.Assertion.prototype, key, wrapAssertion(utils, key, function(properties, message) {
165
- utils.flag(this, "_name", key);
166
- if (utils.flag(this, "negate")) throw new Error(`${key} cannot be used with "not"`);
167
- const expected = utils.flag(this, "object");
168
- const test = getTest(key, this);
169
- if (typeof properties === "string" && typeof message === "undefined") {
170
- message = properties;
171
- properties = void 0;
172
- }
173
- const errorMessage = utils.flag(this, "message");
174
- getSnapshotClient().assert({
175
- received: expected,
176
- message,
177
- isInline: false,
178
- properties,
179
- errorMessage,
180
- ...getTestNames(test)
181
- });
182
- }));
183
- utils.addMethod(chai.Assertion.prototype, "toMatchFileSnapshot", function(file, message) {
184
- utils.flag(this, "_name", "toMatchFileSnapshot");
185
- if (utils.flag(this, "negate")) throw new Error("toMatchFileSnapshot cannot be used with \"not\"");
186
- const error = /* @__PURE__ */ new Error("resolves");
187
- const expected = utils.flag(this, "object");
188
- const test = getTest("toMatchFileSnapshot", this);
189
- const errorMessage = utils.flag(this, "message");
190
- return recordAsyncExpect(test, getSnapshotClient().assertRaw({
191
- received: expected,
192
- message,
193
- isInline: false,
194
- rawSnapshot: { file },
195
- errorMessage,
196
- ...getTestNames(test)
197
- }), createAssertionMessage(utils, this, true), error, utils.flag(this, "soft"));
198
- });
199
- utils.addMethod(chai.Assertion.prototype, "toMatchInlineSnapshot", wrapAssertion(utils, "toMatchInlineSnapshot", function __INLINE_SNAPSHOT_OFFSET_3__(properties, inlineSnapshot, message) {
200
- utils.flag(this, "_name", "toMatchInlineSnapshot");
201
- if (utils.flag(this, "negate")) throw new Error("toMatchInlineSnapshot cannot be used with \"not\"");
202
- const test = getTest("toMatchInlineSnapshot", this);
203
- const expected = utils.flag(this, "object");
204
- const error = utils.flag(this, "error");
205
- if (typeof properties === "string") {
206
- message = inlineSnapshot;
207
- inlineSnapshot = properties;
208
- properties = void 0;
209
- }
210
- if (inlineSnapshot) inlineSnapshot = stripSnapshotIndentation(inlineSnapshot);
211
- const errorMessage = utils.flag(this, "message");
212
- getSnapshotClient().assert({
213
- received: expected,
214
- message,
215
- isInline: true,
216
- properties,
217
- inlineSnapshot,
218
- error,
219
- errorMessage,
220
- ...getTestNames(test)
221
- });
222
- }));
223
- utils.addMethod(chai.Assertion.prototype, "toThrowErrorMatchingSnapshot", wrapAssertion(utils, "toThrowErrorMatchingSnapshot", function(properties, message) {
224
- utils.flag(this, "_name", "toThrowErrorMatchingSnapshot");
225
- if (utils.flag(this, "negate")) throw new Error("toThrowErrorMatchingSnapshot cannot be used with \"not\"");
226
- const expected = utils.flag(this, "object");
227
- const test = getTest("toThrowErrorMatchingSnapshot", this);
228
- const promise = utils.flag(this, "promise");
229
- const errorMessage = utils.flag(this, "message");
230
- getSnapshotClient().assert({
231
- received: getError(expected, promise),
232
- message,
233
- errorMessage,
234
- ...getTestNames(test)
235
- });
236
- }));
237
- utils.addMethod(chai.Assertion.prototype, "toThrowErrorMatchingInlineSnapshot", wrapAssertion(utils, "toThrowErrorMatchingInlineSnapshot", function __INLINE_SNAPSHOT_OFFSET_3__(inlineSnapshot, message) {
238
- if (utils.flag(this, "negate")) throw new Error("toThrowErrorMatchingInlineSnapshot cannot be used with \"not\"");
239
- const test = getTest("toThrowErrorMatchingInlineSnapshot", this);
240
- const expected = utils.flag(this, "object");
241
- const error = utils.flag(this, "error");
242
- const promise = utils.flag(this, "promise");
243
- const errorMessage = utils.flag(this, "message");
244
- if (inlineSnapshot) inlineSnapshot = stripSnapshotIndentation(inlineSnapshot);
245
- getSnapshotClient().assert({
246
- received: getError(expected, promise),
247
- message,
248
- inlineSnapshot,
249
- isInline: true,
250
- error,
251
- errorMessage,
252
- ...getTestNames(test)
253
- });
254
- }));
255
- utils.addMethod(chai.expect, "addSnapshotSerializer", addSerializer);
256
- };
257
- use(JestExtend);
258
- use(JestChaiExpect);
259
- use(ChaiStyleAssertions);
260
- use(SnapshotPlugin);
261
- use(JestAsymmetricMatchers);
262
- function createExpect(test) {
263
- const expect$1 = ((value, message) => {
264
- const { assertionCalls } = getState(expect$1);
265
- setState({ assertionCalls: assertionCalls + 1 }, expect$1);
266
- const assert = expect(value, message);
267
- const _test = test || getCurrentTest();
268
- if (_test) return assert.withTest(_test);
269
- else return assert;
270
- });
271
- Object.assign(expect$1, expect);
272
- Object.assign(expect$1, globalThis[ASYMMETRIC_MATCHERS_OBJECT]);
273
- expect$1.getState = () => getState(expect$1);
274
- expect$1.setState = (state) => setState(state, expect$1);
275
- const globalState = getState(globalThis[GLOBAL_EXPECT]) || {};
276
- setState({
277
- ...globalState,
278
- assertionCalls: 0,
279
- isExpectingAssertions: false,
280
- isExpectingAssertionsError: null,
281
- expectedAssertionsNumber: null,
282
- expectedAssertionsNumberErrorGen: null,
283
- get testPath() {
284
- return getWorkerState().filepath;
285
- },
286
- currentTestName: test ? test.fullTestName ?? "" : globalState.currentTestName
287
- }, expect$1);
288
- expect$1.assert = assert$1;
289
- expect$1.extend = (matchers) => expect.extend(expect$1, matchers);
290
- expect$1.addEqualityTesters = (customTesters) => addCustomEqualityTesters(customTesters);
291
- expect$1.soft = (...args) => {
292
- return expect$1(...args).withContext({ soft: true });
293
- };
294
- expect$1.poll = createExpectPoll(expect$1);
295
- expect$1.unreachable = (message) => {
296
- assert$1.fail(`expected${message ? ` "${message}" ` : " "}not to be reached`);
297
- };
298
- function assertions(expected) {
299
- const errorGen = () => /* @__PURE__ */ new Error(`expected number of assertions to be ${expected}, but got ${expect$1.getState().assertionCalls}`);
300
- if (Error.captureStackTrace) Error.captureStackTrace(errorGen(), assertions);
301
- expect$1.setState({
302
- expectedAssertionsNumber: expected,
303
- expectedAssertionsNumberErrorGen: errorGen
304
- });
305
- }
306
- function hasAssertions() {
307
- const error = /* @__PURE__ */ new Error("expected any number of assertion, but got none");
308
- if (Error.captureStackTrace) Error.captureStackTrace(error, hasAssertions);
309
- expect$1.setState({
310
- isExpectingAssertions: true,
311
- isExpectingAssertionsError: error
312
- });
313
- }
314
- utils_exports.addMethod(expect$1, "assertions", assertions);
315
- utils_exports.addMethod(expect$1, "hasAssertions", hasAssertions);
316
- expect$1.extend(customMatchers);
317
- return expect$1;
318
- }
319
- const globalExpect = createExpect();
320
- Object.defineProperty(globalThis, GLOBAL_EXPECT, {
321
- value: globalExpect,
322
- writable: true,
323
- configurable: true
324
- });
325
- const assert = assert$1;
326
- const should = should$1;
327
- /**
328
- * Gives access to injected context provided from the main thread.
329
- * This usually returns a value provided by `globalSetup` or an external library.
330
- */
331
- function inject(key) {
332
- return getWorkerState().providedContext[key];
333
- }
334
- var fakeTimersSrc = {};
335
- var global;
336
- var hasRequiredGlobal;
337
- function requireGlobal() {
338
- if (hasRequiredGlobal) return global;
339
- hasRequiredGlobal = 1;
340
- /**
341
- * A reference to the global object
342
- * @type {object} globalObject
343
- */
344
- var globalObject;
345
- /* istanbul ignore else */
346
- if (typeof commonjsGlobal !== "undefined") globalObject = commonjsGlobal;
347
- else if (typeof window !== "undefined") globalObject = window;
348
- else globalObject = self;
349
- global = globalObject;
350
- return global;
351
- }
352
- var throwsOnProto_1;
353
- var hasRequiredThrowsOnProto;
354
- function requireThrowsOnProto() {
355
- if (hasRequiredThrowsOnProto) return throwsOnProto_1;
356
- hasRequiredThrowsOnProto = 1;
357
- /**
358
- * Is true when the environment causes an error to be thrown for accessing the
359
- * __proto__ property.
360
- * This is necessary in order to support `node --disable-proto=throw`.
361
- *
362
- * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto
363
- * @type {boolean}
364
- */
365
- let throwsOnProto;
366
- try {
367
- ({}).__proto__;
368
- throwsOnProto = false;
369
- } catch (_) {
370
- /* istanbul ignore next */
371
- throwsOnProto = true;
372
- }
373
- throwsOnProto_1 = throwsOnProto;
374
- return throwsOnProto_1;
375
- }
376
- var copyPrototypeMethods;
377
- var hasRequiredCopyPrototypeMethods;
378
- function requireCopyPrototypeMethods() {
379
- if (hasRequiredCopyPrototypeMethods) return copyPrototypeMethods;
380
- hasRequiredCopyPrototypeMethods = 1;
381
- var call = Function.call;
382
- var throwsOnProto = requireThrowsOnProto();
383
- var disallowedProperties = [
384
- "size",
385
- "caller",
386
- "callee",
387
- "arguments"
388
- ];
389
- /* istanbul ignore next */
390
- if (throwsOnProto) disallowedProperties.push("__proto__");
391
- copyPrototypeMethods = function copyPrototypeMethods(prototype) {
392
- return Object.getOwnPropertyNames(prototype).reduce(function(result, name) {
393
- if (disallowedProperties.includes(name)) return result;
394
- if (typeof prototype[name] !== "function") return result;
395
- result[name] = call.bind(prototype[name]);
396
- return result;
397
- }, Object.create(null));
398
- };
399
- return copyPrototypeMethods;
400
- }
401
- var array;
402
- var hasRequiredArray;
403
- function requireArray() {
404
- if (hasRequiredArray) return array;
405
- hasRequiredArray = 1;
406
- array = requireCopyPrototypeMethods()(Array.prototype);
407
- return array;
408
- }
409
- var calledInOrder_1;
410
- var hasRequiredCalledInOrder;
411
- function requireCalledInOrder() {
412
- if (hasRequiredCalledInOrder) return calledInOrder_1;
413
- hasRequiredCalledInOrder = 1;
414
- var every = requireArray().every;
415
- /**
416
- * @private
417
- */
418
- function hasCallsLeft(callMap, spy) {
419
- if (callMap[spy.id] === void 0) callMap[spy.id] = 0;
420
- return callMap[spy.id] < spy.callCount;
421
- }
422
- /**
423
- * @private
424
- */
425
- function checkAdjacentCalls(callMap, spy, index, spies) {
426
- var calledBeforeNext = true;
427
- if (index !== spies.length - 1) calledBeforeNext = spy.calledBefore(spies[index + 1]);
428
- if (hasCallsLeft(callMap, spy) && calledBeforeNext) {
429
- callMap[spy.id] += 1;
430
- return true;
431
- }
432
- return false;
433
- }
434
- /**
435
- * A Sinon proxy object (fake, spy, stub)
436
- * @typedef {object} SinonProxy
437
- * @property {Function} calledBefore - A method that determines if this proxy was called before another one
438
- * @property {string} id - Some id
439
- * @property {number} callCount - Number of times this proxy has been called
440
- */
441
- /**
442
- * Returns true when the spies have been called in the order they were supplied in
443
- * @param {SinonProxy[] | SinonProxy} spies An array of proxies, or several proxies as arguments
444
- * @returns {boolean} true when spies are called in order, false otherwise
445
- */
446
- function calledInOrder(spies) {
447
- return every(arguments.length > 1 ? arguments : spies, checkAdjacentCalls.bind(null, {}));
448
- }
449
- calledInOrder_1 = calledInOrder;
450
- return calledInOrder_1;
451
- }
452
- var className_1;
453
- var hasRequiredClassName;
454
- function requireClassName() {
455
- if (hasRequiredClassName) return className_1;
456
- hasRequiredClassName = 1;
457
- /**
458
- * Returns a display name for a value from a constructor
459
- * @param {object} value A value to examine
460
- * @returns {(string|null)} A string or null
461
- */
462
- function className(value) {
463
- return value.constructor && value.constructor.name || null;
464
- }
465
- className_1 = className;
466
- return className_1;
467
- }
468
- var deprecated = {};
469
- var hasRequiredDeprecated;
470
- function requireDeprecated() {
471
- if (hasRequiredDeprecated) return deprecated;
472
- hasRequiredDeprecated = 1;
473
- (function(exports$1) {
474
- /**
475
- * Returns a function that will invoke the supplied function and print a
476
- * deprecation warning to the console each time it is called.
477
- * @param {Function} func
478
- * @param {string} msg
479
- * @returns {Function}
480
- */
481
- exports$1.wrap = function(func, msg) {
482
- var wrapped = function() {
483
- exports$1.printWarning(msg);
484
- return func.apply(this, arguments);
485
- };
486
- if (func.prototype) wrapped.prototype = func.prototype;
487
- return wrapped;
488
- };
489
- /**
490
- * Returns a string which can be supplied to `wrap()` to notify the user that a
491
- * particular part of the sinon API has been deprecated.
492
- * @param {string} packageName
493
- * @param {string} funcName
494
- * @returns {string}
495
- */
496
- exports$1.defaultMsg = function(packageName, funcName) {
497
- return `${packageName}.${funcName} is deprecated and will be removed from the public API in a future version of ${packageName}.`;
498
- };
499
- /**
500
- * Prints a warning on the console, when it exists
501
- * @param {string} msg
502
- * @returns {undefined}
503
- */
504
- exports$1.printWarning = function(msg) {
505
- /* istanbul ignore next */
506
- if (typeof process === "object" && process.emitWarning) process.emitWarning(msg);
507
- else if (console.info) console.info(msg);
508
- else console.log(msg);
509
- };
510
- })(deprecated);
511
- return deprecated;
512
- }
513
- var every;
514
- var hasRequiredEvery;
515
- function requireEvery() {
516
- if (hasRequiredEvery) return every;
517
- hasRequiredEvery = 1;
518
- /**
519
- * Returns true when fn returns true for all members of obj.
520
- * This is an every implementation that works for all iterables
521
- * @param {object} obj
522
- * @param {Function} fn
523
- * @returns {boolean}
524
- */
525
- every = function every(obj, fn) {
526
- var pass = true;
527
- try {
528
- obj.forEach(function() {
529
- if (!fn.apply(this, arguments)) throw new Error();
530
- });
531
- } catch (e) {
532
- pass = false;
533
- }
534
- return pass;
535
- };
536
- return every;
537
- }
538
- var functionName;
539
- var hasRequiredFunctionName;
540
- function requireFunctionName() {
541
- if (hasRequiredFunctionName) return functionName;
542
- hasRequiredFunctionName = 1;
543
- /**
544
- * Returns a display name for a function
545
- * @param {Function} func
546
- * @returns {string}
547
- */
548
- functionName = function functionName(func) {
549
- if (!func) return "";
550
- try {
551
- return func.displayName || func.name || (String(func).match(/function ([^\s(]+)/) || [])[1];
552
- } catch (e) {
553
- return "";
554
- }
555
- };
556
- return functionName;
557
- }
558
- var orderByFirstCall_1;
559
- var hasRequiredOrderByFirstCall;
560
- function requireOrderByFirstCall() {
561
- if (hasRequiredOrderByFirstCall) return orderByFirstCall_1;
562
- hasRequiredOrderByFirstCall = 1;
563
- var sort = requireArray().sort;
564
- var slice = requireArray().slice;
565
- /**
566
- * @private
567
- */
568
- function comparator(a, b) {
569
- var aCall = a.getCall(0);
570
- var bCall = b.getCall(0);
571
- return (aCall && aCall.callId || -1) < (bCall && bCall.callId || -1) ? -1 : 1;
572
- }
573
- /**
574
- * A Sinon proxy object (fake, spy, stub)
575
- * @typedef {object} SinonProxy
576
- * @property {Function} getCall - A method that can return the first call
577
- */
578
- /**
579
- * Sorts an array of SinonProxy instances (fake, spy, stub) by their first call
580
- * @param {SinonProxy[] | SinonProxy} spies
581
- * @returns {SinonProxy[]}
582
- */
583
- function orderByFirstCall(spies) {
584
- return sort(slice(spies), comparator);
585
- }
586
- orderByFirstCall_1 = orderByFirstCall;
587
- return orderByFirstCall_1;
588
- }
589
- var _function;
590
- var hasRequired_function;
591
- function require_function() {
592
- if (hasRequired_function) return _function;
593
- hasRequired_function = 1;
594
- _function = requireCopyPrototypeMethods()(Function.prototype);
595
- return _function;
596
- }
597
- var map;
598
- var hasRequiredMap;
599
- function requireMap() {
600
- if (hasRequiredMap) return map;
601
- hasRequiredMap = 1;
602
- map = requireCopyPrototypeMethods()(Map.prototype);
603
- return map;
604
- }
605
- var object;
606
- var hasRequiredObject;
607
- function requireObject() {
608
- if (hasRequiredObject) return object;
609
- hasRequiredObject = 1;
610
- object = requireCopyPrototypeMethods()(Object.prototype);
611
- return object;
612
- }
613
- var set;
614
- var hasRequiredSet;
615
- function requireSet() {
616
- if (hasRequiredSet) return set;
617
- hasRequiredSet = 1;
618
- set = requireCopyPrototypeMethods()(Set.prototype);
619
- return set;
620
- }
621
- var string;
622
- var hasRequiredString;
623
- function requireString() {
624
- if (hasRequiredString) return string;
625
- hasRequiredString = 1;
626
- string = requireCopyPrototypeMethods()(String.prototype);
627
- return string;
628
- }
629
- var prototypes;
630
- var hasRequiredPrototypes;
631
- function requirePrototypes() {
632
- if (hasRequiredPrototypes) return prototypes;
633
- hasRequiredPrototypes = 1;
634
- prototypes = {
635
- array: requireArray(),
636
- function: require_function(),
637
- map: requireMap(),
638
- object: requireObject(),
639
- set: requireSet(),
640
- string: requireString()
641
- };
642
- return prototypes;
643
- }
644
- var typeDetect$1 = { exports: {} };
645
- var typeDetect = typeDetect$1.exports;
646
- var hasRequiredTypeDetect;
647
- function requireTypeDetect() {
648
- if (hasRequiredTypeDetect) return typeDetect$1.exports;
649
- hasRequiredTypeDetect = 1;
650
- (function(module, exports$1) {
651
- (function(global, factory) {
652
- module.exports = factory();
653
- })(typeDetect, (function() {
654
- var promiseExists = typeof Promise === "function";
655
- var globalObject = typeof self === "object" ? self : commonjsGlobal;
656
- var symbolExists = typeof Symbol !== "undefined";
657
- var mapExists = typeof Map !== "undefined";
658
- var setExists = typeof Set !== "undefined";
659
- var weakMapExists = typeof WeakMap !== "undefined";
660
- var weakSetExists = typeof WeakSet !== "undefined";
661
- var dataViewExists = typeof DataView !== "undefined";
662
- var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== "undefined";
663
- var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== "undefined";
664
- var setEntriesExists = setExists && typeof Set.prototype.entries === "function";
665
- var mapEntriesExists = mapExists && typeof Map.prototype.entries === "function";
666
- var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf((/* @__PURE__ */ new Set()).entries());
667
- var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf((/* @__PURE__ */ new Map()).entries());
668
- var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === "function";
669
- var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]());
670
- var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === "function";
671
- var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(""[Symbol.iterator]());
672
- var toStringLeftSliceLength = 8;
673
- var toStringRightSliceLength = -1;
674
- /**
675
- * ### typeOf (obj)
676
- *
677
- * Uses `Object.prototype.toString` to determine the type of an object,
678
- * normalising behaviour across engine versions & well optimised.
679
- *
680
- * @param {Mixed} object
681
- * @return {String} object type
682
- * @api public
683
- */
684
- function typeDetect(obj) {
685
- var typeofObj = typeof obj;
686
- if (typeofObj !== "object") return typeofObj;
687
- if (obj === null) return "null";
688
- if (obj === globalObject) return "global";
689
- if (Array.isArray(obj) && (symbolToStringTagExists === false || !(Symbol.toStringTag in obj))) return "Array";
690
- if (typeof window === "object" && window !== null) {
691
- if (typeof window.location === "object" && obj === window.location) return "Location";
692
- if (typeof window.document === "object" && obj === window.document) return "Document";
693
- if (typeof window.navigator === "object") {
694
- if (typeof window.navigator.mimeTypes === "object" && obj === window.navigator.mimeTypes) return "MimeTypeArray";
695
- if (typeof window.navigator.plugins === "object" && obj === window.navigator.plugins) return "PluginArray";
696
- }
697
- if ((typeof window.HTMLElement === "function" || typeof window.HTMLElement === "object") && obj instanceof window.HTMLElement) {
698
- if (obj.tagName === "BLOCKQUOTE") return "HTMLQuoteElement";
699
- if (obj.tagName === "TD") return "HTMLTableDataCellElement";
700
- if (obj.tagName === "TH") return "HTMLTableHeaderCellElement";
701
- }
702
- }
703
- var stringTag = symbolToStringTagExists && obj[Symbol.toStringTag];
704
- if (typeof stringTag === "string") return stringTag;
705
- var objPrototype = Object.getPrototypeOf(obj);
706
- if (objPrototype === RegExp.prototype) return "RegExp";
707
- if (objPrototype === Date.prototype) return "Date";
708
- if (promiseExists && objPrototype === Promise.prototype) return "Promise";
709
- if (setExists && objPrototype === Set.prototype) return "Set";
710
- if (mapExists && objPrototype === Map.prototype) return "Map";
711
- if (weakSetExists && objPrototype === WeakSet.prototype) return "WeakSet";
712
- if (weakMapExists && objPrototype === WeakMap.prototype) return "WeakMap";
713
- if (dataViewExists && objPrototype === DataView.prototype) return "DataView";
714
- if (mapExists && objPrototype === mapIteratorPrototype) return "Map Iterator";
715
- if (setExists && objPrototype === setIteratorPrototype) return "Set Iterator";
716
- if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) return "Array Iterator";
717
- if (stringIteratorExists && objPrototype === stringIteratorPrototype) return "String Iterator";
718
- if (objPrototype === null) return "Object";
719
- return Object.prototype.toString.call(obj).slice(toStringLeftSliceLength, toStringRightSliceLength);
720
- }
721
- return typeDetect;
722
- }));
723
- })(typeDetect$1);
724
- return typeDetect$1.exports;
725
- }
726
- var typeOf;
727
- var hasRequiredTypeOf;
728
- function requireTypeOf() {
729
- if (hasRequiredTypeOf) return typeOf;
730
- hasRequiredTypeOf = 1;
731
- var type = requireTypeDetect();
732
- /**
733
- * Returns the lower-case result of running type from type-detect on the value
734
- * @param {*} value
735
- * @returns {string}
736
- */
737
- typeOf = function typeOf(value) {
738
- return type(value).toLowerCase();
739
- };
740
- return typeOf;
741
- }
742
- var valueToString_1;
743
- var hasRequiredValueToString;
744
- function requireValueToString() {
745
- if (hasRequiredValueToString) return valueToString_1;
746
- hasRequiredValueToString = 1;
747
- /**
748
- * Returns a string representation of the value
749
- * @param {*} value
750
- * @returns {string}
751
- */
752
- function valueToString(value) {
753
- if (value && value.toString) return value.toString();
754
- return String(value);
755
- }
756
- valueToString_1 = valueToString;
757
- return valueToString_1;
758
- }
759
- var lib;
760
- var hasRequiredLib;
761
- function requireLib() {
762
- if (hasRequiredLib) return lib;
763
- hasRequiredLib = 1;
764
- lib = {
765
- global: requireGlobal(),
766
- calledInOrder: requireCalledInOrder(),
767
- className: requireClassName(),
768
- deprecated: requireDeprecated(),
769
- every: requireEvery(),
770
- functionName: requireFunctionName(),
771
- orderByFirstCall: requireOrderByFirstCall(),
772
- prototypes: requirePrototypes(),
773
- typeOf: requireTypeOf(),
774
- valueToString: requireValueToString()
775
- };
776
- return lib;
777
- }
778
- var hasRequiredFakeTimersSrc;
779
- function requireFakeTimersSrc() {
780
- if (hasRequiredFakeTimersSrc) return fakeTimersSrc;
781
- hasRequiredFakeTimersSrc = 1;
782
- const globalObject = requireLib().global;
783
- let timersModule, timersPromisesModule;
784
- if (typeof __vitest_required__ !== "undefined") {
785
- try {
786
- timersModule = __vitest_required__.timers;
787
- } catch (e) {}
788
- try {
789
- timersPromisesModule = __vitest_required__.timersPromises;
790
- } catch (e) {}
791
- }
792
- /**
793
- * @typedef {"nextAsync" | "manual" | "interval"} TickMode
794
- */
795
- /**
796
- * @typedef {object} NextAsyncTickMode
797
- * @property {"nextAsync"} mode
798
- */
799
- /**
800
- * @typedef {object} ManualTickMode
801
- * @property {"manual"} mode
802
- */
803
- /**
804
- * @typedef {object} IntervalTickMode
805
- * @property {"interval"} mode
806
- * @property {number} [delta]
807
- */
808
- /**
809
- * @typedef {IntervalTickMode | NextAsyncTickMode | ManualTickMode} TimerTickMode
810
- */
811
- /**
812
- * @typedef {object} IdleDeadline
813
- * @property {boolean} didTimeout - whether or not the callback was called before reaching the optional timeout
814
- * @property {function():number} timeRemaining - a floating-point value providing an estimate of the number of milliseconds remaining in the current idle period
815
- */
816
- /**
817
- * Queues a function to be called during a browser's idle periods
818
- * @callback RequestIdleCallback
819
- * @param {function(IdleDeadline)} callback
820
- * @param {{timeout: number}} options - an options object
821
- * @returns {number} the id
822
- */
823
- /**
824
- * @callback NextTick
825
- * @param {VoidVarArgsFunc} callback - the callback to run
826
- * @param {...*} args - optional arguments to call the callback with
827
- * @returns {void}
828
- */
829
- /**
830
- * @callback SetImmediate
831
- * @param {VoidVarArgsFunc} callback - the callback to run
832
- * @param {...*} args - optional arguments to call the callback with
833
- * @returns {NodeImmediate}
834
- */
835
- /**
836
- * @callback VoidVarArgsFunc
837
- * @param {...*} callback - the callback to run
838
- * @returns {void}
839
- */
840
- /**
841
- * @typedef RequestAnimationFrame
842
- * @property {function(number):void} requestAnimationFrame
843
- * @returns {number} - the id
844
- */
845
- /**
846
- * @typedef Performance
847
- * @property {function(): number} now
848
- */
849
- /**
850
- * @typedef {object} Clock
851
- * @property {number} now - the current time
852
- * @property {Date} Date - the Date constructor
853
- * @property {number} loopLimit - the maximum number of timers before assuming an infinite loop
854
- * @property {RequestIdleCallback} requestIdleCallback
855
- * @property {function(number):void} cancelIdleCallback
856
- * @property {setTimeout} setTimeout
857
- * @property {clearTimeout} clearTimeout
858
- * @property {NextTick} nextTick
859
- * @property {queueMicrotask} queueMicrotask
860
- * @property {setInterval} setInterval
861
- * @property {clearInterval} clearInterval
862
- * @property {SetImmediate} setImmediate
863
- * @property {function(NodeImmediate):void} clearImmediate
864
- * @property {function():number} countTimers
865
- * @property {RequestAnimationFrame} requestAnimationFrame
866
- * @property {function(number):void} cancelAnimationFrame
867
- * @property {function():void} runMicrotasks
868
- * @property {function(string | number): number} tick
869
- * @property {function(string | number): Promise<number>} tickAsync
870
- * @property {function(): number} next
871
- * @property {function(): Promise<number>} nextAsync
872
- * @property {function(): number} runAll
873
- * @property {function(): number} runToFrame
874
- * @property {function(): Promise<number>} runAllAsync
875
- * @property {function(): number} runToLast
876
- * @property {function(): Promise<number>} runToLastAsync
877
- * @property {function(): void} reset
878
- * @property {function(number | Date): void} setSystemTime
879
- * @property {function(number): void} jump
880
- * @property {Performance} performance
881
- * @property {function(number[]): number[]} hrtime - process.hrtime (legacy)
882
- * @property {function(): void} uninstall Uninstall the clock.
883
- * @property {Function[]} methods - the methods that are faked
884
- * @property {boolean} [shouldClearNativeTimers] inherited from config
885
- * @property {{methodName:string, original:any}[] | undefined} timersModuleMethods
886
- * @property {{methodName:string, original:any}[] | undefined} timersPromisesModuleMethods
887
- * @property {Map<function(): void, AbortSignal>} abortListenerMap
888
- * @property {function(TimerTickMode): void} setTickMode
889
- */
890
- /**
891
- * Configuration object for the `install` method.
892
- * @typedef {object} Config
893
- * @property {number|Date} [now] a number (in milliseconds) or a Date object (default epoch)
894
- * @property {string[]} [toFake] names of the methods that should be faked.
895
- * @property {number} [loopLimit] the maximum number of timers that will be run when calling runAll()
896
- * @property {boolean} [shouldAdvanceTime] tells FakeTimers to increment mocked time automatically (default false)
897
- * @property {number} [advanceTimeDelta] increment mocked time every <<advanceTimeDelta>> ms (default: 20ms)
898
- * @property {boolean} [shouldClearNativeTimers] forwards clear timer calls to native functions if they are not fakes (default: false)
899
- * @property {boolean} [ignoreMissingTimers] default is false, meaning asking to fake timers that are not present will throw an error
900
- */
901
- /**
902
- * The internal structure to describe a scheduled fake timer
903
- * @typedef {object} Timer
904
- * @property {Function} func
905
- * @property {*[]} args
906
- * @property {number} delay
907
- * @property {number} callAt
908
- * @property {number} createdAt
909
- * @property {boolean} immediate
910
- * @property {number} id
911
- * @property {Error} [error]
912
- */
913
- /**
914
- * A Node timer
915
- * @typedef {object} NodeImmediate
916
- * @property {function(): boolean} hasRef
917
- * @property {function(): NodeImmediate} ref
918
- * @property {function(): NodeImmediate} unref
919
- */
920
- /**
921
- * Mocks available features in the specified global namespace.
922
- * @param {*} _global Namespace to mock (e.g. `window`)
923
- * @returns {FakeTimers}
924
- */
925
- function withGlobal(_global) {
926
- const maxTimeout = Math.pow(2, 31) - 1;
927
- const idCounterStart = 0xe8d4a51000;
928
- const NOOP = function() {};
929
- const NOOP_ARRAY = function() {
930
- return [];
931
- };
932
- const isPresent = {};
933
- let timeoutResult, addTimerReturnsObject = false;
934
- if (_global.setTimeout) {
935
- isPresent.setTimeout = true;
936
- timeoutResult = _global.setTimeout(NOOP, 0);
937
- addTimerReturnsObject = typeof timeoutResult === "object";
938
- }
939
- isPresent.clearTimeout = Boolean(_global.clearTimeout);
940
- isPresent.setInterval = Boolean(_global.setInterval);
941
- isPresent.clearInterval = Boolean(_global.clearInterval);
942
- isPresent.hrtime = _global.process && typeof _global.process.hrtime === "function";
943
- isPresent.hrtimeBigint = isPresent.hrtime && typeof _global.process.hrtime.bigint === "function";
944
- isPresent.nextTick = _global.process && typeof _global.process.nextTick === "function";
945
- const utilPromisify = _global.process && _global.__vitest_required__ && _global.__vitest_required__.util.promisify;
946
- isPresent.performance = _global.performance && typeof _global.performance.now === "function";
947
- const hasPerformancePrototype = _global.Performance && (typeof _global.Performance).match(/^(function|object)$/);
948
- const hasPerformanceConstructorPrototype = _global.performance && _global.performance.constructor && _global.performance.constructor.prototype;
949
- isPresent.queueMicrotask = _global.hasOwnProperty("queueMicrotask");
950
- isPresent.requestAnimationFrame = _global.requestAnimationFrame && typeof _global.requestAnimationFrame === "function";
951
- isPresent.cancelAnimationFrame = _global.cancelAnimationFrame && typeof _global.cancelAnimationFrame === "function";
952
- isPresent.requestIdleCallback = _global.requestIdleCallback && typeof _global.requestIdleCallback === "function";
953
- isPresent.cancelIdleCallbackPresent = _global.cancelIdleCallback && typeof _global.cancelIdleCallback === "function";
954
- isPresent.setImmediate = _global.setImmediate && typeof _global.setImmediate === "function";
955
- isPresent.clearImmediate = _global.clearImmediate && typeof _global.clearImmediate === "function";
956
- isPresent.Intl = _global.Intl && typeof _global.Intl === "object";
957
- if (_global.clearTimeout) _global.clearTimeout(timeoutResult);
958
- const NativeDate = _global.Date;
959
- const NativeIntl = isPresent.Intl ? Object.defineProperties(Object.create(null), Object.getOwnPropertyDescriptors(_global.Intl)) : void 0;
960
- let uniqueTimerId = idCounterStart;
961
- if (NativeDate === void 0) throw new Error("The global scope doesn't have a `Date` object (see https://github.com/sinonjs/sinon/issues/1852#issuecomment-419622780)");
962
- isPresent.Date = true;
963
- /**
964
- * The PerformanceEntry object encapsulates a single performance metric
965
- * that is part of the browser's performance timeline.
966
- *
967
- * This is an object returned by the `mark` and `measure` methods on the Performance prototype
968
- */
969
- class FakePerformanceEntry {
970
- constructor(name, entryType, startTime, duration) {
971
- this.name = name;
972
- this.entryType = entryType;
973
- this.startTime = startTime;
974
- this.duration = duration;
975
- }
976
- toJSON() {
977
- return JSON.stringify({ ...this });
978
- }
979
- }
980
- /**
981
- * @param {number} num
982
- * @returns {boolean}
983
- */
984
- function isNumberFinite(num) {
985
- if (Number.isFinite) return Number.isFinite(num);
986
- return isFinite(num);
987
- }
988
- let isNearInfiniteLimit = false;
989
- /**
990
- * @param {Clock} clock
991
- * @param {number} i
992
- */
993
- function checkIsNearInfiniteLimit(clock, i) {
994
- if (clock.loopLimit && i === clock.loopLimit - 1) isNearInfiniteLimit = true;
995
- }
996
- /**
997
- *
998
- */
999
- function resetIsNearInfiniteLimit() {
1000
- isNearInfiniteLimit = false;
1001
- }
1002
- /**
1003
- * Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into
1004
- * number of milliseconds. This is used to support human-readable strings passed
1005
- * to clock.tick()
1006
- * @param {string} str
1007
- * @returns {number}
1008
- */
1009
- function parseTime(str) {
1010
- if (!str) return 0;
1011
- const strings = str.split(":");
1012
- const l = strings.length;
1013
- let i = l;
1014
- let ms = 0;
1015
- let parsed;
1016
- if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) throw new Error("tick only understands numbers, 'm:s' and 'h:m:s'. Each part must be two digits");
1017
- while (i--) {
1018
- parsed = parseInt(strings[i], 10);
1019
- if (parsed >= 60) throw new Error(`Invalid time ${str}`);
1020
- ms += parsed * Math.pow(60, l - i - 1);
1021
- }
1022
- return ms * 1e3;
1023
- }
1024
- /**
1025
- * Get the decimal part of the millisecond value as nanoseconds
1026
- * @param {number} msFloat the number of milliseconds
1027
- * @returns {number} an integer number of nanoseconds in the range [0,1e6)
1028
- *
1029
- * Example: nanoRemainer(123.456789) -> 456789
1030
- */
1031
- function nanoRemainder(msFloat) {
1032
- const modulo = 1e6;
1033
- const remainder = msFloat * 1e6 % modulo;
1034
- const positiveRemainder = remainder < 0 ? remainder + modulo : remainder;
1035
- return Math.floor(positiveRemainder);
1036
- }
1037
- /**
1038
- * Used to grok the `now` parameter to createClock.
1039
- * @param {Date|number} epoch the system time
1040
- * @returns {number}
1041
- */
1042
- function getEpoch(epoch) {
1043
- if (!epoch) return 0;
1044
- if (typeof epoch.getTime === "function") return epoch.getTime();
1045
- if (typeof epoch === "number") return epoch;
1046
- throw new TypeError("now should be milliseconds since UNIX epoch");
1047
- }
1048
- /**
1049
- * @param {number} from
1050
- * @param {number} to
1051
- * @param {Timer} timer
1052
- * @returns {boolean}
1053
- */
1054
- function inRange(from, to, timer) {
1055
- return timer && timer.callAt >= from && timer.callAt <= to;
1056
- }
1057
- /**
1058
- * @param {Clock} clock
1059
- * @param {Timer} job
1060
- */
1061
- function getInfiniteLoopError(clock, job) {
1062
- const infiniteLoopError = /* @__PURE__ */ new Error(`Aborting after running ${clock.loopLimit} timers, assuming an infinite loop!`);
1063
- if (!job.error) return infiniteLoopError;
1064
- const computedTargetPattern = /target\.*[<|(|[].*?[>|\]|)]\s*/;
1065
- let clockMethodPattern = new RegExp(String(Object.keys(clock).join("|")));
1066
- if (addTimerReturnsObject) clockMethodPattern = new RegExp(`\\s+at (Object\\.)?(?:${Object.keys(clock).join("|")})\\s+`);
1067
- let matchedLineIndex = -1;
1068
- job.error.stack.split("\n").some(function(line, i) {
1069
- /* istanbul ignore if */
1070
- if (line.match(computedTargetPattern)) {
1071
- matchedLineIndex = i;
1072
- return true;
1073
- }
1074
- if (line.match(clockMethodPattern)) {
1075
- matchedLineIndex = i;
1076
- return false;
1077
- }
1078
- return matchedLineIndex >= 0;
1079
- });
1080
- const stack = `${infiniteLoopError}\n${job.type || "Microtask"} - ${job.func.name || "anonymous"}\n${job.error.stack.split("\n").slice(matchedLineIndex + 1).join("\n")}`;
1081
- try {
1082
- Object.defineProperty(infiniteLoopError, "stack", { value: stack });
1083
- } catch (e) {}
1084
- return infiniteLoopError;
1085
- }
1086
- function createDate() {
1087
- class ClockDate extends NativeDate {
1088
- /**
1089
- * @param {number} year
1090
- * @param {number} month
1091
- * @param {number} date
1092
- * @param {number} hour
1093
- * @param {number} minute
1094
- * @param {number} second
1095
- * @param {number} ms
1096
- * @returns void
1097
- */
1098
- constructor(year, month, date, hour, minute, second, ms) {
1099
- if (arguments.length === 0) super(ClockDate.clock.now);
1100
- else super(...arguments);
1101
- Object.defineProperty(this, "constructor", {
1102
- value: NativeDate,
1103
- enumerable: false
1104
- });
1105
- }
1106
- static [Symbol.hasInstance](instance) {
1107
- return instance instanceof NativeDate;
1108
- }
1109
- }
1110
- ClockDate.isFake = true;
1111
- if (NativeDate.now) ClockDate.now = function now() {
1112
- return ClockDate.clock.now;
1113
- };
1114
- if (NativeDate.toSource) ClockDate.toSource = function toSource() {
1115
- return NativeDate.toSource();
1116
- };
1117
- ClockDate.toString = function toString() {
1118
- return NativeDate.toString();
1119
- };
1120
- return new Proxy(ClockDate, { apply() {
1121
- if (this instanceof ClockDate) throw new TypeError("A Proxy should only capture `new` calls with the `construct` handler. This is not supposed to be possible, so check the logic.");
1122
- return new NativeDate(ClockDate.clock.now).toString();
1123
- } });
1124
- }
1125
- /**
1126
- * Mirror Intl by default on our fake implementation
1127
- *
1128
- * Most of the properties are the original native ones,
1129
- * but we need to take control of those that have a
1130
- * dependency on the current clock.
1131
- * @returns {object} the partly fake Intl implementation
1132
- */
1133
- function createIntl() {
1134
- const ClockIntl = {};
1135
- Object.getOwnPropertyNames(NativeIntl).forEach((property) => ClockIntl[property] = NativeIntl[property]);
1136
- ClockIntl.DateTimeFormat = function(...args) {
1137
- const realFormatter = new NativeIntl.DateTimeFormat(...args);
1138
- const formatter = {};
1139
- [
1140
- "formatRange",
1141
- "formatRangeToParts",
1142
- "resolvedOptions"
1143
- ].forEach((method) => {
1144
- formatter[method] = realFormatter[method].bind(realFormatter);
1145
- });
1146
- ["format", "formatToParts"].forEach((method) => {
1147
- formatter[method] = function(date) {
1148
- return realFormatter[method](date || ClockIntl.clock.now);
1149
- };
1150
- });
1151
- return formatter;
1152
- };
1153
- ClockIntl.DateTimeFormat.prototype = Object.create(NativeIntl.DateTimeFormat.prototype);
1154
- ClockIntl.DateTimeFormat.supportedLocalesOf = NativeIntl.DateTimeFormat.supportedLocalesOf;
1155
- return ClockIntl;
1156
- }
1157
- function enqueueJob(clock, job) {
1158
- if (!clock.jobs) clock.jobs = [];
1159
- clock.jobs.push(job);
1160
- }
1161
- function runJobs(clock) {
1162
- if (!clock.jobs) return;
1163
- for (let i = 0; i < clock.jobs.length; i++) {
1164
- const job = clock.jobs[i];
1165
- job.func.apply(null, job.args);
1166
- checkIsNearInfiniteLimit(clock, i);
1167
- if (clock.loopLimit && i > clock.loopLimit) throw getInfiniteLoopError(clock, job);
1168
- }
1169
- resetIsNearInfiniteLimit();
1170
- clock.jobs = [];
1171
- }
1172
- /**
1173
- * @param {Clock} clock
1174
- * @param {Timer} timer
1175
- * @returns {number} id of the created timer
1176
- */
1177
- function addTimer(clock, timer) {
1178
- if (timer.func === void 0) throw new Error("Callback must be provided to timer calls");
1179
- if (addTimerReturnsObject) {
1180
- if (typeof timer.func !== "function") throw new TypeError(`[ERR_INVALID_CALLBACK]: Callback must be a function. Received ${timer.func} of type ${typeof timer.func}`);
1181
- }
1182
- if (isNearInfiniteLimit) timer.error = /* @__PURE__ */ new Error();
1183
- timer.type = timer.immediate ? "Immediate" : "Timeout";
1184
- if (timer.hasOwnProperty("delay")) {
1185
- if (typeof timer.delay !== "number") timer.delay = parseInt(timer.delay, 10);
1186
- if (!isNumberFinite(timer.delay)) timer.delay = 0;
1187
- timer.delay = timer.delay > maxTimeout ? 1 : timer.delay;
1188
- timer.delay = Math.max(0, timer.delay);
1189
- }
1190
- if (timer.hasOwnProperty("interval")) {
1191
- timer.type = "Interval";
1192
- timer.interval = timer.interval > maxTimeout ? 1 : timer.interval;
1193
- }
1194
- if (timer.hasOwnProperty("animation")) {
1195
- timer.type = "AnimationFrame";
1196
- timer.animation = true;
1197
- }
1198
- if (timer.hasOwnProperty("idleCallback")) {
1199
- timer.type = "IdleCallback";
1200
- timer.idleCallback = true;
1201
- }
1202
- if (!clock.timers) clock.timers = {};
1203
- timer.id = uniqueTimerId++;
1204
- timer.createdAt = clock.now;
1205
- timer.callAt = clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0));
1206
- clock.timers[timer.id] = timer;
1207
- if (addTimerReturnsObject) {
1208
- const res = {
1209
- refed: true,
1210
- ref: function() {
1211
- this.refed = true;
1212
- return res;
1213
- },
1214
- unref: function() {
1215
- this.refed = false;
1216
- return res;
1217
- },
1218
- hasRef: function() {
1219
- return this.refed;
1220
- },
1221
- refresh: function() {
1222
- timer.callAt = clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0));
1223
- clock.timers[timer.id] = timer;
1224
- return res;
1225
- },
1226
- [Symbol.toPrimitive]: function() {
1227
- return timer.id;
1228
- }
1229
- };
1230
- return res;
1231
- }
1232
- return timer.id;
1233
- }
1234
- /**
1235
- * Timer comparitor
1236
- * @param {Timer} a
1237
- * @param {Timer} b
1238
- * @returns {number}
1239
- */
1240
- function compareTimers(a, b) {
1241
- if (a.callAt < b.callAt) return -1;
1242
- if (a.callAt > b.callAt) return 1;
1243
- if (a.immediate && !b.immediate) return -1;
1244
- if (!a.immediate && b.immediate) return 1;
1245
- if (a.createdAt < b.createdAt) return -1;
1246
- if (a.createdAt > b.createdAt) return 1;
1247
- if (a.id < b.id) return -1;
1248
- if (a.id > b.id) return 1;
1249
- }
1250
- /**
1251
- * @param {Clock} clock
1252
- * @param {number} from
1253
- * @param {number} to
1254
- * @returns {Timer}
1255
- */
1256
- function firstTimerInRange(clock, from, to) {
1257
- const timers = clock.timers;
1258
- let timer = null;
1259
- let id, isInRange;
1260
- for (id in timers) if (timers.hasOwnProperty(id)) {
1261
- isInRange = inRange(from, to, timers[id]);
1262
- if (isInRange && (!timer || compareTimers(timer, timers[id]) === 1)) timer = timers[id];
1263
- }
1264
- return timer;
1265
- }
1266
- /**
1267
- * @param {Clock} clock
1268
- * @returns {Timer}
1269
- */
1270
- function firstTimer(clock) {
1271
- const timers = clock.timers;
1272
- let timer = null;
1273
- let id;
1274
- for (id in timers) if (timers.hasOwnProperty(id)) {
1275
- if (!timer || compareTimers(timer, timers[id]) === 1) timer = timers[id];
1276
- }
1277
- return timer;
1278
- }
1279
- /**
1280
- * @param {Clock} clock
1281
- * @returns {Timer}
1282
- */
1283
- function lastTimer(clock) {
1284
- const timers = clock.timers;
1285
- let timer = null;
1286
- let id;
1287
- for (id in timers) if (timers.hasOwnProperty(id)) {
1288
- if (!timer || compareTimers(timer, timers[id]) === -1) timer = timers[id];
1289
- }
1290
- return timer;
1291
- }
1292
- /**
1293
- * @param {Clock} clock
1294
- * @param {Timer} timer
1295
- */
1296
- function callTimer(clock, timer) {
1297
- if (typeof timer.interval === "number") clock.timers[timer.id].callAt += timer.interval;
1298
- else delete clock.timers[timer.id];
1299
- if (typeof timer.func === "function") timer.func.apply(null, timer.args);
1300
- else {
1301
- const eval2 = eval;
1302
- (function() {
1303
- eval2(timer.func);
1304
- })();
1305
- }
1306
- }
1307
- /**
1308
- * Gets clear handler name for a given timer type
1309
- * @param {string} ttype
1310
- */
1311
- function getClearHandler(ttype) {
1312
- if (ttype === "IdleCallback" || ttype === "AnimationFrame") return `cancel${ttype}`;
1313
- return `clear${ttype}`;
1314
- }
1315
- /**
1316
- * Gets schedule handler name for a given timer type
1317
- * @param {string} ttype
1318
- */
1319
- function getScheduleHandler(ttype) {
1320
- if (ttype === "IdleCallback" || ttype === "AnimationFrame") return `request${ttype}`;
1321
- return `set${ttype}`;
1322
- }
1323
- /**
1324
- * Creates an anonymous function to warn only once
1325
- */
1326
- function createWarnOnce() {
1327
- let calls = 0;
1328
- return function(msg) {
1329
- !calls++ && console.warn(msg);
1330
- };
1331
- }
1332
- const warnOnce = createWarnOnce();
1333
- /**
1334
- * @param {Clock} clock
1335
- * @param {number} timerId
1336
- * @param {string} ttype
1337
- */
1338
- function clearTimer(clock, timerId, ttype) {
1339
- if (!timerId) return;
1340
- if (!clock.timers) clock.timers = {};
1341
- const id = Number(timerId);
1342
- if (Number.isNaN(id) || id < idCounterStart) {
1343
- const handlerName = getClearHandler(ttype);
1344
- if (clock.shouldClearNativeTimers === true) {
1345
- const nativeHandler = clock[`_${handlerName}`];
1346
- return typeof nativeHandler === "function" ? nativeHandler(timerId) : void 0;
1347
- }
1348
- warnOnce(`FakeTimers: ${handlerName} was invoked to clear a native timer instead of one created by this library.
1349
- To automatically clean-up native timers, use \`shouldClearNativeTimers\`.`);
1350
- }
1351
- if (clock.timers.hasOwnProperty(id)) {
1352
- const timer = clock.timers[id];
1353
- if (timer.type === ttype || timer.type === "Timeout" && ttype === "Interval" || timer.type === "Interval" && ttype === "Timeout") delete clock.timers[id];
1354
- else {
1355
- const clear = getClearHandler(ttype);
1356
- const schedule = getScheduleHandler(timer.type);
1357
- throw new Error(`Cannot clear timer: timer created with ${schedule}() but cleared with ${clear}()`);
1358
- }
1359
- }
1360
- }
1361
- /**
1362
- * @param {Clock} clock
1363
- * @returns {Timer[]}
1364
- */
1365
- function uninstall(clock) {
1366
- let method, i, l;
1367
- const installedHrTime = "_hrtime";
1368
- const installedNextTick = "_nextTick";
1369
- for (i = 0, l = clock.methods.length; i < l; i++) {
1370
- method = clock.methods[i];
1371
- if (method === "hrtime" && _global.process) _global.process.hrtime = clock[installedHrTime];
1372
- else if (method === "nextTick" && _global.process) _global.process.nextTick = clock[installedNextTick];
1373
- else if (method === "performance") {
1374
- const originalPerfDescriptor = Object.getOwnPropertyDescriptor(clock, `_${method}`);
1375
- if (originalPerfDescriptor && originalPerfDescriptor.get && !originalPerfDescriptor.set) Object.defineProperty(_global, method, originalPerfDescriptor);
1376
- else if (originalPerfDescriptor.configurable) _global[method] = clock[`_${method}`];
1377
- } else if (_global[method] && _global[method].hadOwnProperty) _global[method] = clock[`_${method}`];
1378
- else try {
1379
- delete _global[method];
1380
- } catch (ignore) {}
1381
- if (clock.timersModuleMethods !== void 0) for (let j = 0; j < clock.timersModuleMethods.length; j++) {
1382
- const entry = clock.timersModuleMethods[j];
1383
- timersModule[entry.methodName] = entry.original;
1384
- }
1385
- if (clock.timersPromisesModuleMethods !== void 0) for (let j = 0; j < clock.timersPromisesModuleMethods.length; j++) {
1386
- const entry = clock.timersPromisesModuleMethods[j];
1387
- timersPromisesModule[entry.methodName] = entry.original;
1388
- }
1389
- }
1390
- clock.setTickMode("manual");
1391
- clock.methods = [];
1392
- for (const [listener, signal] of clock.abortListenerMap.entries()) {
1393
- signal.removeEventListener("abort", listener);
1394
- clock.abortListenerMap.delete(listener);
1395
- }
1396
- if (!clock.timers) return [];
1397
- return Object.keys(clock.timers).map(function mapper(key) {
1398
- return clock.timers[key];
1399
- });
1400
- }
1401
- /**
1402
- * @param {object} target the target containing the method to replace
1403
- * @param {string} method the keyname of the method on the target
1404
- * @param {Clock} clock
1405
- */
1406
- function hijackMethod(target, method, clock) {
1407
- clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(target, method);
1408
- clock[`_${method}`] = target[method];
1409
- if (method === "Date") target[method] = clock[method];
1410
- else if (method === "Intl") target[method] = clock[method];
1411
- else if (method === "performance") {
1412
- const originalPerfDescriptor = Object.getOwnPropertyDescriptor(target, method);
1413
- if (originalPerfDescriptor && originalPerfDescriptor.get && !originalPerfDescriptor.set) {
1414
- Object.defineProperty(clock, `_${method}`, originalPerfDescriptor);
1415
- Object.defineProperty(target, method, Object.getOwnPropertyDescriptor(clock, method));
1416
- } else target[method] = clock[method];
1417
- } else {
1418
- target[method] = function() {
1419
- return clock[method].apply(clock, arguments);
1420
- };
1421
- Object.defineProperties(target[method], Object.getOwnPropertyDescriptors(clock[method]));
1422
- }
1423
- target[method].clock = clock;
1424
- }
1425
- /**
1426
- * @param {Clock} clock
1427
- * @param {number} advanceTimeDelta
1428
- */
1429
- function doIntervalTick(clock, advanceTimeDelta) {
1430
- clock.tick(advanceTimeDelta);
1431
- }
1432
- /**
1433
- * @typedef {object} Timers
1434
- * @property {setTimeout} setTimeout
1435
- * @property {clearTimeout} clearTimeout
1436
- * @property {setInterval} setInterval
1437
- * @property {clearInterval} clearInterval
1438
- * @property {Date} Date
1439
- * @property {Intl} Intl
1440
- * @property {SetImmediate=} setImmediate
1441
- * @property {function(NodeImmediate): void=} clearImmediate
1442
- * @property {function(number[]):number[]=} hrtime
1443
- * @property {NextTick=} nextTick
1444
- * @property {Performance=} performance
1445
- * @property {RequestAnimationFrame=} requestAnimationFrame
1446
- * @property {boolean=} queueMicrotask
1447
- * @property {function(number): void=} cancelAnimationFrame
1448
- * @property {RequestIdleCallback=} requestIdleCallback
1449
- * @property {function(number): void=} cancelIdleCallback
1450
- */
1451
- /** @type {Timers} */
1452
- const timers = {
1453
- setTimeout: _global.setTimeout,
1454
- clearTimeout: _global.clearTimeout,
1455
- setInterval: _global.setInterval,
1456
- clearInterval: _global.clearInterval,
1457
- Date: _global.Date
1458
- };
1459
- if (isPresent.setImmediate) timers.setImmediate = _global.setImmediate;
1460
- if (isPresent.clearImmediate) timers.clearImmediate = _global.clearImmediate;
1461
- if (isPresent.hrtime) timers.hrtime = _global.process.hrtime;
1462
- if (isPresent.nextTick) timers.nextTick = _global.process.nextTick;
1463
- if (isPresent.performance) timers.performance = _global.performance;
1464
- if (isPresent.requestAnimationFrame) timers.requestAnimationFrame = _global.requestAnimationFrame;
1465
- if (isPresent.queueMicrotask) timers.queueMicrotask = _global.queueMicrotask;
1466
- if (isPresent.cancelAnimationFrame) timers.cancelAnimationFrame = _global.cancelAnimationFrame;
1467
- if (isPresent.requestIdleCallback) timers.requestIdleCallback = _global.requestIdleCallback;
1468
- if (isPresent.cancelIdleCallback) timers.cancelIdleCallback = _global.cancelIdleCallback;
1469
- if (isPresent.Intl) timers.Intl = NativeIntl;
1470
- const originalSetTimeout = _global.setImmediate || _global.setTimeout;
1471
- const originalClearInterval = _global.clearInterval;
1472
- const originalSetInterval = _global.setInterval;
1473
- /**
1474
- * @param {Date|number} [start] the system time - non-integer values are floored
1475
- * @param {number} [loopLimit] maximum number of timers that will be run when calling runAll()
1476
- * @returns {Clock}
1477
- */
1478
- function createClock(start, loopLimit) {
1479
- start = Math.floor(getEpoch(start));
1480
- loopLimit = loopLimit || 1e3;
1481
- let nanos = 0;
1482
- const adjustedSystemTime = [0, 0];
1483
- const clock = {
1484
- now: start,
1485
- Date: createDate(),
1486
- loopLimit,
1487
- tickMode: {
1488
- mode: "manual",
1489
- counter: 0,
1490
- delta: void 0
1491
- }
1492
- };
1493
- clock.Date.clock = clock;
1494
- function getTimeToNextFrame() {
1495
- return 16 - (clock.now - start) % 16;
1496
- }
1497
- function hrtime(prev) {
1498
- const millisSinceStart = clock.now - adjustedSystemTime[0] - start;
1499
- const secsSinceStart = Math.floor(millisSinceStart / 1e3);
1500
- const remainderInNanos = (millisSinceStart - secsSinceStart * 1e3) * 1e6 + nanos - adjustedSystemTime[1];
1501
- if (Array.isArray(prev)) {
1502
- if (prev[1] > 1e9) throw new TypeError("Number of nanoseconds can't exceed a billion");
1503
- const oldSecs = prev[0];
1504
- let nanoDiff = remainderInNanos - prev[1];
1505
- let secDiff = secsSinceStart - oldSecs;
1506
- if (nanoDiff < 0) {
1507
- nanoDiff += 1e9;
1508
- secDiff -= 1;
1509
- }
1510
- return [secDiff, nanoDiff];
1511
- }
1512
- return [secsSinceStart, remainderInNanos];
1513
- }
1514
- /**
1515
- * A high resolution timestamp in milliseconds.
1516
- * @typedef {number} DOMHighResTimeStamp
1517
- */
1518
- /**
1519
- * performance.now()
1520
- * @returns {DOMHighResTimeStamp}
1521
- */
1522
- function fakePerformanceNow() {
1523
- const hrt = hrtime();
1524
- return hrt[0] * 1e3 + hrt[1] / 1e6;
1525
- }
1526
- if (isPresent.hrtimeBigint) hrtime.bigint = function() {
1527
- const parts = hrtime();
1528
- return BigInt(parts[0]) * BigInt(1e9) + BigInt(parts[1]);
1529
- };
1530
- if (isPresent.Intl) {
1531
- clock.Intl = createIntl();
1532
- clock.Intl.clock = clock;
1533
- }
1534
- /**
1535
- * @param {TimerTickMode} tickModeConfig - The new configuration for how the clock should tick.
1536
- */
1537
- clock.setTickMode = function(tickModeConfig) {
1538
- const { mode: newMode, delta: newDelta } = tickModeConfig;
1539
- const { mode: oldMode, delta: oldDelta } = clock.tickMode;
1540
- if (newMode === oldMode && newDelta === oldDelta) return;
1541
- if (oldMode === "interval") originalClearInterval(clock.attachedInterval);
1542
- clock.tickMode = {
1543
- counter: clock.tickMode.counter + 1,
1544
- mode: newMode,
1545
- delta: newDelta
1546
- };
1547
- if (newMode === "nextAsync") advanceUntilModeChanges();
1548
- else if (newMode === "interval") createIntervalTick(clock, newDelta || 20);
1549
- };
1550
- async function advanceUntilModeChanges() {
1551
- async function newMacrotask() {
1552
- const channel = new MessageChannel();
1553
- await new Promise((resolve) => {
1554
- channel.port1.onmessage = () => {
1555
- resolve();
1556
- channel.port1.close();
1557
- };
1558
- channel.port2.postMessage(void 0);
1559
- });
1560
- channel.port1.close();
1561
- channel.port2.close();
1562
- await new Promise((resolve) => {
1563
- originalSetTimeout(resolve);
1564
- });
1565
- }
1566
- const { counter } = clock.tickMode;
1567
- while (clock.tickMode.counter === counter) {
1568
- await newMacrotask();
1569
- if (clock.tickMode.counter !== counter) return;
1570
- clock.next();
1571
- }
1572
- }
1573
- function pauseAutoTickUntilFinished(promise) {
1574
- if (clock.tickMode.mode !== "nextAsync") return promise;
1575
- clock.setTickMode({ mode: "manual" });
1576
- return promise.finally(() => {
1577
- clock.setTickMode({ mode: "nextAsync" });
1578
- });
1579
- }
1580
- clock.requestIdleCallback = function requestIdleCallback(func, timeout) {
1581
- let timeToNextIdlePeriod = 0;
1582
- if (clock.countTimers() > 0) timeToNextIdlePeriod = 50;
1583
- const result = addTimer(clock, {
1584
- func,
1585
- args: Array.prototype.slice.call(arguments, 2),
1586
- delay: typeof timeout === "undefined" ? timeToNextIdlePeriod : Math.min(timeout, timeToNextIdlePeriod),
1587
- idleCallback: true
1588
- });
1589
- return Number(result);
1590
- };
1591
- clock.cancelIdleCallback = function cancelIdleCallback(timerId) {
1592
- return clearTimer(clock, timerId, "IdleCallback");
1593
- };
1594
- clock.setTimeout = function setTimeout(func, timeout) {
1595
- return addTimer(clock, {
1596
- func,
1597
- args: Array.prototype.slice.call(arguments, 2),
1598
- delay: timeout
1599
- });
1600
- };
1601
- if (typeof _global.Promise !== "undefined" && utilPromisify) clock.setTimeout[utilPromisify.custom] = function promisifiedSetTimeout(timeout, arg) {
1602
- return new _global.Promise(function setTimeoutExecutor(resolve) {
1603
- addTimer(clock, {
1604
- func: resolve,
1605
- args: [arg],
1606
- delay: timeout
1607
- });
1608
- });
1609
- };
1610
- clock.clearTimeout = function clearTimeout(timerId) {
1611
- return clearTimer(clock, timerId, "Timeout");
1612
- };
1613
- clock.nextTick = function nextTick(func) {
1614
- return enqueueJob(clock, {
1615
- func,
1616
- args: Array.prototype.slice.call(arguments, 1),
1617
- error: isNearInfiniteLimit ? /* @__PURE__ */ new Error() : null
1618
- });
1619
- };
1620
- clock.queueMicrotask = function queueMicrotask(func) {
1621
- return clock.nextTick(func);
1622
- };
1623
- clock.setInterval = function setInterval(func, timeout) {
1624
- timeout = parseInt(timeout, 10);
1625
- return addTimer(clock, {
1626
- func,
1627
- args: Array.prototype.slice.call(arguments, 2),
1628
- delay: timeout,
1629
- interval: timeout
1630
- });
1631
- };
1632
- clock.clearInterval = function clearInterval(timerId) {
1633
- return clearTimer(clock, timerId, "Interval");
1634
- };
1635
- if (isPresent.setImmediate) {
1636
- clock.setImmediate = function setImmediate(func) {
1637
- return addTimer(clock, {
1638
- func,
1639
- args: Array.prototype.slice.call(arguments, 1),
1640
- immediate: true
1641
- });
1642
- };
1643
- if (typeof _global.Promise !== "undefined" && utilPromisify) clock.setImmediate[utilPromisify.custom] = function promisifiedSetImmediate(arg) {
1644
- return new _global.Promise(function setImmediateExecutor(resolve) {
1645
- addTimer(clock, {
1646
- func: resolve,
1647
- args: [arg],
1648
- immediate: true
1649
- });
1650
- });
1651
- };
1652
- clock.clearImmediate = function clearImmediate(timerId) {
1653
- return clearTimer(clock, timerId, "Immediate");
1654
- };
1655
- }
1656
- clock.countTimers = function countTimers() {
1657
- return Object.keys(clock.timers || {}).length + (clock.jobs || []).length;
1658
- };
1659
- clock.requestAnimationFrame = function requestAnimationFrame(func) {
1660
- const result = addTimer(clock, {
1661
- func,
1662
- delay: getTimeToNextFrame(),
1663
- get args() {
1664
- return [fakePerformanceNow()];
1665
- },
1666
- animation: true
1667
- });
1668
- return Number(result);
1669
- };
1670
- clock.cancelAnimationFrame = function cancelAnimationFrame(timerId) {
1671
- return clearTimer(clock, timerId, "AnimationFrame");
1672
- };
1673
- clock.runMicrotasks = function runMicrotasks() {
1674
- runJobs(clock);
1675
- };
1676
- /**
1677
- * @param {number|string} tickValue milliseconds or a string parseable by parseTime
1678
- * @param {boolean} isAsync
1679
- * @param {Function} resolve
1680
- * @param {Function} reject
1681
- * @returns {number|undefined} will return the new `now` value or nothing for async
1682
- */
1683
- function doTick(tickValue, isAsync, resolve, reject) {
1684
- const msFloat = typeof tickValue === "number" ? tickValue : parseTime(tickValue);
1685
- const ms = Math.floor(msFloat);
1686
- const remainder = nanoRemainder(msFloat);
1687
- let nanosTotal = nanos + remainder;
1688
- let tickTo = clock.now + ms;
1689
- if (msFloat < 0) throw new TypeError("Negative ticks are not supported");
1690
- if (nanosTotal >= 1e6) {
1691
- tickTo += 1;
1692
- nanosTotal -= 1e6;
1693
- }
1694
- nanos = nanosTotal;
1695
- let tickFrom = clock.now;
1696
- let previous = clock.now;
1697
- let timer, firstException, oldNow, nextPromiseTick, compensationCheck, postTimerCall;
1698
- clock.duringTick = true;
1699
- oldNow = clock.now;
1700
- runJobs(clock);
1701
- if (oldNow !== clock.now) {
1702
- tickFrom += clock.now - oldNow;
1703
- tickTo += clock.now - oldNow;
1704
- }
1705
- function doTickInner() {
1706
- timer = firstTimerInRange(clock, tickFrom, tickTo);
1707
- while (timer && tickFrom <= tickTo) {
1708
- if (clock.timers[timer.id]) {
1709
- tickFrom = timer.callAt;
1710
- clock.now = timer.callAt;
1711
- oldNow = clock.now;
1712
- try {
1713
- runJobs(clock);
1714
- callTimer(clock, timer);
1715
- } catch (e) {
1716
- firstException = firstException || e;
1717
- }
1718
- if (isAsync) {
1719
- originalSetTimeout(nextPromiseTick);
1720
- return;
1721
- }
1722
- compensationCheck();
1723
- }
1724
- postTimerCall();
1725
- }
1726
- oldNow = clock.now;
1727
- runJobs(clock);
1728
- if (oldNow !== clock.now) {
1729
- tickFrom += clock.now - oldNow;
1730
- tickTo += clock.now - oldNow;
1731
- }
1732
- clock.duringTick = false;
1733
- timer = firstTimerInRange(clock, tickFrom, tickTo);
1734
- if (timer) try {
1735
- clock.tick(tickTo - clock.now);
1736
- } catch (e) {
1737
- firstException = firstException || e;
1738
- }
1739
- else {
1740
- clock.now = tickTo;
1741
- nanos = nanosTotal;
1742
- }
1743
- if (firstException) throw firstException;
1744
- if (isAsync) resolve(clock.now);
1745
- else return clock.now;
1746
- }
1747
- nextPromiseTick = isAsync && function() {
1748
- try {
1749
- compensationCheck();
1750
- postTimerCall();
1751
- doTickInner();
1752
- } catch (e) {
1753
- reject(e);
1754
- }
1755
- };
1756
- compensationCheck = function() {
1757
- if (oldNow !== clock.now) {
1758
- tickFrom += clock.now - oldNow;
1759
- tickTo += clock.now - oldNow;
1760
- previous += clock.now - oldNow;
1761
- }
1762
- };
1763
- postTimerCall = function() {
1764
- timer = firstTimerInRange(clock, previous, tickTo);
1765
- previous = tickFrom;
1766
- };
1767
- return doTickInner();
1768
- }
1769
- /**
1770
- * @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"
1771
- * @returns {number} will return the new `now` value
1772
- */
1773
- clock.tick = function tick(tickValue) {
1774
- return doTick(tickValue, false);
1775
- };
1776
- if (typeof _global.Promise !== "undefined")
1777
- /**
1778
- * @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"
1779
- * @returns {Promise}
1780
- */
1781
- clock.tickAsync = function tickAsync(tickValue) {
1782
- return pauseAutoTickUntilFinished(new _global.Promise(function(resolve, reject) {
1783
- originalSetTimeout(function() {
1784
- try {
1785
- doTick(tickValue, true, resolve, reject);
1786
- } catch (e) {
1787
- reject(e);
1788
- }
1789
- });
1790
- }));
1791
- };
1792
- clock.next = function next() {
1793
- runJobs(clock);
1794
- const timer = firstTimer(clock);
1795
- if (!timer) return clock.now;
1796
- clock.duringTick = true;
1797
- try {
1798
- clock.now = timer.callAt;
1799
- callTimer(clock, timer);
1800
- runJobs(clock);
1801
- return clock.now;
1802
- } finally {
1803
- clock.duringTick = false;
1804
- }
1805
- };
1806
- if (typeof _global.Promise !== "undefined") clock.nextAsync = function nextAsync() {
1807
- return pauseAutoTickUntilFinished(new _global.Promise(function(resolve, reject) {
1808
- originalSetTimeout(function() {
1809
- try {
1810
- const timer = firstTimer(clock);
1811
- if (!timer) {
1812
- resolve(clock.now);
1813
- return;
1814
- }
1815
- let err;
1816
- clock.duringTick = true;
1817
- clock.now = timer.callAt;
1818
- try {
1819
- callTimer(clock, timer);
1820
- } catch (e) {
1821
- err = e;
1822
- }
1823
- clock.duringTick = false;
1824
- originalSetTimeout(function() {
1825
- if (err) reject(err);
1826
- else resolve(clock.now);
1827
- });
1828
- } catch (e) {
1829
- reject(e);
1830
- }
1831
- });
1832
- }));
1833
- };
1834
- clock.runAll = function runAll() {
1835
- let numTimers, i;
1836
- runJobs(clock);
1837
- for (i = 0; i < clock.loopLimit; i++) {
1838
- if (!clock.timers) {
1839
- resetIsNearInfiniteLimit();
1840
- return clock.now;
1841
- }
1842
- numTimers = Object.keys(clock.timers).length;
1843
- if (numTimers === 0) {
1844
- resetIsNearInfiniteLimit();
1845
- return clock.now;
1846
- }
1847
- clock.next();
1848
- checkIsNearInfiniteLimit(clock, i);
1849
- }
1850
- throw getInfiniteLoopError(clock, firstTimer(clock));
1851
- };
1852
- clock.runToFrame = function runToFrame() {
1853
- return clock.tick(getTimeToNextFrame());
1854
- };
1855
- if (typeof _global.Promise !== "undefined") clock.runAllAsync = function runAllAsync() {
1856
- return pauseAutoTickUntilFinished(new _global.Promise(function(resolve, reject) {
1857
- let i = 0;
1858
- /**
1859
- *
1860
- */
1861
- function doRun() {
1862
- originalSetTimeout(function() {
1863
- try {
1864
- runJobs(clock);
1865
- let numTimers;
1866
- if (i < clock.loopLimit) {
1867
- if (!clock.timers) {
1868
- resetIsNearInfiniteLimit();
1869
- resolve(clock.now);
1870
- return;
1871
- }
1872
- numTimers = Object.keys(clock.timers).length;
1873
- if (numTimers === 0) {
1874
- resetIsNearInfiniteLimit();
1875
- resolve(clock.now);
1876
- return;
1877
- }
1878
- clock.next();
1879
- i++;
1880
- doRun();
1881
- checkIsNearInfiniteLimit(clock, i);
1882
- return;
1883
- }
1884
- reject(getInfiniteLoopError(clock, firstTimer(clock)));
1885
- } catch (e) {
1886
- reject(e);
1887
- }
1888
- });
1889
- }
1890
- doRun();
1891
- }));
1892
- };
1893
- clock.runToLast = function runToLast() {
1894
- const timer = lastTimer(clock);
1895
- if (!timer) {
1896
- runJobs(clock);
1897
- return clock.now;
1898
- }
1899
- return clock.tick(timer.callAt - clock.now);
1900
- };
1901
- if (typeof _global.Promise !== "undefined") clock.runToLastAsync = function runToLastAsync() {
1902
- return pauseAutoTickUntilFinished(new _global.Promise(function(resolve, reject) {
1903
- originalSetTimeout(function() {
1904
- try {
1905
- const timer = lastTimer(clock);
1906
- if (!timer) {
1907
- runJobs(clock);
1908
- resolve(clock.now);
1909
- }
1910
- resolve(clock.tickAsync(timer.callAt - clock.now));
1911
- } catch (e) {
1912
- reject(e);
1913
- }
1914
- });
1915
- }));
1916
- };
1917
- clock.reset = function reset() {
1918
- nanos = 0;
1919
- clock.timers = {};
1920
- clock.jobs = [];
1921
- clock.now = start;
1922
- };
1923
- clock.setSystemTime = function setSystemTime(systemTime) {
1924
- const newNow = getEpoch(systemTime);
1925
- const difference = newNow - clock.now;
1926
- let id, timer;
1927
- adjustedSystemTime[0] = adjustedSystemTime[0] + difference;
1928
- adjustedSystemTime[1] = adjustedSystemTime[1] + nanos;
1929
- clock.now = newNow;
1930
- nanos = 0;
1931
- for (id in clock.timers) if (clock.timers.hasOwnProperty(id)) {
1932
- timer = clock.timers[id];
1933
- timer.createdAt += difference;
1934
- timer.callAt += difference;
1935
- }
1936
- };
1937
- /**
1938
- * @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"
1939
- * @returns {number} will return the new `now` value
1940
- */
1941
- clock.jump = function jump(tickValue) {
1942
- const msFloat = typeof tickValue === "number" ? tickValue : parseTime(tickValue);
1943
- const ms = Math.floor(msFloat);
1944
- for (const timer of Object.values(clock.timers)) if (clock.now + ms > timer.callAt) timer.callAt = clock.now + ms;
1945
- clock.tick(ms);
1946
- };
1947
- if (isPresent.performance) {
1948
- clock.performance = Object.create(null);
1949
- clock.performance.now = fakePerformanceNow;
1950
- }
1951
- if (isPresent.hrtime) clock.hrtime = hrtime;
1952
- return clock;
1953
- }
1954
- function createIntervalTick(clock, delta) {
1955
- clock.attachedInterval = originalSetInterval(doIntervalTick.bind(null, clock, delta), delta);
1956
- }
1957
- /**
1958
- * @param {Config=} [config] Optional config
1959
- * @returns {Clock}
1960
- */
1961
- function install(config) {
1962
- if (arguments.length > 1 || config instanceof Date || Array.isArray(config) || typeof config === "number") throw new TypeError(`FakeTimers.install called with ${String(config)} install requires an object parameter`);
1963
- if (_global.Date.isFake === true) throw new TypeError("Can't install fake timers twice on the same global object.");
1964
- config = typeof config !== "undefined" ? config : {};
1965
- config.shouldAdvanceTime = config.shouldAdvanceTime || false;
1966
- config.advanceTimeDelta = config.advanceTimeDelta || 20;
1967
- config.shouldClearNativeTimers = config.shouldClearNativeTimers || false;
1968
- if (config.target) throw new TypeError("config.target is no longer supported. Use `withGlobal(target)` instead.");
1969
- /**
1970
- * @param {string} timer/object the name of the thing that is not present
1971
- * @param timer
1972
- */
1973
- function handleMissingTimer(timer) {
1974
- if (config.ignoreMissingTimers) return;
1975
- throw new ReferenceError(`non-existent timers and/or objects cannot be faked: '${timer}'`);
1976
- }
1977
- let i, l;
1978
- const clock = createClock(config.now, config.loopLimit);
1979
- clock.shouldClearNativeTimers = config.shouldClearNativeTimers;
1980
- clock.uninstall = function() {
1981
- return uninstall(clock);
1982
- };
1983
- clock.abortListenerMap = /* @__PURE__ */ new Map();
1984
- clock.methods = config.toFake || [];
1985
- if (clock.methods.length === 0) clock.methods = Object.keys(timers);
1986
- if (config.shouldAdvanceTime === true) clock.setTickMode({
1987
- mode: "interval",
1988
- delta: config.advanceTimeDelta
1989
- });
1990
- if (clock.methods.includes("performance")) {
1991
- const proto = (() => {
1992
- if (hasPerformanceConstructorPrototype) return _global.performance.constructor.prototype;
1993
- if (hasPerformancePrototype) return _global.Performance.prototype;
1994
- })();
1995
- if (proto) {
1996
- Object.getOwnPropertyNames(proto).forEach(function(name) {
1997
- if (name !== "now") clock.performance[name] = name.indexOf("getEntries") === 0 ? NOOP_ARRAY : NOOP;
1998
- });
1999
- clock.performance.mark = (name) => new FakePerformanceEntry(name, "mark", 0, 0);
2000
- clock.performance.measure = (name) => new FakePerformanceEntry(name, "measure", 0, 100);
2001
- clock.performance.timeOrigin = getEpoch(config.now);
2002
- } else if ((config.toFake || []).includes("performance")) return handleMissingTimer("performance");
2003
- }
2004
- if (_global === globalObject && timersModule) clock.timersModuleMethods = [];
2005
- if (_global === globalObject && timersPromisesModule) clock.timersPromisesModuleMethods = [];
2006
- for (i = 0, l = clock.methods.length; i < l; i++) {
2007
- const nameOfMethodToReplace = clock.methods[i];
2008
- if (!isPresent[nameOfMethodToReplace]) {
2009
- handleMissingTimer(nameOfMethodToReplace);
2010
- continue;
2011
- }
2012
- if (nameOfMethodToReplace === "hrtime") {
2013
- if (_global.process && typeof _global.process.hrtime === "function") hijackMethod(_global.process, nameOfMethodToReplace, clock);
2014
- } else if (nameOfMethodToReplace === "nextTick") {
2015
- if (_global.process && typeof _global.process.nextTick === "function") hijackMethod(_global.process, nameOfMethodToReplace, clock);
2016
- } else hijackMethod(_global, nameOfMethodToReplace, clock);
2017
- if (clock.timersModuleMethods !== void 0 && timersModule[nameOfMethodToReplace]) {
2018
- const original = timersModule[nameOfMethodToReplace];
2019
- clock.timersModuleMethods.push({
2020
- methodName: nameOfMethodToReplace,
2021
- original
2022
- });
2023
- timersModule[nameOfMethodToReplace] = _global[nameOfMethodToReplace];
2024
- }
2025
- if (clock.timersPromisesModuleMethods !== void 0) {
2026
- if (nameOfMethodToReplace === "setTimeout") {
2027
- clock.timersPromisesModuleMethods.push({
2028
- methodName: "setTimeout",
2029
- original: timersPromisesModule.setTimeout
2030
- });
2031
- timersPromisesModule.setTimeout = (delay, value, options = {}) => new Promise((resolve, reject) => {
2032
- const abort = () => {
2033
- options.signal.removeEventListener("abort", abort);
2034
- clock.abortListenerMap.delete(abort);
2035
- clock.clearTimeout(handle);
2036
- reject(options.signal.reason);
2037
- };
2038
- const handle = clock.setTimeout(() => {
2039
- if (options.signal) {
2040
- options.signal.removeEventListener("abort", abort);
2041
- clock.abortListenerMap.delete(abort);
2042
- }
2043
- resolve(value);
2044
- }, delay);
2045
- if (options.signal) if (options.signal.aborted) abort();
2046
- else {
2047
- options.signal.addEventListener("abort", abort);
2048
- clock.abortListenerMap.set(abort, options.signal);
2049
- }
2050
- });
2051
- } else if (nameOfMethodToReplace === "setImmediate") {
2052
- clock.timersPromisesModuleMethods.push({
2053
- methodName: "setImmediate",
2054
- original: timersPromisesModule.setImmediate
2055
- });
2056
- timersPromisesModule.setImmediate = (value, options = {}) => new Promise((resolve, reject) => {
2057
- const abort = () => {
2058
- options.signal.removeEventListener("abort", abort);
2059
- clock.abortListenerMap.delete(abort);
2060
- clock.clearImmediate(handle);
2061
- reject(options.signal.reason);
2062
- };
2063
- const handle = clock.setImmediate(() => {
2064
- if (options.signal) {
2065
- options.signal.removeEventListener("abort", abort);
2066
- clock.abortListenerMap.delete(abort);
2067
- }
2068
- resolve(value);
2069
- });
2070
- if (options.signal) if (options.signal.aborted) abort();
2071
- else {
2072
- options.signal.addEventListener("abort", abort);
2073
- clock.abortListenerMap.set(abort, options.signal);
2074
- }
2075
- });
2076
- } else if (nameOfMethodToReplace === "setInterval") {
2077
- clock.timersPromisesModuleMethods.push({
2078
- methodName: "setInterval",
2079
- original: timersPromisesModule.setInterval
2080
- });
2081
- timersPromisesModule.setInterval = (delay, value, options = {}) => ({ [Symbol.asyncIterator]: () => {
2082
- const createResolvable = () => {
2083
- let resolve, reject;
2084
- const promise = new Promise((res, rej) => {
2085
- resolve = res;
2086
- reject = rej;
2087
- });
2088
- promise.resolve = resolve;
2089
- promise.reject = reject;
2090
- return promise;
2091
- };
2092
- let done = false;
2093
- let hasThrown = false;
2094
- let returnCall;
2095
- let nextAvailable = 0;
2096
- const nextQueue = [];
2097
- const handle = clock.setInterval(() => {
2098
- if (nextQueue.length > 0) nextQueue.shift().resolve();
2099
- else nextAvailable++;
2100
- }, delay);
2101
- const abort = () => {
2102
- options.signal.removeEventListener("abort", abort);
2103
- clock.abortListenerMap.delete(abort);
2104
- clock.clearInterval(handle);
2105
- done = true;
2106
- for (const resolvable of nextQueue) resolvable.resolve();
2107
- };
2108
- if (options.signal) if (options.signal.aborted) done = true;
2109
- else {
2110
- options.signal.addEventListener("abort", abort);
2111
- clock.abortListenerMap.set(abort, options.signal);
2112
- }
2113
- return {
2114
- next: async () => {
2115
- if (options.signal?.aborted && !hasThrown) {
2116
- hasThrown = true;
2117
- throw options.signal.reason;
2118
- }
2119
- if (done) return {
2120
- done: true,
2121
- value: void 0
2122
- };
2123
- if (nextAvailable > 0) {
2124
- nextAvailable--;
2125
- return {
2126
- done: false,
2127
- value
2128
- };
2129
- }
2130
- const resolvable = createResolvable();
2131
- nextQueue.push(resolvable);
2132
- await resolvable;
2133
- if (returnCall && nextQueue.length === 0) returnCall.resolve();
2134
- if (options.signal?.aborted && !hasThrown) {
2135
- hasThrown = true;
2136
- throw options.signal.reason;
2137
- }
2138
- if (done) return {
2139
- done: true,
2140
- value: void 0
2141
- };
2142
- return {
2143
- done: false,
2144
- value
2145
- };
2146
- },
2147
- return: async () => {
2148
- if (done) return {
2149
- done: true,
2150
- value: void 0
2151
- };
2152
- if (nextQueue.length > 0) {
2153
- returnCall = createResolvable();
2154
- await returnCall;
2155
- }
2156
- clock.clearInterval(handle);
2157
- done = true;
2158
- if (options.signal) {
2159
- options.signal.removeEventListener("abort", abort);
2160
- clock.abortListenerMap.delete(abort);
2161
- }
2162
- return {
2163
- done: true,
2164
- value: void 0
2165
- };
2166
- }
2167
- };
2168
- } });
2169
- }
2170
- }
2171
- }
2172
- return clock;
2173
- }
2174
- return {
2175
- timers,
2176
- createClock,
2177
- install,
2178
- withGlobal
2179
- };
2180
- }
2181
- /**
2182
- * @typedef {object} FakeTimers
2183
- * @property {Timers} timers
2184
- * @property {createClock} createClock
2185
- * @property {Function} install
2186
- * @property {withGlobal} withGlobal
2187
- */
2188
- /** @type {FakeTimers} */
2189
- const defaultImplementation = withGlobal(globalObject);
2190
- fakeTimersSrc.timers = defaultImplementation.timers;
2191
- fakeTimersSrc.createClock = defaultImplementation.createClock;
2192
- fakeTimersSrc.install = defaultImplementation.install;
2193
- fakeTimersSrc.withGlobal = withGlobal;
2194
- return fakeTimersSrc;
2195
- }
2196
- var fakeTimersSrcExports = requireFakeTimersSrc();
2197
- var FakeTimers = class {
2198
- _global;
2199
- _clock;
2200
- _fakingTime;
2201
- _fakingDate;
2202
- _fakeTimers;
2203
- _userConfig;
2204
- _now = RealDate.now;
2205
- constructor({ global, config }) {
2206
- this._userConfig = config;
2207
- this._fakingDate = null;
2208
- this._fakingTime = false;
2209
- this._fakeTimers = fakeTimersSrcExports.withGlobal(global);
2210
- this._global = global;
2211
- }
2212
- clearAllTimers() {
2213
- if (this._fakingTime) this._clock.reset();
2214
- }
2215
- dispose() {
2216
- this.useRealTimers();
2217
- }
2218
- runAllTimers() {
2219
- if (this._checkFakeTimers()) this._clock.runAll();
2220
- }
2221
- async runAllTimersAsync() {
2222
- if (this._checkFakeTimers()) await this._clock.runAllAsync();
2223
- }
2224
- runOnlyPendingTimers() {
2225
- if (this._checkFakeTimers()) this._clock.runToLast();
2226
- }
2227
- async runOnlyPendingTimersAsync() {
2228
- if (this._checkFakeTimers()) await this._clock.runToLastAsync();
2229
- }
2230
- advanceTimersToNextTimer(steps = 1) {
2231
- if (this._checkFakeTimers()) for (let i = steps; i > 0; i--) {
2232
- this._clock.next();
2233
- this._clock.tick(0);
2234
- if (this._clock.countTimers() === 0) break;
2235
- }
2236
- }
2237
- async advanceTimersToNextTimerAsync(steps = 1) {
2238
- if (this._checkFakeTimers()) for (let i = steps; i > 0; i--) {
2239
- await this._clock.nextAsync();
2240
- this._clock.tick(0);
2241
- if (this._clock.countTimers() === 0) break;
2242
- }
2243
- }
2244
- advanceTimersByTime(msToRun) {
2245
- if (this._checkFakeTimers()) this._clock.tick(msToRun);
2246
- }
2247
- async advanceTimersByTimeAsync(msToRun) {
2248
- if (this._checkFakeTimers()) await this._clock.tickAsync(msToRun);
2249
- }
2250
- advanceTimersToNextFrame() {
2251
- if (this._checkFakeTimers()) this._clock.runToFrame();
2252
- }
2253
- runAllTicks() {
2254
- if (this._checkFakeTimers()) this._clock.runMicrotasks();
2255
- }
2256
- useRealTimers() {
2257
- if (this._fakingDate) {
2258
- resetDate();
2259
- this._fakingDate = null;
2260
- }
2261
- if (this._fakingTime) {
2262
- this._clock.uninstall();
2263
- this._fakingTime = false;
2264
- }
2265
- }
2266
- useFakeTimers() {
2267
- const fakeDate = this._fakingDate || Date.now();
2268
- if (this._fakingDate) {
2269
- resetDate();
2270
- this._fakingDate = null;
2271
- }
2272
- if (this._fakingTime) this._clock.uninstall();
2273
- const toFake = Object.keys(this._fakeTimers.timers).filter((timer) => timer !== "nextTick" && timer !== "queueMicrotask");
2274
- if (this._userConfig?.toFake?.includes("nextTick") && isChildProcess()) throw new Error("process.nextTick cannot be mocked inside child_process");
2275
- this._clock = this._fakeTimers.install({
2276
- now: fakeDate,
2277
- ...this._userConfig,
2278
- toFake: this._userConfig?.toFake || toFake,
2279
- ignoreMissingTimers: true
2280
- });
2281
- this._fakingTime = true;
2282
- }
2283
- reset() {
2284
- if (this._checkFakeTimers()) {
2285
- const { now } = this._clock;
2286
- this._clock.reset();
2287
- this._clock.setSystemTime(now);
2288
- }
2289
- }
2290
- setSystemTime(now) {
2291
- const date = typeof now === "undefined" || now instanceof Date ? now : new Date(now);
2292
- if (this._fakingTime) this._clock.setSystemTime(date);
2293
- else {
2294
- this._fakingDate = date ?? new Date(this.getRealSystemTime());
2295
- mockDate(this._fakingDate);
2296
- }
2297
- }
2298
- getMockedSystemTime() {
2299
- return this._fakingTime ? new Date(this._clock.now) : this._fakingDate;
2300
- }
2301
- getRealSystemTime() {
2302
- return this._now();
2303
- }
2304
- getTimerCount() {
2305
- if (this._checkFakeTimers()) return this._clock.countTimers();
2306
- return 0;
2307
- }
2308
- setTimerTickMode(mode, interval) {
2309
- if (this._checkFakeTimers()) if (mode === "manual") this._clock.setTickMode({ mode: "manual" });
2310
- else if (mode === "nextTimerAsync") this._clock.setTickMode({ mode: "nextAsync" });
2311
- else if (mode === "interval") this._clock.setTickMode({
2312
- mode: "interval",
2313
- delta: interval
2314
- });
2315
- else throw new Error(`Invalid tick mode: ${mode}`);
2316
- }
2317
- configure(config) {
2318
- this._userConfig = config;
2319
- }
2320
- isFakeTimers() {
2321
- return this._fakingTime;
2322
- }
2323
- _checkFakeTimers() {
2324
- if (!this._fakingTime) throw new Error("A function to advance timers was called but the timers APIs are not mocked. Call `vi.useFakeTimers()` in the test file first.");
2325
- return this._fakingTime;
2326
- }
2327
- };
2328
- function copyStackTrace(target, source) {
2329
- if (source.stack !== void 0) target.stack = source.stack.replace(source.message, target.message);
2330
- return target;
2331
- }
2332
- function waitFor(callback, options = {}) {
2333
- const { setTimeout, setInterval, clearTimeout, clearInterval } = getSafeTimers();
2334
- const { interval = 50, timeout = 1e3 } = typeof options === "number" ? { timeout: options } : options;
2335
- const STACK_TRACE_ERROR = /* @__PURE__ */ new Error("STACK_TRACE_ERROR");
2336
- return new Promise((resolve, reject) => {
2337
- let lastError;
2338
- let promiseStatus = "idle";
2339
- let timeoutId;
2340
- let intervalId;
2341
- const onResolve = (result) => {
2342
- if (timeoutId) clearTimeout(timeoutId);
2343
- if (intervalId) clearInterval(intervalId);
2344
- resolve(result);
2345
- };
2346
- const handleTimeout = () => {
2347
- if (intervalId) clearInterval(intervalId);
2348
- let error = lastError;
2349
- if (!error) error = copyStackTrace(/* @__PURE__ */ new Error("Timed out in waitFor!"), STACK_TRACE_ERROR);
2350
- reject(error);
2351
- };
2352
- const checkCallback = () => {
2353
- if (vi.isFakeTimers()) vi.advanceTimersByTime(interval);
2354
- if (promiseStatus === "pending") return;
2355
- try {
2356
- const result = callback();
2357
- if (result !== null && typeof result === "object" && typeof result.then === "function") {
2358
- const thenable = result;
2359
- promiseStatus = "pending";
2360
- thenable.then((resolvedValue) => {
2361
- promiseStatus = "resolved";
2362
- onResolve(resolvedValue);
2363
- }, (rejectedValue) => {
2364
- promiseStatus = "rejected";
2365
- lastError = rejectedValue;
2366
- });
2367
- } else {
2368
- onResolve(result);
2369
- return true;
2370
- }
2371
- } catch (error) {
2372
- lastError = error;
2373
- }
2374
- };
2375
- if (checkCallback() === true) return;
2376
- timeoutId = setTimeout(handleTimeout, timeout);
2377
- intervalId = setInterval(checkCallback, interval);
2378
- });
2379
- }
2380
- function waitUntil(callback, options = {}) {
2381
- const { setTimeout, setInterval, clearTimeout, clearInterval } = getSafeTimers();
2382
- const { interval = 50, timeout = 1e3 } = typeof options === "number" ? { timeout: options } : options;
2383
- const STACK_TRACE_ERROR = /* @__PURE__ */ new Error("STACK_TRACE_ERROR");
2384
- return new Promise((resolve, reject) => {
2385
- let promiseStatus = "idle";
2386
- let timeoutId;
2387
- let intervalId;
2388
- const onReject = (error) => {
2389
- if (intervalId) clearInterval(intervalId);
2390
- if (!error) error = copyStackTrace(/* @__PURE__ */ new Error("Timed out in waitUntil!"), STACK_TRACE_ERROR);
2391
- reject(error);
2392
- };
2393
- const onResolve = (result) => {
2394
- if (!result) return;
2395
- if (timeoutId) clearTimeout(timeoutId);
2396
- if (intervalId) clearInterval(intervalId);
2397
- resolve(result);
2398
- return true;
2399
- };
2400
- const checkCallback = () => {
2401
- if (vi.isFakeTimers()) vi.advanceTimersByTime(interval);
2402
- if (promiseStatus === "pending") return;
2403
- try {
2404
- const result = callback();
2405
- if (result !== null && typeof result === "object" && typeof result.then === "function") {
2406
- const thenable = result;
2407
- promiseStatus = "pending";
2408
- thenable.then((resolvedValue) => {
2409
- promiseStatus = "resolved";
2410
- onResolve(resolvedValue);
2411
- }, (rejectedValue) => {
2412
- promiseStatus = "rejected";
2413
- onReject(rejectedValue);
2414
- });
2415
- } else return onResolve(result);
2416
- } catch (error) {
2417
- onReject(error);
2418
- }
2419
- };
2420
- if (checkCallback() === true) return;
2421
- timeoutId = setTimeout(onReject, timeout);
2422
- intervalId = setInterval(checkCallback, interval);
2423
- });
2424
- }
2425
- function createVitest() {
2426
- let _config = null;
2427
- const state = () => getWorkerState();
2428
- let _timers;
2429
- const timers = () => _timers ||= new FakeTimers({
2430
- global: globalThis,
2431
- config: state().config.fakeTimers
2432
- });
2433
- const _stubsGlobal = /* @__PURE__ */ new Map();
2434
- const _stubsEnv = /* @__PURE__ */ new Map();
2435
- const _envBooleans = [
2436
- "PROD",
2437
- "DEV",
2438
- "SSR"
2439
- ];
2440
- const utils = {
2441
- useFakeTimers(config) {
2442
- if (isChildProcess()) {
2443
- if (config?.toFake?.includes("nextTick") || state().config?.fakeTimers?.toFake?.includes("nextTick")) throw new Error("vi.useFakeTimers({ toFake: [\"nextTick\"] }) is not supported in node:child_process. Use --pool=threads if mocking nextTick is required.");
2444
- }
2445
- if (config) timers().configure({
2446
- ...state().config.fakeTimers,
2447
- ...config
2448
- });
2449
- else timers().configure(state().config.fakeTimers);
2450
- timers().useFakeTimers();
2451
- return utils;
2452
- },
2453
- isFakeTimers() {
2454
- return timers().isFakeTimers();
2455
- },
2456
- useRealTimers() {
2457
- timers().useRealTimers();
2458
- return utils;
2459
- },
2460
- runOnlyPendingTimers() {
2461
- timers().runOnlyPendingTimers();
2462
- return utils;
2463
- },
2464
- async runOnlyPendingTimersAsync() {
2465
- await timers().runOnlyPendingTimersAsync();
2466
- return utils;
2467
- },
2468
- runAllTimers() {
2469
- timers().runAllTimers();
2470
- return utils;
2471
- },
2472
- async runAllTimersAsync() {
2473
- await timers().runAllTimersAsync();
2474
- return utils;
2475
- },
2476
- runAllTicks() {
2477
- timers().runAllTicks();
2478
- return utils;
2479
- },
2480
- advanceTimersByTime(ms) {
2481
- timers().advanceTimersByTime(ms);
2482
- return utils;
2483
- },
2484
- async advanceTimersByTimeAsync(ms) {
2485
- await timers().advanceTimersByTimeAsync(ms);
2486
- return utils;
2487
- },
2488
- advanceTimersToNextTimer() {
2489
- timers().advanceTimersToNextTimer();
2490
- return utils;
2491
- },
2492
- async advanceTimersToNextTimerAsync() {
2493
- await timers().advanceTimersToNextTimerAsync();
2494
- return utils;
2495
- },
2496
- advanceTimersToNextFrame() {
2497
- timers().advanceTimersToNextFrame();
2498
- return utils;
2499
- },
2500
- getTimerCount() {
2501
- return timers().getTimerCount();
2502
- },
2503
- setSystemTime(time) {
2504
- timers().setSystemTime(time);
2505
- return utils;
2506
- },
2507
- getMockedSystemTime() {
2508
- return timers().getMockedSystemTime();
2509
- },
2510
- getRealSystemTime() {
2511
- return timers().getRealSystemTime();
2512
- },
2513
- clearAllTimers() {
2514
- timers().clearAllTimers();
2515
- return utils;
2516
- },
2517
- setTimerTickMode(mode, interval) {
2518
- timers().setTimerTickMode(mode, interval);
2519
- return utils;
2520
- },
2521
- spyOn,
2522
- fn,
2523
- waitFor,
2524
- waitUntil,
2525
- defineHelper: (fn) => {
2526
- return function __VITEST_HELPER__(...args) {
2527
- const result = fn(...args);
2528
- if (result && typeof result === "object" && typeof result.then === "function") return (async function __VITEST_HELPER__() {
2529
- return await result;
2530
- })();
2531
- return result;
2532
- };
2533
- },
2534
- hoisted(factory) {
2535
- assertTypes(factory, "\"vi.hoisted\" factory", ["function"]);
2536
- return factory();
2537
- },
2538
- mock(path, factory) {
2539
- if (typeof path !== "string") throw new TypeError(`vi.mock() expects a string path, but received a ${typeof path}`);
2540
- const importer = getImporter("mock");
2541
- _mocker().queueMock(path, importer, typeof factory === "function" ? () => factory(() => _mocker().importActual(path, importer, _mocker().getMockContext().callstack)) : factory);
2542
- },
2543
- unmock(path) {
2544
- if (typeof path !== "string") throw new TypeError(`vi.unmock() expects a string path, but received a ${typeof path}`);
2545
- _mocker().queueUnmock(path, getImporter("unmock"));
2546
- },
2547
- doMock(path, factory) {
2548
- if (typeof path !== "string") throw new TypeError(`vi.doMock() expects a string path, but received a ${typeof path}`);
2549
- const importer = getImporter("doMock");
2550
- _mocker().queueMock(path, importer, typeof factory === "function" ? () => factory(() => _mocker().importActual(path, importer, _mocker().getMockContext().callstack)) : factory);
2551
- const rv = {};
2552
- if (Symbol.dispose) rv[Symbol.dispose] = () => {
2553
- _mocker().queueUnmock(path, importer);
2554
- };
2555
- return rv;
2556
- },
2557
- doUnmock(path) {
2558
- if (typeof path !== "string") throw new TypeError(`vi.doUnmock() expects a string path, but received a ${typeof path}`);
2559
- const importer = getImporter("doUnmock");
2560
- _mocker().queueUnmock(path, importer);
2561
- },
2562
- async importActual(path) {
2563
- const importer = getImporter("importActual");
2564
- return _mocker().importActual(path, importer, _mocker().getMockContext().callstack);
2565
- },
2566
- async importMock(path) {
2567
- const importer = getImporter("importMock");
2568
- return _mocker().importMock(path, importer);
2569
- },
2570
- mockObject(value, options) {
2571
- return _mocker().mockObject({ value }, void 0, options?.spy ? "autospy" : "automock").value;
2572
- },
2573
- mocked(item, _options = {}) {
2574
- return item;
2575
- },
2576
- isMockFunction(fn) {
2577
- return isMockFunction(fn);
2578
- },
2579
- clearAllMocks() {
2580
- clearAllMocks();
2581
- return utils;
2582
- },
2583
- resetAllMocks() {
2584
- resetAllMocks();
2585
- return utils;
2586
- },
2587
- restoreAllMocks() {
2588
- restoreAllMocks();
2589
- return utils;
2590
- },
2591
- stubGlobal(name, value) {
2592
- if (!_stubsGlobal.has(name)) _stubsGlobal.set(name, Object.getOwnPropertyDescriptor(globalThis, name));
2593
- Object.defineProperty(globalThis, name, {
2594
- value,
2595
- writable: true,
2596
- configurable: true,
2597
- enumerable: true
2598
- });
2599
- return utils;
2600
- },
2601
- stubEnv(name, value) {
2602
- const env = state().metaEnv;
2603
- if (!_stubsEnv.has(name)) _stubsEnv.set(name, env[name]);
2604
- if (_envBooleans.includes(name)) env[name] = value ? "1" : "";
2605
- else if (value === void 0) delete env[name];
2606
- else env[name] = String(value);
2607
- return utils;
2608
- },
2609
- unstubAllGlobals() {
2610
- _stubsGlobal.forEach((original, name) => {
2611
- if (!original) Reflect.deleteProperty(globalThis, name);
2612
- else Object.defineProperty(globalThis, name, original);
2613
- });
2614
- _stubsGlobal.clear();
2615
- return utils;
2616
- },
2617
- unstubAllEnvs() {
2618
- const env = state().metaEnv;
2619
- _stubsEnv.forEach((original, name) => {
2620
- if (original === void 0) delete env[name];
2621
- else env[name] = original;
2622
- });
2623
- _stubsEnv.clear();
2624
- return utils;
2625
- },
2626
- resetModules() {
2627
- resetModules(state().evaluatedModules);
2628
- return utils;
2629
- },
2630
- async dynamicImportSettled() {
2631
- return waitForImportsToResolve();
2632
- },
2633
- setConfig(config) {
2634
- if (!_config) _config = { ...state().config };
2635
- Object.assign(state().config, config);
2636
- },
2637
- resetConfig() {
2638
- if (_config) Object.assign(state().config, _config);
2639
- }
2640
- };
2641
- return utils;
2642
- }
2643
- const vitest = createVitest();
2644
- const vi = vitest;
2645
- function _mocker() {
2646
- return typeof __vitest_mocker__ !== "undefined" ? __vitest_mocker__ : new Proxy({}, { get(_, name) {
2647
- throw new Error(`Vitest mocker was not initialized in this environment. vi.${String(name)}() is forbidden.`);
2648
- } });
2649
- }
2650
- function getImporter(name) {
2651
- const stackArray = createSimpleStackTrace({ stackTraceLimit: 5 }).split("\n");
2652
- return parseSingleStack(stackArray[stackArray.findLastIndex((stack) => {
2653
- return stack.includes(` at Object.${name}`) || stack.includes(`${name}@`) || stack.includes(` at ${name} (`);
2654
- }) + 1])?.file || "";
2655
- }
2656
- function createBenchmarkResult(name) {
2657
- return {
2658
- name,
2659
- rank: 0,
2660
- rme: 0,
2661
- samples: []
2662
- };
2663
- }
2664
- const benchmarkTasks = /* @__PURE__ */ new WeakMap();
2665
- async function runBenchmarkSuite(suite, runner) {
2666
- const { Task, Bench } = await runner.importTinybench();
2667
- const start = performance.now();
2668
- const benchmarkGroup = [];
2669
- const benchmarkSuiteGroup = [];
2670
- for (const task of suite.tasks) {
2671
- if (task.mode !== "run" && task.mode !== "queued") continue;
2672
- if (task.meta?.benchmark) benchmarkGroup.push(task);
2673
- else if (task.type === "suite") benchmarkSuiteGroup.push(task);
2674
- }
2675
- for (const subSuite of benchmarkSuiteGroup) await runBenchmarkSuite(subSuite, runner);
2676
- if (benchmarkGroup.length) {
2677
- const defer = createDefer();
2678
- suite.result = {
2679
- state: "run",
2680
- startTime: start,
2681
- benchmark: createBenchmarkResult(suite.name)
2682
- };
2683
- updateTask$1("suite-prepare", suite);
2684
- const addBenchTaskListener = (task, benchmark) => {
2685
- task.addEventListener("complete", (e) => {
2686
- const taskRes = e.task.result;
2687
- const result = benchmark.result.benchmark;
2688
- benchmark.result.state = "pass";
2689
- Object.assign(result, taskRes);
2690
- const samples = result.samples;
2691
- result.sampleCount = samples.length;
2692
- result.median = samples.length % 2 ? samples[Math.floor(samples.length / 2)] : (samples[samples.length / 2] + samples[samples.length / 2 - 1]) / 2;
2693
- if (!runner.config.benchmark?.includeSamples) result.samples.length = 0;
2694
- updateTask$1("test-finished", benchmark);
2695
- }, { once: true });
2696
- task.addEventListener("error", (e) => {
2697
- const task = e.task;
2698
- defer.reject(benchmark ? task.result.error : e);
2699
- }, { once: true });
2700
- };
2701
- benchmarkGroup.forEach((benchmark) => {
2702
- const benchmarkInstance = new Bench(getBenchOptions(benchmark));
2703
- const benchmarkFn = getBenchFn(benchmark);
2704
- benchmark.result = {
2705
- state: "run",
2706
- startTime: start,
2707
- benchmark: createBenchmarkResult(benchmark.name)
2708
- };
2709
- const task = new Task(benchmarkInstance, benchmark.name, benchmarkFn);
2710
- benchmarkTasks.set(benchmark, task);
2711
- addBenchTaskListener(task, benchmark);
2712
- });
2713
- const { setTimeout } = getSafeTimers();
2714
- const tasks = [];
2715
- for (const benchmark of benchmarkGroup) {
2716
- const task = benchmarkTasks.get(benchmark);
2717
- updateTask$1("test-prepare", benchmark);
2718
- await task.warmup();
2719
- tasks.push([await new Promise((resolve) => setTimeout(async () => {
2720
- resolve(await task.run());
2721
- })), benchmark]);
2722
- }
2723
- suite.result.duration = performance.now() - start;
2724
- suite.result.state = "pass";
2725
- updateTask$1("suite-finished", suite);
2726
- defer.resolve(null);
2727
- await defer;
2728
- }
2729
- function updateTask$1(event, task) {
2730
- updateTask(event, task, runner);
2731
- }
2732
- }
2733
- var NodeBenchmarkRunner = class {
2734
- moduleRunner;
2735
- constructor(config) {
2736
- this.config = config;
2737
- }
2738
- async importTinybench() {
2739
- return await import("../../../../../tinybench@2.9.0/node_modules/tinybench/dist/index.js");
2740
- }
2741
- importFile(filepath, source) {
2742
- if (source === "setup") {
2743
- const moduleNode = getWorkerState().evaluatedModules.getModuleById(filepath);
2744
- if (moduleNode) getWorkerState().evaluatedModules.invalidateModule(moduleNode);
2745
- }
2746
- return this.moduleRunner.import(filepath);
2747
- }
2748
- async runSuite(suite) {
2749
- await runBenchmarkSuite(suite, this);
2750
- }
2751
- async runTask() {
2752
- throw new Error("`test()` and `it()` is only available in test mode.");
2753
- }
2754
- };
2755
- var TestRunner = class {
2756
- snapshotClient = getSnapshotClient();
2757
- workerState = getWorkerState();
2758
- moduleRunner;
2759
- cancelRun = false;
2760
- assertionsErrors = /* @__PURE__ */ new WeakMap();
2761
- pool = this.workerState.ctx.pool;
2762
- _otel;
2763
- viteEnvironment;
2764
- viteModuleRunner;
2765
- constructor(config) {
2766
- this.config = config;
2767
- const environment = this.workerState.environment;
2768
- this.viteEnvironment = environment.viteEnvironment || environment.name;
2769
- this.viteModuleRunner = config.experimental.viteModuleRunner;
2770
- }
2771
- importFile(filepath, source) {
2772
- if (source === "setup") {
2773
- const moduleNode = this.workerState.evaluatedModules.getModuleById(filepath);
2774
- if (moduleNode) this.workerState.evaluatedModules.invalidateModule(moduleNode);
2775
- }
2776
- return this._otel.$(`vitest.module.import_${source === "setup" ? "setup" : "spec"}`, { attributes: { "code.file.path": filepath } }, () => {
2777
- if (!this.viteModuleRunner) filepath = `${filepath}?vitest=${Date.now()}`;
2778
- return this.moduleRunner.import(filepath);
2779
- });
2780
- }
2781
- onCollectStart(file) {
2782
- this.workerState.current = file;
2783
- }
2784
- onCleanupWorkerContext(listener) {
2785
- this.workerState.onCleanup(listener);
2786
- }
2787
- onAfterRunFiles() {
2788
- this.snapshotClient.clear();
2789
- this.workerState.current = void 0;
2790
- }
2791
- async onAfterRunSuite(suite) {
2792
- if (this.config.logHeapUsage && typeof process !== "undefined") suite.result.heap = process.memoryUsage().heapUsed;
2793
- if (suite.mode !== "skip" && "filepath" in suite) {
2794
- for (const test of getTests(suite)) if (test.mode === "skip") {
2795
- const name = getNames(test).slice(1).join(" > ");
2796
- this.snapshotClient.skipTest(suite.file.filepath, name);
2797
- }
2798
- const result = await this.snapshotClient.finish(suite.file.filepath);
2799
- if (this.workerState.config.snapshotOptions.updateSnapshot === "none" && result.unchecked) {
2800
- let message = `Obsolete snapshots found when no snapshot update is expected.\n`;
2801
- for (const key of result.uncheckedKeys) message += `· ${key}\n`;
2802
- suite.result.errors ??= [];
2803
- suite.result.errors.push(processError(new Error(message)));
2804
- suite.result.state = "fail";
2805
- }
2806
- await rpc().snapshotSaved(result);
2807
- }
2808
- this.workerState.current = suite.suite || suite.file;
2809
- }
2810
- onAfterRunTask(test) {
2811
- if (this.config.logHeapUsage && typeof process !== "undefined") test.result.heap = process.memoryUsage().heapUsed;
2812
- this.workerState.current = test.suite || test.file;
2813
- }
2814
- cancel(_reason) {
2815
- this.cancelRun = true;
2816
- }
2817
- injectValue(key) {
2818
- return inject(key);
2819
- }
2820
- async onBeforeRunTask(test) {
2821
- if (this.cancelRun) test.mode = "skip";
2822
- if (test.mode !== "run" && test.mode !== "queued") return;
2823
- this.workerState.current = test;
2824
- }
2825
- async onBeforeRunSuite(suite) {
2826
- if (this.cancelRun) suite.mode = "skip";
2827
- if (suite.mode !== "skip" && "filepath" in suite) await this.snapshotClient.setup(suite.file.filepath, this.workerState.config.snapshotOptions);
2828
- this.workerState.current = suite;
2829
- }
2830
- onBeforeTryTask(test) {
2831
- clearModuleMocks(this.config);
2832
- this.snapshotClient.clearTest(test.file.filepath, test.id);
2833
- setState({
2834
- assertionCalls: 0,
2835
- isExpectingAssertions: false,
2836
- isExpectingAssertionsError: null,
2837
- expectedAssertionsNumber: null,
2838
- expectedAssertionsNumberErrorGen: null,
2839
- currentTestName: getTestName(test),
2840
- snapshotState: this.snapshotClient.getSnapshotState(test.file.filepath)
2841
- }, globalThis[GLOBAL_EXPECT]);
2842
- }
2843
- onAfterTryTask(test) {
2844
- const { assertionCalls, expectedAssertionsNumber, expectedAssertionsNumberErrorGen, isExpectingAssertions, isExpectingAssertionsError } = test.context._local ? test.context.expect.getState() : getState(globalThis[GLOBAL_EXPECT]);
2845
- if (expectedAssertionsNumber !== null && assertionCalls !== expectedAssertionsNumber) throw expectedAssertionsNumberErrorGen();
2846
- if (isExpectingAssertions === true && assertionCalls === 0) throw isExpectingAssertionsError;
2847
- if (this.config.expect.requireAssertions && assertionCalls === 0) throw this.assertionsErrors.get(test);
2848
- }
2849
- extendTaskContext(context) {
2850
- if (this.config.expect.requireAssertions) this.assertionsErrors.set(context.task, /* @__PURE__ */ new Error("expected any number of assertion, but got none"));
2851
- let _expect;
2852
- Object.defineProperty(context, "expect", { get() {
2853
- if (!_expect) _expect = createExpect(context.task);
2854
- return _expect;
2855
- } });
2856
- Object.defineProperty(context, "_local", { get() {
2857
- return _expect != null;
2858
- } });
2859
- return context;
2860
- }
2861
- getImportDurations() {
2862
- const { limit } = this.config.experimental.importDurations;
2863
- if (limit === 0) return {};
2864
- const sortedEntries = [...this.workerState.moduleExecutionInfo?.entries() || []].sort(([, a], [, b]) => b.duration - a.duration).slice(0, limit);
2865
- const importDurations = {};
2866
- for (const [filepath, { duration, selfTime, external, importer }] of sortedEntries) importDurations[normalize(filepath)] = {
2867
- selfTime,
2868
- totalTime: duration,
2869
- external,
2870
- importer
2871
- };
2872
- return importDurations;
2873
- }
2874
- trace = (name, attributes, cb) => {
2875
- const options = typeof attributes === "object" ? { attributes } : {};
2876
- return this._otel.$(`vitest.test.runner.${name}`, options, cb || attributes);
2877
- };
2878
- __setTraces(traces) {
2879
- this._otel = traces;
2880
- }
2881
- static createTaskCollector = createTaskCollector;
2882
- static getCurrentSuite = getCurrentSuite;
2883
- static getCurrentTest = getCurrentTest;
2884
- static createChainable = createChainable;
2885
- static getSuiteHooks = getHooks;
2886
- static getTestFn = getFn;
2887
- static setSuiteHooks = getHooks;
2888
- static setTestFn = getFn;
2889
- static matchesTags = matchesTags;
2890
- /**
2891
- * @deprecated
2892
- */
2893
- static getBenchFn = getBenchFn;
2894
- /**
2895
- * @deprecated
2896
- */
2897
- static getBenchOptions = getBenchOptions;
2898
- };
2899
- function clearModuleMocks(config) {
2900
- const { clearMocks, mockReset, restoreMocks, unstubEnvs, unstubGlobals } = config;
2901
- if (restoreMocks) vi.restoreAllMocks();
2902
- if (mockReset) vi.resetAllMocks();
2903
- if (clearMocks) vi.clearAllMocks();
2904
- if (unstubEnvs) vi.unstubAllEnvs();
2905
- if (unstubGlobals) vi.unstubAllGlobals();
2906
- }
2907
- //#endregion
2908
- export { NodeBenchmarkRunner, TestRunner, assert, createExpect, globalExpect, inject, should, vi, vitest };
2909
-
2910
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5wX0o2ZEI4YS5qcyIsIm5hbWVzIjpbImNoYWkuQXNzZXJ0aW9uIiwiY2hhaS51c2UiLCJleHBlY3QiLCJjaGFpLmV4cGVjdCIsImNoYWkuYXNzZXJ0IiwiY2hhaS5zaG91bGQiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vdml0ZXN0QDQuMS4yX0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMF9AdHlwZXMrbm9kZUAyNS4wLjdfdml0ZUA4LjAuM19AZW1uYXBpK2NvcmVAMS45LjJfX2JiMzEwODcyNzhmOTdhMzliMzFiOTIwMTBiZWFiOTgwL25vZGVfbW9kdWxlcy92aXRlc3QvZGlzdC9jaHVua3MvdGVzdC5wX0o2ZEI4YS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnZXRDdXJyZW50VGVzdCwgdXBkYXRlVGFzaywgY3JlYXRlVGFza0NvbGxlY3RvciwgZ2V0Q3VycmVudFN1aXRlLCBnZXRIb29rcywgZ2V0Rm4gfSBmcm9tICdAdml0ZXN0L3J1bm5lcic7XG5pbXBvcnQgeyBhc3NlcnRUeXBlcywgY3JlYXRlU2ltcGxlU3RhY2tUcmFjZSwgY3JlYXRlRGVmZXIgfSBmcm9tICdAdml0ZXN0L3V0aWxzL2hlbHBlcnMnO1xuaW1wb3J0IHsgZ2V0U2FmZVRpbWVycywgZGVsYXkgfSBmcm9tICdAdml0ZXN0L3V0aWxzL3RpbWVycyc7XG5pbXBvcnQgeyBhIGFzIGdldEJlbmNoT3B0aW9ucywgZyBhcyBnZXRCZW5jaEZuIH0gZnJvbSAnLi9iZW5jaG1hcmsuQ1hfb1kwM1YuanMnO1xuaW1wb3J0IHsgZyBhcyBnZXRXb3JrZXJTdGF0ZSwgaSBhcyBpc0NoaWxkUHJvY2VzcywgdyBhcyB3YWl0Rm9ySW1wb3J0c1RvUmVzb2x2ZSwgciBhcyByZXNldE1vZHVsZXMgfSBmcm9tICcuL3V0aWxzLkJYNUZnOEM0LmpzJztcbmltcG9ydCB7IGNoYWksIHdyYXBBc3NlcnRpb24sIHJlY29yZEFzeW5jRXhwZWN0LCBjcmVhdGVBc3NlcnRpb25NZXNzYWdlLCBlcXVhbHMsIGl0ZXJhYmxlRXF1YWxpdHksIHN1YnNldEVxdWFsaXR5LCBKZXN0RXh0ZW5kLCBKZXN0Q2hhaUV4cGVjdCwgQ2hhaVN0eWxlQXNzZXJ0aW9ucywgSmVzdEFzeW1tZXRyaWNNYXRjaGVycywgR0xPQkFMX0VYUEVDVCwgQVNZTU1FVFJJQ19NQVRDSEVSU19PQkpFQ1QsIGdldFN0YXRlLCBzZXRTdGF0ZSwgYWRkQ3VzdG9tRXF1YWxpdHlUZXN0ZXJzLCBjdXN0b21NYXRjaGVycyB9IGZyb20gJ0B2aXRlc3QvZXhwZWN0JztcbmltcG9ydCB7IGdldE5hbWVzLCBnZXRUZXN0cywgZ2V0VGVzdE5hbWUsIGNyZWF0ZUNoYWluYWJsZSwgbWF0Y2hlc1RhZ3MgfSBmcm9tICdAdml0ZXN0L3J1bm5lci91dGlscyc7XG5pbXBvcnQgeyBwcm9jZXNzRXJyb3IgfSBmcm9tICdAdml0ZXN0L3V0aWxzL2Vycm9yJztcbmltcG9ydCB7IG5vcm1hbGl6ZSB9IGZyb20gJ3BhdGhlJztcbmltcG9ydCB7IHN0cmlwU25hcHNob3RJbmRlbnRhdGlvbiwgYWRkU2VyaWFsaXplciwgU25hcHNob3RDbGllbnQgfSBmcm9tICdAdml0ZXN0L3NuYXBzaG90JztcbmltcG9ydCB7IGZuLCBzcHlPbiwgcmVzdG9yZUFsbE1vY2tzLCByZXNldEFsbE1vY2tzLCBjbGVhckFsbE1vY2tzLCBpc01vY2tGdW5jdGlvbiB9IGZyb20gJ0B2aXRlc3Qvc3B5JztcbmltcG9ydCAnQHZpdGVzdC91dGlscy9vZmZzZXQnO1xuaW1wb3J0IHsgcGFyc2VTaW5nbGVTdGFjayB9IGZyb20gJ0B2aXRlc3QvdXRpbHMvc291cmNlLW1hcCc7XG5pbXBvcnQgeyBjIGFzIGNvbW1vbmpzR2xvYmFsIH0gZnJvbSAnLi9fY29tbW9uanNIZWxwZXJzLkQyNnR5M0V3LmpzJztcbmltcG9ydCB7IFIgYXMgUmVhbERhdGUsIGIgYXMgcmVzZXREYXRlLCBtIGFzIG1vY2tEYXRlLCByIGFzIHJwYyB9IGZyb20gJy4vcnBjLk16WGV0M2psLmpzJztcblxuLy8gdGhlc2UgbWF0Y2hlcnMgYXJlIG5vdCBzdXBwb3J0ZWQgYmVjYXVzZSB0aGV5IGRvbid0IG1ha2Ugc2Vuc2Ugd2l0aCBwb2xsXG5jb25zdCB1bnN1cHBvcnRlZCA9IFtcblx0XCJtYXRjaFNuYXBzaG90XCIsXG5cdFwidG9NYXRjaFNuYXBzaG90XCIsXG5cdFwidG9NYXRjaElubGluZVNuYXBzaG90XCIsXG5cdFwidG9UaHJvd0Vycm9yTWF0Y2hpbmdTbmFwc2hvdFwiLFxuXHRcInRvVGhyb3dFcnJvck1hdGNoaW5nSW5saW5lU25hcHNob3RcIixcblx0XCJ0aHJvd3NcIixcblx0XCJUaHJvd1wiLFxuXHRcInRocm93XCIsXG5cdFwidG9UaHJvd1wiLFxuXHRcInRvVGhyb3dFcnJvclwiXG5dO1xuLyoqXG4qIEF0dGFjaGVzIGEgYGNhdXNlYCBwcm9wZXJ0eSB0byB0aGUgZXJyb3IgaWYgbWlzc2luZywgY29waWVzIHRoZSBzdGFjayB0cmFjZSBmcm9tIHRoZSBzb3VyY2UsIGFuZCB0aHJvd3MuXG4qXG4qIEBwYXJhbSBlcnJvciAtIFRoZSBlcnJvciB0byB0aHJvd1xuKiBAcGFyYW0gc291cmNlIC0gRXJyb3IgdG8gY29weSB0aGUgc3RhY2sgdHJhY2UgZnJvbVxuKlxuKiBAdGhyb3dzIEFsd2F5cyB0aHJvd3MgdGhlIHByb3ZpZGVkIGVycm9yIHdpdGggYW4gYW1lbmRlZCBzdGFjayB0cmFjZVxuKi9cbmZ1bmN0aW9uIHRocm93V2l0aENhdXNlKGVycm9yLCBzb3VyY2UpIHtcblx0aWYgKGVycm9yLmNhdXNlID09IG51bGwpIGVycm9yLmNhdXNlID0gLyogQF9fUFVSRV9fICovIG5ldyBFcnJvcihcIk1hdGNoZXIgZGlkIG5vdCBzdWNjZWVkIGluIHRpbWUuXCIpO1xuXHR0aHJvdyBjb3B5U3RhY2tUcmFjZSQxKGVycm9yLCBzb3VyY2UpO1xufVxuZnVuY3Rpb24gY3JlYXRlRXhwZWN0UG9sbChleHBlY3QpIHtcblx0cmV0dXJuIGZ1bmN0aW9uIHBvbGwoZm4sIG9wdGlvbnMgPSB7fSkge1xuXHRcdGNvbnN0IGRlZmF1bHRzID0gZ2V0V29ya2VyU3RhdGUoKS5jb25maWcuZXhwZWN0Py5wb2xsID8/IHt9O1xuXHRcdGNvbnN0IHsgaW50ZXJ2YWwgPSBkZWZhdWx0cy5pbnRlcnZhbCA/PyA1MCwgdGltZW91dCA9IGRlZmF1bHRzLnRpbWVvdXQgPz8gMWUzLCBtZXNzYWdlIH0gPSBvcHRpb25zO1xuXHRcdC8vIEB0cy1leHBlY3QtZXJyb3IgcHJpdmF0ZSBwb2xsIGFjY2Vzc1xuXHRcdGNvbnN0IGFzc2VydGlvbiA9IGV4cGVjdChudWxsLCBtZXNzYWdlKS53aXRoQ29udGV4dCh7IHBvbGw6IHRydWUgfSk7XG5cdFx0Zm4gPSBmbi5iaW5kKGFzc2VydGlvbik7XG5cdFx0Y29uc3QgdGVzdCA9IGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJ2aXRlc3QtdGVzdFwiKTtcblx0XHRpZiAoIXRlc3QpIHRocm93IG5ldyBFcnJvcihcImV4cGVjdC5wb2xsKCkgbXVzdCBiZSBjYWxsZWQgaW5zaWRlIGEgdGVzdFwiKTtcblx0XHRjb25zdCBwcm94eSA9IG5ldyBQcm94eShhc3NlcnRpb24sIHsgZ2V0KHRhcmdldCwga2V5LCByZWNlaXZlcikge1xuXHRcdFx0Y29uc3QgYXNzZXJ0aW9uRnVuY3Rpb24gPSBSZWZsZWN0LmdldCh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpO1xuXHRcdFx0aWYgKHR5cGVvZiBhc3NlcnRpb25GdW5jdGlvbiAhPT0gXCJmdW5jdGlvblwiKSByZXR1cm4gYXNzZXJ0aW9uRnVuY3Rpb24gaW5zdGFuY2VvZiBjaGFpLkFzc2VydGlvbiA/IHByb3h5IDogYXNzZXJ0aW9uRnVuY3Rpb247XG5cdFx0XHRpZiAoa2V5ID09PSBcImFzc2VydFwiKSByZXR1cm4gYXNzZXJ0aW9uRnVuY3Rpb247XG5cdFx0XHRpZiAodHlwZW9mIGtleSA9PT0gXCJzdHJpbmdcIiAmJiB1bnN1cHBvcnRlZC5pbmNsdWRlcyhrZXkpKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYGV4cGVjdC5wb2xsKCkgaXMgbm90IHN1cHBvcnRlZCBpbiBjb21iaW5hdGlvbiB3aXRoIC4ke2tleX0oKS4gVXNlIHZpLndhaXRGb3IoKSBpZiB5b3VyIGFzc2VydGlvbiBjb25kaXRpb24gaXMgdW5zdGFibGUuYCk7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oLi4uYXJncykge1xuXHRcdFx0XHRjb25zdCBTVEFDS19UUkFDRV9FUlJPUiA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgRXJyb3IoXCJTVEFDS19UUkFDRV9FUlJPUlwiKTtcblx0XHRcdFx0Y29uc3QgcHJvbWlzZSA9IGFzeW5jICgpID0+IHtcblx0XHRcdFx0XHRjb25zdCB7IHNldFRpbWVvdXQsIGNsZWFyVGltZW91dCB9ID0gZ2V0U2FmZVRpbWVycygpO1xuXHRcdFx0XHRcdGxldCBleGVjdXRpb25QaGFzZSA9IFwiZm5cIjtcblx0XHRcdFx0XHRsZXQgaGFzVGltZWRPdXQgPSBmYWxzZTtcblx0XHRcdFx0XHRjb25zdCB0aW1lcklkID0gc2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRcdFx0XHRoYXNUaW1lZE91dCA9IHRydWU7XG5cdFx0XHRcdFx0fSwgdGltZW91dCk7XG5cdFx0XHRcdFx0Y2hhaS51dGlsLmZsYWcoYXNzZXJ0aW9uLCBcIl9uYW1lXCIsIGtleSk7XG5cdFx0XHRcdFx0Y29uc3Qgb25TZXR0bGVkID0gY2hhaS51dGlsLmZsYWcoYXNzZXJ0aW9uLCBcIl9wb2xsLm9uU2V0dGxlZFwiKTtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0d2hpbGUgKHRydWUpIHtcblx0XHRcdFx0XHRcdFx0Y29uc3QgaXNMYXN0QXR0ZW1wdCA9IGhhc1RpbWVkT3V0O1xuXHRcdFx0XHRcdFx0XHRpZiAoaXNMYXN0QXR0ZW1wdCkgY2hhaS51dGlsLmZsYWcoYXNzZXJ0aW9uLCBcIl9pc0xhc3RQb2xsQXR0ZW1wdFwiLCB0cnVlKTtcblx0XHRcdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdFx0XHRleGVjdXRpb25QaGFzZSA9IFwiZm5cIjtcblx0XHRcdFx0XHRcdFx0XHRjb25zdCBvYmogPSBhd2FpdCBmbigpO1xuXHRcdFx0XHRcdFx0XHRcdGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJvYmplY3RcIiwgb2JqKTtcblx0XHRcdFx0XHRcdFx0XHRleGVjdXRpb25QaGFzZSA9IFwiYXNzZXJ0aW9uXCI7XG5cdFx0XHRcdFx0XHRcdFx0Y29uc3Qgb3V0cHV0ID0gYXdhaXQgYXNzZXJ0aW9uRnVuY3Rpb24uY2FsbChhc3NlcnRpb24sIC4uLmFyZ3MpO1xuXHRcdFx0XHRcdFx0XHRcdGF3YWl0IG9uU2V0dGxlZD8uKHtcblx0XHRcdFx0XHRcdFx0XHRcdGFzc2VydGlvbixcblx0XHRcdFx0XHRcdFx0XHRcdHN0YXR1czogXCJwYXNzXCJcblx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gb3V0cHV0O1xuXHRcdFx0XHRcdFx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoaXNMYXN0QXR0ZW1wdCB8fCBleGVjdXRpb25QaGFzZSA9PT0gXCJhc3NlcnRpb25cIiAmJiBjaGFpLnV0aWwuZmxhZyhhc3NlcnRpb24sIFwiX3BvbGwuYXNzZXJ0X29uY2VcIikpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGF3YWl0IG9uU2V0dGxlZD8uKHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0YXNzZXJ0aW9uLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRzdGF0dXM6IFwiZmFpbFwiXG5cdFx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0XHRcdHRocm93V2l0aENhdXNlKGVyciwgU1RBQ0tfVFJBQ0VfRVJST1IpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRhd2FpdCBkZWxheShpbnRlcnZhbCwgc2V0VGltZW91dCk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9IGZpbmFsbHkge1xuXHRcdFx0XHRcdFx0Y2xlYXJUaW1lb3V0KHRpbWVySWQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHRcdFx0bGV0IGF3YWl0ZWQgPSBmYWxzZTtcblx0XHRcdFx0dGVzdC5vbkZpbmlzaGVkID8/PSBbXTtcblx0XHRcdFx0dGVzdC5vbkZpbmlzaGVkLnB1c2goKCkgPT4ge1xuXHRcdFx0XHRcdGlmICghYXdhaXRlZCkge1xuXHRcdFx0XHRcdFx0Y29uc3QgbmVnYXRlZCA9IGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJuZWdhdGVcIikgPyBcIm5vdC5cIiA6IFwiXCI7XG5cdFx0XHRcdFx0XHRjb25zdCBhc3NlcnRpb25TdHJpbmcgPSBgZXhwZWN0LiR7Y2hhaS51dGlsLmZsYWcoYXNzZXJ0aW9uLCBcIl9wb2xsLmVsZW1lbnRcIikgPyBcImVsZW1lbnQobG9jYXRvcilcIiA6IFwicG9sbChhc3NlcnRpb24pXCJ9LiR7bmVnYXRlZH0ke1N0cmluZyhrZXkpfSgpYDtcblx0XHRcdFx0XHRcdHRocm93IGNvcHlTdGFja1RyYWNlJDEoLyogQF9fUFVSRV9fICovIG5ldyBFcnJvcihgJHthc3NlcnRpb25TdHJpbmd9IHdhcyBub3QgYXdhaXRlZC4gVGhpcyBhc3NlcnRpb24gaXMgYXN5bmNocm9ub3VzIGFuZCBtdXN0IGJlIGF3YWl0ZWQ7IG90aGVyd2lzZSwgaXQgaXMgbm90IGV4ZWN1dGVkIHRvIGF2b2lkIHVuaGFuZGxlZCByZWplY3Rpb25zOlxcblxcbmF3YWl0ICR7YXNzZXJ0aW9uU3RyaW5nfVxcbmApLCBTVEFDS19UUkFDRV9FUlJPUik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdFx0bGV0IHJlc3VsdFByb21pc2U7XG5cdFx0XHRcdC8vIG9ubHkgLnRoZW4gaXMgZW5vdWdoIHRvIGNoZWNrIGF3YWl0ZWQsIGJ1dCB3ZSB0eXBlIHRoaXMgYXMgYFByb21pc2U8dm9pZD5gIGluIGdsb2JhbCB0eXBlc1xuXHRcdFx0XHQvLyBzbyBsZXQncyBmb2xsb3cgaXRcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHR0aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKSB7XG5cdFx0XHRcdFx0XHRhd2FpdGVkID0gdHJ1ZTtcblx0XHRcdFx0XHRcdHJldHVybiAocmVzdWx0UHJvbWlzZSB8fD0gcHJvbWlzZSgpKS50aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKTtcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdGNhdGNoKG9uUmVqZWN0ZWQpIHtcblx0XHRcdFx0XHRcdGF3YWl0ZWQgPSB0cnVlO1xuXHRcdFx0XHRcdFx0cmV0dXJuIChyZXN1bHRQcm9taXNlIHx8PSBwcm9taXNlKCkpLmNhdGNoKG9uUmVqZWN0ZWQpO1xuXHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0ZmluYWxseShvbkZpbmFsbHkpIHtcblx0XHRcdFx0XHRcdGF3YWl0ZWQgPSB0cnVlO1xuXHRcdFx0XHRcdFx0cmV0dXJuIChyZXN1bHRQcm9taXNlIHx8PSBwcm9taXNlKCkpLmZpbmFsbHkob25GaW5hbGx5KTtcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFtTeW1ib2wudG9TdHJpbmdUYWddOiBcIlByb21pc2VcIlxuXHRcdFx0XHR9O1xuXHRcdFx0fTtcblx0XHR9IH0pO1xuXHRcdHJldHVybiBwcm94eTtcblx0fTtcbn1cbmZ1bmN0aW9uIGNvcHlTdGFja1RyYWNlJDEodGFyZ2V0LCBzb3VyY2UpIHtcblx0aWYgKHNvdXJjZS5zdGFjayAhPT0gdm9pZCAwKSB0YXJnZXQuc3RhY2sgPSBzb3VyY2Uuc3RhY2sucmVwbGFjZShzb3VyY2UubWVzc2FnZSwgdGFyZ2V0Lm1lc3NhZ2UpO1xuXHRyZXR1cm4gdGFyZ2V0O1xufVxuXG5sZXQgX2NsaWVudDtcbmZ1bmN0aW9uIGdldFNuYXBzaG90Q2xpZW50KCkge1xuXHRpZiAoIV9jbGllbnQpIF9jbGllbnQgPSBuZXcgU25hcHNob3RDbGllbnQoeyBpc0VxdWFsOiAocmVjZWl2ZWQsIGV4cGVjdGVkKSA9PiB7XG5cdFx0cmV0dXJuIGVxdWFscyhyZWNlaXZlZCwgZXhwZWN0ZWQsIFtpdGVyYWJsZUVxdWFsaXR5LCBzdWJzZXRFcXVhbGl0eV0pO1xuXHR9IH0pO1xuXHRyZXR1cm4gX2NsaWVudDtcbn1cbmZ1bmN0aW9uIGdldEVycm9yKGV4cGVjdGVkLCBwcm9taXNlKSB7XG5cdGlmICh0eXBlb2YgZXhwZWN0ZWQgIT09IFwiZnVuY3Rpb25cIikge1xuXHRcdGlmICghcHJvbWlzZSkgdGhyb3cgbmV3IEVycm9yKGBleHBlY3RlZCBtdXN0IGJlIGEgZnVuY3Rpb24sIHJlY2VpdmVkICR7dHlwZW9mIGV4cGVjdGVkfWApO1xuXHRcdC8vIHdoZW4gXCJwcm9taXNlZFwiLCBpdCByZWNlaXZlcyB0aHJvd24gZXJyb3Jcblx0XHRyZXR1cm4gZXhwZWN0ZWQ7XG5cdH1cblx0dHJ5IHtcblx0XHRleHBlY3RlZCgpO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0cmV0dXJuIGU7XG5cdH1cblx0dGhyb3cgbmV3IEVycm9yKFwic25hcHNob3QgZnVuY3Rpb24gZGlkbid0IHRocm93XCIpO1xufVxuZnVuY3Rpb24gZ2V0VGVzdE5hbWVzKHRlc3QpIHtcblx0cmV0dXJuIHtcblx0XHRmaWxlcGF0aDogdGVzdC5maWxlLmZpbGVwYXRoLFxuXHRcdG5hbWU6IGdldE5hbWVzKHRlc3QpLnNsaWNlKDEpLmpvaW4oXCIgPiBcIiksXG5cdFx0dGVzdElkOiB0ZXN0LmlkXG5cdH07XG59XG5jb25zdCBTbmFwc2hvdFBsdWdpbiA9IChjaGFpLCB1dGlscykgPT4ge1xuXHRmdW5jdGlvbiBnZXRUZXN0KGFzc2VydGlvbk5hbWUsIG9iaikge1xuXHRcdGNvbnN0IHRlc3QgPSB1dGlscy5mbGFnKG9iaiwgXCJ2aXRlc3QtdGVzdFwiKTtcblx0XHRpZiAoIXRlc3QpIHRocm93IG5ldyBFcnJvcihgJyR7YXNzZXJ0aW9uTmFtZX0nIGNhbm5vdCBiZSB1c2VkIHdpdGhvdXQgdGVzdCBjb250ZXh0YCk7XG5cdFx0cmV0dXJuIHRlc3Q7XG5cdH1cblx0Zm9yIChjb25zdCBrZXkgb2YgW1wibWF0Y2hTbmFwc2hvdFwiLCBcInRvTWF0Y2hTbmFwc2hvdFwiXSkgdXRpbHMuYWRkTWV0aG9kKGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwga2V5LCB3cmFwQXNzZXJ0aW9uKHV0aWxzLCBrZXksIGZ1bmN0aW9uKHByb3BlcnRpZXMsIG1lc3NhZ2UpIHtcblx0XHR1dGlscy5mbGFnKHRoaXMsIFwiX25hbWVcIiwga2V5KTtcblx0XHRpZiAodXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKSkgdGhyb3cgbmV3IEVycm9yKGAke2tleX0gY2Fubm90IGJlIHVzZWQgd2l0aCBcIm5vdFwiYCk7XG5cdFx0Y29uc3QgZXhwZWN0ZWQgPSB1dGlscy5mbGFnKHRoaXMsIFwib2JqZWN0XCIpO1xuXHRcdGNvbnN0IHRlc3QgPSBnZXRUZXN0KGtleSwgdGhpcyk7XG5cdFx0aWYgKHR5cGVvZiBwcm9wZXJ0aWVzID09PSBcInN0cmluZ1wiICYmIHR5cGVvZiBtZXNzYWdlID09PSBcInVuZGVmaW5lZFwiKSB7XG5cdFx0XHRtZXNzYWdlID0gcHJvcGVydGllcztcblx0XHRcdHByb3BlcnRpZXMgPSB2b2lkIDA7XG5cdFx0fVxuXHRcdGNvbnN0IGVycm9yTWVzc2FnZSA9IHV0aWxzLmZsYWcodGhpcywgXCJtZXNzYWdlXCIpO1xuXHRcdGdldFNuYXBzaG90Q2xpZW50KCkuYXNzZXJ0KHtcblx0XHRcdHJlY2VpdmVkOiBleHBlY3RlZCxcblx0XHRcdG1lc3NhZ2UsXG5cdFx0XHRpc0lubGluZTogZmFsc2UsXG5cdFx0XHRwcm9wZXJ0aWVzLFxuXHRcdFx0ZXJyb3JNZXNzYWdlLFxuXHRcdFx0Li4uZ2V0VGVzdE5hbWVzKHRlc3QpXG5cdFx0fSk7XG5cdH0pKTtcblx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgXCJ0b01hdGNoRmlsZVNuYXBzaG90XCIsIGZ1bmN0aW9uKGZpbGUsIG1lc3NhZ2UpIHtcblx0XHR1dGlscy5mbGFnKHRoaXMsIFwiX25hbWVcIiwgXCJ0b01hdGNoRmlsZVNuYXBzaG90XCIpO1xuXHRcdGlmICh1dGlscy5mbGFnKHRoaXMsIFwibmVnYXRlXCIpKSB0aHJvdyBuZXcgRXJyb3IoXCJ0b01hdGNoRmlsZVNuYXBzaG90IGNhbm5vdCBiZSB1c2VkIHdpdGggXFxcIm5vdFxcXCJcIik7XG5cdFx0Y29uc3QgZXJyb3IgPSAvKiBAX19QVVJFX18gKi8gbmV3IEVycm9yKFwicmVzb2x2ZXNcIik7XG5cdFx0Y29uc3QgZXhwZWN0ZWQgPSB1dGlscy5mbGFnKHRoaXMsIFwib2JqZWN0XCIpO1xuXHRcdGNvbnN0IHRlc3QgPSBnZXRUZXN0KFwidG9NYXRjaEZpbGVTbmFwc2hvdFwiLCB0aGlzKTtcblx0XHRjb25zdCBlcnJvck1lc3NhZ2UgPSB1dGlscy5mbGFnKHRoaXMsIFwibWVzc2FnZVwiKTtcblx0XHRyZXR1cm4gcmVjb3JkQXN5bmNFeHBlY3QodGVzdCwgZ2V0U25hcHNob3RDbGllbnQoKS5hc3NlcnRSYXcoe1xuXHRcdFx0cmVjZWl2ZWQ6IGV4cGVjdGVkLFxuXHRcdFx0bWVzc2FnZSxcblx0XHRcdGlzSW5saW5lOiBmYWxzZSxcblx0XHRcdHJhd1NuYXBzaG90OiB7IGZpbGUgfSxcblx0XHRcdGVycm9yTWVzc2FnZSxcblx0XHRcdC4uLmdldFRlc3ROYW1lcyh0ZXN0KVxuXHRcdH0pLCBjcmVhdGVBc3NlcnRpb25NZXNzYWdlKHV0aWxzLCB0aGlzLCB0cnVlKSwgZXJyb3IsIHV0aWxzLmZsYWcodGhpcywgXCJzb2Z0XCIpKTtcblx0fSk7XG5cdHV0aWxzLmFkZE1ldGhvZChjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsIFwidG9NYXRjaElubGluZVNuYXBzaG90XCIsIHdyYXBBc3NlcnRpb24odXRpbHMsIFwidG9NYXRjaElubGluZVNuYXBzaG90XCIsIGZ1bmN0aW9uIF9fSU5MSU5FX1NOQVBTSE9UX09GRlNFVF8zX18ocHJvcGVydGllcywgaW5saW5lU25hcHNob3QsIG1lc3NhZ2UpIHtcblx0XHR1dGlscy5mbGFnKHRoaXMsIFwiX25hbWVcIiwgXCJ0b01hdGNoSW5saW5lU25hcHNob3RcIik7XG5cdFx0aWYgKHV0aWxzLmZsYWcodGhpcywgXCJuZWdhdGVcIikpIHRocm93IG5ldyBFcnJvcihcInRvTWF0Y2hJbmxpbmVTbmFwc2hvdCBjYW5ub3QgYmUgdXNlZCB3aXRoIFxcXCJub3RcXFwiXCIpO1xuXHRcdGNvbnN0IHRlc3QgPSBnZXRUZXN0KFwidG9NYXRjaElubGluZVNuYXBzaG90XCIsIHRoaXMpO1xuXHRcdGNvbnN0IGV4cGVjdGVkID0gdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKTtcblx0XHRjb25zdCBlcnJvciA9IHV0aWxzLmZsYWcodGhpcywgXCJlcnJvclwiKTtcblx0XHRpZiAodHlwZW9mIHByb3BlcnRpZXMgPT09IFwic3RyaW5nXCIpIHtcblx0XHRcdG1lc3NhZ2UgPSBpbmxpbmVTbmFwc2hvdDtcblx0XHRcdGlubGluZVNuYXBzaG90ID0gcHJvcGVydGllcztcblx0XHRcdHByb3BlcnRpZXMgPSB2b2lkIDA7XG5cdFx0fVxuXHRcdGlmIChpbmxpbmVTbmFwc2hvdCkgaW5saW5lU25hcHNob3QgPSBzdHJpcFNuYXBzaG90SW5kZW50YXRpb24oaW5saW5lU25hcHNob3QpO1xuXHRcdGNvbnN0IGVycm9yTWVzc2FnZSA9IHV0aWxzLmZsYWcodGhpcywgXCJtZXNzYWdlXCIpO1xuXHRcdGdldFNuYXBzaG90Q2xpZW50KCkuYXNzZXJ0KHtcblx0XHRcdHJlY2VpdmVkOiBleHBlY3RlZCxcblx0XHRcdG1lc3NhZ2UsXG5cdFx0XHRpc0lubGluZTogdHJ1ZSxcblx0XHRcdHByb3BlcnRpZXMsXG5cdFx0XHRpbmxpbmVTbmFwc2hvdCxcblx0XHRcdGVycm9yLFxuXHRcdFx0ZXJyb3JNZXNzYWdlLFxuXHRcdFx0Li4uZ2V0VGVzdE5hbWVzKHRlc3QpXG5cdFx0fSk7XG5cdH0pKTtcblx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgXCJ0b1Rocm93RXJyb3JNYXRjaGluZ1NuYXBzaG90XCIsIHdyYXBBc3NlcnRpb24odXRpbHMsIFwidG9UaHJvd0Vycm9yTWF0Y2hpbmdTbmFwc2hvdFwiLCBmdW5jdGlvbihwcm9wZXJ0aWVzLCBtZXNzYWdlKSB7XG5cdFx0dXRpbHMuZmxhZyh0aGlzLCBcIl9uYW1lXCIsIFwidG9UaHJvd0Vycm9yTWF0Y2hpbmdTbmFwc2hvdFwiKTtcblx0XHRpZiAodXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKSkgdGhyb3cgbmV3IEVycm9yKFwidG9UaHJvd0Vycm9yTWF0Y2hpbmdTbmFwc2hvdCBjYW5ub3QgYmUgdXNlZCB3aXRoIFxcXCJub3RcXFwiXCIpO1xuXHRcdGNvbnN0IGV4cGVjdGVkID0gdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKTtcblx0XHRjb25zdCB0ZXN0ID0gZ2V0VGVzdChcInRvVGhyb3dFcnJvck1hdGNoaW5nU25hcHNob3RcIiwgdGhpcyk7XG5cdFx0Y29uc3QgcHJvbWlzZSA9IHV0aWxzLmZsYWcodGhpcywgXCJwcm9taXNlXCIpO1xuXHRcdGNvbnN0IGVycm9yTWVzc2FnZSA9IHV0aWxzLmZsYWcodGhpcywgXCJtZXNzYWdlXCIpO1xuXHRcdGdldFNuYXBzaG90Q2xpZW50KCkuYXNzZXJ0KHtcblx0XHRcdHJlY2VpdmVkOiBnZXRFcnJvcihleHBlY3RlZCwgcHJvbWlzZSksXG5cdFx0XHRtZXNzYWdlLFxuXHRcdFx0ZXJyb3JNZXNzYWdlLFxuXHRcdFx0Li4uZ2V0VGVzdE5hbWVzKHRlc3QpXG5cdFx0fSk7XG5cdH0pKTtcblx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgXCJ0b1Rocm93RXJyb3JNYXRjaGluZ0lubGluZVNuYXBzaG90XCIsIHdyYXBBc3NlcnRpb24odXRpbHMsIFwidG9UaHJvd0Vycm9yTWF0Y2hpbmdJbmxpbmVTbmFwc2hvdFwiLCBmdW5jdGlvbiBfX0lOTElORV9TTkFQU0hPVF9PRkZTRVRfM19fKGlubGluZVNuYXBzaG90LCBtZXNzYWdlKSB7XG5cdFx0aWYgKHV0aWxzLmZsYWcodGhpcywgXCJuZWdhdGVcIikpIHRocm93IG5ldyBFcnJvcihcInRvVGhyb3dFcnJvck1hdGNoaW5nSW5saW5lU25hcHNob3QgY2Fubm90IGJlIHVzZWQgd2l0aCBcXFwibm90XFxcIlwiKTtcblx0XHRjb25zdCB0ZXN0ID0gZ2V0VGVzdChcInRvVGhyb3dFcnJvck1hdGNoaW5nSW5saW5lU25hcHNob3RcIiwgdGhpcyk7XG5cdFx0Y29uc3QgZXhwZWN0ZWQgPSB1dGlscy5mbGFnKHRoaXMsIFwib2JqZWN0XCIpO1xuXHRcdGNvbnN0IGVycm9yID0gdXRpbHMuZmxhZyh0aGlzLCBcImVycm9yXCIpO1xuXHRcdGNvbnN0IHByb21pc2UgPSB1dGlscy5mbGFnKHRoaXMsIFwicHJvbWlzZVwiKTtcblx0XHRjb25zdCBlcnJvck1lc3NhZ2UgPSB1dGlscy5mbGFnKHRoaXMsIFwibWVzc2FnZVwiKTtcblx0XHRpZiAoaW5saW5lU25hcHNob3QpIGlubGluZVNuYXBzaG90ID0gc3RyaXBTbmFwc2hvdEluZGVudGF0aW9uKGlubGluZVNuYXBzaG90KTtcblx0XHRnZXRTbmFwc2hvdENsaWVudCgpLmFzc2VydCh7XG5cdFx0XHRyZWNlaXZlZDogZ2V0RXJyb3IoZXhwZWN0ZWQsIHByb21pc2UpLFxuXHRcdFx0bWVzc2FnZSxcblx0XHRcdGlubGluZVNuYXBzaG90LFxuXHRcdFx0aXNJbmxpbmU6IHRydWUsXG5cdFx0XHRlcnJvcixcblx0XHRcdGVycm9yTWVzc2FnZSxcblx0XHRcdC4uLmdldFRlc3ROYW1lcyh0ZXN0KVxuXHRcdH0pO1xuXHR9KSk7XG5cdHV0aWxzLmFkZE1ldGhvZChjaGFpLmV4cGVjdCwgXCJhZGRTbmFwc2hvdFNlcmlhbGl6ZXJcIiwgYWRkU2VyaWFsaXplcik7XG59O1xuXG5jaGFpLnVzZShKZXN0RXh0ZW5kKTtcbmNoYWkudXNlKEplc3RDaGFpRXhwZWN0KTtcbmNoYWkudXNlKENoYWlTdHlsZUFzc2VydGlvbnMpO1xuY2hhaS51c2UoU25hcHNob3RQbHVnaW4pO1xuY2hhaS51c2UoSmVzdEFzeW1tZXRyaWNNYXRjaGVycyk7XG5cbmZ1bmN0aW9uIGNyZWF0ZUV4cGVjdCh0ZXN0KSB7XG5cdGNvbnN0IGV4cGVjdCA9ICgodmFsdWUsIG1lc3NhZ2UpID0+IHtcblx0XHRjb25zdCB7IGFzc2VydGlvbkNhbGxzIH0gPSBnZXRTdGF0ZShleHBlY3QpO1xuXHRcdHNldFN0YXRlKHsgYXNzZXJ0aW9uQ2FsbHM6IGFzc2VydGlvbkNhbGxzICsgMSB9LCBleHBlY3QpO1xuXHRcdGNvbnN0IGFzc2VydCA9IGNoYWkuZXhwZWN0KHZhbHVlLCBtZXNzYWdlKTtcblx0XHRjb25zdCBfdGVzdCA9IHRlc3QgfHwgZ2V0Q3VycmVudFRlc3QoKTtcblx0XHRpZiAoX3Rlc3QpXG4gLy8gQHRzLWV4cGVjdC1lcnJvciBpbnRlcm5hbFxuXHRcdHJldHVybiBhc3NlcnQud2l0aFRlc3QoX3Rlc3QpO1xuXHRcdGVsc2UgcmV0dXJuIGFzc2VydDtcblx0fSk7XG5cdE9iamVjdC5hc3NpZ24oZXhwZWN0LCBjaGFpLmV4cGVjdCk7XG5cdE9iamVjdC5hc3NpZ24oZXhwZWN0LCBnbG9iYWxUaGlzW0FTWU1NRVRSSUNfTUFUQ0hFUlNfT0JKRUNUXSk7XG5cdGV4cGVjdC5nZXRTdGF0ZSA9ICgpID0+IGdldFN0YXRlKGV4cGVjdCk7XG5cdGV4cGVjdC5zZXRTdGF0ZSA9IChzdGF0ZSkgPT4gc2V0U3RhdGUoc3RhdGUsIGV4cGVjdCk7XG5cdC8vIEB0cy1leHBlY3QtZXJyb3IgZ2xvYmFsIGlzIG5vdCB0eXBlZFxuXHRjb25zdCBnbG9iYWxTdGF0ZSA9IGdldFN0YXRlKGdsb2JhbFRoaXNbR0xPQkFMX0VYUEVDVF0pIHx8IHt9O1xuXHRzZXRTdGF0ZSh7XG5cdFx0Li4uZ2xvYmFsU3RhdGUsXG5cdFx0YXNzZXJ0aW9uQ2FsbHM6IDAsXG5cdFx0aXNFeHBlY3RpbmdBc3NlcnRpb25zOiBmYWxzZSxcblx0XHRpc0V4cGVjdGluZ0Fzc2VydGlvbnNFcnJvcjogbnVsbCxcblx0XHRleHBlY3RlZEFzc2VydGlvbnNOdW1iZXI6IG51bGwsXG5cdFx0ZXhwZWN0ZWRBc3NlcnRpb25zTnVtYmVyRXJyb3JHZW46IG51bGwsXG5cdFx0Z2V0IHRlc3RQYXRoKCkge1xuXHRcdFx0cmV0dXJuIGdldFdvcmtlclN0YXRlKCkuZmlsZXBhdGg7XG5cdFx0fSxcblx0XHRjdXJyZW50VGVzdE5hbWU6IHRlc3QgPyB0ZXN0LmZ1bGxUZXN0TmFtZSA/PyBcIlwiIDogZ2xvYmFsU3RhdGUuY3VycmVudFRlc3ROYW1lXG5cdH0sIGV4cGVjdCk7XG5cdGV4cGVjdC5hc3NlcnQgPSBjaGFpLmFzc2VydDtcblx0Ly8gQHRzLWV4cGVjdC1lcnJvciB1bnR5cGVkXG5cdGV4cGVjdC5leHRlbmQgPSAobWF0Y2hlcnMpID0+IGNoYWkuZXhwZWN0LmV4dGVuZChleHBlY3QsIG1hdGNoZXJzKTtcblx0ZXhwZWN0LmFkZEVxdWFsaXR5VGVzdGVycyA9IChjdXN0b21UZXN0ZXJzKSA9PiBhZGRDdXN0b21FcXVhbGl0eVRlc3RlcnMoY3VzdG9tVGVzdGVycyk7XG5cdGV4cGVjdC5zb2Z0ID0gKC4uLmFyZ3MpID0+IHtcblx0XHQvLyBAdHMtZXhwZWN0LWVycm9yIHByaXZhdGUgc29mdCBhY2Nlc3Ncblx0XHRyZXR1cm4gZXhwZWN0KC4uLmFyZ3MpLndpdGhDb250ZXh0KHsgc29mdDogdHJ1ZSB9KTtcblx0fTtcblx0ZXhwZWN0LnBvbGwgPSBjcmVhdGVFeHBlY3RQb2xsKGV4cGVjdCk7XG5cdGV4cGVjdC51bnJlYWNoYWJsZSA9IChtZXNzYWdlKSA9PiB7XG5cdFx0Y2hhaS5hc3NlcnQuZmFpbChgZXhwZWN0ZWQke21lc3NhZ2UgPyBgIFwiJHttZXNzYWdlfVwiIGAgOiBcIiBcIn1ub3QgdG8gYmUgcmVhY2hlZGApO1xuXHR9O1xuXHRmdW5jdGlvbiBhc3NlcnRpb25zKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgZXJyb3JHZW4gPSAoKSA9PiAvKiBAX19QVVJFX18gKi8gbmV3IEVycm9yKGBleHBlY3RlZCBudW1iZXIgb2YgYXNzZXJ0aW9ucyB0byBiZSAke2V4cGVjdGVkfSwgYnV0IGdvdCAke2V4cGVjdC5nZXRTdGF0ZSgpLmFzc2VydGlvbkNhbGxzfWApO1xuXHRcdGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UoZXJyb3JHZW4oKSwgYXNzZXJ0aW9ucyk7XG5cdFx0ZXhwZWN0LnNldFN0YXRlKHtcblx0XHRcdGV4cGVjdGVkQXNzZXJ0aW9uc051bWJlcjogZXhwZWN0ZWQsXG5cdFx0XHRleHBlY3RlZEFzc2VydGlvbnNOdW1iZXJFcnJvckdlbjogZXJyb3JHZW5cblx0XHR9KTtcblx0fVxuXHRmdW5jdGlvbiBoYXNBc3NlcnRpb25zKCkge1xuXHRcdGNvbnN0IGVycm9yID0gLyogQF9fUFVSRV9fICovIG5ldyBFcnJvcihcImV4cGVjdGVkIGFueSBudW1iZXIgb2YgYXNzZXJ0aW9uLCBidXQgZ290IG5vbmVcIik7XG5cdFx0aWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZShlcnJvciwgaGFzQXNzZXJ0aW9ucyk7XG5cdFx0ZXhwZWN0LnNldFN0YXRlKHtcblx0XHRcdGlzRXhwZWN0aW5nQXNzZXJ0aW9uczogdHJ1ZSxcblx0XHRcdGlzRXhwZWN0aW5nQXNzZXJ0aW9uc0Vycm9yOiBlcnJvclxuXHRcdH0pO1xuXHR9XG5cdGNoYWkudXRpbC5hZGRNZXRob2QoZXhwZWN0LCBcImFzc2VydGlvbnNcIiwgYXNzZXJ0aW9ucyk7XG5cdGNoYWkudXRpbC5hZGRNZXRob2QoZXhwZWN0LCBcImhhc0Fzc2VydGlvbnNcIiwgaGFzQXNzZXJ0aW9ucyk7XG5cdGV4cGVjdC5leHRlbmQoY3VzdG9tTWF0Y2hlcnMpO1xuXHRyZXR1cm4gZXhwZWN0O1xufVxuY29uc3QgZ2xvYmFsRXhwZWN0ID0gY3JlYXRlRXhwZWN0KCk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsVGhpcywgR0xPQkFMX0VYUEVDVCwge1xuXHR2YWx1ZTogZ2xvYmFsRXhwZWN0LFxuXHR3cml0YWJsZTogdHJ1ZSxcblx0Y29uZmlndXJhYmxlOiB0cnVlXG59KTtcbmNvbnN0IGFzc2VydCA9IGNoYWkuYXNzZXJ0O1xuY29uc3Qgc2hvdWxkID0gY2hhaS5zaG91bGQ7XG5cbi8qKlxuKiBHaXZlcyBhY2Nlc3MgdG8gaW5qZWN0ZWQgY29udGV4dCBwcm92aWRlZCBmcm9tIHRoZSBtYWluIHRocmVhZC5cbiogVGhpcyB1c3VhbGx5IHJldHVybnMgYSB2YWx1ZSBwcm92aWRlZCBieSBgZ2xvYmFsU2V0dXBgIG9yIGFuIGV4dGVybmFsIGxpYnJhcnkuXG4qL1xuZnVuY3Rpb24gaW5qZWN0KGtleSkge1xuXHRyZXR1cm4gZ2V0V29ya2VyU3RhdGUoKS5wcm92aWRlZENvbnRleHRba2V5XTtcbn1cblxudmFyIGZha2VUaW1lcnNTcmMgPSB7fTtcblxudmFyIGdsb2JhbDtcbnZhciBoYXNSZXF1aXJlZEdsb2JhbDtcblxuZnVuY3Rpb24gcmVxdWlyZUdsb2JhbCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEdsb2JhbCkgcmV0dXJuIGdsb2JhbDtcblx0aGFzUmVxdWlyZWRHbG9iYWwgPSAxO1xuXG5cdC8qKlxuXHQgKiBBIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdFxuXHQgKiBAdHlwZSB7b2JqZWN0fSBnbG9iYWxPYmplY3Rcblx0ICovXG5cdHZhciBnbG9iYWxPYmplY3Q7XG5cblx0LyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cblx0aWYgKHR5cGVvZiBjb21tb25qc0dsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuXHQgICAgLy8gTm9kZVxuXHQgICAgZ2xvYmFsT2JqZWN0ID0gY29tbW9uanNHbG9iYWw7XG5cdH0gZWxzZSBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuXHQgICAgLy8gQnJvd3NlclxuXHQgICAgZ2xvYmFsT2JqZWN0ID0gd2luZG93O1xuXHR9IGVsc2Uge1xuXHQgICAgLy8gV2ViV29ya2VyXG5cdCAgICBnbG9iYWxPYmplY3QgPSBzZWxmO1xuXHR9XG5cblx0Z2xvYmFsID0gZ2xvYmFsT2JqZWN0O1xuXHRyZXR1cm4gZ2xvYmFsO1xufVxuXG52YXIgdGhyb3dzT25Qcm90b18xO1xudmFyIGhhc1JlcXVpcmVkVGhyb3dzT25Qcm90bztcblxuZnVuY3Rpb24gcmVxdWlyZVRocm93c09uUHJvdG8gKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRUaHJvd3NPblByb3RvKSByZXR1cm4gdGhyb3dzT25Qcm90b18xO1xuXHRoYXNSZXF1aXJlZFRocm93c09uUHJvdG8gPSAxO1xuXG5cdC8qKlxuXHQgKiBJcyB0cnVlIHdoZW4gdGhlIGVudmlyb25tZW50IGNhdXNlcyBhbiBlcnJvciB0byBiZSB0aHJvd24gZm9yIGFjY2Vzc2luZyB0aGVcblx0ICogX19wcm90b19fIHByb3BlcnR5LlxuXHQgKiBUaGlzIGlzIG5lY2Vzc2FyeSBpbiBvcmRlciB0byBzdXBwb3J0IGBub2RlIC0tZGlzYWJsZS1wcm90bz10aHJvd2AuXG5cdCAqXG5cdCAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9PYmplY3QvcHJvdG9cblx0ICogQHR5cGUge2Jvb2xlYW59XG5cdCAqL1xuXHRsZXQgdGhyb3dzT25Qcm90bztcblx0dHJ5IHtcblx0ICAgIGNvbnN0IG9iamVjdCA9IHt9O1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXByb3RvLCBuby11bnVzZWQtZXhwcmVzc2lvbnNcblx0ICAgIG9iamVjdC5fX3Byb3RvX187XG5cdCAgICB0aHJvd3NPblByb3RvID0gZmFsc2U7XG5cdH0gY2F0Y2ggKF8pIHtcblx0ICAgIC8vIFRoaXMgYnJhbmNoIGlzIGNvdmVyZWQgd2hlbiB0ZXN0cyBhcmUgcnVuIHdpdGggYC0tZGlzYWJsZS1wcm90bz10aHJvd2AsXG5cdCAgICAvLyBob3dldmVyIHdlIGNhbiB0ZXN0IGJvdGggYnJhbmNoZXMgYXQgdGhlIHNhbWUgdGltZSwgc28gdGhpcyBpcyBpZ25vcmVkXG5cdCAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuXHQgICAgdGhyb3dzT25Qcm90byA9IHRydWU7XG5cdH1cblxuXHR0aHJvd3NPblByb3RvXzEgPSB0aHJvd3NPblByb3RvO1xuXHRyZXR1cm4gdGhyb3dzT25Qcm90b18xO1xufVxuXG52YXIgY29weVByb3RvdHlwZU1ldGhvZHM7XG52YXIgaGFzUmVxdWlyZWRDb3B5UHJvdG90eXBlTWV0aG9kcztcblxuZnVuY3Rpb24gcmVxdWlyZUNvcHlQcm90b3R5cGVNZXRob2RzICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkQ29weVByb3RvdHlwZU1ldGhvZHMpIHJldHVybiBjb3B5UHJvdG90eXBlTWV0aG9kcztcblx0aGFzUmVxdWlyZWRDb3B5UHJvdG90eXBlTWV0aG9kcyA9IDE7XG5cblx0dmFyIGNhbGwgPSBGdW5jdGlvbi5jYWxsO1xuXHR2YXIgdGhyb3dzT25Qcm90byA9IHJlcXVpcmVUaHJvd3NPblByb3RvKCk7XG5cblx0dmFyIGRpc2FsbG93ZWRQcm9wZXJ0aWVzID0gW1xuXHQgICAgLy8gaWdub3JlIHNpemUgYmVjYXVzZSBpdCB0aHJvd3MgZnJvbSBNYXBcblx0ICAgIFwic2l6ZVwiLFxuXHQgICAgXCJjYWxsZXJcIixcblx0ICAgIFwiY2FsbGVlXCIsXG5cdCAgICBcImFyZ3VtZW50c1wiLFxuXHRdO1xuXG5cdC8vIFRoaXMgYnJhbmNoIGlzIGNvdmVyZWQgd2hlbiB0ZXN0cyBhcmUgcnVuIHdpdGggYC0tZGlzYWJsZS1wcm90bz10aHJvd2AsXG5cdC8vIGhvd2V2ZXIgd2UgY2FuIHRlc3QgYm90aCBicmFuY2hlcyBhdCB0aGUgc2FtZSB0aW1lLCBzbyB0aGlzIGlzIGlnbm9yZWRcblx0LyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0aWYgKHRocm93c09uUHJvdG8pIHtcblx0ICAgIGRpc2FsbG93ZWRQcm9wZXJ0aWVzLnB1c2goXCJfX3Byb3RvX19cIik7XG5cdH1cblxuXHRjb3B5UHJvdG90eXBlTWV0aG9kcyA9IGZ1bmN0aW9uIGNvcHlQcm90b3R5cGVNZXRob2RzKHByb3RvdHlwZSkge1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBzaW5vbmpzL25vLXByb3RvdHlwZS1tZXRob2RzL25vLXByb3RvdHlwZS1tZXRob2RzXG5cdCAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMocHJvdG90eXBlKS5yZWR1Y2UoZnVuY3Rpb24gKFxuXHQgICAgICAgIHJlc3VsdCxcblx0ICAgICAgICBuYW1lXG5cdCAgICApIHtcblx0ICAgICAgICBpZiAoZGlzYWxsb3dlZFByb3BlcnRpZXMuaW5jbHVkZXMobmFtZSkpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAodHlwZW9mIHByb3RvdHlwZVtuYW1lXSAhPT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgcmVzdWx0W25hbWVdID0gY2FsbC5iaW5kKHByb3RvdHlwZVtuYW1lXSk7XG5cblx0ICAgICAgICByZXR1cm4gcmVzdWx0O1xuXHQgICAgfSxcblx0ICAgIE9iamVjdC5jcmVhdGUobnVsbCkpO1xuXHR9O1xuXHRyZXR1cm4gY29weVByb3RvdHlwZU1ldGhvZHM7XG59XG5cbnZhciBhcnJheTtcbnZhciBoYXNSZXF1aXJlZEFycmF5O1xuXG5mdW5jdGlvbiByZXF1aXJlQXJyYXkgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRBcnJheSkgcmV0dXJuIGFycmF5O1xuXHRoYXNSZXF1aXJlZEFycmF5ID0gMTtcblxuXHR2YXIgY29weVByb3RvdHlwZSA9IHJlcXVpcmVDb3B5UHJvdG90eXBlTWV0aG9kcygpO1xuXG5cdGFycmF5ID0gY29weVByb3RvdHlwZShBcnJheS5wcm90b3R5cGUpO1xuXHRyZXR1cm4gYXJyYXk7XG59XG5cbnZhciBjYWxsZWRJbk9yZGVyXzE7XG52YXIgaGFzUmVxdWlyZWRDYWxsZWRJbk9yZGVyO1xuXG5mdW5jdGlvbiByZXF1aXJlQ2FsbGVkSW5PcmRlciAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZENhbGxlZEluT3JkZXIpIHJldHVybiBjYWxsZWRJbk9yZGVyXzE7XG5cdGhhc1JlcXVpcmVkQ2FsbGVkSW5PcmRlciA9IDE7XG5cblx0dmFyIGV2ZXJ5ID0gcmVxdWlyZUFycmF5KCkuZXZlcnk7XG5cblx0LyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRmdW5jdGlvbiBoYXNDYWxsc0xlZnQoY2FsbE1hcCwgc3B5KSB7XG5cdCAgICBpZiAoY2FsbE1hcFtzcHkuaWRdID09PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICBjYWxsTWFwW3NweS5pZF0gPSAwO1xuXHQgICAgfVxuXG5cdCAgICByZXR1cm4gY2FsbE1hcFtzcHkuaWRdIDwgc3B5LmNhbGxDb3VudDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0ZnVuY3Rpb24gY2hlY2tBZGphY2VudENhbGxzKGNhbGxNYXAsIHNweSwgaW5kZXgsIHNwaWVzKSB7XG5cdCAgICB2YXIgY2FsbGVkQmVmb3JlTmV4dCA9IHRydWU7XG5cblx0ICAgIGlmIChpbmRleCAhPT0gc3BpZXMubGVuZ3RoIC0gMSkge1xuXHQgICAgICAgIGNhbGxlZEJlZm9yZU5leHQgPSBzcHkuY2FsbGVkQmVmb3JlKHNwaWVzW2luZGV4ICsgMV0pO1xuXHQgICAgfVxuXG5cdCAgICBpZiAoaGFzQ2FsbHNMZWZ0KGNhbGxNYXAsIHNweSkgJiYgY2FsbGVkQmVmb3JlTmV4dCkge1xuXHQgICAgICAgIGNhbGxNYXBbc3B5LmlkXSArPSAxO1xuXHQgICAgICAgIHJldHVybiB0cnVlO1xuXHQgICAgfVxuXG5cdCAgICByZXR1cm4gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogQSBTaW5vbiBwcm94eSBvYmplY3QgKGZha2UsIHNweSwgc3R1Yilcblx0ICogQHR5cGVkZWYge29iamVjdH0gU2lub25Qcm94eVxuXHQgKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBjYWxsZWRCZWZvcmUgLSBBIG1ldGhvZCB0aGF0IGRldGVybWluZXMgaWYgdGhpcyBwcm94eSB3YXMgY2FsbGVkIGJlZm9yZSBhbm90aGVyIG9uZVxuXHQgKiBAcHJvcGVydHkge3N0cmluZ30gaWQgLSBTb21lIGlkXG5cdCAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjYWxsQ291bnQgLSBOdW1iZXIgb2YgdGltZXMgdGhpcyBwcm94eSBoYXMgYmVlbiBjYWxsZWRcblx0ICovXG5cblx0LyoqXG5cdCAqIFJldHVybnMgdHJ1ZSB3aGVuIHRoZSBzcGllcyBoYXZlIGJlZW4gY2FsbGVkIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgc3VwcGxpZWQgaW5cblx0ICogQHBhcmFtICB7U2lub25Qcm94eVtdIHwgU2lub25Qcm94eX0gc3BpZXMgQW4gYXJyYXkgb2YgcHJveGllcywgb3Igc2V2ZXJhbCBwcm94aWVzIGFzIGFyZ3VtZW50c1xuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSB3aGVuIHNwaWVzIGFyZSBjYWxsZWQgaW4gb3JkZXIsIGZhbHNlIG90aGVyd2lzZVxuXHQgKi9cblx0ZnVuY3Rpb24gY2FsbGVkSW5PcmRlcihzcGllcykge1xuXHQgICAgdmFyIGNhbGxNYXAgPSB7fTtcblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlcnNjb3JlLWRhbmdsZVxuXHQgICAgdmFyIF9zcGllcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzIDogc3BpZXM7XG5cblx0ICAgIHJldHVybiBldmVyeShfc3BpZXMsIGNoZWNrQWRqYWNlbnRDYWxscy5iaW5kKG51bGwsIGNhbGxNYXApKTtcblx0fVxuXG5cdGNhbGxlZEluT3JkZXJfMSA9IGNhbGxlZEluT3JkZXI7XG5cdHJldHVybiBjYWxsZWRJbk9yZGVyXzE7XG59XG5cbnZhciBjbGFzc05hbWVfMTtcbnZhciBoYXNSZXF1aXJlZENsYXNzTmFtZTtcblxuZnVuY3Rpb24gcmVxdWlyZUNsYXNzTmFtZSAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZENsYXNzTmFtZSkgcmV0dXJuIGNsYXNzTmFtZV8xO1xuXHRoYXNSZXF1aXJlZENsYXNzTmFtZSA9IDE7XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYSBkaXNwbGF5IG5hbWUgZm9yIGEgdmFsdWUgZnJvbSBhIGNvbnN0cnVjdG9yXG5cdCAqIEBwYXJhbSAge29iamVjdH0gdmFsdWUgQSB2YWx1ZSB0byBleGFtaW5lXG5cdCAqIEByZXR1cm5zIHsoc3RyaW5nfG51bGwpfSBBIHN0cmluZyBvciBudWxsXG5cdCAqL1xuXHRmdW5jdGlvbiBjbGFzc05hbWUodmFsdWUpIHtcblx0ICAgIGNvbnN0IG5hbWUgPSB2YWx1ZS5jb25zdHJ1Y3RvciAmJiB2YWx1ZS5jb25zdHJ1Y3Rvci5uYW1lO1xuXHQgICAgcmV0dXJuIG5hbWUgfHwgbnVsbDtcblx0fVxuXG5cdGNsYXNzTmFtZV8xID0gY2xhc3NOYW1lO1xuXHRyZXR1cm4gY2xhc3NOYW1lXzE7XG59XG5cbnZhciBkZXByZWNhdGVkID0ge307XG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cblxudmFyIGhhc1JlcXVpcmVkRGVwcmVjYXRlZDtcblxuZnVuY3Rpb24gcmVxdWlyZURlcHJlY2F0ZWQgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWREZXByZWNhdGVkKSByZXR1cm4gZGVwcmVjYXRlZDtcblx0aGFzUmVxdWlyZWREZXByZWNhdGVkID0gMTtcblx0KGZ1bmN0aW9uIChleHBvcnRzJDEpIHtcblxuXHRcdC8qKlxuXHRcdCAqIFJldHVybnMgYSBmdW5jdGlvbiB0aGF0IHdpbGwgaW52b2tlIHRoZSBzdXBwbGllZCBmdW5jdGlvbiBhbmQgcHJpbnQgYVxuXHRcdCAqIGRlcHJlY2F0aW9uIHdhcm5pbmcgdG8gdGhlIGNvbnNvbGUgZWFjaCB0aW1lIGl0IGlzIGNhbGxlZC5cblx0XHQgKiBAcGFyYW0gIHtGdW5jdGlvbn0gZnVuY1xuXHRcdCAqIEBwYXJhbSAge3N0cmluZ30gbXNnXG5cdFx0ICogQHJldHVybnMge0Z1bmN0aW9ufVxuXHRcdCAqL1xuXHRcdGV4cG9ydHMkMS53cmFwID0gZnVuY3Rpb24gKGZ1bmMsIG1zZykge1xuXHRcdCAgICB2YXIgd3JhcHBlZCA9IGZ1bmN0aW9uICgpIHtcblx0XHQgICAgICAgIGV4cG9ydHMkMS5wcmludFdhcm5pbmcobXNnKTtcblx0XHQgICAgICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdFx0ICAgIH07XG5cdFx0ICAgIGlmIChmdW5jLnByb3RvdHlwZSkge1xuXHRcdCAgICAgICAgd3JhcHBlZC5wcm90b3R5cGUgPSBmdW5jLnByb3RvdHlwZTtcblx0XHQgICAgfVxuXHRcdCAgICByZXR1cm4gd3JhcHBlZDtcblx0XHR9O1xuXG5cdFx0LyoqXG5cdFx0ICogUmV0dXJucyBhIHN0cmluZyB3aGljaCBjYW4gYmUgc3VwcGxpZWQgdG8gYHdyYXAoKWAgdG8gbm90aWZ5IHRoZSB1c2VyIHRoYXQgYVxuXHRcdCAqIHBhcnRpY3VsYXIgcGFydCBvZiB0aGUgc2lub24gQVBJIGhhcyBiZWVuIGRlcHJlY2F0ZWQuXG5cdFx0ICogQHBhcmFtICB7c3RyaW5nfSBwYWNrYWdlTmFtZVxuXHRcdCAqIEBwYXJhbSAge3N0cmluZ30gZnVuY05hbWVcblx0XHQgKiBAcmV0dXJucyB7c3RyaW5nfVxuXHRcdCAqL1xuXHRcdGV4cG9ydHMkMS5kZWZhdWx0TXNnID0gZnVuY3Rpb24gKHBhY2thZ2VOYW1lLCBmdW5jTmFtZSkge1xuXHRcdCAgICByZXR1cm4gYCR7cGFja2FnZU5hbWV9LiR7ZnVuY05hbWV9IGlzIGRlcHJlY2F0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBwdWJsaWMgQVBJIGluIGEgZnV0dXJlIHZlcnNpb24gb2YgJHtwYWNrYWdlTmFtZX0uYDtcblx0XHR9O1xuXG5cdFx0LyoqXG5cdFx0ICogUHJpbnRzIGEgd2FybmluZyBvbiB0aGUgY29uc29sZSwgd2hlbiBpdCBleGlzdHNcblx0XHQgKiBAcGFyYW0gIHtzdHJpbmd9IG1zZ1xuXHRcdCAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG5cdFx0ICovXG5cdFx0ZXhwb3J0cyQxLnByaW50V2FybmluZyA9IGZ1bmN0aW9uIChtc2cpIHtcblx0XHQgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0XHQgICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHByb2Nlc3MuZW1pdFdhcm5pbmcpIHtcblx0XHQgICAgICAgIC8vIEVtaXQgV2FybmluZ3MgaW4gTm9kZVxuXHRcdCAgICAgICAgcHJvY2Vzcy5lbWl0V2FybmluZyhtc2cpO1xuXHRcdCAgICB9IGVsc2UgaWYgKGNvbnNvbGUuaW5mbykge1xuXHRcdCAgICAgICAgY29uc29sZS5pbmZvKG1zZyk7XG5cdFx0ICAgIH0gZWxzZSB7XG5cdFx0ICAgICAgICBjb25zb2xlLmxvZyhtc2cpO1xuXHRcdCAgICB9XG5cdFx0fTsgXG5cdH0gKGRlcHJlY2F0ZWQpKTtcblx0cmV0dXJuIGRlcHJlY2F0ZWQ7XG59XG5cbnZhciBldmVyeTtcbnZhciBoYXNSZXF1aXJlZEV2ZXJ5O1xuXG5mdW5jdGlvbiByZXF1aXJlRXZlcnkgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRFdmVyeSkgcmV0dXJuIGV2ZXJ5O1xuXHRoYXNSZXF1aXJlZEV2ZXJ5ID0gMTtcblxuXHQvKipcblx0ICogUmV0dXJucyB0cnVlIHdoZW4gZm4gcmV0dXJucyB0cnVlIGZvciBhbGwgbWVtYmVycyBvZiBvYmouXG5cdCAqIFRoaXMgaXMgYW4gZXZlcnkgaW1wbGVtZW50YXRpb24gdGhhdCB3b3JrcyBmb3IgYWxsIGl0ZXJhYmxlc1xuXHQgKiBAcGFyYW0gIHtvYmplY3R9ICAgb2JqXG5cdCAqIEBwYXJhbSAge0Z1bmN0aW9ufSBmblxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cblx0ICovXG5cdGV2ZXJ5ID0gZnVuY3Rpb24gZXZlcnkob2JqLCBmbikge1xuXHQgICAgdmFyIHBhc3MgPSB0cnVlO1xuXG5cdCAgICB0cnkge1xuXHQgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAc2lub25qcy9uby1wcm90b3R5cGUtbWV0aG9kcy9uby1wcm90b3R5cGUtbWV0aG9kc1xuXHQgICAgICAgIG9iai5mb3JFYWNoKGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKCFmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBUaHJvd2luZyBhbiBlcnJvciBpcyB0aGUgb25seSB3YXkgdG8gYnJlYWsgYGZvckVhY2hgXG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfSBjYXRjaCAoZSkge1xuXHQgICAgICAgIHBhc3MgPSBmYWxzZTtcblx0ICAgIH1cblxuXHQgICAgcmV0dXJuIHBhc3M7XG5cdH07XG5cdHJldHVybiBldmVyeTtcbn1cblxudmFyIGZ1bmN0aW9uTmFtZTtcbnZhciBoYXNSZXF1aXJlZEZ1bmN0aW9uTmFtZTtcblxuZnVuY3Rpb24gcmVxdWlyZUZ1bmN0aW9uTmFtZSAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEZ1bmN0aW9uTmFtZSkgcmV0dXJuIGZ1bmN0aW9uTmFtZTtcblx0aGFzUmVxdWlyZWRGdW5jdGlvbk5hbWUgPSAxO1xuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGEgZGlzcGxheSBuYW1lIGZvciBhIGZ1bmN0aW9uXG5cdCAqIEBwYXJhbSAge0Z1bmN0aW9ufSBmdW5jXG5cdCAqIEByZXR1cm5zIHtzdHJpbmd9XG5cdCAqL1xuXHRmdW5jdGlvbk5hbWUgPSBmdW5jdGlvbiBmdW5jdGlvbk5hbWUoZnVuYykge1xuXHQgICAgaWYgKCFmdW5jKSB7XG5cdCAgICAgICAgcmV0dXJuIFwiXCI7XG5cdCAgICB9XG5cblx0ICAgIHRyeSB7XG5cdCAgICAgICAgcmV0dXJuIChcblx0ICAgICAgICAgICAgZnVuYy5kaXNwbGF5TmFtZSB8fFxuXHQgICAgICAgICAgICBmdW5jLm5hbWUgfHxcblx0ICAgICAgICAgICAgLy8gVXNlIGZ1bmN0aW9uIGRlY29tcG9zaXRpb24gYXMgYSBsYXN0IHJlc29ydCB0byBnZXQgZnVuY3Rpb25cblx0ICAgICAgICAgICAgLy8gbmFtZS4gRG9lcyBub3QgcmVseSBvbiBmdW5jdGlvbiBkZWNvbXBvc2l0aW9uIHRvIHdvcmsgLSBpZiBpdFxuXHQgICAgICAgICAgICAvLyBkb2Vzbid0IGRlYnVnZ2luZyB3aWxsIGJlIHNsaWdodGx5IGxlc3MgaW5mb3JtYXRpdmVcblx0ICAgICAgICAgICAgLy8gKGkuZS4gdG9TdHJpbmcgd2lsbCBzYXkgJ3NweScgcmF0aGVyIHRoYW4gJ215RnVuYycpLlxuXHQgICAgICAgICAgICAoU3RyaW5nKGZ1bmMpLm1hdGNoKC9mdW5jdGlvbiAoW15cXHMoXSspLykgfHwgW10pWzFdXG5cdCAgICAgICAgKTtcblx0ICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAvLyBTdHJpbmdpZnkgbWF5IGZhaWwgYW5kIHdlIG1pZ2h0IGdldCBhbiBleGNlcHRpb24sIGFzIGEgbGFzdC1sYXN0XG5cdCAgICAgICAgLy8gcmVzb3J0IGZhbGwgYmFjayB0byBlbXB0eSBzdHJpbmcuXG5cdCAgICAgICAgcmV0dXJuIFwiXCI7XG5cdCAgICB9XG5cdH07XG5cdHJldHVybiBmdW5jdGlvbk5hbWU7XG59XG5cbnZhciBvcmRlckJ5Rmlyc3RDYWxsXzE7XG52YXIgaGFzUmVxdWlyZWRPcmRlckJ5Rmlyc3RDYWxsO1xuXG5mdW5jdGlvbiByZXF1aXJlT3JkZXJCeUZpcnN0Q2FsbCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZE9yZGVyQnlGaXJzdENhbGwpIHJldHVybiBvcmRlckJ5Rmlyc3RDYWxsXzE7XG5cdGhhc1JlcXVpcmVkT3JkZXJCeUZpcnN0Q2FsbCA9IDE7XG5cblx0dmFyIHNvcnQgPSByZXF1aXJlQXJyYXkoKS5zb3J0O1xuXHR2YXIgc2xpY2UgPSByZXF1aXJlQXJyYXkoKS5zbGljZTtcblxuXHQvKipcblx0ICogQHByaXZhdGVcblx0ICovXG5cdGZ1bmN0aW9uIGNvbXBhcmF0b3IoYSwgYikge1xuXHQgICAgLy8gdXVpZCwgd29uJ3QgZXZlciBiZSBlcXVhbFxuXHQgICAgdmFyIGFDYWxsID0gYS5nZXRDYWxsKDApO1xuXHQgICAgdmFyIGJDYWxsID0gYi5nZXRDYWxsKDApO1xuXHQgICAgdmFyIGFJZCA9IChhQ2FsbCAmJiBhQ2FsbC5jYWxsSWQpIHx8IC0xO1xuXHQgICAgdmFyIGJJZCA9IChiQ2FsbCAmJiBiQ2FsbC5jYWxsSWQpIHx8IC0xO1xuXG5cdCAgICByZXR1cm4gYUlkIDwgYklkID8gLTEgOiAxO1xuXHR9XG5cblx0LyoqXG5cdCAqIEEgU2lub24gcHJveHkgb2JqZWN0IChmYWtlLCBzcHksIHN0dWIpXG5cdCAqIEB0eXBlZGVmIHtvYmplY3R9IFNpbm9uUHJveHlcblx0ICogQHByb3BlcnR5IHtGdW5jdGlvbn0gZ2V0Q2FsbCAtIEEgbWV0aG9kIHRoYXQgY2FuIHJldHVybiB0aGUgZmlyc3QgY2FsbFxuXHQgKi9cblxuXHQvKipcblx0ICogU29ydHMgYW4gYXJyYXkgb2YgU2lub25Qcm94eSBpbnN0YW5jZXMgKGZha2UsIHNweSwgc3R1YikgYnkgdGhlaXIgZmlyc3QgY2FsbFxuXHQgKiBAcGFyYW0gIHtTaW5vblByb3h5W10gfCBTaW5vblByb3h5fSBzcGllc1xuXHQgKiBAcmV0dXJucyB7U2lub25Qcm94eVtdfVxuXHQgKi9cblx0ZnVuY3Rpb24gb3JkZXJCeUZpcnN0Q2FsbChzcGllcykge1xuXHQgICAgcmV0dXJuIHNvcnQoc2xpY2Uoc3BpZXMpLCBjb21wYXJhdG9yKTtcblx0fVxuXG5cdG9yZGVyQnlGaXJzdENhbGxfMSA9IG9yZGVyQnlGaXJzdENhbGw7XG5cdHJldHVybiBvcmRlckJ5Rmlyc3RDYWxsXzE7XG59XG5cbnZhciBfZnVuY3Rpb247XG52YXIgaGFzUmVxdWlyZWRfZnVuY3Rpb247XG5cbmZ1bmN0aW9uIHJlcXVpcmVfZnVuY3Rpb24gKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRfZnVuY3Rpb24pIHJldHVybiBfZnVuY3Rpb247XG5cdGhhc1JlcXVpcmVkX2Z1bmN0aW9uID0gMTtcblxuXHR2YXIgY29weVByb3RvdHlwZSA9IHJlcXVpcmVDb3B5UHJvdG90eXBlTWV0aG9kcygpO1xuXG5cdF9mdW5jdGlvbiA9IGNvcHlQcm90b3R5cGUoRnVuY3Rpb24ucHJvdG90eXBlKTtcblx0cmV0dXJuIF9mdW5jdGlvbjtcbn1cblxudmFyIG1hcDtcbnZhciBoYXNSZXF1aXJlZE1hcDtcblxuZnVuY3Rpb24gcmVxdWlyZU1hcCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZE1hcCkgcmV0dXJuIG1hcDtcblx0aGFzUmVxdWlyZWRNYXAgPSAxO1xuXG5cdHZhciBjb3B5UHJvdG90eXBlID0gcmVxdWlyZUNvcHlQcm90b3R5cGVNZXRob2RzKCk7XG5cblx0bWFwID0gY29weVByb3RvdHlwZShNYXAucHJvdG90eXBlKTtcblx0cmV0dXJuIG1hcDtcbn1cblxudmFyIG9iamVjdDtcbnZhciBoYXNSZXF1aXJlZE9iamVjdDtcblxuZnVuY3Rpb24gcmVxdWlyZU9iamVjdCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZE9iamVjdCkgcmV0dXJuIG9iamVjdDtcblx0aGFzUmVxdWlyZWRPYmplY3QgPSAxO1xuXG5cdHZhciBjb3B5UHJvdG90eXBlID0gcmVxdWlyZUNvcHlQcm90b3R5cGVNZXRob2RzKCk7XG5cblx0b2JqZWN0ID0gY29weVByb3RvdHlwZShPYmplY3QucHJvdG90eXBlKTtcblx0cmV0dXJuIG9iamVjdDtcbn1cblxudmFyIHNldDtcbnZhciBoYXNSZXF1aXJlZFNldDtcblxuZnVuY3Rpb24gcmVxdWlyZVNldCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZFNldCkgcmV0dXJuIHNldDtcblx0aGFzUmVxdWlyZWRTZXQgPSAxO1xuXG5cdHZhciBjb3B5UHJvdG90eXBlID0gcmVxdWlyZUNvcHlQcm90b3R5cGVNZXRob2RzKCk7XG5cblx0c2V0ID0gY29weVByb3RvdHlwZShTZXQucHJvdG90eXBlKTtcblx0cmV0dXJuIHNldDtcbn1cblxudmFyIHN0cmluZztcbnZhciBoYXNSZXF1aXJlZFN0cmluZztcblxuZnVuY3Rpb24gcmVxdWlyZVN0cmluZyAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZFN0cmluZykgcmV0dXJuIHN0cmluZztcblx0aGFzUmVxdWlyZWRTdHJpbmcgPSAxO1xuXG5cdHZhciBjb3B5UHJvdG90eXBlID0gcmVxdWlyZUNvcHlQcm90b3R5cGVNZXRob2RzKCk7XG5cblx0c3RyaW5nID0gY29weVByb3RvdHlwZShTdHJpbmcucHJvdG90eXBlKTtcblx0cmV0dXJuIHN0cmluZztcbn1cblxudmFyIHByb3RvdHlwZXM7XG52YXIgaGFzUmVxdWlyZWRQcm90b3R5cGVzO1xuXG5mdW5jdGlvbiByZXF1aXJlUHJvdG90eXBlcyAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZFByb3RvdHlwZXMpIHJldHVybiBwcm90b3R5cGVzO1xuXHRoYXNSZXF1aXJlZFByb3RvdHlwZXMgPSAxO1xuXG5cdHByb3RvdHlwZXMgPSB7XG5cdCAgICBhcnJheTogcmVxdWlyZUFycmF5KCksXG5cdCAgICBmdW5jdGlvbjogcmVxdWlyZV9mdW5jdGlvbigpLFxuXHQgICAgbWFwOiByZXF1aXJlTWFwKCksXG5cdCAgICBvYmplY3Q6IHJlcXVpcmVPYmplY3QoKSxcblx0ICAgIHNldDogcmVxdWlyZVNldCgpLFxuXHQgICAgc3RyaW5nOiByZXF1aXJlU3RyaW5nKCksXG5cdH07XG5cdHJldHVybiBwcm90b3R5cGVzO1xufVxuXG52YXIgdHlwZURldGVjdCQxID0ge2V4cG9ydHM6IHt9fTtcblxudmFyIHR5cGVEZXRlY3QgPSB0eXBlRGV0ZWN0JDEuZXhwb3J0cztcblxudmFyIGhhc1JlcXVpcmVkVHlwZURldGVjdDtcblxuZnVuY3Rpb24gcmVxdWlyZVR5cGVEZXRlY3QgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRUeXBlRGV0ZWN0KSByZXR1cm4gdHlwZURldGVjdCQxLmV4cG9ydHM7XG5cdGhhc1JlcXVpcmVkVHlwZURldGVjdCA9IDE7XG5cdChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHtcblx0XHQoZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuXHRcdFx0bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCkgO1xuXHRcdH0odHlwZURldGVjdCwgKGZ1bmN0aW9uICgpIHtcblx0XHQvKiAhXG5cdFx0ICogdHlwZS1kZXRlY3Rcblx0XHQgKiBDb3B5cmlnaHQoYykgMjAxMyBqYWtlIGx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cblx0XHQgKiBNSVQgTGljZW5zZWRcblx0XHQgKi9cblx0XHR2YXIgcHJvbWlzZUV4aXN0cyA9IHR5cGVvZiBQcm9taXNlID09PSAnZnVuY3Rpb24nO1xuXG5cdFx0LyogZXNsaW50LWRpc2FibGUgbm8tdW5kZWYgKi9cblx0XHR2YXIgZ2xvYmFsT2JqZWN0ID0gdHlwZW9mIHNlbGYgPT09ICdvYmplY3QnID8gc2VsZiA6IGNvbW1vbmpzR2xvYmFsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGlkLWJsYWNrbGlzdFxuXG5cdFx0dmFyIHN5bWJvbEV4aXN0cyA9IHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnO1xuXHRcdHZhciBtYXBFeGlzdHMgPSB0eXBlb2YgTWFwICE9PSAndW5kZWZpbmVkJztcblx0XHR2YXIgc2V0RXhpc3RzID0gdHlwZW9mIFNldCAhPT0gJ3VuZGVmaW5lZCc7XG5cdFx0dmFyIHdlYWtNYXBFeGlzdHMgPSB0eXBlb2YgV2Vha01hcCAhPT0gJ3VuZGVmaW5lZCc7XG5cdFx0dmFyIHdlYWtTZXRFeGlzdHMgPSB0eXBlb2YgV2Vha1NldCAhPT0gJ3VuZGVmaW5lZCc7XG5cdFx0dmFyIGRhdGFWaWV3RXhpc3RzID0gdHlwZW9mIERhdGFWaWV3ICE9PSAndW5kZWZpbmVkJztcblx0XHR2YXIgc3ltYm9sSXRlcmF0b3JFeGlzdHMgPSBzeW1ib2xFeGlzdHMgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciAhPT0gJ3VuZGVmaW5lZCc7XG5cdFx0dmFyIHN5bWJvbFRvU3RyaW5nVGFnRXhpc3RzID0gc3ltYm9sRXhpc3RzICYmIHR5cGVvZiBTeW1ib2wudG9TdHJpbmdUYWcgIT09ICd1bmRlZmluZWQnO1xuXHRcdHZhciBzZXRFbnRyaWVzRXhpc3RzID0gc2V0RXhpc3RzICYmIHR5cGVvZiBTZXQucHJvdG90eXBlLmVudHJpZXMgPT09ICdmdW5jdGlvbic7XG5cdFx0dmFyIG1hcEVudHJpZXNFeGlzdHMgPSBtYXBFeGlzdHMgJiYgdHlwZW9mIE1hcC5wcm90b3R5cGUuZW50cmllcyA9PT0gJ2Z1bmN0aW9uJztcblx0XHR2YXIgc2V0SXRlcmF0b3JQcm90b3R5cGUgPSBzZXRFbnRyaWVzRXhpc3RzICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihuZXcgU2V0KCkuZW50cmllcygpKTtcblx0XHR2YXIgbWFwSXRlcmF0b3JQcm90b3R5cGUgPSBtYXBFbnRyaWVzRXhpc3RzICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihuZXcgTWFwKCkuZW50cmllcygpKTtcblx0XHR2YXIgYXJyYXlJdGVyYXRvckV4aXN0cyA9IHN5bWJvbEl0ZXJhdG9yRXhpc3RzICYmIHR5cGVvZiBBcnJheS5wcm90b3R5cGVbU3ltYm9sLml0ZXJhdG9yXSA9PT0gJ2Z1bmN0aW9uJztcblx0XHR2YXIgYXJyYXlJdGVyYXRvclByb3RvdHlwZSA9IGFycmF5SXRlcmF0b3JFeGlzdHMgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKFtdW1N5bWJvbC5pdGVyYXRvcl0oKSk7XG5cdFx0dmFyIHN0cmluZ0l0ZXJhdG9yRXhpc3RzID0gc3ltYm9sSXRlcmF0b3JFeGlzdHMgJiYgdHlwZW9mIFN0cmluZy5wcm90b3R5cGVbU3ltYm9sLml0ZXJhdG9yXSA9PT0gJ2Z1bmN0aW9uJztcblx0XHR2YXIgc3RyaW5nSXRlcmF0b3JQcm90b3R5cGUgPSBzdHJpbmdJdGVyYXRvckV4aXN0cyAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoJydbU3ltYm9sLml0ZXJhdG9yXSgpKTtcblx0XHR2YXIgdG9TdHJpbmdMZWZ0U2xpY2VMZW5ndGggPSA4O1xuXHRcdHZhciB0b1N0cmluZ1JpZ2h0U2xpY2VMZW5ndGggPSAtMTtcblx0XHQvKipcblx0XHQgKiAjIyMgdHlwZU9mIChvYmopXG5cdFx0ICpcblx0XHQgKiBVc2VzIGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYCB0byBkZXRlcm1pbmUgdGhlIHR5cGUgb2YgYW4gb2JqZWN0LFxuXHRcdCAqIG5vcm1hbGlzaW5nIGJlaGF2aW91ciBhY3Jvc3MgZW5naW5lIHZlcnNpb25zICYgd2VsbCBvcHRpbWlzZWQuXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0ge01peGVkfSBvYmplY3Rcblx0XHQgKiBAcmV0dXJuIHtTdHJpbmd9IG9iamVjdCB0eXBlXG5cdFx0ICogQGFwaSBwdWJsaWNcblx0XHQgKi9cblx0XHRmdW5jdGlvbiB0eXBlRGV0ZWN0KG9iaikge1xuXHRcdCAgLyogISBTcGVlZCBvcHRpbWlzYXRpb25cblx0XHQgICAqIFByZTpcblx0XHQgICAqICAgc3RyaW5nIGxpdGVyYWwgICAgIHggMywwMzksMDM1IG9wcy9zZWMgwrExLjYyJSAoNzggcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICBib29sZWFuIGxpdGVyYWwgICAgeCAxLDQyNCwxMzggb3BzL3NlYyDCsTQuNTQlICg3NSBydW5zIHNhbXBsZWQpXG5cdFx0ICAgKiAgIG51bWJlciBsaXRlcmFsICAgICB4IDEsNjUzLDE1MyBvcHMvc2VjIMKxMS45MSUgKDgyIHJ1bnMgc2FtcGxlZClcblx0XHQgICAqICAgdW5kZWZpbmVkICAgICAgICAgIHggOSw5NzgsNjYwIG9wcy9zZWMgwrExLjkyJSAoNzUgcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICBmdW5jdGlvbiAgICAgICAgICAgeCAyLDU1Niw3Njkgb3BzL3NlYyDCsTEuNzMlICg3NyBydW5zIHNhbXBsZWQpXG5cdFx0ICAgKiBQb3N0OlxuXHRcdCAgICogICBzdHJpbmcgbGl0ZXJhbCAgICAgeCAzOCw1NjQsNzk2IG9wcy9zZWMgwrExLjE1JSAoNzkgcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICBib29sZWFuIGxpdGVyYWwgICAgeCAzMSwxNDgsOTQwIG9wcy9zZWMgwrExLjEwJSAoNzkgcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICBudW1iZXIgbGl0ZXJhbCAgICAgeCAzMiw2NzksMzMwIG9wcy9zZWMgwrExLjkwJSAoNzggcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICB1bmRlZmluZWQgICAgICAgICAgeCAzMiwzNjMsMzY4IG9wcy9zZWMgwrExLjA3JSAoODIgcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICBmdW5jdGlvbiAgICAgICAgICAgeCAzMSwyOTYsODcwIG9wcy9zZWMgwrEwLjk2JSAoODMgcnVucyBzYW1wbGVkKVxuXHRcdCAgICovXG5cdFx0ICB2YXIgdHlwZW9mT2JqID0gdHlwZW9mIG9iajtcblx0XHQgIGlmICh0eXBlb2ZPYmogIT09ICdvYmplY3QnKSB7XG5cdFx0ICAgIHJldHVybiB0eXBlb2ZPYmo7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAgKiBQcmU6XG5cdFx0ICAgKiAgIG51bGwgICAgICAgICAgICAgICB4IDI4LDY0NSw3NjUgb3BzL3NlYyDCsTEuMTclICg4MiBydW5zIHNhbXBsZWQpXG5cdFx0ICAgKiBQb3N0OlxuXHRcdCAgICogICBudWxsICAgICAgICAgICAgICAgeCAzNiw0MjgsOTYyIG9wcy9zZWMgwrExLjM3JSAoODQgcnVucyBzYW1wbGVkKVxuXHRcdCAgICovXG5cdFx0ICBpZiAob2JqID09PSBudWxsKSB7XG5cdFx0ICAgIHJldHVybiAnbnVsbCc7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICogVGVzdDogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh3aW5kb3cpYGBcblx0XHQgICAqICAtIE5vZGUgPT09IFwiW29iamVjdCBnbG9iYWxdXCJcblx0XHQgICAqICAtIENocm9tZSA9PT0gXCJbb2JqZWN0IGdsb2JhbF1cIlxuXHRcdCAgICogIC0gRmlyZWZveCA9PT0gXCJbb2JqZWN0IFdpbmRvd11cIlxuXHRcdCAgICogIC0gUGhhbnRvbUpTID09PSBcIltvYmplY3QgV2luZG93XVwiXG5cdFx0ICAgKiAgLSBTYWZhcmkgPT09IFwiW29iamVjdCBXaW5kb3ddXCJcblx0XHQgICAqICAtIElFIDExID09PSBcIltvYmplY3QgV2luZG93XVwiXG5cdFx0ICAgKiAgLSBJRSBFZGdlID09PSBcIltvYmplY3QgV2luZG93XVwiXG5cdFx0ICAgKiBUZXN0OiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHRoaXMpYGBcblx0XHQgICAqICAtIENocm9tZSBXb3JrZXIgPT09IFwiW29iamVjdCBnbG9iYWxdXCJcblx0XHQgICAqICAtIEZpcmVmb3ggV29ya2VyID09PSBcIltvYmplY3QgRGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGVdXCJcblx0XHQgICAqICAtIFNhZmFyaSBXb3JrZXIgPT09IFwiW29iamVjdCBEZWRpY2F0ZWRXb3JrZXJHbG9iYWxTY29wZV1cIlxuXHRcdCAgICogIC0gSUUgMTEgV29ya2VyID09PSBcIltvYmplY3QgV29ya2VyR2xvYmFsU2NvcGVdXCJcblx0XHQgICAqICAtIElFIEVkZ2UgV29ya2VyID09PSBcIltvYmplY3QgV29ya2VyR2xvYmFsU2NvcGVdXCJcblx0XHQgICAqL1xuXHRcdCAgaWYgKG9iaiA9PT0gZ2xvYmFsT2JqZWN0KSB7XG5cdFx0ICAgIHJldHVybiAnZ2xvYmFsJztcblx0XHQgIH1cblxuXHRcdCAgLyogISBTcGVlZCBvcHRpbWlzYXRpb25cblx0XHQgICAqIFByZTpcblx0XHQgICAqICAgYXJyYXkgbGl0ZXJhbCAgICAgIHggMiw4ODgsMzUyIG9wcy9zZWMgwrEwLjY3JSAoODIgcnVucyBzYW1wbGVkKVxuXHRcdCAgICogUG9zdDpcblx0XHQgICAqICAgYXJyYXkgbGl0ZXJhbCAgICAgIHggMjIsNDc5LDY1MCBvcHMvc2VjIMKxMC45NiUgKDgxIHJ1bnMgc2FtcGxlZClcblx0XHQgICAqL1xuXHRcdCAgaWYgKFxuXHRcdCAgICBBcnJheS5pc0FycmF5KG9iaikgJiZcblx0XHQgICAgKHN5bWJvbFRvU3RyaW5nVGFnRXhpc3RzID09PSBmYWxzZSB8fCAhKFN5bWJvbC50b1N0cmluZ1RhZyBpbiBvYmopKVxuXHRcdCAgKSB7XG5cdFx0ICAgIHJldHVybiAnQXJyYXknO1xuXHRcdCAgfVxuXG5cdFx0ICAvLyBOb3QgY2FjaGluZyBleGlzdGVuY2Ugb2YgYHdpbmRvd2AgYW5kIHJlbGF0ZWQgcHJvcGVydGllcyBkdWUgdG8gcG90ZW50aWFsXG5cdFx0ICAvLyBmb3IgYHdpbmRvd2AgdG8gYmUgdW5zZXQgYmVmb3JlIHRlc3RzIGluIHF1YXNpLWJyb3dzZXIgZW52aXJvbm1lbnRzLlxuXHRcdCAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICdvYmplY3QnICYmIHdpbmRvdyAhPT0gbnVsbCkge1xuXHRcdCAgICAvKiAhIFNwZWMgQ29uZm9ybWFuY2Vcblx0XHQgICAgICogKGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2Jyb3dzZXJzLmh0bWwjbG9jYXRpb24pXG5cdFx0ICAgICAqIFdoYXRXRyBIVE1MJDcuNy4zIC0gVGhlIGBMb2NhdGlvbmAgaW50ZXJmYWNlXG5cdFx0ICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwod2luZG93LmxvY2F0aW9uKWBgXG5cdFx0ICAgICAqICAtIElFIDw9MTEgPT09IFwiW29iamVjdCBPYmplY3RdXCJcblx0XHQgICAgICogIC0gSUUgRWRnZSA8PTEzID09PSBcIltvYmplY3QgT2JqZWN0XVwiXG5cdFx0ICAgICAqL1xuXHRcdCAgICBpZiAodHlwZW9mIHdpbmRvdy5sb2NhdGlvbiA9PT0gJ29iamVjdCcgJiYgb2JqID09PSB3aW5kb3cubG9jYXRpb24pIHtcblx0XHQgICAgICByZXR1cm4gJ0xvY2F0aW9uJztcblx0XHQgICAgfVxuXG5cdFx0ICAgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICAgKiAoaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy8jZG9jdW1lbnQpXG5cdFx0ICAgICAqIFdoYXRXRyBIVE1MJDMuMS4xIC0gVGhlIGBEb2N1bWVudGAgb2JqZWN0XG5cdFx0ICAgICAqIE5vdGU6IE1vc3QgYnJvd3NlcnMgY3VycmVudGx5IGFkaGVyIHRvIHRoZSBXM0MgRE9NIExldmVsIDIgc3BlY1xuXHRcdCAgICAgKiAgICAgICAoaHR0cHM6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUhUTUwvaHRtbC5odG1sI0lELTI2ODA5MjY4KVxuXHRcdCAgICAgKiAgICAgICB3aGljaCBzdWdnZXN0cyB0aGF0IGJyb3dzZXJzIHNob3VsZCB1c2UgSFRNTFRhYmxlQ2VsbEVsZW1lbnQgZm9yXG5cdFx0ICAgICAqICAgICAgIGJvdGggVEQgYW5kIFRIIGVsZW1lbnRzLiBXaGF0V0cgc2VwYXJhdGVzIHRoZXNlLlxuXHRcdCAgICAgKiAgICAgICBXaGF0V0cgSFRNTCBzdGF0ZXM6XG5cdFx0ICAgICAqICAgICAgICAgPiBGb3IgaGlzdG9yaWNhbCByZWFzb25zLCBXaW5kb3cgb2JqZWN0cyBtdXN0IGFsc28gaGF2ZSBhXG5cdFx0ICAgICAqICAgICAgICAgPiB3cml0YWJsZSwgY29uZmlndXJhYmxlLCBub24tZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lZFxuXHRcdCAgICAgKiAgICAgICAgID4gSFRNTERvY3VtZW50IHdob3NlIHZhbHVlIGlzIHRoZSBEb2N1bWVudCBpbnRlcmZhY2Ugb2JqZWN0LlxuXHRcdCAgICAgKiBUZXN0OiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGRvY3VtZW50KWBgXG5cdFx0ICAgICAqICAtIENocm9tZSA9PT0gXCJbb2JqZWN0IEhUTUxEb2N1bWVudF1cIlxuXHRcdCAgICAgKiAgLSBGaXJlZm94ID09PSBcIltvYmplY3QgSFRNTERvY3VtZW50XVwiXG5cdFx0ICAgICAqICAtIFNhZmFyaSA9PT0gXCJbb2JqZWN0IEhUTUxEb2N1bWVudF1cIlxuXHRcdCAgICAgKiAgLSBJRSA8PTEwID09PSBcIltvYmplY3QgRG9jdW1lbnRdXCJcblx0XHQgICAgICogIC0gSUUgMTEgPT09IFwiW29iamVjdCBIVE1MRG9jdW1lbnRdXCJcblx0XHQgICAgICogIC0gSUUgRWRnZSA8PTEzID09PSBcIltvYmplY3QgSFRNTERvY3VtZW50XVwiXG5cdFx0ICAgICAqL1xuXHRcdCAgICBpZiAodHlwZW9mIHdpbmRvdy5kb2N1bWVudCA9PT0gJ29iamVjdCcgJiYgb2JqID09PSB3aW5kb3cuZG9jdW1lbnQpIHtcblx0XHQgICAgICByZXR1cm4gJ0RvY3VtZW50Jztcblx0XHQgICAgfVxuXG5cdFx0ICAgIGlmICh0eXBlb2Ygd2luZG93Lm5hdmlnYXRvciA9PT0gJ29iamVjdCcpIHtcblx0XHQgICAgICAvKiAhIFNwZWMgQ29uZm9ybWFuY2Vcblx0XHQgICAgICAgKiAoaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvd2ViYXBwYXBpcy5odG1sI21pbWV0eXBlYXJyYXkpXG5cdFx0ICAgICAgICogV2hhdFdHIEhUTUwkOC42LjEuNSAtIFBsdWdpbnMgLSBJbnRlcmZhY2UgTWltZVR5cGVBcnJheVxuXHRcdCAgICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobmF2aWdhdG9yLm1pbWVUeXBlcylgYFxuXHRcdCAgICAgICAqICAtIElFIDw9MTAgPT09IFwiW29iamVjdCBNU01pbWVUeXBlc0NvbGxlY3Rpb25dXCJcblx0XHQgICAgICAgKi9cblx0XHQgICAgICBpZiAodHlwZW9mIHdpbmRvdy5uYXZpZ2F0b3IubWltZVR5cGVzID09PSAnb2JqZWN0JyAmJlxuXHRcdCAgICAgICAgICBvYmogPT09IHdpbmRvdy5uYXZpZ2F0b3IubWltZVR5cGVzKSB7XG5cdFx0ICAgICAgICByZXR1cm4gJ01pbWVUeXBlQXJyYXknO1xuXHRcdCAgICAgIH1cblxuXHRcdCAgICAgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICAgICAqIChodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS93ZWJhcHBhcGlzLmh0bWwjcGx1Z2luYXJyYXkpXG5cdFx0ICAgICAgICogV2hhdFdHIEhUTUwkOC42LjEuNSAtIFBsdWdpbnMgLSBJbnRlcmZhY2UgUGx1Z2luQXJyYXlcblx0XHQgICAgICAgKiBUZXN0OiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG5hdmlnYXRvci5wbHVnaW5zKWBgXG5cdFx0ICAgICAgICogIC0gSUUgPD0xMCA9PT0gXCJbb2JqZWN0IE1TUGx1Z2luc0NvbGxlY3Rpb25dXCJcblx0XHQgICAgICAgKi9cblx0XHQgICAgICBpZiAodHlwZW9mIHdpbmRvdy5uYXZpZ2F0b3IucGx1Z2lucyA9PT0gJ29iamVjdCcgJiZcblx0XHQgICAgICAgICAgb2JqID09PSB3aW5kb3cubmF2aWdhdG9yLnBsdWdpbnMpIHtcblx0XHQgICAgICAgIHJldHVybiAnUGx1Z2luQXJyYXknO1xuXHRcdCAgICAgIH1cblx0XHQgICAgfVxuXG5cdFx0ICAgIGlmICgodHlwZW9mIHdpbmRvdy5IVE1MRWxlbWVudCA9PT0gJ2Z1bmN0aW9uJyB8fFxuXHRcdCAgICAgICAgdHlwZW9mIHdpbmRvdy5IVE1MRWxlbWVudCA9PT0gJ29iamVjdCcpICYmXG5cdFx0ICAgICAgICBvYmogaW5zdGFuY2VvZiB3aW5kb3cuSFRNTEVsZW1lbnQpIHtcblx0XHQgICAgICAvKiAhIFNwZWMgQ29uZm9ybWFuY2Vcblx0XHQgICAgICAqIChodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS93ZWJhcHBhcGlzLmh0bWwjcGx1Z2luYXJyYXkpXG5cdFx0ICAgICAgKiBXaGF0V0cgSFRNTCQ0LjQuNCAtIFRoZSBgYmxvY2txdW90ZWAgZWxlbWVudCAtIEludGVyZmFjZSBgSFRNTFF1b3RlRWxlbWVudGBcblx0XHQgICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYmxvY2txdW90ZScpKWBgXG5cdFx0ICAgICAgKiAgLSBJRSA8PTEwID09PSBcIltvYmplY3QgSFRNTEJsb2NrRWxlbWVudF1cIlxuXHRcdCAgICAgICovXG5cdFx0ICAgICAgaWYgKG9iai50YWdOYW1lID09PSAnQkxPQ0tRVU9URScpIHtcblx0XHQgICAgICAgIHJldHVybiAnSFRNTFF1b3RlRWxlbWVudCc7XG5cdFx0ICAgICAgfVxuXG5cdFx0ICAgICAgLyogISBTcGVjIENvbmZvcm1hbmNlXG5cdFx0ICAgICAgICogKGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI2h0bWx0YWJsZWRhdGFjZWxsZWxlbWVudClcblx0XHQgICAgICAgKiBXaGF0V0cgSFRNTCQ0LjkuOSAtIFRoZSBgdGRgIGVsZW1lbnQgLSBJbnRlcmZhY2UgYEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudGBcblx0XHQgICAgICAgKiBOb3RlOiBNb3N0IGJyb3dzZXJzIGN1cnJlbnRseSBhZGhlciB0byB0aGUgVzNDIERPTSBMZXZlbCAyIHNwZWNcblx0XHQgICAgICAgKiAgICAgICAoaHR0cHM6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUhUTUwvaHRtbC5odG1sI0lELTgyOTE1MDc1KVxuXHRcdCAgICAgICAqICAgICAgIHdoaWNoIHN1Z2dlc3RzIHRoYXQgYnJvd3NlcnMgc2hvdWxkIHVzZSBIVE1MVGFibGVDZWxsRWxlbWVudCBmb3Jcblx0XHQgICAgICAgKiAgICAgICBib3RoIFREIGFuZCBUSCBlbGVtZW50cy4gV2hhdFdHIHNlcGFyYXRlcyB0aGVzZS5cblx0XHQgICAgICAgKiBUZXN0OiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGQnKSlcblx0XHQgICAgICAgKiAgLSBDaHJvbWUgPT09IFwiW29iamVjdCBIVE1MVGFibGVDZWxsRWxlbWVudF1cIlxuXHRcdCAgICAgICAqICAtIEZpcmVmb3ggPT09IFwiW29iamVjdCBIVE1MVGFibGVDZWxsRWxlbWVudF1cIlxuXHRcdCAgICAgICAqICAtIFNhZmFyaSA9PT0gXCJbb2JqZWN0IEhUTUxUYWJsZUNlbGxFbGVtZW50XVwiXG5cdFx0ICAgICAgICovXG5cdFx0ICAgICAgaWYgKG9iai50YWdOYW1lID09PSAnVEQnKSB7XG5cdFx0ICAgICAgICByZXR1cm4gJ0hUTUxUYWJsZURhdGFDZWxsRWxlbWVudCc7XG5cdFx0ICAgICAgfVxuXG5cdFx0ICAgICAgLyogISBTcGVjIENvbmZvcm1hbmNlXG5cdFx0ICAgICAgICogKGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI2h0bWx0YWJsZWhlYWRlcmNlbGxlbGVtZW50KVxuXHRcdCAgICAgICAqIFdoYXRXRyBIVE1MJDQuOS45IC0gVGhlIGB0ZGAgZWxlbWVudCAtIEludGVyZmFjZSBgSFRNTFRhYmxlSGVhZGVyQ2VsbEVsZW1lbnRgXG5cdFx0ICAgICAgICogTm90ZTogTW9zdCBicm93c2VycyBjdXJyZW50bHkgYWRoZXIgdG8gdGhlIFczQyBET00gTGV2ZWwgMiBzcGVjXG5cdFx0ICAgICAgICogICAgICAgKGh0dHBzOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1IVE1ML2h0bWwuaHRtbCNJRC04MjkxNTA3NSlcblx0XHQgICAgICAgKiAgICAgICB3aGljaCBzdWdnZXN0cyB0aGF0IGJyb3dzZXJzIHNob3VsZCB1c2UgSFRNTFRhYmxlQ2VsbEVsZW1lbnQgZm9yXG5cdFx0ICAgICAgICogICAgICAgYm90aCBURCBhbmQgVEggZWxlbWVudHMuIFdoYXRXRyBzZXBhcmF0ZXMgdGhlc2UuXG5cdFx0ICAgICAgICogVGVzdDogT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RoJykpXG5cdFx0ICAgICAgICogIC0gQ2hyb21lID09PSBcIltvYmplY3QgSFRNTFRhYmxlQ2VsbEVsZW1lbnRdXCJcblx0XHQgICAgICAgKiAgLSBGaXJlZm94ID09PSBcIltvYmplY3QgSFRNTFRhYmxlQ2VsbEVsZW1lbnRdXCJcblx0XHQgICAgICAgKiAgLSBTYWZhcmkgPT09IFwiW29iamVjdCBIVE1MVGFibGVDZWxsRWxlbWVudF1cIlxuXHRcdCAgICAgICAqL1xuXHRcdCAgICAgIGlmIChvYmoudGFnTmFtZSA9PT0gJ1RIJykge1xuXHRcdCAgICAgICAgcmV0dXJuICdIVE1MVGFibGVIZWFkZXJDZWxsRWxlbWVudCc7XG5cdFx0ICAgICAgfVxuXHRcdCAgICB9XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAqIFByZTpcblx0XHQgICogICBGbG9hdDY0QXJyYXkgICAgICAgeCA2MjUsNjQ0IG9wcy9zZWMgwrExLjU4JSAoODAgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiAgIEZsb2F0MzJBcnJheSAgICAgICB4IDEsMjc5LDg1MiBvcHMvc2VjIMKxMi45MSUgKDc3IHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBVaW50MzJBcnJheSAgICAgICAgeCAxLDE3OCwxODUgb3BzL3NlYyDCsTEuOTUlICg4MyBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgVWludDE2QXJyYXkgICAgICAgIHggMSwwMDgsMzgwIG9wcy9zZWMgwrEyLjI1JSAoODAgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiAgIFVpbnQ4QXJyYXkgICAgICAgICB4IDEsMTI4LDA0MCBvcHMvc2VjIMKxMi4xMSUgKDgxIHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBJbnQzMkFycmF5ICAgICAgICAgeCAxLDE3MCwxMTkgb3BzL3NlYyDCsTIuODglICg4MCBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgSW50MTZBcnJheSAgICAgICAgIHggMSwxNzYsMzQ4IG9wcy9zZWMgwrE1Ljc5JSAoODYgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiAgIEludDhBcnJheSAgICAgICAgICB4IDEsMDU4LDcwNyBvcHMvc2VjIMKxNC45NCUgKDc3IHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBVaW50OENsYW1wZWRBcnJheSAgeCAxLDExMCw2MzMgb3BzL3NlYyDCsTQuMjAlICg4MCBydW5zIHNhbXBsZWQpXG5cdFx0ICAqIFBvc3Q6XG5cdFx0ICAqICAgRmxvYXQ2NEFycmF5ICAgICAgIHggNywxMDUsNjcxIG9wcy9zZWMgwrExMy40NyUgKDY0IHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBGbG9hdDMyQXJyYXkgICAgICAgeCA1LDg4Nyw5MTIgb3BzL3NlYyDCsTEuNDYlICg4MiBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgVWludDMyQXJyYXkgICAgICAgIHggNiw0OTEsNjYxIG9wcy9zZWMgwrExLjc2JSAoNzkgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiAgIFVpbnQxNkFycmF5ICAgICAgICB4IDYsNTU5LDc5NSBvcHMvc2VjIMKxMS42NyUgKDgyIHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBVaW50OEFycmF5ICAgICAgICAgeCA2LDQ2Myw5NjYgb3BzL3NlYyDCsTEuNDMlICg4NSBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgSW50MzJBcnJheSAgICAgICAgIHggNSw2NDEsODQxIG9wcy9zZWMgwrEzLjQ5JSAoODEgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiAgIEludDE2QXJyYXkgICAgICAgICB4IDYsNTgzLDUxMSBvcHMvc2VjIMKxMS45OCUgKDgwIHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBJbnQ4QXJyYXkgICAgICAgICAgeCA2LDYwNiwwNzggb3BzL3NlYyDCsTEuNzQlICg4MSBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgVWludDhDbGFtcGVkQXJyYXkgIHggNiw2MDIsMjI0IG9wcy9zZWMgwrExLjc3JSAoODMgcnVucyBzYW1wbGVkKVxuXHRcdCAgKi9cblx0XHQgIHZhciBzdHJpbmdUYWcgPSAoc3ltYm9sVG9TdHJpbmdUYWdFeGlzdHMgJiYgb2JqW1N5bWJvbC50b1N0cmluZ1RhZ10pO1xuXHRcdCAgaWYgKHR5cGVvZiBzdHJpbmdUYWcgPT09ICdzdHJpbmcnKSB7XG5cdFx0ICAgIHJldHVybiBzdHJpbmdUYWc7XG5cdFx0ICB9XG5cblx0XHQgIHZhciBvYmpQcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKTtcblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAqIFByZTpcblx0XHQgICogICByZWdleCBsaXRlcmFsICAgICAgeCAxLDc3MiwzODUgb3BzL3NlYyDCsTEuODUlICg3NyBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgcmVnZXggY29uc3RydWN0b3IgIHggMiwxNDMsNjM0IG9wcy9zZWMgwrEyLjQ2JSAoNzggcnVucyBzYW1wbGVkKVxuXHRcdCAgKiBQb3N0OlxuXHRcdCAgKiAgIHJlZ2V4IGxpdGVyYWwgICAgICB4IDMsOTI4LDAwOSBvcHMvc2VjIMKxMC42NSUgKDc4IHJ1bnMgc2FtcGxlZClcblx0XHQgICogICByZWdleCBjb25zdHJ1Y3RvciAgeCAzLDkzMSwxMDggb3BzL3NlYyDCsTAuNTglICg4NCBydW5zIHNhbXBsZWQpXG5cdFx0ICAqL1xuXHRcdCAgaWYgKG9ialByb3RvdHlwZSA9PT0gUmVnRXhwLnByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ1JlZ0V4cCc7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAqIFByZTpcblx0XHQgICogICBkYXRlICAgICAgICAgICAgICAgeCAyLDEzMCwwNzQgb3BzL3NlYyDCsTQuNDIlICg2OCBydW5zIHNhbXBsZWQpXG5cdFx0ICAqIFBvc3Q6XG5cdFx0ICAqICAgZGF0ZSAgICAgICAgICAgICAgIHggMyw5NTMsNzc5IG9wcy9zZWMgwrExLjM1JSAoNzcgcnVucyBzYW1wbGVkKVxuXHRcdCAgKi9cblx0XHQgIGlmIChvYmpQcm90b3R5cGUgPT09IERhdGUucHJvdG90eXBlKSB7XG5cdFx0ICAgIHJldHVybiAnRGF0ZSc7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICogKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvaW5kZXguaHRtbCNzZWMtcHJvbWlzZS5wcm90b3R5cGUtQEB0b3N0cmluZ3RhZylcblx0XHQgICAqIEVTNiQyNS40LjUuNCAtIFByb21pc2UucHJvdG90eXBlW0BAdG9TdHJpbmdUYWddIHNob3VsZCBiZSBcIlByb21pc2VcIjpcblx0XHQgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoUHJvbWlzZS5yZXNvbHZlKCkpYGBcblx0XHQgICAqICAtIENocm9tZSA8PTQ3ID09PSBcIltvYmplY3QgT2JqZWN0XVwiXG5cdFx0ICAgKiAgLSBFZGdlIDw9MjAgPT09IFwiW29iamVjdCBPYmplY3RdXCJcblx0XHQgICAqICAtIEZpcmVmb3ggMjktTGF0ZXN0ID09PSBcIltvYmplY3QgUHJvbWlzZV1cIlxuXHRcdCAgICogIC0gU2FmYXJpIDcuMS1MYXRlc3QgPT09IFwiW29iamVjdCBQcm9taXNlXVwiXG5cdFx0ICAgKi9cblx0XHQgIGlmIChwcm9taXNlRXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gUHJvbWlzZS5wcm90b3R5cGUpIHtcblx0XHQgICAgcmV0dXJuICdQcm9taXNlJztcblx0XHQgIH1cblxuXHRcdCAgLyogISBTcGVlZCBvcHRpbWlzYXRpb25cblx0XHQgICogUHJlOlxuXHRcdCAgKiAgIHNldCAgICAgICAgICAgICAgICB4IDIsMjIyLDE4NiBvcHMvc2VjIMKxMS4zMSUgKDgyIHJ1bnMgc2FtcGxlZClcblx0XHQgICogUG9zdDpcblx0XHQgICogICBzZXQgICAgICAgICAgICAgICAgeCA0LDU0NSw4Nzkgb3BzL3NlYyDCsTEuMTMlICg4MyBydW5zIHNhbXBsZWQpXG5cdFx0ICAqL1xuXHRcdCAgaWYgKHNldEV4aXN0cyAmJiBvYmpQcm90b3R5cGUgPT09IFNldC5wcm90b3R5cGUpIHtcblx0XHQgICAgcmV0dXJuICdTZXQnO1xuXHRcdCAgfVxuXG5cdFx0ICAvKiAhIFNwZWVkIG9wdGltaXNhdGlvblxuXHRcdCAgKiBQcmU6XG5cdFx0ICAqICAgbWFwICAgICAgICAgICAgICAgIHggMiwzOTYsODQyIG9wcy9zZWMgwrExLjU5JSAoODEgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiBQb3N0OlxuXHRcdCAgKiAgIG1hcCAgICAgICAgICAgICAgICB4IDQsMTgzLDk0NSBvcHMvc2VjIMKxNi41OSUgKDgyIHJ1bnMgc2FtcGxlZClcblx0XHQgICovXG5cdFx0ICBpZiAobWFwRXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gTWFwLnByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ01hcCc7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAqIFByZTpcblx0XHQgICogICB3ZWFrc2V0ICAgICAgICAgICAgeCAxLDMyMywyMjAgb3BzL3NlYyDCsTIuMTclICg3NiBydW5zIHNhbXBsZWQpXG5cdFx0ICAqIFBvc3Q6XG5cdFx0ICAqICAgd2Vha3NldCAgICAgICAgICAgIHggNCwyMzcsNTEwIG9wcy9zZWMgwrEyLjAxJSAoNzcgcnVucyBzYW1wbGVkKVxuXHRcdCAgKi9cblx0XHQgIGlmICh3ZWFrU2V0RXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gV2Vha1NldC5wcm90b3R5cGUpIHtcblx0XHQgICAgcmV0dXJuICdXZWFrU2V0Jztcblx0XHQgIH1cblxuXHRcdCAgLyogISBTcGVlZCBvcHRpbWlzYXRpb25cblx0XHQgICogUHJlOlxuXHRcdCAgKiAgIHdlYWttYXAgICAgICAgICAgICB4IDEsNTAwLDI2MCBvcHMvc2VjIMKxMi4wMiUgKDc4IHJ1bnMgc2FtcGxlZClcblx0XHQgICogUG9zdDpcblx0XHQgICogICB3ZWFrbWFwICAgICAgICAgICAgeCAzLDg4MSwzODQgb3BzL3NlYyDCsTEuNDUlICg4MiBydW5zIHNhbXBsZWQpXG5cdFx0ICAqL1xuXHRcdCAgaWYgKHdlYWtNYXBFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBXZWFrTWFwLnByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ1dlYWtNYXAnO1xuXHRcdCAgfVxuXG5cdFx0ICAvKiAhIFNwZWMgQ29uZm9ybWFuY2Vcblx0XHQgICAqIChodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wL2luZGV4Lmh0bWwjc2VjLWRhdGF2aWV3LnByb3RvdHlwZS1AQHRvc3RyaW5ndGFnKVxuXHRcdCAgICogRVM2JDI0LjIuNC4yMSAtIERhdGFWaWV3LnByb3RvdHlwZVtAQHRvU3RyaW5nVGFnXSBzaG91bGQgYmUgXCJEYXRhVmlld1wiOlxuXHRcdCAgICogVGVzdDogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChuZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDEpKSlgYFxuXHRcdCAgICogIC0gRWRnZSA8PTEzID09PSBcIltvYmplY3QgT2JqZWN0XVwiXG5cdFx0ICAgKi9cblx0XHQgIGlmIChkYXRhVmlld0V4aXN0cyAmJiBvYmpQcm90b3R5cGUgPT09IERhdGFWaWV3LnByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ0RhdGFWaWV3Jztcblx0XHQgIH1cblxuXHRcdCAgLyogISBTcGVjIENvbmZvcm1hbmNlXG5cdFx0ICAgKiAoaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC9pbmRleC5odG1sI3NlYy0lbWFwaXRlcmF0b3Jwcm90b3R5cGUlLUBAdG9zdHJpbmd0YWcpXG5cdFx0ICAgKiBFUzYkMjMuMS41LjIuMiAtICVNYXBJdGVyYXRvclByb3RvdHlwZSVbQEB0b1N0cmluZ1RhZ10gc2hvdWxkIGJlIFwiTWFwIEl0ZXJhdG9yXCI6XG5cdFx0ICAgKiBUZXN0OiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG5ldyBNYXAoKS5lbnRyaWVzKCkpYGBcblx0XHQgICAqICAtIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuXHRcdCAgICovXG5cdFx0ICBpZiAobWFwRXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gbWFwSXRlcmF0b3JQcm90b3R5cGUpIHtcblx0XHQgICAgcmV0dXJuICdNYXAgSXRlcmF0b3InO1xuXHRcdCAgfVxuXG5cdFx0ICAvKiAhIFNwZWMgQ29uZm9ybWFuY2Vcblx0XHQgICAqIChodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wL2luZGV4Lmh0bWwjc2VjLSVzZXRpdGVyYXRvcnByb3RvdHlwZSUtQEB0b3N0cmluZ3RhZylcblx0XHQgICAqIEVTNiQyMy4yLjUuMi4yIC0gJVNldEl0ZXJhdG9yUHJvdG90eXBlJVtAQHRvU3RyaW5nVGFnXSBzaG91bGQgYmUgXCJTZXQgSXRlcmF0b3JcIjpcblx0XHQgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobmV3IFNldCgpLmVudHJpZXMoKSlgYFxuXHRcdCAgICogIC0gRWRnZSA8PTEzID09PSBcIltvYmplY3QgT2JqZWN0XVwiXG5cdFx0ICAgKi9cblx0XHQgIGlmIChzZXRFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBzZXRJdGVyYXRvclByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ1NldCBJdGVyYXRvcic7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICogKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvaW5kZXguaHRtbCNzZWMtJWFycmF5aXRlcmF0b3Jwcm90b3R5cGUlLUBAdG9zdHJpbmd0YWcpXG5cdFx0ICAgKiBFUzYkMjIuMS41LjIuMiAtICVBcnJheUl0ZXJhdG9yUHJvdG90eXBlJVtAQHRvU3RyaW5nVGFnXSBzaG91bGQgYmUgXCJBcnJheSBJdGVyYXRvclwiOlxuXHRcdCAgICogVGVzdDogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChbXVtTeW1ib2wuaXRlcmF0b3JdKCkpYGBcblx0XHQgICAqICAtIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuXHRcdCAgICovXG5cdFx0ICBpZiAoYXJyYXlJdGVyYXRvckV4aXN0cyAmJiBvYmpQcm90b3R5cGUgPT09IGFycmF5SXRlcmF0b3JQcm90b3R5cGUpIHtcblx0XHQgICAgcmV0dXJuICdBcnJheSBJdGVyYXRvcic7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICogKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvaW5kZXguaHRtbCNzZWMtJXN0cmluZ2l0ZXJhdG9ycHJvdG90eXBlJS1AQHRvc3RyaW5ndGFnKVxuXHRcdCAgICogRVM2JDIxLjEuNS4yLjIgLSAlU3RyaW5nSXRlcmF0b3JQcm90b3R5cGUlW0BAdG9TdHJpbmdUYWddIHNob3VsZCBiZSBcIlN0cmluZyBJdGVyYXRvclwiOlxuXHRcdCAgICogVGVzdDogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCgnJ1tTeW1ib2wuaXRlcmF0b3JdKCkpYGBcblx0XHQgICAqICAtIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuXHRcdCAgICovXG5cdFx0ICBpZiAoc3RyaW5nSXRlcmF0b3JFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBzdHJpbmdJdGVyYXRvclByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ1N0cmluZyBJdGVyYXRvcic7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAqIFByZTpcblx0XHQgICogICBvYmplY3QgZnJvbSBudWxsICAgeCAyLDQyNCwzMjAgb3BzL3NlYyDCsTEuNjclICg3NiBydW5zIHNhbXBsZWQpXG5cdFx0ICAqIFBvc3Q6XG5cdFx0ICAqICAgb2JqZWN0IGZyb20gbnVsbCAgIHggNSw4MzgsMDAwIG9wcy9zZWMgwrEwLjk5JSAoODQgcnVucyBzYW1wbGVkKVxuXHRcdCAgKi9cblx0XHQgIGlmIChvYmpQcm90b3R5cGUgPT09IG51bGwpIHtcblx0XHQgICAgcmV0dXJuICdPYmplY3QnO1xuXHRcdCAgfVxuXG5cdFx0ICByZXR1cm4gT2JqZWN0XG5cdFx0ICAgIC5wcm90b3R5cGVcblx0XHQgICAgLnRvU3RyaW5nXG5cdFx0ICAgIC5jYWxsKG9iailcblx0XHQgICAgLnNsaWNlKHRvU3RyaW5nTGVmdFNsaWNlTGVuZ3RoLCB0b1N0cmluZ1JpZ2h0U2xpY2VMZW5ndGgpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0eXBlRGV0ZWN0O1xuXG5cdFx0fSkpKTsgXG5cdH0gKHR5cGVEZXRlY3QkMSkpO1xuXHRyZXR1cm4gdHlwZURldGVjdCQxLmV4cG9ydHM7XG59XG5cbnZhciB0eXBlT2Y7XG52YXIgaGFzUmVxdWlyZWRUeXBlT2Y7XG5cbmZ1bmN0aW9uIHJlcXVpcmVUeXBlT2YgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRUeXBlT2YpIHJldHVybiB0eXBlT2Y7XG5cdGhhc1JlcXVpcmVkVHlwZU9mID0gMTtcblxuXHR2YXIgdHlwZSA9IHJlcXVpcmVUeXBlRGV0ZWN0KCk7XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGxvd2VyLWNhc2UgcmVzdWx0IG9mIHJ1bm5pbmcgdHlwZSBmcm9tIHR5cGUtZGV0ZWN0IG9uIHRoZSB2YWx1ZVxuXHQgKiBAcGFyYW0gIHsqfSB2YWx1ZVxuXHQgKiBAcmV0dXJucyB7c3RyaW5nfVxuXHQgKi9cblx0dHlwZU9mID0gZnVuY3Rpb24gdHlwZU9mKHZhbHVlKSB7XG5cdCAgICByZXR1cm4gdHlwZSh2YWx1ZSkudG9Mb3dlckNhc2UoKTtcblx0fTtcblx0cmV0dXJuIHR5cGVPZjtcbn1cblxudmFyIHZhbHVlVG9TdHJpbmdfMTtcbnZhciBoYXNSZXF1aXJlZFZhbHVlVG9TdHJpbmc7XG5cbmZ1bmN0aW9uIHJlcXVpcmVWYWx1ZVRvU3RyaW5nICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkVmFsdWVUb1N0cmluZykgcmV0dXJuIHZhbHVlVG9TdHJpbmdfMTtcblx0aGFzUmVxdWlyZWRWYWx1ZVRvU3RyaW5nID0gMTtcblxuXHQvKipcblx0ICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmFsdWVcblx0ICogQHBhcmFtICB7Kn0gdmFsdWVcblx0ICogQHJldHVybnMge3N0cmluZ31cblx0ICovXG5cdGZ1bmN0aW9uIHZhbHVlVG9TdHJpbmcodmFsdWUpIHtcblx0ICAgIGlmICh2YWx1ZSAmJiB2YWx1ZS50b1N0cmluZykge1xuXHQgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAc2lub25qcy9uby1wcm90b3R5cGUtbWV0aG9kcy9uby1wcm90b3R5cGUtbWV0aG9kc1xuXHQgICAgICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuXHQgICAgfVxuXHQgICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG5cdH1cblxuXHR2YWx1ZVRvU3RyaW5nXzEgPSB2YWx1ZVRvU3RyaW5nO1xuXHRyZXR1cm4gdmFsdWVUb1N0cmluZ18xO1xufVxuXG52YXIgbGliO1xudmFyIGhhc1JlcXVpcmVkTGliO1xuXG5mdW5jdGlvbiByZXF1aXJlTGliICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkTGliKSByZXR1cm4gbGliO1xuXHRoYXNSZXF1aXJlZExpYiA9IDE7XG5cblx0bGliID0ge1xuXHQgICAgZ2xvYmFsOiByZXF1aXJlR2xvYmFsKCksXG5cdCAgICBjYWxsZWRJbk9yZGVyOiByZXF1aXJlQ2FsbGVkSW5PcmRlcigpLFxuXHQgICAgY2xhc3NOYW1lOiByZXF1aXJlQ2xhc3NOYW1lKCksXG5cdCAgICBkZXByZWNhdGVkOiByZXF1aXJlRGVwcmVjYXRlZCgpLFxuXHQgICAgZXZlcnk6IHJlcXVpcmVFdmVyeSgpLFxuXHQgICAgZnVuY3Rpb25OYW1lOiByZXF1aXJlRnVuY3Rpb25OYW1lKCksXG5cdCAgICBvcmRlckJ5Rmlyc3RDYWxsOiByZXF1aXJlT3JkZXJCeUZpcnN0Q2FsbCgpLFxuXHQgICAgcHJvdG90eXBlczogcmVxdWlyZVByb3RvdHlwZXMoKSxcblx0ICAgIHR5cGVPZjogcmVxdWlyZVR5cGVPZigpLFxuXHQgICAgdmFsdWVUb1N0cmluZzogcmVxdWlyZVZhbHVlVG9TdHJpbmcoKSxcblx0fTtcblx0cmV0dXJuIGxpYjtcbn1cblxudmFyIGhhc1JlcXVpcmVkRmFrZVRpbWVyc1NyYztcblxuZnVuY3Rpb24gcmVxdWlyZUZha2VUaW1lcnNTcmMgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRGYWtlVGltZXJzU3JjKSByZXR1cm4gZmFrZVRpbWVyc1NyYztcblx0aGFzUmVxdWlyZWRGYWtlVGltZXJzU3JjID0gMTtcblxuXHRjb25zdCBnbG9iYWxPYmplY3QgPSByZXF1aXJlTGliKCkuZ2xvYmFsO1xuXHRsZXQgdGltZXJzTW9kdWxlLCB0aW1lcnNQcm9taXNlc01vZHVsZTtcblx0aWYgKHR5cGVvZiBfX3ZpdGVzdF9yZXF1aXJlZF9fICE9PSAndW5kZWZpbmVkJykge1xuXHQgICAgdHJ5IHtcblx0ICAgICAgICB0aW1lcnNNb2R1bGUgPSBfX3ZpdGVzdF9yZXF1aXJlZF9fLnRpbWVycztcblx0ICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAvLyBpZ25vcmVkXG5cdCAgICB9XG5cdCAgICB0cnkge1xuXHQgICAgICAgIHRpbWVyc1Byb21pc2VzTW9kdWxlID0gX192aXRlc3RfcmVxdWlyZWRfXy50aW1lcnNQcm9taXNlcztcblx0ICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAvLyBpZ25vcmVkXG5cdCAgICB9XG5cdH1cblxuXHQvKipcblx0ICogQHR5cGVkZWYge1wibmV4dEFzeW5jXCIgfCBcIm1hbnVhbFwiIHwgXCJpbnRlcnZhbFwifSBUaWNrTW9kZVxuXHQgKi9cblxuXHQvKipcblx0ICogQHR5cGVkZWYge29iamVjdH0gTmV4dEFzeW5jVGlja01vZGVcblx0ICogQHByb3BlcnR5IHtcIm5leHRBc3luY1wifSBtb2RlXG5cdCAqL1xuXG5cdC8qKlxuXHQgKiBAdHlwZWRlZiB7b2JqZWN0fSBNYW51YWxUaWNrTW9kZVxuXHQgKiBAcHJvcGVydHkge1wibWFudWFsXCJ9IG1vZGVcblx0ICovXG5cblx0LyoqXG5cdCAqIEB0eXBlZGVmIHtvYmplY3R9IEludGVydmFsVGlja01vZGVcblx0ICogQHByb3BlcnR5IHtcImludGVydmFsXCJ9IG1vZGVcblx0ICogQHByb3BlcnR5IHtudW1iZXJ9IFtkZWx0YV1cblx0ICovXG5cblx0LyoqXG5cdCAqIEB0eXBlZGVmIHtJbnRlcnZhbFRpY2tNb2RlIHwgTmV4dEFzeW5jVGlja01vZGUgfCBNYW51YWxUaWNrTW9kZX0gVGltZXJUaWNrTW9kZVxuXHQgKi9cblxuXHQvKipcblx0ICogQHR5cGVkZWYge29iamVjdH0gSWRsZURlYWRsaW5lXG5cdCAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gZGlkVGltZW91dCAtIHdoZXRoZXIgb3Igbm90IHRoZSBjYWxsYmFjayB3YXMgY2FsbGVkIGJlZm9yZSByZWFjaGluZyB0aGUgb3B0aW9uYWwgdGltZW91dFxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKCk6bnVtYmVyfSB0aW1lUmVtYWluaW5nIC0gYSBmbG9hdGluZy1wb2ludCB2YWx1ZSBwcm92aWRpbmcgYW4gZXN0aW1hdGUgb2YgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgcmVtYWluaW5nIGluIHRoZSBjdXJyZW50IGlkbGUgcGVyaW9kXG5cdCAqL1xuXG5cdC8qKlxuXHQgKiBRdWV1ZXMgYSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgZHVyaW5nIGEgYnJvd3NlcidzIGlkbGUgcGVyaW9kc1xuXHQgKiBAY2FsbGJhY2sgUmVxdWVzdElkbGVDYWxsYmFja1xuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKElkbGVEZWFkbGluZSl9IGNhbGxiYWNrXG5cdCAqIEBwYXJhbSB7e3RpbWVvdXQ6IG51bWJlcn19IG9wdGlvbnMgLSBhbiBvcHRpb25zIG9iamVjdFxuXHQgKiBAcmV0dXJucyB7bnVtYmVyfSB0aGUgaWRcblx0ICovXG5cblx0LyoqXG5cdCAqIEBjYWxsYmFjayBOZXh0VGlja1xuXHQgKiBAcGFyYW0ge1ZvaWRWYXJBcmdzRnVuY30gY2FsbGJhY2sgLSB0aGUgY2FsbGJhY2sgdG8gcnVuXG5cdCAqIEBwYXJhbSB7Li4uKn0gYXJncyAtIG9wdGlvbmFsIGFyZ3VtZW50cyB0byBjYWxsIHRoZSBjYWxsYmFjayB3aXRoXG5cdCAqIEByZXR1cm5zIHt2b2lkfVxuXHQgKi9cblxuXHQvKipcblx0ICogQGNhbGxiYWNrIFNldEltbWVkaWF0ZVxuXHQgKiBAcGFyYW0ge1ZvaWRWYXJBcmdzRnVuY30gY2FsbGJhY2sgLSB0aGUgY2FsbGJhY2sgdG8gcnVuXG5cdCAqIEBwYXJhbSB7Li4uKn0gYXJncyAtIG9wdGlvbmFsIGFyZ3VtZW50cyB0byBjYWxsIHRoZSBjYWxsYmFjayB3aXRoXG5cdCAqIEByZXR1cm5zIHtOb2RlSW1tZWRpYXRlfVxuXHQgKi9cblxuXHQvKipcblx0ICogQGNhbGxiYWNrIFZvaWRWYXJBcmdzRnVuY1xuXHQgKiBAcGFyYW0gey4uLip9IGNhbGxiYWNrIC0gdGhlIGNhbGxiYWNrIHRvIHJ1blxuXHQgKiBAcmV0dXJucyB7dm9pZH1cblx0ICovXG5cblx0LyoqXG5cdCAqIEB0eXBlZGVmIFJlcXVlc3RBbmltYXRpb25GcmFtZVxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcik6dm9pZH0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lXG5cdCAqIEByZXR1cm5zIHtudW1iZXJ9IC0gdGhlIGlkXG5cdCAqL1xuXG5cdC8qKlxuXHQgKiBAdHlwZWRlZiBQZXJmb3JtYW5jZVxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKCk6IG51bWJlcn0gbm93XG5cdCAqL1xuXG5cdC8qIGVzbGludC1kaXNhYmxlIGpzZG9jL3JlcXVpcmUtcHJvcGVydHktZGVzY3JpcHRpb24gKi9cblx0LyoqXG5cdCAqIEB0eXBlZGVmIHtvYmplY3R9IENsb2NrXG5cdCAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBub3cgLSB0aGUgY3VycmVudCB0aW1lXG5cdCAqIEBwcm9wZXJ0eSB7RGF0ZX0gRGF0ZSAtIHRoZSBEYXRlIGNvbnN0cnVjdG9yXG5cdCAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsb29wTGltaXQgLSB0aGUgbWF4aW11bSBudW1iZXIgb2YgdGltZXJzIGJlZm9yZSBhc3N1bWluZyBhbiBpbmZpbml0ZSBsb29wXG5cdCAqIEBwcm9wZXJ0eSB7UmVxdWVzdElkbGVDYWxsYmFja30gcmVxdWVzdElkbGVDYWxsYmFja1xuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcik6dm9pZH0gY2FuY2VsSWRsZUNhbGxiYWNrXG5cdCAqIEBwcm9wZXJ0eSB7c2V0VGltZW91dH0gc2V0VGltZW91dFxuXHQgKiBAcHJvcGVydHkge2NsZWFyVGltZW91dH0gY2xlYXJUaW1lb3V0XG5cdCAqIEBwcm9wZXJ0eSB7TmV4dFRpY2t9IG5leHRUaWNrXG5cdCAqIEBwcm9wZXJ0eSB7cXVldWVNaWNyb3Rhc2t9IHF1ZXVlTWljcm90YXNrXG5cdCAqIEBwcm9wZXJ0eSB7c2V0SW50ZXJ2YWx9IHNldEludGVydmFsXG5cdCAqIEBwcm9wZXJ0eSB7Y2xlYXJJbnRlcnZhbH0gY2xlYXJJbnRlcnZhbFxuXHQgKiBAcHJvcGVydHkge1NldEltbWVkaWF0ZX0gc2V0SW1tZWRpYXRlXG5cdCAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oTm9kZUltbWVkaWF0ZSk6dm9pZH0gY2xlYXJJbW1lZGlhdGVcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOm51bWJlcn0gY291bnRUaW1lcnNcblx0ICogQHByb3BlcnR5IHtSZXF1ZXN0QW5pbWF0aW9uRnJhbWV9IHJlcXVlc3RBbmltYXRpb25GcmFtZVxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcik6dm9pZH0gY2FuY2VsQW5pbWF0aW9uRnJhbWVcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOnZvaWR9IHJ1bk1pY3JvdGFza3Ncblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbihzdHJpbmcgfCBudW1iZXIpOiBudW1iZXJ9IHRpY2tcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbihzdHJpbmcgfCBudW1iZXIpOiBQcm9taXNlPG51bWJlcj59IHRpY2tBc3luY1xuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKCk6IG51bWJlcn0gbmV4dFxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKCk6IFByb21pc2U8bnVtYmVyPn0gbmV4dEFzeW5jXG5cdCAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oKTogbnVtYmVyfSBydW5BbGxcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBudW1iZXJ9IHJ1blRvRnJhbWVcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBQcm9taXNlPG51bWJlcj59IHJ1bkFsbEFzeW5jXG5cdCAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oKTogbnVtYmVyfSBydW5Ub0xhc3Rcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBQcm9taXNlPG51bWJlcj59IHJ1blRvTGFzdEFzeW5jXG5cdCAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oKTogdm9pZH0gcmVzZXRcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbihudW1iZXIgfCBEYXRlKTogdm9pZH0gc2V0U3lzdGVtVGltZVxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcik6IHZvaWR9IGp1bXBcblx0ICogQHByb3BlcnR5IHtQZXJmb3JtYW5jZX0gcGVyZm9ybWFuY2Vcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbihudW1iZXJbXSk6IG51bWJlcltdfSBocnRpbWUgLSBwcm9jZXNzLmhydGltZSAobGVnYWN5KVxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKCk6IHZvaWR9IHVuaW5zdGFsbCBVbmluc3RhbGwgdGhlIGNsb2NrLlxuXHQgKiBAcHJvcGVydHkge0Z1bmN0aW9uW119IG1ldGhvZHMgLSB0aGUgbWV0aG9kcyB0aGF0IGFyZSBmYWtlZFxuXHQgKiBAcHJvcGVydHkge2Jvb2xlYW59IFtzaG91bGRDbGVhck5hdGl2ZVRpbWVyc10gaW5oZXJpdGVkIGZyb20gY29uZmlnXG5cdCAqIEBwcm9wZXJ0eSB7e21ldGhvZE5hbWU6c3RyaW5nLCBvcmlnaW5hbDphbnl9W10gfCB1bmRlZmluZWR9IHRpbWVyc01vZHVsZU1ldGhvZHNcblx0ICogQHByb3BlcnR5IHt7bWV0aG9kTmFtZTpzdHJpbmcsIG9yaWdpbmFsOmFueX1bXSB8IHVuZGVmaW5lZH0gdGltZXJzUHJvbWlzZXNNb2R1bGVNZXRob2RzXG5cdCAqIEBwcm9wZXJ0eSB7TWFwPGZ1bmN0aW9uKCk6IHZvaWQsIEFib3J0U2lnbmFsPn0gYWJvcnRMaXN0ZW5lck1hcFxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKFRpbWVyVGlja01vZGUpOiB2b2lkfSBzZXRUaWNrTW9kZVxuXHQgKi9cblx0LyogZXNsaW50LWVuYWJsZSBqc2RvYy9yZXF1aXJlLXByb3BlcnR5LWRlc2NyaXB0aW9uICovXG5cblx0LyoqXG5cdCAqIENvbmZpZ3VyYXRpb24gb2JqZWN0IGZvciB0aGUgYGluc3RhbGxgIG1ldGhvZC5cblx0ICogQHR5cGVkZWYge29iamVjdH0gQ29uZmlnXG5cdCAqIEBwcm9wZXJ0eSB7bnVtYmVyfERhdGV9IFtub3ddIGEgbnVtYmVyIChpbiBtaWxsaXNlY29uZHMpIG9yIGEgRGF0ZSBvYmplY3QgKGRlZmF1bHQgZXBvY2gpXG5cdCAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IFt0b0Zha2VdIG5hbWVzIG9mIHRoZSBtZXRob2RzIHRoYXQgc2hvdWxkIGJlIGZha2VkLlxuXHQgKiBAcHJvcGVydHkge251bWJlcn0gW2xvb3BMaW1pdF0gdGhlIG1heGltdW0gbnVtYmVyIG9mIHRpbWVycyB0aGF0IHdpbGwgYmUgcnVuIHdoZW4gY2FsbGluZyBydW5BbGwoKVxuXHQgKiBAcHJvcGVydHkge2Jvb2xlYW59IFtzaG91bGRBZHZhbmNlVGltZV0gdGVsbHMgRmFrZVRpbWVycyB0byBpbmNyZW1lbnQgbW9ja2VkIHRpbWUgYXV0b21hdGljYWxseSAoZGVmYXVsdCBmYWxzZSlcblx0ICogQHByb3BlcnR5IHtudW1iZXJ9IFthZHZhbmNlVGltZURlbHRhXSBpbmNyZW1lbnQgbW9ja2VkIHRpbWUgZXZlcnkgPDxhZHZhbmNlVGltZURlbHRhPj4gbXMgKGRlZmF1bHQ6IDIwbXMpXG5cdCAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3Nob3VsZENsZWFyTmF0aXZlVGltZXJzXSBmb3J3YXJkcyBjbGVhciB0aW1lciBjYWxscyB0byBuYXRpdmUgZnVuY3Rpb25zIGlmIHRoZXkgYXJlIG5vdCBmYWtlcyAoZGVmYXVsdDogZmFsc2UpXG5cdCAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2lnbm9yZU1pc3NpbmdUaW1lcnNdIGRlZmF1bHQgaXMgZmFsc2UsIG1lYW5pbmcgYXNraW5nIHRvIGZha2UgdGltZXJzIHRoYXQgYXJlIG5vdCBwcmVzZW50IHdpbGwgdGhyb3cgYW4gZXJyb3Jcblx0ICovXG5cblx0LyogZXNsaW50LWRpc2FibGUganNkb2MvcmVxdWlyZS1wcm9wZXJ0eS1kZXNjcmlwdGlvbiAqL1xuXHQvKipcblx0ICogVGhlIGludGVybmFsIHN0cnVjdHVyZSB0byBkZXNjcmliZSBhIHNjaGVkdWxlZCBmYWtlIHRpbWVyXG5cdCAqIEB0eXBlZGVmIHtvYmplY3R9IFRpbWVyXG5cdCAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGZ1bmNcblx0ICogQHByb3BlcnR5IHsqW119IGFyZ3Ncblx0ICogQHByb3BlcnR5IHtudW1iZXJ9IGRlbGF5XG5cdCAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjYWxsQXRcblx0ICogQHByb3BlcnR5IHtudW1iZXJ9IGNyZWF0ZWRBdFxuXHQgKiBAcHJvcGVydHkge2Jvb2xlYW59IGltbWVkaWF0ZVxuXHQgKiBAcHJvcGVydHkge251bWJlcn0gaWRcblx0ICogQHByb3BlcnR5IHtFcnJvcn0gW2Vycm9yXVxuXHQgKi9cblxuXHQvKipcblx0ICogQSBOb2RlIHRpbWVyXG5cdCAqIEB0eXBlZGVmIHtvYmplY3R9IE5vZGVJbW1lZGlhdGVcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBib29sZWFufSBoYXNSZWZcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBOb2RlSW1tZWRpYXRlfSByZWZcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBOb2RlSW1tZWRpYXRlfSB1bnJlZlxuXHQgKi9cblx0LyogZXNsaW50LWVuYWJsZSBqc2RvYy9yZXF1aXJlLXByb3BlcnR5LWRlc2NyaXB0aW9uICovXG5cblx0LyogZXNsaW50LWRpc2FibGUgY29tcGxleGl0eSAqL1xuXG5cdC8qKlxuXHQgKiBNb2NrcyBhdmFpbGFibGUgZmVhdHVyZXMgaW4gdGhlIHNwZWNpZmllZCBnbG9iYWwgbmFtZXNwYWNlLlxuXHQgKiBAcGFyYW0geyp9IF9nbG9iYWwgTmFtZXNwYWNlIHRvIG1vY2sgKGUuZy4gYHdpbmRvd2ApXG5cdCAqIEByZXR1cm5zIHtGYWtlVGltZXJzfVxuXHQgKi9cblx0ZnVuY3Rpb24gd2l0aEdsb2JhbChfZ2xvYmFsKSB7XG5cdCAgICBjb25zdCBtYXhUaW1lb3V0ID0gTWF0aC5wb3coMiwgMzEpIC0gMTsgLy9zZWUgaHR0cHM6Ly9oZXljYW0uZ2l0aHViLmlvL3dlYmlkbC8jYWJzdHJhY3Qtb3BkZWYtY29udmVydHRvaW50XG5cdCAgICBjb25zdCBpZENvdW50ZXJTdGFydCA9IDFlMTI7IC8vIGFyYml0cmFyaWx5IGxhcmdlIG51bWJlciB0byBhdm9pZCBjb2xsaXNpb25zIHdpdGggbmF0aXZlIHRpbWVyIElEc1xuXHQgICAgY29uc3QgTk9PUCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuXHQgICAgfTtcblx0ICAgIGNvbnN0IE5PT1BfQVJSQVkgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIFtdO1xuXHQgICAgfTtcblx0ICAgIGNvbnN0IGlzUHJlc2VudCA9IHt9O1xuXHQgICAgbGV0IHRpbWVvdXRSZXN1bHQsXG5cdCAgICAgICAgYWRkVGltZXJSZXR1cm5zT2JqZWN0ID0gZmFsc2U7XG5cblx0ICAgIGlmIChfZ2xvYmFsLnNldFRpbWVvdXQpIHtcblx0ICAgICAgICBpc1ByZXNlbnQuc2V0VGltZW91dCA9IHRydWU7XG5cdCAgICAgICAgdGltZW91dFJlc3VsdCA9IF9nbG9iYWwuc2V0VGltZW91dChOT09QLCAwKTtcblx0ICAgICAgICBhZGRUaW1lclJldHVybnNPYmplY3QgPSB0eXBlb2YgdGltZW91dFJlc3VsdCA9PT0gXCJvYmplY3RcIjtcblx0ICAgIH1cblx0ICAgIGlzUHJlc2VudC5jbGVhclRpbWVvdXQgPSBCb29sZWFuKF9nbG9iYWwuY2xlYXJUaW1lb3V0KTtcblx0ICAgIGlzUHJlc2VudC5zZXRJbnRlcnZhbCA9IEJvb2xlYW4oX2dsb2JhbC5zZXRJbnRlcnZhbCk7XG5cdCAgICBpc1ByZXNlbnQuY2xlYXJJbnRlcnZhbCA9IEJvb2xlYW4oX2dsb2JhbC5jbGVhckludGVydmFsKTtcblx0ICAgIGlzUHJlc2VudC5ocnRpbWUgPVxuXHQgICAgICAgIF9nbG9iYWwucHJvY2VzcyAmJiB0eXBlb2YgX2dsb2JhbC5wcm9jZXNzLmhydGltZSA9PT0gXCJmdW5jdGlvblwiO1xuXHQgICAgaXNQcmVzZW50LmhydGltZUJpZ2ludCA9XG5cdCAgICAgICAgaXNQcmVzZW50LmhydGltZSAmJiB0eXBlb2YgX2dsb2JhbC5wcm9jZXNzLmhydGltZS5iaWdpbnQgPT09IFwiZnVuY3Rpb25cIjtcblx0ICAgIGlzUHJlc2VudC5uZXh0VGljayA9XG5cdCAgICAgICAgX2dsb2JhbC5wcm9jZXNzICYmIHR5cGVvZiBfZ2xvYmFsLnByb2Nlc3MubmV4dFRpY2sgPT09IFwiZnVuY3Rpb25cIjtcblx0ICAgIGNvbnN0IHV0aWxQcm9taXNpZnkgPSBfZ2xvYmFsLnByb2Nlc3MgJiYgX2dsb2JhbC5fX3ZpdGVzdF9yZXF1aXJlZF9fICYmIF9nbG9iYWwuX192aXRlc3RfcmVxdWlyZWRfXy51dGlsLnByb21pc2lmeTtcblx0ICAgIGlzUHJlc2VudC5wZXJmb3JtYW5jZSA9XG5cdCAgICAgICAgX2dsb2JhbC5wZXJmb3JtYW5jZSAmJiB0eXBlb2YgX2dsb2JhbC5wZXJmb3JtYW5jZS5ub3cgPT09IFwiZnVuY3Rpb25cIjtcblx0ICAgIGNvbnN0IGhhc1BlcmZvcm1hbmNlUHJvdG90eXBlID1cblx0ICAgICAgICBfZ2xvYmFsLlBlcmZvcm1hbmNlICYmXG5cdCAgICAgICAgKHR5cGVvZiBfZ2xvYmFsLlBlcmZvcm1hbmNlKS5tYXRjaCgvXihmdW5jdGlvbnxvYmplY3QpJC8pO1xuXHQgICAgY29uc3QgaGFzUGVyZm9ybWFuY2VDb25zdHJ1Y3RvclByb3RvdHlwZSA9XG5cdCAgICAgICAgX2dsb2JhbC5wZXJmb3JtYW5jZSAmJlxuXHQgICAgICAgIF9nbG9iYWwucGVyZm9ybWFuY2UuY29uc3RydWN0b3IgJiZcblx0ICAgICAgICBfZ2xvYmFsLnBlcmZvcm1hbmNlLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcblx0ICAgIGlzUHJlc2VudC5xdWV1ZU1pY3JvdGFzayA9IF9nbG9iYWwuaGFzT3duUHJvcGVydHkoXCJxdWV1ZU1pY3JvdGFza1wiKTtcblx0ICAgIGlzUHJlc2VudC5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPVxuXHQgICAgICAgIF9nbG9iYWwucmVxdWVzdEFuaW1hdGlvbkZyYW1lICYmXG5cdCAgICAgICAgdHlwZW9mIF9nbG9iYWwucmVxdWVzdEFuaW1hdGlvbkZyYW1lID09PSBcImZ1bmN0aW9uXCI7XG5cdCAgICBpc1ByZXNlbnQuY2FuY2VsQW5pbWF0aW9uRnJhbWUgPVxuXHQgICAgICAgIF9nbG9iYWwuY2FuY2VsQW5pbWF0aW9uRnJhbWUgJiZcblx0ICAgICAgICB0eXBlb2YgX2dsb2JhbC5jYW5jZWxBbmltYXRpb25GcmFtZSA9PT0gXCJmdW5jdGlvblwiO1xuXHQgICAgaXNQcmVzZW50LnJlcXVlc3RJZGxlQ2FsbGJhY2sgPVxuXHQgICAgICAgIF9nbG9iYWwucmVxdWVzdElkbGVDYWxsYmFjayAmJlxuXHQgICAgICAgIHR5cGVvZiBfZ2xvYmFsLnJlcXVlc3RJZGxlQ2FsbGJhY2sgPT09IFwiZnVuY3Rpb25cIjtcblx0ICAgIGlzUHJlc2VudC5jYW5jZWxJZGxlQ2FsbGJhY2tQcmVzZW50ID1cblx0ICAgICAgICBfZ2xvYmFsLmNhbmNlbElkbGVDYWxsYmFjayAmJlxuXHQgICAgICAgIHR5cGVvZiBfZ2xvYmFsLmNhbmNlbElkbGVDYWxsYmFjayA9PT0gXCJmdW5jdGlvblwiO1xuXHQgICAgaXNQcmVzZW50LnNldEltbWVkaWF0ZSA9XG5cdCAgICAgICAgX2dsb2JhbC5zZXRJbW1lZGlhdGUgJiYgdHlwZW9mIF9nbG9iYWwuc2V0SW1tZWRpYXRlID09PSBcImZ1bmN0aW9uXCI7XG5cdCAgICBpc1ByZXNlbnQuY2xlYXJJbW1lZGlhdGUgPVxuXHQgICAgICAgIF9nbG9iYWwuY2xlYXJJbW1lZGlhdGUgJiYgdHlwZW9mIF9nbG9iYWwuY2xlYXJJbW1lZGlhdGUgPT09IFwiZnVuY3Rpb25cIjtcblx0ICAgIGlzUHJlc2VudC5JbnRsID0gX2dsb2JhbC5JbnRsICYmIHR5cGVvZiBfZ2xvYmFsLkludGwgPT09IFwib2JqZWN0XCI7XG5cblx0ICAgIGlmIChfZ2xvYmFsLmNsZWFyVGltZW91dCkge1xuXHQgICAgICAgIF9nbG9iYWwuY2xlYXJUaW1lb3V0KHRpbWVvdXRSZXN1bHQpO1xuXHQgICAgfVxuXG5cdCAgICBjb25zdCBOYXRpdmVEYXRlID0gX2dsb2JhbC5EYXRlO1xuXHQgICAgY29uc3QgTmF0aXZlSW50bCA9IGlzUHJlc2VudC5JbnRsXG5cdCAgICAgICAgPyBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhcblx0ICAgICAgICAgICAgICBPYmplY3QuY3JlYXRlKG51bGwpLFxuXHQgICAgICAgICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKF9nbG9iYWwuSW50bCksXG5cdCAgICAgICAgICApXG5cdCAgICAgICAgOiB1bmRlZmluZWQ7XG5cdCAgICBsZXQgdW5pcXVlVGltZXJJZCA9IGlkQ291bnRlclN0YXJ0O1xuXG5cdCAgICBpZiAoTmF0aXZlRGF0ZSA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuXHQgICAgICAgICAgICBcIlRoZSBnbG9iYWwgc2NvcGUgZG9lc24ndCBoYXZlIGEgYERhdGVgIG9iamVjdFwiICtcblx0ICAgICAgICAgICAgICAgIFwiIChzZWUgaHR0cHM6Ly9naXRodWIuY29tL3Npbm9uanMvc2lub24vaXNzdWVzLzE4NTIjaXNzdWVjb21tZW50LTQxOTYyMjc4MClcIixcblx0ICAgICAgICApO1xuXHQgICAgfVxuXHQgICAgaXNQcmVzZW50LkRhdGUgPSB0cnVlO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFRoZSBQZXJmb3JtYW5jZUVudHJ5IG9iamVjdCBlbmNhcHN1bGF0ZXMgYSBzaW5nbGUgcGVyZm9ybWFuY2UgbWV0cmljXG5cdCAgICAgKiB0aGF0IGlzIHBhcnQgb2YgdGhlIGJyb3dzZXIncyBwZXJmb3JtYW5jZSB0aW1lbGluZS5cblx0ICAgICAqXG5cdCAgICAgKiBUaGlzIGlzIGFuIG9iamVjdCByZXR1cm5lZCBieSB0aGUgYG1hcmtgIGFuZCBgbWVhc3VyZWAgbWV0aG9kcyBvbiB0aGUgUGVyZm9ybWFuY2UgcHJvdG90eXBlXG5cdCAgICAgKi9cblx0ICAgIGNsYXNzIEZha2VQZXJmb3JtYW5jZUVudHJ5IHtcblx0ICAgICAgICBjb25zdHJ1Y3RvcihuYW1lLCBlbnRyeVR5cGUsIHN0YXJ0VGltZSwgZHVyYXRpb24pIHtcblx0ICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcblx0ICAgICAgICAgICAgdGhpcy5lbnRyeVR5cGUgPSBlbnRyeVR5cGU7XG5cdCAgICAgICAgICAgIHRoaXMuc3RhcnRUaW1lID0gc3RhcnRUaW1lO1xuXHQgICAgICAgICAgICB0aGlzLmR1cmF0aW9uID0gZHVyYXRpb247XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgdG9KU09OKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoeyAuLi50aGlzIH0pO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBAcGFyYW0ge251bWJlcn0gbnVtXG5cdCAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gaXNOdW1iZXJGaW5pdGUobnVtKSB7XG5cdCAgICAgICAgaWYgKE51bWJlci5pc0Zpbml0ZSkge1xuXHQgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKG51bSk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgcmV0dXJuIGlzRmluaXRlKG51bSk7XG5cdCAgICB9XG5cblx0ICAgIGxldCBpc05lYXJJbmZpbml0ZUxpbWl0ID0gZmFsc2U7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtDbG9ja30gY2xvY2tcblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpXG5cdCAgICAgKi9cblx0ICAgIGZ1bmN0aW9uIGNoZWNrSXNOZWFySW5maW5pdGVMaW1pdChjbG9jaywgaSkge1xuXHQgICAgICAgIGlmIChjbG9jay5sb29wTGltaXQgJiYgaSA9PT0gY2xvY2subG9vcExpbWl0IC0gMSkge1xuXHQgICAgICAgICAgICBpc05lYXJJbmZpbml0ZUxpbWl0ID0gdHJ1ZTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICpcblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gcmVzZXRJc05lYXJJbmZpbml0ZUxpbWl0KCkge1xuXHQgICAgICAgIGlzTmVhckluZmluaXRlTGltaXQgPSBmYWxzZTtcblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBQYXJzZSBzdHJpbmdzIGxpa2UgXCIwMToxMDowMFwiIChtZWFuaW5nIDEgaG91ciwgMTAgbWludXRlcywgMCBzZWNvbmRzKSBpbnRvXG5cdCAgICAgKiBudW1iZXIgb2YgbWlsbGlzZWNvbmRzLiBUaGlzIGlzIHVzZWQgdG8gc3VwcG9ydCBodW1hbi1yZWFkYWJsZSBzdHJpbmdzIHBhc3NlZFxuXHQgICAgICogdG8gY2xvY2sudGljaygpXG5cdCAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyXG5cdCAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBwYXJzZVRpbWUoc3RyKSB7XG5cdCAgICAgICAgaWYgKCFzdHIpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIDA7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY29uc3Qgc3RyaW5ncyA9IHN0ci5zcGxpdChcIjpcIik7XG5cdCAgICAgICAgY29uc3QgbCA9IHN0cmluZ3MubGVuZ3RoO1xuXHQgICAgICAgIGxldCBpID0gbDtcblx0ICAgICAgICBsZXQgbXMgPSAwO1xuXHQgICAgICAgIGxldCBwYXJzZWQ7XG5cblx0ICAgICAgICBpZiAobCA+IDMgfHwgIS9eKFxcZFxcZDopezAsMn1cXGRcXGQ/JC8udGVzdChzdHIpKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcblx0ICAgICAgICAgICAgICAgIFwidGljayBvbmx5IHVuZGVyc3RhbmRzIG51bWJlcnMsICdtOnMnIGFuZCAnaDptOnMnLiBFYWNoIHBhcnQgbXVzdCBiZSB0d28gZGlnaXRzXCIsXG5cdCAgICAgICAgICAgICk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgd2hpbGUgKGktLSkge1xuXHQgICAgICAgICAgICBwYXJzZWQgPSBwYXJzZUludChzdHJpbmdzW2ldLCAxMCk7XG5cblx0ICAgICAgICAgICAgaWYgKHBhcnNlZCA+PSA2MCkge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHRpbWUgJHtzdHJ9YCk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBtcyArPSBwYXJzZWQgKiBNYXRoLnBvdyg2MCwgbCAtIGkgLSAxKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICByZXR1cm4gbXMgKiAxMDAwO1xuXHQgICAgfVxuXG5cdCAgICAvKipcblx0ICAgICAqIEdldCB0aGUgZGVjaW1hbCBwYXJ0IG9mIHRoZSBtaWxsaXNlY29uZCB2YWx1ZSBhcyBuYW5vc2Vjb25kc1xuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IG1zRmxvYXQgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHNcblx0ICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IGFuIGludGVnZXIgbnVtYmVyIG9mIG5hbm9zZWNvbmRzIGluIHRoZSByYW5nZSBbMCwxZTYpXG5cdCAgICAgKlxuXHQgICAgICogRXhhbXBsZTogbmFub1JlbWFpbmVyKDEyMy40NTY3ODkpIC0+IDQ1Njc4OVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBuYW5vUmVtYWluZGVyKG1zRmxvYXQpIHtcblx0ICAgICAgICBjb25zdCBtb2R1bG8gPSAxZTY7XG5cdCAgICAgICAgY29uc3QgcmVtYWluZGVyID0gKG1zRmxvYXQgKiAxZTYpICUgbW9kdWxvO1xuXHQgICAgICAgIGNvbnN0IHBvc2l0aXZlUmVtYWluZGVyID1cblx0ICAgICAgICAgICAgcmVtYWluZGVyIDwgMCA/IHJlbWFpbmRlciArIG1vZHVsbyA6IHJlbWFpbmRlcjtcblxuXHQgICAgICAgIHJldHVybiBNYXRoLmZsb29yKHBvc2l0aXZlUmVtYWluZGVyKTtcblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBVc2VkIHRvIGdyb2sgdGhlIGBub3dgIHBhcmFtZXRlciB0byBjcmVhdGVDbG9jay5cblx0ICAgICAqIEBwYXJhbSB7RGF0ZXxudW1iZXJ9IGVwb2NoIHRoZSBzeXN0ZW0gdGltZVxuXHQgICAgICogQHJldHVybnMge251bWJlcn1cblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gZ2V0RXBvY2goZXBvY2gpIHtcblx0ICAgICAgICBpZiAoIWVwb2NoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiAwO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAodHlwZW9mIGVwb2NoLmdldFRpbWUgPT09IFwiZnVuY3Rpb25cIikge1xuXHQgICAgICAgICAgICByZXR1cm4gZXBvY2guZ2V0VGltZSgpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAodHlwZW9mIGVwb2NoID09PSBcIm51bWJlclwiKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBlcG9jaDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIm5vdyBzaG91bGQgYmUgbWlsbGlzZWNvbmRzIHNpbmNlIFVOSVggZXBvY2hcIik7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IGZyb21cblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSB0b1xuXHQgICAgICogQHBhcmFtIHtUaW1lcn0gdGltZXJcblx0ICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBpblJhbmdlKGZyb20sIHRvLCB0aW1lcikge1xuXHQgICAgICAgIHJldHVybiB0aW1lciAmJiB0aW1lci5jYWxsQXQgPj0gZnJvbSAmJiB0aW1lci5jYWxsQXQgPD0gdG87XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtDbG9ja30gY2xvY2tcblx0ICAgICAqIEBwYXJhbSB7VGltZXJ9IGpvYlxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBnZXRJbmZpbml0ZUxvb3BFcnJvcihjbG9jaywgam9iKSB7XG5cdCAgICAgICAgY29uc3QgaW5maW5pdGVMb29wRXJyb3IgPSBuZXcgRXJyb3IoXG5cdCAgICAgICAgICAgIGBBYm9ydGluZyBhZnRlciBydW5uaW5nICR7Y2xvY2subG9vcExpbWl0fSB0aW1lcnMsIGFzc3VtaW5nIGFuIGluZmluaXRlIGxvb3AhYCxcblx0ICAgICAgICApO1xuXG5cdCAgICAgICAgaWYgKCFqb2IuZXJyb3IpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIGluZmluaXRlTG9vcEVycm9yO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8vIHBhdHRlcm4gbmV2ZXIgbWF0Y2hlZCBpbiBOb2RlXG5cdCAgICAgICAgY29uc3QgY29tcHV0ZWRUYXJnZXRQYXR0ZXJuID0gL3RhcmdldFxcLipbPHwofFtdLio/Wz58XFxdfCldXFxzKi87XG5cdCAgICAgICAgbGV0IGNsb2NrTWV0aG9kUGF0dGVybiA9IG5ldyBSZWdFeHAoXG5cdCAgICAgICAgICAgIFN0cmluZyhPYmplY3Qua2V5cyhjbG9jaykuam9pbihcInxcIikpLFxuXHQgICAgICAgICk7XG5cblx0ICAgICAgICBpZiAoYWRkVGltZXJSZXR1cm5zT2JqZWN0KSB7XG5cdCAgICAgICAgICAgIC8vIG5vZGUuanMgZW52aXJvbm1lbnRcblx0ICAgICAgICAgICAgY2xvY2tNZXRob2RQYXR0ZXJuID0gbmV3IFJlZ0V4cChcblx0ICAgICAgICAgICAgICAgIGBcXFxccythdCAoT2JqZWN0XFxcXC4pPyg/OiR7T2JqZWN0LmtleXMoY2xvY2spLmpvaW4oXCJ8XCIpfSlcXFxccytgLFxuXHQgICAgICAgICAgICApO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGxldCBtYXRjaGVkTGluZUluZGV4ID0gLTE7XG5cdCAgICAgICAgam9iLmVycm9yLnN0YWNrLnNwbGl0KFwiXFxuXCIpLnNvbWUoZnVuY3Rpb24gKGxpbmUsIGkpIHtcblx0ICAgICAgICAgICAgLy8gSWYgd2UndmUgbWF0Y2hlZCBhIGNvbXB1dGVkIHRhcmdldCBsaW5lIChlLmcuIHNldFRpbWVvdXQpIHRoZW4gd2Vcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgbmVlZCB0byBsb29rIGFueSBmdXJ0aGVyLiBSZXR1cm4gdHJ1ZSB0byBzdG9wIGl0ZXJhdGluZy5cblx0ICAgICAgICAgICAgY29uc3QgbWF0Y2hlZENvbXB1dGVkVGFyZ2V0ID0gbGluZS5tYXRjaChjb21wdXRlZFRhcmdldFBhdHRlcm4pO1xuXHQgICAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cblx0ICAgICAgICAgICAgaWYgKG1hdGNoZWRDb21wdXRlZFRhcmdldCkge1xuXHQgICAgICAgICAgICAgICAgbWF0Y2hlZExpbmVJbmRleCA9IGk7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIElmIHdlJ3ZlIG1hdGNoZWQgYSBjbG9jayBtZXRob2QgbGluZSwgdGhlbiB0aGVyZSBtYXkgc3RpbGwgYmVcblx0ICAgICAgICAgICAgLy8gb3RoZXJzIGZ1cnRoZXIgZG93biB0aGUgdHJhY2UuIFJldHVybiBmYWxzZSB0byBrZWVwIGl0ZXJhdGluZy5cblx0ICAgICAgICAgICAgY29uc3QgbWF0Y2hlZENsb2NrTWV0aG9kID0gbGluZS5tYXRjaChjbG9ja01ldGhvZFBhdHRlcm4pO1xuXHQgICAgICAgICAgICBpZiAobWF0Y2hlZENsb2NrTWV0aG9kKSB7XG5cdCAgICAgICAgICAgICAgICBtYXRjaGVkTGluZUluZGV4ID0gaTtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIElmIHdlIGhhdmVuJ3QgbWF0Y2hlZCBhbnl0aGluZyBvbiB0aGlzIGxpbmUsIGJ1dCB3ZSBtYXRjaGVkXG5cdCAgICAgICAgICAgIC8vIHByZXZpb3VzbHkgYW5kIHNldCB0aGUgbWF0Y2hlZCBsaW5lIGluZGV4LCB0aGVuIHdlIGNhbiBzdG9wLlxuXHQgICAgICAgICAgICAvLyBJZiB3ZSBoYXZlbid0IG1hdGNoZWQgcHJldmlvdXNseSwgdGhlbiB3ZSBzaG91bGQga2VlcCBpdGVyYXRpbmcuXG5cdCAgICAgICAgICAgIHJldHVybiBtYXRjaGVkTGluZUluZGV4ID49IDA7XG5cdCAgICAgICAgfSk7XG5cblx0ICAgICAgICBjb25zdCBzdGFjayA9IGAke2luZmluaXRlTG9vcEVycm9yfVxcbiR7am9iLnR5cGUgfHwgXCJNaWNyb3Rhc2tcIn0gLSAke1xuXHQgICAgICAgICAgICBqb2IuZnVuYy5uYW1lIHx8IFwiYW5vbnltb3VzXCJcblx0ICAgICAgICB9XFxuJHtqb2IuZXJyb3Iuc3RhY2tcblx0ICAgICAgICAgICAgLnNwbGl0KFwiXFxuXCIpXG5cdCAgICAgICAgICAgIC5zbGljZShtYXRjaGVkTGluZUluZGV4ICsgMSlcblx0ICAgICAgICAgICAgLmpvaW4oXCJcXG5cIil9YDtcblxuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShpbmZpbml0ZUxvb3BFcnJvciwgXCJzdGFja1wiLCB7XG5cdCAgICAgICAgICAgICAgICB2YWx1ZTogc3RhY2ssXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgLy8gbm9vcFxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIHJldHVybiBpbmZpbml0ZUxvb3BFcnJvcjtcblx0ICAgIH1cblxuXHQgICAgLy9lc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xuXHQgICAgZnVuY3Rpb24gY3JlYXRlRGF0ZSgpIHtcblx0ICAgICAgICBjbGFzcyBDbG9ja0RhdGUgZXh0ZW5kcyBOYXRpdmVEYXRlIHtcblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5ZWFyXG5cdCAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBtb250aFxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gZGF0ZVxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gaG91clxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbWludXRlXG5cdCAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzZWNvbmRcblx0ICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IG1zXG5cdCAgICAgICAgICAgICAqIEByZXR1cm5zIHZvaWRcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuXHQgICAgICAgICAgICBjb25zdHJ1Y3Rvcih5ZWFyLCBtb250aCwgZGF0ZSwgaG91ciwgbWludXRlLCBzZWNvbmQsIG1zKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBEZWZlbnNpdmUgYW5kIHZlcmJvc2UgdG8gYXZvaWQgcG90ZW50aWFsIGhhcm0gaW4gcGFzc2luZ1xuXHQgICAgICAgICAgICAgICAgLy8gZXhwbGljaXQgdW5kZWZpbmVkIHdoZW4gdXNlciBkb2VzIG5vdCBwYXNzIGFyZ3VtZW50XG5cdCAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHN1cGVyKENsb2NrRGF0ZS5jbG9jay5ub3cpO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAvLyBlbnN1cmVzIGlkZW50aXR5IGNoZWNrcyB1c2luZyB0aGUgY29uc3RydWN0b3IgcHJvcCBzdGlsbCB3b3Jrc1xuXHQgICAgICAgICAgICAgICAgLy8gdGhpcyBzaG91bGQgaGF2ZSBubyBvdGhlciBmdW5jdGlvbmFsIGVmZmVjdFxuXHQgICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIFwiY29uc3RydWN0b3JcIiwge1xuXHQgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBOYXRpdmVEYXRlLFxuXHQgICAgICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBzdGF0aWMgW1N5bWJvbC5oYXNJbnN0YW5jZV0oaW5zdGFuY2UpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZSBpbnN0YW5jZW9mIE5hdGl2ZURhdGU7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cblx0ICAgICAgICBDbG9ja0RhdGUuaXNGYWtlID0gdHJ1ZTtcblxuXHQgICAgICAgIGlmIChOYXRpdmVEYXRlLm5vdykge1xuXHQgICAgICAgICAgICBDbG9ja0RhdGUubm93ID0gZnVuY3Rpb24gbm93KCkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIENsb2NrRGF0ZS5jbG9jay5ub3c7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgaWYgKE5hdGl2ZURhdGUudG9Tb3VyY2UpIHtcblx0ICAgICAgICAgICAgQ2xvY2tEYXRlLnRvU291cmNlID0gZnVuY3Rpb24gdG9Tb3VyY2UoKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gTmF0aXZlRGF0ZS50b1NvdXJjZSgpO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIENsb2NrRGF0ZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gTmF0aXZlRGF0ZS50b1N0cmluZygpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICAvLyBub2luc3BlY3Rpb24gVW5uZWNlc3NhcnlMb2NhbFZhcmlhYmxlSlNcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBBIG5vcm1hbCBDbGFzcyBjb25zdHJ1Y3RvciBjYW5ub3QgYmUgY2FsbGVkIHdpdGhvdXQgYG5ld2AsIGJ1dCBEYXRlIGNhbiwgc28gd2UgbmVlZFxuXHQgICAgICAgICAqIHRvIHdyYXAgaXQgaW4gYSBQcm94eSBpbiBvcmRlciB0byBlbnN1cmUgdGhpcyBmdW5jdGlvbmFsaXR5IG9mIERhdGUgaXMga2VwdCBpbnRhY3Rcblx0ICAgICAgICAgKiBAdHlwZSB7Q2xvY2tEYXRlfVxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNvbnN0IENsb2NrRGF0ZVByb3h5ID0gbmV3IFByb3h5KENsb2NrRGF0ZSwge1xuXHQgICAgICAgICAgICAvLyBoYW5kbGVyIGZvciBbW0NhbGxdXSBpbnZvY2F0aW9ucyAoaS5lLiBub3QgdXNpbmcgYG5ld2ApXG5cdCAgICAgICAgICAgIGFwcGx5KCkge1xuXHQgICAgICAgICAgICAgICAgLy8gdGhlIERhdGUgY29uc3RydWN0b3IgY2FsbGVkIGFzIGEgZnVuY3Rpb24sIHJlZiBFY21hLTI2MiBFZGl0aW9uIDUuMSwgc2VjdGlvbiAxNS45LjIuXG5cdCAgICAgICAgICAgICAgICAvLyBUaGlzIHJlbWFpbnMgc28gaW4gdGhlIDEwdGggZWRpdGlvbiBvZiAyMDE5IGFzIHdlbGwuXG5cdCAgICAgICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIENsb2NrRGF0ZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIFwiQSBQcm94eSBzaG91bGQgb25seSBjYXB0dXJlIGBuZXdgIGNhbGxzIHdpdGggdGhlIGBjb25zdHJ1Y3RgIGhhbmRsZXIuIFRoaXMgaXMgbm90IHN1cHBvc2VkIHRvIGJlIHBvc3NpYmxlLCBzbyBjaGVjayB0aGUgbG9naWMuXCIsXG5cdCAgICAgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBOYXRpdmVEYXRlKENsb2NrRGF0ZS5jbG9jay5ub3cpLnRvU3RyaW5nKCk7XG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgfSk7XG5cblx0ICAgICAgICByZXR1cm4gQ2xvY2tEYXRlUHJveHk7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogTWlycm9yIEludGwgYnkgZGVmYXVsdCBvbiBvdXIgZmFrZSBpbXBsZW1lbnRhdGlvblxuXHQgICAgICpcblx0ICAgICAqIE1vc3Qgb2YgdGhlIHByb3BlcnRpZXMgYXJlIHRoZSBvcmlnaW5hbCBuYXRpdmUgb25lcyxcblx0ICAgICAqIGJ1dCB3ZSBuZWVkIHRvIHRha2UgY29udHJvbCBvZiB0aG9zZSB0aGF0IGhhdmUgYVxuXHQgICAgICogZGVwZW5kZW5jeSBvbiB0aGUgY3VycmVudCBjbG9jay5cblx0ICAgICAqIEByZXR1cm5zIHtvYmplY3R9IHRoZSBwYXJ0bHkgZmFrZSBJbnRsIGltcGxlbWVudGF0aW9uXG5cdCAgICAgKi9cblx0ICAgIGZ1bmN0aW9uIGNyZWF0ZUludGwoKSB7XG5cdCAgICAgICAgY29uc3QgQ2xvY2tJbnRsID0ge307XG5cdCAgICAgICAgLypcblx0ICAgICAgICAgKiBBbGwgcHJvcGVydGllcyBvZiBJbnRsIGFyZSBub24tZW51bWVyYWJsZSwgc28gd2UgbmVlZFxuXHQgICAgICAgICAqIHRvIGRvIGEgYml0IG9mIHdvcmsgdG8gZ2V0IHRoZW0gb3V0LlxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKE5hdGl2ZUludGwpLmZvckVhY2goXG5cdCAgICAgICAgICAgIChwcm9wZXJ0eSkgPT4gKENsb2NrSW50bFtwcm9wZXJ0eV0gPSBOYXRpdmVJbnRsW3Byb3BlcnR5XSksXG5cdCAgICAgICAgKTtcblxuXHQgICAgICAgIENsb2NrSW50bC5EYXRlVGltZUZvcm1hdCA9IGZ1bmN0aW9uICguLi5hcmdzKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IHJlYWxGb3JtYXR0ZXIgPSBuZXcgTmF0aXZlSW50bC5EYXRlVGltZUZvcm1hdCguLi5hcmdzKTtcblx0ICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVyID0ge307XG5cblx0ICAgICAgICAgICAgW1wiZm9ybWF0UmFuZ2VcIiwgXCJmb3JtYXRSYW5nZVRvUGFydHNcIiwgXCJyZXNvbHZlZE9wdGlvbnNcIl0uZm9yRWFjaChcblx0ICAgICAgICAgICAgICAgIChtZXRob2QpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICBmb3JtYXR0ZXJbbWV0aG9kXSA9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJlYWxGb3JtYXR0ZXJbbWV0aG9kXS5iaW5kKHJlYWxGb3JtYXR0ZXIpO1xuXHQgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgKTtcblxuXHQgICAgICAgICAgICBbXCJmb3JtYXRcIiwgXCJmb3JtYXRUb1BhcnRzXCJdLmZvckVhY2goKG1ldGhvZCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgZm9ybWF0dGVyW21ldGhvZF0gPSBmdW5jdGlvbiAoZGF0ZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWFsRm9ybWF0dGVyW21ldGhvZF0oZGF0ZSB8fCBDbG9ja0ludGwuY2xvY2subm93KTtcblx0ICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgIH0pO1xuXG5cdCAgICAgICAgICAgIHJldHVybiBmb3JtYXR0ZXI7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIENsb2NrSW50bC5EYXRlVGltZUZvcm1hdC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKFxuXHQgICAgICAgICAgICBOYXRpdmVJbnRsLkRhdGVUaW1lRm9ybWF0LnByb3RvdHlwZSxcblx0ICAgICAgICApO1xuXG5cdCAgICAgICAgQ2xvY2tJbnRsLkRhdGVUaW1lRm9ybWF0LnN1cHBvcnRlZExvY2FsZXNPZiA9XG5cdCAgICAgICAgICAgIE5hdGl2ZUludGwuRGF0ZVRpbWVGb3JtYXQuc3VwcG9ydGVkTG9jYWxlc09mO1xuXG5cdCAgICAgICAgcmV0dXJuIENsb2NrSW50bDtcblx0ICAgIH1cblxuXHQgICAgLy9lc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xuXHQgICAgZnVuY3Rpb24gZW5xdWV1ZUpvYihjbG9jaywgam9iKSB7XG5cdCAgICAgICAgLy8gZW5xdWV1ZXMgYSBtaWNyb3RpY2stZGVmZXJyZWQgdGFzayAtIGVjbWEyNjIvI3NlYy1lbnF1ZXVlam9iXG5cdCAgICAgICAgaWYgKCFjbG9jay5qb2JzKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLmpvYnMgPSBbXTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2xvY2suam9icy5wdXNoKGpvYik7XG5cdCAgICB9XG5cblx0ICAgIC8vZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2Ncblx0ICAgIGZ1bmN0aW9uIHJ1bkpvYnMoY2xvY2spIHtcblx0ICAgICAgICAvLyBydW5zIGFsbCBtaWNyb3RpY2stZGVmZXJyZWQgdGFza3MgLSBlY21hMjYyLyNzZWMtcnVuam9ic1xuXHQgICAgICAgIGlmICghY2xvY2suam9icykge1xuXHQgICAgICAgICAgICByZXR1cm47XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2xvY2suam9icy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICBjb25zdCBqb2IgPSBjbG9jay5qb2JzW2ldO1xuXHQgICAgICAgICAgICBqb2IuZnVuYy5hcHBseShudWxsLCBqb2IuYXJncyk7XG5cblx0ICAgICAgICAgICAgY2hlY2tJc05lYXJJbmZpbml0ZUxpbWl0KGNsb2NrLCBpKTtcblx0ICAgICAgICAgICAgaWYgKGNsb2NrLmxvb3BMaW1pdCAmJiBpID4gY2xvY2subG9vcExpbWl0KSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBnZXRJbmZpbml0ZUxvb3BFcnJvcihjbG9jaywgam9iKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICByZXNldElzTmVhckluZmluaXRlTGltaXQoKTtcblx0ICAgICAgICBjbG9jay5qb2JzID0gW107XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtDbG9ja30gY2xvY2tcblx0ICAgICAqIEBwYXJhbSB7VGltZXJ9IHRpbWVyXG5cdCAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBpZCBvZiB0aGUgY3JlYXRlZCB0aW1lclxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBhZGRUaW1lcihjbG9jaywgdGltZXIpIHtcblx0ICAgICAgICBpZiAodGltZXIuZnVuYyA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbGxiYWNrIG11c3QgYmUgcHJvdmlkZWQgdG8gdGltZXIgY2FsbHNcIik7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgaWYgKGFkZFRpbWVyUmV0dXJuc09iamVjdCkge1xuXHQgICAgICAgICAgICAvLyBOb2RlLmpzIGVudmlyb25tZW50XG5cdCAgICAgICAgICAgIGlmICh0eXBlb2YgdGltZXIuZnVuYyAhPT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuXHQgICAgICAgICAgICAgICAgICAgIGBbRVJSX0lOVkFMSURfQ0FMTEJBQ0tdOiBDYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24uIFJlY2VpdmVkICR7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVyLmZ1bmNcblx0ICAgICAgICAgICAgICAgICAgICB9IG9mIHR5cGUgJHt0eXBlb2YgdGltZXIuZnVuY31gLFxuXHQgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChpc05lYXJJbmZpbml0ZUxpbWl0KSB7XG5cdCAgICAgICAgICAgIHRpbWVyLmVycm9yID0gbmV3IEVycm9yKCk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgdGltZXIudHlwZSA9IHRpbWVyLmltbWVkaWF0ZSA/IFwiSW1tZWRpYXRlXCIgOiBcIlRpbWVvdXRcIjtcblxuXHQgICAgICAgIGlmICh0aW1lci5oYXNPd25Qcm9wZXJ0eShcImRlbGF5XCIpKSB7XG5cdCAgICAgICAgICAgIGlmICh0eXBlb2YgdGltZXIuZGVsYXkgIT09IFwibnVtYmVyXCIpIHtcblx0ICAgICAgICAgICAgICAgIHRpbWVyLmRlbGF5ID0gcGFyc2VJbnQodGltZXIuZGVsYXksIDEwKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIGlmICghaXNOdW1iZXJGaW5pdGUodGltZXIuZGVsYXkpKSB7XG5cdCAgICAgICAgICAgICAgICB0aW1lci5kZWxheSA9IDA7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGltZXIuZGVsYXkgPSB0aW1lci5kZWxheSA+IG1heFRpbWVvdXQgPyAxIDogdGltZXIuZGVsYXk7XG5cdCAgICAgICAgICAgIHRpbWVyLmRlbGF5ID0gTWF0aC5tYXgoMCwgdGltZXIuZGVsYXkpO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmICh0aW1lci5oYXNPd25Qcm9wZXJ0eShcImludGVydmFsXCIpKSB7XG5cdCAgICAgICAgICAgIHRpbWVyLnR5cGUgPSBcIkludGVydmFsXCI7XG5cdCAgICAgICAgICAgIHRpbWVyLmludGVydmFsID0gdGltZXIuaW50ZXJ2YWwgPiBtYXhUaW1lb3V0ID8gMSA6IHRpbWVyLmludGVydmFsO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmICh0aW1lci5oYXNPd25Qcm9wZXJ0eShcImFuaW1hdGlvblwiKSkge1xuXHQgICAgICAgICAgICB0aW1lci50eXBlID0gXCJBbmltYXRpb25GcmFtZVwiO1xuXHQgICAgICAgICAgICB0aW1lci5hbmltYXRpb24gPSB0cnVlO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmICh0aW1lci5oYXNPd25Qcm9wZXJ0eShcImlkbGVDYWxsYmFja1wiKSkge1xuXHQgICAgICAgICAgICB0aW1lci50eXBlID0gXCJJZGxlQ2FsbGJhY2tcIjtcblx0ICAgICAgICAgICAgdGltZXIuaWRsZUNhbGxiYWNrID0gdHJ1ZTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAoIWNsb2NrLnRpbWVycykge1xuXHQgICAgICAgICAgICBjbG9jay50aW1lcnMgPSB7fTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICB0aW1lci5pZCA9IHVuaXF1ZVRpbWVySWQrKztcblx0ICAgICAgICB0aW1lci5jcmVhdGVkQXQgPSBjbG9jay5ub3c7XG5cdCAgICAgICAgdGltZXIuY2FsbEF0ID1cblx0ICAgICAgICAgICAgY2xvY2subm93ICsgKHBhcnNlSW50KHRpbWVyLmRlbGF5KSB8fCAoY2xvY2suZHVyaW5nVGljayA/IDEgOiAwKSk7XG5cblx0ICAgICAgICBjbG9jay50aW1lcnNbdGltZXIuaWRdID0gdGltZXI7XG5cblx0ICAgICAgICBpZiAoYWRkVGltZXJSZXR1cm5zT2JqZWN0KSB7XG5cdCAgICAgICAgICAgIGNvbnN0IHJlcyA9IHtcblx0ICAgICAgICAgICAgICAgIHJlZmVkOiB0cnVlLFxuXHQgICAgICAgICAgICAgICAgcmVmOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWZlZCA9IHRydWU7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcztcblx0ICAgICAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgICAgICB1bnJlZjogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMucmVmZWQgPSBmYWxzZTtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xuXHQgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgICAgIGhhc1JlZjogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnJlZmVkO1xuXHQgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgICAgIHJlZnJlc2g6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aW1lci5jYWxsQXQgPVxuXHQgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay5ub3cgK1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAocGFyc2VJbnQodGltZXIuZGVsYXkpIHx8IChjbG9jay5kdXJpbmdUaWNrID8gMSA6IDApKTtcblxuXHQgICAgICAgICAgICAgICAgICAgIC8vIGl0IF9taWdodF8gaGF2ZSBiZWVuIHJlbW92ZWQsIGJ1dCBpZiBub3QgdGhlIGFzc2lnbm1lbnQgaXMgcGVyZmVjdGx5IGZpbmVcblx0ICAgICAgICAgICAgICAgICAgICBjbG9jay50aW1lcnNbdGltZXIuaWRdID0gdGltZXI7XG5cblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xuXHQgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgICAgIFtTeW1ib2wudG9QcmltaXRpdmVdOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRpbWVyLmlkO1xuXHQgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgcmV0dXJuIHJlcztcblx0ICAgICAgICB9XG5cblx0ICAgICAgICByZXR1cm4gdGltZXIuaWQ7XG5cdCAgICB9XG5cblx0ICAgIC8qIGVzbGludCBjb25zaXN0ZW50LXJldHVybjogXCJvZmZcIiAqL1xuXHQgICAgLyoqXG5cdCAgICAgKiBUaW1lciBjb21wYXJpdG9yXG5cdCAgICAgKiBAcGFyYW0ge1RpbWVyfSBhXG5cdCAgICAgKiBAcGFyYW0ge1RpbWVyfSBiXG5cdCAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBjb21wYXJlVGltZXJzKGEsIGIpIHtcblx0ICAgICAgICAvLyBTb3J0IGZpcnN0IGJ5IGFic29sdXRlIHRpbWluZ1xuXHQgICAgICAgIGlmIChhLmNhbGxBdCA8IGIuY2FsbEF0KSB7XG5cdCAgICAgICAgICAgIHJldHVybiAtMTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKGEuY2FsbEF0ID4gYi5jYWxsQXQpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIDE7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLy8gU29ydCBuZXh0IGJ5IGltbWVkaWF0ZSwgaW1tZWRpYXRlIHRpbWVycyB0YWtlIHByZWNlZGVuY2Vcblx0ICAgICAgICBpZiAoYS5pbW1lZGlhdGUgJiYgIWIuaW1tZWRpYXRlKSB7XG5cdCAgICAgICAgICAgIHJldHVybiAtMTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKCFhLmltbWVkaWF0ZSAmJiBiLmltbWVkaWF0ZSkge1xuXHQgICAgICAgICAgICByZXR1cm4gMTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvLyBTb3J0IG5leHQgYnkgY3JlYXRpb24gdGltZSwgZWFybGllci1jcmVhdGVkIHRpbWVycyB0YWtlIHByZWNlZGVuY2Vcblx0ICAgICAgICBpZiAoYS5jcmVhdGVkQXQgPCBiLmNyZWF0ZWRBdCkge1xuXHQgICAgICAgICAgICByZXR1cm4gLTE7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChhLmNyZWF0ZWRBdCA+IGIuY3JlYXRlZEF0KSB7XG5cdCAgICAgICAgICAgIHJldHVybiAxO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8vIFNvcnQgbmV4dCBieSBpZCwgbG93ZXItaWQgdGltZXJzIHRha2UgcHJlY2VkZW5jZVxuXHQgICAgICAgIGlmIChhLmlkIDwgYi5pZCkge1xuXHQgICAgICAgICAgICByZXR1cm4gLTE7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChhLmlkID4gYi5pZCkge1xuXHQgICAgICAgICAgICByZXR1cm4gMTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvLyBBcyB0aW1lciBpZHMgYXJlIHVuaXF1ZSwgbm8gZmFsbGJhY2sgYDBgIGlzIG5lY2Vzc2FyeVxuXHQgICAgfVxuXG5cdCAgICAvKipcblx0ICAgICAqIEBwYXJhbSB7Q2xvY2t9IGNsb2NrXG5cdCAgICAgKiBAcGFyYW0ge251bWJlcn0gZnJvbVxuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IHRvXG5cdCAgICAgKiBAcmV0dXJucyB7VGltZXJ9XG5cdCAgICAgKi9cblx0ICAgIGZ1bmN0aW9uIGZpcnN0VGltZXJJblJhbmdlKGNsb2NrLCBmcm9tLCB0bykge1xuXHQgICAgICAgIGNvbnN0IHRpbWVycyA9IGNsb2NrLnRpbWVycztcblx0ICAgICAgICBsZXQgdGltZXIgPSBudWxsO1xuXHQgICAgICAgIGxldCBpZCwgaXNJblJhbmdlO1xuXG5cdCAgICAgICAgZm9yIChpZCBpbiB0aW1lcnMpIHtcblx0ICAgICAgICAgICAgaWYgKHRpbWVycy5oYXNPd25Qcm9wZXJ0eShpZCkpIHtcblx0ICAgICAgICAgICAgICAgIGlzSW5SYW5nZSA9IGluUmFuZ2UoZnJvbSwgdG8sIHRpbWVyc1tpZF0pO1xuXG5cdCAgICAgICAgICAgICAgICBpZiAoXG5cdCAgICAgICAgICAgICAgICAgICAgaXNJblJhbmdlICYmXG5cdCAgICAgICAgICAgICAgICAgICAgKCF0aW1lciB8fCBjb21wYXJlVGltZXJzKHRpbWVyLCB0aW1lcnNbaWRdKSA9PT0gMSlcblx0ICAgICAgICAgICAgICAgICkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyID0gdGltZXJzW2lkXTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIHJldHVybiB0aW1lcjtcblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBAcGFyYW0ge0Nsb2NrfSBjbG9ja1xuXHQgICAgICogQHJldHVybnMge1RpbWVyfVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBmaXJzdFRpbWVyKGNsb2NrKSB7XG5cdCAgICAgICAgY29uc3QgdGltZXJzID0gY2xvY2sudGltZXJzO1xuXHQgICAgICAgIGxldCB0aW1lciA9IG51bGw7XG5cdCAgICAgICAgbGV0IGlkO1xuXG5cdCAgICAgICAgZm9yIChpZCBpbiB0aW1lcnMpIHtcblx0ICAgICAgICAgICAgaWYgKHRpbWVycy5oYXNPd25Qcm9wZXJ0eShpZCkpIHtcblx0ICAgICAgICAgICAgICAgIGlmICghdGltZXIgfHwgY29tcGFyZVRpbWVycyh0aW1lciwgdGltZXJzW2lkXSkgPT09IDEpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aW1lciA9IHRpbWVyc1tpZF07XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cblx0ICAgICAgICByZXR1cm4gdGltZXI7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtDbG9ja30gY2xvY2tcblx0ICAgICAqIEByZXR1cm5zIHtUaW1lcn1cblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gbGFzdFRpbWVyKGNsb2NrKSB7XG5cdCAgICAgICAgY29uc3QgdGltZXJzID0gY2xvY2sudGltZXJzO1xuXHQgICAgICAgIGxldCB0aW1lciA9IG51bGw7XG5cdCAgICAgICAgbGV0IGlkO1xuXG5cdCAgICAgICAgZm9yIChpZCBpbiB0aW1lcnMpIHtcblx0ICAgICAgICAgICAgaWYgKHRpbWVycy5oYXNPd25Qcm9wZXJ0eShpZCkpIHtcblx0ICAgICAgICAgICAgICAgIGlmICghdGltZXIgfHwgY29tcGFyZVRpbWVycyh0aW1lciwgdGltZXJzW2lkXSkgPT09IC0xKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGltZXIgPSB0aW1lcnNbaWRdO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgcmV0dXJuIHRpbWVyO1xuXHQgICAgfVxuXG5cdCAgICAvKipcblx0ICAgICAqIEBwYXJhbSB7Q2xvY2t9IGNsb2NrXG5cdCAgICAgKiBAcGFyYW0ge1RpbWVyfSB0aW1lclxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBjYWxsVGltZXIoY2xvY2ssIHRpbWVyKSB7XG5cdCAgICAgICAgaWYgKHR5cGVvZiB0aW1lci5pbnRlcnZhbCA9PT0gXCJudW1iZXJcIikge1xuXHQgICAgICAgICAgICBjbG9jay50aW1lcnNbdGltZXIuaWRdLmNhbGxBdCArPSB0aW1lci5pbnRlcnZhbDtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICBkZWxldGUgY2xvY2sudGltZXJzW3RpbWVyLmlkXTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAodHlwZW9mIHRpbWVyLmZ1bmMgPT09IFwiZnVuY3Rpb25cIikge1xuXHQgICAgICAgICAgICB0aW1lci5mdW5jLmFwcGx5KG51bGwsIHRpbWVyLmFyZ3MpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIC8qIGVzbGludCBuby1ldmFsOiBcIm9mZlwiICovXG5cdCAgICAgICAgICAgIGNvbnN0IGV2YWwyID0gZXZhbDtcblx0ICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgIGV2YWwyKHRpbWVyLmZ1bmMpO1xuXHQgICAgICAgICAgICB9KSgpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIGNsZWFyIGhhbmRsZXIgbmFtZSBmb3IgYSBnaXZlbiB0aW1lciB0eXBlXG5cdCAgICAgKiBAcGFyYW0ge3N0cmluZ30gdHR5cGVcblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gZ2V0Q2xlYXJIYW5kbGVyKHR0eXBlKSB7XG5cdCAgICAgICAgaWYgKHR0eXBlID09PSBcIklkbGVDYWxsYmFja1wiIHx8IHR0eXBlID09PSBcIkFuaW1hdGlvbkZyYW1lXCIpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIGBjYW5jZWwke3R0eXBlfWA7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBgY2xlYXIke3R0eXBlfWA7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyBzY2hlZHVsZSBoYW5kbGVyIG5hbWUgZm9yIGEgZ2l2ZW4gdGltZXIgdHlwZVxuXHQgICAgICogQHBhcmFtIHtzdHJpbmd9IHR0eXBlXG5cdCAgICAgKi9cblx0ICAgIGZ1bmN0aW9uIGdldFNjaGVkdWxlSGFuZGxlcih0dHlwZSkge1xuXHQgICAgICAgIGlmICh0dHlwZSA9PT0gXCJJZGxlQ2FsbGJhY2tcIiB8fCB0dHlwZSA9PT0gXCJBbmltYXRpb25GcmFtZVwiKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBgcmVxdWVzdCR7dHR5cGV9YDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIGBzZXQke3R0eXBlfWA7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQ3JlYXRlcyBhbiBhbm9ueW1vdXMgZnVuY3Rpb24gdG8gd2FybiBvbmx5IG9uY2Vcblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gY3JlYXRlV2Fybk9uY2UoKSB7XG5cdCAgICAgICAgbGV0IGNhbGxzID0gMDtcblx0ICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1zZykge1xuXHQgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblx0ICAgICAgICAgICAgIWNhbGxzKysgJiYgY29uc29sZS53YXJuKG1zZyk7XG5cdCAgICAgICAgfTtcblx0ICAgIH1cblx0ICAgIGNvbnN0IHdhcm5PbmNlID0gY3JlYXRlV2Fybk9uY2UoKTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBAcGFyYW0ge0Nsb2NrfSBjbG9ja1xuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IHRpbWVySWRcblx0ICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0dHlwZVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBjbGVhclRpbWVyKGNsb2NrLCB0aW1lcklkLCB0dHlwZSkge1xuXHQgICAgICAgIGlmICghdGltZXJJZCkge1xuXHQgICAgICAgICAgICAvLyBudWxsIGFwcGVhcnMgdG8gYmUgYWxsb3dlZCBpbiBtb3N0IGJyb3dzZXJzLCBhbmQgYXBwZWFycyB0byBiZVxuXHQgICAgICAgICAgICAvLyByZWxpZWQgdXBvbiBieSBzb21lIGxpYnJhcmllcywgbGlrZSBCb290c3RyYXAgY2Fyb3VzZWxcblx0ICAgICAgICAgICAgcmV0dXJuO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmICghY2xvY2sudGltZXJzKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLnRpbWVycyA9IHt9O1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8vIGluIE5vZGUsIHRoZSBJRCBpcyBzdG9yZWQgYXMgdGhlIHByaW1pdGl2ZSB2YWx1ZSBmb3IgYFRpbWVvdXRgIG9iamVjdHNcblx0ICAgICAgICAvLyBmb3IgYEltbWVkaWF0ZWAgb2JqZWN0cywgbm8gSUQgZXhpc3RzLCBzbyBpdCBnZXRzIGNvZXJjZWQgdG8gTmFOXG5cdCAgICAgICAgY29uc3QgaWQgPSBOdW1iZXIodGltZXJJZCk7XG5cblx0ICAgICAgICBpZiAoTnVtYmVyLmlzTmFOKGlkKSB8fCBpZCA8IGlkQ291bnRlclN0YXJ0KSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGhhbmRsZXJOYW1lID0gZ2V0Q2xlYXJIYW5kbGVyKHR0eXBlKTtcblxuXHQgICAgICAgICAgICBpZiAoY2xvY2suc2hvdWxkQ2xlYXJOYXRpdmVUaW1lcnMgPT09IHRydWUpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUhhbmRsZXIgPSBjbG9ja1tgXyR7aGFuZGxlck5hbWV9YF07XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdHlwZW9mIG5hdGl2ZUhhbmRsZXIgPT09IFwiZnVuY3Rpb25cIlxuXHQgICAgICAgICAgICAgICAgICAgID8gbmF0aXZlSGFuZGxlcih0aW1lcklkKVxuXHQgICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHdhcm5PbmNlKFxuXHQgICAgICAgICAgICAgICAgYEZha2VUaW1lcnM6ICR7aGFuZGxlck5hbWV9IHdhcyBpbnZva2VkIHRvIGNsZWFyIGEgbmF0aXZlIHRpbWVyIGluc3RlYWQgb2Ygb25lIGNyZWF0ZWQgYnkgdGhpcyBsaWJyYXJ5LmAgK1xuXHQgICAgICAgICAgICAgICAgICAgIFwiXFxuVG8gYXV0b21hdGljYWxseSBjbGVhbi11cCBuYXRpdmUgdGltZXJzLCB1c2UgYHNob3VsZENsZWFyTmF0aXZlVGltZXJzYC5cIixcblx0ICAgICAgICAgICAgKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAoY2xvY2sudGltZXJzLmhhc093blByb3BlcnR5KGlkKSkge1xuXHQgICAgICAgICAgICAvLyBjaGVjayB0aGF0IHRoZSBJRCBtYXRjaGVzIGEgdGltZXIgb2YgdGhlIGNvcnJlY3QgdHlwZVxuXHQgICAgICAgICAgICBjb25zdCB0aW1lciA9IGNsb2NrLnRpbWVyc1tpZF07XG5cdCAgICAgICAgICAgIGlmIChcblx0ICAgICAgICAgICAgICAgIHRpbWVyLnR5cGUgPT09IHR0eXBlIHx8XG5cdCAgICAgICAgICAgICAgICAodGltZXIudHlwZSA9PT0gXCJUaW1lb3V0XCIgJiYgdHR5cGUgPT09IFwiSW50ZXJ2YWxcIikgfHxcblx0ICAgICAgICAgICAgICAgICh0aW1lci50eXBlID09PSBcIkludGVydmFsXCIgJiYgdHR5cGUgPT09IFwiVGltZW91dFwiKVxuXHQgICAgICAgICAgICApIHtcblx0ICAgICAgICAgICAgICAgIGRlbGV0ZSBjbG9jay50aW1lcnNbaWRdO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgY2xlYXIgPSBnZXRDbGVhckhhbmRsZXIodHR5cGUpO1xuXHQgICAgICAgICAgICAgICAgY29uc3Qgc2NoZWR1bGUgPSBnZXRTY2hlZHVsZUhhbmRsZXIodGltZXIudHlwZSk7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG5cdCAgICAgICAgICAgICAgICAgICAgYENhbm5vdCBjbGVhciB0aW1lcjogdGltZXIgY3JlYXRlZCB3aXRoICR7c2NoZWR1bGV9KCkgYnV0IGNsZWFyZWQgd2l0aCAke2NsZWFyfSgpYCxcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtDbG9ja30gY2xvY2tcblx0ICAgICAqIEByZXR1cm5zIHtUaW1lcltdfVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiB1bmluc3RhbGwoY2xvY2spIHtcblx0ICAgICAgICBsZXQgbWV0aG9kLCBpLCBsO1xuXHQgICAgICAgIGNvbnN0IGluc3RhbGxlZEhyVGltZSA9IFwiX2hydGltZVwiO1xuXHQgICAgICAgIGNvbnN0IGluc3RhbGxlZE5leHRUaWNrID0gXCJfbmV4dFRpY2tcIjtcblxuXHQgICAgICAgIGZvciAoaSA9IDAsIGwgPSBjbG9jay5tZXRob2RzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuXHQgICAgICAgICAgICBtZXRob2QgPSBjbG9jay5tZXRob2RzW2ldO1xuXHQgICAgICAgICAgICBpZiAobWV0aG9kID09PSBcImhydGltZVwiICYmIF9nbG9iYWwucHJvY2Vzcykge1xuXHQgICAgICAgICAgICAgICAgX2dsb2JhbC5wcm9jZXNzLmhydGltZSA9IGNsb2NrW2luc3RhbGxlZEhyVGltZV07XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAobWV0aG9kID09PSBcIm5leHRUaWNrXCIgJiYgX2dsb2JhbC5wcm9jZXNzKSB7XG5cdCAgICAgICAgICAgICAgICBfZ2xvYmFsLnByb2Nlc3MubmV4dFRpY2sgPSBjbG9ja1tpbnN0YWxsZWROZXh0VGlja107XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAobWV0aG9kID09PSBcInBlcmZvcm1hbmNlXCIpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsUGVyZkRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKFxuXHQgICAgICAgICAgICAgICAgICAgIGNsb2NrLFxuXHQgICAgICAgICAgICAgICAgICAgIGBfJHttZXRob2R9YCxcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICBpZiAoXG5cdCAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxQZXJmRGVzY3JpcHRvciAmJlxuXHQgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsUGVyZkRlc2NyaXB0b3IuZ2V0ICYmXG5cdCAgICAgICAgICAgICAgICAgICAgIW9yaWdpbmFsUGVyZkRlc2NyaXB0b3Iuc2V0XG5cdCAgICAgICAgICAgICAgICApIHtcblx0ICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIF9nbG9iYWwsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxQZXJmRGVzY3JpcHRvcixcblx0ICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvcmlnaW5hbFBlcmZEZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIF9nbG9iYWxbbWV0aG9kXSA9IGNsb2NrW2BfJHttZXRob2R9YF07XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoX2dsb2JhbFttZXRob2RdICYmIF9nbG9iYWxbbWV0aG9kXS5oYWRPd25Qcm9wZXJ0eSkge1xuXHQgICAgICAgICAgICAgICAgICAgIF9nbG9iYWxbbWV0aG9kXSA9IGNsb2NrW2BfJHttZXRob2R9YF07XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBfZ2xvYmFsW21ldGhvZF07XG5cdCAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoaWdub3JlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVzbGludCBuby1lbXB0eTogXCJvZmZcIiAqL1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBpZiAoY2xvY2sudGltZXJzTW9kdWxlTWV0aG9kcyAhPT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNsb2NrLnRpbWVyc01vZHVsZU1ldGhvZHMubGVuZ3RoOyBqKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICBjb25zdCBlbnRyeSA9IGNsb2NrLnRpbWVyc01vZHVsZU1ldGhvZHNbal07XG5cdCAgICAgICAgICAgICAgICAgICAgdGltZXJzTW9kdWxlW2VudHJ5Lm1ldGhvZE5hbWVdID0gZW50cnkub3JpZ2luYWw7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKGNsb2NrLnRpbWVyc1Byb21pc2VzTW9kdWxlTWV0aG9kcyAhPT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgICAgICAgICBmb3IgKFxuXHQgICAgICAgICAgICAgICAgICAgIGxldCBqID0gMDtcblx0ICAgICAgICAgICAgICAgICAgICBqIDwgY2xvY2sudGltZXJzUHJvbWlzZXNNb2R1bGVNZXRob2RzLmxlbmd0aDtcblx0ICAgICAgICAgICAgICAgICAgICBqKytcblx0ICAgICAgICAgICAgICAgICkge1xuXHQgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVudHJ5ID0gY2xvY2sudGltZXJzUHJvbWlzZXNNb2R1bGVNZXRob2RzW2pdO1xuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyc1Byb21pc2VzTW9kdWxlW2VudHJ5Lm1ldGhvZE5hbWVdID0gZW50cnkub3JpZ2luYWw7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cblx0ICAgICAgICBjbG9jay5zZXRUaWNrTW9kZShcIm1hbnVhbFwiKTtcblxuXHQgICAgICAgIC8vIFByZXZlbnQgbXVsdGlwbGUgZXhlY3V0aW9ucyB3aGljaCB3aWxsIGNvbXBsZXRlbHkgcmVtb3ZlIHRoZXNlIHByb3BzXG5cdCAgICAgICAgY2xvY2subWV0aG9kcyA9IFtdO1xuXG5cdCAgICAgICAgZm9yIChjb25zdCBbbGlzdGVuZXIsIHNpZ25hbF0gb2YgY2xvY2suYWJvcnRMaXN0ZW5lck1hcC5lbnRyaWVzKCkpIHtcblx0ICAgICAgICAgICAgc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJhYm9ydFwiLCBsaXN0ZW5lcik7XG5cdCAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuZGVsZXRlKGxpc3RlbmVyKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvLyByZXR1cm4gcGVuZGluZyB0aW1lcnMsIHRvIGVuYWJsZSBjaGVja2luZyB3aGF0IHRpbWVycyByZW1haW5lZCBvbiB1bmluc3RhbGxcblx0ICAgICAgICBpZiAoIWNsb2NrLnRpbWVycykge1xuXHQgICAgICAgICAgICByZXR1cm4gW107XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhjbG9jay50aW1lcnMpLm1hcChmdW5jdGlvbiBtYXBwZXIoa2V5KSB7XG5cdCAgICAgICAgICAgIHJldHVybiBjbG9jay50aW1lcnNba2V5XTtcblx0ICAgICAgICB9KTtcblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBAcGFyYW0ge29iamVjdH0gdGFyZ2V0IHRoZSB0YXJnZXQgY29udGFpbmluZyB0aGUgbWV0aG9kIHRvIHJlcGxhY2Vcblx0ICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXRob2QgdGhlIGtleW5hbWUgb2YgdGhlIG1ldGhvZCBvbiB0aGUgdGFyZ2V0XG5cdCAgICAgKiBAcGFyYW0ge0Nsb2NrfSBjbG9ja1xuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBoaWphY2tNZXRob2QodGFyZ2V0LCBtZXRob2QsIGNsb2NrKSB7XG5cdCAgICAgICAgY2xvY2tbbWV0aG9kXS5oYWRPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChcblx0ICAgICAgICAgICAgdGFyZ2V0LFxuXHQgICAgICAgICAgICBtZXRob2QsXG5cdCAgICAgICAgKTtcblx0ICAgICAgICBjbG9ja1tgXyR7bWV0aG9kfWBdID0gdGFyZ2V0W21ldGhvZF07XG5cblx0ICAgICAgICBpZiAobWV0aG9kID09PSBcIkRhdGVcIikge1xuXHQgICAgICAgICAgICB0YXJnZXRbbWV0aG9kXSA9IGNsb2NrW21ldGhvZF07XG5cdCAgICAgICAgfSBlbHNlIGlmIChtZXRob2QgPT09IFwiSW50bFwiKSB7XG5cdCAgICAgICAgICAgIHRhcmdldFttZXRob2RdID0gY2xvY2tbbWV0aG9kXTtcblx0ICAgICAgICB9IGVsc2UgaWYgKG1ldGhvZCA9PT0gXCJwZXJmb3JtYW5jZVwiKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsUGVyZkRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKFxuXHQgICAgICAgICAgICAgICAgdGFyZ2V0LFxuXHQgICAgICAgICAgICAgICAgbWV0aG9kLFxuXHQgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAvLyBKU0RPTSBoYXMgYSByZWFkIG9ubHkgcGVyZm9ybWFuY2UgZmllbGQgc28gd2UgaGF2ZSB0byBzYXZlL2NvcHkgaXQgZGlmZmVyZW50bHlcblx0ICAgICAgICAgICAgaWYgKFxuXHQgICAgICAgICAgICAgICAgb3JpZ2luYWxQZXJmRGVzY3JpcHRvciAmJlxuXHQgICAgICAgICAgICAgICAgb3JpZ2luYWxQZXJmRGVzY3JpcHRvci5nZXQgJiZcblx0ICAgICAgICAgICAgICAgICFvcmlnaW5hbFBlcmZEZXNjcmlwdG9yLnNldFxuXHQgICAgICAgICAgICApIHtcblx0ICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShcblx0ICAgICAgICAgICAgICAgICAgICBjbG9jayxcblx0ICAgICAgICAgICAgICAgICAgICBgXyR7bWV0aG9kfWAsXG5cdCAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxQZXJmRGVzY3JpcHRvcixcblx0ICAgICAgICAgICAgICAgICk7XG5cblx0ICAgICAgICAgICAgICAgIGNvbnN0IHBlcmZEZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihcblx0ICAgICAgICAgICAgICAgICAgICBjbG9jayxcblx0ICAgICAgICAgICAgICAgICAgICBtZXRob2QsXG5cdCAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgbWV0aG9kLCBwZXJmRGVzY3JpcHRvcik7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICB0YXJnZXRbbWV0aG9kXSA9IGNsb2NrW21ldGhvZF07XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICB0YXJnZXRbbWV0aG9kXSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBjbG9ja1ttZXRob2RdLmFwcGx5KGNsb2NrLCBhcmd1bWVudHMpO1xuXHQgICAgICAgICAgICB9O1xuXG5cdCAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFxuXHQgICAgICAgICAgICAgICAgdGFyZ2V0W21ldGhvZF0sXG5cdCAgICAgICAgICAgICAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhjbG9ja1ttZXRob2RdKSxcblx0ICAgICAgICAgICAgKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICB0YXJnZXRbbWV0aG9kXS5jbG9jayA9IGNsb2NrO1xuXHQgICAgfVxuXG5cdCAgICAvKipcblx0ICAgICAqIEBwYXJhbSB7Q2xvY2t9IGNsb2NrXG5cdCAgICAgKiBAcGFyYW0ge251bWJlcn0gYWR2YW5jZVRpbWVEZWx0YVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBkb0ludGVydmFsVGljayhjbG9jaywgYWR2YW5jZVRpbWVEZWx0YSkge1xuXHQgICAgICAgIGNsb2NrLnRpY2soYWR2YW5jZVRpbWVEZWx0YSk7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHR5cGVkZWYge29iamVjdH0gVGltZXJzXG5cdCAgICAgKiBAcHJvcGVydHkge3NldFRpbWVvdXR9IHNldFRpbWVvdXRcblx0ICAgICAqIEBwcm9wZXJ0eSB7Y2xlYXJUaW1lb3V0fSBjbGVhclRpbWVvdXRcblx0ICAgICAqIEBwcm9wZXJ0eSB7c2V0SW50ZXJ2YWx9IHNldEludGVydmFsXG5cdCAgICAgKiBAcHJvcGVydHkge2NsZWFySW50ZXJ2YWx9IGNsZWFySW50ZXJ2YWxcblx0ICAgICAqIEBwcm9wZXJ0eSB7RGF0ZX0gRGF0ZVxuXHQgICAgICogQHByb3BlcnR5IHtJbnRsfSBJbnRsXG5cdCAgICAgKiBAcHJvcGVydHkge1NldEltbWVkaWF0ZT19IHNldEltbWVkaWF0ZVxuXHQgICAgICogQHByb3BlcnR5IHtmdW5jdGlvbihOb2RlSW1tZWRpYXRlKTogdm9pZD19IGNsZWFySW1tZWRpYXRlXG5cdCAgICAgKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcltdKTpudW1iZXJbXT19IGhydGltZVxuXHQgICAgICogQHByb3BlcnR5IHtOZXh0VGljaz19IG5leHRUaWNrXG5cdCAgICAgKiBAcHJvcGVydHkge1BlcmZvcm1hbmNlPX0gcGVyZm9ybWFuY2Vcblx0ICAgICAqIEBwcm9wZXJ0eSB7UmVxdWVzdEFuaW1hdGlvbkZyYW1lPX0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lXG5cdCAgICAgKiBAcHJvcGVydHkge2Jvb2xlYW49fSBxdWV1ZU1pY3JvdGFza1xuXHQgICAgICogQHByb3BlcnR5IHtmdW5jdGlvbihudW1iZXIpOiB2b2lkPX0gY2FuY2VsQW5pbWF0aW9uRnJhbWVcblx0ICAgICAqIEBwcm9wZXJ0eSB7UmVxdWVzdElkbGVDYWxsYmFjaz19IHJlcXVlc3RJZGxlQ2FsbGJhY2tcblx0ICAgICAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24obnVtYmVyKTogdm9pZD19IGNhbmNlbElkbGVDYWxsYmFja1xuXHQgICAgICovXG5cblx0ICAgIC8qKiBAdHlwZSB7VGltZXJzfSAqL1xuXHQgICAgY29uc3QgdGltZXJzID0ge1xuXHQgICAgICAgIHNldFRpbWVvdXQ6IF9nbG9iYWwuc2V0VGltZW91dCxcblx0ICAgICAgICBjbGVhclRpbWVvdXQ6IF9nbG9iYWwuY2xlYXJUaW1lb3V0LFxuXHQgICAgICAgIHNldEludGVydmFsOiBfZ2xvYmFsLnNldEludGVydmFsLFxuXHQgICAgICAgIGNsZWFySW50ZXJ2YWw6IF9nbG9iYWwuY2xlYXJJbnRlcnZhbCxcblx0ICAgICAgICBEYXRlOiBfZ2xvYmFsLkRhdGUsXG5cdCAgICB9O1xuXG5cdCAgICBpZiAoaXNQcmVzZW50LnNldEltbWVkaWF0ZSkge1xuXHQgICAgICAgIHRpbWVycy5zZXRJbW1lZGlhdGUgPSBfZ2xvYmFsLnNldEltbWVkaWF0ZTtcblx0ICAgIH1cblxuXHQgICAgaWYgKGlzUHJlc2VudC5jbGVhckltbWVkaWF0ZSkge1xuXHQgICAgICAgIHRpbWVycy5jbGVhckltbWVkaWF0ZSA9IF9nbG9iYWwuY2xlYXJJbW1lZGlhdGU7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc1ByZXNlbnQuaHJ0aW1lKSB7XG5cdCAgICAgICAgdGltZXJzLmhydGltZSA9IF9nbG9iYWwucHJvY2Vzcy5ocnRpbWU7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc1ByZXNlbnQubmV4dFRpY2spIHtcblx0ICAgICAgICB0aW1lcnMubmV4dFRpY2sgPSBfZ2xvYmFsLnByb2Nlc3MubmV4dFRpY2s7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc1ByZXNlbnQucGVyZm9ybWFuY2UpIHtcblx0ICAgICAgICB0aW1lcnMucGVyZm9ybWFuY2UgPSBfZ2xvYmFsLnBlcmZvcm1hbmNlO1xuXHQgICAgfVxuXG5cdCAgICBpZiAoaXNQcmVzZW50LnJlcXVlc3RBbmltYXRpb25GcmFtZSkge1xuXHQgICAgICAgIHRpbWVycy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPSBfZ2xvYmFsLnJlcXVlc3RBbmltYXRpb25GcmFtZTtcblx0ICAgIH1cblxuXHQgICAgaWYgKGlzUHJlc2VudC5xdWV1ZU1pY3JvdGFzaykge1xuXHQgICAgICAgIHRpbWVycy5xdWV1ZU1pY3JvdGFzayA9IF9nbG9iYWwucXVldWVNaWNyb3Rhc2s7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc1ByZXNlbnQuY2FuY2VsQW5pbWF0aW9uRnJhbWUpIHtcblx0ICAgICAgICB0aW1lcnMuY2FuY2VsQW5pbWF0aW9uRnJhbWUgPSBfZ2xvYmFsLmNhbmNlbEFuaW1hdGlvbkZyYW1lO1xuXHQgICAgfVxuXG5cdCAgICBpZiAoaXNQcmVzZW50LnJlcXVlc3RJZGxlQ2FsbGJhY2spIHtcblx0ICAgICAgICB0aW1lcnMucmVxdWVzdElkbGVDYWxsYmFjayA9IF9nbG9iYWwucmVxdWVzdElkbGVDYWxsYmFjaztcblx0ICAgIH1cblxuXHQgICAgaWYgKGlzUHJlc2VudC5jYW5jZWxJZGxlQ2FsbGJhY2spIHtcblx0ICAgICAgICB0aW1lcnMuY2FuY2VsSWRsZUNhbGxiYWNrID0gX2dsb2JhbC5jYW5jZWxJZGxlQ2FsbGJhY2s7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc1ByZXNlbnQuSW50bCkge1xuXHQgICAgICAgIHRpbWVycy5JbnRsID0gTmF0aXZlSW50bDtcblx0ICAgIH1cblxuXHQgICAgY29uc3Qgb3JpZ2luYWxTZXRUaW1lb3V0ID0gX2dsb2JhbC5zZXRJbW1lZGlhdGUgfHwgX2dsb2JhbC5zZXRUaW1lb3V0O1xuXHQgICAgY29uc3Qgb3JpZ2luYWxDbGVhckludGVydmFsID0gX2dsb2JhbC5jbGVhckludGVydmFsO1xuXHQgICAgY29uc3Qgb3JpZ2luYWxTZXRJbnRlcnZhbCA9IF9nbG9iYWwuc2V0SW50ZXJ2YWw7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtEYXRlfG51bWJlcn0gW3N0YXJ0XSB0aGUgc3lzdGVtIHRpbWUgLSBub24taW50ZWdlciB2YWx1ZXMgYXJlIGZsb29yZWRcblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbG9vcExpbWl0XSBtYXhpbXVtIG51bWJlciBvZiB0aW1lcnMgdGhhdCB3aWxsIGJlIHJ1biB3aGVuIGNhbGxpbmcgcnVuQWxsKClcblx0ICAgICAqIEByZXR1cm5zIHtDbG9ja31cblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gY3JlYXRlQ2xvY2soc3RhcnQsIGxvb3BMaW1pdCkge1xuXHQgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHQgICAgICAgIHN0YXJ0ID0gTWF0aC5mbG9vcihnZXRFcG9jaChzdGFydCkpO1xuXHQgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHQgICAgICAgIGxvb3BMaW1pdCA9IGxvb3BMaW1pdCB8fCAxMDAwO1xuXHQgICAgICAgIGxldCBuYW5vcyA9IDA7XG5cdCAgICAgICAgY29uc3QgYWRqdXN0ZWRTeXN0ZW1UaW1lID0gWzAsIDBdOyAvLyBbbWlsbGlzLCBuYW5vcmVtYWluZGVyXVxuXG5cdCAgICAgICAgY29uc3QgY2xvY2sgPSB7XG5cdCAgICAgICAgICAgIG5vdzogc3RhcnQsXG5cdCAgICAgICAgICAgIERhdGU6IGNyZWF0ZURhdGUoKSxcblx0ICAgICAgICAgICAgbG9vcExpbWl0OiBsb29wTGltaXQsXG5cdCAgICAgICAgICAgIHRpY2tNb2RlOiB7IG1vZGU6IFwibWFudWFsXCIsIGNvdW50ZXI6IDAsIGRlbHRhOiB1bmRlZmluZWQgfSxcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2suRGF0ZS5jbG9jayA9IGNsb2NrO1xuXG5cdCAgICAgICAgLy9lc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xuXHQgICAgICAgIGZ1bmN0aW9uIGdldFRpbWVUb05leHRGcmFtZSgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIDE2IC0gKChjbG9jay5ub3cgLSBzdGFydCkgJSAxNik7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLy9lc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xuXHQgICAgICAgIGZ1bmN0aW9uIGhydGltZShwcmV2KSB7XG5cdCAgICAgICAgICAgIGNvbnN0IG1pbGxpc1NpbmNlU3RhcnQgPSBjbG9jay5ub3cgLSBhZGp1c3RlZFN5c3RlbVRpbWVbMF0gLSBzdGFydDtcblx0ICAgICAgICAgICAgY29uc3Qgc2Vjc1NpbmNlU3RhcnQgPSBNYXRoLmZsb29yKG1pbGxpc1NpbmNlU3RhcnQgLyAxMDAwKTtcblx0ICAgICAgICAgICAgY29uc3QgcmVtYWluZGVySW5OYW5vcyA9XG5cdCAgICAgICAgICAgICAgICAobWlsbGlzU2luY2VTdGFydCAtIHNlY3NTaW5jZVN0YXJ0ICogMWUzKSAqIDFlNiArXG5cdCAgICAgICAgICAgICAgICBuYW5vcyAtXG5cdCAgICAgICAgICAgICAgICBhZGp1c3RlZFN5c3RlbVRpbWVbMV07XG5cblx0ICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocHJldikpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChwcmV2WzFdID4gMWU5KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgXCJOdW1iZXIgb2YgbmFub3NlY29uZHMgY2FuJ3QgZXhjZWVkIGEgYmlsbGlvblwiLFxuXHQgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIGNvbnN0IG9sZFNlY3MgPSBwcmV2WzBdO1xuXHQgICAgICAgICAgICAgICAgbGV0IG5hbm9EaWZmID0gcmVtYWluZGVySW5OYW5vcyAtIHByZXZbMV07XG5cdCAgICAgICAgICAgICAgICBsZXQgc2VjRGlmZiA9IHNlY3NTaW5jZVN0YXJ0IC0gb2xkU2VjcztcblxuXHQgICAgICAgICAgICAgICAgaWYgKG5hbm9EaWZmIDwgMCkge1xuXHQgICAgICAgICAgICAgICAgICAgIG5hbm9EaWZmICs9IDFlOTtcblx0ICAgICAgICAgICAgICAgICAgICBzZWNEaWZmIC09IDE7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIHJldHVybiBbc2VjRGlmZiwgbmFub0RpZmZdO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHJldHVybiBbc2Vjc1NpbmNlU3RhcnQsIHJlbWFpbmRlckluTmFub3NdO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEEgaGlnaCByZXNvbHV0aW9uIHRpbWVzdGFtcCBpbiBtaWxsaXNlY29uZHMuXG5cdCAgICAgICAgICogQHR5cGVkZWYge251bWJlcn0gRE9NSGlnaFJlc1RpbWVTdGFtcFxuXHQgICAgICAgICAqL1xuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogcGVyZm9ybWFuY2Uubm93KClcblx0ICAgICAgICAgKiBAcmV0dXJucyB7RE9NSGlnaFJlc1RpbWVTdGFtcH1cblx0ICAgICAgICAgKi9cblx0ICAgICAgICBmdW5jdGlvbiBmYWtlUGVyZm9ybWFuY2VOb3coKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGhydCA9IGhydGltZSgpO1xuXHQgICAgICAgICAgICBjb25zdCBtaWxsaXMgPSBocnRbMF0gKiAxMDAwICsgaHJ0WzFdIC8gMWU2O1xuXHQgICAgICAgICAgICByZXR1cm4gbWlsbGlzO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChpc1ByZXNlbnQuaHJ0aW1lQmlnaW50KSB7XG5cdCAgICAgICAgICAgIGhydGltZS5iaWdpbnQgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBwYXJ0cyA9IGhydGltZSgpO1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIEJpZ0ludChwYXJ0c1swXSkgKiBCaWdJbnQoMWU5KSArIEJpZ0ludChwYXJ0c1sxXSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAoaXNQcmVzZW50LkludGwpIHtcblx0ICAgICAgICAgICAgY2xvY2suSW50bCA9IGNyZWF0ZUludGwoKTtcblx0ICAgICAgICAgICAgY2xvY2suSW50bC5jbG9jayA9IGNsb2NrO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEBwYXJhbSB7VGltZXJUaWNrTW9kZX0gdGlja01vZGVDb25maWcgLSBUaGUgbmV3IGNvbmZpZ3VyYXRpb24gZm9yIGhvdyB0aGUgY2xvY2sgc2hvdWxkIHRpY2suXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2xvY2suc2V0VGlja01vZGUgPSBmdW5jdGlvbiAodGlja01vZGVDb25maWcpIHtcblx0ICAgICAgICAgICAgY29uc3QgeyBtb2RlOiBuZXdNb2RlLCBkZWx0YTogbmV3RGVsdGEgfSA9IHRpY2tNb2RlQ29uZmlnO1xuXHQgICAgICAgICAgICBjb25zdCB7IG1vZGU6IG9sZE1vZGUsIGRlbHRhOiBvbGREZWx0YSB9ID0gY2xvY2sudGlja01vZGU7XG5cdCAgICAgICAgICAgIGlmIChuZXdNb2RlID09PSBvbGRNb2RlICYmIG5ld0RlbHRhID09PSBvbGREZWx0YSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgaWYgKG9sZE1vZGUgPT09IFwiaW50ZXJ2YWxcIikge1xuXHQgICAgICAgICAgICAgICAgb3JpZ2luYWxDbGVhckludGVydmFsKGNsb2NrLmF0dGFjaGVkSW50ZXJ2YWwpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgY2xvY2sudGlja01vZGUgPSB7XG5cdCAgICAgICAgICAgICAgICBjb3VudGVyOiBjbG9jay50aWNrTW9kZS5jb3VudGVyICsgMSxcblx0ICAgICAgICAgICAgICAgIG1vZGU6IG5ld01vZGUsXG5cdCAgICAgICAgICAgICAgICBkZWx0YTogbmV3RGVsdGEsXG5cdCAgICAgICAgICAgIH07XG5cblx0ICAgICAgICAgICAgaWYgKG5ld01vZGUgPT09IFwibmV4dEFzeW5jXCIpIHtcblx0ICAgICAgICAgICAgICAgIGFkdmFuY2VVbnRpbE1vZGVDaGFuZ2VzKCk7XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAobmV3TW9kZSA9PT0gXCJpbnRlcnZhbFwiKSB7XG5cdCAgICAgICAgICAgICAgICBjcmVhdGVJbnRlcnZhbFRpY2soY2xvY2ssIG5ld0RlbHRhIHx8IDIwKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBhc3luYyBmdW5jdGlvbiBhZHZhbmNlVW50aWxNb2RlQ2hhbmdlcygpIHtcblx0ICAgICAgICAgICAgYXN5bmMgZnVuY3Rpb24gbmV3TWFjcm90YXNrKCkge1xuXHQgICAgICAgICAgICAgICAgLy8gTWVzc2FnZUNoYW5uZWwgZW5zdXJlcyB0aGF0IHNldFRpbWVvdXQgaXMgbm90IHRocm90dGxlZCB0byA0bXMuXG5cdCAgICAgICAgICAgICAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvc2V0VGltZW91dCNyZWFzb25zX2Zvcl9kZWxheXNfbG9uZ2VyX3RoYW5fc3BlY2lmaWVkXG5cdCAgICAgICAgICAgICAgICAvLyBodHRwczovL3N0YWNrYmxpdHouY29tL2VkaXQvc3RhY2tibGl0ei1zdGFydGVycy1xdGxwY2Ncblx0ICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcblx0ICAgICAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbC5wb3J0MS5jbG9zZSgpO1xuXHQgICAgICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgICAgICAgICAgY2hhbm5lbC5wb3J0Mi5wb3N0TWVzc2FnZSh1bmRlZmluZWQpO1xuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICBjaGFubmVsLnBvcnQxLmNsb3NlKCk7XG5cdCAgICAgICAgICAgICAgICBjaGFubmVsLnBvcnQyLmNsb3NlKCk7XG5cdCAgICAgICAgICAgICAgICAvLyBzZXRUaW1lb3V0IGVuc3VyZXMgbWljcm90YXNrIHF1ZXVlIGlzIGVtcHRpZWRcblx0ICAgICAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxTZXRUaW1lb3V0KHJlc29sdmUpO1xuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBjb25zdCB7IGNvdW50ZXIgfSA9IGNsb2NrLnRpY2tNb2RlO1xuXHQgICAgICAgICAgICB3aGlsZSAoY2xvY2sudGlja01vZGUuY291bnRlciA9PT0gY291bnRlcikge1xuXHQgICAgICAgICAgICAgICAgYXdhaXQgbmV3TWFjcm90YXNrKCk7XG5cdCAgICAgICAgICAgICAgICBpZiAoY2xvY2sudGlja01vZGUuY291bnRlciAhPT0gY291bnRlcikge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGNsb2NrLm5leHQoKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGZ1bmN0aW9uIHBhdXNlQXV0b1RpY2tVbnRpbEZpbmlzaGVkKHByb21pc2UpIHtcblx0ICAgICAgICAgICAgaWYgKGNsb2NrLnRpY2tNb2RlLm1vZGUgIT09IFwibmV4dEFzeW5jXCIpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBwcm9taXNlO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNsb2NrLnNldFRpY2tNb2RlKHsgbW9kZTogXCJtYW51YWxcIiB9KTtcblx0ICAgICAgICAgICAgcmV0dXJuIHByb21pc2UuZmluYWxseSgoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBjbG9jay5zZXRUaWNrTW9kZSh7IG1vZGU6IFwibmV4dEFzeW5jXCIgfSk7XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGNsb2NrLnJlcXVlc3RJZGxlQ2FsbGJhY2sgPSBmdW5jdGlvbiByZXF1ZXN0SWRsZUNhbGxiYWNrKFxuXHQgICAgICAgICAgICBmdW5jLFxuXHQgICAgICAgICAgICB0aW1lb3V0LFxuXHQgICAgICAgICkge1xuXHQgICAgICAgICAgICBsZXQgdGltZVRvTmV4dElkbGVQZXJpb2QgPSAwO1xuXG5cdCAgICAgICAgICAgIGlmIChjbG9jay5jb3VudFRpbWVycygpID4gMCkge1xuXHQgICAgICAgICAgICAgICAgdGltZVRvTmV4dElkbGVQZXJpb2QgPSA1MDsgLy8gY29uc3QgZm9yIG5vd1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYWRkVGltZXIoY2xvY2ssIHtcblx0ICAgICAgICAgICAgICAgIGZ1bmM6IGZ1bmMsXG5cdCAgICAgICAgICAgICAgICBhcmdzOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpLFxuXHQgICAgICAgICAgICAgICAgZGVsYXk6XG5cdCAgICAgICAgICAgICAgICAgICAgdHlwZW9mIHRpbWVvdXQgPT09IFwidW5kZWZpbmVkXCJcblx0ICAgICAgICAgICAgICAgICAgICAgICAgPyB0aW1lVG9OZXh0SWRsZVBlcmlvZFxuXHQgICAgICAgICAgICAgICAgICAgICAgICA6IE1hdGgubWluKHRpbWVvdXQsIHRpbWVUb05leHRJZGxlUGVyaW9kKSxcblx0ICAgICAgICAgICAgICAgIGlkbGVDYWxsYmFjazogdHJ1ZSxcblx0ICAgICAgICAgICAgfSk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIE51bWJlcihyZXN1bHQpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBjbG9jay5jYW5jZWxJZGxlQ2FsbGJhY2sgPSBmdW5jdGlvbiBjYW5jZWxJZGxlQ2FsbGJhY2sodGltZXJJZCkge1xuXHQgICAgICAgICAgICByZXR1cm4gY2xlYXJUaW1lcihjbG9jaywgdGltZXJJZCwgXCJJZGxlQ2FsbGJhY2tcIik7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGNsb2NrLnNldFRpbWVvdXQgPSBmdW5jdGlvbiBzZXRUaW1lb3V0KGZ1bmMsIHRpbWVvdXQpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIGFkZFRpbWVyKGNsb2NrLCB7XG5cdCAgICAgICAgICAgICAgICBmdW5jOiBmdW5jLFxuXHQgICAgICAgICAgICAgICAgYXJnczogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKSxcblx0ICAgICAgICAgICAgICAgIGRlbGF5OiB0aW1lb3V0LFxuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIGlmICh0eXBlb2YgX2dsb2JhbC5Qcm9taXNlICE9PSBcInVuZGVmaW5lZFwiICYmIHV0aWxQcm9taXNpZnkpIHtcblx0ICAgICAgICAgICAgY2xvY2suc2V0VGltZW91dFt1dGlsUHJvbWlzaWZ5LmN1c3RvbV0gPVxuXHQgICAgICAgICAgICAgICAgZnVuY3Rpb24gcHJvbWlzaWZpZWRTZXRUaW1lb3V0KHRpbWVvdXQsIGFyZykge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgX2dsb2JhbC5Qcm9taXNlKGZ1bmN0aW9uIHNldFRpbWVvdXRFeGVjdXRvcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSxcblx0ICAgICAgICAgICAgICAgICAgICApIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgYWRkVGltZXIoY2xvY2ssIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmM6IHJlc29sdmUsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzOiBbYXJnXSxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGF5OiB0aW1lb3V0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2xvY2suY2xlYXJUaW1lb3V0ID0gZnVuY3Rpb24gY2xlYXJUaW1lb3V0KHRpbWVySWQpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIGNsZWFyVGltZXIoY2xvY2ssIHRpbWVySWQsIFwiVGltZW91dFwiKTtcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2submV4dFRpY2sgPSBmdW5jdGlvbiBuZXh0VGljayhmdW5jKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBlbnF1ZXVlSm9iKGNsb2NrLCB7XG5cdCAgICAgICAgICAgICAgICBmdW5jOiBmdW5jLFxuXHQgICAgICAgICAgICAgICAgYXJnczogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcblx0ICAgICAgICAgICAgICAgIGVycm9yOiBpc05lYXJJbmZpbml0ZUxpbWl0ID8gbmV3IEVycm9yKCkgOiBudWxsLFxuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2sucXVldWVNaWNyb3Rhc2sgPSBmdW5jdGlvbiBxdWV1ZU1pY3JvdGFzayhmdW5jKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBjbG9jay5uZXh0VGljayhmdW5jKTsgLy8gZXhwbGljaXRseSBkcm9wIGFkZGl0aW9uYWwgYXJndW1lbnRzXG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGNsb2NrLnNldEludGVydmFsID0gZnVuY3Rpb24gc2V0SW50ZXJ2YWwoZnVuYywgdGltZW91dCkge1xuXHQgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cblx0ICAgICAgICAgICAgdGltZW91dCA9IHBhcnNlSW50KHRpbWVvdXQsIDEwKTtcblx0ICAgICAgICAgICAgcmV0dXJuIGFkZFRpbWVyKGNsb2NrLCB7XG5cdCAgICAgICAgICAgICAgICBmdW5jOiBmdW5jLFxuXHQgICAgICAgICAgICAgICAgYXJnczogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKSxcblx0ICAgICAgICAgICAgICAgIGRlbGF5OiB0aW1lb3V0LFxuXHQgICAgICAgICAgICAgICAgaW50ZXJ2YWw6IHRpbWVvdXQsXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBjbG9jay5jbGVhckludGVydmFsID0gZnVuY3Rpb24gY2xlYXJJbnRlcnZhbCh0aW1lcklkKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBjbGVhclRpbWVyKGNsb2NrLCB0aW1lcklkLCBcIkludGVydmFsXCIpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBpZiAoaXNQcmVzZW50LnNldEltbWVkaWF0ZSkge1xuXHQgICAgICAgICAgICBjbG9jay5zZXRJbW1lZGlhdGUgPSBmdW5jdGlvbiBzZXRJbW1lZGlhdGUoZnVuYykge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGFkZFRpbWVyKGNsb2NrLCB7XG5cdCAgICAgICAgICAgICAgICAgICAgZnVuYzogZnVuYyxcblx0ICAgICAgICAgICAgICAgICAgICBhcmdzOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxuXHQgICAgICAgICAgICAgICAgICAgIGltbWVkaWF0ZTogdHJ1ZSxcblx0ICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICB9O1xuXG5cdCAgICAgICAgICAgIGlmICh0eXBlb2YgX2dsb2JhbC5Qcm9taXNlICE9PSBcInVuZGVmaW5lZFwiICYmIHV0aWxQcm9taXNpZnkpIHtcblx0ICAgICAgICAgICAgICAgIGNsb2NrLnNldEltbWVkaWF0ZVt1dGlsUHJvbWlzaWZ5LmN1c3RvbV0gPVxuXHQgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHByb21pc2lmaWVkU2V0SW1tZWRpYXRlKGFyZykge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IF9nbG9iYWwuUHJvbWlzZShcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldEltbWVkaWF0ZUV4ZWN1dG9yKHJlc29sdmUpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRUaW1lcihjbG9jaywge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jOiByZXNvbHZlLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzOiBbYXJnXSxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1tZWRpYXRlOiB0cnVlLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgICAgICAgICB9O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgY2xvY2suY2xlYXJJbW1lZGlhdGUgPSBmdW5jdGlvbiBjbGVhckltbWVkaWF0ZSh0aW1lcklkKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gY2xlYXJUaW1lcihjbG9jaywgdGltZXJJZCwgXCJJbW1lZGlhdGVcIik7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2xvY2suY291bnRUaW1lcnMgPSBmdW5jdGlvbiBjb3VudFRpbWVycygpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIChcblx0ICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKGNsb2NrLnRpbWVycyB8fCB7fSkubGVuZ3RoICtcblx0ICAgICAgICAgICAgICAgIChjbG9jay5qb2JzIHx8IFtdKS5sZW5ndGhcblx0ICAgICAgICAgICAgKTtcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2sucmVxdWVzdEFuaW1hdGlvbkZyYW1lID0gZnVuY3Rpb24gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZ1bmMpIHtcblx0ICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYWRkVGltZXIoY2xvY2ssIHtcblx0ICAgICAgICAgICAgICAgIGZ1bmM6IGZ1bmMsXG5cdCAgICAgICAgICAgICAgICBkZWxheTogZ2V0VGltZVRvTmV4dEZyYW1lKCksXG5cdCAgICAgICAgICAgICAgICBnZXQgYXJncygpIHtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gW2Zha2VQZXJmb3JtYW5jZU5vdygpXTtcblx0ICAgICAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgICAgICBhbmltYXRpb246IHRydWUsXG5cdCAgICAgICAgICAgIH0pO1xuXG5cdCAgICAgICAgICAgIHJldHVybiBOdW1iZXIocmVzdWx0KTtcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2suY2FuY2VsQW5pbWF0aW9uRnJhbWUgPSBmdW5jdGlvbiBjYW5jZWxBbmltYXRpb25GcmFtZSh0aW1lcklkKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBjbGVhclRpbWVyKGNsb2NrLCB0aW1lcklkLCBcIkFuaW1hdGlvbkZyYW1lXCIpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBjbG9jay5ydW5NaWNyb3Rhc2tzID0gZnVuY3Rpb24gcnVuTWljcm90YXNrcygpIHtcblx0ICAgICAgICAgICAgcnVuSm9icyhjbG9jayk7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfHN0cmluZ30gdGlja1ZhbHVlIG1pbGxpc2Vjb25kcyBvciBhIHN0cmluZyBwYXJzZWFibGUgYnkgcGFyc2VUaW1lXG5cdCAgICAgICAgICogQHBhcmFtIHtib29sZWFufSBpc0FzeW5jXG5cdCAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcmVzb2x2ZVxuXHQgICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHJlamVjdFxuXHQgICAgICAgICAqIEByZXR1cm5zIHtudW1iZXJ8dW5kZWZpbmVkfSB3aWxsIHJldHVybiB0aGUgbmV3IGBub3dgIHZhbHVlIG9yIG5vdGhpbmcgZm9yIGFzeW5jXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgZnVuY3Rpb24gZG9UaWNrKHRpY2tWYWx1ZSwgaXNBc3luYywgcmVzb2x2ZSwgcmVqZWN0KSB7XG5cdCAgICAgICAgICAgIGNvbnN0IG1zRmxvYXQgPVxuXHQgICAgICAgICAgICAgICAgdHlwZW9mIHRpY2tWYWx1ZSA9PT0gXCJudW1iZXJcIlxuXHQgICAgICAgICAgICAgICAgICAgID8gdGlja1ZhbHVlXG5cdCAgICAgICAgICAgICAgICAgICAgOiBwYXJzZVRpbWUodGlja1ZhbHVlKTtcblx0ICAgICAgICAgICAgY29uc3QgbXMgPSBNYXRoLmZsb29yKG1zRmxvYXQpO1xuXHQgICAgICAgICAgICBjb25zdCByZW1haW5kZXIgPSBuYW5vUmVtYWluZGVyKG1zRmxvYXQpO1xuXHQgICAgICAgICAgICBsZXQgbmFub3NUb3RhbCA9IG5hbm9zICsgcmVtYWluZGVyO1xuXHQgICAgICAgICAgICBsZXQgdGlja1RvID0gY2xvY2subm93ICsgbXM7XG5cblx0ICAgICAgICAgICAgaWYgKG1zRmxvYXQgPCAwKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTmVnYXRpdmUgdGlja3MgYXJlIG5vdCBzdXBwb3J0ZWRcIik7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBhZGp1c3QgZm9yIHBvc2l0aXZlIG92ZXJmbG93XG5cdCAgICAgICAgICAgIGlmIChuYW5vc1RvdGFsID49IDFlNikge1xuXHQgICAgICAgICAgICAgICAgdGlja1RvICs9IDE7XG5cdCAgICAgICAgICAgICAgICBuYW5vc1RvdGFsIC09IDFlNjtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIG5hbm9zID0gbmFub3NUb3RhbDtcblx0ICAgICAgICAgICAgbGV0IHRpY2tGcm9tID0gY2xvY2subm93O1xuXHQgICAgICAgICAgICBsZXQgcHJldmlvdXMgPSBjbG9jay5ub3c7XG5cdCAgICAgICAgICAgIC8vIEVTTGludCBmYWlscyB0byBkZXRlY3QgdGhpcyBjb3JyZWN0bHlcblx0ICAgICAgICAgICAgLyogZXNsaW50LWRpc2FibGUgcHJlZmVyLWNvbnN0ICovXG5cdCAgICAgICAgICAgIGxldCB0aW1lcixcblx0ICAgICAgICAgICAgICAgIGZpcnN0RXhjZXB0aW9uLFxuXHQgICAgICAgICAgICAgICAgb2xkTm93LFxuXHQgICAgICAgICAgICAgICAgbmV4dFByb21pc2VUaWNrLFxuXHQgICAgICAgICAgICAgICAgY29tcGVuc2F0aW9uQ2hlY2ssXG5cdCAgICAgICAgICAgICAgICBwb3N0VGltZXJDYWxsO1xuXHQgICAgICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIHByZWZlci1jb25zdCAqL1xuXG5cdCAgICAgICAgICAgIGNsb2NrLmR1cmluZ1RpY2sgPSB0cnVlO1xuXG5cdCAgICAgICAgICAgIC8vIHBlcmZvcm0gbWljcm90YXNrc1xuXHQgICAgICAgICAgICBvbGROb3cgPSBjbG9jay5ub3c7XG5cdCAgICAgICAgICAgIHJ1bkpvYnMoY2xvY2spO1xuXHQgICAgICAgICAgICBpZiAob2xkTm93ICE9PSBjbG9jay5ub3cpIHtcblx0ICAgICAgICAgICAgICAgIC8vIGNvbXBlbnNhdGUgZm9yIGFueSBzZXRTeXN0ZW1UaW1lKCkgY2FsbCBkdXJpbmcgbWljcm90YXNrIGNhbGxiYWNrXG5cdCAgICAgICAgICAgICAgICB0aWNrRnJvbSArPSBjbG9jay5ub3cgLSBvbGROb3c7XG5cdCAgICAgICAgICAgICAgICB0aWNrVG8gKz0gY2xvY2subm93IC0gb2xkTm93O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy9lc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xuXHQgICAgICAgICAgICBmdW5jdGlvbiBkb1RpY2tJbm5lcigpIHtcblx0ICAgICAgICAgICAgICAgIC8vIHBlcmZvcm0gZWFjaCB0aW1lciBpbiB0aGUgcmVxdWVzdGVkIHJhbmdlXG5cdCAgICAgICAgICAgICAgICB0aW1lciA9IGZpcnN0VGltZXJJblJhbmdlKGNsb2NrLCB0aWNrRnJvbSwgdGlja1RvKTtcblx0ICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bm1vZGlmaWVkLWxvb3AtY29uZGl0aW9uXG5cdCAgICAgICAgICAgICAgICB3aGlsZSAodGltZXIgJiYgdGlja0Zyb20gPD0gdGlja1RvKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKGNsb2NrLnRpbWVyc1t0aW1lci5pZF0pIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgdGlja0Zyb20gPSB0aW1lci5jYWxsQXQ7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLm5vdyA9IHRpbWVyLmNhbGxBdDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgb2xkTm93ID0gY2xvY2subm93O1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVuSm9icyhjbG9jayk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsVGltZXIoY2xvY2ssIHRpbWVyKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RFeGNlcHRpb24gPSBmaXJzdEV4Y2VwdGlvbiB8fCBlO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQXN5bmMpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbmlzaCB1cCBhZnRlciBuYXRpdmUgc2V0SW1tZWRpYXRlIGNhbGxiYWNrIHRvIGFsbG93XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbGwgbmF0aXZlIGVzNiBwcm9taXNlcyB0byBwcm9jZXNzIHRoZWlyIGNhbGxiYWNrcyBhZnRlclxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZWFjaCB0aW1lciBmaXJlcy5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsU2V0VGltZW91dChuZXh0UHJvbWlzZVRpY2spO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgY29tcGVuc2F0aW9uQ2hlY2soKTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICBwb3N0VGltZXJDYWxsKCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIC8vIHBlcmZvcm0gcHJvY2Vzcy5uZXh0VGljaygpcyBhZ2FpblxuXHQgICAgICAgICAgICAgICAgb2xkTm93ID0gY2xvY2subm93O1xuXHQgICAgICAgICAgICAgICAgcnVuSm9icyhjbG9jayk7XG5cdCAgICAgICAgICAgICAgICBpZiAob2xkTm93ICE9PSBjbG9jay5ub3cpIHtcblx0ICAgICAgICAgICAgICAgICAgICAvLyBjb21wZW5zYXRlIGZvciBhbnkgc2V0U3lzdGVtVGltZSgpIGNhbGwgZHVyaW5nIHByb2Nlc3MubmV4dFRpY2soKSBjYWxsYmFja1xuXHQgICAgICAgICAgICAgICAgICAgIHRpY2tGcm9tICs9IGNsb2NrLm5vdyAtIG9sZE5vdztcblx0ICAgICAgICAgICAgICAgICAgICB0aWNrVG8gKz0gY2xvY2subm93IC0gb2xkTm93O1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgY2xvY2suZHVyaW5nVGljayA9IGZhbHNlO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBjb3JuZXIgY2FzZTogZHVyaW5nIHJ1bkpvYnMgbmV3IHRpbWVycyB3ZXJlIHNjaGVkdWxlZCB3aGljaCBjb3VsZCBiZSBpbiB0aGUgcmFuZ2UgW2Nsb2NrLm5vdywgdGlja1RvXVxuXHQgICAgICAgICAgICAgICAgdGltZXIgPSBmaXJzdFRpbWVySW5SYW5nZShjbG9jaywgdGlja0Zyb20sIHRpY2tUbyk7XG5cdCAgICAgICAgICAgICAgICBpZiAodGltZXIpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay50aWNrKHRpY2tUbyAtIGNsb2NrLm5vdyk7IC8vIGRvIGl0IGFsbCBhZ2FpbiAtIGZvciB0aGUgcmVtYWluZGVyIG9mIHRoZSByZXF1ZXN0ZWQgcmFuZ2Vcblx0ICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0RXhjZXB0aW9uID0gZmlyc3RFeGNlcHRpb24gfHwgZTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIC8vIG5vIHRpbWVycyByZW1haW5pbmcgaW4gdGhlIHJlcXVlc3RlZCByYW5nZTogbW92ZSB0aGUgY2xvY2sgYWxsIHRoZSB3YXkgdG8gdGhlIGVuZFxuXHQgICAgICAgICAgICAgICAgICAgIGNsb2NrLm5vdyA9IHRpY2tUbztcblxuXHQgICAgICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSBuYW5vc1xuXHQgICAgICAgICAgICAgICAgICAgIG5hbm9zID0gbmFub3NUb3RhbDtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGlmIChmaXJzdEV4Y2VwdGlvbikge1xuXHQgICAgICAgICAgICAgICAgICAgIHRocm93IGZpcnN0RXhjZXB0aW9uO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICBpZiAoaXNBc3luYykge1xuXHQgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoY2xvY2subm93KTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNsb2NrLm5vdztcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIG5leHRQcm9taXNlVGljayA9XG5cdCAgICAgICAgICAgICAgICBpc0FzeW5jICYmXG5cdCAgICAgICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgY29tcGVuc2F0aW9uQ2hlY2soKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcG9zdFRpbWVyQ2FsbCgpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBkb1RpY2tJbm5lcigpO1xuXHQgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH07XG5cblx0ICAgICAgICAgICAgY29tcGVuc2F0aW9uQ2hlY2sgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBjb21wZW5zYXRlIGZvciBhbnkgc2V0U3lzdGVtVGltZSgpIGNhbGwgZHVyaW5nIHRpbWVyIGNhbGxiYWNrXG5cdCAgICAgICAgICAgICAgICBpZiAob2xkTm93ICE9PSBjbG9jay5ub3cpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aWNrRnJvbSArPSBjbG9jay5ub3cgLSBvbGROb3c7XG5cdCAgICAgICAgICAgICAgICAgICAgdGlja1RvICs9IGNsb2NrLm5vdyAtIG9sZE5vdztcblx0ICAgICAgICAgICAgICAgICAgICBwcmV2aW91cyArPSBjbG9jay5ub3cgLSBvbGROb3c7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH07XG5cblx0ICAgICAgICAgICAgcG9zdFRpbWVyQ2FsbCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgIHRpbWVyID0gZmlyc3RUaW1lckluUmFuZ2UoY2xvY2ssIHByZXZpb3VzLCB0aWNrVG8pO1xuXHQgICAgICAgICAgICAgICAgcHJldmlvdXMgPSB0aWNrRnJvbTtcblx0ICAgICAgICAgICAgfTtcblxuXHQgICAgICAgICAgICByZXR1cm4gZG9UaWNrSW5uZXIoKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHRpY2tWYWx1ZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIG9yIGEgaHVtYW4tcmVhZGFibGUgdmFsdWUgbGlrZSBcIjAxOjExOjE1XCJcblx0ICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSB3aWxsIHJldHVybiB0aGUgbmV3IGBub3dgIHZhbHVlXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2xvY2sudGljayA9IGZ1bmN0aW9uIHRpY2sodGlja1ZhbHVlKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBkb1RpY2sodGlja1ZhbHVlLCBmYWxzZSk7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGlmICh0eXBlb2YgX2dsb2JhbC5Qcm9taXNlICE9PSBcInVuZGVmaW5lZFwiKSB7XG5cdCAgICAgICAgICAgIC8qKlxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHRpY2tWYWx1ZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIG9yIGEgaHVtYW4tcmVhZGFibGUgdmFsdWUgbGlrZSBcIjAxOjExOjE1XCJcblx0ICAgICAgICAgICAgICogQHJldHVybnMge1Byb21pc2V9XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBjbG9jay50aWNrQXN5bmMgPSBmdW5jdGlvbiB0aWNrQXN5bmModGlja1ZhbHVlKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gcGF1c2VBdXRvVGlja1VudGlsRmluaXNoZWQoXG5cdCAgICAgICAgICAgICAgICAgICAgbmV3IF9nbG9iYWwuUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsU2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvVGljayh0aWNrVmFsdWUsIHRydWUsIHJlc29sdmUsIHJlamVjdCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgICAgICB9KSxcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2xvY2submV4dCA9IGZ1bmN0aW9uIG5leHQoKSB7XG5cdCAgICAgICAgICAgIHJ1bkpvYnMoY2xvY2spO1xuXHQgICAgICAgICAgICBjb25zdCB0aW1lciA9IGZpcnN0VGltZXIoY2xvY2spO1xuXHQgICAgICAgICAgICBpZiAoIXRpbWVyKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gY2xvY2subm93O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgY2xvY2suZHVyaW5nVGljayA9IHRydWU7XG5cdCAgICAgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgICAgICBjbG9jay5ub3cgPSB0aW1lci5jYWxsQXQ7XG5cdCAgICAgICAgICAgICAgICBjYWxsVGltZXIoY2xvY2ssIHRpbWVyKTtcblx0ICAgICAgICAgICAgICAgIHJ1bkpvYnMoY2xvY2spO1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGNsb2NrLm5vdztcblx0ICAgICAgICAgICAgfSBmaW5hbGx5IHtcblx0ICAgICAgICAgICAgICAgIGNsb2NrLmR1cmluZ1RpY2sgPSBmYWxzZTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBpZiAodHlwZW9mIF9nbG9iYWwuUHJvbWlzZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuXHQgICAgICAgICAgICBjbG9jay5uZXh0QXN5bmMgPSBmdW5jdGlvbiBuZXh0QXN5bmMoKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gcGF1c2VBdXRvVGlja1VudGlsRmluaXNoZWQoXG5cdCAgICAgICAgICAgICAgICAgICAgbmV3IF9nbG9iYWwuUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsU2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRpbWVyID0gZmlyc3RUaW1lcihjbG9jayk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aW1lcikge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGNsb2NrLm5vdyk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZXJyO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmR1cmluZ1RpY2sgPSB0cnVlO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLm5vdyA9IHRpbWVyLmNhbGxBdDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsVGltZXIoY2xvY2ssIHRpbWVyKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVyciA9IGU7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmR1cmluZ1RpY2sgPSBmYWxzZTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsU2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShjbG9jay5ub3cpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgICAgICB9KSxcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2xvY2sucnVuQWxsID0gZnVuY3Rpb24gcnVuQWxsKCkge1xuXHQgICAgICAgICAgICBsZXQgbnVtVGltZXJzLCBpO1xuXHQgICAgICAgICAgICBydW5Kb2JzKGNsb2NrKTtcblx0ICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNsb2NrLmxvb3BMaW1pdDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoIWNsb2NrLnRpbWVycykge1xuXHQgICAgICAgICAgICAgICAgICAgIHJlc2V0SXNOZWFySW5maW5pdGVMaW1pdCgpO1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBjbG9jay5ub3c7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIG51bVRpbWVycyA9IE9iamVjdC5rZXlzKGNsb2NrLnRpbWVycykubGVuZ3RoO1xuXHQgICAgICAgICAgICAgICAgaWYgKG51bVRpbWVycyA9PT0gMCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJlc2V0SXNOZWFySW5maW5pdGVMaW1pdCgpO1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBjbG9jay5ub3c7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIGNsb2NrLm5leHQoKTtcblx0ICAgICAgICAgICAgICAgIGNoZWNrSXNOZWFySW5maW5pdGVMaW1pdChjbG9jaywgaSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBjb25zdCBleGNlc3NKb2IgPSBmaXJzdFRpbWVyKGNsb2NrKTtcblx0ICAgICAgICAgICAgdGhyb3cgZ2V0SW5maW5pdGVMb29wRXJyb3IoY2xvY2ssIGV4Y2Vzc0pvYik7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGNsb2NrLnJ1blRvRnJhbWUgPSBmdW5jdGlvbiBydW5Ub0ZyYW1lKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gY2xvY2sudGljayhnZXRUaW1lVG9OZXh0RnJhbWUoKSk7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGlmICh0eXBlb2YgX2dsb2JhbC5Qcm9taXNlICE9PSBcInVuZGVmaW5lZFwiKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLnJ1bkFsbEFzeW5jID0gZnVuY3Rpb24gcnVuQWxsQXN5bmMoKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gcGF1c2VBdXRvVGlja1VudGlsRmluaXNoZWQoXG5cdCAgICAgICAgICAgICAgICAgICAgbmV3IF9nbG9iYWwuUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpID0gMDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb1J1bigpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsU2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVuSm9icyhjbG9jayk7XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG51bVRpbWVycztcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCBjbG9jay5sb29wTGltaXQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY2xvY2sudGltZXJzKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXRJc05lYXJJbmZpbml0ZUxpbWl0KCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShjbG9jay5ub3cpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtVGltZXJzID0gT2JqZWN0LmtleXMoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvY2sudGltZXJzLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKS5sZW5ndGg7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobnVtVGltZXJzID09PSAwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXRJc05lYXJJbmZpbml0ZUxpbWl0KCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShjbG9jay5ub3cpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvY2submV4dCgpO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpKys7XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvUnVuKCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja0lzTmVhckluZmluaXRlTGltaXQoY2xvY2ssIGkpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXhjZXNzSm9iID0gZmlyc3RUaW1lcihjbG9jayk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldEluZmluaXRlTG9vcEVycm9yKGNsb2NrLCBleGNlc3NKb2IpLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGRvUnVuKCk7XG5cdCAgICAgICAgICAgICAgICAgICAgfSksXG5cdCAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGNsb2NrLnJ1blRvTGFzdCA9IGZ1bmN0aW9uIHJ1blRvTGFzdCgpIHtcblx0ICAgICAgICAgICAgY29uc3QgdGltZXIgPSBsYXN0VGltZXIoY2xvY2spO1xuXHQgICAgICAgICAgICBpZiAoIXRpbWVyKSB7XG5cdCAgICAgICAgICAgICAgICBydW5Kb2JzKGNsb2NrKTtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBjbG9jay5ub3c7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gY2xvY2sudGljayh0aW1lci5jYWxsQXQgLSBjbG9jay5ub3cpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBpZiAodHlwZW9mIF9nbG9iYWwuUHJvbWlzZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuXHQgICAgICAgICAgICBjbG9jay5ydW5Ub0xhc3RBc3luYyA9IGZ1bmN0aW9uIHJ1blRvTGFzdEFzeW5jKCkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHBhdXNlQXV0b1RpY2tVbnRpbEZpbmlzaGVkKFxuXHQgICAgICAgICAgICAgICAgICAgIG5ldyBfZ2xvYmFsLlByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbFNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0aW1lciA9IGxhc3RUaW1lcihjbG9jayk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aW1lcikge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydW5Kb2JzKGNsb2NrKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShjbG9jay5ub3cpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLnRpY2tBc3luYyh0aW1lci5jYWxsQXQgLSBjbG9jay5ub3cpLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgICAgICB9KSxcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2xvY2sucmVzZXQgPSBmdW5jdGlvbiByZXNldCgpIHtcblx0ICAgICAgICAgICAgbmFub3MgPSAwO1xuXHQgICAgICAgICAgICBjbG9jay50aW1lcnMgPSB7fTtcblx0ICAgICAgICAgICAgY2xvY2suam9icyA9IFtdO1xuXHQgICAgICAgICAgICBjbG9jay5ub3cgPSBzdGFydDtcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2suc2V0U3lzdGVtVGltZSA9IGZ1bmN0aW9uIHNldFN5c3RlbVRpbWUoc3lzdGVtVGltZSkge1xuXHQgICAgICAgICAgICAvLyBkZXRlcm1pbmUgdGltZSBkaWZmZXJlbmNlXG5cdCAgICAgICAgICAgIGNvbnN0IG5ld05vdyA9IGdldEVwb2NoKHN5c3RlbVRpbWUpO1xuXHQgICAgICAgICAgICBjb25zdCBkaWZmZXJlbmNlID0gbmV3Tm93IC0gY2xvY2subm93O1xuXHQgICAgICAgICAgICBsZXQgaWQsIHRpbWVyO1xuXG5cdCAgICAgICAgICAgIGFkanVzdGVkU3lzdGVtVGltZVswXSA9IGFkanVzdGVkU3lzdGVtVGltZVswXSArIGRpZmZlcmVuY2U7XG5cdCAgICAgICAgICAgIGFkanVzdGVkU3lzdGVtVGltZVsxXSA9IGFkanVzdGVkU3lzdGVtVGltZVsxXSArIG5hbm9zO1xuXHQgICAgICAgICAgICAvLyB1cGRhdGUgJ3N5c3RlbSBjbG9jaydcblx0ICAgICAgICAgICAgY2xvY2subm93ID0gbmV3Tm93O1xuXHQgICAgICAgICAgICBuYW5vcyA9IDA7XG5cblx0ICAgICAgICAgICAgLy8gdXBkYXRlIHRpbWVycyBhbmQgaW50ZXJ2YWxzIHRvIGtlZXAgdGhlbSBzdGFibGVcblx0ICAgICAgICAgICAgZm9yIChpZCBpbiBjbG9jay50aW1lcnMpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChjbG9jay50aW1lcnMuaGFzT3duUHJvcGVydHkoaWQpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGltZXIgPSBjbG9jay50aW1lcnNbaWRdO1xuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyLmNyZWF0ZWRBdCArPSBkaWZmZXJlbmNlO1xuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyLmNhbGxBdCArPSBkaWZmZXJlbmNlO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gdGlja1ZhbHVlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgb3IgYSBodW1hbi1yZWFkYWJsZSB2YWx1ZSBsaWtlIFwiMDE6MTE6MTVcIlxuXHQgICAgICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IHdpbGwgcmV0dXJuIHRoZSBuZXcgYG5vd2AgdmFsdWVcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjbG9jay5qdW1wID0gZnVuY3Rpb24ganVtcCh0aWNrVmFsdWUpIHtcblx0ICAgICAgICAgICAgY29uc3QgbXNGbG9hdCA9XG5cdCAgICAgICAgICAgICAgICB0eXBlb2YgdGlja1ZhbHVlID09PSBcIm51bWJlclwiXG5cdCAgICAgICAgICAgICAgICAgICAgPyB0aWNrVmFsdWVcblx0ICAgICAgICAgICAgICAgICAgICA6IHBhcnNlVGltZSh0aWNrVmFsdWUpO1xuXHQgICAgICAgICAgICBjb25zdCBtcyA9IE1hdGguZmxvb3IobXNGbG9hdCk7XG5cblx0ICAgICAgICAgICAgZm9yIChjb25zdCB0aW1lciBvZiBPYmplY3QudmFsdWVzKGNsb2NrLnRpbWVycykpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChjbG9jay5ub3cgKyBtcyA+IHRpbWVyLmNhbGxBdCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyLmNhbGxBdCA9IGNsb2NrLm5vdyArIG1zO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNsb2NrLnRpY2sobXMpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBpZiAoaXNQcmVzZW50LnBlcmZvcm1hbmNlKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLnBlcmZvcm1hbmNlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblx0ICAgICAgICAgICAgY2xvY2sucGVyZm9ybWFuY2Uubm93ID0gZmFrZVBlcmZvcm1hbmNlTm93O1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChpc1ByZXNlbnQuaHJ0aW1lKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLmhydGltZSA9IGhydGltZTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICByZXR1cm4gY2xvY2s7XG5cdCAgICB9XG5cblx0ICAgIGZ1bmN0aW9uIGNyZWF0ZUludGVydmFsVGljayhjbG9jaywgZGVsdGEpIHtcblx0ICAgICAgICBjb25zdCBpbnRlcnZhbFRpY2sgPSBkb0ludGVydmFsVGljay5iaW5kKG51bGwsIGNsb2NrLCBkZWx0YSk7XG5cdCAgICAgICAgY29uc3QgaW50ZXJ2YWxJZCA9IG9yaWdpbmFsU2V0SW50ZXJ2YWwoaW50ZXJ2YWxUaWNrLCBkZWx0YSk7XG5cdCAgICAgICAgY2xvY2suYXR0YWNoZWRJbnRlcnZhbCA9IGludGVydmFsSWQ7XG5cdCAgICB9XG5cblx0ICAgIC8qIGVzbGludC1kaXNhYmxlIGNvbXBsZXhpdHkgKi9cblxuXHQgICAgLyoqXG5cdCAgICAgKiBAcGFyYW0ge0NvbmZpZz19IFtjb25maWddIE9wdGlvbmFsIGNvbmZpZ1xuXHQgICAgICogQHJldHVybnMge0Nsb2NrfVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBpbnN0YWxsKGNvbmZpZykge1xuXHQgICAgICAgIGlmIChcblx0ICAgICAgICAgICAgYXJndW1lbnRzLmxlbmd0aCA+IDEgfHxcblx0ICAgICAgICAgICAgY29uZmlnIGluc3RhbmNlb2YgRGF0ZSB8fFxuXHQgICAgICAgICAgICBBcnJheS5pc0FycmF5KGNvbmZpZykgfHxcblx0ICAgICAgICAgICAgdHlwZW9mIGNvbmZpZyA9PT0gXCJudW1iZXJcIlxuXHQgICAgICAgICkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuXHQgICAgICAgICAgICAgICAgYEZha2VUaW1lcnMuaW5zdGFsbCBjYWxsZWQgd2l0aCAke1N0cmluZyhcblx0ICAgICAgICAgICAgICAgICAgICBjb25maWcsXG5cdCAgICAgICAgICAgICAgICApfSBpbnN0YWxsIHJlcXVpcmVzIGFuIG9iamVjdCBwYXJhbWV0ZXJgLFxuXHQgICAgICAgICAgICApO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChfZ2xvYmFsLkRhdGUuaXNGYWtlID09PSB0cnVlKSB7XG5cdCAgICAgICAgICAgIC8vIFRpbWVycyBhcmUgYWxyZWFkeSBmYWtlZDsgdGhpcyBpcyBhIHByb2JsZW0uXG5cdCAgICAgICAgICAgIC8vIE1ha2UgdGhlIHVzZXIgcmVzZXQgdGltZXJzIGJlZm9yZSBjb250aW51aW5nLlxuXHQgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuXHQgICAgICAgICAgICAgICAgXCJDYW4ndCBpbnN0YWxsIGZha2UgdGltZXJzIHR3aWNlIG9uIHRoZSBzYW1lIGdsb2JhbCBvYmplY3QuXCIsXG5cdCAgICAgICAgICAgICk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG5cdCAgICAgICAgY29uZmlnID0gdHlwZW9mIGNvbmZpZyAhPT0gXCJ1bmRlZmluZWRcIiA/IGNvbmZpZyA6IHt9O1xuXHQgICAgICAgIGNvbmZpZy5zaG91bGRBZHZhbmNlVGltZSA9IGNvbmZpZy5zaG91bGRBZHZhbmNlVGltZSB8fCBmYWxzZTtcblx0ICAgICAgICBjb25maWcuYWR2YW5jZVRpbWVEZWx0YSA9IGNvbmZpZy5hZHZhbmNlVGltZURlbHRhIHx8IDIwO1xuXHQgICAgICAgIGNvbmZpZy5zaG91bGRDbGVhck5hdGl2ZVRpbWVycyA9XG5cdCAgICAgICAgICAgIGNvbmZpZy5zaG91bGRDbGVhck5hdGl2ZVRpbWVycyB8fCBmYWxzZTtcblxuXHQgICAgICAgIGlmIChjb25maWcudGFyZ2V0KSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG5cdCAgICAgICAgICAgICAgICBcImNvbmZpZy50YXJnZXQgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZC4gVXNlIGB3aXRoR2xvYmFsKHRhcmdldClgIGluc3RlYWQuXCIsXG5cdCAgICAgICAgICAgICk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHRpbWVyL29iamVjdCB0aGUgbmFtZSBvZiB0aGUgdGhpbmcgdGhhdCBpcyBub3QgcHJlc2VudFxuXHQgICAgICAgICAqIEBwYXJhbSB0aW1lclxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGZ1bmN0aW9uIGhhbmRsZU1pc3NpbmdUaW1lcih0aW1lcikge1xuXHQgICAgICAgICAgICBpZiAoY29uZmlnLmlnbm9yZU1pc3NpbmdUaW1lcnMpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihcblx0ICAgICAgICAgICAgICAgIGBub24tZXhpc3RlbnQgdGltZXJzIGFuZC9vciBvYmplY3RzIGNhbm5vdCBiZSBmYWtlZDogJyR7dGltZXJ9J2AsXG5cdCAgICAgICAgICAgICk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgbGV0IGksIGw7XG5cdCAgICAgICAgY29uc3QgY2xvY2sgPSBjcmVhdGVDbG9jayhjb25maWcubm93LCBjb25maWcubG9vcExpbWl0KTtcblx0ICAgICAgICBjbG9jay5zaG91bGRDbGVhck5hdGl2ZVRpbWVycyA9IGNvbmZpZy5zaG91bGRDbGVhck5hdGl2ZVRpbWVycztcblxuXHQgICAgICAgIGNsb2NrLnVuaW5zdGFsbCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHVuaW5zdGFsbChjbG9jayk7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAgPSBuZXcgTWFwKCk7XG5cblx0ICAgICAgICBjbG9jay5tZXRob2RzID0gY29uZmlnLnRvRmFrZSB8fCBbXTtcblxuXHQgICAgICAgIGlmIChjbG9jay5tZXRob2RzLmxlbmd0aCA9PT0gMCkge1xuXHQgICAgICAgICAgICBjbG9jay5tZXRob2RzID0gT2JqZWN0LmtleXModGltZXJzKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAoY29uZmlnLnNob3VsZEFkdmFuY2VUaW1lID09PSB0cnVlKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLnNldFRpY2tNb2RlKHtcblx0ICAgICAgICAgICAgICAgIG1vZGU6IFwiaW50ZXJ2YWxcIixcblx0ICAgICAgICAgICAgICAgIGRlbHRhOiBjb25maWcuYWR2YW5jZVRpbWVEZWx0YSxcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgaWYgKGNsb2NrLm1ldGhvZHMuaW5jbHVkZXMoXCJwZXJmb3JtYW5jZVwiKSkge1xuXHQgICAgICAgICAgICBjb25zdCBwcm90byA9ICgoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBpZiAoaGFzUGVyZm9ybWFuY2VDb25zdHJ1Y3RvclByb3RvdHlwZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBfZ2xvYmFsLnBlcmZvcm1hbmNlLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGlmIChoYXNQZXJmb3JtYW5jZVByb3RvdHlwZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBfZ2xvYmFsLlBlcmZvcm1hbmNlLnByb3RvdHlwZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfSkoKTtcblx0ICAgICAgICAgICAgaWYgKHByb3RvKSB7XG5cdCAgICAgICAgICAgICAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhwcm90bykuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGlmIChuYW1lICE9PSBcIm5vd1wiKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLnBlcmZvcm1hbmNlW25hbWVdID1cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUuaW5kZXhPZihcImdldEVudHJpZXNcIikgPT09IDBcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IE5PT1BfQVJSQVlcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IE5PT1A7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICAvLyBlbnN1cmUgYG1hcmtgIHJldHVybnMgYSB2YWx1ZSB0aGF0IGlzIHZhbGlkXG5cdCAgICAgICAgICAgICAgICBjbG9jay5wZXJmb3JtYW5jZS5tYXJrID0gKG5hbWUpID0+XG5cdCAgICAgICAgICAgICAgICAgICAgbmV3IEZha2VQZXJmb3JtYW5jZUVudHJ5KG5hbWUsIFwibWFya1wiLCAwLCAwKTtcblx0ICAgICAgICAgICAgICAgIGNsb2NrLnBlcmZvcm1hbmNlLm1lYXN1cmUgPSAobmFtZSkgPT5cblx0ICAgICAgICAgICAgICAgICAgICBuZXcgRmFrZVBlcmZvcm1hbmNlRW50cnkobmFtZSwgXCJtZWFzdXJlXCIsIDAsIDEwMCk7XG5cdCAgICAgICAgICAgICAgICAvLyBgdGltZU9yaWdpbmAgc2hvdWxkIHJldHVybiB0aGUgdGltZSBvZiB3aGVuIHRoZSBXaW5kb3cgc2Vzc2lvbiBzdGFydGVkXG5cdCAgICAgICAgICAgICAgICAvLyAob3IgdGhlIFdvcmtlciB3YXMgaW5zdGFsbGVkKVxuXHQgICAgICAgICAgICAgICAgY2xvY2sucGVyZm9ybWFuY2UudGltZU9yaWdpbiA9IGdldEVwb2NoKGNvbmZpZy5ub3cpO1xuXHQgICAgICAgICAgICB9IGVsc2UgaWYgKChjb25maWcudG9GYWtlIHx8IFtdKS5pbmNsdWRlcyhcInBlcmZvcm1hbmNlXCIpKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlTWlzc2luZ1RpbWVyKFwicGVyZm9ybWFuY2VcIik7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKF9nbG9iYWwgPT09IGdsb2JhbE9iamVjdCAmJiB0aW1lcnNNb2R1bGUpIHtcblx0ICAgICAgICAgICAgY2xvY2sudGltZXJzTW9kdWxlTWV0aG9kcyA9IFtdO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAoX2dsb2JhbCA9PT0gZ2xvYmFsT2JqZWN0ICYmIHRpbWVyc1Byb21pc2VzTW9kdWxlKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLnRpbWVyc1Byb21pc2VzTW9kdWxlTWV0aG9kcyA9IFtdO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBmb3IgKGkgPSAwLCBsID0gY2xvY2subWV0aG9kcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcblx0ICAgICAgICAgICAgY29uc3QgbmFtZU9mTWV0aG9kVG9SZXBsYWNlID0gY2xvY2subWV0aG9kc1tpXTtcblxuXHQgICAgICAgICAgICBpZiAoIWlzUHJlc2VudFtuYW1lT2ZNZXRob2RUb1JlcGxhY2VdKSB7XG5cdCAgICAgICAgICAgICAgICBoYW5kbGVNaXNzaW5nVGltZXIobmFtZU9mTWV0aG9kVG9SZXBsYWNlKTtcblx0ICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuXHQgICAgICAgICAgICAgICAgY29udGludWU7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBpZiAobmFtZU9mTWV0aG9kVG9SZXBsYWNlID09PSBcImhydGltZVwiKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoXG5cdCAgICAgICAgICAgICAgICAgICAgX2dsb2JhbC5wcm9jZXNzICYmXG5cdCAgICAgICAgICAgICAgICAgICAgdHlwZW9mIF9nbG9iYWwucHJvY2Vzcy5ocnRpbWUgPT09IFwiZnVuY3Rpb25cIlxuXHQgICAgICAgICAgICAgICAgKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaGlqYWNrTWV0aG9kKF9nbG9iYWwucHJvY2VzcywgbmFtZU9mTWV0aG9kVG9SZXBsYWNlLCBjbG9jayk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZU9mTWV0aG9kVG9SZXBsYWNlID09PSBcIm5leHRUaWNrXCIpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChcblx0ICAgICAgICAgICAgICAgICAgICBfZ2xvYmFsLnByb2Nlc3MgJiZcblx0ICAgICAgICAgICAgICAgICAgICB0eXBlb2YgX2dsb2JhbC5wcm9jZXNzLm5leHRUaWNrID09PSBcImZ1bmN0aW9uXCJcblx0ICAgICAgICAgICAgICAgICkge1xuXHQgICAgICAgICAgICAgICAgICAgIGhpamFja01ldGhvZChfZ2xvYmFsLnByb2Nlc3MsIG5hbWVPZk1ldGhvZFRvUmVwbGFjZSwgY2xvY2spO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgaGlqYWNrTWV0aG9kKF9nbG9iYWwsIG5hbWVPZk1ldGhvZFRvUmVwbGFjZSwgY2xvY2spO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmIChcblx0ICAgICAgICAgICAgICAgIGNsb2NrLnRpbWVyc01vZHVsZU1ldGhvZHMgIT09IHVuZGVmaW5lZCAmJlxuXHQgICAgICAgICAgICAgICAgdGltZXJzTW9kdWxlW25hbWVPZk1ldGhvZFRvUmVwbGFjZV1cblx0ICAgICAgICAgICAgKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBvcmlnaW5hbCA9IHRpbWVyc01vZHVsZVtuYW1lT2ZNZXRob2RUb1JlcGxhY2VdO1xuXHQgICAgICAgICAgICAgICAgY2xvY2sudGltZXJzTW9kdWxlTWV0aG9kcy5wdXNoKHtcblx0ICAgICAgICAgICAgICAgICAgICBtZXRob2ROYW1lOiBuYW1lT2ZNZXRob2RUb1JlcGxhY2UsXG5cdCAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWw6IG9yaWdpbmFsLFxuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICB0aW1lcnNNb2R1bGVbbmFtZU9mTWV0aG9kVG9SZXBsYWNlXSA9XG5cdCAgICAgICAgICAgICAgICAgICAgX2dsb2JhbFtuYW1lT2ZNZXRob2RUb1JlcGxhY2VdO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmIChjbG9jay50aW1lcnNQcm9taXNlc01vZHVsZU1ldGhvZHMgIT09IHVuZGVmaW5lZCkge1xuXHQgICAgICAgICAgICAgICAgaWYgKG5hbWVPZk1ldGhvZFRvUmVwbGFjZSA9PT0gXCJzZXRUaW1lb3V0XCIpIHtcblx0ICAgICAgICAgICAgICAgICAgICBjbG9jay50aW1lcnNQcm9taXNlc01vZHVsZU1ldGhvZHMucHVzaCh7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZE5hbWU6IFwic2V0VGltZW91dFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbDogdGltZXJzUHJvbWlzZXNNb2R1bGUuc2V0VGltZW91dCxcblx0ICAgICAgICAgICAgICAgICAgICB9KTtcblxuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyc1Byb21pc2VzTW9kdWxlLnNldFRpbWVvdXQgPSAoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGRlbGF5LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9LFxuXHQgICAgICAgICAgICAgICAgICAgICkgPT5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWJvcnQgPSAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydCxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuZGVsZXRlKGFib3J0KTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgc2FmZSwgdGhlcmUgaXMgbm8gY29kZSBwYXRoIHRoYXQgbGVhZHMgdG8gdGhpcyBmdW5jdGlvblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJlaW5nIGludm9rZWQgYmVmb3JlIGhhbmRsZSBoYXMgYmVlbiBhc3NpZ25lZC5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlLWJlZm9yZS1kZWZpbmVcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay5jbGVhclRpbWVvdXQoaGFuZGxlKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3Qob3B0aW9ucy5zaWduYWwucmVhc29uKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZSA9IGNsb2NrLnNldFRpbWVvdXQoKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnNpZ25hbCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuZGVsZXRlKGFib3J0KTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHZhbHVlKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIGRlbGF5KTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsLmFib3J0ZWQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuc2V0KFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbCxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lT2ZNZXRob2RUb1JlcGxhY2UgPT09IFwic2V0SW1tZWRpYXRlXCIpIHtcblx0ICAgICAgICAgICAgICAgICAgICBjbG9jay50aW1lcnNQcm9taXNlc01vZHVsZU1ldGhvZHMucHVzaCh7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZE5hbWU6IFwic2V0SW1tZWRpYXRlXCIsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsOiB0aW1lcnNQcm9taXNlc01vZHVsZS5zZXRJbW1lZGlhdGUsXG5cdCAgICAgICAgICAgICAgICAgICAgfSk7XG5cblx0ICAgICAgICAgICAgICAgICAgICB0aW1lcnNQcm9taXNlc01vZHVsZS5zZXRJbW1lZGlhdGUgPSAodmFsdWUsIG9wdGlvbnMgPSB7fSkgPT5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWJvcnQgPSAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydCxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuZGVsZXRlKGFib3J0KTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgc2FmZSwgdGhlcmUgaXMgbm8gY29kZSBwYXRoIHRoYXQgbGVhZHMgdG8gdGhpcyBmdW5jdGlvblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJlaW5nIGludm9rZWQgYmVmb3JlIGhhbmRsZSBoYXMgYmVlbiBhc3NpZ25lZC5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlLWJlZm9yZS1kZWZpbmVcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay5jbGVhckltbWVkaWF0ZShoYW5kbGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChvcHRpb25zLnNpZ25hbC5yZWFzb24pO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaGFuZGxlID0gY2xvY2suc2V0SW1tZWRpYXRlKCgpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5zaWduYWwpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiYWJvcnRcIixcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay5hYm9ydExpc3RlbmVyTWFwLmRlbGV0ZShhYm9ydCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh2YWx1ZSk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsLmFib3J0ZWQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuc2V0KFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbCxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lT2ZNZXRob2RUb1JlcGxhY2UgPT09IFwic2V0SW50ZXJ2YWxcIikge1xuXHQgICAgICAgICAgICAgICAgICAgIGNsb2NrLnRpbWVyc1Byb21pc2VzTW9kdWxlTWV0aG9kcy5wdXNoKHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kTmFtZTogXCJzZXRJbnRlcnZhbFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbDogdGltZXJzUHJvbWlzZXNNb2R1bGUuc2V0SW50ZXJ2YWwsXG5cdCAgICAgICAgICAgICAgICAgICAgfSk7XG5cblx0ICAgICAgICAgICAgICAgICAgICB0aW1lcnNQcm9taXNlc01vZHVsZS5zZXRJbnRlcnZhbCA9IChcblx0ICAgICAgICAgICAgICAgICAgICAgICAgZGVsYXksXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zID0ge30sXG5cdCAgICAgICAgICAgICAgICAgICAgKSA9PiAoe1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBbU3ltYm9sLmFzeW5jSXRlcmF0b3JdOiAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjcmVhdGVSZXNvbHZhYmxlID0gKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCByZXNvbHZlLCByZWplY3Q7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXMsIHJlaikgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlID0gcmVzO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QgPSByZWo7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvbWlzZS5yZXNvbHZlID0gcmVzb2x2ZTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlLnJlamVjdCA9IHJlamVjdDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkb25lID0gZmFsc2U7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgaGFzVGhyb3duID0gZmFsc2U7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcmV0dXJuQ2FsbDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBuZXh0QXZhaWxhYmxlID0gMDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5leHRRdWV1ZSA9IFtdO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBoYW5kbGUgPSBjbG9jay5zZXRJbnRlcnZhbCgoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRRdWV1ZS5sZW5ndGggPiAwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRRdWV1ZS5zaGlmdCgpLnJlc29sdmUoKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0QXZhaWxhYmxlKys7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgZGVsYXkpO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhYm9ydCA9ICgpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImFib3J0XCIsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvY2suYWJvcnRMaXN0ZW5lck1hcC5kZWxldGUoYWJvcnQpO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvY2suY2xlYXJJbnRlcnZhbChoYW5kbGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcmVzb2x2YWJsZSBvZiBuZXh0UXVldWUpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2YWJsZS5yZXNvbHZlKCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsLmFib3J0ZWQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiYWJvcnRcIixcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay5hYm9ydExpc3RlbmVyTWFwLnNldChcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zaWduYWwsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHQ6IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsPy5hYm9ydGVkICYmICFoYXNUaHJvd24pIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc1Rocm93biA9IHRydWU7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBvcHRpb25zLnNpZ25hbC5yZWFzb247XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9uZSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgZG9uZTogdHJ1ZSwgdmFsdWU6IHVuZGVmaW5lZCB9O1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRBdmFpbGFibGUgPiAwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0QXZhaWxhYmxlLS07XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBkb25lOiBmYWxzZSwgdmFsdWU6IHZhbHVlIH07XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZXNvbHZhYmxlID0gY3JlYXRlUmVzb2x2YWJsZSgpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0UXVldWUucHVzaChyZXNvbHZhYmxlKTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCByZXNvbHZhYmxlO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXR1cm5DYWxsICYmIG5leHRRdWV1ZS5sZW5ndGggPT09IDApIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybkNhbGwucmVzb2x2ZSgpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsPy5hYm9ydGVkICYmICFoYXNUaHJvd24pIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc1Rocm93biA9IHRydWU7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBvcHRpb25zLnNpZ25hbC5yZWFzb247XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9uZSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgZG9uZTogdHJ1ZSwgdmFsdWU6IHVuZGVmaW5lZCB9O1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgZG9uZTogZmFsc2UsIHZhbHVlOiB2YWx1ZSB9O1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOiBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb25lKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBkb25lOiB0cnVlLCB2YWx1ZTogdW5kZWZpbmVkIH07XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV4dFF1ZXVlLmxlbmd0aCA+IDApIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybkNhbGwgPSBjcmVhdGVSZXNvbHZhYmxlKCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCByZXR1cm5DYWxsO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvY2suY2xlYXJJbnRlcnZhbChoYW5kbGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5zaWduYWwpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuZGVsZXRlKGFib3J0KTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7IGRvbmU6IHRydWUsIHZhbHVlOiB1bmRlZmluZWQgfTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIHJldHVybiBjbG9jaztcblx0ICAgIH1cblxuXHQgICAgLyogZXNsaW50LWVuYWJsZSBjb21wbGV4aXR5ICovXG5cblx0ICAgIHJldHVybiB7XG5cdCAgICAgICAgdGltZXJzOiB0aW1lcnMsXG5cdCAgICAgICAgY3JlYXRlQ2xvY2s6IGNyZWF0ZUNsb2NrLFxuXHQgICAgICAgIGluc3RhbGw6IGluc3RhbGwsXG5cdCAgICAgICAgd2l0aEdsb2JhbDogd2l0aEdsb2JhbCxcblx0ICAgIH07XG5cdH1cblxuXHQvKipcblx0ICogQHR5cGVkZWYge29iamVjdH0gRmFrZVRpbWVyc1xuXHQgKiBAcHJvcGVydHkge1RpbWVyc30gdGltZXJzXG5cdCAqIEBwcm9wZXJ0eSB7Y3JlYXRlQ2xvY2t9IGNyZWF0ZUNsb2NrXG5cdCAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGluc3RhbGxcblx0ICogQHByb3BlcnR5IHt3aXRoR2xvYmFsfSB3aXRoR2xvYmFsXG5cdCAqL1xuXG5cdC8qIGVzbGludC1lbmFibGUgY29tcGxleGl0eSAqL1xuXG5cdC8qKiBAdHlwZSB7RmFrZVRpbWVyc30gKi9cblx0Y29uc3QgZGVmYXVsdEltcGxlbWVudGF0aW9uID0gd2l0aEdsb2JhbChnbG9iYWxPYmplY3QpO1xuXG5cdGZha2VUaW1lcnNTcmMudGltZXJzID0gZGVmYXVsdEltcGxlbWVudGF0aW9uLnRpbWVycztcblx0ZmFrZVRpbWVyc1NyYy5jcmVhdGVDbG9jayA9IGRlZmF1bHRJbXBsZW1lbnRhdGlvbi5jcmVhdGVDbG9jaztcblx0ZmFrZVRpbWVyc1NyYy5pbnN0YWxsID0gZGVmYXVsdEltcGxlbWVudGF0aW9uLmluc3RhbGw7XG5cdGZha2VUaW1lcnNTcmMud2l0aEdsb2JhbCA9IHdpdGhHbG9iYWw7XG5cdHJldHVybiBmYWtlVGltZXJzU3JjO1xufVxuXG52YXIgZmFrZVRpbWVyc1NyY0V4cG9ydHMgPSByZXF1aXJlRmFrZVRpbWVyc1NyYygpO1xuXG5jbGFzcyBGYWtlVGltZXJzIHtcblx0X2dsb2JhbDtcblx0X2Nsb2NrO1xuXHQvLyB8IF9mYWtpbmdUaW1lIHwgX2Zha2luZ0RhdGUgfFxuXHQvLyArLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tK1xuXHQvLyB8IGZhbHNlICAgICAgIHwgZmFsc3kgICAgICAgfCBpbml0aWFsXG5cdC8vIHwgZmFsc2UgICAgICAgfCB0cnV0aHkgICAgICB8IHZpLnNldFN5c3RlbVRpbWUgY2FsbGVkIGZpcnN0IChmb3IgbW9ja2luZyBvbmx5IERhdGUgd2l0aG91dCBmYWtlIHRpbWVycylcblx0Ly8gfCB0cnVlICAgICAgICB8IGZhbHN5ICAgICAgIHwgdmkudXNlRmFrZVRpbWVycyBjYWxsZWQgZmlyc3Rcblx0Ly8gfCB0cnVlICAgICAgICB8IHRydXRoeSAgICAgIHwgdW5yZWFjaGFibGVcblx0X2Zha2luZ1RpbWU7XG5cdF9mYWtpbmdEYXRlO1xuXHRfZmFrZVRpbWVycztcblx0X3VzZXJDb25maWc7XG5cdF9ub3cgPSBSZWFsRGF0ZS5ub3c7XG5cdGNvbnN0cnVjdG9yKHsgZ2xvYmFsLCBjb25maWcgfSkge1xuXHRcdHRoaXMuX3VzZXJDb25maWcgPSBjb25maWc7XG5cdFx0dGhpcy5fZmFraW5nRGF0ZSA9IG51bGw7XG5cdFx0dGhpcy5fZmFraW5nVGltZSA9IGZhbHNlO1xuXHRcdHRoaXMuX2Zha2VUaW1lcnMgPSBmYWtlVGltZXJzU3JjRXhwb3J0cy53aXRoR2xvYmFsKGdsb2JhbCk7XG5cdFx0dGhpcy5fZ2xvYmFsID0gZ2xvYmFsO1xuXHR9XG5cdGNsZWFyQWxsVGltZXJzKCkge1xuXHRcdGlmICh0aGlzLl9mYWtpbmdUaW1lKSB0aGlzLl9jbG9jay5yZXNldCgpO1xuXHR9XG5cdGRpc3Bvc2UoKSB7XG5cdFx0dGhpcy51c2VSZWFsVGltZXJzKCk7XG5cdH1cblx0cnVuQWxsVGltZXJzKCkge1xuXHRcdGlmICh0aGlzLl9jaGVja0Zha2VUaW1lcnMoKSkgdGhpcy5fY2xvY2sucnVuQWxsKCk7XG5cdH1cblx0YXN5bmMgcnVuQWxsVGltZXJzQXN5bmMoKSB7XG5cdFx0aWYgKHRoaXMuX2NoZWNrRmFrZVRpbWVycygpKSBhd2FpdCB0aGlzLl9jbG9jay5ydW5BbGxBc3luYygpO1xuXHR9XG5cdHJ1bk9ubHlQZW5kaW5nVGltZXJzKCkge1xuXHRcdGlmICh0aGlzLl9jaGVja0Zha2VUaW1lcnMoKSkgdGhpcy5fY2xvY2sucnVuVG9MYXN0KCk7XG5cdH1cblx0YXN5bmMgcnVuT25seVBlbmRpbmdUaW1lcnNBc3luYygpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIGF3YWl0IHRoaXMuX2Nsb2NrLnJ1blRvTGFzdEFzeW5jKCk7XG5cdH1cblx0YWR2YW5jZVRpbWVyc1RvTmV4dFRpbWVyKHN0ZXBzID0gMSkge1xuXHRcdGlmICh0aGlzLl9jaGVja0Zha2VUaW1lcnMoKSkgZm9yIChsZXQgaSA9IHN0ZXBzOyBpID4gMDsgaS0tKSB7XG5cdFx0XHR0aGlzLl9jbG9jay5uZXh0KCk7XG5cdFx0XHQvLyBGaXJlIGFsbCB0aW1lcnMgYXQgdGhpcyBwb2ludDogaHR0cHM6Ly9naXRodWIuY29tL3Npbm9uanMvZmFrZS10aW1lcnMvaXNzdWVzLzI1MFxuXHRcdFx0dGhpcy5fY2xvY2sudGljaygwKTtcblx0XHRcdGlmICh0aGlzLl9jbG9jay5jb3VudFRpbWVycygpID09PSAwKSBicmVhaztcblx0XHR9XG5cdH1cblx0YXN5bmMgYWR2YW5jZVRpbWVyc1RvTmV4dFRpbWVyQXN5bmMoc3RlcHMgPSAxKSB7XG5cdFx0aWYgKHRoaXMuX2NoZWNrRmFrZVRpbWVycygpKSBmb3IgKGxldCBpID0gc3RlcHM7IGkgPiAwOyBpLS0pIHtcblx0XHRcdGF3YWl0IHRoaXMuX2Nsb2NrLm5leHRBc3luYygpO1xuXHRcdFx0Ly8gRmlyZSBhbGwgdGltZXJzIGF0IHRoaXMgcG9pbnQ6IGh0dHBzOi8vZ2l0aHViLmNvbS9zaW5vbmpzL2Zha2UtdGltZXJzL2lzc3Vlcy8yNTBcblx0XHRcdHRoaXMuX2Nsb2NrLnRpY2soMCk7XG5cdFx0XHRpZiAodGhpcy5fY2xvY2suY291bnRUaW1lcnMoKSA9PT0gMCkgYnJlYWs7XG5cdFx0fVxuXHR9XG5cdGFkdmFuY2VUaW1lcnNCeVRpbWUobXNUb1J1bikge1xuXHRcdGlmICh0aGlzLl9jaGVja0Zha2VUaW1lcnMoKSkgdGhpcy5fY2xvY2sudGljayhtc1RvUnVuKTtcblx0fVxuXHRhc3luYyBhZHZhbmNlVGltZXJzQnlUaW1lQXN5bmMobXNUb1J1bikge1xuXHRcdGlmICh0aGlzLl9jaGVja0Zha2VUaW1lcnMoKSkgYXdhaXQgdGhpcy5fY2xvY2sudGlja0FzeW5jKG1zVG9SdW4pO1xuXHR9XG5cdGFkdmFuY2VUaW1lcnNUb05leHRGcmFtZSgpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIHRoaXMuX2Nsb2NrLnJ1blRvRnJhbWUoKTtcblx0fVxuXHRydW5BbGxUaWNrcygpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIHRoaXMuX2Nsb2NrLnJ1bk1pY3JvdGFza3MoKTtcblx0fVxuXHR1c2VSZWFsVGltZXJzKCkge1xuXHRcdGlmICh0aGlzLl9mYWtpbmdEYXRlKSB7XG5cdFx0XHRyZXNldERhdGUoKTtcblx0XHRcdHRoaXMuX2Zha2luZ0RhdGUgPSBudWxsO1xuXHRcdH1cblx0XHRpZiAodGhpcy5fZmFraW5nVGltZSkge1xuXHRcdFx0dGhpcy5fY2xvY2sudW5pbnN0YWxsKCk7XG5cdFx0XHR0aGlzLl9mYWtpbmdUaW1lID0gZmFsc2U7XG5cdFx0fVxuXHR9XG5cdHVzZUZha2VUaW1lcnMoKSB7XG5cdFx0Y29uc3QgZmFrZURhdGUgPSB0aGlzLl9mYWtpbmdEYXRlIHx8IERhdGUubm93KCk7XG5cdFx0aWYgKHRoaXMuX2Zha2luZ0RhdGUpIHtcblx0XHRcdHJlc2V0RGF0ZSgpO1xuXHRcdFx0dGhpcy5fZmFraW5nRGF0ZSA9IG51bGw7XG5cdFx0fVxuXHRcdGlmICh0aGlzLl9mYWtpbmdUaW1lKSB0aGlzLl9jbG9jay51bmluc3RhbGwoKTtcblx0XHRjb25zdCB0b0Zha2UgPSBPYmplY3Qua2V5cyh0aGlzLl9mYWtlVGltZXJzLnRpbWVycykuZmlsdGVyKCh0aW1lcikgPT4gdGltZXIgIT09IFwibmV4dFRpY2tcIiAmJiB0aW1lciAhPT0gXCJxdWV1ZU1pY3JvdGFza1wiKTtcblx0XHRpZiAodGhpcy5fdXNlckNvbmZpZz8udG9GYWtlPy5pbmNsdWRlcyhcIm5leHRUaWNrXCIpICYmIGlzQ2hpbGRQcm9jZXNzKCkpIHRocm93IG5ldyBFcnJvcihcInByb2Nlc3MubmV4dFRpY2sgY2Fubm90IGJlIG1vY2tlZCBpbnNpZGUgY2hpbGRfcHJvY2Vzc1wiKTtcblx0XHR0aGlzLl9jbG9jayA9IHRoaXMuX2Zha2VUaW1lcnMuaW5zdGFsbCh7XG5cdFx0XHRub3c6IGZha2VEYXRlLFxuXHRcdFx0Li4udGhpcy5fdXNlckNvbmZpZyxcblx0XHRcdHRvRmFrZTogdGhpcy5fdXNlckNvbmZpZz8udG9GYWtlIHx8IHRvRmFrZSxcblx0XHRcdGlnbm9yZU1pc3NpbmdUaW1lcnM6IHRydWVcblx0XHR9KTtcblx0XHR0aGlzLl9mYWtpbmdUaW1lID0gdHJ1ZTtcblx0fVxuXHRyZXNldCgpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIHtcblx0XHRcdGNvbnN0IHsgbm93IH0gPSB0aGlzLl9jbG9jaztcblx0XHRcdHRoaXMuX2Nsb2NrLnJlc2V0KCk7XG5cdFx0XHR0aGlzLl9jbG9jay5zZXRTeXN0ZW1UaW1lKG5vdyk7XG5cdFx0fVxuXHR9XG5cdHNldFN5c3RlbVRpbWUobm93KSB7XG5cdFx0Y29uc3QgZGF0ZSA9IHR5cGVvZiBub3cgPT09IFwidW5kZWZpbmVkXCIgfHwgbm93IGluc3RhbmNlb2YgRGF0ZSA/IG5vdyA6IG5ldyBEYXRlKG5vdyk7XG5cdFx0aWYgKHRoaXMuX2Zha2luZ1RpbWUpIHRoaXMuX2Nsb2NrLnNldFN5c3RlbVRpbWUoZGF0ZSk7XG5cdFx0ZWxzZSB7XG5cdFx0XHR0aGlzLl9mYWtpbmdEYXRlID0gZGF0ZSA/PyBuZXcgRGF0ZSh0aGlzLmdldFJlYWxTeXN0ZW1UaW1lKCkpO1xuXHRcdFx0bW9ja0RhdGUodGhpcy5fZmFraW5nRGF0ZSk7XG5cdFx0fVxuXHR9XG5cdGdldE1vY2tlZFN5c3RlbVRpbWUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX2Zha2luZ1RpbWUgPyBuZXcgRGF0ZSh0aGlzLl9jbG9jay5ub3cpIDogdGhpcy5fZmFraW5nRGF0ZTtcblx0fVxuXHRnZXRSZWFsU3lzdGVtVGltZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5fbm93KCk7XG5cdH1cblx0Z2V0VGltZXJDb3VudCgpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIHJldHVybiB0aGlzLl9jbG9jay5jb3VudFRpbWVycygpO1xuXHRcdHJldHVybiAwO1xuXHR9XG5cdHNldFRpbWVyVGlja01vZGUobW9kZSwgaW50ZXJ2YWwpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIGlmIChtb2RlID09PSBcIm1hbnVhbFwiKSB0aGlzLl9jbG9jay5zZXRUaWNrTW9kZSh7IG1vZGU6IFwibWFudWFsXCIgfSk7XG5cdFx0ZWxzZSBpZiAobW9kZSA9PT0gXCJuZXh0VGltZXJBc3luY1wiKSB0aGlzLl9jbG9jay5zZXRUaWNrTW9kZSh7IG1vZGU6IFwibmV4dEFzeW5jXCIgfSk7XG5cdFx0ZWxzZSBpZiAobW9kZSA9PT0gXCJpbnRlcnZhbFwiKSB0aGlzLl9jbG9jay5zZXRUaWNrTW9kZSh7XG5cdFx0XHRtb2RlOiBcImludGVydmFsXCIsXG5cdFx0XHRkZWx0YTogaW50ZXJ2YWxcblx0XHR9KTtcblx0XHRlbHNlIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB0aWNrIG1vZGU6ICR7bW9kZX1gKTtcblx0fVxuXHRjb25maWd1cmUoY29uZmlnKSB7XG5cdFx0dGhpcy5fdXNlckNvbmZpZyA9IGNvbmZpZztcblx0fVxuXHRpc0Zha2VUaW1lcnMoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX2Zha2luZ1RpbWU7XG5cdH1cblx0X2NoZWNrRmFrZVRpbWVycygpIHtcblx0XHRpZiAoIXRoaXMuX2Zha2luZ1RpbWUpIHRocm93IG5ldyBFcnJvcihcIkEgZnVuY3Rpb24gdG8gYWR2YW5jZSB0aW1lcnMgd2FzIGNhbGxlZCBidXQgdGhlIHRpbWVycyBBUElzIGFyZSBub3QgbW9ja2VkLiBDYWxsIGB2aS51c2VGYWtlVGltZXJzKClgIGluIHRoZSB0ZXN0IGZpbGUgZmlyc3QuXCIpO1xuXHRcdHJldHVybiB0aGlzLl9mYWtpbmdUaW1lO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGNvcHlTdGFja1RyYWNlKHRhcmdldCwgc291cmNlKSB7XG5cdGlmIChzb3VyY2Uuc3RhY2sgIT09IHZvaWQgMCkgdGFyZ2V0LnN0YWNrID0gc291cmNlLnN0YWNrLnJlcGxhY2Uoc291cmNlLm1lc3NhZ2UsIHRhcmdldC5tZXNzYWdlKTtcblx0cmV0dXJuIHRhcmdldDtcbn1cbmZ1bmN0aW9uIHdhaXRGb3IoY2FsbGJhY2ssIG9wdGlvbnMgPSB7fSkge1xuXHRjb25zdCB7IHNldFRpbWVvdXQsIHNldEludGVydmFsLCBjbGVhclRpbWVvdXQsIGNsZWFySW50ZXJ2YWwgfSA9IGdldFNhZmVUaW1lcnMoKTtcblx0Y29uc3QgeyBpbnRlcnZhbCA9IDUwLCB0aW1lb3V0ID0gMWUzIH0gPSB0eXBlb2Ygb3B0aW9ucyA9PT0gXCJudW1iZXJcIiA/IHsgdGltZW91dDogb3B0aW9ucyB9IDogb3B0aW9ucztcblx0Y29uc3QgU1RBQ0tfVFJBQ0VfRVJST1IgPSAvKiBAX19QVVJFX18gKi8gbmV3IEVycm9yKFwiU1RBQ0tfVFJBQ0VfRVJST1JcIik7XG5cdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cdFx0bGV0IGxhc3RFcnJvcjtcblx0XHRsZXQgcHJvbWlzZVN0YXR1cyA9IFwiaWRsZVwiO1xuXHRcdGxldCB0aW1lb3V0SWQ7XG5cdFx0bGV0IGludGVydmFsSWQ7XG5cdFx0Y29uc3Qgb25SZXNvbHZlID0gKHJlc3VsdCkgPT4ge1xuXHRcdFx0aWYgKHRpbWVvdXRJZCkgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG5cdFx0XHRpZiAoaW50ZXJ2YWxJZCkgY2xlYXJJbnRlcnZhbChpbnRlcnZhbElkKTtcblx0XHRcdHJlc29sdmUocmVzdWx0KTtcblx0XHR9O1xuXHRcdGNvbnN0IGhhbmRsZVRpbWVvdXQgPSAoKSA9PiB7XG5cdFx0XHRpZiAoaW50ZXJ2YWxJZCkgY2xlYXJJbnRlcnZhbChpbnRlcnZhbElkKTtcblx0XHRcdGxldCBlcnJvciA9IGxhc3RFcnJvcjtcblx0XHRcdGlmICghZXJyb3IpIGVycm9yID0gY29weVN0YWNrVHJhY2UoLyogQF9fUFVSRV9fICovIG5ldyBFcnJvcihcIlRpbWVkIG91dCBpbiB3YWl0Rm9yIVwiKSwgU1RBQ0tfVFJBQ0VfRVJST1IpO1xuXHRcdFx0cmVqZWN0KGVycm9yKTtcblx0XHR9O1xuXHRcdGNvbnN0IGNoZWNrQ2FsbGJhY2sgPSAoKSA9PiB7XG5cdFx0XHRpZiAodmkuaXNGYWtlVGltZXJzKCkpIHZpLmFkdmFuY2VUaW1lcnNCeVRpbWUoaW50ZXJ2YWwpO1xuXHRcdFx0aWYgKHByb21pc2VTdGF0dXMgPT09IFwicGVuZGluZ1wiKSByZXR1cm47XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRjb25zdCByZXN1bHQgPSBjYWxsYmFjaygpO1xuXHRcdFx0XHRpZiAocmVzdWx0ICE9PSBudWxsICYmIHR5cGVvZiByZXN1bHQgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlc3VsdC50aGVuID09PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdFx0XHRjb25zdCB0aGVuYWJsZSA9IHJlc3VsdDtcblx0XHRcdFx0XHRwcm9taXNlU3RhdHVzID0gXCJwZW5kaW5nXCI7XG5cdFx0XHRcdFx0dGhlbmFibGUudGhlbigocmVzb2x2ZWRWYWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0cHJvbWlzZVN0YXR1cyA9IFwicmVzb2x2ZWRcIjtcblx0XHRcdFx0XHRcdG9uUmVzb2x2ZShyZXNvbHZlZFZhbHVlKTtcblx0XHRcdFx0XHR9LCAocmVqZWN0ZWRWYWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0cHJvbWlzZVN0YXR1cyA9IFwicmVqZWN0ZWRcIjtcblx0XHRcdFx0XHRcdGxhc3RFcnJvciA9IHJlamVjdGVkVmFsdWU7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0b25SZXNvbHZlKHJlc3VsdCk7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRcdGxhc3RFcnJvciA9IGVycm9yO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0aWYgKGNoZWNrQ2FsbGJhY2soKSA9PT0gdHJ1ZSkgcmV0dXJuO1xuXHRcdHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoaGFuZGxlVGltZW91dCwgdGltZW91dCk7XG5cdFx0aW50ZXJ2YWxJZCA9IHNldEludGVydmFsKGNoZWNrQ2FsbGJhY2ssIGludGVydmFsKTtcblx0fSk7XG59XG5mdW5jdGlvbiB3YWl0VW50aWwoY2FsbGJhY2ssIG9wdGlvbnMgPSB7fSkge1xuXHRjb25zdCB7IHNldFRpbWVvdXQsIHNldEludGVydmFsLCBjbGVhclRpbWVvdXQsIGNsZWFySW50ZXJ2YWwgfSA9IGdldFNhZmVUaW1lcnMoKTtcblx0Y29uc3QgeyBpbnRlcnZhbCA9IDUwLCB0aW1lb3V0ID0gMWUzIH0gPSB0eXBlb2Ygb3B0aW9ucyA9PT0gXCJudW1iZXJcIiA/IHsgdGltZW91dDogb3B0aW9ucyB9IDogb3B0aW9ucztcblx0Y29uc3QgU1RBQ0tfVFJBQ0VfRVJST1IgPSAvKiBAX19QVVJFX18gKi8gbmV3IEVycm9yKFwiU1RBQ0tfVFJBQ0VfRVJST1JcIik7XG5cdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cdFx0bGV0IHByb21pc2VTdGF0dXMgPSBcImlkbGVcIjtcblx0XHRsZXQgdGltZW91dElkO1xuXHRcdGxldCBpbnRlcnZhbElkO1xuXHRcdGNvbnN0IG9uUmVqZWN0ID0gKGVycm9yKSA9PiB7XG5cdFx0XHRpZiAoaW50ZXJ2YWxJZCkgY2xlYXJJbnRlcnZhbChpbnRlcnZhbElkKTtcblx0XHRcdGlmICghZXJyb3IpIGVycm9yID0gY29weVN0YWNrVHJhY2UoLyogQF9fUFVSRV9fICovIG5ldyBFcnJvcihcIlRpbWVkIG91dCBpbiB3YWl0VW50aWwhXCIpLCBTVEFDS19UUkFDRV9FUlJPUik7XG5cdFx0XHRyZWplY3QoZXJyb3IpO1xuXHRcdH07XG5cdFx0Y29uc3Qgb25SZXNvbHZlID0gKHJlc3VsdCkgPT4ge1xuXHRcdFx0aWYgKCFyZXN1bHQpIHJldHVybjtcblx0XHRcdGlmICh0aW1lb3V0SWQpIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuXHRcdFx0aWYgKGludGVydmFsSWQpIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWxJZCk7XG5cdFx0XHRyZXNvbHZlKHJlc3VsdCk7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9O1xuXHRcdGNvbnN0IGNoZWNrQ2FsbGJhY2sgPSAoKSA9PiB7XG5cdFx0XHRpZiAodmkuaXNGYWtlVGltZXJzKCkpIHZpLmFkdmFuY2VUaW1lcnNCeVRpbWUoaW50ZXJ2YWwpO1xuXHRcdFx0aWYgKHByb21pc2VTdGF0dXMgPT09IFwicGVuZGluZ1wiKSByZXR1cm47XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRjb25zdCByZXN1bHQgPSBjYWxsYmFjaygpO1xuXHRcdFx0XHRpZiAocmVzdWx0ICE9PSBudWxsICYmIHR5cGVvZiByZXN1bHQgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlc3VsdC50aGVuID09PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdFx0XHRjb25zdCB0aGVuYWJsZSA9IHJlc3VsdDtcblx0XHRcdFx0XHRwcm9taXNlU3RhdHVzID0gXCJwZW5kaW5nXCI7XG5cdFx0XHRcdFx0dGhlbmFibGUudGhlbigocmVzb2x2ZWRWYWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0cHJvbWlzZVN0YXR1cyA9IFwicmVzb2x2ZWRcIjtcblx0XHRcdFx0XHRcdG9uUmVzb2x2ZShyZXNvbHZlZFZhbHVlKTtcblx0XHRcdFx0XHR9LCAocmVqZWN0ZWRWYWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0cHJvbWlzZVN0YXR1cyA9IFwicmVqZWN0ZWRcIjtcblx0XHRcdFx0XHRcdG9uUmVqZWN0KHJlamVjdGVkVmFsdWUpO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9IGVsc2UgcmV0dXJuIG9uUmVzb2x2ZShyZXN1bHQpO1xuXHRcdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdFx0b25SZWplY3QoZXJyb3IpO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0aWYgKGNoZWNrQ2FsbGJhY2soKSA9PT0gdHJ1ZSkgcmV0dXJuO1xuXHRcdHRpbWVvdXRJZCA9IHNldFRpbWVvdXQob25SZWplY3QsIHRpbWVvdXQpO1xuXHRcdGludGVydmFsSWQgPSBzZXRJbnRlcnZhbChjaGVja0NhbGxiYWNrLCBpbnRlcnZhbCk7XG5cdH0pO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVWaXRlc3QoKSB7XG5cdGxldCBfY29uZmlnID0gbnVsbDtcblx0Y29uc3Qgc3RhdGUgPSAoKSA9PiBnZXRXb3JrZXJTdGF0ZSgpO1xuXHRsZXQgX3RpbWVycztcblx0Y29uc3QgdGltZXJzID0gKCkgPT4gX3RpbWVycyB8fD0gbmV3IEZha2VUaW1lcnMoe1xuXHRcdGdsb2JhbDogZ2xvYmFsVGhpcyxcblx0XHRjb25maWc6IHN0YXRlKCkuY29uZmlnLmZha2VUaW1lcnNcblx0fSk7XG5cdGNvbnN0IF9zdHVic0dsb2JhbCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7XG5cdGNvbnN0IF9zdHVic0VudiA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7XG5cdGNvbnN0IF9lbnZCb29sZWFucyA9IFtcblx0XHRcIlBST0RcIixcblx0XHRcIkRFVlwiLFxuXHRcdFwiU1NSXCJcblx0XTtcblx0Y29uc3QgdXRpbHMgPSB7XG5cdFx0dXNlRmFrZVRpbWVycyhjb25maWcpIHtcblx0XHRcdGlmIChpc0NoaWxkUHJvY2VzcygpKSB7XG5cdFx0XHRcdGlmIChjb25maWc/LnRvRmFrZT8uaW5jbHVkZXMoXCJuZXh0VGlja1wiKSB8fCBzdGF0ZSgpLmNvbmZpZz8uZmFrZVRpbWVycz8udG9GYWtlPy5pbmNsdWRlcyhcIm5leHRUaWNrXCIpKSB0aHJvdyBuZXcgRXJyb3IoXCJ2aS51c2VGYWtlVGltZXJzKHsgdG9GYWtlOiBbXFxcIm5leHRUaWNrXFxcIl0gfSkgaXMgbm90IHN1cHBvcnRlZCBpbiBub2RlOmNoaWxkX3Byb2Nlc3MuIFVzZSAtLXBvb2w9dGhyZWFkcyBpZiBtb2NraW5nIG5leHRUaWNrIGlzIHJlcXVpcmVkLlwiKTtcblx0XHRcdH1cblx0XHRcdGlmIChjb25maWcpIHRpbWVycygpLmNvbmZpZ3VyZSh7XG5cdFx0XHRcdC4uLnN0YXRlKCkuY29uZmlnLmZha2VUaW1lcnMsXG5cdFx0XHRcdC4uLmNvbmZpZ1xuXHRcdFx0fSk7XG5cdFx0XHRlbHNlIHRpbWVycygpLmNvbmZpZ3VyZShzdGF0ZSgpLmNvbmZpZy5mYWtlVGltZXJzKTtcblx0XHRcdHRpbWVycygpLnVzZUZha2VUaW1lcnMoKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdGlzRmFrZVRpbWVycygpIHtcblx0XHRcdHJldHVybiB0aW1lcnMoKS5pc0Zha2VUaW1lcnMoKTtcblx0XHR9LFxuXHRcdHVzZVJlYWxUaW1lcnMoKSB7XG5cdFx0XHR0aW1lcnMoKS51c2VSZWFsVGltZXJzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRydW5Pbmx5UGVuZGluZ1RpbWVycygpIHtcblx0XHRcdHRpbWVycygpLnJ1bk9ubHlQZW5kaW5nVGltZXJzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRhc3luYyBydW5Pbmx5UGVuZGluZ1RpbWVyc0FzeW5jKCkge1xuXHRcdFx0YXdhaXQgdGltZXJzKCkucnVuT25seVBlbmRpbmdUaW1lcnNBc3luYygpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0cnVuQWxsVGltZXJzKCkge1xuXHRcdFx0dGltZXJzKCkucnVuQWxsVGltZXJzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRhc3luYyBydW5BbGxUaW1lcnNBc3luYygpIHtcblx0XHRcdGF3YWl0IHRpbWVycygpLnJ1bkFsbFRpbWVyc0FzeW5jKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRydW5BbGxUaWNrcygpIHtcblx0XHRcdHRpbWVycygpLnJ1bkFsbFRpY2tzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRhZHZhbmNlVGltZXJzQnlUaW1lKG1zKSB7XG5cdFx0XHR0aW1lcnMoKS5hZHZhbmNlVGltZXJzQnlUaW1lKG1zKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdGFzeW5jIGFkdmFuY2VUaW1lcnNCeVRpbWVBc3luYyhtcykge1xuXHRcdFx0YXdhaXQgdGltZXJzKCkuYWR2YW5jZVRpbWVyc0J5VGltZUFzeW5jKG1zKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdGFkdmFuY2VUaW1lcnNUb05leHRUaW1lcigpIHtcblx0XHRcdHRpbWVycygpLmFkdmFuY2VUaW1lcnNUb05leHRUaW1lcigpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0YXN5bmMgYWR2YW5jZVRpbWVyc1RvTmV4dFRpbWVyQXN5bmMoKSB7XG5cdFx0XHRhd2FpdCB0aW1lcnMoKS5hZHZhbmNlVGltZXJzVG9OZXh0VGltZXJBc3luYygpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0YWR2YW5jZVRpbWVyc1RvTmV4dEZyYW1lKCkge1xuXHRcdFx0dGltZXJzKCkuYWR2YW5jZVRpbWVyc1RvTmV4dEZyYW1lKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRnZXRUaW1lckNvdW50KCkge1xuXHRcdFx0cmV0dXJuIHRpbWVycygpLmdldFRpbWVyQ291bnQoKTtcblx0XHR9LFxuXHRcdHNldFN5c3RlbVRpbWUodGltZSkge1xuXHRcdFx0dGltZXJzKCkuc2V0U3lzdGVtVGltZSh0aW1lKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdGdldE1vY2tlZFN5c3RlbVRpbWUoKSB7XG5cdFx0XHRyZXR1cm4gdGltZXJzKCkuZ2V0TW9ja2VkU3lzdGVtVGltZSgpO1xuXHRcdH0sXG5cdFx0Z2V0UmVhbFN5c3RlbVRpbWUoKSB7XG5cdFx0XHRyZXR1cm4gdGltZXJzKCkuZ2V0UmVhbFN5c3RlbVRpbWUoKTtcblx0XHR9LFxuXHRcdGNsZWFyQWxsVGltZXJzKCkge1xuXHRcdFx0dGltZXJzKCkuY2xlYXJBbGxUaW1lcnMoKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdHNldFRpbWVyVGlja01vZGUobW9kZSwgaW50ZXJ2YWwpIHtcblx0XHRcdHRpbWVycygpLnNldFRpbWVyVGlja01vZGUobW9kZSwgaW50ZXJ2YWwpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0c3B5T24sXG5cdFx0Zm4sXG5cdFx0d2FpdEZvcixcblx0XHR3YWl0VW50aWwsXG5cdFx0ZGVmaW5lSGVscGVyOiAoZm4pID0+IHtcblx0XHRcdHJldHVybiBmdW5jdGlvbiBfX1ZJVEVTVF9IRUxQRVJfXyguLi5hcmdzKSB7XG5cdFx0XHRcdGNvbnN0IHJlc3VsdCA9IGZuKC4uLmFyZ3MpO1xuXHRcdFx0XHRpZiAocmVzdWx0ICYmIHR5cGVvZiByZXN1bHQgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlc3VsdC50aGVuID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiAoYXN5bmMgZnVuY3Rpb24gX19WSVRFU1RfSEVMUEVSX18oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGF3YWl0IHJlc3VsdDtcblx0XHRcdFx0fSkoKTtcblx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdH07XG5cdFx0fSxcblx0XHRob2lzdGVkKGZhY3RvcnkpIHtcblx0XHRcdGFzc2VydFR5cGVzKGZhY3RvcnksIFwiXFxcInZpLmhvaXN0ZWRcXFwiIGZhY3RvcnlcIiwgW1wiZnVuY3Rpb25cIl0pO1xuXHRcdFx0cmV0dXJuIGZhY3RvcnkoKTtcblx0XHR9LFxuXHRcdG1vY2socGF0aCwgZmFjdG9yeSkge1xuXHRcdFx0aWYgKHR5cGVvZiBwYXRoICE9PSBcInN0cmluZ1wiKSB0aHJvdyBuZXcgVHlwZUVycm9yKGB2aS5tb2NrKCkgZXhwZWN0cyBhIHN0cmluZyBwYXRoLCBidXQgcmVjZWl2ZWQgYSAke3R5cGVvZiBwYXRofWApO1xuXHRcdFx0Y29uc3QgaW1wb3J0ZXIgPSBnZXRJbXBvcnRlcihcIm1vY2tcIik7XG5cdFx0XHRfbW9ja2VyKCkucXVldWVNb2NrKHBhdGgsIGltcG9ydGVyLCB0eXBlb2YgZmFjdG9yeSA9PT0gXCJmdW5jdGlvblwiID8gKCkgPT4gZmFjdG9yeSgoKSA9PiBfbW9ja2VyKCkuaW1wb3J0QWN0dWFsKHBhdGgsIGltcG9ydGVyLCBfbW9ja2VyKCkuZ2V0TW9ja0NvbnRleHQoKS5jYWxsc3RhY2spKSA6IGZhY3RvcnkpO1xuXHRcdH0sXG5cdFx0dW5tb2NrKHBhdGgpIHtcblx0XHRcdGlmICh0eXBlb2YgcGF0aCAhPT0gXCJzdHJpbmdcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihgdmkudW5tb2NrKCkgZXhwZWN0cyBhIHN0cmluZyBwYXRoLCBidXQgcmVjZWl2ZWQgYSAke3R5cGVvZiBwYXRofWApO1xuXHRcdFx0X21vY2tlcigpLnF1ZXVlVW5tb2NrKHBhdGgsIGdldEltcG9ydGVyKFwidW5tb2NrXCIpKTtcblx0XHR9LFxuXHRcdGRvTW9jayhwYXRoLCBmYWN0b3J5KSB7XG5cdFx0XHRpZiAodHlwZW9mIHBhdGggIT09IFwic3RyaW5nXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoYHZpLmRvTW9jaygpIGV4cGVjdHMgYSBzdHJpbmcgcGF0aCwgYnV0IHJlY2VpdmVkIGEgJHt0eXBlb2YgcGF0aH1gKTtcblx0XHRcdGNvbnN0IGltcG9ydGVyID0gZ2V0SW1wb3J0ZXIoXCJkb01vY2tcIik7XG5cdFx0XHRfbW9ja2VyKCkucXVldWVNb2NrKHBhdGgsIGltcG9ydGVyLCB0eXBlb2YgZmFjdG9yeSA9PT0gXCJmdW5jdGlvblwiID8gKCkgPT4gZmFjdG9yeSgoKSA9PiBfbW9ja2VyKCkuaW1wb3J0QWN0dWFsKHBhdGgsIGltcG9ydGVyLCBfbW9ja2VyKCkuZ2V0TW9ja0NvbnRleHQoKS5jYWxsc3RhY2spKSA6IGZhY3RvcnkpO1xuXHRcdFx0Y29uc3QgcnYgPSB7fTtcblx0XHRcdGlmIChTeW1ib2wuZGlzcG9zZSkgcnZbU3ltYm9sLmRpc3Bvc2VdID0gKCkgPT4ge1xuXHRcdFx0XHRfbW9ja2VyKCkucXVldWVVbm1vY2socGF0aCwgaW1wb3J0ZXIpO1xuXHRcdFx0fTtcblx0XHRcdHJldHVybiBydjtcblx0XHR9LFxuXHRcdGRvVW5tb2NrKHBhdGgpIHtcblx0XHRcdGlmICh0eXBlb2YgcGF0aCAhPT0gXCJzdHJpbmdcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihgdmkuZG9Vbm1vY2soKSBleHBlY3RzIGEgc3RyaW5nIHBhdGgsIGJ1dCByZWNlaXZlZCBhICR7dHlwZW9mIHBhdGh9YCk7XG5cdFx0XHRjb25zdCBpbXBvcnRlciA9IGdldEltcG9ydGVyKFwiZG9Vbm1vY2tcIik7XG5cdFx0XHRfbW9ja2VyKCkucXVldWVVbm1vY2socGF0aCwgaW1wb3J0ZXIpO1xuXHRcdH0sXG5cdFx0YXN5bmMgaW1wb3J0QWN0dWFsKHBhdGgpIHtcblx0XHRcdGNvbnN0IGltcG9ydGVyID0gZ2V0SW1wb3J0ZXIoXCJpbXBvcnRBY3R1YWxcIik7XG5cdFx0XHRyZXR1cm4gX21vY2tlcigpLmltcG9ydEFjdHVhbChwYXRoLCBpbXBvcnRlciwgX21vY2tlcigpLmdldE1vY2tDb250ZXh0KCkuY2FsbHN0YWNrKTtcblx0XHR9LFxuXHRcdGFzeW5jIGltcG9ydE1vY2socGF0aCkge1xuXHRcdFx0Y29uc3QgaW1wb3J0ZXIgPSBnZXRJbXBvcnRlcihcImltcG9ydE1vY2tcIik7XG5cdFx0XHRyZXR1cm4gX21vY2tlcigpLmltcG9ydE1vY2socGF0aCwgaW1wb3J0ZXIpO1xuXHRcdH0sXG5cdFx0bW9ja09iamVjdCh2YWx1ZSwgb3B0aW9ucykge1xuXHRcdFx0cmV0dXJuIF9tb2NrZXIoKS5tb2NrT2JqZWN0KHsgdmFsdWUgfSwgdm9pZCAwLCBvcHRpb25zPy5zcHkgPyBcImF1dG9zcHlcIiA6IFwiYXV0b21vY2tcIikudmFsdWU7XG5cdFx0fSxcblx0XHRtb2NrZWQoaXRlbSwgX29wdGlvbnMgPSB7fSkge1xuXHRcdFx0cmV0dXJuIGl0ZW07XG5cdFx0fSxcblx0XHRpc01vY2tGdW5jdGlvbihmbikge1xuXHRcdFx0cmV0dXJuIGlzTW9ja0Z1bmN0aW9uKGZuKTtcblx0XHR9LFxuXHRcdGNsZWFyQWxsTW9ja3MoKSB7XG5cdFx0XHRjbGVhckFsbE1vY2tzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRyZXNldEFsbE1vY2tzKCkge1xuXHRcdFx0cmVzZXRBbGxNb2NrcygpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0cmVzdG9yZUFsbE1vY2tzKCkge1xuXHRcdFx0cmVzdG9yZUFsbE1vY2tzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRzdHViR2xvYmFsKG5hbWUsIHZhbHVlKSB7XG5cdFx0XHRpZiAoIV9zdHVic0dsb2JhbC5oYXMobmFtZSkpIF9zdHVic0dsb2JhbC5zZXQobmFtZSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihnbG9iYWxUaGlzLCBuYW1lKSk7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsVGhpcywgbmFtZSwge1xuXHRcdFx0XHR2YWx1ZSxcblx0XHRcdFx0d3JpdGFibGU6IHRydWUsXG5cdFx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZVxuXHRcdFx0fSk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRzdHViRW52KG5hbWUsIHZhbHVlKSB7XG5cdFx0XHRjb25zdCBlbnYgPSBzdGF0ZSgpLm1ldGFFbnY7XG5cdFx0XHRpZiAoIV9zdHVic0Vudi5oYXMobmFtZSkpIF9zdHVic0Vudi5zZXQobmFtZSwgZW52W25hbWVdKTtcblx0XHRcdGlmIChfZW52Qm9vbGVhbnMuaW5jbHVkZXMobmFtZSkpIGVudltuYW1lXSA9IHZhbHVlID8gXCIxXCIgOiBcIlwiO1xuXHRcdFx0ZWxzZSBpZiAodmFsdWUgPT09IHZvaWQgMCkgZGVsZXRlIGVudltuYW1lXTtcblx0XHRcdGVsc2UgZW52W25hbWVdID0gU3RyaW5nKHZhbHVlKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdHVuc3R1YkFsbEdsb2JhbHMoKSB7XG5cdFx0XHRfc3R1YnNHbG9iYWwuZm9yRWFjaCgob3JpZ2luYWwsIG5hbWUpID0+IHtcblx0XHRcdFx0aWYgKCFvcmlnaW5hbCkgUmVmbGVjdC5kZWxldGVQcm9wZXJ0eShnbG9iYWxUaGlzLCBuYW1lKTtcblx0XHRcdFx0ZWxzZSBPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsVGhpcywgbmFtZSwgb3JpZ2luYWwpO1xuXHRcdFx0fSk7XG5cdFx0XHRfc3R1YnNHbG9iYWwuY2xlYXIoKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdHVuc3R1YkFsbEVudnMoKSB7XG5cdFx0XHRjb25zdCBlbnYgPSBzdGF0ZSgpLm1ldGFFbnY7XG5cdFx0XHRfc3R1YnNFbnYuZm9yRWFjaCgob3JpZ2luYWwsIG5hbWUpID0+IHtcblx0XHRcdFx0aWYgKG9yaWdpbmFsID09PSB2b2lkIDApIGRlbGV0ZSBlbnZbbmFtZV07XG5cdFx0XHRcdGVsc2UgZW52W25hbWVdID0gb3JpZ2luYWw7XG5cdFx0XHR9KTtcblx0XHRcdF9zdHVic0Vudi5jbGVhcigpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0cmVzZXRNb2R1bGVzKCkge1xuXHRcdFx0cmVzZXRNb2R1bGVzKHN0YXRlKCkuZXZhbHVhdGVkTW9kdWxlcyk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRhc3luYyBkeW5hbWljSW1wb3J0U2V0dGxlZCgpIHtcblx0XHRcdHJldHVybiB3YWl0Rm9ySW1wb3J0c1RvUmVzb2x2ZSgpO1xuXHRcdH0sXG5cdFx0c2V0Q29uZmlnKGNvbmZpZykge1xuXHRcdFx0aWYgKCFfY29uZmlnKSBfY29uZmlnID0geyAuLi5zdGF0ZSgpLmNvbmZpZyB9O1xuXHRcdFx0T2JqZWN0LmFzc2lnbihzdGF0ZSgpLmNvbmZpZywgY29uZmlnKTtcblx0XHR9LFxuXHRcdHJlc2V0Q29uZmlnKCkge1xuXHRcdFx0aWYgKF9jb25maWcpIE9iamVjdC5hc3NpZ24oc3RhdGUoKS5jb25maWcsIF9jb25maWcpO1xuXHRcdH1cblx0fTtcblx0cmV0dXJuIHV0aWxzO1xufVxuY29uc3Qgdml0ZXN0ID0gY3JlYXRlVml0ZXN0KCk7XG5jb25zdCB2aSA9IHZpdGVzdDtcbmZ1bmN0aW9uIF9tb2NrZXIoKSB7XG5cdC8vIEB0cy1leHBlY3QtZXJyb3IgaW5qZWN0ZWQgYnkgdml0ZS1uaWRlXG5cdHJldHVybiB0eXBlb2YgX192aXRlc3RfbW9ja2VyX18gIT09IFwidW5kZWZpbmVkXCIgPyBfX3ZpdGVzdF9tb2NrZXJfXyA6IG5ldyBQcm94eSh7fSwgeyBnZXQoXywgbmFtZSkge1xuXHRcdHRocm93IG5ldyBFcnJvcihgVml0ZXN0IG1vY2tlciB3YXMgbm90IGluaXRpYWxpemVkIGluIHRoaXMgZW52aXJvbm1lbnQuIHZpLiR7U3RyaW5nKG5hbWUpfSgpIGlzIGZvcmJpZGRlbi5gKTtcblx0fSB9KTtcbn1cbmZ1bmN0aW9uIGdldEltcG9ydGVyKG5hbWUpIHtcblx0Y29uc3Qgc3RhY2tBcnJheSA9IGNyZWF0ZVNpbXBsZVN0YWNrVHJhY2UoeyBzdGFja1RyYWNlTGltaXQ6IDUgfSkuc3BsaXQoXCJcXG5cIik7XG5cdHJldHVybiBwYXJzZVNpbmdsZVN0YWNrKHN0YWNrQXJyYXlbc3RhY2tBcnJheS5maW5kTGFzdEluZGV4KChzdGFjaykgPT4ge1xuXHRcdHJldHVybiBzdGFjay5pbmNsdWRlcyhgIGF0IE9iamVjdC4ke25hbWV9YCkgfHwgc3RhY2suaW5jbHVkZXMoYCR7bmFtZX1AYCkgfHwgc3RhY2suaW5jbHVkZXMoYCBhdCAke25hbWV9IChgKTtcblx0fSkgKyAxXSk/LmZpbGUgfHwgXCJcIjtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQmVuY2htYXJrUmVzdWx0KG5hbWUpIHtcblx0cmV0dXJuIHtcblx0XHRuYW1lLFxuXHRcdHJhbms6IDAsXG5cdFx0cm1lOiAwLFxuXHRcdHNhbXBsZXM6IFtdXG5cdH07XG59XG5jb25zdCBiZW5jaG1hcmtUYXNrcyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpO1xuYXN5bmMgZnVuY3Rpb24gcnVuQmVuY2htYXJrU3VpdGUoc3VpdGUsIHJ1bm5lcikge1xuXHRjb25zdCB7IFRhc2ssIEJlbmNoIH0gPSBhd2FpdCBydW5uZXIuaW1wb3J0VGlueWJlbmNoKCk7XG5cdGNvbnN0IHN0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KCk7XG5cdGNvbnN0IGJlbmNobWFya0dyb3VwID0gW107XG5cdGNvbnN0IGJlbmNobWFya1N1aXRlR3JvdXAgPSBbXTtcblx0Zm9yIChjb25zdCB0YXNrIG9mIHN1aXRlLnRhc2tzKSB7XG5cdFx0aWYgKHRhc2subW9kZSAhPT0gXCJydW5cIiAmJiB0YXNrLm1vZGUgIT09IFwicXVldWVkXCIpIGNvbnRpbnVlO1xuXHRcdGlmICh0YXNrLm1ldGE/LmJlbmNobWFyaykgYmVuY2htYXJrR3JvdXAucHVzaCh0YXNrKTtcblx0XHRlbHNlIGlmICh0YXNrLnR5cGUgPT09IFwic3VpdGVcIikgYmVuY2htYXJrU3VpdGVHcm91cC5wdXNoKHRhc2spO1xuXHR9XG5cdC8vIHJ1biBzdWIgc3VpdGVzIHNlcXVlbnRpYWxseVxuXHRmb3IgKGNvbnN0IHN1YlN1aXRlIG9mIGJlbmNobWFya1N1aXRlR3JvdXApIGF3YWl0IHJ1bkJlbmNobWFya1N1aXRlKHN1YlN1aXRlLCBydW5uZXIpO1xuXHRpZiAoYmVuY2htYXJrR3JvdXAubGVuZ3RoKSB7XG5cdFx0Y29uc3QgZGVmZXIgPSBjcmVhdGVEZWZlcigpO1xuXHRcdHN1aXRlLnJlc3VsdCA9IHtcblx0XHRcdHN0YXRlOiBcInJ1blwiLFxuXHRcdFx0c3RhcnRUaW1lOiBzdGFydCxcblx0XHRcdGJlbmNobWFyazogY3JlYXRlQmVuY2htYXJrUmVzdWx0KHN1aXRlLm5hbWUpXG5cdFx0fTtcblx0XHR1cGRhdGVUYXNrJDEoXCJzdWl0ZS1wcmVwYXJlXCIsIHN1aXRlKTtcblx0XHRjb25zdCBhZGRCZW5jaFRhc2tMaXN0ZW5lciA9ICh0YXNrLCBiZW5jaG1hcmspID0+IHtcblx0XHRcdHRhc2suYWRkRXZlbnRMaXN0ZW5lcihcImNvbXBsZXRlXCIsIChlKSA9PiB7XG5cdFx0XHRcdGNvbnN0IHRhc2tSZXMgPSBlLnRhc2sucmVzdWx0O1xuXHRcdFx0XHRjb25zdCByZXN1bHQgPSBiZW5jaG1hcmsucmVzdWx0LmJlbmNobWFyaztcblx0XHRcdFx0YmVuY2htYXJrLnJlc3VsdC5zdGF0ZSA9IFwicGFzc1wiO1xuXHRcdFx0XHRPYmplY3QuYXNzaWduKHJlc3VsdCwgdGFza1Jlcyk7XG5cdFx0XHRcdC8vIGNvbXB1dGUgZXh0cmEgc3RhdHMgYW5kIGZyZWUgcmF3IHNhbXBsZXMgYXMgZWFybHkgYXMgcG9zc2libGVcblx0XHRcdFx0Y29uc3Qgc2FtcGxlcyA9IHJlc3VsdC5zYW1wbGVzO1xuXHRcdFx0XHRyZXN1bHQuc2FtcGxlQ291bnQgPSBzYW1wbGVzLmxlbmd0aDtcblx0XHRcdFx0cmVzdWx0Lm1lZGlhbiA9IHNhbXBsZXMubGVuZ3RoICUgMiA/IHNhbXBsZXNbTWF0aC5mbG9vcihzYW1wbGVzLmxlbmd0aCAvIDIpXSA6IChzYW1wbGVzW3NhbXBsZXMubGVuZ3RoIC8gMl0gKyBzYW1wbGVzW3NhbXBsZXMubGVuZ3RoIC8gMiAtIDFdKSAvIDI7XG5cdFx0XHRcdGlmICghcnVubmVyLmNvbmZpZy5iZW5jaG1hcms/LmluY2x1ZGVTYW1wbGVzKSByZXN1bHQuc2FtcGxlcy5sZW5ndGggPSAwO1xuXHRcdFx0XHR1cGRhdGVUYXNrJDEoXCJ0ZXN0LWZpbmlzaGVkXCIsIGJlbmNobWFyayk7XG5cdFx0XHR9LCB7IG9uY2U6IHRydWUgfSk7XG5cdFx0XHR0YXNrLmFkZEV2ZW50TGlzdGVuZXIoXCJlcnJvclwiLCAoZSkgPT4ge1xuXHRcdFx0XHRjb25zdCB0YXNrID0gZS50YXNrO1xuXHRcdFx0XHRkZWZlci5yZWplY3QoYmVuY2htYXJrID8gdGFzay5yZXN1bHQuZXJyb3IgOiBlKTtcblx0XHRcdH0sIHsgb25jZTogdHJ1ZSB9KTtcblx0XHR9O1xuXHRcdGJlbmNobWFya0dyb3VwLmZvckVhY2goKGJlbmNobWFyaykgPT4ge1xuXHRcdFx0Y29uc3QgYmVuY2htYXJrSW5zdGFuY2UgPSBuZXcgQmVuY2goZ2V0QmVuY2hPcHRpb25zKGJlbmNobWFyaykpO1xuXHRcdFx0Y29uc3QgYmVuY2htYXJrRm4gPSBnZXRCZW5jaEZuKGJlbmNobWFyayk7XG5cdFx0XHRiZW5jaG1hcmsucmVzdWx0ID0ge1xuXHRcdFx0XHRzdGF0ZTogXCJydW5cIixcblx0XHRcdFx0c3RhcnRUaW1lOiBzdGFydCxcblx0XHRcdFx0YmVuY2htYXJrOiBjcmVhdGVCZW5jaG1hcmtSZXN1bHQoYmVuY2htYXJrLm5hbWUpXG5cdFx0XHR9O1xuXHRcdFx0Y29uc3QgdGFzayA9IG5ldyBUYXNrKGJlbmNobWFya0luc3RhbmNlLCBiZW5jaG1hcmsubmFtZSwgYmVuY2htYXJrRm4pO1xuXHRcdFx0YmVuY2htYXJrVGFza3Muc2V0KGJlbmNobWFyaywgdGFzayk7XG5cdFx0XHRhZGRCZW5jaFRhc2tMaXN0ZW5lcih0YXNrLCBiZW5jaG1hcmspO1xuXHRcdH0pO1xuXHRcdGNvbnN0IHsgc2V0VGltZW91dCB9ID0gZ2V0U2FmZVRpbWVycygpO1xuXHRcdGNvbnN0IHRhc2tzID0gW107XG5cdFx0Zm9yIChjb25zdCBiZW5jaG1hcmsgb2YgYmVuY2htYXJrR3JvdXApIHtcblx0XHRcdGNvbnN0IHRhc2sgPSBiZW5jaG1hcmtUYXNrcy5nZXQoYmVuY2htYXJrKTtcblx0XHRcdHVwZGF0ZVRhc2skMShcInRlc3QtcHJlcGFyZVwiLCBiZW5jaG1hcmspO1xuXHRcdFx0YXdhaXQgdGFzay53YXJtdXAoKTtcblx0XHRcdHRhc2tzLnB1c2goW2F3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KGFzeW5jICgpID0+IHtcblx0XHRcdFx0cmVzb2x2ZShhd2FpdCB0YXNrLnJ1bigpKTtcblx0XHRcdH0pKSwgYmVuY2htYXJrXSk7XG5cdFx0fVxuXHRcdHN1aXRlLnJlc3VsdC5kdXJhdGlvbiA9IHBlcmZvcm1hbmNlLm5vdygpIC0gc3RhcnQ7XG5cdFx0c3VpdGUucmVzdWx0LnN0YXRlID0gXCJwYXNzXCI7XG5cdFx0dXBkYXRlVGFzayQxKFwic3VpdGUtZmluaXNoZWRcIiwgc3VpdGUpO1xuXHRcdGRlZmVyLnJlc29sdmUobnVsbCk7XG5cdFx0YXdhaXQgZGVmZXI7XG5cdH1cblx0ZnVuY3Rpb24gdXBkYXRlVGFzayQxKGV2ZW50LCB0YXNrKSB7XG5cdFx0dXBkYXRlVGFzayhldmVudCwgdGFzaywgcnVubmVyKTtcblx0fVxufVxuY2xhc3MgTm9kZUJlbmNobWFya1J1bm5lciB7XG5cdG1vZHVsZVJ1bm5lcjtcblx0Y29uc3RydWN0b3IoY29uZmlnKSB7XG5cdFx0dGhpcy5jb25maWcgPSBjb25maWc7XG5cdH1cblx0YXN5bmMgaW1wb3J0VGlueWJlbmNoKCkge1xuXHRcdHJldHVybiBhd2FpdCBpbXBvcnQoJ3RpbnliZW5jaCcpO1xuXHR9XG5cdGltcG9ydEZpbGUoZmlsZXBhdGgsIHNvdXJjZSkge1xuXHRcdGlmIChzb3VyY2UgPT09IFwic2V0dXBcIikge1xuXHRcdFx0Y29uc3QgbW9kdWxlTm9kZSA9IGdldFdvcmtlclN0YXRlKCkuZXZhbHVhdGVkTW9kdWxlcy5nZXRNb2R1bGVCeUlkKGZpbGVwYXRoKTtcblx0XHRcdGlmIChtb2R1bGVOb2RlKSBnZXRXb3JrZXJTdGF0ZSgpLmV2YWx1YXRlZE1vZHVsZXMuaW52YWxpZGF0ZU1vZHVsZShtb2R1bGVOb2RlKTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMubW9kdWxlUnVubmVyLmltcG9ydChmaWxlcGF0aCk7XG5cdH1cblx0YXN5bmMgcnVuU3VpdGUoc3VpdGUpIHtcblx0XHRhd2FpdCBydW5CZW5jaG1hcmtTdWl0ZShzdWl0ZSwgdGhpcyk7XG5cdH1cblx0YXN5bmMgcnVuVGFzaygpIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoXCJgdGVzdCgpYCBhbmQgYGl0KClgIGlzIG9ubHkgYXZhaWxhYmxlIGluIHRlc3QgbW9kZS5cIik7XG5cdH1cbn1cblxuY2xhc3MgVGVzdFJ1bm5lciB7XG5cdHNuYXBzaG90Q2xpZW50ID0gZ2V0U25hcHNob3RDbGllbnQoKTtcblx0d29ya2VyU3RhdGUgPSBnZXRXb3JrZXJTdGF0ZSgpO1xuXHRtb2R1bGVSdW5uZXI7XG5cdGNhbmNlbFJ1biA9IGZhbHNlO1xuXHRhc3NlcnRpb25zRXJyb3JzID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrTWFwKCk7XG5cdHBvb2wgPSB0aGlzLndvcmtlclN0YXRlLmN0eC5wb29sO1xuXHRfb3RlbDtcblx0dml0ZUVudmlyb25tZW50O1xuXHR2aXRlTW9kdWxlUnVubmVyO1xuXHRjb25zdHJ1Y3Rvcihjb25maWcpIHtcblx0XHR0aGlzLmNvbmZpZyA9IGNvbmZpZztcblx0XHRjb25zdCBlbnZpcm9ubWVudCA9IHRoaXMud29ya2VyU3RhdGUuZW52aXJvbm1lbnQ7XG5cdFx0dGhpcy52aXRlRW52aXJvbm1lbnQgPSBlbnZpcm9ubWVudC52aXRlRW52aXJvbm1lbnQgfHwgZW52aXJvbm1lbnQubmFtZTtcblx0XHR0aGlzLnZpdGVNb2R1bGVSdW5uZXIgPSBjb25maWcuZXhwZXJpbWVudGFsLnZpdGVNb2R1bGVSdW5uZXI7XG5cdH1cblx0aW1wb3J0RmlsZShmaWxlcGF0aCwgc291cmNlKSB7XG5cdFx0aWYgKHNvdXJjZSA9PT0gXCJzZXR1cFwiKSB7XG5cdFx0XHRjb25zdCBtb2R1bGVOb2RlID0gdGhpcy53b3JrZXJTdGF0ZS5ldmFsdWF0ZWRNb2R1bGVzLmdldE1vZHVsZUJ5SWQoZmlsZXBhdGgpO1xuXHRcdFx0aWYgKG1vZHVsZU5vZGUpIHRoaXMud29ya2VyU3RhdGUuZXZhbHVhdGVkTW9kdWxlcy5pbnZhbGlkYXRlTW9kdWxlKG1vZHVsZU5vZGUpO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5fb3RlbC4kKGB2aXRlc3QubW9kdWxlLmltcG9ydF8ke3NvdXJjZSA9PT0gXCJzZXR1cFwiID8gXCJzZXR1cFwiIDogXCJzcGVjXCJ9YCwgeyBhdHRyaWJ1dGVzOiB7IFwiY29kZS5maWxlLnBhdGhcIjogZmlsZXBhdGggfSB9LCAoKSA9PiB7XG5cdFx0XHRpZiAoIXRoaXMudml0ZU1vZHVsZVJ1bm5lcikgZmlsZXBhdGggPSBgJHtmaWxlcGF0aH0/dml0ZXN0PSR7RGF0ZS5ub3coKX1gO1xuXHRcdFx0cmV0dXJuIHRoaXMubW9kdWxlUnVubmVyLmltcG9ydChmaWxlcGF0aCk7XG5cdFx0fSk7XG5cdH1cblx0b25Db2xsZWN0U3RhcnQoZmlsZSkge1xuXHRcdHRoaXMud29ya2VyU3RhdGUuY3VycmVudCA9IGZpbGU7XG5cdH1cblx0b25DbGVhbnVwV29ya2VyQ29udGV4dChsaXN0ZW5lcikge1xuXHRcdHRoaXMud29ya2VyU3RhdGUub25DbGVhbnVwKGxpc3RlbmVyKTtcblx0fVxuXHRvbkFmdGVyUnVuRmlsZXMoKSB7XG5cdFx0dGhpcy5zbmFwc2hvdENsaWVudC5jbGVhcigpO1xuXHRcdHRoaXMud29ya2VyU3RhdGUuY3VycmVudCA9IHZvaWQgMDtcblx0fVxuXHRhc3luYyBvbkFmdGVyUnVuU3VpdGUoc3VpdGUpIHtcblx0XHRpZiAodGhpcy5jb25maWcubG9nSGVhcFVzYWdlICYmIHR5cGVvZiBwcm9jZXNzICE9PSBcInVuZGVmaW5lZFwiKSBzdWl0ZS5yZXN1bHQuaGVhcCA9IHByb2Nlc3MubWVtb3J5VXNhZ2UoKS5oZWFwVXNlZDtcblx0XHRpZiAoc3VpdGUubW9kZSAhPT0gXCJza2lwXCIgJiYgXCJmaWxlcGF0aFwiIGluIHN1aXRlKSB7XG5cdFx0XHQvLyBtYXJrIHNuYXBzaG90cyBpbiBza2lwcGVkIHRlc3RzIGFzIG5vdCBvYnNvbGV0ZVxuXHRcdFx0Zm9yIChjb25zdCB0ZXN0IG9mIGdldFRlc3RzKHN1aXRlKSkgaWYgKHRlc3QubW9kZSA9PT0gXCJza2lwXCIpIHtcblx0XHRcdFx0Y29uc3QgbmFtZSA9IGdldE5hbWVzKHRlc3QpLnNsaWNlKDEpLmpvaW4oXCIgPiBcIik7XG5cdFx0XHRcdHRoaXMuc25hcHNob3RDbGllbnQuc2tpcFRlc3Qoc3VpdGUuZmlsZS5maWxlcGF0aCwgbmFtZSk7XG5cdFx0XHR9XG5cdFx0XHRjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnNuYXBzaG90Q2xpZW50LmZpbmlzaChzdWl0ZS5maWxlLmZpbGVwYXRoKTtcblx0XHRcdGlmICh0aGlzLndvcmtlclN0YXRlLmNvbmZpZy5zbmFwc2hvdE9wdGlvbnMudXBkYXRlU25hcHNob3QgPT09IFwibm9uZVwiICYmIHJlc3VsdC51bmNoZWNrZWQpIHtcblx0XHRcdFx0bGV0IG1lc3NhZ2UgPSBgT2Jzb2xldGUgc25hcHNob3RzIGZvdW5kIHdoZW4gbm8gc25hcHNob3QgdXBkYXRlIGlzIGV4cGVjdGVkLlxcbmA7XG5cdFx0XHRcdGZvciAoY29uc3Qga2V5IG9mIHJlc3VsdC51bmNoZWNrZWRLZXlzKSBtZXNzYWdlICs9IGDCtyAke2tleX1cXG5gO1xuXHRcdFx0XHRzdWl0ZS5yZXN1bHQuZXJyb3JzID8/PSBbXTtcblx0XHRcdFx0c3VpdGUucmVzdWx0LmVycm9ycy5wdXNoKHByb2Nlc3NFcnJvcihuZXcgRXJyb3IobWVzc2FnZSkpKTtcblx0XHRcdFx0c3VpdGUucmVzdWx0LnN0YXRlID0gXCJmYWlsXCI7XG5cdFx0XHR9XG5cdFx0XHRhd2FpdCBycGMoKS5zbmFwc2hvdFNhdmVkKHJlc3VsdCk7XG5cdFx0fVxuXHRcdHRoaXMud29ya2VyU3RhdGUuY3VycmVudCA9IHN1aXRlLnN1aXRlIHx8IHN1aXRlLmZpbGU7XG5cdH1cblx0b25BZnRlclJ1blRhc2sodGVzdCkge1xuXHRcdGlmICh0aGlzLmNvbmZpZy5sb2dIZWFwVXNhZ2UgJiYgdHlwZW9mIHByb2Nlc3MgIT09IFwidW5kZWZpbmVkXCIpIHRlc3QucmVzdWx0LmhlYXAgPSBwcm9jZXNzLm1lbW9yeVVzYWdlKCkuaGVhcFVzZWQ7XG5cdFx0dGhpcy53b3JrZXJTdGF0ZS5jdXJyZW50ID0gdGVzdC5zdWl0ZSB8fCB0ZXN0LmZpbGU7XG5cdH1cblx0Y2FuY2VsKF9yZWFzb24pIHtcblx0XHR0aGlzLmNhbmNlbFJ1biA9IHRydWU7XG5cdH1cblx0aW5qZWN0VmFsdWUoa2V5KSB7XG5cdFx0Ly8gaW5qZWN0IGhhcyBhIHZlcnkgbGltaXRpbmcgdHlwZSBjb250cm9sbGVkIGJ5IFByb3ZpZGVkQ29udGV4dFxuXHRcdC8vIHNvbWUgdGVzdHMgb3ZlcnJpZGUgaXQgd2hpY2ggY2F1c2VzIHRoZSBidWlsZCB0byBmYWlsXG5cdFx0cmV0dXJuIGluamVjdChrZXkpO1xuXHR9XG5cdGFzeW5jIG9uQmVmb3JlUnVuVGFzayh0ZXN0KSB7XG5cdFx0aWYgKHRoaXMuY2FuY2VsUnVuKSB0ZXN0Lm1vZGUgPSBcInNraXBcIjtcblx0XHRpZiAodGVzdC5tb2RlICE9PSBcInJ1blwiICYmIHRlc3QubW9kZSAhPT0gXCJxdWV1ZWRcIikgcmV0dXJuO1xuXHRcdHRoaXMud29ya2VyU3RhdGUuY3VycmVudCA9IHRlc3Q7XG5cdH1cblx0YXN5bmMgb25CZWZvcmVSdW5TdWl0ZShzdWl0ZSkge1xuXHRcdGlmICh0aGlzLmNhbmNlbFJ1bikgc3VpdGUubW9kZSA9IFwic2tpcFwiO1xuXHRcdC8vIGluaXRpYWxpemUgc25hcHNob3Qgc3RhdGUgYmVmb3JlIHJ1bm5pbmcgZmlsZSBzdWl0ZVxuXHRcdGlmIChzdWl0ZS5tb2RlICE9PSBcInNraXBcIiAmJiBcImZpbGVwYXRoXCIgaW4gc3VpdGUpIGF3YWl0IHRoaXMuc25hcHNob3RDbGllbnQuc2V0dXAoc3VpdGUuZmlsZS5maWxlcGF0aCwgdGhpcy53b3JrZXJTdGF0ZS5jb25maWcuc25hcHNob3RPcHRpb25zKTtcblx0XHR0aGlzLndvcmtlclN0YXRlLmN1cnJlbnQgPSBzdWl0ZTtcblx0fVxuXHRvbkJlZm9yZVRyeVRhc2sodGVzdCkge1xuXHRcdGNsZWFyTW9kdWxlTW9ja3ModGhpcy5jb25maWcpO1xuXHRcdHRoaXMuc25hcHNob3RDbGllbnQuY2xlYXJUZXN0KHRlc3QuZmlsZS5maWxlcGF0aCwgdGVzdC5pZCk7XG5cdFx0c2V0U3RhdGUoe1xuXHRcdFx0YXNzZXJ0aW9uQ2FsbHM6IDAsXG5cdFx0XHRpc0V4cGVjdGluZ0Fzc2VydGlvbnM6IGZhbHNlLFxuXHRcdFx0aXNFeHBlY3RpbmdBc3NlcnRpb25zRXJyb3I6IG51bGwsXG5cdFx0XHRleHBlY3RlZEFzc2VydGlvbnNOdW1iZXI6IG51bGwsXG5cdFx0XHRleHBlY3RlZEFzc2VydGlvbnNOdW1iZXJFcnJvckdlbjogbnVsbCxcblx0XHRcdGN1cnJlbnRUZXN0TmFtZTogZ2V0VGVzdE5hbWUodGVzdCksXG5cdFx0XHRzbmFwc2hvdFN0YXRlOiB0aGlzLnNuYXBzaG90Q2xpZW50LmdldFNuYXBzaG90U3RhdGUodGVzdC5maWxlLmZpbGVwYXRoKVxuXHRcdH0sIGdsb2JhbFRoaXNbR0xPQkFMX0VYUEVDVF0pO1xuXHR9XG5cdG9uQWZ0ZXJUcnlUYXNrKHRlc3QpIHtcblx0XHRjb25zdCB7IGFzc2VydGlvbkNhbGxzLCBleHBlY3RlZEFzc2VydGlvbnNOdW1iZXIsIGV4cGVjdGVkQXNzZXJ0aW9uc051bWJlckVycm9yR2VuLCBpc0V4cGVjdGluZ0Fzc2VydGlvbnMsIGlzRXhwZWN0aW5nQXNzZXJ0aW9uc0Vycm9yIH0gPSB0ZXN0LmNvbnRleHQuX2xvY2FsID8gdGVzdC5jb250ZXh0LmV4cGVjdC5nZXRTdGF0ZSgpIDogZ2V0U3RhdGUoZ2xvYmFsVGhpc1tHTE9CQUxfRVhQRUNUXSk7XG5cdFx0aWYgKGV4cGVjdGVkQXNzZXJ0aW9uc051bWJlciAhPT0gbnVsbCAmJiBhc3NlcnRpb25DYWxscyAhPT0gZXhwZWN0ZWRBc3NlcnRpb25zTnVtYmVyKSB0aHJvdyBleHBlY3RlZEFzc2VydGlvbnNOdW1iZXJFcnJvckdlbigpO1xuXHRcdGlmIChpc0V4cGVjdGluZ0Fzc2VydGlvbnMgPT09IHRydWUgJiYgYXNzZXJ0aW9uQ2FsbHMgPT09IDApIHRocm93IGlzRXhwZWN0aW5nQXNzZXJ0aW9uc0Vycm9yO1xuXHRcdGlmICh0aGlzLmNvbmZpZy5leHBlY3QucmVxdWlyZUFzc2VydGlvbnMgJiYgYXNzZXJ0aW9uQ2FsbHMgPT09IDApIHRocm93IHRoaXMuYXNzZXJ0aW9uc0Vycm9ycy5nZXQodGVzdCk7XG5cdH1cblx0ZXh0ZW5kVGFza0NvbnRleHQoY29udGV4dCkge1xuXHRcdC8vIGNyZWF0ZSBlcnJvciBkdXJpbmcgdGhlIHRlc3QgaW5pdGlhbGl6YXRpb24gc28gd2UgaGF2ZSBhIG5pY2Ugc3RhY2sgdHJhY2Vcblx0XHRpZiAodGhpcy5jb25maWcuZXhwZWN0LnJlcXVpcmVBc3NlcnRpb25zKSB0aGlzLmFzc2VydGlvbnNFcnJvcnMuc2V0KGNvbnRleHQudGFzaywgLyogQF9fUFVSRV9fICovIG5ldyBFcnJvcihcImV4cGVjdGVkIGFueSBudW1iZXIgb2YgYXNzZXJ0aW9uLCBidXQgZ290IG5vbmVcIikpO1xuXHRcdGxldCBfZXhwZWN0O1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb250ZXh0LCBcImV4cGVjdFwiLCB7IGdldCgpIHtcblx0XHRcdGlmICghX2V4cGVjdCkgX2V4cGVjdCA9IGNyZWF0ZUV4cGVjdChjb250ZXh0LnRhc2spO1xuXHRcdFx0cmV0dXJuIF9leHBlY3Q7XG5cdFx0fSB9KTtcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoY29udGV4dCwgXCJfbG9jYWxcIiwgeyBnZXQoKSB7XG5cdFx0XHRyZXR1cm4gX2V4cGVjdCAhPSBudWxsO1xuXHRcdH0gfSk7XG5cdFx0cmV0dXJuIGNvbnRleHQ7XG5cdH1cblx0Z2V0SW1wb3J0RHVyYXRpb25zKCkge1xuXHRcdGNvbnN0IHsgbGltaXQgfSA9IHRoaXMuY29uZmlnLmV4cGVyaW1lbnRhbC5pbXBvcnREdXJhdGlvbnM7XG5cdFx0Ly8gc2tpcCBzb3J0aW5nIGlmIGxpbWl0IGlzIDBcblx0XHRpZiAobGltaXQgPT09IDApIHJldHVybiB7fTtcblx0XHQvLyBTb3J0IGJ5IGR1cmF0aW9uIGRlc2NlbmRpbmcgYW5kIGtlZXAgdG9wIGVudHJpZXNcblx0XHRjb25zdCBzb3J0ZWRFbnRyaWVzID0gWy4uLnRoaXMud29ya2VyU3RhdGUubW9kdWxlRXhlY3V0aW9uSW5mbz8uZW50cmllcygpIHx8IFtdXS5zb3J0KChbLCBhXSwgWywgYl0pID0+IGIuZHVyYXRpb24gLSBhLmR1cmF0aW9uKS5zbGljZSgwLCBsaW1pdCk7XG5cdFx0Y29uc3QgaW1wb3J0RHVyYXRpb25zID0ge307XG5cdFx0Zm9yIChjb25zdCBbZmlsZXBhdGgsIHsgZHVyYXRpb24sIHNlbGZUaW1lLCBleHRlcm5hbCwgaW1wb3J0ZXIgfV0gb2Ygc29ydGVkRW50cmllcykgaW1wb3J0RHVyYXRpb25zW25vcm1hbGl6ZShmaWxlcGF0aCldID0ge1xuXHRcdFx0c2VsZlRpbWUsXG5cdFx0XHR0b3RhbFRpbWU6IGR1cmF0aW9uLFxuXHRcdFx0ZXh0ZXJuYWwsXG5cdFx0XHRpbXBvcnRlclxuXHRcdH07XG5cdFx0cmV0dXJuIGltcG9ydER1cmF0aW9ucztcblx0fVxuXHR0cmFjZSA9IChuYW1lLCBhdHRyaWJ1dGVzLCBjYikgPT4ge1xuXHRcdGNvbnN0IG9wdGlvbnMgPSB0eXBlb2YgYXR0cmlidXRlcyA9PT0gXCJvYmplY3RcIiA/IHsgYXR0cmlidXRlcyB9IDoge307XG5cdFx0cmV0dXJuIHRoaXMuX290ZWwuJChgdml0ZXN0LnRlc3QucnVubmVyLiR7bmFtZX1gLCBvcHRpb25zLCBjYiB8fCBhdHRyaWJ1dGVzKTtcblx0fTtcblx0X19zZXRUcmFjZXModHJhY2VzKSB7XG5cdFx0dGhpcy5fb3RlbCA9IHRyYWNlcztcblx0fVxuXHRzdGF0aWMgY3JlYXRlVGFza0NvbGxlY3RvciA9IGNyZWF0ZVRhc2tDb2xsZWN0b3I7XG5cdHN0YXRpYyBnZXRDdXJyZW50U3VpdGUgPSBnZXRDdXJyZW50U3VpdGU7XG5cdHN0YXRpYyBnZXRDdXJyZW50VGVzdCA9IGdldEN1cnJlbnRUZXN0O1xuXHRzdGF0aWMgY3JlYXRlQ2hhaW5hYmxlID0gY3JlYXRlQ2hhaW5hYmxlO1xuXHRzdGF0aWMgZ2V0U3VpdGVIb29rcyA9IGdldEhvb2tzO1xuXHRzdGF0aWMgZ2V0VGVzdEZuID0gZ2V0Rm47XG5cdHN0YXRpYyBzZXRTdWl0ZUhvb2tzID0gZ2V0SG9va3M7XG5cdHN0YXRpYyBzZXRUZXN0Rm4gPSBnZXRGbjtcblx0c3RhdGljIG1hdGNoZXNUYWdzID0gbWF0Y2hlc1RhZ3M7XG5cdC8qKlxuXHQqIEBkZXByZWNhdGVkXG5cdCovXG5cdHN0YXRpYyBnZXRCZW5jaEZuID0gZ2V0QmVuY2hGbjtcblx0LyoqXG5cdCogQGRlcHJlY2F0ZWRcblx0Ki9cblx0c3RhdGljIGdldEJlbmNoT3B0aW9ucyA9IGdldEJlbmNoT3B0aW9ucztcbn1cbmZ1bmN0aW9uIGNsZWFyTW9kdWxlTW9ja3MoY29uZmlnKSB7XG5cdGNvbnN0IHsgY2xlYXJNb2NrcywgbW9ja1Jlc2V0LCByZXN0b3JlTW9ja3MsIHVuc3R1YkVudnMsIHVuc3R1Ykdsb2JhbHMgfSA9IGNvbmZpZztcblx0aWYgKHJlc3RvcmVNb2NrcykgdmkucmVzdG9yZUFsbE1vY2tzKCk7XG5cdGlmIChtb2NrUmVzZXQpIHZpLnJlc2V0QWxsTW9ja3MoKTtcblx0aWYgKGNsZWFyTW9ja3MpIHZpLmNsZWFyQWxsTW9ja3MoKTtcblx0aWYgKHVuc3R1YkVudnMpIHZpLnVuc3R1YkFsbEVudnMoKTtcblx0aWYgKHVuc3R1Ykdsb2JhbHMpIHZpLnVuc3R1YkFsbEdsb2JhbHMoKTtcbn1cblxuZXhwb3J0IHsgTm9kZUJlbmNobWFya1J1bm5lciBhcyBOLCBUZXN0UnVubmVyIGFzIFQsIGFzc2VydCBhcyBhLCB2aXRlc3QgYXMgYiwgY3JlYXRlRXhwZWN0IGFzIGMsIGdsb2JhbEV4cGVjdCBhcyBnLCBpbmplY3QgYXMgaSwgc2hvdWxk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