@mastra/playground-ui 68.0.0-alpha.2 → 68.0.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 (479) hide show
  1. package/dist/{FilterBar-CQl04O6t.cjs → FilterBar-BSP2UTjc.cjs} +2 -2
  2. package/dist/{FilterBar-CQl04O6t.cjs.map → FilterBar-BSP2UTjc.cjs.map} +1 -1
  3. package/dist/{FilterBar-BgW2dqRQ.js → FilterBar-PSQ1OwqH.js} +2 -2
  4. package/dist/{FilterBar-BgW2dqRQ.js.map → FilterBar-PSQ1OwqH.js.map} +1 -1
  5. package/dist/KnowledgePageGraph.css +55 -0
  6. package/dist/{MarkdownRenderer-2GOXQJEv.js → MarkdownRenderer-CI30RqdB.js} +19 -6
  7. package/dist/MarkdownRenderer-CI30RqdB.js.map +1 -0
  8. package/dist/{MarkdownRenderer-CB8Z_CHc.cjs → MarkdownRenderer-y65WGBhC.cjs} +19 -6
  9. package/dist/MarkdownRenderer-y65WGBhC.cjs.map +1 -0
  10. package/dist/{MetricsCard-CEB-f2sv.cjs → MetricsCard-BEwiS7Pe.cjs} +8 -8
  11. package/dist/MetricsCard-BEwiS7Pe.cjs.map +1 -0
  12. package/dist/{MetricsCard-M8awJ2B_.js → MetricsCard-ua6C6b8a.js} +10 -10
  13. package/dist/MetricsCard-ua6C6b8a.js.map +1 -0
  14. package/dist/{MetricsLineChart-BhHoduO0.js → MetricsLineChart-4SwxBbQx.js} +14 -3
  15. package/dist/MetricsLineChart-4SwxBbQx.js.map +1 -0
  16. package/dist/{MetricsLineChart-CjBm4IXu.cjs → MetricsLineChart-tZxsauau.cjs} +13 -2
  17. package/dist/MetricsLineChart-tZxsauau.cjs.map +1 -0
  18. package/dist/{MetricsStackedBarChart-BdMlKv6G.cjs → MetricsStackedBarChart-CDLE76IB.cjs} +2 -2
  19. package/dist/{MetricsStackedBarChart-BdMlKv6G.cjs.map → MetricsStackedBarChart-CDLE76IB.cjs.map} +1 -1
  20. package/dist/{MetricsStackedBarChart-BRuA6MTE.js → MetricsStackedBarChart-D2QyS4-z.js} +2 -2
  21. package/dist/{MetricsStackedBarChart-BRuA6MTE.js.map → MetricsStackedBarChart-D2QyS4-z.js.map} +1 -1
  22. package/dist/{activity-rJ1NQl_2.js → activity-C8Ql81WM.js} +2 -2
  23. package/dist/{activity-rJ1NQl_2.js.map → activity-C8Ql81WM.js.map} +1 -1
  24. package/dist/{activity-DyB5H3gF.cjs → activity-CcQZeDYi.cjs} +2 -2
  25. package/dist/{activity-DyB5H3gF.cjs.map → activity-CcQZeDYi.cjs.map} +1 -1
  26. package/dist/components/DateTimeRangePicker.cjs.js +1 -1
  27. package/dist/components/DateTimeRangePicker.es.js +1 -1
  28. package/dist/components/FilterBar.cjs.js +2 -2
  29. package/dist/components/FilterBar.es.js +2 -2
  30. package/dist/components/MarkdownRenderer.cjs.js +1 -1
  31. package/dist/components/MarkdownRenderer.es.js +1 -1
  32. package/dist/components/MetricsCard.cjs.js +1 -1
  33. package/dist/components/MetricsCard.es.js +1 -1
  34. package/dist/components/MetricsLineChart.cjs.js +1 -1
  35. package/dist/components/MetricsLineChart.es.js +1 -1
  36. package/dist/components/MetricsStackedBarChart.cjs.js +1 -1
  37. package/dist/components/MetricsStackedBarChart.es.js +1 -1
  38. package/dist/components/SavedViews.cjs.js +1 -1
  39. package/dist/components/SavedViews.es.js +1 -1
  40. package/dist/components/ai/activity.cjs.js +1 -1
  41. package/dist/components/ai/activity.es.js +1 -1
  42. package/dist/components/ai/plan.cjs.js +1 -1
  43. package/dist/components/ai/plan.es.js +1 -1
  44. package/dist/components/ai/tool-approval.cjs.js +1 -1
  45. package/dist/components/ai/tool-approval.es.js +1 -1
  46. package/dist/components/ai/tool-call.cjs.js +2 -2
  47. package/dist/components/ai/tool-call.es.js +2 -2
  48. package/dist/{date-time-range-picker-CTt7Od0P.cjs → date-time-range-picker-CWGjoR3j.cjs} +40 -13
  49. package/dist/date-time-range-picker-CWGjoR3j.cjs.map +1 -0
  50. package/dist/{date-time-range-picker-DKh1K9Iy.js → date-time-range-picker-CdSiXwB4.js} +40 -13
  51. package/dist/date-time-range-picker-CdSiXwB4.js.map +1 -0
  52. package/dist/domains/chat/activity/activity-stretch-line.cjs.js +1 -1
  53. package/dist/domains/chat/activity/activity-stretch-line.es.js +1 -1
  54. package/dist/domains/chat/activity/components/activity-fold.cjs.js +1 -1
  55. package/dist/domains/chat/activity/components/activity-fold.es.js +1 -1
  56. package/dist/domains/chat/activity/components/activity-timed-trigger.cjs.js +1 -1
  57. package/dist/domains/chat/activity/components/activity-timed-trigger.es.js +1 -1
  58. package/dist/domains/chat/activity/components/calls-panel.cjs.js +1 -1
  59. package/dist/domains/chat/activity/components/calls-panel.es.js +1 -1
  60. package/dist/domains/chat/activity/components/stretch-content.cjs.js +1 -1
  61. package/dist/domains/chat/activity/components/stretch-content.es.js +1 -1
  62. package/dist/domains/chat/activity/components/stretch-thought.cjs.js +1 -1
  63. package/dist/domains/chat/activity/components/stretch-thought.es.js +1 -1
  64. package/dist/domains/chat/activity/model/activity-segments.cjs.js +1 -1
  65. package/dist/domains/chat/activity/model/activity-segments.es.js +1 -1
  66. package/dist/domains/chat/activity/model/activity-words.cjs.js +2 -2
  67. package/dist/domains/chat/activity/model/activity-words.es.js +2 -2
  68. package/dist/domains/chat/components/badge-wrapper.cjs.js +1 -1
  69. package/dist/domains/chat/components/badge-wrapper.es.js +1 -1
  70. package/dist/domains/chat/knowledge/knowledge-links.cjs.js +52 -6
  71. package/dist/domains/chat/knowledge/knowledge-links.cjs.js.map +1 -1
  72. package/dist/domains/chat/knowledge/knowledge-links.es.js +53 -9
  73. package/dist/domains/chat/knowledge/knowledge-links.es.js.map +1 -1
  74. package/dist/domains/chat/knowledge/pinned-knowledge-data.cjs.js +10 -3
  75. package/dist/domains/chat/knowledge/pinned-knowledge-data.cjs.js.map +1 -1
  76. package/dist/domains/chat/knowledge/pinned-knowledge-data.es.js +10 -3
  77. package/dist/domains/chat/knowledge/pinned-knowledge-data.es.js.map +1 -1
  78. package/dist/domains/chat/knowledge/pinned-knowledge.cjs.js +8 -3
  79. package/dist/domains/chat/knowledge/pinned-knowledge.cjs.js.map +1 -1
  80. package/dist/domains/chat/knowledge/pinned-knowledge.es.js +8 -3
  81. package/dist/domains/chat/knowledge/pinned-knowledge.es.js.map +1 -1
  82. package/dist/domains/chat/knowledge.cjs.js +2 -0
  83. package/dist/domains/chat/knowledge.es.js +2 -2
  84. package/dist/domains/chat/messages/message-row.cjs.js +3 -3
  85. package/dist/domains/chat/messages/message-row.es.js +3 -3
  86. package/dist/domains/chat/messages/notification-signal-notice.cjs.js +1 -1
  87. package/dist/domains/chat/messages/notification-signal-notice.es.js +1 -1
  88. package/dist/domains/chat/messages/reasoning-content.cjs.js +1 -1
  89. package/dist/domains/chat/messages/reasoning-content.es.js +1 -1
  90. package/dist/domains/chat/messages/renderers/message-text.cjs.js +35 -1
  91. package/dist/domains/chat/messages/renderers/message-text.cjs.js.map +1 -1
  92. package/dist/domains/chat/messages/renderers/message-text.es.js +36 -2
  93. package/dist/domains/chat/messages/renderers/message-text.es.js.map +1 -1
  94. package/dist/domains/chat/messages/renderers/reasoning-part-renderer.cjs.js +1 -1
  95. package/dist/domains/chat/messages/renderers/reasoning-part-renderer.es.js +1 -1
  96. package/dist/domains/chat/messages/signal-badge.cjs.js +1 -1
  97. package/dist/domains/chat/messages/signal-badge.es.js +1 -1
  98. package/dist/domains/chat/messages/skill-message.cjs.js +2 -2
  99. package/dist/domains/chat/messages/skill-message.es.js +2 -2
  100. package/dist/domains/chat/messages/system-reminder-badge.cjs.js +1 -1
  101. package/dist/domains/chat/messages/system-reminder-badge.es.js +1 -1
  102. package/dist/domains/chat/tools/badges/agent-badge-wrapper.cjs.js +1 -1
  103. package/dist/domains/chat/tools/badges/agent-badge-wrapper.es.js +1 -1
  104. package/dist/domains/chat/tools/badges/agent-badge.cjs.js +1 -1
  105. package/dist/domains/chat/tools/badges/agent-badge.es.js +1 -1
  106. package/dist/domains/chat/tools/badges/file-tree-badge.cjs.js +2 -2
  107. package/dist/domains/chat/tools/badges/file-tree-badge.es.js +2 -2
  108. package/dist/domains/chat/tools/badges/knowledge-body-range.cjs.js +80 -0
  109. package/dist/domains/chat/tools/badges/knowledge-body-range.cjs.js.map +1 -0
  110. package/dist/domains/chat/tools/badges/knowledge-body-range.d.ts +1 -0
  111. package/dist/domains/chat/tools/badges/knowledge-body-range.es.js +78 -0
  112. package/dist/domains/chat/tools/badges/knowledge-body-range.es.js.map +1 -0
  113. package/dist/domains/chat/tools/badges/knowledge-tool-badge.cjs.js +163 -13
  114. package/dist/domains/chat/tools/badges/knowledge-tool-badge.cjs.js.map +1 -1
  115. package/dist/domains/chat/tools/badges/knowledge-tool-badge.es.js +165 -15
  116. package/dist/domains/chat/tools/badges/knowledge-tool-badge.es.js.map +1 -1
  117. package/dist/domains/chat/tools/badges/mcp-input-request-badge.cjs.js +51 -0
  118. package/dist/domains/chat/tools/badges/mcp-input-request-badge.cjs.js.map +1 -0
  119. package/dist/domains/chat/tools/badges/mcp-input-request-badge.d.ts +1 -0
  120. package/dist/domains/chat/tools/badges/mcp-input-request-badge.es.js +49 -0
  121. package/dist/domains/chat/tools/badges/mcp-input-request-badge.es.js.map +1 -0
  122. package/dist/domains/chat/tools/badges/mcp-task-chip.cjs.js +7 -2
  123. package/dist/domains/chat/tools/badges/mcp-task-chip.cjs.js.map +1 -1
  124. package/dist/domains/chat/tools/badges/mcp-task-chip.es.js +7 -2
  125. package/dist/domains/chat/tools/badges/mcp-task-chip.es.js.map +1 -1
  126. package/dist/domains/chat/tools/badges/observation-marker-badge.cjs.js +2 -2
  127. package/dist/domains/chat/tools/badges/observation-marker-badge.es.js +2 -2
  128. package/dist/domains/chat/tools/badges/observation-marker-details.cjs.js +2 -2
  129. package/dist/domains/chat/tools/badges/observation-marker-details.es.js +2 -2
  130. package/dist/domains/chat/tools/badges/observation-renderer.cjs.js +1 -1
  131. package/dist/domains/chat/tools/badges/observation-renderer.es.js +1 -1
  132. package/dist/domains/chat/tools/badges/sandbox-execution-badge.cjs.js +2 -2
  133. package/dist/domains/chat/tools/badges/sandbox-execution-badge.es.js +2 -2
  134. package/dist/domains/chat/tools/badges/tool-approval-badge.cjs.js +1 -1
  135. package/dist/domains/chat/tools/badges/tool-approval-badge.es.js +1 -1
  136. package/dist/domains/chat/tools/badges/tool-badge.cjs.js +9 -4
  137. package/dist/domains/chat/tools/badges/tool-badge.cjs.js.map +1 -1
  138. package/dist/domains/chat/tools/badges/tool-badge.es.js +9 -4
  139. package/dist/domains/chat/tools/badges/tool-badge.es.js.map +1 -1
  140. package/dist/domains/chat/tools/badges/use-deferred-input-request.cjs.js +81 -0
  141. package/dist/domains/chat/tools/badges/use-deferred-input-request.cjs.js.map +1 -0
  142. package/dist/domains/chat/tools/badges/use-deferred-input-request.d.ts +1 -0
  143. package/dist/domains/chat/tools/badges/use-deferred-input-request.es.js +77 -0
  144. package/dist/domains/chat/tools/badges/use-deferred-input-request.es.js.map +1 -0
  145. package/dist/domains/chat/tools/badges/use-mcp-task-progress.cjs.js +11 -2
  146. package/dist/domains/chat/tools/badges/use-mcp-task-progress.cjs.js.map +1 -1
  147. package/dist/domains/chat/tools/badges/use-mcp-task-progress.es.js +11 -2
  148. package/dist/domains/chat/tools/badges/use-mcp-task-progress.es.js.map +1 -1
  149. package/dist/domains/chat/tools/badges/workflow-badge.cjs.js +1 -1
  150. package/dist/domains/chat/tools/badges/workflow-badge.es.js +1 -1
  151. package/dist/domains/chat/tools/connect-prompt-tool.cjs.js +79 -4
  152. package/dist/domains/chat/tools/connect-prompt-tool.cjs.js.map +1 -1
  153. package/dist/domains/chat/tools/connect-prompt-tool.es.js +79 -4
  154. package/dist/domains/chat/tools/connect-prompt-tool.es.js.map +1 -1
  155. package/dist/domains/chat/tools/mcp-input-request-tool.cjs.js +238 -0
  156. package/dist/domains/chat/tools/mcp-input-request-tool.cjs.js.map +1 -0
  157. package/dist/domains/chat/tools/mcp-input-request-tool.d.ts +1 -0
  158. package/dist/domains/chat/tools/mcp-input-request-tool.es.js +237 -0
  159. package/dist/domains/chat/tools/mcp-input-request-tool.es.js.map +1 -0
  160. package/dist/domains/chat/tools/mcp-input-request.cjs.js +40 -0
  161. package/dist/domains/chat/tools/mcp-input-request.cjs.js.map +1 -0
  162. package/dist/domains/chat/tools/mcp-input-request.d.ts +1 -0
  163. package/dist/domains/chat/tools/mcp-input-request.es.js +33 -0
  164. package/dist/domains/chat/tools/mcp-input-request.es.js.map +1 -0
  165. package/dist/domains/chat/tools/tool-card-kind.cjs.js +9 -4
  166. package/dist/domains/chat/tools/tool-card-kind.cjs.js.map +1 -1
  167. package/dist/domains/chat/tools/tool-card-kind.es.js +9 -5
  168. package/dist/domains/chat/tools/tool-card-kind.es.js.map +1 -1
  169. package/dist/domains/chat/tools/tool-card.cjs.js +1 -1
  170. package/dist/domains/chat/tools/tool-card.es.js +1 -1
  171. package/dist/domains/chat/tools/tool-groups.cjs.js +1 -1
  172. package/dist/domains/chat/tools/tool-groups.es.js +1 -1
  173. package/dist/domains/chat.cjs.js +5 -3
  174. package/dist/domains/chat.es.js +4 -4
  175. package/dist/domains/connect/types.cjs.js.map +1 -1
  176. package/dist/domains/connect/types.es.js.map +1 -1
  177. package/dist/domains/connect/use-user-connect.cjs.js +19 -2
  178. package/dist/domains/connect/use-user-connect.cjs.js.map +1 -1
  179. package/dist/domains/connect/use-user-connect.es.js +19 -2
  180. package/dist/domains/connect/use-user-connect.es.js.map +1 -1
  181. package/dist/domains/dashboards/components/dashboard-renderer.cjs.js +4 -3
  182. package/dist/domains/dashboards/components/dashboard-renderer.cjs.js.map +1 -1
  183. package/dist/domains/dashboards/components/dashboard-renderer.es.js +4 -3
  184. package/dist/domains/dashboards/components/dashboard-renderer.es.js.map +1 -1
  185. package/dist/domains/dashboards/components/widget-chrome.cjs.js +1 -1
  186. package/dist/domains/dashboards/components/widget-chrome.es.js +1 -1
  187. package/dist/domains/dashboards/components/widget-error.cjs.js +1 -1
  188. package/dist/domains/dashboards/components/widget-error.es.js +1 -1
  189. package/dist/domains/dashboards/hooks/use-widget-views.cjs.js +4 -3
  190. package/dist/domains/dashboards/hooks/use-widget-views.cjs.js.map +1 -1
  191. package/dist/domains/dashboards/hooks/use-widget-views.es.js +4 -3
  192. package/dist/domains/dashboards/hooks/use-widget-views.es.js.map +1 -1
  193. package/dist/domains/dashboards/kinds/scores/scores-widget.cjs.js +9 -6
  194. package/dist/domains/dashboards/kinds/scores/scores-widget.cjs.js.map +1 -1
  195. package/dist/domains/dashboards/kinds/scores/scores-widget.es.js +9 -6
  196. package/dist/domains/dashboards/kinds/scores/scores-widget.es.js.map +1 -1
  197. package/dist/domains/dashboards/kinds/table/table-tabs.cjs.js +2 -2
  198. package/dist/domains/dashboards/kinds/table/table-tabs.es.js +2 -2
  199. package/dist/domains/dashboards/kinds/table/table-widget.cjs.js +1 -1
  200. package/dist/domains/dashboards/kinds/table/table-widget.es.js +1 -1
  201. package/dist/domains/dashboards/kinds/timeseries/timeseries-widget.cjs.js +6 -5
  202. package/dist/domains/dashboards/kinds/timeseries/timeseries-widget.cjs.js.map +1 -1
  203. package/dist/domains/dashboards/kinds/timeseries/timeseries-widget.es.js +6 -5
  204. package/dist/domains/dashboards/kinds/timeseries/timeseries-widget.es.js.map +1 -1
  205. package/dist/domains/dashboards/lib/chrome.cjs.js +9 -2
  206. package/dist/domains/dashboards/lib/chrome.cjs.js.map +1 -1
  207. package/dist/domains/dashboards/lib/chrome.es.js +9 -2
  208. package/dist/domains/dashboards/lib/chrome.es.js.map +1 -1
  209. package/dist/domains/dashboards/widget-kind.cjs.js.map +1 -1
  210. package/dist/domains/dashboards/widget-kind.es.js.map +1 -1
  211. package/dist/domains/knowledge/components/KnowledgePageCard.cjs.js +48 -0
  212. package/dist/domains/knowledge/components/KnowledgePageCard.cjs.js.map +1 -0
  213. package/dist/domains/knowledge/components/KnowledgePageCard.d.ts +1 -0
  214. package/dist/domains/knowledge/components/KnowledgePageCard.es.js +47 -0
  215. package/dist/domains/knowledge/components/KnowledgePageCard.es.js.map +1 -0
  216. package/dist/domains/knowledge/components/KnowledgePageDetail.cjs.js +63 -5
  217. package/dist/domains/knowledge/components/KnowledgePageDetail.cjs.js.map +1 -1
  218. package/dist/domains/knowledge/components/KnowledgePageDetail.es.js +64 -6
  219. package/dist/domains/knowledge/components/KnowledgePageDetail.es.js.map +1 -1
  220. package/dist/domains/knowledge/components/KnowledgePageExplorer.cjs.js +485 -47
  221. package/dist/domains/knowledge/components/KnowledgePageExplorer.cjs.js.map +1 -1
  222. package/dist/domains/knowledge/components/KnowledgePageExplorer.es.js +487 -50
  223. package/dist/domains/knowledge/components/KnowledgePageExplorer.es.js.map +1 -1
  224. package/dist/domains/knowledge/components/KnowledgePageGraph.cjs.js +1051 -123
  225. package/dist/domains/knowledge/components/KnowledgePageGraph.cjs.js.map +1 -1
  226. package/dist/domains/knowledge/components/KnowledgePageGraph.es.js +1054 -126
  227. package/dist/domains/knowledge/components/KnowledgePageGraph.es.js.map +1 -1
  228. package/dist/domains/knowledge/components/KnowledgePageTree.cjs.js +75 -3
  229. package/dist/domains/knowledge/components/KnowledgePageTree.cjs.js.map +1 -1
  230. package/dist/domains/knowledge/components/KnowledgePageTree.es.js +76 -4
  231. package/dist/domains/knowledge/components/KnowledgePageTree.es.js.map +1 -1
  232. package/dist/domains/knowledge/lib/circleText.cjs.js +9 -0
  233. package/dist/domains/knowledge/lib/circleText.cjs.js.map +1 -0
  234. package/dist/domains/knowledge/lib/circleText.d.ts +1 -0
  235. package/dist/domains/knowledge/lib/circleText.es.js +8 -0
  236. package/dist/domains/knowledge/lib/circleText.es.js.map +1 -0
  237. package/dist/domains/knowledge/lib/fitViewport.cjs.js +82 -0
  238. package/dist/domains/knowledge/lib/fitViewport.cjs.js.map +1 -0
  239. package/dist/domains/knowledge/lib/fitViewport.d.ts +1 -0
  240. package/dist/domains/knowledge/lib/fitViewport.es.js +73 -0
  241. package/dist/domains/knowledge/lib/fitViewport.es.js.map +1 -0
  242. package/dist/domains/knowledge/lib/graphShape.cjs.js +524 -0
  243. package/dist/domains/knowledge/lib/graphShape.cjs.js.map +1 -0
  244. package/dist/domains/knowledge/lib/graphShape.d.ts +1 -0
  245. package/dist/domains/knowledge/lib/graphShape.es.js +499 -0
  246. package/dist/domains/knowledge/lib/graphShape.es.js.map +1 -0
  247. package/dist/domains/knowledge/lib/linkCountsText.cjs.js +11 -0
  248. package/dist/domains/knowledge/lib/linkCountsText.cjs.js.map +1 -0
  249. package/dist/domains/knowledge/lib/linkCountsText.d.ts +1 -0
  250. package/dist/domains/knowledge/lib/linkCountsText.es.js +10 -0
  251. package/dist/domains/knowledge/lib/linkCountsText.es.js.map +1 -0
  252. package/dist/domains/knowledge/lib/pageAddress.cjs.js +29 -0
  253. package/dist/domains/knowledge/lib/pageAddress.cjs.js.map +1 -0
  254. package/dist/domains/knowledge/lib/pageAddress.d.ts +1 -0
  255. package/dist/domains/knowledge/lib/pageAddress.es.js +27 -0
  256. package/dist/domains/knowledge/lib/pageAddress.es.js.map +1 -0
  257. package/dist/domains/knowledge/lib/pageGraph.cjs.js +11 -11
  258. package/dist/domains/knowledge/lib/pageGraph.cjs.js.map +1 -1
  259. package/dist/domains/knowledge/lib/pageGraph.es.js +11 -11
  260. package/dist/domains/knowledge/lib/pageGraph.es.js.map +1 -1
  261. package/dist/domains/knowledge/lib/pageRefs.cjs.js +69 -0
  262. package/dist/domains/knowledge/lib/pageRefs.cjs.js.map +1 -0
  263. package/dist/domains/knowledge/lib/pageRefs.d.ts +1 -0
  264. package/dist/domains/knowledge/lib/pageRefs.es.js +66 -0
  265. package/dist/domains/knowledge/lib/pageRefs.es.js.map +1 -0
  266. package/dist/domains/knowledge/lib/pageTree.cjs.js +5 -0
  267. package/dist/domains/knowledge/lib/pageTree.cjs.js.map +1 -1
  268. package/dist/domains/knowledge/lib/pageTree.es.js +5 -1
  269. package/dist/domains/knowledge/lib/pageTree.es.js.map +1 -1
  270. package/dist/domains/knowledge/lib/remarkKnowledgeLinks.cjs.js +82 -0
  271. package/dist/domains/knowledge/lib/remarkKnowledgeLinks.cjs.js.map +1 -0
  272. package/dist/domains/knowledge/lib/remarkKnowledgeLinks.d.ts +1 -0
  273. package/dist/domains/knowledge/lib/remarkKnowledgeLinks.es.js +78 -0
  274. package/dist/domains/knowledge/lib/remarkKnowledgeLinks.es.js.map +1 -0
  275. package/dist/domains/knowledge/lib/tooltipSide.cjs.js +77 -0
  276. package/dist/domains/knowledge/lib/tooltipSide.cjs.js.map +1 -0
  277. package/dist/domains/knowledge/lib/tooltipSide.d.ts +1 -0
  278. package/dist/domains/knowledge/lib/tooltipSide.es.js +75 -0
  279. package/dist/domains/knowledge/lib/tooltipSide.es.js.map +1 -0
  280. package/dist/domains/knowledge/lib/useLeavingNodes.cjs.js +65 -0
  281. package/dist/domains/knowledge/lib/useLeavingNodes.cjs.js.map +1 -0
  282. package/dist/domains/knowledge/lib/useLeavingNodes.d.ts +1 -0
  283. package/dist/domains/knowledge/lib/useLeavingNodes.es.js +62 -0
  284. package/dist/domains/knowledge/lib/useLeavingNodes.es.js.map +1 -0
  285. package/dist/domains/knowledge/lib/useStableWhile.cjs.js +15 -0
  286. package/dist/domains/knowledge/lib/useStableWhile.cjs.js.map +1 -0
  287. package/dist/domains/knowledge/lib/useStableWhile.d.ts +1 -0
  288. package/dist/domains/knowledge/lib/useStableWhile.es.js +14 -0
  289. package/dist/domains/knowledge/lib/useStableWhile.es.js.map +1 -0
  290. package/dist/domains/metrics/components/agent-runs-card.cjs.js +3 -3
  291. package/dist/domains/metrics/components/agent-runs-card.es.js +3 -3
  292. package/dist/domains/metrics/components/breakdown/breakdown-tab-body.cjs.js +1 -1
  293. package/dist/domains/metrics/components/breakdown/breakdown-tab-body.es.js +1 -1
  294. package/dist/domains/metrics/components/breakdown-card.cjs.js +1 -1
  295. package/dist/domains/metrics/components/breakdown-card.es.js +1 -1
  296. package/dist/domains/metrics/components/chart-area.cjs.js +1 -1
  297. package/dist/domains/metrics/components/chart-area.es.js +1 -1
  298. package/dist/domains/metrics/components/chart-card-error.cjs.js +1 -1
  299. package/dist/domains/metrics/components/chart-card-error.es.js +1 -1
  300. package/dist/domains/metrics/components/chart-card.cjs.js +1 -1
  301. package/dist/domains/metrics/components/chart-card.es.js +1 -1
  302. package/dist/domains/metrics/components/date-range-selector.cjs.js +1 -1
  303. package/dist/domains/metrics/components/date-range-selector.es.js +1 -1
  304. package/dist/domains/metrics/components/distinct-ids/distinct-ids-chart.cjs.js +3 -2
  305. package/dist/domains/metrics/components/distinct-ids/distinct-ids-chart.cjs.js.map +1 -1
  306. package/dist/domains/metrics/components/distinct-ids/distinct-ids-chart.es.js +3 -2
  307. package/dist/domains/metrics/components/distinct-ids/distinct-ids-chart.es.js.map +1 -1
  308. package/dist/domains/metrics/components/failure-rate-card.cjs.js +3 -2
  309. package/dist/domains/metrics/components/failure-rate-card.cjs.js.map +1 -1
  310. package/dist/domains/metrics/components/failure-rate-card.es.js +3 -2
  311. package/dist/domains/metrics/components/failure-rate-card.es.js.map +1 -1
  312. package/dist/domains/metrics/components/latency-card.cjs.js +3 -2
  313. package/dist/domains/metrics/components/latency-card.cjs.js.map +1 -1
  314. package/dist/domains/metrics/components/latency-card.es.js +3 -2
  315. package/dist/domains/metrics/components/latency-card.es.js.map +1 -1
  316. package/dist/domains/metrics/components/metrics-time-range-chip.cjs.js +1 -1
  317. package/dist/domains/metrics/components/metrics-time-range-chip.es.js +1 -1
  318. package/dist/domains/metrics/components/scores-card.cjs.js +2 -1
  319. package/dist/domains/metrics/components/scores-card.cjs.js.map +1 -1
  320. package/dist/domains/metrics/components/scores-card.es.js +2 -1
  321. package/dist/domains/metrics/components/scores-card.es.js.map +1 -1
  322. package/dist/domains/metrics/components/token-usage-card.cjs.js +3 -3
  323. package/dist/domains/metrics/components/token-usage-card.es.js +3 -3
  324. package/dist/domains/metrics/components/trace-aggregate-card.cjs.js +1 -1
  325. package/dist/domains/metrics/components/trace-aggregate-card.es.js +1 -1
  326. package/dist/domains/observability/components/observability-histogram.cjs.js +1 -1
  327. package/dist/domains/observability/components/observability-histogram.es.js +1 -1
  328. package/dist/domains/scores/components/trace-scores-list.cjs.js +2 -2
  329. package/dist/domains/scores/components/trace-scores-list.es.js +2 -2
  330. package/dist/domains/skills/skill-simple-form.cjs.js +1 -1
  331. package/dist/domains/skills/skill-simple-form.es.js +1 -1
  332. package/dist/domains/spans/components/spans-filter-bar.cjs.js +2 -2
  333. package/dist/domains/spans/components/spans-filter-bar.es.js +2 -2
  334. package/dist/domains/spans/hooks/use-spans-filter-bar.cjs.js +1 -1
  335. package/dist/domains/spans/hooks/use-spans-filter-bar.es.js +1 -1
  336. package/dist/domains/threads/components/threads-filter-bar.cjs.js +2 -2
  337. package/dist/domains/threads/components/threads-filter-bar.es.js +2 -2
  338. package/dist/domains/threads/hooks/use-threads-filter-bar.cjs.js +1 -1
  339. package/dist/domains/threads/hooks/use-threads-filter-bar.es.js +1 -1
  340. package/dist/domains/traces/components/span-payload/span-error-renderer.cjs.js +1 -1
  341. package/dist/domains/traces/components/span-payload/span-error-renderer.es.js +1 -1
  342. package/dist/domains/traces/components/span-payload/span-input-renderers.cjs.js +1 -1
  343. package/dist/domains/traces/components/span-payload/span-input-renderers.es.js +1 -1
  344. package/dist/domains/traces/components/span-payload/span-output-renderers.cjs.js +2 -2
  345. package/dist/domains/traces/components/span-payload/span-output-renderers.es.js +2 -2
  346. package/dist/domains/traces/components/span-payload/span-payload-messages.cjs.js +2 -2
  347. package/dist/domains/traces/components/span-payload/span-payload-messages.es.js +2 -2
  348. package/dist/domains/traces/components/span-payload/span-payload-primitives.cjs.js +1 -1
  349. package/dist/domains/traces/components/span-payload/span-payload-primitives.es.js +1 -1
  350. package/dist/domains/traces/components/span-payload/span-payload-processor.cjs.js +1 -1
  351. package/dist/domains/traces/components/span-payload/span-payload-processor.es.js +1 -1
  352. package/dist/domains/traces/components/span-payload/span-payload-tool.cjs.js +1 -1
  353. package/dist/domains/traces/components/span-payload/span-payload-tool.es.js +1 -1
  354. package/dist/domains/traces/components/span-payload/span-processor-mutations.cjs.js +1 -1
  355. package/dist/domains/traces/components/span-payload/span-processor-mutations.es.js +1 -1
  356. package/dist/domains/traces/components/span-payload/span-tools-section.cjs.js +1 -1
  357. package/dist/domains/traces/components/span-payload/span-tools-section.es.js +1 -1
  358. package/dist/domains/traces/components/span-timeline-row.cjs.js +1 -1
  359. package/dist/domains/traces/components/span-timeline-row.es.js +1 -1
  360. package/dist/domains/traces/components/span-timing-hover-card.cjs.js +1 -1
  361. package/dist/domains/traces/components/span-timing-hover-card.es.js +1 -1
  362. package/dist/domains/traces/components/trace-data-panel-view.cjs.js +8 -2
  363. package/dist/domains/traces/components/trace-data-panel-view.cjs.js.map +1 -1
  364. package/dist/domains/traces/components/trace-data-panel-view.es.js +8 -2
  365. package/dist/domains/traces/components/trace-data-panel-view.es.js.map +1 -1
  366. package/dist/domains/traces/components/trace-error-cell.cjs.js +1 -1
  367. package/dist/domains/traces/components/trace-error-cell.es.js +1 -1
  368. package/dist/domains/traces/components/traces-explorer/traces-explorer-filter-bar.cjs.js +2 -2
  369. package/dist/domains/traces/components/traces-explorer/traces-explorer-filter-bar.es.js +2 -2
  370. package/dist/domains/traces/components/traces-explorer/use-traces-filter-bar.cjs.js +1 -1
  371. package/dist/domains/traces/components/traces-explorer/use-traces-filter-bar.es.js +1 -1
  372. package/dist/domains/workflows/runs/workflow-run-list.cjs.js +1 -1
  373. package/dist/domains/workflows/runs/workflow-run-list.es.js +1 -1
  374. package/dist/domains/workflows/workflow/input/workflow-processor-input.cjs.js +2 -2
  375. package/dist/domains/workflows/workflow/input/workflow-processor-input.es.js +2 -2
  376. package/dist/domains/workflows/workflow/use-workflow-trigger.cjs.js +3 -3
  377. package/dist/domains/workflows/workflow/use-workflow-trigger.es.js +3 -3
  378. package/dist/domains/workflows/workflow/workflow-input-data.cjs.js +1 -1
  379. package/dist/domains/workflows/workflow/workflow-input-data.es.js +1 -1
  380. package/dist/domains/workflows/workflow/workflow-suspended-steps.cjs.js +2 -2
  381. package/dist/domains/workflows/workflow/workflow-suspended-steps.es.js +2 -2
  382. package/dist/domains/workflows/workflow/workflow-time-travel-form.cjs.js +2 -2
  383. package/dist/domains/workflows/workflow/workflow-time-travel-form.es.js +2 -2
  384. package/dist/domains/workspace/components/workspace-add-skill-dialog.cjs.js +1 -1
  385. package/dist/domains/workspace/components/workspace-add-skill-dialog.es.js +1 -1
  386. package/dist/domains/workspace/components/workspace-markdown-preview.cjs.js +1 -1
  387. package/dist/domains/workspace/components/workspace-markdown-preview.es.js +1 -1
  388. package/dist/{filter-bar-time-range-mg9JeYue.js → filter-bar-time-range-qlV8p7hp.js} +2 -2
  389. package/dist/{filter-bar-time-range-mg9JeYue.js.map → filter-bar-time-range-qlV8p7hp.js.map} +1 -1
  390. package/dist/{filter-bar-time-range-BA-pXMlo.cjs → filter-bar-time-range-zdM024JD.cjs} +2 -2
  391. package/dist/{filter-bar-time-range-BA-pXMlo.cjs.map → filter-bar-time-range-zdM024JD.cjs.map} +1 -1
  392. package/dist/lib/form/dynamic-form.cjs.js +2 -2
  393. package/dist/lib/form/dynamic-form.es.js +2 -2
  394. package/dist/lib/form/json-draft.cjs.js +1 -1
  395. package/dist/lib/form/json-draft.es.js +1 -1
  396. package/dist/lib/form/zod-provider.cjs.js +1 -1
  397. package/dist/lib/form/zod-provider.es.js +1 -1
  398. package/dist/{span-payload-primitives-B3RdahsC.js → span-payload-primitives-CKKIAVPJ.js} +4 -4
  399. package/dist/{span-payload-primitives-B3RdahsC.js.map → span-payload-primitives-CKKIAVPJ.js.map} +1 -1
  400. package/dist/{span-payload-primitives-_2d-pAOD.cjs → span-payload-primitives-D4tHWN2W.cjs} +4 -4
  401. package/dist/{span-payload-primitives-_2d-pAOD.cjs.map → span-payload-primitives-D4tHWN2W.cjs.map} +1 -1
  402. package/dist/src/domains/chat/knowledge/knowledge-links.d.ts +32 -4
  403. package/dist/src/domains/chat/knowledge/pinned-knowledge-data.d.ts +2 -0
  404. package/dist/src/domains/chat/tools/badges/knowledge-body-range.d.ts +12 -0
  405. package/dist/src/domains/chat/tools/badges/knowledge-tool-badge.d.ts +5 -2
  406. package/dist/src/domains/chat/tools/badges/mcp-input-request-badge.d.ts +18 -0
  407. package/dist/src/domains/chat/tools/badges/tool-badge.d.ts +4 -1
  408. package/dist/src/domains/chat/tools/badges/use-deferred-input-request.d.ts +44 -0
  409. package/dist/src/domains/chat/tools/badges/use-mcp-task-progress.d.ts +6 -1
  410. package/dist/src/domains/chat/tools/connect-prompt-tool.d.ts +10 -1
  411. package/dist/src/domains/chat/tools/mcp-input-request-tool.d.ts +18 -0
  412. package/dist/src/domains/chat/tools/mcp-input-request.d.ts +40 -0
  413. package/dist/src/domains/chat/tools/tool-card-kind.d.ts +4 -2
  414. package/dist/src/domains/chat/tools/tool-card.d.ts +1 -1
  415. package/dist/src/domains/connect/types.d.ts +16 -0
  416. package/dist/src/domains/dashboards/components/dashboard-renderer.d.ts +4 -2
  417. package/dist/src/domains/dashboards/hooks/use-widget-views.d.ts +4 -3
  418. package/dist/src/domains/dashboards/index.d.ts +1 -1
  419. package/dist/src/domains/dashboards/kinds/scores/scores-widget.d.ts +1 -1
  420. package/dist/src/domains/dashboards/lib/chrome.d.ts +6 -4
  421. package/dist/src/domains/dashboards/widget-kind.d.ts +12 -0
  422. package/dist/src/domains/knowledge/components/KnowledgePageCard.d.ts +23 -0
  423. package/dist/src/domains/knowledge/components/KnowledgePageExplorer.d.ts +29 -0
  424. package/dist/src/domains/knowledge/components/KnowledgePageGraph.d.ts +27 -1
  425. package/dist/src/domains/knowledge/components/KnowledgePageTree.d.ts +2 -1
  426. package/dist/src/domains/knowledge/lib/circleText.d.ts +2 -0
  427. package/dist/src/domains/knowledge/lib/fitViewport.d.ts +67 -0
  428. package/dist/src/domains/knowledge/lib/graphShape.d.ts +131 -0
  429. package/dist/src/domains/knowledge/lib/linkCountsText.d.ts +5 -0
  430. package/dist/src/domains/knowledge/lib/pageAddress.d.ts +5 -0
  431. package/dist/src/domains/knowledge/lib/pageGraph.d.ts +4 -4
  432. package/dist/src/domains/knowledge/lib/pageRefs.d.ts +15 -0
  433. package/dist/src/domains/knowledge/lib/pageTree.d.ts +2 -0
  434. package/dist/src/domains/knowledge/lib/remarkKnowledgeLinks.d.ts +13 -0
  435. package/dist/src/domains/knowledge/lib/tooltipSide.d.ts +40 -0
  436. package/dist/src/domains/knowledge/lib/useLeavingNodes.d.ts +14 -0
  437. package/dist/src/domains/knowledge/lib/useStableWhile.d.ts +5 -0
  438. package/dist/src/domains/knowledge/pageTypes.d.ts +6 -1
  439. package/dist/src/ds/components/DateTimeRangePicker/date-time-range-picker.d.ts +12 -1
  440. package/dist/src/ds/components/MarkdownRenderer/markdown-renderer.d.ts +8 -1
  441. package/dist/src/ds/components/MetricsCard/metrics-card-headline.d.ts +1 -1
  442. package/dist/src/ds/components/MetricsLineChart/metrics-line-chart.d.ts +8 -0
  443. package/dist/src/ds/components/ai/tool-call/tool-phrases.d.ts +6 -0
  444. package/dist/style.css +73 -2
  445. package/dist/{tool-approval-1qiB4hhG.cjs → tool-approval-CJvPDL7D.cjs} +4 -4
  446. package/dist/{tool-approval-1qiB4hhG.cjs.map → tool-approval-CJvPDL7D.cjs.map} +1 -1
  447. package/dist/{tool-approval-B6MFcaKV.js → tool-approval-DyN11vFA.js} +4 -4
  448. package/dist/{tool-approval-B6MFcaKV.js.map → tool-approval-DyN11vFA.js.map} +1 -1
  449. package/dist/{tool-call-Bu66PkD-.cjs → tool-call-DBn14X-3.cjs} +9 -3
  450. package/dist/{tool-call-Bu66PkD-.cjs.map → tool-call-DBn14X-3.cjs.map} +1 -1
  451. package/dist/{tool-call-Ch9-jjXU.js → tool-call-Dsj43lvJ.js} +9 -3
  452. package/dist/{tool-call-Ch9-jjXU.js.map → tool-call-Dsj43lvJ.js.map} +1 -1
  453. package/dist/{tool-card-DrqPZfPQ.cjs → tool-card-BOLXeKIp.cjs} +167 -126
  454. package/dist/tool-card-BOLXeKIp.cjs.map +1 -0
  455. package/dist/{tool-card-sO6P2Qj4.js → tool-card-HZ5bm7ue.js} +168 -127
  456. package/dist/tool-card-HZ5bm7ue.js.map +1 -0
  457. package/dist/{tool-presentation-DvCsb_kz.js → tool-presentation-CvibOP1J.js} +6 -1
  458. package/dist/tool-presentation-CvibOP1J.js.map +1 -0
  459. package/dist/{tool-presentation-CQlDEwgS.cjs → tool-presentation-D6nzVruN.cjs} +6 -1
  460. package/dist/tool-presentation-D6nzVruN.cjs.map +1 -0
  461. package/package.json +11 -11
  462. package/dist/MarkdownRenderer-2GOXQJEv.js.map +0 -1
  463. package/dist/MarkdownRenderer-CB8Z_CHc.cjs.map +0 -1
  464. package/dist/MetricsCard-CEB-f2sv.cjs.map +0 -1
  465. package/dist/MetricsCard-M8awJ2B_.js.map +0 -1
  466. package/dist/MetricsLineChart-BhHoduO0.js.map +0 -1
  467. package/dist/MetricsLineChart-CjBm4IXu.cjs.map +0 -1
  468. package/dist/date-time-range-picker-CTt7Od0P.cjs.map +0 -1
  469. package/dist/date-time-range-picker-DKh1K9Iy.js.map +0 -1
  470. package/dist/domains/knowledge/lib/pageLayout.cjs.js +0 -49
  471. package/dist/domains/knowledge/lib/pageLayout.cjs.js.map +0 -1
  472. package/dist/domains/knowledge/lib/pageLayout.d.ts +0 -1
  473. package/dist/domains/knowledge/lib/pageLayout.es.js +0 -48
  474. package/dist/domains/knowledge/lib/pageLayout.es.js.map +0 -1
  475. package/dist/src/domains/knowledge/lib/pageLayout.d.ts +0 -24
  476. package/dist/tool-card-DrqPZfPQ.cjs.map +0 -1
  477. package/dist/tool-card-sO6P2Qj4.js.map +0 -1
  478. package/dist/tool-presentation-CQlDEwgS.cjs.map +0 -1
  479. package/dist/tool-presentation-DvCsb_kz.js.map +0 -1
