@cartanova/qgrid-cli 2.10.10 → 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 (313) 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 +21 -19
  10. package/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +40 -33
  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 -70
  24. package/bundle/dist/application/request-log/request-log.types.js +1 -1
  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 +32 -16
  33. package/bundle/dist/application/sonamu.generated.sso.js +1 -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 +1 -1
  39. package/bundle/dist/migrations/20260807133553_manual__backfill_request_log_cost.js +8 -6
  40. package/bundle/dist/server-bootstrap.js +4 -2
  41. package/bundle/dist/server-error-handler.js +1 -1
  42. package/bundle/dist/sonamu.config.js +37 -8
  43. package/bundle/dist/startup-migrations.js +17 -7
  44. package/bundle/dist/testing/global.js +1 -1
  45. package/bundle/dist/testing/schema-bench.js +0 -0
  46. package/bundle/dist/testing/test-database-name.js +1 -1
  47. package/bundle/dist/utils/providers/anthropic/anthropic-constants.js +1 -1
  48. package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +11 -5
  49. package/bundle/dist/utils/providers/anthropic/anthropic-quota.js +4 -4
  50. package/bundle/dist/utils/providers/anthropic/anthropic-thinking.js +1 -1
  51. package/bundle/dist/utils/providers/anthropic/claude-session.js +20 -19
  52. package/bundle/dist/utils/providers/anthropic/fence-strip.js +1 -1
  53. package/bundle/dist/utils/providers/anthropic/stream-json-adapter.js +49 -23
  54. package/bundle/dist/utils/providers/common/credentials.js +5 -1
  55. package/bundle/dist/utils/providers/common/effort.js +3 -3
  56. package/bundle/dist/utils/providers/common/model-cost.js +69 -14
  57. package/bundle/dist/utils/providers/common/provider-types.js +29 -1
  58. package/bundle/dist/utils/providers/common/schema-validation.js +78 -40
  59. package/bundle/dist/utils/providers/common/smooth-weighted-round-robin.js +1 -1
  60. package/bundle/dist/utils/providers/common/strictifier.js +62 -43
  61. package/bundle/dist/utils/providers/common/thinking.js +3 -2
  62. package/bundle/dist/utils/providers/common/ttft.js +1 -1
  63. package/bundle/dist/utils/providers/grok/grok-backend-protocol.js +427 -0
  64. package/bundle/dist/utils/providers/grok/grok-constants.js +55 -0
  65. package/bundle/dist/utils/providers/grok/grok-direct-client.js +196 -0
  66. package/bundle/dist/utils/providers/grok/grok-dispatcher.js +1313 -0
  67. package/bundle/dist/utils/providers/grok/grok-headers.js +118 -0
  68. package/bundle/dist/utils/providers/grok/grok-media-client.js +420 -0
  69. package/bundle/dist/utils/providers/grok/grok-models.js +114 -0
  70. package/bundle/dist/utils/providers/grok/grok-oauth.js +455 -0
  71. package/bundle/dist/utils/providers/grok/grok-quota.js +119 -0
  72. package/bundle/dist/utils/providers/grok/grok-refresh.js +192 -0
  73. package/bundle/dist/utils/providers/grok/grok-types.js +186 -0
  74. package/bundle/dist/utils/providers/grok/grok-voice-client.js +199 -0
  75. package/bundle/dist/utils/providers/grok/index.js +11 -0
  76. package/bundle/dist/utils/providers/openai/openai-backend-protocol.js +111 -83
  77. package/bundle/dist/utils/providers/openai/openai-callback-relay.js +3 -2
  78. package/bundle/dist/utils/providers/openai/openai-constants.js +1 -1
  79. package/bundle/dist/utils/providers/openai/openai-direct-client.js +23 -7
  80. package/bundle/dist/utils/providers/openai/openai-dispatcher.js +143 -106
  81. package/bundle/dist/utils/providers/openai/openai-image-generation.js +48 -33
  82. package/bundle/dist/utils/providers/openai/openai-oauth.js +28 -13
  83. package/bundle/dist/utils/providers/openai/openai-quota.js +38 -27
  84. package/bundle/dist/utils/providers/openai/openai-refresh.js +17 -9
  85. package/bundle/dist/utils/providers/openai/openai-sse.js +1 -1
  86. package/bundle/dist/utils/providers/openai/openai-transport-config.js +1 -1
  87. package/bundle/dist/utils/quiet-hours.js +1 -1
  88. package/bundle/dist/utils/slack-notify.js +14 -8
  89. package/bundle/dist/utils/subset-loaders.js +4 -5
  90. package/bundle/src/application/monit/log-buffer.ts +23 -9
  91. package/bundle/src/application/monit/monit.frame.ts +22 -5
  92. package/bundle/src/application/monit/monit.types.ts +6 -0
  93. package/bundle/src/application/qgrid/conv-routing.test.ts +76 -4
  94. package/bundle/src/application/qgrid/conv-routing.ts +35 -9
  95. package/bundle/src/application/qgrid/expired-token-reminder.ts +9 -1
  96. package/bundle/src/application/qgrid/oauth.ts +51 -15
  97. package/bundle/src/application/qgrid/qgrid-image-generation.ts +9 -0
  98. package/bundle/src/application/qgrid/qgrid-response-format.ts +50 -25
  99. package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +19 -0
  100. package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +84 -40
  101. package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +97 -0
  102. package/bundle/src/application/qgrid/qgrid.dispatcher.ts +274 -126
  103. package/bundle/src/application/qgrid/qgrid.frame.test.ts +1013 -3
  104. package/bundle/src/application/qgrid/qgrid.frame.ts +1415 -60
  105. package/bundle/src/application/qgrid/qgrid.types.ts +335 -0
  106. package/bundle/src/application/qgrid/schema-prompt.ts +105 -41
  107. package/bundle/src/application/qgrid/slack-user-map.ts +5 -0
  108. package/bundle/src/application/qgrid/token-death.ts +4 -0
  109. package/bundle/src/application/qgrid/token-subscriber.test.ts +21 -19
  110. package/bundle/src/application/qgrid/token-subscriber.ts +186 -53
  111. package/bundle/src/application/qgrid/token-trigger-setup.ts +2 -0
  112. package/bundle/src/application/qgrid/token-window-keepalive.ts +49 -6
  113. package/bundle/src/application/qgrid/tool-emulation-schema.ts +33 -29
  114. package/bundle/src/application/qgrid/tool-emulation.ts +52 -27
  115. package/bundle/src/application/request-log/json-schema-type-text.test.ts +5 -5
  116. package/bundle/src/application/request-log/json-schema-type-text.ts +81 -26
  117. package/bundle/src/application/request-log/request-log.model.test.ts +111 -4
  118. package/bundle/src/application/request-log/request-log.model.ts +277 -146
  119. package/bundle/src/application/request-log/request-log.types.ts +6 -0
  120. package/bundle/src/application/request-log/zod-code-format.ts +11 -0
  121. package/bundle/src/application/request-log-step/request-log-step.model.ts +1 -0
  122. package/bundle/src/application/request-log-step/request-log-step.types.ts +2 -0
  123. package/bundle/src/application/setting/setting.constant.ts +9 -0
  124. package/bundle/src/application/setting/setting.model.ts +12 -2
  125. package/bundle/src/application/setting/setting.store.ts +5 -1
  126. package/bundle/src/application/setting/setting.types.ts +8 -0
  127. package/bundle/src/application/sonamu.generated.http +133 -0
  128. package/bundle/src/application/sonamu.generated.sso.ts +2 -0
  129. package/bundle/src/application/sonamu.generated.ts +15 -0
  130. package/bundle/src/application/token/token.identity.test.ts +20 -0
  131. package/bundle/src/application/token/token.model.ts +66 -7
  132. package/bundle/src/application/token/token.types.ts +24 -1
  133. package/bundle/src/i18n/en.ts +19 -0
  134. package/bundle/src/i18n/ko.ts +21 -0
  135. package/bundle/src/i18n/sd.generated.ts +23 -2
  136. package/bundle/src/migrations/20260807133553_manual__backfill_request_log_cost.ts +16 -8
  137. package/bundle/src/server-bootstrap.ts +4 -2
  138. package/bundle/src/server-error-handler.ts +1 -0
  139. package/bundle/src/sonamu.config.ts +69 -7
  140. package/bundle/src/startup-migrations.ts +27 -9
  141. package/bundle/src/testing/global.ts +20 -0
  142. package/bundle/src/testing/schema-bench.ts +105 -30
  143. package/bundle/src/testing/test-database-name.ts +2 -0
  144. package/bundle/src/utils/providers/anthropic/anthropic-constants.ts +8 -0
  145. package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.ts +41 -6
  146. package/bundle/src/utils/providers/anthropic/anthropic-quota.ts +7 -3
  147. package/bundle/src/utils/providers/anthropic/anthropic-thinking.ts +6 -0
  148. package/bundle/src/utils/providers/anthropic/claude-session.ts +58 -24
  149. package/bundle/src/utils/providers/anthropic/fence-strip.ts +11 -0
  150. package/bundle/src/utils/providers/anthropic/stream-json-adapter.ts +110 -45
  151. package/bundle/src/utils/providers/common/credentials.ts +8 -0
  152. package/bundle/src/utils/providers/common/effort.ts +9 -2
  153. package/bundle/src/utils/providers/common/model-cost.test.ts +48 -1
  154. package/bundle/src/utils/providers/common/model-cost.ts +259 -158
  155. package/bundle/src/utils/providers/common/provider-dispatcher.ts +98 -2
  156. package/bundle/src/utils/providers/common/provider-types.ts +46 -3
  157. package/bundle/src/utils/providers/common/schema-validation.test.ts +5 -1
  158. package/bundle/src/utils/providers/common/schema-validation.ts +124 -56
  159. package/bundle/src/utils/providers/common/smooth-weighted-round-robin.ts +4 -0
  160. package/bundle/src/utils/providers/common/strictifier.ts +185 -59
  161. package/bundle/src/utils/providers/common/thinking.ts +2 -2
  162. package/bundle/src/utils/providers/common/ttft.ts +4 -2
  163. package/bundle/src/utils/providers/grok/__fixtures__/golden-responses-1.0.60.json +164 -0
  164. package/bundle/src/utils/providers/grok/grok-backend-protocol.test.ts +325 -0
  165. package/bundle/src/utils/providers/grok/grok-backend-protocol.ts +721 -0
  166. package/bundle/src/utils/providers/grok/grok-constants.ts +105 -0
  167. package/bundle/src/utils/providers/grok/grok-direct-client.test.ts +179 -0
  168. package/bundle/src/utils/providers/grok/grok-direct-client.ts +313 -0
  169. package/bundle/src/utils/providers/grok/grok-dispatcher.test.ts +1395 -0
  170. package/bundle/src/utils/providers/grok/grok-dispatcher.ts +2105 -0
  171. package/bundle/src/utils/providers/grok/grok-headers.test.ts +149 -0
  172. package/bundle/src/utils/providers/grok/grok-headers.ts +199 -0
  173. package/bundle/src/utils/providers/grok/grok-media-client.test.ts +446 -0
  174. package/bundle/src/utils/providers/grok/grok-media-client.ts +703 -0
  175. package/bundle/src/utils/providers/grok/grok-models.test.ts +96 -0
  176. package/bundle/src/utils/providers/grok/grok-models.ts +161 -0
  177. package/bundle/src/utils/providers/grok/grok-oauth.test.ts +406 -0
  178. package/bundle/src/utils/providers/grok/grok-oauth.ts +771 -0
  179. package/bundle/src/utils/providers/grok/grok-quota.test.ts +142 -0
  180. package/bundle/src/utils/providers/grok/grok-quota.ts +198 -0
  181. package/bundle/src/utils/providers/grok/grok-refresh.test.ts +239 -0
  182. package/bundle/src/utils/providers/grok/grok-refresh.ts +325 -0
  183. package/bundle/src/utils/providers/grok/grok-types.test.ts +252 -0
  184. package/bundle/src/utils/providers/grok/grok-types.ts +374 -0
  185. package/bundle/src/utils/providers/grok/grok-voice-client.test.ts +321 -0
  186. package/bundle/src/utils/providers/grok/grok-voice-client.ts +284 -0
  187. package/bundle/src/utils/providers/grok/index.ts +20 -0
  188. package/bundle/src/utils/providers/openai/openai-backend-protocol.ts +221 -137
  189. package/bundle/src/utils/providers/openai/openai-callback-relay.ts +12 -1
  190. package/bundle/src/utils/providers/openai/openai-constants.ts +2 -0
  191. package/bundle/src/utils/providers/openai/openai-direct-client.ts +111 -21
  192. package/bundle/src/utils/providers/openai/openai-dispatcher.ts +322 -169
  193. package/bundle/src/utils/providers/openai/openai-image-generation.ts +116 -36
  194. package/bundle/src/utils/providers/openai/openai-oauth.ts +48 -20
  195. package/bundle/src/utils/providers/openai/openai-quota.ts +77 -46
  196. package/bundle/src/utils/providers/openai/openai-refresh.ts +42 -18
  197. package/bundle/src/utils/providers/openai/openai-sse.ts +27 -3
  198. package/bundle/src/utils/providers/openai/openai-transport-config.ts +2 -0
  199. package/bundle/src/utils/quiet-hours.ts +12 -1
  200. package/bundle/src/utils/slack-notify.ts +44 -13
  201. package/bundle/src/utils/subset-loaders.ts +7 -7
  202. package/bundle/web-dist/client/assets/clsx-5XM_pHvN.js +1 -0
  203. package/bundle/web-dist/client/assets/index-BA7uQ-6c.js +31 -0
  204. package/bundle/web-dist/client/assets/index-Be2qCZmI.css +1 -0
  205. package/bundle/web-dist/client/assets/logs-C47OJGEI.js +1 -0
  206. package/bundle/web-dist/client/assets/monit-BS9no0dU.js +4 -0
  207. package/bundle/web-dist/client/assets/plus-sdACTfH0.js +1 -0
  208. package/bundle/web-dist/client/assets/refresh-cw-CY8o_1cT.js +1 -0
  209. package/bundle/web-dist/client/assets/request-model-BRtFuZvj.js +1 -0
  210. package/bundle/web-dist/client/assets/routes-kqgkUxE8.js +5 -0
  211. package/bundle/web-dist/client/assets/{services.generated-NP-ValHd.js → services.generated-CefiDXEv.js} +5 -5
  212. package/bundle/web-dist/client/assets/settings-DNDvFGSw.js +1 -0
  213. package/bundle/web-dist/client/assets/show-u8Np69q3.js +2 -0
  214. package/bundle/web-dist/client/assets/tokens-QvP410NW.js +1 -0
  215. package/bundle/web-dist/client/assets/total-cost-MnfKU8IN.js +1 -0
  216. package/bundle/web-dist/client/assets/use-oauth-login-flow-Bzdh28Ws.js +1 -0
  217. package/bundle/web-dist/client/assets/use-update-token-mutation-CfJKaxmR.js +1 -0
  218. package/bundle/web-dist/client/assets/vendor-react-CUFFrVN9.js +244 -0
  219. package/bundle/web-dist/client/assets/vendor-tanstack-Bf_jag9G.js +1 -0
  220. package/bundle/web-dist/client/index.html +6 -6
  221. package/bundle/web-dist/server/assets/clsx-D_N5PN_2.js +16 -0
  222. package/bundle/web-dist/server/assets/{lazyRouteComponent-CgBdabgd.js → lazyRouteComponent-D8iTIHyn.js} +129 -2
  223. package/bundle/web-dist/server/assets/logs-B3OTd9hy.js +825 -0
  224. package/bundle/web-dist/server/assets/{monit-ZPt66W5M.js → monit-B2hqorPe.js} +385 -126
  225. package/bundle/web-dist/server/assets/plus-DwG7h9kq.js +28 -0
  226. package/bundle/web-dist/server/assets/{react-dom-Ds75e4Jl.js → react-dom-BIYQzBqG.js} +2 -129
  227. package/bundle/web-dist/server/assets/refresh-cw-mMBkwOq0.js +44 -0
  228. package/bundle/web-dist/server/assets/{request-model-DjGldb-h.js → request-model-I6OdODSH.js} +15 -6
  229. package/bundle/web-dist/server/assets/{routes-Ct-k7nBA.js → routes-B95YlUv2.js} +760 -213
  230. package/bundle/web-dist/server/assets/{services.generated-BA4AcAf5.js → services.generated-DQATJ6qf.js} +12820 -12194
  231. package/bundle/web-dist/server/assets/settings-C3gbGk0m.js +830 -0
  232. package/bundle/web-dist/server/assets/{show-LSFIzvO2.js → show-Bxaj3rhH.js} +1350 -418
  233. package/bundle/web-dist/server/assets/tokens-CZjH3cB7.js +1038 -0
  234. package/bundle/web-dist/server/assets/total-cost-fTE9Xy82.js +18 -0
  235. package/bundle/web-dist/server/assets/use-oauth-login-flow-CKDHgc3U.js +2379 -0
  236. package/bundle/web-dist/server/assets/{use-update-token-mutation-pkArIzCP.js → use-update-token-mutation-BEbgOzaa.js} +1 -1
  237. package/bundle/web-dist/server/entry-server.generated.js +4295 -22810
  238. package/dist/cli.js +9 -9
  239. package/package.json +4 -11
  240. package/postinstall.mjs +12 -0
  241. package/skills/qgrid/SKILL.md +1 -0
  242. package/skills/qgrid/references/cli-env-and-server-boot.md +4 -1
  243. package/skills/qgrid/references/decision-rationale.md +23 -0
  244. package/skills/qgrid/references/grok-runtime.md +89 -0
  245. package/skills/qgrid/references/provider-runtime-differences.md +30 -29
  246. package/skills/qgrid/references/repo-map.md +10 -0
  247. package/skills/qgrid/references/token-auth-quota-lifecycle.md +56 -3
  248. package/bundle/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +0 -406
  249. package/bundle/dist/node_modules/.pnpm/@vitest_expect@4.1.10/node_modules/@vitest/expect/dist/index.js +0 -1507
  250. package/bundle/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.10/node_modules/@vitest/pretty-format/dist/index.js +0 -887
  251. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/chunk-artifact.js +0 -2756
  252. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/index.js +0 -8
  253. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/utils.js +0 -8
  254. package/bundle/dist/node_modules/.pnpm/@vitest_snapshot@4.1.10/node_modules/@vitest/snapshot/dist/index.js +0 -922
  255. package/bundle/dist/node_modules/.pnpm/@vitest_spy@4.1.10/node_modules/@vitest/spy/dist/index.js +0 -386
  256. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +0 -121
  257. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/constants.js +0 -51
  258. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/diff.js +0 -1317
  259. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/display.js +0 -561
  260. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/error.js +0 -40
  261. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/helpers.js +0 -272
  262. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/offset.js +0 -27
  263. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/serialize.js +0 -77
  264. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/source-map.js +0 -381
  265. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/timers.js +0 -51
  266. package/bundle/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +0 -2986
  267. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +0 -10
  268. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +0 -109
  269. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +0 -10
  270. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +0 -10
  271. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +0 -10
  272. package/bundle/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +0 -1126
  273. package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +0 -21
  274. package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +0 -432
  275. package/bundle/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +0 -517
  276. package/bundle/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +0 -101
  277. 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
  278. 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
  279. 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
  280. 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
  281. 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
  282. 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
  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/rpc.MzXet3jl.js +0 -119
  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/test.DNmyFkvJ.js +0 -3044
  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/utils.BX5Fg8C4.js +0 -59
  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/index.js +0 -28
  287. package/bundle/dist/testing/setup-mocks.js +0 -16
  288. package/bundle/src/testing/setup-mocks.ts +0 -44
  289. package/bundle/web-dist/client/assets/index-Bw2s88Ot.css +0 -1
  290. package/bundle/web-dist/client/assets/index-DZwzUfI-.js +0 -106
  291. package/bundle/web-dist/client/assets/logs-Cog79DU5.js +0 -1
  292. package/bundle/web-dist/client/assets/monit-2auznBys.js +0 -1
  293. package/bundle/web-dist/client/assets/plus-B62CuqT8.js +0 -1
  294. package/bundle/web-dist/client/assets/refresh-cw-NNcU0Cmq.js +0 -1
  295. package/bundle/web-dist/client/assets/request-model-CojtinqK.js +0 -1
  296. package/bundle/web-dist/client/assets/routes-B0lTeLK-.js +0 -5
  297. package/bundle/web-dist/client/assets/settings-D8ZxZGSJ.js +0 -1
  298. package/bundle/web-dist/client/assets/show-CFSERlnM.js +0 -2
  299. package/bundle/web-dist/client/assets/tokens-CZXUyI7O.js +0 -1
  300. package/bundle/web-dist/client/assets/use-oauth-login-flow-hboOs3wG.js +0 -1
  301. package/bundle/web-dist/client/assets/use-update-token-mutation-BQHS0byG.js +0 -1
  302. package/bundle/web-dist/client/assets/vendor-react-DH4kUfK2.js +0 -9
  303. package/bundle/web-dist/client/assets/vendor-tanstack-DJRQAbrY.js +0 -1
  304. package/bundle/web-dist/server/assets/logs-BMyR98rU.js +0 -509
  305. package/bundle/web-dist/server/assets/plus-BZ9I0VgC.js +0 -19
  306. package/bundle/web-dist/server/assets/refresh-cw-CztCFis-.js +0 -23
  307. package/bundle/web-dist/server/assets/settings-CBUZ47Xx.js +0 -461
  308. package/bundle/web-dist/server/assets/tokens-DxrBW512.js +0 -448
  309. package/bundle/web-dist/server/assets/use-oauth-login-flow-Gn8flMK5.js +0 -178
  310. package/dist/cli.d.ts +0 -10
  311. /package/bundle/web-dist/client/assets/{cost-DH2jZbrw.js → cost-DB3HbU7T.js} +0 -0
  312. /package/bundle/web-dist/client/assets/{preload-helper-ca-nBW7U.js → preload-helper-DWTEM3RW.js} +0 -0
  313. /package/bundle/web-dist/server/assets/{cost-eEHeTRT5.js → cost-BC9yzyA9.js} +0 -0
