@workflow/core 5.0.0-beta.3 → 5.0.0-beta.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/dist/attribute-changes.d.ts +7 -0
  2. package/dist/attribute-changes.d.ts.map +1 -0
  3. package/dist/attribute-changes.js +25 -0
  4. package/dist/capabilities.d.ts +22 -1
  5. package/dist/capabilities.d.ts.map +1 -1
  6. package/dist/capabilities.js +41 -4
  7. package/dist/capture-stack.d.ts +16 -0
  8. package/dist/capture-stack.d.ts.map +1 -0
  9. package/dist/capture-stack.js +21 -0
  10. package/dist/class-serialization.d.ts +32 -0
  11. package/dist/class-serialization.d.ts.map +1 -1
  12. package/dist/class-serialization.js +37 -1
  13. package/dist/classify-error.d.ts +26 -3
  14. package/dist/classify-error.d.ts.map +1 -1
  15. package/dist/classify-error.js +103 -6
  16. package/dist/context-errors.d.ts +27 -0
  17. package/dist/context-errors.d.ts.map +1 -0
  18. package/dist/context-errors.js +101 -0
  19. package/dist/context-violation-error.d.ts +97 -0
  20. package/dist/context-violation-error.d.ts.map +1 -0
  21. package/dist/context-violation-error.js +147 -0
  22. package/dist/create-hook.d.ts +42 -3
  23. package/dist/create-hook.d.ts.map +1 -1
  24. package/dist/create-hook.js +4 -3
  25. package/dist/define-hook.d.ts.map +1 -1
  26. package/dist/define-hook.js +20 -5
  27. package/dist/describe-error.d.ts +70 -0
  28. package/dist/describe-error.d.ts.map +1 -0
  29. package/dist/describe-error.js +165 -0
  30. package/dist/encryption.d.ts +22 -1
  31. package/dist/encryption.d.ts.map +1 -1
  32. package/dist/encryption.js +72 -27
  33. package/dist/events-consumer.d.ts +25 -1
  34. package/dist/events-consumer.d.ts.map +1 -1
  35. package/dist/events-consumer.js +95 -16
  36. package/dist/flushable-stream.d.ts +10 -10
  37. package/dist/flushable-stream.d.ts.map +1 -1
  38. package/dist/flushable-stream.js +26 -15
  39. package/dist/global.d.ts +35 -1
  40. package/dist/global.d.ts.map +1 -1
  41. package/dist/global.js +21 -3
  42. package/dist/index.d.ts +1 -0
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +2 -1
  45. package/dist/log-format.d.ts +25 -0
  46. package/dist/log-format.d.ts.map +1 -0
  47. package/dist/log-format.js +250 -0
  48. package/dist/logger.d.ts +29 -30
  49. package/dist/logger.d.ts.map +1 -1
  50. package/dist/logger.js +82 -32
  51. package/dist/private.d.ts +107 -2
  52. package/dist/private.d.ts.map +1 -1
  53. package/dist/private.js +80 -3
  54. package/dist/runtime/constants.d.ts +189 -0
  55. package/dist/runtime/constants.d.ts.map +1 -1
  56. package/dist/runtime/constants.js +310 -15
  57. package/dist/runtime/get-port-lazy.d.ts +25 -0
  58. package/dist/runtime/get-port-lazy.d.ts.map +1 -0
  59. package/dist/runtime/get-port-lazy.js +92 -0
  60. package/dist/runtime/get-world-lazy.d.ts +23 -0
  61. package/dist/runtime/get-world-lazy.d.ts.map +1 -0
  62. package/dist/runtime/get-world-lazy.js +46 -0
  63. package/dist/runtime/helpers.d.ts +57 -6
  64. package/dist/runtime/helpers.d.ts.map +1 -1
  65. package/dist/runtime/helpers.js +169 -32
  66. package/dist/runtime/replay-budget.d.ts +98 -0
  67. package/dist/runtime/replay-budget.d.ts.map +1 -0
  68. package/dist/runtime/replay-budget.js +192 -0
  69. package/dist/runtime/resume-hook.d.ts.map +1 -1
  70. package/dist/runtime/resume-hook.js +39 -23
  71. package/dist/runtime/run-id-time.d.ts +10 -0
  72. package/dist/runtime/run-id-time.d.ts.map +1 -0
  73. package/dist/runtime/run-id-time.js +31 -0
  74. package/dist/runtime/run.d.ts +6 -2
  75. package/dist/runtime/run.d.ts.map +1 -1
  76. package/dist/runtime/run.js +52 -10
  77. package/dist/runtime/runs.d.ts +36 -2
  78. package/dist/runtime/runs.d.ts.map +1 -1
  79. package/dist/runtime/runs.js +18 -7
  80. package/dist/runtime/start.d.ts +58 -1
  81. package/dist/runtime/start.d.ts.map +1 -1
  82. package/dist/runtime/start.js +160 -46
  83. package/dist/runtime/step-executor.d.ts +131 -0
  84. package/dist/runtime/step-executor.d.ts.map +1 -0
  85. package/dist/runtime/step-executor.js +818 -0
  86. package/dist/runtime/step-handler.d.ts.map +1 -1
  87. package/dist/runtime/step-handler.js +718 -557
  88. package/dist/runtime/step-latency.d.ts +131 -0
  89. package/dist/runtime/step-latency.d.ts.map +1 -0
  90. package/dist/runtime/step-latency.js +155 -0
  91. package/dist/runtime/step-ownership.d.ts +72 -0
  92. package/dist/runtime/step-ownership.d.ts.map +1 -0
  93. package/dist/runtime/step-ownership.js +114 -0
  94. package/dist/runtime/step-single-flight.d.ts +12 -0
  95. package/dist/runtime/step-single-flight.d.ts.map +1 -0
  96. package/dist/runtime/step-single-flight.js +69 -0
  97. package/dist/runtime/suspension-handler.d.ts +81 -7
  98. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  99. package/dist/runtime/suspension-handler.js +355 -137
  100. package/dist/runtime/wait-continuation.d.ts +84 -0
  101. package/dist/runtime/wait-continuation.d.ts.map +1 -0
  102. package/dist/runtime/wait-continuation.js +105 -0
  103. package/dist/runtime/wait-until.d.ts +18 -0
  104. package/dist/runtime/wait-until.d.ts.map +1 -0
  105. package/dist/runtime/wait-until.js +42 -0
  106. package/dist/runtime/world-compatibility.d.ts +5 -0
  107. package/dist/runtime/world-compatibility.d.ts.map +1 -0
  108. package/dist/runtime/world-compatibility.js +12 -0
  109. package/dist/runtime/world-init.d.ts +50 -0
  110. package/dist/runtime/world-init.d.ts.map +1 -0
  111. package/dist/runtime/world-init.js +50 -0
  112. package/dist/runtime/world-target.d.ts +11 -0
  113. package/dist/runtime/world-target.d.ts.map +1 -0
  114. package/dist/runtime/world-target.js +15 -0
  115. package/dist/runtime/world.d.ts +21 -9
  116. package/dist/runtime/world.d.ts.map +1 -1
  117. package/dist/runtime/world.js +58 -83
  118. package/dist/runtime.d.ts +15 -10
  119. package/dist/runtime.d.ts.map +1 -1
  120. package/dist/runtime.js +1757 -326
  121. package/dist/schemas.d.ts +1 -1
  122. package/dist/schemas.d.ts.map +1 -1
  123. package/dist/schemas.js +1 -1
  124. package/dist/serialization/client.d.ts +17 -0
  125. package/dist/serialization/client.d.ts.map +1 -0
  126. package/dist/serialization/client.js +48 -0
  127. package/dist/serialization/codec-devalue.d.ts +14 -0
  128. package/dist/serialization/codec-devalue.d.ts.map +1 -0
  129. package/dist/serialization/codec-devalue.js +98 -0
  130. package/dist/serialization/codec.d.ts +106 -0
  131. package/dist/serialization/codec.d.ts.map +1 -0
  132. package/dist/serialization/codec.js +17 -0
  133. package/dist/serialization/compression.d.ts +104 -0
  134. package/dist/serialization/compression.d.ts.map +1 -0
  135. package/dist/serialization/compression.js +260 -0
  136. package/dist/serialization/encryption.d.ts +33 -0
  137. package/dist/serialization/encryption.d.ts.map +1 -0
  138. package/dist/serialization/encryption.js +70 -0
  139. package/dist/serialization/errors.d.ts +34 -0
  140. package/dist/serialization/errors.d.ts.map +1 -0
  141. package/dist/serialization/errors.js +59 -0
  142. package/dist/serialization/format.d.ts +60 -0
  143. package/dist/serialization/format.d.ts.map +1 -0
  144. package/dist/serialization/format.js +97 -0
  145. package/dist/serialization/index.d.ts +19 -0
  146. package/dist/serialization/index.d.ts.map +1 -0
  147. package/dist/serialization/index.js +22 -0
  148. package/dist/serialization/reducers/class.d.ts +11 -0
  149. package/dist/serialization/reducers/class.d.ts.map +1 -0
  150. package/dist/serialization/reducers/class.js +68 -0
  151. package/dist/serialization/reducers/common.d.ts +16 -0
  152. package/dist/serialization/reducers/common.d.ts.map +1 -0
  153. package/dist/serialization/reducers/common.js +417 -0
  154. package/dist/serialization/reducers/step-function.d.ts +35 -0
  155. package/dist/serialization/reducers/step-function.d.ts.map +1 -0
  156. package/dist/serialization/reducers/step-function.js +88 -0
  157. package/dist/serialization/step.d.ts +17 -0
  158. package/dist/serialization/step.d.ts.map +1 -0
  159. package/dist/serialization/step.js +48 -0
  160. package/dist/serialization/types.d.ts +253 -0
  161. package/dist/serialization/types.d.ts.map +1 -0
  162. package/dist/serialization/types.js +25 -0
  163. package/dist/serialization/workflow.d.ts +29 -0
  164. package/dist/serialization/workflow.d.ts.map +1 -0
  165. package/dist/serialization/workflow.js +54 -0
  166. package/dist/serialization-format.d.ts +16 -0
  167. package/dist/serialization-format.d.ts.map +1 -1
  168. package/dist/serialization-format.js +213 -50
  169. package/dist/serialization.d.ts +322 -214
  170. package/dist/serialization.d.ts.map +1 -1
  171. package/dist/serialization.js +1575 -664
  172. package/dist/set-attributes.d.ts +18 -0
  173. package/dist/set-attributes.d.ts.map +1 -0
  174. package/dist/set-attributes.js +61 -0
  175. package/dist/sleep.d.ts.map +1 -1
  176. package/dist/sleep.js +3 -2
  177. package/dist/source-map.d.ts +5 -0
  178. package/dist/source-map.d.ts.map +1 -1
  179. package/dist/source-map.js +102 -10
  180. package/dist/step/context-storage.d.ts +53 -0
  181. package/dist/step/context-storage.d.ts.map +1 -1
  182. package/dist/step/context-storage.js +1 -1
  183. package/dist/step/get-closure-vars.d.ts.map +1 -1
  184. package/dist/step/get-closure-vars.js +3 -2
  185. package/dist/step/get-step-metadata.d.ts.map +1 -1
  186. package/dist/step/get-step-metadata.js +3 -2
  187. package/dist/step/get-workflow-metadata.d.ts.map +1 -1
  188. package/dist/step/get-workflow-metadata.js +3 -2
  189. package/dist/step/writable-stream.d.ts.map +1 -1
  190. package/dist/step/writable-stream.js +58 -6
  191. package/dist/step-hydration-cache.d.ts +148 -0
  192. package/dist/step-hydration-cache.d.ts.map +1 -0
  193. package/dist/step-hydration-cache.js +171 -0
  194. package/dist/step.d.ts.map +1 -1
  195. package/dist/step.js +144 -25
  196. package/dist/symbols.d.ts +28 -0
  197. package/dist/symbols.d.ts.map +1 -1
  198. package/dist/symbols.js +29 -1
  199. package/dist/telemetry/semantic-conventions.d.ts +98 -2
  200. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  201. package/dist/telemetry/semantic-conventions.js +66 -1
  202. package/dist/telemetry.d.ts +68 -0
  203. package/dist/telemetry.d.ts.map +1 -1
  204. package/dist/telemetry.js +106 -4
  205. package/dist/types.d.ts +6 -0
  206. package/dist/types.d.ts.map +1 -1
  207. package/dist/types.js +23 -1
  208. package/dist/util.d.ts +16 -6
  209. package/dist/util.d.ts.map +1 -1
  210. package/dist/util.js +25 -16
  211. package/dist/version.d.ts +1 -1
  212. package/dist/version.d.ts.map +1 -1
  213. package/dist/version.js +2 -2
  214. package/dist/vm/index.d.ts.map +1 -1
  215. package/dist/vm/index.js +3 -2
  216. package/dist/vm/script-cache.d.ts +28 -0
  217. package/dist/vm/script-cache.d.ts.map +1 -0
  218. package/dist/vm/script-cache.js +140 -0
  219. package/dist/workflow/abort-controller.d.ts +65 -0
  220. package/dist/workflow/abort-controller.d.ts.map +1 -0
  221. package/dist/workflow/abort-controller.js +277 -0
  222. package/dist/workflow/attribute-dispatcher.d.ts +6 -0
  223. package/dist/workflow/attribute-dispatcher.d.ts.map +1 -0
  224. package/dist/workflow/attribute-dispatcher.js +48 -0
  225. package/dist/workflow/create-hook.d.ts.map +1 -1
  226. package/dist/workflow/create-hook.js +25 -3
  227. package/dist/workflow/define-hook.d.ts +1 -1
  228. package/dist/workflow/define-hook.d.ts.map +1 -1
  229. package/dist/workflow/define-hook.js +8 -4
  230. package/dist/workflow/get-workflow-metadata.d.ts.map +1 -1
  231. package/dist/workflow/get-workflow-metadata.js +14 -3
  232. package/dist/workflow/hook.d.ts.map +1 -1
  233. package/dist/workflow/hook.js +207 -33
  234. package/dist/workflow/index.d.ts +1 -0
  235. package/dist/workflow/index.d.ts.map +1 -1
  236. package/dist/workflow/index.js +5 -3
  237. package/dist/workflow/set-attributes.d.ts +77 -0
  238. package/dist/workflow/set-attributes.d.ts.map +1 -0
  239. package/dist/workflow/set-attributes.js +65 -0
  240. package/dist/workflow/sleep.d.ts.map +1 -1
  241. package/dist/workflow/sleep.js +45 -8
  242. package/dist/workflow/world-init-stub.d.ts +15 -0
  243. package/dist/workflow/world-init-stub.d.ts.map +1 -0
  244. package/dist/workflow/world-init-stub.js +15 -0
  245. package/dist/workflow.d.ts +17 -1
  246. package/dist/workflow.d.ts.map +1 -1
  247. package/dist/workflow.js +190 -56
  248. package/docs/api-reference/create-hook.mdx +38 -0
  249. package/docs/api-reference/create-webhook.mdx +1 -0
  250. package/docs/api-reference/fetch.mdx +5 -0
  251. package/docs/api-reference/index.mdx +3 -0
  252. package/docs/api-reference/set-attributes.mdx +65 -0
  253. package/docs/foundations/cancellation.mdx +459 -0
  254. package/docs/foundations/errors-and-retries.mdx +7 -3
  255. package/docs/foundations/hooks.mdx +29 -0
  256. package/docs/foundations/idempotency.mdx +236 -11
  257. package/docs/foundations/index.mdx +1 -23
  258. package/docs/foundations/meta.json +3 -1
  259. package/docs/foundations/serialization.mdx +77 -41
  260. package/docs/foundations/starting-workflows.mdx +5 -1
  261. package/docs/foundations/streaming.mdx +14 -23
  262. package/docs/foundations/versioning.mdx +263 -0
  263. package/docs/how-it-works/cancellation.mdx +287 -0
  264. package/docs/how-it-works/code-transform.mdx +2 -2
  265. package/docs/how-it-works/encryption.mdx +2 -2
  266. package/docs/how-it-works/event-sourcing.mdx +2 -2
  267. package/docs/how-it-works/meta.json +2 -1
  268. package/package.json +32 -11
@@ -1,19 +1,47 @@
1
- import { waitUntil } from '@vercel/functions';
2
- import { EntityConflictError, ThrottleError, WorkflowRuntimeError, WorkflowWorldError, } from '@workflow/errors';
3
- import { isLegacySpecVersion, SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT, SPEC_VERSION_SUPPORTS_EVENT_SOURCING, } from '@workflow/world';
1
+ import { EntityConflictError, WorkflowRuntimeError } from '@workflow/errors';
2
+ import { workflowDisplayName } from '@workflow/utils/parse-name';
3
+ import { isLegacySpecVersion, SPEC_VERSION_SUPPORTS_ATTRIBUTES, SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT, SPEC_VERSION_SUPPORTS_COMPRESSION, workflowRunIdSchema, } from '@workflow/world';
4
4
  import { monotonicFactory } from 'ulid';
