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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) 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 +33 -1
  5. package/dist/capabilities.d.ts.map +1 -1
  6. package/dist/capabilities.js +71 -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 +109 -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 +149 -0
  22. package/dist/correlation-id.d.ts +109 -0
  23. package/dist/correlation-id.d.ts.map +1 -0
  24. package/dist/correlation-id.js +139 -0
  25. package/dist/create-hook.d.ts +62 -4
  26. package/dist/create-hook.d.ts.map +1 -1
  27. package/dist/create-hook.js +4 -3
  28. package/dist/define-hook.d.ts.map +1 -1
  29. package/dist/define-hook.js +20 -5
  30. package/dist/describe-error.d.ts +70 -0
  31. package/dist/describe-error.d.ts.map +1 -0
  32. package/dist/describe-error.js +189 -0
  33. package/dist/encryption.d.ts +37 -3
  34. package/dist/encryption.d.ts.map +1 -1
  35. package/dist/encryption.js +97 -31
  36. package/dist/events-consumer.d.ts +26 -1
  37. package/dist/events-consumer.d.ts.map +1 -1
  38. package/dist/events-consumer.js +105 -18
  39. package/dist/flushable-stream.d.ts +65 -10
  40. package/dist/flushable-stream.d.ts.map +1 -1
  41. package/dist/flushable-stream.js +131 -18
  42. package/dist/global.d.ts +37 -1
  43. package/dist/global.d.ts.map +1 -1
  44. package/dist/global.js +21 -3
  45. package/dist/index.d.ts +1 -0
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +2 -1
  48. package/dist/log-format.d.ts +25 -0
  49. package/dist/log-format.d.ts.map +1 -0
  50. package/dist/log-format.js +250 -0
  51. package/dist/logger.d.ts +29 -30
  52. package/dist/logger.d.ts.map +1 -1
  53. package/dist/logger.js +82 -32
  54. package/dist/private.d.ts +178 -9
  55. package/dist/private.d.ts.map +1 -1
  56. package/dist/private.js +273 -9
  57. package/dist/replay-payload-cache.d.ts +68 -0
  58. package/dist/replay-payload-cache.d.ts.map +1 -0
  59. package/dist/replay-payload-cache.js +160 -0
  60. package/dist/runtime/compute-instance.d.ts +12 -0
  61. package/dist/runtime/compute-instance.d.ts.map +1 -0
  62. package/dist/runtime/compute-instance.js +13 -0
  63. package/dist/runtime/constants.d.ts +237 -0
  64. package/dist/runtime/constants.d.ts.map +1 -1
  65. package/dist/runtime/constants.js +405 -15
  66. package/dist/runtime/count-step-started-events.d.ts +52 -0
  67. package/dist/runtime/count-step-started-events.d.ts.map +1 -0
  68. package/dist/runtime/count-step-started-events.js +72 -0
  69. package/dist/runtime/deployment-guard.d.ts +99 -0
  70. package/dist/runtime/deployment-guard.d.ts.map +1 -0
  71. package/dist/runtime/deployment-guard.js +154 -0
  72. package/dist/runtime/get-port-lazy.d.ts +25 -0
  73. package/dist/runtime/get-port-lazy.d.ts.map +1 -0
  74. package/dist/runtime/get-port-lazy.js +92 -0
  75. package/dist/runtime/get-world-lazy.d.ts +23 -0
  76. package/dist/runtime/get-world-lazy.d.ts.map +1 -0
  77. package/dist/runtime/get-world-lazy.js +46 -0
  78. package/dist/runtime/helpers.d.ts +219 -10
  79. package/dist/runtime/helpers.d.ts.map +1 -1
  80. package/dist/runtime/helpers.js +414 -40
  81. package/dist/runtime/quickjs-assets.generated.d.ts +14 -0
  82. package/dist/runtime/quickjs-assets.generated.d.ts.map +1 -0
  83. package/dist/runtime/quickjs-assets.generated.js +30 -0
  84. package/dist/runtime/quickjs-entrypoint.d.ts +124 -0
  85. package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -0
  86. package/dist/runtime/quickjs-entrypoint.js +1429 -0
  87. package/dist/runtime/quickjs-runtime.d.ts +193 -0
  88. package/dist/runtime/quickjs-runtime.d.ts.map +1 -0
  89. package/dist/runtime/quickjs-runtime.js +1944 -0
  90. package/dist/runtime/replay-budget.d.ts +98 -0
  91. package/dist/runtime/replay-budget.d.ts.map +1 -0
  92. package/dist/runtime/replay-budget.js +192 -0
  93. package/dist/runtime/replay-recovery-reporter.d.ts +36 -0
  94. package/dist/runtime/replay-recovery-reporter.d.ts.map +1 -0
  95. package/dist/runtime/replay-recovery-reporter.js +64 -0
  96. package/dist/runtime/resume-hook.d.ts +27 -4
  97. package/dist/runtime/resume-hook.d.ts.map +1 -1
  98. package/dist/runtime/resume-hook.js +448 -76
  99. package/dist/runtime/run-id-time.d.ts +19 -0
  100. package/dist/runtime/run-id-time.d.ts.map +1 -0
  101. package/dist/runtime/run-id-time.js +42 -0
  102. package/dist/runtime/run.d.ts +8 -2
  103. package/dist/runtime/run.d.ts.map +1 -1
  104. package/dist/runtime/run.js +62 -15
  105. package/dist/runtime/runs.d.ts +54 -3
  106. package/dist/runtime/runs.d.ts.map +1 -1
  107. package/dist/runtime/runs.js +117 -10
  108. package/dist/runtime/start.d.ts +70 -1
  109. package/dist/runtime/start.d.ts.map +1 -1
  110. package/dist/runtime/start.js +312 -54
  111. package/dist/runtime/step-executor.d.ts +177 -0
  112. package/dist/runtime/step-executor.d.ts.map +1 -0
  113. package/dist/runtime/step-executor.js +949 -0
  114. package/dist/runtime/step-latency.d.ts +197 -0
  115. package/dist/runtime/step-latency.d.ts.map +1 -0
  116. package/dist/runtime/step-latency.js +207 -0
  117. package/dist/runtime/step-ownership.d.ts +72 -0
  118. package/dist/runtime/step-ownership.d.ts.map +1 -0
  119. package/dist/runtime/step-ownership.js +114 -0
  120. package/dist/runtime/step-single-flight.d.ts +12 -0
  121. package/dist/runtime/step-single-flight.d.ts.map +1 -0
  122. package/dist/runtime/step-single-flight.js +69 -0
  123. package/dist/runtime/suspension-handler.d.ts +102 -7
  124. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  125. package/dist/runtime/suspension-handler.js +439 -140
  126. package/dist/runtime/vm-mode.d.ts +44 -0
  127. package/dist/runtime/vm-mode.d.ts.map +1 -0
  128. package/dist/runtime/vm-mode.js +62 -0
  129. package/dist/runtime/vm-serde-bundle.generated.d.ts +14 -0
  130. package/dist/runtime/vm-serde-bundle.generated.d.ts.map +1 -0
  131. package/dist/runtime/vm-serde-bundle.generated.js +16 -0
  132. package/dist/runtime/wait-continuation.d.ts +84 -0
  133. package/dist/runtime/wait-continuation.d.ts.map +1 -0
  134. package/dist/runtime/wait-continuation.js +105 -0
  135. package/dist/runtime/wait-until.d.ts +18 -0
  136. package/dist/runtime/wait-until.d.ts.map +1 -0
  137. package/dist/runtime/wait-until.js +42 -0
  138. package/dist/runtime/world-compatibility.d.ts +5 -0
  139. package/dist/runtime/world-compatibility.d.ts.map +1 -0
  140. package/dist/runtime/world-compatibility.js +12 -0
  141. package/dist/runtime/world-init.d.ts +50 -0
  142. package/dist/runtime/world-init.d.ts.map +1 -0
  143. package/dist/runtime/world-init.js +50 -0
  144. package/dist/runtime/world.d.ts +14 -2
  145. package/dist/runtime/world.d.ts.map +1 -1
  146. package/dist/runtime/world.js +101 -26
  147. package/dist/runtime.d.ts +17 -12
  148. package/dist/runtime.d.ts.map +1 -1
  149. package/dist/runtime.js +3078 -327
  150. package/dist/schemas.d.ts +1 -1
  151. package/dist/schemas.d.ts.map +1 -1
  152. package/dist/schemas.js +1 -1
  153. package/dist/sealed-box.d.ts +167 -0
  154. package/dist/sealed-box.d.ts.map +1 -0
  155. package/dist/sealed-box.js +571 -0
  156. package/dist/serialization/client.d.ts +17 -0
  157. package/dist/serialization/client.d.ts.map +1 -0
  158. package/dist/serialization/client.js +48 -0
  159. package/dist/serialization/codec-devalue-vm.d.ts +9 -0
  160. package/dist/serialization/codec-devalue-vm.d.ts.map +1 -0
  161. package/dist/serialization/codec-devalue-vm.js +137 -0
  162. package/dist/serialization/codec-devalue.d.ts +14 -0
  163. package/dist/serialization/codec-devalue.d.ts.map +1 -0
  164. package/dist/serialization/codec-devalue.js +105 -0
  165. package/dist/serialization/codec.d.ts +125 -0
  166. package/dist/serialization/codec.d.ts.map +1 -0
  167. package/dist/serialization/codec.js +17 -0
  168. package/dist/serialization/compression.d.ts +104 -0
  169. package/dist/serialization/compression.d.ts.map +1 -0
  170. package/dist/serialization/compression.js +260 -0
  171. package/dist/serialization/encryption.d.ts +134 -0
  172. package/dist/serialization/encryption.d.ts.map +1 -0
  173. package/dist/serialization/encryption.js +186 -0
  174. package/dist/serialization/errors.d.ts +34 -0
  175. package/dist/serialization/errors.d.ts.map +1 -0
  176. package/dist/serialization/errors.js +59 -0
  177. package/dist/serialization/format.d.ts +60 -0
  178. package/dist/serialization/format.d.ts.map +1 -0
  179. package/dist/serialization/format.js +97 -0
  180. package/dist/serialization/hardened.d.ts +155 -0
  181. package/dist/serialization/hardened.d.ts.map +1 -0
  182. package/dist/serialization/hardened.js +523 -0
  183. package/dist/serialization/index.d.ts +20 -0
  184. package/dist/serialization/index.d.ts.map +1 -0
  185. package/dist/serialization/index.js +22 -0
  186. package/dist/serialization/reducers/class-vm.d.ts +20 -0
  187. package/dist/serialization/reducers/class-vm.d.ts.map +1 -0
  188. package/dist/serialization/reducers/class-vm.js +77 -0
  189. package/dist/serialization/reducers/class.d.ts +11 -0
  190. package/dist/serialization/reducers/class.d.ts.map +1 -0
  191. package/dist/serialization/reducers/class.js +73 -0
  192. package/dist/serialization/reducers/common-vm.d.ts +15 -0
  193. package/dist/serialization/reducers/common-vm.d.ts.map +1 -0
  194. package/dist/serialization/reducers/common-vm.js +579 -0
  195. package/dist/serialization/reducers/common.d.ts +16 -0
  196. package/dist/serialization/reducers/common.d.ts.map +1 -0
  197. package/dist/serialization/reducers/common.js +478 -0
  198. package/dist/serialization/reducers/step-function-vm.d.ts +44 -0
  199. package/dist/serialization/reducers/step-function-vm.d.ts.map +1 -0
  200. package/dist/serialization/reducers/step-function-vm.js +97 -0
  201. package/dist/serialization/reducers/step-function.d.ts +35 -0
  202. package/dist/serialization/reducers/step-function.d.ts.map +1 -0
  203. package/dist/serialization/reducers/step-function.js +104 -0
  204. package/dist/serialization/step.d.ts +17 -0
  205. package/dist/serialization/step.d.ts.map +1 -0
  206. package/dist/serialization/step.js +48 -0
  207. package/dist/serialization/types.d.ts +273 -0
  208. package/dist/serialization/types.d.ts.map +1 -0
  209. package/dist/serialization/types.js +35 -0
  210. package/dist/serialization/vm-bundle-entry.d.ts +12 -0
  211. package/dist/serialization/vm-bundle-entry.d.ts.map +1 -0
  212. package/dist/serialization/vm-bundle-entry.js +58 -0
  213. package/dist/serialization/workflow-vm.d.ts +24 -0
  214. package/dist/serialization/workflow-vm.d.ts.map +1 -0
  215. package/dist/serialization/workflow-vm.js +66 -0
  216. package/dist/serialization/workflow.d.ts +29 -0
  217. package/dist/serialization/workflow.d.ts.map +1 -0
  218. package/dist/serialization/workflow.js +54 -0
  219. package/dist/serialization-format.d.ts +60 -4
  220. package/dist/serialization-format.d.ts.map +1 -1
  221. package/dist/serialization-format.js +276 -56
  222. package/dist/serialization.d.ts +374 -221
  223. package/dist/serialization.d.ts.map +1 -1
  224. package/dist/serialization.js +2300 -783
  225. package/dist/set-attributes.d.ts +13 -0
  226. package/dist/set-attributes.d.ts.map +1 -0
  227. package/dist/set-attributes.js +60 -0
  228. package/dist/sleep.d.ts.map +1 -1
  229. package/dist/sleep.js +3 -2
  230. package/dist/source-map.d.ts +25 -0
  231. package/dist/source-map.d.ts.map +1 -1
  232. package/dist/source-map.js +148 -10
  233. package/dist/step/context-storage.d.ts +61 -2
  234. package/dist/step/context-storage.d.ts.map +1 -1
  235. package/dist/step/context-storage.js +7 -5
  236. package/dist/step/get-closure-vars.d.ts.map +1 -1
  237. package/dist/step/get-closure-vars.js +3 -2
  238. package/dist/step/get-step-metadata.d.ts.map +1 -1
  239. package/dist/step/get-step-metadata.js +3 -2
  240. package/dist/step/get-workflow-metadata.d.ts.map +1 -1
  241. package/dist/step/get-workflow-metadata.js +3 -2
  242. package/dist/step/writable-stream.d.ts.map +1 -1
  243. package/dist/step/writable-stream.js +71 -7
  244. package/dist/step.d.ts.map +1 -1
  245. package/dist/step.js +226 -30
  246. package/dist/symbols.d.ts +54 -0
  247. package/dist/symbols.d.ts.map +1 -1
  248. package/dist/symbols.js +55 -1
  249. package/dist/telemetry/semantic-conventions.d.ts +242 -2
  250. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  251. package/dist/telemetry/semantic-conventions.js +173 -1
  252. package/dist/telemetry.d.ts +73 -0
  253. package/dist/telemetry.d.ts.map +1 -1
  254. package/dist/telemetry.js +153 -16
  255. package/dist/types.d.ts +6 -0
  256. package/dist/types.d.ts.map +1 -1
  257. package/dist/types.js +23 -1
  258. package/dist/util.d.ts +16 -6
  259. package/dist/util.d.ts.map +1 -1
  260. package/dist/util.js +25 -16
  261. package/dist/version.d.ts +1 -1
  262. package/dist/version.d.ts.map +1 -1
  263. package/dist/version.js +2 -2
  264. package/dist/vm/index.d.ts.map +1 -1
  265. package/dist/vm/index.js +77 -9
  266. package/dist/vm/script-cache.d.ts +28 -0
  267. package/dist/vm/script-cache.d.ts.map +1 -0
  268. package/dist/vm/script-cache.js +140 -0
  269. package/dist/workflow/abort-controller.d.ts +65 -0
  270. package/dist/workflow/abort-controller.d.ts.map +1 -0
  271. package/dist/workflow/abort-controller.js +314 -0
  272. package/dist/workflow/attribute-dispatcher.d.ts +6 -0
  273. package/dist/workflow/attribute-dispatcher.d.ts.map +1 -0
  274. package/dist/workflow/attribute-dispatcher.js +48 -0
  275. package/dist/workflow/create-hook.d.ts.map +1 -1
  276. package/dist/workflow/create-hook.js +25 -3
  277. package/dist/workflow/define-hook.d.ts +1 -1
  278. package/dist/workflow/define-hook.d.ts.map +1 -1
  279. package/dist/workflow/define-hook.js +8 -4
  280. package/dist/workflow/get-workflow-metadata.d.ts.map +1 -1
  281. package/dist/workflow/get-workflow-metadata.js +14 -3
  282. package/dist/workflow/hook.d.ts.map +1 -1
  283. package/dist/workflow/hook.js +303 -37
  284. package/dist/workflow/index.d.ts +1 -0
  285. package/dist/workflow/index.d.ts.map +1 -1
  286. package/dist/workflow/index.js +5 -3
  287. package/dist/workflow/set-attributes.d.ts +68 -0
  288. package/dist/workflow/set-attributes.d.ts.map +1 -0
  289. package/dist/workflow/set-attributes.js +60 -0
  290. package/dist/workflow/sleep.d.ts.map +1 -1
  291. package/dist/workflow/sleep.js +58 -9
  292. package/dist/workflow/world-init-stub.d.ts +15 -0
  293. package/dist/workflow/world-init-stub.d.ts.map +1 -0
  294. package/dist/workflow/world-init-stub.js +15 -0
  295. package/dist/workflow.d.ts +69 -3
  296. package/dist/workflow.d.ts.map +1 -1
  297. package/dist/workflow.js +791 -554
  298. package/docs/api-reference/create-hook.mdx +79 -0
  299. package/docs/api-reference/create-webhook.mdx +1 -0
  300. package/docs/api-reference/define-hook.mdx +26 -24
  301. package/docs/api-reference/fatal-error.mdx +29 -7
  302. package/docs/api-reference/fetch.mdx +8 -4
  303. package/docs/api-reference/index.mdx +3 -0
  304. package/docs/api-reference/set-attributes.mdx +61 -0
  305. package/docs/api-reference/sleep.mdx +1 -1
  306. package/docs/foundations/cancellation.mdx +459 -0
  307. package/docs/foundations/errors-and-retries.mdx +7 -3
  308. package/docs/foundations/hooks.mdx +29 -0
  309. package/docs/foundations/idempotency.mdx +243 -11
  310. package/docs/foundations/index.mdx +1 -23
  311. package/docs/foundations/meta.json +3 -1
  312. package/docs/foundations/serialization.mdx +77 -41
  313. package/docs/foundations/starting-workflows.mdx +79 -2
  314. package/docs/foundations/streaming.mdx +14 -23
  315. package/docs/foundations/versioning.mdx +263 -0
  316. package/docs/how-it-works/cancellation.mdx +287 -0
  317. package/docs/how-it-works/code-transform.mdx +21 -17
  318. package/docs/how-it-works/encryption.mdx +5 -5
  319. package/docs/how-it-works/event-sourcing.mdx +6 -6
  320. package/docs/how-it-works/framework-integrations.mdx +96 -337
  321. package/docs/how-it-works/meta.json +2 -1
  322. package/package.json +31 -13
  323. package/dist/runtime/step-handler.d.ts +0 -2
  324. package/dist/runtime/step-handler.d.ts.map +0 -1
  325. package/dist/runtime/step-handler.js +0 -678
@@ -1,10 +1,13 @@
1
- import { HealthCheckPayloadSchema, SPEC_VERSION_CURRENT, SPEC_VERSION_LEGACY, } from '@workflow/world';
1
+ import { PreconditionFailedError, RUN_ERROR_CODES, WorkflowWorldError, } from '@workflow/errors';
2
+ import { getQueueTopicPrefix, HealthCheckPayloadSchema, HOOK_RESUME_INPUT_VERSION, resolveQueueNamespace, SPEC_VERSION_CURRENT, SPEC_VERSION_LEGACY, ulidToDate, } from '@workflow/world';
2
3
  import { monotonicFactory } from 'ulid';
3
4
  import { runtimeLogger } from '../logger.js';
5
+ import { bytesToBase64, deriveRunKeyPair } from '../sealed-box.js';
6
+ import { deriveRunPayloadKeys, } from '../serialization/encryption.js';
4
7
  import * as Attribute from '../telemetry/semantic-conventions.js';
5
8
  import { getSpanKind, trace } from '../telemetry.js';
6
9
  import { version as workflowCoreVersion } from '../version.js';
7
- import { getWorld } from './world.js';
10
+ import { getWorldLazy } from './get-world-lazy.js';
8
11
  /** Default timeout for health checks in milliseconds */
9
12
  const DEFAULT_HEALTH_CHECK_TIMEOUT = 30_000;
10
13
  /**
@@ -18,11 +21,12 @@ const SAFE_WORKFLOW_NAME_PATTERN = /^[a-zA-Z0-9_\-./@]+$/;
18
21
  * Ensures the workflow name only contains safe characters before
19
22
  * interpolating it into the queue name string.
20
23
  */
