@squadbase/vantage 0.6.2-dev1.b332e5a → 0.6.2-dev1.bcb51d1

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 (337) hide show
  1. package/dist/add-4GHF2TX2.js +6 -0
  2. package/dist/add-4GHF2TX2.js.map +1 -0
  3. package/dist/{build-TVKFIVFQ.js → build-U7GO26HR.js} +9 -9
  4. package/dist/{build-TVKFIVFQ.js.map → build-U7GO26HR.js.map} +1 -1
  5. package/dist/{check-3KHZXZMQ.js → check-MRVAIHG5.js} +7 -7
  6. package/dist/{check-3KHZXZMQ.js.map → check-MRVAIHG5.js.map} +1 -1
  7. package/dist/chunk-2IAPIOPS.js +152 -0
  8. package/dist/chunk-2IAPIOPS.js.map +1 -0
  9. package/dist/{chunk-5ZOP4SQR.js → chunk-2N72FKLB.js} +12 -7
  10. package/dist/chunk-2N72FKLB.js.map +1 -0
  11. package/dist/chunk-57GHR5LN.js +163 -0
  12. package/dist/chunk-57GHR5LN.js.map +1 -0
  13. package/dist/chunk-6OTTGAPO.js +44 -0
  14. package/dist/chunk-6OTTGAPO.js.map +1 -0
  15. package/dist/{chunk-RPZAALCX.js → chunk-7S52M2SL.js} +256 -165
  16. package/dist/chunk-7S52M2SL.js.map +1 -0
  17. package/dist/{chunk-U2M6HGKQ.js → chunk-AABMKHEU.js} +4 -4
  18. package/dist/{chunk-U2M6HGKQ.js.map → chunk-AABMKHEU.js.map} +1 -1
  19. package/dist/{chunk-PVTHHV7X.js → chunk-ANZLVSEP.js} +28 -7
  20. package/dist/chunk-ANZLVSEP.js.map +1 -0
  21. package/dist/chunk-CKWPK4RO.js +50 -0
  22. package/dist/chunk-CKWPK4RO.js.map +1 -0
  23. package/dist/{chunk-QI3XQKHS.js → chunk-GNXCX4WE.js} +10 -3
  24. package/dist/chunk-GNXCX4WE.js.map +1 -0
  25. package/dist/chunk-JXFCSF3K.js +673 -0
  26. package/dist/chunk-JXFCSF3K.js.map +1 -0
  27. package/dist/{chunk-PXRX5PEC.js → chunk-PDOBHMUQ.js} +3 -3
  28. package/dist/chunk-PDOBHMUQ.js.map +1 -0
  29. package/dist/{chunk-P7W4LR3Z.js → chunk-PJ4SPXHS.js} +24 -7
  30. package/dist/chunk-PJ4SPXHS.js.map +1 -0
  31. package/dist/chunk-QOXXOFGL.js +7051 -0
  32. package/dist/chunk-QOXXOFGL.js.map +1 -0
  33. package/dist/{chunk-ZVANIULZ.js → chunk-RNTDBX6S.js} +4 -4
  34. package/dist/{chunk-ZVANIULZ.js.map → chunk-RNTDBX6S.js.map} +1 -1
  35. package/dist/{chunk-CEXAQQ5W.js → chunk-S5MDTHH7.js} +180 -18
  36. package/dist/chunk-S5MDTHH7.js.map +1 -0
  37. package/dist/chunk-SDJTTMLK.js +1877 -0
  38. package/dist/chunk-SDJTTMLK.js.map +1 -0
  39. package/dist/{chunk-LMUACBMA.js → chunk-SHZM3EXB.js} +68 -12
  40. package/dist/chunk-SHZM3EXB.js.map +1 -0
  41. package/dist/{chunk-A2UUGASH.js → chunk-U736PVHY.js} +2 -2
  42. package/dist/chunk-U736PVHY.js.map +1 -0
  43. package/dist/{chunk-JKLLFVEU.js → chunk-UWSQUHX6.js} +4 -99
  44. package/dist/chunk-UWSQUHX6.js.map +1 -0
  45. package/dist/cli.js +12 -11
  46. package/dist/cli.js.map +1 -1
  47. package/dist/client/index.d.ts +34 -3
  48. package/dist/client/index.js +211 -12
  49. package/dist/client/index.js.map +1 -1
  50. package/dist/components/index.d.ts +1740 -29
  51. package/dist/components/index.js +7 -4
  52. package/dist/delta-text-CvwBGJ95.d.ts +15 -0
  53. package/dist/{dev-GDKATCC7.js → dev-O42JFQ64.js} +10 -10
  54. package/dist/dev-O42JFQ64.js.map +1 -0
  55. package/dist/doc/index.d.ts +215 -2
  56. package/dist/doc/index.js +309 -5
  57. package/dist/doc/index.js.map +1 -1
  58. package/dist/{docs-EJJ3BECT.js → docs-JVP4RPKT.js} +3 -3
  59. package/dist/{docs-EJJ3BECT.js.map → docs-JVP4RPKT.js.map} +1 -1
  60. package/dist/{doctor-WQXPXP6K.js → doctor-YD3XAAOT.js} +7 -7
  61. package/dist/{doctor-WQXPXP6K.js.map → doctor-YD3XAAOT.js.map} +1 -1
  62. package/dist/format-U0cQl069.d.ts +243 -0
  63. package/dist/markdown/index.js +1 -1
  64. package/dist/markdown/index.js.map +1 -1
  65. package/dist/{preview-OGMCNQUO.js → preview-T6CLSQVX.js} +3 -3
  66. package/dist/{preview-OGMCNQUO.js.map → preview-T6CLSQVX.js.map} +1 -1
  67. package/dist/query/index.d.ts +0 -11
  68. package/dist/query/index.js +2 -2
  69. package/dist/{routes-MWBWWOJ2.js → routes-PVKNT777.js} +6 -6
  70. package/dist/{routes-MWBWWOJ2.js.map → routes-PVKNT777.js.map} +1 -1
  71. package/dist/{search-6Y422SV6.js → search-5LC4XPB5.js} +3 -3
  72. package/dist/{search-6Y422SV6.js.map → search-5LC4XPB5.js.map} +1 -1
  73. package/dist/slide/index.d.ts +272 -1
  74. package/dist/slide/index.js +974 -4
  75. package/dist/slide/index.js.map +1 -1
  76. package/dist/table/index.js +14 -10
  77. package/dist/table/index.js.map +1 -1
  78. package/dist/ui/index.d.ts +148 -12
  79. package/dist/ui/index.js +1340 -88
  80. package/dist/ui/index.js.map +1 -1
  81. package/dist/{upgrade-HCANX4GQ.js → upgrade-6DT7ADRP.js} +7 -7
  82. package/dist/{upgrade-HCANX4GQ.js.map → upgrade-6DT7ADRP.js.map} +1 -1
  83. package/dist/vite/index.d.ts +10 -0
  84. package/dist/vite/index.js +4 -4
  85. package/docs/en/agent-skills.md +1 -1
  86. package/docs/en/changelog.md +2 -0
  87. package/docs/en/components.md +42 -17
  88. package/docs/en/doc/delta-text.md +40 -0
  89. package/docs/en/doc/doc-action-items.md +49 -0
  90. package/docs/en/doc/doc-callout.md +38 -0
  91. package/docs/en/doc/doc-data-table.md +60 -0
  92. package/docs/en/doc/doc-executive-summary.md +64 -0
  93. package/docs/en/doc/doc-figure.md +56 -0
  94. package/docs/en/doc/doc-key-findings.md +61 -0
  95. package/docs/en/doc/doc-kpi-scorecard.md +80 -0
  96. package/docs/en/doc/doc-notes-and-sources.md +43 -0
  97. package/docs/en/doc/doc-report-header.md +46 -0
  98. package/docs/en/pages-and-metadata.md +15 -0
  99. package/docs/en/parts/area-chart.md +99 -0
  100. package/docs/en/parts/bar-chart.md +91 -0
  101. package/docs/en/parts/bar-list.md +50 -0
  102. package/docs/en/parts/category-bar.md +37 -0
  103. package/docs/en/parts/chart-frame.md +39 -0
  104. package/docs/en/parts/data-table.md +22 -0
  105. package/docs/en/parts/delta.md +51 -0
  106. package/docs/en/parts/donut-chart.md +72 -0
  107. package/docs/en/parts/format.md +43 -0
  108. package/docs/en/parts/funnel-steps.md +2 -1
  109. package/docs/en/parts/heatmap.md +53 -0
  110. package/docs/en/parts/kpi-card.md +58 -0
  111. package/docs/en/parts/legend.md +35 -0
  112. package/docs/en/parts/line-chart.md +94 -0
  113. package/docs/en/parts/metric-value.md +3 -2
  114. package/docs/en/parts/progress-circle.md +33 -0
  115. package/docs/en/parts/sample-data.md +39 -0
  116. package/docs/en/parts/scatter-chart.md +56 -0
  117. package/docs/en/parts/sparkline.md +1 -1
  118. package/docs/en/parts/tracker.md +36 -0
  119. package/docs/en/parts/trend-indicator.md +17 -1
  120. package/docs/en/parts/updated-at.md +30 -0
  121. package/docs/en/parts/waterfall-chart.md +56 -0
  122. package/docs/en/slide/slide-chart-full.md +48 -0
  123. package/docs/en/slide/slide-chart-insight.md +52 -0
  124. package/docs/en/slide/slide-columns.md +46 -0
  125. package/docs/en/slide/slide-comparison.md +68 -0
  126. package/docs/en/slide/slide-cover.md +39 -0
  127. package/docs/en/slide/slide-exec-summary.md +47 -0
  128. package/docs/en/slide/slide-heading.md +38 -0
  129. package/docs/en/slide/slide-kpi-grid.md +55 -0
  130. package/docs/en/slide/slide-kpi-hero.md +58 -0
  131. package/docs/en/slide/slide-next-actions.md +49 -0
  132. package/docs/en/slide/slide-scorecard-table.md +54 -0
  133. package/docs/en/slide/slide-section.md +44 -0
  134. package/docs/en/slide/slide-source-line.md +34 -0
  135. package/docs/en/ui/alert-dialog.md +42 -0
  136. package/docs/en/ui/avatar.md +31 -0
  137. package/docs/en/ui/combobox.md +74 -0
  138. package/docs/en/ui/drawer.md +41 -0
  139. package/docs/en/ui/empty.md +1 -1
  140. package/docs/en/ui/error-state.md +4 -3
  141. package/docs/en/ui/field.md +42 -0
  142. package/docs/en/ui/hover-card.md +21 -0
  143. package/docs/en/ui/kbd.md +17 -0
  144. package/docs/en/ui/loading.md +1 -1
  145. package/docs/en/ui/pagination.md +36 -0
  146. package/docs/en/ui/radio-group.md +21 -0
  147. package/docs/en/ui/toast.md +44 -0
  148. package/docs/en/ui/toggle-group.md +4 -3
  149. package/docs/en/ui-and-theming.md +1 -1
  150. package/docs/index.json +1184 -114
  151. package/docs/ja/agent-skills.md +1 -1
  152. package/docs/ja/changelog.md +33 -0
  153. package/docs/ja/components.md +68 -101
  154. package/docs/ja/doc/delta-text.md +40 -0
  155. package/docs/ja/doc/doc-action-items.md +49 -0
  156. package/docs/ja/doc/doc-callout.md +38 -0
  157. package/docs/ja/doc/doc-data-table.md +60 -0
  158. package/docs/ja/doc/doc-executive-summary.md +64 -0
  159. package/docs/ja/doc/doc-figure.md +56 -0
  160. package/docs/ja/doc/doc-key-findings.md +61 -0
  161. package/docs/ja/doc/doc-kpi-scorecard.md +80 -0
  162. package/docs/ja/doc/doc-notes-and-sources.md +43 -0
  163. package/docs/ja/doc/doc-report-header.md +46 -0
  164. package/docs/ja/page-types/csv.md +83 -0
  165. package/docs/ja/page-types/doc.md +83 -0
  166. package/docs/ja/page-types/excel.md +82 -0
  167. package/docs/ja/page-types/slide.md +133 -0
  168. package/docs/ja/page-types.md +47 -0
  169. package/docs/ja/pages-and-metadata.md +15 -0
  170. package/docs/ja/parts/area-chart.md +85 -0
  171. package/docs/ja/parts/bar-chart.md +95 -0
  172. package/docs/ja/parts/bar-list.md +58 -0
  173. package/docs/ja/parts/category-bar.md +36 -0
  174. package/docs/ja/parts/chart-frame.md +36 -0
  175. package/docs/ja/parts/data-table.md +22 -0
  176. package/docs/ja/parts/delta.md +51 -0
  177. package/docs/ja/parts/donut-chart.md +66 -0
  178. package/docs/ja/parts/echart.md +3 -0
  179. package/docs/ja/parts/format.md +44 -0
  180. package/docs/ja/parts/funnel-steps.md +27 -8
  181. package/docs/ja/parts/heatmap.md +45 -0
  182. package/docs/ja/parts/kpi-card.md +56 -0
  183. package/docs/ja/parts/legend.md +36 -0
  184. package/docs/ja/parts/line-chart.md +84 -0
  185. package/docs/ja/parts/metric-value.md +3 -2
  186. package/docs/ja/parts/progress-circle.md +34 -0
  187. package/docs/ja/parts/sample-data.md +61 -0
  188. package/docs/ja/parts/scatter-chart.md +69 -0
  189. package/docs/ja/parts/sparkline.md +2 -2
  190. package/docs/ja/parts/tracker.md +32 -0
  191. package/docs/ja/parts/trend-indicator.md +17 -1
  192. package/docs/ja/parts/updated-at.md +27 -0
  193. package/docs/ja/parts/waterfall-chart.md +61 -0
  194. package/docs/ja/routing.md +8 -86
  195. package/docs/ja/slide/slide-chart-full.md +48 -0
  196. package/docs/ja/slide/slide-chart-insight.md +52 -0
  197. package/docs/ja/slide/slide-columns.md +46 -0
  198. package/docs/ja/slide/slide-comparison.md +68 -0
  199. package/docs/ja/slide/slide-cover.md +39 -0
  200. package/docs/ja/slide/slide-exec-summary.md +47 -0
  201. package/docs/ja/slide/slide-heading.md +38 -0
  202. package/docs/ja/slide/slide-kpi-grid.md +55 -0
  203. package/docs/ja/slide/slide-kpi-hero.md +58 -0
  204. package/docs/ja/slide/slide-next-actions.md +49 -0
  205. package/docs/ja/slide/slide-scorecard-table.md +54 -0
  206. package/docs/ja/slide/slide-section.md +44 -0
  207. package/docs/ja/slide/slide-source-line.md +34 -0
  208. package/docs/ja/ui/alert-dialog.md +41 -0
  209. package/docs/ja/ui/avatar.md +31 -0
  210. package/docs/ja/ui/combobox.md +74 -0
  211. package/docs/ja/ui/drawer.md +41 -0
  212. package/docs/ja/ui/empty.md +1 -1
  213. package/docs/ja/ui/error-state.md +4 -3
  214. package/docs/ja/ui/field.md +42 -0
  215. package/docs/ja/ui/hover-card.md +21 -0
  216. package/docs/ja/ui/kbd.md +16 -0
  217. package/docs/ja/ui/loading.md +1 -1
  218. package/docs/ja/ui/pagination.md +36 -0
  219. package/docs/ja/ui/radio-group.md +21 -0
  220. package/docs/ja/ui/toast.md +46 -0
  221. package/docs/ja/ui/toggle-group.md +4 -3
  222. package/docs/ja/ui-and-theming.md +14 -7
  223. package/package.json +33 -23
  224. package/registry/ui/accordion.tsx +76 -0
  225. package/registry/ui/alert-dialog.tsx +189 -0
  226. package/registry/ui/alert.tsx +80 -0
  227. package/registry/ui/app-shell.tsx +287 -0
  228. package/registry/ui/area-chart.tsx +3701 -0
  229. package/registry/ui/attention-list.tsx +303 -0
  230. package/registry/ui/avatar.tsx +110 -0
  231. package/registry/ui/badge.tsx +56 -0
  232. package/registry/ui/bar-chart.tsx +3698 -0
  233. package/registry/ui/bar-list.tsx +3743 -0
  234. package/registry/ui/box-plot-chart.tsx +3906 -0
  235. package/registry/ui/breadcrumb.tsx +128 -0
  236. package/registry/ui/button.tsx +62 -0
  237. package/registry/ui/calendar.tsx +223 -0
  238. package/registry/ui/card.tsx +107 -0
  239. package/registry/ui/category-bar.tsx +1290 -0
  240. package/registry/ui/chart-frame.tsx +1393 -0
  241. package/registry/ui/checkbox.tsx +30 -0
  242. package/registry/ui/collapsible.tsx +23 -0
  243. package/registry/ui/combobox.tsx +310 -0
  244. package/registry/ui/command.tsx +198 -0
  245. package/registry/ui/dashboard-card.tsx +217 -0
  246. package/registry/ui/data-table.tsx +693 -146
  247. package/registry/ui/date-range-picker.tsx +390 -0
  248. package/registry/ui/delta.tsx +191 -0
  249. package/registry/ui/dialog.tsx +161 -0
  250. package/registry/ui/donut-chart.tsx +3751 -0
  251. package/registry/ui/drawer.tsx +229 -0
  252. package/registry/ui/dropdown-menu.tsx +274 -0
  253. package/registry/ui/echart.tsx +1040 -0
  254. package/registry/ui/field.tsx +240 -0
  255. package/registry/ui/filter-bar.tsx +392 -0
  256. package/registry/ui/funnel-steps.tsx +3569 -0
  257. package/registry/ui/heatmap.tsx +1786 -0
  258. package/registry/ui/histogram-chart.tsx +3986 -0
  259. package/registry/ui/hover-card.tsx +52 -0
  260. package/registry/ui/input-group.tsx +160 -0
  261. package/registry/ui/input.tsx +24 -0
  262. package/registry/ui/kbd.tsx +30 -0
  263. package/registry/ui/kpi-card.tsx +704 -0
  264. package/registry/ui/label.tsx +22 -0
  265. package/registry/ui/legend.tsx +3563 -0
  266. package/registry/ui/line-chart.tsx +3699 -0
  267. package/registry/ui/metric-value.tsx +62 -0
  268. package/registry/ui/multi-select.tsx +232 -0
  269. package/registry/ui/page-shell.tsx +282 -0
  270. package/registry/ui/pagination.tsx +140 -0
  271. package/registry/ui/paired-chart.tsx +3827 -0
  272. package/registry/ui/placeholder.tsx +36 -0
  273. package/registry/ui/popover.tsx +92 -0
  274. package/registry/ui/progress-circle.tsx +867 -0
  275. package/registry/ui/progress.tsx +85 -0
  276. package/registry/ui/radio-group.tsx +39 -0
  277. package/registry/ui/sample-data.tsx +86 -0
  278. package/registry/ui/scatter-chart.tsx +4212 -0
  279. package/registry/ui/scroll-area.tsx +56 -0
  280. package/registry/ui/searchable-select.tsx +214 -0
  281. package/registry/ui/section-header.tsx +43 -0
  282. package/registry/ui/segmented-control.tsx +76 -0
  283. package/registry/ui/select.tsx +255 -0
  284. package/registry/ui/separator.tsx +27 -0
  285. package/registry/ui/sheet.tsx +139 -0
  286. package/registry/ui/sidebar.tsx +725 -0
  287. package/registry/ui/skeleton.tsx +17 -0
  288. package/registry/ui/slider.tsx +56 -0
  289. package/registry/ui/sparkline.tsx +230 -0
  290. package/registry/ui/spinner.tsx +14 -0
  291. package/registry/ui/states.tsx +90 -0
  292. package/registry/ui/status-badge.tsx +121 -0
  293. package/registry/ui/switch.tsx +34 -0
  294. package/registry/ui/table.tsx +118 -0
  295. package/registry/ui/tabs.tsx +84 -0
  296. package/registry/ui/textarea.tsx +22 -0
  297. package/registry/ui/toast.tsx +250 -0
  298. package/registry/ui/toggle-group.tsx +91 -0
  299. package/registry/ui/toggle.tsx +47 -0
  300. package/registry/ui/tooltip.tsx +72 -0
  301. package/registry/ui/tracker.tsx +849 -0
  302. package/registry/ui/trend-indicator.tsx +74 -0
  303. package/registry/ui/updated-at.tsx +122 -0
  304. package/registry/ui/waterfall-chart.tsx +4248 -0
  305. package/skills/vantage-add-feature/SKILL.md +9 -7
  306. package/skills/vantage-design/SKILL.md +60 -52
  307. package/skills/vantage-design/references/extract.md +26 -27
  308. package/skills/vantage-design/references/format.md +12 -172
  309. package/skills/vantage-design/references/presets.md +50 -110
  310. package/skills/vantage-pitfalls/SKILL.md +10 -1
  311. package/skills/vantage-slide/SKILL.md +54 -36
  312. package/templates/AGENTS.md +53 -16
  313. package/templates/agents/csv.md +2 -1
  314. package/templates/agents/doc.md +52 -3
  315. package/templates/agents/page.md +53 -8
  316. package/templates/agents/slide.md +77 -3
  317. package/templates/agents/xlsx.md +2 -1
  318. package/theme.css +247 -138
  319. package/dist/add-DY4AXANK.js +0 -6
  320. package/dist/add-DY4AXANK.js.map +0 -1
  321. package/dist/chunk-5ZOP4SQR.js.map +0 -1
  322. package/dist/chunk-A2UUGASH.js.map +0 -1
  323. package/dist/chunk-CEXAQQ5W.js.map +0 -1
  324. package/dist/chunk-DTDVSFRY.js +0 -29
  325. package/dist/chunk-DTDVSFRY.js.map +0 -1
  326. package/dist/chunk-JKLLFVEU.js.map +0 -1
  327. package/dist/chunk-LMUACBMA.js.map +0 -1
  328. package/dist/chunk-NKFBFDRZ.js +0 -2241
  329. package/dist/chunk-NKFBFDRZ.js.map +0 -1
  330. package/dist/chunk-P7W4LR3Z.js.map +0 -1
  331. package/dist/chunk-PVTHHV7X.js.map +0 -1
  332. package/dist/chunk-PXRX5PEC.js.map +0 -1
  333. package/dist/chunk-QI3XQKHS.js.map +0 -1
  334. package/dist/chunk-RPZAALCX.js.map +0 -1
  335. package/dist/chunk-VA776YE5.js +0 -316
  336. package/dist/chunk-VA776YE5.js.map +0 -1
  337. package/dist/dev-GDKATCC7.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { SRC_DIR, RESERVED_PAGE_NAMES, PAGE_VARIANTS, UNSUPPORTED_PAGE_EXTENSIONS, NON_ROUTE_DIRS, PAGE_EXTENSIONS, FILE_PAGE_EXTENSIONS, API_EXTENSIONS } from './chunk-C2CX6GLX.js';
