@aceshooting/lyra-ui 3.6.0 → 3.8.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 (1324) hide show
  1. package/README.md +109 -3
  2. package/custom-elements.json +91136 -42119
  3. package/dist/components/activity-feed/activity-feed.class.d.ts +111 -0
  4. package/dist/components/activity-feed/activity-feed.class.d.ts.map +1 -0
  5. package/dist/components/activity-feed/activity-feed.class.js +292 -0
  6. package/dist/components/activity-feed/activity-feed.class.js.map +1 -0
  7. package/dist/components/activity-feed/activity-feed.d.ts +2 -0
  8. package/dist/components/activity-feed/activity-feed.d.ts.map +1 -0
  9. package/dist/components/activity-feed/activity-feed.js +5 -0
  10. package/dist/components/activity-feed/activity-feed.js.map +1 -0
  11. package/dist/components/activity-feed/activity-feed.styles.d.ts +2 -0
  12. package/dist/components/activity-feed/activity-feed.styles.d.ts.map +1 -0
  13. package/dist/components/activity-feed/activity-feed.styles.js +147 -0
  14. package/dist/components/activity-feed/activity-feed.styles.js.map +1 -0
  15. package/dist/components/animation/animation.class.d.ts +12 -0
  16. package/dist/components/animation/animation.class.d.ts.map +1 -1
  17. package/dist/components/animation/animation.class.js +47 -7
  18. package/dist/components/animation/animation.class.js.map +1 -1
  19. package/dist/components/app-rail/app-rail.class.d.ts +19 -3
  20. package/dist/components/app-rail/app-rail.class.d.ts.map +1 -1
  21. package/dist/components/app-rail/app-rail.class.js +34 -12
  22. package/dist/components/app-rail/app-rail.class.js.map +1 -1
  23. package/dist/components/app-rail/app-rail.styles.d.ts.map +1 -1
  24. package/dist/components/app-rail/app-rail.styles.js +19 -11
  25. package/dist/components/app-rail/app-rail.styles.js.map +1 -1
  26. package/dist/components/artifact-panel/artifact-panel.class.d.ts +100 -0
  27. package/dist/components/artifact-panel/artifact-panel.class.d.ts.map +1 -0
  28. package/dist/components/artifact-panel/artifact-panel.class.js +254 -0
  29. package/dist/components/artifact-panel/artifact-panel.class.js.map +1 -0
  30. package/dist/components/artifact-panel/artifact-panel.d.ts +2 -0
  31. package/dist/components/artifact-panel/artifact-panel.d.ts.map +1 -0
  32. package/dist/components/artifact-panel/artifact-panel.js +5 -0
  33. package/dist/components/artifact-panel/artifact-panel.js.map +1 -0
  34. package/dist/components/artifact-panel/artifact-panel.styles.d.ts +2 -0
  35. package/dist/components/artifact-panel/artifact-panel.styles.d.ts.map +1 -0
  36. package/dist/components/artifact-panel/artifact-panel.styles.js +97 -0
  37. package/dist/components/artifact-panel/artifact-panel.styles.js.map +1 -0
  38. package/dist/components/attachment-chip/attachment-chip.class.d.ts +4 -2
  39. package/dist/components/attachment-chip/attachment-chip.class.d.ts.map +1 -1
  40. package/dist/components/attachment-chip/attachment-chip.class.js +10 -5
  41. package/dist/components/attachment-chip/attachment-chip.class.js.map +1 -1
  42. package/dist/components/attachment-chip/attachment-chip.styles.d.ts.map +1 -1
  43. package/dist/components/attachment-chip/attachment-chip.styles.js +7 -2
  44. package/dist/components/attachment-chip/attachment-chip.styles.js.map +1 -1
  45. package/dist/components/attachment-trigger/attachment-trigger.class.d.ts +17 -12
  46. package/dist/components/attachment-trigger/attachment-trigger.class.d.ts.map +1 -1
  47. package/dist/components/attachment-trigger/attachment-trigger.class.js +28 -8
  48. package/dist/components/attachment-trigger/attachment-trigger.class.js.map +1 -1
  49. package/dist/components/attachment-trigger/attachment-trigger.styles.d.ts.map +1 -1
  50. package/dist/components/attachment-trigger/attachment-trigger.styles.js +11 -0
  51. package/dist/components/attachment-trigger/attachment-trigger.styles.js.map +1 -1
  52. package/dist/components/audio-visualizer/audio-visualizer.class.d.ts +111 -0
  53. package/dist/components/audio-visualizer/audio-visualizer.class.d.ts.map +1 -0
  54. package/dist/components/audio-visualizer/audio-visualizer.class.js +435 -0
  55. package/dist/components/audio-visualizer/audio-visualizer.class.js.map +1 -0
  56. package/dist/components/audio-visualizer/audio-visualizer.d.ts +2 -0
  57. package/dist/components/audio-visualizer/audio-visualizer.d.ts.map +1 -0
  58. package/dist/components/audio-visualizer/audio-visualizer.js +5 -0
  59. package/dist/components/audio-visualizer/audio-visualizer.js.map +1 -0
  60. package/dist/components/audio-visualizer/audio-visualizer.styles.d.ts +2 -0
  61. package/dist/components/audio-visualizer/audio-visualizer.styles.d.ts.map +1 -0
  62. package/dist/components/audio-visualizer/audio-visualizer.styles.js +20 -0
  63. package/dist/components/audio-visualizer/audio-visualizer.styles.js.map +1 -0
  64. package/dist/components/av-player/av-player.class.d.ts +215 -0
  65. package/dist/components/av-player/av-player.class.d.ts.map +1 -0
  66. package/dist/components/av-player/av-player.class.js +590 -0
  67. package/dist/components/av-player/av-player.class.js.map +1 -0
  68. package/dist/components/av-player/av-player.d.ts +2 -0
  69. package/dist/components/av-player/av-player.d.ts.map +1 -0
  70. package/dist/components/av-player/av-player.js +36 -0
  71. package/dist/components/av-player/av-player.js.map +1 -0
  72. package/dist/components/av-player/av-player.styles.d.ts +2 -0
  73. package/dist/components/av-player/av-player.styles.d.ts.map +1 -0
  74. package/dist/components/av-player/av-player.styles.js +109 -0
  75. package/dist/components/av-player/av-player.styles.js.map +1 -0
  76. package/dist/components/avatar-group/avatar-group.class.d.ts +7 -2
  77. package/dist/components/avatar-group/avatar-group.class.d.ts.map +1 -1
  78. package/dist/components/avatar-group/avatar-group.class.js +19 -2
  79. package/dist/components/avatar-group/avatar-group.class.js.map +1 -1
  80. package/dist/components/badge/tag.class.d.ts +4 -1
  81. package/dist/components/badge/tag.class.d.ts.map +1 -1
  82. package/dist/components/badge/tag.class.js +4 -1
  83. package/dist/components/badge/tag.class.js.map +1 -1
  84. package/dist/components/branch-picker/branch-picker.class.d.ts +69 -0
  85. package/dist/components/branch-picker/branch-picker.class.d.ts.map +1 -0
  86. package/dist/components/branch-picker/branch-picker.class.js +151 -0
  87. package/dist/components/branch-picker/branch-picker.class.js.map +1 -0
  88. package/dist/components/branch-picker/branch-picker.d.ts +3 -0
  89. package/dist/components/branch-picker/branch-picker.d.ts.map +1 -0
  90. package/dist/components/branch-picker/branch-picker.js +6 -0
  91. package/dist/components/branch-picker/branch-picker.js.map +1 -0
  92. package/dist/components/branch-picker/branch-picker.styles.d.ts +2 -0
  93. package/dist/components/branch-picker/branch-picker.styles.d.ts.map +1 -0
  94. package/dist/components/branch-picker/branch-picker.styles.js +64 -0
  95. package/dist/components/branch-picker/branch-picker.styles.js.map +1 -0
  96. package/dist/components/browser-frame/browser-frame.class.d.ts +70 -0
  97. package/dist/components/browser-frame/browser-frame.class.d.ts.map +1 -0
  98. package/dist/components/browser-frame/browser-frame.class.js +196 -0
  99. package/dist/components/browser-frame/browser-frame.class.js.map +1 -0
  100. package/dist/components/browser-frame/browser-frame.d.ts +2 -0
  101. package/dist/components/browser-frame/browser-frame.d.ts.map +1 -0
  102. package/dist/components/browser-frame/browser-frame.js +5 -0
  103. package/dist/components/browser-frame/browser-frame.js.map +1 -0
  104. package/dist/components/browser-frame/browser-frame.styles.d.ts +2 -0
  105. package/dist/components/browser-frame/browser-frame.styles.d.ts.map +1 -0
  106. package/dist/components/browser-frame/browser-frame.styles.js +88 -0
  107. package/dist/components/browser-frame/browser-frame.styles.js.map +1 -0
  108. package/dist/components/button/button.class.d.ts +32 -4
  109. package/dist/components/button/button.class.d.ts.map +1 -1
  110. package/dist/components/button/button.class.js +43 -7
  111. package/dist/components/button/button.class.js.map +1 -1
  112. package/dist/components/button/button.styles.d.ts.map +1 -1
  113. package/dist/components/button/button.styles.js +33 -0
  114. package/dist/components/button/button.styles.js.map +1 -1
  115. package/dist/components/calendar/calendar.class.d.ts +14 -2
  116. package/dist/components/calendar/calendar.class.d.ts.map +1 -1
  117. package/dist/components/calendar/calendar.class.js +41 -8
  118. package/dist/components/calendar/calendar.class.js.map +1 -1
  119. package/dist/components/calendar/calendar.styles.d.ts.map +1 -1
  120. package/dist/components/calendar/calendar.styles.js +9 -4
  121. package/dist/components/calendar/calendar.styles.js.map +1 -1
  122. package/dist/components/calendar-viewer/calendar-viewer.class.d.ts.map +1 -1
  123. package/dist/components/calendar-viewer/calendar-viewer.class.js +2 -1
  124. package/dist/components/calendar-viewer/calendar-viewer.class.js.map +1 -1
  125. package/dist/components/callout/callout.class.d.ts +5 -1
  126. package/dist/components/callout/callout.class.d.ts.map +1 -1
  127. package/dist/components/callout/callout.class.js +6 -2
  128. package/dist/components/callout/callout.class.js.map +1 -1
  129. package/dist/components/callout/callout.styles.d.ts.map +1 -1
  130. package/dist/components/callout/callout.styles.js +11 -3
  131. package/dist/components/callout/callout.styles.js.map +1 -1
  132. package/dist/components/carousel/carousel.class.d.ts +9 -1
  133. package/dist/components/carousel/carousel.class.d.ts.map +1 -1
  134. package/dist/components/carousel/carousel.class.js +22 -4
  135. package/dist/components/carousel/carousel.class.js.map +1 -1
  136. package/dist/components/carousel/carousel.styles.d.ts.map +1 -1
  137. package/dist/components/carousel/carousel.styles.js +27 -5
  138. package/dist/components/carousel/carousel.styles.js.map +1 -1
  139. package/dist/components/chart/box-plot.class.d.ts.map +1 -1
  140. package/dist/components/chart/box-plot.class.js +3 -2
  141. package/dist/components/chart/box-plot.class.js.map +1 -1
  142. package/dist/components/chart/chart.class.d.ts +31 -0
  143. package/dist/components/chart/chart.class.d.ts.map +1 -1
  144. package/dist/components/chart/chart.class.js +150 -7
  145. package/dist/components/chart/chart.class.js.map +1 -1
  146. package/dist/components/chart/chart.styles.d.ts.map +1 -1
  147. package/dist/components/chart/chart.styles.js +6 -0
  148. package/dist/components/chart/chart.styles.js.map +1 -1
  149. package/dist/components/chart/lite-chart.class.d.ts +15 -1
  150. package/dist/components/chart/lite-chart.class.d.ts.map +1 -1
  151. package/dist/components/chart/lite-chart.class.js +87 -26
  152. package/dist/components/chart/lite-chart.class.js.map +1 -1
  153. package/dist/components/chart/lite-chart.styles.d.ts.map +1 -1
  154. package/dist/components/chart/lite-chart.styles.js +4 -0
  155. package/dist/components/chart/lite-chart.styles.js.map +1 -1
  156. package/dist/components/chat-composer/chat-composer.class.d.ts +6 -0
  157. package/dist/components/chat-composer/chat-composer.class.d.ts.map +1 -1
  158. package/dist/components/chat-composer/chat-composer.class.js +17 -3
  159. package/dist/components/chat-composer/chat-composer.class.js.map +1 -1
  160. package/dist/components/chat-message/chat-message.class.d.ts +11 -1
  161. package/dist/components/chat-message/chat-message.class.d.ts.map +1 -1
  162. package/dist/components/chat-message/chat-message.class.js +28 -7
  163. package/dist/components/chat-message/chat-message.class.js.map +1 -1
  164. package/dist/components/chat-message/chat-message.styles.d.ts.map +1 -1
  165. package/dist/components/chat-message/chat-message.styles.js +16 -5
  166. package/dist/components/chat-message/chat-message.styles.js.map +1 -1
  167. package/dist/components/chat-viewport/chat-viewport.class.d.ts +143 -0
  168. package/dist/components/chat-viewport/chat-viewport.class.d.ts.map +1 -0
  169. package/dist/components/chat-viewport/chat-viewport.class.js +521 -0
  170. package/dist/components/chat-viewport/chat-viewport.class.js.map +1 -0
  171. package/dist/components/chat-viewport/chat-viewport.d.ts +2 -0
  172. package/dist/components/chat-viewport/chat-viewport.d.ts.map +1 -0
  173. package/dist/components/chat-viewport/chat-viewport.js +5 -0
  174. package/dist/components/chat-viewport/chat-viewport.js.map +1 -0
  175. package/dist/components/chat-viewport/chat-viewport.styles.d.ts +2 -0
  176. package/dist/components/chat-viewport/chat-viewport.styles.d.ts.map +1 -0
  177. package/dist/components/chat-viewport/chat-viewport.styles.js +105 -0
  178. package/dist/components/chat-viewport/chat-viewport.styles.js.map +1 -0
  179. package/dist/components/checkbox/checkbox.class.d.ts +2 -1
  180. package/dist/components/checkbox/checkbox.class.d.ts.map +1 -1
  181. package/dist/components/checkbox/checkbox.class.js +17 -2
  182. package/dist/components/checkbox/checkbox.class.js.map +1 -1
  183. package/dist/components/checkbox-group/checkbox-group.class.d.ts +32 -3
  184. package/dist/components/checkbox-group/checkbox-group.class.d.ts.map +1 -1
  185. package/dist/components/checkbox-group/checkbox-group.class.js +70 -18
  186. package/dist/components/checkbox-group/checkbox-group.class.js.map +1 -1
  187. package/dist/components/checkpoint/checkpoint.class.d.ts +71 -0
  188. package/dist/components/checkpoint/checkpoint.class.d.ts.map +1 -0
  189. package/dist/components/checkpoint/checkpoint.class.js +219 -0
  190. package/dist/components/checkpoint/checkpoint.class.js.map +1 -0
  191. package/dist/components/checkpoint/checkpoint.d.ts +2 -0
  192. package/dist/components/checkpoint/checkpoint.d.ts.map +1 -0
  193. package/dist/components/checkpoint/checkpoint.js +5 -0
  194. package/dist/components/checkpoint/checkpoint.js.map +1 -0
  195. package/dist/components/checkpoint/checkpoint.styles.d.ts +2 -0
  196. package/dist/components/checkpoint/checkpoint.styles.d.ts.map +1 -0
  197. package/dist/components/checkpoint/checkpoint.styles.js +123 -0
  198. package/dist/components/checkpoint/checkpoint.styles.js.map +1 -0
  199. package/dist/components/chip/chip-group.class.d.ts +7 -2
  200. package/dist/components/chip/chip-group.class.d.ts.map +1 -1
  201. package/dist/components/chip/chip-group.class.js +19 -2
  202. package/dist/components/chip/chip-group.class.js.map +1 -1
  203. package/dist/components/chip/chip.styles.d.ts.map +1 -1
  204. package/dist/components/chip/chip.styles.js +12 -3
  205. package/dist/components/chip/chip.styles.js.map +1 -1
  206. package/dist/components/chunk-inspector/chunk-inspector.class.d.ts +131 -0
  207. package/dist/components/chunk-inspector/chunk-inspector.class.d.ts.map +1 -0
  208. package/dist/components/chunk-inspector/chunk-inspector.class.js +170 -0
  209. package/dist/components/chunk-inspector/chunk-inspector.class.js.map +1 -0
  210. package/dist/components/chunk-inspector/chunk-inspector.d.ts +4 -0
  211. package/dist/components/chunk-inspector/chunk-inspector.d.ts.map +1 -0
  212. package/dist/components/chunk-inspector/chunk-inspector.js +7 -0
  213. package/dist/components/chunk-inspector/chunk-inspector.js.map +1 -0
  214. package/dist/components/chunk-inspector/chunk-inspector.styles.d.ts +2 -0
  215. package/dist/components/chunk-inspector/chunk-inspector.styles.d.ts.map +1 -0
  216. package/dist/components/chunk-inspector/chunk-inspector.styles.js +84 -0
  217. package/dist/components/chunk-inspector/chunk-inspector.styles.js.map +1 -0
  218. package/dist/components/citation-badge/citation-badge.class.d.ts +7 -2
  219. package/dist/components/citation-badge/citation-badge.class.d.ts.map +1 -1
  220. package/dist/components/citation-badge/citation-badge.class.js +15 -3
  221. package/dist/components/citation-badge/citation-badge.class.js.map +1 -1
  222. package/dist/components/code-block/code-block-core.class.d.ts +62 -0
  223. package/dist/components/code-block/code-block-core.class.d.ts.map +1 -1
  224. package/dist/components/code-block/code-block-core.class.js +229 -42
  225. package/dist/components/code-block/code-block-core.class.js.map +1 -1
  226. package/dist/components/code-block/code-block-shared.d.ts +29 -5
  227. package/dist/components/code-block/code-block-shared.d.ts.map +1 -1
  228. package/dist/components/code-block/code-block-shared.js +73 -5
  229. package/dist/components/code-block/code-block-shared.js.map +1 -1
  230. package/dist/components/code-block/code-block.class.d.ts +62 -0
  231. package/dist/components/code-block/code-block.class.d.ts.map +1 -1
  232. package/dist/components/code-block/code-block.class.js +229 -42
  233. package/dist/components/code-block/code-block.class.js.map +1 -1
  234. package/dist/components/code-block/code-block.styles.d.ts.map +1 -1
  235. package/dist/components/code-block/code-block.styles.js +41 -0
  236. package/dist/components/code-block/code-block.styles.js.map +1 -1
  237. package/dist/components/code-editor/code-editor.class.d.ts +17 -1
  238. package/dist/components/code-editor/code-editor.class.d.ts.map +1 -1
  239. package/dist/components/code-editor/code-editor.class.js +50 -11
  240. package/dist/components/code-editor/code-editor.class.js.map +1 -1
  241. package/dist/components/combobox/combobox.class.d.ts +21 -2
  242. package/dist/components/combobox/combobox.class.d.ts.map +1 -1
  243. package/dist/components/combobox/combobox.class.js +41 -12
  244. package/dist/components/combobox/combobox.class.js.map +1 -1
  245. package/dist/components/combobox/combobox.styles.d.ts.map +1 -1
  246. package/dist/components/combobox/combobox.styles.js +29 -7
  247. package/dist/components/combobox/combobox.styles.js.map +1 -1
  248. package/dist/components/command-palette/command-palette.class.d.ts +14 -0
  249. package/dist/components/command-palette/command-palette.class.d.ts.map +1 -1
  250. package/dist/components/command-palette/command-palette.class.js +33 -6
  251. package/dist/components/command-palette/command-palette.class.js.map +1 -1
  252. package/dist/components/commit-card/commit-card.class.d.ts +78 -0
  253. package/dist/components/commit-card/commit-card.class.d.ts.map +1 -0
  254. package/dist/components/commit-card/commit-card.class.js +209 -0
  255. package/dist/components/commit-card/commit-card.class.js.map +1 -0
  256. package/dist/components/commit-card/commit-card.d.ts +2 -0
  257. package/dist/components/commit-card/commit-card.d.ts.map +1 -0
  258. package/dist/components/commit-card/commit-card.js +5 -0
  259. package/dist/components/commit-card/commit-card.js.map +1 -0
  260. package/dist/components/commit-card/commit-card.styles.d.ts +2 -0
  261. package/dist/components/commit-card/commit-card.styles.d.ts.map +1 -0
  262. package/dist/components/commit-card/commit-card.styles.js +69 -0
  263. package/dist/components/commit-card/commit-card.styles.js.map +1 -0
  264. package/dist/components/community-card/community-card.class.d.ts +68 -0
  265. package/dist/components/community-card/community-card.class.d.ts.map +1 -0
  266. package/dist/components/community-card/community-card.class.js +109 -0
  267. package/dist/components/community-card/community-card.class.js.map +1 -0
  268. package/dist/components/community-card/community-card.d.ts +5 -0
  269. package/dist/components/community-card/community-card.d.ts.map +1 -0
  270. package/dist/components/community-card/community-card.js +8 -0
  271. package/dist/components/community-card/community-card.js.map +1 -0
  272. package/dist/components/community-card/community-card.styles.d.ts +2 -0
  273. package/dist/components/community-card/community-card.styles.d.ts.map +1 -0
  274. package/dist/components/community-card/community-card.styles.js +74 -0
  275. package/dist/components/community-card/community-card.styles.js.map +1 -0
  276. package/dist/components/compare-panel/compare-panel.class.d.ts +112 -0
  277. package/dist/components/compare-panel/compare-panel.class.d.ts.map +1 -0
  278. package/dist/components/compare-panel/compare-panel.class.js +260 -0
  279. package/dist/components/compare-panel/compare-panel.class.js.map +1 -0
  280. package/dist/components/compare-panel/compare-panel.d.ts +3 -0
  281. package/dist/components/compare-panel/compare-panel.d.ts.map +1 -0
  282. package/dist/components/compare-panel/compare-panel.js +6 -0
  283. package/dist/components/compare-panel/compare-panel.js.map +1 -0
  284. package/dist/components/compare-panel/compare-panel.styles.d.ts +2 -0
  285. package/dist/components/compare-panel/compare-panel.styles.d.ts.map +1 -0
  286. package/dist/components/compare-panel/compare-panel.styles.js +97 -0
  287. package/dist/components/compare-panel/compare-panel.styles.js.map +1 -0
  288. package/dist/components/confirm-bar/confirm-bar.class.d.ts +81 -0
  289. package/dist/components/confirm-bar/confirm-bar.class.d.ts.map +1 -0
  290. package/dist/components/confirm-bar/confirm-bar.class.js +193 -0
  291. package/dist/components/confirm-bar/confirm-bar.class.js.map +1 -0
  292. package/dist/components/confirm-bar/confirm-bar.d.ts +5 -0
  293. package/dist/components/confirm-bar/confirm-bar.d.ts.map +1 -0
  294. package/dist/components/confirm-bar/confirm-bar.js +8 -0
  295. package/dist/components/confirm-bar/confirm-bar.js.map +1 -0
  296. package/dist/components/confirm-bar/confirm-bar.styles.d.ts +2 -0
  297. package/dist/components/confirm-bar/confirm-bar.styles.d.ts.map +1 -0
  298. package/dist/components/confirm-bar/confirm-bar.styles.js +96 -0
  299. package/dist/components/confirm-bar/confirm-bar.styles.js.map +1 -0
  300. package/dist/components/context-meter/context-meter.class.d.ts +8 -1
  301. package/dist/components/context-meter/context-meter.class.d.ts.map +1 -1
  302. package/dist/components/context-meter/context-meter.class.js +25 -4
  303. package/dist/components/context-meter/context-meter.class.js.map +1 -1
  304. package/dist/components/context-meter/context-meter.styles.d.ts.map +1 -1
  305. package/dist/components/context-meter/context-meter.styles.js +6 -0
  306. package/dist/components/context-meter/context-meter.styles.js.map +1 -1
  307. package/dist/components/conversation-item/conversation-item.class.d.ts +17 -1
  308. package/dist/components/conversation-item/conversation-item.class.d.ts.map +1 -1
  309. package/dist/components/conversation-item/conversation-item.class.js +43 -4
  310. package/dist/components/conversation-item/conversation-item.class.js.map +1 -1
  311. package/dist/components/conversation-item/conversation-item.styles.d.ts.map +1 -1
  312. package/dist/components/conversation-item/conversation-item.styles.js +15 -2
  313. package/dist/components/conversation-item/conversation-item.styles.js.map +1 -1
  314. package/dist/components/copy-button/copy-button.class.d.ts.map +1 -1
  315. package/dist/components/copy-button/copy-button.class.js +4 -3
  316. package/dist/components/copy-button/copy-button.class.js.map +1 -1
  317. package/dist/components/csv-viewer/csv-viewer.class.d.ts +83 -3
  318. package/dist/components/csv-viewer/csv-viewer.class.d.ts.map +1 -1
  319. package/dist/components/csv-viewer/csv-viewer.class.js +204 -6
  320. package/dist/components/csv-viewer/csv-viewer.class.js.map +1 -1
  321. package/dist/components/csv-viewer/csv-viewer.js +10 -1
  322. package/dist/components/csv-viewer/csv-viewer.js.map +1 -1
  323. package/dist/components/data-grid/data-grid.class.d.ts +2 -1
  324. package/dist/components/data-grid/data-grid.class.d.ts.map +1 -1
  325. package/dist/components/data-grid/data-grid.class.js +10 -1
  326. package/dist/components/data-grid/data-grid.class.js.map +1 -1
  327. package/dist/components/dataset-viewer/dataset-viewer.class.d.ts +93 -4
  328. package/dist/components/dataset-viewer/dataset-viewer.class.d.ts.map +1 -1
  329. package/dist/components/dataset-viewer/dataset-viewer.class.js +212 -14
  330. package/dist/components/dataset-viewer/dataset-viewer.class.js.map +1 -1
  331. package/dist/components/dataset-viewer/dataset-viewer.js +11 -6
  332. package/dist/components/dataset-viewer/dataset-viewer.js.map +1 -1
  333. package/dist/components/dataset-viewer/dataset-viewer.styles.d.ts.map +1 -1
  334. package/dist/components/dataset-viewer/dataset-viewer.styles.js +52 -5
  335. package/dist/components/dataset-viewer/dataset-viewer.styles.js.map +1 -1
  336. package/dist/components/date-picker/calendar-core.d.ts.map +1 -1
  337. package/dist/components/date-picker/calendar-core.js +3 -2
  338. package/dist/components/date-picker/calendar-core.js.map +1 -1
  339. package/dist/components/date-picker/date-input.class.d.ts +6 -0
  340. package/dist/components/date-picker/date-input.class.d.ts.map +1 -1
  341. package/dist/components/date-picker/date-input.class.js +13 -3
  342. package/dist/components/date-picker/date-input.class.js.map +1 -1
  343. package/dist/components/date-picker/date-picker.class.d.ts.map +1 -1
  344. package/dist/components/date-picker/date-picker.class.js +31 -7
  345. package/dist/components/date-picker/date-picker.class.js.map +1 -1
  346. package/dist/components/date-picker/date-picker.styles.d.ts.map +1 -1
  347. package/dist/components/date-picker/date-picker.styles.js +5 -0
  348. package/dist/components/date-picker/date-picker.styles.js.map +1 -1
  349. package/dist/components/details/accordion-item.class.d.ts +4 -1
  350. package/dist/components/details/accordion-item.class.d.ts.map +1 -1
  351. package/dist/components/details/accordion-item.class.js +4 -1
  352. package/dist/components/details/accordion-item.class.js.map +1 -1
  353. package/dist/components/diff-view/diff-line-diff.d.ts +13 -0
  354. package/dist/components/diff-view/diff-line-diff.d.ts.map +1 -1
  355. package/dist/components/diff-view/diff-line-diff.js +33 -0
  356. package/dist/components/diff-view/diff-line-diff.js.map +1 -1
  357. package/dist/components/diff-view/diff-view.class.d.ts +27 -1
  358. package/dist/components/diff-view/diff-view.class.d.ts.map +1 -1
  359. package/dist/components/diff-view/diff-view.class.js +130 -4
  360. package/dist/components/diff-view/diff-view.class.js.map +1 -1
  361. package/dist/components/diff-view/diff-view.styles.d.ts.map +1 -1
  362. package/dist/components/diff-view/diff-view.styles.js +18 -2
  363. package/dist/components/diff-view/diff-view.styles.js.map +1 -1
  364. package/dist/components/dock-panel/dock-panel.class.d.ts.map +1 -1
  365. package/dist/components/dock-panel/dock-panel.class.js +5 -0
  366. package/dist/components/dock-panel/dock-panel.class.js.map +1 -1
  367. package/dist/components/dock-panel/dock-panel.styles.d.ts.map +1 -1
  368. package/dist/components/dock-panel/dock-panel.styles.js +8 -0
  369. package/dist/components/dock-panel/dock-panel.styles.js.map +1 -1
  370. package/dist/components/document-preview/document-preview.class.d.ts +32 -0
  371. package/dist/components/document-preview/document-preview.class.d.ts.map +1 -1
  372. package/dist/components/document-preview/document-preview.class.js +93 -5
  373. package/dist/components/document-preview/document-preview.class.js.map +1 -1
  374. package/dist/components/document-preview/document-preview.styles.d.ts.map +1 -1
  375. package/dist/components/document-preview/document-preview.styles.js +18 -0
  376. package/dist/components/document-preview/document-preview.styles.js.map +1 -1
  377. package/dist/components/document-viewer/anchors.d.ts +89 -0
  378. package/dist/components/document-viewer/anchors.d.ts.map +1 -0
  379. package/dist/components/document-viewer/anchors.js +4 -0
  380. package/dist/components/document-viewer/anchors.js.map +1 -0
  381. package/dist/components/document-viewer/document-viewer.class.d.ts +23 -0
  382. package/dist/components/document-viewer/document-viewer.class.d.ts.map +1 -1
  383. package/dist/components/document-viewer/document-viewer.class.js +72 -3
  384. package/dist/components/document-viewer/document-viewer.class.js.map +1 -1
  385. package/dist/components/document-viewer/registry.d.ts +8 -0
  386. package/dist/components/document-viewer/registry.d.ts.map +1 -1
  387. package/dist/components/document-viewer/registry.js.map +1 -1
  388. package/dist/components/docx-viewer/docx-viewer.class.d.ts +128 -2
  389. package/dist/components/docx-viewer/docx-viewer.class.d.ts.map +1 -1
  390. package/dist/components/docx-viewer/docx-viewer.class.js +433 -3
  391. package/dist/components/docx-viewer/docx-viewer.class.js.map +1 -1
  392. package/dist/components/docx-viewer/docx-viewer.js +1 -0
  393. package/dist/components/docx-viewer/docx-viewer.js.map +1 -1
  394. package/dist/components/docx-viewer/docx-viewer.styles.d.ts.map +1 -1
  395. package/dist/components/docx-viewer/docx-viewer.styles.js +56 -0
  396. package/dist/components/docx-viewer/docx-viewer.styles.js.map +1 -1
  397. package/dist/components/ebook-viewer/ebook-viewer-register.js +1 -0
  398. package/dist/components/ebook-viewer/ebook-viewer-register.js.map +1 -1
  399. package/dist/components/ebook-viewer/ebook-viewer.class.d.ts +111 -2
  400. package/dist/components/ebook-viewer/ebook-viewer.class.d.ts.map +1 -1
  401. package/dist/components/ebook-viewer/ebook-viewer.class.js +289 -4
  402. package/dist/components/ebook-viewer/ebook-viewer.class.js.map +1 -1
  403. package/dist/components/ebook-viewer/ebook-viewer.styles.d.ts.map +1 -1
  404. package/dist/components/ebook-viewer/ebook-viewer.styles.js +6 -2
  405. package/dist/components/ebook-viewer/ebook-viewer.styles.js.map +1 -1
  406. package/dist/components/email-viewer/email-viewer.class.d.ts +26 -1
  407. package/dist/components/email-viewer/email-viewer.class.d.ts.map +1 -1
  408. package/dist/components/email-viewer/email-viewer.class.js +110 -3
  409. package/dist/components/email-viewer/email-viewer.class.js.map +1 -1
  410. package/dist/components/email-viewer/email-viewer.js +1 -0
  411. package/dist/components/email-viewer/email-viewer.js.map +1 -1
  412. package/dist/components/email-viewer/email-viewer.styles.d.ts.map +1 -1
  413. package/dist/components/email-viewer/email-viewer.styles.js +31 -1
  414. package/dist/components/email-viewer/email-viewer.styles.js.map +1 -1
  415. package/dist/components/emoji-picker/emoji-data-loader.d.ts +14 -0
  416. package/dist/components/emoji-picker/emoji-data-loader.d.ts.map +1 -0
  417. package/dist/components/emoji-picker/emoji-data-loader.js +78 -0
  418. package/dist/components/emoji-picker/emoji-data-loader.js.map +1 -0
  419. package/dist/components/emoji-picker/emoji-picker.class.d.ts +98 -0
  420. package/dist/components/emoji-picker/emoji-picker.class.d.ts.map +1 -0
  421. package/dist/components/emoji-picker/emoji-picker.class.js +285 -0
  422. package/dist/components/emoji-picker/emoji-picker.class.js.map +1 -0
  423. package/dist/components/emoji-picker/emoji-picker.d.ts +2 -0
  424. package/dist/components/emoji-picker/emoji-picker.d.ts.map +1 -0
  425. package/dist/components/emoji-picker/emoji-picker.js +5 -0
  426. package/dist/components/emoji-picker/emoji-picker.js.map +1 -0
  427. package/dist/components/emoji-picker/emoji-picker.styles.d.ts +2 -0
  428. package/dist/components/emoji-picker/emoji-picker.styles.d.ts.map +1 -0
  429. package/dist/components/emoji-picker/emoji-picker.styles.js +70 -0
  430. package/dist/components/emoji-picker/emoji-picker.styles.js.map +1 -0
  431. package/dist/components/entity-card/entity-card.class.d.ts +81 -0
  432. package/dist/components/entity-card/entity-card.class.d.ts.map +1 -0
  433. package/dist/components/entity-card/entity-card.class.js +148 -0
  434. package/dist/components/entity-card/entity-card.class.js.map +1 -0
  435. package/dist/components/entity-card/entity-card.d.ts +7 -0
  436. package/dist/components/entity-card/entity-card.d.ts.map +1 -0
  437. package/dist/components/entity-card/entity-card.js +10 -0
  438. package/dist/components/entity-card/entity-card.js.map +1 -0
  439. package/dist/components/entity-card/entity-card.styles.d.ts +2 -0
  440. package/dist/components/entity-card/entity-card.styles.d.ts.map +1 -0
  441. package/dist/components/entity-card/entity-card.styles.js +48 -0
  442. package/dist/components/entity-card/entity-card.styles.js.map +1 -0
  443. package/dist/components/entity-chip/entity-chip.class.d.ts +72 -0
  444. package/dist/components/entity-chip/entity-chip.class.d.ts.map +1 -0
  445. package/dist/components/entity-chip/entity-chip.class.js +200 -0
  446. package/dist/components/entity-chip/entity-chip.class.js.map +1 -0
  447. package/dist/components/entity-chip/entity-chip.d.ts +2 -0
  448. package/dist/components/entity-chip/entity-chip.d.ts.map +1 -0
  449. package/dist/components/entity-chip/entity-chip.js +5 -0
  450. package/dist/components/entity-chip/entity-chip.js.map +1 -0
  451. package/dist/components/entity-chip/entity-chip.styles.d.ts +2 -0
  452. package/dist/components/entity-chip/entity-chip.styles.d.ts.map +1 -0
  453. package/dist/components/entity-chip/entity-chip.styles.js +46 -0
  454. package/dist/components/entity-chip/entity-chip.styles.js.map +1 -0
  455. package/dist/components/env-list/env-list.class.d.ts +55 -0
  456. package/dist/components/env-list/env-list.class.d.ts.map +1 -0
  457. package/dist/components/env-list/env-list.class.js +143 -0
  458. package/dist/components/env-list/env-list.class.js.map +1 -0
  459. package/dist/components/env-list/env-list.d.ts +2 -0
  460. package/dist/components/env-list/env-list.d.ts.map +1 -0
  461. package/dist/components/env-list/env-list.js +5 -0
  462. package/dist/components/env-list/env-list.js.map +1 -0
  463. package/dist/components/env-list/env-list.styles.d.ts +2 -0
  464. package/dist/components/env-list/env-list.styles.d.ts.map +1 -0
  465. package/dist/components/env-list/env-list.styles.js +44 -0
  466. package/dist/components/env-list/env-list.styles.js.map +1 -0
  467. package/dist/components/file-icon/file-icon.class.d.ts +5 -1
  468. package/dist/components/file-icon/file-icon.class.d.ts.map +1 -1
  469. package/dist/components/file-icon/file-icon.class.js +25 -2
  470. package/dist/components/file-icon/file-icon.class.js.map +1 -1
  471. package/dist/components/file-icon/file-icon.styles.d.ts.map +1 -1
  472. package/dist/components/file-icon/file-icon.styles.js +4 -0
  473. package/dist/components/file-icon/file-icon.styles.js.map +1 -1
  474. package/dist/components/file-input/file-input.class.d.ts +19 -0
  475. package/dist/components/file-input/file-input.class.d.ts.map +1 -1
  476. package/dist/components/file-input/file-input.class.js +27 -1
  477. package/dist/components/file-input/file-input.class.js.map +1 -1
  478. package/dist/components/file-tree/file-tree.class.d.ts +68 -0
  479. package/dist/components/file-tree/file-tree.class.d.ts.map +1 -0
  480. package/dist/components/file-tree/file-tree.class.js +235 -0
  481. package/dist/components/file-tree/file-tree.class.js.map +1 -0
  482. package/dist/components/file-tree/file-tree.d.ts +2 -0
  483. package/dist/components/file-tree/file-tree.d.ts.map +1 -0
  484. package/dist/components/file-tree/file-tree.js +5 -0
  485. package/dist/components/file-tree/file-tree.js.map +1 -0
  486. package/dist/components/file-tree/file-tree.styles.d.ts +2 -0
  487. package/dist/components/file-tree/file-tree.styles.d.ts.map +1 -0
  488. package/dist/components/file-tree/file-tree.styles.js +10 -0
  489. package/dist/components/file-tree/file-tree.styles.js.map +1 -0
  490. package/dist/components/flag/flag.class.d.ts.map +1 -1
  491. package/dist/components/flag/flag.class.js +7 -15
  492. package/dist/components/flag/flag.class.js.map +1 -1
  493. package/dist/components/flow-canvas/flow-canvas.class.d.ts +411 -0
  494. package/dist/components/flow-canvas/flow-canvas.class.d.ts.map +1 -0
  495. package/dist/components/flow-canvas/flow-canvas.class.js +1570 -0
  496. package/dist/components/flow-canvas/flow-canvas.class.js.map +1 -0
  497. package/dist/components/flow-canvas/flow-canvas.d.ts +4 -0
  498. package/dist/components/flow-canvas/flow-canvas.d.ts.map +1 -0
  499. package/dist/components/flow-canvas/flow-canvas.js +7 -0
  500. package/dist/components/flow-canvas/flow-canvas.js.map +1 -0
  501. package/dist/components/flow-canvas/flow-canvas.styles.d.ts +2 -0
  502. package/dist/components/flow-canvas/flow-canvas.styles.d.ts.map +1 -0
  503. package/dist/components/flow-canvas/flow-canvas.styles.js +186 -0
  504. package/dist/components/flow-canvas/flow-canvas.styles.js.map +1 -0
  505. package/dist/components/flow-controls/flow-controls.class.d.ts +44 -0
  506. package/dist/components/flow-controls/flow-controls.class.d.ts.map +1 -0
  507. package/dist/components/flow-controls/flow-controls.class.js +203 -0
  508. package/dist/components/flow-controls/flow-controls.class.js.map +1 -0
  509. package/dist/components/flow-controls/flow-controls.d.ts +2 -0
  510. package/dist/components/flow-controls/flow-controls.d.ts.map +1 -0
  511. package/dist/components/flow-controls/flow-controls.js +5 -0
  512. package/dist/components/flow-controls/flow-controls.js.map +1 -0
  513. package/dist/components/flow-controls/flow-controls.styles.d.ts +2 -0
  514. package/dist/components/flow-controls/flow-controls.styles.d.ts.map +1 -0
  515. package/dist/components/flow-controls/flow-controls.styles.js +55 -0
  516. package/dist/components/flow-controls/flow-controls.styles.js.map +1 -0
  517. package/dist/components/flow-minimap/flow-minimap.class.d.ts +62 -0
  518. package/dist/components/flow-minimap/flow-minimap.class.d.ts.map +1 -0
  519. package/dist/components/flow-minimap/flow-minimap.class.js +291 -0
  520. package/dist/components/flow-minimap/flow-minimap.class.js.map +1 -0
  521. package/dist/components/flow-minimap/flow-minimap.d.ts +2 -0
  522. package/dist/components/flow-minimap/flow-minimap.d.ts.map +1 -0
  523. package/dist/components/flow-minimap/flow-minimap.js +5 -0
  524. package/dist/components/flow-minimap/flow-minimap.js.map +1 -0
  525. package/dist/components/flow-minimap/flow-minimap.styles.d.ts +2 -0
  526. package/dist/components/flow-minimap/flow-minimap.styles.d.ts.map +1 -0
  527. package/dist/components/flow-minimap/flow-minimap.styles.js +48 -0
  528. package/dist/components/flow-minimap/flow-minimap.styles.js.map +1 -0
  529. package/dist/components/flow-node/flow-node.class.d.ts +70 -0
  530. package/dist/components/flow-node/flow-node.class.d.ts.map +1 -0
  531. package/dist/components/flow-node/flow-node.class.js +187 -0
  532. package/dist/components/flow-node/flow-node.class.js.map +1 -0
  533. package/dist/components/flow-node/flow-node.d.ts +2 -0
  534. package/dist/components/flow-node/flow-node.d.ts.map +1 -0
  535. package/dist/components/flow-node/flow-node.js +5 -0
  536. package/dist/components/flow-node/flow-node.js.map +1 -0
  537. package/dist/components/flow-node/flow-node.styles.d.ts +2 -0
  538. package/dist/components/flow-node/flow-node.styles.d.ts.map +1 -0
  539. package/dist/components/flow-node/flow-node.styles.js +127 -0
  540. package/dist/components/flow-node/flow-node.styles.js.map +1 -0
  541. package/dist/components/flow-run-overlay/flow-run-overlay.class.d.ts +46 -0
  542. package/dist/components/flow-run-overlay/flow-run-overlay.class.d.ts.map +1 -0
  543. package/dist/components/flow-run-overlay/flow-run-overlay.class.js +182 -0
  544. package/dist/components/flow-run-overlay/flow-run-overlay.class.js.map +1 -0
  545. package/dist/components/flow-run-overlay/flow-run-overlay.d.ts +2 -0
  546. package/dist/components/flow-run-overlay/flow-run-overlay.d.ts.map +1 -0
  547. package/dist/components/flow-run-overlay/flow-run-overlay.js +5 -0
  548. package/dist/components/flow-run-overlay/flow-run-overlay.js.map +1 -0
  549. package/dist/components/flow-run-overlay/flow-run-overlay.styles.d.ts +2 -0
  550. package/dist/components/flow-run-overlay/flow-run-overlay.styles.d.ts.map +1 -0
  551. package/dist/components/flow-run-overlay/flow-run-overlay.styles.js +38 -0
  552. package/dist/components/flow-run-overlay/flow-run-overlay.styles.js.map +1 -0
  553. package/dist/components/format/format-bytes.class.d.ts +8 -0
  554. package/dist/components/format/format-bytes.class.d.ts.map +1 -1
  555. package/dist/components/format/format-bytes.class.js +36 -7
  556. package/dist/components/format/format-bytes.class.js.map +1 -1
  557. package/dist/components/format/format-date.class.d.ts.map +1 -1
  558. package/dist/components/format/format-date.class.js +2 -1
  559. package/dist/components/format/format-date.class.js.map +1 -1
  560. package/dist/components/format/format-number.class.d.ts +6 -0
  561. package/dist/components/format/format-number.class.d.ts.map +1 -1
  562. package/dist/components/format/format-number.class.js +34 -5
  563. package/dist/components/format/format-number.class.js.map +1 -1
  564. package/dist/components/format/relative-time.class.d.ts.map +1 -1
  565. package/dist/components/format/relative-time.class.js +2 -1
  566. package/dist/components/format/relative-time.class.js.map +1 -1
  567. package/dist/components/generation-status/generation-status.class.d.ts +3 -0
  568. package/dist/components/generation-status/generation-status.class.d.ts.map +1 -1
  569. package/dist/components/generation-status/generation-status.class.js +28 -11
  570. package/dist/components/generation-status/generation-status.class.js.map +1 -1
  571. package/dist/components/generation-status/generation-status.styles.d.ts.map +1 -1
  572. package/dist/components/generation-status/generation-status.styles.js +7 -4
  573. package/dist/components/generation-status/generation-status.styles.js.map +1 -1
  574. package/dist/components/geojson-view/geojson-view.class.d.ts +40 -0
  575. package/dist/components/geojson-view/geojson-view.class.d.ts.map +1 -0
  576. package/dist/components/geojson-view/geojson-view.class.js +185 -0
  577. package/dist/components/geojson-view/geojson-view.class.js.map +1 -0
  578. package/dist/components/geojson-view/geojson-view.d.ts +5 -0
  579. package/dist/components/geojson-view/geojson-view.d.ts.map +1 -0
  580. package/dist/components/geojson-view/geojson-view.js +18 -0
  581. package/dist/components/geojson-view/geojson-view.js.map +1 -0
  582. package/dist/components/graph/graph-canvas.d.ts +110 -0
  583. package/dist/components/graph/graph-canvas.d.ts.map +1 -0
  584. package/dist/components/graph/graph-canvas.js +175 -0
  585. package/dist/components/graph/graph-canvas.js.map +1 -0
  586. package/dist/components/graph/graph-hull.d.ts +28 -0
  587. package/dist/components/graph/graph-hull.d.ts.map +1 -0
  588. package/dist/components/graph/graph-hull.js +70 -0
  589. package/dist/components/graph/graph-hull.js.map +1 -0
  590. package/dist/components/graph/graph-loader.d.ts +6 -0
  591. package/dist/components/graph/graph-loader.d.ts.map +1 -1
  592. package/dist/components/graph/graph-loader.js +2 -0
  593. package/dist/components/graph/graph-loader.js.map +1 -1
  594. package/dist/components/graph/graph.class.d.ts +447 -2
  595. package/dist/components/graph/graph.class.d.ts.map +1 -1
  596. package/dist/components/graph/graph.class.js +1700 -121
  597. package/dist/components/graph/graph.class.js.map +1 -1
  598. package/dist/components/graph/graph.styles.d.ts.map +1 -1
  599. package/dist/components/graph/graph.styles.js +100 -0
  600. package/dist/components/graph/graph.styles.js.map +1 -1
  601. package/dist/components/graph-legend/graph-legend.class.d.ts +62 -0
  602. package/dist/components/graph-legend/graph-legend.class.d.ts.map +1 -0
  603. package/dist/components/graph-legend/graph-legend.class.js +132 -0
  604. package/dist/components/graph-legend/graph-legend.class.js.map +1 -0
  605. package/dist/components/graph-legend/graph-legend.d.ts +2 -0
  606. package/dist/components/graph-legend/graph-legend.d.ts.map +1 -0
  607. package/dist/components/graph-legend/graph-legend.js +5 -0
  608. package/dist/components/graph-legend/graph-legend.js.map +1 -0
  609. package/dist/components/graph-legend/graph-legend.styles.d.ts +2 -0
  610. package/dist/components/graph-legend/graph-legend.styles.d.ts.map +1 -0
  611. package/dist/components/graph-legend/graph-legend.styles.js +59 -0
  612. package/dist/components/graph-legend/graph-legend.styles.js.map +1 -0
  613. package/dist/components/handoff-divider/handoff-divider.class.d.ts +46 -0
  614. package/dist/components/handoff-divider/handoff-divider.class.d.ts.map +1 -0
  615. package/dist/components/handoff-divider/handoff-divider.class.js +99 -0
  616. package/dist/components/handoff-divider/handoff-divider.class.js.map +1 -0
  617. package/dist/components/handoff-divider/handoff-divider.d.ts +2 -0
  618. package/dist/components/handoff-divider/handoff-divider.d.ts.map +1 -0
  619. package/dist/components/handoff-divider/handoff-divider.js +5 -0
  620. package/dist/components/handoff-divider/handoff-divider.js.map +1 -0
  621. package/dist/components/handoff-divider/handoff-divider.styles.d.ts +2 -0
  622. package/dist/components/handoff-divider/handoff-divider.styles.d.ts.map +1 -0
  623. package/dist/components/handoff-divider/handoff-divider.styles.js +48 -0
  624. package/dist/components/handoff-divider/handoff-divider.styles.js.map +1 -0
  625. package/dist/components/heatmap/heatmap.class.d.ts +12 -3
  626. package/dist/components/heatmap/heatmap.class.d.ts.map +1 -1
  627. package/dist/components/heatmap/heatmap.class.js +88 -50
  628. package/dist/components/heatmap/heatmap.class.js.map +1 -1
  629. package/dist/components/highlight-layer/highlight-layer.class.d.ts +60 -0
  630. package/dist/components/highlight-layer/highlight-layer.class.d.ts.map +1 -0
  631. package/dist/components/highlight-layer/highlight-layer.class.js +151 -0
  632. package/dist/components/highlight-layer/highlight-layer.class.js.map +1 -0
  633. package/dist/components/highlight-layer/highlight-layer.d.ts +2 -0
  634. package/dist/components/highlight-layer/highlight-layer.d.ts.map +1 -0
  635. package/dist/components/highlight-layer/highlight-layer.js +5 -0
  636. package/dist/components/highlight-layer/highlight-layer.js.map +1 -0
  637. package/dist/components/highlight-layer/highlight-layer.styles.d.ts +2 -0
  638. package/dist/components/highlight-layer/highlight-layer.styles.d.ts.map +1 -0
  639. package/dist/components/highlight-layer/highlight-layer.styles.js +68 -0
  640. package/dist/components/highlight-layer/highlight-layer.styles.js.map +1 -0
  641. package/dist/components/image-comparer/image-comparer.class.d.ts.map +1 -1
  642. package/dist/components/image-comparer/image-comparer.class.js +2 -1
  643. package/dist/components/image-comparer/image-comparer.class.js.map +1 -1
  644. package/dist/components/image-viewer/image-viewer.class.d.ts +143 -0
  645. package/dist/components/image-viewer/image-viewer.class.d.ts.map +1 -0
  646. package/dist/components/image-viewer/image-viewer.class.js +389 -0
  647. package/dist/components/image-viewer/image-viewer.class.js.map +1 -0
  648. package/dist/components/image-viewer/image-viewer.d.ts +4 -0
  649. package/dist/components/image-viewer/image-viewer.d.ts.map +1 -0
  650. package/dist/components/image-viewer/image-viewer.js +25 -0
  651. package/dist/components/image-viewer/image-viewer.js.map +1 -0
  652. package/dist/components/image-viewer/image-viewer.styles.d.ts +2 -0
  653. package/dist/components/image-viewer/image-viewer.styles.d.ts.map +1 -0
  654. package/dist/components/image-viewer/image-viewer.styles.js +126 -0
  655. package/dist/components/image-viewer/image-viewer.styles.js.map +1 -0
  656. package/dist/components/input/input.class.d.ts +3 -2
  657. package/dist/components/input/input.class.d.ts.map +1 -1
  658. package/dist/components/input/input.class.js +2 -1
  659. package/dist/components/input/input.class.js.map +1 -1
  660. package/dist/components/input/input.styles.d.ts.map +1 -1
  661. package/dist/components/input/input.styles.js +5 -0
  662. package/dist/components/input/input.styles.js.map +1 -1
  663. package/dist/components/intersection-observer/intersection-observer.class.d.ts +1 -0
  664. package/dist/components/intersection-observer/intersection-observer.class.d.ts.map +1 -1
  665. package/dist/components/intersection-observer/intersection-observer.class.js +15 -0
  666. package/dist/components/intersection-observer/intersection-observer.class.js.map +1 -1
  667. package/dist/components/json-viewer/json-viewer.class.d.ts +39 -2
  668. package/dist/components/json-viewer/json-viewer.class.d.ts.map +1 -1
  669. package/dist/components/json-viewer/json-viewer.class.js +95 -6
  670. package/dist/components/json-viewer/json-viewer.class.js.map +1 -1
  671. package/dist/components/known-date/known-date.class.d.ts.map +1 -1
  672. package/dist/components/known-date/known-date.class.js +2 -1
  673. package/dist/components/known-date/known-date.class.js.map +1 -1
  674. package/dist/components/lightbox/lightbox.class.d.ts +2 -2
  675. package/dist/components/lightbox/lightbox.class.d.ts.map +1 -1
  676. package/dist/components/lightbox/lightbox.class.js +16 -7
  677. package/dist/components/lightbox/lightbox.class.js.map +1 -1
  678. package/dist/components/live-region/live-region.class.d.ts +5 -0
  679. package/dist/components/live-region/live-region.class.d.ts.map +1 -1
  680. package/dist/components/live-region/live-region.class.js +10 -2
  681. package/dist/components/live-region/live-region.class.js.map +1 -1
  682. package/dist/components/map/map.class.d.ts +33 -3
  683. package/dist/components/map/map.class.d.ts.map +1 -1
  684. package/dist/components/map/map.class.js +140 -5
  685. package/dist/components/map/map.class.js.map +1 -1
  686. package/dist/components/markdown/katex-loader.d.ts +23 -0
  687. package/dist/components/markdown/katex-loader.d.ts.map +1 -0
  688. package/dist/components/markdown/katex-loader.js +33 -0
  689. package/dist/components/markdown/katex-loader.js.map +1 -0
  690. package/dist/components/markdown/markdown.class.d.ts +191 -4
  691. package/dist/components/markdown/markdown.class.d.ts.map +1 -1
  692. package/dist/components/markdown/markdown.class.js +584 -11
  693. package/dist/components/markdown/markdown.class.js.map +1 -1
  694. package/dist/components/markdown/markdown.styles.d.ts.map +1 -1
  695. package/dist/components/markdown/markdown.styles.js +53 -0
  696. package/dist/components/markdown/markdown.styles.js.map +1 -1
  697. package/dist/components/media-card/media-card.styles.d.ts.map +1 -1
  698. package/dist/components/media-card/media-card.styles.js +6 -2
  699. package/dist/components/media-card/media-card.styles.js.map +1 -1
  700. package/dist/components/mention-popover/mention-popover.styles.d.ts.map +1 -1
  701. package/dist/components/mention-popover/mention-popover.styles.js +6 -3
  702. package/dist/components/mention-popover/mention-popover.styles.js.map +1 -1
  703. package/dist/components/message-actions/message-actions.class.d.ts +112 -0
  704. package/dist/components/message-actions/message-actions.class.d.ts.map +1 -0
  705. package/dist/components/message-actions/message-actions.class.js +277 -0
  706. package/dist/components/message-actions/message-actions.class.js.map +1 -0
  707. package/dist/components/message-actions/message-actions.d.ts +4 -0
  708. package/dist/components/message-actions/message-actions.d.ts.map +1 -0
  709. package/dist/components/message-actions/message-actions.js +7 -0
  710. package/dist/components/message-actions/message-actions.js.map +1 -0
  711. package/dist/components/message-actions/message-actions.styles.d.ts +2 -0
  712. package/dist/components/message-actions/message-actions.styles.d.ts.map +1 -0
  713. package/dist/components/message-actions/message-actions.styles.js +66 -0
  714. package/dist/components/message-actions/message-actions.styles.js.map +1 -0
  715. package/dist/components/message-feedback/message-feedback.class.d.ts +91 -0
  716. package/dist/components/message-feedback/message-feedback.class.d.ts.map +1 -0
  717. package/dist/components/message-feedback/message-feedback.class.js +266 -0
  718. package/dist/components/message-feedback/message-feedback.class.js.map +1 -0
  719. package/dist/components/message-feedback/message-feedback.d.ts +2 -0
  720. package/dist/components/message-feedback/message-feedback.d.ts.map +1 -0
  721. package/dist/components/message-feedback/message-feedback.js +5 -0
  722. package/dist/components/message-feedback/message-feedback.js.map +1 -0
  723. package/dist/components/message-feedback/message-feedback.styles.d.ts +2 -0
  724. package/dist/components/message-feedback/message-feedback.styles.d.ts.map +1 -0
  725. package/dist/components/message-feedback/message-feedback.styles.js +133 -0
  726. package/dist/components/message-feedback/message-feedback.styles.js.map +1 -0
  727. package/dist/components/mind-map/mind-map-layout.d.ts +52 -0
  728. package/dist/components/mind-map/mind-map-layout.d.ts.map +1 -0
  729. package/dist/components/mind-map/mind-map-layout.js +69 -0
  730. package/dist/components/mind-map/mind-map-layout.js.map +1 -0
  731. package/dist/components/mind-map/mind-map.class.d.ts +83 -0
  732. package/dist/components/mind-map/mind-map.class.d.ts.map +1 -0
  733. package/dist/components/mind-map/mind-map.class.js +252 -0
  734. package/dist/components/mind-map/mind-map.class.js.map +1 -0
  735. package/dist/components/mind-map/mind-map.d.ts +2 -0
  736. package/dist/components/mind-map/mind-map.d.ts.map +1 -0
  737. package/dist/components/mind-map/mind-map.js +5 -0
  738. package/dist/components/mind-map/mind-map.js.map +1 -0
  739. package/dist/components/mind-map/mind-map.styles.d.ts +2 -0
  740. package/dist/components/mind-map/mind-map.styles.d.ts.map +1 -0
  741. package/dist/components/mind-map/mind-map.styles.js +43 -0
  742. package/dist/components/mind-map/mind-map.styles.js.map +1 -0
  743. package/dist/components/model-select/model-select.class.d.ts +1 -0
  744. package/dist/components/model-select/model-select.class.d.ts.map +1 -1
  745. package/dist/components/model-select/model-select.class.js +13 -0
  746. package/dist/components/model-select/model-select.class.js.map +1 -1
  747. package/dist/components/mutation-observer/mutation-observer.class.d.ts +1 -0
  748. package/dist/components/mutation-observer/mutation-observer.class.d.ts.map +1 -1
  749. package/dist/components/mutation-observer/mutation-observer.class.js +15 -0
  750. package/dist/components/mutation-observer/mutation-observer.class.js.map +1 -1
  751. package/dist/components/neighbor-list/neighbor-list.class.d.ts +70 -0
  752. package/dist/components/neighbor-list/neighbor-list.class.d.ts.map +1 -0
  753. package/dist/components/neighbor-list/neighbor-list.class.js +177 -0
  754. package/dist/components/neighbor-list/neighbor-list.class.js.map +1 -0
  755. package/dist/components/neighbor-list/neighbor-list.d.ts +4 -0
  756. package/dist/components/neighbor-list/neighbor-list.d.ts.map +1 -0
  757. package/dist/components/neighbor-list/neighbor-list.js +7 -0
  758. package/dist/components/neighbor-list/neighbor-list.js.map +1 -0
  759. package/dist/components/neighbor-list/neighbor-list.styles.d.ts +2 -0
  760. package/dist/components/neighbor-list/neighbor-list.styles.d.ts.map +1 -0
  761. package/dist/components/neighbor-list/neighbor-list.styles.js +79 -0
  762. package/dist/components/neighbor-list/neighbor-list.styles.js.map +1 -0
  763. package/dist/components/node-palette/node-palette.class.d.ts +82 -0
  764. package/dist/components/node-palette/node-palette.class.d.ts.map +1 -0
  765. package/dist/components/node-palette/node-palette.class.js +213 -0
  766. package/dist/components/node-palette/node-palette.class.js.map +1 -0
  767. package/dist/components/node-palette/node-palette.d.ts +2 -0
  768. package/dist/components/node-palette/node-palette.d.ts.map +1 -0
  769. package/dist/components/node-palette/node-palette.js +5 -0
  770. package/dist/components/node-palette/node-palette.js.map +1 -0
  771. package/dist/components/node-palette/node-palette.styles.d.ts +2 -0
  772. package/dist/components/node-palette/node-palette.styles.d.ts.map +1 -0
  773. package/dist/components/node-palette/node-palette.styles.js +74 -0
  774. package/dist/components/node-palette/node-palette.styles.js.map +1 -0
  775. package/dist/components/notebook-viewer/dompurify-loader.d.ts +7 -0
  776. package/dist/components/notebook-viewer/dompurify-loader.d.ts.map +1 -0
  777. package/dist/components/notebook-viewer/dompurify-loader.js +23 -0
  778. package/dist/components/notebook-viewer/dompurify-loader.js.map +1 -0
  779. package/dist/components/notebook-viewer/notebook-viewer.class.d.ts +164 -0
  780. package/dist/components/notebook-viewer/notebook-viewer.class.d.ts.map +1 -0
  781. package/dist/components/notebook-viewer/notebook-viewer.class.js +442 -0
  782. package/dist/components/notebook-viewer/notebook-viewer.class.js.map +1 -0
  783. package/dist/components/notebook-viewer/notebook-viewer.d.ts +6 -0
  784. package/dist/components/notebook-viewer/notebook-viewer.d.ts.map +1 -0
  785. package/dist/components/notebook-viewer/notebook-viewer.js +21 -0
  786. package/dist/components/notebook-viewer/notebook-viewer.js.map +1 -0
  787. package/dist/components/notebook-viewer/notebook-viewer.styles.d.ts +2 -0
  788. package/dist/components/notebook-viewer/notebook-viewer.styles.d.ts.map +1 -0
  789. package/dist/components/notebook-viewer/notebook-viewer.styles.js +79 -0
  790. package/dist/components/notebook-viewer/notebook-viewer.styles.js.map +1 -0
  791. package/dist/components/overlay/overlay.styles.d.ts.map +1 -1
  792. package/dist/components/overlay/overlay.styles.js +17 -5
  793. package/dist/components/overlay/overlay.styles.js.map +1 -1
  794. package/dist/components/overlay/popover.class.d.ts +2 -0
  795. package/dist/components/overlay/popover.class.d.ts.map +1 -1
  796. package/dist/components/overlay/popover.class.js +10 -2
  797. package/dist/components/overlay/popover.class.js.map +1 -1
  798. package/dist/components/overlay/tooltip.class.d.ts +4 -0
  799. package/dist/components/overlay/tooltip.class.d.ts.map +1 -1
  800. package/dist/components/overlay/tooltip.class.js +21 -6
  801. package/dist/components/overlay/tooltip.class.js.map +1 -1
  802. package/dist/components/page-rail/page-rail.class.d.ts +99 -0
  803. package/dist/components/page-rail/page-rail.class.d.ts.map +1 -0
  804. package/dist/components/page-rail/page-rail.class.js +279 -0
  805. package/dist/components/page-rail/page-rail.class.js.map +1 -0
  806. package/dist/components/page-rail/page-rail.d.ts +2 -0
  807. package/dist/components/page-rail/page-rail.d.ts.map +1 -0
  808. package/dist/components/page-rail/page-rail.js +5 -0
  809. package/dist/components/page-rail/page-rail.js.map +1 -0
  810. package/dist/components/page-rail/page-rail.styles.d.ts +2 -0
  811. package/dist/components/page-rail/page-rail.styles.d.ts.map +1 -0
  812. package/dist/components/page-rail/page-rail.styles.js +85 -0
  813. package/dist/components/page-rail/page-rail.styles.js.map +1 -0
  814. package/dist/components/pagination/pagination.class.d.ts +5 -0
  815. package/dist/components/pagination/pagination.class.d.ts.map +1 -1
  816. package/dist/components/pagination/pagination.class.js +11 -9
  817. package/dist/components/pagination/pagination.class.js.map +1 -1
  818. package/dist/components/path-strip/path-strip.class.d.ts +61 -0
  819. package/dist/components/path-strip/path-strip.class.d.ts.map +1 -0
  820. package/dist/components/path-strip/path-strip.class.js +164 -0
  821. package/dist/components/path-strip/path-strip.class.js.map +1 -0
  822. package/dist/components/path-strip/path-strip.d.ts +3 -0
  823. package/dist/components/path-strip/path-strip.d.ts.map +1 -0
  824. package/dist/components/path-strip/path-strip.js +6 -0
  825. package/dist/components/path-strip/path-strip.js.map +1 -0
  826. package/dist/components/path-strip/path-strip.styles.d.ts +2 -0
  827. package/dist/components/path-strip/path-strip.styles.d.ts.map +1 -0
  828. package/dist/components/path-strip/path-strip.styles.js +62 -0
  829. package/dist/components/path-strip/path-strip.styles.js.map +1 -0
  830. package/dist/components/pdf-viewer/pdf-viewer.class.d.ts +145 -6
  831. package/dist/components/pdf-viewer/pdf-viewer.class.d.ts.map +1 -1
  832. package/dist/components/pdf-viewer/pdf-viewer.class.js +785 -21
  833. package/dist/components/pdf-viewer/pdf-viewer.class.js.map +1 -1
  834. package/dist/components/pdf-viewer/pdf-viewer.js +7 -1
  835. package/dist/components/pdf-viewer/pdf-viewer.js.map +1 -1
  836. package/dist/components/pdf-viewer/pdf-viewer.styles.d.ts.map +1 -1
  837. package/dist/components/pdf-viewer/pdf-viewer.styles.js +4 -0
  838. package/dist/components/pdf-viewer/pdf-viewer.styles.js.map +1 -1
  839. package/dist/components/phone-input/phone-input.class.d.ts.map +1 -1
  840. package/dist/components/phone-input/phone-input.class.js +5 -1
  841. package/dist/components/phone-input/phone-input.class.js.map +1 -1
  842. package/dist/components/playback/playback.styles.d.ts.map +1 -1
  843. package/dist/components/playback/playback.styles.js +7 -0
  844. package/dist/components/playback/playback.styles.js.map +1 -1
  845. package/dist/components/poll-status/poll-status.class.d.ts +1 -0
  846. package/dist/components/poll-status/poll-status.class.d.ts.map +1 -1
  847. package/dist/components/poll-status/poll-status.class.js +25 -7
  848. package/dist/components/poll-status/poll-status.class.js.map +1 -1
  849. package/dist/components/pptx-viewer/pptx-viewer.styles.d.ts.map +1 -1
  850. package/dist/components/pptx-viewer/pptx-viewer.styles.js +5 -0
  851. package/dist/components/pptx-viewer/pptx-viewer.styles.js.map +1 -1
  852. package/dist/components/progress/progress-bar.class.d.ts +5 -0
  853. package/dist/components/progress/progress-bar.class.d.ts.map +1 -1
  854. package/dist/components/progress/progress-bar.class.js +16 -2
  855. package/dist/components/progress/progress-bar.class.js.map +1 -1
  856. package/dist/components/progress/progress-ring.class.d.ts +5 -0
  857. package/dist/components/progress/progress-ring.class.d.ts.map +1 -1
  858. package/dist/components/progress/progress-ring.class.js +16 -2
  859. package/dist/components/progress/progress-ring.class.js.map +1 -1
  860. package/dist/components/progress/progress.styles.d.ts.map +1 -1
  861. package/dist/components/progress/progress.styles.js +6 -0
  862. package/dist/components/progress/progress.styles.js.map +1 -1
  863. package/dist/components/provenance-panel/provenance-panel.class.d.ts +71 -0
  864. package/dist/components/provenance-panel/provenance-panel.class.d.ts.map +1 -0
  865. package/dist/components/provenance-panel/provenance-panel.class.js +110 -0
  866. package/dist/components/provenance-panel/provenance-panel.class.js.map +1 -0
  867. package/dist/components/provenance-panel/provenance-panel.d.ts +7 -0
  868. package/dist/components/provenance-panel/provenance-panel.d.ts.map +1 -0
  869. package/dist/components/provenance-panel/provenance-panel.js +10 -0
  870. package/dist/components/provenance-panel/provenance-panel.js.map +1 -0
  871. package/dist/components/provenance-panel/provenance-panel.styles.d.ts +2 -0
  872. package/dist/components/provenance-panel/provenance-panel.styles.d.ts.map +1 -0
  873. package/dist/components/provenance-panel/provenance-panel.styles.js +45 -0
  874. package/dist/components/provenance-panel/provenance-panel.styles.js.map +1 -0
  875. package/dist/components/push-to-talk/push-to-talk.class.d.ts +145 -0
  876. package/dist/components/push-to-talk/push-to-talk.class.d.ts.map +1 -0
  877. package/dist/components/push-to-talk/push-to-talk.class.js +478 -0
  878. package/dist/components/push-to-talk/push-to-talk.class.js.map +1 -0
  879. package/dist/components/push-to-talk/push-to-talk.d.ts +3 -0
  880. package/dist/components/push-to-talk/push-to-talk.d.ts.map +1 -0
  881. package/dist/components/push-to-talk/push-to-talk.js +6 -0
  882. package/dist/components/push-to-talk/push-to-talk.js.map +1 -0
  883. package/dist/components/push-to-talk/push-to-talk.styles.d.ts +2 -0
  884. package/dist/components/push-to-talk/push-to-talk.styles.d.ts.map +1 -0
  885. package/dist/components/push-to-talk/push-to-talk.styles.js +79 -0
  886. package/dist/components/push-to-talk/push-to-talk.styles.js.map +1 -0
  887. package/dist/components/radio/radio.class.d.ts +1 -0
  888. package/dist/components/radio/radio.class.d.ts.map +1 -1
  889. package/dist/components/radio/radio.class.js +4 -0
  890. package/dist/components/radio/radio.class.js.map +1 -1
  891. package/dist/components/random-content/random-content.class.d.ts +3 -1
  892. package/dist/components/random-content/random-content.class.d.ts.map +1 -1
  893. package/dist/components/random-content/random-content.class.js +7 -4
  894. package/dist/components/random-content/random-content.class.js.map +1 -1
  895. package/dist/components/rating/rating.class.d.ts +8 -0
  896. package/dist/components/rating/rating.class.d.ts.map +1 -1
  897. package/dist/components/rating/rating.class.js +34 -8
  898. package/dist/components/rating/rating.class.js.map +1 -1
  899. package/dist/components/rubric-form/rubric-form.class.d.ts +195 -0
  900. package/dist/components/rubric-form/rubric-form.class.d.ts.map +1 -0
  901. package/dist/components/rubric-form/rubric-form.class.js +495 -0
  902. package/dist/components/rubric-form/rubric-form.class.js.map +1 -0
  903. package/dist/components/rubric-form/rubric-form.d.ts +9 -0
  904. package/dist/components/rubric-form/rubric-form.d.ts.map +1 -0
  905. package/dist/components/rubric-form/rubric-form.js +12 -0
  906. package/dist/components/rubric-form/rubric-form.js.map +1 -0
  907. package/dist/components/rubric-form/rubric-form.styles.d.ts +2 -0
  908. package/dist/components/rubric-form/rubric-form.styles.d.ts.map +1 -0
  909. package/dist/components/rubric-form/rubric-form.styles.js +90 -0
  910. package/dist/components/rubric-form/rubric-form.styles.js.map +1 -0
  911. package/dist/components/scroller/scroller.class.d.ts +6 -0
  912. package/dist/components/scroller/scroller.class.d.ts.map +1 -1
  913. package/dist/components/scroller/scroller.class.js +14 -4
  914. package/dist/components/scroller/scroller.class.js.map +1 -1
  915. package/dist/components/scroller/scroller.styles.d.ts.map +1 -1
  916. package/dist/components/scroller/scroller.styles.js +18 -0
  917. package/dist/components/scroller/scroller.styles.js.map +1 -1
  918. package/dist/components/segmented/segmented.class.d.ts +1 -0
  919. package/dist/components/segmented/segmented.class.d.ts.map +1 -1
  920. package/dist/components/segmented/segmented.class.js +1 -0
  921. package/dist/components/segmented/segmented.class.js.map +1 -1
  922. package/dist/components/segmented/segmented.styles.d.ts.map +1 -1
  923. package/dist/components/segmented/segmented.styles.js +21 -3
  924. package/dist/components/segmented/segmented.styles.js.map +1 -1
  925. package/dist/components/sequence-strip/sequence-strip.class.d.ts +62 -0
  926. package/dist/components/sequence-strip/sequence-strip.class.d.ts.map +1 -0
  927. package/dist/components/sequence-strip/sequence-strip.class.js +102 -0
  928. package/dist/components/sequence-strip/sequence-strip.class.js.map +1 -0
  929. package/dist/components/sequence-strip/sequence-strip.d.ts +2 -0
  930. package/dist/components/sequence-strip/sequence-strip.d.ts.map +1 -0
  931. package/dist/components/sequence-strip/sequence-strip.js +5 -0
  932. package/dist/components/sequence-strip/sequence-strip.js.map +1 -0
  933. package/dist/components/sequence-strip/sequence-strip.styles.d.ts +2 -0
  934. package/dist/components/sequence-strip/sequence-strip.styles.d.ts.map +1 -0
  935. package/dist/components/sequence-strip/sequence-strip.styles.js +62 -0
  936. package/dist/components/sequence-strip/sequence-strip.styles.js.map +1 -0
  937. package/dist/components/skeleton/skeleton.styles.d.ts.map +1 -1
  938. package/dist/components/skeleton/skeleton.styles.js +7 -0
  939. package/dist/components/skeleton/skeleton.styles.js.map +1 -1
  940. package/dist/components/slider/slider.class.d.ts +6 -1
  941. package/dist/components/slider/slider.class.d.ts.map +1 -1
  942. package/dist/components/slider/slider.class.js +23 -6
  943. package/dist/components/slider/slider.class.js.map +1 -1
  944. package/dist/components/slider/slider.styles.d.ts.map +1 -1
  945. package/dist/components/slider/slider.styles.js +15 -0
  946. package/dist/components/slider/slider.styles.js.map +1 -1
  947. package/dist/components/source-picker/source-picker.class.d.ts +78 -0
  948. package/dist/components/source-picker/source-picker.class.d.ts.map +1 -0
  949. package/dist/components/source-picker/source-picker.class.js +305 -0
  950. package/dist/components/source-picker/source-picker.class.js.map +1 -0
  951. package/dist/components/source-picker/source-picker.d.ts +5 -0
  952. package/dist/components/source-picker/source-picker.d.ts.map +1 -0
  953. package/dist/components/source-picker/source-picker.js +8 -0
  954. package/dist/components/source-picker/source-picker.js.map +1 -0
  955. package/dist/components/source-picker/source-picker.styles.d.ts +2 -0
  956. package/dist/components/source-picker/source-picker.styles.d.ts.map +1 -0
  957. package/dist/components/source-picker/source-picker.styles.js +80 -0
  958. package/dist/components/source-picker/source-picker.styles.js.map +1 -0
  959. package/dist/components/span-waterfall/span-waterfall.class.d.ts +70 -0
  960. package/dist/components/span-waterfall/span-waterfall.class.d.ts.map +1 -0
  961. package/dist/components/span-waterfall/span-waterfall.class.js +307 -0
  962. package/dist/components/span-waterfall/span-waterfall.class.js.map +1 -0
  963. package/dist/components/span-waterfall/span-waterfall.d.ts +4 -0
  964. package/dist/components/span-waterfall/span-waterfall.d.ts.map +1 -0
  965. package/dist/components/span-waterfall/span-waterfall.js +7 -0
  966. package/dist/components/span-waterfall/span-waterfall.js.map +1 -0
  967. package/dist/components/span-waterfall/span-waterfall.styles.d.ts +2 -0
  968. package/dist/components/span-waterfall/span-waterfall.styles.d.ts.map +1 -0
  969. package/dist/components/span-waterfall/span-waterfall.styles.js +130 -0
  970. package/dist/components/span-waterfall/span-waterfall.styles.js.map +1 -0
  971. package/dist/components/sparkline/sparkline.class.d.ts.map +1 -1
  972. package/dist/components/sparkline/sparkline.class.js +17 -7
  973. package/dist/components/sparkline/sparkline.class.js.map +1 -1
  974. package/dist/components/split/split.class.d.ts +13 -0
  975. package/dist/components/split/split.class.d.ts.map +1 -1
  976. package/dist/components/split/split.class.js +24 -4
  977. package/dist/components/split/split.class.js.map +1 -1
  978. package/dist/components/spreadsheet-viewer/spreadsheet-loader.js +1 -1
  979. package/dist/components/spreadsheet-viewer/spreadsheet-loader.js.map +1 -1
  980. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.class.d.ts +93 -3
  981. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.class.d.ts.map +1 -1
  982. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.class.js +241 -9
  983. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.class.js.map +1 -1
  984. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.js +10 -1
  985. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.js.map +1 -1
  986. package/dist/components/stack-trace/stack-trace-parse.d.ts +22 -0
  987. package/dist/components/stack-trace/stack-trace-parse.d.ts.map +1 -0
  988. package/dist/components/stack-trace/stack-trace-parse.js +194 -0
  989. package/dist/components/stack-trace/stack-trace-parse.js.map +1 -0
  990. package/dist/components/stack-trace/stack-trace.class.d.ts +68 -0
  991. package/dist/components/stack-trace/stack-trace.class.d.ts.map +1 -0
  992. package/dist/components/stack-trace/stack-trace.class.js +193 -0
  993. package/dist/components/stack-trace/stack-trace.class.js.map +1 -0
  994. package/dist/components/stack-trace/stack-trace.d.ts +3 -0
  995. package/dist/components/stack-trace/stack-trace.d.ts.map +1 -0
  996. package/dist/components/stack-trace/stack-trace.js +6 -0
  997. package/dist/components/stack-trace/stack-trace.js.map +1 -0
  998. package/dist/components/stack-trace/stack-trace.styles.d.ts +2 -0
  999. package/dist/components/stack-trace/stack-trace.styles.d.ts.map +1 -0
  1000. package/dist/components/stack-trace/stack-trace.styles.js +101 -0
  1001. package/dist/components/stack-trace/stack-trace.styles.js.map +1 -0
  1002. package/dist/components/stat/stat.class.d.ts +10 -1
  1003. package/dist/components/stat/stat.class.d.ts.map +1 -1
  1004. package/dist/components/stat/stat.class.js +22 -7
  1005. package/dist/components/stat/stat.class.js.map +1 -1
  1006. package/dist/components/stepper/stepper.class.d.ts +5 -0
  1007. package/dist/components/stepper/stepper.class.d.ts.map +1 -1
  1008. package/dist/components/stepper/stepper.class.js +9 -1
  1009. package/dist/components/stepper/stepper.class.js.map +1 -1
  1010. package/dist/components/stream-status/stream-status.class.d.ts.map +1 -1
  1011. package/dist/components/stream-status/stream-status.class.js +9 -1
  1012. package/dist/components/stream-status/stream-status.class.js.map +1 -1
  1013. package/dist/components/streaming-text/streaming-text.class.d.ts +6 -0
  1014. package/dist/components/streaming-text/streaming-text.class.d.ts.map +1 -1
  1015. package/dist/components/streaming-text/streaming-text.class.js +22 -3
  1016. package/dist/components/streaming-text/streaming-text.class.js.map +1 -1
  1017. package/dist/components/suggestion-chips/suggestion-chips.class.d.ts +54 -0
  1018. package/dist/components/suggestion-chips/suggestion-chips.class.d.ts.map +1 -0
  1019. package/dist/components/suggestion-chips/suggestion-chips.class.js +120 -0
  1020. package/dist/components/suggestion-chips/suggestion-chips.class.js.map +1 -0
  1021. package/dist/components/suggestion-chips/suggestion-chips.d.ts +3 -0
  1022. package/dist/components/suggestion-chips/suggestion-chips.d.ts.map +1 -0
  1023. package/dist/components/suggestion-chips/suggestion-chips.js +6 -0
  1024. package/dist/components/suggestion-chips/suggestion-chips.js.map +1 -0
  1025. package/dist/components/suggestion-chips/suggestion-chips.styles.d.ts +2 -0
  1026. package/dist/components/suggestion-chips/suggestion-chips.styles.d.ts.map +1 -0
  1027. package/dist/components/suggestion-chips/suggestion-chips.styles.js +60 -0
  1028. package/dist/components/suggestion-chips/suggestion-chips.styles.js.map +1 -0
  1029. package/dist/components/svg-viewer/svg-viewer.class.d.ts +34 -0
  1030. package/dist/components/svg-viewer/svg-viewer.class.d.ts.map +1 -1
  1031. package/dist/components/svg-viewer/svg-viewer.class.js +88 -1
  1032. package/dist/components/svg-viewer/svg-viewer.class.js.map +1 -1
  1033. package/dist/components/svg-viewer/svg-viewer.js +1 -0
  1034. package/dist/components/svg-viewer/svg-viewer.js.map +1 -1
  1035. package/dist/components/svg-viewer/svg-viewer.styles.d.ts.map +1 -1
  1036. package/dist/components/svg-viewer/svg-viewer.styles.js +18 -0
  1037. package/dist/components/svg-viewer/svg-viewer.styles.js.map +1 -1
  1038. package/dist/components/swatch-picker/swatch-picker.class.d.ts +71 -0
  1039. package/dist/components/swatch-picker/swatch-picker.class.d.ts.map +1 -0
  1040. package/dist/components/swatch-picker/swatch-picker.class.js +134 -0
  1041. package/dist/components/swatch-picker/swatch-picker.class.js.map +1 -0
  1042. package/dist/components/swatch-picker/swatch-picker.d.ts +2 -0
  1043. package/dist/components/swatch-picker/swatch-picker.d.ts.map +1 -0
  1044. package/dist/components/swatch-picker/swatch-picker.js +5 -0
  1045. package/dist/components/swatch-picker/swatch-picker.js.map +1 -0
  1046. package/dist/components/swatch-picker/swatch-picker.styles.d.ts +2 -0
  1047. package/dist/components/swatch-picker/swatch-picker.styles.d.ts.map +1 -0
  1048. package/dist/components/swatch-picker/swatch-picker.styles.js +131 -0
  1049. package/dist/components/swatch-picker/swatch-picker.styles.js.map +1 -0
  1050. package/dist/components/table/table.class.d.ts +85 -5
  1051. package/dist/components/table/table.class.d.ts.map +1 -1
  1052. package/dist/components/table/table.class.js +254 -41
  1053. package/dist/components/table/table.class.js.map +1 -1
  1054. package/dist/components/table/table.styles.d.ts.map +1 -1
  1055. package/dist/components/table/table.styles.js +35 -0
  1056. package/dist/components/table/table.styles.js.map +1 -1
  1057. package/dist/components/tabs/tabs.class.d.ts +6 -0
  1058. package/dist/components/tabs/tabs.class.d.ts.map +1 -1
  1059. package/dist/components/tabs/tabs.class.js +10 -1
  1060. package/dist/components/tabs/tabs.class.js.map +1 -1
  1061. package/dist/components/tabs/tabs.styles.d.ts.map +1 -1
  1062. package/dist/components/tabs/tabs.styles.js +15 -0
  1063. package/dist/components/tabs/tabs.styles.js.map +1 -1
  1064. package/dist/components/task-list/task-list.class.d.ts +89 -0
  1065. package/dist/components/task-list/task-list.class.d.ts.map +1 -0
  1066. package/dist/components/task-list/task-list.class.js +271 -0
  1067. package/dist/components/task-list/task-list.class.js.map +1 -0
  1068. package/dist/components/task-list/task-list.d.ts +2 -0
  1069. package/dist/components/task-list/task-list.d.ts.map +1 -0
  1070. package/dist/components/task-list/task-list.js +5 -0
  1071. package/dist/components/task-list/task-list.js.map +1 -0
  1072. package/dist/components/task-list/task-list.styles.d.ts +2 -0
  1073. package/dist/components/task-list/task-list.styles.d.ts.map +1 -0
  1074. package/dist/components/task-list/task-list.styles.js +134 -0
  1075. package/dist/components/task-list/task-list.styles.js.map +1 -0
  1076. package/dist/components/terminal/terminal.class.d.ts +150 -0
  1077. package/dist/components/terminal/terminal.class.d.ts.map +1 -0
  1078. package/dist/components/terminal/terminal.class.js +565 -0
  1079. package/dist/components/terminal/terminal.class.js.map +1 -0
  1080. package/dist/components/terminal/terminal.d.ts +2 -0
  1081. package/dist/components/terminal/terminal.d.ts.map +1 -0
  1082. package/dist/components/terminal/terminal.js +5 -0
  1083. package/dist/components/terminal/terminal.js.map +1 -0
  1084. package/dist/components/terminal/terminal.styles.d.ts +2 -0
  1085. package/dist/components/terminal/terminal.styles.d.ts.map +1 -0
  1086. package/dist/components/terminal/terminal.styles.js +77 -0
  1087. package/dist/components/terminal/terminal.styles.js.map +1 -0
  1088. package/dist/components/test-results/test-results.class.d.ts +99 -0
  1089. package/dist/components/test-results/test-results.class.d.ts.map +1 -0
  1090. package/dist/components/test-results/test-results.class.js +276 -0
  1091. package/dist/components/test-results/test-results.class.js.map +1 -0
  1092. package/dist/components/test-results/test-results.d.ts +2 -0
  1093. package/dist/components/test-results/test-results.d.ts.map +1 -0
  1094. package/dist/components/test-results/test-results.js +5 -0
  1095. package/dist/components/test-results/test-results.js.map +1 -0
  1096. package/dist/components/test-results/test-results.styles.d.ts +2 -0
  1097. package/dist/components/test-results/test-results.styles.d.ts.map +1 -0
  1098. package/dist/components/test-results/test-results.styles.js +118 -0
  1099. package/dist/components/test-results/test-results.styles.js.map +1 -0
  1100. package/dist/components/textarea/textarea.class.d.ts.map +1 -1
  1101. package/dist/components/textarea/textarea.class.js +4 -0
  1102. package/dist/components/textarea/textarea.class.js.map +1 -1
  1103. package/dist/components/thinking-panel/thinking-panel.class.d.ts +6 -0
  1104. package/dist/components/thinking-panel/thinking-panel.class.d.ts.map +1 -1
  1105. package/dist/components/thinking-panel/thinking-panel.class.js +12 -2
  1106. package/dist/components/thinking-panel/thinking-panel.class.js.map +1 -1
  1107. package/dist/components/thread-list/thread-list.class.d.ts +130 -0
  1108. package/dist/components/thread-list/thread-list.class.d.ts.map +1 -0
  1109. package/dist/components/thread-list/thread-list.class.js +480 -0
  1110. package/dist/components/thread-list/thread-list.class.js.map +1 -0
  1111. package/dist/components/thread-list/thread-list.d.ts +5 -0
  1112. package/dist/components/thread-list/thread-list.d.ts.map +1 -0
  1113. package/dist/components/thread-list/thread-list.js +8 -0
  1114. package/dist/components/thread-list/thread-list.js.map +1 -0
  1115. package/dist/components/thread-list/thread-list.styles.d.ts +2 -0
  1116. package/dist/components/thread-list/thread-list.styles.d.ts.map +1 -0
  1117. package/dist/components/thread-list/thread-list.styles.js +81 -0
  1118. package/dist/components/thread-list/thread-list.styles.js.map +1 -0
  1119. package/dist/components/time-range/time-range.class.d.ts.map +1 -1
  1120. package/dist/components/time-range/time-range.class.js +3 -3
  1121. package/dist/components/time-range/time-range.class.js.map +1 -1
  1122. package/dist/components/timeline/timeline-item.class.d.ts.map +1 -1
  1123. package/dist/components/timeline/timeline-item.class.js +2 -1
  1124. package/dist/components/timeline/timeline-item.class.js.map +1 -1
  1125. package/dist/components/toast/toast-item.class.d.ts +8 -0
  1126. package/dist/components/toast/toast-item.class.d.ts.map +1 -1
  1127. package/dist/components/toast/toast-item.class.js +14 -2
  1128. package/dist/components/toast/toast-item.class.js.map +1 -1
  1129. package/dist/components/toast/toast-item.styles.d.ts.map +1 -1
  1130. package/dist/components/toast/toast-item.styles.js +2 -0
  1131. package/dist/components/toast/toast-item.styles.js.map +1 -1
  1132. package/dist/components/token-input/token-input.class.d.ts +29 -3
  1133. package/dist/components/token-input/token-input.class.d.ts.map +1 -1
  1134. package/dist/components/token-input/token-input.class.js +41 -13
  1135. package/dist/components/token-input/token-input.class.js.map +1 -1
  1136. package/dist/components/token-input/token-input.styles.d.ts.map +1 -1
  1137. package/dist/components/token-input/token-input.styles.js +6 -1
  1138. package/dist/components/token-input/token-input.styles.js.map +1 -1
  1139. package/dist/components/tool-call-chip/tool-call-chip.class.d.ts +6 -0
  1140. package/dist/components/tool-call-chip/tool-call-chip.class.d.ts.map +1 -1
  1141. package/dist/components/tool-call-chip/tool-call-chip.class.js +15 -4
  1142. package/dist/components/tool-call-chip/tool-call-chip.class.js.map +1 -1
  1143. package/dist/components/tool-result-dialog/tool-result-dialog.class.d.ts +6 -0
  1144. package/dist/components/tool-result-dialog/tool-result-dialog.class.d.ts.map +1 -1
  1145. package/dist/components/tool-result-dialog/tool-result-dialog.class.js +12 -3
  1146. package/dist/components/tool-result-dialog/tool-result-dialog.class.js.map +1 -1
  1147. package/dist/components/tour/tour.class.d.ts +6 -3
  1148. package/dist/components/tour/tour.class.d.ts.map +1 -1
  1149. package/dist/components/tour/tour.class.js +56 -20
  1150. package/dist/components/tour/tour.class.js.map +1 -1
  1151. package/dist/components/trace-tree/span.d.ts +26 -0
  1152. package/dist/components/trace-tree/span.d.ts.map +1 -0
  1153. package/dist/components/trace-tree/span.js +2 -0
  1154. package/dist/components/trace-tree/span.js.map +1 -0
  1155. package/dist/components/trace-tree/trace-tree.class.d.ts +85 -0
  1156. package/dist/components/trace-tree/trace-tree.class.d.ts.map +1 -0
  1157. package/dist/components/trace-tree/trace-tree.class.js +443 -0
  1158. package/dist/components/trace-tree/trace-tree.class.js.map +1 -0
  1159. package/dist/components/trace-tree/trace-tree.d.ts +5 -0
  1160. package/dist/components/trace-tree/trace-tree.d.ts.map +1 -0
  1161. package/dist/components/trace-tree/trace-tree.js +8 -0
  1162. package/dist/components/trace-tree/trace-tree.js.map +1 -0
  1163. package/dist/components/trace-tree/trace-tree.styles.d.ts +2 -0
  1164. package/dist/components/trace-tree/trace-tree.styles.d.ts.map +1 -0
  1165. package/dist/components/trace-tree/trace-tree.styles.js +186 -0
  1166. package/dist/components/trace-tree/trace-tree.styles.js.map +1 -0
  1167. package/dist/components/transcript-feed/transcript-feed.class.d.ts +89 -0
  1168. package/dist/components/transcript-feed/transcript-feed.class.d.ts.map +1 -0
  1169. package/dist/components/transcript-feed/transcript-feed.class.js +188 -0
  1170. package/dist/components/transcript-feed/transcript-feed.class.js.map +1 -0
  1171. package/dist/components/transcript-feed/transcript-feed.d.ts +2 -0
  1172. package/dist/components/transcript-feed/transcript-feed.d.ts.map +1 -0
  1173. package/dist/components/transcript-feed/transcript-feed.js +5 -0
  1174. package/dist/components/transcript-feed/transcript-feed.js.map +1 -0
  1175. package/dist/components/transcript-feed/transcript-feed.styles.d.ts +2 -0
  1176. package/dist/components/transcript-feed/transcript-feed.styles.d.ts.map +1 -0
  1177. package/dist/components/transcript-feed/transcript-feed.styles.js +94 -0
  1178. package/dist/components/transcript-feed/transcript-feed.styles.js.map +1 -0
  1179. package/dist/components/tree/tree-node.class.d.ts +25 -4
  1180. package/dist/components/tree/tree-node.class.d.ts.map +1 -1
  1181. package/dist/components/tree/tree-node.class.js +61 -11
  1182. package/dist/components/tree/tree-node.class.js.map +1 -1
  1183. package/dist/components/tree/tree-node.styles.d.ts.map +1 -1
  1184. package/dist/components/tree/tree-node.styles.js +34 -5
  1185. package/dist/components/tree/tree-node.styles.js.map +1 -1
  1186. package/dist/components/tree/tree.class.d.ts +9 -0
  1187. package/dist/components/tree/tree.class.d.ts.map +1 -1
  1188. package/dist/components/tree/tree.class.js.map +1 -1
  1189. package/dist/components/usage-badge/usage-badge.class.d.ts +78 -0
  1190. package/dist/components/usage-badge/usage-badge.class.d.ts.map +1 -0
  1191. package/dist/components/usage-badge/usage-badge.class.js +237 -0
  1192. package/dist/components/usage-badge/usage-badge.class.js.map +1 -0
  1193. package/dist/components/usage-badge/usage-badge.d.ts +2 -0
  1194. package/dist/components/usage-badge/usage-badge.d.ts.map +1 -0
  1195. package/dist/components/usage-badge/usage-badge.js +5 -0
  1196. package/dist/components/usage-badge/usage-badge.js.map +1 -0
  1197. package/dist/components/usage-badge/usage-badge.styles.d.ts +2 -0
  1198. package/dist/components/usage-badge/usage-badge.styles.d.ts.map +1 -0
  1199. package/dist/components/usage-badge/usage-badge.styles.js +62 -0
  1200. package/dist/components/usage-badge/usage-badge.styles.js.map +1 -0
  1201. package/dist/components/virtual-list/virtual-list.class.d.ts +62 -0
  1202. package/dist/components/virtual-list/virtual-list.class.d.ts.map +1 -1
  1203. package/dist/components/virtual-list/virtual-list.class.js +123 -8
  1204. package/dist/components/virtual-list/virtual-list.class.js.map +1 -1
  1205. package/dist/components/voice-picker/voice-picker.class.d.ts +241 -0
  1206. package/dist/components/voice-picker/voice-picker.class.d.ts.map +1 -0
  1207. package/dist/components/voice-picker/voice-picker.class.js +808 -0
  1208. package/dist/components/voice-picker/voice-picker.class.js.map +1 -0
  1209. package/dist/components/voice-picker/voice-picker.d.ts +2 -0
  1210. package/dist/components/voice-picker/voice-picker.d.ts.map +1 -0
  1211. package/dist/components/voice-picker/voice-picker.js +5 -0
  1212. package/dist/components/voice-picker/voice-picker.js.map +1 -0
  1213. package/dist/components/voice-picker/voice-picker.styles.d.ts +2 -0
  1214. package/dist/components/voice-picker/voice-picker.styles.d.ts.map +1 -0
  1215. package/dist/components/voice-picker/voice-picker.styles.js +272 -0
  1216. package/dist/components/voice-picker/voice-picker.styles.js.map +1 -0
  1217. package/dist/components/widget-renderer/default-registry.d.ts +14 -0
  1218. package/dist/components/widget-renderer/default-registry.d.ts.map +1 -0
  1219. package/dist/components/widget-renderer/default-registry.js +43 -0
  1220. package/dist/components/widget-renderer/default-registry.js.map +1 -0
  1221. package/dist/components/widget-renderer/registry.d.ts +31 -0
  1222. package/dist/components/widget-renderer/registry.d.ts.map +1 -0
  1223. package/dist/components/widget-renderer/registry.js +23 -0
  1224. package/dist/components/widget-renderer/registry.js.map +1 -0
  1225. package/dist/components/widget-renderer/resolve.d.ts +48 -0
  1226. package/dist/components/widget-renderer/resolve.d.ts.map +1 -0
  1227. package/dist/components/widget-renderer/resolve.js +122 -0
  1228. package/dist/components/widget-renderer/resolve.js.map +1 -0
  1229. package/dist/components/widget-renderer/widget-renderer.class.d.ts +67 -0
  1230. package/dist/components/widget-renderer/widget-renderer.class.d.ts.map +1 -0
  1231. package/dist/components/widget-renderer/widget-renderer.class.js +175 -0
  1232. package/dist/components/widget-renderer/widget-renderer.class.js.map +1 -0
  1233. package/dist/components/widget-renderer/widget-renderer.d.ts +5 -0
  1234. package/dist/components/widget-renderer/widget-renderer.d.ts.map +1 -0
  1235. package/dist/components/widget-renderer/widget-renderer.js +10 -0
  1236. package/dist/components/widget-renderer/widget-renderer.js.map +1 -0
  1237. package/dist/components/widget-renderer/widget-renderer.styles.d.ts +2 -0
  1238. package/dist/components/widget-renderer/widget-renderer.styles.d.ts.map +1 -0
  1239. package/dist/components/widget-renderer/widget-renderer.styles.js +14 -0
  1240. package/dist/components/widget-renderer/widget-renderer.styles.js.map +1 -0
  1241. package/dist/components/word-cloud/word-cloud-layout.d.ts +4 -0
  1242. package/dist/components/word-cloud/word-cloud-layout.d.ts.map +1 -1
  1243. package/dist/components/word-cloud/word-cloud-layout.js +3 -2
  1244. package/dist/components/word-cloud/word-cloud-layout.js.map +1 -1
  1245. package/dist/components/word-cloud/word-cloud.class.d.ts.map +1 -1
  1246. package/dist/components/word-cloud/word-cloud.class.js +11 -3
  1247. package/dist/components/word-cloud/word-cloud.class.js.map +1 -1
  1248. package/dist/components/xml-viewer/xml-viewer.class.d.ts +135 -0
  1249. package/dist/components/xml-viewer/xml-viewer.class.d.ts.map +1 -0
  1250. package/dist/components/xml-viewer/xml-viewer.class.js +0 -0
  1251. package/dist/components/xml-viewer/xml-viewer.class.js.map +1 -0
  1252. package/dist/components/xml-viewer/xml-viewer.d.ts +2 -0
  1253. package/dist/components/xml-viewer/xml-viewer.d.ts.map +1 -0
  1254. package/dist/components/xml-viewer/xml-viewer.js +20 -0
  1255. package/dist/components/xml-viewer/xml-viewer.js.map +1 -0
  1256. package/dist/components/xml-viewer/xml-viewer.styles.d.ts +2 -0
  1257. package/dist/components/xml-viewer/xml-viewer.styles.d.ts.map +1 -0
  1258. package/dist/components/xml-viewer/xml-viewer.styles.js +156 -0
  1259. package/dist/components/xml-viewer/xml-viewer.styles.js.map +1 -0
  1260. package/dist/components/zoomable-frame/zoomable-frame.class.d.ts +14 -2
  1261. package/dist/components/zoomable-frame/zoomable-frame.class.d.ts.map +1 -1
  1262. package/dist/components/zoomable-frame/zoomable-frame.class.js +30 -14
  1263. package/dist/components/zoomable-frame/zoomable-frame.class.js.map +1 -1
  1264. package/dist/internal/anchor-target.d.ts +49 -0
  1265. package/dist/internal/anchor-target.d.ts.map +1 -0
  1266. package/dist/internal/anchor-target.js +255 -0
  1267. package/dist/internal/anchor-target.js.map +1 -0
  1268. package/dist/internal/ansi.d.ts +35 -0
  1269. package/dist/internal/ansi.d.ts.map +1 -0
  1270. package/dist/internal/ansi.js +210 -0
  1271. package/dist/internal/ansi.js.map +1 -0
  1272. package/dist/internal/cell-range.d.ts +19 -0
  1273. package/dist/internal/cell-range.d.ts.map +1 -0
  1274. package/dist/internal/cell-range.js +69 -0
  1275. package/dist/internal/cell-range.js.map +1 -0
  1276. package/dist/internal/intl-cache.d.ts +33 -0
  1277. package/dist/internal/intl-cache.d.ts.map +1 -0
  1278. package/dist/internal/intl-cache.js +0 -0
  1279. package/dist/internal/intl-cache.js.map +1 -0
  1280. package/dist/internal/layered-layout.d.ts +44 -0
  1281. package/dist/internal/layered-layout.d.ts.map +1 -0
  1282. package/dist/internal/layered-layout.js +172 -0
  1283. package/dist/internal/layered-layout.js.map +1 -0
  1284. package/dist/internal/localization.d.ts +12 -1
  1285. package/dist/internal/localization.d.ts.map +1 -1
  1286. package/dist/internal/localization.js +367 -4
  1287. package/dist/internal/localization.js.map +1 -1
  1288. package/dist/internal/lyra-element.d.ts +10 -1
  1289. package/dist/internal/lyra-element.d.ts.map +1 -1
  1290. package/dist/internal/lyra-element.js +19 -1
  1291. package/dist/internal/lyra-element.js.map +1 -1
  1292. package/dist/internal/root-registration-allowlist.d.ts +2 -2
  1293. package/dist/internal/root-registration-allowlist.d.ts.map +1 -1
  1294. package/dist/internal/root-registration-allowlist.js +55 -0
  1295. package/dist/internal/root-registration-allowlist.js.map +1 -1
  1296. package/dist/internal/slugger.d.ts +11 -0
  1297. package/dist/internal/slugger.d.ts.map +1 -0
  1298. package/dist/internal/slugger.js +45 -0
  1299. package/dist/internal/slugger.js.map +1 -0
  1300. package/dist/internal/text-highlights.d.ts +21 -0
  1301. package/dist/internal/text-highlights.d.ts.map +1 -0
  1302. package/dist/internal/text-highlights.js +172 -0
  1303. package/dist/internal/text-highlights.js.map +1 -0
  1304. package/dist/internal/text-quote.d.ts +53 -0
  1305. package/dist/internal/text-quote.d.ts.map +1 -0
  1306. package/dist/internal/text-quote.js +326 -0
  1307. package/dist/internal/text-quote.js.map +1 -0
  1308. package/dist/internal/tokens.styles.d.ts.map +1 -1
  1309. package/dist/internal/tokens.styles.js +49 -0
  1310. package/dist/internal/tokens.styles.js.map +1 -1
  1311. package/dist/internal/viewer-search.d.ts +18 -0
  1312. package/dist/internal/viewer-search.d.ts.map +1 -0
  1313. package/dist/internal/viewer-search.js +21 -0
  1314. package/dist/internal/viewer-search.js.map +1 -0
  1315. package/dist/lyra.d.ts +137 -2
  1316. package/dist/lyra.d.ts.map +1 -1
  1317. package/dist/lyra.js +109 -0
  1318. package/dist/lyra.js.map +1 -1
  1319. package/llms-full.txt +2682 -78
  1320. package/llms.txt +28 -2
  1321. package/package.json +157 -31
  1322. package/vscode-css-data.json +231 -0
  1323. package/vscode-html-data.json +5222 -2201
  1324. package/web-types.json +5721 -2508
