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

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 (317) hide show
  1. package/README.md +5 -0
  2. package/dist/attribute-changes.d.ts +5 -0
  3. package/dist/attribute-changes.d.ts.map +1 -0
  4. package/dist/attribute-changes.js +25 -0
  5. package/dist/capabilities.d.ts +35 -2
  6. package/dist/capabilities.d.ts.map +1 -1
  7. package/dist/capabilities.js +74 -5
  8. package/dist/capture-stack.d.ts +1 -1
  9. package/dist/capture-stack.js +2 -2
  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 +19 -3
  14. package/dist/classify-error.d.ts.map +1 -1
  15. package/dist/classify-error.js +98 -6
  16. package/dist/context-violation-error.d.ts +5 -5
  17. package/dist/context-violation-error.d.ts.map +1 -1
  18. package/dist/context-violation-error.js +8 -6
  19. package/dist/create-hook.d.ts +72 -7
  20. package/dist/create-hook.d.ts.map +1 -1
  21. package/dist/create-hook.js +1 -1
  22. package/dist/define-hook.js +2 -2
  23. package/dist/describe-error.d.ts +7 -7
  24. package/dist/describe-error.d.ts.map +1 -1
  25. package/dist/describe-error.js +97 -12
  26. package/dist/encryption.d.ts +38 -4
  27. package/dist/encryption.d.ts.map +1 -1
  28. package/dist/encryption.js +96 -14
  29. package/dist/events-consumer.d.ts +297 -0
  30. package/dist/events-consumer.d.ts.map +1 -1
  31. package/dist/events-consumer.js +673 -42
  32. package/dist/flushable-stream.d.ts +97 -1
  33. package/dist/flushable-stream.d.ts.map +1 -1
  34. package/dist/flushable-stream.js +291 -11
  35. package/dist/global.d.ts +36 -2
  36. package/dist/global.d.ts.map +1 -1
  37. package/dist/global.js +21 -6
  38. package/dist/index.d.ts +2 -1
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +3 -2
  41. package/dist/log-format.d.ts +2 -2
  42. package/dist/log-format.js +19 -12
  43. package/dist/logger.d.ts +1 -0
  44. package/dist/logger.d.ts.map +1 -1
  45. package/dist/logger.js +10 -6
  46. package/dist/private.d.ts +226 -9
  47. package/dist/private.d.ts.map +1 -1
  48. package/dist/private.js +626 -7
  49. package/dist/replay-divergence.d.ts +25 -0
  50. package/dist/replay-divergence.d.ts.map +1 -0
  51. package/dist/replay-divergence.js +61 -0
  52. package/dist/replay-payload-cache.d.ts +64 -0
  53. package/dist/replay-payload-cache.d.ts.map +1 -0
  54. package/dist/replay-payload-cache.js +158 -0
  55. package/dist/runtime/compute-instance.d.ts +13 -0
  56. package/dist/runtime/compute-instance.d.ts.map +1 -0
  57. package/dist/runtime/compute-instance.js +14 -0
  58. package/dist/runtime/constants.d.ts +315 -0
  59. package/dist/runtime/constants.d.ts.map +1 -1
  60. package/dist/runtime/constants.js +502 -16
  61. package/dist/runtime/count-step-started-events.d.ts +52 -0
  62. package/dist/runtime/count-step-started-events.d.ts.map +1 -0
  63. package/dist/runtime/count-step-started-events.js +72 -0
  64. package/dist/runtime/deployment-guard.d.ts +99 -0
  65. package/dist/runtime/deployment-guard.d.ts.map +1 -0
  66. package/dist/runtime/deployment-guard.js +154 -0
  67. package/dist/runtime/get-port-lazy.d.ts +15 -0
  68. package/dist/runtime/get-port-lazy.d.ts.map +1 -1
  69. package/dist/runtime/get-port-lazy.js +75 -6
  70. package/dist/runtime/get-world-lazy.d.ts +5 -14
  71. package/dist/runtime/get-world-lazy.d.ts.map +1 -1
  72. package/dist/runtime/get-world-lazy.js +19 -29
  73. package/dist/runtime/helpers.d.ts +415 -29
  74. package/dist/runtime/helpers.d.ts.map +1 -1
  75. package/dist/runtime/helpers.js +686 -57
  76. package/dist/runtime/quickjs-assets.generated.d.ts +14 -0
  77. package/dist/runtime/quickjs-assets.generated.d.ts.map +1 -0
  78. package/dist/runtime/quickjs-assets.generated.js +30 -0
  79. package/dist/runtime/quickjs-entrypoint.d.ts +158 -0
  80. package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -0
  81. package/dist/runtime/quickjs-entrypoint.js +1863 -0
  82. package/dist/runtime/quickjs-log-view.d.ts +129 -0
  83. package/dist/runtime/quickjs-log-view.d.ts.map +1 -0
  84. package/dist/runtime/quickjs-log-view.js +229 -0
  85. package/dist/runtime/quickjs-runtime.d.ts +244 -0
  86. package/dist/runtime/quickjs-runtime.d.ts.map +1 -0
  87. package/dist/runtime/quickjs-runtime.js +2427 -0
  88. package/dist/runtime/quickjs-serde.d.ts +107 -0
  89. package/dist/runtime/quickjs-serde.d.ts.map +1 -0
  90. package/dist/runtime/quickjs-serde.js +2159 -0
  91. package/dist/runtime/replay-budget.d.ts +97 -0
  92. package/dist/runtime/replay-budget.d.ts.map +1 -0
  93. package/dist/runtime/replay-budget.js +139 -0
  94. package/dist/runtime/replay-recovery-reporter.d.ts +36 -0
  95. package/dist/runtime/replay-recovery-reporter.d.ts.map +1 -0
  96. package/dist/runtime/replay-recovery-reporter.js +64 -0
  97. package/dist/runtime/resume-hook.d.ts +91 -8
  98. package/dist/runtime/resume-hook.d.ts.map +1 -1
  99. package/dist/runtime/resume-hook.js +512 -89
  100. package/dist/runtime/resume-latency.d.ts +150 -0
  101. package/dist/runtime/resume-latency.d.ts.map +1 -0
  102. package/dist/runtime/resume-latency.js +155 -0
  103. package/dist/runtime/run-id-time.d.ts +19 -0
  104. package/dist/runtime/run-id-time.d.ts.map +1 -0
  105. package/dist/runtime/run-id-time.js +42 -0
  106. package/dist/runtime/run.d.ts +72 -7
  107. package/dist/runtime/run.d.ts.map +1 -1
  108. package/dist/runtime/run.js +280 -53
  109. package/dist/runtime/runs.d.ts +54 -3
  110. package/dist/runtime/runs.d.ts.map +1 -1
  111. package/dist/runtime/runs.js +126 -16
  112. package/dist/runtime/start.d.ts +101 -2
  113. package/dist/runtime/start.d.ts.map +1 -1
  114. package/dist/runtime/start.js +352 -61
  115. package/dist/runtime/step-executor.d.ts +186 -5
  116. package/dist/runtime/step-executor.d.ts.map +1 -1
  117. package/dist/runtime/step-executor.js +768 -130
  118. package/dist/runtime/step-latency.d.ts +220 -0
  119. package/dist/runtime/step-latency.d.ts.map +1 -0
  120. package/dist/runtime/step-latency.js +215 -0
  121. package/dist/runtime/step-ownership.d.ts +72 -0
  122. package/dist/runtime/step-ownership.d.ts.map +1 -0
  123. package/dist/runtime/step-ownership.js +114 -0
  124. package/dist/runtime/step-single-flight.d.ts +12 -0
  125. package/dist/runtime/step-single-flight.d.ts.map +1 -0
  126. package/dist/runtime/step-single-flight.js +75 -0
  127. package/dist/runtime/suspension-handler.d.ts +247 -7
  128. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  129. package/dist/runtime/suspension-handler.js +1304 -125
  130. package/dist/runtime/unserializable-step.d.ts +34 -0
  131. package/dist/runtime/unserializable-step.d.ts.map +1 -0
  132. package/dist/runtime/unserializable-step.js +52 -0
  133. package/dist/runtime/vm-mode.d.ts +44 -0
  134. package/dist/runtime/vm-mode.d.ts.map +1 -0
  135. package/dist/runtime/vm-mode.js +62 -0
  136. package/dist/runtime/vm-serde-bundle.generated.d.ts +14 -0
  137. package/dist/runtime/vm-serde-bundle.generated.d.ts.map +1 -0
  138. package/dist/runtime/vm-serde-bundle.generated.js +16 -0
  139. package/dist/runtime/wait-continuation.d.ts +106 -0
  140. package/dist/runtime/wait-continuation.d.ts.map +1 -0
  141. package/dist/runtime/wait-continuation.js +136 -0
  142. package/dist/runtime/wait-until.d.ts +18 -0
  143. package/dist/runtime/wait-until.d.ts.map +1 -0
  144. package/dist/runtime/wait-until.js +42 -0
  145. package/dist/runtime/world-compatibility.d.ts +32 -0
  146. package/dist/runtime/world-compatibility.d.ts.map +1 -0
  147. package/dist/runtime/world-compatibility.js +44 -0
  148. package/dist/runtime/world-init.d.ts +17 -42
  149. package/dist/runtime/world-init.d.ts.map +1 -1
  150. package/dist/runtime/world-init.js +18 -43
  151. package/dist/runtime/world.d.ts +14 -2
  152. package/dist/runtime/world.d.ts.map +1 -1
  153. package/dist/runtime/world.js +75 -19
  154. package/dist/runtime.d.ts +10 -6
  155. package/dist/runtime.d.ts.map +1 -1
  156. package/dist/runtime.js +3911 -489
  157. package/dist/sealed-box.d.ts +167 -0
  158. package/dist/sealed-box.d.ts.map +1 -0
  159. package/dist/sealed-box.js +571 -0
  160. package/dist/serialization/client.d.ts +3 -3
  161. package/dist/serialization/client.d.ts.map +1 -1
  162. package/dist/serialization/client.js +8 -4
  163. package/dist/serialization/codec-devalue-vm.d.ts +16 -0
  164. package/dist/serialization/codec-devalue-vm.d.ts.map +1 -0
  165. package/dist/serialization/codec-devalue-vm.js +148 -0
  166. package/dist/serialization/codec-devalue.d.ts +1 -1
  167. package/dist/serialization/codec-devalue.d.ts.map +1 -1
  168. package/dist/serialization/codec-devalue.js +24 -6
  169. package/dist/serialization/codec.d.ts +37 -2
  170. package/dist/serialization/codec.d.ts.map +1 -1
  171. package/dist/serialization/codec.js +2 -2
  172. package/dist/serialization/compression.d.ts +105 -0
  173. package/dist/serialization/compression.d.ts.map +1 -0
  174. package/dist/serialization/compression.js +261 -0
  175. package/dist/serialization/encryption.d.ts +119 -17
  176. package/dist/serialization/encryption.d.ts.map +1 -1
  177. package/dist/serialization/encryption.js +152 -17
  178. package/dist/serialization/errors.d.ts +13 -0
  179. package/dist/serialization/errors.d.ts.map +1 -1
  180. package/dist/serialization/errors.js +20 -2
  181. package/dist/serialization/format.d.ts +6 -6
  182. package/dist/serialization/format.js +7 -7
  183. package/dist/serialization/hardened.d.ts +156 -0
  184. package/dist/serialization/hardened.d.ts.map +1 -0
  185. package/dist/serialization/hardened.js +538 -0
  186. package/dist/serialization/index.d.ts +10 -8
  187. package/dist/serialization/index.d.ts.map +1 -1
  188. package/dist/serialization/index.js +10 -8
  189. package/dist/serialization/reducers/class-vm.d.ts +20 -0
  190. package/dist/serialization/reducers/class-vm.d.ts.map +1 -0
  191. package/dist/serialization/reducers/class-vm.js +77 -0
  192. package/dist/serialization/reducers/class.d.ts.map +1 -1
  193. package/dist/serialization/reducers/class.js +11 -6
  194. package/dist/serialization/reducers/common-vm.d.ts +15 -0
  195. package/dist/serialization/reducers/common-vm.d.ts.map +1 -0
  196. package/dist/serialization/reducers/common-vm.js +616 -0
  197. package/dist/serialization/reducers/common.d.ts +1 -1
  198. package/dist/serialization/reducers/common.d.ts.map +1 -1
  199. package/dist/serialization/reducers/common.js +202 -62
  200. package/dist/serialization/reducers/step-function-vm.d.ts +44 -0
  201. package/dist/serialization/reducers/step-function-vm.d.ts.map +1 -0
  202. package/dist/serialization/reducers/step-function-vm.js +97 -0
  203. package/dist/serialization/reducers/step-function.d.ts.map +1 -1
  204. package/dist/serialization/reducers/step-function.js +25 -9
  205. package/dist/serialization/step.d.ts +4 -4
  206. package/dist/serialization/step.d.ts.map +1 -1
  207. package/dist/serialization/step.js +9 -5
  208. package/dist/serialization/types.d.ts +80 -1
  209. package/dist/serialization/types.d.ts.map +1 -1
  210. package/dist/serialization/types.js +15 -1
  211. package/dist/serialization/workflow-vm.d.ts +29 -0
  212. package/dist/serialization/workflow-vm.d.ts.map +1 -0
  213. package/dist/serialization/workflow-vm.js +74 -0
  214. package/dist/serialization-format.d.ts +64 -8
  215. package/dist/serialization-format.d.ts.map +1 -1
  216. package/dist/serialization-format.js +225 -73
  217. package/dist/serialization.d.ts +262 -34
  218. package/dist/serialization.d.ts.map +1 -1
  219. package/dist/serialization.js +1885 -277
  220. package/dist/set-attributes.d.ts +13 -0
  221. package/dist/set-attributes.d.ts.map +1 -0
  222. package/dist/set-attributes.js +60 -0
  223. package/dist/source-map.d.ts +25 -0
  224. package/dist/source-map.d.ts.map +1 -1
  225. package/dist/source-map.js +154 -10
  226. package/dist/step/context-storage.d.ts +63 -2
  227. package/dist/step/context-storage.d.ts.map +1 -1
  228. package/dist/step/context-storage.js +7 -5
  229. package/dist/step/writable-stream.d.ts +3 -3
  230. package/dist/step/writable-stream.d.ts.map +1 -1
  231. package/dist/step/writable-stream.js +80 -13
  232. package/dist/step.d.ts.map +1 -1
  233. package/dist/step.js +148 -27
  234. package/dist/symbols.d.ts +50 -0
  235. package/dist/symbols.d.ts.map +1 -1
  236. package/dist/symbols.js +51 -1
  237. package/dist/telemetry/semantic-conventions.d.ts +433 -2
  238. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  239. package/dist/telemetry/semantic-conventions.js +319 -3
  240. package/dist/telemetry.d.ts +91 -0
  241. package/dist/telemetry.d.ts.map +1 -1
  242. package/dist/telemetry.js +244 -17
  243. package/dist/test-support/orchestrator-context.d.ts +25 -0
  244. package/dist/test-support/orchestrator-context.d.ts.map +1 -0
  245. package/dist/test-support/orchestrator-context.js +107 -0
  246. package/dist/types.d.ts +6 -0
  247. package/dist/types.d.ts.map +1 -1
  248. package/dist/types.js +23 -1
  249. package/dist/util.d.ts +0 -5
  250. package/dist/util.d.ts.map +1 -1
  251. package/dist/util.js +1 -15
  252. package/dist/version.d.ts +1 -1
  253. package/dist/version.d.ts.map +1 -1
  254. package/dist/version.js +2 -2
  255. package/dist/vm/index.d.ts.map +1 -1
  256. package/dist/vm/index.js +84 -14
  257. package/dist/vm/script-cache.d.ts +26 -0
  258. package/dist/vm/script-cache.d.ts.map +1 -0
  259. package/dist/vm/script-cache.js +131 -0
  260. package/dist/vm/uint8array-base64.js +1 -1
  261. package/dist/workflow/abort-controller.d.ts +2 -2
  262. package/dist/workflow/abort-controller.d.ts.map +1 -1
  263. package/dist/workflow/abort-controller.js +88 -21
  264. package/dist/workflow/attribute-dispatcher.d.ts +6 -0
  265. package/dist/workflow/attribute-dispatcher.d.ts.map +1 -0
  266. package/dist/workflow/attribute-dispatcher.js +45 -0
  267. package/dist/workflow/create-hook.d.ts.map +1 -1
  268. package/dist/workflow/create-hook.js +24 -3
  269. package/dist/workflow/get-workflow-metadata.js +2 -2
  270. package/dist/workflow/hook.d.ts.map +1 -1
  271. package/dist/workflow/hook.js +304 -47
  272. package/dist/workflow/index.d.ts +1 -0
  273. package/dist/workflow/index.d.ts.map +1 -1
  274. package/dist/workflow/index.js +2 -1
  275. package/dist/workflow/set-attributes.d.ts +68 -0
  276. package/dist/workflow/set-attributes.d.ts.map +1 -0
  277. package/dist/workflow/set-attributes.js +60 -0
  278. package/dist/workflow/sleep.d.ts.map +1 -1
  279. package/dist/workflow/sleep.js +58 -12
  280. package/dist/workflow/world-init-stub.d.ts +3 -3
  281. package/dist/workflow/world-init-stub.js +4 -4
  282. package/dist/workflow.d.ts +95 -3
  283. package/dist/workflow.d.ts.map +1 -1
  284. package/dist/workflow.js +900 -561
  285. package/docs/api-reference/create-hook.mdx +89 -10
  286. package/docs/api-reference/create-webhook.mdx +16 -15
  287. package/docs/api-reference/define-hook.mdx +35 -33
  288. package/docs/api-reference/fatal-error.mdx +30 -8
  289. package/docs/api-reference/fetch.mdx +14 -10
  290. package/docs/api-reference/get-step-metadata.mdx +2 -2
  291. package/docs/api-reference/get-workflow-metadata.mdx +3 -3
  292. package/docs/api-reference/get-writable.mdx +7 -7
  293. package/docs/api-reference/index.mdx +4 -1
  294. package/docs/api-reference/retryable-error.mdx +1 -1
  295. package/docs/api-reference/set-attributes.mdx +61 -0
  296. package/docs/api-reference/sleep.mdx +4 -4
  297. package/docs/foundations/cancellation.mdx +31 -32
  298. package/docs/foundations/errors-and-retries.mdx +42 -11
  299. package/docs/foundations/hooks.mdx +64 -35
  300. package/docs/foundations/idempotency.mdx +244 -12
  301. package/docs/foundations/index.mdx +1 -23
  302. package/docs/foundations/meta.json +2 -1
  303. package/docs/foundations/serialization.mdx +21 -22
  304. package/docs/foundations/starting-workflows.mdx +106 -30
  305. package/docs/foundations/streaming.mdx +108 -60
  306. package/docs/foundations/versioning.mdx +263 -0
  307. package/docs/foundations/workflows-and-steps.mdx +9 -9
  308. package/docs/how-it-works/cancellation.mdx +63 -63
  309. package/docs/how-it-works/code-transform.mdx +83 -67
  310. package/docs/how-it-works/encryption.mdx +30 -26
  311. package/docs/how-it-works/event-sourcing.mdx +125 -34
  312. package/docs/how-it-works/framework-integrations.mdx +96 -337
  313. package/docs/how-it-works/understanding-directives.mdx +22 -22
  314. package/package.json +24 -15
  315. package/dist/runtime/step-handler.d.ts +0 -2
  316. package/dist/runtime/step-handler.d.ts.map +0 -1
  317. package/dist/runtime/step-handler.js +0 -776
@@ -5,8 +5,23 @@
5
5
  * dispatch, and shared types/classes used by all environments (runtime, web
6
6
  * o11y, CLI o11y). It has NO Node.js dependencies.
7
7
  */
8
+ import { globalSingleton } from '@workflow/utils';
9
+ import { getEventDataRefFields } from '@workflow/world/event-metadata';
8
10
  import { parse, unflatten } from 'devalue';
9
11
  // ---------------------------------------------------------------------------
12
+ // Key material (browser-safe re-exports)
13
+ // ---------------------------------------------------------------------------
14
+ /**
15
+ * Re-exported from the envelope layer so browser consumers (web dashboard,
16
+ * web-shared) can resolve key material without importing
17
+ * `@workflow/core/serialization`, whose module graph reaches Node built-ins
18
+ * (`node:util`, `node:async_hooks`) and cannot be bundled for the browser.
19
+ *
20
+ * Everything below is Web Crypto only: `serialization/encryption.ts`,
21
+ * `encryption.ts` and `sealed-box.ts` are all free of Node dependencies.
22
+ */
23
+ export { decrypt as decryptEnvelope, deriveRunPayloadKeys, encrypt as encryptEnvelope, isRunPayloadKeys, isSealTarget, runPayloadKeys, sealTo, } from './serialization/encryption.js';
24
+ // ---------------------------------------------------------------------------
10
25
  // Format prefix constants and encoding/decoding
11
26
  // ---------------------------------------------------------------------------
