snice 4.8.0 → 4.9.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 (315) hide show
  1. package/adapters/react/camera-annotate.d.ts +27 -0
  2. package/adapters/react/camera-annotate.d.ts.map +1 -0
  3. package/adapters/react/camera-annotate.js +24 -0
  4. package/adapters/react/camera-annotate.js.map +1 -0
  5. package/adapters/react/camera-annotate.tsx +35 -0
  6. package/adapters/react/candlestick.d.ts +34 -0
  7. package/adapters/react/candlestick.d.ts.map +1 -0
  8. package/adapters/react/candlestick.js +24 -0
  9. package/adapters/react/candlestick.js.map +1 -0
  10. package/adapters/react/candlestick.tsx +42 -0
  11. package/adapters/react/components.d.ts +14 -0
  12. package/adapters/react/components.d.ts.map +1 -1
  13. package/adapters/react/components.js +7 -0
  14. package/adapters/react/components.js.map +1 -1
  15. package/adapters/react/components.ts +14 -0
  16. package/adapters/react/funnel.d.ts +31 -0
  17. package/adapters/react/funnel.d.ts.map +1 -0
  18. package/adapters/react/funnel.js +24 -0
  19. package/adapters/react/funnel.js.map +1 -0
  20. package/adapters/react/funnel.tsx +39 -0
  21. package/adapters/react/network-graph.d.ts +32 -0
  22. package/adapters/react/network-graph.d.ts.map +1 -0
  23. package/adapters/react/network-graph.js +24 -0
  24. package/adapters/react/network-graph.js.map +1 -0
  25. package/adapters/react/network-graph.tsx +40 -0
  26. package/adapters/react/sankey.d.ts +31 -0
  27. package/adapters/react/sankey.d.ts.map +1 -0
  28. package/adapters/react/sankey.js +24 -0
  29. package/adapters/react/sankey.js.map +1 -0
  30. package/adapters/react/sankey.tsx +39 -0
  31. package/adapters/react/time-range-picker.d.ts +33 -0
  32. package/adapters/react/time-range-picker.d.ts.map +1 -0
  33. package/adapters/react/time-range-picker.js +24 -0
  34. package/adapters/react/time-range-picker.js.map +1 -0
  35. package/adapters/react/time-range-picker.tsx +41 -0
  36. package/adapters/react/treemap.d.ts +30 -0
  37. package/adapters/react/treemap.d.ts.map +1 -0
  38. package/adapters/react/treemap.js +24 -0
  39. package/adapters/react/treemap.js.map +1 -0
  40. package/adapters/react/treemap.tsx +38 -0
  41. package/adapters/react/virtual-scroller.d.ts +1 -0
  42. package/adapters/react/virtual-scroller.d.ts.map +1 -1
  43. package/adapters/react/virtual-scroller.js +1 -1
  44. package/adapters/react/virtual-scroller.js.map +1 -1
  45. package/adapters/react/virtual-scroller.tsx +2 -1
  46. package/dist/cdn/accordion/snice-accordion.js +1 -1
  47. package/dist/cdn/accordion/snice-accordion.min.js +1 -1
  48. package/dist/cdn/alert/snice-alert.js +1 -1
  49. package/dist/cdn/alert/snice-alert.min.js +1 -1
  50. package/dist/cdn/audio-recorder/snice-audio-recorder.js +1 -1
  51. package/dist/cdn/audio-recorder/snice-audio-recorder.min.js +1 -1
  52. package/dist/cdn/avatar/snice-avatar.js +1 -1
  53. package/dist/cdn/avatar/snice-avatar.min.js +1 -1
  54. package/dist/cdn/badge/snice-badge.js +1 -1
  55. package/dist/cdn/badge/snice-badge.min.js +1 -1
  56. package/dist/cdn/banner/snice-banner.js +1 -1
  57. package/dist/cdn/banner/snice-banner.min.js +1 -1
  58. package/dist/cdn/breadcrumbs/snice-breadcrumbs.js +2 -2
  59. package/dist/cdn/breadcrumbs/snice-breadcrumbs.js.map +1 -1
  60. package/dist/cdn/breadcrumbs/snice-breadcrumbs.min.js +13 -13
  61. package/dist/cdn/breadcrumbs/snice-breadcrumbs.min.js.map +1 -1
  62. package/dist/cdn/button/snice-button.js +1 -1
  63. package/dist/cdn/button/snice-button.min.js +1 -1
  64. package/dist/cdn/calendar/snice-calendar.js +1 -1
  65. package/dist/cdn/calendar/snice-calendar.min.js +1 -1
  66. package/dist/cdn/camera/snice-camera.js +1 -1
  67. package/dist/cdn/camera/snice-camera.min.js +1 -1
  68. package/dist/cdn/camera-annotate/README.md +27 -0
  69. package/dist/cdn/camera-annotate/snice-camera-annotate.js +730 -0
  70. package/dist/cdn/camera-annotate/snice-camera-annotate.js.map +1 -0
  71. package/dist/cdn/camera-annotate/snice-camera-annotate.min.js +144 -0
  72. package/dist/cdn/camera-annotate/snice-camera-annotate.min.js.map +1 -0
  73. package/dist/cdn/candlestick/README.md +27 -0
  74. package/dist/cdn/candlestick/snice-candlestick.js +717 -0
  75. package/dist/cdn/candlestick/snice-candlestick.js.map +1 -0
  76. package/dist/cdn/candlestick/snice-candlestick.min.js +22 -0
  77. package/dist/cdn/candlestick/snice-candlestick.min.js.map +1 -0
  78. package/dist/cdn/card/snice-card.js +1 -1
  79. package/dist/cdn/card/snice-card.min.js +1 -1
  80. package/dist/cdn/carousel/snice-carousel.js +1 -1
  81. package/dist/cdn/carousel/snice-carousel.min.js +1 -1
  82. package/dist/cdn/chart/snice-chart.js +1 -1
  83. package/dist/cdn/chart/snice-chart.min.js +1 -1
  84. package/dist/cdn/chat/snice-chat.js +1 -1
  85. package/dist/cdn/chat/snice-chat.min.js +1 -1
  86. package/dist/cdn/checkbox/snice-checkbox.js +1 -1
  87. package/dist/cdn/checkbox/snice-checkbox.min.js +1 -1
  88. package/dist/cdn/chip/snice-chip.js +1 -1
  89. package/dist/cdn/chip/snice-chip.min.js +1 -1
  90. package/dist/cdn/code-block/snice-code-block.js +1 -1
  91. package/dist/cdn/code-block/snice-code-block.min.js +1 -1
  92. package/dist/cdn/color-display/snice-color-display.js +1 -1
  93. package/dist/cdn/color-display/snice-color-display.min.js +1 -1
  94. package/dist/cdn/color-picker/snice-color-picker.js +1 -1
  95. package/dist/cdn/color-picker/snice-color-picker.min.js +1 -1
  96. package/dist/cdn/command-palette/snice-command-palette.js +1 -1
  97. package/dist/cdn/command-palette/snice-command-palette.min.js +1 -1
  98. package/dist/cdn/date-picker/snice-date-picker.js +1 -1
  99. package/dist/cdn/date-picker/snice-date-picker.min.js +1 -1
  100. package/dist/cdn/divider/snice-divider.js +1 -1
  101. package/dist/cdn/divider/snice-divider.min.js +1 -1
  102. package/dist/cdn/doc/snice-doc.js +1 -1
  103. package/dist/cdn/doc/snice-doc.min.js +1 -1
  104. package/dist/cdn/draw/snice-draw.js +1 -1
  105. package/dist/cdn/draw/snice-draw.min.js +1 -1
  106. package/dist/cdn/drawer/snice-drawer.js +1 -1
  107. package/dist/cdn/drawer/snice-drawer.min.js +1 -1
  108. package/dist/cdn/empty-state/snice-empty-state.js +1 -1
  109. package/dist/cdn/empty-state/snice-empty-state.min.js +1 -1
  110. package/dist/cdn/file-gallery/snice-file-gallery.js +1 -1
  111. package/dist/cdn/file-gallery/snice-file-gallery.min.js +1 -1
  112. package/dist/cdn/file-upload/snice-file-upload.js +1 -1
  113. package/dist/cdn/file-upload/snice-file-upload.min.js +1 -1
  114. package/dist/cdn/funnel/README.md +27 -0
  115. package/dist/cdn/funnel/snice-funnel.js +424 -0
  116. package/dist/cdn/funnel/snice-funnel.js.map +1 -0
  117. package/dist/cdn/funnel/snice-funnel.min.js +20 -0
  118. package/dist/cdn/funnel/snice-funnel.min.js.map +1 -0
  119. package/dist/cdn/gauge/snice-gauge.js +1 -1
  120. package/dist/cdn/gauge/snice-gauge.min.js +1 -1
  121. package/dist/cdn/heatmap/snice-heatmap.js +1 -1
  122. package/dist/cdn/heatmap/snice-heatmap.min.js +1 -1
  123. package/dist/cdn/image/snice-image.js +1 -1
  124. package/dist/cdn/image/snice-image.min.js +1 -1
  125. package/dist/cdn/input/snice-input.js +1 -1
  126. package/dist/cdn/input/snice-input.min.js +1 -1
  127. package/dist/cdn/kanban/snice-kanban.js +1 -1
  128. package/dist/cdn/kanban/snice-kanban.min.js +1 -1
  129. package/dist/cdn/kpi/snice-kpi.js +1 -1
  130. package/dist/cdn/kpi/snice-kpi.min.js +1 -1
  131. package/dist/cdn/layout/README.md +2 -2
  132. package/dist/cdn/layout/snice-layout.js +23 -6
  133. package/dist/cdn/layout/snice-layout.js.map +1 -1
  134. package/dist/cdn/layout/snice-layout.min.js +2 -2
  135. package/dist/cdn/layout/snice-layout.min.js.map +1 -1
  136. package/dist/cdn/link/snice-link.js +1 -1
  137. package/dist/cdn/link/snice-link.min.js +1 -1
  138. package/dist/cdn/link-preview/snice-link-preview.js +1 -1
  139. package/dist/cdn/link-preview/snice-link-preview.min.js +1 -1
  140. package/dist/cdn/list/README.md +6 -2
  141. package/dist/cdn/list/snice-list.js +87 -10
  142. package/dist/cdn/list/snice-list.js.map +1 -1
  143. package/dist/cdn/list/snice-list.min.js +20 -6
  144. package/dist/cdn/list/snice-list.min.js.map +1 -1
  145. package/dist/cdn/location/snice-location.js +1 -1
  146. package/dist/cdn/location/snice-location.min.js +1 -1
  147. package/dist/cdn/login/snice-login.js +1 -1
  148. package/dist/cdn/login/snice-login.min.js +1 -1
  149. package/dist/cdn/masonry/snice-masonry.js +1 -1
  150. package/dist/cdn/masonry/snice-masonry.min.js +1 -1
  151. package/dist/cdn/menu/snice-menu.js +1 -1
  152. package/dist/cdn/menu/snice-menu.min.js +1 -1
  153. package/dist/cdn/modal/snice-modal.js +1 -1
  154. package/dist/cdn/modal/snice-modal.min.js +1 -1
  155. package/dist/cdn/music-player/snice-music-player.js +1 -1
  156. package/dist/cdn/music-player/snice-music-player.min.js +1 -1
  157. package/dist/cdn/nav/README.md +2 -2
  158. package/dist/cdn/nav/snice-nav.js +23 -6
  159. package/dist/cdn/nav/snice-nav.js.map +1 -1
  160. package/dist/cdn/nav/snice-nav.min.js +2 -2
  161. package/dist/cdn/nav/snice-nav.min.js.map +1 -1
  162. package/dist/cdn/network-graph/README.md +27 -0
  163. package/dist/cdn/network-graph/snice-network-graph.js +788 -0
  164. package/dist/cdn/network-graph/snice-network-graph.js.map +1 -0
  165. package/dist/cdn/network-graph/snice-network-graph.min.js +13 -0
  166. package/dist/cdn/network-graph/snice-network-graph.min.js.map +1 -0
  167. package/dist/cdn/pagination/README.md +2 -2
  168. package/dist/cdn/pagination/snice-pagination.js +13 -13
  169. package/dist/cdn/pagination/snice-pagination.js.map +1 -1
  170. package/dist/cdn/pagination/snice-pagination.min.js +14 -14
  171. package/dist/cdn/pagination/snice-pagination.min.js.map +1 -1
  172. package/dist/cdn/paint/snice-paint.js +1 -1
  173. package/dist/cdn/paint/snice-paint.min.js +1 -1
  174. package/dist/cdn/progress/snice-progress.js +1 -1
  175. package/dist/cdn/progress/snice-progress.min.js +1 -1
  176. package/dist/cdn/qr-code/snice-qr-code.js +1 -1
  177. package/dist/cdn/qr-code/snice-qr-code.min.js +1 -1
  178. package/dist/cdn/qr-reader/snice-qr-reader.js +1 -1
  179. package/dist/cdn/qr-reader/snice-qr-reader.min.js +1 -1
  180. package/dist/cdn/radio/snice-radio.js +1 -1
  181. package/dist/cdn/radio/snice-radio.min.js +1 -1
  182. package/dist/cdn/runtime/snice-runtime.esm.js +3 -3
  183. package/dist/cdn/runtime/snice-runtime.esm.js.map +1 -1
  184. package/dist/cdn/runtime/snice-runtime.esm.min.js +3 -3
  185. package/dist/cdn/runtime/snice-runtime.esm.min.js.map +1 -1
  186. package/dist/cdn/runtime/snice-runtime.js +3 -3
  187. package/dist/cdn/runtime/snice-runtime.js.map +1 -1
  188. package/dist/cdn/runtime/snice-runtime.min.js +3 -3
  189. package/dist/cdn/runtime/snice-runtime.min.js.map +1 -1
  190. package/dist/cdn/sankey/README.md +27 -0
  191. package/dist/cdn/sankey/snice-sankey.js +679 -0
  192. package/dist/cdn/sankey/snice-sankey.js.map +1 -0
  193. package/dist/cdn/sankey/snice-sankey.min.js +21 -0
  194. package/dist/cdn/sankey/snice-sankey.min.js.map +1 -0
  195. package/dist/cdn/select/snice-select.js +1 -1
  196. package/dist/cdn/select/snice-select.min.js +1 -1
  197. package/dist/cdn/skeleton/snice-skeleton.js +1 -1
  198. package/dist/cdn/skeleton/snice-skeleton.min.js +1 -1
  199. package/dist/cdn/slider/snice-slider.js +1 -1
  200. package/dist/cdn/slider/snice-slider.min.js +1 -1
  201. package/dist/cdn/sparkline/snice-sparkline.js +1 -1
  202. package/dist/cdn/sparkline/snice-sparkline.min.js +1 -1
  203. package/dist/cdn/spinner/snice-spinner.js +1 -1
  204. package/dist/cdn/spinner/snice-spinner.min.js +1 -1
  205. package/dist/cdn/split-pane/snice-split-pane.js +1 -1
  206. package/dist/cdn/split-pane/snice-split-pane.min.js +1 -1
  207. package/dist/cdn/stepper/README.md +6 -2
  208. package/dist/cdn/stepper/snice-stepper.js +77 -10
  209. package/dist/cdn/stepper/snice-stepper.js.map +1 -1
  210. package/dist/cdn/stepper/snice-stepper.min.js +13 -9
  211. package/dist/cdn/stepper/snice-stepper.min.js.map +1 -1
  212. package/dist/cdn/switch/snice-switch.js +1 -1
  213. package/dist/cdn/switch/snice-switch.min.js +1 -1
  214. package/dist/cdn/table/snice-table.js +1 -1
  215. package/dist/cdn/table/snice-table.min.js +1 -1
  216. package/dist/cdn/tabs/snice-tabs.js +1 -1
  217. package/dist/cdn/tabs/snice-tabs.min.js +1 -1
  218. package/dist/cdn/terminal/snice-terminal.js +1 -1
  219. package/dist/cdn/terminal/snice-terminal.min.js +1 -1
  220. package/dist/cdn/textarea/snice-textarea.js +1 -1
  221. package/dist/cdn/textarea/snice-textarea.min.js +1 -1
  222. package/dist/cdn/time-range-picker/README.md +27 -0
  223. package/dist/cdn/time-range-picker/snice-time-range-picker.js +635 -0
  224. package/dist/cdn/time-range-picker/snice-time-range-picker.js.map +1 -0
  225. package/dist/cdn/time-range-picker/snice-time-range-picker.min.js +34 -0
  226. package/dist/cdn/time-range-picker/snice-time-range-picker.min.js.map +1 -0
  227. package/dist/cdn/timeline/snice-timeline.js +1 -1
  228. package/dist/cdn/timeline/snice-timeline.min.js +1 -1
  229. package/dist/cdn/timer/snice-timer.js +1 -1
  230. package/dist/cdn/timer/snice-timer.min.js +1 -1
  231. package/dist/cdn/toast/snice-toast.js +1 -1
  232. package/dist/cdn/toast/snice-toast.min.js +1 -1
  233. package/dist/cdn/tooltip/snice-tooltip.js +1 -1
  234. package/dist/cdn/tooltip/snice-tooltip.min.js +1 -1
  235. package/dist/cdn/tree/README.md +5 -1
  236. package/dist/cdn/tree/snice-tree.js +4 -8
  237. package/dist/cdn/tree/snice-tree.js.map +1 -1
  238. package/dist/cdn/tree/snice-tree.min.js +5 -5
  239. package/dist/cdn/tree/snice-tree.min.js.map +1 -1
  240. package/dist/cdn/treemap/README.md +27 -0
  241. package/dist/cdn/treemap/snice-treemap.js +522 -0
  242. package/dist/cdn/treemap/snice-treemap.js.map +1 -0
  243. package/dist/cdn/treemap/snice-treemap.min.js +14 -0
  244. package/dist/cdn/treemap/snice-treemap.min.js.map +1 -0
  245. package/dist/cdn/virtual-scroller/README.md +2 -2
  246. package/dist/cdn/virtual-scroller/snice-virtual-scroller.js +47 -16
  247. package/dist/cdn/virtual-scroller/snice-virtual-scroller.js.map +1 -1
  248. package/dist/cdn/virtual-scroller/snice-virtual-scroller.min.js +9 -9
  249. package/dist/cdn/virtual-scroller/snice-virtual-scroller.min.js.map +1 -1
  250. package/dist/components/breadcrumbs/snice-breadcrumbs.js +1 -1
  251. package/dist/components/breadcrumbs/snice-breadcrumbs.js.map +1 -1
  252. package/dist/components/camera-annotate/snice-camera-annotate.d.ts +68 -0
  253. package/dist/components/camera-annotate/snice-camera-annotate.js +663 -0
  254. package/dist/components/camera-annotate/snice-camera-annotate.js.map +1 -0
  255. package/dist/components/camera-annotate/snice-camera-annotate.types.d.ts +50 -0
  256. package/dist/components/candlestick/snice-candlestick.d.ts +78 -0
  257. package/dist/components/candlestick/snice-candlestick.js +650 -0
  258. package/dist/components/candlestick/snice-candlestick.js.map +1 -0
  259. package/dist/components/candlestick/snice-candlestick.types.d.ts +40 -0
  260. package/dist/components/funnel/snice-funnel.d.ts +37 -0
  261. package/dist/components/funnel/snice-funnel.js +357 -0
  262. package/dist/components/funnel/snice-funnel.js.map +1 -0
  263. package/dist/components/funnel/snice-funnel.types.d.ts +28 -0
  264. package/dist/components/list/snice-list-item.d.ts +2 -0
  265. package/dist/components/list/snice-list-item.js +20 -2
  266. package/dist/components/list/snice-list-item.js.map +1 -1
  267. package/dist/components/nav/snice-nav.js +22 -5
  268. package/dist/components/nav/snice-nav.js.map +1 -1
  269. package/dist/components/network-graph/snice-network-graph.d.ts +80 -0
  270. package/dist/components/network-graph/snice-network-graph.js +721 -0
  271. package/dist/components/network-graph/snice-network-graph.js.map +1 -0
  272. package/dist/components/network-graph/snice-network-graph.types.d.ts +49 -0
  273. package/dist/components/pagination/snice-pagination.js +12 -12
  274. package/dist/components/sankey/snice-sankey.d.ts +46 -0
  275. package/dist/components/sankey/snice-sankey.js +612 -0
  276. package/dist/components/sankey/snice-sankey.js.map +1 -0
  277. package/dist/components/sankey/snice-sankey.types.d.ts +59 -0
  278. package/dist/components/stepper/snice-stepper.js +9 -3
  279. package/dist/components/stepper/snice-stepper.js.map +1 -1
  280. package/dist/components/time-range-picker/snice-time-range-picker.d.ts +67 -0
  281. package/dist/components/time-range-picker/snice-time-range-picker.js +568 -0
  282. package/dist/components/time-range-picker/snice-time-range-picker.js.map +1 -0
  283. package/dist/components/time-range-picker/snice-time-range-picker.types.d.ts +39 -0
  284. package/dist/components/treemap/snice-treemap.d.ts +49 -0
  285. package/dist/components/treemap/snice-treemap.js +455 -0
  286. package/dist/components/treemap/snice-treemap.js.map +1 -0
  287. package/dist/components/treemap/snice-treemap.types.d.ts +42 -0
  288. package/dist/components/virtual-scroller/snice-virtual-scroller.d.ts +5 -0
  289. package/dist/components/virtual-scroller/snice-virtual-scroller.js +47 -16
  290. package/dist/components/virtual-scroller/snice-virtual-scroller.js.map +1 -1
  291. package/dist/index.cjs +1 -1
  292. package/dist/index.cjs.map +1 -1
  293. package/dist/index.esm.js +1 -1
  294. package/dist/index.esm.js.map +1 -1
  295. package/dist/index.iife.js +1 -1
  296. package/dist/index.iife.js.map +1 -1
  297. package/dist/symbols.cjs +1 -1
  298. package/dist/symbols.esm.js +1 -1
  299. package/dist/transitions.cjs +1 -1
  300. package/dist/transitions.esm.js +1 -1
  301. package/docs/ai/components/camera-annotate.md +82 -0
  302. package/docs/ai/components/candlestick.md +79 -0
  303. package/docs/ai/components/funnel.md +86 -0
  304. package/docs/ai/components/network-graph.md +87 -0
  305. package/docs/ai/components/sankey.md +63 -0
  306. package/docs/ai/components/time-range-picker.md +78 -0
  307. package/docs/ai/components/treemap.md +78 -0
  308. package/docs/components/camera-annotate.md +186 -0
  309. package/docs/components/candlestick.md +196 -0
  310. package/docs/components/funnel.md +191 -0
  311. package/docs/components/network-graph.md +215 -0
  312. package/docs/components/sankey.md +201 -0
  313. package/docs/components/time-range-picker.md +213 -0
  314. package/docs/components/treemap.md +198 -0
  315. package/package.json +1 -1
