@cardstack/boxel-cli 0.10.0 → 0.10.1-unstable.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1070) hide show
  1. package/bundled-realms/pretui/README.md +49 -0
  2. package/bundled-realms/pretui/color/LICENSE +21 -0
  3. package/bundled-realms/pretui/color/README.md +155 -0
  4. package/bundled-realms/pretui/color/index.js +78 -0
  5. package/bundled-realms/pretui/color-engine.ts +1243 -0
  6. package/bundled-realms/pretui/components/accordion.gts +58 -0
  7. package/bundled-realms/pretui/components/accordion.md +60 -0
  8. package/bundled-realms/pretui/components/accordion.usage.gts +129 -0
  9. package/bundled-realms/pretui/components/action-bar.gts +407 -0
  10. package/bundled-realms/pretui/components/action-bar.md +48 -0
  11. package/bundled-realms/pretui/components/action-bar.usage.gts +213 -0
  12. package/bundled-realms/pretui/components/affix.gts +116 -0
  13. package/bundled-realms/pretui/components/affix.md +54 -0
  14. package/bundled-realms/pretui/components/affix.usage.gts +73 -0
  15. package/bundled-realms/pretui/components/agent-question.gts +116 -0
  16. package/bundled-realms/pretui/components/agent-question.md +50 -0
  17. package/bundled-realms/pretui/components/agent-question.usage.gts +22 -0
  18. package/bundled-realms/pretui/components/ai-instructions.gts +378 -0
  19. package/bundled-realms/pretui/components/ai-instructions.md +49 -0
  20. package/bundled-realms/pretui/components/ai-instructions.usage.gts +101 -0
  21. package/bundled-realms/pretui/components/alert-dialog.gts +223 -0
  22. package/bundled-realms/pretui/components/alert-dialog.md +76 -0
  23. package/bundled-realms/pretui/components/alert-dialog.usage.gts +128 -0
  24. package/bundled-realms/pretui/components/alert.gts +163 -0
  25. package/bundled-realms/pretui/components/alert.md +57 -0
  26. package/bundled-realms/pretui/components/alert.usage.gts +99 -0
  27. package/bundled-realms/pretui/components/amount-input.gts +621 -0
  28. package/bundled-realms/pretui/components/amount-input.md +63 -0
  29. package/bundled-realms/pretui/components/amount-input.usage.gts +170 -0
  30. package/bundled-realms/pretui/components/angle-dial.gts +367 -0
  31. package/bundled-realms/pretui/components/angle-dial.md +56 -0
  32. package/bundled-realms/pretui/components/angle-dial.usage.gts +166 -0
  33. package/bundled-realms/pretui/components/animated-image.gts +291 -0
  34. package/bundled-realms/pretui/components/animated-image.md +49 -0
  35. package/bundled-realms/pretui/components/animated-image.usage.gts +127 -0
  36. package/bundled-realms/pretui/components/app-shell.gts +19 -0
  37. package/bundled-realms/pretui/components/app-shell.md +43 -0
  38. package/bundled-realms/pretui/components/app-shell.usage.gts +52 -0
  39. package/bundled-realms/pretui/components/approval-footer.gts +69 -0
  40. package/bundled-realms/pretui/components/approval-footer.md +49 -0
  41. package/bundled-realms/pretui/components/approval-footer.usage.gts +22 -0
  42. package/bundled-realms/pretui/components/aspect-ratio.gts +328 -0
  43. package/bundled-realms/pretui/components/aspect-ratio.md +72 -0
  44. package/bundled-realms/pretui/components/aspect-ratio.usage.gts +174 -0
  45. package/bundled-realms/pretui/components/asset-grid.gts +542 -0
  46. package/bundled-realms/pretui/components/asset-grid.md +54 -0
  47. package/bundled-realms/pretui/components/asset-grid.usage.gts +171 -0
  48. package/bundled-realms/pretui/components/asset-well.gts +731 -0
  49. package/bundled-realms/pretui/components/asset-well.md +72 -0
  50. package/bundled-realms/pretui/components/asset-well.usage.gts +264 -0
  51. package/bundled-realms/pretui/components/audio-player.gts +152 -0
  52. package/bundled-realms/pretui/components/audio-player.md +51 -0
  53. package/bundled-realms/pretui/components/audio-player.usage.gts +118 -0
  54. package/bundled-realms/pretui/components/autocomplete.gts +1150 -0
  55. package/bundled-realms/pretui/components/autocomplete.md +67 -0
  56. package/bundled-realms/pretui/components/autocomplete.usage.gts +339 -0
  57. package/bundled-realms/pretui/components/avatar-group.gts +30 -0
  58. package/bundled-realms/pretui/components/avatar-group.md +48 -0
  59. package/bundled-realms/pretui/components/avatar-group.usage.gts +39 -0
  60. package/bundled-realms/pretui/components/avatar.gts +134 -0
  61. package/bundled-realms/pretui/components/avatar.md +69 -0
  62. package/bundled-realms/pretui/components/avatar.usage.gts +101 -0
  63. package/bundled-realms/pretui/components/backdrop.gts +179 -0
  64. package/bundled-realms/pretui/components/backdrop.md +56 -0
  65. package/bundled-realms/pretui/components/backdrop.usage.gts +223 -0
  66. package/bundled-realms/pretui/components/background-field.gts +743 -0
  67. package/bundled-realms/pretui/components/background-field.md +62 -0
  68. package/bundled-realms/pretui/components/background-field.usage.gts +328 -0
  69. package/bundled-realms/pretui/components/badge.gts +188 -0
  70. package/bundled-realms/pretui/components/badge.md +62 -0
  71. package/bundled-realms/pretui/components/badge.usage.gts +73 -0
  72. package/bundled-realms/pretui/components/bar-list.gts +255 -0
  73. package/bundled-realms/pretui/components/bar-list.md +49 -0
  74. package/bundled-realms/pretui/components/bar-list.usage.gts +129 -0
  75. package/bundled-realms/pretui/components/board.gts +108 -0
  76. package/bundled-realms/pretui/components/board.md +54 -0
  77. package/bundled-realms/pretui/components/board.usage.gts +321 -0
  78. package/bundled-realms/pretui/components/bottom-nav.gts +217 -0
  79. package/bundled-realms/pretui/components/bottom-nav.md +64 -0
  80. package/bundled-realms/pretui/components/bottom-nav.usage.gts +68 -0
  81. package/bundled-realms/pretui/components/breadcrumb.gts +56 -0
  82. package/bundled-realms/pretui/components/breadcrumb.md +52 -0
  83. package/bundled-realms/pretui/components/breadcrumb.usage.gts +24 -0
  84. package/bundled-realms/pretui/components/broken-link.gts +46 -0
  85. package/bundled-realms/pretui/components/broken-link.md +50 -0
  86. package/bundled-realms/pretui/components/broken-link.usage.gts +57 -0
  87. package/bundled-realms/pretui/components/button-group.gts +246 -0
  88. package/bundled-realms/pretui/components/button-group.md +46 -0
  89. package/bundled-realms/pretui/components/button-group.usage.gts +137 -0
  90. package/bundled-realms/pretui/components/button.examples.gts +67 -0
  91. package/bundled-realms/pretui/components/button.gts +594 -0
  92. package/bundled-realms/pretui/components/button.md +81 -0
  93. package/bundled-realms/pretui/components/button.usage.gts +159 -0
  94. package/bundled-realms/pretui/components/calendar.gts +457 -0
  95. package/bundled-realms/pretui/components/calendar.md +57 -0
  96. package/bundled-realms/pretui/components/calendar.usage.gts +161 -0
  97. package/bundled-realms/pretui/components/callout.gts +2 -0
  98. package/bundled-realms/pretui/components/callout.md +40 -0
  99. package/bundled-realms/pretui/components/callout.usage.gts +48 -0
  100. package/bundled-realms/pretui/components/card.gts +637 -0
  101. package/bundled-realms/pretui/components/card.md +105 -0
  102. package/bundled-realms/pretui/components/card.usage.gts +279 -0
  103. package/bundled-realms/pretui/components/carousel.gts +583 -0
  104. package/bundled-realms/pretui/components/carousel.md +53 -0
  105. package/bundled-realms/pretui/components/carousel.usage.gts +220 -0
  106. package/bundled-realms/pretui/components/cascader.gts +436 -0
  107. package/bundled-realms/pretui/components/cascader.md +61 -0
  108. package/bundled-realms/pretui/components/cascader.usage.gts +79 -0
  109. package/bundled-realms/pretui/components/channel-slider.gts +251 -0
  110. package/bundled-realms/pretui/components/channel-slider.md +51 -0
  111. package/bundled-realms/pretui/components/channel-slider.usage.gts +104 -0
  112. package/bundled-realms/pretui/components/chart.gts +1011 -0
  113. package/bundled-realms/pretui/components/chart.md +60 -0
  114. package/bundled-realms/pretui/components/chart.usage.gts +660 -0
  115. package/bundled-realms/pretui/components/checkbox-card.gts +82 -0
  116. package/bundled-realms/pretui/components/checkbox-card.md +73 -0
  117. package/bundled-realms/pretui/components/checkbox-card.usage.gts +114 -0
  118. package/bundled-realms/pretui/components/checkbox.examples.gts +61 -0
  119. package/bundled-realms/pretui/components/checkbox.gts +123 -0
  120. package/bundled-realms/pretui/components/checkbox.md +55 -0
  121. package/bundled-realms/pretui/components/checkbox.usage.gts +31 -0
  122. package/bundled-realms/pretui/components/chip.gts +136 -0
  123. package/bundled-realms/pretui/components/chip.md +54 -0
  124. package/bundled-realms/pretui/components/chip.usage.gts +97 -0
  125. package/bundled-realms/pretui/components/code-block.gts +888 -0
  126. package/bundled-realms/pretui/components/code-block.md +61 -0
  127. package/bundled-realms/pretui/components/code-block.usage.gts +374 -0
  128. package/bundled-realms/pretui/components/collapsed-turn.gts +44 -0
  129. package/bundled-realms/pretui/components/collapsed-turn.md +48 -0
  130. package/bundled-realms/pretui/components/collapsed-turn.usage.gts +21 -0
  131. package/bundled-realms/pretui/components/collapsible.gts +283 -0
  132. package/bundled-realms/pretui/components/collapsible.md +69 -0
  133. package/bundled-realms/pretui/components/collapsible.usage.gts +173 -0
  134. package/bundled-realms/pretui/components/color-area.gts +339 -0
  135. package/bundled-realms/pretui/components/color-area.md +49 -0
  136. package/bundled-realms/pretui/components/color-area.usage.gts +72 -0
  137. package/bundled-realms/pretui/components/color-field.gts +179 -0
  138. package/bundled-realms/pretui/components/color-field.md +47 -0
  139. package/bundled-realms/pretui/components/color-field.usage.gts +87 -0
  140. package/bundled-realms/pretui/components/color-palette.gts +198 -0
  141. package/bundled-realms/pretui/components/color-palette.md +48 -0
  142. package/bundled-realms/pretui/components/color-picker.gts +721 -0
  143. package/bundled-realms/pretui/components/color-picker.md +59 -0
  144. package/bundled-realms/pretui/components/color-picker.usage.gts +122 -0
  145. package/bundled-realms/pretui/components/color-stop-editor.gts +184 -0
  146. package/bundled-realms/pretui/components/color-stop-editor.md +46 -0
  147. package/bundled-realms/pretui/components/color-stop-editor.usage.gts +75 -0
  148. package/bundled-realms/pretui/components/combobox.gts +333 -0
  149. package/bundled-realms/pretui/components/combobox.md +49 -0
  150. package/bundled-realms/pretui/components/combobox.usage.gts +143 -0
  151. package/bundled-realms/pretui/components/command-palette.gts +982 -0
  152. package/bundled-realms/pretui/components/command-palette.md +47 -0
  153. package/bundled-realms/pretui/components/command-palette.usage.gts +95 -0
  154. package/bundled-realms/pretui/components/command.gts +2 -0
  155. package/bundled-realms/pretui/components/command.md +45 -0
  156. package/bundled-realms/pretui/components/command.usage.gts +58 -0
  157. package/bundled-realms/pretui/components/compaction-chip.gts +273 -0
  158. package/bundled-realms/pretui/components/compaction-chip.md +45 -0
  159. package/bundled-realms/pretui/components/compaction-chip.usage.gts +110 -0
  160. package/bundled-realms/pretui/components/comparison.gts +223 -0
  161. package/bundled-realms/pretui/components/comparison.md +46 -0
  162. package/bundled-realms/pretui/components/comparison.usage.gts +148 -0
  163. package/bundled-realms/pretui/components/composer.gts +566 -0
  164. package/bundled-realms/pretui/components/composer.md +59 -0
  165. package/bundled-realms/pretui/components/composer.usage.gts +173 -0
  166. package/bundled-realms/pretui/components/compound-field.gts +289 -0
  167. package/bundled-realms/pretui/components/compound-field.md +66 -0
  168. package/bundled-realms/pretui/components/compound-field.usage.gts +378 -0
  169. package/bundled-realms/pretui/components/contact-link.gts +583 -0
  170. package/bundled-realms/pretui/components/contact-link.md +53 -0
  171. package/bundled-realms/pretui/components/contact-link.usage.gts +273 -0
  172. package/bundled-realms/pretui/components/context-menu.gts +811 -0
  173. package/bundled-realms/pretui/components/context-menu.md +74 -0
  174. package/bundled-realms/pretui/components/context-menu.usage.gts +244 -0
  175. package/bundled-realms/pretui/components/copy-button.gts +237 -0
  176. package/bundled-realms/pretui/components/copy-button.md +71 -0
  177. package/bundled-realms/pretui/components/copy-button.usage.gts +135 -0
  178. package/bundled-realms/pretui/components/copy-fit.gts +396 -0
  179. package/bundled-realms/pretui/components/copy-fit.md +60 -0
  180. package/bundled-realms/pretui/components/copy-fit.usage.gts +200 -0
  181. package/bundled-realms/pretui/components/cta-band.gts +285 -0
  182. package/bundled-realms/pretui/components/cta-band.md +50 -0
  183. package/bundled-realms/pretui/components/cta-band.usage.gts +208 -0
  184. package/bundled-realms/pretui/components/cue.gts +180 -0
  185. package/bundled-realms/pretui/components/cue.md +53 -0
  186. package/bundled-realms/pretui/components/cue.usage.gts +88 -0
  187. package/bundled-realms/pretui/components/cursor-trail.gts +221 -0
  188. package/bundled-realms/pretui/components/cursor-trail.md +56 -0
  189. package/bundled-realms/pretui/components/cursor-trail.usage.gts +218 -0
  190. package/bundled-realms/pretui/components/dashboard-grid.gts +939 -0
  191. package/bundled-realms/pretui/components/dashboard-grid.md +60 -0
  192. package/bundled-realms/pretui/components/dashboard-grid.usage.gts +307 -0
  193. package/bundled-realms/pretui/components/dashboard-item.gts +286 -0
  194. package/bundled-realms/pretui/components/dashboard-item.md +52 -0
  195. package/bundled-realms/pretui/components/dashboard-item.usage.gts +87 -0
  196. package/bundled-realms/pretui/components/data-grid.gts +263 -0
  197. package/bundled-realms/pretui/components/data-grid.md +64 -0
  198. package/bundled-realms/pretui/components/data-grid.usage.gts +50 -0
  199. package/bundled-realms/pretui/components/data-table.gts +1618 -0
  200. package/bundled-realms/pretui/components/data-table.md +104 -0
  201. package/bundled-realms/pretui/components/data-table.usage.gts +324 -0
  202. package/bundled-realms/pretui/components/date-picker.gts +98 -0
  203. package/bundled-realms/pretui/components/date-picker.md +59 -0
  204. package/bundled-realms/pretui/components/date-picker.usage.gts +66 -0
  205. package/bundled-realms/pretui/components/date-range-picker.gts +131 -0
  206. package/bundled-realms/pretui/components/date-range-picker.md +55 -0
  207. package/bundled-realms/pretui/components/date-range-picker.usage.gts +125 -0
  208. package/bundled-realms/pretui/components/date-time-picker.gts +227 -0
  209. package/bundled-realms/pretui/components/date-time-picker.md +60 -0
  210. package/bundled-realms/pretui/components/date-time-picker.usage.gts +64 -0
  211. package/bundled-realms/pretui/components/defer.gts +374 -0
  212. package/bundled-realms/pretui/components/defer.md +61 -0
  213. package/bundled-realms/pretui/components/defer.usage.gts +174 -0
  214. package/bundled-realms/pretui/components/delta.gts +45 -0
  215. package/bundled-realms/pretui/components/delta.md +53 -0
  216. package/bundled-realms/pretui/components/delta.usage.gts +31 -0
  217. package/bundled-realms/pretui/components/descriptions.gts +365 -0
  218. package/bundled-realms/pretui/components/descriptions.md +73 -0
  219. package/bundled-realms/pretui/components/descriptions.usage.gts +123 -0
  220. package/bundled-realms/pretui/components/dialog.gts +153 -0
  221. package/bundled-realms/pretui/components/dialog.md +60 -0
  222. package/bundled-realms/pretui/components/dialog.usage.gts +86 -0
  223. package/bundled-realms/pretui/components/diff-block.gts +89 -0
  224. package/bundled-realms/pretui/components/diff-block.md +51 -0
  225. package/bundled-realms/pretui/components/diff-block.usage.gts +27 -0
  226. package/bundled-realms/pretui/components/disclosure.gts +2 -0
  227. package/bundled-realms/pretui/components/disclosure.md +45 -0
  228. package/bundled-realms/pretui/components/disclosure.usage.gts +47 -0
  229. package/bundled-realms/pretui/components/divider.gts +75 -0
  230. package/bundled-realms/pretui/components/divider.md +49 -0
  231. package/bundled-realms/pretui/components/divider.usage.gts +98 -0
  232. package/bundled-realms/pretui/components/doc-report.gts +306 -0
  233. package/bundled-realms/pretui/components/doc-report.md +45 -0
  234. package/bundled-realms/pretui/components/doc-report.usage.gts +126 -0
  235. package/bundled-realms/pretui/components/dock.gts +165 -0
  236. package/bundled-realms/pretui/components/dock.md +42 -0
  237. package/bundled-realms/pretui/components/dock.usage.gts +114 -0
  238. package/bundled-realms/pretui/components/drawer.gts +166 -0
  239. package/bundled-realms/pretui/components/drawer.md +66 -0
  240. package/bundled-realms/pretui/components/drawer.usage.gts +111 -0
  241. package/bundled-realms/pretui/components/dropzone.gts +314 -0
  242. package/bundled-realms/pretui/components/dropzone.md +56 -0
  243. package/bundled-realms/pretui/components/dropzone.usage.gts +203 -0
  244. package/bundled-realms/pretui/components/dueling-picklist.gts +991 -0
  245. package/bundled-realms/pretui/components/dueling-picklist.md +67 -0
  246. package/bundled-realms/pretui/components/dueling-picklist.usage.gts +182 -0
  247. package/bundled-realms/pretui/components/dynamic-island.gts +264 -0
  248. package/bundled-realms/pretui/components/dynamic-island.md +45 -0
  249. package/bundled-realms/pretui/components/dynamic-island.usage.gts +195 -0
  250. package/bundled-realms/pretui/components/easing-curve.gts +629 -0
  251. package/bundled-realms/pretui/components/easing-curve.md +46 -0
  252. package/bundled-realms/pretui/components/easing-curve.usage.gts +122 -0
  253. package/bundled-realms/pretui/components/edit-in-place.gts +559 -0
  254. package/bundled-realms/pretui/components/edit-in-place.md +63 -0
  255. package/bundled-realms/pretui/components/edit-in-place.usage.gts +209 -0
  256. package/bundled-realms/pretui/components/editable.gts +299 -0
  257. package/bundled-realms/pretui/components/editable.md +79 -0
  258. package/bundled-realms/pretui/components/editable.usage.gts +68 -0
  259. package/bundled-realms/pretui/components/email-input.gts +83 -0
  260. package/bundled-realms/pretui/components/email-input.md +52 -0
  261. package/bundled-realms/pretui/components/email-input.usage.gts +90 -0
  262. package/bundled-realms/pretui/components/emoji-button.gts +162 -0
  263. package/bundled-realms/pretui/components/emoji-button.md +46 -0
  264. package/bundled-realms/pretui/components/emoji-button.usage.gts +174 -0
  265. package/bundled-realms/pretui/components/emoji-picker.gts +1396 -0
  266. package/bundled-realms/pretui/components/emoji-picker.md +53 -0
  267. package/bundled-realms/pretui/components/emoji-picker.usage.gts +235 -0
  268. package/bundled-realms/pretui/components/empty-state.gts +162 -0
  269. package/bundled-realms/pretui/components/empty-state.md +63 -0
  270. package/bundled-realms/pretui/components/empty-state.usage.gts +113 -0
  271. package/bundled-realms/pretui/components/empty.gts +2 -0
  272. package/bundled-realms/pretui/components/empty.md +43 -0
  273. package/bundled-realms/pretui/components/empty.usage.gts +33 -0
  274. package/bundled-realms/pretui/components/entity-display.gts +126 -0
  275. package/bundled-realms/pretui/components/entity-display.md +50 -0
  276. package/bundled-realms/pretui/components/error-summary.gts +321 -0
  277. package/bundled-realms/pretui/components/error-summary.md +60 -0
  278. package/bundled-realms/pretui/components/error-summary.usage.gts +155 -0
  279. package/bundled-realms/pretui/components/expression-builder.gts +1211 -0
  280. package/bundled-realms/pretui/components/expression-builder.md +60 -0
  281. package/bundled-realms/pretui/components/expression-builder.usage.gts +246 -0
  282. package/bundled-realms/pretui/components/fab.gts +2 -0
  283. package/bundled-realms/pretui/components/fab.md +38 -0
  284. package/bundled-realms/pretui/components/fab.usage.gts +38 -0
  285. package/bundled-realms/pretui/components/feature-voting.gts +365 -0
  286. package/bundled-realms/pretui/components/feature-voting.md +44 -0
  287. package/bundled-realms/pretui/components/feature-voting.usage.gts +114 -0
  288. package/bundled-realms/pretui/components/feed.gts +244 -0
  289. package/bundled-realms/pretui/components/feed.md +56 -0
  290. package/bundled-realms/pretui/components/feed.usage.gts +250 -0
  291. package/bundled-realms/pretui/components/field-error.gts +127 -0
  292. package/bundled-realms/pretui/components/field-error.md +60 -0
  293. package/bundled-realms/pretui/components/field-error.usage.gts +146 -0
  294. package/bundled-realms/pretui/components/field.gts +185 -0
  295. package/bundled-realms/pretui/components/field.md +60 -0
  296. package/bundled-realms/pretui/components/field.usage.gts +73 -0
  297. package/bundled-realms/pretui/components/fieldset.gts +124 -0
  298. package/bundled-realms/pretui/components/fieldset.md +65 -0
  299. package/bundled-realms/pretui/components/fieldset.usage.gts +105 -0
  300. package/bundled-realms/pretui/components/file-trigger.gts +185 -0
  301. package/bundled-realms/pretui/components/file-trigger.md +53 -0
  302. package/bundled-realms/pretui/components/file-trigger.usage.gts +121 -0
  303. package/bundled-realms/pretui/components/file-upload.gts +353 -0
  304. package/bundled-realms/pretui/components/file-upload.md +63 -0
  305. package/bundled-realms/pretui/components/file-upload.usage.gts +64 -0
  306. package/bundled-realms/pretui/components/filmstrip.gts +465 -0
  307. package/bundled-realms/pretui/components/filmstrip.md +53 -0
  308. package/bundled-realms/pretui/components/filmstrip.usage.gts +115 -0
  309. package/bundled-realms/pretui/components/filter-chips.gts +236 -0
  310. package/bundled-realms/pretui/components/filter-chips.md +58 -0
  311. package/bundled-realms/pretui/components/filter-chips.usage.gts +102 -0
  312. package/bundled-realms/pretui/components/filter-set.gts +293 -0
  313. package/bundled-realms/pretui/components/filter-set.md +60 -0
  314. package/bundled-realms/pretui/components/filter-set.usage.gts +145 -0
  315. package/bundled-realms/pretui/components/float-button.gts +339 -0
  316. package/bundled-realms/pretui/components/float-button.md +69 -0
  317. package/bundled-realms/pretui/components/float-button.usage.gts +134 -0
  318. package/bundled-realms/pretui/components/fold.gts +86 -0
  319. package/bundled-realms/pretui/components/fold.md +54 -0
  320. package/bundled-realms/pretui/components/fold.usage.gts +19 -0
  321. package/bundled-realms/pretui/components/form-field.gts +609 -0
  322. package/bundled-realms/pretui/components/form-field.md +77 -0
  323. package/bundled-realms/pretui/components/form-field.usage.gts +279 -0
  324. package/bundled-realms/pretui/components/form-footer.gts +246 -0
  325. package/bundled-realms/pretui/components/form-footer.md +59 -0
  326. package/bundled-realms/pretui/components/form-footer.usage.gts +217 -0
  327. package/bundled-realms/pretui/components/form-layout.gts +130 -0
  328. package/bundled-realms/pretui/components/form-layout.md +52 -0
  329. package/bundled-realms/pretui/components/form-layout.usage.gts +200 -0
  330. package/bundled-realms/pretui/components/form-section.gts +434 -0
  331. package/bundled-realms/pretui/components/form-section.md +67 -0
  332. package/bundled-realms/pretui/components/form-section.usage.gts +402 -0
  333. package/bundled-realms/pretui/components/form.gts +315 -0
  334. package/bundled-realms/pretui/components/form.md +82 -0
  335. package/bundled-realms/pretui/components/form.usage.gts +306 -0
  336. package/bundled-realms/pretui/components/format-bytes.gts +212 -0
  337. package/bundled-realms/pretui/components/format-bytes.md +47 -0
  338. package/bundled-realms/pretui/components/format-bytes.usage.gts +274 -0
  339. package/bundled-realms/pretui/components/format-date.gts +249 -0
  340. package/bundled-realms/pretui/components/format-date.md +55 -0
  341. package/bundled-realms/pretui/components/format-date.usage.gts +245 -0
  342. package/bundled-realms/pretui/components/format-number.gts +138 -0
  343. package/bundled-realms/pretui/components/format-number.md +51 -0
  344. package/bundled-realms/pretui/components/format-number.usage.gts +261 -0
  345. package/bundled-realms/pretui/components/formatted-value.gts +65 -0
  346. package/bundled-realms/pretui/components/freestyle-usage.gts +311 -0
  347. package/bundled-realms/pretui/components/freestyle-usage.md +49 -0
  348. package/bundled-realms/pretui/components/gallery.gts +819 -0
  349. package/bundled-realms/pretui/components/gallery.md +65 -0
  350. package/bundled-realms/pretui/components/gallery.usage.gts +212 -0
  351. package/bundled-realms/pretui/components/gradient-editor.gts +682 -0
  352. package/bundled-realms/pretui/components/gradient-editor.md +43 -0
  353. package/bundled-realms/pretui/components/gradient-editor.usage.gts +69 -0
  354. package/bundled-realms/pretui/components/graph-layout.md +54 -0
  355. package/bundled-realms/pretui/components/graph-layout.usage.gts +343 -0
  356. package/bundled-realms/pretui/components/graph-outline.gts +553 -0
  357. package/bundled-realms/pretui/components/graph-outline.md +50 -0
  358. package/bundled-realms/pretui/components/graph-outline.usage.gts +88 -0
  359. package/bundled-realms/pretui/components/grid.gts +68 -0
  360. package/bundled-realms/pretui/components/grid.md +54 -0
  361. package/bundled-realms/pretui/components/grid.usage.gts +144 -0
  362. package/bundled-realms/pretui/components/handle.gts +192 -0
  363. package/bundled-realms/pretui/components/handle.md +55 -0
  364. package/bundled-realms/pretui/components/handle.usage.gts +174 -0
  365. package/bundled-realms/pretui/components/hero-split.gts +307 -0
  366. package/bundled-realms/pretui/components/hero-split.md +50 -0
  367. package/bundled-realms/pretui/components/hero-split.usage.gts +200 -0
  368. package/bundled-realms/pretui/components/hover-actions.gts +485 -0
  369. package/bundled-realms/pretui/components/hover-actions.md +55 -0
  370. package/bundled-realms/pretui/components/hover-actions.usage.gts +224 -0
  371. package/bundled-realms/pretui/components/hover-card.gts +347 -0
  372. package/bundled-realms/pretui/components/hover-card.md +72 -0
  373. package/bundled-realms/pretui/components/hover-card.usage.gts +174 -0
  374. package/bundled-realms/pretui/components/hover-video-player.gts +315 -0
  375. package/bundled-realms/pretui/components/hover-video-player.md +57 -0
  376. package/bundled-realms/pretui/components/hover-video-player.usage.gts +152 -0
  377. package/bundled-realms/pretui/components/icon-button.examples.gts +69 -0
  378. package/bundled-realms/pretui/components/icon-button.gts +153 -0
  379. package/bundled-realms/pretui/components/icon-button.md +72 -0
  380. package/bundled-realms/pretui/components/icon-button.usage.gts +208 -0
  381. package/bundled-realms/pretui/components/image-cropper.gts +693 -0
  382. package/bundled-realms/pretui/components/image-cropper.md +52 -0
  383. package/bundled-realms/pretui/components/image-cropper.usage.gts +108 -0
  384. package/bundled-realms/pretui/components/image-frame.gts +91 -0
  385. package/bundled-realms/pretui/components/image-frame.md +42 -0
  386. package/bundled-realms/pretui/components/image-frame.usage.gts +28 -0
  387. package/bundled-realms/pretui/components/image.gts +326 -0
  388. package/bundled-realms/pretui/components/image.md +71 -0
  389. package/bundled-realms/pretui/components/image.usage.gts +126 -0
  390. package/bundled-realms/pretui/components/in-view.gts +245 -0
  391. package/bundled-realms/pretui/components/in-view.md +53 -0
  392. package/bundled-realms/pretui/components/in-view.usage.gts +264 -0
  393. package/bundled-realms/pretui/components/indicator.gts +137 -0
  394. package/bundled-realms/pretui/components/indicator.md +60 -0
  395. package/bundled-realms/pretui/components/indicator.usage.gts +66 -0
  396. package/bundled-realms/pretui/components/infinite-scroll.gts +163 -0
  397. package/bundled-realms/pretui/components/infinite-scroll.md +54 -0
  398. package/bundled-realms/pretui/components/infinite-scroll.usage.gts +73 -0
  399. package/bundled-realms/pretui/components/input-group.gts +264 -0
  400. package/bundled-realms/pretui/components/input-group.md +55 -0
  401. package/bundled-realms/pretui/components/input-group.usage.gts +283 -0
  402. package/bundled-realms/pretui/components/input.examples.gts +61 -0
  403. package/bundled-realms/pretui/components/input.gts +202 -0
  404. package/bundled-realms/pretui/components/input.md +67 -0
  405. package/bundled-realms/pretui/components/input.usage.gts +208 -0
  406. package/bundled-realms/pretui/components/interactive-input.gts +343 -0
  407. package/bundled-realms/pretui/components/interactive-input.md +45 -0
  408. package/bundled-realms/pretui/components/interactive-input.usage.gts +98 -0
  409. package/bundled-realms/pretui/components/item.gts +218 -0
  410. package/bundled-realms/pretui/components/item.md +66 -0
  411. package/bundled-realms/pretui/components/item.usage.gts +121 -0
  412. package/bundled-realms/pretui/components/joystick.gts +381 -0
  413. package/bundled-realms/pretui/components/joystick.md +52 -0
  414. package/bundled-realms/pretui/components/joystick.usage.gts +140 -0
  415. package/bundled-realms/pretui/components/json-editor.gts +1016 -0
  416. package/bundled-realms/pretui/components/json-editor.md +51 -0
  417. package/bundled-realms/pretui/components/json-editor.usage.gts +230 -0
  418. package/bundled-realms/pretui/components/json-tree.gts +596 -0
  419. package/bundled-realms/pretui/components/json-tree.md +52 -0
  420. package/bundled-realms/pretui/components/json-tree.usage.gts +217 -0
  421. package/bundled-realms/pretui/components/jump-chip.gts +230 -0
  422. package/bundled-realms/pretui/components/jump-chip.md +44 -0
  423. package/bundled-realms/pretui/components/jump-chip.usage.gts +151 -0
  424. package/bundled-realms/pretui/components/kbd.gts +60 -0
  425. package/bundled-realms/pretui/components/kbd.md +50 -0
  426. package/bundled-realms/pretui/components/kbd.usage.gts +98 -0
  427. package/bundled-realms/pretui/components/key-value.gts +150 -0
  428. package/bundled-realms/pretui/components/key-value.md +81 -0
  429. package/bundled-realms/pretui/components/key-value.usage.gts +125 -0
  430. package/bundled-realms/pretui/components/known-date.gts +770 -0
  431. package/bundled-realms/pretui/components/known-date.md +56 -0
  432. package/bundled-realms/pretui/components/known-date.usage.gts +192 -0
  433. package/bundled-realms/pretui/components/label.gts +60 -0
  434. package/bundled-realms/pretui/components/label.md +56 -0
  435. package/bundled-realms/pretui/components/label.usage.gts +63 -0
  436. package/bundled-realms/pretui/components/layer-manager.gts +1884 -0
  437. package/bundled-realms/pretui/components/layer-manager.md +59 -0
  438. package/bundled-realms/pretui/components/layer-manager.usage.gts +233 -0
  439. package/bundled-realms/pretui/components/lightbox.gts +461 -0
  440. package/bundled-realms/pretui/components/lightbox.md +57 -0
  441. package/bundled-realms/pretui/components/lightbox.usage.gts +180 -0
  442. package/bundled-realms/pretui/components/line-grid.examples.gts +156 -0
  443. package/bundled-realms/pretui/components/line-grid.gts +523 -0
  444. package/bundled-realms/pretui/components/line-grid.md +55 -0
  445. package/bundled-realms/pretui/components/line-grid.usage.gts +181 -0
  446. package/bundled-realms/pretui/components/list.gts +679 -0
  447. package/bundled-realms/pretui/components/list.md +90 -0
  448. package/bundled-realms/pretui/components/list.usage.gts +203 -0
  449. package/bundled-realms/pretui/components/loader.gts +2 -0
  450. package/bundled-realms/pretui/components/loader.md +33 -0
  451. package/bundled-realms/pretui/components/loader.usage.gts +35 -0
  452. package/bundled-realms/pretui/components/loading-overlay.gts +120 -0
  453. package/bundled-realms/pretui/components/loading-overlay.md +68 -0
  454. package/bundled-realms/pretui/components/loading-overlay.usage.gts +102 -0
  455. package/bundled-realms/pretui/components/loading-state.gts +124 -0
  456. package/bundled-realms/pretui/components/loading-state.md +48 -0
  457. package/bundled-realms/pretui/components/loading-state.usage.gts +16 -0
  458. package/bundled-realms/pretui/components/lookup.gts +451 -0
  459. package/bundled-realms/pretui/components/lookup.md +59 -0
  460. package/bundled-realms/pretui/components/lookup.usage.gts +235 -0
  461. package/bundled-realms/pretui/components/magnetic.gts +158 -0
  462. package/bundled-realms/pretui/components/magnetic.md +48 -0
  463. package/bundled-realms/pretui/components/magnetic.usage.gts +125 -0
  464. package/bundled-realms/pretui/components/marquee.gts +141 -0
  465. package/bundled-realms/pretui/components/marquee.md +43 -0
  466. package/bundled-realms/pretui/components/marquee.usage.gts +116 -0
  467. package/bundled-realms/pretui/components/masonry.gts +95 -0
  468. package/bundled-realms/pretui/components/masonry.md +59 -0
  469. package/bundled-realms/pretui/components/masonry.usage.gts +238 -0
  470. package/bundled-realms/pretui/components/media-inspector.gts +145 -0
  471. package/bundled-realms/pretui/components/media-inspector.md +46 -0
  472. package/bundled-realms/pretui/components/media-inspector.usage.gts +83 -0
  473. package/bundled-realms/pretui/components/media-player.gts +1133 -0
  474. package/bundled-realms/pretui/components/media-player.md +74 -0
  475. package/bundled-realms/pretui/components/media-player.usage.gts +265 -0
  476. package/bundled-realms/pretui/components/media-viewer.gts +136 -0
  477. package/bundled-realms/pretui/components/media-viewer.md +47 -0
  478. package/bundled-realms/pretui/components/media-viewer.usage.gts +70 -0
  479. package/bundled-realms/pretui/components/mentions.gts +340 -0
  480. package/bundled-realms/pretui/components/mentions.md +65 -0
  481. package/bundled-realms/pretui/components/mentions.usage.gts +73 -0
  482. package/bundled-realms/pretui/components/menu-panel.gts +367 -0
  483. package/bundled-realms/pretui/components/menu.gts +652 -0
  484. package/bundled-realms/pretui/components/menu.md +69 -0
  485. package/bundled-realms/pretui/components/menu.usage.gts +116 -0
  486. package/bundled-realms/pretui/components/menubar.gts +1200 -0
  487. package/bundled-realms/pretui/components/menubar.md +49 -0
  488. package/bundled-realms/pretui/components/menubar.usage.gts +220 -0
  489. package/bundled-realms/pretui/components/meter.gts +113 -0
  490. package/bundled-realms/pretui/components/meter.md +50 -0
  491. package/bundled-realms/pretui/components/meter.usage.gts +50 -0
  492. package/bundled-realms/pretui/components/modal.gts +2 -0
  493. package/bundled-realms/pretui/components/modal.md +41 -0
  494. package/bundled-realms/pretui/components/modal.usage.gts +50 -0
  495. package/bundled-realms/pretui/components/model-viewer.gts +658 -0
  496. package/bundled-realms/pretui/components/model-viewer.md +57 -0
  497. package/bundled-realms/pretui/components/model-viewer.usage.gts +123 -0
  498. package/bundled-realms/pretui/components/money-input.gts +66 -0
  499. package/bundled-realms/pretui/components/money-input.md +43 -0
  500. package/bundled-realms/pretui/components/money-input.usage.gts +293 -0
  501. package/bundled-realms/pretui/components/morphing-dialog.gts +173 -0
  502. package/bundled-realms/pretui/components/morphing-dialog.md +46 -0
  503. package/bundled-realms/pretui/components/morphing-dialog.usage.gts +168 -0
  504. package/bundled-realms/pretui/components/morphing-popover.gts +245 -0
  505. package/bundled-realms/pretui/components/morphing-popover.md +47 -0
  506. package/bundled-realms/pretui/components/morphing-popover.usage.gts +176 -0
  507. package/bundled-realms/pretui/components/multi-select.gts +392 -0
  508. package/bundled-realms/pretui/components/multi-select.md +57 -0
  509. package/bundled-realms/pretui/components/multi-select.usage.gts +97 -0
  510. package/bundled-realms/pretui/components/native-select.gts +212 -0
  511. package/bundled-realms/pretui/components/native-select.md +77 -0
  512. package/bundled-realms/pretui/components/native-select.usage.gts +109 -0
  513. package/bundled-realms/pretui/components/navigation-menu.gts +351 -0
  514. package/bundled-realms/pretui/components/navigation-menu.md +65 -0
  515. package/bundled-realms/pretui/components/navigation-menu.usage.gts +61 -0
  516. package/bundled-realms/pretui/components/node-canvas.gts +1174 -0
  517. package/bundled-realms/pretui/components/node-canvas.md +57 -0
  518. package/bundled-realms/pretui/components/node-canvas.usage.gts +548 -0
  519. package/bundled-realms/pretui/components/node-card.gts +181 -0
  520. package/bundled-realms/pretui/components/node-card.md +53 -0
  521. package/bundled-realms/pretui/components/node-card.usage.gts +156 -0
  522. package/bundled-realms/pretui/components/notification.gts +242 -0
  523. package/bundled-realms/pretui/components/notification.md +69 -0
  524. package/bundled-realms/pretui/components/notification.usage.gts +125 -0
  525. package/bundled-realms/pretui/components/number-input.gts +191 -0
  526. package/bundled-realms/pretui/components/number-input.md +54 -0
  527. package/bundled-realms/pretui/components/number-input.usage.gts +132 -0
  528. package/bundled-realms/pretui/components/odometer.gts +349 -0
  529. package/bundled-realms/pretui/components/odometer.md +55 -0
  530. package/bundled-realms/pretui/components/odometer.usage.gts +258 -0
  531. package/bundled-realms/pretui/components/onboarding.gts +298 -0
  532. package/bundled-realms/pretui/components/onboarding.md +48 -0
  533. package/bundled-realms/pretui/components/onboarding.usage.gts +155 -0
  534. package/bundled-realms/pretui/components/origin-grid.gts +486 -0
  535. package/bundled-realms/pretui/components/origin-grid.md +47 -0
  536. package/bundled-realms/pretui/components/origin-grid.usage.gts +87 -0
  537. package/bundled-realms/pretui/components/otp-input.gts +289 -0
  538. package/bundled-realms/pretui/components/otp-input.md +47 -0
  539. package/bundled-realms/pretui/components/otp-input.usage.gts +131 -0
  540. package/bundled-realms/pretui/components/page-scaffold.gts +343 -0
  541. package/bundled-realms/pretui/components/page-scaffold.md +57 -0
  542. package/bundled-realms/pretui/components/page-scaffold.usage.gts +391 -0
  543. package/bundled-realms/pretui/components/pagination.gts +150 -0
  544. package/bundled-realms/pretui/components/pagination.md +56 -0
  545. package/bundled-realms/pretui/components/pagination.usage.gts +33 -0
  546. package/bundled-realms/pretui/components/panel-section.gts +301 -0
  547. package/bundled-realms/pretui/components/panel-section.md +48 -0
  548. package/bundled-realms/pretui/components/panel-section.usage.gts +137 -0
  549. package/bundled-realms/pretui/components/panel.gts +158 -0
  550. package/bundled-realms/pretui/components/panel.md +58 -0
  551. package/bundled-realms/pretui/components/panel.usage.gts +82 -0
  552. package/bundled-realms/pretui/components/password-input.gts +329 -0
  553. package/bundled-realms/pretui/components/password-input.md +58 -0
  554. package/bundled-realms/pretui/components/password-input.usage.gts +156 -0
  555. package/bundled-realms/pretui/components/password-strength.gts +485 -0
  556. package/bundled-realms/pretui/components/password-strength.md +50 -0
  557. package/bundled-realms/pretui/components/password-strength.usage.gts +34 -0
  558. package/bundled-realms/pretui/components/path-text.gts +288 -0
  559. package/bundled-realms/pretui/components/path-text.md +58 -0
  560. package/bundled-realms/pretui/components/path-text.usage.gts +239 -0
  561. package/bundled-realms/pretui/components/period-input.gts +1100 -0
  562. package/bundled-realms/pretui/components/period-input.md +54 -0
  563. package/bundled-realms/pretui/components/period-input.usage.gts +299 -0
  564. package/bundled-realms/pretui/components/phone-input.gts +80 -0
  565. package/bundled-realms/pretui/components/phone-input.md +55 -0
  566. package/bundled-realms/pretui/components/phone-input.usage.gts +91 -0
  567. package/bundled-realms/pretui/components/pin-input.gts +2 -0
  568. package/bundled-realms/pretui/components/pin-input.md +45 -0
  569. package/bundled-realms/pretui/components/pin-input.usage.gts +39 -0
  570. package/bundled-realms/pretui/components/pip-scale.gts +717 -0
  571. package/bundled-realms/pretui/components/pip-scale.md +55 -0
  572. package/bundled-realms/pretui/components/pip-scale.usage.gts +318 -0
  573. package/bundled-realms/pretui/components/popconfirm.gts +380 -0
  574. package/bundled-realms/pretui/components/popconfirm.md +78 -0
  575. package/bundled-realms/pretui/components/popconfirm.usage.gts +171 -0
  576. package/bundled-realms/pretui/components/popover.gts +198 -0
  577. package/bundled-realms/pretui/components/popover.md +57 -0
  578. package/bundled-realms/pretui/components/popover.usage.gts +106 -0
  579. package/bundled-realms/pretui/components/popup.gts +85 -0
  580. package/bundled-realms/pretui/components/popup.md +42 -0
  581. package/bundled-realms/pretui/components/popup.usage.gts +23 -0
  582. package/bundled-realms/pretui/components/presence.gts +156 -0
  583. package/bundled-realms/pretui/components/presence.md +55 -0
  584. package/bundled-realms/pretui/components/presence.usage.gts +204 -0
  585. package/bundled-realms/pretui/components/progress-bar.gts +177 -0
  586. package/bundled-realms/pretui/components/progress-bar.md +63 -0
  587. package/bundled-realms/pretui/components/progress-bar.usage.gts +172 -0
  588. package/bundled-realms/pretui/components/progress-radial.gts +67 -0
  589. package/bundled-realms/pretui/components/progress-radial.md +55 -0
  590. package/bundled-realms/pretui/components/progress-radial.usage.gts +76 -0
  591. package/bundled-realms/pretui/components/prompt-library.gts +358 -0
  592. package/bundled-realms/pretui/components/prompt-library.md +45 -0
  593. package/bundled-realms/pretui/components/prompt-library.usage.gts +117 -0
  594. package/bundled-realms/pretui/components/property-row.gts +316 -0
  595. package/bundled-realms/pretui/components/property-row.md +55 -0
  596. package/bundled-realms/pretui/components/property-row.usage.gts +146 -0
  597. package/bundled-realms/pretui/components/property-sheet.gts +133 -0
  598. package/bundled-realms/pretui/components/property-sheet.md +48 -0
  599. package/bundled-realms/pretui/components/property-sheet.usage.gts +132 -0
  600. package/bundled-realms/pretui/components/prose.gts +31 -0
  601. package/bundled-realms/pretui/components/prose.md +57 -0
  602. package/bundled-realms/pretui/components/prose.usage.gts +15 -0
  603. package/bundled-realms/pretui/components/pulsing-border.gts +297 -0
  604. package/bundled-realms/pretui/components/pulsing-border.md +65 -0
  605. package/bundled-realms/pretui/components/pulsing-border.usage.gts +253 -0
  606. package/bundled-realms/pretui/components/qr-code.gts +660 -0
  607. package/bundled-realms/pretui/components/qr-code.md +58 -0
  608. package/bundled-realms/pretui/components/qr-code.usage.gts +224 -0
  609. package/bundled-realms/pretui/components/queued-message.gts +83 -0
  610. package/bundled-realms/pretui/components/queued-message.md +53 -0
  611. package/bundled-realms/pretui/components/queued-message.usage.gts +21 -0
  612. package/bundled-realms/pretui/components/radio-card.gts +88 -0
  613. package/bundled-realms/pretui/components/radio-card.md +72 -0
  614. package/bundled-realms/pretui/components/radio-card.usage.gts +148 -0
  615. package/bundled-realms/pretui/components/radio-group.gts +119 -0
  616. package/bundled-realms/pretui/components/radio-group.md +46 -0
  617. package/bundled-realms/pretui/components/radio-group.usage.gts +80 -0
  618. package/bundled-realms/pretui/components/range-slider.gts +34 -0
  619. package/bundled-realms/pretui/components/range-slider.md +47 -0
  620. package/bundled-realms/pretui/components/range-slider.usage.gts +46 -0
  621. package/bundled-realms/pretui/components/rating.examples.gts +67 -0
  622. package/bundled-realms/pretui/components/rating.gts +266 -0
  623. package/bundled-realms/pretui/components/rating.md +55 -0
  624. package/bundled-realms/pretui/components/rating.usage.gts +96 -0
  625. package/bundled-realms/pretui/components/readiness-panel.gts +856 -0
  626. package/bundled-realms/pretui/components/readiness-panel.md +64 -0
  627. package/bundled-realms/pretui/components/readiness-panel.usage.gts +372 -0
  628. package/bundled-realms/pretui/components/recommendation.gts +316 -0
  629. package/bundled-realms/pretui/components/recommendation.md +49 -0
  630. package/bundled-realms/pretui/components/recommendation.usage.gts +103 -0
  631. package/bundled-realms/pretui/components/record-detail.gts +1170 -0
  632. package/bundled-realms/pretui/components/record-detail.md +63 -0
  633. package/bundled-realms/pretui/components/record-detail.usage.gts +533 -0
  634. package/bundled-realms/pretui/components/record-face.gts +153 -0
  635. package/bundled-realms/pretui/components/record-pill.gts +116 -0
  636. package/bundled-realms/pretui/components/record-pill.md +55 -0
  637. package/bundled-realms/pretui/components/record-pill.usage.gts +108 -0
  638. package/bundled-realms/pretui/components/relative-time.gts +88 -0
  639. package/bundled-realms/pretui/components/relative-time.md +58 -0
  640. package/bundled-realms/pretui/components/relative-time.usage.gts +89 -0
  641. package/bundled-realms/pretui/components/reorder.gts +620 -0
  642. package/bundled-realms/pretui/components/reorder.md +47 -0
  643. package/bundled-realms/pretui/components/reorder.usage.gts +171 -0
  644. package/bundled-realms/pretui/components/resizable.gts +2 -0
  645. package/bundled-realms/pretui/components/resizable.md +37 -0
  646. package/bundled-realms/pretui/components/resizable.usage.gts +53 -0
  647. package/bundled-realms/pretui/components/result-card.gts +68 -0
  648. package/bundled-realms/pretui/components/result-card.md +45 -0
  649. package/bundled-realms/pretui/components/result-card.usage.gts +29 -0
  650. package/bundled-realms/pretui/components/result.gts +204 -0
  651. package/bundled-realms/pretui/components/result.md +67 -0
  652. package/bundled-realms/pretui/components/result.usage.gts +85 -0
  653. package/bundled-realms/pretui/components/rule-row.gts +462 -0
  654. package/bundled-realms/pretui/components/rule-row.md +60 -0
  655. package/bundled-realms/pretui/components/rule-row.usage.gts +157 -0
  656. package/bundled-realms/pretui/components/scroll-area.gts +121 -0
  657. package/bundled-realms/pretui/components/scroll-area.md +59 -0
  658. package/bundled-realms/pretui/components/scroll-area.usage.gts +175 -0
  659. package/bundled-realms/pretui/components/scroll-progress.gts +222 -0
  660. package/bundled-realms/pretui/components/scroll-progress.md +48 -0
  661. package/bundled-realms/pretui/components/scroll-progress.usage.gts +162 -0
  662. package/bundled-realms/pretui/components/scroller.gts +323 -0
  663. package/bundled-realms/pretui/components/scroller.md +44 -0
  664. package/bundled-realms/pretui/components/scroller.usage.gts +184 -0
  665. package/bundled-realms/pretui/components/scrub-input.gts +691 -0
  666. package/bundled-realms/pretui/components/scrub-input.md +61 -0
  667. package/bundled-realms/pretui/components/scrub-input.usage.gts +275 -0
  668. package/bundled-realms/pretui/components/search-input.gts +141 -0
  669. package/bundled-realms/pretui/components/search-input.md +56 -0
  670. package/bundled-realms/pretui/components/search-input.usage.gts +91 -0
  671. package/bundled-realms/pretui/components/segmented-control.gts +198 -0
  672. package/bundled-realms/pretui/components/segmented-control.md +39 -0
  673. package/bundled-realms/pretui/components/segmented-control.usage.gts +66 -0
  674. package/bundled-realms/pretui/components/select.examples.gts +80 -0
  675. package/bundled-realms/pretui/components/select.gts +481 -0
  676. package/bundled-realms/pretui/components/select.md +71 -0
  677. package/bundled-realms/pretui/components/select.usage.gts +109 -0
  678. package/bundled-realms/pretui/components/separator.gts +2 -0
  679. package/bundled-realms/pretui/components/separator.md +36 -0
  680. package/bundled-realms/pretui/components/separator.usage.gts +32 -0
  681. package/bundled-realms/pretui/components/session-prep.gts +164 -0
  682. package/bundled-realms/pretui/components/session-prep.md +48 -0
  683. package/bundled-realms/pretui/components/session-prep.usage.gts +122 -0
  684. package/bundled-realms/pretui/components/sheet-toolbar.gts +130 -0
  685. package/bundled-realms/pretui/components/sheet-toolbar.md +51 -0
  686. package/bundled-realms/pretui/components/sheet-toolbar.usage.gts +151 -0
  687. package/bundled-realms/pretui/components/sheet.gts +1166 -0
  688. package/bundled-realms/pretui/components/sheet.md +78 -0
  689. package/bundled-realms/pretui/components/sheet.usage.gts +318 -0
  690. package/bundled-realms/pretui/components/sidebar.gts +1165 -0
  691. package/bundled-realms/pretui/components/sidebar.md +88 -0
  692. package/bundled-realms/pretui/components/sidebar.usage.gts +360 -0
  693. package/bundled-realms/pretui/components/signature-pad.gts +840 -0
  694. package/bundled-realms/pretui/components/signature-pad.md +57 -0
  695. package/bundled-realms/pretui/components/signature-pad.usage.gts +222 -0
  696. package/bundled-realms/pretui/components/skeleton.gts +46 -0
  697. package/bundled-realms/pretui/components/skeleton.md +56 -0
  698. package/bundled-realms/pretui/components/skeleton.usage.gts +56 -0
  699. package/bundled-realms/pretui/components/skip-link.gts +65 -0
  700. package/bundled-realms/pretui/components/skip-link.md +49 -0
  701. package/bundled-realms/pretui/components/skip-link.usage.gts +47 -0
  702. package/bundled-realms/pretui/components/slide-over.gts +2 -0
  703. package/bundled-realms/pretui/components/slide-over.md +41 -0
  704. package/bundled-realms/pretui/components/slide-over.usage.gts +50 -0
  705. package/bundled-realms/pretui/components/slider.examples.gts +61 -0
  706. package/bundled-realms/pretui/components/slider.gts +331 -0
  707. package/bundled-realms/pretui/components/slider.md +59 -0
  708. package/bundled-realms/pretui/components/slider.usage.gts +99 -0
  709. package/bundled-realms/pretui/components/sliding-highlight.gts +249 -0
  710. package/bundled-realms/pretui/components/sliding-highlight.md +58 -0
  711. package/bundled-realms/pretui/components/sliding-highlight.usage.gts +184 -0
  712. package/bundled-realms/pretui/components/snackbar.gts +2 -0
  713. package/bundled-realms/pretui/components/snackbar.md +34 -0
  714. package/bundled-realms/pretui/components/snackbar.usage.gts +31 -0
  715. package/bundled-realms/pretui/components/sonner.gts +2 -0
  716. package/bundled-realms/pretui/components/sonner.md +42 -0
  717. package/bundled-realms/pretui/components/sonner.usage.gts +43 -0
  718. package/bundled-realms/pretui/components/sparkline.gts +233 -0
  719. package/bundled-realms/pretui/components/sparkline.md +58 -0
  720. package/bundled-realms/pretui/components/sparkline.usage.gts +74 -0
  721. package/bundled-realms/pretui/components/spinner.gts +57 -0
  722. package/bundled-realms/pretui/components/spinner.md +49 -0
  723. package/bundled-realms/pretui/components/spinner.usage.gts +65 -0
  724. package/bundled-realms/pretui/components/split-panes.gts +69 -0
  725. package/bundled-realms/pretui/components/split-panes.md +54 -0
  726. package/bundled-realms/pretui/components/split-panes.usage.gts +171 -0
  727. package/bundled-realms/pretui/components/spotlight.gts +174 -0
  728. package/bundled-realms/pretui/components/spotlight.md +51 -0
  729. package/bundled-realms/pretui/components/spotlight.usage.gts +197 -0
  730. package/bundled-realms/pretui/components/stack-divider.gts +58 -0
  731. package/bundled-realms/pretui/components/stack.gts +284 -0
  732. package/bundled-realms/pretui/components/stack.md +81 -0
  733. package/bundled-realms/pretui/components/stack.usage.gts +228 -0
  734. package/bundled-realms/pretui/components/stacking-cards.gts +137 -0
  735. package/bundled-realms/pretui/components/stacking-cards.md +40 -0
  736. package/bundled-realms/pretui/components/stacking-cards.usage.gts +124 -0
  737. package/bundled-realms/pretui/components/stat.gts +216 -0
  738. package/bundled-realms/pretui/components/stat.md +57 -0
  739. package/bundled-realms/pretui/components/stat.usage.gts +16 -0
  740. package/bundled-realms/pretui/components/statement-table.examples.gts +185 -0
  741. package/bundled-realms/pretui/components/statement-table.gts +792 -0
  742. package/bundled-realms/pretui/components/statement-table.md +58 -0
  743. package/bundled-realms/pretui/components/statement-table.usage.gts +252 -0
  744. package/bundled-realms/pretui/components/status-chip.gts +37 -0
  745. package/bundled-realms/pretui/components/status-chip.md +48 -0
  746. package/bundled-realms/pretui/components/status-chip.usage.gts +36 -0
  747. package/bundled-realms/pretui/components/step-list.gts +624 -0
  748. package/bundled-realms/pretui/components/step-list.md +50 -0
  749. package/bundled-realms/pretui/components/step-list.usage.gts +166 -0
  750. package/bundled-realms/pretui/components/stepper.gts +201 -0
  751. package/bundled-realms/pretui/components/stepper.md +54 -0
  752. package/bundled-realms/pretui/components/stepper.usage.gts +103 -0
  753. package/bundled-realms/pretui/components/steps-with-media.gts +254 -0
  754. package/bundled-realms/pretui/components/steps-with-media.md +54 -0
  755. package/bundled-realms/pretui/components/steps-with-media.usage.gts +208 -0
  756. package/bundled-realms/pretui/components/streaming-text.gts +77 -0
  757. package/bundled-realms/pretui/components/streaming-text.md +55 -0
  758. package/bundled-realms/pretui/components/streaming-text.usage.gts +15 -0
  759. package/bundled-realms/pretui/components/swatch-chip.gts +104 -0
  760. package/bundled-realms/pretui/components/swatch-chip.md +47 -0
  761. package/bundled-realms/pretui/components/swatch-chip.usage.gts +21 -0
  762. package/bundled-realms/pretui/components/swatch.gts +141 -0
  763. package/bundled-realms/pretui/components/swatch.md +50 -0
  764. package/bundled-realms/pretui/components/swatch.usage.gts +80 -0
  765. package/bundled-realms/pretui/components/switch.examples.gts +53 -0
  766. package/bundled-realms/pretui/components/switch.gts +118 -0
  767. package/bundled-realms/pretui/components/switch.md +62 -0
  768. package/bundled-realms/pretui/components/switch.usage.gts +59 -0
  769. package/bundled-realms/pretui/components/table-of-contents.gts +384 -0
  770. package/bundled-realms/pretui/components/table-of-contents.md +75 -0
  771. package/bundled-realms/pretui/components/table-of-contents.usage.gts +270 -0
  772. package/bundled-realms/pretui/components/table.gts +158 -0
  773. package/bundled-realms/pretui/components/table.md +80 -0
  774. package/bundled-realms/pretui/components/table.usage.gts +44 -0
  775. package/bundled-realms/pretui/components/tabs.gts +117 -0
  776. package/bundled-realms/pretui/components/tabs.md +58 -0
  777. package/bundled-realms/pretui/components/tabs.usage.gts +94 -0
  778. package/bundled-realms/pretui/components/tags-input.gts +52 -0
  779. package/bundled-realms/pretui/components/tags-input.md +48 -0
  780. package/bundled-realms/pretui/components/tags-input.usage.gts +56 -0
  781. package/bundled-realms/pretui/components/task-row.gts +483 -0
  782. package/bundled-realms/pretui/components/task-row.md +48 -0
  783. package/bundled-realms/pretui/components/task-row.usage.gts +119 -0
  784. package/bundled-realms/pretui/components/terminal-animation.gts +355 -0
  785. package/bundled-realms/pretui/components/terminal-animation.md +49 -0
  786. package/bundled-realms/pretui/components/terminal-animation.usage.gts +110 -0
  787. package/bundled-realms/pretui/components/text-effects.gts +339 -0
  788. package/bundled-realms/pretui/components/text-effects.md +49 -0
  789. package/bundled-realms/pretui/components/text-effects.usage.gts +192 -0
  790. package/bundled-realms/pretui/components/text-morph.gts +292 -0
  791. package/bundled-realms/pretui/components/text-morph.md +45 -0
  792. package/bundled-realms/pretui/components/text-morph.usage.gts +117 -0
  793. package/bundled-realms/pretui/components/text-rotate.gts +121 -0
  794. package/bundled-realms/pretui/components/text-rotate.md +44 -0
  795. package/bundled-realms/pretui/components/text-rotate.usage.gts +73 -0
  796. package/bundled-realms/pretui/components/text-scramble.gts +189 -0
  797. package/bundled-realms/pretui/components/text-scramble.md +42 -0
  798. package/bundled-realms/pretui/components/text-scramble.usage.gts +80 -0
  799. package/bundled-realms/pretui/components/text-shimmer.gts +89 -0
  800. package/bundled-realms/pretui/components/text-shimmer.md +42 -0
  801. package/bundled-realms/pretui/components/text-shimmer.usage.gts +69 -0
  802. package/bundled-realms/pretui/components/textarea.gts +112 -0
  803. package/bundled-realms/pretui/components/textarea.md +51 -0
  804. package/bundled-realms/pretui/components/textarea.usage.gts +100 -0
  805. package/bundled-realms/pretui/components/theme-frame.gts +272 -0
  806. package/bundled-realms/pretui/components/theme-frame.md +48 -0
  807. package/bundled-realms/pretui/components/thinking.gts +431 -0
  808. package/bundled-realms/pretui/components/thinking.md +47 -0
  809. package/bundled-realms/pretui/components/thinking.usage.gts +134 -0
  810. package/bundled-realms/pretui/components/tilt.gts +194 -0
  811. package/bundled-realms/pretui/components/tilt.md +50 -0
  812. package/bundled-realms/pretui/components/tilt.usage.gts +174 -0
  813. package/bundled-realms/pretui/components/time-input.gts +583 -0
  814. package/bundled-realms/pretui/components/time-input.md +51 -0
  815. package/bundled-realms/pretui/components/time-input.usage.gts +110 -0
  816. package/bundled-realms/pretui/components/timeline.gts +269 -0
  817. package/bundled-realms/pretui/components/timeline.md +63 -0
  818. package/bundled-realms/pretui/components/timeline.usage.gts +180 -0
  819. package/bundled-realms/pretui/components/toast.gts +85 -0
  820. package/bundled-realms/pretui/components/toast.md +57 -0
  821. package/bundled-realms/pretui/components/toast.usage.gts +18 -0
  822. package/bundled-realms/pretui/components/toaster.gts +808 -0
  823. package/bundled-realms/pretui/components/toaster.md +83 -0
  824. package/bundled-realms/pretui/components/toaster.usage.gts +256 -0
  825. package/bundled-realms/pretui/components/toggle-group.gts +435 -0
  826. package/bundled-realms/pretui/components/toggle-group.md +59 -0
  827. package/bundled-realms/pretui/components/toggle-group.usage.gts +260 -0
  828. package/bundled-realms/pretui/components/toggle-matrix.gts +994 -0
  829. package/bundled-realms/pretui/components/toggle-matrix.md +44 -0
  830. package/bundled-realms/pretui/components/toggle-matrix.usage.gts +243 -0
  831. package/bundled-realms/pretui/components/toggle.gts +235 -0
  832. package/bundled-realms/pretui/components/toggle.md +59 -0
  833. package/bundled-realms/pretui/components/toggle.usage.gts +244 -0
  834. package/bundled-realms/pretui/components/token-input.gts +483 -0
  835. package/bundled-realms/pretui/components/token-input.md +50 -0
  836. package/bundled-realms/pretui/components/token-input.usage.gts +137 -0
  837. package/bundled-realms/pretui/components/token.gts +197 -0
  838. package/bundled-realms/pretui/components/token.md +63 -0
  839. package/bundled-realms/pretui/components/token.usage.gts +128 -0
  840. package/bundled-realms/pretui/components/toolbar.gts +62 -0
  841. package/bundled-realms/pretui/components/toolbar.md +50 -0
  842. package/bundled-realms/pretui/components/toolbar.usage.gts +78 -0
  843. package/bundled-realms/pretui/components/tooltip.gts +212 -0
  844. package/bundled-realms/pretui/components/tooltip.md +53 -0
  845. package/bundled-realms/pretui/components/tooltip.usage.gts +64 -0
  846. package/bundled-realms/pretui/components/tour.gts +436 -0
  847. package/bundled-realms/pretui/components/tour.md +62 -0
  848. package/bundled-realms/pretui/components/tour.usage.gts +70 -0
  849. package/bundled-realms/pretui/components/transfer.gts +2 -0
  850. package/bundled-realms/pretui/components/transfer.md +39 -0
  851. package/bundled-realms/pretui/components/transfer.usage.gts +52 -0
  852. package/bundled-realms/pretui/components/transmute.gts +103 -0
  853. package/bundled-realms/pretui/components/transmute.md +49 -0
  854. package/bundled-realms/pretui/components/transmute.usage.gts +16 -0
  855. package/bundled-realms/pretui/components/tree-select.gts +596 -0
  856. package/bundled-realms/pretui/components/tree-select.md +70 -0
  857. package/bundled-realms/pretui/components/tree-select.usage.gts +75 -0
  858. package/bundled-realms/pretui/components/tree.gts +532 -0
  859. package/bundled-realms/pretui/components/tree.md +68 -0
  860. package/bundled-realms/pretui/components/tree.usage.gts +278 -0
  861. package/bundled-realms/pretui/components/trim-bar.gts +611 -0
  862. package/bundled-realms/pretui/components/trim-bar.md +48 -0
  863. package/bundled-realms/pretui/components/trim-bar.usage.gts +112 -0
  864. package/bundled-realms/pretui/components/typewriter.gts +122 -0
  865. package/bundled-realms/pretui/components/typewriter.md +45 -0
  866. package/bundled-realms/pretui/components/typewriter.usage.gts +105 -0
  867. package/bundled-realms/pretui/components/typography.gts +379 -0
  868. package/bundled-realms/pretui/components/typography.md +77 -0
  869. package/bundled-realms/pretui/components/typography.usage.gts +52 -0
  870. package/bundled-realms/pretui/components/url-input.gts +130 -0
  871. package/bundled-realms/pretui/components/url-input.md +58 -0
  872. package/bundled-realms/pretui/components/url-input.usage.gts +97 -0
  873. package/bundled-realms/pretui/components/usage-action.gts +16 -0
  874. package/bundled-realms/pretui/components/usage-argument.gts +109 -0
  875. package/bundled-realms/pretui/components/usage-argument.md +44 -0
  876. package/bundled-realms/pretui/components/usage-array.gts +80 -0
  877. package/bundled-realms/pretui/components/usage-array.md +47 -0
  878. package/bundled-realms/pretui/components/usage-bool.gts +62 -0
  879. package/bundled-realms/pretui/components/usage-bool.md +47 -0
  880. package/bundled-realms/pretui/components/usage-component-arg.gts +16 -0
  881. package/bundled-realms/pretui/components/usage-css-variable.gts +56 -0
  882. package/bundled-realms/pretui/components/usage-css-variable.md +48 -0
  883. package/bundled-realms/pretui/components/usage-number.gts +127 -0
  884. package/bundled-realms/pretui/components/usage-number.md +48 -0
  885. package/bundled-realms/pretui/components/usage-object.gts +58 -0
  886. package/bundled-realms/pretui/components/usage-object.md +48 -0
  887. package/bundled-realms/pretui/components/usage-string.gts +89 -0
  888. package/bundled-realms/pretui/components/usage-string.md +46 -0
  889. package/bundled-realms/pretui/components/usage-yield.gts +16 -0
  890. package/bundled-realms/pretui/components/value-input.gts +265 -0
  891. package/bundled-realms/pretui/components/value-input.md +49 -0
  892. package/bundled-realms/pretui/components/value-input.usage.gts +176 -0
  893. package/bundled-realms/pretui/components/video-player.gts +80 -0
  894. package/bundled-realms/pretui/components/video-player.md +46 -0
  895. package/bundled-realms/pretui/components/video-player.usage.gts +107 -0
  896. package/bundled-realms/pretui/components/viewport.gts +520 -0
  897. package/bundled-realms/pretui/components/viewport.md +55 -0
  898. package/bundled-realms/pretui/components/visually-hidden.gts +49 -0
  899. package/bundled-realms/pretui/components/visually-hidden.md +47 -0
  900. package/bundled-realms/pretui/components/visually-hidden.usage.gts +27 -0
  901. package/bundled-realms/pretui/components/watermark.gts +141 -0
  902. package/bundled-realms/pretui/components/watermark.md +58 -0
  903. package/bundled-realms/pretui/components/watermark.usage.gts +63 -0
  904. package/bundled-realms/pretui/components/waveform.gts +376 -0
  905. package/bundled-realms/pretui/components/waveform.md +56 -0
  906. package/bundled-realms/pretui/components/waveform.usage.gts +131 -0
  907. package/bundled-realms/pretui/components/wizard.gts +677 -0
  908. package/bundled-realms/pretui/components/wizard.md +58 -0
  909. package/bundled-realms/pretui/components/wizard.usage.gts +188 -0
  910. package/bundled-realms/pretui/components/work-item.gts +207 -0
  911. package/bundled-realms/pretui/components/work-item.md +58 -0
  912. package/bundled-realms/pretui/components/work-item.usage.gts +103 -0
  913. package/bundled-realms/pretui/components/zoomable-frame.gts +541 -0
  914. package/bundled-realms/pretui/components/zoomable-frame.md +50 -0
  915. package/bundled-realms/pretui/components/zoomable-frame.usage.gts +175 -0
  916. package/bundled-realms/pretui/cropper/LICENSE +21 -0
  917. package/bundled-realms/pretui/cropper/README.md +92 -0
  918. package/bundled-realms/pretui/cropper/index.js +81 -0
  919. package/bundled-realms/pretui/data-component.gts +1161 -0
  920. package/bundled-realms/pretui/demo-design-layers.gts +112 -0
  921. package/bundled-realms/pretui/demo-design-tools.gts +463 -0
  922. package/bundled-realms/pretui/demo-design-value.gts +9 -0
  923. package/bundled-realms/pretui/demo-forms-core.gts +82 -0
  924. package/bundled-realms/pretui/demo-forms-expression.gts +76 -0
  925. package/bundled-realms/pretui/demo-forms-record.gts +16 -0
  926. package/bundled-realms/pretui/demo-foundations-more.gts +10 -0
  927. package/bundled-realms/pretui/demo-foundations.gts +8 -0
  928. package/bundled-realms/pretui/demo-ink-feedback.gts +12 -0
  929. package/bundled-realms/pretui/demo-json.gts +17 -0
  930. package/bundled-realms/pretui/demo-locations.ts +103 -0
  931. package/bundled-realms/pretui/demo-media-library.gts +101 -0
  932. package/bundled-realms/pretui/demo-media.gts +6 -0
  933. package/bundled-realms/pretui/demo-menu.gts +182 -0
  934. package/bundled-realms/pretui/demo-motion-core.gts +4 -0
  935. package/bundled-realms/pretui/demo-motion-pointer.gts +21 -0
  936. package/bundled-realms/pretui/demo-reading-format.gts +10 -0
  937. package/bundled-realms/pretui/demo-structure-dashboard.gts +212 -0
  938. package/bundled-realms/pretui/demo-structure-data.gts +4 -0
  939. package/bundled-realms/pretui/demo-structure-scroll.gts +19 -0
  940. package/bundled-realms/pretui/demo-structure.gts +21 -0
  941. package/bundled-realms/pretui/demo-surfaces-grid.gts +104 -0
  942. package/bundled-realms/pretui/demo-texture.gts +21 -0
  943. package/bundled-realms/pretui/docs/catalog-taxonomy.md +200 -0
  944. package/bundled-realms/pretui/docs/composites.md +13 -0
  945. package/bundled-realms/pretui/docs/reading.md +12 -0
  946. package/bundled-realms/pretui/docs/structure.md +8 -0
  947. package/bundled-realms/pretui/emoji-data/LICENSE +202 -0
  948. package/bundled-realms/pretui/emoji-data/LICENSE.data +202 -0
  949. package/bundled-realms/pretui/emoji-data/LICENSE.emojibase +21 -0
  950. package/bundled-realms/pretui/emoji-data/LICENSE.unicode +39 -0
  951. package/bundled-realms/pretui/emoji-data/README.md +360 -0
  952. package/bundled-realms/pretui/emoji-data/data.ts +45 -0
  953. package/bundled-realms/pretui/emoji-data/engine.ts +465 -0
  954. package/bundled-realms/pretui/example-gallery.gts +129 -0
  955. package/bundled-realms/pretui/examples-kit.gts +228 -0
  956. package/bundled-realms/pretui/examples-listing.gts +51 -0
  957. package/bundled-realms/pretui/examples.gts +584 -0
  958. package/bundled-realms/pretui/focus.gts +459 -0
  959. package/bundled-realms/pretui/gridstack/LICENSE +21 -0
  960. package/bundled-realms/pretui/gridstack/README.md +103 -0
  961. package/bundled-realms/pretui/gridstack/index.js +169 -0
  962. package/bundled-realms/pretui/icon-registry.gts +753 -0
  963. package/bundled-realms/pretui/index.json +11 -0
  964. package/bundled-realms/pretui/internal/agentic-chat.gts +101 -0
  965. package/bundled-realms/pretui/internal/blocks.gts +35 -0
  966. package/bundled-realms/pretui/internal/choice-cards.gts +258 -0
  967. package/bundled-realms/pretui/internal/color-fixtures.gts +3 -0
  968. package/bundled-realms/pretui/internal/composites-fixtures.gts +16 -0
  969. package/bundled-realms/pretui/internal/corner-mark.gts +83 -0
  970. package/bundled-realms/pretui/internal/design-tools.gts +881 -0
  971. package/bundled-realms/pretui/internal/extras.gts +31 -0
  972. package/bundled-realms/pretui/internal/feedback.gts +27 -0
  973. package/bundled-realms/pretui/internal/file-intake-fixtures.gts +17 -0
  974. package/bundled-realms/pretui/internal/file-intake.gts +193 -0
  975. package/bundled-realms/pretui/internal/forms-core.gts +394 -0
  976. package/bundled-realms/pretui/internal/forms-expression.gts +837 -0
  977. package/bundled-realms/pretui/internal/forms-picker-fixtures.gts +10 -0
  978. package/bundled-realms/pretui/internal/forms-picker.gts +129 -0
  979. package/bundled-realms/pretui/internal/forms-record.gts +173 -0
  980. package/bundled-realms/pretui/internal/freestyle.gts +117 -0
  981. package/bundled-realms/pretui/internal/ink.gts +25 -0
  982. package/bundled-realms/pretui/internal/json-tree.gts +526 -0
  983. package/bundled-realms/pretui/internal/keep-style.gts +168 -0
  984. package/bundled-realms/pretui/internal/media-assets.gts +10 -0
  985. package/bundled-realms/pretui/internal/media-library.gts +14 -0
  986. package/bundled-realms/pretui/internal/media-viewer.gts +322 -0
  987. package/bundled-realms/pretui/internal/media-wave.gts +270 -0
  988. package/bundled-realms/pretui/internal/menu.gts +522 -0
  989. package/bundled-realms/pretui/internal/money-fixtures.gts +6 -0
  990. package/bundled-realms/pretui/internal/money.gts +477 -0
  991. package/bundled-realms/pretui/internal/motion-core.gts +54 -0
  992. package/bundled-realms/pretui/internal/motion-pointer.gts +234 -0
  993. package/bundled-realms/pretui/internal/overlay-confirm.gts +35 -0
  994. package/bundled-realms/pretui/internal/overlay.gts +291 -0
  995. package/bundled-realms/pretui/internal/reading-extras.gts +56 -0
  996. package/bundled-realms/pretui/internal/reading-format.gts +232 -0
  997. package/bundled-realms/pretui/internal/reading-listing.gts +232 -0
  998. package/bundled-realms/pretui/internal/structure-chart.gts +414 -0
  999. package/bundled-realms/pretui/internal/structure-dashboard.gts +503 -0
  1000. package/bundled-realms/pretui/internal/structure-flow.gts +48 -0
  1001. package/bundled-realms/pretui/internal/structure-layout-fixtures.gts +36 -0
  1002. package/bundled-realms/pretui/internal/structure-layout.gts +99 -0
  1003. package/bundled-realms/pretui/internal/structure-morph.gts +140 -0
  1004. package/bundled-realms/pretui/internal/structure-scenes.gts +25 -0
  1005. package/bundled-realms/pretui/internal/structure-scroll.gts +72 -0
  1006. package/bundled-realms/pretui/internal/structure-shell-fixtures.gts +25 -0
  1007. package/bundled-realms/pretui/internal/surfaces-canvas-fixtures.gts +5 -0
  1008. package/bundled-realms/pretui/internal/surfaces-canvas.gts +283 -0
  1009. package/bundled-realms/pretui/internal/texture.gts +81 -0
  1010. package/bundled-realms/pretui/internal/toggle-controls-fixtures.gts +7 -0
  1011. package/bundled-realms/pretui/internal/toggle-controls.gts +81 -0
  1012. package/bundled-realms/pretui/json-model.ts +1981 -0
  1013. package/bundled-realms/pretui/media-chrome/LICENSE +19 -0
  1014. package/bundled-realms/pretui/media-chrome/README.md +111 -0
  1015. package/bundled-realms/pretui/media-chrome/index.js +1647 -0
  1016. package/bundled-realms/pretui/media-examples.gts +315 -0
  1017. package/bundled-realms/pretui/model-viewer/LICENSE +202 -0
  1018. package/{LICENSE → bundled-realms/pretui/model-viewer/LICENSE-gainmap-js} +1 -1
  1019. package/bundled-realms/pretui/model-viewer/LICENSE-lit +28 -0
  1020. package/bundled-realms/pretui/model-viewer/LICENSE-three +21 -0
  1021. package/bundled-realms/pretui/model-viewer/NOTICE +67 -0
  1022. package/bundled-realms/pretui/model-viewer/README.md +122 -0
  1023. package/bundled-realms/pretui/model-viewer/index.js +6413 -0
  1024. package/bundled-realms/pretui/package.json +51 -0
  1025. package/bundled-realms/pretui/photoswipe/LICENSE +21 -0
  1026. package/bundled-realms/pretui/photoswipe/README.md +91 -0
  1027. package/bundled-realms/pretui/photoswipe/index.js +149 -0
  1028. package/bundled-realms/pretui/photoswipe/style.ts +465 -0
  1029. package/bundled-realms/pretui/plot/LICENSE +13 -0
  1030. package/bundled-realms/pretui/plot/LICENSE.d3 +13 -0
  1031. package/bundled-realms/pretui/plot/LICENSE.interval-tree-1d +22 -0
  1032. package/bundled-realms/pretui/plot/LICENSE.isoformat +13 -0
  1033. package/bundled-realms/pretui/plot/README.md +35 -0
  1034. package/bundled-realms/pretui/plot/index.d.ts +31 -0
  1035. package/bundled-realms/pretui/plot/index.js +449 -0
  1036. package/bundled-realms/pretui/pretui-component.gts +1336 -0
  1037. package/bundled-realms/pretui/pretui-css.gts +380 -0
  1038. package/bundled-realms/pretui/pretui-primitives.gts +162 -0
  1039. package/bundled-realms/pretui/qrcode/LICENSE +34 -0
  1040. package/bundled-realms/pretui/qrcode/README.md +87 -0
  1041. package/bundled-realms/pretui/qrcode/index.js +35 -0
  1042. package/bundled-realms/pretui/realm.json +16 -0
  1043. package/bundled-realms/pretui/registry.ts +40 -0
  1044. package/bundled-realms/pretui/sigpad/LICENSE +21 -0
  1045. package/bundled-realms/pretui/sigpad/README.md +103 -0
  1046. package/bundled-realms/pretui/sigpad/index.js +30 -0
  1047. package/bundled-realms/pretui/structure-dashboard-css.ts +166 -0
  1048. package/bundled-realms/pretui/surfaces/README.md +37 -0
  1049. package/bundled-realms/pretui/surfaces/canvas/LICENSE.d3 +168 -0
  1050. package/bundled-realms/pretui/surfaces/canvas/LICENSE.xyflow +21 -0
  1051. package/bundled-realms/pretui/surfaces/canvas/index.js +25420 -0
  1052. package/bundled-realms/pretui/surfaces/grid/LICENSE.tanstack +50 -0
  1053. package/bundled-realms/pretui/surfaces/grid/index.js +21478 -0
  1054. package/bundled-realms/pretui/surfaces/layout/index.js +9036 -0
  1055. package/bundled-realms/pretui/surfaces-canvas-css.ts +1640 -0
  1056. package/bundled-realms/pretui/surfaces-canvas-layout.ts +607 -0
  1057. package/bundled-realms/pretui/tsconfig.json +54 -0
  1058. package/bundled-realms/pretui/wavesurfer/LICENSE +29 -0
  1059. package/bundled-realms/pretui/wavesurfer/README.md +85 -0
  1060. package/bundled-realms/pretui/wavesurfer/index.js +184 -0
  1061. package/bundled-realms/pretui/zxcvbn/LICENSE +21 -0
  1062. package/bundled-realms/pretui/zxcvbn/README.md +192 -0
  1063. package/bundled-realms/pretui/zxcvbn/index.d.ts +28 -0
  1064. package/bundled-realms/pretui/zxcvbn/index.js +5931 -0
  1065. package/bundled-test-harness/index.html +1 -1
  1066. package/bundled-test-harness/tests/index.html +1 -1
  1067. package/dist/api.js +1 -1
  1068. package/dist/index.js +33 -33
  1069. package/package.json +1 -1
  1070. package/src/lib/test-engine.ts +14 -4
