@workflow/core 5.0.0-beta.1 → 5.0.0-beta.10
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/README.md +1 -1
- 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.js +1 -1
- 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.js +1 -1
- package/dist/classify-error.d.ts +11 -3
- package/dist/classify-error.d.ts.map +1 -1
- package/dist/classify-error.js +56 -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 +147 -0
- 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 +165 -0
- package/dist/encryption.d.ts +22 -1
- package/dist/encryption.d.ts.map +1 -1
- package/dist/encryption.js +72 -27
- package/dist/events-consumer.d.ts +7 -0
- package/dist/events-consumer.d.ts.map +1 -1
- package/dist/events-consumer.js +18 -3
- package/dist/flushable-stream.d.ts +10 -10
- package/dist/flushable-stream.d.ts.map +1 -1
- package/dist/flushable-stream.js +18 -13
- package/dist/global.d.ts +4 -0
- package/dist/global.d.ts.map +1 -1
- package/dist/global.js +8 -2
- 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 +28 -30
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +77 -31
- package/dist/private.js +3 -3
- package/dist/runtime/constants.d.ts +48 -0
- package/dist/runtime/constants.d.ts.map +1 -1
- package/dist/runtime/constants.js +91 -8
- package/dist/runtime/get-port-lazy.d.ts +10 -0
- package/dist/runtime/get-port-lazy.d.ts.map +1 -0
- package/dist/runtime/get-port-lazy.js +30 -0
- package/dist/runtime/get-world-lazy.d.ts +32 -0
- package/dist/runtime/get-world-lazy.d.ts.map +1 -0
- package/dist/runtime/get-world-lazy.js +56 -0
- package/dist/runtime/helpers.d.ts +38 -5
- package/dist/runtime/helpers.d.ts.map +1 -1
- package/dist/runtime/helpers.js +76 -19
- 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 +191 -0
- package/dist/runtime/resume-hook.d.ts.map +1 -1
- package/dist/runtime/resume-hook.js +5 -4
- package/dist/runtime/run.d.ts.map +1 -1
- package/dist/runtime/run.js +31 -6
- package/dist/runtime/runs.d.ts.map +1 -1
- package/dist/runtime/runs.js +4 -1
- package/dist/runtime/start.js +9 -4
- package/dist/runtime/step-executor.d.ts +40 -0
- package/dist/runtime/step-executor.d.ts.map +1 -0
- package/dist/runtime/step-executor.js +492 -0
- package/dist/runtime/step-handler.d.ts.map +1 -1
- package/dist/runtime/step-handler.js +215 -114
- package/dist/runtime/suspension-handler.d.ts +22 -4
- package/dist/runtime/suspension-handler.d.ts.map +1 -1
- package/dist/runtime/suspension-handler.js +90 -73
- package/dist/runtime/world-init.d.ts +75 -0
- package/dist/runtime/world-init.d.ts.map +1 -0
- package/dist/runtime/world-init.js +75 -0
- package/dist/runtime/world.d.ts.map +1 -1
- package/dist/runtime/world.js +47 -18
- package/dist/runtime.d.ts +8 -7
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +798 -320
- package/dist/schemas.d.ts +1 -1
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +1 -1
- package/dist/serialization/client.d.ts +17 -0
- package/dist/serialization/client.d.ts.map +1 -0
- package/dist/serialization/client.js +45 -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 +98 -0
- package/dist/serialization/codec.d.ts +90 -0
- package/dist/serialization/codec.d.ts.map +1 -0
- package/dist/serialization/codec.js +17 -0
- package/dist/serialization/encryption.d.ts +32 -0
- package/dist/serialization/encryption.d.ts.map +1 -0
- package/dist/serialization/encryption.js +67 -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/index.d.ts +18 -0
- package/dist/serialization/index.d.ts.map +1 -0
- package/dist/serialization/index.js +20 -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 +68 -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 +417 -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 +88 -0
- package/dist/serialization/step.d.ts +17 -0
- package/dist/serialization/step.d.ts.map +1 -0
- package/dist/serialization/step.js +45 -0
- package/dist/serialization/types.d.ts +222 -0
- package/dist/serialization/types.d.ts.map +1 -0
- package/dist/serialization/types.js +21 -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 +16 -2
- package/dist/serialization-format.d.ts.map +1 -1
- package/dist/serialization-format.js +103 -5
- package/dist/serialization.d.ts +216 -226
- package/dist/serialization.d.ts.map +1 -1
- package/dist/serialization.js +909 -643
- package/dist/set-attributes.d.ts +13 -0
- package/dist/set-attributes.d.ts.map +1 -0
- package/dist/set-attributes.js +40 -0
- package/dist/sleep.d.ts.map +1 -1
- package/dist/sleep.js +3 -2
- package/dist/source-map.d.ts.map +1 -1
- package/dist/source-map.js +44 -6
- package/dist/step/context-storage.d.ts +14 -0
- package/dist/step/context-storage.d.ts.map +1 -1
- package/dist/step/context-storage.js +1 -1
- 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 +38 -4
- package/dist/step.d.ts.map +1 -1
- package/dist/step.js +97 -19
- package/dist/symbols.d.ts +20 -0
- package/dist/symbols.d.ts.map +1 -1
- package/dist/symbols.js +21 -1
- package/dist/telemetry/semantic-conventions.d.ts +2 -2
- package/dist/telemetry/semantic-conventions.js +1 -1
- package/dist/telemetry.js +1 -1
- 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 +18 -3
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +28 -5
- 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 +3 -2
- package/dist/vm/uint8array-base64.js +1 -1
- package/dist/vm/uuid.js +1 -1
- 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 +260 -0
- package/dist/workflow/create-hook.d.ts.map +1 -1
- package/dist/workflow/create-hook.js +3 -2
- 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 +13 -4
- 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 +74 -0
- package/dist/workflow/set-attributes.d.ts.map +1 -0
- package/dist/workflow/set-attributes.js +66 -0
- package/dist/workflow/sleep.d.ts.map +1 -1
- package/dist/workflow/sleep.js +22 -3
- 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/writable-stream.js +1 -1
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +83 -31
- package/docs/api-reference/create-webhook.mdx +37 -18
- package/docs/api-reference/experimental-set-attributes.mdx +63 -0
- package/docs/api-reference/get-workflow-metadata.mdx +34 -0
- package/docs/api-reference/index.mdx +3 -0
- package/docs/foundations/cancellation.mdx +460 -0
- package/docs/foundations/errors-and-retries.mdx +7 -3
- package/docs/foundations/index.mdx +3 -3
- package/docs/foundations/meta.json +3 -2
- package/docs/foundations/serialization.mdx +78 -42
- package/docs/foundations/starting-workflows.mdx +6 -2
- package/docs/foundations/versioning.mdx +263 -0
- package/docs/how-it-works/cancellation.mdx +287 -0
- package/docs/how-it-works/code-transform.mdx +2 -2
- package/docs/how-it-works/event-sourcing.mdx +2 -2
- package/docs/how-it-works/meta.json +2 -1
- package/package.json +16 -7
- package/docs/foundations/common-patterns.mdx +0 -265
package/dist/serialization.js
CHANGED
|
@@ -1,161 +1,39 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE } from '@workflow/serde';
|
|
4
|
-
import { DevalueError, parse, stringify, unflatten } from 'devalue';
|
|
1
|
+
import { RuntimeDecryptionError, SerializationError, WorkflowRuntimeError, } from '@workflow/errors';
|
|
2
|
+
import { parse, stringify, unflatten } from 'devalue';
|
|
5
3
|
import { monotonicFactory } from 'ulid';
|
|
6
|
-
import {
|
|
7
|
-
import { decrypt as aesGcmDecrypt, encrypt as aesGcmEncrypt, } from './encryption.js';
|
|
4
|
+
import { decrypt as aesGcmDecrypt, encrypt as aesGcmEncrypt, importKey, } from './encryption.js';
|
|
8
5
|
import { createFlushableState, flushablePipe, pollReadableLock, pollWritableLock, } from './flushable-stream.js';
|
|
9
|
-
import { runtimeLogger } from './logger.js';
|
|
10
6
|
import { getStepFunction } from './private.js';
|
|
11
|
-
|
|
7
|
+
// V2: use getWorldLazy in step-side code paths so Turbopack can statically
|
|
8
|
+
// resolve the world bridge from the step bundle without dragging the full
|
|
9
|
+
// world.ts module (and its dynamic-import behaviour) into the flow route.
|
|
10
|
+
// See `packages/core/src/runtime/get-world-lazy.ts` and the
|
|
11
|
+
// "Turbopack NFT Tracing Errors in V2 Combined Flow Route" section of
|
|
12
|
+
// `docs/content/docs/changelog/eager-processing.mdx`.
|
|
13
|
+
import { getWorldLazy } from './runtime/get-world-lazy.js';
|
|
14
|
+
import * as clientModule from './serialization/client.js';
|
|
15
|
+
import { decrypt, encrypt, } from './serialization/encryption.js';
|
|
16
|
+
import { formatSerializationError, rethrowIfRuntimeError, } from './serialization/errors.js';
|
|
17
|
+
import { decodeFormatPrefix, encodeWithFormatPrefix, isEncrypted, peekFormatPrefix, } from './serialization/format.js';
|
|
18
|
+
import { getClassReducers, getClassRevivers, } from './serialization/reducers/class.js';
|
|
19
|
+
import { getCommonReducers, getCommonRevivers as getCommonReviversFromModule, revive, } from './serialization/reducers/common.js';
|
|
20
|
+
import { getStepFunctionReducer, getStepFunctionReviver, } from './serialization/reducers/step-function.js';
|
|
21
|
+
import * as stepModule from './serialization/step.js';
|
|
22
|
+
import { isFormatPrefix, SerializationFormat, } from './serialization/types.js';
|
|
23
|
+
import * as workflowModule from './serialization/workflow.js';
|
|
12
24
|
import { contextStorage } from './step/context-storage.js';
|
|
13
|
-
import { BODY_INIT_SYMBOL, STABLE_ULID, STREAM_NAME_SYMBOL, STREAM_TYPE_SYMBOL, WEBHOOK_RESPONSE_WRITABLE, } from './symbols.js';
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
// allows the client to determine how to decode the payload. This enables:
|
|
20
|
-
//
|
|
21
|
-
// 1. Self-describing payloads - The World layer is agnostic to serialization format
|
|
22
|
-
// 2. Gradual migration - Old runs keep working, new runs can use new formats
|
|
23
|
-
// 3. Composability - Encryption can wrap any format (e.g., "encr" wrapping "devl")
|
|
24
|
-
// 4. Debugging - Raw data inspection immediately reveals the format
|
|
25
|
-
//
|
|
26
|
-
// Format: [4 bytes: format identifier][payload]
|
|
27
|
-
//
|
|
28
|
-
// The 4-character prefix convention matches other workflow IDs (wrun, step, wait, etc.)
|
|
29
|
-
//
|
|
30
|
-
// Current formats:
|
|
31
|
-
// - "devl" - devalue stringify/parse with TextEncoder/TextDecoder (current default)
|
|
32
|
-
// - "encr" - Encrypted payload (inner payload has its own format prefix)
|
|
33
|
-
//
|
|
34
|
-
// Future formats (reserved):
|
|
35
|
-
// - "cbor" - CBOR binary serialization
|
|
36
|
-
/**
|
|
37
|
-
* Known serialization format identifiers.
|
|
38
|
-
* Each format ID is exactly 4 ASCII characters, matching the convention
|
|
39
|
-
* used for other workflow IDs (wrun, step, wait, etc.)
|
|
40
|
-
*/
|
|
41
|
-
export const SerializationFormat = {
|
|
42
|
-
/** devalue stringify/parse with TextEncoder/TextDecoder */
|
|
43
|
-
DEVALUE_V1: 'devl',
|
|
44
|
-
/** Encrypted payload (inner payload has its own format prefix) */
|
|
45
|
-
ENCRYPTED: 'encr',
|
|
46
|
-
};
|
|
47
|
-
/** Length of the format prefix in bytes */
|
|
48
|
-
const FORMAT_PREFIX_LENGTH = 4;
|
|
49
|
-
/** TextEncoder instance for format prefix encoding */
|
|
50
|
-
const formatEncoder = new TextEncoder();
|
|
51
|
-
/** TextDecoder instance for format prefix decoding */
|
|
52
|
-
const formatDecoder = new TextDecoder();
|
|
53
|
-
/**
|
|
54
|
-
* Encode a payload with a format prefix.
|
|
55
|
-
*
|
|
56
|
-
* @param format - The format identifier (must be exactly 4 ASCII characters)
|
|
57
|
-
* @param payload - The serialized payload bytes
|
|
58
|
-
* @returns A new Uint8Array with format prefix prepended
|
|
59
|
-
*/
|
|
60
|
-
export function encodeWithFormatPrefix(format, payload) {
|
|
61
|
-
if (!(payload instanceof Uint8Array)) {
|
|
62
|
-
return payload;
|
|
63
|
-
}
|
|
64
|
-
const prefixBytes = formatEncoder.encode(format);
|
|
65
|
-
if (prefixBytes.length !== FORMAT_PREFIX_LENGTH) {
|
|
66
|
-
throw new Error(`Format identifier must be exactly ${FORMAT_PREFIX_LENGTH} ASCII characters, got "${format}" (${prefixBytes.length} bytes)`);
|
|
67
|
-
}
|
|
68
|
-
const result = new Uint8Array(FORMAT_PREFIX_LENGTH + payload.length);
|
|
69
|
-
result.set(prefixBytes, 0);
|
|
70
|
-
result.set(payload, FORMAT_PREFIX_LENGTH);
|
|
71
|
-
return result;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Peek at the format prefix without consuming it.
|
|
75
|
-
* Useful for checking if data is encrypted before deciding how to process it.
|
|
76
|
-
*
|
|
77
|
-
* @param data - The format-prefixed data
|
|
78
|
-
* @returns The format identifier, or null if data is legacy/non-binary
|
|
79
|
-
*/
|
|
80
|
-
export function peekFormatPrefix(data) {
|
|
81
|
-
if (!(data instanceof Uint8Array) || data.length < FORMAT_PREFIX_LENGTH) {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
const prefixBytes = data.subarray(0, FORMAT_PREFIX_LENGTH);
|
|
85
|
-
const format = formatDecoder.decode(prefixBytes);
|
|
86
|
-
const knownFormats = Object.values(SerializationFormat);
|
|
87
|
-
if (!knownFormats.includes(format)) {
|
|
88
|
-
return null;
|
|
89
|
-
}
|
|
90
|
-
return format;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Check if data is encrypted (has 'encr' format prefix).
|
|
94
|
-
*
|
|
95
|
-
* @param data - The format-prefixed data
|
|
96
|
-
* @returns true if data has the encrypted format prefix
|
|
97
|
-
*/
|
|
98
|
-
export function isEncrypted(data) {
|
|
99
|
-
return peekFormatPrefix(data) === SerializationFormat.ENCRYPTED;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Decode a format-prefixed payload.
|
|
103
|
-
*
|
|
104
|
-
* @param data - The format-prefixed data
|
|
105
|
-
* @returns An object with the format identifier and payload
|
|
106
|
-
* @throws Error if the data is too short or has an unknown format
|
|
107
|
-
*/
|
|
108
|
-
export function decodeFormatPrefix(data) {
|
|
109
|
-
// Compat for legacy specVersion 1 runs that don't have a format prefix,
|
|
110
|
-
// and don't have a binary payload
|
|
111
|
-
if (!(data instanceof Uint8Array)) {
|
|
112
|
-
return {
|
|
113
|
-
format: SerializationFormat.DEVALUE_V1,
|
|
114
|
-
payload: new TextEncoder().encode(JSON.stringify(data)),
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
if (data.length < FORMAT_PREFIX_LENGTH) {
|
|
118
|
-
throw new Error(`Data too short to contain format prefix: expected at least ${FORMAT_PREFIX_LENGTH} bytes, got ${data.length}`);
|
|
119
|
-
}
|
|
120
|
-
const prefixBytes = data.subarray(0, FORMAT_PREFIX_LENGTH);
|
|
121
|
-
const format = formatDecoder.decode(prefixBytes);
|
|
122
|
-
// Validate the format is known
|
|
123
|
-
const knownFormats = Object.values(SerializationFormat);
|
|
124
|
-
if (!knownFormats.includes(format)) {
|
|
125
|
-
throw new WorkflowRuntimeError(`Unknown serialization format: "${format}". Known formats: ${knownFormats.join(', ')}`);
|
|
126
|
-
}
|
|
127
|
-
const payload = data.subarray(FORMAT_PREFIX_LENGTH);
|
|
128
|
-
return { format: format, payload };
|
|
129
|
-
}
|
|
25
|
+
import { ABORT_HOOK_TOKEN, ABORT_LISTENER_ATTACHED, ABORT_READER_CANCEL, ABORT_STREAM_NAME, BODY_INIT_SYMBOL, STABLE_ULID, STREAM_NAME_SYMBOL, STREAM_SERVER_RUN_ID_SYMBOL, STREAM_TYPE_SYMBOL, WEBHOOK_RESPONSE_WRITABLE, } from './symbols.js';
|
|
26
|
+
import { getAbortStreamId } from './util.js';
|
|
27
|
+
import { WorkflowAbortSignal } from './workflow/abort-controller.js';
|
|
28
|
+
// Re-export types and utilities from the modular serialization modules
|
|
29
|
+
// so existing consumers of `@workflow/core/serialization` keep working.
|
|
30
|
+
export { SerializationFormat, isFormatPrefix, encodeWithFormatPrefix, decodeFormatPrefix, peekFormatPrefix, isEncrypted, encrypt, decrypt, };
|
|
130
31
|
/**
|
|
131
32
|
* Default ULID generator for contexts where VM's seeded `stableUlid` isn't available.
|
|
132
33
|
* Used as a fallback when serializing streams outside the workflow VM context
|
|
133
34
|
* (e.g., when starting a workflow or handling step return values).
|
|
134
35
|
*/
|
|
135
36
|
const defaultUlid = monotonicFactory();
|
|
136
|
-
/**
|
|
137
|
-
* Format a serialization error with context about what failed.
|
|
138
|
-
* Extracts path, value, and reason from devalue's DevalueError when available.
|
|
139
|
-
* Logs the problematic value to the console for better debugging.
|
|
140
|
-
*/
|
|
141
|
-
function formatSerializationError(context, error) {
|
|
142
|
-
// Use "returning" for return values, "passing" for arguments/inputs
|
|
143
|
-
const verb = context.includes('return value') ? 'returning' : 'passing';
|
|
144
|
-
// Build the error message with path info if available from DevalueError
|
|
145
|
-
let message = `Failed to serialize ${context}`;
|
|
146
|
-
if (error instanceof DevalueError && error.path) {
|
|
147
|
-
message += ` at path "${error.path}"`;
|
|
148
|
-
}
|
|
149
|
-
message += `. Ensure you're ${verb} serializable types (plain objects, arrays, primitives, Date, RegExp, Map, Set).`;
|
|
150
|
-
// Log the problematic value for debugging
|
|
151
|
-
if (error instanceof DevalueError && error.value !== undefined) {
|
|
152
|
-
runtimeLogger.error('Serialization failed', {
|
|
153
|
-
context,
|
|
154
|
-
problematicValue: error.value,
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
return message;
|
|
158
|
-
}
|
|
159
37
|
/**
|
|
160
38
|
* Detect if a readable stream is a byte stream.
|
|
161
39
|
*
|
|
@@ -179,6 +57,33 @@ export function getStreamType(stream) {
|
|
|
179
57
|
* split across transport reads.
|
|
180
58
|
*/
|
|
181
59
|
const FRAME_HEADER_SIZE = 4;
|
|
60
|
+
/**
|
|
61
|
+
* The mode-specific serializers (`./serialization/{client,step,workflow}.ts`)
|
|
62
|
+
* already throw a `SerializationError` whose `.cause` is the underlying
|
|
63
|
+
* devalue / serde failure. The outer dehydrate/hydrate wrappers want to
|
|
64
|
+
* re-frame that error with a more specific context label (e.g. "workflow
|
|
65
|
+
* arguments" instead of generic "workflow value"), so they unwrap the
|
|
66
|
+
* inner SerializationError and reformat with the original cause. Errors
|
|
67
|
+
* that aren't already SerializationError flow through unchanged.
|
|
68
|
+
*
|
|
69
|
+
* `RuntimeDecryptionError` is an exception: it must keep its identity (and
|
|
70
|
+
* `context`) so the run-failure classifier routes it to `RUNTIME_ERROR`,
|
|
71
|
+
* so this rethrows it unchanged before any unwrapping. Note this guard
|
|
72
|
+
* must run before the generic `WorkflowRuntimeError` unwrap below, since
|
|
73
|
+
* `RuntimeDecryptionError` extends `WorkflowRuntimeError` and carries a
|
|
74
|
+
* `cause` (the underlying DOMException) that would otherwise be unwrapped
|
|
75
|
+
* and reframed as a `SerializationError`.
|
|
76
|
+
*/
|
|
77
|
+
function unwrapSerializationCause(error) {
|
|
78
|
+
rethrowIfRuntimeError(error);
|
|
79
|
+
if (error instanceof SerializationError && error.cause !== undefined) {
|
|
80
|
+
return error.cause;
|
|
81
|
+
}
|
|
82
|
+
if (error instanceof WorkflowRuntimeError && error.cause !== undefined) {
|
|
83
|
+
return error.cause;
|
|
84
|
+
}
|
|
85
|
+
return error;
|
|
86
|
+
}
|
|
182
87
|
export function getSerializeStream(reducers, cryptoKey) {
|
|
183
88
|
const encoder = new TextEncoder();
|
|
184
89
|
// Resolve the key promise once on first use and cache the result.
|
|
@@ -210,7 +115,15 @@ export function getSerializeStream(reducers, cryptoKey) {
|
|
|
210
115
|
controller.enqueue(frame);
|
|
211
116
|
}
|
|
212
117
|
catch (error) {
|
|
213
|
-
|
|
118
|
+
// Encryption failures must keep their RuntimeDecryptionError
|
|
119
|
+
// identity (RUNTIME_ERROR) rather than be reframed as a
|
|
120
|
+
// SerializationError (USER_ERROR).
|
|
121
|
+
if (RuntimeDecryptionError.is(error)) {
|
|
122
|
+
controller.error(error);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const { message, hint } = formatSerializationError('stream chunk', error);
|
|
126
|
+
controller.error(new SerializationError(message, { hint, cause: error }));
|
|
214
127
|
}
|
|
215
128
|
},
|
|
216
129
|
});
|
|
@@ -247,11 +160,30 @@ export function getDeserializeStream(revivers, cryptoKey) {
|
|
|
247
160
|
// then fall through to the normal deserialization path.
|
|
248
161
|
if (format === SerializationFormat.ENCRYPTED) {
|
|
249
162
|
if (!keyState.key) {
|
|
250
|
-
controller.error(new
|
|
251
|
-
'Encryption is not configured or no key was provided for this run.'
|
|
163
|
+
controller.error(new RuntimeDecryptionError('Encrypted stream data encountered but no encryption key is available. ' +
|
|
164
|
+
'Encryption is not configured or no key was provided for this run.', {
|
|
165
|
+
context: {
|
|
166
|
+
operation: 'decrypt',
|
|
167
|
+
byteLength: payload.byteLength,
|
|
168
|
+
formatPrefix: 'encr',
|
|
169
|
+
},
|
|
170
|
+
}));
|
|
252
171
|
return;
|
|
253
172
|
}
|
|
254
|
-
|
|
173
|
+
let decrypted;
|
|
174
|
+
try {
|
|
175
|
+
decrypted = await aesGcmDecrypt(keyState.key, payload);
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
// The low-level AES layer only sees the stripped payload, so it
|
|
179
|
+
// cannot record the outer envelope prefix. We peeked it here
|
|
180
|
+
// (`encr`), so enrich the diagnostic context with the real format
|
|
181
|
+
// prefix before propagating — mirroring serialization/encryption.ts.
|
|
182
|
+
if (RuntimeDecryptionError.is(error) && error.context) {
|
|
183
|
+
error.context.formatPrefix = format;
|
|
184
|
+
}
|
|
185
|
+
throw error;
|
|
186
|
+
}
|
|
255
187
|
({ format, payload } = decodeFormatPrefix(decrypted));
|
|
256
188
|
}
|
|
257
189
|
if (format === SerializationFormat.DEVALUE_V1) {
|
|
@@ -303,7 +235,7 @@ export class WorkflowServerReadableStream extends ReadableStream {
|
|
|
303
235
|
#reader;
|
|
304
236
|
constructor(runId, name, startIndex) {
|
|
305
237
|
if (typeof name !== 'string' || name.length === 0) {
|
|
306
|
-
throw new
|
|
238
|
+
throw new WorkflowRuntimeError(`"name" is required, got "${name}"`);
|
|
307
239
|
}
|
|
308
240
|
super({
|
|
309
241
|
// @ts-expect-error Not sure why TypeScript is complaining about this
|
|
@@ -311,7 +243,7 @@ export class WorkflowServerReadableStream extends ReadableStream {
|
|
|
311
243
|
pull: async (controller) => {
|
|
312
244
|
let reader = this.#reader;
|
|
313
245
|
if (!reader) {
|
|
314
|
-
const world = await
|
|
246
|
+
const world = await getWorldLazy();
|
|
315
247
|
const stream = await world.streams.get(runId, name, startIndex);
|
|
316
248
|
reader = this.#reader = stream.getReader();
|
|
317
249
|
}
|
|
@@ -347,12 +279,12 @@ const STREAM_FLUSH_INTERVAL_MS = 10;
|
|
|
347
279
|
export class WorkflowServerWritableStream extends WritableStream {
|
|
348
280
|
constructor(runId, name) {
|
|
349
281
|
if (typeof runId !== 'string') {
|
|
350
|
-
throw new
|
|
282
|
+
throw new WorkflowRuntimeError(`"runId" must be a string, got "${typeof runId}"`);
|
|
351
283
|
}
|
|
352
284
|
if (typeof name !== 'string' || name.length === 0) {
|
|
353
|
-
throw new
|
|
285
|
+
throw new WorkflowRuntimeError(`"name" is required, got "${name}"`);
|
|
354
286
|
}
|
|
355
|
-
const worldPromise =
|
|
287
|
+
const worldPromise = getWorldLazy();
|
|
356
288
|
// Buffering state for batched writes
|
|
357
289
|
// Encryption/decryption is handled at the framing level by
|
|
358
290
|
// getSerializeStream/getDeserializeStream, not here.
|
|
@@ -457,113 +389,22 @@ export class WorkflowServerWritableStream extends WritableStream {
|
|
|
457
389
|
});
|
|
458
390
|
}
|
|
459
391
|
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
function
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
// Create a proper copy to avoid ArrayBuffer detachment issues
|
|
471
|
-
// Buffer.from(ArrayBuffer, offset, length) creates a view, not a copy
|
|
472
|
-
const uint8 = new Uint8Array(value, offset, length);
|
|
473
|
-
return Buffer.from(uint8).toString('base64');
|
|
474
|
-
};
|
|
475
|
-
const viewToBase64 = (value) => abToBase64(value.buffer, value.byteOffset, value.byteLength);
|
|
392
|
+
// ---- Composed reducers ----
|
|
393
|
+
// Composes modular reducers (common, class, step-function) with
|
|
394
|
+
// mode-specific Request/Response/Stream reducers below.
|
|
395
|
+
/**
|
|
396
|
+
* Base reducers shared across all serialization boundaries.
|
|
397
|
+
* Composes: class + step-function + common reducers from the modular modules.
|
|
398
|
+
*/
|
|
399
|
+
function getAllBaseReducers(global = globalThis) {
|
|
400
|
+
// Class/Instance MUST come before Error so that custom Error subclasses
|
|
401
|
+
// with WORKFLOW_SERIALIZE take precedence (devalue uses first-match-wins).
|
|
476
402
|
return {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
// Class and Instance are intentionally placed before Error so that
|
|
483
|
-
// custom Error subclasses with WORKFLOW_SERIALIZE take precedence
|
|
484
|
-
// over the generic Error serialization (devalue uses first-match-wins).
|
|
485
|
-
Class: (value) => {
|
|
486
|
-
// Check if this is a class constructor with a classId property
|
|
487
|
-
// (set by the SWC plugin for classes with static step/workflow methods)
|
|
488
|
-
if (typeof value !== 'function')
|
|
489
|
-
return false;
|
|
490
|
-
const classId = value.classId;
|
|
491
|
-
if (typeof classId !== 'string')
|
|
492
|
-
return false;
|
|
493
|
-
return { classId };
|
|
494
|
-
},
|
|
495
|
-
Instance: (value) => {
|
|
496
|
-
// Check if this is an instance of a class with custom serialization
|
|
497
|
-
if (value === null || typeof value !== 'object')
|
|
498
|
-
return false;
|
|
499
|
-
const cls = value.constructor;
|
|
500
|
-
if (!cls || typeof cls !== 'function')
|
|
501
|
-
return false;
|
|
502
|
-
// Check if the class has a static WORKFLOW_SERIALIZE method
|
|
503
|
-
const serialize = cls[WORKFLOW_SERIALIZE];
|
|
504
|
-
if (typeof serialize !== 'function') {
|
|
505
|
-
return false;
|
|
506
|
-
}
|
|
507
|
-
// Get the classId from the static class property (set by SWC plugin)
|
|
508
|
-
const classId = cls.classId;
|
|
509
|
-
if (typeof classId !== 'string') {
|
|
510
|
-
throw new Error(`Class "${cls.name}" with ${String(WORKFLOW_SERIALIZE)} must have a static "classId" property.`);
|
|
511
|
-
}
|
|
512
|
-
// Serialize the instance using the custom serializer
|
|
513
|
-
const data = serialize.call(cls, value);
|
|
514
|
-
return { classId, data };
|
|
515
|
-
},
|
|
516
|
-
Date: (value) => {
|
|
517
|
-
if (!(value instanceof global.Date))
|
|
518
|
-
return false;
|
|
519
|
-
const valid = !Number.isNaN(value.getDate());
|
|
520
|
-
// Note: "." is to avoid returning a falsy value when the date is invalid
|
|
521
|
-
return valid ? value.toISOString() : '.';
|
|
522
|
-
},
|
|
523
|
-
// DOMException is a special case: in Node.js it passes isNativeError()
|
|
524
|
-
// and instanceof Error, but has a unique constructor signature
|
|
525
|
-
// (message, name) and a read-only numeric `code` property derived from
|
|
526
|
-
// `name`. It must be checked before the generic Error reducer.
|
|
527
|
-
DOMException: (value) => {
|
|
528
|
-
if (!types.isNativeError(value))
|
|
529
|
-
return false;
|
|
530
|
-
if (value.constructor?.name !== 'DOMException')
|
|
531
|
-
return false;
|
|
532
|
-
const reduced = {
|
|
533
|
-
message: value.message,
|
|
534
|
-
name: value.name,
|
|
535
|
-
stack: value.stack,
|
|
536
|
-
};
|
|
537
|
-
if ('cause' in value)
|
|
538
|
-
reduced.cause = value.cause;
|
|
539
|
-
return reduced;
|
|
540
|
-
},
|
|
541
|
-
Error: (value) => {
|
|
542
|
-
// Use types.isNativeError() instead of `instanceof global.Error`
|
|
543
|
-
// because errors may originate from a different VM context (e.g.
|
|
544
|
-
// FatalError from the host context passed into a VM-context workflow).
|
|
545
|
-
// `instanceof` checks fail across VM boundaries since each context
|
|
546
|
-
// has its own Error constructor, but isNativeError() uses V8's
|
|
547
|
-
// internal type tag which works across all contexts.
|
|
548
|
-
if (!types.isNativeError(value))
|
|
549
|
-
return false;
|
|
550
|
-
return {
|
|
551
|
-
name: value.name,
|
|
552
|
-
message: value.message,
|
|
553
|
-
stack: value.stack,
|
|
554
|
-
};
|
|
555
|
-
},
|
|
556
|
-
Float32Array: (value) => value instanceof global.Float32Array && viewToBase64(value),
|
|
557
|
-
Float64Array: (value) => value instanceof global.Float64Array && viewToBase64(value),
|
|
558
|
-
Headers: (value) => value instanceof global.Headers && Array.from(value),
|
|
559
|
-
Int8Array: (value) => value instanceof global.Int8Array && viewToBase64(value),
|
|
560
|
-
Int16Array: (value) => value instanceof global.Int16Array && viewToBase64(value),
|
|
561
|
-
Int32Array: (value) => value instanceof global.Int32Array && viewToBase64(value),
|
|
562
|
-
Map: (value) => value instanceof global.Map && Array.from(value),
|
|
563
|
-
RegExp: (value) => value instanceof global.RegExp && {
|
|
564
|
-
source: value.source,
|
|
565
|
-
flags: value.flags,
|
|
566
|
-
},
|
|
403
|
+
...getClassReducers(),
|
|
404
|
+
...getStepFunctionReducer(),
|
|
405
|
+
...getCommonReducers(global),
|
|
406
|
+
// Request and Response reducers are mode-specific and added by
|
|
407
|
+
// getExternalReducers / getWorkflowReducers / getStepReducers below.
|
|
567
408
|
Request: (value) => {
|
|
568
409
|
if (!(value instanceof global.Request))
|
|
569
410
|
return false;
|
|
@@ -578,6 +419,20 @@ function getCommonReducers(global = globalThis) {
|
|
|
578
419
|
if (responseWritable) {
|
|
579
420
|
data.responseWritable = responseWritable;
|
|
580
421
|
}
|
|
422
|
+
// Forward the signal in two cases:
|
|
423
|
+
// 1. Already aborted — preserve aborted=true/reason so the hydrated
|
|
424
|
+
// step sees the cancellation that happened before serialize.
|
|
425
|
+
// 2. Already tagged with workflow infrastructure — i.e. a signal
|
|
426
|
+
// from a workflow-managed AbortController, which has stream/hook
|
|
427
|
+
// backing for cross-boundary propagation.
|
|
428
|
+
// Plain non-aborted native signals are intentionally dropped (would
|
|
429
|
+
// mint stream infra for every Request, including the auto-generated
|
|
430
|
+
// signal on `new Request(url)`).
|
|
431
|
+
if (value.signal &&
|
|
432
|
+
(value.signal.aborted ||
|
|
433
|
+
value.signal[ABORT_STREAM_NAME])) {
|
|
434
|
+
data.signal = value.signal;
|
|
435
|
+
}
|
|
581
436
|
return data;
|
|
582
437
|
},
|
|
583
438
|
Response: (value) => {
|
|
@@ -593,50 +448,89 @@ function getCommonReducers(global = globalThis) {
|
|
|
593
448
|
redirected: value.redirected,
|
|
594
449
|
};
|
|
595
450
|
},
|
|
596
|
-
Set: (value) => value instanceof global.Set && Array.from(value),
|
|
597
|
-
StepFunction: (value) => {
|
|
598
|
-
if (typeof value !== 'function')
|
|
599
|
-
return false;
|
|
600
|
-
const stepId = value.stepId;
|
|
601
|
-
if (typeof stepId !== 'string')
|
|
602
|
-
return false;
|
|
603
|
-
// Check if the step function has closure variables
|
|
604
|
-
const closureVarsFn = value.__closureVarsFn;
|
|
605
|
-
if (closureVarsFn && typeof closureVarsFn === 'function') {
|
|
606
|
-
// Invoke the closure variables function and serialize along with stepId
|
|
607
|
-
const closureVars = closureVarsFn();
|
|
608
|
-
return { stepId, closureVars };
|
|
609
|
-
}
|
|
610
|
-
// No closure variables - return object with just stepId
|
|
611
|
-
return { stepId };
|
|
612
|
-
},
|
|
613
|
-
URL: (value) => value instanceof global.URL && value.href,
|
|
614
|
-
WorkflowFunction: (value) => {
|
|
615
|
-
// Only match function references with a workflowId property (set by
|
|
616
|
-
// the SWC compiler on workflow functions). Plain { workflowId } objects
|
|
617
|
-
// are NOT matched — this prevents infinite recursion since the reduced
|
|
618
|
-
// form { workflowId } is a plain object, not a function.
|
|
619
|
-
if (typeof value !== 'function')
|
|
620
|
-
return false;
|
|
621
|
-
const workflowId = value.workflowId;
|
|
622
|
-
if (typeof workflowId !== 'string')
|
|
623
|
-
return false;
|
|
624
|
-
return { workflowId };
|
|
625
|
-
},
|
|
626
|
-
URLSearchParams: (value) => {
|
|
627
|
-
if (!(value instanceof global.URLSearchParams))
|
|
628
|
-
return false;
|
|
629
|
-
// Avoid returning a falsy value when the URLSearchParams is empty
|
|
630
|
-
if (value.size === 0)
|
|
631
|
-
return '.';
|
|
632
|
-
return String(value);
|
|
633
|
-
},
|
|
634
|
-
Uint8Array: (value) => value instanceof global.Uint8Array && viewToBase64(value),
|
|
635
|
-
Uint8ClampedArray: (value) => value instanceof global.Uint8ClampedArray && viewToBase64(value),
|
|
636
|
-
Uint16Array: (value) => value instanceof global.Uint16Array && viewToBase64(value),
|
|
637
|
-
Uint32Array: (value) => value instanceof global.Uint32Array && viewToBase64(value),
|
|
638
451
|
};
|
|
639
452
|
}
|
|
453
|
+
/**
|
|
454
|
+
* Shared logic for AbortController/AbortSignal reducers in external and step
|
|
455
|
+
* contexts. Assigns stream/hook names if not already present, optionally
|
|
456
|
+
* attaches an abort listener for real-time propagation, and returns the
|
|
457
|
+
* serialized representation.
|
|
458
|
+
*/
|
|
459
|
+
function reduceAbortWithListener(signal, holder, global, ops, runId, cryptoKey) {
|
|
460
|
+
let streamName = holder[ABORT_STREAM_NAME];
|
|
461
|
+
let hookToken = holder[ABORT_HOOK_TOKEN];
|
|
462
|
+
if (!streamName) {
|
|
463
|
+
const id = (global[STABLE_ULID] || defaultUlid)();
|
|
464
|
+
streamName = getAbortStreamId(id);
|
|
465
|
+
hookToken = `abrt_${id}`;
|
|
466
|
+
holder[ABORT_STREAM_NAME] = streamName;
|
|
467
|
+
holder[ABORT_HOOK_TOKEN] = hookToken;
|
|
468
|
+
if (holder.signal) {
|
|
469
|
+
holder.signal[ABORT_STREAM_NAME] = streamName;
|
|
470
|
+
holder.signal[ABORT_HOOK_TOKEN] = hookToken;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
// Deduped via ABORT_LISTENER_ATTACHED marker — see attachAbortListenerOnce.
|
|
474
|
+
attachAbortListenerOnce(signal, streamName, runId, cryptoKey, ops);
|
|
475
|
+
return {
|
|
476
|
+
streamName,
|
|
477
|
+
hookToken: hookToken,
|
|
478
|
+
aborted: signal.aborted,
|
|
479
|
+
reason: signal.aborted ? signal.reason : undefined,
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Shared logic for AbortController/AbortSignal reducers in workflow context.
|
|
484
|
+
* Reads existing stream/hook names from symbols (must already be set).
|
|
485
|
+
*/
|
|
486
|
+
function reduceAbortBySymbol(signal, holder) {
|
|
487
|
+
const streamName = holder[ABORT_STREAM_NAME] ?? holder.signal?.[ABORT_STREAM_NAME];
|
|
488
|
+
const hookToken = holder[ABORT_HOOK_TOKEN] ?? holder.signal?.[ABORT_HOOK_TOKEN];
|
|
489
|
+
if (!streamName) {
|
|
490
|
+
throw new Error('AbortController/AbortSignal stream name is not set');
|
|
491
|
+
}
|
|
492
|
+
return {
|
|
493
|
+
streamName,
|
|
494
|
+
hookToken: hookToken,
|
|
495
|
+
aborted: signal.aborted,
|
|
496
|
+
reason: signal.aborted ? signal.reason : undefined,
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Attach a single abort listener to a signal, deduped across calls.
|
|
501
|
+
*
|
|
502
|
+
* Each serialization pass goes through the reducer, but a controller passed
|
|
503
|
+
* to N steps would otherwise accumulate N listeners — each writing the same
|
|
504
|
+
* stream packet and double-closing the stream on abort. The marker symbol
|
|
505
|
+
* ensures the stream-write side-effect runs at most once per (signal, runId).
|
|
506
|
+
*/
|
|
507
|
+
function attachAbortListenerOnce(signal, streamName, runId, cryptoKey, ops) {
|
|
508
|
+
if (signal.aborted)
|
|
509
|
+
return;
|
|
510
|
+
if (signal[ABORT_LISTENER_ATTACHED])
|
|
511
|
+
return;
|
|
512
|
+
signal[ABORT_LISTENER_ATTACHED] = true;
|
|
513
|
+
signal.addEventListener('abort', () => {
|
|
514
|
+
ops.push((async () => {
|
|
515
|
+
try {
|
|
516
|
+
// Dehydrate via the same machinery the reader uses (hydrateStepArguments)
|
|
517
|
+
// so the reason round-trips with full type fidelity (DOMException,
|
|
518
|
+
// Errors, custom classes, etc.) and respects the run's encryption key.
|
|
519
|
+
// A bare JSON.stringify here would write a packet the reader can't
|
|
520
|
+
// decode and the listener-side abort would propagate with no reason.
|
|
521
|
+
const key = await cryptoKey;
|
|
522
|
+
const payload = await dehydrateStepArguments({ aborted: true, reason: signal.reason }, runId, key);
|
|
523
|
+
const writable = new WorkflowServerWritableStream(runId, streamName);
|
|
524
|
+
const writer = writable.getWriter();
|
|
525
|
+
await writer.write(payload);
|
|
526
|
+
await writer.close();
|
|
527
|
+
}
|
|
528
|
+
catch {
|
|
529
|
+
// Best-effort stream write
|
|
530
|
+
}
|
|
531
|
+
})());
|
|
532
|
+
}, { once: true });
|
|
533
|
+
}
|
|
640
534
|
/**
|
|
641
535
|
* Reducers for serialization boundary from the client side, passing arguments
|
|
642
536
|
* to the workflow handler.
|
|
@@ -647,13 +541,15 @@ function getCommonReducers(global = globalThis) {
|
|
|
647
541
|
*/
|
|
648
542
|
export function getExternalReducers(global = globalThis, ops, runId, cryptoKey) {
|
|
649
543
|
return {
|
|
650
|
-
...
|
|
544
|
+
...getAllBaseReducers(global),
|
|
651
545
|
ReadableStream: (value) => {
|
|
652
546
|
if (!(value instanceof global.ReadableStream))
|
|
653
547
|
return false;
|
|
654
548
|
// Stream must not be locked when passing across execution boundary
|
|
655
549
|
if (value.locked) {
|
|
656
|
-
throw new
|
|
550
|
+
throw new SerializationError('ReadableStream is locked and cannot be passed across a workflow boundary.', {
|
|
551
|
+
hint: 'Pass the stream before calling .getReader() / .pipeThrough() / .pipeTo(), or tee it with .tee() and pass one of the branches.',
|
|
552
|
+
});
|
|
657
553
|
}
|
|
658
554
|
const streamId = (global[STABLE_ULID] || defaultUlid)();
|
|
659
555
|
const name = `strm_${streamId}`;
|
|
@@ -675,12 +571,41 @@ export function getExternalReducers(global = globalThis, ops, runId, cryptoKey)
|
|
|
675
571
|
WritableStream: (value) => {
|
|
676
572
|
if (!(value instanceof global.WritableStream))
|
|
677
573
|
return false;
|
|
574
|
+
// Fast path: when the writable is already backed by a workflow
|
|
575
|
+
// server stream (e.g. it came from a step-context `getWritable()`
|
|
576
|
+
// or was hydrated from a workflow input by `getStepRevivers`),
|
|
577
|
+
// forward its underlying `(runId, name)` to the receiving run.
|
|
578
|
+
// The receiving run's step-side reviver opens a server writable
|
|
579
|
+
// against the original `(runId, name)` and resolves that run's
|
|
580
|
+
// encryption key directly, so writes land on the original stream
|
|
581
|
+
// for the full lifetime of the receiving run — no in-process
|
|
582
|
+
// bridge tied to the dehydrating step's lifetime.
|
|
583
|
+
const existingName = value[STREAM_NAME_SYMBOL];
|
|
584
|
+
const existingRunId = value[STREAM_SERVER_RUN_ID_SYMBOL];
|
|
585
|
+
if (typeof existingName === 'string' &&
|
|
586
|
+
typeof existingRunId === 'string') {
|
|
587
|
+
return { name: existingName, runId: existingRunId };
|
|
588
|
+
}
|
|
678
589
|
const streamId = (global[STABLE_ULID] || defaultUlid)();
|
|
679
590
|
const name = `strm_${streamId}`;
|
|
680
591
|
const readable = new WorkflowServerReadableStream(runId, name);
|
|
681
592
|
ops.push(readable.pipeTo(value));
|
|
682
593
|
return { name };
|
|
683
594
|
},
|
|
595
|
+
AbortController: (value) => {
|
|
596
|
+
if (!global.AbortController ||
|
|
597
|
+
typeof global.AbortController !== 'function' ||
|
|
598
|
+
!(value instanceof global.AbortController))
|
|
599
|
+
return false;
|
|
600
|
+
return reduceAbortWithListener(value.signal, value, global, ops, runId, cryptoKey);
|
|
601
|
+
},
|
|
602
|
+
AbortSignal: (value) => {
|
|
603
|
+
if (!global.AbortSignal ||
|
|
604
|
+
typeof global.AbortSignal !== 'function' ||
|
|
605
|
+
!(value instanceof global.AbortSignal))
|
|
606
|
+
return false;
|
|
607
|
+
return reduceAbortWithListener(value, value, global, ops, runId, cryptoKey);
|
|
608
|
+
},
|
|
684
609
|
};
|
|
685
610
|
}
|
|
686
611
|
/**
|
|
@@ -692,7 +617,7 @@ export function getExternalReducers(global = globalThis, ops, runId, cryptoKey)
|
|
|
692
617
|
*/
|
|
693
618
|
export function getWorkflowReducers(global = globalThis) {
|
|
694
619
|
return {
|
|
695
|
-
...
|
|
620
|
+
...getAllBaseReducers(global),
|
|
696
621
|
// Readable/Writable streams from within the workflow execution environment
|
|
697
622
|
// are simply "handles" that can be passed around to other steps.
|
|
698
623
|
ReadableStream: (value) => {
|
|
@@ -707,7 +632,7 @@ export function getWorkflowReducers(global = globalThis) {
|
|
|
707
632
|
}
|
|
708
633
|
const name = value[STREAM_NAME_SYMBOL];
|
|
709
634
|
if (!name) {
|
|
710
|
-
throw new
|
|
635
|
+
throw new WorkflowRuntimeError('ReadableStream `name` is not set');
|
|
711
636
|
}
|
|
712
637
|
const s = { name };
|
|
713
638
|
const type = value[STREAM_TYPE_SYMBOL];
|
|
@@ -720,9 +645,42 @@ export function getWorkflowReducers(global = globalThis) {
|
|
|
720
645
|
return false;
|
|
721
646
|
const name = value[STREAM_NAME_SYMBOL];
|
|
722
647
|
if (!name) {
|
|
723
|
-
throw new
|
|
648
|
+
throw new WorkflowRuntimeError('WritableStream `name` is not set');
|
|
724
649
|
}
|
|
725
|
-
|
|
650
|
+
const s = { name };
|
|
651
|
+
// When the handle was forwarded from another run (parent → child
|
|
652
|
+
// via `start()`), preserve the foreign runId so the step-side
|
|
653
|
+
// reviver opens the writable against the original stream.
|
|
654
|
+
const foreignRunId = value[STREAM_SERVER_RUN_ID_SYMBOL];
|
|
655
|
+
if (typeof foreignRunId === 'string')
|
|
656
|
+
s.runId = foreignRunId;
|
|
657
|
+
return s;
|
|
658
|
+
},
|
|
659
|
+
// AbortController/AbortSignal in workflow context — just read symbols (handles).
|
|
660
|
+
// In the workflow VM, global.AbortController is a class but global.AbortSignal
|
|
661
|
+
// is a plain object (not a class), so instanceof checks won't work for signals.
|
|
662
|
+
// Detect instances by the presence of the ABORT_STREAM_NAME symbol instead.
|
|
663
|
+
AbortController: (value) => {
|
|
664
|
+
if (!value || !value.signal)
|
|
665
|
+
return false;
|
|
666
|
+
const holder = value;
|
|
667
|
+
const hasAbortSymbol = holder[ABORT_STREAM_NAME] ?? holder.signal?.[ABORT_STREAM_NAME];
|
|
668
|
+
const isNativeAbortController = global.AbortController &&
|
|
669
|
+
typeof global.AbortController === 'function' &&
|
|
670
|
+
value instanceof global.AbortController;
|
|
671
|
+
if (!hasAbortSymbol && !isNativeAbortController)
|
|
672
|
+
return false;
|
|
673
|
+
return reduceAbortBySymbol(value.signal, holder);
|
|
674
|
+
},
|
|
675
|
+
AbortSignal: (value) => {
|
|
676
|
+
const signal = value;
|
|
677
|
+
const hasAbortSymbol = signal?.[ABORT_STREAM_NAME];
|
|
678
|
+
const isNativeAbortSignal = global.AbortSignal &&
|
|
679
|
+
typeof global.AbortSignal === 'function' &&
|
|
680
|
+
value instanceof global.AbortSignal;
|
|
681
|
+
if (!hasAbortSymbol && !isNativeAbortSignal)
|
|
682
|
+
return false;
|
|
683
|
+
return reduceAbortBySymbol(value, value);
|
|
726
684
|
},
|
|
727
685
|
};
|
|
728
686
|
}
|
|
@@ -737,13 +695,15 @@ export function getWorkflowReducers(global = globalThis) {
|
|
|
737
695
|
*/
|
|
738
696
|
function getStepReducers(global = globalThis, ops, runId, cryptoKey) {
|
|
739
697
|
return {
|
|
740
|
-
...
|
|
698
|
+
...getAllBaseReducers(global),
|
|
741
699
|
ReadableStream: (value) => {
|
|
742
700
|
if (!(value instanceof global.ReadableStream))
|
|
743
701
|
return false;
|
|
744
702
|
// Stream must not be locked when passing across execution boundary
|
|
745
703
|
if (value.locked) {
|
|
746
|
-
throw new
|
|
704
|
+
throw new SerializationError('ReadableStream is locked and cannot be passed across a workflow boundary.', {
|
|
705
|
+
hint: 'Pass the stream before calling .getReader() / .pipeThrough() / .pipeTo(), or tee it with .tee() and pass one of the branches.',
|
|
706
|
+
});
|
|
747
707
|
}
|
|
748
708
|
// Check if the stream already has the name symbol set, in which case
|
|
749
709
|
// it's already being sunk to the server and we can just return the
|
|
@@ -773,6 +733,7 @@ function getStepReducers(global = globalThis, ops, runId, cryptoKey) {
|
|
|
773
733
|
if (!(value instanceof global.WritableStream))
|
|
774
734
|
return false;
|
|
775
735
|
let name = value[STREAM_NAME_SYMBOL];
|
|
736
|
+
const foreignRunId = value[STREAM_SERVER_RUN_ID_SYMBOL];
|
|
776
737
|
if (!name) {
|
|
777
738
|
const streamId = (global[STABLE_ULID] || defaultUlid)();
|
|
778
739
|
name = `strm_${streamId}`;
|
|
@@ -780,118 +741,257 @@ function getStepReducers(global = globalThis, ops, runId, cryptoKey) {
|
|
|
780
741
|
.pipeThrough(getDeserializeStream(getStepRevivers(global, ops, runId, cryptoKey), cryptoKey))
|
|
781
742
|
.pipeTo(value));
|
|
782
743
|
}
|
|
783
|
-
|
|
744
|
+
const s = { name };
|
|
745
|
+
if (typeof foreignRunId === 'string')
|
|
746
|
+
s.runId = foreignRunId;
|
|
747
|
+
return s;
|
|
748
|
+
},
|
|
749
|
+
AbortController: (value) => {
|
|
750
|
+
if (!global.AbortController ||
|
|
751
|
+
typeof global.AbortController !== 'function' ||
|
|
752
|
+
!(value instanceof global.AbortController))
|
|
753
|
+
return false;
|
|
754
|
+
return reduceAbortWithListener(value.signal, value, global, ops, runId, cryptoKey);
|
|
755
|
+
},
|
|
756
|
+
AbortSignal: (value) => {
|
|
757
|
+
if (!global.AbortSignal ||
|
|
758
|
+
typeof global.AbortSignal !== 'function' ||
|
|
759
|
+
!(value instanceof global.AbortSignal))
|
|
760
|
+
return false;
|
|
761
|
+
return reduceAbortWithListener(value, value, global, ops, runId, cryptoKey);
|
|
784
762
|
},
|
|
785
763
|
};
|
|
786
764
|
}
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
765
|
+
/**
|
|
766
|
+
* Cancel dangling abort-stream readers on any AbortController instances found
|
|
767
|
+
* in the hydrated step arguments. Called after the step function returns
|
|
768
|
+
* (success or failure) to prevent reader promises from keeping the serverless
|
|
769
|
+
* function alive indefinitely.
|
|
770
|
+
*/
|
|
771
|
+
export function cancelAbortReaders(...values) {
|
|
772
|
+
const visited = new WeakSet();
|
|
773
|
+
function cancelIfPresent(val) {
|
|
774
|
+
const cancel = val[ABORT_READER_CANCEL];
|
|
775
|
+
if (cancel && !cancel.signal.aborted) {
|
|
776
|
+
cancel.abort();
|
|
777
|
+
}
|
|
796
778
|
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
return
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
return
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
const
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
779
|
+
function walk(val) {
|
|
780
|
+
if (val == null || typeof val !== 'object')
|
|
781
|
+
return;
|
|
782
|
+
if (visited.has(val))
|
|
783
|
+
return;
|
|
784
|
+
visited.add(val);
|
|
785
|
+
if (val instanceof AbortController) {
|
|
786
|
+
cancelIfPresent(val);
|
|
787
|
+
cancelIfPresent(val.signal);
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
if (val instanceof AbortSignal) {
|
|
791
|
+
cancelIfPresent(val);
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
if (Array.isArray(val)) {
|
|
795
|
+
for (const item of val)
|
|
796
|
+
walk(item);
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
if (val instanceof Map) {
|
|
800
|
+
for (const v of val.values())
|
|
801
|
+
walk(v);
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
804
|
+
if (val instanceof Set) {
|
|
805
|
+
for (const v of val)
|
|
806
|
+
walk(v);
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
// Request/Response expose `signal`/`body` as prototype getters, so
|
|
810
|
+
// Object.values() won't find them. Descend explicitly.
|
|
811
|
+
if (typeof Request !== 'undefined' && val instanceof Request) {
|
|
812
|
+
walk(val.signal);
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
815
|
+
for (const v of Object.values(val))
|
|
816
|
+
walk(v);
|
|
817
|
+
}
|
|
818
|
+
for (const v of values)
|
|
819
|
+
walk(v);
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Sets up a stream reader on the controller that listens for an abort packet.
|
|
823
|
+
* Returns the readerCancel controller so it can be stored on both the
|
|
824
|
+
* controller and signal for cleanup by cancelAbortReaders.
|
|
825
|
+
*/
|
|
826
|
+
function setupAbortStreamReader(controller, runId, streamName, ops) {
|
|
827
|
+
const readerCancel = new AbortController();
|
|
828
|
+
ops.push((async () => {
|
|
829
|
+
try {
|
|
830
|
+
const readable = new WorkflowServerReadableStream(runId, streamName);
|
|
831
|
+
const reader = readable.getReader();
|
|
832
|
+
const result = await Promise.race([
|
|
833
|
+
reader.read(),
|
|
834
|
+
new Promise((resolve) => {
|
|
835
|
+
if (readerCancel.signal.aborted) {
|
|
836
|
+
resolve({ value: undefined, done: true });
|
|
837
|
+
return;
|
|
838
|
+
}
|
|
839
|
+
readerCancel.signal.addEventListener('abort', () => resolve({ value: undefined, done: true }), { once: true });
|
|
840
|
+
}),
|
|
841
|
+
]);
|
|
842
|
+
reader.releaseLock();
|
|
843
|
+
if (result.value && !result.done) {
|
|
844
|
+
try {
|
|
845
|
+
// Hydrate via the same machinery the writer used so the reason
|
|
846
|
+
// round-trips with full type fidelity. Encryption key (if any)
|
|
847
|
+
// comes from the step context — set up by the step handler before
|
|
848
|
+
// this reader runs. Fallback to undefined for external-context
|
|
849
|
+
// revives (the hydrate path is encryption-key-tolerant).
|
|
850
|
+
const ctxForKey = contextStorage.getStore();
|
|
851
|
+
const data = (await hydrateStepArguments(result.value, runId, ctxForKey?.encryptionKey));
|
|
852
|
+
controller.abort(data?.reason);
|
|
853
|
+
}
|
|
854
|
+
catch {
|
|
855
|
+
controller.abort();
|
|
856
|
+
}
|
|
867
857
|
}
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
858
|
+
}
|
|
859
|
+
catch {
|
|
860
|
+
// Stream read failed — signal won't propagate in real-time,
|
|
861
|
+
// but hook-based propagation on next replay provides fallback
|
|
862
|
+
}
|
|
863
|
+
})());
|
|
864
|
+
return readerCancel;
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Stores abort serialization symbols and the readerCancel controller
|
|
868
|
+
* on both the controller and its signal.
|
|
869
|
+
*/
|
|
870
|
+
function tagAbortPair(controller, value, readerCancel) {
|
|
871
|
+
const taggedController = controller;
|
|
872
|
+
const taggedSignal = controller.signal;
|
|
873
|
+
taggedController[ABORT_STREAM_NAME] = value.streamName;
|
|
874
|
+
taggedController[ABORT_HOOK_TOKEN] = value.hookToken;
|
|
875
|
+
taggedSignal[ABORT_STREAM_NAME] = value.streamName;
|
|
876
|
+
taggedSignal[ABORT_HOOK_TOKEN] = value.hookToken;
|
|
877
|
+
if (readerCancel) {
|
|
878
|
+
taggedController[ABORT_READER_CANCEL] = readerCancel;
|
|
879
|
+
taggedSignal[ABORT_READER_CANCEL] = readerCancel;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
/**
|
|
883
|
+
* Propagate abort-internal symbols from one signal to another. Used by the
|
|
884
|
+
* Request reviver because `new Request(url, { signal })` copies the signal
|
|
885
|
+
* internally — the constructed `request.signal` is a fresh AbortSignal that
|
|
886
|
+
* doesn't carry symbols from the source.
|
|
887
|
+
*/
|
|
888
|
+
function copyAbortInternals(src, dest) {
|
|
889
|
+
const s = src;
|
|
890
|
+
const d = dest;
|
|
891
|
+
if (s[ABORT_STREAM_NAME] !== undefined) {
|
|
892
|
+
d[ABORT_STREAM_NAME] = s[ABORT_STREAM_NAME];
|
|
893
|
+
}
|
|
894
|
+
if (s[ABORT_HOOK_TOKEN] !== undefined) {
|
|
895
|
+
d[ABORT_HOOK_TOKEN] = s[ABORT_HOOK_TOKEN];
|
|
896
|
+
}
|
|
897
|
+
if (s[ABORT_READER_CANCEL] !== undefined) {
|
|
898
|
+
d[ABORT_READER_CANCEL] = s[ABORT_READER_CANCEL];
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* Creates an AbortController with stream-backed abort propagation.
|
|
903
|
+
* Used by step and external revivers where real abort signal behavior is needed.
|
|
904
|
+
*
|
|
905
|
+
* @param value - The serialized abort controller/signal data
|
|
906
|
+
* @param ops - The ops array for tracking async work
|
|
907
|
+
* @param runId - The workflow run ID (for stream reads)
|
|
908
|
+
* @returns A real AbortController with patched abort() method
|
|
909
|
+
*/
|
|
910
|
+
function reviveAbortController(value, ops, runId) {
|
|
911
|
+
const controller = new AbortController();
|
|
912
|
+
if (value.aborted) {
|
|
913
|
+
tagAbortPair(controller, value);
|
|
914
|
+
controller.abort(value.reason);
|
|
915
|
+
}
|
|
916
|
+
else if (value.streamName) {
|
|
917
|
+
const readerCancel = setupAbortStreamReader(controller, runId, value.streamName, ops);
|
|
918
|
+
tagAbortPair(controller, value, readerCancel);
|
|
919
|
+
}
|
|
920
|
+
else {
|
|
921
|
+
tagAbortPair(controller, value);
|
|
922
|
+
}
|
|
923
|
+
// Override abort() to also write stream + resume hook (for step-initiated abort)
|
|
924
|
+
const originalAbort = controller.abort.bind(controller);
|
|
925
|
+
controller.abort = (reason) => {
|
|
926
|
+
if (controller.signal.aborted)
|
|
927
|
+
return;
|
|
928
|
+
originalAbort(reason);
|
|
929
|
+
const ctx = contextStorage.getStore();
|
|
930
|
+
if (ctx) {
|
|
931
|
+
ctx.ops.push((async () => {
|
|
932
|
+
try {
|
|
933
|
+
// Dehydrate the abort payload through the same machinery the hook
|
|
934
|
+
// event uses so the `reason` round-trips with full type fidelity
|
|
935
|
+
// (DOMException, custom errors, etc.) and respects the run's
|
|
936
|
+
// encryption key — symmetric with what the suspension handler
|
|
937
|
+
// writes for workflow-initiated aborts.
|
|
938
|
+
const payload = await dehydrateStepArguments({ aborted: true, reason }, ctx.workflowMetadata.workflowRunId, ctx.encryptionKey);
|
|
939
|
+
const writable = new WorkflowServerWritableStream(ctx.workflowMetadata.workflowRunId, value.streamName);
|
|
940
|
+
const writer = writable.getWriter();
|
|
941
|
+
await writer.write(payload);
|
|
942
|
+
await writer.close();
|
|
943
|
+
}
|
|
944
|
+
catch {
|
|
945
|
+
// Best-effort stream write
|
|
946
|
+
}
|
|
947
|
+
})());
|
|
948
|
+
if (value.hookToken) {
|
|
949
|
+
ctx.ops.push((async () => {
|
|
950
|
+
try {
|
|
951
|
+
const { resumeHook: resumeHookFn } = await import('./runtime/resume-hook.js');
|
|
952
|
+
await resumeHookFn(value.hookToken, {
|
|
953
|
+
aborted: true,
|
|
954
|
+
reason,
|
|
955
|
+
});
|
|
956
|
+
}
|
|
957
|
+
catch {
|
|
958
|
+
// Best-effort hook resume — retry on next replay
|
|
959
|
+
}
|
|
960
|
+
})());
|
|
872
961
|
}
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
962
|
+
}
|
|
963
|
+
};
|
|
964
|
+
return controller;
|
|
965
|
+
}
|
|
966
|
+
/**
|
|
967
|
+
* Revives just an AbortSignal without the patched abort() overhead.
|
|
968
|
+
* Used when only a signal (not a controller) was serialized.
|
|
969
|
+
*/
|
|
970
|
+
function reviveAbortSignal(value, ops, runId) {
|
|
971
|
+
const controller = new AbortController();
|
|
972
|
+
if (value.aborted) {
|
|
973
|
+
tagAbortPair(controller, value);
|
|
974
|
+
controller.abort(value.reason);
|
|
975
|
+
}
|
|
976
|
+
else if (value.streamName) {
|
|
977
|
+
const readerCancel = setupAbortStreamReader(controller, runId, value.streamName, ops);
|
|
978
|
+
tagAbortPair(controller, value, readerCancel);
|
|
979
|
+
}
|
|
980
|
+
else {
|
|
981
|
+
tagAbortPair(controller, value);
|
|
982
|
+
}
|
|
983
|
+
return controller.signal;
|
|
984
|
+
}
|
|
985
|
+
/**
|
|
986
|
+
* Base revivers shared across all serialization boundaries.
|
|
987
|
+
* Composes: class + common revivers from the modular modules.
|
|
988
|
+
*
|
|
989
|
+
* This is exported because serialization-format.ts and other files reference it.
|
|
990
|
+
*/
|
|
991
|
+
export function getCommonRevivers(global = globalThis) {
|
|
992
|
+
return {
|
|
993
|
+
...getClassRevivers(global),
|
|
994
|
+
...getCommonReviversFromModule(global),
|
|
895
995
|
};
|
|
896
996
|
}
|
|
897
997
|
/**
|
|
@@ -907,18 +1007,31 @@ export function getExternalRevivers(global = globalThis, ops, runId, cryptoKey)
|
|
|
907
1007
|
...getCommonRevivers(global),
|
|
908
1008
|
// StepFunction should not be returned from workflows to clients
|
|
909
1009
|
StepFunction: () => {
|
|
910
|
-
throw new
|
|
1010
|
+
throw new SerializationError('Step functions cannot be deserialized in client context. Step functions should not be returned from workflows.', {
|
|
1011
|
+
hint: 'A step function reference reached the client. Return a serializable value (e.g. the step result) instead of the step itself.',
|
|
1012
|
+
});
|
|
911
1013
|
},
|
|
912
1014
|
WorkflowFunction: (value) => Object.assign(() => {
|
|
913
|
-
throw new
|
|
1015
|
+
throw new SerializationError('Workflow functions cannot be called directly. Use start() to invoke them.', {
|
|
1016
|
+
hint: 'Wrap the workflow with `start(workflowFn, { ... })` from `workflow` to begin a run instead of invoking it like a normal function.',
|
|
1017
|
+
});
|
|
914
1018
|
}, { workflowId: value.workflowId }),
|
|
915
1019
|
Request: (value) => {
|
|
916
|
-
|
|
1020
|
+
const init = {
|
|
917
1021
|
method: value.method,
|
|
918
1022
|
headers: new global.Headers(value.headers),
|
|
919
1023
|
body: value.body,
|
|
920
1024
|
duplex: value.duplex,
|
|
921
|
-
}
|
|
1025
|
+
};
|
|
1026
|
+
if (value.signal)
|
|
1027
|
+
init.signal = value.signal;
|
|
1028
|
+
const request = new global.Request(value.url, init);
|
|
1029
|
+
// The Request constructor creates an internal signal copy, so the
|
|
1030
|
+
// abort-internal symbols set by reviveAbortSignal don't propagate.
|
|
1031
|
+
// Re-tag the request's own signal so cancelAbortReaders can find it.
|
|
1032
|
+
if (value.signal)
|
|
1033
|
+
copyAbortInternals(value.signal, request.signal);
|
|
1034
|
+
return request;
|
|
922
1035
|
},
|
|
923
1036
|
Response: (value) => {
|
|
924
1037
|
// Note: Response constructor only accepts status, statusText, and headers
|
|
@@ -967,8 +1080,19 @@ export function getExternalRevivers(global = globalThis, ops, runId, cryptoKey)
|
|
|
967
1080
|
}
|
|
968
1081
|
},
|
|
969
1082
|
WritableStream: (value) => {
|
|
970
|
-
|
|
971
|
-
|
|
1083
|
+
// Same handling as `getStepRevivers.WritableStream` — see comments
|
|
1084
|
+
// there for the cross-run case (writable carries `runId` from
|
|
1085
|
+
// parent → child forwarding via `start()`).
|
|
1086
|
+
const targetRunId = typeof value.runId === 'string' ? value.runId : runId;
|
|
1087
|
+
const targetKey = targetRunId === runId
|
|
1088
|
+
? cryptoKey
|
|
1089
|
+
: (async () => {
|
|
1090
|
+
const world = await getWorldLazy();
|
|
1091
|
+
const rawKey = await world.getEncryptionKeyForRun?.(targetRunId);
|
|
1092
|
+
return rawKey ? await importKey(rawKey, ['encrypt']) : undefined;
|
|
1093
|
+
})();
|
|
1094
|
+
const serialize = getSerializeStream(getExternalReducers(global, ops, targetRunId, targetKey), targetKey);
|
|
1095
|
+
const serverWritable = new WorkflowServerWritableStream(targetRunId, value.name);
|
|
972
1096
|
// Create flushable state for this stream
|
|
973
1097
|
const state = createFlushableState();
|
|
974
1098
|
ops.push(state.promise);
|
|
@@ -978,8 +1102,18 @@ export function getExternalRevivers(global = globalThis, ops, runId, cryptoKey)
|
|
|
978
1102
|
});
|
|
979
1103
|
// Start polling to detect when user releases lock
|
|
980
1104
|
pollWritableLock(serialize.writable, state);
|
|
1105
|
+
Object.defineProperty(serialize.writable, STREAM_NAME_SYMBOL, {
|
|
1106
|
+
value: value.name,
|
|
1107
|
+
writable: false,
|
|
1108
|
+
});
|
|
1109
|
+
Object.defineProperty(serialize.writable, STREAM_SERVER_RUN_ID_SYMBOL, {
|
|
1110
|
+
value: targetRunId,
|
|
1111
|
+
writable: false,
|
|
1112
|
+
});
|
|
981
1113
|
return serialize.writable;
|
|
982
1114
|
},
|
|
1115
|
+
AbortController: (value) => reviveAbortController(value, ops, runId),
|
|
1116
|
+
AbortSignal: (value) => reviveAbortSignal(value, ops, runId),
|
|
983
1117
|
};
|
|
984
1118
|
}
|
|
985
1119
|
/**
|
|
@@ -991,27 +1125,11 @@ export function getExternalRevivers(global = globalThis, ops, runId, cryptoKey)
|
|
|
991
1125
|
* @returns
|
|
992
1126
|
*/
|
|
993
1127
|
export function getWorkflowRevivers(global = globalThis) {
|
|
994
|
-
// Get the useStep function from the VM's globalThis
|
|
995
|
-
// This is set up by the workflow runner in workflow.ts
|
|
996
|
-
// Use Symbol.for directly to access the symbol on the global object
|
|
997
|
-
const useStep = global[Symbol.for('WORKFLOW_USE_STEP')];
|
|
998
1128
|
return {
|
|
999
1129
|
...getCommonRevivers(global),
|
|
1000
|
-
// StepFunction reviver for workflow context -
|
|
1001
|
-
//
|
|
1002
|
-
|
|
1003
|
-
StepFunction: (value) => {
|
|
1004
|
-
const stepId = value.stepId;
|
|
1005
|
-
const closureVars = value.closureVars;
|
|
1006
|
-
if (!useStep) {
|
|
1007
|
-
throw new Error('WORKFLOW_USE_STEP not found on global object. Step functions cannot be deserialized outside workflow context.');
|
|
1008
|
-
}
|
|
1009
|
-
if (closureVars) {
|
|
1010
|
-
// For step functions with closure variables, create a wrapper that provides them
|
|
1011
|
-
return useStep(stepId, () => closureVars);
|
|
1012
|
-
}
|
|
1013
|
-
return useStep(stepId);
|
|
1014
|
-
},
|
|
1130
|
+
// StepFunction reviver for workflow context - uses the modular reviver
|
|
1131
|
+
// which calls WORKFLOW_USE_STEP from global to reconstruct step proxies
|
|
1132
|
+
...getStepFunctionReviver(global),
|
|
1015
1133
|
Request: (value) => {
|
|
1016
1134
|
Object.setPrototypeOf(value, global.Request.prototype);
|
|
1017
1135
|
const responseWritable = value.responseWritable;
|
|
@@ -1019,7 +1137,9 @@ export function getWorkflowRevivers(global = globalThis) {
|
|
|
1019
1137
|
value[WEBHOOK_RESPONSE_WRITABLE] = responseWritable;
|
|
1020
1138
|
delete value.responseWritable;
|
|
1021
1139
|
value.respondWith = () => {
|
|
1022
|
-
throw new
|
|
1140
|
+
throw new SerializationError('`respondWith()` must be called from within a step function.', {
|
|
1141
|
+
hint: 'Move the `respondWith(...)` call inside a `"use step"` function — it cannot be invoked from a workflow context.',
|
|
1142
|
+
});
|
|
1023
1143
|
};
|
|
1024
1144
|
}
|
|
1025
1145
|
return value;
|
|
@@ -1027,7 +1147,9 @@ export function getWorkflowRevivers(global = globalThis) {
|
|
|
1027
1147
|
// Workflow function reviver for workflow context — returns a function-like
|
|
1028
1148
|
// object with .workflowId that mimics what the SWC compiler produces,
|
|
1029
1149
|
WorkflowFunction: (value) => Object.assign(() => {
|
|
1030
|
-
throw new
|
|
1150
|
+
throw new SerializationError('Workflow functions cannot be called directly. Use start() to invoke them.', {
|
|
1151
|
+
hint: 'Wrap the workflow with `start(workflowFn, { ... })` from `workflow` to begin a run instead of invoking it like a normal function.',
|
|
1152
|
+
});
|
|
1031
1153
|
}, { workflowId: value.workflowId }),
|
|
1032
1154
|
Response: (value) => {
|
|
1033
1155
|
Object.setPrototypeOf(value, global.Response.prototype);
|
|
@@ -1057,12 +1179,46 @@ export function getWorkflowRevivers(global = globalThis) {
|
|
|
1057
1179
|
});
|
|
1058
1180
|
},
|
|
1059
1181
|
WritableStream: (value) => {
|
|
1060
|
-
|
|
1182
|
+
const descriptor = {
|
|
1061
1183
|
[STREAM_NAME_SYMBOL]: {
|
|
1062
1184
|
value: value.name,
|
|
1063
1185
|
writable: false,
|
|
1064
1186
|
},
|
|
1065
|
-
}
|
|
1187
|
+
};
|
|
1188
|
+
// Preserve the foreign runId, if present, so that when the
|
|
1189
|
+
// handle is later passed to a step the workflow reducer can
|
|
1190
|
+
// forward it through to the step reviver.
|
|
1191
|
+
if (typeof value.runId === 'string') {
|
|
1192
|
+
descriptor[STREAM_SERVER_RUN_ID_SYMBOL] = {
|
|
1193
|
+
value: value.runId,
|
|
1194
|
+
writable: false,
|
|
1195
|
+
};
|
|
1196
|
+
}
|
|
1197
|
+
return Object.create(global.WritableStream.prototype, descriptor);
|
|
1198
|
+
},
|
|
1199
|
+
// AbortController/AbortSignal revived inside the workflow VM. Use the
|
|
1200
|
+
// real WorkflowAbortSignal class so addEventListener('abort', fn) actually
|
|
1201
|
+
// fires when the signal aborts (the previous no-op stub silently dropped
|
|
1202
|
+
// listener registrations — silent correctness bug for natural patterns
|
|
1203
|
+
// like `signal.addEventListener('abort', fn)` after receiving a deserialized
|
|
1204
|
+
// signal). The signal does not own a hook subscription here — abort state
|
|
1205
|
+
// is delivered via the existing replay machinery on the source side.
|
|
1206
|
+
AbortController: (value) => {
|
|
1207
|
+
const signal = new WorkflowAbortSignal(value.streamName, value.hookToken);
|
|
1208
|
+
if (value.aborted)
|
|
1209
|
+
signal._setAborted(value.reason);
|
|
1210
|
+
return {
|
|
1211
|
+
[ABORT_STREAM_NAME]: value.streamName,
|
|
1212
|
+
[ABORT_HOOK_TOKEN]: value.hookToken,
|
|
1213
|
+
signal,
|
|
1214
|
+
abort: () => { },
|
|
1215
|
+
};
|
|
1216
|
+
},
|
|
1217
|
+
AbortSignal: (value) => {
|
|
1218
|
+
const signal = new WorkflowAbortSignal(value.streamName, value.hookToken);
|
|
1219
|
+
if (value.aborted)
|
|
1220
|
+
signal._setAborted(value.reason);
|
|
1221
|
+
return signal;
|
|
1066
1222
|
},
|
|
1067
1223
|
};
|
|
1068
1224
|
}
|
|
@@ -1079,59 +1235,91 @@ function getStepRevivers(global = globalThis, ops, runId, cryptoKey) {
|
|
|
1079
1235
|
return {
|
|
1080
1236
|
...getCommonRevivers(global),
|
|
1081
1237
|
// StepFunction reviver for step context - returns raw step function
|
|
1082
|
-
// with closure variable support via AsyncLocalStorage
|
|
1238
|
+
// with closure variable support via AsyncLocalStorage.
|
|
1239
|
+
//
|
|
1240
|
+
// Handles four independent flags from the serialized payload:
|
|
1241
|
+
// - `closureVars`: invoke the body inside an AsyncLocalStorage frame
|
|
1242
|
+
// so the SWC-emitted `WORKFLOW_STEP_CONTEXT_STORAGE` IIFE in the
|
|
1243
|
+
// hoisted body can pull the closure variables back out.
|
|
1244
|
+
// - `boundThis`: a `this` value captured by
|
|
1245
|
+
// `useStep(...).bind(this)` in the workflow bundle (lexical-`this`
|
|
1246
|
+
// arrow steps). The wrapper invokes the body via
|
|
1247
|
+
// `stepFn.apply(boundThis, args)` so the body sees the same
|
|
1248
|
+
// `this` it would have had in the workflow bundle. Property
|
|
1249
|
+
// presence — not truthiness — is significant because
|
|
1250
|
+
// `bind(null)` and `bind(undefined)` are both legal and should
|
|
1251
|
+
// round-trip faithfully.
|
|
1252
|
+
// - `boundArgs`: prefilled args from
|
|
1253
|
+
// `useStep(...).bind(thisArg, x, y)`. Prepended to the call args
|
|
1254
|
+
// so partial application survives serialization.
|
|
1083
1255
|
StepFunction: (value) => {
|
|
1084
1256
|
const stepId = value.stepId;
|
|
1085
1257
|
const closureVars = value.closureVars;
|
|
1258
|
+
const hasBoundThis = 'boundThis' in value;
|
|
1259
|
+
const boundThis = hasBoundThis ? value.boundThis : undefined;
|
|
1260
|
+
const boundArgs = Array.isArray(value.boundArgs) ? value.boundArgs : [];
|
|
1086
1261
|
const stepFn = getStepFunction(stepId);
|
|
1087
1262
|
if (!stepFn) {
|
|
1088
|
-
throw new
|
|
1263
|
+
throw new SerializationError(`Step function "${stepId}" not found. Make sure the step function is registered.`, {
|
|
1264
|
+
hint: 'Make sure the step file is included in your build (i.e. it is listed in the workflow manifest), and that the SWC plugin is configured for the file.',
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
1267
|
+
// Fast path: nothing to wrap.
|
|
1268
|
+
if (!closureVars && !hasBoundThis && boundArgs.length === 0) {
|
|
1269
|
+
return stepFn;
|
|
1089
1270
|
}
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
// Get the current context from AsyncLocalStorage
|
|
1271
|
+
const wrappedStepFn = function (...args) {
|
|
1272
|
+
const callThis = hasBoundThis ? boundThis : this;
|
|
1273
|
+
const callArgs = boundArgs.length > 0 ? [...boundArgs, ...args] : args;
|
|
1274
|
+
if (closureVars) {
|
|
1095
1275
|
const currentContext = contextStorage.getStore();
|
|
1096
1276
|
if (!currentContext) {
|
|
1097
|
-
throw new
|
|
1277
|
+
throw new WorkflowRuntimeError('Cannot call step function with closure variables outside step context');
|
|
1098
1278
|
}
|
|
1099
|
-
// Create a new context with the closure variables merged in
|
|
1100
1279
|
const newContext = {
|
|
1101
1280
|
...currentContext,
|
|
1102
1281
|
closureVars,
|
|
1103
1282
|
};
|
|
1104
|
-
|
|
1105
|
-
return contextStorage.run(newContext, () => stepFn(...args));
|
|
1106
|
-
});
|
|
1107
|
-
// Copy properties from original step function
|
|
1108
|
-
Object.defineProperty(wrappedStepFn, 'name', {
|
|
1109
|
-
value: stepFn.name,
|
|
1110
|
-
});
|
|
1111
|
-
Object.defineProperty(wrappedStepFn, 'stepId', {
|
|
1112
|
-
value: stepId,
|
|
1113
|
-
writable: false,
|
|
1114
|
-
enumerable: false,
|
|
1115
|
-
configurable: false,
|
|
1116
|
-
});
|
|
1117
|
-
if (stepFn.maxRetries !== undefined) {
|
|
1118
|
-
wrappedStepFn.maxRetries = stepFn.maxRetries;
|
|
1283
|
+
return contextStorage.run(newContext, () => stepFn.apply(callThis, callArgs));
|
|
1119
1284
|
}
|
|
1120
|
-
return
|
|
1285
|
+
return stepFn.apply(callThis, callArgs);
|
|
1286
|
+
};
|
|
1287
|
+
// Copy properties from original step function
|
|
1288
|
+
Object.defineProperty(wrappedStepFn, 'name', {
|
|
1289
|
+
value: stepFn.name,
|
|
1290
|
+
});
|
|
1291
|
+
Object.defineProperty(wrappedStepFn, 'stepId', {
|
|
1292
|
+
value: stepId,
|
|
1293
|
+
writable: false,
|
|
1294
|
+
enumerable: false,
|
|
1295
|
+
configurable: false,
|
|
1296
|
+
});
|
|
1297
|
+
if (stepFn.maxRetries !== undefined) {
|
|
1298
|
+
wrappedStepFn.maxRetries = stepFn.maxRetries;
|
|
1121
1299
|
}
|
|
1122
|
-
return
|
|
1300
|
+
return wrappedStepFn;
|
|
1123
1301
|
},
|
|
1124
1302
|
WorkflowFunction: (value) => Object.assign(() => {
|
|
1125
|
-
throw new
|
|
1303
|
+
throw new SerializationError('Workflow functions cannot be called directly. Use start() to invoke them.', {
|
|
1304
|
+
hint: 'Wrap the workflow with `start(workflowFn, { ... })` from `workflow` to begin a run instead of invoking it like a normal function.',
|
|
1305
|
+
});
|
|
1126
1306
|
}, { workflowId: value.workflowId }),
|
|
1127
1307
|
Request: (value) => {
|
|
1128
1308
|
const responseWritable = value.responseWritable;
|
|
1129
|
-
const
|
|
1309
|
+
const init = {
|
|
1130
1310
|
method: value.method,
|
|
1131
1311
|
headers: new global.Headers(value.headers),
|
|
1132
1312
|
body: value.body,
|
|
1133
1313
|
duplex: value.duplex,
|
|
1134
|
-
}
|
|
1314
|
+
};
|
|
1315
|
+
if (value.signal)
|
|
1316
|
+
init.signal = value.signal;
|
|
1317
|
+
const request = new global.Request(value.url, init);
|
|
1318
|
+
// The Request constructor creates an internal signal copy, so the
|
|
1319
|
+
// abort-internal symbols set by reviveAbortSignal don't propagate.
|
|
1320
|
+
// Re-tag the request's own signal so cancelAbortReaders can find it.
|
|
1321
|
+
if (value.signal)
|
|
1322
|
+
copyAbortInternals(value.signal, request.signal);
|
|
1135
1323
|
if (responseWritable) {
|
|
1136
1324
|
request.respondWith = async (response) => {
|
|
1137
1325
|
const writer = responseWritable.getWriter();
|
|
@@ -1188,8 +1376,28 @@ function getStepRevivers(global = globalThis, ops, runId, cryptoKey) {
|
|
|
1188
1376
|
}
|
|
1189
1377
|
},
|
|
1190
1378
|
WritableStream: (value) => {
|
|
1191
|
-
|
|
1192
|
-
|
|
1379
|
+
// Same-run case: the writable belongs to the current run. Use the
|
|
1380
|
+
// local cryptoKey and write to the local runId's server stream.
|
|
1381
|
+
//
|
|
1382
|
+
// Cross-run case (parent → child via `start()`): the descriptor
|
|
1383
|
+
// carries the original `runId` and `name`. Open a server writable
|
|
1384
|
+
// against the original `(runId, name)` and resolve THAT run's key
|
|
1385
|
+
// for encryption. The resolution is async but doesn't need to
|
|
1386
|
+
// block reviver return — `getSerializeStream` accepts the
|
|
1387
|
+
// `Promise<CryptoKey | undefined>` directly and awaits it lazily
|
|
1388
|
+
// on the first chunk written. The key is imported encrypt-only
|
|
1389
|
+
// so the receiving run can never decrypt anything else on the
|
|
1390
|
+
// owning run's stream — it can only contribute new writes.
|
|
1391
|
+
const targetRunId = typeof value.runId === 'string' ? value.runId : runId;
|
|
1392
|
+
const targetKey = targetRunId === runId
|
|
1393
|
+
? cryptoKey
|
|
1394
|
+
: (async () => {
|
|
1395
|
+
const world = await getWorldLazy();
|
|
1396
|
+
const rawKey = await world.getEncryptionKeyForRun?.(targetRunId);
|
|
1397
|
+
return rawKey ? await importKey(rawKey, ['encrypt']) : undefined;
|
|
1398
|
+
})();
|
|
1399
|
+
const serialize = getSerializeStream(getStepReducers(global, ops, targetRunId, targetKey), targetKey);
|
|
1400
|
+
const serverWritable = new WorkflowServerWritableStream(targetRunId, value.name);
|
|
1193
1401
|
// Create flushable state for this stream
|
|
1194
1402
|
const state = createFlushableState();
|
|
1195
1403
|
ops.push(state.promise);
|
|
@@ -1199,211 +1407,272 @@ function getStepRevivers(global = globalThis, ops, runId, cryptoKey) {
|
|
|
1199
1407
|
});
|
|
1200
1408
|
// Start polling to detect when user releases lock
|
|
1201
1409
|
pollWritableLock(serialize.writable, state);
|
|
1410
|
+
// Record the underlying `(runId, name)` so downstream reducers can
|
|
1411
|
+
// recognize that this writable is already backed by a workflow
|
|
1412
|
+
// server stream. When forwarded across `start()` again — e.g.
|
|
1413
|
+
// the child passes this writable on to a grandchild — the
|
|
1414
|
+
// external reducer needs both to emit the original `runId` in
|
|
1415
|
+
// the descriptor.
|
|
1416
|
+
Object.defineProperty(serialize.writable, STREAM_NAME_SYMBOL, {
|
|
1417
|
+
value: value.name,
|
|
1418
|
+
writable: false,
|
|
1419
|
+
});
|
|
1420
|
+
Object.defineProperty(serialize.writable, STREAM_SERVER_RUN_ID_SYMBOL, {
|
|
1421
|
+
value: targetRunId,
|
|
1422
|
+
writable: false,
|
|
1423
|
+
});
|
|
1202
1424
|
return serialize.writable;
|
|
1203
1425
|
},
|
|
1426
|
+
AbortController: (value) => reviveAbortController(value, ops, runId),
|
|
1427
|
+
AbortSignal: (value) => reviveAbortSignal(value, ops, runId),
|
|
1204
1428
|
};
|
|
1205
1429
|
}
|
|
1206
1430
|
// ============================================================================
|
|
1207
1431
|
// Encryption Helpers
|
|
1208
1432
|
// ============================================================================
|
|
1433
|
+
// These delegate to the modular `encrypt`/`decrypt` from `./serialization/encryption.js`
|
|
1434
|
+
// but are kept as named exports for backwards compatibility with existing consumers.
|
|
1209
1435
|
/**
|
|
1210
1436
|
* Encrypt data if the world supports encryption.
|
|
1211
1437
|
* Returns original data if encryption is not available.
|
|
1212
1438
|
*
|
|
1213
|
-
* @
|
|
1214
|
-
* @param key - Encryption key (undefined to skip encryption)
|
|
1215
|
-
* @param context - Encryption context with runId
|
|
1216
|
-
* @returns Encrypted data if encryption available, original data otherwise
|
|
1439
|
+
* @deprecated Use `encrypt` from `./serialization/encryption.js` instead.
|
|
1217
1440
|
*/
|
|
1218
1441
|
export async function maybeEncrypt(data, key) {
|
|
1219
|
-
|
|
1220
|
-
return data;
|
|
1221
|
-
const encrypted = await aesGcmEncrypt(key, data);
|
|
1222
|
-
return encodeWithFormatPrefix(SerializationFormat.ENCRYPTED, encrypted);
|
|
1442
|
+
return (await encrypt(data, key));
|
|
1223
1443
|
}
|
|
1224
1444
|
/**
|
|
1225
1445
|
* Decrypt data if it has the 'encr' prefix.
|
|
1226
1446
|
*
|
|
1227
|
-
* @
|
|
1228
|
-
* @param key - Encryption key (undefined if no key available)
|
|
1229
|
-
* @returns Decrypted data if encrypted, original data otherwise
|
|
1230
|
-
* @throws {WorkflowRuntimeError} If the data is encrypted but no key is
|
|
1231
|
-
* available. Callers (e.g., `Run.pollReturnValue()`, `hydrateStepReturnValue`)
|
|
1232
|
-
* should be aware this can surface as a rejected promise during key rotation
|
|
1233
|
-
* or misconfiguration scenarios.
|
|
1447
|
+
* @deprecated Use `decrypt` from `./serialization/encryption.js` instead.
|
|
1234
1448
|
*/
|
|
1235
1449
|
export async function maybeDecrypt(data, key) {
|
|
1236
|
-
|
|
1237
|
-
// (not binary Uint8Array). Pass through as-is for backwards compat.
|
|
1238
|
-
if (!(data instanceof Uint8Array)) {
|
|
1239
|
-
return data;
|
|
1240
|
-
}
|
|
1241
|
-
if (isEncrypted(data)) {
|
|
1242
|
-
if (!key) {
|
|
1243
|
-
throw new WorkflowRuntimeError('Encrypted data encountered but no encryption key is available. ' +
|
|
1244
|
-
'Encryption is not configured or no key was provided for this run.');
|
|
1245
|
-
}
|
|
1246
|
-
// Strip the 'encr' format prefix — the prefix is a core framing concern
|
|
1247
|
-
const { payload } = decodeFormatPrefix(data);
|
|
1248
|
-
return aesGcmDecrypt(key, payload);
|
|
1249
|
-
}
|
|
1250
|
-
return data;
|
|
1450
|
+
return decrypt(data, key);
|
|
1251
1451
|
}
|
|
1252
1452
|
// ============================================================================
|
|
1253
1453
|
// Dehydrate / Hydrate Functions
|
|
1254
1454
|
// ============================================================================
|
|
1455
|
+
// These delegate to the modular mode modules (workflow, step, client) passing
|
|
1456
|
+
// mode-specific stream and Request/Response reducers/revivers as extra options.
|
|
1457
|
+
// The v1Compat path is handled inline before delegating to the modules.
|
|
1255
1458
|
/**
|
|
1256
1459
|
* Called from the `start()` function to serialize the workflow arguments
|
|
1257
1460
|
* into a format that can be saved to the database and then hydrated from
|
|
1258
1461
|
* within the workflow execution environment.
|
|
1259
|
-
*
|
|
1260
|
-
* @param value - The value to serialize
|
|
1261
|
-
* @param runId - The workflow run ID (required for encryption context)
|
|
1262
|
-
* @param key - Encryption key (undefined to skip encryption)
|
|
1263
|
-
* @param ops - Promise array for stream operations
|
|
1264
|
-
* @param global - Global object for serialization context
|
|
1265
|
-
* @param v1Compat - Enable legacy v1 compatibility mode
|
|
1266
|
-
* @returns The dehydrated value as binary data (Uint8Array) with format prefix
|
|
1267
1462
|
*/
|
|
1268
1463
|
export async function dehydrateWorkflowArguments(value, runId, key, ops = [], global = globalThis, v1Compat = false) {
|
|
1269
|
-
|
|
1464
|
+
if (v1Compat) {
|
|
1270
1465
|
const str = stringify(value, getExternalReducers(global, ops, runId, key));
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1466
|
+
return revive(str);
|
|
1467
|
+
}
|
|
1468
|
+
try {
|
|
1469
|
+
return await clientModule.serialize(value, key, {
|
|
1470
|
+
global,
|
|
1471
|
+
extraReducers: getStreamAndRequestReducers(getExternalReducers(global, ops, runId, key)),
|
|
1472
|
+
});
|
|
1278
1473
|
}
|
|
1279
1474
|
catch (error) {
|
|
1280
|
-
|
|
1475
|
+
const cause = unwrapSerializationCause(error);
|
|
1476
|
+
const { message, hint } = formatSerializationError('workflow arguments', cause);
|
|
1477
|
+
throw new SerializationError(message, { hint, cause });
|
|
1281
1478
|
}
|
|
1282
1479
|
}
|
|
1283
1480
|
/**
|
|
1284
1481
|
* Called from workflow execution environment to hydrate the workflow
|
|
1285
1482
|
* arguments from the database at the start of workflow execution.
|
|
1286
|
-
*
|
|
1287
|
-
* @param value - Binary serialized data (Uint8Array) with format prefix
|
|
1288
|
-
* @param _runId - Workflow run ID (reserved for future decryption context; decryption is currently driven solely by the provided key)
|
|
1289
|
-
* @param key - Encryption key (undefined to skip decryption)
|
|
1290
|
-
* @param global - Global object for deserialization context
|
|
1291
|
-
* @param extraRevivers - Additional revivers for custom types
|
|
1292
|
-
* @returns The hydrated value
|
|
1293
1483
|
*/
|
|
1294
1484
|
export async function hydrateWorkflowArguments(value, _runId, key, global = globalThis, extraRevivers = {}) {
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
// via devalue's unflatten().
|
|
1300
|
-
if (!(decrypted instanceof Uint8Array)) {
|
|
1301
|
-
return unflatten(decrypted, {
|
|
1302
|
-
...getWorkflowRevivers(global),
|
|
1485
|
+
return workflowModule.deserialize(await maybeDecrypt(value, key), {
|
|
1486
|
+
global,
|
|
1487
|
+
extraRevivers: {
|
|
1488
|
+
...getStreamAndRequestRevivers(getWorkflowRevivers(global)),
|
|
1303
1489
|
...extraRevivers,
|
|
1490
|
+
},
|
|
1491
|
+
});
|
|
1492
|
+
}
|
|
1493
|
+
/**
|
|
1494
|
+
* Dehydrate workflow return value for storage.
|
|
1495
|
+
*/
|
|
1496
|
+
export async function dehydrateWorkflowReturnValue(value, _runId, key, global = globalThis, v1Compat = false) {
|
|
1497
|
+
if (v1Compat) {
|
|
1498
|
+
const str = stringify(value, getWorkflowReducers(global));
|
|
1499
|
+
return revive(str);
|
|
1500
|
+
}
|
|
1501
|
+
try {
|
|
1502
|
+
return await stepModule.serialize(value, key, {
|
|
1503
|
+
global,
|
|
1504
|
+
extraReducers: getStreamAndRequestReducers(getWorkflowReducers(global)),
|
|
1304
1505
|
});
|
|
1305
1506
|
}
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
const
|
|
1309
|
-
|
|
1310
|
-
|
|
1507
|
+
catch (error) {
|
|
1508
|
+
const cause = unwrapSerializationCause(error);
|
|
1509
|
+
const { message, hint } = formatSerializationError('workflow return value', cause);
|
|
1510
|
+
throw new SerializationError(message, { hint, cause });
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
/**
|
|
1514
|
+
* Called from the client side to hydrate the workflow return value
|
|
1515
|
+
* of a completed workflow run.
|
|
1516
|
+
*/
|
|
1517
|
+
export async function hydrateWorkflowReturnValue(value, runId, key, ops = [], global = globalThis, extraRevivers = {}) {
|
|
1518
|
+
return clientModule.deserialize(value, key, {
|
|
1519
|
+
global,
|
|
1520
|
+
extraRevivers: {
|
|
1521
|
+
...getStreamAndRequestRevivers(getExternalRevivers(global, ops, runId, key)),
|
|
1522
|
+
...extraRevivers,
|
|
1523
|
+
},
|
|
1524
|
+
});
|
|
1525
|
+
}
|
|
1526
|
+
/**
|
|
1527
|
+
* Called from the workflow handler when a step is being created.
|
|
1528
|
+
* Dehydrates values from within the workflow execution environment.
|
|
1529
|
+
*/
|
|
1530
|
+
export async function dehydrateStepArguments(value, _runId, key, global = globalThis, v1Compat = false) {
|
|
1531
|
+
if (v1Compat) {
|
|
1532
|
+
const str = stringify(value, getWorkflowReducers(global));
|
|
1533
|
+
return revive(str);
|
|
1534
|
+
}
|
|
1535
|
+
try {
|
|
1536
|
+
return await stepModule.serialize(value, key, {
|
|
1537
|
+
global,
|
|
1538
|
+
extraReducers: getStreamAndRequestReducers(getWorkflowReducers(global)),
|
|
1539
|
+
});
|
|
1540
|
+
}
|
|
1541
|
+
catch (error) {
|
|
1542
|
+
const cause = unwrapSerializationCause(error);
|
|
1543
|
+
const { message, hint } = formatSerializationError('step arguments', cause);
|
|
1544
|
+
throw new SerializationError(message, { hint, cause });
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
/**
|
|
1548
|
+
* Called from the step handler to hydrate the arguments of a step
|
|
1549
|
+
* from the database at the start of the step execution.
|
|
1550
|
+
*/
|
|
1551
|
+
export async function hydrateStepArguments(value, runId, key, ops = [], global = globalThis, extraRevivers = {}) {
|
|
1552
|
+
return stepModule.deserialize(value, key, {
|
|
1553
|
+
global,
|
|
1554
|
+
extraRevivers: {
|
|
1555
|
+
...getStreamAndRequestRevivers(getStepRevivers(global, ops, runId, key)),
|
|
1311
1556
|
...extraRevivers,
|
|
1557
|
+
},
|
|
1558
|
+
});
|
|
1559
|
+
}
|
|
1560
|
+
/**
|
|
1561
|
+
* Called from the step handler when a step has completed.
|
|
1562
|
+
* Dehydrates values from within the step execution environment.
|
|
1563
|
+
*/
|
|
1564
|
+
export async function dehydrateStepReturnValue(value, runId, key, ops = [], global = globalThis, v1Compat = false) {
|
|
1565
|
+
if (v1Compat) {
|
|
1566
|
+
const str = stringify(value, getStepReducers(global, ops, runId, key));
|
|
1567
|
+
return revive(str);
|
|
1568
|
+
}
|
|
1569
|
+
try {
|
|
1570
|
+
return await stepModule.serialize(value, key, {
|
|
1571
|
+
global,
|
|
1572
|
+
extraReducers: getStreamAndRequestReducers(getStepReducers(global, ops, runId, key)),
|
|
1312
1573
|
});
|
|
1313
|
-
return obj;
|
|
1314
1574
|
}
|
|
1315
|
-
|
|
1575
|
+
catch (error) {
|
|
1576
|
+
const cause = unwrapSerializationCause(error);
|
|
1577
|
+
const { message, hint } = formatSerializationError('step return value', cause);
|
|
1578
|
+
throw new SerializationError(message, { hint, cause });
|
|
1579
|
+
}
|
|
1316
1580
|
}
|
|
1317
1581
|
/**
|
|
1318
|
-
*
|
|
1582
|
+
* Called from the step handler when a step throws. Dehydrates the thrown
|
|
1583
|
+
* value from within the step execution environment into a format that can
|
|
1584
|
+
* be saved to the database in a `step_failed` or `step_retrying` event.
|
|
1585
|
+
*
|
|
1586
|
+
* Any JavaScript value can be thrown (strings, numbers, objects, Errors,
|
|
1587
|
+
* Error subclasses), so the same serialization pipeline used for step
|
|
1588
|
+
* arguments and return values is applied here.
|
|
1319
1589
|
*
|
|
1320
|
-
* @param value - The value to serialize
|
|
1590
|
+
* @param value - The thrown value to serialize (can be any type)
|
|
1321
1591
|
* @param runId - Run ID for encryption context
|
|
1322
1592
|
* @param key - Encryption key (undefined to skip encryption)
|
|
1593
|
+
* @param ops - Promise array for stream operations
|
|
1323
1594
|
* @param global - Global object for serialization context
|
|
1324
1595
|
* @returns The dehydrated value as binary data (Uint8Array) with format prefix
|
|
1325
1596
|
*/
|
|
1326
|
-
export async function
|
|
1597
|
+
export async function dehydrateStepError(value, runId, key, ops = [], global = globalThis) {
|
|
1327
1598
|
try {
|
|
1328
|
-
const str = stringify(value,
|
|
1329
|
-
if (v1Compat) {
|
|
1330
|
-
return revive(str);
|
|
1331
|
-
}
|
|
1599
|
+
const str = stringify(value, getStepReducers(global, ops, runId, key));
|
|
1332
1600
|
const payload = new TextEncoder().encode(str);
|
|
1333
1601
|
const serialized = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
|
|
1334
|
-
|
|
1335
|
-
return maybeEncrypt(serialized, key);
|
|
1602
|
+
return (await maybeEncrypt(serialized, key));
|
|
1336
1603
|
}
|
|
1337
1604
|
catch (error) {
|
|
1338
|
-
|
|
1605
|
+
const cause = unwrapSerializationCause(error);
|
|
1606
|
+
const { message, hint } = formatSerializationError('step error', cause);
|
|
1607
|
+
throw new SerializationError(message, { hint, cause });
|
|
1339
1608
|
}
|
|
1340
1609
|
}
|
|
1341
1610
|
/**
|
|
1342
|
-
* Called from the
|
|
1343
|
-
*
|
|
1344
|
-
*
|
|
1611
|
+
* Called from the workflow handler when replaying the event log of a
|
|
1612
|
+
* `step_failed` or `step_retrying` event. Hydrates the thrown value from
|
|
1613
|
+
* the database so the workflow can see the original thrown value.
|
|
1345
1614
|
*
|
|
1346
1615
|
* @param value - Binary serialized data (Uint8Array) with format prefix
|
|
1347
1616
|
* @param runId - Run ID for decryption context
|
|
1348
1617
|
* @param key - Encryption key (undefined to skip decryption)
|
|
1349
|
-
* @param ops - Promise array for stream operations
|
|
1350
1618
|
* @param global - Global object for deserialization context
|
|
1351
1619
|
* @param extraRevivers - Additional revivers for custom types
|
|
1352
|
-
* @returns The hydrated
|
|
1620
|
+
* @returns The hydrated thrown value, ready to reject the step promise
|
|
1353
1621
|
*/
|
|
1354
|
-
export async function
|
|
1355
|
-
// Decrypt if needed
|
|
1622
|
+
export async function hydrateStepError(value, _runId, key, global = globalThis, extraRevivers = {}) {
|
|
1356
1623
|
const decrypted = await maybeDecrypt(value, key);
|
|
1357
|
-
// Legacy specVersion 1 runs stored data as plain JSON arrays (not binary).
|
|
1358
|
-
// These pass through maybeDecrypt unchanged and are deserialized directly
|
|
1359
|
-
// via devalue's unflatten().
|
|
1360
1624
|
if (!(decrypted instanceof Uint8Array)) {
|
|
1625
|
+
// Treated as a devalue "flattened" array. In production this branch is
|
|
1626
|
+
// exercised by legacy code paths that bypassed `dehydrateStepError`; the
|
|
1627
|
+
// SDK version is pinned per workflow run via skew protection, so a
|
|
1628
|
+
// current-version producer always emits a Uint8Array here. If a
|
|
1629
|
+
// misshapen value reaches us, `unflatten` throws — that's intentional:
|
|
1630
|
+
// the higher-level hydration helpers (`hydrateStepIO`,
|
|
1631
|
+
// `hydrateResourceIO`) already wrap us in a try/catch that leaves the
|
|
1632
|
+
// field un-hydrated for o11y display, and surfacing the throw to logs
|
|
1633
|
+
// is more debuggable than silently masking the unsupported shape.
|
|
1361
1634
|
return unflatten(decrypted, {
|
|
1362
|
-
...
|
|
1635
|
+
...getWorkflowRevivers(global),
|
|
1363
1636
|
...extraRevivers,
|
|
1364
1637
|
});
|
|
1365
1638
|
}
|
|
1366
1639
|
const { format, payload } = decodeFormatPrefix(decrypted);
|
|
1367
1640
|
if (format === SerializationFormat.DEVALUE_V1) {
|
|
1368
1641
|
const str = new TextDecoder().decode(payload);
|
|
1369
|
-
|
|
1370
|
-
...
|
|
1642
|
+
return parse(str, {
|
|
1643
|
+
...getWorkflowRevivers(global),
|
|
1371
1644
|
...extraRevivers,
|
|
1372
1645
|
});
|
|
1373
|
-
return obj;
|
|
1374
1646
|
}
|
|
1375
1647
|
throw new Error(`Unsupported serialization format: ${format}`);
|
|
1376
1648
|
}
|
|
1377
1649
|
/**
|
|
1378
|
-
* Called from the workflow handler when
|
|
1379
|
-
* Dehydrates
|
|
1380
|
-
* into a format that can be saved to the database.
|
|
1650
|
+
* Called from the workflow handler when the workflow itself throws.
|
|
1651
|
+
* Dehydrates the thrown value from within the workflow execution environment
|
|
1652
|
+
* into a format that can be saved to the database in a `run_failed` event.
|
|
1381
1653
|
*
|
|
1382
|
-
* @param value - The value to serialize
|
|
1654
|
+
* @param value - The thrown value to serialize (can be any type)
|
|
1383
1655
|
* @param runId - Run ID for encryption context
|
|
1384
1656
|
* @param key - Encryption key (undefined to skip encryption)
|
|
1385
1657
|
* @param global - Global object for serialization context
|
|
1386
|
-
* @param v1Compat - Enable legacy v1 compatibility mode
|
|
1387
1658
|
* @returns The dehydrated value as binary data (Uint8Array) with format prefix
|
|
1388
1659
|
*/
|
|
1389
|
-
export async function
|
|
1660
|
+
export async function dehydrateRunError(value, _runId, key, global = globalThis) {
|
|
1390
1661
|
try {
|
|
1391
1662
|
const str = stringify(value, getWorkflowReducers(global));
|
|
1392
|
-
if (v1Compat) {
|
|
1393
|
-
return revive(str);
|
|
1394
|
-
}
|
|
1395
1663
|
const payload = new TextEncoder().encode(str);
|
|
1396
1664
|
const serialized = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
|
|
1397
|
-
|
|
1398
|
-
return maybeEncrypt(serialized, key);
|
|
1665
|
+
return (await maybeEncrypt(serialized, key));
|
|
1399
1666
|
}
|
|
1400
1667
|
catch (error) {
|
|
1401
|
-
|
|
1668
|
+
const cause = unwrapSerializationCause(error);
|
|
1669
|
+
const { message, hint } = formatSerializationError('run error', cause);
|
|
1670
|
+
throw new SerializationError(message, { hint, cause });
|
|
1402
1671
|
}
|
|
1403
1672
|
}
|
|
1404
1673
|
/**
|
|
1405
|
-
* Called from the
|
|
1406
|
-
*
|
|
1674
|
+
* Called from the client side (or observability tools) to hydrate the run
|
|
1675
|
+
* error value of a failed workflow run.
|
|
1407
1676
|
*
|
|
1408
1677
|
* @param value - Binary serialized data (Uint8Array) with format prefix
|
|
1409
1678
|
* @param runId - Run ID for decryption context
|
|
@@ -1411,59 +1680,31 @@ export async function dehydrateStepArguments(value, _runId, key, global = global
|
|
|
1411
1680
|
* @param ops - Promise array for stream operations
|
|
1412
1681
|
* @param global - Global object for deserialization context
|
|
1413
1682
|
* @param extraRevivers - Additional revivers for custom types
|
|
1414
|
-
* @returns The hydrated value, ready to be consumed by the
|
|
1683
|
+
* @returns The hydrated thrown value, ready to be consumed by the client
|
|
1415
1684
|
*/
|
|
1416
|
-
export async function
|
|
1417
|
-
// Decrypt if needed
|
|
1685
|
+
export async function hydrateRunError(value, runId, key, ops = [], global = globalThis, extraRevivers = {}) {
|
|
1418
1686
|
const decrypted = await maybeDecrypt(value, key);
|
|
1419
|
-
// Legacy specVersion 1 runs stored data as plain JSON arrays (not binary).
|
|
1420
|
-
// These pass through maybeDecrypt unchanged and are deserialized directly
|
|
1421
|
-
// via devalue's unflatten().
|
|
1422
1687
|
if (!(decrypted instanceof Uint8Array)) {
|
|
1688
|
+
// See the matching note in `hydrateStepError`: this branch is for
|
|
1689
|
+
// devalue flattened arrays from legacy callers; current SDK versions
|
|
1690
|
+
// always emit a Uint8Array, and a misshapen value here intentionally
|
|
1691
|
+
// throws via `unflatten` so the surrounding try/catch in o11y helpers
|
|
1692
|
+
// surfaces the issue rather than masking it.
|
|
1423
1693
|
return unflatten(decrypted, {
|
|
1424
|
-
...
|
|
1694
|
+
...getExternalRevivers(global, ops, runId, key),
|
|
1425
1695
|
...extraRevivers,
|
|
1426
1696
|
});
|
|
1427
1697
|
}
|
|
1428
1698
|
const { format, payload } = decodeFormatPrefix(decrypted);
|
|
1429
1699
|
if (format === SerializationFormat.DEVALUE_V1) {
|
|
1430
1700
|
const str = new TextDecoder().decode(payload);
|
|
1431
|
-
|
|
1432
|
-
...
|
|
1701
|
+
return parse(str, {
|
|
1702
|
+
...getExternalRevivers(global, ops, runId, key),
|
|
1433
1703
|
...extraRevivers,
|
|
1434
1704
|
});
|
|
1435
|
-
return obj;
|
|
1436
1705
|
}
|
|
1437
1706
|
throw new Error(`Unsupported serialization format: ${format}`);
|
|
1438
1707
|
}
|
|
1439
|
-
/**
|
|
1440
|
-
* Called from the step handler when a step has completed.
|
|
1441
|
-
* Dehydrates values from within the step execution environment
|
|
1442
|
-
* into a format that can be saved to the database.
|
|
1443
|
-
*
|
|
1444
|
-
* @param value - The value to serialize
|
|
1445
|
-
* @param runId - Run ID for encryption context
|
|
1446
|
-
* @param key - Encryption key (undefined to skip encryption)
|
|
1447
|
-
* @param ops - Promise array for stream operations
|
|
1448
|
-
* @param global - Global object for serialization context
|
|
1449
|
-
* @param v1Compat - Enable legacy v1 compatibility mode
|
|
1450
|
-
* @returns The dehydrated value as binary data (Uint8Array) with format prefix
|
|
1451
|
-
*/
|
|
1452
|
-
export async function dehydrateStepReturnValue(value, runId, key, ops = [], global = globalThis, v1Compat = false) {
|
|
1453
|
-
try {
|
|
1454
|
-
const str = stringify(value, getStepReducers(global, ops, runId, key));
|
|
1455
|
-
if (v1Compat) {
|
|
1456
|
-
return revive(str);
|
|
1457
|
-
}
|
|
1458
|
-
const payload = new TextEncoder().encode(str);
|
|
1459
|
-
const serialized = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
|
|
1460
|
-
// Encrypt if world supports encryption
|
|
1461
|
-
return maybeEncrypt(serialized, key);
|
|
1462
|
-
}
|
|
1463
|
-
catch (error) {
|
|
1464
|
-
throw new WorkflowRuntimeError(formatSerializationError('step return value', error), { slug: 'serialization-failed', cause: error });
|
|
1465
|
-
}
|
|
1466
|
-
}
|
|
1467
1708
|
/**
|
|
1468
1709
|
* Called from the workflow handler when replaying the event log of a `step_completed` event.
|
|
1469
1710
|
* Hydrates the return value of a step from the database.
|
|
@@ -1473,28 +1714,53 @@ export async function dehydrateStepReturnValue(value, runId, key, ops = [], glob
|
|
|
1473
1714
|
* @param key - Encryption key (undefined to skip decryption)
|
|
1474
1715
|
* @param global - Global object for deserialization context
|
|
1475
1716
|
* @param extraRevivers - Additional revivers for custom types
|
|
1476
|
-
*
|
|
1717
|
+
* Called from the workflow handler when replaying the event log
|
|
1718
|
+
* of a `step_completed` event.
|
|
1477
1719
|
*/
|
|
1478
1720
|
export async function hydrateStepReturnValue(value, _runId, key, global = globalThis, extraRevivers = {}) {
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
// via devalue's unflatten().
|
|
1484
|
-
if (!(decrypted instanceof Uint8Array)) {
|
|
1485
|
-
return unflatten(decrypted, {
|
|
1486
|
-
...getWorkflowRevivers(global),
|
|
1721
|
+
return workflowModule.deserialize(await maybeDecrypt(value, key), {
|
|
1722
|
+
global,
|
|
1723
|
+
extraRevivers: {
|
|
1724
|
+
...getStreamAndRequestRevivers(getWorkflowRevivers(global)),
|
|
1487
1725
|
...extraRevivers,
|
|
1488
|
-
}
|
|
1726
|
+
},
|
|
1727
|
+
});
|
|
1728
|
+
}
|
|
1729
|
+
// ---- Helpers to extract stream/Request/Response reducers and revivers ----
|
|
1730
|
+
// The mode-specific get*Reducers/get*Revivers functions return objects that
|
|
1731
|
+
// include both "common" entries (Date, Error, Map, etc.) and mode-specific
|
|
1732
|
+
// entries (ReadableStream, WritableStream, Request, Response, StepFunction).
|
|
1733
|
+
// The common entries are already composed by the codec. We only need to
|
|
1734
|
+
// pass through the mode-specific entries as extraReducers/extraRevivers.
|
|
1735
|
+
const STREAM_AND_REQUEST_KEYS = [
|
|
1736
|
+
'ReadableStream',
|
|
1737
|
+
'WritableStream',
|
|
1738
|
+
'Request',
|
|
1739
|
+
'Response',
|
|
1740
|
+
'StepFunction',
|
|
1741
|
+
// Wire AbortController/AbortSignal through the client serialization path so
|
|
1742
|
+
// signals reachable via Request.signal (or as direct arguments) get their
|
|
1743
|
+
// dedicated reducer. Without this, devalue falls back to its arbitrary-POJO
|
|
1744
|
+
// path and fails for any signal the Request reducer forwards.
|
|
1745
|
+
'AbortController',
|
|
1746
|
+
'AbortSignal',
|
|
1747
|
+
];
|
|
1748
|
+
function getStreamAndRequestReducers(allReducers) {
|
|
1749
|
+
const extra = {};
|
|
1750
|
+
for (const key of STREAM_AND_REQUEST_KEYS) {
|
|
1751
|
+
if (key in allReducers) {
|
|
1752
|
+
extra[key] = allReducers[key];
|
|
1753
|
+
}
|
|
1489
1754
|
}
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1755
|
+
return extra;
|
|
1756
|
+
}
|
|
1757
|
+
function getStreamAndRequestRevivers(allRevivers) {
|
|
1758
|
+
const extra = {};
|
|
1759
|
+
for (const key of STREAM_AND_REQUEST_KEYS) {
|
|
1760
|
+
if (key in allRevivers) {
|
|
1761
|
+
extra[key] = allRevivers[key];
|
|
1762
|
+
}
|
|
1497
1763
|
}
|
|
1498
|
-
|
|
1764
|
+
return extra;
|
|
1499
1765
|
}
|
|
1500
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VyaWFsaXphdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zZXJpYWxpemF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDbEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDeEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLGtCQUFrQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0UsT0FBTyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNwRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDeEMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDakUsT0FBTyxFQUNMLE9BQU8sSUFBSSxhQUFhLEVBQ3hCLE9BQU8sSUFBSSxhQUFhLEdBRXpCLE1BQU0saUJBQWlCLENBQUM7QUFhekIsT0FBTyxFQUNMLG9CQUFvQixFQUNwQixhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLGdCQUFnQixHQUNqQixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDNUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUMvQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzNELE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsV0FBVyxFQUNYLGtCQUFrQixFQUNsQixrQkFBa0IsRUFDbEIseUJBQXlCLEdBQzFCLE1BQU0sY0FBYyxDQUFDO0FBRXRCLCtFQUErRTtBQUMvRSxxQ0FBcUM7QUFDckMsK0VBQStFO0FBQy9FLEVBQUU7QUFDRiw0RUFBNEU7QUFD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
|
|
1766
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VyaWFsaXphdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zZXJpYWxpemF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIsa0JBQWtCLEVBQ2xCLG9CQUFvQixHQUNyQixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN0RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDeEMsT0FBTyxFQUNMLE9BQU8sSUFBSSxhQUFhLEVBQ3hCLE9BQU8sSUFBSSxhQUFhLEVBRXhCLFNBQVMsR0FDVixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsYUFBYSxFQUNiLGdCQUFnQixFQUNoQixnQkFBZ0IsR0FDakIsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQy9DLDJFQUEyRTtBQUMzRSwwRUFBMEU7QUFDMUUsMEVBQTBFO0FBQzFFLDREQUE0RDtBQUM1RCxzRUFBc0U7QUFDdEUsc0RBQXNEO0FBQ3RELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMzRCxPQUFPLEtBQUssWUFBWSxNQUFNLDJCQUEyQixDQUFDO0FBQzFELE9BQU8sRUFDTCxPQUFPLEVBRVAsT0FBTyxHQUNSLE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUNMLHdCQUF3QixFQUN4QixxQkFBcUIsR0FDdEIsTUFBTSwyQkFBMkIsQ0FBQztBQUNuQyxPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLHNCQUFzQixFQUN0QixXQUFXLEVBQ1gsZ0JBQWdCLEdBQ2pCLE1BQU0sMkJBQTJCLENBQUM7QUFDbkMsT0FBTyxFQUNMLGdCQUFnQixFQUNoQixnQkFBZ0IsR0FDakIsTUFBTSxt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eUU7QUFFekUsTUFBTSx1QkFBdUIsR0FBRztJQUM5QixnQkFBZ0I7SUFDaEIsZ0JBQWdCO0lBQ2hCLFNBQVM7SUFDVCxVQUFVO0lBQ1YsY0FBYztJQUNkLDRFQUE0RTtJQUM1RSwwRUFBMEU7SUFDMUUsNEVBQTRFO0lBQzVFLDhEQUE4RDtJQUM5RCxpQkFBaUI7SUFDakIsYUFBYTtDQUNMLENBQUM7QUFFWCxTQUFTLDJCQUEyQixDQUNsQyxXQUFnQztJQUVoQyxNQUFNLEtBQUssR0FBd0MsRUFBRSxDQUFDO0lBQ3RELEtBQUssTUFBTSxHQUFHLElBQUksdUJBQXVCLEVBQUUsQ0FBQztRQUMxQyxJQUFJLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUN2QixLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2hDLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBRUQsU0FBUywyQkFBMkIsQ0FDbEMsV0FBZ0M7SUFFaEMsTUFBTSxLQUFLLEdBQXdDLEVBQUUsQ0FBQztJQUN0RCxLQUFLLE1BQU0sR0FBRyxJQUFJLHVCQUF1QixFQUFFLENBQUM7UUFDMUMsSUFBSSxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7WUFDdkIsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNoQyxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIFJ1bnRpbWVEZWNyeXB0aW9uRXJyb3IsXG4gIFNlcmlhbGl6YXRpb25FcnJvcixcbiAgV29ya2Zsb3dSdW50aW1lRXJyb3IsXG59IGZyb20gJ0B3b3JrZmxvdy9lcnJvcnMnO1xuaW1wb3J0IHsgcGFyc2UsIHN0cmluZ2lmeSwgdW5mbGF0dGVuIH0gZnJvbSAnZGV2YWx1ZSc7XG5pbXBvcnQgeyBtb25vdG9uaWNGYWN0b3J5IH0gZnJvbSAndWxpZCc7XG5pbXBvcnQge1xuICBkZWNyeXB0IGFzIGFlc0djbURlY3J5cHQsXG4gIGVuY3J5cHQgYXMgYWVzR2NtRW5jcnlwdCxcbiAgdHlwZSBDcnlwdG9LZXksXG4gIGltcG9ydEtleSxcbn0gZnJvbSAnLi9lbmNyeXB0aW9uLmpzJztcbmltcG9ydCB7XG4gIGNyZWF0ZUZsdXNoYWJsZVN0YXRlLFxuICBmbHVzaGFibGVQaXBlLFxuICBwb2xsUmVhZGFibGVMb2NrLFxuICBwb2xsV3JpdGFibGVMb2NrLFxufSBmcm9tICcuL2ZsdXNoYWJsZS1zdHJlYW0uanMnO1xuaW1wb3J0IHsgZ2V0U3RlcEZ1bmN0aW9uIH0gZnJvbSAnLi9wcml2YXRlLmpzJztcbi8vIFYyOiB1c2UgZ2V0V29ybGRMYXp5IGluIHN0ZXAtc2lkZSBjb2RlIHBhdGhzIHNvIFR1cmJvcGFjayBjYW4gc3RhdGljYWxseVxuLy8gcmVzb2x2ZSB0aGUgd29ybGQgYnJpZGdlIGZyb20gdGhlIHN0ZXAgYnVuZGxlIHdpdGhvdXQgZHJhZ2dpbmcgdGhlIGZ1bGxcbi8vIHdvcmxkLnRzIG1vZHVsZSAoYW5kIGl0cyBkeW5hbWljLWltcG9ydCBiZWhhdmlvdXIpIGludG8gdGhlIGZsb3cgcm91dGUuXG4vLyBTZWUgYHBhY2thZ2VzL2NvcmUvc3JjL3J1bnRpbWUvZ2V0LXdvcmxkLWxhenkudHNgIGFuZCB0aGVcbi8vIFwiVHVyYm9wYWNrIE5GVCBUcmFjaW5nIEVycm9ycyBpbiBWMiBDb21iaW5lZCBGbG93IFJvdXRlXCIgc2VjdGlvbiBvZlxuLy8gYGRvY3MvY29udGVudC9kb2NzL2NoYW5nZWxvZy9lYWdlci1wcm9jZXNzaW5nLm1keGAuXG5pbXBvcnQgeyBnZXRXb3JsZExhenkgfSBmcm9tICcuL3J1bnRpbWUvZ2V0LXdvcmxkLWxhenkuanMnO1xuaW1wb3J0ICogYXMgY2xpZW50TW9kdWxlIGZyb20gJy4vc2VyaWFsaXphdGlvbi9jbGllbnQuanMnO1xuaW1wb3J0IHtcbiAgZGVjcnlwdCxcbiAgdHlwZSBFbmNyeXB0aW9uS2V5UGFyYW0sXG4gIGVuY3J5cHQsXG59IGZyb20gJy4vc2VyaWFsaXphdGlvbi9lbmNyeXB0aW9uLmpzJztcbmltcG9ydCB7XG4gIGZvcm1hdFNlcmlhbGl6YXRpb25FcnJvcixcbiAgcmV0aHJvd0lmUnVudGltZUVycm9yLFxufSBmcm9tICcuL3NlcmlhbGl6YXRpb24vZXJyb3JzLmpzJztcbmltcG9ydCB7XG4gIGRlY29kZUZvcm1hdFByZWZpeCxcbiAgZW5jb2RlV2l0aEZvcm1hdFByZWZpeCxcbiAgaXNFbmNyeXB0ZWQsXG4gIHBlZWtGb3JtYXRQcmVmaXgsXG59IGZyb20gJy4vc2VyaWFsaXphdGlvbi9mb3JtYXQuanMnO1xuaW1wb3J0IHtcbiAgZ2V0Q2xhc3NSZWR1Y2VycyxcbiAgZ2V0Q2xhc3NSZXZpdmVycyxcbn0gZnJvbSAnLi9zZXJpYWxpemF0aW9uL3JlZHVjZXJzL2NsYXNzLmpzJztcbmltcG9ydCB7XG4gIGdldENvbW1vblJlZHVjZXJzLFxuICBnZXRDb21tb25SZXZpdmVycyBhcyBnZXRDb21tb25SZXZpdmVyc0Zyb21Nb2R1bGUsXG4gIHJldml2ZSxcbn0gZnJvbSAnLi9zZXJpYWxpemF0aW9uL3JlZHVjZXJzL2NvbW1vbi5qcyc7XG5pbXBvcnQge1xuICBnZXRTdGVwRnVuY3Rpb25SZWR1Y2VyLFxuICBnZXRTdGVwRnVuY3Rpb25SZXZpdmVyLFxufSBmcm9tICcuL3NlcmlhbGl6YXRpb24vcmVkdWNlcnMvc3RlcC1mdW5jdGlvbi5qcyc7XG5pbXBvcnQgKiBhcyBzdGVwTW9kdWxlIGZyb20gJy4vc2VyaWFsaXphdGlvbi9zdGVwLmpzJztcbmltcG9ydCB7XG4gIHR5cGUgRm9ybWF0UHJlZml4LFxuICBpc0Zvcm1hdFByZWZpeCxcbiAgU2VyaWFsaXphdGlvbkZvcm1hdCxcbn0gZnJvbSAnLi9zZXJpYWxpemF0aW9uL3R5cGVzLmpzJztcbmltcG9ydCAqIGFzIHdvcmtmbG93TW9kdWxlIGZyb20gJy4vc2VyaWFsaXphdGlvbi93b3JrZmxvdy5qcyc7XG5pbXBvcnQgeyBjb250ZXh0U3RvcmFnZSB9IGZyb20gJy4vc3RlcC9jb250ZXh0LXN0b3JhZ2UuanMnO1xuaW1wb3J0IHtcbiAgQUJPUlRfSE9PS19UT0tFTixcbiAgQUJPUlRfTElTVEVORVJfQVRUQUNIRUQsXG4gIEFCT1JUX1JFQURFUl9DQU5DRUwsXG4gIEFCT1JUX1NUUkVBTV9OQU1FLFxuICBCT0RZX0lOSVRfU1lNQk9MLFxuICBTVEFCTEVfVUxJRCxcbiAgU1RSRUFNX05BTUVfU1lNQk9MLFxuICBTVFJFQU1fU0VSVkVSX1JVTl9JRF9TWU1CT0wsXG4gIFNUUkVBTV9UWVBFX1NZTUJPTCxcbiAgV0VCSE9PS19SRVNQT05TRV9XUklUQUJMRSxcbn0gZnJvbSAnLi9zeW1ib2xzLmpzJztcbmltcG9ydCB7IGdldEFib3J0U3RyZWFtSWQgfSBmcm9tICcuL3V0aWwuanMnO1xuaW1wb3J0IHsgV29ya2Zsb3dBYm9ydFNpZ25hbCB9IGZyb20gJy4vd29ya2Zsb3cvYWJvcnQtY29udHJvbGxlci5qcyc7XG5cbi8vIFJlLWV4cG9ydCB0eXBlcyBhbmQgdXRpbGl0aWVzIGZyb20gdGhlIG1vZHVsYXIgc2VyaWFsaXphdGlvbiBtb2R1bGVzXG4vLyBzbyBleGlzdGluZyBjb25zdW1lcnMgb2YgYEB3b3JrZmxvdy9jb3JlL3NlcmlhbGl6YXRpb25gIGtlZXAgd29ya2luZy5cbmV4cG9ydCB7XG4gIFNlcmlhbGl6YXRpb25Gb3JtYXQsXG4gIHR5cGUgRm9ybWF0UHJlZml4LFxuICBpc0Zvcm1hdFByZWZpeCxcbiAgZW5jb2RlV2l0aEZvcm1hdFByZWZpeCxcbiAgZGVjb2RlRm9ybWF0UHJlZml4LFxuICBwZWVrRm9ybWF0UHJlZml4LFxuICBpc0VuY3J5cHRlZCxcbiAgZW5jcnlwdCxcbiAgZGVjcnlwdCxcbiAgdHlwZSBFbmNyeXB0aW9uS2V5UGFyYW0sXG59O1xuXG4vLyBSZS1leHBvcnQgdGhlIGxlZ2FjeSBTZXJpYWxpemF0aW9uRm9ybWF0VHlwZSBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkuXG4vLyBOZXcgY29kZSBzaG91bGQgdXNlIEZvcm1hdFByZWZpeCBmcm9tICcuL3NlcmlhbGl6YXRpb24vdHlwZXMuanMnLlxuZXhwb3J0IHR5cGUgU2VyaWFsaXphdGlvbkZvcm1hdFR5cGUgPVxuICAodHlwZW9mIFNlcmlhbGl6YXRpb25Gb3JtYXQpW2tleW9mIHR5cGVvZiBTZXJpYWxpemF0aW9uRm9ybWF0XTtcblxuLyoqXG4gKiBEZWZhdWx0IFVMSUQgZ2VuZXJhdG9yIGZvciBjb250ZXh0cyB3aGVyZSBWTSdzIHNlZWRlZCBgc3RhYmxlVWxpZGAgaXNuJ3QgYXZhaWxhYmxlLlxuICogVXNlZCBhcyBhIGZhbGxiYWNrIHdoZW4gc2VyaWFsaXppbmcgc3RyZWFtcyBvdXRzaWRlIHRoZSB3b3JrZmxvdyBWTSBjb250ZXh0XG4gKiAoZS5nLiwgd2hlbiBzdGFydGluZyBhIHdvcmtmbG93IG9yIGhhbmRsaW5nIHN0ZXAgcmV0dXJuIHZhbHVlcykuXG4gKi9cbmNvbnN0IGRlZmF1bHRVbGlkID0gbW9ub3RvbmljRmFjdG9yeSgpO1xuXG4vKipcbiAqIERldGVjdCBpZiBhIHJlYWRhYmxlIHN0cmVhbSBpcyBhIGJ5dGUgc3RyZWFtLlxuICpcbiAqIEBwYXJhbSBzdHJlYW1cbiAqIEByZXR1cm5zIGBcImJ5dGVzXCJgIGlmIHRoZSBzdHJlYW0gaXMgYSBieXRlIHN0cmVhbSwgYHVuZGVmaW5lZGAgb3RoZXJ3aXNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTdHJlYW1UeXBlKHN0cmVhbTogUmVhZGFibGVTdHJlYW0pOiAnYnl0ZXMnIHwgdW5kZWZpbmVkIHtcbiAgdHJ5IHtcbiAgICBjb25zdCByZWFkZXIgPSBzdHJlYW0uZ2V0UmVhZGVyKHsgbW9kZTogJ2J5b2InIH0pO1xuICAgIHJlYWRlci5yZWxlYXNlTG9jaygpO1xuICAgIHJldHVybiAnYnl0ZXMnO1xuICB9IGNhdGNoIHt9XG59XG5cbi8qKlxuICogRnJhbWUgZm9ybWF0IGZvciBzdHJlYW0gY2h1bmtzOlxuICogICBbNC1ieXRlIGJpZy1lbmRpYW4gbGVuZ3RoXVtmb3JtYXQtcHJlZml4ZWQgcGF5bG9hZF1cbiAqXG4gKiBFYWNoIGNodW5rIGlzIGluZGVwZW5kZW50bHkgZnJhbWVkIHNvIHRoZSBkZXNlcmlhbGl6ZXIgY2FuIGZpbmRcbiAqIGNodW5rIGJvdW5kYXJpZXMgZXZlbiB3aGVuIG11bHRpcGxlIGNodW5rcyBhcmUgY29uY2F0ZW5hdGVkIG9yXG4gKiBzcGxpdCBhY3Jvc3MgdHJhbnNwb3J0IHJlYWRzLlxuICovXG5jb25zdCBGUkFNRV9IRUFERVJfU0laRSA9IDQ7XG5cbi8qKlxuICogVGhlIG1vZGUtc3BlY2lmaWMgc2VyaWFsaXplcnMgKGAuL3NlcmlhbGl6YXRpb24ve2NsaWVudCxzdGVwLHdvcmtmbG93fS50c2ApXG4gKiBhbHJlYWR5IHRocm93IGEgYFNlcmlhbGl6YXRpb25FcnJvcmAgd2hvc2UgYC5jYXVzZWAgaXMgdGhlIHVuZGVybHlpbmdcbiAqIGRldmFsdWUgLyBzZXJkZSBmYWlsdXJlLiBUaGUgb3V0ZXIgZGVoeWRyYXRlL2h5ZHJhdGUgd3JhcHBlcnMgd2FudCB0b1xuICogcmUtZnJhbWUgdGhhdCBlcnJvciB3aXRoIGEgbW9yZSBzcGVjaWZpYyBjb250ZXh0IGxhYmVsIChlLmcuIFwid29ya2Zsb3dcbiAqIGFyZ3VtZW50c1wiIGluc3RlYWQgb2YgZ2VuZXJpYyBcIndvcmtmbG93IHZhbHVlXCIpLCBzbyB0aGV5IHVud3JhcCB0aGVcbiAqIGlubmVyIFNlcmlhbGl6YXRpb25FcnJvciBhbmQgcmVmb3JtYXQgd2l0aCB0aGUgb3JpZ2luYWwgY2F1c2UuIEVycm9yc1xuICogdGhhdCBhcmVuJ3QgYWxyZWFkeSBTZXJpYWxpemF0aW9uRXJyb3IgZmxvdyB0aHJvdWdoIHVuY2hhbmdlZC5cbiAqXG4gKiBgUnVudGltZURlY3J5cHRpb25FcnJvcmAgaXMgYW4gZXhjZXB0aW9uOiBpdCBtdXN0IGtlZXAgaXRzIGlkZW50aXR5IChhbmRcbiAqIGBjb250ZXh0YCkgc28gdGhlIHJ1bi1mYWlsdXJlIGNsYXNzaWZpZXIgcm91dGVzIGl0IHRvIGBSVU5USU1FX0VSUk9SYCxcbiAqIHNvIHRoaXMgcmV0aHJvd3MgaXQgdW5jaGFuZ2VkIGJlZm9yZSBhbnkgdW53cmFwcGluZy4gTm90ZSB0aGlzIGd1YXJkXG4gKiBtdXN0IHJ1biBiZWZvcmUgdGhlIGdlbmVyaWMgYFdvcmtmbG93UnVudGltZUVycm9yYCB1bndyYXAgYmVsb3csIHNpbmNlXG4gKiBgUnVudGltZURlY3J5cHRpb25FcnJvcmAgZXh0ZW5kcyBgV29ya2Zsb3dSdW50aW1lRXJyb3JgIGFuZCBjYXJyaWVzIGFcbiAqIGBjYXVzZWAgKHRoZSB1bmRlcmx5aW5nIERPTUV4Y2VwdGlvbikgdGhhdCB3b3VsZCBvdGhlcndpc2UgYmUgdW53cmFwcGVkXG4gKiBhbmQgcmVmcmFtZWQgYXMgYSBgU2VyaWFsaXphdGlvbkVycm9yYC5cbiAqL1xuZnVuY3Rpb24gdW53cmFwU2VyaWFsaXphdGlvbkNhdXNlKGVycm9yOiB1bmtub3duKTogdW5rbm93biB7XG4gIHJldGhyb3dJZlJ1bnRpbWVFcnJvcihlcnJvcik7XG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIFNlcmlhbGl6YXRpb25FcnJvciAmJiBlcnJvci5jYXVzZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGVycm9yLmNhdXNlO1xuICB9XG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIFdvcmtmbG93UnVudGltZUVycm9yICYmIGVycm9yLmNhdXNlICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gZXJyb3IuY2F1c2U7XG4gIH1cbiAgcmV0dXJuIGVycm9yO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2VyaWFsaXplU3RyZWFtKFxuICByZWR1Y2VyczogUGFydGlhbDxSZWR1Y2Vycz4sXG4gIGNyeXB0b0tleTogRW5jcnlwdGlvbktleVBhcmFtXG4pOiBUcmFuc2Zvcm1TdHJlYW08YW55LCBVaW50OEFycmF5PiB7XG4gIGNvbnN0IGVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcbiAgLy8gUmVzb2x2ZSB0aGUga2V5IHByb21pc2Ugb25jZSBvbiBmaXJzdCB1c2UgYW5kIGNhY2hlIHRoZSByZXN1bHQuXG4gIC8vIE5vdGU6IGlmIHRoZSBjcnlwdG9LZXkgcHJvbWlzZSByZWplY3RzIChlLmcuLCBuZXR3b3JrIGVycm9yIGZldGNoaW5nXG4gIC8vIHRoZSBkZXJpdmVkIGtleSksIHRoZSByZWplY3Rpb24gd29uJ3Qgc3VyZmFjZSB1bnRpbCB0aGUgZmlyc3QgY2h1bmtcbiAgLy8gaXMgcHJvY2Vzc2VkIOKAlCBub3QgYXQgc3RyZWFtIGNvbnN0cnVjdGlvbiB0aW1lLlxuICBjb25zdCBrZXlTdGF0ZSA9IHsgcmVzb2x2ZWQ6IGZhbHNlLCBrZXk6IHVuZGVmaW5lZCBhcyBDcnlwdG9LZXkgfCB1bmRlZmluZWQgfTtcbiAgY29uc3Qgc3RyZWFtID0gbmV3IFRyYW5zZm9ybVN0cmVhbTxhbnksIFVpbnQ4QXJyYXk+KHtcbiAgICBhc3luYyB0cmFuc2Zvcm0oY2h1bmssIGNvbnRyb2xsZXIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICgha2V5U3RhdGUucmVzb2x2ZWQpIHtcbiAgICAgICAgICBrZXlTdGF0ZS5rZXkgPSBhd2FpdCBjcnlwdG9LZXk7XG4gICAgICAgICAga2V5U3RhdGUucmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSBzdHJpbmdpZnkoY2h1bmssIHJlZHVjZXJzKTtcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IGVuY29kZXIuZW5jb2RlKHNlcmlhbGl6ZWQpO1xuICAgICAgICBsZXQgcHJlZml4ZWQgPSBlbmNvZGVXaXRoRm9ybWF0UHJlZml4KFxuICAgICAgICAgIFNlcmlhbGl6YXRpb25Gb3JtYXQuREVWQUxVRV9WMSxcbiAgICAgICAgICBwYXlsb2FkXG4gICAgICAgICkgYXMgVWludDhBcnJheTtcblxuICAgICAgICAvLyBFbmNyeXB0IHRoZSBmcmFtZSBwYXlsb2FkIGlmIGEga2V5IGlzIHByb3ZpZGVkLlxuICAgICAgICAvLyBUaGUgbGVuZ3RoIGhlYWRlciByZW1haW5zIGluIHRoZSBjbGVhciBzbyB0aGUgZGVzZXJpYWxpemVyIGNhblxuICAgICAgICAvLyBmaW5kIGZyYW1lIGJvdW5kYXJpZXMgcmVnYXJkbGVzcyBvZiB0cmFuc3BvcnQgY2h1bmtpbmcuXG4gICAgICAgIGlmIChrZXlTdGF0ZS5rZXkpIHtcbiAgICAgICAgICBjb25zdCBlbmNyeXB0ZWQgPSBhd2FpdCBhZXNHY21FbmNyeXB0KGtleVN0YXRlLmtleSwgcHJlZml4ZWQpO1xuICAgICAgICAgIHByZWZpeGVkID0gZW5jb2RlV2l0aEZvcm1hdFByZWZpeChcbiAgICAgICAgICAgIFNlcmlhbGl6YXRpb25Gb3JtYXQuRU5DUllQVEVELFxuICAgICAgICAgICAgZW5jcnlwdGVkXG4gICAgICAgICAgKSBhcyBVaW50OEFycmF5O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gV3JpdGUgbGVuZ3RoLXByZWZpeGVkIGZyYW1lOiBbNC1ieXRlIGxlbmd0aF1bcHJlZml4ZWQgZGF0YV1cbiAgICAgICAgY29uc3QgZnJhbWUgPSBuZXcgVWludDhBcnJheShGUkFNRV9IRUFERVJfU0laRSArIHByZWZpeGVkLmxlbmd0aCk7XG4gICAgICAgIG5ldyBEYXRhVmlldyhmcmFtZS5idWZmZXIpLnNldFVpbnQzMigwLCBwcmVmaXhlZC5sZW5ndGgsIGZhbHNlKTtcbiAgICAgICAgZnJhbWUuc2V0KHByZWZpeGVkLCBGUkFNRV9IRUFERVJfU0laRSk7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShmcmFtZSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBFbmNyeXB0aW9uIGZhaWx1cmVzIG11c3Qga2VlcCB0aGVpciBSdW50aW1lRGVjcnlwdGlvbkVycm9yXG4gICAgICAgIC8vIGlkZW50aXR5IChSVU5USU1FX0VSUk9SKSByYXRoZXIgdGhhbiBiZSByZWZyYW1lZCBhcyBhXG4gICAgICAgIC8vIFNlcmlhbGl6YXRpb25FcnJvciAoVVNFUl9FUlJPUikuXG4gICAgICAgIGlmIChSdW50aW1lRGVjcnlwdGlvbkVycm9yLmlzKGVycm9yKSkge1xuICAgICAgICAgIGNvbnRyb2xsZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IG1lc3NhZ2UsIGhpbnQgfSA9IGZvcm1hdFNlcmlhbGl6YXRpb25FcnJvcihcbiAgICAgICAgICAnc3RyZWFtIGNodW5rJyxcbiAgICAgICAgICBlcnJvclxuICAgICAgICApO1xuICAgICAgICBjb250cm9sbGVyLmVycm9yKFxuICAgICAgICAgIG5ldyBTZXJpYWxpemF0aW9uRXJyb3IobWVzc2FnZSwgeyBoaW50LCBjYXVzZTogZXJyb3IgfSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcbiAgcmV0dXJuIHN0cmVhbTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERlc2VyaWFsaXplU3RyZWFtKFxuICByZXZpdmVyczogUGFydGlhbDxSZXZpdmVycz4sXG4gIGNyeXB0b0tleTogRW5jcnlwdGlvbktleVBhcmFtXG4pOiBUcmFuc2Zvcm1TdHJlYW08VWludDhBcnJheSwgYW55PiB7XG4gIGNvbnN0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKTtcbiAgbGV0IGJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KDApO1xuICAvLyBSZXNvbHZlIHRoZSBrZXkgcHJvbWlzZSBvbmNlIG9uIGZpcnN0IHVzZSBhbmQgY2FjaGUgdGhlIHJlc3VsdC5cbiAgY29uc3Qga2V5U3RhdGUgPSB7IHJlc29sdmVkOiBmYWxzZSwga2V5OiB1bmRlZmluZWQgYXMgQ3J5cHRvS2V5IHwgdW5kZWZpbmVkIH07XG5cbiAgZnVuY3Rpb24gYXBwZW5kVG9CdWZmZXIoZGF0YTogVWludDhBcnJheSkge1xuICAgIGNvbnN0IG5ld0J1ZmZlciA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlci5sZW5ndGggKyBkYXRhLmxlbmd0aCk7XG4gICAgbmV3QnVmZmVyLnNldChidWZmZXIsIDApO1xuICAgIG5ld0J1ZmZlci5zZXQoZGF0YSwgYnVmZmVyLmxlbmd0aCk7XG4gICAgYnVmZmVyID0gbmV3QnVmZmVyO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gcHJvY2Vzc0ZyYW1lcyhcbiAgICBjb250cm9sbGVyOiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcjxhbnk+XG4gICkge1xuICAgIC8vIFJlc29sdmUgdGhlIGtleSBwcm9taXNlIG9uY2Ugb24gZmlyc3QgdXNlIGFuZCBjYWNoZSB0aGUgcmVzdWx0XG4gICAgaWYgKCFrZXlTdGF0ZS5yZXNvbHZlZCkge1xuICAgICAga2V5U3RhdGUua2V5ID0gYXdhaXQgY3J5cHRvS2V5O1xuICAgICAga2V5U3RhdGUucmVzb2x2ZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIC8vIFRyeSB0byBleHRyYWN0IGNvbXBsZXRlIGxlbmd0aC1wcmVmaXhlZCBmcmFtZXNcbiAgICB3aGlsZSAoYnVmZmVyLmxlbmd0aCA+PSBGUkFNRV9IRUFERVJfU0laRSkge1xuICAgICAgY29uc3QgZnJhbWVMZW5ndGggPSBuZXcgRGF0YVZpZXcoXG4gICAgICAgIGJ1ZmZlci5idWZmZXIsXG4gICAgICAgIGJ1ZmZlci5ieXRlT2Zmc2V0LFxuICAgICAgICBidWZmZXIuYnl0ZUxlbmd0aFxuICAgICAgKS5nZXRVaW50MzIoMCwgZmFsc2UpO1xuXG4gICAgICBpZiAoYnVmZmVyLmxlbmd0aCA8IEZSQU1FX0hFQURFUl9TSVpFICsgZnJhbWVMZW5ndGgpIHtcbiAgICAgICAgYnJlYWs7IC8vIEluY29tcGxldGUgZnJhbWUsIHdhaXQgZm9yIG1vcmUgZGF0YVxuICAgICAgfVxuXG4gICAgICBjb25zdCBmcmFtZURhdGEgPSBidWZmZXIuc2xpY2UoXG4gICAgICAgIEZSQU1FX0hFQURFUl9TSVpFLFxuICAgICAgICBGUkFNRV9IRUFERVJfU0laRSArIGZyYW1lTGVuZ3RoXG4gICAgICApO1xuICAgICAgYnVmZmVyID0gYnVmZmVyLnNsaWNlKEZSQU1FX0hFQURFUl9TSVpFICsgZnJhbWVMZW5ndGgpO1xuXG4gICAgICBsZXQgeyBmb3JtYXQsIHBheWxvYWQgfSA9IGRlY29kZUZvcm1hdFByZWZpeChmcmFtZURhdGEpO1xuXG4gICAgICAvLyBJZiB0aGUgZnJhbWUgcGF5bG9hZCBpcyBlbmNyeXB0ZWQsIGRlY3J5cHQgaXQgZmlyc3QgdG8gcmV2ZWFsXG4gICAgICAvLyB0aGUgaW5uZXIgZm9ybWF0LXByZWZpeGVkIGRhdGEgKGUuZy4sICdkZXZsJyArIHNlcmlhbGl6ZWQgdGV4dCksXG4gICAgICAvLyB0aGVuIGZhbGwgdGhyb3VnaCB0byB0aGUgbm9ybWFsIGRlc2VyaWFsaXphdGlvbiBwYXRoLlxuICAgICAgaWYgKGZvcm1hdCA9PT0gU2VyaWFsaXphdGlvbkZvcm1hdC5FTkNSWVBURUQpIHtcbiAgICAgICAgaWYgKCFrZXlTdGF0ZS5rZXkpIHtcbiAgICAgICAgICBjb250cm9sbGVyLmVycm9yKFxuICAgICAgICAgICAgbmV3IFJ1bnRpbWVEZWNyeXB0aW9uRXJyb3IoXG4gICAgICAgICAgICAgICdFbmNyeXB0ZWQgc3RyZWFtIGRhdGEgZW5jb3VudGVyZWQgYnV0IG5vIGVuY3J5cHRpb24ga2V5IGlzIGF2YWlsYWJsZS4gJyArXG4gICAgICAgICAgICAgICAgJ0VuY3J5cHRpb24gaXMgbm90IGNvbmZpZ3VyZWQgb3Igbm8ga2V5IHdhcyBwcm92aWRlZCBmb3IgdGhpcyBydW4uJyxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbjogJ2RlY3J5cHQnLFxuICAgICAgICAgICAgICAgICAgYnl0ZUxlbmd0aDogcGF5bG9hZC5ieXRlTGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgZm9ybWF0UHJlZml4OiAnZW5jcicsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxldCBkZWNyeXB0ZWQ6IFVpbnQ4QXJyYXk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZGVjcnlwdGVkID0gYXdhaXQgYWVzR2NtRGVjcnlwdChrZXlTdGF0ZS5rZXksIHBheWxvYWQpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIC8vIFRoZSBsb3ctbGV2ZWwgQUVTIGxheWVyIG9ubHkgc2VlcyB0aGUgc3RyaXBwZWQgcGF5bG9hZCwgc28gaXRcbiAgICAgICAgICAvLyBjYW5ub3QgcmVjb3JkIHRoZSBvdXRlciBlbnZlbG9wZSBwcmVmaXguIFdlIHBlZWtlZCBpdCBoZXJlXG4gICAgICAgICAgLy8gKGBlbmNyYCksIHNvIGVucmljaCB0aGUgZGlhZ25vc3RpYyBjb250ZXh0IHdpdGggdGhlIHJlYWwgZm9ybWF0XG4gICAgICAgICAgLy8gcHJlZml4IGJlZm9yZSBwcm9wYWdhdGluZyDigJQgbWlycm9yaW5nIHNlcmlhbGl6YXRpb24vZW5jcnlwdGlvbi50cy5cbiAgICAgICAgICBpZiAoUnVudGltZURlY3J5cHRpb25FcnJvci5pcyhlcnJvcikgJiYgZXJyb3IuY29udGV4dCkge1xuICAgICAgICAgICAgZXJyb3IuY29udGV4dC5mb3JtYXRQcmVmaXggPSBmb3JtYXQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgICh7IGZvcm1hdCwgcGF5bG9hZCB9ID0gZGVjb2RlRm9ybWF0UHJlZml4KGRlY3J5cHRlZCkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZm9ybWF0ID09PSBTZXJpYWxpemF0aW9uRm9ybWF0LkRFVkFMVUVfVjEpIHtcbiAgICAgICAgY29uc3QgdGV4dCA9IGRlY29kZXIuZGVjb2RlKHBheWxvYWQpO1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUocGFyc2UodGV4dCwgcmV2aXZlcnMpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBzdHJlYW0gPSBuZXcgVHJhbnNmb3JtU3RyZWFtPFVpbnQ4QXJyYXksIGFueT4oe1xuICAgIGFzeW5jIHRyYW5zZm9ybShjaHVuaywgY29udHJvbGxlcikge1xuICAgICAgLy8gRmlyc3QsIHRyeSB0byBkZXRlY3QgaWYgdGhpcyBpcyBsZW5ndGgtcHJlZml4ZWQgZnJhbWVkIGRhdGFcbiAgICAgIC8vIGJ5IGNoZWNraW5nIGlmIHRoZSBmaXJzdCA0IGJ5dGVzIGZvcm0gYSBwbGF1c2libGUgbGVuZ3RoLlxuICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDAgJiYgY2h1bmsubGVuZ3RoID49IEZSQU1FX0hFQURFUl9TSVpFKSB7XG4gICAgICAgIGNvbnN0IHBvc3NpYmxlTGVuZ3RoID0gbmV3IERhdGFWaWV3KFxuICAgICAgICAgIGNodW5rLmJ1ZmZlcixcbiAgICAgICAgICBjaHVuay5ieXRlT2Zmc2V0LFxuICAgICAgICAgIGNodW5rLmJ5dGVMZW5ndGhcbiAgICAgICAgKS5nZXRVaW50MzIoMCwgZmFsc2UpO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgcG9zc2libGVMZW5ndGggPiAwICYmXG4gICAgICAgICAgcG9zc2libGVMZW5ndGggPCAxMDBfMDAwXzAwMCAvLyBzYW5pdHkgY2hlY2s6IDwgMTAwTUJcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gTG9va3MgbGlrZSBmcmFtZWQgZGF0YVxuICAgICAgICAgIGFwcGVuZFRvQnVmZmVyKGNodW5rKTtcbiAgICAgICAgICBhd2FpdCBwcm9jZXNzRnJhbWVzKGNvbnRyb2xsZXIpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChidWZmZXIubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyBBbHJlYWR5IGluIGZyYW1lZCBtb2RlIChoYXZlIGJ1ZmZlcmVkIGRhdGEpXG4gICAgICAgIGFwcGVuZFRvQnVmZmVyKGNodW5rKTtcbiAgICAgICAgYXdhaXQgcHJvY2Vzc0ZyYW1lcyhjb250cm9sbGVyKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBMZWdhY3kgZm9ybWF0OiBuZXdsaW5lLWRlbGltaXRlZCBkZXZhbHVlIHRleHQgKG5vIGZyYW1pbmcpXG4gICAgICBjb25zdCB0ZXh0ID0gZGVjb2Rlci5kZWNvZGUoY2h1bmspO1xuICAgICAgY29uc3QgbGluZXMgPSB0ZXh0LnNwbGl0KCdcXG4nKTtcbiAgICAgIGZvciAoY29uc3QgbGluZSBvZiBsaW5lcykge1xuICAgICAgICBpZiAobGluZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHBhcnNlKGxpbmUsIHJldml2ZXJzKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICAgIGFzeW5jIGZsdXNoKGNvbnRyb2xsZXIpIHtcbiAgICAgIC8vIFByb2Nlc3MgYW55IHJlbWFpbmluZyBmcmFtZWQgZGF0YVxuICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPiAwKSB7XG4gICAgICAgIGF3YWl0IHByb2Nlc3NGcmFtZXMoY29udHJvbGxlcik7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG4gIHJldHVybiBzdHJlYW07XG59XG5cbmV4cG9ydCBjbGFzcyBXb3JrZmxvd1NlcnZlclJlYWRhYmxlU3RyZWFtIGV4dGVuZHMgUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4ge1xuICAjcmVhZGVyPzogUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyPFVpbnQ4QXJyYXk+O1xuXG4gIGNvbnN0cnVjdG9yKHJ1bklkOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgc3RhcnRJbmRleD86IG51bWJlcikge1xuICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycgfHwgbmFtZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcihgXCJuYW1lXCIgaXMgcmVxdWlyZWQsIGdvdCBcIiR7bmFtZX1cImApO1xuICAgIH1cbiAgICBzdXBlcih7XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIE5vdCBzdXJlIHdoeSBUeXBlU2NyaXB0IGlzIGNvbXBsYWluaW5nIGFib3V0IHRoaXNcbiAgICAgIHR5cGU6ICdieXRlcycsXG5cbiAgICAgIHB1bGw6IGFzeW5jIChjb250cm9sbGVyKSA9PiB7XG4gICAgICAgIGxldCByZWFkZXIgPSB0aGlzLiNyZWFkZXI7XG4gICAgICAgIGlmICghcmVhZGVyKSB7XG4gICAgICAgICAgY29uc3Qgd29ybGQgPSBhd2FpdCBnZXRXb3JsZExhenkoKTtcbiAgICAgICAgICBjb25zdCBzdHJlYW0gPSBhd2FpdCB3b3JsZC5zdHJlYW1zLmdldChydW5JZCwgbmFtZSwgc3RhcnRJbmRleCk7XG4gICAgICAgICAgcmVhZGVyID0gdGhpcy4jcmVhZGVyID0gc3RyZWFtLmdldFJlYWRlcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcmVhZGVyKSB7XG4gICAgICAgICAgY29udHJvbGxlci5lcnJvcihuZXcgRXJyb3IoJ0ZhaWxlZCB0byBnZXQgcmVhZGVyJykpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlYWRlci5yZWFkKCk7XG4gICAgICAgIGlmIChyZXN1bHQuZG9uZSkge1xuICAgICAgICAgIHRoaXMuI3JlYWRlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBjb250cm9sbGVyLmNsb3NlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gRm9yd2FyZCByYXcgYnl0ZXM7IGVuY3J5cHRpb24vZGVjcnlwdGlvbiBpcyBoYW5kbGVkIGF0IHRoZVxuICAgICAgICAgIC8vIGZyYW1pbmcgbGV2ZWwgYnkgZ2V0U2VyaWFsaXplU3RyZWFtL2dldERlc2VyaWFsaXplU3RyZWFtLlxuICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShyZXN1bHQudmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FuY2VsOiBhc3luYyAocmVhc29uKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLiNyZWFkZXIpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLiNyZWFkZXIuY2FuY2VsKHJlYXNvbikuY2F0Y2goKCkgPT4ge30pO1xuICAgICAgICAgIHRoaXMuI3JlYWRlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIERlZmF1bHQgZmx1c2ggaW50ZXJ2YWwgaW4gbWlsbGlzZWNvbmRzIGZvciBidWZmZXJlZCBzdHJlYW0gd3JpdGVzLlxuICogQ2h1bmtzIGFyZSBhY2N1bXVsYXRlZCBhbmQgZmx1c2hlZCB0b2dldGhlciB0byByZWR1Y2UgbmV0d29yayBvdmVyaGVhZC5cbiAqL1xuY29uc3QgU1RSRUFNX0ZMVVNIX0lOVEVSVkFMX01TID0gMTA7XG5cbmV4cG9ydCBjbGFzcyBXb3JrZmxvd1NlcnZlcldyaXRhYmxlU3RyZWFtIGV4dGVuZHMgV3JpdGFibGVTdHJlYW08VWludDhBcnJheT4ge1xuICBjb25zdHJ1Y3RvcihydW5JZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcpIHtcbiAgICBpZiAodHlwZW9mIHJ1bklkICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKFxuICAgICAgICBgXCJydW5JZFwiIG11c3QgYmUgYSBzdHJpbmcsIGdvdCBcIiR7dHlwZW9mIHJ1bklkfVwiYFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJyB8fCBuYW1lLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKGBcIm5hbWVcIiBpcyByZXF1aXJlZCwgZ290IFwiJHtuYW1lfVwiYCk7XG4gICAgfVxuICAgIGNvbnN0IHdvcmxkUHJvbWlzZSA9IGdldFdvcmxkTGF6eSgpO1xuXG4gICAgLy8gQnVmZmVyaW5nIHN0YXRlIGZvciBiYXRjaGVkIHdyaXRlc1xuICAgIC8vIEVuY3J5cHRpb24vZGVjcnlwdGlvbiBpcyBoYW5kbGVkIGF0IHRoZSBmcmFtaW5nIGxldmVsIGJ5XG4gICAgLy8gZ2V0U2VyaWFsaXplU3RyZWFtL2dldERlc2VyaWFsaXplU3RyZWFtLCBub3QgaGVyZS5cbiAgICBsZXQgYnVmZmVyOiBVaW50OEFycmF5W10gPSBbXTtcbiAgICBsZXQgZmx1c2hUaW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCBudWxsID0gbnVsbDtcbiAgICBsZXQgZmx1c2hQcm9taXNlOiBQcm9taXNlPHZvaWQ+IHwgbnVsbCA9IG51bGw7XG4gICAgbGV0IHJlc29sdmVkRmx1c2hJbnRlcnZhbE1zOiBudW1iZXIgfCB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBmbHVzaCA9IGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgIGlmIChmbHVzaFRpbWVyKSB7XG4gICAgICAgIGNsZWFyVGltZW91dChmbHVzaFRpbWVyKTtcbiAgICAgICAgZmx1c2hUaW1lciA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmIChidWZmZXIubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICAgIC8vIENvcHkgY2h1bmtzIHRvIGZsdXNoLCBidXQgZG9uJ3QgY2xlYXIgYnVmZmVyIHVudGlsIHdyaXRlIHN1Y2NlZWRzXG4gICAgICAvLyBUaGlzIHByZXZlbnRzIGRhdGEgbG9zcyBpZiB0aGUgd3JpdGUgb3BlcmF0aW9uIGZhaWxzXG4gICAgICBjb25zdCBjaHVua3NUb0ZsdXNoID0gYnVmZmVyLnNsaWNlKCk7XG5cbiAgICAgIGNvbnN0IHdvcmxkID0gYXdhaXQgd29ybGRQcm9taXNlO1xuICAgICAgLy8gQ2FjaGUgdGhlIGZsdXNoIGludGVydmFsIGZyb20gdGhlIHdvcmxkIG9uIGZpcnN0IHVzZVxuICAgICAgaWYgKHJlc29sdmVkRmx1c2hJbnRlcnZhbE1zID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmVzb2x2ZWRGbHVzaEludGVydmFsTXMgPVxuICAgICAgICAgIHdvcmxkLnN0cmVhbUZsdXNoSW50ZXJ2YWxNcyA/PyBTVFJFQU1fRkxVU0hfSU5URVJWQUxfTVM7XG4gICAgICB9XG4gICAgICAvLyBVc2Ugd3JpdGVNdWx0aSBpZiBhdmFpbGFibGUgZm9yIGJhdGNoIHdyaXRlc1xuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2Ygd29ybGQuc3RyZWFtcy53cml0ZU11bHRpID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgIGNodW5rc1RvRmx1c2gubGVuZ3RoID4gMVxuICAgICAgKSB7XG4gICAgICAgIGF3YWl0IHdvcmxkLnN0cmVhbXMud3JpdGVNdWx0aShydW5JZCwgbmFtZSwgY2h1bmtzVG9GbHVzaCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBGYWxsIGJhY2sgdG8gc2VxdWVudGlhbCB3cml0ZXNcbiAgICAgICAgZm9yIChjb25zdCBjaHVuayBvZiBjaHVua3NUb0ZsdXNoKSB7XG4gICAgICAgICAgYXdhaXQgd29ybGQuc3RyZWFtcy53cml0ZShydW5JZCwgbmFtZSwgY2h1bmspO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIE9ubHkgY2xlYXIgYnVmZmVyIGFmdGVyIHN1Y2Nlc3NmdWwgd3JpdGUgdG8gcHJldmVudCBkYXRhIGxvc3NcbiAgICAgIGJ1ZmZlciA9IFtdO1xuICAgIH07XG5cbiAgICAvKiogUmVzb2x2ZXJzL3JlamVjdG9ycyB3YWl0aW5nIGZvciB0aGUgY3VycmVudCBzY2hlZHVsZWQgZmx1c2ggKi9cbiAgICBsZXQgZmx1c2hXYWl0ZXJzOiBBcnJheTx7XG4gICAgICByZXNvbHZlOiAoKSA9PiB2b2lkO1xuICAgICAgcmVqZWN0OiAoZXJyOiB1bmtub3duKSA9PiB2b2lkO1xuICAgIH0+ID0gW107XG5cbiAgICBjb25zdCBzY2hlZHVsZUZsdXNoID0gKCk6IHZvaWQgPT4ge1xuICAgICAgaWYgKGZsdXNoVGltZXIpIHJldHVybjsgLy8gQWxyZWFkeSBzY2hlZHVsZWRcblxuICAgICAgZmx1c2hUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBmbHVzaFRpbWVyID0gbnVsbDtcbiAgICAgICAgY29uc3QgY3VycmVudFdhaXRlcnMgPSBmbHVzaFdhaXRlcnM7XG4gICAgICAgIGZsdXNoV2FpdGVycyA9IFtdO1xuICAgICAgICBmbHVzaFByb21pc2UgPSBmbHVzaCgpLnRoZW4oXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgZm9yIChjb25zdCB3IG9mIGN1cnJlbnRXYWl0ZXJzKSB3LnJlc29sdmUoKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIChlcnIpID0+IHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgdyBvZiBjdXJyZW50V2FpdGVycykgdy5yZWplY3QoZXJyKTtcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9LCByZXNvbHZlZEZsdXNoSW50ZXJ2YWxNcyA/PyBTVFJFQU1fRkxVU0hfSU5URVJWQUxfTVMpO1xuICAgIH07XG5cbiAgICBzdXBlcih7XG4gICAgICBhc3luYyB3cml0ZShjaHVuaykge1xuICAgICAgICAvLyBXYWl0IGZvciBhbnkgaW4tcHJvZ3Jlc3MgZmx1c2ggdG8gY29tcGxldGUgYmVmb3JlIGFkZGluZyB0byBidWZmZXJcbiAgICAgICAgaWYgKGZsdXNoUHJvbWlzZSkge1xuICAgICAgICAgIGF3YWl0IGZsdXNoUHJvbWlzZTtcbiAgICAgICAgICBmbHVzaFByb21pc2UgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgYnVmZmVyLnB1c2goY2h1bmspO1xuICAgICAgICBzY2hlZHVsZUZsdXNoKCk7XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgdGhlIHNjaGVkdWxlZCBmbHVzaCB0byBjb21wbGV0ZSBzbyB0aGF0IGNhbGxlcnNcbiAgICAgICAgLy8gKGxpa2UgZmx1c2hhYmxlUGlwZSkga25vdyBkYXRhIGhhcyByZWFjaGVkIHRoZSBzZXJ2ZXJcbiAgICAgICAgLy8gYmVmb3JlIGRlY3JlbWVudGluZyBwZW5kaW5nT3BzLiBXaXRob3V0IHRoaXMsIHBlbmRpbmdPcHNcbiAgICAgICAgLy8gcmVhY2hlcyAwIHdoZW4gdGhlIGJ1ZmZlcmVkIHdyaXRlIHJldHVybnMgKGluc3RhbnQpLCBidXRcbiAgICAgICAgLy8gdGhlIDEwbXMgZmx1c2ggdGltZXIgaGFzbid0IGZpcmVkIHlldC5cbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgIGZsdXNoV2FpdGVycy5wdXNoKHsgcmVzb2x2ZSwgcmVqZWN0IH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBhc3luYyBjbG9zZSgpIHtcbiAgICAgICAgLy8gV2FpdCBmb3IgYW55IGluLXByb2dyZXNzIGZsdXNoIHRvIGNvbXBsZXRlXG4gICAgICAgIGlmIChmbHVzaFByb21pc2UpIHtcbiAgICAgICAgICBhd2FpdCBmbHVzaFByb21pc2U7XG4gICAgICAgICAgZmx1c2hQcm9taXNlID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZsdXNoIGFueSByZW1haW5pbmcgYnVmZmVyZWQgY2h1bmtzXG4gICAgICAgIGF3YWl0IGZsdXNoKCk7XG5cbiAgICAgICAgY29uc3Qgd29ybGQgPSBhd2FpdCB3b3JsZFByb21pc2U7XG4gICAgICAgIGF3YWl0IHdvcmxkLnN0cmVhbXMuY2xvc2UocnVuSWQsIG5hbWUpO1xuICAgICAgfSxcbiAgICAgIGFib3J0KHJlYXNvbikge1xuICAgICAgICAvLyBDbGVhbiB1cCB0aW1lciB0byBwcmV2ZW50IGxlYWtzXG4gICAgICAgIGlmIChmbHVzaFRpbWVyKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KGZsdXNoVGltZXIpO1xuICAgICAgICAgIGZsdXNoVGltZXIgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIC8vIERpc2NhcmQgYnVmZmVyZWQgY2h1bmtzIC0gdGhleSB3b24ndCBiZSB3cml0dGVuXG4gICAgICAgIGJ1ZmZlciA9IFtdO1xuICAgICAgICAvLyBSZWplY3QgYW55IHBlbmRpbmcgZmx1c2hXYWl0ZXJzIHNvIHRoZSB3cml0ZSgpIHByb21pc2VzIHNldHRsZVxuICAgICAgICAvLyBhbmQgZG9uJ3QgbGVhay4gV2l0aG91dCB0aGlzLCB3cml0ZSgpIGhhbmdzIGZvcmV2ZXIgb24gYW5cbiAgICAgICAgLy8gdW5zZXR0bGVkIHByb21pc2UgYmVjYXVzZSB0aGUgY2xlYXJlZCB0aW1lciB3aWxsIG5ldmVyIGZpcmUuXG4gICAgICAgIGNvbnN0IHdhaXRlcnMgPSBmbHVzaFdhaXRlcnM7XG4gICAgICAgIGZsdXNoV2FpdGVycyA9IFtdO1xuICAgICAgICBjb25zdCBhYm9ydEVycm9yID0gcmVhc29uID8/IG5ldyBFcnJvcignU3RyZWFtIGFib3J0ZWQnKTtcbiAgICAgICAgZm9yIChjb25zdCB3IG9mIHdhaXRlcnMpIHcucmVqZWN0KGFib3J0RXJyb3IpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufVxuXG4vLyBSZS1leHBvcnQgdHlwZXMgZnJvbSB0aGUgbW9kdWxhciBzZXJpYWxpemF0aW9uIG1vZHVsZXMuXG5leHBvcnQgdHlwZSB7XG4gIFJlZHVjZXJzLFxuICBSZXZpdmVycyxcbiAgU2VyaWFsaXphYmxlU3BlY2lhbCxcbn0gZnJvbSAnLi9zZXJpYWxpemF0aW9uL3R5cGVzLmpzJztcblxuLy8gSW1wb3J0IHR5cGVzIGxvY2FsbHkgZm9yIHVzZSB3aXRoaW4gdGhpcyBmaWxlLlxuaW1wb3J0IHR5cGUge1xuICBSZWR1Y2VycyxcbiAgUmV2aXZlcnMsXG4gIFNlcmlhbGl6YWJsZVNwZWNpYWwsXG59IGZyb20gJy4vc2VyaWFsaXphdGlvbi90eXBlcy5qcyc7XG5cbi8vIC0tLS0gQ29tcG9zZWQgcmVkdWNlcnMgLS0tLVxuLy8gQ29tcG9zZXMgbW9kdWxhciByZWR1Y2VycyAoY29tbW9uLCBjbGFzcywgc3RlcC1mdW5jdGlvbikgd2l0aFxuLy8gbW9kZS1zcGVjaWZpYyBSZXF1ZXN0L1Jlc3BvbnNlL1N0cmVhbSByZWR1Y2VycyBiZWxvdy5cblxuLyoqXG4gKiBCYXNlIHJlZHVjZXJzIHNoYXJlZCBhY3Jvc3MgYWxsIHNlcmlhbGl6YXRpb24gYm91bmRhcmllcy5cbiAqIENvbXBvc2VzOiBjbGFzcyArIHN0ZXAtZnVuY3Rpb24gKyBjb21tb24gcmVkdWNlcnMgZnJvbSB0aGUgbW9kdWxhciBtb2R1bGVzLlxuICovXG5mdW5jdGlvbiBnZXRBbGxCYXNlUmVkdWNlcnMoXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXNcbik6IFBhcnRpYWw8UmVkdWNlcnM+IHtcbiAgLy8gQ2xhc3MvSW5zdGFuY2UgTVVTVCBjb21lIGJlZm9yZSBFcnJvciBzbyB0aGF0IGN1c3RvbSBFcnJvciBzdWJjbGFzc2VzXG4gIC8vIHdpdGggV09SS0ZMT1dfU0VSSUFMSVpFIHRha2UgcHJlY2VkZW5jZSAoZGV2YWx1ZSB1c2VzIGZpcnN0LW1hdGNoLXdpbnMpLlxuICByZXR1cm4ge1xuICAgIC4uLmdldENsYXNzUmVkdWNlcnMoKSxcbiAgICAuLi5nZXRTdGVwRnVuY3Rpb25SZWR1Y2VyKCksXG4gICAgLi4uZ2V0Q29tbW9uUmVkdWNlcnMoZ2xvYmFsKSxcbiAgICAvLyBSZXF1ZXN0IGFuZCBSZXNwb25zZSByZWR1Y2VycyBhcmUgbW9kZS1zcGVjaWZpYyBhbmQgYWRkZWQgYnlcbiAgICAvLyBnZXRFeHRlcm5hbFJlZHVjZXJzIC8gZ2V0V29ya2Zsb3dSZWR1Y2VycyAvIGdldFN0ZXBSZWR1Y2VycyBiZWxvdy5cbiAgICBSZXF1ZXN0OiAodmFsdWUpID0+IHtcbiAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLlJlcXVlc3QpKSByZXR1cm4gZmFsc2U7XG4gICAgICBjb25zdCBkYXRhOiBTZXJpYWxpemFibGVTcGVjaWFsWydSZXF1ZXN0J10gPSB7XG4gICAgICAgIG1ldGhvZDogdmFsdWUubWV0aG9kLFxuICAgICAgICB1cmw6IHZhbHVlLnVybCxcbiAgICAgICAgaGVhZGVyczogdmFsdWUuaGVhZGVycyxcbiAgICAgICAgYm9keTogdmFsdWUuYm9keSxcbiAgICAgICAgZHVwbGV4OiB2YWx1ZS5kdXBsZXgsXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzcG9uc2VXcml0YWJsZSA9IHZhbHVlW1dFQkhPT0tfUkVTUE9OU0VfV1JJVEFCTEVdO1xuICAgICAgaWYgKHJlc3BvbnNlV3JpdGFibGUpIHtcbiAgICAgICAgZGF0YS5yZXNwb25zZVdyaXRhYmxlID0gcmVzcG9uc2VXcml0YWJsZTtcbiAgICAgIH1cbiAgICAgIC8vIEZvcndhcmQgdGhlIHNpZ25hbCBpbiB0d28gY2FzZXM6XG4gICAgICAvLyAgIDEuIEFscmVhZHkgYWJvcnRlZCDigJQgcHJlc2VydmUgYWJvcnRlZD10cnVlL3JlYXNvbiBzbyB0aGUgaHlkcmF0ZWRcbiAgICAgIC8vICAgICAgc3RlcCBzZWVzIHRoZSBjYW5jZWxsYXRpb24gdGhhdCBoYXBwZW5lZCBiZWZvcmUgc2VyaWFsaXplLlxuICAgICAgLy8gICAyLiBBbHJlYWR5IHRhZ2dlZCB3aXRoIHdvcmtmbG93IGluZnJhc3RydWN0dXJlIOKAlCBpLmUuIGEgc2lnbmFsXG4gICAgICAvLyAgICAgIGZyb20gYSB3b3JrZmxvdy1tYW5hZ2VkIEFib3J0Q29udHJvbGxlciwgd2hpY2ggaGFzIHN0cmVhbS9ob29rXG4gICAgICAvLyAgICAgIGJhY2tpbmcgZm9yIGNyb3NzLWJvdW5kYXJ5IHByb3BhZ2F0aW9uLlxuICAgICAgLy8gUGxhaW4gbm9uLWFib3J0ZWQgbmF0aXZlIHNpZ25hbHMgYXJlIGludGVudGlvbmFsbHkgZHJvcHBlZCAod291bGRcbiAgICAgIC8vIG1pbnQgc3RyZWFtIGluZnJhIGZvciBldmVyeSBSZXF1ZXN0LCBpbmNsdWRpbmcgdGhlIGF1dG8tZ2VuZXJhdGVkXG4gICAgICAvLyBzaWduYWwgb24gYG5ldyBSZXF1ZXN0KHVybClgKS5cbiAgICAgIGlmIChcbiAgICAgICAgdmFsdWUuc2lnbmFsICYmXG4gICAgICAgICh2YWx1ZS5zaWduYWwuYWJvcnRlZCB8fFxuICAgICAgICAgICh2YWx1ZS5zaWduYWwgYXMgQWJvcnRJbnRlcm5hbHMpW0FCT1JUX1NUUkVBTV9OQU1FXSlcbiAgICAgICkge1xuICAgICAgICBkYXRhLnNpZ25hbCA9IHZhbHVlLnNpZ25hbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH0sXG4gICAgUmVzcG9uc2U6ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuUmVzcG9uc2UpKSByZXR1cm4gZmFsc2U7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiB2YWx1ZS50eXBlLFxuICAgICAgICB1cmw6IHZhbHVlLnVybCxcbiAgICAgICAgc3RhdHVzOiB2YWx1ZS5zdGF0dXMsXG4gICAgICAgIHN0YXR1c1RleHQ6IHZhbHVlLnN0YXR1c1RleHQsXG4gICAgICAgIGhlYWRlcnM6IHZhbHVlLmhlYWRlcnMsXG4gICAgICAgIGJvZHk6IHZhbHVlLmJvZHksXG4gICAgICAgIHJlZGlyZWN0ZWQ6IHZhbHVlLnJlZGlyZWN0ZWQsXG4gICAgICB9O1xuICAgIH0sXG4gIH07XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gU2hhcmVkIGFib3J0IHJlZHVjZXIgaGVscGVyc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbnR5cGUgQWJvcnRTZXJpYWxpemVkRGF0YSA9IHtcbiAgc3RyZWFtTmFtZTogc3RyaW5nO1xuICBob29rVG9rZW46IHN0cmluZztcbiAgYWJvcnRlZDogYm9vbGVhbjtcbiAgcmVhc29uOiB1bmtub3duO1xufTtcblxuLyoqXG4gKiBTeW1ib2wta2V5ZWQgaW50ZXJuYWwgZmllbGRzIHRhZ2dlZCBvbnRvIEFib3J0Q29udHJvbGxlci9BYm9ydFNpZ25hbFxuICogaW5zdGFuY2VzIChhbmQgYGhvbGRlcmBzIGluIHJlZHVjZXIgaGVscGVycykuIEFsbCBvcHRpb25hbCDigJQgYSBwbGFpblxuICogbmF0aXZlIGluc3RhbmNlIGhhcyBub25lIG9mIHRoZW0gc2V0LlxuICovXG50eXBlIEFib3J0SW50ZXJuYWxzID0ge1xuICBbQUJPUlRfU1RSRUFNX05BTUVdPzogc3RyaW5nO1xuICBbQUJPUlRfSE9PS19UT0tFTl0/OiBzdHJpbmc7XG4gIFtBQk9SVF9SRUFERVJfQ0FOQ0VMXT86IEFib3J0Q29udHJvbGxlcjtcbn07XG5cbnR5cGUgQWJvcnRTaWduYWxMaWtlID0gQWJvcnRJbnRlcm5hbHMgJiB7XG4gIGFib3J0ZWQ6IGJvb2xlYW47XG4gIHJlYXNvbj86IHVua25vd247XG4gIGFkZEV2ZW50TGlzdGVuZXI/OiBGdW5jdGlvbjtcbn07XG5cbnR5cGUgQWJvcnRIb2xkZXIgPSBBYm9ydEludGVybmFscyAmIHsgc2lnbmFsPzogQWJvcnRJbnRlcm5hbHMgfTtcblxuLyoqXG4gKiBTaGFyZWQgbG9naWMgZm9yIEFib3J0Q29udHJvbGxlci9BYm9ydFNpZ25hbCByZWR1Y2VycyBpbiBleHRlcm5hbCBhbmQgc3RlcFxuICogY29udGV4dHMuIEFzc2lnbnMgc3RyZWFtL2hvb2sgbmFtZXMgaWYgbm90IGFscmVhZHkgcHJlc2VudCwgb3B0aW9uYWxseVxuICogYXR0YWNoZXMgYW4gYWJvcnQgbGlzdGVuZXIgZm9yIHJlYWwtdGltZSBwcm9wYWdhdGlvbiwgYW5kIHJldHVybnMgdGhlXG4gKiBzZXJpYWxpemVkIHJlcHJlc2VudGF0aW9uLlxuICovXG5mdW5jdGlvbiByZWR1Y2VBYm9ydFdpdGhMaXN0ZW5lcihcbiAgc2lnbmFsOiBBYm9ydFNpZ25hbExpa2UsXG4gIGhvbGRlcjogQWJvcnRIb2xkZXIsXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PixcbiAgb3BzOiBQcm9taXNlPHZvaWQ+W10sXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGNyeXB0b0tleTogRW5jcnlwdGlvbktleVBhcmFtXG4pOiBBYm9ydFNlcmlhbGl6ZWREYXRhIHtcbiAgbGV0IHN0cmVhbU5hbWUgPSBob2xkZXJbQUJPUlRfU1RSRUFNX05BTUVdO1xuICBsZXQgaG9va1Rva2VuID0gaG9sZGVyW0FCT1JUX0hPT0tfVE9LRU5dO1xuICBpZiAoIXN0cmVhbU5hbWUpIHtcbiAgICBjb25zdCBpZCA9ICgoZ2xvYmFsIGFzIGFueSlbU1RBQkxFX1VMSURdIHx8IGRlZmF1bHRVbGlkKSgpO1xuICAgIHN0cmVhbU5hbWUgPSBnZXRBYm9ydFN0cmVhbUlkKGlkKTtcbiAgICBob29rVG9rZW4gPSBgYWJydF8ke2lkfWA7XG4gICAgaG9sZGVyW0FCT1JUX1NUUkVBTV9OQU1FXSA9IHN0cmVhbU5hbWU7XG4gICAgaG9sZGVyW0FCT1JUX0hPT0tfVE9LRU5dID0gaG9va1Rva2VuO1xuICAgIGlmIChob2xkZXIuc2lnbmFsKSB7XG4gICAgICBob2xkZXIuc2lnbmFsW0FCT1JUX1NUUkVBTV9OQU1FXSA9IHN0cmVhbU5hbWU7XG4gICAgICBob2xkZXIuc2lnbmFsW0FCT1JUX0hPT0tfVE9LRU5dID0gaG9va1Rva2VuO1xuICAgIH1cbiAgfVxuXG4gIC8vIERlZHVwZWQgdmlhIEFCT1JUX0xJU1RFTkVSX0FUVEFDSEVEIG1hcmtlciDigJQgc2VlIGF0dGFjaEFib3J0TGlzdGVuZXJPbmNlLlxuICBhdHRhY2hBYm9ydExpc3RlbmVyT25jZShcbiAgICBzaWduYWwgYXMgQWJvcnRTaWduYWwsXG4gICAgc3RyZWFtTmFtZSxcbiAgICBydW5JZCxcbiAgICBjcnlwdG9LZXksXG4gICAgb3BzXG4gICk7XG5cbiAgcmV0dXJuIHtcbiAgICBzdHJlYW1OYW1lLFxuICAgIGhvb2tUb2tlbjogaG9va1Rva2VuISxcbiAgICBhYm9ydGVkOiBzaWduYWwuYWJvcnRlZCxcbiAgICByZWFzb246IHNpZ25hbC5hYm9ydGVkID8gc2lnbmFsLnJlYXNvbiA6IHVuZGVmaW5lZCxcbiAgfTtcbn1cblxuLyoqXG4gKiBTaGFyZWQgbG9naWMgZm9yIEFib3J0Q29udHJvbGxlci9BYm9ydFNpZ25hbCByZWR1Y2VycyBpbiB3b3JrZmxvdyBjb250ZXh0LlxuICogUmVhZHMgZXhpc3Rpbmcgc3RyZWFtL2hvb2sgbmFtZXMgZnJvbSBzeW1ib2xzIChtdXN0IGFscmVhZHkgYmUgc2V0KS5cbiAqL1xuZnVuY3Rpb24gcmVkdWNlQWJvcnRCeVN5bWJvbChcbiAgc2lnbmFsOiB7IGFib3J0ZWQ6IGJvb2xlYW47IHJlYXNvbj86IHVua25vd24gfSxcbiAgaG9sZGVyOiBBYm9ydEhvbGRlclxuKTogQWJvcnRTZXJpYWxpemVkRGF0YSB8IGZhbHNlIHtcbiAgY29uc3Qgc3RyZWFtTmFtZSA9XG4gICAgaG9sZGVyW0FCT1JUX1NUUkVBTV9OQU1FXSA/PyBob2xkZXIuc2lnbmFsPy5bQUJPUlRfU1RSRUFNX05BTUVdO1xuICBjb25zdCBob29rVG9rZW4gPVxuICAgIGhvbGRlcltBQk9SVF9IT09LX1RPS0VOXSA/PyBob2xkZXIuc2lnbmFsPy5bQUJPUlRfSE9PS19UT0tFTl07XG4gIGlmICghc3RyZWFtTmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQWJvcnRDb250cm9sbGVyL0Fib3J0U2lnbmFsIHN0cmVhbSBuYW1lIGlzIG5vdCBzZXQnKTtcbiAgfVxuICByZXR1cm4ge1xuICAgIHN0cmVhbU5hbWUsXG4gICAgaG9va1Rva2VuOiBob29rVG9rZW4hLFxuICAgIGFib3J0ZWQ6IHNpZ25hbC5hYm9ydGVkLFxuICAgIHJlYXNvbjogc2lnbmFsLmFib3J0ZWQgPyBzaWduYWwucmVhc29uIDogdW5kZWZpbmVkLFxuICB9O1xufVxuXG4vKipcbiAqIEF0dGFjaCBhIHNpbmdsZSBhYm9ydCBsaXN0ZW5lciB0byBhIHNpZ25hbCwgZGVkdXBlZCBhY3Jvc3MgY2FsbHMuXG4gKlxuICogRWFjaCBzZXJpYWxpemF0aW9uIHBhc3MgZ29lcyB0aHJvdWdoIHRoZSByZWR1Y2VyLCBidXQgYSBjb250cm9sbGVyIHBhc3NlZFxuICogdG8gTiBzdGVwcyB3b3VsZCBvdGhlcndpc2UgYWNjdW11bGF0ZSBOIGxpc3RlbmVycyDigJQgZWFjaCB3cml0aW5nIHRoZSBzYW1lXG4gKiBzdHJlYW0gcGFja2V0IGFuZCBkb3VibGUtY2xvc2luZyB0aGUgc3RyZWFtIG9uIGFib3J0LiBUaGUgbWFya2VyIHN5bWJvbFxuICogZW5zdXJlcyB0aGUgc3RyZWFtLXdyaXRlIHNpZGUtZWZmZWN0IHJ1bnMgYXQgbW9zdCBvbmNlIHBlciAoc2lnbmFsLCBydW5JZCkuXG4gKi9cbmZ1bmN0aW9uIGF0dGFjaEFib3J0TGlzdGVuZXJPbmNlKFxuICBzaWduYWw6IEFib3J0U2lnbmFsLFxuICBzdHJlYW1OYW1lOiBzdHJpbmcsXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGNyeXB0b0tleTogRW5jcnlwdGlvbktleVBhcmFtLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXVxuKTogdm9pZCB7XG4gIGlmIChzaWduYWwuYWJvcnRlZCkgcmV0dXJuO1xuICBpZiAoKHNpZ25hbCBhcyBhbnkpW0FCT1JUX0xJU1RFTkVSX0FUVEFDSEVEXSkgcmV0dXJuO1xuICAoc2lnbmFsIGFzIGFueSlbQUJPUlRfTElTVEVORVJfQVRUQUNIRURdID0gdHJ1ZTtcblxuICBzaWduYWwuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAnYWJvcnQnLFxuICAgICgpID0+IHtcbiAgICAgIG9wcy5wdXNoKFxuICAgICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBEZWh5ZHJhdGUgdmlhIHRoZSBzYW1lIG1hY2hpbmVyeSB0aGUgcmVhZGVyIHVzZXMgKGh5ZHJhdGVTdGVwQXJndW1lbnRzKVxuICAgICAgICAgICAgLy8gc28gdGhlIHJlYXNvbiByb3VuZC10cmlwcyB3aXRoIGZ1bGwgdHlwZSBmaWRlbGl0eSAoRE9NRXhjZXB0aW9uLFxuICAgICAgICAgICAgLy8gRXJyb3JzLCBjdXN0b20gY2xhc3NlcywgZXRjLikgYW5kIHJlc3BlY3RzIHRoZSBydW4ncyBlbmNyeXB0aW9uIGtleS5cbiAgICAgICAgICAgIC8vIEEgYmFyZSBKU09OLnN0cmluZ2lmeSBoZXJlIHdvdWxkIHdyaXRlIGEgcGFja2V0IHRoZSByZWFkZXIgY2FuJ3RcbiAgICAgICAgICAgIC8vIGRlY29kZSBhbmQgdGhlIGxpc3RlbmVyLXNpZGUgYWJvcnQgd291bGQgcHJvcGFnYXRlIHdpdGggbm8gcmVhc29uLlxuICAgICAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgY3J5cHRvS2V5O1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGF3YWl0IGRlaHlkcmF0ZVN0ZXBBcmd1bWVudHMoXG4gICAgICAgICAgICAgIHsgYWJvcnRlZDogdHJ1ZSwgcmVhc29uOiBzaWduYWwucmVhc29uIH0sXG4gICAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgICBrZXlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCB3cml0YWJsZSA9IG5ldyBXb3JrZmxvd1NlcnZlcldyaXRhYmxlU3RyZWFtKFxuICAgICAgICAgICAgICBydW5JZCxcbiAgICAgICAgICAgICAgc3RyZWFtTmFtZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IHdyaXRlciA9IHdyaXRhYmxlLmdldFdyaXRlcigpO1xuICAgICAgICAgICAgYXdhaXQgd3JpdGVyLndyaXRlKHBheWxvYWQgYXMgVWludDhBcnJheSk7XG4gICAgICAgICAgICBhd2FpdCB3cml0ZXIuY2xvc2UoKTtcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIEJlc3QtZWZmb3J0IHN0cmVhbSB3cml0ZVxuICAgICAgICAgIH1cbiAgICAgICAgfSkoKVxuICAgICAgKTtcbiAgICB9LFxuICAgIHsgb25jZTogdHJ1ZSB9XG4gICk7XG59XG5cbi8qKlxuICogUmVkdWNlcnMgZm9yIHNlcmlhbGl6YXRpb24gYm91bmRhcnkgZnJvbSB0aGUgY2xpZW50IHNpZGUsIHBhc3NpbmcgYXJndW1lbnRzXG4gKiB0byB0aGUgd29ya2Zsb3cgaGFuZGxlci5cbiAqXG4gKiBAcGFyYW0gZ2xvYmFsXG4gKiBAcGFyYW0gb3BzXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXh0ZXJuYWxSZWR1Y2VycyhcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpcyxcbiAgb3BzOiBQcm9taXNlPHZvaWQ+W10sXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGNyeXB0b0tleTogRW5jcnlwdGlvbktleVBhcmFtXG4pOiBQYXJ0aWFsPFJlZHVjZXJzPiB7XG4gIHJldHVybiB7XG4gICAgLi4uZ2V0QWxsQmFzZVJlZHVjZXJzKGdsb2JhbCksXG5cbiAgICBSZWFkYWJsZVN0cmVhbTogKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5SZWFkYWJsZVN0cmVhbSkpIHJldHVybiBmYWxzZTtcblxuICAgICAgLy8gU3RyZWFtIG11c3Qgbm90IGJlIGxvY2tlZCB3aGVuIHBhc3NpbmcgYWNyb3NzIGV4ZWN1dGlvbiBib3VuZGFyeVxuICAgICAgaWYgKHZhbHVlLmxvY2tlZCkge1xuICAgICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgICAgICdSZWFkYWJsZVN0cmVhbSBpcyBsb2NrZWQgYW5kIGNhbm5vdCBiZSBwYXNzZWQgYWNyb3NzIGEgd29ya2Zsb3cgYm91bmRhcnkuJyxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBoaW50OiAnUGFzcyB0aGUgc3RyZWFtIGJlZm9yZSBjYWxsaW5nIC5nZXRSZWFkZXIoKSAvIC5waXBlVGhyb3VnaCgpIC8gLnBpcGVUbygpLCBvciB0ZWUgaXQgd2l0aCAudGVlKCkgYW5kIHBhc3Mgb25lIG9mIHRoZSBicmFuY2hlcy4nLFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RyZWFtSWQgPSAoKGdsb2JhbCBhcyBhbnkpW1NUQUJMRV9VTElEXSB8fCBkZWZhdWx0VWxpZCkoKTtcbiAgICAgIGNvbnN0IG5hbWUgPSBgc3RybV8ke3N0cmVhbUlkfWA7XG4gICAgICBjb25zdCB0eXBlID0gZ2V0U3RyZWFtVHlwZSh2YWx1ZSk7XG5cbiAgICAgIGNvbnN0IHdyaXRhYmxlID0gbmV3IFdvcmtmbG93U2VydmVyV3JpdGFibGVTdHJlYW0ocnVuSWQsIG5hbWUpO1xuICAgICAgaWYgKHR5cGUgPT09ICdieXRlcycpIHtcbiAgICAgICAgb3BzLnB1c2godmFsdWUucGlwZVRvKHdyaXRhYmxlKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcHMucHVzaChcbiAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICAgLnBpcGVUaHJvdWdoKFxuICAgICAgICAgICAgICBnZXRTZXJpYWxpemVTdHJlYW0oXG4gICAgICAgICAgICAgICAgZ2V0RXh0ZXJuYWxSZWR1Y2VycyhnbG9iYWwsIG9wcywgcnVuSWQsIGNyeXB0b0tleSksXG4gICAgICAgICAgICAgICAgY3J5cHRvS2V5XG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5waXBlVG8od3JpdGFibGUpXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHM6IFNlcmlhbGl6YWJsZVNwZWNpYWxbJ1JlYWRhYmxlU3RyZWFtJ10gPSB7IG5hbWUgfTtcbiAgICAgIGlmICh0eXBlKSBzLnR5cGUgPSB0eXBlO1xuICAgICAgcmV0dXJuIHM7XG4gICAgfSxcblxuICAgIFdyaXRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLldyaXRhYmxlU3RyZWFtKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAvLyBGYXN0IHBhdGg6IHdoZW4gdGhlIHdyaXRhYmxlIGlzIGFscmVhZHkgYmFja2VkIGJ5IGEgd29ya2Zsb3dcbiAgICAgIC8vIHNlcnZlciBzdHJlYW0gKGUuZy4gaXQgY2FtZSBmcm9tIGEgc3RlcC1jb250ZXh0IGBnZXRXcml0YWJsZSgpYFxuICAgICAgLy8gb3Igd2FzIGh5ZHJhdGVkIGZyb20gYSB3b3JrZmxvdyBpbnB1dCBieSBgZ2V0U3RlcFJldml2ZXJzYCksXG4gICAgICAvLyBmb3J3YXJkIGl0cyB1bmRlcmx5aW5nIGAocnVuSWQsIG5hbWUpYCB0byB0aGUgcmVjZWl2aW5nIHJ1bi5cbiAgICAgIC8vIFRoZSByZWNlaXZpbmcgcnVuJ3Mgc3RlcC1zaWRlIHJldml2ZXIgb3BlbnMgYSBzZXJ2ZXIgd3JpdGFibGVcbiAgICAgIC8vIGFnYWluc3QgdGhlIG9yaWdpbmFsIGAocnVuSWQsIG5hbWUpYCBhbmQgcmVzb2x2ZXMgdGhhdCBydW4nc1xuICAgICAgLy8gZW5jcnlwdGlvbiBrZXkgZGlyZWN0bHksIHNvIHdyaXRlcyBsYW5kIG9uIHRoZSBvcmlnaW5hbCBzdHJlYW1cbiAgICAgIC8vIGZvciB0aGUgZnVsbCBsaWZldGltZSBvZiB0aGUgcmVjZWl2aW5nIHJ1biDigJQgbm8gaW4tcHJvY2Vzc1xuICAgICAgLy8gYnJpZGdlIHRpZWQgdG8gdGhlIGRlaHlkcmF0aW5nIHN0ZXAncyBsaWZldGltZS5cbiAgICAgIGNvbnN0IGV4aXN0aW5nTmFtZSA9ICh2YWx1ZSBhcyBhbnkpW1NUUkVBTV9OQU1FX1NZTUJPTF07XG4gICAgICBjb25zdCBleGlzdGluZ1J1bklkID0gKHZhbHVlIGFzIGFueSlbU1RSRUFNX1NFUlZFUl9SVU5fSURfU1lNQk9MXTtcbiAgICAgIGlmIChcbiAgICAgICAgdHlwZW9mIGV4aXN0aW5nTmFtZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgdHlwZW9mIGV4aXN0aW5nUnVuSWQgPT09ICdzdHJpbmcnXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIHsgbmFtZTogZXhpc3RpbmdOYW1lLCBydW5JZDogZXhpc3RpbmdSdW5JZCB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdHJlYW1JZCA9ICgoZ2xvYmFsIGFzIGFueSlbU1RBQkxFX1VMSURdIHx8IGRlZmF1bHRVbGlkKSgpO1xuICAgICAgY29uc3QgbmFtZSA9IGBzdHJtXyR7c3RyZWFtSWR9YDtcbiAgICAgIGNvbnN0IHJlYWRhYmxlID0gbmV3IFdvcmtmbG93U2VydmVyUmVhZGFibGVTdHJlYW0ocnVuSWQsIG5hbWUpO1xuICAgICAgb3BzLnB1c2gocmVhZGFibGUucGlwZVRvKHZhbHVlKSk7XG5cbiAgICAgIHJldHVybiB7IG5hbWUgfTtcbiAgICB9LFxuXG4gICAgQWJvcnRDb250cm9sbGVyOiAodmFsdWUpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgIWdsb2JhbC5BYm9ydENvbnRyb2xsZXIgfHxcbiAgICAgICAgdHlwZW9mIGdsb2JhbC5BYm9ydENvbnRyb2xsZXIgIT09ICdmdW5jdGlvbicgfHxcbiAgICAgICAgISh2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5BYm9ydENvbnRyb2xsZXIpXG4gICAgICApXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIHJldHVybiByZWR1Y2VBYm9ydFdpdGhMaXN0ZW5lcihcbiAgICAgICAgdmFsdWUuc2lnbmFsLFxuICAgICAgICB2YWx1ZSxcbiAgICAgICAgZ2xvYmFsLFxuICAgICAgICBvcHMsXG4gICAgICAgIHJ1bklkLFxuICAgICAgICBjcnlwdG9LZXlcbiAgICAgICk7XG4gICAgfSxcblxuICAgIEFib3J0U2lnbmFsOiAodmFsdWUpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgIWdsb2JhbC5BYm9ydFNpZ25hbCB8fFxuICAgICAgICB0eXBlb2YgZ2xvYmFsLkFib3J0U2lnbmFsICE9PSAnZnVuY3Rpb24nIHx8XG4gICAgICAgICEodmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuQWJvcnRTaWduYWwpXG4gICAgICApXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIHJldHVybiByZWR1Y2VBYm9ydFdpdGhMaXN0ZW5lcihcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIHZhbHVlLFxuICAgICAgICBnbG9iYWwsXG4gICAgICAgIG9wcyxcbiAgICAgICAgcnVuSWQsXG4gICAgICAgIGNyeXB0b0tleVxuICAgICAgKTtcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIFJlZHVjZXJzIGZvciBzZXJpYWxpemF0aW9uIGJvdW5kYXJ5IGZyb20gd2l0aGluIHRoZSB3b3JrZmxvdyBleGVjdXRpb25cbiAqIGVudmlyb25tZW50LCBwYXNzaW5nIHJldHVybiB2YWx1ZSB0byB0aGUgY2xpZW50IHNpZGUgYW5kIGludG8gc3RlcCBhcmd1bWVudHMuXG4gKlxuICogQHBhcmFtIGdsb2JhbFxuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmtmbG93UmVkdWNlcnMoXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXNcbik6IFBhcnRpYWw8UmVkdWNlcnM+IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5nZXRBbGxCYXNlUmVkdWNlcnMoZ2xvYmFsKSxcblxuICAgIC8vIFJlYWRhYmxlL1dyaXRhYmxlIHN0cmVhbXMgZnJvbSB3aXRoaW4gdGhlIHdvcmtmbG93IGV4ZWN1dGlvbiBlbnZpcm9ubWVudFxuICAgIC8vIGFyZSBzaW1wbHkgXCJoYW5kbGVzXCIgdGhhdCBjYW4gYmUgcGFzc2VkIGFyb3VuZCB0byBvdGhlciBzdGVwcy5cbiAgICBSZWFkYWJsZVN0cmVhbTogKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5SZWFkYWJsZVN0cmVhbSkpIHJldHVybiBmYWxzZTtcblxuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIGZha2Ugc3RyZWFtIHN0b3JpbmcgQm9keUluaXQgZnJvbSBSZXF1ZXN0L1Jlc3BvbnNlIGNvbnN0cnVjdG9yXG4gICAgICBjb25zdCBib2R5SW5pdCA9IHZhbHVlW0JPRFlfSU5JVF9TWU1CT0xdO1xuICAgICAgaWYgKGJvZHlJbml0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gVGhpcyBpcyBhIGZha2Ugc3RyZWFtIC0gc2VyaWFsaXplIHRoZSBCb2R5SW5pdCBkaXJlY3RseVxuICAgICAgICAvLyBkZXZhbHVlIHdpbGwgaGFuZGxlIHNlcmlhbGl6aW5nIHN0cmluZ3MsIFVpbnQ4QXJyYXksIGV0Yy5cbiAgICAgICAgcmV0dXJuIHsgYm9keUluaXQgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbmFtZSA9IHZhbHVlW1NUUkVBTV9OQU1FX1NZTUJPTF07XG4gICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKCdSZWFkYWJsZVN0cmVhbSBgbmFtZWAgaXMgbm90IHNldCcpO1xuICAgICAgfVxuICAgICAgY29uc3QgczogU2VyaWFsaXphYmxlU3BlY2lhbFsnUmVhZGFibGVTdHJlYW0nXSA9IHsgbmFtZSB9O1xuICAgICAgY29uc3QgdHlwZSA9IHZhbHVlW1NUUkVBTV9UWVBFX1NZTUJPTF07XG4gICAgICBpZiAodHlwZSkgcy50eXBlID0gdHlwZTtcbiAgICAgIHJldHVybiBzO1xuICAgIH0sXG4gICAgV3JpdGFibGVTdHJlYW06ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuV3JpdGFibGVTdHJlYW0pKSByZXR1cm4gZmFsc2U7XG4gICAgICBjb25zdCBuYW1lID0gdmFsdWVbU1RSRUFNX05BTUVfU1lNQk9MXTtcbiAgICAgIGlmICghbmFtZSkge1xuICAgICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IoJ1dyaXRhYmxlU3RyZWFtIGBuYW1lYCBpcyBub3Qgc2V0Jyk7XG4gICAgICB9XG4gICAgICBjb25zdCBzOiBTZXJpYWxpemFibGVTcGVjaWFsWydXcml0YWJsZVN0cmVhbSddID0geyBuYW1lIH07XG4gICAgICAvLyBXaGVuIHRoZSBoYW5kbGUgd2FzIGZvcndhcmRlZCBmcm9tIGFub3RoZXIgcnVuIChwYXJlbnQg4oaSIGNoaWxkXG4gICAgICAvLyB2aWEgYHN0YXJ0KClgKSwgcHJlc2VydmUgdGhlIGZvcmVpZ24gcnVuSWQgc28gdGhlIHN0ZXAtc2lkZVxuICAgICAgLy8gcmV2aXZlciBvcGVucyB0aGUgd3JpdGFibGUgYWdhaW5zdCB0aGUgb3JpZ2luYWwgc3RyZWFtLlxuICAgICAgY29uc3QgZm9yZWlnblJ1bklkID0gdmFsdWVbU1RSRUFNX1NFUlZFUl9SVU5fSURfU1lNQk9MXTtcbiAgICAgIGlmICh0eXBlb2YgZm9yZWlnblJ1bklkID09PSAnc3RyaW5nJykgcy5ydW5JZCA9IGZvcmVpZ25SdW5JZDtcbiAgICAgIHJldHVybiBzO1xuICAgIH0sXG5cbiAgICAvLyBBYm9ydENvbnRyb2xsZXIvQWJvcnRTaWduYWwgaW4gd29ya2Zsb3cgY29udGV4dCDigJQganVzdCByZWFkIHN5bWJvbHMgKGhhbmRsZXMpLlxuICAgIC8vIEluIHRoZSB3b3JrZmxvdyBWTSwgZ2xvYmFsLkFib3J0Q29udHJvbGxlciBpcyBhIGNsYXNzIGJ1dCBnbG9iYWwuQWJvcnRTaWduYWxcbiAgICAvLyBpcyBhIHBsYWluIG9iamVjdCAobm90IGEgY2xhc3MpLCBzbyBpbnN0YW5jZW9mIGNoZWNrcyB3b24ndCB3b3JrIGZvciBzaWduYWxzLlxuICAgIC8vIERldGVjdCBpbnN0YW5jZXMgYnkgdGhlIHByZXNlbmNlIG9mIHRoZSBBQk9SVF9TVFJFQU1fTkFNRSBzeW1ib2wgaW5zdGVhZC5cbiAgICBBYm9ydENvbnRyb2xsZXI6ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKCF2YWx1ZSB8fCAhdmFsdWUuc2lnbmFsKSByZXR1cm4gZmFsc2U7XG4gICAgICBjb25zdCBob2xkZXIgPSB2YWx1ZSBhcyBBYm9ydENvbnRyb2xsZXIgJiBBYm9ydEhvbGRlcjtcbiAgICAgIGNvbnN0IGhhc0Fib3J0U3ltYm9sID1cbiAgICAgICAgaG9sZGVyW0FCT1JUX1NUUkVBTV9OQU1FXSA/PyBob2xkZXIuc2lnbmFsPy5bQUJPUlRfU1RSRUFNX05BTUVdO1xuICAgICAgY29uc3QgaXNOYXRpdmVBYm9ydENvbnRyb2xsZXIgPVxuICAgICAgICBnbG9iYWwuQWJvcnRDb250cm9sbGVyICYmXG4gICAgICAgIHR5cGVvZiBnbG9iYWwuQWJvcnRDb250cm9sbGVyID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgIHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLkFib3J0Q29udHJvbGxlcjtcbiAgICAgIGlmICghaGFzQWJvcnRTeW1ib2wgJiYgIWlzTmF0aXZlQWJvcnRDb250cm9sbGVyKSByZXR1cm4gZmFsc2U7XG4gICAgICByZXR1cm4gcmVkdWNlQWJvcnRCeVN5bWJvbCh2YWx1ZS5zaWduYWwsIGhvbGRlcik7XG4gICAgfSxcbiAgICBBYm9ydFNpZ25hbDogKHZhbHVlKSA9PiB7XG4gICAgICBjb25zdCBzaWduYWwgPSB2YWx1ZSBhcyAoQWJvcnRTaWduYWwgJiBBYm9ydEludGVybmFscykgfCB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBoYXNBYm9ydFN5bWJvbCA9IHNpZ25hbD8uW0FCT1JUX1NUUkVBTV9OQU1FXTtcbiAgICAgIGNvbnN0IGlzTmF0aXZlQWJvcnRTaWduYWwgPVxuICAgICAgICBnbG9iYWwuQWJvcnRTaWduYWwgJiZcbiAgICAgICAgdHlwZW9mIGdsb2JhbC5BYm9ydFNpZ25hbCA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgICB2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5BYm9ydFNpZ25hbDtcbiAgICAgIGlmICghaGFzQWJvcnRTeW1ib2wgJiYgIWlzTmF0aXZlQWJvcnRTaWduYWwpIHJldHVybiBmYWxzZTtcbiAgICAgIHJldHVybiByZWR1Y2VBYm9ydEJ5U3ltYm9sKHZhbHVlLCB2YWx1ZSBhcyBBYm9ydEhvbGRlcik7XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBSZWR1Y2VycyBmb3Igc2VyaWFsaXphdGlvbiBib3VuZGFyeSBmcm9tIHdpdGhpbiB0aGUgc3RlcCBleGVjdXRpb25cbiAqIGVudmlyb25tZW50LCBwYXNzaW5nIHJldHVybiB2YWx1ZSB0byB0aGUgd29ya2Zsb3cgaGFuZGxlci5cbiAqXG4gKiBAcGFyYW0gZ2xvYmFsXG4gKiBAcGFyYW0gb3BzXG4gKiBAcGFyYW0gcnVuSWRcbiAqIEByZXR1cm5zXG4gKi9cbmZ1bmN0aW9uIGdldFN0ZXBSZWR1Y2VycyhcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpcyxcbiAgb3BzOiBQcm9taXNlPHZvaWQ+W10sXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGNyeXB0b0tleTogRW5jcnlwdGlvbktleVBhcmFtXG4pOiBQYXJ0aWFsPFJlZHVjZXJzPiB7XG4gIHJldHVybiB7XG4gICAgLi4uZ2V0QWxsQmFzZVJlZHVjZXJzKGdsb2JhbCksXG5cbiAgICBSZWFkYWJsZVN0cmVhbTogKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5SZWFkYWJsZVN0cmVhbSkpIHJldHVybiBmYWxzZTtcblxuICAgICAgLy8gU3RyZWFtIG11c3Qgbm90IGJlIGxvY2tlZCB3aGVuIHBhc3NpbmcgYWNyb3NzIGV4ZWN1dGlvbiBib3VuZGFyeVxuICAgICAgaWYgKHZhbHVlLmxvY2tlZCkge1xuICAgICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgICAgICdSZWFkYWJsZVN0cmVhbSBpcyBsb2NrZWQgYW5kIGNhbm5vdCBiZSBwYXNzZWQgYWNyb3NzIGEgd29ya2Zsb3cgYm91bmRhcnkuJyxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBoaW50OiAnUGFzcyB0aGUgc3RyZWFtIGJlZm9yZSBjYWxsaW5nIC5nZXRSZWFkZXIoKSAvIC5waXBlVGhyb3VnaCgpIC8gLnBpcGVUbygpLCBvciB0ZWUgaXQgd2l0aCAudGVlKCkgYW5kIHBhc3Mgb25lIG9mIHRoZSBicmFuY2hlcy4nLFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgaWYgdGhlIHN0cmVhbSBhbHJlYWR5IGhhcyB0aGUgbmFtZSBzeW1ib2wgc2V0LCBpbiB3aGljaCBjYXNlXG4gICAgICAvLyBpdCdzIGFscmVhZHkgYmVpbmcgc3VuayB0byB0aGUgc2VydmVyIGFuZCB3ZSBjYW4ganVzdCByZXR1cm4gdGhlXG4gICAgICAvLyBuYW1lIGFuZCB0eXBlLlxuICAgICAgbGV0IG5hbWUgPSB2YWx1ZVtTVFJFQU1fTkFNRV9TWU1CT0xdO1xuICAgICAgbGV0IHR5cGUgPSB2YWx1ZVtTVFJFQU1fVFlQRV9TWU1CT0xdO1xuXG4gICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgY29uc3Qgc3RyZWFtSWQgPSAoKGdsb2JhbCBhcyBhbnkpW1NUQUJMRV9VTElEXSB8fCBkZWZhdWx0VWxpZCkoKTtcbiAgICAgICAgbmFtZSA9IGBzdHJtXyR7c3RyZWFtSWR9YDtcbiAgICAgICAgdHlwZSA9IGdldFN0cmVhbVR5cGUodmFsdWUpO1xuXG4gICAgICAgIGNvbnN0IHdyaXRhYmxlID0gbmV3IFdvcmtmbG93U2VydmVyV3JpdGFibGVTdHJlYW0ocnVuSWQsIG5hbWUpO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ2J5dGVzJykge1xuICAgICAgICAgIG9wcy5wdXNoKHZhbHVlLnBpcGVUbyh3cml0YWJsZSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9wcy5wdXNoKFxuICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgICAgICAgLnBpcGVUaHJvdWdoKFxuICAgICAgICAgICAgICAgIGdldFNlcmlhbGl6ZVN0cmVhbShcbiAgICAgICAgICAgICAgICAgIGdldFN0ZXBSZWR1Y2VycyhnbG9iYWwsIG9wcywgcnVuSWQsIGNyeXB0b0tleSksXG4gICAgICAgICAgICAgICAgICBjcnlwdG9LZXlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgLnBpcGVUbyh3cml0YWJsZSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHM6IFNlcmlhbGl6YWJsZVNwZWNpYWxbJ1JlYWRhYmxlU3RyZWFtJ10gPSB7IG5hbWUgfTtcbiAgICAgIGlmICh0eXBlKSBzLnR5cGUgPSB0eXBlO1xuICAgICAgcmV0dXJuIHM7XG4gICAgfSxcblxuICAgIFdyaXRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLldyaXRhYmxlU3RyZWFtKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICBsZXQgbmFtZSA9IHZhbHVlW1NUUkVBTV9OQU1FX1NZTUJPTF07XG4gICAgICBjb25zdCBmb3JlaWduUnVuSWQgPSAodmFsdWUgYXMgYW55KVtTVFJFQU1fU0VSVkVSX1JVTl9JRF9TWU1CT0xdO1xuICAgICAgaWYgKCFuYW1lKSB7XG4gICAgICAgIGNvbnN0IHN0cmVhbUlkID0gKChnbG9iYWwgYXMgYW55KVtTVEFCTEVfVUxJRF0gfHwgZGVmYXVsdFVsaWQpKCk7XG4gICAgICAgIG5hbWUgPSBgc3RybV8ke3N0cmVhbUlkfWA7XG4gICAgICAgIG9wcy5wdXNoKFxuICAgICAgICAgIG5ldyBXb3JrZmxvd1NlcnZlclJlYWRhYmxlU3RyZWFtKHJ1bklkLCBuYW1lKVxuICAgICAgICAgICAgLnBpcGVUaHJvdWdoKFxuICAgICAgICAgICAgICBnZXREZXNlcmlhbGl6ZVN0cmVhbShcbiAgICAgICAgICAgICAgICBnZXRTdGVwUmV2aXZlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBjcnlwdG9LZXkpLFxuICAgICAgICAgICAgICAgIGNyeXB0b0tleVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAucGlwZVRvKHZhbHVlKVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzOiBTZXJpYWxpemFibGVTcGVjaWFsWydXcml0YWJsZVN0cmVhbSddID0geyBuYW1lIH07XG4gICAgICBpZiAodHlwZW9mIGZvcmVpZ25SdW5JZCA9PT0gJ3N0cmluZycpIHMucnVuSWQgPSBmb3JlaWduUnVuSWQ7XG4gICAgICByZXR1cm4gcztcbiAgICB9LFxuXG4gICAgQWJvcnRDb250cm9sbGVyOiAodmFsdWUpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgIWdsb2JhbC5BYm9ydENvbnRyb2xsZXIgfHxcbiAgICAgICAgdHlwZW9mIGdsb2JhbC5BYm9ydENvbnRyb2xsZXIgIT09ICdmdW5jdGlvbicgfHxcbiAgICAgICAgISh2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5BYm9ydENvbnRyb2xsZXIpXG4gICAgICApXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIHJldHVybiByZWR1Y2VBYm9ydFdpdGhMaXN0ZW5lcihcbiAgICAgICAgdmFsdWUuc2lnbmFsLFxuICAgICAgICB2YWx1ZSxcbiAgICAgICAgZ2xvYmFsLFxuICAgICAgICBvcHMsXG4gICAgICAgIHJ1bklkLFxuICAgICAgICBjcnlwdG9LZXlcbiAgICAgICk7XG4gICAgfSxcblxuICAgIEFib3J0U2lnbmFsOiAodmFsdWUpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgIWdsb2JhbC5BYm9ydFNpZ25hbCB8fFxuICAgICAgICB0eXBlb2YgZ2xvYmFsLkFib3J0U2lnbmFsICE9PSAnZnVuY3Rpb24nIHx8XG4gICAgICAgICEodmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuQWJvcnRTaWduYWwpXG4gICAgICApXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIHJldHVybiByZWR1Y2VBYm9ydFdpdGhMaXN0ZW5lcihcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIHZhbHVlLFxuICAgICAgICBnbG9iYWwsXG4gICAgICAgIG9wcyxcbiAgICAgICAgcnVuSWQsXG4gICAgICAgIGNyeXB0b0tleVxuICAgICAgKTtcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIENhbmNlbCBkYW5nbGluZyBhYm9ydC1zdHJlYW0gcmVhZGVycyBvbiBhbnkgQWJvcnRDb250cm9sbGVyIGluc3RhbmNlcyBmb3VuZFxuICogaW4gdGhlIGh5ZHJhdGVkIHN0ZXAgYXJndW1lbnRzLiBDYWxsZWQgYWZ0ZXIgdGhlIHN0ZXAgZnVuY3Rpb24gcmV0dXJuc1xuICogKHN1Y2Nlc3Mgb3IgZmFpbHVyZSkgdG8gcHJldmVudCByZWFkZXIgcHJvbWlzZXMgZnJvbSBrZWVwaW5nIHRoZSBzZXJ2ZXJsZXNzXG4gKiBmdW5jdGlvbiBhbGl2ZSBpbmRlZmluaXRlbHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYW5jZWxBYm9ydFJlYWRlcnMoLi4udmFsdWVzOiB1bmtub3duW10pOiB2b2lkIHtcbiAgY29uc3QgdmlzaXRlZCA9IG5ldyBXZWFrU2V0KCk7XG4gIGZ1bmN0aW9uIGNhbmNlbElmUHJlc2VudCh2YWw6IEFib3J0SW50ZXJuYWxzKTogdm9pZCB7XG4gICAgY29uc3QgY2FuY2VsID0gdmFsW0FCT1JUX1JFQURFUl9DQU5DRUxdO1xuICAgIGlmIChjYW5jZWwgJiYgIWNhbmNlbC5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgY2FuY2VsLmFib3J0KCk7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIHdhbGsodmFsOiB1bmtub3duKTogdm9pZCB7XG4gICAgaWYgKHZhbCA9PSBudWxsIHx8IHR5cGVvZiB2YWwgIT09ICdvYmplY3QnKSByZXR1cm47XG4gICAgaWYgKHZpc2l0ZWQuaGFzKHZhbCBhcyBvYmplY3QpKSByZXR1cm47XG4gICAgdmlzaXRlZC5hZGQodmFsIGFzIG9iamVjdCk7XG4gICAgaWYgKHZhbCBpbnN0YW5jZW9mIEFib3J0Q29udHJvbGxlcikge1xuICAgICAgY2FuY2VsSWZQcmVzZW50KHZhbCBhcyBBYm9ydENvbnRyb2xsZXIgJiBBYm9ydEludGVybmFscyk7XG4gICAgICBjYW5jZWxJZlByZXNlbnQodmFsLnNpZ25hbCBhcyBBYm9ydFNpZ25hbCAmIEFib3J0SW50ZXJuYWxzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHZhbCBpbnN0YW5jZW9mIEFib3J0U2lnbmFsKSB7XG4gICAgICBjYW5jZWxJZlByZXNlbnQodmFsIGFzIEFib3J0U2lnbmFsICYgQWJvcnRJbnRlcm5hbHMpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgdmFsKSB3YWxrKGl0ZW0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodmFsIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICBmb3IgKGNvbnN0IHYgb2YgdmFsLnZhbHVlcygpKSB3YWxrKHYpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodmFsIGluc3RhbmNlb2YgU2V0KSB7XG4gICAgICBmb3IgKGNvbnN0IHYgb2YgdmFsKSB3YWxrKHYpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBSZXF1ZXN0L1Jlc3BvbnNlIGV4cG9zZSBgc2lnbmFsYC9gYm9keWAgYXMgcHJvdG90eXBlIGdldHRlcnMsIHNvXG4gICAgLy8gT2JqZWN0LnZhbHVlcygpIHdvbid0IGZpbmQgdGhlbS4gRGVzY2VuZCBleHBsaWNpdGx5LlxuICAgIGlmICh0eXBlb2YgUmVxdWVzdCAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsIGluc3RhbmNlb2YgUmVxdWVzdCkge1xuICAgICAgd2Fsayh2YWwuc2lnbmFsKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChjb25zdCB2IG9mIE9iamVjdC52YWx1ZXModmFsIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KSkgd2Fsayh2KTtcbiAgfVxuICBmb3IgKGNvbnN0IHYgb2YgdmFsdWVzKSB3YWxrKHYpO1xufVxuXG4vKipcbiAqIFNldHMgdXAgYSBzdHJlYW0gcmVhZGVyIG9uIHRoZSBjb250cm9sbGVyIHRoYXQgbGlzdGVucyBmb3IgYW4gYWJvcnQgcGFja2V0LlxuICogUmV0dXJucyB0aGUgcmVhZGVyQ2FuY2VsIGNvbnRyb2xsZXIgc28gaXQgY2FuIGJlIHN0b3JlZCBvbiBib3RoIHRoZVxuICogY29udHJvbGxlciBhbmQgc2lnbmFsIGZvciBjbGVhbnVwIGJ5IGNhbmNlbEFib3J0UmVhZGVycy5cbiAqL1xuZnVuY3Rpb24gc2V0dXBBYm9ydFN0cmVhbVJlYWRlcihcbiAgY29udHJvbGxlcjogQWJvcnRDb250cm9sbGVyLFxuICBydW5JZDogc3RyaW5nLFxuICBzdHJlYW1OYW1lOiBzdHJpbmcsXG4gIG9wczogUHJvbWlzZTx2b2lkPltdXG4pOiBBYm9ydENvbnRyb2xsZXIge1xuICBjb25zdCByZWFkZXJDYW5jZWwgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG5cbiAgb3BzLnB1c2goXG4gICAgKGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlYWRhYmxlID0gbmV3IFdvcmtmbG93U2VydmVyUmVhZGFibGVTdHJlYW0ocnVuSWQsIHN0cmVhbU5hbWUpO1xuICAgICAgICBjb25zdCByZWFkZXIgPSByZWFkYWJsZS5nZXRSZWFkZXIoKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgUHJvbWlzZS5yYWNlKFtcbiAgICAgICAgICByZWFkZXIucmVhZCgpLFxuICAgICAgICAgIG5ldyBQcm9taXNlPHsgdmFsdWU6IHVuZGVmaW5lZDsgZG9uZTogdHJ1ZSB9PigocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHJlYWRlckNhbmNlbC5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgICAgICAgICByZXNvbHZlKHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9KTtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVhZGVyQ2FuY2VsLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAnYWJvcnQnLFxuICAgICAgICAgICAgICAoKSA9PiByZXNvbHZlKHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9KSxcbiAgICAgICAgICAgICAgeyBvbmNlOiB0cnVlIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSksXG4gICAgICAgIF0pO1xuICAgICAgICByZWFkZXIucmVsZWFzZUxvY2soKTtcbiAgICAgICAgaWYgKHJlc3VsdC52YWx1ZSAmJiAhcmVzdWx0LmRvbmUpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gSHlkcmF0ZSB2aWEgdGhlIHNhbWUgbWFjaGluZXJ5IHRoZSB3cml0ZXIgdXNlZCBzbyB0aGUgcmVhc29uXG4gICAgICAgICAgICAvLyByb3VuZC10cmlwcyB3aXRoIGZ1bGwgdHlwZSBmaWRlbGl0eS4gRW5jcnlwdGlvbiBrZXkgKGlmIGFueSlcbiAgICAgICAgICAgIC8vIGNvbWVzIGZyb20gdGhlIHN0ZXAgY29udGV4dCDigJQgc2V0IHVwIGJ5IHRoZSBzdGVwIGhhbmRsZXIgYmVmb3JlXG4gICAgICAgICAgICAvLyB0aGlzIHJlYWRlciBydW5zLiBGYWxsYmFjayB0byB1bmRlZmluZWQgZm9yIGV4dGVybmFsLWNvbnRleHRcbiAgICAgICAgICAgIC8vIHJldml2ZXMgKHRoZSBoeWRyYXRlIHBhdGggaXMgZW5jcnlwdGlvbi1rZXktdG9sZXJhbnQpLlxuICAgICAgICAgICAgY29uc3QgY3R4Rm9yS2V5ID0gY29udGV4dFN0b3JhZ2UuZ2V0U3RvcmUoKTtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSAoYXdhaXQgaHlkcmF0ZVN0ZXBBcmd1bWVudHMoXG4gICAgICAgICAgICAgIHJlc3VsdC52YWx1ZSxcbiAgICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICAgIGN0eEZvcktleT8uZW5jcnlwdGlvbktleVxuICAgICAgICAgICAgKSkgYXMgeyByZWFzb24/OiB1bmtub3duIH0gfCB1bmRlZmluZWQ7XG4gICAgICAgICAgICBjb250cm9sbGVyLmFib3J0KGRhdGE/LnJlYXNvbik7XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICBjb250cm9sbGVyLmFib3J0KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gU3RyZWFtIHJlYWQgZmFpbGVkIOKAlCBzaWduYWwgd29uJ3QgcHJvcGFnYXRlIGluIHJlYWwtdGltZSxcbiAgICAgICAgLy8gYnV0IGhvb2stYmFzZWQgcHJvcGFnYXRpb24gb24gbmV4dCByZXBsYXkgcHJvdmlkZXMgZmFsbGJhY2tcbiAgICAgIH1cbiAgICB9KSgpXG4gICk7XG5cbiAgcmV0dXJuIHJlYWRlckNhbmNlbDtcbn1cblxuLyoqXG4gKiBTdG9yZXMgYWJvcnQgc2VyaWFsaXphdGlvbiBzeW1ib2xzIGFuZCB0aGUgcmVhZGVyQ2FuY2VsIGNvbnRyb2xsZXJcbiAqIG9uIGJvdGggdGhlIGNvbnRyb2xsZXIgYW5kIGl0cyBzaWduYWwuXG4gKi9cbmZ1bmN0aW9uIHRhZ0Fib3J0UGFpcihcbiAgY29udHJvbGxlcjogQWJvcnRDb250cm9sbGVyLFxuICB2YWx1ZTogeyBzdHJlYW1OYW1lOiBzdHJpbmc7IGhvb2tUb2tlbjogc3RyaW5nIH0sXG4gIHJlYWRlckNhbmNlbD86IEFib3J0Q29udHJvbGxlclxuKTogdm9pZCB7XG4gIGNvbnN0IHRhZ2dlZENvbnRyb2xsZXIgPSBjb250cm9sbGVyIGFzIEFib3J0Q29udHJvbGxlciAmIEFib3J0SW50ZXJuYWxzO1xuICBjb25zdCB0YWdnZWRTaWduYWwgPSBjb250cm9sbGVyLnNpZ25hbCBhcyBBYm9ydFNpZ25hbCAmIEFib3J0SW50ZXJuYWxzO1xuICB0YWdnZWRDb250cm9sbGVyW0FCT1JUX1NUUkVBTV9OQU1FXSA9IHZhbHVlLnN0cmVhbU5hbWU7XG4gIHRhZ2dlZENvbnRyb2xsZXJbQUJPUlRfSE9PS19UT0tFTl0gPSB2YWx1ZS5ob29rVG9rZW47XG4gIHRhZ2dlZFNpZ25hbFtBQk9SVF9TVFJFQU1fTkFNRV0gPSB2YWx1ZS5zdHJlYW1OYW1lO1xuICB0YWdnZWRTaWduYWxbQUJPUlRfSE9PS19UT0tFTl0gPSB2YWx1ZS5ob29rVG9rZW47XG4gIGlmIChyZWFkZXJDYW5jZWwpIHtcbiAgICB0YWdnZWRDb250cm9sbGVyW0FCT1JUX1JFQURFUl9DQU5DRUxdID0gcmVhZGVyQ2FuY2VsO1xuICAgIHRhZ2dlZFNpZ25hbFtBQk9SVF9SRUFERVJfQ0FOQ0VMXSA9IHJlYWRlckNhbmNlbDtcbiAgfVxufVxuXG4vKipcbiAqIFByb3BhZ2F0ZSBhYm9ydC1pbnRlcm5hbCBzeW1ib2xzIGZyb20gb25lIHNpZ25hbCB0byBhbm90aGVyLiBVc2VkIGJ5IHRoZVxuICogUmVxdWVzdCByZXZpdmVyIGJlY2F1c2UgYG5ldyBSZXF1ZXN0KHVybCwgeyBzaWduYWwgfSlgIGNvcGllcyB0aGUgc2lnbmFsXG4gKiBpbnRlcm5hbGx5IOKAlCB0aGUgY29uc3RydWN0ZWQgYHJlcXVlc3Quc2lnbmFsYCBpcyBhIGZyZXNoIEFib3J0U2lnbmFsIHRoYXRcbiAqIGRvZXNuJ3QgY2Fycnkgc3ltYm9scyBmcm9tIHRoZSBzb3VyY2UuXG4gKi9cbmZ1bmN0aW9uIGNvcHlBYm9ydEludGVybmFscyhzcmM6IEFib3J0U2lnbmFsLCBkZXN0OiBBYm9ydFNpZ25hbCk6IHZvaWQge1xuICBjb25zdCBzID0gc3JjIGFzIEFib3J0U2lnbmFsICYgQWJvcnRJbnRlcm5hbHM7XG4gIGNvbnN0IGQgPSBkZXN0IGFzIEFib3J0U2lnbmFsICYgQWJvcnRJbnRlcm5hbHM7XG4gIGlmIChzW0FCT1JUX1NUUkVBTV9OQU1FXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZFtBQk9SVF9TVFJFQU1fTkFNRV0gPSBzW0FCT1JUX1NUUkVBTV9OQU1FXTtcbiAgfVxuICBpZiAoc1tBQk9SVF9IT09LX1RPS0VOXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZFtBQk9SVF9IT09LX1RPS0VOXSA9IHNbQUJPUlRfSE9PS19UT0tFTl07XG4gIH1cbiAgaWYgKHNbQUJPUlRfUkVBREVSX0NBTkNFTF0gIT09IHVuZGVmaW5lZCkge1xuICAgIGRbQUJPUlRfUkVBREVSX0NBTkNFTF0gPSBzW0FCT1JUX1JFQURFUl9DQU5DRUxdO1xuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBBYm9ydENvbnRyb2xsZXIgd2l0aCBzdHJlYW0tYmFja2VkIGFib3J0IHByb3BhZ2F0aW9uLlxuICogVXNlZCBieSBzdGVwIGFuZCBleHRlcm5hbCByZXZpdmVycyB3aGVyZSByZWFsIGFib3J0IHNpZ25hbCBiZWhhdmlvciBpcyBuZWVkZWQuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHNlcmlhbGl6ZWQgYWJvcnQgY29udHJvbGxlci9zaWduYWwgZGF0YVxuICogQHBhcmFtIG9wcyAtIFRoZSBvcHMgYXJyYXkgZm9yIHRyYWNraW5nIGFzeW5jIHdvcmtcbiAqIEBwYXJhbSBydW5JZCAtIFRoZSB3b3JrZmxvdyBydW4gSUQgKGZvciBzdHJlYW0gcmVhZHMpXG4gKiBAcmV0dXJucyBBIHJlYWwgQWJvcnRDb250cm9sbGVyIHdpdGggcGF0Y2hlZCBhYm9ydCgpIG1ldGhvZFxuICovXG5mdW5jdGlvbiByZXZpdmVBYm9ydENvbnRyb2xsZXIoXG4gIHZhbHVlOiBTZXJpYWxpemFibGVTcGVjaWFsWydBYm9ydENvbnRyb2xsZXInXSxcbiAgb3BzOiBQcm9taXNlPHZvaWQ+W10sXG4gIHJ1bklkOiBzdHJpbmdcbik6IEFib3J0Q29udHJvbGxlciB7XG4gIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG5cbiAgaWYgKHZhbHVlLmFib3J0ZWQpIHtcbiAgICB0YWdBYm9ydFBhaXIoY29udHJvbGxlciwgdmFsdWUpO1xuICAgIGNvbnRyb2xsZXIuYWJvcnQodmFsdWUucmVhc29uKTtcbiAgfSBlbHNlIGlmICh2YWx1ZS5zdHJlYW1OYW1lKSB7XG4gICAgY29uc3QgcmVhZGVyQ2FuY2VsID0gc2V0dXBBYm9ydFN0cmVhbVJlYWRlcihcbiAgICAgIGNvbnRyb2xsZXIsXG4gICAgICBydW5JZCxcbiAgICAgIHZhbHVlLnN0cmVhbU5hbWUsXG4gICAgICBvcHNcbiAgICApO1xuICAgIHRhZ0Fib3J0UGFpcihjb250cm9sbGVyLCB2YWx1ZSwgcmVhZGVyQ2FuY2VsKTtcbiAgfSBlbHNlIHtcbiAgICB0YWdBYm9ydFBhaXIoY29udHJvbGxlciwgdmFsdWUpO1xuICB9XG5cbiAgLy8gT3ZlcnJpZGUgYWJvcnQoKSB0byBhbHNvIHdyaXRlIHN0cmVhbSArIHJlc3VtZSBob29rIChmb3Igc3RlcC1pbml0aWF0ZWQgYWJvcnQpXG4gIGNvbnN0IG9yaWdpbmFsQWJvcnQgPSBjb250cm9sbGVyLmFib3J0LmJpbmQoY29udHJvbGxlcik7XG4gIGNvbnRyb2xsZXIuYWJvcnQgPSAocmVhc29uPzogdW5rbm93bikgPT4ge1xuICAgIGlmIChjb250cm9sbGVyLnNpZ25hbC5hYm9ydGVkKSByZXR1cm47XG4gICAgb3JpZ2luYWxBYm9ydChyZWFzb24pO1xuXG4gICAgY29uc3QgY3R4ID0gY29udGV4dFN0b3JhZ2UuZ2V0U3RvcmUoKTtcbiAgICBpZiAoY3R4KSB7XG4gICAgICBjdHgub3BzLnB1c2goXG4gICAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIERlaHlkcmF0ZSB0aGUgYWJvcnQgcGF5bG9hZCB0aHJvdWdoIHRoZSBzYW1lIG1hY2hpbmVyeSB0aGUgaG9va1xuICAgICAgICAgICAgLy8gZXZlbnQgdXNlcyBzbyB0aGUgYHJlYXNvbmAgcm91bmQtdHJpcHMgd2l0aCBmdWxsIHR5cGUgZmlkZWxpdHlcbiAgICAgICAgICAgIC8vIChET01FeGNlcHRpb24sIGN1c3RvbSBlcnJvcnMsIGV0Yy4pIGFuZCByZXNwZWN0cyB0aGUgcnVuJ3NcbiAgICAgICAgICAgIC8vIGVuY3J5cHRpb24ga2V5IOKAlCBzeW1tZXRyaWMgd2l0aCB3aGF0IHRoZSBzdXNwZW5zaW9uIGhhbmRsZXJcbiAgICAgICAgICAgIC8vIHdyaXRlcyBmb3Igd29ya2Zsb3ctaW5pdGlhdGVkIGFib3J0cy5cbiAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBhd2FpdCBkZWh5ZHJhdGVTdGVwQXJndW1lbnRzKFxuICAgICAgICAgICAgICB7IGFib3J0ZWQ6IHRydWUsIHJlYXNvbiB9LFxuICAgICAgICAgICAgICBjdHgud29ya2Zsb3dNZXRhZGF0YS53b3JrZmxvd1J1bklkLFxuICAgICAgICAgICAgICBjdHguZW5jcnlwdGlvbktleVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IHdyaXRhYmxlID0gbmV3IFdvcmtmbG93U2VydmVyV3JpdGFibGVTdHJlYW0oXG4gICAgICAgICAgICAgIGN0eC53b3JrZmxvd01ldGFkYXRhLndvcmtmbG93UnVuSWQsXG4gICAgICAgICAgICAgIHZhbHVlLnN0cmVhbU5hbWVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCB3cml0ZXIgPSB3cml0YWJsZS5nZXRXcml0ZXIoKTtcbiAgICAgICAgICAgIGF3YWl0IHdyaXRlci53cml0ZShwYXlsb2FkIGFzIFVpbnQ4QXJyYXkpO1xuICAgICAgICAgICAgYXdhaXQgd3JpdGVyLmNsb3NlKCk7XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAvLyBCZXN0LWVmZm9ydCBzdHJlYW0gd3JpdGVcbiAgICAgICAgICB9XG4gICAgICAgIH0pKClcbiAgICAgICk7XG5cbiAgICAgIGlmICh2YWx1ZS5ob29rVG9rZW4pIHtcbiAgICAgICAgY3R4Lm9wcy5wdXNoKFxuICAgICAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCB7IHJlc3VtZUhvb2s6IHJlc3VtZUhvb2tGbiB9ID0gYXdhaXQgaW1wb3J0KFxuICAgICAgICAgICAgICAgICcuL3J1bnRpbWUvcmVzdW1lLWhvb2suanMnXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGF3YWl0IHJlc3VtZUhvb2tGbih2YWx1ZS5ob29rVG9rZW4sIHtcbiAgICAgICAgICAgICAgICBhYm9ydGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIHJlYXNvbixcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgICAgLy8gQmVzdC1lZmZvcnQgaG9vayByZXN1bWUg4oCUIHJldHJ5IG9uIG5leHQgcmVwbGF5XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSkoKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICByZXR1cm4gY29udHJvbGxlcjtcbn1cblxuLyoqXG4gKiBSZXZpdmVzIGp1c3QgYW4gQWJvcnRTaWduYWwgd2l0aG91dCB0aGUgcGF0Y2hlZCBhYm9ydCgpIG92ZXJoZWFkLlxuICogVXNlZCB3aGVuIG9ubHkgYSBzaWduYWwgKG5vdCBhIGNvbnRyb2xsZXIpIHdhcyBzZXJpYWxpemVkLlxuICovXG5mdW5jdGlvbiByZXZpdmVBYm9ydFNpZ25hbChcbiAgdmFsdWU6IFNlcmlhbGl6YWJsZVNwZWNpYWxbJ0Fib3J0U2lnbmFsJ10sXG4gIG9wczogUHJvbWlzZTx2b2lkPltdLFxuICBydW5JZDogc3RyaW5nXG4pOiBBYm9ydFNpZ25hbCB7XG4gIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG5cbiAgaWYgKHZhbHVlLmFib3J0ZWQpIHtcbiAgICB0YWdBYm9ydFBhaXIoY29udHJvbGxlciwgdmFsdWUpO1xuICAgIGNvbnRyb2xsZXIuYWJvcnQodmFsdWUucmVhc29uKTtcbiAgfSBlbHNlIGlmICh2YWx1ZS5zdHJlYW1OYW1lKSB7XG4gICAgY29uc3QgcmVhZGVyQ2FuY2VsID0gc2V0dXBBYm9ydFN0cmVhbVJlYWRlcihcbiAgICAgIGNvbnRyb2xsZXIsXG4gICAgICBydW5JZCxcbiAgICAgIHZhbHVlLnN0cmVhbU5hbWUsXG4gICAgICBvcHNcbiAgICApO1xuICAgIHRhZ0Fib3J0UGFpcihjb250cm9sbGVyLCB2YWx1ZSwgcmVhZGVyQ2FuY2VsKTtcbiAgfSBlbHNlIHtcbiAgICB0YWdBYm9ydFBhaXIoY29udHJvbGxlciwgdmFsdWUpO1xuICB9XG5cbiAgcmV0dXJuIGNvbnRyb2xsZXIuc2lnbmFsO1xufVxuXG4vKipcbiAqIEJhc2UgcmV2aXZlcnMgc2hhcmVkIGFjcm9zcyBhbGwgc2VyaWFsaXphdGlvbiBib3VuZGFyaWVzLlxuICogQ29tcG9zZXM6IGNsYXNzICsgY29tbW9uIHJldml2ZXJzIGZyb20gdGhlIG1vZHVsYXIgbW9kdWxlcy5cbiAqXG4gKiBUaGlzIGlzIGV4cG9ydGVkIGJlY2F1c2Ugc2VyaWFsaXphdGlvbi1mb3JtYXQudHMgYW5kIG90aGVyIGZpbGVzIHJlZmVyZW5jZSBpdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldENvbW1vblJldml2ZXJzKGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMpIHtcbiAgcmV0dXJuIHtcbiAgICAuLi5nZXRDbGFzc1Jldml2ZXJzKGdsb2JhbCksXG4gICAgLi4uZ2V0Q29tbW9uUmV2aXZlcnNGcm9tTW9kdWxlKGdsb2JhbCksXG4gIH0gYXMgY29uc3Qgc2F0aXNmaWVzIFBhcnRpYWw8UmV2aXZlcnM+O1xufVxuXG4vKipcbiAqIFJldml2ZXJzIGZvciBkZXNlcmlhbGl6YXRpb24gYm91bmRhcnkgZnJvbSB0aGUgY2xpZW50IHNpZGUsXG4gKiByZWNlaXZpbmcgdGhlIHJldHVybiB2YWx1ZSBmcm9tIHRoZSB3b3JrZmxvdyBoYW5kbGVyLlxuICpcbiAqIEBwYXJhbSBnbG9iYWxcbiAqIEBwYXJhbSBvcHNcbiAqIEBwYXJhbSBydW5JZFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXh0ZXJuYWxSZXZpdmVycyhcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpcyxcbiAgb3BzOiBQcm9taXNlPHZvaWQ+W10sXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGNyeXB0b0tleTogRW5jcnlwdGlvbktleVBhcmFtXG4pOiBQYXJ0aWFsPFJldml2ZXJzPiB7XG4gIHJldHVybiB7XG4gICAgLi4uZ2V0Q29tbW9uUmV2aXZlcnMoZ2xvYmFsKSxcblxuICAgIC8vIFN0ZXBGdW5jdGlvbiBzaG91bGQgbm90IGJlIHJldHVybmVkIGZyb20gd29ya2Zsb3dzIHRvIGNsaWVudHNcbiAgICBTdGVwRnVuY3Rpb246ICgpID0+IHtcbiAgICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoXG4gICAgICAgICdTdGVwIGZ1bmN0aW9ucyBjYW5ub3QgYmUgZGVzZXJpYWxpemVkIGluIGNsaWVudCBjb250ZXh0LiBTdGVwIGZ1bmN0aW9ucyBzaG91bGQgbm90IGJlIHJldHVybmVkIGZyb20gd29ya2Zsb3dzLicsXG4gICAgICAgIHtcbiAgICAgICAgICBoaW50OiAnQSBzdGVwIGZ1bmN0aW9uIHJlZmVyZW5jZSByZWFjaGVkIHRoZSBjbGllbnQuIFJldHVybiBhIHNlcmlhbGl6YWJsZSB2YWx1ZSAoZS5nLiB0aGUgc3RlcCByZXN1bHQpIGluc3RlYWQgb2YgdGhlIHN0ZXAgaXRzZWxmLicsXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSxcblxuICAgIFdvcmtmbG93RnVuY3Rpb246ICh2YWx1ZSkgPT5cbiAgICAgIE9iamVjdC5hc3NpZ24oXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgICAgICAgJ1dvcmtmbG93IGZ1bmN0aW9ucyBjYW5ub3QgYmUgY2FsbGVkIGRpcmVjdGx5LiBVc2Ugc3RhcnQoKSB0byBpbnZva2UgdGhlbS4nLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBoaW50OiAnV3JhcCB0aGUgd29ya2Zsb3cgd2l0aCBgc3RhcnQod29ya2Zsb3dGbiwgeyAuLi4gfSlgIGZyb20gYHdvcmtmbG93YCB0byBiZWdpbiBhIHJ1biBpbnN0ZWFkIG9mIGludm9raW5nIGl0IGxpa2UgYSBub3JtYWwgZnVuY3Rpb24uJyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9LFxuICAgICAgICB7IHdvcmtmbG93SWQ6IHZhbHVlLndvcmtmbG93SWQgfVxuICAgICAgKSxcblxuICAgIFJlcXVlc3Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgY29uc3QgaW5pdDogUmVxdWVzdEluaXQgJiB7IGR1cGxleD86IHN0cmluZyB9ID0ge1xuICAgICAgICBtZXRob2Q6IHZhbHVlLm1ldGhvZCxcbiAgICAgICAgaGVhZGVyczogbmV3IGdsb2JhbC5IZWFkZXJzKHZhbHVlLmhlYWRlcnMpLFxuICAgICAgICBib2R5OiB2YWx1ZS5ib2R5LFxuICAgICAgICBkdXBsZXg6IHZhbHVlLmR1cGxleCxcbiAgICAgIH07XG4gICAgICBpZiAodmFsdWUuc2lnbmFsKSBpbml0LnNpZ25hbCA9IHZhbHVlLnNpZ25hbDtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ2xvYmFsLlJlcXVlc3QodmFsdWUudXJsLCBpbml0KTtcbiAgICAgIC8vIFRoZSBSZXF1ZXN0IGNvbnN0cnVjdG9yIGNyZWF0ZXMgYW4gaW50ZXJuYWwgc2lnbmFsIGNvcHksIHNvIHRoZVxuICAgICAgLy8gYWJvcnQtaW50ZXJuYWwgc3ltYm9scyBzZXQgYnkgcmV2aXZlQWJvcnRTaWduYWwgZG9uJ3QgcHJvcGFnYXRlLlxuICAgICAgLy8gUmUtdGFnIHRoZSByZXF1ZXN0J3Mgb3duIHNpZ25hbCBzbyBjYW5jZWxBYm9ydFJlYWRlcnMgY2FuIGZpbmQgaXQuXG4gICAgICBpZiAodmFsdWUuc2lnbmFsKSBjb3B5QWJvcnRJbnRlcm5hbHModmFsdWUuc2lnbmFsLCByZXF1ZXN0LnNpZ25hbCk7XG4gICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICB9LFxuICAgIFJlc3BvbnNlOiAodmFsdWUpID0+IHtcbiAgICAgIC8vIE5vdGU6IFJlc3BvbnNlIGNvbnN0cnVjdG9yIG9ubHkgYWNjZXB0cyBzdGF0dXMsIHN0YXR1c1RleHQsIGFuZCBoZWFkZXJzXG4gICAgICAvLyBUaGUgdHlwZSwgdXJsLCBhbmQgcmVkaXJlY3RlZCBwcm9wZXJ0aWVzIGFyZSByZWFkLW9ubHkgYW5kIHNldCBieSB0aGUgY29uc3RydWN0b3JcbiAgICAgIHJldHVybiBuZXcgZ2xvYmFsLlJlc3BvbnNlKHZhbHVlLmJvZHksIHtcbiAgICAgICAgc3RhdHVzOiB2YWx1ZS5zdGF0dXMsXG4gICAgICAgIHN0YXR1c1RleHQ6IHZhbHVlLnN0YXR1c1RleHQsXG4gICAgICAgIGhlYWRlcnM6IG5ldyBnbG9iYWwuSGVhZGVycyh2YWx1ZS5oZWFkZXJzKSxcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgUmVhZGFibGVTdHJlYW06ICh2YWx1ZSkgPT4ge1xuICAgICAgLy8gSWYgdGhpcyBoYXMgYm9keUluaXQsIGl0IGNhbWUgZnJvbSBhIFJlc3BvbnNlIGNvbnN0cnVjdG9yXG4gICAgICAvLyBDb252ZXJ0IGl0IHRvIGEgUkVBTCBzdHJlYW0gbm93IHRoYXQgd2UncmUgb3V0c2lkZSB0aGUgd29ya2Zsb3dcbiAgICAgIGlmICgnYm9keUluaXQnIGluIHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IGJvZHlJbml0ID0gdmFsdWUuYm9keUluaXQ7XG4gICAgICAgIC8vIFVzZSB0aGUgbmF0aXZlIFJlc3BvbnNlIGNvbnN0cnVjdG9yIHRvIHByb3Blcmx5IGNvbnZlcnQgQm9keUluaXQgdG8gUmVhZGFibGVTdHJlYW1cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBuZXcgZ2xvYmFsLlJlc3BvbnNlKGJvZHlJbml0KTtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLmJvZHk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlYWRhYmxlID0gbmV3IFdvcmtmbG93U2VydmVyUmVhZGFibGVTdHJlYW0oXG4gICAgICAgIHJ1bklkLFxuICAgICAgICB2YWx1ZS5uYW1lLFxuICAgICAgICB2YWx1ZS5zdGFydEluZGV4XG4gICAgICApO1xuICAgICAgaWYgKHZhbHVlLnR5cGUgPT09ICdieXRlcycpIHtcbiAgICAgICAgLy8gRm9yIGJ5dGUgc3RyZWFtcywgdXNlIGZsdXNoYWJsZSBwaXBlIHdpdGggbG9jayBwb2xsaW5nXG4gICAgICAgIGNvbnN0IHN0YXRlID0gY3JlYXRlRmx1c2hhYmxlU3RhdGUoKTtcbiAgICAgICAgb3BzLnB1c2goc3RhdGUucHJvbWlzZSk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIGFuIGlkZW50aXR5IHRyYW5zZm9ybSB0byBnaXZlIHRoZSB1c2VyIGEgcmVhZGFibGVcbiAgICAgICAgY29uc3QgeyByZWFkYWJsZTogdXNlclJlYWRhYmxlLCB3cml0YWJsZSB9ID1cbiAgICAgICAgICBuZXcgZ2xvYmFsLlRyYW5zZm9ybVN0cmVhbSgpO1xuXG4gICAgICAgIC8vIFN0YXJ0IHRoZSBmbHVzaGFibGUgcGlwZSBpbiB0aGUgYmFja2dyb3VuZFxuICAgICAgICBmbHVzaGFibGVQaXBlKHJlYWRhYmxlLCB3cml0YWJsZSwgc3RhdGUpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAvLyBFcnJvcnMgYXJlIGhhbmRsZWQgdmlhIHN0YXRlLnJlamVjdFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTdGFydCBwb2xsaW5nIHRvIGRldGVjdCB3aGVuIHVzZXIgcmVsZWFzZXMgbG9ja1xuICAgICAgICBwb2xsUmVhZGFibGVMb2NrKHVzZXJSZWFkYWJsZSwgc3RhdGUpO1xuXG4gICAgICAgIHJldHVybiB1c2VyUmVhZGFibGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCB0cmFuc2Zvcm0gPSBnZXREZXNlcmlhbGl6ZVN0cmVhbShcbiAgICAgICAgICBnZXRFeHRlcm5hbFJldml2ZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwgY3J5cHRvS2V5KSxcbiAgICAgICAgICBjcnlwdG9LZXlcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3Qgc3RhdGUgPSBjcmVhdGVGbHVzaGFibGVTdGF0ZSgpO1xuICAgICAgICBvcHMucHVzaChzdGF0ZS5wcm9taXNlKTtcblxuICAgICAgICAvLyBTdGFydCB0aGUgZmx1c2hhYmxlIHBpcGUgaW4gdGhlIGJhY2tncm91bmRcbiAgICAgICAgZmx1c2hhYmxlUGlwZShyZWFkYWJsZSwgdHJhbnNmb3JtLndyaXRhYmxlLCBzdGF0ZSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgIC8vIEVycm9ycyBhcmUgaGFuZGxlZCB2aWEgc3RhdGUucmVqZWN0XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFN0YXJ0IHBvbGxpbmcgdG8gZGV0ZWN0IHdoZW4gdXNlciByZWxlYXNlcyBsb2NrXG4gICAgICAgIHBvbGxSZWFkYWJsZUxvY2sodHJhbnNmb3JtLnJlYWRhYmxlLCBzdGF0ZSk7XG5cbiAgICAgICAgcmV0dXJuIHRyYW5zZm9ybS5yZWFkYWJsZTtcbiAgICAgIH1cbiAgICB9LFxuICAgIFdyaXRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIC8vIFNhbWUgaGFuZGxpbmcgYXMgYGdldFN0ZXBSZXZpdmVycy5Xcml0YWJsZVN0cmVhbWAg4oCUIHNlZSBjb21tZW50c1xuICAgICAgLy8gdGhlcmUgZm9yIHRoZSBjcm9zcy1ydW4gY2FzZSAod3JpdGFibGUgY2FycmllcyBgcnVuSWRgIGZyb21cbiAgICAgIC8vIHBhcmVudCDihpIgY2hpbGQgZm9yd2FyZGluZyB2aWEgYHN0YXJ0KClgKS5cbiAgICAgIGNvbnN0IHRhcmdldFJ1bklkID0gdHlwZW9mIHZhbHVlLnJ1bklkID09PSAnc3RyaW5nJyA/IHZhbHVlLnJ1bklkIDogcnVuSWQ7XG4gICAgICBjb25zdCB0YXJnZXRLZXk6IEVuY3J5cHRpb25LZXlQYXJhbSA9XG4gICAgICAgIHRhcmdldFJ1bklkID09PSBydW5JZFxuICAgICAgICAgID8gY3J5cHRvS2V5XG4gICAgICAgICAgOiAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB3b3JsZCA9IGF3YWl0IGdldFdvcmxkTGF6eSgpO1xuICAgICAgICAgICAgICBjb25zdCByYXdLZXkgPSBhd2FpdCB3b3JsZC5nZXRFbmNyeXB0aW9uS2V5Rm9yUnVuPy4odGFyZ2V0UnVuSWQpO1xuICAgICAgICAgICAgICByZXR1cm4gcmF3S2V5ID8gYXdhaXQgaW1wb3J0S2V5KHJhd0tleSwgWydlbmNyeXB0J10pIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgfSkoKTtcblxuICAgICAgY29uc3Qgc2VyaWFsaXplID0gZ2V0U2VyaWFsaXplU3RyZWFtKFxuICAgICAgICBnZXRFeHRlcm5hbFJlZHVjZXJzKGdsb2JhbCwgb3BzLCB0YXJnZXRSdW5JZCwgdGFyZ2V0S2V5KSxcbiAgICAgICAgdGFyZ2V0S2V5XG4gICAgICApO1xuICAgICAgY29uc3Qgc2VydmVyV3JpdGFibGUgPSBuZXcgV29ya2Zsb3dTZXJ2ZXJXcml0YWJsZVN0cmVhbShcbiAgICAgICAgdGFyZ2V0UnVuSWQsXG4gICAgICAgIHZhbHVlLm5hbWVcbiAgICAgICk7XG5cbiAgICAgIC8vIENyZWF0ZSBmbHVzaGFibGUgc3RhdGUgZm9yIHRoaXMgc3RyZWFtXG4gICAgICBjb25zdCBzdGF0ZSA9IGNyZWF0ZUZsdXNoYWJsZVN0YXRlKCk7XG4gICAgICBvcHMucHVzaChzdGF0ZS5wcm9taXNlKTtcblxuICAgICAgLy8gU3RhcnQgdGhlIGZsdXNoYWJsZSBwaXBlIGluIHRoZSBiYWNrZ3JvdW5kXG4gICAgICBmbHVzaGFibGVQaXBlKHNlcmlhbGl6ZS5yZWFkYWJsZSwgc2VydmVyV3JpdGFibGUsIHN0YXRlKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgIC8vIEVycm9ycyBhcmUgaGFuZGxlZCB2aWEgc3RhdGUucmVqZWN0XG4gICAgICB9KTtcblxuICAgICAgLy8gU3RhcnQgcG9sbGluZyB0byBkZXRlY3Qgd2hlbiB1c2VyIHJlbGVhc2VzIGxvY2tcbiAgICAgIHBvbGxXcml0YWJsZUxvY2soc2VyaWFsaXplLndyaXRhYmxlLCBzdGF0ZSk7XG5cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzZXJpYWxpemUud3JpdGFibGUsIFNUUkVBTV9OQU1FX1NZTUJPTCwge1xuICAgICAgICB2YWx1ZTogdmFsdWUubmFtZSxcbiAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgfSk7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoc2VyaWFsaXplLndyaXRhYmxlLCBTVFJFQU1fU0VSVkVSX1JVTl9JRF9TWU1CT0wsIHtcbiAgICAgICAgdmFsdWU6IHRhcmdldFJ1bklkLFxuICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHNlcmlhbGl6ZS53cml0YWJsZTtcbiAgICB9LFxuXG4gICAgQWJvcnRDb250cm9sbGVyOiAodmFsdWUpID0+IHJldml2ZUFib3J0Q29udHJvbGxlcih2YWx1ZSwgb3BzLCBydW5JZCksXG4gICAgQWJvcnRTaWduYWw6ICh2YWx1ZSkgPT4gcmV2aXZlQWJvcnRTaWduYWwodmFsdWUsIG9wcywgcnVuSWQpLFxuICB9O1xufVxuXG4vKipcbiAqIFJldml2ZXJzIGZvciBkZXNlcmlhbGl6YXRpb24gYm91bmRhcnkgZnJvbSB3aXRoaW4gdGhlIHdvcmtmbG93IGV4ZWN1dGlvblxuICogZW52aXJvbm1lbnQsIHJlY2VpdmluZyBhcmd1bWVudHMgZnJvbSB0aGUgY2xpZW50IHNpZGUsIGFuZCByZXR1cm4gdmFsdWVzXG4gKiBmcm9tIHRoZSBzdGVwcy5cbiAqXG4gKiBAcGFyYW0gZ2xvYmFsXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0V29ya2Zsb3dSZXZpdmVycyhcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpc1xuKTogUGFydGlhbDxSZXZpdmVycz4ge1xuICByZXR1cm4ge1xuICAgIC4uLmdldENvbW1vblJldml2ZXJzKGdsb2JhbCksXG4gICAgLy8gU3RlcEZ1bmN0aW9uIHJldml2ZXIgZm9yIHdvcmtmbG93IGNvbnRleHQgLSB1c2VzIHRoZSBtb2R1bGFyIHJldml2ZXJcbiAgICAvLyB3aGljaCBjYWxscyBXT1JLRkxPV19VU0VfU1RFUCBmcm9tIGdsb2JhbCB0byByZWNvbnN0cnVjdCBzdGVwIHByb3hpZXNcbiAgICAuLi5nZXRTdGVwRnVuY3Rpb25SZXZpdmVyKGdsb2JhbCksXG4gICAgUmVxdWVzdDogKHZhbHVlKSA9PiB7XG4gICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodmFsdWUsIGdsb2JhbC5SZXF1ZXN0LnByb3RvdHlwZSk7XG4gICAgICBjb25zdCByZXNwb25zZVdyaXRhYmxlID0gdmFsdWUucmVzcG9uc2VXcml0YWJsZTtcbiAgICAgIGlmIChyZXNwb25zZVdyaXRhYmxlKSB7XG4gICAgICAgICh2YWx1ZSBhcyBhbnkpW1dFQkhPT0tfUkVTUE9OU0VfV1JJVEFCTEVdID0gcmVzcG9uc2VXcml0YWJsZTtcbiAgICAgICAgZGVsZXRlIHZhbHVlLnJlc3BvbnNlV3JpdGFibGU7XG4gICAgICAgICh2YWx1ZSBhcyBhbnkpLnJlc3BvbmRXaXRoID0gKCkgPT4ge1xuICAgICAgICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoXG4gICAgICAgICAgICAnYHJlc3BvbmRXaXRoKClgIG11c3QgYmUgY2FsbGVkIGZyb20gd2l0aGluIGEgc3RlcCBmdW5jdGlvbi4nLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBoaW50OiAnTW92ZSB0aGUgYHJlc3BvbmRXaXRoKC4uLilgIGNhbGwgaW5zaWRlIGEgYFwidXNlIHN0ZXBcImAgZnVuY3Rpb24g4oCUIGl0IGNhbm5vdCBiZSBpbnZva2VkIGZyb20gYSB3b3JrZmxvdyBjb250ZXh0LicsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9LFxuICAgIC8vIFdvcmtmbG93IGZ1bmN0aW9uIHJldml2ZXIgZm9yIHdvcmtmbG93IGNvbnRleHQg4oCUIHJldHVybnMgYSBmdW5jdGlvbi1saWtlXG4gICAgLy8gb2JqZWN0IHdpdGggLndvcmtmbG93SWQgdGhhdCBtaW1pY3Mgd2hhdCB0aGUgU1dDIGNvbXBpbGVyIHByb2R1Y2VzLFxuICAgIFdvcmtmbG93RnVuY3Rpb246ICh2YWx1ZSkgPT5cbiAgICAgIE9iamVjdC5hc3NpZ24oXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgICAgICAgJ1dvcmtmbG93IGZ1bmN0aW9ucyBjYW5ub3QgYmUgY2FsbGVkIGRpcmVjdGx5LiBVc2Ugc3RhcnQoKSB0byBpbnZva2UgdGhlbS4nLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBoaW50OiAnV3JhcCB0aGUgd29ya2Zsb3cgd2l0aCBgc3RhcnQod29ya2Zsb3dGbiwgeyAuLi4gfSlgIGZyb20gYHdvcmtmbG93YCB0byBiZWdpbiBhIHJ1biBpbnN0ZWFkIG9mIGludm9raW5nIGl0IGxpa2UgYSBub3JtYWwgZnVuY3Rpb24uJyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9LFxuICAgICAgICB7IHdvcmtmbG93SWQ6IHZhbHVlLndvcmtmbG93SWQgfVxuICAgICAgKSxcbiAgICBSZXNwb25zZTogKHZhbHVlKSA9PiB7XG4gICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodmFsdWUsIGdsb2JhbC5SZXNwb25zZS5wcm90b3R5cGUpO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0sXG4gICAgUmVhZGFibGVTdHJlYW06ICh2YWx1ZSkgPT4ge1xuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIEJvZHlJbml0IHRoYXQgc2hvdWxkIGJlIHdyYXBwZWQgaW4gYSBmYWtlIHN0cmVhbVxuICAgICAgaWYgKCdib2R5SW5pdCcgaW4gdmFsdWUpIHtcbiAgICAgICAgLy8gUmVjcmVhdGUgdGhlIGZha2Ugc3RyZWFtIHdpdGggdGhlIEJvZHlJbml0XG4gICAgICAgIHJldHVybiBPYmplY3QuY3JlYXRlKGdsb2JhbC5SZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICAgICAgICBbQk9EWV9JTklUX1NZTUJPTF06IHtcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZS5ib2R5SW5pdCxcbiAgICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gUmVndWxhciBzdHJlYW0gaGFuZGxpbmdcbiAgICAgIHJldHVybiBPYmplY3QuY3JlYXRlKGdsb2JhbC5SZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICAgICAgW1NUUkVBTV9OQU1FX1NZTUJPTF06IHtcbiAgICAgICAgICB2YWx1ZTogdmFsdWUubmFtZSxcbiAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIFtTVFJFQU1fVFlQRV9TWU1CT0xdOiB7XG4gICAgICAgICAgdmFsdWU6IHZhbHVlLnR5cGUsXG4gICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSxcbiAgICBXcml0YWJsZVN0cmVhbTogKHZhbHVlKSA9PiB7XG4gICAgICBjb25zdCBkZXNjcmlwdG9yOiBQcm9wZXJ0eURlc2NyaXB0b3JNYXAgPSB7XG4gICAgICAgIFtTVFJFQU1fTkFNRV9TWU1CT0xdOiB7XG4gICAgICAgICAgdmFsdWU6IHZhbHVlLm5hbWUsXG4gICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIC8vIFByZXNlcnZlIHRoZSBmb3JlaWduIHJ1bklkLCBpZiBwcmVzZW50LCBzbyB0aGF0IHdoZW4gdGhlXG4gICAgICAvLyBoYW5kbGUgaXMgbGF0ZXIgcGFzc2VkIHRvIGEgc3RlcCB0aGUgd29ya2Zsb3cgcmVkdWNlciBjYW5cbiAgICAgIC8vIGZvcndhcmQgaXQgdGhyb3VnaCB0byB0aGUgc3RlcCByZXZpdmVyLlxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZS5ydW5JZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgZGVzY3JpcHRvcltTVFJFQU1fU0VSVkVSX1JVTl9JRF9TWU1CT0xdID0ge1xuICAgICAgICAgIHZhbHVlOiB2YWx1ZS5ydW5JZCxcbiAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gT2JqZWN0LmNyZWF0ZShnbG9iYWwuV3JpdGFibGVTdHJlYW0ucHJvdG90eXBlLCBkZXNjcmlwdG9yKTtcbiAgICB9LFxuXG4gICAgLy8gQWJvcnRDb250cm9sbGVyL0Fib3J0U2lnbmFsIHJldml2ZWQgaW5zaWRlIHRoZSB3b3JrZmxvdyBWTS4gVXNlIHRoZVxuICAgIC8vIHJlYWwgV29ya2Zsb3dBYm9ydFNpZ25hbCBjbGFzcyBzbyBhZGRFdmVudExpc3RlbmVyKCdhYm9ydCcsIGZuKSBhY3R1YWxseVxuICAgIC8vIGZpcmVzIHdoZW4gdGhlIHNpZ25hbCBhYm9ydHMgKHRoZSBwcmV2aW91cyBuby1vcCBzdHViIHNpbGVudGx5IGRyb3BwZWRcbiAgICAvLyBsaXN0ZW5lciByZWdpc3RyYXRpb25zIOKAlCBzaWxlbnQgY29ycmVjdG5lc3MgYnVnIGZvciBuYXR1cmFsIHBhdHRlcm5zXG4gICAgLy8gbGlrZSBgc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgZm4pYCBhZnRlciByZWNlaXZpbmcgYSBkZXNlcmlhbGl6ZWRcbiAgICAvLyBzaWduYWwpLiBUaGUgc2lnbmFsIGRvZXMgbm90IG93biBhIGhvb2sgc3Vic2NyaXB0aW9uIGhlcmUg4oCUIGFib3J0IHN0YXRlXG4gICAgLy8gaXMgZGVsaXZlcmVkIHZpYSB0aGUgZXhpc3RpbmcgcmVwbGF5IG1hY2hpbmVyeSBvbiB0aGUgc291cmNlIHNpZGUuXG4gICAgQWJvcnRDb250cm9sbGVyOiAodmFsdWUpID0+IHtcbiAgICAgIGNvbnN0IHNpZ25hbCA9IG5ldyBXb3JrZmxvd0Fib3J0U2lnbmFsKHZhbHVlLnN0cmVhbU5hbWUsIHZhbHVlLmhvb2tUb2tlbik7XG4gICAgICBpZiAodmFsdWUuYWJvcnRlZCkgc2lnbmFsLl9zZXRBYm9ydGVkKHZhbHVlLnJlYXNvbik7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBbQUJPUlRfU1RSRUFNX05BTUVdOiB2YWx1ZS5zdHJlYW1OYW1lLFxuICAgICAgICBbQUJPUlRfSE9PS19UT0tFTl06IHZhbHVlLmhvb2tUb2tlbixcbiAgICAgICAgc2lnbmFsLFxuICAgICAgICBhYm9ydDogKCkgPT4ge30sXG4gICAgICB9O1xuICAgIH0sXG4gICAgQWJvcnRTaWduYWw6ICh2YWx1ZSkgPT4ge1xuICAgICAgY29uc3Qgc2lnbmFsID0gbmV3IFdvcmtmbG93QWJvcnRTaWduYWwodmFsdWUuc3RyZWFtTmFtZSwgdmFsdWUuaG9va1Rva2VuKTtcbiAgICAgIGlmICh2YWx1ZS5hYm9ydGVkKSBzaWduYWwuX3NldEFib3J0ZWQodmFsdWUucmVhc29uKTtcbiAgICAgIHJldHVybiBzaWduYWw7XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXZpdmVycyBmb3IgZGVzZXJpYWxpemF0aW9uIGJvdW5kYXJ5IGZyb20gd2l0aGluIHRoZSBzdGVwIGV4ZWN1dGlvblxuICogZW52aXJvbm1lbnQsIHJlY2VpdmluZyBhcmd1bWVudHMgZnJvbSB0aGUgd29ya2Zsb3cgaGFuZGxlci5cbiAqXG4gKiBAcGFyYW0gZ2xvYmFsXG4gKiBAcGFyYW0gb3BzXG4gKiBAcGFyYW0gcnVuSWRcbiAqIEByZXR1cm5zXG4gKi9cbmZ1bmN0aW9uIGdldFN0ZXBSZXZpdmVycyhcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpcyxcbiAgb3BzOiBQcm9taXNlPHZvaWQ+W10sXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGNyeXB0b0tleTogRW5jcnlwdGlvbktleVBhcmFtXG4pOiBQYXJ0aWFsPFJldml2ZXJzPiB7XG4gIHJldHVybiB7XG4gICAgLi4uZ2V0Q29tbW9uUmV2aXZlcnMoZ2xvYmFsKSxcblxuICAgIC8vIFN0ZXBGdW5jdGlvbiByZXZpdmVyIGZvciBzdGVwIGNvbnRleHQgLSByZXR1cm5zIHJhdyBzdGVwIGZ1bmN0aW9uXG4gICAgLy8gd2l0aCBjbG9zdXJlIHZhcmlhYmxlIHN1cHBvcnQgdmlhIEFzeW5jTG9jYWxTdG9yYWdlLlxuICAgIC8vXG4gICAgLy8gSGFuZGxlcyBmb3VyIGluZGVwZW5kZW50IGZsYWdzIGZyb20gdGhlIHNlcmlhbGl6ZWQgcGF5bG9hZDpcbiAgICAvLyAgIC0gYGNsb3N1cmVWYXJzYDogaW52b2tlIHRoZSBib2R5IGluc2lkZSBhbiBBc3luY0xvY2FsU3RvcmFnZSBmcmFtZVxuICAgIC8vICAgICBzbyB0aGUgU1dDLWVtaXR0ZWQgYFdPUktGTE9XX1NURVBfQ09OVEVYVF9TVE9SQUdFYCBJSUZFIGluIHRoZVxuICAgIC8vICAgICBob2lzdGVkIGJvZHkgY2FuIHB1bGwgdGhlIGNsb3N1cmUgdmFyaWFibGVzIGJhY2sgb3V0LlxuICAgIC8vICAgLSBgYm91bmRUaGlzYDogICBhIGB0aGlzYCB2YWx1ZSBjYXB0dXJlZCBieVxuICAgIC8vICAgICBgdXNlU3RlcCguLi4pLmJpbmQodGhpcylgIGluIHRoZSB3b3JrZmxvdyBidW5kbGUgKGxleGljYWwtYHRoaXNgXG4gICAgLy8gICAgIGFycm93IHN0ZXBzKS4gVGhlIHdyYXBwZXIgaW52b2tlcyB0aGUgYm9keSB2aWFcbiAgICAvLyAgICAgYHN0ZXBGbi5hcHBseShib3VuZFRoaXMsIGFyZ3MpYCBzbyB0aGUgYm9keSBzZWVzIHRoZSBzYW1lXG4gICAgLy8gICAgIGB0aGlzYCBpdCB3b3VsZCBoYXZlIGhhZCBpbiB0aGUgd29ya2Zsb3cgYnVuZGxlLiBQcm9wZXJ0eVxuICAgIC8vICAgICBwcmVzZW5jZSDigJQgbm90IHRydXRoaW5lc3Mg4oCUIGlzIHNpZ25pZmljYW50IGJlY2F1c2VcbiAgICAvLyAgICAgYGJpbmQobnVsbClgIGFuZCBgYmluZCh1bmRlZmluZWQpYCBhcmUgYm90aCBsZWdhbCBhbmQgc2hvdWxkXG4gICAgLy8gICAgIHJvdW5kLXRyaXAgZmFpdGhmdWxseS5cbiAgICAvLyAgIC0gYGJvdW5kQXJnc2A6ICAgcHJlZmlsbGVkIGFyZ3MgZnJvbVxuICAgIC8vICAgICBgdXNlU3RlcCguLi4pLmJpbmQodGhpc0FyZywgeCwgeSlgLiBQcmVwZW5kZWQgdG8gdGhlIGNhbGwgYXJnc1xuICAgIC8vICAgICBzbyBwYXJ0aWFsIGFwcGxpY2F0aW9uIHN1cnZpdmVzIHNlcmlhbGl6YXRpb24uXG4gICAgU3RlcEZ1bmN0aW9uOiAodmFsdWUpID0+IHtcbiAgICAgIGNvbnN0IHN0ZXBJZCA9IHZhbHVlLnN0ZXBJZDtcbiAgICAgIGNvbnN0IGNsb3N1cmVWYXJzID0gdmFsdWUuY2xvc3VyZVZhcnM7XG4gICAgICBjb25zdCBoYXNCb3VuZFRoaXMgPSAnYm91bmRUaGlzJyBpbiB2YWx1ZTtcbiAgICAgIGNvbnN0IGJvdW5kVGhpcyA9IGhhc0JvdW5kVGhpcyA/IHZhbHVlLmJvdW5kVGhpcyA6IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IGJvdW5kQXJncyA9IEFycmF5LmlzQXJyYXkodmFsdWUuYm91bmRBcmdzKSA/IHZhbHVlLmJvdW5kQXJncyA6IFtdO1xuXG4gICAgICBjb25zdCBzdGVwRm4gPSBnZXRTdGVwRnVuY3Rpb24oc3RlcElkKTtcbiAgICAgIGlmICghc3RlcEZuKSB7XG4gICAgICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoXG4gICAgICAgICAgYFN0ZXAgZnVuY3Rpb24gXCIke3N0ZXBJZH1cIiBub3QgZm91bmQuIE1ha2Ugc3VyZSB0aGUgc3RlcCBmdW5jdGlvbiBpcyByZWdpc3RlcmVkLmAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgaGludDogJ01ha2Ugc3VyZSB0aGUgc3RlcCBmaWxlIGlzIGluY2x1ZGVkIGluIHlvdXIgYnVpbGQgKGkuZS4gaXQgaXMgbGlzdGVkIGluIHRoZSB3b3JrZmxvdyBtYW5pZmVzdCksIGFuZCB0aGF0IHRoZSBTV0MgcGx1Z2luIGlzIGNvbmZpZ3VyZWQgZm9yIHRoZSBmaWxlLicsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBGYXN0IHBhdGg6IG5vdGhpbmcgdG8gd3JhcC5cbiAgICAgIGlmICghY2xvc3VyZVZhcnMgJiYgIWhhc0JvdW5kVGhpcyAmJiBib3VuZEFyZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBzdGVwRm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHdyYXBwZWRTdGVwRm4gPSBmdW5jdGlvbiAodGhpczogdW5rbm93biwgLi4uYXJnczogYW55W10pIHtcbiAgICAgICAgY29uc3QgY2FsbFRoaXMgPSBoYXNCb3VuZFRoaXMgPyBib3VuZFRoaXMgOiB0aGlzO1xuICAgICAgICBjb25zdCBjYWxsQXJncyA9IGJvdW5kQXJncy5sZW5ndGggPiAwID8gWy4uLmJvdW5kQXJncywgLi4uYXJnc10gOiBhcmdzO1xuICAgICAgICBpZiAoY2xvc3VyZVZhcnMpIHtcbiAgICAgICAgICBjb25zdCBjdXJyZW50Q29udGV4dCA9IGNvbnRleHRTdG9yYWdlLmdldFN0b3JlKCk7XG4gICAgICAgICAgaWYgKCFjdXJyZW50Q29udGV4dCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKFxuICAgICAgICAgICAgICAnQ2Fubm90IGNhbGwgc3RlcCBmdW5jdGlvbiB3aXRoIGNsb3N1cmUgdmFyaWFibGVzIG91dHNpZGUgc3RlcCBjb250ZXh0J1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgbmV3Q29udGV4dCA9IHtcbiAgICAgICAgICAgIC4uLmN1cnJlbnRDb250ZXh0LFxuICAgICAgICAgICAgY2xvc3VyZVZhcnMsXG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXR1cm4gY29udGV4dFN0b3JhZ2UucnVuKG5ld0NvbnRleHQsICgpID0+XG4gICAgICAgICAgICBzdGVwRm4uYXBwbHkoY2FsbFRoaXMsIGNhbGxBcmdzKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN0ZXBGbi5hcHBseShjYWxsVGhpcywgY2FsbEFyZ3MpO1xuICAgICAgfSBhcyBhbnk7XG5cbiAgICAgIC8vIENvcHkgcHJvcGVydGllcyBmcm9tIG9yaWdpbmFsIHN0ZXAgZnVuY3Rpb25cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3cmFwcGVkU3RlcEZuLCAnbmFtZScsIHtcbiAgICAgICAgdmFsdWU6IHN0ZXBGbi5uYW1lLFxuICAgICAgfSk7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod3JhcHBlZFN0ZXBGbiwgJ3N0ZXBJZCcsIHtcbiAgICAgICAgdmFsdWU6IHN0ZXBJZCxcbiAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgIH0pO1xuICAgICAgaWYgKHN0ZXBGbi5tYXhSZXRyaWVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgd3JhcHBlZFN0ZXBGbi5tYXhSZXRyaWVzID0gc3RlcEZuLm1heFJldHJpZXM7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB3cmFwcGVkU3RlcEZuO1xuICAgIH0sXG5cbiAgICBXb3JrZmxvd0Z1bmN0aW9uOiAodmFsdWUpID0+XG4gICAgICBPYmplY3QuYXNzaWduKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihcbiAgICAgICAgICAgICdXb3JrZmxvdyBmdW5jdGlvbnMgY2Fubm90IGJlIGNhbGxlZCBkaXJlY3RseS4gVXNlIHN0YXJ0KCkgdG8gaW52b2tlIHRoZW0uJyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaGludDogJ1dyYXAgdGhlIHdvcmtmbG93IHdpdGggYHN0YXJ0KHdvcmtmbG93Rm4sIHsgLi4uIH0pYCBmcm9tIGB3b3JrZmxvd2AgdG8gYmVnaW4gYSBydW4gaW5zdGVhZCBvZiBpbnZva2luZyBpdCBsaWtlIGEgbm9ybWFsIGZ1bmN0aW9uLicsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSxcbiAgICAgICAgeyB3b3JrZmxvd0lkOiB2YWx1ZS53b3JrZmxvd0lkIH1cbiAgICAgICksXG5cbiAgICBSZXF1ZXN0OiAodmFsdWUpID0+IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlV3JpdGFibGUgPSB2YWx1ZS5yZXNwb25zZVdyaXRhYmxlO1xuICAgICAgY29uc3QgaW5pdDogUmVxdWVzdEluaXQgJiB7IGR1cGxleD86IHN0cmluZyB9ID0ge1xuICAgICAgICBtZXRob2Q6IHZhbHVlLm1ldGhvZCxcbiAgICAgICAgaGVhZGVyczogbmV3IGdsb2JhbC5IZWFkZXJzKHZhbHVlLmhlYWRlcnMpLFxuICAgICAgICBib2R5OiB2YWx1ZS5ib2R5LFxuICAgICAgICBkdXBsZXg6IHZhbHVlLmR1cGxleCxcbiAgICAgIH07XG4gICAgICBpZiAodmFsdWUuc2lnbmFsKSBpbml0LnNpZ25hbCA9IHZhbHVlLnNpZ25hbDtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ2xvYmFsLlJlcXVlc3QodmFsdWUudXJsLCBpbml0KTtcbiAgICAgIC8vIFRoZSBSZXF1ZXN0IGNvbnN0cnVjdG9yIGNyZWF0ZXMgYW4gaW50ZXJuYWwgc2lnbmFsIGNvcHksIHNvIHRoZVxuICAgICAgLy8gYWJvcnQtaW50ZXJuYWwgc3ltYm9scyBzZXQgYnkgcmV2aXZlQWJvcnRTaWduYWwgZG9uJ3QgcHJvcGFnYXRlLlxuICAgICAgLy8gUmUtdGFnIHRoZSByZXF1ZXN0J3Mgb3duIHNpZ25hbCBzbyBjYW5jZWxBYm9ydFJlYWRlcnMgY2FuIGZpbmQgaXQuXG4gICAgICBpZiAodmFsdWUuc2lnbmFsKSBjb3B5QWJvcnRJbnRlcm5hbHModmFsdWUuc2lnbmFsLCByZXF1ZXN0LnNpZ25hbCk7XG4gICAgICBpZiAocmVzcG9uc2VXcml0YWJsZSkge1xuICAgICAgICByZXF1ZXN0LnJlc3BvbmRXaXRoID0gYXN5bmMgKHJlc3BvbnNlOiBSZXNwb25zZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHdyaXRlciA9IHJlc3BvbnNlV3JpdGFibGUuZ2V0V3JpdGVyKCk7XG4gICAgICAgICAgYXdhaXQgd3JpdGVyLndyaXRlKHJlc3BvbnNlKTtcbiAgICAgICAgICBhd2FpdCB3cml0ZXIuY2xvc2UoKTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH0sXG4gICAgUmVzcG9uc2U6ICh2YWx1ZSkgPT4ge1xuICAgICAgLy8gTm90ZTogUmVzcG9uc2UgY29uc3RydWN0b3Igb25seSBhY2NlcHRzIHN0YXR1cywgc3RhdHVzVGV4dCwgYW5kIGhlYWRlcnNcbiAgICAgIC8vIFRoZSB0eXBlLCB1cmwsIGFuZCByZWRpcmVjdGVkIHByb3BlcnRpZXMgYXJlIHJlYWQtb25seSBhbmQgc2V0IGJ5IHRoZSBjb25zdHJ1Y3RvclxuICAgICAgcmV0dXJuIG5ldyBnbG9iYWwuUmVzcG9uc2UodmFsdWUuYm9keSwge1xuICAgICAgICBzdGF0dXM6IHZhbHVlLnN0YXR1cyxcbiAgICAgICAgc3RhdHVzVGV4dDogdmFsdWUuc3RhdHVzVGV4dCxcbiAgICAgICAgaGVhZGVyczogbmV3IGdsb2JhbC5IZWFkZXJzKHZhbHVlLmhlYWRlcnMpLFxuICAgICAgfSk7XG4gICAgfSxcbiAgICBSZWFkYWJsZVN0cmVhbTogKHZhbHVlKSA9PiB7XG4gICAgICAvLyBJZiB0aGlzIGhhcyBib2R5SW5pdCwgaXQgY2FtZSBmcm9tIGEgUmVzcG9uc2UgY29uc3RydWN0b3JcbiAgICAgIC8vIENvbnZlcnQgaXQgdG8gYSBSRUFMIHN0cmVhbSBub3cgdGhhdCB3ZSdyZSBpbiB0aGUgc3RlcCBlbnZpcm9ubWVudFxuICAgICAgaWYgKCdib2R5SW5pdCcgaW4gdmFsdWUpIHtcbiAgICAgICAgY29uc3QgYm9keUluaXQgPSB2YWx1ZS5ib2R5SW5pdDtcbiAgICAgICAgLy8gVXNlIHRoZSBuYXRpdmUgUmVzcG9uc2UgY29uc3RydWN0b3IgdG8gcHJvcGVybHkgY29udmVydCBCb2R5SW5pdCB0byBSZWFkYWJsZVN0cmVhbVxuICAgICAgICBjb25zdCByZXNwb25zZSA9IG5ldyBnbG9iYWwuUmVzcG9uc2UoYm9keUluaXQpO1xuICAgICAgICByZXR1cm4gcmVzcG9uc2UuYm9keTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVhZGFibGUgPSBuZXcgV29ya2Zsb3dTZXJ2ZXJSZWFkYWJsZVN0cmVhbShydW5JZCwgdmFsdWUubmFtZSk7XG4gICAgICBpZiAodmFsdWUudHlwZSA9PT0gJ2J5dGVzJykge1xuICAgICAgICAvLyBGb3IgYnl0ZSBzdHJlYW1zLCB1c2UgZmx1c2hhYmxlIHBpcGUgd2l0aCBsb2NrIHBvbGxpbmdcbiAgICAgICAgY29uc3Qgc3RhdGUgPSBjcmVhdGVGbHVzaGFibGVTdGF0ZSgpO1xuICAgICAgICBvcHMucHVzaChzdGF0ZS5wcm9taXNlKTtcblxuICAgICAgICAvLyBDcmVhdGUgYW4gaWRlbnRpdHkgdHJhbnNmb3JtIHRvIGdpdmUgdGhlIHVzZXIgYSByZWFkYWJsZVxuICAgICAgICBjb25zdCB7IHJlYWRhYmxlOiB1c2VyUmVhZGFibGUsIHdyaXRhYmxlIH0gPVxuICAgICAgICAgIG5ldyBnbG9iYWwuVHJhbnNmb3JtU3RyZWFtKCk7XG5cbiAgICAgICAgLy8gU3RhcnQgdGhlIGZsdXNoYWJsZSBwaXBlIGluIHRoZSBiYWNrZ3JvdW5kXG4gICAgICAgIGZsdXNoYWJsZVBpcGUocmVhZGFibGUsIHdyaXRhYmxlLCBzdGF0ZSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgIC8vIEVycm9ycyBhcmUgaGFuZGxlZCB2aWEgc3RhdGUucmVqZWN0XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFN0YXJ0IHBvbGxpbmcgdG8gZGV0ZWN0IHdoZW4gdXNlciByZWxlYXNlcyBsb2NrXG4gICAgICAgIHBvbGxSZWFkYWJsZUxvY2sodXNlclJlYWRhYmxlLCBzdGF0ZSk7XG5cbiAgICAgICAgcmV0dXJuIHVzZXJSZWFkYWJsZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IGdldERlc2VyaWFsaXplU3RyZWFtKFxuICAgICAgICAgIGdldFN0ZXBSZXZpdmVycyhnbG9iYWwsIG9wcywgcnVuSWQsIGNyeXB0b0tleSksXG4gICAgICAgICAgY3J5cHRvS2V5XG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHN0YXRlID0gY3JlYXRlRmx1c2hhYmxlU3RhdGUoKTtcbiAgICAgICAgb3BzLnB1c2goc3RhdGUucHJvbWlzZSk7XG5cbiAgICAgICAgLy8gU3RhcnQgdGhlIGZsdXNoYWJsZSBwaXBlIGluIHRoZSBiYWNrZ3JvdW5kXG4gICAgICAgIGZsdXNoYWJsZVBpcGUocmVhZGFibGUsIHRyYW5zZm9ybS53cml0YWJsZSwgc3RhdGUpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAvLyBFcnJvcnMgYXJlIGhhbmRsZWQgdmlhIHN0YXRlLnJlamVjdFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTdGFydCBwb2xsaW5nIHRvIGRldGVjdCB3aGVuIHVzZXIgcmVsZWFzZXMgbG9ja1xuICAgICAgICBwb2xsUmVhZGFibGVMb2NrKHRyYW5zZm9ybS5yZWFkYWJsZSwgc3RhdGUpO1xuXG4gICAgICAgIHJldHVybiB0cmFuc2Zvcm0ucmVhZGFibGU7XG4gICAgICB9XG4gICAgfSxcbiAgICBXcml0YWJsZVN0cmVhbTogKHZhbHVlKSA9PiB7XG4gICAgICAvLyBTYW1lLXJ1biBjYXNlOiB0aGUgd3JpdGFibGUgYmVsb25ncyB0byB0aGUgY3VycmVudCBydW4uIFVzZSB0aGVcbiAgICAgIC8vIGxvY2FsIGNyeXB0b0tleSBhbmQgd3JpdGUgdG8gdGhlIGxvY2FsIHJ1bklkJ3Mgc2VydmVyIHN0cmVhbS5cbiAgICAgIC8vXG4gICAgICAvLyBDcm9zcy1ydW4gY2FzZSAocGFyZW50IOKGkiBjaGlsZCB2aWEgYHN0YXJ0KClgKTogdGhlIGRlc2NyaXB0b3JcbiAgICAgIC8vIGNhcnJpZXMgdGhlIG9yaWdpbmFsIGBydW5JZGAgYW5kIGBuYW1lYC4gT3BlbiBhIHNlcnZlciB3cml0YWJsZVxuICAgICAgLy8gYWdhaW5zdCB0aGUgb3JpZ2luYWwgYChydW5JZCwgbmFtZSlgIGFuZCByZXNvbHZlIFRIQVQgcnVuJ3Mga2V5XG4gICAgICAvLyBmb3IgZW5jcnlwdGlvbi4gVGhlIHJlc29sdXRpb24gaXMgYXN5bmMgYnV0IGRvZXNuJ3QgbmVlZCB0b1xuICAgICAgLy8gYmxvY2sgcmV2aXZlciByZXR1cm4g4oCUIGBnZXRTZXJpYWxpemVTdHJlYW1gIGFjY2VwdHMgdGhlXG4gICAgICAvLyBgUHJvbWlzZTxDcnlwdG9LZXkgfCB1bmRlZmluZWQ+YCBkaXJlY3RseSBhbmQgYXdhaXRzIGl0IGxhemlseVxuICAgICAgLy8gb24gdGhlIGZpcnN0IGNodW5rIHdyaXR0ZW4uIFRoZSBrZXkgaXMgaW1wb3J0ZWQgZW5jcnlwdC1vbmx5XG4gICAgICAvLyBzbyB0aGUgcmVjZWl2aW5nIHJ1biBjYW4gbmV2ZXIgZGVjcnlwdCBhbnl0aGluZyBlbHNlIG9uIHRoZVxuICAgICAgLy8gb3duaW5nIHJ1bidzIHN0cmVhbSDigJQgaXQgY2FuIG9ubHkgY29udHJpYnV0ZSBuZXcgd3JpdGVzLlxuICAgICAgY29uc3QgdGFyZ2V0UnVuSWQgPSB0eXBlb2YgdmFsdWUucnVuSWQgPT09ICdzdHJpbmcnID8gdmFsdWUucnVuSWQgOiBydW5JZDtcbiAgICAgIGNvbnN0IHRhcmdldEtleTogRW5jcnlwdGlvbktleVBhcmFtID1cbiAgICAgICAgdGFyZ2V0UnVuSWQgPT09IHJ1bklkXG4gICAgICAgICAgPyBjcnlwdG9LZXlcbiAgICAgICAgICA6IChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHdvcmxkID0gYXdhaXQgZ2V0V29ybGRMYXp5KCk7XG4gICAgICAgICAgICAgIGNvbnN0IHJhd0tleSA9IGF3YWl0IHdvcmxkLmdldEVuY3J5cHRpb25LZXlGb3JSdW4/Lih0YXJnZXRSdW5JZCk7XG4gICAgICAgICAgICAgIHJldHVybiByYXdLZXkgPyBhd2FpdCBpbXBvcnRLZXkocmF3S2V5LCBbJ2VuY3J5cHQnXSkgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9KSgpO1xuXG4gICAgICBjb25zdCBzZXJpYWxpemUgPSBnZXRTZXJpYWxpemVTdHJlYW0oXG4gICAgICAgIGdldFN0ZXBSZWR1Y2VycyhnbG9iYWwsIG9wcywgdGFyZ2V0UnVuSWQsIHRhcmdldEtleSksXG4gICAgICAgIHRhcmdldEtleVxuICAgICAgKTtcbiAgICAgIGNvbnN0IHNlcnZlcldyaXRhYmxlID0gbmV3IFdvcmtmbG93U2VydmVyV3JpdGFibGVTdHJlYW0oXG4gICAgICAgIHRhcmdldFJ1bklkLFxuICAgICAgICB2YWx1ZS5uYW1lXG4gICAgICApO1xuXG4gICAgICAvLyBDcmVhdGUgZmx1c2hhYmxlIHN0YXRlIGZvciB0aGlzIHN0cmVhbVxuICAgICAgY29uc3Qgc3RhdGUgPSBjcmVhdGVGbHVzaGFibGVTdGF0ZSgpO1xuICAgICAgb3BzLnB1c2goc3RhdGUucHJvbWlzZSk7XG5cbiAgICAgIC8vIFN0YXJ0IHRoZSBmbHVzaGFibGUgcGlwZSBpbiB0aGUgYmFja2dyb3VuZFxuICAgICAgZmx1c2hhYmxlUGlwZShzZXJpYWxpemUucmVhZGFibGUsIHNlcnZlcldyaXRhYmxlLCBzdGF0ZSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAvLyBFcnJvcnMgYXJlIGhhbmRsZWQgdmlhIHN0YXRlLnJlamVjdFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFN0YXJ0IHBvbGxpbmcgdG8gZGV0ZWN0IHdoZW4gdXNlciByZWxlYXNlcyBsb2NrXG4gICAgICBwb2xsV3JpdGFibGVMb2NrKHNlcmlhbGl6ZS53cml0YWJsZSwgc3RhdGUpO1xuXG4gICAgICAvLyBSZWNvcmQgdGhlIHVuZGVybHlpbmcgYChydW5JZCwgbmFtZSlgIHNvIGRvd25zdHJlYW0gcmVkdWNlcnMgY2FuXG4gICAgICAvLyByZWNvZ25pemUgdGhhdCB0aGlzIHdyaXRhYmxlIGlzIGFscmVhZHkgYmFja2VkIGJ5IGEgd29ya2Zsb3dcbiAgICAgIC8vIHNlcnZlciBzdHJlYW0uIFdoZW4gZm9yd2FyZGVkIGFjcm9zcyBgc3RhcnQoKWAgYWdhaW4g4oCUIGUuZy5cbiAgICAgIC8vIHRoZSBjaGlsZCBwYXNzZXMgdGhpcyB3cml0YWJsZSBvbiB0byBhIGdyYW5kY2hpbGQg4oCUIHRoZVxuICAgICAgLy8gZXh0ZXJuYWwgcmVkdWNlciBuZWVkcyBib3RoIHRvIGVtaXQgdGhlIG9yaWdpbmFsIGBydW5JZGAgaW5cbiAgICAgIC8vIHRoZSBkZXNjcmlwdG9yLlxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHNlcmlhbGl6ZS53cml0YWJsZSwgU1RSRUFNX05BTUVfU1lNQk9MLCB7XG4gICAgICAgIHZhbHVlOiB2YWx1ZS5uYW1lLFxuICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICB9KTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzZXJpYWxpemUud3JpdGFibGUsIFNUUkVBTV9TRVJWRVJfUlVOX0lEX1NZTUJPTCwge1xuICAgICAgICB2YWx1ZTogdGFyZ2V0UnVuSWQsXG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gc2VyaWFsaXplLndyaXRhYmxlO1xuICAgIH0sXG5cbiAgICBBYm9ydENvbnRyb2xsZXI6ICh2YWx1ZSkgPT4gcmV2aXZlQWJvcnRDb250cm9sbGVyKHZhbHVlLCBvcHMsIHJ1bklkKSxcbiAgICBBYm9ydFNpZ25hbDogKHZhbHVlKSA9PiByZXZpdmVBYm9ydFNpZ25hbCh2YWx1ZSwgb3BzLCBydW5JZCksXG4gIH07XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEVuY3J5cHRpb24gSGVscGVyc1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gVGhlc2UgZGVsZWdhdGUgdG8gdGhlIG1vZHVsYXIgYGVuY3J5cHRgL2BkZWNyeXB0YCBmcm9tIGAuL3NlcmlhbGl6YXRpb24vZW5jcnlwdGlvbi5qc2Bcbi8vIGJ1dCBhcmUga2VwdCBhcyBuYW1lZCBleHBvcnRzIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSB3aXRoIGV4aXN0aW5nIGNvbnN1bWVycy5cblxuLyoqXG4gKiBFbmNyeXB0IGRhdGEgaWYgdGhlIHdvcmxkIHN1cHBvcnRzIGVuY3J5cHRpb24uXG4gKiBSZXR1cm5zIG9yaWdpbmFsIGRhdGEgaWYgZW5jcnlwdGlvbiBpcyBub3QgYXZhaWxhYmxlLlxuICpcbiAqIEBkZXByZWNhdGVkIFVzZSBgZW5jcnlwdGAgZnJvbSBgLi9zZXJpYWxpemF0aW9uL2VuY3J5cHRpb24uanNgIGluc3RlYWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBtYXliZUVuY3J5cHQoXG4gIGRhdGE6IFVpbnQ4QXJyYXksXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgcmV0dXJuIChhd2FpdCBlbmNyeXB0KGRhdGEsIGtleSkpIGFzIFVpbnQ4QXJyYXk7XG59XG5cbi8qKlxuICogRGVjcnlwdCBkYXRhIGlmIGl0IGhhcyB0aGUgJ2VuY3InIHByZWZpeC5cbiAqXG4gKiBAZGVwcmVjYXRlZCBVc2UgYGRlY3J5cHRgIGZyb20gYC4vc2VyaWFsaXphdGlvbi9lbmNyeXB0aW9uLmpzYCBpbnN0ZWFkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWF5YmVEZWNyeXB0KFxuICBkYXRhOiBVaW50OEFycmF5IHwgdW5rbm93bixcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWRcbik6IFByb21pc2U8VWludDhBcnJheSB8IHVua25vd24+IHtcbiAgcmV0dXJuIGRlY3J5cHQoZGF0YSwga2V5KTtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gRGVoeWRyYXRlIC8gSHlkcmF0ZSBGdW5jdGlvbnNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFRoZXNlIGRlbGVnYXRlIHRvIHRoZSBtb2R1bGFyIG1vZGUgbW9kdWxlcyAod29ya2Zsb3csIHN0ZXAsIGNsaWVudCkgcGFzc2luZ1xuLy8gbW9kZS1zcGVjaWZpYyBzdHJlYW0gYW5kIFJlcXVlc3QvUmVzcG9uc2UgcmVkdWNlcnMvcmV2aXZlcnMgYXMgZXh0cmEgb3B0aW9ucy5cbi8vIFRoZSB2MUNvbXBhdCBwYXRoIGlzIGhhbmRsZWQgaW5saW5lIGJlZm9yZSBkZWxlZ2F0aW5nIHRvIHRoZSBtb2R1bGVzLlxuXG4vKipcbiAqIENhbGxlZCBmcm9tIHRoZSBgc3RhcnQoKWAgZnVuY3Rpb24gdG8gc2VyaWFsaXplIHRoZSB3b3JrZmxvdyBhcmd1bWVudHNcbiAqIGludG8gYSBmb3JtYXQgdGhhdCBjYW4gYmUgc2F2ZWQgdG8gdGhlIGRhdGFiYXNlIGFuZCB0aGVuIGh5ZHJhdGVkIGZyb21cbiAqIHdpdGhpbiB0aGUgd29ya2Zsb3cgZXhlY3V0aW9uIGVudmlyb25tZW50LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVoeWRyYXRlV29ya2Zsb3dBcmd1bWVudHMoXG4gIHZhbHVlOiB1bmtub3duLFxuICBydW5JZDogc3RyaW5nLFxuICBrZXk6IENyeXB0b0tleSB8IHVuZGVmaW5lZCxcbiAgb3BzOiBQcm9taXNlPHZvaWQ+W10gPSBbXSxcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpcyxcbiAgdjFDb21wYXQgPSBmYWxzZVxuKTogUHJvbWlzZTxVaW50OEFycmF5IHwgdW5rbm93bj4ge1xuICBpZiAodjFDb21wYXQpIHtcbiAgICBjb25zdCBzdHIgPSBzdHJpbmdpZnkodmFsdWUsIGdldEV4dGVybmFsUmVkdWNlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBrZXkpKTtcbiAgICByZXR1cm4gcmV2aXZlKHN0cik7XG4gIH1cbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgY2xpZW50TW9kdWxlLnNlcmlhbGl6ZSh2YWx1ZSwga2V5LCB7XG4gICAgICBnbG9iYWwsXG4gICAgICBleHRyYVJlZHVjZXJzOiBnZXRTdHJlYW1BbmRSZXF1ZXN0UmVkdWNlcnMoXG4gICAgICAgIGdldEV4dGVybmFsUmVkdWNlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBrZXkpXG4gICAgICApLFxuICAgIH0pO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnN0IGNhdXNlID0gdW53cmFwU2VyaWFsaXphdGlvbkNhdXNlKGVycm9yKTtcbiAgICBjb25zdCB7IG1lc3NhZ2UsIGhpbnQgfSA9IGZvcm1hdFNlcmlhbGl6YXRpb25FcnJvcihcbiAgICAgICd3b3JrZmxvdyBhcmd1bWVudHMnLFxuICAgICAgY2F1c2VcbiAgICApO1xuICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IobWVzc2FnZSwgeyBoaW50LCBjYXVzZSB9KTtcbiAgfVxufVxuXG4vKipcbiAqIENhbGxlZCBmcm9tIHdvcmtmbG93IGV4ZWN1dGlvbiBlbnZpcm9ubWVudCB0byBoeWRyYXRlIHRoZSB3b3JrZmxvd1xuICogYXJndW1lbnRzIGZyb20gdGhlIGRhdGFiYXNlIGF0IHRoZSBzdGFydCBvZiB3b3JrZmxvdyBleGVjdXRpb24uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoeWRyYXRlV29ya2Zsb3dBcmd1bWVudHMoXG4gIHZhbHVlOiBVaW50OEFycmF5IHwgdW5rbm93bixcbiAgX3J1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBleHRyYVJldml2ZXJzOiBSZWNvcmQ8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gYW55PiA9IHt9XG4pOiBQcm9taXNlPGFueT4ge1xuICByZXR1cm4gd29ya2Zsb3dNb2R1bGUuZGVzZXJpYWxpemUoYXdhaXQgbWF5YmVEZWNyeXB0KHZhbHVlLCBrZXkpLCB7XG4gICAgZ2xvYmFsLFxuICAgIGV4dHJhUmV2aXZlcnM6IHtcbiAgICAgIC4uLmdldFN0cmVhbUFuZFJlcXVlc3RSZXZpdmVycyhnZXRXb3JrZmxvd1Jldml2ZXJzKGdsb2JhbCkpLFxuICAgICAgLi4uZXh0cmFSZXZpdmVycyxcbiAgICB9LFxuICB9KTtcbn1cblxuLyoqXG4gKiBEZWh5ZHJhdGUgd29ya2Zsb3cgcmV0dXJuIHZhbHVlIGZvciBzdG9yYWdlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVoeWRyYXRlV29ya2Zsb3dSZXR1cm5WYWx1ZShcbiAgdmFsdWU6IHVua25vd24sXG4gIF9ydW5JZDogc3RyaW5nLFxuICBrZXk6IENyeXB0b0tleSB8IHVuZGVmaW5lZCxcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpcyxcbiAgdjFDb21wYXQgPSBmYWxzZVxuKTogUHJvbWlzZTxVaW50OEFycmF5IHwgdW5rbm93bj4ge1xuICBpZiAodjFDb21wYXQpIHtcbiAgICBjb25zdCBzdHIgPSBzdHJpbmdpZnkodmFsdWUsIGdldFdvcmtmbG93UmVkdWNlcnMoZ2xvYmFsKSk7XG4gICAgcmV0dXJuIHJldml2ZShzdHIpO1xuICB9XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IHN0ZXBNb2R1bGUuc2VyaWFsaXplKHZhbHVlLCBrZXksIHtcbiAgICAgIGdsb2JhbCxcbiAgICAgIGV4dHJhUmVkdWNlcnM6IGdldFN0cmVhbUFuZFJlcXVlc3RSZWR1Y2VycyhnZXRXb3JrZmxvd1JlZHVjZXJzKGdsb2JhbCkpLFxuICAgIH0pO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnN0IGNhdXNlID0gdW53cmFwU2VyaWFsaXphdGlvbkNhdXNlKGVycm9yKTtcbiAgICBjb25zdCB7IG1lc3NhZ2UsIGhpbnQgfSA9IGZvcm1hdFNlcmlhbGl6YXRpb25FcnJvcihcbiAgICAgICd3b3JrZmxvdyByZXR1cm4gdmFsdWUnLFxuICAgICAgY2F1c2VcbiAgICApO1xuICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IobWVzc2FnZSwgeyBoaW50LCBjYXVzZSB9KTtcbiAgfVxufVxuXG4vKipcbiAqIENhbGxlZCBmcm9tIHRoZSBjbGllbnQgc2lkZSB0byBoeWRyYXRlIHRoZSB3b3JrZmxvdyByZXR1cm4gdmFsdWVcbiAqIG9mIGEgY29tcGxldGVkIHdvcmtmbG93IHJ1bi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGh5ZHJhdGVXb3JrZmxvd1JldHVyblZhbHVlKFxuICB2YWx1ZTogVWludDhBcnJheSB8IHVua25vd24sXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXSA9IFtdLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBleHRyYVJldml2ZXJzOiBSZWNvcmQ8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gYW55PiA9IHt9XG4pOiBQcm9taXNlPGFueT4ge1xuICByZXR1cm4gY2xpZW50TW9kdWxlLmRlc2VyaWFsaXplKHZhbHVlLCBrZXksIHtcbiAgICBnbG9iYWwsXG4gICAgZXh0cmFSZXZpdmVyczoge1xuICAgICAgLi4uZ2V0U3RyZWFtQW5kUmVxdWVzdFJldml2ZXJzKFxuICAgICAgICBnZXRFeHRlcm5hbFJldml2ZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwga2V5KVxuICAgICAgKSxcbiAgICAgIC4uLmV4dHJhUmV2aXZlcnMsXG4gICAgfSxcbiAgfSk7XG59XG5cbi8qKlxuICogQ2FsbGVkIGZyb20gdGhlIHdvcmtmbG93IGhhbmRsZXIgd2hlbiBhIHN0ZXAgaXMgYmVpbmcgY3JlYXRlZC5cbiAqIERlaHlkcmF0ZXMgdmFsdWVzIGZyb20gd2l0aGluIHRoZSB3b3JrZmxvdyBleGVjdXRpb24gZW52aXJvbm1lbnQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWh5ZHJhdGVTdGVwQXJndW1lbnRzKFxuICB2YWx1ZTogdW5rbm93bixcbiAgX3J1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICB2MUNvbXBhdCA9IGZhbHNlXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXkgfCB1bmtub3duPiB7XG4gIGlmICh2MUNvbXBhdCkge1xuICAgIGNvbnN0IHN0ciA9IHN0cmluZ2lmeSh2YWx1ZSwgZ2V0V29ya2Zsb3dSZWR1Y2VycyhnbG9iYWwpKTtcbiAgICByZXR1cm4gcmV2aXZlKHN0cik7XG4gIH1cbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgc3RlcE1vZHVsZS5zZXJpYWxpemUodmFsdWUsIGtleSwge1xuICAgICAgZ2xvYmFsLFxuICAgICAgZXh0cmFSZWR1Y2VyczogZ2V0U3RyZWFtQW5kUmVxdWVzdFJlZHVjZXJzKGdldFdvcmtmbG93UmVkdWNlcnMoZ2xvYmFsKSksXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc3QgY2F1c2UgPSB1bndyYXBTZXJpYWxpemF0aW9uQ2F1c2UoZXJyb3IpO1xuICAgIGNvbnN0IHsgbWVzc2FnZSwgaGludCB9ID0gZm9ybWF0U2VyaWFsaXphdGlvbkVycm9yKCdzdGVwIGFyZ3VtZW50cycsIGNhdXNlKTtcbiAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKG1lc3NhZ2UsIHsgaGludCwgY2F1c2UgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBDYWxsZWQgZnJvbSB0aGUgc3RlcCBoYW5kbGVyIHRvIGh5ZHJhdGUgdGhlIGFyZ3VtZW50cyBvZiBhIHN0ZXBcbiAqIGZyb20gdGhlIGRhdGFiYXNlIGF0IHRoZSBzdGFydCBvZiB0aGUgc3RlcCBleGVjdXRpb24uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoeWRyYXRlU3RlcEFyZ3VtZW50cyhcbiAgdmFsdWU6IFVpbnQ4QXJyYXkgfCB1bmtub3duLFxuICBydW5JZDogc3RyaW5nLFxuICBrZXk6IENyeXB0b0tleSB8IHVuZGVmaW5lZCxcbiAgb3BzOiBQcm9taXNlPGFueT5bXSA9IFtdLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBleHRyYVJldml2ZXJzOiBSZWNvcmQ8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gYW55PiA9IHt9XG4pOiBQcm9taXNlPGFueT4ge1xuICByZXR1cm4gc3RlcE1vZHVsZS5kZXNlcmlhbGl6ZSh2YWx1ZSwga2V5LCB7XG4gICAgZ2xvYmFsLFxuICAgIGV4dHJhUmV2aXZlcnM6IHtcbiAgICAgIC4uLmdldFN0cmVhbUFuZFJlcXVlc3RSZXZpdmVycyhnZXRTdGVwUmV2aXZlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBrZXkpKSxcbiAgICAgIC4uLmV4dHJhUmV2aXZlcnMsXG4gICAgfSxcbiAgfSk7XG59XG5cbi8qKlxuICogQ2FsbGVkIGZyb20gdGhlIHN0ZXAgaGFuZGxlciB3aGVuIGEgc3RlcCBoYXMgY29tcGxldGVkLlxuICogRGVoeWRyYXRlcyB2YWx1ZXMgZnJvbSB3aXRoaW4gdGhlIHN0ZXAgZXhlY3V0aW9uIGVudmlyb25tZW50LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVoeWRyYXRlU3RlcFJldHVyblZhbHVlKFxuICB2YWx1ZTogdW5rbm93bixcbiAgcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIG9wczogUHJvbWlzZTxhbnk+W10gPSBbXSxcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpcyxcbiAgdjFDb21wYXQgPSBmYWxzZVxuKTogUHJvbWlzZTxVaW50OEFycmF5IHwgdW5rbm93bj4ge1xuICBpZiAodjFDb21wYXQpIHtcbiAgICBjb25zdCBzdHIgPSBzdHJpbmdpZnkodmFsdWUsIGdldFN0ZXBSZWR1Y2VycyhnbG9iYWwsIG9wcywgcnVuSWQsIGtleSkpO1xuICAgIHJldHVybiByZXZpdmUoc3RyKTtcbiAgfVxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBzdGVwTW9kdWxlLnNlcmlhbGl6ZSh2YWx1ZSwga2V5LCB7XG4gICAgICBnbG9iYWwsXG4gICAgICBleHRyYVJlZHVjZXJzOiBnZXRTdHJlYW1BbmRSZXF1ZXN0UmVkdWNlcnMoXG4gICAgICAgIGdldFN0ZXBSZWR1Y2VycyhnbG9iYWwsIG9wcywgcnVuSWQsIGtleSlcbiAgICAgICksXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc3QgY2F1c2UgPSB1bndyYXBTZXJpYWxpemF0aW9uQ2F1c2UoZXJyb3IpO1xuICAgIGNvbnN0IHsgbWVzc2FnZSwgaGludCB9ID0gZm9ybWF0U2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgJ3N0ZXAgcmV0dXJuIHZhbHVlJyxcbiAgICAgIGNhdXNlXG4gICAgKTtcbiAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKG1lc3NhZ2UsIHsgaGludCwgY2F1c2UgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBDYWxsZWQgZnJvbSB0aGUgc3RlcCBoYW5kbGVyIHdoZW4gYSBzdGVwIHRocm93cy4gRGVoeWRyYXRlcyB0aGUgdGhyb3duXG4gKiB2YWx1ZSBmcm9tIHdpdGhpbiB0aGUgc3RlcCBleGVjdXRpb24gZW52aXJvbm1lbnQgaW50byBhIGZvcm1hdCB0aGF0IGNhblxuICogYmUgc2F2ZWQgdG8gdGhlIGRhdGFiYXNlIGluIGEgYHN0ZXBfZmFpbGVkYCBvciBgc3RlcF9yZXRyeWluZ2AgZXZlbnQuXG4gKlxuICogQW55IEphdmFTY3JpcHQgdmFsdWUgY2FuIGJlIHRocm93biAoc3RyaW5ncywgbnVtYmVycywgb2JqZWN0cywgRXJyb3JzLFxuICogRXJyb3Igc3ViY2xhc3NlcyksIHNvIHRoZSBzYW1lIHNlcmlhbGl6YXRpb24gcGlwZWxpbmUgdXNlZCBmb3Igc3RlcFxuICogYXJndW1lbnRzIGFuZCByZXR1cm4gdmFsdWVzIGlzIGFwcGxpZWQgaGVyZS5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdGhyb3duIHZhbHVlIHRvIHNlcmlhbGl6ZSAoY2FuIGJlIGFueSB0eXBlKVxuICogQHBhcmFtIHJ1bklkIC0gUnVuIElEIGZvciBlbmNyeXB0aW9uIGNvbnRleHRcbiAqIEBwYXJhbSBrZXkgLSBFbmNyeXB0aW9uIGtleSAodW5kZWZpbmVkIHRvIHNraXAgZW5jcnlwdGlvbilcbiAqIEBwYXJhbSBvcHMgLSBQcm9taXNlIGFycmF5IGZvciBzdHJlYW0gb3BlcmF0aW9uc1xuICogQHBhcmFtIGdsb2JhbCAtIEdsb2JhbCBvYmplY3QgZm9yIHNlcmlhbGl6YXRpb24gY29udGV4dFxuICogQHJldHVybnMgVGhlIGRlaHlkcmF0ZWQgdmFsdWUgYXMgYmluYXJ5IGRhdGEgKFVpbnQ4QXJyYXkpIHdpdGggZm9ybWF0IHByZWZpeFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVoeWRyYXRlU3RlcEVycm9yKFxuICB2YWx1ZTogdW5rbm93bixcbiAgcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIG9wczogUHJvbWlzZTxhbnk+W10gPSBbXSxcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpc1xuKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIHRyeSB7XG4gICAgY29uc3Qgc3RyID0gc3RyaW5naWZ5KHZhbHVlLCBnZXRTdGVwUmVkdWNlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBrZXkpKTtcbiAgICBjb25zdCBwYXlsb2FkID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHN0cik7XG4gICAgY29uc3Qgc2VyaWFsaXplZCA9IGVuY29kZVdpdGhGb3JtYXRQcmVmaXgoXG4gICAgICBTZXJpYWxpemF0aW9uRm9ybWF0LkRFVkFMVUVfVjEsXG4gICAgICBwYXlsb2FkXG4gICAgKSBhcyBVaW50OEFycmF5O1xuICAgIHJldHVybiAoYXdhaXQgbWF5YmVFbmNyeXB0KHNlcmlhbGl6ZWQsIGtleSkpIGFzIFVpbnQ4QXJyYXk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc3QgY2F1c2UgPSB1bndyYXBTZXJpYWxpemF0aW9uQ2F1c2UoZXJyb3IpO1xuICAgIGNvbnN0IHsgbWVzc2FnZSwgaGludCB9ID0gZm9ybWF0U2VyaWFsaXphdGlvbkVycm9yKCdzdGVwIGVycm9yJywgY2F1c2UpO1xuICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IobWVzc2FnZSwgeyBoaW50LCBjYXVzZSB9KTtcbiAgfVxufVxuXG4vKipcbiAqIENhbGxlZCBmcm9tIHRoZSB3b3JrZmxvdyBoYW5kbGVyIHdoZW4gcmVwbGF5aW5nIHRoZSBldmVudCBsb2cgb2YgYVxuICogYHN0ZXBfZmFpbGVkYCBvciBgc3RlcF9yZXRyeWluZ2AgZXZlbnQuIEh5ZHJhdGVzIHRoZSB0aHJvd24gdmFsdWUgZnJvbVxuICogdGhlIGRhdGFiYXNlIHNvIHRoZSB3b3JrZmxvdyBjYW4gc2VlIHRoZSBvcmlnaW5hbCB0aHJvd24gdmFsdWUuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gQmluYXJ5IHNlcmlhbGl6ZWQgZGF0YSAoVWludDhBcnJheSkgd2l0aCBmb3JtYXQgcHJlZml4XG4gKiBAcGFyYW0gcnVuSWQgLSBSdW4gSUQgZm9yIGRlY3J5cHRpb24gY29udGV4dFxuICogQHBhcmFtIGtleSAtIEVuY3J5cHRpb24ga2V5ICh1bmRlZmluZWQgdG8gc2tpcCBkZWNyeXB0aW9uKVxuICogQHBhcmFtIGdsb2JhbCAtIEdsb2JhbCBvYmplY3QgZm9yIGRlc2VyaWFsaXphdGlvbiBjb250ZXh0XG4gKiBAcGFyYW0gZXh0cmFSZXZpdmVycyAtIEFkZGl0aW9uYWwgcmV2aXZlcnMgZm9yIGN1c3RvbSB0eXBlc1xuICogQHJldHVybnMgVGhlIGh5ZHJhdGVkIHRocm93biB2YWx1ZSwgcmVhZHkgdG8gcmVqZWN0IHRoZSBzdGVwIHByb21pc2VcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGh5ZHJhdGVTdGVwRXJyb3IoXG4gIHZhbHVlOiBVaW50OEFycmF5IHwgdW5rbm93bixcbiAgX3J1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBleHRyYVJldml2ZXJzOiBSZWNvcmQ8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gYW55PiA9IHt9XG4pOiBQcm9taXNlPHVua25vd24+IHtcbiAgY29uc3QgZGVjcnlwdGVkID0gYXdhaXQgbWF5YmVEZWNyeXB0KHZhbHVlLCBrZXkpO1xuXG4gIGlmICghKGRlY3J5cHRlZCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKSB7XG4gICAgLy8gVHJlYXRlZCBhcyBhIGRldmFsdWUgXCJmbGF0dGVuZWRcIiBhcnJheS4gSW4gcHJvZHVjdGlvbiB0aGlzIGJyYW5jaCBpc1xuICAgIC8vIGV4ZXJjaXNlZCBieSBsZWdhY3kgY29kZSBwYXRocyB0aGF0IGJ5cGFzc2VkIGBkZWh5ZHJhdGVTdGVwRXJyb3JgOyB0aGVcbiAgICAvLyBTREsgdmVyc2lvbiBpcyBwaW5uZWQgcGVyIHdvcmtmbG93IHJ1biB2aWEgc2tldyBwcm90ZWN0aW9uLCBzbyBhXG4gICAgLy8gY3VycmVudC12ZXJzaW9uIHByb2R1Y2VyIGFsd2F5cyBlbWl0cyBhIFVpbnQ4QXJyYXkgaGVyZS4gSWYgYVxuICAgIC8vIG1pc3NoYXBlbiB2YWx1ZSByZWFjaGVzIHVzLCBgdW5mbGF0dGVuYCB0aHJvd3Mg4oCUIHRoYXQncyBpbnRlbnRpb25hbDpcbiAgICAvLyB0aGUgaGlnaGVyLWxldmVsIGh5ZHJhdGlvbiBoZWxwZXJzIChgaHlkcmF0ZVN0ZXBJT2AsXG4gICAgLy8gYGh5ZHJhdGVSZXNvdXJjZUlPYCkgYWxyZWFkeSB3cmFwIHVzIGluIGEgdHJ5L2NhdGNoIHRoYXQgbGVhdmVzIHRoZVxuICAgIC8vIGZpZWxkIHVuLWh5ZHJhdGVkIGZvciBvMTF5IGRpc3BsYXksIGFuZCBzdXJmYWNpbmcgdGhlIHRocm93IHRvIGxvZ3NcbiAgICAvLyBpcyBtb3JlIGRlYnVnZ2FibGUgdGhhbiBzaWxlbnRseSBtYXNraW5nIHRoZSB1bnN1cHBvcnRlZCBzaGFwZS5cbiAgICByZXR1cm4gdW5mbGF0dGVuKGRlY3J5cHRlZCBhcyBhbnlbXSwge1xuICAgICAgLi4uZ2V0V29ya2Zsb3dSZXZpdmVycyhnbG9iYWwpLFxuICAgICAgLi4uZXh0cmFSZXZpdmVycyxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IHsgZm9ybWF0LCBwYXlsb2FkIH0gPSBkZWNvZGVGb3JtYXRQcmVmaXgoZGVjcnlwdGVkKTtcblxuICBpZiAoZm9ybWF0ID09PSBTZXJpYWxpemF0aW9uRm9ybWF0LkRFVkFMVUVfVjEpIHtcbiAgICBjb25zdCBzdHIgPSBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUocGF5bG9hZCk7XG4gICAgcmV0dXJuIHBhcnNlKHN0ciwge1xuICAgICAgLi4uZ2V0V29ya2Zsb3dSZXZpdmVycyhnbG9iYWwpLFxuICAgICAgLi4uZXh0cmFSZXZpdmVycyxcbiAgICB9KTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgc2VyaWFsaXphdGlvbiBmb3JtYXQ6ICR7Zm9ybWF0fWApO1xufVxuXG4vKipcbiAqIENhbGxlZCBmcm9tIHRoZSB3b3JrZmxvdyBoYW5kbGVyIHdoZW4gdGhlIHdvcmtmbG93IGl0c2VsZiB0aHJvd3MuXG4gKiBEZWh5ZHJhdGVzIHRoZSB0aHJvd24gdmFsdWUgZnJvbSB3aXRoaW4gdGhlIHdvcmtmbG93IGV4ZWN1dGlvbiBlbnZpcm9ubWVudFxuICogaW50byBhIGZvcm1hdCB0aGF0IGNhbiBiZSBzYXZlZCB0byB0aGUgZGF0YWJhc2UgaW4gYSBgcnVuX2ZhaWxlZGAgZXZlbnQuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHRocm93biB2YWx1ZSB0byBzZXJpYWxpemUgKGNhbiBiZSBhbnkgdHlwZSlcbiAqIEBwYXJhbSBydW5JZCAtIFJ1biBJRCBmb3IgZW5jcnlwdGlvbiBjb250ZXh0XG4gKiBAcGFyYW0ga2V5IC0gRW5jcnlwdGlvbiBrZXkgKHVuZGVmaW5lZCB0byBza2lwIGVuY3J5cHRpb24pXG4gKiBAcGFyYW0gZ2xvYmFsIC0gR2xvYmFsIG9iamVjdCBmb3Igc2VyaWFsaXphdGlvbiBjb250ZXh0XG4gKiBAcmV0dXJucyBUaGUgZGVoeWRyYXRlZCB2YWx1ZSBhcyBiaW5hcnkgZGF0YSAoVWludDhBcnJheSkgd2l0aCBmb3JtYXQgcHJlZml4XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWh5ZHJhdGVSdW5FcnJvcihcbiAgdmFsdWU6IHVua25vd24sXG4gIF9ydW5JZDogc3RyaW5nLFxuICBrZXk6IENyeXB0b0tleSB8IHVuZGVmaW5lZCxcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpc1xuKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIHRyeSB7XG4gICAgY29uc3Qgc3RyID0gc3RyaW5naWZ5KHZhbHVlLCBnZXRXb3JrZmxvd1JlZHVjZXJzKGdsb2JhbCkpO1xuICAgIGNvbnN0IHBheWxvYWQgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoc3RyKTtcbiAgICBjb25zdCBzZXJpYWxpemVkID0gZW5jb2RlV2l0aEZvcm1hdFByZWZpeChcbiAgICAgIFNlcmlhbGl6YXRpb25Gb3JtYXQuREVWQUxVRV9WMSxcbiAgICAgIHBheWxvYWRcbiAgICApIGFzIFVpbnQ4QXJyYXk7XG4gICAgcmV0dXJuIChhd2FpdCBtYXliZUVuY3J5cHQoc2VyaWFsaXplZCwga2V5KSkgYXMgVWludDhBcnJheTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zdCBjYXVzZSA9IHVud3JhcFNlcmlhbGl6YXRpb25DYXVzZShlcnJvcik7XG4gICAgY29uc3QgeyBtZXNzYWdlLCBoaW50IH0gPSBmb3JtYXRTZXJpYWxpemF0aW9uRXJyb3IoJ3J1biBlcnJvcicsIGNhdXNlKTtcbiAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKG1lc3NhZ2UsIHsgaGludCwgY2F1c2UgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBDYWxsZWQgZnJvbSB0aGUgY2xpZW50IHNpZGUgKG9yIG9ic2VydmFiaWxpdHkgdG9vbHMpIHRvIGh5ZHJhdGUgdGhlIHJ1blxuICogZXJyb3IgdmFsdWUgb2YgYSBmYWlsZWQgd29ya2Zsb3cgcnVuLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIEJpbmFyeSBzZXJpYWxpemVkIGRhdGEgKFVpbnQ4QXJyYXkpIHdpdGggZm9ybWF0IHByZWZpeFxuICogQHBhcmFtIHJ1bklkIC0gUnVuIElEIGZvciBkZWNyeXB0aW9uIGNvbnRleHRcbiAqIEBwYXJhbSBrZXkgLSBFbmNyeXB0aW9uIGtleSAodW5kZWZpbmVkIHRvIHNraXAgZGVjcnlwdGlvbilcbiAqIEBwYXJhbSBvcHMgLSBQcm9taXNlIGFycmF5IGZvciBzdHJlYW0gb3BlcmF0aW9uc1xuICogQHBhcmFtIGdsb2JhbCAtIEdsb2JhbCBvYmplY3QgZm9yIGRlc2VyaWFsaXphdGlvbiBjb250ZXh0XG4gKiBAcGFyYW0gZXh0cmFSZXZpdmVycyAtIEFkZGl0aW9uYWwgcmV2aXZlcnMgZm9yIGN1c3RvbSB0eXBlc1xuICogQHJldHVybnMgVGhlIGh5ZHJhdGVkIHRocm93biB2YWx1ZSwgcmVhZHkgdG8gYmUgY29uc3VtZWQgYnkgdGhlIGNsaWVudFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaHlkcmF0ZVJ1bkVycm9yKFxuICB2YWx1ZTogVWludDhBcnJheSB8IHVua25vd24sXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXSA9IFtdLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBleHRyYVJldml2ZXJzOiBSZWNvcmQ8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gYW55PiA9IHt9XG4pOiBQcm9taXNlPHVua25vd24+IHtcbiAgY29uc3QgZGVjcnlwdGVkID0gYXdhaXQgbWF5YmVEZWNyeXB0KHZhbHVlLCBrZXkpO1xuXG4gIGlmICghKGRlY3J5cHRlZCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKSB7XG4gICAgLy8gU2VlIHRoZSBtYXRjaGluZyBub3RlIGluIGBoeWRyYXRlU3RlcEVycm9yYDogdGhpcyBicmFuY2ggaXMgZm9yXG4gICAgLy8gZGV2YWx1ZSBmbGF0dGVuZWQgYXJyYXlzIGZyb20gbGVnYWN5IGNhbGxlcnM7IGN1cnJlbnQgU0RLIHZlcnNpb25zXG4gICAgLy8gYWx3YXlzIGVtaXQgYSBVaW50OEFycmF5LCBhbmQgYSBtaXNzaGFwZW4gdmFsdWUgaGVyZSBpbnRlbnRpb25hbGx5XG4gICAgLy8gdGhyb3dzIHZpYSBgdW5mbGF0dGVuYCBzbyB0aGUgc3Vycm91bmRpbmcgdHJ5L2NhdGNoIGluIG8xMXkgaGVscGVyc1xuICAgIC8vIHN1cmZhY2VzIHRoZSBpc3N1ZSByYXRoZXIgdGhhbiBtYXNraW5nIGl0LlxuICAgIHJldHVybiB1bmZsYXR0ZW4oZGVjcnlwdGVkIGFzIGFueVtdLCB7XG4gICAgICAuLi5nZXRFeHRlcm5hbFJldml2ZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwga2V5KSxcbiAgICAgIC4uLmV4dHJhUmV2aXZlcnMsXG4gICAgfSk7XG4gIH1cblxuICBjb25zdCB7IGZvcm1hdCwgcGF5bG9hZCB9ID0gZGVjb2RlRm9ybWF0UHJlZml4KGRlY3J5cHRlZCk7XG5cbiAgaWYgKGZvcm1hdCA9PT0gU2VyaWFsaXphdGlvbkZvcm1hdC5ERVZBTFVFX1YxKSB7XG4gICAgY29uc3Qgc3RyID0gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKHBheWxvYWQpO1xuICAgIHJldHVybiBwYXJzZShzdHIsIHtcbiAgICAgIC4uLmdldEV4dGVybmFsUmV2aXZlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBrZXkpLFxuICAgICAgLi4uZXh0cmFSZXZpdmVycyxcbiAgICB9KTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgc2VyaWFsaXphdGlvbiBmb3JtYXQ6ICR7Zm9ybWF0fWApO1xufVxuXG4vKipcbiAqIENhbGxlZCBmcm9tIHRoZSB3b3JrZmxvdyBoYW5kbGVyIHdoZW4gcmVwbGF5aW5nIHRoZSBldmVudCBsb2cgb2YgYSBgc3RlcF9jb21wbGV0ZWRgIGV2ZW50LlxuICogSHlkcmF0ZXMgdGhlIHJldHVybiB2YWx1ZSBvZiBhIHN0ZXAgZnJvbSB0aGUgZGF0YWJhc2UuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gQmluYXJ5IHNlcmlhbGl6ZWQgZGF0YSAoVWludDhBcnJheSkgd2l0aCBmb3JtYXQgcHJlZml4XG4gKiBAcGFyYW0gcnVuSWQgLSBSdW4gSUQgZm9yIGRlY3J5cHRpb24gY29udGV4dFxuICogQHBhcmFtIGtleSAtIEVuY3J5cHRpb24ga2V5ICh1bmRlZmluZWQgdG8gc2tpcCBkZWNyeXB0aW9uKVxuICogQHBhcmFtIGdsb2JhbCAtIEdsb2JhbCBvYmplY3QgZm9yIGRlc2VyaWFsaXphdGlvbiBjb250ZXh0XG4gKiBAcGFyYW0gZXh0cmFSZXZpdmVycyAtIEFkZGl0aW9uYWwgcmV2aXZlcnMgZm9yIGN1c3RvbSB0eXBlc1xuICogQ2FsbGVkIGZyb20gdGhlIHdvcmtmbG93IGhhbmRsZXIgd2hlbiByZXBsYXlpbmcgdGhlIGV2ZW50IGxvZ1xuICogb2YgYSBgc3RlcF9jb21wbGV0ZWRgIGV2ZW50LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaHlkcmF0ZVN0ZXBSZXR1cm5WYWx1ZShcbiAgdmFsdWU6IFVpbnQ4QXJyYXkgfCB1bmtub3duLFxuICBfcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIGV4dHJhUmV2aXZlcnM6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+ID0ge31cbik6IFByb21pc2U8YW55PiB7XG4gIHJldHVybiB3b3JrZmxvd01vZHVsZS5kZXNlcmlhbGl6ZShhd2FpdCBtYXliZURlY3J5cHQodmFsdWUsIGtleSksIHtcbiAgICBnbG9iYWwsXG4gICAgZXh0cmFSZXZpdmVyczoge1xuICAgICAgLi4uZ2V0U3RyZWFtQW5kUmVxdWVzdFJldml2ZXJzKGdldFdvcmtmbG93UmV2aXZlcnMoZ2xvYmFsKSksXG4gICAgICAuLi5leHRyYVJldml2ZXJzLFxuICAgIH0sXG4gIH0pO1xufVxuXG4vLyAtLS0tIEhlbHBlcnMgdG8gZXh0cmFjdCBzdHJlYW0vUmVxdWVzdC9SZXNwb25zZSByZWR1Y2VycyBhbmQgcmV2aXZlcnMgLS0tLVxuLy8gVGhlIG1vZGUtc3BlY2lmaWMgZ2V0KlJlZHVjZXJzL2dldCpSZXZpdmVycyBmdW5jdGlvbnMgcmV0dXJuIG9iamVjdHMgdGhhdFxuLy8gaW5jbHVkZSBib3RoIFwiY29tbW9uXCIgZW50cmllcyAoRGF0ZSwgRXJyb3IsIE1hcCwgZXRjLikgYW5kIG1vZGUtc3BlY2lmaWNcbi8vIGVudHJpZXMgKFJlYWRhYmxlU3RyZWFtLCBXcml0YWJsZVN0cmVhbSwgUmVxdWVzdCwgUmVzcG9uc2UsIFN0ZXBGdW5jdGlvbikuXG4vLyBUaGUgY29tbW9uIGVudHJpZXMgYXJlIGFscmVhZHkgY29tcG9zZWQgYnkgdGhlIGNvZGVjLiBXZSBvbmx5IG5lZWQgdG9cbi8vIHBhc3MgdGhyb3VnaCB0aGUgbW9kZS1zcGVjaWZpYyBlbnRyaWVzIGFzIGV4dHJhUmVkdWNlcnMvZXh0cmFSZXZpdmVycy5cblxuY29uc3QgU1RSRUFNX0FORF9SRVFVRVNUX0tFWVMgPSBbXG4gICdSZWFkYWJsZVN0cmVhbScsXG4gICdXcml0YWJsZVN0cmVhbScsXG4gICdSZXF1ZXN0JyxcbiAgJ1Jlc3BvbnNlJyxcbiAgJ1N0ZXBGdW5jdGlvbicsXG4gIC8vIFdpcmUgQWJvcnRDb250cm9sbGVyL0Fib3J0U2lnbmFsIHRocm91Z2ggdGhlIGNsaWVudCBzZXJpYWxpemF0aW9uIHBhdGggc29cbiAgLy8gc2lnbmFscyByZWFjaGFibGUgdmlhIFJlcXVlc3Quc2lnbmFsIChvciBhcyBkaXJlY3QgYXJndW1lbnRzKSBnZXQgdGhlaXJcbiAgLy8gZGVkaWNhdGVkIHJlZHVjZXIuIFdpdGhvdXQgdGhpcywgZGV2YWx1ZSBmYWxscyBiYWNrIHRvIGl0cyBhcmJpdHJhcnktUE9KT1xuICAvLyBwYXRoIGFuZCBmYWlscyBmb3IgYW55IHNpZ25hbCB0aGUgUmVxdWVzdCByZWR1Y2VyIGZvcndhcmRzLlxuICAnQWJvcnRDb250cm9sbGVyJyxcbiAgJ0Fib3J0U2lnbmFsJyxcbl0gYXMgY29uc3Q7XG5cbmZ1bmN0aW9uIGdldFN0cmVhbUFuZFJlcXVlc3RSZWR1Y2VycyhcbiAgYWxsUmVkdWNlcnM6IFJlY29yZDxzdHJpbmcsIGFueT5cbik6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+IHtcbiAgY29uc3QgZXh0cmE6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+ID0ge307XG4gIGZvciAoY29uc3Qga2V5IG9mIFNUUkVBTV9BTkRfUkVRVUVTVF9LRVlTKSB7XG4gICAgaWYgKGtleSBpbiBhbGxSZWR1Y2Vycykge1xuICAgICAgZXh0cmFba2V5XSA9IGFsbFJlZHVjZXJzW2tleV07XG4gICAgfVxuICB9XG4gIHJldHVybiBleHRyYTtcbn1cblxuZnVuY3Rpb24gZ2V0U3RyZWFtQW5kUmVxdWVzdFJldml2ZXJzKFxuICBhbGxSZXZpdmVyczogUmVjb3JkPHN0cmluZywgYW55PlxuKTogUmVjb3JkPHN0cmluZywgKHZhbHVlOiBhbnkpID0+IGFueT4ge1xuICBjb25zdCBleHRyYTogUmVjb3JkPHN0cmluZywgKHZhbHVlOiBhbnkpID0+IGFueT4gPSB7fTtcbiAgZm9yIChjb25zdCBrZXkgb2YgU1RSRUFNX0FORF9SRVFVRVNUX0tFWVMpIHtcbiAgICBpZiAoa2V5IGluIGFsbFJldml2ZXJzKSB7XG4gICAgICBleHRyYVtrZXldID0gYWxsUmV2aXZlcnNba2V5XTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGV4dHJhO1xufVxuIl19
|