@@ -0,0 +1,663 @@
1
+ import { __runInitializers, __esDecorate } from 'tslib';
2
+ import { element, property, query, styles, ready, dispose, render, watch, dispatch, css, html } from 'snice';
3
+
4
+ var componentStyles = ":host{display:block;width:100%;font-family:var(--snice-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);contain:layout style paint;--ca-bg:var(--snice-color-background, rgb(255 255 255));--ca-bg-element:var(--snice-color-background-element, rgb(252 251 249));--ca-text:var(--snice-color-text, rgb(23 23 23));--ca-text-secondary:var(--snice-color-text-secondary, rgb(82 82 82));--ca-text-tertiary:var(--snice-color-text-tertiary, rgb(115 115 115));--ca-border:var(--snice-color-border, rgb(226 226 226));--ca-primary:var(--snice-color-primary, rgb(37 99 235));--ca-danger:var(--snice-color-danger, rgb(220 38 38))}.ca-layout{display:flex;gap:var(--snice-spacing-md,1rem);width:100%}.ca-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--snice-spacing-sm,.75rem)}.ca-canvas-area{position:relative;width:100%;background:rgb(0 0 0);border-radius:var(--snice-border-radius-lg,.5rem);overflow:hidden}.ca-canvas-area video{display:block;width:100%;height:auto}.ca-canvas-area video.mirror{transform:scaleX(-1)}.ca-canvas-area canvas{display:block;width:100%;height:auto;cursor:crosshair}.ca-canvas-area canvas.hidden,.ca-canvas-area video.hidden{display:none}.ca-toolbar{display:flex;align-items:center;gap:var(--snice-spacing-xs,.5rem);flex-wrap:wrap}.ca-btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--snice-spacing-2xs,.25rem);padding:var(--snice-spacing-xs,.5rem) var(--snice-spacing-sm,.75rem);border:1px solid var(--ca-border);border-radius:var(--snice-border-radius-md,.25rem);background:var(--ca-bg);color:var(--ca-text);font-size:var(--snice-font-size-sm, .875rem);font-family:inherit;cursor:pointer;transition:all var(--snice-transition-fast, 150ms) ease;white-space:nowrap}.ca-btn:hover{background:var(--ca-bg-element)}.ca-btn:active{transform:scale(.97)}.ca-btn.primary{background:var(--ca-primary);color:var(--snice-color-text-inverse,rgb(250 250 250));border-color:var(--ca-primary)}.ca-btn.primary:hover{opacity:.9}.ca-btn.danger{color:var(--ca-danger);border-color:var(--ca-danger)}.ca-btn.danger:hover{background:var(--ca-danger);color:var(--snice-color-text-inverse,rgb(250 250 250))}.ca-btn.small{padding:var(--snice-spacing-3xs,.125rem) var(--snice-spacing-2xs,.25rem);font-size:var(--snice-font-size-xs, .75rem)}.ca-btn.active{background:var(--ca-primary);color:var(--snice-color-text-inverse,rgb(250 250 250));border-color:var(--ca-primary)}.ca-btn svg{width:1rem;height:1rem;flex-shrink:0}.ca-separator{width:1px;height:1.5rem;background:var(--ca-border);margin:0 var(--snice-spacing-3xs,.125rem)}.ca-toolbar-group{display:flex;align-items:center;gap:var(--snice-spacing-2xs,.25rem)}.ca-stroke-width{width:3.5rem;padding:var(--snice-spacing-2xs,.25rem);border:1px solid var(--ca-border);border-radius:var(--snice-border-radius-md,.25rem);font-size:var(--snice-font-size-sm, .875rem);font-family:inherit;background:var(--ca-bg);color:var(--ca-text);text-align:center}.ca-sidebar{width:16rem;flex-shrink:0;display:flex;flex-direction:column;gap:var(--snice-spacing-xs,.5rem);border:1px solid var(--ca-border);border-radius:var(--snice-border-radius-lg,.5rem);padding:var(--snice-spacing-sm,.75rem);background:var(--ca-bg);max-height:32rem;overflow-y:auto}.ca-sidebar.hidden{display:none}.ca-sidebar-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:var(--snice-spacing-xs,.5rem);border-bottom:1px solid var(--ca-border)}.ca-sidebar-title{font-size:var(--snice-font-size-sm, .875rem);font-weight:var(--snice-font-weight-semibold,600);color:var(--ca-text)}.ca-annotation-list{display:flex;flex-direction:column;gap:var(--snice-spacing-2xs,.25rem)}.ca-annotation-item{display:flex;align-items:center;gap:var(--snice-spacing-xs,.5rem);padding:var(--snice-spacing-2xs,.25rem) var(--snice-spacing-xs,.5rem);border-radius:var(--snice-border-radius-md,.25rem);border:1px solid transparent;cursor:pointer;transition:all var(--snice-transition-fast, 150ms) ease}.ca-annotation-item:hover{background:var(--ca-bg-element);border-color:var(--ca-border)}.ca-annotation-item.highlighted{background:var(--ca-bg-element);border-color:var(--ca-primary)}.ca-annotation-color{width:.75rem;height:.75rem;border-radius:50%;flex-shrink:0;border:1px solid var(--ca-border)}.ca-annotation-label{flex:1;min-width:0}.ca-annotation-label input{width:100%;border:none;background:0 0;font-size:var(--snice-font-size-sm, .875rem);font-family:inherit;color:var(--ca-text);padding:var(--snice-spacing-3xs,.125rem) 0;outline:0}.ca-annotation-label input:focus{border-bottom:1px solid var(--ca-primary)}.ca-annotation-label input::placeholder{color:var(--ca-text-tertiary)}.ca-annotation-actions{display:flex;align-items:center;gap:var(--snice-spacing-3xs,.125rem)}.ca-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border:none;background:0 0;color:var(--ca-text-tertiary);cursor:pointer;border-radius:var(--snice-border-radius-md,.25rem);padding:0;transition:all var(--snice-transition-fast, 150ms) ease}.ca-icon-btn:hover{background:var(--ca-bg-element);color:var(--ca-text)}.ca-icon-btn svg{width:.875rem;height:.875rem}.ca-icon-btn.hidden-state{opacity:.4}.ca-color-section{display:flex;flex-direction:column;gap:var(--snice-spacing-2xs,.25rem)}.ca-color-palette{display:flex;flex-wrap:wrap;gap:var(--snice-spacing-3xs,.125rem);justify-content:center}.ca-color-swatch{width:1.25rem;height:1.25rem;border-radius:50%;border:2px solid transparent;cursor:pointer;transition:all var(--snice-transition-fast, 150ms) ease}.ca-color-swatch:hover{transform:scale(1.2)}.ca-color-swatch.active{border-color:var(--ca-text);box-shadow:0 0 0 2px var(--ca-bg),0 0 0 3px var(--ca-text)}.ca-auto-rotate{display:flex;align-items:center;gap:var(--snice-spacing-2xs,.25rem);font-size:var(--snice-font-size-xs, .75rem);color:var(--ca-text-secondary);cursor:pointer}.ca-auto-rotate input{margin:0;cursor:pointer}.ca-empty-state{text-align:center;padding:var(--snice-spacing-lg,1.5rem) var(--snice-spacing-sm,.75rem);color:var(--ca-text-tertiary);font-size:var(--snice-font-size-sm, .875rem)}";
5
+
6
+ const PRESET_COLORS = [
7
+ '#f87171', '#fb923c', '#fbbf24', '#a3e635',
8
+ '#34d399', '#22d3ee', '#60a5fa', '#a78bfa',
9
+ '#f472b6', '#fb7185', '#e879f9', '#818cf8'
10
+ ];
11
+ let SniceCameraAnnotate = (() => {
12
+ let _classDecorators = [element('snice-camera-annotate')];
13
+ let _classDescriptor;
14
+ let _classExtraInitializers = [];
15
+ let _classThis;
16
+ let _classSuper = HTMLElement;
17
+ let _instanceExtraInitializers = [];
18
+ let _mode_decorators;
19
+ let _mode_initializers = [];
20
+ let _mode_extraInitializers = [];
21
+ let _autoRotateColors_decorators;
22
+ let _autoRotateColors_initializers = [];
23
+ let _autoRotateColors_extraInitializers = [];
24
+ let _showLabelsPanel_decorators;
25
+ let _showLabelsPanel_initializers = [];
26
+ let _showLabelsPanel_extraInitializers = [];
27
+ let _videoEl_decorators;
28
+ let _videoEl_initializers = [];
29
+ let _videoEl_extraInitializers = [];
30
+ let _drawCanvas_decorators;
31
+ let _drawCanvas_initializers = [];
32
+ let _drawCanvas_extraInitializers = [];
33
+ let _componentStyles_decorators;
34
+ let _init_decorators;
35
+ let _cleanup_decorators;
36
+ let _template_decorators;
37
+ let _handleModeChange_decorators;
38
+ let _emitCapture_decorators;
39
+ let _emitAnnotate_decorators;
40
+ let _emitAnnotationChange_decorators;
41
+ (class extends _classSuper {
42
+ static { _classThis = this; }
43
+ constructor() {
44
+ super(...arguments);
45
+ this.mode = (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _mode_initializers, 'camera'));
46
+ this.autoRotateColors = (__runInitializers(this, _mode_extraInitializers), __runInitializers(this, _autoRotateColors_initializers, true));
47
+ this.showLabelsPanel = (__runInitializers(this, _autoRotateColors_extraInitializers), __runInitializers(this, _showLabelsPanel_initializers, true));
48
+ this.videoEl = (__runInitializers(this, _showLabelsPanel_extraInitializers), __runInitializers(this, _videoEl_initializers, void 0));
49
+ this.drawCanvas = (__runInitializers(this, _videoEl_extraInitializers), __runInitializers(this, _drawCanvas_initializers, void 0));
50
+ this.stream = (__runInitializers(this, _drawCanvas_extraInitializers), null);
51
+ this.ctx = null;
52
+ this.capturedImageData = '';
53
+ this.capturedImage = null;
54
+ this.imageWidth = 0;
55
+ this.imageHeight = 0;
56
+ // Drawing state
57
+ this.isDrawing = false;
58
+ this.currentPoints = [];
59
+ this.strokes = [];
60
+ this.annotations = [];
61
+ this.activeColor = PRESET_COLORS[0];
62
+ this.colorIndex = 0;
63
+ this.strokeWidth = 3;
64
+ // Highlight state
65
+ this.highlightedAnnotationId = null;
66
+ }
67
+ static {
68
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
69
+ _mode_decorators = [property()];
70
+ _autoRotateColors_decorators = [property({ type: Boolean, attribute: 'auto-rotate-colors' })];
71
+ _showLabelsPanel_decorators = [property({ type: Boolean, attribute: 'show-labels-panel' })];
72
+ _videoEl_decorators = [query('.ca-video')];
73
+ _drawCanvas_decorators = [query('.ca-draw-canvas')];
74
+ _componentStyles_decorators = [styles()];
75
+ _init_decorators = [ready()];
76
+ _cleanup_decorators = [dispose()];
77
+ _template_decorators = [render()];
78
+ _handleModeChange_decorators = [watch('mode')];
79
+ _emitCapture_decorators = [dispatch('capture', { bubbles: true, composed: true })];
80
+ _emitAnnotate_decorators = [dispatch('annotate', { bubbles: true, composed: true })];
81
+ _emitAnnotationChange_decorators = [dispatch('annotation-change', { bubbles: true, composed: true })];
82
+ __esDecorate(this, null, _componentStyles_decorators, { kind: "method", name: "componentStyles", static: false, private: false, access: { has: obj => "componentStyles" in obj, get: obj => obj.componentStyles }, metadata: _metadata }, null, _instanceExtraInitializers);
83
+ __esDecorate(this, null, _init_decorators, { kind: "method", name: "init", static: false, private: false, access: { has: obj => "init" in obj, get: obj => obj.init }, metadata: _metadata }, null, _instanceExtraInitializers);
84
+ __esDecorate(this, null, _cleanup_decorators, { kind: "method", name: "cleanup", static: false, private: false, access: { has: obj => "cleanup" in obj, get: obj => obj.cleanup }, metadata: _metadata }, null, _instanceExtraInitializers);
85
+ __esDecorate(this, null, _template_decorators, { kind: "method", name: "template", static: false, private: false, access: { has: obj => "template" in obj, get: obj => obj.template }, metadata: _metadata }, null, _instanceExtraInitializers);
86
+ __esDecorate(this, null, _handleModeChange_decorators, { kind: "method", name: "handleModeChange", static: false, private: false, access: { has: obj => "handleModeChange" in obj, get: obj => obj.handleModeChange }, metadata: _metadata }, null, _instanceExtraInitializers);
87
+ __esDecorate(this, null, _emitCapture_decorators, { kind: "method", name: "emitCapture", static: false, private: false, access: { has: obj => "emitCapture" in obj, get: obj => obj.emitCapture }, metadata: _metadata }, null, _instanceExtraInitializers);
88
+ __esDecorate(this, null, _emitAnnotate_decorators, { kind: "method", name: "emitAnnotate", static: false, private: false, access: { has: obj => "emitAnnotate" in obj, get: obj => obj.emitAnnotate }, metadata: _metadata }, null, _instanceExtraInitializers);
89
+ __esDecorate(this, null, _emitAnnotationChange_decorators, { kind: "method", name: "emitAnnotationChange", static: false, private: false, access: { has: obj => "emitAnnotationChange" in obj, get: obj => obj.emitAnnotationChange }, metadata: _metadata }, null, _instanceExtraInitializers);
90
+ __esDecorate(null, null, _mode_decorators, { kind: "field", name: "mode", static: false, private: false, access: { has: obj => "mode" in obj, get: obj => obj.mode, set: (obj, value) => { obj.mode = value; } }, metadata: _metadata }, _mode_initializers, _mode_extraInitializers);
91
+ __esDecorate(null, null, _autoRotateColors_decorators, { kind: "field", name: "autoRotateColors", static: false, private: false, access: { has: obj => "autoRotateColors" in obj, get: obj => obj.autoRotateColors, set: (obj, value) => { obj.autoRotateColors = value; } }, metadata: _metadata }, _autoRotateColors_initializers, _autoRotateColors_extraInitializers);
92
+ __esDecorate(null, null, _showLabelsPanel_decorators, { kind: "field", name: "showLabelsPanel", static: false, private: false, access: { has: obj => "showLabelsPanel" in obj, get: obj => obj.showLabelsPanel, set: (obj, value) => { obj.showLabelsPanel = value; } }, metadata: _metadata }, _showLabelsPanel_initializers, _showLabelsPanel_extraInitializers);
93
+ __esDecorate(null, null, _videoEl_decorators, { kind: "field", name: "videoEl", static: false, private: false, access: { has: obj => "videoEl" in obj, get: obj => obj.videoEl, set: (obj, value) => { obj.videoEl = value; } }, metadata: _metadata }, _videoEl_initializers, _videoEl_extraInitializers);
94
+ __esDecorate(null, null, _drawCanvas_decorators, { kind: "field", name: "drawCanvas", static: false, private: false, access: { has: obj => "drawCanvas" in obj, get: obj => obj.drawCanvas, set: (obj, value) => { obj.drawCanvas = value; } }, metadata: _metadata }, _drawCanvas_initializers, _drawCanvas_extraInitializers);
95
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
96
+ _classThis = _classDescriptor.value;
97
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
98
+ __runInitializers(_classThis, _classExtraInitializers);
99
+ }
100
+ componentStyles() {
101
+ return css /*css*/ `${componentStyles}`;
102
+ }
103
+ async init() {
104
+ if (this.mode === 'camera') {
105
+ await this.startCamera();
106
+ }
107
+ }
108
+ cleanup() {
109
+ this.stopCamera();
110
+ }
111
+ template() {
112
+ return html `
113
+ <div class="ca-layout">
114
+ <div class="ca-main">
115
+ <div class="ca-canvas-area">
116
+ <video
117
+ class="ca-video mirror ${this.mode === 'annotate' ? 'hidden' : ''}"
118
+ autoplay
119
+ playsinline
120
+ muted>
121
+ </video>
122
+ <canvas
123
+ class="ca-draw-canvas ${this.mode === 'camera' ? 'hidden' : ''}"
124
+ @pointerdown=${this.handlePointerDown}
125
+ @pointermove=${this.handlePointerMove}
126
+ @pointerup=${this.handlePointerUp}>
127
+ </canvas>
128
+ </div>
129
+ ${this.renderToolbar()}
130
+ </div>
131
+ <div class="ca-sidebar ${this.showLabelsPanel ? '' : 'hidden'}">
132
+ ${this.renderSidebar()}
133
+ </div>
134
+ </div>
135
+ `;
136
+ }
137
+ renderToolbar() {
138
+ const inCamera = this.mode === 'camera';
139
+ return html `
140
+ <div class="ca-toolbar">
141
+ <button class="ca-btn primary" @click=${inCamera ? this.capture : this.retake}>
142
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
143
+ ${inCamera
144
+ ? html `<path d="M9 2L7 5H4C2.9 5 2 5.9 2 7V19C2 20.1 2.9 21 4 21H20C21.1 21 22 20.1 22 19V7C22 5.9 21.1 5 20 5H17L15 2H9Z"/><circle cx="12" cy="13" r="3"/>`
145
+ : html `<path d="M1 4v6h6"/><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/>`}
146
+ </svg>
147
+ ${inCamera ? 'Capture' : 'Retake'}
148
+ </button>
149
+
150
+ <if value=${!inCamera}>
151
+ <div class="ca-separator"></div>
152
+ <div class="ca-toolbar-group">
153
+ <button class="ca-btn small" @click=${this.undoStroke} title="Undo">
154
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
155
+ <path d="M1 4v6h6"/><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/>
156
+ </svg>
157
+ </button>
158
+ <button class="ca-btn small danger" @click=${this.clearAnnotations} title="Clear all">
159
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
160
+ <path d="M3 6h18"/><path d="M8 6V4h8v2"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/>
161
+ </svg>
162
+ </button>
163
+ </div>
164
+ <div class="ca-separator"></div>
165
+ <label class="ca-toolbar-group" style="font-size:0.75rem;color:var(--ca-text-secondary);">
166
+ Width:
167
+ <input
168
+ type="number"
169
+ class="ca-stroke-width"
170
+ min="1"
171
+ max="20"
172
+ .value="${String(this.strokeWidth)}"
173
+ @change=${this.handleStrokeWidthChange}
174
+ />
175
+ </label>
176
+ <div class="ca-separator"></div>
177
+ <button class="ca-btn small" @click=${this.handleExportImage} title="Export image">
178
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
179
+ <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/>
180
+ </svg>
181
+ Export
182
+ </button>
183
+ </if>
184
+ </div>
185
+ `;
186
+ }
187
+ renderSidebar() {
188
+ return html `
189
+ <div class="ca-sidebar-header">
190
+ <span class="ca-sidebar-title">Annotations</span>
191
+ <div class="ca-toolbar-group">
192
+ <button class="ca-icon-btn" @click=${this.toggleAllAnnotations} title="Toggle all">
193
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
194
+ <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>
195
+ </svg>
196
+ </button>
197
+ </div>
198
+ </div>
199
+
200
+ <div class="ca-color-section">
201
+ <div class="ca-color-palette">
202
+ ${PRESET_COLORS.map(color => html `
203
+ <div
204
+ class="ca-color-swatch ${this.activeColor === color ? 'active' : ''}"
205
+ style="background-color: ${color}"
206
+ @click=${() => this.selectColor(color)}
207
+ title="${color}">
208
+ </div>
209
+ `)}
210
+ </div>
211
+ <label class="ca-auto-rotate">
212
+ <input
213
+ type="checkbox"
214
+ ?checked=${this.autoRotateColors}
215
+ @change=${this.handleAutoRotateChange}
216
+ />
217
+ Auto Rotate Colors
218
+ </label>
219
+ </div>
220
+
221
+ <div class="ca-annotation-list">
222
+ ${this.annotations.length === 0
223
+ ? html `<div class="ca-empty-state">Draw on the image to create annotations</div>`
224
+ : this.annotations.map(ann => this.renderAnnotationItem(ann))}
225
+ </div>
226
+ `;
227
+ }
228
+ renderAnnotationItem(ann) {
229
+ const isHighlighted = this.highlightedAnnotationId === ann.id;
230
+ return html `
231
+ <div
232
+ class="ca-annotation-item ${isHighlighted ? 'highlighted' : ''}"
233
+ @mouseenter=${() => this.highlightAnnotation(ann.id)}
234
+ @mouseleave=${() => this.unhighlightAnnotation()}>
235
+ <div class="ca-annotation-color" style="background-color: ${ann.color}"></div>
236
+ <div class="ca-annotation-label">
237
+ <input
238
+ type="text"
239
+ placeholder="Add label..."
240
+ .value="${ann.label}"
241
+ @input=${(e) => this.updateAnnotationLabel(ann.id, e.target.value)}
242
+ />
243
+ </div>
244
+ <div class="ca-annotation-actions">
245
+ <button
246
+ class="ca-icon-btn ${ann.visible ? '' : 'hidden-state'}"
247
+ @click=${() => this.toggleAnnotationVisibility(ann.id)}
248
+ title="${ann.visible ? 'Hide' : 'Show'}">
249
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
250
+ ${ann.visible
251
+ ? html `<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>`
252
+ : html `<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/>`}
253
+ </svg>
254
+ </button>
255
+ <button
256
+ class="ca-icon-btn"
257
+ @click=${() => this.deleteAnnotation(ann.id)}
258
+ title="Delete">
259
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
260
+ <line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
261
+ </svg>
262
+ </button>
263
+ </div>
264
+ </div>
265
+ `;
266
+ }
267
+ // --- Camera ---
268
+ async startCamera() {
269
+ try {
270
+ this.stream = await navigator.mediaDevices.getUserMedia({
271
+ audio: false,
272
+ video: { width: { ideal: 1280 }, height: { ideal: 720 }, facingMode: 'user' }
273
+ });
274
+ if (this.videoEl) {
275
+ this.videoEl.srcObject = this.stream;
276
+ await this.videoEl.play();
277
+ }
278
+ }
279
+ catch (err) {
280
+ console.error('Camera access error:', err);
281
+ }
282
+ }
283
+ stopCamera() {
284
+ if (this.stream) {
285
+ this.stream.getTracks().forEach(t => t.stop());
286
+ this.stream = null;
287
+ }
288
+ }
289
+ // --- Capture ---
290
+ async capture() {
291
+ if (!this.videoEl)
292
+ return;
293
+ const tempCanvas = document.createElement('canvas');
294
+ tempCanvas.width = this.videoEl.videoWidth || 640;
295
+ tempCanvas.height = this.videoEl.videoHeight || 480;
296
+ const tempCtx = tempCanvas.getContext('2d');
297
+ if (!tempCtx)
298
+ return;
299
+ // Mirror for user-facing camera
300
+ tempCtx.scale(-1, 1);
301
+ tempCtx.drawImage(this.videoEl, -tempCanvas.width, 0, tempCanvas.width, tempCanvas.height);
302
+ this.capturedImageData = tempCanvas.toDataURL('image/jpeg', 0.92);
303
+ this.imageWidth = tempCanvas.width;
304
+ this.imageHeight = tempCanvas.height;
305
+ // Load as image for drawing
306
+ this.capturedImage = new Image();
307
+ this.capturedImage.src = this.capturedImageData;
308
+ await new Promise(resolve => {
309
+ this.capturedImage.onload = () => resolve();
310
+ });
311
+ this.stopCamera();
312
+ this.mode = 'annotate';
313
+ // Init canvas after mode switch renders it
314
+ requestAnimationFrame(() => {
315
+ this.initDrawCanvas();
316
+ this.emitCapture();
317
+ });
318
+ }
319
+ retake() {
320
+ this.strokes = [];
321
+ this.annotations = [];
322
+ this.capturedImageData = '';
323
+ this.capturedImage = null;
324
+ this.highlightedAnnotationId = null;
325
+ this.colorIndex = 0;
326
+ this.activeColor = PRESET_COLORS[0];
327
+ this.mode = 'camera';
328
+ requestAnimationFrame(() => this.startCamera());
329
+ }
330
+ // --- Drawing ---
331
+ initDrawCanvas() {
332
+ const canvas = this.drawCanvas;
333
+ if (!canvas || !this.capturedImage)
334
+ return;
335
+ canvas.width = this.imageWidth;
336
+ canvas.height = this.imageHeight;
337
+ this.ctx = canvas.getContext('2d');
338
+ this.redrawCanvas();
339
+ }
340
+ getCanvasPoint(e) {
341
+ const canvas = this.drawCanvas;
342
+ if (!canvas)
343
+ return { x: 0, y: 0 };
344
+ const rect = canvas.getBoundingClientRect();
345
+ return {
346
+ x: (e.clientX - rect.left) * (canvas.width / rect.width),
347
+ y: (e.clientY - rect.top) * (canvas.height / rect.height)
348
+ };
349
+ }
350
+ handlePointerDown(e) {
351
+ if (this.mode !== 'annotate')
352
+ return;
353
+ e.preventDefault();
354
+ this.isDrawing = true;
355
+ this.currentPoints = [this.getCanvasPoint(e)];
356
+ this.drawCanvas?.setPointerCapture(e.pointerId);
357
+ }
358
+ handlePointerMove(e) {
359
+ if (!this.isDrawing)
360
+ return;
361
+ e.preventDefault();
362
+ const point = this.getCanvasPoint(e);
363
+ this.currentPoints.push(point);
364
+ this.redrawCanvas();
365
+ this.drawCurrentStroke();
366
+ }
367
+ handlePointerUp(e) {
368
+ if (!this.isDrawing)
369
+ return;
370
+ e.preventDefault();
371
+ this.isDrawing = false;
372
+ this.drawCanvas?.releasePointerCapture(e.pointerId);
373
+ if (this.currentPoints.length < 2) {
374
+ this.currentPoints = [];
375
+ return;
376
+ }
377
+ const strokeId = `stroke-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
378
+ const stroke = {
379
+ id: strokeId,
380
+ color: this.activeColor,
381
+ width: this.strokeWidth,
382
+ points: [...this.currentPoints],
383
+ timestamp: Date.now()
384
+ };
385
+ this.strokes.push(stroke);
386
+ const annotation = {
387
+ id: `ann-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
388
+ strokeId,
389
+ label: '',
390
+ color: this.activeColor,
391
+ visible: true,
392
+ timestamp: Date.now()
393
+ };
394
+ this.annotations.push(annotation);
395
+ this.currentPoints = [];
396
+ // Auto rotate color
397
+ if (this.autoRotateColors) {
398
+ this.colorIndex = (this.colorIndex + 1) % PRESET_COLORS.length;
399
+ this.activeColor = PRESET_COLORS[this.colorIndex];
400
+ }
401
+ this.redrawCanvas();
402
+ this.emitAnnotate(annotation);
403
+ this.emitAnnotationChange();
404
+ }
405
+ drawCurrentStroke() {
406
+ if (!this.ctx || this.currentPoints.length < 2)
407
+ return;
408
+ this.ctx.lineJoin = 'round';
409
+ this.ctx.lineCap = 'round';
410
+ this.ctx.strokeStyle = this.activeColor;
411
+ this.ctx.lineWidth = this.strokeWidth * 2;
412
+ this.ctx.beginPath();
413
+ this.ctx.moveTo(this.currentPoints[0].x, this.currentPoints[0].y);
414
+ for (let i = 1; i < this.currentPoints.length; i++) {
415
+ const prev = this.currentPoints[i - 1];
416
+ const curr = this.currentPoints[i];
417
+ const midX = (prev.x + curr.x) / 2;
418
+ const midY = (prev.y + curr.y) / 2;
419
+ this.ctx.quadraticCurveTo(prev.x, prev.y, midX, midY);
420
+ }
421
+ const last = this.currentPoints[this.currentPoints.length - 1];
422
+ this.ctx.lineTo(last.x, last.y);
423
+ this.ctx.stroke();
424
+ }
425
+ redrawCanvas() {
426
+ if (!this.ctx || !this.capturedImage)
427
+ return;
428
+ this.ctx.clearRect(0, 0, this.imageWidth, this.imageHeight);
429
+ this.ctx.drawImage(this.capturedImage, 0, 0, this.imageWidth, this.imageHeight);
430
+ for (const stroke of this.strokes) {
431
+ const ann = this.annotations.find(a => a.strokeId === stroke.id);
432
+ if (ann && !ann.visible)
433
+ continue;
434
+ this.ctx.save();
435
+ // Apply highlight/dim effect
436
+ if (this.highlightedAnnotationId !== null) {
437
+ const isHighlighted = ann && ann.id === this.highlightedAnnotationId;
438
+ if (!isHighlighted) {
439
+ this.ctx.globalAlpha = 0.2;
440
+ this.ctx.filter = 'grayscale(1)';
441
+ }
442
+ }
443
+ this.drawStroke(stroke);
444
+ this.ctx.restore();
445
+ }
446
+ }
447
+ drawStroke(stroke) {
448
+ if (!this.ctx || stroke.points.length === 0)
449
+ return;
450
+ this.ctx.lineJoin = 'round';
451
+ this.ctx.lineCap = 'round';
452
+ this.ctx.strokeStyle = stroke.color;
453
+ this.ctx.lineWidth = stroke.width * 2;
454
+ if (stroke.points.length === 1) {
455
+ this.ctx.beginPath();
456
+ this.ctx.arc(stroke.points[0].x, stroke.points[0].y, stroke.width, 0, Math.PI * 2);
457
+ this.ctx.fillStyle = stroke.color;
458
+ this.ctx.fill();
459
+ return;
460
+ }
461
+ this.ctx.beginPath();
462
+ this.ctx.moveTo(stroke.points[0].x, stroke.points[0].y);
463
+ for (let i = 1; i < stroke.points.length; i++) {
464
+ const prev = stroke.points[i - 1];
465
+ const curr = stroke.points[i];
466
+ const midX = (prev.x + curr.x) / 2;
467
+ const midY = (prev.y + curr.y) / 2;
468
+ this.ctx.quadraticCurveTo(prev.x, prev.y, midX, midY);
469
+ }
470
+ const last = stroke.points[stroke.points.length - 1];
471
+ this.ctx.lineTo(last.x, last.y);
472
+ this.ctx.stroke();
473
+ }
474
+ // --- Annotation management ---
475
+ selectColor(color) {
476
+ this.activeColor = color;
477
+ this.colorIndex = PRESET_COLORS.indexOf(color);
478
+ }
479
+ handleAutoRotateChange(e) {
480
+ this.autoRotateColors = e.target.checked;
481
+ }
482
+ handleStrokeWidthChange(e) {
483
+ this.strokeWidth = Math.max(1, Math.min(20, parseInt(e.target.value) || 3));
484
+ }
485
+ updateAnnotationLabel(id, label) {
486
+ const ann = this.annotations.find(a => a.id === id);
487
+ if (ann) {
488
+ ann.label = label;
489
+ this.emitAnnotationChange();
490
+ }
491
+ }
492
+ toggleAnnotationVisibility(id) {
493
+ const ann = this.annotations.find(a => a.id === id);
494
+ if (ann) {
495
+ ann.visible = !ann.visible;
496
+ this.redrawCanvas();
497
+ this.emitAnnotationChange();
498
+ }
499
+ }
500
+ toggleAllAnnotations() {
501
+ const allVisible = this.annotations.every(a => a.visible);
502
+ this.annotations.forEach(a => a.visible = !allVisible);
503
+ this.redrawCanvas();
504
+ this.emitAnnotationChange();
505
+ }
506
+ deleteAnnotation(id) {
507
+ const ann = this.annotations.find(a => a.id === id);
508
+ if (!ann)
509
+ return;
510
+ this.strokes = this.strokes.filter(s => s.id !== ann.strokeId);
511
+ this.annotations = this.annotations.filter(a => a.id !== id);
512
+ this.redrawCanvas();
513
+ this.emitAnnotationChange();
514
+ }
515
+ highlightAnnotation(id) {
516
+ this.highlightedAnnotationId = id;
517
+ this.redrawCanvas();
518
+ }
519
+ unhighlightAnnotation() {
520
+ this.highlightedAnnotationId = null;
521
+ this.redrawCanvas();
522
+ }
523
+ undoStroke() {
524
+ if (this.strokes.length === 0)
525
+ return;
526
+ const lastStroke = this.strokes.pop();
527
+ this.annotations = this.annotations.filter(a => a.strokeId !== lastStroke.id);
528
+ this.redrawCanvas();
529
+ this.emitAnnotationChange();
530
+ }
531
+ handleExportImage() {
532
+ const dataURL = this.exportImage();
533
+ const a = document.createElement('a');
534
+ a.href = dataURL;
535
+ a.download = `annotated-${Date.now()}.png`;
536
+ a.click();
537
+ }
538
+ // --- Public API ---
539
+ exportImage(options) {
540
+ const canvas = document.createElement('canvas');
541
+ canvas.width = this.imageWidth;
542
+ canvas.height = this.imageHeight;
543
+ const ctx = canvas.getContext('2d');
544
+ // Draw base image
545
+ if (this.capturedImage) {
546
+ ctx.drawImage(this.capturedImage, 0, 0, this.imageWidth, this.imageHeight);
547
+ }
548
+ // Draw visible strokes
549
+ for (const stroke of this.strokes) {
550
+ const ann = this.annotations.find(a => a.strokeId === stroke.id);
551
+ if (ann && !ann.visible)
552
+ continue;
553
+ this.drawStrokeOnCtx(ctx, stroke);
554
+ }
555
+ // Optionally draw labels
556
+ if (options?.includeLabels) {
557
+ for (const ann of this.annotations) {
558
+ if (!ann.visible || !ann.label)
559
+ continue;
560
+ const stroke = this.strokes.find(s => s.id === ann.strokeId);
561
+ if (!stroke || stroke.points.length === 0)
562
+ continue;
563
+ // Position label near stroke center
564
+ let cx = 0, cy = 0;
565
+ for (const p of stroke.points) {
566
+ cx += p.x;
567
+ cy += p.y;
568
+ }
569
+ cx /= stroke.points.length;
570
+ cy /= stroke.points.length;
571
+ ctx.font = `${Math.max(14, this.imageWidth / 60)}px sans-serif`;
572
+ ctx.fillStyle = ann.color;
573
+ ctx.strokeStyle = 'white';
574
+ ctx.lineWidth = 3;
575
+ ctx.strokeText(ann.label, cx, cy - 10);
576
+ ctx.fillText(ann.label, cx, cy - 10);
577
+ }
578
+ }
579
+ return canvas.toDataURL('image/png');
580
+ }
581
+ drawStrokeOnCtx(ctx, stroke) {
582
+ if (stroke.points.length === 0)
583
+ return;
584
+ ctx.lineJoin = 'round';
585
+ ctx.lineCap = 'round';
586
+ ctx.strokeStyle = stroke.color;
587
+ ctx.lineWidth = stroke.width * 2;
588
+ if (stroke.points.length === 1) {
589
+ ctx.beginPath();
590
+ ctx.arc(stroke.points[0].x, stroke.points[0].y, stroke.width, 0, Math.PI * 2);
591
+ ctx.fillStyle = stroke.color;
592
+ ctx.fill();
593
+ return;
594
+ }
595
+ ctx.beginPath();
596
+ ctx.moveTo(stroke.points[0].x, stroke.points[0].y);
597
+ for (let i = 1; i < stroke.points.length; i++) {
598
+ const prev = stroke.points[i - 1];
599
+ const curr = stroke.points[i];
600
+ const midX = (prev.x + curr.x) / 2;
601
+ const midY = (prev.y + curr.y) / 2;
602
+ ctx.quadraticCurveTo(prev.x, prev.y, midX, midY);
603
+ }
604
+ const last = stroke.points[stroke.points.length - 1];
605
+ ctx.lineTo(last.x, last.y);
606
+ ctx.stroke();
607
+ }
608
+ exportAnnotations() {
609
+ return {
610
+ annotations: this.annotations.map(a => ({ ...a })),
611
+ strokes: this.strokes.map(s => ({
612
+ ...s,
613
+ points: s.points.map(p => ({ ...p }))
614
+ })),
615
+ imageWidth: this.imageWidth,
616
+ imageHeight: this.imageHeight
617
+ };
618
+ }
619
+ importAnnotations(data) {
620
+ this.annotations = data.annotations.map(a => ({ ...a }));
621
+ this.strokes = data.strokes.map(s => ({
622
+ ...s,
623
+ points: s.points.map(p => ({ ...p }))
624
+ }));
625
+ this.imageWidth = data.imageWidth;
626
+ this.imageHeight = data.imageHeight;
627
+ this.redrawCanvas();
628
+ this.emitAnnotationChange();
629
+ }
630
+ clearAnnotations() {
631
+ this.strokes = [];
632
+ this.annotations = [];
633
+ this.highlightedAnnotationId = null;
634
+ this.colorIndex = 0;
635
+ this.activeColor = PRESET_COLORS[0];
636
+ this.redrawCanvas();
637
+ this.emitAnnotationChange();
638
+ }
639
+ handleModeChange() {
640
+ if (this.mode === 'annotate' && this.capturedImage) {
641
+ requestAnimationFrame(() => this.initDrawCanvas());
642
+ }
643
+ }
644
+ // --- Events ---
645
+ emitCapture() {
646
+ return {
647
+ dataURL: this.capturedImageData,
648
+ width: this.imageWidth,
649
+ height: this.imageHeight
650
+ };
651
+ }
652
+ emitAnnotate(annotation) {
653
+ return { annotation };
654
+ }
655
+ emitAnnotationChange() {
656
+ return { annotations: this.annotations.map(a => ({ ...a })) };
657
+ }
658
+ });
659
+ return _classThis;
660
+ })();
661
+
662
+ export { SniceCameraAnnotate };
663
+ //# sourceMappingURL=snice-camera-annotate.js.map