@workflow/core 5.0.0-beta.5 → 5.0.0-beta.50

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 (310) hide show
  1. package/dist/attribute-changes.d.ts +5 -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 +35 -2
  5. package/dist/capabilities.d.ts.map +1 -1
  6. package/dist/capabilities.js +74 -5
  7. package/dist/capture-stack.d.ts +1 -1
  8. package/dist/capture-stack.js +2 -2
  9. package/dist/class-serialization.d.ts +32 -0
  10. package/dist/class-serialization.d.ts.map +1 -1
  11. package/dist/class-serialization.js +37 -1
  12. package/dist/classify-error.d.ts +19 -3
  13. package/dist/classify-error.d.ts.map +1 -1
  14. package/dist/classify-error.js +98 -6
  15. package/dist/context-violation-error.d.ts +5 -5
  16. package/dist/context-violation-error.d.ts.map +1 -1
  17. package/dist/context-violation-error.js +8 -6
  18. package/dist/create-hook.d.ts +72 -7
  19. package/dist/create-hook.d.ts.map +1 -1
  20. package/dist/create-hook.js +1 -1
  21. package/dist/define-hook.js +2 -2
  22. package/dist/describe-error.d.ts +7 -7
  23. package/dist/describe-error.d.ts.map +1 -1
  24. package/dist/describe-error.js +97 -12
  25. package/dist/encryption.d.ts +38 -4
  26. package/dist/encryption.d.ts.map +1 -1
  27. package/dist/encryption.js +96 -14
  28. package/dist/events-consumer.d.ts +271 -0
  29. package/dist/events-consumer.d.ts.map +1 -1
  30. package/dist/events-consumer.js +646 -42
  31. package/dist/flushable-stream.d.ts +56 -1
  32. package/dist/flushable-stream.d.ts.map +1 -1
  33. package/dist/flushable-stream.js +123 -11
  34. package/dist/global.d.ts +36 -2
  35. package/dist/global.d.ts.map +1 -1
  36. package/dist/global.js +21 -6
  37. package/dist/index.d.ts +2 -1
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +3 -2
  40. package/dist/log-format.d.ts +2 -2
  41. package/dist/log-format.js +7 -7
  42. package/dist/logger.d.ts +1 -0
  43. package/dist/logger.d.ts.map +1 -1
  44. package/dist/logger.js +10 -6
  45. package/dist/private.d.ts +226 -9
  46. package/dist/private.d.ts.map +1 -1
  47. package/dist/private.js +626 -7
  48. package/dist/replay-payload-cache.d.ts +64 -0
  49. package/dist/replay-payload-cache.d.ts.map +1 -0
  50. package/dist/replay-payload-cache.js +158 -0
  51. package/dist/runtime/compute-instance.d.ts +13 -0
  52. package/dist/runtime/compute-instance.d.ts.map +1 -0
  53. package/dist/runtime/compute-instance.js +14 -0
  54. package/dist/runtime/constants.d.ts +315 -0
  55. package/dist/runtime/constants.d.ts.map +1 -1
  56. package/dist/runtime/constants.js +502 -16
  57. package/dist/runtime/count-step-started-events.d.ts +52 -0
  58. package/dist/runtime/count-step-started-events.d.ts.map +1 -0
  59. package/dist/runtime/count-step-started-events.js +72 -0
  60. package/dist/runtime/deployment-guard.d.ts +99 -0
  61. package/dist/runtime/deployment-guard.d.ts.map +1 -0
  62. package/dist/runtime/deployment-guard.js +154 -0
  63. package/dist/runtime/get-port-lazy.d.ts +15 -0
  64. package/dist/runtime/get-port-lazy.d.ts.map +1 -1
  65. package/dist/runtime/get-port-lazy.js +75 -6
  66. package/dist/runtime/get-world-lazy.d.ts +5 -14
  67. package/dist/runtime/get-world-lazy.d.ts.map +1 -1
  68. package/dist/runtime/get-world-lazy.js +19 -29
  69. package/dist/runtime/helpers.d.ts +341 -29
  70. package/dist/runtime/helpers.d.ts.map +1 -1
  71. package/dist/runtime/helpers.js +559 -57
  72. package/dist/runtime/quickjs-assets.generated.d.ts +14 -0
  73. package/dist/runtime/quickjs-assets.generated.d.ts.map +1 -0
  74. package/dist/runtime/quickjs-assets.generated.js +30 -0
  75. package/dist/runtime/quickjs-entrypoint.d.ts +136 -0
  76. package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -0
  77. package/dist/runtime/quickjs-entrypoint.js +1686 -0
  78. package/dist/runtime/quickjs-runtime.d.ts +244 -0
  79. package/dist/runtime/quickjs-runtime.d.ts.map +1 -0
  80. package/dist/runtime/quickjs-runtime.js +2427 -0
  81. package/dist/runtime/quickjs-serde.d.ts +107 -0
  82. package/dist/runtime/quickjs-serde.d.ts.map +1 -0
  83. package/dist/runtime/quickjs-serde.js +2159 -0
  84. package/dist/runtime/replay-budget.d.ts +97 -0
  85. package/dist/runtime/replay-budget.d.ts.map +1 -0
  86. package/dist/runtime/replay-budget.js +139 -0
  87. package/dist/runtime/replay-recovery-reporter.d.ts +36 -0
  88. package/dist/runtime/replay-recovery-reporter.d.ts.map +1 -0
  89. package/dist/runtime/replay-recovery-reporter.js +64 -0
  90. package/dist/runtime/resume-hook.d.ts +91 -8
  91. package/dist/runtime/resume-hook.d.ts.map +1 -1
  92. package/dist/runtime/resume-hook.js +512 -89
  93. package/dist/runtime/resume-latency.d.ts +150 -0
  94. package/dist/runtime/resume-latency.d.ts.map +1 -0
  95. package/dist/runtime/resume-latency.js +155 -0
  96. package/dist/runtime/run-id-time.d.ts +19 -0
  97. package/dist/runtime/run-id-time.d.ts.map +1 -0
  98. package/dist/runtime/run-id-time.js +42 -0
  99. package/dist/runtime/run.d.ts +72 -7
  100. package/dist/runtime/run.d.ts.map +1 -1
  101. package/dist/runtime/run.js +280 -53
  102. package/dist/runtime/runs.d.ts +54 -3
  103. package/dist/runtime/runs.d.ts.map +1 -1
  104. package/dist/runtime/runs.js +126 -16
  105. package/dist/runtime/start.d.ts +101 -2
  106. package/dist/runtime/start.d.ts.map +1 -1
  107. package/dist/runtime/start.js +352 -61
  108. package/dist/runtime/step-executor.d.ts +205 -5
  109. package/dist/runtime/step-executor.d.ts.map +1 -1
  110. package/dist/runtime/step-executor.js +760 -127
  111. package/dist/runtime/step-latency.d.ts +220 -0
  112. package/dist/runtime/step-latency.d.ts.map +1 -0
  113. package/dist/runtime/step-latency.js +215 -0
  114. package/dist/runtime/step-ownership.d.ts +72 -0
  115. package/dist/runtime/step-ownership.d.ts.map +1 -0
  116. package/dist/runtime/step-ownership.js +114 -0
  117. package/dist/runtime/step-single-flight.d.ts +12 -0
  118. package/dist/runtime/step-single-flight.d.ts.map +1 -0
  119. package/dist/runtime/step-single-flight.js +75 -0
  120. package/dist/runtime/suspension-handler.d.ts +269 -7
  121. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  122. package/dist/runtime/suspension-handler.js +1253 -125
  123. package/dist/runtime/unserializable-step.d.ts +34 -0
  124. package/dist/runtime/unserializable-step.d.ts.map +1 -0
  125. package/dist/runtime/unserializable-step.js +52 -0
  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 +106 -0
  133. package/dist/runtime/wait-continuation.d.ts.map +1 -0
  134. package/dist/runtime/wait-continuation.js +136 -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 +32 -0
  139. package/dist/runtime/world-compatibility.d.ts.map +1 -0
  140. package/dist/runtime/world-compatibility.js +44 -0
  141. package/dist/runtime/world-init.d.ts +17 -42
  142. package/dist/runtime/world-init.d.ts.map +1 -1
  143. package/dist/runtime/world-init.js +18 -43
  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 +75 -19
  147. package/dist/runtime.d.ts +10 -6
  148. package/dist/runtime.d.ts.map +1 -1
  149. package/dist/runtime.js +3741 -490
  150. package/dist/sealed-box.d.ts +167 -0
  151. package/dist/sealed-box.d.ts.map +1 -0
  152. package/dist/sealed-box.js +571 -0
  153. package/dist/serialization/client.d.ts +3 -3
  154. package/dist/serialization/client.d.ts.map +1 -1
  155. package/dist/serialization/client.js +8 -4
  156. package/dist/serialization/codec-devalue-vm.d.ts +16 -0
  157. package/dist/serialization/codec-devalue-vm.d.ts.map +1 -0
  158. package/dist/serialization/codec-devalue-vm.js +148 -0
  159. package/dist/serialization/codec-devalue.d.ts +1 -1
  160. package/dist/serialization/codec-devalue.d.ts.map +1 -1
  161. package/dist/serialization/codec-devalue.js +24 -6
  162. package/dist/serialization/codec.d.ts +37 -2
  163. package/dist/serialization/codec.d.ts.map +1 -1
  164. package/dist/serialization/codec.js +2 -2
  165. package/dist/serialization/compression.d.ts +105 -0
  166. package/dist/serialization/compression.d.ts.map +1 -0
  167. package/dist/serialization/compression.js +261 -0
  168. package/dist/serialization/encryption.d.ts +119 -17
  169. package/dist/serialization/encryption.d.ts.map +1 -1
  170. package/dist/serialization/encryption.js +152 -17
  171. package/dist/serialization/errors.d.ts +13 -0
  172. package/dist/serialization/errors.d.ts.map +1 -1
  173. package/dist/serialization/errors.js +20 -2
  174. package/dist/serialization/format.d.ts +6 -6
  175. package/dist/serialization/format.js +7 -7
  176. package/dist/serialization/hardened.d.ts +156 -0
  177. package/dist/serialization/hardened.d.ts.map +1 -0
  178. package/dist/serialization/hardened.js +538 -0
  179. package/dist/serialization/index.d.ts +10 -8
  180. package/dist/serialization/index.d.ts.map +1 -1
  181. package/dist/serialization/index.js +10 -8
  182. package/dist/serialization/reducers/class-vm.d.ts +20 -0
  183. package/dist/serialization/reducers/class-vm.d.ts.map +1 -0
  184. package/dist/serialization/reducers/class-vm.js +77 -0
  185. package/dist/serialization/reducers/class.d.ts.map +1 -1
  186. package/dist/serialization/reducers/class.js +11 -6
  187. package/dist/serialization/reducers/common-vm.d.ts +15 -0
  188. package/dist/serialization/reducers/common-vm.d.ts.map +1 -0
  189. package/dist/serialization/reducers/common-vm.js +616 -0
  190. package/dist/serialization/reducers/common.d.ts +1 -1
  191. package/dist/serialization/reducers/common.d.ts.map +1 -1
  192. package/dist/serialization/reducers/common.js +202 -62
  193. package/dist/serialization/reducers/step-function-vm.d.ts +44 -0
  194. package/dist/serialization/reducers/step-function-vm.d.ts.map +1 -0
  195. package/dist/serialization/reducers/step-function-vm.js +97 -0
  196. package/dist/serialization/reducers/step-function.d.ts.map +1 -1
  197. package/dist/serialization/reducers/step-function.js +25 -9
  198. package/dist/serialization/step.d.ts +4 -4
  199. package/dist/serialization/step.d.ts.map +1 -1
  200. package/dist/serialization/step.js +9 -5
  201. package/dist/serialization/types.d.ts +80 -1
  202. package/dist/serialization/types.d.ts.map +1 -1
  203. package/dist/serialization/types.js +15 -1
  204. package/dist/serialization/workflow-vm.d.ts +29 -0
  205. package/dist/serialization/workflow-vm.d.ts.map +1 -0
  206. package/dist/serialization/workflow-vm.js +74 -0
  207. package/dist/serialization-format.d.ts +64 -8
  208. package/dist/serialization-format.d.ts.map +1 -1
  209. package/dist/serialization-format.js +225 -73
  210. package/dist/serialization.d.ts +262 -34
  211. package/dist/serialization.d.ts.map +1 -1
  212. package/dist/serialization.js +1879 -274
  213. package/dist/set-attributes.d.ts +13 -0
  214. package/dist/set-attributes.d.ts.map +1 -0
  215. package/dist/set-attributes.js +60 -0
  216. package/dist/source-map.d.ts +25 -0
  217. package/dist/source-map.d.ts.map +1 -1
  218. package/dist/source-map.js +154 -10
  219. package/dist/step/context-storage.d.ts +61 -2
  220. package/dist/step/context-storage.d.ts.map +1 -1
  221. package/dist/step/context-storage.js +7 -5
  222. package/dist/step/writable-stream.d.ts +3 -3
  223. package/dist/step/writable-stream.d.ts.map +1 -1
  224. package/dist/step/writable-stream.js +72 -9
  225. package/dist/step.d.ts.map +1 -1
  226. package/dist/step.js +148 -27
  227. package/dist/symbols.d.ts +50 -0
  228. package/dist/symbols.d.ts.map +1 -1
  229. package/dist/symbols.js +51 -1
  230. package/dist/telemetry/semantic-conventions.d.ts +397 -2
  231. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  232. package/dist/telemetry/semantic-conventions.js +297 -3
  233. package/dist/telemetry.d.ts +91 -0
  234. package/dist/telemetry.d.ts.map +1 -1
  235. package/dist/telemetry.js +244 -17
  236. package/dist/test-support/orchestrator-context.d.ts +25 -0
  237. package/dist/test-support/orchestrator-context.d.ts.map +1 -0
  238. package/dist/test-support/orchestrator-context.js +101 -0
  239. package/dist/types.d.ts +6 -0
  240. package/dist/types.d.ts.map +1 -1
  241. package/dist/types.js +23 -1
  242. package/dist/util.d.ts +0 -5
  243. package/dist/util.d.ts.map +1 -1
  244. package/dist/util.js +1 -15
  245. package/dist/version.d.ts +1 -1
  246. package/dist/version.d.ts.map +1 -1
  247. package/dist/version.js +2 -2
  248. package/dist/vm/index.d.ts.map +1 -1
  249. package/dist/vm/index.js +84 -14
  250. package/dist/vm/script-cache.d.ts +26 -0
  251. package/dist/vm/script-cache.d.ts.map +1 -0
  252. package/dist/vm/script-cache.js +131 -0
  253. package/dist/vm/uint8array-base64.js +1 -1
  254. package/dist/workflow/abort-controller.d.ts +2 -2
  255. package/dist/workflow/abort-controller.d.ts.map +1 -1
  256. package/dist/workflow/abort-controller.js +88 -21
  257. package/dist/workflow/attribute-dispatcher.d.ts +6 -0
  258. package/dist/workflow/attribute-dispatcher.d.ts.map +1 -0
  259. package/dist/workflow/attribute-dispatcher.js +45 -0
  260. package/dist/workflow/create-hook.d.ts.map +1 -1
  261. package/dist/workflow/create-hook.js +24 -3
  262. package/dist/workflow/get-workflow-metadata.js +2 -2
  263. package/dist/workflow/hook.d.ts.map +1 -1
  264. package/dist/workflow/hook.js +304 -47
  265. package/dist/workflow/index.d.ts +1 -0
  266. package/dist/workflow/index.d.ts.map +1 -1
  267. package/dist/workflow/index.js +2 -1
  268. package/dist/workflow/set-attributes.d.ts +68 -0
  269. package/dist/workflow/set-attributes.d.ts.map +1 -0
  270. package/dist/workflow/set-attributes.js +60 -0
  271. package/dist/workflow/sleep.d.ts.map +1 -1
  272. package/dist/workflow/sleep.js +58 -12
  273. package/dist/workflow/world-init-stub.d.ts +3 -3
  274. package/dist/workflow/world-init-stub.js +4 -4
  275. package/dist/workflow.d.ts +95 -3
  276. package/dist/workflow.d.ts.map +1 -1
  277. package/dist/workflow.js +895 -561
  278. package/docs/api-reference/create-hook.mdx +89 -10
  279. package/docs/api-reference/create-webhook.mdx +16 -15
  280. package/docs/api-reference/define-hook.mdx +35 -33
  281. package/docs/api-reference/fatal-error.mdx +30 -8
  282. package/docs/api-reference/fetch.mdx +14 -10
  283. package/docs/api-reference/get-step-metadata.mdx +2 -2
  284. package/docs/api-reference/get-workflow-metadata.mdx +3 -3
  285. package/docs/api-reference/get-writable.mdx +7 -7
  286. package/docs/api-reference/index.mdx +4 -1
  287. package/docs/api-reference/retryable-error.mdx +1 -1
  288. package/docs/api-reference/set-attributes.mdx +61 -0
  289. package/docs/api-reference/sleep.mdx +4 -4
  290. package/docs/foundations/cancellation.mdx +31 -32
  291. package/docs/foundations/errors-and-retries.mdx +42 -11
  292. package/docs/foundations/hooks.mdx +64 -35
  293. package/docs/foundations/idempotency.mdx +244 -12
  294. package/docs/foundations/index.mdx +1 -23
  295. package/docs/foundations/meta.json +2 -1
  296. package/docs/foundations/serialization.mdx +21 -22
  297. package/docs/foundations/starting-workflows.mdx +106 -30
  298. package/docs/foundations/streaming.mdx +107 -59
  299. package/docs/foundations/versioning.mdx +263 -0
  300. package/docs/foundations/workflows-and-steps.mdx +9 -9
  301. package/docs/how-it-works/cancellation.mdx +63 -63
  302. package/docs/how-it-works/code-transform.mdx +83 -67
  303. package/docs/how-it-works/encryption.mdx +30 -26
  304. package/docs/how-it-works/event-sourcing.mdx +98 -34
  305. package/docs/how-it-works/framework-integrations.mdx +96 -337
  306. package/docs/how-it-works/understanding-directives.mdx +22 -22
  307. package/package.json +24 -15
  308. package/dist/runtime/step-handler.d.ts +0 -2
  309. package/dist/runtime/step-handler.d.ts.map +0 -1
  310. package/dist/runtime/step-handler.js +0 -776
