@atmos.build/ui 0.1.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 (431) hide show
  1. package/README.md +45 -0
  2. package/dist/components/alert-dialog.d.ts +14 -0
  3. package/dist/components/alert-dialog.js +40 -0
  4. package/dist/components/at-search.d.ts +35 -0
  5. package/dist/components/at-search.js +57 -0
  6. package/dist/components/attachment-thumbnail-stack.d.ts +13 -0
  7. package/dist/components/attachment-thumbnail-stack.js +23 -0
  8. package/dist/components/audio-preview.d.ts +33 -0
  9. package/dist/components/audio-preview.js +176 -0
  10. package/dist/components/avatar-uploader.d.ts +29 -0
  11. package/dist/components/avatar-uploader.js +67 -0
  12. package/dist/components/avatar.d.ts +12 -0
  13. package/dist/components/avatar.js +38 -0
  14. package/dist/components/badge.d.ts +9 -0
  15. package/dist/components/badge.js +25 -0
  16. package/dist/components/button-group.d.ts +12 -0
  17. package/dist/components/button-group.js +29 -0
  18. package/dist/components/button.d.ts +10 -0
  19. package/dist/components/button.js +42 -0
  20. package/dist/components/calendar.d.ts +26 -0
  21. package/dist/components/calendar.js +154 -0
  22. package/dist/components/channel-list.d.ts +33 -0
  23. package/dist/components/channel-list.js +40 -0
  24. package/dist/components/charts/area-chart.d.ts +2 -0
  25. package/dist/components/charts/area-chart.js +5 -0
  26. package/dist/components/charts/bar-chart.d.ts +2 -0
  27. package/dist/components/charts/bar-chart.js +58 -0
  28. package/dist/components/charts/colors.d.ts +2 -0
  29. package/dist/components/charts/colors.js +42 -0
  30. package/dist/components/charts/hover.d.ts +20 -0
  31. package/dist/components/charts/hover.js +31 -0
  32. package/dist/components/charts/index.d.ts +10 -0
  33. package/dist/components/charts/index.js +9 -0
  34. package/dist/components/charts/layout.d.ts +35 -0
  35. package/dist/components/charts/layout.js +101 -0
  36. package/dist/components/charts/legend.d.ts +6 -0
  37. package/dist/components/charts/legend.js +7 -0
  38. package/dist/components/charts/line-area-chart.d.ts +4 -0
  39. package/dist/components/charts/line-area-chart.js +86 -0
  40. package/dist/components/charts/line-chart.d.ts +2 -0
  41. package/dist/components/charts/line-chart.js +5 -0
  42. package/dist/components/charts/pie-chart.d.ts +2 -0
  43. package/dist/components/charts/pie-chart.js +22 -0
  44. package/dist/components/charts/radar-chart.d.ts +2 -0
  45. package/dist/components/charts/radar-chart.js +29 -0
  46. package/dist/components/charts/radial-chart.d.ts +2 -0
  47. package/dist/components/charts/radial-chart.js +19 -0
  48. package/dist/components/charts/scatter-chart.d.ts +2 -0
  49. package/dist/components/charts/scatter-chart.js +16 -0
  50. package/dist/components/charts/story-data.d.ts +24 -0
  51. package/dist/components/charts/story-data.js +48 -0
  52. package/dist/components/charts/types.d.ts +43 -0
  53. package/dist/components/charts/types.js +1 -0
  54. package/dist/components/checkbox.d.ts +4 -0
  55. package/dist/components/checkbox.js +10 -0
  56. package/dist/components/chip.d.ts +25 -0
  57. package/dist/components/chip.js +36 -0
  58. package/dist/components/code-editor-theme.d.ts +19 -0
  59. package/dist/components/code-editor-theme.js +100 -0
  60. package/dist/components/collapsible-section-header.d.ts +82 -0
  61. package/dist/components/collapsible-section-header.js +82 -0
  62. package/dist/components/collection-view/collection-view-group-settings.d.ts +73 -0
  63. package/dist/components/collection-view/collection-view-group-settings.js +55 -0
  64. package/dist/components/collection-view/collection-view-settings.d.ts +115 -0
  65. package/dist/components/collection-view/collection-view-settings.js +146 -0
  66. package/dist/components/collection-view/collection-view.d.ts +87 -0
  67. package/dist/components/collection-view/collection-view.js +95 -0
  68. package/dist/components/collection-view/index.d.ts +6 -0
  69. package/dist/components/collection-view/index.js +6 -0
  70. package/dist/components/collection-view/use-collection-detail-navigation.d.ts +11 -0
  71. package/dist/components/collection-view/use-collection-detail-navigation.js +12 -0
  72. package/dist/components/collection-view/use-collection-escape.d.ts +9 -0
  73. package/dist/components/collection-view/use-collection-escape.js +20 -0
  74. package/dist/components/collection-view/use-collection-selection.d.ts +42 -0
  75. package/dist/components/collection-view/use-collection-selection.js +203 -0
  76. package/dist/components/color-picker.d.ts +18 -0
  77. package/dist/components/color-picker.js +77 -0
  78. package/dist/components/color-swatch-list.d.ts +16 -0
  79. package/dist/components/color-swatch-list.js +60 -0
  80. package/dist/components/combobox/combobox.d.ts +4 -0
  81. package/dist/components/combobox/combobox.js +70 -0
  82. package/dist/components/combobox/compound.d.ts +68 -0
  83. package/dist/components/combobox/compound.js +151 -0
  84. package/dist/components/combobox/context.d.ts +34 -0
  85. package/dist/components/combobox/context.js +123 -0
  86. package/dist/components/combobox/create-step.d.ts +12 -0
  87. package/dist/components/combobox/create-step.js +8 -0
  88. package/dist/components/combobox/index.d.ts +10 -0
  89. package/dist/components/combobox/index.js +5 -0
  90. package/dist/components/combobox/inline-create-form.d.ts +24 -0
  91. package/dist/components/combobox/inline-create-form.js +43 -0
  92. package/dist/components/combobox/types.d.ts +57 -0
  93. package/dist/components/combobox/types.js +10 -0
  94. package/dist/components/command.d.ts +35 -0
  95. package/dist/components/command.js +76 -0
  96. package/dist/components/comment-pin.d.ts +13 -0
  97. package/dist/components/comment-pin.js +33 -0
  98. package/dist/components/confidence-meter.d.ts +11 -0
  99. package/dist/components/confidence-meter.js +24 -0
  100. package/dist/components/context-menu.d.ts +31 -0
  101. package/dist/components/context-menu.js +54 -0
  102. package/dist/components/copy-button.d.ts +12 -0
  103. package/dist/components/copy-button.js +32 -0
  104. package/dist/components/date-picker.d.ts +29 -0
  105. package/dist/components/date-picker.js +86 -0
  106. package/dist/components/date-tile.d.ts +11 -0
  107. package/dist/components/date-tile.js +16 -0
  108. package/dist/components/date-time-picker.d.ts +25 -0
  109. package/dist/components/date-time-picker.js +153 -0
  110. package/dist/components/detail-breadcrumb-utils.d.ts +2 -0
  111. package/dist/components/detail-breadcrumb-utils.js +18 -0
  112. package/dist/components/detail-nav-bar.d.ts +28 -0
  113. package/dist/components/detail-nav-bar.js +28 -0
  114. package/dist/components/detail-top-bar.d.ts +49 -0
  115. package/dist/components/detail-top-bar.js +41 -0
  116. package/dist/components/dialog.d.ts +22 -0
  117. package/dist/components/dialog.js +51 -0
  118. package/dist/components/dropdown-menu.d.ts +29 -0
  119. package/dist/components/dropdown-menu.js +52 -0
  120. package/dist/components/editable-doc-title.d.ts +17 -0
  121. package/dist/components/editable-doc-title.js +147 -0
  122. package/dist/components/empty-state.d.ts +12 -0
  123. package/dist/components/empty-state.js +6 -0
  124. package/dist/components/filter-condition-editor.d.ts +18 -0
  125. package/dist/components/filter-condition-editor.js +102 -0
  126. package/dist/components/form-dialog.d.ts +30 -0
  127. package/dist/components/form-dialog.js +52 -0
  128. package/dist/components/formula-editor.d.ts +18 -0
  129. package/dist/components/formula-editor.js +154 -0
  130. package/dist/components/hover-card.d.ts +52 -0
  131. package/dist/components/hover-card.js +51 -0
  132. package/dist/components/icon-button.d.ts +15 -0
  133. package/dist/components/icon-button.js +18 -0
  134. package/dist/components/inline-alert.d.ts +11 -0
  135. package/dist/components/inline-alert.js +17 -0
  136. package/dist/components/input.d.ts +3 -0
  137. package/dist/components/input.js +7 -0
  138. package/dist/components/kanban-board.d.ts +27 -0
  139. package/dist/components/kanban-board.js +145 -0
  140. package/dist/components/kbd.d.ts +3 -0
  141. package/dist/components/kbd.js +8 -0
  142. package/dist/components/label.d.ts +4 -0
  143. package/dist/components/label.js +9 -0
  144. package/dist/components/markdown-editor/index.d.ts +4 -0
  145. package/dist/components/markdown-editor/index.js +2 -0
  146. package/dist/components/markdown-editor/markdown-editor.d.ts +16 -0
  147. package/dist/components/markdown-editor/markdown-editor.js +53 -0
  148. package/dist/components/markdown-editor/serialize.d.ts +12 -0
  149. package/dist/components/markdown-editor/serialize.js +122 -0
  150. package/dist/components/markdown-editor/vim.d.ts +8 -0
  151. package/dist/components/markdown-editor/vim.js +394 -0
  152. package/dist/components/metric-grid.d.ts +41 -0
  153. package/dist/components/metric-grid.js +39 -0
  154. package/dist/components/microphone-priority.d.ts +29 -0
  155. package/dist/components/microphone-priority.js +15 -0
  156. package/dist/components/middle-truncate.d.ts +6 -0
  157. package/dist/components/middle-truncate.js +15 -0
  158. package/dist/components/multi-combobox.d.ts +48 -0
  159. package/dist/components/multi-combobox.js +221 -0
  160. package/dist/components/naut-avatar-engine.d.ts +83 -0
  161. package/dist/components/naut-avatar-engine.js +803 -0
  162. package/dist/components/naut-avatar.d.ts +31 -0
  163. package/dist/components/naut-avatar.js +108 -0
  164. package/dist/components/navigable-list.d.ts +4 -0
  165. package/dist/components/navigable-list.js +20 -0
  166. package/dist/components/note-icon-picker.d.ts +20 -0
  167. package/dist/components/note-icon-picker.js +84 -0
  168. package/dist/components/note-icon.d.ts +690 -0
  169. package/dist/components/note-icon.js +353 -0
  170. package/dist/components/note-row.d.ts +33 -0
  171. package/dist/components/note-row.js +29 -0
  172. package/dist/components/overlapping-dots.d.ts +10 -0
  173. package/dist/components/overlapping-dots.js +13 -0
  174. package/dist/components/overview-card.d.ts +12 -0
  175. package/dist/components/overview-card.js +9 -0
  176. package/dist/components/panel-header.d.ts +8 -0
  177. package/dist/components/panel-header.js +6 -0
  178. package/dist/components/panel-section-states.d.ts +9 -0
  179. package/dist/components/panel-section-states.js +10 -0
  180. package/dist/components/person-avatar.d.ts +10 -0
  181. package/dist/components/person-avatar.js +23 -0
  182. package/dist/components/photo-avatar.d.ts +11 -0
  183. package/dist/components/photo-avatar.js +24 -0
  184. package/dist/components/picker-field.d.ts +23 -0
  185. package/dist/components/picker-field.js +24 -0
  186. package/dist/components/popover-stack.d.ts +26 -0
  187. package/dist/components/popover-stack.js +89 -0
  188. package/dist/components/popover.d.ts +12 -0
  189. package/dist/components/popover.js +31 -0
  190. package/dist/components/portal-login-barrier.d.ts +12 -0
  191. package/dist/components/portal-login-barrier.js +41 -0
  192. package/dist/components/presence-dot.d.ts +8 -0
  193. package/dist/components/presence-dot.js +15 -0
  194. package/dist/components/presence-overlay.d.ts +27 -0
  195. package/dist/components/presence-overlay.js +34 -0
  196. package/dist/components/property-list.d.ts +64 -0
  197. package/dist/components/property-list.js +313 -0
  198. package/dist/components/property-panel.d.ts +54 -0
  199. package/dist/components/property-panel.js +87 -0
  200. package/dist/components/property-selector.d.ts +36 -0
  201. package/dist/components/property-selector.js +141 -0
  202. package/dist/components/provenance-chip.d.ts +12 -0
  203. package/dist/components/provenance-chip.js +17 -0
  204. package/dist/components/qr-code.d.ts +13 -0
  205. package/dist/components/qr-code.js +42 -0
  206. package/dist/components/qr-encode.d.ts +2 -0
  207. package/dist/components/qr-encode.js +469 -0
  208. package/dist/components/quantity-stepper.d.ts +25 -0
  209. package/dist/components/quantity-stepper.js +43 -0
  210. package/dist/components/radio-group.d.ts +5 -0
  211. package/dist/components/radio-group.js +13 -0
  212. package/dist/components/rename-dialog.d.ts +19 -0
  213. package/dist/components/rename-dialog.js +35 -0
  214. package/dist/components/row-surface.d.ts +1 -0
  215. package/dist/components/row-surface.js +5 -0
  216. package/dist/components/row-trailing.d.ts +30 -0
  217. package/dist/components/row-trailing.js +59 -0
  218. package/dist/components/run-status-badge.d.ts +16 -0
  219. package/dist/components/run-status-badge.js +43 -0
  220. package/dist/components/scroll-area.d.ts +5 -0
  221. package/dist/components/scroll-area.js +12 -0
  222. package/dist/components/select.d.ts +15 -0
  223. package/dist/components/select.js +39 -0
  224. package/dist/components/selectable-card.d.ts +33 -0
  225. package/dist/components/selectable-card.js +66 -0
  226. package/dist/components/separator.d.ts +3 -0
  227. package/dist/components/separator.js +8 -0
  228. package/dist/components/settings-dialog-shell.d.ts +46 -0
  229. package/dist/components/settings-dialog-shell.js +48 -0
  230. package/dist/components/shimmer-text.d.ts +8 -0
  231. package/dist/components/shimmer-text.js +26 -0
  232. package/dist/components/side-panel-tokens.d.ts +27 -0
  233. package/dist/components/side-panel-tokens.js +26 -0
  234. package/dist/components/side-panel.d.ts +94 -0
  235. package/dist/components/side-panel.js +106 -0
  236. package/dist/components/skeleton.d.ts +2 -0
  237. package/dist/components/skeleton.js +6 -0
  238. package/dist/components/sortable.d.ts +65 -0
  239. package/dist/components/sortable.js +110 -0
  240. package/dist/components/spec-strip.d.ts +18 -0
  241. package/dist/components/spec-strip.js +15 -0
  242. package/dist/components/speech-playback.d.ts +25 -0
  243. package/dist/components/speech-playback.js +35 -0
  244. package/dist/components/sql-editor.d.ts +13 -0
  245. package/dist/components/sql-editor.js +228 -0
  246. package/dist/components/stat-tile.d.ts +7 -0
  247. package/dist/components/stat-tile.js +6 -0
  248. package/dist/components/status-badge.d.ts +17 -0
  249. package/dist/components/status-badge.js +8 -0
  250. package/dist/components/status-tone.d.ts +9 -0
  251. package/dist/components/status-tone.js +10 -0
  252. package/dist/components/sticky-header-fade.d.ts +8 -0
  253. package/dist/components/sticky-header-fade.js +11 -0
  254. package/dist/components/swatch-button.d.ts +14 -0
  255. package/dist/components/swatch-button.js +25 -0
  256. package/dist/components/switch.d.ts +6 -0
  257. package/dist/components/switch.js +9 -0
  258. package/dist/components/system-load/index.d.ts +6 -0
  259. package/dist/components/system-load/index.js +6 -0
  260. package/dist/components/system-load/load-block.d.ts +20 -0
  261. package/dist/components/system-load/load-block.js +23 -0
  262. package/dist/components/system-load/load-grid.d.ts +16 -0
  263. package/dist/components/system-load/load-grid.js +23 -0
  264. package/dist/components/system-load/load-meter.d.ts +25 -0
  265. package/dist/components/system-load/load-meter.js +29 -0
  266. package/dist/components/system-load/load-tone.d.ts +21 -0
  267. package/dist/components/system-load/load-tone.js +29 -0
  268. package/dist/components/system-load/meter-row.d.ts +31 -0
  269. package/dist/components/system-load/meter-row.js +29 -0
  270. package/dist/components/system-load/resource-meter.d.ts +19 -0
  271. package/dist/components/system-load/resource-meter.js +15 -0
  272. package/dist/components/tab-title-bar.d.ts +12 -0
  273. package/dist/components/tab-title-bar.js +9 -0
  274. package/dist/components/table.d.ts +10 -0
  275. package/dist/components/table.js +29 -0
  276. package/dist/components/tabs.d.ts +11 -0
  277. package/dist/components/tabs.js +97 -0
  278. package/dist/components/template-chip-input.d.ts +36 -0
  279. package/dist/components/template-chip-input.js +271 -0
  280. package/dist/components/template-input.d.ts +24 -0
  281. package/dist/components/template-input.js +57 -0
  282. package/dist/components/terminal-spinner.d.ts +11 -0
  283. package/dist/components/terminal-spinner.js +48 -0
  284. package/dist/components/textarea.d.ts +3 -0
  285. package/dist/components/textarea.js +7 -0
  286. package/dist/components/time-column.d.ts +24 -0
  287. package/dist/components/time-column.js +60 -0
  288. package/dist/components/timestamped-transcript.d.ts +38 -0
  289. package/dist/components/timestamped-transcript.js +29 -0
  290. package/dist/components/timezone-picker.d.ts +22 -0
  291. package/dist/components/timezone-picker.js +60 -0
  292. package/dist/components/tooltip.d.ts +11 -0
  293. package/dist/components/tooltip.js +29 -0
  294. package/dist/components/transcription-overlay.d.ts +47 -0
  295. package/dist/components/transcription-overlay.js +30 -0
  296. package/dist/components/usage-bar.d.ts +17 -0
  297. package/dist/components/usage-bar.js +26 -0
  298. package/dist/components/view-query-bar.d.ts +13 -0
  299. package/dist/components/view-query-bar.js +13 -0
  300. package/dist/components/view-query-controls.d.ts +159 -0
  301. package/dist/components/view-query-controls.js +109 -0
  302. package/dist/components/view-save-menu.d.ts +20 -0
  303. package/dist/components/view-save-menu.js +13 -0
  304. package/dist/components/view-sort-editor.d.ts +40 -0
  305. package/dist/components/view-sort-editor.js +47 -0
  306. package/dist/components/voice-line.d.ts +37 -0
  307. package/dist/components/voice-line.js +293 -0
  308. package/dist/components/weekly-schedule-editor.d.ts +15 -0
  309. package/dist/components/weekly-schedule-editor.js +28 -0
  310. package/dist/flow/canvas/canvas-frame.d.ts +160 -0
  311. package/dist/flow/canvas/canvas-frame.js +521 -0
  312. package/dist/flow/canvas/collaborator-layer.d.ts +12 -0
  313. package/dist/flow/canvas/collaborator-layer.js +43 -0
  314. package/dist/flow/canvas/connector-edge.d.ts +22 -0
  315. package/dist/flow/canvas/connector-edge.js +61 -0
  316. package/dist/flow/canvas/editor-context.d.ts +23 -0
  317. package/dist/flow/canvas/editor-context.js +6 -0
  318. package/dist/flow/canvas/graph-core.d.ts +60 -0
  319. package/dist/flow/canvas/graph-core.js +296 -0
  320. package/dist/flow/canvas/minimap-sticky-overlay.d.ts +4 -0
  321. package/dist/flow/canvas/minimap-sticky-overlay.js +45 -0
  322. package/dist/flow/canvas/node-card.d.ts +46 -0
  323. package/dist/flow/canvas/node-card.js +56 -0
  324. package/dist/flow/canvas/node-library.d.ts +40 -0
  325. package/dist/flow/canvas/node-library.js +54 -0
  326. package/dist/flow/canvas/sticky-notes.d.ts +25 -0
  327. package/dist/flow/canvas/sticky-notes.js +101 -0
  328. package/dist/flow/collaborative-graph-presence.d.ts +28 -0
  329. package/dist/flow/collaborative-graph-presence.js +55 -0
  330. package/dist/flow/collaborative-graph-sync.d.ts +40 -0
  331. package/dist/flow/collaborative-graph-sync.js +127 -0
  332. package/dist/flow/editor/adapter.d.ts +64 -0
  333. package/dist/flow/editor/adapter.js +1 -0
  334. package/dist/flow/editor/command-registry.d.ts +10 -0
  335. package/dist/flow/editor/command-registry.js +35 -0
  336. package/dist/flow/editor/dag-canvas.d.ts +18 -0
  337. package/dist/flow/editor/dag-canvas.js +33 -0
  338. package/dist/flow/editor/flow-editor.d.ts +54 -0
  339. package/dist/flow/editor/flow-editor.js +199 -0
  340. package/dist/flow/editor/issues-popover.d.ts +11 -0
  341. package/dist/flow/editor/issues-popover.js +70 -0
  342. package/dist/flow/editor/library-rail.d.ts +19 -0
  343. package/dist/flow/editor/library-rail.js +25 -0
  344. package/dist/flow/editor/make-controller.d.ts +18 -0
  345. package/dist/flow/editor/make-controller.js +44 -0
  346. package/dist/flow/editor/node-chip.d.ts +2 -0
  347. package/dist/flow/editor/node-chip.js +16 -0
  348. package/dist/flow/editor/save-publish-bar.d.ts +27 -0
  349. package/dist/flow/editor/save-publish-bar.js +14 -0
  350. package/dist/flow/editor/settings-dialog.d.ts +11 -0
  351. package/dist/flow/editor/settings-dialog.js +11 -0
  352. package/dist/flow/editor/settings-shell.d.ts +21 -0
  353. package/dist/flow/editor/settings-shell.js +20 -0
  354. package/dist/flow/editor/side-rail.d.ts +22 -0
  355. package/dist/flow/editor/side-rail.js +15 -0
  356. package/dist/flow/editor/use-dag-editor.d.ts +94 -0
  357. package/dist/flow/editor/use-dag-editor.js +502 -0
  358. package/dist/flow/index.d.ts +25 -0
  359. package/dist/flow/index.js +25 -0
  360. package/dist/flow/presence-motion.d.ts +10 -0
  361. package/dist/flow/presence-motion.js +88 -0
  362. package/dist/flow/styles.css +1 -0
  363. package/dist/flow/use-collaborative-graph.d.ts +61 -0
  364. package/dist/flow/use-collaborative-graph.js +396 -0
  365. package/dist/flow/use-debounced-value.d.ts +1 -0
  366. package/dist/flow/use-debounced-value.js +10 -0
  367. package/dist/hooks/use-detail-nav.d.ts +11 -0
  368. package/dist/hooks/use-detail-nav.js +49 -0
  369. package/dist/hooks/use-flush-on-hide.d.ts +1 -0
  370. package/dist/hooks/use-flush-on-hide.js +21 -0
  371. package/dist/hooks/use-media-query.d.ts +1 -0
  372. package/dist/hooks/use-media-query.js +20 -0
  373. package/dist/hooks/use-virtualizer.d.ts +1 -0
  374. package/dist/hooks/use-virtualizer.js +1 -0
  375. package/dist/index.d.ts +139 -0
  376. package/dist/index.js +139 -0
  377. package/dist/lib/brand-style.d.ts +6 -0
  378. package/dist/lib/brand-style.js +16 -0
  379. package/dist/lib/cn.d.ts +2 -0
  380. package/dist/lib/cn.js +5 -0
  381. package/dist/lib/composited-glint.d.ts +7 -0
  382. package/dist/lib/composited-glint.js +98 -0
  383. package/dist/lib/date-time-format.d.ts +2 -0
  384. package/dist/lib/date-time-format.js +21 -0
  385. package/dist/lib/disclosure-state.d.ts +11 -0
  386. package/dist/lib/disclosure-state.js +22 -0
  387. package/dist/lib/label-swatches.d.ts +10 -0
  388. package/dist/lib/label-swatches.js +24 -0
  389. package/dist/lib/local-ui-state.d.ts +10 -0
  390. package/dist/lib/local-ui-state.js +95 -0
  391. package/dist/lib/parse-loose-datetime.d.ts +1 -0
  392. package/dist/lib/parse-loose-datetime.js +180 -0
  393. package/dist/lib/parse-loose-time.d.ts +6 -0
  394. package/dist/lib/parse-loose-time.js +53 -0
  395. package/dist/lib/parse-loose.d.ts +1 -0
  396. package/dist/lib/parse-loose.js +170 -0
  397. package/dist/lib/react-19-jsx.d.ts +8 -0
  398. package/dist/lib/react-19-jsx.js +1 -0
  399. package/dist/lib/view-chrome.d.ts +5 -0
  400. package/dist/lib/view-chrome.js +5 -0
  401. package/dist/lib/view-query/config.d.ts +26 -0
  402. package/dist/lib/view-query/config.js +162 -0
  403. package/dist/lib/view-query/evaluate.d.ts +11 -0
  404. package/dist/lib/view-query/evaluate.js +196 -0
  405. package/dist/lib/view-query/group-order.d.ts +25 -0
  406. package/dist/lib/view-query/group-order.js +49 -0
  407. package/dist/lib/view-query/index.d.ts +6 -0
  408. package/dist/lib/view-query/index.js +6 -0
  409. package/dist/lib/view-query/model.d.ts +34 -0
  410. package/dist/lib/view-query/model.js +88 -0
  411. package/dist/lib/view-query/sort.d.ts +7 -0
  412. package/dist/lib/view-query/sort.js +30 -0
  413. package/dist/lib/view-query/types.d.ts +70 -0
  414. package/dist/lib/view-query/types.js +12 -0
  415. package/dist/lib/weekly-schedule.d.ts +8 -0
  416. package/dist/lib/weekly-schedule.js +10 -0
  417. package/dist/mcp-app/index.d.ts +4 -0
  418. package/dist/mcp-app/index.js +3 -0
  419. package/dist/mcp-app/shadcn.css +629 -0
  420. package/dist/mcp-app/styles.css +72 -0
  421. package/dist/mcp-app/theme.d.ts +2 -0
  422. package/dist/mcp-app/theme.js +62 -0
  423. package/dist/mcp-app/use-atmos-mcp-app.d.ts +109 -0
  424. package/dist/mcp-app/use-atmos-mcp-app.js +30 -0
  425. package/dist/mcp-app/vite.d.ts +7 -0
  426. package/dist/mcp-app/vite.js +30 -0
  427. package/dist/tokens/index.d.ts +7 -0
  428. package/dist/tokens/index.js +7 -0
  429. package/dist/tokens/semantic.css +110 -0
  430. package/dist/tokens/tokens.css +195 -0
  431. package/package.json +98 -0
