@aceshooting/lyra-ui 3.7.0 → 3.9.0

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