@workflow/core 5.0.0-beta.39 → 5.0.0-beta.40

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 (95) hide show
  1. package/dist/classify-error.d.ts.map +1 -1
  2. package/dist/classify-error.js +5 -2
  3. package/dist/correlation-id.d.ts +109 -0
  4. package/dist/correlation-id.d.ts.map +1 -0
  5. package/dist/correlation-id.js +139 -0
  6. package/dist/describe-error.d.ts.map +1 -1
  7. package/dist/describe-error.js +14 -1
  8. package/dist/events-consumer.d.ts +1 -0
  9. package/dist/events-consumer.d.ts.map +1 -1
  10. package/dist/events-consumer.js +11 -3
  11. package/dist/private.d.ts +17 -1
  12. package/dist/private.d.ts.map +1 -1
  13. package/dist/private.js +1 -1
  14. package/dist/runtime/constants.d.ts +19 -0
  15. package/dist/runtime/constants.d.ts.map +1 -1
  16. package/dist/runtime/constants.js +30 -1
  17. package/dist/runtime/deployment-guard.d.ts +99 -0
  18. package/dist/runtime/deployment-guard.d.ts.map +1 -0
  19. package/dist/runtime/deployment-guard.js +154 -0
  20. package/dist/runtime/quickjs-assets.generated.d.ts +14 -0
  21. package/dist/runtime/quickjs-assets.generated.d.ts.map +1 -0
  22. package/dist/runtime/quickjs-assets.generated.js +30 -0
  23. package/dist/runtime/quickjs-entrypoint.d.ts +124 -0
  24. package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -0
  25. package/dist/runtime/quickjs-entrypoint.js +1429 -0
  26. package/dist/runtime/quickjs-runtime.d.ts +193 -0
  27. package/dist/runtime/quickjs-runtime.d.ts.map +1 -0
  28. package/dist/runtime/quickjs-runtime.js +1944 -0
  29. package/dist/runtime/run.d.ts +2 -0
  30. package/dist/runtime/run.d.ts.map +1 -1
  31. package/dist/runtime/run.js +9 -4
  32. package/dist/runtime/runs.d.ts +18 -1
  33. package/dist/runtime/runs.d.ts.map +1 -1
  34. package/dist/runtime/runs.js +96 -2
  35. package/dist/runtime/start.d.ts.map +1 -1
  36. package/dist/runtime/start.js +9 -1
  37. package/dist/runtime/suspension-handler.d.ts +7 -0
  38. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  39. package/dist/runtime/suspension-handler.js +29 -2
  40. package/dist/runtime/vm-mode.d.ts +44 -0
  41. package/dist/runtime/vm-mode.d.ts.map +1 -0
  42. package/dist/runtime/vm-mode.js +62 -0
  43. package/dist/runtime/vm-serde-bundle.generated.d.ts +14 -0
  44. package/dist/runtime/vm-serde-bundle.generated.d.ts.map +1 -0
  45. package/dist/runtime/vm-serde-bundle.generated.js +16 -0
  46. package/dist/runtime.d.ts +1 -1
  47. package/dist/runtime.d.ts.map +1 -1
  48. package/dist/runtime.js +484 -47
  49. package/dist/serialization/codec-devalue-vm.d.ts +9 -0
  50. package/dist/serialization/codec-devalue-vm.d.ts.map +1 -0
  51. package/dist/serialization/codec-devalue-vm.js +137 -0
  52. package/dist/serialization/reducers/class-vm.d.ts +20 -0
  53. package/dist/serialization/reducers/class-vm.d.ts.map +1 -0
  54. package/dist/serialization/reducers/class-vm.js +77 -0
  55. package/dist/serialization/reducers/common-vm.d.ts +15 -0
  56. package/dist/serialization/reducers/common-vm.d.ts.map +1 -0
  57. package/dist/serialization/reducers/common-vm.js +579 -0
  58. package/dist/serialization/reducers/common.d.ts.map +1 -1
  59. package/dist/serialization/reducers/common.js +28 -6
  60. package/dist/serialization/reducers/step-function-vm.d.ts +44 -0
  61. package/dist/serialization/reducers/step-function-vm.d.ts.map +1 -0
  62. package/dist/serialization/reducers/step-function-vm.js +97 -0
  63. package/dist/serialization/vm-bundle-entry.d.ts +12 -0
  64. package/dist/serialization/vm-bundle-entry.d.ts.map +1 -0
  65. package/dist/serialization/vm-bundle-entry.js +58 -0
  66. package/dist/serialization/workflow-vm.d.ts +24 -0
  67. package/dist/serialization/workflow-vm.d.ts.map +1 -0
  68. package/dist/serialization/workflow-vm.js +66 -0
  69. package/dist/serialization.d.ts +2 -1
  70. package/dist/serialization.d.ts.map +1 -1
  71. package/dist/serialization.js +26 -21
  72. package/dist/source-map.d.ts +20 -0
  73. package/dist/source-map.d.ts.map +1 -1
  74. package/dist/source-map.js +47 -1
  75. package/dist/step.d.ts.map +1 -1
  76. package/dist/step.js +7 -2
  77. package/dist/telemetry/semantic-conventions.d.ts +78 -0
  78. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  79. package/dist/telemetry/semantic-conventions.js +56 -1
  80. package/dist/telemetry.d.ts +5 -0
  81. package/dist/telemetry.d.ts.map +1 -1
  82. package/dist/telemetry.js +13 -13
  83. package/dist/version.d.ts +1 -1
  84. package/dist/version.js +2 -2
  85. package/dist/workflow/abort-controller.d.ts.map +1 -1
  86. package/dist/workflow/abort-controller.js +6 -4
  87. package/dist/workflow/attribute-dispatcher.js +2 -2
  88. package/dist/workflow/hook.js +2 -2
  89. package/dist/workflow/sleep.js +2 -2
  90. package/dist/workflow.d.ts +49 -2
  91. package/dist/workflow.d.ts.map +1 -1
  92. package/dist/workflow.js +723 -569
  93. package/docs/api-reference/create-hook.mdx +1 -1
  94. package/docs/foundations/starting-workflows.mdx +74 -1
  95. package/package.json +8 -7
package/dist/workflow.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import { ERROR_SLUGS, ReplayDivergenceError, WorkflowNotRegisteredError, WorkflowRuntimeError, } from '@workflow/errors';
2
- import { createWorkflowBaseUrl, withResolvers } from '@workflow/utils';
2
+ import { createWorkflowBaseUrl, withResolvers, } from '@workflow/utils';
3
3
  import { parseWorkflowName } from '@workflow/utils/parse-name';
4
4
  import { SPEC_VERSION_SUPPORTS_COMPRESSION } from '@workflow/world';
5
5
  import * as nanoid from 'nanoid';
6
6
  import { monotonicFactory } from 'ulid';
7
+ import { createCorrelationIdGenerator, isPerKindCorrelationIdsEnabled, } from './correlation-id.js';
7
8
  import { EventConsumerResult, EventsConsumer } from './events-consumer.js';
8
9
  import { ENOTSUP, WorkflowSuspension } from './global.js';
9
10
  import { runtimeLogger } from './logger.js';
@@ -16,7 +17,7 @@ import { dehydrateWorkflowReturnValue, hydrateWorkflowArguments, } from './seria
16
17
  import { createUseStep } from './step.js';
17
18
  import { BODY_INIT_SYMBOL, STABLE_ULID, WORKFLOW_CREATE_HOOK, WORKFLOW_GET_STREAM_ID, WORKFLOW_SET_ATTRIBUTES, WORKFLOW_SLEEP, WORKFLOW_USE_STEP, } from './symbols.js';
18
19
  import * as Attribute from './telemetry/semantic-conventions.js';
19
- import { trace } from './telemetry.js';
20
+ import { applyWorkflowSuspensionToSpan, trace } from './telemetry.js';
20
21
  import { getWorkflowRunStreamId } from './util.js';
21
22
  import { createContext } from './vm/index.js';
22
23
  import { runCachedWorkflowScript } from './vm/script-cache.js';
@@ -77,11 +78,58 @@ runReadyBarrier) {
77
78
  });
78
79
  }
79
80
  }