@@ -1,7 +1,16 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  require('../../../KnowledgePageGraph.css');const require_Txt = require("../../../Txt-BnoSqxKE.cjs");
3
+ const require_domains_knowledge_lib_linkCountsText = require("../lib/linkCountsText.cjs.js");
4
+ const require_domains_knowledge_components_KnowledgePageCard = require("./KnowledgePageCard.cjs.js");
5
+ const require_domains_knowledge_lib_pageTree = require("../lib/pageTree.cjs.js");
6
+ const require_domains_knowledge_lib_graphShape = require("../lib/graphShape.cjs.js");
7
+ const require_domains_knowledge_lib_circleText = require("../lib/circleText.cjs.js");
8
+ const require_domains_knowledge_lib_useLeavingNodes = require("../lib/useLeavingNodes.cjs.js");
9
+ const require_domains_knowledge_lib_fitViewport = require("../lib/fitViewport.cjs.js");
10
+ const require_domains_knowledge_lib_layout = require("../lib/layout.cjs.js");
11
+ const require_domains_knowledge_lib_pageAddress = require("../lib/pageAddress.cjs.js");
3
12
  const require_domains_knowledge_lib_pageGraph = require("../lib/pageGraph.cjs.js");
4
- const require_domains_knowledge_lib_pageLayout = require("../lib/pageLayout.cjs.js");
13
+ const require_domains_knowledge_lib_tooltipSide = require("../lib/tooltipSide.cjs.js");
5
14
  let react = require("react");