5
+ import { normalizeAttributeChanges } from '../attribute-changes.js';
6
+ import { getRunCapabilities } from '../capabilities.js';
7
+ import { isRetryableWorldError } from '../classify-error.js';
5
8
  import { importKey } from '../encryption.js';
6
9
  import { runtimeLogger } from '../logger.js';
7
- import { dehydrateWorkflowArguments } from '../serialization.js';
10
+ import { dehydrateWorkflowArguments, SerializationFormat, } from '../serialization.js';
8
11
  import * as Attribute from '../telemetry/semantic-conventions.js';
9
12
  import { serializeTraceCarrier, trace } from '../telemetry.js';
10
- import { waitedUntil } from '../util.js';
11
13
  import { version as workflowCoreVersion } from '../version.js';
12
- import { getWorkflowQueueName } from './helpers.js';
14
+ import { getWorldLazy } from './get-world-lazy.js';
15
+ import { getWorkflowQueueName, healthCheck } from './helpers.js';
13
16
  import { Run } from './run.js';
14
- import { getWorld } from './world.js';
17
+ import { safeWaitUntil, waitedUntil } from './wait-until.js';
18
+ import { assertWorldSupportsRuntimeProtocol } from './world-compatibility.js';
19
+ /**
20
+ * Timeout for the cross-deployment capability probe done before
21
+ * dehydrating workflow arguments. Kept tight on purpose: the probe is
22
+ * an optimization (it lets the caller emit the framed byte-stream wire
23
+ * format when the target supports it), and the fallback on timeout is
24
+ * the legacy raw format which always works. Long delays here would just
25
+ * make `start({ deploymentId: ... })` slower for users whose target
26
+ * deployments don't recognize the health check at all.
27
+ */
28
+ const CROSS_DEPLOYMENT_CAPABILITY_PROBE_TIMEOUT_MS = 2_000;
15
29
  /** ULID generator for client-side runId generation */
16
30
  const ulid = monotonicFactory();