@@ -1,6 +1,8 @@
1
+ import { composeSystemWithSchemaContract } from "./schema-prompt.js";
1
2
  import { RequestLogModel } from "../request-log/request-log.model.js";
2
3
  import { estimateImageGenerationCostMicroUsd, imageGenerationCostMethod } from "./qgrid-image-generation.js";
3
4
  import { buildImageGenerationToolSteps, extractInputImagesForToolArgs, formatResponseForLog, getImageParts } from "./qgrid-response-format.js";
5
+ import { z } from "zod";
4
6
  import { getLogger } from "@logtape/logtape";
5
7
  //#region src/application/qgrid/qgrid-run-lifecycle.ts
6
8
  const logger = getLogger(["qgrid", "run-lifecycle"]);
@@ -18,13 +20,16 @@ function withProviderPrefix(routeModel, model) {
18
20
  /**
19
21
  * history는 원본 그대로 저장하기보다는, run 분석에 필요한 user/assistant 정보만 필터링해서 저장
20
22
  */
23
+ const StoredHistoryMessage = z.looseObject({
24
+ type: z.literal("message"),
25
+ role: z.enum(["user", "assistant"])
26
+ });
21
27
  function filterHistoryForStorage(rawHistory) {
22
28
  if (!rawHistory) return void 0;
23
29
  try {
24
- const filtered = JSON.parse(rawHistory).filter((item) => {
25
- if (!item || typeof item !== "object") return false;
26
- const record = item;
27
- return record.type === "message" && (record.role === "user" || record.role === "assistant");
30
+ const filtered = z.array(z.unknown()).parse(JSON.parse(rawHistory)).flatMap((item) => {
31
+ const message = StoredHistoryMessage.safeParse(item);
32
+ return message.success ? [message.data] : [];
28
33
  });
29
34
  return filtered.length > 0 ? filtered : void 0;
30
35
  } catch {
@@ -57,7 +62,7 @@ async function beforeQuery(args) {
57
62
  const inputImages = extractInputImagesForToolArgs(args);
58
63
  requestLogId = await RequestLogModel.createRun({
59
64
  user_prompt: args.prompt,
60
- system_prompt: args.system,
65
+ system_prompt: args.model?.startsWith("anthropic/") ? composeSystemWithSchemaContract(args.system, args) : args.system,
61
66
  requested_model_name: args.model,
62
67
  effort: args.thinking === false ? void 0 : args.effort,
63
68
  service_tier: args.model?.startsWith("openai/") ? args.serviceTier : void 0,
@@ -123,7 +128,7 @@ async function afterQuery(requestLogId, stepIndex, args, result) {
123
128
  }
124
129
  const agg = await RequestLogModel.aggregateStepUsage(requestLogId);
125
130
  const responseText = formatResponseForLog(result);
126
- await RequestLogModel.finishRun(requestLogId, {
131
+ const finishParams = {
127
132
  status: "succeeded",
128
133
  response: responseText,
129
134
  response_json_ok: args.jsonSchema ? isParseableJson(responseText) : null,
@@ -142,10 +147,11 @@ async function afterQuery(requestLogId, stepIndex, args, result) {
142
147
  cost_usd: agg.cost_usd,
143
148
  cost_source: agg.cost_source,
144
149
  image_cost_usd: imageCostMicroUsd,
145
- ...imageParts.length > 0 ? { is_image_generation: true } : {},
146
150
  image_cost_method: imageCostMicroUsd !== null ? imageGenerationCostMethod(args.imageGenerationOptions, result) : null,
147
151
  history: filterHistoryForStorage(args.history)
148
- });
152
+ };
153
+ if (imageParts.length > 0) finishParams.is_image_generation = true;
154
+ await RequestLogModel.finishRun(requestLogId, finishParams);
149
155
  return {};
150
156
  }
151
157
  async function finishRunWithError(requestLogId, errorMessage, args, completedStep) {
@@ -159,38 +165,39 @@ async function finishTerminalRun(requestLogId, status, errorMessage, args, compl
159
165
  if (completedStep && args) try {
160
166
  await appendGenerateStep(requestLogId, completedStep.stepIndex, args, completedStep.result);
161
167
  } catch (e) {
162
- logger.error(`appendGenerateStep failed while finishing ${status}: ${e.message}`);
168
+ logger.error(`appendGenerateStep failed while finishing ${status}: ${e instanceof Error ? e.message : String(e)}`);
163
169
  }
164
170
  let aggregate;
165
171
  try {
166
172
  aggregate = await RequestLogModel.aggregateStepUsage(requestLogId);
167
173
  } catch (e) {
168
- logger.error(`aggregateStepUsage failed while finishing ${status}: ${e.message}`);
174
+ logger.error(`aggregateStepUsage failed while finishing ${status}: ${e instanceof Error ? e.message : String(e)}`);
169
175
  }
170
- await RequestLogModel.finishRun(requestLogId, {
176
+ const finishParams = {
171
177
  status,
172
178
  error_message: errorMessage,
173
- history: args ? filterHistoryForStorage(args.history) : void 0,
174
- ...completedStep ? {
175
- token_name: completedStep.result.tokenName,
176
- requested_model_name: withProviderPrefix(args?.model, args?.model ?? completedStep.result.requestedModel ?? completedStep.result.model),
177
- model_name: withProviderPrefix(args?.model, completedStep.result.model)
178
- } : {},
179
- ...aggregate ? {
180
- input_tokens: aggregate.input_tokens,
181
- output_tokens: aggregate.output_tokens,
182
- cache_read_tokens: aggregate.cache_read_tokens,
183
- cache_creation_tokens: aggregate.cache_creation_tokens,
184
- cache_creation_5m_tokens: aggregate.cache_creation_5m_tokens,
185
- cache_creation_1h_tokens: aggregate.cache_creation_1h_tokens,
186
- duration_ms: aggregate.duration_ms,
187
- fallback_count: aggregate.fallback_count,
188
- cost_usd: aggregate.cost_usd,
189
- cost_source: aggregate.cost_source
190
- } : {}
191
- });
179
+ history: args ? filterHistoryForStorage(args.history) : void 0
180
+ };
181
+ if (completedStep) {
182
+ finishParams.token_name = completedStep.result.tokenName;
183
+ finishParams.requested_model_name = withProviderPrefix(args?.model, args?.model ?? completedStep.result.requestedModel ?? completedStep.result.model);
184
+ finishParams.model_name = withProviderPrefix(args?.model, completedStep.result.model);
185
+ }
186
+ if (aggregate) {
187
+ finishParams.input_tokens = aggregate.input_tokens;
188
+ finishParams.output_tokens = aggregate.output_tokens;
189
+ finishParams.cache_read_tokens = aggregate.cache_read_tokens;
190
+ finishParams.cache_creation_tokens = aggregate.cache_creation_tokens;
191
+ finishParams.cache_creation_5m_tokens = aggregate.cache_creation_5m_tokens;
192
+ finishParams.cache_creation_1h_tokens = aggregate.cache_creation_1h_tokens;
193
+ finishParams.duration_ms = aggregate.duration_ms;
194
+ finishParams.fallback_count = aggregate.fallback_count;
195
+ finishParams.cost_usd = aggregate.cost_usd;
196
+ finishParams.cost_source = aggregate.cost_source;
197
+ }
198
+ await RequestLogModel.finishRun(requestLogId, finishParams);
192
199
  } catch (e) {
193
- logger.error(`finishTerminalRun(${status}) failed: ${e.message}`);
200
+ logger.error(`finishTerminalRun(${status}) failed: ${e instanceof Error ? e.message : String(e)}`);
194
201
  }
195
202
  }
196
203
  async function cleanupStaleRuns() {
@@ -214,10 +221,10 @@ async function performStaleRunCleanup() {
214
221
  const cleanedCount = (await RequestLogModel.expireStaleToolWaitingRuns(STALE_RUN_THRESHOLD_MS, "tool-call run: no follow-up within 30 minutes")).length;
215
222
  if (cleanedCount > 0) logger.info(`cleaned up ${cleanedCount} stale running request logs`);
216
223
  } catch (e) {
217
- logger.error(`stale cleanup failed: ${e.message}`);
224
+ logger.error(`stale cleanup failed: ${e instanceof Error ? e.message : String(e)}`);
218
225
  }
219
226
  }
220
227
  //#endregion
221
228
  export { afterQuery, beforeQuery, finishRunAborted, finishRunWithError };
222
229
 
223
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicWdyaWQtcnVuLWxpZmVjeWNsZS5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBwbGljYXRpb24vcWdyaWQvcWdyaWQtcnVuLWxpZmVjeWNsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnZXRMb2dnZXIgfSBmcm9tIFwiQGxvZ3RhcGUvbG9ndGFwZVwiO1xuXG5pbXBvcnQgeyBSZXF1ZXN0TG9nTW9kZWwgfSBmcm9tIFwiLi4vcmVxdWVzdC1sb2cvcmVxdWVzdC1sb2cubW9kZWxcIjtcbmltcG9ydCB7XG4gIGVzdGltYXRlSW1hZ2VHZW5lcmF0aW9uQ29zdE1pY3JvVXNkLFxuICBpbWFnZUdlbmVyYXRpb25Db3N0TWV0aG9kLFxufSBmcm9tIFwiLi9xZ3JpZC1pbWFnZS1nZW5lcmF0aW9uXCI7XG5pbXBvcnQge1xuICBidWlsZEltYWdlR2VuZXJhdGlvblRvb2xTdGVwcyxcbiAgZXh0cmFjdElucHV0SW1hZ2VzRm9yVG9vbEFyZ3MsXG4gIGZvcm1hdFJlc3BvbnNlRm9yTG9nLFxuICBnZXRJbWFnZVBhcnRzLFxufSBmcm9tIFwiLi9xZ3JpZC1yZXNwb25zZS1mb3JtYXRcIjtcbmltcG9ydCB7IHR5cGUgUWdyaWRSdW5Db250ZXh0LCB0eXBlIFF1ZXJ5SW5wdXQsIHR5cGUgUXVlcnlPdXRwdXQgfSBmcm9tIFwiLi9xZ3JpZC50eXBlc1wiO1xuXG5jb25zdCBsb2dnZXIgPSBnZXRMb2dnZXIoW1wicWdyaWRcIiwgXCJydW4tbGlmZWN5Y2xlXCJdKTtcbmNvbnN0IFNUQUxFX1JVTl9USFJFU0hPTERfTVMgPSAzMCAqIDYwICogMTAwMDtcbmNvbnN0IFNUQUxFX0NMRUFOVVBfSU5URVJWQUxfTVMgPSA2MCAqIDEwMDA7XG5sZXQgc3RhbGVDbGVhbnVwSW5GbGlnaHQ6IFByb21pc2U8dm9pZD4gfCB1bmRlZmluZWQ7XG5sZXQgbGFzdFN0YWxlQ2xlYW51cFN0YXJ0ZWRBdCA9IDA7XG5mdW5jdGlvbiB3aXRoUHJvdmlkZXJQcmVmaXgoXG4gIHJvdXRlTW9kZWw6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgbW9kZWw6IHN0cmluZyB8IHVuZGVmaW5lZCxcbik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghbW9kZWwpIHJldHVybiB1bmRlZmluZWQ7XG4gIGlmIChtb2RlbC5pbmNsdWRlcyhcIi9cIikpIHJldHVybiBtb2RlbDtcbiAgY29uc3Qgc2xhc2ggPSByb3V0ZU1vZGVsPy5pbmRleE9mKFwiL1wiKSA/PyAtMTtcbiAgY29uc3QgcHJvdmlkZXIgPSBzbGFzaCA+IDAgPyByb3V0ZU1vZGVsPy5zbGljZSgwLCBzbGFzaCkgOiB1bmRlZmluZWQ7XG4gIHJldHVybiBwcm92aWRlciA/IGAke3Byb3ZpZGVyfS8ke21vZGVsfWAgOiBtb2RlbDtcbn1cblxuLyoqXG4gKiBoaXN0b3J564qUIOybkOuzuCDqt7jrjIDroZwg7KCA7J6l7ZWY6riw67O064uk64qULCBydW4g67aE7ISd7JeQIO2VhOyalO2VnCB1c2VyL2Fzc2lzdGFudCDsoJXrs7Trp4wg7ZWE7YSw66eB7ZW07IScIOyggOyepVxuICovXG5mdW5jdGlvbiBmaWx0ZXJIaXN0b3J5Rm9yU3RvcmFnZShyYXdIaXN0b3J5OiBzdHJpbmcgfCB1bmRlZmluZWQpOiB1bmtub3duIHtcbiAgaWYgKCFyYXdIaXN0b3J5KSByZXR1cm4gdW5kZWZpbmVkO1xuICB0cnkge1xuICAgIGNvbnN0IGl0ZW1zID0gSlNPTi5wYXJzZShyYXdIaXN0b3J5KSBhcyB1bmtub3duW107XG4gICAgY29uc3QgZmlsdGVyZWQgPSBpdGVtcy5maWx0ZXIoKGl0ZW0pID0+IHtcbiAgICAgIGlmICghaXRlbSB8fCB0eXBlb2YgaXRlbSAhPT0gXCJvYmplY3RcIikgcmV0dXJuIGZhbHNlO1xuICAgICAgY29uc3QgcmVjb3JkID0gaXRlbSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgIHJldHVybiByZWNvcmQudHlwZSA9PT0gXCJtZXNzYWdlXCIgJiYgKHJlY29yZC5yb2xlID09PSBcInVzZXJcIiB8fCByZWNvcmQucm9sZSA9PT0gXCJhc3Npc3RhbnRcIik7XG4gICAgfSk7XG4gICAgcmV0dXJuIGZpbHRlcmVkLmxlbmd0aCA+IDAgPyBmaWx0ZXJlZCA6IHVuZGVmaW5lZDtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc1BhcnNlYWJsZUpzb24odGV4dDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgSlNPTi5wYXJzZSh0ZXh0KTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmV4cG9ydCB0eXBlIFJ1bkxpZmVjeWNsZVJlc3VsdCA9IHtcbiAgcnVuQ29udGV4dD86IFFncmlkUnVuQ29udGV4dDtcbn07XG5cbi8qKlxuICogbG9nZ2VyLWVuYWJsZWQgcXVlcnkvc3RyZWFtIOydkeuLtSDsoITtm4Tsl5Ag7Zi47LacLlxuICpcbiAqIDEpIGJlZm9yZVF1ZXJ5OiBydW4g7IOd7ISxL+qzhOyGjSArIHRvb2wgcmVzdWx0IOyZhOujjCArIHN0YWxlIHRvb2wtd2FpdCBjbGVhbnVwXG4gKiAyKSBhZnRlclF1ZXJ5OiBnZW5lcmF0ZSBzdGVwICsgdG9vbC1jYWxsIHN0ZXAgKyBmaW5pc2gva2VlcC1vcGVuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBiZWZvcmVRdWVyeShhcmdzOiBRdWVyeUlucHV0KTogUHJvbWlzZTx7XG4gIHJlcXVlc3RMb2dJZDogbnVtYmVyO1xuICBzdGVwSW5kZXg6IG51bWJlcjtcbn0+IHtcbiAgbGV0IHJlcXVlc3RMb2dJZDogbnVtYmVyO1xuICBsZXQgc3RlcEluZGV4ID0gMDtcblxuICAvLyByZXF1ZXN0TG9nSWQg6rCAIOyeiOydhCDrlYzrp4wg6riw7KG0IHJ1biDsl7DsnqUuIHRocmVhZENvb3JkIOunjCDsnojripQgY29udiDripQg7IOIIHJ1biDsnLzroZwg7Iuc7J6RLlxuICAvLyBjb250aW51YXRpb24g7J2AIGNyZWF0ZVJ1biDsnYQg6rG064SI65uw66+A66GcIHJ1biDsnZggdG9vbHMg64qUIOyyqyDsiqTthZ0g7J6l7LCp67aE7Jy866GcIOqzoOygleuQnOuLpCDigJRcbiAgLy8gQUkgU0RLIHByZXBhcmVTdGVwL2FjdGl2ZVRvb2xzIOuhnCDsiqTthZ3rp4jri6Qg7Yi07IWL7J20IOuwlOuAjOyWtOuPhCDroZzqt7jsl5DripQg67CY7JiB65CY7KeAIOyViuuKlOuLpC5cbiAgaWYgKGFyZ3MucnVuQ29udGV4dD8ucmVxdWVzdExvZ0lkICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXF1ZXN0TG9nSWQgPSBhcmdzLnJ1bkNvbnRleHQucmVxdWVzdExvZ0lkO1xuICAgIC8vIGNsZWFudXDqs7wg6rCZ7J2AIERCIGFkdmlzb3J5IGxvY2vsnYQg7J6h6rOgIHRvb2wg6rKw6rO8IOuwmOyYgSArIOuLpOydjCBzdGVwIOyYiOyVveydhCDtlZxcbiAgICAvLyB0cmFuc2FjdGlvbuyXkOyEnCDsspjrpqztlZzri6QuIOyXrOufrCBxZ3JpZCDtlITroZzshLjsiqQg7IKs7J207JeQ7ISc64+EIHN0YWxlIGV4cGlyeeqwgFxuICAgIC8vIOuPhOywqSDspJHsnbggZm9sbG93LXVw7J2EIGVycm9y66GcIOuNruyWtOyTsOyngCDrqrvtlZzri6QuXG4gICAgc3RlcEluZGV4ID0gYXdhaXQgUmVxdWVzdExvZ01vZGVsLmNvbnRpbnVlVG9vbFJ1bihyZXF1ZXN0TG9nSWQsIGFyZ3MudG9vbFJlc3VsdHMgPz8gW10pO1xuICAgIGF3YWl0IGNsZWFudXBTdGFsZVJ1bnMoKTtcbiAgfSBlbHNlIHtcbiAgICBhd2FpdCBjbGVhbnVwU3RhbGVSdW5zKCk7XG4gICAgY29uc3QgaW5wdXRJbWFnZXMgPSBleHRyYWN0SW5wdXRJbWFnZXNGb3JUb29sQXJncyhhcmdzKTtcbiAgICByZXF1ZXN0TG9nSWQgPSBhd2FpdCBSZXF1ZXN0TG9nTW9kZWwuY3JlYXRlUnVuKHtcbiAgICAgIHVzZXJfcHJvbXB0OiBhcmdzLnByb21wdCxcbiAgICAgIHN5c3RlbV9wcm9tcHQ6IGFyZ3Muc3lzdGVtLFxuICAgICAgcmVxdWVzdGVkX21vZGVsX25hbWU6IGFyZ3MubW9kZWwsXG4gICAgICBlZmZvcnQ6IGFyZ3MudGhpbmtpbmcgPT09IGZhbHNlID8gdW5kZWZpbmVkIDogYXJncy5lZmZvcnQsXG4gICAgICBzZXJ2aWNlX3RpZXI6IGFyZ3MubW9kZWw/LnN0YXJ0c1dpdGgoXCJvcGVuYWkvXCIpID8gYXJncy5zZXJ2aWNlVGllciA6IHVuZGVmaW5lZCxcbiAgICAgIHByb2plY3RfbmFtZTogYXJncy5wcm9qZWN0TmFtZSxcbiAgICAgIGhpc3Rvcnk6IGZpbHRlckhpc3RvcnlGb3JTdG9yYWdlKGFyZ3MuaGlzdG9yeSksXG4gICAgICBpbnB1dF9pbWFnZXM6IGlucHV0SW1hZ2VzLmxlbmd0aCA+IDAgPyBpbnB1dEltYWdlcyA6IHVuZGVmaW5lZCxcbiAgICAgIHRvb2xzOiBhcmdzLnRvb2xzPy5sZW5ndGggPyBhcmdzLnRvb2xzIDogdW5kZWZpbmVkLFxuICAgICAgaXNfaW1hZ2VfZ2VuZXJhdGlvbjogYXJncy5pbWFnZUdlbmVyYXRpb24gPT09IFwiYXV0b1wiID8gZmFsc2UgOiBhcmdzLmltYWdlR2VuZXJhdGlvbixcbiAgICAgIGpzb25fc2NoZW1hOiBhcmdzLmpzb25TY2hlbWEgPz8gbnVsbCxcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiB7IHJlcXVlc3RMb2dJZCwgc3RlcEluZGV4IH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGFwcGVuZEdlbmVyYXRlU3RlcChcbiAgcmVxdWVzdExvZ0lkOiBudW1iZXIsXG4gIHN0ZXBJbmRleDogbnVtYmVyLFxuICBhcmdzOiBRdWVyeUlucHV0LFxuICByZXN1bHQ6IFF1ZXJ5T3V0cHV0LFxuKSB7XG4gIC8vIHByb3ZpZGVy6rCAIGNhbm9uaWNhbCBtb2RlbOydhCDrj4zroKTspJjrj4Qg7JqU7LKtIHJvdXRlIOyekOyytChbMW1dIOuTsSnripQg67O07KG07ZWc64ukLlxuICBjb25zdCByZXF1ZXN0ZWRNb2RlbE5hbWUgPSB3aXRoUHJvdmlkZXJQcmVmaXgoXG4gICAgYXJncy5tb2RlbCxcbiAgICBhcmdzLm1vZGVsID8/IHJlc3VsdC5yZXF1ZXN0ZWRNb2RlbCA/PyByZXN1bHQubW9kZWwsXG4gICk7XG4gIGNvbnN0IHNlcnZlZE1vZGVsTmFtZSA9IHdpdGhQcm92aWRlclByZWZpeChhcmdzLm1vZGVsLCByZXN1bHQubW9kZWwpO1xuXG4gIC8vIGdlbmVyYXRlIHN0ZXAg6riw66GdXG4gIGF3YWl0IFJlcXVlc3RMb2dNb2RlbC5hcHBlbmRTdGVwKHJlcXVlc3RMb2dJZCwge1xuICAgIHN0ZXBfaW5kZXg6IHN0ZXBJbmRleCxcbiAgICB0eXBlOiBcImdlbmVyYXRlXCIsXG4gICAgbW9kZWxfbmFtZTogc2VydmVkTW9kZWxOYW1lLFxuICAgIHJlcXVlc3RlZF9tb2RlbF9uYW1lOiByZXF1ZXN0ZWRNb2RlbE5hbWUsXG4gICAgZmFsbGJhY2tfY291bnQ6IHJlc3VsdC5tb2RlbEZhbGxiYWNrcz8ubGVuZ3RoID8/IDAsXG4gICAgaW5wdXRfdG9rZW5zOiByZXN1bHQudXNhZ2UuaW5wdXRfdG9rZW5zLFxuICAgIG91dHB1dF90b2tlbnM6IHJlc3VsdC51c2FnZS5vdXRwdXRfdG9rZW5zLFxuICAgIGNhY2hlX3JlYWRfdG9rZW5zOiByZXN1bHQudXNhZ2UuY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMsXG4gICAgY2FjaGVfY3JlYXRpb25fdG9rZW5zOiByZXN1bHQudXNhZ2UuY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zLFxuICAgIGNhY2hlX2NyZWF0aW9uXzVtX3Rva2VuczogcmVzdWx0LnVzYWdlLmNhY2hlX2NyZWF0aW9uXzVtX2lucHV0X3Rva2VucyxcbiAgICBjYWNoZV9jcmVhdGlvbl8xaF90b2tlbnM6IHJlc3VsdC51c2FnZS5jYWNoZV9jcmVhdGlvbl8xaF9pbnB1dF90b2tlbnMsXG4gICAgY29zdF91c2Q6IE1hdGgucm91bmQocmVzdWx0LmNvc3RVc2QgKiAxXzAwMF8wMDApLFxuICAgIGNvc3Rfc291cmNlOiByZXN1bHQuY29zdFNvdXJjZSxcbiAgICBkdXJhdGlvbl9tczogcmVzdWx0LmR1cmF0aW9uTXMsXG4gICAgdHRmdF9tczogcmVzdWx0LnR0ZnRNcyxcbiAgICBmaW5pc2hfcmVhc29uOiByZXN1bHQuZmluaXNoUmVhc29uLFxuICB9KTtcbiAgcmV0dXJuIHsgcmVxdWVzdGVkTW9kZWxOYW1lLCBzZXJ2ZWRNb2RlbE5hbWUgfTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFmdGVyUXVlcnkoXG4gIHJlcXVlc3RMb2dJZDogbnVtYmVyLFxuICBzdGVwSW5kZXg6IG51bWJlcixcbiAgYXJnczogUXVlcnlJbnB1dCxcbiAgcmVzdWx0OiBRdWVyeU91dHB1dCxcbik6IFByb21pc2U8UnVuTGlmZWN5Y2xlUmVzdWx0PiB7XG4gIGNvbnN0IHsgcmVxdWVzdGVkTW9kZWxOYW1lLCBzZXJ2ZWRNb2RlbE5hbWUgfSA9IGF3YWl0IGFwcGVuZEdlbmVyYXRlU3RlcChcbiAgICByZXF1ZXN0TG9nSWQsXG4gICAgc3RlcEluZGV4LFxuICAgIGFyZ3MsXG4gICAgcmVzdWx0LFxuICApO1xuXG4gIGNvbnN0IGltYWdlUGFydHMgPSBnZXRJbWFnZVBhcnRzKHJlc3VsdCk7XG4gIGNvbnN0IGltYWdlQ29zdE1pY3JvVXNkID0gZXN0aW1hdGVJbWFnZUdlbmVyYXRpb25Db3N0TWljcm9Vc2QoXG4gICAgcmVzdWx0LFxuICAgIGFyZ3MuaW1hZ2VHZW5lcmF0aW9uT3B0aW9ucyxcbiAgKTtcbiAgZm9yIChjb25zdCBzdGVwIG9mIGJ1aWxkSW1hZ2VHZW5lcmF0aW9uVG9vbFN0ZXBzKGFyZ3MsIGltYWdlUGFydHMsIHN0ZXBJbmRleCkpIHtcbiAgICBhd2FpdCBSZXF1ZXN0TG9nTW9kZWwuYXBwZW5kU3RlcChyZXF1ZXN0TG9nSWQsIHN0ZXApO1xuICB9XG5cbiAgaWYgKHJlc3VsdC5maW5pc2hSZWFzb24gPT09IFwidG9vbC1jYWxsc1wiKSB7XG4gICAgLy8gdG9vbC1jYWxsIHN0ZXDsnYQg7KaJ7IucIOq4sOuhne2VmOqzoCwg64uk7J2MIGZvbGxvdy11cOydtCDqsJnsnYAgcm937JeQIOqysOqzvOulvCDssYTsmrTri6QuXG4gICAgY29uc3QgdG9vbENhbGxzID0gcmVzdWx0LmNvbnRlbnQuZmlsdGVyKChjKSA9PiBjLnR5cGUgPT09IFwidG9vbC1jYWxsXCIpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdG9vbENhbGxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB0YyA9IHRvb2xDYWxsc1tpXSE7XG4gICAgICBpZiAodGMudHlwZSAhPT0gXCJ0b29sLWNhbGxcIikgY29udGludWU7XG4gICAgICBhd2FpdCBSZXF1ZXN0TG9nTW9kZWwuYXBwZW5kU3RlcChyZXF1ZXN0TG9nSWQsIHtcbiAgICAgICAgc3RlcF9pbmRleDogc3RlcEluZGV4LFxuICAgICAgICB0eXBlOiBcInRvb2xfY2FsbFwiLFxuICAgICAgICB0b29sX2NhbGxfaW5kZXg6IGltYWdlUGFydHMubGVuZ3RoICsgaSxcbiAgICAgICAgdG9vbF9jYWxsX2lkOiB0Yy50b29sQ2FsbElkLFxuICAgICAgICB0b29sX25hbWU6IHRjLnRvb2xOYW1lLFxuICAgICAgICB0b29sX2FyZ3M6IHRjLmlucHV0LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgcnVuQ29udGV4dDogeyByZXF1ZXN0TG9nSWQgfSB9O1xuICB9XG5cbiAgLy8gZmluaXNoUmVhc29uID09PSBcInN0b3BcIiDihpIgcnVuIOyiheujjCAo7KCE7LK0IHN0ZXAgdXNhZ2Ug7ZWp7IKwKVxuICBjb25zdCBhZ2cgPSBhd2FpdCBSZXF1ZXN0TG9nTW9kZWwuYWdncmVnYXRlU3RlcFVzYWdlKHJlcXVlc3RMb2dJZCk7XG4gIGNvbnN0IHJlc3BvbnNlVGV4dCA9IGZvcm1hdFJlc3BvbnNlRm9yTG9nKHJlc3VsdCk7XG4gIGF3YWl0IFJlcXVlc3RMb2dNb2RlbC5maW5pc2hSdW4ocmVxdWVzdExvZ0lkLCB7XG4gICAgc3RhdHVzOiBcInN1Y2NlZWRlZFwiLFxuICAgIHJlc3BvbnNlOiByZXNwb25zZVRleHQsXG4gICAgLy8gc3RydWN0dXJlZCDsmpTssq3rp4wg7YyQ7KCV7ZWc64ukLiBkZXRpIOuwsOy5mOydmCBicm9rZW4gSlNPTiDrpZjrpbwg66qp66Gd7JeQ7IScIOuwlOuhnFxuICAgIC8vIOq1rOuzhO2VmOq4sCDsnITtlZwg6riw66Gd7J2066mwLCDruYRzdHJ1Y3R1cmVkIOyalOyyreydgCBudWxsIOuhnCDrgqjripTri6QuXG4gICAgcmVzcG9uc2VfanNvbl9vazogYXJncy5qc29uU2NoZW1hID8gaXNQYXJzZWFibGVKc29uKHJlc3BvbnNlVGV4dCkgOiBudWxsLFxuICAgIHRva2VuX25hbWU6IHJlc3VsdC50b2tlbk5hbWUsXG4gICAgaW5wdXRfdG9rZW5zOiBhZ2cuaW5wdXRfdG9rZW5zLFxuICAgIG91dHB1dF90b2tlbnM6IGFnZy5vdXRwdXRfdG9rZW5zLFxuICAgIGNhY2hlX3JlYWRfdG9rZW5zOiBhZ2cuY2FjaGVfcmVhZF90b2tlbnMsXG4gICAgY2FjaGVfY3JlYXRpb25fdG9rZW5zOiBhZ2cuY2FjaGVfY3JlYXRpb25fdG9rZW5zLFxuICAgIGNhY2hlX2NyZWF0aW9uXzVtX3Rva2VuczogYWdnLmNhY2hlX2NyZWF0aW9uXzVtX3Rva2VucyxcbiAgICBjYWNoZV9jcmVhdGlvbl8xaF90b2tlbnM6IGFnZy5jYWNoZV9jcmVhdGlvbl8xaF90b2tlbnMsXG4gICAgZHVyYXRpb25fbXM6IGFnZy5kdXJhdGlvbl9tcyxcbiAgICAvLyBtdWx0aS1zdGVwIHJ1biDrtoDrqqjsnZgg66qo64247J2AIOy1nOyihSB0dXJu7J2EIOyEnOu5me2VnCDrqqjrjbjsnbTri6QuXG4gICAgcmVxdWVzdGVkX21vZGVsX25hbWU6IHJlcXVlc3RlZE1vZGVsTmFtZSxcbiAgICBtb2RlbF9uYW1lOiBzZXJ2ZWRNb2RlbE5hbWUsXG4gICAgZmFsbGJhY2tfY291bnQ6IGFnZy5mYWxsYmFja19jb3VudCxcbiAgICBzZXJ2aWNlX3RpZXI6IGFyZ3MubW9kZWw/LnN0YXJ0c1dpdGgoXCJvcGVuYWkvXCIpID8gKGFyZ3Muc2VydmljZVRpZXIgPz8gbnVsbCkgOiBudWxsLFxuICAgIGNvc3RfdXNkOiBhZ2cuY29zdF91c2QsXG4gICAgY29zdF9zb3VyY2U6IGFnZy5jb3N0X3NvdXJjZSxcbiAgICBpbWFnZV9jb3N0X3VzZDogaW1hZ2VDb3N0TWljcm9Vc2QsXG4gICAgLi4uKGltYWdlUGFydHMubGVuZ3RoID4gMCA/IHsgaXNfaW1hZ2VfZ2VuZXJhdGlvbjogdHJ1ZSB9IDoge30pLFxuICAgIGltYWdlX2Nvc3RfbWV0aG9kOlxuICAgICAgaW1hZ2VDb3N0TWljcm9Vc2QgIT09IG51bGxcbiAgICAgICAgPyBpbWFnZUdlbmVyYXRpb25Db3N0TWV0aG9kKGFyZ3MuaW1hZ2VHZW5lcmF0aW9uT3B0aW9ucywgcmVzdWx0KVxuICAgICAgICA6IG51bGwsXG4gICAgaGlzdG9yeTogZmlsdGVySGlzdG9yeUZvclN0b3JhZ2UoYXJncy5oaXN0b3J5KSxcbiAgfSk7XG5cbiAgcmV0dXJuIHt9O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmluaXNoUnVuV2l0aEVycm9yKFxuICByZXF1ZXN0TG9nSWQ6IG51bWJlcixcbiAgZXJyb3JNZXNzYWdlOiBzdHJpbmcsXG4gIGFyZ3M/OiBRdWVyeUlucHV0LFxuICBjb21wbGV0ZWRTdGVwPzogeyBzdGVwSW5kZXg6IG51bWJlcjsgcmVzdWx0OiBRdWVyeU91dHB1dCB9LFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGF3YWl0IGZpbmlzaFRlcm1pbmFsUnVuKHJlcXVlc3RMb2dJZCwgXCJlcnJvclwiLCBlcnJvck1lc3NhZ2UsIGFyZ3MsIGNvbXBsZXRlZFN0ZXApO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmluaXNoUnVuQWJvcnRlZChcbiAgcmVxdWVzdExvZ0lkOiBudW1iZXIsXG4gIGFyZ3M/OiBRdWVyeUlucHV0LFxuICBjb21wbGV0ZWRTdGVwPzogeyBzdGVwSW5kZXg6IG51bWJlcjsgcmVzdWx0OiBRdWVyeU91dHB1dCB9LFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGF3YWl0IGZpbmlzaFRlcm1pbmFsUnVuKHJlcXVlc3RMb2dJZCwgXCJhYm9ydGVkXCIsIFwiY2xpZW50IGRpc2Nvbm5lY3RlZFwiLCBhcmdzLCBjb21wbGV0ZWRTdGVwKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZmluaXNoVGVybWluYWxSdW4oXG4gIHJlcXVlc3RMb2dJZDogbnVtYmVyLFxuICBzdGF0dXM6IFwiZXJyb3JcIiB8IFwiYWJvcnRlZFwiLFxuICBlcnJvck1lc3NhZ2U6IHN0cmluZyxcbiAgYXJncz86IFF1ZXJ5SW5wdXQsXG4gIGNvbXBsZXRlZFN0ZXA/OiB7IHN0ZXBJbmRleDogbnVtYmVyOyByZXN1bHQ6IFF1ZXJ5T3V0cHV0IH0sXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgdHJ5IHtcbiAgICBpZiAoY29tcGxldGVkU3RlcCAmJiBhcmdzKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBhcHBlbmRHZW5lcmF0ZVN0ZXAocmVxdWVzdExvZ0lkLCBjb21wbGV0ZWRTdGVwLnN0ZXBJbmRleCwgYXJncywgY29tcGxldGVkU3RlcC5yZXN1bHQpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgYGFwcGVuZEdlbmVyYXRlU3RlcCBmYWlsZWQgd2hpbGUgZmluaXNoaW5nICR7c3RhdHVzfTogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICBsZXQgYWdncmVnYXRlOiBBd2FpdGVkPFJldHVyblR5cGU8dHlwZW9mIFJlcXVlc3RMb2dNb2RlbC5hZ2dyZWdhdGVTdGVwVXNhZ2U+PiB8IHVuZGVmaW5lZDtcbiAgICB0cnkge1xuICAgICAgYWdncmVnYXRlID0gYXdhaXQgUmVxdWVzdExvZ01vZGVsLmFnZ3JlZ2F0ZVN0ZXBVc2FnZShyZXF1ZXN0TG9nSWQpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgYWdncmVnYXRlU3RlcFVzYWdlIGZhaWxlZCB3aGlsZSBmaW5pc2hpbmcgJHtzdGF0dXN9OiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfWApO1xuICAgIH1cblxuICAgIGF3YWl0IFJlcXVlc3RMb2dNb2RlbC5maW5pc2hSdW4ocmVxdWVzdExvZ0lkLCB7XG4gICAgICBzdGF0dXMsXG4gICAgICBlcnJvcl9tZXNzYWdlOiBlcnJvck1lc3NhZ2UsXG4gICAgICBoaXN0b3J5OiBhcmdzID8gZmlsdGVySGlzdG9yeUZvclN0b3JhZ2UoYXJncy5oaXN0b3J5KSA6IHVuZGVmaW5lZCxcbiAgICAgIC4uLihjb21wbGV0ZWRTdGVwXG4gICAgICAgID8ge1xuICAgICAgICAgICAgdG9rZW5fbmFtZTogY29tcGxldGVkU3RlcC5yZXN1bHQudG9rZW5OYW1lLFxuICAgICAgICAgICAgcmVxdWVzdGVkX21vZGVsX25hbWU6IHdpdGhQcm92aWRlclByZWZpeChcbiAgICAgICAgICAgICAgYXJncz8ubW9kZWwsXG4gICAgICAgICAgICAgIGFyZ3M/Lm1vZGVsID8/IGNvbXBsZXRlZFN0ZXAucmVzdWx0LnJlcXVlc3RlZE1vZGVsID8/IGNvbXBsZXRlZFN0ZXAucmVzdWx0Lm1vZGVsLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIG1vZGVsX25hbWU6IHdpdGhQcm92aWRlclByZWZpeChhcmdzPy5tb2RlbCwgY29tcGxldGVkU3RlcC5yZXN1bHQubW9kZWwpLFxuICAgICAgICAgIH1cbiAgICAgICAgOiB7fSksXG4gICAgICAuLi4oYWdncmVnYXRlXG4gICAgICAgID8ge1xuICAgICAgICAgICAgaW5wdXRfdG9rZW5zOiBhZ2dyZWdhdGUuaW5wdXRfdG9rZW5zLFxuICAgICAgICAgICAgb3V0cHV0X3Rva2VuczogYWdncmVnYXRlLm91dHB1dF90b2tlbnMsXG4gICAgICAgICAgICBjYWNoZV9yZWFkX3Rva2VuczogYWdncmVnYXRlLmNhY2hlX3JlYWRfdG9rZW5zLFxuICAgICAgICAgICAgY2FjaGVfY3JlYXRpb25fdG9rZW5zOiBhZ2dyZWdhdGUuY2FjaGVfY3JlYXRpb25fdG9rZW5zLFxuICAgICAgICAgICAgY2FjaGVfY3JlYXRpb25fNW1fdG9rZW5zOiBhZ2dyZWdhdGUuY2FjaGVfY3JlYXRpb25fNW1fdG9rZW5zLFxuICAgICAgICAgICAgY2FjaGVfY3JlYXRpb25fMWhfdG9rZW5zOiBhZ2dyZWdhdGUuY2FjaGVfY3JlYXRpb25fMWhfdG9rZW5zLFxuICAgICAgICAgICAgZHVyYXRpb25fbXM6IGFnZ3JlZ2F0ZS5kdXJhdGlvbl9tcyxcbiAgICAgICAgICAgIGZhbGxiYWNrX2NvdW50OiBhZ2dyZWdhdGUuZmFsbGJhY2tfY291bnQsXG4gICAgICAgICAgICBjb3N0X3VzZDogYWdncmVnYXRlLmNvc3RfdXNkLFxuICAgICAgICAgICAgY29zdF9zb3VyY2U6IGFnZ3JlZ2F0ZS5jb3N0X3NvdXJjZSxcbiAgICAgICAgICB9XG4gICAgICAgIDoge30pLFxuICAgIH0pO1xuICB9IGNhdGNoIChlKSB7XG4gICAgbG9nZ2VyLmVycm9yKGBmaW5pc2hUZXJtaW5hbFJ1bigke3N0YXR1c30pIGZhaWxlZDogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBjbGVhbnVwU3RhbGVSdW5zKCk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoc3RhbGVDbGVhbnVwSW5GbGlnaHQpIHtcbiAgICBhd2FpdCBzdGFsZUNsZWFudXBJbkZsaWdodDtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICBpZiAobm93IC0gbGFzdFN0YWxlQ2xlYW51cFN0YXJ0ZWRBdCA8IFNUQUxFX0NMRUFOVVBfSU5URVJWQUxfTVMpIHJldHVybjtcbiAgbGFzdFN0YWxlQ2xlYW51cFN0YXJ0ZWRBdCA9IG5vdztcblxuICBjb25zdCBjbGVhbnVwID0gcGVyZm9ybVN0YWxlUnVuQ2xlYW51cCgpO1xuICBzdGFsZUNsZWFudXBJbkZsaWdodCA9IGNsZWFudXA7XG4gIHRyeSB7XG4gICAgYXdhaXQgY2xlYW51cDtcbiAgfSBmaW5hbGx5IHtcbiAgICBpZiAoc3RhbGVDbGVhbnVwSW5GbGlnaHQgPT09IGNsZWFudXApIHN0YWxlQ2xlYW51cEluRmxpZ2h0ID0gdW5kZWZpbmVkO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHBlcmZvcm1TdGFsZVJ1bkNsZWFudXAoKTogUHJvbWlzZTx2b2lkPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgZXJyb3JNZXNzYWdlID0gXCJ0b29sLWNhbGwgcnVuOiBubyBmb2xsb3ctdXAgd2l0aGluIDMwIG1pbnV0ZXNcIjtcbiAgICBjb25zdCBzdGFsZUlkcyA9IGF3YWl0IFJlcXVlc3RMb2dNb2RlbC5leHBpcmVTdGFsZVRvb2xXYWl0aW5nUnVucyhcbiAgICAgIFNUQUxFX1JVTl9USFJFU0hPTERfTVMsXG4gICAgICBlcnJvck1lc3NhZ2UsXG4gICAgKTtcbiAgICBjb25zdCBjbGVhbmVkQ291bnQgPSBzdGFsZUlkcy5sZW5ndGg7XG4gICAgaWYgKGNsZWFuZWRDb3VudCA+IDApIHtcbiAgICAgIGxvZ2dlci5pbmZvKGBjbGVhbmVkIHVwICR7Y2xlYW5lZENvdW50fSBzdGFsZSBydW5uaW5nIHJlcXVlc3QgbG9nc2ApO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGxvZ2dlci5lcnJvcihgc3RhbGUgY2xlYW51cCBmYWlsZWQ6ICR7KGUgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFlQSxNQUFNLFNBQVMsVUFBVSxDQUFDLFNBQVMsZUFBZSxDQUFDO0FBQ25ELE1BQU0seUJBQXlCLE9BQVU7QUFDekMsTUFBTSw0QkFBNEIsS0FBSztBQUN2QyxJQUFJO0FBQ0osSUFBSSw0QkFBNEI7QUFDaEMsU0FBUyxtQkFDUCxZQUNBLE9BQ29CO0NBQ3BCLElBQUksQ0FBQyxPQUFPLE9BQU87Q0FDbkIsSUFBSSxNQUFNLFNBQVMsR0FBRyxHQUFHLE9BQU87Q0FDaEMsTUFBTSxRQUFRLFlBQVksUUFBUSxHQUFHLEtBQUs7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
230
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicWdyaWQtcnVuLWxpZmVjeWNsZS5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBwbGljYXRpb24vcWdyaWQvcWdyaWQtcnVuLWxpZmVjeWNsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnZXRMb2dnZXIgfSBmcm9tIFwiQGxvZ3RhcGUvbG9ndGFwZVwiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcblxuaW1wb3J0IHsgUmVxdWVzdExvZ01vZGVsIH0gZnJvbSBcIi4uL3JlcXVlc3QtbG9nL3JlcXVlc3QtbG9nLm1vZGVsXCI7XG5pbXBvcnQge1xuICBlc3RpbWF0ZUltYWdlR2VuZXJhdGlvbkNvc3RNaWNyb1VzZCxcbiAgaW1hZ2VHZW5lcmF0aW9uQ29zdE1ldGhvZCxcbn0gZnJvbSBcIi4vcWdyaWQtaW1hZ2UtZ2VuZXJhdGlvblwiO1xuaW1wb3J0IHtcbiAgYnVpbGRJbWFnZUdlbmVyYXRpb25Ub29sU3RlcHMsXG4gIGV4dHJhY3RJbnB1dEltYWdlc0ZvclRvb2xBcmdzLFxuICBmb3JtYXRSZXNwb25zZUZvckxvZyxcbiAgZ2V0SW1hZ2VQYXJ0cyxcbn0gZnJvbSBcIi4vcWdyaWQtcmVzcG9uc2UtZm9ybWF0XCI7XG5pbXBvcnQgeyB0eXBlIFFncmlkUnVuQ29udGV4dCwgdHlwZSBRdWVyeUlucHV0LCB0eXBlIFF1ZXJ5T3V0cHV0IH0gZnJvbSBcIi4vcWdyaWQudHlwZXNcIjtcbmltcG9ydCB7IGNvbXBvc2VTeXN0ZW1XaXRoU2NoZW1hQ29udHJhY3QgfSBmcm9tIFwiLi9zY2hlbWEtcHJvbXB0XCI7XG5cbmNvbnN0IGxvZ2dlciA9IGdldExvZ2dlcihbXCJxZ3JpZFwiLCBcInJ1bi1saWZlY3ljbGVcIl0pO1xuY29uc3QgU1RBTEVfUlVOX1RIUkVTSE9MRF9NUyA9IDMwICogNjAgKiAxMDAwO1xuY29uc3QgU1RBTEVfQ0xFQU5VUF9JTlRFUlZBTF9NUyA9IDYwICogMTAwMDtcbmxldCBzdGFsZUNsZWFudXBJbkZsaWdodDogUHJvbWlzZTx2b2lkPiB8IHVuZGVmaW5lZDtcbmxldCBsYXN0U3RhbGVDbGVhbnVwU3RhcnRlZEF0ID0gMDtcblxuZnVuY3Rpb24gd2l0aFByb3ZpZGVyUHJlZml4KFxuICByb3V0ZU1vZGVsOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIG1vZGVsOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoIW1vZGVsKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gIGlmIChtb2RlbC5pbmNsdWRlcyhcIi9cIikpIHJldHVybiBtb2RlbDtcbiAgY29uc3Qgc2xhc2ggPSByb3V0ZU1vZGVsPy5pbmRleE9mKFwiL1wiKSA/PyAtMTtcbiAgY29uc3QgcHJvdmlkZXIgPSBzbGFzaCA+IDAgPyByb3V0ZU1vZGVsPy5zbGljZSgwLCBzbGFzaCkgOiB1bmRlZmluZWQ7XG5cbiAgcmV0dXJuIHByb3ZpZGVyID8gYCR7cHJvdmlkZXJ9LyR7bW9kZWx9YCA6IG1vZGVsO1xufVxuXG4vKipcbiAqIGhpc3RvcnnripQg7JuQ67O4IOq3uOuMgOuhnCDsoIDsnqXtlZjquLDrs7Tri6TripQsIHJ1biDrtoTshJ3sl5Ag7ZWE7JqU7ZWcIHVzZXIvYXNzaXN0YW50IOygleuztOunjCDtlYTthLDrp4HtlbTshJwg7KCA7J6lXG4gKi9cbi8vIEtlcHQgaXRlbXMgYXJlIHN0b3JlZCBhcyBzZW50OyBvbmx5IHRoZSB0eXBlL3JvbGUgdGhhdCBzZWxlY3QgdGhlbSBhcmUgZGVjb2RlZC5cbmNvbnN0IFN0b3JlZEhpc3RvcnlNZXNzYWdlID0gei5sb29zZU9iamVjdCh7XG4gIHR5cGU6IHoubGl0ZXJhbChcIm1lc3NhZ2VcIiksXG4gIHJvbGU6IHouZW51bShbXCJ1c2VyXCIsIFwiYXNzaXN0YW50XCJdKSxcbn0pO1xuXG50eXBlIFN0b3JlZEhpc3RvcnlNZXNzYWdlID0gei5pbmZlcjx0eXBlb2YgU3RvcmVkSGlzdG9yeU1lc3NhZ2U+O1xuXG5mdW5jdGlvbiBmaWx0ZXJIaXN0b3J5Rm9yU3RvcmFnZShcbiAgcmF3SGlzdG9yeTogc3RyaW5nIHwgdW5kZWZpbmVkLFxuKTogU3RvcmVkSGlzdG9yeU1lc3NhZ2VbXSB8IHVuZGVmaW5lZCB7XG4gIGlmICghcmF3SGlzdG9yeSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICB0cnkge1xuICAgIGNvbnN0IGl0ZW1zID0gei5hcnJheSh6LnVua25vd24oKSkucGFyc2UoSlNPTi5wYXJzZShyYXdIaXN0b3J5KSk7XG5cbiAgICBjb25zdCBmaWx0ZXJlZCA9IGl0ZW1zLmZsYXRNYXAoKGl0ZW0pID0+IHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBTdG9yZWRIaXN0b3J5TWVzc2FnZS5zYWZlUGFyc2UoaXRlbSk7XG5cbiAgICAgIHJldHVybiBtZXNzYWdlLnN1Y2Nlc3MgPyBbbWVzc2FnZS5kYXRhXSA6IFtdO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGZpbHRlcmVkLmxlbmd0aCA+IDAgPyBmaWx0ZXJlZCA6IHVuZGVmaW5lZDtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc1BhcnNlYWJsZUpzb24odGV4dDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgSlNPTi5wYXJzZSh0ZXh0KTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgUnVuTGlmZWN5Y2xlUmVzdWx0ID0ge1xuICBydW5Db250ZXh0PzogUWdyaWRSdW5Db250ZXh0O1xufTtcblxuLyoqXG4gKiBsb2dnZXItZW5hYmxlZCBxdWVyeS9zdHJlYW0g7J2R64u1IOyghO2bhOyXkCDtmLjstpwuXG4gKlxuICogMSkgYmVmb3JlUXVlcnk6IHJ1biDsg53shLEv6rOE7IaNICsgdG9vbCByZXN1bHQg7JmE66OMICsgc3RhbGUgdG9vbC13YWl0IGNsZWFudXBcbiAqIDIpIGFmdGVyUXVlcnk6IGdlbmVyYXRlIHN0ZXAgKyB0b29sLWNhbGwgc3RlcCArIGZpbmlzaC9rZWVwLW9wZW5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGJlZm9yZVF1ZXJ5KGFyZ3M6IFF1ZXJ5SW5wdXQpOiBQcm9taXNlPHtcbiAgcmVxdWVzdExvZ0lkOiBudW1iZXI7XG4gIHN0ZXBJbmRleDogbnVtYmVyO1xufT4ge1xuICBsZXQgcmVxdWVzdExvZ0lkOiBudW1iZXI7XG4gIGxldCBzdGVwSW5kZXggPSAwO1xuXG4gIC8vIHJlcXVlc3RMb2dJZCDqsIAg7J6I7J2EIOuVjOunjCDquLDsobQgcnVuIOyXsOyepS4gdGhyZWFkQ29vcmQg66eMIOyeiOuKlCBjb252IOuKlCDsg4ggcnVuIOycvOuhnCDsi5zsnpEuXG4gIC8vIGNvbnRpbnVhdGlvbiDsnYAgY3JlYXRlUnVuIOydhCDqsbTrhIjrm7Drr4DroZwgcnVuIOydmCB0b29scyDripQg7LKrIOyKpO2FnSDsnqXssKnrtoTsnLzroZwg6rOg7KCV65Cc64ukIOKAlFxuICAvLyBBSSBTREsgcHJlcGFyZVN0ZXAvYWN0aXZlVG9vbHMg66GcIOyKpO2FneuniOuLpCDtiLTshYvsnbQg67CU64CM7Ja064+EIOuhnOq3uOyXkOuKlCDrsJjsmIHrkJjsp4Ag7JWK64qU64ukLlxuICBpZiAoYXJncy5ydW5Db250ZXh0Py5yZXF1ZXN0TG9nSWQgIT09IHVuZGVmaW5lZCkge1xuICAgIHJlcXVlc3RMb2dJZCA9IGFyZ3MucnVuQ29udGV4dC5yZXF1ZXN0TG9nSWQ7XG4gICAgLy8gY2xlYW51cOqzvCDqsJnsnYAgREIgYWR2aXNvcnkgbG9ja+ydhCDsnqHqs6AgdG9vbCDqsrDqs7wg67CY7JiBICsg64uk7J2MIHN0ZXAg7JiI7JW97J2EIO2VnFxuICAgIC8vIHRyYW5zYWN0aW9u7JeQ7IScIOyymOumrO2VnOuLpC4g7Jes65+sIHFncmlkIO2UhOuhnOyEuOyKpCDsgqzsnbTsl5DshJzrj4Qgc3RhbGUgZXhwaXJ56rCAXG4gICAgLy8g64+E7LCpIOykkeyduCBmb2xsb3ctdXDsnYQgZXJyb3LroZwg642u7Ja07JOw7KeAIOuqu+2VnOuLpC5cbiAgICBzdGVwSW5kZXggPSBhd2FpdCBSZXF1ZXN0TG9nTW9kZWwuY29udGludWVUb29sUnVuKHJlcXVlc3RMb2dJZCwgYXJncy50b29sUmVzdWx0cyA/PyBbXSk7XG4gICAgYXdhaXQgY2xlYW51cFN0YWxlUnVucygpO1xuICB9IGVsc2Uge1xuICAgIGF3YWl0IGNsZWFudXBTdGFsZVJ1bnMoKTtcbiAgICBjb25zdCBpbnB1dEltYWdlcyA9IGV4dHJhY3RJbnB1dEltYWdlc0ZvclRvb2xBcmdzKGFyZ3MpO1xuICAgIHJlcXVlc3RMb2dJZCA9IGF3YWl0IFJlcXVlc3RMb2dNb2RlbC5jcmVhdGVSdW4oe1xuICAgICAgdXNlcl9wcm9tcHQ6IGFyZ3MucHJvbXB0LFxuICAgICAgc3lzdGVtX3Byb21wdDogYXJncy5tb2RlbD8uc3RhcnRzV2l0aChcImFudGhyb3BpYy9cIilcbiAgICAgICAgPyBjb21wb3NlU3lzdGVtV2l0aFNjaGVtYUNvbnRyYWN0KGFyZ3Muc3lzdGVtLCBhcmdzKVxuICAgICAgICA6IGFyZ3Muc3lzdGVtLFxuICAgICAgcmVxdWVzdGVkX21vZGVsX25hbWU6IGFyZ3MubW9kZWwsXG4gICAgICBlZmZvcnQ6IGFyZ3MudGhpbmtpbmcgPT09IGZhbHNlID8gdW5kZWZpbmVkIDogYXJncy5lZmZvcnQsXG4gICAgICBzZXJ2aWNlX3RpZXI6IGFyZ3MubW9kZWw/LnN0YXJ0c1dpdGgoXCJvcGVuYWkvXCIpID8gYXJncy5zZXJ2aWNlVGllciA6IHVuZGVmaW5lZCxcbiAgICAgIHByb2plY3RfbmFtZTogYXJncy5wcm9qZWN0TmFtZSxcbiAgICAgIGhpc3Rvcnk6IGZpbHRlckhpc3RvcnlGb3JTdG9yYWdlKGFyZ3MuaGlzdG9yeSksXG4gICAgICBpbnB1dF9pbWFnZXM6IGlucHV0SW1hZ2VzLmxlbmd0aCA+IDAgPyBpbnB1dEltYWdlcyA6IHVuZGVmaW5lZCxcbiAgICAgIHRvb2xzOiBhcmdzLnRvb2xzPy5sZW5ndGggPyBhcmdzLnRvb2xzIDogdW5kZWZpbmVkLFxuICAgICAgaXNfaW1hZ2VfZ2VuZXJhdGlvbjogYXJncy5pbWFnZUdlbmVyYXRpb24gPT09IFwiYXV0b1wiID8gZmFsc2UgOiBhcmdzLmltYWdlR2VuZXJhdGlvbixcbiAgICAgIGpzb25fc2NoZW1hOiBhcmdzLmpzb25TY2hlbWEgPz8gbnVsbCxcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiB7IHJlcXVlc3RMb2dJZCwgc3RlcEluZGV4IH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGFwcGVuZEdlbmVyYXRlU3RlcChcbiAgcmVxdWVzdExvZ0lkOiBudW1iZXIsXG4gIHN0ZXBJbmRleDogbnVtYmVyLFxuICBhcmdzOiBRdWVyeUlucHV0LFxuICByZXN1bHQ6IFF1ZXJ5T3V0cHV0LFxuKSB7XG4gIC8vIHByb3ZpZGVy6rCAIGNhbm9uaWNhbCBtb2RlbOydhCDrj4zroKTspJjrj4Qg7JqU7LKtIHJvdXRlIOyekOyytChbMW1dIOuTsSnripQg67O07KG07ZWc64ukLlxuICBjb25zdCByZXF1ZXN0ZWRNb2RlbE5hbWUgPSB3aXRoUHJvdmlkZXJQcmVmaXgoXG4gICAgYXJncy5tb2RlbCxcbiAgICBhcmdzLm1vZGVsID8/IHJlc3VsdC5yZXF1ZXN0ZWRNb2RlbCA/PyByZXN1bHQubW9kZWwsXG4gICk7XG5cbiAgY29uc3Qgc2VydmVkTW9kZWxOYW1lID0gd2l0aFByb3ZpZGVyUHJlZml4KGFyZ3MubW9kZWwsIHJlc3VsdC5tb2RlbCk7XG5cbiAgLy8gZ2VuZXJhdGUgc3RlcCDquLDroZ1cbiAgYXdhaXQgUmVxdWVzdExvZ01vZGVsLmFwcGVuZFN0ZXAocmVxdWVzdExvZ0lkLCB7XG4gICAgc3RlcF9pbmRleDogc3RlcEluZGV4LFxuICAgIHR5cGU6IFwiZ2VuZXJhdGVcIixcbiAgICBtb2RlbF9uYW1lOiBzZXJ2ZWRNb2RlbE5hbWUsXG4gICAgcmVxdWVzdGVkX21vZGVsX25hbWU6IHJlcXVlc3RlZE1vZGVsTmFtZSxcbiAgICBmYWxsYmFja19jb3VudDogcmVzdWx0Lm1vZGVsRmFsbGJhY2tzPy5sZW5ndGggPz8gMCxcbiAgICBpbnB1dF90b2tlbnM6IHJlc3VsdC51c2FnZS5pbnB1dF90b2tlbnMsXG4gICAgb3V0cHV0X3Rva2VuczogcmVzdWx0LnVzYWdlLm91dHB1dF90b2tlbnMsXG4gICAgY2FjaGVfcmVhZF90b2tlbnM6IHJlc3VsdC51c2FnZS5jYWNoZV9yZWFkX2lucHV0X3Rva2VucyxcbiAgICBjYWNoZV9jcmVhdGlvbl90b2tlbnM6IHJlc3VsdC51c2FnZS5jYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMsXG4gICAgY2FjaGVfY3JlYXRpb25fNW1fdG9rZW5zOiByZXN1bHQudXNhZ2UuY2FjaGVfY3JlYXRpb25fNW1faW5wdXRfdG9rZW5zLFxuICAgIGNhY2hlX2NyZWF0aW9uXzFoX3Rva2VuczogcmVzdWx0LnVzYWdlLmNhY2hlX2NyZWF0aW9uXzFoX2lucHV0X3Rva2VucyxcbiAgICBjb3N0X3VzZDogTWF0aC5yb3VuZChyZXN1bHQuY29zdFVzZCAqIDFfMDAwXzAwMCksXG4gICAgY29zdF9zb3VyY2U6IHJlc3VsdC5jb3N0U291cmNlLFxuICAgIGR1cmF0aW9uX21zOiByZXN1bHQuZHVyYXRpb25NcyxcbiAgICB0dGZ0X21zOiByZXN1bHQudHRmdE1zLFxuICAgIGZpbmlzaF9yZWFzb246IHJlc3VsdC5maW5pc2hSZWFzb24sXG4gIH0pO1xuXG4gIHJldHVybiB7IHJlcXVlc3RlZE1vZGVsTmFtZSwgc2VydmVkTW9kZWxOYW1lIH07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhZnRlclF1ZXJ5KFxuICByZXF1ZXN0TG9nSWQ6IG51bWJlcixcbiAgc3RlcEluZGV4OiBudW1iZXIsXG4gIGFyZ3M6IFF1ZXJ5SW5wdXQsXG4gIHJlc3VsdDogUXVlcnlPdXRwdXQsXG4pOiBQcm9taXNlPFJ1bkxpZmVjeWNsZVJlc3VsdD4ge1xuICBjb25zdCB7IHJlcXVlc3RlZE1vZGVsTmFtZSwgc2VydmVkTW9kZWxOYW1lIH0gPSBhd2FpdCBhcHBlbmRHZW5lcmF0ZVN0ZXAoXG4gICAgcmVxdWVzdExvZ0lkLFxuICAgIHN0ZXBJbmRleCxcbiAgICBhcmdzLFxuICAgIHJlc3VsdCxcbiAgKTtcblxuICBjb25zdCBpbWFnZVBhcnRzID0gZ2V0SW1hZ2VQYXJ0cyhyZXN1bHQpO1xuXG4gIGNvbnN0IGltYWdlQ29zdE1pY3JvVXNkID0gZXN0aW1hdGVJbWFnZUdlbmVyYXRpb25Db3N0TWljcm9Vc2QoXG4gICAgcmVzdWx0LFxuICAgIGFyZ3MuaW1hZ2VHZW5lcmF0aW9uT3B0aW9ucyxcbiAgKTtcblxuICBmb3IgKGNvbnN0IHN0ZXAgb2YgYnVpbGRJbWFnZUdlbmVyYXRpb25Ub29sU3RlcHMoYXJncywgaW1hZ2VQYXJ0cywgc3RlcEluZGV4KSkge1xuICAgIGF3YWl0IFJlcXVlc3RMb2dNb2RlbC5hcHBlbmRTdGVwKHJlcXVlc3RMb2dJZCwgc3RlcCk7XG4gIH1cblxuICBpZiAocmVzdWx0LmZpbmlzaFJlYXNvbiA9PT0gXCJ0b29sLWNhbGxzXCIpIHtcbiAgICAvLyB0b29sLWNhbGwgc3RlcOydhCDsponsi5wg6riw66Gd7ZWY6rOgLCDri6TsnYwgZm9sbG93LXVw7J20IOqwmeydgCByb3fsl5Ag6rKw6rO866W8IOyxhOyatOuLpC5cbiAgICBjb25zdCB0b29sQ2FsbHMgPSByZXN1bHQuY29udGVudC5maWx0ZXIoKGMpID0+IGMudHlwZSA9PT0gXCJ0b29sLWNhbGxcIik7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRvb2xDYWxscy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgdGMgPSB0b29sQ2FsbHNbaV0hO1xuXG4gICAgICBpZiAodGMudHlwZSAhPT0gXCJ0b29sLWNhbGxcIikgY29udGludWU7XG4gICAgICBhd2FpdCBSZXF1ZXN0TG9nTW9kZWwuYXBwZW5kU3RlcChyZXF1ZXN0TG9nSWQsIHtcbiAgICAgICAgc3RlcF9pbmRleDogc3RlcEluZGV4LFxuICAgICAgICB0eXBlOiBcInRvb2xfY2FsbFwiLFxuICAgICAgICB0b29sX2NhbGxfaW5kZXg6IGltYWdlUGFydHMubGVuZ3RoICsgaSxcbiAgICAgICAgdG9vbF9jYWxsX2lkOiB0Yy50b29sQ2FsbElkLFxuICAgICAgICB0b29sX25hbWU6IHRjLnRvb2xOYW1lLFxuICAgICAgICB0b29sX2FyZ3M6IHRjLmlucHV0LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgcnVuQ29udGV4dDogeyByZXF1ZXN0TG9nSWQgfSB9O1xuICB9XG5cbiAgLy8gZmluaXNoUmVhc29uID09PSBcInN0b3BcIiDihpIgcnVuIOyiheujjCAo7KCE7LK0IHN0ZXAgdXNhZ2Ug7ZWp7IKwKVxuICBjb25zdCBhZ2cgPSBhd2FpdCBSZXF1ZXN0TG9nTW9kZWwuYWdncmVnYXRlU3RlcFVzYWdlKHJlcXVlc3RMb2dJZCk7XG4gIGNvbnN0IHJlc3BvbnNlVGV4dCA9IGZvcm1hdFJlc3BvbnNlRm9yTG9nKHJlc3VsdCk7XG5cbiAgY29uc3QgZmluaXNoUGFyYW1zOiBQYXJhbWV0ZXJzPHR5cGVvZiBSZXF1ZXN0TG9nTW9kZWwuZmluaXNoUnVuPlsxXSA9IHtcbiAgICBzdGF0dXM6IFwic3VjY2VlZGVkXCIsXG4gICAgcmVzcG9uc2U6IHJlc3BvbnNlVGV4dCxcbiAgICAvLyBzdHJ1Y3R1cmVkIOyalOyyreunjCDtjJDsoJXtlZzri6QuIGRldGkg67Cw7LmY7J2YIGJyb2tlbiBKU09OIOulmOulvCDrqqnroZ3sl5DshJwg67CU66GcXG4gICAgLy8g6rWs67OE7ZWY6riwIOychO2VnCDquLDroZ3snbTrqbAsIOu5hHN0cnVjdHVyZWQg7JqU7LKt7J2AIG51bGwg66GcIOuCqOuKlOuLpC5cbiAgICByZXNwb25zZV9qc29uX29rOiBhcmdzLmpzb25TY2hlbWEgPyBpc1BhcnNlYWJsZUpzb24ocmVzcG9uc2VUZXh0KSA6IG51bGwsXG4gICAgdG9rZW5fbmFtZTogcmVzdWx0LnRva2VuTmFtZSxcbiAgICBpbnB1dF90b2tlbnM6IGFnZy5pbnB1dF90b2tlbnMsXG4gICAgb3V0cHV0X3Rva2VuczogYWdnLm91dHB1dF90b2tlbnMsXG4gICAgY2FjaGVfcmVhZF90b2tlbnM6IGFnZy5jYWNoZV9yZWFkX3Rva2VucyxcbiAgICBjYWNoZV9jcmVhdGlvbl90b2tlbnM6IGFnZy5jYWNoZV9jcmVhdGlvbl90b2tlbnMsXG4gICAgY2FjaGVfY3JlYXRpb25fNW1fdG9rZW5zOiBhZ2cuY2FjaGVfY3JlYXRpb25fNW1fdG9rZW5zLFxuICAgIGNhY2hlX2NyZWF0aW9uXzFoX3Rva2VuczogYWdnLmNhY2hlX2NyZWF0aW9uXzFoX3Rva2VucyxcbiAgICBkdXJhdGlvbl9tczogYWdnLmR1cmF0aW9uX21zLFxuICAgIC8vIG11bHRpLXN0ZXAgcnVuIOu2gOuqqOydmCDrqqjrjbjsnYAg7LWc7KKFIHR1cm7snYQg7ISc67mZ7ZWcIOuqqOuNuOydtOuLpC5cbiAgICByZXF1ZXN0ZWRfbW9kZWxfbmFtZTogcmVxdWVzdGVkTW9kZWxOYW1lLFxuICAgIG1vZGVsX25hbWU6IHNlcnZlZE1vZGVsTmFtZSxcbiAgICBmYWxsYmFja19jb3VudDogYWdnLmZhbGxiYWNrX2NvdW50LFxuICAgIHNlcnZpY2VfdGllcjogYXJncy5tb2RlbD8uc3RhcnRzV2l0aChcIm9wZW5haS9cIikgPyAoYXJncy5zZXJ2aWNlVGllciA/PyBudWxsKSA6IG51bGwsXG4gICAgY29zdF91c2Q6IGFnZy5jb3N0X3VzZCxcbiAgICBjb3N0X3NvdXJjZTogYWdnLmNvc3Rfc291cmNlLFxuICAgIGltYWdlX2Nvc3RfdXNkOiBpbWFnZUNvc3RNaWNyb1VzZCxcbiAgICBpbWFnZV9jb3N0X21ldGhvZDpcbiAgICAgIGltYWdlQ29zdE1pY3JvVXNkICE9PSBudWxsXG4gICAgICAgID8gaW1hZ2VHZW5lcmF0aW9uQ29zdE1ldGhvZChhcmdzLmltYWdlR2VuZXJhdGlvbk9wdGlvbnMsIHJlc3VsdClcbiAgICAgICAgOiBudWxsLFxuICAgIGhpc3Rvcnk6IGZpbHRlckhpc3RvcnlGb3JTdG9yYWdlKGFyZ3MuaGlzdG9yeSksXG4gIH07XG5cbiAgaWYgKGltYWdlUGFydHMubGVuZ3RoID4gMCkgZmluaXNoUGFyYW1zLmlzX2ltYWdlX2dlbmVyYXRpb24gPSB0cnVlO1xuICBhd2FpdCBSZXF1ZXN0TG9nTW9kZWwuZmluaXNoUnVuKHJlcXVlc3RMb2dJZCwgZmluaXNoUGFyYW1zKTtcblxuICByZXR1cm4ge307XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmaW5pc2hSdW5XaXRoRXJyb3IoXG4gIHJlcXVlc3RMb2dJZDogbnVtYmVyLFxuICBlcnJvck1lc3NhZ2U6IHN0cmluZyxcbiAgYXJncz86IFF1ZXJ5SW5wdXQsXG4gIGNvbXBsZXRlZFN0ZXA/OiB7IHN0ZXBJbmRleDogbnVtYmVyOyByZXN1bHQ6IFF1ZXJ5T3V0cHV0IH0sXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgZmluaXNoVGVybWluYWxSdW4ocmVxdWVzdExvZ0lkLCBcImVycm9yXCIsIGVycm9yTWVzc2FnZSwgYXJncywgY29tcGxldGVkU3RlcCk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmaW5pc2hSdW5BYm9ydGVkKFxuICByZXF1ZXN0TG9nSWQ6IG51bWJlcixcbiAgYXJncz86IFF1ZXJ5SW5wdXQsXG4gIGNvbXBsZXRlZFN0ZXA/OiB7IHN0ZXBJbmRleDogbnVtYmVyOyByZXN1bHQ6IFF1ZXJ5T3V0cHV0IH0sXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgZmluaXNoVGVybWluYWxSdW4ocmVxdWVzdExvZ0lkLCBcImFib3J0ZWRcIiwgXCJjbGllbnQgZGlzY29ubmVjdGVkXCIsIGFyZ3MsIGNvbXBsZXRlZFN0ZXApO1xufVxuXG5hc3luYyBmdW5jdGlvbiBmaW5pc2hUZXJtaW5hbFJ1bihcbiAgcmVxdWVzdExvZ0lkOiBudW1iZXIsXG4gIHN0YXR1czogXCJlcnJvclwiIHwgXCJhYm9ydGVkXCIsXG4gIGVycm9yTWVzc2FnZTogc3RyaW5nLFxuICBhcmdzPzogUXVlcnlJbnB1dCxcbiAgY29tcGxldGVkU3RlcD86IHsgc3RlcEluZGV4OiBudW1iZXI7IHJlc3VsdDogUXVlcnlPdXRwdXQgfSxcbik6IFByb21pc2U8dm9pZD4ge1xuICB0cnkge1xuICAgIGlmIChjb21wbGV0ZWRTdGVwICYmIGFyZ3MpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGFwcGVuZEdlbmVyYXRlU3RlcChyZXF1ZXN0TG9nSWQsIGNvbXBsZXRlZFN0ZXAuc3RlcEluZGV4LCBhcmdzLCBjb21wbGV0ZWRTdGVwLnJlc3VsdCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICBgYXBwZW5kR2VuZXJhdGVTdGVwIGZhaWxlZCB3aGlsZSBmaW5pc2hpbmcgJHtzdGF0dXN9OiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFN0cmluZyhlKX1gLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBhZ2dyZWdhdGU6IEF3YWl0ZWQ8UmV0dXJuVHlwZTx0eXBlb2YgUmVxdWVzdExvZ01vZGVsLmFnZ3JlZ2F0ZVN0ZXBVc2FnZT4+IHwgdW5kZWZpbmVkO1xuXG4gICAgdHJ5IHtcbiAgICAgIGFnZ3JlZ2F0ZSA9IGF3YWl0IFJlcXVlc3RMb2dNb2RlbC5hZ2dyZWdhdGVTdGVwVXNhZ2UocmVxdWVzdExvZ0lkKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgIGBhZ2dyZWdhdGVTdGVwVXNhZ2UgZmFpbGVkIHdoaWxlIGZpbmlzaGluZyAke3N0YXR1c306ICR7ZSBpbnN0YW5jZW9mIEVycm9yID8gZS5tZXNzYWdlIDogU3RyaW5nKGUpfWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IGZpbmlzaFBhcmFtczogUGFyYW1ldGVyczx0eXBlb2YgUmVxdWVzdExvZ01vZGVsLmZpbmlzaFJ1bj5bMV0gPSB7XG4gICAgICBzdGF0dXMsXG4gICAgICBlcnJvcl9tZXNzYWdlOiBlcnJvck1lc3NhZ2UsXG4gICAgICBoaXN0b3J5OiBhcmdzID8gZmlsdGVySGlzdG9yeUZvclN0b3JhZ2UoYXJncy5oaXN0b3J5KSA6IHVuZGVmaW5lZCxcbiAgICB9O1xuXG4gICAgaWYgKGNvbXBsZXRlZFN0ZXApIHtcbiAgICAgIGZpbmlzaFBhcmFtcy50b2tlbl9uYW1lID0gY29tcGxldGVkU3RlcC5yZXN1bHQudG9rZW5OYW1lO1xuXG4gICAgICBmaW5pc2hQYXJhbXMucmVxdWVzdGVkX21vZGVsX25hbWUgPSB3aXRoUHJvdmlkZXJQcmVmaXgoXG4gICAgICAgIGFyZ3M/Lm1vZGVsLFxuICAgICAgICBhcmdzPy5tb2RlbCA/PyBjb21wbGV0ZWRTdGVwLnJlc3VsdC5yZXF1ZXN0ZWRNb2RlbCA/PyBjb21wbGV0ZWRTdGVwLnJlc3VsdC5tb2RlbCxcbiAgICAgICk7XG5cbiAgICAgIGZpbmlzaFBhcmFtcy5tb2RlbF9uYW1lID0gd2l0aFByb3ZpZGVyUHJlZml4KGFyZ3M/Lm1vZGVsLCBjb21wbGV0ZWRTdGVwLnJlc3VsdC5tb2RlbCk7XG4gICAgfVxuXG4gICAgaWYgKGFnZ3JlZ2F0ZSkge1xuICAgICAgZmluaXNoUGFyYW1zLmlucHV0X3Rva2VucyA9IGFnZ3JlZ2F0ZS5pbnB1dF90b2tlbnM7XG4gICAgICBmaW5pc2hQYXJhbXMub3V0cHV0X3Rva2VucyA9IGFnZ3JlZ2F0ZS5vdXRwdXRfdG9rZW5zO1xuICAgICAgZmluaXNoUGFyYW1zLmNhY2hlX3JlYWRfdG9rZW5zID0gYWdncmVnYXRlLmNhY2hlX3JlYWRfdG9rZW5zO1xuICAgICAgZmluaXNoUGFyYW1zLmNhY2hlX2NyZWF0aW9uX3Rva2VucyA9IGFnZ3JlZ2F0ZS5jYWNoZV9jcmVhdGlvbl90b2tlbnM7XG4gICAgICBmaW5pc2hQYXJhbXMuY2FjaGVfY3JlYXRpb25fNW1fdG9rZW5zID0gYWdncmVnYXRlLmNhY2hlX2NyZWF0aW9uXzVtX3Rva2VucztcbiAgICAgIGZpbmlzaFBhcmFtcy5jYWNoZV9jcmVhdGlvbl8xaF90b2tlbnMgPSBhZ2dyZWdhdGUuY2FjaGVfY3JlYXRpb25fMWhfdG9rZW5zO1xuICAgICAgZmluaXNoUGFyYW1zLmR1cmF0aW9uX21zID0gYWdncmVnYXRlLmR1cmF0aW9uX21zO1xuICAgICAgZmluaXNoUGFyYW1zLmZhbGxiYWNrX2NvdW50ID0gYWdncmVnYXRlLmZhbGxiYWNrX2NvdW50O1xuICAgICAgZmluaXNoUGFyYW1zLmNvc3RfdXNkID0gYWdncmVnYXRlLmNvc3RfdXNkO1xuICAgICAgZmluaXNoUGFyYW1zLmNvc3Rfc291cmNlID0gYWdncmVnYXRlLmNvc3Rfc291cmNlO1xuICAgIH1cblxuICAgIGF3YWl0IFJlcXVlc3RMb2dNb2RlbC5maW5pc2hSdW4ocmVxdWVzdExvZ0lkLCBmaW5pc2hQYXJhbXMpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgbG9nZ2VyLmVycm9yKFxuICAgICAgYGZpbmlzaFRlcm1pbmFsUnVuKCR7c3RhdHVzfSkgZmFpbGVkOiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFN0cmluZyhlKX1gLFxuICAgICk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gY2xlYW51cFN0YWxlUnVucygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKHN0YWxlQ2xlYW51cEluRmxpZ2h0KSB7XG4gICAgYXdhaXQgc3RhbGVDbGVhbnVwSW5GbGlnaHQ7XG5cbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuXG4gIGlmIChub3cgLSBsYXN0U3RhbGVDbGVhbnVwU3RhcnRlZEF0IDwgU1RBTEVfQ0xFQU5VUF9JTlRFUlZBTF9NUykgcmV0dXJuO1xuICBsYXN0U3RhbGVDbGVhbnVwU3RhcnRlZEF0ID0gbm93O1xuXG4gIGNvbnN0IGNsZWFudXAgPSBwZXJmb3JtU3RhbGVSdW5DbGVhbnVwKCk7XG4gIHN0YWxlQ2xlYW51cEluRmxpZ2h0ID0gY2xlYW51cDtcblxuICB0cnkge1xuICAgIGF3YWl0IGNsZWFudXA7XG4gIH0gZmluYWxseSB7XG4gICAgaWYgKHN0YWxlQ2xlYW51cEluRmxpZ2h0ID09PSBjbGVhbnVwKSBzdGFsZUNsZWFudXBJbkZsaWdodCA9IHVuZGVmaW5lZDtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBwZXJmb3JtU3RhbGVSdW5DbGVhbnVwKCk6IFByb21pc2U8dm9pZD4ge1xuICB0cnkge1xuICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IFwidG9vbC1jYWxsIHJ1bjogbm8gZm9sbG93LXVwIHdpdGhpbiAzMCBtaW51dGVzXCI7XG5cbiAgICBjb25zdCBzdGFsZUlkcyA9IGF3YWl0IFJlcXVlc3RMb2dNb2RlbC5leHBpcmVTdGFsZVRvb2xXYWl0aW5nUnVucyhcbiAgICAgIFNUQUxFX1JVTl9USFJFU0hPTERfTVMsXG4gICAgICBlcnJvck1lc3NhZ2UsXG4gICAgKTtcblxuICAgIGNvbnN0IGNsZWFuZWRDb3VudCA9IHN0YWxlSWRzLmxlbmd0aDtcblxuICAgIGlmIChjbGVhbmVkQ291bnQgPiAwKSB7XG4gICAgICBsb2dnZXIuaW5mbyhgY2xlYW5lZCB1cCAke2NsZWFuZWRDb3VudH0gc3RhbGUgcnVubmluZyByZXF1ZXN0IGxvZ3NgKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBsb2dnZXIuZXJyb3IoYHN0YWxlIGNsZWFudXAgZmFpbGVkOiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFN0cmluZyhlKX1gKTtcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBaUJBLE1BQU0sU0FBUyxVQUFVLENBQUMsU0FBUyxlQUFlLENBQUM7QUFDbkQsTUFBTSx5QkFBeUIsT0FBVTtBQUN6QyxNQUFNLDRCQUE0QixLQUFLO0FBQ3ZDLElBQUk7QUFDSixJQUFJLDRCQUE0QjtBQUVoQyxTQUFTLG1CQUNQLFlBQ0EsT0FDb0I7Q0FDcEIsSUFBSSxDQUFDLE9BQU8sT0FBTztDQUVuQixJQUFJLE1BQU0sU0FBUyxHQUFHLEdBQUcsT0FBTztDQUNoQyxNQUFNLFFBQVEsWUFBWSxRQUFRLEdBQUcsS0FBSztDQUMxQyxNQUFNLFdBQVcsUUFBUSxJQUFJLFlBQVksTUFBTSxHQUFHLEtBQUssSUFBSTtDQUUzRCxPQUFPLFdBQVcsR0FBRyxTQUFTLEdBQUcsVUFBVTtB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