6
15
  let react_jsx_runtime = require("react/jsx-runtime");
7
16
  let lucide_react = require("lucide-react");
@@ -13,12 +22,29 @@ var SCOPE_STYLE = {
13
22
  background: "color-mix(in oklab, var(--chart-blue) 16%, var(--card))"
14
23
  };
15
24
  var PAGE_STYLE = { "--knowledge-color": "var(--border-strong)" };
25
+ /** A farther page drawn as a named circle: the legend's "Page in another branch" dot grown, same solid grey fill, name in the page background colour to read on it. */
26
+ var FAR_FILL = "var(--muted-foreground)";
27
+ var FAR_STYLE = {
28
+ "--knowledge-color": FAR_FILL,
29
+ background: FAR_FILL
30
+ };
16
31
  var PARENT_EDGE_STYLE = {
17
32
  stroke: "var(--foreground)",
18
33
  strokeOpacity: .45,
19
34
  strokeDasharray: "4 4",
20
35
  strokeWidth: 1.25
21
36
  };
37
+ var UP_EDGE_COLOR = "var(--chart-cyan)";
38
+ var UP_EDGE_STYLE = {
39
+ stroke: UP_EDGE_COLOR,
40
+ strokeWidth: 2.25
41
+ };
42
+ var UP_ARROW = {
43
+ type: _xyflow_react.MarkerType.ArrowClosed,
44
+ color: UP_EDGE_COLOR,
45
+ width: 14,
46
+ height: 14
47
+ };
22
48
  var MENTION_EDGE_COLOR = "var(--chart-blue)";