@@ -5,16 +5,30 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { html, nothing, svg } from 'lit';
8
- import { property, state } from 'lit/decorators.js';
8
+ import { property, state, query } from 'lit/decorators.js';
9
9
  import { styleMap } from 'lit/directives/style-map.js';
10
10
  import { LyraElement } from '../../internal/lyra-element.js';
11
11
  import { nextId, srOnly } from '../../internal/a11y.js';
12
12
  import { prefersReducedMotion } from '../../internal/motion.js';
13
13
  import { isRtl } from '../../internal/rtl.js';
14
+ import { getScratchCtx } from '../../internal/canvas.js';
14
15
  import { styles } from './graph.styles.js';
15
16
  import { loadD3 } from './graph-loader.js';
17
+ import { convexHull, hullPathD, hullCentroidX, hullTopY } from './graph-hull.js';
18
+ import { drawGraphScene, drawPickingScene, pickColorToIndex } from './graph-canvas.js';
19
+ import { layeredLayout } from '../../internal/layered-layout.js';
20
+ import { finiteNumber, finiteRange, finiteInteger } from '../../internal/numbers.js';
16
21
  import '../skeleton/skeleton.class.js';
17
22
  const STUB_OFFSET_PX = 14; // matches the length of a typical broken-link stub in comparable UIs