@@ -0,0 +1,1981 @@
1
+ /**
2
+ * json-model.ts — Pretui's JSON document model.
3
+ *
4
+ * A precision-preserving, diagnostic-emitting JSON parser plus an immutable
5
+ * edit algebra. Pure logic: no DOM, no Glimmer, no timers, no `Date.now()`,
6
+ * no `Math.random()`. Safe to evaluate anywhere in the realm graph.
7
+ *
8
+ * Ported from the interaction model and edge-case handling of JsonTree.js
9
+ * v4.7.1 (MIT, (c) 2025 William Troup / Bunoon). No JsonTree.js code is
10
+ * vendored — see `json-tree.gts` for the porting rationale.
11
+ *
12
+ * BETTER THAN THE INSPIRATION — the four things upstream gets wrong:
13
+ *
14
+ * 1. Upstream's `Convert.jsonStringToObject` falls back to `eval()` when
15
+ * `JSON.parse` throws. That is arbitrary code execution on user input.
16
+ * We hand-roll a tokenizer instead and never evaluate anything.
17
+ * 2. Upstream deletes a key when you clear its value, so `""` is
18
+ * unreachable and a slip of the keyboard is silent data loss. Here,
19
+ * clearing a string yields `""`; removal is only ever an explicit op.
20
+ * 3. Upstream's `Convert.stringToDataTypeValue` coerces every edit back to
21
+ * the ORIGINAL value's type and returns `null` (edit silently dropped)
22
+ * when it cannot. Here, type is an explicit operation and a value that
23
+ * cannot be interpreted stays pending with a diagnostic attached.
24
+ * 4. Upstream round-trips through `JSON.parse`, so a 25-digit integer
25
+ * silently becomes a different number. Here every number keeps its
26
+ * source literal and is re-emitted verbatim.
27
+ */
28
+
29
+ /** A location inside a JSON document. Object steps are keys; array steps are indices. */
30
+ export type JsonPath = ReadonlyArray<string | number>;
31
+
32
+ /** The six JSON types, as a closed union. */
33
+ export type JsonKind =
34
+ | 'null'
35
+ | 'boolean'
36
+ | 'number'
37
+ | 'string'
38
+ | 'array'
39
+ | 'object';
40
+
41
+ /**
42
+ * One member of an object. Objects are modelled as an ORDERED LIST of entries
43
+ * rather than a JS object so that key order survives editing and duplicate
44
+ * keys survive parsing (a plain object would silently drop all but the last).
45
+ */
46
+ export interface JsonEntry {
47
+ readonly key: string;
48
+ readonly node: JsonNode;
49
+ }
50
+
51
+ export type JsonNode =
52
+ | { readonly kind: 'null' }
53
+ | { readonly kind: 'boolean'; readonly value: boolean }
54
+ /**
55
+ * `literal` is the exact source text of the number. It is what gets
56
+ * re-emitted, so integers beyond `Number.MAX_SAFE_INTEGER` and
57
+ * high-precision decimals round-trip byte-for-byte even though `value`
58
+ * (the IEEE-754 reading, kept for display and arithmetic) cannot hold them.
59
+ */
60
+ | {
61
+ readonly kind: 'number';
62
+ readonly value: number;
63
+ readonly literal: string;
64
+ }
65
+ | { readonly kind: 'string'; readonly value: string }
66
+ | { readonly kind: 'array'; readonly items: ReadonlyArray<JsonNode> }
67
+ | { readonly kind: 'object'; readonly entries: ReadonlyArray<JsonEntry> };
68
+
69
+ export type DiagnosticCode =
70
+ | 'unexpected-end'
71
+ | 'unexpected-token'
72
+ | 'trailing-content'
73
+ | 'bad-number'
74
+ | 'bad-string'
75
+ | 'bad-escape'
76
+ | 'lone-surrogate'
77
+ | 'control-character'
78
+ | 'duplicate-key'
79
+ | 'number-precision'
80
+ | 'empty-document'
81
+ | 'pending-value';
82
+
83
+ export interface JsonDiagnostic {
84
+ readonly severity: 'error' | 'warning';
85
+ readonly code: DiagnosticCode;
86
+ /** Human-readable, already sentence-cased. Safe to render directly. */
87
+ readonly message: string;
88
+ /** Zero-based character offset into the source text, when known. */
89
+ readonly offset: number;
90
+ /** One-based line number, for gutter display. */
91
+ readonly line: number;
92
+ /** One-based column number. */
93
+ readonly column: number;
94
+ /** Where in the document tree the problem sits, when known. */
95
+ readonly path?: JsonPath;
96
+ }
97
+
98
+ export interface ParseSuccess {
99
+ readonly ok: true;
100
+ readonly root: JsonNode;
101
+ /**
102
+ * Non-fatal findings: duplicate keys, numbers that exceed IEEE-754
103
+ * precision, lone surrogates. The document parsed; the caller decides
104
+ * whether these matter.
105
+ */
106
+ readonly diagnostics: ReadonlyArray<JsonDiagnostic>;
107
+ }
108
+
109
+ export interface ParseFailure {
110
+ readonly ok: false;
111
+ readonly diagnostics: ReadonlyArray<JsonDiagnostic>;
112
+ /**
113
+ * TRUE when the text ran out mid-value — `{"a": ` or `[1,`. This is the
114
+ * signature of a half-typed document, which is a PENDING state, not a
115
+ * wrong one. UI should stay neutral for `incomplete`, and only show a
116
+ * hard error when this is false.
117
+ */
118
+ readonly incomplete: boolean;
119
+ }
120
+
121
+ export type ParseResult = ParseSuccess | ParseFailure;
122
+
123
+ /* ------------------------------------------------------------------ *
124
+ * Parser
125
+ * ------------------------------------------------------------------ */
126
+
127
+ const BACKSLASH = '\\';
128
+ const QUOTE = '"';
129
+
130
+ interface Cursor {
131
+ readonly text: string;
132
+ pos: number;
133
+ }
134
+
135
+ /** Convert a character offset into 1-based line/column for gutter display. */
136
+ function locate(
137
+ text: string,
138
+ offset: number,
139
+ ): { line: number; column: number } {
140
+ let line = 1;
141
+ let lineStart = 0;
142
+ const limit = Math.min(offset, text.length);
143
+ for (let i = 0; i < limit; i++) {
144
+ if (text.charCodeAt(i) === 10) {
145
+ line++;
146
+ lineStart = i + 1;
147
+ }
148
+ }
149
+ return { line, column: limit - lineStart + 1 };
150
+ }
151
+
152
+ function diagnostic(
153
+ text: string,
154
+ offset: number,
155
+ severity: 'error' | 'warning',
156
+ code: DiagnosticCode,
157
+ message: string,
158
+ path?: JsonPath,
159
+ ): JsonDiagnostic {
160
+ const at = locate(text, offset);
161
+ return {
162
+ severity,
163
+ code,
164
+ message,
165
+ offset,
166
+ line: at.line,
167
+ column: at.column,
168
+ ...(path ? { path } : {}),
169
+ };
170
+ }
171
+
172
+ /** Thrown internally to unwind the recursive-descent parser. Never escapes `parseJson`. */
173
+ class ParseAbort extends Error {
174
+ readonly diag: JsonDiagnostic;
175
+ readonly incomplete: boolean;
176
+ constructor(diag: JsonDiagnostic, incomplete: boolean) {
177
+ super(diag.message);
178
+ this.diag = diag;
179
+ this.incomplete = incomplete;
180
+ }
181
+ }
182
+
183
+ function isWhitespace(code: number): boolean {
184
+ return code === 32 || code === 9 || code === 10 || code === 13;
185
+ }
186
+
187
+ function skipWhitespace(cur: Cursor): void {
188
+ while (
189
+ cur.pos < cur.text.length &&
190
+ isWhitespace(cur.text.charCodeAt(cur.pos))
191
+ ) {
192
+ cur.pos++;
193
+ }
194
+ }
195
+
196
+ function abortAtEnd(cur: Cursor, what: string): never {
197
+ throw new ParseAbort(
198
+ diagnostic(
199
+ cur.text,
200
+ cur.text.length,
201
+ 'error',
202
+ 'unexpected-end',
203
+ `The document ends before ${what} is complete.`,
204
+ ),
205
+ true,
206
+ );
207
+ }
208
+
209
+ /**
210
+ * Normalise a JSON number literal to `{negative, significand, exponent}` with
211
+ * no leading or trailing zeros, so two literals can be compared for exact
212
+ * mathematical equality. Used to detect precision loss without any float
213
+ * arithmetic.
214
+ */
215
+ function canonicalNumber(literal: string): {
216
+ negative: boolean;
217
+ significand: string;
218
+ exponent: number;
219
+ } {
220
+ let rest = literal;
221
+ let negative = false;
222
+ if (rest.startsWith('-')) {
223
+ negative = true;
224
+ rest = rest.slice(1);
225
+ } else if (rest.startsWith('+')) {
226
+ rest = rest.slice(1);
227
+ }
228
+
229
+ let exponent = 0;
230
+ const eIndex = rest.search(/[eE]/);
231
+ if (eIndex >= 0) {
232
+ exponent = parseInt(rest.slice(eIndex + 1), 10) || 0;
233
+ rest = rest.slice(0, eIndex);
234
+ }
235
+
236
+ const dotIndex = rest.indexOf('.');
237
+ let digits = rest;
238
+ if (dotIndex >= 0) {
239
+ const fraction = rest.slice(dotIndex + 1);
240
+ digits = rest.slice(0, dotIndex) + fraction;
241
+ exponent -= fraction.length;
242
+ }
243
+
244
+ // Strip leading zeros.
245
+ let start = 0;
246
+ while (start < digits.length - 1 && digits.charCodeAt(start) === 48) {
247
+ start++;
248
+ }
249
+ digits = digits.slice(start);
250
+
251
+ // Strip trailing zeros, folding each into the exponent.
252
+ let end = digits.length;
253
+ while (end > 0 && digits.charCodeAt(end - 1) === 48) {
254
+ end--;
255
+ exponent++;
256
+ }
257
+ digits = digits.slice(0, end);
258
+
259
+ if (digits.length === 0) {
260
+ // The value is exactly zero; sign and exponent carry no information.
261
+ return { negative: false, significand: '', exponent: 0 };
262
+ }
263
+ return { negative, significand: digits, exponent };
264
+ }
265
+
266
+ /**
267
+ * TRUE when `literal` survives a round-trip through an IEEE-754 double.
268
+ * `9007199254740993` and `0.1000000000000000055511151231257827` do not.
269
+ */
270
+ export function numberIsExact(literal: string): boolean {
271
+ const value = Number(literal);
272
+ if (!Number.isFinite(value)) {
273
+ return false;
274
+ }
275
+ const source = canonicalNumber(literal);
276
+ const roundTrip = canonicalNumber(String(value));
277
+ return (
278
+ source.negative === roundTrip.negative &&
279
+ source.significand === roundTrip.significand &&
280
+ source.exponent === roundTrip.exponent
281
+ );
282
+ }
283
+
284
+ const NUMBER_PATTERN = /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][-+]?[0-9]+)?/;
285
+
286
+ function parseNumberToken(
287
+ cur: Cursor,
288
+ warnings: JsonDiagnostic[],
289
+ path: JsonPath,
290
+ ): JsonNode {
291
+ const start = cur.pos;
292
+ const match = NUMBER_PATTERN.exec(cur.text.slice(start));
293
+ if (!match || match[0].length === 0) {
294
+ throw new ParseAbort(
295
+ diagnostic(
296
+ cur.text,
297
+ start,
298
+ 'error',
299
+ 'bad-number',
300
+ 'This is not a valid JSON number. JSON has no leading `+`, no leading zeros, no `.5`, and no `Infinity` or `NaN`.',
301
+ path,
302
+ ),
303
+ false,
304
+ );
305
+ }
306
+ const literal = match[0];
307
+ cur.pos = start + literal.length;
308
+
309
+ // A number immediately followed by more number-ish characters is a typo,
310
+ // not two tokens: `01`, `1.2.3`, `1e`, `0x10`.
311
+ const nextCode =
312
+ cur.pos < cur.text.length ? cur.text.charCodeAt(cur.pos) : -1;
313
+ const nextChar = nextCode >= 0 ? String.fromCharCode(nextCode) : '';
314
+ if (nextChar !== '' && /[0-9a-zA-Z._+-]/.test(nextChar)) {
315
+ throw new ParseAbort(
316
+ diagnostic(
317
+ cur.text,
318
+ cur.pos,
319
+ 'error',
320
+ 'bad-number',
321
+ 'This is not a valid JSON number. JSON has no leading `+`, no leading zeros, no `.5`, and no `Infinity` or `NaN`.',
322
+ path,
323
+ ),
324
+ cur.pos >= cur.text.length,
325
+ );
326
+ }
327
+
328
+ const value = Number(literal);
329
+ if (!numberIsExact(literal)) {
330
+ warnings.push(
331
+ diagnostic(
332
+ cur.text,
333
+ start,
334
+ 'warning',
335
+ 'number-precision',
336
+ `The number ${literal} is larger or more precise than JavaScript numbers can hold. Its exact text is preserved, but arithmetic on it would lose precision.`,
337
+ path,
338
+ ),
339
+ );
340
+ }
341
+ return { kind: 'number', value, literal };
342
+ }
343
+
344
+ function parseStringToken(
345
+ cur: Cursor,
346
+ warnings: JsonDiagnostic[],
347
+ path: JsonPath,
348
+ ): string {
349
+ cur.pos++; // consume the opening quote
350
+ let out = '';
351
+
352
+ for (;;) {
353
+ if (cur.pos >= cur.text.length) {
354
+ throw new ParseAbort(
355
+ diagnostic(
356
+ cur.text,
357
+ cur.text.length,
358
+ 'error',
359
+ 'unexpected-end',
360
+ 'The document ends inside a string — the closing quote is missing.',
361
+ path,
362
+ ),
363
+ true,
364
+ );
365
+ }
366
+
367
+ const code = cur.text.charCodeAt(cur.pos);
368
+
369
+ if (code === 34) {
370
+ cur.pos++;
371
+ return out;
372
+ }
373
+
374
+ if (code === 92) {
375
+ cur.pos++;
376
+ if (cur.pos >= cur.text.length) {
377
+ abortAtEnd(cur, 'an escape sequence');
378
+ }
379
+ const esc = cur.text[cur.pos];
380
+ cur.pos++;
381
+ if (esc === QUOTE) {
382
+ out += QUOTE;
383
+ } else if (esc === BACKSLASH) {
384
+ out += BACKSLASH;
385
+ } else if (esc === '/') {
386
+ out += '/';
387
+ } else if (esc === 'b') {
388
+ out += '\b';
389
+ } else if (esc === 'f') {
390
+ out += '\f';
391
+ } else if (esc === 'n') {
392
+ out += '\n';
393
+ } else if (esc === 'r') {
394
+ out += '\r';
395
+ } else if (esc === 't') {
396
+ out += '\t';
397
+ } else if (esc === 'u') {
398
+ const hex = cur.text.slice(cur.pos, cur.pos + 4);
399
+ if (hex.length < 4) {
400
+ abortAtEnd(cur, 'a `\\u` escape');
401
+ }
402
+ if (!/^[0-9a-fA-F]{4}$/.test(hex)) {
403
+ throw new ParseAbort(
404
+ diagnostic(
405
+ cur.text,
406
+ cur.pos,
407
+ 'error',
408
+ 'bad-escape',
409
+ 'A `\\u` escape needs exactly four hexadecimal digits.',
410
+ path,
411
+ ),
412
+ false,
413
+ );
414
+ }
415
+ const unit = parseInt(hex, 16);
416
+ cur.pos += 4;
417
+ out += String.fromCharCode(unit);
418
+ if (unit >= 0xd800 && unit <= 0xdfff) {
419
+ // Only warn once the pair is resolvable; a high surrogate followed
420
+ // by its low partner is perfectly legal.
421
+ const previous = out.charCodeAt(out.length - 2);
422
+ const isCompletedPair =
423
+ unit >= 0xdc00 && previous >= 0xd800 && previous <= 0xdbff;
424
+ if (!isCompletedPair && unit >= 0xdc00) {
425
+ warnings.push(
426
+ diagnostic(
427
+ cur.text,
428
+ cur.pos - 6,
429
+ 'warning',
430
+ 'lone-surrogate',
431
+ 'This string contains an unpaired surrogate escape. It is preserved exactly, but it is not valid Unicode text.',
432
+ path,
433
+ ),
434
+ );
435
+ }
436
+ }
437
+ } else {
438
+ throw new ParseAbort(
439
+ diagnostic(
440
+ cur.text,
441
+ cur.pos - 1,
442
+ 'error',
443
+ 'bad-escape',
444
+ `\\${esc} is not a JSON escape sequence. JSON allows \\" \\\\ \\/ \\b \\f \\n \\r \\t and \\uXXXX.`,
445
+ path,
446
+ ),
447
+ false,
448
+ );
449
+ }
450
+ continue;
451
+ }
452
+
453
+ if (code < 0x20) {
454
+ throw new ParseAbort(
455
+ diagnostic(
456
+ cur.text,
457
+ cur.pos,
458
+ 'error',
459
+ 'control-character',
460
+ 'A raw control character is not allowed inside a JSON string. Write it as an escape such as `\\n`.',
461
+ path,
462
+ ),
463
+ false,
464
+ );
465
+ }
466
+
467
+ out += cur.text[cur.pos];
468
+ cur.pos++;
469
+ }
470
+ }
471
+
472
+ function parseValue(
473
+ cur: Cursor,
474
+ warnings: JsonDiagnostic[],
475
+ path: JsonPath,
476
+ ): JsonNode {
477
+ skipWhitespace(cur);
478
+ if (cur.pos >= cur.text.length) {
479
+ abortAtEnd(cur, 'a value');
480
+ }
481
+
482
+ const char = cur.text[cur.pos];
483
+
484
+ if (char === QUOTE) {
485
+ return { kind: 'string', value: parseStringToken(cur, warnings, path) };
486
+ }
487
+ if (char === '{') {
488
+ return parseObject(cur, warnings, path);
489
+ }
490
+ if (char === '[') {
491
+ return parseArray(cur, warnings, path);
492
+ }
493
+ if (cur.text.startsWith('true', cur.pos)) {
494
+ cur.pos += 4;
495
+ return { kind: 'boolean', value: true };
496
+ }
497
+ if (cur.text.startsWith('false', cur.pos)) {
498
+ cur.pos += 5;
499
+ return { kind: 'boolean', value: false };
500
+ }
501
+ if (cur.text.startsWith('null', cur.pos)) {
502
+ cur.pos += 4;
503
+ return { kind: 'null' };
504
+ }
505
+ if (char === '-' || (char >= '0' && char <= '9')) {
506
+ return parseNumberToken(cur, warnings, path);
507
+ }
508
+
509
+ // A bare prefix of a keyword at end-of-input is a half-typed document.
510
+ const tail = cur.text.slice(cur.pos);
511
+ const isKeywordPrefix =
512
+ 'true'.startsWith(tail) ||
513
+ 'false'.startsWith(tail) ||
514
+ 'null'.startsWith(tail);
515
+ if (isKeywordPrefix && tail.length > 0) {
516
+ abortAtEnd(cur, 'a value');
517
+ }
518
+
519
+ throw new ParseAbort(
520
+ diagnostic(
521
+ cur.text,
522
+ cur.pos,
523
+ 'error',
524
+ 'unexpected-token',
525
+ `Expected a value here, found \`${char}\`. A JSON value is an object, array, string, number, \`true\`, \`false\`, or \`null\`.`,
526
+ path,
527
+ ),
528
+ false,
529
+ );
530
+ }
531
+
532
+ function parseArray(
533
+ cur: Cursor,
534
+ warnings: JsonDiagnostic[],
535
+ path: JsonPath,
536
+ ): JsonNode {
537
+ cur.pos++; // consume `[`
538
+ const items: JsonNode[] = [];
539
+ skipWhitespace(cur);
540
+
541
+ if (cur.pos >= cur.text.length) {
542
+ abortAtEnd(cur, 'an array');
543
+ }
544
+ if (cur.text[cur.pos] === ']') {
545
+ cur.pos++;
546
+ return { kind: 'array', items };
547
+ }
548
+
549
+ for (;;) {
550
+ items.push(parseValue(cur, warnings, [...path, items.length]));
551
+ skipWhitespace(cur);
552
+ if (cur.pos >= cur.text.length) {
553
+ abortAtEnd(cur, 'an array');
554
+ }
555
+ const char = cur.text[cur.pos];
556
+ if (char === ',') {
557
+ cur.pos++;
558
+ skipWhitespace(cur);
559
+ if (cur.pos >= cur.text.length) {
560
+ abortAtEnd(cur, 'an array');
561
+ }
562
+ if (cur.text[cur.pos] === ']') {
563
+ throw new ParseAbort(
564
+ diagnostic(
565
+ cur.text,
566
+ cur.pos,
567
+ 'error',
568
+ 'unexpected-token',
569
+ 'JSON does not allow a trailing comma before `]`.',
570
+ path,
571
+ ),
572
+ false,
573
+ );
574
+ }
575
+ continue;
576
+ }
577
+ if (char === ']') {
578
+ cur.pos++;
579
+ return { kind: 'array', items };
580
+ }
581
+ throw new ParseAbort(
582
+ diagnostic(
583
+ cur.text,
584
+ cur.pos,
585
+ 'error',
586
+ 'unexpected-token',
587
+ `Expected \`,\` or \`]\` here, found \`${char}\`.`,
588
+ path,
589
+ ),
590
+ false,
591
+ );
592
+ }
593
+ }
594
+
595
+ function parseObject(
596
+ cur: Cursor,
597
+ warnings: JsonDiagnostic[],
598
+ path: JsonPath,
599
+ ): JsonNode {
600
+ cur.pos++; // consume `{`
601
+ const entries: JsonEntry[] = [];
602
+ const seen = new Set<string>();
603
+ skipWhitespace(cur);
604
+
605
+ if (cur.pos >= cur.text.length) {
606
+ abortAtEnd(cur, 'an object');
607
+ }
608
+ if (cur.text[cur.pos] === '}') {
609
+ cur.pos++;
610
+ return { kind: 'object', entries };
611
+ }
612
+
613
+ for (;;) {
614
+ skipWhitespace(cur);
615
+ if (cur.pos >= cur.text.length) {
616
+ abortAtEnd(cur, 'an object');
617
+ }
618
+ if (cur.text[cur.pos] !== QUOTE) {
619
+ throw new ParseAbort(
620
+ diagnostic(
621
+ cur.text,
622
+ cur.pos,
623
+ 'error',
624
+ 'unexpected-token',
625
+ `Expected a quoted property name here, found \`${cur.text[cur.pos]}\`.`,
626
+ path,
627
+ ),
628
+ false,
629
+ );
630
+ }
631
+ const keyOffset = cur.pos;
632
+ const key = parseStringToken(cur, warnings, path);
633
+
634
+ if (seen.has(key)) {
635
+ // JSON.parse keeps the last and drops the rest without a word. We keep
636
+ // BOTH entries and flag it, because dropping a key is data loss.
637
+ warnings.push(
638
+ diagnostic(
639
+ cur.text,
640
+ keyOffset,
641
+ 'warning',
642
+ 'duplicate-key',
643
+ `The property name "${key}" appears more than once in this object. Both entries are preserved here, but most JSON readers keep only the last.`,
644
+ [...path, key],
645
+ ),
646
+ );
647
+ }
648
+ seen.add(key);
649
+
650
+ skipWhitespace(cur);
651
+ if (cur.pos >= cur.text.length) {
652
+ abortAtEnd(cur, 'an object');
653
+ }
654
+ if (cur.text[cur.pos] !== ':') {
655
+ throw new ParseAbort(
656
+ diagnostic(
657
+ cur.text,
658
+ cur.pos,
659
+ 'error',
660
+ 'unexpected-token',
661
+ `Expected \`:\` after the property name, found \`${cur.text[cur.pos]}\`.`,
662
+ [...path, key],
663
+ ),
664
+ false,
665
+ );
666
+ }
667
+ cur.pos++;
668
+
669
+ const node = parseValue(cur, warnings, [...path, key]);
670
+ entries.push({ key, node });
671
+
672
+ skipWhitespace(cur);
673
+ if (cur.pos >= cur.text.length) {
674
+ abortAtEnd(cur, 'an object');
675
+ }
676
+ const char = cur.text[cur.pos];
677
+ if (char === ',') {
678
+ cur.pos++;
679
+ skipWhitespace(cur);
680
+ if (cur.pos >= cur.text.length) {
681
+ abortAtEnd(cur, 'an object');
682
+ }
683
+ if (cur.text[cur.pos] === '}') {
684
+ throw new ParseAbort(
685
+ diagnostic(
686
+ cur.text,
687
+ cur.pos,
688
+ 'error',
689
+ 'unexpected-token',
690
+ 'JSON does not allow a trailing comma before `}`.',
691
+ path,
692
+ ),
693
+ false,
694
+ );
695
+ }
696
+ continue;
697
+ }
698
+ if (char === '}') {
699
+ cur.pos++;
700
+ return { kind: 'object', entries };
701
+ }
702
+ throw new ParseAbort(
703
+ diagnostic(
704
+ cur.text,
705
+ cur.pos,
706
+ 'error',
707
+ 'unexpected-token',
708
+ `Expected \`,\` or \`}\` here, found \`${char}\`.`,
709
+ path,
710
+ ),
711
+ false,
712
+ );
713
+ }
714
+ }
715
+
716
+ /**
717
+ * Parse JSON text into a `JsonNode`, preserving number literals and duplicate
718
+ * keys, and reporting precise diagnostics.
719
+ *
720
+ * Never throws and never calls `eval`. An empty or whitespace-only document
721
+ * fails with `incomplete: true`, because "nothing typed yet" is a pending
722
+ * state rather than a mistake.
723
+ */
724
+ export function parseJson(text: string): ParseResult {
725
+ const warnings: JsonDiagnostic[] = [];
726
+ const cur: Cursor = { text, pos: 0 };
727
+
728
+ skipWhitespace(cur);
729
+ if (cur.pos >= text.length) {
730
+ return {
731
+ ok: false,
732
+ incomplete: true,
733
+ diagnostics: [
734
+ diagnostic(
735
+ text,
736
+ 0,
737
+ 'error',
738
+ 'empty-document',
739
+ 'Nothing has been entered yet.',
740
+ ),
741
+ ],
742
+ };
743
+ }
744
+
745
+ try {
746
+ const root = parseValue(cur, warnings, []);
747
+ skipWhitespace(cur);
748
+ if (cur.pos < text.length) {
749
+ return {
750
+ ok: false,
751
+ incomplete: false,
752
+ diagnostics: [
753
+ ...warnings,
754
+ diagnostic(
755
+ text,
756
+ cur.pos,
757
+ 'error',
758
+ 'trailing-content',
759
+ 'There is extra content after the end of the JSON document.',
760
+ ),
761
+ ],
762
+ };
763
+ }
764
+ return { ok: true, root, diagnostics: warnings };
765
+ } catch (error) {
766
+ if (error instanceof ParseAbort) {
767
+ return {
768
+ ok: false,
769
+ incomplete: error.incomplete,
770
+ diagnostics: [...warnings, error.diag],
771
+ };
772
+ }
773
+ throw error;
774
+ }
775
+ }
776
+
777
+ /* ------------------------------------------------------------------ *
778
+ * Serialisation
779
+ * ------------------------------------------------------------------ */
780
+
781
+ const ESCAPE_MAP: Record<string, string> = {
782
+ [QUOTE]: BACKSLASH + QUOTE,
783
+ [BACKSLASH]: BACKSLASH + BACKSLASH,
784
+ '\b': BACKSLASH + 'b',
785
+ '\f': BACKSLASH + 'f',
786
+ '\n': BACKSLASH + 'n',
787
+ '\r': BACKSLASH + 'r',
788
+ '\t': BACKSLASH + 't',
789
+ };
790
+
791
+ /** Quote and escape a string as a JSON string literal, including lone surrogates. */
792
+ export function quoteJsonString(value: string): string {
793
+ let out = QUOTE;
794
+ for (let i = 0; i < value.length; i++) {
795
+ const char = value[i]!;
796
+ const code = value.charCodeAt(i);
797
+ const mapped = ESCAPE_MAP[char];
798
+ if (mapped !== undefined) {
799
+ out += mapped;
800
+ } else if (code < 0x20 || (code >= 0xd800 && code <= 0xdfff)) {
801
+ // Control characters must be escaped; surrogates are escaped so that a
802
+ // lone one survives transport intact rather than becoming U+FFFD.
803
+ const isPaired =
804
+ code <= 0xdbff &&
805
+ i + 1 < value.length &&
806
+ value.charCodeAt(i + 1) >= 0xdc00 &&
807
+ value.charCodeAt(i + 1) <= 0xdfff;
808
+ if (isPaired) {
809
+ out += char;
810
+ } else {
811
+ out += BACKSLASH + 'u' + code.toString(16).padStart(4, '0');
812
+ }
813
+ } else {
814
+ out += char;
815
+ }
816
+ }
817
+ return out + QUOTE;
818
+ }
819
+
820
+ /**
821
+ * Render a node back to JSON text. Number literals are emitted verbatim, so
822
+ * `stringifyJson(parseJson(text).root)` is text-identical to `text` up to
823
+ * whitespace for every document this parser accepts.
824
+ *
825
+ * @param indent spaces per level; `0` produces a single compact line.
826
+ */
827
+ export function stringifyJson(node: JsonNode, indent = 2): string {
828
+ const pad = indent > 0 ? ' '.repeat(indent) : '';
829
+ const newline = indent > 0 ? '\n' : '';
830
+ const colon = indent > 0 ? ': ' : ':';
831
+
832
+ const render = (current: JsonNode, depth: number): string => {
833
+ const here = indent > 0 ? pad.repeat(depth) : '';
834
+ const inner = indent > 0 ? pad.repeat(depth + 1) : '';
835
+
836
+ switch (current.kind) {
837
+ case 'null':
838
+ return 'null';
839
+ case 'boolean':
840
+ return current.value ? 'true' : 'false';
841
+ case 'number':
842
+ return current.literal;
843
+ case 'string':
844
+ return quoteJsonString(current.value);
845
+ case 'array': {
846
+ if (current.items.length === 0) {
847
+ return '[]';
848
+ }
849
+ const parts = current.items.map(
850
+ (item) => inner + render(item, depth + 1),
851
+ );
852
+ return '[' + newline + parts.join(',' + newline) + newline + here + ']';
853
+ }
854
+ case 'object': {
855
+ if (current.entries.length === 0) {
856
+ return '{}';
857
+ }
858
+ const parts = current.entries.map(
859
+ (entry) =>
860
+ inner +
861
+ quoteJsonString(entry.key) +
862
+ colon +
863
+ render(entry.node, depth + 1),
864
+ );
865
+ return '{' + newline + parts.join(',' + newline) + newline + here + '}';
866
+ }
867
+ }
868
+ };
869
+
870
+ return render(node, 0);
871
+ }
872
+
873
+ /**
874
+ * Convert a node to a plain JavaScript value.
875
+ *
876
+ * LOSSY BY DESIGN, and it says so: numbers beyond IEEE-754 range collapse to
877
+ * their nearest double, and duplicate keys collapse to the last occurrence —
878
+ * exactly what `JSON.parse` would have done. Use `stringifyJson` when the
879
+ * document must survive intact; use this when a caller wants ordinary data.
880
+ */
881
+ export function toPlainValue(node: JsonNode): unknown {
882
+ switch (node.kind) {
883
+ case 'null':
884
+ return null;
885
+ case 'boolean':
886
+ return node.value;
887
+ case 'number':
888
+ return node.value;
889
+ case 'string':
890
+ return node.value;
891
+ case 'array':
892
+ return node.items.map(toPlainValue);
893
+ case 'object': {
894
+ const out: Record<string, unknown> = {};
895
+ for (const entry of node.entries) {
896
+ out[entry.key] = toPlainValue(entry.node);
897
+ }
898
+ return out;
899
+ }
900
+ }
901
+ }
902
+
903
+ /** Build a node from a plain JavaScript value. Unsupported types become `null`. */
904
+ export function fromPlainValue(value: unknown): JsonNode {
905
+ if (value === null || value === undefined) {
906
+ return { kind: 'null' };
907
+ }
908
+ if (typeof value === 'boolean') {
909
+ return { kind: 'boolean', value };
910
+ }
911
+ if (typeof value === 'number') {
912
+ if (!Number.isFinite(value)) {
913
+ return { kind: 'null' };
914
+ }
915
+ return { kind: 'number', value, literal: String(value) };
916
+ }
917
+ if (typeof value === 'bigint') {
918
+ return { kind: 'number', value: Number(value), literal: value.toString() };
919
+ }
920
+ if (typeof value === 'string') {
921
+ return { kind: 'string', value };
922
+ }
923
+ if (Array.isArray(value)) {
924
+ return { kind: 'array', items: value.map(fromPlainValue) };
925
+ }
926
+ if (typeof value === 'object') {
927
+ const entries: JsonEntry[] = Object.keys(value as object).map((key) => ({
928
+ key,
929
+ node: fromPlainValue((value as Record<string, unknown>)[key]),
930
+ }));
931
+ return { kind: 'object', entries };
932
+ }
933
+ return { kind: 'null' };
934
+ }
935
+
936
+ /* ------------------------------------------------------------------ *
937
+ * Navigation
938
+ * ------------------------------------------------------------------ */
939
+
940
+ /** Read the node at `path`, or `undefined` if the path does not resolve. */
941
+ export function nodeAt(root: JsonNode, path: JsonPath): JsonNode | undefined {
942
+ let current: JsonNode | undefined = root;
943
+ for (const step of path) {
944
+ const here: JsonNode | undefined = current;
945
+ if (here === undefined) {
946
+ return undefined;
947
+ }
948
+ if (here.kind === 'array' && typeof step === 'number') {
949
+ current = here.items[step];
950
+ } else if (here.kind === 'object' && typeof step === 'string') {
951
+ const hit: JsonEntry | undefined = here.entries.find(
952
+ (entry: JsonEntry) => entry.key === step,
953
+ );
954
+ current = hit === undefined ? undefined : hit.node;
955
+ } else {
956
+ return undefined;
957
+ }
958
+ }
959
+ return current;
960
+ }
961
+
962
+ /**
963
+ * Render a path as a JavaScript accessor expression — `$.users[0].name`.
964
+ * This is the "copy path" payload.
965
+ */
966
+ export function formatPath(path: JsonPath): string {
967
+ let out = '$';
968
+ for (const step of path) {
969
+ if (typeof step === 'number') {
970
+ out += '[' + String(step) + ']';
971
+ } else if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(step)) {
972
+ out += '.' + step;
973
+ } else {
974
+ out += '[' + quoteJsonString(step) + ']';
975
+ }
976
+ }
977
+ return out;
978
+ }
979
+
980
+ /**
981
+ * A stable, collision-free string id for a path. Used for DOM ids, `{{#each}}`
982
+ * keys and the expansion set.
983
+ *
984
+ * The escaping is load-bearing: without it `['a', 'b']` and `['a.b']` both
985
+ * render as `.a.b`, so two unrelated nodes would share one expansion state.
986
+ */
987
+ export function pathKey(path: JsonPath): string {
988
+ return path
989
+ .map((step) =>
990
+ typeof step === 'number'
991
+ ? '#' + String(step)
992
+ : '.' + step.replace(/[\\.#]/g, (char) => '\\' + char),
993
+ )
994
+ .join('');
995
+ }
996
+
997
+ /** The number of direct children a node has; `0` for scalars. */
998
+ export function childCount(node: JsonNode): number {
999
+ if (node.kind === 'array') {
1000
+ return node.items.length;
1001
+ }
1002
+ if (node.kind === 'object') {
1003
+ return node.entries.length;
1004
+ }
1005
+ return 0;
1006
+ }
1007
+
1008
+ /** TRUE for arrays and objects — the nodes that can be expanded. */
1009
+ export function isContainer(node: JsonNode): boolean {
1010
+ return node.kind === 'array' || node.kind === 'object';
1011
+ }
1012
+
1013
+ /* ------------------------------------------------------------------ *
1014
+ * Edit algebra — every operation is pure and returns a NEW root
1015
+ * ------------------------------------------------------------------ */
1016
+
1017
+ export interface EditResult {
1018
+ readonly root: JsonNode;
1019
+ /** Whether anything actually changed. A no-op must not push an undo frame. */
1020
+ readonly changed: boolean;
1021
+ /** Present when the operation was rejected or degraded. Never silent. */
1022
+ readonly diagnostics: ReadonlyArray<JsonDiagnostic>;
1023
+ /**
1024
+ * A short, past-tense sentence describing the change, for the polite live
1025
+ * region — "Added property colour" / "Removed item 3 of 5".
1026
+ */
1027
+ readonly announcement: string;
1028
+ }
1029
+
1030
+ function ok(root: JsonNode, announcement: string): EditResult {
1031
+ return { root, changed: true, diagnostics: [], announcement };
1032
+ }
1033
+
1034
+ function noop(root: JsonNode, announcement: string): EditResult {
1035
+ return { root, changed: false, diagnostics: [], announcement };
1036
+ }
1037
+
1038
+ function rejected(
1039
+ root: JsonNode,
1040
+ code: DiagnosticCode,
1041
+ message: string,
1042
+ path: JsonPath,
1043
+ ): EditResult {
1044
+ return {
1045
+ root,
1046
+ changed: false,
1047
+ diagnostics: [
1048
+ { severity: 'error', code, message, offset: 0, line: 1, column: 1, path },
1049
+ ],
1050
+ announcement: message,
1051
+ };
1052
+ }
1053
+
1054
+ /**
1055
+ * Rebuild the spine from `root` down to `path`, replacing the node there with
1056
+ * `make(existing)`. Structural sharing keeps untouched subtrees identical by
1057
+ * reference, which is what makes the undo stack cheap.
1058
+ */
1059
+ function replaceAt(
1060
+ root: JsonNode,
1061
+ path: JsonPath,
1062
+ make: (existing: JsonNode) => JsonNode,
1063
+ ): JsonNode | undefined {
1064
+ if (path.length === 0) {
1065
+ return make(root);
1066
+ }
1067
+ const [step, ...rest] = path;
1068
+
1069
+ if (root.kind === 'array' && typeof step === 'number') {
1070
+ const existing = root.items[step];
1071
+ if (existing === undefined) {
1072
+ return undefined;
1073
+ }
1074
+ const replacement = replaceAt(existing, rest, make);
1075
+ if (replacement === undefined) {
1076
+ return undefined;
1077
+ }
1078
+ const items = root.items.slice();
1079
+ items[step] = replacement;
1080
+ return { kind: 'array', items };
1081
+ }
1082
+
1083
+ if (root.kind === 'object' && typeof step === 'string') {
1084
+ const index = root.entries.findIndex((entry) => entry.key === step);
1085
+ if (index < 0) {
1086
+ return undefined;
1087
+ }
1088
+ const replacement = replaceAt(root.entries[index]!.node, rest, make);
1089
+ if (replacement === undefined) {
1090
+ return undefined;
1091
+ }
1092
+ const entries = root.entries.slice();
1093
+ entries[index] = { key: step, node: replacement };
1094
+ return { kind: 'object', entries };
1095
+ }
1096
+
1097
+ return undefined;
1098
+ }
1099
+
1100
+ /** A neutral, non-destructive default value for each JSON type. */
1101
+ export function emptyNodeOfKind(kind: JsonKind): JsonNode {
1102
+ switch (kind) {
1103
+ case 'null':
1104
+ return { kind: 'null' };
1105
+ case 'boolean':
1106
+ return { kind: 'boolean', value: false };
1107
+ case 'number':
1108
+ return { kind: 'number', value: 0, literal: '0' };
1109
+ case 'string':
1110
+ return { kind: 'string', value: '' };
1111
+ case 'array':
1112
+ return { kind: 'array', items: [] };
1113
+ case 'object':
1114
+ return { kind: 'object', entries: [] };
1115
+ }
1116
+ }
1117
+
1118
+ /**
1119
+ * Interpret raw editor text as a value of `kind`.
1120
+ *
1121
+ * Returns `undefined` when the text cannot be read as that type — the caller
1122
+ * must then hold the edit as PENDING and show an error. It must never fall
1123
+ * back to a different type and must never discard the keystrokes, which is
1124
+ * exactly the failure mode of `Convert.stringToDataTypeValue` upstream.
1125
+ */
1126
+ export function readScalar(kind: JsonKind, text: string): JsonNode | undefined {
1127
+ if (kind === 'string') {
1128
+ // Every possible text is a valid string, INCLUDING the empty one. An
1129
+ // empty string is a value, not a request to delete the property.
1130
+ return { kind: 'string', value: text };
1131
+ }
1132
+ if (kind === 'number') {
1133
+ const trimmed = text.trim();
1134
+ if (trimmed === '' || !NUMBER_PATTERN.test(trimmed)) {
1135
+ return undefined;
1136
+ }
1137
+ const match = NUMBER_PATTERN.exec(trimmed);
1138
+ if (!match || match[0] !== trimmed) {
1139
+ return undefined;
1140
+ }
1141
+ return { kind: 'number', value: Number(trimmed), literal: trimmed };
1142
+ }
1143
+ if (kind === 'boolean') {
1144
+ const trimmed = text.trim().toLowerCase();
1145
+ if (trimmed === 'true') {
1146
+ return { kind: 'boolean', value: true };
1147
+ }
1148
+ if (trimmed === 'false') {
1149
+ return { kind: 'boolean', value: false };
1150
+ }
1151
+ return undefined;
1152
+ }
1153
+ if (kind === 'null') {
1154
+ return text.trim() === '' || text.trim().toLowerCase() === 'null'
1155
+ ? { kind: 'null' }
1156
+ : undefined;
1157
+ }
1158
+ return undefined;
1159
+ }
1160
+
1161
+ /** Replace the value at `path` outright. */
1162
+ export function setNode(
1163
+ root: JsonNode,
1164
+ path: JsonPath,
1165
+ next: JsonNode,
1166
+ ): EditResult {
1167
+ const updated = replaceAt(root, path, () => next);
1168
+ if (updated === undefined) {
1169
+ return rejected(
1170
+ root,
1171
+ 'unexpected-token',
1172
+ 'That value no longer exists.',
1173
+ path,
1174
+ );
1175
+ }
1176
+ return ok(updated, `Set ${formatPath(path)}.`);
1177
+ }
1178
+
1179
+ /**
1180
+ * Change the TYPE of the value at `path`.
1181
+ *
1182
+ * Conversion preserves as much as it honestly can — `42` becomes `"42"`,
1183
+ * `"true"` becomes `true`, an object becomes an array of its values — and
1184
+ * where a conversion cannot preserve the content, the previous value stays on
1185
+ * the undo stack and the announcement says what was replaced. Nothing is
1186
+ * coerced behind the user's back.
1187
+ */
1188
+ export function changeKind(
1189
+ root: JsonNode,
1190
+ path: JsonPath,
1191
+ kind: JsonKind,
1192
+ ): EditResult {
1193
+ const existing = nodeAt(root, path);
1194
+ if (existing === undefined) {
1195
+ return rejected(
1196
+ root,
1197
+ 'unexpected-token',
1198
+ 'That value no longer exists.',
1199
+ path,
1200
+ );
1201
+ }
1202
+ if (existing.kind === kind) {
1203
+ return noop(root, 'No change.');
1204
+ }
1205
+
1206
+ const converted = convertNode(existing, kind);
1207
+ const updated = replaceAt(root, path, () => converted.node);
1208
+ if (updated === undefined) {
1209
+ return rejected(
1210
+ root,
1211
+ 'unexpected-token',
1212
+ 'That value no longer exists.',
1213
+ path,
1214
+ );
1215
+ }
1216
+ return {
1217
+ root: updated,
1218
+ changed: true,
1219
+ diagnostics: converted.lossy
1220
+ ? [
1221
+ {
1222
+ severity: 'warning',
1223
+ code: 'pending-value',
1224
+ message: `Changing ${formatPath(path)} from ${existing.kind} to ${kind} could not preserve the previous content. Undo restores it.`,
1225
+ offset: 0,
1226
+ line: 1,
1227
+ column: 1,
1228
+ path,
1229
+ },
1230
+ ]
1231
+ : [],
1232
+ announcement: `Changed ${formatPath(path)} to ${kind}.`,
1233
+ };
1234
+ }
1235
+
1236
+ function convertNode(
1237
+ node: JsonNode,
1238
+ kind: JsonKind,
1239
+ ): { node: JsonNode; lossy: boolean } {
1240
+ if (kind === 'string') {
1241
+ switch (node.kind) {
1242
+ case 'string':
1243
+ return { node, lossy: false };
1244
+ case 'number':
1245
+ return { node: { kind: 'string', value: node.literal }, lossy: false };
1246
+ case 'boolean':
1247
+ return {
1248
+ node: { kind: 'string', value: String(node.value) },
1249
+ lossy: false,
1250
+ };
1251
+ case 'null':
1252
+ return { node: { kind: 'string', value: '' }, lossy: false };
1253
+ default:
1254
+ // Containers become their JSON text — reversible by hand, so not lost.
1255
+ return {
1256
+ node: { kind: 'string', value: stringifyJson(node, 0) },
1257
+ lossy: false,
1258
+ };
1259
+ }
1260
+ }
1261
+
1262
+ if (kind === 'number') {
1263
+ if (node.kind === 'number') {
1264
+ return { node, lossy: false };
1265
+ }
1266
+ if (node.kind === 'string') {
1267
+ const read = readScalar('number', node.value);
1268
+ if (read) {
1269
+ return { node: read, lossy: false };
1270
+ }
1271
+ }
1272
+ if (node.kind === 'boolean') {
1273
+ return {
1274
+ node: {
1275
+ kind: 'number',
1276
+ value: node.value ? 1 : 0,
1277
+ literal: node.value ? '1' : '0',
1278
+ },
1279
+ lossy: false,
1280
+ };
1281
+ }
1282
+ return { node: emptyNodeOfKind('number'), lossy: true };
1283
+ }
1284
+
1285
+ if (kind === 'boolean') {
1286
+ if (node.kind === 'boolean') {
1287
+ return { node, lossy: false };
1288
+ }
1289
+ if (node.kind === 'string') {
1290
+ const read = readScalar('boolean', node.value);
1291
+ if (read) {
1292
+ return { node: read, lossy: false };
1293
+ }
1294
+ }
1295
+ if (node.kind === 'number') {
1296
+ return {
1297
+ node: { kind: 'boolean', value: node.value !== 0 },
1298
+ lossy: false,
1299
+ };
1300
+ }
1301
+ return { node: emptyNodeOfKind('boolean'), lossy: true };
1302
+ }
1303
+
1304
+ if (kind === 'null') {
1305
+ return { node: { kind: 'null' }, lossy: node.kind !== 'null' };
1306
+ }
1307
+
1308
+ if (kind === 'array') {
1309
+ if (node.kind === 'array') {
1310
+ return { node, lossy: false };
1311
+ }
1312
+ if (node.kind === 'object') {
1313
+ // Keys are dropped, values kept — say so.
1314
+ return {
1315
+ node: { kind: 'array', items: node.entries.map((entry) => entry.node) },
1316
+ lossy: true,
1317
+ };
1318
+ }
1319
+ if (node.kind === 'null') {
1320
+ return { node: { kind: 'array', items: [] }, lossy: false };
1321
+ }
1322
+ return { node: { kind: 'array', items: [node] }, lossy: false };
1323
+ }
1324
+
1325
+ // kind === 'object'
1326
+ if (node.kind === 'object') {
1327
+ return { node, lossy: false };
1328
+ }
1329
+ if (node.kind === 'array') {
1330
+ return {
1331
+ node: {
1332
+ kind: 'object',
1333
+ entries: node.items.map((item, index) => ({
1334
+ key: String(index),
1335
+ node: item,
1336
+ })),
1337
+ },
1338
+ lossy: false,
1339
+ };
1340
+ }
1341
+ if (node.kind === 'null') {
1342
+ return { node: { kind: 'object', entries: [] }, lossy: false };
1343
+ }
1344
+ return {
1345
+ node: { kind: 'object', entries: [{ key: 'value', node }] },
1346
+ lossy: false,
1347
+ };
1348
+ }
1349
+
1350
+ /** Rename an object property, keeping its position in the key order. */
1351
+ export function renameKey(
1352
+ root: JsonNode,
1353
+ parentPath: JsonPath,
1354
+ index: number,
1355
+ nextKey: string,
1356
+ ): EditResult {
1357
+ const parent = nodeAt(root, parentPath);
1358
+ if (parent === undefined || parent.kind !== 'object') {
1359
+ return rejected(
1360
+ root,
1361
+ 'unexpected-token',
1362
+ 'That object no longer exists.',
1363
+ parentPath,
1364
+ );
1365
+ }
1366
+ const entry = parent.entries[index];
1367
+ if (entry === undefined) {
1368
+ return rejected(
1369
+ root,
1370
+ 'unexpected-token',
1371
+ 'That property no longer exists.',
1372
+ parentPath,
1373
+ );
1374
+ }
1375
+ if (entry.key === nextKey) {
1376
+ return noop(root, 'No change.');
1377
+ }
1378
+ // An empty property name is legal JSON, so it is allowed here. What is NOT
1379
+ // allowed is silently overwriting a sibling.
1380
+ const clash = parent.entries.findIndex(
1381
+ (other, i) => i !== index && other.key === nextKey,
1382
+ );
1383
+ if (clash >= 0) {
1384
+ return rejected(
1385
+ root,
1386
+ 'duplicate-key',
1387
+ `This object already has a property named "${nextKey}". Rename or remove that one first — renaming here would overwrite it.`,
1388
+ parentPath,
1389
+ );
1390
+ }
1391
+
1392
+ const entries = parent.entries.slice();
1393
+ entries[index] = { key: nextKey, node: entry.node };
1394
+ const updated = replaceAt(root, parentPath, () => ({
1395
+ kind: 'object',
1396
+ entries,
1397
+ }));
1398
+ if (updated === undefined) {
1399
+ return rejected(
1400
+ root,
1401
+ 'unexpected-token',
1402
+ 'That object no longer exists.',
1403
+ parentPath,
1404
+ );
1405
+ }
1406
+ return ok(updated, `Renamed property ${entry.key} to ${nextKey}.`);
1407
+ }
1408
+
1409
+ /** Append a new property to an object. The key must not already exist. */
1410
+ export function addEntry(
1411
+ root: JsonNode,
1412
+ parentPath: JsonPath,
1413
+ key: string,
1414
+ node: JsonNode = { kind: 'null' },
1415
+ ): EditResult {
1416
+ const parent = nodeAt(root, parentPath);
1417
+ if (parent === undefined || parent.kind !== 'object') {
1418
+ return rejected(
1419
+ root,
1420
+ 'unexpected-token',
1421
+ 'That object no longer exists.',
1422
+ parentPath,
1423
+ );
1424
+ }
1425
+ if (parent.entries.some((entry) => entry.key === key)) {
1426
+ return rejected(
1427
+ root,
1428
+ 'duplicate-key',
1429
+ `This object already has a property named "${key}".`,
1430
+ parentPath,
1431
+ );
1432
+ }
1433
+ const entries = [...parent.entries, { key, node }];
1434
+ const updated = replaceAt(root, parentPath, () => ({
1435
+ kind: 'object',
1436
+ entries,
1437
+ }));
1438
+ if (updated === undefined) {
1439
+ return rejected(
1440
+ root,
1441
+ 'unexpected-token',
1442
+ 'That object no longer exists.',
1443
+ parentPath,
1444
+ );
1445
+ }
1446
+ return ok(updated, `Added property ${key}.`);
1447
+ }
1448
+
1449
+ /** Append a new item to an array. */
1450
+ export function addItem(
1451
+ root: JsonNode,
1452
+ parentPath: JsonPath,
1453
+ node: JsonNode = { kind: 'null' },
1454
+ ): EditResult {
1455
+ const parent = nodeAt(root, parentPath);
1456
+ if (parent === undefined || parent.kind !== 'array') {
1457
+ return rejected(
1458
+ root,
1459
+ 'unexpected-token',
1460
+ 'That array no longer exists.',
1461
+ parentPath,
1462
+ );
1463
+ }
1464
+ const items = [...parent.items, node];
1465
+ const updated = replaceAt(root, parentPath, () => ({ kind: 'array', items }));
1466
+ if (updated === undefined) {
1467
+ return rejected(
1468
+ root,
1469
+ 'unexpected-token',
1470
+ 'That array no longer exists.',
1471
+ parentPath,
1472
+ );
1473
+ }
1474
+ return ok(updated, `Added item ${items.length} of ${items.length}.`);
1475
+ }
1476
+
1477
+ /** Remove a property or item. This is the ONLY way anything gets deleted. */
1478
+ export function removeAt(
1479
+ root: JsonNode,
1480
+ parentPath: JsonPath,
1481
+ index: number,
1482
+ ): EditResult {
1483
+ const parent = nodeAt(root, parentPath);
1484
+ if (parent === undefined) {
1485
+ return rejected(
1486
+ root,
1487
+ 'unexpected-token',
1488
+ 'That container no longer exists.',
1489
+ parentPath,
1490
+ );
1491
+ }
1492
+
1493
+ if (parent.kind === 'array') {
1494
+ if (index < 0 || index >= parent.items.length) {
1495
+ return rejected(
1496
+ root,
1497
+ 'unexpected-token',
1498
+ 'That item no longer exists.',
1499
+ parentPath,
1500
+ );
1501
+ }
1502
+ const items = parent.items.slice();
1503
+ items.splice(index, 1);
1504
+ const updated = replaceAt(root, parentPath, () => ({
1505
+ kind: 'array',
1506
+ items,
1507
+ }));
1508
+ if (updated === undefined) {
1509
+ return rejected(
1510
+ root,
1511
+ 'unexpected-token',
1512
+ 'That array no longer exists.',
1513
+ parentPath,
1514
+ );
1515
+ }
1516
+ return ok(updated, `Removed item ${index + 1}. ${items.length} remaining.`);
1517
+ }
1518
+
1519
+ if (parent.kind === 'object') {
1520
+ const entry = parent.entries[index];
1521
+ if (entry === undefined) {
1522
+ return rejected(
1523
+ root,
1524
+ 'unexpected-token',
1525
+ 'That property no longer exists.',
1526
+ parentPath,
1527
+ );
1528
+ }
1529
+ const entries = parent.entries.slice();
1530
+ entries.splice(index, 1);
1531
+ const updated = replaceAt(root, parentPath, () => ({
1532
+ kind: 'object',
1533
+ entries,
1534
+ }));
1535
+ if (updated === undefined) {
1536
+ return rejected(
1537
+ root,
1538
+ 'unexpected-token',
1539
+ 'That object no longer exists.',
1540
+ parentPath,
1541
+ );
1542
+ }
1543
+ return ok(
1544
+ updated,
1545
+ `Removed property ${entry.key}. ${entries.length} remaining.`,
1546
+ );
1547
+ }
1548
+
1549
+ return rejected(
1550
+ root,
1551
+ 'unexpected-token',
1552
+ 'Only arrays and objects have children.',
1553
+ parentPath,
1554
+ );
1555
+ }
1556
+
1557
+ /** Move an array item (or object property) from one position to another. */
1558
+ export function moveChild(
1559
+ root: JsonNode,
1560
+ parentPath: JsonPath,
1561
+ from: number,
1562
+ to: number,
1563
+ ): EditResult {
1564
+ const parent = nodeAt(root, parentPath);
1565
+ if (parent === undefined) {
1566
+ return rejected(
1567
+ root,
1568
+ 'unexpected-token',
1569
+ 'That container no longer exists.',
1570
+ parentPath,
1571
+ );
1572
+ }
1573
+
1574
+ const length = childCount(parent);
1575
+ if (from < 0 || from >= length) {
1576
+ return rejected(
1577
+ root,
1578
+ 'unexpected-token',
1579
+ 'That item no longer exists.',
1580
+ parentPath,
1581
+ );
1582
+ }
1583
+ const target = Math.max(0, Math.min(length - 1, to));
1584
+ if (target === from) {
1585
+ return noop(root, 'Already at the end of the list.');
1586
+ }
1587
+
1588
+ if (parent.kind === 'array') {
1589
+ const items = parent.items.slice();
1590
+ const [moved] = items.splice(from, 1);
1591
+ items.splice(target, 0, moved!);
1592
+ const updated = replaceAt(root, parentPath, () => ({
1593
+ kind: 'array',
1594
+ items,
1595
+ }));
1596
+ if (updated === undefined) {
1597
+ return rejected(
1598
+ root,
1599
+ 'unexpected-token',
1600
+ 'That array no longer exists.',
1601
+ parentPath,
1602
+ );
1603
+ }
1604
+ return ok(
1605
+ updated,
1606
+ `Moved item from position ${from + 1} to ${target + 1} of ${length}.`,
1607
+ );
1608
+ }
1609
+
1610
+ if (parent.kind === 'object') {
1611
+ const entries = parent.entries.slice();
1612
+ const [moved] = entries.splice(from, 1);
1613
+ entries.splice(target, 0, moved!);
1614
+ const updated = replaceAt(root, parentPath, () => ({
1615
+ kind: 'object',
1616
+ entries,
1617
+ }));
1618
+ if (updated === undefined) {
1619
+ return rejected(
1620
+ root,
1621
+ 'unexpected-token',
1622
+ 'That object no longer exists.',
1623
+ parentPath,
1624
+ );
1625
+ }
1626
+ return ok(
1627
+ updated,
1628
+ `Moved property ${moved!.key} from position ${from + 1} to ${target + 1} of ${length}.`,
1629
+ );
1630
+ }
1631
+
1632
+ return rejected(
1633
+ root,
1634
+ 'unexpected-token',
1635
+ 'Only arrays and objects have children.',
1636
+ parentPath,
1637
+ );
1638
+ }
1639
+
1640
+ /* ------------------------------------------------------------------ *
1641
+ * Search
1642
+ * ------------------------------------------------------------------ */
1643
+
1644
+ export interface JsonMatch {
1645
+ readonly path: JsonPath;
1646
+ /** Whether the hit was on the property name, the value, or both. */
1647
+ readonly where: 'key' | 'value' | 'both';
1648
+ }
1649
+
1650
+ /** A short, single-line rendering of a node, for collapsed previews and search. */
1651
+ export function previewOf(node: JsonNode, limit = 48): string {
1652
+ let text: string;
1653
+ switch (node.kind) {
1654
+ case 'null':
1655
+ text = 'null';
1656
+ break;
1657
+ case 'boolean':
1658
+ text = node.value ? 'true' : 'false';
1659
+ break;
1660
+ case 'number':
1661
+ text = node.literal;
1662
+ break;
1663
+ case 'string':
1664
+ text = node.value;
1665
+ break;
1666
+ case 'array':
1667
+ text =
1668
+ node.items.length === 1
1669
+ ? '1 item'
1670
+ : String(node.items.length) + ' items';
1671
+ break;
1672
+ case 'object':
1673
+ text =
1674
+ node.entries.length === 1
1675
+ ? '1 property'
1676
+ : String(node.entries.length) + ' properties';
1677
+ break;
1678
+ }
1679
+ return text.length > limit ? text.slice(0, limit - 1) + '…' : text;
1680
+ }
1681
+
1682
+ /**
1683
+ * Find every node whose property name or scalar value contains `query`
1684
+ * (case-insensitive). Returns paths in document order.
1685
+ */
1686
+ export function searchJson(
1687
+ root: JsonNode,
1688
+ query: string,
1689
+ ): ReadonlyArray<JsonMatch> {
1690
+ const needle = query.trim().toLowerCase();
1691
+ if (needle === '') {
1692
+ return [];
1693
+ }
1694
+ const results: JsonMatch[] = [];
1695
+
1696
+ const scalarText = (node: JsonNode): string | undefined => {
1697
+ switch (node.kind) {
1698
+ case 'null':
1699
+ return 'null';
1700
+ case 'boolean':
1701
+ return node.value ? 'true' : 'false';
1702
+ case 'number':
1703
+ return node.literal;
1704
+ case 'string':
1705
+ return node.value;
1706
+ default:
1707
+ return undefined;
1708
+ }
1709
+ };
1710
+
1711
+ const walk = (
1712
+ node: JsonNode,
1713
+ path: JsonPath,
1714
+ key: string | undefined,
1715
+ ): void => {
1716
+ const keyHit = key !== undefined && key.toLowerCase().includes(needle);
1717
+ const text = scalarText(node);
1718
+ const valueHit = text !== undefined && text.toLowerCase().includes(needle);
1719
+ if (keyHit && valueHit) {
1720
+ results.push({ path, where: 'both' });
1721
+ } else if (keyHit) {
1722
+ results.push({ path, where: 'key' });
1723
+ } else if (valueHit) {
1724
+ results.push({ path, where: 'value' });
1725
+ }
1726
+
1727
+ if (node.kind === 'array') {
1728
+ node.items.forEach((item, index) =>
1729
+ walk(item, [...path, index], undefined),
1730
+ );
1731
+ } else if (node.kind === 'object') {
1732
+ node.entries.forEach((entry) =>
1733
+ walk(entry.node, [...path, entry.key], entry.key),
1734
+ );
1735
+ }
1736
+ };
1737
+
1738
+ walk(root, [], undefined);
1739
+ return results;
1740
+ }
1741
+
1742
+ /** Every ancestor path of `path`, shortest first — what a search hit must expand. */
1743
+ export function ancestorPaths(path: JsonPath): ReadonlyArray<JsonPath> {
1744
+ const out: JsonPath[] = [];
1745
+ for (let i = 0; i < path.length; i++) {
1746
+ out.push(path.slice(0, i));
1747
+ }
1748
+ return out;
1749
+ }
1750
+
1751
+ /* ------------------------------------------------------------------ *
1752
+ * Undo history
1753
+ * ------------------------------------------------------------------ */
1754
+
1755
+ /**
1756
+ * An immutable undo stack. Because every edit returns a new root with
1757
+ * structural sharing, a "snapshot" is just a root reference — so history
1758
+ * costs one pointer per step, not a deep clone.
1759
+ *
1760
+ * `limit` caps the stack so a long editing session cannot grow without bound.
1761
+ */
1762
+ export class JsonHistory {
1763
+ readonly #limit: number;
1764
+ #past: JsonNode[] = [];
1765
+ #future: JsonNode[] = [];
1766
+
1767
+ constructor(limit = 100) {
1768
+ this.#limit = Math.max(1, limit);
1769
+ }
1770
+
1771
+ get canUndo(): boolean {
1772
+ return this.#past.length > 0;
1773
+ }
1774
+
1775
+ get canRedo(): boolean {
1776
+ return this.#future.length > 0;
1777
+ }
1778
+
1779
+ get depth(): number {
1780
+ return this.#past.length;
1781
+ }
1782
+
1783
+ /** Record the root as it was BEFORE an edit. Clears the redo branch. */
1784
+ push(previous: JsonNode): void {
1785
+ this.#past.push(previous);
1786
+ if (this.#past.length > this.#limit) {
1787
+ this.#past.shift();
1788
+ }
1789
+ this.#future = [];
1790
+ }
1791
+
1792
+ /** Step back. `current` is the root being left, which becomes redoable. */
1793
+ undo(current: JsonNode): JsonNode | undefined {
1794
+ const previous = this.#past.pop();
1795
+ if (previous === undefined) {
1796
+ return undefined;
1797
+ }
1798
+ this.#future.push(current);
1799
+ return previous;
1800
+ }
1801
+
1802
+ /** Step forward. `current` is the root being left, which becomes undoable. */
1803
+ redo(current: JsonNode): JsonNode | undefined {
1804
+ const next = this.#future.pop();
1805
+ if (next === undefined) {
1806
+ return undefined;
1807
+ }
1808
+ this.#past.push(current);
1809
+ return next;
1810
+ }
1811
+
1812
+ clear(): void {
1813
+ this.#past = [];
1814
+ this.#future = [];
1815
+ }
1816
+ }
1817
+
1818
+ /* ------------------------------------------------------------------ *
1819
+ * Flattening — the tree view's render list
1820
+ * ------------------------------------------------------------------ */
1821
+
1822
+ export interface FlatRow {
1823
+ readonly path: JsonPath;
1824
+ /** Stable id for DOM ids and `{{#each key=}}`. */
1825
+ readonly id: string;
1826
+ /** Property name, array index label, or `undefined` for the root. */
1827
+ readonly label: string | undefined;
1828
+ /** Index within the parent container; `-1` for the root. */
1829
+ readonly index: number;
1830
+ readonly parentPath: JsonPath;
1831
+ /** `pathKey` of the parent row, or `undefined` for the root. */
1832
+ readonly parentId: string | undefined;
1833
+ readonly node: JsonNode;
1834
+ /** ARIA level, 1-based. */
1835
+ readonly level: number;
1836
+ /** ARIA position among siblings, 1-based. */
1837
+ readonly posinset: number;
1838
+ /** ARIA sibling count, including any overflow notice row. */
1839
+ readonly setsize: number;
1840
+ readonly expandable: boolean;
1841
+ readonly expanded: boolean;
1842
+ /** TRUE when this row is a truncation notice rather than a value. */
1843
+ readonly overflow?: { shown: number; total: number };
1844
+ }
1845
+
1846
+ export interface FlattenOptions {
1847
+ /** Paths (as `pathKey` strings) that are currently expanded. */
1848
+ readonly expanded: ReadonlySet<string>;
1849
+ /**
1850
+ * Maximum children rendered per container before truncating. Truncation,
1851
+ * not virtualization — virtualization needs measurement and this realm
1852
+ * forbids the timers that would drive it, and an honest "showing N of M"
1853
+ * beats a scroll position that lies.
1854
+ */
1855
+ readonly pageSize: number;
1856
+ /** Per-container overrides raising the window, keyed by `pathKey`. */
1857
+ readonly revealed?: ReadonlyMap<string, number>;
1858
+ }
1859
+
1860
+ /**
1861
+ * Walk the document into the flat, ordered row list the treeview renders.
1862
+ * Only expanded containers contribute children, so the cost is proportional
1863
+ * to what is on screen.
1864
+ */
1865
+ export function flattenJson(
1866
+ root: JsonNode,
1867
+ options: FlattenOptions,
1868
+ ): ReadonlyArray<FlatRow> {
1869
+ const rows: FlatRow[] = [];
1870
+
1871
+ const visit = (
1872
+ node: JsonNode,
1873
+ path: JsonPath,
1874
+ parentPath: JsonPath,
1875
+ parentId: string | undefined,
1876
+ label: string | undefined,
1877
+ index: number,
1878
+ level: number,
1879
+ posinset: number,
1880
+ setsize: number,
1881
+ ): void => {
1882
+ const key = pathKey(path);
1883
+ const id = key === '' ? '$' : key;
1884
+ const expandable = isContainer(node) && childCount(node) > 0;
1885
+ const expanded = expandable && options.expanded.has(key);
1886
+
1887
+ rows.push({
1888
+ path,
1889
+ id,
1890
+ label,
1891
+ index,
1892
+ parentPath,
1893
+ parentId,
1894
+ node,
1895
+ level,
1896
+ posinset,
1897
+ setsize,
1898
+ expandable,
1899
+ expanded,
1900
+ });
1901
+
1902
+ if (!expanded) {
1903
+ return;
1904
+ }
1905
+
1906
+ const total = childCount(node);
1907
+ const window = Math.max(options.pageSize, options.revealed?.get(key) ?? 0);
1908
+ const shown = Math.min(total, window);
1909
+ // The overflow notice is a focusable row, so it counts toward `setsize`.
1910
+ const siblings = shown < total ? shown + 1 : shown;
1911
+
1912
+ if (node.kind === 'array') {
1913
+ for (let i = 0; i < shown; i++) {
1914
+ visit(
1915
+ node.items[i]!,
1916
+ [...path, i],
1917
+ path,
1918
+ id,
1919
+ String(i),
1920
+ i,
1921
+ level + 1,
1922
+ i + 1,
1923
+ siblings,
1924
+ );
1925
+ }
1926
+ } else if (node.kind === 'object') {
1927
+ for (let i = 0; i < shown; i++) {
1928
+ const entry = node.entries[i]!;
1929
+ visit(
1930
+ entry.node,
1931
+ [...path, entry.key],
1932
+ path,
1933
+ id,
1934
+ entry.key,
1935
+ i,
1936
+ level + 1,
1937
+ i + 1,
1938
+ siblings,
1939
+ );
1940
+ }
1941
+ }
1942
+
1943
+ if (shown < total) {
1944
+ rows.push({
1945
+ path: [...path, '@@overflow'],
1946
+ id: id + '@@overflow',
1947
+ label: undefined,
1948
+ index: shown,
1949
+ parentPath: path,
1950
+ parentId: id,
1951
+ node: { kind: 'null' },
1952
+ level: level + 1,
1953
+ posinset: siblings,
1954
+ setsize: siblings,
1955
+ expandable: false,
1956
+ expanded: false,
1957
+ overflow: { shown, total },
1958
+ });
1959
+ }
1960
+ };
1961
+
1962
+ visit(root, [], [], undefined, undefined, -1, 1, 1, 1);
1963
+ return rows;
1964
+ }
1965
+
1966
+ /** Every container path in the document — what "expand all" needs. */
1967
+ export function allContainerPaths(root: JsonNode): ReadonlyArray<string> {
1968
+ const out: string[] = [];
1969
+ const walk = (node: JsonNode, path: JsonPath): void => {
1970
+ if (isContainer(node) && childCount(node) > 0) {
1971
+ out.push(pathKey(path));
1972
+ }
1973
+ if (node.kind === 'array') {
1974
+ node.items.forEach((item, index) => walk(item, [...path, index]));
1975
+ } else if (node.kind === 'object') {
1976
+ node.entries.forEach((entry) => walk(entry.node, [...path, entry.key]));
1977
+ }
1978
+ };
1979
+ walk(root, []);
1980
+ return out;
1981
+ }