@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
@@ -0,0 +1,427 @@
1
+ import { isJsonObject, jsonValueSchema } from "../common/provider-types.js";
2
+ import { z } from "zod";
3
+ import { promisify } from "node:util";
4
+ import { zstdCompress } from "node:zlib";
5
+ //#region src/utils/providers/grok/grok-backend-protocol.ts
6
+ const GROK_DEFAULT_OUTPUT_SCHEMA_NAME = "qgrid_output";
7
+ function replayItem(item) {
8
+ if (item.type !== "reasoning") return item;
9
+ if (!item.encrypted_content) return void 0;
10
+ const replayed = {
11
+ type: "reasoning",
12
+ summary: item.summary ?? [],
13
+ encrypted_content: item.encrypted_content
14
+ };
15
+ if (item.id) replayed.id = item.id;
16
+ return replayed;
17
+ }
18
+ /** Builds the `/responses` body in the key order of the 1.0.60 golden capture. */
19
+ function buildGrokResponsesRequest(options) {
20
+ if (!options.model) throw new TypeError("Grok model is required");
21
+ if (!options.promptCacheKey) throw new TypeError("Grok prompt_cache_key is required");
22
+ if (options.maxOutputTokens !== void 0 && (!Number.isSafeInteger(options.maxOutputTokens) || options.maxOutputTokens <= 0)) throw new TypeError("maxOutputTokens must be a positive integer");
23
+ const input = [];
24
+ if (options.systemPrompt) input.push({
25
+ type: "message",
26
+ role: "system",
27
+ content: options.systemPrompt
28
+ });
29
+ for (const item of options.history) {
30
+ const wire = replayItem(item);
31
+ if (wire) input.push(wire);
32
+ }
33
+ const request = {
34
+ include: ["reasoning.encrypted_content", "no_inline_citations"],
35
+ input,
36
+ model: options.model,
37
+ prompt_cache_key: options.promptCacheKey,
38
+ reasoning: {
39
+ effort: options.effort,
40
+ summary: "concise"
41
+ },
42
+ store: false,
43
+ stream: true
44
+ };
45
+ if (options.outputSchema) request.text = { format: {
46
+ type: "json_schema",
47
+ name: options.outputSchema.name ?? "qgrid_output",
48
+ strict: true,
49
+ schema: options.outputSchema.schema
50
+ } };
51
+ if (options.tools?.length) request.tools = [...options.tools];
52
+ if (options.toolChoice !== void 0) request.tool_choice = options.toolChoice;
53
+ if (options.maxOutputTokens !== void 0) request.max_output_tokens = options.maxOutputTokens;
54
+ return request;
55
+ }
56
+ const zstdCompressAsync = promisify(zstdCompress);
57
+ /** zstd-compressed JSON body, as the 1.0.60 binary sends it (`content-encoding: zstd`). */
58
+ async function encodeGrokRequestBody(body) {
59
+ const compressed = await zstdCompressAsync(Buffer.from(JSON.stringify(body), "utf8"));
60
+ return {
61
+ bytes: new Uint8Array(compressed.buffer, compressed.byteOffset, compressed.byteLength),
62
+ contentEncoding: "zstd"
63
+ };
64
+ }
65
+ /** Plain JSON body; the proxy accepts it too (U0 item 1). */
66
+ function encodeGrokRequestBodyPlain(body) {
67
+ return {
68
+ bytes: new TextEncoder().encode(JSON.stringify(body)),
69
+ contentEncoding: void 0
70
+ };
71
+ }
72
+ var GrokProtocolError = class extends Error {
73
+ code;
74
+ constructor(message, code) {
75
+ super(message);
76
+ this.name = "GrokProtocolError";
77
+ this.code = code;
78
+ }
79
+ };
80
+ const count = z.number().int().nonnegative();
81
+ const WireUsage = z.object({
82
+ input_tokens: count.optional(),
83
+ input_tokens_details: z.object({ cached_tokens: count.optional() }).nullish(),
84
+ output_tokens: count.optional(),
85
+ output_tokens_details: z.object({ reasoning_tokens: count.optional() }).nullish(),
86
+ total_tokens: count.optional(),
87
+ num_sources_used: count.optional(),
88
+ num_server_side_tools_used: count.optional(),
89
+ cost_in_usd_ticks: count.optional(),
90
+ context_details: z.object({
91
+ input_tokens: count.optional(),
92
+ output_tokens: count.optional()
93
+ }).nullish()
94
+ });
95
+ const WireItem = z.object({ type: z.string() }).catchall(jsonValueSchema);
96
+ const WireResponse = z.looseObject({
97
+ id: z.string().optional(),
98
+ model: z.string().optional(),
99
+ status: z.string().optional(),
100
+ usage: WireUsage.nullish(),
101
+ output: z.array(WireItem).optional(),
102
+ incomplete_details: z.object({ reason: z.string().optional() }).nullish(),
103
+ error: z.object({
104
+ message: z.string().optional(),
105
+ code: z.string().optional()
106
+ }).nullish()
107
+ });
108
+ const WireEvent = z.looseObject({
109
+ type: z.string(),
110
+ response: WireResponse.optional(),
111
+ item: WireItem.optional(),
112
+ item_id: z.string().optional(),
113
+ delta: z.string().optional(),
114
+ message: z.string().optional(),
115
+ code: z.string().nullish(),
116
+ error: z.object({
117
+ message: z.string().optional(),
118
+ code: z.string().optional()
119
+ }).nullish()
120
+ });
121
+ function grokUsageFrom(usage) {
122
+ const inputTokens = usage.input_tokens ?? 0;
123
+ const outputTokens = usage.output_tokens ?? 0;
124
+ const result = {
125
+ inputTokens,
126
+ cachedInputTokens: usage.input_tokens_details?.cached_tokens ?? 0,
127
+ outputTokens,
128
+ reasoningTokens: usage.output_tokens_details?.reasoning_tokens ?? 0,
129
+ totalTokens: usage.total_tokens ?? inputTokens + outputTokens
130
+ };
131
+ if (usage.num_sources_used !== void 0) result.numSourcesUsed = usage.num_sources_used;
132
+ if (usage.num_server_side_tools_used !== void 0) result.numServerSideToolsUsed = usage.num_server_side_tools_used;
133
+ if (usage.cost_in_usd_ticks !== void 0) result.costInUsdTicks = usage.cost_in_usd_ticks;
134
+ if (usage.context_details?.input_tokens !== void 0) result.contextInputTokens = usage.context_details.input_tokens;
135
+ if (usage.context_details?.output_tokens !== void 0) result.contextOutputTokens = usage.context_details.output_tokens;
136
+ return result;
137
+ }
138
+ /**
139
+ * Normalizes one SSE block. Returns `undefined` for well-formed events that carry nothing a
140
+ * caller consumes (`response.in_progress`, part/done bookkeeping). Terminal events are
141
+ * `response.completed | response.incomplete | response.failed | error`; the proxy does not
142
+ * send `[DONE]`, and a `[DONE]` sentinel is ignored if one ever appears.
143
+ */
144
+ function normalizeGrokEvent(raw) {
145
+ if (raw.data.trim() === "[DONE]") return void 0;
146
+ let json;
147
+ try {
148
+ json = JSON.parse(raw.data);
149
+ } catch (error) {
150
+ throw new GrokProtocolError(`Invalid Grok SSE JSON: ${String(error)}`);
151
+ }
152
+ const withType = isJsonObject(json) && !("type" in json) && raw.event ? {
153
+ ...json,
154
+ type: raw.event
155
+ } : json;
156
+ const parsed = WireEvent.safeParse(withType);
157
+ if (!parsed.success) throw new GrokProtocolError(`Unexpected Grok SSE event shape: ${parsed.error.message}`);
158
+ const event = parsed.data;
159
+ const response = event.response;
160
+ switch (event.type) {
161
+ case "response.created": {
162
+ const created = { type: "created" };
163
+ if (response?.id) created.responseId = response.id;
164
+ if (response?.model) created.model = response.model;
165
+ return created;
166
+ }
167
+ case "response.output_text.delta":
168
+ if (event.delta === void 0) return void 0;
169
+ return event.item_id ? {
170
+ type: "text-delta",
171
+ text: event.delta,
172
+ itemId: event.item_id
173
+ } : {
174
+ type: "text-delta",
175
+ text: event.delta
176
+ };
177
+ case "response.reasoning_summary_text.delta":
178
+ if (event.delta === void 0) return void 0;
179
+ return event.item_id ? {
180
+ type: "reasoning-summary-delta",
181
+ text: event.delta,
182
+ itemId: event.item_id
183
+ } : {
184
+ type: "reasoning-summary-delta",
185
+ text: event.delta
186
+ };
187
+ case "response.output_item.added":
188
+ case "response.output_item.done":
189
+ if (!event.item) return void 0;
190
+ return {
191
+ type: "output-item",
192
+ item: event.item,
193
+ completed: event.type === "response.output_item.done"
194
+ };
195
+ case "response.completed": {
196
+ const usage = response?.usage ? grokUsageFrom(response.usage) : void 0;
197
+ const completed = {
198
+ type: "completed",
199
+ terminal: true,
200
+ responseId: response?.id ?? ""
201
+ };
202
+ if (response?.model) completed.model = response.model;
203
+ if (usage) completed.usage = usage;
204
+ if (response?.output) completed.output = response.output;
205
+ return completed;
206
+ }
207
+ case "response.incomplete": {
208
+ const usage = response?.usage ? grokUsageFrom(response.usage) : void 0;
209
+ const reason = response?.incomplete_details?.reason;
210
+ const incomplete = {
211
+ type: "incomplete",
212
+ terminal: true,
213
+ responseId: response?.id ?? ""
214
+ };
215
+ if (reason) incomplete.reason = reason;
216
+ if (response?.model) incomplete.model = response.model;
217
+ if (usage) incomplete.usage = usage;
218
+ return incomplete;
219
+ }
220
+ case "response.failed":
221
+ case "error": {
222
+ const nested = event.error ?? response?.error ?? void 0;
223
+ return {
224
+ type: "error",
225
+ terminal: true,
226
+ error: new GrokProtocolError(nested?.message ?? event.message ?? `Grok stream ended with ${event.type}`, nested?.code ?? event.code ?? void 0)
227
+ };
228
+ }
229
+ default: return;
230
+ }
231
+ }
232
+ function parseSSEBlock(block) {
233
+ const data = [];
234
+ let event;
235
+ for (const line of block.split("\n")) {
236
+ if (line.startsWith(":")) continue;
237
+ const separator = line.indexOf(":");
238
+ const field = separator < 0 ? line : line.slice(0, separator);
239
+ let value = separator < 0 ? "" : line.slice(separator + 1);
240
+ if (value.startsWith(" ")) value = value.slice(1);
241
+ if (field === "data") data.push(value);
242
+ else if (field === "event") event = value;
243
+ }
244
+ if (!data.length) return void 0;
245
+ const parsed = { data: data.join("\n") };
246
+ if (event !== void 0) parsed.event = event;
247
+ return parsed;
248
+ }
249
+ /** Splits a byte stream into SSE blocks across arbitrary UTF-8/chunk boundaries. */
250
+ async function* parseGrokSSE(body) {
251
+ const reader = body.getReader();
252
+ const decoder = new TextDecoder();
253
+ let buffer = "";
254
+ let pending = "";
255
+ let first = true;
256
+ try {
257
+ while (true) {
258
+ const { done, value } = await reader.read();
259
+ let chunk = pending + decoder.decode(value, { stream: !done });
260
+ pending = "";
261
+ if (first && chunk.length) {
262
+ if (chunk.startsWith("")) chunk = chunk.slice(1);
263
+ first = false;
264
+ }
265
+ if (!done && chunk.endsWith("\r")) {
266
+ pending = "\r";
267
+ chunk = chunk.slice(0, -1);
268
+ }
269
+ buffer += chunk.replaceAll("\r\n", "\n").replaceAll("\r", "\n");
270
+ let index;
271
+ while ((index = buffer.indexOf("\n\n")) >= 0) {
272
+ const block = parseSSEBlock(buffer.slice(0, index));
273
+ buffer = buffer.slice(index + 2);
274
+ if (block) yield block;
275
+ }
276
+ if (done) break;
277
+ }
278
+ if (buffer.trim()) {
279
+ const block = parseSSEBlock(buffer);
280
+ if (block) yield block;
281
+ }
282
+ } finally {
283
+ reader.releaseLock();
284
+ }
285
+ }
286
+ /** Normalized stream that ends at the first terminal event and rejects a truncated stream. */
287
+ async function* normalizeGrokSSE(body) {
288
+ for await (const raw of parseGrokSSE(body)) {
289
+ const event = normalizeGrokEvent(raw);
290
+ if (!event) continue;
291
+ yield event;
292
+ if ("terminal" in event) return;
293
+ }
294
+ throw new GrokProtocolError("Grok SSE connection closed before a terminal event");
295
+ }
296
+ function headerValue(headers, name) {
297
+ if (headers instanceof Headers) return headers.get(name) ?? void 0;
298
+ const key = Object.keys(headers).find((candidate) => candidate.toLowerCase() === name);
299
+ return key === void 0 ? void 0 : headers[key];
300
+ }
301
+ function integerHeader(headers, name) {
302
+ const value = headerValue(headers, name)?.trim();
303
+ if (!value || !/^\d+$/.test(value)) return void 0;
304
+ const parsed = Number(value);
305
+ return Number.isSafeInteger(parsed) ? parsed : void 0;
306
+ }
307
+ /** `Retry-After` as whole seconds (delta-seconds or HTTP-date). Uncapped; callers clamp. */
308
+ function parseRetryAfterSec(headers, now = Date.now()) {
309
+ const value = headerValue(headers, "retry-after")?.trim();
310
+ if (!value) return void 0;
311
+ if (/^\d+$/.test(value)) return Number(value);
312
+ const date = Date.parse(value);
313
+ if (Number.isNaN(date)) return void 0;
314
+ return Math.max(0, Math.ceil((date - now) / 1e3));
315
+ }
316
+ function parseShouldRetry(headers) {
317
+ const value = headerValue(headers, "x-should-retry")?.trim().toLowerCase();
318
+ if (value === "true") return true;
319
+ if (value === "false") return false;
320
+ }
321
+ /** Response headers grok-build reads (client.rs:187-224) plus the observed rate-limit set. */
322
+ function readGrokResponseHeaders(headers) {
323
+ const zdr = headerValue(headers, "x-zero-data-retention")?.trim().toLowerCase();
324
+ const entries = [
325
+ ["contextWindow", integerHeader(headers, "x-grok-context-window")],
326
+ ["maxCompletionTokens", integerHeader(headers, "x-grok-max-completion-tokens")],
327
+ ["modelsEtag", headerValue(headers, "x-models-etag")],
328
+ ["requestId", headerValue(headers, "x-request-id")],
329
+ ["rateLimitLimitTokens", integerHeader(headers, "x-ratelimit-limit-tokens")],
330
+ ["rateLimitRemainingTokens", integerHeader(headers, "x-ratelimit-remaining-tokens")],
331
+ ["rateLimitLimitRequests", integerHeader(headers, "x-ratelimit-limit-requests")],
332
+ ["rateLimitRemainingRequests", integerHeader(headers, "x-ratelimit-remaining-requests")],
333
+ ["zeroDataRetention", zdr === "true" ? true : zdr === "false" ? false : void 0]
334
+ ];
335
+ return Object.fromEntries(entries.filter(([, value]) => value !== void 0));
336
+ }
337
+ const MAX_ERROR_MESSAGE_LENGTH = 500;
338
+ const SUBSCRIPTION_CODE_PATTERN = /subscription:[a-z0-9][a-z0-9_.-]*/i;
339
+ const ErrorObject = z.looseObject({
340
+ code: z.string().optional(),
341
+ message: z.string().optional(),
342
+ type: z.string().optional()
343
+ });
344
+ const ErrorBody = z.looseObject({
345
+ code: z.string().optional(),
346
+ message: z.string().optional(),
347
+ error: z.union([z.string(), ErrorObject]).optional()
348
+ });
349
+ function parseErrorBody(bodyText) {
350
+ let json;
351
+ try {
352
+ json = JSON.parse(bodyText);
353
+ } catch {
354
+ return bodyText.trim() ? { message: bodyText.trim() } : {};
355
+ }
356
+ const parsed = ErrorBody.safeParse(json);
357
+ if (!parsed.success) return bodyText.trim() ? { message: bodyText.trim() } : {};
358
+ const { error } = parsed.data;
359
+ const errorText = z.string().safeParse(error).data;
360
+ const errorObject = ErrorObject.safeParse(error).data;
361
+ const code = parsed.data.code ?? errorObject?.code;
362
+ const message = errorText ?? errorObject?.message ?? parsed.data.message;
363
+ const body = {};
364
+ if (code) body.code = code;
365
+ if (message) body.message = message;
366
+ return body;
367
+ }
368
+ /**
369
+ * Classifies a non-2xx proxy or api.x.ai response. Pass `status = 0` for a network failure.
370
+ * The body is not trusted to be JSON.
371
+ */
372
+ function classifyGrokHttpError(status, bodyText, headers) {
373
+ const body = parseErrorBody(bodyText);
374
+ const message = body.message === void 0 ? void 0 : body.message.slice(0, MAX_ERROR_MESSAGE_LENGTH);
375
+ const shouldRetry = parseShouldRetry(headers);
376
+ const retryAfterSec = parseRetryAfterSec(headers);
377
+ const base = { status };
378
+ if (body.code) base.code = body.code;
379
+ if (message !== void 0) base.message = message;
380
+ if (shouldRetry !== void 0) base.shouldRetry = shouldRetry;
381
+ if (retryAfterSec !== void 0) base.retryAfterSec = retryAfterSec;
382
+ const subscriptionCode = SUBSCRIPTION_CODE_PATTERN.exec(bodyText)?.[0];
383
+ if (status === 401) return {
384
+ kind: "auth",
385
+ ...base
386
+ };
387
+ if (status === 426) {
388
+ const minClientVersion = /\bversion\s+(\d+\.\d+\.\d+)\s+or later/i.exec(bodyText)?.[1];
389
+ const gate = {
390
+ kind: "version_gate",
391
+ ...base
392
+ };
393
+ if (minClientVersion) gate.minClientVersion = minClientVersion;
394
+ return gate;
395
+ }
396
+ if (status === 429) {
397
+ if (subscriptionCode) return {
398
+ kind: "quota_exhausted",
399
+ ...base,
400
+ code: subscriptionCode
401
+ };
402
+ return {
403
+ kind: "rate_limited",
404
+ ...base
405
+ };
406
+ }
407
+ if (status === 403) return {
408
+ kind: "entitlement",
409
+ ...base
410
+ };
411
+ if (status === 400 || status === 422) return {
412
+ kind: "invalid_request",
413
+ ...base
414
+ };
415
+ if (status === 0 || status === 408 || status >= 500) return {
416
+ kind: "transient",
417
+ ...base
418
+ };
419
+ return {
420
+ kind: "permanent",
421
+ ...base
422
+ };
423
+ }
424
+ //#endregion
425
+ export { GROK_DEFAULT_OUTPUT_SCHEMA_NAME, GrokProtocolError, buildGrokResponsesRequest, classifyGrokHttpError, encodeGrokRequestBody, encodeGrokRequestBodyPlain, grokUsageFrom, normalizeGrokEvent, normalizeGrokSSE, parseGrokSSE, parseRetryAfterSec, parseShouldRetry, readGrokResponseHeaders };
426
+
427
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3Jvay1iYWNrZW5kLXByb3RvY29sLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy91dGlscy9wcm92aWRlcnMvZ3Jvay9ncm9rLWJhY2tlbmQtcHJvdG9jb2wudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcHJvbWlzaWZ5IH0gZnJvbSBcIm5vZGU6dXRpbFwiO1xuaW1wb3J0IHsgenN0ZENvbXByZXNzIH0gZnJvbSBcIm5vZGU6emxpYlwiO1xuXG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiO1xuXG5pbXBvcnQge1xuICBpc0pzb25PYmplY3QsXG4gIHR5cGUgSnNvbk9iamVjdCxcbiAgdHlwZSBKc29uVmFsdWUsXG4gIGpzb25WYWx1ZVNjaGVtYSxcbn0gZnJvbSBcIi4uL2NvbW1vbi9wcm92aWRlci10eXBlc1wiO1xuaW1wb3J0IHsgdHlwZSBHcm9rUmVhc29uaW5nRWZmb3J0IH0gZnJvbSBcIi4vZ3Jvay1jb25zdGFudHNcIjtcblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBSZXF1ZXN0IGJvZHlcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5leHBvcnQgdHlwZSBHcm9rSW5wdXRDb250ZW50UGFydCA9XG4gIHwgeyB0eXBlOiBcImlucHV0X3RleHRcIjsgdGV4dDogc3RyaW5nIH1cbiAgfCB7IHR5cGU6IFwiaW5wdXRfaW1hZ2VcIjsgaW1hZ2VfdXJsOiBzdHJpbmcgfVxuICB8IHsgdHlwZTogXCJvdXRwdXRfdGV4dFwiOyB0ZXh0OiBzdHJpbmcgfTtcblxuZXhwb3J0IHR5cGUgR3Jva0lucHV0SXRlbSA9XG4gIHwgeyB0eXBlOiBcIm1lc3NhZ2VcIjsgcm9sZTogXCJ1c2VyXCIgfCBcImFzc2lzdGFudFwiOyBjb250ZW50OiBzdHJpbmcgfCBHcm9rSW5wdXRDb250ZW50UGFydFtdIH1cbiAgfCB7IHR5cGU6IFwiZnVuY3Rpb25fY2FsbFwiOyBjYWxsX2lkOiBzdHJpbmc7IG5hbWU6IHN0cmluZzsgYXJndW1lbnRzOiBzdHJpbmc7IGlkPzogc3RyaW5nIH1cbiAgfCB7IHR5cGU6IFwiZnVuY3Rpb25fY2FsbF9vdXRwdXRcIjsgY2FsbF9pZDogc3RyaW5nOyBvdXRwdXQ6IHN0cmluZyB9XG4gIHwge1xuICAgICAgdHlwZTogXCJyZWFzb25pbmdcIjtcbiAgICAgIGlkPzogc3RyaW5nO1xuICAgICAgc3VtbWFyeT86IEFycmF5PHsgdHlwZTogXCJzdW1tYXJ5X3RleHRcIjsgdGV4dDogc3RyaW5nIH0+O1xuICAgICAgZW5jcnlwdGVkX2NvbnRlbnQ/OiBzdHJpbmc7XG4gICAgfTtcblxuZXhwb3J0IHR5cGUgR3Jva0Z1bmN0aW9uVG9vbCA9IHtcbiAgdHlwZTogXCJmdW5jdGlvblwiO1xuICBuYW1lOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICBwYXJhbWV0ZXJzOiBKc29uVmFsdWU7XG4gIHN0cmljdDogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCB0eXBlIEdyb2tUb29sID0gR3Jva0Z1bmN0aW9uVG9vbCB8IHsgdHlwZTogXCJ3ZWJfc2VhcmNoXCIgfSB8IHsgdHlwZTogXCJ4X3NlYXJjaFwiIH07XG5cbmV4cG9ydCB0eXBlIEdyb2tUb29sQ2hvaWNlID0gXCJhdXRvXCIgfCBcIm5vbmVcIiB8IFwicmVxdWlyZWRcIiB8IHsgdHlwZTogXCJmdW5jdGlvblwiOyBuYW1lOiBzdHJpbmcgfTtcblxuZXhwb3J0IGludGVyZmFjZSBHcm9rUmVzcG9uc2VzT3B0aW9ucyB7XG4gIG1vZGVsOiBzdHJpbmc7XG4gIC8qKiBTZW50IGFzIHRoZSBmaXJzdCBgaW5wdXRgIGl0ZW07IGdyb2stYnVpbGQgbmV2ZXIgdXNlcyBgaW5zdHJ1Y3Rpb25zYC4gKi9cbiAgc3lzdGVtUHJvbXB0Pzogc3RyaW5nO1xuICAvKiogRnVsbCBjb252ZXJzYXRpb24gaGlzdG9yeTsgcWdyaWQgcmVwbGF5cyBpdCBldmVyeSB0dXJuIChgc3RvcmU6IGZhbHNlYCkuICovXG4gIGhpc3Rvcnk6IHJlYWRvbmx5IEdyb2tJbnB1dEl0ZW1bXTtcbiAgLyoqIGdyb2stYnVpbGQgc2VuZHMgdGhlIGNvbnZlcnNhdGlvbiBpZCBoZXJlLiAqL1xuICBwcm9tcHRDYWNoZUtleTogc3RyaW5nO1xuICBlZmZvcnQ6IEdyb2tSZWFzb25pbmdFZmZvcnQ7XG4gIG91dHB1dFNjaGVtYT86IHsgbmFtZT86IHN0cmluZzsgc2NoZW1hOiBKc29uVmFsdWUgfTtcbiAgdG9vbHM/OiByZWFkb25seSBHcm9rVG9vbFtdO1xuICB0b29sQ2hvaWNlPzogR3Jva1Rvb2xDaG9pY2U7XG4gIG1heE91dHB1dFRva2Vucz86IG51bWJlcjtcbn1cblxuZXhwb3J0IHR5cGUgR3Jva0lucHV0V2lyZUl0ZW0gPVxuICB8IHsgdHlwZTogXCJtZXNzYWdlXCI7IHJvbGU6IFwic3lzdGVtXCI7IGNvbnRlbnQ6IHN0cmluZyB9XG4gIHwgRXhjbHVkZTxHcm9rSW5wdXRJdGVtLCB7IHR5cGU6IFwicmVhc29uaW5nXCIgfT5cbiAgfCB7XG4gICAgICB0eXBlOiBcInJlYXNvbmluZ1wiO1xuICAgICAgaWQ/OiBzdHJpbmc7XG4gICAgICBzdW1tYXJ5OiBBcnJheTx7IHR5cGU6IFwic3VtbWFyeV90ZXh0XCI7IHRleHQ6IHN0cmluZyB9PjtcbiAgICAgIGVuY3J5cHRlZF9jb250ZW50OiBzdHJpbmc7XG4gICAgfTtcblxuZXhwb3J0IGludGVyZmFjZSBHcm9rUmVzcG9uc2VzUmVxdWVzdCB7XG4gIGluY2x1ZGU6IFtcInJlYXNvbmluZy5lbmNyeXB0ZWRfY29udGVudFwiLCBcIm5vX2lubGluZV9jaXRhdGlvbnNcIl07XG4gIGlucHV0OiBHcm9rSW5wdXRXaXJlSXRlbVtdO1xuICBtb2RlbDogc3RyaW5nO1xuICBwcm9tcHRfY2FjaGVfa2V5OiBzdHJpbmc7XG4gIHJlYXNvbmluZzogeyBlZmZvcnQ6IEdyb2tSZWFzb25pbmdFZmZvcnQ7IHN1bW1hcnk6IFwiY29uY2lzZVwiIH07XG4gIHN0b3JlOiBmYWxzZTtcbiAgc3RyZWFtOiB0cnVlO1xuICB0ZXh0Pzoge1xuICAgIGZvcm1hdDogeyB0eXBlOiBcImpzb25fc2NoZW1hXCI7IG5hbWU6IHN0cmluZzsgc3RyaWN0OiB0cnVlOyBzY2hlbWE6IEpzb25WYWx1ZSB9O1xuICB9O1xuICB0b29scz86IEdyb2tUb29sW107XG4gIHRvb2xfY2hvaWNlPzogR3Jva1Rvb2xDaG9pY2U7XG4gIG1heF9vdXRwdXRfdG9rZW5zPzogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgR1JPS19ERUZBVUxUX09VVFBVVF9TQ0hFTUFfTkFNRSA9IFwicWdyaWRfb3V0cHV0XCI7XG5cbmZ1bmN0aW9uIHJlcGxheUl0ZW0oaXRlbTogR3Jva0lucHV0SXRlbSk6IEdyb2tJbnB1dFdpcmVJdGVtIHwgdW5kZWZpbmVkIHtcbiAgaWYgKGl0ZW0udHlwZSAhPT0gXCJyZWFzb25pbmdcIikgcmV0dXJuIGl0ZW07XG5cbiAgLy8gV2l0aCBzdG9yZTpmYWxzZSB0aGUgcHJveHkgY2Fubm90IHJlc29sdmUgYSByZWFzb25pbmcgaXRlbSBieSBpZDsgd2l0aG91dCB0aGUgZW5jcnlwdGVkXG4gIC8vIHBheWxvYWQgKGZvciBleGFtcGxlIHJlYXNvbmluZyBmcm9tIGFub3RoZXIgYWNjb3VudCkgdGhlIGl0ZW0gaXMgZHJvcHBlZCwgbm90IHJlcGxheWVkLlxuICBpZiAoIWl0ZW0uZW5jcnlwdGVkX2NvbnRlbnQpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgY29uc3QgcmVwbGF5ZWQ6IEV4dHJhY3Q8R3Jva0lucHV0V2lyZUl0ZW0sIHsgdHlwZTogXCJyZWFzb25pbmdcIiB9PiA9IHtcbiAgICB0eXBlOiBcInJlYXNvbmluZ1wiLFxuICAgIHN1bW1hcnk6IGl0ZW0uc3VtbWFyeSA/PyBbXSxcbiAgICBlbmNyeXB0ZWRfY29udGVudDogaXRlbS5lbmNyeXB0ZWRfY29udGVudCxcbiAgfTtcblxuICBpZiAoaXRlbS5pZCkgcmVwbGF5ZWQuaWQgPSBpdGVtLmlkO1xuXG4gIHJldHVybiByZXBsYXllZDtcbn1cblxuLyoqIEJ1aWxkcyB0aGUgYC9yZXNwb25zZXNgIGJvZHkgaW4gdGhlIGtleSBvcmRlciBvZiB0aGUgMS4wLjYwIGdvbGRlbiBjYXB0dXJlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkR3Jva1Jlc3BvbnNlc1JlcXVlc3Qob3B0aW9uczogR3Jva1Jlc3BvbnNlc09wdGlvbnMpOiBHcm9rUmVzcG9uc2VzUmVxdWVzdCB7XG4gIGlmICghb3B0aW9ucy5tb2RlbCkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdyb2sgbW9kZWwgaXMgcmVxdWlyZWRcIik7XG5cbiAgaWYgKCFvcHRpb25zLnByb21wdENhY2hlS2V5KSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR3JvayBwcm9tcHRfY2FjaGVfa2V5IGlzIHJlcXVpcmVkXCIpO1xuXG4gIGlmIChcbiAgICBvcHRpb25zLm1heE91dHB1dFRva2VucyAhPT0gdW5kZWZpbmVkICYmXG4gICAgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihvcHRpb25zLm1heE91dHB1dFRva2VucykgfHwgb3B0aW9ucy5tYXhPdXRwdXRUb2tlbnMgPD0gMClcbiAgKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJtYXhPdXRwdXRUb2tlbnMgbXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXJcIik7XG5cbiAgY29uc3QgaW5wdXQ6IEdyb2tJbnB1dFdpcmVJdGVtW10gPSBbXTtcblxuICBpZiAob3B0aW9ucy5zeXN0ZW1Qcm9tcHQpXG4gICAgaW5wdXQucHVzaCh7IHR5cGU6IFwibWVzc2FnZVwiLCByb2xlOiBcInN5c3RlbVwiLCBjb250ZW50OiBvcHRpb25zLnN5c3RlbVByb21wdCB9KTtcblxuICBmb3IgKGNvbnN0IGl0ZW0gb2Ygb3B0aW9ucy5oaXN0b3J5KSB7XG4gICAgY29uc3Qgd2lyZSA9IHJlcGxheUl0ZW0oaXRlbSk7XG5cbiAgICBpZiAod2lyZSkgaW5wdXQucHVzaCh3aXJlKTtcbiAgfVxuXG4gIGNvbnN0IHJlcXVlc3Q6IEdyb2tSZXNwb25zZXNSZXF1ZXN0ID0ge1xuICAgIGluY2x1ZGU6IFtcInJlYXNvbmluZy5lbmNyeXB0ZWRfY29udGVudFwiLCBcIm5vX2lubGluZV9jaXRhdGlvbnNcIl0sXG4gICAgaW5wdXQsXG4gICAgbW9kZWw6IG9wdGlvbnMubW9kZWwsXG4gICAgcHJvbXB0X2NhY2hlX2tleTogb3B0aW9ucy5wcm9tcHRDYWNoZUtleSxcbiAgICByZWFzb25pbmc6IHsgZWZmb3J0OiBvcHRpb25zLmVmZm9ydCwgc3VtbWFyeTogXCJjb25jaXNlXCIgfSxcbiAgICBzdG9yZTogZmFsc2UsXG4gICAgc3RyZWFtOiB0cnVlLFxuICB9O1xuXG4gIGlmIChvcHRpb25zLm91dHB1dFNjaGVtYSkge1xuICAgIHJlcXVlc3QudGV4dCA9IHtcbiAgICAgIGZvcm1hdDoge1xuICAgICAgICB0eXBlOiBcImpzb25fc2NoZW1hXCIsXG4gICAgICAgIG5hbWU6IG9wdGlvbnMub3V0cHV0U2NoZW1hLm5hbWUgPz8gR1JPS19ERUZBVUxUX09VVFBVVF9TQ0hFTUFfTkFNRSxcbiAgICAgICAgc3RyaWN0OiB0cnVlLFxuICAgICAgICBzY2hlbWE6IG9wdGlvbnMub3V0cHV0U2NoZW1hLnNjaGVtYSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIGlmIChvcHRpb25zLnRvb2xzPy5sZW5ndGgpIHJlcXVlc3QudG9vbHMgPSBbLi4ub3B0aW9ucy50b29sc107XG5cbiAgaWYgKG9wdGlvbnMudG9vbENob2ljZSAhPT0gdW5kZWZpbmVkKSByZXF1ZXN0LnRvb2xfY2hvaWNlID0gb3B0aW9ucy50b29sQ2hvaWNlO1xuXG4gIGlmIChvcHRpb25zLm1heE91dHB1dFRva2VucyAhPT0gdW5kZWZpbmVkKSByZXF1ZXN0Lm1heF9vdXRwdXRfdG9rZW5zID0gb3B0aW9ucy5tYXhPdXRwdXRUb2tlbnM7XG5cbiAgcmV0dXJuIHJlcXVlc3Q7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR3Jva0VuY29kZWRCb2R5IHtcbiAgYnl0ZXM6IFVpbnQ4QXJyYXk7XG4gIGNvbnRlbnRFbmNvZGluZzogXCJ6c3RkXCIgfCB1bmRlZmluZWQ7XG59XG5cbmNvbnN0IHpzdGRDb21wcmVzc0FzeW5jID0gcHJvbWlzaWZ5KHpzdGRDb21wcmVzcyk7XG5cbi8qKiB6c3RkLWNvbXByZXNzZWQgSlNPTiBib2R5LCBhcyB0aGUgMS4wLjYwIGJpbmFyeSBzZW5kcyBpdCAoYGNvbnRlbnQtZW5jb2Rpbmc6IHpzdGRgKS4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBlbmNvZGVHcm9rUmVxdWVzdEJvZHkoXG4gIGJvZHk6IEdyb2tSZXNwb25zZXNSZXF1ZXN0LFxuKTogUHJvbWlzZTxHcm9rRW5jb2RlZEJvZHkgJiB7IGNvbnRlbnRFbmNvZGluZzogXCJ6c3RkXCIgfT4ge1xuICBjb25zdCBjb21wcmVzc2VkID0gYXdhaXQgenN0ZENvbXByZXNzQXN5bmMoQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkoYm9keSksIFwidXRmOFwiKSk7XG5cbiAgcmV0dXJuIHtcbiAgICBieXRlczogbmV3IFVpbnQ4QXJyYXkoY29tcHJlc3NlZC5idWZmZXIsIGNvbXByZXNzZWQuYnl0ZU9mZnNldCwgY29tcHJlc3NlZC5ieXRlTGVuZ3RoKSxcbiAgICBjb250ZW50RW5jb2Rpbmc6IFwienN0ZFwiLFxuICB9O1xufVxuXG4vKiogUGxhaW4gSlNPTiBib2R5OyB0aGUgcHJveHkgYWNjZXB0cyBpdCB0b28gKFUwIGl0ZW0gMSkuICovXG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlR3Jva1JlcXVlc3RCb2R5UGxhaW4oXG4gIGJvZHk6IEdyb2tSZXNwb25zZXNSZXF1ZXN0LFxuKTogR3Jva0VuY29kZWRCb2R5ICYgeyBjb250ZW50RW5jb2Rpbmc6IHVuZGVmaW5lZCB9IHtcbiAgcmV0dXJuIHsgYnl0ZXM6IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShKU09OLnN0cmluZ2lmeShib2R5KSksIGNvbnRlbnRFbmNvZGluZzogdW5kZWZpbmVkIH07XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gU1NFIGV2ZW50c1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmV4cG9ydCBjbGFzcyBHcm9rUHJvdG9jb2xFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgcmVhZG9ubHkgY29kZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgY29kZT86IHN0cmluZykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IFwiR3Jva1Byb3RvY29sRXJyb3JcIjtcbiAgICB0aGlzLmNvZGUgPSBjb2RlO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR3Jva1VzYWdlIHtcbiAgaW5wdXRUb2tlbnM6IG51bWJlcjtcbiAgY2FjaGVkSW5wdXRUb2tlbnM6IG51bWJlcjtcbiAgb3V0cHV0VG9rZW5zOiBudW1iZXI7XG4gIHJlYXNvbmluZ1Rva2VuczogbnVtYmVyO1xuICB0b3RhbFRva2VuczogbnVtYmVyO1xuICBudW1Tb3VyY2VzVXNlZD86IG51bWJlcjtcbiAgbnVtU2VydmVyU2lkZVRvb2xzVXNlZD86IG51bWJlcjtcbiAgLyoqIDEgdGljayA9IEdST0tfVVNEX1BFUl9USUNLIFVTRC4gKi9cbiAgY29zdEluVXNkVGlja3M/OiBudW1iZXI7XG4gIC8qKiBMaXZlIGNvbnRleHQgc2l6ZSAoYGNvbnRleHRfZGV0YWlsc2ApLCBkaXN0aW5jdCBmcm9tIGN1bXVsYXRpdmUgaW5wdXQgdG9rZW5zLiAqL1xuICBjb250ZXh0SW5wdXRUb2tlbnM/OiBudW1iZXI7XG4gIGNvbnRleHRPdXRwdXRUb2tlbnM/OiBudW1iZXI7XG59XG5cbmV4cG9ydCB0eXBlIEdyb2tPdXRwdXRJdGVtID0geyB0eXBlOiBzdHJpbmcgfSAmIEpzb25PYmplY3Q7XG5cbmV4cG9ydCB0eXBlIEdyb2tOb3JtYWxpemVkRXZlbnQgPVxuICB8IHsgdHlwZTogXCJjcmVhdGVkXCI7IHJlc3BvbnNlSWQ/OiBzdHJpbmc7IG1vZGVsPzogc3RyaW5nIH1cbiAgfCB7IHR5cGU6IFwidGV4dC1kZWx0YVwiOyB0ZXh0OiBzdHJpbmc7IGl0ZW1JZD86IHN0cmluZyB9XG4gIHwgeyB0eXBlOiBcInJlYXNvbmluZy1zdW1tYXJ5LWRlbHRhXCI7IHRleHQ6IHN0cmluZzsgaXRlbUlkPzogc3RyaW5nIH1cbiAgfCB7IHR5cGU6IFwib3V0cHV0LWl0ZW1cIjsgaXRlbTogR3Jva091dHB1dEl0ZW07IGNvbXBsZXRlZDogYm9vbGVhbiB9XG4gIHwge1xuICAgICAgdHlwZTogXCJjb21wbGV0ZWRcIjtcbiAgICAgIHRlcm1pbmFsOiB0cnVlO1xuICAgICAgcmVzcG9uc2VJZDogc3RyaW5nO1xuICAgICAgbW9kZWw/OiBzdHJpbmc7XG4gICAgICB1c2FnZT86IEdyb2tVc2FnZTtcbiAgICAgIG91dHB1dD86IEdyb2tPdXRwdXRJdGVtW107XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6IFwiaW5jb21wbGV0ZVwiO1xuICAgICAgdGVybWluYWw6IHRydWU7XG4gICAgICByZXNwb25zZUlkOiBzdHJpbmc7XG4gICAgICByZWFzb24/OiBzdHJpbmc7XG4gICAgICBtb2RlbD86IHN0cmluZztcbiAgICAgIHVzYWdlPzogR3Jva1VzYWdlO1xuICAgIH1cbiAgfCB7IHR5cGU6IFwiZXJyb3JcIjsgdGVybWluYWw6IHRydWU7IGVycm9yOiBHcm9rUHJvdG9jb2xFcnJvciB9O1xuXG5jb25zdCBjb3VudCA9IHoubnVtYmVyKCkuaW50KCkubm9ubmVnYXRpdmUoKTtcblxuY29uc3QgV2lyZVVzYWdlID0gei5vYmplY3Qoe1xuICBpbnB1dF90b2tlbnM6IGNvdW50Lm9wdGlvbmFsKCksXG4gIGlucHV0X3Rva2Vuc19kZXRhaWxzOiB6Lm9iamVjdCh7IGNhY2hlZF90b2tlbnM6IGNvdW50Lm9wdGlvbmFsKCkgfSkubnVsbGlzaCgpLFxuICBvdXRwdXRfdG9rZW5zOiBjb3VudC5vcHRpb25hbCgpLFxuICBvdXRwdXRfdG9rZW5zX2RldGFpbHM6IHoub2JqZWN0KHsgcmVhc29uaW5nX3Rva2VuczogY291bnQub3B0aW9uYWwoKSB9KS5udWxsaXNoKCksXG4gIHRvdGFsX3Rva2VuczogY291bnQub3B0aW9uYWwoKSxcbiAgbnVtX3NvdXJjZXNfdXNlZDogY291bnQub3B0aW9uYWwoKSxcbiAgbnVtX3NlcnZlcl9zaWRlX3Rvb2xzX3VzZWQ6IGNvdW50Lm9wdGlvbmFsKCksXG4gIGNvc3RfaW5fdXNkX3RpY2tzOiBjb3VudC5vcHRpb25hbCgpLFxuICBjb250ZXh0X2RldGFpbHM6IHpcbiAgICAub2JqZWN0KHsgaW5wdXRfdG9rZW5zOiBjb3VudC5vcHRpb25hbCgpLCBvdXRwdXRfdG9rZW5zOiBjb3VudC5vcHRpb25hbCgpIH0pXG4gICAgLm51bGxpc2goKSxcbn0pO1xuXG4vLyBJdGVtcyBhcnJpdmUgZnJvbSBKU09OLnBhcnNlLCBzbyBldmVyeSBleHRyYSBtZW1iZXIgaXMgYSBKU09OIHZhbHVlLlxuY29uc3QgV2lyZUl0ZW0gPSB6Lm9iamVjdCh7IHR5cGU6IHouc3RyaW5nKCkgfSkuY2F0Y2hhbGwoanNvblZhbHVlU2NoZW1hKTtcblxuY29uc3QgV2lyZVJlc3BvbnNlID0gei5sb29zZU9iamVjdCh7XG4gIGlkOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gIG1vZGVsOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gIHN0YXR1czogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICB1c2FnZTogV2lyZVVzYWdlLm51bGxpc2goKSxcbiAgb3V0cHV0OiB6LmFycmF5KFdpcmVJdGVtKS5vcHRpb25hbCgpLFxuICBpbmNvbXBsZXRlX2RldGFpbHM6IHoub2JqZWN0KHsgcmVhc29uOiB6LnN0cmluZygpLm9wdGlvbmFsKCkgfSkubnVsbGlzaCgpLFxuICBlcnJvcjogei5vYmplY3QoeyBtZXNzYWdlOiB6LnN0cmluZygpLm9wdGlvbmFsKCksIGNvZGU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSB9KS5udWxsaXNoKCksXG59KTtcblxuY29uc3QgV2lyZUV2ZW50ID0gei5sb29zZU9iamVjdCh7XG4gIHR5cGU6IHouc3RyaW5nKCksXG4gIHJlc3BvbnNlOiBXaXJlUmVzcG9uc2Uub3B0aW9uYWwoKSxcbiAgaXRlbTogV2lyZUl0ZW0ub3B0aW9uYWwoKSxcbiAgaXRlbV9pZDogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICBkZWx0YTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICBtZXNzYWdlOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gIGNvZGU6IHouc3RyaW5nKCkubnVsbGlzaCgpLFxuICBlcnJvcjogei5vYmplY3QoeyBtZXNzYWdlOiB6LnN0cmluZygpLm9wdGlvbmFsKCksIGNvZGU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSB9KS5udWxsaXNoKCksXG59KTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdyb2tVc2FnZUZyb20odXNhZ2U6IHouaW5mZXI8dHlwZW9mIFdpcmVVc2FnZT4pOiBHcm9rVXNhZ2Uge1xuICBjb25zdCBpbnB1dFRva2VucyA9IHVzYWdlLmlucHV0X3Rva2VucyA/PyAwO1xuICBjb25zdCBvdXRwdXRUb2tlbnMgPSB1c2FnZS5vdXRwdXRfdG9rZW5zID8/IDA7XG5cbiAgY29uc3QgcmVzdWx0OiBHcm9rVXNhZ2UgPSB7XG4gICAgaW5wdXRUb2tlbnMsXG4gICAgY2FjaGVkSW5wdXRUb2tlbnM6IHVzYWdlLmlucHV0X3Rva2Vuc19kZXRhaWxzPy5jYWNoZWRfdG9rZW5zID8/IDAsXG4gICAgb3V0cHV0VG9rZW5zLFxuICAgIHJlYXNvbmluZ1Rva2VuczogdXNhZ2Uub3V0cHV0X3Rva2Vuc19kZXRhaWxzPy5yZWFzb25pbmdfdG9rZW5zID8/IDAsXG4gICAgdG90YWxUb2tlbnM6IHVzYWdlLnRvdGFsX3Rva2VucyA/PyBpbnB1dFRva2VucyArIG91dHB1dFRva2VucyxcbiAgfTtcblxuICBpZiAodXNhZ2UubnVtX3NvdXJjZXNfdXNlZCAhPT0gdW5kZWZpbmVkKSByZXN1bHQubnVtU291cmNlc1VzZWQgPSB1c2FnZS5udW1fc291cmNlc191c2VkO1xuXG4gIGlmICh1c2FnZS5udW1fc2VydmVyX3NpZGVfdG9vbHNfdXNlZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmVzdWx0Lm51bVNlcnZlclNpZGVUb29sc1VzZWQgPSB1c2FnZS5udW1fc2VydmVyX3NpZGVfdG9vbHNfdXNlZDtcbiAgfVxuXG4gIGlmICh1c2FnZS5jb3N0X2luX3VzZF90aWNrcyAhPT0gdW5kZWZpbmVkKSByZXN1bHQuY29zdEluVXNkVGlja3MgPSB1c2FnZS5jb3N0X2luX3VzZF90aWNrcztcblxuICBpZiAodXNhZ2UuY29udGV4dF9kZXRhaWxzPy5pbnB1dF90b2tlbnMgIT09IHVuZGVmaW5lZCkge1xuICAgIHJlc3VsdC5jb250ZXh0SW5wdXRUb2tlbnMgPSB1c2FnZS5jb250ZXh0X2RldGFpbHMuaW5wdXRfdG9rZW5zO1xuICB9XG5cbiAgaWYgKHVzYWdlLmNvbnRleHRfZGV0YWlscz8ub3V0cHV0X3Rva2VucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmVzdWx0LmNvbnRleHRPdXRwdXRUb2tlbnMgPSB1c2FnZS5jb250ZXh0X2RldGFpbHMub3V0cHV0X3Rva2VucztcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR3Jva1Jhd1NTRUV2ZW50IHtcbiAgZXZlbnQ/OiBzdHJpbmc7XG4gIGRhdGE6IHN0cmluZztcbn1cblxuLyoqXG4gKiBOb3JtYWxpemVzIG9uZSBTU0UgYmxvY2suIFJldHVybnMgYHVuZGVmaW5lZGAgZm9yIHdlbGwtZm9ybWVkIGV2ZW50cyB0aGF0IGNhcnJ5IG5vdGhpbmcgYVxuICogY2FsbGVyIGNvbnN1bWVzIChgcmVzcG9uc2UuaW5fcHJvZ3Jlc3NgLCBwYXJ0L2RvbmUgYm9va2tlZXBpbmcpLiBUZXJtaW5hbCBldmVudHMgYXJlXG4gKiBgcmVzcG9uc2UuY29tcGxldGVkIHwgcmVzcG9uc2UuaW5jb21wbGV0ZSB8IHJlc3BvbnNlLmZhaWxlZCB8IGVycm9yYDsgdGhlIHByb3h5IGRvZXMgbm90XG4gKiBzZW5kIGBbRE9ORV1gLCBhbmQgYSBgW0RPTkVdYCBzZW50aW5lbCBpcyBpZ25vcmVkIGlmIG9uZSBldmVyIGFwcGVhcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVHcm9rRXZlbnQocmF3OiBHcm9rUmF3U1NFRXZlbnQpOiBHcm9rTm9ybWFsaXplZEV2ZW50IHwgdW5kZWZpbmVkIHtcbiAgaWYgKHJhdy5kYXRhLnRyaW0oKSA9PT0gXCJbRE9ORV1cIikgcmV0dXJuIHVuZGVmaW5lZDtcbiAgbGV0IGpzb246IEpzb25WYWx1ZTtcblxuICB0cnkge1xuICAgIC8vIEpTT04ucGFyc2Ugd2l0aG91dCBhIHJldml2ZXIgeWllbGRzIG9ubHkgSlNPTiB2YWx1ZXMuXG4gICAganNvbiA9IEpTT04ucGFyc2UocmF3LmRhdGEpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRocm93IG5ldyBHcm9rUHJvdG9jb2xFcnJvcihgSW52YWxpZCBHcm9rIFNTRSBKU09OOiAke1N0cmluZyhlcnJvcil9YCk7XG4gIH1cblxuICAvLyBBbiBTU0UgYGV2ZW50OmAgbGluZSBuYW1lcyB0aGUgdHlwZSB3aGVuIHRoZSBwYXlsb2FkIG9iamVjdCBvbWl0cyBpdC5cbiAgY29uc3Qgd2l0aFR5cGUgPVxuICAgIGlzSnNvbk9iamVjdChqc29uKSAmJiAhKFwidHlwZVwiIGluIGpzb24pICYmIHJhdy5ldmVudCA/IHsgLi4uanNvbiwgdHlwZTogcmF3LmV2ZW50IH0gOiBqc29uO1xuXG4gIGNvbnN0IHBhcnNlZCA9IFdpcmVFdmVudC5zYWZlUGFyc2Uod2l0aFR5cGUpO1xuXG4gIGlmICghcGFyc2VkLnN1Y2Nlc3MpXG4gICAgdGhyb3cgbmV3IEdyb2tQcm90b2NvbEVycm9yKGBVbmV4cGVjdGVkIEdyb2sgU1NFIGV2ZW50IHNoYXBlOiAke3BhcnNlZC5lcnJvci5tZXNzYWdlfWApO1xuICBjb25zdCBldmVudCA9IHBhcnNlZC5kYXRhO1xuICBjb25zdCByZXNwb25zZSA9IGV2ZW50LnJlc3BvbnNlO1xuXG4gIHN3aXRjaCAoZXZlbnQudHlwZSkge1xuICAgIGNhc2UgXCJyZXNwb25zZS5jcmVhdGVkXCI6IHtcbiAgICAgIGNvbnN0IGNyZWF0ZWQ6IEdyb2tOb3JtYWxpemVkRXZlbnQgPSB7IHR5cGU6IFwiY3JlYXRlZFwiIH07XG5cbiAgICAgIGlmIChyZXNwb25zZT8uaWQpIGNyZWF0ZWQucmVzcG9uc2VJZCA9IHJlc3BvbnNlLmlkO1xuXG4gICAgICBpZiAocmVzcG9uc2U/Lm1vZGVsKSBjcmVhdGVkLm1vZGVsID0gcmVzcG9uc2UubW9kZWw7XG5cbiAgICAgIHJldHVybiBjcmVhdGVkO1xuICAgIH1cblxuICAgIGNhc2UgXCJyZXNwb25zZS5vdXRwdXRfdGV4dC5kZWx0YVwiOlxuICAgICAgaWYgKGV2ZW50LmRlbHRhID09PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgIHJldHVybiBldmVudC5pdGVtX2lkXG4gICAgICAgID8geyB0eXBlOiBcInRleHQtZGVsdGFcIiwgdGV4dDogZXZlbnQuZGVsdGEsIGl0ZW1JZDogZXZlbnQuaXRlbV9pZCB9XG4gICAgICAgIDogeyB0eXBlOiBcInRleHQtZGVsdGFcIiwgdGV4dDogZXZlbnQuZGVsdGEgfTtcbiAgICBjYXNlIFwicmVzcG9uc2UucmVhc29uaW5nX3N1bW1hcnlfdGV4dC5kZWx0YVwiOlxuICAgICAgaWYgKGV2ZW50LmRlbHRhID09PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgIHJldHVybiBldmVudC5pdGVtX2lkXG4gICAgICAgID8geyB0eXBlOiBcInJlYXNvbmluZy1zdW1tYXJ5LWRlbHRhXCIsIHRleHQ6IGV2ZW50LmRlbHRhLCBpdGVtSWQ6IGV2ZW50Lml0ZW1faWQgfVxuICAgICAgICA6IHsgdHlwZTogXCJyZWFzb25pbmctc3VtbWFyeS1kZWx0YVwiLCB0ZXh0OiBldmVudC5kZWx0YSB9O1xuICAgIGNhc2UgXCJyZXNwb25zZS5vdXRwdXRfaXRlbS5hZGRlZFwiOlxuICAgIGNhc2UgXCJyZXNwb25zZS5vdXRwdXRfaXRlbS5kb25lXCI6XG4gICAgICBpZiAoIWV2ZW50Lml0ZW0pIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IFwib3V0cHV0LWl0ZW1cIixcbiAgICAgICAgaXRlbTogZXZlbnQuaXRlbSxcbiAgICAgICAgY29tcGxldGVkOiBldmVudC50eXBlID09PSBcInJlc3BvbnNlLm91dHB1dF9pdGVtLmRvbmVcIixcbiAgICAgIH07XG4gICAgY2FzZSBcInJlc3BvbnNlLmNvbXBsZXRlZFwiOiB7XG4gICAgICBjb25zdCB1c2FnZSA9IHJlc3BvbnNlPy51c2FnZSA/IGdyb2tVc2FnZUZyb20ocmVzcG9uc2UudXNhZ2UpIDogdW5kZWZpbmVkO1xuXG4gICAgICBjb25zdCBjb21wbGV0ZWQ6IEdyb2tOb3JtYWxpemVkRXZlbnQgPSB7XG4gICAgICAgIHR5cGU6IFwiY29tcGxldGVkXCIsXG4gICAgICAgIHRlcm1pbmFsOiB0cnVlLFxuICAgICAgICByZXNwb25zZUlkOiByZXNwb25zZT8uaWQgPz8gXCJcIixcbiAgICAgIH07XG5cbiAgICAgIGlmIChyZXNwb25zZT8ubW9kZWwpIGNvbXBsZXRlZC5tb2RlbCA9IHJlc3BvbnNlLm1vZGVsO1xuXG4gICAgICBpZiAodXNhZ2UpIGNvbXBsZXRlZC51c2FnZSA9IHVzYWdlO1xuXG4gICAgICBpZiAocmVzcG9uc2U/Lm91dHB1dCkgY29tcGxldGVkLm91dHB1dCA9IHJlc3BvbnNlLm91dHB1dDtcblxuICAgICAgcmV0dXJuIGNvbXBsZXRlZDtcbiAgICB9XG5cbiAgICBjYXNlIFwicmVzcG9uc2UuaW5jb21wbGV0ZVwiOiB7XG4gICAgICBjb25zdCB1c2FnZSA9IHJlc3BvbnNlPy51c2FnZSA/IGdyb2tVc2FnZUZyb20ocmVzcG9uc2UudXNhZ2UpIDogdW5kZWZpbmVkO1xuICAgICAgY29uc3QgcmVhc29uID0gcmVzcG9uc2U/LmluY29tcGxldGVfZGV0YWlscz8ucmVhc29uO1xuXG4gICAgICBjb25zdCBpbmNvbXBsZXRlOiBHcm9rTm9ybWFsaXplZEV2ZW50ID0ge1xuICAgICAgICB0eXBlOiBcImluY29tcGxldGVcIixcbiAgICAgICAgdGVybWluYWw6IHRydWUsXG4gICAgICAgIHJlc3BvbnNlSWQ6IHJlc3BvbnNlPy5pZCA/PyBcIlwiLFxuICAgICAgfTtcblxuICAgICAgaWYgKHJlYXNvbikgaW5jb21wbGV0ZS5yZWFzb24gPSByZWFzb247XG5cbiAgICAgIGlmIChyZXNwb25zZT8ubW9kZWwpIGluY29tcGxldGUubW9kZWwgPSByZXNwb25zZS5tb2RlbDtcblxuICAgICAgaWYgKHVzYWdlKSBpbmNvbXBsZXRlLnVzYWdlID0gdXNhZ2U7XG5cbiAgICAgIHJldHVybiBpbmNvbXBsZXRlO1xuICAgIH1cblxuICAgIGNhc2UgXCJyZXNwb25zZS5mYWlsZWRcIjpcbiAgICBjYXNlIFwiZXJyb3JcIjoge1xuICAgICAgY29uc3QgbmVzdGVkID0gZXZlbnQuZXJyb3IgPz8gcmVzcG9uc2U/LmVycm9yID8/IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBuZXN0ZWQ/Lm1lc3NhZ2UgPz8gZXZlbnQubWVzc2FnZSA/PyBgR3JvayBzdHJlYW0gZW5kZWQgd2l0aCAke2V2ZW50LnR5cGV9YDtcbiAgICAgIGNvbnN0IGNvZGUgPSBuZXN0ZWQ/LmNvZGUgPz8gZXZlbnQuY29kZSA/PyB1bmRlZmluZWQ7XG5cbiAgICAgIHJldHVybiB7IHR5cGU6IFwiZXJyb3JcIiwgdGVybWluYWw6IHRydWUsIGVycm9yOiBuZXcgR3Jva1Byb3RvY29sRXJyb3IobWVzc2FnZSwgY29kZSkgfTtcbiAgICB9XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG5mdW5jdGlvbiBwYXJzZVNTRUJsb2NrKGJsb2NrOiBzdHJpbmcpOiBHcm9rUmF3U1NFRXZlbnQgfCB1bmRlZmluZWQge1xuICBjb25zdCBkYXRhOiBzdHJpbmdbXSA9IFtdO1xuICBsZXQgZXZlbnQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICBmb3IgKGNvbnN0IGxpbmUgb2YgYmxvY2suc3BsaXQoXCJcXG5cIikpIHtcbiAgICBpZiAobGluZS5zdGFydHNXaXRoKFwiOlwiKSkgY29udGludWU7XG4gICAgY29uc3Qgc2VwYXJhdG9yID0gbGluZS5pbmRleE9mKFwiOlwiKTtcbiAgICBjb25zdCBmaWVsZCA9IHNlcGFyYXRvciA8IDAgPyBsaW5lIDogbGluZS5zbGljZSgwLCBzZXBhcmF0b3IpO1xuICAgIGxldCB2YWx1ZSA9IHNlcGFyYXRvciA8IDAgPyBcIlwiIDogbGluZS5zbGljZShzZXBhcmF0b3IgKyAxKTtcblxuICAgIGlmICh2YWx1ZS5zdGFydHNXaXRoKFwiIFwiKSkgdmFsdWUgPSB2YWx1ZS5zbGljZSgxKTtcblxuICAgIGlmIChmaWVsZCA9PT0gXCJkYXRhXCIpIGRhdGEucHVzaCh2YWx1ZSk7XG4gICAgZWxzZSBpZiAoZmllbGQgPT09IFwiZXZlbnRcIikgZXZlbnQgPSB2YWx1ZTtcbiAgfVxuXG4gIGlmICghZGF0YS5sZW5ndGgpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgY29uc3QgcGFyc2VkOiBHcm9rUmF3U1NFRXZlbnQgPSB7IGRhdGE6IGRhdGEuam9pbihcIlxcblwiKSB9O1xuXG4gIGlmIChldmVudCAhPT0gdW5kZWZpbmVkKSBwYXJzZWQuZXZlbnQgPSBldmVudDtcblxuICByZXR1cm4gcGFyc2VkO1xufVxuXG4vKiogU3BsaXRzIGEgYnl0ZSBzdHJlYW0gaW50byBTU0UgYmxvY2tzIGFjcm9zcyBhcmJpdHJhcnkgVVRGLTgvY2h1bmsgYm91bmRhcmllcy4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiogcGFyc2VHcm9rU1NFKFxuICBib2R5OiBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5Pixcbik6IEFzeW5jR2VuZXJhdG9yPEdyb2tSYXdTU0VFdmVudD4ge1xuICBjb25zdCByZWFkZXIgPSBib2R5LmdldFJlYWRlcigpO1xuICBjb25zdCBkZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKCk7XG4gIGxldCBidWZmZXIgPSBcIlwiO1xuICAvLyBBIHRyYWlsaW5nIENSIG1heSBiZSB0aGUgZmlyc3QgaGFsZiBvZiBhIENSTEYgc3BsaXQgYWNyb3NzIGNodW5rczsgaG9sZCBpdCBiYWNrLlxuICBsZXQgcGVuZGluZyA9IFwiXCI7XG4gIGxldCBmaXJzdCA9IHRydWU7XG5cbiAgdHJ5IHtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgY29uc3QgeyBkb25lLCB2YWx1ZSB9ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcbiAgICAgIGxldCBjaHVuayA9IHBlbmRpbmcgKyBkZWNvZGVyLmRlY29kZSh2YWx1ZSwgeyBzdHJlYW06ICFkb25lIH0pO1xuICAgICAgcGVuZGluZyA9IFwiXCI7XG5cbiAgICAgIGlmIChmaXJzdCAmJiBjaHVuay5sZW5ndGgpIHtcbiAgICAgICAgaWYgKGNodW5rLnN0YXJ0c1dpdGgoXCJcXHVGRUZGXCIpKSBjaHVuayA9IGNodW5rLnNsaWNlKDEpO1xuICAgICAgICBmaXJzdCA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWRvbmUgJiYgY2h1bmsuZW5kc1dpdGgoXCJcXHJcIikpIHtcbiAgICAgICAgcGVuZGluZyA9IFwiXFxyXCI7XG4gICAgICAgIGNodW5rID0gY2h1bmsuc2xpY2UoMCwgLTEpO1xuICAgICAgfVxuXG4gICAgICBidWZmZXIgKz0gY2h1bmsucmVwbGFjZUFsbChcIlxcclxcblwiLCBcIlxcblwiKS5yZXBsYWNlQWxsKFwiXFxyXCIsIFwiXFxuXCIpO1xuICAgICAgbGV0IGluZGV4OiBudW1iZXI7XG5cbiAgICAgIHdoaWxlICgoaW5kZXggPSBidWZmZXIuaW5kZXhPZihcIlxcblxcblwiKSkgPj0gMCkge1xuICAgICAgICBjb25zdCBibG9jayA9IHBhcnNlU1NFQmxvY2soYnVmZmVyLnNsaWNlKDAsIGluZGV4KSk7XG4gICAgICAgIGJ1ZmZlciA9IGJ1ZmZlci5zbGljZShpbmRleCArIDIpO1xuXG4gICAgICAgIGlmIChibG9jaykgeWllbGQgYmxvY2s7XG4gICAgICB9XG5cbiAgICAgIGlmIChkb25lKSBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoYnVmZmVyLnRyaW0oKSkge1xuICAgICAgY29uc3QgYmxvY2sgPSBwYXJzZVNTRUJsb2NrKGJ1ZmZlcik7XG5cbiAgICAgIGlmIChibG9jaykgeWllbGQgYmxvY2s7XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIHJlYWRlci5yZWxlYXNlTG9jaygpO1xuICB9XG59XG5cbi8qKiBOb3JtYWxpemVkIHN0cmVhbSB0aGF0IGVuZHMgYXQgdGhlIGZpcnN0IHRlcm1pbmFsIGV2ZW50IGFuZCByZWplY3RzIGEgdHJ1bmNhdGVkIHN0cmVhbS4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiogbm9ybWFsaXplR3Jva1NTRShcbiAgYm9keTogUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4sXG4pOiBBc3luY0dlbmVyYXRvcjxHcm9rTm9ybWFsaXplZEV2ZW50PiB7XG4gIGZvciBhd2FpdCAoY29uc3QgcmF3IG9mIHBhcnNlR3Jva1NTRShib2R5KSkge1xuICAgIGNvbnN0IGV2ZW50ID0gbm9ybWFsaXplR3Jva0V2ZW50KHJhdyk7XG5cbiAgICBpZiAoIWV2ZW50KSBjb250aW51ZTtcbiAgICB5aWVsZCBldmVudDtcblxuICAgIGlmIChcInRlcm1pbmFsXCIgaW4gZXZlbnQpIHJldHVybjtcbiAgfVxuXG4gIHRocm93IG5ldyBHcm9rUHJvdG9jb2xFcnJvcihcIkdyb2sgU1NFIGNvbm5lY3Rpb24gY2xvc2VkIGJlZm9yZSBhIHRlcm1pbmFsIGV2ZW50XCIpO1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJlc3BvbnNlIGhlYWRlcnMgYW5kIEhUVFAgZXJyb3JzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxudHlwZSBIZWFkZXJTb3VyY2UgPSBIZWFkZXJzIHwgUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPj47XG5cbmZ1bmN0aW9uIGhlYWRlclZhbHVlKGhlYWRlcnM6IEhlYWRlclNvdXJjZSwgbmFtZTogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgaWYgKGhlYWRlcnMgaW5zdGFuY2VvZiBIZWFkZXJzKSByZXR1cm4gaGVhZGVycy5nZXQobmFtZSkgPz8gdW5kZWZpbmVkO1xuICBjb25zdCBrZXkgPSBPYmplY3Qua2V5cyhoZWFkZXJzKS5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS50b0xvd2VyQ2FzZSgpID09PSBuYW1lKTtcblxuICByZXR1cm4ga2V5ID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBoZWFkZXJzW2tleV07XG59XG5cbmZ1bmN0aW9uIGludGVnZXJIZWFkZXIoaGVhZGVyczogSGVhZGVyU291cmNlLCBuYW1lOiBzdHJpbmcpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICBjb25zdCB2YWx1ZSA9IGhlYWRlclZhbHVlKGhlYWRlcnMsIG5hbWUpPy50cmltKCk7XG5cbiAgaWYgKCF2YWx1ZSB8fCAhL15cXGQrJC8udGVzdCh2YWx1ZSkpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IHBhcnNlZCA9IE51bWJlcih2YWx1ZSk7XG5cbiAgcmV0dXJuIE51bWJlci5pc1NhZmVJbnRlZ2VyKHBhcnNlZCkgPyBwYXJzZWQgOiB1bmRlZmluZWQ7XG59XG5cbi8qKiBgUmV0cnktQWZ0ZXJgIGFzIHdob2xlIHNlY29uZHMgKGRlbHRhLXNlY29uZHMgb3IgSFRUUC1kYXRlKS4gVW5jYXBwZWQ7IGNhbGxlcnMgY2xhbXAuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VSZXRyeUFmdGVyU2VjKFxuICBoZWFkZXJzOiBIZWFkZXJTb3VyY2UsXG4gIG5vdzogbnVtYmVyID0gRGF0ZS5ub3coKSxcbik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHZhbHVlID0gaGVhZGVyVmFsdWUoaGVhZGVycywgXCJyZXRyeS1hZnRlclwiKT8udHJpbSgpO1xuXG4gIGlmICghdmFsdWUpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgaWYgKC9eXFxkKyQvLnRlc3QodmFsdWUpKSByZXR1cm4gTnVtYmVyKHZhbHVlKTtcbiAgY29uc3QgZGF0ZSA9IERhdGUucGFyc2UodmFsdWUpO1xuXG4gIGlmIChOdW1iZXIuaXNOYU4oZGF0ZSkpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgcmV0dXJuIE1hdGgubWF4KDAsIE1hdGguY2VpbCgoZGF0ZSAtIG5vdykgLyAxMDAwKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVNob3VsZFJldHJ5KGhlYWRlcnM6IEhlYWRlclNvdXJjZSk6IGJvb2xlYW4gfCB1bmRlZmluZWQge1xuICBjb25zdCB2YWx1ZSA9IGhlYWRlclZhbHVlKGhlYWRlcnMsIFwieC1zaG91bGQtcmV0cnlcIik/LnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuXG4gIGlmICh2YWx1ZSA9PT0gXCJ0cnVlXCIpIHJldHVybiB0cnVlO1xuXG4gIGlmICh2YWx1ZSA9PT0gXCJmYWxzZVwiKSByZXR1cm4gZmFsc2U7XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHcm9rUmVzcG9uc2VIZWFkZXJJbmZvIHtcbiAgY29udGV4dFdpbmRvdz86IG51bWJlcjtcbiAgbWF4Q29tcGxldGlvblRva2Vucz86IG51bWJlcjtcbiAgbW9kZWxzRXRhZz86IHN0cmluZztcbiAgcmVxdWVzdElkPzogc3RyaW5nO1xuICByYXRlTGltaXRMaW1pdFRva2Vucz86IG51bWJlcjtcbiAgcmF0ZUxpbWl0UmVtYWluaW5nVG9rZW5zPzogbnVtYmVyO1xuICByYXRlTGltaXRMaW1pdFJlcXVlc3RzPzogbnVtYmVyO1xuICByYXRlTGltaXRSZW1haW5pbmdSZXF1ZXN0cz86IG51bWJlcjtcbiAgLyoqIGB4LXplcm8tZGF0YS1yZXRlbnRpb246IHRydWVgOiB0aGUgYWNjb3VudCBoYXMgWmVybyBEYXRhIFJldGVudGlvbiBvbiAoVTAsIHBsYW4gwqcxMSkuICovXG4gIHplcm9EYXRhUmV0ZW50aW9uPzogYm9vbGVhbjtcbn1cblxuLyoqIFJlc3BvbnNlIGhlYWRlcnMgZ3Jvay1idWlsZCByZWFkcyAoY2xpZW50LnJzOjE4Ny0yMjQpIHBsdXMgdGhlIG9ic2VydmVkIHJhdGUtbGltaXQgc2V0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWRHcm9rUmVzcG9uc2VIZWFkZXJzKGhlYWRlcnM6IEhlYWRlclNvdXJjZSk6IEdyb2tSZXNwb25zZUhlYWRlckluZm8ge1xuICBjb25zdCB6ZHIgPSBoZWFkZXJWYWx1ZShoZWFkZXJzLCBcIngtemVyby1kYXRhLXJldGVudGlvblwiKT8udHJpbSgpLnRvTG93ZXJDYXNlKCk7XG5cbiAgY29uc3QgZW50cmllczogQXJyYXk8W2tleW9mIEdyb2tSZXNwb25zZUhlYWRlckluZm8sIG51bWJlciB8IHN0cmluZyB8IGJvb2xlYW4gfCB1bmRlZmluZWRdPiA9IFtcbiAgICBbXCJjb250ZXh0V2luZG93XCIsIGludGVnZXJIZWFkZXIoaGVhZGVycywgXCJ4LWdyb2stY29udGV4dC13aW5kb3dcIildLFxuICAgIFtcIm1heENvbXBsZXRpb25Ub2tlbnNcIiwgaW50ZWdlckhlYWRlcihoZWFkZXJzLCBcIngtZ3Jvay1tYXgtY29tcGxldGlvbi10b2tlbnNcIildLFxuICAgIFtcIm1vZGVsc0V0YWdcIiwgaGVhZGVyVmFsdWUoaGVhZGVycywgXCJ4LW1vZGVscy1ldGFnXCIpXSxcbiAgICBbXCJyZXF1ZXN0SWRcIiwgaGVhZGVyVmFsdWUoaGVhZGVycywgXCJ4LXJlcXVlc3QtaWRcIildLFxuICAgIFtcInJhdGVMaW1pdExpbWl0VG9rZW5zXCIsIGludGVnZXJIZWFkZXIoaGVhZGVycywgXCJ4LXJhdGVsaW1pdC1saW1pdC10b2tlbnNcIildLFxuICAgIFtcInJhdGVMaW1pdFJlbWFpbmluZ1Rva2Vuc1wiLCBpbnRlZ2VySGVhZGVyKGhlYWRlcnMsIFwieC1yYXRlbGltaXQtcmVtYWluaW5nLXRva2Vuc1wiKV0sXG4gICAgW1wicmF0ZUxpbWl0TGltaXRSZXF1ZXN0c1wiLCBpbnRlZ2VySGVhZGVyKGhlYWRlcnMsIFwieC1yYXRlbGltaXQtbGltaXQtcmVxdWVzdHNcIildLFxuICAgIFtcInJhdGVMaW1pdFJlbWFpbmluZ1JlcXVlc3RzXCIsIGludGVnZXJIZWFkZXIoaGVhZGVycywgXCJ4LXJhdGVsaW1pdC1yZW1haW5pbmctcmVxdWVzdHNcIildLFxuICAgIFtcInplcm9EYXRhUmV0ZW50aW9uXCIsIHpkciA9PT0gXCJ0cnVlXCIgPyB0cnVlIDogemRyID09PSBcImZhbHNlXCIgPyBmYWxzZSA6IHVuZGVmaW5lZF0sXG4gIF07XG5cbiAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhlbnRyaWVzLmZpbHRlcigoWywgdmFsdWVdKSA9PiB2YWx1ZSAhPT0gdW5kZWZpbmVkKSk7XG59XG5cbmV4cG9ydCB0eXBlIEdyb2tIdHRwRXJyb3JLaW5kID1cbiAgfCBcImF1dGhcIlxuICB8IFwidmVyc2lvbl9nYXRlXCJcbiAgfCBcInJhdGVfbGltaXRlZFwiXG4gIHwgXCJxdW90YV9leGhhdXN0ZWRcIlxuICB8IFwiZW50aXRsZW1lbnRcIlxuICB8IFwiaW52YWxpZF9yZXF1ZXN0XCJcbiAgfCBcInRyYW5zaWVudFwiXG4gIHwgXCJwZXJtYW5lbnRcIjtcblxuZXhwb3J0IGludGVyZmFjZSBHcm9rSHR0cEVycm9yQ2xhc3NpZmljYXRpb24ge1xuICBraW5kOiBHcm9rSHR0cEVycm9yS2luZDtcbiAgc3RhdHVzOiBudW1iZXI7XG4gIHJldHJ5QWZ0ZXJTZWM/OiBudW1iZXI7XG4gIGNvZGU/OiBzdHJpbmc7XG4gIG1lc3NhZ2U/OiBzdHJpbmc7XG4gIC8qKiBgeC1zaG91bGQtcmV0cnlgIG92ZXJyaWRlIGZyb20gdGhlIHNlcnZlcjsgY2FsbGVycyBtdXN0IGhvbm9yIGl0IG92ZXIgYGtpbmRgLiAqL1xuICBzaG91bGRSZXRyeT86IGJvb2xlYW47XG4gIC8qKiBNaW5pbXVtIENMSSB2ZXJzaW9uIG5hbWVkIGJ5IGEgNDI2IGJvZHkuICovXG4gIG1pbkNsaWVudFZlcnNpb24/OiBzdHJpbmc7XG59XG5cbmNvbnN0IE1BWF9FUlJPUl9NRVNTQUdFX0xFTkdUSCA9IDUwMDtcbmNvbnN0IFNVQlNDUklQVElPTl9DT0RFX1BBVFRFUk4gPSAvc3Vic2NyaXB0aW9uOlthLXowLTldW2EtejAtOV8uLV0qL2k7XG5cbmNvbnN0IEVycm9yT2JqZWN0ID0gei5sb29zZU9iamVjdCh7XG4gIGNvZGU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgbWVzc2FnZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICB0eXBlOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG59KTtcblxuY29uc3QgRXJyb3JCb2R5ID0gei5sb29zZU9iamVjdCh7XG4gIGNvZGU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgbWVzc2FnZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICBlcnJvcjogei51bmlvbihbei5zdHJpbmcoKSwgRXJyb3JPYmplY3RdKS5vcHRpb25hbCgpLFxufSk7XG5cbmludGVyZmFjZSBHcm9rRXJyb3JCb2R5IHtcbiAgY29kZT86IHN0cmluZztcbiAgbWVzc2FnZT86IHN0cmluZztcbn1cblxuZnVuY3Rpb24gcGFyc2VFcnJvckJvZHkoYm9keVRleHQ6IHN0cmluZyk6IEdyb2tFcnJvckJvZHkge1xuICBsZXQganNvbjogSnNvblZhbHVlO1xuXG4gIHRyeSB7XG4gICAgLy8gSlNPTi5wYXJzZSB3aXRob3V0IGEgcmV2aXZlciB5aWVsZHMgb25seSBKU09OIHZhbHVlcy5cbiAgICBqc29uID0gSlNPTi5wYXJzZShib2R5VGV4dCk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBib2R5VGV4dC50cmltKCkgPyB7IG1lc3NhZ2U6IGJvZHlUZXh0LnRyaW0oKSB9IDoge307XG4gIH1cblxuICBjb25zdCBwYXJzZWQgPSBFcnJvckJvZHkuc2FmZVBhcnNlKGpzb24pO1xuXG4gIGlmICghcGFyc2VkLnN1Y2Nlc3MpIHJldHVybiBib2R5VGV4dC50cmltKCkgPyB7IG1lc3NhZ2U6IGJvZHlUZXh0LnRyaW0oKSB9IDoge307XG4gIGNvbnN0IHsgZXJyb3IgfSA9IHBhcnNlZC5kYXRhO1xuICBjb25zdCBlcnJvclRleHQgPSB6LnN0cmluZygpLnNhZmVQYXJzZShlcnJvcikuZGF0YTtcbiAgY29uc3QgZXJyb3JPYmplY3QgPSBFcnJvck9iamVjdC5zYWZlUGFyc2UoZXJyb3IpLmRhdGE7XG4gIGNvbnN0IGNvZGUgPSBwYXJzZWQuZGF0YS5jb2RlID8/IGVycm9yT2JqZWN0Py5jb2RlO1xuICBjb25zdCBtZXNzYWdlID0gZXJyb3JUZXh0ID8/IGVycm9yT2JqZWN0Py5tZXNzYWdlID8/IHBhcnNlZC5kYXRhLm1lc3NhZ2U7XG4gIGNvbnN0IGJvZHk6IEdyb2tFcnJvckJvZHkgPSB7fTtcblxuICBpZiAoY29kZSkgYm9keS5jb2RlID0gY29kZTtcblxuICBpZiAobWVzc2FnZSkgYm9keS5tZXNzYWdlID0gbWVzc2FnZTtcblxuICByZXR1cm4gYm9keTtcbn1cblxuLyoqXG4gKiBDbGFzc2lmaWVzIGEgbm9uLTJ4eCBwcm94eSBvciBhcGkueC5haSByZXNwb25zZS4gUGFzcyBgc3RhdHVzID0gMGAgZm9yIGEgbmV0d29yayBmYWlsdXJlLlxuICogVGhlIGJvZHkgaXMgbm90IHRydXN0ZWQgdG8gYmUgSlNPTi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsYXNzaWZ5R3Jva0h0dHBFcnJvcihcbiAgc3RhdHVzOiBudW1iZXIsXG4gIGJvZHlUZXh0OiBzdHJpbmcsXG4gIGhlYWRlcnM6IEhlYWRlclNvdXJjZSxcbik6IEdyb2tIdHRwRXJyb3JDbGFzc2lmaWNhdGlvbiB7XG4gIGNvbnN0IGJvZHkgPSBwYXJzZUVycm9yQm9keShib2R5VGV4dCk7XG5cbiAgY29uc3QgbWVzc2FnZSA9XG4gICAgYm9keS5tZXNzYWdlID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBib2R5Lm1lc3NhZ2Uuc2xpY2UoMCwgTUFYX0VSUk9SX01FU1NBR0VfTEVOR1RIKTtcblxuICBjb25zdCBzaG91bGRSZXRyeSA9IHBhcnNlU2hvdWxkUmV0cnkoaGVhZGVycyk7XG4gIGNvbnN0IHJldHJ5QWZ0ZXJTZWMgPSBwYXJzZVJldHJ5QWZ0ZXJTZWMoaGVhZGVycyk7XG5cbiAgY29uc3QgYmFzZTogT21pdDxHcm9rSHR0cEVycm9yQ2xhc3NpZmljYXRpb24sIFwia2luZFwiPiA9IHsgc3RhdHVzIH07XG5cbiAgaWYgKGJvZHkuY29kZSkgYmFzZS5jb2RlID0gYm9keS5jb2RlO1xuXG4gIGlmIChtZXNzYWdlICE9PSB1bmRlZmluZWQpIGJhc2UubWVzc2FnZSA9IG1lc3NhZ2U7XG5cbiAgaWYgKHNob3VsZFJldHJ5ICE9PSB1bmRlZmluZWQpIGJhc2Uuc2hvdWxkUmV0cnkgPSBzaG91bGRSZXRyeTtcblxuICBpZiAocmV0cnlBZnRlclNlYyAhPT0gdW5kZWZpbmVkKSBiYXNlLnJldHJ5QWZ0ZXJTZWMgPSByZXRyeUFmdGVyU2VjO1xuXG4gIGNvbnN0IHN1YnNjcmlwdGlvbkNvZGUgPSBTVUJTQ1JJUFRJT05fQ09ERV9QQVRURVJOLmV4ZWMoYm9keVRleHQpPy5bMF07XG5cbiAgaWYgKHN0YXR1cyA9PT0gNDAxKSByZXR1cm4geyBraW5kOiBcImF1dGhcIiwgLi4uYmFzZSB9O1xuXG4gIGlmIChzdGF0dXMgPT09IDQyNikge1xuICAgIGNvbnN0IG1pbkNsaWVudFZlcnNpb24gPSAvXFxidmVyc2lvblxccysoXFxkK1xcLlxcZCtcXC5cXGQrKVxccytvciBsYXRlci9pLmV4ZWMoYm9keVRleHQpPy5bMV07XG4gICAgY29uc3QgZ2F0ZTogR3Jva0h0dHBFcnJvckNsYXNzaWZpY2F0aW9uID0geyBraW5kOiBcInZlcnNpb25fZ2F0ZVwiLCAuLi5iYXNlIH07XG5cbiAgICBpZiAobWluQ2xpZW50VmVyc2lvbikgZ2F0ZS5taW5DbGllbnRWZXJzaW9uID0gbWluQ2xpZW50VmVyc2lvbjtcblxuICAgIHJldHVybiBnYXRlO1xuICB9XG5cbiAgaWYgKHN0YXR1cyA9PT0gNDI5KSB7XG4gICAgaWYgKHN1YnNjcmlwdGlvbkNvZGUpIHJldHVybiB7IGtpbmQ6IFwicXVvdGFfZXhoYXVzdGVkXCIsIC4uLmJhc2UsIGNvZGU6IHN1YnNjcmlwdGlvbkNvZGUgfTtcblxuICAgIHJldHVybiB7IGtpbmQ6IFwicmF0ZV9saW1pdGVkXCIsIC4uLmJhc2UgfTtcbiAgfVxuXG4gIGlmIChzdGF0dXMgPT09IDQwMykgcmV0dXJuIHsga2luZDogXCJlbnRpdGxlbWVudFwiLCAuLi5iYXNlIH07XG5cbiAgaWYgKHN0YXR1cyA9PT0gNDAwIHx8IHN0YXR1cyA9PT0gNDIyKSByZXR1cm4geyBraW5kOiBcImludmFsaWRfcmVxdWVzdFwiLCAuLi5iYXNlIH07XG5cbiAgaWYgKHN0YXR1cyA9PT0gMCB8fCBzdGF0dXMgPT09IDQwOCB8fCBzdGF0dXMgPj0gNTAwKSByZXR1cm4geyBraW5kOiBcInRyYW5zaWVudFwiLCAuLi5iYXNlIH07XG5cbiAgcmV0dXJuIHsga2luZDogXCJwZXJtYW5lbnRcIiwgLi4uYmFzZSB9O1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7OztBQXNGQSxNQUFhLGtDQUFrQztBQUUvQyxTQUFTLFdBQVcsTUFBb0Q7Q0FDdEUsSUFBSSxLQUFLLFNBQVMsYUFBYSxPQUFPO0NBSXRDLElBQUksQ0FBQyxLQUFLLG1CQUFtQixPQUFPO0NBRXBDLE1BQU0sV0FBOEQ7RUFDbEUsTUFBTTtFQUNOLFNBQVMsS0FBSyxXQUFXLENBQUM7RUFDMUIsbUJBQW1CLEtBQUs7Q0FDMUI7Q0FFQSxJQUFJLEtBQUssSUFBSSxTQUFTLEtBQUssS0FBSztDQUVoQyxPQUFP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
@@ -0,0 +1,55 @@
1
+ //#region src/utils/providers/grok/grok-constants.ts
2
+ const GROK_CHAT_PROXY_URL = "https://cli-chat-proxy.grok.com/v1";
3
+ const GROK_PUBLIC_API_URL = "https://api.x.ai/v1";
4
+ const GROK_AUTH_ISSUER = "https://auth.x.ai";
5
+ const GROK_OAUTH_CLIENT_ID = "b1a00492-073a-47ea-816f-4c329264a828";
6
+ const GROK_OAUTH_SCOPES = Object.freeze([
7
+ "openid",
8
+ "profile",
9
+ "email",
10
+ "offline_access",
11
+ "grok-cli:access",
12
+ "api:access",
13
+ "conversations:read",
14
+ "conversations:write",
15
+ "workspaces:read",
16
+ "workspaces:write"
17
+ ]);
18
+ const GROK_OAUTH_REFERRER = "grok-build";
19
+ const GROK_DEVICE_CODE_URL = "https://auth.x.ai/oauth2/device/code";
20
+ const GROK_DEVICE_TOKEN_URL = "https://auth.x.ai/oauth2/token";
21
+ const GROK_BUILD_VERSION = "1.0.60";
22
+ const GROK_BUILD_COMMIT = "01a8e1c591c0";
23
+ const GROK_MIN_CLIENT_VERSION_OBSERVED = "1.0.13";
24
+ const GROK_CLIENT_IDENTIFIER = "grok-shell";
25
+ const GROK_CLIENT_MODE = "headless";
26
+ const GROK_DEFAULT_MODEL = "grok-4.7";
27
+ const GROK_IMAGE_DEFAULT_MODEL = "grok-imagine-image-quality";
28
+ const GROK_VIDEO_DEFAULT_MODEL = "grok-imagine-video-1.5";
29
+ const GROK_STT_DEFAULT_MODEL = "grok-voice-transcribe-2.0";
30
+ const GROK_USD_PER_TICK = 1e-10;
31
+ const GROK_REASONING_EFFORTS = Object.freeze([
32
+ "xhigh",
33
+ "high",
34
+ "medium",
35
+ "low"
36
+ ]);
37
+ const GROK_SEED_MODELS = Object.freeze([
38
+ "grok-4.7",
39
+ "grok-4.7-build-fast",
40
+ "grok-4.6",
41
+ "grok-4.5"
42
+ ].map((id) => Object.freeze({
43
+ id,
44
+ contextWindow: 256e3,
45
+ reasoningEfforts: GROK_REASONING_EFFORTS,
46
+ defaultEffort: "high"
47
+ })));
48
+ const GROK_COMPACTION_AT = 204800;
49
+ const GROK_COMPACTIONS_REMAINING_DEFAULT = 1;
50
+ const GROK_DOOM_LOOP_CHECK = 1024;
51
+ const GROK_EXACT_REPETITION_CHECK = 64;
52
+ //#endregion
53
+ export { GROK_AUTH_ISSUER, GROK_BUILD_COMMIT, GROK_BUILD_VERSION, GROK_CHAT_PROXY_URL, GROK_CLIENT_IDENTIFIER, GROK_CLIENT_MODE, GROK_COMPACTIONS_REMAINING_DEFAULT, GROK_COMPACTION_AT, GROK_DEFAULT_MODEL, GROK_DEVICE_CODE_URL, GROK_DEVICE_TOKEN_URL, GROK_DOOM_LOOP_CHECK, GROK_EXACT_REPETITION_CHECK, GROK_IMAGE_DEFAULT_MODEL, GROK_MIN_CLIENT_VERSION_OBSERVED, GROK_OAUTH_CLIENT_ID, GROK_OAUTH_REFERRER, GROK_OAUTH_SCOPES, GROK_PUBLIC_API_URL, GROK_REASONING_EFFORTS, GROK_SEED_MODELS, GROK_STT_DEFAULT_MODEL, GROK_USD_PER_TICK, GROK_VIDEO_DEFAULT_MODEL };
54
+
55
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3Jvay1jb25zdGFudHMuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9ncm9rL2dyb2stY29uc3RhbnRzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEdyb2sgKHhBSSkgZmluZ2VycHJpbnQgbGl0ZXJhbHMuIEJ1bXBpbmcgR1JPS19CVUlMRF9WRVJTSU9OIG1lYW5zOiBlZGl0IHRoZSBjb25zdGFudCxcbi8vIHJlLWNhcHR1cmUgX19maXh0dXJlc19fL2dvbGRlbi1yZXNwb25zZXMtPHZlcj4uanNvbiBmcm9tIHRoZSBpbnN0YWxsZWQgYmluYXJ5LCBhbmQgcmVjb3JkXG4vLyBpdHMgYnVpbGQgaWQgaW4gR1JPS19CVUlMRF9DT01NSVQuXG5cbi8vIGdyb2stYnVpbGQgMS4wLjQ1IHhhaS1ncm9rLWVudi9zcmMvbGliLnJzOjIxXG5leHBvcnQgY29uc3QgR1JPS19DSEFUX1BST1hZX1VSTCA9IFwiaHR0cHM6Ly9jbGktY2hhdC1wcm94eS5ncm9rLmNvbS92MVwiO1xuXG4vLyBncm9rLWJ1aWxkIDEuMC40NSB4YWktZ3Jvay1jb25maWcvc3JjL2VuZHBvaW50cy5yczo0XG5leHBvcnQgY29uc3QgR1JPS19QVUJMSUNfQVBJX1VSTCA9IFwiaHR0cHM6Ly9hcGkueC5haS92MVwiO1xuXG4vLyBncm9rLWJ1aWxkIDEuMC40NSB4YWktZ3Jvay1sb2dpbi9zcmMvY29uZmlnLnJzOjEyNFxuZXhwb3J0IGNvbnN0IEdST0tfQVVUSF9JU1NVRVIgPSBcImh0dHBzOi8vYXV0aC54LmFpXCI7XG5cbi8vIGdyb2stYnVpbGQgMS4wLjQ1IHhhaS1ncm9rLWxvZ2luL3NyYy9jb25maWcucnM6MzgwIChwbGFpbnRleHQgaW4gbWFuYWdlcl90ZXN0cy5yczoxNjQpXG5leHBvcnQgY29uc3QgR1JPS19PQVVUSF9DTElFTlRfSUQgPSBcImIxYTAwNDkyLTA3M2EtNDdlYS04MTZmLTRjMzI5MjY0YTgyOFwiO1xuXG4vLyBncm9rLWJ1aWxkIDEuMC40NSB4YWktZ3Jvay1sb2dpbi9zcmMvY29uZmlnLnJzOjE2LTI4IChvcmRlciBmcm96ZW4gYnkgY29uZmlnLnJzOjYyNClcbmV4cG9ydCBjb25zdCBHUk9LX09BVVRIX1NDT1BFUyA9IE9iamVjdC5mcmVlemUoW1xuICBcIm9wZW5pZFwiLFxuICBcInByb2ZpbGVcIixcbiAgXCJlbWFpbFwiLFxuICBcIm9mZmxpbmVfYWNjZXNzXCIsXG4gIFwiZ3Jvay1jbGk6YWNjZXNzXCIsXG4gIFwiYXBpOmFjY2Vzc1wiLFxuICBcImNvbnZlcnNhdGlvbnM6cmVhZFwiLFxuICBcImNvbnZlcnNhdGlvbnM6d3JpdGVcIixcbiAgXCJ3b3Jrc3BhY2VzOnJlYWRcIixcbiAgXCJ3b3Jrc3BhY2VzOndyaXRlXCIsXG5dIGFzIGNvbnN0KTtcblxuLy8gZ3Jvay1idWlsZCAxLjAuNDUgeGFpLWdyb2stbG9naW4vc3JjL2NvbmZpZy5yczoxNTJcbmV4cG9ydCBjb25zdCBHUk9LX09BVVRIX1JFRkVSUkVSID0gXCJncm9rLWJ1aWxkXCI7XG5cbi8vIGdyb2stYnVpbGQgMS4wLjQ1IHhhaS1ncm9rLWxvZ2luL3NyYy9kZXZpY2VfY29kZS5yczoxMTdcbmV4cG9ydCBjb25zdCBHUk9LX0RFVklDRV9DT0RFX1VSTCA9IFwiaHR0cHM6Ly9hdXRoLnguYWkvb2F1dGgyL2RldmljZS9jb2RlXCI7XG5cbi8vIGdyb2stYnVpbGQgMS4wLjQ1IHhhaS1ncm9rLWxvZ2luL3NyYy9kZXZpY2VfY29kZS5yczoxODdcbmV4cG9ydCBjb25zdCBHUk9LX0RFVklDRV9UT0tFTl9VUkwgPSBcImh0dHBzOi8vYXV0aC54LmFpL29hdXRoMi90b2tlblwiO1xuXG4vLyBVMCBjYXB0dXJlIDIwMjYtMTAtMTYgKGluc3RhbGxlZCBncm9rLWJ1aWxkIDEuMC42MCwgdXNlciBkZWNpc2lvbilcbmV4cG9ydCBjb25zdCBHUk9LX0JVSUxEX1ZFUlNJT04gPSBcIjEuMC42MFwiIGFzIGNvbnN0O1xuXG4vLyBVMCBjYXB0dXJlIDIwMjYtMTAtMTYgKEhvbWVicmV3IGNhc2sgYnVpbGQgaWQgb2YgMS4wLjYwKVxuZXhwb3J0IGNvbnN0IEdST0tfQlVJTERfQ09NTUlUID0gXCIwMWE4ZTFjNTkxYzBcIjtcblxuLy8gVTAgY2FwdHVyZSAyMDI2LTEwLTE2IChHRVQgL3NldHRpbmdzIG1pbl9jbGllbnRfdmVyc2lvbjsgSFRUUCA0MjYgYmVsb3cgaXQpXG5leHBvcnQgY29uc3QgR1JPS19NSU5fQ0xJRU5UX1ZFUlNJT05fT0JTRVJWRUQgPSBcIjEuMC4xM1wiO1xuXG4vLyBncm9rLWJ1aWxkIDEuMC40NSB4YWktZ3Jvay1odHRwL3NyYy9saWIucnM6MjQ2LTI0OFxuZXhwb3J0IGNvbnN0IEdST0tfQ0xJRU5UX0lERU5USUZJRVIgPSBcImdyb2stc2hlbGxcIjtcblxuLy8gVTAgY2FwdHVyZSAyMDI2LTEwLTE2IChncm9rIC1wIHNlbmRzIGhlYWRsZXNzOyB4YWktZ3Jvay1odHRwL3NyYy9saWIucnM6MjUwLTI2MClcbmV4cG9ydCBjb25zdCBHUk9LX0NMSUVOVF9NT0RFID0gXCJoZWFkbGVzc1wiO1xuXG4vLyBVMCBjYXB0dXJlIDIwMjYtMTAtMTYgKEdFVCAvbW9kZWxzIGRlZmF1bHQgYW5kIC9zZXR0aW5ncyBkZWZhdWx0X21vZGVsKVxuZXhwb3J0IGNvbnN0IEdST0tfREVGQVVMVF9NT0RFTCA9IFwiZ3Jvay00LjdcIjtcblxuLy8gZ3Jvay1idWlsZCAxLjAuNDUgaW1hZ2VfZ2VuL21vZC5yczozM1xuZXhwb3J0IGNvbnN0IEdST0tfSU1BR0VfREVGQVVMVF9NT0RFTCA9IFwiZ3Jvay1pbWFnaW5lLWltYWdlLXF1YWxpdHlcIjtcblxuLy8gZ3Jvay1idWlsZCAxLjAuNDUgdmlkZW9fZ2VuL21vZC5yczozNi00MFxuZXhwb3J0IGNvbnN0IEdST0tfVklERU9fREVGQVVMVF9NT0RFTCA9IFwiZ3Jvay1pbWFnaW5lLXZpZGVvLTEuNVwiO1xuXG4vLyBVMCBjYXB0dXJlIDIwMjYtMTAtMTYgKHBhY2tldCBjb250cmFjdDsgdGhlIFNUVCBwcm9iZSBkaWQgbm90IG5hbWUgYSBtb2RlbClcbmV4cG9ydCBjb25zdCBHUk9LX1NUVF9ERUZBVUxUX01PREVMID0gXCJncm9rLXZvaWNlLXRyYW5zY3JpYmUtMi4wXCI7XG5cbi8vIFUwIGNhcHR1cmUgMjAyNi0xMC0xNiAoYXBpLnguYWkgL2xhbmd1YWdlLW1vZGVscyBwcmljZXMgdnMgcHVibGljIHBlci10b2tlbiBwcmljaW5nKVxuZXhwb3J0IGNvbnN0IEdST0tfVVNEX1BFUl9USUNLID0gMWUtMTA7XG5cbi8vIFUwIGNhcHR1cmUgMjAyNi0xMC0xNiAoR0VUIC9tb2RlbHMgcmVhc29uaW5nX2VmZm9ydHMsIGlkZW50aWNhbCBvbiBhbGwgZm91ciBtb2RlbHMpXG5leHBvcnQgY29uc3QgR1JPS19SRUFTT05JTkdfRUZGT1JUUyA9IE9iamVjdC5mcmVlemUoW1wieGhpZ2hcIiwgXCJoaWdoXCIsIFwibWVkaXVtXCIsIFwibG93XCJdIGFzIGNvbnN0KTtcblxuZXhwb3J0IHR5cGUgR3Jva1JlYXNvbmluZ0VmZm9ydCA9ICh0eXBlb2YgR1JPS19SRUFTT05JTkdfRUZGT1JUUylbbnVtYmVyXTtcblxuZXhwb3J0IGludGVyZmFjZSBHcm9rU2VlZE1vZGVsIHtcbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgY29udGV4dFdpbmRvdzogbnVtYmVyO1xuICByZWFkb25seSByZWFzb25pbmdFZmZvcnRzOiByZWFkb25seSBHcm9rUmVhc29uaW5nRWZmb3J0W107XG4gIHJlYWRvbmx5IGRlZmF1bHRFZmZvcnQ6IEdyb2tSZWFzb25pbmdFZmZvcnQ7XG59XG5cbi8vIFUwIGNhcHR1cmUgMjAyNi0xMC0xNiAoR0VUIC9tb2RlbHM6IGZvdXIgaWRzLCBjb250ZXh0X3dpbmRvdyAyNTYwMDAsIGRlZmF1bHQgZWZmb3J0IGhpZ2gpXG5leHBvcnQgY29uc3QgR1JPS19TRUVEX01PREVMUzogcmVhZG9ubHkgR3Jva1NlZWRNb2RlbFtdID0gT2JqZWN0LmZyZWV6ZShcbiAgW1wiZ3Jvay00LjdcIiwgXCJncm9rLTQuNy1idWlsZC1mYXN0XCIsIFwiZ3Jvay00LjZcIiwgXCJncm9rLTQuNVwiXS5tYXAoXG4gICAgKGlkKTogR3Jva1NlZWRNb2RlbCA9PlxuICAgICAgT2JqZWN0LmZyZWV6ZSh7XG4gICAgICAgIGlkLFxuICAgICAgICBjb250ZXh0V2luZG93OiAyNTZfMDAwLFxuICAgICAgICByZWFzb25pbmdFZmZvcnRzOiBHUk9LX1JFQVNPTklOR19FRkZPUlRTLFxuICAgICAgICBkZWZhdWx0RWZmb3J0OiBcImhpZ2hcIixcbiAgICAgIH0pLFxuICApLFxuKTtcblxuLy8gVTAgY2FwdHVyZSAyMDI2LTEwLTE2ICh4LWNvbXBhY3Rpb24tYXQgcmVxdWVzdCBoZWFkZXIpXG5leHBvcnQgY29uc3QgR1JPS19DT01QQUNUSU9OX0FUID0gMjA0XzgwMDtcblxuLy8gVTAgY2FwdHVyZSAyMDI2LTEwLTE2ICh4LWNvbXBhY3Rpb25zLXJlbWFpbmluZyByZXF1ZXN0IGhlYWRlcilcbmV4cG9ydCBjb25zdCBHUk9LX0NPTVBBQ1RJT05TX1JFTUFJTklOR19ERUZBVUxUID0gMTtcblxuLy8gVTAgY2FwdHVyZSAyMDI2LTEwLTE2ICh4LWdyb2stZG9vbS1sb29wLWNoZWNrIHJlcXVlc3QgaGVhZGVyKVxuZXhwb3J0IGNvbnN0IEdST0tfRE9PTV9MT09QX0NIRUNLID0gMTAyNDtcblxuLy8gVTAgY2FwdHVyZSAyMDI2LTEwLTE2ICh4LWdyb2stZXhhY3QtcmVwZXRpdGlvbi1jaGVjayByZXF1ZXN0IGhlYWRlcilcbmV4cG9ydCBjb25zdCBHUk9LX0VYQUNUX1JFUEVUSVRJT05fQ0hFQ0sgPSA2NDtcbiJdLCJtYXBwaW5ncyI6IjtBQUtBLE1BQWEsc0JBQXNCO0FBR25DLE1BQWEsc0JBQXNCO0FBR25DLE1BQWEsbUJBQW1CO0FBR2hDLE1BQWEsdUJBQXVCO0FBR3BDLE1BQWEsb0JBQW9CLE9BQU8sT0FBTztDQUM3QztDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtBQUNGLENBQVU7QUFHVixNQUFhLHNCQUFzQjtBQUduQyxNQUFhLHVCQUF1QjtBQUdwQyxNQUFhLHdCQUF3QjtBQUdyQyxNQUFhLHFCQUFxQjtBQUdsQyxNQUFhLG9CQUFvQjtBQUdqQyxNQUFhLG1DQUFtQztBQUdoRCxNQUFhLHlCQUF5QjtBQUd0QyxNQUFhLG1CQUFtQjtBQUdoQyxNQUFhLHFCQUFxQjtBQUdsQyxNQUFhLDJCQUEyQjtBQUd4QyxNQUFhLDJCQUEyQjtBQUd4QyxNQUFhLHlCQUF5QjtBQUd0QyxNQUFhLG9CQUFvQjtBQUdqQyxNQUFhLHlCQUF5QixPQUFPLE9BQU87Q0FBQztDQUFTO0NBQVE7Q0FBVTtBQUFLLENBQVU7QUFZL0YsTUFBYSxtQkFBNkMsT0FBTyxPQUMvRDtDQUFDO0NBQVk7Q0FBdUI7Q0FBWTtBQUFVLENBQUMsQ0FBQyxLQUN6RCxPQUNDLE9BQU8sT0FBTztDQUNaO0NBQ0EsZUFBZTtDQUNmLGtCQUFrQjtDQUNsQixlQUFlO0FBQ2pCLENBQUMsQ0FDTCxDQUNGO0FBR0EsTUFBYSxxQkFBcUI7QUFHbEMsTUFBYSxxQ0FBcUM7QUFHbEQsTUFBYSx1QkFBdUI7QUFHcEMsTUFBYSw4QkFBOEIifQ==