@elixpo/lixsketch 5.6.5 → 5.6.7
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/mcp/index.js +5 -1
- package/dist/mcp/index.js.map +2 -2
- package/dist/mcp/stdio.js +5 -1
- package/dist/mcp/stdio.js.map +2 -2
- package/dist/react/{AIRenderer-SRF7LU5K.js → AIRenderer-R5M2CIDO.js} +13 -6
- package/dist/react/AIRenderer-R5M2CIDO.js.map +7 -0
- package/dist/react/Circle-HMM5PKJ2.js +10 -0
- package/dist/react/{CopyPaste-YUDZ6DHY.js → CopyPaste-PPDS3AD6.js} +11 -10
- package/dist/react/{CopyPaste-YUDZ6DHY.js.map → CopyPaste-PPDS3AD6.js.map} +1 -1
- package/dist/react/{EventDispatcher-7LAK7GQ7.js → EventDispatcher-UV7LFSAS.js} +216 -63
- package/dist/react/EventDispatcher-UV7LFSAS.js.map +7 -0
- package/dist/react/Frame-DELCMYV6.js +11 -0
- package/dist/react/{FreehandStroke-U6GYZOM4.js → FreehandStroke-WXIJKD5I.js} +2 -2
- package/dist/react/{GraphEngine-MM6ALA2N.js → GraphEngine-XH3RPYO4.js} +9 -2
- package/dist/react/GraphEngine-XH3RPYO4.js.map +7 -0
- package/dist/react/IconShape-PZHMZSLR.js +10 -0
- package/dist/react/ImageShape-ZMBZARRI.js +10 -0
- package/dist/react/Line-VPVPL6ET.js +10 -0
- package/dist/react/{LixScriptParser-JYWJX375.js → LixScriptParser-YS3ZOTGS.js} +6 -2
- package/dist/react/LixScriptParser-YS3ZOTGS.js.map +7 -0
- package/dist/react/{MermaidFlowchartRenderer-PQEC4TMI.js → MermaidFlowchartRenderer-EL3Q2MNW.js} +6 -2
- package/dist/react/MermaidFlowchartRenderer-EL3Q2MNW.js.map +7 -0
- package/dist/react/MermaidSequenceParser-DBYXW23P.js +8 -0
- package/dist/react/{MermaidSequenceRenderer-KCUHO7UI.js → MermaidSequenceRenderer-K4KHHEVC.js} +10 -3
- package/dist/react/MermaidSequenceRenderer-K4KHHEVC.js.map +7 -0
- package/dist/react/{MermaidStructuredRenderer-W7UKN7BM.js → MermaidStructuredRenderer-6LN3WISP.js} +7 -2
- package/dist/react/MermaidStructuredRenderer-6LN3WISP.js.map +7 -0
- package/dist/react/Rectangle-4U4CD2ER.js +10 -0
- package/dist/react/{SceneSerializer-SG6SJN5X.js → SceneSerializer-H6KMQCO2.js} +120 -46
- package/dist/react/SceneSerializer-H6KMQCO2.js.map +7 -0
- package/dist/react/{Selection-2TSH3J6P.js → Selection-CFWRGVKH.js} +4 -4
- package/dist/react/{SketchEngine-UD2XV2KT.js → SketchEngine-UFLZJQXS.js} +26 -26
- package/dist/react/{UndoRedo-IN4SXDG6.js → UndoRedo-RXO7YHA2.js} +12 -2
- package/dist/react/{arrowTool-OYDWJGQK.js → arrowTool-DO327FKU.js} +3 -3
- package/dist/react/{chunk-EOURRJ55.js → chunk-2ALS5JGS.js} +2 -2
- package/dist/react/{chunk-LJR7EVW2.js → chunk-37PF7FG2.js} +3 -3
- package/dist/react/chunk-6AIFXYV6.js +31 -0
- package/dist/react/chunk-6AIFXYV6.js.map +7 -0
- package/dist/react/{chunk-XOWNCYE4.js → chunk-6LWUR7XB.js} +3 -3
- package/dist/react/{chunk-ASBC5G35.js → chunk-7DD2JRBC.js} +2 -2
- package/dist/react/{chunk-OP56XPWF.js → chunk-BOZEDUAF.js} +2 -2
- package/dist/react/{chunk-RGMDWLRJ.js → chunk-CGMUXYPJ.js} +3 -3
- package/dist/react/{chunk-M6TMN76K.js → chunk-DODPOWNX.js} +3 -3
- package/dist/react/{chunk-LSHZYN77.js → chunk-GQLXUZHQ.js} +2 -2
- package/dist/react/{chunk-7CM5XQDN.js → chunk-I7TVGJFF.js} +20 -36
- package/dist/react/chunk-I7TVGJFF.js.map +7 -0
- package/dist/react/{chunk-K5RY4EV7.js → chunk-KC26KJW4.js} +26 -17
- package/dist/react/chunk-KC26KJW4.js.map +7 -0
- package/dist/react/{chunk-XFL4R5ZF.js → chunk-KZBKYHZO.js} +16 -35
- package/dist/react/chunk-KZBKYHZO.js.map +7 -0
- package/dist/react/{chunk-VQVEPJSA.js → chunk-MHV5P6TS.js} +2 -1
- package/dist/react/chunk-MHV5P6TS.js.map +7 -0
- package/dist/react/{chunk-PXFPPO3R.js → chunk-NH3NVSWT.js} +18 -2
- package/dist/react/chunk-NH3NVSWT.js.map +7 -0
- package/dist/react/{chunk-APTOPAOY.js → chunk-O7KXLFZN.js} +3 -3
- package/dist/react/{chunk-GQUZPON4.js → chunk-RK3NVAER.js} +4 -4
- package/dist/react/{chunk-FETTJLCV.js → chunk-VZPH7OAM.js} +14 -22
- package/dist/react/chunk-VZPH7OAM.js.map +7 -0
- package/dist/react/{chunk-6GPEWDRB.js → chunk-VZX55VQL.js} +115 -6
- package/dist/react/chunk-VZX55VQL.js.map +7 -0
- package/dist/react/{chunk-TKXKJNTX.js → chunk-W7XUY4GR.js} +16 -19
- package/dist/react/chunk-W7XUY4GR.js.map +7 -0
- package/dist/react/{chunk-XYUFEIZR.js → chunk-X5ENBMGL.js} +2 -2
- package/dist/react/{chunk-K5BG5MHY.js → chunk-ZNZAICWY.js} +36 -60
- package/dist/react/chunk-ZNZAICWY.js.map +7 -0
- package/dist/react/{circleTool-LDKGZALF.js → circleTool-NK4RVDAR.js} +4 -4
- package/dist/react/{codeTool-4YZO5W7J.js → codeTool-3WF4HEOW.js} +4 -4
- package/dist/react/{frameTool-MXNJEXQQ.js → frameTool-VCNV2NG2.js} +4 -4
- package/dist/react/{freehandTool-26D3FOOX.js → freehandTool-TBAOD46K.js} +4 -4
- package/dist/react/{iconTool-46O5VEUX.js → iconTool-65JCAKYF.js} +4 -4
- package/dist/react/{imageTool-P2RWZRHO.js → imageTool-UQZUBOK2.js} +4 -4
- package/dist/react/index.js +148 -37
- package/dist/react/index.js.map +4 -4
- package/dist/react/{lineTool-ZMR27U5L.js → lineTool-762KBYOM.js} +4 -4
- package/dist/react/{rectangleTool-EJKK6UTX.js → rectangleTool-IQK3HZK6.js} +4 -4
- package/dist/react/{textTool-S4XXZHZH.js → textTool-ITG2SBJK.js} +5 -5
- package/package.json +5 -2
- package/src/core/AIRenderer.js +8 -2
- package/src/core/CanvasSpace.js +28 -0
- package/src/core/GraphRenderer.js +8 -3
- package/src/core/LixScriptParser.js +7 -1
- package/src/core/MermaidFlowchartRenderer.js +5 -1
- package/src/core/MermaidSequenceParser.js +1 -0
- package/src/core/MermaidSequenceRenderer.js +8 -3
- package/src/core/MermaidStructuredRenderer.js +6 -1
- package/src/core/SceneSerializer.js +121 -38
- package/src/core/Selection.js +29 -14
- package/src/core/UndoRedo.js +126 -5
- package/src/react/components/AppMenu.jsx +20 -19
- package/src/react/components/canvas/CanvasRulers.jsx +8 -13
- package/src/react/components/canvas/SVGCanvas.jsx +2 -1
- package/src/react/components/canvas/rulerUnits.js +28 -0
- package/src/react/components/sidebars/PaintBucketSidebar.jsx +1 -1
- package/src/react/store/useSketchStore.js +24 -3
- package/src/react/store/useUIStore.js +24 -1
- package/src/react/utils/canvasBackgrounds.js +29 -0
- package/src/shapes/Circle.js +12 -19
- package/src/shapes/Frame.js +38 -69
- package/src/shapes/FreehandStroke.js +24 -1
- package/src/shapes/Rectangle.js +10 -22
- package/src/tools/circleTool.js +3 -27
- package/src/tools/paintBucketTool.js +72 -15
- package/src/tools/rectangleTool.js +7 -23
- package/src/tools/shapeRecognition.js +270 -0
- package/src/tools/shapeRecognitionTool.js +36 -183
- package/dist/react/AIRenderer-SRF7LU5K.js.map +0 -7
- package/dist/react/Circle-6POZCUZD.js +0 -9
- package/dist/react/EventDispatcher-7LAK7GQ7.js.map +0 -7
- package/dist/react/Frame-7D2MXCFF.js +0 -11
- package/dist/react/GraphEngine-MM6ALA2N.js.map +0 -7
- package/dist/react/IconShape-ZADX7Y33.js +0 -10
- package/dist/react/ImageShape-UJQN2HI7.js +0 -10
- package/dist/react/Line-APEULMHE.js +0 -10
- package/dist/react/LixScriptParser-JYWJX375.js.map +0 -7
- package/dist/react/MermaidFlowchartRenderer-PQEC4TMI.js.map +0 -7
- package/dist/react/MermaidSequenceParser-UKG2NSZY.js +0 -8
- package/dist/react/MermaidSequenceRenderer-KCUHO7UI.js.map +0 -7
- package/dist/react/MermaidStructuredRenderer-W7UKN7BM.js.map +0 -7
- package/dist/react/Rectangle-S7XUKWYD.js +0 -9
- package/dist/react/SceneSerializer-SG6SJN5X.js.map +0 -7
- package/dist/react/chunk-6GPEWDRB.js.map +0 -7
- package/dist/react/chunk-7CM5XQDN.js.map +0 -7
- package/dist/react/chunk-FETTJLCV.js.map +0 -7
- package/dist/react/chunk-K5BG5MHY.js.map +0 -7
- package/dist/react/chunk-K5RY4EV7.js.map +0 -7
- package/dist/react/chunk-PXFPPO3R.js.map +0 -7
- package/dist/react/chunk-TKXKJNTX.js.map +0 -7
- package/dist/react/chunk-VQVEPJSA.js.map +0 -7
- package/dist/react/chunk-XFL4R5ZF.js.map +0 -7
- /package/dist/react/{Circle-6POZCUZD.js.map → Circle-HMM5PKJ2.js.map} +0 -0
- /package/dist/react/{Frame-7D2MXCFF.js.map → Frame-DELCMYV6.js.map} +0 -0
- /package/dist/react/{FreehandStroke-U6GYZOM4.js.map → FreehandStroke-WXIJKD5I.js.map} +0 -0
- /package/dist/react/{IconShape-ZADX7Y33.js.map → IconShape-PZHMZSLR.js.map} +0 -0
- /package/dist/react/{ImageShape-UJQN2HI7.js.map → ImageShape-ZMBZARRI.js.map} +0 -0
- /package/dist/react/{Line-APEULMHE.js.map → Line-VPVPL6ET.js.map} +0 -0
- /package/dist/react/{MermaidSequenceParser-UKG2NSZY.js.map → MermaidSequenceParser-DBYXW23P.js.map} +0 -0
- /package/dist/react/{Rectangle-S7XUKWYD.js.map → Rectangle-4U4CD2ER.js.map} +0 -0
- /package/dist/react/{Selection-2TSH3J6P.js.map → Selection-CFWRGVKH.js.map} +0 -0
- /package/dist/react/{SketchEngine-UD2XV2KT.js.map → SketchEngine-UFLZJQXS.js.map} +0 -0
- /package/dist/react/{UndoRedo-IN4SXDG6.js.map → UndoRedo-RXO7YHA2.js.map} +0 -0
- /package/dist/react/{arrowTool-OYDWJGQK.js.map → arrowTool-DO327FKU.js.map} +0 -0
- /package/dist/react/{chunk-EOURRJ55.js.map → chunk-2ALS5JGS.js.map} +0 -0
- /package/dist/react/{chunk-LJR7EVW2.js.map → chunk-37PF7FG2.js.map} +0 -0
- /package/dist/react/{chunk-XOWNCYE4.js.map → chunk-6LWUR7XB.js.map} +0 -0
- /package/dist/react/{chunk-ASBC5G35.js.map → chunk-7DD2JRBC.js.map} +0 -0
- /package/dist/react/{chunk-OP56XPWF.js.map → chunk-BOZEDUAF.js.map} +0 -0
- /package/dist/react/{chunk-RGMDWLRJ.js.map → chunk-CGMUXYPJ.js.map} +0 -0
- /package/dist/react/{chunk-M6TMN76K.js.map → chunk-DODPOWNX.js.map} +0 -0
- /package/dist/react/{chunk-LSHZYN77.js.map → chunk-GQLXUZHQ.js.map} +0 -0
- /package/dist/react/{chunk-APTOPAOY.js.map → chunk-O7KXLFZN.js.map} +0 -0
- /package/dist/react/{chunk-GQUZPON4.js.map → chunk-RK3NVAER.js.map} +0 -0
- /package/dist/react/{chunk-XYUFEIZR.js.map → chunk-X5ENBMGL.js.map} +0 -0
- /package/dist/react/{circleTool-LDKGZALF.js.map → circleTool-NK4RVDAR.js.map} +0 -0
- /package/dist/react/{codeTool-4YZO5W7J.js.map → codeTool-3WF4HEOW.js.map} +0 -0
- /package/dist/react/{frameTool-MXNJEXQQ.js.map → frameTool-VCNV2NG2.js.map} +0 -0
- /package/dist/react/{freehandTool-26D3FOOX.js.map → freehandTool-TBAOD46K.js.map} +0 -0
- /package/dist/react/{iconTool-46O5VEUX.js.map → iconTool-65JCAKYF.js.map} +0 -0
- /package/dist/react/{imageTool-P2RWZRHO.js.map → imageTool-UQZUBOK2.js.map} +0 -0
- /package/dist/react/{lineTool-ZMR27U5L.js.map → lineTool-762KBYOM.js.map} +0 -0
- /package/dist/react/{rectangleTool-EJKK6UTX.js.map → rectangleTool-IQK3HZK6.js.map} +0 -0
- /package/dist/react/{textTool-S4XXZHZH.js.map → textTool-ITG2SBJK.js.map} +0 -0
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/core/AIRenderer.js"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable */\n/**\n * AIRenderer - Converts diagram JSON into shapes on the canvas.\n *\n * Two entry points:\n * 1. renderAIDiagram(diagram) - from AI text-to-diagram response\n * 2. window.__mermaidRenderer(src) - direct algorithmic Mermaid parser\n *\n * Smart edge routing:\n * - Straight arrows/lines for vertically or horizontally aligned nodes\n * - Curved arrows for diagonal connections or when edges would overlap\n * - Elbow connections for right-angle routing when appropriate\n *\n * All created shapes belong to a Frame with auto-attachment so\n * moving nodes keeps edges connected.\n */\n\nconst PADDING = 80;\nconst NODE_W = 160;\nconst NODE_H = 60;\nconst H_SPACING = 260;\nconst V_SPACING = 180;\nconst NS = 'http://www.w3.org/2000/svg';\n\n// Alignment threshold \u2014 if nodes are within this many pixels\n// of being aligned, treat them as aligned (use straight edge)\nconst ALIGN_THRESHOLD = 30;\n\n// ============================================================\n// MERMAID PARSER\n// ============================================================\n\nexport function parseMermaid(src) {\n const lines = src.trim().split('\\n').map(l => l.trim()).filter(l => l && !l.startsWith('%%'));\n if (lines.length === 0) return null;\n\n const headerMatch = lines[0].match(/^(graph|flowchart)\\s+(TD|TB|LR|RL|BT)/i);\n const direction = headerMatch ? headerMatch[2].toUpperCase() : 'TD';\n const isHorizontal = direction === 'LR' || direction === 'RL';\n const startIdx = headerMatch ? 1 : 0;\n\n const nodesMap = new Map();\n const edges = [];\n const classDefs = new Map(); // classDef name -> { fill, stroke, strokeWidth }\n const classAssigns = []; // { nodeIds: [...], className }\n const nodeStyles = new Map(); // Mermaid `style A fill:...,stroke:...`\n const darkTheme = typeof document === 'undefined'\n || document.body?.classList.contains('theme-dark');\n const palette = darkTheme\n ? [\n { fill: '#352b52', stroke: '#9d86df' },\n { fill: '#403260', stroke: '#ad92ed' },\n { fill: '#2f2948', stroke: '#927fd1' },\n { fill: '#493568', stroke: '#b195e8' },\n { fill: '#322747', stroke: '#9b83d7' },\n { fill: '#3d2e58', stroke: '#a88add' },\n ]\n : [\n { fill: '#eee9f7', stroke: '#7667a8' },\n { fill: '#e6def2', stroke: '#8875b5' },\n { fill: '#ddd2eb', stroke: '#6f5f9c' },\n { fill: '#f2edf8', stroke: '#9a88bf' },\n { fill: '#e2daf0', stroke: '#806cab' },\n { fill: '#ebe4f5', stroke: '#705d9c' },\n ];\n\n function parseStyleProps(value) {\n const props = {};\n for (const part of value.split(',')) {\n const separator = part.indexOf(':');\n if (separator < 0) continue;\n const key = part.slice(0, separator).trim().toLowerCase();\n const val = part.slice(separator + 1).trim();\n if (key === 'fill') props.fill = val;\n else if (key === 'stroke') props.stroke = val;\n else if (key === 'stroke-width') props.strokeWidth = parseFloat(val);\n else if (key === 'color') props.labelColor = val;\n }\n return props;\n }\n\n // Clean <br/> and <br> tags in labels \u2192 newline marker\n function cleanLabel(label) {\n return label.replace(/<br\\s*\\/?>/gi, '\\n').replace(/\"/g, '');\n }\n\n function parseNodeRef(raw) {\n raw = raw.trim();\n if (!raw) return null;\n let id, label, type;\n\n // Circle: id((label))\n let m = raw.match(/^(\\w+)\\(\\((.+?)\\)\\)$/);\n if (m) { id = m[1]; label = m[2]; type = 'circle'; }\n // Diamond: id{label}\n if (!m) { m = raw.match(/^(\\w+)\\{(.+?)\\}$/); if (m) { id = m[1]; label = m[2]; type = 'diamond'; } }\n // Asymmetric/flag: id>label]\n if (!m) { m = raw.match(/^(\\w+)>(.+?)\\]$/); if (m) { id = m[1]; label = m[2]; type = 'asymmetric'; } }\n // Rounded rect: id(label)\n if (!m) { m = raw.match(/^(\\w+)\\((.+?)\\)$/); if (m) { id = m[1]; label = m[2]; type = 'roundrect'; } }\n // Rectangle: id[label]\n if (!m) { m = raw.match(/^(\\w+)\\[(.+?)\\]$/); if (m) { id = m[1]; label = m[2]; type = 'rectangle'; } }\n // Plain id\n if (!m) { id = raw; label = raw; type = 'rectangle'; }\n\n label = cleanLabel(label);\n\n if (!nodesMap.has(id)) {\n nodesMap.set(id, { id, type, label });\n } else if (label !== id) {\n nodesMap.get(id).label = label;\n nodesMap.get(id).type = type;\n }\n return id;\n }\n\n // Parse subgraphs\n const subgraphs = [];\n let currentSubgraph = null;\n\n for (let i = startIdx; i < lines.length; i++) {\n const line = lines[i].replace(/;$/, '').trim();\n if (!line) continue;\n\n // classDef: classDef green fill:#9f6,stroke:#333,stroke-width:2px;\n const classDefMatch = line.match(/^classDef\\s+(\\w+)\\s+(.+)$/i);\n if (classDefMatch) {\n const name = classDefMatch[1];\n classDefs.set(name, parseStyleProps(classDefMatch[2].replace(/;$/, '')));\n continue;\n }\n\n // Direct node styling must be consumed before node/edge parsing.\n // Previously these lines fell through to `parseNodeRef`, producing\n // visible boxes containing the raw `style A fill:...` source.\n const styleMatch = line.match(/^style\\s+([\\w,-]+)\\s+(.+)$/i);\n if (styleMatch) {\n const props = parseStyleProps(styleMatch[2].replace(/;$/, ''));\n styleMatch[1].split(',').map(id => id.trim()).filter(Boolean)\n .forEach(id => nodeStyles.set(id, props));\n continue;\n }\n\n // Presentation-only directives do not represent diagram nodes.\n if (/^(linkStyle|click)\\b/i.test(line)) continue;\n\n // class assignment: class sq,e green\n const classMatch = line.match(/^class\\s+(.+?)\\s+(\\w+)$/i);\n if (classMatch) {\n const nodeIds = classMatch[1].split(',').map(s => s.trim());\n classAssigns.push({ nodeIds, className: classMatch[2] });\n continue;\n }\n\n // Subgraph start: subgraph ID [\"Label\"]\n const sgMatch = line.match(/^subgraph\\s+(\\w+)(?:\\s*\\[?\"?(.+?)\"?\\]?)?$/i);\n if (sgMatch) {\n currentSubgraph = {\n id: sgMatch[1],\n label: sgMatch[2] || sgMatch[1],\n nodeIds: [],\n };\n continue;\n }\n\n // Subgraph end\n if (line.toLowerCase() === 'end' && currentSubgraph) {\n subgraphs.push(currentSubgraph);\n currentSubgraph = null;\n continue;\n }\n\n // Helper to add edge nodes to current subgraph\n function addToSubgraph(fromId, toId) {\n if (currentSubgraph) {\n if (fromId && !currentSubgraph.nodeIds.includes(fromId)) currentSubgraph.nodeIds.push(fromId);\n if (toId && !currentSubgraph.nodeIds.includes(toId)) currentSubgraph.nodeIds.push(toId);\n }\n }\n\n // Labeled edge: A -- text --> B\n let match = line.match(/^(.+?)\\s*--\\s*(.+?)\\s*-->\\s*(.+)$/);\n if (match) {\n const fromId = parseNodeRef(match[1].trim());\n const toId = parseNodeRef(match[3].trim());\n if (fromId && toId) edges.push({ from: fromId, to: toId, label: cleanLabel(match[2].trim()), directed: true, style: 'normal' });\n addToSubgraph(fromId, toId);\n continue;\n }\n\n // Dotted arrow: A -.-> B (with optional |label|)\n match = line.match(/^(.+?)\\s*-\\.->?\\s*(?:\\|([^|]*)\\|)?\\s*(.+)$/);\n if (match) {\n const fromId = parseNodeRef(match[1].trim());\n const toId = parseNodeRef(match[3].trim());\n const edgeLabel = match[2] ? cleanLabel(match[2].trim()) : undefined;\n if (fromId && toId) edges.push({ from: fromId, to: toId, label: edgeLabel, directed: true, style: 'dotted' });\n addToSubgraph(fromId, toId);\n continue;\n }\n\n // Thick arrow: A ==> B (with optional |label|)\n match = line.match(/^(.+?)\\s*==>\\s*(?:\\|([^|]*)\\|)?\\s*(.+)$/);\n if (match) {\n const fromId = parseNodeRef(match[1].trim());\n const toId = parseNodeRef(match[3].trim());\n const edgeLabel = match[2] ? cleanLabel(match[2].trim()) : undefined;\n if (fromId && toId) edges.push({ from: fromId, to: toId, label: edgeLabel, directed: true, style: 'thick' });\n addToSubgraph(fromId, toId);\n continue;\n }\n\n // Undirected line: A --- B\n match = line.match(/^(.+?)\\s*(-{3,})\\s*(?:\\|([^|]*)\\|)?\\s*(.+)$/);\n if (match && !match[2].includes('>')) {\n const fromId = parseNodeRef(match[1].trim());\n const toId = parseNodeRef(match[4].trim());\n const edgeLabel = match[3] ? cleanLabel(match[3].trim()) : undefined;\n if (fromId && toId) edges.push({ from: fromId, to: toId, label: edgeLabel, directed: false, style: 'normal' });\n addToSubgraph(fromId, toId);\n continue;\n }\n\n // Directed edge: A --> B (with optional |label|)\n match = line.match(/^(.+?)\\s*(-{1,2}>|-->)\\s*(?:\\|([^|]*)\\|)?\\s*(.+)$/);\n if (match) {\n const fromId = parseNodeRef(match[1].trim());\n const toId = parseNodeRef(match[4].trim());\n const edgeLabel = match[3] ? cleanLabel(match[3].trim()) : undefined;\n if (fromId && toId) edges.push({ from: fromId, to: toId, label: edgeLabel, directed: true, style: 'normal' });\n addToSubgraph(fromId, toId);\n continue;\n }\n\n // Plain node reference\n const nodeId = parseNodeRef(line);\n if (nodeId && currentSubgraph) {\n if (!currentSubgraph.nodeIds.includes(nodeId)) currentSubgraph.nodeIds.push(nodeId);\n }\n }\n\n if (nodesMap.size === 0) return null;\n\n // Apply classDef styles to nodes\n for (const assign of classAssigns) {\n const style = classDefs.get(assign.className);\n if (!style) continue;\n for (const nid of assign.nodeIds) {\n const node = nodesMap.get(nid);\n if (node) {\n if (style.fill) node.fill = style.fill;\n if (style.stroke) node.stroke = style.stroke;\n if (style.strokeWidth) node.strokeWidth = style.strokeWidth;\n }\n }\n }\n\n\n for (const [nid, style] of nodeStyles) {\n const node = nodesMap.get(nid);\n if (node) Object.assign(node, style);\n }\n\n // Topological BFS layering\n const nodeIds = Array.from(nodesMap.keys());\n const children = new Map();\n const parents = new Map();\n nodeIds.forEach(id => { children.set(id, []); parents.set(id, []); });\n edges.forEach(e => {\n if (children.has(e.from)) children.get(e.from).push(e.to);\n if (parents.has(e.to)) parents.get(e.to).push(e.from);\n });\n\n const layers = new Map();\n const roots = nodeIds.filter(id => parents.get(id).length === 0);\n if (roots.length === 0) roots.push(nodeIds[0]);\n\n const queue = roots.map(id => ({ id, layer: 0 }));\n const visited = new Set();\n while (queue.length > 0) {\n const { id, layer } = queue.shift();\n if (visited.has(id)) { if (layer > (layers.get(id) || 0)) layers.set(id, layer); continue; }\n visited.add(id);\n layers.set(id, Math.max(layer, layers.get(id) || 0));\n for (const child of children.get(id) || []) queue.push({ id: child, layer: layer + 1 });\n }\n nodeIds.forEach(id => { if (!visited.has(id)) layers.set(id, 0); });\n\n const layerGroups = new Map();\n layers.forEach((layer, id) => {\n if (!layerGroups.has(layer)) layerGroups.set(layer, []);\n layerGroups.get(layer).push(id);\n });\n\n // Compute dynamic node sizes based on label length\n const nodes = [];\n let paletteIndex = 0;\n Array.from(layerGroups.keys()).sort((a, b) => a - b).forEach((layerIdx, li) => {\n const group = layerGroups.get(layerIdx);\n const startOffset = -(group.length * H_SPACING) / 2 + H_SPACING / 2;\n group.forEach((id, gi) => {\n const nd = nodesMap.get(id);\n const x = isHorizontal ? li * H_SPACING : startOffset + gi * H_SPACING;\n const y = isHorizontal ? startOffset + gi * V_SPACING : li * V_SPACING;\n // Compute node size based on label lines\n const labelLines = (nd.label || '').split('\\n');\n const maxLineLen = Math.max(...labelLines.map(l => l.length));\n const nw = Math.max(NODE_W, maxLineLen * 10 + 40);\n const nh = Math.max(NODE_H, labelLines.length * 20 + 20);\n nodes.push({\n id: nd.id, type: nd.type, label: nd.label,\n x, y, width: nw, height: nh,\n fill: nd.fill || palette[paletteIndex % palette.length].fill,\n stroke: nd.stroke || palette[paletteIndex % palette.length].stroke,\n strokeWidth: nd.strokeWidth,\n labelColor: nd.labelColor,\n });\n paletteIndex += 1;\n });\n });\n\n return {\n title: 'Mermaid Diagram',\n direction,\n nodes,\n edges: edges.map(e => ({\n from: e.from, to: e.to, label: e.label,\n directed: e.directed !== false,\n style: e.style || 'normal',\n })),\n subgraphs: subgraphs.length > 0 ? subgraphs.map(sg => ({\n id: sg.id, label: sg.label, nodes: sg.nodeIds,\n })) : undefined,\n };\n}\n\n// ============================================================\n// RENDER\n// ============================================================\n\nexport function renderAIDiagram(diagram) {\n if (!diagram?.nodes?.length) { console.error('[AIRenderer] Invalid diagram'); return false; }\n\n const nodes = diagram.nodes;\n const edges = diagram.edges || [];\n const title = diagram.title || 'AI Diagram';\n\n if (!window.svg || !window.Frame || !window.Rectangle) {\n console.error('[AIRenderer] Engine not initialized');\n return false;\n }\n\n // Viewport center\n const vb = window.currentViewBox || { x: 0, y: 0, width: window.innerWidth, height: window.innerHeight };\n const vcx = vb.x + vb.width / 2;\n const vcy = vb.y + vb.height / 2;\n\n // Diagram bounds\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n nodes.forEach(n => {\n minX = Math.min(minX, n.x);\n minY = Math.min(minY, n.y);\n maxX = Math.max(maxX, n.x + (n.width || NODE_W));\n maxY = Math.max(maxY, n.y + (n.height || NODE_H));\n });\n\n const dw = maxX - minX, dh = maxY - minY;\n const ox = vcx - dw / 2 - minX;\n const oy = vcy - dh / 2 - minY;\n\n // Phase 5 (issue #22): no outer wrapper frame. Each generated shape\n // (node, edge, subgraph container) gets the same `groupId` so the whole\n // diagram behaves as one selectable group via Selection.js's existing\n // group-expansion path. Drops the \"solid background frame\" symptom and\n // makes the rendered content as interactive as user-drawn shapes.\n const groupId = `aidiag-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 7)}`;\n // Kept under the same name `frame` to minimise the diff inside this\n // 600-line function \u2014 it's now a thin shim that catches `addShapeToFrame`\n // calls and re-routes them to a groupId assignment. `selectFrame` /\n // `removeSelection` no-op; selection is on the first node below.\n const frame = {\n addShapeToFrame(s) { if (s) s.groupId = groupId; },\n selectFrame() {},\n removeSelection() {},\n shapeName: 'frame',\n };\n\n const nodeMap = new Map();\n\n // --- NODES ---\n for (const node of nodes) {\n const nx = node.x + ox, ny = node.y + oy;\n const nw = node.width || NODE_W, nh = node.height || NODE_H;\n const cx = nx + nw / 2, cy = ny + nh / 2;\n let shape = null;\n\n // Build style options from AI-specified properties (with defaults)\n const nodeOpts = {\n stroke: node.stroke || '#e0e0e0',\n strokeWidth: node.strokeWidth ?? 1.5,\n fill: node.fill || 'transparent',\n fillStyle: node.fillStyle || 'none',\n roughness: node.roughness ?? 1,\n strokeDasharray: node.strokeDasharray || '',\n // Shading support\n shadeColor: node.shadeColor || null,\n shadeOpacity: node.shadeOpacity !== undefined ? node.shadeOpacity : 0.15,\n shadeDirection: node.shadeDirection || 'bottom',\n // Label styling\n labelColor: node.labelColor || undefined,\n labelFontSize: node.labelFontSize || undefined,\n };\n\n try {\n if (node.type === 'icon' && node.iconKeyword) {\n // Icon nodes are placed asynchronously \u2014 create a placeholder rectangle\n // and kick off icon fetch in the background\n shape = new window.Rectangle(nx, ny, nw, nh, {\n ...nodeOpts, stroke: nodeOpts.stroke, strokeDasharray: '4 3',\n });\n // Async fetch & replace with actual icon\n fetchAndPlaceIcon(node.iconKeyword, nx, ny, nw, nh, shape, frame);\n } else if (node.type === 'circle' && window.Circle) {\n shape = new window.Circle(cx, cy, nw / 2, nh / 2, nodeOpts);\n } else if (node.type === 'diamond' && window.Rectangle) {\n const sz = Math.max(nw, nh) * 0.7;\n shape = new window.Rectangle(cx - sz / 2, cy - sz / 2, sz, sz, nodeOpts);\n shape.rotation = 45;\n shape.draw();\n } else if (node.type === 'roundrect' && window.Rectangle) {\n shape = new window.Rectangle(nx, ny, nw, nh, { ...nodeOpts, cornerRadius: Math.min(nw, nh) * 0.2 });\n } else if (window.Rectangle) {\n shape = new window.Rectangle(nx, ny, nw, nh, nodeOpts);\n }\n } catch (err) {\n console.warn('[AIRenderer] Node creation failed:', node.id, err);\n continue;\n }\n\n if (!shape) continue;\n\n // Apply rotation if specified (skip for diamonds \u2014 they already have rotation=45)\n if (node.rotation && shape.rotation !== undefined && node.type !== 'diamond') {\n shape.rotation = node.rotation;\n }\n\n window.shapes.push(shape);\n if (window.pushCreateAction) window.pushCreateAction(shape);\n if (frame.addShapeToFrame) frame.addShapeToFrame(shape);\n\n nodeMap.set(node.id, { shape, x: nx, y: ny, width: nw, height: nh, centerX: cx, centerY: cy });\n\n // Node label \u2014 use embedded label for rect/circle, separate TextShape for icons\n if (node.label) {\n let labelColor = node.labelColor || node.stroke || '#e0e0e0';\n if (isColorTooDark(labelColor)) {\n labelColor = '#e0e0e0';\n }\n const labelFontSize = node.labelFontSize || 14;\n\n if (node.type === 'icon') {\n // Icons: place label below the icon as a separate TextShape\n const labelY = cy + nh / 2 + 18;\n createLabel(node.label, cx, labelY, labelFontSize, labelColor, frame);\n } else if (shape && typeof shape.setLabel === 'function') {\n // Rectangles, circles, diamonds: use embedded label\n shape.setLabel(node.label, labelColor, labelFontSize);\n } else {\n // Fallback: separate TextShape\n createLabel(node.label, cx, cy, labelFontSize, labelColor, frame);\n }\n }\n }\n\n // --- EDGES ---\n // Pre-compute fan-out counts per source node so we can spread edges\n const fanOut = new Map();\n const fanIdx = new Map();\n edges.forEach(e => {\n fanOut.set(e.from, (fanOut.get(e.from) || 0) + 1);\n fanIdx.set(e, fanOut.get(e.from) - 1);\n });\n\n // Collect all node bounds for overlap checking\n const allNodeBounds = [];\n nodeMap.forEach(n => {\n allNodeBounds.push({ x: n.x, y: n.y, width: n.width, height: n.height });\n });\n\n for (const edge of edges) {\n const from = nodeMap.get(edge.from), to = nodeMap.get(edge.to);\n if (!from || !to) continue;\n\n const count = fanOut.get(edge.from) || 1;\n const idx = fanIdx.get(edge);\n const isDirected = edge.directed !== false;\n\n // Determine edge routing style based on node alignment and context\n const edgeStyle = chooseEdgeStyle(from, to, count, idx, allNodeBounds, nodeMap, edges);\n\n // Spread connection ports along the exit edge when fan-out > 1\n const sp = getSpreadEdgePoint(from, to, count, idx);\n const ep = getEdgePoint(to, from);\n\n // Nudge slightly away from node boundaries\n const adx = ep.x - sp.x, ady = ep.y - sp.y;\n const alen = Math.sqrt(adx * adx + ady * ady) || 1;\n const nudge = 6;\n const spN = { x: sp.x + (adx / alen) * nudge, y: sp.y + (ady / alen) * nudge };\n const epN = { x: ep.x - (adx / alen) * nudge, y: ep.y - (ady / alen) * nudge };\n\n let connector = null;\n\n // Edge style from AI (with defaults)\n const edgeStroke = edge.stroke || '#e0e0e0';\n const edgeStrokeWidth = edge.strokeWidth ?? 1.5;\n const edgeLineStyle = edge.lineStyle || 'solid';\n\n // Map lineStyle to arrowOutlineStyle / strokeDasharray\n const dashMap = { solid: '', dashed: '5 3', dotted: '2 2' };\n const dashValue = dashMap[edgeLineStyle] || '';\n\n if (isDirected && window.Arrow) {\n // Use Arrow for directed edges\n try {\n const opts = {\n stroke: edgeStroke, strokeWidth: edgeStrokeWidth, roughness: 1,\n arrowOutlineStyle: edgeLineStyle,\n arrowHeadStyle: edge.arrowHeadStyle || 'default',\n };\n\n if (edgeStyle.type === 'curved') {\n opts.arrowCurved = 'curved';\n opts.arrowCurveAmount = edgeStyle.curveAmount;\n } else if (edgeStyle.type === 'elbow') {\n opts.arrowCurved = 'elbow';\n }\n // 'straight' \u2014 no arrowCurved needed (default)\n\n connector = new window.Arrow(spN, epN, opts);\n window.shapes.push(connector);\n if (window.pushCreateAction) window.pushCreateAction(connector);\n if (frame.addShapeToFrame) frame.addShapeToFrame(connector);\n\n // Auto-attach arrow to source and target shapes\n autoAttach(connector, from.shape, true, sp);\n autoAttach(connector, to.shape, false, ep);\n } catch (err) {\n console.warn('[AIRenderer] Arrow creation failed:', edge, err);\n }\n } else if (!isDirected && window.Line) {\n // Use Line for undirected edges\n try {\n const opts = {\n stroke: edgeStroke, strokeWidth: edgeStrokeWidth, roughness: 1,\n strokeDasharray: dashValue,\n };\n\n connector = new window.Line(spN, epN, opts);\n\n if (edgeStyle.type === 'curved') {\n connector.isCurved = true;\n if (typeof connector.initializeCurveControlPoint === 'function') {\n connector.initializeCurveControlPoint();\n }\n // Re-draw with curve since constructor drew it straight\n if (typeof connector.draw === 'function') connector.draw();\n }\n\n window.shapes.push(connector);\n if (window.pushCreateAction) window.pushCreateAction(connector);\n if (frame.addShapeToFrame) frame.addShapeToFrame(connector);\n } catch (err) {\n console.warn('[AIRenderer] Line creation failed:', edge, err);\n }\n } else if (window.Arrow) {\n // Fallback: use Arrow if Line not available\n try {\n connector = new window.Arrow(spN, epN, {\n stroke: edgeStroke, strokeWidth: edgeStrokeWidth, roughness: 1,\n });\n window.shapes.push(connector);\n if (window.pushCreateAction) window.pushCreateAction(connector);\n if (frame.addShapeToFrame) frame.addShapeToFrame(connector);\n } catch (err) {\n console.warn('[AIRenderer] Fallback arrow creation failed:', edge, err);\n }\n }\n\n // Edge label \u2014 use embedded label on connector if available\n if (edge.label && connector) {\n const edgeLabelColor = edgeStroke === '#e0e0e0' ? '#a0a0b0' : edgeStroke;\n if (typeof connector.setLabel === 'function') {\n connector.setLabel(edge.label, edgeLabelColor, 11);\n } else {\n // Fallback: separate TextShape\n const mx = (spN.x + epN.x) / 2;\n const my = (spN.y + epN.y) / 2 - 18;\n createLabel(edge.label, mx, my, 11, edgeLabelColor, frame);\n }\n }\n }\n\n // --- SUBGRAPHS ---\n const subgraphs = diagram.subgraphs || [];\n for (const sg of subgraphs) {\n if (!sg.nodes || sg.nodes.length === 0) continue;\n\n // Compute bounds of all nodes in this subgraph\n let sgMinX = Infinity, sgMinY = Infinity, sgMaxX = -Infinity, sgMaxY = -Infinity;\n let hasNodes = false;\n for (const nid of sg.nodes) {\n const n = nodeMap.get(nid);\n if (!n) continue;\n hasNodes = true;\n sgMinX = Math.min(sgMinX, n.x);\n sgMinY = Math.min(sgMinY, n.y);\n sgMaxX = Math.max(sgMaxX, n.x + n.width);\n sgMaxY = Math.max(sgMaxY, n.y + n.height);\n }\n if (!hasNodes) continue;\n\n const sgPad = 30;\n try {\n const subFrame = new window.Frame(\n sgMinX - sgPad, sgMinY - sgPad - 20,\n (sgMaxX - sgMinX) + sgPad * 2, (sgMaxY - sgMinY) + sgPad * 2 + 20,\n {\n stroke: sg.stroke || '#555',\n strokeWidth: 1,\n fill: 'transparent',\n opacity: 0.6,\n frameName: sg.label || sg.id,\n }\n );\n window.shapes.push(subFrame);\n if (window.pushCreateAction) window.pushCreateAction(subFrame);\n if (frame.addShapeToFrame) frame.addShapeToFrame(subFrame);\n\n // Add nodes to the sub-frame\n for (const nid of sg.nodes) {\n const n = nodeMap.get(nid);\n if (n && n.shape && subFrame.addShapeToFrame) {\n subFrame.addShapeToFrame(n.shape);\n }\n }\n } catch (err) {\n console.warn('[AIRenderer] Subgraph frame failed:', sg.id, err);\n }\n }\n\n // Phase 5: select the first generated node \u2014 group expansion in\n // Selection.js will pick up the rest via the shared groupId.\n const first = nodeMap.values().next().value;\n if (first && first.shape) {\n window.currentShape = first.shape;\n if (typeof first.shape.selectShape === 'function') first.shape.selectShape();\n }\n\n console.log(`[AIRenderer] Done: ${nodes.length} nodes, ${edges.length} edges, ${subgraphs.length} subgraphs \u2192 \"${title}\" (groupId=${groupId})`);\n return true;\n}\n\n// ============================================================\n// SMART EDGE ROUTING\n// ============================================================\n\n/**\n * Choose the best edge style based on node positions and context.\n * Returns { type: 'straight'|'curved'|'elbow', curveAmount?: number }\n */\nfunction chooseEdgeStyle(from, to, fanCount, fanIdx, allNodeBounds, nodeMap, edges) {\n const dx = Math.abs(from.centerX - to.centerX);\n const dy = Math.abs(from.centerY - to.centerY);\n\n // Multiple edges from same source \u2014 must curve to avoid overlap\n if (fanCount > 1) {\n const curveAmount = 40 + (fanIdx - (fanCount - 1) / 2) * 35;\n return { type: 'curved', curveAmount };\n }\n\n // Check if nodes are aligned (horizontally or vertically)\n const isHAligned = dx < ALIGN_THRESHOLD;\n const isVAligned = dy < ALIGN_THRESHOLD;\n\n // If aligned on either axis, use straight line\n if (isHAligned || isVAligned) {\n // But check if a straight line would cross through any other node\n const sp = getEdgePoint(from, to);\n const ep = getEdgePoint(to, from);\n const blocked = wouldCrossNode(sp, ep, from, to, allNodeBounds);\n\n if (blocked) {\n // Use curved to route around\n return { type: 'curved', curveAmount: 40 };\n }\n return { type: 'straight' };\n }\n\n // Diagonal connection \u2014 check if elbow or curve is better\n // Elbow works well when nodes are in a grid-like arrangement\n const isGridLike = (dx > ALIGN_THRESHOLD * 2) && (dy > ALIGN_THRESHOLD * 2);\n\n if (isGridLike) {\n // Check if elbow would cross another node\n // Elbow goes horizontal then vertical (or vice versa)\n const elbowMidX = to.centerX;\n const elbowMidY = from.centerY;\n const elbowMid = { x: elbowMidX, y: elbowMidY };\n\n const seg1Blocked = wouldCrossNode(\n { x: from.centerX, y: from.centerY }, elbowMid, from, to, allNodeBounds\n );\n const seg2Blocked = wouldCrossNode(\n elbowMid, { x: to.centerX, y: to.centerY }, from, to, allNodeBounds\n );\n\n if (!seg1Blocked && !seg2Blocked) {\n return { type: 'elbow' };\n }\n }\n\n // Default: gentle curve for diagonal connections\n return { type: 'curved', curveAmount: 25 };\n}\n\n/**\n * Check if a straight line between two points would cross through any node\n * (excluding the source and target nodes themselves).\n */\nfunction wouldCrossNode(p1, p2, fromNode, toNode, allNodeBounds) {\n const margin = 10;\n for (const bounds of allNodeBounds) {\n // Skip source and target nodes\n if (bounds.x === fromNode.x && bounds.y === fromNode.y) continue;\n if (bounds.x === toNode.x && bounds.y === toNode.y) continue;\n\n // Inflate node bounds slightly for margin\n const bx = bounds.x - margin;\n const by = bounds.y - margin;\n const bw = bounds.width + margin * 2;\n const bh = bounds.height + margin * 2;\n\n if (lineIntersectsRect(p1.x, p1.y, p2.x, p2.y, bx, by, bw, bh)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if a line segment intersects a rectangle.\n */\nfunction lineIntersectsRect(x1, y1, x2, y2, rx, ry, rw, rh) {\n // Check if line segment intersects any of the 4 edges of the rect\n const left = rx, right = rx + rw, top = ry, bottom = ry + rh;\n\n // Quick bounding box rejection\n if (Math.max(x1, x2) < left || Math.min(x1, x2) > right) return false;\n if (Math.max(y1, y2) < top || Math.min(y1, y2) > bottom) return false;\n\n // Check if either endpoint is inside the rect\n if (x1 >= left && x1 <= right && y1 >= top && y1 <= bottom) return true;\n if (x2 >= left && x2 <= right && y2 >= top && y2 <= bottom) return true;\n\n // Check line intersection with each edge\n return (\n segmentsIntersect(x1, y1, x2, y2, left, top, right, top) ||\n segmentsIntersect(x1, y1, x2, y2, right, top, right, bottom) ||\n segmentsIntersect(x1, y1, x2, y2, left, bottom, right, bottom) ||\n segmentsIntersect(x1, y1, x2, y2, left, top, left, bottom)\n );\n}\n\nfunction segmentsIntersect(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2) {\n const d1 = cross(bx1, by1, bx2, by2, ax1, ay1);\n const d2 = cross(bx1, by1, bx2, by2, ax2, ay2);\n const d3 = cross(ax1, ay1, ax2, ay2, bx1, by1);\n const d4 = cross(ax1, ay1, ax2, ay2, bx2, by2);\n\n if (((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) &&\n ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0))) {\n return true;\n }\n return false;\n}\n\nfunction cross(ax, ay, bx, by, cx, cy) {\n return (bx - ax) * (cy - ay) - (by - ay) * (cx - ax);\n}\n\n// ============================================================\n// AUTO-ATTACHMENT\n// ============================================================\n\n/**\n * Automatically attach an arrow endpoint to a shape.\n * This makes edges follow nodes when they're moved.\n */\nexport function autoAttach(arrow, shape, isStart, contactPoint) {\n if (!arrow || !shape) return;\n if (typeof arrow.attachToShape !== 'function') return;\n\n try {\n // Determine attachment side based on contact point relative to shape\n let side, offset;\n\n if (shape.shapeName === 'rectangle' || shape.shapeName === 'frame') {\n const sx = shape.x, sy = shape.y, sw = shape.width, sh = shape.height;\n const cx = sx + sw / 2, cy = sy + sh / 2;\n\n // Determine which edge the contact point is closest to\n const distTop = Math.abs(contactPoint.y - sy);\n const distBottom = Math.abs(contactPoint.y - (sy + sh));\n const distLeft = Math.abs(contactPoint.x - sx);\n const distRight = Math.abs(contactPoint.x - (sx + sw));\n const minDist = Math.min(distTop, distBottom, distLeft, distRight);\n\n if (minDist === distTop) {\n side = 'top';\n offset = { x: contactPoint.x - sx, y: 0, side: 'top' };\n } else if (minDist === distBottom) {\n side = 'bottom';\n offset = { x: contactPoint.x - sx, y: sh, side: 'bottom' };\n } else if (minDist === distLeft) {\n side = 'left';\n offset = { x: 0, y: contactPoint.y - sy, side: 'left' };\n } else {\n side = 'right';\n offset = { x: sw, y: contactPoint.y - sy, side: 'right' };\n }\n\n const attachment = { side, point: contactPoint, offset };\n arrow.attachToShape(isStart, shape, attachment);\n } else if (shape.shapeName === 'circle') {\n const angle = Math.atan2(\n contactPoint.y - shape.y,\n contactPoint.x - shape.x\n );\n const attachment = {\n side: 'perimeter',\n point: contactPoint,\n offset: { angle, side: 'perimeter' },\n };\n arrow.attachToShape(isStart, shape, attachment);\n }\n } catch (err) {\n // Attachment is optional \u2014 don't fail the render\n console.warn('[AIRenderer] Auto-attach failed:', err);\n }\n}\n\n// ============================================================\n// ICON FETCHING\n// ============================================================\n\n/**\n * Fetch an icon by keyword from the icon API and replace the placeholder shape.\n * Runs asynchronously so it doesn't block diagram rendering.\n */\nasync function fetchAndPlaceIcon(keyword, x, y, w, h, placeholderShape, frame) {\n try {\n const res = await fetch(`/api/icons/search?q=${encodeURIComponent(keyword)}&inline=1`);\n if (!res.ok) return;\n const data = await res.json();\n const results = data.results;\n if (!results || results.length === 0 || !results[0].svg) return;\n\n const svgContent = results[0].svg;\n\n // Use the engine's icon placement bridge if available\n if (window.svg && window.IconShape) {\n const svg = window.svg;\n\n // Parse SVG to extract paths\n const parser = new DOMParser();\n const doc = parser.parseFromString(svgContent, 'image/svg+xml');\n const svgEl = doc.querySelector('svg');\n if (!svgEl) return;\n\n const vbWidth = parseFloat(svgEl.getAttribute('width') || svgEl.viewBox?.baseVal?.width || 24);\n const vbHeight = parseFloat(svgEl.getAttribute('height') || svgEl.viewBox?.baseVal?.height || 24);\n const scale = Math.min(w / vbWidth, h / vbHeight);\n\n // Create icon group\n const g = document.createElementNS(NS, 'g');\n g.setAttribute('type', 'icon');\n g.setAttribute('x', x);\n g.setAttribute('y', y);\n g.setAttribute('width', w);\n g.setAttribute('height', h);\n g.setAttribute('data-shape-x', x);\n g.setAttribute('data-shape-y', y);\n g.setAttribute('data-shape-width', w);\n g.setAttribute('data-shape-height', h);\n g.setAttribute('data-shape-rotation', '0');\n g.setAttribute('data-viewbox-width', vbWidth);\n g.setAttribute('data-viewbox-height', vbHeight);\n g.setAttribute('transform', `translate(${x}, ${y}) scale(${scale})`);\n\n // Copy SVG content into group, apply white fill\n const children = svgEl.querySelectorAll('path, circle, rect, polygon, polyline, line, ellipse');\n children.forEach(child => {\n const clone = child.cloneNode(true);\n // Make visible on dark canvas\n if (!clone.getAttribute('fill') || clone.getAttribute('fill') === 'none' || clone.getAttribute('fill') === 'black' || clone.getAttribute('fill') === '#000' || clone.getAttribute('fill') === '#000000') {\n clone.setAttribute('fill', '#ffffff');\n }\n if (clone.getAttribute('stroke') === 'black' || clone.getAttribute('stroke') === '#000' || clone.getAttribute('stroke') === '#000000') {\n clone.setAttribute('stroke', '#ffffff');\n }\n g.appendChild(clone);\n });\n\n // Add hit detection rect\n const hitRect = document.createElementNS(NS, 'rect');\n hitRect.setAttribute('x', '0');\n hitRect.setAttribute('y', '0');\n hitRect.setAttribute('width', vbWidth);\n hitRect.setAttribute('height', vbHeight);\n hitRect.setAttribute('fill', 'transparent');\n hitRect.setAttribute('stroke', 'none');\n g.insertBefore(hitRect, g.firstChild);\n\n svg.appendChild(g);\n\n // Wrap as IconShape\n const iconShape = new window.IconShape(g);\n window.shapes.push(iconShape);\n if (window.pushCreateAction) window.pushCreateAction(iconShape);\n if (frame?.addShapeToFrame) frame.addShapeToFrame(iconShape);\n\n // Remove placeholder\n if (placeholderShape) {\n const idx = window.shapes.indexOf(placeholderShape);\n if (idx !== -1) window.shapes.splice(idx, 1);\n if (placeholderShape.group && placeholderShape.group.parentNode) {\n placeholderShape.group.parentNode.removeChild(placeholderShape.group);\n }\n }\n }\n } catch (err) {\n console.warn('[AIRenderer] Icon fetch failed for keyword:', keyword, err);\n // Placeholder rectangle remains visible as fallback\n }\n}\n\n// ============================================================\n// HELPERS\n// ============================================================\n\n/**\n * Create an interactive TextShape label at (x, y) and add it to the frame.\n * Sets data-type=\"text-group\" so the text tool recognizes it for\n * click-to-select and double-click-to-edit.\n */\nfunction createLabel(text, x, y, fontSize, fill, frame) {\n const svg = window.svg;\n if (!svg || !window.TextShape) return null;\n\n try {\n const g = document.createElementNS(NS, 'g');\n g.setAttribute('data-type', 'text-group');\n g.setAttribute('transform', `translate(${x}, ${y})`);\n g.setAttribute('data-x', x);\n g.setAttribute('data-y', y);\n\n const t = document.createElementNS(NS, 'text');\n t.setAttribute('x', 0);\n t.setAttribute('y', 0);\n t.setAttribute('text-anchor', 'middle');\n t.setAttribute('dominant-baseline', 'central');\n t.setAttribute('fill', fill);\n t.setAttribute('font-size', fontSize);\n t.setAttribute('font-family', 'lixFont, sans-serif');\n t.setAttribute('data-initial-font', 'lixFont');\n t.setAttribute('data-initial-color', fill);\n t.setAttribute('data-initial-size', fontSize + 'px');\n t.textContent = text;\n\n g.appendChild(t);\n svg.appendChild(g);\n\n const shape = new window.TextShape(g);\n window.shapes.push(shape);\n if (window.pushCreateAction) window.pushCreateAction(shape);\n if (frame?.addShapeToFrame) frame.addShapeToFrame(shape);\n return shape;\n } catch (err) {\n console.warn('[AIRenderer] Label creation failed:', err);\n return null;\n }\n}\n\n/**\n * Like getEdgePoint but spreads multiple connections along the exit edge.\n * count = total edges leaving this side, idx = 0-based index of this edge.\n */\nfunction getSpreadEdgePoint(node, targetNode, count, idx) {\n if (count <= 1) return getEdgePoint(node, targetNode);\n\n const dx = targetNode.centerX - node.centerX;\n const dy = targetNode.centerY - node.centerY;\n const hw = node.width / 2;\n const hh = node.height / 2;\n\n // Spread ratio: distribute along 60% of the edge length\n const spread = 0.6;\n const t = count === 1 ? 0.5 : idx / (count - 1);\n const offset = (t - 0.5) * spread;\n\n if (Math.abs(dx) < 0.001 || Math.abs(dy) * hw > Math.abs(dx) * hh) {\n const px = node.centerX + offset * node.width;\n const py = dy > 0 ? node.y + node.height : node.y;\n return { x: px, y: py };\n }\n const px = dx > 0 ? node.x + node.width : node.x;\n const py = node.centerY + offset * node.height;\n return { x: px, y: py };\n}\n\n/**\n * Get the connection point on a node's boundary toward another node.\n * Uses the angle between centers to pick the closest edge (top/bottom/left/right).\n */\nfunction getEdgePoint(node, targetNode) {\n const dx = targetNode.centerX - node.centerX;\n const dy = targetNode.centerY - node.centerY;\n const hw = node.width / 2;\n const hh = node.height / 2;\n\n if (Math.abs(dx) < 0.001 || Math.abs(dy) * hw > Math.abs(dx) * hh) {\n if (dy > 0) return { x: node.centerX, y: node.y + node.height };\n return { x: node.centerX, y: node.y };\n }\n if (dx > 0) return { x: node.x + node.width, y: node.centerY };\n return { x: node.x, y: node.centerY };\n}\n\n// ============================================================\n// PREVIEW (for AI Modal)\n// ============================================================\n\n/**\n * Generate a simple SVG preview string from a diagram JSON.\n * Used inside the AI modal before placing on canvas.\n */\nexport function generatePreviewSVG(diagram, width = 500, height = 350) {\n if (!diagram?.nodes?.length) return '';\n\n const nodes = diagram.nodes;\n const edges = diagram.edges || [];\n\n // Compute bounds\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n nodes.forEach(n => {\n minX = Math.min(minX, n.x);\n minY = Math.min(minY, n.y);\n maxX = Math.max(maxX, n.x + (n.width || NODE_W));\n maxY = Math.max(maxY, n.y + (n.height || NODE_H));\n });\n\n const dw = maxX - minX || 1;\n const dh = maxY - minY || 1;\n const pad = 40;\n const scale = Math.min((width - pad * 2) / dw, (height - pad * 2) / dh, 1.5);\n const offX = (width - dw * scale) / 2 - minX * scale;\n const offY = (height - dh * scale) / 2 - minY * scale;\n\n // Build node lookup for edge rendering\n const nodeById = new Map();\n nodes.forEach(n => {\n const nx = n.x * scale + offX;\n const ny = n.y * scale + offY;\n const nw = (n.width || NODE_W) * scale;\n const nh = (n.height || NODE_H) * scale;\n nodeById.set(n.id, { x: nx, y: ny, w: nw, h: nh, cx: nx + nw / 2, cy: ny + nh / 2 });\n });\n\n let svgContent = '';\n\n // Draw edges\n edges.forEach(e => {\n const f = nodeById.get(e.from);\n const t = nodeById.get(e.to);\n if (!f || !t) return;\n\n const directed = e.directed !== false;\n const eColor = e.stroke || '#666';\n const markerId = directed ? `url(#preview-arrow-${eColor.replace('#', '')})` : '';\n\n // Add a per-color marker if needed\n if (directed && !svgContent.includes(`id=\"preview-arrow-${eColor.replace('#', '')}\"`)) {\n svgContent = `<marker id=\"preview-arrow-${eColor.replace('#', '')}\" markerWidth=\"8\" markerHeight=\"6\" refX=\"8\" refY=\"3\" orient=\"auto\"><path d=\"M0,0 L8,3 L0,6\" fill=\"none\" stroke=\"${eColor}\" stroke-width=\"1\" /></marker>` + svgContent;\n }\n\n const eDash = e.lineStyle === 'dashed' ? ' stroke-dasharray=\"5 3\"' : e.lineStyle === 'dotted' ? ' stroke-dasharray=\"2 2\"' : '';\n\n // Render curved path if nodes aren't aligned (creates a natural curve)\n const dx = t.cx - f.cx;\n const dy = t.cy - f.cy;\n const dist = Math.sqrt(dx * dx + dy * dy);\n let mx = (f.cx + t.cx) / 2;\n let my = (f.cy + t.cy) / 2;\n\n if (dist > 0 && Math.abs(dy) > 10 && Math.abs(dx) > 10) {\n // Curved edge: perpendicular offset for a quadratic Bezier\n const perpX = -dy / dist;\n const perpY = dx / dist;\n const curveAmt = dist * 0.15;\n const cpx = mx + perpX * curveAmt;\n const cpy = my + perpY * curveAmt;\n // Quadratic bezier midpoint for label\n mx = 0.25 * f.cx + 0.5 * cpx + 0.25 * t.cx;\n my = 0.25 * f.cy + 0.5 * cpy + 0.25 * t.cy;\n svgContent += `<path d=\"M ${f.cx} ${f.cy} Q ${cpx} ${cpy} ${t.cx} ${t.cy}\" fill=\"none\" stroke=\"${eColor}\" stroke-width=\"1.5\"${eDash} marker-end=\"${markerId}\" />`;\n } else {\n svgContent += `<line x1=\"${f.cx}\" y1=\"${f.cy}\" x2=\"${t.cx}\" y2=\"${t.cy}\" stroke=\"${eColor}\" stroke-width=\"1.5\"${eDash} marker-end=\"${markerId}\" />`;\n }\n\n if (e.label) {\n svgContent += `<text x=\"${mx}\" y=\"${my - 8}\" text-anchor=\"middle\" fill=\"${eColor === '#666' ? '#888' : eColor}\" font-size=\"9\" font-family=\"lixFont, sans-serif\">${escapeXml(e.label)}</text>`;\n }\n });\n\n // Draw nodes\n nodes.forEach(n => {\n const d = nodeById.get(n.id);\n if (!d) return;\n\n const nStroke = n.stroke || '#9090c0';\n const nFill = n.fill || 'transparent';\n const nDash = n.strokeDasharray ? ` stroke-dasharray=\"${n.strokeDasharray}\"` : '';\n\n if (n.type === 'circle') {\n svgContent += `<ellipse cx=\"${d.cx}\" cy=\"${d.cy}\" rx=\"${d.w / 2}\" ry=\"${d.h / 2}\" fill=\"${nFill}\" stroke=\"${nStroke}\" stroke-width=\"1.5\"${nDash} />`;\n } else if (n.type === 'diamond') {\n const sz = Math.min(d.w, d.h) * 0.7;\n svgContent += `<rect x=\"${d.cx - sz / 2}\" y=\"${d.cy - sz / 2}\" width=\"${sz}\" height=\"${sz}\" fill=\"${nFill}\" stroke=\"${nStroke}\" stroke-width=\"1.5\"${nDash} transform=\"rotate(45, ${d.cx}, ${d.cy})\" />`;\n } else if (n.type === 'roundrect') {\n svgContent += `<rect x=\"${d.x}\" y=\"${d.y}\" width=\"${d.w}\" height=\"${d.h}\" rx=\"${Math.min(d.w, d.h) * 0.2}\" fill=\"${nFill}\" stroke=\"${nStroke}\" stroke-width=\"1.5\"${nDash} />`;\n } else {\n svgContent += `<rect x=\"${d.x}\" y=\"${d.y}\" width=\"${d.w}\" height=\"${d.h}\" rx=\"4\" fill=\"${nFill}\" stroke=\"${nStroke}\" stroke-width=\"1.5\"${nDash} />`;\n }\n\n // Label \u2014 ensure readable color\n if (n.label) {\n const fontSize = Math.max(8, Math.min(12, 11 * scale));\n let labelFill = nStroke === '#9090c0' ? '#d0d0d0' : nStroke;\n if (isColorTooDark(labelFill)) labelFill = '#d0d0d0';\n // Icon nodes: label below the icon\n const labelY = n.type === 'icon' ? d.cy + d.h / 2 + 12 * scale : d.cy;\n svgContent += `<text x=\"${d.cx}\" y=\"${labelY}\" text-anchor=\"middle\" dominant-baseline=\"central\" fill=\"${labelFill}\" font-size=\"${fontSize}\" font-family=\"lixFont, sans-serif\">${escapeXml(n.label)}</text>`;\n }\n });\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\">\n <defs>${svgContent.match(/<marker[^]*?<\\/marker>/g)?.join('') || ''}</defs>\n ${svgContent.replace(/<marker[^]*?<\\/marker>/g, '')}\n</svg>`;\n}\n\nfunction escapeXml(str) {\n return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n}\n\n/**\n * Check if a hex color is too dark to read on a dark canvas (#1a1a2e).\n * Returns true if perceived luminance is below threshold.\n */\nfunction isColorTooDark(hex) {\n if (!hex || hex === 'transparent' || hex === 'none') return false;\n const c = hex.replace('#', '');\n if (c.length < 6) return false;\n const r = parseInt(c.substring(0, 2), 16);\n const g = parseInt(c.substring(2, 4), 16);\n const b = parseInt(c.substring(4, 6), 16);\n // Relative luminance (perceived brightness)\n const lum = (0.299 * r + 0.587 * g + 0.114 * b);\n return lum < 80; // Below ~31% brightness \u2014 unreadable on dark bg\n}\n\n/**\n * Generate a preview SVG from an existing Frame's DOM contents.\n * Used when the user opens the AI edit dialog for a frame \u2014\n * shows the current state of the frame as an SVG preview.\n */\nexport function generateFramePreviewSVG(frame, width = 500, height = 350) {\n if (!frame || !frame.clipGroup) return '';\n\n const fx = frame.x, fy = frame.y, fw = frame.width, fh = frame.height;\n if (fw <= 0 || fh <= 0) return '';\n\n const pad = 30;\n const scale = Math.min((width - pad * 2) / fw, (height - pad * 2) / fh, 1.5);\n const offX = (width - fw * scale) / 2 - fx * scale;\n const offY = (height - fh * scale) / 2 - fy * scale;\n\n let svgContent = '';\n\n // Frame border\n svgContent += `<rect x=\"${fx * scale + offX}\" y=\"${fy * scale + offY}\" width=\"${fw * scale}\" height=\"${fh * scale}\" rx=\"6\" fill=\"transparent\" stroke=\"#555\" stroke-width=\"1.5\" stroke-dasharray=\"6 3\" />`;\n\n // Frame label\n if (frame.frameName) {\n svgContent += `<text x=\"${fx * scale + offX + 10}\" y=\"${fy * scale + offY + 16}\" fill=\"#888\" font-size=\"11\" font-family=\"lixFont, sans-serif\">${escapeXml(frame.frameName)}</text>`;\n }\n\n // Render contained shapes\n if (frame.containedShapes) {\n frame.containedShapes.forEach(shape => {\n if (!shape) return;\n\n if (shape.shapeName === 'rectangle') {\n const sx = shape.x * scale + offX;\n const sy = shape.y * scale + offY;\n const sw = shape.width * scale;\n const sh = shape.height * scale;\n const stroke = shape.options?.stroke || '#e0e0e0';\n const fill = shape.options?.fill || 'transparent';\n if (shape.rotation === 45) {\n const sz = Math.min(sw, sh) * 0.7;\n const rcx = sx + sw / 2, rcy = sy + sh / 2;\n svgContent += `<rect x=\"${rcx - sz / 2}\" y=\"${rcy - sz / 2}\" width=\"${sz}\" height=\"${sz}\" fill=\"${fill}\" stroke=\"${stroke}\" stroke-width=\"1.5\" transform=\"rotate(45, ${rcx}, ${rcy})\" />`;\n // Embedded label for diamond\n if (shape.label) {\n let lf = shape.labelColor || stroke;\n if (isColorTooDark(lf)) lf = '#d0d0d0';\n const fs = Math.max(8, (shape.labelFontSize || 14) * scale);\n svgContent += `<text x=\"${rcx}\" y=\"${rcy}\" text-anchor=\"middle\" dominant-baseline=\"central\" fill=\"${lf}\" font-size=\"${fs}\" font-family=\"lixFont, sans-serif\">${escapeXml(shape.label)}</text>`;\n }\n } else {\n svgContent += `<rect x=\"${sx}\" y=\"${sy}\" width=\"${sw}\" height=\"${sh}\" rx=\"4\" fill=\"${fill}\" stroke=\"${stroke}\" stroke-width=\"1.5\" />`;\n // Embedded label\n if (shape.label) {\n let lf = shape.labelColor || stroke;\n if (isColorTooDark(lf)) lf = '#d0d0d0';\n const fs = Math.max(8, (shape.labelFontSize || 14) * scale);\n svgContent += `<text x=\"${sx + sw / 2}\" y=\"${sy + sh / 2}\" text-anchor=\"middle\" dominant-baseline=\"central\" fill=\"${lf}\" font-size=\"${fs}\" font-family=\"lixFont, sans-serif\">${escapeXml(shape.label)}</text>`;\n }\n }\n } else if (shape.shapeName === 'circle') {\n const ccx = shape.x * scale + offX;\n const ccy = shape.y * scale + offY;\n const crx = (shape.rx || 30) * scale;\n const cry = (shape.ry || 30) * scale;\n const stroke = shape.options?.stroke || '#e0e0e0';\n const fill = shape.options?.fill || 'transparent';\n svgContent += `<ellipse cx=\"${ccx}\" cy=\"${ccy}\" rx=\"${crx}\" ry=\"${cry}\" fill=\"${fill}\" stroke=\"${stroke}\" stroke-width=\"1.5\" />`;\n // Embedded label\n if (shape.label) {\n let lf = shape.labelColor || stroke;\n if (isColorTooDark(lf)) lf = '#d0d0d0';\n const fs = Math.max(8, (shape.labelFontSize || 14) * scale);\n svgContent += `<text x=\"${ccx}\" y=\"${ccy}\" text-anchor=\"middle\" dominant-baseline=\"central\" fill=\"${lf}\" font-size=\"${fs}\" font-family=\"lixFont, sans-serif\">${escapeXml(shape.label)}</text>`;\n }\n } else if (shape.shapeName === 'text') {\n const textEl = shape.group?.querySelector('text');\n if (textEl) {\n const tx = parseFloat(shape.group.getAttribute('data-x') || '0');\n const ty = parseFloat(shape.group.getAttribute('data-y') || '0');\n const fill = textEl.getAttribute('fill') || '#e0e0e0';\n const fontSize = Math.max(8, (parseFloat(textEl.getAttribute('font-size')) || 14) * scale);\n const text = textEl.textContent || '';\n let labelFill = fill;\n if (isColorTooDark(labelFill)) labelFill = '#d0d0d0';\n svgContent += `<text x=\"${tx * scale + offX}\" y=\"${ty * scale + offY}\" text-anchor=\"middle\" dominant-baseline=\"central\" fill=\"${labelFill}\" font-size=\"${fontSize}\" font-family=\"lixFont, sans-serif\">${escapeXml(text)}</text>`;\n }\n } else if (shape.shapeName === 'arrow') {\n const sp = shape.startPoint, ep = shape.endPoint;\n if (sp && ep) {\n const stroke = shape.options?.stroke || '#e0e0e0';\n const sx1 = sp.x * scale + offX, sy1 = sp.y * scale + offY;\n const sx2 = ep.x * scale + offX, sy2 = ep.y * scale + offY;\n // Render curved if arrow has control points\n if (shape.arrowCurved === 'curved' && shape.controlPoint1 && shape.controlPoint2) {\n const cp1x = shape.controlPoint1.x * scale + offX;\n const cp1y = shape.controlPoint1.y * scale + offY;\n const cp2x = shape.controlPoint2.x * scale + offX;\n const cp2y = shape.controlPoint2.y * scale + offY;\n svgContent += `<path d=\"M ${sx1} ${sy1} C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${sx2} ${sy2}\" fill=\"none\" stroke=\"${stroke}\" stroke-width=\"1.5\" marker-end=\"url(#frame-preview-arrow)\" />`;\n } else {\n svgContent += `<line x1=\"${sx1}\" y1=\"${sy1}\" x2=\"${sx2}\" y2=\"${sy2}\" stroke=\"${stroke}\" stroke-width=\"1.5\" marker-end=\"url(#frame-preview-arrow)\" />`;\n }\n // Arrow label\n if (shape.label) {\n const amx = (sx1 + sx2) / 2, amy = (sy1 + sy2) / 2 - 8;\n const afs = Math.max(7, (shape.labelFontSize || 11) * scale);\n svgContent += `<text x=\"${amx}\" y=\"${amy}\" text-anchor=\"middle\" fill=\"${shape.labelColor || stroke}\" font-size=\"${afs}\" font-family=\"lixFont, sans-serif\">${escapeXml(shape.label)}</text>`;\n }\n }\n } else if (shape.shapeName === 'line') {\n const sp = shape.startPoint, ep = shape.endPoint;\n if (sp && ep) {\n const stroke = shape.options?.stroke || '#e0e0e0';\n const sx1 = sp.x * scale + offX, sy1 = sp.y * scale + offY;\n const sx2 = ep.x * scale + offX, sy2 = ep.y * scale + offY;\n // Render curved if line has control point\n if (shape.isCurved && shape.controlPoint) {\n const cpx = shape.controlPoint.x * scale + offX;\n const cpy = shape.controlPoint.y * scale + offY;\n svgContent += `<path d=\"M ${sx1} ${sy1} Q ${cpx} ${cpy} ${sx2} ${sy2}\" fill=\"none\" stroke=\"${stroke}\" stroke-width=\"1.5\" />`;\n } else {\n svgContent += `<line x1=\"${sx1}\" y1=\"${sy1}\" x2=\"${sx2}\" y2=\"${sy2}\" stroke=\"${stroke}\" stroke-width=\"1.5\" />`;\n }\n // Line label\n if (shape.label) {\n const lmx = (sx1 + sx2) / 2, lmy = (sy1 + sy2) / 2 - 8;\n const lfs = Math.max(7, (shape.labelFontSize || 11) * scale);\n svgContent += `<text x=\"${lmx}\" y=\"${lmy}\" text-anchor=\"middle\" fill=\"${shape.labelColor || stroke}\" font-size=\"${lfs}\" font-family=\"lixFont, sans-serif\">${escapeXml(shape.label)}</text>`;\n }\n }\n } else if (shape.shapeName === 'icon') {\n const ix = parseFloat(shape.group?.getAttribute('data-shape-x') || '0');\n const iy = parseFloat(shape.group?.getAttribute('data-shape-y') || '0');\n const iw = parseFloat(shape.group?.getAttribute('data-shape-width') || '40');\n const ih = parseFloat(shape.group?.getAttribute('data-shape-height') || '40');\n const pix = ix * scale + offX;\n const piy = iy * scale + offY;\n const piw = iw * scale;\n const pih = ih * scale;\n\n // Try to extract actual icon SVG paths from the shape's group\n const iconPaths = shape.group?.querySelectorAll('path, circle, rect, polygon, polyline, line, ellipse');\n if (iconPaths && iconPaths.length > 0) {\n // Get viewbox dimensions for proper scaling\n const vbW = parseFloat(shape.group?.getAttribute('data-viewbox-width') || iw);\n const vbH = parseFloat(shape.group?.getAttribute('data-viewbox-height') || ih);\n const iconScale = Math.min(piw / vbW, pih / vbH);\n svgContent += `<g transform=\"translate(${pix}, ${piy}) scale(${iconScale})\">`;\n iconPaths.forEach(p => {\n // Skip hit-detection rects (transparent fill, no stroke)\n if (p.tagName === 'rect' && p.getAttribute('fill') === 'transparent' && p.getAttribute('stroke') === 'none') return;\n const clone = p.cloneNode(true);\n svgContent += clone.outerHTML;\n });\n svgContent += `</g>`;\n } else {\n // Fallback: dashed bounding box with \"icon\" text\n svgContent += `<rect x=\"${pix}\" y=\"${piy}\" width=\"${piw}\" height=\"${pih}\" rx=\"4\" fill=\"transparent\" stroke=\"#9090c0\" stroke-width=\"1\" stroke-dasharray=\"3 2\" />`;\n svgContent += `<text x=\"${pix + piw / 2}\" y=\"${piy + pih / 2}\" text-anchor=\"middle\" dominant-baseline=\"central\" fill=\"#9090c0\" font-size=\"9\" font-family=\"lixFont\">icon</text>`;\n }\n } else if (shape.shapeName === 'frame') {\n // Sub-frame\n const sx = shape.x * scale + offX;\n const sy = shape.y * scale + offY;\n const sw = shape.width * scale;\n const sh = shape.height * scale;\n svgContent += `<rect x=\"${sx}\" y=\"${sy}\" width=\"${sw}\" height=\"${sh}\" rx=\"4\" fill=\"transparent\" stroke=\"${shape.options?.stroke || '#555'}\" stroke-width=\"1\" stroke-dasharray=\"4 2\" opacity=\"0.6\" />`;\n if (shape.frameName) {\n svgContent += `<text x=\"${sx + 6}\" y=\"${sy + 12}\" fill=\"#888\" font-size=\"9\" font-family=\"lixFont\">${escapeXml(shape.frameName)}</text>`;\n }\n }\n });\n }\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\">\n <defs><marker id=\"frame-preview-arrow\" markerWidth=\"8\" markerHeight=\"6\" refX=\"8\" refY=\"3\" orient=\"auto\"><path d=\"M0,0 L8,3 L0,6\" fill=\"none\" stroke=\"#e0e0e0\" stroke-width=\"1\" /></marker></defs>\n ${svgContent}\n</svg>`;\n}\n\n// ============================================================\n// CANVAS BACKGROUND CONTRAST\n// ============================================================\n\nfunction colorRgb(value) {\n if (!value || typeof value !== 'string') return null;\n const rgbMatch = value.trim().match(/^rgba?\\(\\s*(\\d+(?:\\.\\d+)?)\\s*[, ]\\s*(\\d+(?:\\.\\d+)?)\\s*[, ]\\s*(\\d+(?:\\.\\d+)?)/i);\n if (rgbMatch) {\n return {\n r: Math.min(255, Number(rgbMatch[1])),\n g: Math.min(255, Number(rgbMatch[2])),\n b: Math.min(255, Number(rgbMatch[3])),\n };\n }\n let hex = value.trim().replace('#', '');\n if (hex.length === 3) hex = hex.split('').map(char => char + char).join('');\n if (!/^[0-9a-f]{6}$/i.test(hex)) return null;\n return {\n r: parseInt(hex.slice(0, 2), 16),\n g: parseInt(hex.slice(2, 4), 16),\n b: parseInt(hex.slice(4, 6), 16),\n };\n}\n\nfunction relativeLuminance(value) {\n const rgb = colorRgb(value);\n if (!rgb) return null;\n const channel = component => {\n const normalized = component / 255;\n return normalized <= .03928 ? normalized / 12.92 : Math.pow((normalized + .055) / 1.055, 2.4);\n };\n return .2126 * channel(rgb.r) + .7152 * channel(rgb.g) + .0722 * channel(rgb.b);\n}\n\nfunction contrastRatio(a, b) {\n const first = relativeLuminance(a);\n const second = relativeLuminance(b);\n if (first == null || second == null) return 1;\n return (Math.max(first, second) + .05) / (Math.min(first, second) + .05);\n}\n\nfunction readableForeground(background) {\n return contrastRatio('#34304a', background) >= contrastRatio('#f6f2fb', background)\n ? '#34304a'\n : '#f6f2fb';\n}\n\nfunction readableColor(color, background, minimum = 3) {\n if (!colorRgb(color) || contrastRatio(color, background) >= minimum) return color;\n return readableForeground(background);\n}\n\nexport function adaptCanvasContrast(background) {\n if (typeof window === 'undefined' || !Array.isArray(window.shapes)) return;\n const foreground = readableForeground(background);\n const muted = foreground === '#34304a' ? '#716a7d' : '#c8bddb';\n\n window.__canvasContrastColor = foreground;\n window.__ensureCanvasContrast = readableColor;\n\n for (const shape of window.shapes) {\n if (!shape) continue;\n if (typeof shape.adaptToBackground === 'function') {\n shape.adaptToBackground(background, foreground, muted);\n continue;\n }\n\n const owner = shape.parentFrame;\n const generated = !!(shape._diagramType || shape._frameType === 'graph' || owner?._diagramType || owner?._frameType === 'graph');\n const fill = shape.options?.fill;\n const solidFill = fill && fill !== 'transparent' && fill !== 'none';\n\n if (shape.options?.closedFill) {\n shape.options.outlineStroke = background;\n if (typeof shape.draw === 'function') shape.draw();\n continue;\n }\n\n if (shape.options?.stroke && (generated || ['#fff', '#ffffff', '#000', '#000000', '#1a1a2e'].includes(shape.options.stroke.toLowerCase()))) {\n shape.options.stroke = readableColor(shape.options.stroke, background, 3);\n }\n if (shape.shapeName === 'frame' && generated && shape.options) {\n shape.options.stroke = muted;\n shape.options.labelColor = foreground;\n }\n if ('labelColor' in shape && generated) {\n shape.labelColor = solidFill ? readableColor(shape.labelColor || foreground, fill, 4.5) : foreground;\n }\n if (shape.group && generated) {\n shape.group.querySelectorAll('text').forEach(text => {\n const current = text.getAttribute('fill') || foreground;\n text.setAttribute('fill', solidFill ? readableColor(current, fill, 4.5) : readableColor(current, background, 4.5));\n });\n }\n if (typeof shape.draw === 'function') shape.draw();\n }\n}\n\n// ============================================================\n// INIT\n// ============================================================\n\nexport function initAIRenderer() {\n // Expose the autoAttach helper so sibling renderers (Mermaid flowchart,\n // Graph, LixScript) can wire arrow endpoints into shapes without\n // import-cycling through this large module.\n window.__autoAttach = autoAttach;\n window.__adaptCanvasContrast = adaptCanvasContrast;\n\n // Lazy-load sequence renderer\n let _seqParser = null;\n let _seqPreview = null;\n let _seqCanvas = null;\n\n // Lazy-load flowchart renderer\n let _fcPreview = null;\n let _fcCanvas = null;\n\n // Lazy-load ER / chart renderer\n let _structured = null;\n\n async function loadSequenceRenderer() {\n if (_seqParser) return;\n const mod = await import('./MermaidSequenceParser.js');\n const rend = await import('./MermaidSequenceRenderer.js');\n _seqParser = mod.parseSequenceDiagram;\n _seqPreview = rend.renderSequencePreviewSVG;\n _seqCanvas = rend.renderSequenceOnCanvas;\n }\n\n async function loadFlowchartRenderer() {\n if (_fcPreview) return;\n const mod = await import('./MermaidFlowchartRenderer.js');\n _fcPreview = mod.renderFlowchartPreviewSVG;\n _fcCanvas = mod.renderFlowchartOnCanvas;\n }\n\n async function loadStructuredRenderer() {\n if (_structured) return;\n _structured = await import('./MermaidStructuredRenderer.js');\n }\n\n function mermaidHeader(src) {\n return src.split('\\n').map(line => line.trim()).find(line => line && !line.startsWith('%%'))?.toLowerCase() || '';\n }\n\n // Detect if source is a sequence diagram\n function isSequenceDiagram(src) {\n return mermaidHeader(src) === 'sequencediagram';\n }\n\n function structuredType(src) {\n const header = mermaidHeader(src);\n if (header === 'erdiagram') return 'er';\n if (/^pie(?:\\s|$)/.test(header) || /^xychart(?:-beta)?(?:\\s|$)/.test(header)) return 'chart';\n return null;\n }\n\n window.__aiRenderer = renderAIDiagram;\n window.__aiPreview = generatePreviewSVG;\n window.__aiFramePreview = generateFramePreviewSVG;\n\n // Unified mermaid parser: supports graph/flowchart + sequenceDiagram\n window.__mermaidParser = (src) => {\n if (isSequenceDiagram(src)) {\n try {\n if (_seqParser) return _seqParser(src);\n loadSequenceRenderer();\n return { _pendingSequence: true, src };\n } catch {\n return null;\n }\n }\n if (structuredType(src)) {\n if (!_structured) {\n loadStructuredRenderer();\n return { _pendingStructured: true, src };\n }\n return structuredType(src) === 'er'\n ? _structured.parseERDiagram(src)\n : _structured.parseChartDiagram(src);\n }\n return parseMermaid(src);\n };\n\n // Unified mermaid preview: returns SVG for both flowchart and sequence\n window.__mermaidPreview = async (src) => {\n if (isSequenceDiagram(src)) {\n await loadSequenceRenderer();\n const diagram = _seqParser(src);\n if (!diagram) return '';\n return _seqPreview(diagram);\n }\n const type = structuredType(src);\n if (type) {\n await loadStructuredRenderer();\n const diagram = type === 'er' ? _structured.parseERDiagram(src) : _structured.parseChartDiagram(src);\n if (!diagram) return '';\n return type === 'er' ? _structured.renderERPreviewSVG(diagram) : _structured.renderChartPreviewSVG(diagram);\n }\n // Flowchart: use unified flowchart renderer\n await loadFlowchartRenderer();\n const diagram = parseMermaid(src);\n if (!diagram) return '';\n return _fcPreview(diagram);\n };\n\n // Unified mermaid renderer: places on canvas\n window.__mermaidRenderer = async (src) => {\n if (isSequenceDiagram(src)) {\n await loadSequenceRenderer();\n const diagram = _seqParser(src);\n if (!diagram) { console.error('[AIRenderer] Sequence parse failed'); return false; }\n return _seqCanvas(diagram);\n }\n const type = structuredType(src);\n if (type) {\n await loadStructuredRenderer();\n const diagram = type === 'er' ? _structured.parseERDiagram(src) : _structured.parseChartDiagram(src);\n if (!diagram) { console.error('[AIRenderer] Structured Mermaid parse failed'); return false; }\n return type === 'er' ? _structured.renderEROnCanvas(diagram) : _structured.renderChartOnCanvas(diagram);\n }\n // Flowchart: use unified flowchart renderer (same SVG as preview)\n await loadFlowchartRenderer();\n const diagram = parseMermaid(src);\n if (!diagram) { console.error('[AIRenderer] Mermaid parse failed'); return false; }\n return _fcCanvas(diagram);\n };\n\n // Pre-load renderers so they're ready\n loadSequenceRenderer();\n loadFlowchartRenderer();\n loadStructuredRenderer();\n}\n"],
|
|
5
|
-
"mappings": ";;;AAkBA,IAAM,SAAS;AACf,IAAM,SAAS;AACf,IAAM,YAAY;AAClB,IAAM,YAAY;AAClB,IAAM,KAAK;AAIX,IAAM,kBAAkB;AAMjB,SAAS,aAAa,KAAK;AAC9B,QAAM,QAAQ,IAAI,KAAK,EAAE,MAAM,IAAI,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC,EAAE,OAAO,OAAK,KAAK,CAAC,EAAE,WAAW,IAAI,CAAC;AAC5F,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,QAAM,cAAc,MAAM,CAAC,EAAE,MAAM,wCAAwC;AAC3E,QAAM,YAAY,cAAc,YAAY,CAAC,EAAE,YAAY,IAAI;AAC/D,QAAM,eAAe,cAAc,QAAQ,cAAc;AACzD,QAAM,WAAW,cAAc,IAAI;AAEnC,QAAM,WAAW,oBAAI,IAAI;AACzB,QAAM,QAAQ,CAAC;AACf,QAAM,YAAY,oBAAI,IAAI;AAC1B,QAAM,eAAe,CAAC;AACtB,QAAM,aAAa,oBAAI,IAAI;AAC3B,QAAM,YAAY,OAAO,aAAa,eAC/B,SAAS,MAAM,UAAU,SAAS,YAAY;AACrD,QAAM,UAAU,YACV;AAAA,IACE,EAAE,MAAM,WAAW,QAAQ,UAAU;AAAA,IACrC,EAAE,MAAM,WAAW,QAAQ,UAAU;AAAA,IACrC,EAAE,MAAM,WAAW,QAAQ,UAAU;AAAA,IACrC,EAAE,MAAM,WAAW,QAAQ,UAAU;AAAA,IACrC,EAAE,MAAM,WAAW,QAAQ,UAAU;AAAA,IACrC,EAAE,MAAM,WAAW,QAAQ,UAAU;AAAA,EACzC,IACE;AAAA,IACE,EAAE,MAAM,WAAW,QAAQ,UAAU;AAAA,IACrC,EAAE,MAAM,WAAW,QAAQ,UAAU;AAAA,IACrC,EAAE,MAAM,WAAW,QAAQ,UAAU;AAAA,IACrC,EAAE,MAAM,WAAW,QAAQ,UAAU;AAAA,IACrC,EAAE,MAAM,WAAW,QAAQ,UAAU;AAAA,IACrC,EAAE,MAAM,WAAW,QAAQ,UAAU;AAAA,EACzC;AAEJ,WAAS,gBAAgB,OAAO;AAC5B,UAAM,QAAQ,CAAC;AACf,eAAW,QAAQ,MAAM,MAAM,GAAG,GAAG;AACjC,YAAM,YAAY,KAAK,QAAQ,GAAG;AAClC,UAAI,YAAY,EAAG;AACnB,YAAM,MAAM,KAAK,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,YAAY;AACxD,YAAM,MAAM,KAAK,MAAM,YAAY,CAAC,EAAE,KAAK;AAC3C,UAAI,QAAQ,OAAQ,OAAM,OAAO;AAAA,eACxB,QAAQ,SAAU,OAAM,SAAS;AAAA,eACjC,QAAQ,eAAgB,OAAM,cAAc,WAAW,GAAG;AAAA,eAC1D,QAAQ,QAAS,OAAM,aAAa;AAAA,IACjD;AACA,WAAO;AAAA,EACX;AAGA,WAAS,WAAW,OAAO;AACvB,WAAO,MAAM,QAAQ,gBAAgB,IAAI,EAAE,QAAQ,MAAM,EAAE;AAAA,EAC/D;AAEA,WAAS,aAAa,KAAK;AACvB,UAAM,IAAI,KAAK;AACf,QAAI,CAAC,IAAK,QAAO;AACjB,QAAI,IAAI,OAAO;AAGf,QAAI,IAAI,IAAI,MAAM,sBAAsB;AACxC,QAAI,GAAG;AAAE,WAAK,EAAE,CAAC;AAAG,cAAQ,EAAE,CAAC;AAAG,aAAO;AAAA,IAAU;AAEnD,QAAI,CAAC,GAAG;AAAE,UAAI,IAAI,MAAM,kBAAkB;AAAG,UAAI,GAAG;AAAE,aAAK,EAAE,CAAC;AAAG,gBAAQ,EAAE,CAAC;AAAG,eAAO;AAAA,MAAW;AAAA,IAAE;AAEnG,QAAI,CAAC,GAAG;AAAE,UAAI,IAAI,MAAM,iBAAiB;AAAG,UAAI,GAAG;AAAE,aAAK,EAAE,CAAC;AAAG,gBAAQ,EAAE,CAAC;AAAG,eAAO;AAAA,MAAc;AAAA,IAAE;AAErG,QAAI,CAAC,GAAG;AAAE,UAAI,IAAI,MAAM,kBAAkB;AAAG,UAAI,GAAG;AAAE,aAAK,EAAE,CAAC;AAAG,gBAAQ,EAAE,CAAC;AAAG,eAAO;AAAA,MAAa;AAAA,IAAE;AAErG,QAAI,CAAC,GAAG;AAAE,UAAI,IAAI,MAAM,kBAAkB;AAAG,UAAI,GAAG;AAAE,aAAK,EAAE,CAAC;AAAG,gBAAQ,EAAE,CAAC;AAAG,eAAO;AAAA,MAAa;AAAA,IAAE;AAErG,QAAI,CAAC,GAAG;AAAE,WAAK;AAAK,cAAQ;AAAK,aAAO;AAAA,IAAa;AAErD,YAAQ,WAAW,KAAK;AAExB,QAAI,CAAC,SAAS,IAAI,EAAE,GAAG;AACnB,eAAS,IAAI,IAAI,EAAE,IAAI,MAAM,MAAM,CAAC;AAAA,IACxC,WAAW,UAAU,IAAI;AACrB,eAAS,IAAI,EAAE,EAAE,QAAQ;AACzB,eAAS,IAAI,EAAE,EAAE,OAAO;AAAA,IAC5B;AACA,WAAO;AAAA,EACX;AAGA,QAAM,YAAY,CAAC;AACnB,MAAI,kBAAkB;AAEtB,WAAS,IAAI,UAAU,IAAI,MAAM,QAAQ,KAAK;AAqD1C,QAAS,gBAAT,SAAuB,QAAQ,MAAM;AACjC,UAAI,iBAAiB;AACjB,YAAI,UAAU,CAAC,gBAAgB,QAAQ,SAAS,MAAM,EAAG,iBAAgB,QAAQ,KAAK,MAAM;AAC5F,YAAI,QAAQ,CAAC,gBAAgB,QAAQ,SAAS,IAAI,EAAG,iBAAgB,QAAQ,KAAK,IAAI;AAAA,MAC1F;AAAA,IACJ;AAzDA,UAAM,OAAO,MAAM,CAAC,EAAE,QAAQ,MAAM,EAAE,EAAE,KAAK;AAC7C,QAAI,CAAC,KAAM;AAGX,UAAM,gBAAgB,KAAK,MAAM,4BAA4B;AAC7D,QAAI,eAAe;AACf,YAAM,OAAO,cAAc,CAAC;AAC5B,gBAAU,IAAI,MAAM,gBAAgB,cAAc,CAAC,EAAE,QAAQ,MAAM,EAAE,CAAC,CAAC;AACvE;AAAA,IACJ;AAKA,UAAM,aAAa,KAAK,MAAM,6BAA6B;AAC3D,QAAI,YAAY;AACZ,YAAM,QAAQ,gBAAgB,WAAW,CAAC,EAAE,QAAQ,MAAM,EAAE,CAAC;AAC7D,iBAAW,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,QAAM,GAAG,KAAK,CAAC,EAAE,OAAO,OAAO,EACvD,QAAQ,QAAM,WAAW,IAAI,IAAI,KAAK,CAAC;AAC5C;AAAA,IACJ;AAGA,QAAI,wBAAwB,KAAK,IAAI,EAAG;AAGxC,UAAM,aAAa,KAAK,MAAM,0BAA0B;AACxD,QAAI,YAAY;AACZ,YAAMA,WAAU,WAAW,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC;AAC1D,mBAAa,KAAK,EAAE,SAAAA,UAAS,WAAW,WAAW,CAAC,EAAE,CAAC;AACvD;AAAA,IACJ;AAGA,UAAM,UAAU,KAAK,MAAM,4CAA4C;AACvE,QAAI,SAAS;AACT,wBAAkB;AAAA,QACd,IAAI,QAAQ,CAAC;AAAA,QACb,OAAO,QAAQ,CAAC,KAAK,QAAQ,CAAC;AAAA,QAC9B,SAAS,CAAC;AAAA,MACd;AACA;AAAA,IACJ;AAGA,QAAI,KAAK,YAAY,MAAM,SAAS,iBAAiB;AACjD,gBAAU,KAAK,eAAe;AAC9B,wBAAkB;AAClB;AAAA,IACJ;AAWA,QAAI,QAAQ,KAAK,MAAM,mCAAmC;AAC1D,QAAI,OAAO;AACP,YAAM,SAAS,aAAa,MAAM,CAAC,EAAE,KAAK,CAAC;AAC3C,YAAM,OAAO,aAAa,MAAM,CAAC,EAAE,KAAK,CAAC;AACzC,UAAI,UAAU,KAAM,OAAM,KAAK,EAAE,MAAM,QAAQ,IAAI,MAAM,OAAO,WAAW,MAAM,CAAC,EAAE,KAAK,CAAC,GAAG,UAAU,MAAM,OAAO,SAAS,CAAC;AAC9H,oBAAc,QAAQ,IAAI;AAC1B;AAAA,IACJ;AAGA,YAAQ,KAAK,MAAM,4CAA4C;AAC/D,QAAI,OAAO;AACP,YAAM,SAAS,aAAa,MAAM,CAAC,EAAE,KAAK,CAAC;AAC3C,YAAM,OAAO,aAAa,MAAM,CAAC,EAAE,KAAK,CAAC;AACzC,YAAM,YAAY,MAAM,CAAC,IAAI,WAAW,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI;AAC3D,UAAI,UAAU,KAAM,OAAM,KAAK,EAAE,MAAM,QAAQ,IAAI,MAAM,OAAO,WAAW,UAAU,MAAM,OAAO,SAAS,CAAC;AAC5G,oBAAc,QAAQ,IAAI;AAC1B;AAAA,IACJ;AAGA,YAAQ,KAAK,MAAM,yCAAyC;AAC5D,QAAI,OAAO;AACP,YAAM,SAAS,aAAa,MAAM,CAAC,EAAE,KAAK,CAAC;AAC3C,YAAM,OAAO,aAAa,MAAM,CAAC,EAAE,KAAK,CAAC;AACzC,YAAM,YAAY,MAAM,CAAC,IAAI,WAAW,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI;AAC3D,UAAI,UAAU,KAAM,OAAM,KAAK,EAAE,MAAM,QAAQ,IAAI,MAAM,OAAO,WAAW,UAAU,MAAM,OAAO,QAAQ,CAAC;AAC3G,oBAAc,QAAQ,IAAI;AAC1B;AAAA,IACJ;AAGA,YAAQ,KAAK,MAAM,6CAA6C;AAChE,QAAI,SAAS,CAAC,MAAM,CAAC,EAAE,SAAS,GAAG,GAAG;AAClC,YAAM,SAAS,aAAa,MAAM,CAAC,EAAE,KAAK,CAAC;AAC3C,YAAM,OAAO,aAAa,MAAM,CAAC,EAAE,KAAK,CAAC;AACzC,YAAM,YAAY,MAAM,CAAC,IAAI,WAAW,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI;AAC3D,UAAI,UAAU,KAAM,OAAM,KAAK,EAAE,MAAM,QAAQ,IAAI,MAAM,OAAO,WAAW,UAAU,OAAO,OAAO,SAAS,CAAC;AAC7G,oBAAc,QAAQ,IAAI;AAC1B;AAAA,IACJ;AAGA,YAAQ,KAAK,MAAM,mDAAmD;AACtE,QAAI,OAAO;AACP,YAAM,SAAS,aAAa,MAAM,CAAC,EAAE,KAAK,CAAC;AAC3C,YAAM,OAAO,aAAa,MAAM,CAAC,EAAE,KAAK,CAAC;AACzC,YAAM,YAAY,MAAM,CAAC,IAAI,WAAW,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI;AAC3D,UAAI,UAAU,KAAM,OAAM,KAAK,EAAE,MAAM,QAAQ,IAAI,MAAM,OAAO,WAAW,UAAU,MAAM,OAAO,SAAS,CAAC;AAC5G,oBAAc,QAAQ,IAAI;AAC1B;AAAA,IACJ;AAGA,UAAM,SAAS,aAAa,IAAI;AAChC,QAAI,UAAU,iBAAiB;AAC3B,UAAI,CAAC,gBAAgB,QAAQ,SAAS,MAAM,EAAG,iBAAgB,QAAQ,KAAK,MAAM;AAAA,IACtF;AAAA,EACJ;AAEA,MAAI,SAAS,SAAS,EAAG,QAAO;AAGhC,aAAW,UAAU,cAAc;AAC/B,UAAM,QAAQ,UAAU,IAAI,OAAO,SAAS;AAC5C,QAAI,CAAC,MAAO;AACZ,eAAW,OAAO,OAAO,SAAS;AAC9B,YAAM,OAAO,SAAS,IAAI,GAAG;AAC7B,UAAI,MAAM;AACN,YAAI,MAAM,KAAM,MAAK,OAAO,MAAM;AAClC,YAAI,MAAM,OAAQ,MAAK,SAAS,MAAM;AACtC,YAAI,MAAM,YAAa,MAAK,cAAc,MAAM;AAAA,MACpD;AAAA,IACJ;AAAA,EACJ;AAGA,aAAW,CAAC,KAAK,KAAK,KAAK,YAAY;AACnC,UAAM,OAAO,SAAS,IAAI,GAAG;AAC7B,QAAI,KAAM,QAAO,OAAO,MAAM,KAAK;AAAA,EACvC;AAGA,QAAM,UAAU,MAAM,KAAK,SAAS,KAAK,CAAC;AAC1C,QAAM,WAAW,oBAAI,IAAI;AACzB,QAAM,UAAU,oBAAI,IAAI;AACxB,UAAQ,QAAQ,QAAM;AAAE,aAAS,IAAI,IAAI,CAAC,CAAC;AAAG,YAAQ,IAAI,IAAI,CAAC,CAAC;AAAA,EAAG,CAAC;AACpE,QAAM,QAAQ,OAAK;AACf,QAAI,SAAS,IAAI,EAAE,IAAI,EAAG,UAAS,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;AACxD,QAAI,QAAQ,IAAI,EAAE,EAAE,EAAG,SAAQ,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI;AAAA,EACxD,CAAC;AAED,QAAM,SAAS,oBAAI,IAAI;AACvB,QAAM,QAAQ,QAAQ,OAAO,QAAM,QAAQ,IAAI,EAAE,EAAE,WAAW,CAAC;AAC/D,MAAI,MAAM,WAAW,EAAG,OAAM,KAAK,QAAQ,CAAC,CAAC;AAE7C,QAAM,QAAQ,MAAM,IAAI,SAAO,EAAE,IAAI,OAAO,EAAE,EAAE;AAChD,QAAM,UAAU,oBAAI,IAAI;AACxB,SAAO,MAAM,SAAS,GAAG;AACrB,UAAM,EAAE,IAAI,MAAM,IAAI,MAAM,MAAM;AAClC,QAAI,QAAQ,IAAI,EAAE,GAAG;AAAE,UAAI,SAAS,OAAO,IAAI,EAAE,KAAK,GAAI,QAAO,IAAI,IAAI,KAAK;AAAG;AAAA,IAAU;AAC3F,YAAQ,IAAI,EAAE;AACd,WAAO,IAAI,IAAI,KAAK,IAAI,OAAO,OAAO,IAAI,EAAE,KAAK,CAAC,CAAC;AACnD,eAAW,SAAS,SAAS,IAAI,EAAE,KAAK,CAAC,EAAG,OAAM,KAAK,EAAE,IAAI,OAAO,OAAO,QAAQ,EAAE,CAAC;AAAA,EAC1F;AACA,UAAQ,QAAQ,QAAM;AAAE,QAAI,CAAC,QAAQ,IAAI,EAAE,EAAG,QAAO,IAAI,IAAI,CAAC;AAAA,EAAG,CAAC;AAElE,QAAM,cAAc,oBAAI,IAAI;AAC5B,SAAO,QAAQ,CAAC,OAAO,OAAO;AAC1B,QAAI,CAAC,YAAY,IAAI,KAAK,EAAG,aAAY,IAAI,OAAO,CAAC,CAAC;AACtD,gBAAY,IAAI,KAAK,EAAE,KAAK,EAAE;AAAA,EAClC,CAAC;AAGD,QAAM,QAAQ,CAAC;AACf,MAAI,eAAe;AACnB,QAAM,KAAK,YAAY,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE,QAAQ,CAAC,UAAU,OAAO;AAC3E,UAAM,QAAQ,YAAY,IAAI,QAAQ;AACtC,UAAM,cAAc,EAAE,MAAM,SAAS,aAAa,IAAI,YAAY;AAClE,UAAM,QAAQ,CAAC,IAAI,OAAO;AACtB,YAAM,KAAK,SAAS,IAAI,EAAE;AAC1B,YAAM,IAAI,eAAe,KAAK,YAAY,cAAc,KAAK;AAC7D,YAAM,IAAI,eAAe,cAAc,KAAK,YAAY,KAAK;AAE7D,YAAM,cAAc,GAAG,SAAS,IAAI,MAAM,IAAI;AAC9C,YAAM,aAAa,KAAK,IAAI,GAAG,WAAW,IAAI,OAAK,EAAE,MAAM,CAAC;AAC5D,YAAM,KAAK,KAAK,IAAI,QAAQ,aAAa,KAAK,EAAE;AAChD,YAAM,KAAK,KAAK,IAAI,QAAQ,WAAW,SAAS,KAAK,EAAE;AACvD,YAAM,KAAK;AAAA,QACP,IAAI,GAAG;AAAA,QAAI,MAAM,GAAG;AAAA,QAAM,OAAO,GAAG;AAAA,QACpC;AAAA,QAAG;AAAA,QAAG,OAAO;AAAA,QAAI,QAAQ;AAAA,QACzB,MAAM,GAAG,QAAQ,QAAQ,eAAe,QAAQ,MAAM,EAAE;AAAA,QACxD,QAAQ,GAAG,UAAU,QAAQ,eAAe,QAAQ,MAAM,EAAE;AAAA,QAC5D,aAAa,GAAG;AAAA,QAChB,YAAY,GAAG;AAAA,MACnB,CAAC;AACD,sBAAgB;AAAA,IACpB,CAAC;AAAA,EACL,CAAC;AAED,SAAO;AAAA,IACH,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,OAAO,MAAM,IAAI,QAAM;AAAA,MACnB,MAAM,EAAE;AAAA,MAAM,IAAI,EAAE;AAAA,MAAI,OAAO,EAAE;AAAA,MACjC,UAAU,EAAE,aAAa;AAAA,MACzB,OAAO,EAAE,SAAS;AAAA,IACtB,EAAE;AAAA,IACF,WAAW,UAAU,SAAS,IAAI,UAAU,IAAI,SAAO;AAAA,MACnD,IAAI,GAAG;AAAA,MAAI,OAAO,GAAG;AAAA,MAAO,OAAO,GAAG;AAAA,IAC1C,EAAE,IAAI;AAAA,EACV;AACJ;AAMO,SAAS,gBAAgB,SAAS;AACrC,MAAI,CAAC,SAAS,OAAO,QAAQ;AAAE,YAAQ,MAAM,8BAA8B;AAAG,WAAO;AAAA,EAAO;AAE5F,QAAM,QAAQ,QAAQ;AACtB,QAAM,QAAQ,QAAQ,SAAS,CAAC;AAChC,QAAM,QAAQ,QAAQ,SAAS;AAE/B,MAAI,CAAC,OAAO,OAAO,CAAC,OAAO,SAAS,CAAC,OAAO,WAAW;AACnD,YAAQ,MAAM,qCAAqC;AACnD,WAAO;AAAA,EACX;AAGA,QAAM,KAAK,OAAO,kBAAkB,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,OAAO,YAAY,QAAQ,OAAO,YAAY;AACvG,QAAM,MAAM,GAAG,IAAI,GAAG,QAAQ;AAC9B,QAAM,MAAM,GAAG,IAAI,GAAG,SAAS;AAG/B,MAAI,OAAO,UAAU,OAAO,UAAU,OAAO,WAAW,OAAO;AAC/D,QAAM,QAAQ,OAAK;AACf,WAAO,KAAK,IAAI,MAAM,EAAE,CAAC;AACzB,WAAO,KAAK,IAAI,MAAM,EAAE,CAAC;AACzB,WAAO,KAAK,IAAI,MAAM,EAAE,KAAK,EAAE,SAAS,OAAO;AAC/C,WAAO,KAAK,IAAI,MAAM,EAAE,KAAK,EAAE,UAAU,OAAO;AAAA,EACpD,CAAC;AAED,QAAM,KAAK,OAAO,MAAM,KAAK,OAAO;AACpC,QAAM,KAAK,MAAM,KAAK,IAAI;AAC1B,QAAM,KAAK,MAAM,KAAK,IAAI;AAO1B,QAAM,UAAU,UAAU,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAK3F,QAAM,QAAQ;AAAA,IACV,gBAAgB,GAAG;AAAE,UAAI,EAAG,GAAE,UAAU;AAAA,IAAS;AAAA,IACjD,cAAc;AAAA,IAAC;AAAA,IACf,kBAAkB;AAAA,IAAC;AAAA,IACnB,WAAW;AAAA,EACf;AAEA,QAAM,UAAU,oBAAI,IAAI;AAGxB,aAAW,QAAQ,OAAO;AACtB,UAAM,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI;AACtC,UAAM,KAAK,KAAK,SAAS,QAAQ,KAAK,KAAK,UAAU;AACrD,UAAM,KAAK,KAAK,KAAK,GAAG,KAAK,KAAK,KAAK;AACvC,QAAI,QAAQ;AAGZ,UAAM,WAAW;AAAA,MACb,QAAQ,KAAK,UAAU;AAAA,MACvB,aAAa,KAAK,eAAe;AAAA,MACjC,MAAM,KAAK,QAAQ;AAAA,MACnB,WAAW,KAAK,aAAa;AAAA,MAC7B,WAAW,KAAK,aAAa;AAAA,MAC7B,iBAAiB,KAAK,mBAAmB;AAAA;AAAA,MAEzC,YAAY,KAAK,cAAc;AAAA,MAC/B,cAAc,KAAK,iBAAiB,SAAY,KAAK,eAAe;AAAA,MACpE,gBAAgB,KAAK,kBAAkB;AAAA;AAAA,MAEvC,YAAY,KAAK,cAAc;AAAA,MAC/B,eAAe,KAAK,iBAAiB;AAAA,IACzC;AAEA,QAAI;AACA,UAAI,KAAK,SAAS,UAAU,KAAK,aAAa;AAG1C,gBAAQ,IAAI,OAAO,UAAU,IAAI,IAAI,IAAI,IAAI;AAAA,UACzC,GAAG;AAAA,UAAU,QAAQ,SAAS;AAAA,UAAQ,iBAAiB;AAAA,QAC3D,CAAC;AAED,0BAAkB,KAAK,aAAa,IAAI,IAAI,IAAI,IAAI,OAAO,KAAK;AAAA,MACpE,WAAW,KAAK,SAAS,YAAY,OAAO,QAAQ;AAChD,gBAAQ,IAAI,OAAO,OAAO,IAAI,IAAI,KAAK,GAAG,KAAK,GAAG,QAAQ;AAAA,MAC9D,WAAW,KAAK,SAAS,aAAa,OAAO,WAAW;AACpD,cAAM,KAAK,KAAK,IAAI,IAAI,EAAE,IAAI;AAC9B,gBAAQ,IAAI,OAAO,UAAU,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG,IAAI,IAAI,QAAQ;AACvE,cAAM,WAAW;AACjB,cAAM,KAAK;AAAA,MACf,WAAW,KAAK,SAAS,eAAe,OAAO,WAAW;AACtD,gBAAQ,IAAI,OAAO,UAAU,IAAI,IAAI,IAAI,IAAI,EAAE,GAAG,UAAU,cAAc,KAAK,IAAI,IAAI,EAAE,IAAI,IAAI,CAAC;AAAA,MACtG,WAAW,OAAO,WAAW;AACzB,gBAAQ,IAAI,OAAO,UAAU,IAAI,IAAI,IAAI,IAAI,QAAQ;AAAA,MACzD;AAAA,IACJ,SAAS,KAAK;AACV,cAAQ,KAAK,sCAAsC,KAAK,IAAI,GAAG;AAC/D;AAAA,IACJ;AAEA,QAAI,CAAC,MAAO;AAGZ,QAAI,KAAK,YAAY,MAAM,aAAa,UAAa,KAAK,SAAS,WAAW;AAC1E,YAAM,WAAW,KAAK;AAAA,IAC1B;AAEA,WAAO,OAAO,KAAK,KAAK;AACxB,QAAI,OAAO,iBAAkB,QAAO,iBAAiB,KAAK;AAC1D,QAAI,MAAM,gBAAiB,OAAM,gBAAgB,KAAK;AAEtD,YAAQ,IAAI,KAAK,IAAI,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,OAAO,IAAI,QAAQ,IAAI,SAAS,IAAI,SAAS,GAAG,CAAC;AAG7F,QAAI,KAAK,OAAO;AACZ,UAAI,aAAa,KAAK,cAAc,KAAK,UAAU;AACnD,UAAI,eAAe,UAAU,GAAG;AAC5B,qBAAa;AAAA,MACjB;AACA,YAAM,gBAAgB,KAAK,iBAAiB;AAE5C,UAAI,KAAK,SAAS,QAAQ;AAEtB,cAAM,SAAS,KAAK,KAAK,IAAI;AAC7B,oBAAY,KAAK,OAAO,IAAI,QAAQ,eAAe,YAAY,KAAK;AAAA,MACxE,WAAW,SAAS,OAAO,MAAM,aAAa,YAAY;AAEtD,cAAM,SAAS,KAAK,OAAO,YAAY,aAAa;AAAA,MACxD,OAAO;AAEH,oBAAY,KAAK,OAAO,IAAI,IAAI,eAAe,YAAY,KAAK;AAAA,MACpE;AAAA,IACJ;AAAA,EACJ;AAIA,QAAM,SAAS,oBAAI,IAAI;AACvB,QAAM,SAAS,oBAAI,IAAI;AACvB,QAAM,QAAQ,OAAK;AACf,WAAO,IAAI,EAAE,OAAO,OAAO,IAAI,EAAE,IAAI,KAAK,KAAK,CAAC;AAChD,WAAO,IAAI,GAAG,OAAO,IAAI,EAAE,IAAI,IAAI,CAAC;AAAA,EACxC,CAAC;AAGD,QAAM,gBAAgB,CAAC;AACvB,UAAQ,QAAQ,OAAK;AACjB,kBAAc,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,OAAO,EAAE,OAAO,QAAQ,EAAE,OAAO,CAAC;AAAA,EAC3E,CAAC;AAED,aAAW,QAAQ,OAAO;AACtB,UAAM,OAAO,QAAQ,IAAI,KAAK,IAAI,GAAG,KAAK,QAAQ,IAAI,KAAK,EAAE;AAC7D,QAAI,CAAC,QAAQ,CAAC,GAAI;AAElB,UAAM,QAAQ,OAAO,IAAI,KAAK,IAAI,KAAK;AACvC,UAAM,MAAM,OAAO,IAAI,IAAI;AAC3B,UAAM,aAAa,KAAK,aAAa;AAGrC,UAAM,YAAY,gBAAgB,MAAM,IAAI,OAAO,KAAK,eAAe,SAAS,KAAK;AAGrF,UAAM,KAAK,mBAAmB,MAAM,IAAI,OAAO,GAAG;AAClD,UAAM,KAAK,aAAa,IAAI,IAAI;AAGhC,UAAM,MAAM,GAAG,IAAI,GAAG,GAAG,MAAM,GAAG,IAAI,GAAG;AACzC,UAAM,OAAO,KAAK,KAAK,MAAM,MAAM,MAAM,GAAG,KAAK;AACjD,UAAM,QAAQ;AACd,UAAM,MAAM,EAAE,GAAG,GAAG,IAAK,MAAM,OAAQ,OAAO,GAAG,GAAG,IAAK,MAAM,OAAQ,MAAM;AAC7E,UAAM,MAAM,EAAE,GAAG,GAAG,IAAK,MAAM,OAAQ,OAAO,GAAG,GAAG,IAAK,MAAM,OAAQ,MAAM;AAE7E,QAAI,YAAY;AAGhB,UAAM,aAAa,KAAK,UAAU;AAClC,UAAM,kBAAkB,KAAK,eAAe;AAC5C,UAAM,gBAAgB,KAAK,aAAa;AAGxC,UAAM,UAAU,EAAE,OAAO,IAAI,QAAQ,OAAO,QAAQ,MAAM;AAC1D,UAAM,YAAY,QAAQ,aAAa,KAAK;AAE5C,QAAI,cAAc,OAAO,OAAO;AAE5B,UAAI;AACA,cAAM,OAAO;AAAA,UACT,QAAQ;AAAA,UAAY,aAAa;AAAA,UAAiB,WAAW;AAAA,UAC7D,mBAAmB;AAAA,UACnB,gBAAgB,KAAK,kBAAkB;AAAA,QAC3C;AAEA,YAAI,UAAU,SAAS,UAAU;AAC7B,eAAK,cAAc;AACnB,eAAK,mBAAmB,UAAU;AAAA,QACtC,WAAW,UAAU,SAAS,SAAS;AACnC,eAAK,cAAc;AAAA,QACvB;AAGA,oBAAY,IAAI,OAAO,MAAM,KAAK,KAAK,IAAI;AAC3C,eAAO,OAAO,KAAK,SAAS;AAC5B,YAAI,OAAO,iBAAkB,QAAO,iBAAiB,SAAS;AAC9D,YAAI,MAAM,gBAAiB,OAAM,gBAAgB,SAAS;AAG1D,mBAAW,WAAW,KAAK,OAAO,MAAM,EAAE;AAC1C,mBAAW,WAAW,GAAG,OAAO,OAAO,EAAE;AAAA,MAC7C,SAAS,KAAK;AACV,gBAAQ,KAAK,uCAAuC,MAAM,GAAG;AAAA,MACjE;AAAA,IACJ,WAAW,CAAC,cAAc,OAAO,MAAM;AAEnC,UAAI;AACA,cAAM,OAAO;AAAA,UACT,QAAQ;AAAA,UAAY,aAAa;AAAA,UAAiB,WAAW;AAAA,UAC7D,iBAAiB;AAAA,QACrB;AAEA,oBAAY,IAAI,OAAO,KAAK,KAAK,KAAK,IAAI;AAE1C,YAAI,UAAU,SAAS,UAAU;AAC7B,oBAAU,WAAW;AACrB,cAAI,OAAO,UAAU,gCAAgC,YAAY;AAC7D,sBAAU,4BAA4B;AAAA,UAC1C;AAEA,cAAI,OAAO,UAAU,SAAS,WAAY,WAAU,KAAK;AAAA,QAC7D;AAEA,eAAO,OAAO,KAAK,SAAS;AAC5B,YAAI,OAAO,iBAAkB,QAAO,iBAAiB,SAAS;AAC9D,YAAI,MAAM,gBAAiB,OAAM,gBAAgB,SAAS;AAAA,MAC9D,SAAS,KAAK;AACV,gBAAQ,KAAK,sCAAsC,MAAM,GAAG;AAAA,MAChE;AAAA,IACJ,WAAW,OAAO,OAAO;AAErB,UAAI;AACA,oBAAY,IAAI,OAAO,MAAM,KAAK,KAAK;AAAA,UACnC,QAAQ;AAAA,UAAY,aAAa;AAAA,UAAiB,WAAW;AAAA,QACjE,CAAC;AACD,eAAO,OAAO,KAAK,SAAS;AAC5B,YAAI,OAAO,iBAAkB,QAAO,iBAAiB,SAAS;AAC9D,YAAI,MAAM,gBAAiB,OAAM,gBAAgB,SAAS;AAAA,MAC9D,SAAS,KAAK;AACV,gBAAQ,KAAK,gDAAgD,MAAM,GAAG;AAAA,MAC1E;AAAA,IACJ;AAGA,QAAI,KAAK,SAAS,WAAW;AACzB,YAAM,iBAAiB,eAAe,YAAY,YAAY;AAC9D,UAAI,OAAO,UAAU,aAAa,YAAY;AAC1C,kBAAU,SAAS,KAAK,OAAO,gBAAgB,EAAE;AAAA,MACrD,OAAO;AAEH,cAAM,MAAM,IAAI,IAAI,IAAI,KAAK;AAC7B,cAAM,MAAM,IAAI,IAAI,IAAI,KAAK,IAAI;AACjC,oBAAY,KAAK,OAAO,IAAI,IAAI,IAAI,gBAAgB,KAAK;AAAA,MAC7D;AAAA,IACJ;AAAA,EACJ;AAGA,QAAM,YAAY,QAAQ,aAAa,CAAC;AACxC,aAAW,MAAM,WAAW;AACxB,QAAI,CAAC,GAAG,SAAS,GAAG,MAAM,WAAW,EAAG;AAGxC,QAAI,SAAS,UAAU,SAAS,UAAU,SAAS,WAAW,SAAS;AACvE,QAAI,WAAW;AACf,eAAW,OAAO,GAAG,OAAO;AACxB,YAAM,IAAI,QAAQ,IAAI,GAAG;AACzB,UAAI,CAAC,EAAG;AACR,iBAAW;AACX,eAAS,KAAK,IAAI,QAAQ,EAAE,CAAC;AAC7B,eAAS,KAAK,IAAI,QAAQ,EAAE,CAAC;AAC7B,eAAS,KAAK,IAAI,QAAQ,EAAE,IAAI,EAAE,KAAK;AACvC,eAAS,KAAK,IAAI,QAAQ,EAAE,IAAI,EAAE,MAAM;AAAA,IAC5C;AACA,QAAI,CAAC,SAAU;AAEf,UAAM,QAAQ;AACd,QAAI;AACA,YAAM,WAAW,IAAI,OAAO;AAAA,QACxB,SAAS;AAAA,QAAO,SAAS,QAAQ;AAAA,QAChC,SAAS,SAAU,QAAQ;AAAA,QAAI,SAAS,SAAU,QAAQ,IAAI;AAAA,QAC/D;AAAA,UACI,QAAQ,GAAG,UAAU;AAAA,UACrB,aAAa;AAAA,UACb,MAAM;AAAA,UACN,SAAS;AAAA,UACT,WAAW,GAAG,SAAS,GAAG;AAAA,QAC9B;AAAA,MACJ;AACA,aAAO,OAAO,KAAK,QAAQ;AAC3B,UAAI,OAAO,iBAAkB,QAAO,iBAAiB,QAAQ;AAC7D,UAAI,MAAM,gBAAiB,OAAM,gBAAgB,QAAQ;AAGzD,iBAAW,OAAO,GAAG,OAAO;AACxB,cAAM,IAAI,QAAQ,IAAI,GAAG;AACzB,YAAI,KAAK,EAAE,SAAS,SAAS,iBAAiB;AAC1C,mBAAS,gBAAgB,EAAE,KAAK;AAAA,QACpC;AAAA,MACJ;AAAA,IACJ,SAAS,KAAK;AACV,cAAQ,KAAK,uCAAuC,GAAG,IAAI,GAAG;AAAA,IAClE;AAAA,EACJ;AAIA,QAAM,QAAQ,QAAQ,OAAO,EAAE,KAAK,EAAE;AACtC,MAAI,SAAS,MAAM,OAAO;AACtB,WAAO,eAAe,MAAM;AAC5B,QAAI,OAAO,MAAM,MAAM,gBAAgB,WAAY,OAAM,MAAM,YAAY;AAAA,EAC/E;AAEA,UAAQ,IAAI,sBAAsB,MAAM,MAAM,WAAW,MAAM,MAAM,WAAW,UAAU,MAAM,sBAAiB,KAAK,cAAc,OAAO,GAAG;AAC9I,SAAO;AACX;AAUA,SAAS,gBAAgB,MAAM,IAAI,UAAU,QAAQ,eAAe,SAAS,OAAO;AAChF,QAAM,KAAK,KAAK,IAAI,KAAK,UAAU,GAAG,OAAO;AAC7C,QAAM,KAAK,KAAK,IAAI,KAAK,UAAU,GAAG,OAAO;AAG7C,MAAI,WAAW,GAAG;AACd,UAAM,cAAc,MAAM,UAAU,WAAW,KAAK,KAAK;AACzD,WAAO,EAAE,MAAM,UAAU,YAAY;AAAA,EACzC;AAGA,QAAM,aAAa,KAAK;AACxB,QAAM,aAAa,KAAK;AAGxB,MAAI,cAAc,YAAY;AAE1B,UAAM,KAAK,aAAa,MAAM,EAAE;AAChC,UAAM,KAAK,aAAa,IAAI,IAAI;AAChC,UAAM,UAAU,eAAe,IAAI,IAAI,MAAM,IAAI,aAAa;AAE9D,QAAI,SAAS;AAET,aAAO,EAAE,MAAM,UAAU,aAAa,GAAG;AAAA,IAC7C;AACA,WAAO,EAAE,MAAM,WAAW;AAAA,EAC9B;AAIA,QAAM,aAAc,KAAK,kBAAkB,KAAO,KAAK,kBAAkB;AAEzE,MAAI,YAAY;AAGZ,UAAM,YAAY,GAAG;AACrB,UAAM,YAAY,KAAK;AACvB,UAAM,WAAW,EAAE,GAAG,WAAW,GAAG,UAAU;AAE9C,UAAM,cAAc;AAAA,MAChB,EAAE,GAAG,KAAK,SAAS,GAAG,KAAK,QAAQ;AAAA,MAAG;AAAA,MAAU;AAAA,MAAM;AAAA,MAAI;AAAA,IAC9D;AACA,UAAM,cAAc;AAAA,MAChB;AAAA,MAAU,EAAE,GAAG,GAAG,SAAS,GAAG,GAAG,QAAQ;AAAA,MAAG;AAAA,MAAM;AAAA,MAAI;AAAA,IAC1D;AAEA,QAAI,CAAC,eAAe,CAAC,aAAa;AAC9B,aAAO,EAAE,MAAM,QAAQ;AAAA,IAC3B;AAAA,EACJ;AAGA,SAAO,EAAE,MAAM,UAAU,aAAa,GAAG;AAC7C;AAMA,SAAS,eAAe,IAAI,IAAI,UAAU,QAAQ,eAAe;AAC7D,QAAM,SAAS;AACf,aAAW,UAAU,eAAe;AAEhC,QAAI,OAAO,MAAM,SAAS,KAAK,OAAO,MAAM,SAAS,EAAG;AACxD,QAAI,OAAO,MAAM,OAAO,KAAK,OAAO,MAAM,OAAO,EAAG;AAGpD,UAAM,KAAK,OAAO,IAAI;AACtB,UAAM,KAAK,OAAO,IAAI;AACtB,UAAM,KAAK,OAAO,QAAQ,SAAS;AACnC,UAAM,KAAK,OAAO,SAAS,SAAS;AAEpC,QAAI,mBAAmB,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,IAAI,IAAI,EAAE,GAAG;AAC5D,aAAO;AAAA,IACX;AAAA,EACJ;AACA,SAAO;AACX;AAKA,SAAS,mBAAmB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;AAExD,QAAM,OAAO,IAAI,QAAQ,KAAK,IAAI,MAAM,IAAI,SAAS,KAAK;AAG1D,MAAI,KAAK,IAAI,IAAI,EAAE,IAAI,QAAQ,KAAK,IAAI,IAAI,EAAE,IAAI,MAAO,QAAO;AAChE,MAAI,KAAK,IAAI,IAAI,EAAE,IAAI,OAAO,KAAK,IAAI,IAAI,EAAE,IAAI,OAAQ,QAAO;AAGhE,MAAI,MAAM,QAAQ,MAAM,SAAS,MAAM,OAAO,MAAM,OAAQ,QAAO;AACnE,MAAI,MAAM,QAAQ,MAAM,SAAS,MAAM,OAAO,MAAM,OAAQ,QAAO;AAGnE,SACI,kBAAkB,IAAI,IAAI,IAAI,IAAI,MAAM,KAAK,OAAO,GAAG,KACvD,kBAAkB,IAAI,IAAI,IAAI,IAAI,OAAO,KAAK,OAAO,MAAM,KAC3D,kBAAkB,IAAI,IAAI,IAAI,IAAI,MAAM,QAAQ,OAAO,MAAM,KAC7D,kBAAkB,IAAI,IAAI,IAAI,IAAI,MAAM,KAAK,MAAM,MAAM;AAEjE;AAEA,SAAS,kBAAkB,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AAC/D,QAAM,KAAK,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAC7C,QAAM,KAAK,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAC7C,QAAM,KAAK,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAC7C,QAAM,KAAK,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAE7C,OAAM,KAAK,KAAK,KAAK,KAAO,KAAK,KAAK,KAAK,OACrC,KAAK,KAAK,KAAK,KAAO,KAAK,KAAK,KAAK,IAAK;AAC5C,WAAO;AAAA,EACX;AACA,SAAO;AACX;AAEA,SAAS,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;AACnC,UAAQ,KAAK,OAAO,KAAK,OAAO,KAAK,OAAO,KAAK;AACrD;AAUO,SAAS,WAAW,OAAO,OAAO,SAAS,cAAc;AAC5D,MAAI,CAAC,SAAS,CAAC,MAAO;AACtB,MAAI,OAAO,MAAM,kBAAkB,WAAY;AAE/C,MAAI;AAEA,QAAI,MAAM;AAEV,QAAI,MAAM,cAAc,eAAe,MAAM,cAAc,SAAS;AAChE,YAAM,KAAK,MAAM,GAAG,KAAK,MAAM,GAAG,KAAK,MAAM,OAAO,KAAK,MAAM;AAC/D,YAAM,KAAK,KAAK,KAAK,GAAG,KAAK,KAAK,KAAK;AAGvC,YAAM,UAAU,KAAK,IAAI,aAAa,IAAI,EAAE;AAC5C,YAAM,aAAa,KAAK,IAAI,aAAa,KAAK,KAAK,GAAG;AACtD,YAAM,WAAW,KAAK,IAAI,aAAa,IAAI,EAAE;AAC7C,YAAM,YAAY,KAAK,IAAI,aAAa,KAAK,KAAK,GAAG;AACrD,YAAM,UAAU,KAAK,IAAI,SAAS,YAAY,UAAU,SAAS;AAEjE,UAAI,YAAY,SAAS;AACrB,eAAO;AACP,iBAAS,EAAE,GAAG,aAAa,IAAI,IAAI,GAAG,GAAG,MAAM,MAAM;AAAA,MACzD,WAAW,YAAY,YAAY;AAC/B,eAAO;AACP,iBAAS,EAAE,GAAG,aAAa,IAAI,IAAI,GAAG,IAAI,MAAM,SAAS;AAAA,MAC7D,WAAW,YAAY,UAAU;AAC7B,eAAO;AACP,iBAAS,EAAE,GAAG,GAAG,GAAG,aAAa,IAAI,IAAI,MAAM,OAAO;AAAA,MAC1D,OAAO;AACH,eAAO;AACP,iBAAS,EAAE,GAAG,IAAI,GAAG,aAAa,IAAI,IAAI,MAAM,QAAQ;AAAA,MAC5D;AAEA,YAAM,aAAa,EAAE,MAAM,OAAO,cAAc,OAAO;AACvD,YAAM,cAAc,SAAS,OAAO,UAAU;AAAA,IAClD,WAAW,MAAM,cAAc,UAAU;AACrC,YAAM,QAAQ,KAAK;AAAA,QACf,aAAa,IAAI,MAAM;AAAA,QACvB,aAAa,IAAI,MAAM;AAAA,MAC3B;AACA,YAAM,aAAa;AAAA,QACf,MAAM;AAAA,QACN,OAAO;AAAA,QACP,QAAQ,EAAE,OAAO,MAAM,YAAY;AAAA,MACvC;AACA,YAAM,cAAc,SAAS,OAAO,UAAU;AAAA,IAClD;AAAA,EACJ,SAAS,KAAK;AAEV,YAAQ,KAAK,oCAAoC,GAAG;AAAA,EACxD;AACJ;AAUA,eAAe,kBAAkB,SAAS,GAAG,GAAG,GAAG,GAAG,kBAAkB,OAAO;AAC3E,MAAI;AACA,UAAM,MAAM,MAAM,MAAM,uBAAuB,mBAAmB,OAAO,CAAC,WAAW;AACrF,QAAI,CAAC,IAAI,GAAI;AACb,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,UAAM,UAAU,KAAK;AACrB,QAAI,CAAC,WAAW,QAAQ,WAAW,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAK;AAEzD,UAAM,aAAa,QAAQ,CAAC,EAAE;AAG9B,QAAI,OAAO,OAAO,OAAO,WAAW;AAChC,YAAM,MAAM,OAAO;AAGnB,YAAM,SAAS,IAAI,UAAU;AAC7B,YAAM,MAAM,OAAO,gBAAgB,YAAY,eAAe;AAC9D,YAAM,QAAQ,IAAI,cAAc,KAAK;AACrC,UAAI,CAAC,MAAO;AAEZ,YAAM,UAAU,WAAW,MAAM,aAAa,OAAO,KAAK,MAAM,SAAS,SAAS,SAAS,EAAE;AAC7F,YAAM,WAAW,WAAW,MAAM,aAAa,QAAQ,KAAK,MAAM,SAAS,SAAS,UAAU,EAAE;AAChG,YAAM,QAAQ,KAAK,IAAI,IAAI,SAAS,IAAI,QAAQ;AAGhD,YAAM,IAAI,SAAS,gBAAgB,IAAI,GAAG;AAC1C,QAAE,aAAa,QAAQ,MAAM;AAC7B,QAAE,aAAa,KAAK,CAAC;AACrB,QAAE,aAAa,KAAK,CAAC;AACrB,QAAE,aAAa,SAAS,CAAC;AACzB,QAAE,aAAa,UAAU,CAAC;AAC1B,QAAE,aAAa,gBAAgB,CAAC;AAChC,QAAE,aAAa,gBAAgB,CAAC;AAChC,QAAE,aAAa,oBAAoB,CAAC;AACpC,QAAE,aAAa,qBAAqB,CAAC;AACrC,QAAE,aAAa,uBAAuB,GAAG;AACzC,QAAE,aAAa,sBAAsB,OAAO;AAC5C,QAAE,aAAa,uBAAuB,QAAQ;AAC9C,QAAE,aAAa,aAAa,aAAa,CAAC,KAAK,CAAC,WAAW,KAAK,GAAG;AAGnE,YAAM,WAAW,MAAM,iBAAiB,sDAAsD;AAC9F,eAAS,QAAQ,WAAS;AACtB,cAAM,QAAQ,MAAM,UAAU,IAAI;AAElC,YAAI,CAAC,MAAM,aAAa,MAAM,KAAK,MAAM,aAAa,MAAM,MAAM,UAAU,MAAM,aAAa,MAAM,MAAM,WAAW,MAAM,aAAa,MAAM,MAAM,UAAU,MAAM,aAAa,MAAM,MAAM,WAAW;AACrM,gBAAM,aAAa,QAAQ,SAAS;AAAA,QACxC;AACA,YAAI,MAAM,aAAa,QAAQ,MAAM,WAAW,MAAM,aAAa,QAAQ,MAAM,UAAU,MAAM,aAAa,QAAQ,MAAM,WAAW;AACnI,gBAAM,aAAa,UAAU,SAAS;AAAA,QAC1C;AACA,UAAE,YAAY,KAAK;AAAA,MACvB,CAAC;AAGD,YAAM,UAAU,SAAS,gBAAgB,IAAI,MAAM;AACnD,cAAQ,aAAa,KAAK,GAAG;AAC7B,cAAQ,aAAa,KAAK,GAAG;AAC7B,cAAQ,aAAa,SAAS,OAAO;AACrC,cAAQ,aAAa,UAAU,QAAQ;AACvC,cAAQ,aAAa,QAAQ,aAAa;AAC1C,cAAQ,aAAa,UAAU,MAAM;AACrC,QAAE,aAAa,SAAS,EAAE,UAAU;AAEpC,UAAI,YAAY,CAAC;AAGjB,YAAM,YAAY,IAAI,OAAO,UAAU,CAAC;AACxC,aAAO,OAAO,KAAK,SAAS;AAC5B,UAAI,OAAO,iBAAkB,QAAO,iBAAiB,SAAS;AAC9D,UAAI,OAAO,gBAAiB,OAAM,gBAAgB,SAAS;AAG3D,UAAI,kBAAkB;AAClB,cAAM,MAAM,OAAO,OAAO,QAAQ,gBAAgB;AAClD,YAAI,QAAQ,GAAI,QAAO,OAAO,OAAO,KAAK,CAAC;AAC3C,YAAI,iBAAiB,SAAS,iBAAiB,MAAM,YAAY;AAC7D,2BAAiB,MAAM,WAAW,YAAY,iBAAiB,KAAK;AAAA,QACxE;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ,SAAS,KAAK;AACV,YAAQ,KAAK,+CAA+C,SAAS,GAAG;AAAA,EAE5E;AACJ;AAWA,SAAS,YAAY,MAAM,GAAG,GAAG,UAAU,MAAM,OAAO;AACpD,QAAM,MAAM,OAAO;AACnB,MAAI,CAAC,OAAO,CAAC,OAAO,UAAW,QAAO;AAEtC,MAAI;AACA,UAAM,IAAI,SAAS,gBAAgB,IAAI,GAAG;AAC1C,MAAE,aAAa,aAAa,YAAY;AACxC,MAAE,aAAa,aAAa,aAAa,CAAC,KAAK,CAAC,GAAG;AACnD,MAAE,aAAa,UAAU,CAAC;AAC1B,MAAE,aAAa,UAAU,CAAC;AAE1B,UAAM,IAAI,SAAS,gBAAgB,IAAI,MAAM;AAC7C,MAAE,aAAa,KAAK,CAAC;AACrB,MAAE,aAAa,KAAK,CAAC;AACrB,MAAE,aAAa,eAAe,QAAQ;AACtC,MAAE,aAAa,qBAAqB,SAAS;AAC7C,MAAE,aAAa,QAAQ,IAAI;AAC3B,MAAE,aAAa,aAAa,QAAQ;AACpC,MAAE,aAAa,eAAe,qBAAqB;AACnD,MAAE,aAAa,qBAAqB,SAAS;AAC7C,MAAE,aAAa,sBAAsB,IAAI;AACzC,MAAE,aAAa,qBAAqB,WAAW,IAAI;AACnD,MAAE,cAAc;AAEhB,MAAE,YAAY,CAAC;AACf,QAAI,YAAY,CAAC;AAEjB,UAAM,QAAQ,IAAI,OAAO,UAAU,CAAC;AACpC,WAAO,OAAO,KAAK,KAAK;AACxB,QAAI,OAAO,iBAAkB,QAAO,iBAAiB,KAAK;AAC1D,QAAI,OAAO,gBAAiB,OAAM,gBAAgB,KAAK;AACvD,WAAO;AAAA,EACX,SAAS,KAAK;AACV,YAAQ,KAAK,uCAAuC,GAAG;AACvD,WAAO;AAAA,EACX;AACJ;AAMA,SAAS,mBAAmB,MAAM,YAAY,OAAO,KAAK;AACtD,MAAI,SAAS,EAAG,QAAO,aAAa,MAAM,UAAU;AAEpD,QAAM,KAAK,WAAW,UAAU,KAAK;AACrC,QAAM,KAAK,WAAW,UAAU,KAAK;AACrC,QAAM,KAAK,KAAK,QAAQ;AACxB,QAAM,KAAK,KAAK,SAAS;AAGzB,QAAM,SAAS;AACf,QAAM,IAAI,UAAU,IAAI,MAAM,OAAO,QAAQ;AAC7C,QAAM,UAAU,IAAI,OAAO;AAE3B,MAAI,KAAK,IAAI,EAAE,IAAI,QAAS,KAAK,IAAI,EAAE,IAAI,KAAK,KAAK,IAAI,EAAE,IAAI,IAAI;AAC/D,UAAMC,MAAK,KAAK,UAAU,SAAS,KAAK;AACxC,UAAMC,MAAK,KAAK,IAAI,KAAK,IAAI,KAAK,SAAS,KAAK;AAChD,WAAO,EAAE,GAAGD,KAAI,GAAGC,IAAG;AAAA,EAC1B;AACA,QAAM,KAAK,KAAK,IAAI,KAAK,IAAI,KAAK,QAAQ,KAAK;AAC/C,QAAM,KAAK,KAAK,UAAU,SAAS,KAAK;AACxC,SAAO,EAAE,GAAG,IAAI,GAAG,GAAG;AAC1B;AAMA,SAAS,aAAa,MAAM,YAAY;AACpC,QAAM,KAAK,WAAW,UAAU,KAAK;AACrC,QAAM,KAAK,WAAW,UAAU,KAAK;AACrC,QAAM,KAAK,KAAK,QAAQ;AACxB,QAAM,KAAK,KAAK,SAAS;AAEzB,MAAI,KAAK,IAAI,EAAE,IAAI,QAAS,KAAK,IAAI,EAAE,IAAI,KAAK,KAAK,IAAI,EAAE,IAAI,IAAI;AAC/D,QAAI,KAAK,EAAG,QAAO,EAAE,GAAG,KAAK,SAAS,GAAG,KAAK,IAAI,KAAK,OAAO;AAC9D,WAAO,EAAE,GAAG,KAAK,SAAS,GAAG,KAAK,EAAE;AAAA,EACxC;AACA,MAAI,KAAK,EAAG,QAAO,EAAE,GAAG,KAAK,IAAI,KAAK,OAAO,GAAG,KAAK,QAAQ;AAC7D,SAAO,EAAE,GAAG,KAAK,GAAG,GAAG,KAAK,QAAQ;AACxC;AAUO,SAAS,mBAAmB,SAAS,QAAQ,KAAK,SAAS,KAAK;AACnE,MAAI,CAAC,SAAS,OAAO,OAAQ,QAAO;AAEpC,QAAM,QAAQ,QAAQ;AACtB,QAAM,QAAQ,QAAQ,SAAS,CAAC;AAGhC,MAAI,OAAO,UAAU,OAAO,UAAU,OAAO,WAAW,OAAO;AAC/D,QAAM,QAAQ,OAAK;AACf,WAAO,KAAK,IAAI,MAAM,EAAE,CAAC;AACzB,WAAO,KAAK,IAAI,MAAM,EAAE,CAAC;AACzB,WAAO,KAAK,IAAI,MAAM,EAAE,KAAK,EAAE,SAAS,OAAO;AAC/C,WAAO,KAAK,IAAI,MAAM,EAAE,KAAK,EAAE,UAAU,OAAO;AAAA,EACpD,CAAC;AAED,QAAM,KAAK,OAAO,QAAQ;AAC1B,QAAM,KAAK,OAAO,QAAQ;AAC1B,QAAM,MAAM;AACZ,QAAM,QAAQ,KAAK,KAAK,QAAQ,MAAM,KAAK,KAAK,SAAS,MAAM,KAAK,IAAI,GAAG;AAC3E,QAAM,QAAQ,QAAQ,KAAK,SAAS,IAAI,OAAO;AAC/C,QAAM,QAAQ,SAAS,KAAK,SAAS,IAAI,OAAO;AAGhD,QAAM,WAAW,oBAAI,IAAI;AACzB,QAAM,QAAQ,OAAK;AACf,UAAM,KAAK,EAAE,IAAI,QAAQ;AACzB,UAAM,KAAK,EAAE,IAAI,QAAQ;AACzB,UAAM,MAAM,EAAE,SAAS,UAAU;AACjC,UAAM,MAAM,EAAE,UAAU,UAAU;AAClC,aAAS,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,EAAE,CAAC;AAAA,EACvF,CAAC;AAED,MAAI,aAAa;AAGjB,QAAM,QAAQ,OAAK;AACf,UAAM,IAAI,SAAS,IAAI,EAAE,IAAI;AAC7B,UAAM,IAAI,SAAS,IAAI,EAAE,EAAE;AAC3B,QAAI,CAAC,KAAK,CAAC,EAAG;AAEd,UAAM,WAAW,EAAE,aAAa;AAChC,UAAM,SAAS,EAAE,UAAU;AAC3B,UAAM,WAAW,WAAW,sBAAsB,OAAO,QAAQ,KAAK,EAAE,CAAC,MAAM;AAG/E,QAAI,YAAY,CAAC,WAAW,SAAS,qBAAqB,OAAO,QAAQ,KAAK,EAAE,CAAC,GAAG,GAAG;AACnF,mBAAa,6BAA6B,OAAO,QAAQ,KAAK,EAAE,CAAC,mHAAmH,MAAM,mCAAmC;AAAA,IACjO;AAEA,UAAM,QAAQ,EAAE,cAAc,WAAW,4BAA4B,EAAE,cAAc,WAAW,4BAA4B;AAG5H,UAAM,KAAK,EAAE,KAAK,EAAE;AACpB,UAAM,KAAK,EAAE,KAAK,EAAE;AACpB,UAAM,OAAO,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AACxC,QAAI,MAAM,EAAE,KAAK,EAAE,MAAM;AACzB,QAAI,MAAM,EAAE,KAAK,EAAE,MAAM;AAEzB,QAAI,OAAO,KAAK,KAAK,IAAI,EAAE,IAAI,MAAM,KAAK,IAAI,EAAE,IAAI,IAAI;AAEpD,YAAM,QAAQ,CAAC,KAAK;AACpB,YAAM,QAAQ,KAAK;AACnB,YAAM,WAAW,OAAO;AACxB,YAAM,MAAM,KAAK,QAAQ;AACzB,YAAM,MAAM,KAAK,QAAQ;AAEzB,WAAK,OAAO,EAAE,KAAK,MAAM,MAAM,OAAO,EAAE;AACxC,WAAK,OAAO,EAAE,KAAK,MAAM,MAAM,OAAO,EAAE;AACxC,oBAAc,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,yBAAyB,MAAM,uBAAuB,KAAK,gBAAgB,QAAQ;AAAA,IAC/J,OAAO;AACH,oBAAc,aAAa,EAAE,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,EAAE,aAAa,MAAM,uBAAuB,KAAK,gBAAgB,QAAQ;AAAA,IACjJ;AAEA,QAAI,EAAE,OAAO;AACT,oBAAc,YAAY,EAAE,QAAQ,KAAK,CAAC,gCAAgC,WAAW,SAAS,SAAS,MAAM,qDAAqD,UAAU,EAAE,KAAK,CAAC;AAAA,IACxL;AAAA,EACJ,CAAC;AAGD,QAAM,QAAQ,OAAK;AACf,UAAM,IAAI,SAAS,IAAI,EAAE,EAAE;AAC3B,QAAI,CAAC,EAAG;AAER,UAAM,UAAU,EAAE,UAAU;AAC5B,UAAM,QAAQ,EAAE,QAAQ;AACxB,UAAM,QAAQ,EAAE,kBAAkB,sBAAsB,EAAE,eAAe,MAAM;AAE/E,QAAI,EAAE,SAAS,UAAU;AACrB,oBAAc,gBAAgB,EAAE,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,KAAK,aAAa,OAAO,uBAAuB,KAAK;AAAA,IACnJ,WAAW,EAAE,SAAS,WAAW;AAC7B,YAAM,KAAK,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI;AAChC,oBAAc,YAAY,EAAE,KAAK,KAAK,CAAC,QAAQ,EAAE,KAAK,KAAK,CAAC,YAAY,EAAE,aAAa,EAAE,WAAW,KAAK,aAAa,OAAO,uBAAuB,KAAK,0BAA0B,EAAE,EAAE,KAAK,EAAE,EAAE;AAAA,IACpM,WAAW,EAAE,SAAS,aAAa;AAC/B,oBAAc,YAAY,EAAE,CAAC,QAAQ,EAAE,CAAC,YAAY,EAAE,CAAC,aAAa,EAAE,CAAC,SAAS,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG,WAAW,KAAK,aAAa,OAAO,uBAAuB,KAAK;AAAA,IAC5K,OAAO;AACH,oBAAc,YAAY,EAAE,CAAC,QAAQ,EAAE,CAAC,YAAY,EAAE,CAAC,aAAa,EAAE,CAAC,kBAAkB,KAAK,aAAa,OAAO,uBAAuB,KAAK;AAAA,IAClJ;AAGA,QAAI,EAAE,OAAO;AACT,YAAM,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,KAAK,CAAC;AACrD,UAAI,YAAY,YAAY,YAAY,YAAY;AACpD,UAAI,eAAe,SAAS,EAAG,aAAY;AAE3C,YAAM,SAAS,EAAE,SAAS,SAAS,EAAE,KAAK,EAAE,IAAI,IAAI,KAAK,QAAQ,EAAE;AACnE,oBAAc,YAAY,EAAE,EAAE,QAAQ,MAAM,4DAA4D,SAAS,gBAAgB,QAAQ,uCAAuC,UAAU,EAAE,KAAK,CAAC;AAAA,IACtM;AAAA,EACJ,CAAC;AAED,SAAO,kDAAkD,KAAK,aAAa,MAAM,kBAAkB,KAAK,IAAI,MAAM;AAAA,UAC5G,WAAW,MAAM,yBAAyB,GAAG,KAAK,EAAE,KAAK,EAAE;AAAA,IACjE,WAAW,QAAQ,2BAA2B,EAAE,CAAC;AAAA;AAErD;AAEA,SAAS,UAAU,KAAK;AACpB,SAAO,OAAO,GAAG,EAAE,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,QAAQ;AAChH;AAMA,SAAS,eAAe,KAAK;AACzB,MAAI,CAAC,OAAO,QAAQ,iBAAiB,QAAQ,OAAQ,QAAO;AAC5D,QAAM,IAAI,IAAI,QAAQ,KAAK,EAAE;AAC7B,MAAI,EAAE,SAAS,EAAG,QAAO;AACzB,QAAM,IAAI,SAAS,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE;AACxC,QAAM,IAAI,SAAS,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE;AACxC,QAAM,IAAI,SAAS,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE;AAExC,QAAM,MAAO,QAAQ,IAAI,QAAQ,IAAI,QAAQ;AAC7C,SAAO,MAAM;AACjB;AAOO,SAAS,wBAAwB,OAAO,QAAQ,KAAK,SAAS,KAAK;AACtE,MAAI,CAAC,SAAS,CAAC,MAAM,UAAW,QAAO;AAEvC,QAAM,KAAK,MAAM,GAAG,KAAK,MAAM,GAAG,KAAK,MAAM,OAAO,KAAK,MAAM;AAC/D,MAAI,MAAM,KAAK,MAAM,EAAG,QAAO;AAE/B,QAAM,MAAM;AACZ,QAAM,QAAQ,KAAK,KAAK,QAAQ,MAAM,KAAK,KAAK,SAAS,MAAM,KAAK,IAAI,GAAG;AAC3E,QAAM,QAAQ,QAAQ,KAAK,SAAS,IAAI,KAAK;AAC7C,QAAM,QAAQ,SAAS,KAAK,SAAS,IAAI,KAAK;AAE9C,MAAI,aAAa;AAGjB,gBAAc,YAAY,KAAK,QAAQ,IAAI,QAAQ,KAAK,QAAQ,IAAI,YAAY,KAAK,KAAK,aAAa,KAAK,KAAK;AAGjH,MAAI,MAAM,WAAW;AACjB,kBAAc,YAAY,KAAK,QAAQ,OAAO,EAAE,QAAQ,KAAK,QAAQ,OAAO,EAAE,kEAAkE,UAAU,MAAM,SAAS,CAAC;AAAA,EAC9K;AAGA,MAAI,MAAM,iBAAiB;AACvB,UAAM,gBAAgB,QAAQ,WAAS;AACnC,UAAI,CAAC,MAAO;AAEZ,UAAI,MAAM,cAAc,aAAa;AACjC,cAAM,KAAK,MAAM,IAAI,QAAQ;AAC7B,cAAM,KAAK,MAAM,IAAI,QAAQ;AAC7B,cAAM,KAAK,MAAM,QAAQ;AACzB,cAAM,KAAK,MAAM,SAAS;AAC1B,cAAM,SAAS,MAAM,SAAS,UAAU;AACxC,cAAM,OAAO,MAAM,SAAS,QAAQ;AACpC,YAAI,MAAM,aAAa,IAAI;AACvB,gBAAM,KAAK,KAAK,IAAI,IAAI,EAAE,IAAI;AAC9B,gBAAM,MAAM,KAAK,KAAK,GAAG,MAAM,KAAK,KAAK;AACzC,wBAAc,YAAY,MAAM,KAAK,CAAC,QAAQ,MAAM,KAAK,CAAC,YAAY,EAAE,aAAa,EAAE,WAAW,IAAI,aAAa,MAAM,8CAA8C,GAAG,KAAK,GAAG;AAElL,cAAI,MAAM,OAAO;AACb,gBAAI,KAAK,MAAM,cAAc;AAC7B,gBAAI,eAAe,EAAE,EAAG,MAAK;AAC7B,kBAAM,KAAK,KAAK,IAAI,IAAI,MAAM,iBAAiB,MAAM,KAAK;AAC1D,0BAAc,YAAY,GAAG,QAAQ,GAAG,4DAA4D,EAAE,gBAAgB,EAAE,uCAAuC,UAAU,MAAM,KAAK,CAAC;AAAA,UACzL;AAAA,QACJ,OAAO;AACH,wBAAc,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,IAAI,aAAa,MAAM;AAE5G,cAAI,MAAM,OAAO;AACb,gBAAI,KAAK,MAAM,cAAc;AAC7B,gBAAI,eAAe,EAAE,EAAG,MAAK;AAC7B,kBAAM,KAAK,KAAK,IAAI,IAAI,MAAM,iBAAiB,MAAM,KAAK;AAC1D,0BAAc,YAAY,KAAK,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,4DAA4D,EAAE,gBAAgB,EAAE,uCAAuC,UAAU,MAAM,KAAK,CAAC;AAAA,UACzM;AAAA,QACJ;AAAA,MACJ,WAAW,MAAM,cAAc,UAAU;AACrC,cAAM,MAAM,MAAM,IAAI,QAAQ;AAC9B,cAAM,MAAM,MAAM,IAAI,QAAQ;AAC9B,cAAM,OAAO,MAAM,MAAM,MAAM;AAC/B,cAAM,OAAO,MAAM,MAAM,MAAM;AAC/B,cAAM,SAAS,MAAM,SAAS,UAAU;AACxC,cAAM,OAAO,MAAM,SAAS,QAAQ;AACpC,sBAAc,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,IAAI,aAAa,MAAM;AAEvG,YAAI,MAAM,OAAO;AACb,cAAI,KAAK,MAAM,cAAc;AAC7B,cAAI,eAAe,EAAE,EAAG,MAAK;AAC7B,gBAAM,KAAK,KAAK,IAAI,IAAI,MAAM,iBAAiB,MAAM,KAAK;AAC1D,wBAAc,YAAY,GAAG,QAAQ,GAAG,4DAA4D,EAAE,gBAAgB,EAAE,uCAAuC,UAAU,MAAM,KAAK,CAAC;AAAA,QACzL;AAAA,MACJ,WAAW,MAAM,cAAc,QAAQ;AACnC,cAAM,SAAS,MAAM,OAAO,cAAc,MAAM;AAChD,YAAI,QAAQ;AACR,gBAAM,KAAK,WAAW,MAAM,MAAM,aAAa,QAAQ,KAAK,GAAG;AAC/D,gBAAM,KAAK,WAAW,MAAM,MAAM,aAAa,QAAQ,KAAK,GAAG;AAC/D,gBAAM,OAAO,OAAO,aAAa,MAAM,KAAK;AAC5C,gBAAM,WAAW,KAAK,IAAI,IAAI,WAAW,OAAO,aAAa,WAAW,CAAC,KAAK,MAAM,KAAK;AACzF,gBAAM,OAAO,OAAO,eAAe;AACnC,cAAI,YAAY;AAChB,cAAI,eAAe,SAAS,EAAG,aAAY;AAC3C,wBAAc,YAAY,KAAK,QAAQ,IAAI,QAAQ,KAAK,QAAQ,IAAI,4DAA4D,SAAS,gBAAgB,QAAQ,uCAAuC,UAAU,IAAI,CAAC;AAAA,QAC3N;AAAA,MACJ,WAAW,MAAM,cAAc,SAAS;AACpC,cAAM,KAAK,MAAM,YAAY,KAAK,MAAM;AACxC,YAAI,MAAM,IAAI;AACV,gBAAM,SAAS,MAAM,SAAS,UAAU;AACxC,gBAAM,MAAM,GAAG,IAAI,QAAQ,MAAM,MAAM,GAAG,IAAI,QAAQ;AACtD,gBAAM,MAAM,GAAG,IAAI,QAAQ,MAAM,MAAM,GAAG,IAAI,QAAQ;AAEtD,cAAI,MAAM,gBAAgB,YAAY,MAAM,iBAAiB,MAAM,eAAe;AAC9E,kBAAM,OAAO,MAAM,cAAc,IAAI,QAAQ;AAC7C,kBAAM,OAAO,MAAM,cAAc,IAAI,QAAQ;AAC7C,kBAAM,OAAO,MAAM,cAAc,IAAI,QAAQ;AAC7C,kBAAM,OAAO,MAAM,cAAc,IAAI,QAAQ;AAC7C,0BAAc,cAAc,GAAG,IAAI,GAAG,MAAM,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,GAAG,yBAAyB,MAAM;AAAA,UAC3H,OAAO;AACH,0BAAc,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,MAAM;AAAA,UACzF;AAEA,cAAI,MAAM,OAAO;AACb,kBAAM,OAAO,MAAM,OAAO,GAAG,OAAO,MAAM,OAAO,IAAI;AACrD,kBAAM,MAAM,KAAK,IAAI,IAAI,MAAM,iBAAiB,MAAM,KAAK;AAC3D,0BAAc,YAAY,GAAG,QAAQ,GAAG,gCAAgC,MAAM,cAAc,MAAM,gBAAgB,GAAG,uCAAuC,UAAU,MAAM,KAAK,CAAC;AAAA,UACtL;AAAA,QACJ;AAAA,MACJ,WAAW,MAAM,cAAc,QAAQ;AACnC,cAAM,KAAK,MAAM,YAAY,KAAK,MAAM;AACxC,YAAI,MAAM,IAAI;AACV,gBAAM,SAAS,MAAM,SAAS,UAAU;AACxC,gBAAM,MAAM,GAAG,IAAI,QAAQ,MAAM,MAAM,GAAG,IAAI,QAAQ;AACtD,gBAAM,MAAM,GAAG,IAAI,QAAQ,MAAM,MAAM,GAAG,IAAI,QAAQ;AAEtD,cAAI,MAAM,YAAY,MAAM,cAAc;AACtC,kBAAM,MAAM,MAAM,aAAa,IAAI,QAAQ;AAC3C,kBAAM,MAAM,MAAM,aAAa,IAAI,QAAQ;AAC3C,0BAAc,cAAc,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,yBAAyB,MAAM;AAAA,UACvG,OAAO;AACH,0BAAc,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,MAAM;AAAA,UACzF;AAEA,cAAI,MAAM,OAAO;AACb,kBAAM,OAAO,MAAM,OAAO,GAAG,OAAO,MAAM,OAAO,IAAI;AACrD,kBAAM,MAAM,KAAK,IAAI,IAAI,MAAM,iBAAiB,MAAM,KAAK;AAC3D,0BAAc,YAAY,GAAG,QAAQ,GAAG,gCAAgC,MAAM,cAAc,MAAM,gBAAgB,GAAG,uCAAuC,UAAU,MAAM,KAAK,CAAC;AAAA,UACtL;AAAA,QACJ;AAAA,MACJ,WAAW,MAAM,cAAc,QAAQ;AACnC,cAAM,KAAK,WAAW,MAAM,OAAO,aAAa,cAAc,KAAK,GAAG;AACtE,cAAM,KAAK,WAAW,MAAM,OAAO,aAAa,cAAc,KAAK,GAAG;AACtE,cAAM,KAAK,WAAW,MAAM,OAAO,aAAa,kBAAkB,KAAK,IAAI;AAC3E,cAAM,KAAK,WAAW,MAAM,OAAO,aAAa,mBAAmB,KAAK,IAAI;AAC5E,cAAM,MAAM,KAAK,QAAQ;AACzB,cAAM,MAAM,KAAK,QAAQ;AACzB,cAAM,MAAM,KAAK;AACjB,cAAM,MAAM,KAAK;AAGjB,cAAM,YAAY,MAAM,OAAO,iBAAiB,sDAAsD;AACtG,YAAI,aAAa,UAAU,SAAS,GAAG;AAEnC,gBAAM,MAAM,WAAW,MAAM,OAAO,aAAa,oBAAoB,KAAK,EAAE;AAC5E,gBAAM,MAAM,WAAW,MAAM,OAAO,aAAa,qBAAqB,KAAK,EAAE;AAC7E,gBAAM,YAAY,KAAK,IAAI,MAAM,KAAK,MAAM,GAAG;AAC/C,wBAAc,2BAA2B,GAAG,KAAK,GAAG,WAAW,SAAS;AACxE,oBAAU,QAAQ,OAAK;AAEnB,gBAAI,EAAE,YAAY,UAAU,EAAE,aAAa,MAAM,MAAM,iBAAiB,EAAE,aAAa,QAAQ,MAAM,OAAQ;AAC7G,kBAAM,QAAQ,EAAE,UAAU,IAAI;AAC9B,0BAAc,MAAM;AAAA,UACxB,CAAC;AACD,wBAAc;AAAA,QAClB,OAAO;AAEH,wBAAc,YAAY,GAAG,QAAQ,GAAG,YAAY,GAAG,aAAa,GAAG;AACvE,wBAAc,YAAY,MAAM,MAAM,CAAC,QAAQ,MAAM,MAAM,CAAC;AAAA,QAChE;AAAA,MACJ,WAAW,MAAM,cAAc,SAAS;AAEpC,cAAM,KAAK,MAAM,IAAI,QAAQ;AAC7B,cAAM,KAAK,MAAM,IAAI,QAAQ;AAC7B,cAAM,KAAK,MAAM,QAAQ;AACzB,cAAM,KAAK,MAAM,SAAS;AAC1B,sBAAc,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,uCAAuC,MAAM,SAAS,UAAU,MAAM;AACzI,YAAI,MAAM,WAAW;AACjB,wBAAc,YAAY,KAAK,CAAC,QAAQ,KAAK,EAAE,qDAAqD,UAAU,MAAM,SAAS,CAAC;AAAA,QAClI;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAEA,SAAO,kDAAkD,KAAK,aAAa,MAAM,kBAAkB,KAAK,IAAI,MAAM;AAAA;AAAA,IAElH,UAAU;AAAA;AAEd;AAMA,SAAS,SAAS,OAAO;AACrB,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,WAAW,MAAM,KAAK,EAAE,MAAM,+EAA+E;AACnH,MAAI,UAAU;AACV,WAAO;AAAA,MACH,GAAG,KAAK,IAAI,KAAK,OAAO,SAAS,CAAC,CAAC,CAAC;AAAA,MACpC,GAAG,KAAK,IAAI,KAAK,OAAO,SAAS,CAAC,CAAC,CAAC;AAAA,MACpC,GAAG,KAAK,IAAI,KAAK,OAAO,SAAS,CAAC,CAAC,CAAC;AAAA,IACxC;AAAA,EACJ;AACA,MAAI,MAAM,MAAM,KAAK,EAAE,QAAQ,KAAK,EAAE;AACtC,MAAI,IAAI,WAAW,EAAG,OAAM,IAAI,MAAM,EAAE,EAAE,IAAI,UAAQ,OAAO,IAAI,EAAE,KAAK,EAAE;AAC1E,MAAI,CAAC,iBAAiB,KAAK,GAAG,EAAG,QAAO;AACxC,SAAO;AAAA,IACH,GAAG,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,IAC/B,GAAG,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,IAC/B,GAAG,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,EACnC;AACJ;AAEA,SAAS,kBAAkB,OAAO;AAC9B,QAAM,MAAM,SAAS,KAAK;AAC1B,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,UAAU,eAAa;AACzB,UAAM,aAAa,YAAY;AAC/B,WAAO,cAAc,UAAS,aAAa,QAAQ,KAAK,KAAK,aAAa,SAAQ,OAAO,GAAG;AAAA,EAChG;AACA,SAAO,SAAQ,QAAQ,IAAI,CAAC,IAAI,SAAQ,QAAQ,IAAI,CAAC,IAAI,SAAQ,QAAQ,IAAI,CAAC;AAClF;AAEA,SAAS,cAAc,GAAG,GAAG;AACzB,QAAM,QAAQ,kBAAkB,CAAC;AACjC,QAAM,SAAS,kBAAkB,CAAC;AAClC,MAAI,SAAS,QAAQ,UAAU,KAAM,QAAO;AAC5C,UAAQ,KAAK,IAAI,OAAO,MAAM,IAAI,SAAQ,KAAK,IAAI,OAAO,MAAM,IAAI;AACxE;AAEA,SAAS,mBAAmB,YAAY;AACpC,SAAO,cAAc,WAAW,UAAU,KAAK,cAAc,WAAW,UAAU,IAC5E,YACA;AACV;AAEA,SAAS,cAAc,OAAO,YAAY,UAAU,GAAG;AACnD,MAAI,CAAC,SAAS,KAAK,KAAK,cAAc,OAAO,UAAU,KAAK,QAAS,QAAO;AAC5E,SAAO,mBAAmB,UAAU;AACxC;AAEO,SAAS,oBAAoB,YAAY;AAC5C,MAAI,OAAO,WAAW,eAAe,CAAC,MAAM,QAAQ,OAAO,MAAM,EAAG;AACpE,QAAM,aAAa,mBAAmB,UAAU;AAChD,QAAM,QAAQ,eAAe,YAAY,YAAY;AAErD,SAAO,wBAAwB;AAC/B,SAAO,yBAAyB;AAEhC,aAAW,SAAS,OAAO,QAAQ;AAC/B,QAAI,CAAC,MAAO;AACZ,QAAI,OAAO,MAAM,sBAAsB,YAAY;AAC/C,YAAM,kBAAkB,YAAY,YAAY,KAAK;AACrD;AAAA,IACJ;AAEA,UAAM,QAAQ,MAAM;AACpB,UAAM,YAAY,CAAC,EAAE,MAAM,gBAAgB,MAAM,eAAe,WAAW,OAAO,gBAAgB,OAAO,eAAe;AACxH,UAAM,OAAO,MAAM,SAAS;AAC5B,UAAM,YAAY,QAAQ,SAAS,iBAAiB,SAAS;AAE7D,QAAI,MAAM,SAAS,YAAY;AAC3B,YAAM,QAAQ,gBAAgB;AAC9B,UAAI,OAAO,MAAM,SAAS,WAAY,OAAM,KAAK;AACjD;AAAA,IACJ;AAEA,QAAI,MAAM,SAAS,WAAW,aAAa,CAAC,QAAQ,WAAW,QAAQ,WAAW,SAAS,EAAE,SAAS,MAAM,QAAQ,OAAO,YAAY,CAAC,IAAI;AACxI,YAAM,QAAQ,SAAS,cAAc,MAAM,QAAQ,QAAQ,YAAY,CAAC;AAAA,IAC5E;AACA,QAAI,MAAM,cAAc,WAAW,aAAa,MAAM,SAAS;AAC3D,YAAM,QAAQ,SAAS;AACvB,YAAM,QAAQ,aAAa;AAAA,IAC/B;AACA,QAAI,gBAAgB,SAAS,WAAW;AACpC,YAAM,aAAa,YAAY,cAAc,MAAM,cAAc,YAAY,MAAM,GAAG,IAAI;AAAA,IAC9F;AACA,QAAI,MAAM,SAAS,WAAW;AAC1B,YAAM,MAAM,iBAAiB,MAAM,EAAE,QAAQ,UAAQ;AACjD,cAAM,UAAU,KAAK,aAAa,MAAM,KAAK;AAC7C,aAAK,aAAa,QAAQ,YAAY,cAAc,SAAS,MAAM,GAAG,IAAI,cAAc,SAAS,YAAY,GAAG,CAAC;AAAA,MACrH,CAAC;AAAA,IACL;AACA,QAAI,OAAO,MAAM,SAAS,WAAY,OAAM,KAAK;AAAA,EACrD;AACJ;AAMO,SAAS,iBAAiB;AAI7B,SAAO,eAAe;AACtB,SAAO,wBAAwB;AAG/B,MAAI,aAAa;AACjB,MAAI,cAAc;AAClB,MAAI,aAAa;AAGjB,MAAI,aAAa;AACjB,MAAI,YAAY;AAGhB,MAAI,cAAc;AAElB,iBAAe,uBAAuB;AAClC,QAAI,WAAY;AAChB,UAAM,MAAM,MAAM,OAAO,qCAA4B;AACrD,UAAM,OAAO,MAAM,OAAO,uCAA8B;AACxD,iBAAa,IAAI;AACjB,kBAAc,KAAK;AACnB,iBAAa,KAAK;AAAA,EACtB;AAEA,iBAAe,wBAAwB;AACnC,QAAI,WAAY;AAChB,UAAM,MAAM,MAAM,OAAO,wCAA+B;AACxD,iBAAa,IAAI;AACjB,gBAAY,IAAI;AAAA,EACpB;AAEA,iBAAe,yBAAyB;AACpC,QAAI,YAAa;AACjB,kBAAc,MAAM,OAAO,yCAAgC;AAAA,EAC/D;AAEA,WAAS,cAAc,KAAK;AACxB,WAAO,IAAI,MAAM,IAAI,EAAE,IAAI,UAAQ,KAAK,KAAK,CAAC,EAAE,KAAK,UAAQ,QAAQ,CAAC,KAAK,WAAW,IAAI,CAAC,GAAG,YAAY,KAAK;AAAA,EACnH;AAGA,WAAS,kBAAkB,KAAK;AAC5B,WAAO,cAAc,GAAG,MAAM;AAAA,EAClC;AAEA,WAAS,eAAe,KAAK;AACzB,UAAM,SAAS,cAAc,GAAG;AAChC,QAAI,WAAW,YAAa,QAAO;AACnC,QAAI,eAAe,KAAK,MAAM,KAAK,6BAA6B,KAAK,MAAM,EAAG,QAAO;AACrF,WAAO;AAAA,EACX;AAEA,SAAO,eAAe;AACtB,SAAO,cAAc;AACrB,SAAO,mBAAmB;AAG1B,SAAO,kBAAkB,CAAC,QAAQ;AAC9B,QAAI,kBAAkB,GAAG,GAAG;AACxB,UAAI;AACA,YAAI,WAAY,QAAO,WAAW,GAAG;AACrC,6BAAqB;AACrB,eAAO,EAAE,kBAAkB,MAAM,IAAI;AAAA,MACzC,QAAQ;AACJ,eAAO;AAAA,MACX;AAAA,IACJ;AACA,QAAI,eAAe,GAAG,GAAG;AACrB,UAAI,CAAC,aAAa;AACd,+BAAuB;AACvB,eAAO,EAAE,oBAAoB,MAAM,IAAI;AAAA,MAC3C;AACA,aAAO,eAAe,GAAG,MAAM,OACzB,YAAY,eAAe,GAAG,IAC9B,YAAY,kBAAkB,GAAG;AAAA,IAC3C;AACA,WAAO,aAAa,GAAG;AAAA,EAC3B;AAGA,SAAO,mBAAmB,OAAO,QAAQ;AACrC,QAAI,kBAAkB,GAAG,GAAG;AACxB,YAAM,qBAAqB;AAC3B,YAAMC,WAAU,WAAW,GAAG;AAC9B,UAAI,CAACA,SAAS,QAAO;AACrB,aAAO,YAAYA,QAAO;AAAA,IAC9B;AACA,UAAM,OAAO,eAAe,GAAG;AAC/B,QAAI,MAAM;AACN,YAAM,uBAAuB;AAC7B,YAAMA,WAAU,SAAS,OAAO,YAAY,eAAe,GAAG,IAAI,YAAY,kBAAkB,GAAG;AACnG,UAAI,CAACA,SAAS,QAAO;AACrB,aAAO,SAAS,OAAO,YAAY,mBAAmBA,QAAO,IAAI,YAAY,sBAAsBA,QAAO;AAAA,IAC9G;AAEA,UAAM,sBAAsB;AAC5B,UAAM,UAAU,aAAa,GAAG;AAChC,QAAI,CAAC,QAAS,QAAO;AACrB,WAAO,WAAW,OAAO;AAAA,EAC7B;AAGA,SAAO,oBAAoB,OAAO,QAAQ;AACtC,QAAI,kBAAkB,GAAG,GAAG;AACxB,YAAM,qBAAqB;AAC3B,YAAMA,WAAU,WAAW,GAAG;AAC9B,UAAI,CAACA,UAAS;AAAE,gBAAQ,MAAM,oCAAoC;AAAG,eAAO;AAAA,MAAO;AACnF,aAAO,WAAWA,QAAO;AAAA,IAC7B;AACA,UAAM,OAAO,eAAe,GAAG;AAC/B,QAAI,MAAM;AACN,YAAM,uBAAuB;AAC7B,YAAMA,WAAU,SAAS,OAAO,YAAY,eAAe,GAAG,IAAI,YAAY,kBAAkB,GAAG;AACnG,UAAI,CAACA,UAAS;AAAE,gBAAQ,MAAM,8CAA8C;AAAG,eAAO;AAAA,MAAO;AAC7F,aAAO,SAAS,OAAO,YAAY,iBAAiBA,QAAO,IAAI,YAAY,oBAAoBA,QAAO;AAAA,IAC1G;AAEA,UAAM,sBAAsB;AAC5B,UAAM,UAAU,aAAa,GAAG;AAChC,QAAI,CAAC,SAAS;AAAE,cAAQ,MAAM,mCAAmC;AAAG,aAAO;AAAA,IAAO;AAClF,WAAO,UAAU,OAAO;AAAA,EAC5B;AAGA,uBAAqB;AACrB,wBAAsB;AACtB,yBAAuB;AAC3B;",
|
|
6
|
-
"names": ["nodeIds", "px", "py", "diagram"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/tools/shapeRecognitionTool.js", "../../src/tools/paintBucketTool.js", "../../src/tools/lassoTool.js", "../../src/tools/webEmbedTool.js", "../../src/core/EventDispatcher.js"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable */\nimport { pushCreateAction, pushFrameAttachmentAction } from '../core/UndoRedo.js';\n\nconst SVG_NS = 'http://www.w3.org/2000/svg';\nconst MAX_POINTS = 96;\nconst MIN_SCREEN_SAMPLE_PX = 4;\nconst MIN_SHAPE_SIZE = 8;\n\nlet drawing = false;\nlet points = [];\nlet previewPath = null;\nlet previewFrame = 0;\nlet latestPrediction = null;\n\nfunction getThemeStroke() {\n return document.body?.classList.contains('theme-dark') ? '#f7f4ff' : '#211a33';\n}\n\nfunction getSVGPoint(event) {\n const viewBox = svg.viewBox.baseVal;\n const rect = svg.getBoundingClientRect();\n return {\n x: viewBox.x + ((event.clientX - rect.left) / rect.width) * viewBox.width,\n y: viewBox.y + ((event.clientY - rect.top) / rect.height) * viewBox.height,\n pressure: event.pressure || 0.5,\n };\n}\n\nfunction distance(a, b) {\n return Math.hypot(b.x - a.x, b.y - a.y);\n}\n\nfunction orientedBounds(sample, angle) {\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n let minU = Infinity;\n let maxU = -Infinity;\n let minV = Infinity;\n let maxV = -Infinity;\n for (const point of sample) {\n const u = point.x * cos + point.y * sin;\n const v = -point.x * sin + point.y * cos;\n minU = Math.min(minU, u);\n maxU = Math.max(maxU, u);\n minV = Math.min(minV, v);\n maxV = Math.max(maxV, v);\n }\n const centerU = (minU + maxU) / 2;\n const centerV = (minV + maxV) / 2;\n return {\n center: {\n x: centerU * cos - centerV * sin,\n y: centerU * sin + centerV * cos,\n },\n width: Math.max(MIN_SHAPE_SIZE, maxU - minU),\n height: Math.max(MIN_SHAPE_SIZE, maxV - minV),\n angle,\n minU,\n maxU,\n minV,\n maxV,\n };\n}\n\nfunction principalAngle(sample) {\n let meanX = 0;\n let meanY = 0;\n for (const point of sample) {\n meanX += point.x;\n meanY += point.y;\n }\n meanX /= sample.length;\n meanY /= sample.length;\n let xx = 0;\n let yy = 0;\n let xy = 0;\n for (const point of sample) {\n const dx = point.x - meanX;\n const dy = point.y - meanY;\n xx += dx * dx;\n yy += dy * dy;\n xy += dx * dy;\n }\n if (Math.abs(xx - yy) + Math.abs(xy) < 0.001) return 0;\n return Math.atan2(2 * xy, xx - yy) / 2;\n}\n\nfunction rectangleAngle(sample) {\n let x = 0;\n let y = 0;\n for (let index = 1; index < sample.length; index += 1) {\n const dx = sample[index].x - sample[index - 1].x;\n const dy = sample[index].y - sample[index - 1].y;\n const length = Math.hypot(dx, dy);\n if (length === 0) continue;\n const angle = Math.atan2(dy, dx) * 4;\n x += Math.cos(angle) * length;\n y += Math.sin(angle) * length;\n }\n return Math.atan2(y, x) / 4;\n}\n\nfunction closedShapePrediction(sample, pathLength) {\n const rectBounds = orientedBounds(sample, rectangleAngle(sample));\n const ellipseBounds = orientedBounds(sample, principalAngle(sample));\n let rectangleError = 0;\n let ellipseError = 0;\n\n const rectCos = Math.cos(rectBounds.angle);\n const rectSin = Math.sin(rectBounds.angle);\n const ellipseCos = Math.cos(ellipseBounds.angle);\n const ellipseSin = Math.sin(ellipseBounds.angle);\n const rectHalfW = rectBounds.width / 2;\n const rectHalfH = rectBounds.height / 2;\n const ellipseHalfW = ellipseBounds.width / 2;\n const ellipseHalfH = ellipseBounds.height / 2;\n\n for (const point of sample) {\n const rectDx = point.x - rectBounds.center.x;\n const rectDy = point.y - rectBounds.center.y;\n const rectU = Math.abs(rectDx * rectCos + rectDy * rectSin) / rectHalfW;\n const rectV = Math.abs(-rectDx * rectSin + rectDy * rectCos) / rectHalfH;\n rectangleError += Math.min(Math.abs(1 - rectU), Math.abs(1 - rectV));\n\n const ellipseDx = point.x - ellipseBounds.center.x;\n const ellipseDy = point.y - ellipseBounds.center.y;\n const ellipseU = (ellipseDx * ellipseCos + ellipseDy * ellipseSin) / ellipseHalfW;\n const ellipseV = (-ellipseDx * ellipseSin + ellipseDy * ellipseCos) / ellipseHalfH;\n ellipseError += Math.abs(1 - Math.hypot(ellipseU, ellipseV));\n }\n\n rectangleError /= sample.length;\n ellipseError /= sample.length;\n const rectangle = rectangleError <= ellipseError * 1.08;\n const bestError = rectangle ? rectangleError : ellipseError;\n if (bestError > 0.24) {\n return { type: 'freehand', points: sample.map((point) => ({ ...point })), pathLength };\n }\n const bounds = rectangle ? rectBounds : ellipseBounds;\n return {\n type: rectangle ? 'rectangle' : 'circle',\n ...bounds,\n pathLength,\n };\n}\n\nexport function predictDrawnShape(sample) {\n if (!Array.isArray(sample) || sample.length < 2) return null;\n const start = sample[0];\n let pathLength = 0;\n let farthestIndex = 1;\n let farthestDistance = 0;\n let minX = start.x;\n let maxX = start.x;\n let minY = start.y;\n let maxY = start.y;\n\n for (let index = 1; index < sample.length; index += 1) {\n pathLength += distance(sample[index - 1], sample[index]);\n const fromStart = distance(start, sample[index]);\n if (fromStart > farthestDistance) {\n farthestDistance = fromStart;\n farthestIndex = index;\n }\n minX = Math.min(minX, sample[index].x);\n maxX = Math.max(maxX, sample[index].x);\n minY = Math.min(minY, sample[index].y);\n maxY = Math.max(maxY, sample[index].y);\n }\n\n const diagonal = Math.max(MIN_SHAPE_SIZE, Math.hypot(maxX - minX, maxY - minY));\n const end = sample[sample.length - 1];\n const closed = sample.length >= 8 && distance(start, end) <= diagonal * 0.28 && pathLength >= diagonal * 2.05;\n if (closed) return closedShapePrediction(sample, pathLength);\n\n const tip = sample[farthestIndex];\n let afterTipLength = 0;\n for (let index = farthestIndex + 1; index < sample.length; index += 1) {\n afterTipLength += distance(sample[index - 1], sample[index]);\n }\n let shaftLength = 0;\n for (let index = 1; index <= farthestIndex; index += 1) {\n shaftLength += distance(sample[index - 1], sample[index]);\n }\n const arrow = farthestIndex >= Math.floor(sample.length * 0.45)\n && farthestIndex < sample.length - 2\n && afterTipLength >= diagonal * 0.18\n && distance(end, tip) <= diagonal * 0.48\n && farthestDistance / Math.max(shaftLength, 1) >= 0.86;\n\n const directDistance = distance(start, end);\n const line = !arrow && directDistance / Math.max(pathLength, 1) >= 0.92;\n\n if (!arrow && !line) {\n return { type: 'freehand', points: sample.map((point) => ({ ...point })), pathLength };\n }\n\n return {\n type: arrow ? 'arrow' : 'line',\n start: { ...start },\n end: arrow ? { ...tip } : { ...end },\n width: Math.max(MIN_SHAPE_SIZE, maxX - minX),\n height: Math.max(MIN_SHAPE_SIZE, maxY - minY),\n pathLength,\n };\n}\n\nfunction rotatedPoint(center, x, y, angle) {\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n return { x: center.x + x * cos - y * sin, y: center.y + x * sin + y * cos };\n}\n\nfunction pathForPrediction(prediction) {\n if (!prediction) return '';\n if (prediction.type === 'rectangle') {\n const halfW = prediction.width / 2;\n const halfH = prediction.height / 2;\n const corners = [\n rotatedPoint(prediction.center, -halfW, -halfH, prediction.angle),\n rotatedPoint(prediction.center, halfW, -halfH, prediction.angle),\n rotatedPoint(prediction.center, halfW, halfH, prediction.angle),\n rotatedPoint(prediction.center, -halfW, halfH, prediction.angle),\n ];\n return `M ${corners[0].x} ${corners[0].y} L ${corners[1].x} ${corners[1].y} L ${corners[2].x} ${corners[2].y} L ${corners[3].x} ${corners[3].y} Z`;\n }\n if (prediction.type === 'circle') {\n const rx = prediction.width / 2;\n const ry = prediction.height / 2;\n const start = rotatedPoint(prediction.center, rx, 0, prediction.angle);\n const opposite = rotatedPoint(prediction.center, -rx, 0, prediction.angle);\n const rotation = prediction.angle * 180 / Math.PI;\n return `M ${start.x} ${start.y} A ${rx} ${ry} ${rotation} 1 0 ${opposite.x} ${opposite.y} A ${rx} ${ry} ${rotation} 1 0 ${start.x} ${start.y}`;\n }\n if (prediction.type === 'freehand') {\n if (!prediction.points.length) return '';\n return prediction.points.reduce((path, point, index) => `${path}${index === 0 ? 'M' : ' L'} ${point.x} ${point.y}`, '');\n }\n const { start, end } = prediction;\n let path = `M ${start.x} ${start.y} L ${end.x} ${end.y}`;\n if (prediction.type === 'arrow') {\n const angle = Math.atan2(end.y - start.y, end.x - start.x);\n const head = Math.min(24 / (window.currentZoom || 1), distance(start, end) * 0.25);\n const left = rotatedPoint(end, -head, head * 0.55, angle);\n const right = rotatedPoint(end, -head, -head * 0.55, angle);\n path += ` M ${left.x} ${left.y} L ${end.x} ${end.y} L ${right.x} ${right.y}`;\n }\n return path;\n}\n\nfunction ensurePreview() {\n if (previewPath?.isConnected) return;\n previewPath = document.createElementNS(SVG_NS, 'path');\n previewPath.dataset.recognitionPreview = 'true';\n previewPath.setAttribute('fill', 'rgba(148, 148, 158, 0.06)');\n previewPath.setAttribute('stroke', '#9696a0');\n previewPath.setAttribute('stroke-width', '2');\n previewPath.setAttribute('stroke-dasharray', '5 7');\n previewPath.setAttribute('stroke-linecap', 'round');\n previewPath.setAttribute('stroke-linejoin', 'round');\n previewPath.setAttribute('vector-effect', 'non-scaling-stroke');\n previewPath.setAttribute('pointer-events', 'none');\n svg.appendChild(previewPath);\n}\n\nfunction renderPreview() {\n previewFrame = 0;\n if (!drawing) return;\n latestPrediction = predictDrawnShape(points);\n ensurePreview();\n previewPath.setAttribute('d', pathForPrediction(latestPrediction));\n previewPath.setAttribute('fill', latestPrediction?.type === 'rectangle' || latestPrediction?.type === 'circle'\n ? 'rgba(148, 148, 158, 0.06)'\n : 'none');\n}\n\nfunction schedulePreview() {\n if (!previewFrame) previewFrame = requestAnimationFrame(renderPreview);\n}\n\nfunction cleanupPreview() {\n if (previewFrame) cancelAnimationFrame(previewFrame);\n previewFrame = 0;\n previewPath?.remove();\n previewPath = null;\n}\n\nfunction currentStyle() {\n const settings = window.freehandToolSettings || {};\n const outline = settings.strokeStyle || 'solid';\n return {\n stroke: settings.strokeColor || getThemeStroke(),\n fill: 'transparent',\n fillStyle: 'none',\n strokeWidth: settings.strokeWidth || 2,\n strokeDasharray: outline === 'dashed' ? '10,10' : (outline === 'dotted' ? '2,8' : ''),\n outline,\n };\n}\n\nfunction attachToContainingFrame(shape) {\n for (let index = shapes.length - 1; index >= 0; index -= 1) {\n const frame = shapes[index];\n if (frame.shapeName !== 'frame' || typeof frame.isShapeInFrame !== 'function') continue;\n if (!frame.isShapeInFrame(shape)) continue;\n frame.addShapeToFrame(shape);\n pushFrameAttachmentAction(frame, shape, 'attach', null);\n break;\n }\n}\n\nfunction createPredictedShape(prediction) {\n if (!prediction) return null;\n const style = currentStyle();\n let shape = null;\n if (prediction.type === 'rectangle') {\n shape = new window.Rectangle(\n prediction.center.x - prediction.width / 2,\n prediction.center.y - prediction.height / 2,\n prediction.width,\n prediction.height,\n style,\n );\n shape.rotation = prediction.angle * 180 / Math.PI;\n shape.draw();\n } else if (prediction.type === 'circle') {\n shape = new window.Circle(\n prediction.center.x,\n prediction.center.y,\n prediction.width / 2,\n prediction.height / 2,\n style,\n );\n shape.rotation = prediction.angle * 180 / Math.PI;\n shape.draw();\n } else if (prediction.type === 'freehand') {\n const brush = window.freehandToolSettings || {};\n shape = new window.FreehandStroke(\n prediction.points.map((point) => [point.x, point.y, point.pressure || 0.5]),\n {\n stroke: style.stroke,\n strokeWidth: style.strokeWidth,\n strokeStyle: style.outline,\n thinning: brush.thinning ?? 0.5,\n roughness: brush.roughness || 'smooth',\n strokeOpacity: brush.opacity ?? 1,\n },\n );\n } else if (prediction.type === 'arrow') {\n shape = new window.Arrow(prediction.start, prediction.end, {\n stroke: style.stroke,\n strokeWidth: style.strokeWidth,\n arrowOutlineStyle: style.outline,\n arrowCurved: 'straight',\n });\n } else {\n shape = new window.Line(prediction.start, prediction.end, {\n stroke: style.stroke,\n strokeWidth: style.strokeWidth,\n strokeDasharray: style.strokeDasharray,\n roughness: 1.5,\n bowing: 1,\n });\n }\n shapes.push(shape);\n pushCreateAction(shape);\n attachToContainingFrame(shape);\n return shape;\n}\n\nexport function handleShapeRecognitionDown(event) {\n if (!window.isShapeRecognitionToolActive || event.button !== 0) return;\n drawing = true;\n points = [getSVGPoint(event)];\n latestPrediction = null;\n ensurePreview();\n schedulePreview();\n}\n\nexport function handleShapeRecognitionMove(event) {\n if (!drawing || !window.isShapeRecognitionToolActive) return;\n const point = getSVGPoint(event);\n const last = points[points.length - 1];\n const threshold = MIN_SCREEN_SAMPLE_PX / (window.currentZoom || 1);\n if (distance(last, point) < threshold) return;\n if (points.length < MAX_POINTS) {\n points.push(point);\n } else {\n // Preserve the first point and evenly discard older detail. Memory and\n // recognition time stay constant even during very long gestures.\n points = [points[0], ...points.slice(2).filter((_, index) => index % 2 === 0), point];\n }\n schedulePreview();\n}\n\nexport function handleShapeRecognitionUp(event) {\n if (!drawing) return;\n drawing = false;\n const rect = svg.getBoundingClientRect();\n if (event.clientX >= rect.left && event.clientX <= rect.right && event.clientY >= rect.top && event.clientY <= rect.bottom) {\n const point = getSVGPoint(event);\n if (distance(points[points.length - 1], point) > 0) points.push(point);\n }\n latestPrediction = predictDrawnShape(points);\n cleanupPreview();\n\n const prediction = latestPrediction;\n points = [];\n latestPrediction = null;\n if (!prediction || prediction.pathLength < MIN_SHAPE_SIZE) return;\n\n const shape = createPredictedShape(prediction);\n if (!shape) return;\n if (window.__sketchStoreApi) window.__sketchStoreApi.setActiveTool('select', { afterDraw: true });\n currentShape = shape;\n if (shape.shapeName === 'freehandStroke' && typeof shape.selectStroke === 'function') {\n shape.selectStroke();\n } else {\n shape.isSelected = true;\n if (typeof shape.addAnchors === 'function') shape.addAnchors();\n }\n}\n\nexport function cancelShapeRecognition() {\n drawing = false;\n points = [];\n latestPrediction = null;\n cleanupPreview();\n}\n\nwindow.__cancelShapeRecognition = cancelShapeRecognition;\n", "/* eslint-disable */\nimport { pushOptionsChangeAction } from '../core/UndoRedo.js';\n\nconst CLOSED_SHAPES = new Set(['rectangle', 'circle']);\n\nwindow.paintBucketSettings = window.paintBucketSettings || {\n fillColor: '#A98DEB',\n fillStyle: 'solid',\n};\n\nfunction getSVGPoint(event) {\n const viewBox = svg.viewBox.baseVal;\n const rect = svg.getBoundingClientRect();\n return {\n x: viewBox.x + ((event.clientX - rect.left) / rect.width) * viewBox.width,\n y: viewBox.y + ((event.clientY - rect.top) / rect.height) * viewBox.height,\n };\n}\n\nfunction findClosedShapeAt(x, y) {\n for (let index = shapes.length - 1; index >= 0; index -= 1) {\n const shape = shapes[index];\n if (!CLOSED_SHAPES.has(shape?.shapeName) || typeof shape.contains !== 'function') continue;\n if (shape.contains(x, y)) return shape;\n }\n return null;\n}\n\nexport function handlePaintBucketDown(event) {\n if (!window.isPaintBucketToolActive || event.button !== 0) return;\n const { x, y } = getSVGPoint(event);\n const shape = findClosedShapeAt(x, y);\n if (!shape) {\n window.dispatchEvent(new CustomEvent('lixsketch:bucket-miss'));\n return;\n }\n\n const settings = window.paintBucketSettings;\n const transparent = settings.fillStyle === 'none' || settings.fillStyle === 'transparent';\n const nextFill = transparent ? 'transparent' : settings.fillColor;\n const nextStyle = transparent ? 'none' : settings.fillStyle;\n if (shape.options.fill === nextFill && shape.options.fillStyle === nextStyle) return;\n\n const oldOptions = { ...shape.options };\n const newOptions = { ...shape.options, fill: nextFill, fillStyle: nextStyle };\n pushOptionsChangeAction(shape, oldOptions, newOptions);\n shape.options = newOptions;\n shape.draw();\n window.dispatchEvent(new CustomEvent('lixsketch:bucket-filled', { detail: { shapeID: shape.shapeID } }));\n}\n", "/* eslint-disable */\n\nimport { multiSelection } from '../core/Selection.js';\n\nconst MAX_POINTS = 192;\nconst MIN_SAMPLE_PX = 4;\nlet points = [];\nlet preview = null;\nlet drawing = false;\n\nfunction coords(e) {\n const vb = svg.viewBox.baseVal;\n const rect = svg.getBoundingClientRect();\n return { x: vb.x + ((e.clientX - rect.left) / rect.width) * vb.width, y: vb.y + ((e.clientY - rect.top) / rect.height) * vb.height };\n}\n\nfunction pointInPolygon(point, polygon) {\n let inside = false;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const a = polygon[i], b = polygon[j];\n if (((a.y > point.y) !== (b.y > point.y)) && point.x < ((b.x - a.x) * (point.y - a.y)) / ((b.y - a.y) || Number.EPSILON) + a.x) inside = !inside;\n }\n return inside;\n}\n\nfunction boundsPoints(shape) {\n if ((shape.shapeName === 'line' || shape.shapeName === 'arrow') && shape.startPoint && shape.endPoint) return [shape.startPoint, shape.endPoint];\n if (shape.shapeName === 'freehandStroke' && Array.isArray(shape.points)) {\n const step = Math.max(1, Math.ceil(shape.points.length / 16));\n return shape.points.filter((_, i) => i % step === 0).map((p) => ({ x: p[0], y: p[1] }));\n }\n let x = shape.x || 0, y = shape.y || 0, width = shape.width || 0, height = shape.height || 0;\n if (shape.shapeName === 'circle') { x = shape.x - shape.rx; y = shape.y - shape.ry; width = shape.rx * 2; height = shape.ry * 2; }\n if ((!width || !height) && shape.group?.getBBox) {\n try { const box = shape.group.getBBox(); x = box.x; y = box.y; width = box.width; height = box.height; } catch {}\n }\n const raw = [{ x, y }, { x: x + width, y }, { x: x + width, y: y + height }, { x, y: y + height }, { x: x + width / 2, y: y + height / 2 }];\n const rotation = Number(shape.rotation) || 0;\n if (!rotation) return raw;\n const cx = x + width / 2, cy = y + height / 2, angle = rotation * Math.PI / 180;\n return raw.map((p) => ({ x: cx + (p.x - cx) * Math.cos(angle) - (p.y - cy) * Math.sin(angle), y: cy + (p.x - cx) * Math.sin(angle) + (p.y - cy) * Math.cos(angle) }));\n}\n\nfunction cleanup() {\n preview?.remove(); preview = null; points = []; drawing = false;\n}\n\nexport function handleLassoDown(e) {\n if (!window.isLassoToolActive) return;\n cleanup(); multiSelection.clearSelection(); drawing = true; points = [coords(e)];\n preview = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n preview.setAttribute('fill', 'rgba(139, 118, 214, .10)'); preview.setAttribute('stroke', '#a78bfa');\n preview.setAttribute('stroke-dasharray', '5 4'); preview.setAttribute('vector-effect', 'non-scaling-stroke');\n preview.style.pointerEvents = 'none'; svg.appendChild(preview);\n}\n\nexport function handleLassoMove(e) {\n if (!drawing) return;\n const p = coords(e), last = points[points.length - 1];\n const min = MIN_SAMPLE_PX / (window.currentZoom || 1);\n if (Math.hypot(p.x - last.x, p.y - last.y) < min) return;\n if (points.length < MAX_POINTS) points.push(p); else points[points.length - 1] = p;\n preview?.setAttribute('d', `M ${points.map((v) => `${v.x} ${v.y}`).join(' L ')} Z`);\n}\n\nexport function handleLassoUp() {\n if (!drawing) return;\n const polygon = points.slice(); cleanup();\n // Switching tools clears selection state. Do that before applying the\n // lasso result so the newly selected shapes survive the tool transition.\n window.__sketchStoreApi?.setActiveTool('select', { afterDraw: true });\n if (polygon.length >= 3 && Array.isArray(window.shapes)) {\n const selected = window.shapes.filter((shape) => boundsPoints(shape).every((p) => pointInPolygon(p, polygon)));\n const filtered = selected.filter((shape) => !shape.parentFrame || !selected.includes(shape.parentFrame));\n // Apply the batch once; addShape() rebuilds controls per item and becomes\n // unnecessarily quadratic for a large lasso selection.\n filtered.forEach((shape) => { multiSelection.selectedShapes.add(shape); shape.isSelected = true; });\n if (filtered.length) multiSelection.updateControls();\n window.currentShape = filtered.length === 1 ? filtered[0] : null;\n }\n}\n\nexport function cancelLasso() { cleanup(); }\nwindow.__cancelLasso = cancelLasso;\n", "/* eslint-disable */\n\nimport { Frame } from '../shapes/Frame.js';\nimport { pushCreateAction } from '../core/UndoRedo.js';\nimport { normalizeWebEmbedUrl } from '../core/WebEmbedPolicy.js';\n\nlet frame = null, start = null;\nfunction coords(e) {\n const vb = svg.viewBox.baseVal, rect = svg.getBoundingClientRect();\n return { x: vb.x + ((e.clientX - rect.left) / rect.width) * vb.width, y: vb.y + ((e.clientY - rect.top) / rect.height) * vb.height };\n}\n\nexport function placeWebEmbed(urlValue) {\n const url = normalizeWebEmbedUrl(urlValue);\n if (!url || typeof svg === 'undefined') return null;\n\n // Complete the tool transition first because setActiveTool clears the\n // previous selection. The newly inserted frame should remain selected.\n window.__sketchStoreApi?.setActiveTool('select');\n const viewBox = svg.viewBox.baseVal;\n const width = Math.min(640, Math.max(320, viewBox.width * 0.56));\n const height = width * 9 / 16;\n const x = viewBox.x + (viewBox.width - width) / 2;\n const y = viewBox.y + (viewBox.height - height) / 2;\n const placedFrame = new Frame(x, y, width, height, {\n frameName: 'Web embed', frameType: 'web-embed', webEmbedURL: url,\n stroke: '#8b76d6', strokeWidth: 2,\n });\n shapes.push(placedFrame);\n pushCreateAction(placedFrame);\n currentShape = placedFrame;\n placedFrame.selectFrame();\n window.__pendingWebEmbedURL = null;\n return placedFrame;\n}\n\nexport function handleWebEmbedDown(e) {\n const url = normalizeWebEmbedUrl(window.__pendingWebEmbedURL);\n if (!window.isWebEmbedToolActive || !url) { window.__showWebEmbedModal?.(); return; }\n start = coords(e);\n frame = new Frame(start.x, start.y, 0, 0, { frameName: 'Web embed', frameType: 'web-embed', webEmbedURL: url, stroke: '#8b76d6', strokeWidth: 2 });\n shapes.push(frame); currentShape = frame;\n}\n\nexport function handleWebEmbedMove(e) {\n if (!frame || !start) return;\n const p = coords(e); frame.x = Math.min(start.x, p.x); frame.y = Math.min(start.y, p.y);\n frame.width = Math.abs(p.x - start.x); frame.height = Math.abs(p.y - start.y); frame.draw();\n}\n\nexport function handleWebEmbedUp() {\n if (!frame) return;\n if (frame.width < 40 || frame.height < 30) { frame.width = 560; frame.height = 315; }\n frame.draw(); pushCreateAction(frame);\n const placedFrame = frame;\n window.__pendingWebEmbedURL = null; frame = null; start = null;\n window.__sketchStoreApi?.setActiveTool('select', { afterDraw: true });\n currentShape = placedFrame; placedFrame.selectFrame();\n}\n\nwindow.__placeWebEmbed = placeWebEmbed;\n", "/* eslint-disable */\n// Event dispatcher - extracted from eventListeners.js\n// Central event routing for all tools\n\nimport { handleMouseDownRect, handleMouseMoveRect, handleMouseUpRect } from '../tools/rectangleTool.js';\nimport { handleMouseDownArrow, handleMouseMoveArrow, handleMouseUpArrow } from '../tools/arrowTool.js';\nimport { handleMouseDownCircle, handleMouseMoveCircle, handleMouseUpCircle } from '../tools/circleTool.js';\nimport { handleMouseUpImage, handleMouseDownImage, handleMouseMoveImage } from '../tools/imageTool.js';\nimport { handleMouseDownLine, handleMouseMoveLine, handleMouseUpLine } from '../tools/lineTool.js';\nimport { handleFreehandMouseDown, handleFreehandMouseMove, handleFreehandMouseUp } from '../tools/freehandTool.js';\nimport { handleTextMouseDown, handleTextMouseMove, handleTextMouseUp, enterEditMode } from '../tools/textTool.js';\nimport { handleMouseDownFrame, handleMouseMoveFrame, handleMouseUpFrame } from '../tools/frameTool.js';\nimport { handleMultiSelectionMouseDown, handleMultiSelectionMouseMove, handleMultiSelectionMouseUp, removeMultiSelectionRect, multiSelection, isMultiSelecting} from './Selection.js';\nimport { handleMouseDownIcon, handleMouseMoveIcon, handleMouseUpIcon } from '../tools/iconTool.js';\nimport { handleCodeMouseDown, handleCodeMouseMove, handleCodeMouseUp } from '../tools/codeTool.js';\nimport { handleShapeRecognitionDown, handleShapeRecognitionMove, handleShapeRecognitionUp } from '../tools/shapeRecognitionTool.js';\nimport { handlePaintBucketDown } from '../tools/paintBucketTool.js';\nimport { handleLassoDown, handleLassoMove, handleLassoUp } from '../tools/lassoTool.js';\nimport { handleWebEmbedDown, handleWebEmbedMove, handleWebEmbedUp } from '../tools/webEmbedTool.js';\n\n// === Auto-scroll when dragging near viewport edges ===\nconst EDGE_THRESHOLD = 40; // px from edge to start scrolling\nconst SCROLL_SPEED = 8; // base px per frame (scaled by zoom)\nlet _autoScrollRAF = null;\n\nfunction _autoScroll(e) {\n if (!(e.buttons & 1)) { _stopAutoScroll(); return; } // no primary button\n if (typeof currentViewBox === 'undefined' || typeof currentZoom === 'undefined') return;\n if (typeof isPanning !== 'undefined' && isPanning) return; // don't fight pan tool\n if (typeof isPanningToolActive !== 'undefined' && isPanningToolActive) return;\n\n const rect = svg.getBoundingClientRect();\n const mx = e.clientX - rect.left;\n const my = e.clientY - rect.top;\n\n let dx = 0, dy = 0;\n if (mx < EDGE_THRESHOLD) dx = -SCROLL_SPEED * (1 - mx / EDGE_THRESHOLD);\n else if (mx > rect.width - EDGE_THRESHOLD) dx = SCROLL_SPEED * (1 - (rect.width - mx) / EDGE_THRESHOLD);\n if (my < EDGE_THRESHOLD) dy = -SCROLL_SPEED * (1 - my / EDGE_THRESHOLD);\n else if (my > rect.height - EDGE_THRESHOLD) dy = SCROLL_SPEED * (1 - (rect.height - my) / EDGE_THRESHOLD);\n\n // Also scroll when cursor is outside the canvas entirely\n if (e.clientX < rect.left) dx = -SCROLL_SPEED;\n else if (e.clientX > rect.right) dx = SCROLL_SPEED;\n if (e.clientY < rect.top) dy = -SCROLL_SPEED;\n else if (e.clientY > rect.bottom) dy = SCROLL_SPEED;\n\n if (dx === 0 && dy === 0) { _stopAutoScroll(); return; }\n\n // Scale speed inversely with zoom so scrolling feels consistent\n const scale = 1 / currentZoom;\n currentViewBox.x += dx * scale;\n currentViewBox.y += dy * scale;\n svg.setAttribute('viewBox', `${currentViewBox.x} ${currentViewBox.y} ${currentViewBox.width} ${currentViewBox.height}`);\n if (typeof freehandCanvas !== 'undefined' && freehandCanvas !== svg) {\n freehandCanvas.setAttribute('viewBox', `${currentViewBox.x} ${currentViewBox.y} ${currentViewBox.width} ${currentViewBox.height}`);\n }\n}\n\nfunction _startAutoScroll() {\n if (_autoScrollRAF) return;\n const tick = () => {\n if (_lastDragEvent) _autoScroll(_lastDragEvent);\n _autoScrollRAF = requestAnimationFrame(tick);\n };\n _autoScrollRAF = requestAnimationFrame(tick);\n}\n\nfunction _stopAutoScroll() {\n if (_autoScrollRAF) {\n cancelAnimationFrame(_autoScrollRAF);\n _autoScrollRAF = null;\n }\n _lastDragEvent = null;\n}\n\nlet _lastDragEvent = null;\nlet _documentDragActive = false;\n\nfunction _onDocumentDragMove(e) {\n _lastDragEvent = e;\n // Clamp mouse coordinates to SVG bounds before forwarding to tool handlers,\n // so getSVGCoordsFromMouse doesn't produce extreme values when cursor is outside.\n const rect = svg.getBoundingClientRect();\n const clampedX = Math.max(rect.left, Math.min(rect.right, e.clientX));\n const clampedY = Math.max(rect.top, Math.min(rect.bottom, e.clientY));\n const clampedEvent = new PointerEvent(e.type, {\n clientX: clampedX,\n clientY: clampedY,\n buttons: e.buttons,\n button: e.button,\n ctrlKey: e.ctrlKey,\n shiftKey: e.shiftKey,\n altKey: e.altKey,\n metaKey: e.metaKey,\n });\n handleMainMouseMove(clampedEvent);\n}\n\nfunction _onDocumentDragUp(e) {\n _stopAutoScroll();\n document.removeEventListener('pointermove', _onDocumentDragMove);\n document.removeEventListener('pointerup', _onDocumentDragUp);\n _documentDragActive = false;\n // Finalize the operation\n handleMainMouseUp(e);\n}\n\nconst handleMainMouseDown = (e) => {\n if (!e.target) return;\n // Middle / right mouse buttons are reserved for panning and the\n // browser context menu; they should NOT trigger tool actions or the\n // multi-selection rectangle. Without this guard, middle-click-drag\n // simultaneously pans (handled in ZoomPan) and starts a selection\n // marquee.\n if (e.button === 1 || e.button === 2 || window.__spacePanActive) return;\n // Safety: remove any stray selection rectangle from a previous interrupted drag\n removeMultiSelectionRect();\n\n // For non-selection tools: deselect everything when clicking on empty canvas\n // (Selection tool handles its own deselection in handleMultiSelectionMouseDown)\n if (!isSelectionToolActive) {\n // Clear multi-selection for any tool switch\n if (multiSelection.selectedShapes.size > 0) {\n multiSelection.clearSelection();\n }\n // Deselect current individual shape when starting a new tool action\n if (currentShape && typeof currentShape.removeSelection === 'function') {\n currentShape.removeSelection();\n currentShape = null;\n }\n if (typeof disableAllSideBars === 'function') {\n disableAllSideBars();\n }\n }\n\n if (window.isLassoToolActive) {\n handleLassoDown(e);\n } else if (window.isWebEmbedToolActive) {\n handleWebEmbedDown(e);\n } else if (window.isShapeRecognitionToolActive) {\n handleShapeRecognitionDown(e);\n } else if (window.isPaintBucketToolActive) {\n handlePaintBucketDown(e);\n } else if (isSquareToolActive) {\n handleMouseDownRect(e);\n } else if (isArrowToolActive) {\n handleMouseDownArrow(e);\n } else if (isCircleToolActive) {\n handleMouseDownCircle(e);\n } else if (isImageToolActive) {\n handleMouseDownImage(e);\n } \n else if (isLineToolActive) {\n handleMouseDownLine(e);\n }\n else if (isPaintToolActive) {\n handleFreehandMouseDown(e);\n }\n else if (isTextToolActive) {\n // Text tool handles both text and code shapes based on target and mode\n const targetCodeGroup = e.target.closest('g[data-type=\"code-group\"]');\n const targetTextGroup = e.target.closest('g[data-type=\"text-group\"]');\n if (targetCodeGroup && !targetTextGroup) {\n handleCodeMouseDown(e);\n } else if (isTextInCodeMode && !targetTextGroup && !targetCodeGroup) {\n handleCodeMouseDown(e);\n } else {\n handleTextMouseDown(e);\n }\n }\n else if (isFrameToolActive) {\n handleMouseDownFrame(e);\n }\n else if (isIconToolActive) {\n handleMouseDownIcon(e);\n }\n else if (isSelectionToolActive) {\n // Try multi-selection first when selection tool is active\n if (handleMultiSelectionMouseDown(e)) {\n return; // Multi-selection handled the event\n }\n\n // Remember previous shape to detect deselection\n const prevShape = currentShape;\n let handled = false;\n\n // If multi-selection didn't handle it, proceed with shape-specific selection\n if (currentShape?.shapeName === 'rectangle') {\n handleMouseDownRect(e);\n handled = true;\n } else if (currentShape?.shapeName === 'arrow') {\n handleMouseDownArrow(e);\n handled = true;\n } else if (currentShape?.shapeName === 'circle') {\n handleMouseDownCircle(e);\n handled = true;\n } else if (currentShape?.shapeName === 'image') {\n handleMouseDownImage(e);\n handled = true;\n }\n else if (currentShape?.shapeName === 'line') {\n handleMouseDownLine(e);\n handled = true;\n }\n else if (currentShape?.shapeName === 'freehandStroke') {\n handleFreehandMouseDown(e);\n handled = true;\n }\n else if (currentShape?.shapeName === 'text') {\n handleTextMouseDown(e);\n handled = true;\n }\n else if (currentShape?.shapeName === 'frame') {\n handleMouseDownFrame(e);\n handled = true;\n }\n else if (currentShape?.shapeName === 'icon') {\n handleMouseDownIcon(e);\n handled = true;\n }\n else if( currentShape?.shapeName === 'code') {\n handleCodeMouseDown(e);\n handled = true;\n }\n\n // If the handler deselected (currentShape cleared) but didn't select something new,\n // fall through to try all handlers so clicking another shape type works\n if (handled && prevShape && !currentShape) {\n handled = false;\n }\n\n if (!handled) {\n const originalCurrentShape = currentShape;\n handleMouseDownRect(e);\n if (currentShape && currentShape !== originalCurrentShape) return;\n handleMouseDownCircle(e);\n if (currentShape && currentShape !== originalCurrentShape) return;\n handleMouseDownArrow(e);\n if (currentShape && currentShape !== originalCurrentShape) return;\n handleMouseDownImage(e);\n if (currentShape && currentShape !== originalCurrentShape) return;\n handleMouseDownLine(e);\n if (currentShape && currentShape !== originalCurrentShape) return;\n handleFreehandMouseDown(e);\n if (currentShape && currentShape !== originalCurrentShape) return;\n handleTextMouseDown(e);\n if (currentShape && currentShape !== originalCurrentShape) return;\n handleMouseDownFrame(e);\n if (currentShape && currentShape !== originalCurrentShape) return;\n handleMouseDownIcon(e);\n if (currentShape && currentShape !== originalCurrentShape) return;\n handleCodeMouseDown(e);\n if (currentShape && currentShape !== originalCurrentShape) return;\n if (currentShape === originalCurrentShape) {\n if (currentShape) {\n currentShape.removeSelection();\n currentShape = null;\n }\n }\n }\n }\n};\n\nconst handleMainMouseMove = (e) => {\n if (window.__spacePanPointerActive) return;\n // Auto-scroll when dragging near/past viewport edges (checked first so early returns don't skip it)\n if (e.buttons & 1) {\n _lastDragEvent = e;\n _startAutoScroll();\n } else {\n _stopAutoScroll();\n }\n\n if (window.isLassoToolActive) {\n handleLassoMove(e);\n } else if (window.isWebEmbedToolActive) {\n handleWebEmbedMove(e);\n } else if (window.isShapeRecognitionToolActive) {\n handleShapeRecognitionMove(e);\n } else if (window.isPaintBucketToolActive) {\n return;\n } else if (isSquareToolActive) {\n handleMouseMoveRect(e);\n } else if (isArrowToolActive) {\n handleMouseMoveArrow(e);\n } else if (isCircleToolActive) {\n handleMouseMoveCircle(e);\n } else if (isImageToolActive) {\n handleMouseMoveImage(e);\n } \n else if (isLineToolActive) {\n handleMouseMoveLine(e);\n }\n else if (isPaintToolActive) {\n handleFreehandMouseMove(e);\n }\n else if (isTextToolActive) {\n handleTextMouseMove(e);\n handleCodeMouseMove(e);\n }\n else if (isFrameToolActive) {\n handleMouseMoveFrame(e);\n }\n else if (isIconToolActive) {\n handleMouseMoveIcon(e);\n }\n else if (isSelectionToolActive) {\n // Handle multi-selection operations first - these take priority\n if (isMultiSelecting || multiSelection.isDragging || multiSelection.isResizing || multiSelection.isRotating) {\n if (handleMultiSelectionMouseMove(e)) {\n return; // Multi-selection handled the event\n }\n }\n \n // Shape-specific mouse move handling\n if (currentShape?.shapeName === 'rectangle') {\n handleMouseMoveRect(e);\n } else if (currentShape?.shapeName === 'arrow') {\n handleMouseMoveArrow(e);\n } else if (currentShape?.shapeName === 'circle') {\n handleMouseMoveCircle(e);\n } else if (currentShape?.shapeName === 'image') {\n handleMouseMoveImage(e);\n } \n else if (currentShape?.shapeName === 'line') {\n handleMouseMoveLine(e);\n }\n else if (currentShape?.shapeName === 'freehandStroke') {\n handleFreehandMouseMove(e);\n }\n else if (currentShape?.shapeName === 'text') {\n handleTextMouseMove(e);\n }\n else if (currentShape?.shapeName === 'frame') {\n handleMouseMoveFrame(e);\n }\n else if (currentShape?.shapeName === 'icon') {\n handleMouseMoveIcon(e);\n }\n else if (currentShape?.shapeName === 'code') {\n handleCodeMouseMove(e);\n }\n\n else {\n // Try multi-selection mouse move for cursor updates\n if (handleMultiSelectionMouseMove(e)) {\n return;\n }\n \n handleMouseMoveRect(e);\n handleMouseMoveArrow(e);\n handleMouseMoveCircle(e);\n handleMouseMoveImage(e);\n handleMouseMoveLine(e);\n handleFreehandMouseMove(e);\n handleTextMouseMove(e);\n handleMouseMoveFrame(e);\n handleMouseMoveIcon(e);\n handleCodeMouseMove(e);\n }\n }\n};\n\nconst handleMainMouseUp = (e) => {\n if (window.__spacePanPointerActive) return;\n _stopAutoScroll();\n if (window.isLassoToolActive) {\n handleLassoUp(e);\n } else if (window.isWebEmbedToolActive) {\n handleWebEmbedUp(e);\n } else if (window.isShapeRecognitionToolActive) {\n handleShapeRecognitionUp(e);\n } else if (window.isPaintBucketToolActive) {\n return;\n } else if (isSquareToolActive) {\n handleMouseUpRect(e);\n } else if (isArrowToolActive) {\n handleMouseUpArrow(e);\n } else if (isCircleToolActive) {\n handleMouseUpCircle(e);\n } else if (isImageToolActive) {\n handleMouseUpImage(e);\n } \n else if (isLineToolActive) { \n handleMouseUpLine(e);\n }\n else if (isPaintToolActive) {\n handleFreehandMouseUp(e);\n }\n else if (isTextToolActive) {\n handleTextMouseUp(e);\n handleCodeMouseUp(e);\n }\n else if (isFrameToolActive) {\n handleMouseUpFrame(e);\n }\n else if (isIconToolActive) {\n handleMouseUpIcon(e);\n }\n\n else if (isSelectionToolActive) {\n // Always try multi-selection cleanup first\n if (isMultiSelecting || multiSelection.isDragging || multiSelection.isResizing || multiSelection.isRotating) {\n handleMultiSelectionMouseUp(e);\n return;\n }\n\n // Shape-specific mouse up handling\n if (currentShape?.shapeName === 'rectangle') {\n handleMouseUpRect(e);\n } else if (currentShape?.shapeName === 'arrow') {\n handleMouseUpArrow(e);\n } else if (currentShape?.shapeName === 'circle') {\n handleMouseUpCircle(e);\n } else if (currentShape?.shapeName === 'image') {\n handleMouseUpImage(e);\n }\n else if (currentShape?.shapeName === 'line') {\n handleMouseUpLine(e);\n }\n else if (currentShape?.shapeName === 'freehandStroke') {\n handleFreehandMouseUp(e);\n }\n else if (currentShape?.shapeName === 'text') {\n handleTextMouseUp(e);\n }\n else if (currentShape?.shapeName === 'frame') {\n handleMouseUpFrame(e);\n }\n else if (currentShape?.shapeName === 'icon') {\n handleMouseUpIcon(e);\n }\n else if (currentShape?.shapeName === 'code') {\n handleCodeMouseUp(e);\n }\n\n else {\n handleMultiSelectionMouseUp(e);\n handleMouseUpRect(e);\n handleMouseUpArrow(e);\n handleMouseUpCircle(e);\n handleMouseUpImage(e);\n handleMouseUpLine(e);\n handleFreehandMouseUp(e);\n handleTextMouseUp(e);\n handleMouseUpFrame(e);\n handleMouseUpIcon(e);\n handleCodeMouseUp(e);\n }\n }\n};\n\nconst handleMainMouseLeave = (e) => {\n if (window.__spacePanPointerActive) return;\n // If the user is still holding the primary button (dragging outside the canvas),\n // keep auto-scrolling and don't finalize the operation yet.\n if (e.buttons & 1) {\n _lastDragEvent = e;\n _startAutoScroll();\n\n // Listen on document to continue receiving move events outside the SVG\n if (!_documentDragActive) {\n _documentDragActive = true;\n document.addEventListener('pointermove', _onDocumentDragMove);\n document.addEventListener('pointerup', _onDocumentDragUp);\n }\n return;\n }\n\n // Stop all active drawing tools when pointer leaves the canvas\n\n // Fire mouseUp for whichever tool is active to finalize/cancel the operation\n handleMainMouseUp(e);\n\n // Always clean up any stray selection rectangle when pointer leaves canvas\n removeMultiSelectionRect();\n\n // Eraser: force cleanup any lingering trail\n if (typeof window.forceCleanupEraserTrail === 'function') {\n window.forceCleanupEraserTrail();\n }\n\n // Laser: stop drawing and fade out active laser (globals from laserTool.js)\n if (typeof isDrawing !== 'undefined' && isDrawing) {\n isDrawing = false;\n if (typeof lasers !== 'undefined' && lasers.length > 0 && typeof fadeLaserTrail === 'function') {\n const lastLaser = lasers[lasers.length - 1];\n fadeLaserTrail(lastLaser);\n }\n }\n};\n\nlet _boundSvg = null;\n\nfunction _onMouseEnter(e) {\n // Cursor re-entered the SVG \u2014 stop document-level tracking, SVG handles events again\n if (_documentDragActive) {\n document.removeEventListener('pointermove', _onDocumentDragMove);\n document.removeEventListener('pointerup', _onDocumentDragUp);\n _documentDragActive = false;\n }\n}\n\nconst handleMainDblClick = (e) => {\n if (!e.target) return;\n // Double-click on a text group from any tool: enter text edit mode\n const targetTextGroup = e.target.closest('g[data-type=\"text-group\"]');\n if (targetTextGroup) {\n e.stopPropagation();\n enterEditMode(targetTextGroup);\n }\n};\n\nfunction initEventDispatcher(svgEl) {\n if (_boundSvg) cleanupEventDispatcher();\n const target = svgEl || svg;\n target.addEventListener('pointerdown', handleMainMouseDown);\n target.addEventListener('pointermove', handleMainMouseMove);\n target.addEventListener('pointerup', handleMainMouseUp);\n target.addEventListener('pointerleave', handleMainMouseLeave);\n target.addEventListener('pointerenter', _onMouseEnter);\n target.addEventListener('dblclick', handleMainDblClick);\n _boundSvg = target;\n}\n\nfunction cleanupEventDispatcher() {\n _stopAutoScroll();\n if (_documentDragActive) {\n document.removeEventListener('pointermove', _onDocumentDragMove);\n document.removeEventListener('pointerup', _onDocumentDragUp);\n _documentDragActive = false;\n }\n if (_boundSvg) {\n _boundSvg.removeEventListener('pointerdown', handleMainMouseDown);\n _boundSvg.removeEventListener('pointermove', handleMainMouseMove);\n _boundSvg.removeEventListener('pointerup', handleMainMouseUp);\n _boundSvg.removeEventListener('pointerleave', handleMainMouseLeave);\n _boundSvg.removeEventListener('pointerenter', _onMouseEnter);\n _boundSvg.removeEventListener('dblclick', handleMainDblClick);\n _boundSvg = null;\n }\n}\n\n// Auto-init if svg is already available (first load)\nif (typeof svg !== 'undefined' && svg) {\n initEventDispatcher(svg);\n}\n\nexport { handleMainMouseDown, handleMainMouseMove, handleMainMouseUp, handleMainMouseLeave, initEventDispatcher, cleanupEventDispatcher };\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,IAAM,SAAS;AACf,IAAM,aAAa;AACnB,IAAM,uBAAuB;AAC7B,IAAM,iBAAiB;AAEvB,IAAI,UAAU;AACd,IAAI,SAAS,CAAC;AACd,IAAI,cAAc;AAClB,IAAI,eAAe;AACnB,IAAI,mBAAmB;AAEvB,SAAS,iBAAiB;AACtB,SAAO,SAAS,MAAM,UAAU,SAAS,YAAY,IAAI,YAAY;AACzE;AAEA,SAAS,YAAY,OAAO;AACxB,QAAM,UAAU,IAAI,QAAQ;AAC5B,QAAM,OAAO,IAAI,sBAAsB;AACvC,SAAO;AAAA,IACH,GAAG,QAAQ,KAAM,MAAM,UAAU,KAAK,QAAQ,KAAK,QAAS,QAAQ;AAAA,IACpE,GAAG,QAAQ,KAAM,MAAM,UAAU,KAAK,OAAO,KAAK,SAAU,QAAQ;AAAA,IACpE,UAAU,MAAM,YAAY;AAAA,EAChC;AACJ;AAEA,SAAS,SAAS,GAAG,GAAG;AACpB,SAAO,KAAK,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AAC1C;AAEA,SAAS,eAAe,QAAQ,OAAO;AACnC,QAAM,MAAM,KAAK,IAAI,KAAK;AAC1B,QAAM,MAAM,KAAK,IAAI,KAAK;AAC1B,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,OAAO;AACX,aAAW,SAAS,QAAQ;AACxB,UAAM,IAAI,MAAM,IAAI,MAAM,MAAM,IAAI;AACpC,UAAM,IAAI,CAAC,MAAM,IAAI,MAAM,MAAM,IAAI;AACrC,WAAO,KAAK,IAAI,MAAM,CAAC;AACvB,WAAO,KAAK,IAAI,MAAM,CAAC;AACvB,WAAO,KAAK,IAAI,MAAM,CAAC;AACvB,WAAO,KAAK,IAAI,MAAM,CAAC;AAAA,EAC3B;AACA,QAAM,WAAW,OAAO,QAAQ;AAChC,QAAM,WAAW,OAAO,QAAQ;AAChC,SAAO;AAAA,IACH,QAAQ;AAAA,MACJ,GAAG,UAAU,MAAM,UAAU;AAAA,MAC7B,GAAG,UAAU,MAAM,UAAU;AAAA,IACjC;AAAA,IACA,OAAO,KAAK,IAAI,gBAAgB,OAAO,IAAI;AAAA,IAC3C,QAAQ,KAAK,IAAI,gBAAgB,OAAO,IAAI;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ;AAEA,SAAS,eAAe,QAAQ;AAC5B,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,aAAW,SAAS,QAAQ;AACxB,aAAS,MAAM;AACf,aAAS,MAAM;AAAA,EACnB;AACA,WAAS,OAAO;AAChB,WAAS,OAAO;AAChB,MAAI,KAAK;AACT,MAAI,KAAK;AACT,MAAI,KAAK;AACT,aAAW,SAAS,QAAQ;AACxB,UAAM,KAAK,MAAM,IAAI;AACrB,UAAM,KAAK,MAAM,IAAI;AACrB,UAAM,KAAK;AACX,UAAM,KAAK;AACX,UAAM,KAAK;AAAA,EACf;AACA,MAAI,KAAK,IAAI,KAAK,EAAE,IAAI,KAAK,IAAI,EAAE,IAAI,KAAO,QAAO;AACrD,SAAO,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,IAAI;AACzC;AAEA,SAAS,eAAe,QAAQ;AAC5B,MAAI,IAAI;AACR,MAAI,IAAI;AACR,WAAS,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;AACnD,UAAM,KAAK,OAAO,KAAK,EAAE,IAAI,OAAO,QAAQ,CAAC,EAAE;AAC/C,UAAM,KAAK,OAAO,KAAK,EAAE,IAAI,OAAO,QAAQ,CAAC,EAAE;AAC/C,UAAM,SAAS,KAAK,MAAM,IAAI,EAAE;AAChC,QAAI,WAAW,EAAG;AAClB,UAAM,QAAQ,KAAK,MAAM,IAAI,EAAE,IAAI;AACnC,SAAK,KAAK,IAAI,KAAK,IAAI;AACvB,SAAK,KAAK,IAAI,KAAK,IAAI;AAAA,EAC3B;AACA,SAAO,KAAK,MAAM,GAAG,CAAC,IAAI;AAC9B;AAEA,SAAS,sBAAsB,QAAQ,YAAY;AAC/C,QAAM,aAAa,eAAe,QAAQ,eAAe,MAAM,CAAC;AAChE,QAAM,gBAAgB,eAAe,QAAQ,eAAe,MAAM,CAAC;AACnE,MAAI,iBAAiB;AACrB,MAAI,eAAe;AAEnB,QAAM,UAAU,KAAK,IAAI,WAAW,KAAK;AACzC,QAAM,UAAU,KAAK,IAAI,WAAW,KAAK;AACzC,QAAM,aAAa,KAAK,IAAI,cAAc,KAAK;AAC/C,QAAM,aAAa,KAAK,IAAI,cAAc,KAAK;AAC/C,QAAM,YAAY,WAAW,QAAQ;AACrC,QAAM,YAAY,WAAW,SAAS;AACtC,QAAM,eAAe,cAAc,QAAQ;AAC3C,QAAM,eAAe,cAAc,SAAS;AAE5C,aAAW,SAAS,QAAQ;AACxB,UAAM,SAAS,MAAM,IAAI,WAAW,OAAO;AAC3C,UAAM,SAAS,MAAM,IAAI,WAAW,OAAO;AAC3C,UAAM,QAAQ,KAAK,IAAI,SAAS,UAAU,SAAS,OAAO,IAAI;AAC9D,UAAM,QAAQ,KAAK,IAAI,CAAC,SAAS,UAAU,SAAS,OAAO,IAAI;AAC/D,sBAAkB,KAAK,IAAI,KAAK,IAAI,IAAI,KAAK,GAAG,KAAK,IAAI,IAAI,KAAK,CAAC;AAEnE,UAAM,YAAY,MAAM,IAAI,cAAc,OAAO;AACjD,UAAM,YAAY,MAAM,IAAI,cAAc,OAAO;AACjD,UAAM,YAAY,YAAY,aAAa,YAAY,cAAc;AACrE,UAAM,YAAY,CAAC,YAAY,aAAa,YAAY,cAAc;AACtE,oBAAgB,KAAK,IAAI,IAAI,KAAK,MAAM,UAAU,QAAQ,CAAC;AAAA,EAC/D;AAEA,oBAAkB,OAAO;AACzB,kBAAgB,OAAO;AACvB,QAAM,YAAY,kBAAkB,eAAe;AACnD,QAAM,YAAY,YAAY,iBAAiB;AAC/C,MAAI,YAAY,MAAM;AAClB,WAAO,EAAE,MAAM,YAAY,QAAQ,OAAO,IAAI,CAAC,WAAW,EAAE,GAAG,MAAM,EAAE,GAAG,WAAW;AAAA,EACzF;AACA,QAAM,SAAS,YAAY,aAAa;AACxC,SAAO;AAAA,IACH,MAAM,YAAY,cAAc;AAAA,IAChC,GAAG;AAAA,IACH;AAAA,EACJ;AACJ;AAEO,SAAS,kBAAkB,QAAQ;AACtC,MAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,OAAO,SAAS,EAAG,QAAO;AACxD,QAAMA,SAAQ,OAAO,CAAC;AACtB,MAAI,aAAa;AACjB,MAAI,gBAAgB;AACpB,MAAI,mBAAmB;AACvB,MAAI,OAAOA,OAAM;AACjB,MAAI,OAAOA,OAAM;AACjB,MAAI,OAAOA,OAAM;AACjB,MAAI,OAAOA,OAAM;AAEjB,WAAS,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;AACnD,kBAAc,SAAS,OAAO,QAAQ,CAAC,GAAG,OAAO,KAAK,CAAC;AACvD,UAAM,YAAY,SAASA,QAAO,OAAO,KAAK,CAAC;AAC/C,QAAI,YAAY,kBAAkB;AAC9B,yBAAmB;AACnB,sBAAgB;AAAA,IACpB;AACA,WAAO,KAAK,IAAI,MAAM,OAAO,KAAK,EAAE,CAAC;AACrC,WAAO,KAAK,IAAI,MAAM,OAAO,KAAK,EAAE,CAAC;AACrC,WAAO,KAAK,IAAI,MAAM,OAAO,KAAK,EAAE,CAAC;AACrC,WAAO,KAAK,IAAI,MAAM,OAAO,KAAK,EAAE,CAAC;AAAA,EACzC;AAEA,QAAM,WAAW,KAAK,IAAI,gBAAgB,KAAK,MAAM,OAAO,MAAM,OAAO,IAAI,CAAC;AAC9E,QAAM,MAAM,OAAO,OAAO,SAAS,CAAC;AACpC,QAAM,SAAS,OAAO,UAAU,KAAK,SAASA,QAAO,GAAG,KAAK,WAAW,QAAQ,cAAc,WAAW;AACzG,MAAI,OAAQ,QAAO,sBAAsB,QAAQ,UAAU;AAE3D,QAAM,MAAM,OAAO,aAAa;AAChC,MAAI,iBAAiB;AACrB,WAAS,QAAQ,gBAAgB,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;AACnE,sBAAkB,SAAS,OAAO,QAAQ,CAAC,GAAG,OAAO,KAAK,CAAC;AAAA,EAC/D;AACA,MAAI,cAAc;AAClB,WAAS,QAAQ,GAAG,SAAS,eAAe,SAAS,GAAG;AACpD,mBAAe,SAAS,OAAO,QAAQ,CAAC,GAAG,OAAO,KAAK,CAAC;AAAA,EAC5D;AACA,QAAM,QAAQ,iBAAiB,KAAK,MAAM,OAAO,SAAS,IAAI,KACvD,gBAAgB,OAAO,SAAS,KAChC,kBAAkB,WAAW,QAC7B,SAAS,KAAK,GAAG,KAAK,WAAW,QACjC,mBAAmB,KAAK,IAAI,aAAa,CAAC,KAAK;AAEtD,QAAM,iBAAiB,SAASA,QAAO,GAAG;AAC1C,QAAM,OAAO,CAAC,SAAS,iBAAiB,KAAK,IAAI,YAAY,CAAC,KAAK;AAEnE,MAAI,CAAC,SAAS,CAAC,MAAM;AACjB,WAAO,EAAE,MAAM,YAAY,QAAQ,OAAO,IAAI,CAAC,WAAW,EAAE,GAAG,MAAM,EAAE,GAAG,WAAW;AAAA,EACzF;AAEA,SAAO;AAAA,IACH,MAAM,QAAQ,UAAU;AAAA,IACxB,OAAO,EAAE,GAAGA,OAAM;AAAA,IAClB,KAAK,QAAQ,EAAE,GAAG,IAAI,IAAI,EAAE,GAAG,IAAI;AAAA,IACnC,OAAO,KAAK,IAAI,gBAAgB,OAAO,IAAI;AAAA,IAC3C,QAAQ,KAAK,IAAI,gBAAgB,OAAO,IAAI;AAAA,IAC5C;AAAA,EACJ;AACJ;AAEA,SAAS,aAAa,QAAQ,GAAG,GAAG,OAAO;AACvC,QAAM,MAAM,KAAK,IAAI,KAAK;AAC1B,QAAM,MAAM,KAAK,IAAI,KAAK;AAC1B,SAAO,EAAE,GAAG,OAAO,IAAI,IAAI,MAAM,IAAI,KAAK,GAAG,OAAO,IAAI,IAAI,MAAM,IAAI,IAAI;AAC9E;AAEA,SAAS,kBAAkB,YAAY;AACnC,MAAI,CAAC,WAAY,QAAO;AACxB,MAAI,WAAW,SAAS,aAAa;AACjC,UAAM,QAAQ,WAAW,QAAQ;AACjC,UAAM,QAAQ,WAAW,SAAS;AAClC,UAAM,UAAU;AAAA,MACZ,aAAa,WAAW,QAAQ,CAAC,OAAO,CAAC,OAAO,WAAW,KAAK;AAAA,MAChE,aAAa,WAAW,QAAQ,OAAO,CAAC,OAAO,WAAW,KAAK;AAAA,MAC/D,aAAa,WAAW,QAAQ,OAAO,OAAO,WAAW,KAAK;AAAA,MAC9D,aAAa,WAAW,QAAQ,CAAC,OAAO,OAAO,WAAW,KAAK;AAAA,IACnE;AACA,WAAO,KAAK,QAAQ,CAAC,EAAE,CAAC,IAAI,QAAQ,CAAC,EAAE,CAAC,MAAM,QAAQ,CAAC,EAAE,CAAC,IAAI,QAAQ,CAAC,EAAE,CAAC,MAAM,QAAQ,CAAC,EAAE,CAAC,IAAI,QAAQ,CAAC,EAAE,CAAC,MAAM,QAAQ,CAAC,EAAE,CAAC,IAAI,QAAQ,CAAC,EAAE,CAAC;AAAA,EAClJ;AACA,MAAI,WAAW,SAAS,UAAU;AAC9B,UAAM,KAAK,WAAW,QAAQ;AAC9B,UAAM,KAAK,WAAW,SAAS;AAC/B,UAAMA,SAAQ,aAAa,WAAW,QAAQ,IAAI,GAAG,WAAW,KAAK;AACrE,UAAM,WAAW,aAAa,WAAW,QAAQ,CAAC,IAAI,GAAG,WAAW,KAAK;AACzE,UAAM,WAAW,WAAW,QAAQ,MAAM,KAAK;AAC/C,WAAO,KAAKA,OAAM,CAAC,IAAIA,OAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,QAAQ,QAAQ,SAAS,CAAC,IAAI,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,QAAQ,QAAQA,OAAM,CAAC,IAAIA,OAAM,CAAC;AAAA,EAChJ;AACA,MAAI,WAAW,SAAS,YAAY;AAChC,QAAI,CAAC,WAAW,OAAO,OAAQ,QAAO;AACtC,WAAO,WAAW,OAAO,OAAO,CAACC,OAAM,OAAO,UAAU,GAAGA,KAAI,GAAG,UAAU,IAAI,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE;AAAA,EAC1H;AACA,QAAM,EAAE,OAAAD,QAAO,IAAI,IAAI;AACvB,MAAI,OAAO,KAAKA,OAAM,CAAC,IAAIA,OAAM,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC;AACtD,MAAI,WAAW,SAAS,SAAS;AAC7B,UAAM,QAAQ,KAAK,MAAM,IAAI,IAAIA,OAAM,GAAG,IAAI,IAAIA,OAAM,CAAC;AACzD,UAAM,OAAO,KAAK,IAAI,MAAM,OAAO,eAAe,IAAI,SAASA,QAAO,GAAG,IAAI,IAAI;AACjF,UAAM,OAAO,aAAa,KAAK,CAAC,MAAM,OAAO,MAAM,KAAK;AACxD,UAAM,QAAQ,aAAa,KAAK,CAAC,MAAM,CAAC,OAAO,MAAM,KAAK;AAC1D,YAAQ,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,MAAM,CAAC,IAAI,MAAM,CAAC;AAAA,EAC9E;AACA,SAAO;AACX;AAEA,SAAS,gBAAgB;AACrB,MAAI,aAAa,YAAa;AAC9B,gBAAc,SAAS,gBAAgB,QAAQ,MAAM;AACrD,cAAY,QAAQ,qBAAqB;AACzC,cAAY,aAAa,QAAQ,2BAA2B;AAC5D,cAAY,aAAa,UAAU,SAAS;AAC5C,cAAY,aAAa,gBAAgB,GAAG;AAC5C,cAAY,aAAa,oBAAoB,KAAK;AAClD,cAAY,aAAa,kBAAkB,OAAO;AAClD,cAAY,aAAa,mBAAmB,OAAO;AACnD,cAAY,aAAa,iBAAiB,oBAAoB;AAC9D,cAAY,aAAa,kBAAkB,MAAM;AACjD,MAAI,YAAY,WAAW;AAC/B;AAEA,SAAS,gBAAgB;AACrB,iBAAe;AACf,MAAI,CAAC,QAAS;AACd,qBAAmB,kBAAkB,MAAM;AAC3C,gBAAc;AACd,cAAY,aAAa,KAAK,kBAAkB,gBAAgB,CAAC;AACjE,cAAY,aAAa,QAAQ,kBAAkB,SAAS,eAAe,kBAAkB,SAAS,WAChG,8BACA,MAAM;AAChB;AAEA,SAAS,kBAAkB;AACvB,MAAI,CAAC,aAAc,gBAAe,sBAAsB,aAAa;AACzE;AAEA,SAAS,iBAAiB;AACtB,MAAI,aAAc,sBAAqB,YAAY;AACnD,iBAAe;AACf,eAAa,OAAO;AACpB,gBAAc;AAClB;AAEA,SAAS,eAAe;AACpB,QAAM,WAAW,OAAO,wBAAwB,CAAC;AACjD,QAAM,UAAU,SAAS,eAAe;AACxC,SAAO;AAAA,IACH,QAAQ,SAAS,eAAe,eAAe;AAAA,IAC/C,MAAM;AAAA,IACN,WAAW;AAAA,IACX,aAAa,SAAS,eAAe;AAAA,IACrC,iBAAiB,YAAY,WAAW,UAAW,YAAY,WAAW,QAAQ;AAAA,IAClF;AAAA,EACJ;AACJ;AAEA,SAAS,wBAAwB,OAAO;AACpC,WAAS,QAAQ,OAAO,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;AACxD,UAAME,SAAQ,OAAO,KAAK;AAC1B,QAAIA,OAAM,cAAc,WAAW,OAAOA,OAAM,mBAAmB,WAAY;AAC/E,QAAI,CAACA,OAAM,eAAe,KAAK,EAAG;AAClC,IAAAA,OAAM,gBAAgB,KAAK;AAC3B,8BAA0BA,QAAO,OAAO,UAAU,IAAI;AACtD;AAAA,EACJ;AACJ;AAEA,SAAS,qBAAqB,YAAY;AACtC,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,QAAQ,aAAa;AAC3B,MAAI,QAAQ;AACZ,MAAI,WAAW,SAAS,aAAa;AACjC,YAAQ,IAAI,OAAO;AAAA,MACf,WAAW,OAAO,IAAI,WAAW,QAAQ;AAAA,MACzC,WAAW,OAAO,IAAI,WAAW,SAAS;AAAA,MAC1C,WAAW;AAAA,MACX,WAAW;AAAA,MACX;AAAA,IACJ;AACA,UAAM,WAAW,WAAW,QAAQ,MAAM,KAAK;AAC/C,UAAM,KAAK;AAAA,EACf,WAAW,WAAW,SAAS,UAAU;AACrC,YAAQ,IAAI,OAAO;AAAA,MACf,WAAW,OAAO;AAAA,MAClB,WAAW,OAAO;AAAA,MAClB,WAAW,QAAQ;AAAA,MACnB,WAAW,SAAS;AAAA,MACpB;AAAA,IACJ;AACA,UAAM,WAAW,WAAW,QAAQ,MAAM,KAAK;AAC/C,UAAM,KAAK;AAAA,EACf,WAAW,WAAW,SAAS,YAAY;AACvC,UAAM,QAAQ,OAAO,wBAAwB,CAAC;AAC9C,YAAQ,IAAI,OAAO;AAAA,MACf,WAAW,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,MAAM,GAAG,MAAM,YAAY,GAAG,CAAC;AAAA,MAC1E;AAAA,QACI,QAAQ,MAAM;AAAA,QACd,aAAa,MAAM;AAAA,QACnB,aAAa,MAAM;AAAA,QACnB,UAAU,MAAM,YAAY;AAAA,QAC5B,WAAW,MAAM,aAAa;AAAA,QAC9B,eAAe,MAAM,WAAW;AAAA,MACpC;AAAA,IACJ;AAAA,EACJ,WAAW,WAAW,SAAS,SAAS;AACpC,YAAQ,IAAI,OAAO,MAAM,WAAW,OAAO,WAAW,KAAK;AAAA,MACvD,QAAQ,MAAM;AAAA,MACd,aAAa,MAAM;AAAA,MACnB,mBAAmB,MAAM;AAAA,MACzB,aAAa;AAAA,IACjB,CAAC;AAAA,EACL,OAAO;AACH,YAAQ,IAAI,OAAO,KAAK,WAAW,OAAO,WAAW,KAAK;AAAA,MACtD,QAAQ,MAAM;AAAA,MACd,aAAa,MAAM;AAAA,MACnB,iBAAiB,MAAM;AAAA,MACvB,WAAW;AAAA,MACX,QAAQ;AAAA,IACZ,CAAC;AAAA,EACL;AACA,SAAO,KAAK,KAAK;AACjB,mBAAiB,KAAK;AACtB,0BAAwB,KAAK;AAC7B,SAAO;AACX;AAEO,SAAS,2BAA2B,OAAO;AAC9C,MAAI,CAAC,OAAO,gCAAgC,MAAM,WAAW,EAAG;AAChE,YAAU;AACV,WAAS,CAAC,YAAY,KAAK,CAAC;AAC5B,qBAAmB;AACnB,gBAAc;AACd,kBAAgB;AACpB;AAEO,SAAS,2BAA2B,OAAO;AAC9C,MAAI,CAAC,WAAW,CAAC,OAAO,6BAA8B;AACtD,QAAM,QAAQ,YAAY,KAAK;AAC/B,QAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AACrC,QAAM,YAAY,wBAAwB,OAAO,eAAe;AAChE,MAAI,SAAS,MAAM,KAAK,IAAI,UAAW;AACvC,MAAI,OAAO,SAAS,YAAY;AAC5B,WAAO,KAAK,KAAK;AAAA,EACrB,OAAO;AAGH,aAAS,CAAC,OAAO,CAAC,GAAG,GAAG,OAAO,MAAM,CAAC,EAAE,OAAO,CAAC,GAAG,UAAU,QAAQ,MAAM,CAAC,GAAG,KAAK;AAAA,EACxF;AACA,kBAAgB;AACpB;AAEO,SAAS,yBAAyB,OAAO;AAC5C,MAAI,CAAC,QAAS;AACd,YAAU;AACV,QAAM,OAAO,IAAI,sBAAsB;AACvC,MAAI,MAAM,WAAW,KAAK,QAAQ,MAAM,WAAW,KAAK,SAAS,MAAM,WAAW,KAAK,OAAO,MAAM,WAAW,KAAK,QAAQ;AACxH,UAAM,QAAQ,YAAY,KAAK;AAC/B,QAAI,SAAS,OAAO,OAAO,SAAS,CAAC,GAAG,KAAK,IAAI,EAAG,QAAO,KAAK,KAAK;AAAA,EACzE;AACA,qBAAmB,kBAAkB,MAAM;AAC3C,iBAAe;AAEf,QAAM,aAAa;AACnB,WAAS,CAAC;AACV,qBAAmB;AACnB,MAAI,CAAC,cAAc,WAAW,aAAa,eAAgB;AAE3D,QAAM,QAAQ,qBAAqB,UAAU;AAC7C,MAAI,CAAC,MAAO;AACZ,MAAI,OAAO,iBAAkB,QAAO,iBAAiB,cAAc,UAAU,EAAE,WAAW,KAAK,CAAC;AAChG,iBAAe;AACf,MAAI,MAAM,cAAc,oBAAoB,OAAO,MAAM,iBAAiB,YAAY;AAClF,UAAM,aAAa;AAAA,EACvB,OAAO;AACH,UAAM,aAAa;AACnB,QAAI,OAAO,MAAM,eAAe,WAAY,OAAM,WAAW;AAAA,EACjE;AACJ;AAEO,SAAS,yBAAyB;AACrC,YAAU;AACV,WAAS,CAAC;AACV,qBAAmB;AACnB,iBAAe;AACnB;AAEA,OAAO,2BAA2B;;;AC3alC,IAAM,gBAAgB,oBAAI,IAAI,CAAC,aAAa,QAAQ,CAAC;AAErD,OAAO,sBAAsB,OAAO,uBAAuB;AAAA,EACvD,WAAW;AAAA,EACX,WAAW;AACf;AAEA,SAASC,aAAY,OAAO;AACxB,QAAM,UAAU,IAAI,QAAQ;AAC5B,QAAM,OAAO,IAAI,sBAAsB;AACvC,SAAO;AAAA,IACH,GAAG,QAAQ,KAAM,MAAM,UAAU,KAAK,QAAQ,KAAK,QAAS,QAAQ;AAAA,IACpE,GAAG,QAAQ,KAAM,MAAM,UAAU,KAAK,OAAO,KAAK,SAAU,QAAQ;AAAA,EACxE;AACJ;AAEA,SAAS,kBAAkB,GAAG,GAAG;AAC7B,WAAS,QAAQ,OAAO,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;AACxD,UAAM,QAAQ,OAAO,KAAK;AAC1B,QAAI,CAAC,cAAc,IAAI,OAAO,SAAS,KAAK,OAAO,MAAM,aAAa,WAAY;AAClF,QAAI,MAAM,SAAS,GAAG,CAAC,EAAG,QAAO;AAAA,EACrC;AACA,SAAO;AACX;AAEO,SAAS,sBAAsB,OAAO;AACzC,MAAI,CAAC,OAAO,2BAA2B,MAAM,WAAW,EAAG;AAC3D,QAAM,EAAE,GAAG,EAAE,IAAIA,aAAY,KAAK;AAClC,QAAM,QAAQ,kBAAkB,GAAG,CAAC;AACpC,MAAI,CAAC,OAAO;AACR,WAAO,cAAc,IAAI,YAAY,uBAAuB,CAAC;AAC7D;AAAA,EACJ;AAEA,QAAM,WAAW,OAAO;AACxB,QAAM,cAAc,SAAS,cAAc,UAAU,SAAS,cAAc;AAC5E,QAAM,WAAW,cAAc,gBAAgB,SAAS;AACxD,QAAM,YAAY,cAAc,SAAS,SAAS;AAClD,MAAI,MAAM,QAAQ,SAAS,YAAY,MAAM,QAAQ,cAAc,UAAW;AAE9E,QAAM,aAAa,EAAE,GAAG,MAAM,QAAQ;AACtC,QAAM,aAAa,EAAE,GAAG,MAAM,SAAS,MAAM,UAAU,WAAW,UAAU;AAC5E,0BAAwB,OAAO,YAAY,UAAU;AACrD,QAAM,UAAU;AAChB,QAAM,KAAK;AACX,SAAO,cAAc,IAAI,YAAY,2BAA2B,EAAE,QAAQ,EAAE,SAAS,MAAM,QAAQ,EAAE,CAAC,CAAC;AAC3G;;;AC7CA,IAAMC,cAAa;AACnB,IAAM,gBAAgB;AACtB,IAAIC,UAAS,CAAC;AACd,IAAI,UAAU;AACd,IAAIC,WAAU;AAEd,SAAS,OAAO,GAAG;AACf,QAAM,KAAK,IAAI,QAAQ;AACvB,QAAM,OAAO,IAAI,sBAAsB;AACvC,SAAO,EAAE,GAAG,GAAG,KAAM,EAAE,UAAU,KAAK,QAAQ,KAAK,QAAS,GAAG,OAAO,GAAG,GAAG,KAAM,EAAE,UAAU,KAAK,OAAO,KAAK,SAAU,GAAG,OAAO;AACvI;AAEA,SAAS,eAAe,OAAO,SAAS;AACpC,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,GAAG,IAAI,QAAQ,QAAQ,IAAI,KAAK;AACjE,UAAM,IAAI,QAAQ,CAAC,GAAG,IAAI,QAAQ,CAAC;AACnC,QAAM,EAAE,IAAI,MAAM,MAAQ,EAAE,IAAI,MAAM,KAAO,MAAM,KAAM,EAAE,IAAI,EAAE,MAAM,MAAM,IAAI,EAAE,MAAQ,EAAE,IAAI,EAAE,KAAM,OAAO,WAAW,EAAE,EAAG,UAAS,CAAC;AAAA,EAC9I;AACA,SAAO;AACX;AAEA,SAAS,aAAa,OAAO;AACzB,OAAK,MAAM,cAAc,UAAU,MAAM,cAAc,YAAY,MAAM,cAAc,MAAM,SAAU,QAAO,CAAC,MAAM,YAAY,MAAM,QAAQ;AAC/I,MAAI,MAAM,cAAc,oBAAoB,MAAM,QAAQ,MAAM,MAAM,GAAG;AACrE,UAAM,OAAO,KAAK,IAAI,GAAG,KAAK,KAAK,MAAM,OAAO,SAAS,EAAE,CAAC;AAC5D,WAAO,MAAM,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,SAAS,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE;AAAA,EAC1F;AACA,MAAI,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,QAAQ,MAAM,SAAS,GAAG,SAAS,MAAM,UAAU;AAC3F,MAAI,MAAM,cAAc,UAAU;AAAE,QAAI,MAAM,IAAI,MAAM;AAAI,QAAI,MAAM,IAAI,MAAM;AAAI,YAAQ,MAAM,KAAK;AAAG,aAAS,MAAM,KAAK;AAAA,EAAG;AACjI,OAAK,CAAC,SAAS,CAAC,WAAW,MAAM,OAAO,SAAS;AAC7C,QAAI;AAAE,YAAM,MAAM,MAAM,MAAM,QAAQ;AAAG,UAAI,IAAI;AAAG,UAAI,IAAI;AAAG,cAAQ,IAAI;AAAO,eAAS,IAAI;AAAA,IAAQ,QAAQ;AAAA,IAAC;AAAA,EACpH;AACA,QAAM,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,OAAO,GAAG,IAAI,OAAO,GAAG,EAAE,GAAG,GAAG,IAAI,OAAO,GAAG,EAAE,GAAG,IAAI,QAAQ,GAAG,GAAG,IAAI,SAAS,EAAE,CAAC;AAC1I,QAAM,WAAW,OAAO,MAAM,QAAQ,KAAK;AAC3C,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,KAAK,IAAI,QAAQ,GAAG,KAAK,IAAI,SAAS,GAAG,QAAQ,WAAW,KAAK,KAAK;AAC5E,SAAO,IAAI,IAAI,CAAC,OAAO,EAAE,GAAG,MAAM,EAAE,IAAI,MAAM,KAAK,IAAI,KAAK,KAAK,EAAE,IAAI,MAAM,KAAK,IAAI,KAAK,GAAG,GAAG,MAAM,EAAE,IAAI,MAAM,KAAK,IAAI,KAAK,KAAK,EAAE,IAAI,MAAM,KAAK,IAAI,KAAK,EAAE,EAAE;AACxK;AAEA,SAAS,UAAU;AACf,WAAS,OAAO;AAAG,YAAU;AAAM,EAAAD,UAAS,CAAC;AAAG,EAAAC,WAAU;AAC9D;AAEO,SAAS,gBAAgB,GAAG;AAC/B,MAAI,CAAC,OAAO,kBAAmB;AAC/B,UAAQ;AAAG,iBAAe,eAAe;AAAG,EAAAA,WAAU;AAAM,EAAAD,UAAS,CAAC,OAAO,CAAC,CAAC;AAC/E,YAAU,SAAS,gBAAgB,8BAA8B,MAAM;AACvE,UAAQ,aAAa,QAAQ,0BAA0B;AAAG,UAAQ,aAAa,UAAU,SAAS;AAClG,UAAQ,aAAa,oBAAoB,KAAK;AAAG,UAAQ,aAAa,iBAAiB,oBAAoB;AAC3G,UAAQ,MAAM,gBAAgB;AAAQ,MAAI,YAAY,OAAO;AACjE;AAEO,SAAS,gBAAgB,GAAG;AAC/B,MAAI,CAACC,SAAS;AACd,QAAM,IAAI,OAAO,CAAC,GAAG,OAAOD,QAAOA,QAAO,SAAS,CAAC;AACpD,QAAM,MAAM,iBAAiB,OAAO,eAAe;AACnD,MAAI,KAAK,MAAM,EAAE,IAAI,KAAK,GAAG,EAAE,IAAI,KAAK,CAAC,IAAI,IAAK;AAClD,MAAIA,QAAO,SAASD,YAAY,CAAAC,QAAO,KAAK,CAAC;AAAA,MAAQ,CAAAA,QAAOA,QAAO,SAAS,CAAC,IAAI;AACjF,WAAS,aAAa,KAAK,KAAKA,QAAO,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,KAAK,KAAK,CAAC,IAAI;AACtF;AAEO,SAAS,gBAAgB;AAC5B,MAAI,CAACC,SAAS;AACd,QAAM,UAAUD,QAAO,MAAM;AAAG,UAAQ;AAGxC,SAAO,kBAAkB,cAAc,UAAU,EAAE,WAAW,KAAK,CAAC;AACpE,MAAI,QAAQ,UAAU,KAAK,MAAM,QAAQ,OAAO,MAAM,GAAG;AACrD,UAAM,WAAW,OAAO,OAAO,OAAO,CAAC,UAAU,aAAa,KAAK,EAAE,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC,CAAC;AAC7G,UAAM,WAAW,SAAS,OAAO,CAAC,UAAU,CAAC,MAAM,eAAe,CAAC,SAAS,SAAS,MAAM,WAAW,CAAC;AAGvG,aAAS,QAAQ,CAAC,UAAU;AAAE,qBAAe,eAAe,IAAI,KAAK;AAAG,YAAM,aAAa;AAAA,IAAM,CAAC;AAClG,QAAI,SAAS,OAAQ,gBAAe,eAAe;AACnD,WAAO,eAAe,SAAS,WAAW,IAAI,SAAS,CAAC,IAAI;AAAA,EAChE;AACJ;AAEO,SAAS,cAAc;AAAE,UAAQ;AAAG;AAC3C,OAAO,gBAAgB;;;AC7EvB,IAAI,QAAQ;AAAZ,IAAkB,QAAQ;AAC1B,SAASE,QAAO,GAAG;AACf,QAAM,KAAK,IAAI,QAAQ,SAAS,OAAO,IAAI,sBAAsB;AACjE,SAAO,EAAE,GAAG,GAAG,KAAM,EAAE,UAAU,KAAK,QAAQ,KAAK,QAAS,GAAG,OAAO,GAAG,GAAG,KAAM,EAAE,UAAU,KAAK,OAAO,KAAK,SAAU,GAAG,OAAO;AACvI;AAEO,SAAS,cAAc,UAAU;AACpC,QAAM,MAAM,qBAAqB,QAAQ;AACzC,MAAI,CAAC,OAAO,OAAO,QAAQ,YAAa,QAAO;AAI/C,SAAO,kBAAkB,cAAc,QAAQ;AAC/C,QAAM,UAAU,IAAI,QAAQ;AAC5B,QAAM,QAAQ,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,QAAQ,QAAQ,IAAI,CAAC;AAC/D,QAAM,SAAS,QAAQ,IAAI;AAC3B,QAAM,IAAI,QAAQ,KAAK,QAAQ,QAAQ,SAAS;AAChD,QAAM,IAAI,QAAQ,KAAK,QAAQ,SAAS,UAAU;AAClD,QAAM,cAAc,IAAI,MAAM,GAAG,GAAG,OAAO,QAAQ;AAAA,IAC/C,WAAW;AAAA,IAAa,WAAW;AAAA,IAAa,aAAa;AAAA,IAC7D,QAAQ;AAAA,IAAW,aAAa;AAAA,EACpC,CAAC;AACD,SAAO,KAAK,WAAW;AACvB,mBAAiB,WAAW;AAC5B,iBAAe;AACf,cAAY,YAAY;AACxB,SAAO,uBAAuB;AAC9B,SAAO;AACX;AAEO,SAAS,mBAAmB,GAAG;AAClC,QAAM,MAAM,qBAAqB,OAAO,oBAAoB;AAC5D,MAAI,CAAC,OAAO,wBAAwB,CAAC,KAAK;AAAE,WAAO,sBAAsB;AAAG;AAAA,EAAQ;AACpF,UAAQA,QAAO,CAAC;AAChB,UAAQ,IAAI,MAAM,MAAM,GAAG,MAAM,GAAG,GAAG,GAAG,EAAE,WAAW,aAAa,WAAW,aAAa,aAAa,KAAK,QAAQ,WAAW,aAAa,EAAE,CAAC;AACjJ,SAAO,KAAK,KAAK;AAAG,iBAAe;AACvC;AAEO,SAAS,mBAAmB,GAAG;AAClC,MAAI,CAAC,SAAS,CAAC,MAAO;AACtB,QAAM,IAAIA,QAAO,CAAC;AAAG,QAAM,IAAI,KAAK,IAAI,MAAM,GAAG,EAAE,CAAC;AAAG,QAAM,IAAI,KAAK,IAAI,MAAM,GAAG,EAAE,CAAC;AACtF,QAAM,QAAQ,KAAK,IAAI,EAAE,IAAI,MAAM,CAAC;AAAG,QAAM,SAAS,KAAK,IAAI,EAAE,IAAI,MAAM,CAAC;AAAG,QAAM,KAAK;AAC9F;AAEO,SAAS,mBAAmB;AAC/B,MAAI,CAAC,MAAO;AACZ,MAAI,MAAM,QAAQ,MAAM,MAAM,SAAS,IAAI;AAAE,UAAM,QAAQ;AAAK,UAAM,SAAS;AAAA,EAAK;AACpF,QAAM,KAAK;AAAG,mBAAiB,KAAK;AACpC,QAAM,cAAc;AACpB,SAAO,uBAAuB;AAAM,UAAQ;AAAM,UAAQ;AAC1D,SAAO,kBAAkB,cAAc,UAAU,EAAE,WAAW,KAAK,CAAC;AACpE,iBAAe;AAAa,cAAY,YAAY;AACxD;AAEA,OAAO,kBAAkB;;;ACvCzB,IAAM,iBAAiB;AACvB,IAAM,eAAe;AACrB,IAAI,iBAAiB;AAErB,SAAS,YAAY,GAAG;AACpB,MAAI,EAAE,EAAE,UAAU,IAAI;AAAE,oBAAgB;AAAG;AAAA,EAAQ;AACnD,MAAI,OAAO,mBAAmB,eAAe,OAAO,gBAAgB,YAAa;AACjF,MAAI,OAAO,cAAc,eAAe,UAAW;AACnD,MAAI,OAAO,wBAAwB,eAAe,oBAAqB;AAEvE,QAAM,OAAO,IAAI,sBAAsB;AACvC,QAAM,KAAK,EAAE,UAAU,KAAK;AAC5B,QAAM,KAAK,EAAE,UAAU,KAAK;AAE5B,MAAI,KAAK,GAAG,KAAK;AACjB,MAAI,KAAK,eAAgB,MAAK,CAAC,gBAAgB,IAAI,KAAK;AAAA,WAC/C,KAAK,KAAK,QAAQ,eAAgB,MAAK,gBAAgB,KAAK,KAAK,QAAQ,MAAM;AACxF,MAAI,KAAK,eAAgB,MAAK,CAAC,gBAAgB,IAAI,KAAK;AAAA,WAC/C,KAAK,KAAK,SAAS,eAAgB,MAAK,gBAAgB,KAAK,KAAK,SAAS,MAAM;AAG1F,MAAI,EAAE,UAAU,KAAK,KAAM,MAAK,CAAC;AAAA,WACxB,EAAE,UAAU,KAAK,MAAO,MAAK;AACtC,MAAI,EAAE,UAAU,KAAK,IAAK,MAAK,CAAC;AAAA,WACvB,EAAE,UAAU,KAAK,OAAQ,MAAK;AAEvC,MAAI,OAAO,KAAK,OAAO,GAAG;AAAE,oBAAgB;AAAG;AAAA,EAAQ;AAGvD,QAAM,QAAQ,IAAI;AAClB,iBAAe,KAAK,KAAK;AACzB,iBAAe,KAAK,KAAK;AACzB,MAAI,aAAa,WAAW,GAAG,eAAe,CAAC,IAAI,eAAe,CAAC,IAAI,eAAe,KAAK,IAAI,eAAe,MAAM,EAAE;AACtH,MAAI,OAAO,mBAAmB,eAAe,mBAAmB,KAAK;AACjE,mBAAe,aAAa,WAAW,GAAG,eAAe,CAAC,IAAI,eAAe,CAAC,IAAI,eAAe,KAAK,IAAI,eAAe,MAAM,EAAE;AAAA,EACrI;AACJ;AAEA,SAAS,mBAAmB;AACxB,MAAI,eAAgB;AACpB,QAAM,OAAO,MAAM;AACf,QAAI,eAAgB,aAAY,cAAc;AAC9C,qBAAiB,sBAAsB,IAAI;AAAA,EAC/C;AACA,mBAAiB,sBAAsB,IAAI;AAC/C;AAEA,SAAS,kBAAkB;AACvB,MAAI,gBAAgB;AAChB,yBAAqB,cAAc;AACnC,qBAAiB;AAAA,EACrB;AACA,mBAAiB;AACrB;AAEA,IAAI,iBAAiB;AACrB,IAAI,sBAAsB;AAE1B,SAAS,oBAAoB,GAAG;AAC5B,mBAAiB;AAGjB,QAAM,OAAO,IAAI,sBAAsB;AACvC,QAAM,WAAW,KAAK,IAAI,KAAK,MAAM,KAAK,IAAI,KAAK,OAAO,EAAE,OAAO,CAAC;AACpE,QAAM,WAAW,KAAK,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,QAAQ,EAAE,OAAO,CAAC;AACpE,QAAM,eAAe,IAAI,aAAa,EAAE,MAAM;AAAA,IAC1C,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS,EAAE;AAAA,IACX,QAAQ,EAAE;AAAA,IACV,SAAS,EAAE;AAAA,IACX,UAAU,EAAE;AAAA,IACZ,QAAQ,EAAE;AAAA,IACV,SAAS,EAAE;AAAA,EACf,CAAC;AACD,sBAAoB,YAAY;AACpC;AAEA,SAAS,kBAAkB,GAAG;AAC1B,kBAAgB;AAChB,WAAS,oBAAoB,eAAe,mBAAmB;AAC/D,WAAS,oBAAoB,aAAa,iBAAiB;AAC3D,wBAAsB;AAEtB,oBAAkB,CAAC;AACvB;AAEA,IAAM,sBAAsB,CAAC,MAAM;AAC/B,MAAI,CAAC,EAAE,OAAQ;AAMf,MAAI,EAAE,WAAW,KAAK,EAAE,WAAW,KAAK,OAAO,iBAAkB;AAEjE,2BAAyB;AAIzB,MAAI,CAAC,uBAAuB;AAExB,QAAI,eAAe,eAAe,OAAO,GAAG;AACxC,qBAAe,eAAe;AAAA,IAClC;AAEA,QAAI,gBAAgB,OAAO,aAAa,oBAAoB,YAAY;AACpE,mBAAa,gBAAgB;AAC7B,qBAAe;AAAA,IACnB;AACA,QAAI,OAAO,uBAAuB,YAAY;AAC1C,yBAAmB;AAAA,IACvB;AAAA,EACJ;AAEA,MAAI,OAAO,mBAAmB;AAC1B,oBAAgB,CAAC;AAAA,EACrB,WAAW,OAAO,sBAAsB;AACpC,uBAAmB,CAAC;AAAA,EACxB,WAAW,OAAO,8BAA8B;AAC5C,+BAA2B,CAAC;AAAA,EAChC,WAAW,OAAO,yBAAyB;AACvC,0BAAsB,CAAC;AAAA,EAC3B,WAAW,oBAAoB;AAC3B,wBAAoB,CAAC;AAAA,EACzB,WAAW,mBAAmB;AAC1B,oBAAqB,CAAC;AAAA,EAC1B,WAAW,oBAAoB;AAC3B,IAAAC,iBAAsB,CAAC;AAAA,EAC3B,WAAW,mBAAmB;AAC1B,yBAAqB,CAAC;AAAA,EAC1B,WACS,kBAAkB;AACvB,IAAAA,iBAAoB,CAAC;AAAA,EACzB,WACS,mBAAmB;AACxB,IAAAA,iBAAwB,CAAC;AAAA,EAC7B,WACS,kBAAkB;AAEvB,UAAM,kBAAkB,EAAE,OAAO,QAAQ,2BAA2B;AACpE,UAAM,kBAAkB,EAAE,OAAO,QAAQ,2BAA2B;AACpE,QAAI,mBAAmB,CAAC,iBAAiB;AACrC,0BAAoB,CAAC;AAAA,IACzB,WAAW,oBAAoB,CAAC,mBAAmB,CAAC,iBAAiB;AACjE,0BAAoB,CAAC;AAAA,IACzB,OAAO;AACH,0BAAoB,CAAC;AAAA,IACzB;AAAA,EACJ,WACS,mBAAmB;AACxB,IAAAA,iBAAqB,CAAC;AAAA,EAC1B,WACS,kBAAkB;AACvB,wBAAoB,CAAC;AAAA,EACzB,WACS,uBAAuB;AAE5B,QAAI,8BAA8B,CAAC,GAAG;AAClC;AAAA,IACJ;AAGA,UAAM,YAAY;AAClB,QAAI,UAAU;AAGd,QAAI,cAAc,cAAc,aAAa;AACzC,0BAAoB,CAAC;AACrB,gBAAU;AAAA,IACd,WAAW,cAAc,cAAc,SAAS;AAC5C,sBAAqB,CAAC;AACtB,gBAAU;AAAA,IACd,WAAW,cAAc,cAAc,UAAU;AAC7C,MAAAA,iBAAsB,CAAC;AACvB,gBAAU;AAAA,IACd,WAAW,cAAc,cAAc,SAAS;AAC5C,2BAAqB,CAAC;AACtB,gBAAU;AAAA,IACd,WACS,cAAc,cAAc,QAAQ;AACzC,MAAAA,iBAAoB,CAAC;AACrB,gBAAU;AAAA,IACd,WACS,cAAc,cAAc,kBAAkB;AACnD,MAAAA,iBAAwB,CAAC;AACzB,gBAAU;AAAA,IACd,WACS,cAAc,cAAc,QAAQ;AACzC,0BAAoB,CAAC;AACrB,gBAAU;AAAA,IACd,WACS,cAAc,cAAc,SAAS;AAC1C,MAAAA,iBAAqB,CAAC;AACtB,gBAAU;AAAA,IACd,WACS,cAAc,cAAc,QAAQ;AACzC,0BAAoB,CAAC;AACrB,gBAAU;AAAA,IACd,WACS,cAAc,cAAc,QAAQ;AACzC,0BAAoB,CAAC;AACrB,gBAAU;AAAA,IACd;AAIA,QAAI,WAAW,aAAa,CAAC,cAAc;AACvC,gBAAU;AAAA,IACd;AAEA,QAAI,CAAC,SAAS;AACV,YAAM,uBAAuB;AAC7B,0BAAoB,CAAC;AACrB,UAAI,gBAAgB,iBAAiB,qBAAsB;AAC3D,MAAAA,iBAAsB,CAAC;AACvB,UAAI,gBAAgB,iBAAiB,qBAAsB;AAC3D,sBAAqB,CAAC;AACtB,UAAI,gBAAgB,iBAAiB,qBAAsB;AAC3D,2BAAqB,CAAC;AACtB,UAAI,gBAAgB,iBAAiB,qBAAsB;AAC3D,MAAAA,iBAAoB,CAAC;AACrB,UAAI,gBAAgB,iBAAiB,qBAAsB;AAC3D,MAAAA,iBAAwB,CAAC;AACzB,UAAI,gBAAgB,iBAAiB,qBAAsB;AAC3D,0BAAoB,CAAC;AACrB,UAAI,gBAAgB,iBAAiB,qBAAsB;AAC3D,MAAAA,iBAAqB,CAAC;AACtB,UAAI,gBAAgB,iBAAiB,qBAAsB;AAC3D,0BAAoB,CAAC;AACrB,UAAI,gBAAgB,iBAAiB,qBAAsB;AAC3D,0BAAoB,CAAC;AACrB,UAAI,gBAAgB,iBAAiB,qBAAsB;AAC3D,UAAI,iBAAiB,sBAAsB;AACvC,YAAI,cAAc;AACd,uBAAa,gBAAgB;AAC7B,yBAAe;AAAA,QACnB;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AACJ;AAEA,IAAM,sBAAsB,CAAC,MAAM;AAC/B,MAAI,OAAO,wBAAyB;AAEpC,MAAI,EAAE,UAAU,GAAG;AACf,qBAAiB;AACjB,qBAAiB;AAAA,EACrB,OAAO;AACH,oBAAgB;AAAA,EACpB;AAEA,MAAI,OAAO,mBAAmB;AAC1B,oBAAgB,CAAC;AAAA,EACrB,WAAW,OAAO,sBAAsB;AACpC,uBAAmB,CAAC;AAAA,EACxB,WAAW,OAAO,8BAA8B;AAC5C,+BAA2B,CAAC;AAAA,EAChC,WAAW,OAAO,yBAAyB;AACvC;AAAA,EACJ,WAAW,oBAAoB;AAC3B,wBAAoB,CAAC;AAAA,EACzB,WAAW,mBAAmB;AAC1B,oBAAqB,CAAC;AAAA,EAC1B,WAAW,oBAAoB;AAC3B,IAAAC,iBAAsB,CAAC;AAAA,EAC3B,WAAW,mBAAmB;AAC1B,yBAAqB,CAAC;AAAA,EAC1B,WACS,kBAAkB;AACvB,IAAAA,iBAAoB,CAAC;AAAA,EACzB,WACS,mBAAmB;AACxB,IAAAA,iBAAwB,CAAC;AAAA,EAC7B,WACS,kBAAkB;AACvB,wBAAoB,CAAC;AACrB,wBAAoB,CAAC;AAAA,EACzB,WACS,mBAAmB;AACxB,IAAAA,iBAAqB,CAAC;AAAA,EAC1B,WACS,kBAAkB;AACvB,wBAAoB,CAAC;AAAA,EACzB,WACS,uBAAuB;AAE5B,QAAI,oBAAoB,eAAe,cAAc,eAAe,cAAc,eAAe,YAAY;AACzG,UAAI,8BAA8B,CAAC,GAAG;AAClC;AAAA,MACJ;AAAA,IACJ;AAGA,QAAI,cAAc,cAAc,aAAa;AACzC,0BAAoB,CAAC;AAAA,IACzB,WAAW,cAAc,cAAc,SAAS;AAC5C,sBAAqB,CAAC;AAAA,IAC1B,WAAW,cAAc,cAAc,UAAU;AAC7C,MAAAA,iBAAsB,CAAC;AAAA,IAC3B,WAAW,cAAc,cAAc,SAAS;AAC5C,2BAAqB,CAAC;AAAA,IAC1B,WACS,cAAc,cAAc,QAAQ;AACzC,MAAAA,iBAAoB,CAAC;AAAA,IACzB,WACS,cAAc,cAAc,kBAAkB;AACnD,MAAAA,iBAAwB,CAAC;AAAA,IAC7B,WACS,cAAc,cAAc,QAAQ;AACzC,0BAAoB,CAAC;AAAA,IACzB,WACS,cAAc,cAAc,SAAS;AAC1C,MAAAA,iBAAqB,CAAC;AAAA,IAC1B,WACS,cAAc,cAAc,QAAQ;AACzC,0BAAoB,CAAC;AAAA,IACzB,WACS,cAAc,cAAc,QAAQ;AACzC,0BAAoB,CAAC;AAAA,IACzB,OAEK;AAED,UAAI,8BAA8B,CAAC,GAAG;AAClC;AAAA,MACJ;AAEA,0BAAoB,CAAC;AACrB,sBAAqB,CAAC;AACtB,MAAAA,iBAAsB,CAAC;AACvB,2BAAqB,CAAC;AACtB,MAAAA,iBAAoB,CAAC;AACrB,MAAAA,iBAAwB,CAAC;AACzB,0BAAoB,CAAC;AACrB,MAAAA,iBAAqB,CAAC;AACtB,0BAAoB,CAAC;AACrB,0BAAoB,CAAC;AAAA,IACzB;AAAA,EACJ;AACJ;AAEA,IAAM,oBAAoB,CAAC,MAAM;AAC7B,MAAI,OAAO,wBAAyB;AACpC,kBAAgB;AAChB,MAAI,OAAO,mBAAmB;AAC1B,kBAAc,CAAC;AAAA,EACnB,WAAW,OAAO,sBAAsB;AACpC,qBAAiB,CAAC;AAAA,EACtB,WAAW,OAAO,8BAA8B;AAC5C,6BAAyB,CAAC;AAAA,EAC9B,WAAW,OAAO,yBAAyB;AACvC;AAAA,EACJ,WAAW,oBAAoB;AAC3B,sBAAkB,CAAC;AAAA,EACvB,WAAW,mBAAmB;AAC1B,kBAAmB,CAAC;AAAA,EACxB,WAAW,oBAAoB;AAC3B,IAAAC,eAAoB,CAAC;AAAA,EACzB,WAAW,mBAAmB;AAC1B,uBAAmB,CAAC;AAAA,EACxB,WACS,kBAAkB;AACvB,IAAAA,eAAkB,CAAC;AAAA,EACvB,WACS,mBAAmB;AACxB,IAAAA,eAAsB,CAAC;AAAA,EAC3B,WACS,kBAAkB;AACvB,sBAAkB,CAAC;AACnB,sBAAkB,CAAC;AAAA,EACvB,WACS,mBAAmB;AACxB,IAAAA,eAAmB,CAAC;AAAA,EACxB,WACS,kBAAkB;AACvB,sBAAkB,CAAC;AAAA,EACvB,WAES,uBAAuB;AAE5B,QAAI,oBAAoB,eAAe,cAAc,eAAe,cAAc,eAAe,YAAY;AACzG,kCAA4B,CAAC;AAC7B;AAAA,IACJ;AAGA,QAAI,cAAc,cAAc,aAAa;AACzC,wBAAkB,CAAC;AAAA,IACvB,WAAW,cAAc,cAAc,SAAS;AAC5C,oBAAmB,CAAC;AAAA,IACxB,WAAW,cAAc,cAAc,UAAU;AAC7C,MAAAA,eAAoB,CAAC;AAAA,IACzB,WAAW,cAAc,cAAc,SAAS;AAC5C,yBAAmB,CAAC;AAAA,IACxB,WACS,cAAc,cAAc,QAAQ;AACzC,MAAAA,eAAkB,CAAC;AAAA,IACvB,WACS,cAAc,cAAc,kBAAkB;AACnD,MAAAA,eAAsB,CAAC;AAAA,IAC3B,WACS,cAAc,cAAc,QAAQ;AACzC,wBAAkB,CAAC;AAAA,IACvB,WACS,cAAc,cAAc,SAAS;AAC1C,MAAAA,eAAmB,CAAC;AAAA,IACxB,WACS,cAAc,cAAc,QAAQ;AACzC,wBAAkB,CAAC;AAAA,IACvB,WACS,cAAc,cAAc,QAAQ;AACzC,wBAAkB,CAAC;AAAA,IACvB,OAEK;AACD,kCAA4B,CAAC;AAC7B,wBAAkB,CAAC;AACnB,oBAAmB,CAAC;AACpB,MAAAA,eAAoB,CAAC;AACrB,yBAAmB,CAAC;AACpB,MAAAA,eAAkB,CAAC;AACnB,MAAAA,eAAsB,CAAC;AACvB,wBAAkB,CAAC;AACnB,MAAAA,eAAmB,CAAC;AACpB,wBAAkB,CAAC;AACnB,wBAAkB,CAAC;AAAA,IACvB;AAAA,EACJ;AACJ;AAEA,IAAM,uBAAuB,CAAC,MAAM;AAChC,MAAI,OAAO,wBAAyB;AAGpC,MAAI,EAAE,UAAU,GAAG;AACf,qBAAiB;AACjB,qBAAiB;AAGjB,QAAI,CAAC,qBAAqB;AACtB,4BAAsB;AACtB,eAAS,iBAAiB,eAAe,mBAAmB;AAC5D,eAAS,iBAAiB,aAAa,iBAAiB;AAAA,IAC5D;AACA;AAAA,EACJ;AAKA,oBAAkB,CAAC;AAGnB,2BAAyB;AAGzB,MAAI,OAAO,OAAO,4BAA4B,YAAY;AACtD,WAAO,wBAAwB;AAAA,EACnC;AAGA,MAAI,OAAO,cAAc,eAAe,WAAW;AAC/C,gBAAY;AACZ,QAAI,OAAO,WAAW,eAAe,OAAO,SAAS,KAAK,OAAO,mBAAmB,YAAY;AAC5F,YAAM,YAAY,OAAO,OAAO,SAAS,CAAC;AAC1C,qBAAe,SAAS;AAAA,IAC5B;AAAA,EACJ;AACJ;AAEA,IAAI,YAAY;AAEhB,SAAS,cAAc,GAAG;AAEtB,MAAI,qBAAqB;AACrB,aAAS,oBAAoB,eAAe,mBAAmB;AAC/D,aAAS,oBAAoB,aAAa,iBAAiB;AAC3D,0BAAsB;AAAA,EAC1B;AACJ;AAEA,IAAM,qBAAqB,CAAC,MAAM;AAC9B,MAAI,CAAC,EAAE,OAAQ;AAEf,QAAM,kBAAkB,EAAE,OAAO,QAAQ,2BAA2B;AACpE,MAAI,iBAAiB;AACjB,MAAE,gBAAgB;AAClB,kBAAc,eAAe;AAAA,EACjC;AACJ;AAEA,SAAS,oBAAoB,OAAO;AAChC,MAAI,UAAW,wBAAuB;AACtC,QAAM,SAAS,SAAS;AACxB,SAAO,iBAAiB,eAAe,mBAAmB;AAC1D,SAAO,iBAAiB,eAAe,mBAAmB;AAC1D,SAAO,iBAAiB,aAAa,iBAAiB;AACtD,SAAO,iBAAiB,gBAAgB,oBAAoB;AAC5D,SAAO,iBAAiB,gBAAgB,aAAa;AACrD,SAAO,iBAAiB,YAAY,kBAAkB;AACtD,cAAY;AAChB;AAEA,SAAS,yBAAyB;AAC9B,kBAAgB;AAChB,MAAI,qBAAqB;AACrB,aAAS,oBAAoB,eAAe,mBAAmB;AAC/D,aAAS,oBAAoB,aAAa,iBAAiB;AAC3D,0BAAsB;AAAA,EAC1B;AACA,MAAI,WAAW;AACX,cAAU,oBAAoB,eAAe,mBAAmB;AAChE,cAAU,oBAAoB,eAAe,mBAAmB;AAChE,cAAU,oBAAoB,aAAa,iBAAiB;AAC5D,cAAU,oBAAoB,gBAAgB,oBAAoB;AAClE,cAAU,oBAAoB,gBAAgB,aAAa;AAC3D,cAAU,oBAAoB,YAAY,kBAAkB;AAC5D,gBAAY;AAAA,EAChB;AACJ;AAGA,IAAI,OAAO,QAAQ,eAAe,KAAK;AACnC,sBAAoB,GAAG;AAC3B;",
|
|
6
|
-
"names": ["start", "path", "frame", "getSVGPoint", "MAX_POINTS", "points", "drawing", "coords", "handleMouseDown", "handleMouseMove", "handleMouseUp"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/core/GraphRenderer.js", "../../src/core/GraphEngine.js"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable */\n/**\n * GraphRenderer - Renders mathematical equations as SVG graphs.\n * Produces axes, grid, tick labels, and equation curves.\n */\n\nimport { parseExpression } from './GraphMathParser.js';\n\nconst GRAPH_COLORS = [\n '#4A90D9', '#E74C3C', '#2ECC71', '#F39C12', '#9B59B6',\n '#1ABC9C', '#E67E22', '#3498DB', '#E91E63', '#00BCD4',\n];\n\n// Issue #38 follow-up: theme-aware graph chrome. Light mode flips every\n// hardcoded `rgba(255,255,255,X)` token (designed for dark canvas) to a\n// matching `rgba(60,60,80,X)` so the grid, axes, plot border, and tick\n// labels stay readable on the warm off-white canvas. The equation\n// curves themselves keep their colours from GRAPH_COLORS.\nfunction graphThemeTokens() {\n const isDark = typeof document !== 'undefined'\n && document.body\n && document.body.classList.contains('theme-dark');\n if (isDark) {\n return {\n outerBg: '#0d1117',\n plotBg: '#111822',\n gridStroke:'rgba(255,255,255,0.06)',\n axisStroke:'rgba(255,255,255,0.25)',\n borderStroke:'rgba(255,255,255,0.1)',\n tickLabel: '#8b949e',\n };\n }\n return {\n outerBg: '#fbfaf6',\n plotBg: '#ffffff',\n gridStroke:'rgba(60,60,80,0.08)',\n axisStroke:'rgba(60,60,80,0.35)',\n borderStroke:'rgba(60,60,80,0.16)',\n tickLabel: '#62627a',\n };\n}\n\n/**\n * Calculate nice tick intervals for a given range.\n */\nfunction niceInterval(range) {\n const rough = range / 8;\n const mag = Math.pow(10, Math.floor(Math.log10(rough)));\n const residual = rough / mag;\n let nice;\n if (residual <= 1.5) nice = 1;\n else if (residual <= 3) nice = 2;\n else if (residual <= 7) nice = 5;\n else nice = 10;\n return nice * mag;\n}\n\n/**\n * Render graph as SVG markup string.\n * @param {Array} equations - [{expression: string, color: string}]\n * @param {Object} settings - {xMin, xMax, yMin, yMax, showGrid, width, height}\n * @returns {string} SVG markup\n */\nexport function renderGraphSVG(equations, settings) {\n const {\n xMin = -10, xMax = 10,\n yMin = -10, yMax = 10,\n showGrid = true,\n width = 600, height = 400,\n } = settings || {};\n\n const pad = { top: 20, right: 20, bottom: 35, left: 45 };\n const plotW = width - pad.left - pad.right;\n const plotH = height - pad.top - pad.bottom;\n const xRange = xMax - xMin || 1;\n const yRange = yMax - yMin || 1;\n\n // Coordinate transforms\n const toSvgX = (x) => pad.left + ((x - xMin) / xRange) * plotW;\n const toSvgY = (y) => pad.top + ((yMax - y) / yRange) * plotH;\n\n let svg = '';\n const tk = graphThemeTokens();\n\n // Background\n svg += `<rect x=\"0\" y=\"0\" width=\"${width}\" height=\"${height}\" fill=\"${tk.outerBg}\" rx=\"8\" />`;\n svg += `<rect x=\"${pad.left}\" y=\"${pad.top}\" width=\"${plotW}\" height=\"${plotH}\" fill=\"${tk.plotBg}\" />`;\n\n // Grid & ticks\n const xTick = niceInterval(xRange);\n const yTick = niceInterval(yRange);\n\n // Vertical grid lines + x labels\n const xStart = Math.ceil(xMin / xTick) * xTick;\n for (let x = xStart; x <= xMax; x += xTick) {\n const sx = toSvgX(x);\n if (sx < pad.left || sx > pad.left + plotW) continue;\n if (showGrid) {\n svg += `<line x1=\"${sx}\" y1=\"${pad.top}\" x2=\"${sx}\" y2=\"${pad.top + plotH}\" stroke=\"${tk.gridStroke}\" stroke-width=\"0.5\" />`;\n }\n const label = Math.abs(x) < 1e-10 ? '0' : (Number.isInteger(x) ? x : x.toFixed(1));\n svg += `<text x=\"${sx}\" y=\"${pad.top + plotH + 16}\" text-anchor=\"middle\" fill=\"${tk.tickLabel}\" font-size=\"10\" font-family=\"lixCode, monospace\">${label}</text>`;\n }\n\n // Horizontal grid lines + y labels\n const yStart = Math.ceil(yMin / yTick) * yTick;\n for (let y = yStart; y <= yMax; y += yTick) {\n const sy = toSvgY(y);\n if (sy < pad.top || sy > pad.top + plotH) continue;\n if (showGrid) {\n svg += `<line x1=\"${pad.left}\" y1=\"${sy}\" x2=\"${pad.left + plotW}\" y2=\"${sy}\" stroke=\"${tk.gridStroke}\" stroke-width=\"0.5\" />`;\n }\n const label = Math.abs(y) < 1e-10 ? '0' : (Number.isInteger(y) ? y : y.toFixed(1));\n svg += `<text x=\"${pad.left - 8}\" y=\"${sy + 3}\" text-anchor=\"end\" fill=\"${tk.tickLabel}\" font-size=\"10\" font-family=\"lixCode, monospace\">${label}</text>`;\n }\n\n // Axes\n if (xMin <= 0 && xMax >= 0) {\n const ax = toSvgX(0);\n svg += `<line x1=\"${ax}\" y1=\"${pad.top}\" x2=\"${ax}\" y2=\"${pad.top + plotH}\" stroke=\"${tk.axisStroke}\" stroke-width=\"1\" />`;\n }\n if (yMin <= 0 && yMax >= 0) {\n const ay = toSvgY(0);\n svg += `<line x1=\"${pad.left}\" y1=\"${ay}\" x2=\"${pad.left + plotW}\" y2=\"${ay}\" stroke=\"${tk.axisStroke}\" stroke-width=\"1\" />`;\n }\n\n // Plot border\n svg += `<rect x=\"${pad.left}\" y=\"${pad.top}\" width=\"${plotW}\" height=\"${plotH}\" fill=\"none\" stroke=\"${tk.borderStroke}\" stroke-width=\"1\" />`;\n\n // Equations\n const samplesPerPixel = 2;\n const totalSamples = plotW * samplesPerPixel;\n const dx = xRange / totalSamples;\n\n equations.forEach((eq, eqIdx) => {\n if (!eq.expression || !eq.expression.trim()) return;\n\n const fn = parseExpression(eq.expression);\n if (!fn) return;\n\n const color = eq.color || GRAPH_COLORS[eqIdx % GRAPH_COLORS.length];\n let pathData = '';\n let drawing = false;\n\n for (let i = 0; i <= totalSamples; i++) {\n const x = xMin + i * dx;\n let y;\n try { y = fn(x); } catch { y = NaN; }\n\n if (!isFinite(y) || isNaN(y) || y < yMin - yRange * 5 || y > yMax + yRange * 5) {\n drawing = false;\n continue;\n }\n\n // Clamp to plot area for rendering\n const clampedY = Math.max(yMin - yRange * 0.5, Math.min(yMax + yRange * 0.5, y));\n const sx = toSvgX(x);\n const sy = toSvgY(clampedY);\n\n if (!drawing) {\n pathData += `M ${sx.toFixed(1)} ${sy.toFixed(1)} `;\n drawing = true;\n } else {\n pathData += `L ${sx.toFixed(1)} ${sy.toFixed(1)} `;\n }\n }\n\n if (pathData) {\n svg += `<path d=\"${pathData.trim()}\" fill=\"none\" stroke=\"${color}\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />`;\n }\n });\n\n // Clip path for plot area\n const clipId = 'graph-clip-' + Date.now();\n const defs = `<defs><clipPath id=\"${clipId}\"><rect x=\"${pad.left}\" y=\"${pad.top}\" width=\"${plotW}\" height=\"${plotH}\" /></clipPath></defs>`;\n\n // Re-wrap: curves should be clipped\n // Rebuild with clip group\n let curves = '';\n equations.forEach((eq, eqIdx) => {\n if (!eq.expression || !eq.expression.trim()) return;\n const fn = parseExpression(eq.expression);\n if (!fn) return;\n\n const color = eq.color || GRAPH_COLORS[eqIdx % GRAPH_COLORS.length];\n let pathData = '';\n let drawing = false;\n\n for (let i = 0; i <= totalSamples; i++) {\n const x = xMin + i * dx;\n let y;\n try { y = fn(x); } catch { y = NaN; }\n\n if (!isFinite(y) || isNaN(y)) { drawing = false; continue; }\n\n const sx = toSvgX(x);\n const sy = toSvgY(y);\n\n if (!drawing) {\n pathData += `M ${sx.toFixed(1)} ${sy.toFixed(1)} `;\n drawing = true;\n } else {\n pathData += `L ${sx.toFixed(1)} ${sy.toFixed(1)} `;\n }\n }\n\n if (pathData) {\n curves += `<path d=\"${pathData.trim()}\" fill=\"none\" stroke=\"${color}\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />`;\n }\n });\n\n // Equation legend\n let legendY = pad.top + 12;\n let legend = '';\n equations.forEach((eq, eqIdx) => {\n if (!eq.expression || !eq.expression.trim()) return;\n const color = eq.color || GRAPH_COLORS[eqIdx % GRAPH_COLORS.length];\n legend += `<circle cx=\"${pad.left + 12}\" cy=\"${legendY}\" r=\"4\" fill=\"${color}\" />`;\n legend += `<text x=\"${pad.left + 22}\" y=\"${legendY + 3}\" fill=\"${color}\" font-size=\"11\" font-family=\"lixCode, monospace\">${escapeXml(eq.expression)}</text>`;\n legendY += 18;\n });\n\n // Remove the non-clipped curves from svg (we added them above for building)\n // Rebuild cleanly\n let cleanSvg = '';\n cleanSvg += `<rect x=\"0\" y=\"0\" width=\"${width}\" height=\"${height}\" fill=\"${tk.outerBg}\" rx=\"8\" />`;\n cleanSvg += `<rect x=\"${pad.left}\" y=\"${pad.top}\" width=\"${plotW}\" height=\"${plotH}\" fill=\"${tk.plotBg}\" />`;\n\n // Grid + ticks (re-add)\n for (let x = xStart; x <= xMax; x += xTick) {\n const sx = toSvgX(x);\n if (sx < pad.left || sx > pad.left + plotW) continue;\n if (showGrid) {\n cleanSvg += `<line x1=\"${sx}\" y1=\"${pad.top}\" x2=\"${sx}\" y2=\"${pad.top + plotH}\" stroke=\"${tk.gridStroke}\" stroke-width=\"0.5\" />`;\n }\n const label = Math.abs(x) < 1e-10 ? '0' : (Number.isInteger(x) ? x : x.toFixed(1));\n cleanSvg += `<text x=\"${sx}\" y=\"${pad.top + plotH + 16}\" text-anchor=\"middle\" fill=\"${tk.tickLabel}\" font-size=\"10\" font-family=\"lixCode, monospace\">${label}</text>`;\n }\n for (let y = yStart; y <= yMax; y += yTick) {\n const sy = toSvgY(y);\n if (sy < pad.top || sy > pad.top + plotH) continue;\n if (showGrid) {\n cleanSvg += `<line x1=\"${pad.left}\" y1=\"${sy}\" x2=\"${pad.left + plotW}\" y2=\"${sy}\" stroke=\"${tk.gridStroke}\" stroke-width=\"0.5\" />`;\n }\n const label = Math.abs(y) < 1e-10 ? '0' : (Number.isInteger(y) ? y : y.toFixed(1));\n cleanSvg += `<text x=\"${pad.left - 8}\" y=\"${sy + 3}\" text-anchor=\"end\" fill=\"${tk.tickLabel}\" font-size=\"10\" font-family=\"lixCode, monospace\">${label}</text>`;\n }\n // Axes\n if (xMin <= 0 && xMax >= 0) {\n const ax = toSvgX(0);\n cleanSvg += `<line x1=\"${ax}\" y1=\"${pad.top}\" x2=\"${ax}\" y2=\"${pad.top + plotH}\" stroke=\"${tk.axisStroke}\" stroke-width=\"1\" />`;\n }\n if (yMin <= 0 && yMax >= 0) {\n const ay = toSvgY(0);\n cleanSvg += `<line x1=\"${pad.left}\" y1=\"${ay}\" x2=\"${pad.left + plotW}\" y2=\"${ay}\" stroke=\"${tk.axisStroke}\" stroke-width=\"1\" />`;\n }\n // Plot border\n cleanSvg += `<rect x=\"${pad.left}\" y=\"${pad.top}\" width=\"${plotW}\" height=\"${plotH}\" fill=\"none\" stroke=\"${tk.borderStroke}\" stroke-width=\"1\" />`;\n\n // Clipped curves\n cleanSvg += `<g clip-path=\"url(#${clipId})\">${curves}</g>`;\n\n // Legend\n cleanSvg += legend;\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\">${defs}${cleanSvg}</svg>`;\n}\n\n/**\n * Generate a preview SVG for the modal.\n */\nexport function renderGraphPreviewSVG(equations, settings) {\n return renderGraphSVG(equations, {\n ...settings,\n width: 520,\n height: 380,\n });\n}\n\nfunction escapeXml(str) {\n return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n}\n\nexport { GRAPH_COLORS };\n", "/* eslint-disable */\n/**\n * GraphEngine - bridge between graph rendering and the sketch canvas.\n *\n * Canvas graphs use ImageShape with an SVG data URL. This keeps the graph a\n * single crisp vector element while reusing the engine's established select,\n * translate, resize, rotate, copy/paste, and frame-containment behaviour.\n */\n\nimport { parseExpression, isValidExpression } from './GraphMathParser.js';\nimport { renderGraphSVG, renderGraphPreviewSVG, GRAPH_COLORS } from './GraphRenderer.js';\n\nconst NS = 'http://www.w3.org/2000/svg';\nconst GRAPH_WIDTH = 600;\nconst GRAPH_HEIGHT = 420;\nconst MAX_PLACED_SCREEN_WIDTH = 480;\nconst MAX_VIEWPORT_WIDTH_RATIO = 0.68;\nconst MAX_VIEWPORT_HEIGHT_RATIO = 0.58;\n\nfunction cloneGraphData(equations, settings) {\n return {\n equations: (equations || []).map((equation) => ({\n expression: equation.expression,\n color: equation.color,\n })),\n settings: { ...(settings || {}) },\n };\n}\n\nfunction graphSvgDataUrl(svgMarkup) {\n return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgMarkup)}`;\n}\n\nfunction refreshGraphImage(shape) {\n if (!shape?._graphData || !shape.element) return false;\n const svgMarkup = renderGraphSVG(shape._graphData.equations, {\n ...shape._graphData.settings,\n width: GRAPH_WIDTH,\n height: GRAPH_HEIGHT,\n });\n if (!svgMarkup) return false;\n const href = graphSvgDataUrl(svgMarkup);\n shape.element.setAttribute('href', href);\n shape.element.setAttribute('data-href', href);\n return true;\n}\n\n/** Attach graph behaviour to a regular ImageShape, including restored and\n * pasted graphs. The function is intentionally idempotent. */\nfunction hydrateGraphShape(shape, graphData) {\n if (!shape?.element || !graphData) return shape;\n shape._frameType = 'graph';\n shape._graphData = cloneGraphData(graphData.equations, graphData.settings);\n shape.uploadStatus = 'done';\n shape.element.setAttribute('data-graph-shape', 'true');\n shape.element.setAttribute('preserveAspectRatio', 'none');\n shape.element.style.cursor = 'move';\n shape._refreshGraphImage = () => refreshGraphImage(shape);\n shape.adaptToBackground = () => refreshGraphImage(shape);\n return shape;\n}\n\nfunction selectOnlyGraph(shape) {\n if (!shape) return;\n\n if (window.multiSelection?.selectedShapes?.size) {\n window.multiSelection.clearSelection();\n }\n if (window.currentShape && window.currentShape !== shape\n && typeof window.currentShape.removeSelection === 'function') {\n window.currentShape.removeSelection();\n }\n\n // Generated content always lands ready to manipulate. Use the store bridge\n // so the toolbar and legacy engine flags change together.\n window.__sketchStoreApi?.setActiveTool?.('select');\n window.currentShape = shape;\n shape.selectShape?.();\n}\n\nfunction placedGraphSize(viewBox) {\n const zoom = Math.max(0.001, Number(window.currentZoom) || 1);\n const byScreen = MAX_PLACED_SCREEN_WIDTH / zoom;\n const byViewportWidth = viewBox.width * MAX_VIEWPORT_WIDTH_RATIO;\n const byViewportHeight = viewBox.height * MAX_VIEWPORT_HEIGHT_RATIO * (GRAPH_WIDTH / GRAPH_HEIGHT);\n const width = Math.max(80 / zoom, Math.min(GRAPH_WIDTH, byScreen, byViewportWidth, byViewportHeight));\n return { width, height: width * (GRAPH_HEIGHT / GRAPH_WIDTH) };\n}\n\n/**\n * Place a graph as one editable vector-image shape, or update an existing\n * graph in place without losing its canvas position, size, or rotation.\n */\nfunction renderGraphOnCanvas(equations, settings, existingShape = null) {\n const validEquations = (equations || []).filter((equation) => equation?.expression?.trim());\n if (validEquations.length === 0) return false;\n if (!window.svg || !window.ImageShape) {\n console.error('[GraphEngine] Engine not initialized');\n return false;\n }\n\n const graphData = cloneGraphData(validEquations, settings);\n\n if (existingShape?._frameType === 'graph' && existingShape.element) {\n hydrateGraphShape(existingShape, graphData);\n if (!refreshGraphImage(existingShape)) return false;\n selectOnlyGraph(existingShape);\n window.__adaptCanvasContrast?.(\n window.getComputedStyle(window.svg).backgroundColor || '#15111f'\n );\n return true;\n }\n\n const viewBox = window.currentViewBox || {\n x: 0,\n y: 0,\n width: window.innerWidth,\n height: window.innerHeight,\n };\n const size = placedGraphSize(viewBox);\n const x = viewBox.x + (viewBox.width - size.width) / 2;\n const y = viewBox.y + (viewBox.height - size.height) / 2;\n\n try {\n const image = document.createElementNS(NS, 'image');\n image.setAttribute('x', x);\n image.setAttribute('y', y);\n image.setAttribute('width', size.width);\n image.setAttribute('height', size.height);\n image.setAttribute('data-shape-x', x);\n image.setAttribute('data-shape-y', y);\n image.setAttribute('data-shape-width', size.width);\n image.setAttribute('data-shape-height', size.height);\n\n const graphShape = hydrateGraphShape(new window.ImageShape(image), graphData);\n if (!refreshGraphImage(graphShape)) {\n graphShape.group?.remove();\n return false;\n }\n\n window.shapes.push(graphShape);\n window.pushCreateAction?.(graphShape);\n selectOnlyGraph(graphShape);\n window.__adaptCanvasContrast?.(\n window.getComputedStyle(window.svg).backgroundColor || '#15111f'\n );\n return true;\n } catch (error) {\n console.error('[GraphEngine] SVG insertion failed:', error);\n return false;\n }\n}\n\n/** Initialize graph bridges used by the modal and scene restoration. */\nexport function initGraphEngine() {\n window.__graphPreview = (equations, settings) => renderGraphPreviewSVG(equations, settings);\n window.__graphRenderer = renderGraphOnCanvas;\n window.__hydrateGraphShape = hydrateGraphShape;\n window.__graphParser = (expression) => Boolean(parseExpression(expression));\n window.__graphValidate = isValidExpression;\n window.__graphColors = GRAPH_COLORS;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|