@vasfal/vellum 0.1.0 → 0.1.2

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 (484) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +5 -5
  3. package/.next/build-manifest.json +13 -14
  4. package/.next/next-minimal-server.js.nft.json +1 -1
  5. package/.next/next-server.js.nft.json +1 -1
  6. package/.next/prerender-manifest.json +3 -3
  7. package/.next/required-server-files.js +2 -0
  8. package/.next/required-server-files.json +2 -0
  9. package/.next/server/app/(app)/page.js +2 -15
  10. package/.next/server/app/(app)/page.js.nft.json +1 -1
  11. package/.next/server/app/(app)/page_client-reference-manifest.js +1 -3
  12. package/.next/server/app/(app)/session/[name]/page.js +2 -15
  13. package/.next/server/app/(app)/session/[name]/page.js.nft.json +1 -1
  14. package/.next/server/app/(app)/session/[name]/page_client-reference-manifest.js +1 -3
  15. package/.next/server/app/(app)/settings/key/page.js +2 -15
  16. package/.next/server/app/(app)/settings/key/page.js.nft.json +1 -1
  17. package/.next/server/app/(app)/settings/key/page_client-reference-manifest.js +1 -3
  18. package/.next/server/app/_global-error/page.js +32 -9
  19. package/.next/server/app/_global-error/page.js.nft.json +1 -1
  20. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -3
  21. package/.next/server/app/_global-error.html +1 -1
  22. package/.next/server/app/_global-error.meta +2 -1
  23. package/.next/server/app/_global-error.rsc +7 -7
  24. package/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  25. package/.next/server/app/_global-error.segments/{__PAGE__.segment.rsc → _global-error/__PAGE__.segment.rsc} +2 -2
  26. package/.next/server/app/_global-error.segments/_global-error.segment.rsc +5 -0
  27. package/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  28. package/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  29. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  30. package/.next/server/app/_not-found/page.js +2 -13
  31. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  32. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -3
  33. package/.next/server/app/_not-found.html +1 -1
  34. package/.next/server/app/_not-found.rsc +14 -12
  35. package/.next/server/app/_not-found.segments/_full.segment.rsc +14 -12
  36. package/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  37. package/.next/server/app/_not-found.segments/_index.segment.rsc +6 -6
  38. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  39. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  40. package/.next/server/app/_not-found.segments/_tree.segment.rsc +4 -2
  41. package/.next/server/app/api/analyze/route.js +12 -9
  42. package/.next/server/app/api/analyze/route.js.nft.json +1 -1
  43. package/.next/server/app/api/analyze/route_client-reference-manifest.js +1 -3
  44. package/.next/server/app/api/key/route.js +1 -8
  45. package/.next/server/app/api/key/route.js.nft.json +1 -1
  46. package/.next/server/app/api/key/route_client-reference-manifest.js +1 -3
  47. package/.next/server/app/api/key-status/route.js +1 -7
  48. package/.next/server/app/api/key-status/route.js.nft.json +1 -1
  49. package/.next/server/app/api/key-status/route_client-reference-manifest.js +1 -3
  50. package/.next/server/app/api/models/route.js +1 -7
  51. package/.next/server/app/api/models/route.js.nft.json +1 -1
  52. package/.next/server/app/api/models/route_client-reference-manifest.js +1 -3
  53. package/.next/server/app/api/revise/route.js +1 -8
  54. package/.next/server/app/api/revise/route.js.nft.json +1 -1
  55. package/.next/server/app/api/revise/route_client-reference-manifest.js +1 -3
  56. package/.next/server/app/icon.svg/route.js +1 -7
  57. package/.next/server/app/icon.svg/route.js.nft.json +1 -1
  58. package/.next/server/app/index.html +1 -1
  59. package/.next/server/app/index.rsc +24 -27
  60. package/.next/server/app/index.segments/!KGFwcCk/__PAGE__.segment.rsc +6 -6
  61. package/.next/server/app/index.segments/!KGFwcCk.segment.rsc +9 -9
  62. package/.next/server/app/index.segments/_full.segment.rsc +24 -27
  63. package/.next/server/app/index.segments/_head.segment.rsc +4 -4
  64. package/.next/server/app/index.segments/_index.segment.rsc +6 -6
  65. package/.next/server/app/index.segments/_tree.segment.rsc +4 -4
  66. package/.next/server/app/record-test/page.js +8 -14
  67. package/.next/server/app/record-test/page.js.nft.json +1 -1
  68. package/.next/server/app/record-test/page_client-reference-manifest.js +1 -3
  69. package/.next/server/app/record-test.html +2 -2
  70. package/.next/server/app/record-test.rsc +16 -16
  71. package/.next/server/app/record-test.segments/_full.segment.rsc +16 -16
  72. package/.next/server/app/record-test.segments/_head.segment.rsc +4 -4
  73. package/.next/server/app/record-test.segments/_index.segment.rsc +6 -6
  74. package/.next/server/app/record-test.segments/_tree.segment.rsc +4 -4
  75. package/.next/server/app/record-test.segments/record-test/__PAGE__.segment.rsc +4 -4
  76. package/.next/server/app/record-test.segments/record-test.segment.rsc +3 -3
  77. package/.next/server/app/settings/key.html +1 -1
  78. package/.next/server/app/settings/key.rsc +28 -34
  79. package/.next/server/app/settings/key.segments/!KGFwcCk/settings/key/__PAGE__.segment.rsc +5 -5
  80. package/.next/server/app/settings/key.segments/!KGFwcCk/settings/key.segment.rsc +3 -3
  81. package/.next/server/app/settings/key.segments/!KGFwcCk/settings.segment.rsc +3 -3
  82. package/.next/server/app/settings/key.segments/!KGFwcCk.segment.rsc +9 -9
  83. package/.next/server/app/settings/key.segments/_full.segment.rsc +28 -34
  84. package/.next/server/app/settings/key.segments/_head.segment.rsc +4 -4
  85. package/.next/server/app/settings/key.segments/_index.segment.rsc +6 -6
  86. package/.next/server/app/settings/key.segments/_tree.segment.rsc +4 -4
  87. package/.next/server/app/styleguide/page.js +2 -15
  88. package/.next/server/app/styleguide/page.js.nft.json +1 -1
  89. package/.next/server/app/styleguide/page_client-reference-manifest.js +1 -3
  90. package/.next/server/app/styleguide.html +1 -1
  91. package/.next/server/app/styleguide.rsc +68 -71
  92. package/.next/server/app/styleguide.segments/_full.segment.rsc +68 -71
  93. package/.next/server/app/styleguide.segments/_head.segment.rsc +4 -4
  94. package/.next/server/app/styleguide.segments/_index.segment.rsc +6 -6
  95. package/.next/server/app/styleguide.segments/_tree.segment.rsc +4 -4
  96. package/.next/server/app/styleguide.segments/styleguide/__PAGE__.segment.rsc +43 -45
  97. package/.next/server/app/styleguide.segments/styleguide.segment.rsc +3 -3
  98. package/.next/server/app-paths-manifest.json +5 -5
  99. package/.next/server/chunks/15.js +1 -0
  100. package/.next/server/chunks/319.js +45 -0
  101. package/.next/server/chunks/367.js +122 -0
  102. package/.next/server/chunks/393.js +4 -0
  103. package/.next/server/chunks/491.js +2 -0
  104. package/.next/server/chunks/497.js +1 -0
  105. package/.next/server/chunks/546.js +1 -0
  106. package/.next/server/chunks/592.js +44 -0
  107. package/.next/server/chunks/607.js +4 -0
  108. package/.next/server/chunks/724.js +1 -0
  109. package/.next/server/chunks/741.js +18 -0
  110. package/.next/server/chunks/813.js +1 -0
  111. package/.next/server/chunks/837.js +75 -0
  112. package/.next/server/chunks/852.js +14 -0
  113. package/.next/server/chunks/907.js +62 -0
  114. package/.next/server/chunks/915.js +8 -0
  115. package/.next/server/chunks/994.js +8 -0
  116. package/.next/server/middleware-build-manifest.js +1 -21
  117. package/.next/server/middleware-manifest.json +2 -2
  118. package/.next/server/middleware-react-loadable-manifest.js +1 -0
  119. package/.next/server/next-font-manifest.js +1 -1
  120. package/.next/server/next-font-manifest.json +1 -31
  121. package/.next/server/pages/404.html +1 -1
  122. package/.next/server/pages/500.html +1 -1
  123. package/.next/server/server-reference-manifest.js +1 -1
  124. package/.next/server/server-reference-manifest.json +1 -5
  125. package/.next/server/webpack-runtime.js +1 -0
  126. package/.next/static/FExJe2q2O67X3zxf-SYQ_/_buildManifest.js +1 -0
  127. package/.next/static/chunks/185-9c51ded7cd36ca7e.js +1 -0
  128. package/.next/static/chunks/20-cca33f633fa125b2.js +1 -0
  129. package/.next/static/chunks/27-02413cc56fbb4570.js +1 -0
  130. package/.next/static/chunks/376-6f7bc95550542e0b.js +62 -0
  131. package/.next/static/chunks/479-ea67f878851afbcd.js +1 -0
  132. package/.next/static/chunks/493-6bd8c75c972d3abd.js +2 -0
  133. package/.next/static/chunks/4bd1b696-deb4a0a1da1923b0.js +1 -0
  134. package/.next/static/chunks/603-6235d4d53b37035c.js +1 -0
  135. package/.next/static/chunks/743-c183133e0fbf1564.js +44 -0
  136. package/.next/static/chunks/793-5e37343b804eb1d9.js +1 -0
  137. package/.next/static/chunks/794-dc751ec6c8c611f8.js +32 -0
  138. package/.next/static/chunks/924-9226750edc5c2c2f.js +1 -0
  139. package/.next/static/chunks/95247769-a29d70f7fbba27c6.js +1 -0
  140. package/.next/static/chunks/app/(app)/layout-aad46049bfd54648.js +1 -0
  141. package/.next/static/chunks/app/(app)/page-d75e1fccccdbe30e.js +1 -0
  142. package/.next/static/chunks/app/(app)/session/[name]/page-60529ed1fd7a66a1.js +1 -0
  143. package/.next/static/chunks/app/(app)/settings/key/page-c2aab9f11db98d4e.js +1 -0
  144. package/.next/static/chunks/app/_global-error/page-b1c3f51315835726.js +1 -0
  145. package/.next/static/chunks/app/_not-found/page-6830be21b0ed0c95.js +1 -0
  146. package/.next/static/chunks/app/api/analyze/route-b1c3f51315835726.js +1 -0
  147. package/.next/static/chunks/app/api/key/route-b1c3f51315835726.js +1 -0
  148. package/.next/static/chunks/app/api/key-status/route-b1c3f51315835726.js +1 -0
  149. package/.next/static/chunks/app/api/models/route-b1c3f51315835726.js +1 -0
  150. package/.next/static/chunks/app/api/revise/route-b1c3f51315835726.js +1 -0
  151. package/.next/static/chunks/app/layout-aa71ca14e7f13c0c.js +1 -0
  152. package/.next/static/chunks/app/record-test/page-efb4287dda79ede4.js +7 -0
  153. package/.next/static/chunks/app/styleguide/page-f39510e82c1f9f31.js +1 -0
  154. package/.next/static/chunks/framework-b29f9083d3cda3b2.js +1 -0
  155. package/.next/static/chunks/main-app-39f57c6e6702740e.js +1 -0
  156. package/.next/static/chunks/main-fac8900b4f9c4833.js +5 -0
  157. package/.next/static/chunks/next/dist/client/components/builtin/app-error-b1c3f51315835726.js +1 -0
  158. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-b1c3f51315835726.js +1 -0
  159. package/.next/static/chunks/next/dist/client/components/builtin/global-error-c1d4bb24e31b66a2.js +1 -0
  160. package/.next/static/chunks/next/dist/client/components/builtin/not-found-b1c3f51315835726.js +1 -0
  161. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-b1c3f51315835726.js +1 -0
  162. package/.next/static/chunks/webpack-ceb933bd5f77076f.js +1 -0
  163. package/.next/static/css/e2905f0858acd77d.css +3 -0
  164. package/.next/types/app/(app)/page.ts +87 -0
  165. package/.next/types/app/(app)/session/[name]/page.ts +87 -0
  166. package/.next/types/app/(app)/settings/key/page.ts +87 -0
  167. package/.next/types/app/api/analyze/route.ts +351 -0
  168. package/.next/types/app/api/key/route.ts +351 -0
  169. package/.next/types/app/api/key-status/route.ts +351 -0
  170. package/.next/types/app/api/models/route.ts +351 -0
  171. package/.next/types/app/api/revise/route.ts +351 -0
  172. package/.next/types/app/layout.ts +87 -0
  173. package/.next/types/app/record-test/page.ts +87 -0
  174. package/.next/types/app/styleguide/page.ts +87 -0
  175. package/.next/types/package.json +1 -0
  176. package/README.md +4 -6
  177. package/next.config.ts +8 -0
  178. package/package.json +4 -4
  179. package/.next/build/56416d4ae4ce586f.js +0 -6
  180. package/.next/build/56416d4ae4ce586f.js.map +0 -5
  181. package/.next/build/chunks/[root-of-the-server]__0oj80bi._.js +0 -206
  182. package/.next/build/chunks/[root-of-the-server]__0oj80bi._.js.map +0 -8
  183. package/.next/build/chunks/[root-of-the-server]__1f933tp._.js +0 -500
  184. package/.next/build/chunks/[root-of-the-server]__1f933tp._.js.map +0 -11
  185. package/.next/build/chunks/[turbopack-node]_transforms_postcss_ts_0b7xl6g._.js +0 -13
  186. package/.next/build/chunks/[turbopack-node]_transforms_postcss_ts_0b7xl6g._.js.map +0 -5
  187. package/.next/build/chunks/[turbopack]_runtime.js +0 -890
  188. package/.next/build/chunks/[turbopack]_runtime.js.map +0 -11
  189. package/.next/build/chunks/node_modules_20v-8wl._.js +0 -6832
  190. package/.next/build/chunks/node_modules_20v-8wl._.js.map +0 -47
  191. package/.next/build/package.json +0 -1
  192. package/.next/cache/.previewinfo +0 -1
  193. package/.next/cache/.rscinfo +0 -1
  194. package/.next/cache/.tsbuildinfo +0 -1
  195. package/.next/diagnostics/route-bundle-stats.json +0 -111
  196. package/.next/fallback-build-manifest.json +0 -13
  197. package/.next/server/app/(app)/page/app-paths-manifest.json +0 -3
  198. package/.next/server/app/(app)/page/build-manifest.json +0 -17
  199. package/.next/server/app/(app)/page/next-font-manifest.json +0 -11
  200. package/.next/server/app/(app)/page/server-reference-manifest.json +0 -4
  201. package/.next/server/app/(app)/page.js.map +0 -5
  202. package/.next/server/app/(app)/session/[name]/page/app-paths-manifest.json +0 -3
  203. package/.next/server/app/(app)/session/[name]/page/build-manifest.json +0 -17
  204. package/.next/server/app/(app)/session/[name]/page/next-font-manifest.json +0 -11
  205. package/.next/server/app/(app)/session/[name]/page/react-loadable-manifest.json +0 -1
  206. package/.next/server/app/(app)/session/[name]/page/server-reference-manifest.json +0 -4
  207. package/.next/server/app/(app)/session/[name]/page.js.map +0 -5
  208. package/.next/server/app/(app)/settings/key/page/app-paths-manifest.json +0 -3
  209. package/.next/server/app/(app)/settings/key/page/build-manifest.json +0 -17
  210. package/.next/server/app/(app)/settings/key/page/next-font-manifest.json +0 -11
  211. package/.next/server/app/(app)/settings/key/page/react-loadable-manifest.json +0 -1
  212. package/.next/server/app/(app)/settings/key/page/server-reference-manifest.json +0 -4
  213. package/.next/server/app/(app)/settings/key/page.js.map +0 -5
  214. package/.next/server/app/_global-error/page/app-paths-manifest.json +0 -3
  215. package/.next/server/app/_global-error/page/build-manifest.json +0 -17
  216. package/.next/server/app/_global-error/page/next-font-manifest.json +0 -6
  217. package/.next/server/app/_global-error/page/react-loadable-manifest.json +0 -1
  218. package/.next/server/app/_global-error/page/server-reference-manifest.json +0 -4
  219. package/.next/server/app/_global-error/page.js.map +0 -5
  220. package/.next/server/app/_not-found/page/app-paths-manifest.json +0 -3
  221. package/.next/server/app/_not-found/page/build-manifest.json +0 -17
  222. package/.next/server/app/_not-found/page/next-font-manifest.json +0 -11
  223. package/.next/server/app/_not-found/page/react-loadable-manifest.json +0 -1
  224. package/.next/server/app/_not-found/page/server-reference-manifest.json +0 -4
  225. package/.next/server/app/_not-found/page.js.map +0 -5
  226. package/.next/server/app/api/analyze/route/app-paths-manifest.json +0 -3
  227. package/.next/server/app/api/analyze/route/build-manifest.json +0 -9
  228. package/.next/server/app/api/analyze/route/server-reference-manifest.json +0 -4
  229. package/.next/server/app/api/analyze/route.js.map +0 -5
  230. package/.next/server/app/api/key/route/app-paths-manifest.json +0 -3
  231. package/.next/server/app/api/key/route/build-manifest.json +0 -9
  232. package/.next/server/app/api/key/route/server-reference-manifest.json +0 -4
  233. package/.next/server/app/api/key/route.js.map +0 -5
  234. package/.next/server/app/api/key-status/route/app-paths-manifest.json +0 -3
  235. package/.next/server/app/api/key-status/route/build-manifest.json +0 -9
  236. package/.next/server/app/api/key-status/route/server-reference-manifest.json +0 -4
  237. package/.next/server/app/api/key-status/route.js.map +0 -5
  238. package/.next/server/app/api/models/route/app-paths-manifest.json +0 -3
  239. package/.next/server/app/api/models/route/build-manifest.json +0 -9
  240. package/.next/server/app/api/models/route/server-reference-manifest.json +0 -4
  241. package/.next/server/app/api/models/route.js.map +0 -5
  242. package/.next/server/app/api/revise/route/app-paths-manifest.json +0 -3
  243. package/.next/server/app/api/revise/route/build-manifest.json +0 -9
  244. package/.next/server/app/api/revise/route/server-reference-manifest.json +0 -4
  245. package/.next/server/app/api/revise/route.js.map +0 -5
  246. package/.next/server/app/icon.svg/route/app-paths-manifest.json +0 -3
  247. package/.next/server/app/icon.svg/route/build-manifest.json +0 -9
  248. package/.next/server/app/icon.svg/route.js.map +0 -5
  249. package/.next/server/app/record-test/page/app-paths-manifest.json +0 -3
  250. package/.next/server/app/record-test/page/build-manifest.json +0 -17
  251. package/.next/server/app/record-test/page/next-font-manifest.json +0 -11
  252. package/.next/server/app/record-test/page/react-loadable-manifest.json +0 -1
  253. package/.next/server/app/record-test/page/server-reference-manifest.json +0 -4
  254. package/.next/server/app/record-test/page.js.map +0 -5
  255. package/.next/server/app/styleguide/page/app-paths-manifest.json +0 -3
  256. package/.next/server/app/styleguide/page/build-manifest.json +0 -17
  257. package/.next/server/app/styleguide/page/next-font-manifest.json +0 -11
  258. package/.next/server/app/styleguide/page/react-loadable-manifest.json +0 -1
  259. package/.next/server/app/styleguide/page/server-reference-manifest.json +0 -4
  260. package/.next/server/app/styleguide/page.js.map +0 -5
  261. package/.next/server/chunks/[externals]__1l0bqbz._.js +0 -3
  262. package/.next/server/chunks/[externals]__1l0bqbz._.js.map +0 -1
  263. package/.next/server/chunks/[root-of-the-server]__00u0a0m._.js +0 -3
  264. package/.next/server/chunks/[root-of-the-server]__00u0a0m._.js.map +0 -1
  265. package/.next/server/chunks/[root-of-the-server]__02oblj7._.js +0 -3
  266. package/.next/server/chunks/[root-of-the-server]__02oblj7._.js.map +0 -1
  267. package/.next/server/chunks/[root-of-the-server]__04dzkv1._.js +0 -3
  268. package/.next/server/chunks/[root-of-the-server]__04dzkv1._.js.map +0 -1
  269. package/.next/server/chunks/[root-of-the-server]__081zp1m._.js +0 -3
  270. package/.next/server/chunks/[root-of-the-server]__081zp1m._.js.map +0 -1
  271. package/.next/server/chunks/[root-of-the-server]__0dkua3v._.js +0 -3
  272. package/.next/server/chunks/[root-of-the-server]__0dkua3v._.js.map +0 -1
  273. package/.next/server/chunks/[root-of-the-server]__0ezil_h._.js +0 -3
  274. package/.next/server/chunks/[root-of-the-server]__0ezil_h._.js.map +0 -1
  275. package/.next/server/chunks/[root-of-the-server]__0ww_12a._.js +0 -3
  276. package/.next/server/chunks/[root-of-the-server]__0ww_12a._.js.map +0 -1
  277. package/.next/server/chunks/[root-of-the-server]__0x-kpif._.js +0 -3
  278. package/.next/server/chunks/[root-of-the-server]__0x-kpif._.js.map +0 -1
  279. package/.next/server/chunks/[root-of-the-server]__15bjnu5._.js +0 -3
  280. package/.next/server/chunks/[root-of-the-server]__15bjnu5._.js.map +0 -1
  281. package/.next/server/chunks/[root-of-the-server]__1kmbnvv._.js +0 -3
  282. package/.next/server/chunks/[root-of-the-server]__1kmbnvv._.js.map +0 -1
  283. package/.next/server/chunks/[root-of-the-server]__1kp4vwc._.js +0 -14
  284. package/.next/server/chunks/[root-of-the-server]__1kp4vwc._.js.map +0 -1
  285. package/.next/server/chunks/[root-of-the-server]__1lbd3kd._.js +0 -3
  286. package/.next/server/chunks/[root-of-the-server]__1lbd3kd._.js.map +0 -1
  287. package/.next/server/chunks/[root-of-the-server]__1ra6psc._.js +0 -3
  288. package/.next/server/chunks/[root-of-the-server]__1ra6psc._.js.map +0 -1
  289. package/.next/server/chunks/[root-of-the-server]__1zn977r._.js +0 -3
  290. package/.next/server/chunks/[root-of-the-server]__1zn977r._.js.map +0 -1
  291. package/.next/server/chunks/[turbopack]_runtime.js +0 -903
  292. package/.next/server/chunks/[turbopack]_runtime.js.map +0 -11
  293. package/.next/server/chunks/_04h1cv_._.js +0 -185
  294. package/.next/server/chunks/_04h1cv_._.js.map +0 -1
  295. package/.next/server/chunks/_0pqmhjh._.js +0 -185
  296. package/.next/server/chunks/_0pqmhjh._.js.map +0 -1
  297. package/.next/server/chunks/_next-internal_server_app_api_analyze_route_actions_0lx-23h.js +0 -3
  298. package/.next/server/chunks/_next-internal_server_app_api_analyze_route_actions_0lx-23h.js.map +0 -1
  299. package/.next/server/chunks/_next-internal_server_app_api_key-status_route_actions_1qgztm2.js +0 -3
  300. package/.next/server/chunks/_next-internal_server_app_api_key-status_route_actions_1qgztm2.js.map +0 -1
  301. package/.next/server/chunks/_next-internal_server_app_api_key_route_actions_15n2qsb.js +0 -3
  302. package/.next/server/chunks/_next-internal_server_app_api_key_route_actions_15n2qsb.js.map +0 -1
  303. package/.next/server/chunks/_next-internal_server_app_api_models_route_actions_1h6mkqp.js +0 -3
  304. package/.next/server/chunks/_next-internal_server_app_api_models_route_actions_1h6mkqp.js.map +0 -1
  305. package/.next/server/chunks/_next-internal_server_app_api_revise_route_actions_19kk3m-.js +0 -3
  306. package/.next/server/chunks/_next-internal_server_app_api_revise_route_actions_19kk3m-.js.map +0 -1
  307. package/.next/server/chunks/_next-internal_server_app_icon_svg_route_actions_1r2h_ub.js +0 -3
  308. package/.next/server/chunks/_next-internal_server_app_icon_svg_route_actions_1r2h_ub.js.map +0 -1
  309. package/.next/server/chunks/node_modules_0x51oh_._.js +0 -10
  310. package/.next/server/chunks/node_modules_0x51oh_._.js.map +0 -1
  311. package/.next/server/chunks/node_modules_19bvt3l._.js +0 -6
  312. package/.next/server/chunks/node_modules_19bvt3l._.js.map +0 -1
  313. package/.next/server/chunks/node_modules_1_-az43._.js +0 -16
  314. package/.next/server/chunks/node_modules_1_-az43._.js.map +0 -1
  315. package/.next/server/chunks/node_modules_1t2pqct._.js +0 -10
  316. package/.next/server/chunks/node_modules_1t2pqct._.js.map +0 -1
  317. package/.next/server/chunks/node_modules_next_08s853w._.js +0 -13
  318. package/.next/server/chunks/node_modules_next_08s853w._.js.map +0 -1
  319. package/.next/server/chunks/node_modules_node-fetch_src_index_1gf-_pn.js +0 -3
  320. package/.next/server/chunks/node_modules_node-fetch_src_index_1gf-_pn.js.map +0 -1
  321. package/.next/server/chunks/ssr/[externals]__1l0bqbz._.js +0 -3
  322. package/.next/server/chunks/ssr/[externals]__1l0bqbz._.js.map +0 -1
  323. package/.next/server/chunks/ssr/[root-of-the-server]__06ync7f._.js +0 -3
  324. package/.next/server/chunks/ssr/[root-of-the-server]__06ync7f._.js.map +0 -1
  325. package/.next/server/chunks/ssr/[root-of-the-server]__0hml-pd._.js +0 -3
  326. package/.next/server/chunks/ssr/[root-of-the-server]__0hml-pd._.js.map +0 -1
  327. package/.next/server/chunks/ssr/[root-of-the-server]__0ntia6u._.js +0 -3
  328. package/.next/server/chunks/ssr/[root-of-the-server]__0ntia6u._.js.map +0 -1
  329. package/.next/server/chunks/ssr/[root-of-the-server]__0sdpd0o._.js +0 -3
  330. package/.next/server/chunks/ssr/[root-of-the-server]__0sdpd0o._.js.map +0 -1
  331. package/.next/server/chunks/ssr/[root-of-the-server]__0w2pa_y._.js +0 -33
  332. package/.next/server/chunks/ssr/[root-of-the-server]__0w2pa_y._.js.map +0 -1
  333. package/.next/server/chunks/ssr/[root-of-the-server]__10y0-wv._.js +0 -3
  334. package/.next/server/chunks/ssr/[root-of-the-server]__10y0-wv._.js.map +0 -1
  335. package/.next/server/chunks/ssr/[root-of-the-server]__11_7weu._.js +0 -3
  336. package/.next/server/chunks/ssr/[root-of-the-server]__11_7weu._.js.map +0 -1
  337. package/.next/server/chunks/ssr/[root-of-the-server]__1_stkwn._.js +0 -3
  338. package/.next/server/chunks/ssr/[root-of-the-server]__1_stkwn._.js.map +0 -1
  339. package/.next/server/chunks/ssr/[root-of-the-server]__1dky4g0._.js +0 -33
  340. package/.next/server/chunks/ssr/[root-of-the-server]__1dky4g0._.js.map +0 -1
  341. package/.next/server/chunks/ssr/[root-of-the-server]__1k6ey-q._.js +0 -3
  342. package/.next/server/chunks/ssr/[root-of-the-server]__1k6ey-q._.js.map +0 -1
  343. package/.next/server/chunks/ssr/[root-of-the-server]__1la73u1._.js +0 -3
  344. package/.next/server/chunks/ssr/[root-of-the-server]__1la73u1._.js.map +0 -1
  345. package/.next/server/chunks/ssr/[root-of-the-server]__1nshnxm._.js +0 -3
  346. package/.next/server/chunks/ssr/[root-of-the-server]__1nshnxm._.js.map +0 -1
  347. package/.next/server/chunks/ssr/[root-of-the-server]__1pssg49._.js +0 -3
  348. package/.next/server/chunks/ssr/[root-of-the-server]__1pssg49._.js.map +0 -1
  349. package/.next/server/chunks/ssr/[root-of-the-server]__1q6zd30._.js +0 -3
  350. package/.next/server/chunks/ssr/[root-of-the-server]__1q6zd30._.js.map +0 -1
  351. package/.next/server/chunks/ssr/[root-of-the-server]__1qlmg27._.js +0 -3
  352. package/.next/server/chunks/ssr/[root-of-the-server]__1qlmg27._.js.map +0 -1
  353. package/.next/server/chunks/ssr/[turbopack]_runtime.js +0 -903
  354. package/.next/server/chunks/ssr/[turbopack]_runtime.js.map +0 -11
  355. package/.next/server/chunks/ssr/_01pksvc._.js +0 -78
  356. package/.next/server/chunks/ssr/_01pksvc._.js.map +0 -1
  357. package/.next/server/chunks/ssr/_03lgii8._.js +0 -3
  358. package/.next/server/chunks/ssr/_03lgii8._.js.map +0 -1
  359. package/.next/server/chunks/ssr/_05tft_r._.js +0 -3
  360. package/.next/server/chunks/ssr/_05tft_r._.js.map +0 -1
  361. package/.next/server/chunks/ssr/_06gt995._.js +0 -3
  362. package/.next/server/chunks/ssr/_06gt995._.js.map +0 -1
  363. package/.next/server/chunks/ssr/_0jrh37c._.js +0 -46
  364. package/.next/server/chunks/ssr/_0jrh37c._.js.map +0 -1
  365. package/.next/server/chunks/ssr/_0kw6yq_._.js +0 -3
  366. package/.next/server/chunks/ssr/_0kw6yq_._.js.map +0 -1
  367. package/.next/server/chunks/ssr/_0l3c05z._.js +0 -3
  368. package/.next/server/chunks/ssr/_0l3c05z._.js.map +0 -1
  369. package/.next/server/chunks/ssr/_0n-ojw-._.js +0 -3
  370. package/.next/server/chunks/ssr/_0n-ojw-._.js.map +0 -1
  371. package/.next/server/chunks/ssr/_0t6a1ln._.js +0 -6
  372. package/.next/server/chunks/ssr/_0t6a1ln._.js.map +0 -1
  373. package/.next/server/chunks/ssr/_0td-xk-._.js +0 -3
  374. package/.next/server/chunks/ssr/_0td-xk-._.js.map +0 -1
  375. package/.next/server/chunks/ssr/_0y92f-y._.js +0 -46
  376. package/.next/server/chunks/ssr/_0y92f-y._.js.map +0 -1
  377. package/.next/server/chunks/ssr/_1b6au28._.js +0 -3
  378. package/.next/server/chunks/ssr/_1b6au28._.js.map +0 -1
  379. package/.next/server/chunks/ssr/_next-internal_server_app_(app)_page_actions_1gxdy57.js +0 -3
  380. package/.next/server/chunks/ssr/_next-internal_server_app_(app)_page_actions_1gxdy57.js.map +0 -1
  381. package/.next/server/chunks/ssr/_next-internal_server_app_(app)_session_[name]_page_actions_115d_ja.js +0 -3
  382. package/.next/server/chunks/ssr/_next-internal_server_app_(app)_session_[name]_page_actions_115d_ja.js.map +0 -1
  383. package/.next/server/chunks/ssr/_next-internal_server_app_(app)_settings_key_page_actions_1jsc3or.js +0 -3
  384. package/.next/server/chunks/ssr/_next-internal_server_app_(app)_settings_key_page_actions_1jsc3or.js.map +0 -1
  385. package/.next/server/chunks/ssr/_next-internal_server_app__global-error_page_actions_0zi5s8-.js +0 -3
  386. package/.next/server/chunks/ssr/_next-internal_server_app__global-error_page_actions_0zi5s8-.js.map +0 -1
  387. package/.next/server/chunks/ssr/_next-internal_server_app__not-found_page_actions_0pt47yr.js +0 -3
  388. package/.next/server/chunks/ssr/_next-internal_server_app__not-found_page_actions_0pt47yr.js.map +0 -1
  389. package/.next/server/chunks/ssr/_next-internal_server_app_record-test_page_actions_0a_yofw.js +0 -3
  390. package/.next/server/chunks/ssr/_next-internal_server_app_record-test_page_actions_0a_yofw.js.map +0 -1
  391. package/.next/server/chunks/ssr/_next-internal_server_app_styleguide_page_actions_174h7x7.js +0 -3
  392. package/.next/server/chunks/ssr/_next-internal_server_app_styleguide_page_actions_174h7x7.js.map +0 -1
  393. package/.next/server/chunks/ssr/node_modules_0el53_h._.js +0 -10
  394. package/.next/server/chunks/ssr/node_modules_0el53_h._.js.map +0 -1
  395. package/.next/server/chunks/ssr/node_modules_0h91jdk._.js +0 -33
  396. package/.next/server/chunks/ssr/node_modules_0h91jdk._.js.map +0 -1
  397. package/.next/server/chunks/ssr/node_modules_1fxqp22._.js +0 -10
  398. package/.next/server/chunks/ssr/node_modules_1fxqp22._.js.map +0 -1
  399. package/.next/server/chunks/ssr/node_modules_1loo6j7._.js +0 -6
  400. package/.next/server/chunks/ssr/node_modules_1loo6j7._.js.map +0 -1
  401. package/.next/server/chunks/ssr/node_modules_1pvqj0r._.js +0 -3
  402. package/.next/server/chunks/ssr/node_modules_1pvqj0r._.js.map +0 -1
  403. package/.next/server/chunks/ssr/node_modules_next_dist_0uboya6._.js +0 -6
  404. package/.next/server/chunks/ssr/node_modules_next_dist_0uboya6._.js.map +0 -1
  405. package/.next/server/chunks/ssr/node_modules_next_dist_172hvm-._.js +0 -19
  406. package/.next/server/chunks/ssr/node_modules_next_dist_172hvm-._.js.map +0 -1
  407. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_0wpq8j3._.js +0 -3
  408. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_0wpq8j3._.js.map +0 -1
  409. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_forbidden_0symwr9.js +0 -3
  410. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_forbidden_0symwr9.js.map +0 -1
  411. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0-o-goa.js +0 -3
  412. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0-o-goa.js.map +0 -1
  413. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0x.js +0 -3
  414. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0x.js.map +0 -1
  415. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0_q50sh.js +0 -4
  416. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0_q50sh.js.map +0 -1
  417. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0_xbpm0.js +0 -4
  418. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0_xbpm0.js.map +0 -1
  419. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_119i6eu.js +0 -4
  420. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_119i6eu.js.map +0 -1
  421. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_14nl2rs.js +0 -4
  422. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_14nl2rs.js.map +0 -1
  423. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_18u8k23.js +0 -4
  424. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_18u8k23.js.map +0 -1
  425. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_19--w_z.js +0 -4
  426. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_19--w_z.js.map +0 -1
  427. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1_iwj0a.js +0 -4
  428. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1_iwj0a.js.map +0 -1
  429. package/.next/server/chunks/ssr/node_modules_node-fetch_src_index_1e0t9p6.js +0 -3
  430. package/.next/server/chunks/ssr/node_modules_node-fetch_src_index_1e0t9p6.js.map +0 -1
  431. package/.next/server/chunks/ssr/src_19oqe9t._.js +0 -3
  432. package/.next/server/chunks/ssr/src_19oqe9t._.js.map +0 -1
  433. package/.next/server/chunks/ssr/src_app_record-test_page_tsx_08-2bld._.js +0 -9
  434. package/.next/server/chunks/ssr/src_app_record-test_page_tsx_08-2bld._.js.map +0 -1
  435. package/.next/server/chunks/ssr/src_components_app-sidebar_tsx_1xx2k53._.js +0 -3
  436. package/.next/server/chunks/ssr/src_components_app-sidebar_tsx_1xx2k53._.js.map +0 -1
  437. package/.next/server/chunks/ssr/src_components_settings_key-setup_tsx_0jxhnpa._.js +0 -3
  438. package/.next/server/chunks/ssr/src_components_settings_key-setup_tsx_0jxhnpa._.js.map +0 -1
  439. package/.next/server/chunks/ssr/src_components_ui_0lq7ewx._.js +0 -3
  440. package/.next/server/chunks/ssr/src_components_ui_0lq7ewx._.js.map +0 -1
  441. package/.next/static/CIZxngYjzUw1Kb0KrE473/_buildManifest.js +0 -11
  442. package/.next/static/CIZxngYjzUw1Kb0KrE473/_clientMiddlewareManifest.js +0 -1
  443. package/.next/static/chunks/05-c3ty_6dwfk.js +0 -1
  444. package/.next/static/chunks/07-hzktxqjvzd.js +0 -4
  445. package/.next/static/chunks/09bn0buuu6k2x.js +0 -1
  446. package/.next/static/chunks/0kkimqpuecvfn.js +0 -1
  447. package/.next/static/chunks/0mk1g55o6kl1e.js +0 -2
  448. package/.next/static/chunks/0ul837-9k0zx_.js +0 -63
  449. package/.next/static/chunks/0wpges32btt_p.js +0 -1
  450. package/.next/static/chunks/18qo-4_hfuwko.js +0 -1
  451. package/.next/static/chunks/1_dsevxz78b97.js +0 -1
  452. package/.next/static/chunks/2-oqhnxovgl_2.js +0 -44
  453. package/.next/static/chunks/2et_7fxuzt9cq.js +0 -31
  454. package/.next/static/chunks/2im7c515bo69p.js +0 -1
  455. package/.next/static/chunks/2merpuxt1zcvf.js +0 -1
  456. package/.next/static/chunks/2qb8lge1e2sv2.js +0 -1
  457. package/.next/static/chunks/2sj0gufu0lojq.css +0 -3
  458. package/.next/static/chunks/2zloaj9ja_vpy.js +0 -1
  459. package/.next/static/chunks/3rvy2rc9d_hwt.js +0 -1
  460. package/.next/static/chunks/3uci2qhsbp444.js +0 -50
  461. package/.next/static/chunks/3yao5u25-bf0g.js +0 -1
  462. package/.next/static/chunks/41_0qs6kjmoek.js +0 -1
  463. package/.next/static/chunks/4395sbjm36lbl.js +0 -1
  464. package/.next/static/chunks/turbopack-2cevjmbuh84ft.js +0 -1
  465. package/.next/static/media/icon.2_sgat73yt9an.svg +0 -7
  466. package/.next/trace +0 -1
  467. package/.next/trace-build +0 -1
  468. package/.next/turbopack +0 -0
  469. /package/.next/{server/app/(app)/page/react-loadable-manifest.json → react-loadable-manifest.json} +0 -0
  470. /package/.next/static/{CIZxngYjzUw1Kb0KrE473 → FExJe2q2O67X3zxf-SYQ_}/_ssgManifest.js +0 -0
  471. /package/.next/static/chunks/{0cz1d0mv5g_q7.js → polyfills-42372ed130431b0a.js} +0 -0
  472. /package/.next/static/media/{5ce348bf30bf5439-s.31988l_ccedte.woff2 → 013b72fa676f92e0-s.woff2} +0 -0
  473. /package/.next/static/media/{5476f68d60460930-s.2uwcyprjm3xu3.woff2 → 19cfc7226ec3afaa-s.woff2} +0 -0
  474. /package/.next/static/media/{9c72aa0f40e4eef8-s.1y4-pdgsjb-pw.woff2 → 21350d82a1f187e9-s.woff2} +0 -0
  475. /package/.next/static/media/{bbc41e54d2fcbd21-s.1rgnod-3esatf.woff2 → 2b5b02fc7e511755-s.woff2} +0 -0
  476. /package/.next/static/media/{6306c77e7c8268e4-s.2dbetqa9o8jxf.woff2 → 65f03d54ccadf4a8-s.woff2} +0 -0
  477. /package/.next/static/media/{797e433ab948586e-s.p.0r6juujl39pe6.woff2 → 7d4881bb7e1bf84d-s.p.woff2} +0 -0
  478. /package/.next/static/media/{1bffadaabf893a1e-s.3-6t-g6q0vh0a.woff2 → 8e9860b6e62d6359-s.woff2} +0 -0
  479. /package/.next/static/media/{4fa387ec64143e14-s.2tuy5pz7dlieh.woff2 → b9408752a0c24fb9-s.woff2} +0 -0
  480. /package/.next/static/media/{2c55a0e60120577a-s.0-dom-5bn10r2.woff2 → ba9851c3c22cd980-s.woff2} +0 -0
  481. /package/.next/static/media/{ad66f9afd8947f86-s.3lvt2whj97whp.woff2 → c5fe6dc8356a8c31-s.woff2} +0 -0
  482. /package/.next/static/media/{2bbe8d2671613f1f-s.0k62hbripvv8p.woff2 → df0a9ae256c0569c-s.woff2} +0 -0
  483. /package/.next/static/media/{7d817b4c03b0c5f1-s.1uyisp29ctx0d.woff2 → e038a29029a234f2-s.woff2} +0 -0
  484. /package/.next/static/media/{83afe278b6a6bb3c-s.p.2bn3s6zvc0dyp.woff2 → e4af272ccee01ff0-s.p.woff2} +0 -0