23
49
  var PARENT_ARROW_COLOR = "var(--muted-foreground)";
24
50
  var PARENT_ARROW = {
@@ -40,6 +66,38 @@ var GRANT_ARROW = {
40
66
  width: 13,
41
67
  height: 13
42
68
  };
69
+ var LINK_EDGE_COLOR = "var(--chart-green)";
70
+ var LINK_EDGE_STYLE = {
71
+ stroke: LINK_EDGE_COLOR,
72
+ strokeWidth: 1.25
73
+ };
74
+ var LINK_ARROW = {
75
+ type: _xyflow_react.MarkerType.ArrowClosed,
76
+ color: LINK_EDGE_COLOR,
77
+ width: 12,
78
+ height: 12
79
+ };
80
+ var DIRECTION_EDGE_STYLE = {
81
+ out: { stroke: LINK_EDGE_COLOR },
82
+ in: {
83
+ stroke: "var(--chart-orange)",
84
+ strokeDasharray: "6 3"
85
+ }
86
+ };
87
+ var DIRECTION_ARROW = {
88
+ out: LINK_ARROW,
89
+ in: {
90
+ type: _xyflow_react.MarkerType.ArrowClosed,
91
+ color: "var(--chart-orange)",
92
+ width: 12,
93
+ height: 12
94
+ }
95
+ };
96
+ var DOT_PARENT_EDGE_STYLE = {
97
+ stroke: "var(--foreground)",
98
+ strokeOpacity: .2,
99
+ strokeWidth: 1
100
+ };
43
101
  var PLACEHOLDER_STYLE = {
44
102
  background: "var(--card)",
45
103
  borderColor: "var(--chart-purple)",
@@ -62,44 +120,291 @@ function pinBadgeStyle(size) {
62
120
  }
63
121
  };
64
122
  }
65
- /** A scope or page: its kind on top, its name below, both inside the circle. */
123
+ /** How long a focus change loads before the graph says so. */
124
+ var LOADING_HINT_DELAY_MS = 150;
125
+ /** How long it holds the old layout for pages that never arrive before drawing what it has. */
126
+ var LOADING_RELEASE_MS = 4e3;
127
+ /** Most a tooltip is enlarged to offset a zoomed-out graph. */
128
+ var TOOLTIP_MAX_SCALE = 3;
129
+ /** Screen-space box of an element. */
130
+ function boxOf(el) {
131
+ const { left, top, right, bottom } = el.getBoundingClientRect();
132
+ return {
133
+ left,
134
+ top,
135
+ right,
136
+ bottom
137
+ };
138
+ }
139
+ /** The highlighted lines of the graph as screen-space segments, where the browser can measure them. */
140
+ function drawnLines(root) {
141
+ const lines = [];
142
+ for (const path of root.querySelectorAll(".react-flow__edge-path")) {
143
+ if (typeof path.getTotalLength !== "function" || typeof path.getScreenCTM !== "function") continue;
144
+ const matrix = path.getScreenCTM();
145
+ if (!matrix) continue;
146
+ const length = path.getTotalLength();
147
+ const start = path.getPointAtLength(0);
148
+ const end = path.getPointAtLength(length);
149
+ lines.push({
150
+ from: {
151
+ x: matrix.a * start.x + matrix.c * start.y + matrix.e,
152
+ y: matrix.b * start.x + matrix.d * start.y + matrix.f
153
+ },
154
+ to: {
155
+ x: matrix.a * end.x + matrix.c * end.y + matrix.e,
156
+ y: matrix.b * end.x + matrix.d * end.y + matrix.f
157
+ }
158
+ });
159
+ }
160
+ return lines;
161
+ }
162
+ /** Where a tooltip sits against its dot, and which way it grows from it. */
163
+ var TOOLTIP_PLACEMENT = {
164
+ top: {
165
+ tip: "bottom-full left-1/2 mb-2",
166
+ transform: "translateX(-50%)",
167
+ origin: "bottom center",
168
+ tail: "top-full left-1/2 -translate-x-1/2 -translate-y-1/2 border-r border-b"
169
+ },
170
+ bottom: {
171
+ tip: "top-full left-1/2 mt-2",
172
+ transform: "translateX(-50%)",
173
+ origin: "top center",
174
+ tail: "bottom-full left-1/2 -translate-x-1/2 translate-y-1/2 border-l border-t"
175
+ },
176
+ right: {
177
+ tip: "left-full top-1/2 ml-2",
178
+ transform: "translateY(-50%)",
179
+ origin: "center left",
180
+ tail: "right-full top-1/2 translate-x-1/2 -translate-y-1/2 border-l border-b"
181
+ },
182
+ left: {
183
+ tip: "right-full top-1/2 mr-2",
184
+ transform: "translateY(-50%)",
185
+ origin: "center right",
186
+ tail: "left-full top-1/2 -translate-x-1/2 -translate-y-1/2 border-r border-t"
187
+ }
188
+ };
189
+ /** The mark on a circle for a page that sits above others: layers for a scope, an up arrow for an ancestor page. */
190
+ function LevelIcon({ level }) {
191
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(level === "scope" ? lucide_react.Layers : lucide_react.ArrowUpToLine, {
192
+ "aria-hidden": true,
193
+ "data-testid": `knowledge-level-icon-${level}`,
194
+ className: "mr-1 inline-block size-3 align-text-bottom"
195
+ });
196
+ }
197
+ /** A page far from the focus: a small coloured dot that names itself on hover. */
198
+ function DotNode({ data }) {
199
+ const { page, size, color, path, ref, links, notShown } = data;
200
+ const [hover, setHover] = (0, react.useState)(false);
201
+ const dotRef = (0, react.useRef)(null);
202
+ const tipRef = (0, react.useRef)(null);
203
+ const [side, setSide] = (0, react.useState)("top");
204
+ const zoom = (0, _xyflow_react.useStore)((state) => state.transform[2]);
205
+ const tipScale = Math.min(Math.max(1 / zoom, 1), TOOLTIP_MAX_SCALE);
206
+ const standIn = require_domains_knowledge_lib_graphShape.isChildPlaceholder(page);
207
+ const group = require_domains_knowledge_lib_graphShape.isScopeGroup(page);
208
+ const hint = standIn ? "Hover or click to load them" : group ? "Click to show them" : null;
209
+ const children = !hint && page.childCount ? `${require_domains_knowledge_lib_pageTree.childCountLabel(page)} ${page.childCount === 1 ? "child" : "children"}` : null;
210
+ const kind = page.isScope ? page.displayLabel ?? "Scope" : "Page";
211
+ const linkText = links && (links.in > 0 || links.out > 0) ? require_domains_knowledge_lib_linkCountsText.linkCountsText(links, notShown) : null;
212
+ const label = [
213
+ page.name,
214
+ hint ?? path,
215
+ children,
216
+ linkText
217
+ ].filter(Boolean).join(" · ");
218
+ (0, react.useLayoutEffect)(() => {
219
+ const dot = dotRef.current;
220
+ const tip = tipRef.current;
221
+ const graph = dot?.closest(".knowledge-graph");
222
+ if (!hover || !dot || !tip || !graph) return;
223
+ const dotBox = boxOf(dot);
224
+ const tipBox = boxOf(tip);
225
+ const scaledWidth = tip.offsetWidth * tipScale;
226
+ const scaledHeight = tip.offsetHeight * tipScale;
227
+ if (!scaledWidth || !scaledHeight) return;
228
+ const obstacles = [...graph.querySelectorAll("[data-testid=\"knowledge-page-node\"], [data-testid=\"knowledge-page-dot\"]"), ...(graph.parentElement ?? graph).querySelectorAll("[aria-label=\"Legend\"], [data-testid=\"knowledge-graph-back\"], .react-flow__controls")].map(boxOf).filter((box) => box.right > box.left && !(box.left === tipBox.left && box.top === tipBox.top) && !(box.left === dotBox.left && box.top === dotBox.top));
229
+ setSide(require_domains_knowledge_lib_tooltipSide.chooseTooltipSide({
230
+ dot: dotBox,
231
+ tip: {
232
+ width: scaledWidth,
233
+ height: scaledHeight
234
+ },
235
+ gap: 8,
236
+ bounds: boxOf(graph),
237
+ obstacles,
238
+ lines: drawnLines(graph)
239
+ }));
240
+ }, [hover, tipScale]);
241
+ const placement = TOOLTIP_PLACEMENT[side];
242
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
243
+ ref: dotRef,
244
+ "data-testid": "knowledge-page-dot",
245
+ "data-page-id": page.id,
246
+ "data-page-type": standIn ? "stand-in" : group ? "group" : page.isScope ? "scope" : "page",
247
+ "aria-label": label,
248
+ className: "relative cursor-pointer transition-opacity",
249
+ style: {
250
+ width: size,
251
+ height: size,
252
+ opacity: standIn ? .5 : void 0
253
+ },
254
+ onPointerEnter: () => setHover(true),
255
+ onPointerLeave: () => setHover(false),
256
+ children: [
257
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
258
+ "aria-hidden": true,
259
+ "data-testid": "knowledge-dot-hit-area",
260
+ className: "absolute rounded-full",
261
+ style: { inset: -8 }
262
+ }),
263
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
264
+ className: "size-full rounded-full border",
265
+ style: {
266
+ background: standIn ? "transparent" : color ?? "var(--muted-foreground)",
267
+ borderColor: color ?? "var(--muted-foreground)",
268
+ borderStyle: standIn ? "dashed" : "solid"
269
+ },
270
+ children: data.showCount && !standIn && !group && links && links.in + links.out > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
271
+ as: "span",
272
+ variant: "meta",
273
+ "data-testid": "knowledge-dot-count",
274
+ className: "flex size-full items-center justify-center",
275
+ style: { color: "var(--background)" },
276
+ children: links.in + links.out
277
+ }) : null
278
+ }),
279
+ hover ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
280
+ role: "tooltip",
281
+ ref: tipRef,
282
+ "data-side": side,
283
+ className: `pointer-events-none absolute ${placement.tip} flex w-max max-w-72 flex-col rounded-md border border-border bg-card px-2 py-1 shadow-overlay`,
284
+ style: {
285
+ transform: `${placement.transform} scale(${tipScale})`,
286
+ transformOrigin: placement.origin
287
+ },
288
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
289
+ "data-testid": "knowledge-tooltip-tail",
290
+ "aria-hidden": true,
291
+ className: `absolute size-2 rotate-45 border-border bg-card ${placement.tail}`
292
+ }), hint ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
293
+ as: "span",
294
+ variant: "label",
295
+ tone: "ink",
296
+ children: page.name
297
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
298
+ as: "span",
299
+ variant: "meta",
300
+ tone: "muted",
301
+ children: group ? `${path} · ${hint}` : hint
302
+ })] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_domains_knowledge_components_KnowledgePageCard.KnowledgePageCard, {
303
+ name: page.name,
304
+ kind,
305
+ pageRef: ref,
306
+ path,
307
+ childCount: page.childCount ? require_domains_knowledge_lib_pageTree.childCountLabel(page) : void 0,
308
+ links,
309
+ notShown
310
+ })]
311
+ }) : null,
312
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_xyflow_react.Handle, {
313
+ type: "target",
314
+ position: _xyflow_react.Position.Top,
315
+ className: "!invisible"
316
+ }),
317
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_xyflow_react.Handle, {
318
+ type: "source",
319
+ position: _xyflow_react.Position.Bottom,
320
+ className: "!invisible"
321
+ })
322
+ ]
323
+ });
324
+ }
325
+ /** Below this a circle uses the small type and two lines of name. */
326
+ var COMPACT_CIRCLE_SIZE = 96;
327
+ /** The share of a circle's width its text may use; a circle is narrower toward the top and bottom. */
328
+ var CIRCLE_TEXT_SHARE = .74;
329
+ /** A scope or page: its kind on top, its name below, both inside the circle; far pages draw as dots. */
66
330
  function PageNodeComponent({ data }) {
67
- const { page, size, selected, pinned, dimmed } = data;
331
+ if (data.form === "dot") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DotNode, { data });
332
+ const { page, size, selected, pinned, badge } = data;
333
+ const group = require_domains_knowledge_lib_graphShape.isScopeGroup(page);
68
334
  const kind = page.isScope ? page.displayLabel ?? "Scope" : "Page";