31
+ // `deploymentId: 'latest'` is a no-op in Worlds without atomic deployments.
32
+ // The warning that explains this only needs to fire once per process: a
33
+ // workflow that hardcodes 'latest' for its Vercel deployment would otherwise
34
+ // log it on every local/Postgres run, flooding tight dev loops.
35
+ let hasWarnedLatestNoOp = false;
36
+ /**
37
+ * Reset the `deploymentId: 'latest'` no-op warn-once guard. Test-only —
38
+ * exported so unit tests can exercise the warn path across `start()` calls.
39
+ *
40
+ * @internal
41
+ */
42
+ export function _resetLatestNoOpWarnForTests() {
43
+ hasWarnedLatestNoOp = false;
44
+ }
17
45
  export async function start(workflow, argsOrOptions, options) {
18
46
  'use step';
19
47
  return await waitedUntil(() => {
@@ -22,7 +50,8 @@ export async function start(workflow, argsOrOptions, options) {
22
50
  if (!workflowName) {
23
51
  throw new WorkflowRuntimeError(`'start' received an invalid workflow function. Ensure the Workflow SDK is configured correctly and the function includes a 'use workflow' directive.`, { slug: 'start-invalid-workflow-function' });
24
52
  }
25
- return trace(`workflow.start ${workflowName}`, async (span) => {
53
+ const spanName = `workflow.start ${workflowDisplayName(workflowName)}`;
54
+ return trace(spanName, async (span) => {
26
55
  span?.setAttributes({
27
56
  ...Attribute.WorkflowName(workflowName),
28
57
  ...Attribute.WorkflowOperation('start'),
@@ -38,16 +67,65 @@ export async function start(workflow, argsOrOptions, options) {
38
67
  span?.setAttributes({
39
68
  ...Attribute.WorkflowArgumentsCount(args.length),
40
69
  });
41
- const world = opts?.world ?? (await getWorld());
42
- let deploymentId = opts.deploymentId ?? (await world.getDeploymentId());
70
+ const world = opts.world ?? (await getWorldLazy());
71
+ assertWorldSupportsRuntimeProtocol(world);
72
+ const currentDeploymentId = await world.getDeploymentId();
73
+ let deploymentId = opts.deploymentId ?? currentDeploymentId;
43
74
  // When 'latest' is requested, resolve the actual latest deployment ID
44
75
  // for the current deployment's environment (same production target or
45
76
  // same git branch for preview deployments).
77
+ //
78
+ // Resolving 'latest' only means something in worlds with atomic,
79
+ // immutable deployments (e.g. Vercel), which implement
80
+ // resolveLatestDeploymentId(). Worlds without that concept (local dev,
81
+ // self-hosted Postgres) have nothing to resolve between, so rather than
82
+ // fail a run that works fine on Vercel, we warn and fall back to the
83
+ // current deployment — making 'latest' an effective no-op there.
46
84
  if (deploymentId === 'latest') {
47
- if (!world.resolveLatestDeploymentId) {
48
- throw new WorkflowRuntimeError("deploymentId 'latest' requires a World that implements resolveLatestDeploymentId()");
85
+ if (world.resolveLatestDeploymentId) {
86
+ deploymentId = await world.resolveLatestDeploymentId();
87
+ }
88
+ else {
89
+ // Warn once per process — see hasWarnedLatestNoOp above.
90
+ if (!hasWarnedLatestNoOp) {
91
+ hasWarnedLatestNoOp = true;
92
+ runtimeLogger.warn("deploymentId: 'latest' has no effect in this world and was ignored. " +
93
+ 'It is only supported by worlds with atomic deployments, such as Vercel. ' +
94
+ 'The run will target the current deployment.', { currentDeploymentId });
95
+ }
96
+ deploymentId = currentDeploymentId;
49
97
  }
50
- deploymentId = await world.resolveLatestDeploymentId();
98
+ }
99
+ // Decide whether to write byte streams in the framed wire format.
100
+ // For same-deployment starts (the common case) we know the target is
101
+ // running this same SDK version, so framing is safe. For cross-
102
+ // deployment starts (explicit deploymentId or 'latest' that resolves
103
+ // to a different deployment) we probe the target via healthCheck to
104
+ // learn its workflow-core version, then derive the capability. The
105
+ // probe has a tight timeout — on miss/failure we fall back to the
106
+ // legacy raw byte format, which is universally readable.
107
+ //
108
+ // Worlds that don't expose the `streams` API (e.g. minimal test
109
+ // mocks) can't service health checks, so we skip the probe for them.
110
+ let framedByteStreams;
111
+ let targetSupportsCompression;
112
+ if (deploymentId === currentDeploymentId) {
113
+ framedByteStreams = true;
114
+ targetSupportsCompression = true;
115
+ }
116
+ else if (typeof world.streams?.get !== 'function') {
117
+ framedByteStreams = false;
118
+ targetSupportsCompression = false;
119
+ }
120
+ else {
121
+ const probe = await healthCheck(world, 'workflow', {
122
+ deploymentId,
123
+ timeout: CROSS_DEPLOYMENT_CAPABILITY_PROBE_TIMEOUT_MS,
124
+ namespace: opts.namespace,
125
+ }).catch(() => undefined);
126
+ const capabilities = getRunCapabilities(probe?.workflowCoreVersion);
127
+ framedByteStreams = capabilities.framedByteStreams;
128
+ targetSupportsCompression = capabilities.supportedFormats.has(SerializationFormat.GZIP);
51
129
  }
52
130
  const ops = [];
53
131
  // Generate runId client-side so we have it before serialization
@@ -55,14 +133,47 @@ export async function start(workflow, argsOrOptions, options) {
55
133
  const runId = `wrun_${ulid()}`;
56
134
  // Serialize current trace context to propagate across queue boundary
57
135
  const traceCarrier = await serializeTraceCarrier();
58
- // Use world-declared specVersion when available (our worlds set this),
59
- // otherwise fall back to the safe baseline that community worlds handle.
60
- // Community worlds built against older @workflow/world reject runs with
61
- // specVersion > their SPEC_VERSION_CURRENT via requiresNewerWorld().
62
- const specVersion = opts.specVersion ??
63
- world.specVersion ??
64
- SPEC_VERSION_SUPPORTS_EVENT_SOURCING;
136
+ // Default new runs to the configured world's spec version. The world
137
+ // itself has already been checked against this runtime's spec version.
138
+ const specVersion = opts.specVersion ?? world.specVersion;
65
139
  const v1Compat = isLegacySpecVersion(specVersion);
140
+ const allowReservedAttributes = opts.allowReservedAttributes === true;
141
+ let attributes;
142
+ if (opts.attributes && Object.keys(opts.attributes).length > 0) {
143
+ if (specVersion < SPEC_VERSION_SUPPORTS_ATTRIBUTES) {
144
+ throw new WorkflowRuntimeError('Initial workflow attributes require a World that supports spec version 4 or later.');
145
+ }
146
+ // `normalizeAttributeChanges` treats `undefined` as "remove this
147
+ // key", which is meaningless at creation time — reject it up front
148
+ // so JS callers get a clear error instead of a downstream schema
149
+ // failure (the types already forbid non-string values).
150
+ for (const [key, value] of Object.entries(opts.attributes)) {
151
+ if (typeof value !== 'string') {
152
+ throw new WorkflowRuntimeError(`Initial workflow attribute ${JSON.stringify(key)} must be a string value.`);
153
+ }
154
+ }
155
+ const changes = normalizeAttributeChanges(opts.attributes, {
156
+ allowReservedAttributes,
157
+ });
158
+ attributes = Object.fromEntries(changes.map(({ key, value }) => [key, value]));
159
+ }
160
+ // Seed payload shared by run_created and the resilient-start queue
161
+ // input. The flag rides along so server-side validation matches the
162
+ // client-side check above on both paths.
163
+ const attributeSeed = attributes
164
+ ? {
165
+ attributes,
166
+ ...(allowReservedAttributes
167
+ ? { allowReservedAttributes: true }
168
+ : {}),
169
+ }
170
+ : {};
171
+ // `replayedFromRunId` is a foreign key to the source run; reject anything
172
+ // that isn't a real run ID so the lineage link can't point at garbage.
173
+ if (opts.replayedFromRunId !== undefined &&
174
+ !workflowRunIdSchema.safeParse(opts.replayedFromRunId).success) {
175
+ throw new WorkflowRuntimeError(`replayedFromRunId must be a run ID (wrun_<ulid>); received ${JSON.stringify(String(opts.replayedFromRunId).slice(0, 64))}.`);
176
+ }
66
177
  // Resolve encryption key for the new run. The runId has already been
67
178
  // generated above (client-generated ULID) and will be used for both
68
179
  // key derivation and the run_created event. The World implementation
@@ -77,11 +188,20 @@ export async function start(workflow, argsOrOptions, options) {
77
188
  const encryptionKey = rawKey ? await importKey(rawKey) : undefined;
78
189
  // Create run via run_created event (event-sourced architecture)
79
190
  // Pass client-generated runId - server will accept and use it
80
- const workflowArguments = await dehydrateWorkflowArguments(args, runId, encryptionKey, ops, globalThis, v1Compat);
191
+ // Compress workflow arguments only when the run itself is marked as
192
+ // possibly containing compressed payloads (specVersion >= 5) AND the
193
+ // target deployment can decode them (same-deployment, or probed
194
+ // capability for cross-deployment starts).
195
+ const compression = targetSupportsCompression &&
196
+ specVersion >= SPEC_VERSION_SUPPORTS_COMPRESSION;
197
+ const workflowArguments = await dehydrateWorkflowArguments(args, runId, encryptionKey, ops, globalThis, v1Compat, framedByteStreams, compression);
81
198
  const executionContext = {
82
199
  traceCarrier,
83
200
  workflowCoreVersion,
84
201
  features: { encryption: !!encryptionKey },
202
+ ...(opts.replayedFromRunId
203
+ ? { replayedFromRunId: opts.replayedFromRunId }
204
+ : {}),
85
205
  };
86
206
  // Call events.create (run_created) and queue in parallel.
87
207
  // If events.create fails with 429/5xx, the run was still accepted
@@ -95,9 +215,10 @@ export async function start(workflow, argsOrOptions, options) {
95
215
  workflowName: workflowName,
96
216
  input: workflowArguments,
97
217
  executionContext,
218
+ ...attributeSeed,
98
219
  },
99
220
  }, { v1Compat }),
100
- world.queue(getWorkflowQueueName(workflowName), {
221
+ world.queue(getWorkflowQueueName(workflowName, opts.namespace), {
101
222
  runId,
102
223
  traceCarrier,
103
224
  ...(specVersion >= SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT
@@ -108,6 +229,7 @@ export async function start(workflow, argsOrOptions, options) {
108
229
  workflowName,
109
230
  specVersion,
110
231
  executionContext,
232
+ ...attributeSeed,
111
233
  },
112
234
  }
113
235
  : {}),
@@ -130,10 +252,11 @@ export async function start(workflow, argsOrOptions, options) {
130
252
  // + run_started call completes faster. We expect this to be <=1% of cases.
131
253
  // In this case, we can safely return.
132
254
  }
133
- else if (isRetryableStartError(err)) {
134
- // 429 (ThrottleError) and 5xx (WorkflowWorldError with status >= 500)
135
- // are retryable — the run was accepted via the queue and creation
136
- // will be re-tried by the runtime when it calls run_started.
255
+ else if (isRetryableWorldError(err)) {
256
+ // 429 (ThrottleError), 5xx, and transient transport failures
257
+ // (TRANSPORT/TIMEOUT) are retryable — the run was accepted via the
258
+ // queue and creation will be re-tried by the runtime when it calls
259
+ // run_started.
137
260
  resilientStart = true;
138
261
  runtimeLogger.warn('Run creation event failed, but the run was accepted via the queue. ' +
139
262
  'The run_created event will be re-tried async by the runtime.', { workflowRunId: runId, error: err.message });
@@ -153,12 +276,16 @@ export async function start(workflow, argsOrOptions, options) {
153
276
  throw new WorkflowRuntimeError(`Server returned different runId than requested: expected ${runId}, got ${result.run.runId}`);
154
277
  }
155
278
  }
156
- waitUntil(Promise.all(ops).catch((err) => {
157
- // Ignore expected client disconnect errors (e.g., browser refresh during streaming)
158
- const isAbortError = err?.name === 'AbortError' || err?.name === 'ResponseAborted';
159
- if (!isAbortError)
160
- throw err;
161
- }));
279
+ // These argument-stream ops are flushed in the background; the promise
280
+ // handed to waitUntil must never reject (an unconsumed waitUntil
281
+ // rejection crashes the process as unhandledRejection), so unexpected
282
+ // failures are logged instead.
283
+ safeWaitUntil(Promise.all(ops), (err) => {
284
+ runtimeLogger.warn('Background flush of workflow argument streams failed', {
285
+ workflowRunId: runId,
286
+ error: err instanceof Error ? err.message : String(err),
287
+ });
288
+ });
162
289
  span?.setAttributes({
163
290
  ...Attribute.WorkflowRunId(runId),
164
291
  ...Attribute.DeploymentId(deploymentId),
@@ -171,17 +298,4 @@ export async function start(workflow, argsOrOptions, options) {
171
298
  });
172
299
  });
173
300
  }
174
- /**
175
- * Checks if an error from events.create (run_created) is retryable,
176
- * meaning the queue can re-try creation later via the run_started path.
177
- * - ThrottleError (429): rate limited, will succeed later
178
- * - WorkflowWorldError with status >= 500: server error, will succeed later
179
- */
180
- function isRetryableStartError(err) {
181
- if (ThrottleError.is(err))
182
- return true;
183
- if (WorkflowWorldError.is(err) && err.status && err.status >= 500)
184
- return true;
185
- return false;
186
- }
187
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVudGltZS9zdGFydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixhQUFhLEVBQ2Isb0JBQW9CLEVBQ3BCLGtCQUFrQixHQUNuQixNQUFNLGtCQUFrQixDQUFDO0FBRTFCLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsMENBQTBDLEVBQzFDLG9DQUFvQyxHQUNyQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN4QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUU3QyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRSxPQUFPLEtBQUssU0FBUyxNQUFNLHNDQUFzQyxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxPQUFPLElBQUksbUJBQW1CLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0QsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3BELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDL0IsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUV0QyxzREFBc0Q7QUFDdEQsTUFBTSxJQUFJLEdBQUcsZ0JBQWdCLEVBQUUsQ0FBQztBQXlGaEMsTUFBTSxDQUFDLEtBQUssVUFBVSxLQUFLLENBQ3pCLFFBQTZELEVBQzdELGFBQW9DLEVB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QyxNQUFNLElBQUksR0FBRyxDQUFDLE1BQU0sSUFBSSxHQUFHO1FBQy9ELE9BQU8sSUFBSSxDQUFDO0lBQ2QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgd2FpdFVudGlsIH0gZnJvbSAnQHZlcmNlbC9mdW5jdGlvbnMnO1xuaW1wb3J0IHtcbiAgRW50aXR5Q29uZmxpY3RFcnJvcixcbiAgVGhyb3R0bGVFcnJvcixcbiAgV29ya2Zsb3dSdW50aW1lRXJyb3IsXG4gIFdvcmtmbG93V29ybGRFcnJvcixcbn0gZnJvbSAnQHdvcmtmbG93L2Vycm9ycyc7XG5pbXBvcnQgdHlwZSB7IFdvcmtmbG93SW52b2tlUGF5bG9hZCwgV29ybGQgfSBmcm9tICdAd29ya2Zsb3cvd29ybGQnO1xuaW1wb3J0IHtcbiAgaXNMZWdhY3lTcGVjVmVyc2lvbixcbiAgU1BFQ19WRVJTSU9OX1NVUFBPUlRTX0NCT1JfUVVFVUVfVFJBTlNQT1JULFxuICBTUEVDX1ZFUlNJT05fU1VQUE9SVFNfRVZFTlRfU09VUkNJTkcsXG59IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgeyBtb25vdG9uaWNGYWN0b3J5IH0gZnJvbSAndWxpZCc7XG5pbXBvcnQgeyBpbXBvcnRLZXkgfSBmcm9tICcuLi9lbmNyeXB0aW9uLmpzJztcbmltcG9ydCB7IHJ1bnRpbWVMb2dnZXIgfSBmcm9tICcuLi9sb2dnZXIuanMnO1xuaW1wb3J0IHR5cGUgeyBTZXJpYWxpemFibGUgfSBmcm9tICcuLi9zY2hlbWFzLmpzJztcbmltcG9ydCB7IGRlaHlkcmF0ZVdvcmtmbG93QXJndW1lbnRzIH0gZnJvbSAnLi4vc2VyaWFsaXphdGlvbi5qcyc7XG5pbXBvcnQgKiBhcyBBdHRyaWJ1dGUgZnJvbSAnLi4vdGVsZW1ldHJ5L3NlbWFudGljLWNvbnZlbnRpb25zLmpzJztcbmltcG9ydCB7IHNlcmlhbGl6ZVRyYWNlQ2FycmllciwgdHJhY2UgfSBmcm9tICcuLi90ZWxlbWV0cnkuanMnO1xuaW1wb3J0IHsgd2FpdGVkVW50aWwgfSBmcm9tICcuLi91dGlsLmpzJztcbmltcG9ydCB7IHZlcnNpb24gYXMgd29ya2Zsb3dDb3JlVmVyc2lvbiB9IGZyb20gJy4uL3ZlcnNpb24uanMnO1xuaW1wb3J0IHsgZ2V0V29ya2Zsb3dRdWV1ZU5hbWUgfSBmcm9tICcuL2hlbHBlcnMuanMnO1xuaW1wb3J0IHsgUnVuIH0gZnJvbSAnLi9ydW4uanMnO1xuaW1wb3J0IHsgZ2V0V29ybGQgfSBmcm9tICcuL3dvcmxkLmpzJztcblxuLyoqIFVMSUQgZ2VuZXJhdG9yIGZvciBjbGllbnQtc2lkZSBydW5JZCBnZW5lcmF0aW9uICovXG5jb25zdCB1bGlkID0gbW9ub3RvbmljRmFjdG9yeSgpO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXJ0T3B0aW9uc0Jhc2Uge1xuICAvKipcbiAgICogVGhlIHdvcmxkIHRvIHVzZSBmb3IgdGhlIHdvcmtmbG93IHJ1biBjcmVhdGlvbixcbiAgICogYnkgZGVmYXVsdCB0aGUgd29ybGQgaXMgaW5mZXJyZWQgZnJvbSB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGVzLlxuICAgKi9cbiAgd29ybGQ/OiBXb3JsZDtcblxuICAvKipcbiAgICogVGhlIHNwZWMgdmVyc2lvbiB0byB1c2UgZm9yIHRoZSB3b3JrZmxvdyBydW4uIERlZmF1bHRzIHRvIHRoZSBsYXRlc3QgdmVyc2lvbi5cbiAgICovXG4gIHNwZWNWZXJzaW9uPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXJ0T3B0aW9uc1dpdGhEZXBsb3ltZW50SWQgZXh0ZW5kcyBTdGFydE9wdGlvbnNCYXNlIHtcbiAgLyoqXG4gICAqIFRoZSBkZXBsb3ltZW50IElEIHRvIHVzZSBmb3IgdGhlIHdvcmtmbG93IHJ1bi5cbiAgICpcbiAgICogQnkgZGVmYXVsdCwgdGhpcyBpcyBhdXRvbWF0aWNhbGx5IGluZmVycmVkIGZyb20gZW52aXJvbm1lbnQgdmFyaWFibGVzXG4gICAqIHdoZW4gZGVwbG95aW5nIHRvIFZlcmNlbC5cbiAgICpcbiAgICogU2V0IHRvIGAnbGF0ZXN0J2AgdG8gYXV0b21hdGljYWxseSByZXNvbHZlIHRoZSBtb3N0IHJlY2VudCBkZXBsb3ltZW50XG4gICAqIGZvciB0aGUgY3VycmVudCBlbnZpcm9ubWVudCAoc2FtZSBwcm9kdWN0aW9uIHRhcmdldCBvciBnaXQgYnJhbmNoKS5cbiAgICogVGhpcyBpcyBjdXJyZW50bHkgYSBWZXJjZWwtc3BlY2lmaWMgZmVhdHVyZS5cbiAgICpcbiAgICogKipOb3RlOioqIFdoZW4gYGRlcGxveW1lbnRJZGAgaXMgcHJvdmlkZWQsIHRoZSBhcmd1bWVudCBhbmQgcmV0dXJuIHR5cGVzIGJlY29tZSBgdW5rbm93bmBcbiAgICogc2luY2UgdGhlcmUgaXMgbm8gZ3VhcmFudGVlIHRoZSB0eXBlcyB3aWxsIGJlIGNvbnNpc3RlbnQgYWNyb3NzIGRlcGxveW1lbnRzLlxuICAgKi9cbiAgZGVwbG95bWVudElkOiAnbGF0ZXN0JyB8IChzdHJpbmcgJiB7fSk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhcnRPcHRpb25zV2l0aG91dERlcGxveW1lbnRJZCBleHRlbmRzIFN0YXJ0T3B0aW9uc0Jhc2Uge1xuICBkZXBsb3ltZW50SWQ/OiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3Igc3RhcnRpbmcgYSB3b3JrZmxvdyBydW4uXG4gKi9cbmV4cG9ydCB0eXBlIFN0YXJ0T3B0aW9ucyA9XG4gIHwgU3RhcnRPcHRpb25zV2l0aERlcGxveW1lbnRJZFxuICB8IFN0YXJ0T3B0aW9uc1dpdGhvdXREZXBsb3ltZW50SWQ7XG5cbi8qKlxuICogUmVwcmVzZW50cyBhbiBpbXBvcnRlZCB3b3JrZmxvdyBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IHR5cGUgV29ya2Zsb3dGdW5jdGlvbjxUQXJncyBleHRlbmRzIHVua25vd25bXSwgVFJlc3VsdD4gPSAoXG4gIC4uLmFyZ3M6IFRBcmdzXG4pID0+IFByb21pc2U8VFJlc3VsdD47XG5cbi8qKlxuICogUmVwcmVzZW50cyB0aGUgZ2VuZXJhdGVkIG1ldGFkYXRhIG9mIGEgd29ya2Zsb3cgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCB0eXBlIFdvcmtmbG93TWV0YWRhdGEgPSB7IHdvcmtmbG93SWQ6IHN0cmluZyB9O1xuXG4vKipcbiAqIFN0YXJ0cyBhIHdvcmtmbG93IHJ1bi5cbiAqXG4gKiBAcGFyYW0gd29ya2Zsb3cgLSBUaGUgaW1wb3J0ZWQgd29ya2Zsb3cgZnVuY3Rpb24gdG8gc3RhcnQuXG4gKiBAcGFyYW0gYXJncyAtIFRoZSBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgd29ya2Zsb3cgKG9wdGlvbmFsKS5cbiAqIEBwYXJhbSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgZm9yIHRoZSB3b3JrZmxvdyBydW4gKG9wdGlvbmFsKS5cbiAqIEByZXR1cm5zIFRoZSB1bmlxdWUgcnVuIElEIGZvciB0aGUgbmV3bHkgc3RhcnRlZCB3b3JrZmxvdyBpbnZvY2F0aW9uLlxuICovXG4vLyBPdmVybG9hZHMgd2l0aCBkZXBsb3ltZW50SWQgLSBhcmdzIGFuZCByZXR1cm4gdHlwZSBiZWNvbWUgdW5rbm93blxuLy8gVXNlcyBnZW5lcmljcyBzbyB0eXBlZCB3b3JrZmxvd3MgYXJlIGFzc2lnbmFibGUgKGF2b2lkcyBjb250cmF2YXJpYW5jZSBpc3N1ZXMpLFxuLy8gYnV0IHRoZSByZXR1cm4gdHlwZSBhbmQgYXJncyBhcmUgc3RpbGwgdW5rbm93biBzaW5jZSB0aGUgZGVwbG95ZWQgdmVyc2lvbiBtYXkgZGlmZmVyLlxuZXhwb3J0IGZ1bmN0aW9uIHN0YXJ0PFRBcmdzIGV4dGVuZHMgdW5rbm93bltdLCBUUmVzdWx0PihcbiAgd29ya2Zsb3c6IFdvcmtmbG93RnVuY3Rpb248VEFyZ3MsIFRSZXN1bHQ+IHwgV29ya2Zsb3dNZXRhZGF0YSxcbiAgYXJnczogdW5rbm93bltdLFxuICBvcHRpb25zOiBTdGFydE9wdGlvbnNXaXRoRGVwbG95bWVudElkXG4pOiBQcm9taXNlPFJ1bjx1bmtub3duPj47XG5cbmV4cG9ydCBmdW5jdGlvbiBzdGFydDxUUmVzdWx0PihcbiAgd29ya2Zsb3c6IFdvcmtmbG93RnVuY3Rpb248W10sIFRSZXN1bHQ+IHwgV29ya2Zsb3dNZXRhZGF0YSxcbiAgb3B0aW9uczogU3RhcnRPcHRpb25zV2l0aERlcGxveW1lbnRJZFxuKTogUHJvbWlzZTxSdW48dW5rbm93bj4+O1xuXG4vLyBPdmVybG9hZHMgd2l0aG91dCBkZXBsb3ltZW50SWQgLSBwcmVzZXJ2ZSB0eXBlIGluZmVyZW5jZVxuZXhwb3J0IGZ1bmN0aW9uIHN0YXJ0PFRBcmdzIGV4dGVuZHMgdW5rbm93bltdLCBUUmVzdWx0PihcbiAgd29ya2Zsb3c6IFdvcmtmbG93RnVuY3Rpb248VEFyZ3MsIFRSZXN1bHQ+IHwgV29ya2Zsb3dNZXRhZGF0YSxcbiAgYXJnczogVEFyZ3MsXG4gIG9wdGlvbnM/OiBTdGFydE9wdGlvbnNXaXRob3V0RGVwbG95bWVudElkXG4pOiBQcm9taXNlPFJ1bjxUUmVzdWx0Pj47XG5cbmV4cG9ydCBmdW5jdGlvbiBzdGFydDxUUmVzdWx0PihcbiAgd29ya2Zsb3c6IFdvcmtmbG93RnVuY3Rpb248W10sIFRSZXN1bHQ+IHwgV29ya2Zsb3dNZXRhZGF0YSxcbiAgb3B0aW9ucz86IFN0YXJ0T3B0aW9uc1dpdGhvdXREZXBsb3ltZW50SWRcbik6IFByb21pc2U8UnVuPFRSZXN1bHQ+PjtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN0YXJ0PFRBcmdzIGV4dGVuZHMgdW5rbm93bltdLCBUUmVzdWx0PihcbiAgd29ya2Zsb3c6IFdvcmtmbG93RnVuY3Rpb248VEFyZ3MsIFRSZXN1bHQ+IHwgV29ya2Zsb3dNZXRhZGF0YSxcbiAgYXJnc09yT3B0aW9ucz86IFRBcmdzIHwgU3RhcnRPcHRpb25zLFxuICBvcHRpb25zPzogU3RhcnRPcHRpb25zXG4pIHtcbiAgJ3VzZSBzdGVwJztcbiAgcmV0dXJuIGF3YWl0IHdhaXRlZFVudGlsKCgpID0+IHtcbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIHRoaXMgZmllbGQgaXMgYWRkZWQgYnkgb3VyIGNsaWVudCB0cmFuc2Zvcm1cbiAgICBjb25zdCB3b3JrZmxvd05hbWUgPSB3b3JrZmxvdz8ud29ya2Zsb3dJZDtcblxuICAgIGlmICghd29ya2Zsb3dOYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IoXG4gICAgICAgIGAnc3RhcnQnIHJlY2VpdmVkIGFuIGludmFsaWQgd29ya2Zsb3cgZnVuY3Rpb24uIEVuc3VyZSB0aGUgV29ya2Zsb3cgU0RLIGlzIGNvbmZpZ3VyZWQgY29ycmVjdGx5IGFuZCB0aGUgZnVuY3Rpb24gaW5jbHVkZXMgYSAndXNlIHdvcmtmbG93JyBkaXJlY3RpdmUuYCxcbiAgICAgICAgeyBzbHVnOiAnc3RhcnQtaW52YWxpZC13b3JrZmxvdy1mdW5jdGlvbicgfVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJhY2UoYHdvcmtmbG93LnN0YXJ0ICR7d29ya2Zsb3dOYW1lfWAsIGFzeW5jIChzcGFuKSA9PiB7XG4gICAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93TmFtZSh3b3JrZmxvd05hbWUpLFxuICAgICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dPcGVyYXRpb24oJ3N0YXJ0JyksXG4gICAgICB9KTtcblxuICAgICAgbGV0IGFyZ3M6IFNlcmlhbGl6YWJsZVtdID0gW107XG4gICAgICBsZXQgb3B0czogU3RhcnRPcHRpb25zID0gb3B0aW9ucyA/PyB7fTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGFyZ3NPck9wdGlvbnMpKSB7XG4gICAgICAgIGFyZ3MgPSBhcmdzT3JPcHRpb25zIGFzIFNlcmlhbGl6YWJsZVtdO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnc09yT3B0aW9ucyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgb3B0cyA9IGFyZ3NPck9wdGlvbnM7XG4gICAgICB9XG5cbiAgICAgIHNwYW4/LnNldEF0dHJpYnV0ZXMoe1xuICAgICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dBcmd1bWVudHNDb3VudChhcmdzLmxlbmd0aCksXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgd29ybGQgPSBvcHRzPy53b3JsZCA/PyAoYXdhaXQgZ2V0V29ybGQoKSk7XG4gICAgICBsZXQgZGVwbG95bWVudElkID0gb3B0cy5kZXBsb3ltZW50SWQgPz8gKGF3YWl0IHdvcmxkLmdldERlcGxveW1lbnRJZCgpKTtcblxuICAgICAgLy8gV2hlbiAnbGF0ZXN0JyBpcyByZXF1ZXN0ZWQsIHJlc29sdmUgdGhlIGFjdHVhbCBsYXRlc3QgZGVwbG95bWVudCBJRFxuICAgICAgLy8gZm9yIHRoZSBjdXJyZW50IGRlcGxveW1lbnQncyBlbnZpcm9ubWVudCAoc2FtZSBwcm9kdWN0aW9uIHRhcmdldCBvclxuICAgICAgLy8gc2FtZSBnaXQgYnJhbmNoIGZvciBwcmV2aWV3IGRlcGxveW1lbnRzKS5cbiAgICAgIGlmIChkZXBsb3ltZW50SWQgPT09ICdsYXRlc3QnKSB7XG4gICAgICAgIGlmICghd29ybGQucmVzb2x2ZUxhdGVzdERlcGxveW1lbnRJZCkge1xuICAgICAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcihcbiAgICAgICAgICAgIFwiZGVwbG95bWVudElkICdsYXRlc3QnIHJlcXVpcmVzIGEgV29ybGQgdGhhdCBpbXBsZW1lbnRzIHJlc29sdmVMYXRlc3REZXBsb3ltZW50SWQoKVwiXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBkZXBsb3ltZW50SWQgPSBhd2FpdCB3b3JsZC5yZXNvbHZlTGF0ZXN0RGVwbG95bWVudElkKCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG9wczogUHJvbWlzZTx2b2lkPltdID0gW107XG5cbiAgICAgIC8vIEdlbmVyYXRlIHJ1bklkIGNsaWVudC1zaWRlIHNvIHdlIGhhdmUgaXQgYmVmb3JlIHNlcmlhbGl6YXRpb25cbiAgICAgIC8vIChyZXF1aXJlZCBmb3IgZnV0dXJlIEUyRSBlbmNyeXB0aW9uIHdoZXJlIHJ1bklkIGlzIHBhcnQgb2YgdGhlIGVuY3J5cHRpb24gY29udGV4dClcbiAgICAgIGNvbnN0IHJ1bklkID0gYHdydW5fJHt1bGlkKCl9YDtcblxuICAgICAgLy8gU2VyaWFsaXplIGN1cnJlbnQgdHJhY2UgY29udGV4dCB0byBwcm9wYWdhdGUgYWNyb3NzIHF1ZXVlIGJvdW5kYXJ5XG4gICAgICBjb25zdCB0cmFjZUNhcnJpZXIgPSBhd2FpdCBzZXJpYWxpemVUcmFjZUNhcnJpZXIoKTtcblxuICAgICAgLy8gVXNlIHdvcmxkLWRlY2xhcmVkIHNwZWNWZXJzaW9uIHdoZW4gYXZhaWxhYmxlIChvdXIgd29ybGRzIHNldCB0aGlzKSxcbiAgICAgIC8vIG90aGVyd2lzZSBmYWxsIGJhY2sgdG8gdGhlIHNhZmUgYmFzZWxpbmUgdGhhdCBjb21tdW5pdHkgd29ybGRzIGhhbmRsZS5cbiAgICAgIC8vIENvbW11bml0eSB3b3JsZHMgYnVpbHQgYWdhaW5zdCBvbGRlciBAd29ya2Zsb3cvd29ybGQgcmVqZWN0IHJ1bnMgd2l0aFxuICAgICAgLy8gc3BlY1ZlcnNpb24gPiB0aGVpciBTUEVDX1ZFUlNJT05fQ1VSUkVOVCB2aWEgcmVxdWlyZXNOZXdlcldvcmxkKCkuXG4gICAgICBjb25zdCBzcGVjVmVyc2lvbiA9XG4gICAgICAgIG9wdHMuc3BlY1ZlcnNpb24gPz9cbiAgICAgICAgd29ybGQuc3BlY1ZlcnNpb24gPz9cbiAgICAgICAgU1BFQ19WRVJTSU9OX1NVUFBPUlRTX0VWRU5UX1NPVVJDSU5HO1xuICAgICAgY29uc3QgdjFDb21wYXQgPSBpc0xlZ2FjeVNwZWNWZXJzaW9uKHNwZWNWZXJzaW9uKTtcblxuICAgICAgLy8gUmVzb2x2ZSBlbmNyeXB0aW9uIGtleSBmb3IgdGhlIG5ldyBydW4uIFRoZSBydW5JZCBoYXMgYWxyZWFkeSBiZWVuXG4gICAgICAvLyBnZW5lcmF0ZWQgYWJvdmUgKGNsaWVudC1nZW5lcmF0ZWQgVUxJRCkgYW5kIHdpbGwgYmUgdXNlZCBmb3IgYm90aFxuICAgICAgLy8ga2V5IGRlcml2YXRpb24gYW5kIHRoZSBydW5fY3JlYXRlZCBldmVudC4gVGhlIFdvcmxkIGltcGxlbWVudGF0aW9uXG4gICAgICAvLyB1c2VzIHRoZSBydW5JZCBmb3IgcGVyLXJ1biBIS0RGIGtleSBkZXJpdmF0aW9uLiBXZSBwYXNzIHRoZSByZXNvbHZlZFxuICAgICAgLy8gZGVwbG95bWVudElkIChub3QganVzdCB0aGUgcmF3IG9wdHMpIHNvIHRoZSBXb3JsZCBjYW4gdXNlIGl0IGZvclxuICAgICAgLy8ga2V5IHJlc29sdXRpb24gZXZlbiB3aGVuIGRlcGxveW1lbnRJZCB3YXMgaW5mZXJyZWQgZnJvbSB0aGUgZW52aXJvbm1lbnRcbiAgICAgIC8vIHJhdGhlciB0aGFuIGV4cGxpY2l0bHkgcHJvdmlkZWQgaW4gb3B0cyAoZS5nLiwgaW4gZTJlIHRlc3QgcnVubmVycykuXG4gICAgICBjb25zdCByYXdLZXkgPSBhd2FpdCB3b3JsZC5nZXRFbmNyeXB0aW9uS2V5Rm9yUnVuPy4ocnVuSWQsIHtcbiAgICAgICAgLi4ub3B0cyxcbiAgICAgICAgZGVwbG95bWVudElkLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBlbmNyeXB0aW9uS2V5ID0gcmF3S2V5ID8gYXdhaXQgaW1wb3J0S2V5KHJhd0tleSkgOiB1bmRlZmluZWQ7XG5cbiAgICAgIC8vIENyZWF0ZSBydW4gdmlhIHJ1bl9jcmVhdGVkIGV2ZW50IChldmVudC1zb3VyY2VkIGFyY2hpdGVjdHVyZSlcbiAgICAgIC8vIFBhc3MgY2xpZW50LWdlbmVyYXRlZCBydW5JZCAtIHNlcnZlciB3aWxsIGFjY2VwdCBhbmQgdXNlIGl0XG4gICAgICBjb25zdCB3b3JrZmxvd0FyZ3VtZW50cyA9IGF3YWl0IGRlaHlkcmF0ZVdvcmtmbG93QXJndW1lbnRzKFxuICAgICAgICBhcmdzLFxuICAgICAgICBydW5JZCxcbiAgICAgICAgZW5jcnlwdGlvbktleSxcbiAgICAgICAgb3BzLFxuICAgICAgICBnbG9iYWxUaGlzLFxuICAgICAgICB2MUNvbXBhdFxuICAgICAgKTtcblxuICAgICAgY29uc3QgZXhlY3V0aW9uQ29udGV4dCA9IHtcbiAgICAgICAgdHJhY2VDYXJyaWVyLFxuICAgICAgICB3b3JrZmxvd0NvcmVWZXJzaW9uLFxuICAgICAgICBmZWF0dXJlczogeyBlbmNyeXB0aW9uOiAhIWVuY3J5cHRpb25LZXkgfSxcbiAgICAgIH07XG5cbiAgICAgIC8vIENhbGwgZXZlbnRzLmNyZWF0ZSAocnVuX2NyZWF0ZWQpIGFuZCBxdWV1ZSBpbiBwYXJhbGxlbC5cbiAgICAgIC8vIElmIGV2ZW50cy5jcmVhdGUgZmFpbHMgd2l0aCA0MjkvNXh4LCB0aGUgcnVuIHdhcyBzdGlsbCBhY2NlcHRlZFxuICAgICAgLy8gdmlhIHRoZSBxdWV1ZSBhbmQgY3JlYXRpb24gd2lsbCBiZSByZS10cmllZCBhc3luYyBieSB0aGUgcnVudGltZS5cbiAgICAgIGNvbnN0IFtydW5DcmVhdGVkUmVzdWx0LCBxdWV1ZVJlc3VsdF0gPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoW1xuICAgICAgICB3b3JsZC5ldmVudHMuY3JlYXRlKFxuICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGV2ZW50VHlwZTogJ3J1bl9jcmVhdGVkJyxcbiAgICAgICAgICAgIHNwZWNWZXJzaW9uLFxuICAgICAgICAgICAgZXZlbnREYXRhOiB7XG4gICAgICAgICAgICAgIGRlcGxveW1lbnRJZDogZGVwbG95bWVudElkLFxuICAgICAgICAgICAgICB3b3JrZmxvd05hbWU6IHdvcmtmbG93TmFtZSxcbiAgICAgICAgICAgICAgaW5wdXQ6IHdvcmtmbG93QXJndW1lbnRzLFxuICAgICAgICAgICAgICBleGVjdXRpb25Db250ZXh0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgdjFDb21wYXQgfVxuICAgICAgICApLFxuICAgICAgICB3b3JsZC5xdWV1ZShcbiAgICAgICAgICBnZXRXb3JrZmxvd1F1ZXVlTmFtZSh3b3JrZmxvd05hbWUpLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgdHJhY2VDYXJyaWVyLFxuICAgICAgICAgICAgLi4uKHNwZWNWZXJzaW9uID49IFNQRUNfVkVSU0lPTl9TVVBQT1JUU19DQk9SX1FVRVVFX1RSQU5TUE9SVFxuICAgICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICAgIHJ1bklucHV0OiB7XG4gICAgICAgICAgICAgICAgICAgIGlucHV0OiB3b3JrZmxvd0FyZ3VtZW50cyxcbiAgICAgICAgICAgICAgICAgICAgZGVwbG95bWVudElkLFxuICAgICAgICAgICAgICAgICAgICB3b3JrZmxvd05hbWUsXG4gICAgICAgICAgICAgICAgICAgIHNwZWNWZXJzaW9uLFxuICAgICAgICAgICAgICAgICAgICBleGVjdXRpb25Db250ZXh0LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgIH0gc2F0aXNmaWVzIFdvcmtmbG93SW52b2tlUGF5bG9hZCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkZXBsb3ltZW50SWQsXG4gICAgICAgICAgICBzcGVjVmVyc2lvbixcbiAgICAgICAgICB9XG4gICAgICAgICksXG4gICAgICBdKTtcblxuICAgICAgLy8gUXVldWUgZmFpbHVyZSBpcyBhbHdheXMgZmF0YWwg4oCUIHRoZSBydW4gd2FzIG5vdCBlbnF1ZXVlZFxuICAgICAgaWYgKHF1ZXVlUmVzdWx0LnN0YXR1cyA9PT0gJ3JlamVjdGVkJykge1xuICAgICAgICB0aHJvdyBxdWV1ZVJlc3VsdC5yZWFzb247XG4gICAgICB9XG5cbiAgICAgIC8vIEhhbmRsZSBldmVudHMuY3JlYXRlIHJlc3VsdFxuICAgICAgbGV0IHJlc2lsaWVudFN0YXJ0ID0gZmFsc2U7XG4gICAgICBpZiAocnVuQ3JlYXRlZFJlc3VsdC5zdGF0dXMgPT09ICdyZWplY3RlZCcpIHtcbiAgICAgICAgY29uc3QgZXJyID0gcnVuQ3JlYXRlZFJlc3VsdC5yZWFzb247XG4gICAgICAgIGlmIChFbnRpdHlDb25mbGljdEVycm9yLmlzKGVycikpIHtcbiAgICAgICAgICAvLyA0MDk6IFRoZSBydW4gYWxyZWFkeSBleGlzdHMuIFRoaXMgY2FuIGhhcHBlbiBpbiBleHRyZW1lIGNhc2VzIHdoZXJlXG4gICAgICAgICAgLy8gdGhlIHJ1biBjcmVhdGlvbiBjYWxsIGdldHMgYSBjb2xkIHN0YXJ0IG9yIG90aGVyIHNsb3dkb3duLCBhbmQgdGhlIHF1ZXVlXG4gICAgICAgICAgLy8gKyBydW5fc3RhcnRlZCBjYWxsIGNvbXBsZXRlcyBmYXN0ZXIuIFdlIGV4cGVjdCB0aGlzIHRvIGJlIDw9MSUgb2YgY2FzZXMuXG4gICAgICAgICAgLy8gSW4gdGhpcyBjYXNlLCB3ZSBjYW4gc2FmZWx5IHJldHVybi5cbiAgICAgICAgfSBlbHNlIGlmIChpc1JldHJ5YWJsZVN0YXJ0RXJyb3IoZXJyKSkge1xuICAgICAgICAgIC8vIDQyOSAoVGhyb3R0bGVFcnJvcikgYW5kIDV4eCAoV29ya2Zsb3dXb3JsZEVycm9yIHdpdGggc3RhdHVzID49IDUwMClcbiAgICAgICAgICAvLyBhcmUgcmV0cnlhYmxlIOKAlCB0aGUgcnVuIHdhcyBhY2NlcHRlZCB2aWEgdGhlIHF1ZXVlIGFuZCBjcmVhdGlvblxuICAgICAgICAgIC8vIHdpbGwgYmUgcmUtdHJpZWQgYnkgdGhlIHJ1bnRpbWUgd2hlbiBpdCBjYWxscyBydW5fc3RhcnRlZC5cbiAgICAgICAgICByZXNpbGllbnRTdGFydCA9IHRydWU7XG4gICAgICAgICAgcnVudGltZUxvZ2dlci53YXJuKFxuICAgICAgICAgICAgJ1J1biBjcmVhdGlvbiBldmVudCBmYWlsZWQsIGJ1dCB0aGUgcnVuIHdhcyBhY2NlcHRlZCB2aWEgdGhlIHF1ZXVlLiAnICtcbiAgICAgICAgICAgICAgJ1RoZSBydW5fY3JlYXRlZCBldmVudCB3aWxsIGJlIHJlLXRyaWVkIGFzeW5jIGJ5IHRoZSBydW50aW1lLicsXG4gICAgICAgICAgICB7IHdvcmtmbG93UnVuSWQ6IHJ1bklkLCBlcnJvcjogZXJyLm1lc3NhZ2UgfVxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBydW5DcmVhdGVkUmVzdWx0LnZhbHVlO1xuICAgICAgICAvLyBBc3NlcnQgdGhhdCB0aGUgcnVuIHdhcyBjcmVhdGVkXG4gICAgICAgIGlmICghcmVzdWx0LnJ1bikge1xuICAgICAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcihcbiAgICAgICAgICAgIFwiTWlzc2luZyAncnVuJyBpbiBzZXJ2ZXIgcmVzcG9uc2UgZm9yICdydW5fY3JlYXRlZCcgZXZlbnRcIlxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBWZXJpZnkgc2VydmVyIGFjY2VwdGVkIG91ciBydW5JZFxuICAgICAgICBpZiAoIXYxQ29tcGF0ICYmIHJlc3VsdC5ydW4ucnVuSWQgIT09IHJ1bklkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKFxuICAgICAgICAgICAgYFNlcnZlciByZXR1cm5lZCBkaWZmZXJlbnQgcnVuSWQgdGhhbiByZXF1ZXN0ZWQ6IGV4cGVjdGVkICR7cnVuSWR9LCBnb3QgJHtyZXN1bHQucnVuLnJ1bklkfWBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHdhaXRVbnRpbChcbiAgICAgICAgUHJvbWlzZS5hbGwob3BzKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgLy8gSWdub3JlIGV4cGVjdGVkIGNsaWVudCBkaXNjb25uZWN0IGVycm9ycyAoZS5nLiwgYnJvd3NlciByZWZyZXNoIGR1cmluZyBzdHJlYW1pbmcpXG4gICAgICAgICAgY29uc3QgaXNBYm9ydEVycm9yID1cbiAgICAgICAgICAgIGVycj8ubmFtZSA9PT0gJ0Fib3J0RXJyb3InIHx8IGVycj8ubmFtZSA9PT0gJ1Jlc3BvbnNlQWJvcnRlZCc7XG4gICAgICAgICAgaWYgKCFpc0Fib3J0RXJyb3IpIHRocm93IGVycjtcbiAgICAgICAgfSlcbiAgICAgICk7XG5cbiAgICAgIHNwYW4/LnNldEF0dHJpYnV0ZXMoe1xuICAgICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dSdW5JZChydW5JZCksXG4gICAgICAgIC4uLkF0dHJpYnV0ZS5EZXBsb3ltZW50SWQoZGVwbG95bWVudElkKSxcbiAgICAgICAgLi4uKHJ1bkNyZWF0ZWRSZXN1bHQuc3RhdHVzID09PSAnZnVsZmlsbGVkJyAmJlxuICAgICAgICBydW5DcmVhdGVkUmVzdWx0LnZhbHVlLnJ1blxuICAgICAgICAgID8gQXR0cmlidXRlLldvcmtmbG93UnVuU3RhdHVzKHJ1bkNyZWF0ZWRSZXN1bHQudmFsdWUucnVuLnN0YXR1cylcbiAgICAgICAgICA6IHt9KSxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gbmV3IFJ1bjxUUmVzdWx0PihydW5JZCwgeyByZXNpbGllbnRTdGFydCB9KTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGFuIGVycm9yIGZyb20gZXZlbnRzLmNyZWF0ZSAocnVuX2NyZWF0ZWQpIGlzIHJldHJ5YWJsZSxcbiAqIG1lYW5pbmcgdGhlIHF1ZXVlIGNhbiByZS10cnkgY3JlYXRpb24gbGF0ZXIgdmlhIHRoZSBydW5fc3RhcnRlZCBwYXRoLlxuICogLSBUaHJvdHRsZUVycm9yICg0MjkpOiByYXRlIGxpbWl0ZWQsIHdpbGwgc3VjY2VlZCBsYXRlclxuICogLSBXb3JrZmxvd1dvcmxkRXJyb3Igd2l0aCBzdGF0dXMgPj0gNTAwOiBzZXJ2ZXIgZXJyb3IsIHdpbGwgc3VjY2VlZCBsYXRlclxuICovXG5mdW5jdGlvbiBpc1JldHJ5YWJsZVN0YXJ0RXJyb3IoZXJyOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIGlmIChUaHJvdHRsZUVycm9yLmlzKGVycikpIHJldHVybiB0cnVlO1xuICBpZiAoV29ya2Zsb3dXb3JsZEVycm9yLmlzKGVycikgJiYgZXJyLnN0YXR1cyAmJiBlcnIuc3RhdHVzID49IDUwMClcbiAgICByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuIGZhbHNlO1xufVxuIl19
301
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVudGltZS9zdGFydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM3RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUVqRSxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLGdDQUFnQyxFQUNoQywwQ0FBMEMsRUFDMUMsaUNBQWlDLEVBQ2pDLG1CQUFtQixHQUNwQixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN4QyxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUU3QyxPQUFPLEVBQ0wsMEJBQTBCLEVBQzFCLG1CQUFtQixHQUNwQixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sS0FBSyxTQUFTLE1BQU0sc0NBQXNDLENBQUM7QUFDbEUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9ELE9BQU8sRUFBRSxPQUFPLElBQUksbUJBQW1CLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0QsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxXQUFXLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDakUsT0FBTyxFQUFFLEdBQUcsRUFBRSxN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O1lBRUgsSUFBSSxFQUFFLGFBQWEsQ0FBQztnQkFDbEIsR0FBRyxTQUFTLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQztnQkFDakMsR0FBRyxTQUFTLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQztnQkFDdkMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxXQUFXO29CQUMzQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsR0FBRztvQkFDeEIsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQztvQkFDaEUsQ0FBQyxDQUFDLEVBQUUsQ0FBQzthQUNSLENBQUMsQ0FBQztZQUVILE9BQU8sSUFBSSxHQUFHLENBQVUsS0FBSyxFQUFFLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQztRQUNyRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEVudGl0eUNvbmZsaWN0RXJyb3IsIFdvcmtmbG93UnVudGltZUVycm9yIH0gZnJvbSAnQHdvcmtmbG93L2Vycm9ycyc7XG5pbXBvcnQgeyB3b3JrZmxvd0Rpc3BsYXlOYW1lIH0gZnJvbSAnQHdvcmtmbG93L3V0aWxzL3BhcnNlLW5hbWUnO1xuaW1wb3J0IHR5cGUgeyBXb3JrZmxvd0ludm9rZVBheWxvYWQsIFdvcmxkIH0gZnJvbSAnQHdvcmtmbG93L3dvcmxkJztcbmltcG9ydCB7XG4gIGlzTGVnYWN5U3BlY1ZlcnNpb24sXG4gIFNQRUNfVkVSU0lPTl9TVVBQT1JUU19BVFRSSUJVVEVTLFxuICBTUEVDX1ZFUlNJT05fU1VQUE9SVFNfQ0JPUl9RVUVVRV9UUkFOU1BPUlQsXG4gIFNQRUNfVkVSU0lPTl9TVVBQT1JUU19DT01QUkVTU0lPTixcbiAgd29ya2Zsb3dSdW5JZFNjaGVtYSxcbn0gZnJvbSAnQHdvcmtmbG93L3dvcmxkJztcbmltcG9ydCB7IG1vbm90b25pY0ZhY3RvcnkgfSBmcm9tICd1bGlkJztcbmltcG9ydCB7IG5vcm1hbGl6ZUF0dHJpYnV0ZUNoYW5nZXMgfSBmcm9tICcuLi9hdHRyaWJ1dGUtY2hhbmdlcy5qcyc7XG5pbXBvcnQgeyBnZXRSdW5DYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9jYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgaXNSZXRyeWFibGVXb3JsZEVycm9yIH0gZnJvbSAnLi4vY2xhc3NpZnktZXJyb3IuanMnO1xuaW1wb3J0IHsgaW1wb3J0S2V5IH0gZnJvbSAnLi4vZW5jcnlwdGlvbi5qcyc7XG5pbXBvcnQgeyBydW50aW1lTG9nZ2VyIH0gZnJvbSAnLi4vbG9nZ2VyLmpzJztcbmltcG9ydCB0eXBlIHsgU2VyaWFsaXphYmxlIH0gZnJvbSAnLi4vc2NoZW1hcy5qcyc7XG5pbXBvcnQge1xuICBkZWh5ZHJhdGVXb3JrZmxvd0FyZ3VtZW50cyxcbiAgU2VyaWFsaXphdGlvbkZvcm1hdCxcbn0gZnJvbSAnLi4vc2VyaWFsaXphdGlvbi5qcyc7XG5pbXBvcnQgKiBhcyBBdHRyaWJ1dGUgZnJvbSAnLi4vdGVsZW1ldHJ5L3NlbWFudGljLWNvbnZlbnRpb25zLmpzJztcbmltcG9ydCB7IHNlcmlhbGl6ZVRyYWNlQ2FycmllciwgdHJhY2UgfSBmcm9tICcuLi90ZWxlbWV0cnkuanMnO1xuaW1wb3J0IHsgdmVyc2lvbiBhcyB3b3JrZmxvd0NvcmVWZXJzaW9uIH0gZnJvbSAnLi4vdmVyc2lvbi5qcyc7XG5pbXBvcnQgeyBnZXRXb3JsZExhenkgfSBmcm9tICcuL2dldC13b3JsZC1sYXp5LmpzJztcbmltcG9ydCB7IGdldFdvcmtmbG93UXVldWVOYW1lLCBoZWFsdGhDaGVjayB9IGZyb20gJy4vaGVscGVycy5qcyc7XG5pbXBvcnQgeyBSdW4gfSBmcm9tICcuL3J1bi5qcyc7XG5pbXBvcnQgeyBzYWZlV2FpdFVudGlsLCB3YWl0ZWRVbnRpbCB9IGZyb20gJy4vd2FpdC11bnRpbC5qcyc7XG5pbXBvcnQgeyBhc3NlcnRXb3JsZFN1cHBvcnRzUnVudGltZVByb3RvY29sIH0gZnJvbSAnLi93b3JsZC1jb21wYXRpYmlsaXR5LmpzJztcblxuLyoqXG4gKiBUaW1lb3V0IGZvciB0aGUgY3Jvc3MtZGVwbG95bWVudCBjYXBhYmlsaXR5IHByb2JlIGRvbmUgYmVmb3JlXG4gKiBkZWh5ZHJhdGluZyB3b3JrZmxvdyBhcmd1bWVudHMuIEtlcHQgdGlnaHQgb24gcHVycG9zZTogdGhlIHByb2JlIGlzXG4gKiBhbiBvcHRpbWl6YXRpb24gKGl0IGxldHMgdGhlIGNhbGxlciBlbWl0IHRoZSBmcmFtZWQgYnl0ZS1zdHJlYW0gd2lyZVxuICogZm9ybWF0IHdoZW4gdGhlIHRhcmdldCBzdXBwb3J0cyBpdCksIGFuZCB0aGUgZmFsbGJhY2sgb24gdGltZW91dCBpc1xuICogdGhlIGxlZ2FjeSByYXcgZm9ybWF0IHdoaWNoIGFsd2F5cyB3b3Jrcy4gTG9uZyBkZWxheXMgaGVyZSB3b3VsZCBqdXN0XG4gKiBtYWtlIGBzdGFydCh7IGRlcGxveW1lbnRJZDogLi4uIH0pYCBzbG93ZXIgZm9yIHVzZXJzIHdob3NlIHRhcmdldFxuICogZGVwbG95bWVudHMgZG9uJ3QgcmVjb2duaXplIHRoZSBoZWFsdGggY2hlY2sgYXQgYWxsLlxuICovXG5jb25zdCBDUk9TU19ERVBMT1lNRU5UX0NBUEFCSUxJVFlfUFJPQkVfVElNRU9VVF9NUyA9IDJfMDAwO1xuXG4vKiogVUxJRCBnZW5lcmF0b3IgZm9yIGNsaWVudC1zaWRlIHJ1bklkIGdlbmVyYXRpb24gKi9cbmNvbnN0IHVsaWQgPSBtb25vdG9uaWNGYWN0b3J5KCk7XG5cbi8vIGBkZXBsb3ltZW50SWQ6ICdsYXRlc3QnYCBpcyBhIG5vLW9wIGluIFdvcmxkcyB3aXRob3V0IGF0b21pYyBkZXBsb3ltZW50cy5cbi8vIFRoZSB3YXJuaW5nIHRoYXQgZXhwbGFpbnMgdGhpcyBvbmx5IG5lZWRzIHRvIGZpcmUgb25jZSBwZXIgcHJvY2VzczogYVxuLy8gd29ya2Zsb3cgdGhhdCBoYXJkY29kZXMgJ2xhdGVzdCcgZm9yIGl0cyBWZXJjZWwgZGVwbG95bWVudCB3b3VsZCBvdGhlcndpc2Vcbi8vIGxvZyBpdCBvbiBldmVyeSBsb2NhbC9Qb3N0Z3JlcyBydW4sIGZsb29kaW5nIHRpZ2h0IGRldiBsb29wcy5cbmxldCBoYXNXYXJuZWRMYXRlc3ROb09wID0gZmFsc2U7XG5cbi8qKlxuICogUmVzZXQgdGhlIGBkZXBsb3ltZW50SWQ6ICdsYXRlc3QnYCBuby1vcCB3YXJuLW9uY2UgZ3VhcmQuIFRlc3Qtb25seSDigJRcbiAqIGV4cG9ydGVkIHNvIHVuaXQgdGVzdHMgY2FuIGV4ZXJjaXNlIHRoZSB3YXJuIHBhdGggYWNyb3NzIGBzdGFydCgpYCBjYWxscy5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9yZXNldExhdGVzdE5vT3BXYXJuRm9yVGVzdHMoKTogdm9pZCB7XG4gIGhhc1dhcm5lZExhdGVzdE5vT3AgPSBmYWxzZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTdGFydE9wdGlvbnNCYXNlIHtcbiAgLyoqXG4gICAqIFRoZSB3b3JsZCB0byB1c2UgZm9yIHRoZSB3b3JrZmxvdyBydW4gY3JlYXRpb24sXG4gICAqIGJ5IGRlZmF1bHQgdGhlIHdvcmxkIGlzIGluZmVycmVkIGZyb20gdGhlIGVudmlyb25tZW50IHZhcmlhYmxlcy5cbiAgICovXG4gIHdvcmxkPzogV29ybGQ7XG5cbiAgLyoqXG4gICAqIFRoZSBzcGVjIHZlcnNpb24gdG8gdXNlIGZvciB0aGUgd29ya2Zsb3cgcnVuLiBEZWZhdWx0cyB0byB0aGUgbGF0ZXN0IHZlcnNpb24uXG4gICAqL1xuICBzcGVjVmVyc2lvbj86IG51bWJlcjtcblxuICAvKipcbiAgICogUGxhaW50ZXh0IGF0dHJpYnV0ZXMgdG8gc2VlZCBvbiB0aGUgcnVuIGFzIGl0IGlzIGNyZWF0ZWQuXG4gICAqXG4gICAqIEF2YWlsYWJsZSBmb3IgbmF0aXZlLWF0dHJpYnV0ZXMgcnVucyAoc3BlYyB2ZXJzaW9uIDQgYW5kIGxhdGVyKS5cbiAgICovXG4gIGF0dHJpYnV0ZXM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuICAgKiBQZXJtaXQgcmVzZXJ2ZWQgYCRgLXByZWZpeGVkIGtleXMgaW4gYGF0dHJpYnV0ZXNgLiBUaGUgYCRgIG5hbWVzcGFjZVxuICAgKiBpcyByZXNlcnZlZCBmb3IgZnJhbWV3b3JrL2xpYnJhcnkgY29kZSBidWlsdCBvbiB0b3Agb2YgdGhlIHdvcmtmbG93XG4gICAqIFNESyAodGVsZW1ldHJ5LCBhZ2VudCBtZXRhZGF0YSwgcGxhdGZvcm0tZW1pdHRlZCB0YWdzLCBldGMuKTsgdXNlclxuICAgKiBjb2RlIE1VU1QgTk9UIHdyaXRlIGtleXMgaW4gaXQsIGFuZCB2YWxpZGF0aW9uIHJlamVjdHMgdGhlbSBzb1xuICAgKiBhY2NpZGVudGFsIGNvbGxpc2lvbnMgd2l0aCB0b29saW5nLW93bmVkIGtleXMgY2FuJ3Qgc2xpcCB0aHJvdWdoLlxuICAgKlxuICAgKiBPbmx5IGZsaXAgdGhpcyB0byBgdHJ1ZWAgaWYgeW91ciBjYWxsZXIgaXMgaXRzZWxmIGEgZnJhbWV3b3JrIG9yXG4gICAqIGxpYnJhcnkgdGhhdCBvd25zIGEgYCRgLXByZWZpeGVkIHN1Yi1uYW1lc3BhY2UgYW5kIGtub3dzIHRoZVxuICAgKiBjb252ZW50aW9ucyBvZiBhbnkgb3RoZXIgdG9vbHMgd3JpdGluZyBpbnRvIGl0LiBTYW1lIHNlbWFudGljcyBhc1xuICAgKiB0aGUgYHNldEF0dHJpYnV0ZXNgIG9wdGlvbiBvZiB0aGUgc2FtZSBuYW1lLlxuICAgKi9cbiAgYWxsb3dSZXNlcnZlZEF0dHJpYnV0ZXM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgSUQgb2YgYW4gZXhpc3RpbmcgcnVuIHRoaXMgcnVuIGlzIGJlaW5nIHJlcGxheWVkIGZyb20sIGlmIGFueS5cbiAgICpcbiAgICogUmVjb3JkZWQgb24gdGhlIG5ldyBydW4ncyBgZXhlY3V0aW9uQ29udGV4dGAgYXMgYHJlcGxheWVkRnJvbVJ1bklkYCBzb1xuICAgKiB0b29saW5nIChlLmcuIHRoZSBkYXNoYm9hcmQgcnVucyBsaXN0KSBjYW4gc2hvdyB0aGF0IGEgcnVuIG9yaWdpbmF0ZWQgYXNcbiAgICogYSByZXBsYXkgYW5kIGxpbmsgYmFjayB0byBpdHMgc291cmNlLiBTZXQgYXV0b21hdGljYWxseSBieVxuICAgKiB7QGxpbmsgcmVjcmVhdGVSdW5Gcm9tRXhpc3Rpbmd9OyB0aGVyZSdzIHVzdWFsbHkgbm8gcmVhc29uIHRvIHBhc3MgaXRcbiAgICogZGlyZWN0bHkuXG4gICAqXG4gICAqIE11c3QgYmUgYSBydW4gSUQ6IGB3cnVuX2AgZm9sbG93ZWQgYnkgYSAyNi1jaGFyIFVMSUQuIEl0J3MgYSBmb3JlaWduIGtleVxuICAgKiB0byB0aGUgc291cmNlIHJ1biwgc28gYHN0YXJ0KClgIHZhbGlkYXRlcyB0aGUgZXhhY3Qgc2hhcGUgYW5kIHJlamVjdHNcbiAgICogYW55dGhpbmcgZWxzZSByYXRoZXIgdGhhbiBwZXJzaXN0IGEgbGluZWFnZSBsaW5rIHRoYXQgcG9pbnRzIGF0IGdhcmJhZ2UuXG4gICAqL1xuICByZXBsYXllZEZyb21SdW5JZD86IHN0cmluZztcbiAgLyoqXG4gICAqIFF1ZXVlIG5hbWVzcGFjZSBvZiB0aGUgdGFyZ2V0IGRlcGxveW1lbnQuIFNjb3BlcyB0aGUgd29ya2Zsb3cgcXVldWVcbiAgICogdG9waWMgdG8gYF9fe25hbWVzcGFjZX1fd2tmX3dvcmtmbG93XypgIChlLmcuIGAnZXZlJ2ApIGluc3RlYWQgb2YgdGhlXG4gICAqIGRlZmF1bHQgYF9fd2tmX3dvcmtmbG93XypgLCBhbmQgaXMgYWxzbyB1c2VkIGZvciB0aGUgY3Jvc3MtZGVwbG95bWVudFxuICAgKiBjYXBhYmlsaXR5IHByb2JlLiBGYWxscyBiYWNrIHRvIGBXT1JLRkxPV19RVUVVRV9OQU1FU1BBQ0VgIGluIHRoZVxuICAgKiBjYWxsaW5nIHByb2Nlc3MuXG4gICAqXG4gICAqIFdpdGhpbiBhIGRlcGxveW1lbnQgdGhlIGVudiBmYWxsYmFjayBpcyBjb3JyZWN0LiBDcm9zcy1jb250ZXh0IGNhbGxlcnNcbiAgICogKGUuZy4gdGhlIG9ic2VydmFiaWxpdHkgZGFzaGJvYXJkIHJlcGxheWluZyBhIHJ1bikgbXVzdCBwYXNzIHRoZVxuICAgKiBUQVJHRVQgZGVwbG95bWVudCdzIG5hbWVzcGFjZSBleHBsaWNpdGx5OiB0aGUgZW52IGZhbGxiYWNrIHJlc29sdmVzIGluXG4gICAqIHRoZSBjYWxsZXIncyBwcm9jZXNzLCBhbmQgYSBydW4gZW5xdWV1ZWQgdG8gYSB0b3BpYyB0aGUgdGFyZ2V0IGhhcyBub1xuICAgKiBjb25zdW1lciBmb3IgaXMgbmV2ZXIgcGlja2VkIHVwLlxuICAgKi9cbiAgbmFtZXNwYWNlPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXJ0T3B0aW9uc1dpdGhEZXBsb3ltZW50SWQgZXh0ZW5kcyBTdGFydE9wdGlvbnNCYXNlIHtcbiAgLyoqXG4gICAqIFRoZSBkZXBsb3ltZW50IElEIHRvIHVzZSBmb3IgdGhlIHdvcmtmbG93IHJ1bi5cbiAgICpcbiAgICogQnkgZGVmYXVsdCwgdGhpcyBpcyBhdXRvbWF0aWNhbGx5IGluZmVycmVkIGZyb20gZW52aXJvbm1lbnQgdmFyaWFibGVzXG4gICAqIHdoZW4gZGVwbG95aW5nIHRvIFZlcmNlbC5cbiAgICpcbiAgICogU2V0IHRvIGAnbGF0ZXN0J2AgdG8gYXV0b21hdGljYWxseSByZXNvbHZlIHRoZSBtb3N0IHJlY2VudCBkZXBsb3ltZW50XG4gICAqIGZvciB0aGUgY3VycmVudCBlbnZpcm9ubWVudCAoc2FtZSBwcm9kdWN0aW9uIHRhcmdldCBvciBnaXQgYnJhbmNoKS5cbiAgICogVGhpcyBpcyBvbmx5IG1lYW5pbmdmdWwgaW4gd29ybGRzIHdpdGggYXRvbWljLCBpbW11dGFibGUgZGVwbG95bWVudHNcbiAgICogKGN1cnJlbnRseSBWZXJjZWwpLiBJbiBvdGhlciB3b3JsZHMgKGxvY2FsIGRldiwgUG9zdGdyZXMpIHRoZXJlIGlzIG5vXG4gICAqIG5vdGlvbiBvZiBtdWx0aXBsZSBkZXBsb3ltZW50cyB0byByZXNvbHZlIGJldHdlZW4sIHNvIGAnbGF0ZXN0J2AgaGFzIG5vXG4gICAqIGVmZmVjdCDigJQgYSB3YXJuaW5nIGlzIGxvZ2dlZCBhbmQgdGhlIHJ1biB0YXJnZXRzIHRoZSBjdXJyZW50IGRlcGxveW1lbnQuXG4gICAqXG4gICAqICoqTm90ZToqKiBXaGVuIGBkZXBsb3ltZW50SWRgIGlzIHByb3ZpZGVkLCB0aGUgYXJndW1lbnQgYW5kIHJldHVybiB0eXBlcyBiZWNvbWUgYHVua25vd25gXG4gICAqIHNpbmNlIHRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGUgdHlwZXMgd2lsbCBiZSBjb25zaXN0ZW50IGFjcm9zcyBkZXBsb3ltZW50cy5cbiAgICovXG4gIGRlcGxveW1lbnRJZDogJ2xhdGVzdCcgfCAoc3RyaW5nICYge30pO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXJ0T3B0aW9uc1dpdGhvdXREZXBsb3ltZW50SWQgZXh0ZW5kcyBTdGFydE9wdGlvbnNCYXNlIHtcbiAgZGVwbG95bWVudElkPzogdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHN0YXJ0aW5nIGEgd29ya2Zsb3cgcnVuLlxuICovXG5leHBvcnQgdHlwZSBTdGFydE9wdGlvbnMgPVxuICB8IFN0YXJ0T3B0aW9uc1dpdGhEZXBsb3ltZW50SWRcbiAgfCBTdGFydE9wdGlvbnNXaXRob3V0RGVwbG95bWVudElkO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYW4gaW1wb3J0ZWQgd29ya2Zsb3cgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCB0eXBlIFdvcmtmbG93RnVuY3Rpb248VEFyZ3MgZXh0ZW5kcyB1bmtub3duW10sIFRSZXN1bHQ+ID0gKFxuICAuLi5hcmdzOiBUQXJnc1xuKSA9PiBQcm9taXNlPFRSZXN1bHQ+O1xuXG4vKipcbiAqIFJlcHJlc2VudHMgdGhlIGdlbmVyYXRlZCBtZXRhZGF0YSBvZiBhIHdvcmtmbG93IGZ1bmN0aW9uLlxuICovXG5leHBvcnQgdHlwZSBXb3JrZmxvd01ldGFkYXRhID0geyB3b3JrZmxvd0lkOiBzdHJpbmcgfTtcblxuLyoqXG4gKiBTdGFydHMgYSB3b3JrZmxvdyBydW4uXG4gKlxuICogQHBhcmFtIHdvcmtmbG93IC0gVGhlIGltcG9ydGVkIHdvcmtmbG93IGZ1bmN0aW9uIHRvIHN0YXJ0LlxuICogQHBhcmFtIGFyZ3MgLSBUaGUgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIHdvcmtmbG93IChvcHRpb25hbCkuXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIGZvciB0aGUgd29ya2Zsb3cgcnVuIChvcHRpb25hbCkuXG4gKiBAcmV0dXJucyBUaGUgdW5pcXVlIHJ1biBJRCBmb3IgdGhlIG5ld2x5IHN0YXJ0ZWQgd29ya2Zsb3cgaW52b2NhdGlvbi5cbiAqL1xuLy8gT3ZlcmxvYWRzIHdpdGggZGVwbG95bWVudElkIC0gYXJncyBhbmQgcmV0dXJuIHR5cGUgYmVjb21lIHVua25vd25cbi8vIFVzZXMgZ2VuZXJpY3Mgc28gdHlwZWQgd29ya2Zsb3dzIGFyZSBhc3NpZ25hYmxlIChhdm9pZHMgY29udHJhdmFyaWFuY2UgaXNzdWVzKSxcbi8vIGJ1dCB0aGUgcmV0dXJuIHR5cGUgYW5kIGFyZ3MgYXJlIHN0aWxsIHVua25vd24gc2luY2UgdGhlIGRlcGxveWVkIHZlcnNpb24gbWF5IGRpZmZlci5cbmV4cG9ydCBmdW5jdGlvbiBzdGFydDxUQXJncyBleHRlbmRzIHVua25vd25bXSwgVFJlc3VsdD4oXG4gIHdvcmtmbG93OiBXb3JrZmxvd0Z1bmN0aW9uPFRBcmdzLCBUUmVzdWx0PiB8IFdvcmtmbG93TWV0YWRhdGEsXG4gIGFyZ3M6IHVua25vd25bXSxcbiAgb3B0aW9uczogU3RhcnRPcHRpb25zV2l0aERlcGxveW1lbnRJZFxuKTogUHJvbWlzZTxSdW48dW5rbm93bj4+O1xuXG5leHBvcnQgZnVuY3Rpb24gc3RhcnQ8VFJlc3VsdD4oXG4gIHdvcmtmbG93OiBXb3JrZmxvd0Z1bmN0aW9uPFtdLCBUUmVzdWx0PiB8IFdvcmtmbG93TWV0YWRhdGEsXG4gIG9wdGlvbnM6IFN0YXJ0T3B0aW9uc1dpdGhEZXBsb3ltZW50SWRcbik6IFByb21pc2U8UnVuPHVua25vd24+PjtcblxuLy8gT3ZlcmxvYWRzIHdpdGhvdXQgZGVwbG95bWVudElkIC0gcHJlc2VydmUgdHlwZSBpbmZlcmVuY2VcbmV4cG9ydCBmdW5jdGlvbiBzdGFydDxUQXJncyBleHRlbmRzIHVua25vd25bXSwgVFJlc3VsdD4oXG4gIHdvcmtmbG93OiBXb3JrZmxvd0Z1bmN0aW9uPFRBcmdzLCBUUmVzdWx0PiB8IFdvcmtmbG93TWV0YWRhdGEsXG4gIGFyZ3M6IFRBcmdzLFxuICBvcHRpb25zPzogU3RhcnRPcHRpb25zV2l0aG91dERlcGxveW1lbnRJZFxuKTogUHJvbWlzZTxSdW48VFJlc3VsdD4+O1xuXG5leHBvcnQgZnVuY3Rpb24gc3RhcnQ8VFJlc3VsdD4oXG4gIHdvcmtmbG93OiBXb3JrZmxvd0Z1bmN0aW9uPFtdLCBUUmVzdWx0PiB8IFdvcmtmbG93TWV0YWRhdGEsXG4gIG9wdGlvbnM/OiBTdGFydE9wdGlvbnNXaXRob3V0RGVwbG95bWVudElkXG4pOiBQcm9taXNlPFJ1bjxUUmVzdWx0Pj47XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzdGFydDxUQXJncyBleHRlbmRzIHVua25vd25bXSwgVFJlc3VsdD4oXG4gIHdvcmtmbG93OiBXb3JrZmxvd0Z1bmN0aW9uPFRBcmdzLCBUUmVzdWx0PiB8IFdvcmtmbG93TWV0YWRhdGEsXG4gIGFyZ3NPck9wdGlvbnM/OiBUQXJncyB8IFN0YXJ0T3B0aW9ucyxcbiAgb3B0aW9ucz86IFN0YXJ0T3B0aW9uc1xuKSB7XG4gICd1c2Ugc3RlcCc7XG4gIHJldHVybiBhd2FpdCB3YWl0ZWRVbnRpbCgoKSA9PiB7XG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciB0aGlzIGZpZWxkIGlzIGFkZGVkIGJ5IG91ciBjbGllbnQgdHJhbnNmb3JtXG4gICAgY29uc3Qgd29ya2Zsb3dOYW1lID0gd29ya2Zsb3c/LndvcmtmbG93SWQ7XG5cbiAgICBpZiAoIXdvcmtmbG93TmFtZSkge1xuICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKFxuICAgICAgICBgJ3N0YXJ0JyByZWNlaXZlZCBhbiBpbnZhbGlkIHdvcmtmbG93IGZ1bmN0aW9uLiBFbnN1cmUgdGhlIFdvcmtmbG93IFNESyBpcyBjb25maWd1cmVkIGNvcnJlY3RseSBhbmQgdGhlIGZ1bmN0aW9uIGluY2x1ZGVzIGEgJ3VzZSB3b3JrZmxvdycgZGlyZWN0aXZlLmAsXG4gICAgICAgIHsgc2x1ZzogJ3N0YXJ0LWludmFsaWQtd29ya2Zsb3ctZnVuY3Rpb24nIH1cbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3Bhbk5hbWUgPSBgd29ya2Zsb3cuc3RhcnQgJHt3b3JrZmxvd0Rpc3BsYXlOYW1lKHdvcmtmbG93TmFtZSl9YDtcbiAgICByZXR1cm4gdHJhY2Uoc3Bhbk5hbWUsIGFzeW5jIChzcGFuKSA9PiB7XG4gICAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93TmFtZSh3b3JrZmxvd05hbWUpLFxuICAgICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dPcGVyYXRpb24oJ3N0YXJ0JyksXG4gICAgICB9KTtcblxuICAgICAgbGV0IGFyZ3M6IFNlcmlhbGl6YWJsZVtdID0gW107XG4gICAgICBsZXQgb3B0czogU3RhcnRPcHRpb25zID0gb3B0aW9ucyA/PyB7fTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGFyZ3NPck9wdGlvbnMpKSB7XG4gICAgICAgIGFyZ3MgPSBhcmdzT3JPcHRpb25zIGFzIFNlcmlhbGl6YWJsZVtdO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnc09yT3B0aW9ucyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgb3B0cyA9IGFyZ3NPck9wdGlvbnM7XG4gICAgICB9XG5cbiAgICAgIHNwYW4/LnNldEF0dHJpYnV0ZXMoe1xuICAgICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dBcmd1bWVudHNDb3VudChhcmdzLmxlbmd0aCksXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgd29ybGQgPSBvcHRzLndvcmxkID8/IChhd2FpdCBnZXRXb3JsZExhenkoKSk7XG4gICAgICBhc3NlcnRXb3JsZFN1cHBvcnRzUnVudGltZVByb3RvY29sKHdvcmxkKTtcbiAgICAgIGNvbnN0IGN1cnJlbnREZXBsb3ltZW50SWQgPSBhd2FpdCB3b3JsZC5nZXREZXBsb3ltZW50SWQoKTtcbiAgICAgIGxldCBkZXBsb3ltZW50SWQgPSBvcHRzLmRlcGxveW1lbnRJZCA/PyBjdXJyZW50RGVwbG95bWVudElkO1xuXG4gICAgICAvLyBXaGVuICdsYXRlc3QnIGlzIHJlcXVlc3RlZCwgcmVzb2x2ZSB0aGUgYWN0dWFsIGxhdGVzdCBkZXBsb3ltZW50IElEXG4gICAgICAvLyBmb3IgdGhlIGN1cnJlbnQgZGVwbG95bWVudCdzIGVudmlyb25tZW50IChzYW1lIHByb2R1Y3Rpb24gdGFyZ2V0IG9yXG4gICAgICAvLyBzYW1lIGdpdCBicmFuY2ggZm9yIHByZXZpZXcgZGVwbG95bWVudHMpLlxuICAgICAgLy9cbiAgICAgIC8vIFJlc29sdmluZyAnbGF0ZXN0JyBvbmx5IG1lYW5zIHNvbWV0aGluZyBpbiB3b3JsZHMgd2l0aCBhdG9taWMsXG4gICAgICAvLyBpbW11dGFibGUgZGVwbG95bWVudHMgKGUuZy4gVmVyY2VsKSwgd2hpY2ggaW1wbGVtZW50XG4gICAgICAvLyByZXNvbHZlTGF0ZXN0RGVwbG95bWVudElkKCkuIFdvcmxkcyB3aXRob3V0IHRoYXQgY29uY2VwdCAobG9jYWwgZGV2LFxuICAgICAgLy8gc2VsZi1ob3N0ZWQgUG9zdGdyZXMpIGhhdmUgbm90aGluZyB0byByZXNvbHZlIGJldHdlZW4sIHNvIHJhdGhlciB0aGFuXG4gICAgICAvLyBmYWlsIGEgcnVuIHRoYXQgd29ya3MgZmluZSBvbiBWZXJjZWwsIHdlIHdhcm4gYW5kIGZhbGwgYmFjayB0byB0aGVcbiAgICAgIC8vIGN1cnJlbnQgZGVwbG95bWVudCDigJQgbWFraW5nICdsYXRlc3QnIGFuIGVmZmVjdGl2ZSBuby1vcCB0aGVyZS5cbiAgICAgIGlmIChkZXBsb3ltZW50SWQgPT09ICdsYXRlc3QnKSB7XG4gICAgICAgIGlmICh3b3JsZC5yZXNvbHZlTGF0ZXN0RGVwbG95bWVudElkKSB7XG4gICAgICAgICAgZGVwbG95bWVudElkID0gYXdhaXQgd29ybGQucmVzb2x2ZUxhdGVzdERlcGxveW1lbnRJZCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFdhcm4gb25jZSBwZXIgcHJvY2VzcyDigJQgc2VlIGhhc1dhcm5lZExhdGVzdE5vT3AgYWJvdmUuXG4gICAgICAgICAgaWYgKCFoYXNXYXJuZWRMYXRlc3ROb09wKSB7XG4gICAgICAgICAgICBoYXNXYXJuZWRMYXRlc3ROb09wID0gdHJ1ZTtcbiAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIud2FybihcbiAgICAgICAgICAgICAgXCJkZXBsb3ltZW50SWQ6ICdsYXRlc3QnIGhhcyBubyBlZmZlY3QgaW4gdGhpcyB3b3JsZCBhbmQgd2FzIGlnbm9yZWQuIFwiICtcbiAgICAgICAgICAgICAgICAnSXQgaXMgb25seSBzdXBwb3J0ZWQgYnkgd29ybGRzIHdpdGggYXRvbWljIGRlcGxveW1lbnRzLCBzdWNoIGFzIFZlcmNlbC4gJyArXG4gICAgICAgICAgICAgICAgJ1RoZSBydW4gd2lsbCB0YXJnZXQgdGhlIGN1cnJlbnQgZGVwbG95bWVudC4nLFxuICAgICAgICAgICAgICB7IGN1cnJlbnREZXBsb3ltZW50SWQgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVwbG95bWVudElkID0gY3VycmVudERlcGxveW1lbnRJZDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBEZWNpZGUgd2hldGhlciB0byB3cml0ZSBieXRlIHN0cmVhbXMgaW4gdGhlIGZyYW1lZCB3aXJlIGZvcm1hdC5cbiAgICAgIC8vIEZvciBzYW1lLWRlcGxveW1lbnQgc3RhcnRzICh0aGUgY29tbW9uIGNhc2UpIHdlIGtub3cgdGhlIHRhcmdldCBpc1xuICAgICAgLy8gcnVubmluZyB0aGlzIHNhbWUgU0RLIHZlcnNpb24sIHNvIGZyYW1pbmcgaXMgc2FmZS4gRm9yIGNyb3NzLVxuICAgICAgLy8gZGVwbG95bWVudCBzdGFydHMgKGV4cGxpY2l0IGRlcGxveW1lbnRJZCBvciAnbGF0ZXN0JyB0aGF0IHJlc29sdmVzXG4gICAgICAvLyB0byBhIGRpZmZlcmVudCBkZXBsb3ltZW50KSB3ZSBwcm9iZSB0aGUgdGFyZ2V0IHZpYSBoZWFsdGhDaGVjayB0b1xuICAgICAgLy8gbGVhcm4gaXRzIHdvcmtmbG93LWNvcmUgdmVyc2lvbiwgdGhlbiBkZXJpdmUgdGhlIGNhcGFiaWxpdHkuIFRoZVxuICAgICAgLy8gcHJvYmUgaGFzIGEgdGlnaHQgdGltZW91dCDigJQgb24gbWlzcy9mYWlsdXJlIHdlIGZhbGwgYmFjayB0byB0aGVcbiAgICAgIC8vIGxlZ2FjeSByYXcgYnl0ZSBmb3JtYXQsIHdoaWNoIGlzIHVuaXZlcnNhbGx5IHJlYWRhYmxlLlxuICAgICAgLy9cbiAgICAgIC8vIFdvcmxkcyB0aGF0IGRvbid0IGV4cG9zZSB0aGUgYHN0cmVhbXNgIEFQSSAoZS5nLiBtaW5pbWFsIHRlc3RcbiAgICAgIC8vIG1vY2tzKSBjYW4ndCBzZXJ2aWNlIGhlYWx0aCBjaGVja3MsIHNvIHdlIHNraXAgdGhlIHByb2JlIGZvciB0aGVtLlxuICAgICAgbGV0IGZyYW1lZEJ5dGVTdHJlYW1zOiBib29sZWFuO1xuICAgICAgbGV0IHRhcmdldFN1cHBvcnRzQ29tcHJlc3Npb246IGJvb2xlYW47XG4gICAgICBpZiAoZGVwbG95bWVudElkID09PSBjdXJyZW50RGVwbG95bWVudElkKSB7XG4gICAgICAgIGZyYW1lZEJ5dGVTdHJlYW1zID0gdHJ1ZTtcbiAgICAgICAgdGFyZ2V0U3VwcG9ydHNDb21wcmVzc2lvbiA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiB3b3JsZC5zdHJlYW1zPy5nZXQgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgZnJhbWVkQnl0ZVN0cmVhbXMgPSBmYWxzZTtcbiAgICAgICAgdGFyZ2V0U3VwcG9ydHNDb21wcmVzc2lvbiA9IGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgcHJvYmUgPSBhd2FpdCBoZWFsdGhDaGVjayh3b3JsZCwgJ3dvcmtmbG93Jywge1xuICAgICAgICAgIGRlcGxveW1lbnRJZCxcbiAgICAgICAgICB0aW1lb3V0OiBDUk9TU19ERVBMT1lNRU5UX0NBUEFCSUxJVFlfUFJPQkVfVElNRU9VVF9NUyxcbiAgICAgICAgICBuYW1lc3BhY2U6IG9wdHMubmFtZXNwYWNlLFxuICAgICAgICB9KS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgICAgICBjb25zdCBjYXBhYmlsaXRpZXMgPSBnZXRSdW5DYXBhYmlsaXRpZXMocHJvYmU/LndvcmtmbG93Q29yZVZlcnNpb24pO1xuICAgICAgICBmcmFtZWRCeXRlU3RyZWFtcyA9IGNhcGFiaWxpdGllcy5mcmFtZWRCeXRlU3RyZWFtcztcbiAgICAgICAgdGFyZ2V0U3VwcG9ydHNDb21wcmVzc2lvbiA9IGNhcGFiaWxpdGllcy5zdXBwb3J0ZWRGb3JtYXRzLmhhcyhcbiAgICAgICAgICBTZXJpYWxpemF0aW9uRm9ybWF0LkdaSVBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgb3BzOiBQcm9taXNlPHZvaWQ+W10gPSBbXTtcblxuICAgICAgLy8gR2VuZXJhdGUgcnVuSWQgY2xpZW50LXNpZGUgc28gd2UgaGF2ZSBpdCBiZWZvcmUgc2VyaWFsaXphdGlvblxuICAgICAgLy8gKHJlcXVpcmVkIGZvciBmdXR1cmUgRTJFIGVuY3J5cHRpb24gd2hlcmUgcnVuSWQgaXMgcGFydCBvZiB0aGUgZW5jcnlwdGlvbiBjb250ZXh0KVxuICAgICAgY29uc3QgcnVuSWQgPSBgd3J1bl8ke3VsaWQoKX1gO1xuXG4gICAgICAvLyBTZXJpYWxpemUgY3VycmVudCB0cmFjZSBjb250ZXh0IHRvIHByb3BhZ2F0ZSBhY3Jvc3MgcXVldWUgYm91bmRhcnlcbiAgICAgIGNvbnN0IHRyYWNlQ2FycmllciA9IGF3YWl0IHNlcmlhbGl6ZVRyYWNlQ2FycmllcigpO1xuXG4gICAgICAvLyBEZWZhdWx0IG5ldyBydW5zIHRvIHRoZSBjb25maWd1cmVkIHdvcmxkJ3Mgc3BlYyB2ZXJzaW9uLiBUaGUgd29ybGRcbiAgICAgIC8vIGl0c2VsZiBoYXMgYWxyZWFkeSBiZWVuIGNoZWNrZWQgYWdhaW5zdCB0aGlzIHJ1bnRpbWUncyBzcGVjIHZlcnNpb24uXG4gICAgICBjb25zdCBzcGVjVmVyc2lvbiA9IG9wdHMuc3BlY1ZlcnNpb24gPz8gd29ybGQuc3BlY1ZlcnNpb247XG4gICAgICBjb25zdCB2MUNvbXBhdCA9IGlzTGVnYWN5U3BlY1ZlcnNpb24oc3BlY1ZlcnNpb24pO1xuICAgICAgY29uc3QgYWxsb3dSZXNlcnZlZEF0dHJpYnV0ZXMgPSBvcHRzLmFsbG93UmVzZXJ2ZWRBdHRyaWJ1dGVzID09PSB0cnVlO1xuICAgICAgbGV0IGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfCB1bmRlZmluZWQ7XG4gICAgICBpZiAob3B0cy5hdHRyaWJ1dGVzICYmIE9iamVjdC5rZXlzKG9wdHMuYXR0cmlidXRlcykubGVuZ3RoID4gMCkge1xuICAgICAgICBpZiAoc3BlY1ZlcnNpb24gPCBTUEVDX1ZFUlNJT05fU1VQUE9SVFNfQVRUUklCVVRFUykge1xuICAgICAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcihcbiAgICAgICAgICAgICdJbml0aWFsIHdvcmtmbG93IGF0dHJpYnV0ZXMgcmVxdWlyZSBhIFdvcmxkIHRoYXQgc3VwcG9ydHMgc3BlYyB2ZXJzaW9uIDQgb3IgbGF0ZXIuJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gYG5vcm1hbGl6ZUF0dHJpYnV0ZUNoYW5nZXNgIHRyZWF0cyBgdW5kZWZpbmVkYCBhcyBcInJlbW92ZSB0aGlzXG4gICAgICAgIC8vIGtleVwiLCB3aGljaCBpcyBtZWFuaW5nbGVzcyBhdCBjcmVhdGlvbiB0aW1lIOKAlCByZWplY3QgaXQgdXAgZnJvbnRcbiAgICAgICAgLy8gc28gSlMgY2FsbGVycyBnZXQgYSBjbGVhciBlcnJvciBpbnN0ZWFkIG9mIGEgZG93bnN0cmVhbSBzY2hlbWFcbiAgICAgICAgLy8gZmFpbHVyZSAodGhlIHR5cGVzIGFscmVhZHkgZm9yYmlkIG5vbi1zdHJpbmcgdmFsdWVzKS5cbiAgICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMob3B0cy5hdHRyaWJ1dGVzKSkge1xuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IoXG4gICAgICAgICAgICAgIGBJbml0aWFsIHdvcmtmbG93IGF0dHJpYnV0ZSAke0pTT04uc3RyaW5naWZ5KGtleSl9IG11c3QgYmUgYSBzdHJpbmcgdmFsdWUuYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2hhbmdlcyA9IG5vcm1hbGl6ZUF0dHJpYnV0ZUNoYW5nZXMob3B0cy5hdHRyaWJ1dGVzLCB7XG4gICAgICAgICAgYWxsb3dSZXNlcnZlZEF0dHJpYnV0ZXMsXG4gICAgICAgIH0pO1xuICAgICAgICBhdHRyaWJ1dGVzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgIGNoYW5nZXMubWFwKCh7IGtleSwgdmFsdWUgfSkgPT4gW2tleSwgdmFsdWUgYXMgc3RyaW5nXSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIC8vIFNlZWQgcGF5bG9hZCBzaGFyZWQgYnkgcnVuX2NyZWF0ZWQgYW5kIHRoZSByZXNpbGllbnQtc3RhcnQgcXVldWVcbiAgICAgIC8vIGlucHV0LiBUaGUgZmxhZyByaWRlcyBhbG9uZyBzbyBzZXJ2ZXItc2lkZSB2YWxpZGF0aW9uIG1hdGNoZXMgdGhlXG4gICAgICAvLyBjbGllbnQtc2lkZSBjaGVjayBhYm92ZSBvbiBib3RoIHBhdGhzLlxuICAgICAgY29uc3QgYXR0cmlidXRlU2VlZCA9IGF0dHJpYnV0ZXNcbiAgICAgICAgPyB7XG4gICAgICAgICAgICBhdHRyaWJ1dGVzLFxuICAgICAgICAgICAgLi4uKGFsbG93UmVzZXJ2ZWRBdHRyaWJ1dGVzXG4gICAgICAgICAgICAgID8geyBhbGxvd1Jlc2VydmVkQXR0cmlidXRlczogdHJ1ZSBhcyBjb25zdCB9XG4gICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgIH1cbiAgICAgICAgOiB7fTtcblxuICAgICAgLy8gYHJlcGxheWVkRnJvbVJ1bklkYCBpcyBhIGZvcmVpZ24ga2V5IHRvIHRoZSBzb3VyY2UgcnVuOyByZWplY3QgYW55dGhpbmdcbiAgICAgIC8vIHRoYXQgaXNuJ3QgYSByZWFsIHJ1biBJRCBzbyB0aGUgbGluZWFnZSBsaW5rIGNhbid0IHBvaW50IGF0IGdhcmJhZ2UuXG4gICAgICBpZiAoXG4gICAgICAgIG9wdHMucmVwbGF5ZWRGcm9tUnVuSWQgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAhd29ya2Zsb3dSdW5JZFNjaGVtYS5zYWZlUGFyc2Uob3B0cy5yZXBsYXllZEZyb21SdW5JZCkuc3VjY2Vzc1xuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcihcbiAgICAgICAgICBgcmVwbGF5ZWRGcm9tUnVuSWQgbXVzdCBiZSBhIHJ1biBJRCAod3J1bl88dWxpZD4pOyByZWNlaXZlZCAke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICAgICAgU3RyaW5nKG9wdHMucmVwbGF5ZWRGcm9tUnVuSWQpLnNsaWNlKDAsIDY0KVxuICAgICAgICAgICl9LmBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gUmVzb2x2ZSBlbmNyeXB0aW9uIGtleSBmb3IgdGhlIG5ldyBydW4uIFRoZSBydW5JZCBoYXMgYWxyZWFkeSBiZWVuXG4gICAgICAvLyBnZW5lcmF0ZWQgYWJvdmUgKGNsaWVudC1nZW5lcmF0ZWQgVUxJRCkgYW5kIHdpbGwgYmUgdXNlZCBmb3IgYm90aFxuICAgICAgLy8ga2V5IGRlcml2YXRpb24gYW5kIHRoZSBydW5fY3JlYXRlZCBldmVudC4gVGhlIFdvcmxkIGltcGxlbWVudGF0aW9uXG4gICAgICAvLyB1c2VzIHRoZSBydW5JZCBmb3IgcGVyLXJ1biBIS0RGIGtleSBkZXJpdmF0aW9uLiBXZSBwYXNzIHRoZSByZXNvbHZlZFxuICAgICAgLy8gZGVwbG95bWVudElkIChub3QganVzdCB0aGUgcmF3IG9wdHMpIHNvIHRoZSBXb3JsZCBjYW4gdXNlIGl0IGZvclxuICAgICAgLy8ga2V5IHJlc29sdXRpb24gZXZlbiB3aGVuIGRlcGxveW1lbnRJZCB3YXMgaW5mZXJyZWQgZnJvbSB0aGUgZW52aXJvbm1lbnRcbiAgICAgIC8vIHJhdGhlciB0aGFuIGV4cGxpY2l0bHkgcHJvdmlkZWQgaW4gb3B0cyAoZS5nLiwgaW4gZTJlIHRlc3QgcnVubmVycykuXG4gICAgICBjb25zdCByYXdLZXkgPSBhd2FpdCB3b3JsZC5nZXRFbmNyeXB0aW9uS2V5Rm9yUnVuPy4ocnVuSWQsIHtcbiAgICAgICAgLi4ub3B0cyxcbiAgICAgICAgZGVwbG95bWVudElkLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBlbmNyeXB0aW9uS2V5ID0gcmF3S2V5ID8gYXdhaXQgaW1wb3J0S2V5KHJhd0tleSkgOiB1bmRlZmluZWQ7XG5cbiAgICAgIC8vIENyZWF0ZSBydW4gdmlhIHJ1bl9jcmVhdGVkIGV2ZW50IChldmVudC1zb3VyY2VkIGFyY2hpdGVjdHVyZSlcbiAgICAgIC8vIFBhc3MgY2xpZW50LWdlbmVyYXRlZCBydW5JZCAtIHNlcnZlciB3aWxsIGFjY2VwdCBhbmQgdXNlIGl0XG4gICAgICAvLyBDb21wcmVzcyB3b3JrZmxvdyBhcmd1bWVudHMgb25seSB3aGVuIHRoZSBydW4gaXRzZWxmIGlzIG1hcmtlZCBhc1xuICAgICAgLy8gcG9zc2libHkgY29udGFpbmluZyBjb21wcmVzc2VkIHBheWxvYWRzIChzcGVjVmVyc2lvbiA+PSA1KSBBTkQgdGhlXG4gICAgICAvLyB0YXJnZXQgZGVwbG95bWVudCBjYW4gZGVjb2RlIHRoZW0gKHNhbWUtZGVwbG95bWVudCwgb3IgcHJvYmVkXG4gICAgICAvLyBjYXBhYmlsaXR5IGZvciBjcm9zcy1kZXBsb3ltZW50IHN0YXJ0cykuXG4gICAgICBjb25zdCBjb21wcmVzc2lvbiA9XG4gICAgICAgIHRhcmdldFN1cHBvcnRzQ29tcHJlc3Npb24gJiZcbiAgICAgICAgc3BlY1ZlcnNpb24gPj0gU1BFQ19WRVJTSU9OX1NVUFBPUlRTX0NPTVBSRVNTSU9OO1xuICAgICAgY29uc3Qgd29ya2Zsb3dBcmd1bWVudHMgPSBhd2FpdCBkZWh5ZHJhdGVXb3JrZmxvd0FyZ3VtZW50cyhcbiAgICAgICAgYXJncyxcbiAgICAgICAgcnVuSWQsXG4gICAgICAgIGVuY3J5cHRpb25LZXksXG4gICAgICAgIG9wcyxcbiAgICAgICAgZ2xvYmFsVGhpcyxcbiAgICAgICAgdjFDb21wYXQsXG4gICAgICAgIGZyYW1lZEJ5dGVTdHJlYW1zLFxuICAgICAgICBjb21wcmVzc2lvblxuICAgICAgKTtcblxuICAgICAgY29uc3QgZXhlY3V0aW9uQ29udGV4dCA9IHtcbiAgICAgICAgdHJhY2VDYXJyaWVyLFxuICAgICAgICB3b3JrZmxvd0NvcmVWZXJzaW9uLFxuICAgICAgICBmZWF0dXJlczogeyBlbmNyeXB0aW9uOiAhIWVuY3J5cHRpb25LZXkgfSxcbiAgICAgICAgLi4uKG9wdHMucmVwbGF5ZWRGcm9tUnVuSWRcbiAgICAgICAgICA/IHsgcmVwbGF5ZWRGcm9tUnVuSWQ6IG9wdHMucmVwbGF5ZWRGcm9tUnVuSWQgfVxuICAgICAgICAgIDoge30pLFxuICAgICAgfTtcblxuICAgICAgLy8gQ2FsbCBldmVudHMuY3JlYXRlIChydW5fY3JlYXRlZCkgYW5kIHF1ZXVlIGluIHBhcmFsbGVsLlxuICAgICAgLy8gSWYgZXZlbnRzLmNyZWF0ZSBmYWlscyB3aXRoIDQyOS81eHgsIHRoZSBydW4gd2FzIHN0aWxsIGFjY2VwdGVkXG4gICAgICAvLyB2aWEgdGhlIHF1ZXVlIGFuZCBjcmVhdGlvbiB3aWxsIGJlIHJlLXRyaWVkIGFzeW5jIGJ5IHRoZSBydW50aW1lLlxuICAgICAgY29uc3QgW3J1bkNyZWF0ZWRSZXN1bHQsIHF1ZXVlUmVzdWx0XSA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChbXG4gICAgICAgIHdvcmxkLmV2ZW50cy5jcmVhdGUoXG4gICAgICAgICAgcnVuSWQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZXZlbnRUeXBlOiAncnVuX2NyZWF0ZWQnLFxuICAgICAgICAgICAgc3BlY1ZlcnNpb24sXG4gICAgICAgICAgICBldmVudERhdGE6IHtcbiAgICAgICAgICAgICAgZGVwbG95bWVudElkOiBkZXBsb3ltZW50SWQsXG4gICAgICAgICAgICAgIHdvcmtmbG93TmFtZTogd29ya2Zsb3dOYW1lLFxuICAgICAgICAgICAgICBpbnB1dDogd29ya2Zsb3dBcmd1bWVudHMsXG4gICAgICAgICAgICAgIGV4ZWN1dGlvbkNvbnRleHQsXG4gICAgICAgICAgICAgIC4uLmF0dHJpYnV0ZVNlZWQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgeyB2MUNvbXBhdCB9XG4gICAgICAgICksXG4gICAgICAgIHdvcmxkLnF1ZXVlKFxuICAgICAgICAgIGdldFdvcmtmbG93UXVldWVOYW1lKHdvcmtmbG93TmFtZSwgb3B0cy5uYW1lc3BhY2UpLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgdHJhY2VDYXJyaWVyLFxuICAgICAgICAgICAgLi4uKHNwZWNWZXJzaW9uID49IFNQRUNfVkVSU0lPTl9TVVBQT1JUU19DQk9SX1FVRVVFX1RSQU5TUE9SVFxuICAgICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICAgIHJ1bklucHV0OiB7XG4gICAgICAgICAgICAgICAgICAgIGlucHV0OiB3b3JrZmxvd0FyZ3VtZW50cyxcbiAgICAgICAgICAgICAgICAgICAgZGVwbG95bWVudElkLFxuICAgICAgICAgICAgICAgICAgICB3b3JrZmxvd05hbWUsXG4gICAgICAgICAgICAgICAgICAgIHNwZWNWZXJzaW9uLFxuICAgICAgICAgICAgICAgICAgICBleGVjdXRpb25Db250ZXh0LFxuICAgICAgICAgICAgICAgICAgICAuLi5hdHRyaWJ1dGVTZWVkLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgIH0gc2F0aXNmaWVzIFdvcmtmbG93SW52b2tlUGF5bG9hZCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkZXBsb3ltZW50SWQsXG4gICAgICAgICAgICBzcGVjVmVyc2lvbixcbiAgICAgICAgICB9XG4gICAgICAgICksXG4gICAgICBdKTtcblxuICAgICAgLy8gUXVldWUgZmFpbHVyZSBpcyBhbHdheXMgZmF0YWwg4oCUIHRoZSBydW4gd2FzIG5vdCBlbnF1ZXVlZFxuICAgICAgaWYgKHF1ZXVlUmVzdWx0LnN0YXR1cyA9PT0gJ3JlamVjdGVkJykge1xuICAgICAgICB0aHJvdyBxdWV1ZVJlc3VsdC5yZWFzb247XG4gICAgICB9XG5cbiAgICAgIC8vIEhhbmRsZSBldmVudHMuY3JlYXRlIHJlc3VsdFxuICAgICAgbGV0IHJlc2lsaWVudFN0YXJ0ID0gZmFsc2U7XG4gICAgICBpZiAocnVuQ3JlYXRlZFJlc3VsdC5zdGF0dXMgPT09ICdyZWplY3RlZCcpIHtcbiAgICAgICAgY29uc3QgZXJyID0gcnVuQ3JlYXRlZFJlc3VsdC5yZWFzb247XG4gICAgICAgIGlmIChFbnRpdHlDb25mbGljdEVycm9yLmlzKGVycikpIHtcbiAgICAgICAgICAvLyA0MDk6IFRoZSBydW4gYWxyZWFkeSBleGlzdHMuIFRoaXMgY2FuIGhhcHBlbiBpbiBleHRyZW1lIGNhc2VzIHdoZXJlXG4gICAgICAgICAgLy8gdGhlIHJ1biBjcmVhdGlvbiBjYWxsIGdldHMgYSBjb2xkIHN0YXJ0IG9yIG90aGVyIHNsb3dkb3duLCBhbmQgdGhlIHF1ZXVlXG4gICAgICAgICAgLy8gKyBydW5fc3RhcnRlZCBjYWxsIGNvbXBsZXRlcyBmYXN0ZXIuIFdlIGV4cGVjdCB0aGlzIHRvIGJlIDw9MSUgb2YgY2FzZXMuXG4gICAgICAgICAgLy8gSW4gdGhpcyBjYXNlLCB3ZSBjYW4gc2FmZWx5IHJldHVybi5cbiAgICAgICAgfSBlbHNlIGlmIChpc1JldHJ5YWJsZVdvcmxkRXJyb3IoZXJyKSkge1xuICAgICAgICAgIC8vIDQyOSAoVGhyb3R0bGVFcnJvciksIDV4eCwgYW5kIHRyYW5zaWVudCB0cmFuc3BvcnQgZmFpbHVyZXNcbiAgICAgICAgICAvLyAoVFJBTlNQT1JUL1RJTUVPVVQpIGFyZSByZXRyeWFibGUg4oCUIHRoZSBydW4gd2FzIGFjY2VwdGVkIHZpYSB0aGVcbiAgICAgICAgICAvLyBxdWV1ZSBhbmQgY3JlYXRpb24gd2lsbCBiZSByZS10cmllZCBieSB0aGUgcnVudGltZSB3aGVuIGl0IGNhbGxzXG4gICAgICAgICAgLy8gcnVuX3N0YXJ0ZWQuXG4gICAgICAgICAgcmVzaWxpZW50U3RhcnQgPSB0cnVlO1xuICAgICAgICAgIHJ1bnRpbWVMb2dnZXIud2FybihcbiAgICAgICAgICAgICdSdW4gY3JlYXRpb24gZXZlbnQgZmFpbGVkLCBidXQgdGhlIHJ1biB3YXMgYWNjZXB0ZWQgdmlhIHRoZSBxdWV1ZS4gJyArXG4gICAgICAgICAgICAgICdUaGUgcnVuX2NyZWF0ZWQgZXZlbnQgd2lsbCBiZSByZS10cmllZCBhc3luYyBieSB0aGUgcnVudGltZS4nLFxuICAgICAgICAgICAgeyB3b3JrZmxvd1J1bklkOiBydW5JZCwgZXJyb3I6IGVyci5tZXNzYWdlIH1cbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gcnVuQ3JlYXRlZFJlc3VsdC52YWx1ZTtcbiAgICAgICAgLy8gQXNzZXJ0IHRoYXQgdGhlIHJ1biB3YXMgY3JlYXRlZFxuICAgICAgICBpZiAoIXJlc3VsdC5ydW4pIHtcbiAgICAgICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IoXG4gICAgICAgICAgICBcIk1pc3NpbmcgJ3J1bicgaW4gc2VydmVyIHJlc3BvbnNlIGZvciAncnVuX2NyZWF0ZWQnIGV2ZW50XCJcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVmVyaWZ5IHNlcnZlciBhY2NlcHRlZCBvdXIgcnVuSWRcbiAgICAgICAgaWYgKCF2MUNvbXBhdCAmJiByZXN1bHQucnVuLnJ1bklkICE9PSBydW5JZCkge1xuICAgICAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcihcbiAgICAgICAgICAgIGBTZXJ2ZXIgcmV0dXJuZWQgZGlmZmVyZW50IHJ1bklkIHRoYW4gcmVxdWVzdGVkOiBleHBlY3RlZCAke3J1bklkfSwgZ290ICR7cmVzdWx0LnJ1bi5ydW5JZH1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBUaGVzZSBhcmd1bWVudC1zdHJlYW0gb3BzIGFyZSBmbHVzaGVkIGluIHRoZSBiYWNrZ3JvdW5kOyB0aGUgcHJvbWlzZVxuICAgICAgLy8gaGFuZGVkIHRvIHdhaXRVbnRpbCBtdXN0IG5ldmVyIHJlamVjdCAoYW4gdW5jb25zdW1lZCB3YWl0VW50aWxcbiAgICAgIC8vIHJlamVjdGlvbiBjcmFzaGVzIHRoZSBwcm9jZXNzIGFzIHVuaGFuZGxlZFJlamVjdGlvbiksIHNvIHVuZXhwZWN0ZWRcbiAgICAgIC8vIGZhaWx1cmVzIGFyZSBsb2dnZWQgaW5zdGVhZC5cbiAgICAgIHNhZmVXYWl0VW50aWwoUHJvbWlzZS5hbGwob3BzKSwgKGVycikgPT4ge1xuICAgICAgICBydW50aW1lTG9nZ2VyLndhcm4oXG4gICAgICAgICAgJ0JhY2tncm91bmQgZmx1c2ggb2Ygd29ya2Zsb3cgYXJndW1lbnQgc3RyZWFtcyBmYWlsZWQnLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICAgICAgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgc3Bhbj8uc2V0QXR0cmlidXRlcyh7XG4gICAgICAgIC4uLkF0dHJpYnV0ZS5Xb3JrZmxvd1J1bklkKHJ1bklkKSxcbiAgICAgICAgLi4uQXR0cmlidXRlLkRlcGxveW1lbnRJZChkZXBsb3ltZW50SWQpLFxuICAgICAgICAuLi4ocnVuQ3JlYXRlZFJlc3VsdC5zdGF0dXMgPT09ICdmdWxmaWxsZWQnICYmXG4gICAgICAgIHJ1bkNyZWF0ZWRSZXN1bHQudmFsdWUucnVuXG4gICAgICAgICAgPyBBdHRyaWJ1dGUuV29ya2Zsb3dSdW5TdGF0dXMocnVuQ3JlYXRlZFJlc3VsdC52YWx1ZS5ydW4uc3RhdHVzKVxuICAgICAgICAgIDoge30pLFxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBuZXcgUnVuPFRSZXN1bHQ+KHJ1bklkLCB7IHJlc2lsaWVudFN0YXJ0IH0pO1xuICAgIH0pO1xuICB9KTtcbn1cbiJdfQ==
@@ -0,0 +1,131 @@
1
+ import type { Event, SerializedData, World } from '@workflow/world';
2
+ import type { CryptoKey } from '../encryption.js';
3
+ import { type StepLatencyTracking } from './step-latency.js';
4
+ export interface StepExecutorParams {
5
+ world: World;
6
+ workflowRunId: string;
7
+ /** Deployment that owns the workflow run, for forwarded writable streams. */
8
+ workflowDeploymentId?: string;
9
+ workflowName: string;
10
+ workflowStartedAt: number;
11
+ stepId: string;
12
+ stepName: string;
13
+ encryptionKey?: CryptoKey;
14
+ /**
15
+ * The workflow run's specVersion, used to gate payload compression.
16
+ * Step outputs/errors are only gzip-compressed when the run is marked
17
+ * as possibly containing compressed payloads (specVersion >= 5).
18
+ */
19
+ runSpecVersion?: number;
20
+ /**
21
+ * Lazy step start: the already-dehydrated step input. When provided, the
22
+ * `step_started` event carries this input so the world creates the step on
23
+ * the fly (no separate `step_created` round-trip). Set by the owned-inline
24
+ * path for the step whose `step_created` the suspension handler deferred.
25
+ * The world's atomic create-claim is the exactly-one-owner gate: losing it
26
+ * surfaces as `EntityConflictError` → `{ type: 'skipped' }`, so a handler
27
+ * that did not win the create never runs the body. Omitted on every other
28
+ * path, where the step already has a `step_created` and `step_started`
29
+ * carries no payload (the legacy contract).
30
+ */
31
+ lazyStepInput?: SerializedData;
32
+ /**
33
+ * Inline step ownership: the queue message ID of the invocation this
34
+ * executeStep call runs in (from the queue handler's meta). When set, the
35
+ * `step_started` this call sends is stamped with it — on the lazy paths
36
+ * (where `lazyStepInput` is present) and on the owned-recovery bare start
37
+ * (where it is not; the re-stamp keeps a recovered step readable as owned
38
+ * by this message, since ownership derives from the LATEST start). Wake
39
+ * replays that observe an actively-owned step suppress the immediate
40
+ * requeue and enqueue a delayed backstop instead. Omitted on the
41
+ * background-step path, whose bare start intentionally clears ownership
42
+ * (the step is queue-owned from that point).
43
+ */
44
+ ownerMessageId?: string;
45
+ /**
46
+ * Inline-delta optimization (opt-in). When provided, the cursor of the
47
+ * event log as observed by the caller *before* this step's events were
48
+ * written. It is threaded into the step-terminal `events.create` so a
49
+ * supporting World can return the delta of events written since (see
50
+ * {@link import('@workflow/world').CreateEventParams.sinceCursor}).
51
+ * Only set this when `correlationId`-based ownership guarantees this
52
+ * handler is the sole inline writer for the run on this iteration.
53
+ */
54
+ inlineDeltaSinceCursor?: string;
55
+ /**
56
+ * Force optimistic inline start regardless of
57
+ * `WORKFLOW_OPTIMISTIC_INLINE_START`. Set by turbo mode on the first delivery
58
+ * of the first invocation, where forcing it is safe: there is no concurrent
59
+ * peer handler to race the create-claim, so the body runs exactly once. Only
60
+ * meaningful together with `lazyStepInput` (a brand-new lazy step).
61
+ */
62
+ forceOptimisticStart?: boolean;
63
+ /**
64
+ * Turbo mode only: a promise that resolves once the backgrounded
65
+ * `run_started` has landed. When set, the lazy/optimistic `step_started` is
66
+ * chained on it so the step is never created before its run exists. The body
67
+ * still runs immediately against locally-synthesized state — only the network
68
+ * write waits — so the `run_started` round-trip overlaps the body. `undefined`
69
+ * outside turbo, where `run_started` was already awaited up front.
70
+ */
71
+ runReadyBarrier?: Promise<unknown>;
72
+ /**
73
+ * Latency telemetry (TTFS / STSO): eligibility and anchor timestamps decided
74
+ * by the orchestrator. When set, this executor computes the final values
75
+ * against the wall clock taken immediately before user code runs and
76
+ * attaches them to the step's terminal event. Set only for the first step of
77
+ * an inline batch, and only on first-attempt executions that qualify — see
78
+ * runtime/step-latency.ts.
79
+ */
80
+ latencyTracking?: StepLatencyTracking;
81
+ }
82
+ /**
83
+ * Inline-delta returned by a step-terminal write when the caller passed
84
+ * {@link StepExecutorParams.inlineDeltaSinceCursor} and the World supports
85
+ * the optimization. `events` are the events written strictly after that
86
+ * cursor (this step's events plus anything interleaved in-band), `cursor`
87
+ * is the position past the last one, and `hasMore` signals a further page
88
+ * (the caller then falls back to a full incremental fetch). Absent when
89
+ * the World did not return a delta.
90
+ */
91
+ export interface InlineEventDelta {
92
+ events: Event[];
93
+ cursor: string | null;
94
+ hasMore: boolean;
95
+ }
96
+ /**
97
+ * Result of a step execution attempt. The caller decides what to do
98
+ * based on the result type (e.g., queue workflow continuation, replay inline, etc.).
99
+ *
100
+ * `inlineDelta` is attached to a `completed` result when the caller
101
+ * requested it via {@link StepExecutorParams.inlineDeltaSinceCursor} and
102
+ * the World returned one. Step failures are rare and not the inline
103
+ * optimization's target, so the `failed` path leaves it to the normal
104
+ * incremental fetch.
105
+ */
106
+ export type StepExecutionResult = {
107
+ type: 'completed';
108
+ hasPendingOps?: boolean;
109
+ inlineDelta?: InlineEventDelta;
110
+ } | {
111
+ type: 'failed';
112
+ } | {
113
+ type: 'retry';
114
+ timeoutSeconds: number;
115
+ } | {
116
+ type: 'skipped';
117
+ } | {
118
+ type: 'gone';
119
+ } | {
120
+ type: 'throttled';
121
+ timeoutSeconds: number;
122
+ };
123
+ /**
124
+ * Executes a single step: creates step_started event, hydrates input,
125
+ * runs the step function, creates step_completed/step_failed/step_retrying events.
126
+ *
127
+ * Does NOT queue workflow continuation messages — the caller decides what to do next.
128
+ * Used by both the V1 step handler and the V2 combined handler.
129
+ */
130
+ export declare function executeStep(params: StepExecutorParams): Promise<StepExecutionResult>;
131
+ //# sourceMappingURL=step-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-executor.d.ts","sourceRoot":"","sources":["../../src/runtime/step-executor.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAQ,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAK1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AA0BlD,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,mBAAmB,CAAC;AA0B3B,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,KAAK,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,cAAc,CAAC;IAC/B;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;OAQG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,mBAAmB,CAAC;CACvC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC,GACD;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,mBAAmB,CAAC,CAy6B9B"}