drawui-core 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +16 -16
- package/dist/index.d.cts +28 -1
- package/dist/index.d.ts +28 -1
- package/dist/index.js +16 -16
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
'use strict';var j={identity(){return {a:1,b:0,c:0,d:1,e:0,f:0}},translation(a,t){return {a:1,b:0,c:0,d:1,e:a,f:t}},rotation(a){let t=Math.cos(a),e=Math.sin(a);return {a:t,b:e,c:-e,d:t,e:0,f:0}},scale(a,t){return {a,b:0,c:0,d:t,e:0,f:0}},multiply(a,t){return {a:a.a*t.a+a.b*t.c,b:a.a*t.b+a.b*t.d,c:a.c*t.a+a.d*t.c,d:a.c*t.b+a.d*t.d,e:a.e*t.a+a.f*t.c+t.e,f:a.e*t.b+a.f*t.d+t.f}},apply(a,t){return {x:a.a*t.x+a.c*t.y+a.e,y:a.b*t.x+a.d*t.y+a.f}},invert(a){let t=a.a*a.d-a.b*a.c;if(Math.abs(t)<1e-10)return null;let e=1/t;return {a:a.d*e,b:-a.b*e,c:-a.c*e,d:a.a*e,e:(a.c*a.f-a.d*a.e)*e,f:(a.b*a.e-a.a*a.f)*e}},createCameraMatrix(a){let t=j.scale(a.zoom,a.zoom),e=j.translation(a.x,a.y);return j.multiply(e,t)}};var et=class{x=0;y=0;zoom=1;minZoom=.1;maxZoom=10;getMatrix(){return j.createCameraMatrix({x:this.x,y:this.y,zoom:this.zoom})}getInverseMatrix(){return j.invert(this.getMatrix())}screenToPage(t){let e=this.getInverseMatrix();return e?j.apply(e,t):t}pageToScreen(t){return j.apply(this.getMatrix(),t)}translate(t,e){this.x+=t,this.y+=e;}zoomAt(t,e){let i=this.screenToPage(t);this.zoom=Math.max(this.minZoom,Math.min(this.maxZoom,this.zoom*e));let n=this.pageToScreen(i);this.x+=t.x-n.x,this.y+=t.y-n.y;}reset(){this.x=0,this.y=0,this.zoom=1;}getZoom(){return this.zoom}fitBounds(t,e=50){let i=window.innerWidth,n=window.innerHeight,r=(i-e*2)/t.width,s=(n-e*2)/t.height,o=Math.min(r,s,this.maxZoom);this.zoom=Math.max(this.minZoom,o),this.x=(i-t.width*this.zoom)/2-t.x*this.zoom,this.y=(n-t.height*this.zoom)/2-t.y*this.zoom;}};var Wt={primary:"#3b82f6",selection:{outline:"#3b82f6",handleStroke:"#3b82f6",handleFill:"#ffffff",outlineFill:"rgba(59, 130, 246, 0.1)",shadow:"#3b82f6"},grid:"#e5e7eb",text:"#1f2937",editBorder:"#3b82f6",brushFill:"rgba(59, 130, 246, 0.08)",brushStroke:"rgba(59, 130, 246, 0.8)",guide:"rgba(59, 130, 246, 0.6)",lineHighlight:"rgba(59, 130, 246, 0.4)",genDot:"#3b82f6",genLine:"rgba(59, 130, 246, 0.55)"},I={...Wt,selection:{...Wt.selection}},At=new Set;function de(a){return At.add(a),()=>At.delete(a)}function bt(a){a.selection&&Object.assign(I.selection,a.selection);for(let t of Object.keys(a)){if(t==="selection")continue;let e=a[t];e!==void 0&&(I[t]=e);}At.forEach(t=>t());}function ce(){return I}function nt(a,t){let e=Kt(a);if(!e)return a;let i=parseInt(e,16),n=i>>16&255,r=i>>8&255,s=i&255;return `rgba(${n}, ${r}, ${s}, ${t})`}function ue(a,t){let e=Kt(a);if(!e)return a;let i=parseInt(e,16),n=t<0?0:255,r=Math.abs(t),s=o=>Math.round((n-o)*r+o).toString(16).padStart(2,"0");return `#${s(i>>16&255)}${s(i>>8&255)}${s(i&255)}`}function Kt(a){let t=a.replace("#","").trim();return /^[0-9a-fA-F]{3}$|^[0-9a-fA-F]{6}$/.test(t)?t.length===3?t.split("").map(e=>e+e).join(""):t:null}var H=class{context;constructor(t){this.context=t;}getCursor(t){return null}dispose(){}};var Ft={"zh-CN":{"save.success":"\u5DF2\u4FDD\u5B58","save.fail":"\u4FDD\u5B58\u5931\u8D25","tool.select":"\u9009\u62E9\u5DE5\u5177","tool.hand":"\u62D6\u62FD\u89C6\u53E3","tool.rectangle":"\u77E9\u5F62","tool.rounded-rectangle":"\u5706\u89D2\u77E9\u5F62","tool.circle":"\u5706\u5F62","tool.ellipse":"\u692D\u5706","tool.diamond":"\u83F1\u5F62","tool.triangle":"\u4E09\u89D2\u5F62","tool.hexagon":"\u516D\u8FB9\u5F62","tool.parallelogram":"\u5E73\u884C\u56DB\u8FB9\u5F62","tool.trapezoid":"\u68AF\u5F62","tool.pentagon":"\u4E94\u8FB9\u5F62","tool.octagon":"\u516B\u8FB9\u5F62","tool.star":"\u661F\u5F62","tool.uml-class":"UML \u7C7B\u56FE","tool.uml-interface":"UML \u63A5\u53E3","tool.line":"\u76F4\u7EBF","tool.arrow":"\u7EBF\u6761","tool.text":"\u6587\u672C","tool.draw":"\u753B\u7B14","tool.pen":"\u753B\u7B14","tool.highlighter":"\u8367\u5149\u7B14","tool.eraser":"\u6A61\u76AE\u64E6","status.none":"\u672A\u9009\u62E9","status.selected":"\u5DF2\u9009\u62E9 {n} \u4E2A\u56FE\u5F62","toolbar.select":"\u9009\u62E9 (V)","toolbar.hand":"\u62D6\u62FD\u89C6\u53E3 (H)","toolbar.shapes":"\u5F62\u72B6","toolbar.grid":"\u7F51\u683C","toolbar.undo":"\u64A4\u9500 (Ctrl+Z)","toolbar.redo":"\u91CD\u505A (Ctrl+Shift+Z)","toolbar.arrow":"\u7BAD\u5934","toolbar.text":"\u6587\u672C","toolbar.pen":"\u753B\u7B14","toolbar.highlighter":"\u8367\u5149\u7B14","toolbar.eraser":"\u6A61\u76AE\u64E6","toolbar.uml-class":"UML \u7C7B\u56FE","toolbar.uml-interface":"UML \u63A5\u53E3","zoom.in":"\u653E\u5927","zoom.out":"\u7F29\u5C0F","zoom.reset":"\u91CD\u7F6E","style.stroke":"\u8FB9\u6846","style.fill":"\u586B\u5145","style.text":"\u6587\u5B57","style.highlight":"\u9AD8\u4EAE","style.none":"\u65E0","style.connection":"\u8FDE\u7EBF","style.arrow":"\u7BAD\u5934","style.dashed":"\u865A\u7EBF","style.solid":"\u5B9E\u7EBF","style.connection.straight":"\u76F4\u7EBF","style.connection.polyline":"\u6298\u7EBF","style.connection.orthogonal":"\u76F4\u89D2\u6298\u7EBF","style.connection.curve":"\u66F2\u7EBF","style.arrowhead.none":"\u65E0\u7BAD\u5934","style.arrowhead.end":"\u7EC8\u70B9\u7BAD\u5934","style.arrowhead.start":"\u8D77\u70B9\u7BAD\u5934","style.arrowhead.both":"\u53CC\u7BAD\u5934","style.arrowhead.inheritance":"\u7EE7\u627F","style.arrowhead.composition":"\u7EC4\u5408","style.arrowhead.aggregation":"\u805A\u5408","menu.title":"\u9009\u62E9\u65B0\u56FE\u5F62","menu.cancel":"\u70B9\u51FB\u7A7A\u767D\u5904\u53D6\u6D88","shape.rectangle":"\u77E9\u5F62","shape.rounded-rectangle":"\u5706\u89D2","shape.circle":"\u5706\u5F62","shape.ellipse":"\u692D\u5706","shape.diamond":"\u83F1\u5F62","shape.triangle":"\u4E09\u89D2","shape.hexagon":"\u516D\u8FB9\u5F62","shape.parallelogram":"\u5E73\u884C","shape.trapezoid":"\u68AF\u5F62","shape.pentagon":"\u4E94\u8FB9\u5F62","shape.octagon":"\u516B\u8FB9\u5F62","shape.star":"\u661F\u5F62","shape.uml-class":"\u7C7B\u56FE","shape.uml-interface":"\u63A5\u53E3","uml.drag":"\u62D6\u62FD\u6392\u5E8F","uml.delete":"\u5220\u9664\u8BE5\u884C","uml.textColor":"\u6587\u5B57\u989C\u8272","uml.defaultColor":"\u9ED8\u8BA4\u989C\u8272","uml.fontSize":"\u5B57\u53F7","uml.strikethrough":"\u5220\u9664\u7EBF","uml.attribute":"\u5C5E\u6027","uml.method":"\u65B9\u6CD5","minimap.title":"\u5C0F\u5730\u56FE","minimap.expand":"\u5C55\u5F00\u5C0F\u5730\u56FE","minimap.collapse":"\u6536\u8D77\u5C0F\u5730\u56FE","tool.mind-map":"\u601D\u7EF4\u5BFC\u56FE","toolbar.mind-map":"\u601D\u7EF4\u5BFC\u56FE","toolbar.export":"\u5BFC\u51FA","toolbar.export.png":"PNG \u56FE\u7247","toolbar.export.svg":"SVG \u77E2\u91CF\u56FE","toolbar.export.pdf":"PDF \u6587\u6863","shape.mind-map":"\u601D\u7EF4\u5BFC\u56FE","mindmap.defaultRoot":"\u4E2D\u5FC3\u4E3B\u9898","mindmap.defaultBranch":"\u5206\u652F\u4E3B\u9898","mindmap.nodeText":"\u8282\u70B9\u6587\u672C","mindmap.addChild":"\u5B50\u8282\u70B9","mindmap.addSibling":"\u5144\u5F1F\u8282\u70B9","mindmap.deleteNode":"\u5220\u9664\u8282\u70B9","mindmap.color":"\u989C\u8272","mindmap.levelColor":"\u9ED8\u8BA4\u5C42\u7EA7\u8272","mindmap.icon":"\u56FE\u6807","mindmap.noIcon":"\u65E0\u56FE\u6807","mindmap.note":"\u5C5E\u6027\u8BF4\u660E","mindmap.notePlaceholder":"\u8BF4\u660E\u5185\u5BB9\uFF08\u53EF\u9009\uFF09","mindmap.noteColor":"\u8BF4\u660E\u989C\u8272","mindmap.noteColorDefault":"\u540C\u8282\u70B9\u8272","mindmap.collapse":"\u6298\u53E0","mindmap.expand":"\u5C55\u5F00","mindmap.close":"\u5173\u95ED\u7F16\u8F91","mindmap.more":"\u66F4\u591A\u8BBE\u7F6E"},"en-US":{"save.success":"Saved","save.fail":"Save failed","tool.select":"Select tool","tool.hand":"Pan view","tool.rectangle":"Rectangle","tool.rounded-rectangle":"Rounded rectangle","tool.circle":"Circle","tool.ellipse":"Ellipse","tool.diamond":"Diamond","tool.triangle":"Triangle","tool.hexagon":"Hexagon","tool.parallelogram":"Parallelogram","tool.trapezoid":"Trapezoid","tool.pentagon":"Pentagon","tool.octagon":"Octagon","tool.star":"Star","tool.uml-class":"UML class","tool.uml-interface":"UML interface","tool.line":"Line","tool.arrow":"Line","tool.text":"Text","tool.draw":"Pen","tool.pen":"Pen","tool.highlighter":"Highlighter","tool.eraser":"Eraser","status.none":"Nothing selected","status.selected":"{n} shapes selected","toolbar.select":"Select (V)","toolbar.hand":"Pan view (H)","toolbar.shapes":"Shapes","toolbar.grid":"Grid","toolbar.undo":"Undo (Ctrl+Z)","toolbar.redo":"Redo (Ctrl+Shift+Z)","toolbar.arrow":"Arrow","toolbar.text":"Text","toolbar.pen":"Pen","toolbar.highlighter":"Highlighter","toolbar.eraser":"Eraser","toolbar.uml-class":"UML class","toolbar.uml-interface":"UML interface","zoom.in":"Zoom in","zoom.out":"Zoom out","zoom.reset":"Reset","style.stroke":"Border","style.fill":"Fill","style.text":"Text","style.highlight":"Highlight","style.none":"None","style.connection":"Connection","style.arrow":"Arrow head","style.dashed":"Dashed","style.solid":"Solid","style.connection.straight":"Straight","style.connection.polyline":"Polyline","style.connection.orthogonal":"Orthogonal","style.connection.curve":"Curve","style.arrowhead.none":"None","style.arrowhead.end":"End","style.arrowhead.start":"Start","style.arrowhead.both":"Both","style.arrowhead.inheritance":"Inheritance","style.arrowhead.composition":"Composition","style.arrowhead.aggregation":"Aggregation","menu.title":"Create shape","menu.cancel":"Click empty space to cancel","shape.rectangle":"Rectangle","shape.rounded-rectangle":"Rounded","shape.circle":"Circle","shape.ellipse":"Ellipse","shape.diamond":"Diamond","shape.triangle":"Triangle","shape.hexagon":"Hexagon","shape.parallelogram":"Parallelogram","shape.trapezoid":"Trapezoid","shape.pentagon":"Pentagon","shape.octagon":"Octagon","shape.star":"Star","shape.uml-class":"Class","shape.uml-interface":"Interface","uml.drag":"Drag to reorder","uml.delete":"Delete row","uml.textColor":"Text color","uml.defaultColor":"Default color","uml.fontSize":"Font size","uml.strikethrough":"Strikethrough","uml.attribute":"Attributes","uml.method":"Methods","minimap.title":"Minimap","minimap.expand":"Expand minimap","minimap.collapse":"Collapse minimap","tool.mind-map":"Mind map","toolbar.mind-map":"Mind map","toolbar.export":"Export","toolbar.export.png":"PNG image","toolbar.export.svg":"SVG vector","toolbar.export.pdf":"PDF document","shape.mind-map":"Mind map","mindmap.defaultRoot":"Central topic","mindmap.defaultBranch":"Branch topic","mindmap.nodeText":"Node text","mindmap.addChild":"Child","mindmap.addSibling":"Sibling","mindmap.deleteNode":"Delete node","mindmap.color":"Color","mindmap.levelColor":"Default level color","mindmap.icon":"Icon","mindmap.noIcon":"No icon","mindmap.note":"Note","mindmap.notePlaceholder":"Note content (optional)","mindmap.noteColor":"Note color","mindmap.noteColorDefault":"Same as node","mindmap.collapse":"Collapse","mindmap.expand":"Expand","mindmap.close":"Close editor","mindmap.more":"More settings"}},Mt="zh-CN",Lt=new Set;function vt(a){Mt!==a&&(Mt=a,Lt.forEach(t=>t()));}function ge(){return Mt}function pe(a){return Lt.add(a),()=>Lt.delete(a)}function W(a,t){let i=Ft[Mt][a]??Ft["zh-CN"][a];if(t)for(let[n,r]of Object.entries(t))i=i.replace(new RegExp(`\\{${n}\\}`,"g"),String(r));return i}var Nt=["#ef4444","#f59e0b","#10b981","#3b82f6","#8b5cf6","#ec4899"],Z=14,ye=40,fe=80,me=240;function it(a,t){return a.color??Nt[t%Nt.length]}function jt(a){let t=a.text||"",e=0;for(let n of t)e+=/[\u2e80-\u9fff\uf900-\ufaff\uff00-\uffef\u3000-\u303f]/.test(n)?1:.6;let i=Math.max(80,Math.min(240,Math.ceil(e*14)+24));return a.icon&&(i+=26),{width:i,height:40}}function Pt(a){let t={...a};return a.children&&(t.children=a.children.map(e=>Pt(e))),t}function Tt(a,t,e){if(a.id===t)return {...a,...e};let i=a.children??[],n=i.map(r=>Tt(r,t,e));return n.some((r,s)=>r!==i[s])?{...a,children:n}:a}function Rt(a,t,e){if(a.id===t)return {...a,children:[...a.children??[],e],collapsed:false};let i=a.children??[],n=i.map(r=>Rt(r,t,e));return n.some((r,s)=>r!==i[s])?{...a,children:n}:a}function Vt(a,t,e){let i=a.children??[];for(let n=0;n<i.length;n++){if(i[n].id===t){let s=[...i];return s.splice(n+1,0,e),{...a,children:s}}let r=Vt(i[n],t,e);if(r!==i[n])return {...a,children:i.map(s=>s===i[n]?r:s)}}return a}function Ht(a,t){if(a.id===t)return null;let e=a.children??[],i=e.map(n=>Ht(n,t)).filter(n=>n!==null);return i.length!==e.length||i.some((n,r)=>n!==e[r])?{...a,children:i}:a}function q(a,t){if(a.id===t)return a;for(let e of a.children??[]){let i=q(e,t);if(i)return i}return null}function Zt(a,t){if(a.id===t)return 0;for(let e of a.children??[]){let i=Zt(e,t);if(i!==-1)return i+1}return -1}function lt(a,t){for(let e of a.children??[]){if(e.id===t)return a;let i=lt(e,t);if(i)return i}return null}function qt(a){let t=1;for(let e of a.children??[])t+=qt(e);return t}function Jt(a,t){t.set(a.id,jt(a));for(let e of a.children??[])Jt(e,t);}function k(a){let t=new Map;Jt(a,t);let e=new Map,i=c=>{let g=c.collapsed?[]:c.children??[];if(g.length===0)e.set(c.id,t.get(c.id).height);else {let p=0;for(let y of g)p+=i(y);p+=16*(g.length-1),e.set(c.id,Math.max(t.get(c.id).height,p));}return e.get(c.id)};i(a);let n=new Map,r=(c,g,p,y)=>{let f=e.get(c.id),M=t.get(c.id);if(n.set(c.id,{x:p,y:y+f/2,depth:g,width:M.width,height:M.height}),c.collapsed)return;let x=y;for(let v of c.children??[]){let b=t.get(v.id);r(v,g+1,p+M.width/2+48+b.width/2,x),x+=e.get(v.id)+16;}};r(a,0,0,-e.get(a.id)/2);let s=1/0,o=-1/0,h=1/0,l=-1/0;n.forEach(c=>{s=Math.min(s,c.x-c.width/2),o=Math.max(o,c.x+c.width/2),h=Math.min(h,c.y-c.height/2),l=Math.max(l,c.y+c.height/2);});let d=(s+o)/2,u=(h+l)/2;return n.forEach(c=>{c.x-=d,c.y-=u;}),{positions:n,width:o-s,height:l-h}}var xe={strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:2,strokeDash:null},Se={rectangle:{width:120,height:60},"rounded-rectangle":{width:120,height:60,borderRadius:8},circle:{width:80,height:80},ellipse:{width:100,height:70},diamond:{width:100,height:80},triangle:{width:100,height:90},hexagon:{width:100,height:90},parallelogram:{width:120,height:60},trapezoid:{width:120,height:70},pentagon:{width:100,height:90},octagon:{width:100,height:90},star:{width:100,height:100}},_=14,L=22,K=36,B=14,D=8,dt=160,we=["rectangle","rounded-rectangle","circle","ellipse","diamond","triangle","hexagon","parallelogram","trapezoid","pentagon","octagon","star","uml-class","uml-interface","mind-map"];function It(a){return we.includes(a)}function kt(a,t,e){let i=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,n=Se[a]||{width:120,height:60},r=n.width,s=n.height,o=n.radius??r/2,h=n.borderRadius??8,l=e??{...xe};switch(a){case "rounded-rectangle":return {id:i,type:"rounded-rectangle",x:t.x,y:t.y,width:r,height:s,borderRadius:h,rotation:0,style:l};case "circle":return {id:i,type:"circle",x:t.x,y:t.y,radius:o,rotation:0,style:l};case "ellipse":return {id:i,type:"ellipse",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "diamond":return {id:i,type:"diamond",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "triangle":return {id:i,type:"triangle",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "hexagon":return {id:i,type:"hexagon",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "parallelogram":return {id:i,type:"parallelogram",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "trapezoid":return {id:i,type:"trapezoid",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "pentagon":return {id:i,type:"pentagon",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "octagon":return {id:i,type:"octagon",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "star":return {id:i,type:"star",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "uml-class":{let d="ClassName",u=[{id:`attr_${Date.now()}_1`,visibility:"+",name:"field",type:"string"}],c=[{id:`meth_${Date.now()}_1`,visibility:"+",name:"method",params:"param",returnType:"void"}],{width:g,height:p}=Ct(d,u,c);return {id:i,type:"uml-class",x:t.x,y:t.y,width:g,height:p,className:d,attributes:u,methods:c,rotation:0,style:{...l,fillColor:"#ffffff"}}}case "uml-interface":{let d="Interface",u=[{id:`meth_${Date.now()}_1`,visibility:"+",name:"method",params:"type",returnType:"type"}],c=_*.6,g=u.map(x=>`${x.visibility} ${x.name}(${x.params}): ${x.returnType}`),p=Math.max(d.length,...g.map(x=>x.length),0),y=Math.max(dt,p*c+B*2),f=u.length>0?u.length*L+D*2:D*2,M=K+f;return {id:i,type:"uml-interface",x:t.x,y:t.y,width:y,height:M,className:d,methods:u,rotation:0,style:{...l,fillColor:"#ffffff"}}}case "mind-map":{let d=p=>`mm_${p}_${Date.now()}_${Math.random().toString(36).substr(2,6)}`,u={id:d("root"),text:W("mindmap.defaultRoot"),children:[{id:d("b1"),text:W("mindmap.defaultBranch")},{id:d("b2"),text:W("mindmap.defaultBranch")},{id:d("b3"),text:W("mindmap.defaultBranch")}]},{width:c,height:g}=k(u);return {id:i,type:"mind-map",x:t.x,y:t.y,width:c,height:g,root:u,rotation:0,style:{...l,fillColor:"#ffffff"}}}default:return {id:i,type:"rectangle",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l}}}function Ct(a,t,e){let i=_*.6,n=[a];for(let u of t)n.push(`${u.visibility} ${u.name}: ${u.type}`);for(let u of e)n.push(`${u.visibility} ${u.name}(${u.params}): ${u.returnType}`);let s=Math.max(...n.map(u=>u.length),0)*i+B*2,o=Math.max(dt,s),h=t.length>0?t.length*L+D*2:D*2,l=e.length>0?e.length*L+D*2:D*2,d=K+h+l;return {width:o,height:d}}var V=class extends H{type;constructor(t,e){super(t),this.type=e;}onPointerDown(t,e){let i=kt(this.type,t);this.context.commitHistory(),this.context.addShape(i),this.context.selectShape(i.id,false);}onPointerMove(t,e){}onPointerUp(t,e){this.context.setActiveTool("select");}onKeyDown(t){}onKeyUp(t){}getCursor(t){return this.context.getMindMapCursorHitAtPoint(t)?"pointer":"crosshair"}};var Bt=14,Et=class extends H{type="eraser";erasing=false;lastPoint=null;erasedIds=new Set;onPointerDown(t){this.erasing=true,this.lastPoint=t,this.erasedIds.clear(),this.context.commitHistory(),this.context.setEraserPoint(t),this.eraseAt(t);}onPointerMove(t){if(!this.erasing||!this.lastPoint)return;let e=this.lastPoint,i=Math.hypot(t.x-e.x,t.y-e.y),n=Math.max(1,Math.ceil(i/Math.max(this.brushRadius()*.5,1)));for(let r=1;r<=n;r++){let s=r/n;this.eraseAt({x:e.x+(t.x-e.x)*s,y:e.y+(t.y-e.y)*s});}this.lastPoint=t,this.context.setEraserPoint(t);}onPointerUp(){this.erasing=false,this.lastPoint=null,this.erasedIds.clear(),this.context.setEraserPoint(null);}onKeyDown(){}onKeyUp(){}getCursor(){return this.erasing?"grabbing":"crosshair"}dispose(){this.erasing=false,this.lastPoint=null,this.erasedIds.clear(),this.context.setEraserPoint(null);}brushRadius(){return Bt/this.context.getCamera().getZoom()}eraseAt(t){let e=this.context.getShapesInBrushRadius(t,this.brushRadius());for(let i of e)this.erasedIds.has(i.id)||(this.erasedIds.add(i.id),this.context.deleteShape(i.id));}};var st=class a{ctx;width=0;height=0;dpr=window.devicePixelRatio||1;showGrid=false;textLayoutCache=new Map;static TEXT_CACHE_LIMIT=500;constructor(t,e){let i=t.getContext("2d");if(!i)throw new Error("Failed to get Canvas 2D context");this.ctx=i,typeof e=="number"&&e>0&&(this.dpr=e);}resize(t,e){this.width=t,this.height=e;let i=Math.ceil(t*this.dpr),n=Math.ceil(e*this.dpr);(this.ctx.canvas.width!==i||this.ctx.canvas.height!==n)&&(this.ctx.canvas.width=i,this.ctx.canvas.height=n,this.ctx.canvas.style.width=`${t}px`,this.ctx.canvas.style.height=`${e}px`);}setShowGrid(t){this.showGrid=t;}render(t,e,i,n,r,s,o,h,l,d,u){let c=this.ctx,g=e.getZoom(),p=e.x,y=e.y;c.setTransform(1,0,0,1,0,0),c.clearRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height),u&&(c.fillStyle=u,c.fillRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height));let f=this.dpr*g;c.setTransform(f,0,0,f,f*p,f*y),this.showGrid&&this.drawGrid(c,g,p,y);let M=null;for(let v of t)if(v.type==="arrow"&&(v.startBinding||v.endBinding)){M=new Map,t.forEach(b=>M.set(b.id,b));break}let x=M??new Map;t.forEach(v=>{c.save(),c.translate(v.x,v.y),c.rotate(v.rotation);let b=i.has(v.id);this.drawShape(c,v,b,g,x,l,d),c.restore();}),o&&this.drawGenerationPreview(c,o,g),n&&this.drawBrushRect(c,n,g),r&&r.length>0&&this.drawSnapGuides(c,r,g),s&&this.drawConnectingTargetHighlight(c,s,t,g),h&&this.drawEraserBrush(c,h,g),c.setTransform(1,0,0,1,0,0);}drawEraserBrush(t,e,i){let n=Bt/i;t.beginPath(),t.arc(e.x,e.y,n,0,Math.PI*2),t.fillStyle=nt(I.primary,.12),t.fill(),t.strokeStyle=nt(I.primary,.55),t.lineWidth=1.5/i,t.stroke();}drawConnectingTargetHighlight(t,e,i,n){let r=i.find(l=>l.id===e);if(!r||r.type==="line"||r.type==="arrow"||r.type==="draw")return;let s=this.getShapeWorldBounds(r),o=[{x:s.x+s.width/2,y:s.y},{x:s.x+s.width,y:s.y+s.height/2},{x:s.x+s.width/2,y:s.y+s.height},{x:s.x,y:s.y+s.height/2}],h=6/n;t.save(),o.forEach(l=>{t.beginPath(),t.arc(l.x,l.y,h,0,Math.PI*2),t.fillStyle=I.selection.handleFill,t.fill(),t.strokeStyle=I.primary,t.lineWidth=2/n,t.stroke();}),t.restore();}getShapeWorldBounds(t){let e=this.getShapeBounds(t);return {x:t.x+e.x,y:t.y+e.y,width:e.width,height:e.height}}drawBrushRect(t,e,i){t.save(),t.fillStyle=I.brushFill,t.strokeStyle=I.brushStroke,t.lineWidth=1.5/i,t.setLineDash([4/i,4/i]),t.beginPath(),t.rect(e.x,e.y,e.width,e.height),t.fill(),t.stroke(),t.restore();}drawGrid(t,e,i,n){let r=-i,s=-n,o=r+this.width/e,h=s+this.height/e,l=20;for(;l*e<10;)l*=2;t.strokeStyle=I.grid,t.lineWidth=1/e,t.beginPath();for(let d=Math.floor(r/l)*l;d<=o;d+=l)t.moveTo(d,s),t.lineTo(d,h);for(let d=Math.floor(s/l)*l;d<=h;d+=l)t.moveTo(r,d),t.lineTo(o,d);t.stroke();}drawShape(t,e,i,n,r,s,o){switch(this.applyStyle(t,e.style,n),e.type){case "rectangle":this.drawRectangle(t,e,i);break;case "rounded-rectangle":this.drawRoundedRectangle(t,e,i);break;case "circle":this.drawCircle(t,e,i);break;case "ellipse":this.drawEllipse(t,e,i);break;case "diamond":this.drawDiamond(t,e,i);break;case "triangle":this.drawTriangle(t,e,i);break;case "hexagon":this.drawHexagon(t,e,i);break;case "parallelogram":this.drawParallelogram(t,e,i);break;case "trapezoid":this.drawTrapezoid(t,e,i);break;case "pentagon":this.drawPentagon(t,e,i);break;case "octagon":this.drawOctagon(t,e,i);break;case "star":this.drawStar(t,e,i);break;case "uml-class":this.drawUmlClass(t,e,i);break;case "uml-interface":this.drawUmlInterface(t,e,i);break;case "mind-map":this.drawMindMap(t,e,i,s,o);break;case "line":this.drawLine(t,e,r,i,n);break;case "arrow":this.drawArrow(t,e,r,i,n);break;case "text":this.drawText(t,e);break;case "draw":this.drawFreehand(t,e);break}if(e.text&&e.type!=="text"&&e.type!=="line"&&e.type!=="arrow"&&e.type!=="draw"&&this.drawShapeText(t,e),i){let h=e.type==="line"||e.type==="arrow"||e.type==="draw";e.type==="mind-map"||(h?this.drawSelectionHandles(t,e,n):(this.drawSelectionOutline(t,e,n),this.drawSelectionHandles(t,e,n)));}}applyStyle(t,e,i){t.strokeStyle=e.strokeColor,t.fillStyle=e.fillColor,t.lineWidth=e.strokeWidth/i,t.lineCap="round",t.lineJoin="round",e.strokeDash?t.setLineDash(e.strokeDash):t.setLineDash([]);}drawRectangle(t,e,i){t.beginPath(),t.rect(-e.width/2,-e.height/2,e.width,e.height),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawRoundedRectangle(t,e,i){let{width:n,height:r,borderRadius:s}=e;t.beginPath(),t.roundRect(-n/2,-r/2,n,r,s),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawCircle(t,e,i){t.beginPath(),t.arc(0,0,e.radius,0,Math.PI*2),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawEllipse(t,e,i){t.beginPath(),t.ellipse(0,0,e.width/2,e.height/2,0,0,Math.PI*2),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawDiamond(t,e,i){t.beginPath(),t.moveTo(0,-e.height/2),t.lineTo(e.width/2,0),t.lineTo(0,e.height/2),t.lineTo(-e.width/2,0),t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawTriangle(t,e,i){t.beginPath(),t.moveTo(0,-e.height/2),t.lineTo(e.width/2,e.height/2),t.lineTo(-e.width/2,e.height/2),t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawHexagon(t,e,i){let n=e.width/2,r=e.height/2;t.beginPath();for(let s=0;s<6;s++){let o=s*Math.PI/3-Math.PI/2,h=n*Math.cos(o),l=r*Math.sin(o);s===0?t.moveTo(h,l):t.lineTo(h,l);}t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawParallelogram(t,e,i){let{width:n,height:r}=e,s=n*.2;t.beginPath(),t.moveTo(-n/2+s,-r/2),t.lineTo(n/2,-r/2),t.lineTo(n/2-s,r/2),t.lineTo(-n/2,r/2),t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawTrapezoid(t,e,i){let{width:n,height:r}=e,s=n*.15;t.beginPath(),t.moveTo(-n/2+s,-r/2),t.lineTo(n/2-s,-r/2),t.lineTo(n/2,r/2),t.lineTo(-n/2,r/2),t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawPentagon(t,e,i){let n=e.width/2,r=e.height/2;t.beginPath();for(let s=0;s<5;s++){let o=s*2*Math.PI/5-Math.PI/2,h=n*Math.cos(o),l=r*Math.sin(o);s===0?t.moveTo(h,l):t.lineTo(h,l);}t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawOctagon(t,e,i){let n=e.width/2,r=e.height/2;t.beginPath();for(let s=0;s<8;s++){let o=s*Math.PI/4-Math.PI/8,h=n*Math.cos(o),l=r*Math.sin(o);s===0?t.moveTo(h,l):t.lineTo(h,l);}t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawStar(t,e,i){let n=e.width/2,r=e.height/2,s=5,o=.4;t.beginPath();for(let h=0;h<s*2;h++){let l=h*Math.PI/s-Math.PI/2,d=h%2===0?1:o,u=n*d*Math.cos(l),c=r*d*Math.sin(l);h===0?t.moveTo(u,c):t.lineTo(u,c);}t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawUmlClass(t,e,i){let{width:n,height:r,className:s,attributes:o,methods:h}=e,l=n/2,d=r/2,u=K,c=o.length>0?o.length*L+D*2:D*2;t.beginPath(),t.rect(-l,-d,n,r),e.style.fillColor!=="transparent"&&(t.fillStyle=e.style.fillColor,t.fill()),t.stroke(),t.beginPath(),t.moveTo(-l,-d+u),t.lineTo(l,-d+u),t.moveTo(-l,-d+u+c),t.lineTo(l,-d+u+c),t.stroke(),t.save(),t.textBaseline="middle";let g=n-B*2,p=x=>{if(t.measureText(x).width<=g)return x;let v="\u2026",b=0,P=x.length;for(;b<P;){let T=b+P+1>>1;t.measureText(x.slice(0,T)+v).width<=g?b=T:P=T-1;}return x.slice(0,b)+v},y=(x,v,b,P,T,E,U)=>{let Y=P||_,F=T||"#1f2937";t.font=`${Y}px sans-serif`,t.fillStyle=F,t.textAlign=U;let N=p(x);if(t.fillText(N,v,b),E){let R=t.measureText(N).width,St=v;t.strokeStyle=F,t.beginPath(),t.moveTo(St,b),t.lineTo(St+R,b),t.stroke();}};t.font=`bold ${e.fontSize||_}px sans-serif`,t.textAlign="center",t.fillStyle=e.textColor||"#1f2937",t.fillText(p(s),0,-d+u/2);let f=-d+u+D+L/2;o.forEach((x,v)=>{let b=`${x.visibility} ${x.name}: ${x.type}`;y(b,-l+B,f+v*L,x.fontSize||e.fontSize||0,x.textColor||e.textColor||"",!!x.strikethrough,"left");});let M=-d+u+c+D+L/2;h.forEach((x,v)=>{let b=`${x.visibility} ${x.name}(${x.params}): ${x.returnType}`;y(b,-l+B,M+v*L,x.fontSize||e.fontSize||0,x.textColor||e.textColor||"",!!x.strikethrough,"left");}),t.restore();}drawUmlInterface(t,e,i){let{width:n,height:r,className:s,methods:o}=e,h=n/2,l=r/2,d=K;t.beginPath(),t.rect(-h,-l,n,r),e.style.fillColor!=="transparent"&&(t.fillStyle=e.style.fillColor,t.fill()),t.stroke(),t.beginPath(),t.moveTo(-h,-l+d),t.lineTo(h,-l+d),t.stroke(),t.save(),t.textBaseline="middle";let u=n-B*2,c=f=>{if(t.measureText(f).width<=u)return f;let M="\u2026",x=0,v=f.length;for(;x<v;){let b=x+v+1>>1;t.measureText(f.slice(0,b)+M).width<=u?x=b:v=b-1;}return f.slice(0,x)+M},g=(f,M,x,v,b,P,T)=>{let E=v||_,U=b||"#1f2937";t.font=`${E}px sans-serif`,t.fillStyle=U,t.textAlign=T;let Y=c(f);if(t.fillText(Y,M,x),P){let F=t.measureText(Y).width,N=M;t.strokeStyle=U,t.beginPath(),t.moveTo(N,x),t.lineTo(N+F,x),t.stroke();}};t.font=`bold ${e.fontSize||_}px sans-serif`,t.textAlign="center",t.fillStyle=e.textColor||"#1f2937";let p=`<<${s||"Interface"}>>`;t.fillText(c(p),0,-l+d/2);let y=-l+d+D+L/2;o.forEach((f,M)=>{let x=`${f.visibility} ${f.name}(${f.params}): ${f.returnType}`;g(x,-h+B,y+M*L,f.fontSize||e.fontSize||0,f.textColor||e.textColor||"",!!f.strikethrough,"left");}),t.restore();}static DEFAULT_CORNER_RADIUS=10;static ROUTE_CLEARANCE=30;static CONNECTION_LEAD=24;static CONNECTED_PAD=8;drawMindMap(t,e,i,n,r){let o=k(e.root).positions;this.drawMindMapConnections(t,e.root,o),this.drawMindMapNodes(t,e,o,n,r);}drawMindMapConnections(t,e,i){let n=r=>{if(r.collapsed)return;let s=i.get(r.id);if(s)for(let o of r.children??[]){let h=i.get(o.id);if(!h)continue;let l=it(o,h.depth);t.strokeStyle=l,t.lineWidth=2,t.lineCap="round",t.beginPath(),t.moveTo(s.x+s.width/2,s.y);let d=(s.x+s.width/2+(h.x-h.width/2))/2;t.bezierCurveTo(d,s.y,d,h.y,h.x-h.width/2,h.y),t.stroke(),n(o);}};n(e);}drawMindMapNodes(t,e,i,n,r){let s=e.root,o=h=>{let l=i.get(h.id);if(!l)return;let d=it(h,l.depth),u=l.width/2,c=l.height/2;if(t.fillStyle="#ffffff",t.strokeStyle=d,t.lineWidth=2,t.beginPath(),t.roundRect(l.x-u,l.y-c,l.width,l.height,6),t.fill(),t.stroke(),r&&r.shapeId===e.id&&r.nodeId===h.id&&(t.fillStyle=nt(I.primary,.06),t.strokeStyle=nt(I.primary,.55),t.lineWidth=2,t.beginPath(),t.roundRect(l.x-u,l.y-c,l.width,l.height,6),t.fill(),t.stroke()),n&&n.shapeId===e.id&&n.nodeId===h.id&&(t.fillStyle=nt(I.primary,.12),t.strokeStyle=I.primary,t.lineWidth=2.5,t.beginPath(),t.roundRect(l.x-u,l.y-c,l.width,l.height,6),t.fill(),t.stroke()),h.children&&h.children.length>0&&(t.fillStyle="#ffffff",t.strokeStyle=d,t.lineWidth=2,t.beginPath(),t.arc(l.x+u+10,l.y,8,0,Math.PI*2),t.fill(),t.stroke(),t.fillStyle=d,t.font="bold 13px sans-serif",t.textAlign="center",t.textBaseline="middle",t.fillText(h.collapsed?"+":"\u2212",l.x+u+10,l.y+.5)),h.note){let T=h.noteColor??d;t.font="11px sans-serif";let E=Math.min(t.measureText(h.note).width+12,130),U=16;t.fillStyle=T,t.beginPath(),t.roundRect(l.x-u,l.y-c-U+2,E,U,4),t.fill(),t.fillStyle="#ffffff",t.font="11px sans-serif",t.textAlign="left",t.textBaseline="middle",t.fillText(t.measureText(h.note).width+12>130?h.note.slice(0,12)+"\u2026":h.note,l.x-u+6,l.y-c-U/2+2);}t.font=`${14}px sans-serif`;let f=h.icon?18:0,M=l.width-f-(h.icon?8:0)-16,x=this.ellipsizeText(t,h.text||"",M),v=t.measureText(x).width,b=f+(f?8:0)+v,P=l.x-b/2;if(t.textBaseline="middle",h.icon&&(t.font="16px sans-serif",t.textAlign="left",t.fillStyle="#1f2937",t.fillText(h.icon,P,l.y+1),P+=f+8),t.font=`${14}px sans-serif`,t.textAlign="left",t.fillStyle="#1f2937",t.fillText(x,P,l.y),!h.collapsed)for(let T of h.children??[])o(T);};o(s);}ellipsizeText(t,e,i){if(i<=0)return "";if(t.measureText(e).width<=i)return e;let n="\u2026",r=0,s=e.length;for(;r<s;){let o=r+s+1>>1;t.measureText(e.slice(0,o)+n).width<=i?r=o:s=o-1;}return e.slice(0,r)+n}drawLine(t,e,i,n,r){if(e.points.length<2)return;let s=e.points.map(d=>({x:d.x,y:d.y}));s.length>=2&&(s[0]=this.clampToShapeOutline(s[0],i,e.id,s[s.length-1]),s[s.length-1]=this.clampToShapeOutline(s[s.length-1],i,e.id,s[0]));let o=s.map(d=>({x:d.x-e.x,y:d.y-e.y})),h=e.connectionType||"straight",l=h==="straight"?this.getAlignedPoints(o):this.buildPathPoints(o,h,this.collectRoutingObstacles(e.id,o[0],o[o.length-1],i,{x:e.x,y:e.y}),{fromN:this.getDockNormal(s[0],i,e.id),toN:this.getDockNormal(s[s.length-1],i,e.id)});if(h==="straight"){t.beginPath(),t.moveTo(o[0].x,o[0].y);for(let d=1;d<o.length;d++)t.lineTo(o[d].x,o[d].y);t.stroke(),t.setLineDash([]);}else h==="orthogonal"?this.drawSharpPolyline(t,l):this.drawRoundedPolyline(t,l,a.DEFAULT_CORNER_RADIUS),t.stroke(),t.setLineDash([]);n&&this.drawLinearHighlight(t,l,r);}drawArrow(t,e,i,n,r){if(e.points.length<2)return;let s=e.points.map(c=>({x:c.x,y:c.y}));if(e.startBinding){let c=i.get(e.startBinding.toShapeId);c&&(s[0]=this.getBindingPoint(c,e.startBinding));}if(e.endBinding){let c=i.get(e.endBinding.toShapeId);c&&(s[s.length-1]=this.getBindingPoint(c,e.endBinding));}s[0]=this.clampToShapeOutline(s[0],i,e.id,s[s.length-1]),s[s.length-1]=this.clampToShapeOutline(s[s.length-1],i,e.id,s[0]);let o=s.map(c=>({x:c.x-e.x,y:c.y-e.y})),h=e.connectionType||"straight",l=e.arrowHead??"end";!!e.dashed?t.setLineDash([8,5]):t.setLineDash([]);let u;if(h==="straight"){let c=this.getAlignedPoints(o);u=c,t.beginPath(),t.moveTo(c[0].x,c[0].y);for(let g=1;g<c.length;g++)t.lineTo(c[g].x,c[g].y);t.stroke(),this.drawArrowHeads(t,c,l);}else u=this.buildPathPoints(o,h,this.collectRoutingObstacles(e.id,o[0],o[o.length-1],i,{x:e.x,y:e.y}),{fromN:this.getDockNormal(s[0],i,e.id),toN:this.getDockNormal(s[s.length-1],i,e.id)}),h==="orthogonal"?this.drawSharpPolyline(t,u):this.drawRoundedPolyline(t,u,a.DEFAULT_CORNER_RADIUS),t.stroke(),this.drawArrowHeads(t,u,l);t.setLineDash([]),n&&this.drawLinearHighlight(t,u,r);}drawLinearHighlight(t,e,i){if(!(!e||e.length<2)){t.save(),t.strokeStyle=I.lineHighlight,t.lineWidth=7/i,t.lineCap="round",t.lineJoin="round",t.setLineDash([]),t.beginPath(),t.moveTo(e[0].x,e[0].y);for(let n=1;n<e.length;n++)t.lineTo(e[n].x,e[n].y);t.stroke(),t.restore();}}drawGenerationPreview(t,e,i){let{from:n,to:r,type:s}=e;t.save(),t.beginPath(),t.arc(n.x,n.y,7/i,0,Math.PI*2),t.fillStyle=I.genDot,t.fill(),t.strokeStyle=I.genLine,t.lineWidth=2/i,t.setLineDash([5/i,4/i]),t.lineCap="round",t.beginPath(),t.moveTo(n.x,n.y),t.lineTo(r.x,r.y),t.stroke(),s&&this.drawPreviewShapeOutline(t,r,s,i),t.restore();}drawPreviewShapeOutline(t,e,i,n){let l=e.x,d=e.y;switch(t.strokeStyle=I.genLine,t.lineWidth=1.5/n,t.setLineDash([6/n,4/n]),t.beginPath(),i){case "circle":case "ellipse":t.ellipse(l,d,i==="circle"?40:120/2,i==="circle"?40:60/2,0,0,Math.PI*2);break;case "diamond":t.moveTo(l,d-30),t.lineTo(l+60,d),t.lineTo(l,d+30),t.lineTo(l-60,d),t.closePath();break;case "triangle":t.moveTo(l,d-30),t.lineTo(l+60,d+30),t.lineTo(l-60,d+30),t.closePath();break;case "hexagon":for(let u=0;u<6;u++){let c=u*Math.PI/3-Math.PI/2,g=l+60*Math.cos(c),p=d+30*Math.sin(c);u===0?t.moveTo(g,p):t.lineTo(g,p);}t.closePath();break;case "parallelogram":t.moveTo(l-60+18,d-30),t.lineTo(l+60,d-30),t.lineTo(l+60-18,d+30),t.lineTo(l-60,d+30),t.closePath();break;default:t.roundRect(l-60,d-30,120,60,i==="rounded-rectangle"?8:4);break}t.stroke();}static ALIGN_TOLERANCE=8;getAlignedPoints(t){if(t.length<2)return t;let e=t[0],i=t[t.length-1],n=i.x-e.x,r=i.y-e.y,s=a.ALIGN_TOLERANCE;if(Math.abs(r)<=s){let o=(e.y+i.y)/2;return t.map(h=>({x:h.x,y:o}))}if(Math.abs(n)<=s){let o=(e.x+i.x)/2;return t.map(h=>({x:o,y:h.y}))}return t}buildPathPoints(t,e,i=[],n={}){if(t.length<2||e==="straight")return t;switch(e){case "polyline":return this.generatePolylinePoints(t,i,n);case "orthogonal":return this.generateOrthogonalPoints(t,i,n);case "curve":return this.generateCurvePoints(t);default:return t}}drawRoundedPolyline(t,e,i){if(t.beginPath(),!(e.length<2)){if(e.length===2||i<=0){t.moveTo(e[0].x,e[0].y);for(let n=1;n<e.length;n++)t.lineTo(e[n].x,e[n].y);return}t.moveTo(e[0].x,e[0].y);for(let n=1;n<e.length-1;n++){let r=e[n-1],s=e[n],o=e[n+1],h=s.x-r.x,l=s.y-r.y,d=o.x-s.x,u=o.y-s.y,c=Math.hypot(h,l),g=Math.hypot(d,u);if(c<1e-6||g<1e-6){t.lineTo(s.x,s.y);continue}let p=Math.min(i,c*.5,g*.5),y=s.x-h/c*p,f=s.y-l/c*p,M=s.x+d/g*p,x=s.y+u/g*p;t.lineTo(y,f),t.arcTo(s.x,s.y,M,x,p);}t.lineTo(e[e.length-1].x,e[e.length-1].y);}}drawSharpPolyline(t,e){if(t.beginPath(),!(e.length<2)){t.moveTo(e[0].x,e[0].y);for(let i=1;i<e.length;i++)t.lineTo(e[i].x,e[i].y);}}drawSnapGuides(t,e,i){t.save(),t.strokeStyle=I.guide,t.lineWidth=1/i,t.setLineDash([6/i,4/i]),t.beginPath();for(let n of e)n.type==="horizontal"?(t.moveTo(n.start,n.position),t.lineTo(n.end,n.position)):(t.moveTo(n.position,n.start),t.lineTo(n.position,n.end));t.stroke(),t.restore();}generatePolylinePoints(t,e=[],i={}){if(t.length<2)return t;let n=[];n.push(t[0]);let r=t.length-1,s=a.CONNECTION_LEAD;for(let o=1;o<t.length;o++){let h=t[o-1],l=t[o],d=o===1,u=o===r,c=d&&i.fromN?{x:h.x+i.fromN.x*s,y:h.y+i.fromN.y*s}:h,g=u&&i.toN?{x:l.x+i.toN.x*s,y:l.y+i.toN.y*s}:l;d&&i.fromN&&n.push(c);let p=this.computeOrthogonalRoute(c,g,e);for(let y of p)n.push(y);u&&i.toN&&n.push(l);}return this.collapseLinePoints(n)}generateOrthogonalPoints(t,e=[],i={}){return this.generatePolylinePoints(t,e,i)}collapseLinePoints(t){let e=[];for(let i of t){let n=e.length;if(!(n>0&&Math.abs(e[n-1].x-i.x)<1e-6&&Math.abs(e[n-1].y-i.y)<1e-6)){if(n>=2){let r=e[n-2],s=e[n-1];if(Math.abs(r.y-s.y)<1e-6&&Math.abs(s.y-i.y)<1e-6||Math.abs(r.x-s.x)<1e-6&&Math.abs(s.x-i.x)<1e-6){e[n-1]=i;continue}}e.push(i);}}return e}computeOrthogonalRoute(t,e,i=[]){let n=e.x-t.x,r=e.y-t.y;if(Math.abs(n)<1||Math.abs(r)<1)return [e];let s=t.x+n/2,o=t.y+r/2,h=i.length>0,l=[[{x:s,y:t.y},{x:s,y:e.y},e],[{x:t.x,y:o},{x:e.x,y:o},e],[{x:e.x,y:t.y},e],[{x:t.x,y:e.y},e]];if(h){for(let u of l)if(!this.routeHitsObstacles(t,u,i))return u;let d=this.routeOrthogonalAvoidance(t,e,i);return d&&d.length>0?d:i.length>0&&!this.routeHitsObstacles(t,l[0],i)?l[0]:this.routeHitsObstacles(t,l[1],i)?[e]:l[1]}return Math.abs(n)>=Math.abs(r)?[{x:s,y:t.y},{x:s,y:e.y},e]:[{x:t.x,y:o},{x:e.x,y:o},e]}collectRoutingObstacles(t,e,i,n,r){if(!n||n.size===0)return [];let s=[];return n.forEach((o,h)=>{if(h===t)return;let l=this.getShapeBounds(o),d={x:o.x+l.x-r.x,y:o.y+l.y-r.y,width:l.width,height:l.height};d.pad=this.pointInRect(e,d)||this.pointInRect(i,d)?a.CONNECTED_PAD:a.ROUTE_CLEARANCE,s.push(d);}),s}pointInRect(t,e){return t.x>=e.x&&t.x<=e.x+e.width&&t.y>=e.y&&t.y<=e.y+e.height}routeHitsObstacles(t,e,i){let n=[t,...e];for(let r=1;r<n.length;r++)if(this.segmentHitsObstacle(n[r-1],n[r],i))return true;return false}segmentHitsObstacle(t,e,i){for(let n of i){let r=n.pad??a.ROUTE_CLEARANCE,s=n.y-r,o=n.y+n.height+r,h=n.x-r,l=n.x+n.width+r;if(Math.abs(t.y-e.y)<.5){if(t.y>=s&&t.y<=o){let d=Math.min(t.x,e.x);if(Math.max(t.x,e.x)>=h&&d<=l)return true}}else if(t.x>=h&&t.x<=l){let d=Math.min(t.y,e.y);if(Math.max(t.y,e.y)>=s&&d<=o)return true}}return false}routeOrthogonalAvoidance(t,e,i){let n=new Set([t.x,e.x]),r=new Set([t.y,e.y]);for(let S of i){let w=S.pad??a.ROUTE_CLEARANCE;n.add(S.x-w),n.add(S.x+S.width+w),r.add(S.y-w),r.add(S.y+S.height+w);}let s=[...n].sort((S,w)=>S-w),o=[...r].sort((S,w)=>S-w),h=s.length,l=o.length,d=S=>{for(let w=0;w<h;w++)if(Math.abs(s[w]-S)<1e-6)return w;return 0},u=S=>{for(let w=0;w<l;w++)if(Math.abs(o[w]-S)<1e-6)return w;return 0},c=d(t.x),g=u(t.y),p=d(e.x),y=u(e.y),f=[],M=[];for(let S=0;S<h;S++)f.push(new Array(l).fill(true)),M.push(new Array(l).fill(true));for(let S of i){let w=S.pad??a.ROUTE_CLEARANCE,C=S.x-w,$=S.x+S.width+w,G=S.y-w,z=S.y+S.height+w;for(let A=0;A<h-1;A++)if(!(s[A+1]<=C||s[A]>=$))for(let X=0;X<l;X++)o[X]>G&&o[X]<z&&(f[A][X]=false);for(let A=0;A<l-1;A++)if(!(o[A+1]<=G||o[A]>=z))for(let X=0;X<h;X++)s[X]>C&&s[X]<$&&(M[X][A]=false);}let x=h*l,v=1/0,b=new Float64Array(x).fill(v),P=new Int32Array(x).fill(-1),T=new Uint8Array(x),E=S=>{let w=S%h,C=S/h|0;return Math.abs(s[w]-e.x)+Math.abs(o[C]-e.y)},U=(S,w)=>S%h===w%h,Y=g*h+c,F=y*h+p;b[Y]=0;let N=[Y],R=[E(Y)],St=S=>{let w=b[S]+E(S);N.push(S),R.push(w);let C=N.length-1;for(;C>0;){let $=C-1>>1;if(R[$]<=R[C])break;[N[$],N[C]]=[N[C],N[$]],[R[$],R[C]]=[R[C],R[$]],C=$;}},le=()=>{let S=N[0],w=N.pop(),C=R.pop();if(N.length){N[0]=w,R[0]=C;let $=0;for(;;){let G=$*2+1,z=G+1,A=$;if(G<N.length&&R[G]<R[A]&&(A=G),z<N.length&&R[z]<R[A]&&(A=z),A===$)break;[N[A],N[$]]=[N[$],N[A]],[R[A],R[$]]=[R[$],R[A]],$=A;}}return S},wt=(S,w,C)=>{let $=S%h,G=w%h,z=b[S]+(Math.abs(G-$)===0?Math.abs(o[w/h|0]-o[S/h|0]):Math.abs(s[G]-s[$]))+C;z<b[w]&&(b[w]=z,P[w]=S,T[w]||St(w));};for(;N.length;){let S=le();if(S===F||T[S]){if(S===F)break;continue}T[S]=1;let w=S%h,C=S/h|0,$=P[S],G=$>=0?U($,S)?"v":"h":"",z=A=>{let X=U(S,A)?"v":"h";return G!==""&&G!==X?24:0};w+1<h&&f[w][C]&&wt(S,C*h+w+1,z(C*h+w+1)),w-1>=0&&f[w-1][C]&&wt(S,C*h+w-1,z(C*h+w-1)),C+1<l&&M[w][C]&&wt(S,(C+1)*h+w,z((C+1)*h+w)),C-1>=0&&M[w][C-1]&&wt(S,(C-1)*h+w,z((C-1)*h+w));}if(b[F]===v)return null;let Dt=[];for(let S=F;S!==-1;S=P[S])Dt.push({x:s[S%h],y:o[S/h|0]});Dt.reverse();let ot=[];for(let S of Dt){let w=ot.length;if(w>=2){let C=ot[w-2],$=ot[w-1];if(Math.abs(C.y-$.y)<1e-6&&Math.abs($.y-S.y)<1e-6||Math.abs(C.x-$.x)<1e-6&&Math.abs($.x-S.x)<1e-6){ot[w-1]=S;continue}}ot.push(S);}return ot.slice(1)}generateCurvePoints(t){if(t.length<2)return t;let e=[],i=20,n=t[0],r=n;e.push(n);for(let s=1;s<t.length;s++){let o=t[s],h=this.computeCurveControlPoint(r,o);for(let l=1;l<=i;l++){let d=l/i,u=(1-d)*(1-d)*r.x+2*(1-d)*d*h.x+d*d*o.x,c=(1-d)*(1-d)*r.y+2*(1-d)*d*h.y+d*d*o.y;e.push({x:u,y:c});}r=o;}return e}computeCurveControlPoint(t,e){let i=e.x-t.x,n=e.y-t.y,r=Math.sqrt(i*i+n*n);if(r<1)return {x:t.x,y:t.y};let s=(t.x+e.x)/2,o=(t.y+e.y)/2,h=-n/r,l=i/r,d=Math.min(r*.2,30);return {x:s+h*d,y:o+l*d}}getDisplayLines(t,e,i,n,r,s){let o=n*1.3,h=Math.max(1,Math.floor(s/o)),l=`${e.id}\0${i}\0${n}\0${r}x${s}\0${h}`,d=this.textLayoutCache.get(l);if(d)return d;let u=i.split(`
|
|
2
|
-
`),c=[];for(let p of u){let y=this.wrapLine(t,p,r);for(let f of y)c.push(f);}let g=c.slice(0,h);return c.length>h&&g.length>0&&(g[g.length-1]=this.truncateLine(t,g[g.length-1],r)),this.textLayoutCache.size>=a.TEXT_CACHE_LIMIT&&this.textLayoutCache.clear(),this.textLayoutCache.set(l,g),g}drawShapeText(t,e){let i=e.text||"";if(!i)return;let n=e.fontSize||16;t.font=`${n}px sans-serif`,t.fillStyle=e.textColor||"#1f2937";let r=this.getTextBounds(e),s=n*1.3,o=this.getDisplayLines(t,e,i,n,r.width,r.height),l=-(o.length*s)/2+s/2;t.textAlign="center",t.textBaseline="middle",o.forEach((d,u)=>{let c=l+u*s;t.fillText(d,0,c);});}getTextBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":return {width:t.width*.85,height:t.height*.85};case "circle":return {width:t.radius*2*.85,height:t.radius*2*.85};default:return {width:100,height:40}}}wrapLine(t,e,i){if(!e)return [""];let n=[],r="";for(let s of e){let o=r+s;t.measureText(o).width>i&&r?(n.push(r),r=s):r=o;}return r&&n.push(r),n}truncateLine(t,e,i){if(!e)return "...";let n="...",r=e;for(;r.length>0&&t.measureText(r+n).width>i;)r=r.slice(0,-1);return r+n}getBindingPoint(t,e){if(e.isPrecise&&e.normalizedAnchor){let i=this.getShapePageBounds(t),n={x:i.x+i.width*e.normalizedAnchor.x,y:i.y+i.height*e.normalizedAnchor.y},r={x:t.x,y:t.y};return this.nearestPointOnShapeOutline(t,r,n)}if(e.handle){let i=this.getShapeBounds(t);switch(e.handle){case "top":return {x:t.x,y:t.y+i.y};case "bottom":return {x:t.x,y:t.y+i.y+i.height};case "left":return {x:t.x+i.x,y:t.y};case "right":return {x:t.x+i.x+i.width,y:t.y}}}return {x:t.x,y:t.y}}getDockNormal(t,e,i){if(!e||e.size===0)return;let n=null,r=1/0,s=.5;if(e.forEach((d,u)=>{if(u===i)return;let c=this.getShapePageBounds(d);if(t.x>=c.x-s&&t.x<=c.x+c.width+s&&t.y>=c.y-s&&t.y<=c.y+c.height+s){let g=(t.x-d.x)**2+(t.y-d.y)**2;g<r&&(r=g,n=d);}}),!n)return;let o=n,h=t.x-o.x,l=t.y-o.y;return Math.abs(l)>Math.abs(h)?{x:0,y:l<0?-1:1}:{x:h<0?-1:1,y:0}}getShapePageBounds(t){let e=this.getShapeBounds(t);return {x:t.x+e.x,y:t.y+e.y,width:e.width,height:e.height}}clampToShapeOutline(t,e,i,n){if(!e||e.size===0)return t;let r=null,s=1/0;if(e.forEach((h,l)=>{if(l===i)return;let d=this.getShapePageBounds(h);if(t.x>d.x&&t.x<d.x+d.width&&t.y>d.y&&t.y<d.y+d.height){let u=(h.x-n.x)**2+(h.y-n.y)**2;u<s&&(s=u,r=h);}}),!r)return t;let o=r;return this.nearestPointOnShapeOutline(o,{x:o.x,y:o.y},t)}nearestPointOnShapeOutline(t,e,i){let n=i.x-e.x,r=i.y-e.y,s=Math.hypot(n,r);if(s<1e-6)return {x:e.x,y:e.y};let o=n/s,h=r/s,l=Math.max(1e4,s*2),d={x:e.x+o*l,y:e.y+h*l},u=this.intersectShapeOutlineWithSegment(t,e,d);if(u.length===0)return i;let c=u[0],g=(c.x-e.x)**2+(c.y-e.y)**2;for(let p=1;p<u.length;p++){let y=(u[p].x-e.x)**2+(u[p].y-e.y)**2;y<g&&(g=y,c=u[p]);}return c}intersectShapeOutlineWithSegment(t,e,i){let n={x:e.x-t.x,y:e.y-t.y},r={x:i.x-t.x,y:i.y-t.y};return this.intersectLocalShapeOutlineWithSegment(t,n,r).map(o=>({x:o.x+t.x,y:o.y+t.y}))}intersectLocalShapeOutlineWithSegment(t,e,i){switch(t.type){case "rectangle":case "rounded-rectangle":{let n=t.width,r=t.height,s={x:-n/2,y:-r/2,width:n,height:r};return this.intersectSegmentRect(e,i,s)}case "ellipse":case "diamond":case "triangle":{let n=t.width,r=t.height,s={x:-n/2,y:-r/2,width:n,height:r};return this.intersectSegmentRect(e,i,s)}case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":{let n=t.width,r=t.height,s={x:-n/2,y:-r/2,width:n,height:r};return this.intersectSegmentRect(e,i,s)}case "circle":{let n=t.radius;return this.intersectSegmentCircle(e,i,{x:0,y:0},n)}default:return []}}intersectSegmentRect(t,e,i){let n=i.x,r=i.y,s=i.width,o=i.height,h=[[{x:n,y:r},{x:n+s,y:r}],[{x:n+s,y:r},{x:n+s,y:r+o}],[{x:n+s,y:r+o},{x:n,y:r+o}],[{x:n,y:r+o},{x:n,y:r}]],l=[];for(let[d,u]of h){let c=this.segmentIntersection(t,e,d,u);c&&l.push(c);}return l}segmentIntersection(t,e,i,n){let r=t.x,s=t.y,o=e.x,h=e.y,l=i.x,d=i.y,u=n.x,c=n.y,g=(r-o)*(d-c)-(s-h)*(l-u);if(Math.abs(g)<1e-9)return null;let p=((r-l)*(d-c)-(s-d)*(l-u))/g,y=-((r-o)*(s-d)-(s-h)*(r-l))/g;return p<0||p>1||y<0||y>1?null:{x:r+p*(o-r),y:s+p*(h-s)}}intersectSegmentCircle(t,e,i,n){let r=e.x-t.x,s=e.y-t.y,o=t.x-i.x,h=t.y-i.y,l=r*r+s*s,d=2*(o*r+h*s),u=o*o+h*h-n*n,c=d*d-4*l*u;if(c<0)return [];c=Math.sqrt(c);let g=(-d-c)/(2*l),p=(-d+c)/(2*l),y=[];return g>=0&&g<=1&&y.push({x:t.x+g*r,y:t.y+g*s}),p>=0&&p<=1&&Math.abs(p-g)>1e-6&&y.push({x:t.x+p*r,y:t.y+p*s}),y}drawArrowHead(t,e,i){let n=Math.atan2(i.y-e.y,i.x-e.x),r=12;t.beginPath(),t.moveTo(i.x,i.y),t.lineTo(i.x-r*Math.cos(n-Math.PI/6),i.y-r*Math.sin(n-Math.PI/6)),t.moveTo(i.x,i.y),t.lineTo(i.x-r*Math.cos(n+Math.PI/6),i.y-r*Math.sin(n+Math.PI/6)),t.stroke();}drawInheritanceHead(t,e,i){let n=Math.atan2(i.y-e.y,i.x-e.x),r=14,s=i.x,o=i.y,h=i.x-r*Math.cos(n),l=i.y-r*Math.sin(n),d=h+r*.5*Math.cos(n-Math.PI/2),u=l+r*.5*Math.sin(n-Math.PI/2),c=h+r*.5*Math.cos(n+Math.PI/2),g=l+r*.5*Math.sin(n+Math.PI/2);t.save(),t.fillStyle="#ffffff",t.beginPath(),t.moveTo(s,o),t.lineTo(d,u),t.lineTo(c,g),t.closePath(),t.fill(),t.stroke(),t.restore();}drawDiamondHead(t,e,i,n){let r=Math.atan2(i.y-e.y,i.x-e.x),s=14,o=i.x,h=i.y,l=i.x-s*.5*Math.cos(r),d=i.y-s*.5*Math.sin(r),u=i.x-s*Math.cos(r),c=i.y-s*Math.sin(r),g=l+s*.4*Math.cos(r-Math.PI/2),p=d+s*.4*Math.sin(r-Math.PI/2),y=l+s*.4*Math.cos(r+Math.PI/2),f=d+s*.4*Math.sin(r+Math.PI/2);t.save(),t.fillStyle=n?"#1f2937":"#ffffff",t.beginPath(),t.moveTo(o,h),t.lineTo(g,p),t.lineTo(u,c),t.lineTo(y,f),t.closePath(),t.fill(),t.stroke(),t.restore();}drawArrowHeads(t,e,i){if(i!=="none"){if(i==="start"||i==="both"){let n=e[0],r=e[1];this.drawArrowHead(t,r,n);}if(i==="end"||i==="both"){let n=e.length,r=e[n-2],s=e[n-1];this.drawArrowHead(t,r,s);}if(i==="inheritance"){let n=e.length,r=e[n-2],s=e[n-1];this.drawInheritanceHead(t,r,s);}if(i==="aggregation"){let n=e[0],r=e[1];this.drawDiamondHead(t,r,n,false);}if(i==="composition"){let n=e[0],r=e[1];this.drawDiamondHead(t,r,n,true);}}}drawText(t,e){if(!e.text)return;let i=e.fontSize;t.font=`${i}px sans-serif`,t.textAlign="center",t.textBaseline="middle";let n=e.width,r=e.height,s=i*1.3,o=this.getDisplayLines(t,e,e.text,i,n,r),h=o.length*s,l=-h/2+s/2;if(e.highlightColor&&e.highlightColor!=="transparent"){t.fillStyle=e.highlightColor;let d=i*.15;t.beginPath(),t.roundRect(-n/2-d,-h/2-d,n+d*2,h+d*2,4),t.fill();}t.fillStyle=e.textColor||"#1f2937",o.forEach((d,u)=>{let c=l+u*s;t.fillText(d,0,c);});}drawFreehand(t,e){if(e.points.length<2)return;let i=e.points.map(n=>({x:n.x-e.x,y:n.y-e.y}));t.beginPath(),t.moveTo(i[0].x,i[0].y);for(let n=1;n<i.length-1;n++){let r=(i[n].x+i[n+1].x)/2,s=(i[n].y+i[n+1].y)/2;t.quadraticCurveTo(i[n].x,i[n].y,r,s);}t.lineTo(i[i.length-1].x,i[i.length-1].y),t.stroke();}drawSelectionOutline(t,e,i){let n=this.getShapeBounds(e);t.strokeStyle=I.selection.outline,t.lineWidth=1/i,t.setLineDash([]),t.save(),t.shadowColor=I.selection.shadow,t.shadowBlur=8,t.shadowOffsetX=0,t.shadowOffsetY=0,t.beginPath(),t.roundRect(n.x-2,n.y-2,n.width+4,n.height+4,4),t.stroke(),t.restore(),t.fillStyle=I.selection.outlineFill,t.beginPath(),t.roundRect(n.x-2,n.y-2,n.width+4,n.height+4,4),t.fill();}drawSelectionHandles(t,e,i){let n=8/i;if((e.type==="line"||e.type==="arrow"||e.type==="draw")&&e.points&&e.points.length>=2){let s=e.points.map(u=>({x:u.x-e.x,y:u.y-e.y})),o=s[0],h=s[s.length-1];t.fillStyle=I.selection.handleFill,t.strokeStyle=I.selection.handleStroke,t.lineWidth=2/i,t.setLineDash([]),[o,h].forEach(u=>{t.beginPath(),t.arc(u.x,u.y,n/2,0,Math.PI*2),t.fill(),t.stroke();});let l=(o.x+h.x)/2,d=(o.y+h.y)/2;t.beginPath(),t.arc(l,d,7/i,0,Math.PI*2),t.fillStyle=I.selection.handleFill,t.fill(),t.strokeStyle=I.primary,t.lineWidth=1.5/i,t.stroke(),t.beginPath(),t.arc(l,d,3/i,0,Math.PI*2),t.fillStyle=I.genDot,t.fill();}else {let s=this.getShapeBounds(e),o=n,h=[{x:s.x,y:s.y},{x:s.x+s.width,y:s.y},{x:s.x+s.width,y:s.y+s.height},{x:s.x,y:s.y+s.height}];t.fillStyle=I.selection.handleFill,t.strokeStyle=I.selection.handleStroke,t.lineWidth=2/i,t.setLineDash([]),h.forEach(p=>{t.beginPath(),t.roundRect(p.x-o/2,p.y-o/2,o,o,2),t.fill(),t.stroke();});let l=9/i;[{x:s.x+s.width/2,y:s.y},{x:s.x+s.width,y:s.y+s.height/2},{x:s.x+s.width/2,y:s.y+s.height},{x:s.x,y:s.y+s.height/2}].forEach(p=>{t.beginPath(),t.arc(p.x,p.y,l,0,Math.PI*2),t.fillStyle=I.selection.handleFill,t.fill(),t.strokeStyle=I.primary,t.lineWidth=1.5/i,t.stroke(),t.beginPath(),t.arc(p.x,p.y,l*.45,0,Math.PI*2),t.fillStyle=I.primary,t.fill();});let u=26/i,c=s.x+s.width/2,g=s.y-u;t.strokeStyle="#94a3b8",t.lineWidth=1.5/i,t.setLineDash([]),t.beginPath(),t.moveTo(c,s.y),t.lineTo(c,g),t.stroke(),t.beginPath(),t.arc(c,g,8/i,0,Math.PI*2),t.fillStyle=I.selection.handleFill,t.fill(),t.strokeStyle=I.primary,t.lineWidth=1.6/i,t.stroke(),this.drawRotateIcon(t,c,g,i);}}drawRotateIcon(t,e,i,n){let r=8/n;t.save(),t.translate(e,i),t.strokeStyle=I.primary,t.lineWidth=1.8/n,t.lineCap="round",t.beginPath(),t.arc(0,0,r*.5,Math.PI*.18,Math.PI*1.6,false),t.stroke();let s=Math.PI*.18,o=Math.cos(s)*r*.5,h=Math.sin(s)*r*.5,l=1;t.beginPath(),t.moveTo(o,h),t.lineTo(o-Math.cos(s)*r*.26+l*Math.sin(s)*r*.16,h-Math.sin(s)*r*.26-l*Math.cos(s)*r*.16),t.moveTo(o,h),t.lineTo(o-Math.cos(s)*r*.26-l*Math.sin(s)*r*.16,h-Math.sin(s)*r*.26+l*Math.cos(s)*r*.16),t.stroke(),t.restore();}getShapeBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":return {x:-t.width/2,y:-t.height/2,width:t.width,height:t.height};case "circle":return {x:-t.radius,y:-t.radius,width:t.radius*2,height:t.radius*2};case "line":case "arrow":case "draw":if(t.points.length===0)return {x:0,y:0,width:0,height:0};let e=1/0,i=1/0,n=-1/0,r=-1/0;return t.points.forEach(s=>{e=Math.min(e,s.x-t.x),i=Math.min(i,s.y-t.y),n=Math.max(n,s.x-t.x),r=Math.max(r,s.y-t.y);}),{x:e,y:i,width:n-e,height:r-i};case "text":{let s=t;return {x:-s.width/2,y:-s.height/2,width:s.width,height:s.height}}default:return {x:0,y:0,width:0,height:0}}}};var rt={create(a=0,t=0){return {x:a,y:t}},add(a,t){return {x:a.x+t.x,y:a.y+t.y}},subtract(a,t){return {x:a.x-t.x,y:a.y-t.y}},multiply(a,t){return {x:a.x*t,y:a.y*t}},divide(a,t){return {x:a.x/t,y:a.y/t}},dot(a,t){return a.x*t.x+a.y*t.y},length(a){return Math.sqrt(a.x*a.x+a.y*a.y)},normalize(a){let t=rt.length(a);return t===0?{x:0,y:0}:{x:a.x/t,y:a.y/t}},distance(a,t){return rt.length(rt.subtract(a,t))},rotate(a,t){let e=Math.cos(t),i=Math.sin(t);return {x:a.x*e-a.y*i,y:a.x*i+a.y*e}},clone(a){return {x:a.x,y:a.y}},equals(a,t){return a.x===t.x&&a.y===t.y}};function J(a,t,e,i=8){let n=[];if(e==="horizontal"){let r=Math.min(a.x,t.x),s=Math.max(a.x+a.width,t.x+t.width),o=Math.abs(a.y-t.y)<=i,h=Math.abs(a.y+a.height-(t.y+t.height))<=i,l=Math.abs(a.y+a.height/2-(t.y+t.height/2))<=i;o&&n.push({type:"horizontal",position:(a.y+t.y)/2,start:r,end:s}),h&&n.push({type:"horizontal",position:(a.y+a.height+t.y+t.height)/2,start:r,end:s}),l&&!(o&&h)&&n.push({type:"horizontal",position:(a.y+a.height/2+t.y+t.height/2)/2,start:r,end:s});}else {let r=Math.min(a.y,t.y),s=Math.max(a.y+a.height,t.y+t.height),o=Math.abs(a.x-t.x)<=i,h=Math.abs(a.x+a.width-(t.x+t.width))<=i,l=Math.abs(a.x+a.width/2-(t.x+t.width/2))<=i;o&&n.push({type:"vertical",position:(a.x+t.x)/2,start:r,end:s}),h&&n.push({type:"vertical",position:(a.x+a.width+t.x+t.width)/2,start:r,end:s}),l&&!(o&&h)&&n.push({type:"vertical",position:(a.x+a.width/2+t.x+t.width/2)/2,start:r,end:s});}return n}var ct=class a extends H{type="select";state="idle";translatingState=null;resizingState=null;generatingState=null;hoverGenPoint=null;rotatingState=null;draggingArrowId=null;draggingTerminal=null;pendingHistoryCommit=false;brushStart={x:0,y:0};brushShiftKey=false;defaultGenType(t){if(t){let e=this.context.getShapes().find(i=>i.id===t);if(e&&It(e.type))return e.type}return "rectangle"}genPreviewOf(t,e){return {from:t.point,to:e,type:this.defaultGenType(t.sourceShapeId)}}genContext(t,e){return {from:t.point,to:e,sourceShapeId:t.sourceShapeId,edge:t.edge}}onPointerDown(t,e){let i=this.context.getShapes(),n=this.context.getSelectedIds(),r=this.hitTestArrowTerminal(t,i);if(r&&n.includes(r.shapeId)){this.state="dragging-terminal",this.draggingArrowId=r.shapeId,this.draggingTerminal=r.terminal,this.pendingHistoryCommit=true,this.context.updateArrowBinding(r.shapeId,r.terminal,null);return}let s=this.hitGenPoint(t,i,n);if(s){this.state="generating",this.generatingState={source:s,startPoint:t,hasMoved:false},this.pendingHistoryCommit=true,this.context.setGenerationPreview(this.genPreviewOf(s,this.genPreviewTarget(s,t,false)));return}let o=this.hitTest(t,i,n);if(o.handle==="rotation"){this.state="rotating",this.pendingHistoryCommit=true;let h=o.shape;this.rotatingState={shapeId:h.id,center:{x:h.x,y:h.y},startAngle:Math.atan2(t.y-h.y,t.x-h.x),startRotation:h.rotation};return}if(o.handle&&o.shape&&o.shape.type!=="mind-map"){this.state="resizing",this.resizingState={startPoint:t,startShape:o.shape,handle:o.handle},this.pendingHistoryCommit=true;return}if(o.shape){let h=o.shape,l=h.type==="line"||h.type==="arrow"||h.type==="draw",d=n.includes(h.id);if(l&&!d){this.context.selectShape(h.id,e.shiftKey);return}this.state="translating",this.pendingHistoryCommit=true,d||this.context.selectShape(h.id,e.shiftKey);let u=this.context.getSelectedIds(),c=new Map,g=new Map,p=new Map;u.forEach(y=>{let f=i.find(M=>M.id===y);f&&(c.set(y,{x:f.x,y:f.y}),g.set(y,f.rotation),p.set(y,this.getShapeWorldBounds(f)));}),this.translatingState={startPoint:t,startPositions:c,startRotation:g,startBounds:p};}else this.state="brushing",this.brushStart=t,this.brushShiftKey=e.shiftKey,e.shiftKey||this.context.selectShape("",false);}onPointerMove(t,e){let i=this.context.getShapes();if(this.state==="translating"&&this.translatingState)this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false),this.handleTranslating(t,e);else if(this.state==="generating"&&this.generatingState)this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false),this.handleGenerating(t,i);else if(this.state==="rotating"&&this.rotatingState)this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false),this.handleRotating(t,e);else if(this.state==="resizing"&&this.resizingState)this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false),this.handleResizing(t);else if(this.state==="dragging-terminal"&&this.draggingArrowId&&this.draggingTerminal){this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false);let n=i.find(r=>r.id===this.draggingArrowId);if(n){let r=this.draggingTerminal==="start"?t:n.points[n.points.length-1],s=this.draggingTerminal==="start"?n.points[0]:t,o=this.computeSnapGuidesForArrow(r,s,t,n,i);this.context.setSnapGuides(o);let h=t;if(o.length>0){let u=o.filter(g=>g.type==="horizontal"),c=o.filter(g=>g.type==="vertical");if(u.length>0){let g=u[0].position,p=Math.abs(t.y-g);for(let y of u){let f=Math.abs(t.y-y.position);f<p&&(p=f,g=y.position);}h={...h,y:g};}else if(c.length>0){let g=c[0].position,p=Math.abs(t.x-g);for(let y of c){let f=Math.abs(t.x-y.position);f<p&&(p=f,g=y.position);}h={...h,x:g};}}let l=this.draggingTerminal==="start"?0:n.points.length-1,d=[...n.points];d[l]=h,this.context.updateShape(this.draggingArrowId,{points:d});}}else if(this.state==="brushing")this.handleBrushing(t);else {let n=this.context.getSelectedIds(),r=this.hitGenPoint(t,i,n);r?(this.hoverGenPoint=r,this.context.setGenerationPreview(this.genPreviewOf(r,this.genPreviewTarget(r,t,false)))):this.hoverGenPoint&&(this.hoverGenPoint=null,this.context.setGenerationPreview(null));}}onPointerUp(t,e){if(this.state==="dragging-terminal"&&this.draggingArrowId&&this.draggingTerminal){let i=this.context.getShapes(),n=this.findBindingNearPoint(t,i,this.draggingArrowId);n&&this.context.updateArrowBinding(this.draggingArrowId,this.draggingTerminal,n.toShapeId,n.binding);}if(this.state==="generating"&&this.generatingState){let i=this.generatingState,n=this.context.getShapes(),r=i.source,s=this.findBindingNearPoint(t,n,r.sourceShapeId);if(s)this.context.connectToExisting(this.genContext(r,t),s.toShapeId,s.binding);else if(!i.hasMoved)this.context.createGeneratedConnection(this.genContext(r,this.genPreviewTarget(r,r.point,false)),{type:this.defaultGenType(r.sourceShapeId)});else {let o=this.context.createFloatingLine(this.genContext(r,t));this.context.openGenerationMenu({context:this.genContext(r,t),existingArrowId:o,defaultShapeType:this.defaultGenType(r.sourceShapeId)});}this.generatingState=null,this.context.setGenerationPreview(null);}this.state==="brushing"&&this.context.setBrushRect(null),this.context.setConnectingTarget(null),this.hoverGenPoint=null,this.pendingHistoryCommit=false,this.state="idle",this.draggingArrowId=null,this.draggingTerminal=null,this.translatingState=null,this.resizingState=null,this.rotatingState=null,this.context.setSnapGuides([]);}onKeyDown(t){let e=t.target;if(!(e&&(e.tagName==="INPUT"||e.tagName==="TEXTAREA"||e.isContentEditable))){if(t.key==="Delete"||t.key==="Backspace"){let i=this.context.getSelectedIds();i.length>0&&(this.context.commitHistory(),i.forEach(n=>{this.context.deleteShape(n);}));}t.key==="Escape"&&(this.context.selectShape("",false),this.context.setSnapGuides([]),this.state="idle"),(t.key==="+"||t.key==="=")&&t.shiftKey&&(this.context.commitHistory(),this.handleRotation(15)),t.key==="-"&&t.shiftKey&&(this.context.commitHistory(),this.handleRotation(-15)),t.key==="ArrowUp"&&(t.preventDefault(),this.context.commitHistory(),this.handleNudge(0,-5)),t.key==="ArrowDown"&&(t.preventDefault(),this.context.commitHistory(),this.handleNudge(0,5)),t.key==="ArrowLeft"&&(t.preventDefault(),this.context.commitHistory(),this.handleNudge(-5,0)),t.key==="ArrowRight"&&(t.preventDefault(),this.context.commitHistory(),this.handleNudge(5,0));}}onKeyUp(t){}getCursor(t){switch(this.state){case "translating":return "grabbing";case "generating":return "crosshair";case "rotating":return "grabbing";case "resizing":return this.resizingState?this.getHandleCursor(this.resizingState.handle,this.resizingState.startShape):"default";case "dragging-terminal":return "crosshair";case "brushing":return "crosshair"}let e=this.context.getShapes(),i=this.context.getSelectedIds();if(this.context.getMindMapCursorHitAtPoint(t))return "pointer";if(this.hitGenPoint(t,e,i))return "crosshair";if(this.hitTestArrowTerminal(t,e)&&i.includes(this.hitTestArrowTerminal(t,e).shapeId))return "move";let n=this.hitTest(t,e,i);return n.handle==="rotation"?"grab":n.handle?this.getHandleCursor(n.handle,n.shape):n.shape?"move":null}getHandleCursor(t,e){let n={e:0,se:45,s:90,sw:135,w:180,nw:225,n:270,ne:315}[t];if(n===void 0)return "grab";let r=((n+e.rotation*180/Math.PI)%360+360)%360,s=Math.round(r/45)%4;return ["ew-resize","nwse-resize","ns-resize","nesw-resize"][s]}static ALIGN_SNAP_THRESHOLD=8;handleTranslating(t,e){if(!this.translatingState)return;let i=rt.subtract(t,this.translatingState.startPoint),n={...i};e.shiftKey&&(Math.abs(i.x)>Math.abs(i.y)?n.y=0:n.x=0);let r=this.context.getShapes(),s=this.context.getSelectedIds(),o=new Set(s),h=[],l=[];if(this.translatingState.startBounds.forEach(d=>{l.push({x:d.x+n.x,y:d.y+n.y,width:d.width,height:d.height});}),!e.shiftKey&&l.length>0){let d=[];for(let g of r)o.has(g.id)||g.type==="line"||g.type==="arrow"||g.type==="draw"||d.push(this.getShapeWorldBounds(g));let u=[],c=[];for(let g of l){let p=[g.y,g.y+g.height/2,g.y+g.height],y=[g.x,g.x+g.width/2,g.x+g.width];for(let f of d){let M=[f.y,f.y+f.height/2,f.y+f.height];for(let v of p)for(let b of M){let P=b-v;Math.abs(P)<=a.ALIGN_SNAP_THRESHOLD&&u.push(P);}let x=[f.x,f.x+f.width/2,f.x+f.width];for(let v of y)for(let b of x){let P=b-v;Math.abs(P)<=a.ALIGN_SNAP_THRESHOLD&&c.push(P);}}}if(u.length>0){let g=u[0];for(let p of u)Math.abs(p)<Math.abs(g)&&(g=p);n.y+=g;}if(c.length>0){let g=c[0];for(let p of c)Math.abs(p)<Math.abs(g)&&(g=p);n.x+=g;}this.translatingState.startBounds.forEach(g=>{let p={x:g.x+n.x,y:g.y+n.y,width:g.width,height:g.height};for(let y of d)h.push(...J(p,y,"horizontal",1)),h.push(...J(p,y,"vertical",1));});}this.translatingState.startPositions.forEach((d,u)=>{this.context.updateShape(u,{x:d.x+n.x,y:d.y+n.y});}),this.context.setSnapGuides(this.mergeGuides(h));}handleResizing(t){if(!this.resizingState)return;let e=this.resizingState.startShape,i=this.resizingState.handle,n=this.resizingState.startPoint;if(!i||i==="rotation")return;let s={nw:[-1,-1],n:[0,-1],ne:[1,-1],w:[-1,0],e:[1,0],sw:[-1,1],s:[0,1],se:[1,1]}[i];if(!s)return;let[o,h]=s,l=rt.subtract(t,n),d=[];for(let P of this.context.getShapes())P.id!==e.id&&(P.type==="line"||P.type==="arrow"||P.type==="draw"||d.push(this.getShapeWorldBounds(P)));let u=20,c=this.getShapeWorldBounds(e),g=c.x,p=c.y,y=c.x+c.width,f=c.y+c.height;o===1?y=Math.max(g+u,y+l.x):o===-1&&(g=Math.min(y-u,g+l.x)),h===1?f=Math.max(p+u,f+l.y):h===-1&&(p=Math.min(f-u,p+l.y));let M=(P,T)=>{let E=null;for(let U of T){let Y=U-P;Math.abs(Y)<=a.ALIGN_SNAP_THRESHOLD&&(E===null||Math.abs(Y)<Math.abs(E))&&(E=Y);}return E};if(o!==0&&d.length>0){let P=[];for(let E of d)P.push(E.x,E.x+E.width/2,E.x+E.width);let T=M(o===1?y:g,P);T!==null&&(o===1?y+=T:g+=T);}if(h!==0&&d.length>0){let P=[];for(let E of d)P.push(E.y,E.y+E.height/2,E.y+E.height);let T=M(h===1?f:p,P);T!==null&&(h===1?f+=T:p+=T);}let x={x:g,y:p,width:y-g,height:f-p},v=[];for(let P of d)o!==0&&v.push(...J(x,P,"vertical",1)),h!==0&&v.push(...J(x,P,"horizontal",1));this.context.setSnapGuides(this.mergeGuides(v));let b={};if(e.type==="circle"){let P=Math.max(10,Math.max(o!==0?x.width/2:0,h!==0?x.height/2:0));if(b.radius=P,o!==0){let T=o===1?c.x:c.x+c.width;b.x=o===1?T+P:T-P;}if(h!==0){let T=h===1?c.y:c.y+c.height;b.y=h===1?T+P:T-P;}}else "width"in e&&o!==0&&(b.width=x.width,b.x=x.x+x.width/2),"height"in e&&h!==0&&(b.height=x.height,b.y=x.y+x.height/2);Object.keys(b).length>0&&this.context.updateShape(e.id,b);}mergeGuides(t){let e=new Map;for(let i of t){let n=`${i.type}\0${Math.round(i.position*2)/2}`,r=e.get(n);r?(r.start=Math.min(r.start,i.start),r.end=Math.max(r.end,i.end)):e.set(n,{...i});}return [...e.values()]}handleRotation(t){let e=this.context.getSelectedIds(),i=this.context.getShapes();e.forEach(n=>{let r=i.find(s=>s.id===n);r&&this.context.updateShape(n,{rotation:r.rotation+t*Math.PI/180});});}handleNudge(t,e){let i=this.context.getSelectedIds(),n=this.context.getShapes();i.forEach(r=>{let s=n.find(o=>o.id===r);s&&this.context.updateShape(r,{x:s.x+t,y:s.y+e});});}handleBrushing(t){let e=Math.min(this.brushStart.x,t.x),i=Math.min(this.brushStart.y,t.y),n=Math.abs(t.x-this.brushStart.x),r=Math.abs(t.y-this.brushStart.y);this.context.setBrushRect({x:e,y:i,width:n,height:r});let s=this.context.getShapes(),o=[];for(let h of s){let l=this.getShapeWorldBounds(h);this.rectsIntersect({x:e,y:i,width:n,height:r},l)&&o.push(h.id);}if(this.brushShiftKey){let h=this.context.getSelectedIds(),l=new Set([...h,...o]);this.context.selectShapes([...l]);}else this.context.selectShapes(o);}getShapeWorldBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":return {x:t.x-t.width/2,y:t.y-t.height/2,width:t.width,height:t.height};case "circle":return {x:t.x-t.radius,y:t.y-t.radius,width:t.radius*2,height:t.radius*2};case "line":case "arrow":case "draw":{if(!t.points||t.points.length===0)return {x:t.x,y:t.y,width:0,height:0};let e=1/0,i=1/0,n=-1/0,r=-1/0;return t.points.forEach(s=>{e=Math.min(e,s.x),i=Math.min(i,s.y),n=Math.max(n,s.x),r=Math.max(r,s.y);}),{x:e,y:i,width:n-e,height:r-i}}case "text":{let e=t;return {x:t.x-e.width/2,y:t.y-e.height/2,width:e.width,height:e.height}}default:{let e=t;return {x:e.x,y:e.y,width:0,height:0}}}}rectsIntersect(t,e){return t.x<e.x+e.width&&t.x+t.width>e.x&&t.y<e.y+e.height&&t.y+t.height>e.y}hitTest(t,e,i){for(let n=e.length-1;n>=0;n--){let r=e[n];if(i.includes(r.id)){let s=this.getHitHandle(t,r);if(s)return {shape:r,handle:s}}if(this.isPointInShape(t,r))return {shape:r,handle:null}}return {shape:null,handle:null}}getHitHandle(t,e){if(e.type==="mind-map")return null;let i=14,n=this.getShapeBounds(e),r=Math.cos(-e.rotation),s=Math.sin(-e.rotation),o=t.x-e.x,h=t.y-e.y,l=o*r-h*s,d=o*s+h*r,u=[{type:"nw",x:n.x,y:n.y},{type:"ne",x:n.x+n.width,y:n.y},{type:"se",x:n.x+n.width,y:n.y+n.height},{type:"sw",x:n.x,y:n.y+n.height},{type:"rotation",x:n.x+n.width/2,y:n.y-26}];for(let c of u)if(Math.abs(l-c.x)<i&&Math.abs(d-c.y)<i)return c.type;return null}static GEN_HIT_THRESHOLD=14;static CLICK_MOVE_THRESHOLD=6;computeGenPoints(t,e){let i=[];for(let n of e){let r=t.find(s=>s.id===n);if(r){if(r.type==="line"||r.type==="arrow"||r.type==="draw"){if(r.points&&r.points.length>=2){let s=this.getShapeWorldBounds(r);i.push({point:{x:s.x+s.width/2,y:s.y+s.height/2},sourceShapeId:r.id});}}else if(r.type==="rectangle"||r.type==="rounded-rectangle"||r.type==="ellipse"||r.type==="diamond"||r.type==="triangle"||r.type==="hexagon"||r.type==="parallelogram"||r.type==="trapezoid"||r.type==="pentagon"||r.type==="octagon"||r.type==="star"||r.type==="uml-class"||r.type==="uml-interface"||r.type==="circle"){let s=this.getShapeBounds(r),o={x:r.x,y:r.y};i.push({point:{x:o.x+s.x+s.width/2,y:o.y+s.y},edge:"n",sourceShapeId:r.id}),i.push({point:{x:o.x+s.x+s.width,y:o.y+s.y+s.height/2},edge:"e",sourceShapeId:r.id}),i.push({point:{x:o.x+s.x+s.width/2,y:o.y+s.y+s.height},edge:"s",sourceShapeId:r.id}),i.push({point:{x:o.x+s.x,y:o.y+s.y+s.height/2},edge:"w",sourceShapeId:r.id});}}}return i}hitGenPoint(t,e,i){let n=a.GEN_HIT_THRESHOLD,r=null,s=n;for(let o of this.computeGenPoints(e,i)){let h=Math.hypot(o.point.x-t.x,o.point.y-t.y);h<=s&&(s=h,r=o);}return r}genPreviewTarget(t,e,i){if(i)return e;let n=96;if(t.edge)switch(t.edge){case "n":return {x:t.point.x,y:t.point.y-n};case "s":return {x:t.point.x,y:t.point.y+n};case "e":return {x:t.point.x+n,y:t.point.y};case "w":return {x:t.point.x-n,y:t.point.y}}return {x:t.point.x,y:t.point.y-n}}handleGenerating(t,e){if(!this.generatingState)return;let i=this.generatingState,n=i.source;Math.hypot(t.x-i.startPoint.x,t.y-i.startPoint.y)>a.CLICK_MOVE_THRESHOLD&&(i.hasMoved=true);let s=this.findBindingNearPoint(t,e,n.sourceShapeId),o=s?this.bindingPosition(s.toShapeId,s.binding,e):i.hasMoved?t:this.genPreviewTarget(n,t,false);this.context.setConnectingTarget(s?s.toShapeId:null),this.context.setGenerationPreview({from:n.point,to:o,type:s?void 0:this.defaultGenType(n.sourceShapeId)});}handleRotating(t,e){if(!this.rotatingState)return;let i=this.rotatingState,n=Math.atan2(t.y-i.center.y,t.x-i.center.x),r=i.startRotation+(n-i.startAngle);e.shiftKey&&(r=Math.round(r/(Math.PI/12))*(Math.PI/12)),this.context.updateShape(i.shapeId,{rotation:r});}bindingPosition(t,e,i){let n=i.find(s=>s.id===t);if(!n)return {x:0,y:0};let r=this.getShapeWorldBounds(n);if(e.handle)switch(e.handle){case "top":return {x:n.x,y:r.y};case "bottom":return {x:n.x,y:r.y+r.height};case "left":return {x:r.x,y:n.y};case "right":return {x:r.x+r.width,y:n.y}}return e.normalizedAnchor?{x:r.x+r.width*e.normalizedAnchor.x,y:r.y+r.height*e.normalizedAnchor.y}:{x:n.x,y:n.y}}isPointInShape(t,e){let i=t.x-e.x,n=t.y-e.y;switch(e.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":return Math.abs(i)<=e.width/2&&Math.abs(n)<=e.height/2;case "circle":return i*i+n*n<=e.radius*e.radius;case "hexagon":return this.isPointInHexagon(i,n,e.width,e.height);case "line":case "arrow":case "draw":for(let r=0;r<e.points.length-1;r++){let s=e.points[r],o=e.points[r+1];if(this.pointToLineDistance(t,s,o)<10)return true}return false;case "text":return Math.abs(i)<=50&&Math.abs(n)<=e.fontSize/2;default:return false}}isPointInHexagon(t,e,i,n){let r=Math.abs(t),s=Math.abs(e),o=i/2,h=n/2;return r<=o&&s<=h&&r/o+s/h<=1.5}pointToLineDistance(t,e,i){let n=t.x-e.x,r=t.y-e.y,s=i.x-e.x,o=i.y-e.y,h=n*s+r*o,l=s*s+o*o,d=-1;l!==0&&(d=h/l);let u,c;d<0?(u=e.x,c=e.y):d>1?(u=i.x,c=i.y):(u=e.x+d*s,c=e.y+d*o);let g=t.x-u,p=t.y-c;return Math.sqrt(g*g+p*p)}getShapeBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":return {x:-t.width/2,y:-t.height/2,width:t.width,height:t.height};case "circle":return {x:-t.radius,y:-t.radius,width:t.radius*2,height:t.radius*2};case "line":case "arrow":case "draw":if(t.points.length===0)return {x:0,y:0,width:0,height:0};let e=1/0,i=1/0,n=-1/0,r=-1/0;return t.points.forEach(s=>{e=Math.min(e,s.x-t.x),i=Math.min(i,s.y-t.y),n=Math.max(n,s.x-t.x),r=Math.max(r,s.y-t.y);}),{x:e,y:i,width:n-e,height:r-i};case "text":return {x:-50,y:-t.fontSize/2,width:100,height:t.fontSize};default:return {x:0,y:0,width:0,height:0}}}hitTestArrowTerminal(t,e){for(let n of e){if(n.type!=="arrow")continue;let r=n;if(r.points.length<2)continue;let s=r.points[0],o=r.points[r.points.length-1],h=Math.sqrt(Math.pow(t.x-s.x,2)+Math.pow(t.y-s.y,2)),l=Math.sqrt(Math.pow(t.x-o.x,2)+Math.pow(t.y-o.y,2));if(h<20)return {shapeId:r.id,terminal:"start"};if(l<20)return {shapeId:r.id,terminal:"end"}}return null}findShapeNearPoint(t,e,i){for(let r=e.length-1;r>=0;r--){let s=e[r];if(i&&s.id===i||s.type==="arrow"||s.type==="line"||s.type==="draw")continue;let o;switch(s.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":o=this.pointToRectDistance(t,{x:s.x-s.width/2,y:s.y-s.height/2,width:s.width,height:s.height});break;case "circle":o=Math.sqrt(Math.pow(t.x-s.x,2)+Math.pow(t.y-s.y,2))-s.radius;break;case "hexagon":{let h=s.width/2,l=s.height/2,d=Math.abs(t.x-s.x),u=Math.abs(t.y-s.y);o=d/h+u/l-1;break}default:continue}if(o<=30)return s}return null}pointToRectDistance(t,e){let i=Math.max(e.x,Math.min(t.x,e.x+e.width)),n=Math.max(e.y,Math.min(t.y,e.y+e.height));return Math.sqrt(Math.pow(t.x-i,2)+Math.pow(t.y-n,2))}static SNAP_THRESHOLD=32;static HANDLE_SNAP_DISTANCE=18;static ANCHOR_EPS=.001;computeSnapGuidesForArrow(t,e,i,n,r){let s=this.draggingTerminal==="start"?n.endBinding:n.startBinding,o=s?r.find(p=>p.id===s.toShapeId):null;if(!o)return [];let h=this.findShapeNearPoint(i,r,n.id);if(!h)return [];let l=this.getShapeWorldBounds(o),d=this.getShapeWorldBounds(h),u=e.x-t.x,c=e.y-t.y,g=Math.abs(u)>=Math.abs(c)?"horizontal":"vertical";return J(l,d,g)}findBindingNearPoint(t,e,i){let n;for(let r=e.length-1;r>=0;r--){let s=e[r];if(i&&s.id===i||s.type==="arrow"||s.type==="line"||s.type==="draw")continue;let o=this.getPageBounds(s),h=a.SNAP_THRESHOLD;if(t.x<o.x-h||t.x>o.x+o.width+h||t.y<o.y-h||t.y>o.y+o.height+h)continue;let l={x:s.x,y:s.y},d=[{handle:"top",pos:{x:l.x,y:o.y}},{handle:"bottom",pos:{x:l.x,y:o.y+o.height}},{handle:"left",pos:{x:o.x,y:l.y}},{handle:"right",pos:{x:o.x+o.width,y:l.y}}];for(let c of d){let g=Math.hypot(c.pos.x-t.x,c.pos.y-t.y);g<=a.HANDLE_SNAP_DISTANCE&&(!n||g<n.distance)&&(n={toShapeId:s.id,binding:{toShapeId:s.id,handle:c.handle,isPrecise:false},distance:g});}let u=this.nearestPointOnShapeOutline(s,t);if(u&&u.distance<=a.SNAP_THRESHOLD&&(!n||u.distance<n.distance)){let c=this.computeNormalizedAnchor(o,u.point);n={toShapeId:s.id,binding:{toShapeId:s.id,isPrecise:true,normalizedAnchor:c},distance:u.distance};}}if(n)return {toShapeId:n.toShapeId,binding:n.binding}}getPageBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":return {x:t.x-t.width/2,y:t.y-t.height/2,width:t.width,height:t.height};case "circle":return {x:t.x-t.radius,y:t.y-t.radius,width:t.radius*2,height:t.radius*2};default:return {x:t.x-50,y:t.y-50,width:100,height:100}}}computeNormalizedAnchor(t,e){let i=a.ANCHOR_EPS,n=t.width>0?(e.x-t.x)/t.width:.5,r=t.height>0?(e.y-t.y)/t.height:.5;return n=Math.max(i,Math.min(1-i,n)),r=Math.max(i,Math.min(1-i,r)),{x:n,y:r}}nearestPointOnShapeOutline(t,e){let i={x:e.x-t.x,y:e.y-t.y},n=this.nearestLocalPointOnShapeOutline(t,i);if(!n)return null;let r={x:n.point.x+t.x,y:n.point.y+t.y};return {point:r,distance:Math.hypot(r.x-e.x,r.y-e.y)}}nearestLocalPointOnShapeOutline(t,e){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":{let i=t.width,n=t.height;return this.nearestPointOnRectOutlineLocal(e,{x:-i/2,y:-n/2,width:i,height:n})}case "circle":{let i=t.radius;return this.nearestPointOnCircleOutlineLocal(e,{x:0,y:0},i)}default:return null}}nearestPointOnRectOutlineLocal(t,e){let i=[[{x:e.x,y:e.y},{x:e.x+e.width,y:e.y}],[{x:e.x+e.width,y:e.y},{x:e.x+e.width,y:e.y+e.height}],[{x:e.x+e.width,y:e.y+e.height},{x:e.x,y:e.y+e.height}],[{x:e.x,y:e.y+e.height},{x:e.x,y:e.y}]],n=null;for(let[r,s]of i){let o=this.nearestPointOnSegment(t,r,s);(!n||o.distance<n.distance)&&(n=o);}return n}nearestPointOnCircleOutlineLocal(t,e,i){let n=t.x-e.x,r=t.y-e.y,s=Math.hypot(n,r);if(s<1e-9)return {point:{x:e.x+i,y:e.y},distance:i};let o=e.x+n/s*i,h=e.y+r/s*i,l={x:o,y:h};return {point:l,distance:Math.hypot(l.x-t.x,l.y-t.y)}}nearestPointOnSegment(t,e,i){let n=i.x-e.x,r=i.y-e.y,s=n*n+r*r,o=s>0?((t.x-e.x)*n+(t.y-e.y)*r)/s:0;o=Math.max(0,Math.min(1,o));let h=e.x+o*n,l=e.y+o*r,d={x:h,y:l};return {point:d,distance:Math.hypot(d.x-t.x,d.y-t.y)}}};var ut=class a extends H{type="hand";state="idle";startScreenPoint={x:0,y:0};initialCameraPos={x:0,y:0};static DRAG_THRESHOLD=4;onPointerDown(t,e){this.startScreenPoint={x:e.clientX,y:e.clientY};let i=this.context.getCamera();this.initialCameraPos={x:i.x,y:i.y},this.state="pointing";}onPointerMove(t,e){if(this.state!=="idle"){if(this.state==="pointing"){let i=e.clientX-this.startScreenPoint.x,n=e.clientY-this.startScreenPoint.y;if(Math.hypot(i,n)<a.DRAG_THRESHOLD)return;this.state="dragging",this.applyCameraDelta(i,n);return}if(this.state==="dragging"){let i=e.clientX-this.startScreenPoint.x,n=e.clientY-this.startScreenPoint.y;this.applyCameraDelta(i,n);}}}onPointerUp(t,e){if(this.state!=="idle"){if(this.state==="dragging"){let i=this.context.getCamera();this.initialCameraPos={x:i.x,y:i.y},this.startScreenPoint={x:e.clientX,y:e.clientY};}this.state="idle";}}onKeyDown(t){t.key==="Escape"&&this.state!=="idle"&&(this.context.setCameraPosition(this.initialCameraPos.x,this.initialCameraPos.y),this.state="idle");}onKeyUp(t){}getCursor(t){return this.state==="dragging"||this.state==="pointing"?"grabbing":"grab"}applyCameraDelta(t,e){this.context.setCameraPosition(this.initialCameraPos.x+t,this.initialCameraPos.y+e);}};var be={strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:2,strokeDash:null},gt=class extends H{type="line";isDrawing=false;startPoint={x:0,y:0};currentShape=null;onPointerDown(t,e){this.isDrawing=true,this.startPoint=t,this.currentShape={id:`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,type:"line",x:t.x,y:t.y,points:[t],rotation:0,style:{...be}},this.context.commitHistory(),this.context.addShape(this.currentShape);}onPointerMove(t,e){!this.isDrawing||!this.currentShape||this.context.updateShape(this.currentShape.id,{points:[this.startPoint,t]});}onPointerUp(t,e){this.isDrawing=false,this.currentShape=null,this.context.setActiveTool("select");}onKeyDown(t){}onKeyUp(t){}getCursor(){return "crosshair"}};var Me={strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:4,strokeDash:null},ve={strokeColor:"rgba(255, 235, 59, 0.5)",fillColor:"transparent",strokeWidth:16,strokeDash:null},Pe=4e3,at=class extends H{type;mode;isDrawing=false;points=[];currentShapeId=null;committed=false;fadeTimer=null;constructor(t,e){super(t),this.mode=e,this.type=e==="pen"?"pen":"highlighter";}onPointerDown(t,e){this.isDrawing=true,this.committed=false,this.currentShapeId=null,this.points=[{...t}];}onPointerMove(t,e){if(this.isDrawing)if(this.points.push({...t}),!this.committed&&this.points.length>=2){this.context.commitHistory();let i=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;this.currentShapeId=i;let n=this.points[0],r=this.mode==="pen"?{...Me}:{...ve},s={id:i,type:"draw",x:n.x,y:n.y,points:this.points.map(o=>({...o})),rotation:0,style:r};this.context.addShape(s),this.committed=true;}else this.committed&&this.currentShapeId&&this.context.updateShape(this.currentShapeId,{points:this.points.map(i=>({...i}))});}onPointerUp(t,e){if(!this.isDrawing||(this.isDrawing=false,!this.committed||!this.currentShapeId))return;let i=this.currentShapeId;this.currentShapeId=null,this.mode==="highlighter"&&(this.fadeTimer=setTimeout(()=>{this.context.deleteShape(i);},Pe));}onKeyDown(t){}onKeyUp(t){}getCursor(){return "crosshair"}dispose(){this.fadeTimer&&(clearTimeout(this.fadeTimer),this.fadeTimer=null);}};var Te={strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:2,strokeDash:null},pt=class extends H{type="arrow";isDrawing=false;startPoint={x:0,y:0};currentShapeId=null;startBindingInfo=null;onPointerDown(t,e){this.isDrawing=true,this.startPoint=t,this.startBindingInfo=null;let i=this.context.getShapes(),n=this.findShapeBinding(t,i),r=t;n&&(r=this.getBindingPosition(n.toShapeId,n.handle,i),this.startBindingInfo={...n,position:r});let s=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;this.currentShapeId=s;let o={id:s,type:"arrow",x:r.x,y:r.y,points:[r],rotation:0,style:{...Te},startBinding:n?{toShapeId:n.toShapeId,handle:n.handle}:void 0,connectionType:"straight",arrowHead:"end",dashed:false};this.context.commitHistory(),this.context.addShape(o);}onPointerMove(t,e){if(!this.isDrawing||!this.currentShapeId)return;let i=this.context.getShapes(),n=this.findShapeBinding(t,i),r=t;n&&(r=this.getBindingPosition(n.toShapeId,n.handle,i));let s=this.startBindingInfo?.position||this.startPoint,o=this.computeSnapGuides(s,r,n,i);this.context.setSnapGuides(o),this.context.updateShape(this.currentShapeId,{points:[s,r],endBinding:n?{toShapeId:n.toShapeId,handle:n.handle}:void 0});}onPointerUp(t,e){this.isDrawing=false,this.currentShapeId=null,this.startBindingInfo=null,this.context.setSnapGuides([]),this.context.setActiveTool("select");}onKeyDown(t){}onKeyUp(t){}getCursor(){return "crosshair"}computeSnapGuides(t,e,i,n){let r=this.startBindingInfo?n.find(c=>c.id===this.startBindingInfo.toShapeId):null,s=i?n.find(c=>c.id===i.toShapeId):null;if(!r||!s)return [];let o=this.getShapeBounds(r),h=this.getShapeBounds(s),l=e.x-t.x,d=e.y-t.y,u=Math.abs(l)>=Math.abs(d)?"horizontal":"vertical";return J(o,h,u)}getShapeBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":return {x:t.x-t.width/2,y:t.y-t.height/2,width:t.width,height:t.height};case "circle":return {x:t.x-t.radius,y:t.y-t.radius,width:t.radius*2,height:t.radius*2};case "text":return {x:t.x-t.width/2,y:t.y-t.height/2,width:t.width,height:t.height};default:return {x:t.x-50,y:t.y-20,width:100,height:40}}}findShapeBinding(t,e){for(let n=e.length-1;n>=0;n--){let r=e[n];if(r.type==="arrow"||r.type==="line"||r.type==="draw")continue;let s;switch(r.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "uml-class":case "uml-interface":s=this.pointToRectDistance(t,{x:r.x-r.width/2,y:r.y-r.height/2,width:r.width,height:r.height});break;case "circle":{let o=Math.sqrt(Math.pow(t.x-r.x,2)+Math.pow(t.y-r.y,2));s=Math.abs(o-r.radius);break}case "hexagon":{let o=r.width/2,h=r.height/2,l=Math.abs(t.x-r.x),d=Math.abs(t.y-r.y);s=l/o+d/h-1;break}default:continue}if(s<=40){let o=this.getClosestHandle(t,r);return {toShapeId:r.id,handle:o}}}}pointToRectDistance(t,e){let i=Math.max(e.x,Math.min(t.x,e.x+e.width)),n=Math.max(e.y,Math.min(t.y,e.y+e.height));return Math.sqrt(Math.pow(t.x-i,2)+Math.pow(t.y-n,2))}getClosestHandle(t,e){let i=t.x-e.x,n=t.y-e.y;if(e.type==="circle"||e.type==="hexagon"){let l=Math.atan2(n,i);return l>=-Math.PI/4&&l<Math.PI/4?"right":l>=Math.PI/4&&l<3*Math.PI/4?"bottom":l>=3*Math.PI/4||l<-(3*Math.PI)/4?"left":"top"}let r="width"in e?e.width:100,s="height"in e?e.height:100,o=Math.abs(i)/(r/2),h=Math.abs(n)/(s/2);return o>h?i>0?"right":"left":n>0?"bottom":"top"}getBindingPosition(t,e,i){let n=i.find(r=>r.id===t);if(!n)return {x:0,y:0};switch(n.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":return this.getRectBindingPosition(n,e);case "circle":return this.getCircleBindingPosition(n,e);case "hexagon":return this.getRectBindingPosition(n,e);default:return {x:n.x,y:n.y}}}getRectBindingPosition(t,e){switch(e){case "top":return {x:t.x,y:t.y-t.height/2};case "bottom":return {x:t.x,y:t.y+t.height/2};case "left":return {x:t.x-t.width/2,y:t.y};case "right":return {x:t.x+t.width/2,y:t.y}}}getCircleBindingPosition(t,e){switch(e){case "top":return {x:t.x,y:t.y-t.radius};case "bottom":return {x:t.x,y:t.y+t.radius};case "left":return {x:t.x-t.radius,y:t.y};case "right":return {x:t.x+t.radius,y:t.y}}}};var Ie={strokeColor:"transparent",fillColor:"transparent",strokeWidth:0,strokeDash:null},$t=class extends H{type="text";onPointerDown(t,e){let i=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,n={id:i,type:"text",x:t.x,y:t.y,rotation:0,style:{...Ie},text:"",fontSize:16,textColor:"#1f2937",width:200,height:24};this.context.commitHistory(),this.context.addShape(n),this.context.enterEditing(i);}onPointerMove(t,e){}onPointerUp(t,e){}onKeyDown(t){}onKeyUp(t){}getCursor(){return "text"}};var mt="#1f2937";function Ut(a){switch(a.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":case "text":return {x:-(a.width/2),y:-(a.height/2),width:a.width,height:a.height};case "circle":return {x:-a.radius,y:-a.radius,width:a.radius*2,height:a.radius*2};case "line":case "arrow":case "draw":{let t=a.points;if(!t||t.length===0)return {x:0,y:0,width:0,height:0};let e=1/0,i=1/0,n=-1/0,r=-1/0;for(let s of t){let o=s.x-a.x,h=s.y-a.y;e=Math.min(e,o),i=Math.min(i,h),n=Math.max(n,o),r=Math.max(r,h);}return {x:e,y:i,width:n-e,height:r-i}}default:return {x:0,y:0,width:0,height:0}}}function Ce(a){let t=Ut(a),e=Math.cos(a.rotation),i=Math.sin(a.rotation),n=1/0,r=1/0,s=-1/0,o=-1/0,h=[[t.x,t.y],[t.x+t.width,t.y],[t.x+t.width,t.y+t.height],[t.x,t.y+t.height]];for(let[l,d]of h){let u=l*e-d*i+a.x,c=l*i+d*e+a.y;n=Math.min(n,u),r=Math.min(r,c),s=Math.max(s,u),o=Math.max(o,c);}return {x:n,y:r,width:s-n,height:o-r}}function xt(a,t=24){if(!a||a.length===0)return {x:0,y:0,width:400,height:300};let e=1/0,i=1/0,n=-1/0,r=-1/0;for(let s of a){let o=Ce(s);e=Math.min(e,o.x),i=Math.min(i,o.y),n=Math.max(n,o.x+o.width),r=Math.max(r,o.y+o.height);}return {x:e-t,y:i-t,width:n-e+t*2,height:r-i+t*2}}function re(a,t={}){let e=t.padding??24,i=t.scale??2,n=t.background===void 0?"#ffffff":t.background??null,r=xt(a,e),s=Math.max(1,Math.ceil(r.width)),o=Math.max(1,Math.ceil(r.height)),h=document.createElement("canvas");h.width=Math.ceil(s*i),h.height=Math.ceil(o*i);let l=new st(h,i);l.resize(s*i,o*i);let d=new et;return d.zoom=1,d.x=-r.x,d.y=-r.y,l.render(a,d,new Set,void 0,void 0,void 0,void 0,void 0,void 0,void 0,n),h}function Ee(a,t,e){return new Promise((i,n)=>{a.toBlob(r=>{r?i(r):n(new Error("canvas.toBlob failed"));},t,e);})}function $e(a,t,e){return a.toDataURL(t,e)}var yt=null;function tt(a,t){return yt||(yt=document.createElement("canvas").getContext("2d")),yt?(yt.font=t,yt.measureText(a).width):a.length*8}function ht(a){return a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function Qt(a,t,e,i){let n=t*1.3,r=Math.max(1,Math.floor(i/n)),s=`${t}px sans-serif`,o=a.split(`
|
|
3
|
-
`),h=[];for(let d of o){let u="";for(let c of d){let g=u+c;tt(g,s)>e&&u?(h.push(u),u=c):u=g;}u&&h.push(u);}let l=h.slice(0,r);if(h.length>r&&l.length>0){let d=l[l.length-1],u="...";for(;d.length>0&&tt(d+u,s)>e;)d=d.slice(0,-1);l[l.length-1]=d+u;}return l}function Gt(a,t,e){if(tt(a,e)<=t)return a;let i="\u2026",n=0,r=a.length;for(;n<r;){let s=n+r+1>>1;tt(a.slice(0,s)+i,e)<=t?n=s:r=s-1;}return a.slice(0,n)+i}function Q(a){return a.map(([t,e])=>`${m(t)},${m(e)}`).join(" ")}function m(a){return Math.round(a*100)/100}function oe(a){return a.strokeDash&&a.strokeDash.length?a.strokeDash.join(","):void 0}function ae(a,t){let e=t.x-a.x,i=t.y-a.y,n=Math.cos(a.rotation),r=Math.sin(a.rotation);return {x:e*n-i*r+a.x,y:e*r+i*n+a.y}}function te(a,t){if(t.isPrecise&&t.normalizedAnchor){let e=Ut(a),i=a.x+e.x+e.width*t.normalizedAnchor.x,n=a.y+e.y+e.height*t.normalizedAnchor.y;return {x:i,y:n}}if(t.handle){let e=Ut(a);switch(t.handle){case "top":return {x:a.x,y:a.y+e.y};case "bottom":return {x:a.x,y:a.y+e.y+e.height};case "left":return {x:a.x+e.x,y:a.y};case "right":return {x:a.x+e.x+e.width,y:a.y}}}return {x:a.x,y:a.y}}function De(a,t){let e=a.points.map(i=>({...i}));if(e.length===0)return e;if(a.startBinding){let i=t.get(a.startBinding.toShapeId);i&&(e[0]=te(i,a.startBinding));}if(a.endBinding){let i=t.get(a.endBinding.toShapeId);i&&(e[e.length-1]=te(i,a.endBinding));}return e.map(i=>ae(a,i))}function Ae(a){if(a.length<2)return a;let t=a[0],e=a[a.length-1],i=e.x-t.x,n=e.y-t.y,r=8;if(Math.abs(n)<=r){let s=(t.y+e.y)/2;return a.map(o=>({x:o.x,y:s}))}if(Math.abs(i)<=r){let s=(t.x+e.x)/2;return a.map(o=>({x:s,y:o.y}))}return a}function Le(a){if(a.length<2)return a;let t=[a[0]];for(let e=1;e<a.length;e++){let i=a[e-1],n=a[e],r=(i.x+n.x)/2,s=(i.y+n.y)/2;Math.abs(n.x-i.x)>=Math.abs(n.y-i.y)?(t.push({x:r,y:i.y}),t.push({x:r,y:n.y})):(t.push({x:i.x,y:s}),t.push({x:n.x,y:s})),t.push(n);}return t}function Ne(a){if(a.length<2)return "";let t=`M ${m(a[0].x)} ${m(a[0].y)}`,e=a[0];for(let i=1;i<a.length;i++){let n=a[i],r=n.x-e.x,s=n.y-e.y,o=Math.hypot(r,s),h={x:(e.x+n.x)/2,y:(e.y+n.y)/2};if(o>=1){let l=-s/o,d=r/o,u=Math.min(o*.2,30);h={x:h.x+l*u,y:h.y+d*u};}t+=` Q ${m(h.x)} ${m(h.y)} ${m(n.x)} ${m(n.y)}`,e=n;}return t}function Re(a,t){if(t==="curve")return Ne(a);let e=t==="straight"?Ae(a):Le(a);if(e.length<2)return "";let i=`M ${m(e[0].x)} ${m(e[0].y)}`;for(let n=1;n<e.length;n++)i+=` L ${m(e[n].x)} ${m(e[n].y)}`;return i}function ee(a,t,e,i){let n=Math.atan2(t.y-a.y,t.x-a.x),r=12,s={x:t.x-r*Math.cos(n-Math.PI/6),y:t.y-r*Math.sin(n-Math.PI/6)},o={x:t.x-r*Math.cos(n+Math.PI/6),y:t.y-r*Math.sin(n+Math.PI/6)};return `<path d="M ${m(t.x)} ${m(t.y)} L ${m(s.x)} ${m(s.y)} M ${m(t.x)} ${m(t.y)} L ${m(o.x)} ${m(o.y)}" stroke="${e}" stroke-width="${i}" stroke-linecap="round" fill="none" />`}function Ve(a,t,e,i){let n=Math.atan2(t.y-a.y,t.x-a.x),r=14,s=t.x,o=t.y,h=t.x-r*Math.cos(n),l=t.y-r*Math.sin(n),d=h+r*.5*Math.cos(n-Math.PI/2),u=l+r*.5*Math.sin(n-Math.PI/2),c=h+r*.5*Math.cos(n+Math.PI/2),g=l+r*.5*Math.sin(n+Math.PI/2);return `<polygon points="${m(s)},${m(o)} ${m(d)},${m(u)} ${m(c)},${m(g)}" fill="#ffffff" stroke="${e}" stroke-width="${i}" />`}function ne(a,t,e,i,n){let r=Math.atan2(t.y-a.y,t.x-a.x),s=14,o=t.x,h=t.y,l=t.x-s*.5*Math.cos(r),d=t.y-s*.5*Math.sin(r),u=t.x-s*Math.cos(r),c=t.y-s*Math.sin(r),g=l+s*.4*Math.cos(r-Math.PI/2),p=d+s*.4*Math.sin(r-Math.PI/2),y=l+s*.4*Math.cos(r+Math.PI/2),f=d+s*.4*Math.sin(r+Math.PI/2);return `<polygon points="${m(o)},${m(h)} ${m(g)},${m(p)} ${m(u)},${m(c)} ${m(y)},${m(f)}" fill="${n?e:"#ffffff"}" stroke="${e}" stroke-width="${i}" />`}function He(a,t,e,i){if(t==="none"||a.length<2)return "";let n="";return (t==="start"||t==="both")&&(n+=ee(a[1],a[0],e,i)),(t==="end"||t==="both")&&(n+=ee(a[a.length-2],a[a.length-1],e,i)),t==="inheritance"&&(n+=Ve(a[a.length-2],a[a.length-1],e,i)),t==="aggregation"&&(n+=ne(a[1],a[0],e,i,false)),t==="composition"&&(n+=ne(a[1],a[0],e,i,true)),n}function ie(a,t,e,i=0,n=0){if(a.length===0)return "";let r=t*1.3,o=-(a.length*r)/2+r/2,h=a.map((l,d)=>`<tspan x="${m(i)}" y="${m(n+o+d*r)}">${ht(l)}</tspan>`).join("");return `<text text-anchor="middle" dominant-baseline="central" font-family="sans-serif" font-size="${t}" fill="${e}">${h}</text>`}function O(a,t){let e=oe(a);return [a.fillColor!=="transparent"?`fill="${a.fillColor}"`:'fill="none"',`stroke="${a.strokeColor}"`,`stroke-width="${a.strokeWidth}"`,'stroke-linecap="round"','stroke-linejoin="round"',e?`stroke-dasharray="${e}"`:""].filter(Boolean).join(" ")}function se(a,t){let{width:e,height:i}=a,n=e/2,r=i/2,s=`${_}px sans-serif`,o=K,h=t?0:a.attributes.length>0?a.attributes.length*L+D*2:D*2,l=e-B*2,d=[];d.push(`<rect x="${m(-n)}" y="${m(-r)}" width="${e}" height="${i}" ${O(a.style)} />`),d.push(`<line x1="${m(-n)}" y1="${m(-r+o)}" x2="${m(n)}" y2="${m(-r+o)}" stroke="${a.style.strokeColor}" stroke-width="${a.style.strokeWidth}" />`),t||d.push(`<line x1="${m(-n)}" y1="${m(-r+o+h)}" x2="${m(n)}" y2="${m(-r+o+h)}" stroke="${a.style.strokeColor}" stroke-width="${a.style.strokeWidth}" />`);let u=t?`<<${a.className||"Interface"}>>`:a.className;d.push(`<text text-anchor="middle" dominant-baseline="central" font-family="sans-serif" font-weight="bold" font-size="${_}" fill="${a.textColor||mt}" x="0" y="${m(-r+o/2)}">${ht(Gt(u,l,s))}</text>`);let c=(p,y,f,M,x)=>{let v=`${f||_}px sans-serif`,b=Gt(p,l,v),P=`<text text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-size="${f||_}" fill="${M||mt}" x="${m(-n+B)}" y="${m(y)}">${ht(b)}</text>`;if(x){let T=tt(b,v);P+=`<line x1="${m(-n+B)}" y1="${m(y)}" x2="${m(-n+B+T)}" y2="${m(y)}" stroke="${M||mt}" stroke-width="1" />`;}return P};if(!t){let p=-r+o+D+L/2;a.attributes.forEach((y,f)=>{d.push(c(`${y.visibility} ${y.name}: ${y.type}`,p+f*L,y.fontSize||a.fontSize||0,y.textColor||a.textColor||"",!!y.strikethrough));});}let g=-r+o+h+D+L/2;return a.methods.forEach((p,y)=>{d.push(c(`${p.visibility} ${p.name}(${p.params}): ${p.returnType}`,g+y*L,p.fontSize||a.fontSize||0,p.textColor||a.textColor||"",!!p.strikethrough));}),d.join("")}function ke(a){let e=k(a.root).positions,i=[],n=s=>{if(s.collapsed)return;let o=e.get(s.id);if(o)for(let h of s.children??[]){let l=e.get(h.id);if(!l)continue;let d=it(h,l.depth),u=a.x+o.x+o.width/2,c=a.y+o.y,g=a.x+l.x-l.width/2,p=a.y+l.y,y=(u+g)/2;i.push(`<path d="M ${m(u)} ${m(c)} C ${m(y)} ${m(c)} ${m(y)} ${m(p)} ${m(g)} ${m(p)}" stroke="${d}" stroke-width="2" fill="none" stroke-linecap="round" />`),n(h);}};n(a.root);let r=s=>{let o=e.get(s.id);if(!o)return;let h=it(s,o.depth),l=o.width/2,d=o.height/2,u=a.x+o.x,c=a.y+o.y;if(i.push(`<rect x="${m(u-l)}" y="${m(c-d)}" width="${o.width}" height="${o.height}" rx="6" ry="6" fill="#ffffff" stroke="${h}" stroke-width="2" />`),s.note){let v="11px sans-serif",b=s.noteColor??h,P=Math.min(tt(s.note,v)+12,130),T=16,E=tt(s.note,v)+12>130?s.note.slice(0,12)+"\u2026":s.note;i.push(`<rect x="${m(u-l)}" y="${m(c-d-T+2)}" width="${P}" height="${T}" rx="4" ry="4" fill="${b}" />`),i.push(`<text text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-size="11" fill="#ffffff" x="${m(u-l+6)}" y="${m(c-d-T/2+2)}">${ht(E)}</text>`);}let g=s.icon?18:0,p=o.width-g-(s.icon?8:0)-16,y=Gt(s.text||"",p,`${14}px sans-serif`),f=tt(y,`${14}px sans-serif`),M=g+(g?8:0)+f,x=u-M/2;if(s.icon&&(i.push(`<text text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-size="16" fill="#1f2937" x="${m(x)}" y="${m(c)}">${ht(s.icon)}</text>`),x+=g+8),i.push(`<text text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-size="${14}" fill="#1f2937" x="${m(x)}" y="${m(c)}">${ht(y)}</text>`),s.children&&s.children.length>0&&!s.collapsed)for(let v of s.children)r(v);};return r(a.root),i.join("")}function Be(a,t){let e=a.rotation*180/Math.PI,i=`<g transform="translate(${m(a.x)} ${m(a.y)}) rotate(${m(e)})">`,n="</g>",r=a.style;switch(a.type){case "rectangle":{let s=a.width,o=a.height;return `${i}<rect x="${m(-s/2)}" y="${m(-o/2)}" width="${s}" height="${o}" ${O(r)} />${n}`}case "rounded-rectangle":{let s=a.width,o=a.height,h=a.borderRadius||8;return `${i}<rect x="${m(-s/2)}" y="${m(-o/2)}" width="${s}" height="${o}" rx="${h}" ry="${h}" ${O(r)} />${n}`}case "circle":{let s=a.radius;return `${i}<circle cx="0" cy="0" r="${s}" ${O(r)} />${n}`}case "ellipse":{let s=a.width,o=a.height;return `${i}<ellipse cx="0" cy="0" rx="${s/2}" ry="${o/2}" ${O(r)} />${n}`}case "diamond":{let s=a.width,o=a.height;return `${i}<polygon points="${Q([[0,-o/2],[s/2,0],[0,o/2],[-s/2,0]])}" ${O(r)} />${n}`}case "triangle":{let s=a.width,o=a.height;return `${i}<polygon points="${Q([[0,-o/2],[s/2,o/2],[-s/2,o/2]])}" ${O(r)} />${n}`}case "hexagon":{let s=a.width,o=a.height;return `${i}<polygon points="${Q(_t(s,o,6,-Math.PI/2))}" ${O(r)} />${n}`}case "pentagon":{let s=a.width,o=a.height;return `${i}<polygon points="${Q(_t(s,o,5,-Math.PI/2))}" ${O(r)} />${n}`}case "octagon":{let s=a.width,o=a.height;return `${i}<polygon points="${Q(_t(s,o,8,-Math.PI/8))}" ${O(r)} />${n}`}case "star":{let s=a.width,o=a.height;return `${i}<polygon points="${Q(_e(s,o))}" ${O(r)} />${n}`}case "parallelogram":{let s=a.width,o=a.height,h=s*.2;return `${i}<polygon points="${Q([[-s/2+h,-o/2],[s/2,-o/2],[s/2-h,o/2],[-s/2,o/2]])}" ${O(r)} />${n}`}case "trapezoid":{let s=a.width,o=a.height,h=s*.15;return `${i}<polygon points="${Q([[-s/2+h,-o/2],[s/2-h,-o/2],[s/2,o/2],[-s/2,o/2]])}" ${O(r)} />${n}`}case "uml-class":return `${i}${se(a,false)}${n}`;case "uml-interface":return `${i}${se(a,true)}${n}`;case "mind-map":return ke(a);case "line":case "arrow":{let s=a,o=s.connectionType||"straight",h=De(s,t);if(h.length<2)return "";let l=s.style.strokeColor,d=s.style.strokeWidth,u=oe(s.style),c=`<path d="${Re(h,o)}" fill="none" stroke="${l}" stroke-width="${d}" stroke-linecap="round" stroke-linejoin="round"${u?` stroke-dasharray="${u}"`:""} />`,g=He(h,s.arrowHead||"end",l,d);return `${c}${g}`}case "draw":{let s=a.points;if(!s||s.length<2)return "";let o=s.map(l=>ae(a,l));if(o.length<2)return "";let h=`M ${m(o[0].x)} ${m(o[0].y)}`;for(let l=1;l<o.length-1;l++){let d=(o[l].x+o[l+1].x)/2,u=(o[l].y+o[l+1].y)/2;h+=` Q ${m(o[l].x)} ${m(o[l].y)} ${m(d)} ${m(u)}`;}return h+=` L ${m(o[o.length-1].x)} ${m(o[o.length-1].y)}`,`<path d="${h}" fill="none" stroke="${r.strokeColor}" stroke-width="${r.strokeWidth}" stroke-linecap="round" stroke-linejoin="round" />`}case "text":{let s=a,o=s.fontSize||16,h=s.textColor||mt,l=Qt(s.text||"",o,s.width,s.height),d="";if(s.highlightColor&&s.highlightColor!=="transparent"){let u=o*.15;d+=`<rect x="${m(-s.width/2-u)}" y="${m(-(l.length*o*1.3)/2-u)}" width="${s.width+u*2}" height="${l.length*o*1.3+u*2}" rx="4" fill="${s.highlightColor}" />`;}return d+=ie(l,o,h),`${i}${d}${n}`}default:{let s=a,o=s.width||100,h=s.height||40,l="";if(s.text){let d=s.fontSize||16,u=Qt(s.text,d,o*.85,h*.85);l+=ie(u,d,s.textColor||mt);}return `${i}<rect x="${m(-o/2)}" y="${m(-h/2)}" width="${o}" height="${h}" ${O(r)} />${l}${n}`}}}function _t(a,t,e,i){let n=a/2,r=t/2,s=[];for(let o=0;o<e;o++){let h=o*2*Math.PI/e+i;s.push([n*Math.cos(h),r*Math.sin(h)]);}return s}function _e(a,t){let e=a/2,i=t/2,n=5,r=.4,s=[];for(let o=0;o<n*2;o++){let h=o*Math.PI/n-Math.PI/2,l=o%2===0?1:r;s.push([e*l*Math.cos(h),i*l*Math.sin(h)]);}return s}function he(a,t={}){let e=t.padding??24,i=t.background===void 0?"#ffffff":t.background??null,n=xt(a,e),r=Math.max(1,Math.ceil(n.width)),s=Math.max(1,Math.ceil(n.height)),o=new Map(a.map(d=>[d.id,d])),h=a.map(d=>Be(d,o)).filter(Boolean).join(`
|
|
4
|
-
`),l=i?`<rect x="${
|
|
5
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="${
|
|
1
|
+
'use strict';var Z={identity(){return {a:1,b:0,c:0,d:1,e:0,f:0}},translation(a,t){return {a:1,b:0,c:0,d:1,e:a,f:t}},rotation(a){let t=Math.cos(a),e=Math.sin(a);return {a:t,b:e,c:-e,d:t,e:0,f:0}},scale(a,t){return {a,b:0,c:0,d:t,e:0,f:0}},multiply(a,t){return {a:a.a*t.a+a.b*t.c,b:a.a*t.b+a.b*t.d,c:a.c*t.a+a.d*t.c,d:a.c*t.b+a.d*t.d,e:a.e*t.a+a.f*t.c+t.e,f:a.e*t.b+a.f*t.d+t.f}},apply(a,t){return {x:a.a*t.x+a.c*t.y+a.e,y:a.b*t.x+a.d*t.y+a.f}},invert(a){let t=a.a*a.d-a.b*a.c;if(Math.abs(t)<1e-10)return null;let e=1/t;return {a:a.d*e,b:-a.b*e,c:-a.c*e,d:a.a*e,e:(a.c*a.f-a.d*a.e)*e,f:(a.b*a.e-a.a*a.f)*e}},createCameraMatrix(a){let t=Z.scale(a.zoom,a.zoom),e=Z.translation(a.x,a.y);return Z.multiply(e,t)}};var nt=class{x=0;y=0;zoom=1;minZoom=.1;maxZoom=10;getMatrix(){return Z.createCameraMatrix({x:this.x,y:this.y,zoom:this.zoom})}getInverseMatrix(){return Z.invert(this.getMatrix())}screenToPage(t){let e=this.getInverseMatrix();return e?Z.apply(e,t):t}pageToScreen(t){return Z.apply(this.getMatrix(),t)}translate(t,e){this.x+=t,this.y+=e;}zoomAt(t,e){let i=this.screenToPage(t);this.zoom=Math.max(this.minZoom,Math.min(this.maxZoom,this.zoom*e));let n=this.pageToScreen(i);this.x+=t.x-n.x,this.y+=t.y-n.y;}reset(){this.x=0,this.y=0,this.zoom=1;}getZoom(){return this.zoom}fitBounds(t,e=50){let i=window.innerWidth,n=window.innerHeight,s=(i-e*2)/t.width,r=(n-e*2)/t.height,o=Math.min(s,r,this.maxZoom);this.zoom=Math.max(this.minZoom,o),this.x=(i-t.width*this.zoom)/2-t.x*this.zoom,this.y=(n-t.height*this.zoom)/2-t.y*this.zoom;}};var Wt={primary:"#3b82f6",selection:{outline:"#3b82f6",handleStroke:"#3b82f6",handleFill:"#ffffff",outlineFill:"rgba(59, 130, 246, 0.1)",shadow:"#3b82f6"},grid:"#e5e7eb",text:"#1f2937",editBorder:"#3b82f6",brushFill:"rgba(59, 130, 246, 0.08)",brushStroke:"rgba(59, 130, 246, 0.8)",guide:"rgba(59, 130, 246, 0.6)",lineHighlight:"rgba(59, 130, 246, 0.4)",genDot:"#3b82f6",genLine:"rgba(59, 130, 246, 0.55)"},I={...Wt,selection:{...Wt.selection}},At=new Set;function le(a){return At.add(a),()=>At.delete(a)}function bt(a){a.selection&&Object.assign(I.selection,a.selection);for(let t of Object.keys(a)){if(t==="selection")continue;let e=a[t];e!==void 0&&(I[t]=e);}At.forEach(t=>t());}function de(){return I}function j(a,t){let e=Kt(a);if(!e)return a;let i=parseInt(e,16),n=i>>16&255,s=i>>8&255,r=i&255;return `rgba(${n}, ${s}, ${r}, ${t})`}function ce(a,t){let e=Kt(a);if(!e)return a;let i=parseInt(e,16),n=t<0?0:255,s=Math.abs(t),r=o=>Math.round((n-o)*s+o).toString(16).padStart(2,"0");return `#${r(i>>16&255)}${r(i>>8&255)}${r(i&255)}`}function Kt(a){let t=a.replace("#","").trim();return /^[0-9a-fA-F]{3}$|^[0-9a-fA-F]{6}$/.test(t)?t.length===3?t.split("").map(e=>e+e).join(""):t:null}var k=class{context;constructor(t){this.context=t;}getCursor(t){return null}dispose(){}};var Ft={"zh-CN":{"save.success":"\u5DF2\u4FDD\u5B58","save.fail":"\u4FDD\u5B58\u5931\u8D25","tool.select":"\u9009\u62E9\u5DE5\u5177","tool.hand":"\u62D6\u62FD\u89C6\u53E3","tool.rectangle":"\u77E9\u5F62","tool.rounded-rectangle":"\u5706\u89D2\u77E9\u5F62","tool.circle":"\u5706\u5F62","tool.ellipse":"\u692D\u5706","tool.diamond":"\u83F1\u5F62","tool.triangle":"\u4E09\u89D2\u5F62","tool.hexagon":"\u516D\u8FB9\u5F62","tool.parallelogram":"\u5E73\u884C\u56DB\u8FB9\u5F62","tool.trapezoid":"\u68AF\u5F62","tool.pentagon":"\u4E94\u8FB9\u5F62","tool.octagon":"\u516B\u8FB9\u5F62","tool.star":"\u661F\u5F62","tool.uml-class":"UML \u7C7B\u56FE","tool.uml-interface":"UML \u63A5\u53E3","tool.line":"\u76F4\u7EBF","tool.arrow":"\u7EBF\u6761","tool.text":"\u6587\u672C","tool.draw":"\u753B\u7B14","tool.pen":"\u753B\u7B14","tool.highlighter":"\u8367\u5149\u7B14","tool.eraser":"\u6A61\u76AE\u64E6","status.none":"\u672A\u9009\u62E9","status.selected":"\u5DF2\u9009\u62E9 {n} \u4E2A\u56FE\u5F62","toolbar.select":"\u9009\u62E9 (V)","toolbar.hand":"\u62D6\u62FD\u89C6\u53E3 (H)","toolbar.shapes":"\u5F62\u72B6","toolbar.grid":"\u7F51\u683C","toolbar.undo":"\u64A4\u9500 (Ctrl+Z)","toolbar.redo":"\u91CD\u505A (Ctrl+Shift+Z)","toolbar.arrow":"\u7BAD\u5934","toolbar.text":"\u6587\u672C","toolbar.pen":"\u753B\u7B14","toolbar.highlighter":"\u8367\u5149\u7B14","toolbar.eraser":"\u6A61\u76AE\u64E6","toolbar.uml-class":"UML \u7C7B\u56FE","toolbar.uml-interface":"UML \u63A5\u53E3","zoom.in":"\u653E\u5927","zoom.out":"\u7F29\u5C0F","zoom.reset":"\u91CD\u7F6E","style.stroke":"\u8FB9\u6846","style.line":"\u7EBF\u6761","style.fill":"\u586B\u5145","style.text":"\u6587\u5B57","style.highlight":"\u9AD8\u4EAE","style.prefix":"\u524D\u7F00\u7B26\u53F7","style.prefix.soon":"\u524D\u7F00\u7B26\u53F7\u5F00\u53D1\u4E2D\uFF0C\u656C\u8BF7\u671F\u5F85","style.none":"\u65E0","style.addColor":"\u6DFB\u52A0\u989C\u8272","style.connection":"\u8FDE\u7EBF","style.arrow":"\u7BAD\u5934","style.dashed":"\u865A\u7EBF","style.solid":"\u5B9E\u7EBF","style.opacity":"\u4E0D\u900F\u660E\u5EA6","style.connection.straight":"\u76F4\u7EBF","style.connection.polyline":"\u6298\u7EBF","style.connection.orthogonal":"\u76F4\u89D2\u6298\u7EBF","style.connection.curve":"\u66F2\u7EBF","style.arrowhead.none":"\u65E0\u7BAD\u5934","style.arrowhead.end":"\u7EC8\u70B9\u7BAD\u5934","style.arrowhead.start":"\u8D77\u70B9\u7BAD\u5934","style.arrowhead.both":"\u53CC\u7BAD\u5934","style.arrowhead.inheritance":"\u7EE7\u627F","style.arrowhead.composition":"\u7EC4\u5408","style.arrowhead.aggregation":"\u805A\u5408","menu.title":"\u9009\u62E9\u65B0\u56FE\u5F62","menu.cancel":"\u70B9\u51FB\u7A7A\u767D\u5904\u53D6\u6D88","shape.rectangle":"\u77E9\u5F62","shape.rounded-rectangle":"\u5706\u89D2","shape.circle":"\u5706\u5F62","shape.ellipse":"\u692D\u5706","shape.diamond":"\u83F1\u5F62","shape.triangle":"\u4E09\u89D2","shape.hexagon":"\u516D\u8FB9\u5F62","shape.parallelogram":"\u5E73\u884C","shape.trapezoid":"\u68AF\u5F62","shape.pentagon":"\u4E94\u8FB9\u5F62","shape.octagon":"\u516B\u8FB9\u5F62","shape.star":"\u661F\u5F62","shape.uml-class":"\u7C7B\u56FE","shape.uml-interface":"\u63A5\u53E3","uml.drag":"\u62D6\u62FD\u6392\u5E8F","uml.delete":"\u5220\u9664\u8BE5\u884C","uml.textColor":"\u6587\u5B57\u989C\u8272","uml.defaultColor":"\u9ED8\u8BA4\u989C\u8272","uml.fontSize":"\u5B57\u53F7","uml.strikethrough":"\u5220\u9664\u7EBF","uml.attribute":"\u5C5E\u6027","uml.method":"\u65B9\u6CD5","minimap.title":"\u5C0F\u5730\u56FE","minimap.expand":"\u5C55\u5F00\u5C0F\u5730\u56FE","minimap.collapse":"\u6536\u8D77\u5C0F\u5730\u56FE","tool.mind-map":"\u601D\u7EF4\u5BFC\u56FE","toolbar.mind-map":"\u601D\u7EF4\u5BFC\u56FE","toolbar.export":"\u5BFC\u51FA","toolbar.export.png":"PNG \u56FE\u7247","toolbar.export.svg":"SVG \u77E2\u91CF\u56FE","toolbar.export.pdf":"PDF \u6587\u6863","shape.mind-map":"\u601D\u7EF4\u5BFC\u56FE","mindmap.defaultRoot":"\u4E2D\u5FC3\u4E3B\u9898","mindmap.defaultBranch":"\u5206\u652F\u4E3B\u9898","mindmap.nodeText":"\u8282\u70B9\u6587\u672C","mindmap.addChild":"\u5B50\u8282\u70B9","mindmap.addSibling":"\u5144\u5F1F\u8282\u70B9","mindmap.deleteNode":"\u5220\u9664\u8282\u70B9","mindmap.color":"\u989C\u8272","mindmap.levelColor":"\u9ED8\u8BA4\u5C42\u7EA7\u8272","mindmap.icon":"\u56FE\u6807","mindmap.noIcon":"\u65E0\u56FE\u6807","mindmap.note":"\u5C5E\u6027\u8BF4\u660E","mindmap.notePlaceholder":"\u8BF4\u660E\u5185\u5BB9\uFF08\u53EF\u9009\uFF09","mindmap.noteColor":"\u8BF4\u660E\u989C\u8272","mindmap.noteColorDefault":"\u540C\u8282\u70B9\u8272","mindmap.collapse":"\u6298\u53E0","mindmap.expand":"\u5C55\u5F00","mindmap.close":"\u5173\u95ED\u7F16\u8F91","mindmap.more":"\u66F4\u591A\u8BBE\u7F6E"},"en-US":{"save.success":"Saved","save.fail":"Save failed","tool.select":"Select tool","tool.hand":"Pan view","tool.rectangle":"Rectangle","tool.rounded-rectangle":"Rounded rectangle","tool.circle":"Circle","tool.ellipse":"Ellipse","tool.diamond":"Diamond","tool.triangle":"Triangle","tool.hexagon":"Hexagon","tool.parallelogram":"Parallelogram","tool.trapezoid":"Trapezoid","tool.pentagon":"Pentagon","tool.octagon":"Octagon","tool.star":"Star","tool.uml-class":"UML class","tool.uml-interface":"UML interface","tool.line":"Line","tool.arrow":"Line","tool.text":"Text","tool.draw":"Pen","tool.pen":"Pen","tool.highlighter":"Highlighter","tool.eraser":"Eraser","status.none":"Nothing selected","status.selected":"{n} shapes selected","toolbar.select":"Select (V)","toolbar.hand":"Pan view (H)","toolbar.shapes":"Shapes","toolbar.grid":"Grid","toolbar.undo":"Undo (Ctrl+Z)","toolbar.redo":"Redo (Ctrl+Shift+Z)","toolbar.arrow":"Arrow","toolbar.text":"Text","toolbar.pen":"Pen","toolbar.highlighter":"Highlighter","toolbar.eraser":"Eraser","toolbar.uml-class":"UML class","toolbar.uml-interface":"UML interface","zoom.in":"Zoom in","zoom.out":"Zoom out","zoom.reset":"Reset","style.stroke":"Border","style.line":"Line","style.fill":"Fill","style.text":"Text","style.highlight":"Highlight","style.prefix":"Prefix","style.prefix.soon":"Prefix symbols are coming soon","style.none":"None","style.addColor":"Add color","style.connection":"Connection","style.arrow":"Arrow head","style.dashed":"Dashed","style.solid":"Solid","style.opacity":"Opacity","style.connection.straight":"Straight","style.connection.polyline":"Polyline","style.connection.orthogonal":"Orthogonal","style.connection.curve":"Curve","style.arrowhead.none":"None","style.arrowhead.end":"End","style.arrowhead.start":"Start","style.arrowhead.both":"Both","style.arrowhead.inheritance":"Inheritance","style.arrowhead.composition":"Composition","style.arrowhead.aggregation":"Aggregation","menu.title":"Create shape","menu.cancel":"Click empty space to cancel","shape.rectangle":"Rectangle","shape.rounded-rectangle":"Rounded","shape.circle":"Circle","shape.ellipse":"Ellipse","shape.diamond":"Diamond","shape.triangle":"Triangle","shape.hexagon":"Hexagon","shape.parallelogram":"Parallelogram","shape.trapezoid":"Trapezoid","shape.pentagon":"Pentagon","shape.octagon":"Octagon","shape.star":"Star","shape.uml-class":"Class","shape.uml-interface":"Interface","uml.drag":"Drag to reorder","uml.delete":"Delete row","uml.textColor":"Text color","uml.defaultColor":"Default color","uml.fontSize":"Font size","uml.strikethrough":"Strikethrough","uml.attribute":"Attributes","uml.method":"Methods","minimap.title":"Minimap","minimap.expand":"Expand minimap","minimap.collapse":"Collapse minimap","tool.mind-map":"Mind map","toolbar.mind-map":"Mind map","toolbar.export":"Export","toolbar.export.png":"PNG image","toolbar.export.svg":"SVG vector","toolbar.export.pdf":"PDF document","shape.mind-map":"Mind map","mindmap.defaultRoot":"Central topic","mindmap.defaultBranch":"Branch topic","mindmap.nodeText":"Node text","mindmap.addChild":"Child","mindmap.addSibling":"Sibling","mindmap.deleteNode":"Delete node","mindmap.color":"Color","mindmap.levelColor":"Default level color","mindmap.icon":"Icon","mindmap.noIcon":"No icon","mindmap.note":"Note","mindmap.notePlaceholder":"Note content (optional)","mindmap.noteColor":"Note color","mindmap.noteColorDefault":"Same as node","mindmap.collapse":"Collapse","mindmap.expand":"Expand","mindmap.close":"Close editor","mindmap.more":"More settings"}},Mt="zh-CN",Lt=new Set;function vt(a){Mt!==a&&(Mt=a,Lt.forEach(t=>t()));}function ue(){return Mt}function ge(a){return Lt.add(a),()=>Lt.delete(a)}function W(a,t){let i=Ft[Mt][a]??Ft["zh-CN"][a];if(t)for(let[n,s]of Object.entries(t))i=i.replace(new RegExp(`\\{${n}\\}`,"g"),String(s));return i}var Nt=["#ef4444","#f59e0b","#10b981","#3b82f6","#8b5cf6","#ec4899"],q=14,pe=40,ye=80,fe=240;function it(a,t){return a.color??Nt[t%Nt.length]}function jt(a){let t=a.text||"",e=0;for(let n of t)e+=/[\u2e80-\u9fff\uf900-\ufaff\uff00-\uffef\u3000-\u303f]/.test(n)?1:.6;let i=Math.max(80,Math.min(240,Math.ceil(e*14)+24));return a.icon&&(i+=26),{width:i,height:40}}function Pt(a){let t={...a};return a.children&&(t.children=a.children.map(e=>Pt(e))),t}function Tt(a,t,e){if(a.id===t)return {...a,...e};let i=a.children??[],n=i.map(s=>Tt(s,t,e));return n.some((s,r)=>s!==i[r])?{...a,children:n}:a}function Rt(a,t,e){if(a.id===t)return {...a,children:[...a.children??[],e],collapsed:false};let i=a.children??[],n=i.map(s=>Rt(s,t,e));return n.some((s,r)=>s!==i[r])?{...a,children:n}:a}function Vt(a,t,e){let i=a.children??[];for(let n=0;n<i.length;n++){if(i[n].id===t){let r=[...i];return r.splice(n+1,0,e),{...a,children:r}}let s=Vt(i[n],t,e);if(s!==i[n])return {...a,children:i.map(r=>r===i[n]?s:r)}}return a}function kt(a,t){if(a.id===t)return null;let e=a.children??[],i=e.map(n=>kt(n,t)).filter(n=>n!==null);return i.length!==e.length||i.some((n,s)=>n!==e[s])?{...a,children:i}:a}function J(a,t){if(a.id===t)return a;for(let e of a.children??[]){let i=J(e,t);if(i)return i}return null}function Zt(a,t){if(a.id===t)return 0;for(let e of a.children??[]){let i=Zt(e,t);if(i!==-1)return i+1}return -1}function lt(a,t){for(let e of a.children??[]){if(e.id===t)return a;let i=lt(e,t);if(i)return i}return null}function qt(a){let t=1;for(let e of a.children??[])t+=qt(e);return t}function Jt(a,t){t.set(a.id,jt(a));for(let e of a.children??[])Jt(e,t);}function B(a){let t=new Map;Jt(a,t);let e=new Map,i=c=>{let g=c.collapsed?[]:c.children??[];if(g.length===0)e.set(c.id,t.get(c.id).height);else {let p=0;for(let y of g)p+=i(y);p+=16*(g.length-1),e.set(c.id,Math.max(t.get(c.id).height,p));}return e.get(c.id)};i(a);let n=new Map,s=(c,g,p,y)=>{let m=e.get(c.id),v=t.get(c.id);if(n.set(c.id,{x:p,y:y+m/2,depth:g,width:v.width,height:v.height}),c.collapsed)return;let x=y;for(let P of c.children??[]){let b=t.get(P.id);s(P,g+1,p+v.width/2+48+b.width/2,x),x+=e.get(P.id)+16;}};s(a,0,0,-e.get(a.id)/2);let r=1/0,o=-1/0,h=1/0,l=-1/0;n.forEach(c=>{r=Math.min(r,c.x-c.width/2),o=Math.max(o,c.x+c.width/2),h=Math.min(h,c.y-c.height/2),l=Math.max(l,c.y+c.height/2);});let d=(r+o)/2,u=(h+l)/2;return n.forEach(c=>{c.x-=d,c.y-=u;}),{positions:n,width:o-r,height:l-h}}var me={strokeColor:"#1f2937",fillColor:"#f8fafc",fillOpacity:.9,strokeWidth:2,strokeDash:null},xe={rectangle:{width:120,height:60},"rounded-rectangle":{width:120,height:60,borderRadius:8},circle:{width:80,height:80},ellipse:{width:100,height:70},diamond:{width:100,height:80},triangle:{width:100,height:90},hexagon:{width:100,height:90},parallelogram:{width:120,height:60},trapezoid:{width:120,height:70},pentagon:{width:100,height:90},octagon:{width:100,height:90},star:{width:100,height:100}},U=14,L=22,K=36,_=14,D=8,dt=160,Se=["rectangle","rounded-rectangle","circle","ellipse","diamond","triangle","hexagon","parallelogram","trapezoid","pentagon","octagon","star","uml-class","uml-interface","mind-map"];function It(a){return Se.includes(a)}function Ht(a,t,e){let i=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,n=xe[a]||{width:120,height:60},s=n.width,r=n.height,o=n.radius??s/2,h=n.borderRadius??8,l=e??{...me};switch(a){case "rounded-rectangle":return {id:i,type:"rounded-rectangle",x:t.x,y:t.y,width:s,height:r,borderRadius:h,rotation:0,style:l};case "circle":return {id:i,type:"circle",x:t.x,y:t.y,radius:o,rotation:0,style:l};case "ellipse":return {id:i,type:"ellipse",x:t.x,y:t.y,width:s,height:r,rotation:0,style:l};case "diamond":return {id:i,type:"diamond",x:t.x,y:t.y,width:s,height:r,rotation:0,style:l};case "triangle":return {id:i,type:"triangle",x:t.x,y:t.y,width:s,height:r,rotation:0,style:l};case "hexagon":return {id:i,type:"hexagon",x:t.x,y:t.y,width:s,height:r,rotation:0,style:l};case "parallelogram":return {id:i,type:"parallelogram",x:t.x,y:t.y,width:s,height:r,rotation:0,style:l};case "trapezoid":return {id:i,type:"trapezoid",x:t.x,y:t.y,width:s,height:r,rotation:0,style:l};case "pentagon":return {id:i,type:"pentagon",x:t.x,y:t.y,width:s,height:r,rotation:0,style:l};case "octagon":return {id:i,type:"octagon",x:t.x,y:t.y,width:s,height:r,rotation:0,style:l};case "star":return {id:i,type:"star",x:t.x,y:t.y,width:s,height:r,rotation:0,style:l};case "uml-class":{let d="ClassName",u=[{id:`attr_${Date.now()}_1`,visibility:"+",name:"field",type:"string"}],c=[{id:`meth_${Date.now()}_1`,visibility:"+",name:"method",params:"param",returnType:"void"}],{width:g,height:p}=Ct(d,u,c);return {id:i,type:"uml-class",x:t.x,y:t.y,width:g,height:p,className:d,attributes:u,methods:c,rotation:0,style:{...l,fillColor:"#ffffff"}}}case "uml-interface":{let d="Interface",u=[{id:`meth_${Date.now()}_1`,visibility:"+",name:"method",params:"type",returnType:"type"}],c=U*.6,g=u.map(x=>`${x.visibility} ${x.name}(${x.params}): ${x.returnType}`),p=Math.max(d.length,...g.map(x=>x.length),0),y=Math.max(dt,p*c+_*2),m=u.length>0?u.length*L+D*2:D*2,v=K+m;return {id:i,type:"uml-interface",x:t.x,y:t.y,width:y,height:v,className:d,methods:u,rotation:0,style:{...l,fillColor:"#ffffff"}}}case "mind-map":{let d=p=>`mm_${p}_${Date.now()}_${Math.random().toString(36).substr(2,6)}`,u={id:d("root"),text:W("mindmap.defaultRoot"),children:[{id:d("b1"),text:W("mindmap.defaultBranch")},{id:d("b2"),text:W("mindmap.defaultBranch")},{id:d("b3"),text:W("mindmap.defaultBranch")}]},{width:c,height:g}=B(u);return {id:i,type:"mind-map",x:t.x,y:t.y,width:c,height:g,root:u,rotation:0,style:{...l,fillColor:"#ffffff"}}}default:return {id:i,type:"rectangle",x:t.x,y:t.y,width:s,height:r,rotation:0,style:l}}}function Ct(a,t,e){let i=U*.6,n=[a];for(let u of t)n.push(`${u.visibility} ${u.name}: ${u.type}`);for(let u of e)n.push(`${u.visibility} ${u.name}(${u.params}): ${u.returnType}`);let r=Math.max(...n.map(u=>u.length),0)*i+_*2,o=Math.max(dt,r),h=t.length>0?t.length*L+D*2:D*2,l=e.length>0?e.length*L+D*2:D*2,d=K+h+l;return {width:o,height:d}}var V=class extends k{type;constructor(t,e){super(t),this.type=e;}onPointerDown(t,e){let i=Ht(this.type,t);this.context.commitHistory(),this.context.addShape(i),this.context.selectShape(i.id,false);}onPointerMove(t,e){}onPointerUp(t,e){this.context.setActiveTool("select");}onKeyDown(t){}onKeyUp(t){}getCursor(t){return this.context.getMindMapCursorHitAtPoint(t)?"pointer":"crosshair"}};var Bt=14,Et=class extends k{type="eraser";erasing=false;lastPoint=null;erasedIds=new Set;onPointerDown(t){this.erasing=true,this.lastPoint=t,this.erasedIds.clear(),this.context.commitHistory(),this.context.setEraserPoint(t),this.eraseAt(t);}onPointerMove(t){if(!this.erasing||!this.lastPoint)return;let e=this.lastPoint,i=Math.hypot(t.x-e.x,t.y-e.y),n=Math.max(1,Math.ceil(i/Math.max(this.brushRadius()*.5,1)));for(let s=1;s<=n;s++){let r=s/n;this.eraseAt({x:e.x+(t.x-e.x)*r,y:e.y+(t.y-e.y)*r});}this.lastPoint=t,this.context.setEraserPoint(t);}onPointerUp(){this.erasing=false,this.lastPoint=null,this.erasedIds.clear(),this.context.setEraserPoint(null);}onKeyDown(){}onKeyUp(){}getCursor(){return this.erasing?"grabbing":"crosshair"}dispose(){this.erasing=false,this.lastPoint=null,this.erasedIds.clear(),this.context.setEraserPoint(null);}brushRadius(){return Bt/this.context.getCamera().getZoom()}eraseAt(t){let e=this.context.getShapesInBrushRadius(t,this.brushRadius());for(let i of e)this.erasedIds.has(i.id)||(this.erasedIds.add(i.id),this.context.deleteShape(i.id));}};var st=class a{ctx;width=0;height=0;dpr=window.devicePixelRatio||1;showGrid=false;textLayoutCache=new Map;static TEXT_CACHE_LIMIT=500;constructor(t,e){let i=t.getContext("2d");if(!i)throw new Error("Failed to get Canvas 2D context");this.ctx=i,typeof e=="number"&&e>0&&(this.dpr=e);}resize(t,e){this.width=t,this.height=e;let i=Math.ceil(t*this.dpr),n=Math.ceil(e*this.dpr);(this.ctx.canvas.width!==i||this.ctx.canvas.height!==n)&&(this.ctx.canvas.width=i,this.ctx.canvas.height=n,this.ctx.canvas.style.width=`${t}px`,this.ctx.canvas.style.height=`${e}px`);}setShowGrid(t){this.showGrid=t;}render(t,e,i,n,s,r,o,h,l,d,u){let c=this.ctx,g=e.getZoom(),p=e.x,y=e.y;c.setTransform(1,0,0,1,0,0),c.clearRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height),u&&(c.fillStyle=u,c.fillRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height));let m=this.dpr*g;c.setTransform(m,0,0,m,m*p,m*y),this.showGrid&&this.drawGrid(c,g,p,y);let v=null;for(let P of t)if(P.type==="arrow"&&(P.startBinding||P.endBinding)){v=new Map,t.forEach(b=>v.set(b.id,b));break}let x=v??new Map;t.forEach(P=>{c.save(),c.translate(P.x,P.y),c.rotate(P.rotation);let b=i.has(P.id);this.drawShape(c,P,b,g,x,l,d),c.restore();}),o&&this.drawGenerationPreview(c,o,g),n&&this.drawBrushRect(c,n,g),s&&s.length>0&&this.drawSnapGuides(c,s,g),r&&this.drawConnectingTargetHighlight(c,r,t,g),h&&this.drawEraserBrush(c,h,g),c.setTransform(1,0,0,1,0,0);}drawEraserBrush(t,e,i){let n=Bt/i;t.beginPath(),t.arc(e.x,e.y,n,0,Math.PI*2),t.fillStyle=j(I.primary,.12),t.fill(),t.strokeStyle=j(I.primary,.55),t.lineWidth=1.5/i,t.stroke();}drawConnectingTargetHighlight(t,e,i,n){let s=i.find(l=>l.id===e);if(!s||s.type==="line"||s.type==="arrow"||s.type==="draw")return;let r=this.getShapeWorldBounds(s),o=[{x:r.x+r.width/2,y:r.y},{x:r.x+r.width,y:r.y+r.height/2},{x:r.x+r.width/2,y:r.y+r.height},{x:r.x,y:r.y+r.height/2}],h=6/n;t.save(),o.forEach(l=>{t.beginPath(),t.arc(l.x,l.y,h,0,Math.PI*2),t.fillStyle=I.selection.handleFill,t.fill(),t.strokeStyle=I.primary,t.lineWidth=2/n,t.stroke();}),t.restore();}getShapeWorldBounds(t){let e=this.getShapeBounds(t);return {x:t.x+e.x,y:t.y+e.y,width:e.width,height:e.height}}drawBrushRect(t,e,i){t.save(),t.fillStyle=I.brushFill,t.strokeStyle=I.brushStroke,t.lineWidth=1.5/i,t.setLineDash([4/i,4/i]),t.beginPath(),t.rect(e.x,e.y,e.width,e.height),t.fill(),t.stroke(),t.restore();}drawGrid(t,e,i,n){let s=-i,r=-n,o=s+this.width/e,h=r+this.height/e,l=20;for(;l*e<10;)l*=2;t.strokeStyle=I.grid,t.lineWidth=1/e,t.beginPath();for(let d=Math.floor(s/l)*l;d<=o;d+=l)t.moveTo(d,r),t.lineTo(d,h);for(let d=Math.floor(r/l)*l;d<=h;d+=l)t.moveTo(s,d),t.lineTo(o,d);t.stroke();}drawShape(t,e,i,n,s,r,o){switch(this.applyStyle(t,e.style,n),e.type){case "rectangle":this.drawRectangle(t,e,i);break;case "rounded-rectangle":this.drawRoundedRectangle(t,e,i);break;case "circle":this.drawCircle(t,e,i);break;case "ellipse":this.drawEllipse(t,e,i);break;case "diamond":this.drawDiamond(t,e,i);break;case "triangle":this.drawTriangle(t,e,i);break;case "hexagon":this.drawHexagon(t,e,i);break;case "parallelogram":this.drawParallelogram(t,e,i);break;case "trapezoid":this.drawTrapezoid(t,e,i);break;case "pentagon":this.drawPentagon(t,e,i);break;case "octagon":this.drawOctagon(t,e,i);break;case "star":this.drawStar(t,e,i);break;case "uml-class":this.drawUmlClass(t,e,i);break;case "uml-interface":this.drawUmlInterface(t,e,i);break;case "mind-map":this.drawMindMap(t,e,i,r,o);break;case "line":this.drawLine(t,e,s,i,n);break;case "arrow":this.drawArrow(t,e,s,i,n);break;case "text":this.drawText(t,e);break;case "draw":this.drawFreehand(t,e);break}if(e.text&&e.type!=="text"&&e.type!=="line"&&e.type!=="arrow"&&e.type!=="draw"&&this.drawShapeText(t,e),i){let h=e.type==="line"||e.type==="arrow";e.type==="mind-map"||(h?this.drawSelectionHandles(t,e,n):(this.drawSelectionOutline(t,e,n),this.drawSelectionHandles(t,e,n)));}}applyStyle(t,e,i){let n=e.strokeOpacity??1;t.strokeStyle=n<1&&e.strokeColor!=="transparent"?j(e.strokeColor,n):e.strokeColor,t.lineWidth=e.strokeWidth/i,t.lineCap="round",t.lineJoin="round";let s=e.fillOpacity??1;s<1&&e.fillColor!=="transparent"?t.fillStyle=j(e.fillColor,s):t.fillStyle=e.fillColor,e.strokeDash?t.setLineDash(e.strokeDash):t.setLineDash([]);}drawRectangle(t,e,i){t.beginPath(),t.rect(-e.width/2,-e.height/2,e.width,e.height),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawRoundedRectangle(t,e,i){let{width:n,height:s,borderRadius:r}=e;t.beginPath(),t.roundRect(-n/2,-s/2,n,s,r),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawCircle(t,e,i){t.beginPath(),t.arc(0,0,e.radius,0,Math.PI*2),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawEllipse(t,e,i){t.beginPath(),t.ellipse(0,0,e.width/2,e.height/2,0,0,Math.PI*2),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawDiamond(t,e,i){t.beginPath(),t.moveTo(0,-e.height/2),t.lineTo(e.width/2,0),t.lineTo(0,e.height/2),t.lineTo(-e.width/2,0),t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawTriangle(t,e,i){t.beginPath(),t.moveTo(0,-e.height/2),t.lineTo(e.width/2,e.height/2),t.lineTo(-e.width/2,e.height/2),t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawHexagon(t,e,i){let n=e.width/2,s=e.height/2;t.beginPath();for(let r=0;r<6;r++){let o=r*Math.PI/3-Math.PI/2,h=n*Math.cos(o),l=s*Math.sin(o);r===0?t.moveTo(h,l):t.lineTo(h,l);}t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawParallelogram(t,e,i){let{width:n,height:s}=e,r=n*.2;t.beginPath(),t.moveTo(-n/2+r,-s/2),t.lineTo(n/2,-s/2),t.lineTo(n/2-r,s/2),t.lineTo(-n/2,s/2),t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawTrapezoid(t,e,i){let{width:n,height:s}=e,r=n*.15;t.beginPath(),t.moveTo(-n/2+r,-s/2),t.lineTo(n/2-r,-s/2),t.lineTo(n/2,s/2),t.lineTo(-n/2,s/2),t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawPentagon(t,e,i){let n=e.width/2,s=e.height/2;t.beginPath();for(let r=0;r<5;r++){let o=r*2*Math.PI/5-Math.PI/2,h=n*Math.cos(o),l=s*Math.sin(o);r===0?t.moveTo(h,l):t.lineTo(h,l);}t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawOctagon(t,e,i){let n=e.width/2,s=e.height/2;t.beginPath();for(let r=0;r<8;r++){let o=r*Math.PI/4-Math.PI/8,h=n*Math.cos(o),l=s*Math.sin(o);r===0?t.moveTo(h,l):t.lineTo(h,l);}t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawStar(t,e,i){let n=e.width/2,s=e.height/2,r=5,o=.4;t.beginPath();for(let h=0;h<r*2;h++){let l=h*Math.PI/r-Math.PI/2,d=h%2===0?1:o,u=n*d*Math.cos(l),c=s*d*Math.sin(l);h===0?t.moveTo(u,c):t.lineTo(u,c);}t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawUmlClass(t,e,i){let{width:n,height:s,className:r,attributes:o,methods:h}=e,l=n/2,d=s/2,u=K,c=o.length>0?o.length*L+D*2:D*2;t.beginPath(),t.rect(-l,-d,n,s),e.style.fillColor!=="transparent"&&(t.fillStyle=e.style.fillColor,t.fill()),t.stroke(),t.beginPath(),t.moveTo(-l,-d+u),t.lineTo(l,-d+u),t.moveTo(-l,-d+u+c),t.lineTo(l,-d+u+c),t.stroke(),t.save(),t.textBaseline="middle";let g=n-_*2,p=x=>{if(t.measureText(x).width<=g)return x;let P="\u2026",b=0,M=x.length;for(;b<M;){let T=b+M+1>>1;t.measureText(x.slice(0,T)+P).width<=g?b=T:M=T-1;}return x.slice(0,b)+P},y=(x,P,b,M,T,E,H)=>{let Y=M||U,F=T||"#1f2937";t.font=`${Y}px sans-serif`,t.fillStyle=F,t.textAlign=H;let N=p(x);if(t.fillText(N,P,b),E){let R=t.measureText(N).width,St=P;t.strokeStyle=F,t.beginPath(),t.moveTo(St,b),t.lineTo(St+R,b),t.stroke();}};t.font=`bold ${e.fontSize||U}px sans-serif`,t.textAlign="center",t.fillStyle=e.textColor||"#1f2937",t.fillText(p(r),0,-d+u/2);let m=-d+u+D+L/2;o.forEach((x,P)=>{let b=`${x.visibility} ${x.name}: ${x.type}`;y(b,-l+_,m+P*L,x.fontSize||e.fontSize||0,x.textColor||e.textColor||"",!!x.strikethrough,"left");});let v=-d+u+c+D+L/2;h.forEach((x,P)=>{let b=`${x.visibility} ${x.name}(${x.params}): ${x.returnType}`;y(b,-l+_,v+P*L,x.fontSize||e.fontSize||0,x.textColor||e.textColor||"",!!x.strikethrough,"left");}),t.restore();}drawUmlInterface(t,e,i){let{width:n,height:s,className:r,methods:o}=e,h=n/2,l=s/2,d=K;t.beginPath(),t.rect(-h,-l,n,s),e.style.fillColor!=="transparent"&&(t.fillStyle=e.style.fillColor,t.fill()),t.stroke(),t.beginPath(),t.moveTo(-h,-l+d),t.lineTo(h,-l+d),t.stroke(),t.save(),t.textBaseline="middle";let u=n-_*2,c=m=>{if(t.measureText(m).width<=u)return m;let v="\u2026",x=0,P=m.length;for(;x<P;){let b=x+P+1>>1;t.measureText(m.slice(0,b)+v).width<=u?x=b:P=b-1;}return m.slice(0,x)+v},g=(m,v,x,P,b,M,T)=>{let E=P||U,H=b||"#1f2937";t.font=`${E}px sans-serif`,t.fillStyle=H,t.textAlign=T;let Y=c(m);if(t.fillText(Y,v,x),M){let F=t.measureText(Y).width,N=v;t.strokeStyle=H,t.beginPath(),t.moveTo(N,x),t.lineTo(N+F,x),t.stroke();}};t.font=`bold ${e.fontSize||U}px sans-serif`,t.textAlign="center",t.fillStyle=e.textColor||"#1f2937";let p=`<<${r||"Interface"}>>`;t.fillText(c(p),0,-l+d/2);let y=-l+d+D+L/2;o.forEach((m,v)=>{let x=`${m.visibility} ${m.name}(${m.params}): ${m.returnType}`;g(x,-h+_,y+v*L,m.fontSize||e.fontSize||0,m.textColor||e.textColor||"",!!m.strikethrough,"left");}),t.restore();}static DEFAULT_CORNER_RADIUS=10;static ROUTE_CLEARANCE=30;static CONNECTION_LEAD=24;static CONNECTED_PAD=8;drawMindMap(t,e,i,n,s){let o=B(e.root).positions;this.drawMindMapConnections(t,e.root,o),this.drawMindMapNodes(t,e,o,n,s);}drawMindMapConnections(t,e,i){let n=s=>{if(s.collapsed)return;let r=i.get(s.id);if(r)for(let o of s.children??[]){let h=i.get(o.id);if(!h)continue;let l=it(o,h.depth);t.strokeStyle=l,t.lineWidth=2,t.lineCap="round",t.beginPath(),t.moveTo(r.x+r.width/2,r.y);let d=(r.x+r.width/2+(h.x-h.width/2))/2;t.bezierCurveTo(d,r.y,d,h.y,h.x-h.width/2,h.y),t.stroke(),n(o);}};n(e);}drawMindMapNodes(t,e,i,n,s){let r=e.root,o=h=>{let l=i.get(h.id);if(!l)return;let d=it(h,l.depth),u=l.width/2,c=l.height/2;if(t.fillStyle="#ffffff",t.strokeStyle=d,t.lineWidth=2,t.beginPath(),t.roundRect(l.x-u,l.y-c,l.width,l.height,6),t.fill(),t.stroke(),s&&s.shapeId===e.id&&s.nodeId===h.id&&(t.fillStyle=j(I.primary,.06),t.strokeStyle=j(I.primary,.55),t.lineWidth=2,t.beginPath(),t.roundRect(l.x-u,l.y-c,l.width,l.height,6),t.fill(),t.stroke()),n&&n.shapeId===e.id&&n.nodeId===h.id&&(t.fillStyle=j(I.primary,.12),t.strokeStyle=I.primary,t.lineWidth=2.5,t.beginPath(),t.roundRect(l.x-u,l.y-c,l.width,l.height,6),t.fill(),t.stroke()),h.children&&h.children.length>0&&(t.fillStyle="#ffffff",t.strokeStyle=d,t.lineWidth=2,t.beginPath(),t.arc(l.x+u+10,l.y,8,0,Math.PI*2),t.fill(),t.stroke(),t.fillStyle=d,t.font="bold 13px sans-serif",t.textAlign="center",t.textBaseline="middle",t.fillText(h.collapsed?"+":"\u2212",l.x+u+10,l.y+.5)),h.note){let T=h.noteColor??d;t.font="11px sans-serif";let E=Math.min(t.measureText(h.note).width+12,130),H=16;t.fillStyle=T,t.beginPath(),t.roundRect(l.x-u,l.y-c-H+2,E,H,4),t.fill(),t.fillStyle="#ffffff",t.font="11px sans-serif",t.textAlign="left",t.textBaseline="middle",t.fillText(t.measureText(h.note).width+12>130?h.note.slice(0,12)+"\u2026":h.note,l.x-u+6,l.y-c-H/2+2);}t.font=`${14}px sans-serif`;let m=h.icon?18:0,v=l.width-m-(h.icon?8:0)-16,x=this.ellipsizeText(t,h.text||"",v),P=t.measureText(x).width,b=m+(m?8:0)+P,M=l.x-b/2;if(t.textBaseline="middle",h.icon&&(t.font="16px sans-serif",t.textAlign="left",t.fillStyle="#1f2937",t.fillText(h.icon,M,l.y+1),M+=m+8),t.font=`${14}px sans-serif`,t.textAlign="left",t.fillStyle="#1f2937",t.fillText(x,M,l.y),!h.collapsed)for(let T of h.children??[])o(T);};o(r);}ellipsizeText(t,e,i){if(i<=0)return "";if(t.measureText(e).width<=i)return e;let n="\u2026",s=0,r=e.length;for(;s<r;){let o=s+r+1>>1;t.measureText(e.slice(0,o)+n).width<=i?s=o:r=o-1;}return e.slice(0,s)+n}drawLine(t,e,i,n,s){if(e.points.length<2)return;let r=e.points.map(d=>({x:d.x,y:d.y}));r.length>=2&&(r[0]=this.clampToShapeOutline(r[0],i,e.id,r[r.length-1]),r[r.length-1]=this.clampToShapeOutline(r[r.length-1],i,e.id,r[0]));let o=r.map(d=>({x:d.x-e.x,y:d.y-e.y})),h=e.connectionType||"straight",l=h==="straight"?this.getAlignedPoints(o):this.buildPathPoints(o,h,this.collectRoutingObstacles(e.id,o[0],o[o.length-1],i,{x:e.x,y:e.y}),{fromN:this.getDockNormal(r[0],i,e.id),toN:this.getDockNormal(r[r.length-1],i,e.id)});if(h==="straight"){t.beginPath(),t.moveTo(o[0].x,o[0].y);for(let d=1;d<o.length;d++)t.lineTo(o[d].x,o[d].y);t.stroke(),t.setLineDash([]);}else h==="orthogonal"?this.drawSharpPolyline(t,l):this.drawRoundedPolyline(t,l,a.DEFAULT_CORNER_RADIUS),t.stroke(),t.setLineDash([]);n&&this.drawLinearHighlight(t,l,s);}drawArrow(t,e,i,n,s){if(e.points.length<2)return;let r=e.points.map(c=>({x:c.x,y:c.y}));if(e.startBinding){let c=i.get(e.startBinding.toShapeId);c&&(r[0]=this.getBindingPoint(c,e.startBinding));}if(e.endBinding){let c=i.get(e.endBinding.toShapeId);c&&(r[r.length-1]=this.getBindingPoint(c,e.endBinding));}r[0]=this.clampToShapeOutline(r[0],i,e.id,r[r.length-1]),r[r.length-1]=this.clampToShapeOutline(r[r.length-1],i,e.id,r[0]);let o=r.map(c=>({x:c.x-e.x,y:c.y-e.y})),h=e.connectionType||"straight",l=e.arrowHead??"end";!!e.dashed?t.setLineDash([8,5]):t.setLineDash([]);let u;if(h==="straight"){let c=this.getAlignedPoints(o);u=c,t.beginPath(),t.moveTo(c[0].x,c[0].y);for(let g=1;g<c.length;g++)t.lineTo(c[g].x,c[g].y);t.stroke(),this.drawArrowHeads(t,c,l);}else u=this.buildPathPoints(o,h,this.collectRoutingObstacles(e.id,o[0],o[o.length-1],i,{x:e.x,y:e.y}),{fromN:this.getDockNormal(r[0],i,e.id),toN:this.getDockNormal(r[r.length-1],i,e.id)}),h==="orthogonal"?this.drawSharpPolyline(t,u):this.drawRoundedPolyline(t,u,a.DEFAULT_CORNER_RADIUS),t.stroke(),this.drawArrowHeads(t,u,l);t.setLineDash([]),n&&this.drawLinearHighlight(t,u,s);}drawLinearHighlight(t,e,i){if(!(!e||e.length<2)){t.save(),t.strokeStyle=I.lineHighlight,t.lineWidth=7/i,t.lineCap="round",t.lineJoin="round",t.setLineDash([]),t.beginPath(),t.moveTo(e[0].x,e[0].y);for(let n=1;n<e.length;n++)t.lineTo(e[n].x,e[n].y);t.stroke(),t.restore();}}drawGenerationPreview(t,e,i){let{from:n,to:s,type:r}=e;t.save(),t.beginPath(),t.arc(n.x,n.y,7/i,0,Math.PI*2),t.fillStyle=I.genDot,t.fill(),t.strokeStyle=I.genLine,t.lineWidth=2/i,t.setLineDash([5/i,4/i]),t.lineCap="round",t.beginPath(),t.moveTo(n.x,n.y),t.lineTo(s.x,s.y),t.stroke(),r&&this.drawPreviewShapeOutline(t,s,r,i),t.restore();}drawPreviewShapeOutline(t,e,i,n){let l=e.x,d=e.y;switch(t.strokeStyle=I.genLine,t.lineWidth=1.5/n,t.setLineDash([6/n,4/n]),t.beginPath(),i){case "circle":case "ellipse":t.ellipse(l,d,i==="circle"?40:120/2,i==="circle"?40:60/2,0,0,Math.PI*2);break;case "diamond":t.moveTo(l,d-30),t.lineTo(l+60,d),t.lineTo(l,d+30),t.lineTo(l-60,d),t.closePath();break;case "triangle":t.moveTo(l,d-30),t.lineTo(l+60,d+30),t.lineTo(l-60,d+30),t.closePath();break;case "hexagon":for(let u=0;u<6;u++){let c=u*Math.PI/3-Math.PI/2,g=l+60*Math.cos(c),p=d+30*Math.sin(c);u===0?t.moveTo(g,p):t.lineTo(g,p);}t.closePath();break;case "parallelogram":t.moveTo(l-60+18,d-30),t.lineTo(l+60,d-30),t.lineTo(l+60-18,d+30),t.lineTo(l-60,d+30),t.closePath();break;default:t.roundRect(l-60,d-30,120,60,i==="rounded-rectangle"?8:4);break}t.stroke();}static ALIGN_TOLERANCE=8;getAlignedPoints(t){if(t.length<2)return t;let e=t[0],i=t[t.length-1],n=i.x-e.x,s=i.y-e.y,r=a.ALIGN_TOLERANCE;if(Math.abs(s)<=r){let o=(e.y+i.y)/2;return t.map(h=>({x:h.x,y:o}))}if(Math.abs(n)<=r){let o=(e.x+i.x)/2;return t.map(h=>({x:o,y:h.y}))}return t}buildPathPoints(t,e,i=[],n={}){if(t.length<2||e==="straight")return t;switch(e){case "polyline":return this.generatePolylinePoints(t,i,n);case "orthogonal":return this.generateOrthogonalPoints(t,i,n);case "curve":return this.generateCurvePoints(t);default:return t}}drawRoundedPolyline(t,e,i){if(t.beginPath(),!(e.length<2)){if(e.length===2||i<=0){t.moveTo(e[0].x,e[0].y);for(let n=1;n<e.length;n++)t.lineTo(e[n].x,e[n].y);return}t.moveTo(e[0].x,e[0].y);for(let n=1;n<e.length-1;n++){let s=e[n-1],r=e[n],o=e[n+1],h=r.x-s.x,l=r.y-s.y,d=o.x-r.x,u=o.y-r.y,c=Math.hypot(h,l),g=Math.hypot(d,u);if(c<1e-6||g<1e-6){t.lineTo(r.x,r.y);continue}let p=Math.min(i,c*.5,g*.5),y=r.x-h/c*p,m=r.y-l/c*p,v=r.x+d/g*p,x=r.y+u/g*p;t.lineTo(y,m),t.arcTo(r.x,r.y,v,x,p);}t.lineTo(e[e.length-1].x,e[e.length-1].y);}}drawSharpPolyline(t,e){if(t.beginPath(),!(e.length<2)){t.moveTo(e[0].x,e[0].y);for(let i=1;i<e.length;i++)t.lineTo(e[i].x,e[i].y);}}drawSnapGuides(t,e,i){t.save(),t.strokeStyle=I.guide,t.lineWidth=1/i,t.setLineDash([6/i,4/i]),t.beginPath();for(let n of e)n.type==="horizontal"?(t.moveTo(n.start,n.position),t.lineTo(n.end,n.position)):(t.moveTo(n.position,n.start),t.lineTo(n.position,n.end));t.stroke(),t.restore();}generatePolylinePoints(t,e=[],i={}){if(t.length<2)return t;let n=[];n.push(t[0]);let s=t.length-1,r=a.CONNECTION_LEAD;for(let o=1;o<t.length;o++){let h=t[o-1],l=t[o],d=o===1,u=o===s,c=d&&i.fromN?{x:h.x+i.fromN.x*r,y:h.y+i.fromN.y*r}:h,g=u&&i.toN?{x:l.x+i.toN.x*r,y:l.y+i.toN.y*r}:l;d&&i.fromN&&n.push(c);let p=this.computeOrthogonalRoute(c,g,e);for(let y of p)n.push(y);u&&i.toN&&n.push(l);}return this.collapseLinePoints(n)}generateOrthogonalPoints(t,e=[],i={}){return this.generatePolylinePoints(t,e,i)}collapseLinePoints(t){let e=[];for(let i of t){let n=e.length;if(!(n>0&&Math.abs(e[n-1].x-i.x)<1e-6&&Math.abs(e[n-1].y-i.y)<1e-6)){if(n>=2){let s=e[n-2],r=e[n-1];if(Math.abs(s.y-r.y)<1e-6&&Math.abs(r.y-i.y)<1e-6||Math.abs(s.x-r.x)<1e-6&&Math.abs(r.x-i.x)<1e-6){e[n-1]=i;continue}}e.push(i);}}return e}computeOrthogonalRoute(t,e,i=[]){let n=e.x-t.x,s=e.y-t.y;if(Math.abs(n)<1||Math.abs(s)<1)return [e];let r=t.x+n/2,o=t.y+s/2,h=i.length>0,l=[[{x:r,y:t.y},{x:r,y:e.y},e],[{x:t.x,y:o},{x:e.x,y:o},e],[{x:e.x,y:t.y},e],[{x:t.x,y:e.y},e]];if(h){for(let u of l)if(!this.routeHitsObstacles(t,u,i))return u;let d=this.routeOrthogonalAvoidance(t,e,i);return d&&d.length>0?d:i.length>0&&!this.routeHitsObstacles(t,l[0],i)?l[0]:this.routeHitsObstacles(t,l[1],i)?[e]:l[1]}return Math.abs(n)>=Math.abs(s)?[{x:r,y:t.y},{x:r,y:e.y},e]:[{x:t.x,y:o},{x:e.x,y:o},e]}collectRoutingObstacles(t,e,i,n,s){if(!n||n.size===0)return [];let r=[];return n.forEach((o,h)=>{if(h===t)return;let l=this.getShapeBounds(o),d={x:o.x+l.x-s.x,y:o.y+l.y-s.y,width:l.width,height:l.height};d.pad=this.pointInRect(e,d)||this.pointInRect(i,d)?a.CONNECTED_PAD:a.ROUTE_CLEARANCE,r.push(d);}),r}pointInRect(t,e){return t.x>=e.x&&t.x<=e.x+e.width&&t.y>=e.y&&t.y<=e.y+e.height}routeHitsObstacles(t,e,i){let n=[t,...e];for(let s=1;s<n.length;s++)if(this.segmentHitsObstacle(n[s-1],n[s],i))return true;return false}segmentHitsObstacle(t,e,i){for(let n of i){let s=n.pad??a.ROUTE_CLEARANCE,r=n.y-s,o=n.y+n.height+s,h=n.x-s,l=n.x+n.width+s;if(Math.abs(t.y-e.y)<.5){if(t.y>=r&&t.y<=o){let d=Math.min(t.x,e.x);if(Math.max(t.x,e.x)>=h&&d<=l)return true}}else if(t.x>=h&&t.x<=l){let d=Math.min(t.y,e.y);if(Math.max(t.y,e.y)>=r&&d<=o)return true}}return false}routeOrthogonalAvoidance(t,e,i){let n=new Set([t.x,e.x]),s=new Set([t.y,e.y]);for(let S of i){let w=S.pad??a.ROUTE_CLEARANCE;n.add(S.x-w),n.add(S.x+S.width+w),s.add(S.y-w),s.add(S.y+S.height+w);}let r=[...n].sort((S,w)=>S-w),o=[...s].sort((S,w)=>S-w),h=r.length,l=o.length,d=S=>{for(let w=0;w<h;w++)if(Math.abs(r[w]-S)<1e-6)return w;return 0},u=S=>{for(let w=0;w<l;w++)if(Math.abs(o[w]-S)<1e-6)return w;return 0},c=d(t.x),g=u(t.y),p=d(e.x),y=u(e.y),m=[],v=[];for(let S=0;S<h;S++)m.push(new Array(l).fill(true)),v.push(new Array(l).fill(true));for(let S of i){let w=S.pad??a.ROUTE_CLEARANCE,C=S.x-w,$=S.x+S.width+w,O=S.y-w,G=S.y+S.height+w;for(let A=0;A<h-1;A++)if(!(r[A+1]<=C||r[A]>=$))for(let X=0;X<l;X++)o[X]>O&&o[X]<G&&(m[A][X]=false);for(let A=0;A<l-1;A++)if(!(o[A+1]<=O||o[A]>=G))for(let X=0;X<h;X++)r[X]>C&&r[X]<$&&(v[X][A]=false);}let x=h*l,P=1/0,b=new Float64Array(x).fill(P),M=new Int32Array(x).fill(-1),T=new Uint8Array(x),E=S=>{let w=S%h,C=S/h|0;return Math.abs(r[w]-e.x)+Math.abs(o[C]-e.y)},H=(S,w)=>S%h===w%h,Y=g*h+c,F=y*h+p;b[Y]=0;let N=[Y],R=[E(Y)],St=S=>{let w=b[S]+E(S);N.push(S),R.push(w);let C=N.length-1;for(;C>0;){let $=C-1>>1;if(R[$]<=R[C])break;[N[$],N[C]]=[N[C],N[$]],[R[$],R[C]]=[R[C],R[$]],C=$;}},he=()=>{let S=N[0],w=N.pop(),C=R.pop();if(N.length){N[0]=w,R[0]=C;let $=0;for(;;){let O=$*2+1,G=O+1,A=$;if(O<N.length&&R[O]<R[A]&&(A=O),G<N.length&&R[G]<R[A]&&(A=G),A===$)break;[N[A],N[$]]=[N[$],N[A]],[R[A],R[$]]=[R[$],R[A]],$=A;}}return S},wt=(S,w,C)=>{let $=S%h,O=w%h,G=b[S]+(Math.abs(O-$)===0?Math.abs(o[w/h|0]-o[S/h|0]):Math.abs(r[O]-r[$]))+C;G<b[w]&&(b[w]=G,M[w]=S,T[w]||St(w));};for(;N.length;){let S=he();if(S===F||T[S]){if(S===F)break;continue}T[S]=1;let w=S%h,C=S/h|0,$=M[S],O=$>=0?H($,S)?"v":"h":"",G=A=>{let X=H(S,A)?"v":"h";return O!==""&&O!==X?24:0};w+1<h&&m[w][C]&&wt(S,C*h+w+1,G(C*h+w+1)),w-1>=0&&m[w-1][C]&&wt(S,C*h+w-1,G(C*h+w-1)),C+1<l&&v[w][C]&&wt(S,(C+1)*h+w,G((C+1)*h+w)),C-1>=0&&v[w][C-1]&&wt(S,(C-1)*h+w,G((C-1)*h+w));}if(b[F]===P)return null;let Dt=[];for(let S=F;S!==-1;S=M[S])Dt.push({x:r[S%h],y:o[S/h|0]});Dt.reverse();let ot=[];for(let S of Dt){let w=ot.length;if(w>=2){let C=ot[w-2],$=ot[w-1];if(Math.abs(C.y-$.y)<1e-6&&Math.abs($.y-S.y)<1e-6||Math.abs(C.x-$.x)<1e-6&&Math.abs($.x-S.x)<1e-6){ot[w-1]=S;continue}}ot.push(S);}return ot.slice(1)}generateCurvePoints(t){if(t.length<2)return t;let e=[],i=20,n=t[0],s=n;e.push(n);for(let r=1;r<t.length;r++){let o=t[r],h=this.computeCurveControlPoint(s,o);for(let l=1;l<=i;l++){let d=l/i,u=(1-d)*(1-d)*s.x+2*(1-d)*d*h.x+d*d*o.x,c=(1-d)*(1-d)*s.y+2*(1-d)*d*h.y+d*d*o.y;e.push({x:u,y:c});}s=o;}return e}computeCurveControlPoint(t,e){let i=e.x-t.x,n=e.y-t.y,s=Math.sqrt(i*i+n*n);if(s<1)return {x:t.x,y:t.y};let r=(t.x+e.x)/2,o=(t.y+e.y)/2,h=-n/s,l=i/s,d=Math.min(s*.2,30);return {x:r+h*d,y:o+l*d}}getDisplayLines(t,e,i,n,s,r){let o=n*1.3,h=Math.max(1,Math.floor(r/o)),l=`${e.id}\0${i}\0${n}\0${s}x${r}\0${h}`,d=this.textLayoutCache.get(l);if(d)return d;let u=i.split(`
|
|
2
|
+
`),c=[];for(let p of u){let y=this.wrapLine(t,p,s);for(let m of y)c.push(m);}let g=c.slice(0,h);return c.length>h&&g.length>0&&(g[g.length-1]=this.truncateLine(t,g[g.length-1],s)),this.textLayoutCache.size>=a.TEXT_CACHE_LIMIT&&this.textLayoutCache.clear(),this.textLayoutCache.set(l,g),g}drawShapeText(t,e){let i=e.text||"";if(!i)return;let n=e.fontSize||16;t.font=`${n}px sans-serif`,t.fillStyle=e.textColor||"#1f2937";let s=this.getTextBounds(e),r=n*1.3,o=this.getDisplayLines(t,e,i,n,s.width,s.height),l=-(o.length*r)/2+r/2;t.textAlign="center",t.textBaseline="middle",o.forEach((d,u)=>{let c=l+u*r;t.fillText(d,0,c);});}getTextBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":return {width:t.width*.85,height:t.height*.85};case "circle":return {width:t.radius*2*.85,height:t.radius*2*.85};default:return {width:100,height:40}}}wrapLine(t,e,i){if(!e)return [""];let n=[],s="";for(let r of e){let o=s+r;t.measureText(o).width>i&&s?(n.push(s),s=r):s=o;}return s&&n.push(s),n}truncateLine(t,e,i){if(!e)return "...";let n="...",s=e;for(;s.length>0&&t.measureText(s+n).width>i;)s=s.slice(0,-1);return s+n}getBindingPoint(t,e){if(e.isPrecise&&e.normalizedAnchor){let i=this.getShapePageBounds(t),n={x:i.x+i.width*e.normalizedAnchor.x,y:i.y+i.height*e.normalizedAnchor.y},s={x:t.x,y:t.y};return this.nearestPointOnShapeOutline(t,s,n)}if(e.handle){let i=this.getShapeBounds(t);switch(e.handle){case "top":return {x:t.x,y:t.y+i.y};case "bottom":return {x:t.x,y:t.y+i.y+i.height};case "left":return {x:t.x+i.x,y:t.y};case "right":return {x:t.x+i.x+i.width,y:t.y}}}return {x:t.x,y:t.y}}getDockNormal(t,e,i){if(!e||e.size===0)return;let n=null,s=1/0,r=.5;if(e.forEach((d,u)=>{if(u===i)return;let c=this.getShapePageBounds(d);if(t.x>=c.x-r&&t.x<=c.x+c.width+r&&t.y>=c.y-r&&t.y<=c.y+c.height+r){let g=(t.x-d.x)**2+(t.y-d.y)**2;g<s&&(s=g,n=d);}}),!n)return;let o=n,h=t.x-o.x,l=t.y-o.y;return Math.abs(l)>Math.abs(h)?{x:0,y:l<0?-1:1}:{x:h<0?-1:1,y:0}}getShapePageBounds(t){let e=this.getShapeBounds(t);return {x:t.x+e.x,y:t.y+e.y,width:e.width,height:e.height}}clampToShapeOutline(t,e,i,n){if(!e||e.size===0)return t;let s=null,r=1/0;if(e.forEach((h,l)=>{if(l===i)return;let d=this.getShapePageBounds(h);if(t.x>d.x&&t.x<d.x+d.width&&t.y>d.y&&t.y<d.y+d.height){let u=(h.x-n.x)**2+(h.y-n.y)**2;u<r&&(r=u,s=h);}}),!s)return t;let o=s;return this.nearestPointOnShapeOutline(o,{x:o.x,y:o.y},t)}nearestPointOnShapeOutline(t,e,i){let n=i.x-e.x,s=i.y-e.y,r=Math.hypot(n,s);if(r<1e-6)return {x:e.x,y:e.y};let o=n/r,h=s/r,l=Math.max(1e4,r*2),d={x:e.x+o*l,y:e.y+h*l},u=this.intersectShapeOutlineWithSegment(t,e,d);if(u.length===0)return i;let c=u[0],g=(c.x-e.x)**2+(c.y-e.y)**2;for(let p=1;p<u.length;p++){let y=(u[p].x-e.x)**2+(u[p].y-e.y)**2;y<g&&(g=y,c=u[p]);}return c}intersectShapeOutlineWithSegment(t,e,i){let n={x:e.x-t.x,y:e.y-t.y},s={x:i.x-t.x,y:i.y-t.y};return this.intersectLocalShapeOutlineWithSegment(t,n,s).map(o=>({x:o.x+t.x,y:o.y+t.y}))}intersectLocalShapeOutlineWithSegment(t,e,i){switch(t.type){case "rectangle":case "rounded-rectangle":{let n=t.width,s=t.height,r={x:-n/2,y:-s/2,width:n,height:s};return this.intersectSegmentRect(e,i,r)}case "ellipse":case "diamond":case "triangle":{let n=t.width,s=t.height,r={x:-n/2,y:-s/2,width:n,height:s};return this.intersectSegmentRect(e,i,r)}case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":{let n=t.width,s=t.height,r={x:-n/2,y:-s/2,width:n,height:s};return this.intersectSegmentRect(e,i,r)}case "circle":{let n=t.radius;return this.intersectSegmentCircle(e,i,{x:0,y:0},n)}default:return []}}intersectSegmentRect(t,e,i){let n=i.x,s=i.y,r=i.width,o=i.height,h=[[{x:n,y:s},{x:n+r,y:s}],[{x:n+r,y:s},{x:n+r,y:s+o}],[{x:n+r,y:s+o},{x:n,y:s+o}],[{x:n,y:s+o},{x:n,y:s}]],l=[];for(let[d,u]of h){let c=this.segmentIntersection(t,e,d,u);c&&l.push(c);}return l}segmentIntersection(t,e,i,n){let s=t.x,r=t.y,o=e.x,h=e.y,l=i.x,d=i.y,u=n.x,c=n.y,g=(s-o)*(d-c)-(r-h)*(l-u);if(Math.abs(g)<1e-9)return null;let p=((s-l)*(d-c)-(r-d)*(l-u))/g,y=-((s-o)*(r-d)-(r-h)*(s-l))/g;return p<0||p>1||y<0||y>1?null:{x:s+p*(o-s),y:r+p*(h-r)}}intersectSegmentCircle(t,e,i,n){let s=e.x-t.x,r=e.y-t.y,o=t.x-i.x,h=t.y-i.y,l=s*s+r*r,d=2*(o*s+h*r),u=o*o+h*h-n*n,c=d*d-4*l*u;if(c<0)return [];c=Math.sqrt(c);let g=(-d-c)/(2*l),p=(-d+c)/(2*l),y=[];return g>=0&&g<=1&&y.push({x:t.x+g*s,y:t.y+g*r}),p>=0&&p<=1&&Math.abs(p-g)>1e-6&&y.push({x:t.x+p*s,y:t.y+p*r}),y}drawArrowHead(t,e,i){let n=Math.atan2(i.y-e.y,i.x-e.x),s=12;t.beginPath(),t.moveTo(i.x,i.y),t.lineTo(i.x-s*Math.cos(n-Math.PI/6),i.y-s*Math.sin(n-Math.PI/6)),t.moveTo(i.x,i.y),t.lineTo(i.x-s*Math.cos(n+Math.PI/6),i.y-s*Math.sin(n+Math.PI/6)),t.stroke();}drawInheritanceHead(t,e,i){let n=Math.atan2(i.y-e.y,i.x-e.x),s=14,r=i.x,o=i.y,h=i.x-s*Math.cos(n),l=i.y-s*Math.sin(n),d=h+s*.5*Math.cos(n-Math.PI/2),u=l+s*.5*Math.sin(n-Math.PI/2),c=h+s*.5*Math.cos(n+Math.PI/2),g=l+s*.5*Math.sin(n+Math.PI/2);t.save(),t.fillStyle="#ffffff",t.beginPath(),t.moveTo(r,o),t.lineTo(d,u),t.lineTo(c,g),t.closePath(),t.fill(),t.stroke(),t.restore();}drawDiamondHead(t,e,i,n){let s=Math.atan2(i.y-e.y,i.x-e.x),r=14,o=i.x,h=i.y,l=i.x-r*.5*Math.cos(s),d=i.y-r*.5*Math.sin(s),u=i.x-r*Math.cos(s),c=i.y-r*Math.sin(s),g=l+r*.4*Math.cos(s-Math.PI/2),p=d+r*.4*Math.sin(s-Math.PI/2),y=l+r*.4*Math.cos(s+Math.PI/2),m=d+r*.4*Math.sin(s+Math.PI/2);t.save(),t.fillStyle=n?"#1f2937":"#ffffff",t.beginPath(),t.moveTo(o,h),t.lineTo(g,p),t.lineTo(u,c),t.lineTo(y,m),t.closePath(),t.fill(),t.stroke(),t.restore();}drawArrowHeads(t,e,i){if(i!=="none"){if(i==="start"||i==="both"){let n=e[0],s=e[1];this.drawArrowHead(t,s,n);}if(i==="end"||i==="both"){let n=e.length,s=e[n-2],r=e[n-1];this.drawArrowHead(t,s,r);}if(i==="inheritance"){let n=e.length,s=e[n-2],r=e[n-1];this.drawInheritanceHead(t,s,r);}if(i==="aggregation"){let n=e[0],s=e[1];this.drawDiamondHead(t,s,n,false);}if(i==="composition"){let n=e[0],s=e[1];this.drawDiamondHead(t,s,n,true);}}}drawText(t,e){if(!e.text)return;let i=e.fontSize;t.font=`${i}px sans-serif`,t.textAlign="center",t.textBaseline="middle";let n=e.width,s=e.height,r=i*1.3,o=this.getDisplayLines(t,e,e.text,i,n,s),h=o.length*r,l=-h/2+r/2;if(e.highlightColor&&e.highlightColor!=="transparent"){let d=e.highlightOpacity??1;t.fillStyle=d<1?j(e.highlightColor,d):e.highlightColor;let u=i*.15;t.beginPath(),t.roundRect(-n/2-u,-h/2-u,n+u*2,h+u*2,4),t.fill();}t.fillStyle=e.textColor||"#1f2937",o.forEach((d,u)=>{let c=l+u*r;t.fillText(d,0,c);});}drawFreehand(t,e){if(e.points.length<2)return;let i=e.points;t.beginPath(),t.moveTo(i[0].x,i[0].y);for(let n=1;n<i.length-1;n++){let s=(i[n].x+i[n+1].x)/2,r=(i[n].y+i[n+1].y)/2;t.quadraticCurveTo(i[n].x,i[n].y,s,r);}t.lineTo(i[i.length-1].x,i[i.length-1].y),t.stroke();}drawSelectionOutline(t,e,i){let n=this.getShapeBounds(e);t.strokeStyle=I.selection.outline,t.lineWidth=1/i,t.setLineDash([]),t.save(),t.shadowColor=I.selection.shadow,t.shadowBlur=8,t.shadowOffsetX=0,t.shadowOffsetY=0,t.beginPath(),t.roundRect(n.x-2,n.y-2,n.width+4,n.height+4,4),t.stroke(),t.restore(),t.fillStyle=I.selection.outlineFill,t.beginPath(),t.roundRect(n.x-2,n.y-2,n.width+4,n.height+4,4),t.fill();}drawSelectionHandles(t,e,i){let n=8/i;if((e.type==="line"||e.type==="arrow")&&e.points&&e.points.length>=2){let r=e.points.map(u=>({x:u.x-e.x,y:u.y-e.y})),o=r[0],h=r[r.length-1];t.fillStyle=I.selection.handleFill,t.strokeStyle=I.selection.handleStroke,t.lineWidth=2/i,t.setLineDash([]),[o,h].forEach(u=>{t.beginPath(),t.arc(u.x,u.y,n/2,0,Math.PI*2),t.fill(),t.stroke();});let l=(o.x+h.x)/2,d=(o.y+h.y)/2;t.beginPath(),t.arc(l,d,7/i,0,Math.PI*2),t.fillStyle=I.selection.handleFill,t.fill(),t.strokeStyle=I.primary,t.lineWidth=1.5/i,t.stroke(),t.beginPath(),t.arc(l,d,3/i,0,Math.PI*2),t.fillStyle=I.genDot,t.fill();}else {let r=this.getShapeBounds(e),o=n,h=[{x:r.x,y:r.y},{x:r.x+r.width,y:r.y},{x:r.x+r.width,y:r.y+r.height},{x:r.x,y:r.y+r.height}];t.fillStyle=I.selection.handleFill,t.strokeStyle=I.selection.handleStroke,t.lineWidth=2/i,t.setLineDash([]),h.forEach(p=>{t.beginPath(),t.roundRect(p.x-o/2,p.y-o/2,o,o,2),t.fill(),t.stroke();});let l=9/i;[{x:r.x+r.width/2,y:r.y},{x:r.x+r.width,y:r.y+r.height/2},{x:r.x+r.width/2,y:r.y+r.height},{x:r.x,y:r.y+r.height/2}].forEach(p=>{t.beginPath(),t.arc(p.x,p.y,l,0,Math.PI*2),t.fillStyle=I.selection.handleFill,t.fill(),t.strokeStyle=I.primary,t.lineWidth=1.5/i,t.stroke(),t.beginPath(),t.arc(p.x,p.y,l*.45,0,Math.PI*2),t.fillStyle=I.primary,t.fill();});let u=26/i,c=r.x+r.width/2,g=r.y-u;t.strokeStyle="#94a3b8",t.lineWidth=1.5/i,t.setLineDash([]),t.beginPath(),t.moveTo(c,r.y),t.lineTo(c,g),t.stroke(),t.beginPath(),t.arc(c,g,8/i,0,Math.PI*2),t.fillStyle=I.selection.handleFill,t.fill(),t.strokeStyle=I.primary,t.lineWidth=1.6/i,t.stroke(),this.drawRotateIcon(t,c,g,i);}}drawRotateIcon(t,e,i,n){let s=8/n;t.save(),t.translate(e,i),t.strokeStyle=I.primary,t.lineWidth=1.8/n,t.lineCap="round",t.beginPath(),t.arc(0,0,s*.5,Math.PI*.18,Math.PI*1.6,false),t.stroke();let r=Math.PI*.18,o=Math.cos(r)*s*.5,h=Math.sin(r)*s*.5,l=1;t.beginPath(),t.moveTo(o,h),t.lineTo(o-Math.cos(r)*s*.26+l*Math.sin(r)*s*.16,h-Math.sin(r)*s*.26-l*Math.cos(r)*s*.16),t.moveTo(o,h),t.lineTo(o-Math.cos(r)*s*.26-l*Math.sin(r)*s*.16,h-Math.sin(r)*s*.26+l*Math.cos(r)*s*.16),t.stroke(),t.restore();}getShapeBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":return {x:-t.width/2,y:-t.height/2,width:t.width,height:t.height};case "circle":return {x:-t.radius,y:-t.radius,width:t.radius*2,height:t.radius*2};case "line":case "arrow":{if(t.points.length===0)return {x:0,y:0,width:0,height:0};let e=1/0,i=1/0,n=-1/0,s=-1/0;return t.points.forEach(r=>{e=Math.min(e,r.x-t.x),i=Math.min(i,r.y-t.y),n=Math.max(n,r.x-t.x),s=Math.max(s,r.y-t.y);}),{x:e,y:i,width:n-e,height:s-i}}case "draw":{let e=t;if(typeof e.width=="number"&&typeof e.height=="number")return {x:-e.width/2,y:-e.height/2,width:e.width,height:e.height};if(e.points.length===0)return {x:0,y:0,width:0,height:0};let i=1/0,n=1/0,s=-1/0,r=-1/0;return e.points.forEach(o=>{let h=o.x-e.x,l=o.y-e.y;i=Math.min(i,h),n=Math.min(n,l),s=Math.max(s,h),r=Math.max(r,l);}),{x:i,y:n,width:s-i,height:r-n}}case "text":{let e=t;return {x:-e.width/2,y:-e.height/2,width:e.width,height:e.height}}default:return {x:0,y:0,width:0,height:0}}}};var rt={create(a=0,t=0){return {x:a,y:t}},add(a,t){return {x:a.x+t.x,y:a.y+t.y}},subtract(a,t){return {x:a.x-t.x,y:a.y-t.y}},multiply(a,t){return {x:a.x*t,y:a.y*t}},divide(a,t){return {x:a.x/t,y:a.y/t}},dot(a,t){return a.x*t.x+a.y*t.y},length(a){return Math.sqrt(a.x*a.x+a.y*a.y)},normalize(a){let t=rt.length(a);return t===0?{x:0,y:0}:{x:a.x/t,y:a.y/t}},distance(a,t){return rt.length(rt.subtract(a,t))},rotate(a,t){let e=Math.cos(t),i=Math.sin(t);return {x:a.x*e-a.y*i,y:a.x*i+a.y*e}},clone(a){return {x:a.x,y:a.y}},equals(a,t){return a.x===t.x&&a.y===t.y}};function Q(a,t,e,i=8){let n=[];if(e==="horizontal"){let s=Math.min(a.x,t.x),r=Math.max(a.x+a.width,t.x+t.width),o=Math.abs(a.y-t.y)<=i,h=Math.abs(a.y+a.height-(t.y+t.height))<=i,l=Math.abs(a.y+a.height/2-(t.y+t.height/2))<=i;o&&n.push({type:"horizontal",position:(a.y+t.y)/2,start:s,end:r}),h&&n.push({type:"horizontal",position:(a.y+a.height+t.y+t.height)/2,start:s,end:r}),l&&!(o&&h)&&n.push({type:"horizontal",position:(a.y+a.height/2+t.y+t.height/2)/2,start:s,end:r});}else {let s=Math.min(a.y,t.y),r=Math.max(a.y+a.height,t.y+t.height),o=Math.abs(a.x-t.x)<=i,h=Math.abs(a.x+a.width-(t.x+t.width))<=i,l=Math.abs(a.x+a.width/2-(t.x+t.width/2))<=i;o&&n.push({type:"vertical",position:(a.x+t.x)/2,start:s,end:r}),h&&n.push({type:"vertical",position:(a.x+a.width+t.x+t.width)/2,start:s,end:r}),l&&!(o&&h)&&n.push({type:"vertical",position:(a.x+a.width/2+t.x+t.width/2)/2,start:s,end:r});}return n}var ct=class a extends k{type="select";state="idle";translatingState=null;resizingState=null;generatingState=null;hoverGenPoint=null;rotatingState=null;draggingArrowId=null;draggingTerminal=null;pendingHistoryCommit=false;brushStart={x:0,y:0};brushShiftKey=false;defaultGenType(t){if(t){let e=this.context.getShapes().find(i=>i.id===t);if(e&&It(e.type))return e.type}return "rectangle"}genPreviewOf(t,e){return {from:t.point,to:e,type:this.defaultGenType(t.sourceShapeId)}}genContext(t,e){return {from:t.point,to:e,sourceShapeId:t.sourceShapeId,edge:t.edge}}onPointerDown(t,e){let i=this.context.getShapes(),n=this.context.getSelectedIds(),s=this.hitTestArrowTerminal(t,i);if(s&&n.includes(s.shapeId)){this.state="dragging-terminal",this.draggingArrowId=s.shapeId,this.draggingTerminal=s.terminal,this.pendingHistoryCommit=true,this.context.updateArrowBinding(s.shapeId,s.terminal,null);return}let r=this.hitGenPoint(t,i,n);if(r){this.state="generating",this.generatingState={source:r,startPoint:t,hasMoved:false},this.pendingHistoryCommit=true,this.context.setGenerationPreview(this.genPreviewOf(r,this.genPreviewTarget(r,t,false)));return}let o=this.hitTest(t,i,n);if(o.handle==="rotation"){this.state="rotating",this.pendingHistoryCommit=true;let h=o.shape;this.rotatingState={shapeId:h.id,center:{x:h.x,y:h.y},startAngle:Math.atan2(t.y-h.y,t.x-h.x),startRotation:h.rotation};return}if(o.handle&&o.shape&&o.shape.type!=="mind-map"){this.state="resizing",this.resizingState={startPoint:t,startShape:o.shape,handle:o.handle},this.pendingHistoryCommit=true;return}if(o.shape){let h=o.shape,l=h.type==="line"||h.type==="arrow",d=n.includes(h.id);if(l&&!d){this.context.selectShape(h.id,e.shiftKey);return}this.state="translating",this.pendingHistoryCommit=true,d||this.context.selectShape(h.id,e.shiftKey);let u=this.context.getSelectedIds(),c=new Map,g=new Map,p=new Map;u.forEach(y=>{let m=i.find(v=>v.id===y);m&&(c.set(y,{x:m.x,y:m.y}),g.set(y,m.rotation),p.set(y,this.getShapeWorldBounds(m)));}),this.translatingState={startPoint:t,startPositions:c,startRotation:g,startBounds:p};}else this.state="brushing",this.brushStart=t,this.brushShiftKey=e.shiftKey,e.shiftKey||this.context.selectShape("",false);}onPointerMove(t,e){let i=this.context.getShapes();if(this.state==="translating"&&this.translatingState)this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false),this.handleTranslating(t,e);else if(this.state==="generating"&&this.generatingState)this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false),this.handleGenerating(t,i);else if(this.state==="rotating"&&this.rotatingState)this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false),this.handleRotating(t,e);else if(this.state==="resizing"&&this.resizingState)this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false),this.handleResizing(t);else if(this.state==="dragging-terminal"&&this.draggingArrowId&&this.draggingTerminal){this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false);let n=i.find(s=>s.id===this.draggingArrowId);if(n){let s=this.draggingTerminal==="start"?t:n.points[n.points.length-1],r=this.draggingTerminal==="start"?n.points[0]:t,o=this.computeSnapGuidesForArrow(s,r,t,n,i);this.context.setSnapGuides(o);let h=t;if(o.length>0){let u=o.filter(g=>g.type==="horizontal"),c=o.filter(g=>g.type==="vertical");if(u.length>0){let g=u[0].position,p=Math.abs(t.y-g);for(let y of u){let m=Math.abs(t.y-y.position);m<p&&(p=m,g=y.position);}h={...h,y:g};}else if(c.length>0){let g=c[0].position,p=Math.abs(t.x-g);for(let y of c){let m=Math.abs(t.x-y.position);m<p&&(p=m,g=y.position);}h={...h,x:g};}}let l=this.draggingTerminal==="start"?0:n.points.length-1,d=[...n.points];d[l]=h,this.context.updateShape(this.draggingArrowId,{points:d});}}else if(this.state==="brushing")this.handleBrushing(t);else {let n=this.context.getSelectedIds(),s=this.hitGenPoint(t,i,n);s?(this.hoverGenPoint=s,this.context.setGenerationPreview(this.genPreviewOf(s,this.genPreviewTarget(s,t,false)))):this.hoverGenPoint&&(this.hoverGenPoint=null,this.context.setGenerationPreview(null));}}onPointerUp(t,e){if(this.state==="dragging-terminal"&&this.draggingArrowId&&this.draggingTerminal){let i=this.context.getShapes(),n=this.findBindingNearPoint(t,i,this.draggingArrowId);n&&this.context.updateArrowBinding(this.draggingArrowId,this.draggingTerminal,n.toShapeId,n.binding);}if(this.state==="generating"&&this.generatingState){let i=this.generatingState,n=this.context.getShapes(),s=i.source,r=this.findBindingNearPoint(t,n,s.sourceShapeId);if(r)this.context.connectToExisting(this.genContext(s,t),r.toShapeId,r.binding);else if(!i.hasMoved)this.context.createGeneratedConnection(this.genContext(s,this.genPreviewTarget(s,s.point,false)),{type:this.defaultGenType(s.sourceShapeId)});else {let o=this.context.createFloatingLine(this.genContext(s,t));this.context.openGenerationMenu({context:this.genContext(s,t),existingArrowId:o,defaultShapeType:this.defaultGenType(s.sourceShapeId)});}this.generatingState=null,this.context.setGenerationPreview(null);}this.state==="brushing"&&this.context.setBrushRect(null),this.context.setConnectingTarget(null),this.hoverGenPoint=null,this.pendingHistoryCommit=false,this.state="idle",this.draggingArrowId=null,this.draggingTerminal=null,this.translatingState=null,this.resizingState=null,this.rotatingState=null,this.context.setSnapGuides([]);}onKeyDown(t){let e=t.target;if(!(e&&(e.tagName==="INPUT"||e.tagName==="TEXTAREA"||e.isContentEditable))){if(t.key==="Delete"||t.key==="Backspace"){let i=this.context.getSelectedIds();i.length>0&&(this.context.commitHistory(),i.forEach(n=>{this.context.deleteShape(n);}));}t.key==="Escape"&&(this.context.selectShape("",false),this.context.setSnapGuides([]),this.state="idle"),(t.key==="+"||t.key==="=")&&t.shiftKey&&(this.context.commitHistory(),this.handleRotation(15)),t.key==="-"&&t.shiftKey&&(this.context.commitHistory(),this.handleRotation(-15)),t.key==="ArrowUp"&&(t.preventDefault(),this.context.commitHistory(),this.handleNudge(0,-5)),t.key==="ArrowDown"&&(t.preventDefault(),this.context.commitHistory(),this.handleNudge(0,5)),t.key==="ArrowLeft"&&(t.preventDefault(),this.context.commitHistory(),this.handleNudge(-5,0)),t.key==="ArrowRight"&&(t.preventDefault(),this.context.commitHistory(),this.handleNudge(5,0));}}onKeyUp(t){}getCursor(t){switch(this.state){case "translating":return "grabbing";case "generating":return "crosshair";case "rotating":return "grabbing";case "resizing":return this.resizingState?this.getHandleCursor(this.resizingState.handle,this.resizingState.startShape):"default";case "dragging-terminal":return "crosshair";case "brushing":return "crosshair"}let e=this.context.getShapes(),i=this.context.getSelectedIds();if(this.context.getMindMapCursorHitAtPoint(t))return "pointer";if(this.hitGenPoint(t,e,i))return "crosshair";if(this.hitTestArrowTerminal(t,e)&&i.includes(this.hitTestArrowTerminal(t,e).shapeId))return "move";let n=this.hitTest(t,e,i);return n.handle==="rotation"?"grab":n.handle?this.getHandleCursor(n.handle,n.shape):n.shape?"move":null}getHandleCursor(t,e){let n={e:0,se:45,s:90,sw:135,w:180,nw:225,n:270,ne:315}[t];if(n===void 0)return "grab";let s=((n+e.rotation*180/Math.PI)%360+360)%360,r=Math.round(s/45)%4;return ["ew-resize","nwse-resize","ns-resize","nesw-resize"][r]}static ALIGN_SNAP_THRESHOLD=8;handleTranslating(t,e){if(!this.translatingState)return;let i=rt.subtract(t,this.translatingState.startPoint),n={...i};e.shiftKey&&(Math.abs(i.x)>Math.abs(i.y)?n.y=0:n.x=0);let s=this.context.getShapes(),r=this.context.getSelectedIds(),o=new Set(r),h=[],l=[];if(this.translatingState.startBounds.forEach(d=>{l.push({x:d.x+n.x,y:d.y+n.y,width:d.width,height:d.height});}),!e.shiftKey&&l.length>0){let d=[];for(let g of s)o.has(g.id)||g.type==="line"||g.type==="arrow"||g.type==="draw"||d.push(this.getShapeWorldBounds(g));let u=[],c=[];for(let g of l){let p=[g.y,g.y+g.height/2,g.y+g.height],y=[g.x,g.x+g.width/2,g.x+g.width];for(let m of d){let v=[m.y,m.y+m.height/2,m.y+m.height];for(let P of p)for(let b of v){let M=b-P;Math.abs(M)<=a.ALIGN_SNAP_THRESHOLD&&u.push(M);}let x=[m.x,m.x+m.width/2,m.x+m.width];for(let P of y)for(let b of x){let M=b-P;Math.abs(M)<=a.ALIGN_SNAP_THRESHOLD&&c.push(M);}}}if(u.length>0){let g=u[0];for(let p of u)Math.abs(p)<Math.abs(g)&&(g=p);n.y+=g;}if(c.length>0){let g=c[0];for(let p of c)Math.abs(p)<Math.abs(g)&&(g=p);n.x+=g;}this.translatingState.startBounds.forEach(g=>{let p={x:g.x+n.x,y:g.y+n.y,width:g.width,height:g.height};for(let y of d)h.push(...Q(p,y,"horizontal",1)),h.push(...Q(p,y,"vertical",1));});}this.translatingState.startPositions.forEach((d,u)=>{this.context.updateShape(u,{x:d.x+n.x,y:d.y+n.y});}),this.context.setSnapGuides(this.mergeGuides(h));}handleResizing(t){if(!this.resizingState)return;let e=this.resizingState.startShape,i=this.resizingState.handle,n=this.resizingState.startPoint;if(!i||i==="rotation")return;let r={nw:[-1,-1],n:[0,-1],ne:[1,-1],w:[-1,0],e:[1,0],sw:[-1,1],s:[0,1],se:[1,1]}[i];if(!r)return;let[o,h]=r,l=rt.subtract(t,n),d=[];for(let M of this.context.getShapes())M.id!==e.id&&(M.type==="line"||M.type==="arrow"||M.type==="draw"||d.push(this.getShapeWorldBounds(M)));let u=20,c=this.getShapeWorldBounds(e),g=c.x,p=c.y,y=c.x+c.width,m=c.y+c.height;o===1?y=Math.max(g+u,y+l.x):o===-1&&(g=Math.min(y-u,g+l.x)),h===1?m=Math.max(p+u,m+l.y):h===-1&&(p=Math.min(m-u,p+l.y));let v=(M,T)=>{let E=null;for(let H of T){let Y=H-M;Math.abs(Y)<=a.ALIGN_SNAP_THRESHOLD&&(E===null||Math.abs(Y)<Math.abs(E))&&(E=Y);}return E};if(o!==0&&d.length>0){let M=[];for(let E of d)M.push(E.x,E.x+E.width/2,E.x+E.width);let T=v(o===1?y:g,M);T!==null&&(o===1?y+=T:g+=T);}if(h!==0&&d.length>0){let M=[];for(let E of d)M.push(E.y,E.y+E.height/2,E.y+E.height);let T=v(h===1?m:p,M);T!==null&&(h===1?m+=T:p+=T);}let x={x:g,y:p,width:y-g,height:m-p},P=[];for(let M of d)o!==0&&P.push(...Q(x,M,"vertical",1)),h!==0&&P.push(...Q(x,M,"horizontal",1));this.context.setSnapGuides(this.mergeGuides(P));let b={};if(e.type==="circle"){let M=Math.max(10,Math.max(o!==0?x.width/2:0,h!==0?x.height/2:0));if(b.radius=M,o!==0){let T=o===1?c.x:c.x+c.width;b.x=o===1?T+M:T-M;}if(h!==0){let T=h===1?c.y:c.y+c.height;b.y=h===1?T+M:T-M;}}else if("width"in e&&o!==0&&(b.width=x.width,b.x=x.x+x.width/2),"height"in e&&h!==0&&(b.height=x.height,b.y=x.y+x.height/2),e.type==="draw"){let M=this.getShapeWorldBounds(e),T=o!==0?x.width/Math.max(1,M.width):1,E=h!==0?x.height/Math.max(1,M.height):1;b.points=e.points.map(H=>({x:H.x*T,y:H.y*E}));}Object.keys(b).length>0&&this.context.updateShape(e.id,b);}mergeGuides(t){let e=new Map;for(let i of t){let n=`${i.type}\0${Math.round(i.position*2)/2}`,s=e.get(n);s?(s.start=Math.min(s.start,i.start),s.end=Math.max(s.end,i.end)):e.set(n,{...i});}return [...e.values()]}handleRotation(t){let e=this.context.getSelectedIds(),i=this.context.getShapes();e.forEach(n=>{let s=i.find(r=>r.id===n);s&&this.context.updateShape(n,{rotation:s.rotation+t*Math.PI/180});});}handleNudge(t,e){let i=this.context.getSelectedIds(),n=this.context.getShapes();i.forEach(s=>{let r=n.find(o=>o.id===s);r&&this.context.updateShape(s,{x:r.x+t,y:r.y+e});});}handleBrushing(t){let e=Math.min(this.brushStart.x,t.x),i=Math.min(this.brushStart.y,t.y),n=Math.abs(t.x-this.brushStart.x),s=Math.abs(t.y-this.brushStart.y);this.context.setBrushRect({x:e,y:i,width:n,height:s});let r=this.context.getShapes(),o=[];for(let h of r){let l=this.getShapeWorldBounds(h);this.rectsIntersect({x:e,y:i,width:n,height:s},l)&&o.push(h.id);}if(this.brushShiftKey){let h=this.context.getSelectedIds(),l=new Set([...h,...o]);this.context.selectShapes([...l]);}else this.context.selectShapes(o);}getShapeWorldBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":return {x:t.x-t.width/2,y:t.y-t.height/2,width:t.width,height:t.height};case "circle":return {x:t.x-t.radius,y:t.y-t.radius,width:t.radius*2,height:t.radius*2};case "line":case "arrow":{if(!t.points||t.points.length===0)return {x:t.x,y:t.y,width:0,height:0};let e=1/0,i=1/0,n=-1/0,s=-1/0;return t.points.forEach(r=>{e=Math.min(e,r.x),i=Math.min(i,r.y),n=Math.max(n,r.x),s=Math.max(s,r.y);}),{x:e,y:i,width:n-e,height:s-i}}case "draw":{let e=t,i=e.width,n=e.height;if(typeof i=="number"&&typeof n=="number"&&i>0&&n>0)return {x:e.x-i/2,y:e.y-n/2,width:i,height:n};if(!e.points||e.points.length===0)return {x:e.x,y:e.y,width:0,height:0};let s=1/0,r=1/0,o=-1/0,h=-1/0;return e.points.forEach(l=>{let d=l.x+e.x,u=l.y+e.y;s=Math.min(s,d),r=Math.min(r,u),o=Math.max(o,d),h=Math.max(h,u);}),{x:s,y:r,width:o-s,height:h-r}}case "text":{let e=t;return {x:t.x-e.width/2,y:t.y-e.height/2,width:e.width,height:e.height}}default:{let e=t;return {x:e.x,y:e.y,width:0,height:0}}}}rectsIntersect(t,e){return t.x<e.x+e.width&&t.x+t.width>e.x&&t.y<e.y+e.height&&t.y+t.height>e.y}hitTest(t,e,i){for(let n=e.length-1;n>=0;n--){let s=e[n];if(i.includes(s.id)){let r=this.getHitHandle(t,s);if(r)return {shape:s,handle:r}}if(this.isPointInShape(t,s))return {shape:s,handle:null}}return {shape:null,handle:null}}getHitHandle(t,e){if(e.type==="mind-map")return null;let i=14,n=this.getShapeBounds(e),s=Math.cos(-e.rotation),r=Math.sin(-e.rotation),o=t.x-e.x,h=t.y-e.y,l=o*s-h*r,d=o*r+h*s,u=[{type:"nw",x:n.x,y:n.y},{type:"ne",x:n.x+n.width,y:n.y},{type:"se",x:n.x+n.width,y:n.y+n.height},{type:"sw",x:n.x,y:n.y+n.height},{type:"rotation",x:n.x+n.width/2,y:n.y-26}];for(let c of u)if(Math.abs(l-c.x)<i&&Math.abs(d-c.y)<i)return c.type;return null}static GEN_HIT_THRESHOLD=14;static CLICK_MOVE_THRESHOLD=6;computeGenPoints(t,e){let i=[];for(let n of e){let s=t.find(r=>r.id===n);if(s){if(s.type==="line"||s.type==="arrow"){if(s.points&&s.points.length>=2){let r=this.getShapeWorldBounds(s);i.push({point:{x:r.x+r.width/2,y:r.y+r.height/2},sourceShapeId:s.id});}}else if(s.type==="rectangle"||s.type==="rounded-rectangle"||s.type==="ellipse"||s.type==="diamond"||s.type==="triangle"||s.type==="hexagon"||s.type==="parallelogram"||s.type==="trapezoid"||s.type==="pentagon"||s.type==="octagon"||s.type==="star"||s.type==="uml-class"||s.type==="uml-interface"||s.type==="circle"||s.type==="draw"){let r=this.getShapeBounds(s),o={x:s.x,y:s.y};i.push({point:{x:o.x+r.x+r.width/2,y:o.y+r.y},edge:"n",sourceShapeId:s.id}),i.push({point:{x:o.x+r.x+r.width,y:o.y+r.y+r.height/2},edge:"e",sourceShapeId:s.id}),i.push({point:{x:o.x+r.x+r.width/2,y:o.y+r.y+r.height},edge:"s",sourceShapeId:s.id}),i.push({point:{x:o.x+r.x,y:o.y+r.y+r.height/2},edge:"w",sourceShapeId:s.id});}}}return i}hitGenPoint(t,e,i){let n=a.GEN_HIT_THRESHOLD,s=null,r=n;for(let o of this.computeGenPoints(e,i)){let h=Math.hypot(o.point.x-t.x,o.point.y-t.y);h<=r&&(r=h,s=o);}return s}genPreviewTarget(t,e,i){if(i)return e;let n=96;if(t.edge)switch(t.edge){case "n":return {x:t.point.x,y:t.point.y-n};case "s":return {x:t.point.x,y:t.point.y+n};case "e":return {x:t.point.x+n,y:t.point.y};case "w":return {x:t.point.x-n,y:t.point.y}}return {x:t.point.x,y:t.point.y-n}}handleGenerating(t,e){if(!this.generatingState)return;let i=this.generatingState,n=i.source;Math.hypot(t.x-i.startPoint.x,t.y-i.startPoint.y)>a.CLICK_MOVE_THRESHOLD&&(i.hasMoved=true);let r=this.findBindingNearPoint(t,e,n.sourceShapeId),o=r?this.bindingPosition(r.toShapeId,r.binding,e):i.hasMoved?t:this.genPreviewTarget(n,t,false);this.context.setConnectingTarget(r?r.toShapeId:null),this.context.setGenerationPreview({from:n.point,to:o,type:r?void 0:this.defaultGenType(n.sourceShapeId)});}handleRotating(t,e){if(!this.rotatingState)return;let i=this.rotatingState,n=Math.atan2(t.y-i.center.y,t.x-i.center.x),s=i.startRotation+(n-i.startAngle);e.shiftKey&&(s=Math.round(s/(Math.PI/12))*(Math.PI/12)),this.context.updateShape(i.shapeId,{rotation:s});}bindingPosition(t,e,i){let n=i.find(r=>r.id===t);if(!n)return {x:0,y:0};let s=this.getShapeWorldBounds(n);if(e.handle)switch(e.handle){case "top":return {x:n.x,y:s.y};case "bottom":return {x:n.x,y:s.y+s.height};case "left":return {x:s.x,y:n.y};case "right":return {x:s.x+s.width,y:n.y}}return e.normalizedAnchor?{x:s.x+s.width*e.normalizedAnchor.x,y:s.y+s.height*e.normalizedAnchor.y}:{x:n.x,y:n.y}}isPointInShape(t,e){let i=t.x-e.x,n=t.y-e.y;switch(e.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":return Math.abs(i)<=e.width/2&&Math.abs(n)<=e.height/2;case "circle":return i*i+n*n<=e.radius*e.radius;case "hexagon":return this.isPointInHexagon(i,n,e.width,e.height);case "line":case "arrow":for(let s=0;s<e.points.length-1;s++){let r=e.points[s],o=e.points[s+1];if(this.pointToLineDistance(t,r,o)<10)return true}return false;case "draw":{let s=this.getShapeBounds(e);return Math.abs(i)<=s.width/2&&Math.abs(n)<=s.height/2}case "text":return Math.abs(i)<=50&&Math.abs(n)<=e.fontSize/2;default:return false}}isPointInHexagon(t,e,i,n){let s=Math.abs(t),r=Math.abs(e),o=i/2,h=n/2;return s<=o&&r<=h&&s/o+r/h<=1.5}pointToLineDistance(t,e,i){let n=t.x-e.x,s=t.y-e.y,r=i.x-e.x,o=i.y-e.y,h=n*r+s*o,l=r*r+o*o,d=-1;l!==0&&(d=h/l);let u,c;d<0?(u=e.x,c=e.y):d>1?(u=i.x,c=i.y):(u=e.x+d*r,c=e.y+d*o);let g=t.x-u,p=t.y-c;return Math.sqrt(g*g+p*p)}getShapeBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":return {x:-t.width/2,y:-t.height/2,width:t.width,height:t.height};case "circle":return {x:-t.radius,y:-t.radius,width:t.radius*2,height:t.radius*2};case "line":case "arrow":{if(t.points.length===0)return {x:0,y:0,width:0,height:0};let e=1/0,i=1/0,n=-1/0,s=-1/0;return t.points.forEach(r=>{e=Math.min(e,r.x-t.x),i=Math.min(i,r.y-t.y),n=Math.max(n,r.x-t.x),s=Math.max(s,r.y-t.y);}),{x:e,y:i,width:n-e,height:s-i}}case "draw":{let e=t;if(typeof e.width=="number"&&typeof e.height=="number")return {x:-e.width/2,y:-e.height/2,width:e.width,height:e.height};if(e.points.length===0)return {x:0,y:0,width:0,height:0};let i=1/0,n=1/0,s=-1/0,r=-1/0;return e.points.forEach(o=>{let h=o.x-e.x,l=o.y-e.y;i=Math.min(i,h),n=Math.min(n,l),s=Math.max(s,h),r=Math.max(r,l);}),{x:i,y:n,width:s-i,height:r-n}}case "text":return {x:-50,y:-t.fontSize/2,width:100,height:t.fontSize};default:return {x:0,y:0,width:0,height:0}}}hitTestArrowTerminal(t,e){for(let n of e){if(n.type!=="arrow")continue;let s=n;if(s.points.length<2)continue;let r=s.points[0],o=s.points[s.points.length-1],h=Math.sqrt(Math.pow(t.x-r.x,2)+Math.pow(t.y-r.y,2)),l=Math.sqrt(Math.pow(t.x-o.x,2)+Math.pow(t.y-o.y,2));if(h<20)return {shapeId:s.id,terminal:"start"};if(l<20)return {shapeId:s.id,terminal:"end"}}return null}findShapeNearPoint(t,e,i){for(let s=e.length-1;s>=0;s--){let r=e[s];if(i&&r.id===i||r.type==="arrow"||r.type==="line"||r.type==="draw")continue;let o;switch(r.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":o=this.pointToRectDistance(t,{x:r.x-r.width/2,y:r.y-r.height/2,width:r.width,height:r.height});break;case "circle":o=Math.sqrt(Math.pow(t.x-r.x,2)+Math.pow(t.y-r.y,2))-r.radius;break;case "hexagon":{let h=r.width/2,l=r.height/2,d=Math.abs(t.x-r.x),u=Math.abs(t.y-r.y);o=d/h+u/l-1;break}default:continue}if(o<=30)return r}return null}pointToRectDistance(t,e){let i=Math.max(e.x,Math.min(t.x,e.x+e.width)),n=Math.max(e.y,Math.min(t.y,e.y+e.height));return Math.sqrt(Math.pow(t.x-i,2)+Math.pow(t.y-n,2))}static SNAP_THRESHOLD=32;static HANDLE_SNAP_DISTANCE=18;static ANCHOR_EPS=.001;computeSnapGuidesForArrow(t,e,i,n,s){let r=this.draggingTerminal==="start"?n.endBinding:n.startBinding,o=r?s.find(p=>p.id===r.toShapeId):null;if(!o)return [];let h=this.findShapeNearPoint(i,s,n.id);if(!h)return [];let l=this.getShapeWorldBounds(o),d=this.getShapeWorldBounds(h),u=e.x-t.x,c=e.y-t.y,g=Math.abs(u)>=Math.abs(c)?"horizontal":"vertical";return Q(l,d,g)}findBindingNearPoint(t,e,i){let n;for(let s=e.length-1;s>=0;s--){let r=e[s];if(i&&r.id===i||r.type==="arrow"||r.type==="line"||r.type==="draw")continue;let o=this.getPageBounds(r),h=a.SNAP_THRESHOLD;if(t.x<o.x-h||t.x>o.x+o.width+h||t.y<o.y-h||t.y>o.y+o.height+h)continue;let l={x:r.x,y:r.y},d=[{handle:"top",pos:{x:l.x,y:o.y}},{handle:"bottom",pos:{x:l.x,y:o.y+o.height}},{handle:"left",pos:{x:o.x,y:l.y}},{handle:"right",pos:{x:o.x+o.width,y:l.y}}];for(let c of d){let g=Math.hypot(c.pos.x-t.x,c.pos.y-t.y);g<=a.HANDLE_SNAP_DISTANCE&&(!n||g<n.distance)&&(n={toShapeId:r.id,binding:{toShapeId:r.id,handle:c.handle,isPrecise:false},distance:g});}let u=this.nearestPointOnShapeOutline(r,t);if(u&&u.distance<=a.SNAP_THRESHOLD&&(!n||u.distance<n.distance)){let c=this.computeNormalizedAnchor(o,u.point);n={toShapeId:r.id,binding:{toShapeId:r.id,isPrecise:true,normalizedAnchor:c},distance:u.distance};}}if(n)return {toShapeId:n.toShapeId,binding:n.binding}}getPageBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":return {x:t.x-t.width/2,y:t.y-t.height/2,width:t.width,height:t.height};case "circle":return {x:t.x-t.radius,y:t.y-t.radius,width:t.radius*2,height:t.radius*2};default:return {x:t.x-50,y:t.y-50,width:100,height:100}}}computeNormalizedAnchor(t,e){let i=a.ANCHOR_EPS,n=t.width>0?(e.x-t.x)/t.width:.5,s=t.height>0?(e.y-t.y)/t.height:.5;return n=Math.max(i,Math.min(1-i,n)),s=Math.max(i,Math.min(1-i,s)),{x:n,y:s}}nearestPointOnShapeOutline(t,e){let i={x:e.x-t.x,y:e.y-t.y},n=this.nearestLocalPointOnShapeOutline(t,i);if(!n)return null;let s={x:n.point.x+t.x,y:n.point.y+t.y};return {point:s,distance:Math.hypot(s.x-e.x,s.y-e.y)}}nearestLocalPointOnShapeOutline(t,e){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":{let i=t.width,n=t.height;return this.nearestPointOnRectOutlineLocal(e,{x:-i/2,y:-n/2,width:i,height:n})}case "circle":{let i=t.radius;return this.nearestPointOnCircleOutlineLocal(e,{x:0,y:0},i)}default:return null}}nearestPointOnRectOutlineLocal(t,e){let i=[[{x:e.x,y:e.y},{x:e.x+e.width,y:e.y}],[{x:e.x+e.width,y:e.y},{x:e.x+e.width,y:e.y+e.height}],[{x:e.x+e.width,y:e.y+e.height},{x:e.x,y:e.y+e.height}],[{x:e.x,y:e.y+e.height},{x:e.x,y:e.y}]],n=null;for(let[s,r]of i){let o=this.nearestPointOnSegment(t,s,r);(!n||o.distance<n.distance)&&(n=o);}return n}nearestPointOnCircleOutlineLocal(t,e,i){let n=t.x-e.x,s=t.y-e.y,r=Math.hypot(n,s);if(r<1e-9)return {point:{x:e.x+i,y:e.y},distance:i};let o=e.x+n/r*i,h=e.y+s/r*i,l={x:o,y:h};return {point:l,distance:Math.hypot(l.x-t.x,l.y-t.y)}}nearestPointOnSegment(t,e,i){let n=i.x-e.x,s=i.y-e.y,r=n*n+s*s,o=r>0?((t.x-e.x)*n+(t.y-e.y)*s)/r:0;o=Math.max(0,Math.min(1,o));let h=e.x+o*n,l=e.y+o*s,d={x:h,y:l};return {point:d,distance:Math.hypot(d.x-t.x,d.y-t.y)}}};var ut=class a extends k{type="hand";state="idle";startScreenPoint={x:0,y:0};initialCameraPos={x:0,y:0};static DRAG_THRESHOLD=4;onPointerDown(t,e){this.startScreenPoint={x:e.clientX,y:e.clientY};let i=this.context.getCamera();this.initialCameraPos={x:i.x,y:i.y},this.state="pointing";}onPointerMove(t,e){if(this.state!=="idle"){if(this.state==="pointing"){let i=e.clientX-this.startScreenPoint.x,n=e.clientY-this.startScreenPoint.y;if(Math.hypot(i,n)<a.DRAG_THRESHOLD)return;this.state="dragging",this.applyCameraDelta(i,n);return}if(this.state==="dragging"){let i=e.clientX-this.startScreenPoint.x,n=e.clientY-this.startScreenPoint.y;this.applyCameraDelta(i,n);}}}onPointerUp(t,e){if(this.state!=="idle"){if(this.state==="dragging"){let i=this.context.getCamera();this.initialCameraPos={x:i.x,y:i.y},this.startScreenPoint={x:e.clientX,y:e.clientY};}this.state="idle";}}onKeyDown(t){t.key==="Escape"&&this.state!=="idle"&&(this.context.setCameraPosition(this.initialCameraPos.x,this.initialCameraPos.y),this.state="idle");}onKeyUp(t){}getCursor(t){return this.state==="dragging"||this.state==="pointing"?"grabbing":"grab"}applyCameraDelta(t,e){this.context.setCameraPosition(this.initialCameraPos.x+t,this.initialCameraPos.y+e);}};var we={strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:2,strokeDash:null},gt=class extends k{type="line";isDrawing=false;startPoint={x:0,y:0};currentShape=null;onPointerDown(t,e){this.isDrawing=true,this.startPoint=t,this.currentShape={id:`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,type:"line",x:t.x,y:t.y,points:[t],rotation:0,style:{...we}},this.context.commitHistory(),this.context.addShape(this.currentShape);}onPointerMove(t,e){!this.isDrawing||!this.currentShape||this.context.updateShape(this.currentShape.id,{points:[this.startPoint,t]});}onPointerUp(t,e){this.isDrawing=false,this.currentShape=null,this.context.setActiveTool("select");}onKeyDown(t){}onKeyUp(t){}getCursor(){return "crosshair"}};var be={strokeColor:"#1f2937",fillColor:"transparent",fillOpacity:1,strokeWidth:4,strokeDash:null},Me={strokeColor:"rgba(255, 235, 59, 0.5)",fillColor:"transparent",fillOpacity:1,strokeWidth:16,strokeDash:null},ve=4e3,at=class extends k{type;mode;isDrawing=false;points=[];currentShapeId=null;committed=false;fadeTimer=null;constructor(t,e){super(t),this.mode=e,this.type=e==="pen"?"pen":"highlighter";}onPointerDown(t,e){this.isDrawing=true,this.committed=false,this.currentShapeId=null,this.points=[{...t}];}buildGeometry(t){let e=1/0,i=1/0,n=-1/0,s=-1/0;for(let c of t)c.x<e&&(e=c.x),c.y<i&&(i=c.y),c.x>n&&(n=c.x),c.y>s&&(s=c.y);let r=(e+n)/2,o=(i+s)/2,h=6,l=Math.max(1,n-e)+h*2,d=Math.max(1,s-i)+h*2,u=t.map(c=>({x:c.x-r,y:c.y-o}));return {x:r,y:o,width:l,height:d,points:u}}onPointerMove(t,e){if(this.isDrawing){if(this.points.push({...t}),!this.committed&&this.points.length>=2){this.context.commitHistory();let i=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;this.currentShapeId=i;let n=this.buildGeometry(this.points),s=this.mode==="pen"?{...be}:{...Me},r={id:i,type:"draw",x:n.x,y:n.y,width:n.width,height:n.height,points:n.points,rotation:0,style:s};this.context.addShape(r),this.committed=true;}else if(this.committed&&this.currentShapeId){let i=this.buildGeometry(this.points);this.context.updateShape(this.currentShapeId,{x:i.x,y:i.y,width:i.width,height:i.height,points:i.points});}}}onPointerUp(t,e){if(!this.isDrawing||(this.isDrawing=false,!this.committed||!this.currentShapeId))return;let i=this.currentShapeId;this.currentShapeId=null,this.mode==="highlighter"&&(this.fadeTimer=setTimeout(()=>{this.context.deleteShape(i);},ve));}onKeyDown(t){}onKeyUp(t){}getCursor(){return "crosshair"}dispose(){this.fadeTimer&&(clearTimeout(this.fadeTimer),this.fadeTimer=null);}};var Pe={strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:2,strokeDash:null},pt=class extends k{type="arrow";isDrawing=false;startPoint={x:0,y:0};currentShapeId=null;startBindingInfo=null;onPointerDown(t,e){this.isDrawing=true,this.startPoint=t,this.startBindingInfo=null;let i=this.context.getShapes(),n=this.findShapeBinding(t,i),s=t;n&&(s=this.getBindingPosition(n.toShapeId,n.handle,i),this.startBindingInfo={...n,position:s});let r=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;this.currentShapeId=r;let o={id:r,type:"arrow",x:s.x,y:s.y,points:[s],rotation:0,style:{...Pe},startBinding:n?{toShapeId:n.toShapeId,handle:n.handle}:void 0,connectionType:"straight",arrowHead:"end",dashed:false};this.context.commitHistory(),this.context.addShape(o);}onPointerMove(t,e){if(!this.isDrawing||!this.currentShapeId)return;let i=this.context.getShapes(),n=this.findShapeBinding(t,i),s=t;n&&(s=this.getBindingPosition(n.toShapeId,n.handle,i));let r=this.startBindingInfo?.position||this.startPoint,o=this.computeSnapGuides(r,s,n,i);this.context.setSnapGuides(o),this.context.updateShape(this.currentShapeId,{points:[r,s],endBinding:n?{toShapeId:n.toShapeId,handle:n.handle}:void 0});}onPointerUp(t,e){this.isDrawing=false,this.currentShapeId=null,this.startBindingInfo=null,this.context.setSnapGuides([]),this.context.setActiveTool("select");}onKeyDown(t){}onKeyUp(t){}getCursor(){return "crosshair"}computeSnapGuides(t,e,i,n){let s=this.startBindingInfo?n.find(c=>c.id===this.startBindingInfo.toShapeId):null,r=i?n.find(c=>c.id===i.toShapeId):null;if(!s||!r)return [];let o=this.getShapeBounds(s),h=this.getShapeBounds(r),l=e.x-t.x,d=e.y-t.y,u=Math.abs(l)>=Math.abs(d)?"horizontal":"vertical";return Q(o,h,u)}getShapeBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":return {x:t.x-t.width/2,y:t.y-t.height/2,width:t.width,height:t.height};case "circle":return {x:t.x-t.radius,y:t.y-t.radius,width:t.radius*2,height:t.radius*2};case "text":return {x:t.x-t.width/2,y:t.y-t.height/2,width:t.width,height:t.height};default:return {x:t.x-50,y:t.y-20,width:100,height:40}}}findShapeBinding(t,e){for(let n=e.length-1;n>=0;n--){let s=e[n];if(s.type==="arrow"||s.type==="line"||s.type==="draw")continue;let r;switch(s.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "uml-class":case "uml-interface":r=this.pointToRectDistance(t,{x:s.x-s.width/2,y:s.y-s.height/2,width:s.width,height:s.height});break;case "circle":{let o=Math.sqrt(Math.pow(t.x-s.x,2)+Math.pow(t.y-s.y,2));r=Math.abs(o-s.radius);break}case "hexagon":{let o=s.width/2,h=s.height/2,l=Math.abs(t.x-s.x),d=Math.abs(t.y-s.y);r=l/o+d/h-1;break}default:continue}if(r<=40){let o=this.getClosestHandle(t,s);return {toShapeId:s.id,handle:o}}}}pointToRectDistance(t,e){let i=Math.max(e.x,Math.min(t.x,e.x+e.width)),n=Math.max(e.y,Math.min(t.y,e.y+e.height));return Math.sqrt(Math.pow(t.x-i,2)+Math.pow(t.y-n,2))}getClosestHandle(t,e){let i=t.x-e.x,n=t.y-e.y;if(e.type==="circle"||e.type==="hexagon"){let l=Math.atan2(n,i);return l>=-Math.PI/4&&l<Math.PI/4?"right":l>=Math.PI/4&&l<3*Math.PI/4?"bottom":l>=3*Math.PI/4||l<-(3*Math.PI)/4?"left":"top"}let s="width"in e?e.width:100,r="height"in e?e.height:100,o=Math.abs(i)/(s/2),h=Math.abs(n)/(r/2);return o>h?i>0?"right":"left":n>0?"bottom":"top"}getBindingPosition(t,e,i){let n=i.find(s=>s.id===t);if(!n)return {x:0,y:0};switch(n.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":return this.getRectBindingPosition(n,e);case "circle":return this.getCircleBindingPosition(n,e);case "hexagon":return this.getRectBindingPosition(n,e);default:return {x:n.x,y:n.y}}}getRectBindingPosition(t,e){switch(e){case "top":return {x:t.x,y:t.y-t.height/2};case "bottom":return {x:t.x,y:t.y+t.height/2};case "left":return {x:t.x-t.width/2,y:t.y};case "right":return {x:t.x+t.width/2,y:t.y}}}getCircleBindingPosition(t,e){switch(e){case "top":return {x:t.x,y:t.y-t.radius};case "bottom":return {x:t.x,y:t.y+t.radius};case "left":return {x:t.x-t.radius,y:t.y};case "right":return {x:t.x+t.radius,y:t.y}}}};var Te={strokeColor:"transparent",fillColor:"transparent",strokeWidth:0,strokeDash:null},$t=class extends k{type="text";onPointerDown(t,e){let i=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,n={id:i,type:"text",x:t.x,y:t.y,rotation:0,style:{...Te},text:"",fontSize:16,textColor:"#1f2937",width:200,height:24};this.context.commitHistory(),this.context.addShape(n),this.context.enterEditing(i);}onPointerMove(t,e){}onPointerUp(t,e){}onKeyDown(t){}onKeyUp(t){}getCursor(){return "text"}};var mt="#1f2937";function Ut(a){switch(a.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":case "text":return {x:-(a.width/2),y:-(a.height/2),width:a.width,height:a.height};case "circle":return {x:-a.radius,y:-a.radius,width:a.radius*2,height:a.radius*2};case "line":case "arrow":{let t=a.points;if(!t||t.length===0)return {x:0,y:0,width:0,height:0};let e=1/0,i=1/0,n=-1/0,s=-1/0;for(let r of t){let o=r.x-a.x,h=r.y-a.y;e=Math.min(e,o),i=Math.min(i,h),n=Math.max(n,o),s=Math.max(s,h);}return {x:e,y:i,width:n-e,height:s-i}}case "draw":{let t=a,e=t.width,i=t.height;if(typeof e=="number"&&typeof i=="number")return {x:-e/2,y:-i/2,width:e,height:i};let n=t.points;if(!n||n.length===0)return {x:0,y:0,width:0,height:0};let s=1/0,r=1/0,o=-1/0,h=-1/0;for(let l of n)s=Math.min(s,l.x),r=Math.min(r,l.y),o=Math.max(o,l.x),h=Math.max(h,l.y);return {x:s,y:r,width:o-s,height:h-r}}default:return {x:0,y:0,width:0,height:0}}}function Ie(a){let t=Ut(a),e=Math.cos(a.rotation),i=Math.sin(a.rotation),n=1/0,s=1/0,r=-1/0,o=-1/0,h=[[t.x,t.y],[t.x+t.width,t.y],[t.x+t.width,t.y+t.height],[t.x,t.y+t.height]];for(let[l,d]of h){let u=l*e-d*i+a.x,c=l*i+d*e+a.y;n=Math.min(n,u),s=Math.min(s,c),r=Math.max(r,u),o=Math.max(o,c);}return {x:n,y:s,width:r-n,height:o-s}}function xt(a,t=24){if(!a||a.length===0)return {x:0,y:0,width:400,height:300};let e=1/0,i=1/0,n=-1/0,s=-1/0;for(let r of a){let o=Ie(r);e=Math.min(e,o.x),i=Math.min(i,o.y),n=Math.max(n,o.x+o.width),s=Math.max(s,o.y+o.height);}return {x:e-t,y:i-t,width:n-e+t*2,height:s-i+t*2}}function re(a,t={}){let e=t.padding??24,i=t.scale??2,n=t.background===void 0?"#ffffff":t.background??null,s=xt(a,e),r=Math.max(1,Math.ceil(s.width)),o=Math.max(1,Math.ceil(s.height)),h=document.createElement("canvas");h.width=Math.ceil(r*i),h.height=Math.ceil(o*i);let l=new st(h,i);l.resize(r*i,o*i);let d=new nt;return d.zoom=1,d.x=-s.x,d.y=-s.y,l.render(a,d,new Set,void 0,void 0,void 0,void 0,void 0,void 0,void 0,n),h}function Ce(a,t,e){return new Promise((i,n)=>{a.toBlob(s=>{s?i(s):n(new Error("canvas.toBlob failed"));},t,e);})}function Ee(a,t,e){return a.toDataURL(t,e)}var yt=null;function et(a,t){return yt||(yt=document.createElement("canvas").getContext("2d")),yt?(yt.font=t,yt.measureText(a).width):a.length*8}function ht(a){return a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function Qt(a,t,e,i){let n=t*1.3,s=Math.max(1,Math.floor(i/n)),r=`${t}px sans-serif`,o=a.split(`
|
|
3
|
+
`),h=[];for(let d of o){let u="";for(let c of d){let g=u+c;et(g,r)>e&&u?(h.push(u),u=c):u=g;}u&&h.push(u);}let l=h.slice(0,s);if(h.length>s&&l.length>0){let d=l[l.length-1],u="...";for(;d.length>0&&et(d+u,r)>e;)d=d.slice(0,-1);l[l.length-1]=d+u;}return l}function Ot(a,t,e){if(et(a,e)<=t)return a;let i="\u2026",n=0,s=a.length;for(;n<s;){let r=n+s+1>>1;et(a.slice(0,r)+i,e)<=t?n=r:s=r-1;}return a.slice(0,n)+i}function tt(a){return a.map(([t,e])=>`${f(t)},${f(e)}`).join(" ")}function f(a){return Math.round(a*100)/100}function oe(a){return a.strokeDash&&a.strokeDash.length?a.strokeDash.join(","):void 0}function $e(a,t){let e=t.x-a.x,i=t.y-a.y,n=Math.cos(a.rotation),s=Math.sin(a.rotation);return {x:e*n-i*s+a.x,y:e*s+i*n+a.y}}function te(a,t){if(t.isPrecise&&t.normalizedAnchor){let e=Ut(a),i=a.x+e.x+e.width*t.normalizedAnchor.x,n=a.y+e.y+e.height*t.normalizedAnchor.y;return {x:i,y:n}}if(t.handle){let e=Ut(a);switch(t.handle){case "top":return {x:a.x,y:a.y+e.y};case "bottom":return {x:a.x,y:a.y+e.y+e.height};case "left":return {x:a.x+e.x,y:a.y};case "right":return {x:a.x+e.x+e.width,y:a.y}}}return {x:a.x,y:a.y}}function De(a,t){let e=a.points.map(i=>({...i}));if(e.length===0)return e;if(a.startBinding){let i=t.get(a.startBinding.toShapeId);i&&(e[0]=te(i,a.startBinding));}if(a.endBinding){let i=t.get(a.endBinding.toShapeId);i&&(e[e.length-1]=te(i,a.endBinding));}return e.map(i=>$e(a,i))}function Ae(a){if(a.length<2)return a;let t=a[0],e=a[a.length-1],i=e.x-t.x,n=e.y-t.y,s=8;if(Math.abs(n)<=s){let r=(t.y+e.y)/2;return a.map(o=>({x:o.x,y:r}))}if(Math.abs(i)<=s){let r=(t.x+e.x)/2;return a.map(o=>({x:r,y:o.y}))}return a}function Le(a){if(a.length<2)return a;let t=[a[0]];for(let e=1;e<a.length;e++){let i=a[e-1],n=a[e],s=(i.x+n.x)/2,r=(i.y+n.y)/2;Math.abs(n.x-i.x)>=Math.abs(n.y-i.y)?(t.push({x:s,y:i.y}),t.push({x:s,y:n.y})):(t.push({x:i.x,y:r}),t.push({x:n.x,y:r})),t.push(n);}return t}function Ne(a){if(a.length<2)return "";let t=`M ${f(a[0].x)} ${f(a[0].y)}`,e=a[0];for(let i=1;i<a.length;i++){let n=a[i],s=n.x-e.x,r=n.y-e.y,o=Math.hypot(s,r),h={x:(e.x+n.x)/2,y:(e.y+n.y)/2};if(o>=1){let l=-r/o,d=s/o,u=Math.min(o*.2,30);h={x:h.x+l*u,y:h.y+d*u};}t+=` Q ${f(h.x)} ${f(h.y)} ${f(n.x)} ${f(n.y)}`,e=n;}return t}function Re(a,t){if(t==="curve")return Ne(a);let e=t==="straight"?Ae(a):Le(a);if(e.length<2)return "";let i=`M ${f(e[0].x)} ${f(e[0].y)}`;for(let n=1;n<e.length;n++)i+=` L ${f(e[n].x)} ${f(e[n].y)}`;return i}function ee(a,t,e,i){let n=Math.atan2(t.y-a.y,t.x-a.x),s=12,r={x:t.x-s*Math.cos(n-Math.PI/6),y:t.y-s*Math.sin(n-Math.PI/6)},o={x:t.x-s*Math.cos(n+Math.PI/6),y:t.y-s*Math.sin(n+Math.PI/6)};return `<path d="M ${f(t.x)} ${f(t.y)} L ${f(r.x)} ${f(r.y)} M ${f(t.x)} ${f(t.y)} L ${f(o.x)} ${f(o.y)}" stroke="${e}" stroke-width="${i}" stroke-linecap="round" fill="none" />`}function Ve(a,t,e,i){let n=Math.atan2(t.y-a.y,t.x-a.x),s=14,r=t.x,o=t.y,h=t.x-s*Math.cos(n),l=t.y-s*Math.sin(n),d=h+s*.5*Math.cos(n-Math.PI/2),u=l+s*.5*Math.sin(n-Math.PI/2),c=h+s*.5*Math.cos(n+Math.PI/2),g=l+s*.5*Math.sin(n+Math.PI/2);return `<polygon points="${f(r)},${f(o)} ${f(d)},${f(u)} ${f(c)},${f(g)}" fill="#ffffff" stroke="${e}" stroke-width="${i}" />`}function ne(a,t,e,i,n){let s=Math.atan2(t.y-a.y,t.x-a.x),r=14,o=t.x,h=t.y,l=t.x-r*.5*Math.cos(s),d=t.y-r*.5*Math.sin(s),u=t.x-r*Math.cos(s),c=t.y-r*Math.sin(s),g=l+r*.4*Math.cos(s-Math.PI/2),p=d+r*.4*Math.sin(s-Math.PI/2),y=l+r*.4*Math.cos(s+Math.PI/2),m=d+r*.4*Math.sin(s+Math.PI/2);return `<polygon points="${f(o)},${f(h)} ${f(g)},${f(p)} ${f(u)},${f(c)} ${f(y)},${f(m)}" fill="${n?e:"#ffffff"}" stroke="${e}" stroke-width="${i}" />`}function ke(a,t,e,i){if(t==="none"||a.length<2)return "";let n="";return (t==="start"||t==="both")&&(n+=ee(a[1],a[0],e,i)),(t==="end"||t==="both")&&(n+=ee(a[a.length-2],a[a.length-1],e,i)),t==="inheritance"&&(n+=Ve(a[a.length-2],a[a.length-1],e,i)),t==="aggregation"&&(n+=ne(a[1],a[0],e,i,false)),t==="composition"&&(n+=ne(a[1],a[0],e,i,true)),n}function ie(a,t,e,i=0,n=0){if(a.length===0)return "";let s=t*1.3,o=-(a.length*s)/2+s/2,h=a.map((l,d)=>`<tspan x="${f(i)}" y="${f(n+o+d*s)}">${ht(l)}</tspan>`).join("");return `<text text-anchor="middle" dominant-baseline="central" font-family="sans-serif" font-size="${t}" fill="${e}">${h}</text>`}function z(a,t){let e=oe(a),i=a.fillColor!=="transparent",n=a.fillOpacity??1,s=a.strokeOpacity??1;return [i?`fill="${a.fillColor}"`:'fill="none"',i&&n<1?`fill-opacity="${f(n)}"`:"",`stroke="${a.strokeColor}"`,s<1&&a.strokeColor!=="transparent"?`stroke-opacity="${f(s)}"`:"",`stroke-width="${a.strokeWidth}"`,'stroke-linecap="round"','stroke-linejoin="round"',e?`stroke-dasharray="${e}"`:""].filter(Boolean).join(" ")}function se(a,t){let{width:e,height:i}=a,n=e/2,s=i/2,r=`${U}px sans-serif`,o=K,h=t?0:a.attributes.length>0?a.attributes.length*L+D*2:D*2,l=e-_*2,d=[];d.push(`<rect x="${f(-n)}" y="${f(-s)}" width="${e}" height="${i}" ${z(a.style)} />`),d.push(`<line x1="${f(-n)}" y1="${f(-s+o)}" x2="${f(n)}" y2="${f(-s+o)}" stroke="${a.style.strokeColor}" stroke-width="${a.style.strokeWidth}" />`),t||d.push(`<line x1="${f(-n)}" y1="${f(-s+o+h)}" x2="${f(n)}" y2="${f(-s+o+h)}" stroke="${a.style.strokeColor}" stroke-width="${a.style.strokeWidth}" />`);let u=t?`<<${a.className||"Interface"}>>`:a.className;d.push(`<text text-anchor="middle" dominant-baseline="central" font-family="sans-serif" font-weight="bold" font-size="${U}" fill="${a.textColor||mt}" x="0" y="${f(-s+o/2)}">${ht(Ot(u,l,r))}</text>`);let c=(p,y,m,v,x)=>{let P=`${m||U}px sans-serif`,b=Ot(p,l,P),M=`<text text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-size="${m||U}" fill="${v||mt}" x="${f(-n+_)}" y="${f(y)}">${ht(b)}</text>`;if(x){let T=et(b,P);M+=`<line x1="${f(-n+_)}" y1="${f(y)}" x2="${f(-n+_+T)}" y2="${f(y)}" stroke="${v||mt}" stroke-width="1" />`;}return M};if(!t){let p=-s+o+D+L/2;a.attributes.forEach((y,m)=>{d.push(c(`${y.visibility} ${y.name}: ${y.type}`,p+m*L,y.fontSize||a.fontSize||0,y.textColor||a.textColor||"",!!y.strikethrough));});}let g=-s+o+h+D+L/2;return a.methods.forEach((p,y)=>{d.push(c(`${p.visibility} ${p.name}(${p.params}): ${p.returnType}`,g+y*L,p.fontSize||a.fontSize||0,p.textColor||a.textColor||"",!!p.strikethrough));}),d.join("")}function He(a){let e=B(a.root).positions,i=[],n=r=>{if(r.collapsed)return;let o=e.get(r.id);if(o)for(let h of r.children??[]){let l=e.get(h.id);if(!l)continue;let d=it(h,l.depth),u=a.x+o.x+o.width/2,c=a.y+o.y,g=a.x+l.x-l.width/2,p=a.y+l.y,y=(u+g)/2;i.push(`<path d="M ${f(u)} ${f(c)} C ${f(y)} ${f(c)} ${f(y)} ${f(p)} ${f(g)} ${f(p)}" stroke="${d}" stroke-width="2" fill="none" stroke-linecap="round" />`),n(h);}};n(a.root);let s=r=>{let o=e.get(r.id);if(!o)return;let h=it(r,o.depth),l=o.width/2,d=o.height/2,u=a.x+o.x,c=a.y+o.y;if(i.push(`<rect x="${f(u-l)}" y="${f(c-d)}" width="${o.width}" height="${o.height}" rx="6" ry="6" fill="#ffffff" stroke="${h}" stroke-width="2" />`),r.note){let P="11px sans-serif",b=r.noteColor??h,M=Math.min(et(r.note,P)+12,130),T=16,E=et(r.note,P)+12>130?r.note.slice(0,12)+"\u2026":r.note;i.push(`<rect x="${f(u-l)}" y="${f(c-d-T+2)}" width="${M}" height="${T}" rx="4" ry="4" fill="${b}" />`),i.push(`<text text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-size="11" fill="#ffffff" x="${f(u-l+6)}" y="${f(c-d-T/2+2)}">${ht(E)}</text>`);}let g=r.icon?18:0,p=o.width-g-(r.icon?8:0)-16,y=Ot(r.text||"",p,`${14}px sans-serif`),m=et(y,`${14}px sans-serif`),v=g+(g?8:0)+m,x=u-v/2;if(r.icon&&(i.push(`<text text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-size="16" fill="#1f2937" x="${f(x)}" y="${f(c)}">${ht(r.icon)}</text>`),x+=g+8),i.push(`<text text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-size="${14}" fill="#1f2937" x="${f(x)}" y="${f(c)}">${ht(y)}</text>`),r.children&&r.children.length>0&&!r.collapsed)for(let P of r.children)s(P);};return s(a.root),i.join("")}function Be(a,t){let e=a.rotation*180/Math.PI,i=`<g transform="translate(${f(a.x)} ${f(a.y)}) rotate(${f(e)})">`,n="</g>",s=a.style;switch(a.type){case "rectangle":{let r=a.width,o=a.height;return `${i}<rect x="${f(-r/2)}" y="${f(-o/2)}" width="${r}" height="${o}" ${z(s)} />${n}`}case "rounded-rectangle":{let r=a.width,o=a.height,h=a.borderRadius||8;return `${i}<rect x="${f(-r/2)}" y="${f(-o/2)}" width="${r}" height="${o}" rx="${h}" ry="${h}" ${z(s)} />${n}`}case "circle":{let r=a.radius;return `${i}<circle cx="0" cy="0" r="${r}" ${z(s)} />${n}`}case "ellipse":{let r=a.width,o=a.height;return `${i}<ellipse cx="0" cy="0" rx="${r/2}" ry="${o/2}" ${z(s)} />${n}`}case "diamond":{let r=a.width,o=a.height;return `${i}<polygon points="${tt([[0,-o/2],[r/2,0],[0,o/2],[-r/2,0]])}" ${z(s)} />${n}`}case "triangle":{let r=a.width,o=a.height;return `${i}<polygon points="${tt([[0,-o/2],[r/2,o/2],[-r/2,o/2]])}" ${z(s)} />${n}`}case "hexagon":{let r=a.width,o=a.height;return `${i}<polygon points="${tt(_t(r,o,6,-Math.PI/2))}" ${z(s)} />${n}`}case "pentagon":{let r=a.width,o=a.height;return `${i}<polygon points="${tt(_t(r,o,5,-Math.PI/2))}" ${z(s)} />${n}`}case "octagon":{let r=a.width,o=a.height;return `${i}<polygon points="${tt(_t(r,o,8,-Math.PI/8))}" ${z(s)} />${n}`}case "star":{let r=a.width,o=a.height;return `${i}<polygon points="${tt(_e(r,o))}" ${z(s)} />${n}`}case "parallelogram":{let r=a.width,o=a.height,h=r*.2;return `${i}<polygon points="${tt([[-r/2+h,-o/2],[r/2,-o/2],[r/2-h,o/2],[-r/2,o/2]])}" ${z(s)} />${n}`}case "trapezoid":{let r=a.width,o=a.height,h=r*.15;return `${i}<polygon points="${tt([[-r/2+h,-o/2],[r/2-h,-o/2],[r/2,o/2],[-r/2,o/2]])}" ${z(s)} />${n}`}case "uml-class":return `${i}${se(a,false)}${n}`;case "uml-interface":return `${i}${se(a,true)}${n}`;case "mind-map":return He(a);case "line":case "arrow":{let r=a,o=r.connectionType||"straight",h=De(r,t);if(h.length<2)return "";let l=r.style.strokeColor,d=r.style.strokeWidth,u=oe(r.style),c=`<path d="${Re(h,o)}" fill="none" stroke="${l}" stroke-width="${d}" stroke-linecap="round" stroke-linejoin="round"${u?` stroke-dasharray="${u}"`:""} />`,g=ke(h,r.arrowHead||"end",l,d);return `${c}${g}`}case "draw":{let r=a,o=r.points;if(!o||o.length<2)return "";let h=Math.cos(r.rotation||0),l=Math.sin(r.rotation||0),d=o.map(c=>({x:c.x*h-c.y*l+r.x,y:c.x*l+c.y*h+r.y}));if(d.length<2)return "";let u=`M ${f(d[0].x)} ${f(d[0].y)}`;for(let c=1;c<d.length-1;c++){let g=(d[c].x+d[c+1].x)/2,p=(d[c].y+d[c+1].y)/2;u+=` Q ${f(d[c].x)} ${f(d[c].y)} ${f(g)} ${f(p)}`;}return u+=` L ${f(d[d.length-1].x)} ${f(d[d.length-1].y)}`,`<path d="${u}" fill="none" stroke="${s.strokeColor}" stroke-width="${s.strokeWidth}" stroke-linecap="round" stroke-linejoin="round" />`}case "text":{let r=a,o=r.fontSize||16,h=r.textColor||mt,l=Qt(r.text||"",o,r.width,r.height),d="";if(r.highlightColor&&r.highlightColor!=="transparent"){let u=o*.15,c=typeof r.highlightOpacity=="number"?r.highlightOpacity:1,g=c<1?` fill-opacity="${f(c)}"`:"";d+=`<rect x="${f(-r.width/2-u)}" y="${f(-(l.length*o*1.3)/2-u)}" width="${r.width+u*2}" height="${l.length*o*1.3+u*2}" rx="4" fill="${r.highlightColor}"${g} />`;}return d+=ie(l,o,h),`${i}${d}${n}`}default:{let r=a,o=r.width||100,h=r.height||40,l="";if(r.text){let d=r.fontSize||16,u=Qt(r.text,d,o*.85,h*.85);l+=ie(u,d,r.textColor||mt);}return `${i}<rect x="${f(-o/2)}" y="${f(-h/2)}" width="${o}" height="${h}" ${z(s)} />${l}${n}`}}}function _t(a,t,e,i){let n=a/2,s=t/2,r=[];for(let o=0;o<e;o++){let h=o*2*Math.PI/e+i;r.push([n*Math.cos(h),s*Math.sin(h)]);}return r}function _e(a,t){let e=a/2,i=t/2,n=5,s=.4,r=[];for(let o=0;o<n*2;o++){let h=o*Math.PI/n-Math.PI/2,l=o%2===0?1:s;r.push([e*l*Math.cos(h),i*l*Math.sin(h)]);}return r}function ae(a,t={}){let e=t.padding??24,i=t.background===void 0?"#ffffff":t.background??null,n=xt(a,e),s=Math.max(1,Math.ceil(n.width)),r=Math.max(1,Math.ceil(n.height)),o=new Map(a.map(d=>[d.id,d])),h=a.map(d=>Be(d,o)).filter(Boolean).join(`
|
|
4
|
+
`),l=i?`<rect x="${f(n.x)}" y="${f(n.y)}" width="${s}" height="${r}" fill="${i}" />`:"";return `<?xml version="1.0" encoding="UTF-8"?>
|
|
5
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${s}" height="${r}" viewBox="${f(n.x)} ${f(n.y)} ${s} ${r}" font-family="sans-serif">
|
|
6
6
|
${l}
|
|
7
7
|
${h}
|
|
8
|
-
</svg>`}function ft(a){return a.toString().padStart(10,"0")}function Ue(a,t,e){let i=a.split(",")[1]||"",n=atob(i),
|
|
8
|
+
</svg>`}function ft(a){return a.toString().padStart(10,"0")}function Ue(a,t,e){let i=a.split(",")[1]||"",n=atob(i),s=new Uint8Array(n.length);for(let E=0;E<n.length;E++)s[E]=n.charCodeAt(E);let r=Math.round(t),o=Math.round(e),h=`<< /Type /XObject /Subtype /Image /Width ${r} /Height ${o} /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length ${s.length} >>`,l=`q ${r} 0 0 ${o} 0 0 cm /Im0 Do Q`,d=`1 0 obj
|
|
9
9
|
<< /Type /Catalog /Pages 2 0 R >>
|
|
10
10
|
endobj
|
|
11
11
|
`,u=`2 0 obj
|
|
12
12
|
<< /Type /Pages /Kids [3 0 R] /Count 1 >>
|
|
13
13
|
endobj
|
|
14
14
|
`,c=`3 0 obj
|
|
15
|
-
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 ${
|
|
15
|
+
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 ${r} ${o}] /Resources << /XObject << /Im0 4 0 R >> >> /Contents 5 0 R >>
|
|
16
16
|
endobj
|
|
17
17
|
`,g=`4 0 obj
|
|
18
18
|
${h}
|
|
@@ -25,19 +25,19 @@ stream
|
|
|
25
25
|
${l}
|
|
26
26
|
endstream
|
|
27
27
|
endobj
|
|
28
|
-
`,
|
|
29
|
-
`,
|
|
28
|
+
`,m=`%PDF-1.4
|
|
29
|
+
`,v=m.length,x=v+d.length,P=x+u.length,b=P+c.length,M=b+g.length+s.length+p.length,T=`xref
|
|
30
30
|
0 6
|
|
31
31
|
0000000000 65535 f
|
|
32
|
-
`+ft(M)+` 00000 n
|
|
33
|
-
`+ft(x)+` 00000 n
|
|
34
32
|
`+ft(v)+` 00000 n
|
|
35
|
-
`+ft(
|
|
33
|
+
`+ft(x)+` 00000 n
|
|
36
34
|
`+ft(P)+` 00000 n
|
|
35
|
+
`+ft(b)+` 00000 n
|
|
36
|
+
`+ft(M)+` 00000 n
|
|
37
37
|
trailer
|
|
38
38
|
<< /Size 6 /Root 1 0 R >>
|
|
39
39
|
startxref
|
|
40
|
-
${
|
|
41
|
-
%%EOF`;return new Blob([f+d+u+c+g,r,p+y+T],{type:"application/pdf"})}async function zt(a,t,e={}){if(t==="svg"){let r=he(a,e);return new Blob([r],{type:"image/svg+xml;charset=utf-8"})}let i=re(a,e);if(t==="png")return Ee(i,"image/png");let n=$e(i,"image/jpeg",.92);return Ue(n,i.width,i.height)}function Ot(a,t){let e=URL.createObjectURL(a),i=document.createElement("a");i.href=e,i.download=t,document.body.appendChild(i),i.click(),document.body.removeChild(i),setTimeout(()=>URL.revokeObjectURL(e),1e3);}var Xt="drawui-canvas-data",Ge=50,Yt=class{canvas;renderer;camera;tools=new Map;activeTool="select";shapes=[];selectedIds=[];listeners=new Set;notificationListeners=new Set;uiListeners=new Set;isPanning=false;panStart={x:0,y:0};dragStartPositions=new Map;lastClickTime=0;lastClickShapeId=null;editingShapeId=null;textInput=null;textOverlay=null;isNewTextShape=false;originalTextValue="";undoStack=[];redoStack=[];isUndoing=false;brushRect=null;snapGuides=[];connectingTargetId=null;genPreview=null;eraserPoint=null;mindMapEditingShapeId=null;mindMapSelectedNode=null;mindMapHoverNode=null;renderScheduled=false;pointerIsDown=false;notifyScheduled=false;persist=true;constructor(t,e={}){this.canvas=t,this.persist=e.persist??!e.shapes,e.theme&&bt(e.theme),e.language&&vt(e.language);let i=t.getBoundingClientRect();this.renderer=new st(t),this.renderer.resize(i.width,i.height),this.camera=new et;let n={addShape:r=>this.addShape(r),updateShape:(r,s)=>this.updateShape(r,s),deleteShape:r=>this.deleteShape(r),selectShape:(r,s)=>this.selectShape(r,s),selectShapes:r=>this.selectShapes(r),getShapes:()=>[...this.shapes],getSelectedIds:()=>[...this.selectedIds],setActiveTool:r=>this.setActiveTool(r),screenToPage:r=>this.screenToPage(r),getCamera:()=>this.camera,panBy:(r,s)=>this.panBy(r,s),setCameraPosition:(r,s)=>this.setCameraPosition(r,s),getShapeAtPoint:(r,s)=>this.getShapeAtPoint(r,s),getShapesInBrushRadius:(r,s)=>this.getShapesInBrushRadius(r,s),setEraserPoint:r=>this.setEraserPoint(r),updateArrowBinding:(r,s,o,h)=>this.updateArrowBinding(r,s,o,h),enterEditing:r=>this.enterEditing(r),exitEditing:()=>this.exitEditing(),commitHistory:()=>this.commitHistory(),setBrushRect:r=>this.setBrushRect(r),setSnapGuides:r=>this.setSnapGuides(r),setConnectingTarget:r=>this.setConnectingTarget(r),setGenerationPreview:r=>this.setGenerationPreview(r),openGenerationMenu:r=>this.openGenerationMenu(r),createGeneratedConnection:(r,s)=>this.createGeneratedConnection(r,s),createFloatingLine:r=>this.createFloatingLine(r),connectToExisting:(r,s,o)=>this.connectToExisting(r,s,o),updateSelectedShapesStyle:r=>this.updateSelectedShapesStyle(r),updateSelectedShapesText:r=>this.updateSelectedShapesText(r),updateConnectionType:r=>this.updateConnectionType(r),getMindMapCursorHitAtPoint:r=>this.getMindMapCursorHitAtPoint(r),selectMindMapNode:(r,s)=>this.selectMindMapNode(r,s)};this.tools.set("select",new ct(n)),this.tools.set("hand",new ut(n)),this.tools.set("rectangle",new V(n,"rectangle")),this.tools.set("rounded-rectangle",new V(n,"rounded-rectangle")),this.tools.set("circle",new V(n,"circle")),this.tools.set("ellipse",new V(n,"ellipse")),this.tools.set("diamond",new V(n,"diamond")),this.tools.set("triangle",new V(n,"triangle")),this.tools.set("hexagon",new V(n,"hexagon")),this.tools.set("parallelogram",new V(n,"parallelogram")),this.tools.set("trapezoid",new V(n,"trapezoid")),this.tools.set("pentagon",new V(n,"pentagon")),this.tools.set("octagon",new V(n,"octagon")),this.tools.set("star",new V(n,"star")),this.tools.set("uml-class",new V(n,"uml-class")),this.tools.set("uml-interface",new V(n,"uml-interface")),this.tools.set("line",new gt(n)),this.tools.set("arrow",new pt(n)),this.tools.set("text",new $t(n)),this.tools.set("pen",new at(n,"pen")),this.tools.set("highlighter",new at(n,"highlighter")),this.tools.set("eraser",new Et(n)),this.tools.set("mind-map",new V(n,"mind-map")),this.setupEventListeners(),e.shapes?this.shapes=e.shapes.map(r=>({...r,style:{...r.style}})):this.persist&&this.loadFromStorage(),this.render();}setupEventListeners(){this.canvas.addEventListener("pointerdown",this.handlePointerDown),this.canvas.addEventListener("pointermove",this.handlePointerMove),this.canvas.addEventListener("pointerup",this.handlePointerUp),this.canvas.addEventListener("pointerleave",this.handlePointerUp),this.canvas.addEventListener("wheel",this.handleWheel,{passive:false}),window.addEventListener("keydown",this.handleKeyDown),window.addEventListener("keyup",this.handleKeyUp),window.addEventListener("resize",this.handleResize);}handlePointerDown=t=>{if(this.editingShapeId)return this.textInput&&t.target===this.textInput,void 0;if(this.pointerIsDown=true,t.button===1||t.button===0&&t.altKey){this.isPanning=true,this.panStart={x:t.clientX,y:t.clientY},this.canvas.setPointerCapture(t.pointerId),this.canvas.style.cursor="grabbing";return}let e=this.screenToPage({x:t.clientX,y:t.clientY}),i=this.activeTool==="select"?this.getMindMapCollapseHitAtPoint(e):null;if(i){this.toggleMindMapCollapse(i.shapeId,i.nodeId);return}if(this.activeTool==="select"){let r=Date.now(),s=this.getShapeAtPoint(e);if(r-this.lastClickTime<400&&this.lastClickShapeId&&s&&s.id===this.lastClickShapeId&&this.canEditShape(s)){this.enterEditing(s.id),this.lastClickTime=0,this.lastClickShapeId=null;return}if(this.lastClickTime=r,this.lastClickShapeId=s?.id||null,s&&s.type==="mind-map"&&this.mindMapEditingShapeId===s.id){let o=this.getMindMapNodeAtPoint(e);o&&(this.mindMapSelectedNode=o,this.notifyListeners(),this.render());return}s&&(this.dragStartPositions.clear(),this.selectedIds.forEach(o=>{let h=this.shapes.find(l=>l.id===o);h&&this.dragStartPositions.set(o,{x:h.x,y:h.y});}));}this.tools.get(this.activeTool)?.onPointerDown(e,t),this.updateCursor(e),this.render();};handlePointerMove=t=>{if(this.editingShapeId)return;if(this.isPanning){let n=t.clientX-this.panStart.x,r=t.clientY-this.panStart.y;this.camera.translate(n,r),this.panStart={x:t.clientX,y:t.clientY},this.scheduleRender(),this.notifyListeners();return}let e=this.screenToPage({x:t.clientX,y:t.clientY});this.tools.get(this.activeTool)?.onPointerMove(e,t),this.updateCursor(e),this.scheduleRender();};handlePointerUp=t=>{if(this.pointerIsDown=false,t.type==="pointerleave"&&(this.mindMapHoverNode=null),this.editingShapeId)return;if(this.isPanning){this.isPanning=false,this.updateCursor(this.screenToPage({x:t.clientX,y:t.clientY}));return}let e=this.screenToPage({x:t.clientX,y:t.clientY});this.tools.get(this.activeTool)?.onPointerUp(e,t),this.updateCursor(e),this.scheduleRender();};updateCursor(t){let i=this.tools.get(this.activeTool)?.getCursor(t)??"default";if(this.canvas.style.cursor!==i&&(this.canvas.style.cursor=i),!this.pointerIsDown){let n=this.getMindMapCursorHitAtPoint(t);(n?.shapeId!==this.mindMapHoverNode?.shapeId||n?.nodeId!==this.mindMapHoverNode?.nodeId)&&(this.mindMapHoverNode=n,this.scheduleRender());}}handleWheel=t=>{if(t.preventDefault(),t.ctrlKey||t.metaKey){let n=t.deltaY>0?.9:1.1;this.camera.zoomAt({x:t.clientX,y:t.clientY},n),this.scheduleRender(),this.notifyListeners();return}let e=t.deltaX||0,i=t.deltaY||0;t.deltaMode===1?(e*=40,i*=40):t.deltaMode===2&&(e*=120,i*=120),t.shiftKey&&(e=e||i,i=0),this.camera.translate(-e,-i),this.scheduleRender(),this.notifyListeners();};handleKeyDown=t=>{if(this.editingShapeId)return;if((t.ctrlKey||t.metaKey)&&t.key.toLowerCase()==="z"){t.preventDefault(),t.shiftKey?this.redo():this.undo();return}if((t.ctrlKey||t.metaKey)&&t.key.toLowerCase()==="y"){t.preventDefault(),this.redo();return}if((t.ctrlKey||t.metaKey)&&t.key.toLowerCase()==="s"){t.preventDefault(),this.saveToStorage();return}if(!t.ctrlKey&&!t.metaKey&&!t.altKey){if(t.key==="v"||t.key==="V"){this.setActiveTool("select"),t.preventDefault();return}if(t.key==="h"||t.key==="H"){this.setActiveTool("hand"),t.preventDefault();return}}this.tools.get(this.activeTool)?.onKeyDown(t),this.scheduleRender();};handleKeyUp=t=>{if(this.editingShapeId)return;this.tools.get(this.activeTool)?.onKeyUp(t),this.scheduleRender();};handleResize=()=>{this.renderer.resize(window.innerWidth,window.innerHeight),this.scheduleRender();};screenToPage(t){let e=this.canvas.getBoundingClientRect();return this.camera.screenToPage({x:t.x-e.left,y:t.y-e.top})}addShape(t){this.shapes.push(t),this.notifyListeners();}updateShape(t,e){let i=this.shapes.findIndex(n=>n.id===t);i!==-1&&(this.shapes[i]={...this.shapes[i],...e},(e.x!==void 0||e.y!==void 0)&&this.updateBoundArrows(t),this.notifyListeners());}updateBoundArrows(t){let e=this.shapes.find(i=>i.id===t);e&&this.shapes.forEach(i=>{if(i.type==="arrow"){let n=i,r={};if(n.startBinding?.toShapeId===t){let s=this.getBindingPosition(e,n.startBinding.handle||"top");r.points=n.points.map((o,h)=>h===0?s:o);}if(n.endBinding?.toShapeId===t){let s=this.getBindingPosition(e,n.endBinding.handle||"top"),o=r.points||[...n.points];r.points=o.map((h,l)=>l===o.length-1?s:h);}r.points&&(this.shapes[this.shapes.indexOf(i)]={...n,...r});}});}getBindingPosition(t,e){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":switch(e){case "top":return {x:t.x,y:t.y-t.height/2};case "bottom":return {x:t.x,y:t.y+t.height/2};case "left":return {x:t.x-t.width/2,y:t.y};case "right":return {x:t.x+t.width/2,y:t.y}}case "circle":switch(e){case "top":return {x:t.x,y:t.y-t.radius};case "bottom":return {x:t.x,y:t.y+t.radius};case "left":return {x:t.x-t.radius,y:t.y};case "right":return {x:t.x+t.radius,y:t.y}}case "hexagon":switch(e){case "top":return {x:t.x,y:t.y-t.height/2};case "bottom":return {x:t.x,y:t.y+t.height/2};case "left":return {x:t.x-t.width/2,y:t.y};case "right":return {x:t.x+t.width/2,y:t.y}}default:return {x:t.x,y:t.y}}}deleteShape(t){this.shapes=this.shapes.filter(e=>e.id!==t),this.selectedIds=this.selectedIds.filter(e=>e!==t),this.shapes=this.shapes.map(e=>{if(e.type==="arrow"){let i=e;if(i.startBinding?.toShapeId===t)return {...i,startBinding:void 0};if(i.endBinding?.toShapeId===t)return {...i,endBinding:void 0}}return e}),this.notifyListeners(),this.scheduleRender();}selectShape(t,e){if(!t)this.selectedIds=[];else if(e){let i=this.selectedIds.indexOf(t);i===-1?this.selectedIds.push(t):this.selectedIds.splice(i,1);}else this.selectedIds=[t];this.notifyListeners(),this.scheduleRender();}selectShapes(t){this.selectedIds=[...t],this.notifyListeners(),this.scheduleRender();}setBrushRect(t){this.brushRect=t,this.scheduleRender();}setSnapGuides(t){this.snapGuides=t;}setConnectingTarget(t){this.connectingTargetId!==t&&(this.connectingTargetId=t,this.scheduleRender());}setGenerationPreview(t){this.genPreview?.from.x===t?.from.x&&this.genPreview?.from.y===t?.from.y&&this.genPreview?.to.x===t?.to.x&&this.genPreview?.to.y===t?.to.y&&this.genPreview?.type===t?.type||(this.genPreview=t,this.scheduleRender());}openGenerationMenu(t){let e=this.camera.getZoom(),i=(t.context.to.x+this.camera.x)*e,n=(t.context.to.y+this.camera.y)*e;this.emitUi({kind:"shapeTypeMenu",screenX:i,screenY:n,context:t.context,existingArrowId:t.existingArrowId,defaultShapeType:t.defaultShapeType});}lineStyle(){return {strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:2,strokeDash:null}}computeSourceBinding(t){if(!t.sourceShapeId||!t.edge)return;let e=this.shapes.find(n=>n.id===t.sourceShapeId);if(!e)return;let i={n:"top",e:"right",s:"bottom",w:"left"};return {toShapeId:e.id,handle:i[t.edge]}}connectHandle(t,e){let i=e.x-t.x,n=e.y-t.y;return Math.abs(i)>=Math.abs(n)?i>=0?"left":"right":n>=0?"top":"bottom"}createFloatingLine(t){this.commitHistory();let e=t.from,i=t.to,n=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,r={id:n,type:"arrow",x:e.x,y:e.y,points:[{x:e.x,y:e.y},{x:i.x,y:i.y}],rotation:0,style:this.lineStyle(),startBinding:this.computeSourceBinding(t),connectionType:"polyline",arrowHead:"end",dashed:false};return this.addShape(r),this.selectedIds=[n],this.notifyListeners(),this.render(),n}createGeneratedConnection(t,e){this.commitHistory();let i=e.type,n;if(t.sourceShapeId){let h=this.shapes.find(l=>l.id===t.sourceShapeId);h&&It(h.type)&&(n={...h.style});}let r=kt(i,t.to,n);this.addShape(r);let s=t.from,o={toShapeId:r.id,handle:this.connectHandle(s,t.to)};if(e.existingArrowId)this.updateArrowBinding(e.existingArrowId,"end",r.id,{toShapeId:r.id,handle:this.connectHandle(s,t.to)});else {let l={id:`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,type:"arrow",x:s.x,y:s.y,points:[{x:s.x,y:s.y},{x:t.to.x,y:t.to.y}],rotation:0,style:this.lineStyle(),startBinding:this.computeSourceBinding(t),endBinding:o,connectionType:"polyline",arrowHead:"end",dashed:false};this.addShape(l);}this.selectedIds=[r.id],this.notifyListeners(),this.render();}connectToExisting(t,e,i){this.commitHistory();let n=this.shapes.find(d=>d.id===e);if(!n)return;let r=t.from,s=i?.handle??this.connectHandle(r,{x:n.x,y:n.y}),o=this.getBindingPosition(n,s),h=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,l={id:h,type:"arrow",x:r.x,y:r.y,points:[{x:r.x,y:r.y},{x:o.x,y:o.y}],rotation:0,style:this.lineStyle(),startBinding:this.computeSourceBinding(t),endBinding:{toShapeId:e,handle:s},connectionType:"polyline",arrowHead:"end",dashed:false};this.addShape(l),this.selectedIds=[h],this.notifyListeners(),this.render();}subscribeUi(t){return this.uiListeners.add(t),()=>this.uiListeners.delete(t)}emitUi(t){this.uiListeners.forEach(e=>e(t));}updateSelectedShapesStyle(t){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(e=>{let i=this.shapes.findIndex(n=>n.id===e);i!==-1&&(this.shapes[i]={...this.shapes[i],style:{...this.shapes[i].style,...t}});}),this.notifyListeners(),this.render());}updateSelectedShapesText(t){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(e=>{let i=this.shapes.findIndex(n=>n.id===e);i!==-1&&(this.shapes[i]={...this.shapes[i],...t});}),this.notifyListeners(),this.render());}updateConnectionType(t){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(e=>{let i=this.shapes.findIndex(n=>n.id===e);if(i!==-1){let n=this.shapes[i];(n.type==="line"||n.type==="arrow")&&(this.shapes[i]={...n,connectionType:t});}}),this.notifyListeners(),this.render());}updateArrowHeadType(t){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(e=>{let i=this.shapes.findIndex(n=>n.id===e);if(i!==-1){let n=this.shapes[i];n.type==="arrow"&&(this.shapes[i]={...n,arrowHead:t});}}),this.notifyListeners(),this.render());}updateArrowDashed(t){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(e=>{let i=this.shapes.findIndex(n=>n.id===e);if(i!==-1){let n=this.shapes[i];n.type==="arrow"&&(this.shapes[i]={...n,dashed:t});}}),this.notifyListeners(),this.render());}updateUmlClass(t,e){let i=this.shapes.findIndex(d=>d.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="uml-class")return;this.commitHistory();let r=e.className??n.className,s=e.attributes??n.attributes,o=e.methods??n.methods,{width:h,height:l}=Ct(r,s,o);this.shapes[i]={...n,className:r,attributes:s,methods:o,width:h,height:l},this.notifyListeners(),this.render();}updateUmlInterface(t,e){let i=this.shapes.findIndex(p=>p.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="uml-interface")return;this.commitHistory();let r=n,s=e.className??r.className,o=e.methods??r.methods,h=_*.6,l=o.map(p=>`${p.visibility} ${p.name}(${p.params}): ${p.returnType}`),d=Math.max(s.length,...l.map(p=>p.length),0),u=Math.max(dt,d*h+B*2),c=o.length>0?o.length*L+D*2:D*2,g=K+c;this.shapes[i]={...n,className:s,methods:o,width:u,height:g},this.notifyListeners(),this.render();}getSelectedUml(){if(this.selectedIds.length!==1)return null;let t=this.shapes.find(e=>e.id===this.selectedIds[0]);return t&&(t.type==="uml-class"||t.type==="uml-interface")?t:null}getUmlById(t){let e=this.shapes.find(i=>i.id===t);return e&&(e.type==="uml-class"||e.type==="uml-interface")?e:null}getSelectedMindMap(){if(this.selectedIds.length!==1)return null;let t=this.shapes.find(e=>e.id===this.selectedIds[0]);return t&&t.type==="mind-map"?t:null}getMindMapNodeAtPoint(t){for(let e=this.shapes.length-1;e>=0;e--){let i=this.shapes[e];if(i.type!=="mind-map")continue;let n=i,r=t.x-n.x,s=t.y-n.y,o=Math.cos(n.rotation),h=Math.sin(n.rotation),l=r*o+s*h,d=-r*h+s*o;if(Math.abs(l)>n.width/2||Math.abs(d)>n.height/2)continue;let u=k(n.root);for(let[c,g]of u.positions)if(Math.abs(l-g.x)<=g.width/2&&Math.abs(d-g.y)<=g.height/2)return {shapeId:n.id,nodeId:c};return {shapeId:n.id,nodeId:n.root.id}}return null}getMindMapNodeAtScreenPoint(t){return this.getMindMapNodeAtPoint(this.screenToPage(t))}getMindMapCursorHitAtPoint(t){let e=this.getMindMapCollapseHitAtPoint(t);if(e)return e;for(let i=this.shapes.length-1;i>=0;i--){let n=this.shapes[i];if(n.type!=="mind-map")continue;let r=n,s=t.x-r.x,o=t.y-r.y,h=Math.cos(r.rotation),l=Math.sin(r.rotation),d=s*h+o*l,u=-s*l+o*h,c=k(r.root);for(let[g,p]of c.positions)if(Math.abs(d-p.x)<=p.width/2&&Math.abs(u-p.y)<=p.height/2)return {shapeId:r.id,nodeId:g}}return null}selectMindMapNode(t,e){let i=this.shapes.find(n=>n.id===t);!i||i.type!=="mind-map"||(this.selectedIds=[t],this.mindMapSelectedNode={shapeId:t,nodeId:e},this.notifyListeners(),this.render());}getMindMapEditingShapeId(){return this.mindMapEditingShapeId}getMindMapSelectedNode(){return this.mindMapSelectedNode}getMindMapNode(t,e){let i=this.shapes.find(n=>n.id===t);return !i||i.type!=="mind-map"?null:q(i.root,e)}getMindMapNodeScreenRect(t,e){let i=this.shapes.find(M=>M.id===t);if(!i||i.type!=="mind-map")return null;let n=i,s=k(n.root).positions.get(e);if(!s)return null;let o=this.camera.getZoom(),h=s.x,l=s.y,d=Math.cos(n.rotation),u=Math.sin(n.rotation),c=h*d-l*u,g=h*u+l*d,p=this.camera.pageToScreen({x:n.x,y:n.y}),y=p.x+c*o,f=p.y+g*o;return {x:y-s.width*o/2,y:f-s.height*o/2,width:s.width*o,height:s.height*o}}getMindMapCollapseHitAtPoint(t){for(let e of this.shapes){if(e.type!=="mind-map")continue;let i=e,n=k(i.root),r=t.x-i.x,s=t.y-i.y,o=Math.cos(i.rotation),h=Math.sin(i.rotation),l=r*o+s*h,d=-r*h+s*o;for(let[u,c]of n.positions){let g=q(i.root,u);if(!g||!g.children||g.children.length===0)continue;let p=c.x+c.width/2+10,y=c.y,f=l-p,M=d-y;if(f*f+M*M<=121)return {shapeId:e.id,nodeId:u}}}return null}beginMindMapEdit(t,e){let i=this.shapes.find(r=>r.id===t);if(!i||i.type!=="mind-map")return;let n=i;this.mindMapEditingShapeId=t,this.mindMapSelectedNode={shapeId:t,nodeId:e&&q(n.root,e)?e:n.root.id},this.selectedIds=[t],this.notifyListeners(),this.render();}exitMindMapEdit(){this.mindMapEditingShapeId=null,this.mindMapSelectedNode=null,this.notifyListeners(),this.render();}updateMindMapNode(t,e,i,n=true){let r=this.shapes.findIndex(g=>g.id===t);if(r===-1)return;let s=this.shapes[r];if(s.type!=="mind-map")return;let o=s,h=q(o.root,e);if(!h||!Object.keys(i).some(g=>h[g]!==i[g]))return;n&&this.commitHistory();let d=Tt(o.root,e,i),{width:u,height:c}=k(d);this.shapes[r]={...o,root:d,width:u,height:c},this.notifyListeners(),this.render();}addMindMapChild(t,e){let i=this.shapes.findIndex(d=>d.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="mind-map")return;let r=n,s={id:`mm_${Date.now()}_${Math.random().toString(36).substr(2,6)}`,text:W("mindmap.defaultBranch")},o=Rt(r.root,e,s);this.commitHistory();let{width:h,height:l}=k(o);this.shapes[i]={...r,root:o,width:h,height:l},this.mindMapSelectedNode={shapeId:t,nodeId:s.id},this.notifyListeners(),this.render();}addMindMapSibling(t,e){let i=this.shapes.findIndex(d=>d.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="mind-map")return;let r=n;if(!lt(r.root,e))return;let s={id:`mm_${Date.now()}_${Math.random().toString(36).substr(2,6)}`,text:W("mindmap.defaultBranch")},o=Vt(r.root,e,s);this.commitHistory();let{width:h,height:l}=k(o);this.shapes[i]={...r,root:o,width:h,height:l},this.mindMapSelectedNode={shapeId:t,nodeId:s.id},this.notifyListeners(),this.render();}deleteMindMapNode(t,e){let i=this.shapes.findIndex(d=>d.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="mind-map")return;let r=n;if(r.root.id===e){this.commitHistory(),this.shapes=this.shapes.filter(d=>d.id!==t),this.selectedIds=this.selectedIds.filter(d=>d!==t),this.mindMapEditingShapeId=null,this.mindMapSelectedNode=null,this.notifyListeners(),this.render();return}let s=Ht(r.root,e);if(!s)return;this.commitHistory();let{width:o,height:h}=k(s);this.shapes[i]={...r,root:s,width:o,height:h};let l=lt(r.root,e);this.mindMapSelectedNode=l?{shapeId:t,nodeId:l.id}:{shapeId:t,nodeId:s.id},this.notifyListeners(),this.render();}toggleMindMapCollapse(t,e){let i=this.shapes.findIndex(d=>d.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="mind-map")return;let r=n,s=q(r.root,e);if(!s||!s.children||s.children.length===0)return;this.commitHistory();let o=Tt(r.root,e,{collapsed:!s.collapsed}),{width:h,height:l}=k(o);this.shapes[i]={...r,root:o,width:h,height:l},this.notifyListeners(),this.render();}addUmlAttribute(t){let e=this.shapes.find(n=>n.id===t);if(!e||e.type!=="uml-class")return;let i={id:`attr_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,visibility:"+",name:"newField",type:"string"};this.updateUmlClass(t,{attributes:[...e.attributes,i]});}addUmlMethod(t){let e=this.getUmlById(t);if(!e)return;let i={id:`meth_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,visibility:"+",name:"newMethod",params:"",returnType:"void"};e.type==="uml-class"?this.updateUmlClass(t,{methods:[...e.methods,i]}):this.updateUmlInterface(t,{methods:[...e.methods,i]});}removeUmlAttribute(t,e){let i=this.shapes.find(n=>n.id===t);!i||i.type!=="uml-class"||this.updateUmlClass(t,{attributes:i.attributes.filter(n=>n.id!==e)});}removeUmlMethod(t,e){let i=this.getUmlById(t);if(!i)return;let n=i.methods.filter(r=>r.id!==e);i.type==="uml-class"?this.updateUmlClass(t,{methods:n}):this.updateUmlInterface(t,{methods:n});}reorderUmlAttribute(t,e,i){let n=this.shapes.find(o=>o.id===t);if(!n||n.type!=="uml-class"||e===i)return;let r=[...n.attributes];if(e<0||e>=r.length||i<0||i>=r.length)return;let[s]=r.splice(e,1);r.splice(i,0,s),this.updateUmlClass(t,{attributes:r});}reorderUmlMethod(t,e,i){let n=this.getUmlById(t);if(!n||e===i)return;let r=[...n.methods];if(e<0||e>=r.length||i<0||i>=r.length)return;let[s]=r.splice(e,1);r.splice(i,0,s),n.type==="uml-class"?this.updateUmlClass(t,{methods:r}):this.updateUmlInterface(t,{methods:r});}updateUmlRowStyle(t,e,i,n){let r=this.getUmlById(t);if(r)if(e==="attribute"){if(r.type!=="uml-class")return;let s=r.attributes.map(o=>o.id===i?{...o,textColor:n.textColor===null?void 0:n.textColor??o.textColor,fontSize:n.fontSize===null?void 0:n.fontSize??o.fontSize,strikethrough:n.strikethrough===null?void 0:n.strikethrough??o.strikethrough}:o);this.updateUmlClass(t,{attributes:s});}else {let s=r.methods.map(o=>o.id===i?{...o,textColor:n.textColor===null?void 0:n.textColor??o.textColor,fontSize:n.fontSize===null?void 0:n.fontSize??o.fontSize,strikethrough:n.strikethrough===null?void 0:n.strikethrough??o.strikethrough}:o);r.type==="uml-class"?this.updateUmlClass(t,{methods:s}):this.updateUmlInterface(t,{methods:s});}}getUmlRowAtScreenPoint(t){let e=this.camera.screenToPage(t);for(let i=this.shapes.length-1;i>=0;i--){let n=this.shapes[i];if(n.type!=="uml-class"&&n.type!=="uml-interface")continue;let r=n.width/2,s=n.height/2;if(e.x<n.x-r||e.x>n.x+r||e.y<n.y-s||e.y>n.y+s)continue;let o=K,h=e.y-n.y;if(h>=-s&&h<=-s+o)return {shape:n,section:"className",rowIndex:-1,text:n.className};if(n.type==="uml-interface"){let p=-s+o,y=s;if(n.methods.length>0&&h>=p&&h<=y){let f=Math.floor((h-p-D)/L);if(f>=0&&f<n.methods.length){let M=n.methods[f];return {shape:n,section:"method",rowIndex:f,text:`${M.visibility} ${M.name}(${M.params}): ${M.returnType}`}}return {shape:n,section:"method",rowIndex:-1,text:""}}return {shape:n,section:"className",rowIndex:-1,text:n.className}}let l=n.attributes.length>0?n.attributes.length*L+D*2:D*2,d=-s+o,u=d+l;if(n.attributes.length>0&&h>=d&&h<=u){let p=Math.floor((h-d-D)/L);if(p>=0&&p<n.attributes.length){let y=n.attributes[p];return {shape:n,section:"attribute",rowIndex:p,text:`${y.visibility} ${y.name}: ${y.type}`}}return {shape:n,section:"attribute",rowIndex:-1,text:""}}let c=u,g=s;if(n.methods.length>0&&h>=c&&h<=g){let p=Math.floor((h-c-D)/L);if(p>=0&&p<n.methods.length){let y=n.methods[p];return {shape:n,section:"method",rowIndex:p,text:`${y.visibility} ${y.name}(${y.params}): ${y.returnType}`}}return {shape:n,section:"method",rowIndex:-1,text:""}}return {shape:n,section:"className",rowIndex:-1,text:n.className}}return null}setActiveTool(t){this.tools.has(t)&&(this.activeTool=t,this.eraserPoint=null,this.notifyListeners());}getActiveTool(){return this.activeTool}getShapes(){return [...this.shapes]}getData(){return {shapes:this.getShapes(),camera:{x:this.camera.x,y:this.camera.y,zoom:this.camera.zoom}}}setShapes(t){return Array.isArray(t)?(this.shapes=t.map(e=>({...e,style:{...e.style}})),this.selectedIds=[],this.undoStack=[],this.redoStack=[],this.notifyListeners(),this.render(),true):false}setTheme(t){bt(t),this.scheduleRender();}setLanguage(t){vt(t);}getSelectedIds(){return [...this.selectedIds]}getCamera(){return this.camera}isPointerDown(){return this.pointerIsDown}getContentBounds(t=24){return xt(this.shapes,t)}async exportImage(t,e={}){return zt(this.getShapes(),t,e)}async downloadImage(t="drawui",e="png",i={}){let n=await this.exportImage(e,i);Ot(n,`${t}.${e}`);}zoomIn(){this.camera.zoomAt({x:window.innerWidth/2,y:window.innerHeight/2},1.2),this.scheduleRender(),this.notifyListeners();}zoomOut(){this.camera.zoomAt({x:window.innerWidth/2,y:window.innerHeight/2},.8),this.scheduleRender(),this.notifyListeners();}resetZoom(){this.camera.reset(),this.scheduleRender(),this.notifyListeners();}panBy(t,e){this.camera.translate(t,e),this.scheduleRender(),this.notifyListeners();}setCameraPosition(t,e){this.camera.x=t,this.camera.y=e,this.scheduleRender(),this.notifyListeners();}requestRender(){this.scheduleRender(),this.notifyListeners();}setShowGrid(t){this.renderer.setShowGrid(t),this.scheduleRender();}render(){this.renderer.render(this.shapes,this.camera,new Set(this.selectedIds),this.brushRect,this.snapGuides,this.connectingTargetId,this.genPreview,this.eraserPoint,this.mindMapSelectedNode,this.mindMapHoverNode);}scheduleRender(){this.renderScheduled||(this.renderScheduled=true,requestAnimationFrame(()=>{this.renderScheduled=false,this.render();}));}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}subscribeNotifications(t){return this.notificationListeners.add(t),()=>this.notificationListeners.delete(t)}notify(t){this.notificationListeners.forEach(e=>e(t));}notifyListeners(){this.notifyScheduled||(this.notifyScheduled=true,queueMicrotask(()=>{this.notifyScheduled=false,this.mindMapEditingShapeId&&!this.selectedIds.includes(this.mindMapEditingShapeId)&&(this.mindMapEditingShapeId=null,this.mindMapSelectedNode=null),this.listeners.forEach(t=>t());}));}cloneShapes(t){return t.map(e=>{let i={...e,style:{...e.style}};return Array.isArray(e.points)&&(i.points=e.points.map(n=>({...n}))),e.startBinding&&(i.startBinding={...e.startBinding}),e.endBinding&&(i.endBinding={...e.endBinding}),e.root&&(i.root=Pt(e.root)),i})}commitHistory(){if(this.isUndoing)return;let t={shapes:this.cloneShapes(this.shapes),selectedIds:[...this.selectedIds]};this.undoStack.push(t),this.undoStack.length>Ge&&this.undoStack.shift(),this.redoStack=[];}mark(){this.commitHistory();}undo(){if(this.undoStack.length!==0){this.isUndoing=true;try{this.redoStack.push({shapes:this.cloneShapes(this.shapes),selectedIds:[...this.selectedIds]});let t=this.undoStack.pop();this.shapes=this.cloneShapes(t.shapes),this.selectedIds=[...t.selectedIds];}finally{this.isUndoing=false;}this.notifyListeners(),this.render();}}redo(){if(this.redoStack.length!==0){this.isUndoing=true;try{this.undoStack.push({shapes:this.cloneShapes(this.shapes),selectedIds:[...this.selectedIds]});let t=this.redoStack.pop();this.shapes=this.cloneShapes(t.shapes),this.selectedIds=[...t.selectedIds];}finally{this.isUndoing=false;}this.notifyListeners(),this.render();}}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}saveToStorage(){if(!this.persist)return false;try{let t=JSON.stringify({version:1,shapes:this.shapes,savedAt:Date.now()});return localStorage.setItem(Xt,t),this.notifyListeners(),this.notify(W("save.success")),!0}catch(t){return console.error("\u4FDD\u5B58\u5931\u8D25:",t),this.notify(W("save.fail")),false}}loadFromStorage(){if(!this.persist)return false;try{let t=localStorage.getItem(Xt);if(!t)return !1;let e=JSON.parse(t);return e.shapes&&Array.isArray(e.shapes)?(this.shapes=e.shapes,this.selectedIds=[],this.undoStack=[],this.redoStack=[],this.notifyListeners(),this.scheduleRender(),!0):!1}catch(t){return console.error("\u52A0\u8F7D\u5931\u8D25:",t),false}}clearStorage(){localStorage.removeItem(Xt);}exportJSON(){return JSON.stringify({version:1,shapes:this.shapes,savedAt:Date.now()},null,2)}importJSON(t){try{let e=JSON.parse(t);return e.shapes&&Array.isArray(e.shapes)?(this.commitHistory(),this.shapes=e.shapes,this.selectedIds=[],this.notifyListeners(),this.render(),!0):!1}catch(e){return console.error("\u5BFC\u5165\u5931\u8D25:",e),false}}getEditingShapeId(){return this.editingShapeId}canEditShape(t){return !(t.type==="line"||t.type==="arrow"||t.type==="draw"||t.type==="uml-class"||t.type==="uml-interface"||t.type==="mind-map")}enterEditing(t){let e=this.shapes.find(i=>i.id===t);!e||!this.canEditShape(e)||(this.editingShapeId=t,this.selectedIds=[t],this.isNewTextShape=e.type==="text"&&!e.text,this.originalTextValue=e.text||"",this.notifyListeners(),this.scheduleRender(),requestAnimationFrame(()=>{this.createTextInput(e);}));}exitEditing(){if(!this.editingShapeId)return;let t=this.editingShapeId,e=this.shapes.find(n=>n.id===t),i=this.textInput?this.textInput.value:"";if(this.removeTextInput(),e)if(e.type==="text")if(this.commitHistory(),!i.trim()&&this.isNewTextShape)this.shapes=this.shapes.filter(n=>n.id!==t),this.selectedIds=this.selectedIds.filter(n=>n!==t);else {let n=e,r=n.fontSize||16,s=r*1.3,o=n.width||200,h=i.split(`
|
|
42
|
-
`),l=0;for(let c of h){let g="";for(let p of c){let y=g+p;y.length*
|
|
43
|
-
`+d.value.substring(g),d.selectionStart=d.selectionEnd=c+1;}}),e.appendChild(d),d.focus(),t.type==="text"&&!t.text&&(d.placeholder="\u8F93\u5165\u6587\u672C..."),this.textInput=d;}getShapeScreenBounds(t){let e=this.camera.getZoom(),i=this.camera.pageToScreen({x:t.x,y:t.y});switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":return {x:i.x-t.width*e/2,y:i.y-t.height*e/2,width:t.width*e,height:t.height*e};case "circle":return {x:i.x-t.radius*e,y:i.y-t.radius*e,width:t.radius*2*e,height:t.radius*2*e};case "text":{let n=t,
|
|
40
|
+
${M+y.length}
|
|
41
|
+
%%EOF`;return new Blob([m+d+u+c+g,s,p+y+T],{type:"application/pdf"})}async function Gt(a,t,e={}){if(t==="svg"){let s=ae(a,e);return new Blob([s],{type:"image/svg+xml;charset=utf-8"})}let i=re(a,e);if(t==="png")return Ce(i,"image/png");let n=Ee(i,"image/jpeg",.92);return Ue(n,i.width,i.height)}function zt(a,t){let e=URL.createObjectURL(a),i=document.createElement("a");i.href=e,i.download=t,document.body.appendChild(i),i.click(),document.body.removeChild(i),setTimeout(()=>URL.revokeObjectURL(e),1e3);}var Xt="drawui-canvas-data",Oe=50,Yt=class{canvas;renderer;camera;tools=new Map;activeTool="select";shapes=[];selectedIds=[];listeners=new Set;notificationListeners=new Set;uiListeners=new Set;isPanning=false;panStart={x:0,y:0};dragStartPositions=new Map;lastClickTime=0;lastClickShapeId=null;editingShapeId=null;textInput=null;textOverlay=null;isNewTextShape=false;originalTextValue="";undoStack=[];redoStack=[];isUndoing=false;brushRect=null;snapGuides=[];connectingTargetId=null;genPreview=null;eraserPoint=null;mindMapEditingShapeId=null;mindMapSelectedNode=null;mindMapHoverNode=null;renderScheduled=false;pointerIsDown=false;notifyScheduled=false;persist=true;constructor(t,e={}){this.canvas=t,this.persist=e.persist??!e.shapes,e.theme&&bt(e.theme),e.language&&vt(e.language);let i=t.getBoundingClientRect();this.renderer=new st(t),this.renderer.resize(i.width,i.height),this.camera=new nt;let n={addShape:s=>this.addShape(s),updateShape:(s,r)=>this.updateShape(s,r),deleteShape:s=>this.deleteShape(s),selectShape:(s,r)=>this.selectShape(s,r),selectShapes:s=>this.selectShapes(s),getShapes:()=>[...this.shapes],getSelectedIds:()=>[...this.selectedIds],setActiveTool:s=>this.setActiveTool(s),screenToPage:s=>this.screenToPage(s),getCamera:()=>this.camera,panBy:(s,r)=>this.panBy(s,r),setCameraPosition:(s,r)=>this.setCameraPosition(s,r),getShapeAtPoint:(s,r)=>this.getShapeAtPoint(s,r),getShapesInBrushRadius:(s,r)=>this.getShapesInBrushRadius(s,r),setEraserPoint:s=>this.setEraserPoint(s),updateArrowBinding:(s,r,o,h)=>this.updateArrowBinding(s,r,o,h),enterEditing:s=>this.enterEditing(s),exitEditing:()=>this.exitEditing(),commitHistory:()=>this.commitHistory(),setBrushRect:s=>this.setBrushRect(s),setSnapGuides:s=>this.setSnapGuides(s),setConnectingTarget:s=>this.setConnectingTarget(s),setGenerationPreview:s=>this.setGenerationPreview(s),openGenerationMenu:s=>this.openGenerationMenu(s),createGeneratedConnection:(s,r)=>this.createGeneratedConnection(s,r),createFloatingLine:s=>this.createFloatingLine(s),connectToExisting:(s,r,o)=>this.connectToExisting(s,r,o),updateSelectedShapesStyle:s=>this.updateSelectedShapesStyle(s),updateSelectedShapesText:s=>this.updateSelectedShapesText(s),updateConnectionType:s=>this.updateConnectionType(s),getMindMapCursorHitAtPoint:s=>this.getMindMapCursorHitAtPoint(s),selectMindMapNode:(s,r)=>this.selectMindMapNode(s,r)};this.tools.set("select",new ct(n)),this.tools.set("hand",new ut(n)),this.tools.set("rectangle",new V(n,"rectangle")),this.tools.set("rounded-rectangle",new V(n,"rounded-rectangle")),this.tools.set("circle",new V(n,"circle")),this.tools.set("ellipse",new V(n,"ellipse")),this.tools.set("diamond",new V(n,"diamond")),this.tools.set("triangle",new V(n,"triangle")),this.tools.set("hexagon",new V(n,"hexagon")),this.tools.set("parallelogram",new V(n,"parallelogram")),this.tools.set("trapezoid",new V(n,"trapezoid")),this.tools.set("pentagon",new V(n,"pentagon")),this.tools.set("octagon",new V(n,"octagon")),this.tools.set("star",new V(n,"star")),this.tools.set("uml-class",new V(n,"uml-class")),this.tools.set("uml-interface",new V(n,"uml-interface")),this.tools.set("line",new gt(n)),this.tools.set("arrow",new pt(n)),this.tools.set("text",new $t(n)),this.tools.set("pen",new at(n,"pen")),this.tools.set("highlighter",new at(n,"highlighter")),this.tools.set("eraser",new Et(n)),this.tools.set("mind-map",new V(n,"mind-map")),this.setupEventListeners(),e.shapes?this.shapes=e.shapes.map(s=>({...s,style:{...s.style}})):this.persist&&this.loadFromStorage(),this.render();}setupEventListeners(){this.canvas.addEventListener("pointerdown",this.handlePointerDown),this.canvas.addEventListener("pointermove",this.handlePointerMove),this.canvas.addEventListener("pointerup",this.handlePointerUp),this.canvas.addEventListener("pointerleave",this.handlePointerUp),this.canvas.addEventListener("wheel",this.handleWheel,{passive:false}),window.addEventListener("keydown",this.handleKeyDown),window.addEventListener("keyup",this.handleKeyUp),window.addEventListener("resize",this.handleResize);}handlePointerDown=t=>{if(this.editingShapeId)return this.textInput&&t.target===this.textInput,void 0;if(this.pointerIsDown=true,t.button===1||t.button===0&&t.altKey){this.isPanning=true,this.panStart={x:t.clientX,y:t.clientY},this.canvas.setPointerCapture(t.pointerId),this.canvas.style.cursor="grabbing";return}let e=this.screenToPage({x:t.clientX,y:t.clientY}),i=this.activeTool==="select"?this.getMindMapCollapseHitAtPoint(e):null;if(i){this.toggleMindMapCollapse(i.shapeId,i.nodeId);return}if(this.activeTool==="select"){let s=Date.now(),r=this.getShapeAtPoint(e);if(s-this.lastClickTime<400&&this.lastClickShapeId&&r&&r.id===this.lastClickShapeId&&this.canEditShape(r)){this.enterEditing(r.id),this.lastClickTime=0,this.lastClickShapeId=null;return}if(this.lastClickTime=s,this.lastClickShapeId=r?.id||null,r&&r.type==="mind-map"&&this.mindMapEditingShapeId===r.id){let o=this.getMindMapNodeAtPoint(e);o&&(this.mindMapSelectedNode=o,this.notifyListeners(),this.render());return}r&&(this.dragStartPositions.clear(),this.selectedIds.forEach(o=>{let h=this.shapes.find(l=>l.id===o);h&&this.dragStartPositions.set(o,{x:h.x,y:h.y});}));}this.tools.get(this.activeTool)?.onPointerDown(e,t),this.updateCursor(e),this.render();};handlePointerMove=t=>{if(this.editingShapeId)return;if(this.isPanning){let n=t.clientX-this.panStart.x,s=t.clientY-this.panStart.y;this.camera.translate(n,s),this.panStart={x:t.clientX,y:t.clientY},this.scheduleRender(),this.notifyListeners();return}let e=this.screenToPage({x:t.clientX,y:t.clientY});this.tools.get(this.activeTool)?.onPointerMove(e,t),this.updateCursor(e),this.scheduleRender();};handlePointerUp=t=>{if(this.pointerIsDown=false,t.type==="pointerleave"&&(this.mindMapHoverNode=null),this.editingShapeId)return;if(this.isPanning){this.isPanning=false,this.updateCursor(this.screenToPage({x:t.clientX,y:t.clientY}));return}let e=this.screenToPage({x:t.clientX,y:t.clientY});this.tools.get(this.activeTool)?.onPointerUp(e,t),this.updateCursor(e),this.scheduleRender();};updateCursor(t){let i=this.tools.get(this.activeTool)?.getCursor(t)??"default";if(this.canvas.style.cursor!==i&&(this.canvas.style.cursor=i),!this.pointerIsDown){let n=this.getMindMapCursorHitAtPoint(t);(n?.shapeId!==this.mindMapHoverNode?.shapeId||n?.nodeId!==this.mindMapHoverNode?.nodeId)&&(this.mindMapHoverNode=n,this.scheduleRender());}}handleWheel=t=>{if(t.preventDefault(),t.ctrlKey||t.metaKey){let n=t.deltaY>0?.9:1.1;this.camera.zoomAt({x:t.clientX,y:t.clientY},n),this.scheduleRender(),this.notifyListeners();return}let e=t.deltaX||0,i=t.deltaY||0;t.deltaMode===1?(e*=40,i*=40):t.deltaMode===2&&(e*=120,i*=120),t.shiftKey&&(e=e||i,i=0),this.camera.translate(-e,-i),this.scheduleRender(),this.notifyListeners();};handleKeyDown=t=>{if(this.editingShapeId)return;if((t.ctrlKey||t.metaKey)&&t.key.toLowerCase()==="z"){t.preventDefault(),t.shiftKey?this.redo():this.undo();return}if((t.ctrlKey||t.metaKey)&&t.key.toLowerCase()==="y"){t.preventDefault(),this.redo();return}if((t.ctrlKey||t.metaKey)&&t.key.toLowerCase()==="s"){t.preventDefault(),this.saveToStorage();return}if(!t.ctrlKey&&!t.metaKey&&!t.altKey){if(t.key==="v"||t.key==="V"){this.setActiveTool("select"),t.preventDefault();return}if(t.key==="h"||t.key==="H"){this.setActiveTool("hand"),t.preventDefault();return}}this.tools.get(this.activeTool)?.onKeyDown(t),this.scheduleRender();};handleKeyUp=t=>{if(this.editingShapeId)return;this.tools.get(this.activeTool)?.onKeyUp(t),this.scheduleRender();};handleResize=()=>{this.renderer.resize(window.innerWidth,window.innerHeight),this.scheduleRender();};screenToPage(t){let e=this.canvas.getBoundingClientRect();return this.camera.screenToPage({x:t.x-e.left,y:t.y-e.top})}addShape(t){this.shapes.push(t),this.notifyListeners();}updateShape(t,e){let i=this.shapes.findIndex(n=>n.id===t);i!==-1&&(this.shapes[i]={...this.shapes[i],...e},(e.x!==void 0||e.y!==void 0)&&this.updateBoundArrows(t),this.notifyListeners());}updateBoundArrows(t){let e=this.shapes.find(i=>i.id===t);e&&this.shapes.forEach(i=>{if(i.type==="arrow"){let n=i,s={};if(n.startBinding?.toShapeId===t){let r=this.getBindingPosition(e,n.startBinding.handle||"top");s.points=n.points.map((o,h)=>h===0?r:o);}if(n.endBinding?.toShapeId===t){let r=this.getBindingPosition(e,n.endBinding.handle||"top"),o=s.points||[...n.points];s.points=o.map((h,l)=>l===o.length-1?r:h);}s.points&&(this.shapes[this.shapes.indexOf(i)]={...n,...s});}});}getBindingPosition(t,e){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":switch(e){case "top":return {x:t.x,y:t.y-t.height/2};case "bottom":return {x:t.x,y:t.y+t.height/2};case "left":return {x:t.x-t.width/2,y:t.y};case "right":return {x:t.x+t.width/2,y:t.y}}case "circle":switch(e){case "top":return {x:t.x,y:t.y-t.radius};case "bottom":return {x:t.x,y:t.y+t.radius};case "left":return {x:t.x-t.radius,y:t.y};case "right":return {x:t.x+t.radius,y:t.y}}case "hexagon":switch(e){case "top":return {x:t.x,y:t.y-t.height/2};case "bottom":return {x:t.x,y:t.y+t.height/2};case "left":return {x:t.x-t.width/2,y:t.y};case "right":return {x:t.x+t.width/2,y:t.y}}default:return {x:t.x,y:t.y}}}deleteShape(t){this.shapes=this.shapes.filter(e=>e.id!==t),this.selectedIds=this.selectedIds.filter(e=>e!==t),this.shapes=this.shapes.map(e=>{if(e.type==="arrow"){let i=e;if(i.startBinding?.toShapeId===t)return {...i,startBinding:void 0};if(i.endBinding?.toShapeId===t)return {...i,endBinding:void 0}}return e}),this.notifyListeners(),this.scheduleRender();}selectShape(t,e){if(!t)this.selectedIds=[];else if(e){let i=this.selectedIds.indexOf(t);i===-1?this.selectedIds.push(t):this.selectedIds.splice(i,1);}else this.selectedIds=[t];this.notifyListeners(),this.scheduleRender();}selectShapes(t){this.selectedIds=[...t],this.notifyListeners(),this.scheduleRender();}setBrushRect(t){this.brushRect=t,this.scheduleRender();}setSnapGuides(t){this.snapGuides=t;}setConnectingTarget(t){this.connectingTargetId!==t&&(this.connectingTargetId=t,this.scheduleRender());}setGenerationPreview(t){this.genPreview?.from.x===t?.from.x&&this.genPreview?.from.y===t?.from.y&&this.genPreview?.to.x===t?.to.x&&this.genPreview?.to.y===t?.to.y&&this.genPreview?.type===t?.type||(this.genPreview=t,this.scheduleRender());}openGenerationMenu(t){let e=this.camera.getZoom(),i=(t.context.to.x+this.camera.x)*e,n=(t.context.to.y+this.camera.y)*e;this.emitUi({kind:"shapeTypeMenu",screenX:i,screenY:n,context:t.context,existingArrowId:t.existingArrowId,defaultShapeType:t.defaultShapeType});}lineStyle(){return {strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:2,strokeDash:null}}computeSourceBinding(t){if(!t.sourceShapeId||!t.edge)return;let e=this.shapes.find(n=>n.id===t.sourceShapeId);if(!e)return;let i={n:"top",e:"right",s:"bottom",w:"left"};return {toShapeId:e.id,handle:i[t.edge]}}connectHandle(t,e){let i=e.x-t.x,n=e.y-t.y;return Math.abs(i)>=Math.abs(n)?i>=0?"left":"right":n>=0?"top":"bottom"}createFloatingLine(t){this.commitHistory();let e=t.from,i=t.to,n=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,s={id:n,type:"arrow",x:e.x,y:e.y,points:[{x:e.x,y:e.y},{x:i.x,y:i.y}],rotation:0,style:this.lineStyle(),startBinding:this.computeSourceBinding(t),connectionType:"polyline",arrowHead:"end",dashed:false};return this.addShape(s),this.selectedIds=[n],this.notifyListeners(),this.render(),n}createGeneratedConnection(t,e){this.commitHistory();let i=e.type,n;if(t.sourceShapeId){let h=this.shapes.find(l=>l.id===t.sourceShapeId);h&&It(h.type)&&(n={...h.style});}let s=Ht(i,t.to,n);this.addShape(s);let r=t.from,o={toShapeId:s.id,handle:this.connectHandle(r,t.to)};if(e.existingArrowId)this.updateArrowBinding(e.existingArrowId,"end",s.id,{toShapeId:s.id,handle:this.connectHandle(r,t.to)});else {let l={id:`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,type:"arrow",x:r.x,y:r.y,points:[{x:r.x,y:r.y},{x:t.to.x,y:t.to.y}],rotation:0,style:this.lineStyle(),startBinding:this.computeSourceBinding(t),endBinding:o,connectionType:"polyline",arrowHead:"end",dashed:false};this.addShape(l);}this.selectedIds=[s.id],this.notifyListeners(),this.render();}connectToExisting(t,e,i){this.commitHistory();let n=this.shapes.find(d=>d.id===e);if(!n)return;let s=t.from,r=i?.handle??this.connectHandle(s,{x:n.x,y:n.y}),o=this.getBindingPosition(n,r),h=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,l={id:h,type:"arrow",x:s.x,y:s.y,points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],rotation:0,style:this.lineStyle(),startBinding:this.computeSourceBinding(t),endBinding:{toShapeId:e,handle:r},connectionType:"polyline",arrowHead:"end",dashed:false};this.addShape(l),this.selectedIds=[h],this.notifyListeners(),this.render();}subscribeUi(t){return this.uiListeners.add(t),()=>this.uiListeners.delete(t)}emitUi(t){this.uiListeners.forEach(e=>e(t));}updateSelectedShapesStyle(t){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(e=>{let i=this.shapes.findIndex(n=>n.id===e);i!==-1&&(this.shapes[i]={...this.shapes[i],style:{...this.shapes[i].style,...t}});}),this.notifyListeners(),this.render());}updateSelectedShapesText(t){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(e=>{let i=this.shapes.findIndex(n=>n.id===e);i!==-1&&(this.shapes[i]={...this.shapes[i],...t});}),this.notifyListeners(),this.render());}updateConnectionType(t){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(e=>{let i=this.shapes.findIndex(n=>n.id===e);if(i!==-1){let n=this.shapes[i];(n.type==="line"||n.type==="arrow")&&(this.shapes[i]={...n,connectionType:t});}}),this.notifyListeners(),this.render());}updateArrowHeadType(t){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(e=>{let i=this.shapes.findIndex(n=>n.id===e);if(i!==-1){let n=this.shapes[i];n.type==="arrow"&&(this.shapes[i]={...n,arrowHead:t});}}),this.notifyListeners(),this.render());}updateArrowDashed(t){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(e=>{let i=this.shapes.findIndex(n=>n.id===e);if(i!==-1){let n=this.shapes[i];n.type==="arrow"&&(this.shapes[i]={...n,dashed:t});}}),this.notifyListeners(),this.render());}updateUmlClass(t,e){let i=this.shapes.findIndex(d=>d.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="uml-class")return;this.commitHistory();let s=e.className??n.className,r=e.attributes??n.attributes,o=e.methods??n.methods,{width:h,height:l}=Ct(s,r,o);this.shapes[i]={...n,className:s,attributes:r,methods:o,width:h,height:l},this.notifyListeners(),this.render();}updateUmlInterface(t,e){let i=this.shapes.findIndex(p=>p.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="uml-interface")return;this.commitHistory();let s=n,r=e.className??s.className,o=e.methods??s.methods,h=U*.6,l=o.map(p=>`${p.visibility} ${p.name}(${p.params}): ${p.returnType}`),d=Math.max(r.length,...l.map(p=>p.length),0),u=Math.max(dt,d*h+_*2),c=o.length>0?o.length*L+D*2:D*2,g=K+c;this.shapes[i]={...n,className:r,methods:o,width:u,height:g},this.notifyListeners(),this.render();}getSelectedUml(){if(this.selectedIds.length!==1)return null;let t=this.shapes.find(e=>e.id===this.selectedIds[0]);return t&&(t.type==="uml-class"||t.type==="uml-interface")?t:null}getUmlById(t){let e=this.shapes.find(i=>i.id===t);return e&&(e.type==="uml-class"||e.type==="uml-interface")?e:null}getSelectedMindMap(){if(this.selectedIds.length!==1)return null;let t=this.shapes.find(e=>e.id===this.selectedIds[0]);return t&&t.type==="mind-map"?t:null}getMindMapNodeAtPoint(t){for(let e=this.shapes.length-1;e>=0;e--){let i=this.shapes[e];if(i.type!=="mind-map")continue;let n=i,s=t.x-n.x,r=t.y-n.y,o=Math.cos(n.rotation),h=Math.sin(n.rotation),l=s*o+r*h,d=-s*h+r*o;if(Math.abs(l)>n.width/2||Math.abs(d)>n.height/2)continue;let u=B(n.root);for(let[c,g]of u.positions)if(Math.abs(l-g.x)<=g.width/2&&Math.abs(d-g.y)<=g.height/2)return {shapeId:n.id,nodeId:c};return {shapeId:n.id,nodeId:n.root.id}}return null}getMindMapNodeAtScreenPoint(t){return this.getMindMapNodeAtPoint(this.screenToPage(t))}getMindMapCursorHitAtPoint(t){let e=this.getMindMapCollapseHitAtPoint(t);if(e)return e;for(let i=this.shapes.length-1;i>=0;i--){let n=this.shapes[i];if(n.type!=="mind-map")continue;let s=n,r=t.x-s.x,o=t.y-s.y,h=Math.cos(s.rotation),l=Math.sin(s.rotation),d=r*h+o*l,u=-r*l+o*h,c=B(s.root);for(let[g,p]of c.positions)if(Math.abs(d-p.x)<=p.width/2&&Math.abs(u-p.y)<=p.height/2)return {shapeId:s.id,nodeId:g}}return null}selectMindMapNode(t,e){let i=this.shapes.find(n=>n.id===t);!i||i.type!=="mind-map"||(this.selectedIds=[t],this.mindMapSelectedNode={shapeId:t,nodeId:e},this.notifyListeners(),this.render());}getMindMapEditingShapeId(){return this.mindMapEditingShapeId}getMindMapSelectedNode(){return this.mindMapSelectedNode}getMindMapNode(t,e){let i=this.shapes.find(n=>n.id===t);return !i||i.type!=="mind-map"?null:J(i.root,e)}getMindMapNodeScreenRect(t,e){let i=this.shapes.find(v=>v.id===t);if(!i||i.type!=="mind-map")return null;let n=i,r=B(n.root).positions.get(e);if(!r)return null;let o=this.camera.getZoom(),h=r.x,l=r.y,d=Math.cos(n.rotation),u=Math.sin(n.rotation),c=h*d-l*u,g=h*u+l*d,p=this.camera.pageToScreen({x:n.x,y:n.y}),y=p.x+c*o,m=p.y+g*o;return {x:y-r.width*o/2,y:m-r.height*o/2,width:r.width*o,height:r.height*o}}getMindMapCollapseHitAtPoint(t){for(let e of this.shapes){if(e.type!=="mind-map")continue;let i=e,n=B(i.root),s=t.x-i.x,r=t.y-i.y,o=Math.cos(i.rotation),h=Math.sin(i.rotation),l=s*o+r*h,d=-s*h+r*o;for(let[u,c]of n.positions){let g=J(i.root,u);if(!g||!g.children||g.children.length===0)continue;let p=c.x+c.width/2+10,y=c.y,m=l-p,v=d-y;if(m*m+v*v<=121)return {shapeId:e.id,nodeId:u}}}return null}beginMindMapEdit(t,e){let i=this.shapes.find(s=>s.id===t);if(!i||i.type!=="mind-map")return;let n=i;this.mindMapEditingShapeId=t,this.mindMapSelectedNode={shapeId:t,nodeId:e&&J(n.root,e)?e:n.root.id},this.selectedIds=[t],this.notifyListeners(),this.render();}exitMindMapEdit(){this.mindMapEditingShapeId=null,this.mindMapSelectedNode=null,this.notifyListeners(),this.render();}updateMindMapNode(t,e,i,n=true){let s=this.shapes.findIndex(g=>g.id===t);if(s===-1)return;let r=this.shapes[s];if(r.type!=="mind-map")return;let o=r,h=J(o.root,e);if(!h||!Object.keys(i).some(g=>h[g]!==i[g]))return;n&&this.commitHistory();let d=Tt(o.root,e,i),{width:u,height:c}=B(d);this.shapes[s]={...o,root:d,width:u,height:c},this.notifyListeners(),this.render();}addMindMapChild(t,e){let i=this.shapes.findIndex(d=>d.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="mind-map")return;let s=n,r={id:`mm_${Date.now()}_${Math.random().toString(36).substr(2,6)}`,text:W("mindmap.defaultBranch")},o=Rt(s.root,e,r);this.commitHistory();let{width:h,height:l}=B(o);this.shapes[i]={...s,root:o,width:h,height:l},this.mindMapSelectedNode={shapeId:t,nodeId:r.id},this.notifyListeners(),this.render();}addMindMapSibling(t,e){let i=this.shapes.findIndex(d=>d.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="mind-map")return;let s=n;if(!lt(s.root,e))return;let r={id:`mm_${Date.now()}_${Math.random().toString(36).substr(2,6)}`,text:W("mindmap.defaultBranch")},o=Vt(s.root,e,r);this.commitHistory();let{width:h,height:l}=B(o);this.shapes[i]={...s,root:o,width:h,height:l},this.mindMapSelectedNode={shapeId:t,nodeId:r.id},this.notifyListeners(),this.render();}deleteMindMapNode(t,e){let i=this.shapes.findIndex(d=>d.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="mind-map")return;let s=n;if(s.root.id===e){this.commitHistory(),this.shapes=this.shapes.filter(d=>d.id!==t),this.selectedIds=this.selectedIds.filter(d=>d!==t),this.mindMapEditingShapeId=null,this.mindMapSelectedNode=null,this.notifyListeners(),this.render();return}let r=kt(s.root,e);if(!r)return;this.commitHistory();let{width:o,height:h}=B(r);this.shapes[i]={...s,root:r,width:o,height:h};let l=lt(s.root,e);this.mindMapSelectedNode=l?{shapeId:t,nodeId:l.id}:{shapeId:t,nodeId:r.id},this.notifyListeners(),this.render();}toggleMindMapCollapse(t,e){let i=this.shapes.findIndex(d=>d.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="mind-map")return;let s=n,r=J(s.root,e);if(!r||!r.children||r.children.length===0)return;this.commitHistory();let o=Tt(s.root,e,{collapsed:!r.collapsed}),{width:h,height:l}=B(o);this.shapes[i]={...s,root:o,width:h,height:l},this.notifyListeners(),this.render();}addUmlAttribute(t){let e=this.shapes.find(n=>n.id===t);if(!e||e.type!=="uml-class")return;let i={id:`attr_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,visibility:"+",name:"newField",type:"string"};this.updateUmlClass(t,{attributes:[...e.attributes,i]});}addUmlMethod(t){let e=this.getUmlById(t);if(!e)return;let i={id:`meth_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,visibility:"+",name:"newMethod",params:"",returnType:"void"};e.type==="uml-class"?this.updateUmlClass(t,{methods:[...e.methods,i]}):this.updateUmlInterface(t,{methods:[...e.methods,i]});}removeUmlAttribute(t,e){let i=this.shapes.find(n=>n.id===t);!i||i.type!=="uml-class"||this.updateUmlClass(t,{attributes:i.attributes.filter(n=>n.id!==e)});}removeUmlMethod(t,e){let i=this.getUmlById(t);if(!i)return;let n=i.methods.filter(s=>s.id!==e);i.type==="uml-class"?this.updateUmlClass(t,{methods:n}):this.updateUmlInterface(t,{methods:n});}reorderUmlAttribute(t,e,i){let n=this.shapes.find(o=>o.id===t);if(!n||n.type!=="uml-class"||e===i)return;let s=[...n.attributes];if(e<0||e>=s.length||i<0||i>=s.length)return;let[r]=s.splice(e,1);s.splice(i,0,r),this.updateUmlClass(t,{attributes:s});}reorderUmlMethod(t,e,i){let n=this.getUmlById(t);if(!n||e===i)return;let s=[...n.methods];if(e<0||e>=s.length||i<0||i>=s.length)return;let[r]=s.splice(e,1);s.splice(i,0,r),n.type==="uml-class"?this.updateUmlClass(t,{methods:s}):this.updateUmlInterface(t,{methods:s});}updateUmlRowStyle(t,e,i,n){let s=this.getUmlById(t);if(s)if(e==="attribute"){if(s.type!=="uml-class")return;let r=s.attributes.map(o=>o.id===i?{...o,textColor:n.textColor===null?void 0:n.textColor??o.textColor,fontSize:n.fontSize===null?void 0:n.fontSize??o.fontSize,strikethrough:n.strikethrough===null?void 0:n.strikethrough??o.strikethrough}:o);this.updateUmlClass(t,{attributes:r});}else {let r=s.methods.map(o=>o.id===i?{...o,textColor:n.textColor===null?void 0:n.textColor??o.textColor,fontSize:n.fontSize===null?void 0:n.fontSize??o.fontSize,strikethrough:n.strikethrough===null?void 0:n.strikethrough??o.strikethrough}:o);s.type==="uml-class"?this.updateUmlClass(t,{methods:r}):this.updateUmlInterface(t,{methods:r});}}getUmlRowAtScreenPoint(t){let e=this.camera.screenToPage(t);for(let i=this.shapes.length-1;i>=0;i--){let n=this.shapes[i];if(n.type!=="uml-class"&&n.type!=="uml-interface")continue;let s=n.width/2,r=n.height/2;if(e.x<n.x-s||e.x>n.x+s||e.y<n.y-r||e.y>n.y+r)continue;let o=K,h=e.y-n.y;if(h>=-r&&h<=-r+o)return {shape:n,section:"className",rowIndex:-1,text:n.className};if(n.type==="uml-interface"){let p=-r+o,y=r;if(n.methods.length>0&&h>=p&&h<=y){let m=Math.floor((h-p-D)/L);if(m>=0&&m<n.methods.length){let v=n.methods[m];return {shape:n,section:"method",rowIndex:m,text:`${v.visibility} ${v.name}(${v.params}): ${v.returnType}`}}return {shape:n,section:"method",rowIndex:-1,text:""}}return {shape:n,section:"className",rowIndex:-1,text:n.className}}let l=n.attributes.length>0?n.attributes.length*L+D*2:D*2,d=-r+o,u=d+l;if(n.attributes.length>0&&h>=d&&h<=u){let p=Math.floor((h-d-D)/L);if(p>=0&&p<n.attributes.length){let y=n.attributes[p];return {shape:n,section:"attribute",rowIndex:p,text:`${y.visibility} ${y.name}: ${y.type}`}}return {shape:n,section:"attribute",rowIndex:-1,text:""}}let c=u,g=r;if(n.methods.length>0&&h>=c&&h<=g){let p=Math.floor((h-c-D)/L);if(p>=0&&p<n.methods.length){let y=n.methods[p];return {shape:n,section:"method",rowIndex:p,text:`${y.visibility} ${y.name}(${y.params}): ${y.returnType}`}}return {shape:n,section:"method",rowIndex:-1,text:""}}return {shape:n,section:"className",rowIndex:-1,text:n.className}}return null}setActiveTool(t){this.tools.has(t)&&(this.activeTool=t,this.eraserPoint=null,this.notifyListeners());}getActiveTool(){return this.activeTool}getShapes(){return [...this.shapes]}getData(){return {shapes:this.getShapes(),camera:{x:this.camera.x,y:this.camera.y,zoom:this.camera.zoom}}}setShapes(t){return Array.isArray(t)?(this.shapes=t.map(e=>({...e,style:{...e.style}})),this.selectedIds=[],this.undoStack=[],this.redoStack=[],this.notifyListeners(),this.render(),true):false}setTheme(t){bt(t),this.scheduleRender();}setLanguage(t){vt(t);}getSelectedIds(){return [...this.selectedIds]}getCamera(){return this.camera}isPointerDown(){return this.pointerIsDown}getContentBounds(t=24){return xt(this.shapes,t)}async exportImage(t,e={}){return Gt(this.getShapes(),t,e)}async downloadImage(t="drawui",e="png",i={}){let n=await this.exportImage(e,i);zt(n,`${t}.${e}`);}zoomIn(){this.camera.zoomAt({x:window.innerWidth/2,y:window.innerHeight/2},1.2),this.scheduleRender(),this.notifyListeners();}zoomOut(){this.camera.zoomAt({x:window.innerWidth/2,y:window.innerHeight/2},.8),this.scheduleRender(),this.notifyListeners();}resetZoom(){this.camera.reset(),this.scheduleRender(),this.notifyListeners();}panBy(t,e){this.camera.translate(t,e),this.scheduleRender(),this.notifyListeners();}setCameraPosition(t,e){this.camera.x=t,this.camera.y=e,this.scheduleRender(),this.notifyListeners();}requestRender(){this.scheduleRender(),this.notifyListeners();}setShowGrid(t){this.renderer.setShowGrid(t),this.scheduleRender();}render(){this.renderer.render(this.shapes,this.camera,new Set(this.selectedIds),this.brushRect,this.snapGuides,this.connectingTargetId,this.genPreview,this.eraserPoint,this.mindMapSelectedNode,this.mindMapHoverNode);}scheduleRender(){this.renderScheduled||(this.renderScheduled=true,requestAnimationFrame(()=>{this.renderScheduled=false,this.render();}));}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}subscribeNotifications(t){return this.notificationListeners.add(t),()=>this.notificationListeners.delete(t)}notify(t){this.notificationListeners.forEach(e=>e(t));}notifyListeners(){this.notifyScheduled||(this.notifyScheduled=true,queueMicrotask(()=>{this.notifyScheduled=false,this.mindMapEditingShapeId&&!this.selectedIds.includes(this.mindMapEditingShapeId)&&(this.mindMapEditingShapeId=null,this.mindMapSelectedNode=null),this.listeners.forEach(t=>t());}));}cloneShapes(t){return t.map(e=>{let i={...e,style:{...e.style}};return Array.isArray(e.points)&&(i.points=e.points.map(n=>({...n}))),e.startBinding&&(i.startBinding={...e.startBinding}),e.endBinding&&(i.endBinding={...e.endBinding}),e.root&&(i.root=Pt(e.root)),i})}commitHistory(){if(this.isUndoing)return;let t={shapes:this.cloneShapes(this.shapes),selectedIds:[...this.selectedIds]};this.undoStack.push(t),this.undoStack.length>Oe&&this.undoStack.shift(),this.redoStack=[];}mark(){this.commitHistory();}undo(){if(this.undoStack.length!==0){this.isUndoing=true;try{this.redoStack.push({shapes:this.cloneShapes(this.shapes),selectedIds:[...this.selectedIds]});let t=this.undoStack.pop();this.shapes=this.cloneShapes(t.shapes),this.selectedIds=[...t.selectedIds];}finally{this.isUndoing=false;}this.notifyListeners(),this.render();}}redo(){if(this.redoStack.length!==0){this.isUndoing=true;try{this.undoStack.push({shapes:this.cloneShapes(this.shapes),selectedIds:[...this.selectedIds]});let t=this.redoStack.pop();this.shapes=this.cloneShapes(t.shapes),this.selectedIds=[...t.selectedIds];}finally{this.isUndoing=false;}this.notifyListeners(),this.render();}}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}saveToStorage(){if(!this.persist)return false;try{let t=JSON.stringify({version:1,shapes:this.shapes,savedAt:Date.now()});return localStorage.setItem(Xt,t),this.notifyListeners(),this.notify(W("save.success")),!0}catch(t){return console.error("\u4FDD\u5B58\u5931\u8D25:",t),this.notify(W("save.fail")),false}}loadFromStorage(){if(!this.persist)return false;try{let t=localStorage.getItem(Xt);if(!t)return !1;let e=JSON.parse(t);return e.shapes&&Array.isArray(e.shapes)?(this.shapes=e.shapes,this.selectedIds=[],this.undoStack=[],this.redoStack=[],this.notifyListeners(),this.scheduleRender(),!0):!1}catch(t){return console.error("\u52A0\u8F7D\u5931\u8D25:",t),false}}clearStorage(){localStorage.removeItem(Xt);}exportJSON(){return JSON.stringify({version:1,shapes:this.shapes,savedAt:Date.now()},null,2)}importJSON(t){try{let e=JSON.parse(t);return e.shapes&&Array.isArray(e.shapes)?(this.commitHistory(),this.shapes=e.shapes,this.selectedIds=[],this.notifyListeners(),this.render(),!0):!1}catch(e){return console.error("\u5BFC\u5165\u5931\u8D25:",e),false}}getEditingShapeId(){return this.editingShapeId}canEditShape(t){return !(t.type==="line"||t.type==="arrow"||t.type==="draw"||t.type==="uml-class"||t.type==="uml-interface"||t.type==="mind-map")}enterEditing(t){let e=this.shapes.find(i=>i.id===t);!e||!this.canEditShape(e)||(this.editingShapeId=t,this.selectedIds=[t],this.isNewTextShape=e.type==="text"&&!e.text,this.originalTextValue=e.text||"",this.notifyListeners(),this.scheduleRender(),requestAnimationFrame(()=>{this.createTextInput(e);}));}exitEditing(){if(!this.editingShapeId)return;let t=this.editingShapeId,e=this.shapes.find(n=>n.id===t),i=this.textInput?this.textInput.value:"";if(this.removeTextInput(),e)if(e.type==="text")if(this.commitHistory(),!i.trim()&&this.isNewTextShape)this.shapes=this.shapes.filter(n=>n.id!==t),this.selectedIds=this.selectedIds.filter(n=>n!==t);else {let n=e,s=n.fontSize||16,r=s*1.3,o=n.width||200,h=i.split(`
|
|
42
|
+
`),l=0;for(let c of h){let g="";for(let p of c){let y=g+p;y.length*s*.6>o&&g?(l++,g=p):g=y;}g&&l++;}let d={...n,text:i,height:Math.max(l*r,r)},u=this.shapes.indexOf(e);u!==-1&&(this.shapes[u]=d),i.trim()||(this.shapes=this.shapes.filter(c=>c.id!==t),this.selectedIds=this.selectedIds.filter(c=>c!==t));}else this.commitHistory(),this.updateShape(t,{text:i,textColor:e.textColor||I.text,fontSize:e.fontSize||16});this.editingShapeId=null,this.isNewTextShape=false,this.originalTextValue="",this.setActiveTool("select"),this.notifyListeners(),this.render();}removeTextInput(){this.textOverlay&&(this.textOverlay.remove(),this.textOverlay=null),this.textInput&&(this.textInput.remove(),this.textInput=null);}createTextInput(t){this.removeTextInput();let e=this.canvas.parentElement;if(!e)return;let i=this.canvas.getBoundingClientRect(),n=e.getBoundingClientRect(),s=i.left-n.left,r=i.top-n.top;this.textOverlay=document.createElement("div"),this.textOverlay.style.position="absolute",this.textOverlay.style.left=`${s}px`,this.textOverlay.style.top=`${r}px`,this.textOverlay.style.width=`${i.width}px`,this.textOverlay.style.height=`${i.height}px`,this.textOverlay.style.background="transparent",this.textOverlay.style.zIndex="1000",this.textOverlay.style.cursor="text",this.textOverlay.addEventListener("pointerdown",u=>{this.textInput&&u.target!==this.textInput&&(u.preventDefault(),this.exitEditing());}),e.appendChild(this.textOverlay);let o=this.getShapeScreenBounds(t),h=this.camera.getZoom(),l=(t.fontSize||16)*h,d=document.createElement("textarea");d.style.position="absolute",d.style.left=`${s+o.x}px`,d.style.top=`${r+o.y}px`,d.style.width=`${Math.max(o.width,60)}px`,d.style.height=`${Math.max(o.height,24)}px`,d.style.fontSize=`${l}px`,d.style.color=t.textColor||"#1f2937",d.style.textAlign="center",d.style.border=`2px solid ${I.editBorder}`,d.style.borderRadius="4px",d.style.background="rgba(255, 255, 255, 0.95)",d.style.resize="none",d.style.padding="4px 8px",d.style.boxSizing="border-box",d.style.lineHeight="1.4",d.style.fontFamily="sans-serif",d.style.outline="none",d.style.whiteSpace="pre-wrap",d.style.wordBreak="break-word",d.style.overflow="hidden",d.style.zIndex="1001",d.value=t.text||"",d.dataset.shapeId=t.id,d.addEventListener("pointerdown",u=>{u.stopPropagation();}),d.addEventListener("mousedown",u=>{u.stopPropagation();}),d.addEventListener("keydown",u=>{if(u.stopPropagation(),u.key==="Escape"&&(u.preventDefault(),this.textInput&&(this.textInput.value=this.originalTextValue),this.exitEditing()),u.key==="Enter"&&!u.shiftKey&&(u.preventDefault(),this.exitEditing()),u.key==="Enter"&&u.shiftKey){u.preventDefault();let c=d.selectionStart,g=d.selectionEnd;d.value=d.value.substring(0,c)+`
|
|
43
|
+
`+d.value.substring(g),d.selectionStart=d.selectionEnd=c+1;}}),e.appendChild(d),d.focus(),t.type==="text"&&!t.text&&(d.placeholder="\u8F93\u5165\u6587\u672C..."),this.textInput=d;}getShapeScreenBounds(t){let e=this.camera.getZoom(),i=this.camera.pageToScreen({x:t.x,y:t.y});switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":return {x:i.x-t.width*e/2,y:i.y-t.height*e/2,width:t.width*e,height:t.height*e};case "circle":return {x:i.x-t.radius*e,y:i.y-t.radius*e,width:t.radius*2*e,height:t.radius*2*e};case "text":{let n=t,s=n.width*e,r=n.height*e;return {x:i.x-s/2,y:i.y-r/2,width:s,height:r}}default:return {x:i.x-50*e,y:i.y-20*e,width:100*e,height:40*e}}}getShapeAtScreenPoint(t){let e=this.screenToPage(t);return this.getShapeAtPoint(e)}getShapeAtPoint(t,e){for(let i=this.shapes.length-1;i>=0;i--){let n=this.shapes[i];if(!(e&&n.id===e)&&this.isPointInShape(t,n))return n}return null}getShapesInBrushRadius(t,e){let i=[];for(let n of this.shapes)this.shapeIntersectsBrush(n,t,e)&&i.push(n);return i}shapeIntersectsBrush(t,e,i){switch(t.type){case "line":case "arrow":{let n=t.points,s=i+4;for(let r=1;r<n.length;r++)if(this.pointToSegmentDist(e,n[r-1],n[r])<=s)return true;return n.length>0&&Math.hypot(e.x-n[0].x,e.y-n[0].y)<=s}case "draw":{let n=t.points,s=i+4;for(let r=1;r<n.length;r++){let o={x:t.x+n[r-1].x,y:t.y+n[r-1].y},h={x:t.x+n[r].x,y:t.y+n[r].y};if(this.pointToSegmentDist(e,o,h)<=s)return true}return n.length>0&&Math.hypot(e.x-(t.x+n[0].x),e.y-(t.y+n[0].y))<=s}case "circle":return Math.hypot(e.x-t.x,e.y-t.y)<=t.radius+i;case "text":{let n=t;return Math.abs(e.x-t.x)<=n.width/2+i&&Math.abs(e.y-t.y)<=n.height/2+i}default:return Math.abs(e.x-t.x)<=t.width/2+i&&Math.abs(e.y-t.y)<=t.height/2+i}}pointToSegmentDist(t,e,i){let n=i.x-e.x,s=i.y-e.y,r=n*n+s*s,o=r===0?0:Math.max(0,Math.min(1,((t.x-e.x)*n+(t.y-e.y)*s)/r));return Math.hypot(t.x-(e.x+o*n),t.y-(e.y+o*s))}setEraserPoint(t){this.eraserPoint=t,this.scheduleRender();}isPointInShape(t,e){let i=t.x-e.x,n=t.y-e.y;switch(e.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":return Math.abs(i)<=e.width/2&&Math.abs(n)<=e.height/2;case "circle":return i*i+n*n<=e.radius*e.radius;case "hexagon":{let s=e.width/2,r=e.height/2;return Math.abs(i)<=s&&Math.abs(n)<=r&&Math.abs(i)/s+Math.abs(n)/r<=1.5}case "mind-map":return Math.abs(i)<=e.width/2&&Math.abs(n)<=e.height/2;case "text":{let s=e;return Math.abs(i)<=s.width/2&&Math.abs(n)<=s.height/2}default:return false}}updateArrowBinding(t,e,i,n){let s=this.shapes.find(h=>h.id===t);if(!s||s.type!=="arrow")return;let r=s,o={};if(i){let h=this.shapes.find(c=>c.id===i);if(!h)return;let l=n?.handle||this.getClosestHandle(r,h),d=this.getBindingPosition(h,l),u=n?{...n,toShapeId:i}:{toShapeId:i,handle:l};e==="start"?(o.startBinding=u,o.points=r.points.map((c,g)=>g===0?d:c)):(o.endBinding=u,o.points=r.points.map((c,g)=>g===r.points.length-1?d:c));}else e==="start"?o.startBinding=void 0:o.endBinding=void 0;this.updateShape(t,o);}getClosestHandle(t,e){let i=t.points[0],n=t.points[t.points.length-1],s=t.endBinding?n:i,r=s.x-e.x,o=s.y-e.y;return Math.abs(r)>Math.abs(o)?r>0?"right":"left":o>0?"bottom":"top"}dispose(){this.canvas.removeEventListener("pointerdown",this.handlePointerDown),this.canvas.removeEventListener("pointermove",this.handlePointerMove),this.canvas.removeEventListener("pointerup",this.handlePointerUp),this.canvas.removeEventListener("pointerleave",this.handlePointerUp),this.canvas.removeEventListener("wheel",this.handleWheel),window.removeEventListener("keydown",this.handleKeyDown),window.removeEventListener("keyup",this.handleKeyUp),window.removeEventListener("resize",this.handleResize),this.removeTextInput(),this.tools.forEach(t=>t.dispose()),this.listeners.clear();}};exports.ArrowTool=pt;exports.Camera=nt;exports.Editor=Yt;exports.FreehandTool=at;exports.HandTool=ut;exports.LineTool=gt;exports.MINDMAP_COLORS=Nt;exports.MINDMAP_FONT_SIZE=q;exports.MINDMAP_MAX_WIDTH=fe;exports.MINDMAP_MIN_WIDTH=ye;exports.MINDMAP_NODE_HEIGHT=pe;exports.Mat2d=Z;exports.Renderer=st;exports.SelectTool=ct;exports.ShapeTool=V;exports.THEME=I;exports.UML_FONT_SIZE=U;exports.UML_HEADER_HEIGHT=K;exports.UML_LINE_HEIGHT=L;exports.UML_MIN_WIDTH=dt;exports.UML_PADDING_X=_;exports.UML_PADDING_Y=D;exports.Vec=rt;exports.calcUmlClassSize=Ct;exports.cloneMindMapNode=Pt;exports.countMindMapNodes=qt;exports.downloadBlob=zt;exports.exportToBlob=Gt;exports.findMindMapNode=J;exports.getContentBounds=xt;exports.getLanguage=ue;exports.getMindMapNodeDepth=Zt;exports.getMindMapParent=lt;exports.getTheme=de;exports.hexToRgba=j;exports.layoutMindMap=B;exports.mindMapNodeColor=it;exports.mindMapNodeSize=jt;exports.renderSVGString=ae;exports.renderToCanvas=re;exports.setLanguage=vt;exports.setTheme=bt;exports.shadeColor=ce;exports.subscribeLanguage=ge;exports.subscribeTheme=le;exports.t=W;
|