1
+ import { PAGE_VARIANTS, SRC_DIR, PAGE_EXTENSIONS, RESERVED_PAGE_NAMES, UNSUPPORTED_PAGE_EXTENSIONS, API_EXTENSIONS, NON_ROUTE_DIRS, FILE_PAGE_EXTENSIONS } from './chunk-C2CX6GLX.js';
2
2
  import fs from 'fs';
3
3
  import path from 'path';
4
4
 
@@ -244,6 +244,6 @@ function scanProject(root) {
244
244
  });
245
245
  }
246
246
 
247
- export { resolvePageRoot, scanProject, timed, timedAsync };
248
- //# sourceMappingURL=chunk-ZVANIULZ.js.map
249
- //# sourceMappingURL=chunk-ZVANIULZ.js.map
247
+ export { displayPath, fileToSegments, resolvePageRoot, routeSortKey, scanProject, splitPageVariant, stripExt, timed, timedAsync };
248
+ //# sourceMappingURL=chunk-RNTDBX6S.js.map
249
+ //# sourceMappingURL=chunk-RNTDBX6S.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/profile.ts","../src/core/scan.ts"],"names":[],"mappings":";;;;;;;AAQA,IAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,eAAe,CAAA;AAKnD,SAAS,MAAA,CAAO,OAAe,EAAA,EAAkB;AAC/C,EAAA,MAAM,SAAS,WAAA,CAAY,GAAA,EAAI,GAAI,GAAA,EAAM,QAAQ,CAAC,CAAA;AAClD,EAAA,OAAA,CAAQ,OAAO,KAAA,CAAM,CAAA,kBAAA,EAAqB,KAAA,CAAM,MAAA,CAAO,EAAE,CAAC,CAAA,CAAA,EAAI,EAAA,CAAG,OAAA,CAAQ,CAAC,CAAA,CAAE,QAAA,CAAS,CAAC,CAAC,QAAQ,KAAK,CAAA;AAAA,CAAK,CAAA;AAC3G;AAGO,SAAS,KAAA,CAAS,OAAe,EAAA,EAAgB;AACtD,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,EAAA,EAAG;AACxB,EAAA,MAAM,EAAA,GAAK,YAAY,GAAA,EAAI;AAC3B,EAAA,IAAI;AACF,IAAA,OAAO,EAAA,EAAG;AAAA,EACZ,CAAA,SAAE;AACA,IAAA,MAAA,CAAO,KAAA,EAAO,WAAA,CAAY,GAAA,EAAI,GAAI,EAAE,CAAA;AAAA,EACtC;AACF;AAGA,eAAsB,UAAA,CAAc,OAAe,EAAA,EAAkC;AACnF,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,EAAA,EAAG;AACxB,EAAA,MAAM,EAAA,GAAK,YAAY,GAAA,EAAI;AAC3B,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,EAAA,EAAG;AAAA,EAClB,CAAA,SAAE;AACA,IAAA,MAAA,CAAO,KAAA,EAAO,WAAA,CAAY,GAAA,EAAI,GAAI,EAAE,CAAA;AAAA,EACtC;AACF;ACdA,SAAS,OAAA,CAAQ,MAAc,GAAA,EAAqB;AAClD,EAAA,OAAO,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,GAAG,CAAA,CAAE,MAAM,IAAA,CAAK,GAAG,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAC1D;AAGA,SAAS,gBAAgB,GAAA,EAAsB;AAC7C,EAAA,MAAM,QAAA,GAAW,GAAA,CAAI,KAAA,CAAM,kBAAkB,CAAA;AAC7C,EAAA,IAAI,QAAA,SAAiB,EAAE,IAAA,EAAM,YAAY,IAAA,EAAM,QAAA,CAAS,CAAC,CAAA,EAAG;AAC5D,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,YAAY,CAAA;AACpC,EAAA,IAAI,KAAA,SAAc,EAAE,IAAA,EAAM,SAAS,IAAA,EAAM,KAAA,CAAM,CAAC,CAAA,EAAG;AACnD,EAAA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,GAAA,EAAI;AACtC;AAGA,SAAS,YAAY,QAAA,EAA6B;AAChD,EAAA,IAAI,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG,OAAO,GAAA;AAClC,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM;AAChC,IAAA,IAAI,CAAA,CAAE,IAAA,KAAS,QAAA,EAAU,OAAO,CAAA,CAAE,KAAA;AAClC,IAAA,IAAI,EAAE,IAAA,KAAS,OAAA,EAAS,OAAO,CAAA,CAAA,EAAI,EAAE,IAAI,CAAA,CAAA;AACzC,IAAA,OAAO,GAAA;AAAA,EACT,CAAC,CAAA;AACD,EAAA,OAAO,GAAA,GAAM,KAAA,CAAM,IAAA,CAAK,GAAG,CAAA;AAC7B;AAGA,SAAS,eAAe,QAAA,EAA6B;AACnD,EAAA,MAAM,GAAA,GAAM,QAAA,CAAS,KAAA,CAAM,GAAG,CAAA;AAE9B,EAAA,IAAI,IAAI,GAAA,CAAI,MAAA,GAAS,CAAC,CAAA,KAAM,OAAA,MAAa,GAAA,EAAI;AAC7C,EAAA,OAAO,GAAA,CAAI,IAAI,eAAe,CAAA;AAChC;AAGA,SAAS,QAAA,CAAS,MAAc,IAAA,EAAwB;AACtD,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAG,OAAO,KAAK,KAAA,CAAM,CAAA,EAAG,CAAC,GAAA,CAAI,MAAM,CAAA;AAAA,EAC1D;AACA,EAAA,OAAO,IAAA;AACT;AAOO,SAAS,iBAAiB,SAAA,EAAkE;AACjG,EAAA,KAAA,MAAW,WAAW,aAAA,EAAe;AACnC,IAAA,MAAM,MAAA,GAAS,IAAI,OAAO,CAAA,CAAA;AAC1B,IAAA,IAAI,UAAU,QAAA,CAAS,MAAM,KAAK,SAAA,CAAU,MAAA,GAAS,OAAO,MAAA,EAAQ;AAClE,MAAA,OAAO,EAAE,MAAM,SAAA,CAAU,KAAA,CAAM,GAAG,CAAC,MAAA,CAAO,MAAM,CAAA,EAAG,OAAA,EAAQ;AAAA,IAC7D;AAAA,EACF;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,OAAA,EAAS,IAAA,EAAK;AAC1C;AAQA,SAAS,iBAAiB,IAAA,EAAuC;AAC/D,EAAA,MAAM,KAAA,GAAQ,KAAK,WAAA,EAAY;AAC/B,EAAA,OAAO,qBAAqB,IAAA,CAAK,CAAC,QAAQ,KAAA,CAAM,QAAA,CAAS,GAAG,CAAC,CAAA;AAC/D;AAGA,SAAS,WAAW,IAAA,EAAuB;AACzC,EAAA,OAAO,IAAA,CAAK,WAAW,IAAI,CAAA;AAC7B;AAEA,SAAS,MAAA,CAAO,MAAc,IAAA,EAAyB;AACrD,EAAA,OAAO,KAAK,IAAA,CAAK,CAAC,QAAQ,IAAA,CAAK,QAAA,CAAS,GAAG,CAAC,CAAA;AAC9C;AAGA,SAAS,IAAA,CAAK,GAAA,EAAa,IAAA,EAAc,GAAA,EAAqB;AAC5D,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI;AACF,IAAA,OAAA,GAAU,GAAG,WAAA,CAAY,GAAA,EAAK,EAAE,aAAA,EAAe,MAAM,CAAA;AAAA,EACvD,CAAA,CAAA,MAAQ;AACN,IAAA;AAAA,EACF;AACA,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,MAAM,IAAI,CAAA;AACrC,IAAA,IAAI,KAAA,CAAM,aAAY,EAAG;AACvB,MAAA,IAAI,cAAA,CAAe,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,EAAG;AACpC,MAAA,IAAI,KAAA,CAAM,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,EAAG;AAChC,MAAA,IAAA,CAAK,GAAA,EAAK,MAAM,GAAG,CAAA;AAAA,IACrB,CAAA,MAAA,IAAW,KAAA,CAAM,MAAA,EAAO,EAAG;AACzB,MAAA,GAAA,CAAI,KAAK,GAAG,CAAA;AAAA,IACd;AAAA,EACF;AACF;AAOO,SAAS,gBAAgB,IAAA,EAA4C;AAC1E,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,OAAO,CAAA;AACnC,EAAA,IAAI;AACF,IAAA,IAAI,EAAA,CAAG,QAAA,CAAS,GAAG,CAAA,CAAE,WAAA,IAAe,OAAO,EAAE,GAAA,EAAK,OAAA,EAAS,GAAA,EAAI;AAAA,EACjE,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,EAAE,GAAA,EAAK,EAAA,EAAI,GAAA,EAAK,IAAA,EAAK;AAC9B;AASA,SAAS,SAAA,CACP,MACA,QAAA,EAOA;AACA,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,IAAA,CAAK,QAAA,EAAU,UAAU,KAAK,CAAA;AAE9B,EAAA,MAAM,QAAqB,EAAC;AAC5B,EAAA,MAAM,UAAyB,EAAC;AAChC,EAAA,MAAM,WAA2B,EAAC;AAClC,EAAA,IAAI,QAAA,GAA0B,IAAA;AAC9B,EAAA,IAAI,KAAA,GAAuB,IAAA;AAE3B,EAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAA;AAC9B,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,QAAA,EAAU,GAAG,CAAA;AACjC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,GAAG,CAAA;AACpC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA;AAClC,IAAA,MAAM,QAAA,GAAW,GAAA,KAAQ,GAAA,GAAM,EAAA,GAAK,GAAA;AAEpC,IAAA,IAAI,MAAA,CAAO,IAAA,EAAM,eAAe,CAAA,EAAG;AACjC,MAAA,MAAM,SAAA,GAAY,QAAA,CAAS,IAAA,EAAM,eAAe,CAAA;AAIhD,MAAA,IAAI,SAAA,KAAc,oBAAoB,MAAA,EAAQ;AAC5C,QAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,SAAS,GAAA,EAAK,GAAA,EAAK,UAAU,CAAA;AAClD,QAAA;AAAA,MACF;AACA,MAAA,IAAI,SAAA,KAAc,oBAAoB,QAAA,EAAU;AAC9C,QAAA,IAAI,QAAA,KAAa,IAAI,QAAA,GAAW,IAAA;AAChC,QAAA;AAAA,MACF;AACA,MAAA,IAAI,SAAA,KAAc,oBAAoB,KAAA,EAAO;AAC3C,QAAA,IAAI,QAAA,KAAa,IAAI,KAAA,GAAQ,IAAA;AAC7B,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAU,OAAA,EAAQ,GAAI,iBAAiB,SAAS,CAAA;AAI9D,MAAA,IAAI,QAAA,CAAS,UAAA,CAAW,GAAG,CAAA,EAAG;AAC5B,QAAA,IAAI,OAAA,WAAkB,IAAA,CAAK,EAAE,MAAM,MAAA,EAAQ,SAAA,EAAW,SAAS,CAAA;AAC/D,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,QAAA,GAAW,QAAA,CAAS,GAAA,EAAK,eAAe,CAAA;AAG9C,MAAA,MAAM,cAAA,GAAiB,UAAU,QAAA,CAAS,KAAA,CAAM,GAAG,EAAE,OAAA,CAAQ,MAAA,GAAS,CAAA,CAAE,CAAA,GAAI,QAAA;AAC5E,MAAA,MAAM,QAAA,GAAW,eAAe,cAAc,CAAA;AAC9C,MAAA,MAAM,SAAA,GAAY,YAAY,QAAQ,CAAA;AACtC,MAAA,MAAM,UAAU,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,QAAQ,CAAA;AACxD,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,IAAA;AAAA,QACA,OAAA,EAAS,GAAA;AAAA,QACT,SAAA;AAAA,QACA,QAAA;AAAA,QACA,GAAA,EAAK,QAAA;AAAA,QACL,OAAA;AAAA,QACA,IAAA,EAAM,QAAA;AAAA,QACN,GAAI,OAAA,GAAU,EAAE,OAAA,KAAY;AAAC,OAC9B,CAAA;AACD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAU,iBAAiB,IAAI,CAAA;AACrC,IAAA,IAAI,OAAA,EAAS;AAEX,MAAA,IAAI,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,IAAK,IAAA,CAAK,WAAW,GAAG,CAAA,IAAK,UAAA,CAAW,IAAI,CAAA,EAAG;AACtE,MAAA,MAAM,WAAW,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,CAAC,QAAQ,MAAM,CAAA;AAC7C,MAAA,MAAM,QAAA,GAAW,eAAe,QAAQ,CAAA;AACxC,MAAA,MAAM,SAAA,GAAY,YAAY,QAAQ,CAAA;AACtC,MAAA,MAAM,UAAU,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,QAAQ,CAAA;AACxD,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,IAAA;AAAA,QACA,OAAA,EAAS,GAAA;AAAA,QACT,SAAA;AAAA,QACA,QAAA;AAAA,QACA,GAAA,EAAK,QAAA;AAAA,QACL,OAAA;AAAA,QACA,IAAA,EAAM,MAAA;AAAA,QACN;AAAA,OACD,CAAA;AACD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAAQ,KAAK,WAAA,EAAY;AAG/B,IAAA,MAAM,YAAA,GAAe,aAAA,CAAc,IAAA,CAAK,CAAC,CAAA,KAAM,MAAM,QAAA,CAAS,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,CAAG,CAAC,CAAA;AACvE,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,QAAA,CAAS,KAAK,EAAE,IAAA,EAAM,QAAQ,SAAA,EAAW,OAAA,EAAS,cAAc,CAAA;AAAA,IAClE,CAAA,MAAA,IAAW,4BAA4B,IAAA,CAAK,CAAC,QAAQ,KAAA,CAAM,QAAA,CAAS,GAAG,CAAC,CAAA,EAAG;AACzE,MAAA,QAAA,CAAS,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,aAAa,CAAA;AAAA,IAC7C;AAAA,EACF;AAIA,EAAA,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,YAAA,CAAa,CAAC,CAAA,CAAE,aAAA,CAAc,YAAA,CAAa,CAAC,CAAC,CAAC,CAAA;AACnE,EAAA,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,GAAA,CAAI,aAAA,CAAc,CAAA,CAAE,GAAG,CAAC,CAAA;AACjD,EAAA,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,IAAA,CAAK,aAAA,CAAc,CAAA,CAAE,IAAI,CAAC,CAAA;AACpD,EAAA,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,QAAA,EAAU,OAAO,QAAA,EAAS;AACrD;AAGA,SAAS,aAAa,CAAA,EAAsB;AAC1C,EAAA,OAAO,EAAE,QAAA,CACN,GAAA,CAAI,CAAC,CAAA,KAAO,CAAA,CAAE,SAAS,QAAA,GAAW,GAAA,GAAM,CAAA,CAAE,KAAA,GAAQ,EAAE,IAAA,KAAS,OAAA,GAAU,MAAM,GAAI,CAAA,CACjF,KAAK,GAAG,CAAA;AACb;AAGA,SAAS,SAAS,IAAA,EAA0B;AAC1C,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,UAAU,KAAK,CAAA;AAC9C,EAAA,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,MAAM,CAAA,SAAU,EAAC;AAEpC,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,MAAM,OAAA,GAAU,CAAC,GAAA,KAAgB;AAC/B,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAA,GAAU,GAAG,WAAA,CAAY,GAAA,EAAK,EAAE,aAAA,EAAe,MAAM,CAAA;AAAA,IACvD,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AACA,IAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,MAAM,IAAI,CAAA;AACrC,MAAA,IAAI,KAAA,CAAM,WAAA,EAAY,EAAG,OAAA,CAAQ,GAAG,CAAA;AAAA,WAAA,IAC3B,KAAA,CAAM,MAAA,EAAO,EAAG,KAAA,CAAM,KAAK,GAAG,CAAA;AAAA,IACzC;AAAA,EACF,CAAA;AACA,EAAA,OAAA,CAAQ,MAAM,CAAA;AAEd,EAAA,MAAM,OAAmB,EAAC;AAC1B,EAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA;AAC9B,IAAA,IAAI,CAAC,MAAA,CAAO,IAAA,EAAM,cAAc,CAAA,EAAG;AACnC,IAAA,MAAM,SAAA,GAAY,QAAA,CAAS,IAAA,EAAM,cAAc,CAAA;AAE/C,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,EAAG;AAC5B,IAAA,IAAI,SAAA,CAAU,UAAA,CAAW,GAAG,CAAA,EAAG;AAE/B,IAAA,MAAM,gBAAgB,OAAA,CAAQ,IAAA,CAAK,KAAK,IAAA,EAAM,QAAQ,GAAG,GAAG,CAAA;AAC5D,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,aAAA,EAAe,cAAc,CAAA;AACvD,IAAA,MAAM,gBAAA,GAAmB,QAAA,CAAS,OAAA,CAAQ,SAAA,EAAW,EAAE,CAAA;AACvD,IAAA,MAAM,YAAY,gBAAA,KAAqB,EAAA,GAAK,EAAC,GAAI,gBAAA,CAAiB,MAAM,GAAG,CAAA;AAC3E,IAAA,IAAI,UAAU,SAAA,CAAU,MAAA,GAAS,CAAC,CAAA,KAAM,OAAA,YAAmB,GAAA,EAAI;AAC/D,IAAA,MAAM,QAAA,GAAW,SAAA,CAAU,GAAA,CAAI,eAAe,CAAA;AAC9C,IAAA,MAAM,YAAY,MAAA,IAAU,QAAA,CAAS,MAAA,GAAS,WAAA,CAAY,QAAQ,CAAA,GAAI,EAAA,CAAA;AACtE,IAAA,MAAM,MAAA,GAAS,QAAA,CACZ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,QAAQ,CAAA,CACjC,GAAA,CAAI,CAAC,CAAA,KAAO,EAAuB,IAAI,CAAA;AAE1C,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,IAAA,EAAM,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAA;AAAA,MACvB,OAAA,EAAS,GAAA;AAAA,MACT,SAAA;AAAA,MACA,OAAA,EAAS,SAAA;AAAA,MACT,QAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,SAAA,CAAU,aAAA,CAAc,CAAA,CAAE,SAAS,CAAC,CAAA;AAC1D,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,YAAY,IAAA,EAA0B;AACpD,EAAA,OAAO,KAAA,CAAM,QAAQ,MAAM;AACzB,IAAA,MAAM,QAAA,GAAW,gBAAgB,IAAI,CAAA;AACrC,IAAA,MAAM,EAAE,KAAA,EAAO,OAAA,EAAS,QAAA,EAAU,KAAA,EAAO,UAAS,GAAI,SAAA,CAAU,IAAA,EAAM,QAAA,CAAS,GAAG,CAAA;AAGlF,IAAA,MAAM,YAAY,EAAA,CAAG,UAAA,CAAW,KAAK,IAAA,CAAK,IAAA,EAAM,QAAQ,CAAC,CAAA;AACzD,IAAA,MAAM,IAAA,GAAO,SAAA,GAAY,QAAA,CAAS,IAAI,IAAI,EAAC;AAC3C,IAAA,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,QAAA,EAAU,KAAA,EAAO,MAAM,SAAA,EAAW,OAAA,EAAS,QAAA,CAAS,GAAA,EAAK,QAAA,EAAS;AAAA,EAC7F,CAAC,CAAA;AACH","file":"chunk-ZVANIULZ.js","sourcesContent":["/**\n * Opt-in phase timing, enabled with `VANTAGE_PROFILE=1`.\n *\n * Every line goes to **stderr**, so turning it on never corrupts the `--json`\n * payloads other commands write to stdout. Disabled, `timed()` is a direct call\n * through — no timers, no allocation.\n */\n\nconst ENABLED = Boolean(process.env.VANTAGE_PROFILE)\n\n/** Whether profiling output is on. Cheap enough to branch on in hot paths. */\nexport const profiling = ENABLED\n\nfunction report(label: string, ms: number): void {\n const since = (performance.now() / 1000).toFixed(3)\n process.stderr.write(`[vantage:profile] ${label.padEnd(24)} ${ms.toFixed(1).padStart(8)}ms @${since}s\\n`)\n}\n\n/** Time a synchronous phase. */\nexport function timed<T>(label: string, fn: () => T): T {\n if (!ENABLED) return fn()\n const t0 = performance.now()\n try {\n return fn()\n } finally {\n report(label, performance.now() - t0)\n }\n}\n\n/** Time an asynchronous phase. */\nexport async function timedAsync<T>(label: string, fn: () => Promise<T>): Promise<T> {\n if (!ENABLED) return fn()\n const t0 = performance.now()\n try {\n return await fn()\n } finally {\n report(label, performance.now() - t0)\n }\n}\n\n/** Record a one-off duration measured by the caller. */\nexport function note(label: string, ms: number): void {\n if (ENABLED) report(label, ms)\n}\n","import fs from \"node:fs\"\nimport path from \"node:path\"\nimport {\n API_EXTENSIONS,\n FILE_PAGE_EXTENSIONS,\n NON_ROUTE_DIRS,\n PAGE_EXTENSIONS,\n PAGE_VARIANTS,\n RESERVED_PAGE_NAMES,\n SRC_DIR,\n UNSUPPORTED_PAGE_EXTENSIONS,\n} from \"./constants\"\nimport type { FilePageExt, PageVariant } from \"./constants\"\nimport { timed } from \"./profile\"\nimport type {\n ApiRoute,\n LayoutRoute,\n PageRoute,\n RouteModel,\n Segment,\n UnroutedFile,\n} from \"./types\"\n\n/** Convert an absolute path to a project-relative POSIX path. */\nfunction toPosix(root: string, abs: string): string {\n return path.relative(root, abs).split(path.sep).join(\"/\")\n}\n\n/** Parse one raw path token into a segment descriptor. */\nfunction parseRawSegment(raw: string): Segment {\n const catchall = raw.match(/^\\[\\.\\.\\.(.+)\\]$/)\n if (catchall) return { kind: \"catchall\", name: catchall[1]! }\n const param = raw.match(/^\\[(.+)\\]$/)\n if (param) return { kind: \"param\", name: param[1]! }\n return { kind: \"static\", value: raw }\n}\n\n/** Build a human/display route path from segments. */\nfunction displayPath(segments: Segment[]): string {\n if (segments.length === 0) return \"/\"\n const parts = segments.map((s) => {\n if (s.kind === \"static\") return s.value\n if (s.kind === \"param\") return `:${s.name}`\n return \"*\"\n })\n return \"/\" + parts.join(\"/\")\n}\n\n/** Split a relative POSIX file (without extension) into route segments. */\nfunction fileToSegments(relNoExt: string): Segment[] {\n const raw = relNoExt.split(\"/\")\n // A trailing `index` maps to its directory (drop it).\n if (raw[raw.length - 1] === \"index\") raw.pop()\n return raw.map(parseRawSegment)\n}\n\n/** Strip a known extension from a filename. */\nfunction stripExt(file: string, exts: string[]): string {\n for (const ext of exts) {\n if (file.endsWith(ext)) return file.slice(0, -ext.length)\n }\n return file\n}\n\n/**\n * Split a page-kind suffix off a name that has already lost its extension:\n * `june.slide` -> `{ base: \"june\", variant: \"slide\" }`, `june` -> variant null.\n * A bare `.slide.tsx` (empty base) is a nameless page, not a variant.\n */\nexport function splitPageVariant(nameNoExt: string): { base: string; variant: PageVariant | null } {\n for (const variant of PAGE_VARIANTS) {\n const suffix = `.${variant}`\n if (nameNoExt.endsWith(suffix) && nameNoExt.length > suffix.length) {\n return { base: nameNoExt.slice(0, -suffix.length), variant }\n }\n }\n return { base: nameNoExt, variant: null }\n}\n\n/**\n * Case-insensitive match against the data-file extensions, returning the\n * canonical (lowercased) form. `stripExt` cannot be reused here: it matches\n * case-sensitively, and `REPORT.CSV` must still lose exactly its extension\n * while its stem keeps its own case.\n */\nfunction matchFilePageExt(base: string): FilePageExt | undefined {\n const lower = base.toLowerCase()\n return FILE_PAGE_EXTENSIONS.find((ext) => lower.endsWith(ext))\n}\n\n/** Excel and Numbers drop a `~$book.xlsx` lock file while a workbook is open. */\nfunction isLockFile(base: string): boolean {\n return base.startsWith(\"~$\")\n}\n\nfunction hasExt(file: string, exts: string[]): boolean {\n return exts.some((ext) => file.endsWith(ext))\n}\n\n/** Recursively collect files under a directory, respecting ignore rules. */\nfunction walk(dir: string, root: string, out: string[]): void {\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n return\n }\n for (const entry of entries) {\n const abs = path.join(dir, entry.name)\n if (entry.isDirectory()) {\n if (NON_ROUTE_DIRS.has(entry.name)) continue\n if (entry.name.startsWith(\".\")) continue\n walk(abs, root, out)\n } else if (entry.isFile()) {\n out.push(abs)\n }\n }\n}\n\n/**\n * Decide where pages are scanned from: `<root>/src` when that directory exists,\n * the project root otherwise. The two never mix — a project that has `src/`\n * keeps every page inside it (`SRC_DIR_SPLIT` reports the leftovers).\n */\nexport function resolvePageRoot(root: string): { dir: string; abs: string } {\n const abs = path.join(root, SRC_DIR)\n try {\n if (fs.statSync(abs).isDirectory()) return { dir: SRC_DIR, abs }\n } catch {\n /* no src/ — pages live at the project root */\n }\n return { dir: \"\", abs: root }\n}\n\n/**\n * Discover page and layout routes under the page root. `file` stays relative to\n * the *project* root (generated imports resolve from `.vantage/`), while\n * `dir`/`segments`/`routePath` are relative to the *page* root so that `src/`\n * never leaks into a URL — and so `dir` keeps matching `segments` one-to-one,\n * which is how `buildRouteTree` pairs pages with their layouts.\n */\nfunction scanPages(\n root: string,\n pageRoot: string,\n): {\n pages: PageRoute[]\n layouts: LayoutRoute[]\n notFound: string | null\n error: string | null\n unrouted: UnroutedFile[]\n} {\n const files: string[] = []\n walk(pageRoot, pageRoot, files)\n\n const pages: PageRoute[] = []\n const layouts: LayoutRoute[] = []\n const unrouted: UnroutedFile[] = []\n let notFound: string | null = null\n let error: string | null = null\n\n for (const abs of files) {\n const file = toPosix(root, abs)\n const rel = toPosix(pageRoot, abs)\n const base = path.posix.basename(rel)\n const dir = path.posix.dirname(rel)\n const dirPosix = dir === \".\" ? \"\" : dir\n\n if (hasExt(base, PAGE_EXTENSIONS)) {\n const nameNoExt = stripExt(base, PAGE_EXTENSIONS)\n // Reserved modules are matched on the full name: `_layout.slide` is not\n // `_layout`, and a variant on a reserved module is an error the\n // diagnostics report rather than a route.\n if (nameNoExt === RESERVED_PAGE_NAMES.layout) {\n layouts.push({ file, absFile: abs, dir: dirPosix })\n continue\n }\n if (nameNoExt === RESERVED_PAGE_NAMES.notFound) {\n if (dirPosix === \"\") notFound = file\n continue\n }\n if (nameNoExt === RESERVED_PAGE_NAMES.error) {\n if (dirPosix === \"\") error = file\n continue\n }\n\n const { base: pageName, variant } = splitPageVariant(nameNoExt)\n // Any other underscore-prefixed file is a private module, not a route.\n // The test runs on the name with its variant suffix removed, so\n // `_layout.slide.tsx` and `_draft.slide.tsx` both drop out here.\n if (pageName.startsWith(\"_\")) {\n if (variant) unrouted.push({ file, reason: \"variant\", variant })\n continue\n }\n\n const relNoExt = stripExt(rel, PAGE_EXTENSIONS)\n // The variant suffix always sits at the end of the final token, so\n // trimming the tail is enough to keep it out of the URL.\n const relForSegments = variant ? relNoExt.slice(0, -(variant.length + 1)) : relNoExt\n const segments = fileToSegments(relForSegments)\n const routePath = displayPath(segments)\n const dynamic = segments.some((s) => s.kind !== \"static\")\n pages.push({\n file,\n absFile: abs,\n routePath,\n segments,\n dir: dirPosix,\n dynamic,\n kind: \"module\",\n ...(variant ? { variant } : {}),\n })\n continue\n }\n\n const fileExt = matchFilePageExt(base)\n if (fileExt) {\n // Same privacy rules as page modules, plus spreadsheet lock files.\n if (base.startsWith(\"_\") || base.startsWith(\".\") || isLockFile(base)) continue\n const relNoExt = rel.slice(0, -fileExt.length)\n const segments = fileToSegments(relNoExt)\n const routePath = displayPath(segments)\n const dynamic = segments.some((s) => s.kind !== \"static\")\n pages.push({\n file,\n absFile: abs,\n routePath,\n segments,\n dir: dirPosix,\n dynamic,\n kind: \"file\",\n fileExt,\n })\n continue\n }\n\n const lower = base.toLowerCase()\n // A page-kind suffix on something that is not a page module at all\n // (`deck.slide.ts`, `deck.slide.css`) is a typo worth naming.\n const strayVariant = PAGE_VARIANTS.find((v) => lower.includes(`.${v}.`))\n if (strayVariant) {\n unrouted.push({ file, reason: \"variant\", variant: strayVariant })\n } else if (UNSUPPORTED_PAGE_EXTENSIONS.some((ext) => lower.endsWith(ext))) {\n unrouted.push({ file, reason: \"extension\" })\n }\n }\n\n // Stable ordering: shallow before deep, static before dynamic, alpha. Data\n // files share the key, so they interleave with modules instead of clumping.\n pages.sort((a, b) => routeSortKey(a).localeCompare(routeSortKey(b)))\n layouts.sort((a, b) => a.dir.localeCompare(b.dir))\n unrouted.sort((a, b) => a.file.localeCompare(b.file))\n return { pages, layouts, notFound, error, unrouted }\n}\n\n/** Sort key that keeps static routes ahead of dynamic ones at each depth. */\nfunction routeSortKey(p: PageRoute): string {\n return p.segments\n .map((s) => (s.kind === \"static\" ? \"0\" + s.value : s.kind === \"param\" ? \"1\" : \"2\"))\n .join(\"/\")\n}\n\n/** Discover server API routes under `server/api`. */\nfunction scanApis(root: string): ApiRoute[] {\n const apiDir = path.join(root, \"server\", \"api\")\n if (!fs.existsSync(apiDir)) return []\n\n const files: string[] = []\n const walkApi = (dir: string) => {\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n return\n }\n for (const entry of entries) {\n const abs = path.join(dir, entry.name)\n if (entry.isDirectory()) walkApi(abs)\n else if (entry.isFile()) files.push(abs)\n }\n }\n walkApi(apiDir)\n\n const apis: ApiRoute[] = []\n for (const abs of files) {\n const base = path.basename(abs)\n if (!hasExt(base, API_EXTENSIONS)) continue\n const nameNoExt = stripExt(base, API_EXTENSIONS)\n // Type declaration files and private helpers are not routes.\n if (base.endsWith(\".d.ts\")) continue\n if (nameNoExt.startsWith(\"_\")) continue\n\n const relFromServer = toPosix(path.join(root, \"server\"), abs) // e.g. api/customers/[id].ts\n const relNoExt = stripExt(relFromServer, API_EXTENSIONS) // api/customers/[id]\n const withoutApiPrefix = relNoExt.replace(/^api\\/?/, \"\") // customers/[id] or \"\" for api/index\n const segTokens = withoutApiPrefix === \"\" ? [] : withoutApiPrefix.split(\"/\")\n if (segTokens[segTokens.length - 1] === \"index\") segTokens.pop()\n const segments = segTokens.map(parseRawSegment)\n const routePath = \"/api\" + (segments.length ? displayPath(segments) : \"\")\n const params = segments\n .filter((s) => s.kind !== \"static\")\n .map((s) => (s as { name: string }).name)\n\n apis.push({\n file: toPosix(root, abs),\n absFile: abs,\n routePath,\n pattern: routePath,\n segments,\n params,\n })\n }\n\n apis.sort((a, b) => a.routePath.localeCompare(b.routePath))\n return apis\n}\n\n/** Scan a project into a full route model. */\nexport function scanProject(root: string): RouteModel {\n return timed(\"scan\", () => {\n const pageRoot = resolvePageRoot(root)\n const { pages, layouts, notFound, error, unrouted } = scanPages(root, pageRoot.abs)\n // server/ is always at the project root: it is the other side of the\n // client/server boundary, not part of the client source tree.\n const hasServer = fs.existsSync(path.join(root, \"server\"))\n const apis = hasServer ? scanApis(root) : []\n return { pages, layouts, notFound, error, apis, hasServer, pageDir: pageRoot.dir, unrouted }\n })\n}\n\n/** Convert a display route path segment list into a TanStack Router path. */\nexport function toRouterPath(segments: Segment[]): string {\n if (segments.length === 0) return \"/\"\n const parts = segments.map((s) => {\n if (s.kind === \"static\") return s.value\n if (s.kind === \"param\") return `$${s.name}`\n return \"$\" // TanStack splat\n })\n return \"/\" + parts.join(\"/\")\n}\n"]}
1
+ {"version":3,"sources":["../src/core/profile.ts","../src/core/scan.ts"],"names":[],"mappings":"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","file":"chunk-RNTDBX6S.js","sourcesContent":["/**\n * Opt-in phase timing, enabled with `VANTAGE_PROFILE=1`.\n *\n * Every line goes to **stderr**, so turning it on never corrupts the `--json`\n * payloads other commands write to stdout. Disabled, `timed()` is a direct call\n * through — no timers, no allocation.\n */\n\nconst ENABLED = Boolean(process.env.VANTAGE_PROFILE)\n\n/** Whether profiling output is on. Cheap enough to branch on in hot paths. */\nexport const profiling = ENABLED\n\nfunction report(label: string, ms: number): void {\n const since = (performance.now() / 1000).toFixed(3)\n process.stderr.write(`[vantage:profile] ${label.padEnd(24)} ${ms.toFixed(1).padStart(8)}ms @${since}s\\n`)\n}\n\n/** Time a synchronous phase. */\nexport function timed<T>(label: string, fn: () => T): T {\n if (!ENABLED) return fn()\n const t0 = performance.now()\n try {\n return fn()\n } finally {\n report(label, performance.now() - t0)\n }\n}\n\n/** Time an asynchronous phase. */\nexport async function timedAsync<T>(label: string, fn: () => Promise<T>): Promise<T> {\n if (!ENABLED) return fn()\n const t0 = performance.now()\n try {\n return await fn()\n } finally {\n report(label, performance.now() - t0)\n }\n}\n\n/** Record a one-off duration measured by the caller. */\nexport function note(label: string, ms: number): void {\n if (ENABLED) report(label, ms)\n}\n","import fs from \"node:fs\"\nimport path from \"node:path\"\nimport {\n API_EXTENSIONS,\n FILE_PAGE_EXTENSIONS,\n NON_ROUTE_DIRS,\n PAGE_EXTENSIONS,\n PAGE_VARIANTS,\n RESERVED_PAGE_NAMES,\n SRC_DIR,\n UNSUPPORTED_PAGE_EXTENSIONS,\n} from \"./constants\"\nimport type { FilePageExt, PageVariant } from \"./constants\"\nimport { timed } from \"./profile\"\nimport type {\n ApiRoute,\n LayoutRoute,\n PageRoute,\n RouteModel,\n Segment,\n UnroutedFile,\n} from \"./types\"\n\n/** Convert an absolute path to a project-relative POSIX path. */\nfunction toPosix(root: string, abs: string): string {\n return path.relative(root, abs).split(path.sep).join(\"/\")\n}\n\n/** Parse one raw path token into a segment descriptor. */\nfunction parseRawSegment(raw: string): Segment {\n const catchall = raw.match(/^\\[\\.\\.\\.(.+)\\]$/)\n if (catchall) return { kind: \"catchall\", name: catchall[1]! }\n const param = raw.match(/^\\[(.+)\\]$/)\n if (param) return { kind: \"param\", name: param[1]! }\n return { kind: \"static\", value: raw }\n}\n\n/** Build a human/display route path from segments. */\nexport function displayPath(segments: Segment[]): string {\n if (segments.length === 0) return \"/\"\n const parts = segments.map((s) => {\n if (s.kind === \"static\") return s.value\n if (s.kind === \"param\") return `:${s.name}`\n return \"*\"\n })\n return \"/\" + parts.join(\"/\")\n}\n\n/** Split a relative POSIX file (without extension) into route segments. */\nexport function fileToSegments(relNoExt: string): Segment[] {\n const raw = relNoExt.split(\"/\")\n // A trailing `index` maps to its directory (drop it).\n if (raw[raw.length - 1] === \"index\") raw.pop()\n return raw.map(parseRawSegment)\n}\n\n/** Strip a known extension from a filename. */\nexport function stripExt(file: string, exts: string[]): string {\n for (const ext of exts) {\n if (file.endsWith(ext)) return file.slice(0, -ext.length)\n }\n return file\n}\n\n/**\n * Split a page-kind suffix off a name that has already lost its extension:\n * `june.slide` -> `{ base: \"june\", variant: \"slide\" }`, `june` -> variant null.\n * A bare `.slide.tsx` (empty base) is a nameless page, not a variant.\n */\nexport function splitPageVariant(nameNoExt: string): { base: string; variant: PageVariant | null } {\n for (const variant of PAGE_VARIANTS) {\n const suffix = `.${variant}`\n if (nameNoExt.endsWith(suffix) && nameNoExt.length > suffix.length) {\n return { base: nameNoExt.slice(0, -suffix.length), variant }\n }\n }\n return { base: nameNoExt, variant: null }\n}\n\n/**\n * Case-insensitive match against the data-file extensions, returning the\n * canonical (lowercased) form. `stripExt` cannot be reused here: it matches\n * case-sensitively, and `REPORT.CSV` must still lose exactly its extension\n * while its stem keeps its own case.\n */\nfunction matchFilePageExt(base: string): FilePageExt | undefined {\n const lower = base.toLowerCase()\n return FILE_PAGE_EXTENSIONS.find((ext) => lower.endsWith(ext))\n}\n\n/** Excel and Numbers drop a `~$book.xlsx` lock file while a workbook is open. */\nfunction isLockFile(base: string): boolean {\n return base.startsWith(\"~$\")\n}\n\nfunction hasExt(file: string, exts: string[]): boolean {\n return exts.some((ext) => file.endsWith(ext))\n}\n\n/** Recursively collect files under a directory, respecting ignore rules. */\nfunction walk(dir: string, root: string, out: string[]): void {\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n return\n }\n for (const entry of entries) {\n const abs = path.join(dir, entry.name)\n if (entry.isDirectory()) {\n if (NON_ROUTE_DIRS.has(entry.name)) continue\n if (entry.name.startsWith(\".\")) continue\n walk(abs, root, out)\n } else if (entry.isFile()) {\n out.push(abs)\n }\n }\n}\n\n/**\n * Decide where pages are scanned from: `<root>/src` when that directory exists,\n * the project root otherwise. The two never mix — a project that has `src/`\n * keeps every page inside it (`SRC_DIR_SPLIT` reports the leftovers).\n */\nexport function resolvePageRoot(root: string): { dir: string; abs: string } {\n const abs = path.join(root, SRC_DIR)\n try {\n if (fs.statSync(abs).isDirectory()) return { dir: SRC_DIR, abs }\n } catch {\n /* no src/ — pages live at the project root */\n }\n return { dir: \"\", abs: root }\n}\n\n/**\n * Discover page and layout routes under the page root. `file` stays relative to\n * the *project* root (generated imports resolve from `.vantage/`), while\n * `dir`/`segments`/`routePath` are relative to the *page* root so that `src/`\n * never leaks into a URL — and so `dir` keeps matching `segments` one-to-one,\n * which is how `buildRouteTree` pairs pages with their layouts.\n */\nfunction scanPages(\n root: string,\n pageRoot: string,\n): {\n pages: PageRoute[]\n layouts: LayoutRoute[]\n notFound: string | null\n error: string | null\n unrouted: UnroutedFile[]\n} {\n const files: string[] = []\n walk(pageRoot, pageRoot, files)\n\n const pages: PageRoute[] = []\n const layouts: LayoutRoute[] = []\n const unrouted: UnroutedFile[] = []\n let notFound: string | null = null\n let error: string | null = null\n\n for (const abs of files) {\n const file = toPosix(root, abs)\n const rel = toPosix(pageRoot, abs)\n const base = path.posix.basename(rel)\n const dir = path.posix.dirname(rel)\n const dirPosix = dir === \".\" ? \"\" : dir\n\n if (hasExt(base, PAGE_EXTENSIONS)) {\n const nameNoExt = stripExt(base, PAGE_EXTENSIONS)\n // Reserved modules are matched on the full name: `_layout.slide` is not\n // `_layout`, and a variant on a reserved module is an error the\n // diagnostics report rather than a route.\n if (nameNoExt === RESERVED_PAGE_NAMES.layout) {\n layouts.push({ file, absFile: abs, dir: dirPosix })\n continue\n }\n if (nameNoExt === RESERVED_PAGE_NAMES.notFound) {\n if (dirPosix === \"\") notFound = file\n continue\n }\n if (nameNoExt === RESERVED_PAGE_NAMES.error) {\n if (dirPosix === \"\") error = file\n continue\n }\n\n const { base: pageName, variant } = splitPageVariant(nameNoExt)\n // Any other underscore-prefixed file is a private module, not a route.\n // The test runs on the name with its variant suffix removed, so\n // `_layout.slide.tsx` and `_draft.slide.tsx` both drop out here.\n if (pageName.startsWith(\"_\")) {\n if (variant) unrouted.push({ file, reason: \"variant\", variant })\n continue\n }\n\n const relNoExt = stripExt(rel, PAGE_EXTENSIONS)\n // The variant suffix always sits at the end of the final token, so\n // trimming the tail is enough to keep it out of the URL.\n const relForSegments = variant ? relNoExt.slice(0, -(variant.length + 1)) : relNoExt\n const segments = fileToSegments(relForSegments)\n const routePath = displayPath(segments)\n const dynamic = segments.some((s) => s.kind !== \"static\")\n pages.push({\n file,\n absFile: abs,\n routePath,\n segments,\n dir: dirPosix,\n dynamic,\n kind: \"module\",\n ...(variant ? { variant } : {}),\n })\n continue\n }\n\n const fileExt = matchFilePageExt(base)\n if (fileExt) {\n // Same privacy rules as page modules, plus spreadsheet lock files.\n if (base.startsWith(\"_\") || base.startsWith(\".\") || isLockFile(base)) continue\n const relNoExt = rel.slice(0, -fileExt.length)\n const segments = fileToSegments(relNoExt)\n const routePath = displayPath(segments)\n const dynamic = segments.some((s) => s.kind !== \"static\")\n pages.push({\n file,\n absFile: abs,\n routePath,\n segments,\n dir: dirPosix,\n dynamic,\n kind: \"file\",\n fileExt,\n })\n continue\n }\n\n const lower = base.toLowerCase()\n // A page-kind suffix on something that is not a page module at all\n // (`deck.slide.ts`, `deck.slide.css`) is a typo worth naming.\n const strayVariant = PAGE_VARIANTS.find((v) => lower.includes(`.${v}.`))\n if (strayVariant) {\n unrouted.push({ file, reason: \"variant\", variant: strayVariant })\n } else if (UNSUPPORTED_PAGE_EXTENSIONS.some((ext) => lower.endsWith(ext))) {\n unrouted.push({ file, reason: \"extension\" })\n }\n }\n\n // Stable ordering: shallow before deep, static before dynamic, alpha. Data\n // files share the key, so they interleave with modules instead of clumping.\n pages.sort((a, b) => routeSortKey(a).localeCompare(routeSortKey(b)))\n layouts.sort((a, b) => a.dir.localeCompare(b.dir))\n unrouted.sort((a, b) => a.file.localeCompare(b.file))\n return { pages, layouts, notFound, error, unrouted }\n}\n\n/** Sort key that keeps static routes ahead of dynamic ones at each depth. */\nexport function routeSortKey(p: PageRoute): string {\n return p.segments\n .map((s) => (s.kind === \"static\" ? \"0\" + s.value : s.kind === \"param\" ? \"1\" : \"2\"))\n .join(\"/\")\n}\n\n/** Discover server API routes under `server/api`. */\nfunction scanApis(root: string): ApiRoute[] {\n const apiDir = path.join(root, \"server\", \"api\")\n if (!fs.existsSync(apiDir)) return []\n\n const files: string[] = []\n const walkApi = (dir: string) => {\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n return\n }\n for (const entry of entries) {\n const abs = path.join(dir, entry.name)\n if (entry.isDirectory()) walkApi(abs)\n else if (entry.isFile()) files.push(abs)\n }\n }\n walkApi(apiDir)\n\n const apis: ApiRoute[] = []\n for (const abs of files) {\n const base = path.basename(abs)\n if (!hasExt(base, API_EXTENSIONS)) continue\n const nameNoExt = stripExt(base, API_EXTENSIONS)\n // Type declaration files and private helpers are not routes.\n if (base.endsWith(\".d.ts\")) continue\n if (nameNoExt.startsWith(\"_\")) continue\n\n const relFromServer = toPosix(path.join(root, \"server\"), abs) // e.g. api/customers/[id].ts\n const relNoExt = stripExt(relFromServer, API_EXTENSIONS) // api/customers/[id]\n const withoutApiPrefix = relNoExt.replace(/^api\\/?/, \"\") // customers/[id] or \"\" for api/index\n const segTokens = withoutApiPrefix === \"\" ? [] : withoutApiPrefix.split(\"/\")\n if (segTokens[segTokens.length - 1] === \"index\") segTokens.pop()\n const segments = segTokens.map(parseRawSegment)\n const routePath = \"/api\" + (segments.length ? displayPath(segments) : \"\")\n const params = segments\n .filter((s) => s.kind !== \"static\")\n .map((s) => (s as { name: string }).name)\n\n apis.push({\n file: toPosix(root, abs),\n absFile: abs,\n routePath,\n pattern: routePath,\n segments,\n params,\n })\n }\n\n apis.sort((a, b) => a.routePath.localeCompare(b.routePath))\n return apis\n}\n\n/** Scan a project into a full route model. */\nexport function scanProject(root: string): RouteModel {\n return timed(\"scan\", () => {\n const pageRoot = resolvePageRoot(root)\n const { pages, layouts, notFound, error, unrouted } = scanPages(root, pageRoot.abs)\n // server/ is always at the project root: it is the other side of the\n // client/server boundary, not part of the client source tree.\n const hasServer = fs.existsSync(path.join(root, \"server\"))\n const apis = hasServer ? scanApis(root) : []\n return { pages, layouts, notFound, error, apis, hasServer, pageDir: pageRoot.dir, unrouted }\n })\n}\n\n/** Convert a display route path segment list into a TanStack Router path. */\nexport function toRouterPath(segments: Segment[]): string {\n if (segments.length === 0) return \"/\"\n const parts = segments.map((s) => {\n if (s.kind === \"static\") return s.value\n if (s.kind === \"param\") return `$${s.name}`\n return \"$\" // TanStack splat\n })\n return \"/\" + parts.join(\"/\")\n}\n"]}
@@ -1,9 +1,28 @@
1
+ import fs from 'fs';
1
2
  import path from 'path';