23
+ const EDGE_LABEL_OFFSET_PX = 4; // perpendicular offset from the segment midpoint, in world px
24
+ const EDGE_LABEL_LENGTH_GATE_RATIO = 0.85; // label hides when its measured width exceeds this * edge length
25
+ const EDGE_LABEL_WIDTH_CACHE_MAX = 512; // distinct measured label texts kept before the oldest entry is evicted
26
+ const EXPAND_KEY_INTERVAL_MS = 500; // window for a double-Enter/Space to count as a double-activate
27
+ const EXPAND_BADGE_R = 5; // world px, the "+" badge circle radius
28
+ const EXPAND_BADGE_OFFSET = Math.SQRT1_2; // places the badge at the node's edge, diagonally upper-right
29
+ const FOCUS_HALO_PADDING = 6; // world px added to the node's own radius for the halo ring
30
+ const HULL_PADDING = 24; // world px; CSS mirrors this via stroke-width: 2 * --lyra-size-24px
31
+ const CANVAS_NODE_LABEL_MIN_ZOOM = 0.5; // canvas-only declutter -- node labels draw only at/above this scale
18
32
  /**
19
33
  * Tiny deterministic PRNG (mulberry32, public-domain) used only when `seed`
20
34
  * is set, so a node's initial x/y is reproducible instead of whatever
@@ -65,6 +79,29 @@ function normalizeLinkDash(dash) {
65
79
  return undefined;
66
80
  return dash.join(' ');
67
81
  }
82
+ /** Assigns a typed node with no explicit color a slot from the ordered categorical fallback
83
+ * palette, cycling every 8 entries (`--lyra-graph-cat-1`…`--lyra-graph-cat-8`). `index` is the
84
+ * node's `GraphNodeType`'s position in `nodeTypes`, not the node's own index in `nodes`. */
85
+ function categoricalPaletteColor(index) {
86
+ return `var(--lyra-graph-cat-${(index % 8) + 1})`;
87
+ }
88
+ /** side = r * sqrt(pi), area-matched to a circle of radius r (side^2 = pi*r^2). Half-side is what
89
+ * the path data actually needs, since both shapes are drawn centered on the origin and
90
+ * positioned via a `transform="translate(x,y)"` per tick, never via absolute cx/cy. */
91
+ function shapeHalfSide(r) {
92
+ return (r * Math.sqrt(Math.PI)) / 2;
93
+ }
94
+ /** A square, centered on the origin, side ~= 1.772 * r (area-matched to the circle of radius r). */
95
+ function squarePath(r) {
96
+ const s = shapeHalfSide(r);
97
+ return `M ${-s} ${-s} L ${s} ${-s} L ${s} ${s} L ${-s} ${s} Z`;
98
+ }
99
+ /** The same square as `squarePath()`, rotated 45 degrees: same side length, vertices at the
100
+ * half-diagonal distance (s * sqrt(2)) along each axis instead of the square's own corners. */
101
+ function diamondPath(r) {
102
+ const d = shapeHalfSide(r) * Math.SQRT2;
103
+ return `M 0 ${-d} L ${d} 0 L 0 ${d} L ${-d} 0 Z`;
104
+ }
68
105
  /**
69
106
  * `<lyra-graph>` — a force-directed node-link diagram with pan/zoom/drag.
70
107
  * Requires the optional peer deps `d3-force`/`d3-drag`/`d3-zoom`/`d3-selection`
@@ -80,26 +117,114 @@ function normalizeLinkDash(dash) {
80
117
  * already-rendered graph is a no-op; nothing re-derives already-positioned
81
118
  * nodes' x/y from the new value.
82
119
  *
120
+ * `hiddenTypes` filters nodes/links by `GraphNode.type` without discarding position state --
121
+ * `lastPositionById` remembers every node's last settled x/y across a hide/show round-trip, so
122
+ * toggling a type off and back on restores each node where it was instead of re-randomizing it.
123
+ *
124
+ * `communities` draws one translucent convex-hull blob per entry, behind links/nodes -- a hull's
125
+ * membership is the union of its own `memberIds` and every node whose `communityId` matches its
126
+ * `id`. A community with no currently-visible members (all its nodes hidden by `hiddenTypes`, or
127
+ * simply empty) renders no hull.
128
+ *
129
+ * `layout="layered"` swaps the d3-force simulation for a deterministic layered layout (see
130
+ * `src/internal/layered-layout.ts`) -- node drag is disabled in that mode, and `chargeStrength` is
131
+ * a documented no-op.
132
+ *
133
+ * `renderer="canvas"` swaps the per-node/per-link SVG DOM for a single DPR-aware `<canvas>` --
134
+ * every event/method/property behaves identically to `renderer="svg"` (the default), with hit-
135
+ * testing resolved via an offscreen color-picking canvas instead of DOM event targets. The
136
+ * documented trade-offs: no `::part(node)`/`::part(link)` styling (pixels, not elements -- theme
137
+ * via cssprops instead), no native SVG `<title>` tooltip (replaced by `part="tooltip"`), and a
138
+ * drawn focus ring instead of a CSS one. Keyboard roving/announcements are preserved through an
139
+ * offscreen `part="cursor-item"` button per node/link/hull, driving the identical roving-tabindex
140
+ * logic as `renderer="svg"`.
141
+ *
83
142
  * @customElement lyra-graph
84
- * @event lyra-node-click - `detail: { id }`.
143
+ * @event lyra-node-click - `detail: { id, x, y }`, where `x` and `y` are the
144
+ * node's current coordinates in the graph's local drawing space.
85
145
  * @event lyra-link-click - `detail: { source, target, id? }`.
146
+ * @event lyra-node-enter - A node was hovered. `detail: { id }`. Suppressed while dragging or
147
+ * panning. Also toggles a `data-hovered` attribute on that node's `[part="node"]` element for
148
+ * pure-CSS theming (not a substitute for this event — a consumer computing its own
149
+ * adjacency-based highlight needs the id, which only the event carries).
150
+ * @event lyra-node-leave - The hover from `lyra-node-enter` ended. `detail: { id }`.
151
+ * @event lyra-link-enter - A link was hovered. `detail: { source, target, id? }`. Same
152
+ * suppression/`data-hovered` behavior as `lyra-node-enter`.
153
+ * @event lyra-link-leave - The hover from `lyra-link-enter` ended. `detail: { source, target, id?
154
+ * }`.
155
+ * @event lyra-node-expand - A node was double-activated (native `dblclick`, or two Enter/Space
156
+ * activations of the same focused node within 500ms). `detail: { id }`. Fires for any node
157
+ * regardless of `GraphNode.expandable` -- that flag only controls the visual "+" affordance and
158
+ * spoken "expandable" suffix.
159
+ * @event lyra-selection-change - `detail: { nodeIds, linkIds }`. Fires when `selectionMode` is not
160
+ * `'none'` and the user activates/clears a node or link. The component never assigns
161
+ * `selectedNodeIds`/`selectedLinkIds` itself -- controlled, mirroring `lyra-heatmap.selectedCell`.
162
+ * @event lyra-community-click - A hull was activated. `detail: { id }`.
86
163
  * @csspart base - The graph wrapper.
87
164
  * @csspart svg - The graph SVG.
88
165
  * @csspart node - A graph node.
89
166
  * @csspart link - A graph link.
90
167
  * @csspart arrowhead - The marker used by directed graph links.
91
168
  * @csspart label - A node label.
169
+ * @csspart link-label - A drawn edge label (only rendered when `showEdgeLabels` is set).
170
+ * @csspart expand-indicator - The "+" badge rendered on a node with `expandable: true`.
171
+ * @csspart focus-halo - The persistent ring tracking `focusId`'s node.
172
+ * @csspart hull - A community hull (behind links/nodes; role="button").
173
+ * @csspart community-label - A hull's label text.
92
174
  * @csspart live-region - The current graph item announcement.
93
175
  * @csspart data-list - A visually hidden list alternative for graph data.
94
176
  * @csspart empty - The empty-state message, shown when `nodes` is empty.
177
+ * @csspart canvas - The single canvas surface (`renderer="canvas"` only).
178
+ * @csspart tooltip - The hover tooltip (`renderer="canvas"` only; the SVG `<title>` replacement).
179
+ * @csspart cursor-items - The container of offscreen keyboard-roving items (`renderer="canvas"` only).
180
+ * @csspart cursor-item - An offscreen keyboard-roving item (`renderer="canvas"`'s a11y virtual cursor).
95
181
  * @cssprop [--lyra-node-fill=var(--lyra-color-brand)] - Default node fill, overridden per-node by `GraphNode.color`.
96
182
  * @cssprop [--lyra-link-color=var(--lyra-color-border)] - Default link stroke, overridden per-link by a link's own `color`.
183
+ * @cssprop [--lyra-graph-cat-1..8] - Ordered categorical fallback palette for a typed node with no
184
+ * `GraphNodeType.color`, assigned by the type's index in `nodeTypes` (wraps every 8 entries).
185
+ * Declared centrally in `tokens.styles.ts` so `<lyra-graph>` and any future `<lyra-graph-legend>`-
186
+ * style component resolve the identical default.
187
+ * @cssprop [--lyra-graph-edge-label-halo=var(--lyra-color-surface)] - Legibility halo (`stroke`)
188
+ * behind a drawn edge label, painted under the fill via `paint-order: stroke`.
189
+ * @cssprop [--lyra-graph-focus-halo-color=var(--lyra-color-brand)] - `focus-halo` stroke color.
190
+ * @cssprop [--lyra-graph-selected-color=var(--lyra-color-success)] - Selected node/link stroke.
191
+ * @cssprop [--lyra-graph-hull-fill=var(--lyra-color-brand)] - Hull fill/stroke color.
192
+ * @cssprop [--lyra-graph-hull-opacity=0.12] - Hull element opacity (composites fill+stroke as one
193
+ * group, avoiding a double-opacity seam at the fill/stroke boundary).
97
194
  */