@@ -0,0 +1,538 @@
1
+ /**
2
+ * Hardened introspection for serializing values that may originate inside a
3
+ * workflow VM (`node:vm`) sandbox realm.
4
+ *
5
+ * Serialization runs on the host, but the values it inspects were
6
+ * constructed by workflow code, so a naive dynamic operation like
7
+ * `value.toISOString()`, `Array.from(map)`, or `Object.prototype.toString`
8
+ * dispatches into the sandbox realm and executes workflow code (patched
9
+ * prototype methods, getters, proxy traps, `Symbol.toStringTag` accessors).
10
+ * That is a determinism hazard: serialization happens exactly once per
11
+ * payload (never again on replay), so any workflow-visible side effect it
12
+ * triggers exists only on the live execution path and diverges from replay.
13
+ *
14
+ * This module makes serialization side-effect free wherever the data allows
15
+ * it, and *observable* where it does not:
16
+ *
17
+ * - **Classification** uses engine-level brand checks (`node:util` `types`,
18
+ * internal-slot probes) instead of `instanceof` / `Object.prototype.toString`,
19
+ * which makes it immune to `Symbol.hasInstance`, `Symbol.toStringTag`, and
20
+ * reassigned globals.
21
+ * - **Extraction** goes through intrinsics captured at module load (host
22
+ * boot, before any workflow code runs). Internal slots are realm-agnostic,
23
+ * so host intrinsics read VM-realm objects without touching the sandbox's
24
+ * (patchable) prototypes.
25
+ * - **Property access** reads through descriptors, so plain data never
26
+ * invokes anything. Where workflow code *must* run because the data itself
27
+ * lives behind it (getters, proxies, custom `[WORKFLOW_SERIALIZE]`
28
+ * methods, `toString()` on toStringTag-branded objects such as Temporal
29
+ * polyfills), the execution is preserved for compatibility and recorded
30
+ * in the active {@link GuestCodeStats} sink, so callers (e.g. a retained-VM
31
+ * gate) can react.
32
+ *
33
+ * **Recording is not prevention.** For the recorded cases the determinism
34
+ * hazard is still live: a getter that calls `Math.random()` advances the
35
+ * run's seeded PRNG during serialization, and because serialization happens
36
+ * exactly once and is never replayed, every subsequent draw (including the
37
+ * correlation ids derived from that stream) shifts relative to replay. The
38
+ * report is the only trace of that; acting on it (warning, demoting a
39
+ * retained VM to replay) is left to the caller.
40
+ *
41
+ * The recorder is ambient module state, set for the duration of a
42
+ * synchronous `stringify` call via {@link withGuestCodeStats}. devalue's
43
+ * `stringify` is fully synchronous, so this is safe without async context.
44
+ */
45
+ import { types } from 'node:util';
46
+ import { globalSingleton } from '@workflow/utils';
47
+ import { defaultStringifyOperations } from 'devalue';
48
+ export const GUEST_CODE_EXECUTION_SAMPLE_LIMIT = 5;
49
+ // per-copy-ok: both are set and cleared by `withGuestCodeStats` around a single
50
+ // synchronous call, so the sink is only ever read by the same copy that armed
51
+ // it. A shared slot would let two copies recording concurrently clobber each
52
+ // other's sink.
53
+ let activeStats = null;
54
+ // per-copy-ok: same scope as `activeStats` above, armed and cleared together.
55
+ let reportedProxies = null;
56
+ /**
57
+ * Runs `fn` (synchronously) with `stats` as the active guest-code sink.
58
+ * Nested calls stack correctly; a `null`/`undefined` sink disables
59
+ * recording without disabling hardening.
60
+ */
61
+ export function withGuestCodeStats(stats, fn) {
62
+ const previousStats = activeStats;
63
+ const previousProxies = reportedProxies;
64
+ activeStats = stats ?? null;
65
+ reportedProxies = stats ? new WeakSet() : null;
66
+ try {
67
+ return fn();
68
+ }
69
+ finally {
70
+ activeStats = previousStats;
71
+ reportedProxies = previousProxies;
72
+ }
73
+ }
74
+ /**
75
+ * Closure-variable functions that arrived through `useStep` when a step
76
+ * proxy was built. The step-function reducer must invoke `__closureVarsFn`,
77
+ * and the compiler-generated function is a pure sequence of lexical reads.
78
+ * But the *property* is reachable from workflow code, which can replace it
79
+ * with an arbitrary function. The reducer checks membership here instead of
80
+ * assuming provenance, and reports anything it does not recognize.
81
+ *
82
+ * Membership proves the function was passed to `useStep`, not that the
83
+ * compiler generated it: workflow code can call `useStep` directly and
84
+ * launder a side-effectful function past the report. That costs a missing
85
+ * report entry, never incorrect output; closing it means branding at the
86
+ * compiler, which does not belong here.
87
+ */
88
+ // On `globalThis` (see `globalSingleton`): functions cross module copies freely,
89
+ // so a closure marked by one copy would not be recognized by another, costing a
90
+ // report entry for no reason.
91
+ const useStepClosures = globalSingleton('@workflow/core//useStepClosures.fns', 1, () => ({ fns: new WeakSet() }));
92
+ /** Marks a function as having been passed to `useStep`. */
93
+ export function markUseStepClosureFn(fn) {
94
+ useStepClosures.fns.add(fn);
95
+ return fn;
96
+ }
97
+ /** Whether `fn` was marked by {@link markUseStepClosureFn}. */
98
+ export function isUseStepClosureFn(fn) {
99
+ return typeof fn === 'function' && useStepClosures.fns.has(fn);
100
+ }
101
+ export function recordGuestCode(kind, detail) {
102
+ if (!activeStats)
103
+ return;
104
+ activeStats.totalExecutions =
105
+ (activeStats.totalExecutions ?? activeStats.executions.length) + 1;
106
+ if (activeStats.executions.length >= GUEST_CODE_EXECUTION_SAMPLE_LIMIT) {
107
+ return;
108
+ }
109
+ const execution = { kind };
110
+ if (detail !== undefined)
111
+ execution.detail = detail;
112
+ activeStats.executions.push(execution);
113
+ }
114
+ /** Records a proxy once per serialization pass (proxies fire many traps). */
115
+ function recordProxy(value) {
116
+ if (!activeStats || !reportedProxies)
117
+ return;
118
+ if (reportedProxies.has(value))
119
+ return;
120
+ reportedProxies.add(value);
121
+ recordGuestCode('proxy');
122
+ }
123
+ // ---- Captured intrinsics ----------------------------------------------------
124
+ //
125
+ // Captured at module load (host boot, before any workflow bundle can run)
126
+ // and invoked with explicit receivers, so no lookup ever resolves through a
127
+ // sandbox-reachable prototype. Every member below exists on every supported
128
+ // engine (Node 18+), so a missing one is a bug in this table: fail at import
129
+ // rather than serialize through a live (patchable) lookup later.
130
+ const uncurryThis = Function.prototype.bind.bind(Function.prototype.call);
131
+ function protoGetter(prototype, key) {
132
+ const getter = Object.getOwnPropertyDescriptor(prototype, key)?.get;
133
+ if (!getter) {
134
+ throw new Error(`Missing intrinsic getter: ${String(key)}`);
135
+ }
136
+ return uncurryThis(getter);
137
+ }
138
+ // ECMAScript intrinsics. All read internal slots, so they work on values
139
+ // from any realm and are unaffected by prototype patching in any realm.
140
+ /** `Date.prototype.getDate`, for invalid-date checks. */
141
+ export const dateGetDate = uncurryThis(Date.prototype.getDate);
142
+ /** `Date.prototype.getTime`. */
143
+ export const dateGetTime = uncurryThis(Date.prototype.getTime);
144
+ /** `Date.prototype.toISOString`. */
145
+ export const dateToISOString = uncurryThis(Date.prototype.toISOString);
146
+ /** `RegExp.prototype.source` getter. */
147
+ export const regExpSource = protoGetter(RegExp.prototype, 'source');
148
+ /** `RegExp.prototype.flags` getter. */
149
+ export const regExpFlags = protoGetter(RegExp.prototype, 'flags');
150
+ /** `ArrayBuffer.prototype.byteLength` getter (internal slot read). */
151
+ export const arrayBufferByteLength = protoGetter(ArrayBuffer.prototype, 'byteLength');
152
+ const mapEntries = uncurryThis(Map.prototype.entries);
153
+ const setValues = uncurryThis(Set.prototype.values);
154
+ const numberValueOf = uncurryThis(Number.prototype.valueOf);
155
+ const stringValueOf = uncurryThis(String.prototype.valueOf);
156
+ const booleanValueOf = uncurryThis(Boolean.prototype.valueOf);
157
+ const bigIntValueOf = uncurryThis(BigInt.prototype.valueOf);
158
+ const TypedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
159
+ const typedArrayTag = protoGetter(TypedArrayPrototype, Symbol.toStringTag);
160
+ const typedArrayBuffer = protoGetter(TypedArrayPrototype, 'buffer');
161
+ const typedArrayByteOffset = protoGetter(TypedArrayPrototype, 'byteOffset');
162
+ const typedArrayByteLength = protoGetter(TypedArrayPrototype, 'byteLength');
163
+ const typedArrayLength = protoGetter(TypedArrayPrototype, 'length');
164
+ const dataViewBuffer = protoGetter(DataView.prototype, 'buffer');
165
+ const dataViewByteOffset = protoGetter(DataView.prototype, 'byteOffset');
166
+ const dataViewByteLength = protoGetter(DataView.prototype, 'byteLength');
167
+ const sharedArrayBufferByteLength = protoGetter(SharedArrayBuffer.prototype, 'byteLength');
168
+ // Host (WHATWG) classes. Injected into the sandbox by reference, so
169
+ // instances from any realm carry these prototypes, and the shared
170
+ // prototypes are reachable from workflow code, which makes the boot-time
171
+ // capture (rather than a live lookup) load-bearing.
172
+ const headersIterator = uncurryThis(Headers.prototype[Symbol.iterator]);
173
+ const urlHrefGetter = protoGetter(URL.prototype, 'href');
174
+ const urlSearchParamsToStringMethod = uncurryThis(URLSearchParams.prototype.toString);
175
+ // ---- Safe access primitives -------------------------------------------------
176
+ const { isProxy } = types;
177
+ const functionToString = uncurryThis(Function.prototype.toString);
178
+ /**
179
+ * Whether an accessor is provided by the engine or the host, rather than
180
+ * defined by workflow code. Serialization must read some properties that are
181
+ * accessors by construction (V8 defines `stack` as an own accessor on every
182
+ * Error instance; Node implements `DOMException.prototype.message` in
183
+ * JavaScript), and reporting those would drown the signal in noise.
184
+ *
185
+ * - Engine accessors are native code, detected via the captured host
186
+ * `Function.prototype.toString` (cross-realm, uninterceptable). Bound
187
+ * functions and callable Proxies also present as native code but run
188
+ * workflow code, so both are excluded first.
189
+ * - Host builtins implemented in JavaScript are ordinary functions, but they
190
+ * belong to the host realm, detected by comparing the function's
191
+ * prototype against the host `Function.prototype`. Workflow code that
192
+ * reaches a host function can `setPrototypeOf` its own getter to
193
+ * impersonate this; that costs a missing report entry, never incorrect
194
+ * output.
195
+ *
196
+ * V8's native `stack` getter can itself invoke a workflow-defined
197
+ * `Error.prepareStackTrace`; that indirection is not detected here.
198
+ */
199
+ function isEngineAccessor(getter) {
200
+ if (isProxy(getter))
201
+ return false;
202
+ // A bound function stringifies as native code but runs its target. The
203
+ // one passive distinguisher V8 exposes is the `name` own property
204
+ // (`"bound fn"`). Workflow code can redefine the name to hide it; that
205
+ // costs a missing report entry, like the other impersonation caveats.
206
+ const name = Object.getOwnPropertyDescriptor(getter, 'name')?.value;
207
+ if (typeof name === 'string' && name.startsWith('bound '))
208
+ return false;
209
+ return (functionToString(getter).endsWith('{ [native code] }') ||
210
+ Reflect.getPrototypeOf(getter) === Function.prototype);
211
+ }
212
+ /**
213
+ * Reads `value[key]` with `[[Get]]` semantics, but through descriptors:
214
+ * plain data properties never invoke anything; accessor properties are
215
+ * invoked (the data lives behind them) and recorded; proxies fall back to
216
+ * a plain read (their traps are the only access path) and are recorded.
217
+ */
218
+ export function readProperty(value, key) {
219
+ if (value === null ||
220
+ (typeof value !== 'object' && typeof value !== 'function')) {
221
+ return undefined;
222
+ }
223
+ if (isProxy(value)) {
224
+ recordProxy(value);
225
+ return value[key];
226
+ }
227
+ let current = value;
228
+ while (current !== null) {
229
+ if (isProxy(current)) {
230
+ // a proxy in the prototype chain: its traps answer the lookup
231
+ recordProxy(current);
232
+ return value[key];
233
+ }
234
+ const descriptor = Object.getOwnPropertyDescriptor(current, key);
235
+ if (descriptor) {
236
+ if ('value' in descriptor)
237
+ return descriptor.value;
238
+ if (descriptor.get) {
239
+ if (!isEngineAccessor(descriptor.get)) {
240
+ recordGuestCode('getter', String(key));
241
+ }
242
+ return descriptor.get.call(value);
243
+ }
244
+ return undefined; // setter-only property
245
+ }
246
+ current = Reflect.getPrototypeOf(current);
247
+ }
248
+ return undefined;
249
+ }
250
+ /**
251
+ * `key in value` semantics without firing proxy traps for ordinary
252
+ * objects. Proxies fall back to the `in` operator and are recorded.
253
+ */
254
+ export function hasProperty(value, key) {
255
+ if (value === null ||
256
+ (typeof value !== 'object' && typeof value !== 'function')) {
257
+ return false;
258
+ }
259
+ if (isProxy(value)) {
260
+ recordProxy(value);
261
+ return key in value;
262
+ }
263
+ let current = value;
264
+ while (current !== null) {
265
+ if (isProxy(current)) {
266
+ recordProxy(current);
267
+ return key in value;
268
+ }
269
+ if (Object.getOwnPropertyDescriptor(current, key))
270
+ return true;
271
+ current = Reflect.getPrototypeOf(current);
272
+ }
273
+ return false;
274
+ }
275
+ /**
276
+ * `value instanceof C` semantics for a known `C.prototype`, without
277
+ * consulting `Symbol.hasInstance` (which workflow code can define). Used
278
+ * for host classes that are injected into the sandbox (Headers, URL,
279
+ * URLSearchParams, DOMException), where the instances (from any realm the
280
+ * host handed the class to) carry the host prototype in their chain.
281
+ *
282
+ * Proxies are walked rather than rejected: `Reflect.getPrototypeOf` fires
283
+ * the proxy's `getPrototypeOf` trap, matching `instanceof` semantics, and
284
+ * real values depend on that: Next.js hands the runtime a proxied
285
+ * `NextRequest`, and answering "not a Request" for it would silently break
286
+ * webhooks. The traps are guest-observable, so the proxy is recorded.
287
+ */
288
+ export function isInstanceOfPrototype(value, prototype) {
289
+ if (!prototype)
290
+ return false;
291
+ if (value === null || typeof value !== 'object')
292
+ return false;
293
+ if (isProxy(value))
294
+ recordProxy(value);
295
+ let current = Reflect.getPrototypeOf(value);
296
+ while (current !== null) {
297
+ if (current === prototype)
298
+ return true;
299
+ if (isProxy(current))
300
+ recordProxy(current);
301
+ current = Reflect.getPrototypeOf(current);
302
+ }
303
+ return false;
304
+ }
305
+ // ---- Intrinsic-backed extraction helpers (used by the reducers) -------------
306
+ //
307
+ // Intrinsics read internal slots, which a Proxy does not have: invoking one
308
+ // with a proxy receiver throws, where the pre-existing dynamic read forwarded
309
+ // through the trap. For the (rare) proxy case, fall back to the dynamic read
310
+ // so behavior is unchanged, and record that the traps ran.
311
+ /** `URL.prototype.href` getter. */
312
+ export function urlHref(value) {
313
+ if (isProxy(value)) {
314
+ recordProxy(value);
315
+ return value.href;
316
+ }
317
+ return urlHrefGetter(value);
318
+ }
319
+ /** `URLSearchParams.prototype.toString`: returns `''` iff empty. */
320
+ export function urlSearchParamsToString(value) {
321
+ if (isProxy(value)) {
322
+ recordProxy(value);
323
+ return String(value);
324
+ }
325
+ return urlSearchParamsToStringMethod(value);
326
+ }
327
+ /**
328
+ * Iterates a Headers instance through the captured host iterator, so the
329
+ * iterator object, and its `next`, are host-realm.
330
+ */
331
+ export function headersToEntries(value) {
332
+ if (isProxy(value)) {
333
+ recordProxy(value);
334
+ return Array.from(value);
335
+ }
336
+ return [...headersIterator(value)];
337
+ }
338
+ /**
339
+ * Iterates a genuine Map's entries entirely through host intrinsics: the
340
+ * iterator object is created by the host `Map.prototype.entries`, so its
341
+ * realm, and therefore its `next`, is the host's, not the sandbox's.
342
+ */
343
+ export function mapToEntries(value) {
344
+ return [...mapEntries(value)];
345
+ }
346
+ /** See {@link mapToEntries}. */
347
+ export function setToValues(value) {
348
+ return [...setValues(value)];
349
+ }
350
+ /**
351
+ * The bytes of an `ArrayBufferView`, read via internal-slot getters, so
352
+ * own-property shadowing and prototype patches cannot change which bytes
353
+ * are serialized.
354
+ */
355
+ export function viewInfo(value) {
356
+ if (types.isDataView(value)) {
357
+ return {
358
+ buffer: dataViewBuffer(value),
359
+ byteOffset: dataViewByteOffset(value),
360
+ byteLength: dataViewByteLength(value),
361
+ };
362
+ }
363
+ return {
364
+ buffer: typedArrayBuffer(value),
365
+ byteOffset: typedArrayByteOffset(value),
366
+ byteLength: typedArrayByteLength(value),
367
+ };
368
+ }
369
+ // ---- Hardened devalue operations ---------------------------------------------
370
+ //
371
+ // The workflow reducers claim most special types before devalue's built-in
372
+ // handling runs, so these operations mainly govern plain objects, arrays,
373
+ // boxed primitives, thenable probes, and classification (`tagOf`), which
374
+ // runs for every object the reducers did not claim.
375
+ const KNOWN_VIEW_TAGS = new Set([
376
+ 'Int8Array',
377
+ 'Uint8Array',
378
+ 'Uint8ClampedArray',
379
+ 'Int16Array',
380
+ 'Uint16Array',
381
+ 'Float16Array',
382
+ 'Int32Array',
383
+ 'Uint32Array',
384
+ 'Float32Array',
385
+ 'Float64Array',
386
+ 'BigInt64Array',
387
+ 'BigUint64Array',
388
+ ]);
389
+ /**
390
+ * Tags that {@link brandOf} decides authoritatively. If the brand check said
391
+ * "not one of these" then a `Symbol.toStringTag` claiming one is a spoof, and
392
+ * honouring it would route the value into an extractor that requires the real
393
+ * internal slot (`Object.prototype.toString` semantics let any object claim
394
+ * `[object Date]`). Unbranded values that claim one of these are classified
395
+ * as plain objects instead.
396
+ */
397
+ const BRAND_DECIDED_TAGS = new Set([
398
+ 'Date',
399
+ 'RegExp',
400
+ 'Map',
401
+ 'Set',
402
+ 'Array',
403
+ 'DataView',
404
+ 'ArrayBuffer',
405
+ 'SharedArrayBuffer',
406
+ 'Number',
407
+ 'String',
408
+ 'Boolean',
409
+ 'BigInt',
410
+ 'URL',
411
+ 'URLSearchParams',
412
+ ...KNOWN_VIEW_TAGS,
413
+ ]);
414
+ /**
415
+ * Classifies a value by engine brand. Returns undefined when no brand
416
+ * matches (the caller falls back to `Symbol.toStringTag` semantics).
417
+ */
418
+ function brandOf(value) {
419
+ if (types.isDate(value))
420
+ return 'Date';
421
+ if (types.isRegExp(value))
422
+ return 'RegExp';
423
+ if (types.isMap(value))
424
+ return 'Map';
425
+ if (types.isSet(value))
426
+ return 'Set';
427
+ if (Array.isArray(value))
428
+ return 'Array';
429
+ if (types.isTypedArray(value)) {
430
+ const tag = typedArrayTag(value);
431
+ return tag !== undefined && KNOWN_VIEW_TAGS.has(tag) ? tag : undefined;
432
+ }
433
+ if (types.isDataView(value))
434
+ return 'DataView';
435
+ if (types.isArrayBuffer(value))
436
+ return 'ArrayBuffer';
437
+ if (types.isSharedArrayBuffer(value))
438
+ return 'SharedArrayBuffer';
439
+ if (types.isNumberObject(value))
440
+ return 'Number';
441
+ if (types.isStringObject(value))
442
+ return 'String';
443
+ if (types.isBooleanObject(value))
444
+ return 'Boolean';
445
+ if (types.isBigIntObject(value))
446
+ return 'BigInt';
447
+ if (isInstanceOfPrototype(value, URL.prototype))
448
+ return 'URL';
449
+ if (isInstanceOfPrototype(value, URLSearchParams.prototype)) {
450
+ return 'URLSearchParams';
451
+ }
452
+ return undefined;
453
+ }
454
+ /**
455
+ * Reads `Symbol.toStringTag` the way `Object.prototype.toString` would,
456
+ * but through descriptors: a data-property tag (the common case, e.g.
457
+ * Temporal polyfills) costs no workflow-code execution; an accessor tag is
458
+ * invoked (compat) and recorded.
459
+ */
460
+ function readToStringTag(value) {
461
+ const tag = readProperty(value, Symbol.toStringTag);
462
+ return typeof tag === 'string' ? tag : undefined;
463
+ }
464
+ export const hardenedStringifyOperations = {
465
+ tagOf: (value) => {
466
+ if (isProxy(value)) {
467
+ // A proxy's classification is answered by its traps, which is the
468
+ // only access path there is. Record it and preserve today's
469
+ // behavior for everything downstream.
470
+ recordProxy(value);
471
+ return defaultStringifyOperations.tagOf(value);
472
+ }
473
+ const brand = brandOf(value);
474
+ if (brand !== undefined)
475
+ return brand;
476
+ // No engine brand matched. A `Symbol.toStringTag` is still meaningful for
477
+ // types devalue identifies that way (`Temporal.*`), but one naming a
478
+ // brand-decided type is a spoof and is ignored.
479
+ const tag = readToStringTag(value);
480
+ if (tag === undefined || BRAND_DECIDED_TAGS.has(tag))
481
+ return 'Object';
482
+ return tag;
483
+ },
484
+ isThenable: (value) => {
485
+ if (types.isPromise(value))
486
+ return true;
487
+ return typeof readProperty(value, 'then') === 'function';
488
+ },
489
+ unbox: (boxed) => {
490
+ if (types.isNumberObject(boxed))
491
+ return numberValueOf(boxed);
492
+ if (types.isStringObject(boxed))
493
+ return stringValueOf(boxed);
494
+ if (types.isBooleanObject(boxed))
495
+ return booleanValueOf(boxed);
496
+ return bigIntValueOf(boxed);
497
+ },
498
+ toISOString: (date) => Number.isNaN(dateGetDate(date)) ? '' : dateToISOString(date),
499
+ toStringValue: (value) => {
500
+ // Reached for URL / URLSearchParams (when the reducers did not claim
501
+ // them, e.g. instances of a different realm's classes) and for
502
+ // toStringTag-branded objects like Temporal polyfills, whose string
503
+ // form only their own toString() can produce.
504
+ if (isInstanceOfPrototype(value, URL.prototype)) {
505
+ return urlHref(value);
506
+ }
507
+ if (isInstanceOfPrototype(value, URLSearchParams.prototype)) {
508
+ return urlSearchParamsToString(value);
509
+ }
510
+ recordGuestCode('method', `toString (${readToStringTag(value) ?? 'unknown'})`);
511
+ return value.toString();
512
+ },
513
+ regExpInfo: (regexp) => ({
514
+ source: regExpSource(regexp),
515
+ flags: regExpFlags(regexp),
516
+ }),
517
+ valuesOf: (set) => setToValues(set),
518
+ entriesOf: (map) => mapToEntries(map),
519
+ viewInfo: (view) => {
520
+ const info = viewInfo(view);
521
+ return {
522
+ ...info,
523
+ // devalue only reads `length` for typed-array subviews; DataView
524
+ // subviews are encoded from `byteLength`.
525
+ length: types.isDataView(view) ? 0 : typedArrayLength(view),
526
+ bufferByteLength: types.isSharedArrayBuffer(info.buffer)
527
+ ? sharedArrayBufferByteLength(info.buffer)
528
+ : arrayBufferByteLength(info.buffer),
529
+ };
530
+ },
531
+ shapeOf: (value) => {
532
+ if (isProxy(value))
533
+ recordProxy(value);
534
+ return defaultStringifyOperations.shapeOf(value);
535
+ },
536
+ get: (value, key) => readProperty(value, key),
537
+ };
538
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFyZGVuZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VyaWFsaXphdGlvbi9oYXJkZW5lZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTJDRztBQUVILE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDbEMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWxELE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQXNDckQsTUFBTSxDQUFDLE1BQU0saUNBQWlDLEdBQUcsQ0FBQyxDQUFDO0FBRW5ELGdGQUFnRjtBQUNoRiw4RUFBOEU7QUFDOUUsNkVBQTZFO0FBQzdFLGdCQUFnQjtBQUNoQixJQUFJLFdBQVcsR0FBMEIsSUFBSSxDQUFDO0FBQzlDLDhFQUE4RTtBQUM5RSxJQUFJLGVBQWUsR0FBMkIsSUFBSSxDQUFDO0FBRW5EOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsa0JBQWtCLENBQ2hDLEtBQWlDLEVBQ2pDLEVBQVc7SUFFWCxNQUFNLGFBQWEsR0FBRyxXQUFXLENBQUM7SUFDbEMsTUFBTSxlQUFlLEdBQUcsZUFBZSxDQUFDO0lBQ3hDLFdBQVcsR0FBRyxLQUFLLElBQUksSUFBSSxDQUFDO0lBQzVCLGVBQWUsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUMvQyxJQUFJLENBQUM7UUFDSCxPQUFPLEVBQUUsRUFBRSxDQUFDO0lBQ2QsQ0FBQztZQUFTLENBQUM7UUFDVCxXQUFXLEdBQUcsYUFBYSxDQUFDO1FBQzVCLGVBQWUsR0FBRyxlQUFlLENBQUM7SUFDcEMsQ0FBQztBQUNILENBQUM7QUFFRDs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsaUZBQWlGO0FBQ2pGLGdGQUFnRjtBQUNoRiw4QkFBOEI7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LENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUVELEdBQUcsRUFBRSxDQUFDLEtBQWEsRUFBRSxHQUFvQixFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQztDQUN2RSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBIYXJkZW5lZCBpbnRyb3NwZWN0aW9uIGZvciBzZXJpYWxpemluZyB2YWx1ZXMgdGhhdCBtYXkgb3JpZ2luYXRlIGluc2lkZSBhXG4gKiB3b3JrZmxvdyBWTSAoYG5vZGU6dm1gKSBzYW5kYm94IHJlYWxtLlxuICpcbiAqIFNlcmlhbGl6YXRpb24gcnVucyBvbiB0aGUgaG9zdCwgYnV0IHRoZSB2YWx1ZXMgaXQgaW5zcGVjdHMgd2VyZVxuICogY29uc3RydWN0ZWQgYnkgd29ya2Zsb3cgY29kZSwgc28gYSBuYWl2ZSBkeW5hbWljIG9wZXJhdGlvbiBsaWtlXG4gKiBgdmFsdWUudG9JU09TdHJpbmcoKWAsIGBBcnJheS5mcm9tKG1hcClgLCBvciBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2BcbiAqIGRpc3BhdGNoZXMgaW50byB0aGUgc2FuZGJveCByZWFsbSBhbmQgZXhlY3V0ZXMgd29ya2Zsb3cgY29kZSAocGF0Y2hlZFxuICogcHJvdG90eXBlIG1ldGhvZHMsIGdldHRlcnMsIHByb3h5IHRyYXBzLCBgU3ltYm9sLnRvU3RyaW5nVGFnYCBhY2Nlc3NvcnMpLlxuICogVGhhdCBpcyBhIGRldGVybWluaXNtIGhhemFyZDogc2VyaWFsaXphdGlvbiBoYXBwZW5zIGV4YWN0bHkgb25jZSBwZXJcbiAqIHBheWxvYWQgKG5ldmVyIGFnYWluIG9uIHJlcGxheSksIHNvIGFueSB3b3JrZmxvdy12aXNpYmxlIHNpZGUgZWZmZWN0IGl0XG4gKiB0cmlnZ2VycyBleGlzdHMgb25seSBvbiB0aGUgbGl2ZSBleGVjdXRpb24gcGF0aCBhbmQgZGl2ZXJnZXMgZnJvbSByZXBsYXkuXG4gKlxuICogVGhpcyBtb2R1bGUgbWFrZXMgc2VyaWFsaXphdGlvbiBzaWRlLWVmZmVjdCBmcmVlIHdoZXJldmVyIHRoZSBkYXRhIGFsbG93c1xuICogaXQsIGFuZCAqb2JzZXJ2YWJsZSogd2hlcmUgaXQgZG9lcyBub3Q6XG4gKlxuICogLSAqKkNsYXNzaWZpY2F0aW9uKiogdXNlcyBlbmdpbmUtbGV2ZWwgYnJhbmQgY2hlY2tzIChgbm9kZTp1dGlsYCBgdHlwZXNgLFxuICogICBpbnRlcm5hbC1zbG90IHByb2JlcykgaW5zdGVhZCBvZiBgaW5zdGFuY2VvZmAgLyBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2AsXG4gKiAgIHdoaWNoIG1ha2VzIGl0IGltbXVuZSB0byBgU3ltYm9sLmhhc0luc3RhbmNlYCwgYFN5bWJvbC50b1N0cmluZ1RhZ2AsIGFuZFxuICogICByZWFzc2lnbmVkIGdsb2JhbHMuXG4gKiAtICoqRXh0cmFjdGlvbioqIGdvZXMgdGhyb3VnaCBpbnRyaW5zaWNzIGNhcHR1cmVkIGF0IG1vZHVsZSBsb2FkIChob3N0XG4gKiAgIGJvb3QsIGJlZm9yZSBhbnkgd29ya2Zsb3cgY29kZSBydW5zKS4gSW50ZXJuYWwgc2xvdHMgYXJlIHJlYWxtLWFnbm9zdGljLFxuICogICBzbyBob3N0IGludHJpbnNpY3MgcmVhZCBWTS1yZWFsbSBvYmplY3RzIHdpdGhvdXQgdG91Y2hpbmcgdGhlIHNhbmRib3gnc1xuICogICAocGF0Y2hhYmxlKSBwcm90b3R5cGVzLlxuICogLSAqKlByb3BlcnR5IGFjY2VzcyoqIHJlYWRzIHRocm91Z2ggZGVzY3JpcHRvcnMsIHNvIHBsYWluIGRhdGEgbmV2ZXJcbiAqICAgaW52b2tlcyBhbnl0aGluZy4gV2hlcmUgd29ya2Zsb3cgY29kZSAqbXVzdCogcnVuIGJlY2F1c2UgdGhlIGRhdGEgaXRzZWxmXG4gKiAgIGxpdmVzIGJlaGluZCBpdCAoZ2V0dGVycywgcHJveGllcywgY3VzdG9tIGBbV09SS0ZMT1dfU0VSSUFMSVpFXWBcbiAqICAgbWV0aG9kcywgYHRvU3RyaW5nKClgIG9uIHRvU3RyaW5nVGFnLWJyYW5kZWQgb2JqZWN0cyBzdWNoIGFzIFRlbXBvcmFsXG4gKiAgIHBvbHlmaWxscyksIHRoZSBleGVjdXRpb24gaXMgcHJlc2VydmVkIGZvciBjb21wYXRpYmlsaXR5IGFuZCByZWNvcmRlZFxuICogICBpbiB0aGUgYWN0aXZlIHtAbGluayBHdWVzdENvZGVTdGF0c30gc2luaywgc28gY2FsbGVycyAoZS5nLiBhIHJldGFpbmVkLVZNXG4gKiAgIGdhdGUpIGNhbiByZWFjdC5cbiAqXG4gKiAqKlJlY29yZGluZyBpcyBub3QgcHJldmVudGlvbi4qKiBGb3IgdGhlIHJlY29yZGVkIGNhc2VzIHRoZSBkZXRlcm1pbmlzbVxuICogaGF6YXJkIGlzIHN0aWxsIGxpdmU6IGEgZ2V0dGVyIHRoYXQgY2FsbHMgYE1hdGgucmFuZG9tKClgIGFkdmFuY2VzIHRoZVxuICogcnVuJ3Mgc2VlZGVkIFBSTkcgZHVyaW5nIHNlcmlhbGl6YXRpb24sIGFuZCBiZWNhdXNlIHNlcmlhbGl6YXRpb24gaGFwcGVuc1xuICogZXhhY3RseSBvbmNlIGFuZCBpcyBuZXZlciByZXBsYXllZCwgZXZlcnkgc3Vic2VxdWVudCBkcmF3IChpbmNsdWRpbmcgdGhlXG4gKiBjb3JyZWxhdGlvbiBpZHMgZGVyaXZlZCBmcm9tIHRoYXQgc3RyZWFtKSBzaGlmdHMgcmVsYXRpdmUgdG8gcmVwbGF5LiBUaGVcbiAqIHJlcG9ydCBpcyB0aGUgb25seSB0cmFjZSBvZiB0aGF0OyBhY3Rpbmcgb24gaXQgKHdhcm5pbmcsIGRlbW90aW5nIGFcbiAqIHJldGFpbmVkIFZNIHRvIHJlcGxheSkgaXMgbGVmdCB0byB0aGUgY2FsbGVyLlxuICpcbiAqIFRoZSByZWNvcmRlciBpcyBhbWJpZW50IG1vZHVsZSBzdGF0ZSwgc2V0IGZvciB0aGUgZHVyYXRpb24gb2YgYVxuICogc3luY2hyb25vdXMgYHN0cmluZ2lmeWAgY2FsbCB2aWEge0BsaW5rIHdpdGhHdWVzdENvZGVTdGF0c30uIGRldmFsdWUnc1xuICogYHN0cmluZ2lmeWAgaXMgZnVsbHkgc3luY2hyb25vdXMsIHNvIHRoaXMgaXMgc2FmZSB3aXRob3V0IGFzeW5jIGNvbnRleHQuXG4gKi9cblxuaW1wb3J0IHsgdHlwZXMgfSBmcm9tICdub2RlOnV0aWwnO1xuaW1wb3J0IHsgZ2xvYmFsU2luZ2xldG9uIH0gZnJvbSAnQHdvcmtmbG93L3V0aWxzJztcbmltcG9ydCB0eXBlIHsgU3RyaW5naWZ5T3BlcmF0aW9ucyB9IGZyb20gJ2RldmFsdWUnO1xuaW1wb3J0IHsgZGVmYXVsdFN0cmluZ2lmeU9wZXJhdGlvbnMgfSBmcm9tICdkZXZhbHVlJztcblxuLy8gLS0tLSBHdWVzdCBjb2RlIG9ic2VydmF0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLyoqXG4gKiBBIHNpbmdsZSBpbnN0YW5jZSBvZiB3b3JrZmxvdyAoZ3Vlc3QpIGNvZGUgZXhlY3V0aW5nIGR1cmluZyBzZXJpYWxpemF0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEd1ZXN0Q29kZUV4ZWN1dGlvbiB7XG4gIC8qKlxuICAgKiBXaGF0IGZvcmNlZCB0aGUgZXhlY3V0aW9uOlxuICAgKiAtIGBnZXR0ZXJgOiBhbiBhY2Nlc3NvciBwcm9wZXJ0eSB3YXMgaW52b2tlZCB0byByZWFkIGRhdGFcbiAgICogLSBgcHJveHlgOiBhIHByb3h5IHdhcyBpbnRyb3NwZWN0ZWQsIGZpcmluZyBpdHMgdHJhcHMuIE5vdGUgdGhpcyBhbHNvXG4gICAqICAgaW1wbGllcyBhICoqc2hhcGUgY2hhbmdlKio6IGJyYW5kIGNoZWNrcyBhbnN3ZXIgXCJub3QgdGhhdCB0eXBlXCIgZm9yIGFcbiAgICogICBwcm94eSwgc28gYSBwcm94aWVkIGBNYXBgIHNlcmlhbGl6ZXMgYXMgYSBwbGFpbiBvYmplY3QgcmF0aGVyIHRoYW4gYXMgYVxuICAgKiAgIGBNYXBgLCBhbmQgdGhpcyByZXBvcnQgaXMgdGhlIG9ubHkgZXZpZGVuY2Ugb2YgaXQuIChTdWNoIHZhbHVlcyB3ZXJlXG4gICAqICAgbmV2ZXIgc2VyaWFsaXphYmxlIGJlZm9yZSwgc2luY2UgdGhlIGludGVybmFsLXNsb3QgcmVhZHMgaW4gdGhlIHByZXZpb3VzXG4gICAqICAgaW1wbGVtZW50YXRpb24gdGhyZXcgb24gdGhlbSwgc28gdGhlIHNoYXBlIGNoYW5nZSByZXBsYWNlcyBhIGNyYXNoLFxuICAgKiAgIGJ1dCBpdCBpcyBzaWxlbnQuKVxuICAgKiAtIGBtZXRob2RgOiBhIHdvcmtmbG93LWRlZmluZWQgZnVuY3Rpb24gd2FzIGludm9rZWQgKGUuZy4gYSBjdXN0b21cbiAgICogICBgW1dPUktGTE9XX1NFUklBTElaRV1gIHNlcmlhbGl6ZXIsIGB0b1N0cmluZygpYCBvbiBhXG4gICAqICAgYFN5bWJvbC50b1N0cmluZ1RhZ2AtYnJhbmRlZCBvYmplY3QsIGEgZHVjay10eXBlZCBgZ2V0VGltZSgpYCwgb3IgYVxuICAgKiAgIGBfX2Nsb3N1cmVWYXJzRm5gIHRoaXMgcGFja2FnZSBkaWQgbm90IGdlbmVyYXRlKVxuICAgKi9cbiAga2luZDogJ2dldHRlcicgfCAncHJveHknIHwgJ21ldGhvZCc7XG4gIC8qKiBCZXN0LWVmZm9ydCBjb250ZXh0OiB0aGUgcHJvcGVydHkga2V5LCBtZXRob2QgbmFtZSwgb3IgdGFnIGludm9sdmVkLiAqL1xuICBkZXRhaWw/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogTXV0YWJsZSBzaW5rIHJlY29yZGluZyB3b3JrZmxvdy1jb2RlIGV4ZWN1dGlvbiBzZXJpYWxpemF0aW9uIGNvdWxkIG5vdFxuICogYXZvaWQuIGBleGVjdXRpb25zYCBjb250YWlucyB0aGUgZmlyc3QgZml2ZSBzYW1wbGVzIGFuZCBgdG90YWxFeGVjdXRpb25zYFxuICogaXMgdGhlIGV4YWN0IGNvdW50LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEd1ZXN0Q29kZVN0YXRzIHtcbiAgZXhlY3V0aW9uczogR3Vlc3RDb2RlRXhlY3V0aW9uW107XG4gIHRvdGFsRXhlY3V0aW9ucz86IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IEdVRVNUX0NPREVfRVhFQ1VUSU9OX1NBTVBMRV9MSU1JVCA9IDU7XG5cbi8vIHBlci1jb3B5LW9rOiBib3RoIGFyZSBzZXQgYW5kIGNsZWFyZWQgYnkgYHdpdGhHdWVzdENvZGVTdGF0c2AgYXJvdW5kIGEgc2luZ2xlXG4vLyBzeW5jaHJvbm91cyBjYWxsLCBzbyB0aGUgc2luayBpcyBvbmx5IGV2ZXIgcmVhZCBieSB0aGUgc2FtZSBjb3B5IHRoYXQgYXJtZWRcbi8vIGl0LiBBIHNoYXJlZCBzbG90IHdvdWxkIGxldCB0d28gY29waWVzIHJlY29yZGluZyBjb25jdXJyZW50bHkgY2xvYmJlciBlYWNoXG4vLyBvdGhlcidzIHNpbmsuXG5sZXQgYWN0aXZlU3RhdHM6IEd1ZXN0Q29kZVN0YXRzIHwgbnVsbCA9IG51bGw7XG4vLyBwZXItY29weS1vazogc2FtZSBzY29wZSBhcyBgYWN0aXZlU3RhdHNgIGFib3ZlLCBhcm1lZCBhbmQgY2xlYXJlZCB0b2dldGhlci5cbmxldCByZXBvcnRlZFByb3hpZXM6IFdlYWtTZXQ8b2JqZWN0PiB8IG51bGwgPSBudWxsO1xuXG4vKipcbiAqIFJ1bnMgYGZuYCAoc3luY2hyb25vdXNseSkgd2l0aCBgc3RhdHNgIGFzIHRoZSBhY3RpdmUgZ3Vlc3QtY29kZSBzaW5rLlxuICogTmVzdGVkIGNhbGxzIHN0YWNrIGNvcnJlY3RseTsgYSBgbnVsbGAvYHVuZGVmaW5lZGAgc2luayBkaXNhYmxlc1xuICogcmVjb3JkaW5nIHdpdGhvdXQgZGlzYWJsaW5nIGhhcmRlbmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdpdGhHdWVzdENvZGVTdGF0czxUPihcbiAgc3RhdHM6IEd1ZXN0Q29kZVN0YXRzIHwgdW5kZWZpbmVkLFxuICBmbjogKCkgPT4gVFxuKTogVCB7XG4gIGNvbnN0IHByZXZpb3VzU3RhdHMgPSBhY3RpdmVTdGF0cztcbiAgY29uc3QgcHJldmlvdXNQcm94aWVzID0gcmVwb3J0ZWRQcm94aWVzO1xuICBhY3RpdmVTdGF0cyA9IHN0YXRzID8/IG51bGw7XG4gIHJlcG9ydGVkUHJveGllcyA9IHN0YXRzID8gbmV3IFdlYWtTZXQoKSA6IG51bGw7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGZuKCk7XG4gIH0gZmluYWxseSB7XG4gICAgYWN0aXZlU3RhdHMgPSBwcmV2aW91c1N0YXRzO1xuICAgIHJlcG9ydGVkUHJveGllcyA9IHByZXZpb3VzUHJveGllcztcbiAgfVxufVxuXG4vKipcbiAqIENsb3N1cmUtdmFyaWFibGUgZnVuY3Rpb25zIHRoYXQgYXJyaXZlZCB0aHJvdWdoIGB1c2VTdGVwYCB3aGVuIGEgc3RlcFxuICogcHJveHkgd2FzIGJ1aWx0LiBUaGUgc3RlcC1mdW5jdGlvbiByZWR1Y2VyIG11c3QgaW52b2tlIGBfX2Nsb3N1cmVWYXJzRm5gLFxuICogYW5kIHRoZSBjb21waWxlci1nZW5lcmF0ZWQgZnVuY3Rpb24gaXMgYSBwdXJlIHNlcXVlbmNlIG9mIGxleGljYWwgcmVhZHMuXG4gKiBCdXQgdGhlICpwcm9wZXJ0eSogaXMgcmVhY2hhYmxlIGZyb20gd29ya2Zsb3cgY29kZSwgd2hpY2ggY2FuIHJlcGxhY2UgaXRcbiAqIHdpdGggYW4gYXJiaXRyYXJ5IGZ1bmN0aW9uLiBUaGUgcmVkdWNlciBjaGVja3MgbWVtYmVyc2hpcCBoZXJlIGluc3RlYWQgb2ZcbiAqIGFzc3VtaW5nIHByb3ZlbmFuY2UsIGFuZCByZXBvcnRzIGFueXRoaW5nIGl0IGRvZXMgbm90IHJlY29nbml6ZS5cbiAqXG4gKiBNZW1iZXJzaGlwIHByb3ZlcyB0aGUgZnVuY3Rpb24gd2FzIHBhc3NlZCB0byBgdXNlU3RlcGAsIG5vdCB0aGF0IHRoZVxuICogY29tcGlsZXIgZ2VuZXJhdGVkIGl0OiB3b3JrZmxvdyBjb2RlIGNhbiBjYWxsIGB1c2VTdGVwYCBkaXJlY3RseSBhbmRcbiAqIGxhdW5kZXIgYSBzaWRlLWVmZmVjdGZ1bCBmdW5jdGlvbiBwYXN0IHRoZSByZXBvcnQuIFRoYXQgY29zdHMgYSBtaXNzaW5nXG4gKiByZXBvcnQgZW50cnksIG5ldmVyIGluY29ycmVjdCBvdXRwdXQ7IGNsb3NpbmcgaXQgbWVhbnMgYnJhbmRpbmcgYXQgdGhlXG4gKiBjb21waWxlciwgd2hpY2ggZG9lcyBub3QgYmVsb25nIGhlcmUuXG4gKi9cbi8vIE9uIGBnbG9iYWxUaGlzYCAoc2VlIGBnbG9iYWxTaW5nbGV0b25gKTogZnVuY3Rpb25zIGNyb3NzIG1vZHVsZSBjb3BpZXMgZnJlZWx5LFxuLy8gc28gYSBjbG9zdXJlIG1hcmtlZCBieSBvbmUgY29weSB3b3VsZCBub3QgYmUgcmVjb2duaXplZCBieSBhbm90aGVyLCBjb3N0aW5nIGFcbi8vIHJlcG9ydCBlbnRyeSBmb3Igbm8gcmVhc29uLlxuY29uc3QgdXNlU3RlcENsb3N1cmVzID0gZ2xvYmFsU2luZ2xldG9uKFxuICAnQHdvcmtmbG93L2NvcmUvL3VzZVN0ZXBDbG9zdXJlcy5mbnMnLFxuICAxLFxuICAoKSA9PiAoeyBmbnM6IG5ldyBXZWFrU2V0PG9iamVjdD4oKSB9KVxuKTtcblxuLyoqIE1hcmtzIGEgZnVuY3Rpb24gYXMgaGF2aW5nIGJlZW4gcGFzc2VkIHRvIGB1c2VTdGVwYC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXJrVXNlU3RlcENsb3N1cmVGbjxUIGV4dGVuZHMgb2JqZWN0PihmbjogVCk6IFQge1xuICB1c2VTdGVwQ2xvc3VyZXMuZm5zLmFkZChmbik7XG4gIHJldHVybiBmbjtcbn1cblxuLyoqIFdoZXRoZXIgYGZuYCB3YXMgbWFya2VkIGJ5IHtAbGluayBtYXJrVXNlU3RlcENsb3N1cmVGbn0uICovXG5leHBvcnQgZnVuY3Rpb24gaXNVc2VTdGVwQ2xvc3VyZUZuKGZuOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIHJldHVybiB0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicgJiYgdXNlU3RlcENsb3N1cmVzLmZucy5oYXMoZm4gYXMgb2JqZWN0KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlY29yZEd1ZXN0Q29kZShcbiAga2luZDogR3Vlc3RDb2RlRXhlY3V0aW9uWydraW5kJ10sXG4gIGRldGFpbD86IHN0cmluZ1xuKTogdm9pZCB7XG4gIGlmICghYWN0aXZlU3RhdHMpIHJldHVybjtcbiAgYWN0aXZlU3RhdHMudG90YWxFeGVjdXRpb25zID1cbiAgICAoYWN0aXZlU3RhdHMudG90YWxFeGVjdXRpb25zID8/IGFjdGl2ZVN0YXRzLmV4ZWN1dGlvbnMubGVuZ3RoKSArIDE7XG4gIGlmIChhY3RpdmVTdGF0cy5leGVjdXRpb25zLmxlbmd0aCA+PSBHVUVTVF9DT0RFX0VYRUNVVElPTl9TQU1QTEVfTElNSVQpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3QgZXhlY3V0aW9uOiBHdWVzdENvZGVFeGVjdXRpb24gPSB7IGtpbmQgfTtcbiAgaWYgKGRldGFpbCAhPT0gdW5kZWZpbmVkKSBleGVjdXRpb24uZGV0YWlsID0gZGV0YWlsO1xuICBhY3RpdmVTdGF0cy5leGVjdXRpb25zLnB1c2goZXhlY3V0aW9uKTtcbn1cblxuLyoqIFJlY29yZHMgYSBwcm94eSBvbmNlIHBlciBzZXJpYWxpemF0aW9uIHBhc3MgKHByb3hpZXMgZmlyZSBtYW55IHRyYXBzKS4gKi9cbmZ1bmN0aW9uIHJlY29yZFByb3h5KHZhbHVlOiBvYmplY3QpOiB2b2lkIHtcbiAgaWYgKCFhY3RpdmVTdGF0cyB8fCAhcmVwb3J0ZWRQcm94aWVzKSByZXR1cm47XG4gIGlmIChyZXBvcnRlZFByb3hpZXMuaGFzKHZhbHVlKSkgcmV0dXJuO1xuICByZXBvcnRlZFByb3hpZXMuYWRkKHZhbHVlKTtcbiAgcmVjb3JkR3Vlc3RDb2RlKCdwcm94eScpO1xufVxuXG4vLyAtLS0tIENhcHR1cmVkIGludHJpbnNpY3MgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy9cbi8vIENhcHR1cmVkIGF0IG1vZHVsZSBsb2FkIChob3N0IGJvb3QsIGJlZm9yZSBhbnkgd29ya2Zsb3cgYnVuZGxlIGNhbiBydW4pXG4vLyBhbmQgaW52b2tlZCB3aXRoIGV4cGxpY2l0IHJlY2VpdmVycywgc28gbm8gbG9va3VwIGV2ZXIgcmVzb2x2ZXMgdGhyb3VnaCBhXG4vLyBzYW5kYm94LXJlYWNoYWJsZSBwcm90b3R5cGUuIEV2ZXJ5IG1lbWJlciBiZWxvdyBleGlzdHMgb24gZXZlcnkgc3VwcG9ydGVkXG4vLyBlbmdpbmUgKE5vZGUgMTgrKSwgc28gYSBtaXNzaW5nIG9uZSBpcyBhIGJ1ZyBpbiB0aGlzIHRhYmxlOiBmYWlsIGF0IGltcG9ydFxuLy8gcmF0aGVyIHRoYW4gc2VyaWFsaXplIHRocm91Z2ggYSBsaXZlIChwYXRjaGFibGUpIGxvb2t1cCBsYXRlci5cblxuY29uc3QgdW5jdXJyeVRoaXMgPSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZC5iaW5kKEZ1bmN0aW9uLnByb3RvdHlwZS5jYWxsKSBhcyA8XG4gIFQsXG4gIEEgZXh0ZW5kcyB1bmtub3duW10sXG4gIFIsXG4+KFxuICBmbjogKHRoaXM6IFQsIC4uLmFyZ3M6IEEpID0+IFJcbikgPT4gKHRoaXNBcmc6IFQsIC4uLmFyZ3M6IEEpID0+IFI7XG5cbmZ1bmN0aW9uIHByb3RvR2V0dGVyPFQ+KFxuICBwcm90b3R5cGU6IG9iamVjdCxcbiAga2V5OiBQcm9wZXJ0eUtleVxuKTogKHZhbHVlOiB1bmtub3duKSA9PiBUIHtcbiAgY29uc3QgZ2V0dGVyID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihwcm90b3R5cGUsIGtleSk/LmdldDtcbiAgaWYgKCFnZXR0ZXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgaW50cmluc2ljIGdldHRlcjogJHtTdHJpbmcoa2V5KX1gKTtcbiAgfVxuICByZXR1cm4gdW5jdXJyeVRoaXMoZ2V0dGVyKSBhcyAodmFsdWU6IHVua25vd24pID0+IFQ7XG59XG5cbi8vIEVDTUFTY3JpcHQgaW50cmluc2ljcy4gQWxsIHJlYWQgaW50ZXJuYWwgc2xvdHMsIHNvIHRoZXkgd29yayBvbiB2YWx1ZXNcbi8vIGZyb20gYW55IHJlYWxtIGFuZCBhcmUgdW5hZmZlY3RlZCBieSBwcm90b3R5cGUgcGF0Y2hpbmcgaW4gYW55IHJlYWxtLlxuXG4vKiogYERhdGUucHJvdG90eXBlLmdldERhdGVgLCBmb3IgaW52YWxpZC1kYXRlIGNoZWNrcy4gKi9cbmV4cG9ydCBjb25zdCBkYXRlR2V0RGF0ZSA9IHVuY3VycnlUaGlzKERhdGUucHJvdG90eXBlLmdldERhdGUpO1xuLyoqIGBEYXRlLnByb3RvdHlwZS5nZXRUaW1lYC4gKi9cbmV4cG9ydCBjb25zdCBkYXRlR2V0VGltZSA9IHVuY3VycnlUaGlzKERhdGUucHJvdG90eXBlLmdldFRpbWUpO1xuLyoqIGBEYXRlLnByb3RvdHlwZS50b0lTT1N0cmluZ2AuICovXG5leHBvcnQgY29uc3QgZGF0ZVRvSVNPU3RyaW5nID0gdW5jdXJyeVRoaXMoRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmcpO1xuLyoqIGBSZWdFeHAucHJvdG90eXBlLnNvdXJjZWAgZ2V0dGVyLiAqL1xuZXhwb3J0IGNvbnN0IHJlZ0V4cFNvdXJjZSA9IHByb3RvR2V0dGVyPHN0cmluZz4oUmVnRXhwLnByb3RvdHlwZSwgJ3NvdXJjZScpO1xuLyoqIGBSZWdFeHAucHJvdG90eXBlLmZsYWdzYCBnZXR0ZXIuICovXG5leHBvcnQgY29uc3QgcmVnRXhwRmxhZ3MgPSBwcm90b0dldHRlcjxzdHJpbmc+KFJlZ0V4cC5wcm90b3R5cGUsICdmbGFncycpO1xuLyoqIGBBcnJheUJ1ZmZlci5wcm90b3R5cGUuYnl0ZUxlbmd0aGAgZ2V0dGVyIChpbnRlcm5hbCBzbG90IHJlYWQpLiAqL1xuZXhwb3J0IGNvbnN0IGFycmF5QnVmZmVyQnl0ZUxlbmd0aCA9IHByb3RvR2V0dGVyPG51bWJlcj4oXG4gIEFycmF5QnVmZmVyLnByb3RvdHlwZSxcbiAgJ2J5dGVMZW5ndGgnXG4pO1xuXG5jb25zdCBtYXBFbnRyaWVzID0gdW5jdXJyeVRoaXMoTWFwLnByb3RvdHlwZS5lbnRyaWVzKTtcbmNvbnN0IHNldFZhbHVlcyA9IHVuY3VycnlUaGlzKFNldC5wcm90b3R5cGUudmFsdWVzKTtcbmNvbnN0IG51bWJlclZhbHVlT2YgPSB1bmN1cnJ5VGhpcyhOdW1iZXIucHJvdG90eXBlLnZhbHVlT2YpO1xuY29uc3Qgc3RyaW5nVmFsdWVPZiA9IHVuY3VycnlUaGlzKFN0cmluZy5wcm90b3R5cGUudmFsdWVPZik7XG5jb25zdCBib29sZWFuVmFsdWVPZiA9IHVuY3VycnlUaGlzKEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YpO1xuY29uc3QgYmlnSW50VmFsdWVPZiA9IHVuY3VycnlUaGlzKFxuICBCaWdJbnQucHJvdG90eXBlLnZhbHVlT2YgYXMgKHRoaXM6IHVua25vd24pID0+IGJpZ2ludFxuKTtcblxuY29uc3QgVHlwZWRBcnJheVByb3RvdHlwZTogb2JqZWN0ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKFVpbnQ4QXJyYXkucHJvdG90eXBlKTtcbmNvbnN0IHR5cGVkQXJyYXlUYWcgPSBwcm90b0dldHRlcjxzdHJpbmcgfCB1bmRlZmluZWQ+KFxuICBUeXBlZEFycmF5UHJvdG90eXBlLFxuICBTeW1ib2wudG9TdHJpbmdUYWdcbik7XG5jb25zdCB0eXBlZEFycmF5QnVmZmVyID0gcHJvdG9HZXR0ZXI8QXJyYXlCdWZmZXJMaWtlPihcbiAgVHlwZWRBcnJheVByb3RvdHlwZSxcbiAgJ2J1ZmZlcidcbik7XG5jb25zdCB0eXBlZEFycmF5Qnl0ZU9mZnNldCA9IHByb3RvR2V0dGVyPG51bWJlcj4oXG4gIFR5cGVkQXJyYXlQcm90b3R5cGUsXG4gICdieXRlT2Zmc2V0J1xuKTtcbmNvbnN0IHR5cGVkQXJyYXlCeXRlTGVuZ3RoID0gcHJvdG9HZXR0ZXI8bnVtYmVyPihcbiAgVHlwZWRBcnJheVByb3RvdHlwZSxcbiAgJ2J5dGVMZW5ndGgnXG4pO1xuY29uc3QgdHlwZWRBcnJheUxlbmd0aCA9IHByb3RvR2V0dGVyPG51bWJlcj4oVHlwZWRBcnJheVByb3RvdHlwZSwgJ2xlbmd0aCcpO1xuY29uc3QgZGF0YVZpZXdCdWZmZXIgPSBwcm90b0dldHRlcjxBcnJheUJ1ZmZlckxpa2U+KFxuICBEYXRhVmlldy5wcm90b3R5cGUsXG4gICdidWZmZXInXG4pO1xuY29uc3QgZGF0YVZpZXdCeXRlT2Zmc2V0ID0gcHJvdG9HZXR0ZXI8bnVtYmVyPihcbiAgRGF0YVZpZXcucHJvdG90eXBlLFxuICAnYnl0ZU9mZnNldCdcbik7XG5jb25zdCBkYXRhVmlld0J5dGVMZW5ndGggPSBwcm90b0dldHRlcjxudW1iZXI+KFxuICBEYXRhVmlldy5wcm90b3R5cGUsXG4gICdieXRlTGVuZ3RoJ1xuKTtcbmNvbnN0IHNoYXJlZEFycmF5QnVmZmVyQnl0ZUxlbmd0aCA9IHByb3RvR2V0dGVyPG51bWJlcj4oXG4gIFNoYXJlZEFycmF5QnVmZmVyLnByb3RvdHlwZSxcbiAgJ2J5dGVMZW5ndGgnXG4pO1xuXG4vLyBIb3N0IChXSEFUV0cpIGNsYXNzZXMuIEluamVjdGVkIGludG8gdGhlIHNhbmRib3ggYnkgcmVmZXJlbmNlLCBzb1xuLy8gaW5zdGFuY2VzIGZyb20gYW55IHJlYWxtIGNhcnJ5IHRoZXNlIHByb3RvdHlwZXMsIGFuZCB0aGUgc2hhcmVkXG4vLyBwcm90b3R5cGVzIGFyZSByZWFjaGFibGUgZnJvbSB3b3JrZmxvdyBjb2RlLCB3aGljaCBtYWtlcyB0aGUgYm9vdC10aW1lXG4vLyBjYXB0dXJlIChyYXRoZXIgdGhhbiBhIGxpdmUgbG9va3VwKSBsb2FkLWJlYXJpbmcuXG5jb25zdCBoZWFkZXJzSXRlcmF0b3IgPSB1bmN1cnJ5VGhpcyhIZWFkZXJzLnByb3RvdHlwZVtTeW1ib2wuaXRlcmF0b3JdKTtcbmNvbnN0IHVybEhyZWZHZXR0ZXIgPSBwcm90b0dldHRlcjxzdHJpbmc+KFVSTC5wcm90b3R5cGUsICdocmVmJyk7XG5jb25zdCB1cmxTZWFyY2hQYXJhbXNUb1N0cmluZ01ldGhvZCA9IHVuY3VycnlUaGlzKFxuICBVUkxTZWFyY2hQYXJhbXMucHJvdG90eXBlLnRvU3RyaW5nXG4pO1xuXG4vLyAtLS0tIFNhZmUgYWNjZXNzIHByaW1pdGl2ZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5jb25zdCB7IGlzUHJveHkgfSA9IHR5cGVzO1xuXG5jb25zdCBmdW5jdGlvblRvU3RyaW5nID0gdW5jdXJyeVRoaXMoRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nKTtcblxuLyoqXG4gKiBXaGV0aGVyIGFuIGFjY2Vzc29yIGlzIHByb3ZpZGVkIGJ5IHRoZSBlbmdpbmUgb3IgdGhlIGhvc3QsIHJhdGhlciB0aGFuXG4gKiBkZWZpbmVkIGJ5IHdvcmtmbG93IGNvZGUuIFNlcmlhbGl6YXRpb24gbXVzdCByZWFkIHNvbWUgcHJvcGVydGllcyB0aGF0IGFyZVxuICogYWNjZXNzb3JzIGJ5IGNvbnN0cnVjdGlvbiAoVjggZGVmaW5lcyBgc3RhY2tgIGFzIGFuIG93biBhY2Nlc3NvciBvbiBldmVyeVxuICogRXJyb3IgaW5zdGFuY2U7IE5vZGUgaW1wbGVtZW50cyBgRE9NRXhjZXB0aW9uLnByb3RvdHlwZS5tZXNzYWdlYCBpblxuICogSmF2YVNjcmlwdCksIGFuZCByZXBvcnRpbmcgdGhvc2Ugd291bGQgZHJvd24gdGhlIHNpZ25hbCBpbiBub2lzZS5cbiAqXG4gKiAtIEVuZ2luZSBhY2Nlc3NvcnMgYXJlIG5hdGl2ZSBjb2RlLCBkZXRlY3RlZCB2aWEgdGhlIGNhcHR1cmVkIGhvc3RcbiAqICAgYEZ1bmN0aW9uLnByb3RvdHlwZS50b1N0cmluZ2AgKGNyb3NzLXJlYWxtLCB1bmludGVyY2VwdGFibGUpLiBCb3VuZFxuICogICBmdW5jdGlvbnMgYW5kIGNhbGxhYmxlIFByb3hpZXMgYWxzbyBwcmVzZW50IGFzIG5hdGl2ZSBjb2RlIGJ1dCBydW5cbiAqICAgd29ya2Zsb3cgY29kZSwgc28gYm90aCBhcmUgZXhjbHVkZWQgZmlyc3QuXG4gKiAtIEhvc3QgYnVpbHRpbnMgaW1wbGVtZW50ZWQgaW4gSmF2YVNjcmlwdCBhcmUgb3JkaW5hcnkgZnVuY3Rpb25zLCBidXQgdGhleVxuICogICBiZWxvbmcgdG8gdGhlIGhvc3QgcmVhbG0sIGRldGVjdGVkIGJ5IGNvbXBhcmluZyB0aGUgZnVuY3Rpb24nc1xuICogICBwcm90b3R5cGUgYWdhaW5zdCB0aGUgaG9zdCBgRnVuY3Rpb24ucHJvdG90eXBlYC4gV29ya2Zsb3cgY29kZSB0aGF0XG4gKiAgIHJlYWNoZXMgYSBob3N0IGZ1bmN0aW9uIGNhbiBgc2V0UHJvdG90eXBlT2ZgIGl0cyBvd24gZ2V0dGVyIHRvXG4gKiAgIGltcGVyc29uYXRlIHRoaXM7IHRoYXQgY29zdHMgYSBtaXNzaW5nIHJlcG9ydCBlbnRyeSwgbmV2ZXIgaW5jb3JyZWN0XG4gKiAgIG91dHB1dC5cbiAqXG4gKiBWOCdzIG5hdGl2ZSBgc3RhY2tgIGdldHRlciBjYW4gaXRzZWxmIGludm9rZSBhIHdvcmtmbG93LWRlZmluZWRcbiAqIGBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZWA7IHRoYXQgaW5kaXJlY3Rpb24gaXMgbm90IGRldGVjdGVkIGhlcmUuXG4gKi9cbmZ1bmN0aW9uIGlzRW5naW5lQWNjZXNzb3IoZ2V0dGVyOiBvYmplY3QpOiBib29sZWFuIHtcbiAgaWYgKGlzUHJveHkoZ2V0dGVyKSkgcmV0dXJuIGZhbHNlO1xuICAvLyBBIGJvdW5kIGZ1bmN0aW9uIHN0cmluZ2lmaWVzIGFzIG5hdGl2ZSBjb2RlIGJ1dCBydW5zIGl0cyB0YXJnZXQuIFRoZVxuICAvLyBvbmUgcGFzc2l2ZSBkaXN0aW5ndWlzaGVyIFY4IGV4cG9zZXMgaXMgdGhlIGBuYW1lYCBvd24gcHJvcGVydHlcbiAgLy8gKGBcImJvdW5kIGZuXCJgKS4gV29ya2Zsb3cgY29kZSBjYW4gcmVkZWZpbmUgdGhlIG5hbWUgdG8gaGlkZSBpdDsgdGhhdFxuICAvLyBjb3N0cyBhIG1pc3NpbmcgcmVwb3J0IGVudHJ5LCBsaWtlIHRoZSBvdGhlciBpbXBlcnNvbmF0aW9uIGNhdmVhdHMuXG4gIGNvbnN0IG5hbWUgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGdldHRlciwgJ25hbWUnKT8udmFsdWU7XG4gIGlmICh0eXBlb2YgbmFtZSA9PT0gJ3N0cmluZycgJiYgbmFtZS5zdGFydHNXaXRoKCdib3VuZCAnKSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gKFxuICAgIGZ1bmN0aW9uVG9TdHJpbmcoZ2V0dGVyIGFzICgpID0+IHVua25vd24pLmVuZHNXaXRoKCd7IFtuYXRpdmUgY29kZV0gfScpIHx8XG4gICAgUmVmbGVjdC5nZXRQcm90b3R5cGVPZihnZXR0ZXIpID09PSBGdW5jdGlvbi5wcm90b3R5cGVcbiAgKTtcbn1cblxuLyoqXG4gKiBSZWFkcyBgdmFsdWVba2V5XWAgd2l0aCBgW1tHZXRdXWAgc2VtYW50aWNzLCBidXQgdGhyb3VnaCBkZXNjcmlwdG9yczpcbiAqIHBsYWluIGRhdGEgcHJvcGVydGllcyBuZXZlciBpbnZva2UgYW55dGhpbmc7IGFjY2Vzc29yIHByb3BlcnRpZXMgYXJlXG4gKiBpbnZva2VkICh0aGUgZGF0YSBsaXZlcyBiZWhpbmQgdGhlbSkgYW5kIHJlY29yZGVkOyBwcm94aWVzIGZhbGwgYmFjayB0b1xuICogYSBwbGFpbiByZWFkICh0aGVpciB0cmFwcyBhcmUgdGhlIG9ubHkgYWNjZXNzIHBhdGgpIGFuZCBhcmUgcmVjb3JkZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWFkUHJvcGVydHkodmFsdWU6IHVua25vd24sIGtleTogUHJvcGVydHlLZXkpOiB1bmtub3duIHtcbiAgaWYgKFxuICAgIHZhbHVlID09PSBudWxsIHx8XG4gICAgKHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcgJiYgdHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nKVxuICApIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGlmIChpc1Byb3h5KHZhbHVlKSkge1xuICAgIHJlY29yZFByb3h5KHZhbHVlKTtcbiAgICByZXR1cm4gKHZhbHVlIGFzIFJlY29yZDxQcm9wZXJ0eUtleSwgdW5rbm93bj4pW2tleV07XG4gIH1cblxuICBsZXQgY3VycmVudDogb2JqZWN0IHwgbnVsbCA9IHZhbHVlO1xuICB3aGlsZSAoY3VycmVudCAhPT0gbnVsbCkge1xuICAgIGlmIChpc1Byb3h5KGN1cnJlbnQpKSB7XG4gICAgICAvLyBhIHByb3h5IGluIHRoZSBwcm90b3R5cGUgY2hhaW46IGl0cyB0cmFwcyBhbnN3ZXIgdGhlIGxvb2t1cFxuICAgICAgcmVjb3JkUHJveHkoY3VycmVudCk7XG4gICAgICByZXR1cm4gKHZhbHVlIGFzIFJlY29yZDxQcm9wZXJ0eUtleSwgdW5rbm93bj4pW2tleV07XG4gICAgfVxuICAgIGNvbnN0IGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGN1cnJlbnQsIGtleSk7XG4gICAgaWYgKGRlc2NyaXB0b3IpIHtcbiAgICAgIGlmICgndmFsdWUnIGluIGRlc2NyaXB0b3IpIHJldHVybiBkZXNjcmlwdG9yLnZhbHVlO1xuICAgICAgaWYgKGRlc2NyaXB0b3IuZ2V0KSB7XG4gICAgICAgIGlmICghaXNFbmdpbmVBY2Nlc3NvcihkZXNjcmlwdG9yLmdldCkpIHtcbiAgICAgICAgICByZWNvcmRHdWVzdENvZGUoJ2dldHRlcicsIFN0cmluZyhrZXkpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVzY3JpcHRvci5nZXQuY2FsbCh2YWx1ZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdW5kZWZpbmVkOyAvLyBzZXR0ZXItb25seSBwcm9wZXJ0eVxuICAgIH1cbiAgICBjdXJyZW50ID0gUmVmbGVjdC5nZXRQcm90b3R5cGVPZihjdXJyZW50KTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIGBrZXkgaW4gdmFsdWVgIHNlbWFudGljcyB3aXRob3V0IGZpcmluZyBwcm94eSB0cmFwcyBmb3Igb3JkaW5hcnlcbiAqIG9iamVjdHMuIFByb3hpZXMgZmFsbCBiYWNrIHRvIHRoZSBgaW5gIG9wZXJhdG9yIGFuZCBhcmUgcmVjb3JkZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNQcm9wZXJ0eSh2YWx1ZTogdW5rbm93biwga2V5OiBQcm9wZXJ0eUtleSk6IGJvb2xlYW4ge1xuICBpZiAoXG4gICAgdmFsdWUgPT09IG51bGwgfHxcbiAgICAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicpXG4gICkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoaXNQcm94eSh2YWx1ZSkpIHtcbiAgICByZWNvcmRQcm94eSh2YWx1ZSk7XG4gICAgcmV0dXJuIGtleSBpbiAodmFsdWUgYXMgb2JqZWN0KTtcbiAgfVxuXG4gIGxldCBjdXJyZW50OiBvYmplY3QgfCBudWxsID0gdmFsdWU7XG4gIHdoaWxlIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgaWYgKGlzUHJveHkoY3VycmVudCkpIHtcbiAgICAgIHJlY29yZFByb3h5KGN1cnJlbnQpO1xuICAgICAgcmV0dXJuIGtleSBpbiAodmFsdWUgYXMgb2JqZWN0KTtcbiAgICB9XG4gICAgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoY3VycmVudCwga2V5KSkgcmV0dXJuIHRydWU7XG4gICAgY3VycmVudCA9IFJlZmxlY3QuZ2V0UHJvdG90eXBlT2YoY3VycmVudCk7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIGB2YWx1ZSBpbnN0YW5jZW9mIENgIHNlbWFudGljcyBmb3IgYSBrbm93biBgQy5wcm90b3R5cGVgLCB3aXRob3V0XG4gKiBjb25zdWx0aW5nIGBTeW1ib2wuaGFzSW5zdGFuY2VgICh3aGljaCB3b3JrZmxvdyBjb2RlIGNhbiBkZWZpbmUpLiBVc2VkXG4gKiBmb3IgaG9zdCBjbGFzc2VzIHRoYXQgYXJlIGluamVjdGVkIGludG8gdGhlIHNhbmRib3ggKEhlYWRlcnMsIFVSTCxcbiAqIFVSTFNlYXJjaFBhcmFtcywgRE9NRXhjZXB0aW9uKSwgd2hlcmUgdGhlIGluc3RhbmNlcyAoZnJvbSBhbnkgcmVhbG0gdGhlXG4gKiBob3N0IGhhbmRlZCB0aGUgY2xhc3MgdG8pIGNhcnJ5IHRoZSBob3N0IHByb3RvdHlwZSBpbiB0aGVpciBjaGFpbi5cbiAqXG4gKiBQcm94aWVzIGFyZSB3YWxrZWQgcmF0aGVyIHRoYW4gcmVqZWN0ZWQ6IGBSZWZsZWN0LmdldFByb3RvdHlwZU9mYCBmaXJlc1xuICogdGhlIHByb3h5J3MgYGdldFByb3RvdHlwZU9mYCB0cmFwLCBtYXRjaGluZyBgaW5zdGFuY2VvZmAgc2VtYW50aWNzLCBhbmRcbiAqIHJlYWwgdmFsdWVzIGRlcGVuZCBvbiB0aGF0OiBOZXh0LmpzIGhhbmRzIHRoZSBydW50aW1lIGEgcHJveGllZFxuICogYE5leHRSZXF1ZXN0YCwgYW5kIGFuc3dlcmluZyBcIm5vdCBhIFJlcXVlc3RcIiBmb3IgaXQgd291bGQgc2lsZW50bHkgYnJlYWtcbiAqIHdlYmhvb2tzLiBUaGUgdHJhcHMgYXJlIGd1ZXN0LW9ic2VydmFibGUsIHNvIHRoZSBwcm94eSBpcyByZWNvcmRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzSW5zdGFuY2VPZlByb3RvdHlwZShcbiAgdmFsdWU6IHVua25vd24sXG4gIHByb3RvdHlwZTogb2JqZWN0IHwgdW5kZWZpbmVkXG4pOiBib29sZWFuIHtcbiAgaWYgKCFwcm90b3R5cGUpIHJldHVybiBmYWxzZTtcbiAgaWYgKHZhbHVlID09PSBudWxsIHx8IHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHJldHVybiBmYWxzZTtcbiAgaWYgKGlzUHJveHkodmFsdWUpKSByZWNvcmRQcm94eSh2YWx1ZSk7XG4gIGxldCBjdXJyZW50OiBvYmplY3QgfCBudWxsID0gUmVmbGVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSk7XG4gIHdoaWxlIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgaWYgKGN1cnJlbnQgPT09IHByb3RvdHlwZSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzUHJveHkoY3VycmVudCkpIHJlY29yZFByb3h5KGN1cnJlbnQpO1xuICAgIGN1cnJlbnQgPSBSZWZsZWN0LmdldFByb3RvdHlwZU9mKGN1cnJlbnQpO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLy8gLS0tLSBJbnRyaW5zaWMtYmFja2VkIGV4dHJhY3Rpb24gaGVscGVycyAodXNlZCBieSB0aGUgcmVkdWNlcnMpIC0tLS0tLS0tLS0tLS1cbi8vXG4vLyBJbnRyaW5zaWNzIHJlYWQgaW50ZXJuYWwgc2xvdHMsIHdoaWNoIGEgUHJveHkgZG9lcyBub3QgaGF2ZTogaW52b2tpbmcgb25lXG4vLyB3aXRoIGEgcHJveHkgcmVjZWl2ZXIgdGhyb3dzLCB3aGVyZSB0aGUgcHJlLWV4aXN0aW5nIGR5bmFtaWMgcmVhZCBmb3J3YXJkZWRcbi8vIHRocm91Z2ggdGhlIHRyYXAuIEZvciB0aGUgKHJhcmUpIHByb3h5IGNhc2UsIGZhbGwgYmFjayB0byB0aGUgZHluYW1pYyByZWFkXG4vLyBzbyBiZWhhdmlvciBpcyB1bmNoYW5nZWQsIGFuZCByZWNvcmQgdGhhdCB0aGUgdHJhcHMgcmFuLlxuXG4vKiogYFVSTC5wcm90b3R5cGUuaHJlZmAgZ2V0dGVyLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVybEhyZWYodmFsdWU6IFVSTCk6IHN0cmluZyB7XG4gIGlmIChpc1Byb3h5KHZhbHVlKSkge1xuICAgIHJlY29yZFByb3h5KHZhbHVlKTtcbiAgICByZXR1cm4gdmFsdWUuaHJlZjtcbiAgfVxuICByZXR1cm4gdXJsSHJlZkdldHRlcih2YWx1ZSk7XG59XG5cbi8qKiBgVVJMU2VhcmNoUGFyYW1zLnByb3RvdHlwZS50b1N0cmluZ2A6IHJldHVybnMgYCcnYCBpZmYgZW1wdHkuICovXG5leHBvcnQgZnVuY3Rpb24gdXJsU2VhcmNoUGFyYW1zVG9TdHJpbmcodmFsdWU6IFVSTFNlYXJjaFBhcmFtcyk6IHN0cmluZyB7XG4gIGlmIChpc1Byb3h5KHZhbHVlKSkge1xuICAgIHJlY29yZFByb3h5KHZhbHVlKTtcbiAgICByZXR1cm4gU3RyaW5nKHZhbHVlKTtcbiAgfVxuICByZXR1cm4gdXJsU2VhcmNoUGFyYW1zVG9TdHJpbmdNZXRob2QodmFsdWUpO1xufVxuXG4vKipcbiAqIEl0ZXJhdGVzIGEgSGVhZGVycyBpbnN0YW5jZSB0aHJvdWdoIHRoZSBjYXB0dXJlZCBob3N0IGl0ZXJhdG9yLCBzbyB0aGVcbiAqIGl0ZXJhdG9yIG9iamVjdCwgYW5kIGl0cyBgbmV4dGAsIGFyZSBob3N0LXJlYWxtLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGVhZGVyc1RvRW50cmllcyh2YWx1ZTogSGVhZGVycyk6IFtzdHJpbmcsIHN0cmluZ11bXSB7XG4gIGlmIChpc1Byb3h5KHZhbHVlKSkge1xuICAgIHJlY29yZFByb3h5KHZhbHVlKTtcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh2YWx1ZSkgYXMgW3N0cmluZywgc3RyaW5nXVtdO1xuICB9XG4gIHJldHVybiBbLi4uaGVhZGVyc0l0ZXJhdG9yKHZhbHVlKV0gYXMgW3N0cmluZywgc3RyaW5nXVtdO1xufVxuXG4vKipcbiAqIEl0ZXJhdGVzIGEgZ2VudWluZSBNYXAncyBlbnRyaWVzIGVudGlyZWx5IHRocm91Z2ggaG9zdCBpbnRyaW5zaWNzOiB0aGVcbiAqIGl0ZXJhdG9yIG9iamVjdCBpcyBjcmVhdGVkIGJ5IHRoZSBob3N0IGBNYXAucHJvdG90eXBlLmVudHJpZXNgLCBzbyBpdHNcbiAqIHJlYWxtLCBhbmQgdGhlcmVmb3JlIGl0cyBgbmV4dGAsIGlzIHRoZSBob3N0J3MsIG5vdCB0aGUgc2FuZGJveCdzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFwVG9FbnRyaWVzKFxuICB2YWx1ZTogTWFwPHVua25vd24sIHVua25vd24+XG4pOiBbdW5rbm93biwgdW5rbm93bl1bXSB7XG4gIHJldHVybiBbLi4ubWFwRW50cmllcyh2YWx1ZSldO1xufVxuXG4vKiogU2VlIHtAbGluayBtYXBUb0VudHJpZXN9LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldFRvVmFsdWVzKHZhbHVlOiBTZXQ8dW5rbm93bj4pOiB1bmtub3duW10ge1xuICByZXR1cm4gWy4uLnNldFZhbHVlcyh2YWx1ZSldO1xufVxuXG4vKipcbiAqIFRoZSBieXRlcyBvZiBhbiBgQXJyYXlCdWZmZXJWaWV3YCwgcmVhZCB2aWEgaW50ZXJuYWwtc2xvdCBnZXR0ZXJzLCBzb1xuICogb3duLXByb3BlcnR5IHNoYWRvd2luZyBhbmQgcHJvdG90eXBlIHBhdGNoZXMgY2Fubm90IGNoYW5nZSB3aGljaCBieXRlc1xuICogYXJlIHNlcmlhbGl6ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2aWV3SW5mbyh2YWx1ZTogQXJyYXlCdWZmZXJWaWV3KToge1xuICBidWZmZXI6IEFycmF5QnVmZmVyTGlrZTtcbiAgYnl0ZU9mZnNldDogbnVtYmVyO1xuICBieXRlTGVuZ3RoOiBudW1iZXI7XG59IHtcbiAgaWYgKHR5cGVzLmlzRGF0YVZpZXcodmFsdWUpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGJ1ZmZlcjogZGF0YVZpZXdCdWZmZXIodmFsdWUpLFxuICAgICAgYnl0ZU9mZnNldDogZGF0YVZpZXdCeXRlT2Zmc2V0KHZhbHVlKSxcbiAgICAgIGJ5dGVMZW5ndGg6IGRhdGFWaWV3Qnl0ZUxlbmd0aCh2YWx1ZSksXG4gICAgfTtcbiAgfVxuICByZXR1cm4ge1xuICAgIGJ1ZmZlcjogdHlwZWRBcnJheUJ1ZmZlcih2YWx1ZSksXG4gICAgYnl0ZU9mZnNldDogdHlwZWRBcnJheUJ5dGVPZmZzZXQodmFsdWUpLFxuICAgIGJ5dGVMZW5ndGg6IHR5cGVkQXJyYXlCeXRlTGVuZ3RoKHZhbHVlKSxcbiAgfTtcbn1cblxuLy8gLS0tLSBIYXJkZW5lZCBkZXZhbHVlIG9wZXJhdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vL1xuLy8gVGhlIHdvcmtmbG93IHJlZHVjZXJzIGNsYWltIG1vc3Qgc3BlY2lhbCB0eXBlcyBiZWZvcmUgZGV2YWx1ZSdzIGJ1aWx0LWluXG4vLyBoYW5kbGluZyBydW5zLCBzbyB0aGVzZSBvcGVyYXRpb25zIG1haW5seSBnb3Zlcm4gcGxhaW4gb2JqZWN0cywgYXJyYXlzLFxuLy8gYm94ZWQgcHJpbWl0aXZlcywgdGhlbmFibGUgcHJvYmVzLCBhbmQgY2xhc3NpZmljYXRpb24gKGB0YWdPZmApLCB3aGljaFxuLy8gcnVucyBmb3IgZXZlcnkgb2JqZWN0IHRoZSByZWR1Y2VycyBkaWQgbm90IGNsYWltLlxuXG5jb25zdCBLTk9XTl9WSUVXX1RBR1MgPSBuZXcgU2V0KFtcbiAgJ0ludDhBcnJheScsXG4gICdVaW50OEFycmF5JyxcbiAgJ1VpbnQ4Q2xhbXBlZEFycmF5JyxcbiAgJ0ludDE2QXJyYXknLFxuICAnVWludDE2QXJyYXknLFxuICAnRmxvYXQxNkFycmF5JyxcbiAgJ0ludDMyQXJyYXknLFxuICAnVWludDMyQXJyYXknLFxuICAnRmxvYXQzMkFycmF5JyxcbiAgJ0Zsb2F0NjRBcnJheScsXG4gICdCaWdJbnQ2NEFycmF5JyxcbiAgJ0JpZ1VpbnQ2NEFycmF5Jyxcbl0pO1xuXG4vKipcbiAqIFRhZ3MgdGhhdCB7QGxpbmsgYnJhbmRPZn0gZGVjaWRlcyBhdXRob3JpdGF0aXZlbHkuIElmIHRoZSBicmFuZCBjaGVjayBzYWlkXG4gKiBcIm5vdCBvbmUgb2YgdGhlc2VcIiB0aGVuIGEgYFN5bWJvbC50b1N0cmluZ1RhZ2AgY2xhaW1pbmcgb25lIGlzIGEgc3Bvb2YsIGFuZFxuICogaG9ub3VyaW5nIGl0IHdvdWxkIHJvdXRlIHRoZSB2YWx1ZSBpbnRvIGFuIGV4dHJhY3RvciB0aGF0IHJlcXVpcmVzIHRoZSByZWFsXG4gKiBpbnRlcm5hbCBzbG90IChgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2Agc2VtYW50aWNzIGxldCBhbnkgb2JqZWN0IGNsYWltXG4gKiBgW29iamVjdCBEYXRlXWApLiBVbmJyYW5kZWQgdmFsdWVzIHRoYXQgY2xhaW0gb25lIG9mIHRoZXNlIGFyZSBjbGFzc2lmaWVkXG4gKiBhcyBwbGFpbiBvYmplY3RzIGluc3RlYWQuXG4gKi9cbmNvbnN0IEJSQU5EX0RFQ0lERURfVEFHUyA9IG5ldyBTZXQoW1xuICAnRGF0ZScsXG4gICdSZWdFeHAnLFxuICAnTWFwJyxcbiAgJ1NldCcsXG4gICdBcnJheScsXG4gICdEYXRhVmlldycsXG4gICdBcnJheUJ1ZmZlcicsXG4gICdTaGFyZWRBcnJheUJ1ZmZlcicsXG4gICdOdW1iZXInLFxuICAnU3RyaW5nJyxcbiAgJ0Jvb2xlYW4nLFxuICAnQmlnSW50JyxcbiAgJ1VSTCcsXG4gICdVUkxTZWFyY2hQYXJhbXMnLFxuICAuLi5LTk9XTl9WSUVXX1RBR1MsXG5dKTtcblxuLyoqXG4gKiBDbGFzc2lmaWVzIGEgdmFsdWUgYnkgZW5naW5lIGJyYW5kLiBSZXR1cm5zIHVuZGVmaW5lZCB3aGVuIG5vIGJyYW5kXG4gKiBtYXRjaGVzICh0aGUgY2FsbGVyIGZhbGxzIGJhY2sgdG8gYFN5bWJvbC50b1N0cmluZ1RhZ2Agc2VtYW50aWNzKS5cbiAqL1xuZnVuY3Rpb24gYnJhbmRPZih2YWx1ZTogb2JqZWN0KTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHR5cGVzLmlzRGF0ZSh2YWx1ZSkpIHJldHVybiAnRGF0ZSc7XG4gIGlmICh0eXBlcy5pc1JlZ0V4cCh2YWx1ZSkpIHJldHVybiAnUmVnRXhwJztcbiAgaWYgKHR5cGVzLmlzTWFwKHZhbHVlKSkgcmV0dXJuICdNYXAnO1xuICBpZiAodHlwZXMuaXNTZXQodmFsdWUpKSByZXR1cm4gJ1NldCc7XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuICdBcnJheSc7XG4gIGlmICh0eXBlcy5pc1R5cGVkQXJyYXkodmFsdWUpKSB7XG4gICAgY29uc3QgdGFnID0gdHlwZWRBcnJheVRhZyh2YWx1ZSk7XG4gICAgcmV0dXJuIHRhZyAhPT0gdW5kZWZpbmVkICYmIEtOT1dOX1ZJRVdfVEFHUy5oYXModGFnKSA/IHRhZyA6IHVuZGVmaW5lZDtcbiAgfVxuICBpZiAodHlwZXMuaXNEYXRhVmlldyh2YWx1ZSkpIHJldHVybiAnRGF0YVZpZXcnO1xuICBpZiAodHlwZXMuaXNBcnJheUJ1ZmZlcih2YWx1ZSkpIHJldHVybiAnQXJyYXlCdWZmZXInO1xuICBpZiAodHlwZXMuaXNTaGFyZWRBcnJheUJ1ZmZlcih2YWx1ZSkpIHJldHVybiAnU2hhcmVkQXJyYXlCdWZmZXInO1xuICBpZiAodHlwZXMuaXNOdW1iZXJPYmplY3QodmFsdWUpKSByZXR1cm4gJ051bWJlcic7XG4gIGlmICh0eXBlcy5pc1N0cmluZ09iamVjdCh2YWx1ZSkpIHJldHVybiAnU3RyaW5nJztcbiAgaWYgKHR5cGVzLmlzQm9vbGVhbk9iamVjdCh2YWx1ZSkpIHJldHVybiAnQm9vbGVhbic7XG4gIGlmICh0eXBlcy5pc0JpZ0ludE9iamVjdCh2YWx1ZSkpIHJldHVybiAnQmlnSW50JztcbiAgaWYgKGlzSW5zdGFuY2VPZlByb3RvdHlwZSh2YWx1ZSwgVVJMLnByb3RvdHlwZSkpIHJldHVybiAnVVJMJztcbiAgaWYgKGlzSW5zdGFuY2VPZlByb3RvdHlwZSh2YWx1ZSwgVVJMU2VhcmNoUGFyYW1zLnByb3RvdHlwZSkpIHtcbiAgICByZXR1cm4gJ1VSTFNlYXJjaFBhcmFtcyc7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZWFkcyBgU3ltYm9sLnRvU3RyaW5nVGFnYCB0aGUgd2F5IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYCB3b3VsZCxcbiAqIGJ1dCB0aHJvdWdoIGRlc2NyaXB0b3JzOiBhIGRhdGEtcHJvcGVydHkgdGFnICh0aGUgY29tbW9uIGNhc2UsIGUuZy5cbiAqIFRlbXBvcmFsIHBvbHlmaWxscykgY29zdHMgbm8gd29ya2Zsb3ctY29kZSBleGVjdXRpb247IGFuIGFjY2Vzc29yIHRhZyBpc1xuICogaW52b2tlZCAoY29tcGF0KSBhbmQgcmVjb3JkZWQuXG4gKi9cbmZ1bmN0aW9uIHJlYWRUb1N0cmluZ1RhZyh2YWx1ZTogb2JqZWN0KTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgdGFnID0gcmVhZFByb3BlcnR5KHZhbHVlLCBTeW1ib2wudG9TdHJpbmdUYWcpO1xuICByZXR1cm4gdHlwZW9mIHRhZyA9PT0gJ3N0cmluZycgPyB0YWcgOiB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBjb25zdCBoYXJkZW5lZFN0cmluZ2lmeU9wZXJhdGlvbnM6IFBhcnRpYWw8U3RyaW5naWZ5T3BlcmF0aW9ucz4gPSB7XG4gIHRhZ09mOiAodmFsdWU6IG9iamVjdCkgPT4ge1xuICAgIGlmIChpc1Byb3h5KHZhbHVlKSkge1xuICAgICAgLy8gQSBwcm94eSdzIGNsYXNzaWZpY2F0aW9uIGlzIGFuc3dlcmVkIGJ5IGl0cyB0cmFwcywgd2hpY2ggaXMgdGhlXG4gICAgICAvLyBvbmx5IGFjY2VzcyBwYXRoIHRoZXJlIGlzLiBSZWNvcmQgaXQgYW5kIHByZXNlcnZlIHRvZGF5J3NcbiAgICAgIC8vIGJlaGF2aW9yIGZvciBldmVyeXRoaW5nIGRvd25zdHJlYW0uXG4gICAgICByZWNvcmRQcm94eSh2YWx1ZSk7XG4gICAgICByZXR1cm4gZGVmYXVsdFN0cmluZ2lmeU9wZXJhdGlvbnMudGFnT2YodmFsdWUpO1xuICAgIH1cbiAgICBjb25zdCBicmFuZCA9IGJyYW5kT2YodmFsdWUpO1xuICAgIGlmIChicmFuZCAhPT0gdW5kZWZpbmVkKSByZXR1cm4gYnJhbmQ7XG4gICAgLy8gTm8gZW5naW5lIGJyYW5kIG1hdGNoZWQuIEEgYFN5bWJvbC50b1N0cmluZ1RhZ2AgaXMgc3RpbGwgbWVhbmluZ2Z1bCBmb3JcbiAgICAvLyB0eXBlcyBkZXZhbHVlIGlkZW50aWZpZXMgdGhhdCB3YXkgKGBUZW1wb3JhbC4qYCksIGJ1dCBvbmUgbmFtaW5nIGFcbiAgICAvLyBicmFuZC1kZWNpZGVkIHR5cGUgaXMgYSBzcG9vZiBhbmQgaXMgaWdub3JlZC5cbiAgICBjb25zdCB0YWcgPSByZWFkVG9TdHJpbmdUYWcodmFsdWUpO1xuICAgIGlmICh0YWcgPT09IHVuZGVmaW5lZCB8fCBCUkFORF9ERUNJREVEX1RBR1MuaGFzKHRhZykpIHJldHVybiAnT2JqZWN0JztcbiAgICByZXR1cm4gdGFnO1xuICB9LFxuXG4gIGlzVGhlbmFibGU6ICh2YWx1ZTogeyB0aGVuPzogdW5rbm93biB9KSA9PiB7XG4gICAgaWYgKHR5cGVzLmlzUHJvbWlzZSh2YWx1ZSkpIHJldHVybiB0cnVlO1xuICAgIHJldHVybiB0eXBlb2YgcmVhZFByb3BlcnR5KHZhbHVlLCAndGhlbicpID09PSAnZnVuY3Rpb24nO1xuICB9LFxuXG4gIHVuYm94OiAoYm94ZWQ6IG9iamVjdCkgPT4ge1xuICAgIGlmICh0eXBlcy5pc051bWJlck9iamVjdChib3hlZCkpIHJldHVybiBudW1iZXJWYWx1ZU9mKGJveGVkKTtcbiAgICBpZiAodHlwZXMuaXNTdHJpbmdPYmplY3QoYm94ZWQpKSByZXR1cm4gc3RyaW5nVmFsdWVPZihib3hlZCk7XG4gICAgaWYgKHR5cGVzLmlzQm9vbGVhbk9iamVjdChib3hlZCkpIHJldHVybiBib29sZWFuVmFsdWVPZihib3hlZCk7XG4gICAgcmV0dXJuIGJpZ0ludFZhbHVlT2YoYm94ZWQpO1xuICB9LFxuXG4gIHRvSVNPU3RyaW5nOiAoZGF0ZTogRGF0ZSkgPT5cbiAgICBOdW1iZXIuaXNOYU4oZGF0ZUdldERhdGUoZGF0ZSkpID8gJycgOiBkYXRlVG9JU09TdHJpbmcoZGF0ZSksXG5cbiAgdG9TdHJpbmdWYWx1ZTogKHZhbHVlOiBvYmplY3QpID0+IHtcbiAgICAvLyBSZWFjaGVkIGZvciBVUkwgLyBVUkxTZWFyY2hQYXJhbXMgKHdoZW4gdGhlIHJlZHVjZXJzIGRpZCBub3QgY2xhaW1cbiAgICAvLyB0aGVtLCBlLmcuIGluc3RhbmNlcyBvZiBhIGRpZmZlcmVudCByZWFsbSdzIGNsYXNzZXMpIGFuZCBmb3JcbiAgICAvLyB0b1N0cmluZ1RhZy1icmFuZGVkIG9iamVjdHMgbGlrZSBUZW1wb3JhbCBwb2x5ZmlsbHMsIHdob3NlIHN0cmluZ1xuICAgIC8vIGZvcm0gb25seSB0aGVpciBvd24gdG9TdHJpbmcoKSBjYW4gcHJvZHVjZS5cbiAgICBpZiAoaXNJbnN0YW5jZU9mUHJvdG90eXBlKHZhbHVlLCBVUkwucHJvdG90eXBlKSkge1xuICAgICAgcmV0dXJuIHVybEhyZWYodmFsdWUgYXMgVVJMKTtcbiAgICB9XG4gICAgaWYgKGlzSW5zdGFuY2VPZlByb3RvdHlwZSh2YWx1ZSwgVVJMU2VhcmNoUGFyYW1zLnByb3RvdHlwZSkpIHtcbiAgICAgIHJldHVybiB1cmxTZWFyY2hQYXJhbXNUb1N0cmluZyh2YWx1ZSBhcyBVUkxTZWFyY2hQYXJhbXMpO1xuICAgIH1cbiAgICByZWNvcmRHdWVzdENvZGUoXG4gICAgICAnbWV0aG9kJyxcbiAgICAgIGB0b1N0cmluZyAoJHtyZWFkVG9TdHJpbmdUYWcodmFsdWUpID8/ICd1bmtub3duJ30pYFxuICAgICk7XG4gICAgcmV0dXJuICh2YWx1ZSBhcyB7IHRvU3RyaW5nKCk6IHN0cmluZyB9KS50b1N0cmluZygpO1xuICB9LFxuXG4gIHJlZ0V4cEluZm86IChyZWdleHA6IFJlZ0V4cCkgPT4gKHtcbiAgICBzb3VyY2U6IHJlZ0V4cFNvdXJjZShyZWdleHApLFxuICAgIGZsYWdzOiByZWdFeHBGbGFncyhyZWdleHApLFxuICB9KSxcblxuICB2YWx1ZXNPZjogKHNldDogU2V0PHVua25vd24+KSA9PiBzZXRUb1ZhbHVlcyhzZXQpLFxuICBlbnRyaWVzT2Y6IChtYXA6IE1hcDx1bmtub3duLCB1bmtub3duPikgPT5cbiAgICBtYXBUb0VudHJpZXMobWFwKSBhcyBbdW5rbm93biwgdW5rbm93bl1bXSxcblxuICB2aWV3SW5mbzogKHZpZXc6IEFycmF5QnVmZmVyVmlldykgPT4ge1xuICAgIGNvbnN0IGluZm8gPSB2aWV3SW5mbyh2aWV3KTtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uaW5mbyxcbiAgICAgIC8vIGRldmFsdWUgb25seSByZWFkcyBgbGVuZ3RoYCBmb3IgdHlwZWQtYXJyYXkgc3Vidmlld3M7IERhdGFWaWV3XG4gICAgICAvLyBzdWJ2aWV3cyBhcmUgZW5jb2RlZCBmcm9tIGBieXRlTGVuZ3RoYC5cbiAgICAgIGxlbmd0aDogdHlwZXMuaXNEYXRhVmlldyh2aWV3KSA/IDAgOiB0eXBlZEFycmF5TGVuZ3RoKHZpZXcpLFxuICAgICAgYnVmZmVyQnl0ZUxlbmd0aDogdHlwZXMuaXNTaGFyZWRBcnJheUJ1ZmZlcihpbmZvLmJ1ZmZlcilcbiAgICAgICAgPyBzaGFyZWRBcnJheUJ1ZmZlckJ5dGVMZW5ndGgoaW5mby5idWZmZXIpXG4gICAgICAgIDogYXJyYXlCdWZmZXJCeXRlTGVuZ3RoKGluZm8uYnVmZmVyKSxcbiAgICB9O1xuICB9LFxuXG4gIHNoYXBlT2Y6ICh2YWx1ZTogb2JqZWN0KSA9PiB7XG4gICAgaWYgKGlzUHJveHkodmFsdWUpKSByZWNvcmRQcm94eSh2YWx1ZSk7XG4gICAgcmV0dXJuIGRlZmF1bHRTdHJpbmdpZnlPcGVyYXRpb25zLnNoYXBlT2YodmFsdWUpO1xuICB9LFxuXG4gIGdldDogKHZhbHVlOiBvYmplY3QsIGtleTogc3RyaW5nIHwgbnVtYmVyKSA9PiByZWFkUHJvcGVydHkodmFsdWUsIGtleSksXG59O1xuIl19