dishui 0.0.97 → 0.0.104
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.
- package/dist/.release-verified.json +2 -2
- package/dist/ai.js +17 -15
- package/dist/components/Card/Ticket.d.ts +52 -0
- package/dist/components/Card/Ticket2.js +218 -0
- package/dist/components/Card/Ticket2.js.map +1 -0
- package/dist/components/Card/index.d.ts +12 -0
- package/dist/components/Card/index.js +142 -139
- package/dist/components/Card/index.js.map +1 -1
- package/dist/components/ai/AgentRunCard/index.d.ts +38 -0
- package/dist/components/ai/AgentRunCard/index.js +100 -0
- package/dist/components/ai/AgentRunCard/index.js.map +1 -0
- package/dist/components/ai/IssueCard/index.d.ts +39 -0
- package/dist/components/ai/IssueCard/index.js +78 -0
- package/dist/components/ai/IssueCard/index.js.map +1 -0
- package/dist/components/ai/index.d.ts +4 -0
- package/dist/components/pro/Flow/constants.js +3 -3
- package/dist/components/pro/Flow/constants.js.map +1 -1
- package/dist/components/pro/Flow/context/FlowAIContext.d.ts +2 -0
- package/dist/components/pro/Flow/context/FlowAIContext.js +9 -4
- package/dist/components/pro/Flow/context/FlowAIContext.js.map +1 -1
- package/dist/components/pro/Flow/nodes/MediaContent.d.ts +3 -2
- package/dist/components/pro/Flow/nodes/MediaContent.js +16 -16
- package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
- package/dist/components/pro/Flow/nodes/MediaOverlay.js +25 -23
- package/dist/components/pro/Flow/nodes/MediaOverlay.js.map +1 -1
- package/dist/components/pro/Flow/nodes/shapes.js +3 -3
- package/dist/components/pro/Flow/nodes/shapes.js.map +1 -1
- package/dist/components/pro/Flow/panels/InspectorPanel.js +396 -384
- package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
- package/dist/components/pro/Flow/utils/themeColor.d.ts +2 -2
- package/dist/components/pro/Flow/utils/themeColor.js +2 -2
- package/dist/components/pro/Flow/utils/themeColor.js.map +1 -1
- package/dist/components/pro/Kanban/Kanban.d.ts +3 -0
- package/dist/components/pro/Kanban/Kanban.js +339 -0
- package/dist/components/pro/Kanban/Kanban.js.map +1 -0
- package/dist/components/pro/Kanban/Swimlanes.d.ts +3 -0
- package/dist/components/pro/Kanban/Swimlanes.js +60 -0
- package/dist/components/pro/Kanban/Swimlanes.js.map +1 -0
- package/dist/components/pro/Kanban/index.d.ts +5 -0
- package/dist/components/pro/Kanban/types.d.ts +103 -0
- package/dist/components/pro/Kanban/useKanbanDrag.d.ts +17 -0
- package/dist/components/pro/Kanban/useKanbanDrag.js +69 -0
- package/dist/components/pro/Kanban/useKanbanDrag.js.map +1 -0
- package/dist/components/pro/Kanban/utils.d.ts +13 -0
- package/dist/components/pro/Kanban/utils.js +48 -0
- package/dist/components/pro/Kanban/utils.js.map +1 -0
- package/dist/components/pro/RichTextEditor/AIRewrite.js +158 -127
- package/dist/components/pro/RichTextEditor/AIRewrite.js.map +1 -1
- package/dist/components/pro/RichTextEditor/BlockHandle.d.ts +2 -0
- package/dist/components/pro/RichTextEditor/BlockHandle.js +156 -115
- package/dist/components/pro/RichTextEditor/BlockHandle.js.map +1 -1
- package/dist/components/pro/RichTextEditor/RichTextEditor.js +136 -159
- package/dist/components/pro/RichTextEditor/RichTextEditor.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js +44 -41
- package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js +59 -53
- package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js +48 -44
- package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js +67 -63
- package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.d.ts +1 -0
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js +182 -129
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.d.ts +1 -0
- package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.js +3 -3
- package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.d.ts +3 -0
- package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.js +31 -0
- package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.js.map +1 -0
- package/dist/components/pro/RichTextEditor/index.d.ts +1 -1
- package/dist/components/pro/RichTextEditor/types.d.ts +78 -11
- package/dist/components/pro/RichTextEditor/types.js +11 -0
- package/dist/components/pro/RichTextEditor/types.js.map +1 -1
- package/dist/dishui.css +1 -1
- package/dist/index-nostyled.d.ts +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +128 -122
- package/dist/kanban.js +5 -0
- package/dist/utils/i18n.js +20 -0
- package/dist/utils/i18n.js.map +1 -1
- package/dist/utils/menu.js +1 -1
- package/dist/utils/menu.js.map +1 -1
- package/package.json +5 -1
|
@@ -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}\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 value = useMemo<FlowAIContextValue>(\n () => ({ aiConfig, setAIConfig, showAIConfig }),\n [aiConfig, showAIConfig],\n );\n return <FlowAIContext.Provider value={value}>{children}</FlowAIContext.Provider>;\n}\n"],"mappings":";;;
|
|
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,7 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { FlowNode } from '../types';
|
|
2
|
+
import type { FlowNode, FlowAIConfig } from '../types';
|
|
3
3
|
/** Dispatches to the correct renderer for the node's media kind. */
|
|
4
|
-
export declare function MediaContent({ node, interactive }: {
|
|
4
|
+
export declare function MediaContent({ node, interactive, aiConfig }: {
|
|
5
5
|
node: FlowNode;
|
|
6
6
|
interactive: boolean;
|
|
7
|
+
aiConfig?: FlowAIConfig;
|
|
7
8
|
}): React.JSX.Element | null;
|
|
@@ -153,7 +153,7 @@ function x({ node: t, config: n, interactive: i, color: a }) {
|
|
|
153
153
|
children: [
|
|
154
154
|
s.length === 0 && /* @__PURE__ */ u("div", {
|
|
155
155
|
className: "flow-media-ai-empty",
|
|
156
|
-
children: n?.gateway ? "开始对话…" : "
|
|
156
|
+
children: n?.gateway ? "开始对话…" : "请先配置 AI 接口"
|
|
157
157
|
}),
|
|
158
158
|
s.map((t, n) => /* @__PURE__ */ u("div", {
|
|
159
159
|
className: `flow-media-ai-msg flow-media-ai-msg--${t.role}`,
|
|
@@ -194,43 +194,43 @@ function x({ node: t, config: n, interactive: i, color: a }) {
|
|
|
194
194
|
]
|
|
195
195
|
});
|
|
196
196
|
}
|
|
197
|
-
function S({ node: r, interactive: a }) {
|
|
198
|
-
let
|
|
199
|
-
switch (
|
|
197
|
+
function S({ node: r, interactive: a, aiConfig: o }) {
|
|
198
|
+
let s = r.data.mediaKind ?? "markdown", c = r.data.mediaContent ?? "", l = n(r.data.labelColor ?? r.data.color, "#111827");
|
|
199
|
+
switch (s) {
|
|
200
200
|
case "markdown": return /* @__PURE__ */ u("div", {
|
|
201
201
|
className: "flow-media-markdown",
|
|
202
202
|
style: {
|
|
203
|
-
color:
|
|
203
|
+
color: l,
|
|
204
204
|
fontSize: r.data.fontSize
|
|
205
205
|
},
|
|
206
|
-
children: /* @__PURE__ */ u(e, { content:
|
|
206
|
+
children: /* @__PURE__ */ u(e, { content: c })
|
|
207
207
|
});
|
|
208
208
|
case "html": return /* @__PURE__ */ u(y, {
|
|
209
|
-
content:
|
|
209
|
+
content: c,
|
|
210
210
|
interactive: a,
|
|
211
211
|
color: t(r.data.labelColor ?? r.data.color, "#111827"),
|
|
212
212
|
fontSize: r.data.fontSize
|
|
213
213
|
});
|
|
214
214
|
case "mermaid": return /* @__PURE__ */ u(_, {
|
|
215
|
-
content:
|
|
216
|
-
color:
|
|
215
|
+
content: c,
|
|
216
|
+
color: l
|
|
217
217
|
});
|
|
218
218
|
case "math": return /* @__PURE__ */ u(v, {
|
|
219
|
-
content:
|
|
220
|
-
color:
|
|
219
|
+
content: c,
|
|
220
|
+
color: l,
|
|
221
221
|
fontSize: r.data.fontSize
|
|
222
222
|
});
|
|
223
|
-
case "image": return /* @__PURE__ */ u(b, { content:
|
|
223
|
+
case "image": return /* @__PURE__ */ u(b, { content: c });
|
|
224
224
|
case "model3d": return /* @__PURE__ */ u(i, {
|
|
225
|
-
content:
|
|
225
|
+
content: c,
|
|
226
226
|
format: r.data.modelFormat ?? "stl",
|
|
227
227
|
interactive: a
|
|
228
228
|
});
|
|
229
229
|
case "ai": return /* @__PURE__ */ u(x, {
|
|
230
230
|
node: r,
|
|
231
|
-
config: r.data.aiConfig,
|
|
231
|
+
config: o ?? r.data.aiConfig,
|
|
232
232
|
interactive: a,
|
|
233
|
-
color:
|
|
233
|
+
color: l
|
|
234
234
|
});
|
|
235
235
|
case "data": return /* @__PURE__ */ u("div", {
|
|
236
236
|
className: "flow-media-data",
|
|
@@ -242,7 +242,7 @@ function S({ node: r, interactive: a }) {
|
|
|
242
242
|
view: "table"
|
|
243
243
|
},
|
|
244
244
|
surfaceColor: r.data.fill === "transparent" ? void 0 : n(r.data.fill, ""),
|
|
245
|
-
textColor:
|
|
245
|
+
textColor: l,
|
|
246
246
|
primaryColor: n(r.data.color, "")
|
|
247
247
|
})
|
|
248
248
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MediaContent.js","names":[],"sources":["../../../../../src/components/pro/Flow/nodes/MediaContent.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport katex from 'katex';\nimport mermaid from 'mermaid';\nimport Markdown from '../../../Markdown';\nimport type { FlowNode, FlowAIConfig } from '../types';\nimport { streamAIChat, type AIChatMessage } from './aiClient';\nimport { resolveThemeColorCss, resolveThemeColor } from '../utils/themeColor';\nimport 'katex/dist/katex.min.css';\nimport { Model3DView } from './Model3DView';\n\n// Data-node view pulls in DataTable + Chart; lazy-load so it only enters the\n// bundle when a data node actually renders.\nconst DataNodeView = React.lazy(() =>\n import('./DataNodeView').then((m) => ({ default: m.DataNodeView })),\n);\n\nlet mermaidReady = false;\nfunction ensureMermaid() {\n if (mermaidReady) return;\n mermaid.initialize({ startOnLoad: false, theme: 'default', securityLevel: 'loose', fontFamily: 'inherit' });\n mermaidReady = true;\n}\n\n/** Renders a Mermaid diagram from source into an inline SVG. */\nfunction MermaidView({ content, color }: { content: string; color?: string }) {\n const [svg, setSvg] = useState('');\n const [error, setError] = useState<string | null>(null);\n const idRef = useRef(`flow-mermaid-${Math.random().toString(36).slice(2)}`);\n\n useEffect(() => {\n let cancelled = false;\n ensureMermaid();\n const src = content.trim();\n if (!src) { setSvg(''); setError(null); return; }\n mermaid\n .render(idRef.current, src)\n .then(({ svg }) => { if (!cancelled) { setSvg(svg); setError(null); } })\n .catch((e) => { if (!cancelled) setError(e?.message ?? 'Mermaid error'); });\n return () => { cancelled = true; };\n }, [content]);\n\n if (error) return <div className=\"flow-media-error\">{error}</div>;\n return <div className=\"flow-media-mermaid\" style={{ color }} dangerouslySetInnerHTML={{ __html: svg }} />;\n}\n\n/** Renders a LaTeX formula (display mode) via KaTeX. */\nfunction MathView({ content, color, fontSize }: { content: string; color?: string; fontSize?: number }) {\n const html = useMemo(() => {\n try {\n return katex.renderToString(content.trim() || '\\\\;', { displayMode: true, throwOnError: false });\n } catch (e: any) {\n return `<span class=\"flow-media-error\">${e?.message ?? 'KaTeX error'}</span>`;\n }\n }, [content]);\n return <div className=\"flow-media-math\" style={{ color, fontSize }} dangerouslySetInnerHTML={{ __html: html }} />;\n}\n\n/** Renders raw HTML in a sandboxed iframe (isolated from the host document).\n * A base stylesheet is injected so the fragment inherits the node's themed\n * text color / font size and a transparent background, keeping it readable on\n * any theme without the author having to set colors.\n * Content is always untrusted: scripts can drive the preview, but the opaque\n * sandbox origin prevents host DOM/storage access. Do not add allow-same-origin\n * alongside allow-scripts; interactive only controls pointer input. */\nfunction HtmlView({ content, interactive, color, fontSize }: { content: string; interactive: boolean; color?: string; fontSize?: number }) {\n const srcDoc = useMemo(() => {\n const base = `<!doctype html><html><head><meta charset=\"utf-8\"><style>\n :root { color-scheme: light dark; }\n html, body { margin: 0; background: transparent; }\n body {\n color: ${color ?? '#111827'};\n font-size: ${fontSize ?? 13}px;\n font-family: system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif;\n line-height: 1.5;\n padding: 0;\n }\n a { color: inherit; }\n </style></head><body>${content}</body></html>`;\n return base;\n }, [content, color, fontSize]);\n return (\n <iframe\n title=\"html-media\"\n className=\"flow-media-iframe\"\n style={{ pointerEvents: interactive ? 'auto' : 'none' }}\n sandbox=\"allow-scripts\"\n srcDoc={srcDoc}\n />\n );\n}\n\nfunction ImageView({ content }: { content: string }) {\n const src = content.trim();\n if (!src) {\n return <div className=\"flow-media-image-empty\">输入图片链接,或直接粘贴图片</div>;\n }\n return (\n <img\n className=\"flow-media-image\"\n src={src}\n alt=\"\"\n draggable={false}\n referrerPolicy=\"no-referrer\"\n />\n );\n}\n\n/** Interactive AI chat backed by an OpenAI/Anthropic-compatible endpoint. */\nfunction AIView({ node, config, interactive, color }: { node: FlowNode; config?: FlowAIConfig; interactive: boolean; color?: string }) {\n const [messages, setMessages] = useState<AIChatMessage[]>([]);\n const [input, setInput] = useState('');\n const [streaming, setStreaming] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n scrollRef.current?.scrollTo({ top: scrollRef.current.scrollHeight });\n }, [messages, streaming]);\n\n useEffect(() => () => abortRef.current?.abort(), []);\n\n const canSend = !!config?.gateway && !!config?.model && !streaming;\n\n const send = async () => {\n const text = input.trim();\n if (!text || !config?.gateway) return;\n setError(null);\n // Only keep non-empty assistant messages in history; an aborted/errored\n // request can leave an empty assistant placeholder behind, which the API\n // then rejects (\"assistant message must not be empty\").\n const history = messages.filter(\n (m) => !(m.role === 'assistant' && m.content.trim() === ''),\n );\n const next: AIChatMessage[] = [...history, { role: 'user', content: text }];\n setMessages(next);\n setInput('');\n setStreaming(true);\n const ac = new AbortController();\n abortRef.current = ac;\n let acc = '';\n setMessages((m) => [...m, { role: 'assistant', content: '' }]);\n try {\n for await (const delta of streamAIChat(config, next, ac.signal)) {\n acc += delta;\n setMessages((m) => {\n const copy = m.slice();\n copy[copy.length - 1] = { role: 'assistant', content: acc };\n return copy;\n });\n }\n } catch (e: any) {\n if (e?.name !== 'AbortError') setError(e?.message ?? 'Request failed');\n } finally {\n // Drop the trailing assistant placeholder if nothing streamed in.\n setMessages((m) => {\n const last = m[m.length - 1];\n if (last && last.role === 'assistant' && last.content.trim() === '') {\n return m.slice(0, -1);\n }\n return m;\n });\n setStreaming(false);\n abortRef.current = null;\n }\n };\n\n return (\n <div className=\"flow-media-ai\" style={{ color }}>\n <div className=\"flow-media-ai-header\">\n {config?.model ? `AI · ${config.model}` : (node.data.label || 'AI')}\n </div>\n <div className=\"flow-media-ai-log\" ref={scrollRef}>\n {messages.length === 0 && (\n <div className=\"flow-media-ai-empty\">\n {config?.gateway ? '开始对话…' : '请在属性面板配置 AI 接口'}\n </div>\n )}\n {messages.map((m, i) => (\n <div key={i} className={`flow-media-ai-msg flow-media-ai-msg--${m.role}`}>\n {m.role === 'assistant'\n ? <Markdown content={m.content || '…'} enableMermaid={false} enableMarkmap={false} />\n : <span>{m.content}</span>}\n </div>\n ))}\n {error && <div className=\"flow-media-error\">{error}</div>}\n </div>\n <div className=\"flow-media-ai-input\" style={{ pointerEvents: interactive ? 'auto' : 'none' }}>\n <textarea\n value={input}\n placeholder=\"输入消息,Enter 发送\"\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); if (canSend) send(); }\n }}\n onPointerDown={(e) => e.stopPropagation()}\n />\n {streaming ? (\n <button type=\"button\" onClick={() => abortRef.current?.abort()}>停止</button>\n ) : (\n <button type=\"button\" disabled={!canSend || !input.trim()} onClick={send}>发送</button>\n )}\n </div>\n </div>\n );\n}\n\n/** Dispatches to the correct renderer for the node's media kind. */\nexport function MediaContent({ node, interactive }: { node: FlowNode; interactive: boolean }) {\n const kind = node.data.mediaKind ?? 'markdown';\n const content = node.data.mediaContent ?? '';\n const textColor = resolveThemeColorCss(node.data.labelColor ?? node.data.color, '#111827');\n\n switch (kind) {\n case 'markdown':\n return (\n <div className=\"flow-media-markdown\" style={{ color: textColor, fontSize: node.data.fontSize }}>\n <Markdown content={content} />\n </div>\n );\n case 'html':\n // The iframe is an isolated document with no access to the parent's CSS\n // variables, so pass a concrete resolved color instead of a var().\n return (\n <HtmlView\n content={content}\n interactive={interactive}\n color={resolveThemeColor(node.data.labelColor ?? node.data.color, '#111827')}\n fontSize={node.data.fontSize}\n />\n );\n case 'mermaid':\n return <MermaidView content={content} color={textColor} />;\n case 'math':\n return <MathView content={content} color={textColor} fontSize={node.data.fontSize} />;\n case 'image':\n return <ImageView content={content} />;\n case 'model3d':\n return (\n <Model3DView\n content={content}\n format={node.data.modelFormat ?? 'stl'}\n interactive={interactive}\n />\n );\n case 'ai':\n return <AIView node={node} config={node.data.aiConfig} interactive={interactive} color={textColor} />;\n case 'data':\n return (\n <div className=\"flow-media-data\" style={{ pointerEvents: interactive ? 'auto' : 'none' }}>\n <DataNodeView\n config={node.data.dataConfig ?? { columns: [], rows: [], view: 'table' }}\n surfaceColor={node.data.fill === 'transparent' ? undefined : resolveThemeColorCss(node.data.fill, '')}\n textColor={textColor}\n primaryColor={resolveThemeColorCss(node.data.color, '')}\n />\n </div>\n );\n default:\n return null;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MediaContent.js","names":[],"sources":["../../../../../src/components/pro/Flow/nodes/MediaContent.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport katex from 'katex';\nimport mermaid from 'mermaid';\nimport Markdown from '../../../Markdown';\nimport type { FlowNode, FlowAIConfig } from '../types';\nimport { streamAIChat, type AIChatMessage } from './aiClient';\nimport { resolveThemeColorCss, resolveThemeColor } from '../utils/themeColor';\nimport 'katex/dist/katex.min.css';\nimport { Model3DView } from './Model3DView';\n\n// Data-node view pulls in DataTable + Chart; lazy-load so it only enters the\n// bundle when a data node actually renders.\nconst DataNodeView = React.lazy(() =>\n import('./DataNodeView').then((m) => ({ default: m.DataNodeView })),\n);\n\nlet mermaidReady = false;\nfunction ensureMermaid() {\n if (mermaidReady) return;\n mermaid.initialize({ startOnLoad: false, theme: 'default', securityLevel: 'loose', fontFamily: 'inherit' });\n mermaidReady = true;\n}\n\n/** Renders a Mermaid diagram from source into an inline SVG. */\nfunction MermaidView({ content, color }: { content: string; color?: string }) {\n const [svg, setSvg] = useState('');\n const [error, setError] = useState<string | null>(null);\n const idRef = useRef(`flow-mermaid-${Math.random().toString(36).slice(2)}`);\n\n useEffect(() => {\n let cancelled = false;\n ensureMermaid();\n const src = content.trim();\n if (!src) { setSvg(''); setError(null); return; }\n mermaid\n .render(idRef.current, src)\n .then(({ svg }) => { if (!cancelled) { setSvg(svg); setError(null); } })\n .catch((e) => { if (!cancelled) setError(e?.message ?? 'Mermaid error'); });\n return () => { cancelled = true; };\n }, [content]);\n\n if (error) return <div className=\"flow-media-error\">{error}</div>;\n return <div className=\"flow-media-mermaid\" style={{ color }} dangerouslySetInnerHTML={{ __html: svg }} />;\n}\n\n/** Renders a LaTeX formula (display mode) via KaTeX. */\nfunction MathView({ content, color, fontSize }: { content: string; color?: string; fontSize?: number }) {\n const html = useMemo(() => {\n try {\n return katex.renderToString(content.trim() || '\\\\;', { displayMode: true, throwOnError: false });\n } catch (e: any) {\n return `<span class=\"flow-media-error\">${e?.message ?? 'KaTeX error'}</span>`;\n }\n }, [content]);\n return <div className=\"flow-media-math\" style={{ color, fontSize }} dangerouslySetInnerHTML={{ __html: html }} />;\n}\n\n/** Renders raw HTML in a sandboxed iframe (isolated from the host document).\n * A base stylesheet is injected so the fragment inherits the node's themed\n * text color / font size and a transparent background, keeping it readable on\n * any theme without the author having to set colors.\n * Content is always untrusted: scripts can drive the preview, but the opaque\n * sandbox origin prevents host DOM/storage access. Do not add allow-same-origin\n * alongside allow-scripts; interactive only controls pointer input. */\nfunction HtmlView({ content, interactive, color, fontSize }: { content: string; interactive: boolean; color?: string; fontSize?: number }) {\n const srcDoc = useMemo(() => {\n const base = `<!doctype html><html><head><meta charset=\"utf-8\"><style>\n :root { color-scheme: light dark; }\n html, body { margin: 0; background: transparent; }\n body {\n color: ${color ?? '#111827'};\n font-size: ${fontSize ?? 13}px;\n font-family: system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif;\n line-height: 1.5;\n padding: 0;\n }\n a { color: inherit; }\n </style></head><body>${content}</body></html>`;\n return base;\n }, [content, color, fontSize]);\n return (\n <iframe\n title=\"html-media\"\n className=\"flow-media-iframe\"\n style={{ pointerEvents: interactive ? 'auto' : 'none' }}\n sandbox=\"allow-scripts\"\n srcDoc={srcDoc}\n />\n );\n}\n\nfunction ImageView({ content }: { content: string }) {\n const src = content.trim();\n if (!src) {\n return <div className=\"flow-media-image-empty\">输入图片链接,或直接粘贴图片</div>;\n }\n return (\n <img\n className=\"flow-media-image\"\n src={src}\n alt=\"\"\n draggable={false}\n referrerPolicy=\"no-referrer\"\n />\n );\n}\n\n/** Interactive AI chat backed by an OpenAI/Anthropic-compatible endpoint. */\nfunction AIView({ node, config, interactive, color }: { node: FlowNode; config?: FlowAIConfig; interactive: boolean; color?: string }) {\n const [messages, setMessages] = useState<AIChatMessage[]>([]);\n const [input, setInput] = useState('');\n const [streaming, setStreaming] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n scrollRef.current?.scrollTo({ top: scrollRef.current.scrollHeight });\n }, [messages, streaming]);\n\n useEffect(() => () => abortRef.current?.abort(), []);\n\n const canSend = !!config?.gateway && !!config?.model && !streaming;\n\n const send = async () => {\n const text = input.trim();\n if (!text || !config?.gateway) return;\n setError(null);\n // Only keep non-empty assistant messages in history; an aborted/errored\n // request can leave an empty assistant placeholder behind, which the API\n // then rejects (\"assistant message must not be empty\").\n const history = messages.filter(\n (m) => !(m.role === 'assistant' && m.content.trim() === ''),\n );\n const next: AIChatMessage[] = [...history, { role: 'user', content: text }];\n setMessages(next);\n setInput('');\n setStreaming(true);\n const ac = new AbortController();\n abortRef.current = ac;\n let acc = '';\n setMessages((m) => [...m, { role: 'assistant', content: '' }]);\n try {\n for await (const delta of streamAIChat(config, next, ac.signal)) {\n acc += delta;\n setMessages((m) => {\n const copy = m.slice();\n copy[copy.length - 1] = { role: 'assistant', content: acc };\n return copy;\n });\n }\n } catch (e: any) {\n if (e?.name !== 'AbortError') setError(e?.message ?? 'Request failed');\n } finally {\n // Drop the trailing assistant placeholder if nothing streamed in.\n setMessages((m) => {\n const last = m[m.length - 1];\n if (last && last.role === 'assistant' && last.content.trim() === '') {\n return m.slice(0, -1);\n }\n return m;\n });\n setStreaming(false);\n abortRef.current = null;\n }\n };\n\n return (\n <div className=\"flow-media-ai\" style={{ color }}>\n <div className=\"flow-media-ai-header\">\n {config?.model ? `AI · ${config.model}` : (node.data.label || 'AI')}\n </div>\n <div className=\"flow-media-ai-log\" ref={scrollRef}>\n {messages.length === 0 && (\n <div className=\"flow-media-ai-empty\">\n {config?.gateway ? '开始对话…' : '请先配置 AI 接口'}\n </div>\n )}\n {messages.map((m, i) => (\n <div key={i} className={`flow-media-ai-msg flow-media-ai-msg--${m.role}`}>\n {m.role === 'assistant'\n ? <Markdown content={m.content || '…'} enableMermaid={false} enableMarkmap={false} />\n : <span>{m.content}</span>}\n </div>\n ))}\n {error && <div className=\"flow-media-error\">{error}</div>}\n </div>\n <div className=\"flow-media-ai-input\" style={{ pointerEvents: interactive ? 'auto' : 'none' }}>\n <textarea\n value={input}\n placeholder=\"输入消息,Enter 发送\"\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); if (canSend) send(); }\n }}\n onPointerDown={(e) => e.stopPropagation()}\n />\n {streaming ? (\n <button type=\"button\" onClick={() => abortRef.current?.abort()}>停止</button>\n ) : (\n <button type=\"button\" disabled={!canSend || !input.trim()} onClick={send}>发送</button>\n )}\n </div>\n </div>\n );\n}\n\n/** Dispatches to the correct renderer for the node's media kind. */\nexport function MediaContent({ node, interactive, aiConfig }: { node: FlowNode; interactive: boolean; aiConfig?: FlowAIConfig }) {\n const kind = node.data.mediaKind ?? 'markdown';\n const content = node.data.mediaContent ?? '';\n const textColor = resolveThemeColorCss(node.data.labelColor ?? node.data.color, '#111827');\n\n switch (kind) {\n case 'markdown':\n return (\n <div className=\"flow-media-markdown\" style={{ color: textColor, fontSize: node.data.fontSize }}>\n <Markdown content={content} />\n </div>\n );\n case 'html':\n // The iframe is an isolated document with no access to the parent's CSS\n // variables, so pass a concrete resolved color instead of a var().\n return (\n <HtmlView\n content={content}\n interactive={interactive}\n color={resolveThemeColor(node.data.labelColor ?? node.data.color, '#111827')}\n fontSize={node.data.fontSize}\n />\n );\n case 'mermaid':\n return <MermaidView content={content} color={textColor} />;\n case 'math':\n return <MathView content={content} color={textColor} fontSize={node.data.fontSize} />;\n case 'image':\n return <ImageView content={content} />;\n case 'model3d':\n return (\n <Model3DView\n content={content}\n format={node.data.modelFormat ?? 'stl'}\n interactive={interactive}\n />\n );\n case 'ai':\n return <AIView node={node} config={aiConfig ?? node.data.aiConfig} interactive={interactive} color={textColor} />;\n case 'data':\n return (\n <div className=\"flow-media-data\" style={{ pointerEvents: interactive ? 'auto' : 'none' }}>\n <DataNodeView\n config={node.data.dataConfig ?? { columns: [], rows: [], view: 'table' }}\n surfaceColor={node.data.fill === 'transparent' ? undefined : resolveThemeColorCss(node.data.fill, '')}\n textColor={textColor}\n primaryColor={resolveThemeColorCss(node.data.color, '')}\n />\n </div>\n );\n default:\n return null;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { useFlowContext as e } from "../context/FlowContext.js";
|
|
2
2
|
import { useFlowUI as t } from "../context/FlowUIContext.js";
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
3
|
+
import { useFlowAI as n } from "../context/FlowAIContext.js";
|
|
4
|
+
import { resolveThemeColorCss as r } from "../utils/themeColor.js";
|
|
5
|
+
import i, { Suspense as a, useMemo as o } from "react";
|
|
6
|
+
import { jsx as s } from "react/jsx-runtime";
|
|
6
7
|
//#region src/components/pro/Flow/nodes/MediaOverlay.tsx
|
|
7
|
-
var
|
|
8
|
+
var c = i.memo(i.lazy(() => import("./MediaContent.js").then((e) => ({ default: e.MediaContent })))), l = class extends i.Component {
|
|
8
9
|
constructor(e) {
|
|
9
10
|
super(e), this.state = { error: null };
|
|
10
11
|
}
|
|
@@ -12,48 +13,49 @@ var s = r.memo(r.lazy(() => import("./MediaContent.js").then((e) => ({ default:
|
|
|
12
13
|
return { error: e };
|
|
13
14
|
}
|
|
14
15
|
render() {
|
|
15
|
-
return this.state.error ? /* @__PURE__ */
|
|
16
|
+
return this.state.error ? /* @__PURE__ */ s("div", {
|
|
16
17
|
className: "flow-media-error",
|
|
17
18
|
children: this.state.error.message
|
|
18
19
|
}) : this.props.children;
|
|
19
20
|
}
|
|
20
21
|
};
|
|
21
|
-
function
|
|
22
|
-
let { currentCanvas:
|
|
23
|
-
if (
|
|
24
|
-
let { x:
|
|
25
|
-
return /* @__PURE__ */
|
|
22
|
+
function u() {
|
|
23
|
+
let { currentCanvas: i, selection: u } = e(), { viewport: d, isNodeDragging: f } = t(), { aiConfig: p } = n(), m = o(() => i.nodes.filter((e) => e.type === "mediaNode"), [i.nodes]);
|
|
24
|
+
if (m.length === 0) return null;
|
|
25
|
+
let { x: h, y: g, zoom: _ } = d;
|
|
26
|
+
return /* @__PURE__ */ s("div", {
|
|
26
27
|
className: "flow-media-layer",
|
|
27
|
-
children:
|
|
28
|
-
let t = e.position.x *
|
|
29
|
-
return /* @__PURE__ */
|
|
28
|
+
children: m.map((e) => {
|
|
29
|
+
let t = e.position.x * _ + h, n = e.position.y * _ + g, i = u.nodeIds.has(e.id) && !f, o = e.data.fill === "transparent" ? "transparent" : r(e.data.fill, "transparent"), d = r(e.data.labelColor ?? e.data.color, "#111827");
|
|
30
|
+
return /* @__PURE__ */ s("div", {
|
|
30
31
|
className: "flow-media-node",
|
|
31
32
|
"data-media-node": e.id,
|
|
32
33
|
style: {
|
|
33
34
|
position: "absolute",
|
|
34
35
|
left: t,
|
|
35
|
-
top:
|
|
36
|
+
top: n,
|
|
36
37
|
width: e.width,
|
|
37
38
|
height: e.height,
|
|
38
|
-
transform: `scale(${
|
|
39
|
+
transform: `scale(${_})`,
|
|
39
40
|
transformOrigin: "top left",
|
|
40
41
|
pointerEvents: "none"
|
|
41
42
|
},
|
|
42
|
-
children: /* @__PURE__ */
|
|
43
|
+
children: /* @__PURE__ */ s("div", {
|
|
43
44
|
className: "flow-media-surface",
|
|
44
45
|
onWheel: (e) => e.stopPropagation(),
|
|
45
46
|
style: {
|
|
46
|
-
background:
|
|
47
|
-
color:
|
|
47
|
+
background: o,
|
|
48
|
+
color: d
|
|
48
49
|
},
|
|
49
|
-
children: /* @__PURE__ */
|
|
50
|
-
fallback: /* @__PURE__ */
|
|
50
|
+
children: /* @__PURE__ */ s(a, {
|
|
51
|
+
fallback: /* @__PURE__ */ s("div", {
|
|
51
52
|
className: "flow-media-loading",
|
|
52
53
|
children: "…"
|
|
53
54
|
}),
|
|
54
|
-
children: /* @__PURE__ */
|
|
55
|
+
children: /* @__PURE__ */ s(l, { children: /* @__PURE__ */ s(c, {
|
|
55
56
|
node: e,
|
|
56
|
-
interactive:
|
|
57
|
+
interactive: i,
|
|
58
|
+
aiConfig: p
|
|
57
59
|
}) })
|
|
58
60
|
})
|
|
59
61
|
})
|
|
@@ -62,6 +64,6 @@ function l() {
|
|
|
62
64
|
});
|
|
63
65
|
}
|
|
64
66
|
//#endregion
|
|
65
|
-
export {
|
|
67
|
+
export { u as MediaOverlay };
|
|
66
68
|
|
|
67
69
|
//# sourceMappingURL=MediaOverlay.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MediaOverlay.js","names":[],"sources":["../../../../../src/components/pro/Flow/nodes/MediaOverlay.tsx"],"sourcesContent":["import React, { useMemo, Suspense } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport { useFlowUI } from '../context/FlowUIContext';\nimport { resolveThemeColorCss } from '../utils/themeColor';\n\n// Lazy-load the media renderers so the heavy optional deps they pull in\n// (react-markdown, mermaid, katex, markmap, …) are only fetched when a media\n// node actually needs to render. This keeps the base `dishui/flow` bundle\n// lightweight and avoids loading that stack for diagrams without media nodes.\n// Viewport-only updates move the outer box, not the live media subtree. Keep\n// nodes mounted offscreen so iframe/AI state and model camera state survive.\nconst MediaContent = React.memo(React.lazy(() =>\n import('./MediaContent').then((m) => ({ default: m.MediaContent })),\n));\n\n/** Isolates media render/load failures so one bad node never blanks the editor. */\nclass MediaErrorBoundary extends React.Component<\n { children: React.ReactNode },\n { error: Error | null }\n> {\n constructor(props: { children: React.ReactNode }) {\n super(props);\n this.state = { error: null };\n }\n static getDerivedStateFromError(error: Error) {\n return { error };\n }\n render() {\n if (this.state.error) {\n return <div className=\"flow-media-error\">{this.state.error.message}</div>;\n }\n return this.props.children;\n }\n}\n\n/**\n * DOM overlay for media nodes. PixiJS draws the frame; this layer renders the\n * live content (markdown/html/mermaid/math/AI) on top, synced to the viewport\n * so it pans and zooms with the canvas.\n *\n * Event model: a media surface is `pointer-events: none` by default so the\n * canvas underneath can be clicked to select/drag the node's frame. The\n * surface only becomes interactive while its node is selected (so AI chat can\n * be typed into, HTML can be scrolled). This also stops an always-interactive\n * iframe/AI box from swallowing pointer gestures and leaving the drag stuck.\n */\nexport function MediaOverlay() {\n const { currentCanvas, selection } = useFlowContext();\n const { viewport, isNodeDragging } = useFlowUI();\n\n const mediaNodes = useMemo(\n () => currentCanvas.nodes.filter((n) => n.type === 'mediaNode'),\n [currentCanvas.nodes],\n );\n\n if (mediaNodes.length === 0) return null;\n\n const { x: vx, y: vy, zoom } = viewport;\n\n return (\n <div className=\"flow-media-layer\">\n {mediaNodes.map((node) => {\n // World → screen (CSS px, matching ViewportManager.worldToScreen).\n const left = node.position.x * zoom + vx;\n const top = node.position.y * zoom + vy;\n // Interactive only while selected, so the canvas stays draggable.\n // Suppress entirely during a drag: an interactive iframe would swallow\n // the pointer and the canvas would never receive pointerup (stuck drag).\n const interactive = selection.nodeIds.has(node.id) && !isNodeDragging;\n // Drive the overlay's background / text from the node's own color data.\n // Theme tokens (`theme:*`) resolve to CSS variables so the media content\n // follows theme switches natively; literal colors are used as-is. This\n // keeps html / ai / data (which render opaque content) in sync with the\n // fill/color chosen in the inspector, matching the PixiJS frame drawn\n // underneath. The border is owned by the Pixi frame (also what PNG/PDF\n // export captures), so we don't redraw it here.\n const fillCss = node.data.fill === 'transparent'\n ? 'transparent'\n : resolveThemeColorCss(node.data.fill, 'transparent');\n const textColor = resolveThemeColorCss(node.data.labelColor ?? node.data.color, '#111827');\n return (\n <div\n key={node.id}\n className=\"flow-media-node\"\n data-media-node={node.id}\n style={{\n position: 'absolute',\n left,\n top,\n width: node.width,\n height: node.height,\n // Scale the fixed-size content box to match zoom without\n // reflowing text on every zoom step.\n transform: `scale(${zoom})`,\n transformOrigin: 'top left',\n // Below the frame's selection outline but above the canvas.\n pointerEvents: 'none',\n }}\n >\n <div\n className=\"flow-media-surface\"\n onWheel={(e) => e.stopPropagation()}\n style={{\n background: fillCss,\n color: textColor,\n }}\n >\n <Suspense fallback={<div className=\"flow-media-loading\">…</div>}>\n <MediaErrorBoundary>\n <MediaContent node={node} interactive={interactive} />\n </MediaErrorBoundary>\n </Suspense>\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"MediaOverlay.js","names":[],"sources":["../../../../../src/components/pro/Flow/nodes/MediaOverlay.tsx"],"sourcesContent":["import React, { useMemo, Suspense } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport { useFlowUI } from '../context/FlowUIContext';\nimport { useFlowAI } from '../context/FlowAIContext';\nimport { resolveThemeColorCss } from '../utils/themeColor';\n\n// Lazy-load the media renderers so the heavy optional deps they pull in\n// (react-markdown, mermaid, katex, markmap, …) are only fetched when a media\n// node actually needs to render. This keeps the base `dishui/flow` bundle\n// lightweight and avoids loading that stack for diagrams without media nodes.\n// Viewport-only updates move the outer box, not the live media subtree. Keep\n// nodes mounted offscreen so iframe/AI state and model camera state survive.\nconst MediaContent = React.memo(React.lazy(() =>\n import('./MediaContent').then((m) => ({ default: m.MediaContent })),\n));\n\n/** Isolates media render/load failures so one bad node never blanks the editor. */\nclass MediaErrorBoundary extends React.Component<\n { children: React.ReactNode },\n { error: Error | null }\n> {\n constructor(props: { children: React.ReactNode }) {\n super(props);\n this.state = { error: null };\n }\n static getDerivedStateFromError(error: Error) {\n return { error };\n }\n render() {\n if (this.state.error) {\n return <div className=\"flow-media-error\">{this.state.error.message}</div>;\n }\n return this.props.children;\n }\n}\n\n/**\n * DOM overlay for media nodes. PixiJS draws the frame; this layer renders the\n * live content (markdown/html/mermaid/math/AI) on top, synced to the viewport\n * so it pans and zooms with the canvas.\n *\n * Event model: a media surface is `pointer-events: none` by default so the\n * canvas underneath can be clicked to select/drag the node's frame. The\n * surface only becomes interactive while its node is selected (so AI chat can\n * be typed into, HTML can be scrolled). This also stops an always-interactive\n * iframe/AI box from swallowing pointer gestures and leaving the drag stuck.\n */\nexport function MediaOverlay() {\n const { currentCanvas, selection } = useFlowContext();\n const { viewport, isNodeDragging } = useFlowUI();\n const { aiConfig } = useFlowAI();\n\n const mediaNodes = useMemo(\n () => currentCanvas.nodes.filter((n) => n.type === 'mediaNode'),\n [currentCanvas.nodes],\n );\n\n if (mediaNodes.length === 0) return null;\n\n const { x: vx, y: vy, zoom } = viewport;\n\n return (\n <div className=\"flow-media-layer\">\n {mediaNodes.map((node) => {\n // World → screen (CSS px, matching ViewportManager.worldToScreen).\n const left = node.position.x * zoom + vx;\n const top = node.position.y * zoom + vy;\n // Interactive only while selected, so the canvas stays draggable.\n // Suppress entirely during a drag: an interactive iframe would swallow\n // the pointer and the canvas would never receive pointerup (stuck drag).\n const interactive = selection.nodeIds.has(node.id) && !isNodeDragging;\n // Drive the overlay's background / text from the node's own color data.\n // Theme tokens (`theme:*`) resolve to CSS variables so the media content\n // follows theme switches natively; literal colors are used as-is. This\n // keeps html / ai / data (which render opaque content) in sync with the\n // fill/color chosen in the inspector, matching the PixiJS frame drawn\n // underneath. The border is owned by the Pixi frame (also what PNG/PDF\n // export captures), so we don't redraw it here.\n const fillCss = node.data.fill === 'transparent'\n ? 'transparent'\n : resolveThemeColorCss(node.data.fill, 'transparent');\n const textColor = resolveThemeColorCss(node.data.labelColor ?? node.data.color, '#111827');\n return (\n <div\n key={node.id}\n className=\"flow-media-node\"\n data-media-node={node.id}\n style={{\n position: 'absolute',\n left,\n top,\n width: node.width,\n height: node.height,\n // Scale the fixed-size content box to match zoom without\n // reflowing text on every zoom step.\n transform: `scale(${zoom})`,\n transformOrigin: 'top left',\n // Below the frame's selection outline but above the canvas.\n pointerEvents: 'none',\n }}\n >\n <div\n className=\"flow-media-surface\"\n onWheel={(e) => e.stopPropagation()}\n style={{\n background: fillCss,\n color: textColor,\n }}\n >\n <Suspense fallback={<div className=\"flow-media-loading\">…</div>}>\n <MediaErrorBoundary>\n <MediaContent node={node} interactive={interactive} aiConfig={aiConfig} />\n </MediaErrorBoundary>\n </Suspense>\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;;;;;AAYA,IAAM,IAAe,EAAM,KAAK,EAAM,WACpC,OAAO,oBAAiB,CAAC,MAAM,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CACpE,CAAC,GAGK,IAAN,cAAiC,EAAM,UAGrC;CACA,YAAY,GAAsC;EAEhD,AADA,MAAM,CAAK,GACX,KAAK,QAAQ,EAAE,OAAO,KAAK;CAC7B;CACA,OAAO,yBAAyB,GAAc;EAC5C,OAAO,EAAE,SAAM;CACjB;CACA,SAAS;EAIP,OAHI,KAAK,MAAM,QACN,kBAAC,OAAD;GAAK,WAAU;GAAoB,UAAA,KAAK,MAAM,MAAM;EAAa,CAAA,IAEnE,KAAK,MAAM;CACpB;AACF;AAaA,SAAgB,IAAe;CAC7B,IAAM,EAAE,kBAAe,iBAAc,EAAe,GAC9C,EAAE,aAAU,sBAAmB,EAAU,GACzC,EAAE,gBAAa,EAAU,GAEzB,IAAa,QACX,EAAc,MAAM,QAAQ,MAAM,EAAE,SAAS,WAAW,GAC9D,CAAC,EAAc,KAAK,CACtB;CAEA,IAAI,EAAW,WAAW,GAAG,OAAO;CAEpC,IAAM,EAAE,GAAG,GAAI,GAAG,GAAI,YAAS;CAE/B,OACE,kBAAC,OAAD;EAAK,WAAU;EACZ,UAAA,EAAW,KAAK,MAAS;GAExB,IAAM,IAAO,EAAK,SAAS,IAAI,IAAO,GAChC,IAAM,EAAK,SAAS,IAAI,IAAO,GAI/B,IAAc,EAAU,QAAQ,IAAI,EAAK,EAAE,KAAK,CAAC,GAQjD,IAAU,EAAK,KAAK,SAAS,gBAC/B,gBACA,EAAqB,EAAK,KAAK,MAAM,aAAa,GAChD,IAAY,EAAqB,EAAK,KAAK,cAAc,EAAK,KAAK,OAAO,SAAS;GACzF,OACE,kBAAC,OAAD;IAEE,WAAU;IACV,mBAAiB,EAAK;IACtB,OAAO;KACL,UAAU;KACV;KACA;KACA,OAAO,EAAK;KACZ,QAAQ,EAAK;KAGb,WAAW,SAAS,EAAK;KACzB,iBAAiB;KAEjB,eAAe;IACjB;IAEA,UAAA,kBAAC,OAAD;KACE,WAAU;KACV,UAAU,MAAM,EAAE,gBAAgB;KAClC,OAAO;MACL,YAAY;MACZ,OAAO;KACT;KAEA,UAAA,kBAAC,GAAD;MAAU,UAAU,kBAAC,OAAD;OAAK,WAAU;OAAqB,UAAA;MAAM,CAAA;MAC5D,UAAA,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;OAAoB;OAAmB;OAAuB;MAAW,CAAA,EACvD,CAAA;KACZ,CAAA;IACP,CAAA;GACF,GA/BE,EAAK,EA+BP;EAET,CAAC;CACE,CAAA;AAET"}
|
|
@@ -106,7 +106,7 @@ function c(e, t, r) {
|
|
|
106
106
|
}
|
|
107
107
|
function l(e, t, r) {
|
|
108
108
|
if (t.borderStyle === "none" || !t.stroke || t.stroke === "transparent" || t.strokeWidth <= 0) return;
|
|
109
|
-
let a = r ?? Math.min(
|
|
109
|
+
let a = r ?? Math.min(14, t.width * .1, t.height * .1), s = n(t.borderStyle, t.strokeWidth);
|
|
110
110
|
if (s) {
|
|
111
111
|
let n = t.borderStyle === "dynamic" ? t.dashOffset ?? 0 : 0;
|
|
112
112
|
o(e, i(t.width, t.height, a), s, n, t.stroke, t.strokeWidth);
|
|
@@ -122,7 +122,7 @@ function d(e, t) {
|
|
|
122
122
|
e.rect(0, 0, t.width, t.height), s(e, t), c(e, t, r(t.width, t.height));
|
|
123
123
|
}
|
|
124
124
|
function f(e, t) {
|
|
125
|
-
let n = Math.min(
|
|
125
|
+
let n = Math.min(14, t.width * .1, t.height * .1);
|
|
126
126
|
e.roundRect(0, 0, t.width, t.height, n), s(e, t), c(e, t, i(t.width, t.height, n));
|
|
127
127
|
}
|
|
128
128
|
function p(e, t) {
|
|
@@ -373,7 +373,7 @@ function A(e, t) {
|
|
|
373
373
|
}
|
|
374
374
|
function j(e, t, n) {
|
|
375
375
|
switch (e) {
|
|
376
|
-
case "shapeRoundRect": return Math.min(
|
|
376
|
+
case "shapeRoundRect": return Math.min(14, t * .1, n * .1);
|
|
377
377
|
case "mediaNode": return 6;
|
|
378
378
|
case "flowGroup":
|
|
379
379
|
case "geometryGroup": return Math.min(6, t * .04, n * .04);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shapes.js","names":[],"sources":["../../../../../src/components/pro/Flow/nodes/shapes.ts"],"sourcesContent":["import { Graphics } from 'pixi.js';\nimport type { FlowShapeType, FlowNodeData, FlowBorderSides, FlowBorderSideOverride } from '../types';\nimport { drawDashedPath, type PathSeg } from '../utils/dashedLine';\nimport { resolveThemeColor } from '../utils/themeColor';\n\nexport interface ShapeDrawOptions {\n width: number;\n height: number;\n fill: string;\n stroke: string;\n strokeWidth: number;\n borderStyle?: 'solid' | 'dashed' | 'dotted' | 'dynamic' | 'none';\n dashOffset?: number;\n}\n\nfunction parseDash(style: string | undefined, strokeWidth: number): number[] | undefined {\n if (!style || style === 'solid') return undefined;\n if (style === 'dynamic') return [strokeWidth * 4, strokeWidth * 3];\n if (style === 'dashed') return [strokeWidth * 4, strokeWidth * 2];\n if (style === 'dotted') return [strokeWidth, strokeWidth * 2];\n return undefined;\n}\n\n/**\n * Sample a rectangle's outline as points for dashed border.\n */\nfunction sampleRect(w: number, h: number, step = 3): Array<{ x: number; y: number }> {\n const pts: Array<{ x: number; y: number }> = [];\n for (let x = 0; x <= w; x += step) pts.push({ x, y: 0 });\n for (let y = step; y <= h; y += step) pts.push({ x: w, y });\n for (let x = w - step; x >= 0; x -= step) pts.push({ x, y: h });\n for (let y = h - step; y > 0; y -= step) pts.push({ x: 0, y });\n pts.push({ x: 0, y: 0 });\n return pts;\n}\n\n/**\n * Sample a rounded rectangle outline as points.\n */\nfunction sampleRoundRect(w: number, h: number, r: number, step = 3): Array<{ x: number; y: number }> {\n const pts: Array<{ x: number; y: number }> = [];\n const cornerSamples = Math.max(4, Math.ceil((Math.PI / 2) * r / step));\n const addCorner = (cx: number, cy: number, startAngle: number) => {\n for (let i = 0; i <= cornerSamples; i++) {\n const a = startAngle + (Math.PI / 2) * (i / cornerSamples);\n pts.push({ x: cx + r * Math.cos(a), y: cy + r * Math.sin(a) });\n }\n };\n addCorner(w - r, r, -Math.PI / 2);\n addCorner(w - r, h - r, 0);\n addCorner(r, h - r, Math.PI / 2);\n addCorner(r, r, Math.PI);\n if (pts.length > 0) pts.push(pts[0]);\n return pts;\n}\n\n/**\n * Sample an ellipse outline.\n */\nfunction sampleEllipse(cx: number, cy: number, rx: number, ry: number, samples = 60): Array<{ x: number; y: number }> {\n const pts: Array<{ x: number; y: number }> = [];\n for (let i = 0; i <= samples; i++) {\n const a = (Math.PI * 2 * i) / samples;\n pts.push({ x: cx + rx * Math.cos(a), y: cy + ry * Math.sin(a) });\n }\n return pts;\n}\n\n/**\n * Draw dashed polyline onto graphics.\n */\nfunction drawDashedPoly(g: Graphics, pts: Array<{ x: number; y: number }>, dash: number[], offset: number, color: string, width: number): void {\n if (pts.length < 2) return;\n const dists = [0];\n for (let i = 1; i < pts.length; i++) {\n dists.push(dists[i - 1] + Math.hypot(pts[i].x - pts[i - 1].x, pts[i].y - pts[i - 1].y));\n }\n const total = dists[dists.length - 1];\n if (total < 1) return;\n const patternLen = dash[0] + dash[1];\n let pos = -(((offset % patternLen) + patternLen) % patternLen);\n let drawing = true;\n\n const lerp = (d: number) => {\n if (d <= 0) return pts[0];\n if (d >= total) return pts[pts.length - 1];\n let lo = 0, hi = dists.length - 1;\n while (lo < hi - 1) { const m = (lo + hi) >> 1; if (dists[m] <= d) lo = m; else hi = m; }\n const t = dists[hi] - dists[lo] > 0 ? (d - dists[lo]) / (dists[hi] - dists[lo]) : 0;\n return { x: pts[lo].x + (pts[hi].x - pts[lo].x) * t, y: pts[lo].y + (pts[hi].y - pts[lo].y) * t };\n };\n\n while (pos < total) {\n const segLen = drawing ? dash[0] : dash[1];\n const start = Math.max(pos, 0);\n const end = Math.min(pos + segLen, total);\n if (drawing && end > start) {\n const p0 = lerp(start);\n g.moveTo(p0.x, p0.y);\n for (let d = start + 2; d < end; d += 2) {\n const p = lerp(d);\n g.lineTo(p.x, p.y);\n }\n const pe = lerp(end);\n g.lineTo(pe.x, pe.y);\n }\n pos += segLen;\n drawing = !drawing;\n }\n g.stroke({ color, width, cap: 'round' as const });\n}\n\nfunction fillShape(g: Graphics, o: ShapeDrawOptions) {\n if (o.fill && o.fill !== 'transparent') {\n g.fill({ color: o.fill });\n }\n if (o.borderStyle === 'none') return;\n if (o.stroke && o.stroke !== 'transparent' && o.strokeWidth > 0) {\n const dash = parseDash(o.borderStyle, o.strokeWidth);\n if (dash) {\n // Dashed/dotted/dynamic: don't stroke the shape path, we'll draw dashed separately\n } else {\n g.stroke({ color: o.stroke, width: o.strokeWidth });\n }\n }\n}\n\n/**\n * After fillShape, draw dashed border if needed.\n * Pass shape-specific outline points.\n */\nfunction drawDashedBorder(g: Graphics, o: ShapeDrawOptions, outlinePts: Array<{ x: number; y: number }>) {\n const dash = parseDash(o.borderStyle, o.strokeWidth);\n if (!dash || !o.stroke || o.stroke === 'transparent' || o.strokeWidth <= 0) return;\n const offset = o.borderStyle === 'dynamic' ? (o.dashOffset ?? 0) : 0;\n drawDashedPoly(g, outlinePts, dash, offset, o.stroke, o.strokeWidth);\n}\n\n/** Draw only a rounded-rectangle border, without leaving a base path that can\n * be picked up by the dashed stroke. Useful when fill and border are rendered\n * independently, as they are for SVG icon nodes. */\nexport function drawRoundRectBorder(g: Graphics, o: ShapeDrawOptions, radius?: number): void {\n if (o.borderStyle === 'none' || !o.stroke || o.stroke === 'transparent' || o.strokeWidth <= 0) return;\n const r = radius ?? Math.min(12, o.width * 0.1, o.height * 0.1);\n const dash = parseDash(o.borderStyle, o.strokeWidth);\n if (dash) {\n const offset = o.borderStyle === 'dynamic' ? (o.dashOffset ?? 0) : 0;\n drawDashedPoly(g, sampleRoundRect(o.width, o.height, r), dash, offset, o.stroke, o.strokeWidth);\n } else {\n g.roundRect(0, 0, o.width, o.height, r).stroke({ color: o.stroke, width: o.strokeWidth });\n }\n}\n\nfunction polyPoints(verts: Array<{ x: number; y: number }>): Array<{ x: number; y: number }> {\n return [...verts, verts[0]];\n}\n\nexport function drawRect(g: Graphics, o: ShapeDrawOptions): void {\n g.rect(0, 0, o.width, o.height);\n fillShape(g, o);\n drawDashedBorder(g, o, sampleRect(o.width, o.height));\n}\n\nexport function drawRoundRect(g: Graphics, o: ShapeDrawOptions): void {\n const r = Math.min(12, o.width * 0.1, o.height * 0.1);\n g.roundRect(0, 0, o.width, o.height, r);\n fillShape(g, o);\n drawDashedBorder(g, o, sampleRoundRect(o.width, o.height, r));\n}\n\nexport function drawEllipse(g: Graphics, o: ShapeDrawOptions): void {\n g.ellipse(o.width / 2, o.height / 2, o.width / 2, o.height / 2);\n fillShape(g, o);\n drawDashedBorder(g, o, sampleEllipse(o.width / 2, o.height / 2, o.width / 2, o.height / 2));\n}\n\nexport function drawDiamond(g: Graphics, o: ShapeDrawOptions): void {\n const cx = o.width / 2, cy = o.height / 2;\n const verts = [{ x: cx, y: 0 }, { x: o.width, y: cy }, { x: cx, y: o.height }, { x: 0, y: cy }];\n g.moveTo(cx, 0).lineTo(o.width, cy).lineTo(cx, o.height).lineTo(0, cy).closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawDocument(g: Graphics, o: ShapeDrawOptions): void {\n const w = o.width, h = o.height, curve = h * 0.15;\n g.moveTo(0, 0)\n .lineTo(w, 0)\n .lineTo(w, h - curve)\n .bezierCurveTo(w * 0.75, h - curve * 2, w * 0.25, h, 0, h - curve)\n .closePath();\n fillShape(g, o);\n const pts: Array<{ x: number; y: number }> = [{ x: 0, y: 0 }, { x: w, y: 0 }, { x: w, y: h - curve }];\n const samples = 20;\n for (let i = 1; i <= samples; i++) {\n const t = i / samples;\n const u = 1 - t;\n pts.push({\n x: u * u * u * w + 3 * u * u * t * (w * 0.75) + 3 * u * t * t * (w * 0.25),\n y: u * u * u * (h - curve) + 3 * u * u * t * (h - curve * 2) + 3 * u * t * t * h + t * t * t * (h - curve),\n });\n }\n pts.push({ x: 0, y: 0 });\n drawDashedBorder(g, o, pts);\n}\n\nexport function drawParallelogram(g: Graphics, o: ShapeDrawOptions): void {\n const skew = o.width * 0.2;\n const verts = [{ x: skew, y: 0 }, { x: o.width, y: 0 }, { x: o.width - skew, y: o.height }, { x: 0, y: o.height }];\n g.moveTo(skew, 0).lineTo(o.width, 0).lineTo(o.width - skew, o.height).lineTo(0, o.height).closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawTriangle(g: Graphics, o: ShapeDrawOptions): void {\n const verts = [{ x: o.width / 2, y: 0 }, { x: o.width, y: o.height }, { x: 0, y: o.height }];\n g.moveTo(o.width / 2, 0).lineTo(o.width, o.height).lineTo(0, o.height).closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawTrapezoid(g: Graphics, o: ShapeDrawOptions): void {\n const inset = o.width * 0.15;\n const verts = [{ x: inset, y: 0 }, { x: o.width - inset, y: 0 }, { x: o.width, y: o.height }, { x: 0, y: o.height }];\n g.moveTo(inset, 0).lineTo(o.width - inset, 0).lineTo(o.width, o.height).lineTo(0, o.height).closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nfunction regularPoly(cx: number, cy: number, sides: number, rx: number, ry: number, startAngle: number): Array<{ x: number; y: number }> {\n const verts: Array<{ x: number; y: number }> = [];\n for (let i = 0; i < sides; i++) {\n const a = (Math.PI * 2 * i) / sides + startAngle;\n verts.push({ x: cx + rx * Math.cos(a), y: cy + ry * Math.sin(a) });\n }\n return verts;\n}\n\nexport function drawPentagon(g: Graphics, o: ShapeDrawOptions): void {\n const cx = o.width / 2, cy = o.height / 2, r = Math.min(cx, cy);\n const verts = regularPoly(cx, cy, 5, r, r, -Math.PI / 2);\n for (let i = 0; i < verts.length; i++) {\n if (i === 0) g.moveTo(verts[i].x, verts[i].y); else g.lineTo(verts[i].x, verts[i].y);\n }\n g.closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawHexagon(g: Graphics, o: ShapeDrawOptions): void {\n const cx = o.width / 2, cy = o.height / 2;\n const verts = regularPoly(cx, cy, 6, cx, cy, -Math.PI / 6);\n for (let i = 0; i < verts.length; i++) {\n if (i === 0) g.moveTo(verts[i].x, verts[i].y); else g.lineTo(verts[i].x, verts[i].y);\n }\n g.closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawStar(g: Graphics, o: ShapeDrawOptions): void {\n const cx = o.width / 2, cy = o.height / 2;\n const outer = Math.min(cx, cy), inner = outer * 0.4, points = 5;\n const verts: Array<{ x: number; y: number }> = [];\n for (let i = 0; i < points * 2; i++) {\n const angle = (Math.PI * i) / points - Math.PI / 2;\n const r = i % 2 === 0 ? outer : inner;\n verts.push({ x: cx + r * Math.cos(angle), y: cy + r * Math.sin(angle) });\n }\n for (let i = 0; i < verts.length; i++) {\n if (i === 0) g.moveTo(verts[i].x, verts[i].y); else g.lineTo(verts[i].x, verts[i].y);\n }\n g.closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawHexagram(g: Graphics, o: ShapeDrawOptions): void {\n const cx = o.width / 2, cy = o.height / 2;\n const outer = Math.min(cx, cy), inner = outer * 0.55;\n const verts: Array<{ x: number; y: number }> = [];\n for (let i = 0; i < 12; i++) {\n const angle = (Math.PI * i) / 6 - Math.PI / 2;\n const r = i % 2 === 0 ? outer : inner;\n verts.push({ x: cx + r * Math.cos(angle), y: cy + r * Math.sin(angle) });\n }\n for (let i = 0; i < verts.length; i++) {\n if (i === 0) g.moveTo(verts[i].x, verts[i].y); else g.lineTo(verts[i].x, verts[i].y);\n }\n g.closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawRightTriangle(g: Graphics, o: ShapeDrawOptions): void {\n const verts = [{ x: 0, y: 0 }, { x: o.width, y: o.height }, { x: 0, y: o.height }];\n g.moveTo(0, 0).lineTo(o.width, o.height).lineTo(0, o.height).closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawCorner(g: Graphics, o: ShapeDrawOptions): void {\n const half = Math.min(o.width, o.height) * 0.4;\n const verts = [\n { x: 0, y: 0 }, { x: o.width, y: 0 }, { x: o.width, y: half },\n { x: half, y: half }, { x: half, y: o.height }, { x: 0, y: o.height },\n ];\n g.moveTo(0, 0).lineTo(o.width, 0).lineTo(o.width, half)\n .lineTo(half, half).lineTo(half, o.height).lineTo(0, o.height).closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawFlowGroup(g: Graphics, o: ShapeDrawOptions): void {\n const r = Math.min(6, o.width * 0.04, o.height * 0.04);\n g.roundRect(0, 0, o.width, o.height, r);\n if (o.fill && o.fill !== 'transparent') {\n g.fill({ color: o.fill, alpha: 0.08 });\n }\n const border = o.borderStyle ?? 'dashed';\n if (border !== 'none' && o.stroke && o.stroke !== 'transparent' && o.strokeWidth > 0) {\n const dash = parseDash(border, o.strokeWidth);\n if (dash) {\n const offset = border === 'dynamic' ? (o.dashOffset ?? 0) : 0;\n drawDashedPoly(g, sampleRoundRect(o.width, o.height, r), dash, offset, o.stroke, o.strokeWidth);\n } else {\n g.stroke({ color: o.stroke, width: o.strokeWidth });\n }\n }\n}\n\nexport const drawGeometryGroup = drawFlowGroup;\n\n/* ─── Per-side borders (top / right / bottom / left) ─────────────────── */\n\nexport type BorderSideName = 'top' | 'right' | 'bottom' | 'left';\nexport const BORDER_SIDE_NAMES: BorderSideName[] = ['top', 'right', 'bottom', 'left'];\n\n/** Shape types whose geometry has four well-defined sides. Other shapes ignore\n * `borderSides` and keep a full outline. */\nexport const BORDER_SIDE_TYPES = new Set<string>([\n 'shapeRect', 'shapeRoundRect', 'shapeEllipse', 'shapeDiamond', 'shapeDocument',\n 'shapeParallelogram', 'shapeTrapezoid', 'mediaNode', 'flowGroup', 'geometryGroup',\n]);\n\n/** True when `borderSides` carries at least one effective override AND the\n * shape type supports per-side borders. */\nexport function hasBorderSideOverrides(data: FlowNodeData, type?: string): boolean {\n if (type !== undefined && !BORDER_SIDE_TYPES.has(type)) return false;\n const sides = data.borderSides;\n if (!sides) return false;\n return BORDER_SIDE_NAMES.some((name) => {\n const side = sides[name];\n return !!side\n && (side.visible === false || side.color !== undefined || side.width !== undefined);\n });\n}\n\n/** Corner radius used by each shape's own drawer, so side segments line up\n * exactly with the (possibly hidden) full outline. */\nfunction borderSideRadius(type: string, w: number, h: number): number {\n switch (type) {\n case 'shapeRoundRect': return Math.min(12, w * 0.1, h * 0.1);\n case 'mediaNode': return 6;\n case 'flowGroup':\n case 'geometryGroup': return Math.min(6, w * 0.04, h * 0.04);\n default: return 0;\n }\n}\n\nconst BEZIER_K = 0.5522847498; // kappa for a 90° arc approximation\n\n/** Build the drawable path of one side of the shape. Corners are owned by the\n * side that starts there (clockwise): top owns the top-left arc, right the\n * top-right arc, and so on — with uniform styling the four sides reconstruct\n * the full outline seamlessly. */\nexport function buildBorderSideSegments(\n type: string,\n w: number,\n h: number,\n side: BorderSideName,\n): PathSeg[] {\n const segs: PathSeg[] = [];\n const line = (x: number, y: number) => segs.push({ type: 'L', x, y });\n const cubic = (\n c1x: number, c1y: number, c2x: number, c2y: number, x: number, y: number,\n ) => segs.push({ type: 'C', cp1x: c1x, cp1y: c1y, cp2x: c2x, cp2y: c2y, x, y });\n\n const r = borderSideRadius(type, w, h);\n if (r >= 0.5) {\n // Rounded rect family (shapeRoundRect / mediaNode / group frames): each\n // side owns its starting corner arc (clockwise), so uniform styling\n // reconstructs the full rounded outline seamlessly.\n const k = BEZIER_K * r;\n switch (side) {\n case 'top':\n segs.push({ type: 'M', x: 0, y: r });\n cubic(0, r - k, r - k, 0, r, 0);\n line(w - r, 0);\n break;\n case 'right':\n segs.push({ type: 'M', x: w - r, y: 0 });\n cubic(w - r + k, 0, w, r - k, w, r);\n line(w, h - r);\n break;\n case 'bottom':\n segs.push({ type: 'M', x: w, y: h - r });\n cubic(w, h - r + k, w - r + k, h, w - r, h);\n line(r, h);\n break;\n case 'left':\n segs.push({ type: 'M', x: r, y: h });\n cubic(r - k, h, 0, h - r + k, 0, h - r);\n line(0, r);\n break;\n }\n return segs;\n }\n\n if (type === 'shapeEllipse') {\n // Split the outline at the 45° diagonals so each side is the arc centered\n // on its direction (top arc spans the top, etc.).\n const cx = w / 2, cy = h / 2, rx = w / 2, ry = h / 2;\n const angles: Record<BorderSideName, [number, number]> = {\n top: [Math.PI * 1.25, Math.PI * 1.75],\n right: [Math.PI * 1.75, Math.PI * 2.25],\n bottom: [Math.PI * 0.25, Math.PI * 0.75],\n left: [Math.PI * 0.75, Math.PI * 1.25],\n };\n const [a0, a1] = angles[side];\n const p0x = cx + rx * Math.cos(a0), p0y = cy + ry * Math.sin(a0);\n const p3x = cx + rx * Math.cos(a1), p3y = cy + ry * Math.sin(a1);\n segs.push({ type: 'M', x: p0x, y: p0y });\n cubic(\n p0x - BEZIER_K * rx * Math.sin(a0), p0y + BEZIER_K * ry * Math.cos(a0),\n p3x + BEZIER_K * rx * Math.sin(a1), p3y - BEZIER_K * ry * Math.cos(a1),\n p3x, p3y,\n );\n return segs;\n }\n\n if (type === 'shapeDocument') {\n const curve = h * 0.15;\n if (side === 'top') {\n segs.push({ type: 'M', x: 0, y: 0 });\n line(w, 0);\n } else if (side === 'right') {\n segs.push({ type: 'M', x: w, y: 0 });\n line(w, h - curve);\n } else if (side === 'bottom') {\n segs.push({ type: 'M', x: w, y: h - curve });\n cubic(w * 0.75, h - curve * 2, w * 0.25, h, 0, h - curve);\n } else {\n segs.push({ type: 'M', x: 0, y: h - curve });\n line(0, 0);\n }\n return segs;\n }\n\n // Quadrilaterals (rect / diamond / parallelogram / trapezoid).\n let v0: { x: number; y: number }, v1: { x: number; y: number }, v2: { x: number; y: number }, v3: { x: number; y: number };\n if (type === 'shapeDiamond') {\n const cx = w / 2, cy = h / 2;\n v0 = { x: cx, y: 0 }; v1 = { x: w, y: cy }; v2 = { x: cx, y: h }; v3 = { x: 0, y: cy };\n } else if (type === 'shapeParallelogram') {\n const skew = w * 0.2;\n v0 = { x: skew, y: 0 }; v1 = { x: w, y: 0 }; v2 = { x: w - skew, y: h }; v3 = { x: 0, y: h };\n } else if (type === 'shapeTrapezoid') {\n const inset = w * 0.15;\n v0 = { x: inset, y: 0 }; v1 = { x: w - inset, y: 0 }; v2 = { x: w, y: h }; v3 = { x: 0, y: h };\n } else {\n v0 = { x: 0, y: 0 }; v1 = { x: w, y: 0 }; v2 = { x: w, y: h }; v3 = { x: 0, y: h };\n }\n\n const edges: Record<BorderSideName, [{ x: number; y: number }, { x: number; y: number }]> = {\n top: [v0, v1],\n right: [v1, v2],\n bottom: [v2, v3],\n left: [v3, v0],\n };\n const [a, b] = edges[side];\n segs.push({ type: 'M', x: a.x, y: a.y });\n line(b.x, b.y);\n return segs;\n}\n\n/** Draw the four sides of a node independently, honoring per-side color /\n * width / visibility overrides (falling back to the node's defaults). The\n * node's `borderStyle` (solid / dashed / dotted / dynamic) applies to every\n * side. `defaultColor` is the node's (already theme-resolved) stroke. */\nexport function drawBorderSides(\n g: Graphics,\n type: string,\n width: number,\n height: number,\n sides: FlowBorderSides | undefined,\n defaultColor: string,\n defaultWidth: number,\n borderStyle: string | undefined,\n dashOffset: number,\n): void {\n if (borderStyle === 'none') return;\n for (const name of BORDER_SIDE_NAMES) {\n const side: FlowBorderSideOverride | undefined = sides?.[name];\n if (side?.visible === false) continue;\n const color = resolveThemeColor(side?.color, defaultColor) || defaultColor;\n const strokeWidth = side?.width ?? defaultWidth;\n if (!color || color === 'transparent' || !(strokeWidth > 0)) continue;\n const segs = buildBorderSideSegments(type, width, height, name);\n const dash = parseDash(borderStyle, strokeWidth);\n if (dash) {\n const offset = borderStyle === 'dynamic' ? dashOffset : 0;\n drawDashedPath(g, segs, dash, offset);\n g.stroke({ color, width: strokeWidth, 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: strokeWidth });\n }\n }\n}\n\n/** Lookup table mapping shape type to draw function */\nexport const shapeDrawers: Record<string, (g: Graphics, o: ShapeDrawOptions) => void> = {\n shapeRect: drawRect,\n shapeRoundRect: drawRoundRect,\n shapeEllipse: drawEllipse,\n shapeDiamond: drawDiamond,\n shapeDocument: drawDocument,\n shapeParallelogram: drawParallelogram,\n shapeTriangle: drawTriangle,\n shapeTrapezoid: drawTrapezoid,\n shapePentagon: drawPentagon,\n shapeHexagon: drawHexagon,\n shapeStar: drawStar,\n shapeHexagram: drawHexagram,\n shapeRightTriangle: drawRightTriangle,\n shapeCorner: drawCorner,\n textLabel: drawRect,\n flowGroup: drawFlowGroup,\n geometryGroup: drawGeometryGroup,\n shapeSvg: drawRoundRect,\n};\n"],"mappings":";;;AAeA,SAAS,EAAU,GAA2B,GAA2C;CACnF,IAAC,KAAS,MAAU,SACxB;MAAI,MAAU,WAAW,OAAO,CAAC,IAAc,GAAG,IAAc,CAAC;EACjE,IAAI,MAAU,UAAU,OAAO,CAAC,IAAc,GAAG,IAAc,CAAC;EAChE,IAAI,MAAU,UAAU,OAAO,CAAC,GAAa,IAAc,CAAC;CAFK;AAInE;AAKA,SAAS,EAAW,GAAW,GAAW,IAAO,GAAoC;CACnF,IAAM,IAAuC,CAAC;CAC9C,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK,GAAM,EAAI,KAAK;EAAE;EAAG,GAAG;CAAE,CAAC;CACvD,KAAK,IAAI,IAAI,GAAM,KAAK,GAAG,KAAK,GAAM,EAAI,KAAK;EAAE,GAAG;EAAG;CAAE,CAAC;CAC1D,KAAK,IAAI,IAAI,IAAI,GAAM,KAAK,GAAG,KAAK,GAAM,EAAI,KAAK;EAAE;EAAG,GAAG;CAAE,CAAC;CAC9D,KAAK,IAAI,IAAI,IAAI,GAAM,IAAI,GAAG,KAAK,GAAM,EAAI,KAAK;EAAE,GAAG;EAAG;CAAE,CAAC;CAE7D,OADA,EAAI,KAAK;EAAE,GAAG;EAAG,GAAG;CAAE,CAAC,GAChB;AACT;AAKA,SAAS,EAAgB,GAAW,GAAW,GAAW,IAAO,GAAoC;CACnG,IAAM,IAAuC,CAAC,GACxC,IAAgB,KAAK,IAAI,GAAG,KAAK,KAAM,KAAK,KAAK,IAAK,IAAI,CAAI,CAAC,GAC/D,KAAa,GAAY,GAAY,MAAuB;EAChE,KAAK,IAAI,IAAI,GAAG,KAAK,GAAe,KAAK;GACvC,IAAM,IAAI,IAAc,KAAK,KAAK,KAAM,IAAI;GAC5C,EAAI,KAAK;IAAE,GAAG,IAAK,IAAI,KAAK,IAAI,CAAC;IAAG,GAAG,IAAK,IAAI,KAAK,IAAI,CAAC;GAAE,CAAC;EAC/D;CACF;CAMA,OALA,EAAU,IAAI,GAAG,GAAG,CAAC,KAAK,KAAK,CAAC,GAChC,EAAU,IAAI,GAAG,IAAI,GAAG,CAAC,GACzB,EAAU,GAAG,IAAI,GAAG,KAAK,KAAK,CAAC,GAC/B,EAAU,GAAG,GAAG,KAAK,EAAE,GACnB,EAAI,SAAS,KAAG,EAAI,KAAK,EAAI,EAAE,GAC5B;AACT;AAKA,SAAS,EAAc,GAAY,GAAY,GAAY,GAAY,IAAU,IAAqC;CACpH,IAAM,IAAuC,CAAC;CAC9C,KAAK,IAAI,IAAI,GAAG,KAAK,GAAS,KAAK;EACjC,IAAM,IAAK,KAAK,KAAK,IAAI,IAAK;EAC9B,EAAI,KAAK;GAAE,GAAG,IAAK,IAAK,KAAK,IAAI,CAAC;GAAG,GAAG,IAAK,IAAK,KAAK,IAAI,CAAC;EAAE,CAAC;CACjE;CACA,OAAO;AACT;AAKA,SAAS,EAAe,GAAa,GAAsC,GAAgB,GAAgB,GAAe,GAAqB;CAC7I,IAAI,EAAI,SAAS,GAAG;CACpB,IAAM,IAAQ,CAAC,CAAC;CAChB,KAAK,IAAI,IAAI,GAAG,IAAI,EAAI,QAAQ,KAC9B,EAAM,KAAK,EAAM,IAAI,KAAK,KAAK,MAAM,EAAI,EAAE,CAAC,IAAI,EAAI,IAAI,EAAE,CAAC,GAAG,EAAI,EAAE,CAAC,IAAI,EAAI,IAAI,EAAE,CAAC,CAAC,CAAC;CAExF,IAAM,IAAQ,EAAM,EAAM,SAAS;CACnC,IAAI,IAAQ,GAAG;CACf,IAAM,IAAa,EAAK,KAAK,EAAK,IAC9B,IAAM,GAAI,IAAS,IAAc,KAAc,IAC/C,IAAU,IAER,KAAQ,MAAc;EAC1B,IAAI,KAAK,GAAG,OAAO,EAAI;EACvB,IAAI,KAAK,GAAO,OAAO,EAAI,EAAI,SAAS;EACxC,IAAI,IAAK,GAAG,IAAK,EAAM,SAAS;EAChC,OAAO,IAAK,IAAK,IAAG;GAAE,IAAM,IAAK,IAAK,KAAO;GAAG,AAAI,EAAM,MAAM,IAAG,IAAK,IAAQ,IAAK;EAAG;EACxF,IAAM,IAAI,EAAM,KAAM,EAAM,KAAM,KAAK,IAAI,EAAM,OAAQ,EAAM,KAAM,EAAM,MAAO;EAClF,OAAO;GAAE,GAAG,EAAI,EAAG,CAAC,KAAK,EAAI,EAAG,CAAC,IAAI,EAAI,EAAG,CAAC,KAAK;GAAG,GAAG,EAAI,EAAG,CAAC,KAAK,EAAI,EAAG,CAAC,IAAI,EAAI,EAAG,CAAC,KAAK;EAAE;CAClG;CAEA,OAAO,IAAM,IAAO;EAClB,IAAM,IAAS,IAAU,EAAK,KAAK,EAAK,IAClC,IAAQ,KAAK,IAAI,GAAK,CAAC,GACvB,IAAM,KAAK,IAAI,IAAM,GAAQ,CAAK;EACxC,IAAI,KAAW,IAAM,GAAO;GAC1B,IAAM,IAAK,EAAK,CAAK;GACrB,EAAE,OAAO,EAAG,GAAG,EAAG,CAAC;GACnB,KAAK,IAAI,IAAI,IAAQ,GAAG,IAAI,GAAK,KAAK,GAAG;IACvC,IAAM,IAAI,EAAK,CAAC;IAChB,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;GACnB;GACA,IAAM,IAAK,EAAK,CAAG;GACnB,EAAE,OAAO,EAAG,GAAG,EAAG,CAAC;EACrB;EAEA,AADA,KAAO,GACP,IAAU,CAAC;CACb;CACA,EAAE,OAAO;EAAE;EAAO;EAAO,KAAK;CAAiB,CAAC;AAClD;AAEA,SAAS,EAAU,GAAa,GAAqB;CACnD,AAAI,EAAE,QAAQ,EAAE,SAAS,iBACvB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,GAEtB,EAAE,gBAAgB,UAClB,EAAE,UAAU,EAAE,WAAW,iBAAiB,EAAE,cAAc,MAC/C,EAAU,EAAE,aAAa,EAAE,WACpC,KAGF,EAAE,OAAO;EAAE,OAAO,EAAE;EAAQ,OAAO,EAAE;CAAY,CAAC;AAGxD;AAMA,SAAS,EAAiB,GAAa,GAAqB,GAA6C;CACvG,IAAM,IAAO,EAAU,EAAE,aAAa,EAAE,WAAW;CAC/C,CAAC,KAAQ,CAAC,EAAE,UAAU,EAAE,WAAW,iBAAiB,EAAE,eAAe,KAEzE,EAAe,GAAG,GAAY,GADf,EAAE,gBAAgB,YAAa,EAAE,cAAc,IAAK,GACvB,EAAE,QAAQ,EAAE,WAAW;AACrE;AAKA,SAAgB,EAAoB,GAAa,GAAqB,GAAuB;CAC3F,IAAI,EAAE,gBAAgB,UAAU,CAAC,EAAE,UAAU,EAAE,WAAW,iBAAiB,EAAE,eAAe,GAAG;CAC/F,IAAM,IAAI,KAAU,KAAK,IAAI,IAAI,EAAE,QAAQ,IAAK,EAAE,SAAS,EAAG,GACxD,IAAO,EAAU,EAAE,aAAa,EAAE,WAAW;CACnD,IAAI,GAAM;EACR,IAAM,IAAS,EAAE,gBAAgB,YAAa,EAAE,cAAc,IAAK;EACnE,EAAe,GAAG,EAAgB,EAAE,OAAO,EAAE,QAAQ,CAAC,GAAG,GAAM,GAAQ,EAAE,QAAQ,EAAE,WAAW;CAChG,OACE,EAAE,UAAU,GAAG,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO;EAAE,OAAO,EAAE;EAAQ,OAAO,EAAE;CAAY,CAAC;AAE5F;AAEA,SAAS,EAAW,GAAyE;CAC3F,OAAO,CAAC,GAAG,GAAO,EAAM,EAAE;AAC5B;AAEA,SAAgB,EAAS,GAAa,GAA2B;CAG/D,AAFA,EAAE,KAAK,GAAG,GAAG,EAAE,OAAO,EAAE,MAAM,GAC9B,EAAU,GAAG,CAAC,GACd,EAAiB,GAAG,GAAG,EAAW,EAAE,OAAO,EAAE,MAAM,CAAC;AACtD;AAEA,SAAgB,EAAc,GAAa,GAA2B;CACpE,IAAM,IAAI,KAAK,IAAI,IAAI,EAAE,QAAQ,IAAK,EAAE,SAAS,EAAG;CAGpD,AAFA,EAAE,UAAU,GAAG,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,GACtC,EAAU,GAAG,CAAC,GACd,EAAiB,GAAG,GAAG,EAAgB,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC9D;AAEA,SAAgB,EAAY,GAAa,GAA2B;CAGlE,AAFA,EAAE,QAAQ,EAAE,QAAQ,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ,GAAG,EAAE,SAAS,CAAC,GAC9D,EAAU,GAAG,CAAC,GACd,EAAiB,GAAG,GAAG,EAAc,EAAE,QAAQ,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ,GAAG,EAAE,SAAS,CAAC,CAAC;AAC5F;AAEA,SAAgB,EAAY,GAAa,GAA2B;CAClE,IAAM,IAAK,EAAE,QAAQ,GAAG,IAAK,EAAE,SAAS,GAClC,IAAQ;EAAC;GAAE,GAAG;GAAI,GAAG;EAAE;EAAG;GAAE,GAAG,EAAE;GAAO,GAAG;EAAG;EAAG;GAAE,GAAG;GAAI,GAAG,EAAE;EAAO;EAAG;GAAE,GAAG;GAAG,GAAG;EAAG;CAAC;CAG9F,AAFA,EAAE,OAAO,GAAI,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAE,CAAC,CAAC,OAAO,GAAI,EAAE,MAAM,CAAC,CAAC,OAAO,GAAG,CAAE,CAAC,CAAC,UAAU,GACjF,EAAU,GAAG,CAAC,GACd,EAAiB,GAAG,GAAG,EAAW,CAAK,CAAC;AAC1C;AAEA,SAAgB,EAAa,GAAa,GAA2B;CACnE,IAAM,IAAI,EAAE,OAAO,IAAI,EAAE,QAAQ,IAAQ,IAAI;CAM7C,AALA,EAAE,OAAO,GAAG,CAAC,CAAC,CACX,OAAO,GAAG,CAAC,CAAC,CACZ,OAAO,GAAG,IAAI,CAAK,CAAC,CACpB,cAAc,IAAI,KAAM,IAAI,IAAQ,GAAG,IAAI,KAAM,GAAG,GAAG,IAAI,CAAK,CAAC,CACjE,UAAU,GACb,EAAU,GAAG,CAAC;CACd,IAAM,IAAuC;EAAC;GAAE,GAAG;GAAG,GAAG;EAAE;EAAG;GAAE,GAAG;GAAG,GAAG;EAAE;EAAG;GAAE,GAAG;GAAG,GAAG,IAAI;EAAM;CAAC;CAEpG,KAAK,IAAI,IAAI,GAAG,KAAK,IAAS,KAAK;EACjC,IAAM,IAAI,IAAI,IACR,IAAI,IAAI;EACd,EAAI,KAAK;GACP,GAAG,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,OAAQ,IAAI,IAAI,IAAI,KAAK,IAAI;GACrE,GAAG,IAAI,IAAI,KAAK,IAAI,KAAS,IAAI,IAAI,IAAI,KAAK,IAAI,IAAQ,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI;EACtG,CAAC;CACH;CAEA,AADA,EAAI,KAAK;EAAE,GAAG;EAAG,GAAG;CAAE,CAAC,GACvB,EAAiB,GAAG,GAAG,CAAG;AAC5B;AAEA,SAAgB,EAAkB,GAAa,GAA2B;CACxE,IAAM,IAAO,EAAE,QAAQ,IACjB,IAAQ;EAAC;GAAE,GAAG;GAAM,GAAG;EAAE;EAAG;GAAE,GAAG,EAAE;GAAO,GAAG;EAAE;EAAG;GAAE,GAAG,EAAE,QAAQ;GAAM,GAAG,EAAE;EAAO;EAAG;GAAE,GAAG;GAAG,GAAG,EAAE;EAAO;CAAC;CAGjH,AAFA,EAAE,OAAO,GAAM,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,GAAM,EAAE,MAAM,CAAC,CAAC,OAAO,GAAG,EAAE,MAAM,CAAC,CAAC,UAAU,GACpG,EAAU,GAAG,CAAC,GACd,EAAiB,GAAG,GAAG,EAAW,CAAK,CAAC;AAC1C;AAEA,SAAgB,EAAa,GAAa,GAA2B;CACnE,IAAM,IAAQ;EAAC;GAAE,GAAG,EAAE,QAAQ;GAAG,GAAG;EAAE;EAAG;GAAE,GAAG,EAAE;GAAO,GAAG,EAAE;EAAO;EAAG;GAAE,GAAG;GAAG,GAAG,EAAE;EAAO;CAAC;CAG3F,AAFA,EAAE,OAAO,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,OAAO,GAAG,EAAE,MAAM,CAAC,CAAC,UAAU,GACjF,EAAU,GAAG,CAAC,GACd,EAAiB,GAAG,GAAG,EAAW,CAAK,CAAC;AAC1C;AAEA,SAAgB,EAAc,GAAa,GAA2B;CACpE,IAAM,IAAQ,EAAE,QAAQ,KAClB,IAAQ;EAAC;GAAE,GAAG;GAAO,GAAG;EAAE;EAAG;GAAE,GAAG,EAAE,QAAQ;GAAO,GAAG;EAAE;EAAG;GAAE,GAAG,EAAE;GAAO,GAAG,EAAE;EAAO;EAAG;GAAE,GAAG;GAAG,GAAG,EAAE;EAAO;CAAC;CAGnH,AAFA,EAAE,OAAO,GAAO,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,GAAO,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,OAAO,GAAG,EAAE,MAAM,CAAC,CAAC,UAAU,GACtG,EAAU,GAAG,CAAC,GACd,EAAiB,GAAG,GAAG,EAAW,CAAK,CAAC;AAC1C;AAEA,SAAS,EAAY,GAAY,GAAY,GAAe,GAAY,GAAY,GAAqD;CACvI,IAAM,IAAyC,CAAC;CAChD,KAAK,IAAI,IAAI,GAAG,IAAI,GAAO,KAAK;EAC9B,IAAM,IAAK,KAAK,KAAK,IAAI,IAAK,IAAQ;EACtC,EAAM,KAAK;GAAE,GAAG,IAAK,IAAK,KAAK,IAAI,CAAC;GAAG,GAAG,IAAK,IAAK,KAAK,IAAI,CAAC;EAAE,CAAC;CACnE;CACA,OAAO;AACT;AAEA,SAAgB,EAAa,GAAa,GAA2B;CACnE,IAAM,IAAK,EAAE,QAAQ,GAAG,IAAK,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,GAAI,CAAE,GACxD,IAAQ,EAAY,GAAI,GAAI,GAAG,GAAG,GAAG,CAAC,KAAK,KAAK,CAAC;CACvD,KAAK,IAAI,IAAI,GAAG,IAAI,EAAM,QAAQ,KAChC,AAAI,MAAM,IAAG,EAAE,OAAO,EAAM,EAAE,CAAC,GAAG,EAAM,EAAE,CAAC,CAAC,IAAQ,EAAE,OAAO,EAAM,EAAE,CAAC,GAAG,EAAM,EAAE,CAAC,CAAC;CAIrF,AAFA,EAAE,UAAU,GACZ,EAAU,GAAG,CAAC,GACd,EAAiB,GAAG,GAAG,EAAW,CAAK,CAAC;AAC1C;AAEA,SAAgB,EAAY,GAAa,GAA2B;CAClE,IAAM,IAAK,EAAE,QAAQ,GAAG,IAAK,EAAE,SAAS,GAClC,IAAQ,EAAY,GAAI,GAAI,GAAG,GAAI,GAAI,CAAC,KAAK,KAAK,CAAC;CACzD,KAAK,IAAI,IAAI,GAAG,IAAI,EAAM,QAAQ,KAChC,AAAI,MAAM,IAAG,EAAE,OAAO,EAAM,EAAE,CAAC,GAAG,EAAM,EAAE,CAAC,CAAC,IAAQ,EAAE,OAAO,EAAM,EAAE,CAAC,GAAG,EAAM,EAAE,CAAC,CAAC;CAIrF,AAFA,EAAE,UAAU,GACZ,EAAU,GAAG,CAAC,GACd,EAAiB,GAAG,GAAG,EAAW,CAAK,CAAC;AAC1C;AAEA,SAAgB,EAAS,GAAa,GAA2B;CAC/D,IAAM,IAAK,EAAE,QAAQ,GAAG,IAAK,EAAE,SAAS,GAClC,IAAQ,KAAK,IAAI,GAAI,CAAE,GAAG,IAAQ,IAAQ,IAC1C,IAAyC,CAAC;CAChD,KAAK,IAAI,IAAI,GAAG,IAAI,IAAY,KAAK;EACnC,IAAM,IAAS,KAAK,KAAK,IAAK,IAAS,KAAK,KAAK,GAC3C,IAAI,IAAI,KAAM,IAAI,IAAQ;EAChC,EAAM,KAAK;GAAE,GAAG,IAAK,IAAI,KAAK,IAAI,CAAK;GAAG,GAAG,IAAK,IAAI,KAAK,IAAI,CAAK;EAAE,CAAC;CACzE;CACA,KAAK,IAAI,IAAI,GAAG,IAAI,EAAM,QAAQ,KAChC,AAAI,MAAM,IAAG,EAAE,OAAO,EAAM,EAAE,CAAC,GAAG,EAAM,EAAE,CAAC,CAAC,IAAQ,EAAE,OAAO,EAAM,EAAE,CAAC,GAAG,EAAM,EAAE,CAAC,CAAC;CAIrF,AAFA,EAAE,UAAU,GACZ,EAAU,GAAG,CAAC,GACd,EAAiB,GAAG,GAAG,EAAW,CAAK,CAAC;AAC1C;AAEA,SAAgB,EAAa,GAAa,GAA2B;CACnE,IAAM,IAAK,EAAE,QAAQ,GAAG,IAAK,EAAE,SAAS,GAClC,IAAQ,KAAK,IAAI,GAAI,CAAE,GAAG,IAAQ,IAAQ,KAC1C,IAAyC,CAAC;CAChD,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;EAC3B,IAAM,IAAS,KAAK,KAAK,IAAK,IAAI,KAAK,KAAK,GACtC,IAAI,IAAI,KAAM,IAAI,IAAQ;EAChC,EAAM,KAAK;GAAE,GAAG,IAAK,IAAI,KAAK,IAAI,CAAK;GAAG,GAAG,IAAK,IAAI,KAAK,IAAI,CAAK;EAAE,CAAC;CACzE;CACA,KAAK,IAAI,IAAI,GAAG,IAAI,EAAM,QAAQ,KAChC,AAAI,MAAM,IAAG,EAAE,OAAO,EAAM,EAAE,CAAC,GAAG,EAAM,EAAE,CAAC,CAAC,IAAQ,EAAE,OAAO,EAAM,EAAE,CAAC,GAAG,EAAM,EAAE,CAAC,CAAC;CAIrF,AAFA,EAAE,UAAU,GACZ,EAAU,GAAG,CAAC,GACd,EAAiB,GAAG,GAAG,EAAW,CAAK,CAAC;AAC1C;AAEA,SAAgB,EAAkB,GAAa,GAA2B;CACxE,IAAM,IAAQ;EAAC;GAAE,GAAG;GAAG,GAAG;EAAE;EAAG;GAAE,GAAG,EAAE;GAAO,GAAG,EAAE;EAAO;EAAG;GAAE,GAAG;GAAG,GAAG,EAAE;EAAO;CAAC;CAGjF,AAFA,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,OAAO,GAAG,EAAE,MAAM,CAAC,CAAC,UAAU,GACvE,EAAU,GAAG,CAAC,GACd,EAAiB,GAAG,GAAG,EAAW,CAAK,CAAC;AAC1C;AAEA,SAAgB,EAAW,GAAa,GAA2B;CACjE,IAAM,IAAO,KAAK,IAAI,EAAE,OAAO,EAAE,MAAM,IAAI,IACrC,IAAQ;EACZ;GAAE,GAAG;GAAG,GAAG;EAAE;EAAG;GAAE,GAAG,EAAE;GAAO,GAAG;EAAE;EAAG;GAAE,GAAG,EAAE;GAAO,GAAG;EAAK;EAC5D;GAAE,GAAG;GAAM,GAAG;EAAK;EAAG;GAAE,GAAG;GAAM,GAAG,EAAE;EAAO;EAAG;GAAE,GAAG;GAAG,GAAG,EAAE;EAAO;CACtE;CAIA,AAHA,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAI,CAAC,CACpD,OAAO,GAAM,CAAI,CAAC,CAAC,OAAO,GAAM,EAAE,MAAM,CAAC,CAAC,OAAO,GAAG,EAAE,MAAM,CAAC,CAAC,UAAU,GAC3E,EAAU,GAAG,CAAC,GACd,EAAiB,GAAG,GAAG,EAAW,CAAK,CAAC;AAC1C;AAEA,SAAgB,EAAc,GAAa,GAA2B;CACpE,IAAM,IAAI,KAAK,IAAI,GAAG,EAAE,QAAQ,KAAM,EAAE,SAAS,GAAI;CAErD,AADA,EAAE,UAAU,GAAG,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,GAClC,EAAE,QAAQ,EAAE,SAAS,iBACvB,EAAE,KAAK;EAAE,OAAO,EAAE;EAAM,OAAO;CAAK,CAAC;CAEvC,IAAM,IAAS,EAAE,eAAe;CAChC,IAAI,MAAW,UAAU,EAAE,UAAU,EAAE,WAAW,iBAAiB,EAAE,cAAc,GAAG;EACpF,IAAM,IAAO,EAAU,GAAQ,EAAE,WAAW;EAC5C,IAAI,GAAM;GACR,IAAM,IAAS,MAAW,YAAa,EAAE,cAAc,IAAK;GAC5D,EAAe,GAAG,EAAgB,EAAE,OAAO,EAAE,QAAQ,CAAC,GAAG,GAAM,GAAQ,EAAE,QAAQ,EAAE,WAAW;EAChG,OACE,EAAE,OAAO;GAAE,OAAO,EAAE;GAAQ,OAAO,EAAE;EAAY,CAAC;CAEtD;AACF;AAEA,IAAa,IAAoB,GAKpB,IAAsC;CAAC;CAAO;CAAS;CAAU;AAAM,GAIvE,oBAAoB,IAAI,IAAY;CAC/C;CAAa;CAAkB;CAAgB;CAAgB;CAC/D;CAAsB;CAAkB;CAAa;CAAa;AACpE,CAAC;AAID,SAAgB,EAAuB,GAAoB,GAAwB;CACjF,IAAI,MAAS,KAAA,KAAa,CAAC,EAAkB,IAAI,CAAI,GAAG,OAAO;CAC/D,IAAM,IAAQ,EAAK;CAEnB,OADK,IACE,EAAkB,MAAM,MAAS;EACtC,IAAM,IAAO,EAAM;EACnB,OAAO,CAAC,CAAC,MACH,EAAK,YAAY,MAAS,EAAK,UAAU,KAAA,KAAa,EAAK,UAAU,KAAA;CAC7E,CAAC,IALkB;AAMrB;AAIA,SAAS,EAAiB,GAAc,GAAW,GAAmB;CACpE,QAAQ,GAAR;EACE,KAAK,kBAAkB,OAAO,KAAK,IAAI,IAAI,IAAI,IAAK,IAAI,EAAG;EAC3D,KAAK,aAAa,OAAO;EACzB,KAAK;EACL,KAAK,iBAAiB,OAAO,KAAK,IAAI,GAAG,IAAI,KAAM,IAAI,GAAI;EAC3D,SAAS,OAAO;CAClB;AACF;AAEA,IAAM,IAAW;AAMjB,SAAgB,EACd,GACA,GACA,GACA,GACW;CACX,IAAM,IAAkB,CAAC,GACnB,KAAQ,GAAW,MAAc,EAAK,KAAK;EAAE,MAAM;EAAK;EAAG;CAAE,CAAC,GAC9D,KACJ,GAAa,GAAa,GAAa,GAAa,GAAW,MAC5D,EAAK,KAAK;EAAE,MAAM;EAAK,MAAM;EAAK,MAAM;EAAK,MAAM;EAAK,MAAM;EAAK;EAAG;CAAE,CAAC,GAExE,IAAI,EAAiB,GAAM,GAAG,CAAC;CACrC,IAAI,KAAK,IAAK;EAIZ,IAAM,IAAI,IAAW;EACrB,QAAQ,GAAR;GACE,KAAK;IAGH,AAFA,EAAK,KAAK;KAAE,MAAM;KAAK,GAAG;KAAG,GAAG;IAAE,CAAC,GACnC,EAAM,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC,GAC9B,EAAK,IAAI,GAAG,CAAC;IACb;GACF,KAAK;IAGH,AAFA,EAAK,KAAK;KAAE,MAAM;KAAK,GAAG,IAAI;KAAG,GAAG;IAAE,CAAC,GACvC,EAAM,IAAI,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC,GAClC,EAAK,GAAG,IAAI,CAAC;IACb;GACF,KAAK;IAGH,AAFA,EAAK,KAAK;KAAE,MAAM;KAAK,GAAG;KAAG,GAAG,IAAI;IAAE,CAAC,GACvC,EAAM,GAAG,IAAI,IAAI,GAAG,IAAI,IAAI,GAAG,GAAG,IAAI,GAAG,CAAC,GAC1C,EAAK,GAAG,CAAC;IACT;GACF,KAAK,QAGH,AAFA,EAAK,KAAK;IAAE,MAAM;IAAK,GAAG;IAAG,GAAG;GAAE,CAAC,GACnC,EAAM,IAAI,GAAG,GAAG,GAAG,IAAI,IAAI,GAAG,GAAG,IAAI,CAAC,GACtC,EAAK,GAAG,CAAC;EAEb;EACA,OAAO;CACT;CAEA,IAAI,MAAS,gBAAgB;EAG3B,IAAM,IAAK,IAAI,GAAG,IAAK,IAAI,GAAG,IAAK,IAAI,GAAG,IAAK,IAAI,GAO7C,CAAC,GAAI,KAAM;GALf,KAAK,CAAC,KAAK,KAAK,MAAM,KAAK,KAAK,IAAI;GACpC,OAAO,CAAC,KAAK,KAAK,MAAM,KAAK,KAAK,IAAI;GACtC,QAAQ,CAAC,KAAK,KAAK,KAAM,KAAK,KAAK,GAAI;GACvC,MAAM,CAAC,KAAK,KAAK,KAAM,KAAK,KAAK,IAAI;EAEtB,EAAO,IAClB,IAAM,IAAK,IAAK,KAAK,IAAI,CAAE,GAAG,IAAM,IAAK,IAAK,KAAK,IAAI,CAAE,GACzD,IAAM,IAAK,IAAK,KAAK,IAAI,CAAE,GAAG,IAAM,IAAK,IAAK,KAAK,IAAI,CAAE;EAO/D,OANA,EAAK,KAAK;GAAE,MAAM;GAAK,GAAG;GAAK,GAAG;EAAI,CAAC,GACvC,EACE,IAAM,IAAW,IAAK,KAAK,IAAI,CAAE,GAAG,IAAM,IAAW,IAAK,KAAK,IAAI,CAAE,GACrE,IAAM,IAAW,IAAK,KAAK,IAAI,CAAE,GAAG,IAAM,IAAW,IAAK,KAAK,IAAI,CAAE,GACrE,GAAK,CACP,GACO;CACT;CAEA,IAAI,MAAS,iBAAiB;EAC5B,IAAM,IAAQ,IAAI;EAclB,OAbI,MAAS,SACX,EAAK,KAAK;GAAE,MAAM;GAAK,GAAG;GAAG,GAAG;EAAE,CAAC,GACnC,EAAK,GAAG,CAAC,KACA,MAAS,WAClB,EAAK,KAAK;GAAE,MAAM;GAAK,GAAG;GAAG,GAAG;EAAE,CAAC,GACnC,EAAK,GAAG,IAAI,CAAK,KACR,MAAS,YAClB,EAAK,KAAK;GAAE,MAAM;GAAK,GAAG;GAAG,GAAG,IAAI;EAAM,CAAC,GAC3C,EAAM,IAAI,KAAM,IAAI,IAAQ,GAAG,IAAI,KAAM,GAAG,GAAG,IAAI,CAAK,MAExD,EAAK,KAAK;GAAE,MAAM;GAAK,GAAG;GAAG,GAAG,IAAI;EAAM,CAAC,GAC3C,EAAK,GAAG,CAAC,IAEJ;CACT;CAGA,IAAI,GAA8B,GAA8B,GAA8B;CAC9F,IAAI,MAAS,gBAAgB;EAC3B,IAAM,IAAK,IAAI,GAAG,IAAK,IAAI;EACuC,AAAlE,IAAK;GAAE,GAAG;GAAI,GAAG;EAAE,GAAG,IAAK;GAAE,GAAG;GAAG,GAAG;EAAG,GAAG,IAAK;GAAE,GAAG;GAAI,GAAG;EAAE,GAAG,IAAK;GAAE,GAAG;GAAG,GAAG;EAAG;CACvF,OAAO,IAAI,MAAS,sBAAsB;EACxC,IAAM,IAAO,IAAI;EACwD,AAAzE,IAAK;GAAE,GAAG;GAAM,GAAG;EAAE,GAAG,IAAK;GAAE,GAAG;GAAG,GAAG;EAAE,GAAG,IAAK;GAAE,GAAG,IAAI;GAAM,GAAG;EAAE,GAAG,IAAK;GAAE,GAAG;GAAG,GAAG;EAAE;CAC7F,OAAO,IAAI,MAAS,kBAAkB;EACpC,IAAM,IAAQ,IAAI;EACyD,AAA3E,IAAK;GAAE,GAAG;GAAO,GAAG;EAAE,GAAG,IAAK;GAAE,GAAG,IAAI;GAAO,GAAG;EAAE,GAAG,IAAK;GAAE,GAAG;GAAG,GAAG;EAAE,GAAG,IAAK;GAAE,GAAG;GAAG,GAAG;EAAE;CAC/F,OACiE,AAA/D,IAAK;EAAE,GAAG;EAAG,GAAG;CAAE,GAAG,IAAK;EAAE,GAAG;EAAG,GAAG;CAAE,GAAG,IAAK;EAAE,GAAG;EAAG,GAAG;CAAE,GAAG,IAAK;EAAE,GAAG;EAAG,GAAG;CAAE;CASnF,IAAM,CAAC,GAAG,KAAK;EALb,KAAK,CAAC,GAAI,CAAE;EACZ,OAAO,CAAC,GAAI,CAAE;EACd,QAAQ,CAAC,GAAI,CAAE;EACf,MAAM,CAAC,GAAI,CAAE;CAEA,EAAM;CAGrB,OAFA,EAAK,KAAK;EAAE,MAAM;EAAK,GAAG,EAAE;EAAG,GAAG,EAAE;CAAE,CAAC,GACvC,EAAK,EAAE,GAAG,EAAE,CAAC,GACN;AACT;AAMA,SAAgB,EACd,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACM;CACF,UAAgB,QACpB,KAAK,IAAM,KAAQ,GAAmB;EACpC,IAAM,IAA2C,IAAQ;EACzD,IAAI,GAAM,YAAY,IAAO;EAC7B,IAAM,IAAQ,EAAkB,GAAM,OAAO,CAAY,KAAK,GACxD,IAAc,GAAM,SAAS;EACnC,IAAI,CAAC,KAAS,MAAU,iBAAiB,EAAE,IAAc,IAAI;EAC7D,IAAM,IAAO,EAAwB,GAAM,GAAO,GAAQ,CAAI,GACxD,IAAO,EAAU,GAAa,CAAW;EAC/C,IAAI,GAGF,AADA,EAAe,GAAG,GAAM,GADT,MAAgB,YAAY,IAAa,CACpB,GACpC,EAAE,OAAO;GAAE;GAAO,OAAO;GAAa,KAAK;EAAiB,CAAC;OACxD;GACL,KAAK,IAAM,KAAO,GAChB,QAAQ,EAAI,MAAZ;IACE,KAAK;KAAK,EAAE,OAAO,EAAI,GAAG,EAAI,CAAC;KAAG;IAClC,KAAK;KAAK,EAAE,OAAO,EAAI,GAAG,EAAI,CAAC;KAAG;IAClC,KAAK;KAAK,EAAE,cAAc,EAAI,MAAO,EAAI,MAAO,EAAI,MAAO,EAAI,MAAO,EAAI,GAAG,EAAI,CAAC;KAAG;IACrF,KAAK,KAAK,EAAE,iBAAiB,EAAI,MAAO,EAAI,MAAO,EAAI,GAAG,EAAI,CAAC;GACjE;GAEF,EAAE,OAAO;IAAE;IAAO,OAAO;GAAY,CAAC;EACxC;CACF;AACF;AAGA,IAAa,IAA2E;CACtF,WAAW;CACX,gBAAgB;CAChB,cAAc;CACd,cAAc;CACd,eAAe;CACf,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,eAAe;CACf,cAAc;CACd,WAAW;CACX,eAAe;CACf,oBAAoB;CACpB,aAAa;CACb,WAAW;CACX,WAAW;CACX,eAAe;CACf,UAAU;AACZ"}
|
|
1
|
+
{"version":3,"file":"shapes.js","names":[],"sources":["../../../../../src/components/pro/Flow/nodes/shapes.ts"],"sourcesContent":["import { Graphics } from 'pixi.js';\nimport type { FlowShapeType, FlowNodeData, FlowBorderSides, FlowBorderSideOverride } from '../types';\nimport { drawDashedPath, type PathSeg } from '../utils/dashedLine';\nimport { resolveThemeColor } from '../utils/themeColor';\n\nexport interface ShapeDrawOptions {\n width: number;\n height: number;\n fill: string;\n stroke: string;\n strokeWidth: number;\n borderStyle?: 'solid' | 'dashed' | 'dotted' | 'dynamic' | 'none';\n dashOffset?: number;\n}\n\nfunction parseDash(style: string | undefined, strokeWidth: number): number[] | undefined {\n if (!style || style === 'solid') return undefined;\n if (style === 'dynamic') return [strokeWidth * 4, strokeWidth * 3];\n if (style === 'dashed') return [strokeWidth * 4, strokeWidth * 2];\n if (style === 'dotted') return [strokeWidth, strokeWidth * 2];\n return undefined;\n}\n\n/**\n * Sample a rectangle's outline as points for dashed border.\n */\nfunction sampleRect(w: number, h: number, step = 3): Array<{ x: number; y: number }> {\n const pts: Array<{ x: number; y: number }> = [];\n for (let x = 0; x <= w; x += step) pts.push({ x, y: 0 });\n for (let y = step; y <= h; y += step) pts.push({ x: w, y });\n for (let x = w - step; x >= 0; x -= step) pts.push({ x, y: h });\n for (let y = h - step; y > 0; y -= step) pts.push({ x: 0, y });\n pts.push({ x: 0, y: 0 });\n return pts;\n}\n\n/**\n * Sample a rounded rectangle outline as points.\n */\nfunction sampleRoundRect(w: number, h: number, r: number, step = 3): Array<{ x: number; y: number }> {\n const pts: Array<{ x: number; y: number }> = [];\n const cornerSamples = Math.max(4, Math.ceil((Math.PI / 2) * r / step));\n const addCorner = (cx: number, cy: number, startAngle: number) => {\n for (let i = 0; i <= cornerSamples; i++) {\n const a = startAngle + (Math.PI / 2) * (i / cornerSamples);\n pts.push({ x: cx + r * Math.cos(a), y: cy + r * Math.sin(a) });\n }\n };\n addCorner(w - r, r, -Math.PI / 2);\n addCorner(w - r, h - r, 0);\n addCorner(r, h - r, Math.PI / 2);\n addCorner(r, r, Math.PI);\n if (pts.length > 0) pts.push(pts[0]);\n return pts;\n}\n\n/**\n * Sample an ellipse outline.\n */\nfunction sampleEllipse(cx: number, cy: number, rx: number, ry: number, samples = 60): Array<{ x: number; y: number }> {\n const pts: Array<{ x: number; y: number }> = [];\n for (let i = 0; i <= samples; i++) {\n const a = (Math.PI * 2 * i) / samples;\n pts.push({ x: cx + rx * Math.cos(a), y: cy + ry * Math.sin(a) });\n }\n return pts;\n}\n\n/**\n * Draw dashed polyline onto graphics.\n */\nfunction drawDashedPoly(g: Graphics, pts: Array<{ x: number; y: number }>, dash: number[], offset: number, color: string, width: number): void {\n if (pts.length < 2) return;\n const dists = [0];\n for (let i = 1; i < pts.length; i++) {\n dists.push(dists[i - 1] + Math.hypot(pts[i].x - pts[i - 1].x, pts[i].y - pts[i - 1].y));\n }\n const total = dists[dists.length - 1];\n if (total < 1) return;\n const patternLen = dash[0] + dash[1];\n let pos = -(((offset % patternLen) + patternLen) % patternLen);\n let drawing = true;\n\n const lerp = (d: number) => {\n if (d <= 0) return pts[0];\n if (d >= total) return pts[pts.length - 1];\n let lo = 0, hi = dists.length - 1;\n while (lo < hi - 1) { const m = (lo + hi) >> 1; if (dists[m] <= d) lo = m; else hi = m; }\n const t = dists[hi] - dists[lo] > 0 ? (d - dists[lo]) / (dists[hi] - dists[lo]) : 0;\n return { x: pts[lo].x + (pts[hi].x - pts[lo].x) * t, y: pts[lo].y + (pts[hi].y - pts[lo].y) * t };\n };\n\n while (pos < total) {\n const segLen = drawing ? dash[0] : dash[1];\n const start = Math.max(pos, 0);\n const end = Math.min(pos + segLen, total);\n if (drawing && end > start) {\n const p0 = lerp(start);\n g.moveTo(p0.x, p0.y);\n for (let d = start + 2; d < end; d += 2) {\n const p = lerp(d);\n g.lineTo(p.x, p.y);\n }\n const pe = lerp(end);\n g.lineTo(pe.x, pe.y);\n }\n pos += segLen;\n drawing = !drawing;\n }\n g.stroke({ color, width, cap: 'round' as const });\n}\n\nfunction fillShape(g: Graphics, o: ShapeDrawOptions) {\n if (o.fill && o.fill !== 'transparent') {\n g.fill({ color: o.fill });\n }\n if (o.borderStyle === 'none') return;\n if (o.stroke && o.stroke !== 'transparent' && o.strokeWidth > 0) {\n const dash = parseDash(o.borderStyle, o.strokeWidth);\n if (dash) {\n // Dashed/dotted/dynamic: don't stroke the shape path, we'll draw dashed separately\n } else {\n g.stroke({ color: o.stroke, width: o.strokeWidth });\n }\n }\n}\n\n/**\n * After fillShape, draw dashed border if needed.\n * Pass shape-specific outline points.\n */\nfunction drawDashedBorder(g: Graphics, o: ShapeDrawOptions, outlinePts: Array<{ x: number; y: number }>) {\n const dash = parseDash(o.borderStyle, o.strokeWidth);\n if (!dash || !o.stroke || o.stroke === 'transparent' || o.strokeWidth <= 0) return;\n const offset = o.borderStyle === 'dynamic' ? (o.dashOffset ?? 0) : 0;\n drawDashedPoly(g, outlinePts, dash, offset, o.stroke, o.strokeWidth);\n}\n\n/** Draw only a rounded-rectangle border, without leaving a base path that can\n * be picked up by the dashed stroke. Useful when fill and border are rendered\n * independently, as they are for SVG icon nodes. */\nexport function drawRoundRectBorder(g: Graphics, o: ShapeDrawOptions, radius?: number): void {\n if (o.borderStyle === 'none' || !o.stroke || o.stroke === 'transparent' || o.strokeWidth <= 0) return;\n const r = radius ?? Math.min(14, o.width * 0.1, o.height * 0.1);\n const dash = parseDash(o.borderStyle, o.strokeWidth);\n if (dash) {\n const offset = o.borderStyle === 'dynamic' ? (o.dashOffset ?? 0) : 0;\n drawDashedPoly(g, sampleRoundRect(o.width, o.height, r), dash, offset, o.stroke, o.strokeWidth);\n } else {\n g.roundRect(0, 0, o.width, o.height, r).stroke({ color: o.stroke, width: o.strokeWidth });\n }\n}\n\nfunction polyPoints(verts: Array<{ x: number; y: number }>): Array<{ x: number; y: number }> {\n return [...verts, verts[0]];\n}\n\nexport function drawRect(g: Graphics, o: ShapeDrawOptions): void {\n g.rect(0, 0, o.width, o.height);\n fillShape(g, o);\n drawDashedBorder(g, o, sampleRect(o.width, o.height));\n}\n\nexport function drawRoundRect(g: Graphics, o: ShapeDrawOptions): void {\n const r = Math.min(14, o.width * 0.1, o.height * 0.1);\n g.roundRect(0, 0, o.width, o.height, r);\n fillShape(g, o);\n drawDashedBorder(g, o, sampleRoundRect(o.width, o.height, r));\n}\n\nexport function drawEllipse(g: Graphics, o: ShapeDrawOptions): void {\n g.ellipse(o.width / 2, o.height / 2, o.width / 2, o.height / 2);\n fillShape(g, o);\n drawDashedBorder(g, o, sampleEllipse(o.width / 2, o.height / 2, o.width / 2, o.height / 2));\n}\n\nexport function drawDiamond(g: Graphics, o: ShapeDrawOptions): void {\n const cx = o.width / 2, cy = o.height / 2;\n const verts = [{ x: cx, y: 0 }, { x: o.width, y: cy }, { x: cx, y: o.height }, { x: 0, y: cy }];\n g.moveTo(cx, 0).lineTo(o.width, cy).lineTo(cx, o.height).lineTo(0, cy).closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawDocument(g: Graphics, o: ShapeDrawOptions): void {\n const w = o.width, h = o.height, curve = h * 0.15;\n g.moveTo(0, 0)\n .lineTo(w, 0)\n .lineTo(w, h - curve)\n .bezierCurveTo(w * 0.75, h - curve * 2, w * 0.25, h, 0, h - curve)\n .closePath();\n fillShape(g, o);\n const pts: Array<{ x: number; y: number }> = [{ x: 0, y: 0 }, { x: w, y: 0 }, { x: w, y: h - curve }];\n const samples = 20;\n for (let i = 1; i <= samples; i++) {\n const t = i / samples;\n const u = 1 - t;\n pts.push({\n x: u * u * u * w + 3 * u * u * t * (w * 0.75) + 3 * u * t * t * (w * 0.25),\n y: u * u * u * (h - curve) + 3 * u * u * t * (h - curve * 2) + 3 * u * t * t * h + t * t * t * (h - curve),\n });\n }\n pts.push({ x: 0, y: 0 });\n drawDashedBorder(g, o, pts);\n}\n\nexport function drawParallelogram(g: Graphics, o: ShapeDrawOptions): void {\n const skew = o.width * 0.2;\n const verts = [{ x: skew, y: 0 }, { x: o.width, y: 0 }, { x: o.width - skew, y: o.height }, { x: 0, y: o.height }];\n g.moveTo(skew, 0).lineTo(o.width, 0).lineTo(o.width - skew, o.height).lineTo(0, o.height).closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawTriangle(g: Graphics, o: ShapeDrawOptions): void {\n const verts = [{ x: o.width / 2, y: 0 }, { x: o.width, y: o.height }, { x: 0, y: o.height }];\n g.moveTo(o.width / 2, 0).lineTo(o.width, o.height).lineTo(0, o.height).closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawTrapezoid(g: Graphics, o: ShapeDrawOptions): void {\n const inset = o.width * 0.15;\n const verts = [{ x: inset, y: 0 }, { x: o.width - inset, y: 0 }, { x: o.width, y: o.height }, { x: 0, y: o.height }];\n g.moveTo(inset, 0).lineTo(o.width - inset, 0).lineTo(o.width, o.height).lineTo(0, o.height).closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nfunction regularPoly(cx: number, cy: number, sides: number, rx: number, ry: number, startAngle: number): Array<{ x: number; y: number }> {\n const verts: Array<{ x: number; y: number }> = [];\n for (let i = 0; i < sides; i++) {\n const a = (Math.PI * 2 * i) / sides + startAngle;\n verts.push({ x: cx + rx * Math.cos(a), y: cy + ry * Math.sin(a) });\n }\n return verts;\n}\n\nexport function drawPentagon(g: Graphics, o: ShapeDrawOptions): void {\n const cx = o.width / 2, cy = o.height / 2, r = Math.min(cx, cy);\n const verts = regularPoly(cx, cy, 5, r, r, -Math.PI / 2);\n for (let i = 0; i < verts.length; i++) {\n if (i === 0) g.moveTo(verts[i].x, verts[i].y); else g.lineTo(verts[i].x, verts[i].y);\n }\n g.closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawHexagon(g: Graphics, o: ShapeDrawOptions): void {\n const cx = o.width / 2, cy = o.height / 2;\n const verts = regularPoly(cx, cy, 6, cx, cy, -Math.PI / 6);\n for (let i = 0; i < verts.length; i++) {\n if (i === 0) g.moveTo(verts[i].x, verts[i].y); else g.lineTo(verts[i].x, verts[i].y);\n }\n g.closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawStar(g: Graphics, o: ShapeDrawOptions): void {\n const cx = o.width / 2, cy = o.height / 2;\n const outer = Math.min(cx, cy), inner = outer * 0.4, points = 5;\n const verts: Array<{ x: number; y: number }> = [];\n for (let i = 0; i < points * 2; i++) {\n const angle = (Math.PI * i) / points - Math.PI / 2;\n const r = i % 2 === 0 ? outer : inner;\n verts.push({ x: cx + r * Math.cos(angle), y: cy + r * Math.sin(angle) });\n }\n for (let i = 0; i < verts.length; i++) {\n if (i === 0) g.moveTo(verts[i].x, verts[i].y); else g.lineTo(verts[i].x, verts[i].y);\n }\n g.closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawHexagram(g: Graphics, o: ShapeDrawOptions): void {\n const cx = o.width / 2, cy = o.height / 2;\n const outer = Math.min(cx, cy), inner = outer * 0.55;\n const verts: Array<{ x: number; y: number }> = [];\n for (let i = 0; i < 12; i++) {\n const angle = (Math.PI * i) / 6 - Math.PI / 2;\n const r = i % 2 === 0 ? outer : inner;\n verts.push({ x: cx + r * Math.cos(angle), y: cy + r * Math.sin(angle) });\n }\n for (let i = 0; i < verts.length; i++) {\n if (i === 0) g.moveTo(verts[i].x, verts[i].y); else g.lineTo(verts[i].x, verts[i].y);\n }\n g.closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawRightTriangle(g: Graphics, o: ShapeDrawOptions): void {\n const verts = [{ x: 0, y: 0 }, { x: o.width, y: o.height }, { x: 0, y: o.height }];\n g.moveTo(0, 0).lineTo(o.width, o.height).lineTo(0, o.height).closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawCorner(g: Graphics, o: ShapeDrawOptions): void {\n const half = Math.min(o.width, o.height) * 0.4;\n const verts = [\n { x: 0, y: 0 }, { x: o.width, y: 0 }, { x: o.width, y: half },\n { x: half, y: half }, { x: half, y: o.height }, { x: 0, y: o.height },\n ];\n g.moveTo(0, 0).lineTo(o.width, 0).lineTo(o.width, half)\n .lineTo(half, half).lineTo(half, o.height).lineTo(0, o.height).closePath();\n fillShape(g, o);\n drawDashedBorder(g, o, polyPoints(verts));\n}\n\nexport function drawFlowGroup(g: Graphics, o: ShapeDrawOptions): void {\n const r = Math.min(6, o.width * 0.04, o.height * 0.04);\n g.roundRect(0, 0, o.width, o.height, r);\n if (o.fill && o.fill !== 'transparent') {\n g.fill({ color: o.fill, alpha: 0.08 });\n }\n const border = o.borderStyle ?? 'dashed';\n if (border !== 'none' && o.stroke && o.stroke !== 'transparent' && o.strokeWidth > 0) {\n const dash = parseDash(border, o.strokeWidth);\n if (dash) {\n const offset = border === 'dynamic' ? (o.dashOffset ?? 0) : 0;\n drawDashedPoly(g, sampleRoundRect(o.width, o.height, r), dash, offset, o.stroke, o.strokeWidth);\n } else {\n g.stroke({ color: o.stroke, width: o.strokeWidth });\n }\n }\n}\n\nexport const drawGeometryGroup = drawFlowGroup;\n\n/* ─── Per-side borders (top / right / bottom / left) ─────────────────── */\n\nexport type BorderSideName = 'top' | 'right' | 'bottom' | 'left';\nexport const BORDER_SIDE_NAMES: BorderSideName[] = ['top', 'right', 'bottom', 'left'];\n\n/** Shape types whose geometry has four well-defined sides. Other shapes ignore\n * `borderSides` and keep a full outline. */\nexport const BORDER_SIDE_TYPES = new Set<string>([\n 'shapeRect', 'shapeRoundRect', 'shapeEllipse', 'shapeDiamond', 'shapeDocument',\n 'shapeParallelogram', 'shapeTrapezoid', 'mediaNode', 'flowGroup', 'geometryGroup',\n]);\n\n/** True when `borderSides` carries at least one effective override AND the\n * shape type supports per-side borders. */\nexport function hasBorderSideOverrides(data: FlowNodeData, type?: string): boolean {\n if (type !== undefined && !BORDER_SIDE_TYPES.has(type)) return false;\n const sides = data.borderSides;\n if (!sides) return false;\n return BORDER_SIDE_NAMES.some((name) => {\n const side = sides[name];\n return !!side\n && (side.visible === false || side.color !== undefined || side.width !== undefined);\n });\n}\n\n/** Corner radius used by each shape's own drawer, so side segments line up\n * exactly with the (possibly hidden) full outline. */\nfunction borderSideRadius(type: string, w: number, h: number): number {\n switch (type) {\n case 'shapeRoundRect': return Math.min(14, w * 0.1, h * 0.1);\n case 'mediaNode': return 6;\n case 'flowGroup':\n case 'geometryGroup': return Math.min(6, w * 0.04, h * 0.04);\n default: return 0;\n }\n}\n\nconst BEZIER_K = 0.5522847498; // kappa for a 90° arc approximation\n\n/** Build the drawable path of one side of the shape. Corners are owned by the\n * side that starts there (clockwise): top owns the top-left arc, right the\n * top-right arc, and so on — with uniform styling the four sides reconstruct\n * the full outline seamlessly. */\nexport function buildBorderSideSegments(\n type: string,\n w: number,\n h: number,\n side: BorderSideName,\n): PathSeg[] {\n const segs: PathSeg[] = [];\n const line = (x: number, y: number) => segs.push({ type: 'L', x, y });\n const cubic = (\n c1x: number, c1y: number, c2x: number, c2y: number, x: number, y: number,\n ) => segs.push({ type: 'C', cp1x: c1x, cp1y: c1y, cp2x: c2x, cp2y: c2y, x, y });\n\n const r = borderSideRadius(type, w, h);\n if (r >= 0.5) {\n // Rounded rect family (shapeRoundRect / mediaNode / group frames): each\n // side owns its starting corner arc (clockwise), so uniform styling\n // reconstructs the full rounded outline seamlessly.\n const k = BEZIER_K * r;\n switch (side) {\n case 'top':\n segs.push({ type: 'M', x: 0, y: r });\n cubic(0, r - k, r - k, 0, r, 0);\n line(w - r, 0);\n break;\n case 'right':\n segs.push({ type: 'M', x: w - r, y: 0 });\n cubic(w - r + k, 0, w, r - k, w, r);\n line(w, h - r);\n break;\n case 'bottom':\n segs.push({ type: 'M', x: w, y: h - r });\n cubic(w, h - r + k, w - r + k, h, w - r, h);\n line(r, h);\n break;\n case 'left':\n segs.push({ type: 'M', x: r, y: h });\n cubic(r - k, h, 0, h - r + k, 0, h - r);\n line(0, r);\n break;\n }\n return segs;\n }\n\n if (type === 'shapeEllipse') {\n // Split the outline at the 45° diagonals so each side is the arc centered\n // on its direction (top arc spans the top, etc.).\n const cx = w / 2, cy = h / 2, rx = w / 2, ry = h / 2;\n const angles: Record<BorderSideName, [number, number]> = {\n top: [Math.PI * 1.25, Math.PI * 1.75],\n right: [Math.PI * 1.75, Math.PI * 2.25],\n bottom: [Math.PI * 0.25, Math.PI * 0.75],\n left: [Math.PI * 0.75, Math.PI * 1.25],\n };\n const [a0, a1] = angles[side];\n const p0x = cx + rx * Math.cos(a0), p0y = cy + ry * Math.sin(a0);\n const p3x = cx + rx * Math.cos(a1), p3y = cy + ry * Math.sin(a1);\n segs.push({ type: 'M', x: p0x, y: p0y });\n cubic(\n p0x - BEZIER_K * rx * Math.sin(a0), p0y + BEZIER_K * ry * Math.cos(a0),\n p3x + BEZIER_K * rx * Math.sin(a1), p3y - BEZIER_K * ry * Math.cos(a1),\n p3x, p3y,\n );\n return segs;\n }\n\n if (type === 'shapeDocument') {\n const curve = h * 0.15;\n if (side === 'top') {\n segs.push({ type: 'M', x: 0, y: 0 });\n line(w, 0);\n } else if (side === 'right') {\n segs.push({ type: 'M', x: w, y: 0 });\n line(w, h - curve);\n } else if (side === 'bottom') {\n segs.push({ type: 'M', x: w, y: h - curve });\n cubic(w * 0.75, h - curve * 2, w * 0.25, h, 0, h - curve);\n } else {\n segs.push({ type: 'M', x: 0, y: h - curve });\n line(0, 0);\n }\n return segs;\n }\n\n // Quadrilaterals (rect / diamond / parallelogram / trapezoid).\n let v0: { x: number; y: number }, v1: { x: number; y: number }, v2: { x: number; y: number }, v3: { x: number; y: number };\n if (type === 'shapeDiamond') {\n const cx = w / 2, cy = h / 2;\n v0 = { x: cx, y: 0 }; v1 = { x: w, y: cy }; v2 = { x: cx, y: h }; v3 = { x: 0, y: cy };\n } else if (type === 'shapeParallelogram') {\n const skew = w * 0.2;\n v0 = { x: skew, y: 0 }; v1 = { x: w, y: 0 }; v2 = { x: w - skew, y: h }; v3 = { x: 0, y: h };\n } else if (type === 'shapeTrapezoid') {\n const inset = w * 0.15;\n v0 = { x: inset, y: 0 }; v1 = { x: w - inset, y: 0 }; v2 = { x: w, y: h }; v3 = { x: 0, y: h };\n } else {\n v0 = { x: 0, y: 0 }; v1 = { x: w, y: 0 }; v2 = { x: w, y: h }; v3 = { x: 0, y: h };\n }\n\n const edges: Record<BorderSideName, [{ x: number; y: number }, { x: number; y: number }]> = {\n top: [v0, v1],\n right: [v1, v2],\n bottom: [v2, v3],\n left: [v3, v0],\n };\n const [a, b] = edges[side];\n segs.push({ type: 'M', x: a.x, y: a.y });\n line(b.x, b.y);\n return segs;\n}\n\n/** Draw the four sides of a node independently, honoring per-side color /\n * width / visibility overrides (falling back to the node's defaults). The\n * node's `borderStyle` (solid / dashed / dotted / dynamic) applies to every\n * side. `defaultColor` is the node's (already theme-resolved) stroke. */\nexport function drawBorderSides(\n g: Graphics,\n type: string,\n width: number,\n height: number,\n sides: FlowBorderSides | undefined,\n defaultColor: string,\n defaultWidth: number,\n borderStyle: string | undefined,\n dashOffset: number,\n): void {\n if (borderStyle === 'none') return;\n for (const name of BORDER_SIDE_NAMES) {\n const side: FlowBorderSideOverride | undefined = sides?.[name];\n if (side?.visible === false) continue;\n const color = resolveThemeColor(side?.color, defaultColor) || defaultColor;\n const strokeWidth = side?.width ?? defaultWidth;\n if (!color || color === 'transparent' || !(strokeWidth > 0)) continue;\n const segs = buildBorderSideSegments(type, width, height, name);\n const dash = parseDash(borderStyle, strokeWidth);\n if (dash) {\n const offset = borderStyle === 'dynamic' ? dashOffset : 0;\n drawDashedPath(g, segs, dash, offset);\n g.stroke({ color, width: strokeWidth, 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: strokeWidth });\n }\n }\n}\n\n/** Lookup table mapping shape type to draw function */\nexport const shapeDrawers: Record<string, (g: Graphics, o: ShapeDrawOptions) => void> = {\n shapeRect: drawRect,\n shapeRoundRect: drawRoundRect,\n shapeEllipse: drawEllipse,\n shapeDiamond: drawDiamond,\n shapeDocument: drawDocument,\n shapeParallelogram: drawParallelogram,\n shapeTriangle: drawTriangle,\n shapeTrapezoid: drawTrapezoid,\n shapePentagon: drawPentagon,\n shapeHexagon: drawHexagon,\n shapeStar: drawStar,\n shapeHexagram: drawHexagram,\n shapeRightTriangle: drawRightTriangle,\n shapeCorner: drawCorner,\n textLabel: drawRect,\n flowGroup: drawFlowGroup,\n geometryGroup: drawGeometryGroup,\n shapeSvg: drawRoundRect,\n};\n"],"mappings":"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"}
|