@@ -1,3 +0,0 @@
1
- module.exports=[59639,(e,t,r)=>{t.exports=e.x("node:process",()=>require("node:process"))},37702,(e,t,r)=>{t.exports=e.x("worker_threads",()=>require("worker_threads"))},18352,(e,t,r)=>{t.exports=e.x("node:stream/web",()=>require("node:stream/web"))},20585,e=>{"use strict";e.i(34636);var t=e.i(99029),r=e.i(33329);let a=0,n={START_BOUNDARY:a++,HEADER_FIELD_START:a++,HEADER_FIELD:a++,HEADER_VALUE_START:a++,HEADER_VALUE:a++,HEADER_VALUE_ALMOST_DONE:a++,HEADERS_ALMOST_DONE:a++,PART_DATA_START:a++,PART_DATA:a++,END:a++},i=1,o=2,s=e=>32|e,d=()=>{};class E{constructor(e){this.index=0,this.flags=0,this.onHeaderEnd=d,this.onHeaderField=d,this.onHeadersEnd=d,this.onHeaderValue=d,this.onPartBegin=d,this.onPartData=d,this.onPartEnd=d,this.boundaryChars={};const t=new Uint8Array((e="\r\n--"+e).length);for(let r=0;r<e.length;r++)t[r]=e.charCodeAt(r),this.boundaryChars[t[r]]=!0;this.boundary=t,this.lookbehind=new Uint8Array(this.boundary.length+8),this.state=n.START_BOUNDARY}write(e){let t,r,a=0,d=e.length,E=this.index,{lookbehind:A,boundary:h,boundaryChars:l,index:D,state:_,flags:T}=this,f=this.boundary.length,R=f-1,c=e.length,u=e=>{this[e+"Mark"]=a},H=e=>{delete this[e+"Mark"]},b=(e,t,r,a)=>{(void 0===t||t!==r)&&this[e](a&&a.subarray(t,r))},L=(t,r)=>{let n=t+"Mark";n in this&&(r?(b(t,this[n],a,e),delete this[n]):(b(t,this[n],e.length,e),this[n]=0))};for(a=0;a<d;a++)switch(t=e[a],_){case n.START_BOUNDARY:if(D===h.length-2){if(45===t)T|=o;else if(13!==t)return;D++;break}if(D-1==h.length-2){if(T&o&&45===t)_=n.END,T=0;else{if(T&o||10!==t)return;D=0,b("onPartBegin"),_=n.HEADER_FIELD_START}break}t!==h[D+2]&&(D=-2),t===h[D+2]&&D++;break;case n.HEADER_FIELD_START:_=n.HEADER_FIELD,u("onHeaderField"),D=0;case n.HEADER_FIELD:if(13===t){H("onHeaderField"),_=n.HEADERS_ALMOST_DONE;break}if(D++,45===t)break;if(58===t){if(1===D)return;L("onHeaderField",!0),_=n.HEADER_VALUE_START;break}if((r=s(t))<97||r>122)return;break;case n.HEADER_VALUE_START:if(32===t)break;u("onHeaderValue"),_=n.HEADER_VALUE;case n.HEADER_VALUE:13===t&&(L("onHeaderValue",!0),b("onHeaderEnd"),_=n.HEADER_VALUE_ALMOST_DONE);break;case n.HEADER_VALUE_ALMOST_DONE:if(10!==t)return;_=n.HEADER_FIELD_START;break;case n.HEADERS_ALMOST_DONE:if(10!==t)return;b("onHeadersEnd"),_=n.PART_DATA_START;break;case n.PART_DATA_START:_=n.PART_DATA,u("onPartData");case n.PART_DATA:if(E=D,0===D){for(a+=R;a<c&&!(e[a]in l);)a+=f;a-=R,t=e[a]}if(D<h.length)h[D]===t?(0===D&&L("onPartData",!0),D++):D=0;else if(D===h.length)D++,13===t?T|=i:45===t?T|=o:D=0;else if(D-1===h.length)if(T&i){if(D=0,10===t){T&=~i,b("onPartEnd"),b("onPartBegin"),_=n.HEADER_FIELD_START;break}}else T&o&&45===t?(b("onPartEnd"),_=n.END,T=0):D=0;D>0?A[D-1]=t:E>0&&(b("onPartData",0,E,new Uint8Array(A.buffer,A.byteOffset,A.byteLength)),E=0,u("onPartData"),a--);break;case n.END:break;default:throw Error(`Unexpected state entered: ${_}`)}L("onHeaderField"),L("onHeaderValue"),L("onPartData"),this.index=D,this.state=_,this.flags=T}end(){if(this.state===n.HEADER_FIELD_START&&0===this.index||this.state===n.PART_DATA&&this.index===this.boundary.length)this.onPartEnd();else if(this.state!==n.END)throw Error("MultipartParser.end(): stream ended unexpectedly")}}async function A(e,a){let n,i,o,s,d,A;if(!/multipart/i.test(a))throw TypeError("Failed to fetch");let h=a.match(/boundary=(?:"([^"]+)"|([^;]+))/i);if(!h)throw TypeError("no or bad content-type header, no multipart boundary");let l=new E(h[1]||h[2]),D=[],_=new r.FormData,T=e=>{o+=u.decode(e,{stream:!0})},f=e=>{D.push(e)},R=()=>{let e=new t.File(D,A,{type:d});_.append(s,e)},c=()=>{_.append(s,o)},u=new TextDecoder("utf-8");for await(let t of(u.decode(),l.onPartBegin=function(){l.onPartData=T,l.onPartEnd=c,n="",i="",o="",s="",d="",A=null,D.length=0},l.onHeaderField=function(e){n+=u.decode(e,{stream:!0})},l.onHeaderValue=function(e){i+=u.decode(e,{stream:!0})},l.onHeaderEnd=function(){if(i+=u.decode(),"content-disposition"===(n=n.toLowerCase())){let e=i.match(/\bname=("([^"]*)"|([^()<>@,;:\\"/[\]?={}\s\t]+))/i);e&&(s=e[2]||e[3]||""),(A=function(e){let t=e.match(/\bfilename=("(.*?)"|([^()<>@,;:\\"/[\]?={}\s\t]+))($|;\s)/i);if(!t)return;let r=t[2]||t[3]||"",a=r.slice(r.lastIndexOf("\\")+1);return(a=a.replace(/%22/g,'"')).replace(/&#(\d{4});/g,(e,t)=>String.fromCharCode(t))}(i))&&(l.onPartData=f,l.onPartEnd=R)}else"content-type"===n&&(d=i);i="",n=""},e))l.write(t);return l.end(),_}e.s(["toFormData",0,A])}];
2
-
3
- //# sourceMappingURL=%5Broot-of-the-server%5D__1kmbnvv._.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../node_modules/node-fetch/src/utils/multipart-parser.js"],"sourcesContent":["import {File} from 'fetch-blob/from.js';\nimport {FormData} from 'formdata-polyfill/esm.min.js';\n\nlet s = 0;\nconst S = {\n\tSTART_BOUNDARY: s++,\n\tHEADER_FIELD_START: s++,\n\tHEADER_FIELD: s++,\n\tHEADER_VALUE_START: s++,\n\tHEADER_VALUE: s++,\n\tHEADER_VALUE_ALMOST_DONE: s++,\n\tHEADERS_ALMOST_DONE: s++,\n\tPART_DATA_START: s++,\n\tPART_DATA: s++,\n\tEND: s++\n};\n\nlet f = 1;\nconst F = {\n\tPART_BOUNDARY: f,\n\tLAST_BOUNDARY: f *= 2\n};\n\nconst LF = 10;\nconst CR = 13;\nconst SPACE = 32;\nconst HYPHEN = 45;\nconst COLON = 58;\nconst A = 97;\nconst Z = 122;\n\nconst lower = c => c | 0x20;\n\nconst noop = () => {};\n\nclass MultipartParser {\n\t/**\n\t * @param {string} boundary\n\t */\n\tconstructor(boundary) {\n\t\tthis.index = 0;\n\t\tthis.flags = 0;\n\n\t\tthis.onHeaderEnd = noop;\n\t\tthis.onHeaderField = noop;\n\t\tthis.onHeadersEnd = noop;\n\t\tthis.onHeaderValue = noop;\n\t\tthis.onPartBegin = noop;\n\t\tthis.onPartData = noop;\n\t\tthis.onPartEnd = noop;\n\n\t\tthis.boundaryChars = {};\n\n\t\tboundary = '\\r\\n--' + boundary;\n\t\tconst ui8a = new Uint8Array(boundary.length);\n\t\tfor (let i = 0; i < boundary.length; i++) {\n\t\t\tui8a[i] = boundary.charCodeAt(i);\n\t\t\tthis.boundaryChars[ui8a[i]] = true;\n\t\t}\n\n\t\tthis.boundary = ui8a;\n\t\tthis.lookbehind = new Uint8Array(this.boundary.length + 8);\n\t\tthis.state = S.START_BOUNDARY;\n\t}\n\n\t/**\n\t * @param {Uint8Array} data\n\t */\n\twrite(data) {\n\t\tlet i = 0;\n\t\tconst length_ = data.length;\n\t\tlet previousIndex = this.index;\n\t\tlet {lookbehind, boundary, boundaryChars, index, state, flags} = this;\n\t\tconst boundaryLength = this.boundary.length;\n\t\tconst boundaryEnd = boundaryLength - 1;\n\t\tconst bufferLength = data.length;\n\t\tlet c;\n\t\tlet cl;\n\n\t\tconst mark = name => {\n\t\t\tthis[name + 'Mark'] = i;\n\t\t};\n\n\t\tconst clear = name => {\n\t\t\tdelete this[name + 'Mark'];\n\t\t};\n\n\t\tconst callback = (callbackSymbol, start, end, ui8a) => {\n\t\t\tif (start === undefined || start !== end) {\n\t\t\t\tthis[callbackSymbol](ui8a && ui8a.subarray(start, end));\n\t\t\t}\n\t\t};\n\n\t\tconst dataCallback = (name, clear) => {\n\t\t\tconst markSymbol = name + 'Mark';\n\t\t\tif (!(markSymbol in this)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (clear) {\n\t\t\t\tcallback(name, this[markSymbol], i, data);\n\t\t\t\tdelete this[markSymbol];\n\t\t\t} else {\n\t\t\t\tcallback(name, this[markSymbol], data.length, data);\n\t\t\t\tthis[markSymbol] = 0;\n\t\t\t}\n\t\t};\n\n\t\tfor (i = 0; i < length_; i++) {\n\t\t\tc = data[i];\n\n\t\t\tswitch (state) {\n\t\t\t\tcase S.START_BOUNDARY:\n\t\t\t\t\tif (index === boundary.length - 2) {\n\t\t\t\t\t\tif (c === HYPHEN) {\n\t\t\t\t\t\t\tflags |= F.LAST_BOUNDARY;\n\t\t\t\t\t\t} else if (c !== CR) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tindex++;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (index - 1 === boundary.length - 2) {\n\t\t\t\t\t\tif (flags & F.LAST_BOUNDARY && c === HYPHEN) {\n\t\t\t\t\t\t\tstate = S.END;\n\t\t\t\t\t\t\tflags = 0;\n\t\t\t\t\t\t} else if (!(flags & F.LAST_BOUNDARY) && c === LF) {\n\t\t\t\t\t\t\tindex = 0;\n\t\t\t\t\t\t\tcallback('onPartBegin');\n\t\t\t\t\t\t\tstate = S.HEADER_FIELD_START;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (c !== boundary[index + 2]) {\n\t\t\t\t\t\tindex = -2;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (c === boundary[index + 2]) {\n\t\t\t\t\t\tindex++;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\tcase S.HEADER_FIELD_START:\n\t\t\t\t\tstate = S.HEADER_FIELD;\n\t\t\t\t\tmark('onHeaderField');\n\t\t\t\t\tindex = 0;\n\t\t\t\t\t// falls through\n\t\t\t\tcase S.HEADER_FIELD:\n\t\t\t\t\tif (c === CR) {\n\t\t\t\t\t\tclear('onHeaderField');\n\t\t\t\t\t\tstate = S.HEADERS_ALMOST_DONE;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tindex++;\n\t\t\t\t\tif (c === HYPHEN) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (c === COLON) {\n\t\t\t\t\t\tif (index === 1) {\n\t\t\t\t\t\t\t// empty header field\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdataCallback('onHeaderField', true);\n\t\t\t\t\t\tstate = S.HEADER_VALUE_START;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcl = lower(c);\n\t\t\t\t\tif (cl < A || cl > Z) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\tcase S.HEADER_VALUE_START:\n\t\t\t\t\tif (c === SPACE) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tmark('onHeaderValue');\n\t\t\t\t\tstate = S.HEADER_VALUE;\n\t\t\t\t\t// falls through\n\t\t\t\tcase S.HEADER_VALUE:\n\t\t\t\t\tif (c === CR) {\n\t\t\t\t\t\tdataCallback('onHeaderValue', true);\n\t\t\t\t\t\tcallback('onHeaderEnd');\n\t\t\t\t\t\tstate = S.HEADER_VALUE_ALMOST_DONE;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\tcase S.HEADER_VALUE_ALMOST_DONE:\n\t\t\t\t\tif (c !== LF) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tstate = S.HEADER_FIELD_START;\n\t\t\t\t\tbreak;\n\t\t\t\tcase S.HEADERS_ALMOST_DONE:\n\t\t\t\t\tif (c !== LF) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback('onHeadersEnd');\n\t\t\t\t\tstate = S.PART_DATA_START;\n\t\t\t\t\tbreak;\n\t\t\t\tcase S.PART_DATA_START:\n\t\t\t\t\tstate = S.PART_DATA;\n\t\t\t\t\tmark('onPartData');\n\t\t\t\t\t// falls through\n\t\t\t\tcase S.PART_DATA:\n\t\t\t\t\tpreviousIndex = index;\n\n\t\t\t\t\tif (index === 0) {\n\t\t\t\t\t\t// boyer-moore derrived algorithm to safely skip non-boundary data\n\t\t\t\t\t\ti += boundaryEnd;\n\t\t\t\t\t\twhile (i < bufferLength && !(data[i] in boundaryChars)) {\n\t\t\t\t\t\t\ti += boundaryLength;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ti -= boundaryEnd;\n\t\t\t\t\t\tc = data[i];\n\t\t\t\t\t}\n\n\t\t\t\t\tif (index < boundary.length) {\n\t\t\t\t\t\tif (boundary[index] === c) {\n\t\t\t\t\t\t\tif (index === 0) {\n\t\t\t\t\t\t\t\tdataCallback('onPartData', true);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tindex++;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tindex = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (index === boundary.length) {\n\t\t\t\t\t\tindex++;\n\t\t\t\t\t\tif (c === CR) {\n\t\t\t\t\t\t\t// CR = part boundary\n\t\t\t\t\t\t\tflags |= F.PART_BOUNDARY;\n\t\t\t\t\t\t} else if (c === HYPHEN) {\n\t\t\t\t\t\t\t// HYPHEN = end boundary\n\t\t\t\t\t\t\tflags |= F.LAST_BOUNDARY;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tindex = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (index - 1 === boundary.length) {\n\t\t\t\t\t\tif (flags & F.PART_BOUNDARY) {\n\t\t\t\t\t\t\tindex = 0;\n\t\t\t\t\t\t\tif (c === LF) {\n\t\t\t\t\t\t\t\t// unset the PART_BOUNDARY flag\n\t\t\t\t\t\t\t\tflags &= ~F.PART_BOUNDARY;\n\t\t\t\t\t\t\t\tcallback('onPartEnd');\n\t\t\t\t\t\t\t\tcallback('onPartBegin');\n\t\t\t\t\t\t\t\tstate = S.HEADER_FIELD_START;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (flags & F.LAST_BOUNDARY) {\n\t\t\t\t\t\t\tif (c === HYPHEN) {\n\t\t\t\t\t\t\t\tcallback('onPartEnd');\n\t\t\t\t\t\t\t\tstate = S.END;\n\t\t\t\t\t\t\t\tflags = 0;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tindex = 0;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tindex = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (index > 0) {\n\t\t\t\t\t\t// when matching a possible boundary, keep a lookbehind reference\n\t\t\t\t\t\t// in case it turns out to be a false lead\n\t\t\t\t\t\tlookbehind[index - 1] = c;\n\t\t\t\t\t} else if (previousIndex > 0) {\n\t\t\t\t\t\t// if our boundary turned out to be rubbish, the captured lookbehind\n\t\t\t\t\t\t// belongs to partData\n\t\t\t\t\t\tconst _lookbehind = new Uint8Array(lookbehind.buffer, lookbehind.byteOffset, lookbehind.byteLength);\n\t\t\t\t\t\tcallback('onPartData', 0, previousIndex, _lookbehind);\n\t\t\t\t\t\tpreviousIndex = 0;\n\t\t\t\t\t\tmark('onPartData');\n\n\t\t\t\t\t\t// reconsider the current character even so it interrupted the sequence\n\t\t\t\t\t\t// it could be the beginning of a new sequence\n\t\t\t\t\t\ti--;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\tcase S.END:\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(`Unexpected state entered: ${state}`);\n\t\t\t}\n\t\t}\n\n\t\tdataCallback('onHeaderField');\n\t\tdataCallback('onHeaderValue');\n\t\tdataCallback('onPartData');\n\n\t\t// Update properties for the next call\n\t\tthis.index = index;\n\t\tthis.state = state;\n\t\tthis.flags = flags;\n\t}\n\n\tend() {\n\t\tif ((this.state === S.HEADER_FIELD_START && this.index === 0) ||\n\t\t\t(this.state === S.PART_DATA && this.index === this.boundary.length)) {\n\t\t\tthis.onPartEnd();\n\t\t} else if (this.state !== S.END) {\n\t\t\tthrow new Error('MultipartParser.end(): stream ended unexpectedly');\n\t\t}\n\t}\n}\n\nfunction _fileName(headerValue) {\n\t// matches either a quoted-string or a token (RFC 2616 section 19.5.1)\n\tconst m = headerValue.match(/\\bfilename=(\"(.*?)\"|([^()<>@,;:\\\\\"/[\\]?={}\\s\\t]+))($|;\\s)/i);\n\tif (!m) {\n\t\treturn;\n\t}\n\n\tconst match = m[2] || m[3] || '';\n\tlet filename = match.slice(match.lastIndexOf('\\\\') + 1);\n\tfilename = filename.replace(/%22/g, '\"');\n\tfilename = filename.replace(/&#(\\d{4});/g, (m, code) => {\n\t\treturn String.fromCharCode(code);\n\t});\n\treturn filename;\n}\n\nexport async function toFormData(Body, ct) {\n\tif (!/multipart/i.test(ct)) {\n\t\tthrow new TypeError('Failed to fetch');\n\t}\n\n\tconst m = ct.match(/boundary=(?:\"([^\"]+)\"|([^;]+))/i);\n\n\tif (!m) {\n\t\tthrow new TypeError('no or bad content-type header, no multipart boundary');\n\t}\n\n\tconst parser = new MultipartParser(m[1] || m[2]);\n\n\tlet headerField;\n\tlet headerValue;\n\tlet entryValue;\n\tlet entryName;\n\tlet contentType;\n\tlet filename;\n\tconst entryChunks = [];\n\tconst formData = new FormData();\n\n\tconst onPartData = ui8a => {\n\t\tentryValue += decoder.decode(ui8a, {stream: true});\n\t};\n\n\tconst appendToFile = ui8a => {\n\t\tentryChunks.push(ui8a);\n\t};\n\n\tconst appendFileToFormData = () => {\n\t\tconst file = new File(entryChunks, filename, {type: contentType});\n\t\tformData.append(entryName, file);\n\t};\n\n\tconst appendEntryToFormData = () => {\n\t\tformData.append(entryName, entryValue);\n\t};\n\n\tconst decoder = new TextDecoder('utf-8');\n\tdecoder.decode();\n\n\tparser.onPartBegin = function () {\n\t\tparser.onPartData = onPartData;\n\t\tparser.onPartEnd = appendEntryToFormData;\n\n\t\theaderField = '';\n\t\theaderValue = '';\n\t\tentryValue = '';\n\t\tentryName = '';\n\t\tcontentType = '';\n\t\tfilename = null;\n\t\tentryChunks.length = 0;\n\t};\n\n\tparser.onHeaderField = function (ui8a) {\n\t\theaderField += decoder.decode(ui8a, {stream: true});\n\t};\n\n\tparser.onHeaderValue = function (ui8a) {\n\t\theaderValue += decoder.decode(ui8a, {stream: true});\n\t};\n\n\tparser.onHeaderEnd = function () {\n\t\theaderValue += decoder.decode();\n\t\theaderField = headerField.toLowerCase();\n\n\t\tif (headerField === 'content-disposition') {\n\t\t\t// matches either a quoted-string or a token (RFC 2616 section 19.5.1)\n\t\t\tconst m = headerValue.match(/\\bname=(\"([^\"]*)\"|([^()<>@,;:\\\\\"/[\\]?={}\\s\\t]+))/i);\n\n\t\t\tif (m) {\n\t\t\t\tentryName = m[2] || m[3] || '';\n\t\t\t}\n\n\t\t\tfilename = _fileName(headerValue);\n\n\t\t\tif (filename) {\n\t\t\t\tparser.onPartData = appendToFile;\n\t\t\t\tparser.onPartEnd = appendFileToFormData;\n\t\t\t}\n\t\t} else if (headerField === 'content-type') {\n\t\t\tcontentType = headerValue;\n\t\t}\n\n\t\theaderValue = '';\n\t\theaderField = '';\n\t};\n\n\tfor await (const chunk of Body) {\n\t\tparser.write(chunk);\n\t}\n\n\tparser.end();\n\n\treturn formData;\n}\n"],"names":["s","S","START_BOUNDARY","HEADER_FIELD_START","HEADER_FIELD","HEADER_VALUE_START","HEADER_VALUE","HEADER_VALUE_ALMOST_DONE","HEADERS_ALMOST_DONE","PART_DATA_START","PART_DATA","END","f","F","PART_BOUNDARY","LAST_BOUNDARY","LF","CR","SPACE","HYPHEN","COLON","A","Z","lower","c","noop","MultipartParser","boundary","index","flags","onHeaderEnd","onHeaderField","onHeadersEnd","onHeaderValue","onPartBegin","onPartData","onPartEnd","boundaryChars","ui8a","Uint8Array","length","i","charCodeAt","lookbehind","state","write","data","length_","previousIndex","boundaryLength","boundaryEnd","bufferLength","cl","mark","name","clear","callback","callbackSymbol","start","end","undefined","subarray","dataCallback","markSymbol","_lookbehind","buffer","byteOffset","byteLength","Error","_fileName","headerValue","m","match","filename","slice","lastIndexOf","replace","code","String","fromCharCode","toFormData","Body","ct","test","TypeError","parser","headerField","entryValue","entryName","contentType","entryChunks","formData","decoder","decode","stream","appendToFile","push","appendFileToFormData","file","type","append","appendEntryToFormData","TextDecoder","toLowerCase","chunk"],"mappings":"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","ignoreList":[0]}
@@ -1,14 +0,0 @@
1
- module.exports=[74533,(e,t,r)=>{t.exports=e.x("node:child_process",()=>require("node:child_process"))},63438,(e,t,r)=>{t.exports=e.x("ffmpeg-static-10162aab81a6ffb5",()=>require("ffmpeg-static-10162aab81a6ffb5"))},26794,e=>{"use strict";var t=e.i(47909),r=e.i(74017),n=e.i(96250),a=e.i(59756),o=e.i(61916),i=e.i(74677),s=e.i(69741),l=e.i(16795),u=e.i(87718),d=e.i(95169),c=e.i(47587),p=e.i(66012),m=e.i(70101),f=e.i(74838),h=e.i(10372),g=e.i(93695);e.i(52474);var w=e.i(220),v=e.i(12714),y=e.i(60526),E=e.i(50227),S=e.i(34731);let _=[".webm",".mp4"];class R extends Error{kind;constructor(e,t){super(t),this.kind=e,this.name="UploadError"}}async function b(e){await T(e);let t=function(){let e=process.env.GEMINI_API_KEY?.trim();if(!e)throw new R("missing_api_key","GEMINI_API_KEY is not set.\n\n 1. Get a key at https://aistudio.google.com/apikey\n 2. Copy .env.example to .env.local\n 3. Paste the key after GEMINI_API_KEY=\n 4. Re-run this command");return new S.GoogleGenAI({apiKey:e})}(),r=await x(t,e),n=await N(t,r.name);if(!n.uri)throw new R("processing_failed",`File became ACTIVE but the API returned no URI (file: ${r.name}). This is unexpected — re-run the upload.`);return{fileUri:n.uri}}async function T(e){let t;try{t=await (0,v.stat)(e)}catch{throw new R("file_not_found",`No file at "${e}". Pass the path to a .webm or .mp4 recording.`)}if(!t.isFile())throw new R("file_not_found",`"${e}" is not a file. Pass the path to a .webm or .mp4 recording.`);let r=(0,E.extname)(e).toLowerCase();if(!_.includes(r))throw new R("unsupported_format",`Unsupported file type "${r||"(none)"}". Vellum records WebM; supported inputs are: ${_.join(", ")}.`);if(t.size>0x80000000){let e=(t.size/1024/1024/1024).toFixed(2);throw new R("file_too_large",`File is ${e} GB, over the Gemini Files API limit of 2 GB. Long recordings are segmented automatically once that path lands (TASK-9); for now, use a shorter recording.`)}}async function x(e,t){try{return await e.files.upload({file:t})}catch(i){var r;let n,a,o;if(A(i))throw C(i);if(r=i,n=r?.code??"",a=r?.name??"",o=M(r).toLowerCase(),!("ETIMEDOUT"===n||"ECONNRESET"===n||"ECONNREFUSED"===n||"ENOTFOUND"===n||"UND_ERR_CONNECT_TIMEOUT"===n||"TimeoutError"===a||"AbortError"===a||o.includes("timeout")||o.includes("network")))throw i;console.error("Upload timed out, retrying once…");try{return await e.files.upload({file:t})}catch(e){if(A(e))throw C(e);throw new R("upload_timeout",`Upload timed out twice (one automatic retry already used). Check your connection and re-run. Original error: ${M(e)}`)}}}async function N(e,t){let r=function(){let e=process.env.GEMINI_UPLOAD_TIMEOUT_MS;if(!e)return 6e5;let t=Number(e);return Number.isFinite(t)&&t>0?t:6e5}(),n=$()+r;for(;;){let a=await e.files.get({name:t});if(a.state===S.FileState.ACTIVE)return a;if(a.state===S.FileState.FAILED)throw new R("processing_failed",`Gemini failed to process the file: ${a.error?.message??"no reason given"}. The video may be corrupt or an unsupported codec.`);if($()>=n){let e=Math.round(r/6e4);throw new R("upload_timeout",`File still PROCESSING after ${e} min. Increase GEMINI_UPLOAD_TIMEOUT_MS for very long videos, or check https://aistudio.google.com for service status.`)}process.stdout.write("."),await new Promise(e=>setTimeout(e,3e3))}}function A(e){if(e instanceof S.ApiError&&(401===e.status||403===e.status))return!0;let t=M(e).toLowerCase();return t.includes("api key not valid")||t.includes("api_key_invalid")||t.includes("permission_denied")}function C(e){return new R("invalid_api_key",`Gemini rejected the API key (${M(e)}).
2
-
3
- 1. Check GEMINI_API_KEY in .env.local has no extra spaces or quotes
4
- 2. Confirm the key is active at https://aistudio.google.com/apikey
5
- 3. If unsure, generate a fresh key and paste it in`)}function M(e){let t=e instanceof Error?e.message:String(e);try{let e=JSON.parse(t);if(e?.error?.message)return e.error.message}catch{}return t}function $(){return Date.now()}var I=e.i(418),P=e.i(76655),O=e.i(74533),k=e.i(2157),U=e.i(63438);function L(){let e=U.default;if(!e||!(0,k.existsSync)(e))throw Error("ffmpeg-static binary not found. Run: npm install ffmpeg-static");return e}function F(e){return new Promise(t=>{G(["-nostdin","-i",e]).then(r=>{let n,a=(n=r.match(/Duration:\s*(\d+):(\d+):(\d+(?:\.\d+)?)/))?3600*Number(n[1])+60*Number(n[2])+Number(n[3]):null;null!==a?t(a):G(["-nostdin","-i",e,"-c","copy","-f","null","-"]).then(e=>t(function(e){let t=[...e.matchAll(/time=\s*(\d+):(\d+):(\d+(?:\.\d+)?)/g)];if(0===t.length)return null;let r=t[t.length-1],n=3600*Number(r[1])+60*Number(r[2])+Number(r[3]);return n>0?n:null}(e))).catch(()=>t(null))},()=>t(null))})}function G(e){let t=L();return new Promise((r,n)=>{let a=(0,O.spawn)(t,e,{stdio:["ignore","ignore","pipe"]}),o="";a.stderr.on("data",e=>{o+=e.toString()}),a.on("error",n),a.on("close",()=>r(o))})}let D=Math.floor(1932735283.2);function q(){return j("VELLUM_SEGMENT_MAX_BYTES",D)}function j(e,t){let r=process.env[e];if(!r)return t;let n=Number(r);return Number.isFinite(n)&&n>0?n:t}async function z(e,t="thorough",r="en",n,a){var o,i,s;let l,u,{size:d}=await (0,v.stat)(e),c=q();c>0x80000000&&console.warn(" ! VELLUM_SEGMENT_MAX_BYTES is above Gemini's 2 GB limit; segments may be rejected.");let p=await F(e);if(null===p)throw Error(`Could not read the duration of "${e}" (ffmpeg printed no Duration line). The file may be corrupt or an unsupported container.`);let m=function(e,t,r){if(!(t>0))throw Error(`Cannot plan segments: video duration is ${t}s. ffmpeg could not read a usable Duration from the file.`);let n=r?.maxBytes??q(),a=r?.overlap??j("VELLUM_SEGMENT_OVERLAP_SEC",12),o=Math.min(Math.max(1,Math.floor(n/(e/t))),t);if(a>=o)throw Error(`Overlap (${a}s) must be smaller than the segment length (${o}s). Lower VELLUM_SEGMENT_OVERLAP_SEC or raise VELLUM_SEGMENT_MAX_BYTES.`);let i=o-a,s=[],l=0;for(let e=0;;e+=i){let r=Math.min(o,t-e);if(s.push({index:l++,startSec:e,durationSec:r}),e+o>=t)break}return{segments:s,totalDurationSec:t,overlapSec:a,single:1===s.length}}(d,p,{maxBytes:c});o=m,i=d,s=c,l=(i/1024/1024/1024).toFixed(2),u=(s/1024/1024).toFixed(0),console.log(` Long recording: ${l} GB over the ${u} MB segment budget — splitting into ${o.segments.length} segment(s) (~${o.overlapSec}s overlap). This is the normal path for long videos.`);let f=await (0,v.mkdtemp)(E.default.join((0,y.tmpdir)(),"vellum-seg-"));try{return await B(e,m,f,t,r,n,a)}finally{await (0,v.rm)(f,{recursive:!0,force:!0})}}async function B(e,t,r,n,a,o,i){let s,l=[],u=[],d=[],c="";for(let f of t.segments){var p,m;let h=`[segment ${f.index+1}/${t.segments.length}]`;console.log(`
6
- ${h} ${(0,P.secToMmss)(f.startSec)}–${(0,P.secToMmss)(f.startSec+f.durationSec)} of the original …`);let g=E.default.join(r,`segment-${f.index}.webm`);await function(e,t,r){let n=L(),a=["-nostdin","-y","-ss",t.startSec.toFixed(3),"-i",e,"-t",t.durationSec.toFixed(3),"-c","copy","-avoid_negative_ts","make_zero",r];return new Promise((e,o)=>{let i=(0,O.spawn)(n,a,{stdio:["ignore","ignore","pipe"]}),s="";i.stderr.on("data",e=>{s+=e.toString()}),i.on("error",o),i.on("close",n=>{0===n&&(0,k.existsSync)(r)?e():o(Error(`ffmpeg failed to cut segment ${t.index} (${t.startSec}s +${t.durationSec}s, exit ${n}).
7
- ${function(e,t=8){return e.trim().split("\n").slice(-t).join("\n")}(s)}`))})})}(e,f,g),process.stdout.write(" uploading ");let{fileUri:w}=await b(g);console.log(" ✓");let v=(p=i,m=0===f.index?void 0:function(e,t,r){let n=t.slice(-40),a=["CONTEXT FROM EARLIER SEGMENTS OF THIS RECORDING (background — already analyzed, do not redo):",`Overview so far: ${e}`,"","Items already captured (timestamps are in the FULL original recording):",...n.map(e=>`- [${e.timestamp}] ${e.title} (${e.category})`),"","IMPORTANT: The video below is ONE SEGMENT of a longer recording, not the whole",`thing. Its first ~${r}s overlap the end of the previous segment. Do NOT`,"re-report any item already listed above. Emit timestamps LOCAL to the video","below, starting at 00:00 — the segments are stitched back together afterwards."];return 0===n.length&&a.splice(3,1,"(no actionable items captured yet)"),a.join("\n")}(c,l,t.overlapSec),p?m?`${p}
8
-
9
- ---
10
-
11
- ${m}`:p:m),{result:y,calls:S}=await (0,I.analyzeSegment)(w,v,void 0,void 0,n,a,o);d.push(...S),0===f.index&&(c=y.overview,s=y.suggested_name),u.push(y.review_type);let _=function(e,t){let r=e=>{let r=Math.min(Math.max((0,P.mmssToSec)(e),0),t.durationSec);return(0,P.secToMmss)(r+t.startSec)};return e.map(e=>({...e,timestamp:r(e.timestamp),screenshot_timestamp:r(e.screenshot_timestamp)}))}(y.tasks,f),R=0;for(let e of _)!function(e,t,r){let n=H(e.title),a=(0,P.mmssToSec)(e.timestamp),o=r+15;return t.some(e=>H(e.title)===n&&Math.abs((0,P.mmssToSec)(e.timestamp)-a)<=o)}(e,l,t.overlapSec)&&(l.push(e),R+=1);console.log(` ${y.tasks.length} task(s) found, ${R} new after overlap dedup`)}return l.sort((e,t)=>(0,P.mmssToSec)(e.timestamp)-(0,P.mmssToSec)(t.timestamp)),{review_type:function(e){let t=new Map;for(let r of e)t.set(r,(t.get(r)??0)+1);let r=e[0],n=0;for(let a of e){let e=t.get(a);e>n&&(r=a,n=e)}return r}(u),overview:c,suggested_name:s,tasks:l,run:(0,I.buildRun)(d,n,a)}}function H(e){return e.trim().toLowerCase().replace(/\s+/g," ")}async function V(e,t,r){if(!(0,k.existsSync)(e))throw Error(`Video not found: ${e}`);await (0,v.mkdir)(r,{recursive:!0});let n=L(),a=await F(e),o=new Set,i=t.map(e=>{var t,n;let i,s,l,u=(t=e,n=a,!Number.isFinite(t)||t<0?0:null!==n&&t>=n?Math.max(0,n-.1):t),d=function(e,t){if(!t.has(e))return t.add(e),e;let r=e.replace(/\.png$/,""),n=2;for(;t.has(`${r}-${n}.png`);)n+=1;let a=`${r}-${n}.png`;return t.add(a),a}((s=String(Math.floor((i=Math.floor(u))/60)).padStart(2,"0"),l=String(i%60).padStart(2,"0"),`frame-${s}-${l}.png`),o);return{seekSec:u,outPath:E.default.resolve(r,d)}}),s=Array(i.length);for(let t=0;t<i.length;t+=4){let r=i.slice(t,t+4);await Promise.all(r.map(async(r,a)=>{await function(e,t,r,n){let a=["-nostdin","-y","-ss",r.toFixed(3),"-i",t,"-frames:v","1","-update","1",n];return new Promise((t,o)=>{let i=(0,O.spawn)(e,a,{stdio:["ignore","ignore","pipe"]}),s="";i.stderr.on("data",e=>{s+=e.toString()}),i.on("error",o),i.on("close",e=>{0===e&&(0,k.existsSync)(n)?t():o(Error(`ffmpeg failed to extract frame at ${r}s (exit ${e}).
12
- ${function(e,t=8){return e.trim().split("\n").slice(-t).join("\n")}(s)}`))})})}(n,e,r.seekSec,r.outPath),s[t+a]=r.outPath}))}return s}var K=e.i(94708),Y=e.i(5846),X=e.i(29242),W=e.i(69719);async function J(e){var t;let r,n,a=function(e){let t=new URL(e.url).searchParams.get("ext");if(t)return t.startsWith(".")?t:`.${t}`;let r=e.headers.get("content-type")??"";return r.includes("mp4")?".mp4":(r.includes("webm"),".webm")}(e),o=".mp4"===a?"video/mp4":"video/webm",i=(r=new URL(e.url).searchParams.get("mode"),P.ANALYSIS_MODES.includes(r)?r:"thorough"),s=(n=new URL(e.url).searchParams.get("lang"),P.ANALYSIS_LANGUAGES.includes(n)?n:"en"),l=(t=e,new URL(t.url).searchParams.get("model")?.trim()||void 0),{signal:u}=e,d=new ReadableStream({async start(t){let r,n=new TextEncoder,d=e=>{t.enqueue(n.encode(JSON.stringify(e)+"\n"))};try{let{bytes:t,reviseContext:n}=await Q(e);u.throwIfAborted(),r=await (0,v.mkdtemp)(E.default.join((0,y.tmpdir)(),"vellum-analyze-"));let c=E.default.join(r,`recording${a}`);await (0,v.writeFile)(c,t);let p=await Z(c,o,i,s,l,n,d,u);n&&p.run&&(p.run.origin="revise-video");let m=E.default.join(r,"screenshots"),f=[];for(let e=0;e<p.tasks.length;e+=1){u.throwIfAborted();let t=(0,P.mmssToSec)(p.tasks[e].screenshot_timestamp),[r]=await V(c,[t],m),n=await (0,v.readFile)(r);f.push({name:E.default.basename(r),base64:n.toString("base64")}),d({type:"progress",phase:"extracting",n:e+1,m:p.tasks.length})}u.throwIfAborted(),d({type:"progress",phase:"writing"}),d({type:"done",result:p,screenshots:f})}catch(e){var c;u.aborted||(console.error("[analyze] pipeline error:",e),d({type:"error",...(c=e)instanceof R?{kind:"upload",message:c.message}:c instanceof I.AnalyzeError?{kind:"analyze",message:c.message}:{kind:"internal",message:c instanceof Error?c.message:String(c)}}))}finally{r&&await (0,v.rm)(r,{recursive:!0,force:!0}),t.close()}}});return new Response(d,{headers:{"Content-Type":"application/x-ndjson; charset=utf-8","Cache-Control":"no-store, no-transform"}})}async function Z(e,t,r,n,a,o,i,s){let{size:l}=await (0,v.stat)(e);if(i({type:"progress",phase:"upload"}),l>q())return i({type:"progress",phase:"analyzing"}),z(e,r,n,a,o);let{fileUri:u}=await b(e);return s.throwIfAborted(),i({type:"progress",phase:"analyzing"}),(0,I.analyze)(u,t,s,r,n,a,o)}async function Q(e){if(!(e.headers.get("content-type")??"").includes("multipart/form-data"))return{bytes:Buffer.from(await e.arrayBuffer()),reviseContext:void 0};let t=await e.formData(),r=t.get("video");if(!(r instanceof Blob))throw Error("Revise request is missing its 'video' part.");let n=Buffer.from(await r.arrayBuffer()),a=t.get("revise");if("string"!=typeof a)return{bytes:n,reviseContext:void 0};let{source:o,comments:i}=function(e){let t=ee.safeParse(JSON.parse(e));if(!t.success)throw Error(`Invalid revise payload: ${t.error.message}`);let r=t.data.result.tasks.map((e,t)=>"id"in e?e:{...e,id:`t${t+1}`,origin:"ai"});return{source:{overview:t.data.result.overview,review_type:t.data.result.review_type,tasks:r},comments:t.data.comments}}(a);return{bytes:n,reviseContext:(0,X.buildReviseVideoContext)(o,i)}}let ee=W.z.object({result:W.z.union([K.StoredAnalysisResultSchema,P.AnalysisResultSchema]),comments:W.z.array(Y.CommentSchema)});e.s(["POST",0,J,"runtime",0,"nodejs"],61312);var et=e.i(61312);let er=new t.AppRouteRouteModule({definition:{kind:r.RouteKind.APP_ROUTE,page:"/api/analyze/route",pathname:"/api/analyze",filename:"route",bundlePath:""},distDir:".next",relativeProjectDir:"",resolvedPagePath:"[project]/src/app/api/analyze/route.ts",nextConfigOutput:"",userland:et,...{}}),{workAsyncStorage:en,workUnitAsyncStorage:ea,serverHooks:eo}=er;async function ei(e,t,n){n.requestMeta&&(0,a.setRequestMeta)(e,n.requestMeta),er.isDev&&(0,a.addRequestMeta)(e,"devRequestTimingInternalsEnd",process.hrtime.bigint());let v="/api/analyze/route";v=v.replace(/\/index$/,"")||"/";let y=await er.prepare(e,t,{srcPage:v,multiZoneDraftMode:!1});if(!y)return t.statusCode=400,t.end("Bad Request"),null==n.waitUntil||n.waitUntil.call(n,Promise.resolve()),null;let{buildId:E,deploymentId:S,params:_,nextConfig:R,parsedUrl:b,isDraftMode:T,prerenderManifest:x,routerServerContext:N,isOnDemandRevalidate:A,revalidateOnlyGenerated:C,resolvedPathname:M,clientReferenceManifest:$,serverActionsManifest:I}=y,P=(0,s.normalizeAppPath)(v),O=!!(x.dynamicRoutes[P]||x.routes[M]),k=async()=>((null==N?void 0:N.render404)?await N.render404(e,t,b,!1):t.end("This page could not be found"),null);if(O&&!T){let e=!!x.routes[M],t=x.dynamicRoutes[P];if(t&&!1===t.fallback&&!e){if(R.adapterPath)return await k();throw new g.NoFallbackError}}let U=null;!O||er.isDev||T||(U="/index"===(U=M)?"/":U);let L=!0===er.isDev||!O,F=O&&!L;I&&$&&(0,i.setManifestsSingleton)({page:v,clientReferenceManifest:$,serverActionsManifest:I});let G=e.method||"GET",D=(0,o.getTracer)(),q=D.getActiveScopeSpan(),j=!!(null==N?void 0:N.isWrappedByNextServer),z=!!(0,a.getRequestMeta)(e,"minimalMode"),B=(0,a.getRequestMeta)(e,"incrementalCache")||await er.getIncrementalCache(e,R,x,z);null==B||B.resetRequestCache(),globalThis.__incrementalCache=B;let H={params:_,previewProps:x.preview,renderOpts:{experimental:{authInterrupts:!!R.experimental.authInterrupts},cacheComponents:!!R.cacheComponents,supportsDynamicResponse:L,incrementalCache:B,cacheLifeProfiles:R.cacheLife,waitUntil:n.waitUntil,onClose:e=>{t.on("close",e)},onAfterTaskError:void 0,onInstrumentationRequestError:(t,r,n,a)=>er.onRequestError(e,t,n,a,N)},sharedContext:{buildId:E,deploymentId:S}},V=new l.NodeNextRequest(e),K=new l.NodeNextResponse(t),Y=u.NextRequestAdapter.fromNodeNextRequest(V,(0,u.signalFromNodeResponse)(t));try{let a,i=async e=>er.handle(Y,H).finally(()=>{if(!e)return;e.setAttributes({"http.status_code":t.statusCode,"next.rsc":!1});let r=D.getRootSpanAttributes();if(!r)return;if(r.get("next.span_type")!==d.BaseServerSpan.handleRequest)return void console.warn(`Unexpected root span type '${r.get("next.span_type")}'. Please report this Next.js issue https://github.com/vercel/next.js`);let n=r.get("next.route");if(n){let t=`${G} ${n}`;e.setAttributes({"next.route":n,"http.route":n,"next.span_name":t}),e.updateName(t),a&&a!==e&&(a.setAttribute("http.route",n),a.updateName(t))}else e.updateName(`${G} ${v}`)}),s=async a=>{var o,s;let l=async({previousCacheEntry:r})=>{try{if(!z&&A&&C&&!r)return t.statusCode=404,t.setHeader("x-nextjs-cache","REVALIDATED"),t.end("This page could not be found"),null;let o=await i(a);e.fetchMetrics=H.renderOpts.fetchMetrics;let s=H.renderOpts.pendingWaitUntil;s&&n.waitUntil&&(n.waitUntil(s),s=void 0);let l=H.renderOpts.collectedTags;if(!O)return await (0,p.sendResponse)(V,K,o,H.renderOpts.pendingWaitUntil),null;{let e=await o.blob(),t=(0,m.toNodeOutgoingHttpHeaders)(o.headers);l&&(t[h.NEXT_CACHE_TAGS_HEADER]=l),!t["content-type"]&&e.type&&(t["content-type"]=e.type);let r=void 0!==H.renderOpts.collectedRevalidate&&!(H.renderOpts.collectedRevalidate>=h.INFINITE_CACHE)&&H.renderOpts.collectedRevalidate,n=void 0===H.renderOpts.collectedExpire||H.renderOpts.collectedExpire>=h.INFINITE_CACHE?void 0:H.renderOpts.collectedExpire;return{value:{kind:w.CachedRouteKind.APP_ROUTE,status:o.status,body:Buffer.from(await e.arrayBuffer()),headers:t},cacheControl:{revalidate:r,expire:n}}}}catch(t){throw(null==r?void 0:r.isStale)&&await er.onRequestError(e,t,{routerKind:"App Router",routePath:v,routeType:"route",revalidateReason:(0,c.getRevalidateReason)({isStaticGeneration:F,isOnDemandRevalidate:A})},!1,N),t}},u=await er.handleResponse({req:e,nextConfig:R,cacheKey:U,routeKind:r.RouteKind.APP_ROUTE,isFallback:!1,prerenderManifest:x,isRoutePPREnabled:!1,isOnDemandRevalidate:A,revalidateOnlyGenerated:C,responseGenerator:l,waitUntil:n.waitUntil,isMinimalMode:z});if(!O)return null;if((null==u||null==(o=u.value)?void 0:o.kind)!==w.CachedRouteKind.APP_ROUTE)throw Object.defineProperty(Error(`Invariant: app-route received invalid cache entry ${null==u||null==(s=u.value)?void 0:s.kind}`),"__NEXT_ERROR_CODE",{value:"E701",enumerable:!1,configurable:!0});z||t.setHeader("x-nextjs-cache",A?"REVALIDATED":u.isMiss?"MISS":u.isStale?"STALE":"HIT"),T&&t.setHeader("Cache-Control","private, no-cache, no-store, max-age=0, must-revalidate");let d=(0,m.fromNodeOutgoingHttpHeaders)(u.value.headers);return z&&O||d.delete(h.NEXT_CACHE_TAGS_HEADER),!u.cacheControl||t.getHeader("Cache-Control")||d.get("Cache-Control")||d.set("Cache-Control",(0,f.getCacheControlHeader)(u.cacheControl)),await (0,p.sendResponse)(V,K,new Response(u.value.body,{headers:d,status:u.value.status||200})),null};j&&q?await s(q):(a=D.getActiveScopeSpan(),await D.withPropagatedContext(e.headers,()=>D.trace(d.BaseServerSpan.handleRequest,{spanName:`${G} ${v}`,kind:o.SpanKind.SERVER,attributes:{"http.method":G,"http.target":e.url}},s),void 0,!j))}catch(t){if(t instanceof g.NoFallbackError||await er.onRequestError(e,t,{routerKind:"App Router",routePath:P,routeType:"route",revalidateReason:(0,c.getRevalidateReason)({isStaticGeneration:F,isOnDemandRevalidate:A})},!1,N),O)throw t;return await (0,p.sendResponse)(V,K,new Response(null,{status:500})),null}}e.s(["handler",0,ei,"patchFetch",0,function(){return(0,n.patchFetch)({workAsyncStorage:en,workUnitAsyncStorage:ea})},"routeModule",0,er,"serverHooks",0,eo,"workAsyncStorage",0,en,"workUnitAsyncStorage",0,ea],26794)}];
13
-
14
- //# sourceMappingURL=%5Broot-of-the-server%5D__1kp4vwc._.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/app/api/analyze/route.ts","../../../src/lib/gemini/upload.ts","../../../node_modules/next/dist/esm/build/templates/app-route.js","../../../src/lib/ffmpeg/segment-video.ts","../../../src/lib/ffmpeg/binary.ts","../../../src/lib/gemini/analyze-long.ts","../../../src/lib/ffmpeg/extract-screenshots.ts","../../../src/lib/ffmpeg/probe-duration.ts"],"sourcesContent":["import { mkdtemp, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { uploadVideo, UploadError } from \"@/lib/gemini/upload\";\nimport { analyze, AnalyzeError } from \"@/lib/gemini/analyze\";\nimport { analyzeLong } from \"@/lib/gemini/analyze-long\";\nimport { maxSegmentBytes } from \"@/lib/ffmpeg/segment-video\";\nimport { extractScreenshots } from \"@/lib/ffmpeg/extract-screenshots\";\nimport {\n ANALYSIS_LANGUAGES,\n ANALYSIS_MODES,\n AnalysisResultSchema,\n mmssToSec,\n type AnalysisLanguage,\n type AnalysisMode,\n type AnalysisResult,\n} from \"@/lib/gemini/schema\";\nimport { StoredAnalysisResultSchema, type StoredVellumTask } from \"@/lib/gemini/stored\";\nimport type { VellumTask } from \"@/lib/gemini/schema\";\nimport { CommentSchema } from \"@/lib/comments/comment\";\nimport {\n buildReviseVideoContext,\n type ReviseSource,\n} from \"@/lib/gemini/prompts/revise-tasks\";\nimport { z } from \"zod\";\n\n/**\n * POST /api/analyze — the stateless bridge between the browser workspace and the\n * Node pipeline (ADR-014, ARCHITECTURE §Data flow steps 5–9).\n *\n * The browser holds the recording only through a File-System-Access directory\n * handle, which never exposes an absolute path to JS or the server. So the\n * client POSTs the recording BYTES; this route writes them to a throwaway temp\n * file, runs the SAME Phase 1 pipeline the CLI does — uploadVideo → analyze\n * (analyzeLong for files over the segment budget) → extractScreenshots — and\n * streams progress + the validated AnalysisResult + the screenshot PNGs back.\n *\n * It mirrors scripts/cli.ts's orchestration MINUS every write to a session\n * folder: nothing is persisted server-side. The browser owns writing report.md,\n * tasks.json, and screenshots/ into the workspace (a browser-side writeReport).\n * The temp file is always discarded — on success AND on failure (AC#4, #5).\n *\n * Wire format: NDJSON — one JSON object per line, \"\\n\"-separated — over a\n * streaming Response. HTTP status stays 200 even on a pipeline failure; the\n * failure rides as a terminal {\"type\":\"error\"} event so a partial stream is\n * still well-formed (ARCHITECTURE §Error handling: fail loud, structured).\n */\nexport const runtime = \"nodejs\";\n\n/** ffmpeg + the Gemini SDK need Node APIs — never the edge runtime. */\ntype StreamEvent =\n | {\n type: \"progress\";\n phase: \"upload\" | \"analyzing\" | \"extracting\" | \"writing\";\n /** upload may carry a percentage; extracting carries n-of-m. Both optional. */\n pct?: number;\n n?: number;\n m?: number;\n }\n | {\n type: \"done\";\n result: AnalysisResult;\n /** Parallel to result.tasks, same order (one PNG per screenshot_timestamp). */\n screenshots: { name: string; base64: string }[];\n }\n | { type: \"error\"; kind: string; message: string };\n\nexport async function POST(req: Request): Promise<Response> {\n const ext = resolveExt(req);\n const mimeType = mimeTypeForExt(ext);\n // TASK-46 — cost mode from ?mode=; defaults to \"thorough\" so an old client\n // (or the local CLI) that never sends it keeps the two-pass behavior. Only\n // \"economy\" switches to the single-pass path; anything else falls back safely.\n const mode = resolveMode(req);\n // TASK-49 — output language from ?lang=; defaults to \"en\" so an old client\n // (or the local CLI) that never sends it keeps the English-only behavior\n // (ADR-006). Only \"uk\" switches on the Ukrainian normalization.\n const language = resolveLanguage(req);\n // TASK-50 — an optional PRIMARY model override from ?model=. undefined (no\n // query) keeps the built-in MODEL, so an old client (or the local CLI) that\n // never sends it runs byte-identical. NOT validated against a model list on\n // purpose: a dead/unknown model fails loud in runStructured, which is the\n // acceptable, honest failure (the picker in TASK-47 only offers live models).\n const model = resolveModel(req);\n // req.signal aborts when the client cancels (TASK-42) — the browser aborts the\n // fetch, which disconnects here. We check it between stages so a Cancel stops\n // the pipeline (no wasted ffmpeg/Gemini work) and always reaches the temp\n // cleanup in finally, instead of running to completion after the client left.\n const { signal } = req;\n\n const stream = new ReadableStream<Uint8Array>({\n async start(controller) {\n const encoder = new TextEncoder();\n const emit = (event: StreamEvent): void => {\n controller.enqueue(encoder.encode(JSON.stringify(event) + \"\\n\"));\n };\n\n // Created lazily so a failure before mkdtemp still hits the finally with\n // nothing to clean; once set, the whole dir (temp video + screenshots) is\n // removed regardless of how we exit (AC#4).\n let tmpDir: string | undefined;\n try {\n // Read the recording bytes and, for a re-run-with-video (TASK-60), the\n // optional revise payload. A plain analysis posts the raw bytes (the\n // historical path); a revise posts multipart (video + { priorResult,\n // comments }) so the payload isn't header-size-bounded. Redundant I/O\n // either way — the bytes already sit on disk in the workspace — but there\n // is no path to hand the server (ADR-014), so we re-materialize them.\n const { bytes, reviseContext } = await readBody(req);\n signal.throwIfAborted();\n tmpDir = await mkdtemp(path.join(tmpdir(), \"vellum-analyze-\"));\n const videoPath = path.join(tmpDir, `recording${ext}`);\n await writeFile(videoPath, bytes);\n\n const result = await runAnalysis(\n videoPath,\n mimeType,\n mode,\n language,\n model,\n reviseContext,\n emit,\n signal,\n );\n // TASK-60 — stamp the run's origin so the Details tab labels a video revise\n // apart from a fresh analysis. run is pipeline-assembled telemetry (never a\n // Gemini field), so overriding it here doesn't touch the model contract.\n if (reviseContext && result.run) result.run.origin = \"revise-video\";\n\n // Screenshots: one ffmpeg pass per task so progress is a real N/M\n // counter, mirroring cli.ts. extractScreenshots already produces the\n // ADR-013 \"frame-MM-SS.png\" names — keep them, the browser reuses them\n // verbatim when it writes screenshots/ into the workspace. Read each PNG\n // back immediately (before the next pass can overwrite a same-second\n // name) and base64 it; the array stays parallel to result.tasks.\n const screenshotsDir = path.join(tmpDir, \"screenshots\");\n const screenshots: { name: string; base64: string }[] = [];\n for (let i = 0; i < result.tasks.length; i += 1) {\n // Bail before each ffmpeg pass so a Cancel stops the extract loop\n // promptly rather than grinding through every remaining frame.\n signal.throwIfAborted();\n const sec = mmssToSec(result.tasks[i].screenshot_timestamp);\n const [shotPath] = await extractScreenshots(videoPath, [sec], screenshotsDir);\n const png = await readFile(shotPath);\n screenshots.push({ name: path.basename(shotPath), base64: png.toString(\"base64\") });\n emit({ type: \"progress\", phase: \"extracting\", n: i + 1, m: result.tasks.length });\n }\n\n signal.throwIfAborted();\n // The server writes nothing, but the client still needs the \"wrapping\n // up\" beat before the terminal event — it maps to the browser-side\n // writeReport that follows (ADR-014).\n emit({ type: \"progress\", phase: \"writing\" });\n emit({ type: \"done\", result, screenshots });\n } catch (err) {\n // A client Cancel (aborted signal) is not a failure to report — the\n // browser already tore down its stream reader; just fall through to the\n // finally so the temp dir is cleaned. Any other error is structured, not\n // a raw 500: the typed stage errors carry user-facing guidance (a\n // missing/invalid GEMINI_API_KEY becomes a hint, not a trace). HTTP is\n // already 200; the failure is the payload.\n if (!signal.aborted) {\n // Log server-side too — the failure is otherwise only in the stream\n // payload, invisible in the dev server console (the route stays 200).\n console.error(\"[analyze] pipeline error:\", err);\n emit({ type: \"error\", ...toStreamError(err) });\n }\n } finally {\n if (tmpDir) await rm(tmpDir, { recursive: true, force: true });\n controller.close();\n }\n },\n });\n\n return new Response(stream, {\n headers: {\n \"Content-Type\": \"application/x-ndjson; charset=utf-8\",\n \"Cache-Control\": \"no-store, no-transform\",\n },\n });\n}\n\n/**\n * Stages 1–2, routed by file size exactly like cli.ts: a recording over the\n * per-segment byte budget goes through analyzeLong (which does its own\n * per-segment upload + analyze + timestamp remap); everything else takes the\n * single uploadVideo → analyze path. Both return the same AnalysisResult shape,\n * so the caller is identical downstream (AC#3).\n *\n * Progress is best-effort around opaque calls (uploadVideo/analyze expose no\n * fine-grained callbacks): we emit the phase boundaries the client needs to\n * drive its UI — upload → analyzing — in a consistent order for both paths.\n */\nasync function runAnalysis(\n videoPath: string,\n mimeType: string,\n mode: AnalysisMode,\n language: AnalysisLanguage,\n // TASK-50 — the chosen PRIMARY model (or undefined for the built-in MODEL),\n // threaded into both the short and long analysis paths.\n model: string | undefined,\n // TASK-60 — the re-run-with-video revise context (prior tasks + comments), or\n // undefined for a plain analysis. Woven into the analysis prompt(s).\n reviseContext: string | undefined,\n emit: (event: StreamEvent) => void,\n signal: AbortSignal,\n): Promise<AnalysisResult> {\n const { size } = await stat(videoPath);\n\n emit({ type: \"progress\", phase: \"upload\" });\n if (size > maxSegmentBytes()) {\n // analyzeLong uploads + analyzes each segment behind its boundary; we can't\n // interleave finer phases through it, so we mark the whole pass \"analyzing\".\n // Its segments are always re-encoded to WebM, so it needs no mimeType. It\n // does NOT yet forward the abort signal into its per-segment Gemini calls\n // (follow-up); the boundary checks in POST still short-circuit around it.\n emit({ type: \"progress\", phase: \"analyzing\" });\n return analyzeLong(videoPath, mode, language, model, reviseContext);\n }\n\n const { fileUri } = await uploadVideo(videoPath);\n signal.throwIfAborted();\n emit({ type: \"progress\", phase: \"analyzing\" });\n // Thread the real container mimeType so an imported mp4 is described to Gemini\n // as mp4, not webm (S13); webm callers pass \"video/webm\" and are unchanged.\n // The signal reaches the in-flight generateContent so a Cancel tears it down.\n return analyze(fileUri, mimeType, signal, mode, language, model, reviseContext);\n}\n\n/**\n * Read the POST body: raw video bytes for a plain analysis, or a multipart form\n * (video + revise JSON) for a re-run-with-video (TASK-60). The revise JSON carries\n * the prior analysis + the reviewer's comments, which become the reviseContext\n * woven into the analysis prompt. A malformed revise part fails loud (AnalyzeError-\n * shaped via the caller's toStreamError) rather than silently analyzing plain.\n */\nasync function readBody(\n req: Request,\n): Promise<{ bytes: Buffer; reviseContext: string | undefined }> {\n const contentType = req.headers.get(\"content-type\") ?? \"\";\n if (!contentType.includes(\"multipart/form-data\")) {\n return { bytes: Buffer.from(await req.arrayBuffer()), reviseContext: undefined };\n }\n\n const form = await req.formData();\n const video = form.get(\"video\");\n if (!(video instanceof Blob)) {\n throw new Error(\"Revise request is missing its 'video' part.\");\n }\n const bytes = Buffer.from(await video.arrayBuffer());\n\n const reviseRaw = form.get(\"revise\");\n if (typeof reviseRaw !== \"string\") {\n // Multipart with no revise part — treat as a plain analysis of the video.\n return { bytes, reviseContext: undefined };\n }\n const { source, comments } = parseRevisePart(reviseRaw);\n return { bytes, reviseContext: buildReviseVideoContext(source, comments) };\n}\n\n/** The shape of the multipart \"revise\" field (mirrors /api/revise's body). */\nconst RevisePartSchema = z.object({\n result: z.union([StoredAnalysisResultSchema, AnalysisResultSchema]),\n comments: z.array(CommentSchema),\n});\n\n/** Parse + validate the revise JSON into a prompt source + comments. */\nfunction parseRevisePart(raw: string): {\n source: ReviseSource;\n comments: z.infer<typeof CommentSchema>[];\n} {\n const parsed = RevisePartSchema.safeParse(JSON.parse(raw));\n if (!parsed.success) {\n throw new Error(`Invalid revise payload: ${parsed.error.message}`);\n }\n const rawTasks: (StoredVellumTask | VellumTask)[] = parsed.data.result.tasks;\n const tasks: StoredVellumTask[] = rawTasks.map((task, i) =>\n \"id\" in task ? task : { ...task, id: `t${i + 1}`, origin: \"ai\" },\n );\n return {\n source: {\n overview: parsed.data.result.overview,\n review_type: parsed.data.result.review_type,\n tasks,\n },\n comments: parsed.data.comments,\n };\n}\n\n/**\n * Map a thrown error to the structured stream event. The typed stage errors\n * carry actionable messages verbatim (UploadError's missing_api_key message is\n * a step-by-step hint, not a stack); anything else is an unexpected internal\n * fault whose message we surface without a trace.\n */\nfunction toStreamError(err: unknown): { kind: string; message: string } {\n if (err instanceof UploadError) return { kind: \"upload\", message: err.message };\n if (err instanceof AnalyzeError) return { kind: \"analyze\", message: err.message };\n return {\n kind: \"internal\",\n message: err instanceof Error ? err.message : String(err),\n };\n}\n\n/**\n * The temp file needs a real extension: uploadVideo validates it (.webm/.mp4)\n * and ffmpeg infers the container from it. The browser records WebM (ADR-003),\n * so that is the default; an explicit `?ext=` (from the client, which knows the\n * source name) or a video Content-Type can override it. A leading dot is\n * optional in the query value.\n */\nfunction resolveExt(req: Request): string {\n const raw = new URL(req.url).searchParams.get(\"ext\");\n if (raw) return raw.startsWith(\".\") ? raw : `.${raw}`;\n\n const contentType = req.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"mp4\")) return \".mp4\";\n if (contentType.includes(\"webm\")) return \".webm\";\n return \".webm\";\n}\n\n/**\n * The container mimeType Gemini needs for the uploaded file (analyze threads it\n * into createPartFromUri). Mirrors mimeForRecordingExt on the browser side; the\n * two halves share a wire format, not a module (ADR-014). Anything other than\n * mp4 defaults to webm, matching resolveExt's default.\n */\nfunction mimeTypeForExt(ext: string): string {\n return ext === \".mp4\" ? \"video/mp4\" : \"video/webm\";\n}\n\n/**\n * The cost mode from ?mode= (TASK-46). Validated against ANALYSIS_MODES so a\n * missing, empty, or unknown value falls back to \"thorough\" — the safe default\n * (never silently downgrade quality on a malformed request).\n */\nfunction resolveMode(req: Request): AnalysisMode {\n const raw = new URL(req.url).searchParams.get(\"mode\");\n return ANALYSIS_MODES.includes(raw as AnalysisMode) ? (raw as AnalysisMode) : \"thorough\";\n}\n\n/**\n * The output language from ?lang= (TASK-49). Validated against ANALYSIS_LANGUAGES\n * so a missing, empty, or unknown value falls back to \"en\" — the safe default\n * that keeps the historical English-only behavior (ADR-006). Only \"uk\" turns on\n * the Ukrainian normalization instruction in the prompts.\n */\nfunction resolveLanguage(req: Request): AnalysisLanguage {\n const raw = new URL(req.url).searchParams.get(\"lang\");\n return ANALYSIS_LANGUAGES.includes(raw as AnalysisLanguage) ? (raw as AnalysisLanguage) : \"en\";\n}\n\n/**\n * The chosen PRIMARY model from ?model= (TASK-50), or undefined when absent —\n * which the pipeline treats as the built-in MODEL, so behavior is unchanged\n * until TASK-47's picker sends a choice. Deliberately NOT validated against the\n * live model list: /api/models only ever offers real models, and a stale/dead\n * choice fails loud in runStructured (the accepted, honest failure). We only\n * trim/empty-guard so a bare \"?model=\" doesn't select an empty-string model.\n */\nfunction resolveModel(req: Request): string | undefined {\n const raw = new URL(req.url).searchParams.get(\"model\")?.trim();\n return raw ? raw : undefined;\n}\n","import { ApiError, FileState, GoogleGenAI } from \"@google/genai\";\nimport { extname } from \"node:path\";\nimport { stat } from \"node:fs/promises\";\n\n/**\n * Stage 1 of the Phase 1 pipeline (ARCHITECTURE.md §Pipeline contracts):\n *\n * uploadVideo(videoPath): Promise<{ fileUri: string }>\n *\n * Takes a local recording, uploads it to the Gemini Files API, waits for it to\n * become ACTIVE, and returns the file URI that the analysis stage will consume.\n *\n * Error philosophy (ARCHITECTURE.md §Error handling): fail loud, never silent\n * retry loops. The only automatic retry is a SINGLE retry on a network timeout\n * during upload — everything else throws immediately with a human message.\n */\n\n// Gemini Files API hard limit. Bigger files are TASK-9's job (segment + overlap),\n// not something we silently try and let the API reject with a cryptic error.\nconst MAX_FILE_BYTES = 2 * 1024 * 1024 * 1024; // 2 GB\n\nconst SUPPORTED_EXTENSIONS = [\".webm\", \".mp4\"] as const;\n\nconst POLL_INTERVAL_MS = 3_000;\nconst DEFAULT_POLL_TIMEOUT_MS = 10 * 60 * 1000; // 10 min; override with GEMINI_UPLOAD_TIMEOUT_MS\n\n/**\n * A failure the user can act on. The CLI prints `message` verbatim — so the\n * message itself must be the guidance, not a code the user has to look up.\n */\nexport class UploadError extends Error {\n constructor(\n readonly kind:\n | \"missing_api_key\"\n | \"invalid_api_key\"\n | \"file_not_found\"\n | \"unsupported_format\"\n | \"file_too_large\"\n | \"upload_timeout\"\n | \"processing_failed\",\n message: string,\n ) {\n super(message);\n this.name = \"UploadError\";\n }\n}\n\nexport async function uploadVideo(videoPath: string): Promise<{ fileUri: string }> {\n await validateFile(videoPath);\n const ai = makeClient();\n\n const file = await uploadWithOneRetry(ai, videoPath);\n const active = await pollUntilActive(ai, file.name!);\n\n if (!active.uri) {\n // ACTIVE but no URI should never happen; treat as a hard failure rather\n // than returning an empty string downstream.\n throw new UploadError(\n \"processing_failed\",\n `File became ACTIVE but the API returned no URI (file: ${file.name}). This is unexpected — re-run the upload.`,\n );\n }\n\n return { fileUri: active.uri };\n}\n\nasync function validateFile(videoPath: string): Promise<void> {\n let stats;\n try {\n stats = await stat(videoPath);\n } catch {\n throw new UploadError(\n \"file_not_found\",\n `No file at \"${videoPath}\". Pass the path to a .webm or .mp4 recording.`,\n );\n }\n\n if (!stats.isFile()) {\n throw new UploadError(\n \"file_not_found\",\n `\"${videoPath}\" is not a file. Pass the path to a .webm or .mp4 recording.`,\n );\n }\n\n const ext = extname(videoPath).toLowerCase();\n if (!SUPPORTED_EXTENSIONS.includes(ext as (typeof SUPPORTED_EXTENSIONS)[number])) {\n throw new UploadError(\n \"unsupported_format\",\n `Unsupported file type \"${ext || \"(none)\"}\". Vellum records WebM; supported inputs are: ${SUPPORTED_EXTENSIONS.join(\", \")}.`,\n );\n }\n\n if (stats.size > MAX_FILE_BYTES) {\n const gb = (stats.size / 1024 / 1024 / 1024).toFixed(2);\n throw new UploadError(\n \"file_too_large\",\n `File is ${gb} GB, over the Gemini Files API limit of 2 GB. Long recordings are segmented automatically once that path lands (TASK-9); for now, use a shorter recording.`,\n );\n }\n}\n\n/**\n * Build the client here (rather than importing the shared one) so we own the\n * missing-key message: the user gets step-by-step guidance, not a raw 401.\n */\nfunction makeClient(): GoogleGenAI {\n const apiKey = process.env.GEMINI_API_KEY?.trim();\n if (!apiKey) {\n throw new UploadError(\n \"missing_api_key\",\n [\n \"GEMINI_API_KEY is not set.\",\n \"\",\n \" 1. Get a key at https://aistudio.google.com/apikey\",\n \" 2. Copy .env.example to .env.local\",\n \" 3. Paste the key after GEMINI_API_KEY=\",\n \" 4. Re-run this command\",\n ].join(\"\\n\"),\n );\n }\n return new GoogleGenAI({ apiKey });\n}\n\nasync function uploadWithOneRetry(ai: GoogleGenAI, videoPath: string) {\n try {\n return await ai.files.upload({ file: videoPath });\n } catch (err) {\n if (isAuthError(err)) throw authGuidance(err);\n if (!isNetworkTimeout(err)) throw err; // fail loud — no retry on unknown errors\n\n // The one allowed automatic retry (error philosophy: at most one, on a\n // network timeout). If this also fails, the error propagates loud.\n console.error(\"Upload timed out, retrying once…\");\n try {\n return await ai.files.upload({ file: videoPath });\n } catch (retryErr) {\n if (isAuthError(retryErr)) throw authGuidance(retryErr);\n throw new UploadError(\n \"upload_timeout\",\n `Upload timed out twice (one automatic retry already used). Check your connection and re-run. Original error: ${messageOf(retryErr)}`,\n );\n }\n }\n}\n\nasync function pollUntilActive(ai: GoogleGenAI, fileName: string) {\n const timeoutMs = pollTimeoutMs();\n const deadline = nowMs() + timeoutMs;\n\n // We re-fetch the file by name; the freshly-uploaded object starts in\n // PROCESSING and flips to ACTIVE (or FAILED) when Gemini finishes ingesting.\n for (;;) {\n const file = await ai.files.get({ name: fileName });\n\n if (file.state === FileState.ACTIVE) return file;\n if (file.state === FileState.FAILED) {\n throw new UploadError(\n \"processing_failed\",\n `Gemini failed to process the file: ${file.error?.message ?? \"no reason given\"}. The video may be corrupt or an unsupported codec.`,\n );\n }\n\n if (nowMs() >= deadline) {\n const mins = Math.round(timeoutMs / 60_000);\n throw new UploadError(\n \"upload_timeout\",\n `File still PROCESSING after ${mins} min. Increase GEMINI_UPLOAD_TIMEOUT_MS for very long videos, or check https://aistudio.google.com for service status.`,\n );\n }\n\n process.stdout.write(\".\");\n await sleep(POLL_INTERVAL_MS);\n }\n}\n\n// --- error classification -------------------------------------------------\n\nfunction isAuthError(err: unknown): boolean {\n // An invalid key comes back as HTTP 400 with an API_KEY_INVALID reason — not\n // a 401 — so we can't classify on status alone; we also sniff the message.\n if (err instanceof ApiError && (err.status === 401 || err.status === 403)) {\n return true;\n }\n const msg = messageOf(err).toLowerCase();\n return (\n msg.includes(\"api key not valid\") ||\n msg.includes(\"api_key_invalid\") ||\n msg.includes(\"permission_denied\")\n );\n}\n\nfunction authGuidance(err: unknown): UploadError {\n return new UploadError(\n \"invalid_api_key\",\n [\n `Gemini rejected the API key (${messageOf(err)}).`,\n \"\",\n \" 1. Check GEMINI_API_KEY in .env.local has no extra spaces or quotes\",\n \" 2. Confirm the key is active at https://aistudio.google.com/apikey\",\n \" 3. If unsure, generate a fresh key and paste it in\",\n ].join(\"\\n\"),\n );\n}\n\nfunction isNetworkTimeout(err: unknown): boolean {\n // Node fetch / undici surface timeouts and dropped connections through these\n // codes or names; we treat all of them as a retryable network timeout.\n const code = (err as { code?: string } | null)?.code ?? \"\";\n const name = (err as { name?: string } | null)?.name ?? \"\";\n const msg = messageOf(err).toLowerCase();\n return (\n code === \"ETIMEDOUT\" ||\n code === \"ECONNRESET\" ||\n code === \"ECONNREFUSED\" ||\n code === \"ENOTFOUND\" ||\n code === \"UND_ERR_CONNECT_TIMEOUT\" ||\n name === \"TimeoutError\" ||\n name === \"AbortError\" ||\n msg.includes(\"timeout\") ||\n msg.includes(\"network\")\n );\n}\n\nfunction messageOf(err: unknown): string {\n const raw = err instanceof Error ? err.message : String(err);\n // ApiError stuffs the whole JSON error envelope into .message; pull out the\n // human-readable line so we don't echo a wall of JSON at the user.\n try {\n const parsed = JSON.parse(raw) as { error?: { message?: string } };\n if (parsed?.error?.message) return parsed.error.message;\n } catch {\n // not JSON — fall through\n }\n return raw;\n}\n\n// --- small helpers --------------------------------------------------------\n\nfunction pollTimeoutMs(): number {\n const raw = process.env.GEMINI_UPLOAD_TIMEOUT_MS;\n if (!raw) return DEFAULT_POLL_TIMEOUT_MS;\n const parsed = Number(raw);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_POLL_TIMEOUT_MS;\n}\n\n// Date.now wrapped so the polling loop reads as intent, not arithmetic.\nfunction nowMs(): number {\n return Date.now();\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { AppRouteRouteModule } from \"next/dist/esm/server/route-modules/app-route/module.compiled\";\nimport { RouteKind } from \"next/dist/esm/server/route-kind\";\nimport { patchFetch as _patchFetch } from \"next/dist/esm/server/lib/patch-fetch\";\nimport { addRequestMeta, getRequestMeta, setRequestMeta } from \"next/dist/esm/server/request-meta\";\nimport { getTracer, SpanKind } from \"next/dist/esm/server/lib/trace/tracer\";\nimport { setManifestsSingleton } from \"next/dist/esm/server/app-render/manifests-singleton\";\nimport { normalizeAppPath } from \"next/dist/esm/shared/lib/router/utils/app-paths\";\nimport { NodeNextRequest, NodeNextResponse } from \"next/dist/esm/server/base-http/node\";\nimport { NextRequestAdapter, signalFromNodeResponse } from \"next/dist/esm/server/web/spec-extension/adapters/next-request\";\nimport { BaseServerSpan } from \"next/dist/esm/server/lib/trace/constants\";\nimport { getRevalidateReason } from \"next/dist/esm/server/instrumentation/utils\";\nimport { sendResponse } from \"next/dist/esm/server/send-response\";\nimport { fromNodeOutgoingHttpHeaders, toNodeOutgoingHttpHeaders } from \"next/dist/esm/server/web/utils\";\nimport { getCacheControlHeader } from \"next/dist/esm/server/lib/cache-control\";\nimport { INFINITE_CACHE, NEXT_CACHE_TAGS_HEADER } from \"next/dist/esm/lib/constants\";\nimport { NoFallbackError } from \"next/dist/esm/shared/lib/no-fallback-error.external\";\nimport { CachedRouteKind } from \"next/dist/esm/server/response-cache\";\nimport * as userland from \"INNER_APP_ROUTE\";\n// We inject the nextConfigOutput here so that we can use them in the route\n// module.\nconst nextConfigOutput = \"\"\nconst routeModule = new AppRouteRouteModule({\n definition: {\n kind: RouteKind.APP_ROUTE,\n page: \"/api/analyze/route\",\n pathname: \"/api/analyze\",\n filename: \"route\",\n bundlePath: \"\"\n },\n distDir: process.env.__NEXT_RELATIVE_DIST_DIR || '',\n relativeProjectDir: process.env.__NEXT_RELATIVE_PROJECT_DIR || '',\n resolvedPagePath: \"[project]/src/app/api/analyze/route.ts\",\n nextConfigOutput,\n // The static import is used for initialization (methods, dynamic, etc.).\n userland: userland,\n // In Turbopack dev mode, also provide a getter that calls require() on every\n // request. This re-reads from devModuleCache so HMR updates are picked up,\n // and the async wrapper unwraps async-module Promises (ESM-only\n // serverExternalPackages) automatically.\n ...process.env.TURBOPACK && process.env.__NEXT_DEV_SERVER ? {\n getUserland: ()=>import(\"INNER_APP_ROUTE\")\n } : {}\n});\n// Pull out the exports that we need to expose from the module. This should\n// be eliminated when we've moved the other routes to the new format. These\n// are used to hook into the route.\nconst { workAsyncStorage, workUnitAsyncStorage, serverHooks } = routeModule;\nfunction patchFetch() {\n return _patchFetch({\n workAsyncStorage,\n workUnitAsyncStorage\n });\n}\nexport { routeModule, workAsyncStorage, workUnitAsyncStorage, serverHooks, patchFetch, };\nexport async function handler(req, res, ctx) {\n if (ctx.requestMeta) {\n setRequestMeta(req, ctx.requestMeta);\n }\n if (routeModule.isDev) {\n addRequestMeta(req, 'devRequestTimingInternalsEnd', process.hrtime.bigint());\n }\n let srcPage = \"/api/analyze/route\";\n // turbopack doesn't normalize `/index` in the page name\n // so we need to to process dynamic routes properly\n // TODO: fix turbopack providing differing value from webpack\n if (process.env.TURBOPACK) {\n srcPage = srcPage.replace(/\\/index$/, '') || '/';\n } else if (srcPage === '/index') {\n // we always normalize /index specifically\n srcPage = '/';\n }\n const multiZoneDraftMode = process.env.__NEXT_MULTI_ZONE_DRAFT_MODE;\n const prepareResult = await routeModule.prepare(req, res, {\n srcPage,\n multiZoneDraftMode\n });\n if (!prepareResult) {\n res.statusCode = 400;\n res.end('Bad Request');\n ctx.waitUntil == null ? void 0 : ctx.waitUntil.call(ctx, Promise.resolve());\n return null;\n }\n const { buildId, deploymentId, params, nextConfig, parsedUrl, isDraftMode, prerenderManifest, routerServerContext, isOnDemandRevalidate, revalidateOnlyGenerated, resolvedPathname, clientReferenceManifest, serverActionsManifest } = prepareResult;\n const normalizedSrcPage = normalizeAppPath(srcPage);\n let isIsr = Boolean(prerenderManifest.dynamicRoutes[normalizedSrcPage] || prerenderManifest.routes[resolvedPathname]);\n const render404 = async ()=>{\n // TODO: should route-module itself handle rendering the 404\n if (routerServerContext == null ? void 0 : routerServerContext.render404) {\n await routerServerContext.render404(req, res, parsedUrl, false);\n } else {\n res.end('This page could not be found');\n }\n return null;\n };\n if (isIsr && !isDraftMode) {\n const isPrerendered = Boolean(prerenderManifest.routes[resolvedPathname]);\n const prerenderInfo = prerenderManifest.dynamicRoutes[normalizedSrcPage];\n if (prerenderInfo) {\n if (prerenderInfo.fallback === false && !isPrerendered) {\n if (nextConfig.adapterPath) {\n return await render404();\n }\n throw new NoFallbackError();\n }\n }\n }\n let cacheKey = null;\n if (isIsr && !routeModule.isDev && !isDraftMode) {\n cacheKey = resolvedPathname;\n // ensure /index and / is normalized to one key\n cacheKey = cacheKey === '/index' ? '/' : cacheKey;\n }\n const supportsDynamicResponse = // If we're in development, we always support dynamic HTML\n routeModule.isDev === true || // If this is not SSG or does not have static paths, then it supports\n // dynamic HTML.\n !isIsr;\n // This is a revalidation request if the request is for a static\n // page and it is not being resumed from a postponed render and\n // it is not a dynamic RSC request then it is a revalidation\n // request.\n const isStaticGeneration = isIsr && !supportsDynamicResponse;\n // Before rendering (which initializes component tree modules), we have to\n // set the reference manifests to our global store so Server Action's\n // encryption util can access to them at the top level of the page module.\n if (serverActionsManifest && clientReferenceManifest) {\n setManifestsSingleton({\n page: srcPage,\n clientReferenceManifest,\n serverActionsManifest\n });\n }\n const method = req.method || 'GET';\n const tracer = getTracer();\n const activeSpan = tracer.getActiveScopeSpan();\n const isWrappedByNextServer = Boolean(routerServerContext == null ? void 0 : routerServerContext.isWrappedByNextServer);\n const isMinimalMode = Boolean(getRequestMeta(req, 'minimalMode'));\n const incrementalCache = getRequestMeta(req, 'incrementalCache') || await routeModule.getIncrementalCache(req, nextConfig, prerenderManifest, isMinimalMode);\n incrementalCache == null ? void 0 : incrementalCache.resetRequestCache();\n globalThis.__incrementalCache = incrementalCache;\n const context = {\n params,\n previewProps: prerenderManifest.preview,\n renderOpts: {\n experimental: {\n authInterrupts: Boolean(nextConfig.experimental.authInterrupts)\n },\n cacheComponents: Boolean(nextConfig.cacheComponents),\n supportsDynamicResponse,\n incrementalCache,\n cacheLifeProfiles: nextConfig.cacheLife,\n waitUntil: ctx.waitUntil,\n onClose: (cb)=>{\n res.on('close', cb);\n },\n onAfterTaskError: undefined,\n onInstrumentationRequestError: (error, _request, errorContext, silenceLog)=>routeModule.onRequestError(req, error, errorContext, silenceLog, routerServerContext)\n },\n sharedContext: {\n buildId,\n deploymentId\n }\n };\n const nodeNextReq = new NodeNextRequest(req);\n const nodeNextRes = new NodeNextResponse(res);\n const nextReq = NextRequestAdapter.fromNodeNextRequest(nodeNextReq, signalFromNodeResponse(res));\n try {\n let parentSpan;\n const invokeRouteModule = async (span)=>{\n return routeModule.handle(nextReq, context).finally(()=>{\n if (!span) return;\n span.setAttributes({\n 'http.status_code': res.statusCode,\n 'next.rsc': false\n });\n const rootSpanAttributes = tracer.getRootSpanAttributes();\n // We were unable to get attributes, probably OTEL is not enabled\n if (!rootSpanAttributes) {\n return;\n }\n if (rootSpanAttributes.get('next.span_type') !== BaseServerSpan.handleRequest) {\n console.warn(`Unexpected root span type '${rootSpanAttributes.get('next.span_type')}'. Please report this Next.js issue https://github.com/vercel/next.js`);\n return;\n }\n const route = rootSpanAttributes.get('next.route');\n if (route) {\n const name = `${method} ${route}`;\n span.setAttributes({\n 'next.route': route,\n 'http.route': route,\n 'next.span_name': name\n });\n span.updateName(name);\n // Propagate http.route to the parent span if one exists (e.g.\n // a platform-created HTTP span in adapter deployments).\n if (parentSpan && parentSpan !== span) {\n parentSpan.setAttribute('http.route', route);\n parentSpan.updateName(name);\n }\n } else {\n span.updateName(`${method} ${srcPage}`);\n }\n });\n };\n const handleResponse = async (currentSpan)=>{\n var _cacheEntry_value;\n const responseGenerator = async ({ previousCacheEntry })=>{\n try {\n if (!isMinimalMode && isOnDemandRevalidate && revalidateOnlyGenerated && !previousCacheEntry) {\n res.statusCode = 404;\n // on-demand revalidate always sets this header\n res.setHeader('x-nextjs-cache', 'REVALIDATED');\n res.end('This page could not be found');\n return null;\n }\n const response = await invokeRouteModule(currentSpan);\n req.fetchMetrics = context.renderOpts.fetchMetrics;\n let pendingWaitUntil = context.renderOpts.pendingWaitUntil;\n // Attempt using provided waitUntil if available\n // if it's not we fallback to sendResponse's handling\n if (pendingWaitUntil) {\n if (ctx.waitUntil) {\n ctx.waitUntil(pendingWaitUntil);\n pendingWaitUntil = undefined;\n }\n }\n const cacheTags = context.renderOpts.collectedTags;\n // If the request is for a static response, we can cache it so long\n // as it's not edge.\n if (isIsr) {\n const blob = await response.blob();\n // Copy the headers from the response.\n const headers = toNodeOutgoingHttpHeaders(response.headers);\n if (cacheTags) {\n headers[NEXT_CACHE_TAGS_HEADER] = cacheTags;\n }\n if (!headers['content-type'] && blob.type) {\n headers['content-type'] = blob.type;\n }\n const revalidate = typeof context.renderOpts.collectedRevalidate === 'undefined' || context.renderOpts.collectedRevalidate >= INFINITE_CACHE ? false : context.renderOpts.collectedRevalidate;\n const expire = typeof context.renderOpts.collectedExpire === 'undefined' || context.renderOpts.collectedExpire >= INFINITE_CACHE ? undefined : context.renderOpts.collectedExpire;\n // Create the cache entry for the response.\n const cacheEntry = {\n value: {\n kind: CachedRouteKind.APP_ROUTE,\n status: response.status,\n body: Buffer.from(await blob.arrayBuffer()),\n headers\n },\n cacheControl: {\n revalidate,\n expire\n }\n };\n return cacheEntry;\n } else {\n // send response without caching if not ISR\n await sendResponse(nodeNextReq, nodeNextRes, response, context.renderOpts.pendingWaitUntil);\n return null;\n }\n } catch (err) {\n // if this is a background revalidate we need to report\n // the request error here as it won't be bubbled\n if (previousCacheEntry == null ? void 0 : previousCacheEntry.isStale) {\n const silenceLog = false;\n await routeModule.onRequestError(req, err, {\n routerKind: 'App Router',\n routePath: srcPage,\n routeType: 'route',\n revalidateReason: getRevalidateReason({\n isStaticGeneration,\n isOnDemandRevalidate\n })\n }, silenceLog, routerServerContext);\n }\n throw err;\n }\n };\n const cacheEntry = await routeModule.handleResponse({\n req,\n nextConfig,\n cacheKey,\n routeKind: RouteKind.APP_ROUTE,\n isFallback: false,\n prerenderManifest,\n isRoutePPREnabled: false,\n isOnDemandRevalidate,\n revalidateOnlyGenerated,\n responseGenerator,\n waitUntil: ctx.waitUntil,\n isMinimalMode\n });\n // we don't create a cacheEntry for ISR\n if (!isIsr) {\n return null;\n }\n if ((cacheEntry == null ? void 0 : (_cacheEntry_value = cacheEntry.value) == null ? void 0 : _cacheEntry_value.kind) !== CachedRouteKind.APP_ROUTE) {\n var _cacheEntry_value1;\n throw Object.defineProperty(new Error(`Invariant: app-route received invalid cache entry ${cacheEntry == null ? void 0 : (_cacheEntry_value1 = cacheEntry.value) == null ? void 0 : _cacheEntry_value1.kind}`), \"__NEXT_ERROR_CODE\", {\n value: \"E701\",\n enumerable: false,\n configurable: true\n });\n }\n if (!isMinimalMode) {\n res.setHeader('x-nextjs-cache', isOnDemandRevalidate ? 'REVALIDATED' : cacheEntry.isMiss ? 'MISS' : cacheEntry.isStale ? 'STALE' : 'HIT');\n }\n // Draft mode should never be cached\n if (isDraftMode) {\n res.setHeader('Cache-Control', 'private, no-cache, no-store, max-age=0, must-revalidate');\n }\n const headers = fromNodeOutgoingHttpHeaders(cacheEntry.value.headers);\n if (!(isMinimalMode && isIsr)) {\n headers.delete(NEXT_CACHE_TAGS_HEADER);\n }\n // If cache control is already set on the response we don't\n // override it to allow users to customize it via next.config\n if (cacheEntry.cacheControl && !res.getHeader('Cache-Control') && !headers.get('Cache-Control')) {\n headers.set('Cache-Control', getCacheControlHeader(cacheEntry.cacheControl));\n }\n await sendResponse(nodeNextReq, nodeNextRes, // @ts-expect-error - Argument of type 'Buffer<ArrayBufferLike>' is not assignable to parameter of type 'BodyInit | null | undefined'.\n new Response(cacheEntry.value.body, {\n headers,\n status: cacheEntry.value.status || 200\n }));\n return null;\n };\n // TODO: activeSpan code path is for when wrapped by\n // next-server can be removed when this is no longer used\n if (isWrappedByNextServer && activeSpan) {\n await handleResponse(activeSpan);\n } else {\n parentSpan = tracer.getActiveScopeSpan();\n await tracer.withPropagatedContext(req.headers, ()=>tracer.trace(BaseServerSpan.handleRequest, {\n spanName: `${method} ${srcPage}`,\n kind: SpanKind.SERVER,\n attributes: {\n 'http.method': method,\n 'http.target': req.url\n }\n }, handleResponse), undefined, !isWrappedByNextServer);\n }\n } catch (err) {\n if (!(err instanceof NoFallbackError)) {\n const silenceLog = false;\n await routeModule.onRequestError(req, err, {\n routerKind: 'App Router',\n routePath: normalizedSrcPage,\n routeType: 'route',\n revalidateReason: getRevalidateReason({\n isStaticGeneration,\n isOnDemandRevalidate\n })\n }, silenceLog, routerServerContext);\n }\n // rethrow so that we can handle serving error page\n // If this is during static generation, throw the error again.\n if (isIsr) throw err;\n // Otherwise, send a 500 response.\n await sendResponse(nodeNextReq, nodeNextRes, new Response(null, {\n status: 500\n }));\n return null;\n }\n}\n\n//# sourceMappingURL=app-route.js.map\n","import { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { getFfmpegPath } from \"./binary\";\n\n// Re-exported so this stage's consumers (analyze-long.ts) keep importing the\n// probe from here, while the implementation lives in one shared module rather\n// than being copied into each ffmpeg stage (TASK-23).\nexport { probeDurationSec } from \"./probe-duration\";\n\n/**\n * Segmenting a long recording for the Gemini File API (TASK-9).\n *\n * The Gemini File API rejects files past ~2 GB, so a recording that long is cut\n * into overlapping segments, each analyzed on its own (ARCHITECTURE §Recording\n * defaults — long recordings). This module owns ONLY the ffmpeg side: planning\n * where the cuts go and producing the segment files. The orchestration (upload\n * each segment, carry a running summary, remap timestamps back to the original)\n * lives in analyze-long.ts.\n *\n * Cutting is stream-copy (`-c copy`), not re-encode: the segments are throwaway\n * inputs for Gemini and are never the source of the final screenshots (those\n * come from the original recording in the glue command), so segment quality does\n * not matter and a slow VP9 re-encode would only cost time. Copy snaps the cut\n * to the nearest keyframe at or before the requested start, so a segment may\n * begin slightly earlier than its nominal start; we treat the NOMINAL start as\n * the offset, which keeps timestamp drift within the ±5–15 s ADR-002 already\n * tolerates, and the per-segment overlap absorbs anything lost at the seam.\n */\n\n/** One planned segment, in seconds against the ORIGINAL recording's timeline. */\nexport interface Segment {\n index: number; // 0-based\n startSec: number; // nominal start in the original recording (the remap offset)\n durationSec: number; // length of this segment\n}\n\nexport interface SegmentPlan {\n segments: Segment[];\n totalDurationSec: number;\n overlapSec: number;\n /** True when the file fit in one piece (segments.length === 1). */\n single: boolean;\n}\n\n/** Gemini File API hard limit; segment budget defaults a little under it. */\nconst GEMINI_FILE_LIMIT_BYTES = 2 * 1024 * 1024 * 1024; // 2 GB\nconst DEFAULT_MAX_SEGMENT_BYTES = Math.floor(1.8 * 1024 * 1024 * 1024); // ~1.8 GB\nconst DEFAULT_OVERLAP_SEC = 12; // within the 10–15 s window (ARCHITECTURE)\n\n/**\n * The byte budget per segment, also used by the glue command as the routing\n * threshold (a file over this is segmented). Configurable so segmentation can be\n * forced on a short clip in tests without a 1.8 h recording — set\n * VELLUM_SEGMENT_MAX_BYTES tiny and a 10 s clip splits into overlapping parts.\n */\nexport function maxSegmentBytes(): number {\n return readPositiveEnv(\"VELLUM_SEGMENT_MAX_BYTES\", DEFAULT_MAX_SEGMENT_BYTES);\n}\n\n/** Overlap between adjacent segments, in seconds. Configurable for the same tests. */\nexport function overlapSec(): number {\n return readPositiveEnv(\"VELLUM_SEGMENT_OVERLAP_SEC\", DEFAULT_OVERLAP_SEC);\n}\n\n/**\n * Plan the cuts. Segment length is derived from the file's MEASURED bitrate\n * (size / duration) so each segment lands under the byte budget regardless of\n * the actual encode. Segments advance by (segLen - overlap) and the last one\n * runs to the end. A file that already fits yields a single segment spanning the\n * whole recording (so analyzeLong on a small file behaves like analyze).\n */\nexport function planSegments(\n fileSizeBytes: number,\n totalDurationSec: number,\n opts?: { maxBytes?: number; overlap?: number },\n): SegmentPlan {\n if (!(totalDurationSec > 0)) {\n throw new Error(\n `Cannot plan segments: video duration is ${totalDurationSec}s. ffmpeg could not read a usable Duration from the file.`,\n );\n }\n\n const maxBytes = opts?.maxBytes ?? maxSegmentBytes();\n const overlap = opts?.overlap ?? overlapSec();\n const bytesPerSec = fileSizeBytes / totalDurationSec;\n\n // Seconds of video that fit in the budget at the measured bitrate, capped at\n // the whole recording. Math.max(1, …) guards a pathological tiny budget so\n // segLen never collapses to 0.\n const segLenForBudget = Math.max(1, Math.floor(maxBytes / bytesPerSec));\n const segLen = Math.min(segLenForBudget, totalDurationSec);\n\n // Overlap must leave a positive forward step, else segments never advance.\n if (overlap >= segLen) {\n throw new Error(\n `Overlap (${overlap}s) must be smaller than the segment length (${segLen}s). ` +\n `Lower VELLUM_SEGMENT_OVERLAP_SEC or raise VELLUM_SEGMENT_MAX_BYTES.`,\n );\n }\n const step = segLen - overlap;\n\n const segments: Segment[] = [];\n let index = 0;\n for (let start = 0; ; start += step) {\n const durationSec = Math.min(segLen, totalDurationSec - start);\n segments.push({ index: index++, startSec: start, durationSec });\n // Stop once this segment already reaches the end of the recording.\n if (start + segLen >= totalDurationSec) break;\n }\n\n return {\n segments,\n totalDurationSec,\n overlapSec: overlap,\n single: segments.length === 1,\n };\n}\n\n/**\n * Cut one segment to `outPath` (a .webm) via stream-copy. `-ss` before `-i` is a\n * fast keyframe seek; `-avoid_negative_ts make_zero` rebases the output to start\n * at ~0 so Gemini reads the segment as a 0-based video and emits local \"mm:ss\".\n */\nexport function cutSegment(\n videoPath: string,\n segment: Segment,\n outPath: string,\n): Promise<void> {\n const ffmpeg = getFfmpegPath();\n const args = [\n \"-nostdin\",\n \"-y\",\n \"-ss\",\n segment.startSec.toFixed(3),\n \"-i\",\n videoPath,\n \"-t\",\n segment.durationSec.toFixed(3),\n \"-c\",\n \"copy\",\n \"-avoid_negative_ts\",\n \"make_zero\",\n outPath,\n ];\n return new Promise((resolve, reject) => {\n const proc = spawn(ffmpeg, args, { stdio: [\"ignore\", \"ignore\", \"pipe\"] });\n let stderr = \"\";\n proc.stderr.on(\"data\", (chunk) => {\n stderr += chunk.toString();\n });\n proc.on(\"error\", reject);\n proc.on(\"close\", (code) => {\n if (code === 0 && existsSync(outPath)) {\n resolve();\n return;\n }\n reject(\n new Error(\n `ffmpeg failed to cut segment ${segment.index} ` +\n `(${segment.startSec}s +${segment.durationSec}s, exit ${code}).\\n${tail(stderr)}`,\n ),\n );\n });\n });\n}\n\n/** Warn (don't fail) if a misconfigured budget could exceed Gemini's hard limit. */\nexport function budgetExceedsGeminiLimit(maxBytes: number): boolean {\n return maxBytes > GEMINI_FILE_LIMIT_BYTES;\n}\n\nfunction readPositiveEnv(name: string, fallback: number): number {\n const raw = process.env[name];\n if (!raw) return fallback;\n const parsed = Number(raw);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;\n}\n\nfunction tail(text: string, lines = 8): string {\n return text.trim().split(\"\\n\").slice(-lines).join(\"\\n\");\n}\n","import ffmpegStatic from \"ffmpeg-static\";\nimport { existsSync } from \"node:fs\";\n\nexport function getFfmpegPath(): string {\n const p = ffmpegStatic;\n if (!p || !existsSync(p)) {\n throw new Error(\n \"ffmpeg-static binary not found. Run: npm install ffmpeg-static\",\n );\n }\n return p;\n}\n","import { mkdtemp, rm } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { stat } from \"node:fs/promises\";\nimport { uploadVideo } from \"./upload\";\nimport { analyzeSegment, buildRun, type GeminiCall } from \"./analyze\";\nimport {\n mmssToSec,\n secToMmss,\n type AnalysisLanguage,\n type AnalysisMode,\n type AnalysisResult,\n type ReviewType,\n type VellumTask,\n} from \"./schema\";\nimport {\n budgetExceedsGeminiLimit,\n cutSegment,\n maxSegmentBytes,\n planSegments,\n probeDurationSec,\n type Segment,\n type SegmentPlan,\n} from \"../ffmpeg/segment-video\";\n\n/**\n * Stage 2-long of the Phase 1 pipeline (ARCHITECTURE §Pipeline contracts):\n *\n * analyzeLong(videoPath): Promise<AnalysisResult>\n *\n * Same OUTPUT contract as analyze(); segmentation and global-timestamp remapping\n * are hidden behind this boundary. Note the input differs from analyze(): this\n * takes a LOCAL videoPath (not a fileUri), because it must cut the file locally\n * before uploading each segment.\n *\n * What it does (ARCHITECTURE §Recording defaults — long recordings):\n * 1. Probe duration, plan overlapping segments under the byte budget.\n * 2. For each segment, in order: cut it (stream-copy), upload it, analyze it\n * seeded with a running summary of everything earlier segments established.\n * 3. Shift each segment's LOCAL \"mm:ss\" timestamps to the ORIGINAL recording's\n * timeline (offset = segment start), dropping overlap-zone duplicates.\n * 4. Merge into one AnalysisResult.\n *\n * Segmentation is a NORMAL path, not an error state (AC#4): a long recording is\n * expected here and is logged as routine progress, never thrown.\n *\n * Logging: this is a multi-minute operation with real sub-steps, so it prints\n * progress (like uploadVideo's dots), matching the glue command's plain-stdout\n * style so the segmentation + remap are visible in a run.\n */\nexport async function analyzeLong(\n videoPath: string,\n // TASK-46 — threaded per-segment: in \"economy\" each segment is a single\n // combined call. Default \"thorough\" keeps the long path byte-identical.\n mode: AnalysisMode = \"thorough\",\n // TASK-49 — output language, threaded into every segment's prompts and the\n // merged run block. \"en\" (default) keeps the long path byte-identical.\n language: AnalysisLanguage = \"en\",\n // TASK-50 — the chosen PRIMARY model, threaded into every segment so an\n // override applies to long recordings too. undefined → the built-in MODEL\n // (unchanged behavior).\n model?: string,\n // TASK-60 — the re-run-with-video revise context (prior tasks + comments),\n // prepended to every segment's prompt so the reviewer's feedback grounds the\n // whole recording. undefined for a plain analysis (byte-identical to before).\n reviseContext?: string,\n): Promise<AnalysisResult> {\n const { size } = await stat(videoPath);\n\n const maxBytes = maxSegmentBytes();\n if (budgetExceedsGeminiLimit(maxBytes)) {\n // Not fatal — segments could still come in under 2 GB — but warn loudly:\n // a budget over the hard limit risks a segment Gemini will reject.\n console.warn(\n ` ! VELLUM_SEGMENT_MAX_BYTES is above Gemini's 2 GB limit; segments may be rejected.`,\n );\n }\n\n const duration = await probeDurationSec(videoPath);\n if (duration === null) {\n throw new Error(\n `Could not read the duration of \"${videoPath}\" (ffmpeg printed no Duration line). ` +\n `The file may be corrupt or an unsupported container.`,\n );\n }\n\n const plan = planSegments(size, duration, { maxBytes });\n logPlan(plan, size, maxBytes);\n\n const tmpDir = await mkdtemp(path.join(tmpdir(), \"vellum-seg-\"));\n try {\n return await analyzePlan(videoPath, plan, tmpDir, mode, language, model, reviseContext);\n } finally {\n // Segments are throwaway; clean them up regardless of success or failure.\n await rm(tmpDir, { recursive: true, force: true });\n }\n}\n\n/** Run every planned segment in order, threading the running summary forward. */\nasync function analyzePlan(\n videoPath: string,\n plan: SegmentPlan,\n tmpDir: string,\n mode: AnalysisMode,\n language: AnalysisLanguage,\n model: string | undefined,\n reviseContext: string | undefined,\n): Promise<AnalysisResult> {\n const captured: VellumTask[] = [];\n const reviewTypes: ReviewType[] = [];\n // TASK-45 — every segment's Gemini calls, accumulated so the whole recording's\n // token usage + cost is summed into one `run` block on the merged result.\n const calls: GeminiCall[] = [];\n let firstOverview = \"\";\n // The whole recording gets ONE name; segment 0 saw the opening, so its\n // suggested_name is the most representative (TASK-22). undefined → the\n // timestamp folder name is the fallback downstream.\n let firstSuggestedName: string | undefined;\n\n for (const segment of plan.segments) {\n const label = `[segment ${segment.index + 1}/${plan.segments.length}]`;\n console.log(\n `\\n ${label} ${secToMmss(segment.startSec)}–` +\n `${secToMmss(segment.startSec + segment.durationSec)} of the original …`,\n );\n\n // 1. Cut this segment out of the original (stream-copy, throwaway file).\n const segPath = path.join(tmpDir, `segment-${segment.index}.webm`);\n await cutSegment(videoPath, segment, segPath);\n\n // 2. Upload it (uploadVideo validates + waits for ACTIVE, same as the short path).\n process.stdout.write(` uploading `);\n const { fileUri } = await uploadVideo(segPath);\n console.log(` ✓`);\n\n // 3. Analyze it, seeded with what earlier segments established. Segment 0 has\n // no running summary yet; later segments carry one. TASK-60: when this is a\n // re-run-with-video, the revise context prepends to whatever's there (and\n // is the sole context for segment 0), so the feedback grounds every segment.\n const runningSummary =\n segment.index === 0\n ? undefined\n : buildRunningSummary(firstOverview, captured, plan.overlapSec);\n const priorContext = prependContext(reviseContext, runningSummary);\n const { result: segResult, calls: segCalls } = await analyzeSegment(\n fileUri,\n priorContext,\n undefined, // mimeType — segments are always re-encoded WebM (the default).\n undefined, // signal — analyzeLong doesn't forward abort yet (see route.ts).\n mode,\n language,\n model,\n );\n calls.push(...segCalls);\n\n if (segment.index === 0) {\n firstOverview = segResult.overview;\n firstSuggestedName = segResult.suggested_name;\n }\n reviewTypes.push(segResult.review_type);\n\n // 4. Shift local timestamps onto the original timeline, drop overlap dupes.\n const remapped = remapTasks(segResult.tasks, segment);\n let added = 0;\n for (const task of remapped) {\n if (!isDuplicate(task, captured, plan.overlapSec)) {\n captured.push(task);\n added += 1;\n }\n }\n console.log(\n ` ${segResult.tasks.length} task(s) found, ${added} new after overlap dedup`,\n );\n }\n\n // Chronological by global timestamp (segments already run in order, but dedup\n // and within-segment ordering can leave minor gaps — sort to be safe).\n captured.sort((a, b) => mmssToSec(a.timestamp) - mmssToSec(b.timestamp));\n\n return {\n review_type: majorityReviewType(reviewTypes),\n overview: firstOverview,\n suggested_name: firstSuggestedName,\n tasks: captured,\n // One run block for the whole recording: usage summed across every segment's\n // calls (TASK-45), recording the real mode (TASK-46) + language (TASK-49).\n run: buildRun(calls, mode, language),\n };\n}\n\n/**\n * Shift one segment's LOCAL timestamps to the ORIGINAL recording's timeline.\n * A local second is clamped into [0, durationSec] first, so a Gemini timestamp\n * that drifts past the segment's end never maps beyond the segment's real span\n * (the screenshot stage clamps again against the full recording's true end).\n */\n/**\n * Prepend the TASK-60 revise context (if any) to a segment's running summary.\n * With no revise context the summary is returned untouched (plain long-video path,\n * byte-identical to before). With no summary (segment 0) the revise context alone\n * is the context. Same \"---\" separator withContext uses, so the prompt reads\n * consistently whichever pieces are present.\n */\nfunction prependContext(\n reviseContext: string | undefined,\n summary: string | undefined,\n): string | undefined {\n if (!reviseContext) return summary;\n if (!summary) return reviseContext;\n return `${reviseContext}\\n\\n---\\n\\n${summary}`;\n}\n\n// Exported (with buildRunningSummary below) so the two pieces of pure TASK-9\n// logic — remap and the running summary — can be exercised deterministically\n// without a Gemini call, since a synthetic test clip yields no real tasks.\nexport function remapTasks(tasks: VellumTask[], segment: Segment): VellumTask[] {\n const toGlobal = (mmss: string): string => {\n const local = Math.min(Math.max(mmssToSec(mmss), 0), segment.durationSec);\n return secToMmss(local + segment.startSec);\n };\n return tasks.map((task) => ({\n ...task,\n timestamp: toGlobal(task.timestamp),\n screenshot_timestamp: toGlobal(task.screenshot_timestamp),\n }));\n}\n\n/**\n * The running summary carried into the NEXT segment (local synthesis — no extra\n * Gemini call). It tells the model what's already established and, crucially,\n * that this video is one segment of a larger recording whose first seconds\n * overlap the previous one, so it should not re-report items already captured\n * and should emit timestamps local to its own 0-based clip.\n */\nexport function buildRunningSummary(\n overview: string,\n captured: VellumTask[],\n overlap: number,\n): string {\n // Cap the carried list so a very long recording doesn't grow the prompt\n // unbounded; the most recent items are the ones the overlap could duplicate.\n const recent = captured.slice(-40);\n const lines = [\n \"CONTEXT FROM EARLIER SEGMENTS OF THIS RECORDING (background — already analyzed, do not redo):\",\n `Overview so far: ${overview}`,\n \"\",\n \"Items already captured (timestamps are in the FULL original recording):\",\n ...recent.map((t) => `- [${t.timestamp}] ${t.title} (${t.category})`),\n \"\",\n \"IMPORTANT: The video below is ONE SEGMENT of a longer recording, not the whole\",\n `thing. Its first ~${overlap}s overlap the end of the previous segment. Do NOT`,\n \"re-report any item already listed above. Emit timestamps LOCAL to the video\",\n \"below, starting at 00:00 — the segments are stitched back together afterwards.\",\n ];\n if (recent.length === 0) {\n // Defensive: earlier segments found nothing actionable. Keep the framing.\n lines.splice(3, 1, \"(no actionable items captured yet)\");\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Two segments share an overlap window, so the same item can surface in both.\n * Treat a task as a duplicate when an already-captured task has the same title\n * (normalized) AND a global timestamp within the overlap window (plus a small\n * margin for the ±5–15 s timestamp drift ADR-002 tolerates). The prompt already\n * asks the model not to repeat itself; this is the safety net.\n */\nfunction isDuplicate(\n task: VellumTask,\n captured: VellumTask[],\n overlap: number,\n): boolean {\n const title = normalizeTitle(task.title);\n const sec = mmssToSec(task.timestamp);\n const window = overlap + 15; // overlap zone plus ADR-002 drift margin\n return captured.some(\n (c) =>\n normalizeTitle(c.title) === title &&\n Math.abs(mmssToSec(c.timestamp) - sec) <= window,\n );\n}\n\nfunction normalizeTitle(title: string): string {\n return title.trim().toLowerCase().replace(/\\s+/g, \" \");\n}\n\n/** Most common review_type across segments; ties resolve to the first segment's. */\nfunction majorityReviewType(types: ReviewType[]): ReviewType {\n const counts = new Map<ReviewType, number>();\n for (const t of types) counts.set(t, (counts.get(t) ?? 0) + 1);\n let best = types[0];\n let bestCount = 0;\n // Iterate types in segment order so the first segment wins any tie.\n for (const t of types) {\n const c = counts.get(t)!;\n if (c > bestCount) {\n best = t;\n bestCount = c;\n }\n }\n return best;\n}\n\nfunction logPlan(plan: SegmentPlan, sizeBytes: number, maxBytes: number): void {\n const gb = (sizeBytes / 1024 / 1024 / 1024).toFixed(2);\n const budgetMb = (maxBytes / 1024 / 1024).toFixed(0);\n console.log(\n ` Long recording: ${gb} GB over the ${budgetMb} MB segment budget — ` +\n `splitting into ${plan.segments.length} segment(s) ` +\n `(~${plan.overlapSec}s overlap). This is the normal path for long videos.`,\n );\n}\n","import { spawn } from \"node:child_process\";\nimport { mkdir } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { getFfmpegPath } from \"./binary\";\nimport { probeDurationSec } from \"./probe-duration\";\n\n/**\n * Extract one PNG frame per requested timestamp from a video.\n *\n * Timestamps are in SECONDS — the glue layer (TASK-8) converts the Gemini\n * \"mm:ss\" strings to seconds before calling this (ARCHITECTURE §Pipeline\n * contracts). Output is PNG at the source (recording) resolution — no scaling —\n * for sharp UI edges (ARCHITECTURE §Screenshot strategy). We spawn the\n * ffmpeg-static binary directly, one short subprocess per frame, with no\n * wrapper library (CLAUDE.md §ffmpeg-static).\n *\n * Out-of-range timestamps are clamped into the video, not treated as errors:\n * a slightly-off Gemini timestamp past the end still yields the last usable\n * frame rather than crashing the pipeline (CLAUDE.md ambiguity example, AC#4).\n *\n * @returns absolute paths of the generated PNGs, parallel to `timestampsSec`.\n */\nexport async function extractScreenshots(\n videoPath: string,\n timestampsSec: number[],\n outDir: string,\n): Promise<string[]> {\n if (!existsSync(videoPath)) {\n throw new Error(`Video not found: ${videoPath}`);\n }\n await mkdir(outDir, { recursive: true });\n\n const ffmpeg = getFfmpegPath();\n const durationSec = await probeDurationSec(videoPath);\n\n // Resolve every requested timestamp to a clamped seek point and a\n // collision-free filename up front, so parallel jobs never race over a name.\n const usedNames = new Set<string>();\n const jobs = timestampsSec.map((requested) => {\n const seekSec = clampToRange(requested, durationSec);\n const fileName = uniqueName(secondsToName(seekSec), usedNames);\n return { seekSec, outPath: path.resolve(outDir, fileName) };\n });\n\n // Bounded concurrency: a handful of short ffmpeg processes at a time keeps\n // 10+ timestamps fast without spawning an unbounded swarm.\n const CONCURRENCY = 4;\n const results: string[] = new Array(jobs.length);\n for (let i = 0; i < jobs.length; i += CONCURRENCY) {\n const batch = jobs.slice(i, i + CONCURRENCY);\n await Promise.all(\n batch.map(async (job, j) => {\n await extractOne(ffmpeg, videoPath, job.seekSec, job.outPath);\n results[i + j] = job.outPath;\n }),\n );\n }\n return results;\n}\n\n/** Clamp a requested second into [0, duration); never seek past the end. */\nfunction clampToRange(seconds: number, durationSec: number | null): number {\n if (!Number.isFinite(seconds) || seconds < 0) return 0;\n if (durationSec !== null && seconds >= durationSec) {\n // Step just inside the last frame instead of seeking past the end.\n return Math.max(0, durationSec - 0.1);\n }\n return seconds;\n}\n\n/** \"frame-MM-SS.png\", zero-padded (e.g. 72.4s -> \"frame-01-12.png\"). */\nfunction secondsToName(seconds: number): string {\n const total = Math.floor(seconds);\n const mm = String(Math.floor(total / 60)).padStart(2, \"0\");\n const ss = String(total % 60).padStart(2, \"0\");\n return `frame-${mm}-${ss}.png`;\n}\n\n/** Two timestamps in the same second would collide — suffix the later one. */\nfunction uniqueName(base: string, used: Set<string>): string {\n if (!used.has(base)) {\n used.add(base);\n return base;\n }\n const stem = base.replace(/\\.png$/, \"\");\n let n = 2;\n while (used.has(`${stem}-${n}.png`)) n += 1;\n const candidate = `${stem}-${n}.png`;\n used.add(candidate);\n return candidate;\n}\n\n/** Extract a single frame at `seekSec` to `outPath` as PNG. */\nfunction extractOne(\n ffmpeg: string,\n videoPath: string,\n seekSec: number,\n outPath: string,\n): Promise<void> {\n // Input-side -ss (before -i) = fast keyframe seek then decode to the exact\n // timestamp; accurate to well within the 0.5s budget. No -vf scale, so the\n // PNG stays at the source (recording) resolution.\n const args = [\n \"-nostdin\",\n \"-y\",\n \"-ss\",\n seekSec.toFixed(3),\n \"-i\",\n videoPath,\n \"-frames:v\",\n \"1\",\n \"-update\",\n \"1\",\n outPath,\n ];\n return new Promise((resolve, reject) => {\n const proc = spawn(ffmpeg, args, { stdio: [\"ignore\", \"ignore\", \"pipe\"] });\n let stderr = \"\";\n proc.stderr.on(\"data\", (chunk) => {\n stderr += chunk.toString();\n });\n proc.on(\"error\", reject);\n proc.on(\"close\", (code) => {\n if (code === 0 && existsSync(outPath)) {\n resolve();\n return;\n }\n reject(\n new Error(\n `ffmpeg failed to extract frame at ${seekSec}s (exit ${code}).\\n${tail(stderr)}`,\n ),\n );\n });\n });\n}\n\n/** Last few lines of ffmpeg stderr — enough to diagnose, not a wall of text. */\nfunction tail(text: string, lines = 8): string {\n return text.trim().split(\"\\n\").slice(-lines).join(\"\\n\");\n}\n","import { spawn } from \"node:child_process\";\nimport { getFfmpegPath } from \"./binary\";\n\n/**\n * Read a recording's duration in seconds, or null if it genuinely can't be read.\n *\n * ffmpeg-static bundles no ffprobe, so we lean on ffmpeg itself. Two strategies,\n * fast one first:\n *\n * 1. Banner probe — `ffmpeg -i <file>` (no output) exits non-zero but prints a\n * \"Duration: HH:MM:SS.ms\" line. Instant. This is all a re-encoded file (one\n * ffmpeg wrote) needs.\n *\n * 2. Decode-the-length fallback — MediaRecorder WebM has NO duration header, so\n * the banner shows \"Duration: N/A\" and step 1 finds nothing (TASK-23). We\n * then REMUX the file to the null muxer with `-c copy -f null -`: ffmpeg\n * walks every packet and reports the last one's timestamp as `time=...`,\n * which IS the duration. `-c copy` means demux-only (no VP9 decode), so this\n * stays near-instant even on a 1.8 h recording — measured ~30 ms on a 17 s\n * clip, and it does NOT grow with pixel count the way a full decode would.\n *\n * Used by both the screenshot stage (to clamp past-end Gemini timestamps) and the\n * segmentation stage (to plan cuts), so it lives in its own module rather than\n * being copied into each (it previously was, and only one copy would have been\n * fixed). The banner-vs-N/A difference is exactly why the calendar test file\n * worked before this fix and a raw recorder file did not: the former had been\n * re-encoded by ffmpeg (header written), the latter came straight from\n * MediaRecorder (no header).\n */\nexport function probeDurationSec(videoPath: string): Promise<number | null> {\n return new Promise((resolve) => {\n runFfmpegStderr([\"-nostdin\", \"-i\", videoPath]).then((stderr) => {\n const fromBanner = parseDurationLine(stderr);\n if (fromBanner !== null) {\n resolve(fromBanner);\n return;\n }\n // No usable \"Duration:\" line (header-less recorder WebM) — decode the\n // real length by remuxing to null and reading the final packet time.\n runFfmpegStderr([\"-nostdin\", \"-i\", videoPath, \"-c\", \"copy\", \"-f\", \"null\", \"-\"])\n .then((decodeStderr) => resolve(parseLastProgressTime(decodeStderr)))\n .catch(() => resolve(null));\n }, () => resolve(null));\n });\n}\n\n/** Spawn ffmpeg and resolve with its full stderr (it exits non-zero here — fine). */\nfunction runFfmpegStderr(args: string[]): Promise<string> {\n const ffmpeg = getFfmpegPath();\n return new Promise((resolve, reject) => {\n const proc = spawn(ffmpeg, args, { stdio: [\"ignore\", \"ignore\", \"pipe\"] });\n let stderr = \"\";\n proc.stderr.on(\"data\", (chunk) => {\n stderr += chunk.toString();\n });\n proc.on(\"error\", reject);\n proc.on(\"close\", () => resolve(stderr));\n });\n}\n\n/** \"Duration: HH:MM:SS.ms\" from the banner. null if absent or \"Duration: N/A\". */\nfunction parseDurationLine(stderr: string): number | null {\n const m = stderr.match(/Duration:\\s*(\\d+):(\\d+):(\\d+(?:\\.\\d+)?)/);\n if (!m) return null;\n return Number(m[1]) * 3600 + Number(m[2]) * 60 + Number(m[3]);\n}\n\n/**\n * The LAST \"time=HH:MM:SS.ms\" ffmpeg prints while processing — the end of the\n * file when remuxing to null. ffmpeg emits this repeatedly as it advances, so we\n * take the final match. Early frames can momentarily print \"time=N/A\" or a\n * negative value before timestamps settle; the global scan + \"take last\" skips\n * those, and a never-positive result resolves to null rather than 0.\n */\nfunction parseLastProgressTime(stderr: string): number | null {\n const matches = [...stderr.matchAll(/time=\\s*(\\d+):(\\d+):(\\d+(?:\\.\\d+)?)/g)];\n if (matches.length === 0) return null;\n const m = matches[matches.length - 1];\n const seconds = Number(m[1]) * 3600 + Number(m[2]) * 60 + Number(m[3]);\n return seconds > 0 ? seconds : null;\n}\n"],"names":["MAX_FILE_BYTES","SUPPORTED_EXTENSIONS","videoPath","POLL_INTERVAL_MS","DEFAULT_POLL_TIMEOUT_MS","uploadWithOneRetry","name","UploadError","Error","kind","active","message","makeClient","uri","pollUntilActive","ai","includes","ext","uploadVideo","validateFile","file","fileUri","size","apiKey","stats","toFixed","isFile","toLowerCase","err","env","join","trim","messageOf","gb","upload","FAILED","retryErr","process","GEMINI_API_KEY","error","Math","isAuthError","timeoutMs","deadline","msg","files","authGuidance","isNetworkTimeout","console","fileName","pollTimeoutMs","nowMs","get","state","ACTIVE","parse","mins","round","raw","parsed","stdout","write","sleep","ms","code","status","Number","Date","String","JSON","GEMINI_UPLOAD_TIMEOUT_MS","isFinite","now","Promise","resolve","setTimeout"],"mappings":"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","ignoreList":[2]}
@@ -1,3 +0,0 @@
1
- module.exports=[93695,(e,t,r)=>{t.exports=e.x("next/dist/shared/lib/no-fallback-error.external.js",()=>require("next/dist/shared/lib/no-fallback-error.external.js"))},18622,(e,t,r)=>{t.exports=e.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},56704,(e,t,r)=>{t.exports=e.x("next/dist/server/app-render/work-async-storage.external.js",()=>require("next/dist/server/app-render/work-async-storage.external.js"))},32319,(e,t,r)=>{t.exports=e.x("next/dist/server/app-render/work-unit-async-storage.external.js",()=>require("next/dist/server/app-render/work-unit-async-storage.external.js"))},24725,(e,t,r)=>{t.exports=e.x("next/dist/server/app-render/after-task-async-storage.external.js",()=>require("next/dist/server/app-render/after-task-async-storage.external.js"))},70406,(e,t,r)=>{t.exports=e.x("next/dist/compiled/@opentelemetry/api",()=>require("next/dist/compiled/@opentelemetry/api"))},13571,e=>{"use strict";let t={"gemini-2.5-pro":{input:{threshold:2e5,below:1.25,above:2.5},output:{threshold:2e5,below:10,above:15}},"gemini-2.5-flash":{input:.3,output:2.5},"gemini-2.5-flash-lite":{input:.1,output:.4}};function r(){let e=process.env.GEMINI_PRICING?.trim();if(!e)return t;try{let r=JSON.parse(e);return{...t,...r}}catch{return console.warn("[pricing] GEMINI_PRICING is not valid JSON — using built-in prices."),t}}function n(e,t){return"number"==typeof e?e:t>e.threshold?e.above:e.below}function a(e){return"number"==typeof e?e:e.below}e.s(["basePrice",0,function(e){let t=r()[e];if(t)return{input:a(t.input),output:a(t.output)}},"costUsd",0,function(e,t,a,i){let s=r()[e];if(s)return t/1e6*n(s.input,i)+a/1e6*n(s.output,i)}])},55863,e=>{"use strict";var t=e.i(47909),r=e.i(74017),n=e.i(96250),a=e.i(59756),i=e.i(61916),s=e.i(74677),o=e.i(69741),l=e.i(16795),u=e.i(87718),d=e.i(95169),p=e.i(47587),c=e.i(66012),h=e.i(70101),m=e.i(74838),f=e.i(10372),g=e.i(93695);e.i(52474);var x=e.i(220),v=e.i(89171),R=e.i(13571);let w=new Set(["gemini-2.5-pro","gemini-2.5-flash","gemini-2.5-flash-lite"]),E=["image","tts","embedding","aqa","imagen"];async function y(){let e,t=process.env.GEMINI_API_KEY?.trim();if(!t)return v.NextResponse.json({error:"No Gemini API key is configured. Add GEMINI_API_KEY to .env.local."},{status:400});try{e=await b(t)}catch(e){return console.error("[models] failed to list Gemini models:",e),v.NextResponse.json({error:"Couldn't load the model list from Gemini. Check the API key and try again."},{status:502})}let r=e.filter(C).map(N).filter(e=>null!==e);return v.NextResponse.json({models:r})}async function b(e){let t,r=[];for(let n=0;n<5;n++){let n=new URL("https://generativelanguage.googleapis.com/v1beta/models");n.searchParams.set("key",e),n.searchParams.set("pageSize","1000"),t&&n.searchParams.set("pageToken",t);let a=await fetch(n,{cache:"no-store"});if(!a.ok)throw Error(`models.list responded ${a.status} ${a.statusText}`);let i=await a.json();if(i.models&&r.push(...i.models),!i.nextPageToken)break;t=i.nextPageToken}return r}function C(e){if(!e.supportedGenerationMethods?.includes("generateContent"))return!1;let t=P(e.name);return!E.some(e=>t.includes(e))}function N(e){let t=P(e.name);if(!t)return null;let r=(0,R.basePrice)(t);return{id:t,displayName:e.displayName?.trim()||t,recommended:w.has(t),preview:t.includes("preview"),...r?{inputPrice:r.input,outputPrice:r.output}:{}}}function P(e){return(e??"").replace(/^models\//,"").trim().toLowerCase()}e.s(["GET",0,y,"runtime",0,"nodejs"],37381);var A=e.i(37381);let I=new t.AppRouteRouteModule({definition:{kind:r.RouteKind.APP_ROUTE,page:"/api/models/route",pathname:"/api/models",filename:"route",bundlePath:""},distDir:".next",relativeProjectDir:"",resolvedPagePath:"[project]/src/app/api/models/route.ts",nextConfigOutput:"",userland:A,...{}}),{workAsyncStorage:k,workUnitAsyncStorage:T,serverHooks:_}=I;async function S(e,t,n){n.requestMeta&&(0,a.setRequestMeta)(e,n.requestMeta),I.isDev&&(0,a.addRequestMeta)(e,"devRequestTimingInternalsEnd",process.hrtime.bigint());let v="/api/models/route";v=v.replace(/\/index$/,"")||"/";let R=await I.prepare(e,t,{srcPage:v,multiZoneDraftMode:!1});if(!R)return t.statusCode=400,t.end("Bad Request"),null==n.waitUntil||n.waitUntil.call(n,Promise.resolve()),null;let{buildId:w,deploymentId:E,params:y,nextConfig:b,parsedUrl:C,isDraftMode:N,prerenderManifest:P,routerServerContext:A,isOnDemandRevalidate:k,revalidateOnlyGenerated:T,resolvedPathname:_,clientReferenceManifest:S,serverActionsManifest:q}=R,O=(0,o.normalizeAppPath)(v),j=!!(P.dynamicRoutes[O]||P.routes[_]),M=async()=>((null==A?void 0:A.render404)?await A.render404(e,t,C,!1):t.end("This page could not be found"),null);if(j&&!N){let e=!!P.routes[_],t=P.dynamicRoutes[O];if(t&&!1===t.fallback&&!e){if(b.adapterPath)return await M();throw new g.NoFallbackError}}let U=null;!j||I.isDev||N||(U="/index"===(U=_)?"/":U);let H=!0===I.isDev||!j,G=j&&!H;q&&S&&(0,s.setManifestsSingleton)({page:v,clientReferenceManifest:S,serverActionsManifest:q});let D=e.method||"GET",$=(0,i.getTracer)(),K=$.getActiveScopeSpan(),F=!!(null==A?void 0:A.isWrappedByNextServer),L=!!(0,a.getRequestMeta)(e,"minimalMode"),B=(0,a.getRequestMeta)(e,"incrementalCache")||await I.getIncrementalCache(e,b,P,L);null==B||B.resetRequestCache(),globalThis.__incrementalCache=B;let V={params:y,previewProps:P.preview,renderOpts:{experimental:{authInterrupts:!!b.experimental.authInterrupts},cacheComponents:!!b.cacheComponents,supportsDynamicResponse:H,incrementalCache:B,cacheLifeProfiles:b.cacheLife,waitUntil:n.waitUntil,onClose:e=>{t.on("close",e)},onAfterTaskError:void 0,onInstrumentationRequestError:(t,r,n,a)=>I.onRequestError(e,t,n,a,A)},sharedContext:{buildId:w,deploymentId:E}},W=new l.NodeNextRequest(e),X=new l.NodeNextResponse(t),z=u.NextRequestAdapter.fromNodeNextRequest(W,(0,u.signalFromNodeResponse)(t));try{let a,s=async e=>I.handle(z,V).finally(()=>{if(!e)return;e.setAttributes({"http.status_code":t.statusCode,"next.rsc":!1});let r=$.getRootSpanAttributes();if(!r)return;if(r.get("next.span_type")!==d.BaseServerSpan.handleRequest)return void console.warn(`Unexpected root span type '${r.get("next.span_type")}'. Please report this Next.js issue https://github.com/vercel/next.js`);let n=r.get("next.route");if(n){let t=`${D} ${n}`;e.setAttributes({"next.route":n,"http.route":n,"next.span_name":t}),e.updateName(t),a&&a!==e&&(a.setAttribute("http.route",n),a.updateName(t))}else e.updateName(`${D} ${v}`)}),o=async a=>{var i,o;let l=async({previousCacheEntry:r})=>{try{if(!L&&k&&T&&!r)return t.statusCode=404,t.setHeader("x-nextjs-cache","REVALIDATED"),t.end("This page could not be found"),null;let i=await s(a);e.fetchMetrics=V.renderOpts.fetchMetrics;let o=V.renderOpts.pendingWaitUntil;o&&n.waitUntil&&(n.waitUntil(o),o=void 0);let l=V.renderOpts.collectedTags;if(!j)return await (0,c.sendResponse)(W,X,i,V.renderOpts.pendingWaitUntil),null;{let e=await i.blob(),t=(0,h.toNodeOutgoingHttpHeaders)(i.headers);l&&(t[f.NEXT_CACHE_TAGS_HEADER]=l),!t["content-type"]&&e.type&&(t["content-type"]=e.type);let r=void 0!==V.renderOpts.collectedRevalidate&&!(V.renderOpts.collectedRevalidate>=f.INFINITE_CACHE)&&V.renderOpts.collectedRevalidate,n=void 0===V.renderOpts.collectedExpire||V.renderOpts.collectedExpire>=f.INFINITE_CACHE?void 0:V.renderOpts.collectedExpire;return{value:{kind:x.CachedRouteKind.APP_ROUTE,status:i.status,body:Buffer.from(await e.arrayBuffer()),headers:t},cacheControl:{revalidate:r,expire:n}}}}catch(t){throw(null==r?void 0:r.isStale)&&await I.onRequestError(e,t,{routerKind:"App Router",routePath:v,routeType:"route",revalidateReason:(0,p.getRevalidateReason)({isStaticGeneration:G,isOnDemandRevalidate:k})},!1,A),t}},u=await I.handleResponse({req:e,nextConfig:b,cacheKey:U,routeKind:r.RouteKind.APP_ROUTE,isFallback:!1,prerenderManifest:P,isRoutePPREnabled:!1,isOnDemandRevalidate:k,revalidateOnlyGenerated:T,responseGenerator:l,waitUntil:n.waitUntil,isMinimalMode:L});if(!j)return null;if((null==u||null==(i=u.value)?void 0:i.kind)!==x.CachedRouteKind.APP_ROUTE)throw Object.defineProperty(Error(`Invariant: app-route received invalid cache entry ${null==u||null==(o=u.value)?void 0:o.kind}`),"__NEXT_ERROR_CODE",{value:"E701",enumerable:!1,configurable:!0});L||t.setHeader("x-nextjs-cache",k?"REVALIDATED":u.isMiss?"MISS":u.isStale?"STALE":"HIT"),N&&t.setHeader("Cache-Control","private, no-cache, no-store, max-age=0, must-revalidate");let d=(0,h.fromNodeOutgoingHttpHeaders)(u.value.headers);return L&&j||d.delete(f.NEXT_CACHE_TAGS_HEADER),!u.cacheControl||t.getHeader("Cache-Control")||d.get("Cache-Control")||d.set("Cache-Control",(0,m.getCacheControlHeader)(u.cacheControl)),await (0,c.sendResponse)(W,X,new Response(u.value.body,{headers:d,status:u.value.status||200})),null};F&&K?await o(K):(a=$.getActiveScopeSpan(),await $.withPropagatedContext(e.headers,()=>$.trace(d.BaseServerSpan.handleRequest,{spanName:`${D} ${v}`,kind:i.SpanKind.SERVER,attributes:{"http.method":D,"http.target":e.url}},o),void 0,!F))}catch(t){if(t instanceof g.NoFallbackError||await I.onRequestError(e,t,{routerKind:"App Router",routePath:O,routeType:"route",revalidateReason:(0,p.getRevalidateReason)({isStaticGeneration:G,isOnDemandRevalidate:k})},!1,A),j)throw t;return await (0,c.sendResponse)(W,X,new Response(null,{status:500})),null}}e.s(["handler",0,S,"patchFetch",0,function(){return(0,n.patchFetch)({workAsyncStorage:k,workUnitAsyncStorage:T})},"routeModule",0,I,"serverHooks",0,_,"workAsyncStorage",0,k,"workUnitAsyncStorage",0,T],55863)}];
2
-
3
- //# sourceMappingURL=%5Broot-of-the-server%5D__1lbd3kd._.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/lib/gemini/pricing.ts","../../../src/app/api/models/route.ts","../../../node_modules/next/dist/esm/build/templates/app-route.js"],"sourcesContent":["// TASK-45 — per-model Gemini pricing, so a run's captured token usage can be\n// turned into a dollar estimate for the info tab (TASK-48) and picker (TASK-47).\n//\n// Cost is an ESTIMATE, deliberately labelled as of a date: prices move, and the\n// authoritative source is Google's page (see PRICES_AS_OF). An unknown model —\n// or a run that used one — yields NO cost rather than a wrong one (callers omit\n// the field). Prices can be overridden at runtime via the GEMINI_PRICING env var\n// (JSON) without a code change, mirroring how MODEL/FALLBACK_MODELS are env-tunable.\n\n/** prices as of 2026-07; verify at https://ai.google.dev/gemini-api/docs/pricing */\nexport const PRICES_AS_OF = \"2026-07\";\n\n/**\n * A price in USD per 1,000,000 tokens. Either a flat rate, or a two-tier rate\n * that switches at a prompt-size `threshold` (gemini-2.5-pro charges more once a\n * single request's prompt exceeds 200k tokens — for both input and output).\n */\nexport type Rate = number | { threshold: number; below: number; above: number };\n\nexport interface ModelPricing {\n /** USD / 1M input (prompt) tokens. */\n input: Rate;\n /** USD / 1M output tokens — candidates PLUS thinking tokens, both billed here. */\n output: Rate;\n}\n\n/**\n * Built-in table (USD per 1M tokens). gemini-2.5-pro is tiered at 200k prompt\n * tokens; the flash tiers are flat. Keep in step with PRICES_AS_OF above.\n */\nconst DEFAULT_PRICING: Record<string, ModelPricing> = {\n \"gemini-2.5-pro\": {\n input: { threshold: 200_000, below: 1.25, above: 2.5 },\n output: { threshold: 200_000, below: 10.0, above: 15.0 },\n },\n \"gemini-2.5-flash\": { input: 0.3, output: 2.5 },\n \"gemini-2.5-flash-lite\": { input: 0.1, output: 0.4 },\n};\n\n/**\n * The active pricing table: the built-in defaults, with any entries from the\n * GEMINI_PRICING env var merged over the top (per-model replacement, not a deep\n * merge). Malformed JSON is ignored with a warning rather than crashing the\n * pipeline — a bad override must never take down analysis (fail soft, telemetry).\n */\nfunction pricingTable(): Record<string, ModelPricing> {\n const raw = process.env.GEMINI_PRICING?.trim();\n if (!raw) return DEFAULT_PRICING;\n try {\n // Trusted-but-loose: the operator sets this, so we parse and shallow-merge\n // without validating every field. The `as` is the intentional escape hatch\n // (env-provided JSON has no compile-time type). A malformed shape simply\n // produces NaN costs downstream for that model, not a crash.\n const override = JSON.parse(raw) as Record<string, ModelPricing>;\n return { ...DEFAULT_PRICING, ...override };\n } catch {\n console.warn(\"[pricing] GEMINI_PRICING is not valid JSON — using built-in prices.\");\n return DEFAULT_PRICING;\n }\n}\n\n/** Resolve a possibly-tiered rate for a given prompt size. */\nfunction rateFor(rate: Rate, promptTokens: number): number {\n if (typeof rate === \"number\") return rate;\n return promptTokens > rate.threshold ? rate.above : rate.below;\n}\n\n/** The headline rate for display/comparison: a flat rate as-is, a tiered rate's\n * `below` (the price a typical sub-threshold run pays — gemini-2.5-pro's cheaper\n * tier). Not for costing a real call (use costUsd, which knows the prompt size). */\nfunction baseRate(rate: Rate): number {\n return typeof rate === \"number\" ? rate : rate.below;\n}\n\n/**\n * The lower-tier (or flat) USD-per-1M input/output rates for a model, for the\n * model picker's price labels (TASK-47/50) and the fallback-chain \"not pricier\"\n * comparison (analyze.ts). Tiered models report their `below` rate. Returns\n * `undefined` for a model with no known price, so callers OMIT the field —\n * mirroring costUsd (a missing price is not a $0 price).\n */\nexport function basePrice(model: string): { input: number; output: number } | undefined {\n const pricing = pricingTable()[model];\n if (!pricing) return undefined;\n return { input: baseRate(pricing.input), output: baseRate(pricing.output) };\n}\n\n/**\n * Estimated USD cost of one Gemini call. `promptTokens` selects the pricing tier\n * for tiered models (gemini-2.5-pro splits at 200k); pass the call's own input\n * token count. Returns `undefined` when the model has no known price, so callers\n * OMIT cost rather than reporting $0 (a missing price ≠ free).\n *\n * Worked example (gemini-2.5-pro, a small run under the 200k tier):\n * in 120_000, out 8_000 → 120_000/1e6 * 1.25 + 8_000/1e6 * 10.0\n * = 0.15 + 0.08 = $0.23\n */\nexport function costUsd(\n model: string,\n tokensIn: number,\n tokensOut: number,\n promptTokens: number,\n): number | undefined {\n const pricing = pricingTable()[model];\n if (!pricing) return undefined;\n const inRate = rateFor(pricing.input, promptTokens);\n const outRate = rateFor(pricing.output, promptTokens);\n return (tokensIn / 1_000_000) * inRate + (tokensOut / 1_000_000) * outRate;\n}\n","import { NextResponse } from \"next/server\";\nimport { basePrice } from \"@/lib/gemini/pricing\";\n\n/**\n * GET /api/models — the model list that feeds the pre-analysis picker (TASK-47).\n *\n * The server queries Gemini's models.list REST endpoint (NOT the SDK — this is a\n * plain list read) and returns the video-capable, generateContent-able models,\n * each labelled with a known price (pricing.ts) and a recommended/preview hint.\n *\n * Privacy stance (ARCHITECTURE §Privacy, mirrors key-status): GEMINI_API_KEY\n * lives in .env.local and NEVER leaves the server. It is read here to authorize\n * the upstream call and is never serialized into the response.\n *\n * Failure stance (ARCHITECTURE §Error handling): a missing key or an upstream\n * error returns a structured { error } with an honest status — never a 500 stack\n * trace — so the picker can show a clean \"couldn't load models\" state and fall\n * back to the built-in default.\n *\n * ADR-021 caveat: models.list can include a model that merely *appears* available\n * but is actually retired for generateContent (gemini-2.0-flash was). So we only\n * mark the LIVE-verified allowlist as `recommended`; everything else is returned\n * as-is for the picker to show with less prominence. We do NOT probe each model\n * here — that would be one paid call per model on every picker open.\n */\nexport const runtime = \"nodejs\";\n\n/** One model as the picker consumes it. `id` has the \"models/\" prefix stripped. */\nexport interface ModelInfo {\n id: string;\n displayName: string;\n /** LIVE-verified, offer-first (the 2.5 pro/flash/flash-lite allowlist). */\n recommended: boolean;\n /** The id advertises itself as a preview (\"preview\" in the name). */\n preview: boolean;\n /** USD / 1M input tokens (lower tier for tiered models); omitted when unknown. */\n inputPrice?: number;\n /** USD / 1M output tokens (lower tier for tiered models); omitted when unknown. */\n outputPrice?: number;\n}\n\n/** The wire shape: models on success, a structured error otherwise. */\nexport type ModelsResponse = { models: ModelInfo[] } | { error: string };\n\n/**\n * LIVE-verified against generateContent and offered first in the picker. Kept in\n * step with client.ts's MODEL + FALLBACK_MODELS (the tiers the pipeline trusts).\n */\nconst RECOMMENDED = new Set([\"gemini-2.5-pro\", \"gemini-2.5-flash\", \"gemini-2.5-flash-lite\"]);\n\n/**\n * Substrings that mark a model id as a NON-video / non-analysis modality we must\n * not offer as a primary analysis model: image generation, text-to-speech,\n * embeddings, the attributed-QA model, and Imagen. Matched case-insensitively\n * against the bare id.\n */\nconst EXCLUDE_ID_SUBSTRINGS = [\"image\", \"tts\", \"embedding\", \"aqa\", \"imagen\"];\n\n/** The raw model shape from models.list — only the fields we read, all optional. */\ninterface RawModel {\n name?: string;\n displayName?: string;\n supportedGenerationMethods?: string[];\n}\n\nexport async function GET(): Promise<NextResponse<ModelsResponse>> {\n const apiKey = process.env.GEMINI_API_KEY?.trim();\n if (!apiKey) {\n return NextResponse.json(\n { error: \"No Gemini API key is configured. Add GEMINI_API_KEY to .env.local.\" },\n { status: 400 },\n );\n }\n\n let raw: RawModel[];\n try {\n raw = await fetchAllModels(apiKey);\n } catch (err) {\n // Never leak the key or a stack: the key rides in the upstream URL, so we\n // return only a generic, actionable message (the real cause is logged).\n console.error(\"[models] failed to list Gemini models:\", err);\n return NextResponse.json(\n { error: \"Couldn't load the model list from Gemini. Check the API key and try again.\" },\n { status: 502 },\n );\n }\n\n const models = raw\n .filter(isAnalysisCapable)\n .map(toModelInfo)\n // toModelInfo needs a usable id; a nameless entry (shouldn't happen) is dropped.\n .filter((m): m is ModelInfo => m !== null);\n\n return NextResponse.json({ models });\n}\n\n/**\n * Page through models.list (pageSize 1000 returns everything in one call for the\n * current catalog, but we still follow nextPageToken defensively, bounded to a\n * few pages so a misbehaving upstream can't loop forever). Throws on a non-OK\n * response so GET() turns it into the structured 502.\n */\nasync function fetchAllModels(apiKey: string): Promise<RawModel[]> {\n const all: RawModel[] = [];\n let pageToken: string | undefined;\n\n for (let page = 0; page < 5; page++) {\n const url = new URL(\"https://generativelanguage.googleapis.com/v1beta/models\");\n url.searchParams.set(\"key\", apiKey);\n url.searchParams.set(\"pageSize\", \"1000\");\n if (pageToken) url.searchParams.set(\"pageToken\", pageToken);\n\n const res = await fetch(url, { cache: \"no-store\" });\n if (!res.ok) {\n throw new Error(`models.list responded ${res.status} ${res.statusText}`);\n }\n const body = (await res.json()) as { models?: RawModel[]; nextPageToken?: string };\n if (body.models) all.push(...body.models);\n if (!body.nextPageToken) break;\n pageToken = body.nextPageToken;\n }\n\n return all;\n}\n\n/** Keep only models that can run generateContent and aren't an excluded modality. */\nfunction isAnalysisCapable(model: RawModel): boolean {\n if (!model.supportedGenerationMethods?.includes(\"generateContent\")) return false;\n const id = bareId(model.name);\n return !EXCLUDE_ID_SUBSTRINGS.some((bad) => id.includes(bad));\n}\n\n/** Shape one raw model into the picker's ModelInfo, or null if it has no id. */\nfunction toModelInfo(model: RawModel): ModelInfo | null {\n const id = bareId(model.name);\n if (!id) return null;\n const price = basePrice(id);\n return {\n id,\n displayName: model.displayName?.trim() || id,\n recommended: RECOMMENDED.has(id),\n preview: id.includes(\"preview\"),\n // Omit unknown prices entirely (a missing price is not $0 — mirrors costUsd).\n ...(price ? { inputPrice: price.input, outputPrice: price.output } : {}),\n };\n}\n\n/** The model id without the \"models/\" prefix, lowercased for matching. */\nfunction bareId(name: string | undefined): string {\n return (name ?? \"\").replace(/^models\\//, \"\").trim().toLowerCase();\n}\n","import { AppRouteRouteModule } from \"next/dist/esm/server/route-modules/app-route/module.compiled\";\nimport { RouteKind } from \"next/dist/esm/server/route-kind\";\nimport { patchFetch as _patchFetch } from \"next/dist/esm/server/lib/patch-fetch\";\nimport { addRequestMeta, getRequestMeta, setRequestMeta } from \"next/dist/esm/server/request-meta\";\nimport { getTracer, SpanKind } from \"next/dist/esm/server/lib/trace/tracer\";\nimport { setManifestsSingleton } from \"next/dist/esm/server/app-render/manifests-singleton\";\nimport { normalizeAppPath } from \"next/dist/esm/shared/lib/router/utils/app-paths\";\nimport { NodeNextRequest, NodeNextResponse } from \"next/dist/esm/server/base-http/node\";\nimport { NextRequestAdapter, signalFromNodeResponse } from \"next/dist/esm/server/web/spec-extension/adapters/next-request\";\nimport { BaseServerSpan } from \"next/dist/esm/server/lib/trace/constants\";\nimport { getRevalidateReason } from \"next/dist/esm/server/instrumentation/utils\";\nimport { sendResponse } from \"next/dist/esm/server/send-response\";\nimport { fromNodeOutgoingHttpHeaders, toNodeOutgoingHttpHeaders } from \"next/dist/esm/server/web/utils\";\nimport { getCacheControlHeader } from \"next/dist/esm/server/lib/cache-control\";\nimport { INFINITE_CACHE, NEXT_CACHE_TAGS_HEADER } from \"next/dist/esm/lib/constants\";\nimport { NoFallbackError } from \"next/dist/esm/shared/lib/no-fallback-error.external\";\nimport { CachedRouteKind } from \"next/dist/esm/server/response-cache\";\nimport * as userland from \"INNER_APP_ROUTE\";\n// We inject the nextConfigOutput here so that we can use them in the route\n// module.\nconst nextConfigOutput = \"\"\nconst routeModule = new AppRouteRouteModule({\n definition: {\n kind: RouteKind.APP_ROUTE,\n page: \"/api/models/route\",\n pathname: \"/api/models\",\n filename: \"route\",\n bundlePath: \"\"\n },\n distDir: process.env.__NEXT_RELATIVE_DIST_DIR || '',\n relativeProjectDir: process.env.__NEXT_RELATIVE_PROJECT_DIR || '',\n resolvedPagePath: \"[project]/src/app/api/models/route.ts\",\n nextConfigOutput,\n // The static import is used for initialization (methods, dynamic, etc.).\n userland: userland,\n // In Turbopack dev mode, also provide a getter that calls require() on every\n // request. This re-reads from devModuleCache so HMR updates are picked up,\n // and the async wrapper unwraps async-module Promises (ESM-only\n // serverExternalPackages) automatically.\n ...process.env.TURBOPACK && process.env.__NEXT_DEV_SERVER ? {\n getUserland: ()=>import(\"INNER_APP_ROUTE\")\n } : {}\n});\n// Pull out the exports that we need to expose from the module. This should\n// be eliminated when we've moved the other routes to the new format. These\n// are used to hook into the route.\nconst { workAsyncStorage, workUnitAsyncStorage, serverHooks } = routeModule;\nfunction patchFetch() {\n return _patchFetch({\n workAsyncStorage,\n workUnitAsyncStorage\n });\n}\nexport { routeModule, workAsyncStorage, workUnitAsyncStorage, serverHooks, patchFetch, };\nexport async function handler(req, res, ctx) {\n if (ctx.requestMeta) {\n setRequestMeta(req, ctx.requestMeta);\n }\n if (routeModule.isDev) {\n addRequestMeta(req, 'devRequestTimingInternalsEnd', process.hrtime.bigint());\n }\n let srcPage = \"/api/models/route\";\n // turbopack doesn't normalize `/index` in the page name\n // so we need to to process dynamic routes properly\n // TODO: fix turbopack providing differing value from webpack\n if (process.env.TURBOPACK) {\n srcPage = srcPage.replace(/\\/index$/, '') || '/';\n } else if (srcPage === '/index') {\n // we always normalize /index specifically\n srcPage = '/';\n }\n const multiZoneDraftMode = process.env.__NEXT_MULTI_ZONE_DRAFT_MODE;\n const prepareResult = await routeModule.prepare(req, res, {\n srcPage,\n multiZoneDraftMode\n });\n if (!prepareResult) {\n res.statusCode = 400;\n res.end('Bad Request');\n ctx.waitUntil == null ? void 0 : ctx.waitUntil.call(ctx, Promise.resolve());\n return null;\n }\n const { buildId, deploymentId, params, nextConfig, parsedUrl, isDraftMode, prerenderManifest, routerServerContext, isOnDemandRevalidate, revalidateOnlyGenerated, resolvedPathname, clientReferenceManifest, serverActionsManifest } = prepareResult;\n const normalizedSrcPage = normalizeAppPath(srcPage);\n let isIsr = Boolean(prerenderManifest.dynamicRoutes[normalizedSrcPage] || prerenderManifest.routes[resolvedPathname]);\n const render404 = async ()=>{\n // TODO: should route-module itself handle rendering the 404\n if (routerServerContext == null ? void 0 : routerServerContext.render404) {\n await routerServerContext.render404(req, res, parsedUrl, false);\n } else {\n res.end('This page could not be found');\n }\n return null;\n };\n if (isIsr && !isDraftMode) {\n const isPrerendered = Boolean(prerenderManifest.routes[resolvedPathname]);\n const prerenderInfo = prerenderManifest.dynamicRoutes[normalizedSrcPage];\n if (prerenderInfo) {\n if (prerenderInfo.fallback === false && !isPrerendered) {\n if (nextConfig.adapterPath) {\n return await render404();\n }\n throw new NoFallbackError();\n }\n }\n }\n let cacheKey = null;\n if (isIsr && !routeModule.isDev && !isDraftMode) {\n cacheKey = resolvedPathname;\n // ensure /index and / is normalized to one key\n cacheKey = cacheKey === '/index' ? '/' : cacheKey;\n }\n const supportsDynamicResponse = // If we're in development, we always support dynamic HTML\n routeModule.isDev === true || // If this is not SSG or does not have static paths, then it supports\n // dynamic HTML.\n !isIsr;\n // This is a revalidation request if the request is for a static\n // page and it is not being resumed from a postponed render and\n // it is not a dynamic RSC request then it is a revalidation\n // request.\n const isStaticGeneration = isIsr && !supportsDynamicResponse;\n // Before rendering (which initializes component tree modules), we have to\n // set the reference manifests to our global store so Server Action's\n // encryption util can access to them at the top level of the page module.\n if (serverActionsManifest && clientReferenceManifest) {\n setManifestsSingleton({\n page: srcPage,\n clientReferenceManifest,\n serverActionsManifest\n });\n }\n const method = req.method || 'GET';\n const tracer = getTracer();\n const activeSpan = tracer.getActiveScopeSpan();\n const isWrappedByNextServer = Boolean(routerServerContext == null ? void 0 : routerServerContext.isWrappedByNextServer);\n const isMinimalMode = Boolean(getRequestMeta(req, 'minimalMode'));\n const incrementalCache = getRequestMeta(req, 'incrementalCache') || await routeModule.getIncrementalCache(req, nextConfig, prerenderManifest, isMinimalMode);\n incrementalCache == null ? void 0 : incrementalCache.resetRequestCache();\n globalThis.__incrementalCache = incrementalCache;\n const context = {\n params,\n previewProps: prerenderManifest.preview,\n renderOpts: {\n experimental: {\n authInterrupts: Boolean(nextConfig.experimental.authInterrupts)\n },\n cacheComponents: Boolean(nextConfig.cacheComponents),\n supportsDynamicResponse,\n incrementalCache,\n cacheLifeProfiles: nextConfig.cacheLife,\n waitUntil: ctx.waitUntil,\n onClose: (cb)=>{\n res.on('close', cb);\n },\n onAfterTaskError: undefined,\n onInstrumentationRequestError: (error, _request, errorContext, silenceLog)=>routeModule.onRequestError(req, error, errorContext, silenceLog, routerServerContext)\n },\n sharedContext: {\n buildId,\n deploymentId\n }\n };\n const nodeNextReq = new NodeNextRequest(req);\n const nodeNextRes = new NodeNextResponse(res);\n const nextReq = NextRequestAdapter.fromNodeNextRequest(nodeNextReq, signalFromNodeResponse(res));\n try {\n let parentSpan;\n const invokeRouteModule = async (span)=>{\n return routeModule.handle(nextReq, context).finally(()=>{\n if (!span) return;\n span.setAttributes({\n 'http.status_code': res.statusCode,\n 'next.rsc': false\n });\n const rootSpanAttributes = tracer.getRootSpanAttributes();\n // We were unable to get attributes, probably OTEL is not enabled\n if (!rootSpanAttributes) {\n return;\n }\n if (rootSpanAttributes.get('next.span_type') !== BaseServerSpan.handleRequest) {\n console.warn(`Unexpected root span type '${rootSpanAttributes.get('next.span_type')}'. Please report this Next.js issue https://github.com/vercel/next.js`);\n return;\n }\n const route = rootSpanAttributes.get('next.route');\n if (route) {\n const name = `${method} ${route}`;\n span.setAttributes({\n 'next.route': route,\n 'http.route': route,\n 'next.span_name': name\n });\n span.updateName(name);\n // Propagate http.route to the parent span if one exists (e.g.\n // a platform-created HTTP span in adapter deployments).\n if (parentSpan && parentSpan !== span) {\n parentSpan.setAttribute('http.route', route);\n parentSpan.updateName(name);\n }\n } else {\n span.updateName(`${method} ${srcPage}`);\n }\n });\n };\n const handleResponse = async (currentSpan)=>{\n var _cacheEntry_value;\n const responseGenerator = async ({ previousCacheEntry })=>{\n try {\n if (!isMinimalMode && isOnDemandRevalidate && revalidateOnlyGenerated && !previousCacheEntry) {\n res.statusCode = 404;\n // on-demand revalidate always sets this header\n res.setHeader('x-nextjs-cache', 'REVALIDATED');\n res.end('This page could not be found');\n return null;\n }\n const response = await invokeRouteModule(currentSpan);\n req.fetchMetrics = context.renderOpts.fetchMetrics;\n let pendingWaitUntil = context.renderOpts.pendingWaitUntil;\n // Attempt using provided waitUntil if available\n // if it's not we fallback to sendResponse's handling\n if (pendingWaitUntil) {\n if (ctx.waitUntil) {\n ctx.waitUntil(pendingWaitUntil);\n pendingWaitUntil = undefined;\n }\n }\n const cacheTags = context.renderOpts.collectedTags;\n // If the request is for a static response, we can cache it so long\n // as it's not edge.\n if (isIsr) {\n const blob = await response.blob();\n // Copy the headers from the response.\n const headers = toNodeOutgoingHttpHeaders(response.headers);\n if (cacheTags) {\n headers[NEXT_CACHE_TAGS_HEADER] = cacheTags;\n }\n if (!headers['content-type'] && blob.type) {\n headers['content-type'] = blob.type;\n }\n const revalidate = typeof context.renderOpts.collectedRevalidate === 'undefined' || context.renderOpts.collectedRevalidate >= INFINITE_CACHE ? false : context.renderOpts.collectedRevalidate;\n const expire = typeof context.renderOpts.collectedExpire === 'undefined' || context.renderOpts.collectedExpire >= INFINITE_CACHE ? undefined : context.renderOpts.collectedExpire;\n // Create the cache entry for the response.\n const cacheEntry = {\n value: {\n kind: CachedRouteKind.APP_ROUTE,\n status: response.status,\n body: Buffer.from(await blob.arrayBuffer()),\n headers\n },\n cacheControl: {\n revalidate,\n expire\n }\n };\n return cacheEntry;\n } else {\n // send response without caching if not ISR\n await sendResponse(nodeNextReq, nodeNextRes, response, context.renderOpts.pendingWaitUntil);\n return null;\n }\n } catch (err) {\n // if this is a background revalidate we need to report\n // the request error here as it won't be bubbled\n if (previousCacheEntry == null ? void 0 : previousCacheEntry.isStale) {\n const silenceLog = false;\n await routeModule.onRequestError(req, err, {\n routerKind: 'App Router',\n routePath: srcPage,\n routeType: 'route',\n revalidateReason: getRevalidateReason({\n isStaticGeneration,\n isOnDemandRevalidate\n })\n }, silenceLog, routerServerContext);\n }\n throw err;\n }\n };\n const cacheEntry = await routeModule.handleResponse({\n req,\n nextConfig,\n cacheKey,\n routeKind: RouteKind.APP_ROUTE,\n isFallback: false,\n prerenderManifest,\n isRoutePPREnabled: false,\n isOnDemandRevalidate,\n revalidateOnlyGenerated,\n responseGenerator,\n waitUntil: ctx.waitUntil,\n isMinimalMode\n });\n // we don't create a cacheEntry for ISR\n if (!isIsr) {\n return null;\n }\n if ((cacheEntry == null ? void 0 : (_cacheEntry_value = cacheEntry.value) == null ? void 0 : _cacheEntry_value.kind) !== CachedRouteKind.APP_ROUTE) {\n var _cacheEntry_value1;\n throw Object.defineProperty(new Error(`Invariant: app-route received invalid cache entry ${cacheEntry == null ? void 0 : (_cacheEntry_value1 = cacheEntry.value) == null ? void 0 : _cacheEntry_value1.kind}`), \"__NEXT_ERROR_CODE\", {\n value: \"E701\",\n enumerable: false,\n configurable: true\n });\n }\n if (!isMinimalMode) {\n res.setHeader('x-nextjs-cache', isOnDemandRevalidate ? 'REVALIDATED' : cacheEntry.isMiss ? 'MISS' : cacheEntry.isStale ? 'STALE' : 'HIT');\n }\n // Draft mode should never be cached\n if (isDraftMode) {\n res.setHeader('Cache-Control', 'private, no-cache, no-store, max-age=0, must-revalidate');\n }\n const headers = fromNodeOutgoingHttpHeaders(cacheEntry.value.headers);\n if (!(isMinimalMode && isIsr)) {\n headers.delete(NEXT_CACHE_TAGS_HEADER);\n }\n // If cache control is already set on the response we don't\n // override it to allow users to customize it via next.config\n if (cacheEntry.cacheControl && !res.getHeader('Cache-Control') && !headers.get('Cache-Control')) {\n headers.set('Cache-Control', getCacheControlHeader(cacheEntry.cacheControl));\n }\n await sendResponse(nodeNextReq, nodeNextRes, // @ts-expect-error - Argument of type 'Buffer<ArrayBufferLike>' is not assignable to parameter of type 'BodyInit | null | undefined'.\n new Response(cacheEntry.value.body, {\n headers,\n status: cacheEntry.value.status || 200\n }));\n return null;\n };\n // TODO: activeSpan code path is for when wrapped by\n // next-server can be removed when this is no longer used\n if (isWrappedByNextServer && activeSpan) {\n await handleResponse(activeSpan);\n } else {\n parentSpan = tracer.getActiveScopeSpan();\n await tracer.withPropagatedContext(req.headers, ()=>tracer.trace(BaseServerSpan.handleRequest, {\n spanName: `${method} ${srcPage}`,\n kind: SpanKind.SERVER,\n attributes: {\n 'http.method': method,\n 'http.target': req.url\n }\n }, handleResponse), undefined, !isWrappedByNextServer);\n }\n } catch (err) {\n if (!(err instanceof NoFallbackError)) {\n const silenceLog = false;\n await routeModule.onRequestError(req, err, {\n routerKind: 'App Router',\n routePath: normalizedSrcPage,\n routeType: 'route',\n revalidateReason: getRevalidateReason({\n isStaticGeneration,\n isOnDemandRevalidate\n })\n }, silenceLog, routerServerContext);\n }\n // rethrow so that we can handle serving error page\n // If this is during static generation, throw the error again.\n if (isIsr) throw err;\n // Otherwise, send a 500 response.\n await sendResponse(nodeNextReq, nodeNextRes, new Response(null, {\n status: 500\n }));\n return null;\n }\n}\n\n//# sourceMappingURL=app-route.js.map\n"],"names":["PRICES_AS_OF","DEFAULT_PRICING","input","threshold","below","above","output","pricingTable","raw","process","env","GEMINI_PRICING","trim","override","JSON","parse","console","warn","rateFor","rate","promptTokens","baseRate","basePrice","model","pricing","undefined","costUsd","tokensIn","tokensOut","inRate","outRate","runtime","RECOMMENDED","Set","EXCLUDE_ID_SUBSTRINGS","status","GET","error","apiKey","GEMINI_API_KEY","json","toModelInfo","fetchAllModels","err","set","models","filter","isAnalysisCapable","map","m","all","pageToken","page","url","URL","searchParams","res","fetch","cache","ok","Error","outputPrice","statusText","body","push","nextPageToken","supportedGenerationMethods","includes","id","bareId","name","some","bad","price","displayName","recommended","has","preview","inputPrice","replace","toLowerCase"],"mappings":"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","ignoreList":[2]}
@@ -1,3 +0,0 @@
1
- module.exports=[59639,(e,r,o)=>{r.exports=e.x("node:process",()=>require("node:process"))},2157,(e,r,o)=>{r.exports=e.x("node:fs",()=>require("node:fs"))},18352,(e,r,o)=>{r.exports=e.x("node:stream/web",()=>require("node:stream/web"))},37702,(e,r,o)=>{r.exports=e.x("worker_threads",()=>require("worker_threads"))},57764,(e,r,o)=>{r.exports=e.x("node:url",()=>require("node:url"))},47299,(e,r,o)=>{r.exports=e.x("node:http",()=>require("node:http"))},43698,(e,r,o)=>{r.exports=e.x("node:https",()=>require("node:https"))},27028,(e,r,o)=>{r.exports=e.x("node:zlib",()=>require("node:zlib"))},51615,(e,r,o)=>{r.exports=e.x("node:buffer",()=>require("node:buffer"))},12057,(e,r,o)=>{r.exports=e.x("node:util",()=>require("node:util"))},61095,(e,r,o)=>{r.exports=e.x("node:net",()=>require("node:net"))},25897,e=>{e.v(r=>Promise.all(["server/chunks/[root-of-the-server]__081zp1m._.js","server/chunks/node_modules_1t2pqct._.js"].map(r=>e.l(r))).then(()=>r(20585)))}];
2
-
3
- //# sourceMappingURL=%5Broot-of-the-server%5D__1ra6psc._.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":""}
@@ -1,3 +0,0 @@
1
- module.exports=[93695,(e,r,t)=>{r.exports=e.x("next/dist/shared/lib/no-fallback-error.external.js",()=>require("next/dist/shared/lib/no-fallback-error.external.js"))},70406,(e,r,t)=>{r.exports=e.x("next/dist/compiled/@opentelemetry/api",()=>require("next/dist/compiled/@opentelemetry/api"))},18622,(e,r,t)=>{r.exports=e.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},56704,(e,r,t)=>{r.exports=e.x("next/dist/server/app-render/work-async-storage.external.js",()=>require("next/dist/server/app-render/work-async-storage.external.js"))},32319,(e,r,t)=>{r.exports=e.x("next/dist/server/app-render/work-unit-async-storage.external.js",()=>require("next/dist/server/app-render/work-unit-async-storage.external.js"))},14747,(e,r,t)=>{r.exports=e.x("path",()=>require("path"))},24361,(e,r,t)=>{r.exports=e.x("util",()=>require("util"))},24836,(e,r,t)=>{r.exports=e.x("https",()=>require("https"))},46786,(e,r,t)=>{r.exports=e.x("os",()=>require("os"))},21517,(e,r,t)=>{r.exports=e.x("http",()=>require("http"))},4446,(e,r,t)=>{r.exports=e.x("net",()=>require("net"))},55004,(e,r,t)=>{r.exports=e.x("tls",()=>require("tls"))},92509,(e,r,t)=>{r.exports=e.x("url",()=>require("url"))},874,(e,r,t)=>{r.exports=e.x("buffer",()=>require("buffer"))},81111,(e,r,t)=>{r.exports=e.x("node:stream",()=>require("node:stream"))},54799,(e,r,t)=>{r.exports=e.x("crypto",()=>require("crypto"))},33405,(e,r,t)=>{r.exports=e.x("child_process",()=>require("child_process"))},22734,(e,r,t)=>{r.exports=e.x("fs",()=>require("fs"))},88947,(e,r,t)=>{r.exports=e.x("stream",()=>require("stream"))},27699,(e,r,t)=>{r.exports=e.x("events",()=>require("events"))},5365,(e,r,t)=>{r.exports=e.x("process",()=>require("process"))},45706,(e,r,t)=>{r.exports=e.x("querystring",()=>require("querystring"))},24868,(e,r,t)=>{r.exports=e.x("fs/promises",()=>require("fs/promises"))},88646,(e,r,t)=>{r.exports=e.x("node:stream/promises",()=>require("node:stream/promises"))},6461,(e,r,t)=>{r.exports=e.x("zlib",()=>require("zlib"))},50227,(e,r,t)=>{r.exports=e.x("node:path",()=>require("node:path"))},2157,(e,r,t)=>{r.exports=e.x("node:fs",()=>require("node:fs"))},12714,(e,r,t)=>{r.exports=e.x("node:fs/promises",()=>require("node:fs/promises"))},60526,(e,r,t)=>{r.exports=e.x("node:os",()=>require("node:os"))},13571,e=>{"use strict";let r={"gemini-2.5-pro":{input:{threshold:2e5,below:1.25,above:2.5},output:{threshold:2e5,below:10,above:15}},"gemini-2.5-flash":{input:.3,output:2.5},"gemini-2.5-flash-lite":{input:.1,output:.4}};function t(){let e=process.env.GEMINI_PRICING?.trim();if(!e)return r;try{let t=JSON.parse(e);return{...r,...t}}catch{return console.warn("[pricing] GEMINI_PRICING is not valid JSON — using built-in prices."),r}}function s(e,r){return"number"==typeof e?e:r>e.threshold?e.above:e.below}function o(e){return"number"==typeof e?e:e.below}e.s(["basePrice",0,function(e){let r=t()[e];if(r)return{input:o(r.input),output:o(r.output)}},"costUsd",0,function(e,r,o,i){let n=t()[e];if(n)return r/1e6*s(n.input,i)+o/1e6*s(n.output,i)}])},85685,e=>{e.v(e=>Promise.resolve().then(()=>e(54799)))},91961,e=>{e.v(r=>Promise.all(["server/chunks/[externals]__1l0bqbz._.js","server/chunks/node_modules_19bvt3l._.js"].map(r=>e.l(r))).then(()=>r(12111)))},72331,e=>{e.v(r=>Promise.all(["server/chunks/[root-of-the-server]__0x-kpif._.js","server/chunks/node_modules_0x51oh_._.js","server/chunks/node_modules_node-fetch_src_index_1gf-_pn.js"].map(r=>e.l(r))).then(()=>r(20442)))}];
2
-
3
- //# sourceMappingURL=%5Broot-of-the-server%5D__1zn977r._.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/lib/gemini/pricing.ts"],"sourcesContent":["// TASK-45 — per-model Gemini pricing, so a run's captured token usage can be\n// turned into a dollar estimate for the info tab (TASK-48) and picker (TASK-47).\n//\n// Cost is an ESTIMATE, deliberately labelled as of a date: prices move, and the\n// authoritative source is Google's page (see PRICES_AS_OF). An unknown model —\n// or a run that used one — yields NO cost rather than a wrong one (callers omit\n// the field). Prices can be overridden at runtime via the GEMINI_PRICING env var\n// (JSON) without a code change, mirroring how MODEL/FALLBACK_MODELS are env-tunable.\n\n/** prices as of 2026-07; verify at https://ai.google.dev/gemini-api/docs/pricing */\nexport const PRICES_AS_OF = \"2026-07\";\n\n/**\n * A price in USD per 1,000,000 tokens. Either a flat rate, or a two-tier rate\n * that switches at a prompt-size `threshold` (gemini-2.5-pro charges more once a\n * single request's prompt exceeds 200k tokens — for both input and output).\n */\nexport type Rate = number | { threshold: number; below: number; above: number };\n\nexport interface ModelPricing {\n /** USD / 1M input (prompt) tokens. */\n input: Rate;\n /** USD / 1M output tokens — candidates PLUS thinking tokens, both billed here. */\n output: Rate;\n}\n\n/**\n * Built-in table (USD per 1M tokens). gemini-2.5-pro is tiered at 200k prompt\n * tokens; the flash tiers are flat. Keep in step with PRICES_AS_OF above.\n */\nconst DEFAULT_PRICING: Record<string, ModelPricing> = {\n \"gemini-2.5-pro\": {\n input: { threshold: 200_000, below: 1.25, above: 2.5 },\n output: { threshold: 200_000, below: 10.0, above: 15.0 },\n },\n \"gemini-2.5-flash\": { input: 0.3, output: 2.5 },\n \"gemini-2.5-flash-lite\": { input: 0.1, output: 0.4 },\n};\n\n/**\n * The active pricing table: the built-in defaults, with any entries from the\n * GEMINI_PRICING env var merged over the top (per-model replacement, not a deep\n * merge). Malformed JSON is ignored with a warning rather than crashing the\n * pipeline — a bad override must never take down analysis (fail soft, telemetry).\n */\nfunction pricingTable(): Record<string, ModelPricing> {\n const raw = process.env.GEMINI_PRICING?.trim();\n if (!raw) return DEFAULT_PRICING;\n try {\n // Trusted-but-loose: the operator sets this, so we parse and shallow-merge\n // without validating every field. The `as` is the intentional escape hatch\n // (env-provided JSON has no compile-time type). A malformed shape simply\n // produces NaN costs downstream for that model, not a crash.\n const override = JSON.parse(raw) as Record<string, ModelPricing>;\n return { ...DEFAULT_PRICING, ...override };\n } catch {\n console.warn(\"[pricing] GEMINI_PRICING is not valid JSON — using built-in prices.\");\n return DEFAULT_PRICING;\n }\n}\n\n/** Resolve a possibly-tiered rate for a given prompt size. */\nfunction rateFor(rate: Rate, promptTokens: number): number {\n if (typeof rate === \"number\") return rate;\n return promptTokens > rate.threshold ? rate.above : rate.below;\n}\n\n/** The headline rate for display/comparison: a flat rate as-is, a tiered rate's\n * `below` (the price a typical sub-threshold run pays — gemini-2.5-pro's cheaper\n * tier). Not for costing a real call (use costUsd, which knows the prompt size). */\nfunction baseRate(rate: Rate): number {\n return typeof rate === \"number\" ? rate : rate.below;\n}\n\n/**\n * The lower-tier (or flat) USD-per-1M input/output rates for a model, for the\n * model picker's price labels (TASK-47/50) and the fallback-chain \"not pricier\"\n * comparison (analyze.ts). Tiered models report their `below` rate. Returns\n * `undefined` for a model with no known price, so callers OMIT the field —\n * mirroring costUsd (a missing price is not a $0 price).\n */\nexport function basePrice(model: string): { input: number; output: number } | undefined {\n const pricing = pricingTable()[model];\n if (!pricing) return undefined;\n return { input: baseRate(pricing.input), output: baseRate(pricing.output) };\n}\n\n/**\n * Estimated USD cost of one Gemini call. `promptTokens` selects the pricing tier\n * for tiered models (gemini-2.5-pro splits at 200k); pass the call's own input\n * token count. Returns `undefined` when the model has no known price, so callers\n * OMIT cost rather than reporting $0 (a missing price ≠ free).\n *\n * Worked example (gemini-2.5-pro, a small run under the 200k tier):\n * in 120_000, out 8_000 → 120_000/1e6 * 1.25 + 8_000/1e6 * 10.0\n * = 0.15 + 0.08 = $0.23\n */\nexport function costUsd(\n model: string,\n tokensIn: number,\n tokensOut: number,\n promptTokens: number,\n): number | undefined {\n const pricing = pricingTable()[model];\n if (!pricing) return undefined;\n const inRate = rateFor(pricing.input, promptTokens);\n const outRate = rateFor(pricing.output, promptTokens);\n return (tokensIn / 1_000_000) * inRate + (tokensOut / 1_000_000) * outRate;\n}\n"],"names":["PRICES_AS_OF","DEFAULT_PRICING","input","threshold","below","above","output","pricingTable","raw","process","env","GEMINI_PRICING","trim","override","JSON","parse","console","warn","rateFor","rate","promptTokens","baseRate","basePrice","model","pricing","undefined","costUsd","tokensIn","tokensOut","inRate","outRate"],"mappings":"s1EA8BA,IAAMC,EAAgD,CACpD,iBAAkB,CAChBC,MAAO,CAAEC,UAAW,IAASC,MAAO,KAAMC,MAAO,GAAI,EACrDC,OAAQ,CAAEH,UAAW,IAASC,MAAO,GAAMC,MAAO,EAAK,CACzD,EACA,mBAAoB,CAAEH,MAAO,GAAKI,OAAQ,GAAI,EAC9C,wBAAyB,CAAEJ,MAAO,GAAKI,OAAQ,EAAI,CACrD,EAQA,SAASC,IACP,IAAMC,EAAMC,QAAQC,GAAG,CAACC,cAAc,EAAEC,OACxC,GAAI,CAACJ,EAAK,OAAOP,EACjB,GAAI,CAKF,IAAMY,EAAWC,KAAKC,KAAK,CAACP,GAC5B,MAAO,CAAE,GAAGP,CAAe,CAAE,GAAGY,CAAQ,AAAC,CAC3C,CAAE,KAAM,CAEN,OADAG,QAAQC,IAAI,CAAC,uEACNhB,CACT,CACF,CAGA,SAASiB,EAAQC,CAAU,CAAEC,CAAoB,QAC/C,AAAoB,UAAhB,AAA0B,OAAnBD,EAA0BA,EAC9BC,EAAeD,EAAKhB,SAAS,CAAGgB,EAAKd,KAAK,CAAGc,EAAKf,KAAK,AAChE,CAKA,SAASiB,EAASF,CAAU,EAC1B,MAAuB,UAAhB,OAAOA,EAAoBA,EAAOA,EAAKf,KAAK,AACrD,oBASO,SAASkB,AAAUC,CAAa,EACrC,IAAMC,EAAUjB,GAAc,CAACgB,EAAM,CACrC,GAAKC,CAAD,CACJ,MAAO,CADO,AACLtB,MAAOmB,CADKI,CACID,EAAQtB,KAAK,EAAGI,OAAQe,EAASG,EAAQlB,MAAM,CAAE,CAC5E,cAYO,SAASoB,AACdH,CAAa,CACbI,CAAgB,CAChBC,CAAiB,CACjBR,CAAoB,EAEpB,IAAMI,EAAUjB,GAAc,CAACgB,EAAM,CACrC,GAAKC,CAAD,CAGJ,OAHc,AAGNG,EAAW,IAFJT,CADMO,CACED,EAAQtB,IAEC2B,CAFI,CAAET,GAEIQ,EAAY,IADtCV,EAAQM,EAAQlB,IACmCwB,EAD7B,CAAEV,EAE1C"}