21
- export function getWorkflowQueueName(workflowName) {
24
+ export function getWorkflowQueueName(workflowName, namespace) {
22
25
  if (!SAFE_WORKFLOW_NAME_PATTERN.test(workflowName)) {
23
26
  throw new Error(`Invalid workflow name "${workflowName}": must only contain alphanumeric characters, underscores, hyphens, dots, forward slashes, or at signs`);
24
27
  }
25
- return `__wkf_workflow_${workflowName}`;
28
+ const prefix = getQueueTopicPrefix('workflow', resolveQueueNamespace(namespace));
29
+ return `${prefix}${workflowName}`;
26
30
  }
27
31
  const generateId = monotonicFactory();
28
32
  /**
@@ -56,17 +60,45 @@ function generateHealthCheckRunId(correlationId) {
56
60
  * The caller can listen to this stream to get the health check response.
57
61
  *
58
62
  * @param healthCheck - The parsed health check payload
59
- * @param endpoint - Which endpoint is responding ('workflow' or 'step')
60
63
  */
61
- export async function handleHealthCheckMessage(healthCheck, endpoint, worldSpecVersion) {
62
- const world = await getWorld();
64
+ export async function handleHealthCheckMessage(healthCheck, worldSpecVersion) {
65
+ const world = await getWorldLazy();
63
66
  const streamName = getHealthCheckStreamName(healthCheck.correlationId);
67
+ // When the probe names a run the caller is about to create, publish that
68
+ // run's public key. We are executing inside the target deployment, so its
69
+ // key material is available locally (no API call), and the caller can then
70
+ // seal the workflow arguments straight from this response rather than
71
+ // making a separate key-lookup request.
72
+ //
73
+ // Only a *public* key may travel this way: the probe response stream is
74
+ // deliberately unauthenticated, so anything secret would be exposed.
75
+ // Best-effort — a failure here must not fail the health check itself, which
76
+ // callers also rely on for plain capability detection.
77
+ let encryptionPublicKey;
78
+ if (healthCheck.runId) {
79
+ try {
80
+ const rawKey = await world.getEncryptionKeyForRun?.(healthCheck.runId);
81
+ if (rawKey) {
82
+ encryptionPublicKey = bytesToBase64((await deriveRunKeyPair(rawKey)).publicKey);
83
+ }
84
+ }
85
+ catch (err) {
86
+ runtimeLogger.warn('Health check could not derive a run public key; the caller will fall back to a key lookup', {
87
+ correlationId: healthCheck.correlationId,
88
+ error: err instanceof Error ? err.message : String(err),
89
+ });
90
+ }
91
+ }
64
92
  const response = JSON.stringify({
65
93
  healthy: true,
66
- endpoint,
67
94
  correlationId: healthCheck.correlationId,
68
95
  specVersion: worldSpecVersion ?? SPEC_VERSION_CURRENT,
69
96
  workflowCoreVersion,
97
+ // We are executing inside the target deployment, so this constant reflects
98
+ // the *consumer's* hook-resume protocol version — exactly what a
99
+ // cross-deployment caller needs to gate its parallel resume path on.
100
+ hookResumeInputVersion: HOOK_RESUME_INPUT_VERSION,
101
+ ...(encryptionPublicKey ? { encryptionPublicKey } : {}),
70
102
  timestamp: Date.now(),
71
103
  });
72
104
  // Use a deterministic fake runId derived from the correlationId so that
@@ -77,13 +109,12 @@ export async function handleHealthCheckMessage(healthCheck, endpoint, worldSpecV
77
109
  }
78
110
  /**
79
111
  * Performs a health check by sending a message through the queue pipeline
80
- * and verifying it is processed by the specified endpoint.
112
+ * and verifying it is processed by the combined workflow endpoint.
81
113
  *
82
114
  * This function bypasses Deployment Protection on Vercel because it goes
83
115
  * through the queue infrastructure rather than direct HTTP.
84
116
  *
85
117
  * @param world - The World instance to use for the health check
86
- * @param endpoint - Which endpoint to health check: 'workflow' or 'step'
87
118
  * @param options - Optional configuration for the health check
88
119
  * @returns Promise resolving to health check result
89
120
  */
@@ -96,6 +127,24 @@ const HEALTH_CHECK_READ_TIMEOUT = 500;
96
127
  * Read chunks from a stream with a timeout per read operation.
97
128
  * Returns { chunks, timedOut } where timedOut indicates if a read timed out.
98
129
  */
130
+ /**
131
+ * Race a promise against a deadline. Rejects with a timeout error when the
132
+ * deadline elapses first. Used to bound `world.streams.get()` inside the
133
+ * health-check poll loop: some worlds hold that request open until the
134
+ * stream has data (e.g. workflow-server holds unwritten streams open for
135
+ * ~2 minutes), which would otherwise blow through the configured health
136
+ * check timeout — the `while` condition is only re-checked between
137
+ * iterations.
138
+ */
139
+ function withDeadline(promise, ms) {
140
+ let timer;
141
+ return Promise.race([
142
+ promise,
143
+ new Promise((_, reject) => {
144
+ timer = setTimeout(() => reject(new Error(`Operation timed out after ${ms}ms`)), ms);
145
+ }),
146
+ ]).finally(() => clearTimeout(timer));
147
+ }
99
148
  async function readStreamWithTimeout(reader, readTimeout) {
100
149
  const chunks = [];
101
150
  let done = false;
@@ -154,18 +203,37 @@ function parseHealthCheckResponse(chunks) {
154
203
  if (typeof r.specVersion === 'number') {
155
204
  parsed.specVersion = r.specVersion;
156
205
  }
206
+ if (typeof r.workflowCoreVersion === 'string') {
207
+ parsed.workflowCoreVersion = r.workflowCoreVersion;
208
+ }
209
+ if (typeof r.encryptionPublicKey === 'string') {
210
+ parsed.encryptionPublicKey = r.encryptionPublicKey;
211
+ }
212
+ if (typeof r.hookResumeInputVersion === 'number') {
213
+ parsed.hookResumeInputVersion = r.hookResumeInputVersion;
214
+ }
157
215
  return parsed;
158
216
  }
159
- export async function healthCheck(world, endpoint, options) {
217
+ export async function healthCheck(world, options) {
160
218
  const timeout = options?.timeout ?? DEFAULT_HEALTH_CHECK_TIMEOUT;
161
- const correlationId = generateId();
219
+ // Use the world's ID generator when available so the correlationId is a
220
+ // region-tagged ULID. The health-check response is delivered over a stream
221
+ // whose name embeds this correlationId; under platform-directed routing the
222
+ // reader and the responding endpoint can be served from different physical
223
+ // regions, so the region must be encoded in the ID itself for both sides to
224
+ // resolve the same (region-pinned) backend. Falls back to a plain ULID for
225
+ // worlds that don't tag IDs (e.g. local), which resolve to the default
226
+ // region on both sides.
227
+ const correlationId = world.createRunId?.() ?? generateId();
162
228
  const streamName = getHealthCheckStreamName(correlationId);
163
- const queueName = endpoint === 'workflow'
164
- ? '__wkf_workflow_health_check'
165
- : '__wkf_step_health_check';
229
+ const queueName = `${getQueueTopicPrefix('workflow', resolveQueueNamespace(options?.namespace))}health_check`;
166
230
  const startTime = Date.now();
167
231
  try {
168
- await world.queue(queueName, { __healthCheck: true, correlationId }, {
232
+ await world.queue(queueName, {
233
+ __healthCheck: true,
234
+ correlationId,
235
+ ...(options?.runId ? { runId: options.runId } : {}),
236
+ }, {
169
237
  // Use JSON transport so the health check works against both
170
238
  // old (JSON-only) and new (dual) deployments.
171
239
  specVersion: SPEC_VERSION_LEGACY,
@@ -173,7 +241,8 @@ export async function healthCheck(world, endpoint, options) {
173
241
  });
174
242
  while (Date.now() - startTime < timeout) {
175
243
  try {
176
- const stream = await world.streams.get(generateHealthCheckRunId(correlationId), streamName);
244
+ const remainingMs = timeout - (Date.now() - startTime);
245
+ const stream = await withDeadline(world.streams.get(generateHealthCheckRunId(correlationId), streamName), remainingMs);
177
246
  const reader = stream.getReader();
178
247
  const { chunks, timedOut } = await readStreamWithTimeout(reader, HEALTH_CHECK_READ_TIMEOUT);
179
248
  if (timedOut) {
@@ -211,60 +280,314 @@ export async function healthCheck(world, endpoint, options) {
211
280
  };
212
281
  }
213
282
  }
283
+ function eventPaginationContractError(runId, message) {
284
+ return new WorkflowWorldError(`Event pagination ${message} for workflow run "${runId}".`, { code: RUN_ERROR_CODES.WORLD_CONTRACT_ERROR });
285
+ }
286
+ function recordRequestedEventCursor(runId, cursor, requestedCursors) {
287
+ if (!cursor) {
288
+ return;
289
+ }
290
+ if (requestedCursors.has(cursor)) {
291
+ throw eventPaginationContractError(runId, 'did not advance');
292
+ }
293
+ requestedCursors.add(cursor);
294
+ }
295
+ /**
296
+ * Appends events whose IDs are not already present in `target`.
297
+ *
298
+ * Pass the IDs currently present in `target` when appending repeatedly to the
299
+ * same array. The set is updated alongside `target`.
300
+ *
301
+ * Events are appended in the order the World returned them, and are not
302
+ * re-sorted: a World's canonical order is its own, and the runtime cannot
303
+ * reproduce it from event ids alone. `world-vercel` orders by event id, while
304
+ * `world-local` orders by `(createdAt, eventId)` and deliberately re-mints keys
305
+ * so that the two diverge. Every append source is already in canonical order
306
+ * relative to the tail (a cursor-delimited page, or a write-response delta), so
307
+ * receipt order is the order to keep. Nothing downstream may assume the tail is
308
+ * the newest event — see {@link latestEventStateUpdatedAt}.
309
+ */
310
+ export function appendUniqueEvents(target, events, targetIds) {
311
+ if (events.length === 0) {
312
+ return;
313
+ }
314
+ const ids = targetIds ?? new Set(target.map((event) => event.eventId));
315
+ for (const event of events) {
316
+ if (ids.has(event.eventId)) {
317
+ continue;
318
+ }
319
+ ids.add(event.eventId);
320
+ target.push(event);
321
+ }
322
+ }
214
323
  /**
215
- * Loads all workflow run events by iterating through all pages of paginated results.
216
- * This ensures that *all* events are loaded into memory before running the workflow.
217
- * Events must be in chronological order (ascending) for proper workflow replay.
324
+ * Inserts `event` into `target` at the position that keeps `target` ordered by
325
+ * ascending `eventId`, or no-ops if an event with the same `eventId` is already
326
+ * present (idempotent).
327
+ *
328
+ * `preloadedEvents` is loaded `sortOrder: 'asc'` and is never re-sorted
329
+ * client-side, so a `hook_received` spliced in by the lazy-resume consumer must
330
+ * land in `eventId` order — a plain `push` would place a late-committing
331
+ * earlier event after events that sort before it, corrupting replay. Event IDs
332
+ * are ULIDs, so lexicographic string order matches commit order.
218
333
  */
219
- export async function getAllWorkflowRunEvents(runId) {
220
- return trace('workflow.loadEvents', async (span) => {
334
+ export function insertEventByEventId(target, event) {
335
+ // Linear scan from the end: the spliced event is almost always the newest
336
+ // (it sorts at or near the tail), so this finds the slot in O(1)–O(k) for the
337
+ // common case while still handling an out-of-order late arrival correctly.
338
+ let i = target.length;
339
+ while (i > 0) {
340
+ const existing = target[i - 1];
341
+ if (existing.eventId === event.eventId) {
342
+ // Already present — keep the splice idempotent.
343
+ return;
344
+ }
345
+ if (existing.eventId < event.eventId) {
346
+ break;
347
+ }
348
+ i--;
349
+ }
350
+ target.splice(i, 0, event);
351
+ }
352
+ function assertEventPaginationProgress(runId, hasMore, cursor, requestedCursors) {
353
+ if (!hasMore) {
354
+ return;
355
+ }
356
+ if (cursor === null) {
357
+ throw eventPaginationContractError(runId, 'returned more pages without a cursor');
358
+ }
359
+ if (requestedCursors.has(cursor)) {
360
+ throw eventPaginationContractError(runId, 'repeated a cursor');
361
+ }
362
+ }
363
+ function shouldRetryWithoutEventCursor(error, cursor, alreadyRetried) {
364
+ return (cursor !== null &&
365
+ !alreadyRetried &&
366
+ WorkflowWorldError.is(error) &&
367
+ error.status === 400);
368
+ }
369
+ /**
370
+ * Loads workflow run events by iterating through all pages of paginated
371
+ * results. Events are returned in chronological (ascending) order for
372
+ * deterministic workflow replay.
373
+ *
374
+ * @param runId - The workflow run ID.
375
+ * @param afterCursor - If provided, only events after this cursor are
376
+ * returned (incremental load). If omitted, all events are returned.
377
+ * The returned cursor can be passed back in on a subsequent call for
378
+ * incremental loading.
379
+ */
380
+ export async function loadWorkflowRunEvents(runId, afterCursor) {
381
+ const incremental = afterCursor !== undefined;
382
+ return trace(incremental ? 'workflow.loadNewEvents' : 'workflow.loadEvents', async (span) => {
221
383
  span?.setAttributes({
222
384
  ...Attribute.WorkflowRunId(runId),
223
385
  });
224
- const allEvents = [];
225
- let cursor = null;
386
+ const loadedEvents = [];
387
+ const loadedEventIds = new Set();
388
+ const requestedCursors = new Set();
389
+ let cursor = afterCursor ?? null;
226
390
  let hasMore = true;
227
391
  let pagesLoaded = 0;
228
- const world = await getWorld();
392
+ let retriedWithoutCursor = false;
393
+ const world = await getWorldLazy();
229
394
  const loadStart = Date.now();
230
395
  while (hasMore) {
231
396
  // TODO: we're currently loading all the data with resolveRef behaviour. We need to update this
232
397
  // to lazyload the data from the world instead so that we can optimize and make the event log loading
233
398
  // much faster and memory efficient
234
399
  const pageStart = Date.now();
235
- const response = await world.events.list({
236
- runId,
237
- pagination: {
238
- sortOrder: 'asc', // Required: events must be in chronological order for replay
239
- cursor: cursor ?? undefined,
240
- },
241
- });
242
- allEvents.push(...response.data);
400
+ const requestedCursor = cursor;
401
+ recordRequestedEventCursor(runId, requestedCursor, requestedCursors);
402
+ let response;
403
+ try {
404
+ response = await world.events.list({
405
+ runId,
406
+ pagination: {
407
+ sortOrder: 'asc',
408
+ cursor: requestedCursor ?? undefined,
409
+ },
410
+ });
411
+ }
412
+ catch (error) {
413
+ if (shouldRetryWithoutEventCursor(error, requestedCursor, retriedWithoutCursor)) {
414
+ runtimeLogger.warn('Event cursor was rejected; retrying with a full event reload.', { workflowRunId: runId });
415
+ loadedEvents.length = 0;
416
+ loadedEventIds.clear();
417
+ requestedCursors.clear();
418
+ cursor = null;
419
+ retriedWithoutCursor = true;
420
+ continue;
421
+ }
422
+ throw error;
423
+ }
424
+ appendUniqueEvents(loadedEvents, response.data, loadedEventIds);
243
425
  hasMore = response.hasMore;
244
- cursor = response.cursor;
426
+ assertEventPaginationProgress(runId, hasMore, response.cursor, requestedCursors);
427
+ // Preserve the last non-null cursor across pages. A World may
428
+ // legitimately return `{ data: [], cursor: null, hasMore: false }`
429
+ // on a trailing empty page — for example when the previous page's
430
+ // underlying DB query hit the limit exactly and returned a
431
+ // `LastEvaluatedKey` "just in case". Overwriting with that null
432
+ // would lose the position past the last real event we loaded and
433
+ // force the runtime into the "no cursor after initial load" full-
434
+ // reload fallback on every subsequent replay iteration.
435
+ cursor = response.cursor ?? cursor;
245
436
  pagesLoaded++;
246
437
  runtimeLogger.debug('Loaded event page', {
247
438
  workflowRunId: runId,
439
+ incremental,
248
440
  page: pagesLoaded,
249
441
  pageEvents: response.data.length,
250
- totalEvents: allEvents.length,
442
+ totalEvents: loadedEvents.length,
251
443
  hasMore,
252
444
  pageMs: Date.now() - pageStart,
253
445
  });
254
446
  }
255
- runtimeLogger.debug('Event loading complete', {
447
+ runtimeLogger.debug('Event load complete', {
256
448
  workflowRunId: runId,
257
- totalEvents: allEvents.length,
449
+ incremental,
450
+ totalEvents: loadedEvents.length,
258
451
  pagesLoaded,
259
452
  totalMs: Date.now() - loadStart,
260
453
  });
261
454
  span?.setAttributes({
262
- ...Attribute.WorkflowEventsCount(allEvents.length),
455
+ ...Attribute.WorkflowEventsCount(loadedEvents.length),
263
456
  ...Attribute.WorkflowEventsPagesLoaded(pagesLoaded),
264
457
  });
265
- return allEvents;
458
+ return { events: loadedEvents, cursor };
266
459
  });
267
460
  }
461
+ /**
462
+ * Whether the optimistic-concurrency guard for event creation is enabled.
463
+ * **On by default** where the runtime executes: replay-context creates send a
464
+ * `stateUpdatedAt` snapshot (and can be rejected with 412 by a supporting
465
+ * backend) unless `WORKFLOW_PRECONDITION_GUARD` is set to `0`. Backends without
466
+ * guard support ignore the snapshot, so enabling by default is
467
+ * backward-compatible.
468
+ */
469
+ export function isPreconditionGuardEnabled() {
470
+ return process.env.WORKFLOW_PRECONDITION_GUARD !== '0';
471
+ }
472
+ /**
473
+ * The `stateUpdatedAt` value to send with a replay-context event creation: the
474
+ * *maximum* ULID time (epoch ms) over the events the runtime has loaded. Returns
475
+ * `undefined` when there are no events or that id is not a decodable ULID.
476
+ *
477
+ * It is the maximum rather than the tail's because the loaded log is in the
478
+ * World's canonical order, which is not necessarily event-id order (see
479
+ * {@link appendUniqueEvents}). The maximum is what lets the count sent alongside
480
+ * it be read as "events at or below this watermark": every loaded event is at or
481
+ * below it, so the count is exactly `events.length`. Reading the tail instead
482
+ * would understate the watermark on a World whose order is not id-ordered, which
483
+ * is safe (it can only weaken detection) but needlessly imprecise.
484
+ *
485
+ * The maximum is found by lexicographic id comparison, decoding only once: the
486
+ * 26-character Crockford ULID encodes its timestamp in the leading 10
487
+ * characters, so the greatest id also carries the greatest time.
488
+ *
489
+ * Granularity: snapshots are epoch-milliseconds, and the backend allows an
490
+ * equal-timestamp snapshot (an up-to-date client must not be rejected). Two
491
+ * out-of-band events landing in the same millisecond where only the first was
492
+ * loaded therefore pass this half of the guard undetected — that is exactly
493
+ * the hole `stateEventCount` closes, since the count of events at or below the
494
+ * watermark differs even when the watermarks are equal.
495
+ */
496
+ export function latestEventStateUpdatedAt(events) {
497
+ let latest;
498
+ for (const event of events) {
499
+ if (latest === undefined || event.eventId > latest) {
500
+ latest = event.eventId;
501
+ }
502
+ }
503
+ if (latest === undefined) {
504
+ return undefined;
505
+ }
506
+ // Event IDs are prefixed ULIDs (e.g. `evnt_01ARYZ...`); ulidToDate only
507
+ // decodes the bare 26-char ULID, so strip the prefix first.
508
+ const eventId = latest;
509
+ const underscore = eventId.lastIndexOf('_');
510
+ const rawUlid = underscore === -1 ? eventId : eventId.slice(underscore + 1);
511
+ const time = ulidToDate(rawUlid)?.getTime();
512
+ if (time === undefined) {
513
+ // Fail open: a non-decodable id disarms the guard for this create (no
514
+ // snapshot sent). Log so a fleet-wide silent disarm is diagnosable.
515
+ runtimeLogger.debug('Precondition guard: latest event id is not a decodable ULID; sending no snapshot', { eventId });
516
+ return undefined;
517
+ }
518
+ return time;
519
+ }
520
+ /**
521
+ * Build the precondition snapshot to attach to a replay-context event creation.
522
+ *
523
+ * Returns an empty object — no guard, backend behaves as before — when the
524
+ * guard is disabled or the watermark is not derivable. All three fields fail
525
+ * open together: a count without a watermark is meaningless to the backend, and
526
+ * a cursor without either would invite a delta nobody asked for.
527
+ *
528
+ * `stateEventCount` is `events.length` because the watermark is the log's
529
+ * *maximum* ULID time, so every loaded event is at or below it regardless of the
530
+ * order the World returned them in.
531
+ *
532
+ * Both fields are therefore invariant under permutation of the log: a maximum is
533
+ * order-independent, and the length is set cardinality once `appendUniqueEvents`
534
+ * has deduped by event id. Two replays that consume the same events in different
535
+ * orders send an identical snapshot, so this guard detects that a log is missing
536
+ * an event and can never detect that a replay consumed one in a different order.
537
+ */
538
+ export function preconditionSnapshotParams(events, cursor) {
539
+ if (!isPreconditionGuardEnabled()) {
540
+ return {};
541
+ }
542
+ const stateUpdatedAt = latestEventStateUpdatedAt(events);
543
+ if (stateUpdatedAt === undefined) {
544
+ return {};
545
+ }
546
+ return {
547
+ stateUpdatedAt,
548
+ stateEventCount: events.length,
549
+ ...(cursor ? { stateCursor: cursor } : {}),
550
+ };
551
+ }
552
+ /**
553
+ * The events a rejecting World attached to a `PreconditionFailedError`, when it
554
+ * returned the ones the client's snapshot was missing inline.
555
+ *
556
+ * Returns `null` for anything else — no details, a World that did not implement
557
+ * this, or a payload that does not narrow cleanly. Callers fall back to
558
+ * reloading the event log, which is always correct; this is untrusted-shaped
559
+ * data on a failure path, so nothing here is repaired.
560
+ *
561
+ * `runId` is the caller's run. Every event must belong to it: the delta is
562
+ * merged straight into the replay's log, and one foreign event there is a
563
+ * corrupt log rather than a corrected one — the replay would consume a
564
+ * correlation id for an event that does not exist on this run.
565
+ */
566
+ export function preconditionEventDelta(error, runId) {
567
+ if (!PreconditionFailedError.is(error)) {
568
+ return null;
569
+ }
570
+ const details = error.details;
571
+ if (typeof details !== 'object' || details === null) {
572
+ return null;
573
+ }
574
+ const { events, cursor } = details;
575
+ if (!Array.isArray(events) || events.length === 0) {
576
+ return null;
577
+ }
578
+ for (const event of events) {
579
+ if (typeof event !== 'object' ||
580
+ event === null ||
581
+ typeof event.eventId !== 'string' ||
582
+ event.runId !== runId) {
583
+ return null;
584
+ }
585
+ }
586
+ return {
587
+ events: events,
588
+ cursor: typeof cursor === 'string' ? cursor : null,
589
+ };
590
+ }
268
591
  /**
269
592
  * CORS headers for health check responses.
270
593
  * Allows the observability UI to check endpoint health from a different origin.
@@ -344,4 +667,55 @@ export function getQueueOverhead(message) {
344
667
  return;
345
668
  }
346
669
  }
347
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW50aW1lL2hlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTUEsT0FBTyxFQUNMLHdCQUF3QixFQUN4QixvQkFBb0IsRUFDcEIsbUJBQW1CLEdBQ3BCLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXhDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDN0MsT0FBTyxLQUFLLFNBQVMsTUFBTSxzQ0FBc0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxPQUFPLElBQUksbUJBQW1CLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUV0Qyx3REFBd0Q7QUFDeEQsTUFBTSw0QkFBNEIsR0FBRyxNQUFNLENBQUM7QUFFNUM7Ozs7R0FJRztBQUNILE1BQU0sMEJBQTBCLEdBQUcsc0JBQXNCLENBQUM7QUFFMUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxZQUFvQjtJQUN2RCxJQUFJLENBQUMsMEJBQTBCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7UUFDbkQsTUFBTSxJQUFJLEtBQUssQ0FDYiwwQkFBMEIsWUFBWSx3R0FBd0csQ0FDL0ksQ0FBQztJQUNKLENBQUM7SUFDRCxPQUFPLGtCQUFrQixZQUFZLEVBQW9CLENBQUM7QUFDNUQsQ0FBQztBQUVELE1BQU0sVUFBVSxHQUFHLGdCQUFnQixFQUFFLENBQUM7QUFFdEM7O0dBRUc7QUFDSCxTQUFTLHdCQUF3QixDQUFDLGFBQXFCO0lBQ3JELE9BQU8sbUJBQW1CLGFBQWEsRUFBRSxDQUFDO0FBQzVDLENBQUM7QUFlRDs7O0dBR0c7QUFD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LHdCQUF3QixDQUFDLFNBQVMsQ0FBQztZQUNoRCxHQUFHLFNBQVMsQ0FBQyxzQkFBc0IsQ0FBQyxTQUFTLENBQUM7WUFDOUMsd0NBQXdDO1lBQ3hDLEdBQUcsU0FBUyxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUM7WUFDeEMsR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQztZQUN0QyxHQUFHLFNBQVMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDO1lBQzlCLEdBQUcsU0FBUyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUM7U0FDbEM7UUFDRCxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUMsVUFBVSxDQUFDO0tBQ3BDLEVBQ0QsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFO1FBQ2IsTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQ2pELElBQUksU0FBUyxFQUFFLENBQUM7WUFDZCxJQUFJLEVBQUUsYUFBYSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQy9ELENBQUM7SUFDSCxDQUFDLENBQ0YsQ0FBQztBQUNKLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxPQUErQjtJQUM5RCxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVc7UUFBRSxPQUFPO0lBQ2pDLElBQUksQ0FBQztRQUNILE9BQU8sU0FBUyxDQUFDLGVBQWUsQ0FDOUIsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLENBQzNDLENBQUM7SUFDSixDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTztJQUNULENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUge1xuICBFdmVudCxcbiAgSGVhbHRoQ2hlY2tQYXlsb2FkLFxuICBWYWxpZFF1ZXVlTmFtZSxcbiAgV29ybGQsXG59IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQge1xuICBIZWFsdGhDaGVja1BheWxvYWRTY2hlbWEsXG4gIFNQRUNfVkVSU0lPTl9DVVJSRU5ULFxuICBTUEVDX1ZFUlNJT05fTEVHQUNZLFxufSBmcm9tICdAd29ya2Zsb3cvd29ybGQnO1xuaW1wb3J0IHsgbW9ub3RvbmljRmFjdG9yeSB9IGZyb20gJ3VsaWQnO1xuXG5pbXBvcnQgeyBydW50aW1lTG9nZ2VyIH0gZnJvbSAnLi4vbG9nZ2VyLmpzJztcbmltcG9ydCAqIGFzIEF0dHJpYnV0ZSBmcm9tICcuLi90ZWxlbWV0cnkvc2VtYW50aWMtY29udmVudGlvbnMuanMnO1xuaW1wb3J0IHsgZ2V0U3BhbktpbmQsIHRyYWNlIH0gZnJvbSAnLi4vdGVsZW1ldHJ5LmpzJztcbmltcG9ydCB7IHZlcnNpb24gYXMgd29ya2Zsb3dDb3JlVmVyc2lvbiB9IGZyb20gJy4uL3ZlcnNpb24uanMnO1xuaW1wb3J0IHsgZ2V0V29ybGQgfSBmcm9tICcuL3dvcmxkLmpzJztcblxuLyoqIERlZmF1bHQgdGltZW91dCBmb3IgaGVhbHRoIGNoZWNrcyBpbiBtaWxsaXNlY29uZHMgKi9cbmNvbnN0IERFRkFVTFRfSEVBTFRIX0NIRUNLX1RJTUVPVVQgPSAzMF8wMDA7XG5cbi8qKlxuICogUGF0dGVybiBmb3Igc2FmZSB3b3JrZmxvdyBuYW1lcy4gT25seSBhbGxvd3MgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMsXG4gKiB1bmRlcnNjb3JlcywgaHlwaGVucywgZG90cywgZm9yd2FyZCBzbGFzaGVzIChmb3IgbmFtZXNwYWNlZCB3b3JrZmxvd3MpLFxuICogYW5kIGF0IHNpZ25zIChmb3Igc2NvcGVkIHBhY2thZ2VzKS5cbiAqL1xuY29uc3QgU0FGRV9XT1JLRkxPV19OQU1FX1BBVFRFUk4gPSAvXlthLXpBLVowLTlfXFwtLi9AXSskLztcblxuLyoqXG4gKiBWYWxpZGF0ZXMgYSB3b3JrZmxvdyBuYW1lIGFuZCByZXR1cm5zIHRoZSBjb3JyZXNwb25kaW5nIHF1ZXVlIG5hbWUuXG4gKiBFbnN1cmVzIHRoZSB3b3JrZmxvdyBuYW1lIG9ubHkgY29udGFpbnMgc2FmZSBjaGFyYWN0ZXJzIGJlZm9yZVxuICogaW50ZXJwb2xhdGluZyBpdCBpbnRvIHRoZSBxdWV1ZSBuYW1lIHN0cmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmtmbG93UXVldWVOYW1lKHdvcmtmbG93TmFtZTogc3RyaW5nKTogVmFsaWRRdWV1ZU5hbWUge1xuICBpZiAoIVNBRkVfV09SS0ZMT1dfTkFNRV9QQVRURVJOLnRlc3Qod29ya2Zsb3dOYW1lKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBJbnZhbGlkIHdvcmtmbG93IG5hbWUgXCIke3dvcmtmbG93TmFtZX1cIjogbXVzdCBvbmx5IGNvbnRhaW4gYWxwaGFudW1lcmljIGNoYXJhY3RlcnMsIHVuZGVyc2NvcmVzLCBoeXBoZW5zLCBkb3RzLCBmb3J3YXJkIHNsYXNoZXMsIG9yIGF0IHNpZ25zYFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGBfX3drZl93b3JrZmxvd18ke3dvcmtmbG93TmFtZX1gIGFzIFZhbGlkUXVldWVOYW1lO1xufVxuXG5jb25zdCBnZW5lcmF0ZUlkID0gbW9ub3RvbmljRmFjdG9yeSgpO1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHN0cmVhbSBuYW1lIGZvciBhIGhlYWx0aCBjaGVjayB3aXRoIHRoZSBnaXZlbiBjb3JyZWxhdGlvbiBJRC5cbiAqL1xuZnVuY3Rpb24gZ2V0SGVhbHRoQ2hlY2tTdHJlYW1OYW1lKGNvcnJlbGF0aW9uSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgX19oZWFsdGhfY2hlY2tfXyR7Y29ycmVsYXRpb25JZH1gO1xufVxuXG4vKipcbiAqIFJlc3VsdCBvZiBhIGhlYWx0aCBjaGVjayBvcGVyYXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSGVhbHRoQ2hlY2tSZXN1bHQge1xuICBoZWFsdGh5OiBib29sZWFuO1xuICAvKiogRXJyb3IgbWVzc2FnZSBpZiBoZWFsdGggY2hlY2sgZmFpbGVkICovXG4gIGVycm9yPzogc3RyaW5nO1xuICAvKiogTGF0ZW5jeSBpZiB0aGUgaGVhbHRoIGNoZWNrIHdhcyBzdWNjZXNzZnVsICovXG4gIGxhdGVuY3lNcz86IG51bWJlcjtcbiAgLyoqIFNwZWMgdmVyc2lvbiBvZiB0aGUgcmVzcG9uZGluZyBkZXBsb3ltZW50ICovXG4gIHNwZWNWZXJzaW9uPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gbWVzc2FnZSBpcyBhIGhlYWx0aCBjaGVjayBwYXlsb2FkLlxuICogSWYgc28sIHJldHVybnMgdGhlIHBhcnNlZCBwYXlsb2FkLiBPdGhlcndpc2UgcmV0dXJucyB1bmRlZmluZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUhlYWx0aENoZWNrUGF5bG9hZChcbiAgbWVzc2FnZTogdW5rbm93blxuKTogSGVhbHRoQ2hlY2tQYXlsb2FkIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcmVzdWx0ID0gSGVhbHRoQ2hlY2tQYXlsb2FkU2NoZW1hLnNhZmVQYXJzZShtZXNzYWdlKTtcbiAgaWYgKHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgcmV0dXJuIHJlc3VsdC5kYXRhO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgZGV0ZXJtaW5pc3RpYyBmYWtlIHJ1bklkIGZvciBoZWFsdGggY2hlY2sgc3RyZWFtcy5cbiAqIEJvdGggdGhlIHdyaXRlciAoaGFuZGxlSGVhbHRoQ2hlY2tNZXNzYWdlKSBhbmQgcmVhZGVyIChoZWFsdGhDaGVjaykgZGVyaXZlXG4gKiB0aGUgc2FtZSBydW5JZCBmcm9tIHRoZSBjb3JyZWxhdGlvbklkIHNvIHRoYXQgaW1wbGVtZW50YXRpb25zIHRoYXQgc2NvcGVcbiAqIHN0cmVhbSByZWFkcyBieSBydW5JZCBzdGlsbCB3b3JrIGNvcnJlY3RseS5cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVIZWFsdGhDaGVja1J1bklkKGNvcnJlbGF0aW9uSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgd3J1bl9oY18ke2NvcnJlbGF0aW9uSWR9YDtcbn1cblxuLyoqXG4gKiBIYW5kbGVzIGEgaGVhbHRoIGNoZWNrIG1lc3NhZ2UgYnkgd3JpdGluZyB0aGUgcmVzdWx0IHRvIHRoZSB3b3JsZCdzIHN0cmVhbS5cbiAqIFRoZSBjYWxsZXIgY2FuIGxpc3RlbiB0byB0aGlzIHN0cmVhbSB0byBnZXQgdGhlIGhlYWx0aCBjaGVjayByZXNwb25zZS5cbiAqXG4gKiBAcGFyYW0gaGVhbHRoQ2hlY2sgLSBUaGUgcGFyc2VkIGhlYWx0aCBjaGVjayBwYXlsb2FkXG4gKiBAcGFyYW0gZW5kcG9pbnQgLSBXaGljaCBlbmRwb2ludCBpcyByZXNwb25kaW5nICgnd29ya2Zsb3cnIG9yICdzdGVwJylcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZUhlYWx0aENoZWNrTWVzc2FnZShcbiAgaGVhbHRoQ2hlY2s6IEhlYWx0aENoZWNrUGF5bG9hZCxcbiAgZW5kcG9pbnQ6ICd3b3JrZmxvdycgfCAnc3RlcCcsXG4gIHdvcmxkU3BlY1ZlcnNpb24/OiBudW1iZXJcbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB3b3JsZCA9IGF3YWl0IGdldFdvcmxkKCk7XG4gIGNvbnN0IHN0cmVhbU5hbWUgPSBnZXRIZWFsdGhDaGVja1N0cmVhbU5hbWUoaGVhbHRoQ2hlY2suY29ycmVsYXRpb25JZCk7XG4gIGNvbnN0IHJlc3BvbnNlID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgIGhlYWx0aHk6IHRydWUsXG4gICAgZW5kcG9pbnQsXG4gICAgY29ycmVsYXRpb25JZDogaGVhbHRoQ2hlY2suY29ycmVsYXRpb25JZCxcbiAgICBzcGVjVmVyc2lvbjogd29ybGRTcGVjVmVyc2lvbiA/PyBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICB3b3JrZmxvd0NvcmVWZXJzaW9uLFxuICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgfSk7XG4gIC8vIFVzZSBhIGRldGVybWluaXN0aWMgZmFrZSBydW5JZCBkZXJpdmVkIGZyb20gdGhlIGNvcnJlbGF0aW9uSWQgc28gdGhhdFxuICAvLyB0aGUgcmVhZGVyIHNpZGUgcHJvZHVjZXMgdGhlIHNhbWUgdmFsdWUuXG4gIGNvbnN0IGZha2VSdW5JZCA9IGdlbmVyYXRlSGVhbHRoQ2hlY2tSdW5JZChoZWFsdGhDaGVjay5jb3JyZWxhdGlvbklkKTtcbiAgYXdhaXQgd29ybGQuc3RyZWFtcy53cml0ZShmYWtlUnVuSWQsIHN0cmVhbU5hbWUsIHJlc3BvbnNlKTtcbiAgYXdhaXQgd29ybGQuc3RyZWFtcy5jbG9zZShmYWtlUnVuSWQsIHN0cmVhbU5hbWUpO1xufVxuXG5leHBvcnQgdHlwZSBIZWFsdGhDaGVja0VuZHBvaW50ID0gJ3dvcmtmbG93JyB8ICdzdGVwJztcblxuZXhwb3J0IGludGVyZmFjZSBIZWFsdGhDaGVja09wdGlvbnMge1xuICAvKiogVGltZW91dCBpbiBtaWxsaXNlY29uZHMgdG8gd2FpdCBmb3IgaGVhbHRoIGNoZWNrIHJlc3BvbnNlLiBEZWZhdWx0OiAzMDAwMCAoMzBzKSAqL1xuICB0aW1lb3V0PzogbnVtYmVyO1xuICAvKiogRGVwbG95bWVudCBJRCB0byBzZW5kIHRoZSBoZWFsdGggY2hlY2sgdG8uIEZhbGxzIGJhY2sgdG8gcHJvY2Vzcy5lbnYuVkVSQ0VMX0RFUExPWU1FTlRfSUQuICovXG4gIGRlcGxveW1lbnRJZD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBQZXJmb3JtcyBhIGhlYWx0aCBjaGVjayBieSBzZW5kaW5nIGEgbWVzc2FnZSB0aHJvdWdoIHRoZSBxdWV1ZSBwaXBlbGluZVxuICogYW5kIHZlcmlmeWluZyBpdCBpcyBwcm9jZXNzZWQgYnkgdGhlIHNwZWNpZmllZCBlbmRwb2ludC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGJ5cGFzc2VzIERlcGxveW1lbnQgUHJvdGVjdGlvbiBvbiBWZXJjZWwgYmVjYXVzZSBpdCBnb2VzXG4gKiB0aHJvdWdoIHRoZSBxdWV1ZSBpbmZyYXN0cnVjdHVyZSByYXRoZXIgdGhhbiBkaXJlY3QgSFRUUC5cbiAqXG4gKiBAcGFyYW0gd29ybGQgLSBUaGUgV29ybGQgaW5zdGFuY2UgdG8gdXNlIGZvciB0aGUgaGVhbHRoIGNoZWNrXG4gKiBAcGFyYW0gZW5kcG9pbnQgLSBXaGljaCBlbmRwb2ludCB0byBoZWFsdGggY2hlY2s6ICd3b3JrZmxvdycgb3IgJ3N0ZXAnXG4gKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBoZWFsdGggY2hlY2tcbiAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIGhlYWx0aCBjaGVjayByZXN1bHRcbiAqL1xuLy8gUG9sbCBpbnRlcnZhbCBmb3IgaGVhbHRoIGNoZWNrIHJldHJpZXMgKG1zKVxuY29uc3QgSEVBTFRIX0NIRUNLX1BPTExfSU5URVJWQUwgPSAxMDA7XG4vLyBQZXItcmVhZCB0aW1lb3V0IHRvIHByZXZlbnQgYmxvY2tpbmcgZm9yZXZlciBvbiBsb2NhbCB3b3JsZCdzIEV2ZW50RW1pdHRlclxuLy8gKHdoaWNoIGRvZXNuJ3Qgd29yayBhY3Jvc3MgcHJvY2Vzc2VzKVxuY29uc3QgSEVBTFRIX0NIRUNLX1JFQURfVElNRU9VVCA9IDUwMDtcblxuLyoqXG4gKiBSZWFkIGNodW5rcyBmcm9tIGEgc3RyZWFtIHdpdGggYSB0aW1lb3V0IHBlciByZWFkIG9wZXJhdGlvbi5cbiAqIFJldHVybnMgeyBjaHVua3MsIHRpbWVkT3V0IH0gd2hlcmUgdGltZWRPdXQgaW5kaWNhdGVzIGlmIGEgcmVhZCB0aW1lZCBvdXQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlYWRTdHJlYW1XaXRoVGltZW91dChcbiAgcmVhZGVyOiBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXI8VWludDhBcnJheT4sXG4gIHJlYWRUaW1lb3V0OiBudW1iZXJcbik6IFByb21pc2U8eyBjaHVua3M6IFVpbnQ4QXJyYXlbXTsgdGltZWRPdXQ6IGJvb2xlYW4gfT4ge1xuICBjb25zdCBjaHVua3M6IFVpbnQ4QXJyYXlbXSA9IFtdO1xuICBsZXQgZG9uZSA9IGZhbHNlO1xuICBsZXQgdGltZWRPdXQgPSBmYWxzZTtcblxuICB3aGlsZSAoIWRvbmUgJiYgIXRpbWVkT3V0KSB7XG4gICAgY29uc3QgcmVhZFByb21pc2UgPSByZWFkZXIucmVhZCgpO1xuICAgIGNvbnN0IHRpbWVvdXRQcm9taXNlID0gbmV3IFByb21pc2U8eyBkb25lOiB0cnVlOyB2YWx1ZTogdW5kZWZpbmVkIH0+KFxuICAgICAgKHJlc29sdmUpID0+XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHRpbWVkT3V0ID0gdHJ1ZTtcbiAgICAgICAgICByZXNvbHZlKHsgZG9uZTogdHJ1ZSwgdmFsdWU6IHVuZGVmaW5lZCB9KTtcbiAgICAgICAgfSwgcmVhZFRpbWVvdXQpXG4gICAgKTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IFByb21pc2UucmFjZShbcmVhZFByb21pc2UsIHRpbWVvdXRQcm9taXNlXSk7XG4gICAgZG9uZSA9IHJlc3VsdC5kb25lO1xuICAgIGlmIChyZXN1bHQudmFsdWUpIGNodW5rcy5wdXNoKHJlc3VsdC52YWx1ZSk7XG4gIH1cblxuICByZXR1cm4geyBjaHVua3MsIHRpbWVkT3V0IH07XG59XG5cbi8qKlxuICogUGFyc2UgYW5kIHZhbGlkYXRlIGEgaGVhbHRoIGNoZWNrIHJlc3BvbnNlIGZyb20gc3RyZWFtIGNodW5rcy5cbiAqIFJldHVybnMgdGhlIHBhcnNlZCByZXNwb25zZSBvciBudWxsIGlmIGludmFsaWQuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlSGVhbHRoQ2hlY2tSZXNwb25zZShcbiAgY2h1bmtzOiBVaW50OEFycmF5W11cbik6IHsgaGVhbHRoeTogYm9vbGVhbiB9IHwgbnVsbCB7XG4gIGlmIChjaHVua3MubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcblxuICBjb25zdCB0b3RhbExlbmd0aCA9IGNodW5rcy5yZWR1Y2UoKHN1bSwgY2h1bmspID0+IHN1bSArIGNodW5rLmxlbmd0aCwgMCk7XG4gIGNvbnN0IGNvbWJpbmVkID0gbmV3IFVpbnQ4QXJyYXkodG90YWxMZW5ndGgpO1xuICBsZXQgb2Zmc2V0ID0gMDtcbiAgZm9yIChjb25zdCBjaHVuayBvZiBjaHVua3MpIHtcbiAgICBjb21iaW5lZC5zZXQoY2h1bmssIG9mZnNldCk7XG4gICAgb2Zmc2V0ICs9IGNodW5rLmxlbmd0aDtcbiAgfVxuICBjb25zdCByZXNwb25zZVRleHQgPSBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoY29tYmluZWQpO1xuXG4gIGxldCByZXNwb25zZTogdW5rbm93bjtcbiAgdHJ5IHtcbiAgICByZXNwb25zZSA9IEpTT04ucGFyc2UocmVzcG9uc2VUZXh0KTtcbiAgfSBjYXRjaCB7XG4gICAgLy8gT2xkIGRlcGxveW1lbnRzIChzcGVjVmVyc2lvbiA8IDMpIHJldHVybiBwbGFpbiB0ZXh0IGxpa2VcbiAgICAvLyAnV29ya2Zsb3cgU0RLIFwiLi4uXCIgZW5kcG9pbnQgaXMgaGVhbHRoeScuIFRyZWF0IGFueSBub24tZW1wdHlcbiAgICAvLyB0ZXh0IHJlc3BvbnNlIGFzIGEgaGVhbHRoeSBkZXBsb3ltZW50IHdpdGggdW5rbm93biBzcGVjVmVyc2lvbi5cbiAgICBpZiAocmVzcG9uc2VUZXh0Lmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiB7IGhlYWx0aHk6IHRydWUgfTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoXG4gICAgdHlwZW9mIHJlc3BvbnNlICE9PSAnb2JqZWN0JyB8fFxuICAgIHJlc3BvbnNlID09PSBudWxsIHx8XG4gICAgISgnaGVhbHRoeScgaW4gcmVzcG9uc2UpIHx8XG4gICAgdHlwZW9mIChyZXNwb25zZSBhcyB7IGhlYWx0aHk6IHVua25vd24gfSkuaGVhbHRoeSAhPT0gJ2Jvb2xlYW4nXG4gICkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgciA9IHJlc3BvbnNlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBjb25zdCBwYXJzZWQ6IHsgaGVhbHRoeTogYm9vbGVhbjsgc3BlY1ZlcnNpb24/OiBudW1iZXIgfSA9IHtcbiAgICBoZWFsdGh5OiByLmhlYWx0aHkgYXMgYm9vbGVhbixcbiAgfTtcbiAgaWYgKHR5cGVvZiByLnNwZWNWZXJzaW9uID09PSAnbnVtYmVyJykge1xuICAgIHBhcnNlZC5zcGVjVmVyc2lvbiA9IHIuc3BlY1ZlcnNpb247XG4gIH1cbiAgcmV0dXJuIHBhcnNlZDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhlYWx0aENoZWNrKFxuICB3b3JsZDogV29ybGQsXG4gIGVuZHBvaW50OiBIZWFsdGhDaGVja0VuZHBvaW50LFxuICBvcHRpb25zPzogSGVhbHRoQ2hlY2tPcHRpb25zXG4pOiBQcm9taXNlPEhlYWx0aENoZWNrUmVzdWx0PiB7XG4gIGNvbnN0IHRpbWVvdXQgPSBvcHRpb25zPy50aW1lb3V0ID8/IERFRkFVTFRfSEVBTFRIX0NIRUNLX1RJTUVPVVQ7XG4gIGNvbnN0IGNvcnJlbGF0aW9uSWQgPSBnZW5lcmF0ZUlkKCk7XG4gIGNvbnN0IHN0cmVhbU5hbWUgPSBnZXRIZWFsdGhDaGVja1N0cmVhbU5hbWUoY29ycmVsYXRpb25JZCk7XG5cbiAgY29uc3QgcXVldWVOYW1lOiBWYWxpZFF1ZXVlTmFtZSA9XG4gICAgZW5kcG9pbnQgPT09ICd3b3JrZmxvdydcbiAgICAgID8gJ19fd2tmX3dvcmtmbG93X2hlYWx0aF9jaGVjaydcbiAgICAgIDogJ19fd2tmX3N0ZXBfaGVhbHRoX2NoZWNrJztcblxuICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgd29ybGQucXVldWUoXG4gICAgICBxdWV1ZU5hbWUsXG4gICAgICB7IF9faGVhbHRoQ2hlY2s6IHRydWUsIGNvcnJlbGF0aW9uSWQgfSxcbiAgICAgIHtcbiAgICAgICAgLy8gVXNlIEpTT04gdHJhbnNwb3J0IHNvIHRoZSBoZWFsdGggY2hlY2sgd29ya3MgYWdhaW5zdCBib3RoXG4gICAgICAgIC8vIG9sZCAoSlNPTi1vbmx5KSBhbmQgbmV3IChkdWFsKSBkZXBsb3ltZW50cy5cbiAgICAgICAgc3BlY1ZlcnNpb246IFNQRUNfVkVSU0lPTl9MRUdBQ1ksXG4gICAgICAgIGRlcGxveW1lbnRJZDogb3B0aW9ucz8uZGVwbG95bWVudElkLFxuICAgICAgfVxuICAgICk7XG5cbiAgICB3aGlsZSAoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSA8IHRpbWVvdXQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHN0cmVhbSA9IGF3YWl0IHdvcmxkLnN0cmVhbXMuZ2V0KFxuICAgICAgICAgIGdlbmVyYXRlSGVhbHRoQ2hlY2tSdW5JZChjb3JyZWxhdGlvbklkKSxcbiAgICAgICAgICBzdHJlYW1OYW1lXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5nZXRSZWFkZXIoKTtcbiAgICAgICAgY29uc3QgeyBjaHVua3MsIHRpbWVkT3V0IH0gPSBhd2FpdCByZWFkU3RyZWFtV2l0aFRpbWVvdXQoXG4gICAgICAgICAgcmVhZGVyLFxuICAgICAgICAgIEhFQUxUSF9DSEVDS19SRUFEX1RJTUVPVVRcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAodGltZWRPdXQpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmVhZGVyLmNhbmNlbCgpO1xuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLy8gSWdub3JlIGNhbmNlbCBlcnJvcnNcbiAgICAgICAgICB9XG4gICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+XG4gICAgICAgICAgICBzZXRUaW1lb3V0KHJlc29sdmUsIEhFQUxUSF9DSEVDS19QT0xMX0lOVEVSVkFMKVxuICAgICAgICAgICk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IHBhcnNlSGVhbHRoQ2hlY2tSZXNwb25zZShjaHVua3MpO1xuICAgICAgICBpZiAocmVzcG9uc2UpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4ucmVzcG9uc2UsXG4gICAgICAgICAgICBsYXRlbmN5TXM6IERhdGUubm93KCkgLSBzdGFydFRpbWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PlxuICAgICAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgSEVBTFRIX0NIRUNLX1BPTExfSU5URVJWQUwpXG4gICAgICAgICk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+XG4gICAgICAgICAgc2V0VGltZW91dChyZXNvbHZlLCBIRUFMVEhfQ0hFQ0tfUE9MTF9JTlRFUlZBTClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGhlYWx0aHk6IGZhbHNlLFxuICAgICAgZXJyb3I6IGBIZWFsdGggY2hlY2sgdGltZWQgb3V0IGFmdGVyICR7dGltZW91dH1tc2AsXG4gICAgfTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaGVhbHRoeTogZmFsc2UsXG4gICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBMb2FkcyBhbGwgd29ya2Zsb3cgcnVuIGV2ZW50cyBieSBpdGVyYXRpbmcgdGhyb3VnaCBhbGwgcGFnZXMgb2YgcGFnaW5hdGVkIHJlc3VsdHMuXG4gKiBUaGlzIGVuc3VyZXMgdGhhdCAqYWxsKiBldmVudHMgYXJlIGxvYWRlZCBpbnRvIG1lbW9yeSBiZWZvcmUgcnVubmluZyB0aGUgd29ya2Zsb3cuXG4gKiBFdmVudHMgbXVzdCBiZSBpbiBjaHJvbm9sb2dpY2FsIG9yZGVyIChhc2NlbmRpbmcpIGZvciBwcm9wZXIgd29ya2Zsb3cgcmVwbGF5LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0QWxsV29ya2Zsb3dSdW5FdmVudHMocnVuSWQ6IHN0cmluZyk6IFByb21pc2U8RXZlbnRbXT4ge1xuICByZXR1cm4gdHJhY2UoJ3dvcmtmbG93LmxvYWRFdmVudHMnLCBhc3luYyAoc3BhbikgPT4ge1xuICAgIHNwYW4/LnNldEF0dHJpYnV0ZXMoe1xuICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93UnVuSWQocnVuSWQpLFxuICAgIH0pO1xuXG4gICAgY29uc3QgYWxsRXZlbnRzOiBFdmVudFtdID0gW107XG4gICAgbGV0IGN1cnNvcjogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gICAgbGV0IGhhc01vcmUgPSB0cnVlO1xuICAgIGxldCBwYWdlc0xvYWRlZCA9IDA7XG5cbiAgICBjb25zdCB3b3JsZCA9IGF3YWl0IGdldFdvcmxkKCk7XG4gICAgY29uc3QgbG9hZFN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICB3aGlsZSAoaGFzTW9yZSkge1xuICAgICAgLy8gVE9ETzogd2UncmUgY3VycmVudGx5IGxvYWRpbmcgYWxsIHRoZSBkYXRhIHdpdGggcmVzb2x2ZVJlZiBiZWhhdmlvdXIuIFdlIG5lZWQgdG8gdXBkYXRlIHRoaXNcbiAgICAgIC8vIHRvIGxhenlsb2FkIHRoZSBkYXRhIGZyb20gdGhlIHdvcmxkIGluc3RlYWQgc28gdGhhdCB3ZSBjYW4gb3B0aW1pemUgYW5kIG1ha2UgdGhlIGV2ZW50IGxvZyBsb2FkaW5nXG4gICAgICAvLyBtdWNoIGZhc3RlciBhbmQgbWVtb3J5IGVmZmljaWVudFxuICAgICAgY29uc3QgcGFnZVN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd29ybGQuZXZlbnRzLmxpc3Qoe1xuICAgICAgICBydW5JZCxcbiAgICAgICAgcGFnaW5hdGlvbjoge1xuICAgICAgICAgIHNvcnRPcmRlcjogJ2FzYycsIC8vIFJlcXVpcmVkOiBldmVudHMgbXVzdCBiZSBpbiBjaHJvbm9sb2dpY2FsIG9yZGVyIGZvciByZXBsYXlcbiAgICAgICAgICBjdXJzb3I6IGN1cnNvciA/PyB1bmRlZmluZWQsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgYWxsRXZlbnRzLnB1c2goLi4ucmVzcG9uc2UuZGF0YSk7XG4gICAgICBoYXNNb3JlID0gcmVzcG9uc2UuaGFzTW9yZTtcbiAgICAgIGN1cnNvciA9IHJlc3BvbnNlLmN1cnNvcjtcbiAgICAgIHBhZ2VzTG9hZGVkKys7XG5cbiAgICAgIHJ1bnRpbWVMb2dnZXIuZGVidWcoJ0xvYWRlZCBldmVudCBwYWdlJywge1xuICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgcGFnZTogcGFnZXNMb2FkZWQsXG4gICAgICAgIHBhZ2VFdmVudHM6IHJlc3BvbnNlLmRhdGEubGVuZ3RoLFxuICAgICAgICB0b3RhbEV2ZW50czogYWxsRXZlbnRzLmxlbmd0aCxcbiAgICAgICAgaGFzTW9yZSxcbiAgICAgICAgcGFnZU1zOiBEYXRlLm5vdygpIC0gcGFnZVN0YXJ0LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcnVudGltZUxvZ2dlci5kZWJ1ZygnRXZlbnQgbG9hZGluZyBjb21wbGV0ZScsIHtcbiAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgdG90YWxFdmVudHM6IGFsbEV2ZW50cy5sZW5ndGgsXG4gICAgICBwYWdlc0xvYWRlZCxcbiAgICAgIHRvdGFsTXM6IERhdGUubm93KCkgLSBsb2FkU3RhcnQsXG4gICAgfSk7XG5cbiAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgIC4uLkF0dHJpYnV0ZS5Xb3JrZmxvd0V2ZW50c0NvdW50KGFsbEV2ZW50cy5sZW5ndGgpLFxuICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93RXZlbnRzUGFnZXNMb2FkZWQocGFnZXNMb2FkZWQpLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGFsbEV2ZW50cztcbiAgfSk7XG59XG5cbi8qKlxuICogQ09SUyBoZWFkZXJzIGZvciBoZWFsdGggY2hlY2sgcmVzcG9uc2VzLlxuICogQWxsb3dzIHRoZSBvYnNlcnZhYmlsaXR5IFVJIHRvIGNoZWNrIGVuZHBvaW50IGhlYWx0aCBmcm9tIGEgZGlmZmVyZW50IG9yaWdpbi5cbiAqL1xuY29uc3QgSEVBTFRIX0NIRUNLX0NPUlNfSEVBREVSUyA9IHtcbiAgJ0FjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbic6ICcqJyxcbiAgJ0FjY2Vzcy1Db250cm9sLUFsbG93LU1ldGhvZHMnOiAnUE9TVCwgT1BUSU9OUywgR0VULCBIRUFEJyxcbiAgJ0FjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnMnOiAnQ29udGVudC1UeXBlJyxcbn07XG5cbi8qKlxuICogV3JhcHMgYSByZXF1ZXN0L3Jlc3BvbnNlIGhhbmRsZXIgYW5kIGFkZHMgYSBoZWFsdGggY2hlY2sgXCJtb2RlXCJcbiAqIGJhc2VkIG9uIHRoZSBwcmVzZW5jZSBvZiBhIGBfX2hlYWx0aGAgcXVlcnkgcGFyYW1ldGVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2l0aEhlYWx0aENoZWNrKFxuICBoYW5kbGVyOiAocmVxOiBSZXF1ZXN0KSA9PiBQcm9taXNlPFJlc3BvbnNlPixcbiAgd29ybGRTcGVjVmVyc2lvbj86IG51bWJlclxuKTogKHJlcTogUmVxdWVzdCkgPT4gUHJvbWlzZTxSZXNwb25zZT4ge1xuICByZXR1cm4gYXN5bmMgKHJlcTogUmVxdWVzdCkgPT4ge1xuICAgIGNvbnN0IHVybCA9IG5ldyBVUkwocmVxLnVybCk7XG4gICAgY29uc3QgaXNIZWFsdGhDaGVjayA9IHVybC5zZWFyY2hQYXJhbXMuaGFzKCdfX2hlYWx0aCcpO1xuICAgIGlmIChpc0hlYWx0aENoZWNrKSB7XG4gICAgICAvLyBIYW5kbGUgQ09SUyBwcmVmbGlnaHQgZm9yIGhlYWx0aCBjaGVja1xuICAgICAgaWYgKHJlcS5tZXRob2QgPT09ICdPUFRJT05TJykge1xuICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKG51bGwsIHtcbiAgICAgICAgICBzdGF0dXM6IDIwNCxcbiAgICAgICAgICBoZWFkZXJzOiBIRUFMVEhfQ0hFQ0tfQ09SU19IRUFERVJTLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UoXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBoZWFsdGh5OiB0cnVlLFxuICAgICAgICAgIGVuZHBvaW50OiB1cmwucGF0aG5hbWUsXG4gICAgICAgICAgc3BlY1ZlcnNpb246IHdvcmxkU3BlY1ZlcnNpb24gPz8gU1BFQ19WRVJTSU9OX0NVUlJFTlQsXG4gICAgICAgICAgd29ya2Zsb3dDb3JlVmVyc2lvbixcbiAgICAgICAgfSksXG4gICAgICAgIHtcbiAgICAgICAgICBzdGF0dXM6IDIwMCxcbiAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgLi4uSEVBTFRIX0NIRUNLX0NPUlNfSEVBREVSUyxcbiAgICAgICAgICB9LFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gYXdhaXQgaGFuZGxlcihyZXEpO1xuICB9O1xufVxuXG4vKipcbiAqIFF1ZXVlcyBhIG1lc3NhZ2UgdG8gdGhlIHNwZWNpZmllZCBxdWV1ZSB3aXRoIHRyYWNpbmcuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBxdWV1ZU1lc3NhZ2UoXG4gIHdvcmxkOiBXb3JsZCxcbiAgLi4uYXJnczogUGFyYW1ldGVyczx0eXBlb2Ygd29ybGQucXVldWU+XG4pIHtcbiAgY29uc3QgcXVldWVOYW1lID0gYXJnc1swXTtcbiAgYXdhaXQgdHJhY2UoXG4gICAgJ3F1ZXVlLnB1Ymxpc2gnLFxuICAgIHtcbiAgICAgIC8vIFN0YW5kYXJkIE9URUwgbWVzc2FnaW5nIGNvbnZlbnRpb25zXG4gICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgIC4uLkF0dHJpYnV0ZS5NZXNzYWdpbmdTeXN0ZW0oJ3ZlcmNlbC1xdWV1ZScpLFxuICAgICAgICAuLi5BdHRyaWJ1dGUuTWVzc2FnaW5nRGVzdGluYXRpb25OYW1lKHF1ZXVlTmFtZSksXG4gICAgICAgIC4uLkF0dHJpYnV0ZS5NZXNzYWdpbmdPcGVyYXRpb25UeXBlKCdwdWJsaXNoJyksXG4gICAgICAgIC8vIFBlZXIgc2VydmljZSBmb3IgRGF0YWRvZyBzZXJ2aWNlIG1hcHNcbiAgICAgICAgLi4uQXR0cmlidXRlLlBlZXJTZXJ2aWNlKCd2ZXJjZWwtcXVldWUnKSxcbiAgICAgICAgLi4uQXR0cmlidXRlLlJwY1N5c3RlbSgndmVyY2VsLXF1ZXVlJyksXG4gICAgICAgIC4uLkF0dHJpYnV0ZS5ScGNTZXJ2aWNlKCd2cXMnKSxcbiAgICAgICAgLi4uQXR0cmlidXRlLlJwY01ldGhvZCgncHVibGlzaCcpLFxuICAgICAgfSxcbiAgICAgIGtpbmQ6IGF3YWl0IGdldFNwYW5LaW5kKCdQUk9EVUNFUicpLFxuICAgIH0sXG4gICAgYXN5bmMgKHNwYW4pID0+IHtcbiAgICAgIGNvbnN0IHsgbWVzc2FnZUlkIH0gPSBhd2FpdCB3b3JsZC5xdWV1ZSguLi5hcmdzKTtcbiAgICAgIGlmIChtZXNzYWdlSWQpIHtcbiAgICAgICAgc3Bhbj8uc2V0QXR0cmlidXRlcyhBdHRyaWJ1dGUuTWVzc2FnaW5nTWVzc2FnZUlkKG1lc3NhZ2VJZCkpO1xuICAgICAgfVxuICAgIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBxdWV1ZSBvdmVyaGVhZCB0aW1lIGluIG1pbGxpc2Vjb25kcyBmb3IgYSBnaXZlbiBtZXNzYWdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UXVldWVPdmVyaGVhZChtZXNzYWdlOiB7IHJlcXVlc3RlZEF0PzogRGF0ZSB9KSB7XG4gIGlmICghbWVzc2FnZS5yZXF1ZXN0ZWRBdCkgcmV0dXJuO1xuICB0cnkge1xuICAgIHJldHVybiBBdHRyaWJ1dGUuUXVldWVPdmVyaGVhZE1zKFxuICAgICAgRGF0ZS5ub3coKSAtIG1lc3NhZ2UucmVxdWVzdGVkQXQuZ2V0VGltZSgpXG4gICAgKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuO1xuICB9XG59XG4iXX0=
670
+ /**
671
+ * Returns a memoized accessor for a run's full encryption capability.
672
+ *
673
+ * The first call resolves the run's key material via
674
+ * `world.getEncryptionKeyForRun` (which may do HKDF derivation locally on
675
+ * Vercel, or a network fetch from external contexts) and derives a
676
+ * {@link PayloadKey} from it; subsequent calls await the same cached promise.
677
+ * If the world doesn't support encryption or the run has no key configured,
678
+ * the cached value is `undefined`.
679
+ *
680
+ * The resolved value is deliberately the *full* capability — the symmetric AES
681
+ * key plus the run's X25519 keypair — not just a `CryptoKey`. A run reading
682
+ * its own event log can encounter sealed (`encp`) payloads that another run
683
+ * wrote to it (a cross-deployment hook resumption, say), and opening those
684
+ * needs the keypair. Resolving only the symmetric key would leave those
685
+ * payloads unopenable and wedge the run.
686
+ *
687
+ * Used by step / workflow handlers to defer the (potentially expensive)
688
+ * key fetch until the first code path that actually needs it — typically
689
+ * input hydration on the success path, or error dehydration on a failure
690
+ * path. Both paths can race-call the accessor without triggering duplicate
691
+ * fetches.
692
+ *
693
+ * Errors thrown by `getEncryptionKeyForRun` propagate to every caller
694
+ * (the cached promise rejects). This is intentional: when encryption is
695
+ * configured, we never want to silently fall back to plaintext
696
+ * serialization. A propagated error in an event-emission path leaves the
697
+ * outer try/catch to log and surface the issue; the queue's redelivery
698
+ * semantics will retry the key fetch on the next attempt.
699
+ */
700
+ export function memoizeEncryptionKey(world, runOrId) {
701
+ let cached;
702
+ return () => {
703
+ if (!cached) {
704
+ cached = (async () => {
705
+ // The `getEncryptionKeyForRun` overload set takes either a
706
+ // `WorkflowRun` or a `runId: string` (with optional context). Branch
707
+ // here so TypeScript picks the right overload for each shape.
708
+ const rawKey = typeof runOrId === 'string'
709
+ ? await world.getEncryptionKeyForRun?.(runOrId)
710
+ : await world.getEncryptionKeyForRun?.(runOrId);
711
+ // Resolve the *full* capability, not just the symmetric key: a run
712
+ // reading its own event log may encounter sealed (`encp`) payloads
713
+ // that another run wrote to it, and opening those needs the run's
714
+ // X25519 scalar as well.
715
+ return rawKey ? await deriveRunPayloadKeys(rawKey) : undefined;
716
+ })();
717
+ }
718
+ return cached;
719
+ };
720
+ }
721
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW50aW1lL2hlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixlQUFlLEVBQ2Ysa0JBQWtCLEdBQ25CLE1BQU0sa0JBQWtCLENBQUM7QUFXMUIsT0FBTyxFQUNMLG1CQUFtQixFQUNuQix3QkFBd0IsRUFDeEIseUJBQXlCLEVBQ3pCLHFCQUFxQixFQUNyQixvQkFBb0IsRUFDcEIsbUJBQW1CLEVBQ25CLFVBQVUsR0FDWCxNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN4QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxhQUFhLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNuRSxPQUFPLEVBQ0wsb0JBQW9CLEdBRXJCLE1BQU0sZ0NBQWdDLENBQUM7QUFDeEMsT0FBTyxLQUFLLFNBQVMsTUFBTSxzQ0FBc0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxPQUFPLElBQUksbUJBQW1CLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0QsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRW5ELHdEQUF3RDtBQUN4RCxNQUFNLDRCQUE0QixHQUFHLE1BQU0sQ0FBQztBQUU1Qzs7OztHQUlHO0FBQ0gsTUFBTSwwQkFBMEIsR0FBRyxzQkFBc0IsQ0FBQztBQUUxRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUNsQyxZQUFvQixFQUNwQixTQUFrQjtJQUVsQixJQUFJLENBQUMsMEJBQTBCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7UUFDbkQsTUFBTSxJ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QUM7WUFDWixNQUFNLEdBQUcsQ0FBQyxLQUFLLElBQUksRUFBRTtnQkFDbkIsMkRBQTJEO2dCQUMzRCxxRUFBcUU7Z0JBQ3JFLDhEQUE4RDtnQkFDOUQsTUFBTSxNQUFNLEdBQ1YsT0FBTyxPQUFPLEtBQUssUUFBUTtvQkFDekIsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLHNCQUFzQixFQUFFLENBQUMsT0FBTyxDQUFDO29CQUMvQyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDcEQsbUVBQW1FO2dCQUNuRSxtRUFBbUU7Z0JBQ25FLGtFQUFrRTtnQkFDbEUseUJBQXlCO2dCQUN6QixPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ2pFLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDUCxDQUFDO1FBQ0QsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIFByZWNvbmRpdGlvbkZhaWxlZEVycm9yLFxuICBSVU5fRVJST1JfQ09ERVMsXG4gIFdvcmtmbG93V29ybGRFcnJvcixcbn0gZnJvbSAnQHdvcmtmbG93L2Vycm9ycyc7XG5pbXBvcnQgdHlwZSB7XG4gIENyZWF0ZUV2ZW50UGFyYW1zLFxuICBDcmVhdGVFdmVudFJlcXVlc3QsXG4gIEV2ZW50LFxuICBFdmVudFJlc3VsdCxcbiAgSGVhbHRoQ2hlY2tQYXlsb2FkLFxuICBWYWxpZFF1ZXVlTmFtZSxcbiAgV29ya2Zsb3dSdW4sXG4gIFdvcmxkLFxufSBmcm9tICdAd29ya2Zsb3cvd29ybGQnO1xuaW1wb3J0IHtcbiAgZ2V0UXVldWVUb3BpY1ByZWZpeCxcbiAgSGVhbHRoQ2hlY2tQYXlsb2FkU2NoZW1hLFxuICBIT09LX1JFU1VNRV9JTlBVVF9WRVJTSU9OLFxuICByZXNvbHZlUXVldWVOYW1lc3BhY2UsXG4gIFNQRUNfVkVSU0lPTl9DVVJSRU5ULFxuICBTUEVDX1ZFUlNJT05fTEVHQUNZLFxuICB1bGlkVG9EYXRlLFxufSBmcm9tICdAd29ya2Zsb3cvd29ybGQnO1xuaW1wb3J0IHsgbW9ub3RvbmljRmFjdG9yeSB9IGZyb20gJ3VsaWQnO1xuaW1wb3J0IHsgcnVudGltZUxvZ2dlciB9IGZyb20gJy4uL2xvZ2dlci5qcyc7XG5pbXBvcnQgeyBieXRlc1RvQmFzZTY0LCBkZXJpdmVSdW5LZXlQYWlyIH0gZnJvbSAnLi4vc2VhbGVkLWJveC5qcyc7XG5pbXBvcnQge1xuICBkZXJpdmVSdW5QYXlsb2FkS2V5cyxcbiAgdHlwZSBQYXlsb2FkS2V5LFxufSBmcm9tICcuLi9zZXJpYWxpemF0aW9uL2VuY3J5cHRpb24uanMnO1xuaW1wb3J0ICogYXMgQXR0cmlidXRlIGZyb20gJy4uL3RlbGVtZXRyeS9zZW1hbnRpYy1jb252ZW50aW9ucy5qcyc7XG5pbXBvcnQgeyBnZXRTcGFuS2luZCwgdHJhY2UgfSBmcm9tICcuLi90ZWxlbWV0cnkuanMnO1xuaW1wb3J0IHsgdmVyc2lvbiBhcyB3b3JrZmxvd0NvcmVWZXJzaW9uIH0gZnJvbSAnLi4vdmVyc2lvbi5qcyc7XG5pbXBvcnQgeyBnZXRXb3JsZExhenkgfSBmcm9tICcuL2dldC13b3JsZC1sYXp5LmpzJztcblxuLyoqIERlZmF1bHQgdGltZW91dCBmb3IgaGVhbHRoIGNoZWNrcyBpbiBtaWxsaXNlY29uZHMgKi9cbmNvbnN0IERFRkFVTFRfSEVBTFRIX0NIRUNLX1RJTUVPVVQgPSAzMF8wMDA7XG5cbi8qKlxuICogUGF0dGVybiBmb3Igc2FmZSB3b3JrZmxvdyBuYW1lcy4gT25seSBhbGxvd3MgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMsXG4gKiB1bmRlcnNjb3JlcywgaHlwaGVucywgZG90cywgZm9yd2FyZCBzbGFzaGVzIChmb3IgbmFtZXNwYWNlZCB3b3JrZmxvd3MpLFxuICogYW5kIGF0IHNpZ25zIChmb3Igc2NvcGVkIHBhY2thZ2VzKS5cbiAqL1xuY29uc3QgU0FGRV9XT1JLRkxPV19OQU1FX1BBVFRFUk4gPSAvXlthLXpBLVowLTlfXFwtLi9AXSskLztcblxuLyoqXG4gKiBWYWxpZGF0ZXMgYSB3b3JrZmxvdyBuYW1lIGFuZCByZXR1cm5zIHRoZSBjb3JyZXNwb25kaW5nIHF1ZXVlIG5hbWUuXG4gKiBFbnN1cmVzIHRoZSB3b3JrZmxvdyBuYW1lIG9ubHkgY29udGFpbnMgc2FmZSBjaGFyYWN0ZXJzIGJlZm9yZVxuICogaW50ZXJwb2xhdGluZyBpdCBpbnRvIHRoZSBxdWV1ZSBuYW1lIHN0cmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmtmbG93UXVldWVOYW1lKFxuICB3b3JrZmxvd05hbWU6IHN0cmluZyxcbiAgbmFtZXNwYWNlPzogc3RyaW5nXG4pOiBWYWxpZFF1ZXVlTmFtZSB7XG4gIGlmICghU0FGRV9XT1JLRkxPV19OQU1FX1BBVFRFUk4udGVzdCh3b3JrZmxvd05hbWUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYEludmFsaWQgd29ya2Zsb3cgbmFtZSBcIiR7d29ya2Zsb3dOYW1lfVwiOiBtdXN0IG9ubHkgY29udGFpbiBhbHBoYW51bWVyaWMgY2hhcmFjdGVycywgdW5kZXJzY29yZXMsIGh5cGhlbnMsIGRvdHMsIGZvcndhcmQgc2xhc2hlcywgb3IgYXQgc2lnbnNgXG4gICAgKTtcbiAgfVxuICBjb25zdCBwcmVmaXggPSBnZXRRdWV1ZVRvcGljUHJlZml4KFxuICAgICd3b3JrZmxvdycsXG4gICAgcmVzb2x2ZVF1ZXVlTmFtZXNwYWNlKG5hbWVzcGFjZSlcbiAgKTtcbiAgcmV0dXJuIGAke3ByZWZpeH0ke3dvcmtmbG93TmFtZX1gIGFzIFZhbGlkUXVldWVOYW1lO1xufVxuXG5jb25zdCBnZW5lcmF0ZUlkID0gbW9ub3RvbmljRmFjdG9yeSgpO1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHN0cmVhbSBuYW1lIGZvciBhIGhlYWx0aCBjaGVjayB3aXRoIHRoZSBnaXZlbiBjb3JyZWxhdGlvbiBJRC5cbiAqL1xuZnVuY3Rpb24gZ2V0SGVhbHRoQ2hlY2tTdHJlYW1OYW1lKGNvcnJlbGF0aW9uSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgX19oZWFsdGhfY2hlY2tfXyR7Y29ycmVsYXRpb25JZH1gO1xufVxuXG4vKipcbiAqIFJlc3VsdCBvZiBhIGhlYWx0aCBjaGVjayBvcGVyYXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSGVhbHRoQ2hlY2tSZXN1bHQge1xuICBoZWFsdGh5OiBib29sZWFuO1xuICAvKiogRXJyb3IgbWVzc2FnZSBpZiBoZWFsdGggY2hlY2sgZmFpbGVkICovXG4gIGVycm9yPzogc3RyaW5nO1xuICAvKiogTGF0ZW5jeSBpZiB0aGUgaGVhbHRoIGNoZWNrIHdhcyBzdWNjZXNzZnVsICovXG4gIGxhdGVuY3lNcz86IG51bWJlcjtcbiAgLyoqIFNwZWMgdmVyc2lvbiBvZiB0aGUgcmVzcG9uZGluZyBkZXBsb3ltZW50ICovXG4gIHNwZWNWZXJzaW9uPzogbnVtYmVyO1xuICAvKipcbiAgICogYEB3b3JrZmxvdy9jb3JlYCB2ZXJzaW9uIG9mIHRoZSByZXNwb25kaW5nIGRlcGxveW1lbnQsIHVzZWQgZm9yXG4gICAqIGNhcGFiaWxpdHkgZGV0ZWN0aW9uIChzZWUgYGdldFJ1bkNhcGFiaWxpdGllc2ApLiBPbWl0dGVkIHdoZW4gdGhlXG4gICAqIHJlc3BvbmRpbmcgZGVwbG95bWVudCBkaWQgbm90IHByb3ZpZGUgdGhlIGZpZWxkIGFzIGEgc3RyaW5nIOKAlFxuICAgKiBmb3IgZXhhbXBsZSwgYW4gb2xkZXIgYEB3b3JrZmxvdy9jb3JlYCB0aGF0IHByZWRhdGVzIHRoaXMgZmllbGQsXG4gICAqIG9yIGEgbm9uLUpTT04gcGxhaW4tdGV4dCBoZWFsdGggcmVzcG9uc2UuXG4gICAqL1xuICB3b3JrZmxvd0NvcmVWZXJzaW9uPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHRhcmdldCBydW4ncyBYMjU1MTkgcHVibGljIGtleSAoYmFzZTY0KSwgcmV0dXJuZWQgb25seSB3aGVuIHRoZSBwcm9iZVxuICAgKiBjYXJyaWVkIGEgYHJ1bklkYCBhbmQgdGhlIHJlc3BvbmRpbmcgZGVwbG95bWVudCBoYXMgZW5jcnlwdGlvbiBlbmFibGVkLlxuICAgKlxuICAgKiBMZXRzIGEgY3Jvc3MtZGVwbG95bWVudCBgc3RhcnQoKWAgc2VhbCB0aGUgd29ya2Zsb3cgYXJndW1lbnRzIHVzaW5nIGFcbiAgICogcmVzcG9uc2UgaXQgd2FzIGFscmVhZHkgd2FpdGluZyBvbiwgaW5zdGVhZCBvZiBtYWtpbmcgYSBzZXBhcmF0ZVxuICAgKiBrZXktbG9va3VwIHJlcXVlc3QuXG4gICAqL1xuICBlbmNyeXB0aW9uUHVibGljS2V5Pzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHJlc3BvbmRpbmcgZGVwbG95bWVudCdzIGBIT09LX1JFU1VNRV9JTlBVVF9WRVJTSU9OYCDigJQgdGhlIHByb3RvY29sXG4gICAqIHZlcnNpb24gYXQgd2hpY2ggdGhlICpjb25zdW1lciogKHF1ZXVlLW1lc3NhZ2UgdGFyZ2V0KSByZS1lbnN1cmVzIHRoZVxuICAgKiBgaG9va19yZWNlaXZlZGAgZXZlbnQgZnJvbSBgaG9va0lucHV0YCBvbiByZXBsYXkuIEEgY3Jvc3MtZGVwbG95bWVudFxuICAgKiBgc3RhcnQoKWAgc3RhbXBzIHRoZSAqdGFyZ2V0J3MqIHZhbHVlIChub3QgdGhlIGNhbGxlcidzKSBpbnRvIHRoZSBuZXdcbiAgICogcnVuJ3MgYGV4ZWN1dGlvbkNvbnRleHQuaG9va1Jlc3VtZUlucHV0VmVyc2lvbmAgc28gdGhhdCBgcmVzdW1lSG9vaygpYFxuICAgKiBvbmx5IHRha2VzIHRoZSBwYXJhbGxlbCBwYXRoIHdoZW4gdGhlIGRlcGxveW1lbnQgdGhhdCB3aWxsIGFjdHVhbGx5XG4gICAqIGNvbnN1bWUgdGhlIHF1ZXVlIG1lc3NhZ2UgaXMga25vd24gdG8gaG9ub3IgYGhvb2tJbnB1dGAuIE9taXR0ZWQgd2hlbiB0aGVcbiAgICogcmVzcG9uZGluZyBkZXBsb3ltZW50IHByZWRhdGVzIHRoaXMgZmllbGQgKGFuIG9sZGVyIGNvbnN1bWVyIHRoYXQgaWdub3Jlc1xuICAgKiBgaG9va0lucHV0YCksIHdoaWNoIGZhaWxzIHRoZSBnYXRlIGNsb3NlZC5cbiAgICovXG4gIGhvb2tSZXN1bWVJbnB1dFZlcnNpb24/OiBudW1iZXI7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBtZXNzYWdlIGlzIGEgaGVhbHRoIGNoZWNrIHBheWxvYWQuXG4gKiBJZiBzbywgcmV0dXJucyB0aGUgcGFyc2VkIHBheWxvYWQuIE90aGVyd2lzZSByZXR1cm5zIHVuZGVmaW5lZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlSGVhbHRoQ2hlY2tQYXlsb2FkKFxuICBtZXNzYWdlOiB1bmtub3duXG4pOiBIZWFsdGhDaGVja1BheWxvYWQgfCB1bmRlZmluZWQge1xuICBjb25zdCByZXN1bHQgPSBIZWFsdGhDaGVja1BheWxvYWRTY2hlbWEuc2FmZVBhcnNlKG1lc3NhZ2UpO1xuICBpZiAocmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICByZXR1cm4gcmVzdWx0LmRhdGE7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBkZXRlcm1pbmlzdGljIGZha2UgcnVuSWQgZm9yIGhlYWx0aCBjaGVjayBzdHJlYW1zLlxuICogQm90aCB0aGUgd3JpdGVyIChoYW5kbGVIZWFsdGhDaGVja01lc3NhZ2UpIGFuZCByZWFkZXIgKGhlYWx0aENoZWNrKSBkZXJpdmVcbiAqIHRoZSBzYW1lIHJ1bklkIGZyb20gdGhlIGNvcnJlbGF0aW9uSWQgc28gdGhhdCBpbXBsZW1lbnRhdGlvbnMgdGhhdCBzY29wZVxuICogc3RyZWFtIHJlYWRzIGJ5IHJ1bklkIHN0aWxsIHdvcmsgY29ycmVjdGx5LlxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZUhlYWx0aENoZWNrUnVuSWQoY29ycmVsYXRpb25JZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGB3cnVuX2hjXyR7Y29ycmVsYXRpb25JZH1gO1xufVxuXG4vKipcbiAqIEhhbmRsZXMgYSBoZWFsdGggY2hlY2sgbWVzc2FnZSBieSB3cml0aW5nIHRoZSByZXN1bHQgdG8gdGhlIHdvcmxkJ3Mgc3RyZWFtLlxuICogVGhlIGNhbGxlciBjYW4gbGlzdGVuIHRvIHRoaXMgc3RyZWFtIHRvIGdldCB0aGUgaGVhbHRoIGNoZWNrIHJlc3BvbnNlLlxuICpcbiAqIEBwYXJhbSBoZWFsdGhDaGVjayAtIFRoZSBwYXJzZWQgaGVhbHRoIGNoZWNrIHBheWxvYWRcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZUhlYWx0aENoZWNrTWVzc2FnZShcbiAgaGVhbHRoQ2hlY2s6IEhlYWx0aENoZWNrUGF5bG9hZCxcbiAgd29ybGRTcGVjVmVyc2lvbj86IG51bWJlclxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHdvcmxkID0gYXdhaXQgZ2V0V29ybGRMYXp5KCk7XG4gIGNvbnN0IHN0cmVhbU5hbWUgPSBnZXRIZWFsdGhDaGVja1N0cmVhbU5hbWUoaGVhbHRoQ2hlY2suY29ycmVsYXRpb25JZCk7XG5cbiAgLy8gV2hlbiB0aGUgcHJvYmUgbmFtZXMgYSBydW4gdGhlIGNhbGxlciBpcyBhYm91dCB0byBjcmVhdGUsIHB1Ymxpc2ggdGhhdFxuICAvLyBydW4ncyBwdWJsaWMga2V5LiBXZSBhcmUgZXhlY3V0aW5nIGluc2lkZSB0aGUgdGFyZ2V0IGRlcGxveW1lbnQsIHNvIGl0c1xuICAvLyBrZXkgbWF0ZXJpYWwgaXMgYXZhaWxhYmxlIGxvY2FsbHkgKG5vIEFQSSBjYWxsKSwgYW5kIHRoZSBjYWxsZXIgY2FuIHRoZW5cbiAgLy8gc2VhbCB0aGUgd29ya2Zsb3cgYXJndW1lbnRzIHN0cmFpZ2h0IGZyb20gdGhpcyByZXNwb25zZSByYXRoZXIgdGhhblxuICAvLyBtYWtpbmcgYSBzZXBhcmF0ZSBrZXktbG9va3VwIHJlcXVlc3QuXG4gIC8vXG4gIC8vIE9ubHkgYSAqcHVibGljKiBrZXkgbWF5IHRyYXZlbCB0aGlzIHdheTogdGhlIHByb2JlIHJlc3BvbnNlIHN0cmVhbSBpc1xuICAvLyBkZWxpYmVyYXRlbHkgdW5hdXRoZW50aWNhdGVkLCBzbyBhbnl0aGluZyBzZWNyZXQgd291bGQgYmUgZXhwb3NlZC5cbiAgLy8gQmVzdC1lZmZvcnQg4oCUIGEgZmFpbHVyZSBoZXJlIG11c3Qgbm90IGZhaWwgdGhlIGhlYWx0aCBjaGVjayBpdHNlbGYsIHdoaWNoXG4gIC8vIGNhbGxlcnMgYWxzbyByZWx5IG9uIGZvciBwbGFpbiBjYXBhYmlsaXR5IGRldGVjdGlvbi5cbiAgbGV0IGVuY3J5cHRpb25QdWJsaWNLZXk6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgaWYgKGhlYWx0aENoZWNrLnJ1bklkKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJhd0tleSA9IGF3YWl0IHdvcmxkLmdldEVuY3J5cHRpb25LZXlGb3JSdW4/LihoZWFsdGhDaGVjay5ydW5JZCk7XG4gICAgICBpZiAocmF3S2V5KSB7XG4gICAgICAgIGVuY3J5cHRpb25QdWJsaWNLZXkgPSBieXRlc1RvQmFzZTY0KFxuICAgICAgICAgIChhd2FpdCBkZXJpdmVSdW5LZXlQYWlyKHJhd0tleSkpLnB1YmxpY0tleVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcnVudGltZUxvZ2dlci53YXJuKFxuICAgICAgICAnSGVhbHRoIGNoZWNrIGNvdWxkIG5vdCBkZXJpdmUgYSBydW4gcHVibGljIGtleTsgdGhlIGNhbGxlciB3aWxsIGZhbGwgYmFjayB0byBhIGtleSBsb29rdXAnLFxuICAgICAgICB7XG4gICAgICAgICAgY29ycmVsYXRpb25JZDogaGVhbHRoQ2hlY2suY29ycmVsYXRpb25JZCxcbiAgICAgICAgICBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpLFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHJlc3BvbnNlID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgIGhlYWx0aHk6IHRydWUsXG4gICAgY29ycmVsYXRpb25JZDogaGVhbHRoQ2hlY2suY29ycmVsYXRpb25JZCxcbiAgICBzcGVjVmVyc2lvbjogd29ybGRTcGVjVmVyc2lvbiA/PyBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICB3b3JrZmxvd0NvcmVWZXJzaW9uLFxuICAgIC8vIFdlIGFyZSBleGVjdXRpbmcgaW5zaWRlIHRoZSB0YXJnZXQgZGVwbG95bWVudCwgc28gdGhpcyBjb25zdGFudCByZWZsZWN0c1xuICAgIC8vIHRoZSAqY29uc3VtZXIncyogaG9vay1yZXN1bWUgcHJvdG9jb2wgdmVyc2lvbiDigJQgZXhhY3RseSB3aGF0IGFcbiAgICAvLyBjcm9zcy1kZXBsb3ltZW50IGNhbGxlciBuZWVkcyB0byBnYXRlIGl0cyBwYXJhbGxlbCByZXN1bWUgcGF0aCBvbi5cbiAgICBob29rUmVzdW1lSW5wdXRWZXJzaW9uOiBIT09LX1JFU1VNRV9JTlBVVF9WRVJTSU9OLFxuICAgIC4uLihlbmNyeXB0aW9uUHVibGljS2V5ID8geyBlbmNyeXB0aW9uUHVibGljS2V5IH0gOiB7fSksXG4gICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICB9KTtcbiAgLy8gVXNlIGEgZGV0ZXJtaW5pc3RpYyBmYWtlIHJ1bklkIGRlcml2ZWQgZnJvbSB0aGUgY29ycmVsYXRpb25JZCBzbyB0aGF0XG4gIC8vIHRoZSByZWFkZXIgc2lkZSBwcm9kdWNlcyB0aGUgc2FtZSB2YWx1ZS5cbiAgY29uc3QgZmFrZVJ1bklkID0gZ2VuZXJhdGVIZWFsdGhDaGVja1J1bklkKGhlYWx0aENoZWNrLmNvcnJlbGF0aW9uSWQpO1xuICBhd2FpdCB3b3JsZC5zdHJlYW1zLndyaXRlKGZha2VSdW5JZCwgc3RyZWFtTmFtZSwgcmVzcG9uc2UpO1xuICBhd2FpdCB3b3JsZC5zdHJlYW1zLmNsb3NlKGZha2VSdW5JZCwgc3RyZWFtTmFtZSk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSGVhbHRoQ2hlY2tPcHRpb25zIHtcbiAgLyoqIFRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIHRvIHdhaXQgZm9yIGhlYWx0aCBjaGVjayByZXNwb25zZS4gRGVmYXVsdDogMzAwMDAgKDMwcykgKi9cbiAgdGltZW91dD86IG51bWJlcjtcbiAgLyoqIERlcGxveW1lbnQgSUQgdG8gc2VuZCB0aGUgaGVhbHRoIGNoZWNrIHRvLiBGYWxscyBiYWNrIHRvIHByb2Nlc3MuZW52LlZFUkNFTF9ERVBMT1lNRU5UX0lELiAqL1xuICBkZXBsb3ltZW50SWQ/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgcnVuIGlkIHRoZSBjYWxsZXIgaXMgYWJvdXQgdG8gY3JlYXRlLiBXaGVuIHNldCwgdGhlIHJlc3BvbmRpbmdcbiAgICogZGVwbG95bWVudCBkZXJpdmVzIHRoYXQgcnVuJ3MgcHVibGljIGtleSBsb2NhbGx5IGFuZCByZXR1cm5zIGl0IGFzXG4gICAqIGBlbmNyeXB0aW9uUHVibGljS2V5YCwgbGV0dGluZyBhIGNyb3NzLWRlcGxveW1lbnQgYHN0YXJ0KClgIHNlYWwgdGhlXG4gICAqIHdvcmtmbG93IGFyZ3VtZW50cyB3aXRob3V0IGEgc2VwYXJhdGUga2V5IGxvb2t1cC5cbiAgICovXG4gIHJ1bklkPzogc3RyaW5nO1xuICAvKipcbiAgICogUXVldWUgbmFtZXNwYWNlIG9mIHRoZSB0YXJnZXQgZGVwbG95bWVudCAoZS5nLiBgJ2V2ZSdgIGZvciB0b3BpY3MgbGlrZVxuICAgKiBgX19ldmVfd2tmX3dvcmtmbG93XypgKS4gRmFsbHMgYmFjayB0byBgV09SS0ZMT1dfUVVFVUVfTkFNRVNQQUNFYCBpbiB0aGVcbiAgICogY2FsbGluZyBwcm9jZXNzLiBDcm9zcy1jb250ZXh0IGNhbGxlcnMgKGUuZy4gdGhlIG9ic2VydmFiaWxpdHlcbiAgICogZGFzaGJvYXJkKSBtdXN0IHBhc3MgdGhlIHRhcmdldCBkZXBsb3ltZW50J3MgbmFtZXNwYWNlIGV4cGxpY2l0bHkg4oCUXG4gICAqIHRoZSBlbnYgZmFsbGJhY2sgcmVzb2x2ZXMgaW4gdGhlIGNhbGxlcidzIHByb2Nlc3MsIGFuZCBhIG1lc3NhZ2VcbiAgICogcHVibGlzaGVkIHRvIGEgbWlzbWF0Y2hlZCB0b3BpYyBoYXMgbm8gY29uc3VtZXIsIHNvIHRoZSBjaGVjayB3b3VsZFxuICAgKiBhbHdheXMgdGltZSBvdXQuXG4gICAqL1xuICBuYW1lc3BhY2U/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogUGVyZm9ybXMgYSBoZWFsdGggY2hlY2sgYnkgc2VuZGluZyBhIG1lc3NhZ2UgdGhyb3VnaCB0aGUgcXVldWUgcGlwZWxpbmVcbiAqIGFuZCB2ZXJpZnlpbmcgaXQgaXMgcHJvY2Vzc2VkIGJ5IHRoZSBjb21iaW5lZCB3b3JrZmxvdyBlbmRwb2ludC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGJ5cGFzc2VzIERlcGxveW1lbnQgUHJvdGVjdGlvbiBvbiBWZXJjZWwgYmVjYXVzZSBpdCBnb2VzXG4gKiB0aHJvdWdoIHRoZSBxdWV1ZSBpbmZyYXN0cnVjdHVyZSByYXRoZXIgdGhhbiBkaXJlY3QgSFRUUC5cbiAqXG4gKiBAcGFyYW0gd29ybGQgLSBUaGUgV29ybGQgaW5zdGFuY2UgdG8gdXNlIGZvciB0aGUgaGVhbHRoIGNoZWNrXG4gKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBoZWFsdGggY2hlY2tcbiAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIGhlYWx0aCBjaGVjayByZXN1bHRcbiAqL1xuLy8gUG9sbCBpbnRlcnZhbCBmb3IgaGVhbHRoIGNoZWNrIHJldHJpZXMgKG1zKVxuY29uc3QgSEVBTFRIX0NIRUNLX1BPTExfSU5URVJWQUwgPSAxMDA7XG4vLyBQZXItcmVhZCB0aW1lb3V0IHRvIHByZXZlbnQgYmxvY2tpbmcgZm9yZXZlciBvbiBsb2NhbCB3b3JsZCdzIEV2ZW50RW1pdHRlclxuLy8gKHdoaWNoIGRvZXNuJ3Qgd29yayBhY3Jvc3MgcHJvY2Vzc2VzKVxuY29uc3QgSEVBTFRIX0NIRUNLX1JFQURfVElNRU9VVCA9IDUwMDtcblxuLyoqXG4gKiBSZWFkIGNodW5rcyBmcm9tIGEgc3RyZWFtIHdpdGggYSB0aW1lb3V0IHBlciByZWFkIG9wZXJhdGlvbi5cbiAqIFJldHVybnMgeyBjaHVua3MsIHRpbWVkT3V0IH0gd2hlcmUgdGltZWRPdXQgaW5kaWNhdGVzIGlmIGEgcmVhZCB0aW1lZCBvdXQuXG4gKi9cbi8qKlxuICogUmFjZSBhIHByb21pc2UgYWdhaW5zdCBhIGRlYWRsaW5lLiBSZWplY3RzIHdpdGggYSB0aW1lb3V0IGVycm9yIHdoZW4gdGhlXG4gKiBkZWFkbGluZSBlbGFwc2VzIGZpcnN0LiBVc2VkIHRvIGJvdW5kIGB3b3JsZC5zdHJlYW1zLmdldCgpYCBpbnNpZGUgdGhlXG4gKiBoZWFsdGgtY2hlY2sgcG9sbCBsb29wOiBzb21lIHdvcmxkcyBob2xkIHRoYXQgcmVxdWVzdCBvcGVuIHVudGlsIHRoZVxuICogc3RyZWFtIGhhcyBkYXRhIChlLmcuIHdvcmtmbG93LXNlcnZlciBob2xkcyB1bndyaXR0ZW4gc3RyZWFtcyBvcGVuIGZvclxuICogfjIgbWludXRlcyksIHdoaWNoIHdvdWxkIG90aGVyd2lzZSBibG93IHRocm91Z2ggdGhlIGNvbmZpZ3VyZWQgaGVhbHRoXG4gKiBjaGVjayB0aW1lb3V0IOKAlCB0aGUgYHdoaWxlYCBjb25kaXRpb24gaXMgb25seSByZS1jaGVja2VkIGJldHdlZW5cbiAqIGl0ZXJhdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIHdpdGhEZWFkbGluZTxUPihwcm9taXNlOiBQcm9taXNlPFQ+LCBtczogbnVtYmVyKTogUHJvbWlzZTxUPiB7XG4gIGxldCB0aW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCB1bmRlZmluZWQ7XG4gIHJldHVybiBQcm9taXNlLnJhY2UoW1xuICAgIHByb21pc2UsXG4gICAgbmV3IFByb21pc2U8bmV2ZXI+KChfLCByZWplY3QpID0+IHtcbiAgICAgIHRpbWVyID0gc2V0VGltZW91dChcbiAgICAgICAgKCkgPT4gcmVqZWN0KG5ldyBFcnJvcihgT3BlcmF0aW9uIHRpbWVkIG91dCBhZnRlciAke21zfW1zYCkpLFxuICAgICAgICBtc1xuICAgICAgKTtcbiAgICB9KSxcbiAgXSkuZmluYWxseSgoKSA9PiBjbGVhclRpbWVvdXQodGltZXIpKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVhZFN0cmVhbVdpdGhUaW1lb3V0KFxuICByZWFkZXI6IFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcjxVaW50OEFycmF5PixcbiAgcmVhZFRpbWVvdXQ6IG51bWJlclxuKTogUHJvbWlzZTx7IGNodW5rczogVWludDhBcnJheVtdOyB0aW1lZE91dDogYm9vbGVhbiB9PiB7XG4gIGNvbnN0IGNodW5rczogVWludDhBcnJheVtdID0gW107XG4gIGxldCBkb25lID0gZmFsc2U7XG4gIGxldCB0aW1lZE91dCA9IGZhbHNlO1xuXG4gIHdoaWxlICghZG9uZSAmJiAhdGltZWRPdXQpIHtcbiAgICBjb25zdCByZWFkUHJvbWlzZSA9IHJlYWRlci5yZWFkKCk7XG4gICAgY29uc3QgdGltZW91dFByb21pc2UgPSBuZXcgUHJvbWlzZTx7IGRvbmU6IHRydWU7IHZhbHVlOiB1bmRlZmluZWQgfT4oXG4gICAgICAocmVzb2x2ZSkgPT5cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGltZWRPdXQgPSB0cnVlO1xuICAgICAgICAgIHJlc29sdmUoeyBkb25lOiB0cnVlLCB2YWx1ZTogdW5kZWZpbmVkIH0pO1xuICAgICAgICB9LCByZWFkVGltZW91dClcbiAgICApO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgUHJvbWlzZS5yYWNlKFtyZWFkUHJvbWlzZSwgdGltZW91dFByb21pc2VdKTtcbiAgICBkb25lID0gcmVzdWx0LmRvbmU7XG4gICAgaWYgKHJlc3VsdC52YWx1ZSkgY2h1bmtzLnB1c2gocmVzdWx0LnZhbHVlKTtcbiAgfVxuXG4gIHJldHVybiB7IGNodW5rcywgdGltZWRPdXQgfTtcbn1cblxuLyoqXG4gKiBQYXJzZSBhbmQgdmFsaWRhdGUgYSBoZWFsdGggY2hlY2sgcmVzcG9uc2UgZnJvbSBzdHJlYW0gY2h1bmtzLlxuICogUmV0dXJucyB0aGUgcGFyc2VkIHJlc3BvbnNlIG9yIG51bGwgaWYgaW52YWxpZC5cbiAqL1xuZnVuY3Rpb24gcGFyc2VIZWFsdGhDaGVja1Jlc3BvbnNlKGNodW5rczogVWludDhBcnJheVtdKToge1xuICBoZWFsdGh5OiBib29sZWFuO1xuICBzcGVjVmVyc2lvbj86IG51bWJlcjtcbiAgd29ya2Zsb3dDb3JlVmVyc2lvbj86IHN0cmluZztcbiAgZW5jcnlwdGlvblB1YmxpY0tleT86IHN0cmluZztcbn0gfCBudWxsIHtcbiAgaWYgKGNodW5rcy5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuXG4gIGNvbnN0IHRvdGFsTGVuZ3RoID0gY2h1bmtzLnJlZHVjZSgoc3VtLCBjaHVuaykgPT4gc3VtICsgY2h1bmsubGVuZ3RoLCAwKTtcbiAgY29uc3QgY29tYmluZWQgPSBuZXcgVWludDhBcnJheSh0b3RhbExlbmd0aCk7XG4gIGxldCBvZmZzZXQgPSAwO1xuICBmb3IgKGNvbnN0IGNodW5rIG9mIGNodW5rcykge1xuICAgIGNvbWJpbmVkLnNldChjaHVuaywgb2Zmc2V0KTtcbiAgICBvZmZzZXQgKz0gY2h1bmsubGVuZ3RoO1xuICB9XG4gIGNvbnN0IHJlc3BvbnNlVGV4dCA9IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShjb21iaW5lZCk7XG5cbiAgbGV0IHJlc3BvbnNlOiB1bmtub3duO1xuICB0cnkge1xuICAgIHJlc3BvbnNlID0gSlNPTi5wYXJzZShyZXNwb25zZVRleHQpO1xuICB9IGNhdGNoIHtcbiAgICAvLyBPbGQgZGVwbG95bWVudHMgKHNwZWNWZXJzaW9uIDwgMykgcmV0dXJuIHBsYWluIHRleHQgbGlrZVxuICAgIC8vICdXb3JrZmxvdyBTREsgXCIuLi5cIiBlbmRwb2ludCBpcyBoZWFsdGh5Jy4gVHJlYXQgYW55IG5vbi1lbXB0eVxuICAgIC8vIHRleHQgcmVzcG9uc2UgYXMgYSBoZWFsdGh5IGRlcGxveW1lbnQgd2l0aCB1bmtub3duIHNwZWNWZXJzaW9uLlxuICAgIGlmIChyZXNwb25zZVRleHQubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIHsgaGVhbHRoeTogdHJ1ZSB9O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmIChcbiAgICB0eXBlb2YgcmVzcG9uc2UgIT09ICdvYmplY3QnIHx8XG4gICAgcmVzcG9uc2UgPT09IG51bGwgfHxcbiAgICAhKCdoZWFsdGh5JyBpbiByZXNwb25zZSkgfHxcbiAgICB0eXBlb2YgKHJlc3BvbnNlIGFzIHsgaGVhbHRoeTogdW5rbm93biB9KS5oZWFsdGh5ICE9PSAnYm9vbGVhbidcbiAgKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCByID0gcmVzcG9uc2UgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGNvbnN0IHBhcnNlZDoge1xuICAgIGhlYWx0aHk6IGJvb2xlYW47XG4gICAgc3BlY1ZlcnNpb24/OiBudW1iZXI7XG4gICAgd29ya2Zsb3dDb3JlVmVyc2lvbj86IHN0cmluZztcbiAgICBlbmNyeXB0aW9uUHVibGljS2V5Pzogc3RyaW5nO1xuICAgIGhvb2tSZXN1bWVJbnB1dFZlcnNpb24/OiBudW1iZXI7XG4gIH0gPSB7XG4gICAgaGVhbHRoeTogci5oZWFsdGh5IGFzIGJvb2xlYW4sXG4gIH07XG4gIGlmICh0eXBlb2Ygci5zcGVjVmVyc2lvbiA9PT0gJ251bWJlcicpIHtcbiAgICBwYXJzZWQuc3BlY1ZlcnNpb24gPSByLnNwZWNWZXJzaW9uO1xuICB9XG4gIGlmICh0eXBlb2Ygci53b3JrZmxvd0NvcmVWZXJzaW9uID09PSAnc3RyaW5nJykge1xuICAgIHBhcnNlZC53b3JrZmxvd0NvcmVWZXJzaW9uID0gci53b3JrZmxvd0NvcmVWZXJzaW9uO1xuICB9XG4gIGlmICh0eXBlb2Ygci5lbmNyeXB0aW9uUHVibGljS2V5ID09PSAnc3RyaW5nJykge1xuICAgIHBhcnNlZC5lbmNyeXB0aW9uUHVibGljS2V5ID0gci5lbmNyeXB0aW9uUHVibGljS2V5O1xuICB9XG4gIGlmICh0eXBlb2Ygci5ob29rUmVzdW1lSW5wdXRWZXJzaW9uID09PSAnbnVtYmVyJykge1xuICAgIHBhcnNlZC5ob29rUmVzdW1lSW5wdXRWZXJzaW9uID0gci5ob29rUmVzdW1lSW5wdXRWZXJzaW9uO1xuICB9XG4gIHJldHVybiBwYXJzZWQ7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoZWFsdGhDaGVjayhcbiAgd29ybGQ6IFdvcmxkLFxuICBvcHRpb25zPzogSGVhbHRoQ2hlY2tPcHRpb25zXG4pOiBQcm9taXNlPEhlYWx0aENoZWNrUmVzdWx0PiB7XG4gIGNvbnN0IHRpbWVvdXQgPSBvcHRpb25zPy50aW1lb3V0ID8/IERFRkFVTFRfSEVBTFRIX0NIRUNLX1RJTUVPVVQ7XG4gIC8vIFVzZSB0aGUgd29ybGQncyBJRCBnZW5lcmF0b3Igd2hlbiBhdmFpbGFibGUgc28gdGhlIGNvcnJlbGF0aW9uSWQgaXMgYVxuICAvLyByZWdpb24tdGFnZ2VkIFVMSUQuIFRoZSBoZWFsdGgtY2hlY2sgcmVzcG9uc2UgaXMgZGVsaXZlcmVkIG92ZXIgYSBzdHJlYW1cbiAgLy8gd2hvc2UgbmFtZSBlbWJlZHMgdGhpcyBjb3JyZWxhdGlvbklkOyB1bmRlciBwbGF0Zm9ybS1kaXJlY3RlZCByb3V0aW5nIHRoZVxuICAvLyByZWFkZXIgYW5kIHRoZSByZXNwb25kaW5nIGVuZHBvaW50IGNhbiBiZSBzZXJ2ZWQgZnJvbSBkaWZmZXJlbnQgcGh5c2ljYWxcbiAgLy8gcmVnaW9ucywgc28gdGhlIHJlZ2lvbiBtdXN0IGJlIGVuY29kZWQgaW4gdGhlIElEIGl0c2VsZiBmb3IgYm90aCBzaWRlcyB0b1xuICAvLyByZXNvbHZlIHRoZSBzYW1lIChyZWdpb24tcGlubmVkKSBiYWNrZW5kLiBGYWxscyBiYWNrIHRvIGEgcGxhaW4gVUxJRCBmb3JcbiAgLy8gd29ybGRzIHRoYXQgZG9uJ3QgdGFnIElEcyAoZS5nLiBsb2NhbCksIHdoaWNoIHJlc29sdmUgdG8gdGhlIGRlZmF1bHRcbiAgLy8gcmVnaW9uIG9uIGJvdGggc2lkZXMuXG4gIGNvbnN0IGNvcnJlbGF0aW9uSWQgPSB3b3JsZC5jcmVhdGVSdW5JZD8uKCkgPz8gZ2VuZXJhdGVJZCgpO1xuICBjb25zdCBzdHJlYW1OYW1lID0gZ2V0SGVhbHRoQ2hlY2tTdHJlYW1OYW1lKGNvcnJlbGF0aW9uSWQpO1xuXG4gIGNvbnN0IHF1ZXVlTmFtZSA9XG4gICAgYCR7Z2V0UXVldWVUb3BpY1ByZWZpeCgnd29ya2Zsb3cnLCByZXNvbHZlUXVldWVOYW1lc3BhY2Uob3B0aW9ucz8ubmFtZXNwYWNlKSl9aGVhbHRoX2NoZWNrYCBhcyBWYWxpZFF1ZXVlTmFtZTtcblxuICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgd29ybGQucXVldWUoXG4gICAgICBxdWV1ZU5hbWUsXG4gICAgICB7XG4gICAgICAgIF9faGVhbHRoQ2hlY2s6IHRydWUsXG4gICAgICAgIGNvcnJlbGF0aW9uSWQsXG4gICAgICAgIC4uLihvcHRpb25zPy5ydW5JZCA/IHsgcnVuSWQ6IG9wdGlvbnMucnVuSWQgfSA6IHt9KSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIC8vIFVzZSBKU09OIHRyYW5zcG9ydCBzbyB0aGUgaGVhbHRoIGNoZWNrIHdvcmtzIGFnYWluc3QgYm90aFxuICAgICAgICAvLyBvbGQgKEpTT04tb25seSkgYW5kIG5ldyAoZHVhbCkgZGVwbG95bWVudHMuXG4gICAgICAgIHNwZWNWZXJzaW9uOiBTUEVDX1ZFUlNJT05fTEVHQUNZLFxuICAgICAgICBkZXBsb3ltZW50SWQ6IG9wdGlvbnM/LmRlcGxveW1lbnRJZCxcbiAgICAgIH1cbiAgICApO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgLSBzdGFydFRpbWUgPCB0aW1lb3V0KSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZW1haW5pbmdNcyA9IHRpbWVvdXQgLSAoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSk7XG4gICAgICAgIGNvbnN0IHN0cmVhbSA9IGF3YWl0IHdpdGhEZWFkbGluZShcbiAgICAgICAgICB3b3JsZC5zdHJlYW1zLmdldChcbiAgICAgICAgICAgIGdlbmVyYXRlSGVhbHRoQ2hlY2tSdW5JZChjb3JyZWxhdGlvbklkKSxcbiAgICAgICAgICAgIHN0cmVhbU5hbWVcbiAgICAgICAgICApLFxuICAgICAgICAgIHJlbWFpbmluZ01zXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5nZXRSZWFkZXIoKTtcbiAgICAgICAgY29uc3QgeyBjaHVua3MsIHRpbWVkT3V0IH0gPSBhd2FpdCByZWFkU3RyZWFtV2l0aFRpbWVvdXQoXG4gICAgICAgICAgcmVhZGVyLFxuICAgICAgICAgIEhFQUxUSF9DSEVDS19SRUFEX1RJTUVPVVRcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAodGltZWRPdXQpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmVhZGVyLmNhbmNlbCgpO1xuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLy8gSWdub3JlIGNhbmNlbCBlcnJvcnNcbiAgICAgICAgICB9XG4gICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+XG4gICAgICAgICAgICBzZXRUaW1lb3V0KHJlc29sdmUsIEhFQUxUSF9DSEVDS19QT0xMX0lOVEVSVkFMKVxuICAgICAgICAgICk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IHBhcnNlSGVhbHRoQ2hlY2tSZXNwb25zZShjaHVua3MpO1xuICAgICAgICBpZiAocmVzcG9uc2UpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4ucmVzcG9uc2UsXG4gICAgICAgICAgICBsYXRlbmN5TXM6IERhdGUubm93KCkgLSBzdGFydFRpbWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PlxuICAgICAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgSEVBTFRIX0NIRUNLX1BPTExfSU5URVJWQUwpXG4gICAgICAgICk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+XG4gICAgICAgICAgc2V0VGltZW91dChyZXNvbHZlLCBIRUFMVEhfQ0hFQ0tfUE9MTF9JTlRFUlZBTClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGhlYWx0aHk6IGZhbHNlLFxuICAgICAgZXJyb3I6IGBIZWFsdGggY2hlY2sgdGltZWQgb3V0IGFmdGVyICR7dGltZW91dH1tc2AsXG4gICAgfTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaGVhbHRoeTogZmFsc2UsXG4gICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgIH07XG4gIH1cbn1cblxuZnVuY3Rpb24gZXZlbnRQYWdpbmF0aW9uQ29udHJhY3RFcnJvcihcbiAgcnVuSWQ6IHN0cmluZyxcbiAgbWVzc2FnZTogc3RyaW5nXG4pOiBXb3JrZmxvd1dvcmxkRXJyb3Ige1xuICByZXR1cm4gbmV3IFdvcmtmbG93V29ybGRFcnJvcihcbiAgICBgRXZlbnQgcGFnaW5hdGlvbiAke21lc3NhZ2V9IGZvciB3b3JrZmxvdyBydW4gXCIke3J1bklkfVwiLmAsXG4gICAgeyBjb2RlOiBSVU5fRVJST1JfQ09ERVMuV09STERfQ09OVFJBQ1RfRVJST1IgfVxuICApO1xufVxuXG5mdW5jdGlvbiByZWNvcmRSZXF1ZXN0ZWRFdmVudEN1cnNvcihcbiAgcnVuSWQ6IHN0cmluZyxcbiAgY3Vyc29yOiBzdHJpbmcgfCBudWxsLFxuICByZXF1ZXN0ZWRDdXJzb3JzOiBTZXQ8c3RyaW5nPlxuKTogdm9pZCB7XG4gIGlmICghY3Vyc29yKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChyZXF1ZXN0ZWRDdXJzb3JzLmhhcyhjdXJzb3IpKSB7XG4gICAgdGhyb3cgZXZlbnRQYWdpbmF0aW9uQ29udHJhY3RFcnJvcihydW5JZCwgJ2RpZCBub3QgYWR2YW5jZScpO1xuICB9XG4gIHJlcXVlc3RlZEN1cnNvcnMuYWRkKGN1cnNvcik7XG59XG5cbi8qKlxuICogQXBwZW5kcyBldmVudHMgd2hvc2UgSURzIGFyZSBub3QgYWxyZWFkeSBwcmVzZW50IGluIGB0YXJnZXRgLlxuICpcbiAqIFBhc3MgdGhlIElEcyBjdXJyZW50bHkgcHJlc2VudCBpbiBgdGFyZ2V0YCB3aGVuIGFwcGVuZGluZyByZXBlYXRlZGx5IHRvIHRoZVxuICogc2FtZSBhcnJheS4gVGhlIHNldCBpcyB1cGRhdGVkIGFsb25nc2lkZSBgdGFyZ2V0YC5cbiAqXG4gKiBFdmVudHMgYXJlIGFwcGVuZGVkIGluIHRoZSBvcmRlciB0aGUgV29ybGQgcmV0dXJuZWQgdGhlbSwgYW5kIGFyZSBub3RcbiAqIHJlLXNvcnRlZDogYSBXb3JsZCdzIGNhbm9uaWNhbCBvcmRlciBpcyBpdHMgb3duLCBhbmQgdGhlIHJ1bnRpbWUgY2Fubm90XG4gKiByZXByb2R1Y2UgaXQgZnJvbSBldmVudCBpZHMgYWxvbmUuIGB3b3JsZC12ZXJjZWxgIG9yZGVycyBieSBldmVudCBpZCwgd2hpbGVcbiAqIGB3b3JsZC1sb2NhbGAgb3JkZXJzIGJ5IGAoY3JlYXRlZEF0LCBldmVudElkKWAgYW5kIGRlbGliZXJhdGVseSByZS1taW50cyBrZXlzXG4gKiBzbyB0aGF0IHRoZSB0d28gZGl2ZXJnZS4gRXZlcnkgYXBwZW5kIHNvdXJjZSBpcyBhbHJlYWR5IGluIGNhbm9uaWNhbCBvcmRlclxuICogcmVsYXRpdmUgdG8gdGhlIHRhaWwgKGEgY3Vyc29yLWRlbGltaXRlZCBwYWdlLCBvciBhIHdyaXRlLXJlc3BvbnNlIGRlbHRhKSwgc29cbiAqIHJlY2VpcHQgb3JkZXIgaXMgdGhlIG9yZGVyIHRvIGtlZXAuIE5vdGhpbmcgZG93bnN0cmVhbSBtYXkgYXNzdW1lIHRoZSB0YWlsIGlzXG4gKiB0aGUgbmV3ZXN0IGV2ZW50IOKAlCBzZWUge0BsaW5rIGxhdGVzdEV2ZW50U3RhdGVVcGRhdGVkQXR9LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwZW5kVW5pcXVlRXZlbnRzKFxuICB0YXJnZXQ6IEV2ZW50W10sXG4gIGV2ZW50czogcmVhZG9ubHkgRXZlbnRbXSxcbiAgdGFyZ2V0SWRzPzogU2V0PHN0cmluZz5cbik6IHZvaWQge1xuICBpZiAoZXZlbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGlkcyA9IHRhcmdldElkcyA/PyBuZXcgU2V0KHRhcmdldC5tYXAoKGV2ZW50KSA9PiBldmVudC5ldmVudElkKSk7XG4gIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgaWYgKGlkcy5oYXMoZXZlbnQuZXZlbnRJZCkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZHMuYWRkKGV2ZW50LmV2ZW50SWQpO1xuICAgIHRhcmdldC5wdXNoKGV2ZW50KTtcbiAgfVxufVxuXG4vKipcbiAqIEluc2VydHMgYGV2ZW50YCBpbnRvIGB0YXJnZXRgIGF0IHRoZSBwb3NpdGlvbiB0aGF0IGtlZXBzIGB0YXJnZXRgIG9yZGVyZWQgYnlcbiAqIGFzY2VuZGluZyBgZXZlbnRJZGAsIG9yIG5vLW9wcyBpZiBhbiBldmVudCB3aXRoIHRoZSBzYW1lIGBldmVudElkYCBpcyBhbHJlYWR5XG4gKiBwcmVzZW50IChpZGVtcG90ZW50KS5cbiAqXG4gKiBgcHJlbG9hZGVkRXZlbnRzYCBpcyBsb2FkZWQgYHNvcnRPcmRlcjogJ2FzYydgIGFuZCBpcyBuZXZlciByZS1zb3J0ZWRcbiAqIGNsaWVudC1zaWRlLCBzbyBhIGBob29rX3JlY2VpdmVkYCBzcGxpY2VkIGluIGJ5IHRoZSBsYXp5LXJlc3VtZSBjb25zdW1lciBtdXN0XG4gKiBsYW5kIGluIGBldmVudElkYCBvcmRlciDigJQgYSBwbGFpbiBgcHVzaGAgd291bGQgcGxhY2UgYSBsYXRlLWNvbW1pdHRpbmdcbiAqIGVhcmxpZXIgZXZlbnQgYWZ0ZXIgZXZlbnRzIHRoYXQgc29ydCBiZWZvcmUgaXQsIGNvcnJ1cHRpbmcgcmVwbGF5LiBFdmVudCBJRHNcbiAqIGFyZSBVTElEcywgc28gbGV4aWNvZ3JhcGhpYyBzdHJpbmcgb3JkZXIgbWF0Y2hlcyBjb21taXQgb3JkZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnNlcnRFdmVudEJ5RXZlbnRJZCh0YXJnZXQ6IEV2ZW50W10sIGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAvLyBMaW5lYXIgc2NhbiBmcm9tIHRoZSBlbmQ6IHRoZSBzcGxpY2VkIGV2ZW50IGlzIGFsbW9zdCBhbHdheXMgdGhlIG5ld2VzdFxuICAvLyAoaXQgc29ydHMgYXQgb3IgbmVhciB0aGUgdGFpbCksIHNvIHRoaXMgZmluZHMgdGhlIHNsb3QgaW4gTygxKeKAk08oaykgZm9yIHRoZVxuICAvLyBjb21tb24gY2FzZSB3aGlsZSBzdGlsbCBoYW5kbGluZyBhbiBvdXQtb2Ytb3JkZXIgbGF0ZSBhcnJpdmFsIGNvcnJlY3RseS5cbiAgbGV0IGkgPSB0YXJnZXQubGVuZ3RoO1xuICB3aGlsZSAoaSA+IDApIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHRhcmdldFtpIC0gMV07XG4gICAgaWYgKGV4aXN0aW5nLmV2ZW50SWQgPT09IGV2ZW50LmV2ZW50SWQpIHtcbiAgICAgIC8vIEFscmVhZHkgcHJlc2VudCDigJQga2VlcCB0aGUgc3BsaWNlIGlkZW1wb3RlbnQuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChleGlzdGluZy5ldmVudElkIDwgZXZlbnQuZXZlbnRJZCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGktLTtcbiAgfVxuICB0YXJnZXQuc3BsaWNlKGksIDAsIGV2ZW50KTtcbn1cblxuZnVuY3Rpb24gYXNzZXJ0RXZlbnRQYWdpbmF0aW9uUHJvZ3Jlc3MoXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGhhc01vcmU6IGJvb2xlYW4sXG4gIGN1cnNvcjogc3RyaW5nIHwgbnVsbCxcbiAgcmVxdWVzdGVkQ3Vyc29yczogU2V0PHN0cmluZz5cbik6IHZvaWQge1xuICBpZiAoIWhhc01vcmUpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKGN1cnNvciA9PT0gbnVsbCkge1xuICAgIHRocm93IGV2ZW50UGFnaW5hdGlvbkNvbnRyYWN0RXJyb3IoXG4gICAgICBydW5JZCxcbiAgICAgICdyZXR1cm5lZCBtb3JlIHBhZ2VzIHdpdGhvdXQgYSBjdXJzb3InXG4gICAgKTtcbiAgfVxuICBpZiAocmVxdWVzdGVkQ3Vyc29ycy5oYXMoY3Vyc29yKSkge1xuICAgIHRocm93IGV2ZW50UGFnaW5hdGlvbkNvbnRyYWN0RXJyb3IocnVuSWQsICdyZXBlYXRlZCBhIGN1cnNvcicpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNob3VsZFJldHJ5V2l0aG91dEV2ZW50Q3Vyc29yKFxuICBlcnJvcjogdW5rbm93bixcbiAgY3Vyc29yOiBzdHJpbmcgfCBudWxsLFxuICBhbHJlYWR5UmV0cmllZDogYm9vbGVhblxuKTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgY3Vyc29yICE9PSBudWxsICYmXG4gICAgIWFscmVhZHlSZXRyaWVkICYmXG4gICAgV29ya2Zsb3dXb3JsZEVycm9yLmlzKGVycm9yKSAmJlxuICAgIGVycm9yLnN0YXR1cyA9PT0gNDAwXG4gICk7XG59XG5cbi8qKlxuICogTG9hZHMgd29ya2Zsb3cgcnVuIGV2ZW50cyBieSBpdGVyYXRpbmcgdGhyb3VnaCBhbGwgcGFnZXMgb2YgcGFnaW5hdGVkXG4gKiByZXN1bHRzLiBFdmVudHMgYXJlIHJldHVybmVkIGluIGNocm9ub2xvZ2ljYWwgKGFzY2VuZGluZykgb3JkZXIgZm9yXG4gKiBkZXRlcm1pbmlzdGljIHdvcmtmbG93IHJlcGxheS5cbiAqXG4gKiBAcGFyYW0gcnVuSWQgLSBUaGUgd29ya2Zsb3cgcnVuIElELlxuICogQHBhcmFtIGFmdGVyQ3Vyc29yIC0gSWYgcHJvdmlkZWQsIG9ubHkgZXZlbnRzIGFmdGVyIHRoaXMgY3Vyc29yIGFyZVxuICogICByZXR1cm5lZCAoaW5jcmVtZW50YWwgbG9hZCkuIElmIG9taXR0ZWQsIGFsbCBldmVudHMgYXJlIHJldHVybmVkLlxuICogICBUaGUgcmV0dXJuZWQgY3Vyc29yIGNhbiBiZSBwYXNzZWQgYmFjayBpbiBvbiBhIHN1YnNlcXVlbnQgY2FsbCBmb3JcbiAqICAgaW5jcmVtZW50YWwgbG9hZGluZy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvYWRXb3JrZmxvd1J1bkV2ZW50cyhcbiAgcnVuSWQ6IHN0cmluZyxcbiAgYWZ0ZXJDdXJzb3I/OiBzdHJpbmdcbik6IFByb21pc2U8eyBldmVudHM6IEV2ZW50W107IGN1cnNvcjogc3RyaW5nIHwgbnVsbCB9PiB7XG4gIGNvbnN0IGluY3JlbWVudGFsID0gYWZ0ZXJDdXJzb3IgIT09IHVuZGVmaW5lZDtcbiAgcmV0dXJuIHRyYWNlKFxuICAgIGluY3JlbWVudGFsID8gJ3dvcmtmbG93LmxvYWROZXdFdmVudHMnIDogJ3dvcmtmbG93LmxvYWRFdmVudHMnLFxuICAgIGFzeW5jIChzcGFuKSA9PiB7XG4gICAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93UnVuSWQocnVuSWQpLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGxvYWRlZEV2ZW50czogRXZlbnRbXSA9IFtdO1xuICAgICAgY29uc3QgbG9hZGVkRXZlbnRJZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICAgIGNvbnN0IHJlcXVlc3RlZEN1cnNvcnMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICAgIGxldCBjdXJzb3I6IHN0cmluZyB8IG51bGwgPSBhZnRlckN1cnNvciA/PyBudWxsO1xuICAgICAgbGV0IGhhc01vcmUgPSB0cnVlO1xuICAgICAgbGV0IHBhZ2VzTG9hZGVkID0gMDtcbiAgICAgIGxldCByZXRyaWVkV2l0aG91dEN1cnNvciA9IGZhbHNlO1xuXG4gICAgICBjb25zdCB3b3JsZCA9IGF3YWl0IGdldFdvcmxkTGF6eSgpO1xuICAgICAgY29uc3QgbG9hZFN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgIHdoaWxlIChoYXNNb3JlKSB7XG4gICAgICAgIC8vIFRPRE86IHdlJ3JlIGN1cnJlbnRseSBsb2FkaW5nIGFsbCB0aGUgZGF0YSB3aXRoIHJlc29sdmVSZWYgYmVoYXZpb3VyLiBXZSBuZWVkIHRvIHVwZGF0ZSB0aGlzXG4gICAgICAgIC8vIHRvIGxhenlsb2FkIHRoZSBkYXRhIGZyb20gdGhlIHdvcmxkIGluc3RlYWQgc28gdGhhdCB3ZSBjYW4gb3B0aW1pemUgYW5kIG1ha2UgdGhlIGV2ZW50IGxvZyBsb2FkaW5nXG4gICAgICAgIC8vIG11Y2ggZmFzdGVyIGFuZCBtZW1vcnkgZWZmaWNpZW50XG4gICAgICAgIGNvbnN0IHBhZ2VTdGFydCA9IERhdGUubm93KCk7XG4gICAgICAgIGNvbnN0IHJlcXVlc3RlZEN1cnNvciA9IGN1cnNvcjtcbiAgICAgICAgcmVjb3JkUmVxdWVzdGVkRXZlbnRDdXJzb3IocnVuSWQsIHJlcXVlc3RlZEN1cnNvciwgcmVxdWVzdGVkQ3Vyc29ycyk7XG5cbiAgICAgICAgbGV0IHJlc3BvbnNlOiBBd2FpdGVkPFJldHVyblR5cGU8dHlwZW9mIHdvcmxkLmV2ZW50cy5saXN0Pj47XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmVzcG9uc2UgPSBhd2FpdCB3b3JsZC5ldmVudHMubGlzdCh7XG4gICAgICAgICAgICBydW5JZCxcbiAgICAgICAgICAgIHBhZ2luYXRpb246IHtcbiAgICAgICAgICAgICAgc29ydE9yZGVyOiAnYXNjJyxcbiAgICAgICAgICAgICAgY3Vyc29yOiByZXF1ZXN0ZWRDdXJzb3IgPz8gdW5kZWZpbmVkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBzaG91bGRSZXRyeVdpdGhvdXRFdmVudEN1cnNvcihcbiAgICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICAgIHJlcXVlc3RlZEN1cnNvcixcbiAgICAgICAgICAgICAgcmV0cmllZFdpdGhvdXRDdXJzb3JcbiAgICAgICAgICAgIClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIud2FybihcbiAgICAgICAgICAgICAgJ0V2ZW50IGN1cnNvciB3YXMgcmVqZWN0ZWQ7IHJldHJ5aW5nIHdpdGggYSBmdWxsIGV2ZW50IHJlbG9hZC4nLFxuICAgICAgICAgICAgICB7IHdvcmtmbG93UnVuSWQ6IHJ1bklkIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBsb2FkZWRFdmVudHMubGVuZ3RoID0gMDtcbiAgICAgICAgICAgIGxvYWRlZEV2ZW50SWRzLmNsZWFyKCk7XG4gICAgICAgICAgICByZXF1ZXN0ZWRDdXJzb3JzLmNsZWFyKCk7XG4gICAgICAgICAgICBjdXJzb3IgPSBudWxsO1xuICAgICAgICAgICAgcmV0cmllZFdpdGhvdXRDdXJzb3IgPSB0cnVlO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgYXBwZW5kVW5pcXVlRXZlbnRzKGxvYWRlZEV2ZW50cywgcmVzcG9uc2UuZGF0YSwgbG9hZGVkRXZlbnRJZHMpO1xuICAgICAgICBoYXNNb3JlID0gcmVzcG9uc2UuaGFzTW9yZTtcbiAgICAgICAgYXNzZXJ0RXZlbnRQYWdpbmF0aW9uUHJvZ3Jlc3MoXG4gICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgaGFzTW9yZSxcbiAgICAgICAgICByZXNwb25zZS5jdXJzb3IsXG4gICAgICAgICAgcmVxdWVzdGVkQ3Vyc29yc1xuICAgICAgICApO1xuICAgICAgICAvLyBQcmVzZXJ2ZSB0aGUgbGFzdCBub24tbnVsbCBjdXJzb3IgYWNyb3NzIHBhZ2VzLiBBIFdvcmxkIG1heVxuICAgICAgICAvLyBsZWdpdGltYXRlbHkgcmV0dXJuIGB7IGRhdGE6IFtdLCBjdXJzb3I6IG51bGwsIGhhc01vcmU6IGZhbHNlIH1gXG4gICAgICAgIC8vIG9uIGEgdHJhaWxpbmcgZW1wdHkgcGFnZSDigJQgZm9yIGV4YW1wbGUgd2hlbiB0aGUgcHJldmlvdXMgcGFnZSdzXG4gICAgICAgIC8vIHVuZGVybHlpbmcgREIgcXVlcnkgaGl0IHRoZSBsaW1pdCBleGFjdGx5IGFuZCByZXR1cm5lZCBhXG4gICAgICAgIC8vIGBMYXN0RXZhbHVhdGVkS2V5YCBcImp1c3QgaW4gY2FzZVwiLiBPdmVyd3JpdGluZyB3aXRoIHRoYXQgbnVsbFxuICAgICAgICAvLyB3b3VsZCBsb3NlIHRoZSBwb3NpdGlvbiBwYXN0IHRoZSBsYXN0IHJlYWwgZXZlbnQgd2UgbG9hZGVkIGFuZFxuICAgICAgICAvLyBmb3JjZSB0aGUgcnVudGltZSBpbnRvIHRoZSBcIm5vIGN1cnNvciBhZnRlciBpbml0aWFsIGxvYWRcIiBmdWxsLVxuICAgICAgICAvLyByZWxvYWQgZmFsbGJhY2sgb24gZXZlcnkgc3Vic2VxdWVudCByZXBsYXkgaXRlcmF0aW9uLlxuICAgICAgICBjdXJzb3IgPSByZXNwb25zZS5jdXJzb3IgPz8gY3Vyc29yO1xuICAgICAgICBwYWdlc0xvYWRlZCsrO1xuXG4gICAgICAgIHJ1bnRpbWVMb2dnZXIuZGVidWcoJ0xvYWRlZCBldmVudCBwYWdlJywge1xuICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICAgIGluY3JlbWVudGFsLFxuICAgICAgICAgIHBhZ2U6IHBhZ2VzTG9hZGVkLFxuICAgICAgICAgIHBhZ2VFdmVudHM6IHJlc3BvbnNlLmRhdGEubGVuZ3RoLFxuICAgICAgICAgIHRvdGFsRXZlbnRzOiBsb2FkZWRFdmVudHMubGVuZ3RoLFxuICAgICAgICAgIGhhc01vcmUsXG4gICAgICAgICAgcGFnZU1zOiBEYXRlLm5vdygpIC0gcGFnZVN0YXJ0LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcnVudGltZUxvZ2dlci5kZWJ1ZygnRXZlbnQgbG9hZCBjb21wbGV0ZScsIHtcbiAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgIGluY3JlbWVudGFsLFxuICAgICAgICB0b3RhbEV2ZW50czogbG9hZGVkRXZlbnRzLmxlbmd0aCxcbiAgICAgICAgcGFnZXNMb2FkZWQsXG4gICAgICAgIHRvdGFsTXM6IERhdGUubm93KCkgLSBsb2FkU3RhcnQsXG4gICAgICB9KTtcblxuICAgICAgc3Bhbj8uc2V0QXR0cmlidXRlcyh7XG4gICAgICAgIC4uLkF0dHJpYnV0ZS5Xb3JrZmxvd0V2ZW50c0NvdW50KGxvYWRlZEV2ZW50cy5sZW5ndGgpLFxuICAgICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dFdmVudHNQYWdlc0xvYWRlZChwYWdlc0xvYWRlZCksXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHsgZXZlbnRzOiBsb2FkZWRFdmVudHMsIGN1cnNvciB9O1xuICAgIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBUaGUgcnVudGltZSdzIGxvYWRlZCBldmVudC1sb2cgc25hcHNob3Q6IHRoZSBldmVudHMgcmVwbGF5ZWQgc28gZmFyIGFuZCB0aGVcbiAqIGN1cnNvciBwb3NpdGlvbmVkIGFmdGVyIHRoZW0uIEhhbmRlZCB0byBoZWxwZXJzIHRoYXQgZGVyaXZlIHRoZSBwcmVjb25kaXRpb25cbiAqIHNuYXBzaG90IGZyb20gaXQ7IHRoZXkgZG8gbm90IG11dGF0ZSBpdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMb2FkZWRFdmVudExvZyB7XG4gIGV2ZW50czogRXZlbnRbXTtcbiAgY3Vyc29yOiBzdHJpbmcgfCBudWxsO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgdGhlIG9wdGltaXN0aWMtY29uY3VycmVuY3kgZ3VhcmQgZm9yIGV2ZW50IGNyZWF0aW9uIGlzIGVuYWJsZWQuXG4gKiAqKk9uIGJ5IGRlZmF1bHQqKiB3aGVyZSB0aGUgcnVudGltZSBleGVjdXRlczogcmVwbGF5LWNvbnRleHQgY3JlYXRlcyBzZW5kIGFcbiAqIGBzdGF0ZVVwZGF0ZWRBdGAgc25hcHNob3QgKGFuZCBjYW4gYmUgcmVqZWN0ZWQgd2l0aCA0MTIgYnkgYSBzdXBwb3J0aW5nXG4gKiBiYWNrZW5kKSB1bmxlc3MgYFdPUktGTE9XX1BSRUNPTkRJVElPTl9HVUFSRGAgaXMgc2V0IHRvIGAwYC4gQmFja2VuZHMgd2l0aG91dFxuICogZ3VhcmQgc3VwcG9ydCBpZ25vcmUgdGhlIHNuYXBzaG90LCBzbyBlbmFibGluZyBieSBkZWZhdWx0IGlzXG4gKiBiYWNrd2FyZC1jb21wYXRpYmxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNQcmVjb25kaXRpb25HdWFyZEVuYWJsZWQoKTogYm9vbGVhbiB7XG4gIHJldHVybiBwcm9jZXNzLmVudi5XT1JLRkxPV19QUkVDT05ESVRJT05fR1VBUkQgIT09ICcwJztcbn1cblxuLyoqXG4gKiBUaGUgYHN0YXRlVXBkYXRlZEF0YCB2YWx1ZSB0byBzZW5kIHdpdGggYSByZXBsYXktY29udGV4dCBldmVudCBjcmVhdGlvbjogdGhlXG4gKiAqbWF4aW11bSogVUxJRCB0aW1lIChlcG9jaCBtcykgb3ZlciB0aGUgZXZlbnRzIHRoZSBydW50aW1lIGhhcyBsb2FkZWQuIFJldHVybnNcbiAqIGB1bmRlZmluZWRgIHdoZW4gdGhlcmUgYXJlIG5vIGV2ZW50cyBvciB0aGF0IGlkIGlzIG5vdCBhIGRlY29kYWJsZSBVTElELlxuICpcbiAqIEl0IGlzIHRoZSBtYXhpbXVtIHJhdGhlciB0aGFuIHRoZSB0YWlsJ3MgYmVjYXVzZSB0aGUgbG9hZGVkIGxvZyBpcyBpbiB0aGVcbiAqIFdvcmxkJ3MgY2Fub25pY2FsIG9yZGVyLCB3aGljaCBpcyBub3QgbmVjZXNzYXJpbHkgZXZlbnQtaWQgb3JkZXIgKHNlZVxuICoge0BsaW5rIGFwcGVuZFVuaXF1ZUV2ZW50c30pLiBUaGUgbWF4aW11bSBpcyB3aGF0IGxldHMgdGhlIGNvdW50IHNlbnQgYWxvbmdzaWRlXG4gKiBpdCBiZSByZWFkIGFzIFwiZXZlbnRzIGF0IG9yIGJlbG93IHRoaXMgd2F0ZXJtYXJrXCI6IGV2ZXJ5IGxvYWRlZCBldmVudCBpcyBhdCBvclxuICogYmVsb3cgaXQsIHNvIHRoZSBjb3VudCBpcyBleGFjdGx5IGBldmVudHMubGVuZ3RoYC4gUmVhZGluZyB0aGUgdGFpbCBpbnN0ZWFkXG4gKiB3b3VsZCB1bmRlcnN0YXRlIHRoZSB3YXRlcm1hcmsgb24gYSBXb3JsZCB3aG9zZSBvcmRlciBpcyBub3QgaWQtb3JkZXJlZCwgd2hpY2hcbiAqIGlzIHNhZmUgKGl0IGNhbiBvbmx5IHdlYWtlbiBkZXRlY3Rpb24pIGJ1dCBuZWVkbGVzc2x5IGltcHJlY2lzZS5cbiAqXG4gKiBUaGUgbWF4aW11bSBpcyBmb3VuZCBieSBsZXhpY29ncmFwaGljIGlkIGNvbXBhcmlzb24sIGRlY29kaW5nIG9ubHkgb25jZTogdGhlXG4gKiAyNi1jaGFyYWN0ZXIgQ3JvY2tmb3JkIFVMSUQgZW5jb2RlcyBpdHMgdGltZXN0YW1wIGluIHRoZSBsZWFkaW5nIDEwXG4gKiBjaGFyYWN0ZXJzLCBzbyB0aGUgZ3JlYXRlc3QgaWQgYWxzbyBjYXJyaWVzIHRoZSBncmVhdGVzdCB0aW1lLlxuICpcbiAqIEdyYW51bGFyaXR5OiBzbmFwc2hvdHMgYXJlIGVwb2NoLW1pbGxpc2Vjb25kcywgYW5kIHRoZSBiYWNrZW5kIGFsbG93cyBhblxuICogZXF1YWwtdGltZXN0YW1wIHNuYXBzaG90IChhbiB1cC10by1kYXRlIGNsaWVudCBtdXN0IG5vdCBiZSByZWplY3RlZCkuIFR3b1xuICogb3V0LW9mLWJhbmQgZXZlbnRzIGxhbmRpbmcgaW4gdGhlIHNhbWUgbWlsbGlzZWNvbmQgd2hlcmUgb25seSB0aGUgZmlyc3Qgd2FzXG4gKiBsb2FkZWQgdGhlcmVmb3JlIHBhc3MgdGhpcyBoYWxmIG9mIHRoZSBndWFyZCB1bmRldGVjdGVkIOKAlCB0aGF0IGlzIGV4YWN0bHlcbiAqIHRoZSBob2xlIGBzdGF0ZUV2ZW50Q291bnRgIGNsb3Nlcywgc2luY2UgdGhlIGNvdW50IG9mIGV2ZW50cyBhdCBvciBiZWxvdyB0aGVcbiAqIHdhdGVybWFyayBkaWZmZXJzIGV2ZW4gd2hlbiB0aGUgd2F0ZXJtYXJrcyBhcmUgZXF1YWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsYXRlc3RFdmVudFN0YXRlVXBkYXRlZEF0KGV2ZW50czogRXZlbnRbXSk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIGxldCBsYXRlc3Q6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgZm9yIChjb25zdCBldmVudCBvZiBldmVudHMpIHtcbiAgICBpZiAobGF0ZXN0ID09PSB1bmRlZmluZWQgfHwgZXZlbnQuZXZlbnRJZCA+IGxhdGVzdCkge1xuICAgICAgbGF0ZXN0ID0gZXZlbnQuZXZlbnRJZDtcbiAgICB9XG4gIH1cbiAgaWYgKGxhdGVzdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICAvLyBFdmVudCBJRHMgYXJlIHByZWZpeGVkIFVMSURzIChlLmcuIGBldm50XzAxQVJZWi4uLmApOyB1bGlkVG9EYXRlIG9ubHlcbiAgLy8gZGVjb2RlcyB0aGUgYmFyZSAyNi1jaGFyIFVMSUQsIHNvIHN0cmlwIHRoZSBwcmVmaXggZmlyc3QuXG4gIGNvbnN0IGV2ZW50SWQgPSBsYXRlc3Q7XG4gIGNvbnN0IHVuZGVyc2NvcmUgPSBldmVudElkLmxhc3RJbmRleE9mKCdfJyk7XG4gIGNvbnN0IHJhd1VsaWQgPSB1bmRlcnNjb3JlID09PSAtMSA/IGV2ZW50SWQgOiBldmVudElkLnNsaWNlKHVuZGVyc2NvcmUgKyAxKTtcbiAgY29uc3QgdGltZSA9IHVsaWRUb0RhdGUocmF3VWxpZCk/LmdldFRpbWUoKTtcbiAgaWYgKHRpbWUgPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIEZhaWwgb3BlbjogYSBub24tZGVjb2RhYmxlIGlkIGRpc2FybXMgdGhlIGd1YXJkIGZvciB0aGlzIGNyZWF0ZSAobm9cbiAgICAvLyBzbmFwc2hvdCBzZW50KS4gTG9nIHNvIGEgZmxlZXQtd2lkZSBzaWxlbnQgZGlzYXJtIGlzIGRpYWdub3NhYmxlLlxuICAgIHJ1bnRpbWVMb2dnZXIuZGVidWcoXG4gICAgICAnUHJlY29uZGl0aW9uIGd1YXJkOiBsYXRlc3QgZXZlbnQgaWQgaXMgbm90IGEgZGVjb2RhYmxlIFVMSUQ7IHNlbmRpbmcgbm8gc25hcHNob3QnLFxuICAgICAgeyBldmVudElkIH1cbiAgICApO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgcmV0dXJuIHRpbWU7XG59XG5cbi8qKlxuICogVGhlIHByZWNvbmRpdGlvbiBzbmFwc2hvdCBhIHJlcGxheS1jb250ZXh0IGV2ZW50IGNyZWF0aW9uIHNlbmRzLCBkZXNjcmliaW5nXG4gKiB0aGUgZXZlbnQgbG9nIHRoZSByZXBsYXkgZGVyaXZlZCB0aGUgZXZlbnQgZnJvbS5cbiAqXG4gKiBUaGUgdGhyZWUgZmllbGRzIGFyZSBvbmUgaW5kaXZpc2libGUgdW5pdDogdGhlIGJhY2tlbmQgcmVhZHMgdGhlIGNvdW50IG9ubHlcbiAqIHJlbGF0aXZlIHRvIHRoZSB3YXRlcm1hcmssIGFuZCByZXR1cm5zIGl0cyBpbmxpbmUgZGVsdGEgb25seSByZWxhdGl2ZSB0byB0aGVcbiAqIGN1cnNvci4gUGFzc2luZyB0aGVtIGFzIGEgc2luZ2xlIG9iamVjdCBpcyB3aGF0IGtlZXBzIHRoZW0gZnJvbSBkcmlmdGluZ1xuICogYXBhcnQgYXQgYSBjYWxsIHNpdGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJlY29uZGl0aW9uU25hcHNob3RQYXJhbXMge1xuICBzdGF0ZVVwZGF0ZWRBdD86IG51bWJlcjtcbiAgc3RhdGVFdmVudENvdW50PzogbnVtYmVyO1xuICBzdGF0ZUN1cnNvcj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBCdWlsZCB0aGUgcHJlY29uZGl0aW9uIHNuYXBzaG90IHRvIGF0dGFjaCB0byBhIHJlcGxheS1jb250ZXh0IGV2ZW50IGNyZWF0aW9uLlxuICpcbiAqIFJldHVybnMgYW4gZW1wdHkgb2JqZWN0IOKAlCBubyBndWFyZCwgYmFja2VuZCBiZWhhdmVzIGFzIGJlZm9yZSDigJQgd2hlbiB0aGVcbiAqIGd1YXJkIGlzIGRpc2FibGVkIG9yIHRoZSB3YXRlcm1hcmsgaXMgbm90IGRlcml2YWJsZS4gQWxsIHRocmVlIGZpZWxkcyBmYWlsXG4gKiBvcGVuIHRvZ2V0aGVyOiBhIGNvdW50IHdpdGhvdXQgYSB3YXRlcm1hcmsgaXMgbWVhbmluZ2xlc3MgdG8gdGhlIGJhY2tlbmQsIGFuZFxuICogYSBjdXJzb3Igd2l0aG91dCBlaXRoZXIgd291bGQgaW52aXRlIGEgZGVsdGEgbm9ib2R5IGFza2VkIGZvci5cbiAqXG4gKiBgc3RhdGVFdmVudENvdW50YCBpcyBgZXZlbnRzLmxlbmd0aGAgYmVjYXVzZSB0aGUgd2F0ZXJtYXJrIGlzIHRoZSBsb2cnc1xuICogKm1heGltdW0qIFVMSUQgdGltZSwgc28gZXZlcnkgbG9hZGVkIGV2ZW50IGlzIGF0IG9yIGJlbG93IGl0IHJlZ2FyZGxlc3Mgb2YgdGhlXG4gKiBvcmRlciB0aGUgV29ybGQgcmV0dXJuZWQgdGhlbSBpbi5cbiAqXG4gKiBCb3RoIGZpZWxkcyBhcmUgdGhlcmVmb3JlIGludmFyaWFudCB1bmRlciBwZXJtdXRhdGlvbiBvZiB0aGUgbG9nOiBhIG1heGltdW0gaXNcbiAqIG9yZGVyLWluZGVwZW5kZW50LCBhbmQgdGhlIGxlbmd0aCBpcyBzZXQgY2FyZGluYWxpdHkgb25jZSBgYXBwZW5kVW5pcXVlRXZlbnRzYFxuICogaGFzIGRlZHVwZWQgYnkgZXZlbnQgaWQuIFR3byByZXBsYXlzIHRoYXQgY29uc3VtZSB0aGUgc2FtZSBldmVudHMgaW4gZGlmZmVyZW50XG4gKiBvcmRlcnMgc2VuZCBhbiBpZGVudGljYWwgc25hcHNob3QsIHNvIHRoaXMgZ3VhcmQgZGV0ZWN0cyB0aGF0IGEgbG9nIGlzIG1pc3NpbmdcbiAqIGFuIGV2ZW50IGFuZCBjYW4gbmV2ZXIgZGV0ZWN0IHRoYXQgYSByZXBsYXkgY29uc3VtZWQgb25lIGluIGEgZGlmZmVyZW50IG9yZGVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJlY29uZGl0aW9uU25hcHNob3RQYXJhbXMoXG4gIGV2ZW50czogRXZlbnRbXSxcbiAgY3Vyc29yPzogc3RyaW5nIHwgbnVsbFxuKTogUHJlY29uZGl0aW9uU25hcHNob3RQYXJhbXMge1xuICBpZiAoIWlzUHJlY29uZGl0aW9uR3VhcmRFbmFibGVkKCkpIHtcbiAgICByZXR1cm4ge307XG4gIH1cbiAgY29uc3Qgc3RhdGVVcGRhdGVkQXQgPSBsYXRlc3RFdmVudFN0YXRlVXBkYXRlZEF0KGV2ZW50cyk7XG4gIGlmIChzdGF0ZVVwZGF0ZWRBdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIHJldHVybiB7XG4gICAgc3RhdGVVcGRhdGVkQXQsXG4gICAgc3RhdGVFdmVudENvdW50OiBldmVudHMubGVuZ3RoLFxuICAgIC4uLihjdXJzb3IgPyB7IHN0YXRlQ3Vyc29yOiBjdXJzb3IgfSA6IHt9KSxcbiAgfTtcbn1cblxuLyoqXG4gKiBUaGUgZXZlbnRzIGEgcmVqZWN0aW5nIFdvcmxkIGF0dGFjaGVkIHRvIGEgYFByZWNvbmRpdGlvbkZhaWxlZEVycm9yYCwgd2hlbiBpdFxuICogcmV0dXJuZWQgdGhlIG9uZXMgdGhlIGNsaWVudCdzIHNuYXBzaG90IHdhcyBtaXNzaW5nIGlubGluZS5cbiAqXG4gKiBSZXR1cm5zIGBudWxsYCBmb3IgYW55dGhpbmcgZWxzZSDigJQgbm8gZGV0YWlscywgYSBXb3JsZCB0aGF0IGRpZCBub3QgaW1wbGVtZW50XG4gKiB0aGlzLCBvciBhIHBheWxvYWQgdGhhdCBkb2VzIG5vdCBuYXJyb3cgY2xlYW5seS4gQ2FsbGVycyBmYWxsIGJhY2sgdG9cbiAqIHJlbG9hZGluZyB0aGUgZXZlbnQgbG9nLCB3aGljaCBpcyBhbHdheXMgY29ycmVjdDsgdGhpcyBpcyB1bnRydXN0ZWQtc2hhcGVkXG4gKiBkYXRhIG9uIGEgZmFpbHVyZSBwYXRoLCBzbyBub3RoaW5nIGhlcmUgaXMgcmVwYWlyZWQuXG4gKlxuICogYHJ1bklkYCBpcyB0aGUgY2FsbGVyJ3MgcnVuLiBFdmVyeSBldmVudCBtdXN0IGJlbG9uZyB0byBpdDogdGhlIGRlbHRhIGlzXG4gKiBtZXJnZWQgc3RyYWlnaHQgaW50byB0aGUgcmVwbGF5J3MgbG9nLCBhbmQgb25lIGZvcmVpZ24gZXZlbnQgdGhlcmUgaXMgYVxuICogY29ycnVwdCBsb2cgcmF0aGVyIHRoYW4gYSBjb3JyZWN0ZWQgb25lIOKAlCB0aGUgcmVwbGF5IHdvdWxkIGNvbnN1bWUgYVxuICogY29ycmVsYXRpb24gaWQgZm9yIGFuIGV2ZW50IHRoYXQgZG9lcyBub3QgZXhpc3Qgb24gdGhpcyBydW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcmVjb25kaXRpb25FdmVudERlbHRhKFxuICBlcnJvcjogdW5rbm93bixcbiAgcnVuSWQ6IHN0cmluZ1xuKTogeyBldmVudHM6IEV2ZW50W107IGN1cnNvcjogc3RyaW5nIHwgbnVsbCB9IHwgbnVsbCB7XG4gIGlmICghUHJlY29uZGl0aW9uRmFpbGVkRXJyb3IuaXMoZXJyb3IpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgY29uc3QgZGV0YWlscyA9IGVycm9yLmRldGFpbHM7XG4gIGlmICh0eXBlb2YgZGV0YWlscyAhPT0gJ29iamVjdCcgfHwgZGV0YWlscyA9PT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGNvbnN0IHsgZXZlbnRzLCBjdXJzb3IgfSA9IGRldGFpbHMgYXMgeyBldmVudHM/OiB1bmtub3duOyBjdXJzb3I/OiB1bmtub3duIH07XG4gIGlmICghQXJyYXkuaXNBcnJheShldmVudHMpIHx8IGV2ZW50cy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBmb3IgKGNvbnN0IGV2ZW50IG9mIGV2ZW50cykge1xuICAgIGlmIChcbiAgICAgIHR5cGVvZiBldmVudCAhPT0gJ29iamVjdCcgfHxcbiAgICAgIGV2ZW50ID09PSBudWxsIHx8XG4gICAgICB0eXBlb2YgKGV2ZW50IGFzIHsgZXZlbnRJZD86IHVua25vd24gfSkuZXZlbnRJZCAhPT0gJ3N0cmluZycgfHxcbiAgICAgIChldmVudCBhcyB7IHJ1bklkPzogdW5rbm93biB9KS5ydW5JZCAhPT0gcnVuSWRcbiAgICApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuICByZXR1cm4ge1xuICAgIGV2ZW50czogZXZlbnRzIGFzIEV2ZW50W10sXG4gICAgY3Vyc29yOiB0eXBlb2YgY3Vyc29yID09PSAnc3RyaW5nJyA/IGN1cnNvciA6IG51bGwsXG4gIH07XG59XG5cbi8qKiBDcmVhdGVzIG9uZSBldmVudCBvbiBhIGJvdW5kIHJ1biwgY2FycnlpbmcgcmVwbGF5LXJlY292ZXJ5IHRlbGVtZXRyeS4gKi9cbmV4cG9ydCB0eXBlIEV2ZW50Q3JlYXRvciA9IChcbiAgZGF0YTogQ3JlYXRlRXZlbnRSZXF1ZXN0LFxuICBwYXJhbXM/OiBDcmVhdGVFdmVudFBhcmFtc1xuKSA9PiBQcm9taXNlPEV2ZW50UmVzdWx0PjtcblxuLyoqXG4gKiBDT1JTIGhlYWRlcnMgZm9yIGhlYWx0aCBjaGVjayByZXNwb25zZXMuXG4gKiBBbGxvd3MgdGhlIG9ic2VydmFiaWxpdHkgVUkgdG8gY2hlY2sgZW5kcG9pbnQgaGVhbHRoIGZyb20gYSBkaWZmZXJlbnQgb3JpZ2luLlxuICovXG5jb25zdCBIRUFMVEhfQ0hFQ0tfQ09SU19IRUFERVJTID0ge1xuICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luJzogJyonLFxuICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctTWV0aG9kcyc6ICdQT1NULCBPUFRJT05TLCBHRVQsIEhFQUQnLFxuICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycyc6ICdDb250ZW50LVR5cGUnLFxufTtcblxuLyoqXG4gKiBXcmFwcyBhIHJlcXVlc3QvcmVzcG9uc2UgaGFuZGxlciBhbmQgYWRkcyBhIGhlYWx0aCBjaGVjayBcIm1vZGVcIlxuICogYmFzZWQgb24gdGhlIHByZXNlbmNlIG9mIGEgYF9faGVhbHRoYCBxdWVyeSBwYXJhbWV0ZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoSGVhbHRoQ2hlY2soXG4gIGhhbmRsZXI6IChyZXE6IFJlcXVlc3QpID0+IFByb21pc2U8UmVzcG9uc2U+LFxuICB3b3JsZFNwZWNWZXJzaW9uPzogbnVtYmVyXG4pOiAocmVxOiBSZXF1ZXN0KSA9PiBQcm9taXNlPFJlc3BvbnNlPiB7XG4gIHJldHVybiBhc3luYyAocmVxOiBSZXF1ZXN0KSA9PiB7XG4gICAgY29uc3QgdXJsID0gbmV3IFVSTChyZXEudXJsKTtcbiAgICBjb25zdCBpc0hlYWx0aENoZWNrID0gdXJsLnNlYXJjaFBhcmFtcy5oYXMoJ19faGVhbHRoJyk7XG4gICAgaWYgKGlzSGVhbHRoQ2hlY2spIHtcbiAgICAgIC8vIEhhbmRsZSBDT1JTIHByZWZsaWdodCBmb3IgaGVhbHRoIGNoZWNrXG4gICAgICBpZiAocmVxLm1ldGhvZCA9PT0gJ09QVElPTlMnKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UobnVsbCwge1xuICAgICAgICAgIHN0YXR1czogMjA0LFxuICAgICAgICAgIGhlYWRlcnM6IEhFQUxUSF9DSEVDS19DT1JTX0hFQURFUlMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgIGhlYWx0aHk6IHRydWUsXG4gICAgICAgICAgZW5kcG9pbnQ6IHVybC5wYXRobmFtZSxcbiAgICAgICAgICBzcGVjVmVyc2lvbjogd29ybGRTcGVjVmVyc2lvbiA/PyBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICAgICAgICB3b3JrZmxvd0NvcmVWZXJzaW9uLFxuICAgICAgICB9KSxcbiAgICAgICAge1xuICAgICAgICAgIHN0YXR1czogMjAwLFxuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICAuLi5IRUFMVEhfQ0hFQ0tfQ09SU19IRUFERVJTLFxuICAgICAgICAgIH0sXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBhd2FpdCBoYW5kbGVyKHJlcSk7XG4gIH07XG59XG5cbi8qKlxuICogUXVldWVzIGEgbWVzc2FnZSB0byB0aGUgc3BlY2lmaWVkIHF1ZXVlIHdpdGggdHJhY2luZy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHF1ZXVlTWVzc2FnZShcbiAgd29ybGQ6IFdvcmxkLFxuICAuLi5hcmdzOiBQYXJhbWV0ZXJzPHR5cGVvZiB3b3JsZC5xdWV1ZT5cbikge1xuICBjb25zdCBxdWV1ZU5hbWUgPSBhcmdzWzBdO1xuICBhd2FpdCB0cmFjZShcbiAgICAncXVldWUucHVibGlzaCcsXG4gICAge1xuICAgICAgLy8gU3RhbmRhcmQgT1RFTCBtZXNzYWdpbmcgY29udmVudGlvbnNcbiAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgLi4uQXR0cmlidXRlLk1lc3NhZ2luZ1N5c3RlbSgndmVyY2VsLXF1ZXVlJyksXG4gICAgICAgIC4uLkF0dHJpYnV0ZS5NZXNzYWdpbmdEZXN0aW5hdGlvbk5hbWUocXVldWVOYW1lKSxcbiAgICAgICAgLi4uQXR0cmlidXRlLk1lc3NhZ2luZ09wZXJhdGlvblR5cGUoJ3B1Ymxpc2gnKSxcbiAgICAgICAgLy8gUGVlciBzZXJ2aWNlIGZvciBEYXRhZG9nIHNlcnZpY2UgbWFwc1xuICAgICAgICAuLi5BdHRyaWJ1dGUuUGVlclNlcnZpY2UoJ3ZlcmNlbC1xdWV1ZScpLFxuICAgICAgICAuLi5BdHRyaWJ1dGUuUnBjU3lzdGVtKCd2ZXJjZWwtcXVldWUnKSxcbiAgICAgICAgLi4uQXR0cmlidXRlLlJwY1NlcnZpY2UoJ3ZxcycpLFxuICAgICAgICAuLi5BdHRyaWJ1dGUuUnBjTWV0aG9kKCdwdWJsaXNoJyksXG4gICAgICB9LFxuICAgICAga2luZDogYXdhaXQgZ2V0U3BhbktpbmQoJ1BST0RVQ0VSJyksXG4gICAgfSxcbiAgICBhc3luYyAoc3BhbikgPT4ge1xuICAgICAgY29uc3QgeyBtZXNzYWdlSWQgfSA9IGF3YWl0IHdvcmxkLnF1ZXVlKC4uLmFyZ3MpO1xuICAgICAgaWYgKG1lc3NhZ2VJZCkge1xuICAgICAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKEF0dHJpYnV0ZS5NZXNzYWdpbmdNZXNzYWdlSWQobWVzc2FnZUlkKSk7XG4gICAgICB9XG4gICAgfVxuICApO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHF1ZXVlIG92ZXJoZWFkIHRpbWUgaW4gbWlsbGlzZWNvbmRzIGZvciBhIGdpdmVuIG1lc3NhZ2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRRdWV1ZU92ZXJoZWFkKG1lc3NhZ2U6IHsgcmVxdWVzdGVkQXQ/OiBEYXRlIH0pIHtcbiAgaWYgKCFtZXNzYWdlLnJlcXVlc3RlZEF0KSByZXR1cm47XG4gIHRyeSB7XG4gICAgcmV0dXJuIEF0dHJpYnV0ZS5RdWV1ZU92ZXJoZWFkTXMoXG4gICAgICBEYXRlLm5vdygpIC0gbWVzc2FnZS5yZXF1ZXN0ZWRBdC5nZXRUaW1lKClcbiAgICApO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm47XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgbWVtb2l6ZWQgYWNjZXNzb3IgZm9yIGEgcnVuJ3MgZnVsbCBlbmNyeXB0aW9uIGNhcGFiaWxpdHkuXG4gKlxuICogVGhlIGZpcnN0IGNhbGwgcmVzb2x2ZXMgdGhlIHJ1bidzIGtleSBtYXRlcmlhbCB2aWFcbiAqIGB3b3JsZC5nZXRFbmNyeXB0aW9uS2V5Rm9yUnVuYCAod2hpY2ggbWF5IGRvIEhLREYgZGVyaXZhdGlvbiBsb2NhbGx5IG9uXG4gKiBWZXJjZWwsIG9yIGEgbmV0d29yayBmZXRjaCBmcm9tIGV4dGVybmFsIGNvbnRleHRzKSBhbmQgZGVyaXZlcyBhXG4gKiB7QGxpbmsgUGF5bG9hZEtleX0gZnJvbSBpdDsgc3Vic2VxdWVudCBjYWxscyBhd2FpdCB0aGUgc2FtZSBjYWNoZWQgcHJvbWlzZS5cbiAqIElmIHRoZSB3b3JsZCBkb2Vzbid0IHN1cHBvcnQgZW5jcnlwdGlvbiBvciB0aGUgcnVuIGhhcyBubyBrZXkgY29uZmlndXJlZCxcbiAqIHRoZSBjYWNoZWQgdmFsdWUgaXMgYHVuZGVmaW5lZGAuXG4gKlxuICogVGhlIHJlc29sdmVkIHZhbHVlIGlzIGRlbGliZXJhdGVseSB0aGUgKmZ1bGwqIGNhcGFiaWxpdHkg4oCUIHRoZSBzeW1tZXRyaWMgQUVTXG4gKiBrZXkgcGx1cyB0aGUgcnVuJ3MgWDI1NTE5IGtleXBhaXIg4oCUIG5vdCBqdXN0IGEgYENyeXB0b0tleWAuIEEgcnVuIHJlYWRpbmdcbiAqIGl0cyBvd24gZXZlbnQgbG9nIGNhbiBlbmNvdW50ZXIgc2VhbGVkIChgZW5jcGApIHBheWxvYWRzIHRoYXQgYW5vdGhlciBydW5cbiAqIHdyb3RlIHRvIGl0IChhIGNyb3NzLWRlcGxveW1lbnQgaG9vayByZXN1bXB0aW9uLCBzYXkpLCBhbmQgb3BlbmluZyB0aG9zZVxuICogbmVlZHMgdGhlIGtleXBhaXIuIFJlc29sdmluZyBvbmx5IHRoZSBzeW1tZXRyaWMga2V5IHdvdWxkIGxlYXZlIHRob3NlXG4gKiBwYXlsb2FkcyB1bm9wZW5hYmxlIGFuZCB3ZWRnZSB0aGUgcnVuLlxuICpcbiAqIFVzZWQgYnkgc3RlcCAvIHdvcmtmbG93IGhhbmRsZXJzIHRvIGRlZmVyIHRoZSAocG90ZW50aWFsbHkgZXhwZW5zaXZlKVxuICoga2V5IGZldGNoIHVudGlsIHRoZSBmaXJzdCBjb2RlIHBhdGggdGhhdCBhY3R1YWxseSBuZWVkcyBpdCDigJQgdHlwaWNhbGx5XG4gKiBpbnB1dCBoeWRyYXRpb24gb24gdGhlIHN1Y2Nlc3MgcGF0aCwgb3IgZXJyb3IgZGVoeWRyYXRpb24gb24gYSBmYWlsdXJlXG4gKiBwYXRoLiBCb3RoIHBhdGhzIGNhbiByYWNlLWNhbGwgdGhlIGFjY2Vzc29yIHdpdGhvdXQgdHJpZ2dlcmluZyBkdXBsaWNhdGVcbiAqIGZldGNoZXMuXG4gKlxuICogRXJyb3JzIHRocm93biBieSBgZ2V0RW5jcnlwdGlvbktleUZvclJ1bmAgcHJvcGFnYXRlIHRvIGV2ZXJ5IGNhbGxlclxuICogKHRoZSBjYWNoZWQgcHJvbWlzZSByZWplY3RzKS4gVGhpcyBpcyBpbnRlbnRpb25hbDogd2hlbiBlbmNyeXB0aW9uIGlzXG4gKiBjb25maWd1cmVkLCB3ZSBuZXZlciB3YW50IHRvIHNpbGVudGx5IGZhbGwgYmFjayB0byBwbGFpbnRleHRcbiAqIHNlcmlhbGl6YXRpb24uIEEgcHJvcGFnYXRlZCBlcnJvciBpbiBhbiBldmVudC1lbWlzc2lvbiBwYXRoIGxlYXZlcyB0aGVcbiAqIG91dGVyIHRyeS9jYXRjaCB0byBsb2cgYW5kIHN1cmZhY2UgdGhlIGlzc3VlOyB0aGUgcXVldWUncyByZWRlbGl2ZXJ5XG4gKiBzZW1hbnRpY3Mgd2lsbCByZXRyeSB0aGUga2V5IGZldGNoIG9uIHRoZSBuZXh0IGF0dGVtcHQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZW1vaXplRW5jcnlwdGlvbktleShcbiAgd29ybGQ6IFdvcmxkLFxuICBydW5PcklkOiBXb3JrZmxvd1J1biB8IHN0cmluZ1xuKTogKCkgPT4gUHJvbWlzZTxQYXlsb2FkS2V5IHwgdW5kZWZpbmVkPiB7XG4gIGxldCBjYWNoZWQ6IFByb21pc2U8UGF5bG9hZEtleSB8IHVuZGVmaW5lZD4gfCB1bmRlZmluZWQ7XG4gIHJldHVybiAoKSA9PiB7XG4gICAgaWYgKCFjYWNoZWQpIHtcbiAgICAgIGNhY2hlZCA9IChhc3luYyAoKSA9PiB7XG4gICAgICAgIC8vIFRoZSBgZ2V0RW5jcnlwdGlvbktleUZvclJ1bmAgb3ZlcmxvYWQgc2V0IHRha2VzIGVpdGhlciBhXG4gICAgICAgIC8vIGBXb3JrZmxvd1J1bmAgb3IgYSBgcnVuSWQ6IHN0cmluZ2AgKHdpdGggb3B0aW9uYWwgY29udGV4dCkuIEJyYW5jaFxuICAgICAgICAvLyBoZXJlIHNvIFR5cGVTY3JpcHQgcGlja3MgdGhlIHJpZ2h0IG92ZXJsb2FkIGZvciBlYWNoIHNoYXBlLlxuICAgICAgICBjb25zdCByYXdLZXkgPVxuICAgICAgICAgIHR5cGVvZiBydW5PcklkID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgPyBhd2FpdCB3b3JsZC5nZXRFbmNyeXB0aW9uS2V5Rm9yUnVuPy4ocnVuT3JJZClcbiAgICAgICAgICAgIDogYXdhaXQgd29ybGQuZ2V0RW5jcnlwdGlvbktleUZvclJ1bj8uKHJ1bk9ySWQpO1xuICAgICAgICAvLyBSZXNvbHZlIHRoZSAqZnVsbCogY2FwYWJpbGl0eSwgbm90IGp1c3QgdGhlIHN5bW1ldHJpYyBrZXk6IGEgcnVuXG4gICAgICAgIC8vIHJlYWRpbmcgaXRzIG93biBldmVudCBsb2cgbWF5IGVuY291bnRlciBzZWFsZWQgKGBlbmNwYCkgcGF5bG9hZHNcbiAgICAgICAgLy8gdGhhdCBhbm90aGVyIHJ1biB3cm90ZSB0byBpdCwgYW5kIG9wZW5pbmcgdGhvc2UgbmVlZHMgdGhlIHJ1bidzXG4gICAgICAgIC8vIFgyNTUxOSBzY2FsYXIgYXMgd2VsbC5cbiAgICAgICAgcmV0dXJuIHJhd0tleSA/IGF3YWl0IGRlcml2ZVJ1blBheWxvYWRLZXlzKHJhd0tleSkgOiB1bmRlZmluZWQ7XG4gICAgICB9KSgpO1xuICAgIH1cbiAgICByZXR1cm4gY2FjaGVkO1xuICB9O1xufVxuIl19