81
+ /** Cold-start: build a fresh VM session and replay it over `events`. */
82
+ export function replayWorkflow(options) {
83
+ return traceExecution('replay', options.workflowRun, options.events, async (span) => {
84
+ const { session, execution } = await createWorkflowSession(options);
85
+ span?.setAttributes({
86
+ ...Attribute.WorkflowArgumentsCount(session.argumentCount),
87
+ });
88
+ return recordResult(await execution, span);
89
+ });
90
+ }
91
+ /** Warm-start: advance a retained session by appending events. */
92
+ export function resumeWorkflow(session, events) {
93
+ return traceExecution('retained', session.workflowRun, events, async (span) => {
94
+ span?.setAttributes({
95
+ ...Attribute.WorkflowArgumentsCount(session.argumentCount),
96
+ });
97
+ const result = await session.resume(events);
98
+ return result.type === 'replay' ? result : recordResult(result, span);
99
+ });
100
+ }
101
+ function traceExecution(mode, workflowRun, events, fn) {
102
+ return trace(`workflow.run ${workflowRun.workflowName}`, (span) => {
103
+ span?.setAttributes({
104
+ ...Attribute.WorkflowName(workflowRun.workflowName),
105
+ ...Attribute.WorkflowRunId(workflowRun.runId),
106
+ ...Attribute.WorkflowRunStatus(workflowRun.status),
107
+ ...Attribute.WorkflowEventsCount(events.length),
108
+ ...Attribute.WorkflowExecutionMode(mode),
109
+ });
110
+ return fn(span);
111
+ });
112
+ }
113
+ function recordResult(result, span) {
114
+ if (result.type === 'completed') {
115
+ span?.setAttributes({
116
+ ...Attribute.WorkflowResultType(result.resultType),
117
+ });
118
+ }
119
+ else if (span) {
120
+ applyWorkflowSuspensionToSpan(result.suspension, span);
121
+ }
122
+ return result;
123
+ }
124
+ /**
125
+ * Single-shot replay: execute the workflow over `events` and either return
126
+ * its output or throw its suspension. Kept for the extensive existing test
127
+ * suites — production code goes through `replayWorkflow`/`resumeWorkflow`.
128
+ */
80
129
  export async function runWorkflow(workflowCode, workflowRun, events, encryptionKey,
81
130
  /**
82
131
  * Optional per-run cache for replay payload preparation and immutable final
83
- * values. Owned by the inline replay loop so it survives fresh VM contexts
84
- * created by successive iterations of this invocation.
132
+ * values. Owned by the inline execution loop for this invocation.
85
133
  */
86
134
  replayPayloadCache = new ReplayPayloadCache(encryptionKey),
87
135
  /**
@@ -96,231 +144,265 @@ runReadyBarrier,
96
144
  * capabilities are treated as unsupported.
97
145
  */
98
146
  worldCapabilities) {
99
- return trace(`workflow.run ${workflowRun.workflowName}`, async (span) => {
100
- span?.setAttributes({
101
- ...Attribute.WorkflowName(workflowRun.workflowName),
102
- ...Attribute.WorkflowRunId(workflowRun.runId),
103
- ...Attribute.WorkflowRunStatus(workflowRun.status),
104
- ...Attribute.WorkflowEventsCount(events.length),
147
+ const result = await replayWorkflow({
148
+ workflowCode,
149
+ workflowRun,
150
+ events,
151
+ encryptionKey,
152
+ replayPayloadCache,
153
+ runReadyBarrier,
154
+ worldCapabilities,
155
+ });
156
+ if (result.type === 'suspended')
157
+ throw result.suspension;
158
+ return result.output;
159
+ }
160
+ async function createWorkflowSession({ workflowCode, workflowRun, events, encryptionKey, replayPayloadCache, runReadyBarrier, worldCapabilities, }) {
161
+ const startedAt = workflowRun.startedAt;
162
+ if (!startedAt) {
163
+ throw new WorkflowRuntimeError(`Workflow run "${workflowRun.runId}" has no "startedAt" timestamp (should not happen)`);
164
+ }
165
+ // Seed and initial clock must be available before I/O and remain stable on
166
+ // replay. After the first event, EventsConsumer advances the VM clock from
167
+ // each event's `createdAt`.
168
+ const fixedTimestamp = runIdCreatedAt(workflowRun.runId) ?? +workflowRun.createdAt;
169
+ // Truthiness, not presence: `vercel env pull` writes `VERCEL_URL=""` into
170
+ // `.env.local`, and a framework that loads that file locally would otherwise
171
+ // put us on the Vercel branch with nothing to build a host from, making
172
+ // `https://` the base URL of every run.
173
+ const isVercel = Boolean(process.env.VERCEL_URL);
174
+ // Load getPort lazily to prevent Turbopack from tracing get-port's
175
+ // fs ops (readdir, readFile) into the flow route bundle. The resolved
176
+ // port is cached per process (see get-port-lazy.ts), so this is cheap
177
+ // on replays after the first.
178
+ const workflowBaseUrl = createWorkflowBaseUrl(isVercel
179
+ ? `https://${process.env.VERCEL_URL}`
180
+ : `http://localhost:${(await getPortLazy()) ?? 3000}`);
181
+ const seed = `${workflowRun.runId}:${workflowRun.workflowName}:${workflowRun.deploymentId}`;
182
+ const { context, globalThis: vmGlobalThis, updateTimestamp, } = createContext({
183
+ seed,
184
+ fixedTimestamp,
185
+ });
186
+ const initialInterruption = withResolvers();
187
+ let state = {
188
+ type: 'running',
189
+ interruption: initialInterruption,
190
+ };
191
+ const onWorkflowError = (error) => {
192
+ switch (state.type) {
193
+ case 'running': {
194
+ const { interruption } = state;
195
+ state = WorkflowSuspension.is(error)
196
+ ? { type: 'suspended', suspension: error }
197
+ : { type: 'replay' };
198
+ // Each parked step consumer schedules its own (identical) suspension
199
+ // signal; the first one lands here, and bumping the generation makes
200
+ // the step-consumer guard drop the rest at fire time.
201
+ workflowContext.suspensionGeneration++;
202
+ interruption.reject(error);
203
+ return;
204
+ }
205
+ case 'suspended':
206
+ // Same-boundary duplicates were staled by the generation bump above,
207
+ // so anything landing here is out-of-band — an unguarded sleep/hook/
208
+ // attribute signal or a divergence. Those boundaries are unretainable
209
+ // (the runtime demotes them too), so fall back to replay.
210
+ state = { type: 'replay' };
211
+ return;
212
+ case 'replay':
213
+ case 'completed':
214
+ return;
215
+ }
216
+ state;
217
+ };
218
+ const ulid = monotonicFactory(() => vmGlobalThis.Math.random());
219
+ const generateCorrelationId = createCorrelationIdGenerator({
220
+ seed,
221
+ fixedTimestamp,
222
+ // Correlation IDs must be replay-stable. `startedAt` differs between a
223
+ // turbo delivery and a later server-backed replay, so use fixedTimestamp.
224
+ positional: () => ulid(fixedTimestamp),
225
+ perKind: isPerKindCorrelationIdsEnabled(),
226
+ });
227
+ const generateNanoid = nanoid.customRandom(nanoid.urlAlphabet, 21, (size) => new Uint8Array(size).map(() => 256 * vmGlobalThis.Math.random()));
228
+ // Create a mutable holder for the promise queue so the EventsConsumer
229
+ // can access the current queue state via a getter. The queue is mutated
230
+ // by step/hook/sleep callbacks as events are processed.
231
+ const promiseQueueHolder = { current: Promise.resolve() };
232
+ const eventsConsumer = new EventsConsumer(events, {
233
+ onConsumedEvent: (event) => {
234
+ updateTimestamp(+event.createdAt);
235
+ },
236
+ onUnconsumedEvent: (event) => {
237
+ onWorkflowError(new ReplayDivergenceError(`Replay could not consume event: eventType=${event.eventType}, correlationId=${event.correlationId}, eventId=${event.eventId}.`, { eventId: event.eventId }));
238
+ },
239
+ getPromiseQueue: () => promiseQueueHolder.current,
240
+ });
241
+ const workflowContext = {
242
+ runId: workflowRun.runId,
243
+ encryptionKey,
244
+ worldCapabilities,
245
+ globalThis: vmGlobalThis,
246
+ onWorkflowError,
247
+ eventsConsumer,
248
+ generateCorrelationId,
249
+ generateNanoid,
250
+ invocationsQueue: new Map(),
251
+ // Use getter/setter so the EventsConsumer's getPromiseQueue() always
252
+ // sees the latest queue state as it's mutated by step/hook/sleep callbacks.
253
+ get promiseQueue() {
254
+ return promiseQueueHolder.current;
255
+ },
256
+ set promiseQueue(value) {
257
+ promiseQueueHolder.current = value;
258
+ },
259
+ pendingDeliveries: 0,
260
+ suspensionGeneration: 0,
261
+ pendingDeliveryBarriers: new Map(),
262
+ replayPayloadCache,
263
+ };
264
+ // Consume run lifecycle events - these are structural events that don't
265
+ // need special handling in the workflow, but must be consumed to advance
266
+ // past them in the event log
267
+ workflowContext.eventsConsumer.subscribe((event) => {
268
+ if (!event) {
269
+ return EventConsumerResult.NotConsumed;
270
+ }
271
+ // Consume run_created - every run has exactly one
272
+ if (event.eventType === 'run_created') {
273
+ return EventConsumerResult.Consumed;
274
+ }
275
+ // Consume run_started - every run has exactly one
276
+ if (event.eventType === 'run_started') {
277
+ return EventConsumerResult.Consumed;
278
+ }
279
+ // Attribute writes performed from a step have no workflow-body call to
280
+ // consume them during replay; they are already reflected in the run
281
+ // snapshot and remain structural until a read API is introduced.
282
+ if (event.eventType === 'attr_set' &&
283
+ event.eventData.writer.type === 'step') {
284
+ return EventConsumerResult.Consumed;
285
+ }
286
+ return EventConsumerResult.NotConsumed;
287
+ });
288
+ const useStep = createUseStep(workflowContext);
289
+ const createHook = createCreateHook(workflowContext);
290
+ const sleep = createSleep(workflowContext);
291
+ const setAttributes = createSetAttributes(workflowContext);
292
+ // @ts-expect-error - `@types/node` says symbol is not valid, but it does work
293
+ vmGlobalThis[WORKFLOW_USE_STEP] = useStep;
294
+ // @ts-expect-error - `@types/node` says symbol is not valid, but it does work
295
+ vmGlobalThis[WORKFLOW_SET_ATTRIBUTES] = setAttributes;
296
+ // @ts-expect-error - `@types/node` says symbol is not valid, but it does work
297
+ vmGlobalThis[WORKFLOW_CREATE_HOOK] = createHook;
298
+ // @ts-expect-error - `@types/node` says symbol is not valid, but it does work
299
+ vmGlobalThis[WORKFLOW_SLEEP] = sleep;
300
+ // @ts-expect-error - `@types/node` says symbol is not valid, but it does work
301
+ vmGlobalThis[WORKFLOW_GET_STREAM_ID] = (namespace) => getWorkflowRunStreamId(workflowRun.runId, namespace);
302
+ // For the workflow VM, we store the context in a symbol on the `globalThis` object
303
+ const ctx = {
304
+ workflowName: workflowRun.workflowName,
305
+ workflowRunId: workflowRun.runId,
306
+ workflowStartedAt: new vmGlobalThis.Date(+startedAt),
307
+ url: workflowBaseUrl,
308
+ features: { encryption: !!encryptionKey },
309
+ };
310
+ // @ts-expect-error - `@types/node` says symbol is not valid, but it does work
311
+ vmGlobalThis[WORKFLOW_CONTEXT_SYMBOL] = ctx;
312
+ // Serialization mints stream ids through this symbol, and calls it with no
313
+ // seed time. `monotonicFactory` returns `encodeTime(lastTime)` on its
314
+ // increment branch, so one such call latches the *host* wall clock into
315
+ // `lastTime` and every id the run mints afterwards carries that timestamp
316
+ // instead of `fixedTimestamp` — a value that differs on every replay.
317
+ // Binding the seed time here keeps the whole run on one replay-stable clock.
318
+ // @ts-expect-error - `@types/node` says symbol is not valid, but it does work
319
+ vmGlobalThis[STABLE_ULID] = () => generateCorrelationId('stream');
320
+ // Workflow code must import the deterministic `fetch` step from `workflow`.
321
+ vmGlobalThis.fetch = () => {
322
+ throw new vmGlobalThis.Error(`Global "fetch" is unavailable in workflow functions. Use the "fetch" step function from "workflow" to make HTTP requests.\n\nLearn more: https://workflow-sdk.dev/err/${ERROR_SLUGS.FETCH_IN_WORKFLOW_FUNCTION}`);
323
+ };
324
+ // Override timeout/interval functions to throw helpful errors
325
+ // These are not supported in workflow functions because they rely on
326
+ // asynchronous scheduling which breaks deterministic replay
327
+ const timeoutErrorMessage = 'Timeout functions like "setTimeout" and "setInterval" are not supported in workflow functions. Use the "sleep" function from "workflow" for time-based delays.';
328
+ vmGlobalThis.setTimeout = () => {
329
+ throw new WorkflowRuntimeError(timeoutErrorMessage, {
330
+ slug: ERROR_SLUGS.TIMEOUT_FUNCTIONS_IN_WORKFLOW,
105
331
  });
106
- const startedAt = workflowRun.startedAt;
107
- if (!startedAt) {
108
- throw new WorkflowRuntimeError(`Workflow run "${workflowRun.runId}" has no "startedAt" timestamp (should not happen)`);
109
- }
110
- // Seed and initial clock must be available before I/O and remain stable on
111
- // replay. After the first event, EventsConsumer advances the VM clock from
112
- // each event's `createdAt`.
113
- const fixedTimestamp = runIdCreatedAt(workflowRun.runId) ?? +workflowRun.createdAt;
114
- // Truthiness, not presence: `vercel env pull` writes `VERCEL_URL=""` into
115
- // `.env.local`, and a framework that loads that file locally would otherwise
116
- // put us on the Vercel branch with nothing to build a host from, making
117
- // `https://` the base URL of every run.
118
- const isVercel = Boolean(process.env.VERCEL_URL);
119
- // Load getPort lazily to prevent Turbopack from tracing get-port's
120
- // fs ops (readdir, readFile) into the flow route bundle. The resolved
121
- // port is cached per process (see get-port-lazy.ts), so this is cheap
122
- // on replays after the first.
123
- const workflowBaseUrl = createWorkflowBaseUrl(isVercel
124
- ? `https://${process.env.VERCEL_URL}`
125
- : `http://localhost:${(await getPortLazy()) ?? 3000}`);
126
- const { context, globalThis: vmGlobalThis, updateTimestamp, } = createContext({
127
- seed: `${workflowRun.runId}:${workflowRun.workflowName}:${workflowRun.deploymentId}`,
128
- fixedTimestamp,
332
+ };
333
+ vmGlobalThis.setInterval = () => {
334
+ throw new WorkflowRuntimeError(timeoutErrorMessage, {
335
+ slug: ERROR_SLUGS.TIMEOUT_FUNCTIONS_IN_WORKFLOW,
129
336
  });
130
- const workflowDiscontinuation = withResolvers();
131
- const ulid = monotonicFactory(() => vmGlobalThis.Math.random());
132
- const generateNanoid = nanoid.customRandom(nanoid.urlAlphabet, 21, (size) => new Uint8Array(size).map(() => 256 * vmGlobalThis.Math.random()));
133
- // Create a mutable holder for the promise queue so the EventsConsumer
134
- // can access the current queue state via a getter. The queue is mutated
135
- // by step/hook/sleep callbacks as events are processed.
136
- const promiseQueueHolder = { current: Promise.resolve() };
137
- const eventsConsumer = new EventsConsumer(events, {
138
- onConsumedEvent: (event) => {
139
- updateTimestamp(+event.createdAt);
140
- },
141
- onUnconsumedEvent: (event) => {
142
- workflowDiscontinuation.reject(new ReplayDivergenceError(`Replay could not consume event: eventType=${event.eventType}, correlationId=${event.correlationId}, eventId=${event.eventId}.`, { eventId: event.eventId }));
143
- },
144
- getPromiseQueue: () => promiseQueueHolder.current,
337
+ };
338
+ vmGlobalThis.clearTimeout = () => {
339
+ throw new WorkflowRuntimeError(timeoutErrorMessage, {
340
+ slug: ERROR_SLUGS.TIMEOUT_FUNCTIONS_IN_WORKFLOW,
145
341
  });
146
- const workflowContext = {
147
- runId: workflowRun.runId,
148
- encryptionKey,
149
- worldCapabilities,
150
- globalThis: vmGlobalThis,
151
- onWorkflowError: workflowDiscontinuation.reject,
152
- eventsConsumer,
153
- // Correlation IDs must be replay-stable. `startedAt` differs between a
154
- // turbo delivery and a later server-backed replay, so use fixedTimestamp.
155
- generateUlid: () => ulid(fixedTimestamp),
156
- generateNanoid,
157
- invocationsQueue: new Map(),
158
- // Use getter/setter so the EventsConsumer's getPromiseQueue() always
159
- // sees the latest queue state as it's mutated by step/hook/sleep callbacks.
160
- get promiseQueue() {
161
- return promiseQueueHolder.current;
162
- },
163
- set promiseQueue(value) {
164
- promiseQueueHolder.current = value;
165
- },
166
- pendingDeliveries: 0,
167
- pendingDeliveryBarriers: new Map(),
168
- replayPayloadCache,
169
- };
170
- // Consume run lifecycle events - these are structural events that don't
171
- // need special handling in the workflow, but must be consumed to advance
172
- // past them in the event log
173
- workflowContext.eventsConsumer.subscribe((event) => {
174
- if (!event) {
175
- return EventConsumerResult.NotConsumed;
176
- }
177
- // Consume run_created - every run has exactly one
178
- if (event.eventType === 'run_created') {
179
- return EventConsumerResult.Consumed;
180
- }
181
- // Consume run_started - every run has exactly one
182
- if (event.eventType === 'run_started') {
183
- return EventConsumerResult.Consumed;
184
- }
185
- // Attribute writes performed from a step have no workflow-body call to
186
- // consume them during replay; they are already reflected in the run
187
- // snapshot and remain structural until a read API is introduced.
188
- if (event.eventType === 'attr_set' &&
189
- event.eventData.writer.type === 'step') {
190
- return EventConsumerResult.Consumed;
191
- }
192
- return EventConsumerResult.NotConsumed;
342
+ };
343
+ vmGlobalThis.clearInterval = () => {
344
+ throw new WorkflowRuntimeError(timeoutErrorMessage, {
345
+ slug: ERROR_SLUGS.TIMEOUT_FUNCTIONS_IN_WORKFLOW,
193
346
  });
194
- const useStep = createUseStep(workflowContext);
195
- const createHook = createCreateHook(workflowContext);
196
- const sleep = createSleep(workflowContext);
197
- const setAttributes = createSetAttributes(workflowContext);
198
- // @ts-expect-error - `@types/node` says symbol is not valid, but it does work
199
- vmGlobalThis[WORKFLOW_USE_STEP] = useStep;
200
- // @ts-expect-error - `@types/node` says symbol is not valid, but it does work
201
- vmGlobalThis[WORKFLOW_SET_ATTRIBUTES] = setAttributes;
202
- // @ts-expect-error - `@types/node` says symbol is not valid, but it does work
203
- vmGlobalThis[WORKFLOW_CREATE_HOOK] = createHook;
204
- // @ts-expect-error - `@types/node` says symbol is not valid, but it does work
205
- vmGlobalThis[WORKFLOW_SLEEP] = sleep;
206
- // @ts-expect-error - `@types/node` says symbol is not valid, but it does work
207
- vmGlobalThis[WORKFLOW_GET_STREAM_ID] = (namespace) => getWorkflowRunStreamId(workflowRun.runId, namespace);
208
- // For the workflow VM, we store the context in a symbol on the `globalThis` object
209
- const ctx = {
210
- workflowName: workflowRun.workflowName,
211
- workflowRunId: workflowRun.runId,
212
- workflowStartedAt: new vmGlobalThis.Date(+startedAt),
213
- url: workflowBaseUrl,
214
- features: { encryption: !!encryptionKey },
215
- };
216
- // @ts-expect-error - `@types/node` says symbol is not valid, but it does work
217
- vmGlobalThis[WORKFLOW_CONTEXT_SYMBOL] = ctx;
218
- // @ts-expect-error - `@types/node` says symbol is not valid, but it does work
219
- vmGlobalThis[STABLE_ULID] = ulid;
220
- // Workflow code must import the deterministic `fetch` step from `workflow`.
221
- vmGlobalThis.fetch = () => {
222
- throw new vmGlobalThis.Error(`Global "fetch" is unavailable in workflow functions. Use the "fetch" step function from "workflow" to make HTTP requests.\n\nLearn more: https://workflow-sdk.dev/err/${ERROR_SLUGS.FETCH_IN_WORKFLOW_FUNCTION}`);
223
- };
224
- // Override timeout/interval functions to throw helpful errors
225
- // These are not supported in workflow functions because they rely on
226
- // asynchronous scheduling which breaks deterministic replay
227
- const timeoutErrorMessage = 'Timeout functions like "setTimeout" and "setInterval" are not supported in workflow functions. Use the "sleep" function from "workflow" for time-based delays.';
228
- vmGlobalThis.setTimeout = () => {
229
- throw new WorkflowRuntimeError(timeoutErrorMessage, {
230
- slug: ERROR_SLUGS.TIMEOUT_FUNCTIONS_IN_WORKFLOW,
231
- });
232
- };
233
- vmGlobalThis.setInterval = () => {
234
- throw new WorkflowRuntimeError(timeoutErrorMessage, {
235
- slug: ERROR_SLUGS.TIMEOUT_FUNCTIONS_IN_WORKFLOW,
236
- });
237
- };
238
- vmGlobalThis.clearTimeout = () => {
239
- throw new WorkflowRuntimeError(timeoutErrorMessage, {
240
- slug: ERROR_SLUGS.TIMEOUT_FUNCTIONS_IN_WORKFLOW,
241
- });
242
- };
243
- vmGlobalThis.clearInterval = () => {
244
- throw new WorkflowRuntimeError(timeoutErrorMessage, {
245
- slug: ERROR_SLUGS.TIMEOUT_FUNCTIONS_IN_WORKFLOW,
246
- });
247
- };
248
- vmGlobalThis.setImmediate = () => {
249
- throw new WorkflowRuntimeError(timeoutErrorMessage, {
250
- slug: ERROR_SLUGS.TIMEOUT_FUNCTIONS_IN_WORKFLOW,
251
- });
252
- };
253
- vmGlobalThis.clearImmediate = () => {
254
- throw new WorkflowRuntimeError(timeoutErrorMessage, {
255
- slug: ERROR_SLUGS.TIMEOUT_FUNCTIONS_IN_WORKFLOW,
256
- });
257
- };
258
- // `AbortController` and `AbortSignal` in the workflow VM are hook-backed
259
- // for deterministic replay. The controller's abort() queues a hook resumption,
260
- // and signal.aborted is updated when the hook event is processed during replay.
261
- vmGlobalThis.AbortController =
262
- createCreateAbortController(workflowContext);
263
- const abortSignalStatics = createAbortSignalStatics();
264
- vmGlobalThis.AbortSignal = {
265
- abort: abortSignalStatics.abort,
266
- any: abortSignalStatics.any,
267
- timeout: abortSignalStatics.timeout,
268
- };
269
- // `Request` and `Response` are special built-in classes that invoke steps
270
- // for the `json()`, `text()` and `arrayBuffer()` instance methods
271
- class Request {
272
- cache;
273
- credentials;
274
- destination;
275
- headers;
276
- integrity;
277
- method;
278
- mode;
279
- redirect;
280
- referrer;
281
- referrerPolicy;
282
- url;
283
- keepalive;
284
- signal;
285
- duplex;
286
- body;
287
- constructor(input, init) {
288
- // Handle URL input
289
- if (typeof input === 'string' || input instanceof vmGlobalThis.URL) {
290
- const urlString = String(input);
291
- // Validate URL format
292
- try {
293
- new vmGlobalThis.URL(urlString);
294
- this.url = urlString;
295
- }
296
- catch (cause) {
297
- throw new TypeError(`Failed to parse URL from ${urlString}`, {
298
- cause,
299
- });
300
- }
347
+ };
348
+ vmGlobalThis.setImmediate = () => {
349
+ throw new WorkflowRuntimeError(timeoutErrorMessage, {
350
+ slug: ERROR_SLUGS.TIMEOUT_FUNCTIONS_IN_WORKFLOW,
351
+ });
352
+ };
353
+ vmGlobalThis.clearImmediate = () => {
354
+ throw new WorkflowRuntimeError(timeoutErrorMessage, {
355
+ slug: ERROR_SLUGS.TIMEOUT_FUNCTIONS_IN_WORKFLOW,
356
+ });
357
+ };
358
+ // `AbortController` and `AbortSignal` in the workflow VM are hook-backed
359
+ // for deterministic replay. The controller's abort() queues a hook resumption,
360
+ // and signal.aborted is updated when the hook event is processed during replay.
361
+ vmGlobalThis.AbortController =
362
+ createCreateAbortController(workflowContext);
363
+ const abortSignalStatics = createAbortSignalStatics();
364
+ vmGlobalThis.AbortSignal = {
365
+ abort: abortSignalStatics.abort,
366
+ any: abortSignalStatics.any,
367
+ timeout: abortSignalStatics.timeout,
368
+ };
369
+ // `Request` and `Response` are special built-in classes that invoke steps
370
+ // for the `json()`, `text()` and `arrayBuffer()` instance methods
371
+ class Request {
372
+ cache;
373
+ credentials;
374
+ destination;
375
+ headers;
376
+ integrity;
377
+ method;
378
+ mode;
379
+ redirect;
380
+ referrer;
381
+ referrerPolicy;
382
+ url;
383
+ keepalive;
384
+ signal;
385
+ duplex;
386
+ body;
387
+ constructor(input, init) {
388
+ // Handle URL input
389
+ if (typeof input === 'string' || input instanceof vmGlobalThis.URL) {
390
+ const urlString = String(input);
391
+ // Validate URL format
392
+ try {
393
+ new vmGlobalThis.URL(urlString);
394
+ this.url = urlString;
395
+ }
396
+ catch (cause) {
397
+ throw new TypeError(`Failed to parse URL from ${urlString}`, {
398
+ cause,
399
+ });
301
400
  }
302
- else {
303
- // Input is a Request object - clone its properties
304
- this.url = input.url;
305
- if (!init) {
306
- this.method = input.method;
307
- this.headers = new vmGlobalThis.Headers(input.headers);
308
- this.body = input.body;
309
- this.mode = input.mode;
310
- this.credentials = input.credentials;
311
- this.cache = input.cache;
312
- this.redirect = input.redirect;
313
- this.referrer = input.referrer;
314
- this.referrerPolicy = input.referrerPolicy;
315
- this.integrity = input.integrity;
316
- this.keepalive = input.keepalive;
317
- this.signal = input.signal;
318
- this.duplex = input.duplex;
319
- this.destination = input.destination;
320
- return;
321
- }
322
- // If init is provided, merge: use source properties, then override with init
323
- // Copy all properties from the source Request first
401
+ }
402
+ else {
403
+ // Input is a Request object - clone its properties
404
+ this.url = input.url;
405
+ if (!init) {
324
406
  this.method = input.method;
325
407
  this.headers = new vmGlobalThis.Headers(input.headers);
326
408
  this.body = input.body;
@@ -335,361 +417,433 @@ worldCapabilities) {
335
417
  this.signal = input.signal;
336
418
  this.duplex = input.duplex;
337
419
  this.destination = input.destination;
420
+ return;
338
421
  }
339
- // Override with init options if provided
340
- // Set method
341
- if (init?.method) {
342
- this.method = init.method.toUpperCase();
343
- }
344
- else if (typeof this.method !== 'string') {
345
- // Fallback to default for string input case
346
- this.method = 'GET';
347
- }
348
- // Set headers
349
- if (init?.headers) {
350
- this.headers = new vmGlobalThis.Headers(init.headers);
351
- }
352
- else if (typeof input === 'string' ||
353
- input instanceof vmGlobalThis.URL) {
354
- // For string/URL input, create empty headers
355
- this.headers = new vmGlobalThis.Headers();
356
- }
357
- // Set other properties with init values or defaults
358
- if (init?.mode !== undefined) {
359
- this.mode = init.mode;
360
- }
361
- else if (typeof this.mode !== 'string') {
362
- this.mode = 'cors';
363
- }
364
- if (init?.credentials !== undefined) {
365
- this.credentials = init.credentials;
366
- }
367
- else if (typeof this.credentials !== 'string') {
368
- this.credentials = 'same-origin';
369
- }
370
- // `any` cast here because @types/node v22 does not yet have `cache`
371
- if (init?.cache !== undefined) {
372
- this.cache = init.cache;
373
- }
374
- else if (typeof this.cache !== 'string') {
375
- this.cache = 'default';
376
- }
377
- if (init?.redirect !== undefined) {
378
- this.redirect = init.redirect;
379
- }
380
- else if (typeof this.redirect !== 'string') {
381
- this.redirect = 'follow';
382
- }
383
- if (init?.referrer !== undefined) {
384
- this.referrer = init.referrer;
385
- }
386
- else if (typeof this.referrer !== 'string') {
387
- this.referrer = 'about:client';
388
- }
389
- if (init?.referrerPolicy !== undefined) {
390
- this.referrerPolicy = init.referrerPolicy;
391
- }
392
- else if (typeof this.referrerPolicy !== 'string') {
393
- this.referrerPolicy = '';
394
- }
395
- if (init?.integrity !== undefined) {
396
- this.integrity = init.integrity;
397
- }
398
- else if (typeof this.integrity !== 'string') {
399
- this.integrity = '';
400
- }
401
- if (init?.keepalive !== undefined) {
402
- this.keepalive = init.keepalive;
403
- }
404
- else if (typeof this.keepalive !== 'boolean') {
405
- this.keepalive = false;
406
- }
407
- if (init?.signal !== undefined) {
408
- // @ts-expect-error - AbortSignal stub
409
- this.signal = init.signal;
410
- }
411
- else if (!this.signal) {
412
- // @ts-expect-error - AbortSignal stub
413
- this.signal = { aborted: false };
414
- }
415
- if (!this.duplex) {
416
- this.duplex = 'half';
417
- }
418
- if (!this.destination) {
419
- this.destination = 'document';
420
- }
421
- const body = init?.body;
422
- // Validate that GET/HEAD methods don't have a body
423
- if (body !== null &&
424
- body !== undefined &&
425
- (this.method === 'GET' || this.method === 'HEAD')) {
426
- throw new TypeError(`Request with GET/HEAD method cannot have body.`);
427
- }
428
- // Store the original BodyInit for serialization
429
- if (body !== null && body !== undefined) {
430
- // Create a "fake" ReadableStream that stores the original body
431
- // This avoids doing async work during workflow replay
432
- this.body = Object.create(vmGlobalThis.ReadableStream.prototype, {
433
- [BODY_INIT_SYMBOL]: {
434
- value: body,
435
- writable: false,
436
- },
437
- });
438
- }
439
- else {
440
- this.body = null;
441
- }
422
+ // If init is provided, merge: use source properties, then override with init
423
+ // Copy all properties from the source Request first
424
+ this.method = input.method;
425
+ this.headers = new vmGlobalThis.Headers(input.headers);
426
+ this.body = input.body;
427
+ this.mode = input.mode;
428
+ this.credentials = input.credentials;
429
+ this.cache = input.cache;
430
+ this.redirect = input.redirect;
431
+ this.referrer = input.referrer;
432
+ this.referrerPolicy = input.referrerPolicy;
433
+ this.integrity = input.integrity;
434
+ this.keepalive = input.keepalive;
435
+ this.signal = input.signal;
436
+ this.duplex = input.duplex;
437
+ this.destination = input.destination;
438
+ }
439
+ // Override with init options if provided
440
+ // Set method
441
+ if (init?.method) {
442
+ this.method = init.method.toUpperCase();
443
+ }
444
+ else if (typeof this.method !== 'string') {
445
+ // Fallback to default for string input case
446
+ this.method = 'GET';
447
+ }
448
+ // Set headers
449
+ if (init?.headers) {
450
+ this.headers = new vmGlobalThis.Headers(init.headers);
451
+ }
452
+ else if (typeof input === 'string' ||
453
+ input instanceof vmGlobalThis.URL) {
454
+ // For string/URL input, create empty headers
455
+ this.headers = new vmGlobalThis.Headers();
456
+ }
457
+ // Set other properties with init values or defaults
458
+ if (init?.mode !== undefined) {
459
+ this.mode = init.mode;
460
+ }
461
+ else if (typeof this.mode !== 'string') {
462
+ this.mode = 'cors';
463
+ }
464
+ if (init?.credentials !== undefined) {
465
+ this.credentials = init.credentials;
466
+ }
467
+ else if (typeof this.credentials !== 'string') {
468
+ this.credentials = 'same-origin';
469
+ }
470
+ // `any` cast here because @types/node v22 does not yet have `cache`
471
+ if (init?.cache !== undefined) {
472
+ this.cache = init.cache;
473
+ }
474
+ else if (typeof this.cache !== 'string') {
475
+ this.cache = 'default';
476
+ }
477
+ if (init?.redirect !== undefined) {
478
+ this.redirect = init.redirect;
479
+ }
480
+ else if (typeof this.redirect !== 'string') {
481
+ this.redirect = 'follow';
482
+ }
483
+ if (init?.referrer !== undefined) {
484
+ this.referrer = init.referrer;
485
+ }
486
+ else if (typeof this.referrer !== 'string') {
487
+ this.referrer = 'about:client';
488
+ }
489
+ if (init?.referrerPolicy !== undefined) {
490
+ this.referrerPolicy = init.referrerPolicy;
491
+ }
492
+ else if (typeof this.referrerPolicy !== 'string') {
493
+ this.referrerPolicy = '';
494
+ }
495
+ if (init?.integrity !== undefined) {
496
+ this.integrity = init.integrity;
497
+ }
498
+ else if (typeof this.integrity !== 'string') {
499
+ this.integrity = '';
500
+ }
501
+ if (init?.keepalive !== undefined) {
502
+ this.keepalive = init.keepalive;
503
+ }
504
+ else if (typeof this.keepalive !== 'boolean') {
505
+ this.keepalive = false;
506
+ }
507
+ if (init?.signal !== undefined) {
508
+ // @ts-expect-error - AbortSignal stub
509
+ this.signal = init.signal;
510
+ }
511
+ else if (!this.signal) {
512
+ // @ts-expect-error - AbortSignal stub
513
+ this.signal = { aborted: false };
514
+ }
515
+ if (!this.duplex) {
516
+ this.duplex = 'half';
517
+ }
518
+ if (!this.destination) {
519
+ this.destination = 'document';
520
+ }
521
+ const body = init?.body;
522
+ // Validate that GET/HEAD methods don't have a body
523
+ if (body !== null &&
524
+ body !== undefined &&
525
+ (this.method === 'GET' || this.method === 'HEAD')) {
526
+ throw new TypeError(`Request with GET/HEAD method cannot have body.`);
442
527
  }
443
- clone() {
444
- ENOTSUP();
445
- }
446
- get bodyUsed() {
447
- return false;
448
- }
449
- // TODO: implement these
450
- blob;
451
- formData;
452
- arrayBuffer;
453
- json;
454
- text;
455
- async bytes() {
456
- return new Uint8Array(await this.arrayBuffer());
457
- }
458
- }
459
- vmGlobalThis.Request = Request;
460
- Object.defineProperties(Request.prototype, {
461
- arrayBuffer: {
462
- value: useStep('__builtin_response_array_buffer'),
463
- writable: true,
464
- configurable: true,
465
- },
466
- json: {
467
- value: useStep('__builtin_response_json'),
468
- writable: true,
469
- configurable: true,
470
- },
471
- text: {
472
- value: useStep('__builtin_response_text'),
473
- writable: true,
474
- configurable: true,
475
- },
476
- });
477
- class Response {
478
- type;
479
- url;
480
- status;
481
- statusText;
482
- body;
483
- headers;
484
- redirected;
485
- constructor(body, init) {
486
- this.status = init?.status ?? 200;
487
- this.statusText = init?.statusText ?? '';
488
- this.headers = new vmGlobalThis.Headers(init?.headers);
489
- this.type = 'default';
490
- this.url = '';
491
- this.redirected = false;
492
- // Validate that null-body status codes don't have a body
493
- // Per HTTP spec: 204 (No Content), 205 (Reset Content), and 304 (Not Modified)
494
- if (body !== null &&
495
- body !== undefined &&
496
- (this.status === 204 || this.status === 205 || this.status === 304)) {
497
- throw new TypeError(`Response constructor: Invalid response status code ${this.status}`);
498
- }
499
- // Store the original BodyInit for serialization
500
- if (body !== null && body !== undefined) {
501
- // Create a "fake" ReadableStream that stores the original body
502
- // This avoids doing async work during workflow replay
503
- this.body = Object.create(vmGlobalThis.ReadableStream.prototype, {
504
- [BODY_INIT_SYMBOL]: {
505
- value: body,
506
- writable: false,
507
- },
508
- });
509
- }
510
- else {
511
- this.body = null;
512
- }
528
+ // Store the original BodyInit for serialization
529
+ if (body !== null && body !== undefined) {
530
+ // Create a "fake" ReadableStream that stores the original body
531
+ // This avoids doing async work during workflow replay
532
+ this.body = Object.create(vmGlobalThis.ReadableStream.prototype, {
533
+ [BODY_INIT_SYMBOL]: {
534
+ value: body,
535
+ writable: false,
536
+ },
537
+ });
513
538
  }
514
- // TODO: implement these
515
- clone;
516
- blob;
517
- formData;
518
- get ok() {
519
- return this.status >= 200 && this.status < 300;
520
- }
521
- get bodyUsed() {
522
- return false;
523
- }
524
- arrayBuffer;
525
- json;
526
- text;
527
- async bytes() {
528
- return new Uint8Array(await this.arrayBuffer());
529
- }
530
- static json(data, init) {
531
- const body = JSON.stringify(data);
532
- const headers = new vmGlobalThis.Headers(init?.headers);
533
- if (!headers.has('content-type')) {
534
- headers.set('content-type', 'application/json');
535
- }
536
- return new Response(body, { ...init, headers });
539
+ else {
540
+ this.body = null;
537
541
  }
538
- static error() {
539
- ENOTSUP();
542
+ }
543
+ clone() {
544
+ ENOTSUP();
545
+ }
546
+ get bodyUsed() {
547
+ return false;
548
+ }
549
+ // TODO: implement these
550
+ blob;
551
+ formData;
552
+ arrayBuffer;
553
+ json;
554
+ text;
555
+ async bytes() {
556
+ return new Uint8Array(await this.arrayBuffer());
557
+ }
558
+ }
559
+ vmGlobalThis.Request = Request;
560
+ Object.defineProperties(Request.prototype, {
561
+ arrayBuffer: {
562
+ value: useStep('__builtin_response_array_buffer'),
563
+ writable: true,
564
+ configurable: true,
565
+ },
566
+ json: {
567
+ value: useStep('__builtin_response_json'),
568
+ writable: true,
569
+ configurable: true,
570
+ },
571
+ text: {
572
+ value: useStep('__builtin_response_text'),
573
+ writable: true,
574
+ configurable: true,
575
+ },
576
+ });
577
+ class Response {
578
+ type;
579
+ url;
580
+ status;
581
+ statusText;
582
+ body;
583
+ headers;
584
+ redirected;
585
+ constructor(body, init) {
586
+ this.status = init?.status ?? 200;
587
+ this.statusText = init?.statusText ?? '';
588
+ this.headers = new vmGlobalThis.Headers(init?.headers);
589
+ this.type = 'default';
590
+ this.url = '';
591
+ this.redirected = false;
592
+ // Validate that null-body status codes don't have a body
593
+ // Per HTTP spec: 204 (No Content), 205 (Reset Content), and 304 (Not Modified)
594
+ if (body !== null &&
595
+ body !== undefined &&
596
+ (this.status === 204 || this.status === 205 || this.status === 304)) {
597
+ throw new TypeError(`Response constructor: Invalid response status code ${this.status}`);
598
+ }
599
+ // Store the original BodyInit for serialization
600
+ if (body !== null && body !== undefined) {
601
+ // Create a "fake" ReadableStream that stores the original body
602
+ // This avoids doing async work during workflow replay
603
+ this.body = Object.create(vmGlobalThis.ReadableStream.prototype, {
604
+ [BODY_INIT_SYMBOL]: {
605
+ value: body,
606
+ writable: false,
607
+ },
608
+ });
609
+ }
610
+ else {
611
+ this.body = null;
540
612
  }
541
- static redirect(url, status = 302) {
542
- // Validate status code - only specific redirect codes are allowed
543
- if (![301, 302, 303, 307, 308].includes(status)) {
544
- throw new RangeError(`Invalid redirect status code: ${status}. Must be one of: 301, 302, 303, 307, 308`);
545
- }
546
- // Create response with Location header
547
- const headers = new vmGlobalThis.Headers();
548
- headers.set('Location', String(url));
549
- const response = Object.create(Response.prototype);
550
- response.status = status;
551
- response.statusText = '';
552
- response.headers = headers;
553
- response.body = null;
554
- response.type = 'default';
555
- response.url = '';
556
- response.redirected = false;
557
- return response;
558
- }
559
- }
560
- vmGlobalThis.Response = Response;
561
- Object.defineProperties(Response.prototype, {
562
- arrayBuffer: {
563
- value: useStep('__builtin_response_array_buffer'),
564
- writable: true,
565
- configurable: true,
566
- },
567
- json: {
568
- value: useStep('__builtin_response_json'),
569
- writable: true,
570
- configurable: true,
571
- },
572
- text: {
573
- value: useStep('__builtin_response_text'),
574
- writable: true,
575
- configurable: true,
576
- },
577
- });
578
- class ReadableStream {
579
- constructor() {
580
- ENOTSUP();
581
- }
582
- get locked() {
583
- return false;
584
- }
585
- cancel() {
586
- ENOTSUP();
587
- }
588
- getReader() {
589
- ENOTSUP();
590
- }
591
- pipeThrough() {
592
- ENOTSUP();
593
- }
594
- pipeTo() {
595
- ENOTSUP();
596
- }
597
- tee() {
598
- ENOTSUP();
599
- }
600
- values() {
601
- ENOTSUP();
602
- }
603
- static from() {
604
- ENOTSUP();
605
- }
606
- [Symbol.asyncIterator]() {
607
- ENOTSUP();
608
- }
609
- }
610
- vmGlobalThis.ReadableStream = ReadableStream;
611
- class WritableStream {
612
- constructor() {
613
- ENOTSUP();
614
- }
615
- get locked() {
616
- return false;
617
- }
618
- abort() {
619
- ENOTSUP();
620
- }
621
- close() {
622
- ENOTSUP();
623
- }
624
- getWriter() {
625
- ENOTSUP();
626
- }
627
- }
628
- vmGlobalThis.WritableStream = WritableStream;
629
- class TransformStream {
630
- readable;
631
- writable;
632
- constructor() {
633
- ENOTSUP();
634
- }
635
- }
636
- vmGlobalThis.TransformStream = TransformStream;
637
- vmGlobalThis.console = globalThis.console;
638
- // Expose the request-context symbol required by AI Gateway.
639
- const SYMBOL_FOR_REQ_CONTEXT = Symbol.for('@vercel/request-context');
640
- // @ts-expect-error - `@types/node` says symbol is not valid, but it does work
641
- vmGlobalThis[SYMBOL_FOR_REQ_CONTEXT] = globalThis[SYMBOL_FOR_REQ_CONTEXT];
642
- // Get a reference to the user-defined workflow function.
643
- // The filename parameter ensures stack traces show a meaningful name
644
- // (e.g., "example/workflows/99_e2e.ts") instead of "evalmachine.<anonymous>".
645
- const parsedName = parseWorkflowName(workflowRun.workflowName);
646
- const filename = parsedName?.moduleSpecifier || workflowRun.workflowName;
647
- // Reuse compiled scripts by `(code, filename)`: compilation is deterministic
648
- // and the filename preserves workflow source attribution in stack traces.
649
- // The bundle registers workflows on `globalThis.__private_workflows`.
650
- runCachedWorkflowScript(workflowCode, filename, context);
651
- const workflowFn = runCachedWorkflowScript(`globalThis.__private_workflows?.get(${JSON.stringify(workflowRun.workflowName)})`, filename, context);
652
- if (typeof workflowFn !== 'function') {
653
- throw new WorkflowNotRegisteredError(workflowRun.workflowName);
654
- }
655
- // Chain workflow argument hydration onto the promiseQueue so that the
656
- // unconsumed event check (which waits for the queue to drain) doesn't
657
- // fire during the async gap between run_started consumption and the
658
- // workflow function subscribing its first step callbacks.
659
- let args = [];
660
- workflowContext.promiseQueue = workflowContext.promiseQueue.then(async () => {
661
- const prepared = await replayPayloadCache.prepareWorkflowInput(workflowRun);
662
- args = await hydrateWorkflowArguments(workflowRun.input, workflowRun.runId, encryptionKey, vmGlobalThis, {}, prepared);
663
- });
664
- await workflowContext.promiseQueue;
665
- span?.setAttributes({
666
- ...Attribute.WorkflowArgumentsCount(args.length),
667
- });
668
- // Invoke user workflow
613
+ }
614
+ // TODO: implement these
615
+ clone;
616
+ blob;
617
+ formData;
618
+ get ok() {
619
+ return this.status >= 200 && this.status < 300;
620
+ }
621
+ get bodyUsed() {
622
+ return false;
623
+ }
624
+ arrayBuffer;
625
+ json;
626
+ text;
627
+ async bytes() {
628
+ return new Uint8Array(await this.arrayBuffer());
629
+ }
630
+ static json(data, init) {
631
+ const body = JSON.stringify(data);
632
+ const headers = new vmGlobalThis.Headers(init?.headers);
633
+ if (!headers.has('content-type')) {
634
+ headers.set('content-type', 'application/json');
635
+ }
636
+ return new Response(body, { ...init, headers });
637
+ }
638
+ static error() {
639
+ ENOTSUP();
640
+ }
641
+ static redirect(url, status = 302) {
642
+ // Validate status code - only specific redirect codes are allowed
643
+ if (![301, 302, 303, 307, 308].includes(status)) {
644
+ throw new RangeError(`Invalid redirect status code: ${status}. Must be one of: 301, 302, 303, 307, 308`);
645
+ }
646
+ // Create response with Location header
647
+ const headers = new vmGlobalThis.Headers();
648
+ headers.set('Location', String(url));
649
+ const response = Object.create(Response.prototype);
650
+ response.status = status;
651
+ response.statusText = '';
652
+ response.headers = headers;
653
+ response.body = null;
654
+ response.type = 'default';
655
+ response.url = '';
656
+ response.redirected = false;
657
+ return response;
658
+ }
659
+ }
660
+ vmGlobalThis.Response = Response;
661
+ Object.defineProperties(Response.prototype, {
662
+ arrayBuffer: {
663
+ value: useStep('__builtin_response_array_buffer'),
664
+ writable: true,
665
+ configurable: true,
666
+ },
667
+ json: {
668
+ value: useStep('__builtin_response_json'),
669
+ writable: true,
670
+ configurable: true,
671
+ },
672
+ text: {
673
+ value: useStep('__builtin_response_text'),
674
+ writable: true,
675
+ configurable: true,
676
+ },
677
+ });
678
+ class ReadableStream {
679
+ constructor() {
680
+ ENOTSUP();
681
+ }
682
+ get locked() {
683
+ return false;
684
+ }
685
+ cancel() {
686
+ ENOTSUP();
687
+ }
688
+ getReader() {
689
+ ENOTSUP();
690
+ }
691
+ pipeThrough() {
692
+ ENOTSUP();
693
+ }
694
+ pipeTo() {
695
+ ENOTSUP();
696
+ }
697
+ tee() {
698
+ ENOTSUP();
699
+ }
700
+ values() {
701
+ ENOTSUP();
702
+ }
703
+ static from() {
704
+ ENOTSUP();
705
+ }
706
+ [Symbol.asyncIterator]() {
707
+ ENOTSUP();
708
+ }
709
+ }
710
+ vmGlobalThis.ReadableStream = ReadableStream;
711
+ class WritableStream {
712
+ constructor() {
713
+ ENOTSUP();
714
+ }
715
+ get locked() {
716
+ return false;
717
+ }
718
+ abort() {
719
+ ENOTSUP();
720
+ }
721
+ close() {
722
+ ENOTSUP();
723
+ }
724
+ getWriter() {
725
+ ENOTSUP();
726
+ }
727
+ }
728
+ vmGlobalThis.WritableStream = WritableStream;
729
+ class TransformStream {
730
+ readable;
731
+ writable;
732
+ constructor() {
733
+ ENOTSUP();
734
+ }
735
+ }
736
+ vmGlobalThis.TransformStream = TransformStream;
737
+ vmGlobalThis.console = globalThis.console;
738
+ // Expose the request-context symbol required by AI Gateway.
739
+ const SYMBOL_FOR_REQ_CONTEXT = Symbol.for('@vercel/request-context');
740
+ // @ts-expect-error - `@types/node` says symbol is not valid, but it does work
741
+ vmGlobalThis[SYMBOL_FOR_REQ_CONTEXT] = globalThis[SYMBOL_FOR_REQ_CONTEXT];
742
+ // Get a reference to the user-defined workflow function.
743
+ // The filename parameter ensures stack traces show a meaningful name
744
+ // (e.g., "example/workflows/99_e2e.ts") instead of "evalmachine.<anonymous>".
745
+ const parsedName = parseWorkflowName(workflowRun.workflowName);
746
+ const filename = parsedName?.moduleSpecifier || workflowRun.workflowName;
747
+ // Reuse compiled scripts by `(code, filename)`: compilation is deterministic
748
+ // and the filename preserves workflow source attribution in stack traces.
749
+ // The bundle registers workflows on `globalThis.__private_workflows`.
750
+ runCachedWorkflowScript(workflowCode, filename, context);
751
+ const workflowFn = runCachedWorkflowScript(`globalThis.__private_workflows?.get(${JSON.stringify(workflowRun.workflowName)})`, filename, context);
752
+ if (typeof workflowFn !== 'function') {
753
+ throw new WorkflowNotRegisteredError(workflowRun.workflowName);
754
+ }
755
+ // Chain workflow argument hydration onto the promiseQueue so that the
756
+ // unconsumed event check (which waits for the queue to drain) doesn't
757
+ // fire during the async gap between run_started consumption and the
758
+ // workflow function subscribing its first step callbacks.
759
+ let args = [];
760
+ workflowContext.promiseQueue = workflowContext.promiseQueue.then(async () => {
761
+ const prepared = await replayPayloadCache.prepareWorkflowInput(workflowRun);
762
+ args = await hydrateWorkflowArguments(workflowRun.input, workflowRun.runId, encryptionKey, vmGlobalThis, {}, prepared);
763
+ });
764
+ await workflowContext.promiseQueue;
765
+ // The user function's promise. It may stay pending across many resumes
766
+ // (each parked step promise holds it up) and is raced against the current
767
+ // attempt's interruption in waitForExecution.
768
+ const workflowBody = (async () => {
769
+ return await workflowFn(...args);
770
+ })();
771
+ const failWorkflow = async (error) => {
772
+ // Control-flow signals are handled by the runtime and do not mean the
773
+ // workflow has terminally failed. `onWorkflowError` usually already moved
774
+ // the state machine, but a divergence can also arrive via a step
775
+ // promise's direct rejection (bypassing `onWorkflowError`) — demote so
776
+ // every control-flow path converges on `replay` and a later resume falls
777
+ // back instead of throwing.
778
+ if (WorkflowSuspension.is(error) || ReplayDivergenceError.is(error)) {
779
+ if (state.type === 'running')
780
+ state = { type: 'replay' };
781
+ throw error;
782
+ }
783
+ state = { type: 'completed' };
784
+ await drainPendingQueueItems(workflowRun.runId, workflowContext.invocationsQueue, vmGlobalThis, workflowRun, 'failed', runReadyBarrier);
785
+ throw error;
786
+ };
787
+ const waitForExecution = async (interruption) => {
788
+ let result;
789
+ try {
790
+ result = await Promise.race([workflowBody, interruption.promise]);
791
+ }
792
+ catch (error) {
793
+ if (state.type === 'suspended' && error === state.suspension) {
794
+ return { type: 'suspended', suspension: state.suspension, session };
795
+ }
796
+ return failWorkflow(error);
797
+ }
798
+ state = { type: 'completed' };
669
799
  try {
670
- const result = await Promise.race([
671
- workflowFn(...args),
672
- workflowDiscontinuation.promise,
673
- ]);
674
- const dehydrated = await dehydrateWorkflowReturnValue(result, workflowRun.runId, encryptionKey, vmGlobalThis, false,
800
+ const output = await dehydrateWorkflowReturnValue(result, workflowRun.runId, encryptionKey, vmGlobalThis, false,
675
801
  // Only compression-capable runs (spec >= 5) may write compressed
676
802
  // payloads. The serializer uses zstd when supported and may use gzip.
677
803
  (workflowRun.specVersion ?? 0) >= SPEC_VERSION_SUPPORTS_COMPRESSION);
678
- span?.setAttributes({
679
- ...Attribute.WorkflowResultType(typeof result),
680
- });
681
804
  await drainPendingQueueItems(workflowRun.runId, workflowContext.invocationsQueue, vmGlobalThis, workflowRun, 'completed', runReadyBarrier);
682
- return dehydrated;
805
+ return { type: 'completed', output, resultType: typeof result };
683
806
  }
684
- catch (err) {
685
- // Control-flow signals are handled by the runtime and do not mean the
686
- // workflow has terminally failed.
687
- if (WorkflowSuspension.is(err) || ReplayDivergenceError.is(err)) {
688
- throw err;
689
- }
690
- await drainPendingQueueItems(workflowRun.runId, workflowContext.invocationsQueue, vmGlobalThis, workflowRun, 'failed', runReadyBarrier);
691
- throw err;
807
+ catch (error) {
808
+ return failWorkflow(error);
692
809
  }
693
- });
810
+ };
811
+ const session = {
812
+ workflowRun,
813
+ argumentCount: args.length,
814
+ async resume(nextEvents) {
815
+ switch (state.type) {
816
+ case 'suspended': {
817
+ // The full O(known events) prefix compare is required: the runtime
818
+ // usually grows one array in place, but its wait-completion and
819
+ // stale-reload paths REPLACE the array with a fresh full fetch, so
820
+ // a rewritten prefix is a real input, not paranoia. The compares
821
+ // are cheap string equality and dwarfed by the replay they avoid.
822
+ const knownEvents = eventsConsumer.events;
823
+ const isStrictExtension = nextEvents.length > knownEvents.length &&
824
+ knownEvents.every((event, index) => event.eventId === nextEvents[index].eventId);
825
+ if (!isStrictExtension) {
826
+ state = { type: 'replay' };
827
+ return { type: 'replay' };
828
+ }
829
+ const interruption = withResolvers();
830
+ state = { type: 'running', interruption };
831
+ workflowContext.suspensionGeneration++;
832
+ eventsConsumer.append(nextEvents.slice(knownEvents.length));
833
+ return waitForExecution(interruption);
834
+ }
835
+ case 'replay':
836
+ return { type: 'replay' };
837
+ case 'completed':
838
+ case 'running':
839
+ throw new WorkflowRuntimeError(`Cannot resume ${state.type} workflow "${workflowRun.runId}"`);
840
+ }
841
+ state;
842
+ },
843
+ };
844
+ return {
845
+ session,
846
+ execution: waitForExecution(initialInterruption),
847
+ };
694
848
  }
695
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2Zsb3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvd29ya2Zsb3cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFdBQVcsRUFDWCxxQkFBcUIsRUFDckIsMEJBQTBCLEVBQzFCLG9CQUFvQixHQUNyQixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN2RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUUvRCxPQUFPLEVBQUUsaUNBQWlDLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRSxPQUFPLEtBQUssTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUNqQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDeEMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLGNBQWMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRTNFLE9BQU8sRUFBRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDMUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUU1QyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDekQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzFELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUU5QyxPQUFPLEVBQ0wsNEJBQTRCLEVBQzVCLHdCQUF3QixHQUN6QixNQUFNLG9CQUFvQixDQUFDO0FBQzVCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDMUMsT0FBTyxFQUNMLGdCQUFn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ZSxDQUFDLGdCQUFnQixFQUNoQyxZQUFZLEVBQ1osV0FBVyxFQUNYLFFBQVEsRUFDUixlQUFlLENBQ2hCLENBQUM7WUFFRixNQUFNLEdBQUcsQ0FBQztRQUNaLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBFUlJPUl9TTFVHUyxcbiAgUmVwbGF5RGl2ZXJnZW5jZUVycm9yLFxuICBXb3JrZmxvd05vdFJlZ2lzdGVyZWRFcnJvcixcbiAgV29ya2Zsb3dSdW50aW1lRXJyb3IsXG59IGZyb20gJ0B3b3JrZmxvdy9lcnJvcnMnO1xuaW1wb3J0IHsgY3JlYXRlV29ya2Zsb3dCYXNlVXJsLCB3aXRoUmVzb2x2ZXJzIH0gZnJvbSAnQHdvcmtmbG93L3V0aWxzJztcbmltcG9ydCB7IHBhcnNlV29ya2Zsb3dOYW1lIH0gZnJvbSAnQHdvcmtmbG93L3V0aWxzL3BhcnNlLW5hbWUnO1xuaW1wb3J0IHR5cGUgeyBFdmVudCwgV29ya2Zsb3dSdW4sIFdvcmxkQ2FwYWJpbGl0aWVzIH0gZnJvbSAnQHdvcmtmbG93L3dvcmxkJztcbmltcG9ydCB7IFNQRUNfVkVSU0lPTl9TVVBQT1JUU19DT01QUkVTU0lPTiB9IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgKiBhcyBuYW5vaWQgZnJvbSAnbmFub2lkJztcbmltcG9ydCB7IG1vbm90b25pY0ZhY3RvcnkgfSBmcm9tICd1bGlkJztcbmltcG9ydCB7IEV2ZW50Q29uc3VtZXJSZXN1bHQsIEV2ZW50c0NvbnN1bWVyIH0gZnJvbSAnLi9ldmVudHMtY29uc3VtZXIuanMnO1xuaW1wb3J0IHR5cGUgeyBRdWV1ZUl0ZW0gfSBmcm9tICcuL2dsb2JhbC5qcyc7XG5pbXBvcnQgeyBFTk9UU1VQLCBXb3JrZmxvd1N1c3BlbnNpb24gfSBmcm9tICcuL2dsb2JhbC5qcyc7XG5pbXBvcnQgeyBydW50aW1lTG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXIuanMnO1xuaW1wb3J0IHR5cGUgeyBXb3JrZmxvd09yY2hlc3RyYXRvckNvbnRleHQgfSBmcm9tICcuL3ByaXZhdGUuanMnO1xuaW1wb3J0IHsgUmVwbGF5UGF5bG9hZENhY2hlIH0gZnJvbSAnLi9yZXBsYXktcGF5bG9hZC1jYWNoZS5qcyc7XG5pbXBvcnQgeyBnZXRQb3J0TGF6eSB9IGZyb20gJy4vcnVudGltZS9nZXQtcG9ydC1sYXp5LmpzJztcbmltcG9ydCB7IHJ1bklkQ3JlYXRlZEF0IH0gZnJvbSAnLi9ydW50aW1lL3J1bi1pZC10aW1lLmpzJztcbmltcG9ydCB7IGhhbmRsZVN1c3BlbnNpb24gfSBmcm9tICcuL3J1bnRpbWUvc3VzcGVuc2lvbi1oYW5kbGVyLmpzJztcbmltcG9ydCB7IGdldFdvcmxkIH0gZnJvbSAnLi9ydW50aW1lL3dvcmxkLmpzJztcbmltcG9ydCB0eXBlIHsgUGF5bG9hZEtleSB9IGZyb20gJy4vc2VyaWFsaXphdGlvbi9lbmNyeXB0aW9uLmpzJztcbmltcG9ydCB7XG4gIGRlaHlkcmF0ZVdvcmtmbG93UmV0dXJuVmFsdWUsXG4gIGh5ZHJhdGVXb3JrZmxvd0FyZ3VtZW50cyxcbn0gZnJvbSAnLi9zZXJpYWxpemF0aW9uLmpzJztcbmltcG9ydCB7IGNyZWF0ZVVzZVN0ZXAgfSBmcm9tICcuL3N0ZXAuanMnO1xuaW1wb3J0IHtcbiAgQk9EWV9JTklUX1NZTUJPTCxcbiAgU1RBQkxFX1VMSUQsXG4gIFdPUktGTE9XX0NSRUFURV9IT09LLFxuICBXT1JLRkxPV19HRVRfU1RSRUFNX0lELFxuICBXT1JLRkxPV19TRVRfQVRUUklCVVRFUyxcbiAgV09SS0ZMT1dfU0xFRVAsXG4gIFdPUktGTE9XX1VTRV9TVEVQLFxufSBmcm9tICcuL3N5bWJvbHMuanMnO1xuaW1wb3J0ICogYXMgQXR0cmlidXRlIGZyb20gJy4vdGVsZW1ldHJ5L3NlbWFudGljLWNvbnZlbnRpb25zLmpzJztcbmltcG9ydCB7IHRyYWNlIH0gZnJvbSAnLi90ZWxlbWV0cnkuanMnO1xuaW1wb3J0IHsgZ2V0V29ya2Zsb3dSdW5TdHJlYW1JZCB9IGZyb20gJy4vdXRpbC5qcyc7XG5pbXBvcnQgeyBjcmVhdGVDb250ZXh0IH0gZnJvbSAnLi92bS9pbmRleC5qcyc7XG5pbXBvcnQgeyBydW5DYWNoZWRXb3JrZmxvd1NjcmlwdCB9IGZyb20gJy4vdm0vc2NyaXB0LWNhY2hlLmpzJztcbmltcG9ydCB7XG4gIGNyZWF0ZUFib3J0U2lnbmFsU3RhdGljcyxcbiAgY3JlYXRlQ3JlYXRlQWJvcnRDb250cm9sbGVyLFxufSBmcm9tICcuL3dvcmtmbG93L2Fib3J0LWNvbnRyb2xsZXIuanMnO1xuaW1wb3J0IHsgY3JlYXRlU2V0QXR0cmlidXRlcyB9IGZyb20gJy4vd29ya2Zsb3cvYXR0cmlidXRlLWRpc3BhdGNoZXIuanMnO1xuaW1wb3J0IHR5cGUgeyBXb3JrZmxvd01ldGFkYXRhIH0gZnJvbSAnLi93b3JrZmxvdy9nZXQtd29ya2Zsb3ctbWV0YWRhdGEuanMnO1xuaW1wb3J0IHsgV09SS0ZMT1dfQ09OVEVYVF9TWU1CT0wgfSBmcm9tICcuL3dvcmtmbG93L2dldC13b3JrZmxvdy1tZXRhZGF0YS5qcyc7XG5pbXBvcnQgeyBjcmVhdGVDcmVhdGVIb29rIH0gZnJvbSAnLi93b3JrZmxvdy9ob29rLmpzJztcbmltcG9ydCB7IGNyZWF0ZVNsZWVwIH0gZnJvbSAnLi93b3JrZmxvdy9zbGVlcC5qcyc7XG5cbi8qKlxuICogRHJhaW4gcGVuZGluZyBxdWV1ZSBpdGVtcyBhdCB3b3JrZmxvdyBjb21wbGV0aW9uIChzdWNjZXNzIG9yIGZhaWx1cmUpLlxuICpcbiAqIFRyZWF0cyBjb21wbGV0aW9uIGFzIGEgZmluYWwgc3VzcGVuc2lvbiBzbyB1bmF3YWl0ZWQgaG9vaywgd2FpdCwgYW5kXG4gKiBhdHRyaWJ1dGUgb3BlcmF0aW9ucyBhcmUgcmVjb3JkZWQgYmVmb3JlIHRoZSBydW4gYmVjb21lcyB0ZXJtaW5hbC4gVGhpc1xuICogYWxzbyBsZXRzIGEgZmluYWwgYGNvbnRyb2xsZXIuYWJvcnQoKWAgcmVhY2ggaW4tZmxpZ2h0IHN0ZXBzLlxuICpcbiAqIEl0IHJlY29yZHMgYCpfY3JlYXRlZGAgYW5kIG5hdGl2ZSBhdHRyaWJ1dGUgZXZlbnRzLCBidXQgbmV2ZXIgZXhlY3V0ZXMgc3RlcFxuICogYm9kaWVzOiBgc3RlcF9zdGFydGVkYCBpcyByZWplY3RlZCBhZnRlciB0aGUgcnVuIGJlY29tZXMgdGVybWluYWwuIEFcbiAqIGZpcmUtYW5kLWZvcmdldCBzdGVwIHRoZXJlZm9yZSBuZWVkcyBhIGxhdGVyIHN1c3BlbnNpb24gdG8gYmUgc2NoZWR1bGVkLlxuICpcbiAqIERyYWluIGZhaWx1cmVzIGRvIG5vdCBjaGFuZ2UgdGhlIHdvcmtmbG93J3MgdGVybWluYWwgb3V0Y29tZS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZHJhaW5QZW5kaW5nUXVldWVJdGVtcyhcbiAgcnVuSWQ6IHN0cmluZyxcbiAgcGVuZGluZ1F1ZXVlOiBNYXA8c3RyaW5nLCBRdWV1ZUl0ZW0+LFxuICB2bUdsb2JhbFRoaXM6IHR5cGVvZiBnbG9iYWxUaGlzLFxuICB3b3JrZmxvd1J1bjogV29ya2Zsb3dSdW4sXG4gIG91dGNvbWU6ICdjb21wbGV0ZWQnIHwgJ2ZhaWxlZCcsXG4gIC8qKlxuICAgKiBJbiB0dXJibyBtb2RlLCBnYXRlcyBmaW5hbCBgKl9jcmVhdGVkYCB3cml0ZXMgb24gYmFja2dyb3VuZGVkXG4gICAqIGBydW5fc3RhcnRlZGAuIFVuZGVmaW5lZCB3aGVuIGBydW5fc3RhcnRlZGAgaXMgYXdhaXRlZC5cbiAgICovXG4gIHJ1blJlYWR5QmFycmllcj86IFByb21pc2U8dW5rbm93bj5cbik6IFByb21pc2U8dm9pZD4ge1xuICBpZiAocGVuZGluZ1F1ZXVlLnNpemUgPT09IDApIHJldHVybjtcbiAgLy8gSW1wbGljaXRseSBkaXNwb3NlIGFueSBhYm9ydCBob29rcyAoc3lzdGVtIGhvb2tzKSB0aGF0IGFyZSBzdGlsbCBhbGl2ZSBhdFxuICAvLyB3b3JrZmxvdyBjb21wbGV0aW9uIHNvIHRoZXkgZG9uJ3QgbGVhayByb3dzIGluIHRoZSBob29rcyB0YWJsZSBmb3IgdGhlXG4gIC8vIHJ1bidzIGxpZmV0aW1lLiBTa2lwIGhvb2tzIHRoYXQgYWxyZWFkeSBoYXZlIGFuIGFib3J0IGluIGZsaWdodCDigJQgdGhvc2VcbiAgLy8gd2lsbCBlbWl0IGhvb2tfcmVjZWl2ZWQgdmlhIHRoZSBhYm9ydCBwcm9jZXNzaW5nIHBhdGguIFVzZXIgaG9va3NcbiAgLy8gKGlzU3lzdGVtICE9PSB0cnVlKSBhcmUgaW50ZW50aW9uYWxseSBsZWZ0IGFsb25lOiB0aGVpciBsaWZldGltZSBpc1xuICAvLyBtYW5hZ2VkIGJ5IHRoZSB1c2VyJ3MgY29kZSwgbm90IHRoZSBydW50aW1lLlxuICBmb3IgKGNvbnN0IGl0ZW0gb2YgcGVuZGluZ1F1ZXVlLnZhbHVlcygpKSB7XG4gICAgaWYgKFxuICAgICAgaXRlbS50eXBlID09PSAnaG9vaycgJiZcbiAgICAgIGl0ZW0uaXNTeXN0ZW0gJiZcbiAgICAgICFpdGVtLmRpc3Bvc2VkICYmXG4gICAgICAhaXRlbS5hYm9ydFJlcXVlc3RlZFxuICAgICkge1xuICAgICAgaXRlbS5kaXNwb3NlZCA9IHRydWU7XG4gICAgfVxuICB9XG4gIHRyeSB7XG4gICAgY29uc3Qgd29ybGQgPSBhd2FpdCBnZXRXb3JsZCgpO1xuICAgIGNvbnN0IHN5bnRoZXNpemVkID0gbmV3IFdvcmtmbG93U3VzcGVuc2lvbihwZW5kaW5nUXVldWUsIHZtR2xvYmFsVGhpcyk7XG4gICAgYXdhaXQgaGFuZGxlU3VzcGVuc2lvbih7XG4gICAgICBzdXNwZW5zaW9uOiBzeW50aGVzaXplZCxcbiAgICAgIHdvcmxkLFxuICAgICAgcnVuOiB3b3JrZmxvd1J1bixcbiAgICAgIHJ1blJlYWR5QmFycmllcixcbiAgICB9KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgcnVudGltZUxvZ2dlci53YXJuKFxuICAgICAgYEZhaWxlZCB0byBkcmFpbiBwZW5kaW5nIHF1ZXVlIGl0ZW1zIGZvciAke291dGNvbWV9IHdvcmtmbG93IHJ1bmAsXG4gICAgICB7XG4gICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICBtZXNzYWdlOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVyciksXG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuV29ya2Zsb3coXG4gIHdvcmtmbG93Q29kZTogc3RyaW5nLFxuICB3b3JrZmxvd1J1bjogV29ya2Zsb3dSdW4sXG4gIGV2ZW50czogRXZlbnRbXSxcbiAgZW5jcnlwdGlvbktleTogUGF5bG9hZEtleSB8IHVuZGVmaW5lZCxcbiAgLyoqXG4gICAqIE9wdGlvbmFsIHBlci1ydW4gY2FjaGUgZm9yIHJlcGxheSBwYXlsb2FkIHByZXBhcmF0aW9uIGFuZCBpbW11dGFibGUgZmluYWxcbiAgICogdmFsdWVzLiBPd25lZCBieSB0aGUgaW5saW5lIHJlcGxheSBsb29wIHNvIGl0IHN1cnZpdmVzIGZyZXNoIFZNIGNvbnRleHRzXG4gICAqIGNyZWF0ZWQgYnkgc3VjY2Vzc2l2ZSBpdGVyYXRpb25zIG9mIHRoaXMgaW52b2NhdGlvbi5cbiAgICovXG4gIHJlcGxheVBheWxvYWRDYWNoZTogUmVwbGF5UGF5bG9hZENhY2hlID0gbmV3IFJlcGxheVBheWxvYWRDYWNoZShcbiAgICBlbmNyeXB0aW9uS2V5XG4gICksXG4gIC8qKlxuICAgKiBUdXJibyBtb2RlIG9ubHk6IHJlc29sdmVzIG9uY2UgdGhlIGJhY2tncm91bmRlZCBgcnVuX3N0YXJ0ZWRgIGhhcyBsYW5kZWQuXG4gICAqIFRocmVhZGVkIGludG8gdGhlIGVuZC1vZi1ydW4gZHJhaW4gc28gZmlyZS1hbmQtZm9yZ2V0IGAqX2NyZWF0ZWRgIHdyaXRlc1xuICAgKiBjb21taXR0ZWQgYXQgd29ya2Zsb3cgY29tcGxldGlvbiBvcmRlciBhZnRlciB0aGUgcnVuJ3MgY3JlYXRpb24uIFVuZGVmaW5lZFxuICAgKiBvdXRzaWRlIHR1cmJvLCB3aGVyZSBgcnVuX3N0YXJ0ZWRgIGlzIGF3YWl0ZWQgdXAgZnJvbnQuXG4gICAqL1xuICBydW5SZWFkeUJhcnJpZXI/OiBQcm9taXNlPHVua25vd24+LFxuICAvKipcbiAgICogRmVhdHVyZXMgc3VwcG9ydGVkIGJ5IHRoZSBXb3JsZCBleGVjdXRpbmcgdGhpcyB3b3JrZmxvdy4gTWlzc2luZ1xuICAgKiBjYXBhYmlsaXRpZXMgYXJlIHRyZWF0ZWQgYXMgdW5zdXBwb3J0ZWQuXG4gICAqL1xuICB3b3JsZENhcGFiaWxpdGllcz86IFdvcmxkQ2FwYWJpbGl0aWVzXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXkgfCB1bmtub3duPiB7XG4gIHJldHVybiB0cmFjZShgd29ya2Zsb3cucnVuICR7d29ya2Zsb3dSdW4ud29ya2Zsb3dOYW1lfWAsIGFzeW5jIChzcGFuKSA9PiB7XG4gICAgc3Bhbj8uc2V0QXR0cmlidXRlcyh7XG4gICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dOYW1lKHdvcmtmbG93UnVuLndvcmtmbG93TmFtZSksXG4gICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dSdW5JZCh3b3JrZmxvd1J1bi5ydW5JZCksXG4gICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dSdW5TdGF0dXMod29ya2Zsb3dSdW4uc3RhdHVzKSxcbiAgICAgIC4uLkF0dHJpYnV0ZS5Xb3JrZmxvd0V2ZW50c0NvdW50KGV2ZW50cy5sZW5ndGgpLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgc3RhcnRlZEF0ID0gd29ya2Zsb3dSdW4uc3RhcnRlZEF0O1xuICAgIGlmICghc3RhcnRlZEF0KSB7XG4gICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IoXG4gICAgICAgIGBXb3JrZmxvdyBydW4gXCIke3dvcmtmbG93UnVuLnJ1bklkfVwiIGhhcyBubyBcInN0YXJ0ZWRBdFwiIHRpbWVzdGFtcCAoc2hvdWxkIG5vdCBoYXBwZW4pYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBTZWVkIGFuZCBpbml0aWFsIGNsb2NrIG11c3QgYmUgYXZhaWxhYmxlIGJlZm9yZSBJL08gYW5kIHJlbWFpbiBzdGFibGUgb25cbiAgICAvLyByZXBsYXkuIEFmdGVyIHRoZSBmaXJzdCBldmVudCwgRXZlbnRzQ29uc3VtZXIgYWR2YW5jZXMgdGhlIFZNIGNsb2NrIGZyb21cbiAgICAvLyBlYWNoIGV2ZW50J3MgYGNyZWF0ZWRBdGAuXG4gICAgY29uc3QgZml4ZWRUaW1lc3RhbXAgPVxuICAgICAgcnVuSWRDcmVhdGVkQXQod29ya2Zsb3dSdW4ucnVuSWQpID8/ICt3b3JrZmxvd1J1bi5jcmVhdGVkQXQ7XG5cbiAgICAvLyBUcnV0aGluZXNzLCBub3QgcHJlc2VuY2U6IGB2ZXJjZWwgZW52IHB1bGxgIHdyaXRlcyBgVkVSQ0VMX1VSTD1cIlwiYCBpbnRvXG4gICAgLy8gYC5lbnYubG9jYWxgLCBhbmQgYSBmcmFtZXdvcmsgdGhhdCBsb2FkcyB0aGF0IGZpbGUgbG9jYWxseSB3b3VsZCBvdGhlcndpc2VcbiAgICAvLyBwdXQgdXMgb24gdGhlIFZlcmNlbCBicmFuY2ggd2l0aCBub3RoaW5nIHRvIGJ1aWxkIGEgaG9zdCBmcm9tLCBtYWtpbmdcbiAgICAvLyBgaHR0cHM6Ly9gIHRoZSBiYXNlIFVSTCBvZiBldmVyeSBydW4uXG4gICAgY29uc3QgaXNWZXJjZWwgPSBCb29sZWFuKHByb2Nlc3MuZW52LlZFUkNFTF9VUkwpO1xuICAgIC8vIExvYWQgZ2V0UG9ydCBsYXppbHkgdG8gcHJldmVudCBUdXJib3BhY2sgZnJvbSB0cmFjaW5nIGdldC1wb3J0J3NcbiAgICAvLyBmcyBvcHMgKHJlYWRkaXIsIHJlYWRGaWxlKSBpbnRvIHRoZSBmbG93IHJvdXRlIGJ1bmRsZS4gVGhlIHJlc29sdmVkXG4gICAgLy8gcG9ydCBpcyBjYWNoZWQgcGVyIHByb2Nlc3MgKHNlZSBnZXQtcG9ydC1sYXp5LnRzKSwgc28gdGhpcyBpcyBjaGVhcFxuICAgIC8vIG9uIHJlcGxheXMgYWZ0ZXIgdGhlIGZpcnN0LlxuICAgIGNvbnN0IHdvcmtmbG93QmFzZVVybCA9IGNyZWF0ZVdvcmtmbG93QmFzZVVybChcbiAgICAgIGlzVmVyY2VsXG4gICAgICAgID8gYGh0dHBzOi8vJHtwcm9jZXNzLmVudi5WRVJDRUxfVVJMfWBcbiAgICAgICAgOiBgaHR0cDovL2xvY2FsaG9zdDokeyhhd2FpdCBnZXRQb3J0TGF6eSgpKSA/PyAzMDAwfWBcbiAgICApO1xuXG4gICAgY29uc3Qge1xuICAgICAgY29udGV4dCxcbiAgICAgIGdsb2JhbFRoaXM6IHZtR2xvYmFsVGhpcyxcbiAgICAgIHVwZGF0ZVRpbWVzdGFtcCxcbiAgICB9ID0gY3JlYXRlQ29udGV4dCh7XG4gICAgICBzZWVkOiBgJHt3b3JrZmxvd1J1bi5ydW5JZH06JHt3b3JrZmxvd1J1bi53b3JrZmxvd05hbWV9OiR7d29ya2Zsb3dSdW4uZGVwbG95bWVudElkfWAsXG4gICAgICBmaXhlZFRpbWVzdGFtcCxcbiAgICB9KTtcblxuICAgIGNvbnN0IHdvcmtmbG93RGlzY29udGludWF0aW9uID0gd2l0aFJlc29sdmVyczx2b2lkPigpO1xuXG4gICAgY29uc3QgdWxpZCA9IG1vbm90b25pY0ZhY3RvcnkoKCkgPT4gdm1HbG9iYWxUaGlzLk1hdGgucmFuZG9tKCkpO1xuICAgIGNvbnN0IGdlbmVyYXRlTmFub2lkID0gbmFub2lkLmN1c3RvbVJhbmRvbShuYW5vaWQudXJsQWxwaGFiZXQsIDIxLCAoc2l6ZSkgPT5cbiAgICAgIG5ldyBVaW50OEFycmF5KHNpemUpLm1hcCgoKSA9PiAyNTYgKiB2bUdsb2JhbFRoaXMuTWF0aC5yYW5kb20oKSlcbiAgICApO1xuXG4gICAgLy8gQ3JlYXRlIGEgbXV0YWJsZSBob2xkZXIgZm9yIHRoZSBwcm9taXNlIHF1ZXVlIHNvIHRoZSBFdmVudHNDb25zdW1lclxuICAgIC8vIGNhbiBhY2Nlc3MgdGhlIGN1cnJlbnQgcXVldWUgc3RhdGUgdmlhIGEgZ2V0dGVyLiBUaGUgcXVldWUgaXMgbXV0YXRlZFxuICAgIC8vIGJ5IHN0ZXAvaG9vay9zbGVlcCBjYWxsYmFja3MgYXMgZXZlbnRzIGFyZSBwcm9jZXNzZWQuXG4gICAgY29uc3QgcHJvbWlzZVF1ZXVlSG9sZGVyID0geyBjdXJyZW50OiBQcm9taXNlLnJlc29sdmUoKSB9O1xuXG4gICAgY29uc3QgZXZlbnRzQ29uc3VtZXIgPSBuZXcgRXZlbnRzQ29uc3VtZXIoZXZlbnRzLCB7XG4gICAgICBvbkNvbnN1bWVkRXZlbnQ6IChldmVudCkgPT4ge1xuICAgICAgICB1cGRhdGVUaW1lc3RhbXAoK2V2ZW50LmNyZWF0ZWRBdCk7XG4gICAgICB9LFxuICAgICAgb25VbmNvbnN1bWVkRXZlbnQ6IChldmVudCkgPT4ge1xuICAgICAgICB3b3JrZmxvd0Rpc2NvbnRpbnVhdGlvbi5yZWplY3QoXG4gICAgICAgICAgbmV3IFJlcGxheURpdmVyZ2VuY2VFcnJvcihcbiAgICAgICAgICAgIGBSZXBsYXkgY291bGQgbm90IGNvbnN1bWUgZXZlbnQ6IGV2ZW50VHlwZT0ke2V2ZW50LmV2ZW50VHlwZX0sIGNvcnJlbGF0aW9uSWQ9JHtldmVudC5jb3JyZWxhdGlvbklkfSwgZXZlbnRJZD0ke2V2ZW50LmV2ZW50SWR9LmAsXG4gICAgICAgICAgICB7IGV2ZW50SWQ6IGV2ZW50LmV2ZW50SWQgfVxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH0sXG4gICAgICBnZXRQcm9taXNlUXVldWU6ICgpID0+IHByb21pc2VRdWV1ZUhvbGRlci5jdXJyZW50LFxuICAgIH0pO1xuXG4gICAgY29uc3Qgd29ya2Zsb3dDb250ZXh0OiBXb3JrZmxvd09yY2hlc3RyYXRvckNvbnRleHQgPSB7XG4gICAgICBydW5JZDogd29ya2Zsb3dSdW4ucnVuSWQsXG4gICAgICBlbmNyeXB0aW9uS2V5LFxuICAgICAgd29ybGRDYXBhYmlsaXRpZXMsXG4gICAgICBnbG9iYWxUaGlzOiB2bUdsb2JhbFRoaXMsXG4gICAgICBvbldvcmtmbG93RXJyb3I6IHdvcmtmbG93RGlzY29udGludWF0aW9uLnJlamVjdCxcbiAgICAgIGV2ZW50c0NvbnN1bWVyLFxuICAgICAgLy8gQ29ycmVsYXRpb24gSURzIG11c3QgYmUgcmVwbGF5LXN0YWJsZS4gYHN0YXJ0ZWRBdGAgZGlmZmVycyBiZXR3ZWVuIGFcbiAgICAgIC8vIHR1cmJvIGRlbGl2ZXJ5IGFuZCBhIGxhdGVyIHNlcnZlci1iYWNrZWQgcmVwbGF5LCBzbyB1c2UgZml4ZWRUaW1lc3RhbXAuXG4gICAgICBnZW5lcmF0ZVVsaWQ6ICgpID0+IHVsaWQoZml4ZWRUaW1lc3RhbXApLFxuICAgICAgZ2VuZXJhdGVOYW5vaWQsXG4gICAgICBpbnZvY2F0aW9uc1F1ZXVlOiBuZXcgTWFwKCksXG4gICAgICAvLyBVc2UgZ2V0dGVyL3NldHRlciBzbyB0aGUgRXZlbnRzQ29uc3VtZXIncyBnZXRQcm9taXNlUXVldWUoKSBhbHdheXNcbiAgICAgIC8vIHNlZXMgdGhlIGxhdGVzdCBxdWV1ZSBzdGF0ZSBhcyBpdCdzIG11dGF0ZWQgYnkgc3RlcC9ob29rL3NsZWVwIGNhbGxiYWNrcy5cbiAgICAgIGdldCBwcm9taXNlUXVldWUoKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUXVldWVIb2xkZXIuY3VycmVudDtcbiAgICAgIH0sXG4gICAgICBzZXQgcHJvbWlzZVF1ZXVlKHZhbHVlOiBQcm9taXNlPHZvaWQ+KSB7XG4gICAgICAgIHByb21pc2VRdWV1ZUhvbGRlci5jdXJyZW50ID0gdmFsdWU7XG4gICAgICB9LFxuICAgICAgcGVuZGluZ0RlbGl2ZXJpZXM6IDAsXG4gICAgICBwZW5kaW5nRGVsaXZlcnlCYXJyaWVyczogbmV3IE1hcCgpLFxuICAgICAgcmVwbGF5UGF5bG9hZENhY2hlLFxuICAgIH07XG5cbiAgICAvLyBDb25zdW1lIHJ1biBsaWZlY3ljbGUgZXZlbnRzIC0gdGhlc2UgYXJlIHN0cnVjdHVyYWwgZXZlbnRzIHRoYXQgZG9uJ3RcbiAgICAvLyBuZWVkIHNwZWNpYWwgaGFuZGxpbmcgaW4gdGhlIHdvcmtmbG93LCBidXQgbXVzdCBiZSBjb25zdW1lZCB0byBhZHZhbmNlXG4gICAgLy8gcGFzdCB0aGVtIGluIHRoZSBldmVudCBsb2dcbiAgICB3b3JrZmxvd0NvbnRleHQuZXZlbnRzQ29uc3VtZXIuc3Vic2NyaWJlKChldmVudCkgPT4ge1xuICAgICAgaWYgKCFldmVudCkge1xuICAgICAgICByZXR1cm4gRXZlbnRDb25zdW1lclJlc3VsdC5Ob3RDb25zdW1lZDtcbiAgICAgIH1cblxuICAgICAgLy8gQ29uc3VtZSBydW5fY3JlYXRlZCAtIGV2ZXJ5IHJ1biBoYXMgZXhhY3RseSBvbmVcbiAgICAgIGlmIChldmVudC5ldmVudFR5cGUgPT09ICdydW5fY3JlYXRlZCcpIHtcbiAgICAgICAgcmV0dXJuIEV2ZW50Q29uc3VtZXJSZXN1bHQuQ29uc3VtZWQ7XG4gICAgICB9XG5cbiAgICAgIC8vIENvbnN1bWUgcnVuX3N0YXJ0ZWQgLSBldmVyeSBydW4gaGFzIGV4YWN0bHkgb25lXG4gICAgICBpZiAoZXZlbnQuZXZlbnRUeXBlID09PSAncnVuX3N0YXJ0ZWQnKSB7XG4gICAgICAgIHJldHVybiBFdmVudENvbnN1bWVyUmVzdWx0LkNvbnN1bWVkO1xuICAgICAgfVxuXG4gICAgICAvLyBBdHRyaWJ1dGUgd3JpdGVzIHBlcmZvcm1lZCBmcm9tIGEgc3RlcCBoYXZlIG5vIHdvcmtmbG93LWJvZHkgY2FsbCB0b1xuICAgICAgLy8gY29uc3VtZSB0aGVtIGR1cmluZyByZXBsYXk7IHRoZXkgYXJlIGFscmVhZHkgcmVmbGVjdGVkIGluIHRoZSBydW5cbiAgICAgIC8vIHNuYXBzaG90IGFuZCByZW1haW4gc3RydWN0dXJhbCB1bnRpbCBhIHJlYWQgQVBJIGlzIGludHJvZHVjZWQuXG4gICAgICBpZiAoXG4gICAgICAgIGV2ZW50LmV2ZW50VHlwZSA9PT0gJ2F0dHJfc2V0JyAmJlxuICAgICAgICBldmVudC5ldmVudERhdGEud3JpdGVyLnR5cGUgPT09ICdzdGVwJ1xuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBFdmVudENvbnN1bWVyUmVzdWx0LkNvbnN1bWVkO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gRXZlbnRDb25zdW1lclJlc3VsdC5Ob3RDb25zdW1lZDtcbiAgICB9KTtcblxuICAgIGNvbnN0IHVzZVN0ZXAgPSBjcmVhdGVVc2VTdGVwKHdvcmtmbG93Q29udGV4dCk7XG4gICAgY29uc3QgY3JlYXRlSG9vayA9IGNyZWF0ZUNyZWF0ZUhvb2sod29ya2Zsb3dDb250ZXh0KTtcbiAgICBjb25zdCBzbGVlcCA9IGNyZWF0ZVNsZWVwKHdvcmtmbG93Q29udGV4dCk7XG4gICAgY29uc3Qgc2V0QXR0cmlidXRlcyA9IGNyZWF0ZVNldEF0dHJpYnV0ZXMod29ya2Zsb3dDb250ZXh0KTtcblxuICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBgQHR5cGVzL25vZGVgIHNheXMgc3ltYm9sIGlzIG5vdCB2YWxpZCwgYnV0IGl0IGRvZXMgd29ya1xuICAgIHZtR2xvYmFsVGhpc1tXT1JLRkxPV19VU0VfU1RFUF0gPSB1c2VTdGVwO1xuICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBgQHR5cGVzL25vZGVgIHNheXMgc3ltYm9sIGlzIG5vdCB2YWxpZCwgYnV0IGl0IGRvZXMgd29ya1xuICAgIHZtR2xvYmFsVGhpc1tXT1JLRkxPV19TRVRfQVRUUklCVVRFU10gPSBzZXRBdHRyaWJ1dGVzO1xuICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBgQHR5cGVzL25vZGVgIHNheXMgc3ltYm9sIGlzIG5vdCB2YWxpZCwgYnV0IGl0IGRvZXMgd29ya1xuICAgIHZtR2xvYmFsVGhpc1tXT1JLRkxPV19DUkVBVEVfSE9PS10gPSBjcmVhdGVIb29rO1xuICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBgQHR5cGVzL25vZGVgIHNheXMgc3ltYm9sIGlzIG5vdCB2YWxpZCwgYnV0IGl0IGRvZXMgd29ya1xuICAgIHZtR2xvYmFsVGhpc1tXT1JLRkxPV19TTEVFUF0gPSBzbGVlcDtcbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIC0gYEB0eXBlcy9ub2RlYCBzYXlzIHN5bWJvbCBpcyBub3QgdmFsaWQsIGJ1dCBpdCBkb2VzIHdvcmtcbiAgICB2bUdsb2JhbFRoaXNbV09SS0ZMT1dfR0VUX1NUUkVBTV9JRF0gPSAobmFtZXNwYWNlPzogc3RyaW5nKSA9PlxuICAgICAgZ2V0V29ya2Zsb3dSdW5TdHJlYW1JZCh3b3JrZmxvd1J1bi5ydW5JZCwgbmFtZXNwYWNlKTtcblxuICAgIC8vIEZvciB0aGUgd29ya2Zsb3cgVk0sIHdlIHN0b3JlIHRoZSBjb250ZXh0IGluIGEgc3ltYm9sIG9uIHRoZSBgZ2xvYmFsVGhpc2Agb2JqZWN0XG4gICAgY29uc3QgY3R4OiBXb3JrZmxvd01ldGFkYXRhID0ge1xuICAgICAgd29ya2Zsb3dOYW1lOiB3b3JrZmxvd1J1bi53b3JrZmxvd05hbWUsXG4gICAgICB3b3JrZmxvd1J1bklkOiB3b3JrZmxvd1J1bi5ydW5JZCxcbiAgICAgIHdvcmtmbG93U3RhcnRlZEF0OiBuZXcgdm1HbG9iYWxUaGlzLkRhdGUoK3N0YXJ0ZWRBdCksXG4gICAgICB1cmw6IHdvcmtmbG93QmFzZVVybCxcbiAgICAgIGZlYXR1cmVzOiB7IGVuY3J5cHRpb246ICEhZW5jcnlwdGlvbktleSB9LFxuICAgIH07XG5cbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIC0gYEB0eXBlcy9ub2RlYCBzYXlzIHN5bWJvbCBpcyBub3QgdmFsaWQsIGJ1dCBpdCBkb2VzIHdvcmtcbiAgICB2bUdsb2JhbFRoaXNbV09SS0ZMT1dfQ09OVEVYVF9TWU1CT0xdID0gY3R4O1xuICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBgQHR5cGVzL25vZGVgIHNheXMgc3ltYm9sIGlzIG5vdCB2YWxpZCwgYnV0IGl0IGRvZXMgd29ya1xuICAgIHZtR2xvYmFsVGhpc1tTVEFCTEVfVUxJRF0gPSB1bGlkO1xuXG4gICAgLy8gV29ya2Zsb3cgY29kZSBtdXN0IGltcG9ydCB0aGUgZGV0ZXJtaW5pc3RpYyBgZmV0Y2hgIHN0ZXAgZnJvbSBgd29ya2Zsb3dgLlxuICAgIHZtR2xvYmFsVGhpcy5mZXRjaCA9ICgpID0+IHtcbiAgICAgIHRocm93IG5ldyB2bUdsb2JhbFRoaXMuRXJyb3IoXG4gICAgICAgIGBHbG9iYWwgXCJmZXRjaFwiIGlzIHVuYXZhaWxhYmxlIGluIHdvcmtmbG93IGZ1bmN0aW9ucy4gVXNlIHRoZSBcImZldGNoXCIgc3RlcCBmdW5jdGlvbiBmcm9tIFwid29ya2Zsb3dcIiB0byBtYWtlIEhUVFAgcmVxdWVzdHMuXFxuXFxuTGVhcm4gbW9yZTogaHR0cHM6Ly93b3JrZmxvdy1zZGsuZGV2L2Vyci8ke0VSUk9SX1NMVUdTLkZFVENIX0lOX1dPUktGTE9XX0ZVTkNUSU9OfWBcbiAgICAgICk7XG4gICAgfTtcblxuICAgIC8vIE92ZXJyaWRlIHRpbWVvdXQvaW50ZXJ2YWwgZnVuY3Rpb25zIHRvIHRocm93IGhlbHBmdWwgZXJyb3JzXG4gICAgLy8gVGhlc2UgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gd29ya2Zsb3cgZnVuY3Rpb25zIGJlY2F1c2UgdGhleSByZWx5IG9uXG4gICAgLy8gYXN5bmNocm9ub3VzIHNjaGVkdWxpbmcgd2hpY2ggYnJlYWtzIGRldGVybWluaXN0aWMgcmVwbGF5XG4gICAgY29uc3QgdGltZW91dEVycm9yTWVzc2FnZSA9XG4gICAgICAnVGltZW91dCBmdW5jdGlvbnMgbGlrZSBcInNldFRpbWVvdXRcIiBhbmQgXCJzZXRJbnRlcnZhbFwiIGFyZSBub3Qgc3VwcG9ydGVkIGluIHdvcmtmbG93IGZ1bmN0aW9ucy4gVXNlIHRoZSBcInNsZWVwXCIgZnVuY3Rpb24gZnJvbSBcIndvcmtmbG93XCIgZm9yIHRpbWUtYmFzZWQgZGVsYXlzLic7XG5cbiAgICAodm1HbG9iYWxUaGlzIGFzIGFueSkuc2V0VGltZW91dCA9ICgpID0+IHtcbiAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcih0aW1lb3V0RXJyb3JNZXNzYWdlLCB7XG4gICAgICAgIHNsdWc6IEVSUk9SX1NMVUdTLlRJTUVPVVRfRlVOQ1RJT05TX0lOX1dPUktGTE9XLFxuICAgICAgfSk7XG4gICAgfTtcbiAgICAodm1HbG9iYWxUaGlzIGFzIGFueSkuc2V0SW50ZXJ2YWwgPSAoKSA9PiB7XG4gICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IodGltZW91dEVycm9yTWVzc2FnZSwge1xuICAgICAgICBzbHVnOiBFUlJPUl9TTFVHUy5USU1FT1VUX0ZVTkNUSU9OU19JTl9XT1JLRkxPVyxcbiAgICAgIH0pO1xuICAgIH07XG4gICAgKHZtR2xvYmFsVGhpcyBhcyBhbnkpLmNsZWFyVGltZW91dCA9ICgpID0+IHtcbiAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcih0aW1lb3V0RXJyb3JNZXNzYWdlLCB7XG4gICAgICAgIHNsdWc6IEVSUk9SX1NMVUdTLlRJTUVPVVRfRlVOQ1RJT05TX0lOX1dPUktGTE9XLFxuICAgICAgfSk7XG4gICAgfTtcbiAgICAodm1HbG9iYWxUaGlzIGFzIGFueSkuY2xlYXJJbnRlcnZhbCA9ICgpID0+IHtcbiAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcih0aW1lb3V0RXJyb3JNZXNzYWdlLCB7XG4gICAgICAgIHNsdWc6IEVSUk9SX1NMVUdTLlRJTUVPVVRfRlVOQ1RJT05TX0lOX1dPUktGTE9XLFxuICAgICAgfSk7XG4gICAgfTtcbiAgICAodm1HbG9iYWxUaGlzIGFzIGFueSkuc2V0SW1tZWRpYXRlID0gKCkgPT4ge1xuICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKHRpbWVvdXRFcnJvck1lc3NhZ2UsIHtcbiAgICAgICAgc2x1ZzogRVJST1JfU0xVR1MuVElNRU9VVF9GVU5DVElPTlNfSU5fV09SS0ZMT1csXG4gICAgICB9KTtcbiAgICB9O1xuICAgICh2bUdsb2JhbFRoaXMgYXMgYW55KS5jbGVhckltbWVkaWF0ZSA9ICgpID0+IHtcbiAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcih0aW1lb3V0RXJyb3JNZXNzYWdlLCB7XG4gICAgICAgIHNsdWc6IEVSUk9SX1NMVUdTLlRJTUVPVVRfRlVOQ1RJT05TX0lOX1dPUktGTE9XLFxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8vIGBBYm9ydENvbnRyb2xsZXJgIGFuZCBgQWJvcnRTaWduYWxgIGluIHRoZSB3b3JrZmxvdyBWTSBhcmUgaG9vay1iYWNrZWRcbiAgICAvLyBmb3IgZGV0ZXJtaW5pc3RpYyByZXBsYXkuIFRoZSBjb250cm9sbGVyJ3MgYWJvcnQoKSBxdWV1ZXMgYSBob29rIHJlc3VtcHRpb24sXG4gICAgLy8gYW5kIHNpZ25hbC5hYm9ydGVkIGlzIHVwZGF0ZWQgd2hlbiB0aGUgaG9vayBldmVudCBpcyBwcm9jZXNzZWQgZHVyaW5nIHJlcGxheS5cbiAgICAodm1HbG9iYWxUaGlzIGFzIGFueSkuQWJvcnRDb250cm9sbGVyID1cbiAgICAgIGNyZWF0ZUNyZWF0ZUFib3J0Q29udHJvbGxlcih3b3JrZmxvd0NvbnRleHQpO1xuICAgIGNvbnN0IGFib3J0U2lnbmFsU3RhdGljcyA9IGNyZWF0ZUFib3J0U2lnbmFsU3RhdGljcygpO1xuICAgICh2bUdsb2JhbFRoaXMgYXMgYW55KS5BYm9ydFNpZ25hbCA9IHtcbiAgICAgIGFib3J0OiBhYm9ydFNpZ25hbFN0YXRpY3MuYWJvcnQsXG4gICAgICBhbnk6IGFib3J0U2lnbmFsU3RhdGljcy5hbnksXG4gICAgICB0aW1lb3V0OiBhYm9ydFNpZ25hbFN0YXRpY3MudGltZW91dCxcbiAgICB9O1xuXG4gICAgLy8gYFJlcXVlc3RgIGFuZCBgUmVzcG9uc2VgIGFyZSBzcGVjaWFsIGJ1aWx0LWluIGNsYXNzZXMgdGhhdCBpbnZva2Ugc3RlcHNcbiAgICAvLyBmb3IgdGhlIGBqc29uKClgLCBgdGV4dCgpYCBhbmQgYGFycmF5QnVmZmVyKClgIGluc3RhbmNlIG1ldGhvZHNcbiAgICBjbGFzcyBSZXF1ZXN0IGltcGxlbWVudHMgZ2xvYmFsVGhpcy5SZXF1ZXN0IHtcbiAgICAgIGNhY2hlITogZ2xvYmFsVGhpcy5SZXF1ZXN0WydjYWNoZSddO1xuICAgICAgY3JlZGVudGlhbHMhOiBnbG9iYWxUaGlzLlJlcXVlc3RbJ2NyZWRlbnRpYWxzJ107XG4gICAgICBkZXN0aW5hdGlvbiE6IGdsb2JhbFRoaXMuUmVxdWVzdFsnZGVzdGluYXRpb24nXTtcbiAgICAgIGhlYWRlcnMhOiBIZWFkZXJzO1xuICAgICAgaW50ZWdyaXR5ITogc3RyaW5nO1xuICAgICAgbWV0aG9kITogc3RyaW5nO1xuICAgICAgbW9kZSE6IGdsb2JhbFRoaXMuUmVxdWVzdFsnbW9kZSddO1xuICAgICAgcmVkaXJlY3QhOiBnbG9iYWxUaGlzLlJlcXVlc3RbJ3JlZGlyZWN0J107XG4gICAgICByZWZlcnJlciE6IHN0cmluZztcbiAgICAgIHJlZmVycmVyUG9saWN5ITogZ2xvYmFsVGhpcy5SZXF1ZXN0WydyZWZlcnJlclBvbGljeSddO1xuICAgICAgdXJsITogc3RyaW5nO1xuICAgICAga2VlcGFsaXZlITogYm9vbGVhbjtcbiAgICAgIHNpZ25hbCE6IEFib3J0U2lnbmFsO1xuICAgICAgZHVwbGV4ITogJ2hhbGYnO1xuICAgICAgYm9keSE6IFJlYWRhYmxlU3RyZWFtPGFueT4gfCBudWxsO1xuXG4gICAgICBjb25zdHJ1Y3RvcihpbnB1dDogYW55LCBpbml0PzogUmVxdWVzdEluaXQpIHtcbiAgICAgICAgLy8gSGFuZGxlIFVSTCBpbnB1dFxuICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJyB8fCBpbnB1dCBpbnN0YW5jZW9mIHZtR2xvYmFsVGhpcy5VUkwpIHtcbiAgICAgICAgICBjb25zdCB1cmxTdHJpbmcgPSBTdHJpbmcoaW5wdXQpO1xuICAgICAgICAgIC8vIFZhbGlkYXRlIFVSTCBmb3JtYXRcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgbmV3IHZtR2xvYmFsVGhpcy5VUkwodXJsU3RyaW5nKTtcbiAgICAgICAgICAgIHRoaXMudXJsID0gdXJsU3RyaW5nO1xuICAgICAgICAgIH0gY2F0Y2ggKGNhdXNlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBGYWlsZWQgdG8gcGFyc2UgVVJMIGZyb20gJHt1cmxTdHJpbmd9YCwge1xuICAgICAgICAgICAgICBjYXVzZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBJbnB1dCBpcyBhIFJlcXVlc3Qgb2JqZWN0IC0gY2xvbmUgaXRzIHByb3BlcnRpZXNcbiAgICAgICAgICB0aGlzLnVybCA9IGlucHV0LnVybDtcbiAgICAgICAgICBpZiAoIWluaXQpIHtcbiAgICAgICAgICAgIHRoaXMubWV0aG9kID0gaW5wdXQubWV0aG9kO1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJzID0gbmV3IHZtR2xvYmFsVGhpcy5IZWFkZXJzKGlucHV0LmhlYWRlcnMpO1xuICAgICAgICAgICAgdGhpcy5ib2R5ID0gaW5wdXQuYm9keTtcbiAgICAgICAgICAgIHRoaXMubW9kZSA9IGlucHV0Lm1vZGU7XG4gICAgICAgICAgICB0aGlzLmNyZWRlbnRpYWxzID0gaW5wdXQuY3JlZGVudGlhbHM7XG4gICAgICAgICAgICB0aGlzLmNhY2hlID0gaW5wdXQuY2FjaGU7XG4gICAgICAgICAgICB0aGlzLnJlZGlyZWN0ID0gaW5wdXQucmVkaXJlY3Q7XG4gICAgICAgICAgICB0aGlzLnJlZmVycmVyID0gaW5wdXQucmVmZXJyZXI7XG4gICAgICAgICAgICB0aGlzLnJlZmVycmVyUG9saWN5ID0gaW5wdXQucmVmZXJyZXJQb2xpY3k7XG4gICAgICAgICAgICB0aGlzLmludGVncml0eSA9IGlucHV0LmludGVncml0eTtcbiAgICAgICAgICAgIHRoaXMua2VlcGFsaXZlID0gaW5wdXQua2VlcGFsaXZlO1xuICAgICAgICAgICAgdGhpcy5zaWduYWwgPSBpbnB1dC5zaWduYWw7XG4gICAgICAgICAgICB0aGlzLmR1cGxleCA9IGlucHV0LmR1cGxleDtcbiAgICAgICAgICAgIHRoaXMuZGVzdGluYXRpb24gPSBpbnB1dC5kZXN0aW5hdGlvbjtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gSWYgaW5pdCBpcyBwcm92aWRlZCwgbWVyZ2U6IHVzZSBzb3VyY2UgcHJvcGVydGllcywgdGhlbiBvdmVycmlkZSB3aXRoIGluaXRcbiAgICAgICAgICAvLyBDb3B5IGFsbCBwcm9wZXJ0aWVzIGZyb20gdGhlIHNvdXJjZSBSZXF1ZXN0IGZpcnN0XG4gICAgICAgICAgdGhpcy5tZXRob2QgPSBpbnB1dC5tZXRob2Q7XG4gICAgICAgICAgdGhpcy5oZWFkZXJzID0gbmV3IHZtR2xvYmFsVGhpcy5IZWFkZXJzKGlucHV0LmhlYWRlcnMpO1xuICAgICAgICAgIHRoaXMuYm9keSA9IGlucHV0LmJvZHk7XG4gICAgICAgICAgdGhpcy5tb2RlID0gaW5wdXQubW9kZTtcbiAgICAgICAgICB0aGlzLmNyZWRlbnRpYWxzID0gaW5wdXQuY3JlZGVudGlhbHM7XG4gICAgICAgICAgdGhpcy5jYWNoZSA9IGlucHV0LmNhY2hlO1xuICAgICAgICAgIHRoaXMucmVkaXJlY3QgPSBpbnB1dC5yZWRpcmVjdDtcbiAgICAgICAgICB0aGlzLnJlZmVycmVyID0gaW5wdXQucmVmZXJyZXI7XG4gICAgICAgICAgdGhpcy5yZWZlcnJlclBvbGljeSA9IGlucHV0LnJlZmVycmVyUG9saWN5O1xuICAgICAgICAgIHRoaXMuaW50ZWdyaXR5ID0gaW5wdXQuaW50ZWdyaXR5O1xuICAgICAgICAgIHRoaXMua2VlcGFsaXZlID0gaW5wdXQua2VlcGFsaXZlO1xuICAgICAgICAgIHRoaXMuc2lnbmFsID0gaW5wdXQuc2lnbmFsO1xuICAgICAgICAgIHRoaXMuZHVwbGV4ID0gaW5wdXQuZHVwbGV4O1xuICAgICAgICAgIHRoaXMuZGVzdGluYXRpb24gPSBpbnB1dC5kZXN0aW5hdGlvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE92ZXJyaWRlIHdpdGggaW5pdCBvcHRpb25zIGlmIHByb3ZpZGVkXG4gICAgICAgIC8vIFNldCBtZXRob2RcbiAgICAgICAgaWYgKGluaXQ/Lm1ldGhvZCkge1xuICAgICAgICAgIHRoaXMubWV0aG9kID0gaW5pdC5tZXRob2QudG9VcHBlckNhc2UoKTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5tZXRob2QgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgLy8gRmFsbGJhY2sgdG8gZGVmYXVsdCBmb3Igc3RyaW5nIGlucHV0IGNhc2VcbiAgICAgICAgICB0aGlzLm1ldGhvZCA9ICdHRVQnO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IGhlYWRlcnNcbiAgICAgICAgaWYgKGluaXQ/LmhlYWRlcnMpIHtcbiAgICAgICAgICB0aGlzLmhlYWRlcnMgPSBuZXcgdm1HbG9iYWxUaGlzLkhlYWRlcnMoaW5pdC5oZWFkZXJzKTtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICB0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICAgaW5wdXQgaW5zdGFuY2VvZiB2bUdsb2JhbFRoaXMuVVJMXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIEZvciBzdHJpbmcvVVJMIGlucHV0LCBjcmVhdGUgZW1wdHkgaGVhZGVyc1xuICAgICAgICAgIHRoaXMuaGVhZGVycyA9IG5ldyB2bUdsb2JhbFRoaXMuSGVhZGVycygpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IG90aGVyIHByb3BlcnRpZXMgd2l0aCBpbml0IHZhbHVlcyBvciBkZWZhdWx0c1xuICAgICAgICBpZiAoaW5pdD8ubW9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhpcy5tb2RlID0gaW5pdC5tb2RlO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLm1vZGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhpcy5tb2RlID0gJ2NvcnMnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGluaXQ/LmNyZWRlbnRpYWxzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aGlzLmNyZWRlbnRpYWxzID0gaW5pdC5jcmVkZW50aWFscztcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5jcmVkZW50aWFscyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aGlzLmNyZWRlbnRpYWxzID0gJ3NhbWUtb3JpZ2luJztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGBhbnlgIGNhc3QgaGVyZSBiZWNhdXNlIEB0eXBlcy9ub2RlIHYyMiBkb2VzIG5vdCB5ZXQgaGF2ZSBgY2FjaGVgXG4gICAgICAgIGlmICgoaW5pdCBhcyBhbnkpPy5jYWNoZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhpcy5jYWNoZSA9IChpbml0IGFzIGFueSkuY2FjaGU7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuY2FjaGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhpcy5jYWNoZSA9ICdkZWZhdWx0JztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbml0Py5yZWRpcmVjdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhpcy5yZWRpcmVjdCA9IGluaXQucmVkaXJlY3Q7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMucmVkaXJlY3QgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhpcy5yZWRpcmVjdCA9ICdmb2xsb3cnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGluaXQ/LnJlZmVycmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aGlzLnJlZmVycmVyID0gaW5pdC5yZWZlcnJlcjtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5yZWZlcnJlciAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aGlzLnJlZmVycmVyID0gJ2Fib3V0OmNsaWVudCc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaW5pdD8ucmVmZXJyZXJQb2xpY3kgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRoaXMucmVmZXJyZXJQb2xpY3kgPSBpbml0LnJlZmVycmVyUG9saWN5O1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLnJlZmVycmVyUG9saWN5ICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRoaXMucmVmZXJyZXJQb2xpY3kgPSAnJztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbml0Py5pbnRlZ3JpdHkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRoaXMuaW50ZWdyaXR5ID0gaW5pdC5pbnRlZ3JpdHk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuaW50ZWdyaXR5ICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRoaXMuaW50ZWdyaXR5ID0gJyc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaW5pdD8ua2VlcGFsaXZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aGlzLmtlZXBhbGl2ZSA9IGluaXQua2VlcGFsaXZlO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLmtlZXBhbGl2ZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgdGhpcy5rZWVwYWxpdmUgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbml0Py5zaWduYWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBBYm9ydFNpZ25hbCBzdHViXG4gICAgICAgICAgdGhpcy5zaWduYWwgPSBpbml0LnNpZ25hbDtcbiAgICAgICAgfSBlbHNlIGlmICghdGhpcy5zaWduYWwpIHtcbiAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIC0gQWJvcnRTaWduYWwgc3R1YlxuICAgICAgICAgIHRoaXMuc2lnbmFsID0geyBhYm9ydGVkOiBmYWxzZSB9O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLmR1cGxleCkge1xuICAgICAgICAgIHRoaXMuZHVwbGV4ID0gJ2hhbGYnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLmRlc3RpbmF0aW9uKSB7XG4gICAgICAgICAgdGhpcy5kZXN0aW5hdGlvbiA9ICdkb2N1bWVudCc7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBib2R5ID0gaW5pdD8uYm9keTtcblxuICAgICAgICAvLyBWYWxpZGF0ZSB0aGF0IEdFVC9IRUFEIG1ldGhvZHMgZG9uJ3QgaGF2ZSBhIGJvZHlcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGJvZHkgIT09IG51bGwgJiZcbiAgICAgICAgICBib2R5ICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAodGhpcy5tZXRob2QgPT09ICdHRVQnIHx8IHRoaXMubWV0aG9kID09PSAnSEVBRCcpXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFJlcXVlc3Qgd2l0aCBHRVQvSEVBRCBtZXRob2QgY2Fubm90IGhhdmUgYm9keS5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFN0b3JlIHRoZSBvcmlnaW5hbCBCb2R5SW5pdCBmb3Igc2VyaWFsaXphdGlvblxuICAgICAgICBpZiAoYm9keSAhPT0gbnVsbCAmJiBib2R5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAvLyBDcmVhdGUgYSBcImZha2VcIiBSZWFkYWJsZVN0cmVhbSB0aGF0IHN0b3JlcyB0aGUgb3JpZ2luYWwgYm9keVxuICAgICAgICAgIC8vIFRoaXMgYXZvaWRzIGRvaW5nIGFzeW5jIHdvcmsgZHVyaW5nIHdvcmtmbG93IHJlcGxheVxuICAgICAgICAgIHRoaXMuYm9keSA9IE9iamVjdC5jcmVhdGUodm1HbG9iYWxUaGlzLlJlYWRhYmxlU3RyZWFtLnByb3RvdHlwZSwge1xuICAgICAgICAgICAgW0JPRFlfSU5JVF9TWU1CT0xdOiB7XG4gICAgICAgICAgICAgIHZhbHVlOiBib2R5LFxuICAgICAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuYm9keSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY2xvbmUoKTogUmVxdWVzdCB7XG4gICAgICAgIEVOT1RTVVAoKTtcbiAgICAgIH1cblxuICAgICAgZ2V0IGJvZHlVc2VkKCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIC8vIFRPRE86IGltcGxlbWVudCB0aGVzZVxuICAgICAgYmxvYiE6ICgpID0+IFByb21pc2U8QmxvYj47XG4gICAgICBmb3JtRGF0YSE6ICgpID0+IFByb21pc2U8Rm9ybURhdGE+O1xuXG4gICAgICBhcnJheUJ1ZmZlciE6ICgpID0+IFByb21pc2U8QXJyYXlCdWZmZXI+O1xuICAgICAganNvbiE6ICgpID0+IFByb21pc2U8YW55PjtcbiAgICAgIHRleHQhOiAoKSA9PiBQcm9taXNlPHN0cmluZz47XG5cbiAgICAgIGFzeW5jIGJ5dGVzKCkge1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYXdhaXQgdGhpcy5hcnJheUJ1ZmZlcigpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdm1HbG9iYWxUaGlzLlJlcXVlc3QgPSBSZXF1ZXN0O1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoUmVxdWVzdC5wcm90b3R5cGUsIHtcbiAgICAgIGFycmF5QnVmZmVyOiB7XG4gICAgICAgIHZhbHVlOiB1c2VTdGVwPFtdLCBBcnJheUJ1ZmZlcj4oJ19fYnVpbHRpbl9yZXNwb25zZV9hcnJheV9idWZmZXInKSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIH0sXG4gICAgICBqc29uOiB7XG4gICAgICAgIHZhbHVlOiB1c2VTdGVwPFtdLCBhbnk+KCdfX2J1aWx0aW5fcmVzcG9uc2VfanNvbicpLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgfSxcbiAgICAgIHRleHQ6IHtcbiAgICAgICAgdmFsdWU6IHVzZVN0ZXA8W10sIHN0cmluZz4oJ19fYnVpbHRpbl9yZXNwb25zZV90ZXh0JyksXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY2xhc3MgUmVzcG9uc2UgaW1wbGVtZW50cyBnbG9iYWxUaGlzLlJlc3BvbnNlIHtcbiAgICAgIHR5cGUhOiBnbG9iYWxUaGlzLlJlc3BvbnNlWyd0eXBlJ107XG4gICAgICB1cmwhOiBzdHJpbmc7XG4gICAgICBzdGF0dXMhOiBudW1iZXI7XG4gICAgICBzdGF0dXNUZXh0ITogc3RyaW5nO1xuICAgICAgYm9keSE6IFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+IHwgbnVsbDtcbiAgICAgIGhlYWRlcnMhOiBIZWFkZXJzO1xuICAgICAgcmVkaXJlY3RlZCE6IGJvb2xlYW47XG5cbiAgICAgIGNvbnN0cnVjdG9yKGJvZHk/OiBhbnksIGluaXQ/OiBSZXNwb25zZUluaXQpIHtcbiAgICAgICAgdGhpcy5zdGF0dXMgPSBpbml0Py5zdGF0dXMgPz8gMjAwO1xuICAgICAgICB0aGlzLnN0YXR1c1RleHQgPSBpbml0Py5zdGF0dXNUZXh0ID8/ICcnO1xuICAgICAgICB0aGlzLmhlYWRlcnMgPSBuZXcgdm1HbG9iYWxUaGlzLkhlYWRlcnMoaW5pdD8uaGVhZGVycyk7XG4gICAgICAgIHRoaXMudHlwZSA9ICdkZWZhdWx0JztcbiAgICAgICAgdGhpcy51cmwgPSAnJztcbiAgICAgICAgdGhpcy5yZWRpcmVjdGVkID0gZmFsc2U7XG5cbiAgICAgICAgLy8gVmFsaWRhdGUgdGhhdCBudWxsLWJvZHkgc3RhdHVzIGNvZGVzIGRvbid0IGhhdmUgYSBib2R5XG4gICAgICAgIC8vIFBlciBIVFRQIHNwZWM6IDIwNCAoTm8gQ29udGVudCksIDIwNSAoUmVzZXQgQ29udGVudCksIGFuZCAzMDQgKE5vdCBNb2RpZmllZClcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGJvZHkgIT09IG51bGwgJiZcbiAgICAgICAgICBib2R5ICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAodGhpcy5zdGF0dXMgPT09IDIwNCB8fCB0aGlzLnN0YXR1cyA9PT0gMjA1IHx8IHRoaXMuc3RhdHVzID09PSAzMDQpXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICBgUmVzcG9uc2UgY29uc3RydWN0b3I6IEludmFsaWQgcmVzcG9uc2Ugc3RhdHVzIGNvZGUgJHt0aGlzLnN0YXR1c31gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFN0b3JlIHRoZSBvcmlnaW5hbCBCb2R5SW5pdCBmb3Igc2VyaWFsaXphdGlvblxuICAgICAgICBpZiAoYm9keSAhPT0gbnVsbCAmJiBib2R5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAvLyBDcmVhdGUgYSBcImZha2VcIiBSZWFkYWJsZVN0cmVhbSB0aGF0IHN0b3JlcyB0aGUgb3JpZ2luYWwgYm9keVxuICAgICAgICAgIC8vIFRoaXMgYXZvaWRzIGRvaW5nIGFzeW5jIHdvcmsgZHVyaW5nIHdvcmtmbG93IHJlcGxheVxuICAgICAgICAgIHRoaXMuYm9keSA9IE9iamVjdC5jcmVhdGUodm1HbG9iYWxUaGlzLlJlYWRhYmxlU3RyZWFtLnByb3RvdHlwZSwge1xuICAgICAgICAgICAgW0JPRFlfSU5JVF9TWU1CT0xdOiB7XG4gICAgICAgICAgICAgIHZhbHVlOiBib2R5LFxuICAgICAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuYm9keSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVE9ETzogaW1wbGVtZW50IHRoZXNlXG4gICAgICBjbG9uZSE6ICgpID0+IFJlc3BvbnNlO1xuICAgICAgYmxvYiE6ICgpID0+IFByb21pc2U8Z2xvYmFsVGhpcy5CbG9iPjtcbiAgICAgIGZvcm1EYXRhITogKCkgPT4gUHJvbWlzZTxnbG9iYWxUaGlzLkZvcm1EYXRhPjtcblxuICAgICAgZ2V0IG9rKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zdGF0dXMgPj0gMjAwICYmIHRoaXMuc3RhdHVzIDwgMzAwO1xuICAgICAgfVxuXG4gICAgICBnZXQgYm9keVVzZWQoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgYXJyYXlCdWZmZXIhOiAoKSA9PiBQcm9taXNlPEFycmF5QnVmZmVyPjtcbiAgICAgIGpzb24hOiAoKSA9PiBQcm9taXNlPGFueT47XG4gICAgICB0ZXh0ITogKCkgPT4gUHJvbWlzZTxzdHJpbmc+O1xuXG4gICAgICBhc3luYyBieXRlcygpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGF3YWl0IHRoaXMuYXJyYXlCdWZmZXIoKSk7XG4gICAgICB9XG5cbiAgICAgIHN0YXRpYyBqc29uKGRhdGE6IGFueSwgaW5pdD86IFJlc3BvbnNlSW5pdCk6IFJlc3BvbnNlIHtcbiAgICAgICAgY29uc3QgYm9keSA9IEpTT04uc3RyaW5naWZ5KGRhdGEpO1xuICAgICAgICBjb25zdCBoZWFkZXJzID0gbmV3IHZtR2xvYmFsVGhpcy5IZWFkZXJzKGluaXQ/LmhlYWRlcnMpO1xuICAgICAgICBpZiAoIWhlYWRlcnMuaGFzKCdjb250ZW50LXR5cGUnKSkge1xuICAgICAgICAgIGhlYWRlcnMuc2V0KCdjb250ZW50LXR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UoYm9keSwgeyAuLi5pbml0LCBoZWFkZXJzIH0pO1xuICAgICAgfVxuXG4gICAgICBzdGF0aWMgZXJyb3IoKTogUmVzcG9uc2Uge1xuICAgICAgICBFTk9UU1VQKCk7XG4gICAgICB9XG5cbiAgICAgIHN0YXRpYyByZWRpcmVjdCh1cmw6IHN0cmluZyB8IFVSTCwgc3RhdHVzOiBudW1iZXIgPSAzMDIpOiBSZXNwb25zZSB7XG4gICAgICAgIC8vIFZhbGlkYXRlIHN0YXR1cyBjb2RlIC0gb25seSBzcGVjaWZpYyByZWRpcmVjdCBjb2RlcyBhcmUgYWxsb3dlZFxuICAgICAgICBpZiAoIVszMDEsIDMwMiwgMzAzLCAzMDcsIDMwOF0uaW5jbHVkZXMoc3RhdHVzKSkge1xuICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFxuICAgICAgICAgICAgYEludmFsaWQgcmVkaXJlY3Qgc3RhdHVzIGNvZGU6ICR7c3RhdHVzfS4gTXVzdCBiZSBvbmUgb2Y6IDMwMSwgMzAyLCAzMDMsIDMwNywgMzA4YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDcmVhdGUgcmVzcG9uc2Ugd2l0aCBMb2NhdGlvbiBoZWFkZXJcbiAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyB2bUdsb2JhbFRoaXMuSGVhZGVycygpO1xuICAgICAgICBoZWFkZXJzLnNldCgnTG9jYXRpb24nLCBTdHJpbmcodXJsKSk7XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBPYmplY3QuY3JlYXRlKFJlc3BvbnNlLnByb3RvdHlwZSk7XG4gICAgICAgIHJlc3BvbnNlLnN0YXR1cyA9IHN0YXR1cztcbiAgICAgICAgcmVzcG9uc2Uuc3RhdHVzVGV4dCA9ICcnO1xuICAgICAgICByZXNwb25zZS5oZWFkZXJzID0gaGVhZGVycztcbiAgICAgICAgcmVzcG9uc2UuYm9keSA9IG51bGw7XG4gICAgICAgIHJlc3BvbnNlLnR5cGUgPSAnZGVmYXVsdCc7XG4gICAgICAgIHJlc3BvbnNlLnVybCA9ICcnO1xuICAgICAgICByZXNwb25zZS5yZWRpcmVjdGVkID0gZmFsc2U7XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgfVxuICAgIH1cbiAgICB2bUdsb2JhbFRoaXMuUmVzcG9uc2UgPSBSZXNwb25zZTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlc3BvbnNlLnByb3RvdHlwZSwge1xuICAgICAgYXJyYXlCdWZmZXI6IHtcbiAgICAgICAgdmFsdWU6IHVzZVN0ZXA8W10sIEFycmF5QnVmZmVyPignX19idWlsdGluX3Jlc3BvbnNlX2FycmF5X2J1ZmZlcicpLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgfSxcbiAgICAgIGpzb246IHtcbiAgICAgICAgdmFsdWU6IHVzZVN0ZXA8W10sIGFueT4oJ19fYnVpbHRpbl9yZXNwb25zZV9qc29uJyksXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB9LFxuICAgICAgdGV4dDoge1xuICAgICAgICB2YWx1ZTogdXNlU3RlcDxbXSwgc3RyaW5nPignX19idWlsdGluX3Jlc3BvbnNlX3RleHQnKSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjbGFzcyBSZWFkYWJsZVN0cmVhbTxUPiBpbXBsZW1lbnRzIGdsb2JhbFRoaXMuUmVhZGFibGVTdHJlYW08VD4ge1xuICAgICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIEVOT1RTVVAoKTtcbiAgICAgIH1cblxuICAgICAgZ2V0IGxvY2tlZCgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBjYW5jZWwoKTogYW55IHtcbiAgICAgICAgRU5PVFNVUCgpO1xuICAgICAgfVxuXG4gICAgICBnZXRSZWFkZXIoKTogYW55IHtcbiAgICAgICAgRU5PVFNVUCgpO1xuICAgICAgfVxuXG4gICAgICBwaXBlVGhyb3VnaCgpOiBhbnkge1xuICAgICAgICBFTk9UU1VQKCk7XG4gICAgICB9XG5cbiAgICAgIHBpcGVUbygpOiBhbnkge1xuICAgICAgICBFTk9UU1VQKCk7XG4gICAgICB9XG5cbiAgICAgIHRlZSgpOiBhbnkge1xuICAgICAgICBFTk9UU1VQKCk7XG4gICAgICB9XG5cbiAgICAgIHZhbHVlcygpOiBhbnkge1xuICAgICAgICBFTk9UU1VQKCk7XG4gICAgICB9XG5cbiAgICAgIHN0YXRpYyBmcm9tKCk6IGFueSB7XG4gICAgICAgIEVOT1RTVVAoKTtcbiAgICAgIH1cblxuICAgICAgW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSgpOiBhbnkge1xuICAgICAgICBFTk9UU1VQKCk7XG4gICAgICB9XG4gICAgfVxuICAgIHZtR2xvYmFsVGhpcy5SZWFkYWJsZVN0cmVhbSA9IFJlYWRhYmxlU3RyZWFtO1xuXG4gICAgY2xhc3MgV3JpdGFibGVTdHJlYW08VD4gaW1wbGVtZW50cyBnbG9iYWxUaGlzLldyaXRhYmxlU3RyZWFtPFQ+IHtcbiAgICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBFTk9UU1VQKCk7XG4gICAgICB9XG5cbiAgICAgIGdldCBsb2NrZWQoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgYWJvcnQoKTogYW55IHtcbiAgICAgICAgRU5PVFNVUCgpO1xuICAgICAgfVxuXG4gICAgICBjbG9zZSgpOiBhbnkge1xuICAgICAgICBFTk9UU1VQKCk7XG4gICAgICB9XG5cbiAgICAgIGdldFdyaXRlcigpOiBhbnkge1xuICAgICAgICBFTk9UU1VQKCk7XG4gICAgICB9XG4gICAgfVxuICAgIHZtR2xvYmFsVGhpcy5Xcml0YWJsZVN0cmVhbSA9IFdyaXRhYmxlU3RyZWFtO1xuXG4gICAgY2xhc3MgVHJhbnNmb3JtU3RyZWFtPEksIE8+IGltcGxlbWVudHMgZ2xvYmFsVGhpcy5UcmFuc2Zvcm1TdHJlYW08SSwgTz4ge1xuICAgICAgcmVhZGFibGU6IGdsb2JhbFRoaXMuUmVhZGFibGVTdHJlYW08Tz47XG4gICAgICB3cml0YWJsZTogZ2xvYmFsVGhpcy5Xcml0YWJsZVN0cmVhbTxJPjtcblxuICAgICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIEVOT1RTVVAoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdm1HbG9iYWxUaGlzLlRyYW5zZm9ybVN0cmVhbSA9IFRyYW5zZm9ybVN0cmVhbTtcblxuICAgIHZtR2xvYmFsVGhpcy5jb25zb2xlID0gZ2xvYmFsVGhpcy5jb25zb2xlO1xuXG4gICAgLy8gRXhwb3NlIHRoZSByZXF1ZXN0LWNvbnRleHQgc3ltYm9sIHJlcXVpcmVkIGJ5IEFJIEdhdGV3YXkuXG4gICAgY29uc3QgU1lNQk9MX0ZPUl9SRVFfQ09OVEVYVCA9IFN5bWJvbC5mb3IoJ0B2ZXJjZWwvcmVxdWVzdC1jb250ZXh0Jyk7XG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciAtIGBAdHlwZXMvbm9kZWAgc2F5cyBzeW1ib2wgaXMgbm90IHZhbGlkLCBidXQgaXQgZG9lcyB3b3JrXG4gICAgdm1HbG9iYWxUaGlzW1NZTUJPTF9GT1JfUkVRX0NPTlRFWFRdID0gKGdsb2JhbFRoaXMgYXMgYW55KVtcbiAgICAgIFNZTUJPTF9GT1JfUkVRX0NPTlRFWFRcbiAgICBdO1xuXG4gICAgLy8gR2V0IGEgcmVmZXJlbmNlIHRvIHRoZSB1c2VyLWRlZmluZWQgd29ya2Zsb3cgZnVuY3Rpb24uXG4gICAgLy8gVGhlIGZpbGVuYW1lIHBhcmFtZXRlciBlbnN1cmVzIHN0YWNrIHRyYWNlcyBzaG93IGEgbWVhbmluZ2Z1bCBuYW1lXG4gICAgLy8gKGUuZy4sIFwiZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzXCIpIGluc3RlYWQgb2YgXCJldmFsbWFjaGluZS48YW5vbnltb3VzPlwiLlxuICAgIGNvbnN0IHBhcnNlZE5hbWUgPSBwYXJzZVdvcmtmbG93TmFtZSh3b3JrZmxvd1J1bi53b3JrZmxvd05hbWUpO1xuICAgIGNvbnN0IGZpbGVuYW1lID0gcGFyc2VkTmFtZT8ubW9kdWxlU3BlY2lmaWVyIHx8IHdvcmtmbG93UnVuLndvcmtmbG93TmFtZTtcblxuICAgIC8vIFJldXNlIGNvbXBpbGVkIHNjcmlwdHMgYnkgYChjb2RlLCBmaWxlbmFtZSlgOiBjb21waWxhdGlvbiBpcyBkZXRlcm1pbmlzdGljXG4gICAgLy8gYW5kIHRoZSBmaWxlbmFtZSBwcmVzZXJ2ZXMgd29ya2Zsb3cgc291cmNlIGF0dHJpYnV0aW9uIGluIHN0YWNrIHRyYWNlcy5cbiAgICAvLyBUaGUgYnVuZGxlIHJlZ2lzdGVycyB3b3JrZmxvd3Mgb24gYGdsb2JhbFRoaXMuX19wcml2YXRlX3dvcmtmbG93c2AuXG4gICAgcnVuQ2FjaGVkV29ya2Zsb3dTY3JpcHQod29ya2Zsb3dDb2RlLCBmaWxlbmFtZSwgY29udGV4dCk7XG4gICAgY29uc3Qgd29ya2Zsb3dGbiA9IHJ1bkNhY2hlZFdvcmtmbG93U2NyaXB0KFxuICAgICAgYGdsb2JhbFRoaXMuX19wcml2YXRlX3dvcmtmbG93cz8uZ2V0KCR7SlNPTi5zdHJpbmdpZnkod29ya2Zsb3dSdW4ud29ya2Zsb3dOYW1lKX0pYCxcbiAgICAgIGZpbGVuYW1lLFxuICAgICAgY29udGV4dFxuICAgICk7XG5cbiAgICBpZiAodHlwZW9mIHdvcmtmbG93Rm4gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93IG5ldyBXb3JrZmxvd05vdFJlZ2lzdGVyZWRFcnJvcih3b3JrZmxvd1J1bi53b3JrZmxvd05hbWUpO1xuICAgIH1cblxuICAgIC8vIENoYWluIHdvcmtmbG93IGFyZ3VtZW50IGh5ZHJhdGlvbiBvbnRvIHRoZSBwcm9taXNlUXVldWUgc28gdGhhdCB0aGVcbiAgICAvLyB1bmNvbnN1bWVkIGV2ZW50IGNoZWNrICh3aGljaCB3YWl0cyBmb3IgdGhlIHF1ZXVlIHRvIGRyYWluKSBkb2Vzbid0XG4gICAgLy8gZmlyZSBkdXJpbmcgdGhlIGFzeW5jIGdhcCBiZXR3ZWVuIHJ1bl9zdGFydGVkIGNvbnN1bXB0aW9uIGFuZCB0aGVcbiAgICAvLyB3b3JrZmxvdyBmdW5jdGlvbiBzdWJzY3JpYmluZyBpdHMgZmlyc3Qgc3RlcCBjYWxsYmFja3MuXG4gICAgbGV0IGFyZ3M6IHVua25vd25bXSA9IFtdO1xuICAgIHdvcmtmbG93Q29udGV4dC5wcm9taXNlUXVldWUgPSB3b3JrZmxvd0NvbnRleHQucHJvbWlzZVF1ZXVlLnRoZW4oXG4gICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHByZXBhcmVkID1cbiAgICAgICAgICBhd2FpdCByZXBsYXlQYXlsb2FkQ2FjaGUucHJlcGFyZVdvcmtmbG93SW5wdXQod29ya2Zsb3dSdW4pO1xuICAgICAgICBhcmdzID0gYXdhaXQgaHlkcmF0ZVdvcmtmbG93QXJndW1lbnRzKFxuICAgICAgICAgIHdvcmtmbG93UnVuLmlucHV0LFxuICAgICAgICAgIHdvcmtmbG93UnVuLnJ1bklkLFxuICAgICAgICAgIGVuY3J5cHRpb25LZXksXG4gICAgICAgICAgdm1HbG9iYWxUaGlzLFxuICAgICAgICAgIHt9LFxuICAgICAgICAgIHByZXBhcmVkXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgKTtcbiAgICBhd2FpdCB3b3JrZmxvd0NvbnRleHQucHJvbWlzZVF1ZXVlO1xuXG4gICAgc3Bhbj8uc2V0QXR0cmlidXRlcyh7XG4gICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dBcmd1bWVudHNDb3VudChhcmdzLmxlbmd0aCksXG4gICAgfSk7XG5cbiAgICAvLyBJbnZva2UgdXNlciB3b3JrZmxvd1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBQcm9taXNlLnJhY2UoW1xuICAgICAgICB3b3JrZmxvd0ZuKC4uLmFyZ3MpLFxuICAgICAgICB3b3JrZmxvd0Rpc2NvbnRpbnVhdGlvbi5wcm9taXNlLFxuICAgICAgXSk7XG5cbiAgICAgIGNvbnN0IGRlaHlkcmF0ZWQgPSBhd2FpdCBkZWh5ZHJhdGVXb3JrZmxvd1JldHVyblZhbHVlKFxuICAgICAgICByZXN1bHQsXG4gICAgICAgIHdvcmtmbG93UnVuLnJ1bklkLFxuICAgICAgICBlbmNyeXB0aW9uS2V5LFxuICAgICAgICB2bUdsb2JhbFRoaXMsXG4gICAgICAgIGZhbHNlLFxuICAgICAgICAvLyBPbmx5IGNvbXByZXNzaW9uLWNhcGFibGUgcnVucyAoc3BlYyA+PSA1KSBtYXkgd3JpdGUgY29tcHJlc3NlZFxuICAgICAgICAvLyBwYXlsb2Fkcy4gVGhlIHNlcmlhbGl6ZXIgdXNlcyB6c3RkIHdoZW4gc3VwcG9ydGVkIGFuZCBtYXkgdXNlIGd6aXAuXG4gICAgICAgICh3b3JrZmxvd1J1bi5zcGVjVmVyc2lvbiA/PyAwKSA+PSBTUEVDX1ZFUlNJT05fU1VQUE9SVFNfQ09NUFJFU1NJT05cbiAgICAgICk7XG5cbiAgICAgIHNwYW4/LnNldEF0dHJpYnV0ZXMoe1xuICAgICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dSZXN1bHRUeXBlKHR5cGVvZiByZXN1bHQpLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IGRyYWluUGVuZGluZ1F1ZXVlSXRlbXMoXG4gICAgICAgIHdvcmtmbG93UnVuLnJ1bklkLFxuICAgICAgICB3b3JrZmxvd0NvbnRleHQuaW52b2NhdGlvbnNRdWV1ZSxcbiAgICAgICAgdm1HbG9iYWxUaGlzLFxuICAgICAgICB3b3JrZmxvd1J1bixcbiAgICAgICAgJ2NvbXBsZXRlZCcsXG4gICAgICAgIHJ1blJlYWR5QmFycmllclxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIGRlaHlkcmF0ZWQ7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBDb250cm9sLWZsb3cgc2lnbmFscyBhcmUgaGFuZGxlZCBieSB0aGUgcnVudGltZSBhbmQgZG8gbm90IG1lYW4gdGhlXG4gICAgICAvLyB3b3JrZmxvdyBoYXMgdGVybWluYWxseSBmYWlsZWQuXG4gICAgICBpZiAoV29ya2Zsb3dTdXNwZW5zaW9uLmlzKGVycikgfHwgUmVwbGF5RGl2ZXJnZW5jZUVycm9yLmlzKGVycikpIHtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBkcmFpblBlbmRpbmdRdWV1ZUl0ZW1zKFxuICAgICAgICB3b3JrZmxvd1J1bi5ydW5JZCxcbiAgICAgICAgd29ya2Zsb3dDb250ZXh0Lmludm9jYXRpb25zUXVldWUsXG4gICAgICAgIHZtR2xvYmFsVGhpcyxcbiAgICAgICAgd29ya2Zsb3dSdW4sXG4gICAgICAgICdmYWlsZWQnLFxuICAgICAgICBydW5SZWFkeUJhcnJpZXJcbiAgICAgICk7XG5cbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gIH0pO1xufVxuIl19
849
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2Zsb3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvd29ya2Zsb3cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUNMLFdBQVcsRUFDWCxxQkFBcUIsRUFDckIsMEJBQTBCLEVBQzFCLG9CQUFvQixHQUNyQixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFDTCxxQkFBcUIsRUFFckIsYUFBYSxHQUNkLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFL0QsT0FBTyxFQUFFLGlDQUFpQyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDcEUsT0FBTyxLQUFLLE1BQU0sTUFBTSxRQUFRLENBQUM7QUFDakMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3hDLE9BQU8sRUFDTCw0QkFBNEIsRUFDNUIsOEJBQThCLEdBQy9CLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLG1CQUFtQixFQUFFLGNBQWMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRTNFLE9BQU8sRUFBRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDMUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUU1QyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDekQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzFELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUU5QyxPQUFPLEVBQ0wsNEJBQTRCLEVBQzVCLHdCQUF3QixHQUN6QixNQUFNLG9CQUFvQixDQUFDO0FB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ICdAb3BlbnRlbGVtZXRyeS9hcGknO1xuaW1wb3J0IHtcbiAgRVJST1JfU0xVR1MsXG4gIFJlcGxheURpdmVyZ2VuY2VFcnJvcixcbiAgV29ya2Zsb3dOb3RSZWdpc3RlcmVkRXJyb3IsXG4gIFdvcmtmbG93UnVudGltZUVycm9yLFxufSBmcm9tICdAd29ya2Zsb3cvZXJyb3JzJztcbmltcG9ydCB7XG4gIGNyZWF0ZVdvcmtmbG93QmFzZVVybCxcbiAgdHlwZSBQcm9taXNlV2l0aFJlc29sdmVycyxcbiAgd2l0aFJlc29sdmVycyxcbn0gZnJvbSAnQHdvcmtmbG93L3V0aWxzJztcbmltcG9ydCB7IHBhcnNlV29ya2Zsb3dOYW1lIH0gZnJvbSAnQHdvcmtmbG93L3V0aWxzL3BhcnNlLW5hbWUnO1xuaW1wb3J0IHR5cGUgeyBFdmVudCwgV29ya2Zsb3dSdW4sIFdvcmxkQ2FwYWJpbGl0aWVzIH0gZnJvbSAnQHdvcmtmbG93L3dvcmxkJztcbmltcG9ydCB7IFNQRUNfVkVSU0lPTl9TVVBQT1JUU19DT01QUkVTU0lPTiB9IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgKiBhcyBuYW5vaWQgZnJvbSAnbmFub2lkJztcbmltcG9ydCB7IG1vbm90b25pY0ZhY3RvcnkgfSBmcm9tICd1bGlkJztcbmltcG9ydCB7XG4gIGNyZWF0ZUNvcnJlbGF0aW9uSWRHZW5lcmF0b3IsXG4gIGlzUGVyS2luZENvcnJlbGF0aW9uSWRzRW5hYmxlZCxcbn0gZnJvbSAnLi9jb3JyZWxhdGlvbi1pZC5qcyc7XG5pbXBvcnQgeyBFdmVudENvbnN1bWVyUmVzdWx0LCBFdmVudHNDb25zdW1lciB9IGZyb20gJy4vZXZlbnRzLWNvbnN1bWVyLmpzJztcbmltcG9ydCB0eXBlIHsgUXVldWVJdGVtIH0gZnJvbSAnLi9nbG9iYWwuanMnO1xuaW1wb3J0IHsgRU5PVFNVUCwgV29ya2Zsb3dTdXNwZW5zaW9uIH0gZnJvbSAnLi9nbG9iYWwuanMnO1xuaW1wb3J0IHsgcnVudGltZUxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyLmpzJztcbmltcG9ydCB0eXBlIHsgV29ya2Zsb3dPcmNoZXN0cmF0b3JDb250ZXh0IH0gZnJvbSAnLi9wcml2YXRlLmpzJztcbmltcG9ydCB7IFJlcGxheVBheWxvYWRDYWNoZSB9IGZyb20gJy4vcmVwbGF5LXBheWxvYWQtY2FjaGUuanMnO1xuaW1wb3J0IHsgZ2V0UG9ydExhenkgfSBmcm9tICcuL3J1bnRpbWUvZ2V0LXBvcnQtbGF6eS5qcyc7XG5pbXBvcnQgeyBydW5JZENyZWF0ZWRBdCB9IGZyb20gJy4vcnVudGltZS9ydW4taWQtdGltZS5qcyc7XG5pbXBvcnQgeyBoYW5kbGVTdXNwZW5zaW9uIH0gZnJvbSAnLi9ydW50aW1lL3N1c3BlbnNpb24taGFuZGxlci5qcyc7XG5pbXBvcnQgeyBnZXRXb3JsZCB9IGZyb20gJy4vcnVudGltZS93b3JsZC5qcyc7XG5pbXBvcnQgdHlwZSB7IFBheWxvYWRLZXkgfSBmcm9tICcuL3NlcmlhbGl6YXRpb24vZW5jcnlwdGlvbi5qcyc7XG5pbXBvcnQge1xuICBkZWh5ZHJhdGVXb3JrZmxvd1JldHVyblZhbHVlLFxuICBoeWRyYXRlV29ya2Zsb3dBcmd1bWVudHMsXG59IGZyb20gJy4vc2VyaWFsaXphdGlvbi5qcyc7XG5pbXBvcnQgeyBjcmVhdGVVc2VTdGVwIH0gZnJvbSAnLi9zdGVwLmpzJztcbmltcG9ydCB7XG4gIEJPRFlfSU5JVF9TWU1CT0wsXG4gIFNUQUJMRV9VTElELFxuICBXT1JLRkxPV19DUkVBVEVfSE9PSyxcbiAgV09SS0ZMT1dfR0VUX1NUUkVBTV9JRCxcbiAgV09SS0ZMT1dfU0VUX0FUVFJJQlVURVMsXG4gIFdPUktGTE9XX1NMRUVQLFxuICBXT1JLRkxPV19VU0VfU1RFUCxcbn0gZnJvbSAnLi9zeW1ib2xzLmpzJztcbmltcG9ydCAqIGFzIEF0dHJpYnV0ZSBmcm9tICcuL3RlbGVtZXRyeS9zZW1hbnRpYy1jb252ZW50aW9ucy5qcyc7XG5pbXBvcnQgeyBhcHBseVdvcmtmbG93U3VzcGVuc2lvblRvU3BhbiwgdHJhY2UgfSBmcm9tICcuL3RlbGVtZXRyeS5qcyc7XG5pbXBvcnQgeyBnZXRXb3JrZmxvd1J1blN0cmVhbUlkIH0gZnJvbSAnLi91dGlsLmpzJztcbmltcG9ydCB7IGNyZWF0ZUNvbnRleHQgfSBmcm9tICcuL3ZtL2luZGV4LmpzJztcbmltcG9ydCB7IHJ1bkNhY2hlZFdvcmtmbG93U2NyaXB0IH0gZnJvbSAnLi92bS9zY3JpcHQtY2FjaGUuanMnO1xuaW1wb3J0IHtcbiAgY3JlYXRlQWJvcnRTaWduYWxTdGF0aWNzLFxuICBjcmVhdGVDcmVhdGVBYm9ydENvbnRyb2xsZXIsXG59IGZyb20gJy4vd29ya2Zsb3cvYWJvcnQtY29udHJvbGxlci5qcyc7XG5pbXBvcnQgeyBjcmVhdGVTZXRBdHRyaWJ1dGVzIH0gZnJvbSAnLi93b3JrZmxvdy9hdHRyaWJ1dGUtZGlzcGF0Y2hlci5qcyc7XG5pbXBvcnQgdHlwZSB7IFdvcmtmbG93TWV0YWRhdGEgfSBmcm9tICcuL3dvcmtmbG93L2dldC13b3JrZmxvdy1tZXRhZGF0YS5qcyc7XG5pbXBvcnQgeyBXT1JLRkxPV19DT05URVhUX1NZTUJPTCB9IGZyb20gJy4vd29ya2Zsb3cvZ2V0LXdvcmtmbG93LW1ldGFkYXRhLmpzJztcbmltcG9ydCB7IGNyZWF0ZUNyZWF0ZUhvb2sgfSBmcm9tICcuL3dvcmtmbG93L2hvb2suanMnO1xuaW1wb3J0IHsgY3JlYXRlU2xlZXAgfSBmcm9tICcuL3dvcmtmbG93L3NsZWVwLmpzJztcblxuLyoqXG4gKiBEcmFpbiBwZW5kaW5nIHF1ZXVlIGl0ZW1zIGF0IHdvcmtmbG93IGNvbXBsZXRpb24gKHN1Y2Nlc3Mgb3IgZmFpbHVyZSkuXG4gKlxuICogVHJlYXRzIGNvbXBsZXRpb24gYXMgYSBmaW5hbCBzdXNwZW5zaW9uIHNvIHVuYXdhaXRlZCBob29rLCB3YWl0LCBhbmRcbiAqIGF0dHJpYnV0ZSBvcGVyYXRpb25zIGFyZSByZWNvcmRlZCBiZWZvcmUgdGhlIHJ1biBiZWNvbWVzIHRlcm1pbmFsLiBUaGlzXG4gKiBhbHNvIGxldHMgYSBmaW5hbCBgY29udHJvbGxlci5hYm9ydCgpYCByZWFjaCBpbi1mbGlnaHQgc3RlcHMuXG4gKlxuICogSXQgcmVjb3JkcyBgKl9jcmVhdGVkYCBhbmQgbmF0aXZlIGF0dHJpYnV0ZSBldmVudHMsIGJ1dCBuZXZlciBleGVjdXRlcyBzdGVwXG4gKiBib2RpZXM6IGBzdGVwX3N0YXJ0ZWRgIGlzIHJlamVjdGVkIGFmdGVyIHRoZSBydW4gYmVjb21lcyB0ZXJtaW5hbC4gQVxuICogZmlyZS1hbmQtZm9yZ2V0IHN0ZXAgdGhlcmVmb3JlIG5lZWRzIGEgbGF0ZXIgc3VzcGVuc2lvbiB0byBiZSBzY2hlZHVsZWQuXG4gKlxuICogRHJhaW4gZmFpbHVyZXMgZG8gbm90IGNoYW5nZSB0aGUgd29ya2Zsb3cncyB0ZXJtaW5hbCBvdXRjb21lLlxuICovXG5hc3luYyBmdW5jdGlvbiBkcmFpblBlbmRpbmdRdWV1ZUl0ZW1zKFxuICBydW5JZDogc3RyaW5nLFxuICBwZW5kaW5nUXVldWU6IE1hcDxzdHJpbmcsIFF1ZXVlSXRlbT4sXG4gIHZtR2xvYmFsVGhpczogdHlwZW9mIGdsb2JhbFRoaXMsXG4gIHdvcmtmbG93UnVuOiBXb3JrZmxvd1J1bixcbiAgb3V0Y29tZTogJ2NvbXBsZXRlZCcgfCAnZmFpbGVkJyxcbiAgLyoqXG4gICAqIEluIHR1cmJvIG1vZGUsIGdhdGVzIGZpbmFsIGAqX2NyZWF0ZWRgIHdyaXRlcyBvbiBiYWNrZ3JvdW5kZWRcbiAgICogYHJ1bl9zdGFydGVkYC4gVW5kZWZpbmVkIHdoZW4gYHJ1bl9zdGFydGVkYCBpcyBhd2FpdGVkLlxuICAgKi9cbiAgcnVuUmVhZHlCYXJyaWVyPzogUHJvbWlzZTx1bmtub3duPlxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmIChwZW5kaW5nUXVldWUuc2l6ZSA9PT0gMCkgcmV0dXJuO1xuICAvLyBJbXBsaWNpdGx5IGRpc3Bvc2UgYW55IGFib3J0IGhvb2tzIChzeXN0ZW0gaG9va3MpIHRoYXQgYXJlIHN0aWxsIGFsaXZlIGF0XG4gIC8vIHdvcmtmbG93IGNvbXBsZXRpb24gc28gdGhleSBkb24ndCBsZWFrIHJvd3MgaW4gdGhlIGhvb2tzIHRhYmxlIGZvciB0aGVcbiAgLy8gcnVuJ3MgbGlmZXRpbWUuIFNraXAgaG9va3MgdGhhdCBhbHJlYWR5IGhhdmUgYW4gYWJvcnQgaW4gZmxpZ2h0IOKAlCB0aG9zZVxuICAvLyB3aWxsIGVtaXQgaG9va19yZWNlaXZlZCB2aWEgdGhlIGFib3J0IHByb2Nlc3NpbmcgcGF0aC4gVXNlciBob29rc1xuICAvLyAoaXNTeXN0ZW0gIT09IHRydWUpIGFyZSBpbnRlbnRpb25hbGx5IGxlZnQgYWxvbmU6IHRoZWlyIGxpZmV0aW1lIGlzXG4gIC8vIG1hbmFnZWQgYnkgdGhlIHVzZXIncyBjb2RlLCBub3QgdGhlIHJ1bnRpbWUuXG4gIGZvciAoY29uc3QgaXRlbSBvZiBwZW5kaW5nUXVldWUudmFsdWVzKCkpIHtcbiAgICBpZiAoXG4gICAgICBpdGVtLnR5cGUgPT09ICdob29rJyAmJlxuICAgICAgaXRlbS5pc1N5c3RlbSAmJlxuICAgICAgIWl0ZW0uZGlzcG9zZWQgJiZcbiAgICAgICFpdGVtLmFib3J0UmVxdWVzdGVkXG4gICAgKSB7XG4gICAgICBpdGVtLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgdHJ5IHtcbiAgICBjb25zdCB3b3JsZCA9IGF3YWl0IGdldFdvcmxkKCk7XG4gICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBuZXcgV29ya2Zsb3dTdXNwZW5zaW9uKHBlbmRpbmdRdWV1ZSwgdm1HbG9iYWxUaGlzKTtcbiAgICBhd2FpdCBoYW5kbGVTdXNwZW5zaW9uKHtcbiAgICAgIHN1c3BlbnNpb246IHN5bnRoZXNpemVkLFxuICAgICAgd29ybGQsXG4gICAgICBydW46IHdvcmtmbG93UnVuLFxuICAgICAgcnVuUmVhZHlCYXJyaWVyLFxuICAgIH0pO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBydW50aW1lTG9nZ2VyLndhcm4oXG4gICAgICBgRmFpbGVkIHRvIGRyYWluIHBlbmRpbmcgcXVldWUgaXRlbXMgZm9yICR7b3V0Y29tZX0gd29ya2Zsb3cgcnVuYCxcbiAgICAgIHtcbiAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgIG1lc3NhZ2U6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSxcbiAgICAgIH1cbiAgICApO1xuICB9XG59XG5cbi8qKiBFdmVyeXRoaW5nIG5lZWRlZCB0byBjb2xkLXN0YXJ0IGEgd29ya2Zsb3cgVk0gb3ZlciBhbiBldmVudCBsb2cuICovXG5pbnRlcmZhY2UgV29ya2Zsb3dTZXNzaW9uT3B0aW9ucyB7XG4gIHJlYWRvbmx5IHdvcmtmbG93Q29kZTogc3RyaW5nO1xuICByZWFkb25seSB3b3JrZmxvd1J1bjogV29ya2Zsb3dSdW47XG4gIHJlYWRvbmx5IGV2ZW50czogRXZlbnRbXTtcbiAgcmVhZG9ubHkgZW5jcnlwdGlvbktleTogUGF5bG9hZEtleSB8IHVuZGVmaW5lZDtcbiAgcmVhZG9ubHkgcmVwbGF5UGF5bG9hZENhY2hlOiBSZXBsYXlQYXlsb2FkQ2FjaGU7XG4gIHJlYWRvbmx5IHJ1blJlYWR5QmFycmllcj86IFByb21pc2U8dW5rbm93bj47XG4gIHJlYWRvbmx5IHdvcmxkQ2FwYWJpbGl0aWVzPzogV29ybGRDYXBhYmlsaXRpZXM7XG59XG5cbi8qKlxuICogQSBsaXZlIHdvcmtmbG93IFZNLCBwYXJrZWQgYXQgYSBzdXNwZW5zaW9uIGJvdW5kYXJ5LiBgcmVzdW1lYCBhZHZhbmNlcyBpdFxuICogYnkgYXBwZW5kaW5nIGV2ZW50cyBpbnN0ZWFkIG9mIHJlcGxheWluZyBmcm9tIHNjcmF0Y2guXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV29ya2Zsb3dTZXNzaW9uIHtcbiAgcmVhZG9ubHkgd29ya2Zsb3dSdW46IFdvcmtmbG93UnVuO1xuICByZWFkb25seSBhcmd1bWVudENvdW50OiBudW1iZXI7XG4gIHJlc3VtZShldmVudHM6IEV2ZW50W10pOiBQcm9taXNlPFdvcmtmbG93UmVzdW1lUmVzdWx0Pjtcbn1cblxuLyoqIEEgZmluaXNoZWQgZXhlY3V0aW9uIGF0dGVtcHQ6IHRoZSB3b3JrZmxvdydzIG91dHB1dCBvciBhIGxpdmUgYm91bmRhcnkuICovXG5leHBvcnQgdHlwZSBXb3JrZmxvd1Jlc3VsdCA9XG4gIHwge1xuICAgICAgcmVhZG9ubHkgdHlwZTogJ2NvbXBsZXRlZCc7XG4gICAgICByZWFkb25seSBvdXRwdXQ6IHVua25vd247XG4gICAgICAvKiogYHR5cGVvZmAgdGhlIHJhdyByZXR1cm4gdmFsdWUsIGZvciB0ZWxlbWV0cnkuICovXG4gICAgICByZWFkb25seSByZXN1bHRUeXBlOiBzdHJpbmc7XG4gICAgfVxuICB8IHtcbiAgICAgIHJlYWRvbmx5IHR5cGU6ICdzdXNwZW5kZWQnO1xuICAgICAgcmVhZG9ubHkgc3VzcGVuc2lvbjogV29ya2Zsb3dTdXNwZW5zaW9uO1xuICAgICAgcmVhZG9ubHkgc2Vzc2lvbjogV29ya2Zsb3dTZXNzaW9uO1xuICAgIH07XG5cbi8qKlxuICogYHJlc3VtZWAgY2FuIGFkZGl0aW9uYWxseSBkZWNsaW5lIOKAlCBgeyB0eXBlOiAncmVwbGF5JyB9YCBtZWFucyBcInRoaXNcbiAqIHNlc3Npb24gaXMgdW51c2FibGUsIGNvbGQtcmVwbGF5IGluc3RlYWRcIi4gQSBmcmVzaCByZXBsYXkgbmV2ZXIgZGVjbGluZXMuXG4gKi9cbmV4cG9ydCB0eXBlIFdvcmtmbG93UmVzdW1lUmVzdWx0ID0gV29ya2Zsb3dSZXN1bHQgfCB7IHJlYWRvbmx5IHR5cGU6ICdyZXBsYXknIH07XG5cbi8qKiBUaGUgc2Vzc2lvbidzIHByaXZhdGUgc3RhdGUgbWFjaGluZS4gKi9cbnR5cGUgV29ya2Zsb3dTZXNzaW9uU3RhdGUgPVxuICB8IHtcbiAgICAgIHJlYWRvbmx5IHR5cGU6ICdydW5uaW5nJztcbiAgICAgIHJlYWRvbmx5IGludGVycnVwdGlvbjogUHJvbWlzZVdpdGhSZXNvbHZlcnM8bmV2ZXI+O1xuICAgIH1cbiAgfCB7IHJlYWRvbmx5IHR5cGU6ICdzdXNwZW5kZWQnOyByZWFkb25seSBzdXNwZW5zaW9uOiBXb3JrZmxvd1N1c3BlbnNpb24gfVxuICB8IHsgcmVhZG9ubHkgdHlwZTogJ3JlcGxheScgfVxuICB8IHsgcmVhZG9ubHkgdHlwZTogJ2NvbXBsZXRlZCcgfTtcblxuLyoqIENvbGQtc3RhcnQ6IGJ1aWxkIGEgZnJlc2ggVk0gc2Vzc2lvbiBhbmQgcmVwbGF5IGl0IG92ZXIgYGV2ZW50c2AuICovXG5leHBvcnQgZnVuY3Rpb24gcmVwbGF5V29ya2Zsb3coXG4gIG9wdGlvbnM6IFdvcmtmbG93U2Vzc2lvbk9wdGlvbnNcbik6IFByb21pc2U8V29ya2Zsb3dSZXN1bHQ+IHtcbiAgcmV0dXJuIHRyYWNlRXhlY3V0aW9uKFxuICAgICdyZXBsYXknLFxuICAgIG9wdGlvbnMud29ya2Zsb3dSdW4sXG4gICAgb3B0aW9ucy5ldmVudHMsXG4gICAgYXN5bmMgKHNwYW4pID0+IHtcbiAgICAgIGNvbnN0IHsgc2Vzc2lvbiwgZXhlY3V0aW9uIH0gPSBhd2FpdCBjcmVhdGVXb3JrZmxvd1Nlc3Npb24ob3B0aW9ucyk7XG4gICAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93QXJndW1lbnRzQ291bnQoc2Vzc2lvbi5hcmd1bWVudENvdW50KSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlY29yZFJlc3VsdChhd2FpdCBleGVjdXRpb24sIHNwYW4pO1xuICAgIH1cbiAgKTtcbn1cblxuLyoqIFdhcm0tc3RhcnQ6IGFkdmFuY2UgYSByZXRhaW5lZCBzZXNzaW9uIGJ5IGFwcGVuZGluZyBldmVudHMuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzdW1lV29ya2Zsb3coXG4gIHNlc3Npb246IFdvcmtmbG93U2Vzc2lvbixcbiAgZXZlbnRzOiBFdmVudFtdXG4pOiBQcm9taXNlPFdvcmtmbG93UmVzdW1lUmVzdWx0PiB7XG4gIHJldHVybiB0cmFjZUV4ZWN1dGlvbihcbiAgICAncmV0YWluZWQnLFxuICAgIHNlc3Npb24ud29ya2Zsb3dSdW4sXG4gICAgZXZlbnRzLFxuICAgIGFzeW5jIChzcGFuKSA9PiB7XG4gICAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93QXJndW1lbnRzQ291bnQoc2Vzc2lvbi5hcmd1bWVudENvdW50KSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2Vzc2lvbi5yZXN1bWUoZXZlbnRzKTtcbiAgICAgIHJldHVybiByZXN1bHQudHlwZSA9PT0gJ3JlcGxheScgPyByZXN1bHQgOiByZWNvcmRSZXN1bHQocmVzdWx0LCBzcGFuKTtcbiAgICB9XG4gICk7XG59XG5cbmZ1bmN0aW9uIHRyYWNlRXhlY3V0aW9uPFQ+KFxuICBtb2RlOiAncmVwbGF5JyB8ICdyZXRhaW5lZCcsXG4gIHdvcmtmbG93UnVuOiBXb3JrZmxvd1J1bixcbiAgZXZlbnRzOiBFdmVudFtdLFxuICBmbjogKHNwYW46IFNwYW4gfCB1bmRlZmluZWQpID0+IFByb21pc2U8VD5cbik6IFByb21pc2U8VD4ge1xuICByZXR1cm4gdHJhY2UoYHdvcmtmbG93LnJ1biAke3dvcmtmbG93UnVuLndvcmtmbG93TmFtZX1gLCAoc3BhbikgPT4ge1xuICAgIHNwYW4/LnNldEF0dHJpYnV0ZXMoe1xuICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93TmFtZSh3b3JrZmxvd1J1bi53b3JrZmxvd05hbWUpLFxuICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93UnVuSWQod29ya2Zsb3dSdW4ucnVuSWQpLFxuICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93UnVuU3RhdHVzKHdvcmtmbG93UnVuLnN0YXR1cyksXG4gICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dFdmVudHNDb3VudChldmVudHMubGVuZ3RoKSxcbiAgICAgIC4uLkF0dHJpYnV0ZS5Xb3JrZmxvd0V4ZWN1dGlvbk1vZGUobW9kZSksXG4gICAgfSk7XG4gICAgcmV0dXJuIGZuKHNwYW4pO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gcmVjb3JkUmVzdWx0KFxuICByZXN1bHQ6IFdvcmtmbG93UmVzdWx0LFxuICBzcGFuOiBTcGFuIHwgdW5kZWZpbmVkXG4pOiBXb3JrZmxvd1Jlc3VsdCB7XG4gIGlmIChyZXN1bHQudHlwZSA9PT0gJ2NvbXBsZXRlZCcpIHtcbiAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgIC4uLkF0dHJpYnV0ZS5Xb3JrZmxvd1Jlc3VsdFR5cGUocmVzdWx0LnJlc3VsdFR5cGUpLFxuICAgIH0pO1xuICB9IGVsc2UgaWYgKHNwYW4pIHtcbiAgICBhcHBseVdvcmtmbG93U3VzcGVuc2lvblRvU3BhbihyZXN1bHQuc3VzcGVuc2lvbiwgc3Bhbik7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBTaW5nbGUtc2hvdCByZXBsYXk6IGV4ZWN1dGUgdGhlIHdvcmtmbG93IG92ZXIgYGV2ZW50c2AgYW5kIGVpdGhlciByZXR1cm5cbiAqIGl0cyBvdXRwdXQgb3IgdGhyb3cgaXRzIHN1c3BlbnNpb24uIEtlcHQgZm9yIHRoZSBleHRlbnNpdmUgZXhpc3RpbmcgdGVzdFxuICogc3VpdGVzIOKAlCBwcm9kdWN0aW9uIGNvZGUgZ29lcyB0aHJvdWdoIGByZXBsYXlXb3JrZmxvd2AvYHJlc3VtZVdvcmtmbG93YC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1bldvcmtmbG93KFxuICB3b3JrZmxvd0NvZGU6IHN0cmluZyxcbiAgd29ya2Zsb3dSdW46IFdvcmtmbG93UnVuLFxuICBldmVudHM6IEV2ZW50W10sXG4gIGVuY3J5cHRpb25LZXk6IFBheWxvYWRLZXkgfCB1bmRlZmluZWQsXG4gIC8qKlxuICAgKiBPcHRpb25hbCBwZXItcnVuIGNhY2hlIGZvciByZXBsYXkgcGF5bG9hZCBwcmVwYXJhdGlvbiBhbmQgaW1tdXRhYmxlIGZpbmFsXG4gICAqIHZhbHVlcy4gT3duZWQgYnkgdGhlIGlubGluZSBleGVjdXRpb24gbG9vcCBmb3IgdGhpcyBpbnZvY2F0aW9uLlxuICAgKi9cbiAgcmVwbGF5UGF5bG9hZENhY2hlOiBSZXBsYXlQYXlsb2FkQ2FjaGUgPSBuZXcgUmVwbGF5UGF5bG9hZENhY2hlKFxuICAgIGVuY3J5cHRpb25LZXlcbiAgKSxcbiAgLyoqXG4gICAqIFR1cmJvIG1vZGUgb25seTogcmVzb2x2ZXMgb25jZSB0aGUgYmFja2dyb3VuZGVkIGBydW5fc3RhcnRlZGAgaGFzIGxhbmRlZC5cbiAgICogVGhyZWFkZWQgaW50byB0aGUgZW5kLW9mLXJ1biBkcmFpbiBzbyBmaXJlLWFuZC1mb3JnZXQgYCpfY3JlYXRlZGAgd3JpdGVzXG4gICAqIGNvbW1pdHRlZCBhdCB3b3JrZmxvdyBjb21wbGV0aW9uIG9yZGVyIGFmdGVyIHRoZSBydW4ncyBjcmVhdGlvbi4gVW5kZWZpbmVkXG4gICAqIG91dHNpZGUgdHVyYm8sIHdoZXJlIGBydW5fc3RhcnRlZGAgaXMgYXdhaXRlZCB1cCBmcm9udC5cbiAgICovXG4gIHJ1blJlYWR5QmFycmllcj86IFByb21pc2U8dW5rbm93bj4sXG4gIC8qKlxuICAgKiBGZWF0dXJlcyBzdXBwb3J0ZWQgYnkgdGhlIFdvcmxkIGV4ZWN1dGluZyB0aGlzIHdvcmtmbG93LiBNaXNzaW5nXG4gICAqIGNhcGFiaWxpdGllcyBhcmUgdHJlYXRlZCBhcyB1bnN1cHBvcnRlZC5cbiAgICovXG4gIHdvcmxkQ2FwYWJpbGl0aWVzPzogV29ybGRDYXBhYmlsaXRpZXNcbik6IFByb21pc2U8VWludDhBcnJheSB8IHVua25vd24+IHtcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVwbGF5V29ya2Zsb3coe1xuICAgIHdvcmtmbG93Q29kZSxcbiAgICB3b3JrZmxvd1J1bixcbiAgICBldmVudHMsXG4gICAgZW5jcnlwdGlvbktleSxcbiAgICByZXBsYXlQYXlsb2FkQ2FjaGUsXG4gICAgcnVuUmVhZHlCYXJyaWVyLFxuICAgIHdvcmxkQ2FwYWJpbGl0aWVzLFxuICB9KTtcbiAgaWYgKHJlc3VsdC50eXBlID09PSAnc3VzcGVuZGVkJykgdGhyb3cgcmVzdWx0LnN1c3BlbnNpb247XG4gIHJldHVybiByZXN1bHQub3V0cHV0O1xufVxuXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVXb3JrZmxvd1Nlc3Npb24oe1xuICB3b3JrZmxvd0NvZGUsXG4gIHdvcmtmbG93UnVuLFxuICBldmVudHMsXG4gIGVuY3J5cHRpb25LZXksXG4gIHJlcGxheVBheWxvYWRDYWNoZSxcbiAgcnVuUmVhZHlCYXJyaWVyLFxuICB3b3JsZENhcGFiaWxpdGllcyxcbn06IFdvcmtmbG93U2Vzc2lvbk9wdGlvbnMpOiBQcm9taXNlPHtcbiAgc2Vzc2lvbjogV29ya2Zsb3dTZXNzaW9uO1xuICBleGVjdXRpb246IFByb21pc2U8V29ya2Zsb3dSZXN1bHQ+O1xufT4ge1xuICBjb25zdCBzdGFydGVkQXQgPSB3b3JrZmxvd1J1bi5zdGFydGVkQXQ7XG4gIGlmICghc3RhcnRlZEF0KSB7XG4gICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKFxuICAgICAgYFdvcmtmbG93IHJ1biBcIiR7d29ya2Zsb3dSdW4ucnVuSWR9XCIgaGFzIG5vIFwic3RhcnRlZEF0XCIgdGltZXN0YW1wIChzaG91bGQgbm90IGhhcHBlbilgXG4gICAgKTtcbiAgfVxuXG4gIC8vIFNlZWQgYW5kIGluaXRpYWwgY2xvY2sgbXVzdCBiZSBhdmFpbGFibGUgYmVmb3JlIEkvTyBhbmQgcmVtYWluIHN0YWJsZSBvblxuICAvLyByZXBsYXkuIEFmdGVyIHRoZSBmaXJzdCBldmVudCwgRXZlbnRzQ29uc3VtZXIgYWR2YW5jZXMgdGhlIFZNIGNsb2NrIGZyb21cbiAgLy8gZWFjaCBldmVudCdzIGBjcmVhdGVkQXRgLlxuICBjb25zdCBmaXhlZFRpbWVzdGFtcCA9XG4gICAgcnVuSWRDcmVhdGVkQXQod29ya2Zsb3dSdW4ucnVuSWQpID8/ICt3b3JrZmxvd1J1bi5jcmVhdGVkQXQ7XG5cbiAgLy8gVHJ1dGhpbmVzcywgbm90IHByZXNlbmNlOiBgdmVyY2VsIGVudiBwdWxsYCB3cml0ZXMgYFZFUkNFTF9VUkw9XCJcImAgaW50b1xuICAvLyBgLmVudi5sb2NhbGAsIGFuZCBhIGZyYW1ld29yayB0aGF0IGxvYWRzIHRoYXQgZmlsZSBsb2NhbGx5IHdvdWxkIG90aGVyd2lzZVxuICAvLyBwdXQgdXMgb24gdGhlIFZlcmNlbCBicmFuY2ggd2l0aCBub3RoaW5nIHRvIGJ1aWxkIGEgaG9zdCBmcm9tLCBtYWtpbmdcbiAgLy8gYGh0dHBzOi8vYCB0aGUgYmFzZSBVUkwgb2YgZXZlcnkgcnVuLlxuICBjb25zdCBpc1ZlcmNlbCA9IEJvb2xlYW4ocHJvY2Vzcy5lbnYuVkVSQ0VMX1VSTCk7XG4gIC8vIExvYWQgZ2V0UG9ydCBsYXppbHkgdG8gcHJldmVudCBUdXJib3BhY2sgZnJvbSB0cmFjaW5nIGdldC1wb3J0J3NcbiAgLy8gZnMgb3BzIChyZWFkZGlyLCByZWFkRmlsZSkgaW50byB0aGUgZmxvdyByb3V0ZSBidW5kbGUuIFRoZSByZXNvbHZlZFxuICAvLyBwb3J0IGlzIGNhY2hlZCBwZXIgcHJvY2VzcyAoc2VlIGdldC1wb3J0LWxhenkudHMpLCBzbyB0aGlzIGlzIGNoZWFwXG4gIC8vIG9uIHJlcGxheXMgYWZ0ZXIgdGhlIGZpcnN0LlxuICBjb25zdCB3b3JrZmxvd0Jhc2VVcmwgPSBjcmVhdGVXb3JrZmxvd0Jhc2VVcmwoXG4gICAgaXNWZXJjZWxcbiAgICAgID8gYGh0dHBzOi8vJHtwcm9jZXNzLmVudi5WRVJDRUxfVVJMfWBcbiAgICAgIDogYGh0dHA6Ly9sb2NhbGhvc3Q6JHsoYXdhaXQgZ2V0UG9ydExhenkoKSkgPz8gMzAwMH1gXG4gICk7XG5cbiAgY29uc3Qgc2VlZCA9IGAke3dvcmtmbG93UnVuLnJ1bklkfToke3dvcmtmbG93UnVuLndvcmtmbG93TmFtZX06JHt3b3JrZmxvd1J1bi5kZXBsb3ltZW50SWR9YDtcblxuICBjb25zdCB7XG4gICAgY29udGV4dCxcbiAgICBnbG9iYWxUaGlzOiB2bUdsb2JhbFRoaXMsXG4gICAgdXBkYXRlVGltZXN0YW1wLFxuICB9ID0gY3JlYXRlQ29udGV4dCh7XG4gICAgc2VlZCxcbiAgICBmaXhlZFRpbWVzdGFtcCxcbiAgfSk7XG5cbiAgY29uc3QgaW5pdGlhbEludGVycnVwdGlvbiA9IHdpdGhSZXNvbHZlcnM8bmV2ZXI+KCk7XG4gIGxldCBzdGF0ZTogV29ya2Zsb3dTZXNzaW9uU3RhdGUgPSB7XG4gICAgdHlwZTogJ3J1bm5pbmcnLFxuICAgIGludGVycnVwdGlvbjogaW5pdGlhbEludGVycnVwdGlvbixcbiAgfTtcblxuICBjb25zdCBvbldvcmtmbG93RXJyb3IgPSAoZXJyb3I6IEVycm9yKTogdm9pZCA9PiB7XG4gICAgc3dpdGNoIChzdGF0ZS50eXBlKSB7XG4gICAgICBjYXNlICdydW5uaW5nJzoge1xuICAgICAgICBjb25zdCB7IGludGVycnVwdGlvbiB9ID0gc3RhdGU7XG4gICAgICAgIHN0YXRlID0gV29ya2Zsb3dTdXNwZW5zaW9uLmlzKGVycm9yKVxuICAgICAgICAgID8geyB0eXBlOiAnc3VzcGVuZGVkJywgc3VzcGVuc2lvbjogZXJyb3IgfVxuICAgICAgICAgIDogeyB0eXBlOiAncmVwbGF5JyB9O1xuICAgICAgICAvLyBFYWNoIHBhcmtlZCBzdGVwIGNvbnN1bWVyIHNjaGVkdWxlcyBpdHMgb3duIChpZGVudGljYWwpIHN1c3BlbnNpb25cbiAgICAgICAgLy8gc2lnbmFsOyB0aGUgZmlyc3Qgb25lIGxhbmRzIGhlcmUsIGFuZCBidW1waW5nIHRoZSBnZW5lcmF0aW9uIG1ha2VzXG4gICAgICAgIC8vIHRoZSBzdGVwLWNvbnN1bWVyIGd1YXJkIGRyb3AgdGhlIHJlc3QgYXQgZmlyZSB0aW1lLlxuICAgICAgICB3b3JrZmxvd0NvbnRleHQuc3VzcGVuc2lvbkdlbmVyYXRpb24rKztcbiAgICAgICAgaW50ZXJydXB0aW9uLnJlamVjdChlcnJvcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNhc2UgJ3N1c3BlbmRlZCc6XG4gICAgICAgIC8vIFNhbWUtYm91bmRhcnkgZHVwbGljYXRlcyB3ZXJlIHN0YWxlZCBieSB0aGUgZ2VuZXJhdGlvbiBidW1wIGFib3ZlLFxuICAgICAgICAvLyBzbyBhbnl0aGluZyBsYW5kaW5nIGhlcmUgaXMgb3V0LW9mLWJhbmQg4oCUIGFuIHVuZ3VhcmRlZCBzbGVlcC9ob29rL1xuICAgICAgICAvLyBhdHRyaWJ1dGUgc2lnbmFsIG9yIGEgZGl2ZXJnZW5jZS4gVGhvc2UgYm91bmRhcmllcyBhcmUgdW5yZXRhaW5hYmxlXG4gICAgICAgIC8vICh0aGUgcnVudGltZSBkZW1vdGVzIHRoZW0gdG9vKSwgc28gZmFsbCBiYWNrIHRvIHJlcGxheS5cbiAgICAgICAgc3RhdGUgPSB7IHR5cGU6ICdyZXBsYXknIH07XG4gICAgICAgIHJldHVybjtcbiAgICAgIGNhc2UgJ3JlcGxheSc6XG4gICAgICBjYXNlICdjb21wbGV0ZWQnOlxuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHN0YXRlIHNhdGlzZmllcyBuZXZlcjtcbiAgfTtcblxuICBjb25zdCB1bGlkID0gbW9ub3RvbmljRmFjdG9yeSgoKSA9PiB2bUdsb2JhbFRoaXMuTWF0aC5yYW5kb20oKSk7XG4gIGNvbnN0IGdlbmVyYXRlQ29ycmVsYXRpb25JZCA9IGNyZWF0ZUNvcnJlbGF0aW9uSWRHZW5lcmF0b3Ioe1xuICAgIHNlZWQsXG4gICAgZml4ZWRUaW1lc3RhbXAsXG4gICAgLy8gQ29ycmVsYXRpb24gSURzIG11c3QgYmUgcmVwbGF5LXN0YWJsZS4gYHN0YXJ0ZWRBdGAgZGlmZmVycyBiZXR3ZWVuIGFcbiAgICAvLyB0dXJibyBkZWxpdmVyeSBhbmQgYSBsYXRlciBzZXJ2ZXItYmFja2VkIHJlcGxheSwgc28gdXNlIGZpeGVkVGltZXN0YW1wLlxuICAgIHBvc2l0aW9uYWw6ICgpID0+IHVsaWQoZml4ZWRUaW1lc3RhbXApLFxuICAgIHBlcktpbmQ6IGlzUGVyS2luZENvcnJlbGF0aW9uSWRzRW5hYmxlZCgpLFxuICB9KTtcbiAgY29uc3QgZ2VuZXJhdGVOYW5vaWQgPSBuYW5vaWQuY3VzdG9tUmFuZG9tKG5hbm9pZC51cmxBbHBoYWJldCwgMjEsIChzaXplKSA9PlxuICAgIG5ldyBVaW50OEFycmF5KHNpemUpLm1hcCgoKSA9PiAyNTYgKiB2bUdsb2JhbFRoaXMuTWF0aC5yYW5kb20oKSlcbiAgKTtcblxuICAvLyBDcmVhdGUgYSBtdXRhYmxlIGhvbGRlciBmb3IgdGhlIHByb21pc2UgcXVldWUgc28gdGhlIEV2ZW50c0NvbnN1bWVyXG4gIC8vIGNhbiBhY2Nlc3MgdGhlIGN1cnJlbnQgcXVldWUgc3RhdGUgdmlhIGEgZ2V0dGVyLiBUaGUgcXVldWUgaXMgbXV0YXRlZFxuICAvLyBieSBzdGVwL2hvb2svc2xlZXAgY2FsbGJhY2tzIGFzIGV2ZW50cyBhcmUgcHJvY2Vzc2VkLlxuICBjb25zdCBwcm9taXNlUXVldWVIb2xkZXIgPSB7IGN1cnJlbnQ6IFByb21pc2UucmVzb2x2ZSgpIH07XG5cbiAgY29uc3QgZXZlbnRzQ29uc3VtZXIgPSBuZXcgRXZlbnRzQ29uc3VtZXIoZXZlbnRzLCB7XG4gICAgb25Db25zdW1lZEV2ZW50OiAoZXZlbnQpID0+IHtcbiAgICAgIHVwZGF0ZVRpbWVzdGFtcCgrZXZlbnQuY3JlYXRlZEF0KTtcbiAgICB9LFxuICAgIG9uVW5jb25zdW1lZEV2ZW50OiAoZXZlbnQpID0+IHtcbiAgICAgIG9uV29ya2Zsb3dFcnJvcihcbiAgICAgICAgbmV3IFJlcGxheURpdmVyZ2VuY2VFcnJvcihcbiAgICAgICAgICBgUmVwbGF5IGNvdWxkIG5vdCBjb25zdW1lIGV2ZW50OiBldmVudFR5cGU9JHtldmVudC5ldmVudFR5cGV9LCBjb3JyZWxhdGlvbklkPSR7ZXZlbnQuY29ycmVsYXRpb25JZH0sIGV2ZW50SWQ9JHtldmVudC5ldmVudElkfS5gLFxuICAgICAgICAgIHsgZXZlbnRJZDogZXZlbnQuZXZlbnRJZCB9XG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfSxcbiAgICBnZXRQcm9taXNlUXVldWU6ICgpID0+IHByb21pc2VRdWV1ZUhvbGRlci5jdXJyZW50LFxuICB9KTtcblxuICBjb25zdCB3b3JrZmxvd0NvbnRleHQ6IFdvcmtmbG93T3JjaGVzdHJhdG9yQ29udGV4dCA9IHtcbiAgICBydW5JZDogd29ya2Zsb3dSdW4ucnVuSWQsXG4gICAgZW5jcnlwdGlvbktleSxcbiAgICB3b3JsZENhcGFiaWxpdGllcyxcbiAgICBnbG9iYWxUaGlzOiB2bUdsb2JhbFRoaXMsXG4gICAgb25Xb3JrZmxvd0Vycm9yLFxuICAgIGV2ZW50c0NvbnN1bWVyLFxuICAgIGdlbmVyYXRlQ29ycmVsYXRpb25JZCxcbiAgICBnZW5lcmF0ZU5hbm9pZCxcbiAgICBpbnZvY2F0aW9uc1F1ZXVlOiBuZXcgTWFwKCksXG4gICAgLy8gVXNlIGdldHRlci9zZXR0ZXIgc28gdGhlIEV2ZW50c0NvbnN1bWVyJ3MgZ2V0UHJvbWlzZVF1ZXVlKCkgYWx3YXlzXG4gICAgLy8gc2VlcyB0aGUgbGF0ZXN0IHF1ZXVlIHN0YXRlIGFzIGl0J3MgbXV0YXRlZCBieSBzdGVwL2hvb2svc2xlZXAgY2FsbGJhY2tzLlxuICAgIGdldCBwcm9taXNlUXVldWUoKSB7XG4gICAgICByZXR1cm4gcHJvbWlzZVF1ZXVlSG9sZGVyLmN1cnJlbnQ7XG4gICAgfSxcbiAgICBzZXQgcHJvbWlzZVF1ZXVlKHZhbHVlOiBQcm9taXNlPHZvaWQ+KSB7XG4gICAgICBwcm9taXNlUXVldWVIb2xkZXIuY3VycmVudCA9IHZhbHVlO1xuICAgIH0sXG4gICAgcGVuZGluZ0RlbGl2ZXJpZXM6IDAsXG4gICAgc3VzcGVuc2lvbkdlbmVyYXRpb246IDAsXG4gICAgcGVuZGluZ0RlbGl2ZXJ5QmFycmllcnM6IG5ldyBNYXAoKSxcbiAgICByZXBsYXlQYXlsb2FkQ2FjaGUsXG4gIH07XG5cbiAgLy8gQ29uc3VtZSBydW4gbGlmZWN5Y2xlIGV2ZW50cyAtIHRoZXNlIGFyZSBzdHJ1Y3R1cmFsIGV2ZW50cyB0aGF0IGRvbid0XG4gIC8vIG5lZWQgc3BlY2lhbCBoYW5kbGluZyBpbiB0aGUgd29ya2Zsb3csIGJ1dCBtdXN0IGJlIGNvbnN1bWVkIHRvIGFkdmFuY2VcbiAgLy8gcGFzdCB0aGVtIGluIHRoZSBldmVudCBsb2dcbiAgd29ya2Zsb3dDb250ZXh0LmV2ZW50c0NvbnN1bWVyLnN1YnNjcmliZSgoZXZlbnQpID0+IHtcbiAgICBpZiAoIWV2ZW50KSB7XG4gICAgICByZXR1cm4gRXZlbnRDb25zdW1lclJlc3VsdC5Ob3RDb25zdW1lZDtcbiAgICB9XG5cbiAgICAvLyBDb25zdW1lIHJ1bl9jcmVhdGVkIC0gZXZlcnkgcnVuIGhhcyBleGFjdGx5IG9uZVxuICAgIGlmIChldmVudC5ldmVudFR5cGUgPT09ICdydW5fY3JlYXRlZCcpIHtcbiAgICAgIHJldHVybiBFdmVudENvbnN1bWVyUmVzdWx0LkNvbnN1bWVkO1xuICAgIH1cblxuICAgIC8vIENvbnN1bWUgcnVuX3N0YXJ0ZWQgLSBldmVyeSBydW4gaGFzIGV4YWN0bHkgb25lXG4gICAgaWYgKGV2ZW50LmV2ZW50VHlwZSA9PT0gJ3J1bl9zdGFydGVkJykge1xuICAgICAgcmV0dXJuIEV2ZW50Q29uc3VtZXJSZXN1bHQuQ29uc3VtZWQ7XG4gICAgfVxuXG4gICAgLy8gQXR0cmlidXRlIHdyaXRlcyBwZXJmb3JtZWQgZnJvbSBhIHN0ZXAgaGF2ZSBubyB3b3JrZmxvdy1ib2R5IGNhbGwgdG9cbiAgICAvLyBjb25zdW1lIHRoZW0gZHVyaW5nIHJlcGxheTsgdGhleSBhcmUgYWxyZWFkeSByZWZsZWN0ZWQgaW4gdGhlIHJ1blxuICAgIC8vIHNuYXBzaG90IGFuZCByZW1haW4gc3RydWN0dXJhbCB1bnRpbCBhIHJlYWQgQVBJIGlzIGludHJvZHVjZWQuXG4gICAgaWYgKFxuICAgICAgZXZlbnQuZXZlbnRUeXBlID09PSAnYXR0cl9zZXQnICYmXG4gICAgICBldmVudC5ldmVudERhdGEud3JpdGVyLnR5cGUgPT09ICdzdGVwJ1xuICAgICkge1xuICAgICAgcmV0dXJuIEV2ZW50Q29uc3VtZXJSZXN1bHQuQ29uc3VtZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIEV2ZW50Q29uc3VtZXJSZXN1bHQuTm90Q29uc3VtZWQ7XG4gIH0pO1xuXG4gIGNvbnN0IHVzZVN0ZXAgPSBjcmVhdGVVc2VTdGVwKHdvcmtmbG93Q29udGV4dCk7XG4gIGNvbnN0IGNyZWF0ZUhvb2sgPSBjcmVhdGVDcmVhdGVIb29rKHdvcmtmbG93Q29udGV4dCk7XG4gIGNvbnN0IHNsZWVwID0gY3JlYXRlU2xlZXAod29ya2Zsb3dDb250ZXh0KTtcbiAgY29uc3Qgc2V0QXR0cmlidXRlcyA9IGNyZWF0ZVNldEF0dHJpYnV0ZXMod29ya2Zsb3dDb250ZXh0KTtcblxuICAvLyBAdHMtZXhwZWN0LWVycm9yIC0gYEB0eXBlcy9ub2RlYCBzYXlzIHN5bWJvbCBpcyBub3QgdmFsaWQsIGJ1dCBpdCBkb2VzIHdvcmtcbiAgdm1HbG9iYWxUaGlzW1dPUktGTE9XX1VTRV9TVEVQXSA9IHVzZVN0ZXA7XG4gIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBgQHR5cGVzL25vZGVgIHNheXMgc3ltYm9sIGlzIG5vdCB2YWxpZCwgYnV0IGl0IGRvZXMgd29ya1xuICB2bUdsb2JhbFRoaXNbV09SS0ZMT1dfU0VUX0FUVFJJQlVURVNdID0gc2V0QXR0cmlidXRlcztcbiAgLy8gQHRzLWV4cGVjdC1lcnJvciAtIGBAdHlwZXMvbm9kZWAgc2F5cyBzeW1ib2wgaXMgbm90IHZhbGlkLCBidXQgaXQgZG9lcyB3b3JrXG4gIHZtR2xvYmFsVGhpc1tXT1JLRkxPV19DUkVBVEVfSE9PS10gPSBjcmVhdGVIb29rO1xuICAvLyBAdHMtZXhwZWN0LWVycm9yIC0gYEB0eXBlcy9ub2RlYCBzYXlzIHN5bWJvbCBpcyBub3QgdmFsaWQsIGJ1dCBpdCBkb2VzIHdvcmtcbiAgdm1HbG9iYWxUaGlzW1dPUktGTE9XX1NMRUVQXSA9IHNsZWVwO1xuICAvLyBAdHMtZXhwZWN0LWVycm9yIC0gYEB0eXBlcy9ub2RlYCBzYXlzIHN5bWJvbCBpcyBub3QgdmFsaWQsIGJ1dCBpdCBkb2VzIHdvcmtcbiAgdm1HbG9iYWxUaGlzW1dPUktGTE9XX0dFVF9TVFJFQU1fSURdID0gKG5hbWVzcGFjZT86IHN0cmluZykgPT5cbiAgICBnZXRXb3JrZmxvd1J1blN0cmVhbUlkKHdvcmtmbG93UnVuLnJ1bklkLCBuYW1lc3BhY2UpO1xuXG4gIC8vIEZvciB0aGUgd29ya2Zsb3cgVk0sIHdlIHN0b3JlIHRoZSBjb250ZXh0IGluIGEgc3ltYm9sIG9uIHRoZSBgZ2xvYmFsVGhpc2Agb2JqZWN0XG4gIGNvbnN0IGN0eDogV29ya2Zsb3dNZXRhZGF0YSA9IHtcbiAgICB3b3JrZmxvd05hbWU6IHdvcmtmbG93UnVuLndvcmtmbG93TmFtZSxcbiAgICB3b3JrZmxvd1J1bklkOiB3b3JrZmxvd1J1bi5ydW5JZCxcbiAgICB3b3JrZmxvd1N0YXJ0ZWRBdDogbmV3IHZtR2xvYmFsVGhpcy5EYXRlKCtzdGFydGVkQXQpLFxuICAgIHVybDogd29ya2Zsb3dCYXNlVXJsLFxuICAgIGZlYXR1cmVzOiB7IGVuY3J5cHRpb246ICEhZW5jcnlwdGlvbktleSB9LFxuICB9O1xuXG4gIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBgQHR5cGVzL25vZGVgIHNheXMgc3ltYm9sIGlzIG5vdCB2YWxpZCwgYnV0IGl0IGRvZXMgd29ya1xuICB2bUdsb2JhbFRoaXNbV09SS0ZMT1dfQ09OVEVYVF9TWU1CT0xdID0gY3R4O1xuICAvLyBTZXJpYWxpemF0aW9uIG1pbnRzIHN0cmVhbSBpZHMgdGhyb3VnaCB0aGlzIHN5bWJvbCwgYW5kIGNhbGxzIGl0IHdpdGggbm9cbiAgLy8gc2VlZCB0aW1lLiBgbW9ub3RvbmljRmFjdG9yeWAgcmV0dXJucyBgZW5jb2RlVGltZShsYXN0VGltZSlgIG9uIGl0c1xuICAvLyBpbmNyZW1lbnQgYnJhbmNoLCBzbyBvbmUgc3VjaCBjYWxsIGxhdGNoZXMgdGhlICpob3N0KiB3YWxsIGNsb2NrIGludG9cbiAgLy8gYGxhc3RUaW1lYCBhbmQgZXZlcnkgaWQgdGhlIHJ1biBtaW50cyBhZnRlcndhcmRzIGNhcnJpZXMgdGhhdCB0aW1lc3RhbXBcbiAgLy8gaW5zdGVhZCBvZiBgZml4ZWRUaW1lc3RhbXBgIOKAlCBhIHZhbHVlIHRoYXQgZGlmZmVycyBvbiBldmVyeSByZXBsYXkuXG4gIC8vIEJpbmRpbmcgdGhlIHNlZWQgdGltZSBoZXJlIGtlZXBzIHRoZSB3aG9sZSBydW4gb24gb25lIHJlcGxheS1zdGFibGUgY2xvY2suXG4gIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBgQHR5cGVzL25vZGVgIHNheXMgc3ltYm9sIGlzIG5vdCB2YWxpZCwgYnV0IGl0IGRvZXMgd29ya1xuICB2bUdsb2JhbFRoaXNbU1RBQkxFX1VMSURdID0gKCkgPT4gZ2VuZXJhdGVDb3JyZWxhdGlvbklkKCdzdHJlYW0nKTtcblxuICAvLyBXb3JrZmxvdyBjb2RlIG11c3QgaW1wb3J0IHRoZSBkZXRlcm1pbmlzdGljIGBmZXRjaGAgc3RlcCBmcm9tIGB3b3JrZmxvd2AuXG4gIHZtR2xvYmFsVGhpcy5mZXRjaCA9ICgpID0+IHtcbiAgICB0aHJvdyBuZXcgdm1HbG9iYWxUaGlzLkVycm9yKFxuICAgICAgYEdsb2JhbCBcImZldGNoXCIgaXMgdW5hdmFpbGFibGUgaW4gd29ya2Zsb3cgZnVuY3Rpb25zLiBVc2UgdGhlIFwiZmV0Y2hcIiBzdGVwIGZ1bmN0aW9uIGZyb20gXCJ3b3JrZmxvd1wiIHRvIG1ha2UgSFRUUCByZXF1ZXN0cy5cXG5cXG5MZWFybiBtb3JlOiBodHRwczovL3dvcmtmbG93LXNkay5kZXYvZXJyLyR7RVJST1JfU0xVR1MuRkVUQ0hfSU5fV09SS0ZMT1dfRlVOQ1RJT059YFxuICAgICk7XG4gIH07XG5cbiAgLy8gT3ZlcnJpZGUgdGltZW91dC9pbnRlcnZhbCBmdW5jdGlvbnMgdG8gdGhyb3cgaGVscGZ1bCBlcnJvcnNcbiAgLy8gVGhlc2UgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gd29ya2Zsb3cgZnVuY3Rpb25zIGJlY2F1c2UgdGhleSByZWx5IG9uXG4gIC8vIGFzeW5jaHJvbm91cyBzY2hlZHVsaW5nIHdoaWNoIGJyZWFrcyBkZXRlcm1pbmlzdGljIHJlcGxheVxuICBjb25zdCB0aW1lb3V0RXJyb3JNZXNzYWdlID1cbiAgICAnVGltZW91dCBmdW5jdGlvbnMgbGlrZSBcInNldFRpbWVvdXRcIiBhbmQgXCJzZXRJbnRlcnZhbFwiIGFyZSBub3Qgc3VwcG9ydGVkIGluIHdvcmtmbG93IGZ1bmN0aW9ucy4gVXNlIHRoZSBcInNsZWVwXCIgZnVuY3Rpb24gZnJvbSBcIndvcmtmbG93XCIgZm9yIHRpbWUtYmFzZWQgZGVsYXlzLic7XG5cbiAgKHZtR2xvYmFsVGhpcyBhcyBhbnkpLnNldFRpbWVvdXQgPSAoKSA9PiB7XG4gICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKHRpbWVvdXRFcnJvck1lc3NhZ2UsIHtcbiAgICAgIHNsdWc6IEVSUk9SX1NMVUdTLlRJTUVPVVRfRlVOQ1RJT05TX0lOX1dPUktGTE9XLFxuICAgIH0pO1xuICB9O1xuICAodm1HbG9iYWxUaGlzIGFzIGFueSkuc2V0SW50ZXJ2YWwgPSAoKSA9PiB7XG4gICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKHRpbWVvdXRFcnJvck1lc3NhZ2UsIHtcbiAgICAgIHNsdWc6IEVSUk9SX1NMVUdTLlRJTUVPVVRfRlVOQ1RJT05TX0lOX1dPUktGTE9XLFxuICAgIH0pO1xuICB9O1xuICAodm1HbG9iYWxUaGlzIGFzIGFueSkuY2xlYXJUaW1lb3V0ID0gKCkgPT4ge1xuICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcih0aW1lb3V0RXJyb3JNZXNzYWdlLCB7XG4gICAgICBzbHVnOiBFUlJPUl9TTFVHUy5USU1FT1VUX0ZVTkNUSU9OU19JTl9XT1JLRkxPVyxcbiAgICB9KTtcbiAgfTtcbiAgKHZtR2xvYmFsVGhpcyBhcyBhbnkpLmNsZWFySW50ZXJ2YWwgPSAoKSA9PiB7XG4gICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKHRpbWVvdXRFcnJvck1lc3NhZ2UsIHtcbiAgICAgIHNsdWc6IEVSUk9SX1NMVUdTLlRJTUVPVVRfRlVOQ1RJT05TX0lOX1dPUktGTE9XLFxuICAgIH0pO1xuICB9O1xuICAodm1HbG9iYWxUaGlzIGFzIGFueSkuc2V0SW1tZWRpYXRlID0gKCkgPT4ge1xuICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcih0aW1lb3V0RXJyb3JNZXNzYWdlLCB7XG4gICAgICBzbHVnOiBFUlJPUl9TTFVHUy5USU1FT1VUX0ZVTkNUSU9OU19JTl9XT1JLRkxPVyxcbiAgICB9KTtcbiAgfTtcbiAgKHZtR2xvYmFsVGhpcyBhcyBhbnkpLmNsZWFySW1tZWRpYXRlID0gKCkgPT4ge1xuICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcih0aW1lb3V0RXJyb3JNZXNzYWdlLCB7XG4gICAgICBzbHVnOiBFUlJPUl9TTFVHUy5USU1FT1VUX0ZVTkNUSU9OU19JTl9XT1JLRkxPVyxcbiAgICB9KTtcbiAgfTtcblxuICAvLyBgQWJvcnRDb250cm9sbGVyYCBhbmQgYEFib3J0U2lnbmFsYCBpbiB0aGUgd29ya2Zsb3cgVk0gYXJlIGhvb2stYmFja2VkXG4gIC8vIGZvciBkZXRlcm1pbmlzdGljIHJlcGxheS4gVGhlIGNvbnRyb2xsZXIncyBhYm9ydCgpIHF1ZXVlcyBhIGhvb2sgcmVzdW1wdGlvbixcbiAgLy8gYW5kIHNpZ25hbC5hYm9ydGVkIGlzIHVwZGF0ZWQgd2hlbiB0aGUgaG9vayBldmVudCBpcyBwcm9jZXNzZWQgZHVyaW5nIHJlcGxheS5cbiAgKHZtR2xvYmFsVGhpcyBhcyBhbnkpLkFib3J0Q29udHJvbGxlciA9XG4gICAgY3JlYXRlQ3JlYXRlQWJvcnRDb250cm9sbGVyKHdvcmtmbG93Q29udGV4dCk7XG4gIGNvbnN0IGFib3J0U2lnbmFsU3RhdGljcyA9IGNyZWF0ZUFib3J0U2lnbmFsU3RhdGljcygpO1xuICAodm1HbG9iYWxUaGlzIGFzIGFueSkuQWJvcnRTaWduYWwgPSB7XG4gICAgYWJvcnQ6IGFib3J0U2lnbmFsU3RhdGljcy5hYm9ydCxcbiAgICBhbnk6IGFib3J0U2lnbmFsU3RhdGljcy5hbnksXG4gICAgdGltZW91dDogYWJvcnRTaWduYWxTdGF0aWNzLnRpbWVvdXQsXG4gIH07XG5cbiAgLy8gYFJlcXVlc3RgIGFuZCBgUmVzcG9uc2VgIGFyZSBzcGVjaWFsIGJ1aWx0LWluIGNsYXNzZXMgdGhhdCBpbnZva2Ugc3RlcHNcbiAgLy8gZm9yIHRoZSBganNvbigpYCwgYHRleHQoKWAgYW5kIGBhcnJheUJ1ZmZlcigpYCBpbnN0YW5jZSBtZXRob2RzXG4gIGNsYXNzIFJlcXVlc3QgaW1wbGVtZW50cyBnbG9iYWxUaGlzLlJlcXVlc3Qge1xuICAgIGNhY2hlITogZ2xvYmFsVGhpcy5SZXF1ZXN0WydjYWNoZSddO1xuICAgIGNyZWRlbnRpYWxzITogZ2xvYmFsVGhpcy5SZXF1ZXN0WydjcmVkZW50aWFscyddO1xuICAgIGRlc3RpbmF0aW9uITogZ2xvYmFsVGhpcy5SZXF1ZXN0WydkZXN0aW5hdGlvbiddO1xuICAgIGhlYWRlcnMhOiBIZWFkZXJzO1xuICAgIGludGVncml0eSE6IHN0cmluZztcbiAgICBtZXRob2QhOiBzdHJpbmc7XG4gICAgbW9kZSE6IGdsb2JhbFRoaXMuUmVxdWVzdFsnbW9kZSddO1xuICAgIHJlZGlyZWN0ITogZ2xvYmFsVGhpcy5SZXF1ZXN0WydyZWRpcmVjdCddO1xuICAgIHJlZmVycmVyITogc3RyaW5nO1xuICAgIHJlZmVycmVyUG9saWN5ITogZ2xvYmFsVGhpcy5SZXF1ZXN0WydyZWZlcnJlclBvbGljeSddO1xuICAgIHVybCE6IHN0cmluZztcbiAgICBrZWVwYWxpdmUhOiBib29sZWFuO1xuICAgIHNpZ25hbCE6IEFib3J0U2lnbmFsO1xuICAgIGR1cGxleCE6ICdoYWxmJztcbiAgICBib2R5ITogUmVhZGFibGVTdHJlYW08YW55PiB8IG51bGw7XG5cbiAgICBjb25zdHJ1Y3RvcihpbnB1dDogYW55LCBpbml0PzogUmVxdWVzdEluaXQpIHtcbiAgICAgIC8vIEhhbmRsZSBVUkwgaW5wdXRcbiAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnIHx8IGlucHV0IGluc3RhbmNlb2Ygdm1HbG9iYWxUaGlzLlVSTCkge1xuICAgICAgICBjb25zdCB1cmxTdHJpbmcgPSBTdHJpbmcoaW5wdXQpO1xuICAgICAgICAvLyBWYWxpZGF0ZSBVUkwgZm9ybWF0XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbmV3IHZtR2xvYmFsVGhpcy5VUkwodXJsU3RyaW5nKTtcbiAgICAgICAgICB0aGlzLnVybCA9IHVybFN0cmluZztcbiAgICAgICAgfSBjYXRjaCAoY2F1c2UpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBGYWlsZWQgdG8gcGFyc2UgVVJMIGZyb20gJHt1cmxTdHJpbmd9YCwge1xuICAgICAgICAgICAgY2F1c2UsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIElucHV0IGlzIGEgUmVxdWVzdCBvYmplY3QgLSBjbG9uZSBpdHMgcHJvcGVydGllc1xuICAgICAgICB0aGlzLnVybCA9IGlucHV0LnVybDtcbiAgICAgICAgaWYgKCFpbml0KSB7XG4gICAgICAgICAgdGhpcy5tZXRob2QgPSBpbnB1dC5tZXRob2Q7XG4gICAgICAgICAgdGhpcy5oZWFkZXJzID0gbmV3IHZtR2xvYmFsVGhpcy5IZWFkZXJzKGlucHV0LmhlYWRlcnMpO1xuICAgICAgICAgIHRoaXMuYm9keSA9IGlucHV0LmJvZHk7XG4gICAgICAgICAgdGhpcy5tb2RlID0gaW5wdXQubW9kZTtcbiAgICAgICAgICB0aGlzLmNyZWRlbnRpYWxzID0gaW5wdXQuY3JlZGVudGlhbHM7XG4gICAgICAgICAgdGhpcy5jYWNoZSA9IGlucHV0LmNhY2hlO1xuICAgICAgICAgIHRoaXMucmVkaXJlY3QgPSBpbnB1dC5yZWRpcmVjdDtcbiAgICAgICAgICB0aGlzLnJlZmVycmVyID0gaW5wdXQucmVmZXJyZXI7XG4gICAgICAgICAgdGhpcy5yZWZlcnJlclBvbGljeSA9IGlucHV0LnJlZmVycmVyUG9saWN5O1xuICAgICAgICAgIHRoaXMuaW50ZWdyaXR5ID0gaW5wdXQuaW50ZWdyaXR5O1xuICAgICAgICAgIHRoaXMua2VlcGFsaXZlID0gaW5wdXQua2VlcGFsaXZlO1xuICAgICAgICAgIHRoaXMuc2lnbmFsID0gaW5wdXQuc2lnbmFsO1xuICAgICAgICAgIHRoaXMuZHVwbGV4ID0gaW5wdXQuZHVwbGV4O1xuICAgICAgICAgIHRoaXMuZGVzdGluYXRpb24gPSBpbnB1dC5kZXN0aW5hdGlvbjtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgaW5pdCBpcyBwcm92aWRlZCwgbWVyZ2U6IHVzZSBzb3VyY2UgcHJvcGVydGllcywgdGhlbiBvdmVycmlkZSB3aXRoIGluaXRcbiAgICAgICAgLy8gQ29weSBhbGwgcHJvcGVydGllcyBmcm9tIHRoZSBzb3VyY2UgUmVxdWVzdCBmaXJzdFxuICAgICAgICB0aGlzLm1ldGhvZCA9IGlucHV0Lm1ldGhvZDtcbiAgICAgICAgdGhpcy5oZWFkZXJzID0gbmV3IHZtR2xvYmFsVGhpcy5IZWFkZXJzKGlucHV0LmhlYWRlcnMpO1xuICAgICAgICB0aGlzLmJvZHkgPSBpbnB1dC5ib2R5O1xuICAgICAgICB0aGlzLm1vZGUgPSBpbnB1dC5tb2RlO1xuICAgICAgICB0aGlzLmNyZWRlbnRpYWxzID0gaW5wdXQuY3JlZGVudGlhbHM7XG4gICAgICAgIHRoaXMuY2FjaGUgPSBpbnB1dC5jYWNoZTtcbiAgICAgICAgdGhpcy5yZWRpcmVjdCA9IGlucHV0LnJlZGlyZWN0O1xuICAgICAgICB0aGlzLnJlZmVycmVyID0gaW5wdXQucmVmZXJyZXI7XG4gICAgICAgIHRoaXMucmVmZXJyZXJQb2xpY3kgPSBpbnB1dC5yZWZlcnJlclBvbGljeTtcbiAgICAgICAgdGhpcy5pbnRlZ3JpdHkgPSBpbnB1dC5pbnRlZ3JpdHk7XG4gICAgICAgIHRoaXMua2VlcGFsaXZlID0gaW5wdXQua2VlcGFsaXZlO1xuICAgICAgICB0aGlzLnNpZ25hbCA9IGlucHV0LnNpZ25hbDtcbiAgICAgICAgdGhpcy5kdXBsZXggPSBpbnB1dC5kdXBsZXg7XG4gICAgICAgIHRoaXMuZGVzdGluYXRpb24gPSBpbnB1dC5kZXN0aW5hdGlvbjtcbiAgICAgIH1cblxuICAgICAgLy8gT3ZlcnJpZGUgd2l0aCBpbml0IG9wdGlvbnMgaWYgcHJvdmlkZWRcbiAgICAgIC8vIFNldCBtZXRob2RcbiAgICAgIGlmIChpbml0Py5tZXRob2QpIHtcbiAgICAgICAgdGhpcy5tZXRob2QgPSBpbml0Lm1ldGhvZC50b1VwcGVyQ2FzZSgpO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5tZXRob2QgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIC8vIEZhbGxiYWNrIHRvIGRlZmF1bHQgZm9yIHN0cmluZyBpbnB1dCBjYXNlXG4gICAgICAgIHRoaXMubWV0aG9kID0gJ0dFVCc7XG4gICAgICB9XG5cbiAgICAgIC8vIFNldCBoZWFkZXJzXG4gICAgICBpZiAoaW5pdD8uaGVhZGVycykge1xuICAgICAgICB0aGlzLmhlYWRlcnMgPSBuZXcgdm1HbG9iYWxUaGlzLkhlYWRlcnMoaW5pdC5oZWFkZXJzKTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycgfHxcbiAgICAgICAgaW5wdXQgaW5zdGFuY2VvZiB2bUdsb2JhbFRoaXMuVVJMXG4gICAgICApIHtcbiAgICAgICAgLy8gRm9yIHN0cmluZy9VUkwgaW5wdXQsIGNyZWF0ZSBlbXB0eSBoZWFkZXJzXG4gICAgICAgIHRoaXMuaGVhZGVycyA9IG5ldyB2bUdsb2JhbFRoaXMuSGVhZGVycygpO1xuICAgICAgfVxuXG4gICAgICAvLyBTZXQgb3RoZXIgcHJvcGVydGllcyB3aXRoIGluaXQgdmFsdWVzIG9yIGRlZmF1bHRzXG4gICAgICBpZiAoaW5pdD8ubW9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMubW9kZSA9IGluaXQubW9kZTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMubW9kZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGhpcy5tb2RlID0gJ2NvcnMnO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5pdD8uY3JlZGVudGlhbHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLmNyZWRlbnRpYWxzID0gaW5pdC5jcmVkZW50aWFscztcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuY3JlZGVudGlhbHMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRoaXMuY3JlZGVudGlhbHMgPSAnc2FtZS1vcmlnaW4nO1xuICAgICAgfVxuXG4gICAgICAvLyBgYW55YCBjYXN0IGhlcmUgYmVjYXVzZSBAdHlwZXMvbm9kZSB2MjIgZG9lcyBub3QgeWV0IGhhdmUgYGNhY2hlYFxuICAgICAgaWYgKChpbml0IGFzIGFueSk/LmNhY2hlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5jYWNoZSA9IChpbml0IGFzIGFueSkuY2FjaGU7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLmNhY2hlICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aGlzLmNhY2hlID0gJ2RlZmF1bHQnO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5pdD8ucmVkaXJlY3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLnJlZGlyZWN0ID0gaW5pdC5yZWRpcmVjdDtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMucmVkaXJlY3QgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRoaXMucmVkaXJlY3QgPSAnZm9sbG93JztcbiAgICAgIH1cblxuICAgICAgaWYgKGluaXQ/LnJlZmVycmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5yZWZlcnJlciA9IGluaXQucmVmZXJyZXI7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLnJlZmVycmVyICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aGlzLnJlZmVycmVyID0gJ2Fib3V0OmNsaWVudCc7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbml0Py5yZWZlcnJlclBvbGljeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMucmVmZXJyZXJQb2xpY3kgPSBpbml0LnJlZmVycmVyUG9saWN5O1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5yZWZlcnJlclBvbGljeSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGhpcy5yZWZlcnJlclBvbGljeSA9ICcnO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5pdD8uaW50ZWdyaXR5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5pbnRlZ3JpdHkgPSBpbml0LmludGVncml0eTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuaW50ZWdyaXR5ICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aGlzLmludGVncml0eSA9ICcnO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5pdD8ua2VlcGFsaXZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5rZWVwYWxpdmUgPSBpbml0LmtlZXBhbGl2ZTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMua2VlcGFsaXZlICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgdGhpcy5rZWVwYWxpdmUgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGluaXQ/LnNpZ25hbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBBYm9ydFNpZ25hbCBzdHViXG4gICAgICAgIHRoaXMuc2lnbmFsID0gaW5pdC5zaWduYWw7XG4gICAgICB9IGVsc2UgaWYgKCF0aGlzLnNpZ25hbCkge1xuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIC0gQWJvcnRTaWduYWwgc3R1YlxuICAgICAgICB0aGlzLnNpZ25hbCA9IHsgYWJvcnRlZDogZmFsc2UgfTtcbiAgICAgIH1cblxuICAgICAgaWYgKCF0aGlzLmR1cGxleCkge1xuICAgICAgICB0aGlzLmR1cGxleCA9ICdoYWxmJztcbiAgICAgIH1cblxuICAgICAgaWYgKCF0aGlzLmRlc3RpbmF0aW9uKSB7XG4gICAgICAgIHRoaXMuZGVzdGluYXRpb24gPSAnZG9jdW1lbnQnO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBib2R5ID0gaW5pdD8uYm9keTtcblxuICAgICAgLy8gVmFsaWRhdGUgdGhhdCBHRVQvSEVBRCBtZXRob2RzIGRvbid0IGhhdmUgYSBib2R5XG4gICAgICBpZiAoXG4gICAgICAgIGJvZHkgIT09IG51bGwgJiZcbiAgICAgICAgYm9keSAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICh0aGlzLm1ldGhvZCA9PT0gJ0dFVCcgfHwgdGhpcy5tZXRob2QgPT09ICdIRUFEJylcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBSZXF1ZXN0IHdpdGggR0VUL0hFQUQgbWV0aG9kIGNhbm5vdCBoYXZlIGJvZHkuYCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFN0b3JlIHRoZSBvcmlnaW5hbCBCb2R5SW5pdCBmb3Igc2VyaWFsaXphdGlvblxuICAgICAgaWYgKGJvZHkgIT09IG51bGwgJiYgYm9keSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIENyZWF0ZSBhIFwiZmFrZVwiIFJlYWRhYmxlU3RyZWFtIHRoYXQgc3RvcmVzIHRoZSBvcmlnaW5hbCBib2R5XG4gICAgICAgIC8vIFRoaXMgYXZvaWRzIGRvaW5nIGFzeW5jIHdvcmsgZHVyaW5nIHdvcmtmbG93IHJlcGxheVxuICAgICAgICB0aGlzLmJvZHkgPSBPYmplY3QuY3JlYXRlKHZtR2xvYmFsVGhpcy5SZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICAgICAgICBbQk9EWV9JTklUX1NZTUJPTF06IHtcbiAgICAgICAgICAgIHZhbHVlOiBib2R5LFxuICAgICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5ib2R5ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjbG9uZSgpOiBSZXF1ZXN0IHtcbiAgICAgIEVOT1RTVVAoKTtcbiAgICB9XG5cbiAgICBnZXQgYm9keVVzZWQoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gVE9ETzogaW1wbGVtZW50IHRoZXNlXG4gICAgYmxvYiE6ICgpID0+IFByb21pc2U8QmxvYj47XG4gICAgZm9ybURhdGEhOiAoKSA9PiBQcm9taXNlPEZvcm1EYXRhPjtcblxuICAgIGFycmF5QnVmZmVyITogKCkgPT4gUHJvbWlzZTxBcnJheUJ1ZmZlcj47XG4gICAganNvbiE6ICgpID0+IFByb21pc2U8YW55PjtcbiAgICB0ZXh0ITogKCkgPT4gUHJvbWlzZTxzdHJpbmc+O1xuXG4gICAgYXN5bmMgYnl0ZXMoKSB7XG4gICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYXdhaXQgdGhpcy5hcnJheUJ1ZmZlcigpKTtcbiAgICB9XG4gIH1cbiAgdm1HbG9iYWxUaGlzLlJlcXVlc3QgPSBSZXF1ZXN0O1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlcXVlc3QucHJvdG90eXBlLCB7XG4gICAgYXJyYXlCdWZmZXI6IHtcbiAgICAgIHZhbHVlOiB1c2VTdGVwPFtdLCBBcnJheUJ1ZmZlcj4oJ19fYnVpbHRpbl9yZXNwb25zZV9hcnJheV9idWZmZXInKSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIH0sXG4gICAganNvbjoge1xuICAgICAgdmFsdWU6IHVzZVN0ZXA8W10sIGFueT4oJ19fYnVpbHRpbl9yZXNwb25zZV9qc29uJyksXG4gICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICB9LFxuICAgIHRleHQ6IHtcbiAgICAgIHZhbHVlOiB1c2VTdGVwPFtdLCBzdHJpbmc+KCdfX2J1aWx0aW5fcmVzcG9uc2VfdGV4dCcpLFxuICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgfSxcbiAgfSk7XG5cbiAgY2xhc3MgUmVzcG9uc2UgaW1wbGVtZW50cyBnbG9iYWxUaGlzLlJlc3BvbnNlIHtcbiAgICB0eXBlITogZ2xvYmFsVGhpcy5SZXNwb25zZVsndHlwZSddO1xuICAgIHVybCE6IHN0cmluZztcbiAgICBzdGF0dXMhOiBudW1iZXI7XG4gICAgc3RhdHVzVGV4dCE6IHN0cmluZztcbiAgICBib2R5ITogUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4gfCBudWxsO1xuICAgIGhlYWRlcnMhOiBIZWFkZXJzO1xuICAgIHJlZGlyZWN0ZWQhOiBib29sZWFuO1xuXG4gICAgY29uc3RydWN0b3IoYm9keT86IGFueSwgaW5pdD86IFJlc3BvbnNlSW5pdCkge1xuICAgICAgdGhpcy5zdGF0dXMgPSBpbml0Py5zdGF0dXMgPz8gMjAwO1xuICAgICAgdGhpcy5zdGF0dXNUZXh0ID0gaW5pdD8uc3RhdHVzVGV4dCA/PyAnJztcbiAgICAgIHRoaXMuaGVhZGVycyA9IG5ldyB2bUdsb2JhbFRoaXMuSGVhZGVycyhpbml0Py5oZWFkZXJzKTtcbiAgICAgIHRoaXMudHlwZSA9ICdkZWZhdWx0JztcbiAgICAgIHRoaXMudXJsID0gJyc7XG4gICAgICB0aGlzLnJlZGlyZWN0ZWQgPSBmYWxzZTtcblxuICAgICAgLy8gVmFsaWRhdGUgdGhhdCBudWxsLWJvZHkgc3RhdHVzIGNvZGVzIGRvbid0IGhhdmUgYSBib2R5XG4gICAgICAvLyBQZXIgSFRUUCBzcGVjOiAyMDQgKE5vIENvbnRlbnQpLCAyMDUgKFJlc2V0IENvbnRlbnQpLCBhbmQgMzA0IChOb3QgTW9kaWZpZWQpXG4gICAgICBpZiAoXG4gICAgICAgIGJvZHkgIT09IG51bGwgJiZcbiAgICAgICAgYm9keSAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICh0aGlzLnN0YXR1cyA9PT0gMjA0IHx8IHRoaXMuc3RhdHVzID09PSAyMDUgfHwgdGhpcy5zdGF0dXMgPT09IDMwNClcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgIGBSZXNwb25zZSBjb25zdHJ1Y3RvcjogSW52YWxpZCByZXNwb25zZSBzdGF0dXMgY29kZSAke3RoaXMuc3RhdHVzfWBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gU3RvcmUgdGhlIG9yaWdpbmFsIEJvZHlJbml0IGZvciBzZXJpYWxpemF0aW9uXG4gICAgICBpZiAoYm9keSAhPT0gbnVsbCAmJiBib2R5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gQ3JlYXRlIGEgXCJmYWtlXCIgUmVhZGFibGVTdHJlYW0gdGhhdCBzdG9yZXMgdGhlIG9yaWdpbmFsIGJvZHlcbiAgICAgICAgLy8gVGhpcyBhdm9pZHMgZG9pbmcgYXN5bmMgd29yayBkdXJpbmcgd29ya2Zsb3cgcmVwbGF5XG4gICAgICAgIHRoaXMuYm9keSA9IE9iamVjdC5jcmVhdGUodm1HbG9iYWxUaGlzLlJlYWRhYmxlU3RyZWFtLnByb3RvdHlwZSwge1xuICAgICAgICAgIFtCT0RZX0lOSVRfU1lNQk9MXToge1xuICAgICAgICAgICAgdmFsdWU6IGJvZHksXG4gICAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmJvZHkgPSBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRPRE86IGltcGxlbWVudCB0aGVzZVxuICAgIGNsb25lITogKCkgPT4gUmVzcG9uc2U7XG4gICAgYmxvYiE6ICgpID0+IFByb21pc2U8Z2xvYmFsVGhpcy5CbG9iPjtcbiAgICBmb3JtRGF0YSE6ICgpID0+IFByb21pc2U8Z2xvYmFsVGhpcy5Gb3JtRGF0YT47XG5cbiAgICBnZXQgb2soKSB7XG4gICAgICByZXR1cm4gdGhpcy5zdGF0dXMgPj0gMjAwICYmIHRoaXMuc3RhdHVzIDwgMzAwO1xuICAgIH1cblxuICAgIGdldCBib2R5VXNlZCgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBhcnJheUJ1ZmZlciE6ICgpID0+IFByb21pc2U8QXJyYXlCdWZmZXI+O1xuICAgIGpzb24hOiAoKSA9PiBQcm9taXNlPGFueT47XG4gICAgdGV4dCE6ICgpID0+IFByb21pc2U8c3RyaW5nPjtcblxuICAgIGFzeW5jIGJ5dGVzKCkge1xuICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGF3YWl0IHRoaXMuYXJyYXlCdWZmZXIoKSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGpzb24oZGF0YTogYW55LCBpbml0PzogUmVzcG9uc2VJbml0KTogUmVzcG9uc2Uge1xuICAgICAgY29uc3QgYm9keSA9IEpTT04uc3RyaW5naWZ5KGRhdGEpO1xuICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyB2bUdsb2JhbFRoaXMuSGVhZGVycyhpbml0Py5oZWFkZXJzKTtcbiAgICAgIGlmICghaGVhZGVycy5oYXMoJ2NvbnRlbnQtdHlwZScpKSB7XG4gICAgICAgIGhlYWRlcnMuc2V0KCdjb250ZW50LXR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShib2R5LCB7IC4uLmluaXQsIGhlYWRlcnMgfSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGVycm9yKCk6IFJlc3BvbnNlIHtcbiAgICAgIEVOT1RTVVAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgcmVkaXJlY3QodXJsOiBzdHJpbmcgfCBVUkwsIHN0YXR1czogbnVtYmVyID0gMzAyKTogUmVzcG9uc2Uge1xuICAgICAgLy8gVmFsaWRhdGUgc3RhdHVzIGNvZGUgLSBvbmx5IHNwZWNpZmljIHJlZGlyZWN0IGNvZGVzIGFyZSBhbGxvd2VkXG4gICAgICBpZiAoIVszMDEsIDMwMiwgMzAzLCAzMDcsIDMwOF0uaW5jbHVkZXMoc3RhdHVzKSkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcbiAgICAgICAgICBgSW52YWxpZCByZWRpcmVjdCBzdGF0dXMgY29kZTogJHtzdGF0dXN9LiBNdXN0IGJlIG9uZSBvZjogMzAxLCAzMDIsIDMwMywgMzA3LCAzMDhgXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIENyZWF0ZSByZXNwb25zZSB3aXRoIExvY2F0aW9uIGhlYWRlclxuICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyB2bUdsb2JhbFRoaXMuSGVhZGVycygpO1xuICAgICAgaGVhZGVycy5zZXQoJ0xvY2F0aW9uJywgU3RyaW5nKHVybCkpO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IE9iamVjdC5jcmVhdGUoUmVzcG9uc2UucHJvdG90eXBlKTtcbiAgICAgIHJlc3BvbnNlLnN0YXR1cyA9IHN0YXR1cztcbiAgICAgIHJlc3BvbnNlLnN0YXR1c1RleHQgPSAnJztcbiAgICAgIHJlc3BvbnNlLmhlYWRlcnMgPSBoZWFkZXJzO1xuICAgICAgcmVzcG9uc2UuYm9keSA9IG51bGw7XG4gICAgICByZXNwb25zZS50eXBlID0gJ2RlZmF1bHQnO1xuICAgICAgcmVzcG9uc2UudXJsID0gJyc7XG4gICAgICByZXNwb25zZS5yZWRpcmVjdGVkID0gZmFsc2U7XG5cbiAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9XG4gIH1cbiAgdm1HbG9iYWxUaGlzLlJlc3BvbnNlID0gUmVzcG9uc2U7XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoUmVzcG9uc2UucHJvdG90eXBlLCB7XG4gICAgYXJyYXlCdWZmZXI6IHtcbiAgICAgIHZhbHVlOiB1c2VTdGVwPFtdLCBBcnJheUJ1ZmZlcj4oJ19fYnVpbHRpbl9yZXNwb25zZV9hcnJheV9idWZmZXInKSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIH0sXG4gICAganNvbjoge1xuICAgICAgdmFsdWU6IHVzZVN0ZXA8W10sIGFueT4oJ19fYnVpbHRpbl9yZXNwb25zZV9qc29uJyksXG4gICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICB9LFxuICAgIHRleHQ6IHtcbiAgICAgIHZhbHVlOiB1c2VTdGVwPFtdLCBzdHJpbmc+KCdfX2J1aWx0aW5fcmVzcG9uc2VfdGV4dCcpLFxuICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgfSxcbiAgfSk7XG5cbiAgY2xhc3MgUmVhZGFibGVTdHJlYW08VD4gaW1wbGVtZW50cyBnbG9iYWxUaGlzLlJlYWRhYmxlU3RyZWFtPFQ+IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgIEVOT1RTVVAoKTtcbiAgICB9XG5cbiAgICBnZXQgbG9ja2VkKCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNhbmNlbCgpOiBhbnkge1xuICAgICAgRU5PVFNVUCgpO1xuICAgIH1cblxuICAgIGdldFJlYWRlcigpOiBhbnkge1xuICAgICAgRU5PVFNVUCgpO1xuICAgIH1cblxuICAgIHBpcGVUaHJvdWdoKCk6IGFueSB7XG4gICAgICBFTk9UU1VQKCk7XG4gICAgfVxuXG4gICAgcGlwZVRvKCk6IGFueSB7XG4gICAgICBFTk9UU1VQKCk7XG4gICAgfVxuXG4gICAgdGVlKCk6IGFueSB7XG4gICAgICBFTk9UU1VQKCk7XG4gICAgfVxuXG4gICAgdmFsdWVzKCk6IGFueSB7XG4gICAgICBFTk9UU1VQKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIGZyb20oKTogYW55IHtcbiAgICAgIEVOT1RTVVAoKTtcbiAgICB9XG5cbiAgICBbU3ltYm9sLmFzeW5jSXRlcmF0b3JdKCk6IGFueSB7XG4gICAgICBFTk9UU1VQKCk7XG4gICAgfVxuICB9XG4gIHZtR2xvYmFsVGhpcy5SZWFkYWJsZVN0cmVhbSA9IFJlYWRhYmxlU3RyZWFtO1xuXG4gIGNsYXNzIFdyaXRhYmxlU3RyZWFtPFQ+IGltcGxlbWVudHMgZ2xvYmFsVGhpcy5Xcml0YWJsZVN0cmVhbTxUPiB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICBFTk9UU1VQKCk7XG4gICAgfVxuXG4gICAgZ2V0IGxvY2tlZCgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBhYm9ydCgpOiBhbnkge1xuICAgICAgRU5PVFNVUCgpO1xuICAgIH1cblxuICAgIGNsb3NlKCk6IGFueSB7XG4gICAgICBFTk9UU1VQKCk7XG4gICAgfVxuXG4gICAgZ2V0V3JpdGVyKCk6IGFueSB7XG4gICAgICBFTk9UU1VQKCk7XG4gICAgfVxuICB9XG4gIHZtR2xvYmFsVGhpcy5Xcml0YWJsZVN0cmVhbSA9IFdyaXRhYmxlU3RyZWFtO1xuXG4gIGNsYXNzIFRyYW5zZm9ybVN0cmVhbTxJLCBPPiBpbXBsZW1lbnRzIGdsb2JhbFRoaXMuVHJhbnNmb3JtU3RyZWFtPEksIE8+IHtcbiAgICByZWFkYWJsZTogZ2xvYmFsVGhpcy5SZWFkYWJsZVN0cmVhbTxPPjtcbiAgICB3cml0YWJsZTogZ2xvYmFsVGhpcy5Xcml0YWJsZVN0cmVhbTxJPjtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgRU5PVFNVUCgpO1xuICAgIH1cbiAgfVxuICB2bUdsb2JhbFRoaXMuVHJhbnNmb3JtU3RyZWFtID0gVHJhbnNmb3JtU3RyZWFtO1xuXG4gIHZtR2xvYmFsVGhpcy5jb25zb2xlID0gZ2xvYmFsVGhpcy5jb25zb2xlO1xuXG4gIC8vIEV4cG9zZSB0aGUgcmVxdWVzdC1jb250ZXh0IHN5bWJvbCByZXF1aXJlZCBieSBBSSBHYXRld2F5LlxuICBjb25zdCBTWU1CT0xfRk9SX1JFUV9DT05URVhUID0gU3ltYm9sLmZvcignQHZlcmNlbC9yZXF1ZXN0LWNvbnRleHQnKTtcbiAgLy8gQHRzLWV4cGVjdC1lcnJvciAtIGBAdHlwZXMvbm9kZWAgc2F5cyBzeW1ib2wgaXMgbm90IHZhbGlkLCBidXQgaXQgZG9lcyB3b3JrXG4gIHZtR2xvYmFsVGhpc1tTWU1CT0xfRk9SX1JFUV9DT05URVhUXSA9IChnbG9iYWxUaGlzIGFzIGFueSlbXG4gICAgU1lNQk9MX0ZPUl9SRVFfQ09OVEVYVFxuICBdO1xuXG4gIC8vIEdldCBhIHJlZmVyZW5jZSB0byB0aGUgdXNlci1kZWZpbmVkIHdvcmtmbG93IGZ1bmN0aW9uLlxuICAvLyBUaGUgZmlsZW5hbWUgcGFyYW1ldGVyIGVuc3VyZXMgc3RhY2sgdHJhY2VzIHNob3cgYSBtZWFuaW5nZnVsIG5hbWVcbiAgLy8gKGUuZy4sIFwiZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzXCIpIGluc3RlYWQgb2YgXCJldmFsbWFjaGluZS48YW5vbnltb3VzPlwiLlxuICBjb25zdCBwYXJzZWROYW1lID0gcGFyc2VXb3JrZmxvd05hbWUod29ya2Zsb3dSdW4ud29ya2Zsb3dOYW1lKTtcbiAgY29uc3QgZmlsZW5hbWUgPSBwYXJzZWROYW1lPy5tb2R1bGVTcGVjaWZpZXIgfHwgd29ya2Zsb3dSdW4ud29ya2Zsb3dOYW1lO1xuXG4gIC8vIFJldXNlIGNvbXBpbGVkIHNjcmlwdHMgYnkgYChjb2RlLCBmaWxlbmFtZSlgOiBjb21waWxhdGlvbiBpcyBkZXRlcm1pbmlzdGljXG4gIC8vIGFuZCB0aGUgZmlsZW5hbWUgcHJlc2VydmVzIHdvcmtmbG93IHNvdXJjZSBhdHRyaWJ1dGlvbiBpbiBzdGFjayB0cmFjZXMuXG4gIC8vIFRoZSBidW5kbGUgcmVnaXN0ZXJzIHdvcmtmbG93cyBvbiBgZ2xvYmFsVGhpcy5fX3ByaXZhdGVfd29ya2Zsb3dzYC5cbiAgcnVuQ2FjaGVkV29ya2Zsb3dTY3JpcHQod29ya2Zsb3dDb2RlLCBmaWxlbmFtZSwgY29udGV4dCk7XG4gIGNvbnN0IHdvcmtmbG93Rm4gPSBydW5DYWNoZWRXb3JrZmxvd1NjcmlwdChcbiAgICBgZ2xvYmFsVGhpcy5fX3ByaXZhdGVfd29ya2Zsb3dzPy5nZXQoJHtKU09OLnN0cmluZ2lmeSh3b3JrZmxvd1J1bi53b3JrZmxvd05hbWUpfSlgLFxuICAgIGZpbGVuYW1lLFxuICAgIGNvbnRleHRcbiAgKTtcblxuICBpZiAodHlwZW9mIHdvcmtmbG93Rm4gIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgV29ya2Zsb3dOb3RSZWdpc3RlcmVkRXJyb3Iod29ya2Zsb3dSdW4ud29ya2Zsb3dOYW1lKTtcbiAgfVxuXG4gIC8vIENoYWluIHdvcmtmbG93IGFyZ3VtZW50IGh5ZHJhdGlvbiBvbnRvIHRoZSBwcm9taXNlUXVldWUgc28gdGhhdCB0aGVcbiAgLy8gdW5jb25zdW1lZCBldmVudCBjaGVjayAod2hpY2ggd2FpdHMgZm9yIHRoZSBxdWV1ZSB0byBkcmFpbikgZG9lc24ndFxuICAvLyBmaXJlIGR1cmluZyB0aGUgYXN5bmMgZ2FwIGJldHdlZW4gcnVuX3N0YXJ0ZWQgY29uc3VtcHRpb24gYW5kIHRoZVxuICAvLyB3b3JrZmxvdyBmdW5jdGlvbiBzdWJzY3JpYmluZyBpdHMgZmlyc3Qgc3RlcCBjYWxsYmFja3MuXG4gIGxldCBhcmdzOiB1bmtub3duW10gPSBbXTtcbiAgd29ya2Zsb3dDb250ZXh0LnByb21pc2VRdWV1ZSA9IHdvcmtmbG93Q29udGV4dC5wcm9taXNlUXVldWUudGhlbihhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcHJlcGFyZWQgPSBhd2FpdCByZXBsYXlQYXlsb2FkQ2FjaGUucHJlcGFyZVdvcmtmbG93SW5wdXQod29ya2Zsb3dSdW4pO1xuICAgIGFyZ3MgPSBhd2FpdCBoeWRyYXRlV29ya2Zsb3dBcmd1bWVudHMoXG4gICAgICB3b3JrZmxvd1J1bi5pbnB1dCxcbiAgICAgIHdvcmtmbG93UnVuLnJ1bklkLFxuICAgICAgZW5jcnlwdGlvbktleSxcbiAgICAgIHZtR2xvYmFsVGhpcyxcbiAgICAgIHt9LFxuICAgICAgcHJlcGFyZWRcbiAgICApO1xuICB9KTtcbiAgYXdhaXQgd29ya2Zsb3dDb250ZXh0LnByb21pc2VRdWV1ZTtcblxuICAvLyBUaGUgdXNlciBmdW5jdGlvbidzIHByb21pc2UuIEl0IG1heSBzdGF5IHBlbmRpbmcgYWNyb3NzIG1hbnkgcmVzdW1lc1xuICAvLyAoZWFjaCBwYXJrZWQgc3RlcCBwcm9taXNlIGhvbGRzIGl0IHVwKSBhbmQgaXMgcmFjZWQgYWdhaW5zdCB0aGUgY3VycmVudFxuICAvLyBhdHRlbXB0J3MgaW50ZXJydXB0aW9uIGluIHdhaXRGb3JFeGVjdXRpb24uXG4gIGNvbnN0IHdvcmtmbG93Qm9keSA9IChhc3luYyAoKTogUHJvbWlzZTx1bmtub3duPiA9PiB7XG4gICAgcmV0dXJuIGF3YWl0IHdvcmtmbG93Rm4oLi4uYXJncyk7XG4gIH0pKCk7XG5cbiAgY29uc3QgZmFpbFdvcmtmbG93ID0gYXN5bmMgKGVycm9yOiB1bmtub3duKTogUHJvbWlzZTxuZXZlcj4gPT4ge1xuICAgIC8vIENvbnRyb2wtZmxvdyBzaWduYWxzIGFyZSBoYW5kbGVkIGJ5IHRoZSBydW50aW1lIGFuZCBkbyBub3QgbWVhbiB0aGVcbiAgICAvLyB3b3JrZmxvdyBoYXMgdGVybWluYWxseSBmYWlsZWQuIGBvbldvcmtmbG93RXJyb3JgIHVzdWFsbHkgYWxyZWFkeSBtb3ZlZFxuICAgIC8vIHRoZSBzdGF0ZSBtYWNoaW5lLCBidXQgYSBkaXZlcmdlbmNlIGNhbiBhbHNvIGFycml2ZSB2aWEgYSBzdGVwXG4gICAgLy8gcHJvbWlzZSdzIGRpcmVjdCByZWplY3Rpb24gKGJ5cGFzc2luZyBgb25Xb3JrZmxvd0Vycm9yYCkg4oCUIGRlbW90ZSBzb1xuICAgIC8vIGV2ZXJ5IGNvbnRyb2wtZmxvdyBwYXRoIGNvbnZlcmdlcyBvbiBgcmVwbGF5YCBhbmQgYSBsYXRlciByZXN1bWUgZmFsbHNcbiAgICAvLyBiYWNrIGluc3RlYWQgb2YgdGhyb3dpbmcuXG4gICAgaWYgKFdvcmtmbG93U3VzcGVuc2lvbi5pcyhlcnJvcikgfHwgUmVwbGF5RGl2ZXJnZW5jZUVycm9yLmlzKGVycm9yKSkge1xuICAgICAgaWYgKHN0YXRlLnR5cGUgPT09ICdydW5uaW5nJykgc3RhdGUgPSB7IHR5cGU6ICdyZXBsYXknIH07XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gICAgc3RhdGUgPSB7IHR5cGU6ICdjb21wbGV0ZWQnIH07XG5cbiAgICBhd2FpdCBkcmFpblBlbmRpbmdRdWV1ZUl0ZW1zKFxuICAgICAgd29ya2Zsb3dSdW4ucnVuSWQsXG4gICAgICB3b3JrZmxvd0NvbnRleHQuaW52b2NhdGlvbnNRdWV1ZSxcbiAgICAgIHZtR2xvYmFsVGhpcyxcbiAgICAgIHdvcmtmbG93UnVuLFxuICAgICAgJ2ZhaWxlZCcsXG4gICAgICBydW5SZWFkeUJhcnJpZXJcbiAgICApO1xuXG4gICAgdGhyb3cgZXJyb3I7XG4gIH07XG5cbiAgY29uc3Qgd2FpdEZvckV4ZWN1dGlvbiA9IGFzeW5jIChcbiAgICBpbnRlcnJ1cHRpb246IFByb21pc2VXaXRoUmVzb2x2ZXJzPG5ldmVyPlxuICApOiBQcm9taXNlPFdvcmtmbG93UmVzdWx0PiA9PiB7XG4gICAgbGV0IHJlc3VsdDogdW5rbm93bjtcbiAgICB0cnkge1xuICAgICAgcmVzdWx0ID0gYXdhaXQgUHJvbWlzZS5yYWNlKFt3b3JrZmxvd0JvZHksIGludGVycnVwdGlvbi5wcm9taXNlXSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChzdGF0ZS50eXBlID09PSAnc3VzcGVuZGVkJyAmJiBlcnJvciA9PT0gc3RhdGUuc3VzcGVuc2lvbikge1xuICAgICAgICByZXR1cm4geyB0eXBlOiAnc3VzcGVuZGVkJywgc3VzcGVuc2lvbjogc3RhdGUuc3VzcGVuc2lvbiwgc2Vzc2lvbiB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhaWxXb3JrZmxvdyhlcnJvcik7XG4gICAgfVxuXG4gICAgc3RhdGUgPSB7IHR5cGU6ICdjb21wbGV0ZWQnIH07XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG91dHB1dCA9IGF3YWl0IGRlaHlkcmF0ZVdvcmtmbG93UmV0dXJuVmFsdWUoXG4gICAgICAgIHJlc3VsdCxcbiAgICAgICAgd29ya2Zsb3dSdW4ucnVuSWQsXG4gICAgICAgIGVuY3J5cHRpb25LZXksXG4gICAgICAgIHZtR2xvYmFsVGhpcyxcbiAgICAgICAgZmFsc2UsXG4gICAgICAgIC8vIE9ubHkgY29tcHJlc3Npb24tY2FwYWJsZSBydW5zIChzcGVjID49IDUpIG1heSB3cml0ZSBjb21wcmVzc2VkXG4gICAgICAgIC8vIHBheWxvYWRzLiBUaGUgc2VyaWFsaXplciB1c2VzIHpzdGQgd2hlbiBzdXBwb3J0ZWQgYW5kIG1heSB1c2UgZ3ppcC5cbiAgICAgICAgKHdvcmtmbG93UnVuLnNwZWNWZXJzaW9uID8/IDApID49IFNQRUNfVkVSU0lPTl9TVVBQT1JUU19DT01QUkVTU0lPTlxuICAgICAgKTtcblxuICAgICAgYXdhaXQgZHJhaW5QZW5kaW5nUXVldWVJdGVtcyhcbiAgICAgICAgd29ya2Zsb3dSdW4ucnVuSWQsXG4gICAgICAgIHdvcmtmbG93Q29udGV4dC5pbnZvY2F0aW9uc1F1ZXVlLFxuICAgICAgICB2bUdsb2JhbFRoaXMsXG4gICAgICAgIHdvcmtmbG93UnVuLFxuICAgICAgICAnY29tcGxldGVkJyxcbiAgICAgICAgcnVuUmVhZHlCYXJyaWVyXG4gICAgICApO1xuXG4gICAgICByZXR1cm4geyB0eXBlOiAnY29tcGxldGVkJywgb3V0cHV0LCByZXN1bHRUeXBlOiB0eXBlb2YgcmVzdWx0IH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBmYWlsV29ya2Zsb3coZXJyb3IpO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBzZXNzaW9uOiBXb3JrZmxvd1Nlc3Npb24gPSB7XG4gICAgd29ya2Zsb3dSdW4sXG4gICAgYXJndW1lbnRDb3VudDogYXJncy5sZW5ndGgsXG4gICAgYXN5bmMgcmVzdW1lKG5leHRFdmVudHMpIHtcbiAgICAgIHN3aXRjaCAoc3RhdGUudHlwZSkge1xuICAgICAgICBjYXNlICdzdXNwZW5kZWQnOiB7XG4gICAgICAgICAgLy8gVGhlIGZ1bGwgTyhrbm93biBldmVudHMpIHByZWZpeCBjb21wYXJlIGlzIHJlcXVpcmVkOiB0aGUgcnVudGltZVxuICAgICAgICAgIC8vIHVzdWFsbHkgZ3Jvd3Mgb25lIGFycmF5IGluIHBsYWNlLCBidXQgaXRzIHdhaXQtY29tcGxldGlvbiBhbmRcbiAgICAgICAgICAvLyBzdGFsZS1yZWxvYWQgcGF0aHMgUkVQTEFDRSB0aGUgYXJyYXkgd2l0aCBhIGZyZXNoIGZ1bGwgZmV0Y2gsIHNvXG4gICAgICAgICAgLy8gYSByZXdyaXR0ZW4gcHJlZml4IGlzIGEgcmVhbCBpbnB1dCwgbm90IHBhcmFub2lhLiBUaGUgY29tcGFyZXNcbiAgICAgICAgICAvLyBhcmUgY2hlYXAgc3RyaW5nIGVxdWFsaXR5IGFuZCBkd2FyZmVkIGJ5IHRoZSByZXBsYXkgdGhleSBhdm9pZC5cbiAgICAgICAgICBjb25zdCBrbm93bkV2ZW50cyA9IGV2ZW50c0NvbnN1bWVyLmV2ZW50cztcbiAgICAgICAgICBjb25zdCBpc1N0cmljdEV4dGVuc2lvbiA9XG4gICAgICAgICAgICBuZXh0RXZlbnRzLmxlbmd0aCA+IGtub3duRXZlbnRzLmxlbmd0aCAmJlxuICAgICAgICAgICAga25vd25FdmVudHMuZXZlcnkoXG4gICAgICAgICAgICAgIChldmVudCwgaW5kZXgpID0+IGV2ZW50LmV2ZW50SWQgPT09IG5leHRFdmVudHNbaW5kZXhdLmV2ZW50SWRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKCFpc1N0cmljdEV4dGVuc2lvbikge1xuICAgICAgICAgICAgc3RhdGUgPSB7IHR5cGU6ICdyZXBsYXknIH07XG4gICAgICAgICAgICByZXR1cm4geyB0eXBlOiAncmVwbGF5JyB9O1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBpbnRlcnJ1cHRpb24gPSB3aXRoUmVzb2x2ZXJzPG5ldmVyPigpO1xuICAgICAgICAgIHN0YXRlID0geyB0eXBlOiAncnVubmluZycsIGludGVycnVwdGlvbiB9O1xuICAgICAgICAgIHdvcmtmbG93Q29udGV4dC5zdXNwZW5zaW9uR2VuZXJhdGlvbisrO1xuICAgICAgICAgIGV2ZW50c0NvbnN1bWVyLmFwcGVuZChuZXh0RXZlbnRzLnNsaWNlKGtub3duRXZlbnRzLmxlbmd0aCkpO1xuICAgICAgICAgIHJldHVybiB3YWl0Rm9yRXhlY3V0aW9uKGludGVycnVwdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAncmVwbGF5JzpcbiAgICAgICAgICByZXR1cm4geyB0eXBlOiAncmVwbGF5JyB9O1xuICAgICAgICBjYXNlICdjb21wbGV0ZWQnOlxuICAgICAgICBjYXNlICdydW5uaW5nJzpcbiAgICAgICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IoXG4gICAgICAgICAgICBgQ2Fubm90IHJlc3VtZSAke3N0YXRlLnR5cGV9IHdvcmtmbG93IFwiJHt3b3JrZmxvd1J1bi5ydW5JZH1cImBcbiAgICAgICAgICApO1xuICAgICAgfVxuICAgICAgc3RhdGUgc2F0aXNmaWVzIG5ldmVyO1xuICAgIH0sXG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBzZXNzaW9uLFxuICAgIGV4ZWN1dGlvbjogd2FpdEZvckV4ZWN1dGlvbihpbml0aWFsSW50ZXJydXB0aW9uKSxcbiAgfTtcbn1cbiJdfQ==