2
3
  import { createHash } from 'crypto';
3
- import fs from 'fs';
4
4
 
5
5
  // @squadbase/vantage — generated build. Do not edit.
6
6
 
7
+ function humanize(stem) {
8
+ return stem.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[-_\s]+/).filter(Boolean).map((word) => word === word.toUpperCase() ? word : word[0].toUpperCase() + word.slice(1)).join(" ");
9
+ }
10
+ function filePageMeta(page) {
11
+ const base = path.posix.basename(page.file);
12
+ let stem = page.fileExt ? base.slice(0, -page.fileExt.length) : base;
13
+ if (stem.toLowerCase() === "index") stem = page.dir.split("/").filter(Boolean).pop() ?? "";
14
+ if (stem === "") return {};
15
+ return { title: humanize(stem) };
16
+ }
17
+ function filePageKind(page) {
18
+ return (page.fileExt ?? "").slice(1);
19
+ }
20
+ function filePageModuleName(page) {
21
+ const slug = page.file.replace(/[^A-Za-z0-9]+/g, "-").replace(/^-|-$/g, "").toLowerCase();
22
+ const hash = createHash("sha256").update(page.file).digest("hex").slice(0, 8);
23
+ return `${slug}-${hash}.tsx`;
24
+ }
25
+
7
26
  // src/core/placeholder.ts