12
27
  export const SerializationFormat = {
@@ -14,6 +29,21 @@ export const SerializationFormat = {
14
29
  DEVALUE_V1: 'devl',
15
30
  /** Encrypted payload (inner payload has its own format prefix after decryption) */
16
31
  ENCRYPTED: 'encr',
32
+ /**
33
+ * Sealed payload: asymmetrically encrypted to a run's X25519 public key
34
+ * (inner payload has its own format prefix after opening).
35
+ *
36
+ * Written by cross-run writers that hold only the recipient run's public
37
+ * key. Opening it requires the run's private scalar rather than the
38
+ * symmetric per-run key, so o11y display treats it as ciphertext via
39
+ * {@link isEncryptedData} but {@link hydrateDataWithKey} does not attempt
40
+ * an AES-GCM decrypt on it.
41
+ */
42
+ SEALED: 'encp',
43
+ /** Gzip-compressed payload (inner payload has its own format prefix after decompression) */
44
+ GZIP: 'gzip',
45
+ /** Zstandard-compressed payload (inner payload has its own format prefix after decompression) */
46
+ ZSTD: 'zstd',
17
47
  };
18
48
  /** Length of the format prefix in bytes */
19
49
  const FORMAT_PREFIX_LENGTH = 4;
@@ -69,7 +99,7 @@ export const ENCRYPTED_PLACEHOLDER = '\u{1F512} Encrypted';
69
99
  // Expired data detection
70
100
  // ---------------------------------------------------------------------------
71
101
  /**
72
- * Check if a plain object is `{ expiredAt: "<ISO date>" }` a single-key
102
+ * Check if a plain object is `{ expiredAt: "<ISO date>" }`: a single-key
73
103
  * object with a string `expiredAt` value.
74
104
  */
75
105
  function isExpiredObject(data) {
@@ -100,15 +130,141 @@ export function isExpiredStub(data) {
100
130
  return false;
101
131
  }
102
132
  /**
103
- * Check if a binary value has the 'encr' format prefix indicating encryption.
104
- * Browser-safe does not depend on the full serialization module.
133
+ * Check if a binary value is ciphertext: either a symmetrically encrypted
134
+ * payload ('encr') or a sealed cross-run payload ('encp').
135
+ *
136
+ * This is the predicate display layers want: both schemes are opaque bytes
137
+ * that must not be fed to the devalue parser, and both render as the same
138
+ * "Encrypted" affordance in the CLI and web UI. Use {@link isSealedData} when
139
+ * the *scheme* matters, notably when choosing a decryption path, since a
140
+ * sealed payload needs the run's private scalar rather than its symmetric key.
141
+ *
142
+ * Browser-safe: does not depend on the full serialization module.
105
143
  */
106
144
  export function isEncryptedData(data) {
107
145
  if (!(data instanceof Uint8Array) || data.length < FORMAT_PREFIX_LENGTH) {
108
146
  return false;
109
147
  }
110
148
  const prefix = formatDecoder.decode(data.subarray(0, FORMAT_PREFIX_LENGTH));
111
- return prefix === SerializationFormat.ENCRYPTED;
149
+ return (prefix === SerializationFormat.ENCRYPTED ||
150
+ prefix === SerializationFormat.SEALED);
151
+ }
152
+ /**
153
+ * Check if a binary value has the 'encp' format prefix, indicating a sealed
154
+ * (asymmetrically encrypted) cross-run payload.
155
+ *
156
+ * Browser-safe: does not depend on the full serialization module.
157
+ */
158
+ export function isSealedData(data) {
159
+ if (!(data instanceof Uint8Array) || data.length < FORMAT_PREFIX_LENGTH) {
160
+ return false;
161
+ }
162
+ const prefix = formatDecoder.decode(data.subarray(0, FORMAT_PREFIX_LENGTH));
163
+ return prefix === SerializationFormat.SEALED;
164
+ }
165
+ /**
166
+ * Check if a binary value has a compression format prefix ('gzip' or 'zstd').
167
+ * Browser-safe: does not depend on the full serialization module.
168
+ */
169
+ export function isCompressedData(data) {
170
+ if (!(data instanceof Uint8Array) || data.length < FORMAT_PREFIX_LENGTH) {
171
+ return false;
172
+ }
173
+ const prefix = formatDecoder.decode(data.subarray(0, FORMAT_PREFIX_LENGTH));
174
+ return (prefix === SerializationFormat.GZIP || prefix === SerializationFormat.ZSTD);
175
+ }
176
+ /**
177
+ * Resolve `node:zlib` via `process.getBuiltinModule`: no static Node
178
+ * dependency, invisible to browser bundlers. Returns undefined off Node.
179
+ */
180
+ function getNodeZlib() {
181
+ try {
182
+ return globalThis.process?.getBuiltinModule?.('node:zlib');
183
+ }
184
+ catch {
185
+ return undefined;
186
+ }
187
+ }
188
+ /**
189
+ * Synchronously decompress a `gzip`/`zstd` payload when running on Node.js.
190
+ *
191
+ * Returns `undefined` when sync decompression isn't available (e.g. in the
192
+ * browser, or zstd on Node < 22.15); callers fall back to leaving the data
193
+ * un-hydrated (the async `hydrateDataWithKey` path handles decompression in
194
+ * browsers via `DecompressionStream` / a registered zstd decoder).
195
+ */
196
+ function decompressSyncIfAvailable(format, payload) {
197
+ try {
198
+ const zlib = getNodeZlib();
199
+ if (format === SerializationFormat.GZIP && zlib?.gunzipSync) {
200
+ return new Uint8Array(zlib.gunzipSync(payload));
201
+ }
202
+ if (format === SerializationFormat.ZSTD && zlib?.zstdDecompressSync) {
203
+ return new Uint8Array(zlib.zstdDecompressSync(payload));
204
+ }
205
+ }
206
+ catch {
207
+ // Fall through: treat as unavailable
208
+ }
209
+ return undefined;
210
+ }
211
+ /**
212
+ * Browser zstd decoder, registered by the o11y host (web-shared) since the
213
+ * Web `DecompressionStream` has no zstd support. Node decodes via `node:zlib`
214
+ * and never needs this. See `registerZstdDecoder`.
215
+ */
216
+ // On `globalThis` (see `globalSingleton`): the o11y host registers the decoder
217
+ // once, and a per-copy slot would leave every other copy of this module without
218
+ // one.
219
+ const zstd = globalSingleton('@workflow/core//zstd.decoder', 1, () => ({
220
+ decoder: undefined,
221
+ }));
222
+ /**
223
+ * Register a browser zstd decoder (e.g. a WASM-backed one). The web o11y UI
224
+ * calls this at init so `hydrateDataWithKey` can inflate zstd payloads after
225
+ * client-side decryption. Node readers use `node:zlib` and ignore this.
226
+ */
227
+ export function registerZstdDecoder(decoder) {
228
+ zstd.decoder = decoder;
229
+ }
230
+ /**
231
+ * Asynchronously decompress a `gzip`/`zstd` payload.
232
+ * - gzip: web-standard `DecompressionStream` (Node 18+, browsers, edge).
233
+ * - zstd: `node:zlib` when on Node, else the registered browser decoder.
234
+ */
235
+ async function decompressAsync(format, payload) {
236
+ if (format === SerializationFormat.ZSTD) {
237
+ const sync = decompressSyncIfAvailable(format, payload);
238
+ if (sync)
239
+ return sync;
240
+ if (zstd.decoder)
241
+ return zstd.decoder(payload);
242
+ throw new Error('zstd-compressed workflow data encountered but no zstd decoder is ' +
243
+ 'available. Node.js 22.15+ decodes natively; in the browser register ' +
244
+ 'one via registerZstdDecoder (the web o11y package does this).');
245
+ }
246
+ const transform = new DecompressionStream('gzip');
247
+ const writer = transform.writable.getWriter();
248
+ const writePromise = writer.write(payload).then(() => writer.close());
249
+ writePromise.catch(() => { });
250
+ const chunks = [];
251
+ let total = 0;
252
+ const reader = transform.readable.getReader();
253
+ for (;;) {
254
+ const { done, value } = await reader.read();
255
+ if (done)
256
+ break;
257
+ chunks.push(value);
258
+ total += value.length;
259
+ }
260
+ await writePromise;
261
+ const out = new Uint8Array(total);
262
+ let offset = 0;
263
+ for (const chunk of chunks) {
264
+ out.set(chunk, offset);
265
+ offset += chunk.length;
266
+ }
267
+ return out;
112
268
  }
113
269
  // ---------------------------------------------------------------------------
114
270
  // Generic hydrate/dehydrate dispatch
@@ -124,13 +280,13 @@ export function isEncryptedData(data) {
124
280
  *
125
281
  * Encrypted data is intentionally left as a `Uint8Array` so that consumers
126
282
  * (CLI, web UI) can detect it with `isEncryptedData()` and decide how to
127
- * handle it the CLI replaces it with a styled placeholder, the web UI
283
+ * handle it: the CLI replaces it with a styled placeholder, the web UI
128
284
  * renders an "Encrypted" card with a Decrypt button that triggers
129
285
  * client-side decryption on demand.
130
286
  */
131
287
  export function hydrateData(value, revivers) {
132
288
  if (value instanceof Uint8Array) {
133
- // Encrypted data passes through untouched o11y layers detect it with
289
+ // Encrypted data passes through untouched: o11y layers detect it with
134
290
  // isEncryptedData() and handle display (web: named constructor object,
135
291
  // CLI: EncryptedDataRef with util.inspect.custom).
136
292
  if (isEncryptedData(value)) {
@@ -141,6 +297,20 @@ export function hydrateData(value, revivers) {
141
297
  const str = new TextDecoder().decode(payload);
142
298
  return parse(str, revivers);
143
299
  }
300
+ if (format === SerializationFormat.GZIP ||
301
+ format === SerializationFormat.ZSTD) {
302
+ // Compressed payload: decompress synchronously when running on
303
+ // Node.js (CLI, server o11y). In browsers there is no sync codec;
304
+ // pass the data through untouched (like encrypted data) so async
305
+ // consumers can route it through `hydrateDataWithKey`, which
306
+ // decompresses via DecompressionStream / a registered zstd decoder.
307
+ const inflated = decompressSyncIfAvailable(format, payload);
308
+ if (inflated === undefined) {
309
+ return value;
310
+ }
311
+ // The inflated bytes carry their own format prefix (e.g. 'devl')
312
+ return hydrateData(inflated, revivers);
313
+ }
144
314
  throw new Error(`Unsupported serialization format: ${format}`);
145
315
  }
146
316
  if (Array.isArray(value)) {
@@ -156,21 +326,39 @@ export function hydrateData(value, revivers) {
156
326
  * decryption. Used by o11y tooling (web UI, CLI) when the user requests
157
327
  * decryption.
158
328
  *
159
- * @param value - The value to hydrate (may be encrypted)
329
+ * @param value - The value to hydrate (may be encrypted or sealed)
160
330
  * @param revivers - Devalue revivers for deserialization
161
- * @param key - AES-256 encryption key (if provided, encrypted data will be decrypted)
331
+ * @param key - The run's key material. Pass `RunPayloadKeys` (from
332
+ * `deriveRunPayloadKeys`) to open both symmetric (`encr`) and sealed
333
+ * (`encp`) payloads; a bare `CryptoKey` opens only the symmetric ones.
334
+ * Typed as a read capability so a write-only seal target (which could open
335
+ * neither scheme) is rejected at compile time rather than failing here.
162
336
  */
163
337
  export async function hydrateDataWithKey(value, revivers, key) {
164
- if (value instanceof Uint8Array && isEncryptedData(value) && key) {
165
- // Decrypt: strip 'encr' prefix, AES-GCM decrypt, then hydrate the result
166
- const { decrypt } = await import('./encryption.js');
167
- const { payload } = decodeFormatPrefix(value);
168
- const decrypted = await decrypt(key, payload);
169
- // The decrypted bytes have their own format prefix (e.g., 'devl')
170
- return hydrateData(decrypted, revivers);
171
- }
172
- // No key or not encrypted delegate to sync hydrateData
173
- return hydrateData(value, revivers);
338
+ let data = value;
339
+ if (data instanceof Uint8Array && isEncryptedData(data) && key) {
340
+ // Envelope-aware decrypt: handles both `encr` (AES-GCM under the run's
341
+ // symmetric key) and `encp` (sealed to the run's X25519 public key by
342
+ // some other run), dispatching on the format prefix.
343
+ const { decrypt, isRunPayloadKeys } = await import('./serialization/encryption.js');
344
+ // Opening a sealed payload needs the run's private scalar. If the caller
345
+ // supplied only a symmetric key, leave the bytes as ciphertext so the UI
346
+ // keeps showing its "Encrypted" affordance, rather than surfacing a
347
+ // decryption error for something that was never openable with this key.
348
+ if (!isSealedData(data) || isRunPayloadKeys(key)) {
349
+ data = await decrypt(data, key);
350
+ }
351
+ }
352
+ if (data instanceof Uint8Array && isCompressedData(data)) {
353
+ // Decompress: strip the codec prefix and inflate. gzip uses the
354
+ // web-standard DecompressionStream (works in browsers); zstd uses
355
+ // node:zlib on Node or the registered WASM decoder in the browser.
356
+ // The inflated bytes carry their own format prefix (e.g. 'devl').
357
+ const { format, payload } = decodeFormatPrefix(data);
358
+ data = await decompressAsync(format, payload);
359
+ }
360
+ // Delegate the (decrypted/decompressed) result to sync hydrateData
361
+ return hydrateData(data, revivers);
174
362
  }
175
363
  // ---------------------------------------------------------------------------
176
364
  // Shared marker types for o11y display
@@ -198,7 +386,7 @@ export const CLASS_INSTANCE_REF_TYPE = '__workflow_class_instance_ref__';
198
386
  /**
199
387
  * A class instance reference for o11y display.
200
388
  *
201
- * Browser-safe base class no `util.inspect.custom`. Environment-specific
389
+ * Browser-safe base class: no `util.inspect.custom`. Environment-specific
202
390
  * rendering (CLI inspect, web component) is handled by each consumer.
203
391
  */
204
392
  export class ClassInstanceRef {
@@ -314,7 +502,7 @@ export const observabilityRevivers = {
314
502
  // throws on the `["DOMException", ...]` tag and `hydrateStepIO`'s
315
503
  // try/catch leaves the raw flat-encoded string in the UI. AbortController
316
504
  // synthesizes a DOMException as the default `signal.reason` when abort()
317
- // is called with no arg so any abort that round-trips through a step
505
+ // is called with no arg, so any abort that round-trips through a step
318
506
  // boundary surfaces here. Reconstruct as a real DOMException when the
319
507
  // global is available (modern browsers + Node 18+), else fall back to
320
508
  // an Error preserving name/message/stack/cause for display.
@@ -433,58 +621,11 @@ function hydrateEventData(resource, revivers) {
433
621
  if (!resource.eventData)
434
622
  return resource;
435
623
  const eventData = { ...resource.eventData };
436
- // step_completed events have eventData.result (serialized return value)
437
- if ('result' in eventData && eventData.result != null) {
438
- try {
439
- eventData.result = hydrateData(eventData.result, revivers);
440
- }
441
- catch {
442
- // Leave un-hydrated
443
- }
444
- }
445
- // step_created events have eventData.input (serialized step arguments)
446
- if ('input' in eventData && eventData.input != null) {
447
- try {
448
- eventData.input = hydrateData(eventData.input, revivers);
449
- }
450
- catch {
451
- // Leave un-hydrated
452
- }
453
- }
454
- // run_completed events have eventData.output (serialized return value)
455
- if ('output' in eventData && eventData.output != null) {
456
- try {
457
- eventData.output = hydrateData(eventData.output, revivers);
458
- }
459
- catch {
460
- // Leave un-hydrated
461
- }
462
- }
463
- // hook_created events may have serialized metadata
464
- if ('metadata' in eventData && eventData.metadata != null) {
465
- try {
466
- eventData.metadata = hydrateData(eventData.metadata, revivers);
467
- }
468
- catch {
469
- // Leave un-hydrated
470
- }
471
- }
472
- // hook_received events have eventData.payload (serialized hook payload)
473
- if ('payload' in eventData && eventData.payload != null) {
474
- try {
475
- eventData.payload = hydrateData(eventData.payload, revivers);
476
- }
477
- catch {
478
- // Leave un-hydrated
479
- }
480
- }
481
- // step_failed / step_retrying / run_failed events have eventData.error
482
- // (the thrown value, serialized via the error pipeline). Without this,
483
- // event listings in o11y tooling would surface the raw `Uint8Array`
484
- // payload instead of a hydrated `{ name, message, stack, … }` object.
485
- if ('error' in eventData && eventData.error != null) {
624
+ for (const field of getEventDataRefFields(resource.eventType ?? '')) {
625
+ if (eventData[field] == null)
626
+ continue;
486
627
  try {
487
- eventData.error = hydrateData(eventData.error, revivers);
628
+ eventData[field] = hydrateData(eventData[field], revivers);
488
629
  }
489
630
  catch {
490
631
  // Leave un-hydrated
@@ -513,7 +654,7 @@ function hydrateHookMetadata(resource, revivers) {
513
654
  * Dispatches by resource type (step, hook, event, workflow) and calls
514
655
  * `hydrateData` with the provided revivers for each data field.
515
656
  *
516
- * Each environment (web, CLI) provides its own revivers this function
657
+ * Each environment (web, CLI) provides its own revivers; this function
517
658
  * only handles the dispatch logic and field mapping.
518
659
  */
519
660
  export function hydrateResourceIO(resource, revivers) {
@@ -553,16 +694,27 @@ export function hydrateResourceIO(resource, revivers) {
553
694
  /** Extract all stream IDs from a value (recursively traverses objects/arrays) */
554
695
  export function extractStreamIds(obj) {
555
696
  const streamIds = [];
697
+ // The hydrated o11y data this walks comes from devalue, which supports
698
+ // circular and repeated references. Track visited containers so a cycle
699
+ // (e.g. a step result whose object refers back to itself) doesn't recurse
700
+ // forever and overflow the stack.
701
+ const seen = new WeakSet();
556
702
  function traverse(value) {
557
703
  if (isStreamId(value)) {
558
704
  streamIds.push(value);
559
705
  }
560
706
  else if (Array.isArray(value)) {
707
+ if (seen.has(value))
708
+ return;
709
+ seen.add(value);
561
710
  for (const item of value) {
562
711
  traverse(item);
563
712
  }
564
713
  }
565
714
  else if (value && typeof value === 'object') {
715
+ if (seen.has(value))
716
+ return;
717
+ seen.add(value);
566
718
  for (const val of Object.values(value)) {
567
719
  traverse(val);
568
720
  }
@@ -577,4 +729,4 @@ export function truncateId(id, maxLength = 12) {
577
729
  return id;
578
730
  return `${id.slice(0, maxLength)}...`;
579
731
  }
580
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VyaWFsaXphdGlvbi1mb3JtYXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2VyaWFsaXphdGlvbi1mb3JtYXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFM0MsOEVBQThFO0FBQzlFLGdEQUFnRDtBQUNoRCw4RUFBOEU7QUFFOUUsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUc7SUFDakMsMkRBQTJEO0lBQzNELFVBQVUsRUFBRSxNQUFNO0lBQ2xCLG1GQUFtRjtJQUNuRixTQUFTLEVBQUUsTUFBTTtDQUNULENBQUM7QUFLWCwyQ0FBMkM7QUFDM0MsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLENBQUM7QUFFL0IsTUFBTSxhQUFhLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQztBQUN4QyxNQUFNLGFBQWEsR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDO0FBRXhDOztHQUVHO0FBQ0gsTUFBTSxVQUFVLHNCQUFzQixDQUNwQyxNQUErQixFQUMvQixPQUE2QjtJQUU3QixJQUFJLENBQUMsQ0FBQyxPQUFPLFlBQVksVUFBVSxDQUFDLEVBQUUsQ0FBQztRQUNyQyxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQsTUFBTSxXQUFXLEdBQUcsYUFBYSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNqRCxJQUFJLFdBQVcsQ0FBQyxNQUFNLEtBQUssb0JBQW9CLEVBQUUsQ0FBQztRQUNoRCxNQUFNLElBQUksS0FBSyxDQUNiLHFDQUFxQyxvQkFBb0IsMkJBQTJCLE1BQU0sTUFBTSxXQUFXLENBQUMsTUFBTSxTQUFTLENBQzVILENBQUM7SUFDSixDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxVQUFVLENBQUMsb0JBQW9CLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3JFLE1BQU0sQ0FB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Q0FBQztRQUNsQyxDQUFDO2FBQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDaEMsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztnQkFDekIsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2pCLENBQUM7UUFDSCxDQUFDO2FBQU0sSUFBSSxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDOUMsS0FBSyxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNoQixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDZCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUN4QyxDQUFDO0FBRUQsdUVBQXVFO0FBQ3ZFLE1BQU0sVUFBVSxVQUFVLENBQUMsRUFBVSxFQUFFLFNBQVMsR0FBRyxFQUFFO0lBQ25ELElBQUksRUFBRSxDQUFDLE1BQU0sSUFBSSxTQUFTO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDdEMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUM7QUFDeEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQnJvd3Nlci1zYWZlIHNlcmlhbGl6YXRpb24gZm9ybWF0IHV0aWxpdGllcy5cbiAqXG4gKiBUaGlzIG1vZHVsZSBjb250YWlucyB0aGUgZm9ybWF0IHByZWZpeCBoYW5kbGluZywgZ2VuZXJpYyBoeWRyYXRlL2RlaHlkcmF0ZVxuICogZGlzcGF0Y2gsIGFuZCBzaGFyZWQgdHlwZXMvY2xhc3NlcyB1c2VkIGJ5IGFsbCBlbnZpcm9ubWVudHMgKHJ1bnRpbWUsIHdlYlxuICogbzExeSwgQ0xJIG8xMXkpLiBJdCBoYXMgTk8gTm9kZS5qcyBkZXBlbmRlbmNpZXMuXG4gKi9cblxuaW1wb3J0IHsgcGFyc2UsIHVuZmxhdHRlbiB9IGZyb20gJ2RldmFsdWUnO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEZvcm1hdCBwcmVmaXggY29uc3RhbnRzIGFuZCBlbmNvZGluZy9kZWNvZGluZ1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmV4cG9ydCBjb25zdCBTZXJpYWxpemF0aW9uRm9ybWF0ID0ge1xuICAvKiogZGV2YWx1ZSBzdHJpbmdpZnkvcGFyc2Ugd2l0aCBUZXh0RW5jb2Rlci9UZXh0RGVjb2RlciAqL1xuICBERVZBTFVFX1YxOiAnZGV2bCcsXG4gIC8qKiBFbmNyeXB0ZWQgcGF5bG9hZCAoaW5uZXIgcGF5bG9hZCBoYXMgaXRzIG93biBmb3JtYXQgcHJlZml4IGFmdGVyIGRlY3J5cHRpb24pICovXG4gIEVOQ1JZUFRFRDogJ2VuY3InLFxufSBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgU2VyaWFsaXphdGlvbkZvcm1hdFR5cGUgPVxuICAodHlwZW9mIFNlcmlhbGl6YXRpb25Gb3JtYXQpW2tleW9mIHR5cGVvZiBTZXJpYWxpemF0aW9uRm9ybWF0XTtcblxuLyoqIExlbmd0aCBvZiB0aGUgZm9ybWF0IHByZWZpeCBpbiBieXRlcyAqL1xuY29uc3QgRk9STUFUX1BSRUZJWF9MRU5HVEggPSA0O1xuXG5jb25zdCBmb3JtYXRFbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7XG5jb25zdCBmb3JtYXREZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKCk7XG5cbi8qKlxuICogRW5jb2RlIGEgcGF5bG9hZCB3aXRoIGEgZm9ybWF0IHByZWZpeC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuY29kZVdpdGhGb3JtYXRQcmVmaXgoXG4gIGZvcm1hdDogU2VyaWFsaXphdGlvbkZvcm1hdFR5cGUsXG4gIHBheWxvYWQ6IFVpbnQ4QXJyYXkgfCB1bmtub3duXG4pOiBVaW50OEFycmF5IHwgdW5rbm93biB7XG4gIGlmICghKHBheWxvYWQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSkge1xuICAgIHJldHVybiBwYXlsb2FkO1xuICB9XG5cbiAgY29uc3QgcHJlZml4Qnl0ZXMgPSBmb3JtYXRFbmNvZGVyLmVuY29kZShmb3JtYXQpO1xuICBpZiAocHJlZml4Qnl0ZXMubGVuZ3RoICE9PSBGT1JNQVRfUFJFRklYX0xFTkdUSCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBGb3JtYXQgaWRlbnRpZmllciBtdXN0IGJlIGV4YWN0bHkgJHtGT1JNQVRfUFJFRklYX0xFTkdUSH0gQVNDSUkgY2hhcmFjdGVycywgZ290IFwiJHtmb3JtYXR9XCIgKCR7cHJlZml4Qnl0ZXMubGVuZ3RofSBieXRlcylgXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IHJlc3VsdCA9IG5ldyBVaW50OEFycmF5KEZPUk1BVF9QUkVGSVhfTEVOR1RIICsgcGF5bG9hZC5sZW5ndGgpO1xuICByZXN1bHQuc2V0KHByZWZpeEJ5dGVzLCAwKTtcbiAgcmVzdWx0LnNldChwYXlsb2FkLCBGT1JNQVRfUFJFRklYX0xFTkdUSCk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogRGVjb2RlIGEgZm9ybWF0LXByZWZpeGVkIHBheWxvYWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGVGb3JtYXRQcmVmaXgoZGF0YTogVWludDhBcnJheSB8IHVua25vd24pOiB7XG4gIGZvcm1hdDogU2VyaWFsaXphdGlvbkZvcm1hdFR5cGU7XG4gIHBheWxvYWQ6IFVpbnQ4QXJyYXk7XG59IHtcbiAgaWYgKCEoZGF0YSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGZvcm1hdDogU2VyaWFsaXphdGlvbkZvcm1hdC5ERVZBTFVFX1YxLFxuICAgICAgcGF5bG9hZDogbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKEpTT04uc3RyaW5naWZ5KGRhdGEpKSxcbiAgICB9O1xuICB9XG5cbiAgaWYgKGRhdGEubGVuZ3RoIDwgRk9STUFUX1BSRUZJWF9MRU5HVEgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgRGF0YSB0b28gc2hvcnQgdG8gY29udGFpbiBmb3JtYXQgcHJlZml4OiBleHBlY3RlZCBhdCBsZWFzdCAke0ZPUk1BVF9QUkVGSVhfTEVOR1RIfSBieXRlcywgZ290ICR7ZGF0YS5sZW5ndGh9YFxuICAgICk7XG4gIH1cblxuICBjb25zdCBwcmVmaXhCeXRlcyA9IGRhdGEuc3ViYXJyYXkoMCwgRk9STUFUX1BSRUZJWF9MRU5HVEgpO1xuICBjb25zdCBmb3JtYXQgPSBmb3JtYXREZWNvZGVyLmRlY29kZShwcmVmaXhCeXRlcyk7XG5cbiAgY29uc3Qga25vd25Gb3JtYXRzID0gT2JqZWN0LnZhbHVlcyhTZXJpYWxpemF0aW9uRm9ybWF0KSBhcyBzdHJpbmdbXTtcbiAgaWYgKCFrbm93bkZvcm1hdHMuaW5jbHVkZXMoZm9ybWF0KSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBVbmtub3duIHNlcmlhbGl6YXRpb24gZm9ybWF0OiBcIiR7Zm9ybWF0fVwiLiBLbm93biBmb3JtYXRzOiAke2tub3duRm9ybWF0cy5qb2luKCcsICcpfWBcbiAgICApO1xuICB9XG5cbiAgY29uc3QgcGF5bG9hZCA9IGRhdGEuc3ViYXJyYXkoRk9STUFUX1BSRUZJWF9MRU5HVEgpO1xuICByZXR1cm4geyBmb3JtYXQ6IGZvcm1hdCBhcyBTZXJpYWxpemF0aW9uRm9ybWF0VHlwZSwgcGF5bG9hZCB9O1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEVuY3J5cHRlZCBkYXRhIGRldGVjdGlvblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKlxuICogUGxhY2Vob2xkZXIgc3RyaW5nIGRpc3BsYXllZCB3aGVuIGRhdGEgaXMgZW5jcnlwdGVkIGFuZCBkZWNyeXB0aW9uXG4gKiBoYXMgbm90IGJlZW4gcmVxdWVzdGVkLiBVc2VkIGJ5IGJvdGggQ0xJIGFuZCB3ZWIgbzExeS5cbiAqL1xuZXhwb3J0IGNvbnN0IEVOQ1JZUFRFRF9QTEFDRUhPTERFUiA9ICdcXHV7MUY1MTJ9IEVuY3J5cHRlZCc7XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gRXhwaXJlZCBkYXRhIGRldGVjdGlvblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKlxuICogQ2hlY2sgaWYgYSBwbGFpbiBvYmplY3QgaXMgYHsgZXhwaXJlZEF0OiBcIjxJU08gZGF0ZT5cIiB9YCDigJQgYSBzaW5nbGUta2V5XG4gKiBvYmplY3Qgd2l0aCBhIHN0cmluZyBgZXhwaXJlZEF0YCB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gaXNFeHBpcmVkT2JqZWN0KGRhdGE6IHVua25vd24pOiBkYXRhIGlzIHsgZXhwaXJlZEF0OiBzdHJpbmcgfSB7XG4gIGlmIChkYXRhID09PSBudWxsIHx8IHR5cGVvZiBkYXRhICE9PSAnb2JqZWN0JyB8fCBBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhkYXRhKTtcbiAgcmV0dXJuIChcbiAgICBrZXlzLmxlbmd0aCA9PT0gMSAmJlxuICAgIGtleXNbMF0gPT09ICdleHBpcmVkQXQnICYmXG4gICAgdHlwZW9mIChkYXRhIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5leHBpcmVkQXQgPT09ICdzdHJpbmcnXG4gICk7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYSBoeWRyYXRlZCB2YWx1ZSBpcyBhbiBleHBpcmVkIGRhdGEgc3R1YiBmcm9tIHRoZSBzZXJ2ZXIuXG4gKlxuICogVGhlIHNlcnZlciByZXBsYWNlcyBleHBpcmVkIHJlZiBmaWVsZHMgd2l0aCBhIGRldmFsdWUtZW5jb2RlZCBzdHViXG4gKiAoYG1ha2VFeHBpcmVkU3R1YmApIHRoYXQgZGVzZXJpYWxpemVzIHRvIGBbeyBleHBpcmVkQXQ6IFwiPElTTyBkYXRlPlwiIH1dYFxuICogYWZ0ZXIgYHVuZmxhdHRlbmAgKGFycmF5LXdyYXBwZWQgZHVlIHRvIGJhY2t3YXJkcy1jb21wYXRpYmxlIGVuY29kaW5nKS5cbiAqIEFsc28gbWF0Y2hlcyB0aGUgdW53cmFwcGVkIGB7IGV4cGlyZWRBdDogXCIuLi5cIiB9YCBmb3JtIGZvciByb2J1c3RuZXNzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFeHBpcmVkU3R1YihkYXRhOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIC8vIERpcmVjdCBvYmplY3QgZm9ybTogeyBleHBpcmVkQXQ6IFwiLi4uXCIgfVxuICBpZiAoaXNFeHBpcmVkT2JqZWN0KGRhdGEpKSByZXR1cm4gdHJ1ZTtcbiAgLy8gQXJyYXktd3JhcHBlZCBmb3JtIGZyb20gZGV2YWx1ZSB1bmZsYXR0ZW46IFt7IGV4cGlyZWRBdDogXCIuLi5cIiB9XVxuICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSAmJiBkYXRhLmxlbmd0aCA9PT0gMSAmJiBpc0V4cGlyZWRPYmplY3QoZGF0YVswXSkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYSBiaW5hcnkgdmFsdWUgaGFzIHRoZSAnZW5jcicgZm9ybWF0IHByZWZpeCBpbmRpY2F0aW5nIGVuY3J5cHRpb24uXG4gKiBCcm93c2VyLXNhZmUg4oCUIGRvZXMgbm90IGRlcGVuZCBvbiB0aGUgZnVsbCBzZXJpYWxpemF0aW9uIG1vZHVsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRW5jcnlwdGVkRGF0YShkYXRhOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIGlmICghKGRhdGEgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB8fCBkYXRhLmxlbmd0aCA8IEZPUk1BVF9QUkVGSVhfTEVOR1RIKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGNvbnN0IHByZWZpeCA9IGZvcm1hdERlY29kZXIuZGVjb2RlKGRhdGEuc3ViYXJyYXkoMCwgRk9STUFUX1BSRUZJWF9MRU5HVEgpKTtcbiAgcmV0dXJuIHByZWZpeCA9PT0gU2VyaWFsaXphdGlvbkZvcm1hdC5FTkNSWVBURUQ7XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUmV2aXZlcnMgdHlwZSAoc2hhcmVkIGFjcm9zcyBhbGwgZW52aXJvbm1lbnRzKVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKlxuICogQSBtYXAgb2YgdHlwZSBuYW1lIOKGkiByZXZpdmVyIGZ1bmN0aW9uLCB1c2VkIGJ5IGRldmFsdWUncyBgcGFyc2VgL2B1bmZsYXR0ZW5gLlxuICogRWFjaCBlbnZpcm9ubWVudCAocnVudGltZSwgd2ViLCBDTEkpIHByb3ZpZGVzIGl0cyBvd24gc2V0LlxuICovXG5leHBvcnQgdHlwZSBSZXZpdmVycyA9IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+O1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEdlbmVyaWMgaHlkcmF0ZS9kZWh5ZHJhdGUgZGlzcGF0Y2hcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vKipcbiAqIEh5ZHJhdGUgKGRlc2VyaWFsaXplKSBhIHZhbHVlIHRoYXQgd2FzIHN0b3JlZCBpbiB0aGUgZGF0YWJhc2UuXG4gKlxuICogSGFuZGxlcyBmb3VyIGRhdGEgc2hhcGVzOlxuICogMS4gYFVpbnQ4QXJyYXlgIHdpdGggJ2VuY3InIHByZWZpeCDihpIgcmV0dXJuZWQgYXMtaXMgKGVuY3J5cHRlZCwgbm90IHlldCBkZWNyeXB0ZWQpXG4gKiAyLiBgVWludDhBcnJheWAgd2l0aCBhIGZvcm1hdCBwcmVmaXggKHNwZWNWZXJzaW9uIDIrKSDihpIgZGVjb2RlIHByZWZpeCwgcGFyc2VcbiAqIDMuIGBBcnJheWAgKGxlZ2FjeSBzcGVjVmVyc2lvbiAxLCBcInJldml2ZWQgZGV2YWx1ZVwiKSDihpIgdW5mbGF0dGVuXG4gKiA0LiBPdGhlciAoYWxyZWFkeSBhIHBsYWluIEpTIHZhbHVlKSDihpIgcmV0dXJuIGFzLWlzXG4gKlxuICogRW5jcnlwdGVkIGRhdGEgaXMgaW50ZW50aW9uYWxseSBsZWZ0IGFzIGEgYFVpbnQ4QXJyYXlgIHNvIHRoYXQgY29uc3VtZXJzXG4gKiAoQ0xJLCB3ZWIgVUkpIGNhbiBkZXRlY3QgaXQgd2l0aCBgaXNFbmNyeXB0ZWREYXRhKClgIGFuZCBkZWNpZGUgaG93IHRvXG4gKiBoYW5kbGUgaXQg4oCUIHRoZSBDTEkgcmVwbGFjZXMgaXQgd2l0aCBhIHN0eWxlZCBwbGFjZWhvbGRlciwgdGhlIHdlYiBVSVxuICogcmVuZGVycyBhbiBcIkVuY3J5cHRlZFwiIGNhcmQgd2l0aCBhIERlY3J5cHQgYnV0dG9uIHRoYXQgdHJpZ2dlcnNcbiAqIGNsaWVudC1zaWRlIGRlY3J5cHRpb24gb24gZGVtYW5kLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaHlkcmF0ZURhdGEodmFsdWU6IHVua25vd24sIHJldml2ZXJzOiBSZXZpdmVycyk6IHVua25vd24ge1xuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgLy8gRW5jcnlwdGVkIGRhdGEgcGFzc2VzIHRocm91Z2ggdW50b3VjaGVkIOKAlCBvMTF5IGxheWVycyBkZXRlY3QgaXQgd2l0aFxuICAgIC8vIGlzRW5jcnlwdGVkRGF0YSgpIGFuZCBoYW5kbGUgZGlzcGxheSAod2ViOiBuYW1lZCBjb25zdHJ1Y3RvciBvYmplY3QsXG4gICAgLy8gQ0xJOiBFbmNyeXB0ZWREYXRhUmVmIHdpdGggdXRpbC5pbnNwZWN0LmN1c3RvbSkuXG4gICAgaWYgKGlzRW5jcnlwdGVkRGF0YSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGZvcm1hdCwgcGF5bG9hZCB9ID0gZGVjb2RlRm9ybWF0UHJlZml4KHZhbHVlKTtcbiAgICBpZiAoZm9ybWF0ID09PSBTZXJpYWxpemF0aW9uRm9ybWF0LkRFVkFMVUVfVjEpIHtcbiAgICAgIGNvbnN0IHN0ciA9IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShwYXlsb2FkKTtcbiAgICAgIHJldHVybiBwYXJzZShzdHIsIHJldml2ZXJzKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBzZXJpYWxpemF0aW9uIGZvcm1hdDogJHtmb3JtYXR9YCk7XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdW5mbGF0dGVuKHZhbHVlLCByZXZpdmVycyk7XG4gIH1cblxuICAvLyBBbHJlYWR5IGEgcGxhaW4gSlMgdmFsdWUgKGUuZy4sIG51bWJlciwgc3RyaW5nLCBudWxsKVxuICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogSHlkcmF0ZSBhIHZhbHVlLCBkZWNyeXB0aW5nIGl0IGZpcnN0IGlmIGFuIGVuY3J5cHRpb24ga2V5IGlzIHByb3ZpZGVkLlxuICpcbiAqIFRoaXMgaXMgdGhlIGFzeW5jIHZlcnNpb24gb2YgYGh5ZHJhdGVEYXRhYCB0aGF0IHN1cHBvcnRzIHRyYW5zcGFyZW50XG4gKiBkZWNyeXB0aW9uLiBVc2VkIGJ5IG8xMXkgdG9vbGluZyAod2ViIFVJLCBDTEkpIHdoZW4gdGhlIHVzZXIgcmVxdWVzdHNcbiAqIGRlY3J5cHRpb24uXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIGh5ZHJhdGUgKG1heSBiZSBlbmNyeXB0ZWQpXG4gKiBAcGFyYW0gcmV2aXZlcnMgLSBEZXZhbHVlIHJldml2ZXJzIGZvciBkZXNlcmlhbGl6YXRpb25cbiAqIEBwYXJhbSBrZXkgLSBBRVMtMjU2IGVuY3J5cHRpb24ga2V5IChpZiBwcm92aWRlZCwgZW5jcnlwdGVkIGRhdGEgd2lsbCBiZSBkZWNyeXB0ZWQpXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoeWRyYXRlRGF0YVdpdGhLZXkoXG4gIHZhbHVlOiB1bmtub3duLFxuICByZXZpdmVyczogUmV2aXZlcnMsXG4gIGtleTogaW1wb3J0KCcuL2VuY3J5cHRpb24uanMnKS5DcnlwdG9LZXkgfCB1bmRlZmluZWRcbik6IFByb21pc2U8dW5rbm93bj4ge1xuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBVaW50OEFycmF5ICYmIGlzRW5jcnlwdGVkRGF0YSh2YWx1ZSkgJiYga2V5KSB7XG4gICAgLy8gRGVjcnlwdDogc3RyaXAgJ2VuY3InIHByZWZpeCwgQUVTLUdDTSBkZWNyeXB0LCB0aGVuIGh5ZHJhdGUgdGhlIHJlc3VsdFxuICAgIGNvbnN0IHsgZGVjcnlwdCB9ID0gYXdhaXQgaW1wb3J0KCcuL2VuY3J5cHRpb24uanMnKTtcbiAgICBjb25zdCB7IHBheWxvYWQgfSA9IGRlY29kZUZvcm1hdFByZWZpeCh2YWx1ZSk7XG4gICAgY29uc3QgZGVjcnlwdGVkID0gYXdhaXQgZGVjcnlwdChrZXksIHBheWxvYWQpO1xuICAgIC8vIFRoZSBkZWNyeXB0ZWQgYnl0ZXMgaGF2ZSB0aGVpciBvd24gZm9ybWF0IHByZWZpeCAoZS5nLiwgJ2RldmwnKVxuICAgIHJldHVybiBoeWRyYXRlRGF0YShkZWNyeXB0ZWQsIHJldml2ZXJzKTtcbiAgfVxuICAvLyBObyBrZXkgb3Igbm90IGVuY3J5cHRlZCDigJQgZGVsZWdhdGUgdG8gc3luYyBoeWRyYXRlRGF0YVxuICByZXR1cm4gaHlkcmF0ZURhdGEodmFsdWUsIHJldml2ZXJzKTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBTaGFyZWQgbWFya2VyIHR5cGVzIGZvciBvMTF5IGRpc3BsYXlcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5jb25zdCBTVFJFQU1fSURfUFJFRklYID0gJ3N0cm1fJztcblxuLyoqIE1hcmtlciBmb3Igc3RyZWFtIHJlZmVyZW5jZSBvYmplY3RzIHJlbmRlcmVkIGFzIGxpbmtzIGluIHRoZSBVSSAqL1xuZXhwb3J0IGNvbnN0IFNUUkVBTV9SRUZfVFlQRSA9ICdfX3dvcmtmbG93X3N0cmVhbV9yZWZfXyc7XG5cbi8qKiBBIHN0cmVhbSByZWZlcmVuY2UgZm9yIFVJIGRpc3BsYXkgKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RyZWFtUmVmIHtcbiAgX190eXBlOiB0eXBlb2YgU1RSRUFNX1JFRl9UWVBFO1xuICBzdHJlYW1JZDogc3RyaW5nO1xufVxuXG4vKiogTWFya2VyIGZvciBSdW4gcmVmZXJlbmNlIG9iamVjdHMgcmVuZGVyZWQgYXMgbGlua3MgaW4gdGhlIFVJICovXG5leHBvcnQgY29uc3QgUlVOX1JFRl9UWVBFID0gJ19fd29ya2Zsb3dfcnVuX3JlZl9fJztcblxuLyoqIEEgUnVuIHJlZmVyZW5jZSBmb3IgVUkgZGlzcGxheSAqL1xuZXhwb3J0IGludGVyZmFjZSBSdW5SZWYge1xuICBfX3R5cGU6IHR5cGVvZiBSVU5fUkVGX1RZUEU7XG4gIHJ1bklkOiBzdHJpbmc7XG59XG5cbi8qKiBDaGVjayBpZiBhIHZhbHVlIGlzIGEgUnVuUmVmIG9iamVjdCAqL1xuZXhwb3J0IGNvbnN0IGlzUnVuUmVmID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgUnVuUmVmID0+IHtcbiAgcmV0dXJuIChcbiAgICB2YWx1ZSAhPT0gbnVsbCAmJlxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAnX190eXBlJyBpbiB2YWx1ZSAmJlxuICAgIHZhbHVlLl9fdHlwZSA9PT0gUlVOX1JFRl9UWVBFICYmXG4gICAgJ3J1bklkJyBpbiB2YWx1ZSAmJlxuICAgIHR5cGVvZiB2YWx1ZS5ydW5JZCA9PT0gJ3N0cmluZydcbiAgKTtcbn07XG5cbi8qKiBDb252ZXJ0IGEgc2VyaWFsaXplZCBSdW4gdmFsdWUgdG8gYSBSdW5SZWYgZm9yIGRpc3BsYXkgKi9cbmV4cG9ydCBjb25zdCBzZXJpYWxpemVkUnVuVG9SdW5SZWYgPSAodmFsdWU6IHsgcnVuSWQ6IHN0cmluZyB9KTogUnVuUmVmID0+IHtcbiAgcmV0dXJuIHsgX190eXBlOiBSVU5fUkVGX1RZUEUsIHJ1bklkOiB2YWx1ZS5ydW5JZCB9O1xufTtcblxuLyoqIE1hcmtlciBmb3IgY3VzdG9tIGNsYXNzIGluc3RhbmNlIHJlZmVyZW5jZXMgKi9cbmV4cG9ydCBjb25zdCBDTEFTU19JTlNUQU5DRV9SRUZfVFlQRSA9ICdfX3dvcmtmbG93X2NsYXNzX2luc3RhbmNlX3JlZl9fJztcblxuLyoqXG4gKiBBIGNsYXNzIGluc3RhbmNlIHJlZmVyZW5jZSBmb3IgbzExeSBkaXNwbGF5LlxuICpcbiAqIEJyb3dzZXItc2FmZSBiYXNlIGNsYXNzIOKAlCBubyBgdXRpbC5pbnNwZWN0LmN1c3RvbWAuIEVudmlyb25tZW50LXNwZWNpZmljXG4gKiByZW5kZXJpbmcgKENMSSBpbnNwZWN0LCB3ZWIgY29tcG9uZW50KSBpcyBoYW5kbGVkIGJ5IGVhY2ggY29uc3VtZXIuXG4gKi9cbmV4cG9ydCBjbGFzcyBDbGFzc0luc3RhbmNlUmVmIHtcbiAgcmVhZG9ubHkgX190eXBlID0gQ0xBU1NfSU5TVEFOQ0VfUkVGX1RZUEU7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWRvbmx5IGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHB1YmxpYyByZWFkb25seSBjbGFzc0lkOiBzdHJpbmcsXG4gICAgcHVibGljIHJlYWRvbmx5IGRhdGE6IHVua25vd25cbiAgKSB7fVxuXG4gIHRvSlNPTigpOiB7XG4gICAgX190eXBlOiBzdHJpbmc7XG4gICAgY2xhc3NOYW1lOiBzdHJpbmc7XG4gICAgY2xhc3NJZDogc3RyaW5nO1xuICAgIGRhdGE6IHVua25vd247XG4gIH0ge1xuICAgIHJldHVybiB7XG4gICAgICBfX3R5cGU6IHRoaXMuX190eXBlLFxuICAgICAgY2xhc3NOYW1lOiB0aGlzLmNsYXNzTmFtZSxcbiAgICAgIGNsYXNzSWQ6IHRoaXMuY2xhc3NJZCxcbiAgICAgIGRhdGE6IHRoaXMuZGF0YSxcbiAgICB9O1xuICB9XG59XG5cbi8qKiBDaGVjayBpZiBhIHZhbHVlIGlzIGEgQ2xhc3NJbnN0YW5jZVJlZiBvYmplY3QgKi9cbmV4cG9ydCBjb25zdCBpc0NsYXNzSW5zdGFuY2VSZWYgPSAoXG4gIHZhbHVlOiB1bmtub3duXG4pOiB2YWx1ZSBpcyBDbGFzc0luc3RhbmNlUmVmID0+IHtcbiAgcmV0dXJuIChcbiAgICB2YWx1ZSBpbnN0YW5jZW9mIENsYXNzSW5zdGFuY2VSZWYgfHxcbiAgICAodmFsdWUgIT09IG51bGwgJiZcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICdfX3R5cGUnIGluIHZhbHVlICYmXG4gICAgICB2YWx1ZS5fX3R5cGUgPT09IENMQVNTX0lOU1RBTkNFX1JFRl9UWVBFICYmXG4gICAgICAnY2xhc3NOYW1lJyBpbiB2YWx1ZSAmJlxuICAgICAgdHlwZW9mIHZhbHVlLmNsYXNzTmFtZSA9PT0gJ3N0cmluZycpXG4gICk7XG59O1xuXG4vKiogQ2hlY2sgaWYgYSB2YWx1ZSBpcyBhIHN0cmVhbSBJRCBzdHJpbmcgKi9cbmV4cG9ydCBjb25zdCBpc1N0cmVhbUlkID0gKHZhbHVlOiB1bmtub3duKTogYm9vbGVhbiA9PiB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHZhbHVlLnN0YXJ0c1dpdGgoU1RSRUFNX0lEX1BSRUZJWCk7XG59O1xuXG4vKiogQ2hlY2sgaWYgYSB2YWx1ZSBpcyBhIFN0cmVhbVJlZiBvYmplY3QgKi9cbmV4cG9ydCBjb25zdCBpc1N0cmVhbVJlZiA9ICh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFN0cmVhbVJlZiA9PiB7XG4gIHJldHVybiAoXG4gICAgdmFsdWUgIT09IG51bGwgJiZcbiAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgJ19fdHlwZScgaW4gdmFsdWUgJiZcbiAgICB2YWx1ZS5fX3R5cGUgPT09IFNUUkVBTV9SRUZfVFlQRSAmJlxuICAgICdzdHJlYW1JZCcgaW4gdmFsdWUgJiZcbiAgICB0eXBlb2YgdmFsdWUuc3RyZWFtSWQgPT09ICdzdHJpbmcnXG4gICk7XG59O1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFNoYXJlZCBvMTF5IHJldml2ZXIgaGVscGVyc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKlxuICogQ29udmVydCBhIHNlcmlhbGl6ZWQgc3RyZWFtIHZhbHVlIHRvIGEgU3RyZWFtUmVmIGZvciBkaXNwbGF5LlxuICovXG5leHBvcnQgY29uc3Qgc3RyZWFtVG9TdHJlYW1SZWYgPSAodmFsdWU6IGFueSk6IFN0cmVhbVJlZiA9PiB7XG4gIGxldCBzdHJlYW1JZDogc3RyaW5nO1xuICBpZiAoJ25hbWUnIGluIHZhbHVlKSB7XG4gICAgY29uc3QgbmFtZSA9IFN0cmluZyh2YWx1ZS5uYW1lKTtcbiAgICBpZiAoIW5hbWUuc3RhcnRzV2l0aChTVFJFQU1fSURfUFJFRklYKSkge1xuICAgICAgc3RyZWFtSWQgPSBgJHtTVFJFQU1fSURfUFJFRklYfSR7bmFtZX1gO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHJlYW1JZCA9IG5hbWU7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHN0cmVhbUlkID0gYCR7U1RSRUFNX0lEX1BSRUZJWH1udWxsYDtcbiAgfVxuICByZXR1cm4geyBfX3R5cGU6IFNUUkVBTV9SRUZfVFlQRSwgc3RyZWFtSWQgfTtcbn07XG5cbi8qKiBDb252ZXJ0IGEgc2VyaWFsaXplZCBzdGVwIGZ1bmN0aW9uIHRvIGEgZGlzcGxheSBzdHJpbmcgKi9cbmV4cG9ydCBjb25zdCBzZXJpYWxpemVkU3RlcEZ1bmN0aW9uVG9TdHJpbmcgPSAodmFsdWU6IHVua25vd24pOiBzdHJpbmcgPT4ge1xuICBpZiAoIXZhbHVlKSByZXR1cm4gJ251bGwnO1xuICBpZiAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JykgcmV0dXJuICdudWxsJztcbiAgaWYgKCdzdGVwSWQnIGluIHZhbHVlKSB7XG4gICAgcmV0dXJuIGA8c3RlcDokeyh2YWx1ZSBhcyB7IHN0ZXBJZDogc3RyaW5nIH0pLnN0ZXBJZH0+YDtcbiAgfVxuICByZXR1cm4gJzxmdW5jdGlvbj4nO1xufTtcblxuLyoqIEV4dHJhY3QgdGhlIGNsYXNzIG5hbWUgZnJvbSBhIGNsYXNzSWQgKi9cbmV4cG9ydCBjb25zdCBleHRyYWN0Q2xhc3NOYW1lID0gKGNsYXNzSWQ6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIGlmICghY2xhc3NJZCkgcmV0dXJuICdVbmtub3duJztcbiAgY29uc3QgcGFydHMgPSBjbGFzc0lkLnNwbGl0KCcvJyk7XG4gIHJldHVybiBwYXJ0c1twYXJ0cy5sZW5ndGggLSAxXSB8fCBjbGFzc0lkO1xufTtcblxuLyoqIENvbnZlcnQgYSBzZXJpYWxpemVkIGNsYXNzIGluc3RhbmNlIHRvIGEgQ2xhc3NJbnN0YW5jZVJlZiBmb3IgZGlzcGxheS5cbiAqICBSdW4gaW5zdGFuY2VzIGFyZSBzcGVjaWFsLWNhc2VkIHRvIGEgUnVuUmVmIGZvciBjbGlja2FibGUgcmVuZGVyaW5nLiAqL1xuZXhwb3J0IGNvbnN0IHNlcmlhbGl6ZWRJbnN0YW5jZVRvUmVmID0gKHZhbHVlOiB7XG4gIGNsYXNzSWQ6IHN0cmluZztcbiAgZGF0YTogdW5rbm93bjtcbn0pOiBDbGFzc0luc3RhbmNlUmVmIHwgUnVuUmVmID0+IHtcbiAgY29uc3QgY2xhc3NOYW1lID0gZXh0cmFjdENsYXNzTmFtZSh2YWx1ZS5jbGFzc0lkKTtcbiAgaWYgKFxuICAgIGNsYXNzTmFtZSA9PT0gJ1J1bicgJiZcbiAgICB2YWx1ZS5kYXRhICE9PSBudWxsICYmXG4gICAgdHlwZW9mIHZhbHVlLmRhdGEgPT09ICdvYmplY3QnICYmXG4gICAgJ3J1bklkJyBpbiB2YWx1ZS5kYXRhICYmXG4gICAgdHlwZW9mICh2YWx1ZS5kYXRhIGFzIHsgcnVuSWQ6IHVua25vd24gfSkucnVuSWQgPT09ICdzdHJpbmcnXG4gICkge1xuICAgIHJldHVybiBzZXJpYWxpemVkUnVuVG9SdW5SZWYodmFsdWUuZGF0YSBhcyB7IHJ1bklkOiBzdHJpbmcgfSk7XG4gIH1cbiAgcmV0dXJuIG5ldyBDbGFzc0luc3RhbmNlUmVmKGNsYXNzTmFtZSwgdmFsdWUuY2xhc3NJZCwgdmFsdWUuZGF0YSk7XG59O1xuXG4vKiogQ29udmVydCBhIHNlcmlhbGl6ZWQgY2xhc3MgcmVmZXJlbmNlIHRvIGEgZGlzcGxheSBzdHJpbmcgKi9cbmV4cG9ydCBjb25zdCBzZXJpYWxpemVkQ2xhc3NUb1N0cmluZyA9ICh2YWx1ZTogeyBjbGFzc0lkOiBzdHJpbmcgfSk6IHN0cmluZyA9PiB7XG4gIHJldHVybiBgPGNsYXNzOiR7ZXh0cmFjdENsYXNzTmFtZSh2YWx1ZS5jbGFzc0lkKX0+YDtcbn07XG5cbi8qKlxuICogU3RhbmRhcmQgbzExeSByZXZpdmVycyB0aGF0IG92ZXJyaWRlIHJ1bnRpbWUtc3BlY2lmaWMgdHlwZXMgd2l0aFxuICogZGlzcGxheS1mcmllbmRseSB2YWx1ZXMuIFVzZWQgYnkgYm90aCB3ZWIgYW5kIENMSSBoeWRyYXRpb24uXG4gKi9cbmV4cG9ydCBjb25zdCBvYnNlcnZhYmlsaXR5UmV2aXZlcnM6IFJldml2ZXJzID0ge1xuICBSZWFkYWJsZVN0cmVhbTogc3RyZWFtVG9TdHJlYW1SZWYsXG4gIFdyaXRhYmxlU3RyZWFtOiBzdHJlYW1Ub1N0cmVhbVJlZixcbiAgVHJhbnNmb3JtU3RyZWFtOiBzdHJlYW1Ub1N0cmVhbVJlZixcbiAgQWJvcnRDb250cm9sbGVyOiAodmFsdWU6IGFueSkgPT5cbiAgICBgPEFib3J0Q29udHJvbGxlcihhYm9ydGVkOiAke3ZhbHVlLmFib3J0ZWR9KT5gLFxuICBBYm9ydFNpZ25hbDogKHZhbHVlOiBhbnkpID0+IGA8QWJvcnRTaWduYWwoYWJvcnRlZDogJHt2YWx1ZS5hYm9ydGVkfSk+YCxcbiAgLy8gRE9NRXhjZXB0aW9uIG5lZWRzIGFuIGV4cGxpY2l0IHJldml2ZXI6IHdpdGhvdXQgb25lLCBkZXZhbHVlLnBhcnNlXG4gIC8vIHRocm93cyBvbiB0aGUgYFtcIkRPTUV4Y2VwdGlvblwiLCAuLi5dYCB0YWcgYW5kIGBoeWRyYXRlU3RlcElPYCdzXG4gIC8vIHRyeS9jYXRjaCBsZWF2ZXMgdGhlIHJhdyBmbGF0LWVuY29kZWQgc3RyaW5nIGluIHRoZSBVSS4gQWJvcnRDb250cm9sbGVyXG4gIC8vIHN5bnRoZXNpemVzIGEgRE9NRXhjZXB0aW9uIGFzIHRoZSBkZWZhdWx0IGBzaWduYWwucmVhc29uYCB3aGVuIGFib3J0KClcbiAgLy8gaXMgY2FsbGVkIHdpdGggbm8gYXJnIOKAlCBzbyBhbnkgYWJvcnQgdGhhdCByb3VuZC10cmlwcyB0aHJvdWdoIGEgc3RlcFxuICAvLyBib3VuZGFyeSBzdXJmYWNlcyBoZXJlLiBSZWNvbnN0cnVjdCBhcyBhIHJlYWwgRE9NRXhjZXB0aW9uIHdoZW4gdGhlXG4gIC8vIGdsb2JhbCBpcyBhdmFpbGFibGUgKG1vZGVybiBicm93c2VycyArIE5vZGUgMTgrKSwgZWxzZSBmYWxsIGJhY2sgdG9cbiAgLy8gYW4gRXJyb3IgcHJlc2VydmluZyBuYW1lL21lc3NhZ2Uvc3RhY2svY2F1c2UgZm9yIGRpc3BsYXkuXG4gIERPTUV4Y2VwdGlvbjogKHZhbHVlOiB7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICAgIG5hbWU6IHN0cmluZztcbiAgICBzdGFjaz86IHN0cmluZztcbiAgICBjYXVzZT86IHVua25vd247XG4gIH0pID0+IHtcbiAgICBjb25zdCBHID0gZ2xvYmFsVGhpcyBhcyB7IERPTUV4Y2VwdGlvbj86IHR5cGVvZiBET01FeGNlcHRpb24gfTtcbiAgICBpZiAodHlwZW9mIEcuRE9NRXhjZXB0aW9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjb25zdCBlID0gbmV3IEcuRE9NRXhjZXB0aW9uKHZhbHVlLm1lc3NhZ2UsIHZhbHVlLm5hbWUpO1xuICAgICAgaWYgKHZhbHVlLnN0YWNrICE9PSB1bmRlZmluZWQpIGUuc3RhY2sgPSB2YWx1ZS5zdGFjaztcbiAgICAgIGlmICgnY2F1c2UnIGluIHZhbHVlKSAoZSBhcyB7IGNhdXNlPzogdW5rbm93biB9KS5jYXVzZSA9IHZhbHVlLmNhdXNlO1xuICAgICAgcmV0dXJuIGU7XG4gICAgfVxuICAgIGNvbnN0IGU6IEVycm9yICYgeyBjYXVzZT86IHVua25vd24gfSA9IG5ldyBFcnJvcih2YWx1ZS5tZXNzYWdlKTtcbiAgICBlLm5hbWUgPSB2YWx1ZS5uYW1lO1xuICAgIGlmICh2YWx1ZS5zdGFjayAhPT0gdW5kZWZpbmVkKSBlLnN0YWNrID0gdmFsdWUuc3RhY2s7XG4gICAgaWYgKCdjYXVzZScgaW4gdmFsdWUpIGUuY2F1c2UgPSB2YWx1ZS5jYXVzZTtcbiAgICByZXR1cm4gZTtcbiAgfSxcbiAgU3RlcEZ1bmN0aW9uOiBzZXJpYWxpemVkU3RlcEZ1bmN0aW9uVG9TdHJpbmcsXG4gIFdvcmtmbG93RnVuY3Rpb246ICh2YWx1ZTogeyB3b3JrZmxvd0lkOiBzdHJpbmcgfSkgPT5cbiAgICBgPHdvcmtmbG93OiR7dmFsdWUud29ya2Zsb3dJZH0+YCxcbiAgSW5zdGFuY2U6IHNlcmlhbGl6ZWRJbnN0YW5jZVRvUmVmLFxuICBDbGFzczogc2VyaWFsaXplZENsYXNzVG9TdHJpbmcsXG59O1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJlc291cmNlLWxldmVsIGh5ZHJhdGlvbiBkaXNwYXRjaCAoZm9yIG8xMXkpXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLyoqXG4gKiBIeWRyYXRlIHRoZSBkYXRhIGZpZWxkcyBvZiBhIHN0ZXAgcmVzb3VyY2UuXG4gKi9cbmZ1bmN0aW9uIGh5ZHJhdGVTdGVwSU88XG4gIFQgZXh0ZW5kcyB7IHN0ZXBJZD86IHN0cmluZzsgaW5wdXQ/OiBhbnk7IG91dHB1dD86IGFueTsgZXJyb3I/OiBhbnkgfSxcbj4ocmVzb3VyY2U6IFQsIHJldml2ZXJzOiBSZXZpdmVycyk6IFQge1xuICBsZXQgaHlkcmF0ZWRJbnB1dCA9IHJlc291cmNlLmlucHV0O1xuICBsZXQgaHlkcmF0ZWRPdXRwdXQgPSByZXNvdXJjZS5vdXRwdXQ7XG4gIGxldCBoeWRyYXRlZEVycm9yID0gcmVzb3VyY2UuZXJyb3I7XG5cbiAgaWYgKHJlc291cmNlLmlucHV0ICE9IG51bGwpIHtcbiAgICB0cnkge1xuICAgICAgaHlkcmF0ZWRJbnB1dCA9IGh5ZHJhdGVEYXRhKHJlc291cmNlLmlucHV0LCByZXZpdmVycyk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBMZWF2ZSB1bi1oeWRyYXRlZFxuICAgIH1cbiAgfVxuXG4gIGlmIChyZXNvdXJjZS5vdXRwdXQgIT0gbnVsbCkge1xuICAgIHRyeSB7XG4gICAgICBoeWRyYXRlZE91dHB1dCA9IGh5ZHJhdGVEYXRhKHJlc291cmNlLm91dHB1dCwgcmV2aXZlcnMpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gTGVhdmUgdW4taHlkcmF0ZWRcbiAgICB9XG4gIH1cblxuICAvLyBUaGUgYGVycm9yYCBmaWVsZCBpcyBgU2VyaWFsaXplZERhdGFgIChVaW50OEFycmF5KSBwcm9kdWNlZCBieVxuICAvLyBgZGVoeWRyYXRlU3RlcEVycm9yYC4gSHlkcmF0ZSBpdCBzbyBvYnNlcnZhYmlsaXR5IHRvb2xzIChDTEksIHdlYiBVSSlcbiAgLy8gY2FuIHJlYWQgYHN0ZXAuZXJyb3IubWVzc2FnZWAsIGBzdGVwLmVycm9yLnN0YWNrYCwgZXRjLlxuICBpZiAocmVzb3VyY2UuZXJyb3IgIT0gbnVsbCkge1xuICAgIHRyeSB7XG4gICAgICBoeWRyYXRlZEVycm9yID0gaHlkcmF0ZURhdGEocmVzb3VyY2UuZXJyb3IsIHJldml2ZXJzKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIExlYXZlIHVuLWh5ZHJhdGVkXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5yZXNvdXJjZSxcbiAgICBpbnB1dDogaHlkcmF0ZWRJbnB1dCxcbiAgICBvdXRwdXQ6IGh5ZHJhdGVkT3V0cHV0LFxuICAgIGVycm9yOiBoeWRyYXRlZEVycm9yLFxuICB9O1xufVxuXG4vKipcbiAqIEh5ZHJhdGUgdGhlIGRhdGEgZmllbGRzIG9mIGEgd29ya2Zsb3cgcnVuIHJlc291cmNlLlxuICovXG5mdW5jdGlvbiBoeWRyYXRlV29ya2Zsb3dJTzxcbiAgVCBleHRlbmRzIHsgaW5wdXQ/OiBhbnk7IG91dHB1dD86IGFueTsgZXJyb3I/OiBhbnkgfSxcbj4ocmVzb3VyY2U6IFQsIHJldml2ZXJzOiBSZXZpdmVycyk6IFQge1xuICBsZXQgaHlkcmF0ZWRJbnB1dCA9IHJlc291cmNlLmlucHV0O1xuICBsZXQgaHlkcmF0ZWRPdXRwdXQgPSByZXNvdXJjZS5vdXRwdXQ7XG4gIGxldCBoeWRyYXRlZEVycm9yID0gcmVzb3VyY2UuZXJyb3I7XG5cbiAgaWYgKHJlc291cmNlLmlucHV0ICE9IG51bGwpIHtcbiAgICB0cnkge1xuICAgICAgaHlkcmF0ZWRJbnB1dCA9IGh5ZHJhdGVEYXRhKHJlc291cmNlLmlucHV0LCByZXZpdmVycyk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBMZWF2ZSB1bi1oeWRyYXRlZFxuICAgIH1cbiAgfVxuXG4gIGlmIChyZXNvdXJjZS5vdXRwdXQgIT0gbnVsbCkge1xuICAgIHRyeSB7XG4gICAgICBoeWRyYXRlZE91dHB1dCA9IGh5ZHJhdGVEYXRhKHJlc291cmNlLm91dHB1dCwgcmV2aXZlcnMpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gTGVhdmUgdW4taHlkcmF0ZWRcbiAgICB9XG4gIH1cblxuICAvLyBUaGUgYGVycm9yYCBmaWVsZCBpcyBgU2VyaWFsaXplZERhdGFgIChVaW50OEFycmF5KSBwcm9kdWNlZCBieVxuICAvLyBgZGVoeWRyYXRlUnVuRXJyb3JgLiBIeWRyYXRlIGl0IHNvIG9ic2VydmFiaWxpdHkgdG9vbHMgKENMSSwgd2ViIFVJKVxuICAvLyBjYW4gcmVhZCBgcnVuLmVycm9yLm1lc3NhZ2VgLCBgcnVuLmVycm9yLnN0YWNrYCwgZXRjLlxuICBpZiAocmVzb3VyY2UuZXJyb3IgIT0gbnVsbCkge1xuICAgIHRyeSB7XG4gICAgICBoeWRyYXRlZEVycm9yID0gaHlkcmF0ZURhdGEocmVzb3VyY2UuZXJyb3IsIHJldml2ZXJzKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIExlYXZlIHVuLWh5ZHJhdGVkXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5yZXNvdXJjZSxcbiAgICBpbnB1dDogaHlkcmF0ZWRJbnB1dCxcbiAgICBvdXRwdXQ6IGh5ZHJhdGVkT3V0cHV0LFxuICAgIGVycm9yOiBoeWRyYXRlZEVycm9yLFxuICB9O1xufVxuXG4vKipcbiAqIEh5ZHJhdGUgdGhlIGV2ZW50RGF0YSBmaWVsZHMgb2YgYW4gZXZlbnQgcmVzb3VyY2UuXG4gKi9cbmZ1bmN0aW9uIGh5ZHJhdGVFdmVudERhdGE8VCBleHRlbmRzIHsgZXZlbnRJZD86IHN0cmluZzsgZXZlbnREYXRhPzogYW55IH0+KFxuICByZXNvdXJjZTogVCxcbiAgcmV2aXZlcnM6IFJldml2ZXJzXG4pOiBUIHtcbiAgaWYgKCFyZXNvdXJjZS5ldmVudERhdGEpIHJldHVybiByZXNvdXJjZTtcblxuICBjb25zdCBldmVudERhdGEgPSB7IC4uLnJlc291cmNlLmV2ZW50RGF0YSB9O1xuXG4gIC8vIHN0ZXBfY29tcGxldGVkIGV2ZW50cyBoYXZlIGV2ZW50RGF0YS5yZXN1bHQgKHNlcmlhbGl6ZWQgcmV0dXJuIHZhbHVlKVxuICBpZiAoJ3Jlc3VsdCcgaW4gZXZlbnREYXRhICYmIGV2ZW50RGF0YS5yZXN1bHQgIT0gbnVsbCkge1xuICAgIHRyeSB7XG4gICAgICBldmVudERhdGEucmVzdWx0ID0gaHlkcmF0ZURhdGEoZXZlbnREYXRhLnJlc3VsdCwgcmV2aXZlcnMpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gTGVhdmUgdW4taHlkcmF0ZWRcbiAgICB9XG4gIH1cblxuICAvLyBzdGVwX2NyZWF0ZWQgZXZlbnRzIGhhdmUgZXZlbnREYXRhLmlucHV0IChzZXJpYWxpemVkIHN0ZXAgYXJndW1lbnRzKVxuICBpZiAoJ2lucHV0JyBpbiBldmVudERhdGEgJiYgZXZlbnREYXRhLmlucHV0ICE9IG51bGwpIHtcbiAgICB0cnkge1xuICAgICAgZXZlbnREYXRhLmlucHV0ID0gaHlkcmF0ZURhdGEoZXZlbnREYXRhLmlucHV0LCByZXZpdmVycyk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBMZWF2ZSB1bi1oeWRyYXRlZFxuICAgIH1cbiAgfVxuXG4gIC8vIHJ1bl9jb21wbGV0ZWQgZXZlbnRzIGhhdmUgZXZlbnREYXRhLm91dHB1dCAoc2VyaWFsaXplZCByZXR1cm4gdmFsdWUpXG4gIGlmICgnb3V0cHV0JyBpbiBldmVudERhdGEgJiYgZXZlbnREYXRhLm91dHB1dCAhPSBudWxsKSB7XG4gICAgdHJ5IHtcbiAgICAgIGV2ZW50RGF0YS5vdXRwdXQgPSBoeWRyYXRlRGF0YShldmVudERhdGEub3V0cHV0LCByZXZpdmVycyk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBMZWF2ZSB1bi1oeWRyYXRlZFxuICAgIH1cbiAgfVxuXG4gIC8vIGhvb2tfY3JlYXRlZCBldmVudHMgbWF5IGhhdmUgc2VyaWFsaXplZCBtZXRhZGF0YVxuICBpZiAoJ21ldGFkYXRhJyBpbiBldmVudERhdGEgJiYgZXZlbnREYXRhLm1ldGFkYXRhICE9IG51bGwpIHtcbiAgICB0cnkge1xuICAgICAgZXZlbnREYXRhLm1ldGFkYXRhID0gaHlkcmF0ZURhdGEoZXZlbnREYXRhLm1ldGFkYXRhLCByZXZpdmVycyk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBMZWF2ZSB1bi1oeWRyYXRlZFxuICAgIH1cbiAgfVxuXG4gIC8vIGhvb2tfcmVjZWl2ZWQgZXZlbnRzIGhhdmUgZXZlbnREYXRhLnBheWxvYWQgKHNlcmlhbGl6ZWQgaG9vayBwYXlsb2FkKVxuICBpZiAoJ3BheWxvYWQnIGluIGV2ZW50RGF0YSAmJiBldmVudERhdGEucGF5bG9hZCAhPSBudWxsKSB7XG4gICAgdHJ5IHtcbiAgICAgIGV2ZW50RGF0YS5wYXlsb2FkID0gaHlkcmF0ZURhdGEoZXZlbnREYXRhLnBheWxvYWQsIHJldml2ZXJzKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIExlYXZlIHVuLWh5ZHJhdGVkXG4gICAgfVxuICB9XG5cbiAgLy8gc3RlcF9mYWlsZWQgLyBzdGVwX3JldHJ5aW5nIC8gcnVuX2ZhaWxlZCBldmVudHMgaGF2ZSBldmVudERhdGEuZXJyb3JcbiAgLy8gKHRoZSB0aHJvd24gdmFsdWUsIHNlcmlhbGl6ZWQgdmlhIHRoZSBlcnJvciBwaXBlbGluZSkuIFdpdGhvdXQgdGhpcyxcbiAgLy8gZXZlbnQgbGlzdGluZ3MgaW4gbzExeSB0b29saW5nIHdvdWxkIHN1cmZhY2UgdGhlIHJhdyBgVWludDhBcnJheWBcbiAgLy8gcGF5bG9hZCBpbnN0ZWFkIG9mIGEgaHlkcmF0ZWQgYHsgbmFtZSwgbWVzc2FnZSwgc3RhY2ssIOKApiB9YCBvYmplY3QuXG4gIGlmICgnZXJyb3InIGluIGV2ZW50RGF0YSAmJiBldmVudERhdGEuZXJyb3IgIT0gbnVsbCkge1xuICAgIHRyeSB7XG4gICAgICBldmVudERhdGEuZXJyb3IgPSBoeWRyYXRlRGF0YShldmVudERhdGEuZXJyb3IsIHJldml2ZXJzKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIExlYXZlIHVuLWh5ZHJhdGVkXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgLi4ucmVzb3VyY2UsIGV2ZW50RGF0YSB9O1xufVxuXG4vKipcbiAqIEh5ZHJhdGUgdGhlIG1ldGFkYXRhIGZpZWxkIG9mIGEgaG9vayByZXNvdXJjZS5cbiAqL1xuZnVuY3Rpb24gaHlkcmF0ZUhvb2tNZXRhZGF0YTxUIGV4dGVuZHMgeyBob29rSWQ/OiBzdHJpbmc7IG1ldGFkYXRhPzogYW55IH0+KFxuICByZXNvdXJjZTogVCxcbiAgcmV2aXZlcnM6IFJldml2ZXJzXG4pOiBUIHtcbiAgaWYgKHJlc291cmNlLm1ldGFkYXRhID09IG51bGwpIHJldHVybiByZXNvdXJjZTtcblxuICBsZXQgaHlkcmF0ZWRNZXRhZGF0YSA9IHJlc291cmNlLm1ldGFkYXRhO1xuICB0cnkge1xuICAgIGh5ZHJhdGVkTWV0YWRhdGEgPSBoeWRyYXRlRGF0YShyZXNvdXJjZS5tZXRhZGF0YSwgcmV2aXZlcnMpO1xuICB9IGNhdGNoIHtcbiAgICAvLyBMZWF2ZSB1bi1oeWRyYXRlZFxuICB9XG5cbiAgcmV0dXJuIHsgLi4ucmVzb3VyY2UsIG1ldGFkYXRhOiBoeWRyYXRlZE1ldGFkYXRhIH07XG59XG5cbi8qKlxuICogSHlkcmF0ZSB0aGUgc2VyaWFsaXplZCBkYXRhIGZpZWxkcyBvZiBhbnkgcmVzb3VyY2UgZm9yIG8xMXkgZGlzcGxheS5cbiAqXG4gKiBEaXNwYXRjaGVzIGJ5IHJlc291cmNlIHR5cGUgKHN0ZXAsIGhvb2ssIGV2ZW50LCB3b3JrZmxvdykgYW5kIGNhbGxzXG4gKiBgaHlkcmF0ZURhdGFgIHdpdGggdGhlIHByb3ZpZGVkIHJldml2ZXJzIGZvciBlYWNoIGRhdGEgZmllbGQuXG4gKlxuICogRWFjaCBlbnZpcm9ubWVudCAod2ViLCBDTEkpIHByb3ZpZGVzIGl0cyBvd24gcmV2aXZlcnMg4oCUIHRoaXMgZnVuY3Rpb25cbiAqIG9ubHkgaGFuZGxlcyB0aGUgZGlzcGF0Y2ggbG9naWMgYW5kIGZpZWxkIG1hcHBpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoeWRyYXRlUmVzb3VyY2VJTzxcbiAgVCBleHRlbmRzIHtcbiAgICBzdGVwSWQ/OiBzdHJpbmc7XG4gICAgaG9va0lkPzogc3RyaW5nO1xuICAgIGV2ZW50SWQ/OiBzdHJpbmc7XG4gICAgaW5wdXQ/OiBhbnk7XG4gICAgb3V0cHV0PzogYW55O1xuICAgIG1ldGFkYXRhPzogYW55O1xuICAgIGV2ZW50RGF0YT86IGFueTtcbiAgICBleGVjdXRpb25Db250ZXh0PzogYW55O1xuICB9LFxuPihyZXNvdXJjZTogVCwgcmV2aXZlcnM6IFJldml2ZXJzKTogVCB7XG4gIGlmICghcmVzb3VyY2UpIHJldHVybiByZXNvdXJjZTtcblxuICBsZXQgaHlkcmF0ZWQ6IFQ7XG4gIGlmICgnc3RlcElkJyBpbiByZXNvdXJjZSkge1xuICAgIGh5ZHJhdGVkID0gaHlkcmF0ZVN0ZXBJTyhyZXNvdXJjZSwgcmV2aXZlcnMpO1xuICB9IGVsc2UgaWYgKCdob29rSWQnIGluIHJlc291cmNlKSB7XG4gICAgaHlkcmF0ZWQgPSBoeWRyYXRlSG9va01ldGFkYXRhKHJlc291cmNlLCByZXZpdmVycyk7XG4gIH0gZWxzZSBpZiAoJ2V2ZW50SWQnIGluIHJlc291cmNlKSB7XG4gICAgaHlkcmF0ZWQgPSBoeWRyYXRlRXZlbnREYXRhKHJlc291cmNlLCByZXZpdmVycyk7XG4gIH0gZWxzZSB7XG4gICAgaHlkcmF0ZWQgPSBoeWRyYXRlV29ya2Zsb3dJTyhyZXNvdXJjZSwgcmV2aXZlcnMpO1xuICB9XG5cbiAgLy8gU3RyaXAgZXhlY3V0aW9uQ29udGV4dCwgcHJlc2VydmluZyBvbmx5IHdvcmtmbG93Q29yZVZlcnNpb24gZm9yIGRpc3BsYXlcbiAgaWYgKCdleGVjdXRpb25Db250ZXh0JyBpbiBoeWRyYXRlZCkge1xuICAgIGNvbnN0IHsgZXhlY3V0aW9uQ29udGV4dCwgLi4ucmVzdCB9ID0gaHlkcmF0ZWQ7XG4gICAgY29uc3Qgd29ya2Zsb3dDb3JlVmVyc2lvbiA9XG4gICAgICBleGVjdXRpb25Db250ZXh0ICYmXG4gICAgICB0eXBlb2YgZXhlY3V0aW9uQ29udGV4dCA9PT0gJ29iamVjdCcgJiZcbiAgICAgICd3b3JrZmxvd0NvcmVWZXJzaW9uJyBpbiBleGVjdXRpb25Db250ZXh0XG4gICAgICAgID8gZXhlY3V0aW9uQ29udGV4dC53b3JrZmxvd0NvcmVWZXJzaW9uXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgIGlmICh3b3JrZmxvd0NvcmVWZXJzaW9uKSB7XG4gICAgICByZXR1cm4geyAuLi5yZXN0LCB3b3JrZmxvd0NvcmVWZXJzaW9uIH0gYXMgdW5rbm93biBhcyBUO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdCBhcyBUO1xuICB9XG5cbiAgcmV0dXJuIGh5ZHJhdGVkO1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFV0aWxpdHkgZnVuY3Rpb25zXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLyoqIEV4dHJhY3QgYWxsIHN0cmVhbSBJRHMgZnJvbSBhIHZhbHVlIChyZWN1cnNpdmVseSB0cmF2ZXJzZXMgb2JqZWN0cy9hcnJheXMpICovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdFN0cmVhbUlkcyhvYmo6IHVua25vd24pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHN0cmVhbUlkczogc3RyaW5nW10gPSBbXTtcblxuICBmdW5jdGlvbiB0cmF2ZXJzZSh2YWx1ZTogdW5rbm93bik6IHZvaWQge1xuICAgIGlmIChpc1N0cmVhbUlkKHZhbHVlKSkge1xuICAgICAgc3RyZWFtSWRzLnB1c2godmFsdWUgYXMgc3RyaW5nKTtcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgdmFsdWUpIHtcbiAgICAgICAgdHJhdmVyc2UoaXRlbSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICBmb3IgKGNvbnN0IHZhbCBvZiBPYmplY3QudmFsdWVzKHZhbHVlKSkge1xuICAgICAgICB0cmF2ZXJzZSh2YWwpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHRyYXZlcnNlKG9iaik7XG4gIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQoc3RyZWFtSWRzKSk7XG59XG5cbi8qKiBUcnVuY2F0ZSBhIHN0cmluZyB0byBhIG1heGltdW0gbGVuZ3RoLCBhZGRpbmcgZWxsaXBzaXMgaWYgbmVlZGVkICovXG5leHBvcnQgZnVuY3Rpb24gdHJ1bmNhdGVJZChpZDogc3RyaW5nLCBtYXhMZW5ndGggPSAxMik6IHN0cmluZyB7XG4gIGlmIChpZC5sZW5ndGggPD0gbWF4TGVuZ3RoKSByZXR1cm4gaWQ7XG4gIHJldHVybiBgJHtpZC5zbGljZSgwLCBtYXhMZW5ndGgpfS4uLmA7XG59XG4iXX0=
732
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VyaWFsaXphdGlvbi1mb3JtYXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2VyaWFsaXphdGlvbi1mb3JtYXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBRTNDLDhFQUE4RTtBQUM5RSx5Q0FBeUM7QUFDekMsOEVBQThFO0FBRTlFOzs7Ozs7OztHQVFHO0FBQ0gsT0FBTyxFQUVMLE9BQU8sSUFBSSxlQUFlLEVBQzFCLG9CQUFvQixFQUNwQixPQUFPLElBQUksZUFBZSxFQUMxQixnQkFBZ0IsRUFDaEIsWUFBWSxFQUdaLGNBQWMsRUFFZCxNQUFNLEdBQ1AsTUFBTSwrQkFBK0IsQ0FBQztBQUV2Qyw4RUFBOEU7QUFDOUUsZ0RBQWdEO0FBQ2hELDhFQUE4RTtBQUU5RSxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRztJQUNqQywyREFBMkQ7SUFDM0QsVUFBVSxFQUFFLE1BQU07SUFDbEIsbUZBQW1GO0lBQ25GLFNBQVMsRUFBRSxNQUFNO0lBQ2pCOzs7Ozs7Ozs7T0FTRztJQUNILE1BQU0sRUFBRSxNQUFNO0lBQ2QsNEZBQTRGO0lBQzVGLElBQUksRUFBRSxNQUFNO0lBQ1osaUdBQWlHO0lBQ2pHLElBQUksRUFBRSxNQUFNO0NBQ0osQ0FBQztBQUtYLDJDQUEyQztBQUMzQyxNQUFNLG9CQUFvQixHQUFHLENBQUMsQ0FBQztBQUUvQixNQUFNLGFBQWEsR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDO0FBQ3hDLE1BQU0sYUFBYSxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7QUFFeEM7O0dBRUc7QUFDSCxNQUFNLFVBQVUsc0JBQXNCLENBQ3BDLE1BQStCLEVB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QVM7UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUN0QyxPQUFPLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQztBQUN4QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCcm93c2VyLXNhZmUgc2VyaWFsaXphdGlvbiBmb3JtYXQgdXRpbGl0aWVzLlxuICpcbiAqIFRoaXMgbW9kdWxlIGNvbnRhaW5zIHRoZSBmb3JtYXQgcHJlZml4IGhhbmRsaW5nLCBnZW5lcmljIGh5ZHJhdGUvZGVoeWRyYXRlXG4gKiBkaXNwYXRjaCwgYW5kIHNoYXJlZCB0eXBlcy9jbGFzc2VzIHVzZWQgYnkgYWxsIGVudmlyb25tZW50cyAocnVudGltZSwgd2ViXG4gKiBvMTF5LCBDTEkgbzExeSkuIEl0IGhhcyBOTyBOb2RlLmpzIGRlcGVuZGVuY2llcy5cbiAqL1xuXG5pbXBvcnQgeyBnbG9iYWxTaW5nbGV0b24gfSBmcm9tICdAd29ya2Zsb3cvdXRpbHMnO1xuaW1wb3J0IHsgZ2V0RXZlbnREYXRhUmVmRmllbGRzIH0gZnJvbSAnQHdvcmtmbG93L3dvcmxkL2V2ZW50LW1ldGFkYXRhJztcbmltcG9ydCB7IHBhcnNlLCB1bmZsYXR0ZW4gfSBmcm9tICdkZXZhbHVlJztcblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBLZXkgbWF0ZXJpYWwgKGJyb3dzZXItc2FmZSByZS1leHBvcnRzKVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKlxuICogUmUtZXhwb3J0ZWQgZnJvbSB0aGUgZW52ZWxvcGUgbGF5ZXIgc28gYnJvd3NlciBjb25zdW1lcnMgKHdlYiBkYXNoYm9hcmQsXG4gKiB3ZWItc2hhcmVkKSBjYW4gcmVzb2x2ZSBrZXkgbWF0ZXJpYWwgd2l0aG91dCBpbXBvcnRpbmdcbiAqIGBAd29ya2Zsb3cvY29yZS9zZXJpYWxpemF0aW9uYCwgd2hvc2UgbW9kdWxlIGdyYXBoIHJlYWNoZXMgTm9kZSBidWlsdC1pbnNcbiAqIChgbm9kZTp1dGlsYCwgYG5vZGU6YXN5bmNfaG9va3NgKSBhbmQgY2Fubm90IGJlIGJ1bmRsZWQgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEV2ZXJ5dGhpbmcgYmVsb3cgaXMgV2ViIENyeXB0byBvbmx5OiBgc2VyaWFsaXphdGlvbi9lbmNyeXB0aW9uLnRzYCxcbiAqIGBlbmNyeXB0aW9uLnRzYCBhbmQgYHNlYWxlZC1ib3gudHNgIGFyZSBhbGwgZnJlZSBvZiBOb2RlIGRlcGVuZGVuY2llcy5cbiAqL1xuZXhwb3J0IHtcbiAgdHlwZSBEZWNyeXB0aW9uS2V5LFxuICBkZWNyeXB0IGFzIGRlY3J5cHRFbnZlbG9wZSxcbiAgZGVyaXZlUnVuUGF5bG9hZEtleXMsXG4gIGVuY3J5cHQgYXMgZW5jcnlwdEVudmVsb3BlLFxuICBpc1J1blBheWxvYWRLZXlzLFxuICBpc1NlYWxUYXJnZXQsXG4gIHR5cGUgUGF5bG9hZEtleSxcbiAgdHlwZSBSdW5QYXlsb2FkS2V5cyxcbiAgcnVuUGF5bG9hZEtleXMsXG4gIHR5cGUgU2VhbFRhcmdldCxcbiAgc2VhbFRvLFxufSBmcm9tICcuL3NlcmlhbGl6YXRpb24vZW5jcnlwdGlvbi5qcyc7XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gRm9ybWF0IHByZWZpeCBjb25zdGFudHMgYW5kIGVuY29kaW5nL2RlY29kaW5nXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuZXhwb3J0IGNvbnN0IFNlcmlhbGl6YXRpb25Gb3JtYXQgPSB7XG4gIC8qKiBkZXZhbHVlIHN0cmluZ2lmeS9wYXJzZSB3aXRoIFRleHRFbmNvZGVyL1RleHREZWNvZGVyICovXG4gIERFVkFMVUVfVjE6ICdkZXZsJyxcbiAgLyoqIEVuY3J5cHRlZCBwYXlsb2FkIChpbm5lciBwYXlsb2FkIGhhcyBpdHMgb3duIGZvcm1hdCBwcmVmaXggYWZ0ZXIgZGVjcnlwdGlvbikgKi9cbiAgRU5DUllQVEVEOiAnZW5jcicsXG4gIC8qKlxuICAgKiBTZWFsZWQgcGF5bG9hZDogYXN5bW1ldHJpY2FsbHkgZW5jcnlwdGVkIHRvIGEgcnVuJ3MgWDI1NTE5IHB1YmxpYyBrZXlcbiAgICogKGlubmVyIHBheWxvYWQgaGFzIGl0cyBvd24gZm9ybWF0IHByZWZpeCBhZnRlciBvcGVuaW5nKS5cbiAgICpcbiAgICogV3JpdHRlbiBieSBjcm9zcy1ydW4gd3JpdGVycyB0aGF0IGhvbGQgb25seSB0aGUgcmVjaXBpZW50IHJ1bidzIHB1YmxpY1xuICAgKiBrZXkuIE9wZW5pbmcgaXQgcmVxdWlyZXMgdGhlIHJ1bidzIHByaXZhdGUgc2NhbGFyIHJhdGhlciB0aGFuIHRoZVxuICAgKiBzeW1tZXRyaWMgcGVyLXJ1biBrZXksIHNvIG8xMXkgZGlzcGxheSB0cmVhdHMgaXQgYXMgY2lwaGVydGV4dCB2aWFcbiAgICoge0BsaW5rIGlzRW5jcnlwdGVkRGF0YX0gYnV0IHtAbGluayBoeWRyYXRlRGF0YVdpdGhLZXl9IGRvZXMgbm90IGF0dGVtcHRcbiAgICogYW4gQUVTLUdDTSBkZWNyeXB0IG9uIGl0LlxuICAgKi9cbiAgU0VBTEVEOiAnZW5jcCcsXG4gIC8qKiBHemlwLWNvbXByZXNzZWQgcGF5bG9hZCAoaW5uZXIgcGF5bG9hZCBoYXMgaXRzIG93biBmb3JtYXQgcHJlZml4IGFmdGVyIGRlY29tcHJlc3Npb24pICovXG4gIEdaSVA6ICdnemlwJyxcbiAgLyoqIFpzdGFuZGFyZC1jb21wcmVzc2VkIHBheWxvYWQgKGlubmVyIHBheWxvYWQgaGFzIGl0cyBvd24gZm9ybWF0IHByZWZpeCBhZnRlciBkZWNvbXByZXNzaW9uKSAqL1xuICBaU1REOiAnenN0ZCcsXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgdHlwZSBTZXJpYWxpemF0aW9uRm9ybWF0VHlwZSA9XG4gICh0eXBlb2YgU2VyaWFsaXphdGlvbkZvcm1hdClba2V5b2YgdHlwZW9mIFNlcmlhbGl6YXRpb25Gb3JtYXRdO1xuXG4vKiogTGVuZ3RoIG9mIHRoZSBmb3JtYXQgcHJlZml4IGluIGJ5dGVzICovXG5jb25zdCBGT1JNQVRfUFJFRklYX0xFTkdUSCA9IDQ7XG5cbmNvbnN0IGZvcm1hdEVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcbmNvbnN0IGZvcm1hdERlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKTtcblxuLyoqXG4gKiBFbmNvZGUgYSBwYXlsb2FkIHdpdGggYSBmb3JtYXQgcHJlZml4LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlV2l0aEZvcm1hdFByZWZpeChcbiAgZm9ybWF0OiBTZXJpYWxpemF0aW9uRm9ybWF0VHlwZSxcbiAgcGF5bG9hZDogVWludDhBcnJheSB8IHVua25vd25cbik6IFVpbnQ4QXJyYXkgfCB1bmtub3duIHtcbiAgaWYgKCEocGF5bG9hZCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKSB7XG4gICAgcmV0dXJuIHBheWxvYWQ7XG4gIH1cblxuICBjb25zdCBwcmVmaXhCeXRlcyA9IGZvcm1hdEVuY29kZXIuZW5jb2RlKGZvcm1hdCk7XG4gIGlmIChwcmVmaXhCeXRlcy5sZW5ndGggIT09IEZPUk1BVF9QUkVGSVhfTEVOR1RIKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYEZvcm1hdCBpZGVudGlmaWVyIG11c3QgYmUgZXhhY3RseSAke0ZPUk1BVF9QUkVGSVhfTEVOR1RIfSBBU0NJSSBjaGFyYWN0ZXJzLCBnb3QgXCIke2Zvcm1hdH1cIiAoJHtwcmVmaXhCeXRlcy5sZW5ndGh9IGJ5dGVzKWBcbiAgICApO1xuICB9XG5cbiAgY29uc3QgcmVzdWx0ID0gbmV3IFVpbnQ4QXJyYXkoRk9STUFUX1BSRUZJWF9MRU5HVEggKyBwYXlsb2FkLmxlbmd0aCk7XG4gIHJlc3VsdC5zZXQocHJlZml4Qnl0ZXMsIDApO1xuICByZXN1bHQuc2V0KHBheWxvYWQsIEZPUk1BVF9QUkVGSVhfTEVOR1RIKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBEZWNvZGUgYSBmb3JtYXQtcHJlZml4ZWQgcGF5bG9hZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZUZvcm1hdFByZWZpeChkYXRhOiBVaW50OEFycmF5IHwgdW5rbm93bik6IHtcbiAgZm9ybWF0OiBTZXJpYWxpemF0aW9uRm9ybWF0VHlwZTtcbiAgcGF5bG9hZDogVWludDhBcnJheTtcbn0ge1xuICBpZiAoIShkYXRhIGluc3RhbmNlb2YgVWludDhBcnJheSkpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZm9ybWF0OiBTZXJpYWxpemF0aW9uRm9ybWF0LkRFVkFMVUVfVjEsXG4gICAgICBwYXlsb2FkOiBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoSlNPTi5zdHJpbmdpZnkoZGF0YSkpLFxuICAgIH07XG4gIH1cblxuICBpZiAoZGF0YS5sZW5ndGggPCBGT1JNQVRfUFJFRklYX0xFTkdUSCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBEYXRhIHRvbyBzaG9ydCB0byBjb250YWluIGZvcm1hdCBwcmVmaXg6IGV4cGVjdGVkIGF0IGxlYXN0ICR7Rk9STUFUX1BSRUZJWF9MRU5HVEh9IGJ5dGVzLCBnb3QgJHtkYXRhLmxlbmd0aH1gXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IHByZWZpeEJ5dGVzID0gZGF0YS5zdWJhcnJheSgwLCBGT1JNQVRfUFJFRklYX0xFTkdUSCk7XG4gIGNvbnN0IGZvcm1hdCA9IGZvcm1hdERlY29kZXIuZGVjb2RlKHByZWZpeEJ5dGVzKTtcblxuICBjb25zdCBrbm93bkZvcm1hdHMgPSBPYmplY3QudmFsdWVzKFNlcmlhbGl6YXRpb25Gb3JtYXQpIGFzIHN0cmluZ1tdO1xuICBpZiAoIWtub3duRm9ybWF0cy5pbmNsdWRlcyhmb3JtYXQpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFVua25vd24gc2VyaWFsaXphdGlvbiBmb3JtYXQ6IFwiJHtmb3JtYXR9XCIuIEtub3duIGZvcm1hdHM6ICR7a25vd25Gb3JtYXRzLmpvaW4oJywgJyl9YFxuICAgICk7XG4gIH1cblxuICBjb25zdCBwYXlsb2FkID0gZGF0YS5zdWJhcnJheShGT1JNQVRfUFJFRklYX0xFTkdUSCk7XG4gIHJldHVybiB7IGZvcm1hdDogZm9ybWF0IGFzIFNlcmlhbGl6YXRpb25Gb3JtYXRUeXBlLCBwYXlsb2FkIH07XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gRW5jcnlwdGVkIGRhdGEgZGV0ZWN0aW9uXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLyoqXG4gKiBQbGFjZWhvbGRlciBzdHJpbmcgZGlzcGxheWVkIHdoZW4gZGF0YSBpcyBlbmNyeXB0ZWQgYW5kIGRlY3J5cHRpb25cbiAqIGhhcyBub3QgYmVlbiByZXF1ZXN0ZWQuIFVzZWQgYnkgYm90aCBDTEkgYW5kIHdlYiBvMTF5LlxuICovXG5leHBvcnQgY29uc3QgRU5DUllQVEVEX1BMQUNFSE9MREVSID0gJ1xcdXsxRjUxMn0gRW5jcnlwdGVkJztcblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBFeHBpcmVkIGRhdGEgZGV0ZWN0aW9uXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLyoqXG4gKiBDaGVjayBpZiBhIHBsYWluIG9iamVjdCBpcyBgeyBleHBpcmVkQXQ6IFwiPElTTyBkYXRlPlwiIH1gOiBhIHNpbmdsZS1rZXlcbiAqIG9iamVjdCB3aXRoIGEgc3RyaW5nIGBleHBpcmVkQXRgIHZhbHVlLlxuICovXG5mdW5jdGlvbiBpc0V4cGlyZWRPYmplY3QoZGF0YTogdW5rbm93bik6IGRhdGEgaXMgeyBleHBpcmVkQXQ6IHN0cmluZyB9IHtcbiAgaWYgKGRhdGEgPT09IG51bGwgfHwgdHlwZW9mIGRhdGEgIT09ICdvYmplY3QnIHx8IEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGRhdGEpO1xuICByZXR1cm4gKFxuICAgIGtleXMubGVuZ3RoID09PSAxICYmXG4gICAga2V5c1swXSA9PT0gJ2V4cGlyZWRBdCcgJiZcbiAgICB0eXBlb2YgKGRhdGEgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLmV4cGlyZWRBdCA9PT0gJ3N0cmluZydcbiAgKTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhIGh5ZHJhdGVkIHZhbHVlIGlzIGFuIGV4cGlyZWQgZGF0YSBzdHViIGZyb20gdGhlIHNlcnZlci5cbiAqXG4gKiBUaGUgc2VydmVyIHJlcGxhY2VzIGV4cGlyZWQgcmVmIGZpZWxkcyB3aXRoIGEgZGV2YWx1ZS1lbmNvZGVkIHN0dWJcbiAqIChgbWFrZUV4cGlyZWRTdHViYCkgdGhhdCBkZXNlcmlhbGl6ZXMgdG8gYFt7IGV4cGlyZWRBdDogXCI8SVNPIGRhdGU+XCIgfV1gXG4gKiBhZnRlciBgdW5mbGF0dGVuYCAoYXJyYXktd3JhcHBlZCBkdWUgdG8gYmFja3dhcmRzLWNvbXBhdGlibGUgZW5jb2RpbmcpLlxuICogQWxzbyBtYXRjaGVzIHRoZSB1bndyYXBwZWQgYHsgZXhwaXJlZEF0OiBcIi4uLlwiIH1gIGZvcm0gZm9yIHJvYnVzdG5lc3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0V4cGlyZWRTdHViKGRhdGE6IHVua25vd24pOiBib29sZWFuIHtcbiAgLy8gRGlyZWN0IG9iamVjdCBmb3JtOiB7IGV4cGlyZWRBdDogXCIuLi5cIiB9XG4gIGlmIChpc0V4cGlyZWRPYmplY3QoZGF0YSkpIHJldHVybiB0cnVlO1xuICAvLyBBcnJheS13cmFwcGVkIGZvcm0gZnJvbSBkZXZhbHVlIHVuZmxhdHRlbjogW3sgZXhwaXJlZEF0OiBcIi4uLlwiIH1dXG4gIGlmIChBcnJheS5pc0FycmF5KGRhdGEpICYmIGRhdGEubGVuZ3RoID09PSAxICYmIGlzRXhwaXJlZE9iamVjdChkYXRhWzBdKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhIGJpbmFyeSB2YWx1ZSBpcyBjaXBoZXJ0ZXh0OiBlaXRoZXIgYSBzeW1tZXRyaWNhbGx5IGVuY3J5cHRlZFxuICogcGF5bG9hZCAoJ2VuY3InKSBvciBhIHNlYWxlZCBjcm9zcy1ydW4gcGF5bG9hZCAoJ2VuY3AnKS5cbiAqXG4gKiBUaGlzIGlzIHRoZSBwcmVkaWNhdGUgZGlzcGxheSBsYXllcnMgd2FudDogYm90aCBzY2hlbWVzIGFyZSBvcGFxdWUgYnl0ZXNcbiAqIHRoYXQgbXVzdCBub3QgYmUgZmVkIHRvIHRoZSBkZXZhbHVlIHBhcnNlciwgYW5kIGJvdGggcmVuZGVyIGFzIHRoZSBzYW1lXG4gKiBcIkVuY3J5cHRlZFwiIGFmZm9yZGFuY2UgaW4gdGhlIENMSSBhbmQgd2ViIFVJLiBVc2Uge0BsaW5rIGlzU2VhbGVkRGF0YX0gd2hlblxuICogdGhlICpzY2hlbWUqIG1hdHRlcnMsIG5vdGFibHkgd2hlbiBjaG9vc2luZyBhIGRlY3J5cHRpb24gcGF0aCwgc2luY2UgYVxuICogc2VhbGVkIHBheWxvYWQgbmVlZHMgdGhlIHJ1bidzIHByaXZhdGUgc2NhbGFyIHJhdGhlciB0aGFuIGl0cyBzeW1tZXRyaWMga2V5LlxuICpcbiAqIEJyb3dzZXItc2FmZTogZG9lcyBub3QgZGVwZW5kIG9uIHRoZSBmdWxsIHNlcmlhbGl6YXRpb24gbW9kdWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFbmNyeXB0ZWREYXRhKGRhdGE6IHVua25vd24pOiBib29sZWFuIHtcbiAgaWYgKCEoZGF0YSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHx8IGRhdGEubGVuZ3RoIDwgRk9STUFUX1BSRUZJWF9MRU5HVEgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3QgcHJlZml4ID0gZm9ybWF0RGVjb2Rlci5kZWNvZGUoZGF0YS5zdWJhcnJheSgwLCBGT1JNQVRfUFJFRklYX0xFTkdUSCkpO1xuICByZXR1cm4gKFxuICAgIHByZWZpeCA9PT0gU2VyaWFsaXphdGlvbkZvcm1hdC5FTkNSWVBURUQgfHxcbiAgICBwcmVmaXggPT09IFNlcmlhbGl6YXRpb25Gb3JtYXQuU0VBTEVEXG4gICk7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYSBiaW5hcnkgdmFsdWUgaGFzIHRoZSAnZW5jcCcgZm9ybWF0IHByZWZpeCwgaW5kaWNhdGluZyBhIHNlYWxlZFxuICogKGFzeW1tZXRyaWNhbGx5IGVuY3J5cHRlZCkgY3Jvc3MtcnVuIHBheWxvYWQuXG4gKlxuICogQnJvd3Nlci1zYWZlOiBkb2VzIG5vdCBkZXBlbmQgb24gdGhlIGZ1bGwgc2VyaWFsaXphdGlvbiBtb2R1bGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1NlYWxlZERhdGEoZGF0YTogdW5rbm93bik6IGJvb2xlYW4ge1xuICBpZiAoIShkYXRhIGluc3RhbmNlb2YgVWludDhBcnJheSkgfHwgZGF0YS5sZW5ndGggPCBGT1JNQVRfUFJFRklYX0xFTkdUSCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBjb25zdCBwcmVmaXggPSBmb3JtYXREZWNvZGVyLmRlY29kZShkYXRhLnN1YmFycmF5KDAsIEZPUk1BVF9QUkVGSVhfTEVOR1RIKSk7XG4gIHJldHVybiBwcmVmaXggPT09IFNlcmlhbGl6YXRpb25Gb3JtYXQuU0VBTEVEO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGEgYmluYXJ5IHZhbHVlIGhhcyBhIGNvbXByZXNzaW9uIGZvcm1hdCBwcmVmaXggKCdnemlwJyBvciAnenN0ZCcpLlxuICogQnJvd3Nlci1zYWZlOiBkb2VzIG5vdCBkZXBlbmQgb24gdGhlIGZ1bGwgc2VyaWFsaXphdGlvbiBtb2R1bGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbXByZXNzZWREYXRhKGRhdGE6IHVua25vd24pOiBib29sZWFuIHtcbiAgaWYgKCEoZGF0YSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHx8IGRhdGEubGVuZ3RoIDwgRk9STUFUX1BSRUZJWF9MRU5HVEgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3QgcHJlZml4ID0gZm9ybWF0RGVjb2Rlci5kZWNvZGUoZGF0YS5zdWJhcnJheSgwLCBGT1JNQVRfUFJFRklYX0xFTkdUSCkpO1xuICByZXR1cm4gKFxuICAgIHByZWZpeCA9PT0gU2VyaWFsaXphdGlvbkZvcm1hdC5HWklQIHx8IHByZWZpeCA9PT0gU2VyaWFsaXphdGlvbkZvcm1hdC5aU1REXG4gICk7XG59XG5cbmludGVyZmFjZSBOb2RlWmxpYkRlY29kZSB7XG4gIGd1bnppcFN5bmM/OiAoZGF0YTogVWludDhBcnJheSkgPT4gVWludDhBcnJheTtcbiAgenN0ZERlY29tcHJlc3NTeW5jPzogKGRhdGE6IFVpbnQ4QXJyYXkpID0+IFVpbnQ4QXJyYXk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBgbm9kZTp6bGliYCB2aWEgYHByb2Nlc3MuZ2V0QnVpbHRpbk1vZHVsZWA6IG5vIHN0YXRpYyBOb2RlXG4gKiBkZXBlbmRlbmN5LCBpbnZpc2libGUgdG8gYnJvd3NlciBidW5kbGVycy4gUmV0dXJucyB1bmRlZmluZWQgb2ZmIE5vZGUuXG4gKi9cbmZ1bmN0aW9uIGdldE5vZGVabGliKCk6IE5vZGVabGliRGVjb2RlIHwgdW5kZWZpbmVkIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gKFxuICAgICAgZ2xvYmFsVGhpcyBhcyB7XG4gICAgICAgIHByb2Nlc3M/OiB7IGdldEJ1aWx0aW5Nb2R1bGU/OiAoaWQ6IHN0cmluZykgPT4gTm9kZVpsaWJEZWNvZGUgfTtcbiAgICAgIH1cbiAgICApLnByb2Nlc3M/LmdldEJ1aWx0aW5Nb2R1bGU/Lignbm9kZTp6bGliJyk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBTeW5jaHJvbm91c2x5IGRlY29tcHJlc3MgYSBgZ3ppcGAvYHpzdGRgIHBheWxvYWQgd2hlbiBydW5uaW5nIG9uIE5vZGUuanMuXG4gKlxuICogUmV0dXJucyBgdW5kZWZpbmVkYCB3aGVuIHN5bmMgZGVjb21wcmVzc2lvbiBpc24ndCBhdmFpbGFibGUgKGUuZy4gaW4gdGhlXG4gKiBicm93c2VyLCBvciB6c3RkIG9uIE5vZGUgPCAyMi4xNSk7IGNhbGxlcnMgZmFsbCBiYWNrIHRvIGxlYXZpbmcgdGhlIGRhdGFcbiAqIHVuLWh5ZHJhdGVkICh0aGUgYXN5bmMgYGh5ZHJhdGVEYXRhV2l0aEtleWAgcGF0aCBoYW5kbGVzIGRlY29tcHJlc3Npb24gaW5cbiAqIGJyb3dzZXJzIHZpYSBgRGVjb21wcmVzc2lvblN0cmVhbWAgLyBhIHJlZ2lzdGVyZWQgenN0ZCBkZWNvZGVyKS5cbiAqL1xuZnVuY3Rpb24gZGVjb21wcmVzc1N5bmNJZkF2YWlsYWJsZShcbiAgZm9ybWF0OiBzdHJpbmcsXG4gIHBheWxvYWQ6IFVpbnQ4QXJyYXlcbik6IFVpbnQ4QXJyYXkgfCB1bmRlZmluZWQge1xuICB0cnkge1xuICAgIGNvbnN0IHpsaWIgPSBnZXROb2RlWmxpYigpO1xuICAgIGlmIChmb3JtYXQgPT09IFNlcmlhbGl6YXRpb25Gb3JtYXQuR1pJUCAmJiB6bGliPy5ndW56aXBTeW5jKSB7XG4gICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoemxpYi5ndW56aXBTeW5jKHBheWxvYWQpKTtcbiAgICB9XG4gICAgaWYgKGZvcm1hdCA9PT0gU2VyaWFsaXphdGlvbkZvcm1hdC5aU1REICYmIHpsaWI/LnpzdGREZWNvbXByZXNzU3luYykge1xuICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KHpsaWIuenN0ZERlY29tcHJlc3NTeW5jKHBheWxvYWQpKTtcbiAgICB9XG4gIH0gY2F0Y2gge1xuICAgIC8vIEZhbGwgdGhyb3VnaDogdHJlYXQgYXMgdW5hdmFpbGFibGVcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEJyb3dzZXIgenN0ZCBkZWNvZGVyLCByZWdpc3RlcmVkIGJ5IHRoZSBvMTF5IGhvc3QgKHdlYi1zaGFyZWQpIHNpbmNlIHRoZVxuICogV2ViIGBEZWNvbXByZXNzaW9uU3RyZWFtYCBoYXMgbm8genN0ZCBzdXBwb3J0LiBOb2RlIGRlY29kZXMgdmlhIGBub2RlOnpsaWJgXG4gKiBhbmQgbmV2ZXIgbmVlZHMgdGhpcy4gU2VlIGByZWdpc3RlclpzdGREZWNvZGVyYC5cbiAqL1xuLy8gT24gYGdsb2JhbFRoaXNgIChzZWUgYGdsb2JhbFNpbmdsZXRvbmApOiB0aGUgbzExeSBob3N0IHJlZ2lzdGVycyB0aGUgZGVjb2RlclxuLy8gb25jZSwgYW5kIGEgcGVyLWNvcHkgc2xvdCB3b3VsZCBsZWF2ZSBldmVyeSBvdGhlciBjb3B5IG9mIHRoaXMgbW9kdWxlIHdpdGhvdXRcbi8vIG9uZS5cbmNvbnN0IHpzdGQgPSBnbG9iYWxTaW5nbGV0b24oJ0B3b3JrZmxvdy9jb3JlLy96c3RkLmRlY29kZXInLCAxLCAoKSA9PiAoe1xuICBkZWNvZGVyOiB1bmRlZmluZWQgYXNcbiAgICB8ICgocGF5bG9hZDogVWludDhBcnJheSkgPT4gUHJvbWlzZTxVaW50OEFycmF5PilcbiAgICB8IHVuZGVmaW5lZCxcbn0pKTtcblxuLyoqXG4gKiBSZWdpc3RlciBhIGJyb3dzZXIgenN0ZCBkZWNvZGVyIChlLmcuIGEgV0FTTS1iYWNrZWQgb25lKS4gVGhlIHdlYiBvMTF5IFVJXG4gKiBjYWxscyB0aGlzIGF0IGluaXQgc28gYGh5ZHJhdGVEYXRhV2l0aEtleWAgY2FuIGluZmxhdGUgenN0ZCBwYXlsb2FkcyBhZnRlclxuICogY2xpZW50LXNpZGUgZGVjcnlwdGlvbi4gTm9kZSByZWFkZXJzIHVzZSBgbm9kZTp6bGliYCBhbmQgaWdub3JlIHRoaXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlclpzdGREZWNvZGVyKFxuICBkZWNvZGVyOiAocGF5bG9hZDogVWludDhBcnJheSkgPT4gUHJvbWlzZTxVaW50OEFycmF5PlxuKTogdm9pZCB7XG4gIHpzdGQuZGVjb2RlciA9IGRlY29kZXI7XG59XG5cbi8qKlxuICogQXN5bmNocm9ub3VzbHkgZGVjb21wcmVzcyBhIGBnemlwYC9genN0ZGAgcGF5bG9hZC5cbiAqIC0gZ3ppcDogd2ViLXN0YW5kYXJkIGBEZWNvbXByZXNzaW9uU3RyZWFtYCAoTm9kZSAxOCssIGJyb3dzZXJzLCBlZGdlKS5cbiAqIC0genN0ZDogYG5vZGU6emxpYmAgd2hlbiBvbiBOb2RlLCBlbHNlIHRoZSByZWdpc3RlcmVkIGJyb3dzZXIgZGVjb2Rlci5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZGVjb21wcmVzc0FzeW5jKFxuICBmb3JtYXQ6IHN0cmluZyxcbiAgcGF5bG9hZDogVWludDhBcnJheVxuKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIGlmIChmb3JtYXQgPT09IFNlcmlhbGl6YXRpb25Gb3JtYXQuWlNURCkge1xuICAgIGNvbnN0IHN5bmMgPSBkZWNvbXByZXNzU3luY0lmQXZhaWxhYmxlKGZvcm1hdCwgcGF5bG9hZCk7XG4gICAgaWYgKHN5bmMpIHJldHVybiBzeW5jO1xuICAgIGlmICh6c3RkLmRlY29kZXIpIHJldHVybiB6c3RkLmRlY29kZXIocGF5bG9hZCk7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ3pzdGQtY29tcHJlc3NlZCB3b3JrZmxvdyBkYXRhIGVuY291bnRlcmVkIGJ1dCBubyB6c3RkIGRlY29kZXIgaXMgJyArXG4gICAgICAgICdhdmFpbGFibGUuIE5vZGUuanMgMjIuMTUrIGRlY29kZXMgbmF0aXZlbHk7IGluIHRoZSBicm93c2VyIHJlZ2lzdGVyICcgK1xuICAgICAgICAnb25lIHZpYSByZWdpc3RlclpzdGREZWNvZGVyICh0aGUgd2ViIG8xMXkgcGFja2FnZSBkb2VzIHRoaXMpLidcbiAgICApO1xuICB9XG5cbiAgY29uc3QgdHJhbnNmb3JtID0gbmV3IERlY29tcHJlc3Npb25TdHJlYW0oJ2d6aXAnKTtcbiAgY29uc3Qgd3JpdGVyID0gdHJhbnNmb3JtLndyaXRhYmxlLmdldFdyaXRlcigpO1xuICBjb25zdCB3cml0ZVByb21pc2UgPSB3cml0ZXIud3JpdGUocGF5bG9hZCkudGhlbigoKSA9PiB3cml0ZXIuY2xvc2UoKSk7XG4gIHdyaXRlUHJvbWlzZS5jYXRjaCgoKSA9PiB7fSk7XG4gIGNvbnN0IGNodW5rczogVWludDhBcnJheVtdID0gW107XG4gIGxldCB0b3RhbCA9IDA7XG4gIGNvbnN0IHJlYWRlciA9IHRyYW5zZm9ybS5yZWFkYWJsZS5nZXRSZWFkZXIoKTtcbiAgZm9yICg7Oykge1xuICAgIGNvbnN0IHsgZG9uZSwgdmFsdWUgfSA9IGF3YWl0IHJlYWRlci5yZWFkKCk7XG4gICAgaWYgKGRvbmUpIGJyZWFrO1xuICAgIGNodW5rcy5wdXNoKHZhbHVlKTtcbiAgICB0b3RhbCArPSB2YWx1ZS5sZW5ndGg7XG4gIH1cbiAgYXdhaXQgd3JpdGVQcm9taXNlO1xuICBjb25zdCBvdXQgPSBuZXcgVWludDhBcnJheSh0b3RhbCk7XG4gIGxldCBvZmZzZXQgPSAwO1xuICBmb3IgKGNvbnN0IGNodW5rIG9mIGNodW5rcykge1xuICAgIG91dC5zZXQoY2h1bmssIG9mZnNldCk7XG4gICAgb2Zmc2V0ICs9IGNodW5rLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gb3V0O1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJldml2ZXJzIHR5cGUgKHNoYXJlZCBhY3Jvc3MgYWxsIGVudmlyb25tZW50cylcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vKipcbiAqIEEgbWFwIG9mIHR5cGUgbmFtZSDihpIgcmV2aXZlciBmdW5jdGlvbiwgdXNlZCBieSBkZXZhbHVlJ3MgYHBhcnNlYC9gdW5mbGF0dGVuYC5cbiAqIEVhY2ggZW52aXJvbm1lbnQgKHJ1bnRpbWUsIHdlYiwgQ0xJKSBwcm92aWRlcyBpdHMgb3duIHNldC5cbiAqL1xuZXhwb3J0IHR5cGUgUmV2aXZlcnMgPSBSZWNvcmQ8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gYW55PjtcblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBHZW5lcmljIGh5ZHJhdGUvZGVoeWRyYXRlIGRpc3BhdGNoXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLyoqXG4gKiBIeWRyYXRlIChkZXNlcmlhbGl6ZSkgYSB2YWx1ZSB0aGF0IHdhcyBzdG9yZWQgaW4gdGhlIGRhdGFiYXNlLlxuICpcbiAqIEhhbmRsZXMgZm91ciBkYXRhIHNoYXBlczpcbiAqIDEuIGBVaW50OEFycmF5YCB3aXRoICdlbmNyJyBwcmVmaXgg4oaSIHJldHVybmVkIGFzLWlzIChlbmNyeXB0ZWQsIG5vdCB5ZXQgZGVjcnlwdGVkKVxuICogMi4gYFVpbnQ4QXJyYXlgIHdpdGggYSBmb3JtYXQgcHJlZml4IChzcGVjVmVyc2lvbiAyKykg4oaSIGRlY29kZSBwcmVmaXgsIHBhcnNlXG4gKiAzLiBgQXJyYXlgIChsZWdhY3kgc3BlY1ZlcnNpb24gMSwgXCJyZXZpdmVkIGRldmFsdWVcIikg4oaSIHVuZmxhdHRlblxuICogNC4gT3RoZXIgKGFscmVhZHkgYSBwbGFpbiBKUyB2YWx1ZSkg4oaSIHJldHVybiBhcy1pc1xuICpcbiAqIEVuY3J5cHRlZCBkYXRhIGlzIGludGVudGlvbmFsbHkgbGVmdCBhcyBhIGBVaW50OEFycmF5YCBzbyB0aGF0IGNvbnN1bWVyc1xuICogKENMSSwgd2ViIFVJKSBjYW4gZGV0ZWN0IGl0IHdpdGggYGlzRW5jcnlwdGVkRGF0YSgpYCBhbmQgZGVjaWRlIGhvdyB0b1xuICogaGFuZGxlIGl0OiB0aGUgQ0xJIHJlcGxhY2VzIGl0IHdpdGggYSBzdHlsZWQgcGxhY2Vob2xkZXIsIHRoZSB3ZWIgVUlcbiAqIHJlbmRlcnMgYW4gXCJFbmNyeXB0ZWRcIiBjYXJkIHdpdGggYSBEZWNyeXB0IGJ1dHRvbiB0aGF0IHRyaWdnZXJzXG4gKiBjbGllbnQtc2lkZSBkZWNyeXB0aW9uIG9uIGRlbWFuZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGh5ZHJhdGVEYXRhKHZhbHVlOiB1bmtub3duLCByZXZpdmVyczogUmV2aXZlcnMpOiB1bmtub3duIHtcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgIC8vIEVuY3J5cHRlZCBkYXRhIHBhc3NlcyB0aHJvdWdoIHVudG91Y2hlZDogbzExeSBsYXllcnMgZGV0ZWN0IGl0IHdpdGhcbiAgICAvLyBpc0VuY3J5cHRlZERhdGEoKSBhbmQgaGFuZGxlIGRpc3BsYXkgKHdlYjogbmFtZWQgY29uc3RydWN0b3Igb2JqZWN0LFxuICAgIC8vIENMSTogRW5jcnlwdGVkRGF0YVJlZiB3aXRoIHV0aWwuaW5zcGVjdC5jdXN0b20pLlxuICAgIGlmIChpc0VuY3J5cHRlZERhdGEodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgY29uc3QgeyBmb3JtYXQsIHBheWxvYWQgfSA9IGRlY29kZUZvcm1hdFByZWZpeCh2YWx1ZSk7XG4gICAgaWYgKGZvcm1hdCA9PT0gU2VyaWFsaXphdGlvbkZvcm1hdC5ERVZBTFVFX1YxKSB7XG4gICAgICBjb25zdCBzdHIgPSBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUocGF5bG9hZCk7XG4gICAgICByZXR1cm4gcGFyc2Uoc3RyLCByZXZpdmVycyk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIGZvcm1hdCA9PT0gU2VyaWFsaXphdGlvbkZvcm1hdC5HWklQIHx8XG4gICAgICBmb3JtYXQgPT09IFNlcmlhbGl6YXRpb25Gb3JtYXQuWlNURFxuICAgICkge1xuICAgICAgLy8gQ29tcHJlc3NlZCBwYXlsb2FkOiBkZWNvbXByZXNzIHN5bmNocm9ub3VzbHkgd2hlbiBydW5uaW5nIG9uXG4gICAgICAvLyBOb2RlLmpzIChDTEksIHNlcnZlciBvMTF5KS4gSW4gYnJvd3NlcnMgdGhlcmUgaXMgbm8gc3luYyBjb2RlYztcbiAgICAgIC8vIHBhc3MgdGhlIGRhdGEgdGhyb3VnaCB1bnRvdWNoZWQgKGxpa2UgZW5jcnlwdGVkIGRhdGEpIHNvIGFzeW5jXG4gICAgICAvLyBjb25zdW1lcnMgY2FuIHJvdXRlIGl0IHRocm91Z2ggYGh5ZHJhdGVEYXRhV2l0aEtleWAsIHdoaWNoXG4gICAgICAvLyBkZWNvbXByZXNzZXMgdmlhIERlY29tcHJlc3Npb25TdHJlYW0gLyBhIHJlZ2lzdGVyZWQgenN0ZCBkZWNvZGVyLlxuICAgICAgY29uc3QgaW5mbGF0ZWQgPSBkZWNvbXByZXNzU3luY0lmQXZhaWxhYmxlKGZvcm1hdCwgcGF5bG9hZCk7XG4gICAgICBpZiAoaW5mbGF0ZWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICAvLyBUaGUgaW5mbGF0ZWQgYnl0ZXMgY2FycnkgdGhlaXIgb3duIGZvcm1hdCBwcmVmaXggKGUuZy4gJ2RldmwnKVxuICAgICAgcmV0dXJuIGh5ZHJhdGVEYXRhKGluZmxhdGVkLCByZXZpdmVycyk7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgc2VyaWFsaXphdGlvbiBmb3JtYXQ6ICR7Zm9ybWF0fWApO1xuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIHVuZmxhdHRlbih2YWx1ZSwgcmV2aXZlcnMpO1xuICB9XG5cbiAgLy8gQWxyZWFkeSBhIHBsYWluIEpTIHZhbHVlIChlLmcuLCBudW1iZXIsIHN0cmluZywgbnVsbClcbiAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIEh5ZHJhdGUgYSB2YWx1ZSwgZGVjcnlwdGluZyBpdCBmaXJzdCBpZiBhbiBlbmNyeXB0aW9uIGtleSBpcyBwcm92aWRlZC5cbiAqXG4gKiBUaGlzIGlzIHRoZSBhc3luYyB2ZXJzaW9uIG9mIGBoeWRyYXRlRGF0YWAgdGhhdCBzdXBwb3J0cyB0cmFuc3BhcmVudFxuICogZGVjcnlwdGlvbi4gVXNlZCBieSBvMTF5IHRvb2xpbmcgKHdlYiBVSSwgQ0xJKSB3aGVuIHRoZSB1c2VyIHJlcXVlc3RzXG4gKiBkZWNyeXB0aW9uLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBoeWRyYXRlIChtYXkgYmUgZW5jcnlwdGVkIG9yIHNlYWxlZClcbiAqIEBwYXJhbSByZXZpdmVycyAtIERldmFsdWUgcmV2aXZlcnMgZm9yIGRlc2VyaWFsaXphdGlvblxuICogQHBhcmFtIGtleSAtIFRoZSBydW4ncyBrZXkgbWF0ZXJpYWwuIFBhc3MgYFJ1blBheWxvYWRLZXlzYCAoZnJvbVxuICogICBgZGVyaXZlUnVuUGF5bG9hZEtleXNgKSB0byBvcGVuIGJvdGggc3ltbWV0cmljIChgZW5jcmApIGFuZCBzZWFsZWRcbiAqICAgKGBlbmNwYCkgcGF5bG9hZHM7IGEgYmFyZSBgQ3J5cHRvS2V5YCBvcGVucyBvbmx5IHRoZSBzeW1tZXRyaWMgb25lcy5cbiAqICAgVHlwZWQgYXMgYSByZWFkIGNhcGFiaWxpdHkgc28gYSB3cml0ZS1vbmx5IHNlYWwgdGFyZ2V0ICh3aGljaCBjb3VsZCBvcGVuXG4gKiAgIG5laXRoZXIgc2NoZW1lKSBpcyByZWplY3RlZCBhdCBjb21waWxlIHRpbWUgcmF0aGVyIHRoYW4gZmFpbGluZyBoZXJlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaHlkcmF0ZURhdGFXaXRoS2V5KFxuICB2YWx1ZTogdW5rbm93bixcbiAgcmV2aXZlcnM6IFJldml2ZXJzLFxuICBrZXk6IGltcG9ydCgnLi9zZXJpYWxpemF0aW9uL2VuY3J5cHRpb24uanMnKS5EZWNyeXB0aW9uS2V5IHwgdW5kZWZpbmVkXG4pOiBQcm9taXNlPHVua25vd24+IHtcbiAgbGV0IGRhdGEgPSB2YWx1ZTtcbiAgaWYgKGRhdGEgaW5zdGFuY2VvZiBVaW50OEFycmF5ICYmIGlzRW5jcnlwdGVkRGF0YShkYXRhKSAmJiBrZXkpIHtcbiAgICAvLyBFbnZlbG9wZS1hd2FyZSBkZWNyeXB0OiBoYW5kbGVzIGJvdGggYGVuY3JgIChBRVMtR0NNIHVuZGVyIHRoZSBydW4nc1xuICAgIC8vIHN5bW1ldHJpYyBrZXkpIGFuZCBgZW5jcGAgKHNlYWxlZCB0byB0aGUgcnVuJ3MgWDI1NTE5IHB1YmxpYyBrZXkgYnlcbiAgICAvLyBzb21lIG90aGVyIHJ1biksIGRpc3BhdGNoaW5nIG9uIHRoZSBmb3JtYXQgcHJlZml4LlxuICAgIGNvbnN0IHsgZGVjcnlwdCwgaXNSdW5QYXlsb2FkS2V5cyB9ID0gYXdhaXQgaW1wb3J0KFxuICAgICAgJy4vc2VyaWFsaXphdGlvbi9lbmNyeXB0aW9uLmpzJ1xuICAgICk7XG4gICAgLy8gT3BlbmluZyBhIHNlYWxlZCBwYXlsb2FkIG5lZWRzIHRoZSBydW4ncyBwcml2YXRlIHNjYWxhci4gSWYgdGhlIGNhbGxlclxuICAgIC8vIHN1cHBsaWVkIG9ubHkgYSBzeW1tZXRyaWMga2V5LCBsZWF2ZSB0aGUgYnl0ZXMgYXMgY2lwaGVydGV4dCBzbyB0aGUgVUlcbiAgICAvLyBrZWVwcyBzaG93aW5nIGl0cyBcIkVuY3J5cHRlZFwiIGFmZm9yZGFuY2UsIHJhdGhlciB0aGFuIHN1cmZhY2luZyBhXG4gICAgLy8gZGVjcnlwdGlvbiBlcnJvciBmb3Igc29tZXRoaW5nIHRoYXQgd2FzIG5ldmVyIG9wZW5hYmxlIHdpdGggdGhpcyBrZXkuXG4gICAgaWYgKCFpc1NlYWxlZERhdGEoZGF0YSkgfHwgaXNSdW5QYXlsb2FkS2V5cyhrZXkpKSB7XG4gICAgICBkYXRhID0gYXdhaXQgZGVjcnlwdChkYXRhLCBrZXkpO1xuICAgIH1cbiAgfVxuICBpZiAoZGF0YSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkgJiYgaXNDb21wcmVzc2VkRGF0YShkYXRhKSkge1xuICAgIC8vIERlY29tcHJlc3M6IHN0cmlwIHRoZSBjb2RlYyBwcmVmaXggYW5kIGluZmxhdGUuIGd6aXAgdXNlcyB0aGVcbiAgICAvLyB3ZWItc3RhbmRhcmQgRGVjb21wcmVzc2lvblN0cmVhbSAod29ya3MgaW4gYnJvd3NlcnMpOyB6c3RkIHVzZXNcbiAgICAvLyBub2RlOnpsaWIgb24gTm9kZSBvciB0aGUgcmVnaXN0ZXJlZCBXQVNNIGRlY29kZXIgaW4gdGhlIGJyb3dzZXIuXG4gICAgLy8gVGhlIGluZmxhdGVkIGJ5dGVzIGNhcnJ5IHRoZWlyIG93biBmb3JtYXQgcHJlZml4IChlLmcuICdkZXZsJykuXG4gICAgY29uc3QgeyBmb3JtYXQsIHBheWxvYWQgfSA9IGRlY29kZUZvcm1hdFByZWZpeChkYXRhKTtcbiAgICBkYXRhID0gYXdhaXQgZGVjb21wcmVzc0FzeW5jKGZvcm1hdCwgcGF5bG9hZCk7XG4gIH1cbiAgLy8gRGVsZWdhdGUgdGhlIChkZWNyeXB0ZWQvZGVjb21wcmVzc2VkKSByZXN1bHQgdG8gc3luYyBoeWRyYXRlRGF0YVxuICByZXR1cm4gaHlkcmF0ZURhdGEoZGF0YSwgcmV2aXZlcnMpO1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFNoYXJlZCBtYXJrZXIgdHlwZXMgZm9yIG8xMXkgZGlzcGxheVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmNvbnN0IFNUUkVBTV9JRF9QUkVGSVggPSAnc3RybV8nO1xuXG4vKiogTWFya2VyIGZvciBzdHJlYW0gcmVmZXJlbmNlIG9iamVjdHMgcmVuZGVyZWQgYXMgbGlua3MgaW4gdGhlIFVJICovXG5leHBvcnQgY29uc3QgU1RSRUFNX1JFRl9UWVBFID0gJ19fd29ya2Zsb3dfc3RyZWFtX3JlZl9fJztcblxuLyoqIEEgc3RyZWFtIHJlZmVyZW5jZSBmb3IgVUkgZGlzcGxheSAqL1xuZXhwb3J0IGludGVyZmFjZSBTdHJlYW1SZWYge1xuICBfX3R5cGU6IHR5cGVvZiBTVFJFQU1fUkVGX1RZUEU7XG4gIHN0cmVhbUlkOiBzdHJpbmc7XG59XG5cbi8qKiBNYXJrZXIgZm9yIFJ1biByZWZlcmVuY2Ugb2JqZWN0cyByZW5kZXJlZCBhcyBsaW5rcyBpbiB0aGUgVUkgKi9cbmV4cG9ydCBjb25zdCBSVU5fUkVGX1RZUEUgPSAnX193b3JrZmxvd19ydW5fcmVmX18nO1xuXG4vKiogQSBSdW4gcmVmZXJlbmNlIGZvciBVSSBkaXNwbGF5ICovXG5leHBvcnQgaW50ZXJmYWNlIFJ1blJlZiB7XG4gIF9fdHlwZTogdHlwZW9mIFJVTl9SRUZfVFlQRTtcbiAgcnVuSWQ6IHN0cmluZztcbn1cblxuLyoqIENoZWNrIGlmIGEgdmFsdWUgaXMgYSBSdW5SZWYgb2JqZWN0ICovXG5leHBvcnQgY29uc3QgaXNSdW5SZWYgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBSdW5SZWYgPT4ge1xuICByZXR1cm4gKFxuICAgIHZhbHVlICE9PSBudWxsICYmXG4gICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJlxuICAgICdfX3R5cGUnIGluIHZhbHVlICYmXG4gICAgdmFsdWUuX190eXBlID09PSBSVU5fUkVGX1RZUEUgJiZcbiAgICAncnVuSWQnIGluIHZhbHVlICYmXG4gICAgdHlwZW9mIHZhbHVlLnJ1bklkID09PSAnc3RyaW5nJ1xuICApO1xufTtcblxuLyoqIENvbnZlcnQgYSBzZXJpYWxpemVkIFJ1biB2YWx1ZSB0byBhIFJ1blJlZiBmb3IgZGlzcGxheSAqL1xuZXhwb3J0IGNvbnN0IHNlcmlhbGl6ZWRSdW5Ub1J1blJlZiA9ICh2YWx1ZTogeyBydW5JZDogc3RyaW5nIH0pOiBSdW5SZWYgPT4ge1xuICByZXR1cm4geyBfX3R5cGU6IFJVTl9SRUZfVFlQRSwgcnVuSWQ6IHZhbHVlLnJ1bklkIH07XG59O1xuXG4vKiogTWFya2VyIGZvciBjdXN0b20gY2xhc3MgaW5zdGFuY2UgcmVmZXJlbmNlcyAqL1xuZXhwb3J0IGNvbnN0IENMQVNTX0lOU1RBTkNFX1JFRl9UWVBFID0gJ19fd29ya2Zsb3dfY2xhc3NfaW5zdGFuY2VfcmVmX18nO1xuXG4vKipcbiAqIEEgY2xhc3MgaW5zdGFuY2UgcmVmZXJlbmNlIGZvciBvMTF5IGRpc3BsYXkuXG4gKlxuICogQnJvd3Nlci1zYWZlIGJhc2UgY2xhc3M6IG5vIGB1dGlsLmluc3BlY3QuY3VzdG9tYC4gRW52aXJvbm1lbnQtc3BlY2lmaWNcbiAqIHJlbmRlcmluZyAoQ0xJIGluc3BlY3QsIHdlYiBjb21wb25lbnQpIGlzIGhhbmRsZWQgYnkgZWFjaCBjb25zdW1lci5cbiAqL1xuZXhwb3J0IGNsYXNzIENsYXNzSW5zdGFuY2VSZWYge1xuICByZWFkb25seSBfX3R5cGUgPSBDTEFTU19JTlNUQU5DRV9SRUZfVFlQRTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgcmVhZG9ubHkgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgcHVibGljIHJlYWRvbmx5IGNsYXNzSWQ6IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgZGF0YTogdW5rbm93blxuICApIHt9XG5cbiAgdG9KU09OKCk6IHtcbiAgICBfX3R5cGU6IHN0cmluZztcbiAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICBjbGFzc0lkOiBzdHJpbmc7XG4gICAgZGF0YTogdW5rbm93bjtcbiAgfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF9fdHlwZTogdGhpcy5fX3R5cGUsXG4gICAgICBjbGFzc05hbWU6IHRoaXMuY2xhc3NOYW1lLFxuICAgICAgY2xhc3NJZDogdGhpcy5jbGFzc0lkLFxuICAgICAgZGF0YTogdGhpcy5kYXRhLFxuICAgIH07XG4gIH1cbn1cblxuLyoqIENoZWNrIGlmIGEgdmFsdWUgaXMgYSBDbGFzc0luc3RhbmNlUmVmIG9iamVjdCAqL1xuZXhwb3J0IGNvbnN0IGlzQ2xhc3NJbnN0YW5jZVJlZiA9IChcbiAgdmFsdWU6IHVua25vd25cbik6IHZhbHVlIGlzIENsYXNzSW5zdGFuY2VSZWYgPT4ge1xuICByZXR1cm4gKFxuICAgIHZhbHVlIGluc3RhbmNlb2YgQ2xhc3NJbnN0YW5jZVJlZiB8fFxuICAgICh2YWx1ZSAhPT0gbnVsbCAmJlxuICAgICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJlxuICAgICAgJ19fdHlwZScgaW4gdmFsdWUgJiZcbiAgICAgIHZhbHVlLl9fdHlwZSA9PT0gQ0xBU1NfSU5TVEFOQ0VfUkVGX1RZUEUgJiZcbiAgICAgICdjbGFzc05hbWUnIGluIHZhbHVlICYmXG4gICAgICB0eXBlb2YgdmFsdWUuY2xhc3NOYW1lID09PSAnc3RyaW5nJylcbiAgKTtcbn07XG5cbi8qKiBDaGVjayBpZiBhIHZhbHVlIGlzIGEgc3RyZWFtIElEIHN0cmluZyAqL1xuZXhwb3J0IGNvbnN0IGlzU3RyZWFtSWQgPSAodmFsdWU6IHVua25vd24pOiBib29sZWFuID0+IHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWUuc3RhcnRzV2l0aChTVFJFQU1fSURfUFJFRklYKTtcbn07XG5cbi8qKiBDaGVjayBpZiBhIHZhbHVlIGlzIGEgU3RyZWFtUmVmIG9iamVjdCAqL1xuZXhwb3J0IGNvbnN0IGlzU3RyZWFtUmVmID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgU3RyZWFtUmVmID0+IHtcbiAgcmV0dXJuIChcbiAgICB2YWx1ZSAhPT0gbnVsbCAmJlxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAnX190eXBlJyBpbiB2YWx1ZSAmJlxuICAgIHZhbHVlLl9fdHlwZSA9PT0gU1RSRUFNX1JFRl9UWVBFICYmXG4gICAgJ3N0cmVhbUlkJyBpbiB2YWx1ZSAmJlxuICAgIHR5cGVvZiB2YWx1ZS5zdHJlYW1JZCA9PT0gJ3N0cmluZydcbiAgKTtcbn07XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gU2hhcmVkIG8xMXkgcmV2aXZlciBoZWxwZXJzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLyoqXG4gKiBDb252ZXJ0IGEgc2VyaWFsaXplZCBzdHJlYW0gdmFsdWUgdG8gYSBTdHJlYW1SZWYgZm9yIGRpc3BsYXkuXG4gKi9cbmV4cG9ydCBjb25zdCBzdHJlYW1Ub1N0cmVhbVJlZiA9ICh2YWx1ZTogYW55KTogU3RyZWFtUmVmID0+IHtcbiAgbGV0IHN0cmVhbUlkOiBzdHJpbmc7XG4gIGlmICgnbmFtZScgaW4gdmFsdWUpIHtcbiAgICBjb25zdCBuYW1lID0gU3RyaW5nKHZhbHVlLm5hbWUpO1xuICAgIGlmICghbmFtZS5zdGFydHNXaXRoKFNUUkVBTV9JRF9QUkVGSVgpKSB7XG4gICAgICBzdHJlYW1JZCA9IGAke1NUUkVBTV9JRF9QUkVGSVh9JHtuYW1lfWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0cmVhbUlkID0gbmFtZTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgc3RyZWFtSWQgPSBgJHtTVFJFQU1fSURfUFJFRklYfW51bGxgO1xuICB9XG4gIHJldHVybiB7IF9fdHlwZTogU1RSRUFNX1JFRl9UWVBFLCBzdHJlYW1JZCB9O1xufTtcblxuLyoqIENvbnZlcnQgYSBzZXJpYWxpemVkIHN0ZXAgZnVuY3Rpb24gdG8gYSBkaXNwbGF5IHN0cmluZyAqL1xuZXhwb3J0IGNvbnN0IHNlcmlhbGl6ZWRTdGVwRnVuY3Rpb25Ub1N0cmluZyA9ICh2YWx1ZTogdW5rbm93bik6IHN0cmluZyA9PiB7XG4gIGlmICghdmFsdWUpIHJldHVybiAnbnVsbCc7XG4gIGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSByZXR1cm4gJ251bGwnO1xuICBpZiAoJ3N0ZXBJZCcgaW4gdmFsdWUpIHtcbiAgICByZXR1cm4gYDxzdGVwOiR7KHZhbHVlIGFzIHsgc3RlcElkOiBzdHJpbmcgfSkuc3RlcElkfT5gO1xuICB9XG4gIHJldHVybiAnPGZ1bmN0aW9uPic7XG59O1xuXG4vKiogRXh0cmFjdCB0aGUgY2xhc3MgbmFtZSBmcm9tIGEgY2xhc3NJZCAqL1xuZXhwb3J0IGNvbnN0IGV4dHJhY3RDbGFzc05hbWUgPSAoY2xhc3NJZDogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgaWYgKCFjbGFzc0lkKSByZXR1cm4gJ1Vua25vd24nO1xuICBjb25zdCBwYXJ0cyA9IGNsYXNzSWQuc3BsaXQoJy8nKTtcbiAgcmV0dXJuIHBhcnRzW3BhcnRzLmxlbmd0aCAtIDFdIHx8IGNsYXNzSWQ7XG59O1xuXG4vKiogQ29udmVydCBhIHNlcmlhbGl6ZWQgY2xhc3MgaW5zdGFuY2UgdG8gYSBDbGFzc0luc3RhbmNlUmVmIGZvciBkaXNwbGF5LlxuICogIFJ1biBpbnN0YW5jZXMgYXJlIHNwZWNpYWwtY2FzZWQgdG8gYSBSdW5SZWYgZm9yIGNsaWNrYWJsZSByZW5kZXJpbmcuICovXG5leHBvcnQgY29uc3Qgc2VyaWFsaXplZEluc3RhbmNlVG9SZWYgPSAodmFsdWU6IHtcbiAgY2xhc3NJZDogc3RyaW5nO1xuICBkYXRhOiB1bmtub3duO1xufSk6IENsYXNzSW5zdGFuY2VSZWYgfCBSdW5SZWYgPT4ge1xuICBjb25zdCBjbGFzc05hbWUgPSBleHRyYWN0Q2xhc3NOYW1lKHZhbHVlLmNsYXNzSWQpO1xuICBpZiAoXG4gICAgY2xhc3NOYW1lID09PSAnUnVuJyAmJlxuICAgIHZhbHVlLmRhdGEgIT09IG51bGwgJiZcbiAgICB0eXBlb2YgdmFsdWUuZGF0YSA9PT0gJ29iamVjdCcgJiZcbiAgICAncnVuSWQnIGluIHZhbHVlLmRhdGEgJiZcbiAgICB0eXBlb2YgKHZhbHVlLmRhdGEgYXMgeyBydW5JZDogdW5rbm93biB9KS5ydW5JZCA9PT0gJ3N0cmluZydcbiAgKSB7XG4gICAgcmV0dXJuIHNlcmlhbGl6ZWRSdW5Ub1J1blJlZih2YWx1ZS5kYXRhIGFzIHsgcnVuSWQ6IHN0cmluZyB9KTtcbiAgfVxuICByZXR1cm4gbmV3IENsYXNzSW5zdGFuY2VSZWYoY2xhc3NOYW1lLCB2YWx1ZS5jbGFzc0lkLCB2YWx1ZS5kYXRhKTtcbn07XG5cbi8qKiBDb252ZXJ0IGEgc2VyaWFsaXplZCBjbGFzcyByZWZlcmVuY2UgdG8gYSBkaXNwbGF5IHN0cmluZyAqL1xuZXhwb3J0IGNvbnN0IHNlcmlhbGl6ZWRDbGFzc1RvU3RyaW5nID0gKHZhbHVlOiB7IGNsYXNzSWQ6IHN0cmluZyB9KTogc3RyaW5nID0+IHtcbiAgcmV0dXJuIGA8Y2xhc3M6JHtleHRyYWN0Q2xhc3NOYW1lKHZhbHVlLmNsYXNzSWQpfT5gO1xufTtcblxuLyoqXG4gKiBTdGFuZGFyZCBvMTF5IHJldml2ZXJzIHRoYXQgb3ZlcnJpZGUgcnVudGltZS1zcGVjaWZpYyB0eXBlcyB3aXRoXG4gKiBkaXNwbGF5LWZyaWVuZGx5IHZhbHVlcy4gVXNlZCBieSBib3RoIHdlYiBhbmQgQ0xJIGh5ZHJhdGlvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IG9ic2VydmFiaWxpdHlSZXZpdmVyczogUmV2aXZlcnMgPSB7XG4gIFJlYWRhYmxlU3RyZWFtOiBzdHJlYW1Ub1N0cmVhbVJlZixcbiAgV3JpdGFibGVTdHJlYW06IHN0cmVhbVRvU3RyZWFtUmVmLFxuICBUcmFuc2Zvcm1TdHJlYW06IHN0cmVhbVRvU3RyZWFtUmVmLFxuICBBYm9ydENvbnRyb2xsZXI6ICh2YWx1ZTogYW55KSA9PlxuICAgIGA8QWJvcnRDb250cm9sbGVyKGFib3J0ZWQ6ICR7dmFsdWUuYWJvcnRlZH0pPmAsXG4gIEFib3J0U2lnbmFsOiAodmFsdWU6IGFueSkgPT4gYDxBYm9ydFNpZ25hbChhYm9ydGVkOiAke3ZhbHVlLmFib3J0ZWR9KT5gLFxuICAvLyBET01FeGNlcHRpb24gbmVlZHMgYW4gZXhwbGljaXQgcmV2aXZlcjogd2l0aG91dCBvbmUsIGRldmFsdWUucGFyc2VcbiAgLy8gdGhyb3dzIG9uIHRoZSBgW1wiRE9NRXhjZXB0aW9uXCIsIC4uLl1gIHRhZyBhbmQgYGh5ZHJhdGVTdGVwSU9gJ3NcbiAgLy8gdHJ5L2NhdGNoIGxlYXZlcyB0aGUgcmF3IGZsYXQtZW5jb2RlZCBzdHJpbmcgaW4gdGhlIFVJLiBBYm9ydENvbnRyb2xsZXJcbiAgLy8gc3ludGhlc2l6ZXMgYSBET01FeGNlcHRpb24gYXMgdGhlIGRlZmF1bHQgYHNpZ25hbC5yZWFzb25gIHdoZW4gYWJvcnQoKVxuICAvLyBpcyBjYWxsZWQgd2l0aCBubyBhcmcsIHNvIGFueSBhYm9ydCB0aGF0IHJvdW5kLXRyaXBzIHRocm91Z2ggYSBzdGVwXG4gIC8vIGJvdW5kYXJ5IHN1cmZhY2VzIGhlcmUuIFJlY29uc3RydWN0IGFzIGEgcmVhbCBET01FeGNlcHRpb24gd2hlbiB0aGVcbiAgLy8gZ2xvYmFsIGlzIGF2YWlsYWJsZSAobW9kZXJuIGJyb3dzZXJzICsgTm9kZSAxOCspLCBlbHNlIGZhbGwgYmFjayB0b1xuICAvLyBhbiBFcnJvciBwcmVzZXJ2aW5nIG5hbWUvbWVzc2FnZS9zdGFjay9jYXVzZSBmb3IgZGlzcGxheS5cbiAgRE9NRXhjZXB0aW9uOiAodmFsdWU6IHtcbiAgICBtZXNzYWdlOiBzdHJpbmc7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIHN0YWNrPzogc3RyaW5nO1xuICAgIGNhdXNlPzogdW5rbm93bjtcbiAgfSkgPT4ge1xuICAgIGNvbnN0IEcgPSBnbG9iYWxUaGlzIGFzIHsgRE9NRXhjZXB0aW9uPzogdHlwZW9mIERPTUV4Y2VwdGlvbiB9O1xuICAgIGlmICh0eXBlb2YgRy5ET01FeGNlcHRpb24gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGNvbnN0IGUgPSBuZXcgRy5ET01FeGNlcHRpb24odmFsdWUubWVzc2FnZSwgdmFsdWUubmFtZSk7XG4gICAgICBpZiAodmFsdWUuc3RhY2sgIT09IHVuZGVmaW5lZCkgZS5zdGFjayA9IHZhbHVlLnN0YWNrO1xuICAgICAgaWYgKCdjYXVzZScgaW4gdmFsdWUpIChlIGFzIHsgY2F1c2U/OiB1bmtub3duIH0pLmNhdXNlID0gdmFsdWUuY2F1c2U7XG4gICAgICByZXR1cm4gZTtcbiAgICB9XG4gICAgY29uc3QgZTogRXJyb3IgJiB7IGNhdXNlPzogdW5rbm93biB9ID0gbmV3IEVycm9yKHZhbHVlLm1lc3NhZ2UpO1xuICAgIGUubmFtZSA9IHZhbHVlLm5hbWU7XG4gICAgaWYgKHZhbHVlLnN0YWNrICE9PSB1bmRlZmluZWQpIGUuc3RhY2sgPSB2YWx1ZS5zdGFjaztcbiAgICBpZiAoJ2NhdXNlJyBpbiB2YWx1ZSkgZS5jYXVzZSA9IHZhbHVlLmNhdXNlO1xuICAgIHJldHVybiBlO1xuICB9LFxuICBTdGVwRnVuY3Rpb246IHNlcmlhbGl6ZWRTdGVwRnVuY3Rpb25Ub1N0cmluZyxcbiAgV29ya2Zsb3dGdW5jdGlvbjogKHZhbHVlOiB7IHdvcmtmbG93SWQ6IHN0cmluZyB9KSA9PlxuICAgIGA8d29ya2Zsb3c6JHt2YWx1ZS53b3JrZmxvd0lkfT5gLFxuICBJbnN0YW5jZTogc2VyaWFsaXplZEluc3RhbmNlVG9SZWYsXG4gIENsYXNzOiBzZXJpYWxpemVkQ2xhc3NUb1N0cmluZyxcbn07XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUmVzb3VyY2UtbGV2ZWwgaHlkcmF0aW9uIGRpc3BhdGNoIChmb3IgbzExeSlcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vKipcbiAqIEh5ZHJhdGUgdGhlIGRhdGEgZmllbGRzIG9mIGEgc3RlcCByZXNvdXJjZS5cbiAqL1xuZnVuY3Rpb24gaHlkcmF0ZVN0ZXBJTzxcbiAgVCBleHRlbmRzIHsgc3RlcElkPzogc3RyaW5nOyBpbnB1dD86IGFueTsgb3V0cHV0PzogYW55OyBlcnJvcj86IGFueSB9LFxuPihyZXNvdXJjZTogVCwgcmV2aXZlcnM6IFJldml2ZXJzKTogVCB7XG4gIGxldCBoeWRyYXRlZElucHV0ID0gcmVzb3VyY2UuaW5wdXQ7XG4gIGxldCBoeWRyYXRlZE91dHB1dCA9IHJlc291cmNlLm91dHB1dDtcbiAgbGV0IGh5ZHJhdGVkRXJyb3IgPSByZXNvdXJjZS5lcnJvcjtcblxuICBpZiAocmVzb3VyY2UuaW5wdXQgIT0gbnVsbCkge1xuICAgIHRyeSB7XG4gICAgICBoeWRyYXRlZElucHV0ID0gaHlkcmF0ZURhdGEocmVzb3VyY2UuaW5wdXQsIHJldml2ZXJzKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIExlYXZlIHVuLWh5ZHJhdGVkXG4gICAgfVxuICB9XG5cbiAgaWYgKHJlc291cmNlLm91dHB1dCAhPSBudWxsKSB7XG4gICAgdHJ5IHtcbiAgICAgIGh5ZHJhdGVkT3V0cHV0ID0gaHlkcmF0ZURhdGEocmVzb3VyY2Uub3V0cHV0LCByZXZpdmVycyk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBMZWF2ZSB1bi1oeWRyYXRlZFxuICAgIH1cbiAgfVxuXG4gIC8vIFRoZSBgZXJyb3JgIGZpZWxkIGlzIGBTZXJpYWxpemVkRGF0YWAgKFVpbnQ4QXJyYXkpIHByb2R1Y2VkIGJ5XG4gIC8vIGBkZWh5ZHJhdGVTdGVwRXJyb3JgLiBIeWRyYXRlIGl0IHNvIG9ic2VydmFiaWxpdHkgdG9vbHMgKENMSSwgd2ViIFVJKVxuICAvLyBjYW4gcmVhZCBgc3RlcC5lcnJvci5tZXNzYWdlYCwgYHN0ZXAuZXJyb3Iuc3RhY2tgLCBldGMuXG4gIGlmIChyZXNvdXJjZS5lcnJvciAhPSBudWxsKSB7XG4gICAgdHJ5IHtcbiAgICAgIGh5ZHJhdGVkRXJyb3IgPSBoeWRyYXRlRGF0YShyZXNvdXJjZS5lcnJvciwgcmV2aXZlcnMpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gTGVhdmUgdW4taHlkcmF0ZWRcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC4uLnJlc291cmNlLFxuICAgIGlucHV0OiBoeWRyYXRlZElucHV0LFxuICAgIG91dHB1dDogaHlkcmF0ZWRPdXRwdXQsXG4gICAgZXJyb3I6IGh5ZHJhdGVkRXJyb3IsXG4gIH07XG59XG5cbi8qKlxuICogSHlkcmF0ZSB0aGUgZGF0YSBmaWVsZHMgb2YgYSB3b3JrZmxvdyBydW4gcmVzb3VyY2UuXG4gKi9cbmZ1bmN0aW9uIGh5ZHJhdGVXb3JrZmxvd0lPPFxuICBUIGV4dGVuZHMgeyBpbnB1dD86IGFueTsgb3V0cHV0PzogYW55OyBlcnJvcj86IGFueSB9LFxuPihyZXNvdXJjZTogVCwgcmV2aXZlcnM6IFJldml2ZXJzKTogVCB7XG4gIGxldCBoeWRyYXRlZElucHV0ID0gcmVzb3VyY2UuaW5wdXQ7XG4gIGxldCBoeWRyYXRlZE91dHB1dCA9IHJlc291cmNlLm91dHB1dDtcbiAgbGV0IGh5ZHJhdGVkRXJyb3IgPSByZXNvdXJjZS5lcnJvcjtcblxuICBpZiAocmVzb3VyY2UuaW5wdXQgIT0gbnVsbCkge1xuICAgIHRyeSB7XG4gICAgICBoeWRyYXRlZElucHV0ID0gaHlkcmF0ZURhdGEocmVzb3VyY2UuaW5wdXQsIHJldml2ZXJzKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIExlYXZlIHVuLWh5ZHJhdGVkXG4gICAgfVxuICB9XG5cbiAgaWYgKHJlc291cmNlLm91dHB1dCAhPSBudWxsKSB7XG4gICAgdHJ5IHtcbiAgICAgIGh5ZHJhdGVkT3V0cHV0ID0gaHlkcmF0ZURhdGEocmVzb3VyY2Uub3V0cHV0LCByZXZpdmVycyk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBMZWF2ZSB1bi1oeWRyYXRlZFxuICAgIH1cbiAgfVxuXG4gIC8vIFRoZSBgZXJyb3JgIGZpZWxkIGlzIGBTZXJpYWxpemVkRGF0YWAgKFVpbnQ4QXJyYXkpIHByb2R1Y2VkIGJ5XG4gIC8vIGBkZWh5ZHJhdGVSdW5FcnJvcmAuIEh5ZHJhdGUgaXQgc28gb2JzZXJ2YWJpbGl0eSB0b29scyAoQ0xJLCB3ZWIgVUkpXG4gIC8vIGNhbiByZWFkIGBydW4uZXJyb3IubWVzc2FnZWAsIGBydW4uZXJyb3Iuc3RhY2tgLCBldGMuXG4gIGlmIChyZXNvdXJjZS5lcnJvciAhPSBudWxsKSB7XG4gICAgdHJ5IHtcbiAgICAgIGh5ZHJhdGVkRXJyb3IgPSBoeWRyYXRlRGF0YShyZXNvdXJjZS5lcnJvciwgcmV2aXZlcnMpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gTGVhdmUgdW4taHlkcmF0ZWRcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC4uLnJlc291cmNlLFxuICAgIGlucHV0OiBoeWRyYXRlZElucHV0LFxuICAgIG91dHB1dDogaHlkcmF0ZWRPdXRwdXQsXG4gICAgZXJyb3I6IGh5ZHJhdGVkRXJyb3IsXG4gIH07XG59XG5cbi8qKlxuICogSHlkcmF0ZSB0aGUgZXZlbnREYXRhIGZpZWxkcyBvZiBhbiBldmVudCByZXNvdXJjZS5cbiAqL1xuZnVuY3Rpb24gaHlkcmF0ZUV2ZW50RGF0YTxcbiAgVCBleHRlbmRzIHsgZXZlbnRJZD86IHN0cmluZzsgZXZlbnRUeXBlPzogc3RyaW5nOyBldmVudERhdGE/OiBhbnkgfSxcbj4ocmVzb3VyY2U6IFQsIHJldml2ZXJzOiBSZXZpdmVycyk6IFQge1xuICBpZiAoIXJlc291cmNlLmV2ZW50RGF0YSkgcmV0dXJuIHJlc291cmNlO1xuXG4gIGNvbnN0IGV2ZW50RGF0YSA9IHsgLi4ucmVzb3VyY2UuZXZlbnREYXRhIH07XG5cbiAgZm9yIChjb25zdCBmaWVsZCBvZiBnZXRFdmVudERhdGFSZWZGaWVsZHMocmVzb3VyY2UuZXZlbnRUeXBlID8/ICcnKSkge1xuICAgIGlmIChldmVudERhdGFbZmllbGRdID09IG51bGwpIGNvbnRpbnVlO1xuICAgIHRyeSB7XG4gICAgICBldmVudERhdGFbZmllbGRdID0gaHlkcmF0ZURhdGEoZXZlbnREYXRhW2ZpZWxkXSwgcmV2aXZlcnMpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gTGVhdmUgdW4taHlkcmF0ZWRcbiAgICB9XG4gIH1cblxuICByZXR1cm4geyAuLi5yZXNvdXJjZSwgZXZlbnREYXRhIH07XG59XG5cbi8qKlxuICogSHlkcmF0ZSB0aGUgbWV0YWRhdGEgZmllbGQgb2YgYSBob29rIHJlc291cmNlLlxuICovXG5mdW5jdGlvbiBoeWRyYXRlSG9va01ldGFkYXRhPFQgZXh0ZW5kcyB7IGhvb2tJZD86IHN0cmluZzsgbWV0YWRhdGE/OiBhbnkgfT4oXG4gIHJlc291cmNlOiBULFxuICByZXZpdmVyczogUmV2aXZlcnNcbik6IFQge1xuICBpZiAocmVzb3VyY2UubWV0YWRhdGEgPT0gbnVsbCkgcmV0dXJuIHJlc291cmNlO1xuXG4gIGxldCBoeWRyYXRlZE1ldGFkYXRhID0gcmVzb3VyY2UubWV0YWRhdGE7XG4gIHRyeSB7XG4gICAgaHlkcmF0ZWRNZXRhZGF0YSA9IGh5ZHJhdGVEYXRhKHJlc291cmNlLm1ldGFkYXRhLCByZXZpdmVycyk7XG4gIH0gY2F0Y2gge1xuICAgIC8vIExlYXZlIHVuLWh5ZHJhdGVkXG4gIH1cblxuICByZXR1cm4geyAuLi5yZXNvdXJjZSwgbWV0YWRhdGE6IGh5ZHJhdGVkTWV0YWRhdGEgfTtcbn1cblxuLyoqXG4gKiBIeWRyYXRlIHRoZSBzZXJpYWxpemVkIGRhdGEgZmllbGRzIG9mIGFueSByZXNvdXJjZSBmb3IgbzExeSBkaXNwbGF5LlxuICpcbiAqIERpc3BhdGNoZXMgYnkgcmVzb3VyY2UgdHlwZSAoc3RlcCwgaG9vaywgZXZlbnQsIHdvcmtmbG93KSBhbmQgY2FsbHNcbiAqIGBoeWRyYXRlRGF0YWAgd2l0aCB0aGUgcHJvdmlkZWQgcmV2aXZlcnMgZm9yIGVhY2ggZGF0YSBmaWVsZC5cbiAqXG4gKiBFYWNoIGVudmlyb25tZW50ICh3ZWIsIENMSSkgcHJvdmlkZXMgaXRzIG93biByZXZpdmVyczsgdGhpcyBmdW5jdGlvblxuICogb25seSBoYW5kbGVzIHRoZSBkaXNwYXRjaCBsb2dpYyBhbmQgZmllbGQgbWFwcGluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGh5ZHJhdGVSZXNvdXJjZUlPPFxuICBUIGV4dGVuZHMge1xuICAgIHN0ZXBJZD86IHN0cmluZztcbiAgICBob29rSWQ/OiBzdHJpbmc7XG4gICAgZXZlbnRJZD86IHN0cmluZztcbiAgICBldmVudFR5cGU/OiBzdHJpbmc7XG4gICAgaW5wdXQ/OiBhbnk7XG4gICAgb3V0cHV0PzogYW55O1xuICAgIG1ldGFkYXRhPzogYW55O1xuICAgIGV2ZW50RGF0YT86IGFueTtcbiAgICBleGVjdXRpb25Db250ZXh0PzogYW55O1xuICB9LFxuPihyZXNvdXJjZTogVCwgcmV2aXZlcnM6IFJldml2ZXJzKTogVCB7XG4gIGlmICghcmVzb3VyY2UpIHJldHVybiByZXNvdXJjZTtcblxuICBsZXQgaHlkcmF0ZWQ6IFQ7XG4gIGlmICgnc3RlcElkJyBpbiByZXNvdXJjZSkge1xuICAgIGh5ZHJhdGVkID0gaHlkcmF0ZVN0ZXBJTyhyZXNvdXJjZSwgcmV2aXZlcnMpO1xuICB9IGVsc2UgaWYgKCdob29rSWQnIGluIHJlc291cmNlKSB7XG4gICAgaHlkcmF0ZWQgPSBoeWRyYXRlSG9va01ldGFkYXRhKHJlc291cmNlLCByZXZpdmVycyk7XG4gIH0gZWxzZSBpZiAoJ2V2ZW50SWQnIGluIHJlc291cmNlKSB7XG4gICAgaHlkcmF0ZWQgPSBoeWRyYXRlRXZlbnREYXRhKHJlc291cmNlLCByZXZpdmVycyk7XG4gIH0gZWxzZSB7XG4gICAgaHlkcmF0ZWQgPSBoeWRyYXRlV29ya2Zsb3dJTyhyZXNvdXJjZSwgcmV2aXZlcnMpO1xuICB9XG5cbiAgLy8gU3RyaXAgZXhlY3V0aW9uQ29udGV4dCwgcHJlc2VydmluZyBvbmx5IHdvcmtmbG93Q29yZVZlcnNpb24gZm9yIGRpc3BsYXlcbiAgaWYgKCdleGVjdXRpb25Db250ZXh0JyBpbiBoeWRyYXRlZCkge1xuICAgIGNvbnN0IHsgZXhlY3V0aW9uQ29udGV4dCwgLi4ucmVzdCB9ID0gaHlkcmF0ZWQ7XG4gICAgY29uc3Qgd29ya2Zsb3dDb3JlVmVyc2lvbiA9XG4gICAgICBleGVjdXRpb25Db250ZXh0ICYmXG4gICAgICB0eXBlb2YgZXhlY3V0aW9uQ29udGV4dCA9PT0gJ29iamVjdCcgJiZcbiAgICAgICd3b3JrZmxvd0NvcmVWZXJzaW9uJyBpbiBleGVjdXRpb25Db250ZXh0XG4gICAgICAgID8gZXhlY3V0aW9uQ29udGV4dC53b3JrZmxvd0NvcmVWZXJzaW9uXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgIGlmICh3b3JrZmxvd0NvcmVWZXJzaW9uKSB7XG4gICAgICByZXR1cm4geyAuLi5yZXN0LCB3b3JrZmxvd0NvcmVWZXJzaW9uIH0gYXMgdW5rbm93biBhcyBUO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdCBhcyBUO1xuICB9XG5cbiAgcmV0dXJuIGh5ZHJhdGVkO1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFV0aWxpdHkgZnVuY3Rpb25zXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLyoqIEV4dHJhY3QgYWxsIHN0cmVhbSBJRHMgZnJvbSBhIHZhbHVlIChyZWN1cnNpdmVseSB0cmF2ZXJzZXMgb2JqZWN0cy9hcnJheXMpICovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdFN0cmVhbUlkcyhvYmo6IHVua25vd24pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHN0cmVhbUlkczogc3RyaW5nW10gPSBbXTtcbiAgLy8gVGhlIGh5ZHJhdGVkIG8xMXkgZGF0YSB0aGlzIHdhbGtzIGNvbWVzIGZyb20gZGV2YWx1ZSwgd2hpY2ggc3VwcG9ydHNcbiAgLy8gY2lyY3VsYXIgYW5kIHJlcGVhdGVkIHJlZmVyZW5jZXMuIFRyYWNrIHZpc2l0ZWQgY29udGFpbmVycyBzbyBhIGN5Y2xlXG4gIC8vIChlLmcuIGEgc3RlcCByZXN1bHQgd2hvc2Ugb2JqZWN0IHJlZmVycyBiYWNrIHRvIGl0c2VsZikgZG9lc24ndCByZWN1cnNlXG4gIC8vIGZvcmV2ZXIgYW5kIG92ZXJmbG93IHRoZSBzdGFjay5cbiAgY29uc3Qgc2VlbiA9IG5ldyBXZWFrU2V0PG9iamVjdD4oKTtcblxuICBmdW5jdGlvbiB0cmF2ZXJzZSh2YWx1ZTogdW5rbm93bik6IHZvaWQge1xuICAgIGlmIChpc1N0cmVhbUlkKHZhbHVlKSkge1xuICAgICAgc3RyZWFtSWRzLnB1c2godmFsdWUgYXMgc3RyaW5nKTtcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICBpZiAoc2Vlbi5oYXModmFsdWUpKSByZXR1cm47XG4gICAgICBzZWVuLmFkZCh2YWx1ZSk7XG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgdmFsdWUpIHtcbiAgICAgICAgdHJhdmVyc2UoaXRlbSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICBpZiAoc2Vlbi5oYXModmFsdWUpKSByZXR1cm47XG4gICAgICBzZWVuLmFkZCh2YWx1ZSk7XG4gICAgICBmb3IgKGNvbnN0IHZhbCBvZiBPYmplY3QudmFsdWVzKHZhbHVlKSkge1xuICAgICAgICB0cmF2ZXJzZSh2YWwpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHRyYXZlcnNlKG9iaik7XG4gIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQoc3RyZWFtSWRzKSk7XG59XG5cbi8qKiBUcnVuY2F0ZSBhIHN0cmluZyB0byBhIG1heGltdW0gbGVuZ3RoLCBhZGRpbmcgZWxsaXBzaXMgaWYgbmVlZGVkICovXG5leHBvcnQgZnVuY3Rpb24gdHJ1bmNhdGVJZChpZDogc3RyaW5nLCBtYXhMZW5ndGggPSAxMik6IHN0cmluZyB7XG4gIGlmIChpZC5sZW5ndGggPD0gbWF4TGVuZ3RoKSByZXR1cm4gaWQ7XG4gIHJldHVybiBgJHtpZC5zbGljZSgwLCBtYXhMZW5ndGgpfS4uLmA7XG59XG4iXX0=