dishui 0.0.108 → 0.0.110

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 (384) hide show
  1. package/dist/.release-verified.json +3 -2
  2. package/dist/components/Accordion/index.js.map +1 -1
  3. package/dist/components/Avatar/index.js.map +1 -1
  4. package/dist/components/Badge/index.js.map +1 -1
  5. package/dist/components/Button/index.js.map +1 -1
  6. package/dist/components/ButtonMenu/index.js.map +1 -1
  7. package/dist/components/Card/Metric2.js.map +1 -1
  8. package/dist/components/Card/Ticket2.js.map +1 -1
  9. package/dist/components/Card/index.js.map +1 -1
  10. package/dist/components/Chart/Chart.js.map +1 -1
  11. package/dist/components/Checkbox/index.js.map +1 -1
  12. package/dist/components/ChoicePicker/index.js.map +1 -1
  13. package/dist/components/Column/index.js.map +1 -1
  14. package/dist/components/ConfirmDialog/index.js.map +1 -1
  15. package/dist/components/DateTimeInput/index.js.map +1 -1
  16. package/dist/components/Demo/index.js.map +1 -1
  17. package/dist/components/Demo/source.js.map +1 -1
  18. package/dist/components/Divider/index.js.map +1 -1
  19. package/dist/components/EmptyState/index.js.map +1 -1
  20. package/dist/components/Field/index.js.map +1 -1
  21. package/dist/components/FileUploader/DropZone.js.map +1 -1
  22. package/dist/components/FileUploader/FileItem.js.map +1 -1
  23. package/dist/components/FileUploader/FileUploader.js.map +1 -1
  24. package/dist/components/FileUploader/UploadQueue.js.map +1 -1
  25. package/dist/components/GroupButton/index.js.map +1 -1
  26. package/dist/components/GroupedTable/index.js.map +1 -1
  27. package/dist/components/Icon/index.js.map +1 -1
  28. package/dist/components/Image/index.js.map +1 -1
  29. package/dist/components/Input/index.js.map +1 -1
  30. package/dist/components/Label/index.js.map +1 -1
  31. package/dist/components/Layout/index.js.map +1 -1
  32. package/dist/components/LayoutSuite/DashboardSuite.js.map +1 -1
  33. package/dist/components/LayoutSuite/index.js.map +1 -1
  34. package/dist/components/List/index.js.map +1 -1
  35. package/dist/components/Markdown/Markdown.js.map +1 -1
  36. package/dist/components/Markdown/codeThemes.js.map +1 -1
  37. package/dist/components/Markdown/markdownComponents.js.map +1 -1
  38. package/dist/components/Markdown/parseCodeBlockMeta.js.map +1 -1
  39. package/dist/components/Markdown/useMarkdownSource.js.map +1 -1
  40. package/dist/components/Markdown/useMarkmapRenderer.js.map +1 -1
  41. package/dist/components/Markdown/useMermaidRenderer.js.map +1 -1
  42. package/dist/components/Modal/focusScope.js.map +1 -1
  43. package/dist/components/Modal/index.js.map +1 -1
  44. package/dist/components/MultipleChoice/index.js.map +1 -1
  45. package/dist/components/NavigationList/index.js.map +1 -1
  46. package/dist/components/Page/Float2.js.map +1 -1
  47. package/dist/components/Page/index.js.map +1 -1
  48. package/dist/components/Page/resize2.js.map +1 -1
  49. package/dist/components/PageHeader/index.js.map +1 -1
  50. package/dist/components/PagePanel/index.js.map +1 -1
  51. package/dist/components/ProtectedRoute/index.js.map +1 -1
  52. package/dist/components/Resizable/ResizeGrip.js.map +1 -1
  53. package/dist/components/Resizable/index.js.map +1 -1
  54. package/dist/components/Resizable/useResize.js.map +1 -1
  55. package/dist/components/Row/index.js.map +1 -1
  56. package/dist/components/Section/index.js.map +1 -1
  57. package/dist/components/Select/index.js.map +1 -1
  58. package/dist/components/SidebarToggleButton/index.js.map +1 -1
  59. package/dist/components/Skeleton/index.js.map +1 -1
  60. package/dist/components/Slider/index.js.map +1 -1
  61. package/dist/components/Switch/index.js.map +1 -1
  62. package/dist/components/Tab/index.js.map +1 -1
  63. package/dist/components/Table/index.js.map +1 -1
  64. package/dist/components/Tabs/index.js.map +1 -1
  65. package/dist/components/Tabs/tabNavigation.js.map +1 -1
  66. package/dist/components/Text/index.js.map +1 -1
  67. package/dist/components/Textarea/index.js.map +1 -1
  68. package/dist/components/Tooltip/index.js.map +1 -1
  69. package/dist/components/Tree/Tree.js.map +1 -1
  70. package/dist/components/ai/AgentChat/index.js.map +1 -1
  71. package/dist/components/ai/AgentRunCard/index.js.map +1 -1
  72. package/dist/components/ai/AgentScreen/index.js.map +1 -1
  73. package/dist/components/ai/ApprovalCard/index.js.map +1 -1
  74. package/dist/components/ai/CodeView/index.js.map +1 -1
  75. package/dist/components/ai/CommandSearch/index.js.map +1 -1
  76. package/dist/components/ai/ContextCards/index.js.map +1 -1
  77. package/dist/components/ai/DiffTable/index.js.map +1 -1
  78. package/dist/components/ai/FilterTable/index.js.map +1 -1
  79. package/dist/components/ai/FineTuneCard/index.js.map +1 -1
  80. package/dist/components/ai/InsightCards/index.js.map +1 -1
  81. package/dist/components/ai/IssueCard/index.js.map +1 -1
  82. package/dist/components/ai/LoadingState/index.js.map +1 -1
  83. package/dist/components/ai/PromptBar/index.js.map +1 -1
  84. package/dist/components/ai/RecommendationCard/index.js.map +1 -1
  85. package/dist/components/ai/RecordsTable/index.js.map +1 -1
  86. package/dist/components/ai/SelectionActions/index.js.map +1 -1
  87. package/dist/components/ai/StateFlow/index.js.map +1 -1
  88. package/dist/components/ai/StreamingText/index.js.map +1 -1
  89. package/dist/components/ai/TaskRows/index.js.map +1 -1
  90. package/dist/components/ai/Thinking/index.js.map +1 -1
  91. package/dist/components/ai/ToolChips/index.js.map +1 -1
  92. package/dist/components/ai/shared.js.map +1 -1
  93. package/dist/components/pro/ArticleContextMenu/index.js.map +1 -1
  94. package/dist/components/pro/ArticleControl/ArticleControl2.js.map +1 -1
  95. package/dist/components/pro/ArticleControl/buildHeadingTree.js.map +1 -1
  96. package/dist/components/pro/ArticleControl/useArticleToc.js.map +1 -1
  97. package/dist/components/pro/Calendar/Calendar.js +165 -160
  98. package/dist/components/pro/Calendar/Calendar.js.map +1 -1
  99. package/dist/components/pro/Calendar/hooks/useCalendarDrag.js.map +1 -1
  100. package/dist/components/pro/Calendar/hooks/useCalendarState.js +31 -31
  101. package/dist/components/pro/Calendar/hooks/useCalendarState.js.map +1 -1
  102. package/dist/components/pro/Calendar/utils.js.map +1 -1
  103. package/dist/components/pro/CodeEditor/editors/CodeEditor.js.map +1 -1
  104. package/dist/components/pro/CodeEditor/editors/MarkdownEditor.js.map +1 -1
  105. package/dist/components/pro/CodeEditor/editors/markdownExtensions.js.map +1 -1
  106. package/dist/components/pro/CodeEditor/extensions/contextMenu.js.map +1 -1
  107. package/dist/components/pro/CodeEditor/extensions/index.js.map +1 -1
  108. package/dist/components/pro/CodeEditor/langs/index.js.map +1 -1
  109. package/dist/components/pro/CodeEditor/langs/javascript.js.map +1 -1
  110. package/dist/components/pro/CodeEditor/langs/python.js.map +1 -1
  111. package/dist/components/pro/CodeEditor/langs/snippets.js.map +1 -1
  112. package/dist/components/pro/CodeEditor/panels/FootnotePanel.js.map +1 -1
  113. package/dist/components/pro/CodeEditor/panels/HistoryPanel.js +65 -59
  114. package/dist/components/pro/CodeEditor/panels/HistoryPanel.js.map +1 -1
  115. package/dist/components/pro/CodeEditor/panels/OutlinePanel.js.map +1 -1
  116. package/dist/components/pro/CodeEditor/panels/TableOfContentsPanel.js.map +1 -1
  117. package/dist/components/pro/CodeEditor/panels/VariablePanel.js.map +1 -1
  118. package/dist/components/pro/CodeEditor/themes.js.map +1 -1
  119. package/dist/components/pro/CodeEditor/utils.js.map +1 -1
  120. package/dist/components/pro/DataTable/DataTable.js.map +1 -1
  121. package/dist/components/pro/DataTable/Filters.js.map +1 -1
  122. package/dist/components/pro/DataTable/PivotPanel.js.map +1 -1
  123. package/dist/components/pro/DataTable/PivotView.js.map +1 -1
  124. package/dist/components/pro/DataTable/components/BulkActions.js.map +1 -1
  125. package/dist/components/pro/DataTable/components/ColumnSelector.js.map +1 -1
  126. package/dist/components/pro/DataTable/components/FilterBar.js.map +1 -1
  127. package/dist/components/pro/DataTable/components/TableBody.js.map +1 -1
  128. package/dist/components/pro/DataTable/components/TableHeader.js.map +1 -1
  129. package/dist/components/pro/DataTable/components/TablePagination.js.map +1 -1
  130. package/dist/components/pro/DataTable/components/TableToolbar.js.map +1 -1
  131. package/dist/components/pro/DataTable/extension.js.map +1 -1
  132. package/dist/components/pro/DataTable/pivotEngine.js.map +1 -1
  133. package/dist/components/pro/DataTable/pivotExtension.js.map +1 -1
  134. package/dist/components/pro/DataTable/rowDetailExtension.js.map +1 -1
  135. package/dist/components/pro/DataTable/tanstack-table.js.map +1 -1
  136. package/dist/components/pro/DataTable/treeDataUtils.js.map +1 -1
  137. package/dist/components/pro/DataTable/useColumnDragReorder.js.map +1 -1
  138. package/dist/components/pro/DataTable/useDataTableModel.js +119 -104
  139. package/dist/components/pro/DataTable/useDataTableModel.js.map +1 -1
  140. package/dist/components/pro/DataTable/utils.js.map +1 -1
  141. package/dist/components/pro/FileExplorer/Breadcrumb.js.map +1 -1
  142. package/dist/components/pro/FileExplorer/CreateDialog.js.map +1 -1
  143. package/dist/components/pro/FileExplorer/FileExplorer.js.map +1 -1
  144. package/dist/components/pro/FileExplorer/FileIcon.js.map +1 -1
  145. package/dist/components/pro/FileExplorer/GridView.js.map +1 -1
  146. package/dist/components/pro/FileExplorer/ListView.js.map +1 -1
  147. package/dist/components/pro/FileExplorer/Toolbar.js.map +1 -1
  148. package/dist/components/pro/Flow/Flow.js.map +1 -1
  149. package/dist/components/pro/Flow/FlowCanvas.js.map +1 -1
  150. package/dist/components/pro/Flow/archify/build.js.map +1 -1
  151. package/dist/components/pro/Flow/archify/convert.js.map +1 -1
  152. package/dist/components/pro/Flow/archify/palette.js.map +1 -1
  153. package/dist/components/pro/Flow/archify/presets.js.map +1 -1
  154. package/dist/components/pro/Flow/archify/spec.js.map +1 -1
  155. package/dist/components/pro/Flow/canvas/AlignmentGuides.js.map +1 -1
  156. package/dist/components/pro/Flow/canvas/GridRenderer.js.map +1 -1
  157. package/dist/components/pro/Flow/canvas/MiniMapRenderer.js.map +1 -1
  158. package/dist/components/pro/Flow/canvas/PixiApp.js.map +1 -1
  159. package/dist/components/pro/Flow/canvas/SelectionOverlay.js.map +1 -1
  160. package/dist/components/pro/Flow/canvas/ViewportContainer.js.map +1 -1
  161. package/dist/components/pro/Flow/constants.js.map +1 -1
  162. package/dist/components/pro/Flow/context/FlowAIContext.js.map +1 -1
  163. package/dist/components/pro/Flow/context/FlowContext.js.map +1 -1
  164. package/dist/components/pro/Flow/context/FlowUIContext.js.map +1 -1
  165. package/dist/components/pro/Flow/edges/EdgeRenderer.js.map +1 -1
  166. package/dist/components/pro/Flow/edges/edgeMarkers.js.map +1 -1
  167. package/dist/components/pro/Flow/edges/edgePaths.js.map +1 -1
  168. package/dist/components/pro/Flow/hooks/useAlignmentGuides.js.map +1 -1
  169. package/dist/components/pro/Flow/hooks/useClipboard.js.map +1 -1
  170. package/dist/components/pro/Flow/hooks/useCompactMode.js.map +1 -1
  171. package/dist/components/pro/Flow/hooks/useDeleteSelection.js.map +1 -1
  172. package/dist/components/pro/Flow/hooks/useDraggablePanel.js.map +1 -1
  173. package/dist/components/pro/Flow/hooks/useEdgeMutations.js.map +1 -1
  174. package/dist/components/pro/Flow/hooks/useFlowImportExport.js.map +1 -1
  175. package/dist/components/pro/Flow/hooks/useKeyboardShortcuts.js.map +1 -1
  176. package/dist/components/pro/Flow/hooks/useLayoutActions.js.map +1 -1
  177. package/dist/components/pro/Flow/hooks/useLineMutations.js.map +1 -1
  178. package/dist/components/pro/Flow/hooks/useMindMap.js.map +1 -1
  179. package/dist/components/pro/Flow/hooks/useNodeMutations.js.map +1 -1
  180. package/dist/components/pro/Flow/hooks/usePdfExport.js.map +1 -1
  181. package/dist/components/pro/Flow/hooks/usePixiApp.js.map +1 -1
  182. package/dist/components/pro/Flow/hooks/useResizablePanel.js.map +1 -1
  183. package/dist/components/pro/Flow/hooks/useSelection.js.map +1 -1
  184. package/dist/components/pro/Flow/hooks/useUndoRedo.js.map +1 -1
  185. package/dist/components/pro/Flow/hooks/useViewport.js.map +1 -1
  186. package/dist/components/pro/Flow/lines/FreehandTool.js.map +1 -1
  187. package/dist/components/pro/Flow/lines/GeometricLineTool.js.map +1 -1
  188. package/dist/components/pro/Flow/lines/LineRenderer.js.map +1 -1
  189. package/dist/components/pro/Flow/lines/lineSmoothing.js.map +1 -1
  190. package/dist/components/pro/Flow/nodes/DataNodeView.js.map +1 -1
  191. package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
  192. package/dist/components/pro/Flow/nodes/MediaOverlay.js.map +1 -1
  193. package/dist/components/pro/Flow/nodes/Model3DView.js.map +1 -1
  194. package/dist/components/pro/Flow/nodes/NodeHandles.js.map +1 -1
  195. package/dist/components/pro/Flow/nodes/NodeRenderer.js.map +1 -1
  196. package/dist/components/pro/Flow/nodes/NodeText.js.map +1 -1
  197. package/dist/components/pro/Flow/nodes/aiClient.js.map +1 -1
  198. package/dist/components/pro/Flow/nodes/animAnchors.js.map +1 -1
  199. package/dist/components/pro/Flow/nodes/chartGeometryBudget.js.map +1 -1
  200. package/dist/components/pro/Flow/nodes/dataUtils.js.map +1 -1
  201. package/dist/components/pro/Flow/nodes/demandRender.js.map +1 -1
  202. package/dist/components/pro/Flow/nodes/nodeUtils.js.map +1 -1
  203. package/dist/components/pro/Flow/nodes/shapes.js.map +1 -1
  204. package/dist/components/pro/Flow/nodes/svgIconTexture.js.map +1 -1
  205. package/dist/components/pro/Flow/nodes/svgIcons.js.map +1 -1
  206. package/dist/components/pro/Flow/panels/AIPanel.js.map +1 -1
  207. package/dist/components/pro/Flow/panels/Breadcrumb.js.map +1 -1
  208. package/dist/components/pro/Flow/panels/ContextMenu.js.map +1 -1
  209. package/dist/components/pro/Flow/panels/DataInspectorSection.js.map +1 -1
  210. package/dist/components/pro/Flow/panels/ExpandableTextarea.js.map +1 -1
  211. package/dist/components/pro/Flow/panels/FlowPanelGroup.js.map +1 -1
  212. package/dist/components/pro/Flow/panels/FlowToolbar.js.map +1 -1
  213. package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
  214. package/dist/components/pro/Flow/panels/OutlinePanel.js.map +1 -1
  215. package/dist/components/pro/Flow/panels/PresentationMode.js.map +1 -1
  216. package/dist/components/pro/Flow/panels/ProjectTitle.js.map +1 -1
  217. package/dist/components/pro/Flow/panels/ShapePalette.js.map +1 -1
  218. package/dist/components/pro/Flow/panels/toolbarIcons.js.map +1 -1
  219. package/dist/components/pro/Flow/types.js.map +1 -1
  220. package/dist/components/pro/Flow/utils/dashedLine.js.map +1 -1
  221. package/dist/components/pro/Flow/utils/gradient.js.map +1 -1
  222. package/dist/components/pro/Flow/utils/pdfExport.js.map +1 -1
  223. package/dist/components/pro/Flow/utils/themeColor.js.map +1 -1
  224. package/dist/components/pro/Gantt/Gantt.js.map +1 -1
  225. package/dist/components/pro/Gantt/hooks/useGanttDrag.js.map +1 -1
  226. package/dist/components/pro/Gantt/hooks/useGanttState.js +79 -71
  227. package/dist/components/pro/Gantt/hooks/useGanttState.js.map +1 -1
  228. package/dist/components/pro/Gantt/utils.js.map +1 -1
  229. package/dist/components/pro/Kanban/Kanban.js.map +1 -1
  230. package/dist/components/pro/Kanban/Swimlanes.js.map +1 -1
  231. package/dist/components/pro/Kanban/useKanbanDrag.js.map +1 -1
  232. package/dist/components/pro/Kanban/utils.js.map +1 -1
  233. package/dist/components/pro/RichTextEditor/AIRewrite.js.map +1 -1
  234. package/dist/components/pro/RichTextEditor/BlockHandle.js.map +1 -1
  235. package/dist/components/pro/RichTextEditor/BubbleToolbar.js.map +1 -1
  236. package/dist/components/pro/RichTextEditor/CommentDialog.js.map +1 -1
  237. package/dist/components/pro/RichTextEditor/CommentPanel.js.map +1 -1
  238. package/dist/components/pro/RichTextEditor/CommentPopover.js.map +1 -1
  239. package/dist/components/pro/RichTextEditor/ContextMenu.js.map +1 -1
  240. package/dist/components/pro/RichTextEditor/RichTextEditor.js.map +1 -1
  241. package/dist/components/pro/RichTextEditor/SlashMenu.js.map +1 -1
  242. package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js.map +1 -1
  243. package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js.map +1 -1
  244. package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js.map +1 -1
  245. package/dist/components/pro/RichTextEditor/Toolbar/SelectDropdown.js.map +1 -1
  246. package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js.map +1 -1
  247. package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js.map +1 -1
  248. package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.js.map +1 -1
  249. package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.js.map +1 -1
  250. package/dist/components/pro/RichTextEditor/extensions/CodeBlockView.js.map +1 -1
  251. package/dist/components/pro/RichTextEditor/extensions/CommentMark.js.map +1 -1
  252. package/dist/components/pro/RichTextEditor/extensions/FloatingDialog.js.map +1 -1
  253. package/dist/components/pro/RichTextEditor/extensions/FontSize.js.map +1 -1
  254. package/dist/components/pro/RichTextEditor/extensions/MarkdownBlock.js.map +1 -1
  255. package/dist/components/pro/RichTextEditor/extensions/ResizableImage.js.map +1 -1
  256. package/dist/components/pro/RichTextEditor/extensions/legacyMermaid.js.map +1 -1
  257. package/dist/components/pro/RichTextEditor/types.js.map +1 -1
  258. package/dist/components/pro/Sprite/Molly/animations.d.ts +6 -0
  259. package/dist/components/pro/Sprite/Molly/animations.js +52 -0
  260. package/dist/components/pro/Sprite/Molly/animations.js.map +1 -0
  261. package/dist/components/pro/Sprite/Molly/events.d.ts +2 -0
  262. package/dist/components/pro/Sprite/Molly/events.js +46 -0
  263. package/dist/components/pro/Sprite/Molly/events.js.map +1 -0
  264. package/dist/components/pro/Sprite/Molly/index.d.ts +1 -0
  265. package/dist/components/pro/Sprite/Molly/index.js +12 -0
  266. package/dist/components/pro/Sprite/Molly/index.js.map +1 -0
  267. package/dist/components/pro/Sprite/Molly/legFlexion.d.ts +3 -0
  268. package/dist/components/pro/Sprite/Molly/legFlexion.js +48 -0
  269. package/dist/components/pro/Sprite/Molly/legFlexion.js.map +1 -0
  270. package/dist/components/pro/Sprite/Molly/locomotion.d.ts +4 -0
  271. package/dist/components/pro/Sprite/Molly/locomotion.js +51 -0
  272. package/dist/components/pro/Sprite/Molly/locomotion.js.map +1 -0
  273. package/dist/components/pro/Sprite/Molly/model.d.ts +23 -0
  274. package/dist/components/pro/Sprite/Molly/model.js +614 -0
  275. package/dist/components/pro/Sprite/Molly/model.js.map +1 -0
  276. package/dist/components/pro/Sprite/Molly/rig.d.ts +25 -0
  277. package/dist/components/pro/Sprite/Molly/rig.js +102 -0
  278. package/dist/components/pro/Sprite/Molly/rig.js.map +1 -0
  279. package/dist/components/pro/Sprite/Ruby/animations.d.ts +6 -0
  280. package/dist/components/pro/Sprite/Ruby/animations.js +58 -0
  281. package/dist/components/pro/Sprite/Ruby/animations.js.map +1 -0
  282. package/dist/components/pro/Sprite/Ruby/events.d.ts +2 -0
  283. package/dist/components/pro/Sprite/Ruby/events.js +46 -0
  284. package/dist/components/pro/Sprite/Ruby/events.js.map +1 -0
  285. package/dist/components/pro/Sprite/Ruby/index.d.ts +1 -0
  286. package/dist/components/pro/Sprite/Ruby/index.js +12 -0
  287. package/dist/components/pro/Sprite/Ruby/index.js.map +1 -0
  288. package/dist/components/pro/Sprite/Ruby/locomotion.d.ts +4 -0
  289. package/dist/components/pro/Sprite/Ruby/locomotion.js +41 -0
  290. package/dist/components/pro/Sprite/Ruby/locomotion.js.map +1 -0
  291. package/dist/components/pro/Sprite/Ruby/model.d.ts +23 -0
  292. package/dist/components/pro/Sprite/Ruby/model.js +605 -0
  293. package/dist/components/pro/Sprite/Ruby/model.js.map +1 -0
  294. package/dist/components/pro/Sprite/Ruby/rig.d.ts +26 -0
  295. package/dist/components/pro/Sprite/Ruby/rig.js +112 -0
  296. package/dist/components/pro/Sprite/Ruby/rig.js.map +1 -0
  297. package/dist/components/pro/Sprite/Sprite.d.ts +23 -0
  298. package/dist/components/pro/Sprite/Sprite2.js +224 -0
  299. package/dist/components/pro/Sprite/Sprite2.js.map +1 -0
  300. package/dist/components/pro/Sprite/actions.d.ts +3 -0
  301. package/dist/components/pro/Sprite/actions.js +16 -0
  302. package/dist/components/pro/Sprite/actions.js.map +1 -0
  303. package/dist/components/pro/Sprite/createSpriteScene.d.ts +4 -0
  304. package/dist/components/pro/Sprite/createSpriteScene.js +14 -0
  305. package/dist/components/pro/Sprite/createSpriteScene.js.map +1 -0
  306. package/dist/components/pro/Sprite/index.d.ts +4 -0
  307. package/dist/components/pro/Sprite/shared/animation.d.ts +33 -0
  308. package/dist/components/pro/Sprite/shared/animation.js +39 -0
  309. package/dist/components/pro/Sprite/shared/animation.js.map +1 -0
  310. package/dist/components/pro/Sprite/shared/createSpriteStage.d.ts +14 -0
  311. package/dist/components/pro/Sprite/shared/createSpriteStage.js +127 -0
  312. package/dist/components/pro/Sprite/shared/createSpriteStage.js.map +1 -0
  313. package/dist/components/pro/Sprite/shared/events.d.ts +5 -0
  314. package/dist/components/pro/Sprite/shared/events.js +21 -0
  315. package/dist/components/pro/Sprite/shared/events.js.map +1 -0
  316. package/dist/components/pro/Sprite/shared/face.d.ts +15 -0
  317. package/dist/components/pro/Sprite/shared/face.js +33 -0
  318. package/dist/components/pro/Sprite/shared/face.js.map +1 -0
  319. package/dist/components/pro/Sprite/shared/faceSurface.d.ts +6 -0
  320. package/dist/components/pro/Sprite/shared/faceSurface.js +66 -0
  321. package/dist/components/pro/Sprite/shared/faceSurface.js.map +1 -0
  322. package/dist/components/pro/Sprite/shared/gait.d.ts +5 -0
  323. package/dist/components/pro/Sprite/shared/gait.js +19 -0
  324. package/dist/components/pro/Sprite/shared/gait.js.map +1 -0
  325. package/dist/components/pro/Sprite/shared/geometry.d.ts +8 -0
  326. package/dist/components/pro/Sprite/shared/geometry.js +59 -0
  327. package/dist/components/pro/Sprite/shared/geometry.js.map +1 -0
  328. package/dist/components/pro/Sprite/shared/magicEffect.d.ts +27 -0
  329. package/dist/components/pro/Sprite/shared/magicEffect.js +61 -0
  330. package/dist/components/pro/Sprite/shared/magicEffect.js.map +1 -0
  331. package/dist/components/pro/Sprite/shared/playback.d.ts +8 -0
  332. package/dist/components/pro/Sprite/shared/playback.js +74 -0
  333. package/dist/components/pro/Sprite/shared/playback.js.map +1 -0
  334. package/dist/components/pro/Sprite/shared/rig.d.ts +6 -0
  335. package/dist/components/pro/Sprite/shared/rig.js +48 -0
  336. package/dist/components/pro/Sprite/shared/rig.js.map +1 -0
  337. package/dist/components/pro/Sprite/shared/scene.d.ts +9 -0
  338. package/dist/components/pro/Sprite/shared/scene.js +21 -0
  339. package/dist/components/pro/Sprite/shared/scene.js.map +1 -0
  340. package/dist/components/pro/Sprite/shared/sculptor.d.ts +14 -0
  341. package/dist/components/pro/Sprite/shared/sculptor.js +78 -0
  342. package/dist/components/pro/Sprite/shared/sculptor.js.map +1 -0
  343. package/dist/components/pro/Sprite/shared/speechBubble.d.ts +15 -0
  344. package/dist/components/pro/Sprite/shared/speechBubble.js +129 -0
  345. package/dist/components/pro/Sprite/shared/speechBubble.js.map +1 -0
  346. package/dist/components/pro/Sprite/types.d.ts +40 -0
  347. package/dist/contexts/AppContext.js.map +1 -1
  348. package/dist/contexts/authentication.js.map +1 -1
  349. package/dist/data-table.js +3 -3
  350. package/dist/data-table.js.map +1 -1
  351. package/dist/dishui.css +1 -1
  352. package/dist/hooks/useClickOutside.js.map +1 -1
  353. package/dist/hooks/useContainerElement.js.map +1 -1
  354. package/dist/hooks/useControllableState.js.map +1 -1
  355. package/dist/hooks/useCopyToClipboard.js.map +1 -1
  356. package/dist/hooks/useDebounce.js.map +1 -1
  357. package/dist/hooks/useDraggable.js.map +1 -1
  358. package/dist/hooks/useTableColumns.js.map +1 -1
  359. package/dist/hooks/useTableData.js.map +1 -1
  360. package/dist/index-nostyled.d.ts +2 -0
  361. package/dist/index.d.ts +2 -0
  362. package/dist/index.js +116 -115
  363. package/dist/layouts/MainLayout.js.map +1 -1
  364. package/dist/layouts/Navbar.js.map +1 -1
  365. package/dist/layouts/Sidebar.js.map +1 -1
  366. package/dist/layouts/headbar/Headbar.js.map +1 -1
  367. package/dist/layouts/headbar/HeadbarLangSwitcher.js.map +1 -1
  368. package/dist/layouts/headbar/HeadbarSearch.js.map +1 -1
  369. package/dist/layouts/headbar/HeadbarThemeSwitcher.js.map +1 -1
  370. package/dist/layouts/headbar/HeadbarTitle.js.map +1 -1
  371. package/dist/sprite.js +2 -0
  372. package/dist/styles/themeStyles.js.map +1 -1
  373. package/dist/utils/cn.js.map +1 -1
  374. package/dist/utils/flexLayout.js.map +1 -1
  375. package/dist/utils/i18n.js.map +1 -1
  376. package/dist/utils/menu.js.map +1 -1
  377. package/dist/utils/rehype-code-meta.js.map +1 -1
  378. package/dist/utils/remark-code-meta.js.map +1 -1
  379. package/dist/utils/routerBuilder.js.map +1 -1
  380. package/dist/utils/safeStorage.js.map +1 -1
  381. package/dist/utils/selection.js +29 -20
  382. package/dist/utils/selection.js.map +1 -1
  383. package/dist/utils/themes.js.map +1 -1
  384. package/package.json +15 -11
