@cartanova/qgrid-cli 2.10.9 → 2.11.0

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 (318) hide show
  1. package/bundle/dist/_virtual/_rolldown/runtime.js +1 -10
  2. package/bundle/dist/application/monit/log-buffer.js +12 -6
  3. package/bundle/dist/application/monit/monit.frame.js +11 -3
  4. package/bundle/dist/application/monit/monit.types.js +1 -1
  5. package/bundle/dist/application/qgrid/conv-routing.js +9 -6
  6. package/bundle/dist/application/qgrid/expired-token-reminder.js +2 -2
  7. package/bundle/dist/application/qgrid/oauth.js +31 -4
  8. package/bundle/dist/application/qgrid/qgrid-image-generation.js +1 -1
  9. package/bundle/dist/application/qgrid/qgrid-response-format.js +22 -20
  10. package/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +43 -34
  11. package/bundle/dist/application/qgrid/qgrid.dispatcher.js +128 -93
  12. package/bundle/dist/application/qgrid/qgrid.frame.js +930 -49
  13. package/bundle/dist/application/qgrid/qgrid.types.js +212 -5
  14. package/bundle/dist/application/qgrid/schema-prompt.js +75 -48
  15. package/bundle/dist/application/qgrid/slack-user-map.js +1 -1
  16. package/bundle/dist/application/qgrid/token-death.js +1 -1
  17. package/bundle/dist/application/qgrid/token-subscriber.js +83 -30
  18. package/bundle/dist/application/qgrid/token-trigger-setup.js +1 -1
  19. package/bundle/dist/application/qgrid/token-window-keepalive.js +8 -6
  20. package/bundle/dist/application/qgrid/tool-emulation-schema.js +13 -13
  21. package/bundle/dist/application/qgrid/tool-emulation.js +19 -15
  22. package/bundle/dist/application/request-log/json-schema-type-text.js +29 -12
  23. package/bundle/dist/application/request-log/request-log.model.js +83 -69
  24. package/bundle/dist/application/request-log/request-log.types.js +8 -2
  25. package/bundle/dist/application/request-log/zod-code-format.js +1 -1
  26. package/bundle/dist/application/request-log-step/request-log-step.model.js +1 -1
  27. package/bundle/dist/application/request-log-step/request-log-step.types.js +1 -1
  28. package/bundle/dist/application/setting/setting.constant.js +1 -1
  29. package/bundle/dist/application/setting/setting.model.js +2 -2
  30. package/bundle/dist/application/setting/setting.store.js +2 -2
  31. package/bundle/dist/application/setting/setting.types.js +1 -1
  32. package/bundle/dist/application/sonamu.generated.js +40 -16
  33. package/bundle/dist/application/sonamu.generated.sso.js +2 -1
  34. package/bundle/dist/application/token/token.model.js +26 -9
  35. package/bundle/dist/application/token/token.types.js +20 -3
  36. package/bundle/dist/i18n/en.js +15 -1
  37. package/bundle/dist/i18n/ko.js +15 -1
  38. package/bundle/dist/i18n/sd.generated.js +2 -1
  39. package/bundle/dist/migrations/20260807133553_manual__backfill_request_log_cost.js +8 -6
  40. package/bundle/dist/migrations/20261018215031_alter_request_logs_add1_alter1.js +15 -0
  41. package/bundle/dist/server-bootstrap.js +4 -2
  42. package/bundle/dist/server-error-handler.js +1 -1
  43. package/bundle/dist/sonamu.config.js +37 -8
  44. package/bundle/dist/startup-migrations.js +17 -7
  45. package/bundle/dist/testing/global.js +1 -1
  46. package/bundle/dist/testing/schema-bench.js +0 -0
  47. package/bundle/dist/testing/test-database-name.js +1 -1
  48. package/bundle/dist/utils/providers/anthropic/anthropic-constants.js +1 -1
  49. package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +11 -5
  50. package/bundle/dist/utils/providers/anthropic/anthropic-quota.js +4 -4
  51. package/bundle/dist/utils/providers/anthropic/anthropic-thinking.js +1 -1
  52. package/bundle/dist/utils/providers/anthropic/claude-session.js +20 -19
  53. package/bundle/dist/utils/providers/anthropic/fence-strip.js +1 -1
  54. package/bundle/dist/utils/providers/anthropic/stream-json-adapter.js +49 -23
  55. package/bundle/dist/utils/providers/common/credentials.js +5 -1
  56. package/bundle/dist/utils/providers/common/effort.js +3 -3
  57. package/bundle/dist/utils/providers/common/model-cost.js +69 -14
  58. package/bundle/dist/utils/providers/common/provider-types.js +29 -1
  59. package/bundle/dist/utils/providers/common/schema-validation.js +78 -40
  60. package/bundle/dist/utils/providers/common/smooth-weighted-round-robin.js +1 -1
  61. package/bundle/dist/utils/providers/common/strictifier.js +62 -43
  62. package/bundle/dist/utils/providers/common/thinking.js +3 -2
  63. package/bundle/dist/utils/providers/common/ttft.js +1 -1
  64. package/bundle/dist/utils/providers/grok/grok-backend-protocol.js +427 -0
  65. package/bundle/dist/utils/providers/grok/grok-constants.js +55 -0
  66. package/bundle/dist/utils/providers/grok/grok-direct-client.js +196 -0
  67. package/bundle/dist/utils/providers/grok/grok-dispatcher.js +1313 -0
  68. package/bundle/dist/utils/providers/grok/grok-headers.js +118 -0
  69. package/bundle/dist/utils/providers/grok/grok-media-client.js +420 -0
  70. package/bundle/dist/utils/providers/grok/grok-models.js +114 -0
  71. package/bundle/dist/utils/providers/grok/grok-oauth.js +455 -0
  72. package/bundle/dist/utils/providers/grok/grok-quota.js +119 -0
  73. package/bundle/dist/utils/providers/grok/grok-refresh.js +192 -0
  74. package/bundle/dist/utils/providers/grok/grok-types.js +186 -0
  75. package/bundle/dist/utils/providers/grok/grok-voice-client.js +199 -0
  76. package/bundle/dist/utils/providers/grok/index.js +11 -0
  77. package/bundle/dist/utils/providers/openai/openai-backend-protocol.js +111 -83
  78. package/bundle/dist/utils/providers/openai/openai-callback-relay.js +3 -2
  79. package/bundle/dist/utils/providers/openai/openai-constants.js +1 -1
  80. package/bundle/dist/utils/providers/openai/openai-direct-client.js +23 -7
  81. package/bundle/dist/utils/providers/openai/openai-dispatcher.js +143 -106
  82. package/bundle/dist/utils/providers/openai/openai-image-generation.js +48 -33
  83. package/bundle/dist/utils/providers/openai/openai-oauth.js +28 -13
  84. package/bundle/dist/utils/providers/openai/openai-quota.js +38 -27
  85. package/bundle/dist/utils/providers/openai/openai-refresh.js +17 -9
  86. package/bundle/dist/utils/providers/openai/openai-sse.js +1 -1
  87. package/bundle/dist/utils/providers/openai/openai-transport-config.js +1 -1
  88. package/bundle/dist/utils/quiet-hours.js +1 -1
  89. package/bundle/dist/utils/slack-notify.js +14 -8
  90. package/bundle/dist/utils/subset-loaders.js +4 -5
  91. package/bundle/src/application/monit/log-buffer.ts +23 -9
  92. package/bundle/src/application/monit/monit.frame.ts +22 -5
  93. package/bundle/src/application/monit/monit.types.ts +6 -0
  94. package/bundle/src/application/qgrid/conv-routing.test.ts +76 -4
  95. package/bundle/src/application/qgrid/conv-routing.ts +35 -9
  96. package/bundle/src/application/qgrid/expired-token-reminder.ts +9 -1
  97. package/bundle/src/application/qgrid/oauth.ts +51 -15
  98. package/bundle/src/application/qgrid/qgrid-image-generation.ts +9 -0
  99. package/bundle/src/application/qgrid/qgrid-response-format.ts +50 -25
  100. package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +33 -0
  101. package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +87 -40
  102. package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +97 -0
  103. package/bundle/src/application/qgrid/qgrid.dispatcher.ts +274 -126
  104. package/bundle/src/application/qgrid/qgrid.frame.test.ts +1013 -3
  105. package/bundle/src/application/qgrid/qgrid.frame.ts +1415 -60
  106. package/bundle/src/application/qgrid/qgrid.types.ts +335 -0
  107. package/bundle/src/application/qgrid/schema-prompt.ts +105 -41
  108. package/bundle/src/application/qgrid/slack-user-map.ts +5 -0
  109. package/bundle/src/application/qgrid/token-death.ts +4 -0
  110. package/bundle/src/application/qgrid/token-subscriber.test.ts +21 -19
  111. package/bundle/src/application/qgrid/token-subscriber.ts +186 -53
  112. package/bundle/src/application/qgrid/token-trigger-setup.ts +2 -0
  113. package/bundle/src/application/qgrid/token-window-keepalive.ts +49 -6
  114. package/bundle/src/application/qgrid/tool-emulation-schema.ts +33 -29
  115. package/bundle/src/application/qgrid/tool-emulation.ts +52 -27
  116. package/bundle/src/application/request-log/json-schema-type-text.test.ts +5 -5
  117. package/bundle/src/application/request-log/json-schema-type-text.ts +81 -26
  118. package/bundle/src/application/request-log/request-log.entity.json +8 -0
  119. package/bundle/src/application/request-log/request-log.model.test.ts +111 -4
  120. package/bundle/src/application/request-log/request-log.model.ts +279 -145
  121. package/bundle/src/application/request-log/request-log.types.ts +17 -0
  122. package/bundle/src/application/request-log/zod-code-format.ts +11 -0
  123. package/bundle/src/application/request-log-step/request-log-step.model.ts +1 -0
  124. package/bundle/src/application/request-log-step/request-log-step.types.ts +2 -0
  125. package/bundle/src/application/setting/setting.constant.ts +9 -0
  126. package/bundle/src/application/setting/setting.model.ts +12 -2
  127. package/bundle/src/application/setting/setting.store.ts +5 -1
  128. package/bundle/src/application/setting/setting.types.ts +8 -0
  129. package/bundle/src/application/sonamu.generated.http +135 -0
  130. package/bundle/src/application/sonamu.generated.sso.ts +3 -0
  131. package/bundle/src/application/sonamu.generated.ts +29 -0
  132. package/bundle/src/application/token/token.identity.test.ts +20 -0
  133. package/bundle/src/application/token/token.model.ts +66 -7
  134. package/bundle/src/application/token/token.types.ts +24 -1
  135. package/bundle/src/i18n/en.ts +19 -0
  136. package/bundle/src/i18n/ko.ts +21 -0
  137. package/bundle/src/i18n/sd.generated.ts +24 -2
  138. package/bundle/src/migrations/20260807133553_manual__backfill_request_log_cost.ts +16 -8
  139. package/bundle/src/migrations/20261018215031_alter_request_logs_add1_alter1.ts +15 -0
  140. package/bundle/src/server-bootstrap.ts +4 -2
  141. package/bundle/src/server-error-handler.ts +1 -0
  142. package/bundle/src/sonamu.config.ts +69 -7
  143. package/bundle/src/startup-migrations.ts +27 -9
  144. package/bundle/src/testing/global.ts +20 -0
  145. package/bundle/src/testing/schema-bench.ts +105 -30
  146. package/bundle/src/testing/test-database-name.ts +2 -0
  147. package/bundle/src/utils/providers/anthropic/anthropic-constants.ts +8 -0
  148. package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.ts +41 -6
  149. package/bundle/src/utils/providers/anthropic/anthropic-quota.ts +7 -3
  150. package/bundle/src/utils/providers/anthropic/anthropic-thinking.ts +6 -0
  151. package/bundle/src/utils/providers/anthropic/claude-session.ts +58 -24
  152. package/bundle/src/utils/providers/anthropic/fence-strip.ts +11 -0
  153. package/bundle/src/utils/providers/anthropic/stream-json-adapter.ts +110 -45
  154. package/bundle/src/utils/providers/common/credentials.ts +8 -0
  155. package/bundle/src/utils/providers/common/effort.ts +9 -2
  156. package/bundle/src/utils/providers/common/model-cost.test.ts +48 -1
  157. package/bundle/src/utils/providers/common/model-cost.ts +259 -158
  158. package/bundle/src/utils/providers/common/provider-dispatcher.ts +98 -2
  159. package/bundle/src/utils/providers/common/provider-types.ts +46 -3
  160. package/bundle/src/utils/providers/common/schema-validation.test.ts +5 -1
  161. package/bundle/src/utils/providers/common/schema-validation.ts +124 -56
  162. package/bundle/src/utils/providers/common/smooth-weighted-round-robin.ts +4 -0
  163. package/bundle/src/utils/providers/common/strictifier.ts +185 -59
  164. package/bundle/src/utils/providers/common/thinking.ts +2 -2
  165. package/bundle/src/utils/providers/common/ttft.ts +4 -2
  166. package/bundle/src/utils/providers/grok/__fixtures__/golden-responses-1.0.60.json +164 -0
  167. package/bundle/src/utils/providers/grok/grok-backend-protocol.test.ts +325 -0
  168. package/bundle/src/utils/providers/grok/grok-backend-protocol.ts +721 -0
  169. package/bundle/src/utils/providers/grok/grok-constants.ts +105 -0
  170. package/bundle/src/utils/providers/grok/grok-direct-client.test.ts +179 -0
  171. package/bundle/src/utils/providers/grok/grok-direct-client.ts +313 -0
  172. package/bundle/src/utils/providers/grok/grok-dispatcher.test.ts +1395 -0
  173. package/bundle/src/utils/providers/grok/grok-dispatcher.ts +2105 -0
  174. package/bundle/src/utils/providers/grok/grok-headers.test.ts +149 -0
  175. package/bundle/src/utils/providers/grok/grok-headers.ts +199 -0
  176. package/bundle/src/utils/providers/grok/grok-media-client.test.ts +446 -0
  177. package/bundle/src/utils/providers/grok/grok-media-client.ts +703 -0
  178. package/bundle/src/utils/providers/grok/grok-models.test.ts +96 -0
  179. package/bundle/src/utils/providers/grok/grok-models.ts +161 -0
  180. package/bundle/src/utils/providers/grok/grok-oauth.test.ts +406 -0
  181. package/bundle/src/utils/providers/grok/grok-oauth.ts +771 -0
  182. package/bundle/src/utils/providers/grok/grok-quota.test.ts +142 -0
  183. package/bundle/src/utils/providers/grok/grok-quota.ts +198 -0
  184. package/bundle/src/utils/providers/grok/grok-refresh.test.ts +239 -0
  185. package/bundle/src/utils/providers/grok/grok-refresh.ts +325 -0
  186. package/bundle/src/utils/providers/grok/grok-types.test.ts +252 -0
  187. package/bundle/src/utils/providers/grok/grok-types.ts +374 -0
  188. package/bundle/src/utils/providers/grok/grok-voice-client.test.ts +321 -0
  189. package/bundle/src/utils/providers/grok/grok-voice-client.ts +284 -0
  190. package/bundle/src/utils/providers/grok/index.ts +20 -0
  191. package/bundle/src/utils/providers/openai/openai-backend-protocol.ts +221 -137
  192. package/bundle/src/utils/providers/openai/openai-callback-relay.ts +12 -1
  193. package/bundle/src/utils/providers/openai/openai-constants.ts +2 -0
  194. package/bundle/src/utils/providers/openai/openai-direct-client.ts +111 -21
  195. package/bundle/src/utils/providers/openai/openai-dispatcher.ts +322 -169
  196. package/bundle/src/utils/providers/openai/openai-image-generation.ts +116 -36
  197. package/bundle/src/utils/providers/openai/openai-oauth.ts +48 -20
  198. package/bundle/src/utils/providers/openai/openai-quota.ts +77 -46
  199. package/bundle/src/utils/providers/openai/openai-refresh.ts +42 -18
  200. package/bundle/src/utils/providers/openai/openai-sse.ts +27 -3
  201. package/bundle/src/utils/providers/openai/openai-transport-config.ts +2 -0
  202. package/bundle/src/utils/quiet-hours.ts +12 -1
  203. package/bundle/src/utils/slack-notify.ts +44 -13
  204. package/bundle/src/utils/subset-loaders.ts +7 -7
  205. package/bundle/web-dist/client/assets/clsx-5XM_pHvN.js +1 -0
  206. package/bundle/web-dist/client/assets/index-BA7uQ-6c.js +31 -0
  207. package/bundle/web-dist/client/assets/index-Be2qCZmI.css +1 -0
  208. package/bundle/web-dist/client/assets/logs-C47OJGEI.js +1 -0
  209. package/bundle/web-dist/client/assets/monit-BS9no0dU.js +4 -0
  210. package/bundle/web-dist/client/assets/plus-sdACTfH0.js +1 -0
  211. package/bundle/web-dist/client/assets/refresh-cw-CY8o_1cT.js +1 -0
  212. package/bundle/web-dist/client/assets/request-model-BRtFuZvj.js +1 -0
  213. package/bundle/web-dist/client/assets/routes-kqgkUxE8.js +5 -0
  214. package/bundle/web-dist/client/assets/{services.generated-BsieU37H.js → services.generated-CefiDXEv.js} +5 -5
  215. package/bundle/web-dist/client/assets/settings-DNDvFGSw.js +1 -0
  216. package/bundle/web-dist/client/assets/show-u8Np69q3.js +2 -0
  217. package/bundle/web-dist/client/assets/tokens-QvP410NW.js +1 -0
  218. package/bundle/web-dist/client/assets/total-cost-MnfKU8IN.js +1 -0
  219. package/bundle/web-dist/client/assets/use-oauth-login-flow-Bzdh28Ws.js +1 -0
  220. package/bundle/web-dist/client/assets/use-update-token-mutation-CfJKaxmR.js +1 -0
  221. package/bundle/web-dist/client/assets/vendor-react-CUFFrVN9.js +244 -0
  222. package/bundle/web-dist/client/assets/vendor-tanstack-Bf_jag9G.js +1 -0
  223. package/bundle/web-dist/client/index.html +6 -6
  224. package/bundle/web-dist/server/assets/clsx-D_N5PN_2.js +16 -0
  225. package/bundle/web-dist/server/assets/{lazyRouteComponent-Dtd0NR4r.js → lazyRouteComponent-D8iTIHyn.js} +129 -2
  226. package/bundle/web-dist/server/assets/logs-B3OTd9hy.js +825 -0
  227. package/bundle/web-dist/server/assets/{monit-DvzribSE.js → monit-B2hqorPe.js} +385 -126
  228. package/bundle/web-dist/server/assets/plus-DwG7h9kq.js +28 -0
  229. package/bundle/web-dist/server/assets/{react-dom-B4a6-uuR.js → react-dom-BIYQzBqG.js} +2 -129
  230. package/bundle/web-dist/server/assets/refresh-cw-mMBkwOq0.js +44 -0
  231. package/bundle/web-dist/server/assets/{request-model-CbqfnQOJ.js → request-model-I6OdODSH.js} +15 -6
  232. package/bundle/web-dist/server/assets/{routes-BAPWTizT.js → routes-B95YlUv2.js} +760 -213
  233. package/bundle/web-dist/server/assets/{services.generated-CEbGjsI0.js → services.generated-DQATJ6qf.js} +12821 -12194
  234. package/bundle/web-dist/server/assets/settings-C3gbGk0m.js +830 -0
  235. package/bundle/web-dist/server/assets/{show-CxVZTAdv.js → show-Bxaj3rhH.js} +1355 -419
  236. package/bundle/web-dist/server/assets/tokens-CZjH3cB7.js +1038 -0
  237. package/bundle/web-dist/server/assets/total-cost-fTE9Xy82.js +18 -0
  238. package/bundle/web-dist/server/assets/use-oauth-login-flow-CKDHgc3U.js +2379 -0
  239. package/bundle/web-dist/server/assets/{use-update-token-mutation-CfYmk_4_.js → use-update-token-mutation-BEbgOzaa.js} +1 -1
  240. package/bundle/web-dist/server/entry-server.generated.js +4303 -22810
  241. package/dist/cli.js +9 -9
  242. package/package.json +4 -11
  243. package/postinstall.mjs +12 -0
  244. package/skills/qgrid/SKILL.md +1 -0
  245. package/skills/qgrid/references/cli-env-and-server-boot.md +4 -1
  246. package/skills/qgrid/references/decision-rationale.md +24 -1
  247. package/skills/qgrid/references/grok-runtime.md +89 -0
  248. package/skills/qgrid/references/provider-runtime-differences.md +30 -29
  249. package/skills/qgrid/references/repo-map.md +10 -0
  250. package/skills/qgrid/references/request-log-run-lifecycle.md +1 -1
  251. package/skills/qgrid/references/sonamu-api-web-flow.md +1 -1
  252. package/skills/qgrid/references/token-auth-quota-lifecycle.md +56 -3
  253. package/bundle/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +0 -406
  254. package/bundle/dist/node_modules/.pnpm/@vitest_expect@4.1.10/node_modules/@vitest/expect/dist/index.js +0 -1507
  255. package/bundle/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.10/node_modules/@vitest/pretty-format/dist/index.js +0 -887
  256. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/chunk-artifact.js +0 -2756
  257. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/index.js +0 -8
  258. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/utils.js +0 -8
  259. package/bundle/dist/node_modules/.pnpm/@vitest_snapshot@4.1.10/node_modules/@vitest/snapshot/dist/index.js +0 -922
  260. package/bundle/dist/node_modules/.pnpm/@vitest_spy@4.1.10/node_modules/@vitest/spy/dist/index.js +0 -386
  261. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +0 -121
  262. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/constants.js +0 -51
  263. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/diff.js +0 -1317
  264. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/display.js +0 -561
  265. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/error.js +0 -40
  266. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/helpers.js +0 -272
  267. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/offset.js +0 -27
  268. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/serialize.js +0 -77
  269. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/source-map.js +0 -381
  270. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/timers.js +0 -51
  271. package/bundle/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +0 -2986
  272. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +0 -10
  273. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +0 -109
  274. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +0 -10
  275. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +0 -10
  276. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +0 -10
  277. package/bundle/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +0 -1126
  278. package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +0 -21
  279. package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +0 -432
  280. package/bundle/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +0 -517
  281. package/bundle/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +0 -101
  282. package/bundle/dist/node_modules/.pnpm/vite@8.0.3_@emnapi_core@1.11.2_@emnapi_runtime@1.11.2_@types_node@25.0.7_esbuild@0.27.4_5b35fc1fb85d2af4d105e0d74f940f50/node_modules/vite/dist/node/module-runner.js +0 -1265
  283. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +0 -9
  284. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/benchmark.CX_oY03V.js +0 -41
  285. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/evaluatedModules.Dg1zASAC.js +0 -19
  286. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/index.Chj8NDwU.js +0 -202
  287. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/index.DdgEv5B1.js +0 -46
  288. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +0 -119
  289. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/test.DNmyFkvJ.js +0 -3044
  290. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +0 -59
  291. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/index.js +0 -28
  292. package/bundle/dist/testing/setup-mocks.js +0 -16
  293. package/bundle/src/testing/setup-mocks.ts +0 -44
  294. package/bundle/web-dist/client/assets/index-Bw2s88Ot.css +0 -1
  295. package/bundle/web-dist/client/assets/index-CrXKu_J8.js +0 -106
  296. package/bundle/web-dist/client/assets/logs-B2SmWJXA.js +0 -1
  297. package/bundle/web-dist/client/assets/monit-D-JwXXoA.js +0 -1
  298. package/bundle/web-dist/client/assets/plus-B62CuqT8.js +0 -1
  299. package/bundle/web-dist/client/assets/refresh-cw-NNcU0Cmq.js +0 -1
  300. package/bundle/web-dist/client/assets/request-model-CojtinqK.js +0 -1
  301. package/bundle/web-dist/client/assets/routes-C5r4gTvY.js +0 -5
  302. package/bundle/web-dist/client/assets/settings-D3tDSAck.js +0 -1
  303. package/bundle/web-dist/client/assets/show-Cah_kUKC.js +0 -2
  304. package/bundle/web-dist/client/assets/tokens-DU2Iyxxd.js +0 -1
  305. package/bundle/web-dist/client/assets/use-oauth-login-flow-D0UaR9_e.js +0 -1
  306. package/bundle/web-dist/client/assets/use-update-token-mutation-DAq0F8p-.js +0 -1
  307. package/bundle/web-dist/client/assets/vendor-react-DH4kUfK2.js +0 -9
  308. package/bundle/web-dist/client/assets/vendor-tanstack-DJRQAbrY.js +0 -1
  309. package/bundle/web-dist/server/assets/logs-l91avYif.js +0 -509
  310. package/bundle/web-dist/server/assets/plus-KZrECewT.js +0 -19
  311. package/bundle/web-dist/server/assets/refresh-cw-BND93JrF.js +0 -23
  312. package/bundle/web-dist/server/assets/settings-BZR5HSAL.js +0 -461
  313. package/bundle/web-dist/server/assets/tokens-D1hb4eKk.js +0 -448
  314. package/bundle/web-dist/server/assets/use-oauth-login-flow-Cvdy0zF8.js +0 -178
  315. package/dist/cli.d.ts +0 -10
  316. /package/bundle/web-dist/client/assets/{cost-DH2jZbrw.js → cost-DB3HbU7T.js} +0 -0
  317. /package/bundle/web-dist/client/assets/{preload-helper-ca-nBW7U.js → preload-helper-DWTEM3RW.js} +0 -0
  318. /package/bundle/web-dist/server/assets/{cost-eEHeTRT5.js → cost-BC9yzyA9.js} +0 -0
@@ -1,1507 +0,0 @@
1
- import y from "../../../../../tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js";
2
- import { stringify } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/display.js";
3
- import { assertTypes, getType, isObject, noop, ordinal } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/helpers.js";
4
- import { diff, printDiffOrStringify } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/diff.js";
5
- import { processError } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/error.js";
6
- import { isMockFunction } from "../../../../../@vitest_spy@4.1.10/node_modules/@vitest/spy/dist/index.js";
7
- import { chai_exports, use, util as utils_exports } from "../../../../../chai@6.2.2/node_modules/chai/index.js";
8
- //#region ../../node_modules/.pnpm/@vitest+expect@4.1.10/node_modules/@vitest/expect/dist/index.js
9
- const ChaiStyleAssertions = (chai, utils) => {
10
- function defProperty(name, delegateTo) {
11
- utils.addProperty(chai.Assertion.prototype, name, function() {
12
- const jestMethod = chai.Assertion.prototype[delegateTo];
13
- if (!jestMethod) throw new Error(`Cannot delegate to ${String(delegateTo)}: method not found. Ensure JestChaiExpect plugin is loaded first.`);
14
- return jestMethod.call(this);
15
- });
16
- }
17
- function defPropertyWithArgs(name, delegateTo, ...args) {
18
- utils.addProperty(chai.Assertion.prototype, name, function() {
19
- const jestMethod = chai.Assertion.prototype[delegateTo];
20
- if (!jestMethod) throw new Error(`Cannot delegate to ${String(delegateTo)}: method not found. Ensure JestChaiExpect plugin is loaded first.`);
21
- return jestMethod.call(this, ...args);
22
- });
23
- }
24
- function defMethod(name, delegateTo) {
25
- utils.addMethod(chai.Assertion.prototype, name, function(...args) {
26
- const jestMethod = chai.Assertion.prototype[delegateTo];
27
- if (!jestMethod) throw new Error(`Cannot delegate to ${String(delegateTo)}: method not found. Ensure JestChaiExpect plugin is loaded first.`);
28
- return jestMethod.call(this, ...args);
29
- });
30
- }
31
- defProperty("called", "toHaveBeenCalled");
32
- defProperty("calledOnce", "toHaveBeenCalledOnce");
33
- defPropertyWithArgs("calledTwice", "toHaveBeenCalledTimes", 2);
34
- defPropertyWithArgs("calledThrice", "toHaveBeenCalledTimes", 3);
35
- defMethod("callCount", "toHaveBeenCalledTimes");
36
- defMethod("calledWith", "toHaveBeenCalledWith");
37
- defMethod("calledOnceWith", "toHaveBeenCalledExactlyOnceWith");
38
- defMethod("lastCalledWith", "toHaveBeenLastCalledWith");
39
- defMethod("nthCalledWith", "toHaveBeenNthCalledWith");
40
- defMethod("returned", "toHaveReturned");
41
- defMethod("returnedWith", "toHaveReturnedWith");
42
- defMethod("returnedTimes", "toHaveReturnedTimes");
43
- defMethod("lastReturnedWith", "toHaveLastReturnedWith");
44
- defMethod("nthReturnedWith", "toHaveNthReturnedWith");
45
- defMethod("calledBefore", "toHaveBeenCalledBefore");
46
- defMethod("calledAfter", "toHaveBeenCalledAfter");
47
- };
48
- const MATCHERS_OBJECT = Symbol.for("matchers-object");
49
- const JEST_MATCHERS_OBJECT = Symbol.for("$$jest-matchers-object");
50
- const GLOBAL_EXPECT = Symbol.for("expect-global");
51
- const ASYMMETRIC_MATCHERS_OBJECT = Symbol.for("asymmetric-matchers-object");
52
- const customMatchers = {
53
- toSatisfy(actual, expected, message) {
54
- const { printReceived, printExpected, matcherHint } = this.utils;
55
- const pass = expected(actual);
56
- return {
57
- pass,
58
- message: () => pass ? `\
59
- ${matcherHint(".not.toSatisfy", "received", "")}
60
-
61
- Expected value to not satisfy:
62
- ${message || printExpected(expected)}
63
- Received:
64
- ${printReceived(actual)}` : `\
65
- ${matcherHint(".toSatisfy", "received", "")}
66
-
67
- Expected value to satisfy:
68
- ${message || printExpected(expected)}
69
-
70
- Received:
71
- ${printReceived(actual)}`
72
- };
73
- },
74
- toBeOneOf(actual, expected) {
75
- const { equals, customTesters } = this;
76
- const { printReceived, printExpected, matcherHint } = this.utils;
77
- let pass;
78
- if (Array.isArray(expected)) pass = expected.length === 0 || expected.some((item) => equals(item, actual, customTesters));
79
- else if (expected instanceof Set) pass = expected.size === 0 || expected.has(actual) || [...expected].some((item) => equals(item, actual, customTesters));
80
- else throw new TypeError(`You must provide an array or set to ${matcherHint(".toBeOneOf")}, not '${typeof expected}'.`);
81
- return {
82
- pass,
83
- message: () => pass ? `\
84
- ${matcherHint(".not.toBeOneOf", "received", "")}
85
-
86
- Expected value to not be one of:
87
- ${printExpected(expected)}
88
- Received:
89
- ${printReceived(actual)}` : `\
90
- ${matcherHint(".toBeOneOf", "received", "")}
91
-
92
- Expected value to be one of:
93
- ${printExpected(expected)}
94
-
95
- Received:
96
- ${printReceived(actual)}`
97
- };
98
- }
99
- };
100
- const EXPECTED_COLOR = y.green;
101
- const RECEIVED_COLOR = y.red;
102
- const INVERTED_COLOR = y.inverse;
103
- const BOLD_WEIGHT = y.bold;
104
- const DIM_COLOR = y.dim;
105
- function matcherHint(matcherName, received = "received", expected = "expected", options = {}) {
106
- const { comment = "", isDirectExpectCall = false, isNot = false, promise = "", secondArgument = "", expectedColor = EXPECTED_COLOR, receivedColor = RECEIVED_COLOR, secondArgumentColor = EXPECTED_COLOR } = options;
107
- let hint = "";
108
- let dimString = "expect";
109
- if (!isDirectExpectCall && received !== "") {
110
- hint += DIM_COLOR(`${dimString}(`) + receivedColor(received);
111
- dimString = ")";
112
- }
113
- if (promise !== "") {
114
- hint += DIM_COLOR(`${dimString}.`) + promise;
115
- dimString = "";
116
- }
117
- if (isNot) {
118
- hint += `${DIM_COLOR(`${dimString}.`)}not`;
119
- dimString = "";
120
- }
121
- if (matcherName.includes(".")) dimString += matcherName;
122
- else {
123
- hint += DIM_COLOR(`${dimString}.`) + matcherName;
124
- dimString = "";
125
- }
126
- if (expected === "") dimString += "()";
127
- else {
128
- hint += DIM_COLOR(`${dimString}(`) + expectedColor(expected);
129
- if (secondArgument) hint += DIM_COLOR(", ") + secondArgumentColor(secondArgument);
130
- dimString = ")";
131
- }
132
- if (comment !== "") dimString += ` // ${comment}`;
133
- if (dimString !== "") hint += DIM_COLOR(dimString);
134
- return hint;
135
- }
136
- const SPACE_SYMBOL = "·";
137
- function replaceTrailingSpaces(text) {
138
- return text.replace(/\s+$/gm, (spaces) => SPACE_SYMBOL.repeat(spaces.length));
139
- }
140
- function printReceived(object) {
141
- return RECEIVED_COLOR(replaceTrailingSpaces(stringify(object)));
142
- }
143
- function printExpected(value) {
144
- return EXPECTED_COLOR(replaceTrailingSpaces(stringify(value)));
145
- }
146
- function getMatcherUtils() {
147
- return {
148
- EXPECTED_COLOR,
149
- RECEIVED_COLOR,
150
- INVERTED_COLOR,
151
- BOLD_WEIGHT,
152
- DIM_COLOR,
153
- diff,
154
- matcherHint,
155
- printReceived,
156
- printExpected,
157
- printDiffOrStringify,
158
- printWithType
159
- };
160
- }
161
- function printWithType(name, value, print) {
162
- const type = getType(value);
163
- return (type !== "null" && type !== "undefined" ? `${name} has type: ${type}\n` : "") + `${name} has value: ${print(value)}`;
164
- }
165
- function addCustomEqualityTesters(newTesters) {
166
- if (!Array.isArray(newTesters)) throw new TypeError(`expect.customEqualityTesters: Must be set to an array of Testers. Was given "${getType(newTesters)}"`);
167
- globalThis[JEST_MATCHERS_OBJECT].customEqualityTesters.push(...newTesters);
168
- }
169
- function getCustomEqualityTesters() {
170
- return globalThis[JEST_MATCHERS_OBJECT].customEqualityTesters;
171
- }
172
- function equals(a, b, customTesters, strictCheck) {
173
- customTesters = customTesters || [];
174
- return eq(a, b, [], [], customTesters, strictCheck ? hasKey : hasDefinedKey);
175
- }
176
- const functionToString = Function.prototype.toString;
177
- function isAsymmetric(obj) {
178
- return !!obj && typeof obj === "object" && "asymmetricMatch" in obj && isA("Function", obj.asymmetricMatch);
179
- }
180
- function hasAsymmetric(obj, seen = /* @__PURE__ */ new Set()) {
181
- if (seen.has(obj)) return false;
182
- seen.add(obj);
183
- if (isAsymmetric(obj)) return true;
184
- if (Array.isArray(obj)) return obj.some((i) => hasAsymmetric(i, seen));
185
- if (obj instanceof Set) return Array.from(obj).some((i) => hasAsymmetric(i, seen));
186
- if (isObject(obj)) return Object.values(obj).some((v) => hasAsymmetric(v, seen));
187
- return false;
188
- }
189
- function asymmetricMatch(a, b, customTesters) {
190
- const asymmetricA = isAsymmetric(a);
191
- const asymmetricB = isAsymmetric(b);
192
- if (asymmetricA && asymmetricB) return;
193
- if (asymmetricA) return a.asymmetricMatch(b, customTesters);
194
- if (asymmetricB) return b.asymmetricMatch(a, customTesters);
195
- }
196
- function isError(value) {
197
- if (typeof Error.isError === "function") return Error.isError(value);
198
- switch (Object.prototype.toString.call(value)) {
199
- case "[object Error]":
200
- case "[object Exception]":
201
- case "[object DOMException]": return true;
202
- default: return value instanceof Error;
203
- }
204
- }
205
- function eq(a, b, aStack, bStack, customTesters, hasKey) {
206
- let result = true;
207
- const asymmetricResult = asymmetricMatch(a, b, customTesters);
208
- if (asymmetricResult !== void 0) return asymmetricResult;
209
- const testerContext = { equals };
210
- for (let i = 0; i < customTesters.length; i++) {
211
- const customTesterResult = customTesters[i].call(testerContext, a, b, customTesters);
212
- if (customTesterResult !== void 0) return customTesterResult;
213
- }
214
- if (typeof URL === "function" && a instanceof URL && b instanceof URL) return a.href === b.href;
215
- if (Object.is(a, b)) return true;
216
- if (a === null || b === null) return a === b;
217
- const className = Object.prototype.toString.call(a);
218
- if (className !== Object.prototype.toString.call(b)) return false;
219
- switch (className) {
220
- case "[object Boolean]":
221
- case "[object String]":
222
- case "[object Number]": if (typeof a !== typeof b) return false;
223
- else if (typeof a !== "object" && typeof b !== "object") return Object.is(a, b);
224
- else return Object.is(a.valueOf(), b.valueOf());
225
- case "[object Date]": {
226
- const numA = +a;
227
- const numB = +b;
228
- return numA === numB || Number.isNaN(numA) && Number.isNaN(numB);
229
- }
230
- case "[object RegExp]": return a.source === b.source && a.flags === b.flags;
231
- case "[object Temporal.Instant]":
232
- case "[object Temporal.ZonedDateTime]":
233
- case "[object Temporal.PlainDateTime]":
234
- case "[object Temporal.PlainDate]":
235
- case "[object Temporal.PlainTime]":
236
- case "[object Temporal.PlainYearMonth]":
237
- case "[object Temporal.PlainMonthDay]": return a.equals(b);
238
- case "[object Temporal.Duration]": return a.toString() === b.toString();
239
- }
240
- if (typeof a !== "object" || typeof b !== "object") return false;
241
- if (isDomNode(a) && isDomNode(b)) return a.isEqualNode(b);
242
- let length = aStack.length;
243
- while (length--) if (aStack[length] === a) return bStack[length] === b;
244
- else if (bStack[length] === b) return false;
245
- aStack.push(a);
246
- bStack.push(b);
247
- if (className === "[object Array]" && a.length !== b.length) return false;
248
- if (isError(a) && isError(b)) try {
249
- return isErrorEqual(a, b, aStack, bStack, customTesters, hasKey);
250
- } finally {
251
- aStack.pop();
252
- bStack.pop();
253
- }
254
- const aKeys = keys(a, hasKey);
255
- let key;
256
- let size = aKeys.length;
257
- if (keys(b, hasKey).length !== size) return false;
258
- while (size--) {
259
- key = aKeys[size];
260
- result = hasKey(b, key) && eq(a[key], b[key], aStack, bStack, customTesters, hasKey);
261
- if (!result) return false;
262
- }
263
- aStack.pop();
264
- bStack.pop();
265
- return result;
266
- }
267
- function isErrorEqual(a, b, aStack, bStack, customTesters, hasKey) {
268
- let result = Object.prototype.toString.call(a) === Object.prototype.toString.call(b) && a.name === b.name && a.message === b.message;
269
- if (typeof b.cause !== "undefined") result &&= eq(a.cause, b.cause, aStack, bStack, customTesters, hasKey);
270
- if (a instanceof AggregateError && b instanceof AggregateError) result &&= eq(a.errors, b.errors, aStack, bStack, customTesters, hasKey);
271
- result &&= eq({ ...a }, { ...b }, aStack, bStack, customTesters, hasKey);
272
- return result;
273
- }
274
- function keys(obj, hasKey) {
275
- const keys = [];
276
- for (const key in obj) if (hasKey(obj, key)) keys.push(key);
277
- return keys.concat(Object.getOwnPropertySymbols(obj).filter((symbol) => Object.getOwnPropertyDescriptor(obj, symbol).enumerable));
278
- }
279
- function hasDefinedKey(obj, key) {
280
- return hasKey(obj, key) && obj[key] !== void 0;
281
- }
282
- function hasKey(obj, key) {
283
- return Object.hasOwn(obj, key);
284
- }
285
- function isA(typeName, value) {
286
- return Object.prototype.toString.apply(value) === `[object ${typeName}]`;
287
- }
288
- function isDomNode(obj) {
289
- return obj !== null && typeof obj === "object" && "nodeType" in obj && typeof obj.nodeType === "number" && "nodeName" in obj && typeof obj.nodeName === "string" && "isEqualNode" in obj && typeof obj.isEqualNode === "function";
290
- }
291
- function fnNameFor(func) {
292
- if (func.name) return func.name;
293
- const matches = functionToString.call(func).match(/^(?:async)?\s*function\s*(?:\*\s*)?([\w$]+)\s*\(/);
294
- return matches ? matches[1] : "<anonymous>";
295
- }
296
- function getPrototype(obj) {
297
- if (Object.getPrototypeOf) return Object.getPrototypeOf(obj);
298
- if (obj.constructor.prototype === obj) return null;
299
- return obj.constructor.prototype;
300
- }
301
- function hasProperty(obj, property) {
302
- if (!obj) return false;
303
- if (Object.hasOwn(obj, property)) return true;
304
- return hasProperty(getPrototype(obj), property);
305
- }
306
- const IS_KEYED_SENTINEL = "@@__IMMUTABLE_KEYED__@@";
307
- const IS_SET_SENTINEL = "@@__IMMUTABLE_SET__@@";
308
- const IS_LIST_SENTINEL = "@@__IMMUTABLE_LIST__@@";
309
- const IS_ORDERED_SENTINEL = "@@__IMMUTABLE_ORDERED__@@";
310
- const IS_RECORD_SYMBOL = "@@__IMMUTABLE_RECORD__@@";
311
- function isImmutableUnorderedKeyed(maybeKeyed) {
312
- return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL] && !maybeKeyed[IS_ORDERED_SENTINEL]);
313
- }
314
- function isImmutableUnorderedSet(maybeSet) {
315
- return !!(maybeSet && maybeSet[IS_SET_SENTINEL] && !maybeSet[IS_ORDERED_SENTINEL]);
316
- }
317
- function isObjectLiteral(source) {
318
- return source != null && typeof source === "object" && !Array.isArray(source);
319
- }
320
- function isImmutableList(source) {
321
- return Boolean(source && isObjectLiteral(source) && source[IS_LIST_SENTINEL]);
322
- }
323
- function isImmutableOrderedKeyed(source) {
324
- return Boolean(source && isObjectLiteral(source) && source[IS_KEYED_SENTINEL] && source[IS_ORDERED_SENTINEL]);
325
- }
326
- function isImmutableOrderedSet(source) {
327
- return Boolean(source && isObjectLiteral(source) && source[IS_SET_SENTINEL] && source[IS_ORDERED_SENTINEL]);
328
- }
329
- function isImmutableRecord(source) {
330
- return Boolean(source && isObjectLiteral(source) && source[IS_RECORD_SYMBOL]);
331
- }
332
- /**
333
- * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
334
- *
335
- * This source code is licensed under the MIT license found in the
336
- * LICENSE file in the root directory of this source tree.
337
- *
338
- */
339
- const IteratorSymbol = Symbol.iterator;
340
- function hasIterator(object) {
341
- return !!(object != null && object[IteratorSymbol]);
342
- }
343
- function iterableEquality(a, b, customTesters = [], aStack = [], bStack = []) {
344
- if (typeof a !== "object" || typeof b !== "object" || Array.isArray(a) || Array.isArray(b) || !hasIterator(a) || !hasIterator(b)) return;
345
- if (a.constructor !== b.constructor) return false;
346
- let length = aStack.length;
347
- while (length--) if (aStack[length] === a) return bStack[length] === b;
348
- aStack.push(a);
349
- bStack.push(b);
350
- const filteredCustomTesters = [...customTesters.filter((t) => t !== iterableEquality), iterableEqualityWithStack];
351
- function iterableEqualityWithStack(a, b) {
352
- return iterableEquality(a, b, [...customTesters], [...aStack], [...bStack]);
353
- }
354
- if (a.size !== void 0) {
355
- if (a.size !== b.size) return false;
356
- else if (isA("Set", a) || isImmutableUnorderedSet(a)) {
357
- let allFound = true;
358
- for (const aValue of a) if (!b.has(aValue)) {
359
- let has = false;
360
- for (const bValue of b) if (equals(aValue, bValue, filteredCustomTesters) === true) has = true;
361
- if (has === false) {
362
- allFound = false;
363
- break;
364
- }
365
- }
366
- aStack.pop();
367
- bStack.pop();
368
- return allFound;
369
- } else if (isA("Map", a) || isImmutableUnorderedKeyed(a)) {
370
- let allFound = true;
371
- for (const aEntry of a) if (!b.has(aEntry[0]) || !equals(aEntry[1], b.get(aEntry[0]), filteredCustomTesters)) {
372
- let has = false;
373
- for (const bEntry of b) {
374
- const matchedKey = equals(aEntry[0], bEntry[0], filteredCustomTesters);
375
- let matchedValue = false;
376
- if (matchedKey === true) matchedValue = equals(aEntry[1], bEntry[1], filteredCustomTesters);
377
- if (matchedValue === true) has = true;
378
- }
379
- if (has === false) {
380
- allFound = false;
381
- break;
382
- }
383
- }
384
- aStack.pop();
385
- bStack.pop();
386
- return allFound;
387
- }
388
- }
389
- const bIterator = b[IteratorSymbol]();
390
- for (const aValue of a) {
391
- const nextB = bIterator.next();
392
- if (nextB.done || !equals(aValue, nextB.value, filteredCustomTesters)) return false;
393
- }
394
- if (!bIterator.next().done) return false;
395
- if (!isImmutableList(a) && !isImmutableOrderedKeyed(a) && !isImmutableOrderedSet(a) && !isImmutableRecord(a)) {
396
- if (!equals(Object.entries(a), Object.entries(b), filteredCustomTesters)) return false;
397
- }
398
- aStack.pop();
399
- bStack.pop();
400
- return true;
401
- }
402
- /**
403
- * Checks if `hasOwnProperty(object, key)` up the prototype chain, stopping at `Object.prototype`.
404
- */
405
- function hasPropertyInObject(object, key) {
406
- if (!object || typeof object !== "object" || object === Object.prototype) return false;
407
- return Object.hasOwn(object, key) || hasPropertyInObject(Object.getPrototypeOf(object), key);
408
- }
409
- function isObjectWithKeys(a) {
410
- return isObject(a) && !isError(a) && !Array.isArray(a) && !(a instanceof Date) && !(a instanceof Set) && !(a instanceof Map);
411
- }
412
- function subsetEquality(object, subset, customTesters = []) {
413
- const filteredCustomTesters = customTesters.filter((t) => t !== subsetEquality);
414
- const subsetEqualityWithContext = (seenReferences = /* @__PURE__ */ new WeakMap()) => (object, subset) => {
415
- if (!isObjectWithKeys(subset)) return;
416
- return Object.keys(subset).every((key) => {
417
- if (subset[key] != null && typeof subset[key] === "object") {
418
- if (seenReferences.has(subset[key])) return equals(object[key], subset[key], filteredCustomTesters);
419
- seenReferences.set(subset[key], true);
420
- }
421
- const result = object != null && hasPropertyInObject(object, key) && equals(object[key], subset[key], [...filteredCustomTesters, subsetEqualityWithContext(seenReferences)]);
422
- seenReferences.delete(subset[key]);
423
- return result;
424
- });
425
- };
426
- return subsetEqualityWithContext()(object, subset);
427
- }
428
- function typeEquality(a, b) {
429
- if (a == null || b == null || a.constructor === b.constructor) return;
430
- return false;
431
- }
432
- function arrayBufferEquality(a, b) {
433
- let dataViewA = a;
434
- let dataViewB = b;
435
- if (!(a instanceof DataView && b instanceof DataView)) {
436
- if (!(a instanceof ArrayBuffer) || !(b instanceof ArrayBuffer)) return;
437
- try {
438
- dataViewA = new DataView(a);
439
- dataViewB = new DataView(b);
440
- } catch {
441
- return;
442
- }
443
- }
444
- if (dataViewA.byteLength !== dataViewB.byteLength) return false;
445
- for (let i = 0; i < dataViewA.byteLength; i++) if (dataViewA.getUint8(i) !== dataViewB.getUint8(i)) return false;
446
- return true;
447
- }
448
- function sparseArrayEquality(a, b, customTesters = []) {
449
- if (!Array.isArray(a) || !Array.isArray(b)) return;
450
- const aKeys = Object.keys(a);
451
- const bKeys = Object.keys(b);
452
- return equals(a, b, customTesters.filter((t) => t !== sparseArrayEquality), true) && equals(aKeys, bKeys);
453
- }
454
- function generateToBeMessage(deepEqualityName, expected = "#{this}", actual = "#{exp}") {
455
- const toBeMessage = `expected ${expected} to be ${actual} // Object.is equality`;
456
- if (["toStrictEqual", "toEqual"].includes(deepEqualityName)) return `${toBeMessage}\n\nIf it should pass with deep equality, replace "toBe" with "${deepEqualityName}"\n\nExpected: ${expected}\nReceived: serializes to the same string\n`;
457
- return toBeMessage;
458
- }
459
- function pluralize(word, count) {
460
- return `${count} ${word}${count === 1 ? "" : "s"}`;
461
- }
462
- function getObjectKeys(object) {
463
- return [...Object.keys(object), ...Object.getOwnPropertySymbols(object).filter((s) => Object.getOwnPropertyDescriptor(object, s)?.enumerable)];
464
- }
465
- function getObjectSubset(object, subset, customTesters) {
466
- let stripped = 0;
467
- const getObjectSubsetWithContext = (seenReferences = /* @__PURE__ */ new WeakMap()) => (object, subset) => {
468
- if (Array.isArray(object)) {
469
- if (Array.isArray(subset) && subset.length === object.length) return subset.map((sub, i) => getObjectSubsetWithContext(seenReferences)(object[i], sub));
470
- } else if (object instanceof Date) return object;
471
- else if (isObject(object) && isObject(subset)) {
472
- if (equals(object, subset, [
473
- ...customTesters,
474
- iterableEquality,
475
- subsetEquality
476
- ])) return subset;
477
- const trimmed = {};
478
- seenReferences.set(object, trimmed);
479
- if (typeof object.constructor === "function" && typeof object.constructor.name === "string") Object.defineProperty(trimmed, "constructor", {
480
- enumerable: false,
481
- value: object.constructor
482
- });
483
- for (const key of getObjectKeys(object)) if (hasPropertyInObject(subset, key)) trimmed[key] = seenReferences.has(object[key]) ? seenReferences.get(object[key]) : getObjectSubsetWithContext(seenReferences)(object[key], subset[key]);
484
- else if (!seenReferences.has(object[key])) {
485
- stripped += 1;
486
- if (isObject(object[key])) stripped += getObjectKeys(object[key]).length;
487
- getObjectSubsetWithContext(seenReferences)(object[key], subset[key]);
488
- }
489
- if (getObjectKeys(trimmed).length > 0) return trimmed;
490
- }
491
- return object;
492
- };
493
- return {
494
- subset: getObjectSubsetWithContext()(object, subset),
495
- stripped
496
- };
497
- }
498
- /**
499
- * Detects if an object is a Standard Schema V1 compatible schema
500
- */
501
- function isStandardSchema(obj) {
502
- return !!obj && (typeof obj === "object" || typeof obj === "function") && obj["~standard"] && typeof obj["~standard"].validate === "function";
503
- }
504
- if (!Object.hasOwn(globalThis, MATCHERS_OBJECT)) {
505
- const globalState = /* @__PURE__ */ new WeakMap();
506
- const matchers = Object.create(null);
507
- const customEqualityTesters = [];
508
- const asymmetricMatchers = Object.create(null);
509
- Object.defineProperty(globalThis, MATCHERS_OBJECT, { get: () => globalState });
510
- Object.defineProperty(globalThis, JEST_MATCHERS_OBJECT, {
511
- configurable: true,
512
- get: () => ({
513
- state: globalState.get(globalThis[GLOBAL_EXPECT]),
514
- matchers,
515
- customEqualityTesters
516
- })
517
- });
518
- Object.defineProperty(globalThis, ASYMMETRIC_MATCHERS_OBJECT, { get: () => asymmetricMatchers });
519
- }
520
- function getState(expect) {
521
- return globalThis[MATCHERS_OBJECT].get(expect);
522
- }
523
- function setState(state, expect) {
524
- const map = globalThis[MATCHERS_OBJECT];
525
- const current = map.get(expect) || {};
526
- const results = Object.defineProperties(current, {
527
- ...Object.getOwnPropertyDescriptors(current),
528
- ...Object.getOwnPropertyDescriptors(state)
529
- });
530
- map.set(expect, results);
531
- }
532
- var AsymmetricMatcher = class {
533
- $$typeof = Symbol.for("jest.asymmetricMatcher");
534
- constructor(sample, inverse = false) {
535
- this.sample = sample;
536
- this.inverse = inverse;
537
- }
538
- getMatcherContext(expect) {
539
- return {
540
- ...getState(expect || globalThis[GLOBAL_EXPECT]),
541
- equals,
542
- isNot: this.inverse,
543
- customTesters: getCustomEqualityTesters(),
544
- utils: {
545
- ...getMatcherUtils(),
546
- diff,
547
- stringify,
548
- iterableEquality,
549
- subsetEquality
550
- }
551
- };
552
- }
553
- };
554
- AsymmetricMatcher.prototype[Symbol.for("chai/inspect")] = function(options) {
555
- const result = stringify(this, options.depth, { min: true });
556
- if (result.length <= options.truncate) return result;
557
- return `${this.toString()}{…}`;
558
- };
559
- var StringContaining = class extends AsymmetricMatcher {
560
- constructor(sample, inverse = false) {
561
- if (!isA("String", sample)) throw new Error("Expected is not a string");
562
- super(sample, inverse);
563
- }
564
- asymmetricMatch(other) {
565
- const result = isA("String", other) && other.includes(this.sample);
566
- return this.inverse ? !result : result;
567
- }
568
- toString() {
569
- return `String${this.inverse ? "Not" : ""}Containing`;
570
- }
571
- getExpectedType() {
572
- return "string";
573
- }
574
- };
575
- var Anything = class extends AsymmetricMatcher {
576
- asymmetricMatch(other) {
577
- return other != null;
578
- }
579
- toString() {
580
- return "Anything";
581
- }
582
- toAsymmetricMatcher() {
583
- return "Anything";
584
- }
585
- };
586
- var ObjectContaining = class extends AsymmetricMatcher {
587
- constructor(sample, inverse = false) {
588
- super(sample, inverse);
589
- }
590
- getPrototype(obj) {
591
- if (Object.getPrototypeOf) return Object.getPrototypeOf(obj);
592
- if (obj.constructor.prototype === obj) return null;
593
- return obj.constructor.prototype;
594
- }
595
- hasProperty(obj, property) {
596
- if (!obj) return false;
597
- if (Object.hasOwn(obj, property)) return true;
598
- return this.hasProperty(this.getPrototype(obj), property);
599
- }
600
- getProperties(obj) {
601
- return [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj).filter((s) => Object.getOwnPropertyDescriptor(obj, s)?.enumerable)];
602
- }
603
- asymmetricMatch(other, customTesters) {
604
- if (typeof this.sample !== "object") throw new TypeError(`You must provide an object to ${this.toString()}, not '${typeof this.sample}'.`);
605
- let result = true;
606
- const properties = this.getProperties(this.sample);
607
- for (const property of properties) {
608
- if (!this.hasProperty(other, property)) {
609
- result = false;
610
- break;
611
- }
612
- const value = this.sample[property];
613
- const otherValue = other[property];
614
- if (!equals(value, otherValue, customTesters)) {
615
- result = false;
616
- break;
617
- }
618
- }
619
- return this.inverse ? !result : result;
620
- }
621
- toString() {
622
- return `Object${this.inverse ? "Not" : ""}Containing`;
623
- }
624
- getExpectedType() {
625
- return "object";
626
- }
627
- };
628
- var ArrayContaining = class extends AsymmetricMatcher {
629
- constructor(sample, inverse = false) {
630
- super(sample, inverse);
631
- }
632
- asymmetricMatch(other, customTesters) {
633
- if (!Array.isArray(this.sample)) throw new TypeError(`You must provide an array to ${this.toString()}, not '${typeof this.sample}'.`);
634
- const result = this.sample.length === 0 || Array.isArray(other) && this.sample.every((item) => other.some((another) => equals(item, another, customTesters)));
635
- return this.inverse ? !result : result;
636
- }
637
- toString() {
638
- return `Array${this.inverse ? "Not" : ""}Containing`;
639
- }
640
- getExpectedType() {
641
- return "array";
642
- }
643
- };
644
- var Any = class extends AsymmetricMatcher {
645
- constructor(sample) {
646
- if (typeof sample === "undefined") throw new TypeError("any() expects to be passed a constructor function. Please pass one or use anything() to match any object.");
647
- super(sample);
648
- }
649
- fnNameFor(func) {
650
- if (func.name) return func.name;
651
- const matches = Function.prototype.toString.call(func).match(/^(?:async)?\s*function\s*(?:\*\s*)?([\w$]+)\s*\(/);
652
- return matches ? matches[1] : "<anonymous>";
653
- }
654
- asymmetricMatch(other) {
655
- if (this.sample === String) return typeof other == "string" || other instanceof String;
656
- if (this.sample === Number) return typeof other == "number" || other instanceof Number;
657
- if (this.sample === Function) return typeof other == "function" || typeof other === "function";
658
- if (this.sample === Boolean) return typeof other == "boolean" || other instanceof Boolean;
659
- if (this.sample === BigInt) return typeof other == "bigint" || other instanceof BigInt;
660
- if (this.sample === Symbol) return typeof other == "symbol" || other instanceof Symbol;
661
- if (this.sample === Object) return typeof other == "object";
662
- return other instanceof this.sample;
663
- }
664
- toString() {
665
- return "Any";
666
- }
667
- getExpectedType() {
668
- if (this.sample === String) return "string";
669
- if (this.sample === Number) return "number";
670
- if (this.sample === Function) return "function";
671
- if (this.sample === Object) return "object";
672
- if (this.sample === Boolean) return "boolean";
673
- return this.fnNameFor(this.sample);
674
- }
675
- toAsymmetricMatcher() {
676
- return `Any<${this.fnNameFor(this.sample)}>`;
677
- }
678
- };
679
- var StringMatching = class extends AsymmetricMatcher {
680
- constructor(sample, inverse = false) {
681
- if (!isA("String", sample) && !isA("RegExp", sample)) throw new Error("Expected is not a String or a RegExp");
682
- super(new RegExp(sample), inverse);
683
- }
684
- asymmetricMatch(other) {
685
- const result = isA("String", other) && this.sample.test(other);
686
- return this.inverse ? !result : result;
687
- }
688
- toString() {
689
- return `String${this.inverse ? "Not" : ""}Matching`;
690
- }
691
- getExpectedType() {
692
- return "string";
693
- }
694
- };
695
- var CloseTo = class extends AsymmetricMatcher {
696
- precision;
697
- constructor(sample, precision = 2, inverse = false) {
698
- if (!isA("Number", sample)) throw new Error("Expected is not a Number");
699
- if (!isA("Number", precision)) throw new Error("Precision is not a Number");
700
- super(sample);
701
- this.inverse = inverse;
702
- this.precision = precision;
703
- }
704
- asymmetricMatch(other) {
705
- if (!isA("Number", other)) return false;
706
- let result = false;
707
- if (other === Number.POSITIVE_INFINITY && this.sample === Number.POSITIVE_INFINITY) result = true;
708
- else if (other === Number.NEGATIVE_INFINITY && this.sample === Number.NEGATIVE_INFINITY) result = true;
709
- else result = Math.abs(this.sample - other) < 10 ** -this.precision / 2;
710
- return this.inverse ? !result : result;
711
- }
712
- toString() {
713
- return `Number${this.inverse ? "Not" : ""}CloseTo`;
714
- }
715
- getExpectedType() {
716
- return "number";
717
- }
718
- toAsymmetricMatcher() {
719
- return [
720
- this.toString(),
721
- this.sample,
722
- `(${pluralize("digit", this.precision)})`
723
- ].join(" ");
724
- }
725
- };
726
- var SchemaMatching = class extends AsymmetricMatcher {
727
- result;
728
- constructor(sample, inverse = false) {
729
- if (!isStandardSchema(sample)) throw new TypeError("SchemaMatching expected to receive a Standard Schema.");
730
- super(sample, inverse);
731
- }
732
- asymmetricMatch(other) {
733
- const result = this.sample["~standard"].validate(other);
734
- if (result instanceof Promise) throw new TypeError("Async schema validation is not supported in asymmetric matchers.");
735
- this.result = result;
736
- const pass = !this.result.issues || this.result.issues.length === 0;
737
- return this.inverse ? !pass : pass;
738
- }
739
- toString() {
740
- return `Schema${this.inverse ? "Not" : ""}Matching`;
741
- }
742
- getExpectedType() {
743
- return "object";
744
- }
745
- toAsymmetricMatcher() {
746
- const { utils } = this.getMatcherContext();
747
- if ((this.result?.issues || []).length > 0) return `${this.toString()} ${utils.stringify(this.result, void 0, { printBasicPrototype: false })}`;
748
- return this.toString();
749
- }
750
- };
751
- const JestAsymmetricMatchers = (chai, utils) => {
752
- utils.addMethod(chai.expect, "anything", () => new Anything());
753
- utils.addMethod(chai.expect, "any", (expected) => new Any(expected));
754
- utils.addMethod(chai.expect, "stringContaining", (expected) => new StringContaining(expected));
755
- utils.addMethod(chai.expect, "objectContaining", (expected) => new ObjectContaining(expected));
756
- utils.addMethod(chai.expect, "arrayContaining", (expected) => new ArrayContaining(expected));
757
- utils.addMethod(chai.expect, "stringMatching", (expected) => new StringMatching(expected));
758
- utils.addMethod(chai.expect, "closeTo", (expected, precision) => new CloseTo(expected, precision));
759
- utils.addMethod(chai.expect, "schemaMatching", (expected) => new SchemaMatching(expected));
760
- chai.expect.not = {
761
- stringContaining: (expected) => new StringContaining(expected, true),
762
- objectContaining: (expected) => new ObjectContaining(expected, true),
763
- arrayContaining: (expected) => new ArrayContaining(expected, true),
764
- stringMatching: (expected) => new StringMatching(expected, true),
765
- closeTo: (expected, precision) => new CloseTo(expected, precision, true),
766
- schemaMatching: (expected) => new SchemaMatching(expected, true)
767
- };
768
- };
769
- function createAssertionMessage(util, assertion, hasArgs) {
770
- const soft = util.flag(assertion, "soft") ? ".soft" : "";
771
- const not = util.flag(assertion, "negate") ? "not." : "";
772
- const name = `${util.flag(assertion, "_name")}(${hasArgs ? "expected" : ""})`;
773
- const promiseName = util.flag(assertion, "promise");
774
- return `expect${soft}(actual)${promiseName ? `.${promiseName}` : ""}.${not}${name}`;
775
- }
776
- function recordAsyncExpect(_test, promise, assertion, error, isSoft) {
777
- const test = _test;
778
- if (test && promise instanceof Promise) {
779
- promise = promise.finally(() => {
780
- if (!test.promises) return;
781
- const index = test.promises.indexOf(promise);
782
- if (index !== -1) test.promises.splice(index, 1);
783
- });
784
- if (!test.promises) test.promises = [];
785
- if (isSoft) promise = promise.then(noop, (err) => {
786
- handleTestError(test, err);
787
- });
788
- test.promises.push(promise);
789
- let resolved = false;
790
- test.onFinished ??= [];
791
- test.onFinished.push(() => {
792
- if (!resolved) {
793
- const stack = (globalThis.__vitest_worker__?.onFilterStackTrace || ((s) => s || ""))(error.stack);
794
- console.warn([
795
- `Promise returned by \`${assertion}\` was not awaited. `,
796
- "Vitest currently auto-awaits hanging assertions at the end of the test, but this will cause the test to fail in the next Vitest major. ",
797
- "Please remember to await the assertion.\n",
798
- stack
799
- ].join(""));
800
- }
801
- });
802
- return {
803
- then(onFulfilled, onRejected) {
804
- resolved = true;
805
- return promise.then(onFulfilled, onRejected);
806
- },
807
- catch(onRejected) {
808
- resolved = true;
809
- return promise.catch(onRejected);
810
- },
811
- finally(onFinally) {
812
- resolved = true;
813
- return promise.finally(onFinally);
814
- },
815
- [Symbol.toStringTag]: "Promise"
816
- };
817
- }
818
- return promise;
819
- }
820
- function handleTestError(test, err) {
821
- test.result ||= { state: "fail" };
822
- test.result.state = "fail";
823
- test.result.errors ||= [];
824
- test.result.errors.push(processError(err));
825
- }
826
- /** wrap assertion function to support `expect.soft` and provide assertion name as `_name` */
827
- function wrapAssertion(utils, name, fn) {
828
- return function(...args) {
829
- if (name !== "withTest") utils.flag(this, "_name", name);
830
- if (!utils.flag(this, "soft")) try {
831
- return fn.apply(this, args);
832
- } finally {}
833
- const test = utils.flag(this, "vitest-test");
834
- if (!test) throw new Error("expect.soft() can only be used inside a test");
835
- try {
836
- const result = fn.apply(this, args);
837
- if (result && typeof result === "object" && typeof result.then === "function") return result.then(noop, (err) => {
838
- handleTestError(test, err);
839
- });
840
- return result;
841
- } catch (err) {
842
- handleTestError(test, err);
843
- }
844
- };
845
- }
846
- const JestChaiExpect = (chai, utils) => {
847
- const { AssertionError } = chai;
848
- const customTesters = getCustomEqualityTesters();
849
- function def(name, fn) {
850
- const addMethod = (n) => {
851
- const softWrapper = wrapAssertion(utils, n, fn);
852
- utils.addMethod(chai.Assertion.prototype, n, softWrapper);
853
- utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, n, softWrapper);
854
- };
855
- if (Array.isArray(name)) name.forEach((n) => addMethod(n));
856
- else addMethod(name);
857
- }
858
- [
859
- "throw",
860
- "throws",
861
- "Throw"
862
- ].forEach((m) => {
863
- utils.overwriteMethod(chai.Assertion.prototype, m, (_super) => {
864
- return function(...args) {
865
- const promise = utils.flag(this, "promise");
866
- const object = utils.flag(this, "object");
867
- const isNot = utils.flag(this, "negate");
868
- if (promise === "rejects") utils.flag(this, "object", () => {
869
- throw object;
870
- });
871
- else if (promise === "resolves" && typeof object !== "function") if (!isNot) {
872
- const message = utils.flag(this, "message") || "expected promise to throw an error, but it didn't";
873
- throw new AssertionError(message, { showDiff: false }, utils.flag(this, "ssfi"));
874
- } else return;
875
- _super.apply(this, args);
876
- };
877
- });
878
- });
879
- def("withTest", function(test) {
880
- utils.flag(this, "vitest-test", test);
881
- return this;
882
- });
883
- def("toEqual", function(expected) {
884
- const actual = utils.flag(this, "object");
885
- const equal = equals(actual, expected, [...customTesters, iterableEquality]);
886
- return this.assert(equal, "expected #{this} to deeply equal #{exp}", "expected #{this} to not deeply equal #{exp}", expected, actual);
887
- });
888
- def("toStrictEqual", function(expected) {
889
- const obj = utils.flag(this, "object");
890
- const equal = equals(obj, expected, [
891
- ...customTesters,
892
- iterableEquality,
893
- typeEquality,
894
- sparseArrayEquality,
895
- arrayBufferEquality
896
- ], true);
897
- return this.assert(equal, "expected #{this} to strictly equal #{exp}", "expected #{this} to not strictly equal #{exp}", expected, obj);
898
- });
899
- def("toBe", function(expected) {
900
- const actual = this._obj;
901
- const pass = Object.is(actual, expected);
902
- let deepEqualityName = "";
903
- if (!pass) {
904
- if (equals(actual, expected, [
905
- ...customTesters,
906
- iterableEquality,
907
- typeEquality,
908
- sparseArrayEquality,
909
- arrayBufferEquality
910
- ], true)) deepEqualityName = "toStrictEqual";
911
- else if (equals(actual, expected, [...customTesters, iterableEquality])) deepEqualityName = "toEqual";
912
- }
913
- return this.assert(pass, generateToBeMessage(deepEqualityName), "expected #{this} not to be #{exp} // Object.is equality", expected, actual);
914
- });
915
- def("toMatchObject", function(expected) {
916
- const actual = this._obj;
917
- const pass = equals(actual, expected, [
918
- ...customTesters,
919
- iterableEquality,
920
- subsetEquality
921
- ]);
922
- const isNot = utils.flag(this, "negate");
923
- const { subset: actualSubset, stripped } = getObjectSubset(actual, expected, customTesters);
924
- if (pass && isNot || !pass && !isNot) {
925
- const msg = utils.getMessage(this, [
926
- pass,
927
- "expected #{this} to match object #{exp}",
928
- "expected #{this} to not match object #{exp}",
929
- expected,
930
- actualSubset,
931
- false
932
- ]);
933
- const message = stripped === 0 ? msg : `${msg}\n(${stripped} matching ${stripped === 1 ? "property" : "properties"} omitted from actual)`;
934
- throw new AssertionError(message, {
935
- showDiff: true,
936
- expected,
937
- actual: actualSubset
938
- });
939
- }
940
- });
941
- def("toMatch", function(expected) {
942
- const actual = this._obj;
943
- if (typeof actual !== "string") throw new TypeError(`.toMatch() expects to receive a string, but got ${typeof actual}`);
944
- return this.assert(typeof expected === "string" ? actual.includes(expected) : actual.match(expected), `expected #{this} to match #{exp}`, `expected #{this} not to match #{exp}`, expected, actual);
945
- });
946
- def("toContain", function(item) {
947
- const actual = this._obj;
948
- if (typeof Node !== "undefined" && actual instanceof Node) {
949
- if (!(item instanceof Node)) throw new TypeError(`toContain() expected a DOM node as the argument, but got ${typeof item}`);
950
- return this.assert(actual.contains(item), "expected #{this} to contain element #{exp}", "expected #{this} not to contain element #{exp}", item, actual);
951
- }
952
- if (typeof DOMTokenList !== "undefined" && actual instanceof DOMTokenList) {
953
- assertTypes(item, "class name", ["string"]);
954
- const expectedClassList = utils.flag(this, "negate") ? actual.value.replace(item, "").trim() : `${actual.value} ${item}`;
955
- return this.assert(actual.contains(item), `expected "${actual.value}" to contain "${item}"`, `expected "${actual.value}" not to contain "${item}"`, expectedClassList, actual.value);
956
- }
957
- if (typeof actual === "string" && typeof item === "string") return this.assert(actual.includes(item), `expected #{this} to contain #{exp}`, `expected #{this} not to contain #{exp}`, item, actual);
958
- if (actual != null && typeof actual !== "string") utils.flag(this, "object", Array.from(actual));
959
- return this.contain(item);
960
- });
961
- def("toContainEqual", function(expected) {
962
- const obj = utils.flag(this, "object");
963
- const index = Array.from(obj).findIndex((item) => {
964
- return equals(item, expected, customTesters);
965
- });
966
- this.assert(index !== -1, "expected #{this} to deep equally contain #{exp}", "expected #{this} to not deep equally contain #{exp}", expected);
967
- });
968
- def("toBeTruthy", function() {
969
- const obj = utils.flag(this, "object");
970
- this.assert(Boolean(obj), "expected #{this} to be truthy", "expected #{this} to not be truthy", true, obj);
971
- });
972
- def("toBeFalsy", function() {
973
- const obj = utils.flag(this, "object");
974
- this.assert(!obj, "expected #{this} to be falsy", "expected #{this} to not be falsy", false, obj);
975
- });
976
- def("toBeGreaterThan", function(expected) {
977
- const actual = this._obj;
978
- assertTypes(actual, "actual", ["number", "bigint"]);
979
- assertTypes(expected, "expected", ["number", "bigint"]);
980
- return this.assert(actual > expected, `expected ${actual} to be greater than ${expected}`, `expected ${actual} to be not greater than ${expected}`, expected, actual, false);
981
- });
982
- def("toBeGreaterThanOrEqual", function(expected) {
983
- const actual = this._obj;
984
- assertTypes(actual, "actual", ["number", "bigint"]);
985
- assertTypes(expected, "expected", ["number", "bigint"]);
986
- return this.assert(actual >= expected, `expected ${actual} to be greater than or equal to ${expected}`, `expected ${actual} to be not greater than or equal to ${expected}`, expected, actual, false);
987
- });
988
- def("toBeLessThan", function(expected) {
989
- const actual = this._obj;
990
- assertTypes(actual, "actual", ["number", "bigint"]);
991
- assertTypes(expected, "expected", ["number", "bigint"]);
992
- return this.assert(actual < expected, `expected ${actual} to be less than ${expected}`, `expected ${actual} to be not less than ${expected}`, expected, actual, false);
993
- });
994
- def("toBeLessThanOrEqual", function(expected) {
995
- const actual = this._obj;
996
- assertTypes(actual, "actual", ["number", "bigint"]);
997
- assertTypes(expected, "expected", ["number", "bigint"]);
998
- return this.assert(actual <= expected, `expected ${actual} to be less than or equal to ${expected}`, `expected ${actual} to be not less than or equal to ${expected}`, expected, actual, false);
999
- });
1000
- def("toBeNaN", function() {
1001
- const obj = utils.flag(this, "object");
1002
- this.assert(Number.isNaN(obj), "expected #{this} to be NaN", "expected #{this} not to be NaN", NaN, obj);
1003
- });
1004
- def("toBeUndefined", function() {
1005
- const obj = utils.flag(this, "object");
1006
- this.assert(void 0 === obj, "expected #{this} to be undefined", "expected #{this} not to be undefined", void 0, obj);
1007
- });
1008
- def("toBeNull", function() {
1009
- const obj = utils.flag(this, "object");
1010
- this.assert(obj === null, "expected #{this} to be null", "expected #{this} not to be null", null, obj);
1011
- });
1012
- def("toBeNullable", function() {
1013
- const obj = utils.flag(this, "object");
1014
- this.assert(obj == null, "expected #{this} to be nullish", "expected #{this} not to be nullish", null, obj);
1015
- });
1016
- def("toBeDefined", function() {
1017
- const obj = utils.flag(this, "object");
1018
- this.assert(typeof obj !== "undefined", "expected #{this} to be defined", "expected #{this} to be undefined", obj);
1019
- });
1020
- def("toBeTypeOf", function(expected) {
1021
- const actual = typeof this._obj;
1022
- const equal = expected === actual;
1023
- return this.assert(equal, "expected #{this} to be type of #{exp}", "expected #{this} not to be type of #{exp}", expected, actual);
1024
- });
1025
- def("toBeInstanceOf", function(obj) {
1026
- return this.instanceOf(obj);
1027
- });
1028
- def("toHaveLength", function(length) {
1029
- return this.have.length(length);
1030
- });
1031
- def("toHaveProperty", function(...args) {
1032
- if (Array.isArray(args[0])) args[0] = args[0].map((key) => String(key).replace(/([.[\]])/g, "\\$1")).join(".");
1033
- const actual = this._obj;
1034
- const [propertyName, expected] = args;
1035
- const getValue = () => {
1036
- if (Object.hasOwn(actual, propertyName)) return {
1037
- value: actual[propertyName],
1038
- exists: true
1039
- };
1040
- return utils.getPathInfo(actual, propertyName);
1041
- };
1042
- const { value, exists } = getValue();
1043
- const pass = exists && (args.length === 1 || equals(expected, value, customTesters));
1044
- const valueString = args.length === 1 ? "" : ` with value ${utils.objDisplay(expected)}`;
1045
- return this.assert(pass, `expected #{this} to have property "${propertyName}"${valueString}`, `expected #{this} to not have property "${propertyName}"${valueString}`, expected, exists ? value : void 0);
1046
- });
1047
- def("toBeCloseTo", function(received, precision = 2) {
1048
- const expected = this._obj;
1049
- let pass = false;
1050
- let expectedDiff = 0;
1051
- let receivedDiff = 0;
1052
- if (received === Number.POSITIVE_INFINITY && expected === Number.POSITIVE_INFINITY) pass = true;
1053
- else if (received === Number.NEGATIVE_INFINITY && expected === Number.NEGATIVE_INFINITY) pass = true;
1054
- else {
1055
- expectedDiff = 10 ** -precision / 2;
1056
- receivedDiff = Math.abs(expected - received);
1057
- pass = receivedDiff < expectedDiff;
1058
- }
1059
- return this.assert(pass, `expected #{this} to be close to #{exp}, received difference is ${receivedDiff}, but expected ${expectedDiff}`, `expected #{this} to not be close to #{exp}, received difference is ${receivedDiff}, but expected ${expectedDiff}`, received, expected, false);
1060
- });
1061
- function assertIsMock(assertion) {
1062
- if (!isMockFunction(assertion._obj)) throw new TypeError(`${utils.inspect(assertion._obj)} is not a spy or a call to a spy!`);
1063
- }
1064
- function getSpy(assertion) {
1065
- assertIsMock(assertion);
1066
- return assertion._obj;
1067
- }
1068
- def(["toHaveBeenCalledTimes", "toBeCalledTimes"], function(number) {
1069
- const spy = getSpy(this);
1070
- const spyName = spy.getMockName();
1071
- const callCount = spy.mock.calls.length;
1072
- return this.assert(callCount === number, `expected "${spyName}" to be called #{exp} times, but got ${callCount} times`, `expected "${spyName}" to not be called #{exp} times`, number, callCount, false);
1073
- });
1074
- def("toHaveBeenCalledOnce", function() {
1075
- const spy = getSpy(this);
1076
- const spyName = spy.getMockName();
1077
- const callCount = spy.mock.calls.length;
1078
- return this.assert(callCount === 1, `expected "${spyName}" to be called once, but got ${callCount} times`, `expected "${spyName}" to not be called once`, 1, callCount, false);
1079
- });
1080
- def(["toHaveBeenCalled", "toBeCalled"], function() {
1081
- const spy = getSpy(this);
1082
- const spyName = spy.getMockName();
1083
- const callCount = spy.mock.calls.length;
1084
- const called = callCount > 0;
1085
- const isNot = utils.flag(this, "negate");
1086
- let msg = utils.getMessage(this, [
1087
- called,
1088
- `expected "${spyName}" to be called at least once`,
1089
- `expected "${spyName}" to not be called at all, but actually been called ${callCount} times`,
1090
- true,
1091
- called
1092
- ]);
1093
- if (called && isNot) msg = formatCalls(spy, msg);
1094
- if (called && isNot || !called && !isNot) throw new AssertionError(msg);
1095
- });
1096
- function equalsArgumentArray(a, b) {
1097
- return a.length === b.length && a.every((aItem, i) => equals(aItem, b[i], [...customTesters, iterableEquality]));
1098
- }
1099
- def(["toHaveBeenCalledWith", "toBeCalledWith"], function(...args) {
1100
- const spy = getSpy(this);
1101
- const spyName = spy.getMockName();
1102
- const pass = spy.mock.calls.some((callArg) => equalsArgumentArray(callArg, args));
1103
- const isNot = utils.flag(this, "negate");
1104
- const msg = utils.getMessage(this, [
1105
- pass,
1106
- `expected "${spyName}" to be called with arguments: #{exp}`,
1107
- `expected "${spyName}" to not be called with arguments: #{exp}`,
1108
- args
1109
- ]);
1110
- if (pass && isNot || !pass && !isNot) throw new AssertionError(formatCalls(spy, msg, args));
1111
- });
1112
- def("toHaveBeenCalledExactlyOnceWith", function(...args) {
1113
- const spy = getSpy(this);
1114
- const spyName = spy.getMockName();
1115
- const callCount = spy.mock.calls.length;
1116
- const pass = spy.mock.calls.some((callArg) => equalsArgumentArray(callArg, args)) && callCount === 1;
1117
- const isNot = utils.flag(this, "negate");
1118
- const msg = utils.getMessage(this, [
1119
- pass,
1120
- `expected "${spyName}" to be called once with arguments: #{exp}`,
1121
- `expected "${spyName}" to not be called once with arguments: #{exp}`,
1122
- args
1123
- ]);
1124
- if (pass && isNot || !pass && !isNot) throw new AssertionError(formatCalls(spy, msg, args));
1125
- });
1126
- def("toHaveBeenNthCalledWith", function(times, ...args) {
1127
- const spy = getSpy(this);
1128
- const spyName = spy.getMockName();
1129
- const nthCall = spy.mock.calls[times - 1];
1130
- const callCount = spy.mock.calls.length;
1131
- const isCalled = times <= callCount;
1132
- this.assert(nthCall && equalsArgumentArray(nthCall, args), `expected ${ordinal(times)} "${spyName}" call to have been called with #{exp}${isCalled ? `` : `, but called only ${callCount} times`}`, `expected ${ordinal(times)} "${spyName}" call to not have been called with #{exp}`, args, nthCall, isCalled);
1133
- });
1134
- def("toHaveBeenLastCalledWith", function(...args) {
1135
- const spy = getSpy(this);
1136
- const spyName = spy.getMockName();
1137
- const lastCall = spy.mock.calls.at(-1);
1138
- this.assert(lastCall && equalsArgumentArray(lastCall, args), `expected last "${spyName}" call to have been called with #{exp}`, `expected last "${spyName}" call to not have been called with #{exp}`, args, lastCall);
1139
- });
1140
- /**
1141
- * Used for `toHaveBeenCalledBefore` and `toHaveBeenCalledAfter` to determine if the expected spy was called before the result spy.
1142
- */
1143
- function isSpyCalledBeforeAnotherSpy(beforeSpy, afterSpy, failIfNoFirstInvocation) {
1144
- const beforeInvocationCallOrder = beforeSpy.mock.invocationCallOrder;
1145
- const afterInvocationCallOrder = afterSpy.mock.invocationCallOrder;
1146
- if (beforeInvocationCallOrder.length === 0) return !failIfNoFirstInvocation;
1147
- if (afterInvocationCallOrder.length === 0) return false;
1148
- return beforeInvocationCallOrder[0] < afterInvocationCallOrder[0];
1149
- }
1150
- def(["toHaveBeenCalledBefore"], function(resultSpy, failIfNoFirstInvocation = true) {
1151
- const expectSpy = getSpy(this);
1152
- if (!isMockFunction(resultSpy)) throw new TypeError(`${utils.inspect(resultSpy)} is not a spy or a call to a spy`);
1153
- this.assert(isSpyCalledBeforeAnotherSpy(expectSpy, resultSpy, failIfNoFirstInvocation), `expected "${expectSpy.getMockName()}" to have been called before "${resultSpy.getMockName()}"`, `expected "${expectSpy.getMockName()}" to not have been called before "${resultSpy.getMockName()}"`, resultSpy, expectSpy);
1154
- });
1155
- def(["toHaveBeenCalledAfter"], function(resultSpy, failIfNoFirstInvocation = true) {
1156
- const expectSpy = getSpy(this);
1157
- if (!isMockFunction(resultSpy)) throw new TypeError(`${utils.inspect(resultSpy)} is not a spy or a call to a spy`);
1158
- this.assert(isSpyCalledBeforeAnotherSpy(resultSpy, expectSpy, failIfNoFirstInvocation), `expected "${expectSpy.getMockName()}" to have been called after "${resultSpy.getMockName()}"`, `expected "${expectSpy.getMockName()}" to not have been called after "${resultSpy.getMockName()}"`, resultSpy, expectSpy);
1159
- });
1160
- def(["toThrow", "toThrowError"], function(expected) {
1161
- if (typeof expected === "string" || typeof expected === "undefined" || expected instanceof RegExp) return this.throws(expected === "" ? /^$/ : expected);
1162
- const obj = this._obj;
1163
- const promise = utils.flag(this, "promise");
1164
- const isNot = utils.flag(this, "negate");
1165
- let thrown = null;
1166
- if (promise === "rejects") thrown = obj;
1167
- else if (promise === "resolves" && typeof obj !== "function") if (!isNot) {
1168
- const message = utils.flag(this, "message") || "expected promise to throw an error, but it didn't";
1169
- throw new AssertionError(message, { showDiff: false }, utils.flag(this, "ssfi"));
1170
- } else return;
1171
- else {
1172
- let isThrow = false;
1173
- try {
1174
- obj();
1175
- } catch (err) {
1176
- isThrow = true;
1177
- thrown = err;
1178
- }
1179
- if (!isThrow && !isNot) {
1180
- const message = utils.flag(this, "message") || "expected function to throw an error, but it didn't";
1181
- throw new AssertionError(message, { showDiff: false }, utils.flag(this, "ssfi"));
1182
- }
1183
- }
1184
- if (typeof expected === "function") {
1185
- const name = expected.name || expected.prototype.constructor.name;
1186
- return this.assert(thrown && thrown instanceof expected, `expected error to be instance of ${name}`, `expected error not to be instance of ${name}`, expected, thrown);
1187
- }
1188
- if (isError(expected)) {
1189
- const equal = equals(thrown, expected, [...customTesters, iterableEquality]);
1190
- return this.assert(equal, "expected a thrown error to be #{exp}", "expected a thrown error not to be #{exp}", expected, thrown);
1191
- }
1192
- if (typeof expected === "object" && "asymmetricMatch" in expected && typeof expected.asymmetricMatch === "function") {
1193
- const matcher = expected;
1194
- return this.assert(thrown && matcher.asymmetricMatch(thrown), "expected error to match asymmetric matcher", "expected error not to match asymmetric matcher", matcher, thrown);
1195
- }
1196
- const equal = equals(thrown, expected, [...customTesters, iterableEquality]);
1197
- return this.assert(equal, "expected a thrown value to equal #{exp}", "expected a thrown value not to equal #{exp}", expected, thrown);
1198
- });
1199
- [{
1200
- name: "toHaveResolved",
1201
- condition: (spy) => spy.mock.settledResults.length > 0 && spy.mock.settledResults.some(({ type }) => type === "fulfilled"),
1202
- action: "resolved"
1203
- }, {
1204
- name: ["toHaveReturned", "toReturn"],
1205
- condition: (spy) => spy.mock.calls.length > 0 && spy.mock.results.some(({ type }) => type !== "throw"),
1206
- action: "called"
1207
- }].forEach(({ name, condition, action }) => {
1208
- def(name, function() {
1209
- const spy = getSpy(this);
1210
- const spyName = spy.getMockName();
1211
- const pass = condition(spy);
1212
- this.assert(pass, `expected "${spyName}" to be successfully ${action} at least once`, `expected "${spyName}" to not be successfully ${action}`, pass, !pass, false);
1213
- });
1214
- });
1215
- [{
1216
- name: "toHaveResolvedTimes",
1217
- condition: (spy, times) => spy.mock.settledResults.reduce((s, { type }) => type === "fulfilled" ? ++s : s, 0) === times,
1218
- action: "resolved"
1219
- }, {
1220
- name: ["toHaveReturnedTimes", "toReturnTimes"],
1221
- condition: (spy, times) => spy.mock.results.reduce((s, { type }) => type === "throw" ? s : ++s, 0) === times,
1222
- action: "called"
1223
- }].forEach(({ name, condition, action }) => {
1224
- def(name, function(times) {
1225
- const spy = getSpy(this);
1226
- const spyName = spy.getMockName();
1227
- const pass = condition(spy, times);
1228
- this.assert(pass, `expected "${spyName}" to be successfully ${action} ${times} times`, `expected "${spyName}" to not be successfully ${action} ${times} times`, `expected resolved times: ${times}`, `received resolved times: ${pass}`, false);
1229
- });
1230
- });
1231
- [{
1232
- name: "toHaveResolvedWith",
1233
- condition: (spy, value) => spy.mock.settledResults.some(({ type, value: result }) => type === "fulfilled" && equals(value, result)),
1234
- action: "resolve"
1235
- }, {
1236
- name: ["toHaveReturnedWith", "toReturnWith"],
1237
- condition: (spy, value) => spy.mock.results.some(({ type, value: result }) => type === "return" && equals(value, result)),
1238
- action: "return"
1239
- }].forEach(({ name, condition, action }) => {
1240
- def(name, function(value) {
1241
- const spy = getSpy(this);
1242
- const pass = condition(spy, value);
1243
- const isNot = utils.flag(this, "negate");
1244
- if (pass && isNot || !pass && !isNot) {
1245
- const spyName = spy.getMockName();
1246
- const msg = utils.getMessage(this, [
1247
- pass,
1248
- `expected "${spyName}" to ${action} with: #{exp} at least once`,
1249
- `expected "${spyName}" to not ${action} with: #{exp}`,
1250
- value
1251
- ]);
1252
- const results = action === "return" ? spy.mock.results : spy.mock.settledResults;
1253
- throw new AssertionError(formatReturns(spy, results, msg, value));
1254
- }
1255
- });
1256
- });
1257
- [{
1258
- name: "toHaveLastResolvedWith",
1259
- condition: (spy, value) => {
1260
- const result = spy.mock.settledResults.at(-1);
1261
- return Boolean(result && result.type === "fulfilled" && equals(result.value, value));
1262
- },
1263
- action: "resolve"
1264
- }, {
1265
- name: "toHaveLastReturnedWith",
1266
- condition: (spy, value) => {
1267
- const result = spy.mock.results.at(-1);
1268
- return Boolean(result && result.type === "return" && equals(result.value, value));
1269
- },
1270
- action: "return"
1271
- }].forEach(({ name, condition, action }) => {
1272
- def(name, function(value) {
1273
- const spy = getSpy(this);
1274
- const result = (action === "return" ? spy.mock.results : spy.mock.settledResults).at(-1);
1275
- const spyName = spy.getMockName();
1276
- this.assert(condition(spy, value), `expected last "${spyName}" call to ${action} #{exp}`, `expected last "${spyName}" call to not ${action} #{exp}`, value, result?.value);
1277
- });
1278
- });
1279
- [{
1280
- name: "toHaveNthResolvedWith",
1281
- condition: (spy, index, value) => {
1282
- const result = spy.mock.settledResults[index - 1];
1283
- return result && result.type === "fulfilled" && equals(result.value, value);
1284
- },
1285
- action: "resolve"
1286
- }, {
1287
- name: "toHaveNthReturnedWith",
1288
- condition: (spy, index, value) => {
1289
- const result = spy.mock.results[index - 1];
1290
- return result && result.type === "return" && equals(result.value, value);
1291
- },
1292
- action: "return"
1293
- }].forEach(({ name, condition, action }) => {
1294
- def(name, function(nthCall, value) {
1295
- const spy = getSpy(this);
1296
- const spyName = spy.getMockName();
1297
- const result = (action === "return" ? spy.mock.results : spy.mock.settledResults)[nthCall - 1];
1298
- const ordinalCall = `${ordinal(nthCall)} call`;
1299
- this.assert(condition(spy, nthCall, value), `expected ${ordinalCall} "${spyName}" call to ${action} #{exp}`, `expected ${ordinalCall} "${spyName}" call to not ${action} #{exp}`, value, result?.value);
1300
- });
1301
- });
1302
- def("withContext", function(context) {
1303
- for (const key in context) utils.flag(this, key, context[key]);
1304
- return this;
1305
- });
1306
- utils.addProperty(chai.Assertion.prototype, "resolves", function __VITEST_RESOLVES__() {
1307
- const error = /* @__PURE__ */ new Error("resolves");
1308
- utils.flag(this, "promise", "resolves");
1309
- utils.flag(this, "error", error);
1310
- const test = utils.flag(this, "vitest-test");
1311
- const obj = utils.flag(this, "object");
1312
- if (utils.flag(this, "poll")) throw new SyntaxError(`expect.poll() is not supported in combination with .resolves`);
1313
- if (typeof obj?.then !== "function") throw new TypeError(`You must provide a Promise to expect() when using .resolves, not '${typeof obj}'.`);
1314
- const proxy = new Proxy(this, { get: (target, key, receiver) => {
1315
- const result = Reflect.get(target, key, receiver);
1316
- if (typeof result !== "function") return result instanceof chai.Assertion ? proxy : result;
1317
- return (...args) => {
1318
- utils.flag(this, "_name", key);
1319
- const promise = Promise.resolve(obj).then((value) => {
1320
- utils.flag(this, "object", value);
1321
- return result.call(this, ...args);
1322
- }, (err) => {
1323
- const _error = new AssertionError(`promise rejected "${utils.inspect(err)}" instead of resolving`, { showDiff: false });
1324
- _error.cause = err;
1325
- throw _error;
1326
- }).catch((err) => {
1327
- if (isError(err) && error.stack) err.stack = error.stack.replace(error.message, err.message);
1328
- throw err;
1329
- });
1330
- return recordAsyncExpect(test, promise, createAssertionMessage(utils, this, !!args.length), error, utils.flag(this, "soft"));
1331
- };
1332
- } });
1333
- return proxy;
1334
- });
1335
- utils.addProperty(chai.Assertion.prototype, "rejects", function __VITEST_REJECTS__() {
1336
- const error = /* @__PURE__ */ new Error("rejects");
1337
- utils.flag(this, "promise", "rejects");
1338
- utils.flag(this, "error", error);
1339
- const test = utils.flag(this, "vitest-test");
1340
- const obj = utils.flag(this, "object");
1341
- const wrapper = typeof obj === "function" ? obj() : obj;
1342
- if (utils.flag(this, "poll")) throw new SyntaxError(`expect.poll() is not supported in combination with .rejects`);
1343
- if (typeof wrapper?.then !== "function") throw new TypeError(`You must provide a Promise to expect() when using .rejects, not '${typeof wrapper}'.`);
1344
- const proxy = new Proxy(this, { get: (target, key, receiver) => {
1345
- const result = Reflect.get(target, key, receiver);
1346
- if (typeof result !== "function") return result instanceof chai.Assertion ? proxy : result;
1347
- return (...args) => {
1348
- utils.flag(this, "_name", key);
1349
- const promise = Promise.resolve(wrapper).then((value) => {
1350
- throw new AssertionError(`promise resolved "${utils.inspect(value)}" instead of rejecting`, {
1351
- showDiff: true,
1352
- expected: /* @__PURE__ */ new Error("rejected promise"),
1353
- actual: value
1354
- });
1355
- }, (err) => {
1356
- utils.flag(this, "object", err);
1357
- return result.call(this, ...args);
1358
- }).catch((err) => {
1359
- if (isError(err) && error.stack) err.stack = error.stack.replace(error.message, err.message);
1360
- throw err;
1361
- });
1362
- return recordAsyncExpect(test, promise, createAssertionMessage(utils, this, !!args.length), error, utils.flag(this, "soft"));
1363
- };
1364
- } });
1365
- return proxy;
1366
- });
1367
- };
1368
- function formatCalls(spy, msg, showActualCall) {
1369
- if (spy.mock.calls.length) msg += y.gray(`\n\nReceived:\n\n${spy.mock.calls.map((callArg, i) => {
1370
- let methodCall = y.bold(` ${ordinal(i + 1)} ${spy.getMockName()} call:\n\n`);
1371
- if (showActualCall) methodCall += diff(showActualCall, callArg, { omitAnnotationLines: true });
1372
- else methodCall += stringify(callArg).split("\n").map((line) => ` ${line}`).join("\n");
1373
- methodCall += "\n";
1374
- return methodCall;
1375
- }).join("\n")}`);
1376
- msg += y.gray(`\n\nNumber of calls: ${y.bold(spy.mock.calls.length)}\n`);
1377
- return msg;
1378
- }
1379
- function formatReturns(spy, results, msg, showActualReturn) {
1380
- if (results.length) msg += y.gray(`\n\nReceived:\n\n${results.map((callReturn, i) => {
1381
- let methodCall = y.bold(` ${ordinal(i + 1)} ${spy.getMockName()} call return:\n\n`);
1382
- if (showActualReturn) methodCall += diff(showActualReturn, callReturn.value, { omitAnnotationLines: true });
1383
- else methodCall += stringify(callReturn).split("\n").map((line) => ` ${line}`).join("\n");
1384
- methodCall += "\n";
1385
- return methodCall;
1386
- }).join("\n")}`);
1387
- msg += y.gray(`\n\nNumber of calls: ${y.bold(spy.mock.calls.length)}\n`);
1388
- return msg;
1389
- }
1390
- function getMatcherState(assertion, expect) {
1391
- const obj = assertion._obj;
1392
- const isNot = utils_exports.flag(assertion, "negate");
1393
- const promise = utils_exports.flag(assertion, "promise") || "";
1394
- const customMessage = utils_exports.flag(assertion, "message");
1395
- const jestUtils = {
1396
- ...getMatcherUtils(),
1397
- diff,
1398
- stringify,
1399
- iterableEquality,
1400
- subsetEquality
1401
- };
1402
- let task = utils_exports.flag(assertion, "vitest-test");
1403
- const currentTestName = task?.fullTestName ?? "";
1404
- if (task?.type !== "test") task = void 0;
1405
- const matcherState = {
1406
- ...getState(expect),
1407
- currentTestName,
1408
- customTesters: getCustomEqualityTesters(),
1409
- isNot,
1410
- utils: jestUtils,
1411
- promise,
1412
- equals,
1413
- suppressedErrors: [],
1414
- soft: utils_exports.flag(assertion, "soft"),
1415
- poll: utils_exports.flag(assertion, "poll"),
1416
- assertion
1417
- };
1418
- Object.assign(matcherState, { task });
1419
- return {
1420
- state: matcherState,
1421
- isNot,
1422
- obj,
1423
- customMessage
1424
- };
1425
- }
1426
- var JestExtendError = class extends Error {
1427
- constructor(message, actual, expected, __vitest_error_context__) {
1428
- super(message);
1429
- this.actual = actual;
1430
- this.expected = expected;
1431
- this.__vitest_error_context__ = __vitest_error_context__;
1432
- }
1433
- };
1434
- function JestExtendPlugin(c, expect, matchers) {
1435
- return (_, utils) => {
1436
- Object.entries(matchers).forEach(([expectAssertionName, expectAssertion]) => {
1437
- function __VITEST_EXTEND_ASSERTION__(...args) {
1438
- const { state, isNot, obj, customMessage } = getMatcherState(this, expect);
1439
- const result = expectAssertion.call(state, obj, ...args);
1440
- if (result && typeof result === "object" && typeof result.then === "function") return result.then(({ pass, message, actual, expected, meta }) => {
1441
- if (pass && isNot || !pass && !isNot) throw new JestExtendError((customMessage ? `${customMessage}: ` : "") + message(), actual, expected, {
1442
- assertionName: expectAssertionName,
1443
- meta
1444
- });
1445
- });
1446
- const { pass, message, actual, expected, meta } = result;
1447
- if (pass && isNot || !pass && !isNot) throw new JestExtendError((customMessage ? `${customMessage}: ` : "") + message(), actual, expected, {
1448
- assertionName: expectAssertionName,
1449
- meta
1450
- });
1451
- }
1452
- const softWrapper = wrapAssertion(utils, expectAssertionName, __VITEST_EXTEND_ASSERTION__);
1453
- utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, expectAssertionName, softWrapper);
1454
- utils.addMethod(c.Assertion.prototype, expectAssertionName, softWrapper);
1455
- if (expectAssertion.__vitest_poll_takeover__) {
1456
- const addedMethod = c.Assertion.prototype[expectAssertionName];
1457
- Object.defineProperty(addedMethod, "__vitest_poll_takeover__", { value: true });
1458
- }
1459
- class CustomMatcher extends AsymmetricMatcher {
1460
- constructor(inverse = false, ...sample) {
1461
- super(sample, inverse);
1462
- }
1463
- asymmetricMatch(other) {
1464
- const { pass } = expectAssertion.call(this.getMatcherContext(expect), other, ...this.sample);
1465
- return this.inverse ? !pass : pass;
1466
- }
1467
- toString() {
1468
- return `${this.inverse ? "not." : ""}${expectAssertionName}`;
1469
- }
1470
- getExpectedType() {
1471
- return "any";
1472
- }
1473
- toAsymmetricMatcher() {
1474
- return `${this.toString()}<${this.sample.map((item) => stringify(item)).join(", ")}>`;
1475
- }
1476
- }
1477
- const customMatcher = (...sample) => new CustomMatcher(false, ...sample);
1478
- Object.defineProperty(expect, expectAssertionName, {
1479
- configurable: true,
1480
- enumerable: true,
1481
- value: customMatcher,
1482
- writable: true
1483
- });
1484
- Object.defineProperty(expect.not, expectAssertionName, {
1485
- configurable: true,
1486
- enumerable: true,
1487
- value: (...sample) => new CustomMatcher(true, ...sample),
1488
- writable: true
1489
- });
1490
- Object.defineProperty(globalThis[ASYMMETRIC_MATCHERS_OBJECT], expectAssertionName, {
1491
- configurable: true,
1492
- enumerable: true,
1493
- value: customMatcher,
1494
- writable: true
1495
- });
1496
- });
1497
- };
1498
- }
1499
- const JestExtend = (chai, utils) => {
1500
- utils.addMethod(chai.expect, "extend", (expect, expects) => {
1501
- use(JestExtendPlugin(chai, expect, expects));
1502
- });
1503
- };
1504
- //#endregion
1505
- export { ASYMMETRIC_MATCHERS_OBJECT, Any, Anything, ArrayContaining, AsymmetricMatcher, ChaiStyleAssertions, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, JestAsymmetricMatchers, JestChaiExpect, JestExtend, MATCHERS_OBJECT, ObjectContaining, SchemaMatching, StringContaining, StringMatching, addCustomEqualityTesters, arrayBufferEquality, chai_exports as chai, createAssertionMessage, customMatchers, equals, fnNameFor, generateToBeMessage, getObjectKeys, getObjectSubset, getState, hasAsymmetric, hasProperty, isA, isAsymmetric, isError, isImmutableUnorderedKeyed, isImmutableUnorderedSet, isStandardSchema, iterableEquality, pluralize, recordAsyncExpect, setState, sparseArrayEquality, subsetEquality, typeEquality, wrapAssertion };
1506
-
1507
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJuYW1lcyI6WyJjIiwidXRpbCJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Adml0ZXN0K2V4cGVjdEA0LjEuMTAvbm9kZV9tb2R1bGVzL0B2aXRlc3QvZXhwZWN0L2Rpc3QvaW5kZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcHJpbnREaWZmT3JTdHJpbmdpZnksIGRpZmYgfSBmcm9tICdAdml0ZXN0L3V0aWxzL2RpZmYnO1xuaW1wb3J0IHsgc3RyaW5naWZ5IH0gZnJvbSAnQHZpdGVzdC91dGlscy9kaXNwbGF5JztcbmltcG9ydCB7IGdldFR5cGUsIGlzT2JqZWN0LCBub29wLCBhc3NlcnRUeXBlcywgb3JkaW5hbCB9IGZyb20gJ0B2aXRlc3QvdXRpbHMvaGVscGVycyc7XG5pbXBvcnQgYyBmcm9tICd0aW55cmFpbmJvdyc7XG5pbXBvcnQgeyBpc01vY2tGdW5jdGlvbiB9IGZyb20gJ0B2aXRlc3Qvc3B5JztcbmltcG9ydCB7IHByb2Nlc3NFcnJvciB9IGZyb20gJ0B2aXRlc3QvdXRpbHMvZXJyb3InO1xuaW1wb3J0IHsgdXNlLCB1dGlsIH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQgKiBhcyBjaGFpIGZyb20gJ2NoYWknO1xuZXhwb3J0IHsgY2hhaSB9O1xuXG5jb25zdCBDaGFpU3R5bGVBc3NlcnRpb25zID0gKGNoYWksIHV0aWxzKSA9PiB7XG5cdGZ1bmN0aW9uIGRlZlByb3BlcnR5KG5hbWUsIGRlbGVnYXRlVG8pIHtcblx0XHR1dGlscy5hZGRQcm9wZXJ0eShjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsIG5hbWUsIGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29uc3QgamVzdE1ldGhvZCA9IGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZVtkZWxlZ2F0ZVRvXTtcblx0XHRcdGlmICghamVzdE1ldGhvZCkge1xuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBkZWxlZ2F0ZSB0byAke1N0cmluZyhkZWxlZ2F0ZVRvKX06IG1ldGhvZCBub3QgZm91bmQuIEVuc3VyZSBKZXN0Q2hhaUV4cGVjdCBwbHVnaW4gaXMgbG9hZGVkIGZpcnN0LmApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGplc3RNZXRob2QuY2FsbCh0aGlzKTtcblx0XHR9KTtcblx0fVxuXHRmdW5jdGlvbiBkZWZQcm9wZXJ0eVdpdGhBcmdzKG5hbWUsIGRlbGVnYXRlVG8sIC4uLmFyZ3MpIHtcblx0XHR1dGlscy5hZGRQcm9wZXJ0eShjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsIG5hbWUsIGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29uc3QgamVzdE1ldGhvZCA9IGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZVtkZWxlZ2F0ZVRvXTtcblx0XHRcdGlmICghamVzdE1ldGhvZCkge1xuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBkZWxlZ2F0ZSB0byAke1N0cmluZyhkZWxlZ2F0ZVRvKX06IG1ldGhvZCBub3QgZm91bmQuIEVuc3VyZSBKZXN0Q2hhaUV4cGVjdCBwbHVnaW4gaXMgbG9hZGVkIGZpcnN0LmApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGplc3RNZXRob2QuY2FsbCh0aGlzLCAuLi5hcmdzKTtcblx0XHR9KTtcblx0fVxuXHRmdW5jdGlvbiBkZWZNZXRob2QobmFtZSwgZGVsZWdhdGVUbykge1xuXHRcdHV0aWxzLmFkZE1ldGhvZChjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsIG5hbWUsIGZ1bmN0aW9uKC4uLmFyZ3MpIHtcblx0XHRcdGNvbnN0IGplc3RNZXRob2QgPSBjaGFpLkFzc2VydGlvbi5wcm90b3R5cGVbZGVsZWdhdGVUb107XG5cdFx0XHRpZiAoIWplc3RNZXRob2QpIHtcblx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgZGVsZWdhdGUgdG8gJHtTdHJpbmcoZGVsZWdhdGVUbyl9OiBtZXRob2Qgbm90IGZvdW5kLiBFbnN1cmUgSmVzdENoYWlFeHBlY3QgcGx1Z2luIGlzIGxvYWRlZCBmaXJzdC5gKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBqZXN0TWV0aG9kLmNhbGwodGhpcywgLi4uYXJncyk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gQVBJIHRvIChzb21ld2hhdCkgbWlycm9yIHNpbm9uLWNoYWlcblx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL2NoYWlqcy9zaW5vbi1jaGFpXG5cdGRlZlByb3BlcnR5KFwiY2FsbGVkXCIsIFwidG9IYXZlQmVlbkNhbGxlZFwiKTtcblx0ZGVmUHJvcGVydHkoXCJjYWxsZWRPbmNlXCIsIFwidG9IYXZlQmVlbkNhbGxlZE9uY2VcIik7XG5cdGRlZlByb3BlcnR5V2l0aEFyZ3MoXCJjYWxsZWRUd2ljZVwiLCBcInRvSGF2ZUJlZW5DYWxsZWRUaW1lc1wiLCAyKTtcblx0ZGVmUHJvcGVydHlXaXRoQXJncyhcImNhbGxlZFRocmljZVwiLCBcInRvSGF2ZUJlZW5DYWxsZWRUaW1lc1wiLCAzKTtcblx0ZGVmTWV0aG9kKFwiY2FsbENvdW50XCIsIFwidG9IYXZlQmVlbkNhbGxlZFRpbWVzXCIpO1xuXHRkZWZNZXRob2QoXCJjYWxsZWRXaXRoXCIsIFwidG9IYXZlQmVlbkNhbGxlZFdpdGhcIik7XG5cdGRlZk1ldGhvZChcImNhbGxlZE9uY2VXaXRoXCIsIFwidG9IYXZlQmVlbkNhbGxlZEV4YWN0bHlPbmNlV2l0aFwiKTtcblx0ZGVmTWV0aG9kKFwibGFzdENhbGxlZFdpdGhcIiwgXCJ0b0hhdmVCZWVuTGFzdENhbGxlZFdpdGhcIik7XG5cdGRlZk1ldGhvZChcIm50aENhbGxlZFdpdGhcIiwgXCJ0b0hhdmVCZWVuTnRoQ2FsbGVkV2l0aFwiKTtcblx0ZGVmTWV0aG9kKFwicmV0dXJuZWRcIiwgXCJ0b0hhdmVSZXR1cm5lZFwiKTtcblx0ZGVmTWV0aG9kKFwicmV0dXJuZWRXaXRoXCIsIFwidG9IYXZlUmV0dXJuZWRXaXRoXCIpO1xuXHRkZWZNZXRob2QoXCJyZXR1cm5lZFRpbWVzXCIsIFwidG9IYXZlUmV0dXJuZWRUaW1lc1wiKTtcblx0ZGVmTWV0aG9kKFwibGFzdFJldHVybmVkV2l0aFwiLCBcInRvSGF2ZUxhc3RSZXR1cm5lZFdpdGhcIik7XG5cdGRlZk1ldGhvZChcIm50aFJldHVybmVkV2l0aFwiLCBcInRvSGF2ZU50aFJldHVybmVkV2l0aFwiKTtcblx0ZGVmTWV0aG9kKFwiY2FsbGVkQmVmb3JlXCIsIFwidG9IYXZlQmVlbkNhbGxlZEJlZm9yZVwiKTtcblx0ZGVmTWV0aG9kKFwiY2FsbGVkQWZ0ZXJcIiwgXCJ0b0hhdmVCZWVuQ2FsbGVkQWZ0ZXJcIik7XG5cdC8vIFRPRE86IGltcGxlbWVudFxuXHQvLyBkZWZNZXRob2QoJ3Rocm93bicsICd0b0hhdmVUaHJvd24nKVxufTtcblxuY29uc3QgTUFUQ0hFUlNfT0JKRUNUID0gU3ltYm9sLmZvcihcIm1hdGNoZXJzLW9iamVjdFwiKTtcbmNvbnN0IEpFU1RfTUFUQ0hFUlNfT0JKRUNUID0gU3ltYm9sLmZvcihcIiQkamVzdC1tYXRjaGVycy1vYmplY3RcIik7XG5jb25zdCBHTE9CQUxfRVhQRUNUID0gU3ltYm9sLmZvcihcImV4cGVjdC1nbG9iYWxcIik7XG5jb25zdCBBU1lNTUVUUklDX01BVENIRVJTX09CSkVDVCA9IFN5bWJvbC5mb3IoXCJhc3ltbWV0cmljLW1hdGNoZXJzLW9iamVjdFwiKTtcblxuLy8gc2VsZWN0aXZlbHkgcG9ydGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2plc3QtY29tbXVuaXR5L2plc3QtZXh0ZW5kZWRcbmNvbnN0IGN1c3RvbU1hdGNoZXJzID0ge1xuXHR0b1NhdGlzZnkoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuXHRcdGNvbnN0IHsgcHJpbnRSZWNlaXZlZCwgcHJpbnRFeHBlY3RlZCwgbWF0Y2hlckhpbnQgfSA9IHRoaXMudXRpbHM7XG5cdFx0Y29uc3QgcGFzcyA9IGV4cGVjdGVkKGFjdHVhbCk7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHBhc3MsXG5cdFx0XHRtZXNzYWdlOiAoKSA9PiBwYXNzID8gYFxcXG4ke21hdGNoZXJIaW50KFwiLm5vdC50b1NhdGlzZnlcIiwgXCJyZWNlaXZlZFwiLCBcIlwiKX1cblxuRXhwZWN0ZWQgdmFsdWUgdG8gbm90IHNhdGlzZnk6XG4ke21lc3NhZ2UgfHwgcHJpbnRFeHBlY3RlZChleHBlY3RlZCl9XG5SZWNlaXZlZDpcbiR7cHJpbnRSZWNlaXZlZChhY3R1YWwpfWAgOiBgXFxcbiR7bWF0Y2hlckhpbnQoXCIudG9TYXRpc2Z5XCIsIFwicmVjZWl2ZWRcIiwgXCJcIil9XG5cbkV4cGVjdGVkIHZhbHVlIHRvIHNhdGlzZnk6XG4ke21lc3NhZ2UgfHwgcHJpbnRFeHBlY3RlZChleHBlY3RlZCl9XG5cblJlY2VpdmVkOlxuJHtwcmludFJlY2VpdmVkKGFjdHVhbCl9YFxuXHRcdH07XG5cdH0sXG5cdHRvQmVPbmVPZihhY3R1YWwsIGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgeyBlcXVhbHMsIGN1c3RvbVRlc3RlcnMgfSA9IHRoaXM7XG5cdFx0Y29uc3QgeyBwcmludFJlY2VpdmVkLCBwcmludEV4cGVjdGVkLCBtYXRjaGVySGludCB9ID0gdGhpcy51dGlscztcblx0XHRsZXQgcGFzcztcblx0XHRpZiAoQXJyYXkuaXNBcnJheShleHBlY3RlZCkpIHtcblx0XHRcdHBhc3MgPSBleHBlY3RlZC5sZW5ndGggPT09IDAgfHwgZXhwZWN0ZWQuc29tZSgoaXRlbSkgPT4gZXF1YWxzKGl0ZW0sIGFjdHVhbCwgY3VzdG9tVGVzdGVycykpO1xuXHRcdH0gZWxzZSBpZiAoZXhwZWN0ZWQgaW5zdGFuY2VvZiBTZXQpIHtcblx0XHRcdHBhc3MgPSBleHBlY3RlZC5zaXplID09PSAwIHx8IGV4cGVjdGVkLmhhcyhhY3R1YWwpIHx8IFsuLi5leHBlY3RlZF0uc29tZSgoaXRlbSkgPT4gZXF1YWxzKGl0ZW0sIGFjdHVhbCwgY3VzdG9tVGVzdGVycykpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKGBZb3UgbXVzdCBwcm92aWRlIGFuIGFycmF5IG9yIHNldCB0byAke21hdGNoZXJIaW50KFwiLnRvQmVPbmVPZlwiKX0sIG5vdCAnJHt0eXBlb2YgZXhwZWN0ZWR9Jy5gKTtcblx0XHR9XG5cdFx0cmV0dXJuIHtcblx0XHRcdHBhc3MsXG5cdFx0XHRtZXNzYWdlOiAoKSA9PiBwYXNzID8gYFxcXG4ke21hdGNoZXJIaW50KFwiLm5vdC50b0JlT25lT2ZcIiwgXCJyZWNlaXZlZFwiLCBcIlwiKX1cblxuRXhwZWN0ZWQgdmFsdWUgdG8gbm90IGJlIG9uZSBvZjpcbiR7cHJpbnRFeHBlY3RlZChleHBlY3RlZCl9XG5SZWNlaXZlZDpcbiR7cHJpbnRSZWNlaXZlZChhY3R1YWwpfWAgOiBgXFxcbiR7bWF0Y2hlckhpbnQoXCIudG9CZU9uZU9mXCIsIFwicmVjZWl2ZWRcIiwgXCJcIil9XG5cbkV4cGVjdGVkIHZhbHVlIHRvIGJlIG9uZSBvZjpcbiR7cHJpbnRFeHBlY3RlZChleHBlY3RlZCl9XG5cblJlY2VpdmVkOlxuJHtwcmludFJlY2VpdmVkKGFjdHVhbCl9YFxuXHRcdH07XG5cdH1cbn07XG5cbmNvbnN0IEVYUEVDVEVEX0NPTE9SID0gYy5ncmVlbjtcbmNvbnN0IFJFQ0VJVkVEX0NPTE9SID0gYy5yZWQ7XG5jb25zdCBJTlZFUlRFRF9DT0xPUiA9IGMuaW52ZXJzZTtcbmNvbnN0IEJPTERfV0VJR0hUID0gYy5ib2xkO1xuY29uc3QgRElNX0NPTE9SID0gYy5kaW07XG5mdW5jdGlvbiBtYXRjaGVySGludChtYXRjaGVyTmFtZSwgcmVjZWl2ZWQgPSBcInJlY2VpdmVkXCIsIGV4cGVjdGVkID0gXCJleHBlY3RlZFwiLCBvcHRpb25zID0ge30pIHtcblx0Y29uc3QgeyBjb21tZW50ID0gXCJcIiwgaXNEaXJlY3RFeHBlY3RDYWxsID0gZmFsc2UsIGlzTm90ID0gZmFsc2UsIHByb21pc2UgPSBcIlwiLCBzZWNvbmRBcmd1bWVudCA9IFwiXCIsIGV4cGVjdGVkQ29sb3IgPSBFWFBFQ1RFRF9DT0xPUiwgcmVjZWl2ZWRDb2xvciA9IFJFQ0VJVkVEX0NPTE9SLCBzZWNvbmRBcmd1bWVudENvbG9yID0gRVhQRUNURURfQ09MT1IgfSA9IG9wdGlvbnM7XG5cdGxldCBoaW50ID0gXCJcIjtcblx0bGV0IGRpbVN0cmluZyA9IFwiZXhwZWN0XCI7XG5cdGlmICghaXNEaXJlY3RFeHBlY3RDYWxsICYmIHJlY2VpdmVkICE9PSBcIlwiKSB7XG5cdFx0aGludCArPSBESU1fQ09MT1IoYCR7ZGltU3RyaW5nfShgKSArIHJlY2VpdmVkQ29sb3IocmVjZWl2ZWQpO1xuXHRcdGRpbVN0cmluZyA9IFwiKVwiO1xuXHR9XG5cdGlmIChwcm9taXNlICE9PSBcIlwiKSB7XG5cdFx0aGludCArPSBESU1fQ09MT1IoYCR7ZGltU3RyaW5nfS5gKSArIHByb21pc2U7XG5cdFx0ZGltU3RyaW5nID0gXCJcIjtcblx0fVxuXHRpZiAoaXNOb3QpIHtcblx0XHRoaW50ICs9IGAke0RJTV9DT0xPUihgJHtkaW1TdHJpbmd9LmApfW5vdGA7XG5cdFx0ZGltU3RyaW5nID0gXCJcIjtcblx0fVxuXHRpZiAobWF0Y2hlck5hbWUuaW5jbHVkZXMoXCIuXCIpKSB7XG5cdFx0Ly8gT2xkIGZvcm1hdDogZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksXG5cdFx0Ly8gZXNwZWNpYWxseSB3aXRob3V0IHByb21pc2Ugb3IgaXNOb3Qgb3B0aW9uc1xuXHRcdGRpbVN0cmluZyArPSBtYXRjaGVyTmFtZTtcblx0fSBlbHNlIHtcblx0XHQvLyBOZXcgZm9ybWF0OiBvbWl0IHBlcmlvZCBmcm9tIG1hdGNoZXJOYW1lIGFyZ1xuXHRcdGhpbnQgKz0gRElNX0NPTE9SKGAke2RpbVN0cmluZ30uYCkgKyBtYXRjaGVyTmFtZTtcblx0XHRkaW1TdHJpbmcgPSBcIlwiO1xuXHR9XG5cdGlmIChleHBlY3RlZCA9PT0gXCJcIikge1xuXHRcdGRpbVN0cmluZyArPSBcIigpXCI7XG5cdH0gZWxzZSB7XG5cdFx0aGludCArPSBESU1fQ09MT1IoYCR7ZGltU3RyaW5nfShgKSArIGV4cGVjdGVkQ29sb3IoZXhwZWN0ZWQpO1xuXHRcdGlmIChzZWNvbmRBcmd1bWVudCkge1xuXHRcdFx0aGludCArPSBESU1fQ09MT1IoXCIsIFwiKSArIHNlY29uZEFyZ3VtZW50Q29sb3Ioc2Vjb25kQXJndW1lbnQpO1xuXHRcdH1cblx0XHRkaW1TdHJpbmcgPSBcIilcIjtcblx0fVxuXHRpZiAoY29tbWVudCAhPT0gXCJcIikge1xuXHRcdGRpbVN0cmluZyArPSBgIC8vICR7Y29tbWVudH1gO1xuXHR9XG5cdGlmIChkaW1TdHJpbmcgIT09IFwiXCIpIHtcblx0XHRoaW50ICs9IERJTV9DT0xPUihkaW1TdHJpbmcpO1xuXHR9XG5cdHJldHVybiBoaW50O1xufVxuY29uc3QgU1BBQ0VfU1lNQk9MID0gXCLCt1wiO1xuLy8gSW5zdGVhZCBvZiBpbnZlcnNlIGhpZ2hsaWdodCB3aGljaCBub3cgaW1wbGllcyBhIGNoYW5nZSxcbi8vIHJlcGxhY2UgY29tbW9uIHNwYWNlcyB3aXRoIG1pZGRsZSBkb3QgYXQgdGhlIGVuZCBvZiBhbnkgbGluZS5cbmZ1bmN0aW9uIHJlcGxhY2VUcmFpbGluZ1NwYWNlcyh0ZXh0KSB7XG5cdHJldHVybiB0ZXh0LnJlcGxhY2UoL1xccyskL2dtLCAoc3BhY2VzKSA9PiBTUEFDRV9TWU1CT0wucmVwZWF0KHNwYWNlcy5sZW5ndGgpKTtcbn1cbmZ1bmN0aW9uIHByaW50UmVjZWl2ZWQob2JqZWN0KSB7XG5cdHJldHVybiBSRUNFSVZFRF9DT0xPUihyZXBsYWNlVHJhaWxpbmdTcGFjZXMoc3RyaW5naWZ5KG9iamVjdCkpKTtcbn1cbmZ1bmN0aW9uIHByaW50RXhwZWN0ZWQodmFsdWUpIHtcblx0cmV0dXJuIEVYUEVDVEVEX0NPTE9SKHJlcGxhY2VUcmFpbGluZ1NwYWNlcyhzdHJpbmdpZnkodmFsdWUpKSk7XG59XG5mdW5jdGlvbiBnZXRNYXRjaGVyVXRpbHMoKSB7XG5cdHJldHVybiB7XG5cdFx0RVhQRUNURURfQ09MT1IsXG5cdFx0UkVDRUlWRURfQ09MT1IsXG5cdFx0SU5WRVJURURfQ09MT1IsXG5cdFx0Qk9MRF9XRUlHSFQsXG5cdFx0RElNX0NPTE9SLFxuXHRcdGRpZmYsXG5cdFx0bWF0Y2hlckhpbnQsXG5cdFx0cHJpbnRSZWNlaXZlZCxcblx0XHRwcmludEV4cGVjdGVkLFxuXHRcdHByaW50RGlmZk9yU3RyaW5naWZ5LFxuXHRcdHByaW50V2l0aFR5cGVcblx0fTtcbn1cbmZ1bmN0aW9uIHByaW50V2l0aFR5cGUobmFtZSwgdmFsdWUsIHByaW50KSB7XG5cdGNvbnN0IHR5cGUgPSBnZXRUeXBlKHZhbHVlKTtcblx0Y29uc3QgaGFzVHlwZSA9IHR5cGUgIT09IFwibnVsbFwiICYmIHR5cGUgIT09IFwidW5kZWZpbmVkXCIgPyBgJHtuYW1lfSBoYXMgdHlwZTogICR7dHlwZX1cXG5gIDogXCJcIjtcblx0Y29uc3QgaGFzVmFsdWUgPSBgJHtuYW1lfSBoYXMgdmFsdWU6ICR7cHJpbnQodmFsdWUpfWA7XG5cdHJldHVybiBoYXNUeXBlICsgaGFzVmFsdWU7XG59XG5mdW5jdGlvbiBhZGRDdXN0b21FcXVhbGl0eVRlc3RlcnMobmV3VGVzdGVycykge1xuXHRpZiAoIUFycmF5LmlzQXJyYXkobmV3VGVzdGVycykpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKGBleHBlY3QuY3VzdG9tRXF1YWxpdHlUZXN0ZXJzOiBNdXN0IGJlIHNldCB0byBhbiBhcnJheSBvZiBUZXN0ZXJzLiBXYXMgZ2l2ZW4gXCIke2dldFR5cGUobmV3VGVzdGVycyl9XCJgKTtcblx0fVxuXHRnbG9iYWxUaGlzW0pFU1RfTUFUQ0hFUlNfT0JKRUNUXS5jdXN0b21FcXVhbGl0eVRlc3RlcnMucHVzaCguLi5uZXdUZXN0ZXJzKTtcbn1cbmZ1bmN0aW9uIGdldEN1c3RvbUVxdWFsaXR5VGVzdGVycygpIHtcblx0cmV0dXJuIGdsb2JhbFRoaXNbSkVTVF9NQVRDSEVSU19PQkpFQ1RdLmN1c3RvbUVxdWFsaXR5VGVzdGVycztcbn1cblxuLy8gRXh0cmFjdGVkIG91dCBvZiBqYXNtaW5lIDIuNS4yXG5mdW5jdGlvbiBlcXVhbHMoYSwgYiwgY3VzdG9tVGVzdGVycywgc3RyaWN0Q2hlY2spIHtcblx0Y3VzdG9tVGVzdGVycyA9IGN1c3RvbVRlc3RlcnMgfHwgW107XG5cdHJldHVybiBlcShhLCBiLCBbXSwgW10sIGN1c3RvbVRlc3RlcnMsIHN0cmljdENoZWNrID8gaGFzS2V5IDogaGFzRGVmaW5lZEtleSk7XG59XG5jb25zdCBmdW5jdGlvblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xuZnVuY3Rpb24gaXNBc3ltbWV0cmljKG9iaikge1xuXHRyZXR1cm4gISFvYmogJiYgdHlwZW9mIG9iaiA9PT0gXCJvYmplY3RcIiAmJiBcImFzeW1tZXRyaWNNYXRjaFwiIGluIG9iaiAmJiBpc0EoXCJGdW5jdGlvblwiLCBvYmouYXN5bW1ldHJpY01hdGNoKTtcbn1cbmZ1bmN0aW9uIGhhc0FzeW1tZXRyaWMob2JqLCBzZWVuID0gbmV3IFNldCgpKSB7XG5cdGlmIChzZWVuLmhhcyhvYmopKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdHNlZW4uYWRkKG9iaik7XG5cdGlmIChpc0FzeW1tZXRyaWMob2JqKSkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcblx0XHRyZXR1cm4gb2JqLnNvbWUoKGkpID0+IGhhc0FzeW1tZXRyaWMoaSwgc2VlbikpO1xuXHR9XG5cdGlmIChvYmogaW5zdGFuY2VvZiBTZXQpIHtcblx0XHRyZXR1cm4gQXJyYXkuZnJvbShvYmopLnNvbWUoKGkpID0+IGhhc0FzeW1tZXRyaWMoaSwgc2VlbikpO1xuXHR9XG5cdGlmIChpc09iamVjdChvYmopKSB7XG5cdFx0cmV0dXJuIE9iamVjdC52YWx1ZXMob2JqKS5zb21lKCh2KSA9PiBoYXNBc3ltbWV0cmljKHYsIHNlZW4pKTtcblx0fVxuXHRyZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBhc3ltbWV0cmljTWF0Y2goYSwgYiwgY3VzdG9tVGVzdGVycykge1xuXHRjb25zdCBhc3ltbWV0cmljQSA9IGlzQXN5bW1ldHJpYyhhKTtcblx0Y29uc3QgYXN5bW1ldHJpY0IgPSBpc0FzeW1tZXRyaWMoYik7XG5cdGlmIChhc3ltbWV0cmljQSAmJiBhc3ltbWV0cmljQikge1xuXHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdH1cblx0aWYgKGFzeW1tZXRyaWNBKSB7XG5cdFx0cmV0dXJuIGEuYXN5bW1ldHJpY01hdGNoKGIsIGN1c3RvbVRlc3RlcnMpO1xuXHR9XG5cdGlmIChhc3ltbWV0cmljQikge1xuXHRcdHJldHVybiBiLmFzeW1tZXRyaWNNYXRjaChhLCBjdXN0b21UZXN0ZXJzKTtcblx0fVxufVxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2plc3Rqcy9qZXN0L2Jsb2IvOTA1YmNiY2VkM2Q0MGNkZjdhYWRjNGNkZjZmYjczMWM0YmIzZGJlMy9wYWNrYWdlcy9leHBlY3QtdXRpbHMvc3JjL3V0aWxzLnRzI0w1MDlcbmZ1bmN0aW9uIGlzRXJyb3IodmFsdWUpIHtcblx0aWYgKHR5cGVvZiBFcnJvci5pc0Vycm9yID09PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRyZXR1cm4gRXJyb3IuaXNFcnJvcih2YWx1ZSk7XG5cdH1cblx0c3dpdGNoIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpKSB7XG5cdFx0Y2FzZSBcIltvYmplY3QgRXJyb3JdXCI6XG5cdFx0Y2FzZSBcIltvYmplY3QgRXhjZXB0aW9uXVwiOlxuXHRcdGNhc2UgXCJbb2JqZWN0IERPTUV4Y2VwdGlvbl1cIjogcmV0dXJuIHRydWU7XG5cdFx0ZGVmYXVsdDogcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgRXJyb3I7XG5cdH1cbn1cbi8vIEVxdWFsaXR5IGZ1bmN0aW9uIGxvdmluZ2x5IGFkYXB0ZWQgZnJvbSBpc0VxdWFsIGluXG4vLyAgIFtVbmRlcnNjb3JlXShodHRwOi8vdW5kZXJzY29yZWpzLm9yZylcbmZ1bmN0aW9uIGVxKGEsIGIsIGFTdGFjaywgYlN0YWNrLCBjdXN0b21UZXN0ZXJzLCBoYXNLZXkpIHtcblx0bGV0IHJlc3VsdCA9IHRydWU7XG5cdGNvbnN0IGFzeW1tZXRyaWNSZXN1bHQgPSBhc3ltbWV0cmljTWF0Y2goYSwgYiwgY3VzdG9tVGVzdGVycyk7XG5cdGlmIChhc3ltbWV0cmljUmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gYXN5bW1ldHJpY1Jlc3VsdDtcblx0fVxuXHRjb25zdCB0ZXN0ZXJDb250ZXh0ID0geyBlcXVhbHMgfTtcblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBjdXN0b21UZXN0ZXJzLmxlbmd0aDsgaSsrKSB7XG5cdFx0Y29uc3QgY3VzdG9tVGVzdGVyUmVzdWx0ID0gY3VzdG9tVGVzdGVyc1tpXS5jYWxsKHRlc3RlckNvbnRleHQsIGEsIGIsIGN1c3RvbVRlc3RlcnMpO1xuXHRcdGlmIChjdXN0b21UZXN0ZXJSZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0cmV0dXJuIGN1c3RvbVRlc3RlclJlc3VsdDtcblx0XHR9XG5cdH1cblx0aWYgKHR5cGVvZiBVUkwgPT09IFwiZnVuY3Rpb25cIiAmJiBhIGluc3RhbmNlb2YgVVJMICYmIGIgaW5zdGFuY2VvZiBVUkwpIHtcblx0XHRyZXR1cm4gYS5ocmVmID09PSBiLmhyZWY7XG5cdH1cblx0aWYgKE9iamVjdC5pcyhhLCBiKSkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdC8vIEEgc3RyaWN0IGNvbXBhcmlzb24gaXMgbmVjZXNzYXJ5IGJlY2F1c2UgYG51bGwgPT0gdW5kZWZpbmVkYC5cblx0aWYgKGEgPT09IG51bGwgfHwgYiA9PT0gbnVsbCkge1xuXHRcdHJldHVybiBhID09PSBiO1xuXHR9XG5cdGNvbnN0IGNsYXNzTmFtZSA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhKTtcblx0aWYgKGNsYXNzTmFtZSAhPT0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGIpKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdHN3aXRjaCAoY2xhc3NOYW1lKSB7XG5cdFx0Y2FzZSBcIltvYmplY3QgQm9vbGVhbl1cIjpcblx0XHRjYXNlIFwiW29iamVjdCBTdHJpbmddXCI6XG5cdFx0Y2FzZSBcIltvYmplY3QgTnVtYmVyXVwiOiBpZiAodHlwZW9mIGEgIT09IHR5cGVvZiBiKSB7XG5cdFx0XHQvLyBPbmUgaXMgYSBwcmltaXRpdmUsIG9uZSBhIGBuZXcgUHJpbWl0aXZlKClgXG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fSBlbHNlIGlmICh0eXBlb2YgYSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgYiAhPT0gXCJvYmplY3RcIikge1xuXHRcdFx0Ly8gYm90aCBhcmUgcHJvcGVyIHByaW1pdGl2ZXNcblx0XHRcdHJldHVybiBPYmplY3QuaXMoYSwgYik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIGJvdGggYXJlIGBuZXcgUHJpbWl0aXZlKClgc1xuXHRcdFx0cmV0dXJuIE9iamVjdC5pcyhhLnZhbHVlT2YoKSwgYi52YWx1ZU9mKCkpO1xuXHRcdH1cblx0XHRjYXNlIFwiW29iamVjdCBEYXRlXVwiOiB7XG5cdFx0XHRjb25zdCBudW1BID0gK2E7XG5cdFx0XHRjb25zdCBudW1CID0gK2I7XG5cdFx0XHQvLyBDb2VyY2UgZGF0ZXMgdG8gbnVtZXJpYyBwcmltaXRpdmUgdmFsdWVzLiBEYXRlcyBhcmUgY29tcGFyZWQgYnkgdGhlaXJcblx0XHRcdC8vIG1pbGxpc2Vjb25kIHJlcHJlc2VudGF0aW9ucy4gTm90ZSB0aGF0IGludmFsaWQgZGF0ZXMgd2l0aCBtaWxsaXNlY29uZCByZXByZXNlbnRhdGlvbnNcblx0XHRcdC8vIG9mIGBOYU5gIGFyZSBlcXVpdmFsZW50LlxuXHRcdFx0cmV0dXJuIG51bUEgPT09IG51bUIgfHwgTnVtYmVyLmlzTmFOKG51bUEpICYmIE51bWJlci5pc05hTihudW1CKTtcblx0XHR9XG5cdFx0Y2FzZSBcIltvYmplY3QgUmVnRXhwXVwiOiByZXR1cm4gYS5zb3VyY2UgPT09IGIuc291cmNlICYmIGEuZmxhZ3MgPT09IGIuZmxhZ3M7XG5cdFx0Y2FzZSBcIltvYmplY3QgVGVtcG9yYWwuSW5zdGFudF1cIjpcblx0XHRjYXNlIFwiW29iamVjdCBUZW1wb3JhbC5ab25lZERhdGVUaW1lXVwiOlxuXHRcdGNhc2UgXCJbb2JqZWN0IFRlbXBvcmFsLlBsYWluRGF0ZVRpbWVdXCI6XG5cdFx0Y2FzZSBcIltvYmplY3QgVGVtcG9yYWwuUGxhaW5EYXRlXVwiOlxuXHRcdGNhc2UgXCJbb2JqZWN0IFRlbXBvcmFsLlBsYWluVGltZV1cIjpcblx0XHRjYXNlIFwiW29iamVjdCBUZW1wb3JhbC5QbGFpblllYXJNb250aF1cIjpcblx0XHRjYXNlIFwiW29iamVjdCBUZW1wb3JhbC5QbGFpbk1vbnRoRGF5XVwiOiByZXR1cm4gYS5lcXVhbHMoYik7XG5cdFx0Y2FzZSBcIltvYmplY3QgVGVtcG9yYWwuRHVyYXRpb25dXCI6IHJldHVybiBhLnRvU3RyaW5nKCkgPT09IGIudG9TdHJpbmcoKTtcblx0fVxuXHRpZiAodHlwZW9mIGEgIT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIGIgIT09IFwib2JqZWN0XCIpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0Ly8gVXNlIERPTTMgbWV0aG9kIGlzRXF1YWxOb2RlIChJRT49OSlcblx0aWYgKGlzRG9tTm9kZShhKSAmJiBpc0RvbU5vZGUoYikpIHtcblx0XHRyZXR1cm4gYS5pc0VxdWFsTm9kZShiKTtcblx0fVxuXHQvLyBVc2VkIHRvIGRldGVjdCBjaXJjdWxhciByZWZlcmVuY2VzLlxuXHRsZXQgbGVuZ3RoID0gYVN0YWNrLmxlbmd0aDtcblx0d2hpbGUgKGxlbmd0aC0tKSB7XG5cdFx0Ly8gTGluZWFyIHNlYXJjaC4gUGVyZm9ybWFuY2UgaXMgaW52ZXJzZWx5IHByb3BvcnRpb25hbCB0byB0aGUgbnVtYmVyIG9mXG5cdFx0Ly8gdW5pcXVlIG5lc3RlZCBzdHJ1Y3R1cmVzLlxuXHRcdC8vIGNpcmN1bGFyIHJlZmVyZW5jZXMgYXQgc2FtZSBkZXB0aCBhcmUgZXF1YWxcblx0XHQvLyBjaXJjdWxhciByZWZlcmVuY2UgaXMgbm90IGVxdWFsIHRvIG5vbi1jaXJjdWxhciBvbmVcblx0XHRpZiAoYVN0YWNrW2xlbmd0aF0gPT09IGEpIHtcblx0XHRcdHJldHVybiBiU3RhY2tbbGVuZ3RoXSA9PT0gYjtcblx0XHR9IGVsc2UgaWYgKGJTdGFja1tsZW5ndGhdID09PSBiKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cdC8vIEFkZCB0aGUgZmlyc3Qgb2JqZWN0IHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cblx0YVN0YWNrLnB1c2goYSk7XG5cdGJTdGFjay5wdXNoKGIpO1xuXHQvLyBSZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgYW5kIGFycmF5cy5cblx0Ly8gQ29tcGFyZSBhcnJheSBsZW5ndGhzIHRvIGRldGVybWluZSBpZiBhIGRlZXAgY29tcGFyaXNvbiBpcyBuZWNlc3NhcnkuXG5cdGlmIChjbGFzc05hbWUgPT09IFwiW29iamVjdCBBcnJheV1cIiAmJiBhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0aWYgKGlzRXJyb3IoYSkgJiYgaXNFcnJvcihiKSkge1xuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gaXNFcnJvckVxdWFsKGEsIGIsIGFTdGFjaywgYlN0YWNrLCBjdXN0b21UZXN0ZXJzLCBoYXNLZXkpO1xuXHRcdH0gZmluYWxseSB7XG5cdFx0XHRhU3RhY2sucG9wKCk7XG5cdFx0XHRiU3RhY2sucG9wKCk7XG5cdFx0fVxuXHR9XG5cdC8vIERlZXAgY29tcGFyZSBvYmplY3RzLlxuXHRjb25zdCBhS2V5cyA9IGtleXMoYSwgaGFzS2V5KTtcblx0bGV0IGtleTtcblx0bGV0IHNpemUgPSBhS2V5cy5sZW5ndGg7XG5cdC8vIEVuc3VyZSB0aGF0IGJvdGggb2JqZWN0cyBjb250YWluIHRoZSBzYW1lIG51bWJlciBvZiBwcm9wZXJ0aWVzIGJlZm9yZSBjb21wYXJpbmcgZGVlcCBlcXVhbGl0eS5cblx0aWYgKGtleXMoYiwgaGFzS2V5KS5sZW5ndGggIT09IHNpemUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0d2hpbGUgKHNpemUtLSkge1xuXHRcdGtleSA9IGFLZXlzW3NpemVdO1xuXHRcdC8vIERlZXAgY29tcGFyZSBlYWNoIG1lbWJlclxuXHRcdHJlc3VsdCA9IGhhc0tleShiLCBrZXkpICYmIGVxKGFba2V5XSwgYltrZXldLCBhU3RhY2ssIGJTdGFjaywgY3VzdG9tVGVzdGVycywgaGFzS2V5KTtcblx0XHRpZiAoIXJlc3VsdCkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fVxuXHQvLyBSZW1vdmUgdGhlIGZpcnN0IG9iamVjdCBmcm9tIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cblx0YVN0YWNrLnBvcCgpO1xuXHRiU3RhY2sucG9wKCk7XG5cdHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBpc0Vycm9yRXF1YWwoYSwgYiwgYVN0YWNrLCBiU3RhY2ssIGN1c3RvbVRlc3RlcnMsIGhhc0tleSkge1xuXHQvLyBodHRwczovL25vZGVqcy5vcmcvZG9jcy9sYXRlc3QtdjIyLngvYXBpL2Fzc2VydC5odG1sI2NvbXBhcmlzb24tZGV0YWlsc1xuXHQvLyAtIFtbUHJvdG90eXBlXV0gb2Ygb2JqZWN0cyBhcmUgY29tcGFyZWQgdXNpbmcgdGhlID09PSBvcGVyYXRvci5cblx0Ly8gLSBPbmx5IGVudW1lcmFibGUgXCJvd25cIiBwcm9wZXJ0aWVzIGFyZSBjb25zaWRlcmVkLlxuXHQvLyAtIEVycm9yIG5hbWVzLCBtZXNzYWdlcywgY2F1c2VzLCBhbmQgZXJyb3JzIGFyZSBhbHdheXMgY29tcGFyZWQsIGV2ZW4gaWYgdGhlc2UgYXJlIG5vdCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuIGVycm9ycyBpcyBhbHNvIGNvbXBhcmVkLlxuXHRsZXQgcmVzdWx0ID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGEpID09PSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYikgJiYgYS5uYW1lID09PSBiLm5hbWUgJiYgYS5tZXNzYWdlID09PSBiLm1lc3NhZ2U7XG5cdC8vIGNoZWNrIEVycm9yLmNhdXNlIGFzeW1tZXRyaWNhbGx5XG5cdGlmICh0eXBlb2YgYi5jYXVzZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuXHRcdHJlc3VsdCAmJj0gZXEoYS5jYXVzZSwgYi5jYXVzZSwgYVN0YWNrLCBiU3RhY2ssIGN1c3RvbVRlc3RlcnMsIGhhc0tleSk7XG5cdH1cblx0Ly8gQWdncmVnYXRlRXJyb3IuZXJyb3JzXG5cdGlmIChhIGluc3RhbmNlb2YgQWdncmVnYXRlRXJyb3IgJiYgYiBpbnN0YW5jZW9mIEFnZ3JlZ2F0ZUVycm9yKSB7XG5cdFx0cmVzdWx0ICYmPSBlcShhLmVycm9ycywgYi5lcnJvcnMsIGFTdGFjaywgYlN0YWNrLCBjdXN0b21UZXN0ZXJzLCBoYXNLZXkpO1xuXHR9XG5cdC8vIHNwcmVhZCB0byBjb21wYXJlIGVudW1lcmFibGUgcHJvcGVydGllc1xuXHRyZXN1bHQgJiY9IGVxKHsgLi4uYSB9LCB7IC4uLmIgfSwgYVN0YWNrLCBiU3RhY2ssIGN1c3RvbVRlc3RlcnMsIGhhc0tleSk7XG5cdHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBrZXlzKG9iaiwgaGFzS2V5KSB7XG5cdGNvbnN0IGtleXMgPSBbXTtcblx0Zm9yIChjb25zdCBrZXkgaW4gb2JqKSB7XG5cdFx0aWYgKGhhc0tleShvYmosIGtleSkpIHtcblx0XHRcdGtleXMucHVzaChrZXkpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4ga2V5cy5jb25jYXQoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmopLmZpbHRlcigoc3ltYm9sKSA9PiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgc3ltYm9sKS5lbnVtZXJhYmxlKSk7XG59XG5mdW5jdGlvbiBoYXNEZWZpbmVkS2V5KG9iaiwga2V5KSB7XG5cdHJldHVybiBoYXNLZXkob2JqLCBrZXkpICYmIG9ialtrZXldICE9PSB1bmRlZmluZWQ7XG59XG5mdW5jdGlvbiBoYXNLZXkob2JqLCBrZXkpIHtcblx0cmV0dXJuIE9iamVjdC5oYXNPd24ob2JqLCBrZXkpO1xufVxuZnVuY3Rpb24gaXNBKHR5cGVOYW1lLCB2YWx1ZSkge1xuXHRyZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5hcHBseSh2YWx1ZSkgPT09IGBbb2JqZWN0ICR7dHlwZU5hbWV9XWA7XG59XG5mdW5jdGlvbiBpc0RvbU5vZGUob2JqKSB7XG5cdHJldHVybiBvYmogIT09IG51bGwgJiYgdHlwZW9mIG9iaiA9PT0gXCJvYmplY3RcIiAmJiBcIm5vZGVUeXBlXCIgaW4gb2JqICYmIHR5cGVvZiBvYmoubm9kZVR5cGUgPT09IFwibnVtYmVyXCIgJiYgXCJub2RlTmFtZVwiIGluIG9iaiAmJiB0eXBlb2Ygb2JqLm5vZGVOYW1lID09PSBcInN0cmluZ1wiICYmIFwiaXNFcXVhbE5vZGVcIiBpbiBvYmogJiYgdHlwZW9mIG9iai5pc0VxdWFsTm9kZSA9PT0gXCJmdW5jdGlvblwiO1xufVxuZnVuY3Rpb24gZm5OYW1lRm9yKGZ1bmMpIHtcblx0aWYgKGZ1bmMubmFtZSkge1xuXHRcdHJldHVybiBmdW5jLm5hbWU7XG5cdH1cblx0Y29uc3QgbWF0Y2hlcyA9IGZ1bmN0aW9uVG9TdHJpbmcuY2FsbChmdW5jKS5tYXRjaCgvXig/OmFzeW5jKT9cXHMqZnVuY3Rpb25cXHMqKD86XFwqXFxzKik/KFtcXHckXSspXFxzKlxcKC8pO1xuXHRyZXR1cm4gbWF0Y2hlcyA/IG1hdGNoZXNbMV0gOiBcIjxhbm9ueW1vdXM+XCI7XG59XG5mdW5jdGlvbiBnZXRQcm90b3R5cGUob2JqKSB7XG5cdGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YpIHtcblx0XHRyZXR1cm4gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iaik7XG5cdH1cblx0aWYgKG9iai5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgPT09IG9iaikge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cdHJldHVybiBvYmouY29uc3RydWN0b3IucHJvdG90eXBlO1xufVxuZnVuY3Rpb24gaGFzUHJvcGVydHkob2JqLCBwcm9wZXJ0eSkge1xuXHRpZiAoIW9iaikge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHRpZiAoT2JqZWN0Lmhhc093bihvYmosIHByb3BlcnR5KSkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHJldHVybiBoYXNQcm9wZXJ0eShnZXRQcm90b3R5cGUob2JqKSwgcHJvcGVydHkpO1xufVxuLy8gU0VOVElORUwgY29uc3RhbnRzIGFyZSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9pbW11dGFibGUtanNcbmNvbnN0IElTX0tFWUVEX1NFTlRJTkVMID0gXCJAQF9fSU1NVVRBQkxFX0tFWUVEX19AQFwiO1xuY29uc3QgSVNfU0VUX1NFTlRJTkVMID0gXCJAQF9fSU1NVVRBQkxFX1NFVF9fQEBcIjtcbmNvbnN0IElTX0xJU1RfU0VOVElORUwgPSBcIkBAX19JTU1VVEFCTEVfTElTVF9fQEBcIjtcbmNvbnN0IElTX09SREVSRURfU0VOVElORUwgPSBcIkBAX19JTU1VVEFCTEVfT1JERVJFRF9fQEBcIjtcbmNvbnN0IElTX1JFQ09SRF9TWU1CT0wgPSBcIkBAX19JTU1VVEFCTEVfUkVDT1JEX19AQFwiO1xuZnVuY3Rpb24gaXNJbW11dGFibGVVbm9yZGVyZWRLZXllZChtYXliZUtleWVkKSB7XG5cdHJldHVybiAhIShtYXliZUtleWVkICYmIG1heWJlS2V5ZWRbSVNfS0VZRURfU0VOVElORUxdICYmICFtYXliZUtleWVkW0lTX09SREVSRURfU0VOVElORUxdKTtcbn1cbmZ1bmN0aW9uIGlzSW1tdXRhYmxlVW5vcmRlcmVkU2V0KG1heWJlU2V0KSB7XG5cdHJldHVybiAhIShtYXliZVNldCAmJiBtYXliZVNldFtJU19TRVRfU0VOVElORUxdICYmICFtYXliZVNldFtJU19PUkRFUkVEX1NFTlRJTkVMXSk7XG59XG5mdW5jdGlvbiBpc09iamVjdExpdGVyYWwoc291cmNlKSB7XG5cdHJldHVybiBzb3VyY2UgIT0gbnVsbCAmJiB0eXBlb2Ygc291cmNlID09PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KHNvdXJjZSk7XG59XG5mdW5jdGlvbiBpc0ltbXV0YWJsZUxpc3Qoc291cmNlKSB7XG5cdHJldHVybiBCb29sZWFuKHNvdXJjZSAmJiBpc09iamVjdExpdGVyYWwoc291cmNlKSAmJiBzb3VyY2VbSVNfTElTVF9TRU5USU5FTF0pO1xufVxuZnVuY3Rpb24gaXNJbW11dGFibGVPcmRlcmVkS2V5ZWQoc291cmNlKSB7XG5cdHJldHVybiBCb29sZWFuKHNvdXJjZSAmJiBpc09iamVjdExpdGVyYWwoc291cmNlKSAmJiBzb3VyY2VbSVNfS0VZRURfU0VOVElORUxdICYmIHNvdXJjZVtJU19PUkRFUkVEX1NFTlRJTkVMXSk7XG59XG5mdW5jdGlvbiBpc0ltbXV0YWJsZU9yZGVyZWRTZXQoc291cmNlKSB7XG5cdHJldHVybiBCb29sZWFuKHNvdXJjZSAmJiBpc09iamVjdExpdGVyYWwoc291cmNlKSAmJiBzb3VyY2VbSVNfU0VUX1NFTlRJTkVMXSAmJiBzb3VyY2VbSVNfT1JERVJFRF9TRU5USU5FTF0pO1xufVxuZnVuY3Rpb24gaXNJbW11dGFibGVSZWNvcmQoc291cmNlKSB7XG5cdHJldHVybiBCb29sZWFuKHNvdXJjZSAmJiBpc09iamVjdExpdGVyYWwoc291cmNlKSAmJiBzb3VyY2VbSVNfUkVDT1JEX1NZTUJPTF0pO1xufVxuLyoqXG4qIENvcHlyaWdodCAoYykgRmFjZWJvb2ssIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuKlxuKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuKlxuKi9cbmNvbnN0IEl0ZXJhdG9yU3ltYm9sID0gU3ltYm9sLml0ZXJhdG9yO1xuZnVuY3Rpb24gaGFzSXRlcmF0b3Iob2JqZWN0KSB7XG5cdHJldHVybiAhIShvYmplY3QgIT0gbnVsbCAmJiBvYmplY3RbSXRlcmF0b3JTeW1ib2xdKTtcbn1cbmZ1bmN0aW9uIGl0ZXJhYmxlRXF1YWxpdHkoYSwgYiwgY3VzdG9tVGVzdGVycyA9IFtdLCBhU3RhY2sgPSBbXSwgYlN0YWNrID0gW10pIHtcblx0aWYgKHR5cGVvZiBhICE9PSBcIm9iamVjdFwiIHx8IHR5cGVvZiBiICE9PSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoYSkgfHwgQXJyYXkuaXNBcnJheShiKSB8fCAhaGFzSXRlcmF0b3IoYSkgfHwgIWhhc0l0ZXJhdG9yKGIpKSB7XG5cdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0fVxuXHRpZiAoYS5jb25zdHJ1Y3RvciAhPT0gYi5jb25zdHJ1Y3Rvcikge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHRsZXQgbGVuZ3RoID0gYVN0YWNrLmxlbmd0aDtcblx0d2hpbGUgKGxlbmd0aC0tKSB7XG5cdFx0Ly8gTGluZWFyIHNlYXJjaC4gUGVyZm9ybWFuY2UgaXMgaW52ZXJzZWx5IHByb3BvcnRpb25hbCB0byB0aGUgbnVtYmVyIG9mXG5cdFx0Ly8gdW5pcXVlIG5lc3RlZCBzdHJ1Y3R1cmVzLlxuXHRcdC8vIGNpcmN1bGFyIHJlZmVyZW5jZXMgYXQgc2FtZSBkZXB0aCBhcmUgZXF1YWxcblx0XHQvLyBjaXJjdWxhciByZWZlcmVuY2UgaXMgbm90IGVxdWFsIHRvIG5vbi1jaXJjdWxhciBvbmVcblx0XHRpZiAoYVN0YWNrW2xlbmd0aF0gPT09IGEpIHtcblx0XHRcdHJldHVybiBiU3RhY2tbbGVuZ3RoXSA9PT0gYjtcblx0XHR9XG5cdH1cblx0YVN0YWNrLnB1c2goYSk7XG5cdGJTdGFjay5wdXNoKGIpO1xuXHRjb25zdCBmaWx0ZXJlZEN1c3RvbVRlc3RlcnMgPSBbLi4uY3VzdG9tVGVzdGVycy5maWx0ZXIoKHQpID0+IHQgIT09IGl0ZXJhYmxlRXF1YWxpdHkpLCBpdGVyYWJsZUVxdWFsaXR5V2l0aFN0YWNrXTtcblx0ZnVuY3Rpb24gaXRlcmFibGVFcXVhbGl0eVdpdGhTdGFjayhhLCBiKSB7XG5cdFx0cmV0dXJuIGl0ZXJhYmxlRXF1YWxpdHkoYSwgYiwgWy4uLmN1c3RvbVRlc3RlcnNdLCBbLi4uYVN0YWNrXSwgWy4uLmJTdGFja10pO1xuXHR9XG5cdGlmIChhLnNpemUgIT09IHVuZGVmaW5lZCkge1xuXHRcdGlmIChhLnNpemUgIT09IGIuc2l6ZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH0gZWxzZSBpZiAoaXNBKFwiU2V0XCIsIGEpIHx8IGlzSW1tdXRhYmxlVW5vcmRlcmVkU2V0KGEpKSB7XG5cdFx0XHRsZXQgYWxsRm91bmQgPSB0cnVlO1xuXHRcdFx0Zm9yIChjb25zdCBhVmFsdWUgb2YgYSkge1xuXHRcdFx0XHRpZiAoIWIuaGFzKGFWYWx1ZSkpIHtcblx0XHRcdFx0XHRsZXQgaGFzID0gZmFsc2U7XG5cdFx0XHRcdFx0Zm9yIChjb25zdCBiVmFsdWUgb2YgYikge1xuXHRcdFx0XHRcdFx0Y29uc3QgaXNFcXVhbCA9IGVxdWFscyhhVmFsdWUsIGJWYWx1ZSwgZmlsdGVyZWRDdXN0b21UZXN0ZXJzKTtcblx0XHRcdFx0XHRcdGlmIChpc0VxdWFsID09PSB0cnVlKSB7XG5cdFx0XHRcdFx0XHRcdGhhcyA9IHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmIChoYXMgPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0XHRhbGxGb3VuZCA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHQvLyBSZW1vdmUgdGhlIGZpcnN0IHZhbHVlIGZyb20gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCB2YWx1ZXMuXG5cdFx0XHRhU3RhY2sucG9wKCk7XG5cdFx0XHRiU3RhY2sucG9wKCk7XG5cdFx0XHRyZXR1cm4gYWxsRm91bmQ7XG5cdFx0fSBlbHNlIGlmIChpc0EoXCJNYXBcIiwgYSkgfHwgaXNJbW11dGFibGVVbm9yZGVyZWRLZXllZChhKSkge1xuXHRcdFx0bGV0IGFsbEZvdW5kID0gdHJ1ZTtcblx0XHRcdGZvciAoY29uc3QgYUVudHJ5IG9mIGEpIHtcblx0XHRcdFx0aWYgKCFiLmhhcyhhRW50cnlbMF0pIHx8ICFlcXVhbHMoYUVudHJ5WzFdLCBiLmdldChhRW50cnlbMF0pLCBmaWx0ZXJlZEN1c3RvbVRlc3RlcnMpKSB7XG5cdFx0XHRcdFx0bGV0IGhhcyA9IGZhbHNlO1xuXHRcdFx0XHRcdGZvciAoY29uc3QgYkVudHJ5IG9mIGIpIHtcblx0XHRcdFx0XHRcdGNvbnN0IG1hdGNoZWRLZXkgPSBlcXVhbHMoYUVudHJ5WzBdLCBiRW50cnlbMF0sIGZpbHRlcmVkQ3VzdG9tVGVzdGVycyk7XG5cdFx0XHRcdFx0XHRsZXQgbWF0Y2hlZFZhbHVlID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRpZiAobWF0Y2hlZEtleSA9PT0gdHJ1ZSkge1xuXHRcdFx0XHRcdFx0XHRtYXRjaGVkVmFsdWUgPSBlcXVhbHMoYUVudHJ5WzFdLCBiRW50cnlbMV0sIGZpbHRlcmVkQ3VzdG9tVGVzdGVycyk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZiAobWF0Y2hlZFZhbHVlID09PSB0cnVlKSB7XG5cdFx0XHRcdFx0XHRcdGhhcyA9IHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmIChoYXMgPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0XHRhbGxGb3VuZCA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHQvLyBSZW1vdmUgdGhlIGZpcnN0IHZhbHVlIGZyb20gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCB2YWx1ZXMuXG5cdFx0XHRhU3RhY2sucG9wKCk7XG5cdFx0XHRiU3RhY2sucG9wKCk7XG5cdFx0XHRyZXR1cm4gYWxsRm91bmQ7XG5cdFx0fVxuXHR9XG5cdGNvbnN0IGJJdGVyYXRvciA9IGJbSXRlcmF0b3JTeW1ib2xdKCk7XG5cdGZvciAoY29uc3QgYVZhbHVlIG9mIGEpIHtcblx0XHRjb25zdCBuZXh0QiA9IGJJdGVyYXRvci5uZXh0KCk7XG5cdFx0aWYgKG5leHRCLmRvbmUgfHwgIWVxdWFscyhhVmFsdWUsIG5leHRCLnZhbHVlLCBmaWx0ZXJlZEN1c3RvbVRlc3RlcnMpKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cdGlmICghYkl0ZXJhdG9yLm5leHQoKS5kb25lKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdGlmICghaXNJbW11dGFibGVMaXN0KGEpICYmICFpc0ltbXV0YWJsZU9yZGVyZWRLZXllZChhKSAmJiAhaXNJbW11dGFibGVPcmRlcmVkU2V0KGEpICYmICFpc0ltbXV0YWJsZVJlY29yZChhKSkge1xuXHRcdGNvbnN0IGFFbnRyaWVzID0gT2JqZWN0LmVudHJpZXMoYSk7XG5cdFx0Y29uc3QgYkVudHJpZXMgPSBPYmplY3QuZW50cmllcyhiKTtcblx0XHRpZiAoIWVxdWFscyhhRW50cmllcywgYkVudHJpZXMsIGZpbHRlcmVkQ3VzdG9tVGVzdGVycykpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdH1cblx0Ly8gUmVtb3ZlIHRoZSBmaXJzdCB2YWx1ZSBmcm9tIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgdmFsdWVzLlxuXHRhU3RhY2sucG9wKCk7XG5cdGJTdGFjay5wb3AoKTtcblx0cmV0dXJuIHRydWU7XG59XG4vKipcbiogQ2hlY2tzIGlmIGBoYXNPd25Qcm9wZXJ0eShvYmplY3QsIGtleSlgIHVwIHRoZSBwcm90b3R5cGUgY2hhaW4sIHN0b3BwaW5nIGF0IGBPYmplY3QucHJvdG90eXBlYC5cbiovXG5mdW5jdGlvbiBoYXNQcm9wZXJ0eUluT2JqZWN0KG9iamVjdCwga2V5KSB7XG5cdGNvbnN0IHNob3VsZFRlcm1pbmF0ZSA9ICFvYmplY3QgfHwgdHlwZW9mIG9iamVjdCAhPT0gXCJvYmplY3RcIiB8fCBvYmplY3QgPT09IE9iamVjdC5wcm90b3R5cGU7XG5cdGlmIChzaG91bGRUZXJtaW5hdGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0cmV0dXJuIE9iamVjdC5oYXNPd24ob2JqZWN0LCBrZXkpIHx8IGhhc1Byb3BlcnR5SW5PYmplY3QoT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iamVjdCksIGtleSk7XG59XG5mdW5jdGlvbiBpc09iamVjdFdpdGhLZXlzKGEpIHtcblx0cmV0dXJuIGlzT2JqZWN0KGEpICYmICFpc0Vycm9yKGEpICYmICFBcnJheS5pc0FycmF5KGEpICYmICEoYSBpbnN0YW5jZW9mIERhdGUpICYmICEoYSBpbnN0YW5jZW9mIFNldCkgJiYgIShhIGluc3RhbmNlb2YgTWFwKTtcbn1cbmZ1bmN0aW9uIHN1YnNldEVxdWFsaXR5KG9iamVjdCwgc3Vic2V0LCBjdXN0b21UZXN0ZXJzID0gW10pIHtcblx0Y29uc3QgZmlsdGVyZWRDdXN0b21UZXN0ZXJzID0gY3VzdG9tVGVzdGVycy5maWx0ZXIoKHQpID0+IHQgIT09IHN1YnNldEVxdWFsaXR5KTtcblx0Ly8gc3Vic2V0RXF1YWxpdHkgbmVlZHMgdG8ga2VlcCB0cmFjayBvZiB0aGUgcmVmZXJlbmNlc1xuXHQvLyBpdCBoYXMgYWxyZWFkeSB2aXNpdGVkIHRvIGF2b2lkIGluZmluaXRlIGxvb3BzIGluIGNhc2Vcblx0Ly8gdGhlcmUgYXJlIGNpcmN1bGFyIHJlZmVyZW5jZXMgaW4gdGhlIHN1YnNldCBwYXNzZWQgdG8gaXQuXG5cdGNvbnN0IHN1YnNldEVxdWFsaXR5V2l0aENvbnRleHQgPSAoc2VlblJlZmVyZW5jZXMgPSBuZXcgV2Vha01hcCgpKSA9PiAob2JqZWN0LCBzdWJzZXQpID0+IHtcblx0XHRpZiAoIWlzT2JqZWN0V2l0aEtleXMoc3Vic2V0KSkge1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0cmV0dXJuIE9iamVjdC5rZXlzKHN1YnNldCkuZXZlcnkoKGtleSkgPT4ge1xuXHRcdFx0aWYgKHN1YnNldFtrZXldICE9IG51bGwgJiYgdHlwZW9mIHN1YnNldFtrZXldID09PSBcIm9iamVjdFwiKSB7XG5cdFx0XHRcdGlmIChzZWVuUmVmZXJlbmNlcy5oYXMoc3Vic2V0W2tleV0pKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGVxdWFscyhvYmplY3Rba2V5XSwgc3Vic2V0W2tleV0sIGZpbHRlcmVkQ3VzdG9tVGVzdGVycyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0c2VlblJlZmVyZW5jZXMuc2V0KHN1YnNldFtrZXldLCB0cnVlKTtcblx0XHRcdH1cblx0XHRcdGNvbnN0IHJlc3VsdCA9IG9iamVjdCAhPSBudWxsICYmIGhhc1Byb3BlcnR5SW5PYmplY3Qob2JqZWN0LCBrZXkpICYmIGVxdWFscyhvYmplY3Rba2V5XSwgc3Vic2V0W2tleV0sIFsuLi5maWx0ZXJlZEN1c3RvbVRlc3RlcnMsIHN1YnNldEVxdWFsaXR5V2l0aENvbnRleHQoc2VlblJlZmVyZW5jZXMpXSk7XG5cdFx0XHQvLyBUaGUgbWFpbiBnb2FsIG9mIHVzaW5nIHNlZW5SZWZlcmVuY2UgaXMgdG8gYXZvaWQgY2lyY3VsYXIgbm9kZSBvbiB0cmVlLlxuXHRcdFx0Ly8gSXQgd2lsbCBvbmx5IGhhcHBlbiB3aXRoaW4gYSBwYXJlbnQgYW5kIGl0cyBjaGlsZCwgbm90IGEgbm9kZSBhbmQgbm9kZXMgbmV4dCB0byBpdCAoc2FtZSBsZXZlbClcblx0XHRcdC8vIFdlIHNob3VsZCBrZWVwIHRoZSByZWZlcmVuY2UgZm9yIGEgcGFyZW50IGFuZCBpdHMgY2hpbGQgb25seVxuXHRcdFx0Ly8gVGh1cyB3ZSBzaG91bGQgZGVsZXRlIHRoZSByZWZlcmVuY2UgaW1tZWRpYXRlbHkgc28gdGhhdCBpdCBkb2Vzbid0IGludGVyZmVyZVxuXHRcdFx0Ly8gb3RoZXIgbm9kZXMgd2l0aGluIHRoZSBzYW1lIGxldmVsIG9uIHRyZWUuXG5cdFx0XHRzZWVuUmVmZXJlbmNlcy5kZWxldGUoc3Vic2V0W2tleV0pO1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9KTtcblx0fTtcblx0cmV0dXJuIHN1YnNldEVxdWFsaXR5V2l0aENvbnRleHQoKShvYmplY3QsIHN1YnNldCk7XG59XG5mdW5jdGlvbiB0eXBlRXF1YWxpdHkoYSwgYikge1xuXHRpZiAoYSA9PSBudWxsIHx8IGIgPT0gbnVsbCB8fCBhLmNvbnN0cnVjdG9yID09PSBiLmNvbnN0cnVjdG9yKSB7XG5cdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0fVxuXHRyZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBhcnJheUJ1ZmZlckVxdWFsaXR5KGEsIGIpIHtcblx0bGV0IGRhdGFWaWV3QSA9IGE7XG5cdGxldCBkYXRhVmlld0IgPSBiO1xuXHRpZiAoIShhIGluc3RhbmNlb2YgRGF0YVZpZXcgJiYgYiBpbnN0YW5jZW9mIERhdGFWaWV3KSkge1xuXHRcdGlmICghKGEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgfHwgIShiIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpKSB7XG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHR0cnkge1xuXHRcdFx0ZGF0YVZpZXdBID0gbmV3IERhdGFWaWV3KGEpO1xuXHRcdFx0ZGF0YVZpZXdCID0gbmV3IERhdGFWaWV3KGIpO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cdH1cblx0Ly8gQnVmZmVycyBhcmUgbm90IGVxdWFsIHdoZW4gdGhleSBkbyBub3QgaGF2ZSB0aGUgc2FtZSBieXRlIGxlbmd0aFxuXHRpZiAoZGF0YVZpZXdBLmJ5dGVMZW5ndGggIT09IGRhdGFWaWV3Qi5ieXRlTGVuZ3RoKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdC8vIENoZWNrIGlmIGV2ZXJ5IGJ5dGUgdmFsdWUgaXMgZXF1YWwgdG8gZWFjaCBvdGhlclxuXHRmb3IgKGxldCBpID0gMDsgaSA8IGRhdGFWaWV3QS5ieXRlTGVuZ3RoOyBpKyspIHtcblx0XHRpZiAoZGF0YVZpZXdBLmdldFVpbnQ4KGkpICE9PSBkYXRhVmlld0IuZ2V0VWludDgoaSkpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBzcGFyc2VBcnJheUVxdWFsaXR5KGEsIGIsIGN1c3RvbVRlc3RlcnMgPSBbXSkge1xuXHRpZiAoIUFycmF5LmlzQXJyYXkoYSkgfHwgIUFycmF5LmlzQXJyYXkoYikpIHtcblx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHR9XG5cdC8vIEEgc3BhcnNlIGFycmF5IFssICwgMV0gd2lsbCBoYXZlIGtleXMgW1wiMlwiXSB3aGVyZWFzIFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgMV0gd2lsbCBoYXZlIGtleXMgW1wiMFwiLCBcIjFcIiwgXCIyXCJdXG5cdGNvbnN0IGFLZXlzID0gT2JqZWN0LmtleXMoYSk7XG5cdGNvbnN0IGJLZXlzID0gT2JqZWN0LmtleXMoYik7XG5cdGNvbnN0IGZpbHRlcmVkQ3VzdG9tVGVzdGVycyA9IGN1c3RvbVRlc3RlcnMuZmlsdGVyKCh0KSA9PiB0ICE9PSBzcGFyc2VBcnJheUVxdWFsaXR5KTtcblx0cmV0dXJuIGVxdWFscyhhLCBiLCBmaWx0ZXJlZEN1c3RvbVRlc3RlcnMsIHRydWUpICYmIGVxdWFscyhhS2V5cywgYktleXMpO1xufVxuZnVuY3Rpb24gZ2VuZXJhdGVUb0JlTWVzc2FnZShkZWVwRXF1YWxpdHlOYW1lLCBleHBlY3RlZCA9IFwiI3t0aGlzfVwiLCBhY3R1YWwgPSBcIiN7ZXhwfVwiKSB7XG5cdGNvbnN0IHRvQmVNZXNzYWdlID0gYGV4cGVjdGVkICR7ZXhwZWN0ZWR9IHRvIGJlICR7YWN0dWFsfSAvLyBPYmplY3QuaXMgZXF1YWxpdHlgO1xuXHRpZiAoW1widG9TdHJpY3RFcXVhbFwiLCBcInRvRXF1YWxcIl0uaW5jbHVkZXMoZGVlcEVxdWFsaXR5TmFtZSkpIHtcblx0XHRyZXR1cm4gYCR7dG9CZU1lc3NhZ2V9XFxuXFxuSWYgaXQgc2hvdWxkIHBhc3Mgd2l0aCBkZWVwIGVxdWFsaXR5LCByZXBsYWNlIFwidG9CZVwiIHdpdGggXCIke2RlZXBFcXVhbGl0eU5hbWV9XCJcXG5cXG5FeHBlY3RlZDogJHtleHBlY3RlZH1cXG5SZWNlaXZlZDogc2VyaWFsaXplcyB0byB0aGUgc2FtZSBzdHJpbmdcXG5gO1xuXHR9XG5cdHJldHVybiB0b0JlTWVzc2FnZTtcbn1cbmZ1bmN0aW9uIHBsdXJhbGl6ZSh3b3JkLCBjb3VudCkge1xuXHRyZXR1cm4gYCR7Y291bnR9ICR7d29yZH0ke2NvdW50ID09PSAxID8gXCJcIiA6IFwic1wifWA7XG59XG5mdW5jdGlvbiBnZXRPYmplY3RLZXlzKG9iamVjdCkge1xuXHRyZXR1cm4gWy4uLk9iamVjdC5rZXlzKG9iamVjdCksIC4uLk9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqZWN0KS5maWx0ZXIoKHMpID0+IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBzKT8uZW51bWVyYWJsZSldO1xufVxuZnVuY3Rpb24gZ2V0T2JqZWN0U3Vic2V0KG9iamVjdCwgc3Vic2V0LCBjdXN0b21UZXN0ZXJzKSB7XG5cdGxldCBzdHJpcHBlZCA9IDA7XG5cdGNvbnN0IGdldE9iamVjdFN1YnNldFdpdGhDb250ZXh0ID0gKHNlZW5SZWZlcmVuY2VzID0gbmV3IFdlYWtNYXAoKSkgPT4gKG9iamVjdCwgc3Vic2V0KSA9PiB7XG5cdFx0aWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuXHRcdFx0aWYgKEFycmF5LmlzQXJyYXkoc3Vic2V0KSAmJiBzdWJzZXQubGVuZ3RoID09PSBvYmplY3QubGVuZ3RoKSB7XG5cdFx0XHRcdC8vIFRoZSBtYXAgbWV0aG9kIHJldHVybnMgY29ycmVjdCBzdWJjbGFzcyBvZiBzdWJzZXQuXG5cdFx0XHRcdHJldHVybiBzdWJzZXQubWFwKChzdWIsIGkpID0+IGdldE9iamVjdFN1YnNldFdpdGhDb250ZXh0KHNlZW5SZWZlcmVuY2VzKShvYmplY3RbaV0sIHN1YikpO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSBpZiAob2JqZWN0IGluc3RhbmNlb2YgRGF0ZSkge1xuXHRcdFx0cmV0dXJuIG9iamVjdDtcblx0XHR9IGVsc2UgaWYgKGlzT2JqZWN0KG9iamVjdCkgJiYgaXNPYmplY3Qoc3Vic2V0KSkge1xuXHRcdFx0aWYgKGVxdWFscyhvYmplY3QsIHN1YnNldCwgW1xuXHRcdFx0XHQuLi5jdXN0b21UZXN0ZXJzLFxuXHRcdFx0XHRpdGVyYWJsZUVxdWFsaXR5LFxuXHRcdFx0XHRzdWJzZXRFcXVhbGl0eVxuXHRcdFx0XSkpIHtcblx0XHRcdFx0Ly8gcmV0dXJuIFwiZXhwZWN0ZWRcIiBzdWJzZXQgdG8gYXZvaWQgc2hvd2luZyBpcnJlbGV2YW50IHRvTWF0Y2hPYmplY3QgZGlmZlxuXHRcdFx0XHRyZXR1cm4gc3Vic2V0O1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgdHJpbW1lZCA9IHt9O1xuXHRcdFx0c2VlblJlZmVyZW5jZXMuc2V0KG9iamVjdCwgdHJpbW1lZCk7XG5cdFx0XHQvLyBwcmVzZXJ2ZSBjb25zdHJ1Y3RvciBmb3IgdG9NYXRjaE9iamVjdCBkaWZmXG5cdFx0XHRpZiAodHlwZW9mIG9iamVjdC5jb25zdHJ1Y3RvciA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBvYmplY3QuY29uc3RydWN0b3IubmFtZSA9PT0gXCJzdHJpbmdcIikge1xuXHRcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkodHJpbW1lZCwgXCJjb25zdHJ1Y3RvclwiLCB7XG5cdFx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0dmFsdWU6IG9iamVjdC5jb25zdHJ1Y3RvclxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHRcdGZvciAoY29uc3Qga2V5IG9mIGdldE9iamVjdEtleXMob2JqZWN0KSkge1xuXHRcdFx0XHRpZiAoaGFzUHJvcGVydHlJbk9iamVjdChzdWJzZXQsIGtleSkpIHtcblx0XHRcdFx0XHR0cmltbWVkW2tleV0gPSBzZWVuUmVmZXJlbmNlcy5oYXMob2JqZWN0W2tleV0pID8gc2VlblJlZmVyZW5jZXMuZ2V0KG9iamVjdFtrZXldKSA6IGdldE9iamVjdFN1YnNldFdpdGhDb250ZXh0KHNlZW5SZWZlcmVuY2VzKShvYmplY3Rba2V5XSwgc3Vic2V0W2tleV0pO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGlmICghc2VlblJlZmVyZW5jZXMuaGFzKG9iamVjdFtrZXldKSkge1xuXHRcdFx0XHRcdFx0c3RyaXBwZWQgKz0gMTtcblx0XHRcdFx0XHRcdGlmIChpc09iamVjdChvYmplY3Rba2V5XSkpIHtcblx0XHRcdFx0XHRcdFx0c3RyaXBwZWQgKz0gZ2V0T2JqZWN0S2V5cyhvYmplY3Rba2V5XSkubGVuZ3RoO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0Z2V0T2JqZWN0U3Vic2V0V2l0aENvbnRleHQoc2VlblJlZmVyZW5jZXMpKG9iamVjdFtrZXldLCBzdWJzZXRba2V5XSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZiAoZ2V0T2JqZWN0S2V5cyh0cmltbWVkKS5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdHJldHVybiB0cmltbWVkO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gb2JqZWN0O1xuXHR9O1xuXHRyZXR1cm4ge1xuXHRcdHN1YnNldDogZ2V0T2JqZWN0U3Vic2V0V2l0aENvbnRleHQoKShvYmplY3QsIHN1YnNldCksXG5cdFx0c3RyaXBwZWRcblx0fTtcbn1cbi8qKlxuKiBEZXRlY3RzIGlmIGFuIG9iamVjdCBpcyBhIFN0YW5kYXJkIFNjaGVtYSBWMSBjb21wYXRpYmxlIHNjaGVtYVxuKi9cbmZ1bmN0aW9uIGlzU3RhbmRhcmRTY2hlbWEob2JqKSB7XG5cdHJldHVybiAhIW9iaiAmJiAodHlwZW9mIG9iaiA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2Ygb2JqID09PSBcImZ1bmN0aW9uXCIpICYmIG9ialtcIn5zdGFuZGFyZFwiXSAmJiB0eXBlb2Ygb2JqW1wifnN0YW5kYXJkXCJdLnZhbGlkYXRlID09PSBcImZ1bmN0aW9uXCI7XG59XG5cbmlmICghT2JqZWN0Lmhhc093bihnbG9iYWxUaGlzLCBNQVRDSEVSU19PQkpFQ1QpKSB7XG5cdGNvbnN0IGdsb2JhbFN0YXRlID0gbmV3IFdlYWtNYXAoKTtcblx0Y29uc3QgbWF0Y2hlcnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXHRjb25zdCBjdXN0b21FcXVhbGl0eVRlc3RlcnMgPSBbXTtcblx0Y29uc3QgYXN5bW1ldHJpY01hdGNoZXJzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGdsb2JhbFRoaXMsIE1BVENIRVJTX09CSkVDVCwgeyBnZXQ6ICgpID0+IGdsb2JhbFN0YXRlIH0pO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsVGhpcywgSkVTVF9NQVRDSEVSU19PQkpFQ1QsIHtcblx0XHRjb25maWd1cmFibGU6IHRydWUsXG5cdFx0Z2V0OiAoKSA9PiAoe1xuXHRcdFx0c3RhdGU6IGdsb2JhbFN0YXRlLmdldChnbG9iYWxUaGlzW0dMT0JBTF9FWFBFQ1RdKSxcblx0XHRcdG1hdGNoZXJzLFxuXHRcdFx0Y3VzdG9tRXF1YWxpdHlUZXN0ZXJzXG5cdFx0fSlcblx0fSk7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxUaGlzLCBBU1lNTUVUUklDX01BVENIRVJTX09CSkVDVCwgeyBnZXQ6ICgpID0+IGFzeW1tZXRyaWNNYXRjaGVycyB9KTtcbn1cbmZ1bmN0aW9uIGdldFN0YXRlKGV4cGVjdCkge1xuXHRyZXR1cm4gZ2xvYmFsVGhpc1tNQVRDSEVSU19PQkpFQ1RdLmdldChleHBlY3QpO1xufVxuZnVuY3Rpb24gc2V0U3RhdGUoc3RhdGUsIGV4cGVjdCkge1xuXHRjb25zdCBtYXAgPSBnbG9iYWxUaGlzW01BVENIRVJTX09CSkVDVF07XG5cdGNvbnN0IGN1cnJlbnQgPSBtYXAuZ2V0KGV4cGVjdCkgfHwge307XG5cdC8vIHNvIGl0IGtlZXBzIGdldHRlcnMgZnJvbSBgdGVzdFBhdGhgXG5cdGNvbnN0IHJlc3VsdHMgPSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhjdXJyZW50LCB7XG5cdFx0Li4uT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoY3VycmVudCksXG5cdFx0Li4uT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoc3RhdGUpXG5cdH0pO1xuXHRtYXAuc2V0KGV4cGVjdCwgcmVzdWx0cyk7XG59XG5cbmNsYXNzIEFzeW1tZXRyaWNNYXRjaGVyIHtcblx0Ly8gc2hvdWxkIGhhdmUgXCJqZXN0XCIgdG8gYmUgY29tcGF0aWJsZSB3aXRoIGl0cyBlY29zeXN0ZW1cblx0JCR0eXBlb2YgPSBTeW1ib2wuZm9yKFwiamVzdC5hc3ltbWV0cmljTWF0Y2hlclwiKTtcblx0Y29uc3RydWN0b3Ioc2FtcGxlLCBpbnZlcnNlID0gZmFsc2UpIHtcblx0XHR0aGlzLnNhbXBsZSA9IHNhbXBsZTtcblx0XHR0aGlzLmludmVyc2UgPSBpbnZlcnNlO1xuXHR9XG5cdGdldE1hdGNoZXJDb250ZXh0KGV4cGVjdCkge1xuXHRcdHJldHVybiB7XG5cdFx0XHQuLi5nZXRTdGF0ZShleHBlY3QgfHwgZ2xvYmFsVGhpc1tHTE9CQUxfRVhQRUNUXSksXG5cdFx0XHRlcXVhbHMsXG5cdFx0XHRpc05vdDogdGhpcy5pbnZlcnNlLFxuXHRcdFx0Y3VzdG9tVGVzdGVyczogZ2V0Q3VzdG9tRXF1YWxpdHlUZXN0ZXJzKCksXG5cdFx0XHR1dGlsczoge1xuXHRcdFx0XHQuLi5nZXRNYXRjaGVyVXRpbHMoKSxcblx0XHRcdFx0ZGlmZixcblx0XHRcdFx0c3RyaW5naWZ5LFxuXHRcdFx0XHRpdGVyYWJsZUVxdWFsaXR5LFxuXHRcdFx0XHRzdWJzZXRFcXVhbGl0eVxuXHRcdFx0fVxuXHRcdH07XG5cdH1cbn1cbi8vIGltcGxlbWVudCBjdXN0b20gY2hhaS9sb3VwZSBpbnNwZWN0IGZvciBiZXR0ZXIgQXNzZXJ0aW9uRXJyb3IubWVzc2FnZSBmb3JtYXR0aW5nXG4vLyBodHRwczovL2dpdGh1Yi5jb20vY2hhaWpzL2xvdXBlL2Jsb2IvOWI4YTZkZWFiY2Q1MGFkYzA1NmE2NGZiNzA1ODk2MTk0NzEwYzVjNi9zcmMvaW5kZXgudHMjTDI5XG4vLyBAdHMtZXhwZWN0LWVycm9yIGNvbXB1dGVkIHByb3BlcnRpZXMgaXMgbm90IHN1cHBvcnRlZCB3aGVuIGlzb2xhdGVkRGVjbGFyYXRpb25zIGlzIGVuYWJsZWRcbi8vIEZJWE1FOiBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L1R5cGVTY3JpcHQvaXNzdWVzLzYxMDY4XG5Bc3ltbWV0cmljTWF0Y2hlci5wcm90b3R5cGVbU3ltYm9sLmZvcihcImNoYWkvaW5zcGVjdFwiKV0gPSBmdW5jdGlvbihvcHRpb25zKSB7XG5cdC8vIG1pbmltYWwgcHJldHR5LWZvcm1hdCB3aXRoIHNpbXBsZSBtYW51YWwgdHJ1bmNhdGlvblxuXHRjb25zdCByZXN1bHQgPSBzdHJpbmdpZnkodGhpcywgb3B0aW9ucy5kZXB0aCwgeyBtaW46IHRydWUgfSk7XG5cdGlmIChyZXN1bHQubGVuZ3RoIDw9IG9wdGlvbnMudHJ1bmNhdGUpIHtcblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cdHJldHVybiBgJHt0aGlzLnRvU3RyaW5nKCl9e+KApn1gO1xufTtcbmNsYXNzIFN0cmluZ0NvbnRhaW5pbmcgZXh0ZW5kcyBBc3ltbWV0cmljTWF0Y2hlciB7XG5cdGNvbnN0cnVjdG9yKHNhbXBsZSwgaW52ZXJzZSA9IGZhbHNlKSB7XG5cdFx0aWYgKCFpc0EoXCJTdHJpbmdcIiwgc2FtcGxlKSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgaXMgbm90IGEgc3RyaW5nXCIpO1xuXHRcdH1cblx0XHRzdXBlcihzYW1wbGUsIGludmVyc2UpO1xuXHR9XG5cdGFzeW1tZXRyaWNNYXRjaChvdGhlcikge1xuXHRcdGNvbnN0IHJlc3VsdCA9IGlzQShcIlN0cmluZ1wiLCBvdGhlcikgJiYgb3RoZXIuaW5jbHVkZXModGhpcy5zYW1wbGUpO1xuXHRcdHJldHVybiB0aGlzLmludmVyc2UgPyAhcmVzdWx0IDogcmVzdWx0O1xuXHR9XG5cdHRvU3RyaW5nKCkge1xuXHRcdHJldHVybiBgU3RyaW5nJHt0aGlzLmludmVyc2UgPyBcIk5vdFwiIDogXCJcIn1Db250YWluaW5nYDtcblx0fVxuXHRnZXRFeHBlY3RlZFR5cGUoKSB7XG5cdFx0cmV0dXJuIFwic3RyaW5nXCI7XG5cdH1cbn1cbmNsYXNzIEFueXRoaW5nIGV4dGVuZHMgQXN5bW1ldHJpY01hdGNoZXIge1xuXHRhc3ltbWV0cmljTWF0Y2gob3RoZXIpIHtcblx0XHRyZXR1cm4gb3RoZXIgIT0gbnVsbDtcblx0fVxuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gXCJBbnl0aGluZ1wiO1xuXHR9XG5cdHRvQXN5bW1ldHJpY01hdGNoZXIoKSB7XG5cdFx0cmV0dXJuIFwiQW55dGhpbmdcIjtcblx0fVxufVxuY2xhc3MgT2JqZWN0Q29udGFpbmluZyBleHRlbmRzIEFzeW1tZXRyaWNNYXRjaGVyIHtcblx0Y29uc3RydWN0b3Ioc2FtcGxlLCBpbnZlcnNlID0gZmFsc2UpIHtcblx0XHRzdXBlcihzYW1wbGUsIGludmVyc2UpO1xuXHR9XG5cdGdldFByb3RvdHlwZShvYmopIHtcblx0XHRpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKSB7XG5cdFx0XHRyZXR1cm4gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iaik7XG5cdFx0fVxuXHRcdGlmIChvYmouY29uc3RydWN0b3IucHJvdG90eXBlID09PSBvYmopIHtcblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH1cblx0XHRyZXR1cm4gb2JqLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcblx0fVxuXHRoYXNQcm9wZXJ0eShvYmosIHByb3BlcnR5KSB7XG5cdFx0aWYgKCFvYmopIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aWYgKE9iamVjdC5oYXNPd24ob2JqLCBwcm9wZXJ0eSkpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5oYXNQcm9wZXJ0eSh0aGlzLmdldFByb3RvdHlwZShvYmopLCBwcm9wZXJ0eSk7XG5cdH1cblx0Z2V0UHJvcGVydGllcyhvYmopIHtcblx0XHRyZXR1cm4gWy4uLk9iamVjdC5rZXlzKG9iaiksIC4uLk9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqKS5maWx0ZXIoKHMpID0+IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBzKT8uZW51bWVyYWJsZSldO1xuXHR9XG5cdGFzeW1tZXRyaWNNYXRjaChvdGhlciwgY3VzdG9tVGVzdGVycykge1xuXHRcdGlmICh0eXBlb2YgdGhpcy5zYW1wbGUgIT09IFwib2JqZWN0XCIpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYFlvdSBtdXN0IHByb3ZpZGUgYW4gb2JqZWN0IHRvICR7dGhpcy50b1N0cmluZygpfSwgbm90ICcke3R5cGVvZiB0aGlzLnNhbXBsZX0nLmApO1xuXHRcdH1cblx0XHRsZXQgcmVzdWx0ID0gdHJ1ZTtcblx0XHRjb25zdCBwcm9wZXJ0aWVzID0gdGhpcy5nZXRQcm9wZXJ0aWVzKHRoaXMuc2FtcGxlKTtcblx0XHRmb3IgKGNvbnN0IHByb3BlcnR5IG9mIHByb3BlcnRpZXMpIHtcblx0XHRcdGlmICghdGhpcy5oYXNQcm9wZXJ0eShvdGhlciwgcHJvcGVydHkpKSB7XG5cdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGNvbnN0IHZhbHVlID0gdGhpcy5zYW1wbGVbcHJvcGVydHldO1xuXHRcdFx0Y29uc3Qgb3RoZXJWYWx1ZSA9IG90aGVyW3Byb3BlcnR5XTtcblx0XHRcdGlmICghZXF1YWxzKHZhbHVlLCBvdGhlclZhbHVlLCBjdXN0b21UZXN0ZXJzKSkge1xuXHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmludmVyc2UgPyAhcmVzdWx0IDogcmVzdWx0O1xuXHR9XG5cdHRvU3RyaW5nKCkge1xuXHRcdHJldHVybiBgT2JqZWN0JHt0aGlzLmludmVyc2UgPyBcIk5vdFwiIDogXCJcIn1Db250YWluaW5nYDtcblx0fVxuXHRnZXRFeHBlY3RlZFR5cGUoKSB7XG5cdFx0cmV0dXJuIFwib2JqZWN0XCI7XG5cdH1cbn1cbmNsYXNzIEFycmF5Q29udGFpbmluZyBleHRlbmRzIEFzeW1tZXRyaWNNYXRjaGVyIHtcblx0Y29uc3RydWN0b3Ioc2FtcGxlLCBpbnZlcnNlID0gZmFsc2UpIHtcblx0XHRzdXBlcihzYW1wbGUsIGludmVyc2UpO1xuXHR9XG5cdGFzeW1tZXRyaWNNYXRjaChvdGhlciwgY3VzdG9tVGVzdGVycykge1xuXHRcdGlmICghQXJyYXkuaXNBcnJheSh0aGlzLnNhbXBsZSkpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYFlvdSBtdXN0IHByb3ZpZGUgYW4gYXJyYXkgdG8gJHt0aGlzLnRvU3RyaW5nKCl9LCBub3QgJyR7dHlwZW9mIHRoaXMuc2FtcGxlfScuYCk7XG5cdFx0fVxuXHRcdGNvbnN0IHJlc3VsdCA9IHRoaXMuc2FtcGxlLmxlbmd0aCA9PT0gMCB8fCBBcnJheS5pc0FycmF5KG90aGVyKSAmJiB0aGlzLnNhbXBsZS5ldmVyeSgoaXRlbSkgPT4gb3RoZXIuc29tZSgoYW5vdGhlcikgPT4gZXF1YWxzKGl0ZW0sIGFub3RoZXIsIGN1c3RvbVRlc3RlcnMpKSk7XG5cdFx0cmV0dXJuIHRoaXMuaW52ZXJzZSA/ICFyZXN1bHQgOiByZXN1bHQ7XG5cdH1cblx0dG9TdHJpbmcoKSB7XG5cdFx0cmV0dXJuIGBBcnJheSR7dGhpcy5pbnZlcnNlID8gXCJOb3RcIiA6IFwiXCJ9Q29udGFpbmluZ2A7XG5cdH1cblx0Z2V0RXhwZWN0ZWRUeXBlKCkge1xuXHRcdHJldHVybiBcImFycmF5XCI7XG5cdH1cbn1cbmNsYXNzIEFueSBleHRlbmRzIEFzeW1tZXRyaWNNYXRjaGVyIHtcblx0Y29uc3RydWN0b3Ioc2FtcGxlKSB7XG5cdFx0aWYgKHR5cGVvZiBzYW1wbGUgPT09IFwidW5kZWZpbmVkXCIpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoXCJhbnkoKSBleHBlY3RzIHRvIGJlIHBhc3NlZCBhIGNvbnN0cnVjdG9yIGZ1bmN0aW9uLiBcIiArIFwiUGxlYXNlIHBhc3Mgb25lIG9yIHVzZSBhbnl0aGluZygpIHRvIG1hdGNoIGFueSBvYmplY3QuXCIpO1xuXHRcdH1cblx0XHRzdXBlcihzYW1wbGUpO1xuXHR9XG5cdGZuTmFtZUZvcihmdW5jKSB7XG5cdFx0aWYgKGZ1bmMubmFtZSkge1xuXHRcdFx0cmV0dXJuIGZ1bmMubmFtZTtcblx0XHR9XG5cdFx0Y29uc3QgZnVuY3Rpb25Ub1N0cmluZyA9IEZ1bmN0aW9uLnByb3RvdHlwZS50b1N0cmluZztcblx0XHRjb25zdCBtYXRjaGVzID0gZnVuY3Rpb25Ub1N0cmluZy5jYWxsKGZ1bmMpLm1hdGNoKC9eKD86YXN5bmMpP1xccypmdW5jdGlvblxccyooPzpcXCpcXHMqKT8oW1xcdyRdKylcXHMqXFwoLyk7XG5cdFx0cmV0dXJuIG1hdGNoZXMgPyBtYXRjaGVzWzFdIDogXCI8YW5vbnltb3VzPlwiO1xuXHR9XG5cdGFzeW1tZXRyaWNNYXRjaChvdGhlcikge1xuXHRcdGlmICh0aGlzLnNhbXBsZSA9PT0gU3RyaW5nKSB7XG5cdFx0XHRyZXR1cm4gdHlwZW9mIG90aGVyID09IFwic3RyaW5nXCIgfHwgb3RoZXIgaW5zdGFuY2VvZiBTdHJpbmc7XG5cdFx0fVxuXHRcdGlmICh0aGlzLnNhbXBsZSA9PT0gTnVtYmVyKSB7XG5cdFx0XHRyZXR1cm4gdHlwZW9mIG90aGVyID09IFwibnVtYmVyXCIgfHwgb3RoZXIgaW5zdGFuY2VvZiBOdW1iZXI7XG5cdFx0fVxuXHRcdGlmICh0aGlzLnNhbXBsZSA9PT0gRnVuY3Rpb24pIHtcblx0XHRcdHJldHVybiB0eXBlb2Ygb3RoZXIgPT0gXCJmdW5jdGlvblwiIHx8IHR5cGVvZiBvdGhlciA9PT0gXCJmdW5jdGlvblwiO1xuXHRcdH1cblx0XHRpZiAodGhpcy5zYW1wbGUgPT09IEJvb2xlYW4pIHtcblx0XHRcdHJldHVybiB0eXBlb2Ygb3RoZXIgPT0gXCJib29sZWFuXCIgfHwgb3RoZXIgaW5zdGFuY2VvZiBCb29sZWFuO1xuXHRcdH1cblx0XHRpZiAodGhpcy5zYW1wbGUgPT09IEJpZ0ludCkge1xuXHRcdFx0cmV0dXJuIHR5cGVvZiBvdGhlciA9PSBcImJpZ2ludFwiIHx8IG90aGVyIGluc3RhbmNlb2YgQmlnSW50O1xuXHRcdH1cblx0XHRpZiAodGhpcy5zYW1wbGUgPT09IFN5bWJvbCkge1xuXHRcdFx0cmV0dXJuIHR5cGVvZiBvdGhlciA9PSBcInN5bWJvbFwiIHx8IG90aGVyIGluc3RhbmNlb2YgU3ltYm9sO1xuXHRcdH1cblx0XHRpZiAodGhpcy5zYW1wbGUgPT09IE9iamVjdCkge1xuXHRcdFx0cmV0dXJuIHR5cGVvZiBvdGhlciA9PSBcIm9iamVjdFwiO1xuXHRcdH1cblx0XHRyZXR1cm4gb3RoZXIgaW5zdGFuY2VvZiB0aGlzLnNhbXBsZTtcblx0fVxuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gXCJBbnlcIjtcblx0fVxuXHRnZXRFeHBlY3RlZFR5cGUoKSB7XG5cdFx0aWYgKHRoaXMuc2FtcGxlID09PSBTdHJpbmcpIHtcblx0XHRcdHJldHVybiBcInN0cmluZ1wiO1xuXHRcdH1cblx0XHRpZiAodGhpcy5zYW1wbGUgPT09IE51bWJlcikge1xuXHRcdFx0cmV0dXJuIFwibnVtYmVyXCI7XG5cdFx0fVxuXHRcdGlmICh0aGlzLnNhbXBsZSA9PT0gRnVuY3Rpb24pIHtcblx0XHRcdHJldHVybiBcImZ1bmN0aW9uXCI7XG5cdFx0fVxuXHRcdGlmICh0aGlzLnNhbXBsZSA9PT0gT2JqZWN0KSB7XG5cdFx0XHRyZXR1cm4gXCJvYmplY3RcIjtcblx0XHR9XG5cdFx0aWYgKHRoaXMuc2FtcGxlID09PSBCb29sZWFuKSB7XG5cdFx0XHRyZXR1cm4gXCJib29sZWFuXCI7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmZuTmFtZUZvcih0aGlzLnNhbXBsZSk7XG5cdH1cblx0dG9Bc3ltbWV0cmljTWF0Y2hlcigpIHtcblx0XHRyZXR1cm4gYEFueTwke3RoaXMuZm5OYW1lRm9yKHRoaXMuc2FtcGxlKX0+YDtcblx0fVxufVxuY2xhc3MgU3RyaW5nTWF0Y2hpbmcgZXh0ZW5kcyBBc3ltbWV0cmljTWF0Y2hlciB7XG5cdGNvbnN0cnVjdG9yKHNhbXBsZSwgaW52ZXJzZSA9IGZhbHNlKSB7XG5cdFx0aWYgKCFpc0EoXCJTdHJpbmdcIiwgc2FtcGxlKSAmJiAhaXNBKFwiUmVnRXhwXCIsIHNhbXBsZSkpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGVkIGlzIG5vdCBhIFN0cmluZyBvciBhIFJlZ0V4cFwiKTtcblx0XHR9XG5cdFx0c3VwZXIobmV3IFJlZ0V4cChzYW1wbGUpLCBpbnZlcnNlKTtcblx0fVxuXHRhc3ltbWV0cmljTWF0Y2gob3RoZXIpIHtcblx0XHRjb25zdCByZXN1bHQgPSBpc0EoXCJTdHJpbmdcIiwgb3RoZXIpICYmIHRoaXMuc2FtcGxlLnRlc3Qob3RoZXIpO1xuXHRcdHJldHVybiB0aGlzLmludmVyc2UgPyAhcmVzdWx0IDogcmVzdWx0O1xuXHR9XG5cdHRvU3RyaW5nKCkge1xuXHRcdHJldHVybiBgU3RyaW5nJHt0aGlzLmludmVyc2UgPyBcIk5vdFwiIDogXCJcIn1NYXRjaGluZ2A7XG5cdH1cblx0Z2V0RXhwZWN0ZWRUeXBlKCkge1xuXHRcdHJldHVybiBcInN0cmluZ1wiO1xuXHR9XG59XG5jbGFzcyBDbG9zZVRvIGV4dGVuZHMgQXN5bW1ldHJpY01hdGNoZXIge1xuXHRwcmVjaXNpb247XG5cdGNvbnN0cnVjdG9yKHNhbXBsZSwgcHJlY2lzaW9uID0gMiwgaW52ZXJzZSA9IGZhbHNlKSB7XG5cdFx0aWYgKCFpc0EoXCJOdW1iZXJcIiwgc2FtcGxlKSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgaXMgbm90IGEgTnVtYmVyXCIpO1xuXHRcdH1cblx0XHRpZiAoIWlzQShcIk51bWJlclwiLCBwcmVjaXNpb24pKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJQcmVjaXNpb24gaXMgbm90IGEgTnVtYmVyXCIpO1xuXHRcdH1cblx0XHRzdXBlcihzYW1wbGUpO1xuXHRcdHRoaXMuaW52ZXJzZSA9IGludmVyc2U7XG5cdFx0dGhpcy5wcmVjaXNpb24gPSBwcmVjaXNpb247XG5cdH1cblx0YXN5bW1ldHJpY01hdGNoKG90aGVyKSB7XG5cdFx0aWYgKCFpc0EoXCJOdW1iZXJcIiwgb3RoZXIpKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdGxldCByZXN1bHQgPSBmYWxzZTtcblx0XHRpZiAob3RoZXIgPT09IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSAmJiB0aGlzLnNhbXBsZSA9PT0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZKSB7XG5cdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdH0gZWxzZSBpZiAob3RoZXIgPT09IE51bWJlci5ORUdBVElWRV9JTkZJTklUWSAmJiB0aGlzLnNhbXBsZSA9PT0gTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZKSB7XG5cdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXN1bHQgPSBNYXRoLmFicyh0aGlzLnNhbXBsZSAtIG90aGVyKSA8IDEwICoqIC10aGlzLnByZWNpc2lvbiAvIDI7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmludmVyc2UgPyAhcmVzdWx0IDogcmVzdWx0O1xuXHR9XG5cdHRvU3RyaW5nKCkge1xuXHRcdHJldHVybiBgTnVtYmVyJHt0aGlzLmludmVyc2UgPyBcIk5vdFwiIDogXCJcIn1DbG9zZVRvYDtcblx0fVxuXHRnZXRFeHBlY3RlZFR5cGUoKSB7XG5cdFx0cmV0dXJuIFwibnVtYmVyXCI7XG5cdH1cblx0dG9Bc3ltbWV0cmljTWF0Y2hlcigpIHtcblx0XHRyZXR1cm4gW1xuXHRcdFx0dGhpcy50b1N0cmluZygpLFxuXHRcdFx0dGhpcy5zYW1wbGUsXG5cdFx0XHRgKCR7cGx1cmFsaXplKFwiZGlnaXRcIiwgdGhpcy5wcmVjaXNpb24pfSlgXG5cdFx0XS5qb2luKFwiIFwiKTtcblx0fVxufVxuY2xhc3MgU2NoZW1hTWF0Y2hpbmcgZXh0ZW5kcyBBc3ltbWV0cmljTWF0Y2hlciB7XG5cdHJlc3VsdDtcblx0Y29uc3RydWN0b3Ioc2FtcGxlLCBpbnZlcnNlID0gZmFsc2UpIHtcblx0XHRpZiAoIWlzU3RhbmRhcmRTY2hlbWEoc2FtcGxlKSkge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihcIlNjaGVtYU1hdGNoaW5nIGV4cGVjdGVkIHRvIHJlY2VpdmUgYSBTdGFuZGFyZCBTY2hlbWEuXCIpO1xuXHRcdH1cblx0XHRzdXBlcihzYW1wbGUsIGludmVyc2UpO1xuXHR9XG5cdGFzeW1tZXRyaWNNYXRjaChvdGhlcikge1xuXHRcdGNvbnN0IHJlc3VsdCA9IHRoaXMuc2FtcGxlW1wifnN0YW5kYXJkXCJdLnZhbGlkYXRlKG90aGVyKTtcblx0XHQvLyBDaGVjayBpZiB0aGUgcmVzdWx0IGlzIGEgUHJvbWlzZSAoYXN5bmMgdmFsaWRhdGlvbilcblx0XHRpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihcIkFzeW5jIHNjaGVtYSB2YWxpZGF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgaW4gYXN5bW1ldHJpYyBtYXRjaGVycy5cIik7XG5cdFx0fVxuXHRcdHRoaXMucmVzdWx0ID0gcmVzdWx0O1xuXHRcdGNvbnN0IHBhc3MgPSAhdGhpcy5yZXN1bHQuaXNzdWVzIHx8IHRoaXMucmVzdWx0Lmlzc3Vlcy5sZW5ndGggPT09IDA7XG5cdFx0cmV0dXJuIHRoaXMuaW52ZXJzZSA/ICFwYXNzIDogcGFzcztcblx0fVxuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gYFNjaGVtYSR7dGhpcy5pbnZlcnNlID8gXCJOb3RcIiA6IFwiXCJ9TWF0Y2hpbmdgO1xuXHR9XG5cdGdldEV4cGVjdGVkVHlwZSgpIHtcblx0XHRyZXR1cm4gXCJvYmplY3RcIjtcblx0fVxuXHR0b0FzeW1tZXRyaWNNYXRjaGVyKCkge1xuXHRcdGNvbnN0IHsgdXRpbHMgfSA9IHRoaXMuZ2V0TWF0Y2hlckNvbnRleHQoKTtcblx0XHRjb25zdCBpc3N1ZXMgPSB0aGlzLnJlc3VsdD8uaXNzdWVzIHx8IFtdO1xuXHRcdGlmIChpc3N1ZXMubGVuZ3RoID4gMCkge1xuXHRcdFx0cmV0dXJuIGAke3RoaXMudG9TdHJpbmcoKX0gJHt1dGlscy5zdHJpbmdpZnkodGhpcy5yZXN1bHQsIHVuZGVmaW5lZCwgeyBwcmludEJhc2ljUHJvdG90eXBlOiBmYWxzZSB9KX1gO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy50b1N0cmluZygpO1xuXHR9XG59XG5jb25zdCBKZXN0QXN5bW1ldHJpY01hdGNoZXJzID0gKGNoYWksIHV0aWxzKSA9PiB7XG5cdHV0aWxzLmFkZE1ldGhvZChjaGFpLmV4cGVjdCwgXCJhbnl0aGluZ1wiLCAoKSA9PiBuZXcgQW55dGhpbmcoKSk7XG5cdHV0aWxzLmFkZE1ldGhvZChjaGFpLmV4cGVjdCwgXCJhbnlcIiwgKGV4cGVjdGVkKSA9PiBuZXcgQW55KGV4cGVjdGVkKSk7XG5cdHV0aWxzLmFkZE1ldGhvZChjaGFpLmV4cGVjdCwgXCJzdHJpbmdDb250YWluaW5nXCIsIChleHBlY3RlZCkgPT4gbmV3IFN0cmluZ0NvbnRhaW5pbmcoZXhwZWN0ZWQpKTtcblx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuZXhwZWN0LCBcIm9iamVjdENvbnRhaW5pbmdcIiwgKGV4cGVjdGVkKSA9PiBuZXcgT2JqZWN0Q29udGFpbmluZyhleHBlY3RlZCkpO1xuXHR1dGlscy5hZGRNZXRob2QoY2hhaS5leHBlY3QsIFwiYXJyYXlDb250YWluaW5nXCIsIChleHBlY3RlZCkgPT4gbmV3IEFycmF5Q29udGFpbmluZyhleHBlY3RlZCkpO1xuXHR1dGlscy5hZGRNZXRob2QoY2hhaS5leHBlY3QsIFwic3RyaW5nTWF0Y2hpbmdcIiwgKGV4cGVjdGVkKSA9PiBuZXcgU3RyaW5nTWF0Y2hpbmcoZXhwZWN0ZWQpKTtcblx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuZXhwZWN0LCBcImNsb3NlVG9cIiwgKGV4cGVjdGVkLCBwcmVjaXNpb24pID0+IG5ldyBDbG9zZVRvKGV4cGVjdGVkLCBwcmVjaXNpb24pKTtcblx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuZXhwZWN0LCBcInNjaGVtYU1hdGNoaW5nXCIsIChleHBlY3RlZCkgPT4gbmV3IFNjaGVtYU1hdGNoaW5nKGV4cGVjdGVkKSk7XG5cdC8vIGRlZmluZVByb3BlcnR5IGRvZXMgbm90IHdvcmtcblx0Y2hhaS5leHBlY3Qubm90ID0ge1xuXHRcdHN0cmluZ0NvbnRhaW5pbmc6IChleHBlY3RlZCkgPT4gbmV3IFN0cmluZ0NvbnRhaW5pbmcoZXhwZWN0ZWQsIHRydWUpLFxuXHRcdG9iamVjdENvbnRhaW5pbmc6IChleHBlY3RlZCkgPT4gbmV3IE9iamVjdENvbnRhaW5pbmcoZXhwZWN0ZWQsIHRydWUpLFxuXHRcdGFycmF5Q29udGFpbmluZzogKGV4cGVjdGVkKSA9PiBuZXcgQXJyYXlDb250YWluaW5nKGV4cGVjdGVkLCB0cnVlKSxcblx0XHRzdHJpbmdNYXRjaGluZzogKGV4cGVjdGVkKSA9PiBuZXcgU3RyaW5nTWF0Y2hpbmcoZXhwZWN0ZWQsIHRydWUpLFxuXHRcdGNsb3NlVG86IChleHBlY3RlZCwgcHJlY2lzaW9uKSA9PiBuZXcgQ2xvc2VUbyhleHBlY3RlZCwgcHJlY2lzaW9uLCB0cnVlKSxcblx0XHRzY2hlbWFNYXRjaGluZzogKGV4cGVjdGVkKSA9PiBuZXcgU2NoZW1hTWF0Y2hpbmcoZXhwZWN0ZWQsIHRydWUpXG5cdH07XG59O1xuXG5mdW5jdGlvbiBjcmVhdGVBc3NlcnRpb25NZXNzYWdlKHV0aWwsIGFzc2VydGlvbiwgaGFzQXJncykge1xuXHRjb25zdCBzb2Z0ID0gdXRpbC5mbGFnKGFzc2VydGlvbiwgXCJzb2Z0XCIpID8gXCIuc29mdFwiIDogXCJcIjtcblx0Y29uc3Qgbm90ID0gdXRpbC5mbGFnKGFzc2VydGlvbiwgXCJuZWdhdGVcIikgPyBcIm5vdC5cIiA6IFwiXCI7XG5cdGNvbnN0IG5hbWUgPSBgJHt1dGlsLmZsYWcoYXNzZXJ0aW9uLCBcIl9uYW1lXCIpfSgke2hhc0FyZ3MgPyBcImV4cGVjdGVkXCIgOiBcIlwifSlgO1xuXHRjb25zdCBwcm9taXNlTmFtZSA9IHV0aWwuZmxhZyhhc3NlcnRpb24sIFwicHJvbWlzZVwiKTtcblx0Y29uc3QgcHJvbWlzZSA9IHByb21pc2VOYW1lID8gYC4ke3Byb21pc2VOYW1lfWAgOiBcIlwiO1xuXHRyZXR1cm4gYGV4cGVjdCR7c29mdH0oYWN0dWFsKSR7cHJvbWlzZX0uJHtub3R9JHtuYW1lfWA7XG59XG5mdW5jdGlvbiByZWNvcmRBc3luY0V4cGVjdChfdGVzdCwgcHJvbWlzZSwgYXNzZXJ0aW9uLCBlcnJvciwgaXNTb2Z0KSB7XG5cdGNvbnN0IHRlc3QgPSBfdGVzdDtcblx0Ly8gcmVjb3JkIHByb21pc2UgZm9yIHRlc3QsIHRoYXQgcmVzb2x2ZXMgYmVmb3JlIHRlc3QgZW5kc1xuXHRpZiAodGVzdCAmJiBwcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuXHRcdC8vIGlmIHByb21pc2UgaXMgZXhwbGljaXRseSBhd2FpdGVkLCByZW1vdmUgaXQgZnJvbSB0aGUgbGlzdFxuXHRcdHByb21pc2UgPSBwcm9taXNlLmZpbmFsbHkoKCkgPT4ge1xuXHRcdFx0aWYgKCF0ZXN0LnByb21pc2VzKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdGNvbnN0IGluZGV4ID0gdGVzdC5wcm9taXNlcy5pbmRleE9mKHByb21pc2UpO1xuXHRcdFx0aWYgKGluZGV4ICE9PSAtMSkge1xuXHRcdFx0XHR0ZXN0LnByb21pc2VzLnNwbGljZShpbmRleCwgMSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0Ly8gcmVjb3JkIHByb21pc2Vcblx0XHRpZiAoIXRlc3QucHJvbWlzZXMpIHtcblx0XHRcdHRlc3QucHJvbWlzZXMgPSBbXTtcblx0XHR9XG5cdFx0Ly8gc2V0dXAgYGV4cGVjdC5zb2Z0YCBoYW5kbGVyIGhlcmUgaW5zdGVhZCBvZiBgd3JhcEFzc2VydGlvbmBcblx0XHQvLyB0byBhdm9pZCBkb3VibGUgZXJyb3IgdHJhY2tpbmcgd2hpbGUga2VlcGluZyBub24tYXdhaXQgcHJvbWlzZSBkZXRlY3Rpb24uXG5cdFx0aWYgKGlzU29mdCkge1xuXHRcdFx0cHJvbWlzZSA9IHByb21pc2UudGhlbihub29wLCAoZXJyKSA9PiB7XG5cdFx0XHRcdGhhbmRsZVRlc3RFcnJvcih0ZXN0LCBlcnIpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdHRlc3QucHJvbWlzZXMucHVzaChwcm9taXNlKTtcblx0XHRsZXQgcmVzb2x2ZWQgPSBmYWxzZTtcblx0XHR0ZXN0Lm9uRmluaXNoZWQgPz89IFtdO1xuXHRcdHRlc3Qub25GaW5pc2hlZC5wdXNoKCgpID0+IHtcblx0XHRcdGlmICghcmVzb2x2ZWQpIHtcblx0XHRcdFx0Y29uc3QgcHJvY2Vzc29yID0gZ2xvYmFsVGhpcy5fX3ZpdGVzdF93b3JrZXJfXz8ub25GaWx0ZXJTdGFja1RyYWNlIHx8ICgocykgPT4gcyB8fCBcIlwiKTtcblx0XHRcdFx0Y29uc3Qgc3RhY2sgPSBwcm9jZXNzb3IoZXJyb3Iuc3RhY2spO1xuXHRcdFx0XHRjb25zb2xlLndhcm4oW1xuXHRcdFx0XHRcdGBQcm9taXNlIHJldHVybmVkIGJ5IFxcYCR7YXNzZXJ0aW9ufVxcYCB3YXMgbm90IGF3YWl0ZWQuIGAsXG5cdFx0XHRcdFx0XCJWaXRlc3QgY3VycmVudGx5IGF1dG8tYXdhaXRzIGhhbmdpbmcgYXNzZXJ0aW9ucyBhdCB0aGUgZW5kIG9mIHRoZSB0ZXN0LCBidXQgdGhpcyB3aWxsIGNhdXNlIHRoZSB0ZXN0IHRvIGZhaWwgaW4gdGhlIG5leHQgVml0ZXN0IG1ham9yLiBcIixcblx0XHRcdFx0XHRcIlBsZWFzZSByZW1lbWJlciB0byBhd2FpdCB0aGUgYXNzZXJ0aW9uLlxcblwiLFxuXHRcdFx0XHRcdHN0YWNrXG5cdFx0XHRcdF0uam9pbihcIlwiKSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHRoZW4ob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcblx0XHRcdFx0cmVzb2x2ZWQgPSB0cnVlO1xuXHRcdFx0XHRyZXR1cm4gcHJvbWlzZS50aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKTtcblx0XHRcdH0sXG5cdFx0XHRjYXRjaChvblJlamVjdGVkKSB7XG5cdFx0XHRcdHJlc29sdmVkID0gdHJ1ZTtcblx0XHRcdFx0cmV0dXJuIHByb21pc2UuY2F0Y2gob25SZWplY3RlZCk7XG5cdFx0XHR9LFxuXHRcdFx0ZmluYWxseShvbkZpbmFsbHkpIHtcblx0XHRcdFx0cmVzb2x2ZWQgPSB0cnVlO1xuXHRcdFx0XHRyZXR1cm4gcHJvbWlzZS5maW5hbGx5KG9uRmluYWxseSk7XG5cdFx0XHR9LFxuXHRcdFx0W1N5bWJvbC50b1N0cmluZ1RhZ106IFwiUHJvbWlzZVwiXG5cdFx0fTtcblx0fVxuXHRyZXR1cm4gcHJvbWlzZTtcbn1cbmZ1bmN0aW9uIGhhbmRsZVRlc3RFcnJvcih0ZXN0LCBlcnIpIHtcblx0dGVzdC5yZXN1bHQgfHw9IHsgc3RhdGU6IFwiZmFpbFwiIH07XG5cdHRlc3QucmVzdWx0LnN0YXRlID0gXCJmYWlsXCI7XG5cdHRlc3QucmVzdWx0LmVycm9ycyB8fD0gW107XG5cdHRlc3QucmVzdWx0LmVycm9ycy5wdXNoKHByb2Nlc3NFcnJvcihlcnIpKTtcbn1cbi8qKiB3cmFwIGFzc2VydGlvbiBmdW5jdGlvbiB0byBzdXBwb3J0IGBleHBlY3Quc29mdGAgYW5kIHByb3ZpZGUgYXNzZXJ0aW9uIG5hbWUgYXMgYF9uYW1lYCAqL1xuZnVuY3Rpb24gd3JhcEFzc2VydGlvbih1dGlscywgbmFtZSwgZm4pIHtcblx0cmV0dXJuIGZ1bmN0aW9uKC4uLmFyZ3MpIHtcblx0XHQvLyBwcml2YXRlXG5cdFx0aWYgKG5hbWUgIT09IFwid2l0aFRlc3RcIikge1xuXHRcdFx0dXRpbHMuZmxhZyh0aGlzLCBcIl9uYW1lXCIsIG5hbWUpO1xuXHRcdH1cblx0XHRpZiAoIXV0aWxzLmZsYWcodGhpcywgXCJzb2Z0XCIpKSB7XG5cdFx0XHQvLyBhdm9pZCBXZWJLaXQncyBwcm9wZXIgdGFpbCBjYWxsIHRvIHByZXNlcnZlIHN0YWNrdHJhY2Ugb2Zmc2V0IGZvciBpbmxpbmUgc25hcHNob3Rcblx0XHRcdC8vIGh0dHBzOi8vd2Via2l0Lm9yZy9ibG9nLzYyNDAvZWNtYXNjcmlwdC02LXByb3Blci10YWlsLWNhbGxzLWluLXdlYmtpdFxuXHRcdFx0dHJ5IHtcblx0XHRcdFx0cmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXHRcdFx0fSBmaW5hbGx5IHt9XG5cdFx0fVxuXHRcdGNvbnN0IHRlc3QgPSB1dGlscy5mbGFnKHRoaXMsIFwidml0ZXN0LXRlc3RcIik7XG5cdFx0aWYgKCF0ZXN0KSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJleHBlY3Quc29mdCgpIGNhbiBvbmx5IGJlIHVzZWQgaW5zaWRlIGEgdGVzdFwiKTtcblx0XHR9XG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IHJlc3VsdCA9IGZuLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXHRcdFx0aWYgKHJlc3VsdCAmJiB0eXBlb2YgcmVzdWx0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiByZXN1bHQudGhlbiA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHRcdHJldHVybiByZXN1bHQudGhlbihub29wLCAoZXJyKSA9PiB7XG5cdFx0XHRcdFx0aGFuZGxlVGVzdEVycm9yKHRlc3QsIGVycik7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdGhhbmRsZVRlc3RFcnJvcih0ZXN0LCBlcnIpO1xuXHRcdH1cblx0fTtcbn1cblxuLy8gSmVzdCBFeHBlY3QgQ29tcGFjdFxuY29uc3QgSmVzdENoYWlFeHBlY3QgPSAoY2hhaSwgdXRpbHMpID0+IHtcblx0Y29uc3QgeyBBc3NlcnRpb25FcnJvciB9ID0gY2hhaTtcblx0Y29uc3QgY3VzdG9tVGVzdGVycyA9IGdldEN1c3RvbUVxdWFsaXR5VGVzdGVycygpO1xuXHRmdW5jdGlvbiBkZWYobmFtZSwgZm4pIHtcblx0XHRjb25zdCBhZGRNZXRob2QgPSAobikgPT4ge1xuXHRcdFx0Y29uc3Qgc29mdFdyYXBwZXIgPSB3cmFwQXNzZXJ0aW9uKHV0aWxzLCBuLCBmbik7XG5cdFx0XHR1dGlscy5hZGRNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCBuLCBzb2Z0V3JhcHBlcik7XG5cdFx0XHR1dGlscy5hZGRNZXRob2QoZ2xvYmFsVGhpc1tKRVNUX01BVENIRVJTX09CSkVDVF0ubWF0Y2hlcnMsIG4sIHNvZnRXcmFwcGVyKTtcblx0XHR9O1xuXHRcdGlmIChBcnJheS5pc0FycmF5KG5hbWUpKSB7XG5cdFx0XHRuYW1lLmZvckVhY2goKG4pID0+IGFkZE1ldGhvZChuKSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGFkZE1ldGhvZChuYW1lKTtcblx0XHR9XG5cdH1cblx0W1xuXHRcdFwidGhyb3dcIixcblx0XHRcInRocm93c1wiLFxuXHRcdFwiVGhyb3dcIlxuXHRdLmZvckVhY2goKG0pID0+IHtcblx0XHR1dGlscy5vdmVyd3JpdGVNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCBtLCAoX3N1cGVyKSA9PiB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oLi4uYXJncykge1xuXHRcdFx0XHRjb25zdCBwcm9taXNlID0gdXRpbHMuZmxhZyh0aGlzLCBcInByb21pc2VcIik7XG5cdFx0XHRcdGNvbnN0IG9iamVjdCA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0XHRcdGNvbnN0IGlzTm90ID0gdXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKTtcblx0XHRcdFx0aWYgKHByb21pc2UgPT09IFwicmVqZWN0c1wiKSB7XG5cdFx0XHRcdFx0dXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiLCAoKSA9PiB7XG5cdFx0XHRcdFx0XHR0aHJvdyBvYmplY3Q7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH0gZWxzZSBpZiAocHJvbWlzZSA9PT0gXCJyZXNvbHZlc1wiICYmIHR5cGVvZiBvYmplY3QgIT09IFwiZnVuY3Rpb25cIikge1xuXHRcdFx0XHRcdGlmICghaXNOb3QpIHtcblx0XHRcdFx0XHRcdGNvbnN0IG1lc3NhZ2UgPSB1dGlscy5mbGFnKHRoaXMsIFwibWVzc2FnZVwiKSB8fCBcImV4cGVjdGVkIHByb21pc2UgdG8gdGhyb3cgYW4gZXJyb3IsIGJ1dCBpdCBkaWRuJ3RcIjtcblx0XHRcdFx0XHRcdGNvbnN0IGVycm9yID0geyBzaG93RGlmZjogZmFsc2UgfTtcblx0XHRcdFx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtZXNzYWdlLCBlcnJvciwgdXRpbHMuZmxhZyh0aGlzLCBcInNzZmlcIikpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdF9zdXBlci5hcHBseSh0aGlzLCBhcmdzKTtcblx0XHRcdH07XG5cdFx0fSk7XG5cdH0pO1xuXHQvLyBAdHMtZXhwZWN0LWVycm9yIEBpbnRlcm5hbFxuXHRkZWYoXCJ3aXRoVGVzdFwiLCBmdW5jdGlvbih0ZXN0KSB7XG5cdFx0dXRpbHMuZmxhZyh0aGlzLCBcInZpdGVzdC10ZXN0XCIsIHRlc3QpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9KTtcblx0ZGVmKFwidG9FcXVhbFwiLCBmdW5jdGlvbihleHBlY3RlZCkge1xuXHRcdGNvbnN0IGFjdHVhbCA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0Y29uc3QgZXF1YWwgPSBlcXVhbHMoYWN0dWFsLCBleHBlY3RlZCwgWy4uLmN1c3RvbVRlc3RlcnMsIGl0ZXJhYmxlRXF1YWxpdHldKTtcblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQoZXF1YWwsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBkZWVwbHkgZXF1YWwgI3tleHB9XCIsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgZGVlcGx5IGVxdWFsICN7ZXhwfVwiLCBleHBlY3RlZCwgYWN0dWFsKTtcblx0fSk7XG5cdGRlZihcInRvU3RyaWN0RXF1YWxcIiwgZnVuY3Rpb24oZXhwZWN0ZWQpIHtcblx0XHRjb25zdCBvYmogPSB1dGlscy5mbGFnKHRoaXMsIFwib2JqZWN0XCIpO1xuXHRcdGNvbnN0IGVxdWFsID0gZXF1YWxzKG9iaiwgZXhwZWN0ZWQsIFtcblx0XHRcdC4uLmN1c3RvbVRlc3RlcnMsXG5cdFx0XHRpdGVyYWJsZUVxdWFsaXR5LFxuXHRcdFx0dHlwZUVxdWFsaXR5LFxuXHRcdFx0c3BhcnNlQXJyYXlFcXVhbGl0eSxcblx0XHRcdGFycmF5QnVmZmVyRXF1YWxpdHlcblx0XHRdLCB0cnVlKTtcblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQoZXF1YWwsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBzdHJpY3RseSBlcXVhbCAje2V4cH1cIiwgXCJleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBzdHJpY3RseSBlcXVhbCAje2V4cH1cIiwgZXhwZWN0ZWQsIG9iaik7XG5cdH0pO1xuXHRkZWYoXCJ0b0JlXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdGhpcy5fb2JqO1xuXHRcdGNvbnN0IHBhc3MgPSBPYmplY3QuaXMoYWN0dWFsLCBleHBlY3RlZCk7XG5cdFx0bGV0IGRlZXBFcXVhbGl0eU5hbWUgPSBcIlwiO1xuXHRcdGlmICghcGFzcykge1xuXHRcdFx0Y29uc3QgdG9TdHJpY3RFcXVhbFBhc3MgPSBlcXVhbHMoYWN0dWFsLCBleHBlY3RlZCwgW1xuXHRcdFx0XHQuLi5jdXN0b21UZXN0ZXJzLFxuXHRcdFx0XHRpdGVyYWJsZUVxdWFsaXR5LFxuXHRcdFx0XHR0eXBlRXF1YWxpdHksXG5cdFx0XHRcdHNwYXJzZUFycmF5RXF1YWxpdHksXG5cdFx0XHRcdGFycmF5QnVmZmVyRXF1YWxpdHlcblx0XHRcdF0sIHRydWUpO1xuXHRcdFx0aWYgKHRvU3RyaWN0RXF1YWxQYXNzKSB7XG5cdFx0XHRcdGRlZXBFcXVhbGl0eU5hbWUgPSBcInRvU3RyaWN0RXF1YWxcIjtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNvbnN0IHRvRXF1YWxQYXNzID0gZXF1YWxzKGFjdHVhbCwgZXhwZWN0ZWQsIFsuLi5jdXN0b21UZXN0ZXJzLCBpdGVyYWJsZUVxdWFsaXR5XSk7XG5cdFx0XHRcdGlmICh0b0VxdWFsUGFzcykge1xuXHRcdFx0XHRcdGRlZXBFcXVhbGl0eU5hbWUgPSBcInRvRXF1YWxcIjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQocGFzcywgZ2VuZXJhdGVUb0JlTWVzc2FnZShkZWVwRXF1YWxpdHlOYW1lKSwgXCJleHBlY3RlZCAje3RoaXN9IG5vdCB0byBiZSAje2V4cH0gLy8gT2JqZWN0LmlzIGVxdWFsaXR5XCIsIGV4cGVjdGVkLCBhY3R1YWwpO1xuXHR9KTtcblx0ZGVmKFwidG9NYXRjaE9iamVjdFwiLCBmdW5jdGlvbihleHBlY3RlZCkge1xuXHRcdGNvbnN0IGFjdHVhbCA9IHRoaXMuX29iajtcblx0XHRjb25zdCBwYXNzID0gZXF1YWxzKGFjdHVhbCwgZXhwZWN0ZWQsIFtcblx0XHRcdC4uLmN1c3RvbVRlc3RlcnMsXG5cdFx0XHRpdGVyYWJsZUVxdWFsaXR5LFxuXHRcdFx0c3Vic2V0RXF1YWxpdHlcblx0XHRdKTtcblx0XHRjb25zdCBpc05vdCA9IHV0aWxzLmZsYWcodGhpcywgXCJuZWdhdGVcIik7XG5cdFx0Y29uc3QgeyBzdWJzZXQ6IGFjdHVhbFN1YnNldCwgc3RyaXBwZWQgfSA9IGdldE9iamVjdFN1YnNldChhY3R1YWwsIGV4cGVjdGVkLCBjdXN0b21UZXN0ZXJzKTtcblx0XHRpZiAocGFzcyAmJiBpc05vdCB8fCAhcGFzcyAmJiAhaXNOb3QpIHtcblx0XHRcdGNvbnN0IG1zZyA9IHV0aWxzLmdldE1lc3NhZ2UodGhpcywgW1xuXHRcdFx0XHRwYXNzLFxuXHRcdFx0XHRcImV4cGVjdGVkICN7dGhpc30gdG8gbWF0Y2ggb2JqZWN0ICN7ZXhwfVwiLFxuXHRcdFx0XHRcImV4cGVjdGVkICN7dGhpc30gdG8gbm90IG1hdGNoIG9iamVjdCAje2V4cH1cIixcblx0XHRcdFx0ZXhwZWN0ZWQsXG5cdFx0XHRcdGFjdHVhbFN1YnNldCxcblx0XHRcdFx0ZmFsc2Vcblx0XHRcdF0pO1xuXHRcdFx0Y29uc3QgbWVzc2FnZSA9IHN0cmlwcGVkID09PSAwID8gbXNnIDogYCR7bXNnfVxcbigke3N0cmlwcGVkfSBtYXRjaGluZyAke3N0cmlwcGVkID09PSAxID8gXCJwcm9wZXJ0eVwiIDogXCJwcm9wZXJ0aWVzXCJ9IG9taXR0ZWQgZnJvbSBhY3R1YWwpYDtcblx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtZXNzYWdlLCB7XG5cdFx0XHRcdHNob3dEaWZmOiB0cnVlLFxuXHRcdFx0XHRleHBlY3RlZCxcblx0XHRcdFx0YWN0dWFsOiBhY3R1YWxTdWJzZXRcblx0XHRcdH0pO1xuXHRcdH1cblx0fSk7XG5cdGRlZihcInRvTWF0Y2hcIiwgZnVuY3Rpb24oZXhwZWN0ZWQpIHtcblx0XHRjb25zdCBhY3R1YWwgPSB0aGlzLl9vYmo7XG5cdFx0aWYgKHR5cGVvZiBhY3R1YWwgIT09IFwic3RyaW5nXCIpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYC50b01hdGNoKCkgZXhwZWN0cyB0byByZWNlaXZlIGEgc3RyaW5nLCBidXQgZ290ICR7dHlwZW9mIGFjdHVhbH1gKTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuYXNzZXJ0KHR5cGVvZiBleHBlY3RlZCA9PT0gXCJzdHJpbmdcIiA/IGFjdHVhbC5pbmNsdWRlcyhleHBlY3RlZCkgOiBhY3R1YWwubWF0Y2goZXhwZWN0ZWQpLCBgZXhwZWN0ZWQgI3t0aGlzfSB0byBtYXRjaCAje2V4cH1gLCBgZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gbWF0Y2ggI3tleHB9YCwgZXhwZWN0ZWQsIGFjdHVhbCk7XG5cdH0pO1xuXHRkZWYoXCJ0b0NvbnRhaW5cIiwgZnVuY3Rpb24oaXRlbSkge1xuXHRcdGNvbnN0IGFjdHVhbCA9IHRoaXMuX29iajtcblx0XHRpZiAodHlwZW9mIE5vZGUgIT09IFwidW5kZWZpbmVkXCIgJiYgYWN0dWFsIGluc3RhbmNlb2YgTm9kZSkge1xuXHRcdFx0aWYgKCEoaXRlbSBpbnN0YW5jZW9mIE5vZGUpKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYHRvQ29udGFpbigpIGV4cGVjdGVkIGEgRE9NIG5vZGUgYXMgdGhlIGFyZ3VtZW50LCBidXQgZ290ICR7dHlwZW9mIGl0ZW19YCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdGhpcy5hc3NlcnQoYWN0dWFsLmNvbnRhaW5zKGl0ZW0pLCBcImV4cGVjdGVkICN7dGhpc30gdG8gY29udGFpbiBlbGVtZW50ICN7ZXhwfVwiLCBcImV4cGVjdGVkICN7dGhpc30gbm90IHRvIGNvbnRhaW4gZWxlbWVudCAje2V4cH1cIiwgaXRlbSwgYWN0dWFsKTtcblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBET01Ub2tlbkxpc3QgIT09IFwidW5kZWZpbmVkXCIgJiYgYWN0dWFsIGluc3RhbmNlb2YgRE9NVG9rZW5MaXN0KSB7XG5cdFx0XHRhc3NlcnRUeXBlcyhpdGVtLCBcImNsYXNzIG5hbWVcIiwgW1wic3RyaW5nXCJdKTtcblx0XHRcdGNvbnN0IGlzTm90ID0gdXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKTtcblx0XHRcdGNvbnN0IGV4cGVjdGVkQ2xhc3NMaXN0ID0gaXNOb3QgPyBhY3R1YWwudmFsdWUucmVwbGFjZShpdGVtLCBcIlwiKS50cmltKCkgOiBgJHthY3R1YWwudmFsdWV9ICR7aXRlbX1gO1xuXHRcdFx0cmV0dXJuIHRoaXMuYXNzZXJ0KGFjdHVhbC5jb250YWlucyhpdGVtKSwgYGV4cGVjdGVkIFwiJHthY3R1YWwudmFsdWV9XCIgdG8gY29udGFpbiBcIiR7aXRlbX1cImAsIGBleHBlY3RlZCBcIiR7YWN0dWFsLnZhbHVlfVwiIG5vdCB0byBjb250YWluIFwiJHtpdGVtfVwiYCwgZXhwZWN0ZWRDbGFzc0xpc3QsIGFjdHVhbC52YWx1ZSk7XG5cdFx0fVxuXHRcdC8vIGhhbmRsZSBzaW1wbGUgY2FzZSBvbiBvdXIgb3duIHVzaW5nIGB0aGlzLmFzc2VydGAgdG8gaW5jbHVkZSBkaWZmIGluIGVycm9yIG1lc3NhZ2Vcblx0XHRpZiAodHlwZW9mIGFjdHVhbCA9PT0gXCJzdHJpbmdcIiAmJiB0eXBlb2YgaXRlbSA9PT0gXCJzdHJpbmdcIikge1xuXHRcdFx0cmV0dXJuIHRoaXMuYXNzZXJ0KGFjdHVhbC5pbmNsdWRlcyhpdGVtKSwgYGV4cGVjdGVkICN7dGhpc30gdG8gY29udGFpbiAje2V4cH1gLCBgZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gY29udGFpbiAje2V4cH1gLCBpdGVtLCBhY3R1YWwpO1xuXHRcdH1cblx0XHQvLyBtYWtlIFwiYWN0dWFsXCIgaW5kZXhhYmxlIHRvIGhhdmUgY29tcGF0aWJpbGl0eSB3aXRoIGplc3Rcblx0XHRpZiAoYWN0dWFsICE9IG51bGwgJiYgdHlwZW9mIGFjdHVhbCAhPT0gXCJzdHJpbmdcIikge1xuXHRcdFx0dXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiLCBBcnJheS5mcm9tKGFjdHVhbCkpO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5jb250YWluKGl0ZW0pO1xuXHR9KTtcblx0ZGVmKFwidG9Db250YWluRXF1YWxcIiwgZnVuY3Rpb24oZXhwZWN0ZWQpIHtcblx0XHRjb25zdCBvYmogPSB1dGlscy5mbGFnKHRoaXMsIFwib2JqZWN0XCIpO1xuXHRcdGNvbnN0IGluZGV4ID0gQXJyYXkuZnJvbShvYmopLmZpbmRJbmRleCgoaXRlbSkgPT4ge1xuXHRcdFx0cmV0dXJuIGVxdWFscyhpdGVtLCBleHBlY3RlZCwgY3VzdG9tVGVzdGVycyk7XG5cdFx0fSk7XG5cdFx0dGhpcy5hc3NlcnQoaW5kZXggIT09IC0xLCBcImV4cGVjdGVkICN7dGhpc30gdG8gZGVlcCBlcXVhbGx5IGNvbnRhaW4gI3tleHB9XCIsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgZGVlcCBlcXVhbGx5IGNvbnRhaW4gI3tleHB9XCIsIGV4cGVjdGVkKTtcblx0fSk7XG5cdGRlZihcInRvQmVUcnV0aHlcIiwgZnVuY3Rpb24oKSB7XG5cdFx0Y29uc3Qgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKTtcblx0XHR0aGlzLmFzc2VydChCb29sZWFuKG9iaiksIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSB0cnV0aHlcIiwgXCJleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBiZSB0cnV0aHlcIiwgdHJ1ZSwgb2JqKTtcblx0fSk7XG5cdGRlZihcInRvQmVGYWxzeVwiLCBmdW5jdGlvbigpIHtcblx0XHRjb25zdCBvYmogPSB1dGlscy5mbGFnKHRoaXMsIFwib2JqZWN0XCIpO1xuXHRcdHRoaXMuYXNzZXJ0KCFvYmosIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBmYWxzeVwiLCBcImV4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIGZhbHN5XCIsIGZhbHNlLCBvYmopO1xuXHR9KTtcblx0ZGVmKFwidG9CZUdyZWF0ZXJUaGFuXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdGhpcy5fb2JqO1xuXHRcdGFzc2VydFR5cGVzKGFjdHVhbCwgXCJhY3R1YWxcIiwgW1wibnVtYmVyXCIsIFwiYmlnaW50XCJdKTtcblx0XHRhc3NlcnRUeXBlcyhleHBlY3RlZCwgXCJleHBlY3RlZFwiLCBbXCJudW1iZXJcIiwgXCJiaWdpbnRcIl0pO1xuXHRcdHJldHVybiB0aGlzLmFzc2VydChhY3R1YWwgPiBleHBlY3RlZCwgYGV4cGVjdGVkICR7YWN0dWFsfSB0byBiZSBncmVhdGVyIHRoYW4gJHtleHBlY3RlZH1gLCBgZXhwZWN0ZWQgJHthY3R1YWx9IHRvIGJlIG5vdCBncmVhdGVyIHRoYW4gJHtleHBlY3RlZH1gLCBleHBlY3RlZCwgYWN0dWFsLCBmYWxzZSk7XG5cdH0pO1xuXHRkZWYoXCJ0b0JlR3JlYXRlclRoYW5PckVxdWFsXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdGhpcy5fb2JqO1xuXHRcdGFzc2VydFR5cGVzKGFjdHVhbCwgXCJhY3R1YWxcIiwgW1wibnVtYmVyXCIsIFwiYmlnaW50XCJdKTtcblx0XHRhc3NlcnRUeXBlcyhleHBlY3RlZCwgXCJleHBlY3RlZFwiLCBbXCJudW1iZXJcIiwgXCJiaWdpbnRcIl0pO1xuXHRcdHJldHVybiB0aGlzLmFzc2VydChhY3R1YWwgPj0gZXhwZWN0ZWQsIGBleHBlY3RlZCAke2FjdHVhbH0gdG8gYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICR7ZXhwZWN0ZWR9YCwgYGV4cGVjdGVkICR7YWN0dWFsfSB0byBiZSBub3QgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICR7ZXhwZWN0ZWR9YCwgZXhwZWN0ZWQsIGFjdHVhbCwgZmFsc2UpO1xuXHR9KTtcblx0ZGVmKFwidG9CZUxlc3NUaGFuXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdGhpcy5fb2JqO1xuXHRcdGFzc2VydFR5cGVzKGFjdHVhbCwgXCJhY3R1YWxcIiwgW1wibnVtYmVyXCIsIFwiYmlnaW50XCJdKTtcblx0XHRhc3NlcnRUeXBlcyhleHBlY3RlZCwgXCJleHBlY3RlZFwiLCBbXCJudW1iZXJcIiwgXCJiaWdpbnRcIl0pO1xuXHRcdHJldHVybiB0aGlzLmFzc2VydChhY3R1YWwgPCBleHBlY3RlZCwgYGV4cGVjdGVkICR7YWN0dWFsfSB0byBiZSBsZXNzIHRoYW4gJHtleHBlY3RlZH1gLCBgZXhwZWN0ZWQgJHthY3R1YWx9IHRvIGJlIG5vdCBsZXNzIHRoYW4gJHtleHBlY3RlZH1gLCBleHBlY3RlZCwgYWN0dWFsLCBmYWxzZSk7XG5cdH0pO1xuXHRkZWYoXCJ0b0JlTGVzc1RoYW5PckVxdWFsXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdGhpcy5fb2JqO1xuXHRcdGFzc2VydFR5cGVzKGFjdHVhbCwgXCJhY3R1YWxcIiwgW1wibnVtYmVyXCIsIFwiYmlnaW50XCJdKTtcblx0XHRhc3NlcnRUeXBlcyhleHBlY3RlZCwgXCJleHBlY3RlZFwiLCBbXCJudW1iZXJcIiwgXCJiaWdpbnRcIl0pO1xuXHRcdHJldHVybiB0aGlzLmFzc2VydChhY3R1YWwgPD0gZXhwZWN0ZWQsIGBleHBlY3RlZCAke2FjdHVhbH0gdG8gYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICR7ZXhwZWN0ZWR9YCwgYGV4cGVjdGVkICR7YWN0dWFsfSB0byBiZSBub3QgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICR7ZXhwZWN0ZWR9YCwgZXhwZWN0ZWQsIGFjdHVhbCwgZmFsc2UpO1xuXHR9KTtcblx0ZGVmKFwidG9CZU5hTlwiLCBmdW5jdGlvbigpIHtcblx0XHRjb25zdCBvYmogPSB1dGlscy5mbGFnKHRoaXMsIFwib2JqZWN0XCIpO1xuXHRcdHRoaXMuYXNzZXJ0KE51bWJlci5pc05hTihvYmopLCBcImV4cGVjdGVkICN7dGhpc30gdG8gYmUgTmFOXCIsIFwiZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgTmFOXCIsIE51bWJlci5OYU4sIG9iaik7XG5cdH0pO1xuXHRkZWYoXCJ0b0JlVW5kZWZpbmVkXCIsIGZ1bmN0aW9uKCkge1xuXHRcdGNvbnN0IG9iaiA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0dGhpcy5hc3NlcnQodW5kZWZpbmVkID09PSBvYmosIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSB1bmRlZmluZWRcIiwgXCJleHBlY3RlZCAje3RoaXN9IG5vdCB0byBiZSB1bmRlZmluZWRcIiwgdW5kZWZpbmVkLCBvYmopO1xuXHR9KTtcblx0ZGVmKFwidG9CZU51bGxcIiwgZnVuY3Rpb24oKSB7XG5cdFx0Y29uc3Qgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKTtcblx0XHR0aGlzLmFzc2VydChvYmogPT09IG51bGwsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBudWxsXCIsIFwiZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgbnVsbFwiLCBudWxsLCBvYmopO1xuXHR9KTtcblx0ZGVmKFwidG9CZU51bGxhYmxlXCIsIGZ1bmN0aW9uKCkge1xuXHRcdGNvbnN0IG9iaiA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0dGhpcy5hc3NlcnQob2JqID09IG51bGwsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBudWxsaXNoXCIsIFwiZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgbnVsbGlzaFwiLCBudWxsLCBvYmopO1xuXHR9KTtcblx0ZGVmKFwidG9CZURlZmluZWRcIiwgZnVuY3Rpb24oKSB7XG5cdFx0Y29uc3Qgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKTtcblx0XHR0aGlzLmFzc2VydCh0eXBlb2Ygb2JqICE9PSBcInVuZGVmaW5lZFwiLCBcImV4cGVjdGVkICN7dGhpc30gdG8gYmUgZGVmaW5lZFwiLCBcImV4cGVjdGVkICN7dGhpc30gdG8gYmUgdW5kZWZpbmVkXCIsIG9iaik7XG5cdH0pO1xuXHRkZWYoXCJ0b0JlVHlwZU9mXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdHlwZW9mIHRoaXMuX29iajtcblx0XHRjb25zdCBlcXVhbCA9IGV4cGVjdGVkID09PSBhY3R1YWw7XG5cdFx0cmV0dXJuIHRoaXMuYXNzZXJ0KGVxdWFsLCBcImV4cGVjdGVkICN7dGhpc30gdG8gYmUgdHlwZSBvZiAje2V4cH1cIiwgXCJleHBlY3RlZCAje3RoaXN9IG5vdCB0byBiZSB0eXBlIG9mICN7ZXhwfVwiLCBleHBlY3RlZCwgYWN0dWFsKTtcblx0fSk7XG5cdGRlZihcInRvQmVJbnN0YW5jZU9mXCIsIGZ1bmN0aW9uKG9iaikge1xuXHRcdHJldHVybiB0aGlzLmluc3RhbmNlT2Yob2JqKTtcblx0fSk7XG5cdGRlZihcInRvSGF2ZUxlbmd0aFwiLCBmdW5jdGlvbihsZW5ndGgpIHtcblx0XHRyZXR1cm4gdGhpcy5oYXZlLmxlbmd0aChsZW5ndGgpO1xuXHR9KTtcblx0Ly8gZGVzdHJ1Y3R1cmluZywgYmVjYXVzZSBpdCBjaGVja3MgYGFyZ3VtZW50c2AgaW5zaWRlLCBhbmQgdmFsdWUgaXMgcGFzc2luZyBhcyBgdW5kZWZpbmVkYFxuXHRkZWYoXCJ0b0hhdmVQcm9wZXJ0eVwiLCBmdW5jdGlvbiguLi5hcmdzKSB7XG5cdFx0aWYgKEFycmF5LmlzQXJyYXkoYXJnc1swXSkpIHtcblx0XHRcdGFyZ3NbMF0gPSBhcmdzWzBdLm1hcCgoa2V5KSA9PiBTdHJpbmcoa2V5KS5yZXBsYWNlKC8oWy5bXFxdXSkvZywgXCJcXFxcJDFcIikpLmpvaW4oXCIuXCIpO1xuXHRcdH1cblx0XHRjb25zdCBhY3R1YWwgPSB0aGlzLl9vYmo7XG5cdFx0Y29uc3QgW3Byb3BlcnR5TmFtZSwgZXhwZWN0ZWRdID0gYXJncztcblx0XHRjb25zdCBnZXRWYWx1ZSA9ICgpID0+IHtcblx0XHRcdGNvbnN0IGhhc093biA9IE9iamVjdC5oYXNPd24oYWN0dWFsLCBwcm9wZXJ0eU5hbWUpO1xuXHRcdFx0aWYgKGhhc093bikge1xuXHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdHZhbHVlOiBhY3R1YWxbcHJvcGVydHlOYW1lXSxcblx0XHRcdFx0XHRleGlzdHM6IHRydWVcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB1dGlscy5nZXRQYXRoSW5mbyhhY3R1YWwsIHByb3BlcnR5TmFtZSk7XG5cdFx0fTtcblx0XHRjb25zdCB7IHZhbHVlLCBleGlzdHMgfSA9IGdldFZhbHVlKCk7XG5cdFx0Y29uc3QgcGFzcyA9IGV4aXN0cyAmJiAoYXJncy5sZW5ndGggPT09IDEgfHwgZXF1YWxzKGV4cGVjdGVkLCB2YWx1ZSwgY3VzdG9tVGVzdGVycykpO1xuXHRcdGNvbnN0IHZhbHVlU3RyaW5nID0gYXJncy5sZW5ndGggPT09IDEgPyBcIlwiIDogYCB3aXRoIHZhbHVlICR7dXRpbHMub2JqRGlzcGxheShleHBlY3RlZCl9YDtcblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQocGFzcywgYGV4cGVjdGVkICN7dGhpc30gdG8gaGF2ZSBwcm9wZXJ0eSBcIiR7cHJvcGVydHlOYW1lfVwiJHt2YWx1ZVN0cmluZ31gLCBgZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgaGF2ZSBwcm9wZXJ0eSBcIiR7cHJvcGVydHlOYW1lfVwiJHt2YWx1ZVN0cmluZ31gLCBleHBlY3RlZCwgZXhpc3RzID8gdmFsdWUgOiB1bmRlZmluZWQpO1xuXHR9KTtcblx0ZGVmKFwidG9CZUNsb3NlVG9cIiwgZnVuY3Rpb24ocmVjZWl2ZWQsIHByZWNpc2lvbiA9IDIpIHtcblx0XHRjb25zdCBleHBlY3RlZCA9IHRoaXMuX29iajtcblx0XHRsZXQgcGFzcyA9IGZhbHNlO1xuXHRcdGxldCBleHBlY3RlZERpZmYgPSAwO1xuXHRcdGxldCByZWNlaXZlZERpZmYgPSAwO1xuXHRcdGlmIChyZWNlaXZlZCA9PT0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZICYmIGV4cGVjdGVkID09PSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpIHtcblx0XHRcdHBhc3MgPSB0cnVlO1xuXHRcdH0gZWxzZSBpZiAocmVjZWl2ZWQgPT09IE51bWJlci5ORUdBVElWRV9JTkZJTklUWSAmJiBleHBlY3RlZCA9PT0gTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZKSB7XG5cdFx0XHRwYXNzID0gdHJ1ZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZXhwZWN0ZWREaWZmID0gMTAgKiogLXByZWNpc2lvbiAvIDI7XG5cdFx0XHRyZWNlaXZlZERpZmYgPSBNYXRoLmFicyhleHBlY3RlZCAtIHJlY2VpdmVkKTtcblx0XHRcdHBhc3MgPSByZWNlaXZlZERpZmYgPCBleHBlY3RlZERpZmY7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmFzc2VydChwYXNzLCBgZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBjbG9zZSB0byAje2V4cH0sIHJlY2VpdmVkIGRpZmZlcmVuY2UgaXMgJHtyZWNlaXZlZERpZmZ9LCBidXQgZXhwZWN0ZWQgJHtleHBlY3RlZERpZmZ9YCwgYGV4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIGNsb3NlIHRvICN7ZXhwfSwgcmVjZWl2ZWQgZGlmZmVyZW5jZSBpcyAke3JlY2VpdmVkRGlmZn0sIGJ1dCBleHBlY3RlZCAke2V4cGVjdGVkRGlmZn1gLCByZWNlaXZlZCwgZXhwZWN0ZWQsIGZhbHNlKTtcblx0fSk7XG5cdGZ1bmN0aW9uIGFzc2VydElzTW9jayhhc3NlcnRpb24pIHtcblx0XHRpZiAoIWlzTW9ja0Z1bmN0aW9uKGFzc2VydGlvbi5fb2JqKSkge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihgJHt1dGlscy5pbnNwZWN0KGFzc2VydGlvbi5fb2JqKX0gaXMgbm90IGEgc3B5IG9yIGEgY2FsbCB0byBhIHNweSFgKTtcblx0XHR9XG5cdH1cblx0ZnVuY3Rpb24gZ2V0U3B5KGFzc2VydGlvbikge1xuXHRcdGFzc2VydElzTW9jayhhc3NlcnRpb24pO1xuXHRcdHJldHVybiBhc3NlcnRpb24uX29iajtcblx0fVxuXHRkZWYoW1widG9IYXZlQmVlbkNhbGxlZFRpbWVzXCIsIFwidG9CZUNhbGxlZFRpbWVzXCJdLCBmdW5jdGlvbihudW1iZXIpIHtcblx0XHRjb25zdCBzcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdGNvbnN0IGNhbGxDb3VudCA9IHNweS5tb2NrLmNhbGxzLmxlbmd0aDtcblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQoY2FsbENvdW50ID09PSBudW1iZXIsIGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byBiZSBjYWxsZWQgI3tleHB9IHRpbWVzLCBidXQgZ290ICR7Y2FsbENvdW50fSB0aW1lc2AsIGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byBub3QgYmUgY2FsbGVkICN7ZXhwfSB0aW1lc2AsIG51bWJlciwgY2FsbENvdW50LCBmYWxzZSk7XG5cdH0pO1xuXHRkZWYoXCJ0b0hhdmVCZWVuQ2FsbGVkT25jZVwiLCBmdW5jdGlvbigpIHtcblx0XHRjb25zdCBzcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdGNvbnN0IGNhbGxDb3VudCA9IHNweS5tb2NrLmNhbGxzLmxlbmd0aDtcblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQoY2FsbENvdW50ID09PSAxLCBgZXhwZWN0ZWQgXCIke3NweU5hbWV9XCIgdG8gYmUgY2FsbGVkIG9uY2UsIGJ1dCBnb3QgJHtjYWxsQ291bnR9IHRpbWVzYCwgYGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIG5vdCBiZSBjYWxsZWQgb25jZWAsIDEsIGNhbGxDb3VudCwgZmFsc2UpO1xuXHR9KTtcblx0ZGVmKFtcInRvSGF2ZUJlZW5DYWxsZWRcIiwgXCJ0b0JlQ2FsbGVkXCJdLCBmdW5jdGlvbigpIHtcblx0XHRjb25zdCBzcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdGNvbnN0IGNhbGxDb3VudCA9IHNweS5tb2NrLmNhbGxzLmxlbmd0aDtcblx0XHRjb25zdCBjYWxsZWQgPSBjYWxsQ291bnQgPiAwO1xuXHRcdGNvbnN0IGlzTm90ID0gdXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKTtcblx0XHRsZXQgbXNnID0gdXRpbHMuZ2V0TWVzc2FnZSh0aGlzLCBbXG5cdFx0XHRjYWxsZWQsXG5cdFx0XHRgZXhwZWN0ZWQgXCIke3NweU5hbWV9XCIgdG8gYmUgY2FsbGVkIGF0IGxlYXN0IG9uY2VgLFxuXHRcdFx0YGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIG5vdCBiZSBjYWxsZWQgYXQgYWxsLCBidXQgYWN0dWFsbHkgYmVlbiBjYWxsZWQgJHtjYWxsQ291bnR9IHRpbWVzYCxcblx0XHRcdHRydWUsXG5cdFx0XHRjYWxsZWRcblx0XHRdKTtcblx0XHRpZiAoY2FsbGVkICYmIGlzTm90KSB7XG5cdFx0XHRtc2cgPSBmb3JtYXRDYWxscyhzcHksIG1zZyk7XG5cdFx0fVxuXHRcdGlmIChjYWxsZWQgJiYgaXNOb3QgfHwgIWNhbGxlZCAmJiAhaXNOb3QpIHtcblx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtc2cpO1xuXHRcdH1cblx0fSk7XG5cdC8vIG1hbnVhbGx5IGNvbXBhcmUgYXJyYXkgZWxlbWVudHMgc2luY2UgYGplc3RFcXVhbHNgIGNhbm5vdFxuXHQvLyBhcHBseSBhc3ltbWV0cmljIG1hdGNoZXIgdG8gYHVuZGVmaW5lZGAgYXJyYXkgZWxlbWVudC5cblx0ZnVuY3Rpb24gZXF1YWxzQXJndW1lbnRBcnJheShhLCBiKSB7XG5cdFx0cmV0dXJuIGEubGVuZ3RoID09PSBiLmxlbmd0aCAmJiBhLmV2ZXJ5KChhSXRlbSwgaSkgPT4gZXF1YWxzKGFJdGVtLCBiW2ldLCBbLi4uY3VzdG9tVGVzdGVycywgaXRlcmFibGVFcXVhbGl0eV0pKTtcblx0fVxuXHRkZWYoW1widG9IYXZlQmVlbkNhbGxlZFdpdGhcIiwgXCJ0b0JlQ2FsbGVkV2l0aFwiXSwgZnVuY3Rpb24oLi4uYXJncykge1xuXHRcdGNvbnN0IHNweSA9IGdldFNweSh0aGlzKTtcblx0XHRjb25zdCBzcHlOYW1lID0gc3B5LmdldE1vY2tOYW1lKCk7XG5cdFx0Y29uc3QgcGFzcyA9IHNweS5tb2NrLmNhbGxzLnNvbWUoKGNhbGxBcmcpID0+IGVxdWFsc0FyZ3VtZW50QXJyYXkoY2FsbEFyZywgYXJncykpO1xuXHRcdGNvbnN0IGlzTm90ID0gdXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKTtcblx0XHRjb25zdCBtc2cgPSB1dGlscy5nZXRNZXNzYWdlKHRoaXMsIFtcblx0XHRcdHBhc3MsXG5cdFx0XHRgZXhwZWN0ZWQgXCIke3NweU5hbWV9XCIgdG8gYmUgY2FsbGVkIHdpdGggYXJndW1lbnRzOiAje2V4cH1gLFxuXHRcdFx0YGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIG5vdCBiZSBjYWxsZWQgd2l0aCBhcmd1bWVudHM6ICN7ZXhwfWAsXG5cdFx0XHRhcmdzXG5cdFx0XSk7XG5cdFx0aWYgKHBhc3MgJiYgaXNOb3QgfHwgIXBhc3MgJiYgIWlzTm90KSB7XG5cdFx0XHR0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZm9ybWF0Q2FsbHMoc3B5LCBtc2csIGFyZ3MpKTtcblx0XHR9XG5cdH0pO1xuXHRkZWYoXCJ0b0hhdmVCZWVuQ2FsbGVkRXhhY3RseU9uY2VXaXRoXCIsIGZ1bmN0aW9uKC4uLmFyZ3MpIHtcblx0XHRjb25zdCBzcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdGNvbnN0IGNhbGxDb3VudCA9IHNweS5tb2NrLmNhbGxzLmxlbmd0aDtcblx0XHRjb25zdCBoYXNDYWxsV2l0aEFyZ3MgPSBzcHkubW9jay5jYWxscy5zb21lKChjYWxsQXJnKSA9PiBlcXVhbHNBcmd1bWVudEFycmF5KGNhbGxBcmcsIGFyZ3MpKTtcblx0XHRjb25zdCBwYXNzID0gaGFzQ2FsbFdpdGhBcmdzICYmIGNhbGxDb3VudCA9PT0gMTtcblx0XHRjb25zdCBpc05vdCA9IHV0aWxzLmZsYWcodGhpcywgXCJuZWdhdGVcIik7XG5cdFx0Y29uc3QgbXNnID0gdXRpbHMuZ2V0TWVzc2FnZSh0aGlzLCBbXG5cdFx0XHRwYXNzLFxuXHRcdFx0YGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIGJlIGNhbGxlZCBvbmNlIHdpdGggYXJndW1lbnRzOiAje2V4cH1gLFxuXHRcdFx0YGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIG5vdCBiZSBjYWxsZWQgb25jZSB3aXRoIGFyZ3VtZW50czogI3tleHB9YCxcblx0XHRcdGFyZ3Ncblx0XHRdKTtcblx0XHRpZiAocGFzcyAmJiBpc05vdCB8fCAhcGFzcyAmJiAhaXNOb3QpIHtcblx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihmb3JtYXRDYWxscyhzcHksIG1zZywgYXJncykpO1xuXHRcdH1cblx0fSk7XG5cdGRlZihcInRvSGF2ZUJlZW5OdGhDYWxsZWRXaXRoXCIsIGZ1bmN0aW9uKHRpbWVzLCAuLi5hcmdzKSB7XG5cdFx0Y29uc3Qgc3B5ID0gZ2V0U3B5KHRoaXMpO1xuXHRcdGNvbnN0IHNweU5hbWUgPSBzcHkuZ2V0TW9ja05hbWUoKTtcblx0XHRjb25zdCBudGhDYWxsID0gc3B5Lm1vY2suY2FsbHNbdGltZXMgLSAxXTtcblx0XHRjb25zdCBjYWxsQ291bnQgPSBzcHkubW9jay5jYWxscy5sZW5ndGg7XG5cdFx0Y29uc3QgaXNDYWxsZWQgPSB0aW1lcyA8PSBjYWxsQ291bnQ7XG5cdFx0dGhpcy5hc3NlcnQobnRoQ2FsbCAmJiBlcXVhbHNBcmd1bWVudEFycmF5KG50aENhbGwsIGFyZ3MpLCBgZXhwZWN0ZWQgJHtvcmRpbmFsKHRpbWVzKX0gXCIke3NweU5hbWV9XCIgY2FsbCB0byBoYXZlIGJlZW4gY2FsbGVkIHdpdGggI3tleHB9JHtpc0NhbGxlZCA/IGBgIDogYCwgYnV0IGNhbGxlZCBvbmx5ICR7Y2FsbENvdW50fSB0aW1lc2B9YCwgYGV4cGVjdGVkICR7b3JkaW5hbCh0aW1lcyl9IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gbm90IGhhdmUgYmVlbiBjYWxsZWQgd2l0aCAje2V4cH1gLCBhcmdzLCBudGhDYWxsLCBpc0NhbGxlZCk7XG5cdH0pO1xuXHRkZWYoXCJ0b0hhdmVCZWVuTGFzdENhbGxlZFdpdGhcIiwgZnVuY3Rpb24oLi4uYXJncykge1xuXHRcdGNvbnN0IHNweSA9IGdldFNweSh0aGlzKTtcblx0XHRjb25zdCBzcHlOYW1lID0gc3B5LmdldE1vY2tOYW1lKCk7XG5cdFx0Y29uc3QgbGFzdENhbGwgPSBzcHkubW9jay5jYWxscy5hdCgtMSk7XG5cdFx0dGhpcy5hc3NlcnQobGFzdENhbGwgJiYgZXF1YWxzQXJndW1lbnRBcnJheShsYXN0Q2FsbCwgYXJncyksIGBleHBlY3RlZCBsYXN0IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gaGF2ZSBiZWVuIGNhbGxlZCB3aXRoICN7ZXhwfWAsIGBleHBlY3RlZCBsYXN0IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gbm90IGhhdmUgYmVlbiBjYWxsZWQgd2l0aCAje2V4cH1gLCBhcmdzLCBsYXN0Q2FsbCk7XG5cdH0pO1xuXHQvKipcblx0KiBVc2VkIGZvciBgdG9IYXZlQmVlbkNhbGxlZEJlZm9yZWAgYW5kIGB0b0hhdmVCZWVuQ2FsbGVkQWZ0ZXJgIHRvIGRldGVybWluZSBpZiB0aGUgZXhwZWN0ZWQgc3B5IHdhcyBjYWxsZWQgYmVmb3JlIHRoZSByZXN1bHQgc3B5LlxuXHQqL1xuXHRmdW5jdGlvbiBpc1NweUNhbGxlZEJlZm9yZUFub3RoZXJTcHkoYmVmb3JlU3B5LCBhZnRlclNweSwgZmFpbElmTm9GaXJzdEludm9jYXRpb24pIHtcblx0XHRjb25zdCBiZWZvcmVJbnZvY2F0aW9uQ2FsbE9yZGVyID0gYmVmb3JlU3B5Lm1vY2suaW52b2NhdGlvbkNhbGxPcmRlcjtcblx0XHRjb25zdCBhZnRlckludm9jYXRpb25DYWxsT3JkZXIgPSBhZnRlclNweS5tb2NrLmludm9jYXRpb25DYWxsT3JkZXI7XG5cdFx0aWYgKGJlZm9yZUludm9jYXRpb25DYWxsT3JkZXIubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRyZXR1cm4gIWZhaWxJZk5vRmlyc3RJbnZvY2F0aW9uO1xuXHRcdH1cblx0XHRpZiAoYWZ0ZXJJbnZvY2F0aW9uQ2FsbE9yZGVyLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRyZXR1cm4gYmVmb3JlSW52b2NhdGlvbkNhbGxPcmRlclswXSA8IGFmdGVySW52b2NhdGlvbkNhbGxPcmRlclswXTtcblx0fVxuXHRkZWYoW1widG9IYXZlQmVlbkNhbGxlZEJlZm9yZVwiXSwgZnVuY3Rpb24ocmVzdWx0U3B5LCBmYWlsSWZOb0ZpcnN0SW52b2NhdGlvbiA9IHRydWUpIHtcblx0XHRjb25zdCBleHBlY3RTcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0aWYgKCFpc01vY2tGdW5jdGlvbihyZXN1bHRTcHkpKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKGAke3V0aWxzLmluc3BlY3QocmVzdWx0U3B5KX0gaXMgbm90IGEgc3B5IG9yIGEgY2FsbCB0byBhIHNweWApO1xuXHRcdH1cblx0XHR0aGlzLmFzc2VydChpc1NweUNhbGxlZEJlZm9yZUFub3RoZXJTcHkoZXhwZWN0U3B5LCByZXN1bHRTcHksIGZhaWxJZk5vRmlyc3RJbnZvY2F0aW9uKSwgYGV4cGVjdGVkIFwiJHtleHBlY3RTcHkuZ2V0TW9ja05hbWUoKX1cIiB0byBoYXZlIGJlZW4gY2FsbGVkIGJlZm9yZSBcIiR7cmVzdWx0U3B5LmdldE1vY2tOYW1lKCl9XCJgLCBgZXhwZWN0ZWQgXCIke2V4cGVjdFNweS5nZXRNb2NrTmFtZSgpfVwiIHRvIG5vdCBoYXZlIGJlZW4gY2FsbGVkIGJlZm9yZSBcIiR7cmVzdWx0U3B5LmdldE1vY2tOYW1lKCl9XCJgLCByZXN1bHRTcHksIGV4cGVjdFNweSk7XG5cdH0pO1xuXHRkZWYoW1widG9IYXZlQmVlbkNhbGxlZEFmdGVyXCJdLCBmdW5jdGlvbihyZXN1bHRTcHksIGZhaWxJZk5vRmlyc3RJbnZvY2F0aW9uID0gdHJ1ZSkge1xuXHRcdGNvbnN0IGV4cGVjdFNweSA9IGdldFNweSh0aGlzKTtcblx0XHRpZiAoIWlzTW9ja0Z1bmN0aW9uKHJlc3VsdFNweSkpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYCR7dXRpbHMuaW5zcGVjdChyZXN1bHRTcHkpfSBpcyBub3QgYSBzcHkgb3IgYSBjYWxsIHRvIGEgc3B5YCk7XG5cdFx0fVxuXHRcdHRoaXMuYXNzZXJ0KGlzU3B5Q2FsbGVkQmVmb3JlQW5vdGhlclNweShyZXN1bHRTcHksIGV4cGVjdFNweSwgZmFpbElmTm9GaXJzdEludm9jYXRpb24pLCBgZXhwZWN0ZWQgXCIke2V4cGVjdFNweS5nZXRNb2NrTmFtZSgpfVwiIHRvIGhhdmUgYmVlbiBjYWxsZWQgYWZ0ZXIgXCIke3Jlc3VsdFNweS5nZXRNb2NrTmFtZSgpfVwiYCwgYGV4cGVjdGVkIFwiJHtleHBlY3RTcHkuZ2V0TW9ja05hbWUoKX1cIiB0byBub3QgaGF2ZSBiZWVuIGNhbGxlZCBhZnRlciBcIiR7cmVzdWx0U3B5LmdldE1vY2tOYW1lKCl9XCJgLCByZXN1bHRTcHksIGV4cGVjdFNweSk7XG5cdH0pO1xuXHRkZWYoW1widG9UaHJvd1wiLCBcInRvVGhyb3dFcnJvclwiXSwgZnVuY3Rpb24oZXhwZWN0ZWQpIHtcblx0XHRpZiAodHlwZW9mIGV4cGVjdGVkID09PSBcInN0cmluZ1wiIHx8IHR5cGVvZiBleHBlY3RlZCA9PT0gXCJ1bmRlZmluZWRcIiB8fCBleHBlY3RlZCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuXHRcdFx0Ly8gRml4ZXMgdGhlIGlzc3VlIHJlbGF0ZWQgdG8gYGNoYWlgIDxodHRwczovL2dpdGh1Yi5jb20vdml0ZXN0LWRldi92aXRlc3QvaXNzdWVzLzY2MTg+XG5cdFx0XHRyZXR1cm4gdGhpcy50aHJvd3MoZXhwZWN0ZWQgPT09IFwiXCIgPyAvXiQvIDogZXhwZWN0ZWQpO1xuXHRcdH1cblx0XHRjb25zdCBvYmogPSB0aGlzLl9vYmo7XG5cdFx0Y29uc3QgcHJvbWlzZSA9IHV0aWxzLmZsYWcodGhpcywgXCJwcm9taXNlXCIpO1xuXHRcdGNvbnN0IGlzTm90ID0gdXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKTtcblx0XHRsZXQgdGhyb3duID0gbnVsbDtcblx0XHRpZiAocHJvbWlzZSA9PT0gXCJyZWplY3RzXCIpIHtcblx0XHRcdHRocm93biA9IG9iajtcblx0XHR9IGVsc2UgaWYgKHByb21pc2UgPT09IFwicmVzb2x2ZXNcIiAmJiB0eXBlb2Ygb2JqICE9PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdGlmICghaXNOb3QpIHtcblx0XHRcdFx0Y29uc3QgbWVzc2FnZSA9IHV0aWxzLmZsYWcodGhpcywgXCJtZXNzYWdlXCIpIHx8IFwiZXhwZWN0ZWQgcHJvbWlzZSB0byB0aHJvdyBhbiBlcnJvciwgYnV0IGl0IGRpZG4ndFwiO1xuXHRcdFx0XHRjb25zdCBlcnJvciA9IHsgc2hvd0RpZmY6IGZhbHNlIH07XG5cdFx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtZXNzYWdlLCBlcnJvciwgdXRpbHMuZmxhZyh0aGlzLCBcInNzZmlcIikpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRsZXQgaXNUaHJvdyA9IGZhbHNlO1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0b2JqKCk7XG5cdFx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdFx0aXNUaHJvdyA9IHRydWU7XG5cdFx0XHRcdHRocm93biA9IGVycjtcblx0XHRcdH1cblx0XHRcdGlmICghaXNUaHJvdyAmJiAhaXNOb3QpIHtcblx0XHRcdFx0Y29uc3QgbWVzc2FnZSA9IHV0aWxzLmZsYWcodGhpcywgXCJtZXNzYWdlXCIpIHx8IFwiZXhwZWN0ZWQgZnVuY3Rpb24gdG8gdGhyb3cgYW4gZXJyb3IsIGJ1dCBpdCBkaWRuJ3RcIjtcblx0XHRcdFx0Y29uc3QgZXJyb3IgPSB7IHNob3dEaWZmOiBmYWxzZSB9O1xuXHRcdFx0XHR0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobWVzc2FnZSwgZXJyb3IsIHV0aWxzLmZsYWcodGhpcywgXCJzc2ZpXCIpKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBleHBlY3RlZCA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHRjb25zdCBuYW1lID0gZXhwZWN0ZWQubmFtZSB8fCBleHBlY3RlZC5wcm90b3R5cGUuY29uc3RydWN0b3IubmFtZTtcblx0XHRcdHJldHVybiB0aGlzLmFzc2VydCh0aHJvd24gJiYgdGhyb3duIGluc3RhbmNlb2YgZXhwZWN0ZWQsIGBleHBlY3RlZCBlcnJvciB0byBiZSBpbnN0YW5jZSBvZiAke25hbWV9YCwgYGV4cGVjdGVkIGVycm9yIG5vdCB0byBiZSBpbnN0YW5jZSBvZiAke25hbWV9YCwgZXhwZWN0ZWQsIHRocm93bik7XG5cdFx0fVxuXHRcdGlmIChpc0Vycm9yKGV4cGVjdGVkKSkge1xuXHRcdFx0Y29uc3QgZXF1YWwgPSBlcXVhbHModGhyb3duLCBleHBlY3RlZCwgWy4uLmN1c3RvbVRlc3RlcnMsIGl0ZXJhYmxlRXF1YWxpdHldKTtcblx0XHRcdHJldHVybiB0aGlzLmFzc2VydChlcXVhbCwgXCJleHBlY3RlZCBhIHRocm93biBlcnJvciB0byBiZSAje2V4cH1cIiwgXCJleHBlY3RlZCBhIHRocm93biBlcnJvciBub3QgdG8gYmUgI3tleHB9XCIsIGV4cGVjdGVkLCB0aHJvd24pO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIGV4cGVjdGVkID09PSBcIm9iamVjdFwiICYmIFwiYXN5bW1ldHJpY01hdGNoXCIgaW4gZXhwZWN0ZWQgJiYgdHlwZW9mIGV4cGVjdGVkLmFzeW1tZXRyaWNNYXRjaCA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHRjb25zdCBtYXRjaGVyID0gZXhwZWN0ZWQ7XG5cdFx0XHRyZXR1cm4gdGhpcy5hc3NlcnQodGhyb3duICYmIG1hdGNoZXIuYXN5bW1ldHJpY01hdGNoKHRocm93biksIFwiZXhwZWN0ZWQgZXJyb3IgdG8gbWF0Y2ggYXN5bW1ldHJpYyBtYXRjaGVyXCIsIFwiZXhwZWN0ZWQgZXJyb3Igbm90IHRvIG1hdGNoIGFzeW1tZXRyaWMgbWF0Y2hlclwiLCBtYXRjaGVyLCB0aHJvd24pO1xuXHRcdH1cblx0XHRjb25zdCBlcXVhbCA9IGVxdWFscyh0aHJvd24sIGV4cGVjdGVkLCBbLi4uY3VzdG9tVGVzdGVycywgaXRlcmFibGVFcXVhbGl0eV0pO1xuXHRcdHJldHVybiB0aGlzLmFzc2VydChlcXVhbCwgXCJleHBlY3RlZCBhIHRocm93biB2YWx1ZSB0byBlcXVhbCAje2V4cH1cIiwgXCJleHBlY3RlZCBhIHRocm93biB2YWx1ZSBub3QgdG8gZXF1YWwgI3tleHB9XCIsIGV4cGVjdGVkLCB0aHJvd24pO1xuXHR9KTtcblx0W3tcblx0XHRuYW1lOiBcInRvSGF2ZVJlc29sdmVkXCIsXG5cdFx0Y29uZGl0aW9uOiAoc3B5KSA9PiBzcHkubW9jay5zZXR0bGVkUmVzdWx0cy5sZW5ndGggPiAwICYmIHNweS5tb2NrLnNldHRsZWRSZXN1bHRzLnNvbWUoKHsgdHlwZSB9KSA9PiB0eXBlID09PSBcImZ1bGZpbGxlZFwiKSxcblx0XHRhY3Rpb246IFwicmVzb2x2ZWRcIlxuXHR9LCB7XG5cdFx0bmFtZTogW1widG9IYXZlUmV0dXJuZWRcIiwgXCJ0b1JldHVyblwiXSxcblx0XHRjb25kaXRpb246IChzcHkpID0+IHNweS5tb2NrLmNhbGxzLmxlbmd0aCA+IDAgJiYgc3B5Lm1vY2sucmVzdWx0cy5zb21lKCh7IHR5cGUgfSkgPT4gdHlwZSAhPT0gXCJ0aHJvd1wiKSxcblx0XHRhY3Rpb246IFwiY2FsbGVkXCJcblx0fV0uZm9yRWFjaCgoeyBuYW1lLCBjb25kaXRpb24sIGFjdGlvbiB9KSA9PiB7XG5cdFx0ZGVmKG5hbWUsIGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29uc3Qgc3B5ID0gZ2V0U3B5KHRoaXMpO1xuXHRcdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdFx0Y29uc3QgcGFzcyA9IGNvbmRpdGlvbihzcHkpO1xuXHRcdFx0dGhpcy5hc3NlcnQocGFzcywgYGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIGJlIHN1Y2Nlc3NmdWxseSAke2FjdGlvbn0gYXQgbGVhc3Qgb25jZWAsIGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byBub3QgYmUgc3VjY2Vzc2Z1bGx5ICR7YWN0aW9ufWAsIHBhc3MsICFwYXNzLCBmYWxzZSk7XG5cdFx0fSk7XG5cdH0pO1xuXHRbe1xuXHRcdG5hbWU6IFwidG9IYXZlUmVzb2x2ZWRUaW1lc1wiLFxuXHRcdGNvbmRpdGlvbjogKHNweSwgdGltZXMpID0+IHNweS5tb2NrLnNldHRsZWRSZXN1bHRzLnJlZHVjZSgocywgeyB0eXBlIH0pID0+IHR5cGUgPT09IFwiZnVsZmlsbGVkXCIgPyArK3MgOiBzLCAwKSA9PT0gdGltZXMsXG5cdFx0YWN0aW9uOiBcInJlc29sdmVkXCJcblx0fSwge1xuXHRcdG5hbWU6IFtcInRvSGF2ZVJldHVybmVkVGltZXNcIiwgXCJ0b1JldHVyblRpbWVzXCJdLFxuXHRcdGNvbmRpdGlvbjogKHNweSwgdGltZXMpID0+IHNweS5tb2NrLnJlc3VsdHMucmVkdWNlKChzLCB7IHR5cGUgfSkgPT4gdHlwZSA9PT0gXCJ0aHJvd1wiID8gcyA6ICsrcywgMCkgPT09IHRpbWVzLFxuXHRcdGFjdGlvbjogXCJjYWxsZWRcIlxuXHR9XS5mb3JFYWNoKCh7IG5hbWUsIGNvbmRpdGlvbiwgYWN0aW9uIH0pID0+IHtcblx0XHRkZWYobmFtZSwgZnVuY3Rpb24odGltZXMpIHtcblx0XHRcdGNvbnN0IHNweSA9IGdldFNweSh0aGlzKTtcblx0XHRcdGNvbnN0IHNweU5hbWUgPSBzcHkuZ2V0TW9ja05hbWUoKTtcblx0XHRcdGNvbnN0IHBhc3MgPSBjb25kaXRpb24oc3B5LCB0aW1lcyk7XG5cdFx0XHR0aGlzLmFzc2VydChwYXNzLCBgZXhwZWN0ZWQgXCIke3NweU5hbWV9XCIgdG8gYmUgc3VjY2Vzc2Z1bGx5ICR7YWN0aW9ufSAke3RpbWVzfSB0aW1lc2AsIGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byBub3QgYmUgc3VjY2Vzc2Z1bGx5ICR7YWN0aW9ufSAke3RpbWVzfSB0aW1lc2AsIGBleHBlY3RlZCByZXNvbHZlZCB0aW1lczogJHt0aW1lc31gLCBgcmVjZWl2ZWQgcmVzb2x2ZWQgdGltZXM6ICR7cGFzc31gLCBmYWxzZSk7XG5cdFx0fSk7XG5cdH0pO1xuXHRbe1xuXHRcdG5hbWU6IFwidG9IYXZlUmVzb2x2ZWRXaXRoXCIsXG5cdFx0Y29uZGl0aW9uOiAoc3B5LCB2YWx1ZSkgPT4gc3B5Lm1vY2suc2V0dGxlZFJlc3VsdHMuc29tZSgoeyB0eXBlLCB2YWx1ZTogcmVzdWx0IH0pID0+IHR5cGUgPT09IFwiZnVsZmlsbGVkXCIgJiYgZXF1YWxzKHZhbHVlLCByZXN1bHQpKSxcblx0XHRhY3Rpb246IFwicmVzb2x2ZVwiXG5cdH0sIHtcblx0XHRuYW1lOiBbXCJ0b0hhdmVSZXR1cm5lZFdpdGhcIiwgXCJ0b1JldHVybldpdGhcIl0sXG5cdFx0Y29uZGl0aW9uOiAoc3B5LCB2YWx1ZSkgPT4gc3B5Lm1vY2sucmVzdWx0cy5zb21lKCh7IHR5cGUsIHZhbHVlOiByZXN1bHQgfSkgPT4gdHlwZSA9PT0gXCJyZXR1cm5cIiAmJiBlcXVhbHModmFsdWUsIHJlc3VsdCkpLFxuXHRcdGFjdGlvbjogXCJyZXR1cm5cIlxuXHR9XS5mb3JFYWNoKCh7IG5hbWUsIGNvbmRpdGlvbiwgYWN0aW9uIH0pID0+IHtcblx0XHRkZWYobmFtZSwgZnVuY3Rpb24odmFsdWUpIHtcblx0XHRcdGNvbnN0IHNweSA9IGdldFNweSh0aGlzKTtcblx0XHRcdGNvbnN0IHBhc3MgPSBjb25kaXRpb24oc3B5LCB2YWx1ZSk7XG5cdFx0XHRjb25zdCBpc05vdCA9IHV0aWxzLmZsYWcodGhpcywgXCJuZWdhdGVcIik7XG5cdFx0XHRpZiAocGFzcyAmJiBpc05vdCB8fCAhcGFzcyAmJiAhaXNOb3QpIHtcblx0XHRcdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdFx0XHRjb25zdCBtc2cgPSB1dGlscy5nZXRNZXNzYWdlKHRoaXMsIFtcblx0XHRcdFx0XHRwYXNzLFxuXHRcdFx0XHRcdGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byAke2FjdGlvbn0gd2l0aDogI3tleHB9IGF0IGxlYXN0IG9uY2VgLFxuXHRcdFx0XHRcdGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byBub3QgJHthY3Rpb259IHdpdGg6ICN7ZXhwfWAsXG5cdFx0XHRcdFx0dmFsdWVcblx0XHRcdFx0XSk7XG5cdFx0XHRcdGNvbnN0IHJlc3VsdHMgPSBhY3Rpb24gPT09IFwicmV0dXJuXCIgPyBzcHkubW9jay5yZXN1bHRzIDogc3B5Lm1vY2suc2V0dGxlZFJlc3VsdHM7XG5cdFx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihmb3JtYXRSZXR1cm5zKHNweSwgcmVzdWx0cywgbXNnLCB2YWx1ZSkpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9KTtcblx0W3tcblx0XHRuYW1lOiBcInRvSGF2ZUxhc3RSZXNvbHZlZFdpdGhcIixcblx0XHRjb25kaXRpb246IChzcHksIHZhbHVlKSA9PiB7XG5cdFx0XHRjb25zdCByZXN1bHQgPSBzcHkubW9jay5zZXR0bGVkUmVzdWx0cy5hdCgtMSk7XG5cdFx0XHRyZXR1cm4gQm9vbGVhbihyZXN1bHQgJiYgcmVzdWx0LnR5cGUgPT09IFwiZnVsZmlsbGVkXCIgJiYgZXF1YWxzKHJlc3VsdC52YWx1ZSwgdmFsdWUpKTtcblx0XHR9LFxuXHRcdGFjdGlvbjogXCJyZXNvbHZlXCJcblx0fSwge1xuXHRcdG5hbWU6IFwidG9IYXZlTGFzdFJldHVybmVkV2l0aFwiLFxuXHRcdGNvbmRpdGlvbjogKHNweSwgdmFsdWUpID0+IHtcblx0XHRcdGNvbnN0IHJlc3VsdCA9IHNweS5tb2NrLnJlc3VsdHMuYXQoLTEpO1xuXHRcdFx0cmV0dXJuIEJvb2xlYW4ocmVzdWx0ICYmIHJlc3VsdC50eXBlID09PSBcInJldHVyblwiICYmIGVxdWFscyhyZXN1bHQudmFsdWUsIHZhbHVlKSk7XG5cdFx0fSxcblx0XHRhY3Rpb246IFwicmV0dXJuXCJcblx0fV0uZm9yRWFjaCgoeyBuYW1lLCBjb25kaXRpb24sIGFjdGlvbiB9KSA9PiB7XG5cdFx0ZGVmKG5hbWUsIGZ1bmN0aW9uKHZhbHVlKSB7XG5cdFx0XHRjb25zdCBzcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0XHRjb25zdCByZXN1bHRzID0gYWN0aW9uID09PSBcInJldHVyblwiID8gc3B5Lm1vY2sucmVzdWx0cyA6IHNweS5tb2NrLnNldHRsZWRSZXN1bHRzO1xuXHRcdFx0Y29uc3QgcmVzdWx0ID0gcmVzdWx0cy5hdCgtMSk7XG5cdFx0XHRjb25zdCBzcHlOYW1lID0gc3B5LmdldE1vY2tOYW1lKCk7XG5cdFx0XHR0aGlzLmFzc2VydChjb25kaXRpb24oc3B5LCB2YWx1ZSksIGBleHBlY3RlZCBsYXN0IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gJHthY3Rpb259ICN7ZXhwfWAsIGBleHBlY3RlZCBsYXN0IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gbm90ICR7YWN0aW9ufSAje2V4cH1gLCB2YWx1ZSwgcmVzdWx0Py52YWx1ZSk7XG5cdFx0fSk7XG5cdH0pO1xuXHRbe1xuXHRcdG5hbWU6IFwidG9IYXZlTnRoUmVzb2x2ZWRXaXRoXCIsXG5cdFx0Y29uZGl0aW9uOiAoc3B5LCBpbmRleCwgdmFsdWUpID0+IHtcblx0XHRcdGNvbnN0IHJlc3VsdCA9IHNweS5tb2NrLnNldHRsZWRSZXN1bHRzW2luZGV4IC0gMV07XG5cdFx0XHRyZXR1cm4gcmVzdWx0ICYmIHJlc3VsdC50eXBlID09PSBcImZ1bGZpbGxlZFwiICYmIGVxdWFscyhyZXN1bHQudmFsdWUsIHZhbHVlKTtcblx0XHR9LFxuXHRcdGFjdGlvbjogXCJyZXNvbHZlXCJcblx0fSwge1xuXHRcdG5hbWU6IFwidG9IYXZlTnRoUmV0dXJuZWRXaXRoXCIsXG5cdFx0Y29uZGl0aW9uOiAoc3B5LCBpbmRleCwgdmFsdWUpID0+IHtcblx0XHRcdGNvbnN0IHJlc3VsdCA9IHNweS5tb2NrLnJlc3VsdHNbaW5kZXggLSAxXTtcblx0XHRcdHJldHVybiByZXN1bHQgJiYgcmVzdWx0LnR5cGUgPT09IFwicmV0dXJuXCIgJiYgZXF1YWxzKHJlc3VsdC52YWx1ZSwgdmFsdWUpO1xuXHRcdH0sXG5cdFx0YWN0aW9uOiBcInJldHVyblwiXG5cdH1dLmZvckVhY2goKHsgbmFtZSwgY29uZGl0aW9uLCBhY3Rpb24gfSkgPT4ge1xuXHRcdGRlZihuYW1lLCBmdW5jdGlvbihudGhDYWxsLCB2YWx1ZSkge1xuXHRcdFx0Y29uc3Qgc3B5ID0gZ2V0U3B5KHRoaXMpO1xuXHRcdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdFx0Y29uc3QgcmVzdWx0cyA9IGFjdGlvbiA9PT0gXCJyZXR1cm5cIiA/IHNweS5tb2NrLnJlc3VsdHMgOiBzcHkubW9jay5zZXR0bGVkUmVzdWx0cztcblx0XHRcdGNvbnN0IHJlc3VsdCA9IHJlc3VsdHNbbnRoQ2FsbCAtIDFdO1xuXHRcdFx0Y29uc3Qgb3JkaW5hbENhbGwgPSBgJHtvcmRpbmFsKG50aENhbGwpfSBjYWxsYDtcblx0XHRcdHRoaXMuYXNzZXJ0KGNvbmRpdGlvbihzcHksIG50aENhbGwsIHZhbHVlKSwgYGV4cGVjdGVkICR7b3JkaW5hbENhbGx9IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gJHthY3Rpb259ICN7ZXhwfWAsIGBleHBlY3RlZCAke29yZGluYWxDYWxsfSBcIiR7c3B5TmFtZX1cIiBjYWxsIHRvIG5vdCAke2FjdGlvbn0gI3tleHB9YCwgdmFsdWUsIHJlc3VsdD8udmFsdWUpO1xuXHRcdH0pO1xuXHR9KTtcblx0Ly8gQHRzLWV4cGVjdC1lcnJvciBAaW50ZXJuYWxcblx0ZGVmKFwid2l0aENvbnRleHRcIiwgZnVuY3Rpb24oY29udGV4dCkge1xuXHRcdGZvciAoY29uc3Qga2V5IGluIGNvbnRleHQpIHtcblx0XHRcdHV0aWxzLmZsYWcodGhpcywga2V5LCBjb250ZXh0W2tleV0pO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fSk7XG5cdHV0aWxzLmFkZFByb3BlcnR5KGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgXCJyZXNvbHZlc1wiLCBmdW5jdGlvbiBfX1ZJVEVTVF9SRVNPTFZFU19fKCkge1xuXHRcdGNvbnN0IGVycm9yID0gbmV3IEVycm9yKFwicmVzb2x2ZXNcIik7XG5cdFx0dXRpbHMuZmxhZyh0aGlzLCBcInByb21pc2VcIiwgXCJyZXNvbHZlc1wiKTtcblx0XHR1dGlscy5mbGFnKHRoaXMsIFwiZXJyb3JcIiwgZXJyb3IpO1xuXHRcdGNvbnN0IHRlc3QgPSB1dGlscy5mbGFnKHRoaXMsIFwidml0ZXN0LXRlc3RcIik7XG5cdFx0Y29uc3Qgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKTtcblx0XHRpZiAodXRpbHMuZmxhZyh0aGlzLCBcInBvbGxcIikpIHtcblx0XHRcdHRocm93IG5ldyBTeW50YXhFcnJvcihgZXhwZWN0LnBvbGwoKSBpcyBub3Qgc3VwcG9ydGVkIGluIGNvbWJpbmF0aW9uIHdpdGggLnJlc29sdmVzYCk7XG5cdFx0fVxuXHRcdGlmICh0eXBlb2Ygb2JqPy50aGVuICE9PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYFlvdSBtdXN0IHByb3ZpZGUgYSBQcm9taXNlIHRvIGV4cGVjdCgpIHdoZW4gdXNpbmcgLnJlc29sdmVzLCBub3QgJyR7dHlwZW9mIG9ian0nLmApO1xuXHRcdH1cblx0XHRjb25zdCBwcm94eSA9IG5ldyBQcm94eSh0aGlzLCB7IGdldDogKHRhcmdldCwga2V5LCByZWNlaXZlcikgPT4ge1xuXHRcdFx0Y29uc3QgcmVzdWx0ID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBrZXksIHJlY2VpdmVyKTtcblx0XHRcdGlmICh0eXBlb2YgcmVzdWx0ICE9PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdFx0cmV0dXJuIHJlc3VsdCBpbnN0YW5jZW9mIGNoYWkuQXNzZXJ0aW9uID8gcHJveHkgOiByZXN1bHQ7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gKC4uLmFyZ3MpID0+IHtcblx0XHRcdFx0dXRpbHMuZmxhZyh0aGlzLCBcIl9uYW1lXCIsIGtleSk7XG5cdFx0XHRcdGNvbnN0IHByb21pc2UgPSBQcm9taXNlLnJlc29sdmUob2JqKS50aGVuKCh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIiwgdmFsdWUpO1xuXHRcdFx0XHRcdHJldHVybiByZXN1bHQuY2FsbCh0aGlzLCAuLi5hcmdzKTtcblx0XHRcdFx0fSwgKGVycikgPT4ge1xuXHRcdFx0XHRcdGNvbnN0IF9lcnJvciA9IG5ldyBBc3NlcnRpb25FcnJvcihgcHJvbWlzZSByZWplY3RlZCBcIiR7dXRpbHMuaW5zcGVjdChlcnIpfVwiIGluc3RlYWQgb2YgcmVzb2x2aW5nYCwgeyBzaG93RGlmZjogZmFsc2UgfSk7XG5cdFx0XHRcdFx0X2Vycm9yLmNhdXNlID0gZXJyO1xuXHRcdFx0XHRcdHRocm93IF9lcnJvcjtcblx0XHRcdFx0fSkuY2F0Y2goKGVycikgPT4ge1xuXHRcdFx0XHRcdGlmIChpc0Vycm9yKGVycikgJiYgZXJyb3Iuc3RhY2spIHtcblx0XHRcdFx0XHRcdGVyci5zdGFjayA9IGVycm9yLnN0YWNrLnJlcGxhY2UoZXJyb3IubWVzc2FnZSwgZXJyLm1lc3NhZ2UpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR0aHJvdyBlcnI7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRyZXR1cm4gcmVjb3JkQXN5bmNFeHBlY3QodGVzdCwgcHJvbWlzZSwgY3JlYXRlQXNzZXJ0aW9uTWVzc2FnZSh1dGlscywgdGhpcywgISFhcmdzLmxlbmd0aCksIGVycm9yLCB1dGlscy5mbGFnKHRoaXMsIFwic29mdFwiKSk7XG5cdFx0XHR9O1xuXHRcdH0gfSk7XG5cdFx0cmV0dXJuIHByb3h5O1xuXHR9KTtcblx0dXRpbHMuYWRkUHJvcGVydHkoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCBcInJlamVjdHNcIiwgZnVuY3Rpb24gX19WSVRFU1RfUkVKRUNUU19fKCkge1xuXHRcdGNvbnN0IGVycm9yID0gbmV3IEVycm9yKFwicmVqZWN0c1wiKTtcblx0XHR1dGlscy5mbGFnKHRoaXMsIFwicHJvbWlzZVwiLCBcInJlamVjdHNcIik7XG5cdFx0dXRpbHMuZmxhZyh0aGlzLCBcImVycm9yXCIsIGVycm9yKTtcblx0XHRjb25zdCB0ZXN0ID0gdXRpbHMuZmxhZyh0aGlzLCBcInZpdGVzdC10ZXN0XCIpO1xuXHRcdGNvbnN0IG9iaiA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0Y29uc3Qgd3JhcHBlciA9IHR5cGVvZiBvYmogPT09IFwiZnVuY3Rpb25cIiA/IG9iaigpIDogb2JqO1xuXHRcdGlmICh1dGlscy5mbGFnKHRoaXMsIFwicG9sbFwiKSkge1xuXHRcdFx0dGhyb3cgbmV3IFN5bnRheEVycm9yKGBleHBlY3QucG9sbCgpIGlzIG5vdCBzdXBwb3J0ZWQgaW4gY29tYmluYXRpb24gd2l0aCAucmVqZWN0c2ApO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHdyYXBwZXI/LnRoZW4gIT09IFwiZnVuY3Rpb25cIikge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihgWW91IG11c3QgcHJvdmlkZSBhIFByb21pc2UgdG8gZXhwZWN0KCkgd2hlbiB1c2luZyAucmVqZWN0cywgbm90ICcke3R5cGVvZiB3cmFwcGVyfScuYCk7XG5cdFx0fVxuXHRcdGNvbnN0IHByb3h5ID0gbmV3IFByb3h5KHRoaXMsIHsgZ2V0OiAodGFyZ2V0LCBrZXksIHJlY2VpdmVyKSA9PiB7XG5cdFx0XHRjb25zdCByZXN1bHQgPSBSZWZsZWN0LmdldCh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpO1xuXHRcdFx0aWYgKHR5cGVvZiByZXN1bHQgIT09IFwiZnVuY3Rpb25cIikge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0IGluc3RhbmNlb2YgY2hhaS5Bc3NlcnRpb24gPyBwcm94eSA6IHJlc3VsdDtcblx0XHRcdH1cblx0XHRcdHJldHVybiAoLi4uYXJncykgPT4ge1xuXHRcdFx0XHR1dGlscy5mbGFnKHRoaXMsIFwiX25hbWVcIiwga2V5KTtcblx0XHRcdFx0Y29uc3QgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSh3cmFwcGVyKS50aGVuKCh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdGNvbnN0IF9lcnJvciA9IG5ldyBBc3NlcnRpb25FcnJvcihgcHJvbWlzZSByZXNvbHZlZCBcIiR7dXRpbHMuaW5zcGVjdCh2YWx1ZSl9XCIgaW5zdGVhZCBvZiByZWplY3RpbmdgLCB7XG5cdFx0XHRcdFx0XHRzaG93RGlmZjogdHJ1ZSxcblx0XHRcdFx0XHRcdGV4cGVjdGVkOiBuZXcgRXJyb3IoXCJyZWplY3RlZCBwcm9taXNlXCIpLFxuXHRcdFx0XHRcdFx0YWN0dWFsOiB2YWx1ZVxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdHRocm93IF9lcnJvcjtcblx0XHRcdFx0fSwgKGVycikgPT4ge1xuXHRcdFx0XHRcdHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIiwgZXJyKTtcblx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0LmNhbGwodGhpcywgLi4uYXJncyk7XG5cdFx0XHRcdH0pLmNhdGNoKChlcnIpID0+IHtcblx0XHRcdFx0XHRpZiAoaXNFcnJvcihlcnIpICYmIGVycm9yLnN0YWNrKSB7XG5cdFx0XHRcdFx0XHRlcnIuc3RhY2sgPSBlcnJvci5zdGFjay5yZXBsYWNlKGVycm9yLm1lc3NhZ2UsIGVyci5tZXNzYWdlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0dGhyb3cgZXJyO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0cmV0dXJuIHJlY29yZEFzeW5jRXhwZWN0KHRlc3QsIHByb21pc2UsIGNyZWF0ZUFzc2VydGlvbk1lc3NhZ2UodXRpbHMsIHRoaXMsICEhYXJncy5sZW5ndGgpLCBlcnJvciwgdXRpbHMuZmxhZyh0aGlzLCBcInNvZnRcIikpO1xuXHRcdFx0fTtcblx0XHR9IH0pO1xuXHRcdHJldHVybiBwcm94eTtcblx0fSk7XG59O1xuZnVuY3Rpb24gZm9ybWF0Q2FsbHMoc3B5LCBtc2csIHNob3dBY3R1YWxDYWxsKSB7XG5cdGlmIChzcHkubW9jay5jYWxscy5sZW5ndGgpIHtcblx0XHRtc2cgKz0gYy5ncmF5KGBcXG5cXG5SZWNlaXZlZDpcXG5cXG4ke3NweS5tb2NrLmNhbGxzLm1hcCgoY2FsbEFyZywgaSkgPT4ge1xuXHRcdFx0bGV0IG1ldGhvZENhbGwgPSBjLmJvbGQoYCAgJHtvcmRpbmFsKGkgKyAxKX0gJHtzcHkuZ2V0TW9ja05hbWUoKX0gY2FsbDpcXG5cXG5gKTtcblx0XHRcdGlmIChzaG93QWN0dWFsQ2FsbCkge1xuXHRcdFx0XHRtZXRob2RDYWxsICs9IGRpZmYoc2hvd0FjdHVhbENhbGwsIGNhbGxBcmcsIHsgb21pdEFubm90YXRpb25MaW5lczogdHJ1ZSB9KTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG1ldGhvZENhbGwgKz0gc3RyaW5naWZ5KGNhbGxBcmcpLnNwbGl0KFwiXFxuXCIpLm1hcCgobGluZSkgPT4gYCAgICAke2xpbmV9YCkuam9pbihcIlxcblwiKTtcblx0XHRcdH1cblx0XHRcdG1ldGhvZENhbGwgKz0gXCJcXG5cIjtcblx0XHRcdHJldHVybiBtZXRob2RDYWxsO1xuXHRcdH0pLmpvaW4oXCJcXG5cIil9YCk7XG5cdH1cblx0bXNnICs9IGMuZ3JheShgXFxuXFxuTnVtYmVyIG9mIGNhbGxzOiAke2MuYm9sZChzcHkubW9jay5jYWxscy5sZW5ndGgpfVxcbmApO1xuXHRyZXR1cm4gbXNnO1xufVxuZnVuY3Rpb24gZm9ybWF0UmV0dXJucyhzcHksIHJlc3VsdHMsIG1zZywgc2hvd0FjdHVhbFJldHVybikge1xuXHRpZiAocmVzdWx0cy5sZW5ndGgpIHtcblx0XHRtc2cgKz0gYy5ncmF5KGBcXG5cXG5SZWNlaXZlZDpcXG5cXG4ke3Jlc3VsdHMubWFwKChjYWxsUmV0dXJuLCBpKSA9PiB7XG5cdFx0XHRsZXQgbWV0aG9kQ2FsbCA9IGMuYm9sZChgICAke29yZGluYWwoaSArIDEpfSAke3NweS5nZXRNb2NrTmFtZSgpfSBjYWxsIHJldHVybjpcXG5cXG5gKTtcblx0XHRcdGlmIChzaG93QWN0dWFsUmV0dXJuKSB7XG5cdFx0XHRcdG1ldGhvZENhbGwgKz0gZGlmZihzaG93QWN0dWFsUmV0dXJuLCBjYWxsUmV0dXJuLnZhbHVlLCB7IG9taXRBbm5vdGF0aW9uTGluZXM6IHRydWUgfSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRtZXRob2RDYWxsICs9IHN0cmluZ2lmeShjYWxsUmV0dXJuKS5zcGxpdChcIlxcblwiKS5tYXAoKGxpbmUpID0+IGAgICAgJHtsaW5lfWApLmpvaW4oXCJcXG5cIik7XG5cdFx0XHR9XG5cdFx0XHRtZXRob2RDYWxsICs9IFwiXFxuXCI7XG5cdFx0XHRyZXR1cm4gbWV0aG9kQ2FsbDtcblx0XHR9KS5qb2luKFwiXFxuXCIpfWApO1xuXHR9XG5cdG1zZyArPSBjLmdyYXkoYFxcblxcbk51bWJlciBvZiBjYWxsczogJHtjLmJvbGQoc3B5Lm1vY2suY2FsbHMubGVuZ3RoKX1cXG5gKTtcblx0cmV0dXJuIG1zZztcbn1cblxuZnVuY3Rpb24gZ2V0TWF0Y2hlclN0YXRlKGFzc2VydGlvbiwgZXhwZWN0KSB7XG5cdGNvbnN0IG9iaiA9IGFzc2VydGlvbi5fb2JqO1xuXHRjb25zdCBpc05vdCA9IHV0aWwuZmxhZyhhc3NlcnRpb24sIFwibmVnYXRlXCIpO1xuXHRjb25zdCBwcm9taXNlID0gdXRpbC5mbGFnKGFzc2VydGlvbiwgXCJwcm9taXNlXCIpIHx8IFwiXCI7XG5cdGNvbnN0IGN1c3RvbU1lc3NhZ2UgPSB1dGlsLmZsYWcoYXNzZXJ0aW9uLCBcIm1lc3NhZ2VcIik7XG5cdGNvbnN0IGplc3RVdGlscyA9IHtcblx0XHQuLi5nZXRNYXRjaGVyVXRpbHMoKSxcblx0XHRkaWZmLFxuXHRcdHN0cmluZ2lmeSxcblx0XHRpdGVyYWJsZUVxdWFsaXR5LFxuXHRcdHN1YnNldEVxdWFsaXR5XG5cdH07XG5cdGxldCB0YXNrID0gdXRpbC5mbGFnKGFzc2VydGlvbiwgXCJ2aXRlc3QtdGVzdFwiKTtcblx0Y29uc3QgY3VycmVudFRlc3ROYW1lID0gdGFzaz8uZnVsbFRlc3ROYW1lID8/IFwiXCI7XG5cdGlmICh0YXNrPy50eXBlICE9PSBcInRlc3RcIikge1xuXHRcdHRhc2sgPSB1bmRlZmluZWQ7XG5cdH1cblx0Y29uc3QgbWF0Y2hlclN0YXRlID0ge1xuXHRcdC4uLmdldFN0YXRlKGV4cGVjdCksXG5cdFx0Y3VycmVudFRlc3ROYW1lLFxuXHRcdGN1c3RvbVRlc3RlcnM6IGdldEN1c3RvbUVxdWFsaXR5VGVzdGVycygpLFxuXHRcdGlzTm90LFxuXHRcdHV0aWxzOiBqZXN0VXRpbHMsXG5cdFx0cHJvbWlzZSxcblx0XHRlcXVhbHMsXG5cdFx0c3VwcHJlc3NlZEVycm9yczogW10sXG5cdFx0c29mdDogdXRpbC5mbGFnKGFzc2VydGlvbiwgXCJzb2Z0XCIpLFxuXHRcdHBvbGw6IHV0aWwuZmxhZyhhc3NlcnRpb24sIFwicG9sbFwiKSxcblx0XHRhc3NlcnRpb25cblx0fTtcblx0T2JqZWN0LmFzc2lnbihtYXRjaGVyU3RhdGUsIHsgdGFzayB9KTtcblx0cmV0dXJuIHtcblx0XHRzdGF0ZTogbWF0Y2hlclN0YXRlLFxuXHRcdGlzTm90LFxuXHRcdG9iaixcblx0XHRjdXN0b21NZXNzYWdlXG5cdH07XG59XG5jbGFzcyBKZXN0RXh0ZW5kRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG5cdGNvbnN0cnVjdG9yKG1lc3NhZ2UsIGFjdHVhbCwgZXhwZWN0ZWQsIF9fdml0ZXN0X2Vycm9yX2NvbnRleHRfXykge1xuXHRcdHN1cGVyKG1lc3NhZ2UpO1xuXHRcdHRoaXMuYWN0dWFsID0gYWN0dWFsO1xuXHRcdHRoaXMuZXhwZWN0ZWQgPSBleHBlY3RlZDtcblx0XHR0aGlzLl9fdml0ZXN0X2Vycm9yX2NvbnRleHRfXyA9IF9fdml0ZXN0X2Vycm9yX2NvbnRleHRfXztcblx0fVxufVxuZnVuY3Rpb24gSmVzdEV4dGVuZFBsdWdpbihjLCBleHBlY3QsIG1hdGNoZXJzKSB7XG5cdHJldHVybiAoXywgdXRpbHMpID0+IHtcblx0XHRPYmplY3QuZW50cmllcyhtYXRjaGVycykuZm9yRWFjaCgoW2V4cGVjdEFzc2VydGlvbk5hbWUsIGV4cGVjdEFzc2VydGlvbl0pID0+IHtcblx0XHRcdGZ1bmN0aW9uIF9fVklURVNUX0VYVEVORF9BU1NFUlRJT05fXyguLi5hcmdzKSB7XG5cdFx0XHRcdGNvbnN0IHsgc3RhdGUsIGlzTm90LCBvYmosIGN1c3RvbU1lc3NhZ2UgfSA9IGdldE1hdGNoZXJTdGF0ZSh0aGlzLCBleHBlY3QpO1xuXHRcdFx0XHRjb25zdCByZXN1bHQgPSBleHBlY3RBc3NlcnRpb24uY2FsbChzdGF0ZSwgb2JqLCAuLi5hcmdzKTtcblx0XHRcdFx0aWYgKHJlc3VsdCAmJiB0eXBlb2YgcmVzdWx0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiByZXN1bHQudGhlbiA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHRcdFx0Y29uc3QgdGhlbmFibGUgPSByZXN1bHQ7XG5cdFx0XHRcdFx0cmV0dXJuIHRoZW5hYmxlLnRoZW4oKHsgcGFzcywgbWVzc2FnZSwgYWN0dWFsLCBleHBlY3RlZCwgbWV0YSB9KSA9PiB7XG5cdFx0XHRcdFx0XHRpZiAocGFzcyAmJiBpc05vdCB8fCAhcGFzcyAmJiAhaXNOb3QpIHtcblx0XHRcdFx0XHRcdFx0Y29uc3QgZXJyb3JNZXNzYWdlID0gKGN1c3RvbU1lc3NhZ2UgPyBgJHtjdXN0b21NZXNzYWdlfTogYCA6IFwiXCIpICsgbWVzc2FnZSgpO1xuXHRcdFx0XHRcdFx0XHR0aHJvdyBuZXcgSmVzdEV4dGVuZEVycm9yKGVycm9yTWVzc2FnZSwgYWN0dWFsLCBleHBlY3RlZCwge1xuXHRcdFx0XHRcdFx0XHRcdGFzc2VydGlvbk5hbWU6IGV4cGVjdEFzc2VydGlvbk5hbWUsXG5cdFx0XHRcdFx0XHRcdFx0bWV0YVxuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRjb25zdCB7IHBhc3MsIG1lc3NhZ2UsIGFjdHVhbCwgZXhwZWN0ZWQsIG1ldGEgfSA9IHJlc3VsdDtcblx0XHRcdFx0aWYgKHBhc3MgJiYgaXNOb3QgfHwgIXBhc3MgJiYgIWlzTm90KSB7XG5cdFx0XHRcdFx0Y29uc3QgZXJyb3JNZXNzYWdlID0gKGN1c3RvbU1lc3NhZ2UgPyBgJHtjdXN0b21NZXNzYWdlfTogYCA6IFwiXCIpICsgbWVzc2FnZSgpO1xuXHRcdFx0XHRcdHRocm93IG5ldyBKZXN0RXh0ZW5kRXJyb3IoZXJyb3JNZXNzYWdlLCBhY3R1YWwsIGV4cGVjdGVkLCB7XG5cdFx0XHRcdFx0XHRhc3NlcnRpb25OYW1lOiBleHBlY3RBc3NlcnRpb25OYW1lLFxuXHRcdFx0XHRcdFx0bWV0YVxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRjb25zdCBzb2Z0V3JhcHBlciA9IHdyYXBBc3NlcnRpb24odXRpbHMsIGV4cGVjdEFzc2VydGlvbk5hbWUsIF9fVklURVNUX0VYVEVORF9BU1NFUlRJT05fXyk7XG5cdFx0XHR1dGlscy5hZGRNZXRob2QoZ2xvYmFsVGhpc1tKRVNUX01BVENIRVJTX09CSkVDVF0ubWF0Y2hlcnMsIGV4cGVjdEFzc2VydGlvbk5hbWUsIHNvZnRXcmFwcGVyKTtcblx0XHRcdHV0aWxzLmFkZE1ldGhvZChjLkFzc2VydGlvbi5wcm90b3R5cGUsIGV4cGVjdEFzc2VydGlvbk5hbWUsIHNvZnRXcmFwcGVyKTtcblx0XHRcdC8vIGBleHBlY3QucG9sbCgpYCBpbnNwZWN0cyB0aGUgaW5zdGFsbGVkIENoYWkgYXNzZXJ0aW9uIG1ldGhvZCxcblx0XHRcdC8vIHNvIGNvcHkgdGhlIGludGVybmFsIG1hcmtlciBmcm9tIHRoZSBvcmlnaW5hbCBtYXRjaGVyIGZ1bmN0aW9uLlxuXHRcdFx0Ly8gdGhpcyBpcyBvbmx5IGZvciBkb21haW4gc25hcHNob3QgbWF0Y2hlcnMgZm9yIG5vdy5cblx0XHRcdGlmIChleHBlY3RBc3NlcnRpb24uX192aXRlc3RfcG9sbF90YWtlb3Zlcl9fKSB7XG5cdFx0XHRcdGNvbnN0IGFkZGVkTWV0aG9kID0gYy5Bc3NlcnRpb24ucHJvdG90eXBlW2V4cGVjdEFzc2VydGlvbk5hbWVdO1xuXHRcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoYWRkZWRNZXRob2QsIFwiX192aXRlc3RfcG9sbF90YWtlb3Zlcl9fXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cdFx0XHR9XG5cdFx0XHRjbGFzcyBDdXN0b21NYXRjaGVyIGV4dGVuZHMgQXN5bW1ldHJpY01hdGNoZXIge1xuXHRcdFx0XHRjb25zdHJ1Y3RvcihpbnZlcnNlID0gZmFsc2UsIC4uLnNhbXBsZSkge1xuXHRcdFx0XHRcdHN1cGVyKHNhbXBsZSwgaW52ZXJzZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0YXN5bW1ldHJpY01hdGNoKG90aGVyKSB7XG5cdFx0XHRcdFx0Y29uc3QgeyBwYXNzIH0gPSBleHBlY3RBc3NlcnRpb24uY2FsbCh0aGlzLmdldE1hdGNoZXJDb250ZXh0KGV4cGVjdCksIG90aGVyLCAuLi50aGlzLnNhbXBsZSk7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXMuaW52ZXJzZSA/ICFwYXNzIDogcGFzcztcblx0XHRcdFx0fVxuXHRcdFx0XHR0b1N0cmluZygpIHtcblx0XHRcdFx0XHRyZXR1cm4gYCR7dGhpcy5pbnZlcnNlID8gXCJub3QuXCIgOiBcIlwifSR7ZXhwZWN0QXNzZXJ0aW9uTmFtZX1gO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGdldEV4cGVjdGVkVHlwZSgpIHtcblx0XHRcdFx0XHRyZXR1cm4gXCJhbnlcIjtcblx0XHRcdFx0fVxuXHRcdFx0XHR0b0FzeW1tZXRyaWNNYXRjaGVyKCkge1xuXHRcdFx0XHRcdHJldHVybiBgJHt0aGlzLnRvU3RyaW5nKCl9PCR7dGhpcy5zYW1wbGUubWFwKChpdGVtKSA9PiBzdHJpbmdpZnkoaXRlbSkpLmpvaW4oXCIsIFwiKX0+YDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Y29uc3QgY3VzdG9tTWF0Y2hlciA9ICguLi5zYW1wbGUpID0+IG5ldyBDdXN0b21NYXRjaGVyKGZhbHNlLCAuLi5zYW1wbGUpO1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cGVjdCwgZXhwZWN0QXNzZXJ0aW9uTmFtZSwge1xuXHRcdFx0XHRjb25maWd1cmFibGU6IHRydWUsXG5cdFx0XHRcdGVudW1lcmFibGU6IHRydWUsXG5cdFx0XHRcdHZhbHVlOiBjdXN0b21NYXRjaGVyLFxuXHRcdFx0XHR3cml0YWJsZTogdHJ1ZVxuXHRcdFx0fSk7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwZWN0Lm5vdCwgZXhwZWN0QXNzZXJ0aW9uTmFtZSwge1xuXHRcdFx0XHRjb25maWd1cmFibGU6IHRydWUsXG5cdFx0XHRcdGVudW1lcmFibGU6IHRydWUsXG5cdFx0XHRcdHZhbHVlOiAoLi4uc2FtcGxlKSA9PiBuZXcgQ3VzdG9tTWF0Y2hlcih0cnVlLCAuLi5zYW1wbGUpLFxuXHRcdFx0XHR3cml0YWJsZTogdHJ1ZVxuXHRcdFx0fSk7XG5cdFx0XHQvLyBrZWVwIHRyYWNrIG9mIGFzeW1tZXRyaWMgbWF0Y2hlcnMgb24gZ2xvYmFsIHNvIHRoYXQgaXQgY2FuIGJlIGNvcGllZCBvdmVyIHRvIGxvY2FsIGNvbnRleHQncyBgZXhwZWN0YC5cblx0XHRcdC8vIG5vdGUgdGhhdCB0aGUgbmVnYXRlZCB2YXJpYW50IGlzIGF1dG9tYXRpY2FsbHkgc2hhcmVkIHNpbmNlIGl0J3MgYXNzaWduZWQgb24gdGhlIHNpbmdsZSBgZXhwZWN0Lm5vdGAgb2JqZWN0LlxuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGdsb2JhbFRoaXNbQVNZTU1FVFJJQ19NQVRDSEVSU19PQkpFQ1RdLCBleHBlY3RBc3NlcnRpb25OYW1lLCB7XG5cdFx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcblx0XHRcdFx0dmFsdWU6IGN1c3RvbU1hdGNoZXIsXG5cdFx0XHRcdHdyaXRhYmxlOiB0cnVlXG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fTtcbn1cbmNvbnN0IEplc3RFeHRlbmQgPSAoY2hhaSwgdXRpbHMpID0+IHtcblx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuZXhwZWN0LCBcImV4dGVuZFwiLCAoZXhwZWN0LCBleHBlY3RzKSA9PiB7XG5cdFx0dXNlKEplc3RFeHRlbmRQbHVnaW4oY2hhaSwgZXhwZWN0LCBleHBlY3RzKSk7XG5cdH0pO1xufTtcblxuZXhwb3J0IHsgQVNZTU1FVFJJQ19NQVRDSEVSU19PQkpFQ1QsIEFueSwgQW55dGhpbmcsIEFycmF5Q29udGFpbmluZywgQXN5bW1ldHJpY01hdGNoZXIsIENoYWlTdHlsZUFzc2VydGlvbnMsIEdMT0JBTF9FWFBFQ1QsIEpFU1RfTUFUQ0hFUlNfT0JKRUNULCBKZXN0QXN5bW1ldHJpY01hdGNoZXJzLCBKZXN0Q2hhaUV4cGVjdCwgSmVzdEV4dGVuZCwgTUFUQ0hFUlNfT0JKRUNULCBPYmplY3RDb250YWluaW5nLCBTY2hlbWFNYXRjaGluZywgU3RyaW5nQ29udGFpbmluZywgU3RyaW5nTWF0Y2hpbmcsIGFkZEN1c3RvbUVxdWFsaXR5VGVzdGVycywgYXJyYXlCdWZmZXJFcXVhbGl0eSwgY3JlYXRlQXNzZXJ0aW9uTWVzc2FnZSwgY3VzdG9tTWF0Y2hlcnMsIGVxdWFscywgZm5OYW1lRm9yLCBnZW5lcmF0ZVRvQmVNZXNzYWdlLCBnZXRPYmplY3RLZXlzLCBnZXRPYmplY3RTdWJzZXQsIGdldFN0YXRlLCBoYXNBc3ltbWV0cmljLCBoYXNQcm9wZXJ0eSwgaXNBLCBpc0FzeW1tZXRyaWMsIGlzRXJyb3IsIGlzSW1tdXRhYmxlVW5vcmRlcmVkS2V5ZWQsIGlzSW1tdXRhYmxlVW5vcmRlcmVkU2V0LCBpc1N0YW5kYXJkU2NoZW1hLCBpdGVyYWJsZUVxdWFsaXR5LCBwbHVyYWxpemUsIHJlY29yZEFzeW5jRXhwZWN0LCBzZXRTdGF0ZSwgc3BhcnNlQXJyYXlFcXVhbGl0eSwgc3Vic2V0RXF1YWxpdHksIHR5cGVFcXVhbGl0eSwgd3JhcEFzc2VydGlvbiB9O1xuIl0sInhfZ29vZ2xlX2lnbm9yZUxpc3QiOlswXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBVUEsTUFBTSx1QkFBdUIsTUFBTSxVQUFVO0NBQzVDLFNBQVMsWUFBWSxNQUFNLFlBQVk7RUFDdEMsTUFBTSxZQUFZLEtBQUssVUFBVSxXQUFXLE1BQU0sV0FBVztHQUM1RCxNQUFNLGFBQWEsS0FBSyxVQUFVLFVBQVU7R0FDNUMsSUFBSSxDQUFDLFlBQ0osTUFBTSxJQUFJLE1BQU0sc0JBQXNCLE9BQU8sVUFBVSxFQUFFLGtFQUFrRTtHQUU1SCxPQUFPLFdBQVcsS0FBSyxJQUFJO0VBQzVCLENBQUM7Q0FDRjtDQUNBLFNBQVMsb0JBQW9CLE1BQU0sWUFBWSxHQUFHLE1BQU07RUFDdkQsTUFBTSxZQUFZLEtBQUssVUFBVSxXQUFXLE1BQU0sV0FBVztHQUM1RCxNQUFNLGFBQWEsS0FBSyxVQUFVLFVBQVU7R0FDNUMsSUFBSSxDQUFDLFlBQ0osTUFBTSxJQUFJLE1BQU0sc0JBQXNCLE9BQU8sVUFBVSxFQUFFLGtFQUFrRTtHQUU1SCxPQUFPLFdBQVcsS0FBSyxNQUFNLEdBQUcsSUFBSTtFQUNyQyxDQUFDO0NBQ0Y7Q0FDQSxTQUFTLFVBQVUsTUFBTSxZQUFZO0VBQ3BDLE1BQU0sVUFBVSxLQUFLLFVBQVUsV0FBVyxNQUFNLFNBQVMsR0FBRyxNQUFNO0dBQ2pFLE1BQU0sYUFBYSxLQUFLLFVBQVUsVUFBVTtHQUM1QyxJQUFJLENBQUMsWUFDSixNQUFNLElBQUksTUFBTSxzQkFBc0Is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