69
335
  const placeholder = isPlaceholder(page);
336
+ const rest = require_domains_knowledge_lib_graphShape.isRestCircle(page);
337
+ const compact = size < COMPACT_CIRCLE_SIZE;
338
+ const fit = Math.max(4, Math.floor(size * CIRCLE_TEXT_SHARE / (compact ? 6.5 : 7.5)));
70
339
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
71
340
  "data-testid": "knowledge-page-node",
72
341
  "data-page-id": page.id,
73
- "data-page-type": placeholder ? "placeholder" : page.isScope ? "scope" : "page",
342
+ "data-page-type": placeholder ? "placeholder" : rest ? "rest" : group ? "group" : page.isScope ? "scope" : "page",
74
343
  className: `relative transition-opacity ${placeholder ? "cursor-default" : "cursor-pointer"}`,
75
344
  style: {
76
345
  width: size,
77
- height: size,
78
- opacity: dimmed ? .35 : 1
346
+ height: size
79
347
  },
80
- title: placeholder ? `${kind} · ${page.address} · nothing written to it yet` : page.isScope && page.address ? `${kind} · ${page.address}` : page.name,
348
+ title: placeholder ? `${kind} · ${page.address} · nothing written to it yet` : rest ? `Show ${Math.min(12, page.childCount ?? 12)} more of ${page.childCount ?? "the rest"}` : group ? `${page.name}: click to show them` : page.isScope && page.address ? `${kind} · ${page.address}` : data.links && data.links.in + data.links.out > 0 ? `${page.name} · ${require_domains_knowledge_lib_linkCountsText.linkCountsText(data.links, data.notShown)}` : page.name,
81
349
  children: [
82
350
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
83
- className: "knowledge-circle flex size-full flex-col items-center justify-center gap-0.5 overflow-hidden rounded-full border-2 px-3 text-center shadow-raised",
351
+ className: `knowledge-circle flex size-full flex-col items-center justify-center gap-0.5 overflow-hidden rounded-full border-2 text-center shadow-raised ${rest ? "hover:border-foreground" : ""}`,
84
352
  "data-selected": selected || void 0,
85
- style: placeholder ? PLACEHOLDER_STYLE : page.isScope ? SCOPE_STYLE : PAGE_STYLE,
86
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
353
+ "data-far": data.far || void 0,
354
+ style: {
355
+ ...placeholder || rest ? PLACEHOLDER_STYLE : data.far ? FAR_STYLE : page.isScope ? SCOPE_STYLE : PAGE_STYLE,
356
+ paddingInline: size * (.26 / 2)
357
+ },
358
+ children: [data.far ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_Txt.Txt, {
87
359
  as: "span",
88
360
  variant: "meta",
89
361
  tone: page.isScope ? void 0 : "muted",
90
- className: "pointer-events-none line-clamp-2 max-w-full tracking-wide uppercase",
362
+ className: "pointer-events-none inline-flex max-w-full items-center justify-center gap-1 whitespace-nowrap uppercase",
91
363
  style: page.isScope ? { color: "var(--chart-blue)" } : void 0,
92
364
  "data-testid": page.isScope ? "knowledge-scope-caption" : "knowledge-page-caption",
93
- children: kind
365
+ children: [data.level ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LevelIcon, { level: data.level }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
366
+ className: "truncate",
367
+ children: rest ? "More" : data.isParent ? "Parent" : kind
368
+ })]
94
369
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
95
370
  as: "span",
96
- variant: "label",
371
+ variant: compact ? "meta" : "label",
97
372
  tone: "ink",
98
- className: "pointer-events-none line-clamp-3 max-w-full break-words",
99
- children: page.isScope && page.address ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BreakAtColons, { text: page.address }) : page.name
373
+ className: `pointer-events-none max-w-full overflow-hidden [overflow-wrap:normal] ${compact ? "line-clamp-2" : "line-clamp-3"}`,
374
+ style: data.far ? { color: "var(--background)" } : void 0,
375
+ "data-testid": "knowledge-circle-name",
376
+ children: page.isScope && page.address && !group ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BreakAtColons, { text: require_domains_knowledge_lib_circleText.fitWords(page.address, fit) }) : require_domains_knowledge_lib_circleText.fitWords(page.name, fit)
100
377
  })]
101
378
  }),
102
379
  pinned ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PinBadge, { size }) : null,
380
+ data.hiddenLinks && (data.hiddenLinks.in > 0 || data.hiddenLinks.out > 0) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
381
+ "data-testid": "knowledge-hidden-links",
382
+ title: require_domains_knowledge_lib_linkCountsText.linkCountsText(data.hiddenLinks),
383
+ "aria-label": require_domains_knowledge_lib_linkCountsText.linkCountsText(data.hiddenLinks),
384
+ className: "absolute bottom-full left-1/2 -mb-1 flex -translate-x-1/2 gap-1 rounded-full border border-border bg-card px-1.5 shadow-raised",
385
+ children: [data.hiddenLinks.in > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_Txt.Txt, {
386
+ as: "span",
387
+ variant: "meta",
388
+ style: { color: "var(--chart-orange)" },
389
+ children: ["→", data.hiddenLinks.in]
390
+ }) : null, data.hiddenLinks.out > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_Txt.Txt, {
391
+ as: "span",
392
+ variant: "meta",
393
+ style: { color: LINK_EDGE_COLOR },
394
+ children: [data.hiddenLinks.out, "→"]
395
+ }) : null]
396
+ }) : null,
397
+ badge ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
398
+ "data-testid": "knowledge-child-count-badge",
399
+ "aria-label": `${badge} children, not all drawn`,
400
+ className: "absolute top-full left-1/2 -mt-1 -translate-x-1/2 rounded-full border border-border bg-card px-1.5 shadow-raised",
401
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
402
+ as: "span",
403
+ variant: "meta",
404
+ tone: "ink",
405
+ children: badge
406
+ })
407
+ }) : null,
103
408
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_xyflow_react.Handle, {
104
409
  type: "target",
105
410
  position: _xyflow_react.Position.Top,
@@ -156,10 +461,7 @@ function RimEdgeComponent({ id, data, style, markerEnd }) {
156
461
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_xyflow_react.BaseEdge, {
157
462
  id,
158
463
  path,
159
- style: {
160
- ...style,
161
- opacity: data.dimmed ? .2 : 1
162
- },
464
+ style,
163
465
  markerEnd,
164
466
  interactionWidth: mention ? 20 : 0
165
467
  }), data.kind === "grant" && data.role ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
@@ -173,7 +475,7 @@ function RimEdgeComponent({ id, data, style, markerEnd }) {
173
475
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("title", { children: `Grants ${data.role}` })
174
476
  }) : null] });
175
477
  }
176
- var edgeTypes = { rim: RimEdgeComponent };
478
+ var edgeTypes = { rim: (0, react.memo)(RimEdgeComponent) };
177
479
  var nodeTypes = { page: (0, react.memo)(PageNodeComponent) };
178
480
  /** The box around laid-out circles, in graph coordinates; `null` when there are none. */
179
481
  function graphBounds(nodes) {
@@ -197,7 +499,7 @@ function graphBounds(nodes) {
197
499
  }
198
500
  var LEGEND_SWATCH = "knowledge-circle inline-block size-3 shrink-0 rounded-full border-2";
199
501
  /** What the circles, lines and badge mean. */
200
- function GraphLegend({ grants }) {
502
+ function GraphLegend({ drawn, counts, dots, linkEnds, focused, levels, branches }) {
201
503
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("ul", {
202
504
  "aria-label": "Legend",
203
505
  className: "pointer-events-none absolute top-2 left-2 z-10 flex flex-col gap-1 rounded-md border border-border bg-card/90 px-2 py-1.5 shadow-raised",
@@ -215,6 +517,32 @@ function GraphLegend({ grants }) {
215
517
  children: "Scope"
216
518
  })]
217
519
  }),
520
+ levels.includes("scope") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
521
+ className: "flex items-center gap-2",
522
+ "data-testid": "knowledge-legend-level-scope",
523
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Layers, {
524
+ "aria-hidden": true,
525
+ className: "size-3 shrink-0 text-muted-foreground"
526
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
527
+ as: "span",
528
+ variant: "meta",
529
+ tone: "muted",
530
+ children: "Scope, above its pages"
531
+ })]
532
+ }) : null,
533
+ levels.includes("ancestor") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
534
+ className: "flex items-center gap-2",
535
+ "data-testid": "knowledge-legend-level-ancestor",
536
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ArrowUpToLine, {
537
+ "aria-hidden": true,
538
+ className: "size-3 shrink-0 text-muted-foreground"
539
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
540
+ as: "span",
541
+ variant: "meta",
542
+ tone: "muted",
543
+ children: "Page above the focus"
544
+ })]
545
+ }) : null,
218
546
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
219
547
  className: "flex items-center gap-2",
220
548
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -228,8 +556,122 @@ function GraphLegend({ grants }) {
228
556
  children: "Page"
229
557
  })]
230
558
  }),
231
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
559
+ focused ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
560
+ className: "flex items-center gap-2",
561
+ "data-testid": "knowledge-legend-focused",
562
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
563
+ className: LEGEND_SWATCH,
564
+ style: {
565
+ ...PAGE_STYLE,
566
+ outline: "2px solid var(--knowledge-color)",
567
+ outlineOffset: 2,
568
+ borderWidth: 3
569
+ },
570
+ "aria-hidden": true
571
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
572
+ as: "span",
573
+ variant: "meta",
574
+ tone: "muted",
575
+ children: "Focused page"
576
+ })]
577
+ }) : null,
578
+ dots || linkEnds ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
579
+ className: "flex items-center gap-2",
580
+ "data-testid": "knowledge-legend-dot",
581
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
582
+ className: "inline-block size-2 shrink-0 rounded-full bg-muted-foreground",
583
+ "aria-hidden": true
584
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
585
+ as: "span",
586
+ variant: "meta",
587
+ tone: "muted",
588
+ children: "Page in another branch"
589
+ })]
590
+ }) : null,
591
+ branches.slice(0, LEGEND_BRANCH_CAP).map((branch) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
592
+ className: "flex items-center gap-2 pl-0.5",
593
+ "data-testid": "knowledge-legend-branch",
594
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
595
+ className: "inline-block size-2 shrink-0 rounded-full",
596
+ style: { background: branch.color },
597
+ "aria-hidden": true
598
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
599
+ as: "span",
600
+ variant: "meta",
601
+ tone: "muted",
602
+ className: "max-w-40 truncate",
603
+ title: branch.name,
604
+ children: branches.length > 1 ? `Under ${branch.name}` : branch.scope ? "Under parent scope" : "Under parent page"
605
+ })]
606
+ }, branch.id)),
607
+ branches.length > LEGEND_BRANCH_CAP ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
608
+ className: "pl-0.5",
609
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_Txt.Txt, {
610
+ as: "span",
611
+ variant: "meta",
612
+ tone: "muted",
613
+ children: [
614
+ "+",
615
+ branches.length - LEGEND_BRANCH_CAP,
616
+ " more branches"
617
+ ]
618
+ })
619
+ }) : null,
620
+ drawn.has("out") || drawn.has("in") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [drawn.has("out") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
232
621
  className: "flex items-center gap-2",
622
+ "data-testid": "knowledge-legend-out",
623
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
624
+ width: "16",
625
+ height: "8",
626
+ "aria-hidden": true,
627
+ className: "shrink-0",
628
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
629
+ x1: "0",
630
+ y1: "4",
631
+ x2: "12",
632
+ y2: "4",
633
+ stroke: LINK_EDGE_COLOR,
634
+ strokeWidth: "1.5"
635
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("polygon", {
636
+ points: "11,1 16,4 11,7",
637
+ fill: LINK_EDGE_COLOR
638
+ })]
639
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
640
+ as: "span",
641
+ variant: "meta",
642
+ tone: "muted",
643
+ children: "Links out of the selected page"
644
+ })]
645
+ }) : null, drawn.has("in") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
646
+ className: "flex items-center gap-2",
647
+ "data-testid": "knowledge-legend-in",
648
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
649
+ width: "16",
650
+ height: "8",
651
+ "aria-hidden": true,
652
+ className: "shrink-0",
653
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
654
+ x1: "0",
655
+ y1: "4",
656
+ x2: "12",
657
+ y2: "4",
658
+ stroke: "var(--chart-orange)",
659
+ strokeWidth: "1.5",
660
+ strokeDasharray: "3 2"
661
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("polygon", {
662
+ points: "11,1 16,4 11,7",
663
+ fill: "var(--chart-orange)"
664
+ })]
665
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
666
+ as: "span",
667
+ variant: "meta",
668
+ tone: "muted",
669
+ children: "Links into it"
670
+ })]
671
+ }) : null] }) : null,
672
+ drawn.has("mention") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
673
+ className: "flex items-center gap-2",
674
+ "data-testid": "knowledge-legend-mention",
233
675
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
234
676
  width: "12",