@@ -1 +1 @@
1
- {"version":3,"file":"FlowAIContext.js","names":[],"sources":["../../../../../src/components/pro/Flow/context/FlowAIContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo, useState } from 'react';\nimport type { FlowAIConfig } from '../types';\n\nexport interface FlowAIContextValue {\n aiConfig: FlowAIConfig;\n setAIConfig: (config: FlowAIConfig) => void;\n /** Whether the model-config form is shown inside the AI panel. */\n showAIConfig: boolean;\n /** Whether the consuming application supplied one shared runtime config. */\n hasSharedConfig: boolean;\n}\n\nconst DEFAULT_AI_CONFIG: FlowAIConfig = {\n gateway: '',\n protocol: 'openai',\n model: '',\n};\n\nconst FlowAIContext = createContext<FlowAIContextValue | null>(null);\n\nexport function useFlowAI(): FlowAIContextValue {\n const ctx = useContext(FlowAIContext);\n if (!ctx) throw new Error('useFlowAI must be used within FlowAIProvider');\n return ctx;\n}\n\nexport interface FlowAIProviderProps {\n initialConfig?: FlowAIConfig;\n showAIConfig?: boolean;\n children: React.ReactNode;\n}\n\nexport function FlowAIProvider({ initialConfig, showAIConfig = true, children }: FlowAIProviderProps) {\n const [aiConfig, setAIConfig] = useState<FlowAIConfig>({ ...DEFAULT_AI_CONFIG, ...initialConfig });\n const hasSharedConfig = initialConfig !== undefined;\n const value = useMemo<FlowAIContextValue>(\n () => ({ aiConfig, setAIConfig, showAIConfig, hasSharedConfig }),\n [aiConfig, showAIConfig, hasSharedConfig],\n );\n return <FlowAIContext.Provider value={value}>{children}</FlowAIContext.Provider>;\n}\n"],"mappings":";;;AAYA,IAAM,IAAkC;CACtC,SAAS;CACT,UAAU;CACV,OAAO;AACT,GAEM,IAAgB,EAAyC,IAAI;AAEnE,SAAgB,IAAgC;CAC9C,IAAM,IAAM,EAAW,CAAa;CACpC,IAAI,CAAC,GAAK,MAAU,MAAM,8CAA8C;CACxE,OAAO;AACT;AAQA,SAAgB,EAAe,EAAE,kBAAe,kBAAe,IAAM,eAAiC;CACpG,IAAM,CAAC,GAAU,KAAe,EAAuB;EAAE,GAAG;EAAmB,GAAG;CAAc,CAAC,GAC3F,IAAkB,MAAkB,KAAA,GACpC,IAAQ,SACL;EAAE;EAAU;EAAa;EAAc;CAAgB,IAC9D;EAAC;EAAU;EAAc;CAAe,CAC1C;CACA,OAAO,kBAAC,EAAc,UAAf;EAA+B;EAAQ;CAAiC,CAAA;AACjF"}
1
+ {"version":3,"file":"FlowAIContext.js","names":["DEFAULT_AI_CONFIG","FlowAIContext","createContext","useFlowAI","ctx","useContext","FlowAIProvider","aiConfig","setAIConfig","useState","initialConfig","hasSharedConfig","value","useMemo","showAIConfig"],"sources":["../../../../../src/components/pro/Flow/context/FlowAIContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo, useState } from 'react';\nimport type { FlowAIConfig } from '../types';\n\nexport interface FlowAIContextValue {\n aiConfig: FlowAIConfig;\n setAIConfig: (config: FlowAIConfig) => void;\n /** Whether the model-config form is shown inside the AI panel. */\n showAIConfig: boolean;\n /** Whether the consuming application supplied one shared runtime config. */\n hasSharedConfig: boolean;\n}\n\nconst DEFAULT_AI_CONFIG: FlowAIConfig = {\n gateway: '',\n protocol: 'openai',\n model: '',\n};\n\nconst FlowAIContext = createContext<FlowAIContextValue | null>(null);\n\nexport function useFlowAI(): FlowAIContextValue {\n const ctx = useContext(FlowAIContext);\n if (!ctx) throw new Error('useFlowAI must be used within FlowAIProvider');\n return ctx;\n}\n\nexport interface FlowAIProviderProps {\n initialConfig?: FlowAIConfig;\n showAIConfig?: boolean;\n children: React.ReactNode;\n}\n\nexport function FlowAIProvider({ initialConfig, showAIConfig = true, children }: FlowAIProviderProps) {\n const [aiConfig, setAIConfig] = useState<FlowAIConfig>({ ...DEFAULT_AI_CONFIG, ...initialConfig });\n const hasSharedConfig = initialConfig !== undefined;\n const value = useMemo<FlowAIContextValue>(\n () => ({ aiConfig, setAIConfig, showAIConfig, hasSharedConfig }),\n [aiConfig, showAIConfig, hasSharedConfig],\n );\n return <FlowAIContext.Provider value={value}>{children}</FlowAIContext.Provider>;\n}\n"],"mappings":";;;AAYA,IAAMA,IAAkC;CACtC,SAAS;CACT,UAAU;CACV,OAAO;AACT,GAEMC,IAAgBC,EAAyC,IAAI;AAEnE,SAAgBC,IAAgC;CAC9C,IAAMC,IAAMC,EAAWJ,CAAa;CACpC,IAAI,CAACG,GAAK,MAAU,MAAM,8CAA8C;CACxE,OAAOA;AACT;AAQA,SAAgBE,EAAe,EAAE,kBAAe,kBAAe,IAAM,eAAiC;CACpG,IAAM,CAACC,GAAUC,KAAeC,EAAuB;EAAE,GAAGT;EAAmB,GAAGU;CAAc,CAAC,GAC3FC,IAAkBD,MAAkB,KAAA,GACpCE,IAAQC,SACL;EAAE;EAAU;EAAa;EAAc;CAAgB,IAC9D;EAACN;EAAUO;EAAcH;CAAe,CAC1C;CACA,OAAO,kBAACV,EAAc,UAAf;EAA+B;EAAQ;CAAiC,CAAA;AACjF"}
@@ -1 +1 @@
1
- {"version":3,"file":"FlowContext.js","names":[],"sources":["../../../../../src/components/pro/Flow/context/FlowContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo } from 'react';\nimport type {\n FlowDocument,\n FlowLine,\n SelectionState,\n FlowCanvasData,\n} from '../types';\nimport { ROOT_CANVAS_ID } from '../constants';\n\nexport interface FlowContextValue {\n doc: FlowDocument;\n setDoc: React.Dispatch<React.SetStateAction<FlowDocument>>;\n /** Commit without recording undo history (transient canvas navigation, e.g. PDF export). */\n setDocTransient: React.Dispatch<React.SetStateAction<FlowDocument>>;\n currentCanvasId: string;\n currentCanvas: FlowCanvasData;\n selection: SelectionState;\n setSelection: React.Dispatch<React.SetStateAction<SelectionState>>;\n /** Push into child canvas */\n pushCanvas: (canvasId: string) => void;\n /** Pop back to parent canvas */\n popCanvas: () => void;\n}\n\nconst FlowContext = createContext<FlowContextValue | null>(null);\n\nexport function useFlowContext(): FlowContextValue {\n const ctx = useContext(FlowContext);\n if (!ctx) throw new Error('useFlowContext must be used within FlowProvider');\n return ctx;\n}\n\nexport interface FlowProviderProps {\n doc: FlowDocument;\n setDoc: React.Dispatch<React.SetStateAction<FlowDocument>>;\n /** History-free update channel; falls back to `setDoc` when not provided. */\n setDocTransient?: React.Dispatch<React.SetStateAction<FlowDocument>>;\n selection: SelectionState;\n setSelection: React.Dispatch<React.SetStateAction<SelectionState>>;\n children: React.ReactNode;\n}\n\nconst EMPTY_CANVAS: FlowCanvasData = { nodes: [], edges: [], lines: [] };\n\nexport function FlowProvider({ doc, setDoc, setDocTransient, selection, setSelection, children }: FlowProviderProps) {\n const currentCanvasId = doc.stack[doc.stack.length - 1] ?? ROOT_CANVAS_ID;\n const currentCanvas = doc.canvases[currentCanvasId] ?? EMPTY_CANVAS;\n const transient = setDocTransient ?? setDoc;\n\n const emptySelection: SelectionState = useMemo(() => ({\n nodeIds: new Set(), edgeIds: new Set(), lineIds: new Set(),\n }), []);\n\n const pushCanvas = useMemo(() => (canvasId: string) => {\n setDoc(prev => ({ ...prev, stack: [...prev.stack, canvasId] }));\n setSelection(emptySelection);\n }, [setDoc, setSelection, emptySelection]);\n\n const popCanvas = useMemo(() => () => {\n setDoc(prev => ({\n ...prev,\n stack: prev.stack.length > 1 ? prev.stack.slice(0, -1) : prev.stack,\n }));\n setSelection(emptySelection);\n }, [setDoc, setSelection, emptySelection]);\n\n const value = useMemo<FlowContextValue>(() => ({\n doc,\n setDoc,\n setDocTransient: transient,\n currentCanvasId,\n currentCanvas,\n selection,\n setSelection,\n pushCanvas,\n popCanvas,\n }), [doc, setDoc, transient, currentCanvasId, currentCanvas, selection, setSelection, pushCanvas, popCanvas]);\n\n return <FlowContext.Provider value={value}>{children}</FlowContext.Provider>;\n}\n"],"mappings":";;;;AAwBA,IAAM,IAAc,EAAuC,IAAI;AAE/D,SAAgB,IAAmC;CACjD,IAAM,IAAM,EAAW,CAAW;CAClC,IAAI,CAAC,GAAK,MAAU,MAAM,iDAAiD;CAC3E,OAAO;AACT;AAYA,IAAM,IAA+B;CAAE,OAAO,CAAC;CAAG,OAAO,CAAC;CAAG,OAAO,CAAC;AAAE;AAEvE,SAAgB,EAAa,EAAE,QAAK,WAAQ,oBAAiB,cAAW,iBAAc,eAA+B;CACnH,IAAM,IAAkB,EAAI,MAAM,EAAI,MAAM,SAAS,MAAA,QAC/C,IAAgB,EAAI,SAAS,MAAoB,GACjD,IAAY,KAAmB,GAE/B,IAAiC,SAAe;EACpD,yBAAS,IAAI,IAAI;EAAG,yBAAS,IAAI,IAAI;EAAG,yBAAS,IAAI,IAAI;CAC3D,IAAI,CAAC,CAAC,GAEA,IAAa,SAAe,MAAqB;EAErD,AADA,GAAO,OAAS;GAAE,GAAG;GAAM,OAAO,CAAC,GAAG,EAAK,OAAO,CAAQ;EAAE,EAAE,GAC9D,EAAa,CAAc;CAC7B,GAAG;EAAC;EAAQ;EAAc;CAAc,CAAC,GAEnC,IAAY,cAAoB;EAKpC,AAJA,GAAO,OAAS;GACd,GAAG;GACH,OAAO,EAAK,MAAM,SAAS,IAAI,EAAK,MAAM,MAAM,GAAG,EAAE,IAAI,EAAK;EAChE,EAAE,GACF,EAAa,CAAc;CAC7B,GAAG;EAAC;EAAQ;EAAc;CAAc,CAAC,GAEnC,IAAQ,SAAiC;EAC7C;EACA;EACA,iBAAiB;EACjB;EACA;EACA;EACA;EACA;EACA;CACF,IAAI;EAAC;EAAK;EAAQ;EAAW;EAAiB;EAAe;EAAW;EAAc;EAAY;CAAS,CAAC;CAE5G,OAAO,kBAAC,EAAY,UAAb;EAA6B;EAAQ;CAA+B,CAAA;AAC7E"}
1
+ {"version":3,"file":"FlowContext.js","names":["FlowContext","createContext","useFlowContext","ctx","useContext","EMPTY_CANVAS","FlowProvider","currentCanvasId","doc","currentCanvas","transient","setDocTransient","setDoc","emptySelection","useMemo","pushCanvas","prev","canvasId","setSelection","popCanvas","value","selection"],"sources":["../../../../../src/components/pro/Flow/context/FlowContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo } from 'react';\nimport type {\n FlowDocument,\n FlowLine,\n SelectionState,\n FlowCanvasData,\n} from '../types';\nimport { ROOT_CANVAS_ID } from '../constants';\n\nexport interface FlowContextValue {\n doc: FlowDocument;\n setDoc: React.Dispatch<React.SetStateAction<FlowDocument>>;\n /** Commit without recording undo history (transient canvas navigation, e.g. PDF export). */\n setDocTransient: React.Dispatch<React.SetStateAction<FlowDocument>>;\n currentCanvasId: string;\n currentCanvas: FlowCanvasData;\n selection: SelectionState;\n setSelection: React.Dispatch<React.SetStateAction<SelectionState>>;\n /** Push into child canvas */\n pushCanvas: (canvasId: string) => void;\n /** Pop back to parent canvas */\n popCanvas: () => void;\n}\n\nconst FlowContext = createContext<FlowContextValue | null>(null);\n\nexport function useFlowContext(): FlowContextValue {\n const ctx = useContext(FlowContext);\n if (!ctx) throw new Error('useFlowContext must be used within FlowProvider');\n return ctx;\n}\n\nexport interface FlowProviderProps {\n doc: FlowDocument;\n setDoc: React.Dispatch<React.SetStateAction<FlowDocument>>;\n /** History-free update channel; falls back to `setDoc` when not provided. */\n setDocTransient?: React.Dispatch<React.SetStateAction<FlowDocument>>;\n selection: SelectionState;\n setSelection: React.Dispatch<React.SetStateAction<SelectionState>>;\n children: React.ReactNode;\n}\n\nconst EMPTY_CANVAS: FlowCanvasData = { nodes: [], edges: [], lines: [] };\n\nexport function FlowProvider({ doc, setDoc, setDocTransient, selection, setSelection, children }: FlowProviderProps) {\n const currentCanvasId = doc.stack[doc.stack.length - 1] ?? ROOT_CANVAS_ID;\n const currentCanvas = doc.canvases[currentCanvasId] ?? EMPTY_CANVAS;\n const transient = setDocTransient ?? setDoc;\n\n const emptySelection: SelectionState = useMemo(() => ({\n nodeIds: new Set(), edgeIds: new Set(), lineIds: new Set(),\n }), []);\n\n const pushCanvas = useMemo(() => (canvasId: string) => {\n setDoc(prev => ({ ...prev, stack: [...prev.stack, canvasId] }));\n setSelection(emptySelection);\n }, [setDoc, setSelection, emptySelection]);\n\n const popCanvas = useMemo(() => () => {\n setDoc(prev => ({\n ...prev,\n stack: prev.stack.length > 1 ? prev.stack.slice(0, -1) : prev.stack,\n }));\n setSelection(emptySelection);\n }, [setDoc, setSelection, emptySelection]);\n\n const value = useMemo<FlowContextValue>(() => ({\n doc,\n setDoc,\n setDocTransient: transient,\n currentCanvasId,\n currentCanvas,\n selection,\n setSelection,\n pushCanvas,\n popCanvas,\n }), [doc, setDoc, transient, currentCanvasId, currentCanvas, selection, setSelection, pushCanvas, popCanvas]);\n\n return <FlowContext.Provider value={value}>{children}</FlowContext.Provider>;\n}\n"],"mappings":";;;;AAwBA,IAAMA,IAAcC,EAAuC,IAAI;AAE/D,SAAgBC,IAAmC;CACjD,IAAMC,IAAMC,EAAWJ,CAAW;CAClC,IAAI,CAACG,GAAK,MAAU,MAAM,iDAAiD;CAC3E,OAAOA;AACT;AAYA,IAAME,IAA+B;CAAE,OAAO,CAAC;CAAG,OAAO,CAAC;CAAG,OAAO,CAAC;AAAE;AAEvE,SAAgBC,EAAa,EAAE,QAAK,WAAQ,oBAAiB,cAAW,iBAAc,eAA+B;CACnH,IAAMC,IAAkBC,EAAI,MAAMA,EAAI,MAAM,SAAS,MAAA,QAC/CC,IAAgBD,EAAI,SAASD,MAAoBF,GACjDK,IAAYC,KAAmBC,GAE/BC,IAAiCC,SAAe;EACpD,yBAAS,IAAI,IAAI;EAAG,yBAAS,IAAI,IAAI;EAAG,yBAAS,IAAI,IAAI;CAC3D,IAAI,CAAC,CAAC,GAEAC,IAAaD,SAAe,MAAqB;EAErD,AADAF,GAAO,OAAS;GAAE,GAAGI;GAAM,OAAO,CAAC,GAAGA,EAAK,OAAOC,CAAQ;EAAE,EAAE,GAC9DC,EAAaL,CAAc;CAC7B,GAAG;EAACD;EAAQM;EAAcL;CAAc,CAAC,GAEnCM,IAAYL,cAAoB;EAKpC,AAJAF,GAAO,OAAS;GACd,GAAGI;GACH,OAAOA,EAAK,MAAM,SAAS,IAAIA,EAAK,MAAM,MAAM,GAAG,EAAE,IAAIA,EAAK;EAChE,EAAE,GACFE,EAAaL,CAAc;CAC7B,GAAG;EAACD;EAAQM;EAAcL;CAAc,CAAC,GAEnCO,IAAQN,SAAiC;EAC7C;EACA;EACA,iBAAiBJ;EACjB;EACA;EACA;EACA;EACA;EACA;CACF,IAAI;EAACF;EAAKI;EAAQF;EAAWH;EAAiBE;EAAeY;EAAWH;EAAcH;EAAYI;CAAS,CAAC;CAE5G,OAAO,kBAACnB,EAAY,UAAb;EAA6B;EAAQ;CAA+B,CAAA;AAC7E"}
@@ -1 +1 @@
1
- {"version":3,"file":"FlowUIContext.js","names":[],"sources":["../../../../../src/components/pro/Flow/context/FlowUIContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo, useState, useRef, useCallback } from 'react';\nimport type { FlowToolMode, FlowEdgeTypeName, FlowShapeType, FlowNodeData, ViewportState } from '../types';\n\nexport interface ContextMenuState {\n x: number;\n y: number;\n nodeId: string | null;\n}\n\n/** Where an editing panel lives: left dock, right dock or a floating overlay. */\nexport type FlowPanelDock = 'left' | 'right' | 'float';\n\nexport interface FocusOnRectOptions {\n /** Screen-space padding around the focused rectangle, in pixels. */\n padding?: number;\n /** Maximum zoom allowed for this focus operation. */\n maxZoom?: number;\n /** Viewport transition duration in milliseconds. */\n duration?: number;\n /** Keep the current zoom and only animate the focused rectangle to center. */\n preserveZoom?: boolean;\n}\n\nexport interface FlowUIContextValue {\n toolMode: FlowToolMode;\n setToolMode: (mode: FlowToolMode) => void;\n edgeType: FlowEdgeTypeName;\n setEdgeType: (type: FlowEdgeTypeName) => void;\n viewport: ViewportState;\n setViewport: (v: ViewportState) => void;\n /** Internal VM→React bridge setter (does not request a VM apply). */\n setViewportInternal: (v: ViewportState) => void;\n /** Monotonic counter of external viewport commands. */\n viewportReqRef: React.MutableRefObject<number>;\n focusOnRect: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void;\n setFocusOnRect: (fn: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void) => void;\n autoFocus: boolean;\n setAutoFocus: (v: boolean) => void;\n editingNodeId: string | null;\n setEditingNodeId: (id: string | null) => void;\n /** True while any node/line is being dragged. Used to suppress interactive\n * DOM overlays (e.g. HTML iframes) that would otherwise swallow pointerup. */\n isNodeDragging: boolean;\n beginNodeDrag: () => void;\n endNodeDrag: () => void;\n showPalette: boolean;\n setShowPalette: (v: boolean) => void;\n showInspector: boolean;\n setShowInspector: (v: boolean) => void;\n showOutline: boolean;\n setShowOutline: (v: boolean) => void;\n showJson: boolean;\n setShowJson: (v: boolean) => void;\n showAI: boolean;\n setShowAI: (v: boolean) => void;\n showMiniMap: boolean;\n setShowMiniMap: (v: boolean) => void;\n showGrid: boolean;\n setShowGrid: (v: boolean) => void;\n /** Global editor-only visibility for animation anchor objects. */\n showAnchors: boolean;\n setShowAnchors: (v: boolean) => void;\n gridSize: number;\n setGridSize: (s: number) => void;\n /** Placement magnet: when true, stamping a shape snaps it to the canvas grid. */\n placementSnap: boolean;\n setPlacementSnap: (v: boolean) => void;\n pendingPlacement: PendingPlacement | null;\n setPendingPlacement: (p: PendingPlacement | null) => void;\n contextMenu: ContextMenuState | null;\n setContextMenu: (m: ContextMenuState | null) => void;\n /** Dock assignment per panel id. Panels not listed default to the left\n * dock; users can move them to the right dock or let them float. */\n panelDocks: Record<string, FlowPanelDock>;\n setPanelDock: (tabId: string, dock: FlowPanelDock) => void;\n /** PPT-style presentation mode. When set, the overlay animates the viewport\n * between animation anchors, navigable via arrow keys. */\n presentation: PresentationState | null;\n setPresentation: (p: PresentationState | null) => void;\n /** When true, all editing affordances are suppressed (read-only preview). */\n readOnly: boolean;\n}\n\nexport interface PresentationState {\n /** Index into the anchor sequence (0-based). */\n current: number;\n /** Whether to show the active anchor frame and sequence badge in preview. */\n showAnchor?: boolean;\n}\n\nexport interface PendingPlacement {\n type: FlowShapeType;\n width: number;\n height: number;\n data: FlowNodeData;\n}\n\nconst FlowUIContext = createContext<FlowUIContextValue | null>(null);\n\nexport function useFlowUI(): FlowUIContextValue {\n const ctx = useContext(FlowUIContext);\n if (!ctx) throw new Error('useFlowUI must be used within FlowUIProvider');\n return ctx;\n}\n\nexport interface FlowUIProviderProps {\n showMiniMap?: boolean;\n showGrid?: boolean;\n gridSize?: number;\n showAI?: boolean;\n /** Suppresses context menu, inline text editing and palette placement.\n * Document mutations are additionally blocked in `Flow` (single choke point). */\n readOnly?: boolean;\n children: React.ReactNode;\n}\n\nexport function FlowUIProvider({ showMiniMap: initMiniMap = true, showGrid: initGrid = true, gridSize: initGridSize = 20, showAI: initShowAI = true, readOnly = false, children }: FlowUIProviderProps) {\n const [toolMode, setToolMode] = useState<FlowToolMode>('select');\n const [edgeType, setEdgeType] = useState<FlowEdgeTypeName>('smoothstep');\n const [viewport, setViewportState] = useState<ViewportState>({ x: 0, y: 0, zoom: 1 });\n // Distinguishes EXTERNAL viewport commands (toolbar, minimap, outline) from\n // internal echoes emitted by the ViewportManager. Only external commands\n // should be pushed back into the VM; echoing VM changes causes jitter.\n const viewportReqRef = useRef(0);\n const setViewport = useCallback((v: ViewportState) => {\n viewportReqRef.current += 1;\n setViewportState(v);\n }, []);\n // Internal setter used by the VM→React bridge; does NOT bump the request\n // counter, so the sync effect will not echo it back to the VM.\n const setViewportInternal = useCallback((v: ViewportState) => {\n setViewportState(v);\n }, []);\n const [autoFocus, setAutoFocus] = useState(false);\n const [editingNodeId, setEditingNodeIdRaw] = useState<string | null>(null);\n // In read-only mode the inline node/edge text editor must never open.\n const setEditingNodeId = useCallback((id: string | null) => {\n if (readOnly) return;\n setEditingNodeIdRaw(id);\n }, [readOnly]);\n // Counter so concurrent drags (multi-node) don't flip the flag early.\n const dragCountRef = useRef(0);\n const [isNodeDragging, setIsNodeDragging] = useState(false);\n const beginNodeDrag = useCallback(() => {\n dragCountRef.current += 1;\n if (!isNodeDragging) setIsNodeDragging(true);\n }, [isNodeDragging]);\n const endNodeDrag = useCallback(() => {\n dragCountRef.current = Math.max(0, dragCountRef.current - 1);\n if (dragCountRef.current === 0) setIsNodeDragging(false);\n }, []);\n const [showPalette, setShowPalette] = useState(true);\n const [showInspector, setShowInspector] = useState(true);\n const [showOutline, setShowOutline] = useState(true);\n const [showJson, setShowJson] = useState(true);\n const [showAI, setShowAI] = useState(initShowAI);\n const [showMiniMap, setShowMiniMap] = useState(initMiniMap);\n const [showGrid, setShowGrid] = useState(initGrid);\n const [showAnchors, setShowAnchors] = useState(true);\n const [gridSize, setGridSize] = useState(initGridSize);\n const [placementSnap, setPlacementSnap] = useState(true);\n const [pendingPlacement, setPendingPlacementRaw] = useState<PendingPlacement | null>(null);\n const [contextMenu, setContextMenuRaw] = useState<ContextMenuState | null>(null);\n // Read-only: palette drops and the right-click menu are editing affordances.\n const setPendingPlacement = useCallback((p: PendingPlacement | null) => {\n if (readOnly) return;\n setPendingPlacementRaw(p);\n }, [readOnly]);\n const setContextMenu = useCallback((m: ContextMenuState | null) => {\n if (readOnly) return;\n setContextMenuRaw(m);\n }, [readOnly]);\n const [presentation, setPresentation] = useState<PresentationState | null>(null);\n const [panelDocks, setPanelDocks] = useState<Record<string, FlowPanelDock>>({});\n const setPanelDock = useCallback((tabId: string, dock: FlowPanelDock) => {\n setPanelDocks(prev => (prev[tabId] === dock ? prev : { ...prev, [tabId]: dock }));\n }, []);\n\n const focusOnRectRef = useRef<(wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void>(() => {});\n const focusOnRect = useCallback((wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => {\n focusOnRectRef.current(wx, wy, ww, wh, options);\n }, []);\n const setFocusOnRect = useCallback((fn: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void) => {\n focusOnRectRef.current = fn;\n }, []);\n\n const value = useMemo<FlowUIContextValue>(() => ({\n toolMode, setToolMode,\n edgeType, setEdgeType,\n viewport, setViewport,\n setViewportInternal,\n viewportReqRef,\n focusOnRect, setFocusOnRect,\n autoFocus, setAutoFocus,\n editingNodeId, setEditingNodeId,\n isNodeDragging, beginNodeDrag, endNodeDrag,\n showPalette, setShowPalette,\n showInspector, setShowInspector,\n showOutline, setShowOutline,\n showJson, setShowJson,\n showAI, setShowAI,\n showMiniMap, setShowMiniMap,\n showGrid, setShowGrid,\n showAnchors, setShowAnchors,\n gridSize, setGridSize,\n placementSnap, setPlacementSnap,\n pendingPlacement, setPendingPlacement,\n contextMenu, setContextMenu,\n presentation, setPresentation,\n panelDocks, setPanelDock,\n readOnly,\n }), [toolMode, edgeType, viewport, autoFocus, editingNodeId, isNodeDragging, beginNodeDrag, endNodeDrag, showPalette, showInspector, showOutline, showJson, showAI, showMiniMap, showGrid, showAnchors, gridSize, placementSnap, pendingPlacement, contextMenu, presentation, panelDocks, setPanelDock, readOnly]);\n\n return <FlowUIContext.Provider value={value}>{children}</FlowUIContext.Provider>;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"FlowUIContext.js","names":["FlowUIContext","createContext","useFlowUI","ctx","useContext","FlowUIProvider","initMiniMap","initGrid","initGridSize","initShowAI","toolMode","setToolMode","useState","edgeType","setEdgeType","viewport","setViewportState","viewportReqRef","useRef","setViewport","useCallback","v","setViewportInternal","autoFocus","setAutoFocus","editingNodeId","setEditingNodeIdRaw","setEditingNodeId","readOnly","id","dragCountRef","isNodeDragging","setIsNodeDragging","beginNodeDrag","endNodeDrag","showPalette","setShowPalette","showInspector","setShowInspector","showOutline","setShowOutline","showJson","setShowJson","showAI","setShowAI","showMiniMap","setShowMiniMap","showGrid","setShowGrid","showAnchors","setShowAnchors","gridSize","setGridSize","placementSnap","setPlacementSnap","pendingPlacement","setPendingPlacementRaw","contextMenu","setContextMenuRaw","setPendingPlacement","p","setContextMenu","m","presentation","setPresentation","panelDocks","setPanelDocks","setPanelDock","prev","tabId","dock","focusOnRectRef","focusOnRect","wx","wy","ww","wh","options","setFocusOnRect","fn","value","useMemo"],"sources":["../../../../../src/components/pro/Flow/context/FlowUIContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo, useState, useRef, useCallback } from 'react';\nimport type { FlowToolMode, FlowEdgeTypeName, FlowShapeType, FlowNodeData, ViewportState } from '../types';\n\nexport interface ContextMenuState {\n x: number;\n y: number;\n nodeId: string | null;\n}\n\n/** Where an editing panel lives: left dock, right dock or a floating overlay. */\nexport type FlowPanelDock = 'left' | 'right' | 'float';\n\nexport interface FocusOnRectOptions {\n /** Screen-space padding around the focused rectangle, in pixels. */\n padding?: number;\n /** Maximum zoom allowed for this focus operation. */\n maxZoom?: number;\n /** Viewport transition duration in milliseconds. */\n duration?: number;\n /** Keep the current zoom and only animate the focused rectangle to center. */\n preserveZoom?: boolean;\n}\n\nexport interface FlowUIContextValue {\n toolMode: FlowToolMode;\n setToolMode: (mode: FlowToolMode) => void;\n edgeType: FlowEdgeTypeName;\n setEdgeType: (type: FlowEdgeTypeName) => void;\n viewport: ViewportState;\n setViewport: (v: ViewportState) => void;\n /** Internal VM→React bridge setter (does not request a VM apply). */\n setViewportInternal: (v: ViewportState) => void;\n /** Monotonic counter of external viewport commands. */\n viewportReqRef: React.MutableRefObject<number>;\n focusOnRect: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void;\n setFocusOnRect: (fn: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void) => void;\n autoFocus: boolean;\n setAutoFocus: (v: boolean) => void;\n editingNodeId: string | null;\n setEditingNodeId: (id: string | null) => void;\n /** True while any node/line is being dragged. Used to suppress interactive\n * DOM overlays (e.g. HTML iframes) that would otherwise swallow pointerup. */\n isNodeDragging: boolean;\n beginNodeDrag: () => void;\n endNodeDrag: () => void;\n showPalette: boolean;\n setShowPalette: (v: boolean) => void;\n showInspector: boolean;\n setShowInspector: (v: boolean) => void;\n showOutline: boolean;\n setShowOutline: (v: boolean) => void;\n showJson: boolean;\n setShowJson: (v: boolean) => void;\n showAI: boolean;\n setShowAI: (v: boolean) => void;\n showMiniMap: boolean;\n setShowMiniMap: (v: boolean) => void;\n showGrid: boolean;\n setShowGrid: (v: boolean) => void;\n /** Global editor-only visibility for animation anchor objects. */\n showAnchors: boolean;\n setShowAnchors: (v: boolean) => void;\n gridSize: number;\n setGridSize: (s: number) => void;\n /** Placement magnet: when true, stamping a shape snaps it to the canvas grid. */\n placementSnap: boolean;\n setPlacementSnap: (v: boolean) => void;\n pendingPlacement: PendingPlacement | null;\n setPendingPlacement: (p: PendingPlacement | null) => void;\n contextMenu: ContextMenuState | null;\n setContextMenu: (m: ContextMenuState | null) => void;\n /** Dock assignment per panel id. Panels not listed default to the left\n * dock; users can move them to the right dock or let them float. */\n panelDocks: Record<string, FlowPanelDock>;\n setPanelDock: (tabId: string, dock: FlowPanelDock) => void;\n /** PPT-style presentation mode. When set, the overlay animates the viewport\n * between animation anchors, navigable via arrow keys. */\n presentation: PresentationState | null;\n setPresentation: (p: PresentationState | null) => void;\n /** When true, all editing affordances are suppressed (read-only preview). */\n readOnly: boolean;\n}\n\nexport interface PresentationState {\n /** Index into the anchor sequence (0-based). */\n current: number;\n /** Whether to show the active anchor frame and sequence badge in preview. */\n showAnchor?: boolean;\n}\n\nexport interface PendingPlacement {\n type: FlowShapeType;\n width: number;\n height: number;\n data: FlowNodeData;\n}\n\nconst FlowUIContext = createContext<FlowUIContextValue | null>(null);\n\nexport function useFlowUI(): FlowUIContextValue {\n const ctx = useContext(FlowUIContext);\n if (!ctx) throw new Error('useFlowUI must be used within FlowUIProvider');\n return ctx;\n}\n\nexport interface FlowUIProviderProps {\n showMiniMap?: boolean;\n showGrid?: boolean;\n gridSize?: number;\n showAI?: boolean;\n /** Suppresses context menu, inline text editing and palette placement.\n * Document mutations are additionally blocked in `Flow` (single choke point). */\n readOnly?: boolean;\n children: React.ReactNode;\n}\n\nexport function FlowUIProvider({ showMiniMap: initMiniMap = true, showGrid: initGrid = true, gridSize: initGridSize = 20, showAI: initShowAI = true, readOnly = false, children }: FlowUIProviderProps) {\n const [toolMode, setToolMode] = useState<FlowToolMode>('select');\n const [edgeType, setEdgeType] = useState<FlowEdgeTypeName>('smoothstep');\n const [viewport, setViewportState] = useState<ViewportState>({ x: 0, y: 0, zoom: 1 });\n // Distinguishes EXTERNAL viewport commands (toolbar, minimap, outline) from\n // internal echoes emitted by the ViewportManager. Only external commands\n // should be pushed back into the VM; echoing VM changes causes jitter.\n const viewportReqRef = useRef(0);\n const setViewport = useCallback((v: ViewportState) => {\n viewportReqRef.current += 1;\n setViewportState(v);\n }, []);\n // Internal setter used by the VM→React bridge; does NOT bump the request\n // counter, so the sync effect will not echo it back to the VM.\n const setViewportInternal = useCallback((v: ViewportState) => {\n setViewportState(v);\n }, []);\n const [autoFocus, setAutoFocus] = useState(false);\n const [editingNodeId, setEditingNodeIdRaw] = useState<string | null>(null);\n // In read-only mode the inline node/edge text editor must never open.\n const setEditingNodeId = useCallback((id: string | null) => {\n if (readOnly) return;\n setEditingNodeIdRaw(id);\n }, [readOnly]);\n // Counter so concurrent drags (multi-node) don't flip the flag early.\n const dragCountRef = useRef(0);\n const [isNodeDragging, setIsNodeDragging] = useState(false);\n const beginNodeDrag = useCallback(() => {\n dragCountRef.current += 1;\n if (!isNodeDragging) setIsNodeDragging(true);\n }, [isNodeDragging]);\n const endNodeDrag = useCallback(() => {\n dragCountRef.current = Math.max(0, dragCountRef.current - 1);\n if (dragCountRef.current === 0) setIsNodeDragging(false);\n }, []);\n const [showPalette, setShowPalette] = useState(true);\n const [showInspector, setShowInspector] = useState(true);\n const [showOutline, setShowOutline] = useState(true);\n const [showJson, setShowJson] = useState(true);\n const [showAI, setShowAI] = useState(initShowAI);\n const [showMiniMap, setShowMiniMap] = useState(initMiniMap);\n const [showGrid, setShowGrid] = useState(initGrid);\n const [showAnchors, setShowAnchors] = useState(true);\n const [gridSize, setGridSize] = useState(initGridSize);\n const [placementSnap, setPlacementSnap] = useState(true);\n const [pendingPlacement, setPendingPlacementRaw] = useState<PendingPlacement | null>(null);\n const [contextMenu, setContextMenuRaw] = useState<ContextMenuState | null>(null);\n // Read-only: palette drops and the right-click menu are editing affordances.\n const setPendingPlacement = useCallback((p: PendingPlacement | null) => {\n if (readOnly) return;\n setPendingPlacementRaw(p);\n }, [readOnly]);\n const setContextMenu = useCallback((m: ContextMenuState | null) => {\n if (readOnly) return;\n setContextMenuRaw(m);\n }, [readOnly]);\n const [presentation, setPresentation] = useState<PresentationState | null>(null);\n const [panelDocks, setPanelDocks] = useState<Record<string, FlowPanelDock>>({});\n const setPanelDock = useCallback((tabId: string, dock: FlowPanelDock) => {\n setPanelDocks(prev => (prev[tabId] === dock ? prev : { ...prev, [tabId]: dock }));\n }, []);\n\n const focusOnRectRef = useRef<(wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void>(() => {});\n const focusOnRect = useCallback((wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => {\n focusOnRectRef.current(wx, wy, ww, wh, options);\n }, []);\n const setFocusOnRect = useCallback((fn: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void) => {\n focusOnRectRef.current = fn;\n }, []);\n\n const value = useMemo<FlowUIContextValue>(() => ({\n toolMode, setToolMode,\n edgeType, setEdgeType,\n viewport, setViewport,\n setViewportInternal,\n viewportReqRef,\n focusOnRect, setFocusOnRect,\n autoFocus, setAutoFocus,\n editingNodeId, setEditingNodeId,\n isNodeDragging, beginNodeDrag, endNodeDrag,\n showPalette, setShowPalette,\n showInspector, setShowInspector,\n showOutline, setShowOutline,\n showJson, setShowJson,\n showAI, setShowAI,\n showMiniMap, setShowMiniMap,\n showGrid, setShowGrid,\n showAnchors, setShowAnchors,\n gridSize, setGridSize,\n placementSnap, setPlacementSnap,\n pendingPlacement, setPendingPlacement,\n contextMenu, setContextMenu,\n presentation, setPresentation,\n panelDocks, setPanelDock,\n readOnly,\n }), [toolMode, edgeType, viewport, autoFocus, editingNodeId, isNodeDragging, beginNodeDrag, endNodeDrag, showPalette, showInspector, showOutline, showJson, showAI, showMiniMap, showGrid, showAnchors, gridSize, placementSnap, pendingPlacement, contextMenu, presentation, panelDocks, setPanelDock, readOnly]);\n\n return <FlowUIContext.Provider value={value}>{children}</FlowUIContext.Provider>;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"EdgeRenderer.js","names":[],"sources":["../../../../../src/components/pro/Flow/edges/EdgeRenderer.ts"],"sourcesContent":["import { Container, Graphics, Text, TextStyle } from 'pixi.js';\nimport type { FlowEdge, FlowNode } from '../types';\nimport { buildEdgePath, getPathCenter, resolveEdgeEndpoints, type PathSegment, type EdgeEndpoints } from './edgePaths';\nimport { drawMarker, angleBetween } from './edgeMarkers';\nimport { drawDashedPath, type PathSeg } from '../utils/dashedLine';\nimport { resolveThemeColor } from '../utils/themeColor';\n\ninterface EdgeDisplay {\n container: Container;\n line: Graphics;\n animation: Graphics;\n hitArea: Graphics;\n labelBg: Graphics | null;\n label: Text | null;\n edgeId: string;\n}\n\nfunction getDashPattern(style?: string, density?: string, width = 2): number[] | undefined {\n if (!style || style === 'solid') return undefined;\n if (style === 'dynamic') return [width * 4, width * 3];\n const base = style === 'dotted' ? width : width * 3;\n const gap = density === 'dense' ? width : density === 'sparse' ? width * 4 : width * 2;\n return [base, gap];\n}\n\n/**\n * Manages PixiJS display objects for all edges.\n */\nexport class EdgeRenderer {\n private world: Container;\n private edgeLayer: Container;\n private edges = new Map<string, EdgeDisplay>();\n private _dynamicOffset = 0;\n\n /** Call once per frame to advance the dynamic dash animation. */\n advanceAnimation(deltaMs: number): void {\n this._dynamicOffset = (this._dynamicOffset + deltaMs * 0.06) % 1000;\n }\n\n constructor(world: Container) {\n this.world = world;\n this.edgeLayer = new Container({ label: 'edges' });\n // Edges below nodes\n this.world.addChildAt(this.edgeLayer, 0);\n }\n\n sync(\n flowEdges: FlowEdge[],\n nodeMap: Map<string, FlowNode>,\n selectedIds: Set<string>,\n hoveredId: string | null,\n options?: { presentation?: boolean },\n ): void {\n const seen = new Set<string>();\n\n for (const edge of flowEdges) {\n seen.add(edge.id);\n const endpoints = resolveEdgeEndpoints(edge, nodeMap);\n if (!endpoints) continue;\n\n let display = this.edges.get(edge.id);\n if (!display) {\n display = this._createEdge(edge);\n this.edges.set(edge.id, display);\n }\n this._updateEdge(\n display,\n edge,\n endpoints,\n selectedIds.has(edge.id),\n hoveredId === edge.id,\n options?.presentation ?? false,\n );\n }\n\n for (const [id, display] of this.edges) {\n if (!seen.has(id)) {\n this.edgeLayer.removeChild(display.container);\n display.container.destroy({ children: true });\n this.edges.delete(id);\n }\n }\n }\n\n private _createEdge(edge: FlowEdge): EdgeDisplay {\n const container = new Container({ label: `edge-${edge.id}` });\n\n const hitArea = new Graphics();\n hitArea.label = 'edge-hitarea';\n hitArea.eventMode = 'static';\n hitArea.cursor = 'pointer';\n hitArea.alpha = 0;\n container.addChild(hitArea);\n\n const line = new Graphics();\n line.label = 'edge-line';\n container.addChild(line);\n\n const animation = new Graphics();\n animation.label = 'edge-animation';\n container.addChild(animation);\n\n this.edgeLayer.addChild(container);\n return { container, line, animation, hitArea, labelBg: null, label: null, edgeId: edge.id };\n }\n\n private _updateEdge(\n display: EdgeDisplay,\n edge: FlowEdge,\n endpoints: EdgeEndpoints,\n selected: boolean,\n hovered: boolean,\n presentation: boolean,\n ): void {\n const { line, animation, hitArea } = display;\n const data = edge.data;\n const color = selected ? '#3b82f6' : resolveThemeColor(data.strokeColor, '#374151');\n const width = data.strokeWidth ?? 2;\n\n const segments = buildEdgePath(edge.type, endpoints, data.waypoints, data.bezierControls);\n\n // Draw visible line\n line.clear();\n this._drawPath(line, segments, color, width, data.lineStyle, data.dashDensity);\n\n // Presentation animation: a bright gradient-like pulse travels from source\n // to target. A short dashed segment plus soft outer stroke gives the pulse\n // a leading highlight and fading tail without requiring SVG filters.\n animation.clear();\n if (presentation && data.animated) {\n const pattern = [Math.max(18, width * 12), Math.max(90, width * 45)];\n drawDashedPath(animation, segments as PathSeg[], pattern, -this._dynamicOffset * 2.2);\n animation.stroke({ color: 0x60a5fa, width: width + 5, alpha: 0.18, cap: 'round' as const });\n drawDashedPath(animation, segments as PathSeg[], pattern, -this._dynamicOffset * 2.2);\n animation.stroke({ color: 0x38bdf8, width: width + 2, alpha: 0.55, cap: 'round' as const });\n drawDashedPath(animation, segments as PathSeg[], pattern, -this._dynamicOffset * 2.2);\n animation.stroke({ color: 0xffffff, width: Math.max(1, width * 0.7), alpha: 0.9, cap: 'round' as const });\n }\n\n // Draw markers — use curve tangent for accurate arrow direction\n if (data.markerStart && data.markerStart !== 'none' && segments.length >= 2) {\n const tip = segments[0];\n const next = segments[1];\n // For curves the tangent at t=0 is tip→cp1; for lines it's tip→next\n const fromX = next.type === 'C' ? next.cp1x! : next.x;\n const fromY = next.type === 'C' ? next.cp1y! : next.y;\n const angle = angleBetween(fromX, fromY, tip.x, tip.y);\n drawMarker(line, data.markerStart, tip.x, tip.y, angle, color);\n }\n if (data.markerEnd && data.markerEnd !== 'none' && segments.length >= 2) {\n const tip = segments[segments.length - 1];\n // For curves the tangent at t=1 is cp2→endpoint\n const fromX = tip.type === 'C' ? tip.cp2x! : segments[segments.length - 2].x;\n const fromY = tip.type === 'C' ? tip.cp2y! : segments[segments.length - 2].y;\n const angle = angleBetween(fromX, fromY, tip.x, tip.y);\n drawMarker(line, data.markerEnd, tip.x, tip.y, angle, color);\n }\n\n // Wider invisible hit area\n hitArea.clear();\n this._drawPath(hitArea, segments, '#000000', Math.max(width + 10, 14), 'solid');\n hitArea.alpha = 0.001;\n\n // Edge label\n if (data.labelText) {\n const center = getPathCenter(segments);\n if (!display.label) {\n // Background chip drawn first so it sits behind the text.\n const labelBg = new Graphics();\n labelBg.label = 'edge-label-bg';\n display.container.addChild(labelBg);\n display.labelBg = labelBg;\n\n const style = new TextStyle({\n fontFamily: data.labelFontFamily ?? 'system-ui, -apple-system, sans-serif',\n fontSize: data.labelFontSize ?? 12,\n fill: color,\n });\n display.label = new Text({ text: data.labelText, style });\n display.label.anchor.set(0.5, 0.5);\n display.container.addChild(display.label);\n }\n display.label.text = data.labelText;\n const lx = center.x;\n const ly = center.y - 10;\n display.label.position.set(lx, ly);\n (display.label.style as TextStyle).fill = color;\n\n // Draw a rounded background chip behind the label so the line / waypoints\n // don't show through the text.\n if (display.labelBg) {\n const padX = 5;\n const padY = 2;\n const tw = display.label.width + padX * 2;\n const th = display.label.height + padY * 2;\n display.labelBg.clear();\n display.labelBg\n .roundRect(lx - tw / 2, ly - th / 2, tw, th, 4)\n .fill({ color: 0xffffff, alpha: 0.92 });\n }\n } else {\n if (display.label) display.label.text = '';\n if (display.labelBg) display.labelBg.clear();\n }\n }\n\n private _drawPath(\n g: Graphics,\n segs: PathSegment[],\n color: string,\n width: number,\n lineStyle?: string,\n dashDensity?: string,\n ): void {\n const dash = getDashPattern(lineStyle, dashDensity, width);\n if (dash) {\n const offset = lineStyle === 'dynamic' ? this._dynamicOffset : 0;\n drawDashedPath(g, segs as PathSeg[], dash, offset);\n g.stroke({ color, width, cap: 'round' as const });\n } else {\n for (const seg of segs) {\n switch (seg.type) {\n case 'M': g.moveTo(seg.x, seg.y); break;\n case 'L': g.lineTo(seg.x, seg.y); break;\n case 'C': g.bezierCurveTo(seg.cp1x!, seg.cp1y!, seg.cp2x!, seg.cp2y!, seg.x, seg.y); break;\n case 'Q': g.quadraticCurveTo(seg.cp1x!, seg.cp1y!, seg.x, seg.y); break;\n }\n }\n g.stroke({ color, width });\n }\n }\n\n destroy(): void {\n for (const [, display] of this.edges) {\n display.container.destroy({ children: true });\n }\n this.edges.clear();\n this.edgeLayer.destroy({ children: true });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EdgeRenderer.js","names":["getDashPattern","style","width","density","EdgeRenderer","deltaMs","world","Container","seen","edge","flowEdges","endpoints","resolveEdgeEndpoints","nodeMap","display","selectedIds","hoveredId","options","id","container","hitArea","Graphics","line","animation","data","color","selected","resolveThemeColor","segments","buildEdgePath","presentation","pattern","drawDashedPath","tip","next","fromX","fromY","angle","angleBetween","center","getPathCenter","labelBg","TextStyle","Text","lx","ly","tw","th","dash","lineStyle","dashDensity","offset","g","segs","seg"],"sources":["../../../../../src/components/pro/Flow/edges/EdgeRenderer.ts"],"sourcesContent":["import { Container, Graphics, Text, TextStyle } from 'pixi.js';\nimport type { FlowEdge, FlowNode } from '../types';\nimport { buildEdgePath, getPathCenter, resolveEdgeEndpoints, type PathSegment, type EdgeEndpoints } from './edgePaths';\nimport { drawMarker, angleBetween } from './edgeMarkers';\nimport { drawDashedPath, type PathSeg } from '../utils/dashedLine';\nimport { resolveThemeColor } from '../utils/themeColor';\n\ninterface EdgeDisplay {\n container: Container;\n line: Graphics;\n animation: Graphics;\n hitArea: Graphics;\n labelBg: Graphics | null;\n label: Text | null;\n edgeId: string;\n}\n\nfunction getDashPattern(style?: string, density?: string, width = 2): number[] | undefined {\n if (!style || style === 'solid') return undefined;\n if (style === 'dynamic') return [width * 4, width * 3];\n const base = style === 'dotted' ? width : width * 3;\n const gap = density === 'dense' ? width : density === 'sparse' ? width * 4 : width * 2;\n return [base, gap];\n}\n\n/**\n * Manages PixiJS display objects for all edges.\n */\nexport class EdgeRenderer {\n private world: Container;\n private edgeLayer: Container;\n private edges = new Map<string, EdgeDisplay>();\n private _dynamicOffset = 0;\n\n /** Call once per frame to advance the dynamic dash animation. */\n advanceAnimation(deltaMs: number): void {\n this._dynamicOffset = (this._dynamicOffset + deltaMs * 0.06) % 1000;\n }\n\n constructor(world: Container) {\n this.world = world;\n this.edgeLayer = new Container({ label: 'edges' });\n // Edges below nodes\n this.world.addChildAt(this.edgeLayer, 0);\n }\n\n sync(\n flowEdges: FlowEdge[],\n nodeMap: Map<string, FlowNode>,\n selectedIds: Set<string>,\n hoveredId: string | null,\n options?: { presentation?: boolean },\n ): void {\n const seen = new Set<string>();\n\n for (const edge of flowEdges) {\n seen.add(edge.id);\n const endpoints = resolveEdgeEndpoints(edge, nodeMap);\n if (!endpoints) continue;\n\n let display = this.edges.get(edge.id);\n if (!display) {\n display = this._createEdge(edge);\n this.edges.set(edge.id, display);\n }\n this._updateEdge(\n display,\n edge,\n endpoints,\n selectedIds.has(edge.id),\n hoveredId === edge.id,\n options?.presentation ?? false,\n );\n }\n\n for (const [id, display] of this.edges) {\n if (!seen.has(id)) {\n this.edgeLayer.removeChild(display.container);\n display.container.destroy({ children: true });\n this.edges.delete(id);\n }\n }\n }\n\n private _createEdge(edge: FlowEdge): EdgeDisplay {\n const container = new Container({ label: `edge-${edge.id}` });\n\n const hitArea = new Graphics();\n hitArea.label = 'edge-hitarea';\n hitArea.eventMode = 'static';\n hitArea.cursor = 'pointer';\n hitArea.alpha = 0;\n container.addChild(hitArea);\n\n const line = new Graphics();\n line.label = 'edge-line';\n container.addChild(line);\n\n const animation = new Graphics();\n animation.label = 'edge-animation';\n container.addChild(animation);\n\n this.edgeLayer.addChild(container);\n return { container, line, animation, hitArea, labelBg: null, label: null, edgeId: edge.id };\n }\n\n private _updateEdge(\n display: EdgeDisplay,\n edge: FlowEdge,\n endpoints: EdgeEndpoints,\n selected: boolean,\n hovered: boolean,\n presentation: boolean,\n ): void {\n const { line, animation, hitArea } = display;\n const data = edge.data;\n const color = selected ? '#3b82f6' : resolveThemeColor(data.strokeColor, '#374151');\n const width = data.strokeWidth ?? 2;\n\n const segments = buildEdgePath(edge.type, endpoints, data.waypoints, data.bezierControls);\n\n // Draw visible line\n line.clear();\n this._drawPath(line, segments, color, width, data.lineStyle, data.dashDensity);\n\n // Presentation animation: a bright gradient-like pulse travels from source\n // to target. A short dashed segment plus soft outer stroke gives the pulse\n // a leading highlight and fading tail without requiring SVG filters.\n animation.clear();\n if (presentation && data.animated) {\n const pattern = [Math.max(18, width * 12), Math.max(90, width * 45)];\n drawDashedPath(animation, segments as PathSeg[], pattern, -this._dynamicOffset * 2.2);\n animation.stroke({ color: 0x60a5fa, width: width + 5, alpha: 0.18, cap: 'round' as const });\n drawDashedPath(animation, segments as PathSeg[], pattern, -this._dynamicOffset * 2.2);\n animation.stroke({ color: 0x38bdf8, width: width + 2, alpha: 0.55, cap: 'round' as const });\n drawDashedPath(animation, segments as PathSeg[], pattern, -this._dynamicOffset * 2.2);\n animation.stroke({ color: 0xffffff, width: Math.max(1, width * 0.7), alpha: 0.9, cap: 'round' as const });\n }\n\n // Draw markers — use curve tangent for accurate arrow direction\n if (data.markerStart && data.markerStart !== 'none' && segments.length >= 2) {\n const tip = segments[0];\n const next = segments[1];\n // For curves the tangent at t=0 is tip→cp1; for lines it's tip→next\n const fromX = next.type === 'C' ? next.cp1x! : next.x;\n const fromY = next.type === 'C' ? next.cp1y! : next.y;\n const angle = angleBetween(fromX, fromY, tip.x, tip.y);\n drawMarker(line, data.markerStart, tip.x, tip.y, angle, color);\n }\n if (data.markerEnd && data.markerEnd !== 'none' && segments.length >= 2) {\n const tip = segments[segments.length - 1];\n // For curves the tangent at t=1 is cp2→endpoint\n const fromX = tip.type === 'C' ? tip.cp2x! : segments[segments.length - 2].x;\n const fromY = tip.type === 'C' ? tip.cp2y! : segments[segments.length - 2].y;\n const angle = angleBetween(fromX, fromY, tip.x, tip.y);\n drawMarker(line, data.markerEnd, tip.x, tip.y, angle, color);\n }\n\n // Wider invisible hit area\n hitArea.clear();\n this._drawPath(hitArea, segments, '#000000', Math.max(width + 10, 14), 'solid');\n hitArea.alpha = 0.001;\n\n // Edge label\n if (data.labelText) {\n const center = getPathCenter(segments);\n if (!display.label) {\n // Background chip drawn first so it sits behind the text.\n const labelBg = new Graphics();\n labelBg.label = 'edge-label-bg';\n display.container.addChild(labelBg);\n display.labelBg = labelBg;\n\n const style = new TextStyle({\n fontFamily: data.labelFontFamily ?? 'system-ui, -apple-system, sans-serif',\n fontSize: data.labelFontSize ?? 12,\n fill: color,\n });\n display.label = new Text({ text: data.labelText, style });\n display.label.anchor.set(0.5, 0.5);\n display.container.addChild(display.label);\n }\n display.label.text = data.labelText;\n const lx = center.x;\n const ly = center.y - 10;\n display.label.position.set(lx, ly);\n (display.label.style as TextStyle).fill = color;\n\n // Draw a rounded background chip behind the label so the line / waypoints\n // don't show through the text.\n if (display.labelBg) {\n const padX = 5;\n const padY = 2;\n const tw = display.label.width + padX * 2;\n const th = display.label.height + padY * 2;\n display.labelBg.clear();\n display.labelBg\n .roundRect(lx - tw / 2, ly - th / 2, tw, th, 4)\n .fill({ color: 0xffffff, alpha: 0.92 });\n }\n } else {\n if (display.label) display.label.text = '';\n if (display.labelBg) display.labelBg.clear();\n }\n }\n\n private _drawPath(\n g: Graphics,\n segs: PathSegment[],\n color: string,\n width: number,\n lineStyle?: string,\n dashDensity?: string,\n ): void {\n const dash = getDashPattern(lineStyle, dashDensity, width);\n if (dash) {\n const offset = lineStyle === 'dynamic' ? this._dynamicOffset : 0;\n drawDashedPath(g, segs as PathSeg[], dash, offset);\n g.stroke({ color, width, cap: 'round' as const });\n } else {\n for (const seg of segs) {\n switch (seg.type) {\n case 'M': g.moveTo(seg.x, seg.y); break;\n case 'L': g.lineTo(seg.x, seg.y); break;\n case 'C': g.bezierCurveTo(seg.cp1x!, seg.cp1y!, seg.cp2x!, seg.cp2y!, seg.x, seg.y); break;\n case 'Q': g.quadraticCurveTo(seg.cp1x!, seg.cp1y!, seg.x, seg.y); break;\n }\n }\n g.stroke({ color, width });\n }\n }\n\n destroy(): void {\n for (const [, display] of this.edges) {\n display.container.destroy({ children: true });\n }\n this.edges.clear();\n this.edgeLayer.destroy({ children: true });\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"edgeMarkers.js","names":[],"sources":["../../../../../src/components/pro/Flow/edges/edgeMarkers.ts"],"sourcesContent":["import { Graphics } from 'pixi.js';\nimport type { FlowEdgeMarkerKind } from '../types';\n\nconst MARKER_SIZE = 10;\n\n/**\n * Draw an arrow marker at a given position and angle.\n */\nexport function drawMarker(\n g: Graphics,\n kind: FlowEdgeMarkerKind,\n x: number,\n y: number,\n angle: number,\n color: string,\n size = MARKER_SIZE,\n): void {\n if (kind === 'none') return;\n\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n\n const tipX = x;\n const tipY = y;\n const leftX = x - size * cos + (size / 2) * sin;\n const leftY = y - size * sin - (size / 2) * cos;\n const rightX = x - size * cos - (size / 2) * sin;\n const rightY = y - size * sin + (size / 2) * cos;\n\n g.moveTo(tipX, tipY)\n .lineTo(leftX, leftY)\n .lineTo(rightX, rightY);\n\n if (kind === 'arrowclosed') {\n g.closePath().fill({ color });\n } else {\n g.stroke({ color, width: 1.5 });\n }\n}\n\n/**\n * Compute the angle between two points (in radians).\n */\nexport function angleBetween(\n fromX: number, fromY: number,\n toX: number, toY: number,\n): number {\n return Math.atan2(toY - fromY, toX - fromX);\n}\n"],"mappings":"AAQA,SAAgB,EACd,GACA,GACA,GACA,GACA,GACA,GACA,IAAO,IACD;CACN,IAAI,MAAS,QAAQ;CAErB,IAAM,IAAM,KAAK,IAAI,CAAK,GACpB,IAAM,KAAK,IAAI,CAAK,GAEpB,IAAO,GACP,IAAO,GACP,IAAQ,IAAI,IAAO,IAAO,IAAO,IAAK,GACtC,IAAQ,IAAI,IAAO,IAAO,IAAO,IAAK,GACtC,IAAS,IAAI,IAAO,IAAO,IAAO,IAAK,GACvC,IAAS,IAAI,IAAO,IAAO,IAAO,IAAK;CAM7C,AAJA,EAAE,OAAO,GAAM,CAAI,CAAC,CACjB,OAAO,GAAO,CAAK,CAAC,CACpB,OAAO,GAAQ,CAAM,GAEpB,MAAS,gBACX,EAAE,UAAU,CAAC,CAAC,KAAK,EAAE,SAAM,CAAC,IAE5B,EAAE,OAAO;EAAE;EAAO,OAAO;CAAI,CAAC;AAElC;AAKA,SAAgB,EACd,GAAe,GACf,GAAa,GACL;CACR,OAAO,KAAK,MAAM,IAAM,GAAO,IAAM,CAAK;AAC5C"}
1
+ {"version":3,"file":"edgeMarkers.js","names":["drawMarker","kind","cos","angle","sin","tipX","x","tipY","y","leftX","size","leftY","rightX","rightY","g","angleBetween","toY","fromY","toX","fromX"],"sources":["../../../../../src/components/pro/Flow/edges/edgeMarkers.ts"],"sourcesContent":["import { Graphics } from 'pixi.js';\nimport type { FlowEdgeMarkerKind } from '../types';\n\nconst MARKER_SIZE = 10;\n\n/**\n * Draw an arrow marker at a given position and angle.\n */\nexport function drawMarker(\n g: Graphics,\n kind: FlowEdgeMarkerKind,\n x: number,\n y: number,\n angle: number,\n color: string,\n size = MARKER_SIZE,\n): void {\n if (kind === 'none') return;\n\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n\n const tipX = x;\n const tipY = y;\n const leftX = x - size * cos + (size / 2) * sin;\n const leftY = y - size * sin - (size / 2) * cos;\n const rightX = x - size * cos - (size / 2) * sin;\n const rightY = y - size * sin + (size / 2) * cos;\n\n g.moveTo(tipX, tipY)\n .lineTo(leftX, leftY)\n .lineTo(rightX, rightY);\n\n if (kind === 'arrowclosed') {\n g.closePath().fill({ color });\n } else {\n g.stroke({ color, width: 1.5 });\n }\n}\n\n/**\n * Compute the angle between two points (in radians).\n */\nexport function angleBetween(\n fromX: number, fromY: number,\n toX: number, toY: number,\n): number {\n return Math.atan2(toY - fromY, toX - fromX);\n}\n"],"mappings":"AAQA,SAAgBA,EACd,GACA,GACA,GACA,GACA,GACA,GACA,IAAO,IACD;CACN,IAAIC,MAAS,QAAQ;CAErB,IAAMC,IAAM,KAAK,IAAIC,CAAK,GACpBC,IAAM,KAAK,IAAID,CAAK,GAEpBE,IAAOC,GACPC,IAAOC,GACPC,IAAQH,IAAII,IAAOR,IAAOQ,IAAO,IAAKN,GACtCO,IAAQH,IAAIE,IAAON,IAAOM,IAAO,IAAKR,GACtCU,IAASN,IAAII,IAAOR,IAAOQ,IAAO,IAAKN,GACvCS,IAASL,IAAIE,IAAON,IAAOM,IAAO,IAAKR;CAM7C,AAJAY,EAAE,OAAOT,GAAME,CAAI,CAAC,CACjB,OAAOE,GAAOE,CAAK,CAAC,CACpB,OAAOC,GAAQC,CAAM,GAEpBZ,MAAS,gBACXa,EAAE,UAAU,CAAC,CAAC,KAAK,EAAE,SAAM,CAAC,IAE5BA,EAAE,OAAO;EAAE;EAAO,OAAO;CAAI,CAAC;AAElC;AAKA,SAAgBC,EACd,GAAe,GACf,GAAa,GACL;CACR,OAAO,KAAK,MAAMC,IAAMC,GAAOC,IAAMC,CAAK;AAC5C"}
@@ -1 +1 @@
1
- {"version":3,"file":"edgePaths.js","names":[],"sources":["../../../../../src/components/pro/Flow/edges/edgePaths.ts"],"sourcesContent":["import type { FlowEdgeTypeName, FlowBezierControl, FlowEdge, FlowNode } from '../types';\nimport { getHandlePositions, type HandleDef } from '../nodes/NodeHandles';\n\n/** Outward unit normal for a handle side */\nconst SIDE_NORMAL: Record<string, { dx: number; dy: number }> = {\n top: { dx: 0, dy: -1 },\n bottom: { dx: 0, dy: 1 },\n left: { dx: -1, dy: 0 },\n right: { dx: 1, dy: 0 },\n};\n\n/** Perpendicular clearance (px) from node edge for step / smoothstep paths */\nconst EDGE_OFFSET = 20;\n/** Bezier control-arm length multiplier (fraction of inter-node distance, clamped) */\nconst BEZ_ARM_MIN = 30;\nconst BEZ_ARM_FRAC = 0.3;\n\nexport interface EdgeEndpoints {\n sx: number; sy: number;\n tx: number; ty: number;\n /** Outward unit-normal at source handle */\n snx: number; sny: number;\n /** Outward unit-normal at target handle */\n tnx: number; tny: number;\n}\n\nexport interface PathSegment {\n type: 'M' | 'L' | 'C' | 'Q';\n x: number; y: number;\n cp1x?: number; cp1y?: number;\n cp2x?: number; cp2y?: number;\n}\n\n/**\n * Build a path (array of segments) for the given edge type.\n * Returns segments that can be drawn with PixiJS Graphics.\n */\nexport function buildEdgePath(\n type: FlowEdgeTypeName,\n endpoints: EdgeEndpoints,\n waypoints?: Array<{ x: number; y: number }>,\n bezierControls?: Array<FlowBezierControl | null> | null,\n): PathSegment[] {\n const src = { x: endpoints.sx, y: endpoints.sy };\n const tgt = { x: endpoints.tx, y: endpoints.ty };\n const wps = waypoints ?? [];\n\n switch (type) {\n case 'straight':\n return buildStraightPath([src, ...wps, tgt]);\n\n case 'step':\n case 'smoothstep': {\n const radius = type === 'smoothstep' ? 8 : 0;\n return buildStepPathWithOffsets(src, tgt, wps, endpoints, radius);\n }\n\n case 'simplebezier':\n return buildBezierPath([src, ...wps, tgt], bezierControls, endpoints);\n\n default:\n return buildStraightPath([src, ...wps, tgt]);\n }\n}\n\nfunction buildStraightPath(points: Array<{ x: number; y: number }>): PathSegment[] {\n const segs: PathSegment[] = [{ type: 'M', x: points[0].x, y: points[0].y }];\n for (let i = 1; i < points.length; i++) {\n segs.push({ type: 'L', x: points[i].x, y: points[i].y });\n }\n return segs;\n}\n\n/**\n * Step path with perpendicular exit / entry offsets.\n *\n * Produces clean orthogonal \"elbow\" routing:\n * 1. source → exit stub (perpendicular to the source face)\n * 2. exit → waypoints → approach (orthogonal)\n * 3. approach stub → target (perpendicular into the target face)\n *\n * The middle routing picks the split axis from the two handle orientations so\n * opposing/aligned handles produce a single clean bend instead of an S/Z jog,\n * and collinear points are collapsed at the end.\n */\nfunction buildStepPathWithOffsets(\n src: { x: number; y: number },\n tgt: { x: number; y: number },\n waypoints: Array<{ x: number; y: number }>,\n ep: EdgeEndpoints,\n borderRadius: number,\n): PathSegment[] {\n const dist = Math.hypot(tgt.x - src.x, tgt.y - src.y);\n const offset = Math.min(EDGE_OFFSET, dist / 4);\n\n const exitPt = { x: src.x + ep.snx * offset, y: src.y + ep.sny * offset };\n const approPt = { x: tgt.x + ep.tnx * offset, y: tgt.y + ep.tny * offset };\n\n const srcVertical = Math.abs(ep.sny) > Math.abs(ep.snx);\n const tgtVertical = Math.abs(ep.tny) > Math.abs(ep.tnx);\n\n // Build the raw corner list (no rounding yet), then simplify + round.\n const corners: Array<{ x: number; y: number }> = [{ x: src.x, y: src.y }, exitPt];\n\n const mids = [exitPt, ...waypoints, approPt];\n for (let i = 0; i < mids.length - 1; i++) {\n const a = mids[i];\n const b = mids[i + 1];\n // Orientation of this leg: first leg follows source, last leg follows target.\n const vertical = i === 0 ? srcVertical : (i === mids.length - 2 ? tgtVertical : srcVertical);\n if (vertical) {\n // V-H-V: go vertically to the mid-Y, across, then down/up.\n const midY = (a.y + b.y) / 2;\n corners.push({ x: a.x, y: midY }, { x: b.x, y: midY });\n } else {\n // H-V-H: go horizontally to the mid-X, vertically, then across.\n const midX = (a.x + b.x) / 2;\n corners.push({ x: midX, y: a.y }, { x: midX, y: b.y });\n }\n corners.push({ x: b.x, y: b.y });\n }\n corners.push({ x: tgt.x, y: tgt.y });\n\n const simplified = simplifyOrthogonal(corners);\n return roundedOrthogonalPath(simplified, borderRadius);\n}\n\n/**\n * Remove collinear / duplicate points from an orthogonal polyline so we don't\n * emit degenerate zero-length jogs (a common source of \"unnatural\" bends).\n */\nfunction simplifyOrthogonal(pts: Array<{ x: number; y: number }>): Array<{ x: number; y: number }> {\n const out: Array<{ x: number; y: number }> = [];\n for (const p of pts) {\n const last = out[out.length - 1];\n if (last && Math.abs(last.x - p.x) < 0.01 && Math.abs(last.y - p.y) < 0.01) continue;\n out.push({ x: p.x, y: p.y });\n }\n // Drop the middle of any 3 collinear points.\n const res: Array<{ x: number; y: number }> = [];\n for (let i = 0; i < out.length; i++) {\n const prev = res[res.length - 1];\n const cur = out[i];\n const next = out[i + 1];\n if (prev && next) {\n const collinearX = Math.abs(prev.x - cur.x) < 0.01 && Math.abs(cur.x - next.x) < 0.01;\n const collinearY = Math.abs(prev.y - cur.y) < 0.01 && Math.abs(cur.y - next.y) < 0.01;\n if (collinearX || collinearY) continue;\n }\n res.push(cur);\n }\n return res;\n}\n\n/**\n * Convert an orthogonal polyline into path segments, rounding each corner.\n */\nfunction roundedOrthogonalPath(\n pts: Array<{ x: number; y: number }>,\n borderRadius: number,\n): PathSegment[] {\n if (pts.length === 0) return [];\n const segs: PathSegment[] = [{ type: 'M', x: pts[0].x, y: pts[0].y }];\n if (pts.length === 1) return segs;\n if (borderRadius <= 0.5) {\n for (let i = 1; i < pts.length; i++) segs.push({ type: 'L', x: pts[i].x, y: pts[i].y });\n return segs;\n }\n for (let i = 1; i < pts.length - 1; i++) {\n const prev = pts[i - 1];\n const cur = pts[i];\n const next = pts[i + 1];\n const inLen = Math.hypot(cur.x - prev.x, cur.y - prev.y);\n const outLen = Math.hypot(next.x - cur.x, next.y - cur.y);\n const r = Math.min(borderRadius, inLen / 2, outLen / 2);\n if (r < 0.5) {\n segs.push({ type: 'L', x: cur.x, y: cur.y });\n continue;\n }\n const inDx = Math.sign(cur.x - prev.x);\n const inDy = Math.sign(cur.y - prev.y);\n const outDx = Math.sign(next.x - cur.x);\n const outDy = Math.sign(next.y - cur.y);\n segs.push({ type: 'L', x: cur.x - inDx * r, y: cur.y - inDy * r });\n segs.push({ type: 'Q', x: cur.x + outDx * r, y: cur.y + outDy * r, cp1x: cur.x, cp1y: cur.y });\n }\n const end = pts[pts.length - 1];\n segs.push({ type: 'L', x: end.x, y: end.y });\n return segs;\n}\n\n/**\n * Cubic bezier path between consecutive points.\n * Uses handle normals on the first / last segment for perpendicular exit/entry.\n */\nfunction buildBezierPath(\n points: Array<{ x: number; y: number }>,\n controls?: Array<FlowBezierControl | null> | null,\n ep?: EdgeEndpoints,\n): PathSegment[] {\n const segs: PathSegment[] = [{ type: 'M', x: points[0].x, y: points[0].y }];\n const lastIdx = points.length - 2;\n\n for (let i = 0; i <= lastIdx; i++) {\n const a = points[i];\n const b = points[i + 1];\n const ctrl = controls?.[i];\n\n if (ctrl) {\n segs.push({\n type: 'C', x: b.x, y: b.y,\n cp1x: ctrl.c1x, cp1y: ctrl.c1y,\n cp2x: ctrl.c2x, cp2y: ctrl.c2y,\n });\n } else {\n const dist = Math.hypot(b.x - a.x, b.y - a.y);\n const arm = Math.max(BEZ_ARM_MIN, dist * BEZ_ARM_FRAC);\n\n let c1x: number, c1y: number;\n if (i === 0 && ep) {\n c1x = a.x + ep.snx * arm;\n c1y = a.y + ep.sny * arm;\n } else {\n c1x = a.x + (b.x - a.x) * 0.4;\n c1y = a.y;\n }\n\n let c2x: number, c2y: number;\n if (i === lastIdx && ep) {\n c2x = b.x + ep.tnx * arm;\n c2y = b.y + ep.tny * arm;\n } else {\n c2x = b.x - (b.x - a.x) * 0.4;\n c2y = b.y;\n }\n\n segs.push({\n type: 'C', x: b.x, y: b.y,\n cp1x: c1x, cp1y: c1y,\n cp2x: c2x, cp2y: c2y,\n });\n }\n }\n return segs;\n}\n\n/**\n * Compute the center point of a path (for label placement).\n */\nexport function getPathCenter(segs: PathSegment[]): { x: number; y: number } {\n if (segs.length < 2) return { x: segs[0]?.x ?? 0, y: segs[0]?.y ?? 0 };\n const mid = Math.floor(segs.length / 2);\n const a = segs[mid - 1];\n const b = segs[mid];\n return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };\n}\n\n/**\n * Get a point on a path at parameter t (0-1), approximate.\n */\nexport function getPointOnPath(segs: PathSegment[], t: number): { x: number; y: number } {\n if (segs.length < 2) return { x: segs[0]?.x ?? 0, y: segs[0]?.y ?? 0 };\n const totalSegs = segs.length - 1;\n const segIdx = Math.min(Math.floor(t * totalSegs), totalSegs - 1);\n const localT = (t * totalSegs) - segIdx;\n const a = segs[segIdx];\n const b = segs[segIdx + 1];\n return {\n x: a.x + (b.x - a.x) * localT,\n y: a.y + (b.y - a.y) * localT,\n };\n}\n\n/**\n * Resolve source/target anchor positions for an edge.\n * Uses stored handle IDs when available; falls back to closest-handle heuristic.\n */\n/**\n * Transform a handle's local-space position into world space,\n * accounting for the node's rotation (degrees, stored in data.rotation).\n */\nfunction handleToWorld(\n hx: number, hy: number,\n node: FlowNode,\n): { x: number; y: number } {\n const deg = node.data.rotation ?? 0;\n if (deg === 0) {\n return { x: node.position.x + hx, y: node.position.y + hy };\n }\n const rad = (deg * Math.PI) / 180;\n const cx = node.width / 2, cy = node.height / 2;\n const dx = hx - cx, dy = hy - cy;\n const cos = Math.cos(rad), sin = Math.sin(rad);\n return {\n x: node.position.x + cx + dx * cos - dy * sin,\n y: node.position.y + cy + dx * sin + dy * cos,\n };\n}\n\n/**\n * Compute the outward unit-normal for a handle, accounting for node rotation.\n */\nfunction handleNormal(h: HandleDef | null, node: FlowNode): { nx: number; ny: number } {\n const base = SIDE_NORMAL[h?.side ?? 'right'] ?? SIDE_NORMAL.right;\n const deg = node.data.rotation ?? 0;\n if (deg === 0) return { nx: base.dx, ny: base.dy };\n const rad = (deg * Math.PI) / 180;\n const cos = Math.cos(rad), sin = Math.sin(rad);\n return {\n nx: base.dx * cos - base.dy * sin,\n ny: base.dx * sin + base.dy * cos,\n };\n}\n\nexport function resolveEdgeEndpoints(\n edge: FlowEdge,\n nodeMap: Map<string, FlowNode>,\n): EdgeEndpoints | null {\n const sn = nodeMap.get(edge.source);\n const tn = nodeMap.get(edge.target);\n if (!sn || !tn) return null;\n\n const sHandles = getHandlePositions(sn.width, sn.height);\n const tHandles = getHandlePositions(tn.width, tn.height);\n\n let sx: number, sy: number, sH: HandleDef | null;\n if (edge.sourceHandle) {\n sH = sHandles.find(h => h.id === edge.sourceHandle) ?? null;\n const pos = handleToWorld(sH ? sH.x : sn.width / 2, sH ? sH.y : sn.height / 2, sn);\n sx = pos.x; sy = pos.y;\n } else {\n // Floating anchor: pick the side by direction, then slide the point along\n // that side to align with the target so aligned nodes connect with a\n // straight line instead of a forced mid-handle jog.\n const anchor = floatingAnchor(sn, tn);\n sx = anchor.x; sy = anchor.y; sH = anchor.handleLike;\n }\n\n let tx: number, ty: number, tH: HandleDef | null;\n if (edge.targetHandle) {\n tH = tHandles.find(h => h.id === edge.targetHandle) ?? null;\n const pos = handleToWorld(tH ? tH.x : tn.width / 2, tH ? tH.y : tn.height / 2, tn);\n tx = pos.x; ty = pos.y;\n } else {\n const anchor = floatingAnchor(tn, sn);\n tx = anchor.x; ty = anchor.y; tH = anchor.handleLike;\n }\n\n const sN = handleNormal(sH, sn);\n const tN = handleNormal(tH, tn);\n\n return { sx, sy, tx, ty, snx: sN.nx, sny: sN.ny, tnx: tN.nx, tny: tN.ny };\n}\n\n/**\n * Compute a floating connection anchor on `self` facing `other`.\n * Chooses the side by dominant direction, then slides the anchor along that\n * side to line up with the other node's center (clamped to the side extent).\n * Returns the world point plus a synthetic handle carrying only the `side`\n * (used for the outward normal).\n */\nfunction floatingAnchor(\n self: FlowNode,\n other: FlowNode,\n): { x: number; y: number; handleLike: HandleDef } {\n const sx = self.position.x, sy = self.position.y;\n const sw = self.width, sh = self.height;\n const sCx = sx + sw / 2, sCy = sy + sh / 2;\n let oCx = other.position.x + other.width / 2;\n let oCy = other.position.y + other.height / 2;\n\n const deg = self.data.rotation ?? 0;\n if (deg !== 0) {\n // Work in the node's local (unrotated) frame: rotate the other node's\n // center into that frame so side-picking and the slide-to-align run in the\n // same space the anchor is computed in. The anchor is mapped back to world\n // space below via `handleToWorld`, so it rides on the rotated border.\n const rad = (deg * Math.PI) / 180;\n const cos = Math.cos(-rad), sin = Math.sin(-rad);\n const dx = oCx - sCx;\n const dy = oCy - sCy;\n oCx = sCx + dx * cos - dy * sin;\n oCy = sCy + dx * sin + dy * cos;\n }\n\n const dx = oCx - sCx;\n const dy = oCy - sCy;\n // Inset so the anchor never sits exactly on a corner.\n const inset = Math.min(12, sw / 2 - 1, sh / 2 - 1);\n\n let side: HandleDef['side'];\n let x: number, y: number;\n if (Math.abs(dx) >= Math.abs(dy)) {\n side = dx >= 0 ? 'right' : 'left';\n x = side === 'right' ? sx + sw : sx;\n // Slide vertically to align with the other center, clamped to the side.\n y = Math.max(sy + inset, Math.min(sy + sh - inset, oCy));\n } else {\n side = dy >= 0 ? 'bottom' : 'top';\n y = side === 'bottom' ? sy + sh : sy;\n x = Math.max(sx + inset, Math.min(sx + sw - inset, oCx));\n }\n\n if (deg !== 0) {\n // Map the (locally chosen) anchor back onto the rotated border.\n const pos = handleToWorld(x - sx, y - sy, self);\n return { x: pos.x, y: pos.y, handleLike: { id: `float_${side}`, x: 0, y: 0, side } };\n }\n\n return { x, y, handleLike: { id: `float_${side}`, x: 0, y: 0, side } };\n}\n\n/**\n * Previously this pinned auto-resolved edges to a fixed middle handle at load\n * time, which forced ugly jogs between misaligned nodes. Edges without an\n * explicit handle are now left \"floating\" and resolved dynamically in\n * `resolveEdgeEndpoints` (see `floatingAnchor`), so this is a no-op that simply\n * preserves any user-pinned handles.\n */\nexport function normalizeEdgeHandles(\n edges: FlowEdge[],\n _nodeMap: Map<string, FlowNode>,\n): FlowEdge[] {\n const legacyOffsets = new Map([\n ['0.25', String(2 / 6)],\n ['0.5', String(3 / 6)],\n ['0.75', String(4 / 6)],\n ]);\n let changed = false;\n const migrate = (handle: string | undefined) => {\n if (!handle) return handle;\n const [side, offset] = handle.split('_');\n const nextOffset = legacyOffsets.get(offset);\n if (!nextOffset || !side) return handle;\n changed = true;\n return `${side}_${nextOffset}`;\n };\n const normalized = edges.map(edge => {\n const sourceHandle = migrate(edge.sourceHandle);\n const targetHandle = migrate(edge.targetHandle);\n return sourceHandle === edge.sourceHandle && targetHandle === edge.targetHandle\n ? edge\n : { ...edge, sourceHandle, targetHandle };\n });\n return changed ? normalized : edges;\n}\n\n/**\n * Convert PathSegments into a polyline by sampling curves.\n */\nexport function linearizeSegments(\n segs: PathSegment[],\n samplesPerCurve = 8,\n): Array<{ x: number; y: number }> {\n const pts: Array<{ x: number; y: number }> = [];\n let cx = 0, cy = 0;\n for (const seg of segs) {\n switch (seg.type) {\n case 'M':\n case 'L':\n cx = seg.x; cy = seg.y;\n pts.push({ x: cx, y: cy });\n break;\n case 'Q': {\n const cpx = seg.cp1x!, cpy = seg.cp1y!;\n for (let i = 1; i <= samplesPerCurve; i++) {\n const t = i / samplesPerCurve, mt = 1 - t;\n pts.push({\n x: mt * mt * cx + 2 * mt * t * cpx + t * t * seg.x,\n y: mt * mt * cy + 2 * mt * t * cpy + t * t * seg.y,\n });\n }\n cx = seg.x; cy = seg.y;\n break;\n }\n case 'C': {\n const c1x = seg.cp1x!, c1y = seg.cp1y!, c2x = seg.cp2x!, c2y = seg.cp2y!;\n for (let i = 1; i <= samplesPerCurve; i++) {\n const t = i / samplesPerCurve, mt = 1 - t;\n pts.push({\n x: mt ** 3 * cx + 3 * mt ** 2 * t * c1x + 3 * mt * t ** 2 * c2x + t ** 3 * seg.x,\n y: mt ** 3 * cy + 3 * mt ** 2 * t * c1y + 3 * mt * t ** 2 * c2y + t ** 3 * seg.y,\n });\n }\n cx = seg.x; cy = seg.y;\n break;\n }\n }\n }\n return pts;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"edgePaths.js","names":["SIDE_NORMAL","EDGE_OFFSET","BEZ_ARM_MIN","BEZ_ARM_FRAC","buildEdgePath","src","endpoints","tgt","wps","waypoints","type","buildStraightPath","buildStepPathWithOffsets","buildBezierPath","bezierControls","segs","points","i","dist","offset","exitPt","ep","approPt","srcVertical","tgtVertical","corners","mids","a","b","midY","midX","roundedOrthogonalPath","simplifyOrthogonal","borderRadius","out","p","pts","last","res","prev","cur","next","collinearX","collinearY","inLen","outLen","r","inDx","inDy","outDx","outDy","end","lastIdx","ctrl","controls","arm","c1x","c1y","c2x","c2y","getPathCenter","mid","handleToWorld","deg","node","hx","hy","rad","cx","cy","dx","dy","cos","sin","handleNormal","base","h","resolveEdgeEndpoints","sn","nodeMap","edge","tn","sHandles","getHandlePositions","tHandles","sx","sy","sH","pos","anchor","floatingAnchor","tx","ty","tH","sN","tN","self","sw","sh","sCx","sCy","oCx","other","oCy","inset","side","x","y","normalizeEdgeHandles","legacyOffsets","changed","migrate","handle","nextOffset","normalized","edges","sourceHandle","targetHandle","linearizeSegments","seg","cpx","cpy","samplesPerCurve","t","mt"],"sources":["../../../../../src/components/pro/Flow/edges/edgePaths.ts"],"sourcesContent":["import type { FlowEdgeTypeName, FlowBezierControl, FlowEdge, FlowNode } from '../types';\nimport { getHandlePositions, type HandleDef } from '../nodes/NodeHandles';\n\n/** Outward unit normal for a handle side */\nconst SIDE_NORMAL: Record<string, { dx: number; dy: number }> = {\n top: { dx: 0, dy: -1 },\n bottom: { dx: 0, dy: 1 },\n left: { dx: -1, dy: 0 },\n right: { dx: 1, dy: 0 },\n};\n\n/** Perpendicular clearance (px) from node edge for step / smoothstep paths */\nconst EDGE_OFFSET = 20;\n/** Bezier control-arm length multiplier (fraction of inter-node distance, clamped) */\nconst BEZ_ARM_MIN = 30;\nconst BEZ_ARM_FRAC = 0.3;\n\nexport interface EdgeEndpoints {\n sx: number; sy: number;\n tx: number; ty: number;\n /** Outward unit-normal at source handle */\n snx: number; sny: number;\n /** Outward unit-normal at target handle */\n tnx: number; tny: number;\n}\n\nexport interface PathSegment {\n type: 'M' | 'L' | 'C' | 'Q';\n x: number; y: number;\n cp1x?: number; cp1y?: number;\n cp2x?: number; cp2y?: number;\n}\n\n/**\n * Build a path (array of segments) for the given edge type.\n * Returns segments that can be drawn with PixiJS Graphics.\n */\nexport function buildEdgePath(\n type: FlowEdgeTypeName,\n endpoints: EdgeEndpoints,\n waypoints?: Array<{ x: number; y: number }>,\n bezierControls?: Array<FlowBezierControl | null> | null,\n): PathSegment[] {\n const src = { x: endpoints.sx, y: endpoints.sy };\n const tgt = { x: endpoints.tx, y: endpoints.ty };\n const wps = waypoints ?? [];\n\n switch (type) {\n case 'straight':\n return buildStraightPath([src, ...wps, tgt]);\n\n case 'step':\n case 'smoothstep': {\n const radius = type === 'smoothstep' ? 8 : 0;\n return buildStepPathWithOffsets(src, tgt, wps, endpoints, radius);\n }\n\n case 'simplebezier':\n return buildBezierPath([src, ...wps, tgt], bezierControls, endpoints);\n\n default:\n return buildStraightPath([src, ...wps, tgt]);\n }\n}\n\nfunction buildStraightPath(points: Array<{ x: number; y: number }>): PathSegment[] {\n const segs: PathSegment[] = [{ type: 'M', x: points[0].x, y: points[0].y }];\n for (let i = 1; i < points.length; i++) {\n segs.push({ type: 'L', x: points[i].x, y: points[i].y });\n }\n return segs;\n}\n\n/**\n * Step path with perpendicular exit / entry offsets.\n *\n * Produces clean orthogonal \"elbow\" routing:\n * 1. source → exit stub (perpendicular to the source face)\n * 2. exit → waypoints → approach (orthogonal)\n * 3. approach stub → target (perpendicular into the target face)\n *\n * The middle routing picks the split axis from the two handle orientations so\n * opposing/aligned handles produce a single clean bend instead of an S/Z jog,\n * and collinear points are collapsed at the end.\n */\nfunction buildStepPathWithOffsets(\n src: { x: number; y: number },\n tgt: { x: number; y: number },\n waypoints: Array<{ x: number; y: number }>,\n ep: EdgeEndpoints,\n borderRadius: number,\n): PathSegment[] {\n const dist = Math.hypot(tgt.x - src.x, tgt.y - src.y);\n const offset = Math.min(EDGE_OFFSET, dist / 4);\n\n const exitPt = { x: src.x + ep.snx * offset, y: src.y + ep.sny * offset };\n const approPt = { x: tgt.x + ep.tnx * offset, y: tgt.y + ep.tny * offset };\n\n const srcVertical = Math.abs(ep.sny) > Math.abs(ep.snx);\n const tgtVertical = Math.abs(ep.tny) > Math.abs(ep.tnx);\n\n // Build the raw corner list (no rounding yet), then simplify + round.\n const corners: Array<{ x: number; y: number }> = [{ x: src.x, y: src.y }, exitPt];\n\n const mids = [exitPt, ...waypoints, approPt];\n for (let i = 0; i < mids.length - 1; i++) {\n const a = mids[i];\n const b = mids[i + 1];\n // Orientation of this leg: first leg follows source, last leg follows target.\n const vertical = i === 0 ? srcVertical : (i === mids.length - 2 ? tgtVertical : srcVertical);\n if (vertical) {\n // V-H-V: go vertically to the mid-Y, across, then down/up.\n const midY = (a.y + b.y) / 2;\n corners.push({ x: a.x, y: midY }, { x: b.x, y: midY });\n } else {\n // H-V-H: go horizontally to the mid-X, vertically, then across.\n const midX = (a.x + b.x) / 2;\n corners.push({ x: midX, y: a.y }, { x: midX, y: b.y });\n }\n corners.push({ x: b.x, y: b.y });\n }\n corners.push({ x: tgt.x, y: tgt.y });\n\n const simplified = simplifyOrthogonal(corners);\n return roundedOrthogonalPath(simplified, borderRadius);\n}\n\n/**\n * Remove collinear / duplicate points from an orthogonal polyline so we don't\n * emit degenerate zero-length jogs (a common source of \"unnatural\" bends).\n */\nfunction simplifyOrthogonal(pts: Array<{ x: number; y: number }>): Array<{ x: number; y: number }> {\n const out: Array<{ x: number; y: number }> = [];\n for (const p of pts) {\n const last = out[out.length - 1];\n if (last && Math.abs(last.x - p.x) < 0.01 && Math.abs(last.y - p.y) < 0.01) continue;\n out.push({ x: p.x, y: p.y });\n }\n // Drop the middle of any 3 collinear points.\n const res: Array<{ x: number; y: number }> = [];\n for (let i = 0; i < out.length; i++) {\n const prev = res[res.length - 1];\n const cur = out[i];\n const next = out[i + 1];\n if (prev && next) {\n const collinearX = Math.abs(prev.x - cur.x) < 0.01 && Math.abs(cur.x - next.x) < 0.01;\n const collinearY = Math.abs(prev.y - cur.y) < 0.01 && Math.abs(cur.y - next.y) < 0.01;\n if (collinearX || collinearY) continue;\n }\n res.push(cur);\n }\n return res;\n}\n\n/**\n * Convert an orthogonal polyline into path segments, rounding each corner.\n */\nfunction roundedOrthogonalPath(\n pts: Array<{ x: number; y: number }>,\n borderRadius: number,\n): PathSegment[] {\n if (pts.length === 0) return [];\n const segs: PathSegment[] = [{ type: 'M', x: pts[0].x, y: pts[0].y }];\n if (pts.length === 1) return segs;\n if (borderRadius <= 0.5) {\n for (let i = 1; i < pts.length; i++) segs.push({ type: 'L', x: pts[i].x, y: pts[i].y });\n return segs;\n }\n for (let i = 1; i < pts.length - 1; i++) {\n const prev = pts[i - 1];\n const cur = pts[i];\n const next = pts[i + 1];\n const inLen = Math.hypot(cur.x - prev.x, cur.y - prev.y);\n const outLen = Math.hypot(next.x - cur.x, next.y - cur.y);\n const r = Math.min(borderRadius, inLen / 2, outLen / 2);\n if (r < 0.5) {\n segs.push({ type: 'L', x: cur.x, y: cur.y });\n continue;\n }\n const inDx = Math.sign(cur.x - prev.x);\n const inDy = Math.sign(cur.y - prev.y);\n const outDx = Math.sign(next.x - cur.x);\n const outDy = Math.sign(next.y - cur.y);\n segs.push({ type: 'L', x: cur.x - inDx * r, y: cur.y - inDy * r });\n segs.push({ type: 'Q', x: cur.x + outDx * r, y: cur.y + outDy * r, cp1x: cur.x, cp1y: cur.y });\n }\n const end = pts[pts.length - 1];\n segs.push({ type: 'L', x: end.x, y: end.y });\n return segs;\n}\n\n/**\n * Cubic bezier path between consecutive points.\n * Uses handle normals on the first / last segment for perpendicular exit/entry.\n */\nfunction buildBezierPath(\n points: Array<{ x: number; y: number }>,\n controls?: Array<FlowBezierControl | null> | null,\n ep?: EdgeEndpoints,\n): PathSegment[] {\n const segs: PathSegment[] = [{ type: 'M', x: points[0].x, y: points[0].y }];\n const lastIdx = points.length - 2;\n\n for (let i = 0; i <= lastIdx; i++) {\n const a = points[i];\n const b = points[i + 1];\n const ctrl = controls?.[i];\n\n if (ctrl) {\n segs.push({\n type: 'C', x: b.x, y: b.y,\n cp1x: ctrl.c1x, cp1y: ctrl.c1y,\n cp2x: ctrl.c2x, cp2y: ctrl.c2y,\n });\n } else {\n const dist = Math.hypot(b.x - a.x, b.y - a.y);\n const arm = Math.max(BEZ_ARM_MIN, dist * BEZ_ARM_FRAC);\n\n let c1x: number, c1y: number;\n if (i === 0 && ep) {\n c1x = a.x + ep.snx * arm;\n c1y = a.y + ep.sny * arm;\n } else {\n c1x = a.x + (b.x - a.x) * 0.4;\n c1y = a.y;\n }\n\n let c2x: number, c2y: number;\n if (i === lastIdx && ep) {\n c2x = b.x + ep.tnx * arm;\n c2y = b.y + ep.tny * arm;\n } else {\n c2x = b.x - (b.x - a.x) * 0.4;\n c2y = b.y;\n }\n\n segs.push({\n type: 'C', x: b.x, y: b.y,\n cp1x: c1x, cp1y: c1y,\n cp2x: c2x, cp2y: c2y,\n });\n }\n }\n return segs;\n}\n\n/**\n * Compute the center point of a path (for label placement).\n */\nexport function getPathCenter(segs: PathSegment[]): { x: number; y: number } {\n if (segs.length < 2) return { x: segs[0]?.x ?? 0, y: segs[0]?.y ?? 0 };\n const mid = Math.floor(segs.length / 2);\n const a = segs[mid - 1];\n const b = segs[mid];\n return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };\n}\n\n/**\n * Get a point on a path at parameter t (0-1), approximate.\n */\nexport function getPointOnPath(segs: PathSegment[], t: number): { x: number; y: number } {\n if (segs.length < 2) return { x: segs[0]?.x ?? 0, y: segs[0]?.y ?? 0 };\n const totalSegs = segs.length - 1;\n const segIdx = Math.min(Math.floor(t * totalSegs), totalSegs - 1);\n const localT = (t * totalSegs) - segIdx;\n const a = segs[segIdx];\n const b = segs[segIdx + 1];\n return {\n x: a.x + (b.x - a.x) * localT,\n y: a.y + (b.y - a.y) * localT,\n };\n}\n\n/**\n * Resolve source/target anchor positions for an edge.\n * Uses stored handle IDs when available; falls back to closest-handle heuristic.\n */\n/**\n * Transform a handle's local-space position into world space,\n * accounting for the node's rotation (degrees, stored in data.rotation).\n */\nfunction handleToWorld(\n hx: number, hy: number,\n node: FlowNode,\n): { x: number; y: number } {\n const deg = node.data.rotation ?? 0;\n if (deg === 0) {\n return { x: node.position.x + hx, y: node.position.y + hy };\n }\n const rad = (deg * Math.PI) / 180;\n const cx = node.width / 2, cy = node.height / 2;\n const dx = hx - cx, dy = hy - cy;\n const cos = Math.cos(rad), sin = Math.sin(rad);\n return {\n x: node.position.x + cx + dx * cos - dy * sin,\n y: node.position.y + cy + dx * sin + dy * cos,\n };\n}\n\n/**\n * Compute the outward unit-normal for a handle, accounting for node rotation.\n */\nfunction handleNormal(h: HandleDef | null, node: FlowNode): { nx: number; ny: number } {\n const base = SIDE_NORMAL[h?.side ?? 'right'] ?? SIDE_NORMAL.right;\n const deg = node.data.rotation ?? 0;\n if (deg === 0) return { nx: base.dx, ny: base.dy };\n const rad = (deg * Math.PI) / 180;\n const cos = Math.cos(rad), sin = Math.sin(rad);\n return {\n nx: base.dx * cos - base.dy * sin,\n ny: base.dx * sin + base.dy * cos,\n };\n}\n\nexport function resolveEdgeEndpoints(\n edge: FlowEdge,\n nodeMap: Map<string, FlowNode>,\n): EdgeEndpoints | null {\n const sn = nodeMap.get(edge.source);\n const tn = nodeMap.get(edge.target);\n if (!sn || !tn) return null;\n\n const sHandles = getHandlePositions(sn.width, sn.height);\n const tHandles = getHandlePositions(tn.width, tn.height);\n\n let sx: number, sy: number, sH: HandleDef | null;\n if (edge.sourceHandle) {\n sH = sHandles.find(h => h.id === edge.sourceHandle) ?? null;\n const pos = handleToWorld(sH ? sH.x : sn.width / 2, sH ? sH.y : sn.height / 2, sn);\n sx = pos.x; sy = pos.y;\n } else {\n // Floating anchor: pick the side by direction, then slide the point along\n // that side to align with the target so aligned nodes connect with a\n // straight line instead of a forced mid-handle jog.\n const anchor = floatingAnchor(sn, tn);\n sx = anchor.x; sy = anchor.y; sH = anchor.handleLike;\n }\n\n let tx: number, ty: number, tH: HandleDef | null;\n if (edge.targetHandle) {\n tH = tHandles.find(h => h.id === edge.targetHandle) ?? null;\n const pos = handleToWorld(tH ? tH.x : tn.width / 2, tH ? tH.y : tn.height / 2, tn);\n tx = pos.x; ty = pos.y;\n } else {\n const anchor = floatingAnchor(tn, sn);\n tx = anchor.x; ty = anchor.y; tH = anchor.handleLike;\n }\n\n const sN = handleNormal(sH, sn);\n const tN = handleNormal(tH, tn);\n\n return { sx, sy, tx, ty, snx: sN.nx, sny: sN.ny, tnx: tN.nx, tny: tN.ny };\n}\n\n/**\n * Compute a floating connection anchor on `self` facing `other`.\n * Chooses the side by dominant direction, then slides the anchor along that\n * side to line up with the other node's center (clamped to the side extent).\n * Returns the world point plus a synthetic handle carrying only the `side`\n * (used for the outward normal).\n */\nfunction floatingAnchor(\n self: FlowNode,\n other: FlowNode,\n): { x: number; y: number; handleLike: HandleDef } {\n const sx = self.position.x, sy = self.position.y;\n const sw = self.width, sh = self.height;\n const sCx = sx + sw / 2, sCy = sy + sh / 2;\n let oCx = other.position.x + other.width / 2;\n let oCy = other.position.y + other.height / 2;\n\n const deg = self.data.rotation ?? 0;\n if (deg !== 0) {\n // Work in the node's local (unrotated) frame: rotate the other node's\n // center into that frame so side-picking and the slide-to-align run in the\n // same space the anchor is computed in. The anchor is mapped back to world\n // space below via `handleToWorld`, so it rides on the rotated border.\n const rad = (deg * Math.PI) / 180;\n const cos = Math.cos(-rad), sin = Math.sin(-rad);\n const dx = oCx - sCx;\n const dy = oCy - sCy;\n oCx = sCx + dx * cos - dy * sin;\n oCy = sCy + dx * sin + dy * cos;\n }\n\n const dx = oCx - sCx;\n const dy = oCy - sCy;\n // Inset so the anchor never sits exactly on a corner.\n const inset = Math.min(12, sw / 2 - 1, sh / 2 - 1);\n\n let side: HandleDef['side'];\n let x: number, y: number;\n if (Math.abs(dx) >= Math.abs(dy)) {\n side = dx >= 0 ? 'right' : 'left';\n x = side === 'right' ? sx + sw : sx;\n // Slide vertically to align with the other center, clamped to the side.\n y = Math.max(sy + inset, Math.min(sy + sh - inset, oCy));\n } else {\n side = dy >= 0 ? 'bottom' : 'top';\n y = side === 'bottom' ? sy + sh : sy;\n x = Math.max(sx + inset, Math.min(sx + sw - inset, oCx));\n }\n\n if (deg !== 0) {\n // Map the (locally chosen) anchor back onto the rotated border.\n const pos = handleToWorld(x - sx, y - sy, self);\n return { x: pos.x, y: pos.y, handleLike: { id: `float_${side}`, x: 0, y: 0, side } };\n }\n\n return { x, y, handleLike: { id: `float_${side}`, x: 0, y: 0, side } };\n}\n\n/**\n * Previously this pinned auto-resolved edges to a fixed middle handle at load\n * time, which forced ugly jogs between misaligned nodes. Edges without an\n * explicit handle are now left \"floating\" and resolved dynamically in\n * `resolveEdgeEndpoints` (see `floatingAnchor`), so this is a no-op that simply\n * preserves any user-pinned handles.\n */\nexport function normalizeEdgeHandles(\n edges: FlowEdge[],\n _nodeMap: Map<string, FlowNode>,\n): FlowEdge[] {\n const legacyOffsets = new Map([\n ['0.25', String(2 / 6)],\n ['0.5', String(3 / 6)],\n ['0.75', String(4 / 6)],\n ]);\n let changed = false;\n const migrate = (handle: string | undefined) => {\n if (!handle) return handle;\n const [side, offset] = handle.split('_');\n const nextOffset = legacyOffsets.get(offset);\n if (!nextOffset || !side) return handle;\n changed = true;\n return `${side}_${nextOffset}`;\n };\n const normalized = edges.map(edge => {\n const sourceHandle = migrate(edge.sourceHandle);\n const targetHandle = migrate(edge.targetHandle);\n return sourceHandle === edge.sourceHandle && targetHandle === edge.targetHandle\n ? edge\n : { ...edge, sourceHandle, targetHandle };\n });\n return changed ? normalized : edges;\n}\n\n/**\n * Convert PathSegments into a polyline by sampling curves.\n */\nexport function linearizeSegments(\n segs: PathSegment[],\n samplesPerCurve = 8,\n): Array<{ x: number; y: number }> {\n const pts: Array<{ x: number; y: number }> = [];\n let cx = 0, cy = 0;\n for (const seg of segs) {\n switch (seg.type) {\n case 'M':\n case 'L':\n cx = seg.x; cy = seg.y;\n pts.push({ x: cx, y: cy });\n break;\n case 'Q': {\n const cpx = seg.cp1x!, cpy = seg.cp1y!;\n for (let i = 1; i <= samplesPerCurve; i++) {\n const t = i / samplesPerCurve, mt = 1 - t;\n pts.push({\n x: mt * mt * cx + 2 * mt * t * cpx + t * t * seg.x,\n y: mt * mt * cy + 2 * mt * t * cpy + t * t * seg.y,\n });\n }\n cx = seg.x; cy = seg.y;\n break;\n }\n case 'C': {\n const c1x = seg.cp1x!, c1y = seg.cp1y!, c2x = seg.cp2x!, c2y = seg.cp2y!;\n for (let i = 1; i <= samplesPerCurve; i++) {\n const t = i / samplesPerCurve, mt = 1 - t;\n pts.push({\n x: mt ** 3 * cx + 3 * mt ** 2 * t * c1x + 3 * mt * t ** 2 * c2x + t ** 3 * seg.x,\n y: mt ** 3 * cy + 3 * mt ** 2 * t * c1y + 3 * mt * t ** 2 * c2y + t ** 3 * seg.y,\n });\n }\n cx = seg.x; cy = seg.y;\n break;\n }\n }\n }\n return pts;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useAlignmentGuides.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useAlignmentGuides.ts"],"sourcesContent":["import { useMemo, useRef } from 'react';\nimport type { FlowNode } from '../types';\nimport { SNAP_THRESHOLD } from '../constants';\n\nexport interface AlignGuide {\n type: 'vertical' | 'horizontal';\n position: number;\n}\n\n/**\n * Computes alignment snap guides during node drag.\n * Returns snap offsets and guide lines to render.\n */\nexport function computeAlignmentSnap(\n draggingNodes: FlowNode[],\n allNodes: FlowNode[],\n threshold = SNAP_THRESHOLD,\n): { dx: number; dy: number; guides: AlignGuide[] } {\n if (draggingNodes.length === 0) return { dx: 0, dy: 0, guides: [] };\n\n const dragIds = new Set(draggingNodes.map(n => n.id));\n const staticNodes = allNodes.filter(n => !dragIds.has(n.id));\n\n if (staticNodes.length === 0) return { dx: 0, dy: 0, guides: [] };\n\n // Compute drag bounds\n let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;\n for (const n of draggingNodes) {\n minX = Math.min(minX, n.position.x);\n maxX = Math.max(maxX, n.position.x + n.width);\n minY = Math.min(minY, n.position.y);\n maxY = Math.max(maxY, n.position.y + n.height);\n }\n const dragCx = (minX + maxX) / 2;\n const dragCy = (minY + maxY) / 2;\n\n // Collect snap lines from static nodes\n const xSnaps: number[] = [];\n const ySnaps: number[] = [];\n for (const n of staticNodes) {\n xSnaps.push(n.position.x, n.position.x + n.width / 2, n.position.x + n.width);\n ySnaps.push(n.position.y, n.position.y + n.height / 2, n.position.y + n.height);\n }\n\n // Dragging node snap points\n const dragXPoints = [minX, dragCx, maxX];\n const dragYPoints = [minY, dragCy, maxY];\n\n let bestDx = 0;\n let bestDistX = threshold + 1;\n let snapXLine: number | null = null;\n\n for (const dx of dragXPoints) {\n for (const sx of xSnaps) {\n const dist = Math.abs(dx - sx);\n if (dist < bestDistX) {\n bestDistX = dist;\n bestDx = sx - dx;\n snapXLine = sx;\n }\n }\n }\n\n let bestDy = 0;\n let bestDistY = threshold + 1;\n let snapYLine: number | null = null;\n\n for (const dy of dragYPoints) {\n for (const sy of ySnaps) {\n const dist = Math.abs(dy - sy);\n if (dist < bestDistY) {\n bestDistY = dist;\n bestDy = sy - dy;\n snapYLine = sy;\n }\n }\n }\n\n const guides: AlignGuide[] = [];\n const dx = bestDistX <= threshold ? bestDx : 0;\n const dy = bestDistY <= threshold ? bestDy : 0;\n if (bestDistX <= threshold && snapXLine !== null) guides.push({ type: 'vertical', position: snapXLine });\n if (bestDistY <= threshold && snapYLine !== null) guides.push({ type: 'horizontal', position: snapYLine });\n\n return { dx, dy, guides };\n}\n"],"mappings":";AAaA,SAAgB,EACd,GACA,GACA,IAAA,GACkD;CAClD,IAAI,EAAc,WAAW,GAAG,OAAO;EAAE,IAAI;EAAG,IAAI;EAAG,QAAQ,CAAC;CAAE;CAElE,IAAM,IAAU,IAAI,IAAI,EAAc,KAAI,MAAK,EAAE,EAAE,CAAC,GAC9C,IAAc,EAAS,QAAO,MAAK,CAAC,EAAQ,IAAI,EAAE,EAAE,CAAC;CAE3D,IAAI,EAAY,WAAW,GAAG,OAAO;EAAE,IAAI;EAAG,IAAI;EAAG,QAAQ,CAAC;CAAE;CAGhE,IAAI,IAAO,UAAU,IAAO,WAAW,IAAO,UAAU,IAAO;CAC/D,KAAK,IAAM,KAAK,GAId,AAHA,IAAO,KAAK,IAAI,GAAM,EAAE,SAAS,CAAC,GAClC,IAAO,KAAK,IAAI,GAAM,EAAE,SAAS,IAAI,EAAE,KAAK,GAC5C,IAAO,KAAK,IAAI,GAAM,EAAE,SAAS,CAAC,GAClC,IAAO,KAAK,IAAI,GAAM,EAAE,SAAS,IAAI,EAAE,MAAM;CAE/C,IAAM,KAAU,IAAO,KAAQ,GACzB,KAAU,IAAO,KAAQ,GAGzB,IAAmB,CAAC,GACpB,IAAmB,CAAC;CAC1B,KAAK,IAAM,KAAK,GAEd,AADA,EAAO,KAAK,EAAE,SAAS,GAAG,EAAE,SAAS,IAAI,EAAE,QAAQ,GAAG,EAAE,SAAS,IAAI,EAAE,KAAK,GAC5E,EAAO,KAAK,EAAE,SAAS,GAAG,EAAE,SAAS,IAAI,EAAE,SAAS,GAAG,EAAE,SAAS,IAAI,EAAE,MAAM;CAIhF,IAAM,IAAc;EAAC;EAAM;EAAQ;CAAI,GACjC,IAAc;EAAC;EAAM;EAAQ;CAAI,GAEnC,IAAS,GACT,IAAY,IAAY,GACxB,IAA2B;CAE/B,KAAK,IAAM,KAAM,GACf,KAAK,IAAM,KAAM,GAAQ;EACvB,IAAM,IAAO,KAAK,IAAI,IAAK,CAAE;EAC7B,AAAI,IAAO,MACT,IAAY,GACZ,IAAS,IAAK,GACd,IAAY;CAEhB;CAGF,IAAI,IAAS,GACT,IAAY,IAAY,GACxB,IAA2B;CAE/B,KAAK,IAAM,KAAM,GACf,KAAK,IAAM,KAAM,GAAQ;EACvB,IAAM,IAAO,KAAK,IAAI,IAAK,CAAE;EAC7B,AAAI,IAAO,MACT,IAAY,GACZ,IAAS,IAAK,GACd,IAAY;CAEhB;CAGF,IAAM,IAAuB,CAAC,GACxB,IAAK,KAAa,IAAY,IAAS,GACvC,IAAK,KAAa,IAAY,IAAS;CAI7C,OAHI,KAAa,KAAa,MAAc,QAAM,EAAO,KAAK;EAAE,MAAM;EAAY,UAAU;CAAU,CAAC,GACnG,KAAa,KAAa,MAAc,QAAM,EAAO,KAAK;EAAE,MAAM;EAAc,UAAU;CAAU,CAAC,GAElG;EAAE;EAAI;EAAI;CAAO;AAC1B"}
1
+ {"version":3,"file":"useAlignmentGuides.js","names":["computeAlignmentSnap","draggingNodes","dragIds","n","staticNodes","allNodes","minX","maxX","minY","maxY","dragCx","dragCy","xSnaps","ySnaps","dragXPoints","dragYPoints","bestDx","bestDistX","threshold","snapXLine","dx","sx","dist","bestDy","bestDistY","snapYLine","dy","sy","guides"],"sources":["../../../../../src/components/pro/Flow/hooks/useAlignmentGuides.ts"],"sourcesContent":["import { useMemo, useRef } from 'react';\nimport type { FlowNode } from '../types';\nimport { SNAP_THRESHOLD } from '../constants';\n\nexport interface AlignGuide {\n type: 'vertical' | 'horizontal';\n position: number;\n}\n\n/**\n * Computes alignment snap guides during node drag.\n * Returns snap offsets and guide lines to render.\n */\nexport function computeAlignmentSnap(\n draggingNodes: FlowNode[],\n allNodes: FlowNode[],\n threshold = SNAP_THRESHOLD,\n): { dx: number; dy: number; guides: AlignGuide[] } {\n if (draggingNodes.length === 0) return { dx: 0, dy: 0, guides: [] };\n\n const dragIds = new Set(draggingNodes.map(n => n.id));\n const staticNodes = allNodes.filter(n => !dragIds.has(n.id));\n\n if (staticNodes.length === 0) return { dx: 0, dy: 0, guides: [] };\n\n // Compute drag bounds\n let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;\n for (const n of draggingNodes) {\n minX = Math.min(minX, n.position.x);\n maxX = Math.max(maxX, n.position.x + n.width);\n minY = Math.min(minY, n.position.y);\n maxY = Math.max(maxY, n.position.y + n.height);\n }\n const dragCx = (minX + maxX) / 2;\n const dragCy = (minY + maxY) / 2;\n\n // Collect snap lines from static nodes\n const xSnaps: number[] = [];\n const ySnaps: number[] = [];\n for (const n of staticNodes) {\n xSnaps.push(n.position.x, n.position.x + n.width / 2, n.position.x + n.width);\n ySnaps.push(n.position.y, n.position.y + n.height / 2, n.position.y + n.height);\n }\n\n // Dragging node snap points\n const dragXPoints = [minX, dragCx, maxX];\n const dragYPoints = [minY, dragCy, maxY];\n\n let bestDx = 0;\n let bestDistX = threshold + 1;\n let snapXLine: number | null = null;\n\n for (const dx of dragXPoints) {\n for (const sx of xSnaps) {\n const dist = Math.abs(dx - sx);\n if (dist < bestDistX) {\n bestDistX = dist;\n bestDx = sx - dx;\n snapXLine = sx;\n }\n }\n }\n\n let bestDy = 0;\n let bestDistY = threshold + 1;\n let snapYLine: number | null = null;\n\n for (const dy of dragYPoints) {\n for (const sy of ySnaps) {\n const dist = Math.abs(dy - sy);\n if (dist < bestDistY) {\n bestDistY = dist;\n bestDy = sy - dy;\n snapYLine = sy;\n }\n }\n }\n\n const guides: AlignGuide[] = [];\n const dx = bestDistX <= threshold ? bestDx : 0;\n const dy = bestDistY <= threshold ? bestDy : 0;\n if (bestDistX <= threshold && snapXLine !== null) guides.push({ type: 'vertical', position: snapXLine });\n if (bestDistY <= threshold && snapYLine !== null) guides.push({ type: 'horizontal', position: snapYLine });\n\n return { dx, dy, guides };\n}\n"],"mappings":";AAaA,SAAgBA,EACd,GACA,GACA,IAAA,GACkD;CAClD,IAAIC,EAAc,WAAW,GAAG,OAAO;EAAE,IAAI;EAAG,IAAI;EAAG,QAAQ,CAAC;CAAE;CAElE,IAAMC,IAAU,IAAI,IAAID,EAAc,KAAI,MAAKE,EAAE,EAAE,CAAC,GAC9CC,IAAcC,EAAS,QAAO,MAAK,CAACH,EAAQ,IAAIC,EAAE,EAAE,CAAC;CAE3D,IAAIC,EAAY,WAAW,GAAG,OAAO;EAAE,IAAI;EAAG,IAAI;EAAG,QAAQ,CAAC;CAAE;CAGhE,IAAIE,IAAO,UAAUC,IAAO,WAAWC,IAAO,UAAUC,IAAO;CAC/D,KAAK,IAAMN,KAAKF,GAId,AAHA,IAAO,KAAK,IAAIK,GAAMH,EAAE,SAAS,CAAC,GAClC,IAAO,KAAK,IAAII,GAAMJ,EAAE,SAAS,IAAIA,EAAE,KAAK,GAC5C,IAAO,KAAK,IAAIK,GAAML,EAAE,SAAS,CAAC,GAClC,IAAO,KAAK,IAAIM,GAAMN,EAAE,SAAS,IAAIA,EAAE,MAAM;CAE/C,IAAMO,KAAUJ,IAAOC,KAAQ,GACzBI,KAAUH,IAAOC,KAAQ,GAGzBG,IAAmB,CAAC,GACpBC,IAAmB,CAAC;CAC1B,KAAK,IAAMV,KAAKC,GAEd,AADAQ,EAAO,KAAKT,EAAE,SAAS,GAAGA,EAAE,SAAS,IAAIA,EAAE,QAAQ,GAAGA,EAAE,SAAS,IAAIA,EAAE,KAAK,GAC5EU,EAAO,KAAKV,EAAE,SAAS,GAAGA,EAAE,SAAS,IAAIA,EAAE,SAAS,GAAGA,EAAE,SAAS,IAAIA,EAAE,MAAM;CAIhF,IAAMW,IAAc;EAACR;EAAMI;EAAQH;CAAI,GACjCQ,IAAc;EAACP;EAAMG;EAAQF;CAAI,GAEnCO,IAAS,GACTC,IAAYC,IAAY,GACxBC,IAA2B;CAE/B,KAAK,IAAMC,KAAMN,GACf,KAAK,IAAMO,KAAMT,GAAQ;EACvB,IAAMU,IAAO,KAAK,IAAIF,IAAKC,CAAE;EAC7B,AAAIC,IAAOL,MACT,IAAYK,GACZ,IAASD,IAAKD,GACd,IAAYC;CAEhB;CAGF,IAAIE,IAAS,GACTC,IAAYN,IAAY,GACxBO,IAA2B;CAE/B,KAAK,IAAMC,KAAMX,GACf,KAAK,IAAMY,KAAMd,GAAQ;EACvB,IAAMS,IAAO,KAAK,IAAII,IAAKC,CAAE;EAC7B,AAAIL,IAAOE,MACT,IAAYF,GACZ,IAASK,IAAKD,GACd,IAAYC;CAEhB;CAGF,IAAMC,IAAuB,CAAC,GACxBR,IAAKH,KAAaC,IAAYF,IAAS,GACvCU,IAAKF,KAAaN,IAAYK,IAAS;CAI7C,OAHIN,KAAaC,KAAaC,MAAc,QAAMS,EAAO,KAAK;EAAE,MAAM;EAAY,UAAUT;CAAU,CAAC,GACnGK,KAAaN,KAAaO,MAAc,QAAMG,EAAO,KAAK;EAAE,MAAM;EAAc,UAAUH;CAAU,CAAC,GAElG;EAAE;EAAI;EAAI;CAAO;AAC1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"useClipboard.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useClipboard.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport { generateId } from '../nodes/nodeUtils';\nimport type { FlowNode, FlowEdge, FlowLine } from '../types';\n\ninterface ClipboardData {\n nodes: FlowNode[];\n edges: FlowEdge[];\n lines: FlowLine[];\n}\n\n/**\n * Copy/paste/cut for selected flow elements.\n * Uses internal clipboard (not system clipboard) for structured data.\n */\nexport function useClipboard() {\n const { currentCanvas, selection, setDoc, currentCanvasId, setSelection } = useFlowContext();\n const clipboardRef = useRef<ClipboardData | null>(null);\n\n const copy = useCallback(() => {\n const nodes = currentCanvas.nodes.filter(n => selection.nodeIds.has(n.id));\n const edges = currentCanvas.edges.filter(e => selection.edgeIds.has(e.id));\n const lines = currentCanvas.lines.filter(l => selection.lineIds.has(l.id));\n\n // Also include edges that connect selected nodes\n const nodeIds = new Set(nodes.map(n => n.id));\n const connectedEdges = currentCanvas.edges.filter(\n e => nodeIds.has(e.source) && nodeIds.has(e.target) && !selection.edgeIds.has(e.id),\n );\n\n clipboardRef.current = {\n nodes: [...nodes],\n edges: [...edges, ...connectedEdges],\n lines: [...lines],\n };\n }, [currentCanvas, selection]);\n\n const cut = useCallback(() => {\n copy();\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.filter(n => !selection.nodeIds.has(n.id))\n .map(n => n.parentId && selection.nodeIds.has(n.parentId) ? { ...n, parentId: undefined } : n),\n edges: canvas.edges.filter(e =>\n !selection.edgeIds.has(e.id) &&\n !selection.nodeIds.has(e.source) &&\n !selection.nodeIds.has(e.target),\n ),\n lines: canvas.lines.filter(l => !selection.lineIds.has(l.id))\n .map(l => l.parentId && selection.nodeIds.has(l.parentId) ? { ...l, parentId: undefined } : l),\n },\n },\n };\n });\n setSelection({ nodeIds: new Set(), edgeIds: new Set(), lineIds: new Set() });\n }, [copy, setDoc, currentCanvasId, selection, setSelection]);\n\n const paste = useCallback((offsetX = 20, offsetY = 20) => {\n const cb = clipboardRef.current;\n if (!cb) return;\n\n const idMap = new Map<string, string>();\n const newNodes: FlowNode[] = cb.nodes.map(n => {\n const newId = generateId('node');\n idMap.set(n.id, newId);\n return {\n ...n,\n id: newId,\n position: { x: n.position.x + offsetX, y: n.position.y + offsetY },\n data: { ...n.data },\n };\n });\n\n for (const n of newNodes) {\n if (n.parentId) n.parentId = idMap.get(n.parentId)\n ?? (currentCanvas.nodes.some(parent => parent.id === n.parentId) ? n.parentId : undefined);\n }\n\n const newEdges: FlowEdge[] = cb.edges\n .filter(e => idMap.has(e.source) && idMap.has(e.target))\n .map(e => ({\n ...e,\n id: generateId('edge'),\n source: idMap.get(e.source)!,\n target: idMap.get(e.target)!,\n data: { ...e.data },\n }));\n\n const newLines: FlowLine[] = cb.lines.map(l => ({\n ...l,\n id: generateId('line'),\n parentId: l.parentId ? idMap.get(l.parentId)\n ?? (currentCanvas.nodes.some(parent => parent.id === l.parentId) ? l.parentId : undefined) : undefined,\n points: l.points.map(p => ({ x: p.x + offsetX, y: p.y + offsetY })),\n }));\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: [...canvas.nodes, ...newNodes],\n edges: [...canvas.edges, ...newEdges],\n lines: [...canvas.lines, ...newLines],\n },\n },\n };\n });\n\n setSelection({\n nodeIds: new Set(newNodes.map(n => n.id)),\n edgeIds: new Set(newEdges.map(e => e.id)),\n lineIds: new Set(newLines.map(l => l.id)),\n });\n }, [setDoc, currentCanvasId, setSelection, currentCanvas]);\n\n const hasClipboard = clipboardRef.current !== null;\n\n /**\n * Duplicate the current selection in place (Cmd/Ctrl+D). Unlike copy+paste\n * this does NOT touch the clipboard, so a prior copy stays intact. Clones the\n * selected nodes (plus edges wholly between them) and lines with a small\n * offset, then selects the clones.\n */\n const duplicate = useCallback((\n offsetX = 24,\n offsetY = 24,\n targets?: { nodeIds?: Set<string>; edgeIds?: Set<string>; lineIds?: Set<string> },\n ) => {\n const nodeSel = targets ? targets.nodeIds ?? new Set<string>() : selection.nodeIds;\n const edgeSel = targets ? targets.edgeIds ?? new Set<string>() : selection.edgeIds;\n const lineSel = targets ? targets.lineIds ?? new Set<string>() : selection.lineIds;\n const nodes = currentCanvas.nodes.filter(n => nodeSel.has(n.id));\n const lines = currentCanvas.lines.filter(l => lineSel.has(l.id));\n const nodeIdSet = new Set(nodes.map(n => n.id));\n const edges = currentCanvas.edges.filter(e =>\n edgeSel.has(e.id) ||\n (nodeIdSet.has(e.source) && nodeIdSet.has(e.target)),\n );\n if (nodes.length === 0 && lines.length === 0 && edges.length === 0) return;\n\n const idMap = new Map<string, string>();\n // Assign fresh ids to nodes first so intra-selection edges can be remapped.\n const newNodes: FlowNode[] = nodes.map(n => {\n const newId = generateId('node');\n idMap.set(n.id, newId);\n return { ...n, id: newId, position: { x: n.position.x + offsetX, y: n.position.y + offsetY }, data: { ...n.data } };\n });\n // Re-parent cloned children onto cloned groups when both were duplicated.\n for (const n of newNodes) {\n if (n.parentId && idMap.has(n.parentId)) n.parentId = idMap.get(n.parentId);\n }\n\n const newEdges: FlowEdge[] = edges\n .filter(e => idMap.has(e.source) && idMap.has(e.target))\n .map(e => ({\n ...e,\n id: generateId('edge'),\n source: idMap.get(e.source)!,\n target: idMap.get(e.target)!,\n data: { ...e.data },\n }));\n\n const newLines: FlowLine[] = lines.map(l => ({\n ...l,\n id: generateId('line'),\n parentId: l.parentId ? idMap.get(l.parentId) ?? l.parentId : undefined,\n points: l.points.map(p => ({ x: p.x + offsetX, y: p.y + offsetY })),\n }));\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: [...canvas.nodes, ...newNodes],\n edges: [...canvas.edges, ...newEdges],\n lines: [...canvas.lines, ...newLines],\n },\n },\n };\n });\n\n setSelection({\n nodeIds: new Set(newNodes.map(n => n.id)),\n edgeIds: new Set(newEdges.map(e => e.id)),\n lineIds: new Set(newLines.map(l => l.id)),\n });\n }, [currentCanvas, selection, setDoc, currentCanvasId, setSelection]);\n\n return { copy, cut, paste, duplicate, hasClipboard };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useClipboard.js","names":["useClipboard","useFlowContext","clipboardRef","useRef","copy","useCallback","nodes","currentCanvas","selection","n","edges","lines","l","nodeIds","connectedEdges","cut","setDoc","canvas","prev","currentCanvasId","setSelection","paste","cb","idMap","newNodes","newId","generateId","offsetX","offsetY","parent","newEdges","newLines","p","hasClipboard","nodeSel","targets","edgeSel","lineSel","nodeIdSet"],"sources":["../../../../../src/components/pro/Flow/hooks/useClipboard.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport { generateId } from '../nodes/nodeUtils';\nimport type { FlowNode, FlowEdge, FlowLine } from '../types';\n\ninterface ClipboardData {\n nodes: FlowNode[];\n edges: FlowEdge[];\n lines: FlowLine[];\n}\n\n/**\n * Copy/paste/cut for selected flow elements.\n * Uses internal clipboard (not system clipboard) for structured data.\n */\nexport function useClipboard() {\n const { currentCanvas, selection, setDoc, currentCanvasId, setSelection } = useFlowContext();\n const clipboardRef = useRef<ClipboardData | null>(null);\n\n const copy = useCallback(() => {\n const nodes = currentCanvas.nodes.filter(n => selection.nodeIds.has(n.id));\n const edges = currentCanvas.edges.filter(e => selection.edgeIds.has(e.id));\n const lines = currentCanvas.lines.filter(l => selection.lineIds.has(l.id));\n\n // Also include edges that connect selected nodes\n const nodeIds = new Set(nodes.map(n => n.id));\n const connectedEdges = currentCanvas.edges.filter(\n e => nodeIds.has(e.source) && nodeIds.has(e.target) && !selection.edgeIds.has(e.id),\n );\n\n clipboardRef.current = {\n nodes: [...nodes],\n edges: [...edges, ...connectedEdges],\n lines: [...lines],\n };\n }, [currentCanvas, selection]);\n\n const cut = useCallback(() => {\n copy();\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.filter(n => !selection.nodeIds.has(n.id))\n .map(n => n.parentId && selection.nodeIds.has(n.parentId) ? { ...n, parentId: undefined } : n),\n edges: canvas.edges.filter(e =>\n !selection.edgeIds.has(e.id) &&\n !selection.nodeIds.has(e.source) &&\n !selection.nodeIds.has(e.target),\n ),\n lines: canvas.lines.filter(l => !selection.lineIds.has(l.id))\n .map(l => l.parentId && selection.nodeIds.has(l.parentId) ? { ...l, parentId: undefined } : l),\n },\n },\n };\n });\n setSelection({ nodeIds: new Set(), edgeIds: new Set(), lineIds: new Set() });\n }, [copy, setDoc, currentCanvasId, selection, setSelection]);\n\n const paste = useCallback((offsetX = 20, offsetY = 20) => {\n const cb = clipboardRef.current;\n if (!cb) return;\n\n const idMap = new Map<string, string>();\n const newNodes: FlowNode[] = cb.nodes.map(n => {\n const newId = generateId('node');\n idMap.set(n.id, newId);\n return {\n ...n,\n id: newId,\n position: { x: n.position.x + offsetX, y: n.position.y + offsetY },\n data: { ...n.data },\n };\n });\n\n for (const n of newNodes) {\n if (n.parentId) n.parentId = idMap.get(n.parentId)\n ?? (currentCanvas.nodes.some(parent => parent.id === n.parentId) ? n.parentId : undefined);\n }\n\n const newEdges: FlowEdge[] = cb.edges\n .filter(e => idMap.has(e.source) && idMap.has(e.target))\n .map(e => ({\n ...e,\n id: generateId('edge'),\n source: idMap.get(e.source)!,\n target: idMap.get(e.target)!,\n data: { ...e.data },\n }));\n\n const newLines: FlowLine[] = cb.lines.map(l => ({\n ...l,\n id: generateId('line'),\n parentId: l.parentId ? idMap.get(l.parentId)\n ?? (currentCanvas.nodes.some(parent => parent.id === l.parentId) ? l.parentId : undefined) : undefined,\n points: l.points.map(p => ({ x: p.x + offsetX, y: p.y + offsetY })),\n }));\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: [...canvas.nodes, ...newNodes],\n edges: [...canvas.edges, ...newEdges],\n lines: [...canvas.lines, ...newLines],\n },\n },\n };\n });\n\n setSelection({\n nodeIds: new Set(newNodes.map(n => n.id)),\n edgeIds: new Set(newEdges.map(e => e.id)),\n lineIds: new Set(newLines.map(l => l.id)),\n });\n }, [setDoc, currentCanvasId, setSelection, currentCanvas]);\n\n const hasClipboard = clipboardRef.current !== null;\n\n /**\n * Duplicate the current selection in place (Cmd/Ctrl+D). Unlike copy+paste\n * this does NOT touch the clipboard, so a prior copy stays intact. Clones the\n * selected nodes (plus edges wholly between them) and lines with a small\n * offset, then selects the clones.\n */\n const duplicate = useCallback((\n offsetX = 24,\n offsetY = 24,\n targets?: { nodeIds?: Set<string>; edgeIds?: Set<string>; lineIds?: Set<string> },\n ) => {\n const nodeSel = targets ? targets.nodeIds ?? new Set<string>() : selection.nodeIds;\n const edgeSel = targets ? targets.edgeIds ?? new Set<string>() : selection.edgeIds;\n const lineSel = targets ? targets.lineIds ?? new Set<string>() : selection.lineIds;\n const nodes = currentCanvas.nodes.filter(n => nodeSel.has(n.id));\n const lines = currentCanvas.lines.filter(l => lineSel.has(l.id));\n const nodeIdSet = new Set(nodes.map(n => n.id));\n const edges = currentCanvas.edges.filter(e =>\n edgeSel.has(e.id) ||\n (nodeIdSet.has(e.source) && nodeIdSet.has(e.target)),\n );\n if (nodes.length === 0 && lines.length === 0 && edges.length === 0) return;\n\n const idMap = new Map<string, string>();\n // Assign fresh ids to nodes first so intra-selection edges can be remapped.\n const newNodes: FlowNode[] = nodes.map(n => {\n const newId = generateId('node');\n idMap.set(n.id, newId);\n return { ...n, id: newId, position: { x: n.position.x + offsetX, y: n.position.y + offsetY }, data: { ...n.data } };\n });\n // Re-parent cloned children onto cloned groups when both were duplicated.\n for (const n of newNodes) {\n if (n.parentId && idMap.has(n.parentId)) n.parentId = idMap.get(n.parentId);\n }\n\n const newEdges: FlowEdge[] = edges\n .filter(e => idMap.has(e.source) && idMap.has(e.target))\n .map(e => ({\n ...e,\n id: generateId('edge'),\n source: idMap.get(e.source)!,\n target: idMap.get(e.target)!,\n data: { ...e.data },\n }));\n\n const newLines: FlowLine[] = lines.map(l => ({\n ...l,\n id: generateId('line'),\n parentId: l.parentId ? idMap.get(l.parentId) ?? l.parentId : undefined,\n points: l.points.map(p => ({ x: p.x + offsetX, y: p.y + offsetY })),\n }));\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: [...canvas.nodes, ...newNodes],\n edges: [...canvas.edges, ...newEdges],\n lines: [...canvas.lines, ...newLines],\n },\n },\n };\n });\n\n setSelection({\n nodeIds: new Set(newNodes.map(n => n.id)),\n edgeIds: new Set(newEdges.map(e => e.id)),\n lineIds: new Set(newLines.map(l => l.id)),\n });\n }, [currentCanvas, selection, setDoc, currentCanvasId, setSelection]);\n\n return { copy, cut, paste, duplicate, hasClipboard };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useCompactMode.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useCompactMode.ts"],"sourcesContent":["import { useEffect, useState, type RefObject } from 'react';\n\n/**\n * Container-width based small-screen (\"compact\") detection.\n *\n * Uses a ResizeObserver on the Flow root element rather than\n * `window.matchMedia`, so the mode follows the space the component actually\n * gets: a phone (narrow container) switches to the compact layout, while the\n * same component embedded in a narrow column on a desktop page does too.\n *\n * In compact mode the Flow editor hides the left/right panel docks and instead\n * offers a single panel switcher at the top with full-screen panels.\n */\nexport function useCompactMode(ref: RefObject<HTMLElement | null>, breakpoint = 768): boolean {\n const [compact, setCompact] = useState(false);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n const update = () => {\n const w = el.clientWidth;\n if (w > 0) setCompact(w < breakpoint);\n };\n update();\n const ro = new ResizeObserver(update);\n ro.observe(el);\n return () => ro.disconnect();\n }, [ref, breakpoint]);\n\n return compact;\n}\n"],"mappings":";;AAaA,SAAgB,EAAe,GAAoC,IAAa,KAAc;CAC5F,IAAM,CAAC,GAAS,KAAc,EAAS,EAAK;CAe5C,OAbA,QAAgB;EACd,IAAM,IAAK,EAAI;EACf,IAAI,CAAC,GAAI;EACT,IAAM,UAAe;GACnB,IAAM,IAAI,EAAG;GACb,AAAI,IAAI,KAAG,EAAW,IAAI,CAAU;EACtC;EACA,EAAO;EACP,IAAM,IAAK,IAAI,eAAe,CAAM;EAEpC,OADA,EAAG,QAAQ,CAAE,SACA,EAAG,WAAW;CAC7B,GAAG,CAAC,GAAK,CAAU,CAAC,GAEb;AACT"}
1
+ {"version":3,"file":"useCompactMode.js","names":["useCompactMode","compact","setCompact","useState","useEffect","el","ref","update","w","breakpoint","ro"],"sources":["../../../../../src/components/pro/Flow/hooks/useCompactMode.ts"],"sourcesContent":["import { useEffect, useState, type RefObject } from 'react';\n\n/**\n * Container-width based small-screen (\"compact\") detection.\n *\n * Uses a ResizeObserver on the Flow root element rather than\n * `window.matchMedia`, so the mode follows the space the component actually\n * gets: a phone (narrow container) switches to the compact layout, while the\n * same component embedded in a narrow column on a desktop page does too.\n *\n * In compact mode the Flow editor hides the left/right panel docks and instead\n * offers a single panel switcher at the top with full-screen panels.\n */\nexport function useCompactMode(ref: RefObject<HTMLElement | null>, breakpoint = 768): boolean {\n const [compact, setCompact] = useState(false);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n const update = () => {\n const w = el.clientWidth;\n if (w > 0) setCompact(w < breakpoint);\n };\n update();\n const ro = new ResizeObserver(update);\n ro.observe(el);\n return () => ro.disconnect();\n }, [ref, breakpoint]);\n\n return compact;\n}\n"],"mappings":";;AAaA,SAAgBA,EAAe,GAAoC,IAAa,KAAc;CAC5F,IAAM,CAACC,GAASC,KAAcC,EAAS,EAAK;CAe5C,OAbAC,QAAgB;EACd,IAAMC,IAAKC,EAAI;EACf,IAAI,CAACD,GAAI;EACT,IAAME,UAAe;GACnB,IAAMC,IAAIH,EAAG;GACb,AAAIG,IAAI,KAAGN,EAAWM,IAAIC,CAAU;EACtC;EACA,EAAO;EACP,IAAMC,IAAK,IAAI,eAAeH,CAAM;EAEpC,OADAG,EAAG,QAAQL,CAAE,SACAK,EAAG,WAAW;CAC7B,GAAG,CAACJ,GAAKG,CAAU,CAAC,GAEbR;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"useDeleteSelection.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useDeleteSelection.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\n\n/**\n * Delete everything selected on the current canvas (nodes, edges, lines).\n *\n * Shared by the Delete/Backspace keyboard shortcut and the on-canvas delete\n * button, so touch devices (no keyboard) get exactly the same behavior,\n * including the multi-node confirmation prompt.\n */\nexport function useDeleteSelection() {\n const { selection, setSelection, setDoc, currentCanvasId } = useFlowContext();\n\n return useCallback(() => {\n const { nodeIds, edgeIds, lineIds } = selection;\n if (nodeIds.size === 0 && edgeIds.size === 0 && lineIds.size === 0) return;\n if (nodeIds.size > 1 && !window.confirm(`确定要删除选中的 ${nodeIds.size} 个节点吗?`)) return;\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes\n .filter(n => !nodeIds.has(n.id))\n .map(n => n.parentId && nodeIds.has(n.parentId) ? { ...n, parentId: undefined } : n),\n edges: canvas.edges.filter(e =>\n !edgeIds.has(e.id) && !nodeIds.has(e.source) && !nodeIds.has(e.target),\n ),\n lines: canvas.lines\n .filter(l => !lineIds.has(l.id))\n .map(l => l.parentId && nodeIds.has(l.parentId) ? { ...l, parentId: undefined } : l),\n },\n },\n };\n });\n setSelection({ nodeIds: new Set(), edgeIds: new Set(), lineIds: new Set() });\n }, [selection, setDoc, currentCanvasId, setSelection]);\n}\n"],"mappings":";;;AAUA,SAAgB,IAAqB;CACnC,IAAM,EAAE,cAAW,iBAAc,WAAQ,uBAAoB,EAAe;CAE5E,OAAO,QAAkB;EACvB,IAAM,EAAE,YAAS,YAAS,eAAY;EAClC,GAAQ,SAAS,KAAK,EAAQ,SAAS,KAAK,EAAQ,SAAS,OAC7D,EAAQ,OAAO,KAAK,CAAC,OAAO,QAAQ,YAAY,EAAQ,KAAK,OAAO,MACxE,GAAO,MAAQ;GACb,IAAM,IAAS,EAAK,SAAS;GAE7B,OADK,IACE;IACL,GAAG;IACH,UAAU;KACR,GAAG,EAAK;MACP,IAAkB;MACjB,GAAG;MACH,OAAO,EAAO,MACX,QAAO,MAAK,CAAC,EAAQ,IAAI,EAAE,EAAE,CAAC,CAAC,CAC/B,KAAI,MAAK,EAAE,YAAY,EAAQ,IAAI,EAAE,QAAQ,IAAI;OAAE,GAAG;OAAG,UAAU,KAAA;MAAU,IAAI,CAAC;MACrF,OAAO,EAAO,MAAM,QAAO,MACzB,CAAC,EAAQ,IAAI,EAAE,EAAE,KAAK,CAAC,EAAQ,IAAI,EAAE,MAAM,KAAK,CAAC,EAAQ,IAAI,EAAE,MAAM,CACvE;MACA,OAAO,EAAO,MACX,QAAO,MAAK,CAAC,EAAQ,IAAI,EAAE,EAAE,CAAC,CAAC,CAC/B,KAAI,MAAK,EAAE,YAAY,EAAQ,IAAI,EAAE,QAAQ,IAAI;OAAE,GAAG;OAAG,UAAU,KAAA;MAAU,IAAI,CAAC;KACvF;IACF;GACF,IAlBoB;EAmBtB,CAAC,GACD,EAAa;GAAE,yBAAS,IAAI,IAAI;GAAG,yBAAS,IAAI,IAAI;GAAG,yBAAS,IAAI,IAAI;EAAE,CAAC;CAC7E,GAAG;EAAC;EAAW;EAAQ;EAAiB;CAAY,CAAC;AACvD"}
1
+ {"version":3,"file":"useDeleteSelection.js","names":["useDeleteSelection","useFlowContext","useCallback","selection","nodeIds","edgeIds","lineIds","setDoc","canvas","prev","currentCanvasId","n","e","l","setSelection"],"sources":["../../../../../src/components/pro/Flow/hooks/useDeleteSelection.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\n\n/**\n * Delete everything selected on the current canvas (nodes, edges, lines).\n *\n * Shared by the Delete/Backspace keyboard shortcut and the on-canvas delete\n * button, so touch devices (no keyboard) get exactly the same behavior,\n * including the multi-node confirmation prompt.\n */\nexport function useDeleteSelection() {\n const { selection, setSelection, setDoc, currentCanvasId } = useFlowContext();\n\n return useCallback(() => {\n const { nodeIds, edgeIds, lineIds } = selection;\n if (nodeIds.size === 0 && edgeIds.size === 0 && lineIds.size === 0) return;\n if (nodeIds.size > 1 && !window.confirm(`确定要删除选中的 ${nodeIds.size} 个节点吗?`)) return;\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes\n .filter(n => !nodeIds.has(n.id))\n .map(n => n.parentId && nodeIds.has(n.parentId) ? { ...n, parentId: undefined } : n),\n edges: canvas.edges.filter(e =>\n !edgeIds.has(e.id) && !nodeIds.has(e.source) && !nodeIds.has(e.target),\n ),\n lines: canvas.lines\n .filter(l => !lineIds.has(l.id))\n .map(l => l.parentId && nodeIds.has(l.parentId) ? { ...l, parentId: undefined } : l),\n },\n },\n };\n });\n setSelection({ nodeIds: new Set(), edgeIds: new Set(), lineIds: new Set() });\n }, [selection, setDoc, currentCanvasId, setSelection]);\n}\n"],"mappings":";;;AAUA,SAAgBA,IAAqB;CACnC,IAAM,EAAE,cAAW,iBAAc,WAAQ,uBAAoBC,EAAe;CAE5E,OAAOC,QAAkB;EACvB,IAAM,EAAE,YAAS,YAAS,eAAYC;EACtC,CAAIC,EAAQ,SAAS,KAAKC,EAAQ,SAAS,KAAKC,EAAQ,SAAS,OAC7DF,EAAQ,OAAO,KAAK,CAAC,OAAO,QAAQ,YAAYA,EAAQ,KAAK,OAAO,MACxEG,GAAO,MAAQ;GACb,IAAMC,IAASC,EAAK,SAASC;GAE7B,OADKF,IACE;IACL,GAAGC;IACH,UAAU;KACR,GAAGA,EAAK;MACPC,IAAkB;MACjB,GAAGF;MACH,OAAOA,EAAO,MACX,QAAO,MAAK,CAACJ,EAAQ,IAAIO,EAAE,EAAE,CAAC,CAAC,CAC/B,KAAI,MAAKA,EAAE,YAAYP,EAAQ,IAAIO,EAAE,QAAQ,IAAI;OAAE,GAAGA;OAAG,UAAU,KAAA;MAAU,IAAIA,CAAC;MACrF,OAAOH,EAAO,MAAM,QAAO,MACzB,CAACH,EAAQ,IAAIO,EAAE,EAAE,KAAK,CAACR,EAAQ,IAAIQ,EAAE,MAAM,KAAK,CAACR,EAAQ,IAAIQ,EAAE,MAAM,CACvE;MACA,OAAOJ,EAAO,MACX,QAAO,MAAK,CAACF,EAAQ,IAAIO,EAAE,EAAE,CAAC,CAAC,CAC/B,KAAI,MAAKA,EAAE,YAAYT,EAAQ,IAAIS,EAAE,QAAQ,IAAI;OAAE,GAAGA;OAAG,UAAU,KAAA;MAAU,IAAIA,CAAC;KACvF;IACF;GACF,IAlBoBJ;EAmBtB,CAAC,GACDK,EAAa;GAAE,yBAAS,IAAI,IAAI;GAAG,yBAAS,IAAI,IAAI;GAAG,yBAAS,IAAI,IAAI;EAAE,CAAC;CAC7E,GAAG;EAACX;EAAWI;EAAQG;EAAiBI;CAAY,CAAC;AACvD"}
@@ -1 +1 @@
1
- {"version":3,"file":"useDraggablePanel.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useDraggablePanel.ts"],"sourcesContent":["import { useState, useRef, useCallback, type PointerEvent as ReactPointerEvent } from 'react';\n\nexport interface PanelPosition {\n x: number;\n y: number;\n}\n\nexport type PanelDropSide = 'left' | 'right';\n\nexport interface DraggablePanelOptions {\n /** Called on pointer-up when the floating panel was dropped over a dock edge. */\n onDropDock?: (side: PanelDropSide) => void;\n /** Notified while dragging so the workspace can highlight the hovered dock. */\n onDragHintChange?: (side: PanelDropSide | null) => void;\n /** Width (px) of the drop zone along each edge of the workspace. */\n edgeZone?: number;\n}\n\ninterface DragState {\n startX: number;\n startY: number;\n originX: number;\n originY: number;\n width: number;\n parentWidth: number;\n}\n\n/**\n * Enables free-position dragging for overlay panels. Returns a position\n * override (null = use default CSS) and a set of props to spread onto the\n * panel's drag handle element.\n *\n * When `onDropDock` is provided, dropping the panel within `edgeZone` of the\n * workspace's left/right edge attaches it to that dock: the hovered edge is\n * reported via `onDragHintChange` during the drag (so the workspace can\n * highlight a drop zone) and the position resets on drop so the panel snaps\n * into its dock slot.\n */\nexport function useDraggablePanel({ onDropDock, onDragHintChange, edgeZone = 72 }: DraggablePanelOptions = {}) {\n const [pos, setPos] = useState<PanelPosition | null>(null);\n const dragState = useRef<DragState | null>(null);\n const hintRef = useRef<PanelDropSide | null>(null);\n\n const clearHint = useCallback(() => {\n if (hintRef.current) {\n hintRef.current = null;\n onDragHintChange?.(null);\n }\n }, [onDragHintChange]);\n\n const onPointerDown = useCallback((e: ReactPointerEvent<HTMLElement>) => {\n const el = (e.currentTarget as HTMLElement).closest('[data-flow-panel]') as HTMLElement | null;\n if (!el) return;\n e.preventDefault();\n e.stopPropagation();\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n const rect = el.getBoundingClientRect();\n const parentRect = el.offsetParent?.getBoundingClientRect() ?? { left: 0, top: 0 };\n dragState.current = {\n startX: e.clientX,\n startY: e.clientY,\n originX: rect.left - parentRect.left,\n originY: rect.top - parentRect.top,\n width: rect.width,\n parentWidth: el.offsetParent?.clientWidth ?? rect.left - parentRect.left + rect.width,\n };\n }, []);\n\n const onPointerMove = useCallback((e: ReactPointerEvent<HTMLElement>) => {\n if (!dragState.current) return;\n const dx = e.clientX - dragState.current.startX;\n const dy = e.clientY - dragState.current.startY;\n const x = dragState.current.originX + dx;\n setPos({ x, y: dragState.current.originY + dy });\n // Dock affinity: the panel's center hovering a workspace edge highlights\n // that dock as the drop target.\n const centerX = x + dragState.current.width / 2;\n const next: PanelDropSide | null =\n centerX < edgeZone ? 'left'\n : centerX > dragState.current.parentWidth - edgeZone ? 'right'\n : null;\n if (next !== hintRef.current) {\n hintRef.current = next;\n onDragHintChange?.(next);\n }\n }, [edgeZone, onDragHintChange]);\n\n const onPointerUp = useCallback(() => {\n const hint = hintRef.current;\n clearHint();\n dragState.current = null;\n if (hint) {\n onDropDock?.(hint);\n setPos(null); // snap back into the dock slot\n }\n }, [clearHint, onDropDock]);\n\n const style: React.CSSProperties | undefined = pos\n ? { position: 'absolute', left: pos.x, top: pos.y, right: 'auto', bottom: 'auto' }\n : undefined;\n\n return {\n panelStyle: style,\n handleProps: { onPointerDown, onPointerMove, onPointerUp },\n resetPosition: () => setPos(null),\n };\n}\n"],"mappings":";;AAsCA,SAAgB,EAAkB,EAAE,eAAY,qBAAkB,cAAW,OAA8B,CAAC,GAAG;CAC7G,IAAM,CAAC,GAAK,KAAU,EAA+B,IAAI,GACnD,IAAY,EAAyB,IAAI,GACzC,IAAU,EAA6B,IAAI,GAE3C,IAAY,QAAkB;EAClC,AAAI,EAAQ,YACV,EAAQ,UAAU,MAClB,IAAmB,IAAI;CAE3B,GAAG,CAAC,CAAgB,CAAC,GAEf,IAAgB,GAAa,MAAsC;EACvE,IAAM,IAAM,EAAE,cAA8B,QAAQ,mBAAmB;EACvE,IAAI,CAAC,GAAI;EAGT,AAFA,EAAE,eAAe,GACjB,EAAE,gBAAgB,GAClB,EAAG,OAAuB,kBAAkB,EAAE,SAAS;EACvD,IAAM,IAAO,EAAG,sBAAsB,GAChC,IAAa,EAAG,cAAc,sBAAsB,KAAK;GAAE,MAAM;GAAG,KAAK;EAAE;EACjF,EAAU,UAAU;GAClB,QAAQ,EAAE;GACV,QAAQ,EAAE;GACV,SAAS,EAAK,OAAO,EAAW;GAChC,SAAS,EAAK,MAAM,EAAW;GAC/B,OAAO,EAAK;GACZ,aAAa,EAAG,cAAc,eAAe,EAAK,OAAO,EAAW,OAAO,EAAK;EAClF;CACF,GAAG,CAAC,CAAC,GAEC,IAAgB,GAAa,MAAsC;EACvE,IAAI,CAAC,EAAU,SAAS;EACxB,IAAM,IAAK,EAAE,UAAU,EAAU,QAAQ,QACnC,IAAK,EAAE,UAAU,EAAU,QAAQ,QACnC,IAAI,EAAU,QAAQ,UAAU;EACtC,EAAO;GAAE;GAAG,GAAG,EAAU,QAAQ,UAAU;EAAG,CAAC;EAG/C,IAAM,IAAU,IAAI,EAAU,QAAQ,QAAQ,GACxC,IACJ,IAAU,IAAW,SACnB,IAAU,EAAU,QAAQ,cAAc,IAAW,UACrD;EACJ,AAAI,MAAS,EAAQ,YACnB,EAAQ,UAAU,GAClB,IAAmB,CAAI;CAE3B,GAAG,CAAC,GAAU,CAAgB,CAAC,GAEzB,IAAc,QAAkB;EACpC,IAAM,IAAO,EAAQ;EAGrB,AAFA,EAAU,GACV,EAAU,UAAU,MAChB,MACF,IAAa,CAAI,GACjB,EAAO,IAAI;CAEf,GAAG,CAAC,GAAW,CAAU,CAAC;CAM1B,OAAO;EACL,YAL6C,IAC3C;GAAE,UAAU;GAAY,MAAM,EAAI;GAAG,KAAK,EAAI;GAAG,OAAO;GAAQ,QAAQ;EAAO,IAC/E,KAAA;EAIF,aAAa;GAAE;GAAe;GAAe;EAAY;EACzD,qBAAqB,EAAO,IAAI;CAClC;AACF"}
1
+ {"version":3,"file":"useDraggablePanel.js","names":["useDraggablePanel","pos","setPos","useState","dragState","useRef","hintRef","clearHint","useCallback","onDragHintChange","onPointerDown","el","rect","parentRect","onPointerMove","dx","dy","x","centerX","next","edgeZone","onPointerUp","hint","onDropDock"],"sources":["../../../../../src/components/pro/Flow/hooks/useDraggablePanel.ts"],"sourcesContent":["import { useState, useRef, useCallback, type PointerEvent as ReactPointerEvent } from 'react';\n\nexport interface PanelPosition {\n x: number;\n y: number;\n}\n\nexport type PanelDropSide = 'left' | 'right';\n\nexport interface DraggablePanelOptions {\n /** Called on pointer-up when the floating panel was dropped over a dock edge. */\n onDropDock?: (side: PanelDropSide) => void;\n /** Notified while dragging so the workspace can highlight the hovered dock. */\n onDragHintChange?: (side: PanelDropSide | null) => void;\n /** Width (px) of the drop zone along each edge of the workspace. */\n edgeZone?: number;\n}\n\ninterface DragState {\n startX: number;\n startY: number;\n originX: number;\n originY: number;\n width: number;\n parentWidth: number;\n}\n\n/**\n * Enables free-position dragging for overlay panels. Returns a position\n * override (null = use default CSS) and a set of props to spread onto the\n * panel's drag handle element.\n *\n * When `onDropDock` is provided, dropping the panel within `edgeZone` of the\n * workspace's left/right edge attaches it to that dock: the hovered edge is\n * reported via `onDragHintChange` during the drag (so the workspace can\n * highlight a drop zone) and the position resets on drop so the panel snaps\n * into its dock slot.\n */\nexport function useDraggablePanel({ onDropDock, onDragHintChange, edgeZone = 72 }: DraggablePanelOptions = {}) {\n const [pos, setPos] = useState<PanelPosition | null>(null);\n const dragState = useRef<DragState | null>(null);\n const hintRef = useRef<PanelDropSide | null>(null);\n\n const clearHint = useCallback(() => {\n if (hintRef.current) {\n hintRef.current = null;\n onDragHintChange?.(null);\n }\n }, [onDragHintChange]);\n\n const onPointerDown = useCallback((e: ReactPointerEvent<HTMLElement>) => {\n const el = (e.currentTarget as HTMLElement).closest('[data-flow-panel]') as HTMLElement | null;\n if (!el) return;\n e.preventDefault();\n e.stopPropagation();\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n const rect = el.getBoundingClientRect();\n const parentRect = el.offsetParent?.getBoundingClientRect() ?? { left: 0, top: 0 };\n dragState.current = {\n startX: e.clientX,\n startY: e.clientY,\n originX: rect.left - parentRect.left,\n originY: rect.top - parentRect.top,\n width: rect.width,\n parentWidth: el.offsetParent?.clientWidth ?? rect.left - parentRect.left + rect.width,\n };\n }, []);\n\n const onPointerMove = useCallback((e: ReactPointerEvent<HTMLElement>) => {\n if (!dragState.current) return;\n const dx = e.clientX - dragState.current.startX;\n const dy = e.clientY - dragState.current.startY;\n const x = dragState.current.originX + dx;\n setPos({ x, y: dragState.current.originY + dy });\n // Dock affinity: the panel's center hovering a workspace edge highlights\n // that dock as the drop target.\n const centerX = x + dragState.current.width / 2;\n const next: PanelDropSide | null =\n centerX < edgeZone ? 'left'\n : centerX > dragState.current.parentWidth - edgeZone ? 'right'\n : null;\n if (next !== hintRef.current) {\n hintRef.current = next;\n onDragHintChange?.(next);\n }\n }, [edgeZone, onDragHintChange]);\n\n const onPointerUp = useCallback(() => {\n const hint = hintRef.current;\n clearHint();\n dragState.current = null;\n if (hint) {\n onDropDock?.(hint);\n setPos(null); // snap back into the dock slot\n }\n }, [clearHint, onDropDock]);\n\n const style: React.CSSProperties | undefined = pos\n ? { position: 'absolute', left: pos.x, top: pos.y, right: 'auto', bottom: 'auto' }\n : undefined;\n\n return {\n panelStyle: style,\n handleProps: { onPointerDown, onPointerMove, onPointerUp },\n resetPosition: () => setPos(null),\n };\n}\n"],"mappings":";;AAsCA,SAAgBA,EAAkB,EAAE,eAAY,qBAAkB,cAAW,OAA8B,CAAC,GAAG;CAC7G,IAAM,CAACC,GAAKC,KAAUC,EAA+B,IAAI,GACnDC,IAAYC,EAAyB,IAAI,GACzCC,IAAUD,EAA6B,IAAI,GAE3CE,IAAYC,QAAkB;EAClC,AAAIF,EAAQ,YACV,EAAQ,UAAU,MAClBG,IAAmB,IAAI;CAE3B,GAAG,CAACA,CAAgB,CAAC,GAEfC,IAAgBF,GAAa,MAAsC;EACvE,IAAMG,IAAM,EAAE,cAA8B,QAAQ,mBAAmB;EACvE,IAAI,CAACA,GAAI;EAGT,AAFA,EAAE,eAAe,GACjB,EAAE,gBAAgB,GAClB,EAAG,OAAuB,kBAAkB,EAAE,SAAS;EACvD,IAAMC,IAAOD,EAAG,sBAAsB,GAChCE,IAAaF,EAAG,cAAc,sBAAsB,KAAK;GAAE,MAAM;GAAG,KAAK;EAAE;EACjF,EAAU,UAAU;GAClB,QAAQ,EAAE;GACV,QAAQ,EAAE;GACV,SAASC,EAAK,OAAOC,EAAW;GAChC,SAASD,EAAK,MAAMC,EAAW;GAC/B,OAAOD,EAAK;GACZ,aAAaD,EAAG,cAAc,eAAeC,EAAK,OAAOC,EAAW,OAAOD,EAAK;EAClF;CACF,GAAG,CAAC,CAAC,GAECE,IAAgBN,GAAa,MAAsC;EACvE,IAAI,CAACJ,EAAU,SAAS;EACxB,IAAMW,IAAK,EAAE,UAAUX,EAAU,QAAQ,QACnCY,IAAK,EAAE,UAAUZ,EAAU,QAAQ,QACnCa,IAAIb,EAAU,QAAQ,UAAUW;EACtC,EAAO;GAAE;GAAG,GAAGX,EAAU,QAAQ,UAAUY;EAAG,CAAC;EAG/C,IAAME,IAAUD,IAAIb,EAAU,QAAQ,QAAQ,GACxCe,IACJD,IAAUE,IAAW,SACnBF,IAAUd,EAAU,QAAQ,cAAcgB,IAAW,UACrD;EACJ,AAAID,MAASb,EAAQ,YACnB,EAAQ,UAAUa,GAClBV,IAAmBU,CAAI;CAE3B,GAAG,CAACC,GAAUX,CAAgB,CAAC,GAEzBY,IAAcb,QAAkB;EACpC,IAAMc,IAAOhB,EAAQ;EAGrB,AAFAC,EAAU,GACV,EAAU,UAAU,MAChBe,MACFC,IAAaD,CAAI,GACjBpB,EAAO,IAAI;CAEf,GAAG,CAACK,GAAWgB,CAAU,CAAC;CAM1B,OAAO;EACL,YAL6CtB,IAC3C;GAAE,UAAU;GAAY,MAAMA,EAAI;GAAG,KAAKA,EAAI;GAAG,OAAO;GAAQ,QAAQ;EAAO,IAC/E,KAAA;EAIF,aAAa;GAAE;GAAe;GAAe;EAAY;EACzD,qBAAqBC,EAAO,IAAI;CAClC;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"useEdgeMutations.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useEdgeMutations.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport type { FlowEdge, FlowEdgeData, FlowEdgeTypeName, FlowBezierControl } from '../types';\nimport { DEFAULT_EDGE_DATA } from '../constants';\nimport { generateId } from '../nodes/nodeUtils';\n\nexport function useEdgeMutations() {\n const { setDoc, currentCanvasId } = useFlowContext();\n\n const addEdge = useCallback(\n (\n source: string,\n target: string,\n type: FlowEdgeTypeName = 'smoothstep',\n data?: Partial<FlowEdgeData>,\n sourceHandle?: string,\n targetHandle?: string,\n ): string => {\n const id = generateId('edge');\n const edge: FlowEdge = {\n id,\n source,\n target,\n sourceHandle,\n targetHandle,\n type,\n data: { ...DEFAULT_EDGE_DATA, ...data },\n };\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n // Prevent duplicates\n const exists = canvas.edges.some(e => e.source === source && e.target === target);\n if (exists) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: { ...canvas, edges: [...canvas.edges, edge] },\n },\n };\n });\n return id;\n },\n [setDoc, currentCanvasId],\n );\n\n const updateEdge = useCallback(\n (id: string, updates: Partial<Pick<FlowEdge, 'type'>> & { data?: Partial<FlowEdgeData> }) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e => {\n if (e.id !== id) return e;\n return {\n ...e,\n ...(updates.type !== undefined ? { type: updates.type } : {}),\n data: updates.data ? { ...e.data, ...updates.data } : e.data,\n };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const updateWaypoint = useCallback(\n (edgeId: string, waypointIndex: number, x: number, y: number) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e => {\n if (e.id !== edgeId || !e.data.waypoints) return e;\n const wps = [...e.data.waypoints];\n wps[waypointIndex] = { x, y };\n return { ...e, data: { ...e.data, waypoints: wps } };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const addWaypoint = useCallback(\n (edgeId: string, x: number, y: number, insertIndex?: number) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e => {\n if (e.id !== edgeId) return e;\n const wps = [...(e.data.waypoints ?? [])];\n const idx = insertIndex ?? wps.length;\n wps.splice(idx, 0, { x, y });\n return { ...e, data: { ...e.data, waypoints: wps } };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const updateBezierControl = useCallback(\n (edgeId: string, segIndex: number, control: FlowBezierControl) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e => {\n if (e.id !== edgeId) return e;\n const ctrls = [...(e.data.bezierControls ?? [])];\n while (ctrls.length <= segIndex) ctrls.push(null);\n ctrls[segIndex] = control;\n return { ...e, data: { ...e.data, bezierControls: ctrls } };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const deleteEdges = useCallback(\n (ids: Set<string>) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.filter(e => !ids.has(e.id)),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n return { addEdge, updateEdge, updateWaypoint, addWaypoint, updateBezierControl, deleteEdges };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useEdgeMutations.js","names":["useEdgeMutations","useFlowContext","useCallback","id","generateId","edge","DEFAULT_EDGE_DATA","data","setDoc","canvas","prev","currentCanvasId","source","target","e","updates","edgeId","wps","waypointIndex","idx","insertIndex","ctrls","segIndex","control","ids"],"sources":["../../../../../src/components/pro/Flow/hooks/useEdgeMutations.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport type { FlowEdge, FlowEdgeData, FlowEdgeTypeName, FlowBezierControl } from '../types';\nimport { DEFAULT_EDGE_DATA } from '../constants';\nimport { generateId } from '../nodes/nodeUtils';\n\nexport function useEdgeMutations() {\n const { setDoc, currentCanvasId } = useFlowContext();\n\n const addEdge = useCallback(\n (\n source: string,\n target: string,\n type: FlowEdgeTypeName = 'smoothstep',\n data?: Partial<FlowEdgeData>,\n sourceHandle?: string,\n targetHandle?: string,\n ): string => {\n const id = generateId('edge');\n const edge: FlowEdge = {\n id,\n source,\n target,\n sourceHandle,\n targetHandle,\n type,\n data: { ...DEFAULT_EDGE_DATA, ...data },\n };\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n // Prevent duplicates\n const exists = canvas.edges.some(e => e.source === source && e.target === target);\n if (exists) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: { ...canvas, edges: [...canvas.edges, edge] },\n },\n };\n });\n return id;\n },\n [setDoc, currentCanvasId],\n );\n\n const updateEdge = useCallback(\n (id: string, updates: Partial<Pick<FlowEdge, 'type'>> & { data?: Partial<FlowEdgeData> }) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e => {\n if (e.id !== id) return e;\n return {\n ...e,\n ...(updates.type !== undefined ? { type: updates.type } : {}),\n data: updates.data ? { ...e.data, ...updates.data } : e.data,\n };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const updateWaypoint = useCallback(\n (edgeId: string, waypointIndex: number, x: number, y: number) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e => {\n if (e.id !== edgeId || !e.data.waypoints) return e;\n const wps = [...e.data.waypoints];\n wps[waypointIndex] = { x, y };\n return { ...e, data: { ...e.data, waypoints: wps } };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const addWaypoint = useCallback(\n (edgeId: string, x: number, y: number, insertIndex?: number) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e => {\n if (e.id !== edgeId) return e;\n const wps = [...(e.data.waypoints ?? [])];\n const idx = insertIndex ?? wps.length;\n wps.splice(idx, 0, { x, y });\n return { ...e, data: { ...e.data, waypoints: wps } };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const updateBezierControl = useCallback(\n (edgeId: string, segIndex: number, control: FlowBezierControl) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e => {\n if (e.id !== edgeId) return e;\n const ctrls = [...(e.data.bezierControls ?? [])];\n while (ctrls.length <= segIndex) ctrls.push(null);\n ctrls[segIndex] = control;\n return { ...e, data: { ...e.data, bezierControls: ctrls } };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const deleteEdges = useCallback(\n (ids: Set<string>) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.filter(e => !ids.has(e.id)),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n return { addEdge, updateEdge, updateWaypoint, addWaypoint, updateBezierControl, deleteEdges };\n}\n"],"mappings":"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"}