8
27
  var PLACEHOLDER_HOME_PAGE = `import { definePage } from "@squadbase/vantage"
9
28
  import {
@@ -117,24 +136,101 @@ function isPlaceholderHomePage(content) {
117
136
  function isHomePagePath(file) {
118
137
  return file === "index.tsx" || file === "src/index.tsx";
119
138
  }
120
- function humanize(stem) {
121
- return stem.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[-_\s]+/).filter(Boolean).map((word) => word === word.toUpperCase() ? word : word[0].toUpperCase() + word.slice(1)).join(" ");
139
+
140
+ // src/core/source.ts
141
+ function stripComments(src) {
142
+ return src.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:"'`\\])\/\/[^\n]*/g, "$1");
122
143
  }
123
- function filePageMeta(page) {
124
- const base = path.posix.basename(page.file);
125
- let stem = page.fileExt ? base.slice(0, -page.fileExt.length) : base;
126
- if (stem.toLowerCase() === "index") stem = page.dir.split("/").filter(Boolean).pop() ?? "";
127
- if (stem === "") return {};
128
- return { title: humanize(stem) };
144
+ var OPENERS = { "(": ")", "[": "]", "{": "}" };
145
+ function readBracketBody(src, openIndex) {
146
+ const open = src[openIndex];
147
+ if (!open || !OPENERS[open]) return null;
148
+ let depth2 = 0;
149
+ let quote = null;
150
+ for (let i = openIndex; i < src.length; i++) {
151
+ const c = src[i];
152
+ if (quote) {
153
+ if (c === "\\") i++;
154
+ else if (c === quote) quote = null;
155
+ continue;
156
+ }
157
+ if (c === '"' || c === "'" || c === "`") {
158
+ quote = c;
159
+ continue;
160
+ }
161
+ if (OPENERS[c]) depth2++;
162
+ else if (c === ")" || c === "]" || c === "}") {
163
+ if (--depth2 === 0) return src.slice(openIndex + 1, i);
164
+ }
165
+ }
166
+ return null;
129
167
  }
130
- function filePageKind(page) {
131
- return (page.fileExt ?? "").slice(1);
168
+ function splitTopLevel(body) {
169
+ const parts = [];
170
+ let depth2 = 0;
171
+ let quote = null;
172
+ let start = 0;
173
+ for (let i = 0; i < body.length; i++) {
174
+ const c = body[i];
175
+ if (quote) {
176
+ if (c === "\\") i++;
177
+ else if (c === quote) quote = null;
178
+ continue;
179
+ }
180
+ if (c === '"' || c === "'" || c === "`") {
181
+ quote = c;
182
+ continue;
183
+ }
184
+ if (OPENERS[c]) depth2++;
185
+ else if (c === ")" || c === "]" || c === "}") depth2--;
186
+ else if (c === "," && depth2 === 0) {
187
+ parts.push(body.slice(start, i));
188
+ start = i + 1;
189
+ }
190
+ }
191
+ parts.push(body.slice(start));
192
+ return parts.map((p) => p.trim()).filter(Boolean);
132
193
  }
133
- function filePageModuleName(page) {
134
- const slug = page.file.replace(/[^A-Za-z0-9]+/g, "-").replace(/^-|-$/g, "").toLowerCase();
135
- const hash = createHash("sha256").update(page.file).digest("hex").slice(0, 8);
136
- return `${slug}-${hash}.tsx`;
194
+ function maskSource(src) {
195
+ const out = src.split("");
196
+ const inString = new Uint8Array(src.length);
197
+ let i = 0;
198
+ while (i < src.length) {
199
+ const c = src[i];
200
+ const next = src[i + 1];
201
+ if (c === "/" && next === "/" && src[i - 1] !== ":") {
202
+ while (i < src.length && src[i] !== "\n") out[i++] = " ";
203
+ continue;
204
+ }
205
+ if (c === "/" && next === "*") {
206
+ const end = src.indexOf("*/", i + 2);
207
+ const stop = end === -1 ? src.length : end + 2;
208
+ for (; i < stop; i++) if (src[i] !== "\n") out[i] = " ";
209
+ continue;
210
+ }
211
+ if (c === '"' || c === "'" || c === "`") {
212
+ i++;
213
+ while (i < src.length) {
214
+ const d = src[i];
215
+ if (d === "\\") {
216
+ inString[i] = 1;
217
+ inString[i + 1] = 1;
218
+ i += 2;
219
+ continue;
220
+ }
221
+ if (d === c) break;
222
+ if (d === "\n" && c !== "`") break;
223
+ inString[i++] = 1;
224
+ }
225
+ i++;
226
+ continue;
227
+ }
228
+ i++;
229
+ }
230
+ return { code: out.join(""), inString };
137
231
  }
232
+
233
+ // src/core/route-tree.ts
138
234
  function segToRouter(s) {
139
235
  if (s.kind === "static") return s.value;
140
236
  if (s.kind === "param") return `$${s.name}`;
@@ -220,6 +316,72 @@ function extractPageMeta(absFile) {
220
316
  metaCache.set(absFile, { mtimeMs: stat.mtimeMs, size: stat.size, meta });
221
317
  return meta;
222
318
  }
319
+ var DEFAULT_APP_LANG = "en";
320
+ var LANG_TAG = /^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$/;
321
+ function isValidLang(lang) {
322
+ return LANG_TAG.test(lang);
323
+ }
324
+ var LANG_DECL = /\bexport\s+const\s+lang\b/g;
325
+ var LANG_LITERAL = /^(?:"((?:\\.|[^"\\\n])*)"|'((?:\\.|[^'\\\n])*)'|`((?:\\.|[^`\\$])*)`)/;
326
+ function parseLangExport(src) {
327
+ const { code, inString } = maskSource(src);
328
+ const depthAt = new Int32Array(src.length + 1);
329
+ let depth2 = 0;
330
+ for (let i = 0; i < src.length; i++) {
331
+ depthAt[i] = depth2;
332
+ if (inString[i]) continue;
333
+ const c = code[i];
334
+ if (c === "{" || c === "(" || c === "[") depth2++;
335
+ else if (c === "}" || c === ")" || c === "]") depth2--;
336
+ }
337
+ LANG_DECL.lastIndex = 0;
338
+ for (let m = LANG_DECL.exec(code); m; m = LANG_DECL.exec(code)) {
339
+ if (inString[m.index] || depthAt[m.index] !== 0) continue;
340
+ let i = m.index + m[0].length;
341
+ const annotation = /^\s*:\s*string\s*/.exec(code.slice(i));
342
+ if (annotation) i += annotation[0].length;
343
+ const eq = /^\s*=\s*/.exec(code.slice(i));
344
+ if (!eq) continue;
345
+ i += eq[0].length;
346
+ const lit = LANG_LITERAL.exec(src.slice(i));
347
+ if (!lit) continue;
348
+ const tail = code.slice(i + lit[0].length);
349
+ const end = /^[ \t]*(?:as\s+const|satisfies\s+string)?[ \t]*(;|\r?\n|$)/.exec(tail);
350
+ if (!end) continue;
351
+ const term = end[1] ?? "";
352
+ if (term !== ";") {
353
+ const next = /^\s*(\S)/.exec(tail.slice(end[0].length - term.length));
354
+ if (next && /[-+*/%&|^<>=?.,([`!~:]/.test(next[1])) continue;
355
+ }
356
+ return (lit[1] ?? lit[2] ?? lit[3] ?? "").replace(/\\(.)/g, "$1");
357
+ }
358
+ return void 0;
359
+ }
360
+ var langCache = /* @__PURE__ */ new Map();
361
+ function readLayoutLang(absFile) {
362
+ let stat;
363
+ try {
364
+ stat = fs.statSync(absFile);
365
+ } catch {
366
+ return void 0;
367
+ }
368
+ const hit = langCache.get(absFile);
369
+ if (hit && hit.mtimeMs === stat.mtimeMs && hit.size === stat.size) return hit.lang;
370
+ let lang;
371
+ try {
372
+ lang = parseLangExport(fs.readFileSync(absFile, "utf8"));
373
+ } catch {
374
+ return void 0;
375
+ }
376
+ langCache.set(absFile, { mtimeMs: stat.mtimeMs, size: stat.size, lang });
377
+ return lang;
378
+ }
379
+ function extractAppLang(model) {
380
+ const root = model.layouts.find((l) => l.dir === "");
381
+ if (!root) return DEFAULT_APP_LANG;
382
+ const lang = readLayoutLang(root.absFile);
383
+ return lang !== void 0 && isValidLang(lang) ? lang : DEFAULT_APP_LANG;
384
+ }
223
385
  function buildRouteTree(model) {
224
386
  const rootLayoutRoute = model.layouts.find((l) => l.dir === "") ?? null;
225
387
  const nestedLayouts = model.layouts.filter((l) => l.dir !== "").sort((a, b) => depth(a.dir) - depth(b.dir));
@@ -299,6 +461,6 @@ function buildRouteTree(model) {
299
461
  };
300
462
  }
301
463
 
302
- export { buildRouteTree, extractPageMeta, filePageKind, filePageMeta, filePageModuleName, isHomePagePath, isPlaceholderHomePage };
303
- //# sourceMappingURL=chunk-CEXAQQ5W.js.map
304
- //# sourceMappingURL=chunk-CEXAQQ5W.js.map
464
+ export { DEFAULT_APP_LANG, buildRouteTree, extractAppLang, extractPageMeta, filePageKind, filePageMeta, filePageModuleName, isHomePagePath, isPlaceholderHomePage, isValidLang, maskSource, readBracketBody, readLayoutLang, splitTopLevel, stripComments };
465
+ //# sourceMappingURL=chunk-S5MDTHH7.js.map
466
+ //# sourceMappingURL=chunk-S5MDTHH7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/file-page.ts","../src/core/placeholder.ts","../src/core/source.ts","../src/core/route-tree.ts"],"names":["depth","path"],"mappings":"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","file":"chunk-S5MDTHH7.js","sourcesContent":["/**\n * Everything the rest of the framework needs to know about a data-file page:\n * its title, the token the viewer switches on, and the name of the wrapper\n * module generated for it. One source of truth, the same way\n * `route-spec.ts`'s `detectApiMethods` is the one source for API methods —\n * `route-tree.ts` (metadata) and `generate.ts` (codegen) both read from here.\n */\nimport path from \"node:path\"\nimport { createHash } from \"node:crypto\"\n\n/** The parts of a file page each helper below needs. */\ninterface FileNamed {\n /** Project-relative POSIX path. */\n file: string\n}\ninterface FileTyped {\n /** The data-file extension, e.g. `\".csv\"`. */\n fileExt?: string\n}\n/** Metadata also needs the page-root-relative directory, which the URL uses. */\ntype FileMetaInput = FileNamed & FileTyped & { dir: string }\n\n/** The same shape `definePage` metadata takes, so callers can spread either. */\ninterface PageMeta {\n title?: string\n description?: string\n navLabel?: string\n placeholder?: boolean\n}\n\n/**\n * Turn a file stem into a title: `monthly_report-2024` -> \"Monthly Report\n * 2024\", `salesByRegion` -> \"Sales By Region\". All-caps tokens are left alone\n * (`KPI` stays `KPI`) because they are almost always acronyms.\n */\nexport function humanize(stem: string): string {\n return stem\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .split(/[-_\\s]+/)\n .filter(Boolean)\n .map((word) => (word === word.toUpperCase() ? word : word[0]!.toUpperCase() + word.slice(1)))\n .join(\" \")\n}\n\n/**\n * Title for a data-file page, derived from its name — a spreadsheet cannot\n * carry a `definePage`. `index.csv` borrows its directory's name (its own name\n * is not in the URL either); a root-level `index.csv` gets no title at all,\n * exactly like a root `index.tsx` without `definePage`.\n */\nexport function filePageMeta(page: FileMetaInput): PageMeta {\n const base = path.posix.basename(page.file)\n let stem = page.fileExt ? base.slice(0, -page.fileExt.length) : base\n if (stem.toLowerCase() === \"index\") stem = page.dir.split(\"/\").filter(Boolean).pop() ?? \"\"\n if (stem === \"\") return {}\n return { title: humanize(stem) }\n}\n\n/** The token handed to the client viewer: `\".xlsx\"` -> `\"xlsx\"`. */\nexport function filePageKind(page: FileTyped): string {\n return (page.fileExt ?? \"\").slice(1)\n}\n\n/**\n * Name of the wrapper module generated for a data-file page. Derived from the\n * source path so it is stable across runs (`writeIfChanged` stays a no-op) and\n * readable in a stack trace; the hash suffix keeps `a/b.csv` and `a-b.csv` from\n * colliding once slugified.\n */\nexport function filePageModuleName(page: FileNamed): string {\n const slug = page.file\n .replace(/[^A-Za-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .toLowerCase()\n const hash = createHash(\"sha256\").update(page.file).digest(\"hex\").slice(0, 8)\n return `${slug}-${hash}.tsx`\n}\n","/**\n * Detect whether a file is an untouched template placeholder.\n *\n * When a Vantage project is initialized from the template, it includes\n * a placeholder home page at `src/index.tsx` (or `index.tsx` at the root).\n * If that file remains completely untouched and a new artifact (e.g. a slide)\n * wants to claim route `/`, we allow it by treating the placeholder as yieldable\n * instead of reporting ROUTE_CONFLICT.\n */\n\n/**\n * Expected content of the template placeholder `src/index.tsx`.\n * This is the exact content from @squadbase/vantage-template 0.1.1.\n * When the template is updated, this constant must be updated as well.\n */\nconst PLACEHOLDER_HOME_PAGE = `import { definePage } from \"@squadbase/vantage\"\nimport {\n DashboardCardPreset,\n EChart,\n PageShell,\n PageShellContent,\n PageShellDescription,\n PageShellHeader,\n PageShellHeading,\n PageShellTitle,\n Placeholder,\n Sparkline,\n type EChartsOption,\n} from \"@squadbase/vantage/components\"\n\nexport const page = definePage({\n title: \"Dashboard\",\n description: \"Sample data — replace with your own to get started.\",\n navLabel: \"Home\",\n})\n\nconst METRICS = [\n { label: \"Metric 1\", value: \"1,234\", trend: [3, 4, 3, 5, 6, 5, 7] },\n { label: \"Metric 2\", value: \"5,678\", trend: [6, 5, 6, 4, 5, 6, 6] },\n { label: \"Metric 3\", value: \"90.1%\", trend: [2, 3, 5, 4, 6, 7, 8] },\n { label: \"Metric 4\", value: \"$12.3k\", trend: [5, 6, 4, 6, 5, 7, 6] },\n]\n\n// Sample charts. \\`EChart\\` paints series with \\`--chart-1..5\\` and the sparklines\n// use \\`--primary\\` (both from \\`styles.css\\`), so a theme change shows up here.\nconst BAR_OPTION: EChartsOption = {\n legend: { top: 0 },\n grid: { top: 36, right: 8, bottom: 24, left: 36 },\n xAxis: { type: \"category\", data: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\"] },\n yAxis: { type: \"value\" },\n series: [\n { name: \"Series A\", type: \"bar\", data: [12, 18, 15, 22, 26, 24] },\n { name: \"Series B\", type: \"bar\", data: [8, 11, 13, 12, 16, 19] },\n { name: \"Series C\", type: \"bar\", data: [5, 7, 6, 9, 8, 11] },\n ],\n}\n\nconst PIE_OPTION: EChartsOption = {\n legend: { bottom: 0 },\n series: [\n {\n type: \"pie\",\n radius: [\"45%\", \"70%\"],\n center: [\"50%\", \"45%\"],\n label: { show: false },\n data: [\n { name: \"Category A\", value: 35 },\n { name: \"Category B\", value: 25 },\n { name: \"Category C\", value: 18 },\n { name: \"Category D\", value: 12 },\n { name: \"Category E\", value: 10 },\n ],\n },\n ],\n}\n\nconst CHARTS = [\n { title: \"Chart 1\", option: BAR_OPTION },\n { title: \"Chart 2\", option: PIE_OPTION },\n]\n\nexport default function HomePage() {\n return (\n <PageShell>\n <PageShellHeader>\n <PageShellHeading>\n <PageShellTitle>Dashboard</PageShellTitle>\n <PageShellDescription>\n Sample data — replace with your own to get started.\n </PageShellDescription>\n </PageShellHeading>\n </PageShellHeader>\n\n <PageShellContent>\n <section className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4\">\n {METRICS.map((metric) => (\n <DashboardCardPreset key={metric.label} title={metric.label}>\n <Placeholder className=\"text-2xl font-bold\">{metric.value}</Placeholder>\n <Sparkline\n className=\"mt-2\"\n data={metric.trend.map((value) => ({ value }))}\n color=\"text-primary\"\n area\n />\n </DashboardCardPreset>\n ))}\n </section>\n\n <section className=\"grid grid-cols-1 gap-4 lg:grid-cols-2\">\n {CHARTS.map((chart) => (\n <DashboardCardPreset key={chart.title} title={chart.title}>\n <EChart option={chart.option} height={256} ariaLabel={chart.title} />\n </DashboardCardPreset>\n ))}\n </section>\n </PageShellContent>\n </PageShell>\n )\n}\n`\n\n/**\n * Check if a file content matches the template placeholder home page.\n * Returns true if the file is the exact untouched placeholder.\n * \n * This is a fallback for projects created from the older template (0.1.1-dev1.2be5c44)\n * before the explicit `placeholder: true` marker was added.\n */\nexport function isPlaceholderHomePage(content: string): boolean {\n // First check for explicit placeholder marker\n if (/\\bplaceholder\\s*:\\s*true\\b/.test(content)) return true\n \n // Fallback: exact content match for older templates\n return content.trim() === PLACEHOLDER_HOME_PAGE.trim()\n}\n\n/**\n * Check if a file path is the home page (index.tsx at root or in src/).\n */\nexport function isHomePagePath(file: string): boolean {\n return file === \"index.tsx\" || file === \"src/index.tsx\"\n}\n","/**\n * Low-level source scanning helpers shared by the static analyzers\n * (`diagnostics.ts`, `route-spec.ts`). Everything here is text-only — user code\n * is never imported or executed.\n */\n\n/**\n * Strip block and line comments so commented-out code doesn't produce false\n * positives (or hide real issues). Naive but adequate for presence checks:\n * URLs (`http://`) are preserved via the `[^:]` guard before `//`.\n */\nexport function stripComments(src: string): string {\n return src.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\").replace(/(^|[^:\"'`\\\\])\\/\\/[^\\n]*/g, \"$1\")\n}\n\nconst OPENERS: Record<string, string> = { \"(\": \")\", \"[\": \"]\", \"{\": \"}\" }\n\n/**\n * Read a balanced bracketed region starting at `openIndex` (which must hold\n * `(`, `[` or `{`), returning the raw text *between* the brackets. Quote- and\n * nesting-aware so brackets inside string literals don't unbalance the scan.\n * Returns null when the region is never closed.\n */\nexport function readBracketBody(src: string, openIndex: number): string | null {\n const open = src[openIndex]\n if (!open || !OPENERS[open]) return null\n let depth = 0\n let quote: string | null = null\n for (let i = openIndex; i < src.length; i++) {\n const c = src[i]!\n if (quote) {\n if (c === \"\\\\\") i++\n else if (c === quote) quote = null\n continue\n }\n if (c === '\"' || c === \"'\" || c === \"`\") {\n quote = c\n continue\n }\n if (OPENERS[c]) depth++\n else if (c === \")\" || c === \"]\" || c === \"}\") {\n if (--depth === 0) return src.slice(openIndex + 1, i)\n }\n }\n return null\n}\n\n/**\n * Split an argument list or object body on top-level commas, ignoring commas\n * nested inside brackets or string literals. Empty parts are dropped.\n */\nexport function splitTopLevel(body: string): string[] {\n const parts: string[] = []\n let depth = 0\n let quote: string | null = null\n let start = 0\n for (let i = 0; i < body.length; i++) {\n const c = body[i]!\n if (quote) {\n if (c === \"\\\\\") i++\n else if (c === quote) quote = null\n continue\n }\n if (c === '\"' || c === \"'\" || c === \"`\") {\n quote = c\n continue\n }\n if (OPENERS[c]) depth++\n else if (c === \")\" || c === \"]\" || c === \"}\") depth--\n else if (c === \",\" && depth === 0) {\n parts.push(body.slice(start, i))\n start = i + 1\n }\n }\n parts.push(body.slice(start))\n return parts.map((p) => p.trim()).filter(Boolean)\n}\n\n/**\n * Lex a module just far enough to tell code, comments and string literals\n * apart, *without* moving anything: comments come back blanked to spaces\n * (newlines kept) so offsets and line numbers still match the raw file, and\n * `inString[i]` is 1 where offset `i` sits inside a `'…'`, `\"…\"` or `` `…` ``\n * literal (template `${…}` bodies count as string — close enough for literal\n * scans). `'`/`\"` literals end at a newline, so an apostrophe in JSX text\n * cannot swallow more than the rest of its own line.\n */\nexport function maskSource(src: string): { code: string; inString: Uint8Array } {\n const out = src.split(\"\")\n const inString = new Uint8Array(src.length)\n let i = 0\n while (i < src.length) {\n const c = src[i]!\n const next = src[i + 1]\n if (c === \"/\" && next === \"/\" && src[i - 1] !== \":\") {\n while (i < src.length && src[i] !== \"\\n\") out[i++] = \" \"\n continue\n }\n if (c === \"/\" && next === \"*\") {\n const end = src.indexOf(\"*/\", i + 2)\n const stop = end === -1 ? src.length : end + 2\n for (; i < stop; i++) if (src[i] !== \"\\n\") out[i] = \" \"\n continue\n }\n if (c === '\"' || c === \"'\" || c === \"`\") {\n i++\n while (i < src.length) {\n const d = src[i]!\n if (d === \"\\\\\") {\n inString[i] = 1\n inString[i + 1] = 1\n i += 2\n continue\n }\n if (d === c) break\n if (d === \"\\n\" && c !== \"`\") break\n inString[i++] = 1\n }\n i++\n continue\n }\n i++\n }\n return { code: out.join(\"\"), inString }\n}\n","import fs from \"node:fs\"\nimport type { FilePageExt, PageVariant } from \"./constants\"\nimport { filePageMeta } from \"./file-page\"\nimport { isHomePagePath, isPlaceholderHomePage } from \"./placeholder\"\nimport { maskSource } from \"./source\"\nimport type { PageKind, RouteModel, Segment } from \"./types\"\n\n/** A layout route (path-bearing) in the built tree. */\nexport interface BuiltLayout {\n id: string\n dir: string\n parentId: string | null\n /** Router path relative to its parent (TanStack `$param` form). */\n path: string\n file: string\n}\n\n/** A page route in the built tree. */\nexport interface BuiltPage {\n file: string\n routePath: string\n parentLayoutId: string | null\n /** Router path relative to parent, or \"/\" for an index route. */\n path: string\n index: boolean\n title?: string\n description?: string\n navLabel?: string\n kind: PageKind\n fileExt?: FilePageExt\n variant?: PageVariant\n placeholder?: boolean\n}\n\n/** The structured route tree emitted for the client runtime. */\nexport interface BuiltTree {\n rootLayout: string | null\n notFound: string | null\n error: string | null\n layouts: BuiltLayout[]\n pages: BuiltPage[]\n}\n\nfunction segToRouter(s: Segment): string {\n if (s.kind === \"static\") return s.value\n if (s.kind === \"param\") return `$${s.name}`\n return \"$\"\n}\n\n/** Convert a relative directory string (may contain `[param]`) to a router path. */\nfunction dirToRouterPath(relDir: string): string {\n return relDir\n .split(\"/\")\n .filter(Boolean)\n .map((token) => {\n const catchall = token.match(/^\\[\\.\\.\\.(.+)\\]$/)\n if (catchall) return \"$\"\n const param = token.match(/^\\[(.+)\\]$/)\n if (param) return `$${param[1]}`\n return token\n })\n .join(\"/\")\n}\n\nfunction isAncestorDir(ancestor: string, dir: string): boolean {\n if (ancestor === \"\") return true\n return dir === ancestor || dir.startsWith(ancestor + \"/\")\n}\n\nfunction isStrictAncestorDir(ancestor: string, dir: string): boolean {\n return dir.startsWith(ancestor + \"/\")\n}\n\nfunction depth(dir: string): number {\n return dir === \"\" ? 0 : dir.split(\"/\").length\n}\n\n/**\n * Extract the argument object body of the first `definePage({ ... })` call\n * using balanced-brace scanning, so nested objects/functions (e.g.\n * `validateSearch: (s) => ({ ... })`) don't truncate the match. Returns null\n * when there is no definePage call — the caller then emits no metadata rather\n * than falling back to the whole file (which would match unrelated `title:`\n * keys in chart/option configs).\n */\nfunction extractDefinePageArgs(src: string): string | null {\n const call = src.match(/\\bdefinePage\\s*\\(/)\n if (!call) return null\n let i = (call.index ?? 0) + call[0].length\n while (i < src.length && /\\s/.test(src[i]!)) i++\n if (src[i] !== \"{\") return null\n const start = i\n let depth = 0\n for (; i < src.length; i++) {\n const c = src[i]\n if (c === \"{\") depth++\n else if (c === \"}\" && --depth === 0) return src.slice(start + 1, i)\n }\n return null\n}\n\n/**\n * Match `key: \"...\"` allowing the value's own quote character to differ and\n * handling escapes, so values containing an apostrophe/quote are not truncated.\n */\nfunction matchStringField(scope: string, key: string): string | undefined {\n const re = new RegExp(\n `\\\\b${key}\\\\s*:\\\\s*(?:\"((?:\\\\\\\\.|[^\"\\\\\\\\])*)\"|'((?:\\\\\\\\.|[^'\\\\\\\\])*)'|\\`((?:\\\\\\\\.|[^\\`\\\\\\\\])*)\\`)`,\n )\n const m = scope.match(re)\n if (!m) return undefined\n return (m[1] ?? m[2] ?? m[3] ?? \"\").replace(/\\\\(.)/g, \"$1\")\n}\n\ninterface PageMeta {\n title?: string\n description?: string\n navLabel?: string\n placeholder?: boolean\n}\n\n/**\n * Cache keyed on mtime+size. A long-lived dev server regenerates the route tree\n * on every structural change, and re-reading + re-parsing every page module for\n * metadata that almost never changes is pure waste. `statSync` is an order of\n * magnitude cheaper than the read plus the brace scan it feeds.\n */\nconst metaCache = new Map<string, { mtimeMs: number; size: number; meta: PageMeta }>()\n\nfunction parsePageMeta(src: string): PageMeta {\n const args = extractDefinePageArgs(src)\n if (args == null) return {}\n const meta: PageMeta = {}\n const title = matchStringField(args, \"title\")\n const description = matchStringField(args, \"description\")\n const navLabel = matchStringField(args, \"navLabel\")\n if (title) meta.title = title\n if (description) meta.description = description\n if (navLabel) meta.navLabel = navLabel\n // Check for placeholder: true (boolean literal)\n if (/\\bplaceholder\\s*:\\s*true\\b/.test(args)) meta.placeholder = true\n return meta\n}\n\n/** Best-effort static extraction of definePage title/description/navLabel. */\nexport function extractPageMeta(absFile: string): PageMeta {\n let stat: fs.Stats\n try {\n stat = fs.statSync(absFile)\n } catch {\n return {}\n }\n const hit = metaCache.get(absFile)\n if (hit && hit.mtimeMs === stat.mtimeMs && hit.size === stat.size) return hit.meta\n\n let src: string\n try {\n src = fs.readFileSync(absFile, \"utf8\")\n } catch {\n return {}\n }\n const meta = parsePageMeta(src)\n \n // Check for placeholder using the robust detection from placeholder.ts\n // This includes both explicit marker and fallback exact match\n const fileName = absFile.split(/[/\\\\]/).pop() ?? \"\"\n const relPath = absFile.includes(\"/src/\") ? `src/${fileName}` : fileName\n if (isHomePagePath(relPath) && isPlaceholderHomePage(src)) {\n meta.placeholder = true\n }\n \n metaCache.set(absFile, { mtimeMs: stat.mtimeMs, size: stat.size, meta })\n return meta\n}\n\n/** `<html lang>` when the root layout does not (validly) set one. */\nexport const DEFAULT_APP_LANG = \"en\"\n\n/** BCP 47-shaped tag. Also keeps the value safe to write into an HTML attribute. */\nconst LANG_TAG = /^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$/\n\nexport function isValidLang(lang: string): boolean {\n return LANG_TAG.test(lang)\n}\n\nconst LANG_DECL = /\\bexport\\s+const\\s+lang\\b/g\nconst LANG_LITERAL = /^(?:\"((?:\\\\.|[^\"\\\\\\n])*)\"|'((?:\\\\.|[^'\\\\\\n])*)'|`((?:\\\\.|[^`\\\\$])*)`)/\n\n/**\n * The initializer of a top-level `export const lang` when it is exactly one\n * string literal (no `${}`), else undefined. Text inside strings/comments and\n * nested scopes is skipped; a literal that is only the prefix of a longer\n * expression (`\"ja\" + x`) is rejected.\n */\nexport function parseLangExport(src: string): string | undefined {\n const { code, inString } = maskSource(src)\n const depthAt = new Int32Array(src.length + 1)\n let depth = 0\n for (let i = 0; i < src.length; i++) {\n depthAt[i] = depth\n if (inString[i]) continue\n const c = code[i]\n if (c === \"{\" || c === \"(\" || c === \"[\") depth++\n else if (c === \"}\" || c === \")\" || c === \"]\") depth--\n }\n LANG_DECL.lastIndex = 0\n for (let m = LANG_DECL.exec(code); m; m = LANG_DECL.exec(code)) {\n if (inString[m.index] || depthAt[m.index] !== 0) continue\n let i = m.index + m[0].length\n const annotation = /^\\s*:\\s*string\\s*/.exec(code.slice(i))\n if (annotation) i += annotation[0].length\n const eq = /^\\s*=\\s*/.exec(code.slice(i))\n if (!eq) continue\n i += eq[0].length\n const lit = LANG_LITERAL.exec(src.slice(i))\n if (!lit) continue\n // The masked tail (comments blanked) must end the statement right after the literal.\n const tail = code.slice(i + lit[0].length)\n const end = /^[ \\t]*(?:as\\s+const|satisfies\\s+string)?[ \\t]*(;|\\r?\\n|$)/.exec(tail)\n if (!end) continue\n const term = end[1] ?? \"\"\n if (term !== \";\") {\n // ASI: a following line starting with an operator continues the expression.\n const next = /^\\s*(\\S)/.exec(tail.slice(end[0].length - term.length))\n if (next && /[-+*/%&|^<>=?.,([`!~:]/.test(next[1]!)) continue\n }\n return (lit[1] ?? lit[2] ?? lit[3] ?? \"\").replace(/\\\\(.)/g, \"$1\")\n }\n return undefined\n}\n\nconst langCache = new Map<string, { mtimeMs: number; size: number; lang: string | undefined }>()\n\n/**\n * The literal `export const lang = \"...\"` of a layout module, as written\n * (not validated), or undefined when absent / not a string literal.\n */\nexport function readLayoutLang(absFile: string): string | undefined {\n let stat: fs.Stats\n try {\n stat = fs.statSync(absFile)\n } catch {\n return undefined\n }\n const hit = langCache.get(absFile)\n if (hit && hit.mtimeMs === stat.mtimeMs && hit.size === stat.size) return hit.lang\n let lang: string | undefined\n try {\n lang = parseLangExport(fs.readFileSync(absFile, \"utf8\"))\n } catch {\n return undefined\n }\n langCache.set(absFile, { mtimeMs: stat.mtimeMs, size: stat.size, lang })\n return lang\n}\n\n/**\n * The app's display language: the root `_layout`'s `lang` literal, or\n * {@link DEFAULT_APP_LANG} when unset or invalid. Nested layouts are ignored.\n */\nexport function extractAppLang(model: RouteModel): string {\n const root = model.layouts.find((l) => l.dir === \"\")\n if (!root) return DEFAULT_APP_LANG\n const lang = readLayoutLang(root.absFile)\n return lang !== undefined && isValidLang(lang) ? lang : DEFAULT_APP_LANG\n}\n\n/**\n * Build the structured route tree from a scan. Layouts become path-bearing\n * routes; pages attach to the deepest layout that owns their directory.\n */\nexport function buildRouteTree(model: RouteModel): BuiltTree {\n const rootLayoutRoute = model.layouts.find((l) => l.dir === \"\") ?? null\n const nestedLayouts = model.layouts\n .filter((l) => l.dir !== \"\")\n .sort((a, b) => depth(a.dir) - depth(b.dir))\n\n const built: BuiltLayout[] = []\n const dirToId = new Map<string, string>()\n\n nestedLayouts.forEach((layout, i) => {\n const id = `L${i}`\n // Parent = deepest other layout that is a strict ancestor of this dir.\n let parent: { id: string; dir: string } | null = null\n for (const cand of built) {\n if (isStrictAncestorDir(cand.dir, layout.dir)) {\n if (!parent || depth(cand.dir) > depth(parent.dir)) parent = { id: cand.id, dir: cand.dir }\n }\n }\n const parentDir = parent ? parent.dir : \"\"\n const relDir = parentDir === \"\" ? layout.dir : layout.dir.slice(parentDir.length + 1)\n built.push({\n id,\n dir: layout.dir,\n parentId: parent ? parent.id : null,\n path: dirToRouterPath(relDir),\n file: layout.file,\n })\n dirToId.set(layout.dir, id)\n })\n\n const pages: BuiltPage[] = model.pages.map((page) => {\n // Owner = deepest layout whose dir is an ancestor-or-equal of the page dir.\n let owner: BuiltLayout | null = null\n for (const l of built) {\n if (isAncestorDir(l.dir, page.dir)) {\n if (!owner || depth(l.dir) > depth(owner.dir)) owner = l\n }\n }\n const ownerSegCount = owner ? depth(owner.dir) : 0\n const remaining = page.segments.slice(ownerSegCount)\n const index = remaining.length === 0\n const path = index ? \"/\" : remaining.map(segToRouter).join(\"/\")\n // `extractPageMeta` reads the file as UTF-8 and runs regexes over it, so a\n // data file must never reach it — a few MB of spreadsheet binary would be\n // decoded and scanned for a `definePage` that cannot exist there.\n const meta = page.kind === \"file\" ? filePageMeta(page) : extractPageMeta(page.absFile)\n const builtPage: BuiltPage = {\n file: page.file,\n routePath: page.routePath,\n parentLayoutId: owner ? owner.id : null,\n path,\n index,\n kind: page.kind,\n }\n if (meta.title) builtPage.title = meta.title\n if (meta.description) builtPage.description = meta.description\n if (meta.navLabel) builtPage.navLabel = meta.navLabel\n if (page.fileExt) builtPage.fileExt = page.fileExt\n if (page.variant) builtPage.variant = page.variant\n if (meta.placeholder) builtPage.placeholder = meta.placeholder\n return builtPage\n })\n\n // Filter out placeholder pages when there's another page at the same route.\n // This allows new artifacts (e.g. index.slide.tsx) to claim \"/\" when the\n // template's placeholder home page is untouched.\n const byRoutePath = new Map<string, { placeholder: BuiltPage[]; nonPlaceholder: BuiltPage[] }>()\n for (const page of pages) {\n const group = byRoutePath.get(page.routePath) ?? { placeholder: [], nonPlaceholder: [] }\n if (page.placeholder) {\n group.placeholder.push(page)\n } else {\n group.nonPlaceholder.push(page)\n }\n byRoutePath.set(page.routePath, group)\n }\n\n const filteredPages: BuiltPage[] = []\n for (const group of byRoutePath.values()) {\n // If there are non-placeholder pages, use only those\n if (group.nonPlaceholder.length > 0) {\n filteredPages.push(...group.nonPlaceholder)\n } else {\n // Otherwise, use the placeholder(s)\n filteredPages.push(...group.placeholder)\n }\n }\n\n return {\n rootLayout: rootLayoutRoute ? rootLayoutRoute.file : null,\n notFound: model.notFound,\n error: model.error,\n layouts: built,\n pages: filteredPages,\n }\n}\n"]}