235
677
  height: "4",
@@ -249,8 +691,81 @@ function GraphLegend({ grants }) {
249
691
  tone: "muted",
250
692
  children: "Mentioned in notes"
251
693
  })]
252
- }),
253
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
694
+ }) : null,
695
+ drawn.has("link") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
696
+ className: "flex items-center gap-2",
697
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
698
+ width: "16",
699
+ height: "8",
700
+ "aria-hidden": true,
701
+ className: "shrink-0",
702
+ "data-testid": "knowledge-legend-link",
703
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
704
+ x1: "0",
705
+ y1: "4",
706
+ x2: "12",
707
+ y2: "4",
708
+ ...LINK_EDGE_STYLE
709
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("polygon", {
710
+ points: "11,1 16,4 11,7",
711
+ fill: LINK_EDGE_COLOR
712
+ })]
713
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
714
+ as: "span",
715
+ variant: "meta",
716
+ tone: "muted",
717
+ children: "Linked in page body"
718
+ })]
719
+ }) : null,
720
+ drawn.has("dot-parent") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
721
+ className: "flex items-center gap-2",
722
+ "data-testid": "knowledge-legend-dot-parent",
723
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
724
+ width: "16",
725
+ height: "4",
726
+ "aria-hidden": true,
727
+ className: "shrink-0",
728
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
729
+ x1: "0",
730
+ y1: "2",
731
+ x2: "16",
732
+ y2: "2",
733
+ ...DOT_PARENT_EDGE_STYLE,
734
+ strokeOpacity: .5
735
+ })
736
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
737
+ as: "span",
738
+ variant: "meta",
739
+ tone: "muted",
740
+ children: "Child page (dot)"
741
+ })]
742
+ }) : null,
743
+ drawn.has("up") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
744
+ className: "flex items-center gap-2",
745
+ "data-testid": "knowledge-legend-up",
746
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
747
+ width: "16",
748
+ height: "8",
749
+ "aria-hidden": true,
750
+ className: "shrink-0",
751
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
752
+ x1: "0",
753
+ y1: "4",
754
+ x2: "12",
755
+ y2: "4",
756
+ ...UP_EDGE_STYLE
757
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("polygon", {
758
+ points: "9,1 15,4 9,7",
759
+ fill: UP_EDGE_COLOR
760
+ })]
761
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
762
+ as: "span",
763
+ variant: "meta",
764
+ tone: "muted",
765
+ children: "Parent of the focused page"
766
+ })]
767
+ }) : null,
768
+ drawn.has("parent") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
254
769
  className: "flex items-center gap-2",
255
770
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
256
771
  width: "16",
@@ -279,8 +794,32 @@ function GraphLegend({ grants }) {
279
794
  tone: "muted",
280
795
  children: "Parent → child"
281
796
  })]
282
- }),
283
- grants ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
797
+ }) : null,
798
+ counts ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
799
+ className: "flex items-center gap-2",
800
+ "data-testid": "knowledge-legend-link-counts",
801
+ children: [
802
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
803
+ as: "span",
804
+ variant: "meta",
805
+ style: { color: "var(--chart-orange)" },
806
+ children: "→4"
807
+ }),
808
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
809
+ as: "span",
810
+ variant: "meta",
811
+ style: { color: LINK_EDGE_COLOR },
812
+ children: "14→"
813
+ }),
814
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
815
+ as: "span",
816
+ variant: "meta",
817
+ tone: "muted",
818
+ children: "Links in, links out (not drawn)"
819
+ })
820
+ ]
821
+ }) : null,
822
+ drawn.has("grant") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
284
823
  className: "flex items-center gap-2",
285
824
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
286
825
  width: "16",
@@ -325,14 +864,82 @@ function GraphLegend({ grants }) {
325
864
  }
326
865
  /** How far the pointer may move between press and release and still count as a click, not a pan. */
327
866
  var CLICK_SLOP_PX = 4;
867
+ /** Marks the nodes and lines that stay lit while the rest of the graph fades (see knowledge.css). */
868
+ var NEIGHBOUR_CLASS = "knowledge-neighbour";
869
+ /**
870
+ * The same edge objects while their content is unchanged. Pointing at a page changes the style of the
871
+ * few lines touching it; handing React Flow fresh objects for every line would redraw them all.
872
+ */
873
+ function useStableEdges(edges) {
874
+ const seen = (0, react.useRef)(/* @__PURE__ */ new Map());
875
+ return (0, react.useMemo)(() => {
876
+ const next = /* @__PURE__ */ new Map();
877
+ const result = edges.map((edge) => {
878
+ const sig = JSON.stringify(edge);
879
+ const before = seen.current.get(edge.id);
880
+ const entry = before && before.sig === sig ? before : {
881
+ sig,
882
+ edge
883
+ };
884
+ next.set(edge.id, entry);
885
+ return entry.edge;
886
+ });
887
+ seen.current = next;
888
+ return result;
889
+ }, [edges]);
890
+ }
891
+ /** The focused page's circle is this much larger than its neighbours'. */
892
+ var FOCUSED_SCALE = 1.2;
893
+ /** Pages in other branches that the focus links to draw a little smaller than its own neighbours. */
894
+ var LINK_END_SCALE = .8;
895
+ /** Most branch colours the legend names; the rest are counted. */
896
+ var LEGEND_BRANCH_CAP = 4;
897
+ /** Most links a hovered page draws that aren't drawn already. */
898
+ var HOVER_LINK_CAP = 40;
328
899
  /**
329
900
  * The schema-4 Knowledge page graph: scopes and pages as circles sized by how often they are mentioned,
330
901
  * parent links as faint edges and mentions as solid ones. The first layout is deterministic for the same pages; later updates start from where pages already sit.
331
902
  */
332
903
  function KnowledgePageGraph(props) {
333
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_xyflow_react.ReactFlowProvider, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(KnowledgePageGraphInner, { ...props }) });
904
+ const { settled = true } = props;
905
+ const held = (0, react.useRef)(props);
906
+ const [released, setReleased] = (0, react.useState)(false);
907
+ const holding = !settled && !released;
908
+ if (!holding) held.current = props;
909
+ const shown = !holding ? props : {
910
+ ...props,
911
+ pages: held.current.pages,
912
+ edges: held.current.edges,
913
+ pinnedIds: held.current.pinnedIds,
914
+ grants: held.current.grants,
915
+ selectedPageId: held.current.selectedPageId,
916
+ centerId: held.current.centerId,
917
+ hiddenLinks: held.current.hiddenLinks,
918
+ knownLinks: held.current.knownLinks,
919
+ nearIds: held.current.nearIds
920
+ };
921
+ const [slow, setSlow] = (0, react.useState)(false);
922
+ (0, react.useEffect)(() => {
923
+ if (settled) {
924
+ setSlow(false);
925
+ setReleased(false);
926
+ return;
927
+ }
928
+ const hint = setTimeout(() => setSlow(true), LOADING_HINT_DELAY_MS);
929
+ const deadline = setTimeout(() => setReleased(true), LOADING_RELEASE_MS);
930
+ return () => {
931
+ clearTimeout(hint);
932
+ clearTimeout(deadline);
933
+ };
934
+ }, [settled, props.selectedPageId]);
935
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_xyflow_react.ReactFlowProvider, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(KnowledgePageGraphInner, { ...shown }), slow && holding ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
936
+ role: "status",
937
+ "data-testid": "knowledge-graph-loading",
938
+ className: "text-ui-sm pointer-events-none absolute bottom-3 left-1/2 z-10 -translate-x-1/2 rounded border border-border bg-card px-3 py-1 text-muted-foreground shadow-overlay",
939
+ children: "Loading pages…"
940
+ }) : null] });
334
941
  }
