@workflow/core 5.0.0-beta.4 → 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.
- package/dist/attribute-changes.d.ts +7 -0
- package/dist/attribute-changes.d.ts.map +1 -0
- package/dist/attribute-changes.js +25 -0
- package/dist/capabilities.d.ts +33 -1
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +71 -4
- package/dist/capture-stack.d.ts +16 -0
- package/dist/capture-stack.d.ts.map +1 -0
- package/dist/capture-stack.js +21 -0
- package/dist/class-serialization.d.ts +32 -0
- package/dist/class-serialization.d.ts.map +1 -1
- package/dist/class-serialization.js +37 -1
- package/dist/classify-error.d.ts +26 -3
- package/dist/classify-error.d.ts.map +1 -1
- package/dist/classify-error.js +109 -6
- package/dist/context-errors.d.ts +27 -0
- package/dist/context-errors.d.ts.map +1 -0
- package/dist/context-errors.js +101 -0
- package/dist/context-violation-error.d.ts +97 -0
- package/dist/context-violation-error.d.ts.map +1 -0
- package/dist/context-violation-error.js +149 -0
- package/dist/correlation-id.d.ts +109 -0
- package/dist/correlation-id.d.ts.map +1 -0
- package/dist/correlation-id.js +139 -0
- package/dist/create-hook.d.ts +62 -4
- package/dist/create-hook.d.ts.map +1 -1
- package/dist/create-hook.js +4 -3
- package/dist/define-hook.d.ts.map +1 -1
- package/dist/define-hook.js +20 -5
- package/dist/describe-error.d.ts +70 -0
- package/dist/describe-error.d.ts.map +1 -0
- package/dist/describe-error.js +189 -0
- package/dist/encryption.d.ts +37 -3
- package/dist/encryption.d.ts.map +1 -1
- package/dist/encryption.js +97 -31
- package/dist/events-consumer.d.ts +26 -1
- package/dist/events-consumer.d.ts.map +1 -1
- package/dist/events-consumer.js +105 -18
- package/dist/flushable-stream.d.ts +65 -10
- package/dist/flushable-stream.d.ts.map +1 -1
- package/dist/flushable-stream.js +131 -18
- package/dist/global.d.ts +37 -1
- package/dist/global.d.ts.map +1 -1
- package/dist/global.js +21 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/log-format.d.ts +25 -0
- package/dist/log-format.d.ts.map +1 -0
- package/dist/log-format.js +250 -0
- package/dist/logger.d.ts +29 -30
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +82 -32
- package/dist/private.d.ts +178 -9
- package/dist/private.d.ts.map +1 -1
- package/dist/private.js +273 -9
- package/dist/replay-payload-cache.d.ts +68 -0
- package/dist/replay-payload-cache.d.ts.map +1 -0
- package/dist/replay-payload-cache.js +160 -0
- package/dist/runtime/compute-instance.d.ts +12 -0
- package/dist/runtime/compute-instance.d.ts.map +1 -0
- package/dist/runtime/compute-instance.js +13 -0
- package/dist/runtime/constants.d.ts +237 -0
- package/dist/runtime/constants.d.ts.map +1 -1
- package/dist/runtime/constants.js +405 -15
- package/dist/runtime/count-step-started-events.d.ts +52 -0
- package/dist/runtime/count-step-started-events.d.ts.map +1 -0
- package/dist/runtime/count-step-started-events.js +72 -0
- package/dist/runtime/deployment-guard.d.ts +99 -0
- package/dist/runtime/deployment-guard.d.ts.map +1 -0
- package/dist/runtime/deployment-guard.js +154 -0
- package/dist/runtime/get-port-lazy.d.ts +25 -0
- package/dist/runtime/get-port-lazy.d.ts.map +1 -0
- package/dist/runtime/get-port-lazy.js +92 -0
- package/dist/runtime/get-world-lazy.d.ts +23 -0
- package/dist/runtime/get-world-lazy.d.ts.map +1 -0
- package/dist/runtime/get-world-lazy.js +46 -0
- package/dist/runtime/helpers.d.ts +219 -10
- package/dist/runtime/helpers.d.ts.map +1 -1
- package/dist/runtime/helpers.js +414 -40
- package/dist/runtime/quickjs-assets.generated.d.ts +14 -0
- package/dist/runtime/quickjs-assets.generated.d.ts.map +1 -0
- package/dist/runtime/quickjs-assets.generated.js +30 -0
- package/dist/runtime/quickjs-entrypoint.d.ts +124 -0
- package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -0
- package/dist/runtime/quickjs-entrypoint.js +1429 -0
- package/dist/runtime/quickjs-runtime.d.ts +193 -0
- package/dist/runtime/quickjs-runtime.d.ts.map +1 -0
- package/dist/runtime/quickjs-runtime.js +1944 -0
- package/dist/runtime/replay-budget.d.ts +98 -0
- package/dist/runtime/replay-budget.d.ts.map +1 -0
- package/dist/runtime/replay-budget.js +192 -0
- package/dist/runtime/replay-recovery-reporter.d.ts +36 -0
- package/dist/runtime/replay-recovery-reporter.d.ts.map +1 -0
- package/dist/runtime/replay-recovery-reporter.js +64 -0
- package/dist/runtime/resume-hook.d.ts +27 -4
- package/dist/runtime/resume-hook.d.ts.map +1 -1
- package/dist/runtime/resume-hook.js +448 -76
- package/dist/runtime/run-id-time.d.ts +19 -0
- package/dist/runtime/run-id-time.d.ts.map +1 -0
- package/dist/runtime/run-id-time.js +42 -0
- package/dist/runtime/run.d.ts +8 -2
- package/dist/runtime/run.d.ts.map +1 -1
- package/dist/runtime/run.js +62 -15
- package/dist/runtime/runs.d.ts +54 -3
- package/dist/runtime/runs.d.ts.map +1 -1
- package/dist/runtime/runs.js +117 -10
- package/dist/runtime/start.d.ts +70 -1
- package/dist/runtime/start.d.ts.map +1 -1
- package/dist/runtime/start.js +312 -54
- package/dist/runtime/step-executor.d.ts +177 -0
- package/dist/runtime/step-executor.d.ts.map +1 -0
- package/dist/runtime/step-executor.js +949 -0
- package/dist/runtime/step-latency.d.ts +197 -0
- package/dist/runtime/step-latency.d.ts.map +1 -0
- package/dist/runtime/step-latency.js +207 -0
- package/dist/runtime/step-ownership.d.ts +72 -0
- package/dist/runtime/step-ownership.d.ts.map +1 -0
- package/dist/runtime/step-ownership.js +114 -0
- package/dist/runtime/step-single-flight.d.ts +12 -0
- package/dist/runtime/step-single-flight.d.ts.map +1 -0
- package/dist/runtime/step-single-flight.js +69 -0
- package/dist/runtime/suspension-handler.d.ts +102 -7
- package/dist/runtime/suspension-handler.d.ts.map +1 -1
- package/dist/runtime/suspension-handler.js +439 -140
- package/dist/runtime/vm-mode.d.ts +44 -0
- package/dist/runtime/vm-mode.d.ts.map +1 -0
- package/dist/runtime/vm-mode.js +62 -0
- package/dist/runtime/vm-serde-bundle.generated.d.ts +14 -0
- package/dist/runtime/vm-serde-bundle.generated.d.ts.map +1 -0
- package/dist/runtime/vm-serde-bundle.generated.js +16 -0
- package/dist/runtime/wait-continuation.d.ts +84 -0
- package/dist/runtime/wait-continuation.d.ts.map +1 -0
- package/dist/runtime/wait-continuation.js +105 -0
- package/dist/runtime/wait-until.d.ts +18 -0
- package/dist/runtime/wait-until.d.ts.map +1 -0
- package/dist/runtime/wait-until.js +42 -0
- package/dist/runtime/world-compatibility.d.ts +5 -0
- package/dist/runtime/world-compatibility.d.ts.map +1 -0
- package/dist/runtime/world-compatibility.js +12 -0
- package/dist/runtime/world-init.d.ts +50 -0
- package/dist/runtime/world-init.d.ts.map +1 -0
- package/dist/runtime/world-init.js +50 -0
- package/dist/runtime/world.d.ts +14 -2
- package/dist/runtime/world.d.ts.map +1 -1
- package/dist/runtime/world.js +101 -26
- package/dist/runtime.d.ts +17 -12
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +3078 -327
- package/dist/schemas.d.ts +1 -1
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +1 -1
- package/dist/sealed-box.d.ts +167 -0
- package/dist/sealed-box.d.ts.map +1 -0
- package/dist/sealed-box.js +571 -0
- package/dist/serialization/client.d.ts +17 -0
- package/dist/serialization/client.d.ts.map +1 -0
- package/dist/serialization/client.js +48 -0
- package/dist/serialization/codec-devalue-vm.d.ts +9 -0
- package/dist/serialization/codec-devalue-vm.d.ts.map +1 -0
- package/dist/serialization/codec-devalue-vm.js +137 -0
- package/dist/serialization/codec-devalue.d.ts +14 -0
- package/dist/serialization/codec-devalue.d.ts.map +1 -0
- package/dist/serialization/codec-devalue.js +105 -0
- package/dist/serialization/codec.d.ts +125 -0
- package/dist/serialization/codec.d.ts.map +1 -0
- package/dist/serialization/codec.js +17 -0
- package/dist/serialization/compression.d.ts +104 -0
- package/dist/serialization/compression.d.ts.map +1 -0
- package/dist/serialization/compression.js +260 -0
- package/dist/serialization/encryption.d.ts +134 -0
- package/dist/serialization/encryption.d.ts.map +1 -0
- package/dist/serialization/encryption.js +186 -0
- package/dist/serialization/errors.d.ts +34 -0
- package/dist/serialization/errors.d.ts.map +1 -0
- package/dist/serialization/errors.js +59 -0
- package/dist/serialization/format.d.ts +60 -0
- package/dist/serialization/format.d.ts.map +1 -0
- package/dist/serialization/format.js +97 -0
- package/dist/serialization/hardened.d.ts +155 -0
- package/dist/serialization/hardened.d.ts.map +1 -0
- package/dist/serialization/hardened.js +523 -0
- package/dist/serialization/index.d.ts +20 -0
- package/dist/serialization/index.d.ts.map +1 -0
- package/dist/serialization/index.js +22 -0
- package/dist/serialization/reducers/class-vm.d.ts +20 -0
- package/dist/serialization/reducers/class-vm.d.ts.map +1 -0
- package/dist/serialization/reducers/class-vm.js +77 -0
- package/dist/serialization/reducers/class.d.ts +11 -0
- package/dist/serialization/reducers/class.d.ts.map +1 -0
- package/dist/serialization/reducers/class.js +73 -0
- package/dist/serialization/reducers/common-vm.d.ts +15 -0
- package/dist/serialization/reducers/common-vm.d.ts.map +1 -0
- package/dist/serialization/reducers/common-vm.js +579 -0
- package/dist/serialization/reducers/common.d.ts +16 -0
- package/dist/serialization/reducers/common.d.ts.map +1 -0
- package/dist/serialization/reducers/common.js +478 -0
- package/dist/serialization/reducers/step-function-vm.d.ts +44 -0
- package/dist/serialization/reducers/step-function-vm.d.ts.map +1 -0
- package/dist/serialization/reducers/step-function-vm.js +97 -0
- package/dist/serialization/reducers/step-function.d.ts +35 -0
- package/dist/serialization/reducers/step-function.d.ts.map +1 -0
- package/dist/serialization/reducers/step-function.js +104 -0
- package/dist/serialization/step.d.ts +17 -0
- package/dist/serialization/step.d.ts.map +1 -0
- package/dist/serialization/step.js +48 -0
- package/dist/serialization/types.d.ts +273 -0
- package/dist/serialization/types.d.ts.map +1 -0
- package/dist/serialization/types.js +35 -0
- package/dist/serialization/vm-bundle-entry.d.ts +12 -0
- package/dist/serialization/vm-bundle-entry.d.ts.map +1 -0
- package/dist/serialization/vm-bundle-entry.js +58 -0
- package/dist/serialization/workflow-vm.d.ts +24 -0
- package/dist/serialization/workflow-vm.d.ts.map +1 -0
- package/dist/serialization/workflow-vm.js +66 -0
- package/dist/serialization/workflow.d.ts +29 -0
- package/dist/serialization/workflow.d.ts.map +1 -0
- package/dist/serialization/workflow.js +54 -0
- package/dist/serialization-format.d.ts +60 -4
- package/dist/serialization-format.d.ts.map +1 -1
- package/dist/serialization-format.js +276 -56
- package/dist/serialization.d.ts +374 -221
- package/dist/serialization.d.ts.map +1 -1
- package/dist/serialization.js +2300 -783
- package/dist/set-attributes.d.ts +13 -0
- package/dist/set-attributes.d.ts.map +1 -0
- package/dist/set-attributes.js +60 -0
- package/dist/sleep.d.ts.map +1 -1
- package/dist/sleep.js +3 -2
- package/dist/source-map.d.ts +25 -0
- package/dist/source-map.d.ts.map +1 -1
- package/dist/source-map.js +148 -10
- package/dist/step/context-storage.d.ts +61 -2
- package/dist/step/context-storage.d.ts.map +1 -1
- package/dist/step/context-storage.js +7 -5
- package/dist/step/get-closure-vars.d.ts.map +1 -1
- package/dist/step/get-closure-vars.js +3 -2
- package/dist/step/get-step-metadata.d.ts.map +1 -1
- package/dist/step/get-step-metadata.js +3 -2
- package/dist/step/get-workflow-metadata.d.ts.map +1 -1
- package/dist/step/get-workflow-metadata.js +3 -2
- package/dist/step/writable-stream.d.ts.map +1 -1
- package/dist/step/writable-stream.js +71 -7
- package/dist/step.d.ts.map +1 -1
- package/dist/step.js +226 -30
- package/dist/symbols.d.ts +54 -0
- package/dist/symbols.d.ts.map +1 -1
- package/dist/symbols.js +55 -1
- package/dist/telemetry/semantic-conventions.d.ts +242 -2
- package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
- package/dist/telemetry/semantic-conventions.js +173 -1
- package/dist/telemetry.d.ts +73 -0
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +153 -16
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +23 -1
- package/dist/util.d.ts +16 -6
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +25 -16
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +2 -2
- package/dist/vm/index.d.ts.map +1 -1
- package/dist/vm/index.js +77 -9
- package/dist/vm/script-cache.d.ts +28 -0
- package/dist/vm/script-cache.d.ts.map +1 -0
- package/dist/vm/script-cache.js +140 -0
- package/dist/workflow/abort-controller.d.ts +65 -0
- package/dist/workflow/abort-controller.d.ts.map +1 -0
- package/dist/workflow/abort-controller.js +314 -0
- package/dist/workflow/attribute-dispatcher.d.ts +6 -0
- package/dist/workflow/attribute-dispatcher.d.ts.map +1 -0
- package/dist/workflow/attribute-dispatcher.js +48 -0
- package/dist/workflow/create-hook.d.ts.map +1 -1
- package/dist/workflow/create-hook.js +25 -3
- package/dist/workflow/define-hook.d.ts +1 -1
- package/dist/workflow/define-hook.d.ts.map +1 -1
- package/dist/workflow/define-hook.js +8 -4
- package/dist/workflow/get-workflow-metadata.d.ts.map +1 -1
- package/dist/workflow/get-workflow-metadata.js +14 -3
- package/dist/workflow/hook.d.ts.map +1 -1
- package/dist/workflow/hook.js +303 -37
- package/dist/workflow/index.d.ts +1 -0
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js +5 -3
- package/dist/workflow/set-attributes.d.ts +68 -0
- package/dist/workflow/set-attributes.d.ts.map +1 -0
- package/dist/workflow/set-attributes.js +60 -0
- package/dist/workflow/sleep.d.ts.map +1 -1
- package/dist/workflow/sleep.js +58 -9
- package/dist/workflow/world-init-stub.d.ts +15 -0
- package/dist/workflow/world-init-stub.d.ts.map +1 -0
- package/dist/workflow/world-init-stub.js +15 -0
- package/dist/workflow.d.ts +69 -3
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +791 -554
- package/docs/api-reference/create-hook.mdx +79 -0
- package/docs/api-reference/create-webhook.mdx +1 -0
- package/docs/api-reference/define-hook.mdx +26 -24
- package/docs/api-reference/fatal-error.mdx +29 -7
- package/docs/api-reference/fetch.mdx +8 -4
- package/docs/api-reference/index.mdx +3 -0
- package/docs/api-reference/set-attributes.mdx +61 -0
- package/docs/api-reference/sleep.mdx +1 -1
- package/docs/foundations/cancellation.mdx +459 -0
- package/docs/foundations/errors-and-retries.mdx +7 -3
- package/docs/foundations/hooks.mdx +29 -0
- package/docs/foundations/idempotency.mdx +243 -11
- package/docs/foundations/index.mdx +1 -23
- package/docs/foundations/meta.json +3 -1
- package/docs/foundations/serialization.mdx +77 -41
- package/docs/foundations/starting-workflows.mdx +79 -2
- package/docs/foundations/streaming.mdx +14 -23
- package/docs/foundations/versioning.mdx +263 -0
- package/docs/how-it-works/cancellation.mdx +287 -0
- package/docs/how-it-works/code-transform.mdx +21 -17
- package/docs/how-it-works/encryption.mdx +5 -5
- package/docs/how-it-works/event-sourcing.mdx +6 -6
- package/docs/how-it-works/framework-integrations.mdx +96 -337
- package/docs/how-it-works/meta.json +2 -1
- package/package.json +31 -13
- package/dist/runtime/step-handler.d.ts +0 -2
- package/dist/runtime/step-handler.d.ts.map +0 -1
- package/dist/runtime/step-handler.js +0 -678
package/dist/workflow.js
CHANGED
|
@@ -1,250 +1,408 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { withResolvers } from '@workflow/utils';
|
|
4
|
-
import { getPort } from '@workflow/utils/get-port';
|
|
1
|
+
import { ERROR_SLUGS, ReplayDivergenceError, WorkflowNotRegisteredError, WorkflowRuntimeError, } from '@workflow/errors';
|
|
2
|
+
import { createWorkflowBaseUrl, withResolvers, } from '@workflow/utils';
|
|
5
3
|
import { parseWorkflowName } from '@workflow/utils/parse-name';
|
|
4
|
+
import { SPEC_VERSION_SUPPORTS_COMPRESSION } from '@workflow/world';
|
|
6
5
|
import * as nanoid from 'nanoid';
|
|
7
6
|
import { monotonicFactory } from 'ulid';
|
|
7
|
+
import { createCorrelationIdGenerator, isPerKindCorrelationIdsEnabled, } from './correlation-id.js';
|
|
8
8
|
import { EventConsumerResult, EventsConsumer } from './events-consumer.js';
|
|
9
9
|
import { ENOTSUP, WorkflowSuspension } from './global.js';
|
|
10
10
|
import { runtimeLogger } from './logger.js';
|
|
11
|
+
import { ReplayPayloadCache } from './replay-payload-cache.js';
|
|
12
|
+
import { getPortLazy } from './runtime/get-port-lazy.js';
|
|
13
|
+
import { runIdCreatedAt } from './runtime/run-id-time.js';
|
|
14
|
+
import { handleSuspension } from './runtime/suspension-handler.js';
|
|
15
|
+
import { getWorld } from './runtime/world.js';
|
|
11
16
|
import { dehydrateWorkflowReturnValue, hydrateWorkflowArguments, } from './serialization.js';
|
|
12
17
|
import { createUseStep } from './step.js';
|
|
13
|
-
import { BODY_INIT_SYMBOL, STABLE_ULID, WORKFLOW_CREATE_HOOK, WORKFLOW_GET_STREAM_ID, WORKFLOW_SLEEP, WORKFLOW_USE_STEP, } from './symbols.js';
|
|
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';
|
|
14
19
|
import * as Attribute from './telemetry/semantic-conventions.js';
|
|
15
|
-
import { trace } from './telemetry.js';
|
|
20
|
+
import { applyWorkflowSuspensionToSpan, trace } from './telemetry.js';
|
|
16
21
|
import { getWorkflowRunStreamId } from './util.js';
|
|
17
22
|
import { createContext } from './vm/index.js';
|
|
23
|
+
import { runCachedWorkflowScript } from './vm/script-cache.js';
|
|
24
|
+
import { createAbortSignalStatics, createCreateAbortController, } from './workflow/abort-controller.js';
|
|
25
|
+
import { createSetAttributes } from './workflow/attribute-dispatcher.js';
|
|
18
26
|
import { WORKFLOW_CONTEXT_SYMBOL } from './workflow/get-workflow-metadata.js';
|
|
19
27
|
import { createCreateHook } from './workflow/hook.js';
|
|
20
28
|
import { createSleep } from './workflow/sleep.js';
|
|
21
29
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
30
|
+
* Drain pending queue items at workflow completion (success or failure).
|
|
31
|
+
*
|
|
32
|
+
* Treats completion as a final suspension so unawaited hook, wait, and
|
|
33
|
+
* attribute operations are recorded before the run becomes terminal. This
|
|
34
|
+
* also lets a final `controller.abort()` reach in-flight steps.
|
|
35
|
+
*
|
|
36
|
+
* It records `*_created` and native attribute events, but never executes step
|
|
37
|
+
* bodies: `step_started` is rejected after the run becomes terminal. A
|
|
38
|
+
* fire-and-forget step therefore needs a later suspension to be scheduled.
|
|
39
|
+
*
|
|
40
|
+
* Drain failures do not change the workflow's terminal outcome.
|
|
25
41
|
*/
|
|
26
|
-
function
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
42
|
+
async function drainPendingQueueItems(runId, pendingQueue, vmGlobalThis, workflowRun, outcome,
|
|
43
|
+
/**
|
|
44
|
+
* In turbo mode, gates final `*_created` writes on backgrounded
|
|
45
|
+
* `run_started`. Undefined when `run_started` is awaited.
|
|
46
|
+
*/
|
|
47
|
+
runReadyBarrier) {
|
|
48
|
+
if (pendingQueue.size === 0)
|
|
32
49
|
return;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
50
|
+
// Implicitly dispose any abort hooks (system hooks) that are still alive at
|
|
51
|
+
// workflow completion so they don't leak rows in the hooks table for the
|
|
52
|
+
// run's lifetime. Skip hooks that already have an abort in flight — those
|
|
53
|
+
// will emit hook_received via the abort processing path. User hooks
|
|
54
|
+
// (isSystem !== true) are intentionally left alone: their lifetime is
|
|
55
|
+
// managed by the user's code, not the runtime.
|
|
56
|
+
for (const item of pendingQueue.values()) {
|
|
57
|
+
if (item.type === 'hook' &&
|
|
58
|
+
item.isSystem &&
|
|
59
|
+
!item.disposed &&
|
|
60
|
+
!item.abortRequested) {
|
|
61
|
+
item.disposed = true;
|
|
43
62
|
}
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const world = await getWorld();
|
|
66
|
+
const synthesized = new WorkflowSuspension(pendingQueue, vmGlobalThis);
|
|
67
|
+
await handleSuspension({
|
|
68
|
+
suspension: synthesized,
|
|
69
|
+
world,
|
|
70
|
+
run: workflowRun,
|
|
71
|
+
runReadyBarrier,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
runtimeLogger.warn(`Failed to drain pending queue items for ${outcome} workflow run`, {
|
|
76
|
+
workflowRunId: runId,
|
|
77
|
+
message: err instanceof Error ? err.message : String(err),
|
|
78
|
+
});
|
|
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);
|
|
44
89
|
});
|
|
45
|
-
runtimeLogger.warn(`Workflow run ${outcome} with ${items.length} uncommitted operation(s): ${details.join(', ')}. ` +
|
|
46
|
-
'Did you forget to `await` a step, hook, or sleep call?', { workflowRunId: runId });
|
|
47
90
|
}
|
|
48
|
-
|
|
49
|
-
|
|
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) => {
|
|
50
103
|
span?.setAttributes({
|
|
51
104
|
...Attribute.WorkflowName(workflowRun.workflowName),
|
|
52
105
|
...Attribute.WorkflowRunId(workflowRun.runId),
|
|
53
106
|
...Attribute.WorkflowRunStatus(workflowRun.status),
|
|
54
107
|
...Attribute.WorkflowEventsCount(events.length),
|
|
108
|
+
...Attribute.WorkflowExecutionMode(mode),
|
|
55
109
|
});
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const port = isVercel ? undefined : await getPort();
|
|
64
|
-
const { context, globalThis: vmGlobalThis, updateTimestamp, } = createContext({
|
|
65
|
-
seed: `${workflowRun.runId}:${workflowRun.workflowName}:${+startedAt}`,
|
|
66
|
-
fixedTimestamp: +startedAt,
|
|
67
|
-
});
|
|
68
|
-
const workflowDiscontinuation = withResolvers();
|
|
69
|
-
const ulid = monotonicFactory(() => vmGlobalThis.Math.random());
|
|
70
|
-
const generateNanoid = nanoid.customRandom(nanoid.urlAlphabet, 21, (size) => new Uint8Array(size).map(() => 256 * vmGlobalThis.Math.random()));
|
|
71
|
-
// Create a mutable holder for the promise queue so the EventsConsumer
|
|
72
|
-
// can access the current queue state via a getter. The queue is mutated
|
|
73
|
-
// by step/hook/sleep callbacks as events are processed.
|
|
74
|
-
const promiseQueueHolder = { current: Promise.resolve() };
|
|
75
|
-
const eventsConsumer = new EventsConsumer(events, {
|
|
76
|
-
onUnconsumedEvent: (event) => {
|
|
77
|
-
workflowDiscontinuation.reject(new WorkflowRuntimeError(`Unconsumed event in event log: eventType=${event.eventType}, correlationId=${event.correlationId}, eventId=${event.eventId}. This indicates a corrupted or invalid event log.`, { slug: ERROR_SLUGS.CORRUPTED_EVENT_LOG }));
|
|
78
|
-
},
|
|
79
|
-
getPromiseQueue: () => promiseQueueHolder.current,
|
|
110
|
+
return fn(span);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
function recordResult(result, span) {
|
|
114
|
+
if (result.type === 'completed') {
|
|
115
|
+
span?.setAttributes({
|
|
116
|
+
...Attribute.WorkflowResultType(result.resultType),
|
|
80
117
|
});
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
+
*/
|
|
129
|
+
export async function runWorkflow(workflowCode, workflowRun, events, encryptionKey,
|
|
130
|
+
/**
|
|
131
|
+
* Optional per-run cache for replay payload preparation and immutable final
|
|
132
|
+
* values. Owned by the inline execution loop for this invocation.
|
|
133
|
+
*/
|
|
134
|
+
replayPayloadCache = new ReplayPayloadCache(encryptionKey),
|
|
135
|
+
/**
|
|
136
|
+
* Turbo mode only: resolves once the backgrounded `run_started` has landed.
|
|
137
|
+
* Threaded into the end-of-run drain so fire-and-forget `*_created` writes
|
|
138
|
+
* committed at workflow completion order after the run's creation. Undefined
|
|
139
|
+
* outside turbo, where `run_started` is awaited up front.
|
|
140
|
+
*/
|
|
141
|
+
runReadyBarrier,
|
|
142
|
+
/**
|
|
143
|
+
* Features supported by the World executing this workflow. Missing
|
|
144
|
+
* capabilities are treated as unsupported.
|
|
145
|
+
*/
|
|
146
|
+
worldCapabilities) {
|
|
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) {
|
|
107
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,
|
|
108
331
|
});
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if (!event) {
|
|
114
|
-
return EventConsumerResult.NotConsumed;
|
|
115
|
-
}
|
|
116
|
-
// Consume run_created - every run has exactly one
|
|
117
|
-
if (event.eventType === 'run_created') {
|
|
118
|
-
return EventConsumerResult.Consumed;
|
|
119
|
-
}
|
|
120
|
-
// Consume run_started - every run has exactly one
|
|
121
|
-
if (event.eventType === 'run_started') {
|
|
122
|
-
return EventConsumerResult.Consumed;
|
|
123
|
-
}
|
|
124
|
-
return EventConsumerResult.NotConsumed;
|
|
332
|
+
};
|
|
333
|
+
vmGlobalThis.setInterval = () => {
|
|
334
|
+
throw new WorkflowRuntimeError(timeoutErrorMessage, {
|
|
335
|
+
slug: ERROR_SLUGS.TIMEOUT_FUNCTIONS_IN_WORKFLOW,
|
|
125
336
|
});
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
throw new WorkflowRuntimeError(timeoutErrorMessage, {
|
|
190
|
-
slug: ERROR_SLUGS.TIMEOUT_FUNCTIONS_IN_WORKFLOW,
|
|
191
|
-
});
|
|
192
|
-
};
|
|
193
|
-
// `Request` and `Response` are special built-in classes that invoke steps
|
|
194
|
-
// for the `json()`, `text()` and `arrayBuffer()` instance methods
|
|
195
|
-
class Request {
|
|
196
|
-
cache;
|
|
197
|
-
credentials;
|
|
198
|
-
destination;
|
|
199
|
-
headers;
|
|
200
|
-
integrity;
|
|
201
|
-
method;
|
|
202
|
-
mode;
|
|
203
|
-
redirect;
|
|
204
|
-
referrer;
|
|
205
|
-
referrerPolicy;
|
|
206
|
-
url;
|
|
207
|
-
keepalive;
|
|
208
|
-
signal;
|
|
209
|
-
duplex;
|
|
210
|
-
body;
|
|
211
|
-
constructor(input, init) {
|
|
212
|
-
// Handle URL input
|
|
213
|
-
if (typeof input === 'string' || input instanceof vmGlobalThis.URL) {
|
|
214
|
-
const urlString = String(input);
|
|
215
|
-
// Validate URL format
|
|
216
|
-
try {
|
|
217
|
-
new vmGlobalThis.URL(urlString);
|
|
218
|
-
this.url = urlString;
|
|
219
|
-
}
|
|
220
|
-
catch (cause) {
|
|
221
|
-
throw new TypeError(`Failed to parse URL from ${urlString}`, {
|
|
222
|
-
cause,
|
|
223
|
-
});
|
|
224
|
-
}
|
|
337
|
+
};
|
|
338
|
+
vmGlobalThis.clearTimeout = () => {
|
|
339
|
+
throw new WorkflowRuntimeError(timeoutErrorMessage, {
|
|
340
|
+
slug: ERROR_SLUGS.TIMEOUT_FUNCTIONS_IN_WORKFLOW,
|
|
341
|
+
});
|
|
342
|
+
};
|
|
343
|
+
vmGlobalThis.clearInterval = () => {
|
|
344
|
+
throw new WorkflowRuntimeError(timeoutErrorMessage, {
|
|
345
|
+
slug: ERROR_SLUGS.TIMEOUT_FUNCTIONS_IN_WORKFLOW,
|
|
346
|
+
});
|
|
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
|
+
});
|
|
225
400
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
this.headers = new vmGlobalThis.Headers(input.headers);
|
|
232
|
-
this.body = input.body;
|
|
233
|
-
this.mode = input.mode;
|
|
234
|
-
this.credentials = input.credentials;
|
|
235
|
-
this.cache = input.cache;
|
|
236
|
-
this.redirect = input.redirect;
|
|
237
|
-
this.referrer = input.referrer;
|
|
238
|
-
this.referrerPolicy = input.referrerPolicy;
|
|
239
|
-
this.integrity = input.integrity;
|
|
240
|
-
this.keepalive = input.keepalive;
|
|
241
|
-
this.signal = input.signal;
|
|
242
|
-
this.duplex = input.duplex;
|
|
243
|
-
this.destination = input.destination;
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
// If init is provided, merge: use source properties, then override with init
|
|
247
|
-
// 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) {
|
|
248
406
|
this.method = input.method;
|
|
249
407
|
this.headers = new vmGlobalThis.Headers(input.headers);
|
|
250
408
|
this.body = input.body;
|
|
@@ -259,354 +417,433 @@ export async function runWorkflow(workflowCode, workflowRun, events, encryptionK
|
|
|
259
417
|
this.signal = input.signal;
|
|
260
418
|
this.duplex = input.duplex;
|
|
261
419
|
this.destination = input.destination;
|
|
420
|
+
return;
|
|
262
421
|
}
|
|
263
|
-
//
|
|
264
|
-
//
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
ENOTSUP();
|
|
369
|
-
}
|
|
370
|
-
get bodyUsed() {
|
|
371
|
-
return false;
|
|
372
|
-
}
|
|
373
|
-
// TODO: implement these
|
|
374
|
-
blob;
|
|
375
|
-
formData;
|
|
376
|
-
arrayBuffer;
|
|
377
|
-
json;
|
|
378
|
-
text;
|
|
379
|
-
async bytes() {
|
|
380
|
-
return new Uint8Array(await this.arrayBuffer());
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
vmGlobalThis.Request = Request;
|
|
384
|
-
Object.defineProperties(Request.prototype, {
|
|
385
|
-
arrayBuffer: {
|
|
386
|
-
value: useStep('__builtin_response_array_buffer'),
|
|
387
|
-
writable: true,
|
|
388
|
-
configurable: true,
|
|
389
|
-
},
|
|
390
|
-
json: {
|
|
391
|
-
value: useStep('__builtin_response_json'),
|
|
392
|
-
writable: true,
|
|
393
|
-
configurable: true,
|
|
394
|
-
},
|
|
395
|
-
text: {
|
|
396
|
-
value: useStep('__builtin_response_text'),
|
|
397
|
-
writable: true,
|
|
398
|
-
configurable: true,
|
|
399
|
-
},
|
|
400
|
-
});
|
|
401
|
-
class Response {
|
|
402
|
-
type;
|
|
403
|
-
url;
|
|
404
|
-
status;
|
|
405
|
-
statusText;
|
|
406
|
-
body;
|
|
407
|
-
headers;
|
|
408
|
-
redirected;
|
|
409
|
-
constructor(body, init) {
|
|
410
|
-
this.status = init?.status ?? 200;
|
|
411
|
-
this.statusText = init?.statusText ?? '';
|
|
412
|
-
this.headers = new vmGlobalThis.Headers(init?.headers);
|
|
413
|
-
this.type = 'default';
|
|
414
|
-
this.url = '';
|
|
415
|
-
this.redirected = false;
|
|
416
|
-
// Validate that null-body status codes don't have a body
|
|
417
|
-
// Per HTTP spec: 204 (No Content), 205 (Reset Content), and 304 (Not Modified)
|
|
418
|
-
if (body !== null &&
|
|
419
|
-
body !== undefined &&
|
|
420
|
-
(this.status === 204 || this.status === 205 || this.status === 304)) {
|
|
421
|
-
throw new TypeError(`Response constructor: Invalid response status code ${this.status}`);
|
|
422
|
-
}
|
|
423
|
-
// Store the original BodyInit for serialization
|
|
424
|
-
if (body !== null && body !== undefined) {
|
|
425
|
-
// Create a "fake" ReadableStream that stores the original body
|
|
426
|
-
// This avoids doing async work during workflow replay
|
|
427
|
-
this.body = Object.create(vmGlobalThis.ReadableStream.prototype, {
|
|
428
|
-
[BODY_INIT_SYMBOL]: {
|
|
429
|
-
value: body,
|
|
430
|
-
writable: false,
|
|
431
|
-
},
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
else {
|
|
435
|
-
this.body = null;
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
// TODO: implement these
|
|
439
|
-
clone;
|
|
440
|
-
blob;
|
|
441
|
-
formData;
|
|
442
|
-
get ok() {
|
|
443
|
-
return this.status >= 200 && this.status < 300;
|
|
444
|
-
}
|
|
445
|
-
get bodyUsed() {
|
|
446
|
-
return false;
|
|
447
|
-
}
|
|
448
|
-
arrayBuffer;
|
|
449
|
-
json;
|
|
450
|
-
text;
|
|
451
|
-
async bytes() {
|
|
452
|
-
return new Uint8Array(await this.arrayBuffer());
|
|
453
|
-
}
|
|
454
|
-
static json(data, init) {
|
|
455
|
-
const body = JSON.stringify(data);
|
|
456
|
-
const headers = new vmGlobalThis.Headers(init?.headers);
|
|
457
|
-
if (!headers.has('content-type')) {
|
|
458
|
-
headers.set('content-type', 'application/json');
|
|
459
|
-
}
|
|
460
|
-
return new Response(body, { ...init, headers });
|
|
461
|
-
}
|
|
462
|
-
static error() {
|
|
463
|
-
ENOTSUP();
|
|
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.`);
|
|
464
527
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
response.statusText = '';
|
|
476
|
-
response.headers = headers;
|
|
477
|
-
response.body = null;
|
|
478
|
-
response.type = 'default';
|
|
479
|
-
response.url = '';
|
|
480
|
-
response.redirected = false;
|
|
481
|
-
return response;
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
vmGlobalThis.Response = Response;
|
|
485
|
-
Object.defineProperties(Response.prototype, {
|
|
486
|
-
arrayBuffer: {
|
|
487
|
-
value: useStep('__builtin_response_array_buffer'),
|
|
488
|
-
writable: true,
|
|
489
|
-
configurable: true,
|
|
490
|
-
},
|
|
491
|
-
json: {
|
|
492
|
-
value: useStep('__builtin_response_json'),
|
|
493
|
-
writable: true,
|
|
494
|
-
configurable: true,
|
|
495
|
-
},
|
|
496
|
-
text: {
|
|
497
|
-
value: useStep('__builtin_response_text'),
|
|
498
|
-
writable: true,
|
|
499
|
-
configurable: true,
|
|
500
|
-
},
|
|
501
|
-
});
|
|
502
|
-
class ReadableStream {
|
|
503
|
-
constructor() {
|
|
504
|
-
ENOTSUP();
|
|
505
|
-
}
|
|
506
|
-
get locked() {
|
|
507
|
-
return false;
|
|
508
|
-
}
|
|
509
|
-
cancel() {
|
|
510
|
-
ENOTSUP();
|
|
511
|
-
}
|
|
512
|
-
getReader() {
|
|
513
|
-
ENOTSUP();
|
|
514
|
-
}
|
|
515
|
-
pipeThrough() {
|
|
516
|
-
ENOTSUP();
|
|
517
|
-
}
|
|
518
|
-
pipeTo() {
|
|
519
|
-
ENOTSUP();
|
|
520
|
-
}
|
|
521
|
-
tee() {
|
|
522
|
-
ENOTSUP();
|
|
523
|
-
}
|
|
524
|
-
values() {
|
|
525
|
-
ENOTSUP();
|
|
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
|
+
});
|
|
526
538
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
}
|
|
530
|
-
[Symbol.asyncIterator]() {
|
|
531
|
-
ENOTSUP();
|
|
539
|
+
else {
|
|
540
|
+
this.body = null;
|
|
532
541
|
}
|
|
533
542
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
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;
|
|
550
612
|
}
|
|
551
613
|
}
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
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');
|
|
558
635
|
}
|
|
636
|
+
return new Response(body, { ...init, headers });
|
|
559
637
|
}
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
// but for now we'll just expose the global one.
|
|
563
|
-
vmGlobalThis.console = globalThis.console;
|
|
564
|
-
// HACK: propagate symbol needed for AI gateway usage
|
|
565
|
-
const SYMBOL_FOR_REQ_CONTEXT = Symbol.for('@vercel/request-context');
|
|
566
|
-
// @ts-expect-error - `@types/node` says symbol is not valid, but it does work
|
|
567
|
-
vmGlobalThis[SYMBOL_FOR_REQ_CONTEXT] = globalThis[SYMBOL_FOR_REQ_CONTEXT];
|
|
568
|
-
// Get a reference to the user-defined workflow function.
|
|
569
|
-
// The filename parameter ensures stack traces show a meaningful name
|
|
570
|
-
// (e.g., "example/workflows/99_e2e.ts") instead of "evalmachine.<anonymous>".
|
|
571
|
-
const parsedName = parseWorkflowName(workflowRun.workflowName);
|
|
572
|
-
const filename = parsedName?.moduleSpecifier || workflowRun.workflowName;
|
|
573
|
-
const workflowFn = runInContext(`${workflowCode}; globalThis.__private_workflows?.get(${JSON.stringify(workflowRun.workflowName)})`, context, { filename });
|
|
574
|
-
if (typeof workflowFn !== 'function') {
|
|
575
|
-
throw new WorkflowNotRegisteredError(workflowRun.workflowName);
|
|
638
|
+
static error() {
|
|
639
|
+
ENOTSUP();
|
|
576
640
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
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();
|
|
609
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);
|
|
610
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' };
|
|
799
|
+
try {
|
|
800
|
+
const output = await dehydrateWorkflowReturnValue(result, workflowRun.runId, encryptionKey, vmGlobalThis, false,
|
|
801
|
+
// Only compression-capable runs (spec >= 5) may write compressed
|
|
802
|
+
// payloads. The serializer uses zstd when supported and may use gzip.
|
|
803
|
+
(workflowRun.specVersion ?? 0) >= SPEC_VERSION_SUPPORTS_COMPRESSION);
|
|
804
|
+
await drainPendingQueueItems(workflowRun.runId, workflowContext.invocationsQueue, vmGlobalThis, workflowRun, 'completed', runReadyBarrier);
|
|
805
|
+
return { type: 'completed', output, resultType: typeof result };
|
|
806
|
+
}
|
|
807
|
+
catch (error) {
|
|
808
|
+
return failWorkflow(error);
|
|
809
|
+
}
|
|
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
|
+
};
|
|
611
848
|
}
|
|
612
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2Zsb3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvd29ya2Zsb3cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN2QyxPQUFPLEVBQ0wsV0FBVyxFQUNYLDBCQUEwQixFQUMxQixvQkFBb0IsR0FDckIsTUFBTSxrQkFBa0IsQ0FBQztBQUMxQixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDaEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRS9ELE9BQU8sS0FBSyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUV4QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFM0UsT0FBTyxFQUFFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUMxRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTVDLE9BQU8sRUFDTCw0QkFBNEIsRUFDNUIsd0JBQXdCLEdBQ3pCLE1BQU0sb0JBQW9CLENBQUM7QUFDNUIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUMxQyxPQUFPLEVBQ0wsZ0JBQWdCLEVBQ2hCLFdBQVcsRUFDWCxvQkFBb0IsRUFDcEIsc0JBQXNCLEVBQ3RCLGNBQWMsRUFDZCxpQkFBaUIsR0FDbEIsTUFBTSxjQUFjLENBQUM7QUFDdEIsT0FBTyxLQUFLLFNBQVMsTUFBTSxxQ0FBcUMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdkMsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sV0FBVyxDQUFD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QUFDLGtCQUFrQixDQUFDLE9BQU8sTUFBTSxDQUFDO2FBQy9DLENBQUMsQ0FBQztZQUVILHFCQUFxQixDQUNuQixXQUFXLENBQUMsS0FBSyxFQUNqQixlQUFlLENBQUMsZ0JBQWdCLEVBQ2hDLFdBQVcsQ0FDWixDQUFDO1lBRUYsT0FBTyxVQUFVLENBQUM7UUFDcEIsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYix1RUFBdUU7WUFDdkUsSUFBSSxrQkFBa0IsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDL0IsTUFBTSxHQUFHLENBQUM7WUFDWixDQUFDO1lBRUQscUJBQXFCLENBQ25CLFdBQVcsQ0FBQyxLQUFLLEVBQ2pCLGVBQWUsQ0FBQyxnQkFBZ0IsRUFDaEMsUUFBUSxDQUNULENBQUM7WUFFRixNQUFNLEdBQUcsQ0FBQztRQUNaLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBydW5JbkNvbnRleHQgfSBmcm9tICdub2RlOnZtJztcbmltcG9ydCB7XG4gIEVSUk9SX1NMVUdTLFxuICBXb3JrZmxvd05vdFJlZ2lzdGVyZWRFcnJvcixcbiAgV29ya2Zsb3dSdW50aW1lRXJyb3IsXG59IGZyb20gJ0B3b3JrZmxvdy9lcnJvcnMnO1xuaW1wb3J0IHsgd2l0aFJlc29sdmVycyB9IGZyb20gJ0B3b3JrZmxvdy91dGlscyc7XG5pbXBvcnQgeyBnZXRQb3J0IH0gZnJvbSAnQHdvcmtmbG93L3V0aWxzL2dldC1wb3J0JztcbmltcG9ydCB7IHBhcnNlV29ya2Zsb3dOYW1lIH0gZnJvbSAnQHdvcmtmbG93L3V0aWxzL3BhcnNlLW5hbWUnO1xuaW1wb3J0IHR5cGUgeyBFdmVudCwgV29ya2Zsb3dSdW4gfSBmcm9tICdAd29ya2Zsb3cvd29ybGQnO1xuaW1wb3J0ICogYXMgbmFub2lkIGZyb20gJ25hbm9pZCc7XG5pbXBvcnQgeyBtb25vdG9uaWNGYWN0b3J5IH0gZnJvbSAndWxpZCc7XG5pbXBvcnQgdHlwZSB7IENyeXB0b0tleSB9IGZyb20gJy4vZW5jcnlwdGlvbi5qcyc7XG5pbXBvcnQgeyBFdmVudENvbnN1bWVyUmVzdWx0LCBFdmVudHNDb25zdW1lciB9IGZyb20gJy4vZXZlbnRzLWNvbnN1bWVyLmpzJztcbmltcG9ydCB0eXBlIHsgUXVldWVJdGVtIH0gZnJvbSAnLi9nbG9iYWwuanMnO1xuaW1wb3J0IHsgRU5PVFNVUCwgV29ya2Zsb3dTdXNwZW5zaW9uIH0gZnJvbSAnLi9nbG9iYWwuanMnO1xuaW1wb3J0IHsgcnVudGltZUxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyLmpzJztcbmltcG9ydCB0eXBlIHsgV29ya2Zsb3dPcmNoZXN0cmF0b3JDb250ZXh0IH0gZnJvbSAnLi9wcml2YXRlLmpzJztcbmltcG9ydCB7XG4gIGRlaHlkcmF0ZVdvcmtmbG93UmV0dXJuVmFsdWUsXG4gIGh5ZHJhdGVXb3JrZmxvd0FyZ3VtZW50cyxcbn0gZnJvbSAnLi9zZXJpYWxpemF0aW9uLmpzJztcbmltcG9ydCB7IGNyZWF0ZVVzZVN0ZXAgfSBmcm9tICcuL3N0ZXAuanMnO1xuaW1wb3J0IHtcbiAgQk9EWV9JTklUX1NZTUJPTCxcbiAgU1RBQkxFX1VMSUQsXG4gIFdPUktGTE9XX0NSRUFURV9IT09LLFxuICBXT1JLRkxPV19HRVRfU1RSRUFNX0lELFxuICBXT1JLRkxPV19TTEVFUCxcbiAgV09SS0ZMT1dfVVNFX1NURVAsXG59IGZyb20gJy4vc3ltYm9scy5qcyc7XG5pbXBvcnQgKiBhcyBBdHRyaWJ1dGUgZnJvbSAnLi90ZWxlbWV0cnkvc2VtYW50aWMtY29udmVudGlvbnMuanMnO1xuaW1wb3J0IHsgdHJhY2UgfSBmcm9tICcuL3RlbGVtZXRyeS5qcyc7XG5pbXBvcnQgeyBnZXRXb3JrZmxvd1J1blN0cmVhbUlkIH0gZnJvbSAnLi91dGlsLmpzJztcbmltcG9ydCB7IGNyZWF0ZUNvbnRleHQgfSBmcm9tICcuL3ZtL2luZGV4LmpzJztcbmltcG9ydCB0eXBlIHsgV29ya2Zsb3dNZXRhZGF0YSB9IGZyb20gJy4vd29ya2Zsb3cvZ2V0LXdvcmtmbG93LW1ldGFkYXRhLmpzJztcbmltcG9ydCB7IFdPUktGTE9XX0NPTlRFWFRfU1lNQk9MIH0gZnJvbSAnLi93b3JrZmxvdy9nZXQtd29ya2Zsb3ctbWV0YWRhdGEuanMnO1xuaW1wb3J0IHsgY3JlYXRlQ3JlYXRlSG9vayB9IGZyb20gJy4vd29ya2Zsb3cvaG9vay5qcyc7XG5pbXBvcnQgeyBjcmVhdGVTbGVlcCB9IGZyb20gJy4vd29ya2Zsb3cvc2xlZXAuanMnO1xuXG4vKipcbiAqIExvZ3MgYSB3YXJuaW5nIHdoZW4gYSB3b3JrZmxvdyBydW4gY29tcGxldGVzIG9yIGZhaWxzIHdpdGggdW5jb21taXR0ZWRcbiAqIG9wZXJhdGlvbnMgc3RpbGwgaW4gdGhlIGludm9jYXRpb25zIHF1ZXVlLiBUaGlzIHR5cGljYWxseSBpbmRpY2F0ZXMgdGhlXG4gKiB1c2VyIGZvcmdvdCB0byBgYXdhaXRgIGEgc3RlcCwgaG9vaywgb3Igc2xlZXAgY2FsbC5cbiAqL1xuZnVuY3Rpb24gd2FyblBlbmRpbmdRdWV1ZUl0ZW1zKFxuICBydW5JZDogc3RyaW5nLFxuICBwZW5kaW5nUXVldWU6IE1hcDxzdHJpbmcsIFF1ZXVlSXRlbT4sXG4gIG91dGNvbWU6ICdjb21wbGV0ZWQnIHwgJ2ZhaWxlZCdcbik6IHZvaWQge1xuICAvLyBGaWx0ZXIgb3V0IGhvb2tzIHRoYXQgYXJlIGVpdGhlciBhbHJlYWR5IGNyZWF0ZWQgKGFsaXZlLCB3YWl0aW5nIGZvciBwYXlsb2FkcylcbiAgLy8gb3IgZXhwbGljaXRseSBkaXNwb3NlZCDigJQgYm90aCBhcmUgYmVuaWduIHNpbmNlIHRoZSBiYWNrZW5kIGF1dG8tZGlzcG9zZXNcbiAgLy8gYWxsIGhvb2tzIHdoZW4gYSBydW4gcmVhY2hlcyBhIHRlcm1pbmFsIHN0YXRlXG4gIGNvbnN0IGl0ZW1zID0gWy4uLnBlbmRpbmdRdWV1ZS52YWx1ZXMoKV0uZmlsdGVyKFxuICAgIChpdGVtKSA9PiAhKGl0ZW0udHlwZSA9PT0gJ2hvb2snICYmIChpdGVtLmhhc0NyZWF0ZWRFdmVudCB8fCBpdGVtLmRpc3Bvc2VkKSlcbiAgKTtcbiAgaWYgKGl0ZW1zLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gIGNvbnN0IGRldGFpbHMgPSBpdGVtcy5tYXAoKGl0ZW0pID0+IHtcbiAgICBzd2l0Y2ggKGl0ZW0udHlwZSkge1xuICAgICAgY2FzZSAnc3RlcCc6XG4gICAgICAgIHJldHVybiBgc3RlcCBcIiR7aXRlbS5zdGVwTmFtZX1cImA7XG4gICAgICBjYXNlICdob29rJzpcbiAgICAgICAgcmV0dXJuIGBob29rIFwiJHtpdGVtLnRva2VufVwiYDtcbiAgICAgIGNhc2UgJ3dhaXQnOlxuICAgICAgICByZXR1cm4gJ3NsZWVwJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBgdW5rbm93biAoJHsoaXRlbSBhcyB7IHR5cGU6IHN0cmluZyB9KS50eXBlfSlgO1xuICAgIH1cbiAgfSk7XG5cbiAgcnVudGltZUxvZ2dlci53YXJuKFxuICAgIGBXb3JrZmxvdyBydW4gJHtvdXRjb21lfSB3aXRoICR7aXRlbXMubGVuZ3RofSB1bmNvbW1pdHRlZCBvcGVyYXRpb24ocyk6ICR7ZGV0YWlscy5qb2luKCcsICcpfS4gYCArXG4gICAgICAnRGlkIHlvdSBmb3JnZXQgdG8gYGF3YWl0YCBhIHN0ZXAsIGhvb2ssIG9yIHNsZWVwIGNhbGw/JyxcbiAgICB7IHdvcmtmbG93UnVuSWQ6IHJ1bklkIH1cbiAgKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1bldvcmtmbG93KFxuICB3b3JrZmxvd0NvZGU6IHN0cmluZyxcbiAgd29ya2Zsb3dSdW46IFdvcmtmbG93UnVuLFxuICBldmVudHM6IEV2ZW50W10sXG4gIGVuY3J5cHRpb25LZXk6IENyeXB0b0tleSB8IHVuZGVmaW5lZFxuKTogUHJvbWlzZTxVaW50OEFycmF5IHwgdW5rbm93bj4ge1xuICByZXR1cm4gdHJhY2UoYHdvcmtmbG93LnJ1biAke3dvcmtmbG93UnVuLndvcmtmbG93TmFtZX1gLCBhc3luYyAoc3BhbikgPT4ge1xuICAgIHNwYW4/LnNldEF0dHJpYnV0ZXMoe1xuICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93TmFtZSh3b3JrZmxvd1J1bi53b3JrZmxvd05hbWUpLFxuICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93UnVuSWQod29ya2Zsb3dSdW4ucnVuSWQpLFxuICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93UnVuU3RhdHVzKHdvcmtmbG93UnVuLnN0YXR1cyksXG4gICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dFdmVudHNDb3VudChldmVudHMubGVuZ3RoKSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHN0YXJ0ZWRBdCA9IHdvcmtmbG93UnVuLnN0YXJ0ZWRBdDtcbiAgICBpZiAoIXN0YXJ0ZWRBdCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgV29ya2Zsb3cgcnVuIFwiJHt3b3JrZmxvd1J1bi5ydW5JZH1cIiBoYXMgbm8gXCJzdGFydGVkQXRcIiB0aW1lc3RhbXAgKHNob3VsZCBub3QgaGFwcGVuKWBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gR2V0IHRoZSBwb3J0IGJlZm9yZSBjcmVhdGluZyBWTSBjb250ZXh0IHRvIGF2b2lkIGFzeW5jIG9wZXJhdGlvbnNcbiAgICAvLyBhZmZlY3RpbmcgdGhlIGRldGVybWluaXN0aWMgdGltZXN0YW1wXG4gICAgY29uc3QgaXNWZXJjZWwgPSBwcm9jZXNzLmVudi5WRVJDRUxfVVJMICE9PSB1bmRlZmluZWQ7XG4gICAgY29uc3QgcG9ydCA9IGlzVmVyY2VsID8gdW5kZWZpbmVkIDogYXdhaXQgZ2V0UG9ydCgpO1xuXG4gICAgY29uc3Qge1xuICAgICAgY29udGV4dCxcbiAgICAgIGdsb2JhbFRoaXM6IHZtR2xvYmFsVGhpcyxcbiAgICAgIHVwZGF0ZVRpbWVzdGFtcCxcbiAgICB9ID0gY3JlYXRlQ29udGV4dCh7XG4gICAgICBzZWVkOiBgJHt3b3JrZmxvd1J1bi5ydW5JZH06JHt3b3JrZmxvd1J1bi53b3JrZmxvd05hbWV9OiR7K3N0YXJ0ZWRBdH1gLFxuICAgICAgZml4ZWRUaW1lc3RhbXA6ICtzdGFydGVkQXQsXG4gICAgfSk7XG5cbiAgICBjb25zdCB3b3JrZmxvd0Rpc2NvbnRpbnVhdGlvbiA9IHdpdGhSZXNvbHZlcnM8dm9pZD4oKTtcblxuICAgIGNvbnN0IHVsaWQgPSBtb25vdG9uaWNGYWN0b3J5KCgpID0+IHZtR2xvYmFsVGhpcy5NYXRoLnJhbmRvbSgpKTtcbiAgICBjb25zdCBnZW5lcmF0ZU5hbm9pZCA9IG5hbm9pZC5jdXN0b21SYW5kb20obmFub2lkLnVybEFscGhhYmV0LCAyMSwgKHNpemUpID0+XG4gICAgICBuZXcgVWludDhBcnJheShzaXplKS5tYXAoKCkgPT4gMjU2ICogdm1HbG9iYWxUaGlzLk1hdGgucmFuZG9tKCkpXG4gICAgKTtcblxuICAgIC8vIENyZWF0ZSBhIG11dGFibGUgaG9sZGVyIGZvciB0aGUgcHJvbWlzZSBxdWV1ZSBzbyB0aGUgRXZlbnRzQ29uc3VtZXJcbiAgICAvLyBjYW4gYWNjZXNzIHRoZSBjdXJyZW50IHF1ZXVlIHN0YXRlIHZpYSBhIGdldHRlci4gVGhlIHF1ZXVlIGlzIG11dGF0ZWRcbiAgICAvLyBieSBzdGVwL2hvb2svc2xlZXAgY2FsbGJhY2tzIGFzIGV2ZW50cyBhcmUgcHJvY2Vzc2VkLlxuICAgIGNvbnN0IHByb21pc2VRdWV1ZUhvbGRlciA9IHsgY3VycmVudDogUHJvbWlzZS5yZXNvbHZlKCkgfTtcblxuICAgIGNvbnN0IGV2ZW50c0NvbnN1bWVyID0gbmV3IEV2ZW50c0NvbnN1bWVyKGV2ZW50cywge1xuICAgICAgb25VbmNvbnN1bWVkRXZlbnQ6IChldmVudCkgPT4ge1xuICAgICAgICB3b3JrZmxvd0Rpc2NvbnRpbnVhdGlvbi5yZWplY3QoXG4gICAgICAgICAgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKFxuICAgICAgICAgICAgYFVuY29uc3VtZWQgZXZlbnQgaW4gZXZlbnQgbG9nOiBldmVudFR5cGU9JHtldmVudC5ldmVudFR5cGV9LCBjb3JyZWxhdGlvbklkPSR7ZXZlbnQuY29ycmVsYXRpb25JZH0sIGV2ZW50SWQ9JHtldmVudC5ldmVudElkfS4gVGhpcyBpbmRpY2F0ZXMgYSBjb3JydXB0ZWQgb3IgaW52YWxpZCBldmVudCBsb2cuYCxcbiAgICAgICAgICAgIHsgc2x1ZzogRVJST1JfU0xVR1MuQ09SUlVQVEVEX0VWRU5UX0xPRyB9XG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfSxcbiAgICAgIGdldFByb21pc2VRdWV1ZTogKCkgPT4gcHJvbWlzZVF1ZXVlSG9sZGVyLmN1cnJlbnQsXG4gICAgfSk7XG5cbiAgICBjb25zdCB3b3JrZmxvd0NvbnRleHQ6IFdvcmtmbG93T3JjaGVzdHJhdG9yQ29udGV4dCA9IHtcbiAgICAgIHJ1bklkOiB3b3JrZmxvd1J1bi5ydW5JZCxcbiAgICAgIGVuY3J5cHRpb25LZXksXG4gICAgICBnbG9iYWxUaGlzOiB2bUdsb2JhbFRoaXMsXG4gICAgICBvbldvcmtmbG93RXJyb3I6IHdvcmtmbG93RGlzY29udGludWF0aW9uLnJlamVjdCxcbiAgICAgIGV2ZW50c0NvbnN1bWVyLFxuICAgICAgZ2VuZXJhdGVVbGlkOiAoKSA9PiB1bGlkKCtzdGFydGVkQXQpLFxuICAgICAgZ2VuZXJhdGVOYW5vaWQsXG4gICAgICBpbnZvY2F0aW9uc1F1ZXVlOiBuZXcgTWFwKCksXG4gICAgICAvLyBVc2UgZ2V0dGVyL3NldHRlciBzbyB0aGUgRXZlbnRzQ29uc3VtZXIncyBnZXRQcm9taXNlUXVldWUoKSBhbHdheXNcbiAgICAgIC8vIHNlZXMgdGhlIGxhdGVzdCBxdWV1ZSBzdGF0ZSBhcyBpdCdzIG11dGF0ZWQgYnkgc3RlcC9ob29rL3NsZWVwIGNhbGxiYWNrcy5cbiAgICAgIGdldCBwcm9taXNlUXVldWUoKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUXVldWVIb2xkZXIuY3VycmVudDtcbiAgICAgIH0sXG4gICAgICBzZXQgcHJvbWlzZVF1ZXVlKHZhbHVlOiBQcm9taXNlPHZvaWQ+KSB7XG4gICAgICAgIHByb21pc2VRdWV1ZUhvbGRlci5jdXJyZW50ID0gdmFsdWU7XG4gICAgICB9LFxuICAgICAgcGVuZGluZ0RlbGl2ZXJpZXM6IDAsXG4gICAgfTtcblxuICAgIC8vIFN1YnNjcmliZSB0byB0aGUgZXZlbnRzIGxvZyB0byB1cGRhdGUgdGhlIHRpbWVzdGFtcCBpbiB0aGUgdm0gY29udGV4dFxuICAgIHdvcmtmbG93Q29udGV4dC5ldmVudHNDb25zdW1lci5zdWJzY3JpYmUoKGV2ZW50KSA9PiB7XG4gICAgICBjb25zdCBjcmVhdGVkQXQgPSBldmVudD8uY3JlYXRlZEF0O1xuICAgICAgaWYgKGNyZWF0ZWRBdCkge1xuICAgICAgICB1cGRhdGVUaW1lc3RhbXAoK2NyZWF0ZWRBdCk7XG4gICAgICB9XG4gICAgICAvLyBOZXZlciBjb25zdW1lIGV2ZW50cyAtIHRoaXMgaXMgb25seSBhIHBhc3NpdmUgc3Vic2NyaWJlclxuICAgICAgcmV0dXJuIEV2ZW50Q29uc3VtZXJSZXN1bHQuTm90Q29uc3VtZWQ7XG4gICAgfSk7XG5cbiAgICAvLyBDb25zdW1lIHJ1biBsaWZlY3ljbGUgZXZlbnRzIC0gdGhlc2UgYXJlIHN0cnVjdHVyYWwgZXZlbnRzIHRoYXQgZG9uJ3RcbiAgICAvLyBuZWVkIHNwZWNpYWwgaGFuZGxpbmcgaW4gdGhlIHdvcmtmbG93LCBidXQgbXVzdCBiZSBjb25zdW1lZCB0byBhZHZhbmNlXG4gICAgLy8gcGFzdCB0aGVtIGluIHRoZSBldmVudCBsb2dcbiAgICB3b3JrZmxvd0NvbnRleHQuZXZlbnRzQ29uc3VtZXIuc3Vic2NyaWJlKChldmVudCkgPT4ge1xuICAgICAgaWYgKCFldmVudCkge1xuICAgICAgICByZXR1cm4gRXZlbnRDb25zdW1lclJlc3VsdC5Ob3RDb25zdW1lZDtcbiAgICAgIH1cblxuICAgICAgLy8gQ29uc3VtZSBydW5fY3JlYXRlZCAtIGV2ZXJ5IHJ1biBoYXMgZXhhY3RseSBvbmVcbiAgICAgIGlmIChldmVudC5ldmVudFR5cGUgPT09ICdydW5fY3JlYXRlZCcpIHtcbiAgICAgICAgcmV0dXJuIEV2ZW50Q29uc3VtZXJSZXN1bHQuQ29uc3VtZWQ7XG4gICAgICB9XG5cbiAgICAgIC8vIENvbnN1bWUgcnVuX3N0YXJ0ZWQgLSBldmVyeSBydW4gaGFzIGV4YWN0bHkgb25lXG4gICAgICBpZiAoZXZlbnQuZXZlbnRUeXBlID09PSAncnVuX3N0YXJ0ZWQnKSB7XG4gICAgICAgIHJldHVybiBFdmVudENvbnN1bWVyUmVzdWx0LkNvbnN1bWVkO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gRXZlbnRDb25zdW1lclJlc3VsdC5Ob3RDb25zdW1lZDtcbiAgICB9KTtcblxuICAgIGNvbnN0IHVzZVN0ZXAgPSBjcmVhdGVVc2VTdGVwKHdvcmtmbG93Q29udGV4dCk7XG4gICAgY29uc3QgY3JlYXRlSG9vayA9IGNyZWF0ZUNyZWF0ZUhvb2sod29ya2Zsb3dDb250ZXh0KTtcbiAgICBjb25zdCBzbGVlcCA9IGNyZWF0ZVNsZWVwKHdvcmtmbG93Q29udGV4dCk7XG5cbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIC0gYEB0eXBlcy9ub2RlYCBzYXlzIHN5bWJvbCBpcyBub3QgdmFsaWQsIGJ1dCBpdCBkb2VzIHdvcmtcbiAgICB2bUdsb2JhbFRoaXNbV09SS0ZMT1dfVVNFX1NURVBdID0gdXNlU3RlcDtcbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIC0gYEB0eXBlcy9ub2RlYCBzYXlzIHN5bWJvbCBpcyBub3QgdmFsaWQsIGJ1dCBpdCBkb2VzIHdvcmtcbiAgICB2bUdsb2JhbFRoaXNbV09SS0ZMT1dfQ1JFQVRFX0hPT0tdID0gY3JlYXRlSG9vaztcbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIC0gYEB0eXBlcy9ub2RlYCBzYXlzIHN5bWJvbCBpcyBub3QgdmFsaWQsIGJ1dCBpdCBkb2VzIHdvcmtcbiAgICB2bUdsb2JhbFRoaXNbV09SS0ZMT1dfU0xFRVBdID0gc2xlZXA7XG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciAtIGBAdHlwZXMvbm9kZWAgc2F5cyBzeW1ib2wgaXMgbm90IHZhbGlkLCBidXQgaXQgZG9lcyB3b3JrXG4gICAgdm1HbG9iYWxUaGlzW1dPUktGTE9XX0dFVF9TVFJFQU1fSURdID0gKG5hbWVzcGFjZT86IHN0cmluZykgPT5cbiAgICAgIGdldFdvcmtmbG93UnVuU3RyZWFtSWQod29ya2Zsb3dSdW4ucnVuSWQsIG5hbWVzcGFjZSk7XG5cbiAgICAvLyBUT0RPOiB0aGVyZSBzaG91bGQgYmUgYSBnZXRVcmwgbWV0aG9kIG9uIHRoZSB3b3JsZCBpbnRlcmZhY2UgaXRzZWxmLiBUaGlzXG4gICAgLy8gc29sdXRpb24gb25seSB3b3JrcyBmb3IgdmVyY2VsICsgbG9jYWwgd29ybGRzLlxuICAgIGNvbnN0IHVybCA9IGlzVmVyY2VsXG4gICAgICA/IGBodHRwczovLyR7cHJvY2Vzcy5lbnYuVkVSQ0VMX1VSTH1gXG4gICAgICA6IGBodHRwOi8vbG9jYWxob3N0OiR7cG9ydCA/PyAzMDAwfWA7XG5cbiAgICAvLyBGb3IgdGhlIHdvcmtmbG93IFZNLCB3ZSBzdG9yZSB0aGUgY29udGV4dCBpbiBhIHN5bWJvbCBvbiB0aGUgYGdsb2JhbFRoaXNgIG9iamVjdFxuICAgIGNvbnN0IGN0eDogV29ya2Zsb3dNZXRhZGF0YSA9IHtcbiAgICAgIHdvcmtmbG93TmFtZTogd29ya2Zsb3dSdW4ud29ya2Zsb3dOYW1lLFxuICAgICAgd29ya2Zsb3dSdW5JZDogd29ya2Zsb3dSdW4ucnVuSWQsXG4gICAgICB3b3JrZmxvd1N0YXJ0ZWRBdDogbmV3IHZtR2xvYmFsVGhpcy5EYXRlKCtzdGFydGVkQXQpLFxuICAgICAgdXJsLFxuICAgICAgZmVhdHVyZXM6IHsgZW5jcnlwdGlvbjogISFlbmNyeXB0aW9uS2V5IH0sXG4gICAgfTtcblxuICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBgQHR5cGVzL25vZGVgIHNheXMgc3ltYm9sIGlzIG5vdCB2YWxpZCwgYnV0IGl0IGRvZXMgd29ya1xuICAgIHZtR2xvYmFsVGhpc1tXT1JLRkxPV19DT05URVhUX1NZTUJPTF0gPSBjdHg7XG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciAtIGBAdHlwZXMvbm9kZWAgc2F5cyBzeW1ib2wgaXMgbm90IHZhbGlkLCBidXQgaXQgZG9lcyB3b3JrXG4gICAgdm1HbG9iYWxUaGlzW1NUQUJMRV9VTElEXSA9IHVsaWQ7XG5cbiAgICAvLyBOT1RFOiBXaWxsIGhhdmUgYSBjb25maWcgb3ZlcnJpZGUgdG8gdXNlIHRoZSBjdXN0b20gZmV0Y2ggc3RlcC5cbiAgICAvLyAgICAgICBGb3Igbm93IGBmZXRjaGAgbXVzdCBiZSBleHBsaWNpdGx5IGltcG9ydGVkIGZyb20gYHdvcmtmbG93YC5cbiAgICB2bUdsb2JhbFRoaXMuZmV0Y2ggPSAoKSA9PiB7XG4gICAgICB0aHJvdyBuZXcgdm1HbG9iYWxUaGlzLkVycm9yKFxuICAgICAgICBgR2xvYmFsIFwiZmV0Y2hcIiBpcyB1bmF2YWlsYWJsZSBpbiB3b3JrZmxvdyBmdW5jdGlvbnMuIFVzZSB0aGUgXCJmZXRjaFwiIHN0ZXAgZnVuY3Rpb24gZnJvbSBcIndvcmtmbG93XCIgdG8gbWFrZSBIVFRQIHJlcXVlc3RzLlxcblxcbkxlYXJuIG1vcmU6IGh0dHBzOi8vd29ya2Zsb3ctc2RrLmRldi9lcnIvJHtFUlJPUl9TTFVHUy5GRVRDSF9JTl9XT1JLRkxPV19GVU5DVElPTn1gXG4gICAgICApO1xuICAgIH07XG5cbiAgICAvLyBPdmVycmlkZSB0aW1lb3V0L2ludGVydmFsIGZ1bmN0aW9ucyB0byB0aHJvdyBoZWxwZnVsIGVycm9yc1xuICAgIC8vIFRoZXNlIGFyZSBub3Qgc3VwcG9ydGVkIGluIHdvcmtmbG93IGZ1bmN0aW9ucyBiZWNhdXNlIHRoZXkgcmVseSBvblxuICAgIC8vIGFzeW5jaHJvbm91cyBzY2hlZHVsaW5nIHdoaWNoIGJyZWFrcyBkZXRlcm1pbmlzdGljIHJlcGxheVxuICAgIGNvbnN0IHRpbWVvdXRFcnJvck1lc3NhZ2UgPVxuICAgICAgJ1RpbWVvdXQgZnVuY3Rpb25zIGxpa2UgXCJzZXRUaW1lb3V0XCIgYW5kIFwic2V0SW50ZXJ2YWxcIiBhcmUgbm90IHN1cHBvcnRlZCBpbiB3b3JrZmxvdyBmdW5jdGlvbnMuIFVzZSB0aGUgXCJzbGVlcFwiIGZ1bmN0aW9uIGZyb20gXCJ3b3JrZmxvd1wiIGZvciB0aW1lLWJhc2VkIGRlbGF5cy4nO1xuXG4gICAgKHZtR2xvYmFsVGhpcyBhcyBhbnkpLnNldFRpbWVvdXQgPSAoKSA9PiB7XG4gICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IodGltZW91dEVycm9yTWVzc2FnZSwge1xuICAgICAgICBzbHVnOiBFUlJPUl9TTFVHUy5USU1FT1VUX0ZVTkNUSU9OU19JTl9XT1JLRkxPVyxcbiAgICAgIH0pO1xuICAgIH07XG4gICAgKHZtR2xvYmFsVGhpcyBhcyBhbnkpLnNldEludGVydmFsID0gKCkgPT4ge1xuICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKHRpbWVvdXRFcnJvck1lc3NhZ2UsIHtcbiAgICAgICAgc2x1ZzogRVJST1JfU0xVR1MuVElNRU9VVF9GVU5DVElPTlNfSU5fV09SS0ZMT1csXG4gICAgICB9KTtcbiAgICB9O1xuICAgICh2bUdsb2JhbFRoaXMgYXMgYW55KS5jbGVhclRpbWVvdXQgPSAoKSA9PiB7XG4gICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IodGltZW91dEVycm9yTWVzc2FnZSwge1xuICAgICAgICBzbHVnOiBFUlJPUl9TTFVHUy5USU1FT1VUX0ZVTkNUSU9OU19JTl9XT1JLRkxPVyxcbiAgICAgIH0pO1xuICAgIH07XG4gICAgKHZtR2xvYmFsVGhpcyBhcyBhbnkpLmNsZWFySW50ZXJ2YWwgPSAoKSA9PiB7XG4gICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IodGltZW91dEVycm9yTWVzc2FnZSwge1xuICAgICAgICBzbHVnOiBFUlJPUl9TTFVHUy5USU1FT1VUX0ZVTkNUSU9OU19JTl9XT1JLRkxPVyxcbiAgICAgIH0pO1xuICAgIH07XG4gICAgKHZtR2xvYmFsVGhpcyBhcyBhbnkpLnNldEltbWVkaWF0ZSA9ICgpID0+IHtcbiAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcih0aW1lb3V0RXJyb3JNZXNzYWdlLCB7XG4gICAgICAgIHNsdWc6IEVSUk9SX1NMVUdTLlRJTUVPVVRfRlVOQ1RJT05TX0lOX1dPUktGTE9XLFxuICAgICAgfSk7XG4gICAgfTtcbiAgICAodm1HbG9iYWxUaGlzIGFzIGFueSkuY2xlYXJJbW1lZGlhdGUgPSAoKSA9PiB7XG4gICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IodGltZW91dEVycm9yTWVzc2FnZSwge1xuICAgICAgICBzbHVnOiBFUlJPUl9TTFVHUy5USU1FT1VUX0ZVTkNUSU9OU19JTl9XT1JLRkxPVyxcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvLyBgUmVxdWVzdGAgYW5kIGBSZXNwb25zZWAgYXJlIHNwZWNpYWwgYnVpbHQtaW4gY2xhc3NlcyB0aGF0IGludm9rZSBzdGVwc1xuICAgIC8vIGZvciB0aGUgYGpzb24oKWAsIGB0ZXh0KClgIGFuZCBgYXJyYXlCdWZmZXIoKWAgaW5zdGFuY2UgbWV0aG9kc1xuICAgIGNsYXNzIFJlcXVlc3QgaW1wbGVtZW50cyBnbG9iYWxUaGlzLlJlcXVlc3Qge1xuICAgICAgY2FjaGUhOiBnbG9iYWxUaGlzLlJlcXVlc3RbJ2NhY2hlJ107XG4gICAgICBjcmVkZW50aWFscyE6IGdsb2JhbFRoaXMuUmVxdWVzdFsnY3JlZGVudGlhbHMnXTtcbiAgICAgIGRlc3RpbmF0aW9uITogZ2xvYmFsVGhpcy5SZXF1ZXN0WydkZXN0aW5hdGlvbiddO1xuICAgICAgaGVhZGVycyE6IEhlYWRlcnM7XG4gICAgICBpbnRlZ3JpdHkhOiBzdHJpbmc7XG4gICAgICBtZXRob2QhOiBzdHJpbmc7XG4gICAgICBtb2RlITogZ2xvYmFsVGhpcy5SZXF1ZXN0Wydtb2RlJ107XG4gICAgICByZWRpcmVjdCE6IGdsb2JhbFRoaXMuUmVxdWVzdFsncmVkaXJlY3QnXTtcbiAgICAgIHJlZmVycmVyITogc3RyaW5nO1xuICAgICAgcmVmZXJyZXJQb2xpY3khOiBnbG9iYWxUaGlzLlJlcXVlc3RbJ3JlZmVycmVyUG9saWN5J107XG4gICAgICB1cmwhOiBzdHJpbmc7XG4gICAgICBrZWVwYWxpdmUhOiBib29sZWFuO1xuICAgICAgc2lnbmFsITogQWJvcnRTaWduYWw7XG4gICAgICBkdXBsZXghOiAnaGFsZic7XG4gICAgICBib2R5ITogUmVhZGFibGVTdHJlYW08YW55PiB8IG51bGw7XG5cbiAgICAgIGNvbnN0cnVjdG9yKGlucHV0OiBhbnksIGluaXQ/OiBSZXF1ZXN0SW5pdCkge1xuICAgICAgICAvLyBIYW5kbGUgVVJMIGlucHV0XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnIHx8IGlucHV0IGluc3RhbmNlb2Ygdm1HbG9iYWxUaGlzLlVSTCkge1xuICAgICAgICAgIGNvbnN0IHVybFN0cmluZyA9IFN0cmluZyhpbnB1dCk7XG4gICAgICAgICAgLy8gVmFsaWRhdGUgVVJMIGZvcm1hdFxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBuZXcgdm1HbG9iYWxUaGlzLlVSTCh1cmxTdHJpbmcpO1xuICAgICAgICAgICAgdGhpcy51cmwgPSB1cmxTdHJpbmc7XG4gICAgICAgICAgfSBjYXRjaCAoY2F1c2UpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEZhaWxlZCB0byBwYXJzZSBVUkwgZnJvbSAke3VybFN0cmluZ31gLCB7XG4gICAgICAgICAgICAgIGNhdXNlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIElucHV0IGlzIGEgUmVxdWVzdCBvYmplY3QgLSBjbG9uZSBpdHMgcHJvcGVydGllc1xuICAgICAgICAgIHRoaXMudXJsID0gaW5wdXQudXJsO1xuICAgICAgICAgIGlmICghaW5pdCkge1xuICAgICAgICAgICAgdGhpcy5tZXRob2QgPSBpbnB1dC5tZXRob2Q7XG4gICAgICAgICAgICB0aGlzLmhlYWRlcnMgPSBuZXcgdm1HbG9iYWxUaGlzLkhlYWRlcnMoaW5wdXQuaGVhZGVycyk7XG4gICAgICAgICAgICB0aGlzLmJvZHkgPSBpbnB1dC5ib2R5O1xuICAgICAgICAgICAgdGhpcy5tb2RlID0gaW5wdXQubW9kZTtcbiAgICAgICAgICAgIHRoaXMuY3JlZGVudGlhbHMgPSBpbnB1dC5jcmVkZW50aWFscztcbiAgICAgICAgICAgIHRoaXMuY2FjaGUgPSBpbnB1dC5jYWNoZTtcbiAgICAgICAgICAgIHRoaXMucmVkaXJlY3QgPSBpbnB1dC5yZWRpcmVjdDtcbiAgICAgICAgICAgIHRoaXMucmVmZXJyZXIgPSBpbnB1dC5yZWZlcnJlcjtcbiAgICAgICAgICAgIHRoaXMucmVmZXJyZXJQb2xpY3kgPSBpbnB1dC5yZWZlcnJlclBvbGljeTtcbiAgICAgICAgICAgIHRoaXMuaW50ZWdyaXR5ID0gaW5wdXQuaW50ZWdyaXR5O1xuICAgICAgICAgICAgdGhpcy5rZWVwYWxpdmUgPSBpbnB1dC5rZWVwYWxpdmU7XG4gICAgICAgICAgICB0aGlzLnNpZ25hbCA9IGlucHV0LnNpZ25hbDtcbiAgICAgICAgICAgIHRoaXMuZHVwbGV4ID0gaW5wdXQuZHVwbGV4O1xuICAgICAgICAgICAgdGhpcy5kZXN0aW5hdGlvbiA9IGlucHV0LmRlc3RpbmF0aW9uO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBJZiBpbml0IGlzIHByb3ZpZGVkLCBtZXJnZTogdXNlIHNvdXJjZSBwcm9wZXJ0aWVzLCB0aGVuIG92ZXJyaWRlIHdpdGggaW5pdFxuICAgICAgICAgIC8vIENvcHkgYWxsIHByb3BlcnRpZXMgZnJvbSB0aGUgc291cmNlIFJlcXVlc3QgZmlyc3RcbiAgICAgICAgICB0aGlzLm1ldGhvZCA9IGlucHV0Lm1ldGhvZDtcbiAgICAgICAgICB0aGlzLmhlYWRlcnMgPSBuZXcgdm1HbG9iYWxUaGlzLkhlYWRlcnMoaW5wdXQuaGVhZGVycyk7XG4gICAgICAgICAgdGhpcy5ib2R5ID0gaW5wdXQuYm9keTtcbiAgICAgICAgICB0aGlzLm1vZGUgPSBpbnB1dC5tb2RlO1xuICAgICAgICAgIHRoaXMuY3JlZGVudGlhbHMgPSBpbnB1dC5jcmVkZW50aWFscztcbiAgICAgICAgICB0aGlzLmNhY2hlID0gaW5wdXQuY2FjaGU7XG4gICAgICAgICAgdGhpcy5yZWRpcmVjdCA9IGlucHV0LnJlZGlyZWN0O1xuICAgICAgICAgIHRoaXMucmVmZXJyZXIgPSBpbnB1dC5yZWZlcnJlcjtcbiAgICAgICAgICB0aGlzLnJlZmVycmVyUG9saWN5ID0gaW5wdXQucmVmZXJyZXJQb2xpY3k7XG4gICAgICAgICAgdGhpcy5pbnRlZ3JpdHkgPSBpbnB1dC5pbnRlZ3JpdHk7XG4gICAgICAgICAgdGhpcy5rZWVwYWxpdmUgPSBpbnB1dC5rZWVwYWxpdmU7XG4gICAgICAgICAgdGhpcy5zaWduYWwgPSBpbnB1dC5zaWduYWw7XG4gICAgICAgICAgdGhpcy5kdXBsZXggPSBpbnB1dC5kdXBsZXg7XG4gICAgICAgICAgdGhpcy5kZXN0aW5hdGlvbiA9IGlucHV0LmRlc3RpbmF0aW9uO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gT3ZlcnJpZGUgd2l0aCBpbml0IG9wdGlvbnMgaWYgcHJvdmlkZWRcbiAgICAgICAgLy8gU2V0IG1ldGhvZFxuICAgICAgICBpZiAoaW5pdD8ubWV0aG9kKSB7XG4gICAgICAgICAgdGhpcy5tZXRob2QgPSBpbml0Lm1ldGhvZC50b1VwcGVyQ2FzZSgpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLm1ldGhvZCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAvLyBGYWxsYmFjayB0byBkZWZhdWx0IGZvciBzdHJpbmcgaW5wdXQgY2FzZVxuICAgICAgICAgIHRoaXMubWV0aG9kID0gJ0dFVCc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgaGVhZGVyc1xuICAgICAgICBpZiAoaW5pdD8uaGVhZGVycykge1xuICAgICAgICAgIHRoaXMuaGVhZGVycyA9IG5ldyB2bUdsb2JhbFRoaXMuSGVhZGVycyhpbml0LmhlYWRlcnMpO1xuICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgIHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycgfHxcbiAgICAgICAgICBpbnB1dCBpbnN0YW5jZW9mIHZtR2xvYmFsVGhpcy5VUkxcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gRm9yIHN0cmluZy9VUkwgaW5wdXQsIGNyZWF0ZSBlbXB0eSBoZWFkZXJzXG4gICAgICAgICAgdGhpcy5oZWFkZXJzID0gbmV3IHZtR2xvYmFsVGhpcy5IZWFkZXJzKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgb3RoZXIgcHJvcGVydGllcyB3aXRoIGluaXQgdmFsdWVzIG9yIGRlZmF1bHRzXG4gICAgICAgIGlmIChpbml0Py5tb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aGlzLm1vZGUgPSBpbml0Lm1vZGU7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMubW9kZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aGlzLm1vZGUgPSAnY29ycyc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaW5pdD8uY3JlZGVudGlhbHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRoaXMuY3JlZGVudGlhbHMgPSBpbml0LmNyZWRlbnRpYWxzO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLmNyZWRlbnRpYWxzICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRoaXMuY3JlZGVudGlhbHMgPSAnc2FtZS1vcmlnaW4nO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gYGFueWAgY2FzdCBoZXJlIGJlY2F1c2UgQHR5cGVzL25vZGUgdjIyIGRvZXMgbm90IHlldCBoYXZlIGBjYWNoZWBcbiAgICAgICAgaWYgKChpbml0IGFzIGFueSk/LmNhY2hlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aGlzLmNhY2hlID0gKGluaXQgYXMgYW55KS5jYWNoZTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5jYWNoZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aGlzLmNhY2hlID0gJ2RlZmF1bHQnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGluaXQ/LnJlZGlyZWN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aGlzLnJlZGlyZWN0ID0gaW5pdC5yZWRpcmVjdDtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5yZWRpcmVjdCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aGlzLnJlZGlyZWN0ID0gJ2ZvbGxvdyc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaW5pdD8ucmVmZXJyZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRoaXMucmVmZXJyZXIgPSBpbml0LnJlZmVycmVyO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLnJlZmVycmVyICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRoaXMucmVmZXJyZXIgPSAnYWJvdXQ6Y2xpZW50JztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbml0Py5yZWZlcnJlclBvbGljeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhpcy5yZWZlcnJlclBvbGljeSA9IGluaXQucmVmZXJyZXJQb2xpY3k7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMucmVmZXJyZXJQb2xpY3kgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhpcy5yZWZlcnJlclBvbGljeSA9ICcnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGluaXQ/LmludGVncml0eSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhpcy5pbnRlZ3JpdHkgPSBpbml0LmludGVncml0eTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5pbnRlZ3JpdHkgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhpcy5pbnRlZ3JpdHkgPSAnJztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbml0Py5rZWVwYWxpdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRoaXMua2VlcGFsaXZlID0gaW5pdC5rZWVwYWxpdmU7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMua2VlcGFsaXZlICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICB0aGlzLmtlZXBhbGl2ZSA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGluaXQ/LnNpZ25hbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciAtIEFib3J0U2lnbmFsIHN0dWJcbiAgICAgICAgICB0aGlzLnNpZ25hbCA9IGluaXQuc2lnbmFsO1xuICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLnNpZ25hbCkge1xuICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBBYm9ydFNpZ25hbCBzdHViXG4gICAgICAgICAgdGhpcy5zaWduYWwgPSB7IGFib3J0ZWQ6IGZhbHNlIH07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuZHVwbGV4KSB7XG4gICAgICAgICAgdGhpcy5kdXBsZXggPSAnaGFsZic7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuZGVzdGluYXRpb24pIHtcbiAgICAgICAgICB0aGlzLmRlc3RpbmF0aW9uID0gJ2RvY3VtZW50JztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGJvZHkgPSBpbml0Py5ib2R5O1xuXG4gICAgICAgIC8vIFZhbGlkYXRlIHRoYXQgR0VUL0hFQUQgbWV0aG9kcyBkb24ndCBoYXZlIGEgYm9keVxuICAgICAgICBpZiAoXG4gICAgICAgICAgYm9keSAhPT0gbnVsbCAmJlxuICAgICAgICAgIGJvZHkgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICh0aGlzLm1ldGhvZCA9PT0gJ0dFVCcgfHwgdGhpcy5tZXRob2QgPT09ICdIRUFEJylcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgUmVxdWVzdCB3aXRoIEdFVC9IRUFEIG1ldGhvZCBjYW5ub3QgaGF2ZSBib2R5LmApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3RvcmUgdGhlIG9yaWdpbmFsIEJvZHlJbml0IGZvciBzZXJpYWxpemF0aW9uXG4gICAgICAgIGlmIChib2R5ICE9PSBudWxsICYmIGJvZHkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vIENyZWF0ZSBhIFwiZmFrZVwiIFJlYWRhYmxlU3RyZWFtIHRoYXQgc3RvcmVzIHRoZSBvcmlnaW5hbCBib2R5XG4gICAgICAgICAgLy8gVGhpcyBhdm9pZHMgZG9pbmcgYXN5bmMgd29yayBkdXJpbmcgd29ya2Zsb3cgcmVwbGF5XG4gICAgICAgICAgdGhpcy5ib2R5ID0gT2JqZWN0LmNyZWF0ZSh2bUdsb2JhbFRoaXMuUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLCB7XG4gICAgICAgICAgICBbQk9EWV9JTklUX1NZTUJPTF06IHtcbiAgICAgICAgICAgICAgdmFsdWU6IGJvZHksXG4gICAgICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5ib2R5ID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjbG9uZSgpOiBSZXF1ZXN0IHtcbiAgICAgICAgRU5PVFNVUCgpO1xuICAgICAgfVxuXG4gICAgICBnZXQgYm9keVVzZWQoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgLy8gVE9ETzogaW1wbGVtZW50IHRoZXNlXG4gICAgICBibG9iITogKCkgPT4gUHJvbWlzZTxCbG9iPjtcbiAgICAgIGZvcm1EYXRhITogKCkgPT4gUHJvbWlzZTxGb3JtRGF0YT47XG5cbiAgICAgIGFycmF5QnVmZmVyITogKCkgPT4gUHJvbWlzZTxBcnJheUJ1ZmZlcj47XG4gICAgICBqc29uITogKCkgPT4gUHJvbWlzZTxhbnk+O1xuICAgICAgdGV4dCE6ICgpID0+IFByb21pc2U8c3RyaW5nPjtcblxuICAgICAgYXN5bmMgYnl0ZXMoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShhd2FpdCB0aGlzLmFycmF5QnVmZmVyKCkpO1xuICAgICAgfVxuICAgIH1cbiAgICB2bUdsb2JhbFRoaXMuUmVxdWVzdCA9IFJlcXVlc3Q7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhSZXF1ZXN0LnByb3RvdHlwZSwge1xuICAgICAgYXJyYXlCdWZmZXI6IHtcbiAgICAgICAgdmFsdWU6IHVzZVN0ZXA8W10sIEFycmF5QnVmZmVyPignX19idWlsdGluX3Jlc3BvbnNlX2FycmF5X2J1ZmZlcicpLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgfSxcbiAgICAgIGpzb246IHtcbiAgICAgICAgdmFsdWU6IHVzZVN0ZXA8W10sIGFueT4oJ19fYnVpbHRpbl9yZXNwb25zZV9qc29uJyksXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB9LFxuICAgICAgdGV4dDoge1xuICAgICAgICB2YWx1ZTogdXNlU3RlcDxbXSwgc3RyaW5nPignX19idWlsdGluX3Jlc3BvbnNlX3RleHQnKSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjbGFzcyBSZXNwb25zZSBpbXBsZW1lbnRzIGdsb2JhbFRoaXMuUmVzcG9uc2Uge1xuICAgICAgdHlwZSE6IGdsb2JhbFRoaXMuUmVzcG9uc2VbJ3R5cGUnXTtcbiAgICAgIHVybCE6IHN0cmluZztcbiAgICAgIHN0YXR1cyE6IG51bWJlcjtcbiAgICAgIHN0YXR1c1RleHQhOiBzdHJpbmc7XG4gICAgICBib2R5ITogUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4gfCBudWxsO1xuICAgICAgaGVhZGVycyE6IEhlYWRlcnM7XG4gICAgICByZWRpcmVjdGVkITogYm9vbGVhbjtcblxuICAgICAgY29uc3RydWN0b3IoYm9keT86IGFueSwgaW5pdD86IFJlc3BvbnNlSW5pdCkge1xuICAgICAgICB0aGlzLnN0YXR1cyA9IGluaXQ/LnN0YXR1cyA/PyAyMDA7XG4gICAgICAgIHRoaXMuc3RhdHVzVGV4dCA9IGluaXQ/LnN0YXR1c1RleHQgPz8gJyc7XG4gICAgICAgIHRoaXMuaGVhZGVycyA9IG5ldyB2bUdsb2JhbFRoaXMuSGVhZGVycyhpbml0Py5oZWFkZXJzKTtcbiAgICAgICAgdGhpcy50eXBlID0gJ2RlZmF1bHQnO1xuICAgICAgICB0aGlzLnVybCA9ICcnO1xuICAgICAgICB0aGlzLnJlZGlyZWN0ZWQgPSBmYWxzZTtcblxuICAgICAgICAvLyBWYWxpZGF0ZSB0aGF0IG51bGwtYm9keSBzdGF0dXMgY29kZXMgZG9uJ3QgaGF2ZSBhIGJvZHlcbiAgICAgICAgLy8gUGVyIEhUVFAgc3BlYzogMjA0IChObyBDb250ZW50KSwgMjA1IChSZXNldCBDb250ZW50KSwgYW5kIDMwNCAoTm90IE1vZGlmaWVkKVxuICAgICAgICBpZiAoXG4gICAgICAgICAgYm9keSAhPT0gbnVsbCAmJlxuICAgICAgICAgIGJvZHkgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICh0aGlzLnN0YXR1cyA9PT0gMjA0IHx8IHRoaXMuc3RhdHVzID09PSAyMDUgfHwgdGhpcy5zdGF0dXMgPT09IDMwNClcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAgIGBSZXNwb25zZSBjb25zdHJ1Y3RvcjogSW52YWxpZCByZXNwb25zZSBzdGF0dXMgY29kZSAke3RoaXMuc3RhdHVzfWBcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3RvcmUgdGhlIG9yaWdpbmFsIEJvZHlJbml0IGZvciBzZXJpYWxpemF0aW9uXG4gICAgICAgIGlmIChib2R5ICE9PSBudWxsICYmIGJvZHkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vIENyZWF0ZSBhIFwiZmFrZVwiIFJlYWRhYmxlU3RyZWFtIHRoYXQgc3RvcmVzIHRoZSBvcmlnaW5hbCBib2R5XG4gICAgICAgICAgLy8gVGhpcyBhdm9pZHMgZG9pbmcgYXN5bmMgd29yayBkdXJpbmcgd29ya2Zsb3cgcmVwbGF5XG4gICAgICAgICAgdGhpcy5ib2R5ID0gT2JqZWN0LmNyZWF0ZSh2bUdsb2JhbFRoaXMuUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLCB7XG4gICAgICAgICAgICBbQk9EWV9JTklUX1NZTUJPTF06IHtcbiAgICAgICAgICAgICAgdmFsdWU6IGJvZHksXG4gICAgICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5ib2R5ID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBUT0RPOiBpbXBsZW1lbnQgdGhlc2VcbiAgICAgIGNsb25lITogKCkgPT4gUmVzcG9uc2U7XG4gICAgICBibG9iITogKCkgPT4gUHJvbWlzZTxnbG9iYWxUaGlzLkJsb2I+O1xuICAgICAgZm9ybURhdGEhOiAoKSA9PiBQcm9taXNlPGdsb2JhbFRoaXMuRm9ybURhdGE+O1xuXG4gICAgICBnZXQgb2soKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXR1cyA+PSAyMDAgJiYgdGhpcy5zdGF0dXMgPCAzMDA7XG4gICAgICB9XG5cbiAgICAgIGdldCBib2R5VXNlZCgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBhcnJheUJ1ZmZlciE6ICgpID0+IFByb21pc2U8QXJyYXlCdWZmZXI+O1xuICAgICAganNvbiE6ICgpID0+IFByb21pc2U8YW55PjtcbiAgICAgIHRleHQhOiAoKSA9PiBQcm9taXNlPHN0cmluZz47XG5cbiAgICAgIGFzeW5jIGJ5dGVzKCkge1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYXdhaXQgdGhpcy5hcnJheUJ1ZmZlcigpKTtcbiAgICAgIH1cblxuICAgICAgc3RhdGljIGpzb24oZGF0YTogYW55LCBpbml0PzogUmVzcG9uc2VJbml0KTogUmVzcG9uc2Uge1xuICAgICAgICBjb25zdCBib2R5ID0gSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG4gICAgICAgIGNvbnN0IGhlYWRlcnMgPSBuZXcgdm1HbG9iYWxUaGlzLkhlYWRlcnMoaW5pdD8uaGVhZGVycyk7XG4gICAgICAgIGlmICghaGVhZGVycy5oYXMoJ2NvbnRlbnQtdHlwZScpKSB7XG4gICAgICAgICAgaGVhZGVycy5zZXQoJ2NvbnRlbnQtdHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShib2R5LCB7IC4uLmluaXQsIGhlYWRlcnMgfSk7XG4gICAgICB9XG5cbiAgICAgIHN0YXRpYyBlcnJvcigpOiBSZXNwb25zZSB7XG4gICAgICAgIEVOT1RTVVAoKTtcbiAgICAgIH1cblxuICAgICAgc3RhdGljIHJlZGlyZWN0KHVybDogc3RyaW5nIHwgVVJMLCBzdGF0dXM6IG51bWJlciA9IDMwMik6IFJlc3BvbnNlIHtcbiAgICAgICAgLy8gVmFsaWRhdGUgc3RhdHVzIGNvZGUgLSBvbmx5IHNwZWNpZmljIHJlZGlyZWN0IGNvZGVzIGFyZSBhbGxvd2VkXG4gICAgICAgIGlmICghWzMwMSwgMzAyLCAzMDMsIDMwNywgMzA4XS5pbmNsdWRlcyhzdGF0dXMpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXG4gICAgICAgICAgICBgSW52YWxpZCByZWRpcmVjdCBzdGF0dXMgY29kZTogJHtzdGF0dXN9LiBNdXN0IGJlIG9uZSBvZjogMzAxLCAzMDIsIDMwMywgMzA3LCAzMDhgXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENyZWF0ZSByZXNwb25zZSB3aXRoIExvY2F0aW9uIGhlYWRlclxuICAgICAgICBjb25zdCBoZWFkZXJzID0gbmV3IHZtR2xvYmFsVGhpcy5IZWFkZXJzKCk7XG4gICAgICAgIGhlYWRlcnMuc2V0KCdMb2NhdGlvbicsIFN0cmluZyh1cmwpKTtcblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IE9iamVjdC5jcmVhdGUoUmVzcG9uc2UucHJvdG90eXBlKTtcbiAgICAgICAgcmVzcG9uc2Uuc3RhdHVzID0gc3RhdHVzO1xuICAgICAgICByZXNwb25zZS5zdGF0dXNUZXh0ID0gJyc7XG4gICAgICAgIHJlc3BvbnNlLmhlYWRlcnMgPSBoZWFkZXJzO1xuICAgICAgICByZXNwb25zZS5ib2R5ID0gbnVsbDtcbiAgICAgICAgcmVzcG9uc2UudHlwZSA9ICdkZWZhdWx0JztcbiAgICAgICAgcmVzcG9uc2UudXJsID0gJyc7XG4gICAgICAgIHJlc3BvbnNlLnJlZGlyZWN0ZWQgPSBmYWxzZTtcblxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHZtR2xvYmFsVGhpcy5SZXNwb25zZSA9IFJlc3BvbnNlO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoUmVzcG9uc2UucHJvdG90eXBlLCB7XG4gICAgICBhcnJheUJ1ZmZlcjoge1xuICAgICAgICB2YWx1ZTogdXNlU3RlcDxbXSwgQXJyYXlCdWZmZXI+KCdfX2J1aWx0aW5fcmVzcG9uc2VfYXJyYXlfYnVmZmVyJyksXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB9LFxuICAgICAganNvbjoge1xuICAgICAgICB2YWx1ZTogdXNlU3RlcDxbXSwgYW55PignX19idWlsdGluX3Jlc3BvbnNlX2pzb24nKSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIH0sXG4gICAgICB0ZXh0OiB7XG4gICAgICAgIHZhbHVlOiB1c2VTdGVwPFtdLCBzdHJpbmc+KCdfX2J1aWx0aW5fcmVzcG9uc2VfdGV4dCcpLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNsYXNzIFJlYWRhYmxlU3RyZWFtPFQ+IGltcGxlbWVudHMgZ2xvYmFsVGhpcy5SZWFkYWJsZVN0cmVhbTxUPiB7XG4gICAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgRU5PVFNVUCgpO1xuICAgICAgfVxuXG4gICAgICBnZXQgbG9ja2VkKCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGNhbmNlbCgpOiBhbnkge1xuICAgICAgICBFTk9UU1VQKCk7XG4gICAgICB9XG5cbiAgICAgIGdldFJlYWRlcigpOiBhbnkge1xuICAgICAgICBFTk9UU1VQKCk7XG4gICAgICB9XG5cbiAgICAgIHBpcGVUaHJvdWdoKCk6IGFueSB7XG4gICAgICAgIEVOT1RTVVAoKTtcbiAgICAgIH1cblxuICAgICAgcGlwZVRvKCk6IGFueSB7XG4gICAgICAgIEVOT1RTVVAoKTtcbiAgICAgIH1cblxuICAgICAgdGVlKCk6IGFueSB7XG4gICAgICAgIEVOT1RTVVAoKTtcbiAgICAgIH1cblxuICAgICAgdmFsdWVzKCk6IGFueSB7XG4gICAgICAgIEVOT1RTVVAoKTtcbiAgICAgIH1cblxuICAgICAgc3RhdGljIGZyb20oKTogYW55IHtcbiAgICAgICAgRU5PVFNVUCgpO1xuICAgICAgfVxuXG4gICAgICBbU3ltYm9sLmFzeW5jSXRlcmF0b3JdKCk6IGFueSB7XG4gICAgICAgIEVOT1RTVVAoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdm1HbG9iYWxUaGlzLlJlYWRhYmxlU3RyZWFtID0gUmVhZGFibGVTdHJlYW07XG5cbiAgICBjbGFzcyBXcml0YWJsZVN0cmVhbTxUPiBpbXBsZW1lbnRzIGdsb2JhbFRoaXMuV3JpdGFibGVTdHJlYW08VD4ge1xuICAgICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIEVOT1RTVVAoKTtcbiAgICAgIH1cblxuICAgICAgZ2V0IGxvY2tlZCgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBhYm9ydCgpOiBhbnkge1xuICAgICAgICBFTk9UU1VQKCk7XG4gICAgICB9XG5cbiAgICAgIGNsb3NlKCk6IGFueSB7XG4gICAgICAgIEVOT1RTVVAoKTtcbiAgICAgIH1cblxuICAgICAgZ2V0V3JpdGVyKCk6IGFueSB7XG4gICAgICAgIEVOT1RTVVAoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdm1HbG9iYWxUaGlzLldyaXRhYmxlU3RyZWFtID0gV3JpdGFibGVTdHJlYW07XG5cbiAgICBjbGFzcyBUcmFuc2Zvcm1TdHJlYW08SSwgTz4gaW1wbGVtZW50cyBnbG9iYWxUaGlzLlRyYW5zZm9ybVN0cmVhbTxJLCBPPiB7XG4gICAgICByZWFkYWJsZTogZ2xvYmFsVGhpcy5SZWFkYWJsZVN0cmVhbTxPPjtcbiAgICAgIHdyaXRhYmxlOiBnbG9iYWxUaGlzLldyaXRhYmxlU3RyZWFtPEk+O1xuXG4gICAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgRU5PVFNVUCgpO1xuICAgICAgfVxuICAgIH1cbiAgICB2bUdsb2JhbFRoaXMuVHJhbnNmb3JtU3RyZWFtID0gVHJhbnNmb3JtU3RyZWFtO1xuXG4gICAgLy8gRXZlbnR1YWxseSB3ZSdsbCBwcm9iYWJseSB3YW50IHRvIHByb3ZpZGUgb3VyIG93biBgY29uc29sZWAgb2JqZWN0LFxuICAgIC8vIGJ1dCBmb3Igbm93IHdlJ2xsIGp1c3QgZXhwb3NlIHRoZSBnbG9iYWwgb25lLlxuICAgIHZtR2xvYmFsVGhpcy5jb25zb2xlID0gZ2xvYmFsVGhpcy5jb25zb2xlO1xuXG4gICAgLy8gSEFDSzogcHJvcGFnYXRlIHN5bWJvbCBuZWVkZWQgZm9yIEFJIGdhdGV3YXkgdXNhZ2VcbiAgICBjb25zdCBTWU1CT0xfRk9SX1JFUV9DT05URVhUID0gU3ltYm9sLmZvcignQHZlcmNlbC9yZXF1ZXN0LWNvbnRleHQnKTtcbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIC0gYEB0eXBlcy9ub2RlYCBzYXlzIHN5bWJvbCBpcyBub3QgdmFsaWQsIGJ1dCBpdCBkb2VzIHdvcmtcbiAgICB2bUdsb2JhbFRoaXNbU1lNQk9MX0ZPUl9SRVFfQ09OVEVYVF0gPSAoZ2xvYmFsVGhpcyBhcyBhbnkpW1xuICAgICAgU1lNQk9MX0ZPUl9SRVFfQ09OVEVYVFxuICAgIF07XG5cbiAgICAvLyBHZXQgYSByZWZlcmVuY2UgdG8gdGhlIHVzZXItZGVmaW5lZCB3b3JrZmxvdyBmdW5jdGlvbi5cbiAgICAvLyBUaGUgZmlsZW5hbWUgcGFyYW1ldGVyIGVuc3VyZXMgc3RhY2sgdHJhY2VzIHNob3cgYSBtZWFuaW5nZnVsIG5hbWVcbiAgICAvLyAoZS5nLiwgXCJleGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHNcIikgaW5zdGVhZCBvZiBcImV2YWxtYWNoaW5lLjxhbm9ueW1vdXM+XCIuXG4gICAgY29uc3QgcGFyc2VkTmFtZSA9IHBhcnNlV29ya2Zsb3dOYW1lKHdvcmtmbG93UnVuLndvcmtmbG93TmFtZSk7XG4gICAgY29uc3QgZmlsZW5hbWUgPSBwYXJzZWROYW1lPy5tb2R1bGVTcGVjaWZpZXIgfHwgd29ya2Zsb3dSdW4ud29ya2Zsb3dOYW1lO1xuXG4gICAgY29uc3Qgd29ya2Zsb3dGbiA9IHJ1bkluQ29udGV4dChcbiAgICAgIGAke3dvcmtmbG93Q29kZX07IGdsb2JhbFRoaXMuX19wcml2YXRlX3dvcmtmbG93cz8uZ2V0KCR7SlNPTi5zdHJpbmdpZnkod29ya2Zsb3dSdW4ud29ya2Zsb3dOYW1lKX0pYCxcbiAgICAgIGNvbnRleHQsXG4gICAgICB7IGZpbGVuYW1lIH1cbiAgICApO1xuXG4gICAgaWYgKHR5cGVvZiB3b3JrZmxvd0ZuICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgV29ya2Zsb3dOb3RSZWdpc3RlcmVkRXJyb3Iod29ya2Zsb3dSdW4ud29ya2Zsb3dOYW1lKTtcbiAgICB9XG5cbiAgICAvLyBDaGFpbiB3b3JrZmxvdyBhcmd1bWVudCBoeWRyYXRpb24gb250byB0aGUgcHJvbWlzZVF1ZXVlIHNvIHRoYXQgdGhlXG4gICAgLy8gdW5jb25zdW1lZCBldmVudCBjaGVjayAod2hpY2ggd2FpdHMgZm9yIHRoZSBxdWV1ZSB0byBkcmFpbikgZG9lc24ndFxuICAgIC8vIGZpcmUgZHVyaW5nIHRoZSBhc3luYyBnYXAgYmV0d2VlbiBydW5fc3RhcnRlZCBjb25zdW1wdGlvbiBhbmQgdGhlXG4gICAgLy8gd29ya2Zsb3cgZnVuY3Rpb24gc3Vic2NyaWJpbmcgaXRzIGZpcnN0IHN0ZXAgY2FsbGJhY2tzLlxuICAgIGxldCBhcmdzOiB1bmtub3duW10gPSBbXTtcbiAgICB3b3JrZmxvd0NvbnRleHQucHJvbWlzZVF1ZXVlID0gd29ya2Zsb3dDb250ZXh0LnByb21pc2VRdWV1ZS50aGVuKFxuICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhcmdzID0gYXdhaXQgaHlkcmF0ZVdvcmtmbG93QXJndW1lbnRzKFxuICAgICAgICAgIHdvcmtmbG93UnVuLmlucHV0LFxuICAgICAgICAgIHdvcmtmbG93UnVuLnJ1bklkLFxuICAgICAgICAgIGVuY3J5cHRpb25LZXksXG4gICAgICAgICAgdm1HbG9iYWxUaGlzXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgKTtcbiAgICBhd2FpdCB3b3JrZmxvd0NvbnRleHQucHJvbWlzZVF1ZXVlO1xuXG4gICAgc3Bhbj8uc2V0QXR0cmlidXRlcyh7XG4gICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dBcmd1bWVudHNDb3VudChhcmdzLmxlbmd0aCksXG4gICAgfSk7XG5cbiAgICAvLyBJbnZva2UgdXNlciB3b3JrZmxvd1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBQcm9taXNlLnJhY2UoW1xuICAgICAgICB3b3JrZmxvd0ZuKC4uLmFyZ3MpLFxuICAgICAgICB3b3JrZmxvd0Rpc2NvbnRpbnVhdGlvbi5wcm9taXNlLFxuICAgICAgXSk7XG5cbiAgICAgIGNvbnN0IGRlaHlkcmF0ZWQgPSBhd2FpdCBkZWh5ZHJhdGVXb3JrZmxvd1JldHVyblZhbHVlKFxuICAgICAgICByZXN1bHQsXG4gICAgICAgIHdvcmtmbG93UnVuLnJ1bklkLFxuICAgICAgICBlbmNyeXB0aW9uS2V5LFxuICAgICAgICB2bUdsb2JhbFRoaXNcbiAgICAgICk7XG5cbiAgICAgIHNwYW4/LnNldEF0dHJpYnV0ZXMoe1xuICAgICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dSZXN1bHRUeXBlKHR5cGVvZiByZXN1bHQpLFxuICAgICAgfSk7XG5cbiAgICAgIHdhcm5QZW5kaW5nUXVldWVJdGVtcyhcbiAgICAgICAgd29ya2Zsb3dSdW4ucnVuSWQsXG4gICAgICAgIHdvcmtmbG93Q29udGV4dC5pbnZvY2F0aW9uc1F1ZXVlLFxuICAgICAgICAnY29tcGxldGVkJ1xuICAgICAgKTtcblxuICAgICAgcmV0dXJuIGRlaHlkcmF0ZWQ7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBMZXQgV29ya2Zsb3dTdXNwZW5zaW9uIHByb3BhZ2F0ZSDigJQgaGFuZGxlZCBzZXBhcmF0ZWx5IGJ5IHRoZSBydW50aW1lXG4gICAgICBpZiAoV29ya2Zsb3dTdXNwZW5zaW9uLmlzKGVycikpIHtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuXG4gICAgICB3YXJuUGVuZGluZ1F1ZXVlSXRlbXMoXG4gICAgICAgIHdvcmtmbG93UnVuLnJ1bklkLFxuICAgICAgICB3b3JrZmxvd0NvbnRleHQuaW52b2NhdGlvbnNRdWV1ZSxcbiAgICAgICAgJ2ZhaWxlZCdcbiAgICAgICk7XG5cbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gIH0pO1xufVxuIl19
|
|
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==
|