@@ -0,0 +1,803 @@
1
+ const clamp = (v, a, b) => Math.max(a, Math.min(b, v));
2
+ const lerp = (a, b, t) => a + (b - a) * t;
3
+ const approach = (cur, tgt, rate, dt) => cur + (tgt - cur) * (1 - Math.exp(-rate * dt));
4
+ const easeInOut = (t) => (t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2);
5
+ function rng(seed) {
6
+ let s = seed >>> 0 || 1;
7
+ return () => {
8
+ s = (s * 1664525 + 1013904223) >>> 0;
9
+ return s / 4294967296;
10
+ };
11
+ }
12
+ const NODE_SLOTS = [0, 1, 2, 3, 4, 5];
13
+ const NODE_COUNT = 12;
14
+ const norm = (v) => {
15
+ const l = Math.hypot(v[0], v[1]) || 1;
16
+ return [v[0] / l, v[1] / l];
17
+ };
18
+ const node = (p, hIn, hOut) => [
19
+ p[0],
20
+ p[1],
21
+ hIn[0],
22
+ hIn[1],
23
+ hOut[0],
24
+ hOut[1],
25
+ ];
26
+ const ring = (items, i, fallback) => items[((i % items.length) + items.length) % items.length] ?? fallback;
27
+ /** Rounded regular polygon as exactly 12 cubic nodes so every shape morphs into every other. */
28
+ function roundedPolygon(n, R, rc, rot, yShift = 0) {
29
+ const vertex = (k) => {
30
+ const a = rot + (k * 2 * Math.PI) / n;
31
+ return [Math.cos(a) * R, Math.sin(a) * R];
32
+ };
33
+ const turn = (2 * Math.PI) / n;
34
+ const interior = Math.PI - turn;
35
+ const t = rc / Math.tan(interior / 2);
36
+ const k = (4 / 3) * Math.tan(turn / 4) * rc;
37
+ const extra = NODE_COUNT / n - 2;
38
+ const nodes = [];
39
+ for (let i = 0; i < n; i++) {
40
+ const P = vertex(i);
41
+ const Pp = vertex(i - 1);
42
+ const Pn = vertex(i + 1);
43
+ const dIn = norm([P[0] - Pp[0], P[1] - Pp[1]]);
44
+ const dOut = norm([Pn[0] - P[0], Pn[1] - P[1]]);
45
+ const A = [P[0] - dIn[0] * t, P[1] - dIn[1] * t];
46
+ const B = [P[0] + dOut[0] * t, P[1] + dOut[1] * t];
47
+ const An = [Pn[0] - dOut[0] * t, Pn[1] - dOut[1] * t];
48
+ const edge = [An[0] - B[0], An[1] - B[1]];
49
+ const segs = extra + 1;
50
+ nodes.push(node(A, A, [A[0] + dIn[0] * k, A[1] + dIn[1] * k]));
51
+ nodes.push(node(B, [B[0] - dOut[0] * k, B[1] - dOut[1] * k], [B[0] + edge[0] / segs / 3, B[1] + edge[1] / segs / 3]));
52
+ for (let j = 1; j <= extra; j++) {
53
+ const Q = [B[0] + (edge[0] * j) / segs, B[1] + (edge[1] * j) / segs];
54
+ nodes.push(node(Q, [Q[0] - edge[0] / segs / 3, Q[1] - edge[1] / segs / 3], [Q[0] + edge[0] / segs / 3, Q[1] + edge[1] / segs / 3]));
55
+ }
56
+ }
57
+ // The first node of each corner gets its incoming handle from the node before it,
58
+ // which is only known once the previous corner's edge nodes exist.
59
+ nodes.forEach((cur, i) => {
60
+ if (i % (extra + 2) !== 0)
61
+ return;
62
+ const prev = ring(nodes, i - 1, cur);
63
+ cur[2] = cur[0] - (cur[0] - prev[0]) / 3;
64
+ cur[3] = cur[1] - (cur[1] - prev[1]) / 3;
65
+ });
66
+ return nodes.map((nd) => [
67
+ nd[0],
68
+ nd[1] + yShift,
69
+ nd[2],
70
+ nd[3] + yShift,
71
+ nd[4],
72
+ nd[5] + yShift,
73
+ ]);
74
+ }
75
+ function circleNodes(R) {
76
+ const nodes = [];
77
+ const k = (4 / 3) * Math.tan(Math.PI / 24) * R;
78
+ for (let i = 0; i < NODE_COUNT; i++) {
79
+ const a = -Math.PI / 2 + (i * Math.PI) / 6;
80
+ const P = [Math.cos(a) * R, Math.sin(a) * R];
81
+ const tan = [-Math.sin(a), Math.cos(a)];
82
+ nodes.push(node(P, [P[0] - tan[0] * k, P[1] - tan[1] * k], [P[0] + tan[0] * k, P[1] + tan[1] * k]));
83
+ }
84
+ return nodes;
85
+ }
86
+ export const NAUT_SHAPES = ['circle', 'squircle', 'triangle', 'diamond', 'hexagon'];
87
+ const SHAPES = {
88
+ circle: { sphere: 100, eyeY: 0, nodes: circleNodes(100) },
89
+ squircle: { sphere: 100, eyeY: 0, nodes: roundedPolygon(4, 136, 46, (-Math.PI * 3) / 4) },
90
+ triangle: { sphere: 62, eyeY: 14, nodes: roundedPolygon(3, 122, 22, -Math.PI / 2, 28) },
91
+ diamond: { sphere: 68, eyeY: 0, nodes: roundedPolygon(4, 112, 18, -Math.PI / 2) },
92
+ hexagon: { sphere: 88, eyeY: 0, nodes: roundedPolygon(6, 106, 18, -Math.PI / 2) },
93
+ };
94
+ export const NAUT_COLORS = {
95
+ ink: '#111216',
96
+ slate: '#4b5163',
97
+ coral: '#ef6f4f',
98
+ sun: '#f0b429',
99
+ mint: '#2fb585',
100
+ sky: '#3d9ff0',
101
+ lavender: '#8b7cf2',
102
+ rose: '#ec5f98',
103
+ ocean: '#3162e8',
104
+ forest: '#2f6b4f',
105
+ plum: '#6b3a8e',
106
+ clay: '#b5654b',
107
+ };
108
+ export const NAUT_COLOR_KEYS = Object.keys(NAUT_COLORS);
109
+ export const isNautShape = (v) => typeof v === 'string' && NAUT_SHAPES.includes(v);
110
+ export const isNautColor = (v) => typeof v === 'string' && v in NAUT_COLORS;
111
+ const EYE_PARAMS = [
112
+ 'w',
113
+ 'h',
114
+ 'topCut',
115
+ 'topSlant',
116
+ 'botCut',
117
+ 'botSlant',
118
+ 'smile',
119
+ 'tilt',
120
+ 'cross',
121
+ 'pill',
122
+ 'round',
123
+ ];
124
+ const NEUTRAL_EYE = {
125
+ w: 8,
126
+ h: 17,
127
+ topCut: 0,
128
+ topSlant: 0,
129
+ botCut: 0,
130
+ botSlant: 0,
131
+ smile: 0,
132
+ tilt: 0,
133
+ cross: 0,
134
+ pill: 1,
135
+ round: 0.5,
136
+ };
137
+ const NEUTRAL_HEAD = {
138
+ eyeSep: 0.3,
139
+ eyeLat: 0.08,
140
+ curve: 1,
141
+ gazeX: 0,
142
+ gazeY: 0,
143
+ spin: 0,
144
+ roll: 0,
145
+ headX: 0,
146
+ headY: 0,
147
+ sx: 1,
148
+ sy: 1,
149
+ };
150
+ const eyeKey = (param, side) => `${param}${side}`;
151
+ function expandFace(spec) {
152
+ const out = {};
153
+ for (const [k, v] of Object.entries(spec)) {
154
+ if (v === undefined)
155
+ continue;
156
+ if (EYE_PARAMS.includes(k)) {
157
+ const param = k;
158
+ out[eyeKey(param, 'L')] = v;
159
+ out[eyeKey(param, 'R')] = v;
160
+ }
161
+ else
162
+ out[k] = v;
163
+ }
164
+ return out;
165
+ }
166
+ const NEUTRAL = { ...expandFace(NEUTRAL_EYE), ...NEUTRAL_HEAD };
167
+ const FACE_KEYS = Object.keys(NEUTRAL);
168
+ export const NAUT_EXPRESSIONS = [
169
+ 'neutral',
170
+ 'happy',
171
+ 'angry',
172
+ 'surprised',
173
+ 'thinking',
174
+ 'sad',
175
+ 'sleepy',
176
+ 'excited',
177
+ 'error',
178
+ 'confused',
179
+ 'wink',
180
+ 'focused',
181
+ 'laughing',
182
+ 'scared',
183
+ 'smug',
184
+ 'talking',
185
+ 'loading',
186
+ ];
187
+ const EXPRESSIONS = {
188
+ neutral: { face: {} },
189
+ happy: {
190
+ face: { smile: 1, w: 13, h: 12, pill: 0, round: 1 },
191
+ loop: (t, o) => {
192
+ o.headY += -1.5 * Math.abs(Math.sin(t * 4));
193
+ },
194
+ },
195
+ angry: {
196
+ face: { topCut: 0.45, topSlant: 24, round: 0.3, gazeY: 0.12 },
197
+ loop: (t, o) => {
198
+ o.headX += Math.sin(t * 60) * 0.7;
199
+ },
200
+ },
201
+ surprised: { face: { w: 11, h: 21, sy: 1.02 }, enter: 'pop' },
202
+ thinking: {
203
+ face: {
204
+ topCutL: 0.5,
205
+ topCutR: 0.25,
206
+ botCut: 0.1,
207
+ round: 0.3,
208
+ gazeX: 0.7,
209
+ gazeY: -0.7,
210
+ roll: -5,
211
+ },
212
+ loop: (t, o) => {
213
+ o.gazeX += Math.sin(t * 0.9) * 0.25;
214
+ o.gazeY += Math.cos(t * 1.3) * 0.08;
215
+ o.headY += Math.sin(t * 2.2) * 0.8;
216
+ },
217
+ },
218
+ sad: {
219
+ face: { topCut: 0.4, topSlant: -20, round: 0.4, gazeY: 0.6, headY: 5, roll: 4 },
220
+ loop: (t, o) => {
221
+ o.roll += Math.sin(t * 1.4) * 1.2;
222
+ o.headY += Math.sin(t * 1.1) * 1;
223
+ },
224
+ },
225
+ sleepy: {
226
+ face: { topCut: 0.55, botCut: 0, round: 0.6, gazeY: 0.25, headY: 3 },
227
+ loop: (t, o) => {
228
+ const s = Math.max(0, Math.sin(t * 1.2));
229
+ o.topCutL += s * 0.25;
230
+ o.topCutR += s * 0.25;
231
+ o.headY += Math.sin(t * 0.6) * 2;
232
+ o.roll += Math.sin(t * 0.6) * 2;
233
+ },
234
+ },
235
+ excited: {
236
+ face: { w: 9.5, h: 21 },
237
+ loop: (t, o) => {
238
+ o.headY += -3 * Math.abs(Math.sin(t * 7));
239
+ o.roll += Math.sin(t * 7) * 2;
240
+ },
241
+ },
242
+ error: {
243
+ face: { cross: 1, w: 15, h: 15, pill: 0, round: 0.2 },
244
+ loop: (t, o) => {
245
+ o.headX += Math.sin(t * 90) * Math.exp(-(t % 2.4) * 3) * 3;
246
+ },
247
+ },
248
+ confused: {
249
+ face: { topCutL: 0.35, topSlantL: -14, round: 0.4, gazeX: 0.35, gazeY: -0.2, roll: 9 },
250
+ loop: (t, o) => {
251
+ o.gazeX += Math.sin(t * 1.1) * 0.3;
252
+ o.roll += Math.sin(t * 0.7) * 3;
253
+ },
254
+ },
255
+ wink: { face: { topCutR: 0.5, botCutR: 0.44, smileL: 0.35, round: 0.6, roll: -3 } },
256
+ focused: {
257
+ face: { topCut: 0.28, botCut: 0.22, round: 0.25, w: 8.5, h: 17 },
258
+ loop: (t, o) => {
259
+ o.headY += Math.sin(t * 1.2) * 0.3;
260
+ },
261
+ },
262
+ laughing: {
263
+ face: { smile: 1, w: 14, h: 12, pill: 0, round: 1, gazeY: -0.15 },
264
+ loop: (t, o) => {
265
+ o.headY += -2.5 * Math.abs(Math.sin(t * 11));
266
+ o.roll += Math.sin(t * 11) * 2.5;
267
+ o.sy += Math.abs(Math.sin(t * 11)) * 0.02;
268
+ },
269
+ },
270
+ scared: {
271
+ face: { w: 7, h: 14, eyeSep: 0.38, gazeY: -0.1 },
272
+ loop: (t, o) => {
273
+ o.headX += Math.sin(t * 70) * 1.2;
274
+ o.gazeX += Math.sin(t * 9) * 0.12;
275
+ },
276
+ },
277
+ smug: { face: { topCut: 0.42, topSlant: -8, round: 0.3, gazeX: 0.45, roll: -4, smile: 0.25 } },
278
+ talking: {
279
+ face: {},
280
+ loop: (t, o) => {
281
+ const s = Math.abs(Math.sin(t * 9)) * 0.55 + Math.abs(Math.sin(t * 5.3)) * 0.45;
282
+ o.hL += s * 3;
283
+ o.hR += s * 3;
284
+ o.headY += Math.sin(t * 9) * 0.6;
285
+ o.gazeY += -0.08 * s;
286
+ },
287
+ },
288
+ loading: {
289
+ face: { w: 7, h: 7, round: 1 },
290
+ loop: (t, o) => {
291
+ o.gazeX += Math.cos(t * 3) * 0.75;
292
+ o.gazeY += Math.sin(t * 3) * 0.55;
293
+ },
294
+ },
295
+ };
296
+ export const NAUT_GESTURES = [
297
+ 'nod',
298
+ 'shake',
299
+ 'blink',
300
+ 'wink',
301
+ 'bounce',
302
+ 'jump',
303
+ 'spin',
304
+ 'lookAround',
305
+ 'shiver',
306
+ 'celebrate',
307
+ 'nope',
308
+ 'pop',
309
+ ];
310
+ const GESTURES = {
311
+ nod: {
312
+ dur: 1.1,
313
+ fn: (t, o) => {
314
+ const s = Math.pow(Math.sin(t * Math.PI * 2), 2) * (1 - t * 0.3);
315
+ o.gazeY += 0.9 * s;
316
+ o.headY += 6 * s;
317
+ o.sy -= 0.04 * s;
318
+ },
319
+ },
320
+ shake: {
321
+ dur: 1.0,
322
+ fn: (t, o) => {
323
+ const env = Math.sin(t * Math.PI);
324
+ const w = Math.sin(t * Math.PI * 2 * 2.5);
325
+ o.gazeX += 0.9 * w * env;
326
+ o.headX += 6 * w * env;
327
+ },
328
+ },
329
+ blink: {
330
+ dur: 0.22,
331
+ fn: (t, o) => {
332
+ const s = Math.sin(t * Math.PI);
333
+ o.topCutL += 0.5 * s;
334
+ o.topCutR += 0.5 * s;
335
+ o.botCutL += 0.5 * s;
336
+ o.botCutR += 0.5 * s;
337
+ },
338
+ },
339
+ wink: {
340
+ dur: 0.5,
341
+ fn: (t, o) => {
342
+ const s = Math.sin(t * Math.PI);
343
+ o.topCutR += 0.5 * s;
344
+ o.botCutR += 0.45 * s;
345
+ o.roll += -3 * s;
346
+ },
347
+ },
348
+ bounce: {
349
+ dur: 0.7,
350
+ fn: (t, o) => {
351
+ const up = Math.sin(t * Math.PI);
352
+ o.headY += -30 * up;
353
+ const sq = Math.sin(t * Math.PI * 2);
354
+ o.sy += 0.1 * sq * (1 - t);
355
+ o.sx -= 0.08 * sq * (1 - t);
356
+ },
357
+ },
358
+ jump: {
359
+ dur: 0.9,
360
+ fn: (t, o) => {
361
+ const up = Math.sin(t * Math.PI);
362
+ o.headY += -55 * up;
363
+ o.gazeY += -0.4 * up;
364
+ const sq = Math.sin(t * Math.PI * 2);
365
+ o.sy += 0.12 * sq * (1 - t);
366
+ o.sx -= 0.1 * sq * (1 - t);
367
+ },
368
+ },
369
+ spin: {
370
+ dur: 1.0,
371
+ fn: (t, o) => {
372
+ o.spin += Math.PI * 2 * easeInOut(t);
373
+ },
374
+ },
375
+ lookAround: {
376
+ dur: 2.4,
377
+ fn: (t, o) => {
378
+ const env = Math.sin(t * Math.PI);
379
+ o.gazeX += -Math.sin(t * Math.PI * 2) * 0.95 * Math.min(1, env * 3);
380
+ o.gazeY += -0.25 * env;
381
+ },
382
+ },
383
+ shiver: {
384
+ dur: 1.0,
385
+ fn: (t, o) => {
386
+ const env = Math.sin(t * Math.PI);
387
+ o.headX += Math.sin(t * 90) * 2 * env;
388
+ o.wL -= 1.5 * env;
389
+ o.wR -= 1.5 * env;
390
+ },
391
+ },
392
+ celebrate: {
393
+ dur: 1.4,
394
+ fn: (t, o) => {
395
+ const b = Math.abs(Math.sin(t * Math.PI * 2));
396
+ o.headY += -22 * b;
397
+ o.roll += Math.sin(t * Math.PI * 4) * 8;
398
+ const s = Math.sin(t * Math.PI);
399
+ o.smileL += s;
400
+ o.smileR += s;
401
+ o.wL += 4 * s;
402
+ o.wR += 4 * s;
403
+ o.hL -= 4 * s;
404
+ o.hR -= 4 * s;
405
+ o.pillL -= s;
406
+ o.pillR -= s;
407
+ },
408
+ },
409
+ nope: {
410
+ dur: 1.3,
411
+ fn: (t, o) => {
412
+ const env = Math.sin(t * Math.PI);
413
+ const w = Math.sin(t * Math.PI * 2 * 3.5);
414
+ o.gazeX += 0.8 * w * env;
415
+ o.headX += 5 * w * env;
416
+ o.topCutL += 0.5 * env;
417
+ o.topCutR += 0.5 * env;
418
+ o.botCutL += 0.44 * env;
419
+ o.botCutR += 0.44 * env;
420
+ },
421
+ },
422
+ pop: {
423
+ dur: 0.5,
424
+ fn: (t, o) => {
425
+ const s = Math.sin(t * Math.PI) * Math.exp(-t * 2);
426
+ o.sx += 0.1 * s;
427
+ o.sy += 0.1 * s;
428
+ },
429
+ },
430
+ };
431
+ // ---------- eye geometry: one closed polygon per eye, in the eye's local tangent plane ----------
432
+ const EYE_SAMPLES = 40;
433
+ const crossR = (a) => 0.32 + 0.68 * Math.pow(Math.abs(Math.sin(2 * a)), 8);
434
+ function stadiumR(a, w, h) {
435
+ const c = Math.cos(a);
436
+ const s = Math.sin(a);
437
+ const ac = Math.abs(c) + 1e-9;
438
+ const as = Math.abs(s) + 1e-9;
439
+ const r = Math.min(w, h);
440
+ const kx = w - r;
441
+ const ky = h - r;
442
+ const rectA = Math.min(w / ac, ky / as);
443
+ const rectB = Math.min(kx / ac, h / as);
444
+ const circ = (cx, cy) => {
445
+ const dc = c * cx + s * cy;
446
+ const disc = dc * dc - (cx * cx + cy * cy) + r * r;
447
+ return disc < 0 ? 0 : dc + Math.sqrt(disc);
448
+ };
449
+ return Math.max(rectA, rectB, circ(kx, ky), circ(-kx, ky), circ(kx, -ky), circ(-kx, -ky));
450
+ }
451
+ function clipHalfPlane(pts, f) {
452
+ const out = [];
453
+ pts.forEach((a, i) => {
454
+ const b = ring(pts, i + 1, a);
455
+ const fa = f(a);
456
+ const fb = f(b);
457
+ if (fa >= 0)
458
+ out.push(a);
459
+ if (fa >= 0 !== fb >= 0) {
460
+ const t = fa / (fa - fb);
461
+ out.push([a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t]);
462
+ }
463
+ });
464
+ return out;
465
+ }
466
+ function chaikin(pts, ratio) {
467
+ if (ratio <= 0.001 || pts.length < 3)
468
+ return pts;
469
+ const out = [];
470
+ pts.forEach((a, i) => {
471
+ const b = ring(pts, i + 1, a);
472
+ out.push([lerp(a[0], b[0], ratio), lerp(a[1], b[1], ratio)], [lerp(a[0], b[0], 1 - ratio), lerp(a[1], b[1], 1 - ratio)]);
473
+ });
474
+ return out;
475
+ }
476
+ function circleHit(pIn, pOut, cx, cy, r) {
477
+ const dx = pOut[0] - pIn[0];
478
+ const dy = pOut[1] - pIn[1];
479
+ const fx = pIn[0] - cx;
480
+ const fy = pIn[1] - cy;
481
+ const a = dx * dx + dy * dy;
482
+ const b = 2 * (fx * dx + fy * dy);
483
+ const c = fx * fx + fy * fy - r * r;
484
+ const t = clamp((-b + Math.sqrt(Math.max(0, b * b - 4 * a * c))) / (2 * a), 0, 1);
485
+ return [pIn[0] + dx * t, pIn[1] + dy * t];
486
+ }
487
+ /** Crescent = eye boundary outside the circle + the circle arc that runs through the eye. */
488
+ function subtractCircle(pts, cx, cy, r) {
489
+ const n = pts.length;
490
+ const inside = pts.map((q) => Math.hypot(q[0] - cx, q[1] - cy) < r);
491
+ if (!inside.some(Boolean))
492
+ return pts;
493
+ if (inside.every(Boolean))
494
+ return [];
495
+ const start = inside.findIndex((isIn, i) => !isIn && ring(inside, i - 1, false));
496
+ if (start < 0)
497
+ return pts;
498
+ const origin = [0, 0];
499
+ const startPt = ring(pts, start, origin);
500
+ const entry = circleHit(ring(pts, start - 1, origin), startPt, cx, cy, r);
501
+ const out = [entry];
502
+ let i = start;
503
+ while (!ring(inside, i, true)) {
504
+ out.push(ring(pts, i, origin));
505
+ i = (i + 1) % n;
506
+ if (i === start)
507
+ break;
508
+ }
509
+ const exit = circleHit(ring(pts, i, origin), ring(pts, i - 1, origin), cx, cy, r);
510
+ out.push(exit);
511
+ const a1 = Math.atan2(exit[1] - cy, exit[0] - cx);
512
+ const a2 = Math.atan2(entry[1] - cy, entry[0] - cx);
513
+ let delta = a2 - a1;
514
+ while (delta <= 0)
515
+ delta += Math.PI * 2;
516
+ const midCW = [cx + Math.cos(a1 + delta / 2) * r, cy + Math.sin(a1 + delta / 2) * r];
517
+ const midCCW = [
518
+ cx + Math.cos(a1 - (Math.PI * 2 - delta) / 2) * r,
519
+ cy + Math.sin(a1 - (Math.PI * 2 - delta) / 2) * r,
520
+ ];
521
+ const cw = Math.hypot(midCW[0], midCW[1]) < Math.hypot(midCCW[0], midCCW[1]);
522
+ const span = cw ? delta : -(Math.PI * 2 - delta);
523
+ for (let k = 1; k < 18; k++) {
524
+ const a = a1 + (span * k) / 18;
525
+ out.push([cx + Math.cos(a) * r, cy + Math.sin(a) * r]);
526
+ }
527
+ return out;
528
+ }
529
+ function eyePolygon(p, sgn) {
530
+ const w = Math.max(p.w, 0.5);
531
+ const h = Math.max(p.h, 0.5);
532
+ const cross = clamp(p.cross, 0, 1);
533
+ const pill = clamp(p.pill, 0, 1);
534
+ let pts = [];
535
+ for (let i = 0; i < EYE_SAMPLES; i++) {
536
+ const a = (i / EYE_SAMPLES) * Math.PI * 2;
537
+ const ellipseR = 1 / Math.hypot(Math.cos(a) / w, Math.sin(a) / h);
538
+ const baseR = lerp(ellipseR, stadiumR(a, w, h), pill);
539
+ const r = (1 - cross) * baseR + cross * crossR(a) * Math.max(w, h);
540
+ pts.push([Math.cos(a) * r, Math.sin(a) * r]);
541
+ }
542
+ let topCut = clamp(p.topCut, 0, 1);
543
+ let botCut = clamp(p.botCut, 0, 1);
544
+ const total = topCut + botCut;
545
+ if (total > 0.94) {
546
+ topCut *= 0.94 / total;
547
+ botCut *= 0.94 / total;
548
+ }
549
+ const topY = -h + topCut * 2 * h;
550
+ const botY = h - botCut * 2 * h;
551
+ const kt = Math.tan((p.topSlant * Math.PI) / 180);
552
+ const kb = Math.tan((p.botSlant * Math.PI) / 180);
553
+ if (topCut > 0.001 || Math.abs(kt) > 0.001)
554
+ pts = clipHalfPlane(pts, (q) => q[1] - (topY - sgn * q[0] * kt));
555
+ if (botCut > 0.001 || Math.abs(kb) > 0.001)
556
+ pts = clipHalfPlane(pts, (q) => botY - sgn * q[0] * kb - q[1]);
557
+ const smile = clamp(p.smile, 0, 1);
558
+ if (smile > 0.001) {
559
+ const cr = Math.max(w, h) * 1.05;
560
+ pts = subtractCircle(pts, 0, lerp(h + cr + 2, cr - h * 0.58, smile), cr);
561
+ }
562
+ if (pts.length < 3)
563
+ return [];
564
+ const ratio = 0.25 * clamp(p.round, 0, 1);
565
+ pts = chaikin(chaikin(pts, ratio), ratio);
566
+ const ang = (-sgn * p.tilt * Math.PI) / 180;
567
+ const ca = Math.cos(ang);
568
+ const sa = Math.sin(ang);
569
+ return pts.map((q) => [q[0] * ca - q[1] * sa, q[0] * sa + q[1] * ca]);
570
+ }
571
+ // ---------- sphere mapping: eyes sit on a ball; gaze rotates the ball ----------
572
+ const rotY = (v, a) => {
573
+ const c = Math.cos(a);
574
+ const s = Math.sin(a);
575
+ return [v[0] * c + v[2] * s, v[1], -v[0] * s + v[2] * c];
576
+ };
577
+ const rotX = (v, a) => {
578
+ const c = Math.cos(a);
579
+ const s = Math.sin(a);
580
+ return [v[0], v[1] * c - v[2] * s, v[1] * s + v[2] * c];
581
+ };
582
+ function eyeFrame(lon, lat, yaw, pitch) {
583
+ const P = [Math.cos(lat) * Math.sin(lon), -Math.sin(lat), Math.cos(lat) * Math.cos(lon)];
584
+ const U = [Math.cos(lon), 0, -Math.sin(lon)];
585
+ const V = [Math.sin(lat) * Math.sin(lon), Math.cos(lat), Math.sin(lat) * Math.cos(lon)];
586
+ const R = (v) => rotX(rotY(v, yaw), pitch);
587
+ return { P: R(P), U: R(U), V: R(V) };
588
+ }
589
+ function nodePath(nodes) {
590
+ const first = nodes[0];
591
+ if (!first)
592
+ return '';
593
+ let d = `M ${first[0].toFixed(2)} ${first[1].toFixed(2)}`;
594
+ nodes.forEach((a, i) => {
595
+ const b = ring(nodes, i + 1, a);
596
+ d += ` C ${a[4].toFixed(2)} ${a[5].toFixed(2)} ${b[2].toFixed(2)} ${b[3].toFixed(2)} ${b[0].toFixed(2)} ${b[1].toFixed(2)}`;
597
+ });
598
+ return d + ' Z';
599
+ }
600
+ const cloneNodes = (nodes) => nodes.map((n) => [n[0], n[1], n[2], n[3], n[4], n[5]]);
601
+ export const NAUT_VIEWBOX = '-126 -126 252 252';
602
+ /**
603
+ * Framework-agnostic renderer: owns the animation state and writes attributes onto the
604
+ * SVG elements it is given. Call `update(dt)` once per frame.
605
+ */
606
+ export class NautAvatarEngine {
607
+ shape;
608
+ color;
609
+ expression;
610
+ idle;
611
+ /** Pointer/gaze target in [-1, 1]; null = no external gaze. */
612
+ gazeTarget = null;
613
+ rand;
614
+ time;
615
+ emotionTime = 0;
616
+ gestures = [];
617
+ nodes;
618
+ sphere;
619
+ eyeYOff;
620
+ face;
621
+ targetFace;
622
+ idleState = {
623
+ gazeX: 0,
624
+ gazeY: 0,
625
+ nextGaze: 1,
626
+ nextBlink: 2,
627
+ roll: 0,
628
+ nextRoll: 3,
629
+ curGazeX: 0,
630
+ curGazeY: 0,
631
+ curRoll: 0,
632
+ };
633
+ el = null;
634
+ constructor(opts = {}) {
635
+ this.rand = rng(opts.seed ?? 1);
636
+ this.shape = opts.shape ?? 'circle';
637
+ this.color = opts.color ?? 'ink';
638
+ this.expression = opts.expression ?? 'neutral';
639
+ this.idle = opts.idle ?? true;
640
+ this.time = this.rand() * 100;
641
+ this.idleState.nextBlink = 2 + this.rand() * 3;
642
+ this.nodes = cloneNodes(SHAPES[this.shape].nodes);
643
+ this.sphere = SHAPES[this.shape].sphere;
644
+ this.eyeYOff = SHAPES[this.shape].eyeY;
645
+ this.face = { ...NEUTRAL };
646
+ this.targetFace = { ...NEUTRAL };
647
+ this.setExpression(this.expression, true);
648
+ }
649
+ attach(el) {
650
+ this.el = el;
651
+ }
652
+ setShape(shape) {
653
+ this.shape = shape;
654
+ }
655
+ setColor(color) {
656
+ this.color = color;
657
+ }
658
+ setExpression(key, instant = false) {
659
+ const def = EXPRESSIONS[key];
660
+ const changed = key !== this.expression;
661
+ this.expression = key;
662
+ if (changed || instant)
663
+ this.emotionTime = 0;
664
+ this.targetFace = { ...NEUTRAL, ...expandFace(def.face) };
665
+ if (instant)
666
+ Object.assign(this.face, this.targetFace);
667
+ if (def.enter && !instant && changed)
668
+ this.play(def.enter);
669
+ }
670
+ play(key) {
671
+ this.gestures.push({ key, t: 0 });
672
+ }
673
+ /** Snap every tween to its target (used for static renders / reduced motion). */
674
+ settle() {
675
+ Object.assign(this.face, this.targetFace);
676
+ this.nodes = cloneNodes(SHAPES[this.shape].nodes);
677
+ this.sphere = SHAPES[this.shape].sphere;
678
+ this.eyeYOff = SHAPES[this.shape].eyeY;
679
+ this.gestures = [];
680
+ }
681
+ update(dt) {
682
+ this.time += dt;
683
+ this.emotionTime += dt;
684
+ const shape = SHAPES[this.shape];
685
+ this.nodes.forEach((cur, i) => {
686
+ const target = ring(shape.nodes, i, cur);
687
+ for (const j of NODE_SLOTS)
688
+ cur[j] = approach(cur[j], target[j], 8, dt);
689
+ });
690
+ this.sphere = approach(this.sphere, shape.sphere, 8, dt);
691
+ this.eyeYOff = approach(this.eyeYOff, shape.eyeY, 8, dt);
692
+ const f = this.face;
693
+ for (const k of FACE_KEYS)
694
+ f[k] = approach(f[k], this.targetFace[k], 9, dt);
695
+ const o = { ...f };
696
+ const def = EXPRESSIONS[this.expression];
697
+ if (def.loop)
698
+ def.loop(this.emotionTime, o);
699
+ this.updateIdle(dt, o);
700
+ for (const g of this.gestures) {
701
+ g.t += dt / GESTURES[g.key].dur;
702
+ GESTURES[g.key].fn(clamp(g.t, 0, 1), o);
703
+ }
704
+ this.gestures = this.gestures.filter((g) => g.t < 1);
705
+ this.render(o);
706
+ }
707
+ updateIdle(dt, o) {
708
+ const s = this.idleState;
709
+ if (this.idle) {
710
+ s.nextGaze -= dt;
711
+ if (s.nextGaze <= 0) {
712
+ if (this.rand() < 0.3) {
713
+ s.gazeX = 0;
714
+ s.gazeY = 0;
715
+ }
716
+ else {
717
+ s.gazeX = (this.rand() * 2 - 1) * 0.8;
718
+ s.gazeY = (this.rand() * 2 - 1) * 0.6;
719
+ }
720
+ s.nextGaze = 1.2 + this.rand() * 3.2;
721
+ }
722
+ s.nextBlink -= dt;
723
+ if (s.nextBlink <= 0) {
724
+ this.play('blink');
725
+ s.nextBlink = this.rand() < 0.2 ? 0.35 : 2.5 + this.rand() * 4;
726
+ }
727
+ s.nextRoll -= dt;
728
+ if (s.nextRoll <= 0) {
729
+ s.roll = (this.rand() * 2 - 1) * 3;
730
+ s.nextRoll = 2.5 + this.rand() * 4;
731
+ }
732
+ o.headY += Math.sin(this.time * 1.6) * 0.6;
733
+ }
734
+ else {
735
+ s.gazeX = 0;
736
+ s.gazeY = 0;
737
+ s.roll = 0;
738
+ }
739
+ s.curGazeX = approach(s.curGazeX, s.gazeX, 14, dt);
740
+ s.curGazeY = approach(s.curGazeY, s.gazeY, 14, dt);
741
+ s.curRoll = approach(s.curRoll, s.roll, 3, dt);
742
+ if (this.gazeTarget) {
743
+ s.curGazeX = approach(s.curGazeX, this.gazeTarget.x, 30, dt);
744
+ s.curGazeY = approach(s.curGazeY, this.gazeTarget.y, 30, dt);
745
+ }
746
+ o.gazeX += s.curGazeX;
747
+ o.gazeY += s.curGazeY;
748
+ o.roll += s.curRoll;
749
+ }
750
+ render(o) {
751
+ const el = this.el;
752
+ if (!el)
753
+ return;
754
+ el.root.setAttribute('transform', `translate(${o.headX.toFixed(2)} ${o.headY.toFixed(2)}) scale(${o.sx.toFixed(3)} ${o.sy.toFixed(3)})`);
755
+ el.body.setAttribute('d', nodePath(this.nodes));
756
+ el.body.setAttribute('fill', NAUT_COLORS[this.color]);
757
+ el.eyes.setAttribute('transform', `rotate(${o.roll.toFixed(2)})`);
758
+ const yaw = clamp(o.gazeX, -1.3, 1.3) * 0.85 + o.spin;
759
+ const pitch = -clamp(o.gazeY, -1.3, 1.3) * 0.7;
760
+ const R = this.sphere;
761
+ for (const side of ['L', 'R']) {
762
+ const sgn = side === 'L' ? -1 : 1;
763
+ const p = { ...NEUTRAL_EYE };
764
+ for (const k of EYE_PARAMS)
765
+ p[k] = o[eyeKey(k, side)];
766
+ const poly = eyePolygon(p, sgn);
767
+ const eye = side === 'L' ? el.eyeL : el.eyeR;
768
+ if (!poly.length) {
769
+ eye.setAttribute('d', '');
770
+ continue;
771
+ }
772
+ const fr = eyeFrame(sgn * o.eyeSep, o.eyeLat, yaw, pitch);
773
+ const curve = clamp(o.curve, 0, 1.5);
774
+ const cx = fr.P[0] * R;
775
+ const cy = fr.P[1] * R + this.eyeYOff;
776
+ const ux = lerp(1, fr.U[0], curve);
777
+ const uy = lerp(0, fr.U[1], curve);
778
+ const vx = lerp(0, fr.V[0], curve);
779
+ const vy = lerp(1, fr.V[1], curve);
780
+ const d = poly
781
+ .map(([lx, ly], i) => `${i ? 'L' : 'M'} ${(cx + ux * lx + vx * ly).toFixed(2)} ${(cy + uy * lx + vy * ly).toFixed(2)}`)
782
+ .join(' ');
783
+ eye.setAttribute('d', d + ' Z');
784
+ eye.style.opacity = fr.P[2] > 0 ? '1' : '0';
785
+ }
786
+ }
787
+ }
788
+ /** Stable pseudo-random pick so the same id always gets the same appearance. */
789
+ export function hashSeed(input) {
790
+ let h = 2166136261;
791
+ for (let i = 0; i < input.length; i++) {
792
+ h ^= input.charCodeAt(i);
793
+ h = Math.imul(h, 16777619);
794
+ }
795
+ return h >>> 0;
796
+ }
797
+ export function nautAppearanceForSeed(seed) {
798
+ const h = hashSeed(seed);
799
+ return {
800
+ shape: NAUT_SHAPES[h % NAUT_SHAPES.length] ?? 'circle',
801
+ color: NAUT_COLOR_KEYS[(h >>> 8) % NAUT_COLOR_KEYS.length] ?? 'ink',
802
+ };
803
+ }