98
195
  export class LyraGraph extends LyraElement {
99
196
  constructor() {
100
197
  super(...arguments);
101
198
  this.nodes = [];
102
199
  this.links = [];
200
+ /** Declares each `GraphNode.type` value's legend label, fill color, and shape. A typed node with
201
+ * no matching entry here renders as untyped (default circle, token fill) but still participates
202
+ * in `hiddenTypes` filtering by its raw `type` string. */
203
+ this.nodeTypes = [];
204
+ /** Hides every node whose raw `type` value is listed here (no matching `nodeTypes` entry
205
+ * required), plus every link incident to a hidden node -- removed from the render, the
206
+ * simulation input, the keyboard roving ring, the sr-only data list, and the accessible
207
+ * diagram counts, as if absent. Positions round-trip via `lastPositionById`: toggling a type
208
+ * off and back on restores each node where it was. */
209
+ this.hiddenTypes = [];
210
+ /** Renders one translucent hull per entry, behind links/nodes. Membership is the union of
211
+ * `memberIds` and every node whose `communityId` matches this entry's `id`. */
212
+ this.communities = [];
213
+ /** `'force'` (default) runs the existing d3-force simulation, untouched. `'layered'` computes a
214
+ * deterministic Sugiyama-lite layout (`src/internal/layered-layout.ts`, a shared,
215
+ * dependency-free util suitable for any future layered-diagram consumer) instead -- no settle
216
+ * animation, node drag disabled (dragging would fight a computed layout), `chargeStrength` a
217
+ * documented no-op, `linkDistance` retunes the layer gap. Switching at runtime repositions
218
+ * without a tween. */
219
+ this.layout = 'force';
220
+ /** `'svg'` (default, unchanged) renders the existing per-node/per-link DOM. `'canvas'` swaps to
221
+ * a single `<canvas part="canvas">` -- the scale path (an honest ceiling for `'svg'`: dozens to
222
+ * low hundreds of nodes; `'canvas'` targets roughly 5,000 nodes / 10,000 links). Feature-reduced
223
+ * by design: no `::part(node)`/`::part(link)` styling (pixels, not elements -- theme via
224
+ * cssprops), no SVG `<title>`, a drawn focus ring instead of a CSS one. All events/methods/
225
+ * props otherwise behave identically across renderers. Runtime changes tear down and rebuild
226
+ * the surface; positions survive via `prevById`/`lastPositionById`. */
227
+ this.renderer = 'svg';
103
228
  this.width = 800;
104
229
  this.height = 600;
105
230
  this.chargeStrength = -300;
@@ -108,12 +233,42 @@ export class LyraGraph extends LyraElement {
108
233
  this.maxZoom = 8;
109
234
  /** Accessible name forwarded from the host to the semantic graph SVG. */
110
235
  this.accessibleLabel = null;
236
+ /** Draws each resolved (non-dangling) link's `label` as visible SVG text at the segment
237
+ * midpoint. Off by default — `GraphLink.label` stays spoken/tooltip-only, matching today's
238
+ * behavior, unless this is set. */
239
+ this.showEdgeLabels = false;
240
+ /** Below this zoom scale, every drawn edge label is hidden (a `data-edge-labels-hidden`
241
+ * attribute toggled on the zoomed `<g>`, no Lit re-render). Ignored when `showEdgeLabels` is
242
+ * false. */
243
+ this.edgeLabelMinZoom = 0.6;
244
+ /** Declaratively centers the camera on this node id once, the first time it resolves (on mount
245
+ * or when the id first appears in `nodes`) -- does not re-center on later mutations, so it
246
+ * can't fight a user's panning on a streaming graph. Renders a persistent halo
247
+ * (`part="focus-halo"`) around the node while set. See `focusNode()` for the imperative twin. */
248
+ this.focusId = null;
249
+ /** `'none'` (default) preserves today's behavior exactly -- no `aria-pressed`/`data-selected`,
250
+ * no `lyra-selection-change`. Controlled, mirroring `lyra-heatmap.selectedCell`: the component
251
+ * never mutates `selectedNodeIds`/`selectedLinkIds` itself, only emits intent; the host assigns
252
+ * them back. */
253
+ this.selectionMode = 'none';
254
+ this.selectedNodeIds = [];
255
+ this.selectedLinkIds = [];
111
256
  this.arrowMarkerId = nextId('graph-arrow');
112
257
  /** True until the lazy-loaded d3 peer dependencies have settled (success or failure). */
113
258
  this.loading = true;
114
259
  this.simNodes = [];
115
260
  this.simLinks = [];
116
261
  this.danglingLinks = [];
262
+ /** Every node's last-known settled position, keyed by id, independent of current visibility --
263
+ * consulted by `rebuildSimulation()` (after the existing carried-over-position map) so a
264
+ * `hiddenTypes` toggle restores a node where it was instead of re-randomizing it. Pruned to ids
265
+ * present in `this.nodes` (not just currently-visible ones) on every rebuild. */
266
+ this.lastPositionById = new Map();
267
+ /** The `hiddenNodeCount` computed by the most recent `rebuildSimulation()` -- lets that method
268
+ * tell "nothing has ever been hidden" (never touch `graphLiveText`, so a consumer that never
269
+ * sets `hiddenTypes` keeps today's exact live-region output) apart from "a hide was just
270
+ * cleared" (still announce the resulting "0 of N" count). */
271
+ this.lastHiddenNodeCount = 0;
117
272
  /** One roving tab stop across all nodes and links; nodes are the initial entry order. */
118
273
  this.activeGraphItem = 0;
119
274
  this.graphLiveText = '';
@@ -126,11 +281,165 @@ export class LyraGraph extends LyraElement {
126
281
  * simNodes/simLinks properties (see rebuildSimulation()'s doc comment). */
127
282
  this.nodeEls = [];
128
283
  this.nodeLabelEls = [];
284
+ this.expandIndicatorEls = [];
285
+ /** Tracks the index/time of the last Enter/Space activation, for double-Enter expand detection
286
+ * (mirroring native dblclick semantics for keyboard users). */
287
+ this.lastKeyActivateIndex = null;
288
+ this.lastKeyActivateTime = 0;
289
+ /** The last `focusId` value `focusNode()` was auto-invoked for by `updated()`'s declarative
290
+ * centering branch -- guards against re-centering on every update while `focusId` stays set
291
+ * (see the `focusId` property doc for why it only ever centers once per value). Reset to `null`
292
+ * whenever `focusId` itself is cleared, so the same id can center again later. */
293
+ this.lastAppliedFocusId = null;
294
+ this.communityHullEls = [];
295
+ this.communityLabelEls = [];
296
+ this.pickDirty = true;
297
+ this.canvasCamera = { k: 1, x: 0, y: 0 };
298
+ /** Flat, index-aligned list matching `drawPickingScene()`'s own hulls-then-links-then-nodes pick
299
+ * order -- rebuilt by `redrawPickCanvas()` alongside the pick canvas itself, so a pick color's
300
+ * decoded index always maps back to the exact item it was drawn for. */
301
+ this.pickItems = [];
302
+ /** Whether `canvasScene` was built with edge labels included -- the zoom gate makes the scene
303
+ * camera-dependent at exactly two thresholds (`edgeLabelMinZoom`, `CANVAS_NODE_LABEL_MIN_ZOOM`),
304
+ * so a camera-only draw that crosses either must rebuild instead of reusing the cache. */
305
+ this.canvasSceneHasEdgeLabels = false;
306
+ /** True for a camera tween's whole duration (set before its first frame, cleared on
307
+ * resolution) -- `isPanning` alone doesn't cover this: `applyZoomTransform()`'s per-frame
308
+ * `zoomBehavior.transform()` call on a non-transition selection fires d3-zoom's
309
+ * start/zoom/end synchronously within that single call, so `isPanning` flips true-then-false
310
+ * within one frame rather than staying true for the tween's real duration the way an actual
311
+ * user gesture does. */
312
+ this.isCameraTweening = false;
129
313
  this.linkEls = [];
314
+ this.linkLabelEls = [];
315
+ /** Per-simLink-index flip cache for the length declutter gate -- `onTick()` only writes
316
+ * `visibility` when the boolean actually changes, not every tick. */
317
+ this.linkLabelHiddenByLength = [];
318
+ this.edgeLabelWidthCache = new Map();
130
319
  /** Dangling-stub `<line>`s, index-aligned with `danglingLinks` -- cached separately from
131
320
  * `linkEls` (real, simulated links only) so onTick() can write their positions too; see
132
321
  * onTick()'s own comment for why a stub needs this at all. */
133
322
  this.danglingLinkEls = [];
323
+ /** Writing a transform on a plain (non-transition) selection makes d3-zoom fire its own
324
+ * start/zoom/end sequence synchronously, in this same call -- `isApplyingZoomTransform` lets
325
+ * the zoom `'start'` handler tell that self-triggered echo apart from a genuine external
326
+ * gesture, so a camera tween's own per-frame write doesn't cancel itself. */
327
+ this.isApplyingZoomTransform = false;
328
+ this.onCanvasDprChange = () => {
329
+ this.watchCanvasDpr();
330
+ this.markCanvasDirty();
331
+ };
332
+ this.onCanvasPointerDown = (e) => {
333
+ if (e.button !== 0)
334
+ return; // primary button only, matching native `click`'s own semantics
335
+ this.canvasPointerDownAt = { x: e.clientX, y: e.clientY };
336
+ if (this.layout === 'layered')
337
+ return; // drag disabled in layered mode, same as svg mode
338
+ const hit = this.hitTest(e.clientX, e.clientY);
339
+ if (hit?.kind === 'node') {
340
+ this.canvasDragNode = hit.node;
341
+ this.canvasPointerId = e.pointerId;
342
+ this.canvasEl.setPointerCapture(e.pointerId);
343
+ hit.node.fx = hit.node.x;
344
+ hit.node.fy = hit.node.y;
345
+ this.simulation?.alphaTarget(0.3).restart();
346
+ }
347
+ };
348
+ this.onCanvasPointerMove = (e) => {
349
+ if (this.canvasDragNode && this.canvasPointerId === e.pointerId) {
350
+ const rect = this.canvasEl.getBoundingClientRect();
351
+ this.canvasDragNode.fx = (e.clientX - rect.left - this.canvasCamera.x) / this.canvasCamera.k;
352
+ this.canvasDragNode.fy = (e.clientY - rect.top - this.canvasCamera.y) / this.canvasCamera.k;
353
+ this.markCanvasDirty();
354
+ return;
355
+ }
356
+ // Coalesce hover hit-testing to one per animation frame (see pendingHover's doc) -- only the
357
+ // latest position matters, and running the readback-per-pointermove would multiply the cost
358
+ // by however many moves the browser delivers between paints.
359
+ this.pendingHover = { x: e.clientX, y: e.clientY };
360
+ if (this.hoverRafId != null)
361
+ return;
362
+ this.hoverRafId = requestAnimationFrame(() => {
363
+ this.hoverRafId = undefined;
364
+ const pending = this.pendingHover;
365
+ this.pendingHover = undefined;
366
+ if (!pending)
367
+ return;
368
+ // While the force simulation is still ticking, every tick invalidates the pick canvas, so
369
+ // resolving hover here would re-render the full offscreen picking scene once per frame on
370
+ // top of the per-tick visible redraw -- and the result would be stale a frame later anyway,
371
+ // since positions are still moving. Defer hover resolution until the layout settles; the
372
+ // next pointermove after that picks it up.
373
+ if (this.pickDirty && this.simulationIsTicking())
374
+ return;
375
+ const hit = this.hitTest(pending.x, pending.y);
376
+ this.updateCanvasTooltip(hit, pending.x, pending.y);
377
+ });
378
+ };
379
+ this.onCanvasPointerUp = (e) => {
380
+ // Starting a drag on a node (onCanvasPointerDown) and ending it here without ever crossing the
381
+ // move-distance threshold below is exactly a plain click -- release the drag state first, but
382
+ // keep going into the same click-vs-drag distance check every pointerup goes through, instead
383
+ // of returning early and silently swallowing the click. This mirrors svg mode, where a plain
384
+ // click on a node fires both d3-drag's own start/end (a no-op, since fx/fy never actually
385
+ // moved) and the browser's native `click` event -- the two aren't mutually exclusive there
386
+ // either.
387
+ if (this.canvasDragNode && this.canvasPointerId === e.pointerId) {
388
+ this.simulation?.alphaTarget(0);
389
+ this.canvasDragNode.fx = null;
390
+ this.canvasDragNode.fy = null;
391
+ this.canvasDragNode = undefined;
392
+ this.canvasPointerId = undefined;
393
+ this.markCanvasDirty();
394
+ }
395
+ const down = this.canvasPointerDownAt;
396
+ this.canvasPointerDownAt = undefined;
397
+ if (!down)
398
+ return;
399
+ if (Math.hypot(e.clientX - down.x, e.clientY - down.y) > 5)
400
+ return; // a pan/drag gesture, not a click
401
+ const hit = this.hitTest(e.clientX, e.clientY);
402
+ if (!hit) {
403
+ this.clearSelection();
404
+ return;
405
+ }
406
+ if (hit.kind === 'node')
407
+ this.onNodeClick(hit.node, e);
408
+ else if (hit.kind === 'link')
409
+ this.onLinkClick(hit.link, e);
410
+ else
411
+ this.onCommunityClick(hit.entry.community);
412
+ };
413
+ this.onCanvasPointerLeave = () => {
414
+ // Drop any coalesced hover still waiting on its frame -- letting it run after the pointer
415
+ // already left would re-show the tooltip this handler is about to hide.
416
+ this.pendingHover = undefined;
417
+ if (this.hoverRafId != null) {
418
+ cancelAnimationFrame(this.hoverRafId);
419
+ this.hoverRafId = undefined;
420
+ }
421
+ this.updateCanvasTooltip(undefined, 0, 0);
422
+ };
423
+ this.onCanvasDblClick = (e) => {
424
+ const hit = this.hitTest(e.clientX, e.clientY);
425
+ const node = hit?.kind === 'node' ? hit.node : this.nodeAtCanvasPoint(e.clientX, e.clientY);
426
+ if (!node)
427
+ return; // background dblclick still reaches d3-zoom's own zoom-in, same as svg mode
428
+ // d3-zoom's own default double-click-to-zoom-in handler is bound to this identical <canvas>
429
+ // element (not an ancestor, so plain stopPropagation() -- which only blocks *bubbling*, not a
430
+ // sibling listener on the very same target -- would not suppress it). Matches svg mode's own
431
+ // onNodeDblClick(), which stops the equivalent bubble-phase echo on the svg one level up.
432
+ e.stopImmediatePropagation();
433
+ this.emit('lyra-node-expand', { id: node.id });
434
+ };
435
+ /** Suppresses hover events/`data-hovered` while a node drag is in progress (tracked from the
436
+ * existing d3-drag `.on('start')`/`.on('end')` handlers in `applyInteractions()`) — a drag
437
+ * crossing over other nodes/links would otherwise spam enter/leave pairs unrelated to genuine
438
+ * pointer hovering. */
439
+ this.isDragging = false;
440
+ /** Same purpose as `isDragging`, for d3-zoom pan/zoom gestures (tracked from `applyInteractions()`'s
441
+ * zoom `.on('start')`/`.on('end')` handlers, added by this same change). */
442
+ this.isPanning = false;
134
443
  }
135
444
  static { this.styles = [LyraElement.styles, styles, srOnly]; }
136
445
  connectedCallback() {
@@ -146,6 +455,16 @@ export class LyraGraph extends LyraElement {
146
455
  // the existing simulation in place instead.
147
456
  if (this.d3) {
148
457
  this.simulation?.restart();
458
+ // renderer="canvas" mode's own resize/DPR watchers are torn down by disconnectedCallback()
459
+ // below on every disconnect (including this reconnect) -- the <canvas> element itself
460
+ // survived the reparent along with the rest of this shadow tree (canvasEl === zoomedEl still
461
+ // holds), so re-arm them in place instead of waiting for a property-driven update that a bare
462
+ // reparent never triggers.
463
+ if (this.renderer === 'canvas' && this.canvasEl && this.canvasEl === this.zoomedEl) {
464
+ this.watchCanvasResize();
465
+ this.watchCanvasDpr();
466
+ this.markCanvasDirty();
467
+ }
149
468
  return;
150
469
  }
151
470
  void loadD3().then((mods) => {
@@ -162,6 +481,21 @@ export class LyraGraph extends LyraElement {
162
481
  disconnectedCallback() {
163
482
  super.disconnectedCallback();
164
483
  this.simulation?.stop();
484
+ // An in-flight focusNode()/fit() tween would otherwise keep scheduling frames and writing
485
+ // zoom transforms against the detached tree -- cancel it (which also settles the caller's
486
+ // pending Promise with `false` instead of leaving it hanging forever).
487
+ this.cancelCameraTween();
488
+ this.canvasResizeObserver?.disconnect();
489
+ this.canvasDprQuery?.removeEventListener('change', this.onCanvasDprChange);
490
+ if (this.canvasDrawRafId != null) {
491
+ cancelAnimationFrame(this.canvasDrawRafId);
492
+ this.canvasDrawRafId = undefined;
493
+ }
494
+ if (this.hoverRafId != null) {
495
+ cancelAnimationFrame(this.hoverRafId);
496
+ this.hoverRafId = undefined;
497
+ }
498
+ this.pendingHover = undefined;
165
499
  }
166
500
  /**
167
501
  * A caller-supplied `radius` is clamped to [MIN_RADIUS, MAX_RADIUS] (and a
@@ -174,6 +508,630 @@ export class LyraGraph extends LyraElement {
174
508
  const r = n.radius ?? (MIN_RADIUS + MAX_RADIUS) / 2;
175
509
  return Number.isFinite(r) ? Math.min(MAX_RADIUS, Math.max(MIN_RADIUS, r)) : (MIN_RADIUS + MAX_RADIUS) / 2;
176
510
  }
511
+ /** `width`/`height` normalized to a finite, positive viewport size — an invalid attribute value
512
+ * would otherwise flow straight into `forceCenter`, the SVG `viewBox`, and the canvas backing
513
+ * store's `width`/`height`, producing `NaN` geometry/transforms that silently render nothing
514
+ * instead of erroring. */
515
+ get safeWidth() {
516
+ return finiteRange(this.width, 800, 1);
517
+ }
518
+ get safeHeight() {
519
+ return finiteRange(this.height, 600, 1);
520
+ }
521
+ /** `minZoom`/`maxZoom` normalized to finite, positive scale bounds before ever reaching
522
+ * d3-zoom's `scaleExtent()` or a camera-clamp `Math.min`/`Math.max` — a non-finite bound would
523
+ * otherwise poison every subsequent zoom/pan computation with `NaN`. */
524
+ get safeMinZoom() {
525
+ return finiteRange(this.minZoom, 0.1, 0.001, 1000);
526
+ }
527
+ get safeMaxZoom() {
528
+ return finiteRange(this.maxZoom, 8, 0.001, 1000);
529
+ }
530
+ /** `edgeLabelMinZoom` is compared directly against the live camera scale (same domain as
531
+ * `minZoom`/`maxZoom`), so it's normalized with the same bounds -- a non-finite value would
532
+ * otherwise make every `>=`/`<` comparison against it silently `false`/`true` forever. */
533
+ get safeEdgeLabelMinZoom() {
534
+ return finiteRange(this.edgeLabelMinZoom, 0.6, 0.001, 1000);
535
+ }
536
+ /** `seed`, normalized to a finite integer when set -- `undefined` (unseeded/random) is left
537
+ * untouched, since it's a meaningful third state, not a missing number. Without this,
538
+ * `hashNodeSeed`/`mulberry32`'s `>>> 0` coercion would silently fold `NaN`/`Infinity` to `0`
539
+ * instead of normalizing an out-of-range attribute value the way every other numeric prop here
540
+ * does. */
541
+ get safeSeed() {
542
+ return this.seed == null ? undefined : finiteInteger(this.seed, 0);
543
+ }
544
+ /** `chargeStrength` is a signed d3-force strength (negative = repulsion, positive = attraction)
545
+ * — only guarded for finiteness, not clamped to a range, since either sign is a legitimate
546
+ * value. */
547
+ get safeChargeStrength() {
548
+ return finiteNumber(this.chargeStrength, -300);
549
+ }
550
+ /** `linkDistance` normalized to a finite, non-negative pixel distance — feeds `forceLink()`'s
551
+ * `distance()`, the layered layout's `gapY`, and the neighbor-jitter spawn radius, none of
552
+ * which have a sane meaning for a negative/non-finite value. */
553
+ get safeLinkDistance() {
554
+ return finiteRange(this.linkDistance, 100, 0);
555
+ }
556
+ resolveNodeType(node) {
557
+ return node.type != null ? this.nodeTypes.find((t) => t.id === node.type) : undefined;
558
+ }
559
+ nodeShape(node) {
560
+ return this.resolveNodeType(node)?.shape ?? 'circle';
561
+ }
562
+ /** Resolution precedence: `node.color` (existing, most specific) > matched `GraphNodeType.color`
563
+ * > the ordered categorical fallback palette by the type's index in `nodeTypes` > (returns
564
+ * `undefined`, letting the untyped `--lyra-node-fill` token default apply). Both data-driven
565
+ * color sources pass the existing `sanitizeNodeColor()`. */
566
+ nodeFill(node) {
567
+ const ownColor = sanitizeNodeColor(node.color);
568
+ if (ownColor)
569
+ return ownColor;
570
+ const type = this.resolveNodeType(node);
571
+ if (!type)
572
+ return undefined;
573
+ const typeColor = sanitizeNodeColor(type.color);
574
+ if (typeColor)
575
+ return typeColor;
576
+ return categoricalPaletteColor(this.nodeTypes.indexOf(type));
577
+ }
578
+ /** `this.nodes` filtered down to the ids `hiddenTypes` doesn't hide -- an untyped node (`type ==
579
+ * null`) is never hidden, regardless of `hiddenTypes`' contents. */
580
+ visibleNodes() {
581
+ if (!this.hiddenTypes.length)
582
+ return this.nodes;
583
+ const hidden = new Set(this.hiddenTypes);
584
+ return this.nodes.filter((n) => n.type == null || !hidden.has(n.type));
585
+ }
586
+ /** Resolves `this.links` against an already-built `byId` node map: a link whose source isn't in
587
+ * `byId` is dropped (hidden source, or a genuinely missing one); a link whose target isn't in
588
+ * `byId` either stubs as a dangling link (target id doesn't exist in `this.nodes` at all) or is
589
+ * dropped (target exists but is hidden by `hiddenTypes`). Shared by both the force and layered
590
+ * layout paths in `rebuildSimulation()`. */
591
+ resolveLinksAgainst(byId) {
592
+ const nodeExists = new Set(this.nodes.map((n) => n.id));
593
+ const resolved = [];
594
+ const dangling = [];
595
+ for (const l of this.links) {
596
+ const source = byId.get(l.source);
597
+ if (!source)
598
+ continue;
599
+ const target = byId.get(l.target);
600
+ if (target) {
601
+ resolved.push({ ...l, source, target });
602
+ }
603
+ else if (!nodeExists.has(l.target)) {
604
+ dangling.push({ ...l, source, target: { id: l.target, x: source.x, y: source.y }, dangling: true });
605
+ }
606
+ }
607
+ return { resolved, dangling };
608
+ }
609
+ /** A community's currently-visible members -- the union of `memberIds` and every currently
610
+ * simulated node (already filtered by `hiddenTypes`) whose `communityId` matches. */
611
+ communityMembers(community) {
612
+ const idSet = new Set(community.memberIds);
613
+ return this.simNodes.filter((n) => idSet.has(n.id) || n.communityId === community.id);
614
+ }
615
+ /** `communities` narrowed to entries with at least one currently-visible member -- a community
616
+ * whose members are all hidden by `hiddenTypes` (or that starts out empty) draws no hull and
617
+ * doesn't occupy a roving-ring slot. */
618
+ visibleCommunities() {
619
+ if (!this.visibleCommunitiesCache) {
620
+ this.visibleCommunitiesCache = this.communities
621
+ .map((community) => ({ community, members: this.communityMembers(community) }))
622
+ .filter((entry) => entry.members.length > 0);
623
+ }
624
+ return this.visibleCommunitiesCache;
625
+ }
626
+ communityHull(members) {
627
+ return convexHull(members.map((n) => ({ x: n.x ?? 0, y: n.y ?? 0 })));
628
+ }
629
+ onCommunityClick(community) {
630
+ this.emit('lyra-community-click', { id: community.id });
631
+ }
632
+ cameraTransitionMs() {
633
+ const parsed = parseFloat(getComputedStyle(this).getPropertyValue('--lyra-transition-base'));
634
+ return Number.isFinite(parsed) ? parsed : 180;
635
+ }
636
+ cancelCameraTween() {
637
+ if (this.cameraTweenId != null) {
638
+ cancelAnimationFrame(this.cameraTweenId);
639
+ this.cameraTweenId = undefined;
640
+ }
641
+ this.isCameraTweening = false;
642
+ const resolve = this.cameraTweenResolve;
643
+ if (resolve) {
644
+ this.cameraTweenResolve = undefined;
645
+ resolve(false);
646
+ }
647
+ }
648
+ applyZoomTransform(transform) {
649
+ if (!this.d3 || !this.zoomedEl || !this.zoomBehavior)
650
+ return;
651
+ this.isApplyingZoomTransform = true;
652
+ try {
653
+ this.zoomBehavior.transform(this.d3.select(this.zoomedEl), transform);
654
+ }
655
+ finally {
656
+ this.isApplyingZoomTransform = false;
657
+ }
658
+ }
659
+ /** Animates from the zoom behavior's current transform toward `computeTarget()`'s result via a
660
+ * rAF tween that calls `zoomBehavior.transform()` every frame -- keeps d3-zoom's own internal
661
+ * state consistent (so the next user pan doesn't jump), unlike writing the `<g>` transform
662
+ * attribute directly. `computeTarget` is re-invoked on every single frame (not read once
663
+ * up-front) so the tween keeps tracking a still-settling force simulation's live node positions
664
+ * instead of tweening toward a stale snapshot from the moment the call was made --
665
+ * `focusNode()`/`fit()` are just as likely to run while the graph is still animating its initial
666
+ * layout as after it's settled. `prefers-reduced-motion` jumps straight to one write of the
667
+ * then-current target. A concurrent call cancels the previous tween -- resolves `true` on
668
+ * genuine arrival, `false` if superseded or interrupted by a user gesture before completing. */
669
+ tweenCamera(computeTarget) {
670
+ return new Promise((resolve) => {
671
+ if (!this.d3 || !this.zoomedEl || !this.zoomBehavior) {
672
+ resolve(false);
673
+ return;
674
+ }
675
+ this.cancelCameraTween();
676
+ this.cameraTweenResolve = resolve;
677
+ this.isCameraTweening = true;
678
+ if (prefersReducedMotion()) {
679
+ this.applyZoomTransform(computeTarget());
680
+ this.isCameraTweening = false;
681
+ this.cameraTweenResolve = undefined;
682
+ resolve(true);
683
+ return;
684
+ }
685
+ const current = this.d3.zoomTransform(this.zoomedEl);
686
+ const duration = this.cameraTransitionMs();
687
+ const start = performance.now();
688
+ const startK = current.k;
689
+ const startX = current.x;
690
+ const startY = current.y;
691
+ const step = (now) => {
692
+ const t = duration > 0 ? Math.min(1, (now - start) / duration) : 1;
693
+ const target = computeTarget();
694
+ const targetK = target.k;
695
+ const targetX = target.x;
696
+ const targetY = target.y;
697
+ this.applyZoomTransform(this.d3.zoomIdentity
698
+ .translate(startX + (targetX - startX) * t, startY + (targetY - startY) * t)
699
+ .scale(startK + (targetK - startK) * t));
700
+ if (t < 1) {
701
+ this.cameraTweenId = requestAnimationFrame(step);
702
+ }
703
+ else {
704
+ this.cameraTweenId = undefined;
705
+ this.isCameraTweening = false;
706
+ this.cameraTweenResolve = undefined;
707
+ resolve(true);
708
+ }
709
+ };
710
+ this.cameraTweenId = requestAnimationFrame(step);
711
+ });
712
+ }
713
+ /** Animates the camera so `id` centers in the viewport (the `width` x `height` viewBox), at
714
+ * `options.zoom` (clamped to `[minZoom, maxZoom]`) or the current scale when omitted. Resolves
715
+ * `true` on arrival; `false` for an id with no matching entry in `simNodes` -- there's nothing
716
+ * to center on. Announces `graphNodeFocused` through the existing live region. Does not move DOM
717
+ * focus -- this is a camera operation, not a roving-focus one. */
718
+ async focusNode(id, options) {
719
+ const node = this.simNodes.find((n) => n.id === id);
720
+ if (!node || !this.d3 || !this.zoomedEl || !this.zoomBehavior)
721
+ return false;
722
+ const current = this.d3.zoomTransform(this.zoomedEl);
723
+ const k = Math.min(this.safeMaxZoom, Math.max(this.safeMinZoom, options?.zoom ?? current.k));
724
+ const arrived = await this.tweenCamera(() => this.d3.zoomIdentity
725
+ .translate(this.safeWidth / 2 - k * (node.x ?? 0), this.safeHeight / 2 - k * (node.y ?? 0))
726
+ .scale(k));
727
+ if (arrived) {
728
+ this.graphLiveText = this.localize('graphNodeFocused', undefined, { label: this.nodeAccessibleText(node) });
729
+ }
730
+ return arrived;
731
+ }
732
+ /** Animates the camera to frame the bounding box of every currently visible node position (plus
733
+ * each node's own radius) at the largest scale that fits within `width` x `height` minus
734
+ * `padding` viewport-px on each side (clamped to `[minZoom, maxZoom]`). Silent -- no data
735
+ * changed, so no announcement. A no-op with no visible nodes. */
736
+ fit(options) {
737
+ if (!this.d3 || !this.zoomedEl || !this.zoomBehavior || !this.simNodes.length)
738
+ return;
739
+ const padding = options?.padding ?? 24;
740
+ void this.tweenCamera(() => {
741
+ let minX = Infinity;
742
+ let minY = Infinity;
743
+ let maxX = -Infinity;
744
+ let maxY = -Infinity;
745
+ for (const n of this.simNodes) {
746
+ const r = this.nodeRadius(n);
747
+ minX = Math.min(minX, (n.x ?? 0) - r);
748
+ maxX = Math.max(maxX, (n.x ?? 0) + r);
749
+ minY = Math.min(minY, (n.y ?? 0) - r);
750
+ maxY = Math.max(maxY, (n.y ?? 0) + r);
751
+ }
752
+ for (const entry of this.visibleCommunities()) {
753
+ for (const p of this.communityHull(entry.members)) {
754
+ minX = Math.min(minX, p.x - HULL_PADDING);
755
+ maxX = Math.max(maxX, p.x + HULL_PADDING);
756
+ minY = Math.min(minY, p.y - HULL_PADDING);
757
+ maxY = Math.max(maxY, p.y + HULL_PADDING);
758
+ }
759
+ }
760
+ const boxW = Math.max(1, maxX - minX);
761
+ const boxH = Math.max(1, maxY - minY);
762
+ const availW = Math.max(1, this.safeWidth - padding * 2);
763
+ const availH = Math.max(1, this.safeHeight - padding * 2);
764
+ const k = Math.min(this.safeMaxZoom, Math.max(this.safeMinZoom, Math.min(availW / boxW, availH / boxH)));
765
+ const cx = (minX + maxX) / 2;
766
+ const cy = (minY + maxY) / 2;
767
+ return this.d3.zoomIdentity.translate(this.safeWidth / 2 - k * cx, this.safeHeight / 2 - k * cy).scale(k);
768
+ });
769
+ }
770
+ updateFocusHalo() {
771
+ if (!this.focusHaloEl)
772
+ return;
773
+ const node = this.focusId != null ? this.simNodes.find((n) => n.id === this.focusId) : undefined;
774
+ if (node) {
775
+ this.focusHaloEl.setAttribute('cx', String(node.x ?? 0));
776
+ this.focusHaloEl.setAttribute('cy', String(node.y ?? 0));
777
+ this.focusHaloEl.setAttribute('r', String(this.nodeRadius(node) + FOCUS_HALO_PADDING));
778
+ this.focusHaloEl.removeAttribute('hidden');
779
+ }
780
+ else {
781
+ this.focusHaloEl.setAttribute('hidden', '');
782
+ }
783
+ }
784
+ // ---------------------------------------------------------------------------------------------
785
+ // renderer="canvas": surface setup, DPR/resize watching, scene building, and the static draw.
786
+ // ---------------------------------------------------------------------------------------------
787
+ setUpCanvasSurface() {
788
+ this.canvasCtx = this.canvasEl.getContext('2d') ?? undefined;
789
+ this.pickCanvas = document.createElement('canvas');
790
+ this.pickCtx = this.pickCanvas.getContext('2d', { willReadFrequently: true });
791
+ this.watchCanvasResize();
792
+ this.watchCanvasDpr();
793
+ this.canvasTooltipEl = this.renderRoot.querySelector('[part="tooltip"]') ?? undefined;
794
+ // bindCanvasPointer() (which owns onCanvasDblClick) is bound BEFORE bindCanvasZoom() -- both
795
+ // end up with a 'dblclick' listener on this same <canvas>, and d3-zoom's own default
796
+ // double-click-to-zoom-in handler calls stopImmediatePropagation() unconditionally (see
797
+ // onCanvasDblClick()'s own comment). Registering first means onCanvasDblClick() runs first and
798
+ // gets the chance to itself stop the event (only when it actually hit a node) before d3-zoom's
799
+ // handler would otherwise suppress it from ever being observed at all.
800
+ this.bindCanvasPointer();
801
+ this.bindCanvasZoom();
802
+ }
803
+ watchCanvasResize() {
804
+ // Re-arming replaces the observer instance -- disconnect the previous one first, or a
805
+ // canvas -> svg -> canvas renderer round trip leaves an orphaned observer still watching the
806
+ // host (disconnectedCallback only ever cleans up whichever instance is current).
807
+ this.canvasResizeObserver?.disconnect();
808
+ this.canvasResizeObserver = new ResizeObserver(() => this.markCanvasDirty());
809
+ this.canvasResizeObserver.observe(this);
810
+ }
811
+ watchCanvasDpr() {
812
+ // A MediaQueryList's `matches` is fixed at creation time, so crossing the DPR threshold it was
813
+ // built for means building a fresh one for the new ratio -- remove the previous instance's
814
+ // listener first, or it leaks (disconnectedCallback only ever cleans up whichever is current).
815
+ this.canvasDprQuery?.removeEventListener('change', this.onCanvasDprChange);
816
+ this.canvasDprQuery = matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
817
+ this.canvasDprQuery.addEventListener('change', this.onCanvasDprChange);
818
+ }
819
+ markCanvasDirty() {
820
+ this.canvasScene = undefined;
821
+ this.pickDirty = true;
822
+ this.scheduleCanvasDraw();
823
+ }
824
+ /** The camera-only sibling of `markCanvasDirty()`: a pan/zoom moves the camera but leaves every
825
+ * world-space scene value (positions, colors, labels) untouched, so the cached `canvasScene`
826
+ * stays valid and only needs redrawing under the new transform. The pick canvas bakes the
827
+ * camera transform into its pixels, though, so it still needs a redraw before the next hit
828
+ * test. */
829
+ markCanvasCameraDirty() {
830
+ this.pickDirty = true;
831
+ this.scheduleCanvasDraw();
832
+ }
833
+ scheduleCanvasDraw() {
834
+ if (this.canvasDrawRafId != null)
835
+ return;
836
+ this.canvasDrawRafId = requestAnimationFrame(() => {
837
+ this.canvasDrawRafId = undefined;
838
+ this.drawCanvas();
839
+ });
840
+ }
841
+ /** Canvas 2D's `fillStyle`/`strokeStyle` don't accept a raw `var(--x)` string the way an inline
842
+ * SVG `style` attribute does -- resolves it to the actual cascaded color via `getComputedStyle`
843
+ * first (the same "canvas can't consume var() directly" resolution `<lyra-heatmap>` already
844
+ * uses for its own canvas-drawn tokens). `value` untouched when it isn't a bare `var(...)` ref
845
+ * (a literal `GraphNode.color`/`GraphLink.color` hex/rgb string already resolves fine as-is). */
846
+ resolveCssColorValue(value, cs) {
847
+ const match = value.match(/^var\((--[\w-]+)/);
848
+ if (!match)
849
+ return value;
850
+ return cs.getPropertyValue(match[1]).trim() || value;
851
+ }
852
+ buildCanvasScene(cs) {
853
+ const hullFillDefault = cs.getPropertyValue('--lyra-graph-hull-fill').trim() || cs.getPropertyValue('--lyra-color-brand').trim();
854
+ const hulls = this.visibleCommunities().map((entry) => ({
855
+ d: hullPathD(this.communityHull(entry.members)),
856
+ fill: sanitizeNodeColor(entry.community.color) ?? hullFillDefault,
857
+ }));
858
+ const linkColorDefault = cs.getPropertyValue('--lyra-link-color').trim() || cs.getPropertyValue('--lyra-color-border').trim();
859
+ const links = this.simLinks.map((l) => {
860
+ const coords = this.linkCoordinates(l);
861
+ const own = sanitizeNodeColor(l.color);
862
+ return {
863
+ x1: coords.x1,
864
+ y1: coords.y1,
865
+ x2: coords.x2,
866
+ y2: coords.y2,
867
+ color: own ? this.resolveCssColorValue(own, cs) : linkColorDefault,
868
+ width: l.width ?? 1.5,
869
+ dash: l.dash,
870
+ directed: l.directed,
871
+ selected: this.isSelected('link', this.linkKey(l)),
872
+ };
873
+ });
874
+ const edgeLabels = this.showEdgeLabels && this.canvasCamera.k >= this.safeEdgeLabelMinZoom
875
+ ? this.simLinks
876
+ .filter((l) => l.label)
877
+ .map((l) => {
878
+ const pos = this.edgeLabelPosition(l);
879
+ const coords = this.linkCoordinates(l);
880
+ const edgeLength = Math.hypot(coords.x2 - coords.x1, coords.y2 - coords.y1);
881
+ const tooLong = this.edgeLabelWidth(l.label) > edgeLength * EDGE_LABEL_LENGTH_GATE_RATIO;
882
+ return { x: pos.x, y: pos.y, text: l.label, tooLong };
883
+ })
884
+ .filter((l) => !l.tooLong)
885
+ .map(({ x, y, text }) => ({ x, y, text }))
886
+ : [];
887
+ const nodeFillDefault = cs.getPropertyValue('--lyra-node-fill').trim() || cs.getPropertyValue('--lyra-color-brand').trim();
888
+ const nodes = this.simNodes.map((n) => {
889
+ const fill = this.nodeFill(n);
890
+ return {
891
+ x: n.x ?? 0,
892
+ y: n.y ?? 0,
893
+ r: this.nodeRadius(n),
894
+ shape: this.nodeShape(n),
895
+ fill: fill ? this.resolveCssColorValue(fill, cs) : nodeFillDefault,
896
+ selected: this.isSelected('node', n.id),
897
+ };
898
+ });
899
+ const nodeLabels = this.simNodes
900
+ .filter((n) => n.label)
901
+ .map((n) => ({ x: (n.x ?? 0) + this.nodeRadius(n) + 2, y: n.y ?? 0, text: n.label }));
902
+ const focusNode = this.focusId != null ? this.simNodes.find((n) => n.id === this.focusId) : undefined;
903
+ const activeNode = this.activeGraphItem >= 0 && this.activeGraphItem < this.simNodes.length
904
+ ? this.simNodes[this.activeGraphItem]
905
+ : undefined;
906
+ return {
907
+ hulls,
908
+ links,
909
+ edgeLabels,
910
+ nodes,
911
+ nodeLabels,
912
+ focusHalo: focusNode
913
+ ? { x: focusNode.x ?? 0, y: focusNode.y ?? 0, r: this.nodeRadius(focusNode) + FOCUS_HALO_PADDING }
914
+ : undefined,
915
+ keyboardFocusRing: activeNode
916
+ ? { x: activeNode.x ?? 0, y: activeNode.y ?? 0, r: this.nodeRadius(activeNode) + 4 }
917
+ : undefined,
918
+ showNodeLabels: this.canvasCamera.k >= CANVAS_NODE_LABEL_MIN_ZOOM,
919
+ haloColor: cs.getPropertyValue('--lyra-graph-focus-halo-color').trim() || cs.getPropertyValue('--lyra-color-brand').trim(),
920
+ selectedColor: cs.getPropertyValue('--lyra-graph-selected-color').trim() || cs.getPropertyValue('--lyra-color-success').trim(),
921
+ labelColor: cs.getPropertyValue('--lyra-color-text').trim(),
922
+ labelHaloColor: cs.getPropertyValue('--lyra-graph-edge-label-halo').trim() || cs.getPropertyValue('--lyra-color-surface').trim(),
923
+ font: `${this.edgeLabelFontPx()}px ${cs.getPropertyValue('--lyra-font').trim() || 'sans-serif'}`,
924
+ };
925
+ }
926
+ /** Sizes the backing store to the canvas's own rendered CSS box (`clientWidth`/`clientHeight`,
927
+ * themselves stretched to fill the host via `[part="base"]`/`[part="canvas"]`'s `100%` sizing)
928
+ * times `devicePixelRatio`, only touching `width`/`height` when the target actually changed --
929
+ * reassigning either unconditionally would implicitly clear the canvas and reset its transform
930
+ * on every single draw, even a pure pan/zoom repaint. Mirrors `<lyra-heatmap>`'s own DPR-scaled
931
+ * backing-store convention (`watchDpr()`/`onDprChange()`), adapted to `setTransform()` (an
932
+ * absolute reset) rather than a relative `scale()`, since this canvas -- unlike heatmap's, which
933
+ * always resizes its backing store on every draw -- only resizes conditionally. */
934
+ drawCanvas() {
935
+ if (!this.canvasEl || !this.canvasCtx)
936
+ return;
937
+ const dpr = window.devicePixelRatio || 1;
938
+ const w = this.canvasEl.clientWidth || this.safeWidth;
939
+ const h = this.canvasEl.clientHeight || this.safeHeight;
940
+ const backingW = Math.round(w * dpr);
941
+ const backingH = Math.round(h * dpr);
942
+ if (this.canvasEl.width !== backingW || this.canvasEl.height !== backingH) {
943
+ this.canvasEl.width = backingW;
944
+ this.canvasEl.height = backingH;
945
+ }
946
+ const ctx = this.canvasCtx;
947
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
948
+ ctx.clearRect(0, 0, w, h);
949
+ // Reuse the cached scene for a camera-only repaint; rebuild when it was invalidated
950
+ // (markCanvasDirty()) or when the camera crossed one of the two label-visibility zoom gates
951
+ // the scene bakes in (see canvasSceneHasEdgeLabels' doc).
952
+ const edgeLabelsVisible = this.showEdgeLabels && this.canvasCamera.k >= this.safeEdgeLabelMinZoom;
953
+ const nodeLabelsVisible = this.canvasCamera.k >= CANVAS_NODE_LABEL_MIN_ZOOM;
954
+ if (!this.canvasScene ||
955
+ this.canvasScene.showNodeLabels !== nodeLabelsVisible ||
956
+ this.canvasSceneHasEdgeLabels !== edgeLabelsVisible) {
957
+ this.canvasScene = this.buildCanvasScene(getComputedStyle(this));
958
+ this.canvasSceneHasEdgeLabels = edgeLabelsVisible;
959
+ }
960
+ drawGraphScene(ctx, this.canvasCamera, this.canvasScene);
961
+ }
962
+ // ---------------------------------------------------------------------------------------------
963
+ // renderer="canvas": color-picking hit-testing, pointer interaction, and the hover tooltip.
964
+ // ---------------------------------------------------------------------------------------------
965
+ rebuildPickItems() {
966
+ this.pickItems = [
967
+ ...this.visibleCommunities().map((entry) => ({ kind: 'hull', entry })),
968
+ ...this.simLinks.map((link) => ({ kind: 'link', link })),
969
+ ...this.simNodes.map((node) => ({ kind: 'node', node })),
970
+ ];
971
+ }
972
+ redrawPickCanvas() {
973
+ if (!this.pickCtx || !this.canvasEl || !this.pickCanvas)
974
+ return;
975
+ if (this.pickCanvas.width !== this.canvasEl.width || this.pickCanvas.height !== this.canvasEl.height) {
976
+ this.pickCanvas.width = this.canvasEl.width;
977
+ this.pickCanvas.height = this.canvasEl.height;
978
+ }
979
+ this.rebuildPickItems();
980
+ const dpr = window.devicePixelRatio || 1;
981
+ this.pickCtx.setTransform(dpr, 0, 0, dpr, 0, 0);
982
+ drawPickingScene(this.pickCtx, this.canvasCamera, {
983
+ hulls: this.pickItems
984
+ .filter((i) => i.kind === 'hull')
985
+ .map((i) => ({ d: hullPathD(this.communityHull(i.entry.members)) })),
986
+ links: this.pickItems
987
+ .filter((i) => i.kind === 'link')
988
+ .map((i) => {
989
+ const c = this.linkCoordinates(i.link);
990
+ return { x1: c.x1, y1: c.y1, x2: c.x2, y2: c.y2, width: i.link.width ?? 1.5 };
991
+ }),
992
+ nodes: this.pickItems
993
+ .filter((i) => i.kind === 'node')
994
+ .map((i) => ({
995
+ x: i.node.x ?? 0,
996
+ y: i.node.y ?? 0,
997
+ r: this.nodeRadius(i.node) + 2,
998
+ shape: this.nodeShape(i.node),
999
+ })),
1000
+ });
1001
+ this.pickDirty = false;
1002
+ }
1003
+ hitTest(clientX, clientY) {
1004
+ if (!this.canvasEl || !this.pickCtx)
1005
+ return undefined;
1006
+ if (this.pickDirty)
1007
+ this.redrawPickCanvas();
1008
+ const rect = this.canvasEl.getBoundingClientRect();
1009
+ const dpr = window.devicePixelRatio || 1;
1010
+ const px = Math.round((clientX - rect.left) * dpr);
1011
+ const py = Math.round((clientY - rect.top) * dpr);
1012
+ if (px < 0 || py < 0 || px >= this.pickCtx.canvas.width || py >= this.pickCtx.canvas.height)
1013
+ return undefined;
1014
+ const data = this.pickCtx.getImageData(px, py, 1, 1).data;
1015
+ const index = pickColorToIndex(data[0], data[1], data[2]);
1016
+ return index >= 0 ? this.pickItems[index] : undefined;
1017
+ }
1018
+ bindCanvasZoom() {
1019
+ if (!this.d3 || !this.canvasEl)
1020
+ return;
1021
+ this.zoomBehavior = this.d3
1022
+ .zoom()
1023
+ .scaleExtent([this.safeMinZoom, this.safeMaxZoom])
1024
+ .on('start', () => {
1025
+ // Same self-triggered-echo guard as the svg zoom bind's own 'start' handler above (see its
1026
+ // comment) -- a camera tween's per-frame applyZoomTransform() call fires this synchronously,
1027
+ // and without the guard cancelCameraTween() here would cancel that very tween on its own
1028
+ // first frame.
1029
+ if (this.isApplyingZoomTransform)
1030
+ return;
1031
+ this.isPanning = true;
1032
+ this.cancelCameraTween();
1033
+ })
1034
+ .on('zoom', (event) => {
1035
+ this.canvasCamera = { k: event.transform.k, x: event.transform.x, y: event.transform.y };
1036
+ this.markCanvasCameraDirty();
1037
+ })
1038
+ .on('end', () => {
1039
+ this.isPanning = false;
1040
+ });
1041
+ this.d3.select(this.canvasEl).call(this.zoomBehavior);
1042
+ }
1043
+ bindCanvasPointer() {
1044
+ const canvas = this.canvasEl;
1045
+ canvas.addEventListener('pointerdown', this.onCanvasPointerDown);
1046
+ canvas.addEventListener('pointermove', this.onCanvasPointerMove);
1047
+ canvas.addEventListener('pointerup', this.onCanvasPointerUp);
1048
+ canvas.addEventListener('pointerleave', this.onCanvasPointerLeave);
1049
+ canvas.addEventListener('dblclick', this.onCanvasDblClick);
1050
+ }
1051
+ /** `alpha` decays toward `alphaMin` and d3-force stops its internal timer once it crosses below
1052
+ * it, so `alpha > alphaMin` mirrors the simulation's own running condition -- including a drag's
1053
+ * `alphaTarget(0.3)` reheat, and correctly excluding a seeded/reduced-motion graph whose settle
1054
+ * loop already converged synchronously. */
1055
+ simulationIsTicking() {
1056
+ return this.simulation != null && this.simulation.alpha() > this.simulation.alphaMin();
1057
+ }
1058
+ /** Geometric fallback for dblclick: browsers can deliver the event before the offscreen pick
1059
+ * canvas has painted the latest frame, while the simulation coordinates are already current. */
1060
+ nodeAtCanvasPoint(clientX, clientY) {
1061
+ if (!this.canvasEl)
1062
+ return undefined;
1063
+ const rect = this.canvasEl.getBoundingClientRect();
1064
+ const worldX = (clientX - rect.left - this.canvasCamera.x) / this.canvasCamera.k;
1065
+ const worldY = (clientY - rect.top - this.canvasCamera.y) / this.canvasCamera.k;
1066
+ let closest;
1067
+ let closestDistance = Infinity;
1068
+ for (const node of this.simNodes) {
1069
+ const distance = Math.hypot((node.x ?? 0) - worldX, (node.y ?? 0) - worldY);
1070
+ if (distance <= this.nodeRadius(node) + 2 / this.canvasCamera.k && distance < closestDistance) {
1071
+ closest = node;
1072
+ closestDistance = distance;
1073
+ }
1074
+ }
1075
+ return closest;
1076
+ }
1077
+ updateCanvasTooltip(hit, clientX, clientY) {
1078
+ if (!this.canvasTooltipEl)
1079
+ return;
1080
+ if (!hit || hit.kind === 'hull') {
1081
+ this.canvasTooltipEl.setAttribute('hidden', '');
1082
+ return;
1083
+ }
1084
+ const rect = this.canvasEl.getBoundingClientRect();
1085
+ this.canvasTooltipEl.textContent =
1086
+ hit.kind === 'node' ? this.nodeAccessibleText(hit.node) : this.linkAccessibleText(hit.link);
1087
+ // `clientX - rect.left`/`clientY - rect.top` are physical viewport offsets, so they must be
1088
+ // written to the physical `left`/`top` -- a logical `inset-inline-start` maps to `right` under
1089
+ // RTL and would mirror the tooltip across the canvas instead of tracking the cursor.
1090
+ this.canvasTooltipEl.style.left = `${clientX - rect.left}px`;
1091
+ this.canvasTooltipEl.style.top = `${clientY - rect.top}px`;
1092
+ this.canvasTooltipEl.removeAttribute('hidden');
1093
+ }
1094
+ isSelected(kind, id) {
1095
+ return kind === 'node' ? this.selectedNodeIds.includes(id) : this.selectedLinkIds.includes(id);
1096
+ }
1097
+ linkKey(link) {
1098
+ const source = typeof link.source === 'object' ? link.source.id : String(link.source);
1099
+ const target = typeof link.target === 'object' ? link.target.id : String(link.target);
1100
+ return link.id ?? `${source}->${target}`;
1101
+ }
1102
+ /** Computes and emits the selection intent for activating `id`; never assigns
1103
+ * `selectedNodeIds`/`selectedLinkIds` itself -- see the class doc's controlled-selection note. */
1104
+ emitSelectionIntent(kind, id, toggle) {
1105
+ if (this.selectionMode === 'none')
1106
+ return;
1107
+ const selected = this.isSelected(kind, id);
1108
+ if (this.selectionMode === 'single' || !toggle) {
1109
+ if (this.selectionMode === 'single' && selected) {
1110
+ this.emit('lyra-selection-change', { nodeIds: [], linkIds: [] });
1111
+ return;
1112
+ }
1113
+ this.emit('lyra-selection-change', kind === 'node' ? { nodeIds: [id], linkIds: [] } : { nodeIds: [], linkIds: [id] });
1114
+ return;
1115
+ }
1116
+ const nodeIds = kind === 'node'
1117
+ ? selected
1118
+ ? this.selectedNodeIds.filter((x) => x !== id)
1119
+ : [...this.selectedNodeIds, id]
1120
+ : this.selectedNodeIds;
1121
+ const linkIds = kind === 'link'
1122
+ ? selected
1123
+ ? this.selectedLinkIds.filter((x) => x !== id)
1124
+ : [...this.selectedLinkIds, id]
1125
+ : this.selectedLinkIds;
1126
+ this.emit('lyra-selection-change', { nodeIds, linkIds });
1127
+ }
1128
+ clearSelection() {
1129
+ if (this.selectionMode === 'none')
1130
+ return;
1131
+ if (!this.selectedNodeIds.length && !this.selectedLinkIds.length)
1132
+ return;
1133
+ this.emit('lyra-selection-change', { nodeIds: [], linkIds: [] });
1134
+ }
177
1135
  willUpdate(changed) {
178
1136
  // rebuildSimulation() (re)assigns the simNodes/simLinks reactive
179
1137
  // properties — doing that from willUpdate() folds them into the render
@@ -181,9 +1139,27 @@ export class LyraGraph extends LyraElement {
181
1139
  // instead would set a reactive property *after* the update completed,
182
1140
  // which Lit schedules as a whole extra update pass (a dev-mode warning,
183
1141
  // and pointless work).
184
- if (this.d3 && (changed.has('nodes') || changed.has('links'))) {
1142
+ if (this.d3 &&
1143
+ (changed.has('nodes') ||
1144
+ changed.has('links') ||
1145
+ changed.has('hiddenTypes') ||
1146
+ changed.has('layout') ||
1147
+ (this.layout === 'layered' && changed.has('linkDistance')))) {
185
1148
  this.rebuildSimulation();
186
1149
  }
1150
+ // rebuildSimulation() above always reassigns simNodes, so checking it here (after that call)
1151
+ // also catches a nodes/links/hiddenTypes-driven rebuild, not just a direct communities set.
1152
+ if (changed.has('simNodes') || changed.has('communities')) {
1153
+ this.visibleCommunitiesCache = undefined;
1154
+ }
1155
+ // Same reasoning as rebuildSimulation() above -- assigning graphLiveText from updated() would
1156
+ // schedule a whole extra update pass instead of landing in the render this update is already
1157
+ // about to perform.
1158
+ if (changed.has('selectedNodeIds') || changed.has('selectedLinkIds')) {
1159
+ this.graphLiveText = this.localize('graphSelectionCount', undefined, {
1160
+ count: this.selectedNodeIds.length + this.selectedLinkIds.length,
1161
+ });
1162
+ }
187
1163
  }
188
1164
  updated(changed) {
189
1165
  if (this.loading)
@@ -192,13 +1168,13 @@ export class LyraGraph extends LyraElement {
192
1168
  this.removeAttribute('aria-busy');
193
1169
  if (!this.d3)
194
1170
  return;
195
- if (!changed.has('nodes') && !changed.has('links')) {
1171
+ if (!changed.has('nodes') && !changed.has('links') && !changed.has('hiddenTypes')) {
196
1172
  // These two branches are independent (not else-if): a consumer can set
197
1173
  // width/height and chargeStrength/linkDistance in the same reactive
198
1174
  // update batch, and both retunes must apply — not just whichever branch
199
1175
  // happens to come first.
200
1176
  if (changed.has('width') || changed.has('height')) {
201
- this.simulation?.force('center', this.d3.forceCenter(this.width / 2, this.height / 2));
1177
+ this.simulation?.force('center', this.d3.forceCenter(this.safeWidth / 2, this.safeHeight / 2));
202
1178
  this.simulation?.alpha(0.1).restart();
203
1179
  }
204
1180
  if (changed.has('chargeStrength') || changed.has('linkDistance')) {
@@ -207,9 +1183,9 @@ export class LyraGraph extends LyraElement {
207
1183
  // them fresh) — retune the already-created force objects in place
208
1184
  // instead of rebuilding the whole simulation.
209
1185
  if (changed.has('chargeStrength'))
210
- this.chargeForce?.strength(this.chargeStrength);
1186
+ this.chargeForce?.strength(this.safeChargeStrength);
211
1187
  if (changed.has('linkDistance'))
212
- this.linkForce?.distance(this.linkDistance);
1188
+ this.linkForce?.distance(this.safeLinkDistance);
213
1189
  this.simulation?.alpha(0.3).restart();
214
1190
  }
215
1191
  }
@@ -218,6 +1194,15 @@ export class LyraGraph extends LyraElement {
218
1194
  // node/link querySelectorAll scan on that is equivalent to "structurally
219
1195
  // changed" without needing a separate flag.
220
1196
  this.applyInteractions(changed);
1197
+ this.applyCanvasInteractions();
1198
+ if (this.focusId == null) {
1199
+ this.lastAppliedFocusId = null;
1200
+ }
1201
+ else if (this.focusId !== this.lastAppliedFocusId && this.simNodes.some((n) => n.id === this.focusId)) {
1202
+ this.lastAppliedFocusId = this.focusId;
1203
+ void this.focusNode(this.focusId);
1204
+ }
1205
+ this.updateFocusHalo();
221
1206
  }
222
1207
  /**
223
1208
  * Imperatively wires up d3-zoom (pan/zoom on the `<svg>`) and d3-drag
@@ -243,58 +1228,115 @@ export class LyraGraph extends LyraElement {
243
1228
  applyInteractions(changed) {
244
1229
  if (!this.d3)
245
1230
  return;
1231
+ if (this.renderer !== 'svg')
1232
+ return;
246
1233
  const svgEl = this.renderRoot.querySelector('svg');
247
1234
  if (svgEl && svgEl !== this.zoomedEl) {
1235
+ // Binding a fresh svg means any previous renderer="canvas" surface is gone -- stop its
1236
+ // resize watcher now (it observes the host, not the removed <canvas>, so it would keep
1237
+ // firing markCanvasDirty() for as long as the element lives in svg mode).
1238
+ this.canvasResizeObserver?.disconnect();
1239
+ this.canvasResizeObserver = undefined;
248
1240
  this.zoomedEl = svgEl;
249
1241
  this.gEl = this.renderRoot.querySelector('g') ?? undefined;
1242
+ this.focusHaloEl = this.renderRoot.querySelector('[part="focus-halo"]') ?? undefined;
250
1243
  this.zoomBehavior = this.d3
251
1244
  .zoom()
252
- .scaleExtent([this.minZoom, this.maxZoom])
1245
+ .scaleExtent([this.safeMinZoom, this.safeMaxZoom])
1246
+ .on('start', () => {
1247
+ // A camera tween writes a transform on every frame via applyZoomTransform(), which
1248
+ // itself synchronously replays this same 'start' handler -- ignore that self-triggered
1249
+ // echo so a tween doesn't cancel itself on its own first frame.
1250
+ if (this.isApplyingZoomTransform)
1251
+ return;
1252
+ this.isPanning = true;
1253
+ this.cancelCameraTween();
1254
+ })
253
1255
  .on('zoom', (event) => {
254
1256
  this.gEl?.setAttribute('transform', event.transform.toString());
1257
+ this.updateEdgeLabelZoomGate(event.transform.k);
1258
+ })
1259
+ .on('end', () => {
1260
+ this.isPanning = false;
255
1261
  });
256
1262
  this.d3.select(svgEl).call(this.zoomBehavior);
1263
+ // `.call(zoomBehavior)` does not synchronously fire the 'zoom' handler above (only a real
1264
+ // user gesture or an explicit `.transform()` call does, and nothing in this component ever
1265
+ // calls `.transform()`) -- so the initial transform right here is always d3-zoom's own
1266
+ // identity transform, k=1. Apply the edge-label zoom gate against that known value now, or
1267
+ // it stays unset (edge labels wrongly visible) until the user's first pan/zoom, regardless
1268
+ // of what edgeLabelMinZoom actually is.
1269
+ this.updateEdgeLabelZoomGate(1);
257
1270
  }
258
1271
  else if (this.zoomBehavior && (changed.has('minZoom') || changed.has('maxZoom'))) {
259
- this.zoomBehavior.scaleExtent([this.minZoom, this.maxZoom]);
1272
+ this.zoomBehavior.scaleExtent([this.safeMinZoom, this.safeMaxZoom]);
260
1273
  }
261
- if (!(changed.has('simNodes') || changed.has('simLinks')))
1274
+ if (!(changed.has('simNodes') ||
1275
+ changed.has('simLinks') ||
1276
+ changed.has('nodeTypes') ||
1277
+ changed.has('showEdgeLabels') ||
1278
+ changed.has('communities')))
262
1279
  return;
263
1280
  const nodeEls = Array.from(this.renderRoot.querySelectorAll('[part="node"]'));
264
1281
  this.nodeEls = nodeEls;
265
1282
  this.nodeLabelEls = nodeEls.map((el) => el.parentElement?.querySelector('[part="label"]') ?? null);
1283
+ this.expandIndicatorEls = nodeEls.map((el) => el.parentElement?.querySelector('[part="expand-indicator"]') ?? null);
266
1284
  // Dangling stubs also carry part="link" (so they inherit the same themeable styling as a
267
1285
  // real edge) -- excluded here explicitly so `linkEls` stays index-aligned with `simLinks`
268
1286
  // rather than relying on stubs always sorting after real links in template/DOM order.
269
1287
  this.linkEls = Array.from(this.renderRoot.querySelectorAll('[part="link"]:not([data-dangling])'));
1288
+ this.linkLabelEls = this.linkEls.map((el) => el.parentElement?.querySelector('[part="link-label"]') ?? null);
1289
+ this.linkLabelHiddenByLength = [];
270
1290
  this.danglingLinkEls = Array.from(this.renderRoot.querySelectorAll('[part="link"][data-dangling]'));
271
- nodeEls.forEach((el, i) => {
272
- if (this.boundNodeEls.has(el))
273
- return;
274
- const n = this.simNodes[i];
275
- if (!n)
276
- return;
277
- this.boundNodeEls.add(el);
278
- this.d3.select(el).call(this.d3.drag()
279
- .on('start', (event) => {
280
- // Keep a node drag from also triggering the svg's own pan gesture.
281
- event.sourceEvent?.stopPropagation();
282
- if (!event.active)
283
- this.simulation?.alphaTarget(0.3).restart();
284
- n.fx = n.x;
285
- n.fy = n.y;
286
- })
287
- .on('drag', (event) => {
288
- n.fx = event.x;
289
- n.fy = event.y;
290
- })
291
- .on('end', (event) => {
292
- if (!event.active)
293
- this.simulation?.alphaTarget(0);
294
- n.fx = null;
295
- n.fy = null;
296
- }));
297
- });
1291
+ this.communityHullEls = Array.from(this.renderRoot.querySelectorAll('[part="hull"]'));
1292
+ this.communityLabelEls = Array.from(this.renderRoot.querySelectorAll('[part="community-label"]'));
1293
+ if (this.layout !== 'layered') {
1294
+ nodeEls.forEach((el, i) => {
1295
+ if (this.boundNodeEls.has(el))
1296
+ return;
1297
+ const n = this.simNodes[i];
1298
+ if (!n)
1299
+ return;
1300
+ this.boundNodeEls.add(el);
1301
+ this.d3.select(el).call(this.d3.drag()
1302
+ .on('start', (event) => {
1303
+ this.isDragging = true;
1304
+ // Keep a node drag from also triggering the svg's own pan gesture.
1305
+ event.sourceEvent?.stopPropagation();
1306
+ if (!event.active)
1307
+ this.simulation?.alphaTarget(0.3).restart();
1308
+ n.fx = n.x;
1309
+ n.fy = n.y;
1310
+ })
1311
+ .on('drag', (event) => {
1312
+ n.fx = event.x;
1313
+ n.fy = event.y;
1314
+ })
1315
+ .on('end', (event) => {
1316
+ this.isDragging = false;
1317
+ if (!event.active)
1318
+ this.simulation?.alphaTarget(0);
1319
+ n.fx = null;
1320
+ n.fy = null;
1321
+ }));
1322
+ });
1323
+ }
1324
+ }
1325
+ /** The `renderer="canvas"` twin of `applyInteractions()`'s svg zoom-bind branch -- binds d3-zoom
1326
+ * and the pointer/hit-testing handlers to the just-rendered `<canvas>` once (guarded by the same
1327
+ * `zoomedEl` field `applyInteractions()` uses, so `focusNode()`/`fit()`/`tweenCamera()` keep
1328
+ * working unmodified against whichever element -- svg or canvas -- is currently bound), then
1329
+ * marks the canvas dirty on every call so any structural/style-affecting change (new nodes/
1330
+ * links, a selection change, a hiddenTypes toggle, ...) schedules a fresh draw the same way a
1331
+ * Lit re-render already does for svg mode. */
1332
+ applyCanvasInteractions() {
1333
+ if (this.renderer !== 'canvas' || !this.canvasEl)
1334
+ return;
1335
+ if (this.canvasEl !== this.zoomedEl) {
1336
+ this.zoomedEl = this.canvasEl;
1337
+ this.setUpCanvasSurface();
1338
+ }
1339
+ this.markCanvasDirty();
298
1340
  }
299
1341
  /**
300
1342
  * Runs on every d3-force simulation tick (up to ~300 while a graph settles
@@ -315,11 +1357,26 @@ export class LyraGraph extends LyraElement {
315
1357
  target.x = (source.x ?? 0) + STUB_OFFSET_PX;
316
1358
  target.y = (source.y ?? 0) + STUB_OFFSET_PX;
317
1359
  }
1360
+ // Keep the remembered-position cache current with a position captured mid-settle or mid-drag
1361
+ // (not just the one snapshotted at the end of rebuildSimulation()) -- a hiddenTypes toggle
1362
+ // that lands before the next structural rebuild should still restore a node to where it
1363
+ // actually was, not an earlier, since-superseded snapshot. Plain Map writes, no DOM/no
1364
+ // reactive-property touch, so this stays on the same cheap per-tick path as the rest of this
1365
+ // method.
1366
+ for (const n of this.simNodes) {
1367
+ if (n.x != null && n.y != null)
1368
+ this.lastPositionById.set(n.id, { x: n.x, y: n.y });
1369
+ }
318
1370
  this.simNodes.forEach((n, i) => {
319
- const circle = this.nodeEls[i];
320
- if (circle) {
321
- circle.setAttribute('cx', String(n.x ?? 0));
322
- circle.setAttribute('cy', String(n.y ?? 0));
1371
+ const el = this.nodeEls[i];
1372
+ if (el) {
1373
+ if (el.tagName === 'circle') {
1374
+ el.setAttribute('cx', String(n.x ?? 0));
1375
+ el.setAttribute('cy', String(n.y ?? 0));
1376
+ }
1377
+ else {
1378
+ el.setAttribute('transform', `translate(${n.x ?? 0},${n.y ?? 0})`);
1379
+ }
323
1380
  }
324
1381
  const label = this.nodeLabelEls[i];
325
1382
  if (label) {
@@ -337,6 +1394,28 @@ export class LyraGraph extends LyraElement {
337
1394
  line.setAttribute('x2', String(coordinates.x2));
338
1395
  line.setAttribute('y2', String(coordinates.y2));
339
1396
  });
1397
+ if (this.showEdgeLabels) {
1398
+ this.simLinks.forEach((l, i) => {
1399
+ const labelEl = this.linkLabelEls[i];
1400
+ if (!labelEl)
1401
+ return;
1402
+ const pos = this.edgeLabelPosition(l);
1403
+ labelEl.setAttribute('x', String(pos.x));
1404
+ labelEl.setAttribute('y', String(pos.y));
1405
+ const { x1, y1, x2, y2 } = this.linkCoordinates(l);
1406
+ const edgeLength = Math.hypot(x2 - x1, y2 - y1);
1407
+ const tooLong = this.edgeLabelWidth(l.label ?? '') > edgeLength * EDGE_LABEL_LENGTH_GATE_RATIO;
1408
+ if (this.linkLabelHiddenByLength[i] !== tooLong) {
1409
+ this.linkLabelHiddenByLength[i] = tooLong;
1410
+ labelEl.setAttribute('visibility', tooLong ? 'hidden' : 'visible');
1411
+ }
1412
+ });
1413
+ }
1414
+ this.simNodes.forEach((n, i) => {
1415
+ const indicator = this.expandIndicatorEls[i];
1416
+ if (indicator)
1417
+ indicator.setAttribute('transform', `translate(${n.x ?? 0},${n.y ?? 0})`);
1418
+ });
340
1419
  // Dangling stubs are excluded from d3-force's own simulation input (see
341
1420
  // rebuildSimulation()'s "stubs never enter d3-force's own simulation input"), so the
342
1421
  // synthetic target position the danglingLinks loop at the top of this method just
@@ -353,12 +1432,41 @@ export class LyraGraph extends LyraElement {
353
1432
  line.setAttribute('x2', String(coordinates.x2));
354
1433
  line.setAttribute('y2', String(coordinates.y2));
355
1434
  });
1435
+ this.updateFocusHalo();
1436
+ this.visibleCommunities().forEach((entry, i) => {
1437
+ const hullEl = this.communityHullEls[i];
1438
+ const labelEl = this.communityLabelEls[i];
1439
+ if (!hullEl && !labelEl)
1440
+ return;
1441
+ const hull = this.communityHull(entry.members);
1442
+ if (hullEl)
1443
+ hullEl.setAttribute('d', hullPathD(hull));
1444
+ if (labelEl) {
1445
+ labelEl.setAttribute('x', String(hullCentroidX(hull)));
1446
+ labelEl.setAttribute('y', String(hullTopY(hull) - HULL_PADDING));
1447
+ }
1448
+ });
1449
+ // renderer="canvas" mode has no DOM to write positions straight to (everything above this line
1450
+ // no-ops there: nodeEls/linkEls/etc. are only ever populated by applyInteractions()'s svg-only
1451
+ // branch) -- schedule a fresh draw off the same simulation tick instead, so the settle
1452
+ // animation and a live node drag actually repaint the canvas rather than freezing at whatever
1453
+ // was last drawn on mount.
1454
+ if (this.renderer === 'canvas')
1455
+ this.markCanvasDirty();
356
1456
  }
357
1457
  rebuildSimulation() {
358
1458
  if (!this.d3)
359
1459
  return;
360
1460
  this.simulation?.stop();
361
1461
  this.boundNodeEls = new WeakSet();
1462
+ // Prune remembered positions for ids no longer present in `this.nodes` at all (not merely
1463
+ // hidden by hiddenTypes) -- otherwise this cache would grow forever across a long-lived,
1464
+ // mutating graph instead of tracking only ids that could plausibly reappear.
1465
+ const liveIds = new Set(this.nodes.map((n) => n.id));
1466
+ for (const id of this.lastPositionById.keys()) {
1467
+ if (!liveIds.has(id))
1468
+ this.lastPositionById.delete(id);
1469
+ }
362
1470
  // Carry over each existing SimNode's settled position/velocity (and any
363
1471
  // in-progress drag fx/fy) by id instead of starting every node fresh —
364
1472
  // otherwise any structural nodes/links change (e.g. appending one new
@@ -367,60 +1475,98 @@ export class LyraGraph extends LyraElement {
367
1475
  // start settle animation from scratch. Only nodes with no previous
368
1476
  // counterpart (genuinely new ids) get forceSimulation()'s default
369
1477
  // fresh random start below.
1478
+ const visible = this.visibleNodes();
1479
+ if (this.layout === 'layered') {
1480
+ this.rebuildLayeredLayout(visible);
1481
+ return;
1482
+ }
370
1483
  const prevById = new Map(this.simNodes.map((n) => [n.id, n]));
371
- const nodes = this.nodes.map((n) => {
1484
+ const nodes = visible.map((n) => {
372
1485
  const prev = prevById.get(n.id);
373
- return prev ? { ...prev, ...n } : { ...n };
1486
+ if (prev)
1487
+ return { ...prev, ...n };
1488
+ // A node hidden by hiddenTypes and now visible again has no prevById entry (it fell out of
1489
+ // simNodes while hidden) but may still have a remembered settled position from before it was
1490
+ // hidden -- restore that instead of leaving it for the neighbor-jitter/seed spawn logic below,
1491
+ // or forceSimulation()'s own random start, to place it as if it were a brand-new node.
1492
+ const remembered = this.lastPositionById.get(n.id);
1493
+ return remembered ? { ...n, x: remembered.x, y: remembered.y } : { ...n };
374
1494
  });
375
1495
  const byId = new Map(nodes.map((n) => [n.id, n]));
376
- const resolvedLinks = [];
377
- const danglingLinks = [];
378
- for (const l of this.links) {
379
- const source = byId.get(l.source);
380
- if (!source)
381
- continue; // no real position to draw a stub from -- stays dropped, unchanged
382
- const target = byId.get(l.target);
383
- if (target) {
384
- resolvedLinks.push({ ...l, source, target });
385
- }
386
- else {
387
- danglingLinks.push({
388
- ...l,
389
- source,
390
- target: { id: l.target, x: source.x, y: source.y },
391
- dangling: true,
392
- });
393
- }
394
- }
1496
+ const { resolved: resolvedLinks, dangling: danglingLinks } = this.resolveLinksAgainst(byId);
395
1497
  const links = resolvedLinks; // stubs never enter d3-force's own simulation input
396
1498
  this.danglingLinks = danglingLinks;
397
- // Give brand-new nodes (no carried-over position from prevById above) a
398
- // deterministic starting x/y, keyed by node id, instead of leaving them
399
- // for forceSimulation() below to randomize. Nodes that already have a
400
- // position are left untouched same "only randomize nodes without x/y"
401
- // rule forceSimulation() itself follows so an incremental update to a
1499
+ const seedForSpawn = this.safeSeed;
1500
+ // Give a brand-new node with no carried-over position (from prevById above) a spawn point
1501
+ // near an already-positioned neighbor instead of forceSimulation()'s eventual random start --
1502
+ // expanded neighborhoods bloom around their origin instead of flying in from nowhere. Only
1503
+ // touches nodes with no position yet, so it can't move anything already settled.
1504
+ for (const n of nodes) {
1505
+ if (n.x != null && n.y != null)
1506
+ continue;
1507
+ const neighborLink = resolvedLinks.find((l) => {
1508
+ const source = l.source;
1509
+ const target = l.target;
1510
+ return (source.id === n.id && target.x != null) || (target.id === n.id && source.x != null);
1511
+ });
1512
+ if (!neighborLink)
1513
+ continue;
1514
+ const source = neighborLink.source;
1515
+ const target = neighborLink.target;
1516
+ const neighbor = source.id === n.id ? target : source;
1517
+ const jitterRadius = this.safeLinkDistance / 2;
1518
+ const angle = seedForSpawn != null
1519
+ ? (hashNodeSeed(seedForSpawn, n.id) / 4294967296) * Math.PI * 2
1520
+ : Math.random() * Math.PI * 2;
1521
+ n.x = (neighbor.x ?? 0) + Math.cos(angle) * jitterRadius;
1522
+ n.y = (neighbor.y ?? 0) + Math.sin(angle) * jitterRadius;
1523
+ }
1524
+ // Give any remaining brand-new nodes (no carried-over position from prevById above, and no
1525
+ // already-positioned neighbor for the jitter spawn above to anchor to) a deterministic
1526
+ // starting x/y, keyed by node id, instead of leaving them for forceSimulation() below to
1527
+ // randomize. Nodes that already have a position are left untouched — same "only randomize
1528
+ // nodes without x/y" rule forceSimulation() itself follows — so an incremental update to a
402
1529
  // seeded, already-settled graph doesn't reshuffle existing nodes.
403
- const seed = this.seed;
404
- if (seed != null) {
1530
+ if (seedForSpawn != null) {
405
1531
  for (const n of nodes) {
406
1532
  if (n.x != null && n.y != null)
407
1533
  continue;
408
- const rng = mulberry32(hashNodeSeed(seed, n.id));
409
- n.x = rng() * this.width;
410
- n.y = rng() * this.height;
1534
+ const rng = mulberry32(hashNodeSeed(seedForSpawn, n.id));
1535
+ n.x = rng() * this.safeWidth;
1536
+ n.y = rng() * this.safeHeight;
411
1537
  }
412
1538
  }
413
- this.linkForce = this.d3.forceLink(links).distance(this.linkDistance);
414
- this.chargeForce = this.d3.forceManyBody().strength(this.chargeStrength);
1539
+ this.linkForce = this.d3.forceLink(links).distance(this.safeLinkDistance);
1540
+ this.chargeForce = this.d3.forceManyBody().strength(this.safeChargeStrength);
415
1541
  const simulation = this.d3
416
1542
  .forceSimulation(nodes)
417
1543
  .force('link', this.linkForce)
418
1544
  .force('charge', this.chargeForce)
419
- .force('center', this.d3.forceCenter(this.width / 2, this.height / 2))
1545
+ .force('center', this.d3.forceCenter(this.safeWidth / 2, this.safeHeight / 2))
420
1546
  .force('collide', this.d3.forceCollide().radius((n) => this.nodeRadius(n) + 10))
421
1547
  .on('tick', () => this.onTick());
422
1548
  this.simulation = simulation;
423
- if (prefersReducedMotion() || this.seed != null) {
1549
+ if (prefersReducedMotion() || this.safeSeed != null) {
1550
+ // Pin every node that already had a known position before this rebuild -- either carried
1551
+ // over directly (fx/fy, the same mechanism a user drag uses) or restored from
1552
+ // lastPositionById after being hidden by hiddenTypes -- so introducing a new node/link can't
1553
+ // visibly reposition it during this synchronous settle. Only a genuinely new node (no prior
1554
+ // counterpart in either source) is free to move while the simulation converges. A node whose
1555
+ // fx/fy was already set (an active user drag concurrent with this rebuild) is left alone
1556
+ // entirely -- both the pin and the later release below only apply to a node this loop itself
1557
+ // pinned, so a real in-progress drag's own fx/fy is never clobbered. Everything this loop
1558
+ // does pin gets released again immediately below, so this has no lasting effect on a later
1559
+ // user-initiated drag, nor on the live, async settle a non-seeded/non-reduced-motion graph
1560
+ // still animates over ~300 frames.
1561
+ const pinnedForSettle = new Set();
1562
+ for (const n of nodes) {
1563
+ const hadKnownPosition = prevById.has(n.id) || this.lastPositionById.has(n.id);
1564
+ if (hadKnownPosition && n.x != null && n.y != null && n.fx == null && n.fy == null) {
1565
+ n.fx = n.x;
1566
+ n.fy = n.y;
1567
+ pinnedForSettle.add(n.id);
1568
+ }
1569
+ }
424
1570
  // Converge synchronously instead of animating the settle over ~300
425
1571
  // rendered frames — the simulation is already stopped (alpha at
426
1572
  // alphaMin) by the time the DOM for this rebuild is first painted.
@@ -431,6 +1577,12 @@ export class LyraGraph extends LyraElement {
431
1577
  simulation.stop();
432
1578
  while (simulation.alpha() > simulation.alphaMin())
433
1579
  simulation.tick();
1580
+ for (const n of nodes) {
1581
+ if (pinnedForSettle.has(n.id)) {
1582
+ n.fx = null;
1583
+ n.fy = null;
1584
+ }
1585
+ }
434
1586
  }
435
1587
  // Assign these SAME array/object references (not copies) exactly once
436
1588
  // for this structural rebuild: forceSimulation(nodes) above already
@@ -442,17 +1594,137 @@ export class LyraGraph extends LyraElement {
442
1594
  // re-render up to ~300 times on load and continuously while dragging.
443
1595
  this.simNodes = nodes;
444
1596
  this.simLinks = links;
1597
+ for (const n of nodes) {
1598
+ if (n.x != null && n.y != null)
1599
+ this.lastPositionById.set(n.id, { x: n.x, y: n.y });
1600
+ }
1601
+ this.announceHiddenNodeCount(nodes.length);
1602
+ }
1603
+ /** Announces the current hidden-node count via the live region -- shared by both the force and
1604
+ * layered rebuild paths (each calls this with its own final visible-node count) so `hiddenTypes`
1605
+ * filtering announces identically regardless of `layout`. Called from right here (not from
1606
+ * willUpdate()/updated() gated on a 'hiddenTypes'/'nodes' PropertyValues diff) because
1607
+ * rebuildSimulation() itself is also invoked directly from connectedCallback() once the lazy d3
1608
+ * peer deps resolve -- a call that never goes through Lit's changed-property diffing at all.
1609
+ * Computing it there instead would miss that path entirely: a graph mounted with hiddenTypes
1610
+ * already set would compute this from a still-empty simNodes (0 settled nodes yet) on the
1611
+ * property-driven pass, then never get a chance to correct it once the real simNodes became
1612
+ * available. Only ever touches graphLiveText when there's something to say -- a node is
1613
+ * currently hidden, or one just stopped being hidden -- so a consumer that never sets
1614
+ * hiddenTypes keeps today's exact live-region output. */
1615
+ announceHiddenNodeCount(visibleNodeCount) {
1616
+ const totalNodeCount = this.nodes.length;
1617
+ const hiddenNodeCount = totalNodeCount - visibleNodeCount;
1618
+ if (totalNodeCount > 0 && (hiddenNodeCount > 0 || this.lastHiddenNodeCount > 0)) {
1619
+ this.graphLiveText = this.localize('graphNodesHidden', undefined, {
1620
+ hidden: hiddenNodeCount,
1621
+ total: totalNodeCount,
1622
+ });
1623
+ }
1624
+ this.lastHiddenNodeCount = hiddenNodeCount;
1625
+ }
1626
+ /** The `layout="layered"` path: computes final positions synchronously via the shared
1627
+ * `layeredLayout()` util (2r x 2r boxes, `gapY = linkDistance`, `gapX = 12`), centers the
1628
+ * drawing in `width` x `height`, and skips forceSimulation() entirely -- no `this.simulation`,
1629
+ * no ticking, no `prevById` carry-over (deterministic input -> output makes it unnecessary; a
1630
+ * structural change simply recomputes wholesale). `lyra-graph` never passes `fixedPositions`. */
1631
+ rebuildLayeredLayout(visible) {
1632
+ const boxes = visible.map((n) => {
1633
+ const r = this.nodeRadius(n);
1634
+ return { id: n.id, width: r * 2, height: r * 2 };
1635
+ });
1636
+ const visibleIds = new Set(visible.map((n) => n.id));
1637
+ const edges = this.links
1638
+ .filter((l) => visibleIds.has(l.source) && visibleIds.has(l.target))
1639
+ .map((l) => ({ source: l.source, target: l.target }));
1640
+ const raw = layeredLayout({ nodes: boxes, edges, options: { gapX: 12, gapY: this.safeLinkDistance } });
1641
+ let minX = Infinity;
1642
+ let minY = Infinity;
1643
+ let maxX = -Infinity;
1644
+ let maxY = -Infinity;
1645
+ for (const p of raw.values()) {
1646
+ minX = Math.min(minX, p.x);
1647
+ maxX = Math.max(maxX, p.x);
1648
+ minY = Math.min(minY, p.y);
1649
+ maxY = Math.max(maxY, p.y);
1650
+ }
1651
+ const offsetX = raw.size ? this.safeWidth / 2 - (minX + (maxX - minX) / 2) : this.safeWidth / 2;
1652
+ const offsetY = raw.size ? this.safeHeight / 2 - (minY + (maxY - minY) / 2) : this.safeHeight / 2;
1653
+ const nodes = visible.map((n) => {
1654
+ const p = raw.get(n.id);
1655
+ return { ...n, x: (p?.x ?? this.safeWidth / 2) + offsetX, y: (p?.y ?? this.safeHeight / 2) + offsetY };
1656
+ });
1657
+ const byId = new Map(nodes.map((n) => [n.id, n]));
1658
+ const { resolved, dangling } = this.resolveLinksAgainst(byId);
1659
+ this.danglingLinks = dangling;
1660
+ this.simulation = undefined;
1661
+ this.simNodes = nodes;
1662
+ this.simLinks = resolved;
1663
+ for (const n of nodes) {
1664
+ if (n.x != null && n.y != null)
1665
+ this.lastPositionById.set(n.id, { x: n.x, y: n.y });
1666
+ }
1667
+ this.announceHiddenNodeCount(nodes.length);
445
1668
  }
446
- onNodeClick(node) {
447
- this.emit('lyra-node-click', { id: node.id });
1669
+ onNodeClick(node, e) {
1670
+ this.emit('lyra-node-click', { id: node.id, x: node.x ?? 0, y: node.y ?? 0 });
1671
+ this.emitSelectionIntent('node', node.id, !!(e?.ctrlKey || e?.metaKey));
448
1672
  }
449
- onLinkClick(link) {
1673
+ /** Returns a node's current position in the graph's local drawing space. */
1674
+ getNodePosition(id) {
1675
+ const node = this.simNodes.find((candidate) => candidate.id === id);
1676
+ if (!node || !Number.isFinite(node.x) || !Number.isFinite(node.y))
1677
+ return undefined;
1678
+ return { x: node.x, y: node.y };
1679
+ }
1680
+ onLinkClick(link, e) {
450
1681
  const source = typeof link.source === 'object' ? link.source.id : String(link.source);
451
1682
  const target = typeof link.target === 'object' ? link.target.id : String(link.target);
452
1683
  this.emit('lyra-link-click', { source, target, ...(link.id ? { id: link.id } : {}) });
1684
+ this.emitSelectionIntent('link', this.linkKey(link), !!(e?.ctrlKey || e?.metaKey));
1685
+ }
1686
+ onNodeEnter(node, e) {
1687
+ if (this.isDragging || this.isPanning || this.isCameraTweening)
1688
+ return;
1689
+ e.currentTarget.setAttribute('data-hovered', '');
1690
+ this.emit('lyra-node-enter', { id: node.id });
1691
+ }
1692
+ onNodeLeave(node, e) {
1693
+ if (this.isDragging || this.isPanning || this.isCameraTweening)
1694
+ return;
1695
+ e.currentTarget.removeAttribute('data-hovered');
1696
+ this.emit('lyra-node-leave', { id: node.id });
1697
+ }
1698
+ onNodeDblClick(node, e) {
1699
+ // Stops the dblclick from also reaching the svg's own d3-zoom double-click-to-zoom-in
1700
+ // listener -- background double-click (not on a node) keeps that default behavior.
1701
+ e.stopPropagation();
1702
+ this.emit('lyra-node-expand', { id: node.id });
1703
+ }
1704
+ onLinkEnter(link, e) {
1705
+ if (this.isDragging || this.isPanning || this.isCameraTweening)
1706
+ return;
1707
+ e.currentTarget.setAttribute('data-hovered', '');
1708
+ const source = typeof link.source === 'object' ? link.source.id : String(link.source);
1709
+ const target = typeof link.target === 'object' ? link.target.id : String(link.target);
1710
+ this.emit('lyra-link-enter', { source, target, ...(link.id ? { id: link.id } : {}) });
1711
+ }
1712
+ onLinkLeave(link, e) {
1713
+ if (this.isDragging || this.isPanning || this.isCameraTweening)
1714
+ return;
1715
+ e.currentTarget.removeAttribute('data-hovered');
1716
+ const source = typeof link.source === 'object' ? link.source.id : String(link.source);
1717
+ const target = typeof link.target === 'object' ? link.target.id : String(link.target);
1718
+ this.emit('lyra-link-leave', { source, target, ...(link.id ? { id: link.id } : {}) });
453
1719
  }
454
1720
  nodeAccessibleText(node) {
455
- return node.accessibleLabel || node.label || node.id;
1721
+ let text = node.accessibleLabel || node.label || node.id;
1722
+ const type = this.resolveNodeType(node);
1723
+ if (type)
1724
+ text = this.localize('graphTypedNode', undefined, { label: text, type: type.label });
1725
+ if (node.expandable)
1726
+ text = this.localize('graphExpandableItem', undefined, { item: text });
1727
+ return text;
456
1728
  }
457
1729
  linkAccessibleText(link) {
458
1730
  if (link.accessibleLabel)
@@ -487,8 +1759,69 @@ export class LyraGraph extends LyraElement {
487
1759
  y2: targetY - (dy / distance) * inset,
488
1760
  };
489
1761
  }
1762
+ /** World-space midpoint of a link, offset EDGE_LABEL_OFFSET_PX perpendicular to the segment
1763
+ * (horizontal, unrotated text — rotated edge-label text is a readability and RTL hazard). */
1764
+ edgeLabelPosition(link) {
1765
+ const { x1, y1, x2, y2 } = this.linkCoordinates(link);
1766
+ const dx = x2 - x1;
1767
+ const dy = y2 - y1;
1768
+ const len = Math.hypot(dx, dy);
1769
+ const mx = (x1 + x2) / 2;
1770
+ const my = (y1 + y2) / 2;
1771
+ if (len === 0)
1772
+ return { x: mx, y: my };
1773
+ return {
1774
+ x: mx + (-dy / len) * EDGE_LABEL_OFFSET_PX,
1775
+ y: my + (dx / len) * EDGE_LABEL_OFFSET_PX,
1776
+ };
1777
+ }
1778
+ edgeLabelFontPx() {
1779
+ const raw = getComputedStyle(this).getPropertyValue('--lyra-font-size-2xs').trim();
1780
+ const parsed = parseFloat(raw);
1781
+ if (!Number.isFinite(parsed))
1782
+ return 10;
1783
+ // rem tokens are resolved relative to the root font-size; this is a decluttering heuristic,
1784
+ // not a pixel-perfect layout, so the standard 16px/rem approximation is sufficient.
1785
+ return raw.endsWith('rem') ? parsed * 16 : parsed;
1786
+ }
1787
+ edgeLabelWidth(text) {
1788
+ const cached = this.edgeLabelWidthCache.get(text);
1789
+ if (cached != null)
1790
+ return cached;
1791
+ const ctx = getScratchCtx();
1792
+ let width;
1793
+ if (ctx) {
1794
+ const fontFamily = getComputedStyle(this).getPropertyValue('--lyra-font').trim() || 'sans-serif';
1795
+ ctx.font = `${this.edgeLabelFontPx()}px ${fontFamily}`;
1796
+ width = ctx.measureText(text).width;
1797
+ }
1798
+ else {
1799
+ width = text.length * this.edgeLabelFontPx() * 0.6;
1800
+ }
1801
+ // Bound the cache under label churn (a streaming graph can cycle through unbounded distinct
1802
+ // label texts) -- Map iteration yields insertion order, so evicting the first key drops the
1803
+ // oldest-measured entry.
1804
+ if (this.edgeLabelWidthCache.size >= EDGE_LABEL_WIDTH_CACHE_MAX) {
1805
+ const oldest = this.edgeLabelWidthCache.keys().next().value;
1806
+ if (oldest !== undefined)
1807
+ this.edgeLabelWidthCache.delete(oldest);
1808
+ }
1809
+ this.edgeLabelWidthCache.set(text, width);
1810
+ return width;
1811
+ }
1812
+ /** Toggles `data-edge-labels-hidden` on the cached zoomed `<g>` when crossing `edgeLabelMinZoom`
1813
+ * -- called from the d3-zoom `'zoom'` handler (render-free, CSS hides `[part="link-label"]`
1814
+ * beneath the attribute) so this scales with every pan/zoom event without a Lit re-render. */
1815
+ updateEdgeLabelZoomGate(k) {
1816
+ if (!this.gEl)
1817
+ return;
1818
+ if (k < this.safeEdgeLabelMinZoom)
1819
+ this.gEl.setAttribute('data-edge-labels-hidden', '');
1820
+ else
1821
+ this.gEl.removeAttribute('data-edge-labels-hidden');
1822
+ }
490
1823
  graphItemCount() {
491
- return this.simNodes.length + this.simLinks.length;
1824
+ return this.simNodes.length + this.simLinks.length + this.visibleCommunities().length;
492
1825
  }
493
1826
  normalizedGraphItem(index = this.activeGraphItem) {
494
1827
  const count = this.graphItemCount();
@@ -499,8 +1832,19 @@ export class LyraGraph extends LyraElement {
499
1832
  const node = this.simNodes[index];
500
1833
  return node ? this.localize('graphNode', undefined, { label: this.nodeAccessibleText(node) }) : '';
501
1834
  }
502
- const link = this.simLinks[index - this.simNodes.length];
503
- return link ? this.linkAccessibleText(link) : '';
1835
+ const linkIndex = index - this.simNodes.length;
1836
+ if (linkIndex < this.simLinks.length) {
1837
+ const link = this.simLinks[linkIndex];
1838
+ return link ? this.linkAccessibleText(link) : '';
1839
+ }
1840
+ const hullIndex = linkIndex - this.simLinks.length;
1841
+ const entry = this.visibleCommunities()[hullIndex];
1842
+ return entry
1843
+ ? this.localize('graphCommunity', undefined, {
1844
+ label: entry.community.label ?? entry.community.id,
1845
+ count: entry.members.length,
1846
+ })
1847
+ : '';
504
1848
  }
505
1849
  graphItemAnnouncement(index) {
506
1850
  return this.localize('graphItemAnnouncement', undefined, {
@@ -522,10 +1866,16 @@ export class LyraGraph extends LyraElement {
522
1866
  this.activeGraphItem = normalized;
523
1867
  this.graphLiveText = this.graphItemAnnouncement(normalized);
524
1868
  void this.updateComplete.then(() => {
525
- const items = [
526
- ...Array.from(this.renderRoot.querySelectorAll('[part="node"]')),
527
- ...Array.from(this.renderRoot.querySelectorAll('[part="link"]')),
528
- ];
1869
+ // renderer="canvas" has no [part="node"]/[part="link"]/[part="hull"] elements at all -- the
1870
+ // roving tab stop lives on the offscreen [part="cursor-item"] buttons instead (see render()),
1871
+ // in the same flat nodes-then-links-then-hulls order.
1872
+ const items = (this.renderer === 'canvas'
1873
+ ? Array.from(this.renderRoot.querySelectorAll('[part="cursor-item"]'))
1874
+ : [
1875
+ ...Array.from(this.renderRoot.querySelectorAll('[part="node"]')),
1876
+ ...Array.from(this.renderRoot.querySelectorAll('[part="link"]')),
1877
+ ...Array.from(this.renderRoot.querySelectorAll('[part="hull"]')),
1878
+ ]);
529
1879
  items[normalized]?.focus();
530
1880
  });
531
1881
  }
@@ -542,7 +1892,20 @@ export class LyraGraph extends LyraElement {
542
1892
  if (e.key === 'Enter' || e.key === ' ') {
543
1893
  e.preventDefault();
544
1894
  this.onGraphItemFocus(index);
545
- activate();
1895
+ activate(e);
1896
+ if (index < this.simNodes.length) {
1897
+ const now = performance.now();
1898
+ if (this.lastKeyActivateIndex === index && now - this.lastKeyActivateTime <= EXPAND_KEY_INTERVAL_MS) {
1899
+ const node = this.simNodes[index];
1900
+ if (node)
1901
+ this.emit('lyra-node-expand', { id: node.id });
1902
+ this.lastKeyActivateIndex = null;
1903
+ }
1904
+ else {
1905
+ this.lastKeyActivateIndex = index;
1906
+ this.lastKeyActivateTime = now;
1907
+ }
1908
+ }
546
1909
  return;
547
1910
  }
548
1911
  const count = this.graphItemCount();
@@ -571,7 +1934,7 @@ export class LyraGraph extends LyraElement {
571
1934
  <div part="base">
572
1935
  <lyra-skeleton
573
1936
  variant="rect"
574
- style=${`--lyra-skeleton-w:${this.width}px;--lyra-skeleton-h:${this.height}px`}
1937
+ style=${`--lyra-skeleton-w:${this.safeWidth}px;--lyra-skeleton-h:${this.safeHeight}px`}
575
1938
  ></lyra-skeleton>
576
1939
  </div>
577
1940
  `;
@@ -579,6 +1942,99 @@ export class LyraGraph extends LyraElement {
579
1942
  if (!this.nodes.length) {
580
1943
  return html `<div part="base"><div part="empty">${this.localize('noData')}</div></div>`;
581
1944
  }
1945
+ if (this.renderer === 'canvas') {
1946
+ return html `
1947
+ <div part="base">
1948
+ <canvas
1949
+ part="canvas"
1950
+ role="group"
1951
+ aria-label=${this.accessibleLabel ||
1952
+ this.localize('graphDiagram', undefined, {
1953
+ nodeCount: this.simNodes.length,
1954
+ linkCount: this.simLinks.length,
1955
+ })}
1956
+ tabindex=${this.graphItemCount() ? '-1' : '0'}
1957
+ ></canvas>
1958
+ <div part="tooltip" hidden></div>
1959
+ <div part="live-region" class="sr-only" role="status" aria-live="polite" aria-atomic="true">
1960
+ ${this.graphLiveText ||
1961
+ (this.normalizedGraphItem() >= 0 ? this.graphItemAnnouncement(this.normalizedGraphItem()) : '')}
1962
+ </div>
1963
+ <ul part="data-list" class="sr-only" aria-label=${this.localize('graphDataList')}>
1964
+ ${this.simNodes.map((node) => html `<li>${this.localize('graphNode', undefined, { label: this.nodeAccessibleText(node) })}</li>`)}
1965
+ ${this.simLinks.map((link) => html `<li>${this.linkAccessibleText(link)}</li>`)}
1966
+ ${this.visibleCommunities().map((entry) => html `<li>${this.localize('graphCommunity', undefined, {
1967
+ label: entry.community.label ?? entry.community.id,
1968
+ count: entry.members.length,
1969
+ })}</li>`)}
1970
+ </ul>
1971
+ <div
1972
+ part="cursor-items"
1973
+ class="sr-only"
1974
+ @keydown=${(e) => {
1975
+ // Escape-clears-selection lives here (not on the canvas itself) because keydown from
1976
+ // a focused cursor-item bubbles up through this container, never through the canvas
1977
+ // -- the cursor-items list is canvas's sibling, not its descendant. Mirrors the svg
1978
+ // template's own root-level Escape handler; each cursor-item's own onGraphKeyDown()
1979
+ // (Enter/Space/arrows/Home/End) leaves Escape unhandled the same way a node/link
1980
+ // element does, so it bubbles here.
1981
+ if (e.key === 'Escape')
1982
+ this.clearSelection();
1983
+ }}
1984
+ >
1985
+ ${this.simNodes.map((n, i) => html `
1986
+ <!-- hit-area-exempt: this button lives inside [part="cursor-items"]'s
1987
+ class="sr-only" (internal/a11y.ts's clip: rect(0 0 0 0) box) -- it's
1988
+ the offscreen keyboard-roving a11y virtual cursor described in this
1989
+ class's own doc comment, never a visible/pointer-clickable box, so
1990
+ the 40px hit-area floor (meant for on-screen tap targets) doesn't apply. -->
1991
+ <button
1992
+ part="cursor-item"
1993
+ tabindex=${this.normalizedGraphItem() === i ? '0' : '-1'}
1994
+ aria-label=${this.nodeAccessibleText(n)}
1995
+ @focus=${() => this.onGraphItemFocus(i)}
1996
+ @keydown=${(e) => this.onGraphKeyDown(e, i, (ev) => this.onNodeClick(n, ev))}
1997
+ @click=${(e) => this.onNodeClick(n, e)}
1998
+ ></button>
1999
+ `)}
2000
+ ${this.simLinks.map((l, li) => {
2001
+ const i = this.simNodes.length + li;
2002
+ return html `
2003
+ <!-- hit-area-exempt: see the node cursor-item above -- same offscreen
2004
+ sr-only virtual-cursor button, no visible/pointer-clickable box. -->
2005
+ <button
2006
+ part="cursor-item"
2007
+ tabindex=${this.normalizedGraphItem() === i ? '0' : '-1'}
2008
+ aria-label=${this.linkAccessibleText(l)}
2009
+ @focus=${() => this.onGraphItemFocus(i)}
2010
+ @keydown=${(e) => this.onGraphKeyDown(e, i, (ev) => this.onLinkClick(l, ev))}
2011
+ @click=${(e) => this.onLinkClick(l, e)}
2012
+ ></button>
2013
+ `;
2014
+ })}
2015
+ ${this.visibleCommunities().map((entry, hi) => {
2016
+ const i = this.simNodes.length + this.simLinks.length + hi;
2017
+ const label = this.localize('graphCommunity', undefined, {
2018
+ label: entry.community.label ?? entry.community.id,
2019
+ count: entry.members.length,
2020
+ });
2021
+ return html `
2022
+ <!-- hit-area-exempt: see the node cursor-item above -- same offscreen
2023
+ sr-only virtual-cursor button, no visible/pointer-clickable box. -->
2024
+ <button
2025
+ part="cursor-item"
2026
+ tabindex=${this.normalizedGraphItem() === i ? '0' : '-1'}
2027
+ aria-label=${label}
2028
+ @focus=${() => this.onGraphItemFocus(i)}
2029
+ @keydown=${(e) => this.onGraphKeyDown(e, i, () => this.onCommunityClick(entry.community))}
2030
+ @click=${() => this.onCommunityClick(entry.community)}
2031
+ ></button>
2032
+ `;
2033
+ })}
2034
+ </div>
2035
+ </div>
2036
+ `;
2037
+ }
582
2038
  return html `
583
2039
  <div part="base">
584
2040
  <svg
@@ -589,8 +2045,16 @@ export class LyraGraph extends LyraElement {
589
2045
  nodeCount: this.simNodes.length,
590
2046
  linkCount: this.simLinks.length,
591
2047
  })}
592
- viewBox="0 0 ${this.width} ${this.height}"
2048
+ viewBox="0 0 ${this.safeWidth} ${this.safeHeight}"
593
2049
  tabindex=${this.graphItemCount() ? '-1' : '0'}
2050
+ @click=${(e) => {
2051
+ if (e.target === e.currentTarget)
2052
+ this.clearSelection();
2053
+ }}
2054
+ @keydown=${(e) => {
2055
+ if (e.key === 'Escape')
2056
+ this.clearSelection();
2057
+ }}
594
2058
  >
595
2059
  <defs>
596
2060
  <marker
@@ -607,28 +2071,63 @@ export class LyraGraph extends LyraElement {
607
2071
  </marker>
608
2072
  </defs>
609
2073
  <g transform="">
2074
+ ${this.visibleCommunities().map((entry, hullIndex) => {
2075
+ const itemIndex = this.simNodes.length + this.simLinks.length + hullIndex;
2076
+ const hull = this.communityHull(entry.members);
2077
+ const fill = sanitizeNodeColor(entry.community.color);
2078
+ const label = this.localize('graphCommunity', undefined, {
2079
+ label: entry.community.label ?? entry.community.id,
2080
+ count: entry.members.length,
2081
+ });
2082
+ return svg `<g>
2083
+ <path
2084
+ part="hull"
2085
+ role="button"
2086
+ tabindex=${this.normalizedGraphItem() === itemIndex ? '0' : '-1'}
2087
+ aria-label=${label}
2088
+ d=${hullPathD(hull)}
2089
+ style=${styleMap(fill ? { '--lyra-graph-hull-fill': fill } : {})}
2090
+ @click=${() => this.onCommunityClick(entry.community)}
2091
+ @focus=${() => this.onGraphItemFocus(itemIndex)}
2092
+ @keydown=${(e) => this.onGraphKeyDown(e, itemIndex, () => this.onCommunityClick(entry.community))}
2093
+ ></path>
2094
+ <text part="community-label" aria-hidden="true" x=${hullCentroidX(hull)} y=${hullTopY(hull) - HULL_PADDING}>${entry.community.label ?? entry.community.id}</text>
2095
+ </g>`;
2096
+ })}
610
2097
  ${this.simLinks.map((l, linkIndex) => {
611
2098
  const itemIndex = this.simNodes.length + linkIndex;
612
2099
  const coordinates = this.linkCoordinates(l);
613
2100
  const color = sanitizeNodeColor(l.color);
614
2101
  const dash = normalizeLinkDash(l.dash);
615
- return svg `<line
616
- part="link"
617
- role="button"
618
- tabindex=${this.normalizedGraphItem() === itemIndex ? '0' : '-1'}
619
- aria-label=${this.linkAccessibleText(l)}
620
- stroke-width=${l.width ?? 1.5}
621
- stroke-dasharray=${dash ?? nothing}
622
- marker-end=${l.directed ? `url(#${this.arrowMarkerId})` : nothing}
623
- style=${styleMap(color ? { '--lyra-link-color': color } : {})}
624
- x1=${coordinates.x1}
625
- y1=${coordinates.y1}
626
- x2=${coordinates.x2}
627
- y2=${coordinates.y2}
628
- @click=${() => this.onLinkClick(l)}
629
- @focus=${() => this.onGraphItemFocus(itemIndex)}
630
- @keydown=${(e) => this.onGraphKeyDown(e, itemIndex, () => this.onLinkClick(l))}
631
- >${l.description || l.label ? svg `<title>${l.description || l.label}</title>` : nothing}</line>`;
2102
+ const labelPos = this.showEdgeLabels && l.label ? this.edgeLabelPosition(l) : undefined;
2103
+ const lineEl = svg `<line
2104
+ part="link"
2105
+ role="button"
2106
+ tabindex=${this.normalizedGraphItem() === itemIndex ? '0' : '-1'}
2107
+ aria-label=${this.linkAccessibleText(l)}
2108
+ aria-pressed=${this.selectionMode !== 'none' ? String(this.isSelected('link', this.linkKey(l))) : nothing}
2109
+ ?data-selected=${this.isSelected('link', this.linkKey(l))}
2110
+ stroke-width=${l.width ?? 1.5}
2111
+ stroke-dasharray=${dash ?? nothing}
2112
+ marker-end=${l.directed ? `url(#${this.arrowMarkerId})` : nothing}
2113
+ style=${styleMap(color ? { '--lyra-link-color': color } : {})}
2114
+ x1=${coordinates.x1}
2115
+ y1=${coordinates.y1}
2116
+ x2=${coordinates.x2}
2117
+ y2=${coordinates.y2}
2118
+ @click=${(e) => this.onLinkClick(l, e)}
2119
+ @focus=${() => this.onGraphItemFocus(itemIndex)}
2120
+ @keydown=${(e) => this.onGraphKeyDown(e, itemIndex, (ev) => this.onLinkClick(l, ev))}
2121
+ @mouseenter=${(e) => this.onLinkEnter(l, e)}
2122
+ @mouseleave=${(e) => this.onLinkLeave(l, e)}
2123
+ >${l.description || l.label ? svg `<title>${l.description || l.label}</title>` : nothing}</line>`;
2124
+ // Only wrap in a <g> when a label will actually be drawn -- an unconditional wrapper
2125
+ // would change existing consumers' rendered link DOM (bare <line part="link">) even
2126
+ // when showEdgeLabels is never set, breaking the "existing usage renders byte-for-byte
2127
+ // identical output" contract this drawn-edge-label feature must preserve.
2128
+ return labelPos
2129
+ ? svg `<g>${lineEl}<text part="link-label" aria-hidden="true" text-anchor="middle" x=${labelPos.x} y=${labelPos.y}>${l.label}</text></g>`
2130
+ : lineEl;
632
2131
  })}
633
2132
  ${this.danglingLinks.map((l) => {
634
2133
  const source = l.source;
@@ -644,27 +2143,67 @@ export class LyraGraph extends LyraElement {
644
2143
  ></line>`;
645
2144
  })}
646
2145
  ${this.simNodes.map((n, nodeIndex) => {
647
- const fill = sanitizeNodeColor(n.color);
2146
+ const shape = this.nodeShape(n);
2147
+ const fill = this.nodeFill(n);
648
2148
  const itemIndex = nodeIndex;
2149
+ const tabindex = this.normalizedGraphItem() === itemIndex ? '0' : '-1';
2150
+ const label = this.nodeAccessibleText(n);
2151
+ // Unlike link styling below (which always renders style=${styleMap(...)}, even as
2152
+ // an empty string), an untyped/unknown-type node must render with NO style
2153
+ // attribute at all -- not just an empty one -- so hasAttribute('style') distinguishes
2154
+ // "no fill override" from "fill override present" for consumers/tests probing the DOM.
2155
+ const style = fill ? styleMap({ '--lyra-node-fill': fill }) : nothing;
2156
+ const title = n.description ? svg `<title>${n.description}</title>` : nothing;
2157
+ const shapeEl = shape === 'circle'
2158
+ ? svg `<circle
2159
+ part="node"
2160
+ role="button"
2161
+ tabindex=${tabindex}
2162
+ aria-label=${label}
2163
+ aria-pressed=${this.selectionMode !== 'none' ? String(this.isSelected('node', n.id)) : nothing}
2164
+ ?data-selected=${this.isSelected('node', n.id)}
2165
+ r=${this.nodeRadius(n)}
2166
+ cx=${n.x ?? 0}
2167
+ cy=${n.y ?? 0}
2168
+ style=${style}
2169
+ @click=${(e) => this.onNodeClick(n, e)}
2170
+ @dblclick=${(e) => this.onNodeDblClick(n, e)}
2171
+ @focus=${() => this.onGraphItemFocus(itemIndex)}
2172
+ @keydown=${(e) => this.onGraphKeyDown(e, itemIndex, (ev) => this.onNodeClick(n, ev))}
2173
+ @mouseenter=${(e) => this.onNodeEnter(n, e)}
2174
+ @mouseleave=${(e) => this.onNodeLeave(n, e)}
2175
+ >${title}</circle>`
2176
+ : svg `<path
2177
+ part="node"
2178
+ role="button"
2179
+ tabindex=${tabindex}
2180
+ aria-label=${label}
2181
+ aria-pressed=${this.selectionMode !== 'none' ? String(this.isSelected('node', n.id)) : nothing}
2182
+ ?data-selected=${this.isSelected('node', n.id)}
2183
+ d=${shape === 'square' ? squarePath(this.nodeRadius(n)) : diamondPath(this.nodeRadius(n))}
2184
+ transform="translate(${n.x ?? 0},${n.y ?? 0})"
2185
+ style=${style}
2186
+ @click=${(e) => this.onNodeClick(n, e)}
2187
+ @dblclick=${(e) => this.onNodeDblClick(n, e)}
2188
+ @focus=${() => this.onGraphItemFocus(itemIndex)}
2189
+ @keydown=${(e) => this.onGraphKeyDown(e, itemIndex, (ev) => this.onNodeClick(n, ev))}
2190
+ @mouseenter=${(e) => this.onNodeEnter(n, e)}
2191
+ @mouseleave=${(e) => this.onNodeLeave(n, e)}
2192
+ >${title}</path>`;
649
2193
  return svg `<g>
650
- <circle
651
- part="node"
652
- role="button"
653
- tabindex=${this.normalizedGraphItem() === itemIndex ? '0' : '-1'}
654
- aria-label=${this.nodeAccessibleText(n)}
655
- r=${this.nodeRadius(n)}
656
- cx=${n.x ?? 0}
657
- cy=${n.y ?? 0}
658
- style=${styleMap(fill ? { '--lyra-node-fill': fill } : {})}
659
- @click=${() => this.onNodeClick(n)}
660
- @focus=${() => this.onGraphItemFocus(itemIndex)}
661
- @keydown=${(e) => this.onGraphKeyDown(e, itemIndex, () => this.onNodeClick(n))}
662
- >${n.description ? svg `<title>${n.description}</title>` : nothing}</circle>
2194
+ ${shapeEl}
663
2195
  ${n.label
664
2196
  ? svg `<text part="label" aria-hidden="true" x=${(n.x ?? 0) + this.nodeRadius(n) + 2} y=${n.y ?? 0}>${n.label}</text>`
665
2197
  : ''}
2198
+ ${n.expandable
2199
+ ? svg `<g part="expand-indicator" aria-hidden="true" transform="translate(${n.x ?? 0},${n.y ?? 0})">
2200
+ <circle r=${EXPAND_BADGE_R} cx=${this.nodeRadius(n) * EXPAND_BADGE_OFFSET} cy=${-this.nodeRadius(n) * EXPAND_BADGE_OFFSET}></circle>
2201
+ <path d="M ${this.nodeRadius(n) * EXPAND_BADGE_OFFSET - EXPAND_BADGE_R / 2} ${-this.nodeRadius(n) * EXPAND_BADGE_OFFSET} L ${this.nodeRadius(n) * EXPAND_BADGE_OFFSET + EXPAND_BADGE_R / 2} ${-this.nodeRadius(n) * EXPAND_BADGE_OFFSET} M ${this.nodeRadius(n) * EXPAND_BADGE_OFFSET} ${-this.nodeRadius(n) * EXPAND_BADGE_OFFSET - EXPAND_BADGE_R / 2} L ${this.nodeRadius(n) * EXPAND_BADGE_OFFSET} ${-this.nodeRadius(n) * EXPAND_BADGE_OFFSET + EXPAND_BADGE_R / 2}"></path>
2202
+ </g>`
2203
+ : ''}
666
2204
  </g>`;
667
2205
  })}
2206
+ <circle part="focus-halo" aria-hidden="true" hidden r="0" cx="0" cy="0"></circle>
668
2207
  </g>
669
2208
  </svg>
670
2209
  <div part="live-region" class="sr-only" role="status" aria-live="polite" aria-atomic="true">
@@ -674,6 +2213,10 @@ export class LyraGraph extends LyraElement {
674
2213
  <ul part="data-list" class="sr-only" aria-label=${this.localize('graphDataList')}>
675
2214
  ${this.simNodes.map((node) => html `<li>${this.localize('graphNode', undefined, { label: this.nodeAccessibleText(node) })}</li>`)}
676
2215
  ${this.simLinks.map((link) => html `<li>${this.linkAccessibleText(link)}</li>`)}
2216
+ ${this.visibleCommunities().map((entry) => html `<li>${this.localize('graphCommunity', undefined, {
2217
+ label: entry.community.label ?? entry.community.id,
2218
+ count: entry.members.length,
2219
+ })}</li>`)}
677
2220
  </ul>
678
2221
  </div>
679
2222
  `;
@@ -685,6 +2228,21 @@ __decorate([
685
2228
  __decorate([
686
2229
  property({ attribute: false })
687
2230
  ], LyraGraph.prototype, "links", void 0);
2231
+ __decorate([
2232
+ property({ attribute: false })
2233
+ ], LyraGraph.prototype, "nodeTypes", void 0);
2234
+ __decorate([
2235
+ property({ attribute: false })
2236
+ ], LyraGraph.prototype, "hiddenTypes", void 0);
2237
+ __decorate([
2238
+ property({ attribute: false })
2239
+ ], LyraGraph.prototype, "communities", void 0);
2240
+ __decorate([
2241
+ property()
2242
+ ], LyraGraph.prototype, "layout", void 0);
2243
+ __decorate([
2244
+ property()
2245
+ ], LyraGraph.prototype, "renderer", void 0);
688
2246
  __decorate([
689
2247
  property({ type: Number })
690
2248
  ], LyraGraph.prototype, "width", void 0);
@@ -709,6 +2267,24 @@ __decorate([
709
2267
  __decorate([
710
2268
  property({ type: Number })
711
2269
  ], LyraGraph.prototype, "seed", void 0);
2270
+ __decorate([
2271
+ property({ type: Boolean, attribute: 'show-edge-labels' })
2272
+ ], LyraGraph.prototype, "showEdgeLabels", void 0);
2273
+ __decorate([
2274
+ property({ type: Number, attribute: 'edge-label-min-zoom' })
2275
+ ], LyraGraph.prototype, "edgeLabelMinZoom", void 0);
2276
+ __decorate([
2277
+ property({ attribute: 'focus-id' })
2278
+ ], LyraGraph.prototype, "focusId", void 0);
2279
+ __decorate([
2280
+ property({ attribute: 'selection-mode' })
2281
+ ], LyraGraph.prototype, "selectionMode", void 0);
2282
+ __decorate([
2283
+ property({ attribute: false })
2284
+ ], LyraGraph.prototype, "selectedNodeIds", void 0);
2285
+ __decorate([
2286
+ property({ attribute: false })
2287
+ ], LyraGraph.prototype, "selectedLinkIds", void 0);
712
2288
  __decorate([
713
2289
  state()
714
2290
  ], LyraGraph.prototype, "loading", void 0);
@@ -724,4 +2300,7 @@ __decorate([
724
2300
  __decorate([
725
2301
  state()
726
2302
  ], LyraGraph.prototype, "graphLiveText", void 0);
2303
+ __decorate([
2304
+ query('canvas')
2305
+ ], LyraGraph.prototype, "canvasEl", void 0);
727
2306
  //# sourceMappingURL=graph.class.js.map