335
- function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selectedPageId, onSelect, onOpen, onClearSelection, onMentionSelect }) {
942
+ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selectedPageId, centerId, hiddenLinks, knownLinks, nearIds, exactLinkCounts, fetchedLinks, onHover, showCounts, onPreview, onSelect, onOpen, onClearSelection, onMentionSelect }) {
336
943
  const { graphPages, allEdges } = (0, react.useMemo)(() => {
337
944
  const granted = require_domains_knowledge_lib_pageGraph.grantGraph(pages, grants);
338
945
  return {
@@ -344,28 +951,167 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
344
951
  edges,
345
952
  grants
346
953
  ]);
347
- const lastLayout = (0, react.useRef)(void 0);
954
+ const linkSource = knownLinks ?? edges;
955
+ const linkCounts = (0, react.useMemo)(() => {
956
+ const counts = /* @__PURE__ */ new Map();
957
+ const pairs = /* @__PURE__ */ new Set();
958
+ for (const edge of linkSource) {
959
+ if (edge.kind !== "mention" && edge.kind !== "link") continue;
960
+ if (edge.source === edge.target || pairs.has(`${edge.source}\u0000${edge.target}`)) continue;
961
+ pairs.add(`${edge.source}\u0000${edge.target}`);
962
+ const out = counts.get(edge.source) ?? {
963
+ in: 0,
964
+ out: 0
965
+ };
966
+ out.out++;
967
+ counts.set(edge.source, out);
968
+ const into = counts.get(edge.target) ?? {
969
+ in: 0,
970
+ out: 0
971
+ };
972
+ into.in++;
973
+ counts.set(edge.target, into);
974
+ }
975
+ for (const [id, exact] of exactLinkCounts ?? []) counts.set(id, exact);
976
+ return counts;
977
+ }, [linkSource, exactLinkCounts]);
978
+ const hoverLinks = (0, react.useMemo)(() => {
979
+ const touching = /* @__PURE__ */ new Map();
980
+ const add = (id, edge) => {
981
+ const list = touching.get(id);
982
+ if (list) list.push(edge);
983
+ else touching.set(id, [edge]);
984
+ };
985
+ for (const edge of [...linkSource, ...fetchedLinks ?? []]) {
986
+ if (edge.kind !== "mention" && edge.kind !== "link") continue;
987
+ add(edge.source, edge);
988
+ if (edge.target !== edge.source) add(edge.target, edge);
989
+ }
990
+ return touching;
991
+ }, [linkSource, fetchedLinks]);
348
992
  const laidOut = (0, react.useMemo)(() => {
993
+ const shape = require_domains_knowledge_lib_graphShape.graphShape(graphPages, selectedPageId ?? centerId ?? null, nearIds);
994
+ const colors = require_domains_knowledge_lib_graphShape.branchColors(graphPages, shape);
349
995
  const flow = require_domains_knowledge_lib_pageGraph.toPageFlow(graphPages, allEdges);
350
- const layout = require_domains_knowledge_lib_pageLayout.layoutPageGraph(lastLayout.current, flow.nodes.map((node) => ({
996
+ for (const node of flow.nodes) if (shape.form.get(node.id) === "dot") {
997
+ const links = linkCounts.get(node.id);
998
+ const counted = showCounts && !require_domains_knowledge_lib_graphShape.isChildPlaceholder(node.data.page) && !!links && links.in + links.out > 0;
999
+ node.data.size = counted ? 28 : 20;
1000
+ } else if (node.id === shape.center) node.data.size = Math.round(node.data.size * FOCUSED_SCALE);
1001
+ else node.data.size = Math.round(108 * (shape.linked.has(node.id) ? LINK_END_SCALE : 1));
1002
+ const ring = flow.nodes.filter((node) => shape.depth.get(node.id) === 1 && shape.form.get(node.id) === "full");
1003
+ const crowd = require_domains_knowledge_lib_graphShape.crowdScale(ring.length);
1004
+ if (crowd < 1) for (const node of ring) node.data.size = Math.round(node.data.size * crowd);
1005
+ const sizes = new Map(flow.nodes.map((node) => [node.id, node.data.size]));
1006
+ const radial = require_domains_knowledge_lib_graphShape.radialLayout(graphPages, shape, (page) => sizes.get(page.id) ?? 20, nearIds);
1007
+ const positions = require_domains_knowledge_lib_layout.runLayout(flow.nodes.map((node) => ({
351
1008
  id: node.id,
352
- size: node.data.size
353
- })), flow.edges.map((edge) => ({
354
- source: edge.source,
355
- target: edge.target
356
- })));
357
- lastLayout.current = layout;
1009
+ size: node.data.size,
1010
+ padding: shape.form.get(node.id) === "dot" ? 4 : 24,
1011
+ initial: radial.get(node.id)
1012
+ })), [], { ticks: 0 });
358
1013
  return {
359
1014
  nodes: flow.nodes,
360
1015
  edges: flow.edges,
361
- positions: layout.positions
1016
+ positions,
1017
+ shape,
1018
+ colors
362
1019
  };
363
- }, [graphPages, allEdges]);
364
- const pinned = (0, react.useMemo)(() => new Set(pinnedIds), [pinnedIds]);
365
- const neighbours = (0, react.useMemo)(() => selectedPageId && laidOut.positions.has(selectedPageId) ? require_domains_knowledge_lib_pageGraph.pageNeighbourIds(selectedPageId, allEdges) : null, [
1020
+ }, [
1021
+ graphPages,
1022
+ allEdges,
366
1023
  selectedPageId,
1024
+ centerId,
1025
+ linkCounts,
1026
+ showCounts,
1027
+ nearIds
1028
+ ]);
1029
+ const pageById = (0, react.useMemo)(() => new Map(graphPages.map((page) => [page.id, page])), [graphPages]);
1030
+ const focusParentId = (0, react.useMemo)(() => {
1031
+ const parentId = laidOut.shape.center ? pageById.get(laidOut.shape.center)?.parentId : void 0;
1032
+ return parentId && laidOut.positions.has(parentId) ? parentId : null;
1033
+ }, [laidOut, pageById]);
1034
+ const drawnLevels = (0, react.useMemo)(() => {
1035
+ const kinds = /* @__PURE__ */ new Set();
1036
+ for (const [id, level] of laidOut.shape.level) if (laidOut.shape.form.get(id) === "full") kinds.add(level);
1037
+ return [...kinds];
1038
+ }, [laidOut]);
1039
+ const dotBranches = (0, react.useMemo)(() => {
1040
+ const seen = /* @__PURE__ */ new Map();
1041
+ for (const node of laidOut.nodes) {
1042
+ if (laidOut.shape.form.get(node.id) !== "dot" || require_domains_knowledge_lib_graphShape.isChildPlaceholder(node.data.page)) continue;
1043
+ const branch = laidOut.shape.branch.get(node.id);
1044
+ const color = branch ? laidOut.colors.get(branch) : void 0;
1045
+ const owner = branch ? pageById.get(branch) : void 0;
1046
+ if (branch && color && owner && !seen.has(branch)) seen.set(branch, {
1047
+ id: branch,
1048
+ name: owner.displayLabel ?? owner.name,
1049
+ color,
1050
+ scope: !!owner.isScope
1051
+ });
1052
+ }
1053
+ return [...seen.values()];
1054
+ }, [laidOut, pageById]);
1055
+ const pinned = (0, react.useMemo)(() => new Set(pinnedIds), [pinnedIds]);
1056
+ const childrenUndrawn = (0, react.useMemo)(() => {
1057
+ const drawn = /* @__PURE__ */ new Map();
1058
+ for (const page of graphPages) if (page.parentId && !require_domains_knowledge_lib_graphShape.isChildPlaceholder(page) && !require_domains_knowledge_lib_graphShape.isRestCircle(page)) drawn.set(page.parentId, (drawn.get(page.parentId) ?? 0) + 1);
1059
+ return new Set(graphPages.filter((page) => !require_domains_knowledge_lib_graphShape.isScopeGroup(page) && !require_domains_knowledge_lib_graphShape.isRestCircle(page) && (page.childCountCapped || (page.childCount ?? 0) > (drawn.get(page.id) ?? 0))).map((page) => page.id));
1060
+ }, [graphPages]);
1061
+ const [hoveredId, setHoveredId] = (0, react.useState)(null);
1062
+ (0, react.useEffect)(() => onHover?.(hoveredId), [hoveredId, onHover]);
1063
+ const hoverExtra = (0, react.useMemo)(() => {
1064
+ if (!hoveredId) return [];
1065
+ const drawnIds = new Set(laidOut.nodes.map((node) => node.id));
1066
+ const have = new Set(laidOut.edges.map((edge) => edge.id));
1067
+ const extra = [];
1068
+ for (const edge of hoverLinks.get(hoveredId) ?? []) {
1069
+ const id = `${edge.kind}:${edge.source}->${edge.target}`;
1070
+ if (have.has(id) || !drawnIds.has(edge.source) || !drawnIds.has(edge.target)) continue;
1071
+ have.add(id);
1072
+ extra.push({
1073
+ id,
1074
+ source: edge.source,
1075
+ target: edge.target,
1076
+ data: {
1077
+ kind: edge.kind,
1078
+ count: edge.count ?? 1
1079
+ }
1080
+ });
1081
+ if (extra.length >= HOVER_LINK_CAP) break;
1082
+ }
1083
+ return extra;
1084
+ }, [
1085
+ hoveredId,
1086
+ hoverLinks,
1087
+ laidOut
1088
+ ]);
1089
+ const hoveredNotShown = (0, react.useMemo)(() => {
1090
+ const total = hoveredId ? linkCounts.get(hoveredId) : void 0;
1091
+ if (!hoveredId || !total) return 0;
1092
+ const pairs = /* @__PURE__ */ new Set();
1093
+ for (const edge of [...laidOut.edges, ...hoverExtra]) {
1094
+ const kind = edge.data?.kind;
1095
+ if (kind !== "mention" && kind !== "link" || edge.source !== hoveredId && edge.target !== hoveredId) continue;
1096
+ pairs.add(`${edge.source}\u0000${edge.target}`);
1097
+ }
1098
+ return Math.max(0, total.in + total.out - pairs.size);
1099
+ }, [
1100
+ hoveredId,
1101
+ linkCounts,
367
1102
  laidOut,
368
- allEdges
1103
+ hoverExtra
1104
+ ]);
1105
+ const emphasisId = hoveredId && laidOut.positions.has(hoveredId) ? hoveredId : selectedPageId ?? null;
1106
+ const neighbours = (0, react.useMemo)(() => emphasisId && laidOut.positions.has(emphasisId) ? require_domains_knowledge_lib_pageGraph.pageNeighbourIds(emphasisId, [...allEdges, ...hoverExtra.map((edge) => ({
1107
+ kind: edge.data?.kind ?? "link",
1108
+ source: edge.source,
1109
+ target: edge.target
1110
+ }))]) : null, [
1111
+ emphasisId,
1112
+ laidOut,
1113
+ allEdges,
1114
+ hoverExtra
369
1115
  ]);
370
1116
  const nodes = (0, react.useMemo)(() => laidOut.nodes.map((node) => {
371
1117
  const center = laidOut.positions.get(node.id) ?? {
@@ -399,16 +1145,32 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
399
1145
  ...node.data,
400
1146
  selected: node.id === selectedPageId,
401
1147
  pinned: pinned.has(node.id),
402
- dimmed: !!neighbours && !neighbours.has(node.id)
1148
+ form: laidOut.shape.form.get(node.id) ?? "full",
1149
+ color: laidOut.colors.get(laidOut.shape.branch.get(node.id) ?? ""),
1150
+ badge: childrenUndrawn.has(node.id) ? require_domains_knowledge_lib_pageTree.childCountLabel(node.data.page) : void 0,
1151
+ path: require_domains_knowledge_lib_pageAddress.pagePath(node.data.page, pageById),
1152
+ hiddenLinks: laidOut.shape.form.get(node.id) === "full" ? hiddenLinks?.get(node.id) : void 0,
1153
+ ref: require_domains_knowledge_lib_pageAddress.pageRef(node.data.page, pageById),
1154
+ links: linkCounts.get(node.id),
1155
+ showCount: showCounts,
1156
+ level: laidOut.shape.form.get(node.id) === "full" ? laidOut.shape.level.get(node.id) : void 0,
1157
+ isParent: node.id === focusParentId,
1158
+ far: laidOut.shape.linked.has(node.id) || void 0
403
1159
  }
404
1160
  };
405
1161
  }), [
406
1162
  laidOut,
407
1163
  selectedPageId,
408
1164
  pinned,
409
- neighbours
1165
+ childrenUndrawn,
1166
+ pageById,
1167
+ hiddenLinks,
1168
+ linkCounts,
1169
+ showCounts,
1170
+ focusParentId
410
1171
  ]);
411
- const flowEdges = (0, react.useMemo)(() => {
1172
+ const { flowEdges: builtEdges, drawnEdgeStyles } = (0, react.useMemo)(() => {
1173
+ const drawn = /* @__PURE__ */ new Set();
412
1174
  const sizes = new Map(laidOut.nodes.map((node) => [node.id, node.data.size]));
413
1175
  const circle = (id) => {
414
1176
  return {
@@ -419,71 +1181,168 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
419
1181
  r: (sizes.get(id) ?? 0) / 2
420
1182
  };
421
1183
  };
422
- return laidOut.edges.map((edge) => {
423
- const mention = edge.data?.kind === "mention";
424
- const grant = edge.data?.kind === "grant";
425
- const dimmed = !!neighbours && !(neighbours.has(edge.source) && neighbours.has(edge.target));
426
- return {
427
- ...edge,
428
- type: "rim",
429
- data: {
430
- kind: edge.data?.kind ?? "parent",
431
- count: edge.data?.count ?? 1,
432
- ...edge.data?.role ? { role: edge.data.role } : {},
433
- from: circle(edge.source),
434
- to: circle(edge.target),
435
- dimmed
436
- },
437
- ...mention && onMentionSelect ? { className: "cursor-pointer" } : {},
438
- style: mention ? {
439
- stroke: MENTION_EDGE_COLOR,
440
- strokeWidth: Math.min(1.5 + (edge.data?.count ?? 1) * .5, 4)
441
- } : grant ? GRANT_EDGE_STYLE : PARENT_EDGE_STYLE,
442
- markerEnd: mention ? {
443
- type: _xyflow_react.MarkerType.ArrowClosed,
444
- color: MENTION_EDGE_COLOR,
445
- width: 14,
446
- height: 14
447
- } : grant ? GRANT_ARROW : PARENT_ARROW
448
- };
449
- });
1184
+ return {
1185
+ flowEdges: [...laidOut.edges, ...hoverExtra].map((edge) => {
1186
+ const mention = edge.data?.kind === "mention";
1187
+ const grant = edge.data?.kind === "grant";
1188
+ const link = edge.data?.kind === "link";
1189
+ const toDot = laidOut.shape.form.get(edge.target) === "dot";
1190
+ const direction = (mention || link) && emphasisId ? edge.source === emphasisId ? "out" : edge.target === emphasisId ? "in" : void 0 : void 0;
1191
+ const up = !mention && !grant && !link && edge.source === focusParentId && edge.target === laidOut.shape.center;
1192
+ drawn.add(direction ?? (up ? "up" : mention ? "mention" : grant ? "grant" : link ? "link" : toDot ? "dot-parent" : "parent"));
1193
+ return {
1194
+ ...edge,
1195
+ type: "rim",
1196
+ data: {
1197
+ kind: edge.data?.kind ?? "parent",
1198
+ count: edge.data?.count ?? 1,
1199
+ ...edge.data?.role ? { role: edge.data.role } : {},
1200
+ from: circle(edge.source),
1201
+ to: circle(edge.target)
1202
+ },
1203
+ ...direction === "in" ? { zIndex: 1 } : {},
1204
+ ...mention && onMentionSelect ? { className: "cursor-pointer" } : {},
1205
+ style: direction ? {
1206
+ ...DIRECTION_EDGE_STYLE[direction],
1207
+ strokeWidth: mention ? 2 : 1.5
1208
+ } : mention ? {
1209
+ stroke: MENTION_EDGE_COLOR,
1210
+ strokeWidth: Math.min(1.5 + (edge.data?.count ?? 1) * .5, 4)
1211
+ } : up ? UP_EDGE_STYLE : grant ? GRANT_EDGE_STYLE : link ? LINK_EDGE_STYLE : toDot ? DOT_PARENT_EDGE_STYLE : PARENT_EDGE_STYLE,
1212
+ markerEnd: direction ? DIRECTION_ARROW[direction] : up ? UP_ARROW : mention ? {
1213
+ type: _xyflow_react.MarkerType.ArrowClosed,
1214
+ color: MENTION_EDGE_COLOR,
1215
+ width: 14,
1216
+ height: 14
1217
+ } : grant ? GRANT_ARROW : link ? LINK_ARROW : toDot ? void 0 : PARENT_ARROW
1218
+ };
1219
+ }),
1220
+ drawnEdgeStyles: drawn
1221
+ };
450
1222
  }, [
451
1223
  laidOut,
1224
+ hoverExtra,
452
1225
  onMentionSelect,
453
- neighbours
1226
+ emphasisId,
1227
+ focusParentId
1228
+ ]);
1229
+ const flowEdges = useStableEdges(builtEdges);
1230
+ const emphasisedNodes = (0, react.useMemo)(() => nodes.map((node) => {
1231
+ const near = neighbours?.has(node.id);
1232
+ const hovered = node.id === hoveredId && hoveredNotShown > 0;
1233
+ if (!near && !hovered) return node;
1234
+ return {
1235
+ ...node,
1236
+ ...near ? { className: NEIGHBOUR_CLASS } : {},
1237
+ ...hovered ? { data: {
1238
+ ...node.data,
1239
+ notShown: hoveredNotShown
1240
+ } } : {}
1241
+ };
1242
+ }), [
1243
+ nodes,
1244
+ neighbours,
1245
+ hoveredId,
1246
+ hoveredNotShown
454
1247
  ]);
1248
+ const emphasisedEdges = (0, react.useMemo)(() => neighbours ? flowEdges.map((edge) => neighbours.has(edge.source) && neighbours.has(edge.target) ? {
1249
+ ...edge,
1250
+ className: [edge.className, NEIGHBOUR_CLASS].filter(Boolean).join(" ")
1251
+ } : edge) : flowEdges, [flowEdges, neighbours]);
455
1252
  const pagesById = (0, react.useMemo)(() => new Map(pages.map((page) => [page.id, page])), [pages]);
456
1253
  const reactFlow = (0, _xyflow_react.useReactFlow)();
457
1254
  const containerRef = (0, react.useRef)(null);
458
1255
  const hasNodes = nodes.length > 0;
1256
+ const drawnNodes = require_domains_knowledge_lib_useLeavingNodes.useLeavingNodes(emphasisedNodes, require_domains_knowledge_lib_useLeavingNodes.prefersMotion());
1257
+ const linkedIds = laidOut.shape.linked;
459
1258
  const fitState = (0, react.useRef)({
460
1259
  nodes,
461
- allEdges,
462
1260
  selectedPageId,
463
- reactFlow
1261
+ centerId,
1262
+ reactFlow,
1263
+ linkedIds
464
1264
  });
465
1265
  fitState.current = {
466
1266
  nodes,
467
- allEdges,
468
1267
  selectedPageId,
469
- reactFlow
1268
+ centerId,
1269
+ reactFlow,
1270
+ linkedIds
470
1271
  };
471
1272
  const fitPending = (0, react.useRef)(false);
472
- const fit = (0, react.useCallback)((focusSelection, duration) => {
1273
+ const paneAndNodes = () => {
473
1274
  const container = containerRef.current;
474
1275
  const width = container?.clientWidth ?? 0;
475
1276
  const height = container?.clientHeight ?? 0;
476
1277
  if (width === 0 || height === 0) {
477
1278
  fitPending.current = true;
478
- return;
1279
+ return null;
479
1280
  }
480
1281
  fitPending.current = false;
481
- const { nodes: current, allEdges: edgesNow, selectedPageId: selected, reactFlow: flow } = fitState.current;
482
- const focus = focusSelection && selected ? require_domains_knowledge_lib_pageGraph.pageNeighbourIds(selected, edgesNow) : null;
483
- const bounds = graphBounds(focus ? current.filter((node) => focus.has(node.id)) : current);
484
- if (!bounds) return;
485
- const viewport = (0, _xyflow_react.getViewportForBounds)(bounds, width, height, .1, focus ? 1.5 : 2, focus ? .3 : .1);
486
- flow.setViewport(viewport, duration ? { duration } : void 0);
1282
+ const { nodes: current, reactFlow: flow } = fitState.current;
1283
+ const bounds = graphBounds(current);
1284
+ return bounds ? {
1285
+ container,
1286
+ width,
1287
+ height,
1288
+ current,
1289
+ flow,
1290
+ bounds
1291
+ } : null;
1292
+ };
1293
+ const fit = (0, react.useCallback)((duration) => {
1294
+ const view = paneAndNodes();
1295
+ if (!view) return;
1296
+ const { selectedPageId: selected, centerId: centre, linkedIds: linked } = fitState.current;
1297
+ const anchor = view.current.find((node) => node.id === (selected ?? centre));
1298
+ const ring = !!selected && view.current.some((node) => linked.has(node.id));
1299
+ const viewport = require_domains_knowledge_lib_fitViewport.fitViewport({
1300
+ bounds: view.bounds,
1301
+ width: view.width,
1302
+ height: view.height,
1303
+ ring,
1304
+ anchor
1305
+ });
1306
+ view.flow.setViewport(viewport, duration ? { duration } : void 0);
1307
+ }, []);
1308
+ const fitInitial = (0, react.useCallback)(() => {
1309
+ const view = paneAndNodes();
1310
+ if (!view) return;
1311
+ const box = view.container?.getBoundingClientRect();
1312
+ const legend = view.container?.querySelector("[aria-label=\"Legend\"]")?.getBoundingClientRect();
1313
+ const viewport = require_domains_knowledge_lib_fitViewport.fitAllViewport({
1314
+ bounds: view.bounds,
1315
+ nodes: view.current.map((node) => ({
1316
+ x: node.position.x,
1317
+ y: node.position.y,
1318
+ width: node.width ?? 0,
1319
+ height: node.height ?? 0
1320
+ })),
1321
+ width: view.width,
1322
+ height: view.height,
1323
+ legend: box && legend ? {
1324
+ right: legend.right - box.left + 8,
1325
+ bottom: legend.bottom - box.top + 8
1326
+ } : void 0
1327
+ });
1328
+ view.flow.setViewport(viewport);
1329
+ }, []);
1330
+ const nudgeToSelection = (0, react.useCallback)((duration) => {
1331
+ const container = containerRef.current;
1332
+ const width = container?.clientWidth ?? 0;
1333
+ const height = container?.clientHeight ?? 0;
1334
+ const { nodes: current, selectedPageId: selected, centerId: centre, reactFlow: flow } = fitState.current;
1335
+ const anchor = current.find((node) => node.id === (selected ?? centre));
1336
+ if (!anchor || width === 0 || height === 0) return;
1337
+ const view = flow.getViewport();
1338
+ const dx = require_domains_knowledge_lib_fitViewport.nudgeAxis(anchor.position.x * view.zoom + view.x, (anchor.width ?? 0) * view.zoom, width);
1339
+ const dy = require_domains_knowledge_lib_fitViewport.nudgeAxis(anchor.position.y * view.zoom + view.y, (anchor.height ?? 0) * view.zoom, height);
1340
+ if (dx === 0 && dy === 0) return;
1341
+ flow.setViewport({
1342
+ zoom: view.zoom,
1343
+ x: view.x + dx,
1344
+ y: view.y + dy
1345
+ }, duration ? { duration } : void 0);
487
1346
  }, []);
488
1347
  (0, react.useEffect)(() => {
489
1348
  const container = containerRef.current;
@@ -493,10 +1352,12 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
493
1352
  height: container.clientHeight
494
1353
  };
495
1354
  let frame;
1355
+ let needsFit = false;
496
1356
  const observer = new ResizeObserver(([entry]) => {
497
1357
  if (!entry) return;
498
1358
  const { width, height } = entry.contentRect;
499
1359
  const changed = width !== last.width || height !== last.height;
1360
+ if (last.width === 0 || last.height === 0) needsFit = true;
500
1361
  last = {
501
1362
  width,
502
1363
  height
@@ -505,7 +1366,10 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
505
1366
  if (frame !== void 0) cancelAnimationFrame(frame);
506
1367
  frame = requestAnimationFrame(() => {
507
1368
  frame = void 0;
508
- fit(true);
1369
+ if (needsFit || fitPending.current) {
1370
+ needsFit = false;
1371
+ fitInitial();
1372
+ } else nudgeToSelection();
509
1373
  });
510
1374
  });
511
1375
  observer.observe(container);
@@ -513,33 +1377,51 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
513
1377
  observer.disconnect();
514
1378
  if (frame !== void 0) cancelAnimationFrame(frame);
515
1379
  };
516
- }, [hasNodes, fit]);
1380
+ }, [
1381
+ hasNodes,
1382
+ fitInitial,
1383
+ nudgeToSelection
1384
+ ]);
517
1385
  const selectedHere = (0, react.useRef)(null);
518
1386
  const selectedIsLoaded = !!selectedPageId && pagesById.has(selectedPageId);
519
1387
  const initialized = (0, react.useRef)(false);
1388
+ const settleUntil = (0, react.useRef)(0);
1389
+ const settledOn = (0, react.useRef)(null);
1390
+ const fittedLayout = (0, react.useRef)("");
1391
+ const stopSettling = (0, react.useCallback)(() => {
1392
+ settleUntil.current = 0;
1393
+ }, []);
1394
+ (0, react.useEffect)(() => {
1395
+ if (!initialized.current) return;
1396
+ if ((selectedPageId ?? null) !== settledOn.current) settleUntil.current = 0;
1397
+ if (Date.now() >= settleUntil.current) return;
1398
+ const layout = nodes.map((node) => `${node.id}@${node.position.x},${node.position.y}`).join("|");
1399
+ if (layout === fittedLayout.current) return;
1400
+ fittedLayout.current = layout;
1401
+ fitInitial();
1402
+ }, [
1403
+ nodes,
1404
+ selectedPageId,
1405
+ fitInitial
1406
+ ]);
520
1407
  (0, react.useEffect)(() => {
521
1408
  if (!initialized.current || !selectedIsLoaded || !selectedPageId) return;
522
1409
  const fromGraph = selectedHere.current === selectedPageId;
523
1410
  selectedHere.current = null;
524
1411
  if (fromGraph) return;
525
- fit(true, 300);
1412
+ nudgeToSelection(require_domains_knowledge_lib_fitViewport.fitDuration(require_domains_knowledge_lib_useLeavingNodes.prefersMotion()));
526
1413
  }, [
527
1414
  selectedPageId,
528
1415
  selectedIsLoaded,
529
- fit
1416
+ nudgeToSelection
530
1417
  ]);
531
1418
  const activate = (page) => {
1419
+ if (require_domains_knowledge_lib_graphShape.isChildPlaceholder(page) || require_domains_knowledge_lib_graphShape.isScopeGroup(page) || require_domains_knowledge_lib_graphShape.isRestCircle(page)) return onSelect(page);
532
1420
  if (page.id === selectedPageId && onOpen) return onOpen(page);
533
1421
  selectedHere.current = page.id;
534
1422
  onSelect(page);
535
1423
  };
536
1424
  const pressedAt = (0, react.useRef)(null);
537
- const onPaneClick = (event) => {
538
- const start = pressedAt.current;
539
- pressedAt.current = null;
540
- if (start && Math.hypot(event.clientX - start.x, event.clientY - start.y) > CLICK_SLOP_PX) return;
541
- onClearSelection?.();
542
- };
543
1425
  const onKeyDown = (event) => {
544
1426
  if (event.key !== "Enter" && event.key !== " ") return;
545
1427
  const id = event.target.closest(".react-flow__node")?.dataset.id;
@@ -548,6 +1430,56 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
548
1430
  event.preventDefault();
549
1431
  activate(page);
550
1432
  };
1433
+ const latest = (0, react.useRef)({
1434
+ activate,
1435
+ onPreview,
1436
+ onMentionSelect,
1437
+ onClearSelection,
1438
+ laidOut,
1439
+ pagesById
1440
+ });
1441
+ latest.current = {
1442
+ activate,
1443
+ onPreview,
1444
+ onMentionSelect,
1445
+ onClearSelection,
1446
+ laidOut,
1447
+ pagesById
1448
+ };
1449
+ const onNodeMouseEnter = (0, react.useCallback)((_, node) => {
1450
+ setHoveredId(node.id);
1451
+ if (latest.current.laidOut.shape.form.get(node.id) === "dot") latest.current.onPreview?.(node.data.page);
1452
+ }, []);
1453
+ const onNodeMouseLeave = (0, react.useCallback)(() => setHoveredId(null), []);
1454
+ const onNodeClick = (0, react.useCallback)((_, node) => {
1455
+ if (!isPlaceholder(node.data.page)) latest.current.activate(node.data.page);
1456
+ }, []);
1457
+ const onEdgeClick = (0, react.useCallback)((event, edge) => {
1458
+ const { onMentionSelect, pagesById } = latest.current;
1459
+ if (edge.data?.kind !== "mention" || !onMentionSelect) return;
1460
+ const source = pagesById.get(edge.source);
1461
+ const target = pagesById.get(edge.target);
1462
+ if (!source || !target) return;
1463
+ const box = containerRef.current?.getBoundingClientRect();
1464
+ onMentionSelect({
1465
+ source,
1466
+ target,
1467
+ point: {
1468
+ x: event.clientX - (box?.left ?? 0),
1469
+ y: event.clientY - (box?.top ?? 0)
1470
+ },
1471
+ pane: {
1472
+ width: box?.width ?? 0,
1473
+ height: box?.height ?? 0
1474
+ }
1475
+ });
1476
+ }, []);
1477
+ const onPaneClick = (0, react.useCallback)((event) => {
1478
+ const start = pressedAt.current;
1479
+ pressedAt.current = null;
1480
+ if (start && Math.hypot(event.clientX - start.x, event.clientY - start.y) > CLICK_SLOP_PX) return;
1481
+ latest.current.onClearSelection?.();
1482
+ }, []);
551
1483
  if (!hasNodes) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
552
1484
  className: "flex h-full items-center justify-center p-6",
553
1485
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
@@ -558,51 +1490,47 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
558
1490
  });
559
1491
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
560
1492
  ref: containerRef,
561
- className: "relative size-full",
1493
+ className: "knowledge-graph relative size-full",
1494
+ "data-emphasis": neighbours ? "on" : void 0,
562
1495
  "data-testid": "knowledge-page-graph",
563
1496
  onKeyDown,
1497
+ onWheelCapture: stopSettling,
564
1498
  onPointerDownCapture: (event) => {
1499
+ stopSettling();
565
1500
  pressedAt.current = {
566
1501
  x: event.clientX,
567
1502
  y: event.clientY
568
1503
  };
569
1504
  },
570
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(GraphLegend, { grants: allEdges.some((edge) => edge.kind === "grant") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_xyflow_react.ReactFlow, {
571
- nodes,
572
- edges: flowEdges,
1505
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(GraphLegend, {
1506
+ branches: dotBranches,
1507
+ levels: drawnLevels,
1508
+ focused: !!selectedPageId && laidOut.positions.has(selectedPageId),
1509
+ dots: [...laidOut.shape.form.values()].includes("dot"),
1510
+ linkEnds: laidOut.shape.linked.size > 0,
1511
+ drawn: drawnEdgeStyles,
1512
+ counts: [...hiddenLinks ?? []].some(([id, hidden]) => laidOut.shape.form.get(id) === "full" && (hidden.in > 0 || hidden.out > 0))
1513
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_xyflow_react.ReactFlow, {
1514
+ nodes: drawnNodes,
1515
+ edges: emphasisedEdges,
573
1516
  nodeTypes,
574
1517
  edgeTypes,
575
1518
  onInit: () => {
576
1519
  initialized.current = true;
577
- fit(true);
1520
+ settleUntil.current = Date.now() + require_domains_knowledge_lib_fitViewport.INITIAL_SETTLE_MS;
1521
+ settledOn.current = fitState.current.selectedPageId ?? null;
1522
+ fittedLayout.current = fitState.current.nodes.map((node) => `${node.id}@${node.position.x},${node.position.y}`).join("|");
1523
+ fitInitial();
578
1524
  },
579
1525
  minZoom: .1,
580
1526
  proOptions: { hideAttribution: true },
581
1527
  nodesConnectable: false,
582
1528
  nodesDraggable: false,
583
1529
  onPaneClick,
584
- onNodeClick: (_, node) => {
585
- if (!isPlaceholder(node.data.page)) activate(node.data.page);
586
- },
587
- onEdgeClick: (event, edge) => {
588
- if (edge.data?.kind !== "mention" || !onMentionSelect) return;
589
- const source = pagesById.get(edge.source);
590
- const target = pagesById.get(edge.target);
591
- if (!source || !target) return;
592
- const box = containerRef.current?.getBoundingClientRect();
593
- onMentionSelect({
594
- source,
595
- target,
596
- point: {
597
- x: event.clientX - (box?.left ?? 0),
598
- y: event.clientY - (box?.top ?? 0)
599
- },
600
- pane: {
601
- width: box?.width ?? 0,
602
- height: box?.height ?? 0
603
- }
604
- });
605
- },
1530
+ onNodeMouseEnter,
1531
+ onNodeMouseLeave,
1532
+ onNodeClick,
1533
+ onEdgeClick,
606
1534
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_xyflow_react.Background, {
607
1535
  variant: _xyflow_react.BackgroundVariant.Dots,
608
1536
  gap: 26,
@@ -612,7 +1540,7 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
612
1540
  showInteractive: false,
613
1541
  showFitView: false,
614
1542
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_xyflow_react.ControlButton, {
615
- onClick: () => fit(false, 300),
1543
+ onClick: () => fit(require_domains_knowledge_lib_fitViewport.fitDuration(require_domains_knowledge_lib_useLeavingNodes.prefersMotion())),
616
1544
  title: "Fit view",
617
1545
  "aria-label": "Fit view",
618
1546
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Maximize, { "aria-hidden": true })