@ehfuse/mindmap 0.1.0 → 0.2.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.esm.js +1 -1
- package/dist/index.esm.js.map +3 -3
- package/dist/index.js +1 -1
- package/dist/index.js.map +3 -3
- package/package.json +3 -2
package/dist/index.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{forwardRef as Ze,useImperativeHandle as qe,useRef as je,useState as Se}from"react";import{Box as G,ButtonBase as Je}from"@mui/material";import Qe from"@mui/icons-material/SwapHoriz";import et from"@mui/icons-material/East";import tt from"@mui/icons-material/West";import ot from"@mui/icons-material/CenterFocusStrongOutlined";import nt from"@mui/icons-material/ZoomIn";import it from"@mui/icons-material/ZoomOut";import{FormatToolbar as rt,OutlineList as at,ToolButton as te,ToolDivider as dt,locateNode as st,setNodeStyle as lt,useTreeHistory as ct}from"@ehfuse/outliner";import{forwardRef as Re,useCallback as fe,useEffect as me,useImperativeHandle as $e,useLayoutEffect as Ce,useMemo as Be,useRef as j,useState as J}from"react";import{Box as P,IconButton as He,Tooltip as Pe}from"@mui/material";import Ve from"@mui/icons-material/SubdirectoryArrowRight";import Oe from"@mui/icons-material/Add";import We from"@mui/icons-material/EditOutlined";import Ae from"@mui/icons-material/DeleteOutline";import{DEFAULT_FONT_FAMILY as he,addChild as ae,addSibling as ge,containsNode as Ye,locateNode as de,measureText as Fe,moveNode as Xe,removeNode as xe,setTopic as ye,toggleFold as be}from"@ehfuse/outliner";import{measureText as ve}from"@ehfuse/outliner";var re=["#e8710a","#1a73e8","#188038","#d93025","#9334e6","#f9ab00","#12b5cb","#c2185b"],Le=64,Ee=40,ne=14;function Ie(s,o){let p=s.style?.fontSize?parseFloat(s.style.fontSize):o===0?22:o===1?16:14,b=s.style?.fontWeight??(o===0?"700":o===1?"500":"400");return{fontSize:p,fontWeight:b}}function q(s,o){let{fontSize:p,fontWeight:b}=Ie(s,o),g=o===0?28:o===1?16:12,M=o===0?14:o===1?8:6,h=ve(s.topic||" ",p,b);return{w:Math.max(o===0?100:48,Math.ceil(h)+g*2),h:Math.ceil(p*1.4)+M*2,fontSize:p,fontWeight:b}}var ie=s=>s.expanded===!1?[]:s.children??[];function K(s,o=2){let p=new Map,b=(r,x)=>{let u=q(r,x).h,T=ie(r),m=T.reduce((S,w)=>S+b(w,x+1),0)+ne*Math.max(0,T.length-1),L=Math.max(u,m);return p.set(r.id,L),L},g=[],M=[],h=q(s,0),D={id:s.id,node:s,depth:0,x:-h.w/2,y:-h.h/2,w:h.w,h:h.h,side:0,color:"#3b3f5c",parentId:null,fontSize:h.fontSize,fontWeight:h.fontWeight};g.push(D);let v=(r,x,u,T,m)=>{x.forEach(k=>b(k,T));let L=x.reduce((k,R)=>k+(p.get(R.id)??0),0)+ne*Math.max(0,x.length-1),S=r.y+r.h/2-L/2,w=T===1?Le:Ee;x.forEach((k,R)=>{let $=p.get(k.id)??0,y=q(k,T),Y=S+$/2,l=u>0?r.x+r.w+w:r.x-w-y.w,C=m(k,R),X={id:k.id,node:k,depth:T,x:l,y:Y-y.h/2,w:y.w,h:y.h,side:u,color:C,parentId:r.id,fontSize:y.fontSize,fontWeight:y.fontWeight};g.push(X),M.push({from:r,to:X,color:C}),v(X,ie(k),u,T+1,()=>C),S+=$+ne})},I=ie(s),W=s.children??[],A=r=>re[Math.max(0,W.indexOf(r))%re.length],f=(r,x)=>o===0?-1:o===1?1:r.direction===0?-1:r.direction===1||x<Math.ceil(I.length/2)?1:-1,n=I.filter((r,x)=>f(r,x)===1),E=I.filter((r,x)=>f(r,x)===-1);v(D,n,1,1,A),v(D,E,-1,1,A);let c={minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0};for(let r of g)c.minX=Math.min(c.minX,r.x),c.minY=Math.min(c.minY,r.y),c.maxX=Math.max(c.maxX,r.x+r.w),c.maxY=Math.max(c.maxY,r.y+r.h);return{nodes:g,byId:new Map(g.map(r=>[r.id,r])),edges:M,bounds:c}}function U(s){let{from:o,to:p}=s,b=p.side>=0?1:-1,g=o.depth===0?o.x+o.w/2+b*o.w/2-b*12:b>0?o.x+o.w:o.x,M=o.y+o.h/2,h=b>0?p.x:p.x+p.w,D=p.y+p.h/2,v=(h-g)*.5;return`M ${g} ${M} C ${g+v} ${M}, ${h-v} ${D}, ${h} ${D}`}function _(s){let o=s.node.style??{};return s.depth===0?{fill:o.background??"#3b3f5c",stroke:"none",strokeWidth:0,text:o.color??"#ffffff",radius:s.h/2}:s.depth===1?{fill:o.background??"#ffffff",stroke:s.color,strokeWidth:2,text:o.color??"#1f2328",radius:s.h/2}:{fill:o.background??"#ffffff",stroke:"#d0d4da",strokeWidth:1,text:o.color??"#1f2328",radius:8}}import{jsx as N,jsxs as Q}from"react/jsx-runtime";var Ke=.3,Ue=2.5,_e=5,se=Re(function({root:o,direction:p,onEdit:b,selectedId:g,onSelect:M,strings:h,readOnly:D,onUndo:v,onRedo:I,hint:W=!0},A){let f=j(null),[n,E]=J({w:0,h:0}),[c,r]=J({x:0,y:0,z:1}),x=j(c);x.current=c;let[u,T]=J(null),[m,L]=J(null),S=j(null),w=Be(()=>K(o,p),[o,p]),k=j(!1);Ce(()=>{let e=f.current;if(!e)return;let t=new ResizeObserver(()=>E({w:e.clientWidth,h:e.clientHeight}));return t.observe(e),E({w:e.clientWidth,h:e.clientHeight}),()=>t.disconnect()},[]);let R=fe(()=>{let{minX:e,minY:t,maxX:i,maxY:d}=w.bounds,a=x.current.z;r({x:n.w/2-(e+i)/2*a,y:n.h/2-(t+d)/2*a,z:a})},[w,n]);me(()=>{k.current||n.w===0||(k.current=!0,R())},[n,R]);let $=fe((e,t,i)=>{r(d=>{let a=Math.min(Ue,Math.max(Ke,d.z*e));return{x:t-(t-d.x)*(a/d.z),y:i-(i-d.y)*(a/d.z),z:a}})},[]);$e(A,()=>({center:R,zoomBy:e=>$(e,n.w/2,n.h/2)}),[R,$,n]),me(()=>{let e=f.current;if(!e)return;let t=i=>{if(!(i.ctrlKey||i.metaKey))return;i.preventDefault();let d=e.getBoundingClientRect();$(i.deltaY<0?1.1:1/1.1,i.clientX-d.left,i.clientY-d.top)};return e.addEventListener("wheel",t,{passive:!1}),()=>e.removeEventListener("wheel",t)},[$]);let y=(e,t,i=!1)=>{e&&(b(e.root,t),e.focusId&&(M(e.focusId),i&&T({id:e.focusId,text:""})))},Y=e=>{if(D)return;let t=de(o,e);t&&T({id:e,text:t.node.topic})},l=()=>{u&&(y(ye(o,u.id,u.text)),T(null),f.current?.focus({preventScroll:!0}))},C=(e,t)=>{let i=f.current.getBoundingClientRect();return{x:(e-i.left-c.x)/c.z,y:(t-i.top-c.y)/c.z}},X=(e,t,i)=>{let d=C(e,t);for(let a of w.nodes){if(d.x<a.x-4||d.x>a.x+a.w+4||d.y<a.y-4||d.y>a.y+a.h+4)continue;if(Ye(i,a.id))return null;if(a.depth===0)return{id:a.id,place:"child"};let O=(d.y-a.y)/a.h;return{id:a.id,place:O<.25?"before":O>.75?"after":"child"}}return null},Te=e=>{if(e.button!==0)return;let t=e.target;if(t.closest("[data-mm-ui]")||(u&&!t.closest("[data-mm-edit]")&&l(),t.closest("[data-mm-edit]")))return;let i=t.closest("[data-mm-fold]");if(i){y(be(o,i.dataset.mmFold));return}let d=t.closest("[data-mm-node]");if(f.current?.focus({preventScroll:!0}),d){let a=d.dataset.mmNode;M(a),S.current={kind:"node",id:a,sx:e.clientX,sy:e.clientY,vx:c.x,vy:c.y,moved:!1}}else M(null),S.current={kind:"pan",sx:e.clientX,sy:e.clientY,vx:c.x,vy:c.y,moved:!1}},ke=e=>{let t=S.current;if(!t)return;let i=e.clientX-t.sx,d=e.clientY-t.sy;if(!t.moved&&Math.hypot(i,d)<_e)return;if(!t.moved&&!f.current?.hasPointerCapture(e.pointerId)&&f.current?.setPointerCapture(e.pointerId),t.moved=!0,t.kind==="pan"){r(F=>({...F,x:t.vx+i,y:t.vy+d}));return}if(D||t.id===o.id)return;let a=de(o,t.id)?.node;if(!a)return;let O=f.current.getBoundingClientRect();L({id:t.id,px:e.clientX-O.left,py:e.clientY-O.top,target:X(e.clientX,e.clientY,a)})},ue=e=>{let t=S.current;S.current=null,f.current?.hasPointerCapture(e.pointerId)&&f.current.releasePointerCapture(e.pointerId),t?.kind==="node"&&m?.target&&y(Xe(o,m.id,m.target.id,m.target.place)),L(null)},De=(e,t)=>{let i=de(o,e.id);if(!i)return null;if(t==="ArrowUp"||t==="ArrowDown"){if(!i.parent)return null;let a=(i.parent.children??[]).filter(F=>w.byId.get(F.id)?.side===e.side),O=a.findIndex(F=>F.id===e.id);return a[O+(t==="ArrowUp"?-1:1)]?.id??null}if(t==="ArrowRight"&&e.side>=0||t==="ArrowLeft"&&e.side<=0){let a=i.node.expanded===!1?[]:i.node.children??[],O=e.side===0?t==="ArrowRight"?1:-1:e.side;return a.find(F=>w.byId.get(F.id)?.side===O)?.id??null}return e.parentId},Ne=e=>{if(u||e.target.tagName==="INPUT")return;let t=e.ctrlKey||e.metaKey;if(t&&(e.key==="z"||e.key==="Z")){e.preventDefault(),e.shiftKey?I?.():v?.();return}if(t&&(e.key==="y"||e.key==="Y")){e.preventDefault(),I?.();return}let i=g?w.byId.get(g):null;if(i){if(e.key.startsWith("Arrow")){let d=De(i,e.key);e.preventDefault(),d&&M(d);return}D||(e.key==="Tab"?(e.preventDefault(),y(ae(o,i.id),void 0,!0)):e.key==="Enter"?(e.preventDefault(),y(ge(o,i.id),void 0,!0)):e.key==="F2"?(e.preventDefault(),Y(i.id)):e.key==="Delete"||e.key==="Backspace"?(e.preventDefault(),y(xe(o,i.id))):e.key===" "&&(e.preventDefault(),y(be(o,i.id))))}},B=g?w.byId.get(g):void 0,V=u?w.byId.get(u.id):void 0,oe=m?w.byId.get(m.id):void 0,H=m?.target?w.byId.get(m.target.id):void 0,Z=(e,t,i,d)=>N(Pe,{title:t,disableInteractive:!0,children:N(He,{size:"small","aria-label":t,onMouseDown:a=>a.preventDefault(),onClick:d,sx:{width:28,height:28,color:"text.secondary","&:hover":{color:"primary.main"}},children:i})},e);return Q(P,{ref:f,tabIndex:0,onKeyDown:Ne,onPointerDown:Te,onPointerMove:ke,onPointerUp:ue,onPointerCancel:ue,onDoubleClick:e=>{let t=e.target.closest("[data-mm-node]");t&&Y(t.dataset.mmNode)},sx:{position:"relative",width:"100%",height:"100%",overflow:"hidden",bgcolor:"#f7f8fa",outline:"none",touchAction:"none",userSelect:"none",cursor:S.current?.kind==="pan"?"grabbing":"default"},children:[Q(P,{sx:{position:"absolute",left:0,top:0,transform:`translate(${c.x}px, ${c.y}px) scale(${c.z})`,transformOrigin:"0 0"},children:[N("svg",{style:{position:"absolute",left:0,top:0,width:1,height:1,overflow:"visible"},children:w.edges.map(e=>N("path",{d:U(e),fill:"none",stroke:e.color,strokeWidth:e.to.depth===1?2.5:1.75,strokeLinecap:"round"},e.to.id))}),w.nodes.map(e=>{let t=_(e),i=e.node.children?.length??0,d=e.node.expanded===!1&&i>0,a=e.id===g;return Q(P,{"data-mm-node":e.id,sx:{position:"absolute",left:e.x,top:e.y,width:e.w,height:e.h,boxSizing:"border-box",display:"flex",alignItems:"center",justifyContent:"center",borderRadius:`${t.radius}px`,bgcolor:t.fill,border:t.stroke!=="none"?`${t.strokeWidth}px solid ${t.stroke}`:0,color:t.text,fontFamily:he,fontSize:e.fontSize,fontWeight:e.fontWeight,textDecoration:e.node.style?.textDecoration,whiteSpace:"nowrap",cursor:D?"default":"pointer",boxShadow:a?"0 0 0 2px #fff, 0 0 0 4px #1a73e8":e.depth===0?"0 2px 6px rgba(0,0,0,0.18)":"none",opacity:m?.id===e.id?.35:1,"&:hover .mm-fold":{opacity:1}},children:[u?.id===e.id?null:e.node.topic||"\xA0",i>0&&e.depth>0?N(P,{className:"mm-fold","data-mm-fold":e.id,title:d?h.unfold:h.fold,sx:{position:"absolute",top:"50%",[e.side>0?"left":"right"]:"100%",transform:`translate(${e.side>0?4:-4}px, -50%)`,minWidth:18,height:18,px:d?.5:0,boxSizing:"border-box",borderRadius:9,bgcolor:"#fff",border:`1.5px solid ${e.color}`,color:e.color,fontSize:11,fontWeight:600,lineHeight:"15px",textAlign:"center",cursor:"pointer",opacity:d||a?1:0,textDecoration:"none"},children:d?i:"\u2212"}):null]},e.id)}),H&&m?.target?m.target.place==="child"?N(P,{sx:{position:"absolute",left:H.x-4,top:H.y-4,width:H.w+8,height:H.h+8,border:"2px dashed #1a73e8",borderRadius:2,pointerEvents:"none"}}):N(P,{sx:{position:"absolute",left:H.x,top:m.target.place==="before"?H.y-6:H.y+H.h+4,width:H.w,height:3,borderRadius:2,bgcolor:"#1a73e8",pointerEvents:"none"}}):null,V&&u?N("input",{"data-mm-edit":"",autoFocus:!0,value:u.text,spellCheck:!1,onFocus:e=>e.currentTarget.select(),onChange:e=>T({id:u.id,text:e.target.value}),onBlur:l,onKeyDown:e=>{if(e.stopPropagation(),!e.nativeEvent.isComposing){if(e.key==="Enter")e.preventDefault(),l();else if(e.key==="Escape")e.preventDefault(),T(null),f.current?.focus({preventScroll:!0});else if(e.key==="Tab"){e.preventDefault();let t=u.id,i=u.text;T(null);let d=ye(o,t,i);y(ae(d?.root??o,t),void 0,!0)}}},style:{position:"absolute",left:V.x,top:V.y,width:Math.max(V.w,Math.ceil(Fe(u.text||" ",V.fontSize,V.fontWeight))+40),height:V.h,boxSizing:"border-box",padding:"0 12px",border:"2px solid #1a73e8",borderRadius:8,outline:"none",textAlign:"center",fontFamily:he,fontSize:V.fontSize,fontWeight:V.fontWeight,color:"#1f2328",background:"#fff",zIndex:5}}):null]}),m&&oe?N(P,{sx:{position:"absolute",left:m.px+10,top:m.py+10,px:1.5,py:.5,borderRadius:2,bgcolor:"#fff",border:`1.5px solid ${oe.color}`,fontSize:13,opacity:.9,pointerEvents:"none",boxShadow:"0 4px 12px rgba(0,0,0,0.15)"},children:oe.node.topic||"\xA0"}):null,B&&!u&&!m&&!D?Q(P,{"data-mm-ui":"",sx:{position:"absolute",left:c.x+(B.x+B.w/2)*c.z,top:c.y+B.y*c.z,transform:"translate(-50%, calc(-100% - 8px))",display:"flex",gap:.25,p:.25,bgcolor:"#fff",border:"1px solid #e0e0e0",borderRadius:1,boxShadow:"0 2px 6px rgba(0,0,0,0.12)",zIndex:6},children:[Z("child",h.addChild,N(Ve,{sx:{fontSize:18}}),()=>y(ae(o,B.id),void 0,!0)),B.depth>0?Z("sibling",h.addSibling,N(Oe,{sx:{fontSize:18}}),()=>y(ge(o,B.id),void 0,!0)):null,Z("edit",h.edit,N(We,{sx:{fontSize:17}}),()=>Y(B.id)),B.depth>0?Z("delete",h.remove,N(Ae,{sx:{fontSize:18}}),()=>y(xe(o,B.id))):null]}):null,W?N(P,{sx:{position:"absolute",left:12,right:12,bottom:8,fontSize:12,lineHeight:1.5,color:"text.secondary",pointerEvents:"none"},children:N(P,{component:"span",sx:{bgcolor:"rgba(247,248,250,0.85)"},children:h.mapHint})}):null]})});import{outlinerStrings as Ge}from"@ehfuse/outliner";var Me={ko:{map:"\uC9C0\uB3C4",outline:"\uBAA9\uB85D",addChild:"\uC544\uB798 \uAC00\uC9C0",addSibling:"\uC606 \uAC00\uC9C0",edit:"\uAE00 \uACE0\uCE58\uAE30",remove:"\uC9C0\uC6B0\uAE30",dirSide:"\uC591\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30",dirRight:"\uC624\uB978\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30",dirLeft:"\uC67C\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30",center:"\uAC00\uC6B4\uB370\uB85C",zoomIn:"\uD655\uB300",zoomOut:"\uCD95\uC18C",mapHint:"\uB450 \uBC88 \uD074\uB9AD: \uAE00 \uACE0\uCE58\uAE30 \xB7 Tab: \uC544\uB798 \uAC00\uC9C0 \xB7 Enter: \uC606 \uAC00\uC9C0 \xB7 \uAC00\uC9C0 \uB04C\uAE30: \uC62E\uAE30\uAE30 \xB7 \uBE48 \uACF3 \uB04C\uAE30: \uC774\uB3D9 \xB7 Ctrl+\uD720: \uD655\uB300",newTopic:"\uC0C8 \uAC00\uC9C0"},en:{map:"Map",outline:"List",addChild:"Child branch",addSibling:"Sibling branch",edit:"Edit text",remove:"Delete",dirSide:"Grow both ways",dirRight:"Grow to the right",dirLeft:"Grow to the left",center:"Center",zoomIn:"Zoom in",zoomOut:"Zoom out",mapHint:"Double-click: edit \xB7 Tab: child \xB7 Enter: sibling \xB7 Drag a branch: move \xB7 Drag empty space: pan \xB7 Ctrl+wheel: zoom",newTopic:"New branch"},ja:{map:"\u30DE\u30C3\u30D7",outline:"\u30EA\u30B9\u30C8",addChild:"\u4E0B\u306E\u679D",addSibling:"\u6A2A\u306E\u679D",edit:"\u6587\u5B57\u3092\u7DE8\u96C6",remove:"\u524A\u9664",dirSide:"\u4E21\u5074\u306B\u5E83\u3052\u308B",dirRight:"\u53F3\u306B\u5E83\u3052\u308B",dirLeft:"\u5DE6\u306B\u5E83\u3052\u308B",center:"\u4E2D\u592E\u3078",zoomIn:"\u62E1\u5927",zoomOut:"\u7E2E\u5C0F",mapHint:"\u30C0\u30D6\u30EB\u30AF\u30EA\u30C3\u30AF: \u7DE8\u96C6 \xB7 Tab: \u4E0B\u306E\u679D \xB7 Enter: \u6A2A\u306E\u679D \xB7 \u679D\u3092\u30C9\u30E9\u30C3\u30B0: \u79FB\u52D5 \xB7 \u7A7A\u767D\u30C9\u30E9\u30C3\u30B0: \u30B9\u30AF\u30ED\u30FC\u30EB \xB7 Ctrl+\u30DB\u30A4\u30FC\u30EB: \u62E1\u5927",newTopic:"\u65B0\u3057\u3044\u679D"},zh:{map:"\u5BFC\u56FE",outline:"\u5217\u8868",addChild:"\u5B50\u5206\u652F",addSibling:"\u540C\u7EA7\u5206\u652F",edit:"\u7F16\u8F91\u6587\u5B57",remove:"\u5220\u9664",dirSide:"\u4E24\u4FA7\u5C55\u5F00",dirRight:"\u5411\u53F3\u5C55\u5F00",dirLeft:"\u5411\u5DE6\u5C55\u5F00",center:"\u5C45\u4E2D",zoomIn:"\u653E\u5927",zoomOut:"\u7F29\u5C0F",mapHint:"\u53CC\u51FB: \u7F16\u8F91 \xB7 Tab: \u5B50\u5206\u652F \xB7 Enter: \u540C\u7EA7\u5206\u652F \xB7 \u62D6\u52A8\u5206\u652F: \u79FB\u52A8 \xB7 \u62D6\u52A8\u7A7A\u767D: \u5E73\u79FB \xB7 Ctrl+\u6EDA\u8F6E: \u7F29\u653E",newTopic:"\u65B0\u5206\u652F"},de:{map:"Karte",outline:"Liste",addChild:"Unterzweig",addSibling:"Nebenzweig",edit:"Text bearbeiten",remove:"L\xF6schen",dirSide:"Beidseitig",dirRight:"Nach rechts",dirLeft:"Nach links",center:"Zentrieren",zoomIn:"Vergr\xF6\xDFern",zoomOut:"Verkleinern",mapHint:"Doppelklick: bearbeiten \xB7 Tab: Unterzweig \xB7 Enter: Nebenzweig \xB7 Zweig ziehen: verschieben \xB7 Leere Fl\xE4che ziehen: schwenken \xB7 Strg+Rad: Zoom",newTopic:"Neuer Zweig"},fr:{map:"Carte",outline:"Liste",addChild:"Branche enfant",addSibling:"Branche s\u0153ur",edit:"Modifier le texte",remove:"Supprimer",dirSide:"Des deux c\xF4t\xE9s",dirRight:"Vers la droite",dirLeft:"Vers la gauche",center:"Centrer",zoomIn:"Zoomer",zoomOut:"D\xE9zoomer",mapHint:"Double-clic : modifier \xB7 Tab : enfant \xB7 Entr\xE9e : s\u0153ur \xB7 Glisser une branche : d\xE9placer \xB7 Glisser le vide : d\xE9filer \xB7 Ctrl+molette : zoom",newTopic:"Nouvelle branche"},it:{map:"Mappa",outline:"Elenco",addChild:"Ramo figlio",addSibling:"Ramo fratello",edit:"Modifica testo",remove:"Elimina",dirSide:"Su entrambi i lati",dirRight:"Verso destra",dirLeft:"Verso sinistra",center:"Centra",zoomIn:"Ingrandisci",zoomOut:"Riduci",mapHint:"Doppio clic: modifica \xB7 Tab: figlio \xB7 Invio: fratello \xB7 Trascina un ramo: sposta \xB7 Trascina il vuoto: scorri \xB7 Ctrl+rotella: zoom",newTopic:"Nuovo ramo"},vi:{map:"B\u1EA3n \u0111\u1ED3",outline:"Danh s\xE1ch",addChild:"Nh\xE1nh con",addSibling:"Nh\xE1nh ngang",edit:"S\u1EEDa ch\u1EEF",remove:"X\xF3a",dirSide:"M\u1EDF hai b\xEAn",dirRight:"M\u1EDF sang ph\u1EA3i",dirLeft:"M\u1EDF sang tr\xE1i",center:"V\u1EC1 gi\u1EEFa",zoomIn:"Ph\xF3ng to",zoomOut:"Thu nh\u1ECF",mapHint:"Nh\u1EA5p \u0111\xFAp: s\u1EEDa \xB7 Tab: nh\xE1nh con \xB7 Enter: nh\xE1nh ngang \xB7 K\xE9o nh\xE1nh: di chuy\u1EC3n \xB7 K\xE9o ch\u1ED7 tr\u1ED1ng: cu\u1ED9n \xB7 Ctrl+cu\u1ED9n: ph\xF3ng to",newTopic:"Nh\xE1nh m\u1EDBi"}};function le(s,o){let p=(s??"en").slice(0,2).toLowerCase();return{...Ge(s),...Me[p]??Me.en,...o}}import{DEFAULT_FONT_FAMILY as we}from"@ehfuse/outliner";var ee=s=>s.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");function ce(s,o={}){let p=o.padding??24,b=K(s.nodeData,s.direction??2),{minX:g,minY:M,maxX:h,maxY:D}=b.bounds,v=Math.ceil(h-g+p*2),I=Math.ceil(D-M+p*2),W=p-g,A=p-M,f=[];f.push(`<rect width="${v}" height="${I}" fill="${o.background??"#ffffff"}"/>`),f.push(`<g transform="translate(${W} ${A})">`);for(let n of b.edges)f.push(`<path d="${U(n)}" fill="none" stroke="${n.color}" stroke-width="${n.to.depth===1?2.5:1.75}" stroke-linecap="round"/>`);for(let n of b.nodes){let E=_(n);f.push(`<rect x="${n.x}" y="${n.y}" width="${n.w}" height="${n.h}" rx="${E.radius}" fill="${E.fill}"${E.stroke!=="none"?` stroke="${E.stroke}" stroke-width="${E.strokeWidth}"`:""}/>`);let c=n.node.style?.textDecoration;if(f.push(`<text x="${n.x+n.w/2}" y="${n.y+n.h/2}" text-anchor="middle" dominant-baseline="central" font-family="${ee(we)}" font-size="${n.fontSize}" font-weight="${n.fontWeight}" fill="${E.text}"${c?` text-decoration="${ee(c)}"`:""}>${ee(n.node.topic)}</text>`),n.node.expanded===!1&&(n.node.children?.length??0)>0&&n.depth>0){let r=n.side>0?n.x+n.w+10:n.x-10,x=n.y+n.h/2;f.push(`<circle cx="${r}" cy="${x}" r="9" fill="#ffffff" stroke="${n.color}" stroke-width="1.5"/>`),f.push(`<text x="${r}" y="${x}" text-anchor="middle" dominant-baseline="central" font-family="${ee(we)}" font-size="10" fill="${n.color}">${n.node.children.length}</text>`)}}return f.push("</g>"),`<svg xmlns="http://www.w3.org/2000/svg" width="${v}" height="${I}" viewBox="0 0 ${v} ${I}">${f.join("")}</svg>`}import{Fragment as ze,jsx as z,jsxs as pe}from"react/jsx-runtime";var pt=[{value:2,key:"dirSide",icon:z(Qe,{sx:{fontSize:19}})},{value:1,key:"dirRight",icon:z(et,{sx:{fontSize:18}})},{value:0,key:"dirLeft",icon:z(tt,{sx:{fontSize:18}})}],ut=Ze(function({value:o,onChange:p,locale:b,strings:g,readOnly:M,view:h,defaultView:D="map",onViewChange:v,toolbarEnd:I,hint:W=!0,height:A="100%"},f){let n=le(b,g),[E,c]=Se(D),r=h??E,x=l=>{c(l),v?.(l),l==="map"&&requestAnimationFrame(()=>L.current?.center())},[u,T]=Se(null),m=ct(),L=je(null),S=o.nodeData,w=o.direction??2,k=(l,C)=>{m.record(S,C),p({...o,nodeData:l})},R=()=>{let l=m.undo(S);l&&p({...o,nodeData:l})},$=()=>{let l=m.redo(S);l&&p({...o,nodeData:l})};qe(f,()=>({exportSvg:()=>ce(o),center:()=>L.current?.center()}),[o]);let y=u?st(S,u)?.node:void 0,Y=z(G,{sx:{display:"flex",p:.25,borderRadius:1,bgcolor:"#f1f3f4"},children:["map","outline"].map(l=>z(Je,{"aria-pressed":r===l,onClick:()=>x(l),sx:{height:26,px:1.25,borderRadius:.75,fontSize:13,fontWeight:r===l?600:400,color:r===l?"primary.main":"text.secondary",bgcolor:r===l?"#fff":"transparent",boxShadow:r===l?"0 1px 2px rgba(0,0,0,0.15)":"none"},children:l==="map"?n.map:n.outline},l))});return pe(G,{sx:{display:"flex",flexDirection:"column",height:A,minHeight:0,bgcolor:"#fff"},children:[z(rt,{strings:n,style:y?y.style??{}:void 0,onStyle:l=>{if(!u)return;let C=lt(S,[u],l);C&&k(C.root)},canUndo:m.canUndo,canRedo:m.canRedo,onUndo:R,onRedo:$,start:Y,end:I,readOnly:M,children:r==="map"?pe(ze,{children:[pt.map(l=>z(te,{label:n[l.key],active:w===l.value,disabled:M,onClick:()=>p({...o,direction:l.value}),children:l.icon},l.value)),z(dt,{}),z(te,{label:n.zoomOut,onClick:()=>L.current?.zoomBy(1/1.2),children:z(it,{sx:{fontSize:19}})}),z(te,{label:n.zoomIn,onClick:()=>L.current?.zoomBy(1.2),children:z(nt,{sx:{fontSize:19}})}),z(te,{label:n.center,onClick:()=>L.current?.center(),children:z(ot,{sx:{fontSize:18}})})]}):null}),z(G,{sx:{position:"relative",flex:1,minHeight:0},children:r==="map"?z(se,{ref:L,root:S,direction:w,onEdit:k,selectedId:u,onSelect:T,strings:n,readOnly:M,onUndo:R,onRedo:$,hint:W}):pe(ze,{children:[z(at,{root:S,onEdit:k,selectedId:u,onSelect:T,strings:n,readOnly:M,onUndo:R,onRedo:$}),W?z(G,{sx:{position:"absolute",left:12,right:12,bottom:8,fontSize:12,lineHeight:1.5,color:"text.secondary",pointerEvents:"none"},children:z(G,{component:"span",sx:{bgcolor:"rgba(255,255,255,0.9)"},children:n.hint})}):null]})})]})});import{createTree as jt}from"@ehfuse/outliner";export{re as BRANCH_COLORS,se as MapView,ut as MindMap,jt as createTree,U as edgePath,ce as exportMindMapSvg,K as layoutMap,le as mindMapStrings,_ as nodeLook,q as nodeSize};
|
|
1
|
+
import{forwardRef as Ge,useImperativeHandle as Ze,useRef as qe,useState as Se}from"react";import{Box as G,ButtonBase as je}from"@mui/material";import{BranchBothIcon as Je,BranchLeftIcon as Qe,BranchRightIcon as et,FitCenterIcon as tt,ZoomInIcon as ot,ZoomOutIcon as nt}from"@ehfuse/toolbar-icons";import{FormatToolbar as it,OutlineList as rt,ToolButton as te,ToolDivider as at,locateNode as dt,setNodeStyle as st,useTreeHistory as lt}from"@ehfuse/outliner";import{forwardRef as Re,useCallback as fe,useEffect as me,useImperativeHandle as $e,useLayoutEffect as Ce,useMemo as Be,useRef as j,useState as J}from"react";import{Box as P}from"@mui/material";import{ChildBranchIcon as He,PencilIcon as Pe,SiblingBranchIcon as Ve,TrashIcon as Oe}from"@ehfuse/toolbar-icons";import{DEFAULT_FONT_FAMILY as he,ToolButton as We,addChild as ae,addSibling as ge,containsNode as Ae,locateNode as de,measureText as Ye,moveNode as Fe,removeNode as xe,setTopic as ye,toggleFold as be}from"@ehfuse/outliner";import{measureText as ve}from"@ehfuse/outliner";var re=["#e8710a","#1a73e8","#188038","#d93025","#9334e6","#f9ab00","#12b5cb","#c2185b"],Le=64,Ee=40,ne=14;function Ie(d,o){let p=d.style?.fontSize?parseFloat(d.style.fontSize):o===0?22:o===1?16:14,b=d.style?.fontWeight??(o===0?"700":o===1?"500":"400");return{fontSize:p,fontWeight:b}}function q(d,o){let{fontSize:p,fontWeight:b}=Ie(d,o),g=o===0?28:o===1?16:12,M=o===0?14:o===1?8:6,h=ve(d.topic||" ",p,b);return{w:Math.max(o===0?100:48,Math.ceil(h)+g*2),h:Math.ceil(p*1.4)+M*2,fontSize:p,fontWeight:b}}var ie=d=>d.expanded===!1?[]:d.children??[];function K(d,o=2){let p=new Map,b=(r,x)=>{let u=q(r,x).h,z=ie(r),m=z.reduce((S,w)=>S+b(w,x+1),0)+ne*Math.max(0,z.length-1),v=Math.max(u,m);return p.set(r.id,v),v},g=[],M=[],h=q(d,0),N={id:d.id,node:d,depth:0,x:-h.w/2,y:-h.h/2,w:h.w,h:h.h,side:0,color:"#3b3f5c",parentId:null,fontSize:h.fontSize,fontWeight:h.fontWeight};g.push(N);let D=(r,x,u,z,m)=>{x.forEach(k=>b(k,z));let v=x.reduce((k,R)=>k+(p.get(R.id)??0),0)+ne*Math.max(0,x.length-1),S=r.y+r.h/2-v/2,w=z===1?Le:Ee;x.forEach((k,R)=>{let $=p.get(k.id)??0,y=q(k,z),Y=S+$/2,s=u>0?r.x+r.w+w:r.x-w-y.w,C=m(k,R),X={id:k.id,node:k,depth:z,x:s,y:Y-y.h/2,w:y.w,h:y.h,side:u,color:C,parentId:r.id,fontSize:y.fontSize,fontWeight:y.fontWeight};g.push(X),M.push({from:r,to:X,color:C}),D(X,ie(k),u,z+1,()=>C),S+=$+ne})},I=ie(d),W=d.children??[],A=r=>re[Math.max(0,W.indexOf(r))%re.length],f=(r,x)=>o===0?-1:o===1?1:r.direction===0?-1:r.direction===1||x<Math.ceil(I.length/2)?1:-1,n=I.filter((r,x)=>f(r,x)===1),E=I.filter((r,x)=>f(r,x)===-1);D(N,n,1,1,A),D(N,E,-1,1,A);let c={minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0};for(let r of g)c.minX=Math.min(c.minX,r.x),c.minY=Math.min(c.minY,r.y),c.maxX=Math.max(c.maxX,r.x+r.w),c.maxY=Math.max(c.maxY,r.y+r.h);return{nodes:g,byId:new Map(g.map(r=>[r.id,r])),edges:M,bounds:c}}function U(d){let{from:o,to:p}=d,b=p.side>=0?1:-1,g=o.depth===0?o.x+o.w/2+b*o.w/2-b*12:b>0?o.x+o.w:o.x,M=o.y+o.h/2,h=b>0?p.x:p.x+p.w,N=p.y+p.h/2,D=(h-g)*.5;return`M ${g} ${M} C ${g+D} ${M}, ${h-D} ${N}, ${h} ${N}`}function _(d){let o=d.node.style??{};return d.depth===0?{fill:o.background??"#3b3f5c",stroke:"none",strokeWidth:0,text:o.color??"#ffffff",radius:d.h/2}:d.depth===1?{fill:o.background??"#ffffff",stroke:d.color,strokeWidth:2,text:o.color??"#1f2328",radius:d.h/2}:{fill:o.background??"#ffffff",stroke:"#d0d4da",strokeWidth:1,text:o.color??"#1f2328",radius:8}}import{jsx as L,jsxs as Q}from"react/jsx-runtime";var Xe=.3,Ke=2.5,Ue=5,se=Re(function({root:o,direction:p,onEdit:b,selectedId:g,onSelect:M,strings:h,readOnly:N,onUndo:D,onRedo:I,hint:W=!0},A){let f=j(null),[n,E]=J({w:0,h:0}),[c,r]=J({x:0,y:0,z:1}),x=j(c);x.current=c;let[u,z]=J(null),[m,v]=J(null),S=j(null),w=Be(()=>K(o,p),[o,p]),k=j(!1);Ce(()=>{let e=f.current;if(!e)return;let t=new ResizeObserver(()=>E({w:e.clientWidth,h:e.clientHeight}));return t.observe(e),E({w:e.clientWidth,h:e.clientHeight}),()=>t.disconnect()},[]);let R=fe(()=>{let{minX:e,minY:t,maxX:i,maxY:a}=w.bounds,l=x.current.z;r({x:n.w/2-(e+i)/2*l,y:n.h/2-(t+a)/2*l,z:l})},[w,n]);me(()=>{k.current||n.w===0||(k.current=!0,R())},[n,R]);let $=fe((e,t,i)=>{r(a=>{let l=Math.min(Ke,Math.max(Xe,a.z*e));return{x:t-(t-a.x)*(l/a.z),y:i-(i-a.y)*(l/a.z),z:l}})},[]);$e(A,()=>({center:R,zoomBy:e=>$(e,n.w/2,n.h/2)}),[R,$,n]),me(()=>{let e=f.current;if(!e)return;let t=i=>{if(!(i.ctrlKey||i.metaKey))return;i.preventDefault();let a=e.getBoundingClientRect();$(i.deltaY<0?1.1:1/1.1,i.clientX-a.left,i.clientY-a.top)};return e.addEventListener("wheel",t,{passive:!1}),()=>e.removeEventListener("wheel",t)},[$]);let y=(e,t,i=!1)=>{e&&(b(e.root,t),e.focusId&&(M(e.focusId),i&&z({id:e.focusId,text:""})))},Y=e=>{if(N)return;let t=de(o,e);t&&z({id:e,text:t.node.topic})},s=()=>{u&&(y(ye(o,u.id,u.text)),z(null),f.current?.focus({preventScroll:!0}))},C=(e,t)=>{let i=f.current.getBoundingClientRect();return{x:(e-i.left-c.x)/c.z,y:(t-i.top-c.y)/c.z}},X=(e,t,i)=>{let a=C(e,t);for(let l of w.nodes){if(a.x<l.x-4||a.x>l.x+l.w+4||a.y<l.y-4||a.y>l.y+l.h+4)continue;if(Ae(i,l.id))return null;if(l.depth===0)return{id:l.id,place:"child"};let O=(a.y-l.y)/l.h;return{id:l.id,place:O<.25?"before":O>.75?"after":"child"}}return null},ze=e=>{if(e.button!==0)return;let t=e.target;if(t.closest("[data-mm-ui]")||(u&&!t.closest("[data-mm-edit]")&&s(),t.closest("[data-mm-edit]")))return;let i=t.closest("[data-mm-fold]");if(i){y(be(o,i.dataset.mmFold));return}let a=t.closest("[data-mm-node]");if(f.current?.focus({preventScroll:!0}),a){let l=a.dataset.mmNode;M(l),S.current={kind:"node",id:l,sx:e.clientX,sy:e.clientY,vx:c.x,vy:c.y,moved:!1}}else M(null),S.current={kind:"pan",sx:e.clientX,sy:e.clientY,vx:c.x,vy:c.y,moved:!1}},ke=e=>{let t=S.current;if(!t)return;let i=e.clientX-t.sx,a=e.clientY-t.sy;if(!t.moved&&Math.hypot(i,a)<Ue)return;if(!t.moved&&!f.current?.hasPointerCapture(e.pointerId)&&f.current?.setPointerCapture(e.pointerId),t.moved=!0,t.kind==="pan"){r(F=>({...F,x:t.vx+i,y:t.vy+a}));return}if(N||t.id===o.id)return;let l=de(o,t.id)?.node;if(!l)return;let O=f.current.getBoundingClientRect();v({id:t.id,px:e.clientX-O.left,py:e.clientY-O.top,target:X(e.clientX,e.clientY,l)})},ue=e=>{let t=S.current;S.current=null,f.current?.hasPointerCapture(e.pointerId)&&f.current.releasePointerCapture(e.pointerId),t?.kind==="node"&&m?.target&&y(Fe(o,m.id,m.target.id,m.target.place)),v(null)},Ne=(e,t)=>{let i=de(o,e.id);if(!i)return null;if(t==="ArrowUp"||t==="ArrowDown"){if(!i.parent)return null;let l=(i.parent.children??[]).filter(F=>w.byId.get(F.id)?.side===e.side),O=l.findIndex(F=>F.id===e.id);return l[O+(t==="ArrowUp"?-1:1)]?.id??null}if(t==="ArrowRight"&&e.side>=0||t==="ArrowLeft"&&e.side<=0){let l=i.node.expanded===!1?[]:i.node.children??[],O=e.side===0?t==="ArrowRight"?1:-1:e.side;return l.find(F=>w.byId.get(F.id)?.side===O)?.id??null}return e.parentId},De=e=>{if(u||e.target.tagName==="INPUT")return;let t=e.ctrlKey||e.metaKey;if(t&&(e.key==="z"||e.key==="Z")){e.preventDefault(),e.shiftKey?I?.():D?.();return}if(t&&(e.key==="y"||e.key==="Y")){e.preventDefault(),I?.();return}let i=g?w.byId.get(g):null;if(i){if(e.key.startsWith("Arrow")){let a=Ne(i,e.key);e.preventDefault(),a&&M(a);return}N||(e.key==="Tab"?(e.preventDefault(),y(ae(o,i.id),void 0,!0)):e.key==="Enter"?(e.preventDefault(),y(ge(o,i.id),void 0,!0)):e.key==="F2"?(e.preventDefault(),Y(i.id)):e.key==="Delete"||e.key==="Backspace"?(e.preventDefault(),y(xe(o,i.id))):e.key===" "&&(e.preventDefault(),y(be(o,i.id))))}},B=g?w.byId.get(g):void 0,V=u?w.byId.get(u.id):void 0,oe=m?w.byId.get(m.id):void 0,H=m?.target?w.byId.get(m.target.id):void 0,Z=(e,t,i,a)=>L(We,{label:t,onClick:a,children:i},e);return Q(P,{ref:f,tabIndex:0,onKeyDown:De,onPointerDown:ze,onPointerMove:ke,onPointerUp:ue,onPointerCancel:ue,onDoubleClick:e=>{let t=e.target.closest("[data-mm-node]");t&&Y(t.dataset.mmNode)},sx:{position:"relative",width:"100%",height:"100%",overflow:"hidden",bgcolor:"#f7f8fa",outline:"none",touchAction:"none",userSelect:"none",cursor:S.current?.kind==="pan"?"grabbing":"default"},children:[Q(P,{sx:{position:"absolute",left:0,top:0,transform:`translate(${c.x}px, ${c.y}px) scale(${c.z})`,transformOrigin:"0 0"},children:[L("svg",{style:{position:"absolute",left:0,top:0,width:1,height:1,overflow:"visible"},children:w.edges.map(e=>L("path",{d:U(e),fill:"none",stroke:e.color,strokeWidth:e.to.depth===1?2.5:1.75,strokeLinecap:"round"},e.to.id))}),w.nodes.map(e=>{let t=_(e),i=e.node.children?.length??0,a=e.node.expanded===!1&&i>0,l=e.id===g;return Q(P,{"data-mm-node":e.id,sx:{position:"absolute",left:e.x,top:e.y,width:e.w,height:e.h,boxSizing:"border-box",display:"flex",alignItems:"center",justifyContent:"center",borderRadius:`${t.radius}px`,bgcolor:t.fill,border:t.stroke!=="none"?`${t.strokeWidth}px solid ${t.stroke}`:0,color:t.text,fontFamily:he,fontSize:e.fontSize,fontWeight:e.fontWeight,textDecoration:e.node.style?.textDecoration,whiteSpace:"nowrap",cursor:N?"default":"pointer",boxShadow:l?"0 0 0 2px #fff, 0 0 0 4px #1a73e8":e.depth===0?"0 2px 6px rgba(0,0,0,0.18)":"none",opacity:m?.id===e.id?.35:1,"&:hover .mm-fold":{opacity:1}},children:[u?.id===e.id?null:e.node.topic||"\xA0",i>0&&e.depth>0?L(P,{className:"mm-fold","data-mm-fold":e.id,title:a?h.unfold:h.fold,sx:{position:"absolute",top:"50%",[e.side>0?"left":"right"]:"100%",transform:`translate(${e.side>0?4:-4}px, -50%)`,minWidth:18,height:18,px:a?.5:0,boxSizing:"border-box",borderRadius:9,bgcolor:"#fff",border:`1.5px solid ${e.color}`,color:e.color,fontSize:11,fontWeight:600,lineHeight:"15px",textAlign:"center",cursor:"pointer",opacity:a||l?1:0,textDecoration:"none"},children:a?i:"\u2212"}):null]},e.id)}),H&&m?.target?m.target.place==="child"?L(P,{sx:{position:"absolute",left:H.x-4,top:H.y-4,width:H.w+8,height:H.h+8,border:"2px dashed #1a73e8",borderRadius:2,pointerEvents:"none"}}):L(P,{sx:{position:"absolute",left:H.x,top:m.target.place==="before"?H.y-6:H.y+H.h+4,width:H.w,height:3,borderRadius:2,bgcolor:"#1a73e8",pointerEvents:"none"}}):null,V&&u?L("input",{"data-mm-edit":"",autoFocus:!0,value:u.text,spellCheck:!1,onFocus:e=>e.currentTarget.select(),onChange:e=>z({id:u.id,text:e.target.value}),onBlur:s,onKeyDown:e=>{if(e.stopPropagation(),!e.nativeEvent.isComposing){if(e.key==="Enter")e.preventDefault(),s();else if(e.key==="Escape")e.preventDefault(),z(null),f.current?.focus({preventScroll:!0});else if(e.key==="Tab"){e.preventDefault();let t=u.id,i=u.text;z(null);let a=ye(o,t,i);y(ae(a?.root??o,t),void 0,!0)}}},style:{position:"absolute",left:V.x,top:V.y,width:Math.max(V.w,Math.ceil(Ye(u.text||" ",V.fontSize,V.fontWeight))+40),height:V.h,boxSizing:"border-box",padding:"0 12px",border:"2px solid #1a73e8",borderRadius:8,outline:"none",textAlign:"center",fontFamily:he,fontSize:V.fontSize,fontWeight:V.fontWeight,color:"#1f2328",background:"#fff",zIndex:5}}):null]}),m&&oe?L(P,{sx:{position:"absolute",left:m.px+10,top:m.py+10,px:1.5,py:.5,borderRadius:2,bgcolor:"#fff",border:`1.5px solid ${oe.color}`,fontSize:13,opacity:.9,pointerEvents:"none",boxShadow:"0 4px 12px rgba(0,0,0,0.15)"},children:oe.node.topic||"\xA0"}):null,B&&!u&&!m&&!N?Q(P,{"data-mm-ui":"",sx:{position:"absolute",left:c.x+(B.x+B.w/2)*c.z,top:c.y+B.y*c.z,transform:"translate(-50%, calc(-100% - 8px))",display:"flex",gap:.25,p:.25,bgcolor:"#fff",border:"1px solid #e0e0e0",borderRadius:1,boxShadow:"0 2px 6px rgba(0,0,0,0.12)",zIndex:6},children:[Z("child",h.addChild,L(He,{}),()=>y(ae(o,B.id),void 0,!0)),B.depth>0?Z("sibling",h.addSibling,L(Ve,{}),()=>y(ge(o,B.id),void 0,!0)):null,Z("edit",h.edit,L(Pe,{}),()=>Y(B.id)),B.depth>0?Z("delete",h.remove,L(Oe,{}),()=>y(xe(o,B.id))):null]}):null,W?L(P,{sx:{position:"absolute",left:12,right:12,bottom:8,fontSize:12,lineHeight:1.5,color:"text.secondary",pointerEvents:"none"},children:L(P,{component:"span",sx:{bgcolor:"rgba(247,248,250,0.85)"},children:h.mapHint})}):null]})});import{outlinerStrings as _e}from"@ehfuse/outliner";var Me={ko:{map:"\uC9C0\uB3C4",outline:"\uBAA9\uB85D",addChild:"\uC544\uB798 \uAC00\uC9C0",addSibling:"\uC606 \uAC00\uC9C0",edit:"\uAE00 \uACE0\uCE58\uAE30",remove:"\uC9C0\uC6B0\uAE30",dirSide:"\uC591\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30",dirRight:"\uC624\uB978\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30",dirLeft:"\uC67C\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30",center:"\uAC00\uC6B4\uB370\uB85C",zoomIn:"\uD655\uB300",zoomOut:"\uCD95\uC18C",mapHint:"\uB450 \uBC88 \uD074\uB9AD: \uAE00 \uACE0\uCE58\uAE30 \xB7 Tab: \uC544\uB798 \uAC00\uC9C0 \xB7 Enter: \uC606 \uAC00\uC9C0 \xB7 \uAC00\uC9C0 \uB04C\uAE30: \uC62E\uAE30\uAE30 \xB7 \uBE48 \uACF3 \uB04C\uAE30: \uC774\uB3D9 \xB7 Ctrl+\uD720: \uD655\uB300",newTopic:"\uC0C8 \uAC00\uC9C0"},en:{map:"Map",outline:"List",addChild:"Child branch",addSibling:"Sibling branch",edit:"Edit text",remove:"Delete",dirSide:"Grow both ways",dirRight:"Grow to the right",dirLeft:"Grow to the left",center:"Center",zoomIn:"Zoom in",zoomOut:"Zoom out",mapHint:"Double-click: edit \xB7 Tab: child \xB7 Enter: sibling \xB7 Drag a branch: move \xB7 Drag empty space: pan \xB7 Ctrl+wheel: zoom",newTopic:"New branch"},ja:{map:"\u30DE\u30C3\u30D7",outline:"\u30EA\u30B9\u30C8",addChild:"\u4E0B\u306E\u679D",addSibling:"\u6A2A\u306E\u679D",edit:"\u6587\u5B57\u3092\u7DE8\u96C6",remove:"\u524A\u9664",dirSide:"\u4E21\u5074\u306B\u5E83\u3052\u308B",dirRight:"\u53F3\u306B\u5E83\u3052\u308B",dirLeft:"\u5DE6\u306B\u5E83\u3052\u308B",center:"\u4E2D\u592E\u3078",zoomIn:"\u62E1\u5927",zoomOut:"\u7E2E\u5C0F",mapHint:"\u30C0\u30D6\u30EB\u30AF\u30EA\u30C3\u30AF: \u7DE8\u96C6 \xB7 Tab: \u4E0B\u306E\u679D \xB7 Enter: \u6A2A\u306E\u679D \xB7 \u679D\u3092\u30C9\u30E9\u30C3\u30B0: \u79FB\u52D5 \xB7 \u7A7A\u767D\u30C9\u30E9\u30C3\u30B0: \u30B9\u30AF\u30ED\u30FC\u30EB \xB7 Ctrl+\u30DB\u30A4\u30FC\u30EB: \u62E1\u5927",newTopic:"\u65B0\u3057\u3044\u679D"},zh:{map:"\u5BFC\u56FE",outline:"\u5217\u8868",addChild:"\u5B50\u5206\u652F",addSibling:"\u540C\u7EA7\u5206\u652F",edit:"\u7F16\u8F91\u6587\u5B57",remove:"\u5220\u9664",dirSide:"\u4E24\u4FA7\u5C55\u5F00",dirRight:"\u5411\u53F3\u5C55\u5F00",dirLeft:"\u5411\u5DE6\u5C55\u5F00",center:"\u5C45\u4E2D",zoomIn:"\u653E\u5927",zoomOut:"\u7F29\u5C0F",mapHint:"\u53CC\u51FB: \u7F16\u8F91 \xB7 Tab: \u5B50\u5206\u652F \xB7 Enter: \u540C\u7EA7\u5206\u652F \xB7 \u62D6\u52A8\u5206\u652F: \u79FB\u52A8 \xB7 \u62D6\u52A8\u7A7A\u767D: \u5E73\u79FB \xB7 Ctrl+\u6EDA\u8F6E: \u7F29\u653E",newTopic:"\u65B0\u5206\u652F"},de:{map:"Karte",outline:"Liste",addChild:"Unterzweig",addSibling:"Nebenzweig",edit:"Text bearbeiten",remove:"L\xF6schen",dirSide:"Beidseitig",dirRight:"Nach rechts",dirLeft:"Nach links",center:"Zentrieren",zoomIn:"Vergr\xF6\xDFern",zoomOut:"Verkleinern",mapHint:"Doppelklick: bearbeiten \xB7 Tab: Unterzweig \xB7 Enter: Nebenzweig \xB7 Zweig ziehen: verschieben \xB7 Leere Fl\xE4che ziehen: schwenken \xB7 Strg+Rad: Zoom",newTopic:"Neuer Zweig"},fr:{map:"Carte",outline:"Liste",addChild:"Branche enfant",addSibling:"Branche s\u0153ur",edit:"Modifier le texte",remove:"Supprimer",dirSide:"Des deux c\xF4t\xE9s",dirRight:"Vers la droite",dirLeft:"Vers la gauche",center:"Centrer",zoomIn:"Zoomer",zoomOut:"D\xE9zoomer",mapHint:"Double-clic : modifier \xB7 Tab : enfant \xB7 Entr\xE9e : s\u0153ur \xB7 Glisser une branche : d\xE9placer \xB7 Glisser le vide : d\xE9filer \xB7 Ctrl+molette : zoom",newTopic:"Nouvelle branche"},it:{map:"Mappa",outline:"Elenco",addChild:"Ramo figlio",addSibling:"Ramo fratello",edit:"Modifica testo",remove:"Elimina",dirSide:"Su entrambi i lati",dirRight:"Verso destra",dirLeft:"Verso sinistra",center:"Centra",zoomIn:"Ingrandisci",zoomOut:"Riduci",mapHint:"Doppio clic: modifica \xB7 Tab: figlio \xB7 Invio: fratello \xB7 Trascina un ramo: sposta \xB7 Trascina il vuoto: scorri \xB7 Ctrl+rotella: zoom",newTopic:"Nuovo ramo"},vi:{map:"B\u1EA3n \u0111\u1ED3",outline:"Danh s\xE1ch",addChild:"Nh\xE1nh con",addSibling:"Nh\xE1nh ngang",edit:"S\u1EEDa ch\u1EEF",remove:"X\xF3a",dirSide:"M\u1EDF hai b\xEAn",dirRight:"M\u1EDF sang ph\u1EA3i",dirLeft:"M\u1EDF sang tr\xE1i",center:"V\u1EC1 gi\u1EEFa",zoomIn:"Ph\xF3ng to",zoomOut:"Thu nh\u1ECF",mapHint:"Nh\u1EA5p \u0111\xFAp: s\u1EEDa \xB7 Tab: nh\xE1nh con \xB7 Enter: nh\xE1nh ngang \xB7 K\xE9o nh\xE1nh: di chuy\u1EC3n \xB7 K\xE9o ch\u1ED7 tr\u1ED1ng: cu\u1ED9n \xB7 Ctrl+cu\u1ED9n: ph\xF3ng to",newTopic:"Nh\xE1nh m\u1EDBi"}};function le(d,o){let p=(d??"en").slice(0,2).toLowerCase();return{..._e(d),...Me[p]??Me.en,...o}}import{DEFAULT_FONT_FAMILY as we}from"@ehfuse/outliner";var ee=d=>d.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");function ce(d,o={}){let p=o.padding??24,b=K(d.nodeData,d.direction??2),{minX:g,minY:M,maxX:h,maxY:N}=b.bounds,D=Math.ceil(h-g+p*2),I=Math.ceil(N-M+p*2),W=p-g,A=p-M,f=[];f.push(`<rect width="${D}" height="${I}" fill="${o.background??"#ffffff"}"/>`),f.push(`<g transform="translate(${W} ${A})">`);for(let n of b.edges)f.push(`<path d="${U(n)}" fill="none" stroke="${n.color}" stroke-width="${n.to.depth===1?2.5:1.75}" stroke-linecap="round"/>`);for(let n of b.nodes){let E=_(n);f.push(`<rect x="${n.x}" y="${n.y}" width="${n.w}" height="${n.h}" rx="${E.radius}" fill="${E.fill}"${E.stroke!=="none"?` stroke="${E.stroke}" stroke-width="${E.strokeWidth}"`:""}/>`);let c=n.node.style?.textDecoration;if(f.push(`<text x="${n.x+n.w/2}" y="${n.y+n.h/2}" text-anchor="middle" dominant-baseline="central" font-family="${ee(we)}" font-size="${n.fontSize}" font-weight="${n.fontWeight}" fill="${E.text}"${c?` text-decoration="${ee(c)}"`:""}>${ee(n.node.topic)}</text>`),n.node.expanded===!1&&(n.node.children?.length??0)>0&&n.depth>0){let r=n.side>0?n.x+n.w+10:n.x-10,x=n.y+n.h/2;f.push(`<circle cx="${r}" cy="${x}" r="9" fill="#ffffff" stroke="${n.color}" stroke-width="1.5"/>`),f.push(`<text x="${r}" y="${x}" text-anchor="middle" dominant-baseline="central" font-family="${ee(we)}" font-size="10" fill="${n.color}">${n.node.children.length}</text>`)}}return f.push("</g>"),`<svg xmlns="http://www.w3.org/2000/svg" width="${D}" height="${I}" viewBox="0 0 ${D} ${I}">${f.join("")}</svg>`}import{Fragment as Te,jsx as T,jsxs as pe}from"react/jsx-runtime";var ct=[{value:2,key:"dirSide",icon:T(Je,{})},{value:1,key:"dirRight",icon:T(et,{})},{value:0,key:"dirLeft",icon:T(Qe,{})}],pt=Ge(function({value:o,onChange:p,locale:b,strings:g,readOnly:M,view:h,defaultView:N="map",onViewChange:D,toolbarEnd:I,hint:W=!0,height:A="100%"},f){let n=le(b,g),[E,c]=Se(N),r=h??E,x=s=>{c(s),D?.(s),s==="map"&&requestAnimationFrame(()=>v.current?.center())},[u,z]=Se(null),m=lt(),v=qe(null),S=o.nodeData,w=o.direction??2,k=(s,C)=>{m.record(S,C),p({...o,nodeData:s})},R=()=>{let s=m.undo(S);s&&p({...o,nodeData:s})},$=()=>{let s=m.redo(S);s&&p({...o,nodeData:s})};Ze(f,()=>({exportSvg:()=>ce(o),center:()=>v.current?.center()}),[o]);let y=u?dt(S,u)?.node:void 0,Y=T(G,{sx:{display:"flex",p:.25,borderRadius:1,bgcolor:"#f1f3f4"},children:["map","outline"].map(s=>T(je,{"aria-pressed":r===s,onClick:()=>x(s),sx:{height:26,px:1.25,borderRadius:.75,fontSize:13,fontWeight:r===s?600:400,color:r===s?"primary.main":"text.secondary",bgcolor:r===s?"#fff":"transparent",boxShadow:r===s?"0 1px 2px rgba(0,0,0,0.15)":"none"},children:s==="map"?n.map:n.outline},s))});return pe(G,{sx:{display:"flex",flexDirection:"column",height:A,minHeight:0,bgcolor:"#fff"},children:[T(it,{strings:n,style:y?y.style??{}:void 0,onStyle:s=>{if(!u)return;let C=st(S,[u],s);C&&k(C.root)},canUndo:m.canUndo,canRedo:m.canRedo,onUndo:R,onRedo:$,start:Y,end:I,readOnly:M,children:r==="map"?pe(Te,{children:[ct.map(s=>T(te,{label:n[s.key],active:w===s.value,disabled:M,onClick:()=>p({...o,direction:s.value}),children:s.icon},s.value)),T(at,{}),T(te,{label:n.zoomOut,onClick:()=>v.current?.zoomBy(1/1.2),children:T(nt,{})}),T(te,{label:n.zoomIn,onClick:()=>v.current?.zoomBy(1.2),children:T(ot,{})}),T(te,{label:n.center,onClick:()=>v.current?.center(),children:T(tt,{})})]}):null}),T(G,{sx:{position:"relative",flex:1,minHeight:0},children:r==="map"?T(se,{ref:v,root:S,direction:w,onEdit:k,selectedId:u,onSelect:z,strings:n,readOnly:M,onUndo:R,onRedo:$,hint:W}):pe(Te,{children:[T(rt,{root:S,onEdit:k,selectedId:u,onSelect:z,strings:n,readOnly:M,onUndo:R,onRedo:$}),W?T(G,{sx:{position:"absolute",left:12,right:12,bottom:8,fontSize:12,lineHeight:1.5,color:"text.secondary",pointerEvents:"none"},children:T(G,{component:"span",sx:{bgcolor:"rgba(255,255,255,0.9)"},children:n.hint})}):null]})})]})});import{createTree as Yt}from"@ehfuse/outliner";export{re as BRANCH_COLORS,se as MapView,pt as MindMap,Yt as createTree,U as edgePath,ce as exportMindMapSvg,K as layoutMap,le as mindMapStrings,_ as nodeLook,q as nodeSize};
|
|
2
2
|
//# sourceMappingURL=index.esm.js.map
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/MindMap.tsx", "../src/MapView.tsx", "../src/layout.ts", "../src/i18n.ts", "../src/exportSvg.ts", "../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * MindMap \u2014 one tree shown as a map or as a list (outline), with one formatting toolbar for both.\n * Controlled: pass `value` and `onChange`. Undo history lives inside (map and list share it).\n */\nimport { forwardRef, useImperativeHandle, useRef, useState, type ReactNode } from \"react\";\nimport { Box, ButtonBase } from \"@mui/material\";\nimport SwapHorizIcon from \"@mui/icons-material/SwapHoriz\";\nimport EastIcon from \"@mui/icons-material/East\";\nimport WestIcon from \"@mui/icons-material/West\";\nimport CenterFocusStrongOutlinedIcon from \"@mui/icons-material/CenterFocusStrongOutlined\";\nimport ZoomInIcon from \"@mui/icons-material/ZoomIn\";\nimport ZoomOutIcon from \"@mui/icons-material/ZoomOut\";\nimport { FormatToolbar, OutlineList, ToolButton, ToolDivider, locateNode, setNodeStyle, useTreeHistory, type TreeNode } from \"@ehfuse/outliner\";\nimport { MapView, type MapViewHandle } from \"./MapView\";\nimport { mindMapStrings, type MindMapStrings } from \"./i18n\";\nimport type { MapDirection } from \"./layout\";\nimport type { MindMapData, MindMapView } from \"./types\";\nimport { exportMindMapSvg } from \"./exportSvg\";\n\nexport interface MindMapProps {\n value: MindMapData;\n onChange: (value: MindMapData) => void;\n locale?: string;\n strings?: Partial<MindMapStrings>;\n readOnly?: boolean;\n /** Controlled view; or use `defaultView`. */\n view?: MindMapView;\n defaultView?: MindMapView;\n onViewChange?: (view: MindMapView) => void;\n /** Extra controls at the right end of the toolbar. */\n toolbarEnd?: ReactNode;\n /** Show the one-line help at the bottom (default true). */\n hint?: boolean;\n height?: number | string;\n}\n\nexport interface MindMapHandle {\n exportSvg: () => string;\n center: () => void;\n}\n\nconst DIRECTIONS: Array<{ value: MapDirection; key: \"dirSide\" | \"dirRight\" | \"dirLeft\"; icon: ReactNode }> = [\n { value: 2, key: \"dirSide\", icon: <SwapHorizIcon sx={{ fontSize: 19 }} /> },\n { value: 1, key: \"dirRight\", icon: <EastIcon sx={{ fontSize: 18 }} /> },\n { value: 0, key: \"dirLeft\", icon: <WestIcon sx={{ fontSize: 18 }} /> },\n];\n\nexport const MindMap = forwardRef<MindMapHandle, MindMapProps>(function MindMap(\n { value, onChange, locale, strings: overrides, readOnly, view: viewProp, defaultView = \"map\", onViewChange, toolbarEnd, hint = true, height = \"100%\" },\n ref\n) {\n const strings = mindMapStrings(locale, overrides);\n const [ownView, setOwnView] = useState<MindMapView>(defaultView);\n const view = viewProp ?? ownView;\n const setView = (next: MindMapView) => {\n setOwnView(next);\n onViewChange?.(next);\n if (next === \"map\") requestAnimationFrame(() => mapRef.current?.center());\n };\n const [selected, setSelected] = useState<string | null>(null);\n const history = useTreeHistory();\n const mapRef = useRef<MapViewHandle | null>(null);\n const root = value.nodeData;\n const direction = (value.direction ?? 2) as MapDirection;\n\n const commit = (next: TreeNode, mergeKey?: string) => {\n history.record(root, mergeKey);\n onChange({ ...value, nodeData: next });\n };\n const undo = () => {\n const prev = history.undo(root);\n if (prev) onChange({ ...value, nodeData: prev });\n };\n const redo = () => {\n const next = history.redo(root);\n if (next) onChange({ ...value, nodeData: next });\n };\n useImperativeHandle(ref, () => ({ exportSvg: () => exportMindMapSvg(value), center: () => mapRef.current?.center() }), [value]);\n\n const selectedNode = selected ? locateNode(root, selected)?.node : undefined;\n const viewSwitch = (\n <Box sx={{ display: \"flex\", p: 0.25, borderRadius: 1, bgcolor: \"#f1f3f4\" }}>\n {([\"map\", \"outline\"] as const).map((item) => (\n <ButtonBase\n key={item}\n aria-pressed={view === item}\n onClick={() => setView(item)}\n sx={{\n height: 26,\n px: 1.25,\n borderRadius: 0.75,\n fontSize: 13,\n fontWeight: view === item ? 600 : 400,\n color: view === item ? \"primary.main\" : \"text.secondary\",\n bgcolor: view === item ? \"#fff\" : \"transparent\",\n boxShadow: view === item ? \"0 1px 2px rgba(0,0,0,0.15)\" : \"none\",\n }}\n >\n {item === \"map\" ? strings.map : strings.outline}\n </ButtonBase>\n ))}\n </Box>\n );\n\n return (\n <Box sx={{ display: \"flex\", flexDirection: \"column\", height, minHeight: 0, bgcolor: \"#fff\" }}>\n <FormatToolbar\n strings={strings}\n style={selectedNode ? (selectedNode.style ?? {}) : undefined}\n onStyle={(patch) => {\n if (!selected) return;\n const result = setNodeStyle(root, [selected], patch);\n if (result) commit(result.root);\n }}\n canUndo={history.canUndo}\n canRedo={history.canRedo}\n onUndo={undo}\n onRedo={redo}\n start={viewSwitch}\n end={toolbarEnd}\n readOnly={readOnly}\n >\n {view === \"map\" ? (\n <>\n {DIRECTIONS.map((item) => (\n <ToolButton key={item.value} label={strings[item.key]} active={direction === item.value} disabled={readOnly} onClick={() => onChange({ ...value, direction: item.value })}>\n {item.icon}\n </ToolButton>\n ))}\n <ToolDivider />\n <ToolButton label={strings.zoomOut} onClick={() => mapRef.current?.zoomBy(1 / 1.2)}>\n <ZoomOutIcon sx={{ fontSize: 19 }} />\n </ToolButton>\n <ToolButton label={strings.zoomIn} onClick={() => mapRef.current?.zoomBy(1.2)}>\n <ZoomInIcon sx={{ fontSize: 19 }} />\n </ToolButton>\n <ToolButton label={strings.center} onClick={() => mapRef.current?.center()}>\n <CenterFocusStrongOutlinedIcon sx={{ fontSize: 18 }} />\n </ToolButton>\n </>\n ) : null}\n </FormatToolbar>\n <Box sx={{ position: \"relative\", flex: 1, minHeight: 0 }}>\n {view === \"map\" ? (\n <MapView ref={mapRef} root={root} direction={direction} onEdit={commit} selectedId={selected} onSelect={setSelected} strings={strings} readOnly={readOnly} onUndo={undo} onRedo={redo} hint={hint} />\n ) : (\n <>\n <OutlineList root={root} onEdit={commit} selectedId={selected} onSelect={setSelected} strings={strings} readOnly={readOnly} onUndo={undo} onRedo={redo} />\n {hint ? (\n <Box sx={{ position: \"absolute\", left: 12, right: 12, bottom: 8, fontSize: 12, lineHeight: 1.5, color: \"text.secondary\", pointerEvents: \"none\" }}>\n <Box component=\"span\" sx={{ bgcolor: \"rgba(255,255,255,0.9)\" }}>\n {strings.hint}\n </Box>\n </Box>\n ) : null}\n </>\n )}\n </Box>\n </Box>\n );\n});\n", "/**\n * Map view \u2014 draws the tree as a mind map and edits it in place.\n *\n * Mouse: click to select \u00B7 double-click to edit \u00B7 drag a branch onto another (middle = into it, top / bottom edge = before / after)\n * \u00B7 drag empty space to pan \u00B7 Ctrl/\u2318 + wheel to zoom (a plain wheel scrolls the page, not the map).\n * Keys (map focused): Tab child \u00B7 Enter sibling \u00B7 F2 edit \u00B7 Delete / Backspace remove \u00B7 Space fold \u00B7 arrows move the selection \u00B7\n * Ctrl/\u2318+Z undo \u00B7 Ctrl/\u2318+Shift+Z / Ctrl+Y redo.\n */\nimport { forwardRef, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, type KeyboardEvent, type PointerEvent } from \"react\";\nimport { Box, IconButton, Tooltip } from \"@mui/material\";\nimport SubdirectoryArrowRightIcon from \"@mui/icons-material/SubdirectoryArrowRight\";\nimport AddIcon from \"@mui/icons-material/Add\";\nimport EditOutlinedIcon from \"@mui/icons-material/EditOutlined\";\nimport DeleteOutlineIcon from \"@mui/icons-material/DeleteOutline\";\nimport {\n DEFAULT_FONT_FAMILY,\n addChild,\n addSibling,\n containsNode,\n locateNode,\n measureText,\n moveNode,\n removeNode,\n setTopic,\n toggleFold,\n type TreeEdit,\n type TreeNode,\n} from \"@ehfuse/outliner\";\nimport { edgePath, layoutMap, nodeLook, type LayoutNode, type MapDirection } from \"./layout\";\nimport type { MindMapStrings } from \"./i18n\";\n\nexport interface MapViewHandle {\n center: () => void;\n zoomBy: (factor: number) => void;\n}\n\nexport interface MapViewProps {\n root: TreeNode;\n direction: MapDirection;\n onEdit: (root: TreeNode, mergeKey?: string) => void;\n selectedId: string | null;\n onSelect: (id: string | null) => void;\n strings: MindMapStrings;\n readOnly?: boolean;\n onUndo?: () => void;\n onRedo?: () => void;\n /** Show the one-line help at the bottom (default true). */\n hint?: boolean;\n}\n\nconst ZOOM_MIN = 0.3;\nconst ZOOM_MAX = 2.5;\nconst DRAG_START = 5;\n\ntype DropPlace = \"before\" | \"after\" | \"child\";\n\nexport const MapView = forwardRef<MapViewHandle, MapViewProps>(function MapView({ root, direction, onEdit, selectedId, onSelect, strings, readOnly, onUndo, onRedo, hint = true }, ref) {\n const boxRef = useRef<HTMLDivElement | null>(null);\n const [size, setSize] = useState({ w: 0, h: 0 });\n const [view, setView] = useState({ x: 0, y: 0, z: 1 });\n const viewRef = useRef(view);\n viewRef.current = view;\n const [editing, setEditing] = useState<{ id: string; text: string } | null>(null);\n const [drag, setDrag] = useState<{ id: string; px: number; py: number; target: { id: string; place: DropPlace } | null } | null>(null);\n const pointer = useRef<{ kind: \"pan\" | \"node\"; id?: string; sx: number; sy: number; vx: number; vy: number; moved: boolean } | null>(null);\n const layout = useMemo(() => layoutMap(root, direction), [root, direction]);\n\n // Size \u2014 center the map the first time the box has a size.\n const centered = useRef(false);\n useLayoutEffect(() => {\n const el = boxRef.current;\n if (!el) return;\n const ro = new ResizeObserver(() => setSize({ w: el.clientWidth, h: el.clientHeight }));\n ro.observe(el);\n setSize({ w: el.clientWidth, h: el.clientHeight });\n return () => ro.disconnect();\n }, []);\n const center = useCallback(() => {\n const { minX, minY, maxX, maxY } = layout.bounds;\n const z = viewRef.current.z;\n setView({ x: size.w / 2 - ((minX + maxX) / 2) * z, y: size.h / 2 - ((minY + maxY) / 2) * z, z });\n }, [layout, size]);\n useEffect(() => {\n if (centered.current || size.w === 0) return;\n centered.current = true;\n center();\n }, [size, center]);\n const zoomAt = useCallback((factor: number, cx: number, cy: number) => {\n setView((v) => {\n const z = Math.min(ZOOM_MAX, Math.max(ZOOM_MIN, v.z * factor));\n return { x: cx - (cx - v.x) * (z / v.z), y: cy - (cy - v.y) * (z / v.z), z };\n });\n }, []);\n useImperativeHandle(ref, () => ({ center, zoomBy: (factor) => zoomAt(factor, size.w / 2, size.h / 2) }), [center, zoomAt, size]);\n\n // Ctrl/\u2318 + wheel zooms at the cursor; a plain wheel is left to the page (it must not pan the map).\n useEffect(() => {\n const el = boxRef.current;\n if (!el) return;\n const onWheel = (event: WheelEvent) => {\n if (!(event.ctrlKey || event.metaKey)) return;\n event.preventDefault();\n const r = el.getBoundingClientRect();\n zoomAt(event.deltaY < 0 ? 1.1 : 1 / 1.1, event.clientX - r.left, event.clientY - r.top);\n };\n el.addEventListener(\"wheel\", onWheel, { passive: false });\n return () => el.removeEventListener(\"wheel\", onWheel);\n }, [zoomAt]);\n\n const apply = (result: TreeEdit | null, mergeKey?: string, editNew = false) => {\n if (!result) return;\n onEdit(result.root, mergeKey);\n if (result.focusId) {\n onSelect(result.focusId);\n if (editNew) setEditing({ id: result.focusId, text: \"\" });\n }\n };\n const startEdit = (id: string) => {\n if (readOnly) return;\n const at = locateNode(root, id);\n if (at) setEditing({ id, text: at.node.topic });\n };\n const commitEdit = () => {\n if (!editing) return;\n apply(setTopic(root, editing.id, editing.text));\n setEditing(null);\n boxRef.current?.focus({ preventScroll: true });\n };\n\n const toCanvas = (clientX: number, clientY: number) => {\n const r = boxRef.current!.getBoundingClientRect();\n return { x: (clientX - r.left - view.x) / view.z, y: (clientY - r.top - view.y) / view.z };\n };\n const dropAt = (clientX: number, clientY: number, dragged: TreeNode): { id: string; place: DropPlace } | null => {\n const p = toCanvas(clientX, clientY);\n for (const ln of layout.nodes) {\n if (p.x < ln.x - 4 || p.x > ln.x + ln.w + 4 || p.y < ln.y - 4 || p.y > ln.y + ln.h + 4) continue;\n if (containsNode(dragged, ln.id)) return null;\n if (ln.depth === 0) return { id: ln.id, place: \"child\" };\n const rel = (p.y - ln.y) / ln.h;\n return { id: ln.id, place: rel < 0.25 ? \"before\" : rel > 0.75 ? \"after\" : \"child\" };\n }\n return null;\n };\n\n const onPointerDown = (event: PointerEvent<HTMLDivElement>) => {\n if (event.button !== 0) return;\n const target = event.target as HTMLElement;\n if (target.closest(\"[data-mm-ui]\")) return;\n if (editing && !target.closest(\"[data-mm-edit]\")) commitEdit();\n if (target.closest(\"[data-mm-edit]\")) return;\n const fold = target.closest(\"[data-mm-fold]\") as HTMLElement | null;\n if (fold) {\n apply(toggleFold(root, fold.dataset.mmFold!));\n return;\n }\n const nodeEl = target.closest(\"[data-mm-node]\") as HTMLElement | null;\n boxRef.current?.focus({ preventScroll: true });\n // Capture the pointer only once a drag starts \u2014 capturing on press retargets the double-click to the box, so editing never opened.\n if (nodeEl) {\n const id = nodeEl.dataset.mmNode!;\n onSelect(id);\n pointer.current = { kind: \"node\", id, sx: event.clientX, sy: event.clientY, vx: view.x, vy: view.y, moved: false };\n } else {\n onSelect(null);\n pointer.current = { kind: \"pan\", sx: event.clientX, sy: event.clientY, vx: view.x, vy: view.y, moved: false };\n }\n };\n const onPointerMove = (event: PointerEvent<HTMLDivElement>) => {\n const p = pointer.current;\n if (!p) return;\n const dx = event.clientX - p.sx;\n const dy = event.clientY - p.sy;\n if (!p.moved && Math.hypot(dx, dy) < DRAG_START) return;\n if (!p.moved && !boxRef.current?.hasPointerCapture(event.pointerId)) boxRef.current?.setPointerCapture(event.pointerId);\n p.moved = true;\n if (p.kind === \"pan\") {\n setView((v) => ({ ...v, x: p.vx + dx, y: p.vy + dy }));\n return;\n }\n if (readOnly || p.id === root.id) return;\n const dragged = locateNode(root, p.id!)?.node;\n if (!dragged) return;\n const r = boxRef.current!.getBoundingClientRect();\n setDrag({ id: p.id!, px: event.clientX - r.left, py: event.clientY - r.top, target: dropAt(event.clientX, event.clientY, dragged) });\n };\n const onPointerUp = (event: PointerEvent<HTMLDivElement>) => {\n const p = pointer.current;\n pointer.current = null;\n if (boxRef.current?.hasPointerCapture(event.pointerId)) boxRef.current.releasePointerCapture(event.pointerId);\n if (p?.kind === \"node\" && drag?.target) apply(moveNode(root, drag.id, drag.target.id, drag.target.place));\n setDrag(null);\n };\n\n const neighbor = (ln: LayoutNode, key: string): string | null => {\n const at = locateNode(root, ln.id);\n if (!at) return null;\n if (key === \"ArrowUp\" || key === \"ArrowDown\") {\n if (!at.parent) return null;\n const sibs = (at.parent.children ?? []).filter((kid) => layout.byId.get(kid.id)?.side === ln.side);\n const i = sibs.findIndex((kid) => kid.id === ln.id);\n return sibs[i + (key === \"ArrowUp\" ? -1 : 1)]?.id ?? null;\n }\n const outward = (key === \"ArrowRight\" && ln.side >= 0) || (key === \"ArrowLeft\" && ln.side <= 0);\n if (outward) {\n const kids = at.node.expanded === false ? [] : (at.node.children ?? []);\n const want = ln.side === 0 ? (key === \"ArrowRight\" ? 1 : -1) : ln.side;\n return kids.find((kid) => layout.byId.get(kid.id)?.side === want)?.id ?? null;\n }\n return ln.parentId;\n };\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (editing || (event.target as HTMLElement).tagName === \"INPUT\") return;\n const mod = event.ctrlKey || event.metaKey;\n if (mod && (event.key === \"z\" || event.key === \"Z\")) {\n event.preventDefault();\n if (event.shiftKey) onRedo?.();\n else onUndo?.();\n return;\n }\n if (mod && (event.key === \"y\" || event.key === \"Y\")) {\n event.preventDefault();\n onRedo?.();\n return;\n }\n const ln = selectedId ? layout.byId.get(selectedId) : null;\n if (!ln) return;\n if (event.key.startsWith(\"Arrow\")) {\n const next = neighbor(ln, event.key);\n event.preventDefault();\n if (next) onSelect(next);\n return;\n }\n if (readOnly) return;\n if (event.key === \"Tab\") {\n event.preventDefault();\n apply(addChild(root, ln.id), undefined, true);\n } else if (event.key === \"Enter\") {\n event.preventDefault();\n apply(addSibling(root, ln.id), undefined, true);\n } else if (event.key === \"F2\") {\n event.preventDefault();\n startEdit(ln.id);\n } else if (event.key === \"Delete\" || event.key === \"Backspace\") {\n event.preventDefault();\n apply(removeNode(root, ln.id));\n } else if (event.key === \" \") {\n event.preventDefault();\n apply(toggleFold(root, ln.id));\n }\n };\n\n const selected = selectedId ? layout.byId.get(selectedId) : undefined;\n const editingLN = editing ? layout.byId.get(editing.id) : undefined;\n const dragLN = drag ? layout.byId.get(drag.id) : undefined;\n const dropLN = drag?.target ? layout.byId.get(drag.target.id) : undefined;\n const barButton = (key: string, label: string, icon: React.ReactNode, onClick: () => void) => (\n <Tooltip key={key} title={label} disableInteractive>\n <IconButton size=\"small\" aria-label={label} onMouseDown={(event) => event.preventDefault()} onClick={onClick} sx={{ width: 28, height: 28, color: \"text.secondary\", \"&:hover\": { color: \"primary.main\" } }}>\n {icon}\n </IconButton>\n </Tooltip>\n );\n\n return (\n <Box\n ref={boxRef}\n tabIndex={0}\n onKeyDown={onKeyDown}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerUp}\n onDoubleClick={(event) => {\n const nodeEl = (event.target as HTMLElement).closest(\"[data-mm-node]\") as HTMLElement | null;\n if (nodeEl) startEdit(nodeEl.dataset.mmNode!);\n }}\n sx={{ position: \"relative\", width: \"100%\", height: \"100%\", overflow: \"hidden\", bgcolor: \"#f7f8fa\", outline: \"none\", touchAction: \"none\", userSelect: \"none\", cursor: pointer.current?.kind === \"pan\" ? \"grabbing\" : \"default\" }}\n >\n <Box sx={{ position: \"absolute\", left: 0, top: 0, transform: `translate(${view.x}px, ${view.y}px) scale(${view.z})`, transformOrigin: \"0 0\" }}>\n <svg style={{ position: \"absolute\", left: 0, top: 0, width: 1, height: 1, overflow: \"visible\" }}>\n {layout.edges.map((edge) => (\n <path key={edge.to.id} d={edgePath(edge)} fill=\"none\" stroke={edge.color} strokeWidth={edge.to.depth === 1 ? 2.5 : 1.75} strokeLinecap=\"round\" />\n ))}\n </svg>\n {layout.nodes.map((ln) => {\n const look = nodeLook(ln);\n const kids = ln.node.children?.length ?? 0;\n const folded = ln.node.expanded === false && kids > 0;\n const isSel = ln.id === selectedId;\n return (\n <Box\n key={ln.id}\n data-mm-node={ln.id}\n sx={{\n position: \"absolute\",\n left: ln.x,\n top: ln.y,\n width: ln.w,\n height: ln.h,\n boxSizing: \"border-box\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: `${look.radius}px`,\n bgcolor: look.fill,\n border: look.stroke !== \"none\" ? `${look.strokeWidth}px solid ${look.stroke}` : 0,\n color: look.text,\n fontFamily: DEFAULT_FONT_FAMILY,\n fontSize: ln.fontSize,\n fontWeight: ln.fontWeight,\n textDecoration: ln.node.style?.textDecoration,\n whiteSpace: \"nowrap\",\n cursor: readOnly ? \"default\" : \"pointer\",\n boxShadow: isSel ? \"0 0 0 2px #fff, 0 0 0 4px #1a73e8\" : ln.depth === 0 ? \"0 2px 6px rgba(0,0,0,0.18)\" : \"none\",\n opacity: drag?.id === ln.id ? 0.35 : 1,\n \"&:hover .mm-fold\": { opacity: 1 },\n }}\n >\n {editing?.id === ln.id ? null : ln.node.topic || \"\u00A0\"}\n {kids > 0 && ln.depth > 0 ? (\n <Box\n className=\"mm-fold\"\n data-mm-fold={ln.id}\n title={folded ? strings.unfold : strings.fold}\n sx={{\n position: \"absolute\",\n top: \"50%\",\n [ln.side > 0 ? \"left\" : \"right\"]: \"100%\",\n transform: `translate(${ln.side > 0 ? 4 : -4}px, -50%)`,\n minWidth: 18,\n height: 18,\n px: folded ? 0.5 : 0,\n boxSizing: \"border-box\",\n borderRadius: 9,\n bgcolor: \"#fff\",\n border: `1.5px solid ${ln.color}`,\n color: ln.color,\n fontSize: 11,\n fontWeight: 600,\n lineHeight: \"15px\",\n textAlign: \"center\",\n cursor: \"pointer\",\n opacity: folded || isSel ? 1 : 0,\n textDecoration: \"none\",\n }}\n >\n {folded ? kids : \"\u2212\"}\n </Box>\n ) : null}\n </Box>\n );\n })}\n {/* Drop target \u2014 into (outline) or before / after (line). */}\n {dropLN && drag?.target ? (\n drag.target.place === \"child\" ? (\n <Box sx={{ position: \"absolute\", left: dropLN.x - 4, top: dropLN.y - 4, width: dropLN.w + 8, height: dropLN.h + 8, border: \"2px dashed #1a73e8\", borderRadius: 2, pointerEvents: \"none\" }} />\n ) : (\n <Box sx={{ position: \"absolute\", left: dropLN.x, top: drag.target.place === \"before\" ? dropLN.y - 6 : dropLN.y + dropLN.h + 4, width: dropLN.w, height: 3, borderRadius: 2, bgcolor: \"#1a73e8\", pointerEvents: \"none\" }} />\n )\n ) : null}\n {editingLN && editing ? (\n <input\n data-mm-edit=\"\"\n autoFocus\n value={editing.text}\n spellCheck={false}\n onFocus={(event) => event.currentTarget.select()}\n onChange={(event) => setEditing({ id: editing.id, text: event.target.value })}\n onBlur={commitEdit}\n onKeyDown={(event) => {\n event.stopPropagation();\n if (event.nativeEvent.isComposing) return;\n if (event.key === \"Enter\") {\n event.preventDefault();\n commitEdit();\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n setEditing(null);\n boxRef.current?.focus({ preventScroll: true });\n } else if (event.key === \"Tab\") {\n event.preventDefault();\n const id = editing.id;\n const text = editing.text;\n setEditing(null);\n const named = setTopic(root, id, text);\n apply(addChild(named?.root ?? root, id), undefined, true);\n }\n }}\n style={{\n position: \"absolute\",\n left: editingLN.x,\n top: editingLN.y,\n width: Math.max(editingLN.w, Math.ceil(measureText(editing.text || \" \", editingLN.fontSize, editingLN.fontWeight)) + 40),\n height: editingLN.h,\n boxSizing: \"border-box\",\n padding: \"0 12px\",\n border: \"2px solid #1a73e8\",\n borderRadius: 8,\n outline: \"none\",\n textAlign: \"center\",\n fontFamily: DEFAULT_FONT_FAMILY,\n fontSize: editingLN.fontSize,\n fontWeight: editingLN.fontWeight,\n color: \"#1f2328\",\n background: \"#fff\",\n zIndex: 5,\n }}\n />\n ) : null}\n </Box>\n {/* Dragged branch follows the pointer. */}\n {drag && dragLN ? (\n <Box sx={{ position: \"absolute\", left: drag.px + 10, top: drag.py + 10, px: 1.5, py: 0.5, borderRadius: 2, bgcolor: \"#fff\", border: `1.5px solid ${dragLN.color}`, fontSize: 13, opacity: 0.9, pointerEvents: \"none\", boxShadow: \"0 4px 12px rgba(0,0,0,0.15)\" }}>\n {dragLN.node.topic || \"\u00A0\"}\n </Box>\n ) : null}\n {/* Buttons above the selected branch \u2014 growing the map without knowing the keys. */}\n {selected && !editing && !drag && !readOnly ? (\n <Box\n data-mm-ui=\"\"\n sx={{\n position: \"absolute\",\n left: view.x + (selected.x + selected.w / 2) * view.z,\n top: view.y + selected.y * view.z,\n transform: \"translate(-50%, calc(-100% - 8px))\",\n display: \"flex\",\n gap: 0.25,\n p: 0.25,\n bgcolor: \"#fff\",\n border: \"1px solid #e0e0e0\",\n borderRadius: 1,\n boxShadow: \"0 2px 6px rgba(0,0,0,0.12)\",\n zIndex: 6,\n }}\n >\n {barButton(\"child\", strings.addChild, <SubdirectoryArrowRightIcon sx={{ fontSize: 18 }} />, () => apply(addChild(root, selected.id), undefined, true))}\n {selected.depth > 0 ? barButton(\"sibling\", strings.addSibling, <AddIcon sx={{ fontSize: 18 }} />, () => apply(addSibling(root, selected.id), undefined, true)) : null}\n {barButton(\"edit\", strings.edit, <EditOutlinedIcon sx={{ fontSize: 17 }} />, () => startEdit(selected.id))}\n {selected.depth > 0 ? barButton(\"delete\", strings.remove, <DeleteOutlineIcon sx={{ fontSize: 18 }} />, () => apply(removeNode(root, selected.id))) : null}\n </Box>\n ) : null}\n {hint ? (\n <Box sx={{ position: \"absolute\", left: 12, right: 12, bottom: 8, fontSize: 12, lineHeight: 1.5, color: \"text.secondary\", pointerEvents: \"none\" }}>\n <Box component=\"span\" sx={{ bgcolor: \"rgba(247,248,250,0.85)\" }}>\n {strings.mapHint}\n </Box>\n </Box>\n ) : null}\n </Box>\n );\n});\n", "/**\n * Map layout \u2014 root in the middle, branches to the right / left / both sides.\n * Node sizes come from measured text (no DOM pass), so layout is a pure function of the data.\n */\nimport { measureText, type TreeNode } from \"@ehfuse/outliner\";\n\n/** 0 = left, 1 = right, 2 = both sides (same values as Mind Elixir). */\nexport type MapDirection = 0 | 1 | 2;\n\nexport interface LayoutNode {\n id: string;\n node: TreeNode;\n depth: number;\n x: number;\n y: number;\n w: number;\n h: number;\n /** 1 = grows to the right, -1 = to the left, 0 = root. */\n side: 1 | -1 | 0;\n color: string;\n parentId: string | null;\n fontSize: number;\n fontWeight: string;\n}\n\nexport interface LayoutEdge {\n from: LayoutNode;\n to: LayoutNode;\n color: string;\n}\n\nexport interface MapLayout {\n nodes: LayoutNode[];\n byId: Map<string, LayoutNode>;\n edges: LayoutEdge[];\n bounds: { minX: number; minY: number; maxX: number; maxY: number };\n}\n\nexport const BRANCH_COLORS = [\"#e8710a\", \"#1a73e8\", \"#188038\", \"#d93025\", \"#9334e6\", \"#f9ab00\", \"#12b5cb\", \"#c2185b\"];\nconst H_GAP_ROOT = 64;\nconst H_GAP = 40;\nconst V_GAP = 14;\n\n/** Default text size / weight by depth (a node's own style wins). */\nexport function nodeFont(node: TreeNode, depth: number) {\n const fontSize = node.style?.fontSize ? parseFloat(node.style.fontSize) : depth === 0 ? 22 : depth === 1 ? 16 : 14;\n const fontWeight = node.style?.fontWeight ?? (depth === 0 ? \"700\" : depth === 1 ? \"500\" : \"400\");\n return { fontSize, fontWeight };\n}\n\nexport function nodeSize(node: TreeNode, depth: number) {\n const { fontSize, fontWeight } = nodeFont(node, depth);\n const padX = depth === 0 ? 28 : depth === 1 ? 16 : 12;\n const padY = depth === 0 ? 14 : depth === 1 ? 8 : 6;\n const textW = measureText(node.topic || \" \", fontSize, fontWeight);\n return {\n w: Math.max(depth === 0 ? 100 : 48, Math.ceil(textW) + padX * 2),\n h: Math.ceil(fontSize * 1.4) + padY * 2,\n fontSize,\n fontWeight,\n };\n}\n\nconst visibleKids = (node: TreeNode) => (node.expanded === false ? [] : (node.children ?? []));\n\nexport function layoutMap(root: TreeNode, direction: MapDirection = 2): MapLayout {\n const heights = new Map<string, number>();\n const subtree = (node: TreeNode, depth: number): number => {\n const own = nodeSize(node, depth).h;\n const kids = visibleKids(node);\n const sum = kids.reduce((acc, kid) => acc + subtree(kid, depth + 1), 0) + V_GAP * Math.max(0, kids.length - 1);\n const value = Math.max(own, sum);\n heights.set(node.id, value);\n return value;\n };\n\n const nodes: LayoutNode[] = [];\n const edges: LayoutEdge[] = [];\n const rootSize = nodeSize(root, 0);\n const rootLN: LayoutNode = { id: root.id, node: root, depth: 0, x: -rootSize.w / 2, y: -rootSize.h / 2, w: rootSize.w, h: rootSize.h, side: 0, color: \"#3b3f5c\", parentId: null, fontSize: rootSize.fontSize, fontWeight: rootSize.fontWeight };\n nodes.push(rootLN);\n\n const place = (parent: LayoutNode, kids: TreeNode[], side: 1 | -1, depth: number, colorOf: (kid: TreeNode, i: number) => string) => {\n kids.forEach((kid) => subtree(kid, depth));\n const total = kids.reduce((acc, kid) => acc + (heights.get(kid.id) ?? 0), 0) + V_GAP * Math.max(0, kids.length - 1);\n let top = parent.y + parent.h / 2 - total / 2;\n const gap = depth === 1 ? H_GAP_ROOT : H_GAP;\n kids.forEach((kid, i) => {\n const sh = heights.get(kid.id) ?? 0;\n const size = nodeSize(kid, depth);\n const cy = top + sh / 2;\n const x = side > 0 ? parent.x + parent.w + gap : parent.x - gap - size.w;\n const color = colorOf(kid, i);\n const ln: LayoutNode = { id: kid.id, node: kid, depth, x, y: cy - size.h / 2, w: size.w, h: size.h, side, color, parentId: parent.id, fontSize: size.fontSize, fontWeight: size.fontWeight };\n nodes.push(ln);\n edges.push({ from: parent, to: ln, color });\n place(ln, visibleKids(kid), side, depth + 1, () => color);\n top += sh + V_GAP;\n });\n };\n\n const kids = visibleKids(root);\n const all = root.children ?? [];\n const colorFor = (kid: TreeNode) => BRANCH_COLORS[Math.max(0, all.indexOf(kid)) % BRANCH_COLORS.length];\n const sideOf = (kid: TreeNode, i: number): 1 | -1 => {\n if (direction === 0) return -1;\n if (direction === 1) return 1;\n if (kid.direction === 0) return -1;\n if (kid.direction === 1) return 1;\n // Both sides: first half right, second half left (keeps reading order top-down on each side).\n return i < Math.ceil(kids.length / 2) ? 1 : -1;\n };\n const right = kids.filter((kid, i) => sideOf(kid, i) === 1);\n const left = kids.filter((kid, i) => sideOf(kid, i) === -1);\n place(rootLN, right, 1, 1, colorFor);\n place(rootLN, left, -1, 1, colorFor);\n\n const bounds = { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity };\n for (const n of nodes) {\n bounds.minX = Math.min(bounds.minX, n.x);\n bounds.minY = Math.min(bounds.minY, n.y);\n bounds.maxX = Math.max(bounds.maxX, n.x + n.w);\n bounds.maxY = Math.max(bounds.maxY, n.y + n.h);\n }\n return { nodes, byId: new Map(nodes.map((n) => [n.id, n])), edges, bounds };\n}\n\n/** Curved connector from the parent's side to the child's near side. */\nexport function edgePath(edge: LayoutEdge): string {\n const { from, to } = edge;\n const side = to.side >= 0 ? 1 : -1;\n const x1 = from.depth === 0 ? from.x + from.w / 2 + (side * from.w) / 2 - side * 12 : side > 0 ? from.x + from.w : from.x;\n const y1 = from.y + from.h / 2;\n const x2 = side > 0 ? to.x : to.x + to.w;\n const y2 = to.y + to.h / 2;\n const dx = (x2 - x1) * 0.5;\n return `M ${x1} ${y1} C ${x1 + dx} ${y1}, ${x2 - dx} ${y2}, ${x2} ${y2}`;\n}\n\n/** Visual look of a node (fill \u00B7 border \u00B7 text color \u00B7 radius) \u2014 shared by the map and the SVG export. */\nexport function nodeLook(ln: LayoutNode) {\n const style = ln.node.style ?? {};\n if (ln.depth === 0) return { fill: style.background ?? \"#3b3f5c\", stroke: \"none\", strokeWidth: 0, text: style.color ?? \"#ffffff\", radius: ln.h / 2 };\n if (ln.depth === 1) return { fill: style.background ?? \"#ffffff\", stroke: ln.color, strokeWidth: 2, text: style.color ?? \"#1f2328\", radius: ln.h / 2 };\n return { fill: style.background ?? \"#ffffff\", stroke: \"#d0d4da\", strokeWidth: 1, text: style.color ?? \"#1f2328\", radius: 8 };\n}\n", "import { outlinerStrings, type OutlinerStrings } from \"@ehfuse/outliner\";\n\n/** Map-only strings (the formatting / outline strings come from @ehfuse/outliner). */\nconst STRINGS = {\n ko: { map: \"\uC9C0\uB3C4\", outline: \"\uBAA9\uB85D\", addChild: \"\uC544\uB798 \uAC00\uC9C0\", addSibling: \"\uC606 \uAC00\uC9C0\", edit: \"\uAE00 \uACE0\uCE58\uAE30\", remove: \"\uC9C0\uC6B0\uAE30\", dirSide: \"\uC591\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30\", dirRight: \"\uC624\uB978\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30\", dirLeft: \"\uC67C\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30\", center: \"\uAC00\uC6B4\uB370\uB85C\", zoomIn: \"\uD655\uB300\", zoomOut: \"\uCD95\uC18C\", mapHint: \"\uB450 \uBC88 \uD074\uB9AD: \uAE00 \uACE0\uCE58\uAE30 \u00B7 Tab: \uC544\uB798 \uAC00\uC9C0 \u00B7 Enter: \uC606 \uAC00\uC9C0 \u00B7 \uAC00\uC9C0 \uB04C\uAE30: \uC62E\uAE30\uAE30 \u00B7 \uBE48 \uACF3 \uB04C\uAE30: \uC774\uB3D9 \u00B7 Ctrl+\uD720: \uD655\uB300\", newTopic: \"\uC0C8 \uAC00\uC9C0\" },\n en: { map: \"Map\", outline: \"List\", addChild: \"Child branch\", addSibling: \"Sibling branch\", edit: \"Edit text\", remove: \"Delete\", dirSide: \"Grow both ways\", dirRight: \"Grow to the right\", dirLeft: \"Grow to the left\", center: \"Center\", zoomIn: \"Zoom in\", zoomOut: \"Zoom out\", mapHint: \"Double-click: edit \u00B7 Tab: child \u00B7 Enter: sibling \u00B7 Drag a branch: move \u00B7 Drag empty space: pan \u00B7 Ctrl+wheel: zoom\", newTopic: \"New branch\" },\n ja: { map: \"\u30DE\u30C3\u30D7\", outline: \"\u30EA\u30B9\u30C8\", addChild: \"\u4E0B\u306E\u679D\", addSibling: \"\u6A2A\u306E\u679D\", edit: \"\u6587\u5B57\u3092\u7DE8\u96C6\", remove: \"\u524A\u9664\", dirSide: \"\u4E21\u5074\u306B\u5E83\u3052\u308B\", dirRight: \"\u53F3\u306B\u5E83\u3052\u308B\", dirLeft: \"\u5DE6\u306B\u5E83\u3052\u308B\", center: \"\u4E2D\u592E\u3078\", zoomIn: \"\u62E1\u5927\", zoomOut: \"\u7E2E\u5C0F\", mapHint: \"\u30C0\u30D6\u30EB\u30AF\u30EA\u30C3\u30AF: \u7DE8\u96C6 \u00B7 Tab: \u4E0B\u306E\u679D \u00B7 Enter: \u6A2A\u306E\u679D \u00B7 \u679D\u3092\u30C9\u30E9\u30C3\u30B0: \u79FB\u52D5 \u00B7 \u7A7A\u767D\u30C9\u30E9\u30C3\u30B0: \u30B9\u30AF\u30ED\u30FC\u30EB \u00B7 Ctrl+\u30DB\u30A4\u30FC\u30EB: \u62E1\u5927\", newTopic: \"\u65B0\u3057\u3044\u679D\" },\n zh: { map: \"\u5BFC\u56FE\", outline: \"\u5217\u8868\", addChild: \"\u5B50\u5206\u652F\", addSibling: \"\u540C\u7EA7\u5206\u652F\", edit: \"\u7F16\u8F91\u6587\u5B57\", remove: \"\u5220\u9664\", dirSide: \"\u4E24\u4FA7\u5C55\u5F00\", dirRight: \"\u5411\u53F3\u5C55\u5F00\", dirLeft: \"\u5411\u5DE6\u5C55\u5F00\", center: \"\u5C45\u4E2D\", zoomIn: \"\u653E\u5927\", zoomOut: \"\u7F29\u5C0F\", mapHint: \"\u53CC\u51FB: \u7F16\u8F91 \u00B7 Tab: \u5B50\u5206\u652F \u00B7 Enter: \u540C\u7EA7\u5206\u652F \u00B7 \u62D6\u52A8\u5206\u652F: \u79FB\u52A8 \u00B7 \u62D6\u52A8\u7A7A\u767D: \u5E73\u79FB \u00B7 Ctrl+\u6EDA\u8F6E: \u7F29\u653E\", newTopic: \"\u65B0\u5206\u652F\" },\n de: { map: \"Karte\", outline: \"Liste\", addChild: \"Unterzweig\", addSibling: \"Nebenzweig\", edit: \"Text bearbeiten\", remove: \"L\u00F6schen\", dirSide: \"Beidseitig\", dirRight: \"Nach rechts\", dirLeft: \"Nach links\", center: \"Zentrieren\", zoomIn: \"Vergr\u00F6\u00DFern\", zoomOut: \"Verkleinern\", mapHint: \"Doppelklick: bearbeiten \u00B7 Tab: Unterzweig \u00B7 Enter: Nebenzweig \u00B7 Zweig ziehen: verschieben \u00B7 Leere Fl\u00E4che ziehen: schwenken \u00B7 Strg+Rad: Zoom\", newTopic: \"Neuer Zweig\" },\n fr: { map: \"Carte\", outline: \"Liste\", addChild: \"Branche enfant\", addSibling: \"Branche s\u0153ur\", edit: \"Modifier le texte\", remove: \"Supprimer\", dirSide: \"Des deux c\u00F4t\u00E9s\", dirRight: \"Vers la droite\", dirLeft: \"Vers la gauche\", center: \"Centrer\", zoomIn: \"Zoomer\", zoomOut: \"D\u00E9zoomer\", mapHint: \"Double-clic : modifier \u00B7 Tab : enfant \u00B7 Entr\u00E9e : s\u0153ur \u00B7 Glisser une branche : d\u00E9placer \u00B7 Glisser le vide : d\u00E9filer \u00B7 Ctrl+molette : zoom\", newTopic: \"Nouvelle branche\" },\n it: { map: \"Mappa\", outline: \"Elenco\", addChild: \"Ramo figlio\", addSibling: \"Ramo fratello\", edit: \"Modifica testo\", remove: \"Elimina\", dirSide: \"Su entrambi i lati\", dirRight: \"Verso destra\", dirLeft: \"Verso sinistra\", center: \"Centra\", zoomIn: \"Ingrandisci\", zoomOut: \"Riduci\", mapHint: \"Doppio clic: modifica \u00B7 Tab: figlio \u00B7 Invio: fratello \u00B7 Trascina un ramo: sposta \u00B7 Trascina il vuoto: scorri \u00B7 Ctrl+rotella: zoom\", newTopic: \"Nuovo ramo\" },\n vi: { map: \"B\u1EA3n \u0111\u1ED3\", outline: \"Danh s\u00E1ch\", addChild: \"Nh\u00E1nh con\", addSibling: \"Nh\u00E1nh ngang\", edit: \"S\u1EEDa ch\u1EEF\", remove: \"X\u00F3a\", dirSide: \"M\u1EDF hai b\u00EAn\", dirRight: \"M\u1EDF sang ph\u1EA3i\", dirLeft: \"M\u1EDF sang tr\u00E1i\", center: \"V\u1EC1 gi\u1EEFa\", zoomIn: \"Ph\u00F3ng to\", zoomOut: \"Thu nh\u1ECF\", mapHint: \"Nh\u1EA5p \u0111\u00FAp: s\u1EEDa \u00B7 Tab: nh\u00E1nh con \u00B7 Enter: nh\u00E1nh ngang \u00B7 K\u00E9o nh\u00E1nh: di chuy\u1EC3n \u00B7 K\u00E9o ch\u1ED7 tr\u1ED1ng: cu\u1ED9n \u00B7 Ctrl+cu\u1ED9n: ph\u00F3ng to\", newTopic: \"Nh\u00E1nh m\u1EDBi\" },\n} as const;\n\nexport type MindMapStrings = OutlinerStrings & { [K in keyof (typeof STRINGS)[\"en\"]]: string };\n\nexport function mindMapStrings(locale?: string, overrides?: Partial<MindMapStrings>): MindMapStrings {\n const lang = (locale ?? \"en\").slice(0, 2).toLowerCase() as keyof typeof STRINGS;\n return { ...outlinerStrings(locale), ...(STRINGS[lang] ?? STRINGS.en), ...overrides };\n}\n", "/**\n * Standalone SVG of the map (for saving a picture next to the data). Built from the layout, not the DOM,\n * so it works while the map is hidden and looks the same in an <img>.\n */\nimport { DEFAULT_FONT_FAMILY } from \"@ehfuse/outliner\";\nimport { edgePath, layoutMap, nodeLook, type MapDirection } from \"./layout\";\nimport type { MindMapData } from \"./types\";\n\nconst esc = (text: string) => text.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\").replace(/\"/g, \""\");\n\nexport function exportMindMapSvg(data: MindMapData, options: { padding?: number; background?: string } = {}): string {\n const padding = options.padding ?? 24;\n const layout = layoutMap(data.nodeData, (data.direction ?? 2) as MapDirection);\n const { minX, minY, maxX, maxY } = layout.bounds;\n const width = Math.ceil(maxX - minX + padding * 2);\n const height = Math.ceil(maxY - minY + padding * 2);\n const ox = padding - minX;\n const oy = padding - minY;\n const parts: string[] = [];\n parts.push(`<rect width=\"${width}\" height=\"${height}\" fill=\"${options.background ?? \"#ffffff\"}\"/>`);\n parts.push(`<g transform=\"translate(${ox} ${oy})\">`);\n for (const edge of layout.edges) parts.push(`<path d=\"${edgePath(edge)}\" fill=\"none\" stroke=\"${edge.color}\" stroke-width=\"${edge.to.depth === 1 ? 2.5 : 1.75}\" stroke-linecap=\"round\"/>`);\n for (const ln of layout.nodes) {\n const look = nodeLook(ln);\n parts.push(\n `<rect x=\"${ln.x}\" y=\"${ln.y}\" width=\"${ln.w}\" height=\"${ln.h}\" rx=\"${look.radius}\" fill=\"${look.fill}\"${look.stroke !== \"none\" ? ` stroke=\"${look.stroke}\" stroke-width=\"${look.strokeWidth}\"` : \"\"}/>`\n );\n const deco = ln.node.style?.textDecoration;\n parts.push(\n `<text x=\"${ln.x + ln.w / 2}\" y=\"${ln.y + ln.h / 2}\" text-anchor=\"middle\" dominant-baseline=\"central\" font-family=\"${esc(DEFAULT_FONT_FAMILY)}\" font-size=\"${ln.fontSize}\" font-weight=\"${ln.fontWeight}\" fill=\"${look.text}\"${deco ? ` text-decoration=\"${esc(deco)}\"` : \"\"}>${esc(ln.node.topic)}</text>`\n );\n if (ln.node.expanded === false && (ln.node.children?.length ?? 0) > 0 && ln.depth > 0) {\n const cx = ln.side > 0 ? ln.x + ln.w + 10 : ln.x - 10;\n const cy = ln.y + ln.h / 2;\n parts.push(`<circle cx=\"${cx}\" cy=\"${cy}\" r=\"9\" fill=\"#ffffff\" stroke=\"${ln.color}\" stroke-width=\"1.5\"/>`);\n parts.push(`<text x=\"${cx}\" y=\"${cy}\" text-anchor=\"middle\" dominant-baseline=\"central\" font-family=\"${esc(DEFAULT_FONT_FAMILY)}\" font-size=\"10\" fill=\"${ln.color}\">${ln.node.children!.length}</text>`);\n }\n }\n parts.push(\"</g>\");\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\">${parts.join(\"\")}</svg>`;\n}\n", "export { MindMap, type MindMapProps, type MindMapHandle } from \"./MindMap\";\nexport { MapView, type MapViewProps, type MapViewHandle } from \"./MapView\";\nexport { exportMindMapSvg } from \"./exportSvg\";\nexport { layoutMap, edgePath, nodeLook, nodeSize, BRANCH_COLORS, type MapDirection, type LayoutNode, type LayoutEdge, type MapLayout } from \"./layout\";\nexport { mindMapStrings, type MindMapStrings } from \"./i18n\";\nexport type { MindMapData, MindMapView } from \"./types\";\nexport { createTree, type TreeNode, type TreeNodeStyle } from \"@ehfuse/outliner\";\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["forwardRef", "useImperativeHandle", "useRef", "useState", "Box", "ButtonBase", "
|
|
4
|
+
"sourcesContent": ["/**\n * MindMap \u2014 one tree shown as a map or as a list (outline), with one formatting toolbar for both.\n * Controlled: pass `value` and `onChange`. Undo history lives inside (map and list share it).\n */\nimport { forwardRef, useImperativeHandle, useRef, useState, type ReactNode } from \"react\";\nimport { Box, ButtonBase } from \"@mui/material\";\nimport { BranchBothIcon, BranchLeftIcon, BranchRightIcon, FitCenterIcon, ZoomInIcon, ZoomOutIcon } from \"@ehfuse/toolbar-icons\";\nimport { FormatToolbar, OutlineList, ToolButton, ToolDivider, locateNode, setNodeStyle, useTreeHistory, type TreeNode } from \"@ehfuse/outliner\";\nimport { MapView, type MapViewHandle } from \"./MapView\";\nimport { mindMapStrings, type MindMapStrings } from \"./i18n\";\nimport type { MapDirection } from \"./layout\";\nimport type { MindMapData, MindMapView } from \"./types\";\nimport { exportMindMapSvg } from \"./exportSvg\";\n\nexport interface MindMapProps {\n value: MindMapData;\n onChange: (value: MindMapData) => void;\n locale?: string;\n strings?: Partial<MindMapStrings>;\n readOnly?: boolean;\n /** Controlled view; or use `defaultView`. */\n view?: MindMapView;\n defaultView?: MindMapView;\n onViewChange?: (view: MindMapView) => void;\n /** Extra controls at the right end of the toolbar. */\n toolbarEnd?: ReactNode;\n /** Show the one-line help at the bottom (default true). */\n hint?: boolean;\n height?: number | string;\n}\n\nexport interface MindMapHandle {\n exportSvg: () => string;\n center: () => void;\n}\n\nconst DIRECTIONS: Array<{ value: MapDirection; key: \"dirSide\" | \"dirRight\" | \"dirLeft\"; icon: ReactNode }> = [\n { value: 2, key: \"dirSide\", icon: <BranchBothIcon /> },\n { value: 1, key: \"dirRight\", icon: <BranchRightIcon /> },\n { value: 0, key: \"dirLeft\", icon: <BranchLeftIcon /> },\n];\n\nexport const MindMap = forwardRef<MindMapHandle, MindMapProps>(function MindMap(\n { value, onChange, locale, strings: overrides, readOnly, view: viewProp, defaultView = \"map\", onViewChange, toolbarEnd, hint = true, height = \"100%\" },\n ref\n) {\n const strings = mindMapStrings(locale, overrides);\n const [ownView, setOwnView] = useState<MindMapView>(defaultView);\n const view = viewProp ?? ownView;\n const setView = (next: MindMapView) => {\n setOwnView(next);\n onViewChange?.(next);\n if (next === \"map\") requestAnimationFrame(() => mapRef.current?.center());\n };\n const [selected, setSelected] = useState<string | null>(null);\n const history = useTreeHistory();\n const mapRef = useRef<MapViewHandle | null>(null);\n const root = value.nodeData;\n const direction = (value.direction ?? 2) as MapDirection;\n\n const commit = (next: TreeNode, mergeKey?: string) => {\n history.record(root, mergeKey);\n onChange({ ...value, nodeData: next });\n };\n const undo = () => {\n const prev = history.undo(root);\n if (prev) onChange({ ...value, nodeData: prev });\n };\n const redo = () => {\n const next = history.redo(root);\n if (next) onChange({ ...value, nodeData: next });\n };\n useImperativeHandle(ref, () => ({ exportSvg: () => exportMindMapSvg(value), center: () => mapRef.current?.center() }), [value]);\n\n const selectedNode = selected ? locateNode(root, selected)?.node : undefined;\n const viewSwitch = (\n <Box sx={{ display: \"flex\", p: 0.25, borderRadius: 1, bgcolor: \"#f1f3f4\" }}>\n {([\"map\", \"outline\"] as const).map((item) => (\n <ButtonBase\n key={item}\n aria-pressed={view === item}\n onClick={() => setView(item)}\n sx={{\n height: 26,\n px: 1.25,\n borderRadius: 0.75,\n fontSize: 13,\n fontWeight: view === item ? 600 : 400,\n color: view === item ? \"primary.main\" : \"text.secondary\",\n bgcolor: view === item ? \"#fff\" : \"transparent\",\n boxShadow: view === item ? \"0 1px 2px rgba(0,0,0,0.15)\" : \"none\",\n }}\n >\n {item === \"map\" ? strings.map : strings.outline}\n </ButtonBase>\n ))}\n </Box>\n );\n\n return (\n <Box sx={{ display: \"flex\", flexDirection: \"column\", height, minHeight: 0, bgcolor: \"#fff\" }}>\n <FormatToolbar\n strings={strings}\n style={selectedNode ? (selectedNode.style ?? {}) : undefined}\n onStyle={(patch) => {\n if (!selected) return;\n const result = setNodeStyle(root, [selected], patch);\n if (result) commit(result.root);\n }}\n canUndo={history.canUndo}\n canRedo={history.canRedo}\n onUndo={undo}\n onRedo={redo}\n start={viewSwitch}\n end={toolbarEnd}\n readOnly={readOnly}\n >\n {view === \"map\" ? (\n <>\n {DIRECTIONS.map((item) => (\n <ToolButton key={item.value} label={strings[item.key]} active={direction === item.value} disabled={readOnly} onClick={() => onChange({ ...value, direction: item.value })}>\n {item.icon}\n </ToolButton>\n ))}\n <ToolDivider />\n <ToolButton label={strings.zoomOut} onClick={() => mapRef.current?.zoomBy(1 / 1.2)}>\n <ZoomOutIcon />\n </ToolButton>\n <ToolButton label={strings.zoomIn} onClick={() => mapRef.current?.zoomBy(1.2)}>\n <ZoomInIcon />\n </ToolButton>\n <ToolButton label={strings.center} onClick={() => mapRef.current?.center()}>\n <FitCenterIcon />\n </ToolButton>\n </>\n ) : null}\n </FormatToolbar>\n <Box sx={{ position: \"relative\", flex: 1, minHeight: 0 }}>\n {view === \"map\" ? (\n <MapView ref={mapRef} root={root} direction={direction} onEdit={commit} selectedId={selected} onSelect={setSelected} strings={strings} readOnly={readOnly} onUndo={undo} onRedo={redo} hint={hint} />\n ) : (\n <>\n <OutlineList root={root} onEdit={commit} selectedId={selected} onSelect={setSelected} strings={strings} readOnly={readOnly} onUndo={undo} onRedo={redo} />\n {hint ? (\n <Box sx={{ position: \"absolute\", left: 12, right: 12, bottom: 8, fontSize: 12, lineHeight: 1.5, color: \"text.secondary\", pointerEvents: \"none\" }}>\n <Box component=\"span\" sx={{ bgcolor: \"rgba(255,255,255,0.9)\" }}>\n {strings.hint}\n </Box>\n </Box>\n ) : null}\n </>\n )}\n </Box>\n </Box>\n );\n});\n", "/**\n * Map view \u2014 draws the tree as a mind map and edits it in place.\n *\n * Mouse: click to select \u00B7 double-click to edit \u00B7 drag a branch onto another (middle = into it, top / bottom edge = before / after)\n * \u00B7 drag empty space to pan \u00B7 Ctrl/\u2318 + wheel to zoom (a plain wheel scrolls the page, not the map).\n * Keys (map focused): Tab child \u00B7 Enter sibling \u00B7 F2 edit \u00B7 Delete / Backspace remove \u00B7 Space fold \u00B7 arrows move the selection \u00B7\n * Ctrl/\u2318+Z undo \u00B7 Ctrl/\u2318+Shift+Z / Ctrl+Y redo.\n */\nimport { forwardRef, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, type KeyboardEvent, type PointerEvent } from \"react\";\nimport { Box } from \"@mui/material\";\nimport { ChildBranchIcon, PencilIcon, SiblingBranchIcon, TrashIcon } from \"@ehfuse/toolbar-icons\";\nimport {\n DEFAULT_FONT_FAMILY,\n ToolButton,\n addChild,\n addSibling,\n containsNode,\n locateNode,\n measureText,\n moveNode,\n removeNode,\n setTopic,\n toggleFold,\n type TreeEdit,\n type TreeNode,\n} from \"@ehfuse/outliner\";\nimport { edgePath, layoutMap, nodeLook, type LayoutNode, type MapDirection } from \"./layout\";\nimport type { MindMapStrings } from \"./i18n\";\n\nexport interface MapViewHandle {\n center: () => void;\n zoomBy: (factor: number) => void;\n}\n\nexport interface MapViewProps {\n root: TreeNode;\n direction: MapDirection;\n onEdit: (root: TreeNode, mergeKey?: string) => void;\n selectedId: string | null;\n onSelect: (id: string | null) => void;\n strings: MindMapStrings;\n readOnly?: boolean;\n onUndo?: () => void;\n onRedo?: () => void;\n /** Show the one-line help at the bottom (default true). */\n hint?: boolean;\n}\n\nconst ZOOM_MIN = 0.3;\nconst ZOOM_MAX = 2.5;\nconst DRAG_START = 5;\n\ntype DropPlace = \"before\" | \"after\" | \"child\";\n\nexport const MapView = forwardRef<MapViewHandle, MapViewProps>(function MapView({ root, direction, onEdit, selectedId, onSelect, strings, readOnly, onUndo, onRedo, hint = true }, ref) {\n const boxRef = useRef<HTMLDivElement | null>(null);\n const [size, setSize] = useState({ w: 0, h: 0 });\n const [view, setView] = useState({ x: 0, y: 0, z: 1 });\n const viewRef = useRef(view);\n viewRef.current = view;\n const [editing, setEditing] = useState<{ id: string; text: string } | null>(null);\n const [drag, setDrag] = useState<{ id: string; px: number; py: number; target: { id: string; place: DropPlace } | null } | null>(null);\n const pointer = useRef<{ kind: \"pan\" | \"node\"; id?: string; sx: number; sy: number; vx: number; vy: number; moved: boolean } | null>(null);\n const layout = useMemo(() => layoutMap(root, direction), [root, direction]);\n\n // Size \u2014 center the map the first time the box has a size.\n const centered = useRef(false);\n useLayoutEffect(() => {\n const el = boxRef.current;\n if (!el) return;\n const ro = new ResizeObserver(() => setSize({ w: el.clientWidth, h: el.clientHeight }));\n ro.observe(el);\n setSize({ w: el.clientWidth, h: el.clientHeight });\n return () => ro.disconnect();\n }, []);\n const center = useCallback(() => {\n const { minX, minY, maxX, maxY } = layout.bounds;\n const z = viewRef.current.z;\n setView({ x: size.w / 2 - ((minX + maxX) / 2) * z, y: size.h / 2 - ((minY + maxY) / 2) * z, z });\n }, [layout, size]);\n useEffect(() => {\n if (centered.current || size.w === 0) return;\n centered.current = true;\n center();\n }, [size, center]);\n const zoomAt = useCallback((factor: number, cx: number, cy: number) => {\n setView((v) => {\n const z = Math.min(ZOOM_MAX, Math.max(ZOOM_MIN, v.z * factor));\n return { x: cx - (cx - v.x) * (z / v.z), y: cy - (cy - v.y) * (z / v.z), z };\n });\n }, []);\n useImperativeHandle(ref, () => ({ center, zoomBy: (factor) => zoomAt(factor, size.w / 2, size.h / 2) }), [center, zoomAt, size]);\n\n // Ctrl/\u2318 + wheel zooms at the cursor; a plain wheel is left to the page (it must not pan the map).\n useEffect(() => {\n const el = boxRef.current;\n if (!el) return;\n const onWheel = (event: WheelEvent) => {\n if (!(event.ctrlKey || event.metaKey)) return;\n event.preventDefault();\n const r = el.getBoundingClientRect();\n zoomAt(event.deltaY < 0 ? 1.1 : 1 / 1.1, event.clientX - r.left, event.clientY - r.top);\n };\n el.addEventListener(\"wheel\", onWheel, { passive: false });\n return () => el.removeEventListener(\"wheel\", onWheel);\n }, [zoomAt]);\n\n const apply = (result: TreeEdit | null, mergeKey?: string, editNew = false) => {\n if (!result) return;\n onEdit(result.root, mergeKey);\n if (result.focusId) {\n onSelect(result.focusId);\n if (editNew) setEditing({ id: result.focusId, text: \"\" });\n }\n };\n const startEdit = (id: string) => {\n if (readOnly) return;\n const at = locateNode(root, id);\n if (at) setEditing({ id, text: at.node.topic });\n };\n const commitEdit = () => {\n if (!editing) return;\n apply(setTopic(root, editing.id, editing.text));\n setEditing(null);\n boxRef.current?.focus({ preventScroll: true });\n };\n\n const toCanvas = (clientX: number, clientY: number) => {\n const r = boxRef.current!.getBoundingClientRect();\n return { x: (clientX - r.left - view.x) / view.z, y: (clientY - r.top - view.y) / view.z };\n };\n const dropAt = (clientX: number, clientY: number, dragged: TreeNode): { id: string; place: DropPlace } | null => {\n const p = toCanvas(clientX, clientY);\n for (const ln of layout.nodes) {\n if (p.x < ln.x - 4 || p.x > ln.x + ln.w + 4 || p.y < ln.y - 4 || p.y > ln.y + ln.h + 4) continue;\n if (containsNode(dragged, ln.id)) return null;\n if (ln.depth === 0) return { id: ln.id, place: \"child\" };\n const rel = (p.y - ln.y) / ln.h;\n return { id: ln.id, place: rel < 0.25 ? \"before\" : rel > 0.75 ? \"after\" : \"child\" };\n }\n return null;\n };\n\n const onPointerDown = (event: PointerEvent<HTMLDivElement>) => {\n if (event.button !== 0) return;\n const target = event.target as HTMLElement;\n if (target.closest(\"[data-mm-ui]\")) return;\n if (editing && !target.closest(\"[data-mm-edit]\")) commitEdit();\n if (target.closest(\"[data-mm-edit]\")) return;\n const fold = target.closest(\"[data-mm-fold]\") as HTMLElement | null;\n if (fold) {\n apply(toggleFold(root, fold.dataset.mmFold!));\n return;\n }\n const nodeEl = target.closest(\"[data-mm-node]\") as HTMLElement | null;\n boxRef.current?.focus({ preventScroll: true });\n // Capture the pointer only once a drag starts \u2014 capturing on press retargets the double-click to the box, so editing never opened.\n if (nodeEl) {\n const id = nodeEl.dataset.mmNode!;\n onSelect(id);\n pointer.current = { kind: \"node\", id, sx: event.clientX, sy: event.clientY, vx: view.x, vy: view.y, moved: false };\n } else {\n onSelect(null);\n pointer.current = { kind: \"pan\", sx: event.clientX, sy: event.clientY, vx: view.x, vy: view.y, moved: false };\n }\n };\n const onPointerMove = (event: PointerEvent<HTMLDivElement>) => {\n const p = pointer.current;\n if (!p) return;\n const dx = event.clientX - p.sx;\n const dy = event.clientY - p.sy;\n if (!p.moved && Math.hypot(dx, dy) < DRAG_START) return;\n if (!p.moved && !boxRef.current?.hasPointerCapture(event.pointerId)) boxRef.current?.setPointerCapture(event.pointerId);\n p.moved = true;\n if (p.kind === \"pan\") {\n setView((v) => ({ ...v, x: p.vx + dx, y: p.vy + dy }));\n return;\n }\n if (readOnly || p.id === root.id) return;\n const dragged = locateNode(root, p.id!)?.node;\n if (!dragged) return;\n const r = boxRef.current!.getBoundingClientRect();\n setDrag({ id: p.id!, px: event.clientX - r.left, py: event.clientY - r.top, target: dropAt(event.clientX, event.clientY, dragged) });\n };\n const onPointerUp = (event: PointerEvent<HTMLDivElement>) => {\n const p = pointer.current;\n pointer.current = null;\n if (boxRef.current?.hasPointerCapture(event.pointerId)) boxRef.current.releasePointerCapture(event.pointerId);\n if (p?.kind === \"node\" && drag?.target) apply(moveNode(root, drag.id, drag.target.id, drag.target.place));\n setDrag(null);\n };\n\n const neighbor = (ln: LayoutNode, key: string): string | null => {\n const at = locateNode(root, ln.id);\n if (!at) return null;\n if (key === \"ArrowUp\" || key === \"ArrowDown\") {\n if (!at.parent) return null;\n const sibs = (at.parent.children ?? []).filter((kid) => layout.byId.get(kid.id)?.side === ln.side);\n const i = sibs.findIndex((kid) => kid.id === ln.id);\n return sibs[i + (key === \"ArrowUp\" ? -1 : 1)]?.id ?? null;\n }\n const outward = (key === \"ArrowRight\" && ln.side >= 0) || (key === \"ArrowLeft\" && ln.side <= 0);\n if (outward) {\n const kids = at.node.expanded === false ? [] : (at.node.children ?? []);\n const want = ln.side === 0 ? (key === \"ArrowRight\" ? 1 : -1) : ln.side;\n return kids.find((kid) => layout.byId.get(kid.id)?.side === want)?.id ?? null;\n }\n return ln.parentId;\n };\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (editing || (event.target as HTMLElement).tagName === \"INPUT\") return;\n const mod = event.ctrlKey || event.metaKey;\n if (mod && (event.key === \"z\" || event.key === \"Z\")) {\n event.preventDefault();\n if (event.shiftKey) onRedo?.();\n else onUndo?.();\n return;\n }\n if (mod && (event.key === \"y\" || event.key === \"Y\")) {\n event.preventDefault();\n onRedo?.();\n return;\n }\n const ln = selectedId ? layout.byId.get(selectedId) : null;\n if (!ln) return;\n if (event.key.startsWith(\"Arrow\")) {\n const next = neighbor(ln, event.key);\n event.preventDefault();\n if (next) onSelect(next);\n return;\n }\n if (readOnly) return;\n if (event.key === \"Tab\") {\n event.preventDefault();\n apply(addChild(root, ln.id), undefined, true);\n } else if (event.key === \"Enter\") {\n event.preventDefault();\n apply(addSibling(root, ln.id), undefined, true);\n } else if (event.key === \"F2\") {\n event.preventDefault();\n startEdit(ln.id);\n } else if (event.key === \"Delete\" || event.key === \"Backspace\") {\n event.preventDefault();\n apply(removeNode(root, ln.id));\n } else if (event.key === \" \") {\n event.preventDefault();\n apply(toggleFold(root, ln.id));\n }\n };\n\n const selected = selectedId ? layout.byId.get(selectedId) : undefined;\n const editingLN = editing ? layout.byId.get(editing.id) : undefined;\n const dragLN = drag ? layout.byId.get(drag.id) : undefined;\n const dropLN = drag?.target ? layout.byId.get(drag.target.id) : undefined;\n const barButton = (key: string, label: string, icon: React.ReactNode, onClick: () => void) => (\n <ToolButton key={key} label={label} onClick={onClick}>\n {icon}\n </ToolButton>\n );\n\n return (\n <Box\n ref={boxRef}\n tabIndex={0}\n onKeyDown={onKeyDown}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerUp}\n onDoubleClick={(event) => {\n const nodeEl = (event.target as HTMLElement).closest(\"[data-mm-node]\") as HTMLElement | null;\n if (nodeEl) startEdit(nodeEl.dataset.mmNode!);\n }}\n sx={{ position: \"relative\", width: \"100%\", height: \"100%\", overflow: \"hidden\", bgcolor: \"#f7f8fa\", outline: \"none\", touchAction: \"none\", userSelect: \"none\", cursor: pointer.current?.kind === \"pan\" ? \"grabbing\" : \"default\" }}\n >\n <Box sx={{ position: \"absolute\", left: 0, top: 0, transform: `translate(${view.x}px, ${view.y}px) scale(${view.z})`, transformOrigin: \"0 0\" }}>\n <svg style={{ position: \"absolute\", left: 0, top: 0, width: 1, height: 1, overflow: \"visible\" }}>\n {layout.edges.map((edge) => (\n <path key={edge.to.id} d={edgePath(edge)} fill=\"none\" stroke={edge.color} strokeWidth={edge.to.depth === 1 ? 2.5 : 1.75} strokeLinecap=\"round\" />\n ))}\n </svg>\n {layout.nodes.map((ln) => {\n const look = nodeLook(ln);\n const kids = ln.node.children?.length ?? 0;\n const folded = ln.node.expanded === false && kids > 0;\n const isSel = ln.id === selectedId;\n return (\n <Box\n key={ln.id}\n data-mm-node={ln.id}\n sx={{\n position: \"absolute\",\n left: ln.x,\n top: ln.y,\n width: ln.w,\n height: ln.h,\n boxSizing: \"border-box\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: `${look.radius}px`,\n bgcolor: look.fill,\n border: look.stroke !== \"none\" ? `${look.strokeWidth}px solid ${look.stroke}` : 0,\n color: look.text,\n fontFamily: DEFAULT_FONT_FAMILY,\n fontSize: ln.fontSize,\n fontWeight: ln.fontWeight,\n textDecoration: ln.node.style?.textDecoration,\n whiteSpace: \"nowrap\",\n cursor: readOnly ? \"default\" : \"pointer\",\n boxShadow: isSel ? \"0 0 0 2px #fff, 0 0 0 4px #1a73e8\" : ln.depth === 0 ? \"0 2px 6px rgba(0,0,0,0.18)\" : \"none\",\n opacity: drag?.id === ln.id ? 0.35 : 1,\n \"&:hover .mm-fold\": { opacity: 1 },\n }}\n >\n {editing?.id === ln.id ? null : ln.node.topic || \"\u00A0\"}\n {kids > 0 && ln.depth > 0 ? (\n <Box\n className=\"mm-fold\"\n data-mm-fold={ln.id}\n title={folded ? strings.unfold : strings.fold}\n sx={{\n position: \"absolute\",\n top: \"50%\",\n [ln.side > 0 ? \"left\" : \"right\"]: \"100%\",\n transform: `translate(${ln.side > 0 ? 4 : -4}px, -50%)`,\n minWidth: 18,\n height: 18,\n px: folded ? 0.5 : 0,\n boxSizing: \"border-box\",\n borderRadius: 9,\n bgcolor: \"#fff\",\n border: `1.5px solid ${ln.color}`,\n color: ln.color,\n fontSize: 11,\n fontWeight: 600,\n lineHeight: \"15px\",\n textAlign: \"center\",\n cursor: \"pointer\",\n opacity: folded || isSel ? 1 : 0,\n textDecoration: \"none\",\n }}\n >\n {folded ? kids : \"\u2212\"}\n </Box>\n ) : null}\n </Box>\n );\n })}\n {/* Drop target \u2014 into (outline) or before / after (line). */}\n {dropLN && drag?.target ? (\n drag.target.place === \"child\" ? (\n <Box sx={{ position: \"absolute\", left: dropLN.x - 4, top: dropLN.y - 4, width: dropLN.w + 8, height: dropLN.h + 8, border: \"2px dashed #1a73e8\", borderRadius: 2, pointerEvents: \"none\" }} />\n ) : (\n <Box sx={{ position: \"absolute\", left: dropLN.x, top: drag.target.place === \"before\" ? dropLN.y - 6 : dropLN.y + dropLN.h + 4, width: dropLN.w, height: 3, borderRadius: 2, bgcolor: \"#1a73e8\", pointerEvents: \"none\" }} />\n )\n ) : null}\n {editingLN && editing ? (\n <input\n data-mm-edit=\"\"\n autoFocus\n value={editing.text}\n spellCheck={false}\n onFocus={(event) => event.currentTarget.select()}\n onChange={(event) => setEditing({ id: editing.id, text: event.target.value })}\n onBlur={commitEdit}\n onKeyDown={(event) => {\n event.stopPropagation();\n if (event.nativeEvent.isComposing) return;\n if (event.key === \"Enter\") {\n event.preventDefault();\n commitEdit();\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n setEditing(null);\n boxRef.current?.focus({ preventScroll: true });\n } else if (event.key === \"Tab\") {\n event.preventDefault();\n const id = editing.id;\n const text = editing.text;\n setEditing(null);\n const named = setTopic(root, id, text);\n apply(addChild(named?.root ?? root, id), undefined, true);\n }\n }}\n style={{\n position: \"absolute\",\n left: editingLN.x,\n top: editingLN.y,\n width: Math.max(editingLN.w, Math.ceil(measureText(editing.text || \" \", editingLN.fontSize, editingLN.fontWeight)) + 40),\n height: editingLN.h,\n boxSizing: \"border-box\",\n padding: \"0 12px\",\n border: \"2px solid #1a73e8\",\n borderRadius: 8,\n outline: \"none\",\n textAlign: \"center\",\n fontFamily: DEFAULT_FONT_FAMILY,\n fontSize: editingLN.fontSize,\n fontWeight: editingLN.fontWeight,\n color: \"#1f2328\",\n background: \"#fff\",\n zIndex: 5,\n }}\n />\n ) : null}\n </Box>\n {/* Dragged branch follows the pointer. */}\n {drag && dragLN ? (\n <Box sx={{ position: \"absolute\", left: drag.px + 10, top: drag.py + 10, px: 1.5, py: 0.5, borderRadius: 2, bgcolor: \"#fff\", border: `1.5px solid ${dragLN.color}`, fontSize: 13, opacity: 0.9, pointerEvents: \"none\", boxShadow: \"0 4px 12px rgba(0,0,0,0.15)\" }}>\n {dragLN.node.topic || \"\u00A0\"}\n </Box>\n ) : null}\n {/* Buttons above the selected branch \u2014 growing the map without knowing the keys. */}\n {selected && !editing && !drag && !readOnly ? (\n <Box\n data-mm-ui=\"\"\n sx={{\n position: \"absolute\",\n left: view.x + (selected.x + selected.w / 2) * view.z,\n top: view.y + selected.y * view.z,\n transform: \"translate(-50%, calc(-100% - 8px))\",\n display: \"flex\",\n gap: 0.25,\n p: 0.25,\n bgcolor: \"#fff\",\n border: \"1px solid #e0e0e0\",\n borderRadius: 1,\n boxShadow: \"0 2px 6px rgba(0,0,0,0.12)\",\n zIndex: 6,\n }}\n >\n {barButton(\"child\", strings.addChild, <ChildBranchIcon />, () => apply(addChild(root, selected.id), undefined, true))}\n {selected.depth > 0 ? barButton(\"sibling\", strings.addSibling, <SiblingBranchIcon />, () => apply(addSibling(root, selected.id), undefined, true)) : null}\n {barButton(\"edit\", strings.edit, <PencilIcon />, () => startEdit(selected.id))}\n {selected.depth > 0 ? barButton(\"delete\", strings.remove, <TrashIcon />, () => apply(removeNode(root, selected.id))) : null}\n </Box>\n ) : null}\n {hint ? (\n <Box sx={{ position: \"absolute\", left: 12, right: 12, bottom: 8, fontSize: 12, lineHeight: 1.5, color: \"text.secondary\", pointerEvents: \"none\" }}>\n <Box component=\"span\" sx={{ bgcolor: \"rgba(247,248,250,0.85)\" }}>\n {strings.mapHint}\n </Box>\n </Box>\n ) : null}\n </Box>\n );\n});\n", "/**\n * Map layout \u2014 root in the middle, branches to the right / left / both sides.\n * Node sizes come from measured text (no DOM pass), so layout is a pure function of the data.\n */\nimport { measureText, type TreeNode } from \"@ehfuse/outliner\";\n\n/** 0 = left, 1 = right, 2 = both sides (same values as Mind Elixir). */\nexport type MapDirection = 0 | 1 | 2;\n\nexport interface LayoutNode {\n id: string;\n node: TreeNode;\n depth: number;\n x: number;\n y: number;\n w: number;\n h: number;\n /** 1 = grows to the right, -1 = to the left, 0 = root. */\n side: 1 | -1 | 0;\n color: string;\n parentId: string | null;\n fontSize: number;\n fontWeight: string;\n}\n\nexport interface LayoutEdge {\n from: LayoutNode;\n to: LayoutNode;\n color: string;\n}\n\nexport interface MapLayout {\n nodes: LayoutNode[];\n byId: Map<string, LayoutNode>;\n edges: LayoutEdge[];\n bounds: { minX: number; minY: number; maxX: number; maxY: number };\n}\n\nexport const BRANCH_COLORS = [\"#e8710a\", \"#1a73e8\", \"#188038\", \"#d93025\", \"#9334e6\", \"#f9ab00\", \"#12b5cb\", \"#c2185b\"];\nconst H_GAP_ROOT = 64;\nconst H_GAP = 40;\nconst V_GAP = 14;\n\n/** Default text size / weight by depth (a node's own style wins). */\nexport function nodeFont(node: TreeNode, depth: number) {\n const fontSize = node.style?.fontSize ? parseFloat(node.style.fontSize) : depth === 0 ? 22 : depth === 1 ? 16 : 14;\n const fontWeight = node.style?.fontWeight ?? (depth === 0 ? \"700\" : depth === 1 ? \"500\" : \"400\");\n return { fontSize, fontWeight };\n}\n\nexport function nodeSize(node: TreeNode, depth: number) {\n const { fontSize, fontWeight } = nodeFont(node, depth);\n const padX = depth === 0 ? 28 : depth === 1 ? 16 : 12;\n const padY = depth === 0 ? 14 : depth === 1 ? 8 : 6;\n const textW = measureText(node.topic || \" \", fontSize, fontWeight);\n return {\n w: Math.max(depth === 0 ? 100 : 48, Math.ceil(textW) + padX * 2),\n h: Math.ceil(fontSize * 1.4) + padY * 2,\n fontSize,\n fontWeight,\n };\n}\n\nconst visibleKids = (node: TreeNode) => (node.expanded === false ? [] : (node.children ?? []));\n\nexport function layoutMap(root: TreeNode, direction: MapDirection = 2): MapLayout {\n const heights = new Map<string, number>();\n const subtree = (node: TreeNode, depth: number): number => {\n const own = nodeSize(node, depth).h;\n const kids = visibleKids(node);\n const sum = kids.reduce((acc, kid) => acc + subtree(kid, depth + 1), 0) + V_GAP * Math.max(0, kids.length - 1);\n const value = Math.max(own, sum);\n heights.set(node.id, value);\n return value;\n };\n\n const nodes: LayoutNode[] = [];\n const edges: LayoutEdge[] = [];\n const rootSize = nodeSize(root, 0);\n const rootLN: LayoutNode = { id: root.id, node: root, depth: 0, x: -rootSize.w / 2, y: -rootSize.h / 2, w: rootSize.w, h: rootSize.h, side: 0, color: \"#3b3f5c\", parentId: null, fontSize: rootSize.fontSize, fontWeight: rootSize.fontWeight };\n nodes.push(rootLN);\n\n const place = (parent: LayoutNode, kids: TreeNode[], side: 1 | -1, depth: number, colorOf: (kid: TreeNode, i: number) => string) => {\n kids.forEach((kid) => subtree(kid, depth));\n const total = kids.reduce((acc, kid) => acc + (heights.get(kid.id) ?? 0), 0) + V_GAP * Math.max(0, kids.length - 1);\n let top = parent.y + parent.h / 2 - total / 2;\n const gap = depth === 1 ? H_GAP_ROOT : H_GAP;\n kids.forEach((kid, i) => {\n const sh = heights.get(kid.id) ?? 0;\n const size = nodeSize(kid, depth);\n const cy = top + sh / 2;\n const x = side > 0 ? parent.x + parent.w + gap : parent.x - gap - size.w;\n const color = colorOf(kid, i);\n const ln: LayoutNode = { id: kid.id, node: kid, depth, x, y: cy - size.h / 2, w: size.w, h: size.h, side, color, parentId: parent.id, fontSize: size.fontSize, fontWeight: size.fontWeight };\n nodes.push(ln);\n edges.push({ from: parent, to: ln, color });\n place(ln, visibleKids(kid), side, depth + 1, () => color);\n top += sh + V_GAP;\n });\n };\n\n const kids = visibleKids(root);\n const all = root.children ?? [];\n const colorFor = (kid: TreeNode) => BRANCH_COLORS[Math.max(0, all.indexOf(kid)) % BRANCH_COLORS.length];\n const sideOf = (kid: TreeNode, i: number): 1 | -1 => {\n if (direction === 0) return -1;\n if (direction === 1) return 1;\n if (kid.direction === 0) return -1;\n if (kid.direction === 1) return 1;\n // Both sides: first half right, second half left (keeps reading order top-down on each side).\n return i < Math.ceil(kids.length / 2) ? 1 : -1;\n };\n const right = kids.filter((kid, i) => sideOf(kid, i) === 1);\n const left = kids.filter((kid, i) => sideOf(kid, i) === -1);\n place(rootLN, right, 1, 1, colorFor);\n place(rootLN, left, -1, 1, colorFor);\n\n const bounds = { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity };\n for (const n of nodes) {\n bounds.minX = Math.min(bounds.minX, n.x);\n bounds.minY = Math.min(bounds.minY, n.y);\n bounds.maxX = Math.max(bounds.maxX, n.x + n.w);\n bounds.maxY = Math.max(bounds.maxY, n.y + n.h);\n }\n return { nodes, byId: new Map(nodes.map((n) => [n.id, n])), edges, bounds };\n}\n\n/** Curved connector from the parent's side to the child's near side. */\nexport function edgePath(edge: LayoutEdge): string {\n const { from, to } = edge;\n const side = to.side >= 0 ? 1 : -1;\n const x1 = from.depth === 0 ? from.x + from.w / 2 + (side * from.w) / 2 - side * 12 : side > 0 ? from.x + from.w : from.x;\n const y1 = from.y + from.h / 2;\n const x2 = side > 0 ? to.x : to.x + to.w;\n const y2 = to.y + to.h / 2;\n const dx = (x2 - x1) * 0.5;\n return `M ${x1} ${y1} C ${x1 + dx} ${y1}, ${x2 - dx} ${y2}, ${x2} ${y2}`;\n}\n\n/** Visual look of a node (fill \u00B7 border \u00B7 text color \u00B7 radius) \u2014 shared by the map and the SVG export. */\nexport function nodeLook(ln: LayoutNode) {\n const style = ln.node.style ?? {};\n if (ln.depth === 0) return { fill: style.background ?? \"#3b3f5c\", stroke: \"none\", strokeWidth: 0, text: style.color ?? \"#ffffff\", radius: ln.h / 2 };\n if (ln.depth === 1) return { fill: style.background ?? \"#ffffff\", stroke: ln.color, strokeWidth: 2, text: style.color ?? \"#1f2328\", radius: ln.h / 2 };\n return { fill: style.background ?? \"#ffffff\", stroke: \"#d0d4da\", strokeWidth: 1, text: style.color ?? \"#1f2328\", radius: 8 };\n}\n", "import { outlinerStrings, type OutlinerStrings } from \"@ehfuse/outliner\";\n\n/** Map-only strings (the formatting / outline strings come from @ehfuse/outliner). */\nconst STRINGS = {\n ko: { map: \"\uC9C0\uB3C4\", outline: \"\uBAA9\uB85D\", addChild: \"\uC544\uB798 \uAC00\uC9C0\", addSibling: \"\uC606 \uAC00\uC9C0\", edit: \"\uAE00 \uACE0\uCE58\uAE30\", remove: \"\uC9C0\uC6B0\uAE30\", dirSide: \"\uC591\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30\", dirRight: \"\uC624\uB978\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30\", dirLeft: \"\uC67C\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30\", center: \"\uAC00\uC6B4\uB370\uB85C\", zoomIn: \"\uD655\uB300\", zoomOut: \"\uCD95\uC18C\", mapHint: \"\uB450 \uBC88 \uD074\uB9AD: \uAE00 \uACE0\uCE58\uAE30 \u00B7 Tab: \uC544\uB798 \uAC00\uC9C0 \u00B7 Enter: \uC606 \uAC00\uC9C0 \u00B7 \uAC00\uC9C0 \uB04C\uAE30: \uC62E\uAE30\uAE30 \u00B7 \uBE48 \uACF3 \uB04C\uAE30: \uC774\uB3D9 \u00B7 Ctrl+\uD720: \uD655\uB300\", newTopic: \"\uC0C8 \uAC00\uC9C0\" },\n en: { map: \"Map\", outline: \"List\", addChild: \"Child branch\", addSibling: \"Sibling branch\", edit: \"Edit text\", remove: \"Delete\", dirSide: \"Grow both ways\", dirRight: \"Grow to the right\", dirLeft: \"Grow to the left\", center: \"Center\", zoomIn: \"Zoom in\", zoomOut: \"Zoom out\", mapHint: \"Double-click: edit \u00B7 Tab: child \u00B7 Enter: sibling \u00B7 Drag a branch: move \u00B7 Drag empty space: pan \u00B7 Ctrl+wheel: zoom\", newTopic: \"New branch\" },\n ja: { map: \"\u30DE\u30C3\u30D7\", outline: \"\u30EA\u30B9\u30C8\", addChild: \"\u4E0B\u306E\u679D\", addSibling: \"\u6A2A\u306E\u679D\", edit: \"\u6587\u5B57\u3092\u7DE8\u96C6\", remove: \"\u524A\u9664\", dirSide: \"\u4E21\u5074\u306B\u5E83\u3052\u308B\", dirRight: \"\u53F3\u306B\u5E83\u3052\u308B\", dirLeft: \"\u5DE6\u306B\u5E83\u3052\u308B\", center: \"\u4E2D\u592E\u3078\", zoomIn: \"\u62E1\u5927\", zoomOut: \"\u7E2E\u5C0F\", mapHint: \"\u30C0\u30D6\u30EB\u30AF\u30EA\u30C3\u30AF: \u7DE8\u96C6 \u00B7 Tab: \u4E0B\u306E\u679D \u00B7 Enter: \u6A2A\u306E\u679D \u00B7 \u679D\u3092\u30C9\u30E9\u30C3\u30B0: \u79FB\u52D5 \u00B7 \u7A7A\u767D\u30C9\u30E9\u30C3\u30B0: \u30B9\u30AF\u30ED\u30FC\u30EB \u00B7 Ctrl+\u30DB\u30A4\u30FC\u30EB: \u62E1\u5927\", newTopic: \"\u65B0\u3057\u3044\u679D\" },\n zh: { map: \"\u5BFC\u56FE\", outline: \"\u5217\u8868\", addChild: \"\u5B50\u5206\u652F\", addSibling: \"\u540C\u7EA7\u5206\u652F\", edit: \"\u7F16\u8F91\u6587\u5B57\", remove: \"\u5220\u9664\", dirSide: \"\u4E24\u4FA7\u5C55\u5F00\", dirRight: \"\u5411\u53F3\u5C55\u5F00\", dirLeft: \"\u5411\u5DE6\u5C55\u5F00\", center: \"\u5C45\u4E2D\", zoomIn: \"\u653E\u5927\", zoomOut: \"\u7F29\u5C0F\", mapHint: \"\u53CC\u51FB: \u7F16\u8F91 \u00B7 Tab: \u5B50\u5206\u652F \u00B7 Enter: \u540C\u7EA7\u5206\u652F \u00B7 \u62D6\u52A8\u5206\u652F: \u79FB\u52A8 \u00B7 \u62D6\u52A8\u7A7A\u767D: \u5E73\u79FB \u00B7 Ctrl+\u6EDA\u8F6E: \u7F29\u653E\", newTopic: \"\u65B0\u5206\u652F\" },\n de: { map: \"Karte\", outline: \"Liste\", addChild: \"Unterzweig\", addSibling: \"Nebenzweig\", edit: \"Text bearbeiten\", remove: \"L\u00F6schen\", dirSide: \"Beidseitig\", dirRight: \"Nach rechts\", dirLeft: \"Nach links\", center: \"Zentrieren\", zoomIn: \"Vergr\u00F6\u00DFern\", zoomOut: \"Verkleinern\", mapHint: \"Doppelklick: bearbeiten \u00B7 Tab: Unterzweig \u00B7 Enter: Nebenzweig \u00B7 Zweig ziehen: verschieben \u00B7 Leere Fl\u00E4che ziehen: schwenken \u00B7 Strg+Rad: Zoom\", newTopic: \"Neuer Zweig\" },\n fr: { map: \"Carte\", outline: \"Liste\", addChild: \"Branche enfant\", addSibling: \"Branche s\u0153ur\", edit: \"Modifier le texte\", remove: \"Supprimer\", dirSide: \"Des deux c\u00F4t\u00E9s\", dirRight: \"Vers la droite\", dirLeft: \"Vers la gauche\", center: \"Centrer\", zoomIn: \"Zoomer\", zoomOut: \"D\u00E9zoomer\", mapHint: \"Double-clic : modifier \u00B7 Tab : enfant \u00B7 Entr\u00E9e : s\u0153ur \u00B7 Glisser une branche : d\u00E9placer \u00B7 Glisser le vide : d\u00E9filer \u00B7 Ctrl+molette : zoom\", newTopic: \"Nouvelle branche\" },\n it: { map: \"Mappa\", outline: \"Elenco\", addChild: \"Ramo figlio\", addSibling: \"Ramo fratello\", edit: \"Modifica testo\", remove: \"Elimina\", dirSide: \"Su entrambi i lati\", dirRight: \"Verso destra\", dirLeft: \"Verso sinistra\", center: \"Centra\", zoomIn: \"Ingrandisci\", zoomOut: \"Riduci\", mapHint: \"Doppio clic: modifica \u00B7 Tab: figlio \u00B7 Invio: fratello \u00B7 Trascina un ramo: sposta \u00B7 Trascina il vuoto: scorri \u00B7 Ctrl+rotella: zoom\", newTopic: \"Nuovo ramo\" },\n vi: { map: \"B\u1EA3n \u0111\u1ED3\", outline: \"Danh s\u00E1ch\", addChild: \"Nh\u00E1nh con\", addSibling: \"Nh\u00E1nh ngang\", edit: \"S\u1EEDa ch\u1EEF\", remove: \"X\u00F3a\", dirSide: \"M\u1EDF hai b\u00EAn\", dirRight: \"M\u1EDF sang ph\u1EA3i\", dirLeft: \"M\u1EDF sang tr\u00E1i\", center: \"V\u1EC1 gi\u1EEFa\", zoomIn: \"Ph\u00F3ng to\", zoomOut: \"Thu nh\u1ECF\", mapHint: \"Nh\u1EA5p \u0111\u00FAp: s\u1EEDa \u00B7 Tab: nh\u00E1nh con \u00B7 Enter: nh\u00E1nh ngang \u00B7 K\u00E9o nh\u00E1nh: di chuy\u1EC3n \u00B7 K\u00E9o ch\u1ED7 tr\u1ED1ng: cu\u1ED9n \u00B7 Ctrl+cu\u1ED9n: ph\u00F3ng to\", newTopic: \"Nh\u00E1nh m\u1EDBi\" },\n} as const;\n\nexport type MindMapStrings = OutlinerStrings & { [K in keyof (typeof STRINGS)[\"en\"]]: string };\n\nexport function mindMapStrings(locale?: string, overrides?: Partial<MindMapStrings>): MindMapStrings {\n const lang = (locale ?? \"en\").slice(0, 2).toLowerCase() as keyof typeof STRINGS;\n return { ...outlinerStrings(locale), ...(STRINGS[lang] ?? STRINGS.en), ...overrides };\n}\n", "/**\n * Standalone SVG of the map (for saving a picture next to the data). Built from the layout, not the DOM,\n * so it works while the map is hidden and looks the same in an <img>.\n */\nimport { DEFAULT_FONT_FAMILY } from \"@ehfuse/outliner\";\nimport { edgePath, layoutMap, nodeLook, type MapDirection } from \"./layout\";\nimport type { MindMapData } from \"./types\";\n\nconst esc = (text: string) => text.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\").replace(/\"/g, \""\");\n\nexport function exportMindMapSvg(data: MindMapData, options: { padding?: number; background?: string } = {}): string {\n const padding = options.padding ?? 24;\n const layout = layoutMap(data.nodeData, (data.direction ?? 2) as MapDirection);\n const { minX, minY, maxX, maxY } = layout.bounds;\n const width = Math.ceil(maxX - minX + padding * 2);\n const height = Math.ceil(maxY - minY + padding * 2);\n const ox = padding - minX;\n const oy = padding - minY;\n const parts: string[] = [];\n parts.push(`<rect width=\"${width}\" height=\"${height}\" fill=\"${options.background ?? \"#ffffff\"}\"/>`);\n parts.push(`<g transform=\"translate(${ox} ${oy})\">`);\n for (const edge of layout.edges) parts.push(`<path d=\"${edgePath(edge)}\" fill=\"none\" stroke=\"${edge.color}\" stroke-width=\"${edge.to.depth === 1 ? 2.5 : 1.75}\" stroke-linecap=\"round\"/>`);\n for (const ln of layout.nodes) {\n const look = nodeLook(ln);\n parts.push(\n `<rect x=\"${ln.x}\" y=\"${ln.y}\" width=\"${ln.w}\" height=\"${ln.h}\" rx=\"${look.radius}\" fill=\"${look.fill}\"${look.stroke !== \"none\" ? ` stroke=\"${look.stroke}\" stroke-width=\"${look.strokeWidth}\"` : \"\"}/>`\n );\n const deco = ln.node.style?.textDecoration;\n parts.push(\n `<text x=\"${ln.x + ln.w / 2}\" y=\"${ln.y + ln.h / 2}\" text-anchor=\"middle\" dominant-baseline=\"central\" font-family=\"${esc(DEFAULT_FONT_FAMILY)}\" font-size=\"${ln.fontSize}\" font-weight=\"${ln.fontWeight}\" fill=\"${look.text}\"${deco ? ` text-decoration=\"${esc(deco)}\"` : \"\"}>${esc(ln.node.topic)}</text>`\n );\n if (ln.node.expanded === false && (ln.node.children?.length ?? 0) > 0 && ln.depth > 0) {\n const cx = ln.side > 0 ? ln.x + ln.w + 10 : ln.x - 10;\n const cy = ln.y + ln.h / 2;\n parts.push(`<circle cx=\"${cx}\" cy=\"${cy}\" r=\"9\" fill=\"#ffffff\" stroke=\"${ln.color}\" stroke-width=\"1.5\"/>`);\n parts.push(`<text x=\"${cx}\" y=\"${cy}\" text-anchor=\"middle\" dominant-baseline=\"central\" font-family=\"${esc(DEFAULT_FONT_FAMILY)}\" font-size=\"10\" fill=\"${ln.color}\">${ln.node.children!.length}</text>`);\n }\n }\n parts.push(\"</g>\");\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\">${parts.join(\"\")}</svg>`;\n}\n", "export { MindMap, type MindMapProps, type MindMapHandle } from \"./MindMap\";\nexport { MapView, type MapViewProps, type MapViewHandle } from \"./MapView\";\nexport { exportMindMapSvg } from \"./exportSvg\";\nexport { layoutMap, edgePath, nodeLook, nodeSize, BRANCH_COLORS, type MapDirection, type LayoutNode, type LayoutEdge, type MapLayout } from \"./layout\";\nexport { mindMapStrings, type MindMapStrings } from \"./i18n\";\nexport type { MindMapData, MindMapView } from \"./types\";\nexport { createTree, type TreeNode, type TreeNodeStyle } from \"@ehfuse/outliner\";\n"],
|
|
5
|
+
"mappings": "AAIA,OAAS,cAAAA,GAAY,uBAAAC,GAAqB,UAAAC,GAAQ,YAAAC,OAAgC,QAClF,OAAS,OAAAC,EAAK,cAAAC,OAAkB,gBAChC,OAAS,kBAAAC,GAAgB,kBAAAC,GAAgB,mBAAAC,GAAiB,iBAAAC,GAAe,cAAAC,GAAY,eAAAC,OAAmB,wBACxG,OAAS,iBAAAC,GAAe,eAAAC,GAAa,cAAAC,GAAY,eAAAC,GAAa,cAAAC,GAAY,gBAAAC,GAAc,kBAAAC,OAAqC,mBCC7H,OAAS,cAAAC,GAAY,eAAAC,GAAa,aAAAC,GAAW,uBAAAC,GAAqB,mBAAAC,GAAiB,WAAAC,GAAS,UAAAC,EAAQ,YAAAC,MAAuD,QAC3J,OAAS,OAAAC,MAAW,gBACpB,OAAS,mBAAAC,GAAiB,cAAAC,GAAY,qBAAAC,GAAmB,aAAAC,OAAiB,wBAC1E,OACI,uBAAAC,GACA,cAAAC,GACA,YAAAC,GACA,cAAAC,GACA,gBAAAC,GACA,cAAAC,GACA,eAAAC,GACA,YAAAC,GACA,cAAAC,GACA,YAAAC,GACA,cAAAC,OAGG,mBCrBP,OAAS,eAAAC,OAAkC,mBAkCpC,IAAMC,GAAgB,CAAC,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,SAAS,EAC9GC,GAAa,GACbC,GAAQ,GACRC,GAAQ,GAGP,SAASC,GAASC,EAAgBC,EAAe,CACpD,IAAMC,EAAWF,EAAK,OAAO,SAAW,WAAWA,EAAK,MAAM,QAAQ,EAAIC,IAAU,EAAI,GAAKA,IAAU,EAAI,GAAK,GAC1GE,EAAaH,EAAK,OAAO,aAAeC,IAAU,EAAI,MAAQA,IAAU,EAAI,MAAQ,OAC1F,MAAO,CAAE,SAAAC,EAAU,WAAAC,CAAW,CAClC,CAEO,SAASC,EAASJ,EAAgBC,EAAe,CACpD,GAAM,CAAE,SAAAC,EAAU,WAAAC,CAAW,EAAIJ,GAASC,EAAMC,CAAK,EAC/CI,EAAOJ,IAAU,EAAI,GAAKA,IAAU,EAAI,GAAK,GAC7CK,EAAOL,IAAU,EAAI,GAAKA,IAAU,EAAI,EAAI,EAC5CM,EAAQb,GAAYM,EAAK,OAAS,IAAKE,EAAUC,CAAU,EACjE,MAAO,CACH,EAAG,KAAK,IAAIF,IAAU,EAAI,IAAM,GAAI,KAAK,KAAKM,CAAK,EAAIF,EAAO,CAAC,EAC/D,EAAG,KAAK,KAAKH,EAAW,GAAG,EAAII,EAAO,EACtC,SAAAJ,EACA,WAAAC,CACJ,CACJ,CAEA,IAAMK,GAAeR,GAAoBA,EAAK,WAAa,GAAQ,CAAC,EAAKA,EAAK,UAAY,CAAC,EAEpF,SAASS,EAAUC,EAAgBC,EAA0B,EAAc,CAC9E,IAAMC,EAAU,IAAI,IACdC,EAAU,CAACb,EAAgBC,IAA0B,CACvD,IAAMa,EAAMV,EAASJ,EAAMC,CAAK,EAAE,EAC5Bc,EAAOP,GAAYR,CAAI,EACvBgB,EAAMD,EAAK,OAAO,CAACE,EAAKC,IAAQD,EAAMJ,EAAQK,EAAKjB,EAAQ,CAAC,EAAG,CAAC,EAAIH,GAAQ,KAAK,IAAI,EAAGiB,EAAK,OAAS,CAAC,EACvGI,EAAQ,KAAK,IAAIL,EAAKE,CAAG,EAC/B,OAAAJ,EAAQ,IAAIZ,EAAK,GAAImB,CAAK,EACnBA,CACX,EAEMC,EAAsB,CAAC,EACvBC,EAAsB,CAAC,EACvBC,EAAWlB,EAASM,EAAM,CAAC,EAC3Ba,EAAqB,CAAE,GAAIb,EAAK,GAAI,KAAMA,EAAM,MAAO,EAAG,EAAG,CAACY,EAAS,EAAI,EAAG,EAAG,CAACA,EAAS,EAAI,EAAG,EAAGA,EAAS,EAAG,EAAGA,EAAS,EAAG,KAAM,EAAG,MAAO,UAAW,SAAU,KAAM,SAAUA,EAAS,SAAU,WAAYA,EAAS,UAAW,EAC9OF,EAAM,KAAKG,CAAM,EAEjB,IAAMC,EAAQ,CAACC,EAAoBV,EAAkBW,EAAczB,EAAe0B,IAAkD,CAChIZ,EAAK,QAASG,GAAQL,EAAQK,EAAKjB,CAAK,CAAC,EACzC,IAAM2B,EAAQb,EAAK,OAAO,CAACE,EAAKC,IAAQD,GAAOL,EAAQ,IAAIM,EAAI,EAAE,GAAK,GAAI,CAAC,EAAIpB,GAAQ,KAAK,IAAI,EAAGiB,EAAK,OAAS,CAAC,EAC9Gc,EAAMJ,EAAO,EAAIA,EAAO,EAAI,EAAIG,EAAQ,EACtCE,EAAM7B,IAAU,EAAIL,GAAaC,GACvCkB,EAAK,QAAQ,CAACG,EAAKa,IAAM,CACrB,IAAMC,EAAKpB,EAAQ,IAAIM,EAAI,EAAE,GAAK,EAC5Be,EAAO7B,EAASc,EAAKjB,CAAK,EAC1BiC,EAAKL,EAAMG,EAAK,EAChBG,EAAIT,EAAO,EAAID,EAAO,EAAIA,EAAO,EAAIK,EAAML,EAAO,EAAIK,EAAMG,EAAK,EACjEG,EAAQT,EAAQT,EAAKa,CAAC,EACtBM,EAAiB,CAAE,GAAInB,EAAI,GAAI,KAAMA,EAAK,MAAAjB,EAAO,EAAAkC,EAAG,EAAGD,EAAKD,EAAK,EAAI,EAAG,EAAGA,EAAK,EAAG,EAAGA,EAAK,EAAG,KAAAP,EAAM,MAAAU,EAAO,SAAUX,EAAO,GAAI,SAAUQ,EAAK,SAAU,WAAYA,EAAK,UAAW,EAC3Lb,EAAM,KAAKiB,CAAE,EACbhB,EAAM,KAAK,CAAE,KAAMI,EAAQ,GAAIY,EAAI,MAAAD,CAAM,CAAC,EAC1CZ,EAAMa,EAAI7B,GAAYU,CAAG,EAAGQ,EAAMzB,EAAQ,EAAG,IAAMmC,CAAK,EACxDP,GAAOG,EAAKlC,EAChB,CAAC,CACL,EAEMiB,EAAOP,GAAYE,CAAI,EACvB4B,EAAM5B,EAAK,UAAY,CAAC,EACxB6B,EAAYrB,GAAkBvB,GAAc,KAAK,IAAI,EAAG2C,EAAI,QAAQpB,CAAG,CAAC,EAAIvB,GAAc,MAAM,EAChG6C,EAAS,CAACtB,EAAea,IACvBpB,IAAc,EAAU,GACxBA,IAAc,EAAU,EACxBO,EAAI,YAAc,EAAU,GAC5BA,EAAI,YAAc,GAEfa,EAAI,KAAK,KAAKhB,EAAK,OAAS,CAAC,EAFJ,EAEY,GAE1C0B,EAAQ1B,EAAK,OAAO,CAACG,EAAKa,IAAMS,EAAOtB,EAAKa,CAAC,IAAM,CAAC,EACpDW,EAAO3B,EAAK,OAAO,CAACG,EAAKa,IAAMS,EAAOtB,EAAKa,CAAC,IAAM,EAAE,EAC1DP,EAAMD,EAAQkB,EAAO,EAAG,EAAGF,CAAQ,EACnCf,EAAMD,EAAQmB,EAAM,GAAI,EAAGH,CAAQ,EAEnC,IAAMI,EAAS,CAAE,KAAM,IAAU,KAAM,IAAU,KAAM,KAAW,KAAM,IAAU,EAClF,QAAWC,KAAKxB,EACZuB,EAAO,KAAO,KAAK,IAAIA,EAAO,KAAMC,EAAE,CAAC,EACvCD,EAAO,KAAO,KAAK,IAAIA,EAAO,KAAMC,EAAE,CAAC,EACvCD,EAAO,KAAO,KAAK,IAAIA,EAAO,KAAMC,EAAE,EAAIA,EAAE,CAAC,EAC7CD,EAAO,KAAO,KAAK,IAAIA,EAAO,KAAMC,EAAE,EAAIA,EAAE,CAAC,EAEjD,MAAO,CAAE,MAAAxB,EAAO,KAAM,IAAI,IAAIA,EAAM,IAAKwB,GAAM,CAACA,EAAE,GAAIA,CAAC,CAAC,CAAC,EAAG,MAAAvB,EAAO,OAAAsB,CAAO,CAC9E,CAGO,SAASE,EAASC,EAA0B,CAC/C,GAAM,CAAE,KAAAC,EAAM,GAAAC,CAAG,EAAIF,EACfpB,EAAOsB,EAAG,MAAQ,EAAI,EAAI,GAC1BC,EAAKF,EAAK,QAAU,EAAIA,EAAK,EAAIA,EAAK,EAAI,EAAKrB,EAAOqB,EAAK,EAAK,EAAIrB,EAAO,GAAKA,EAAO,EAAIqB,EAAK,EAAIA,EAAK,EAAIA,EAAK,EAClHG,EAAKH,EAAK,EAAIA,EAAK,EAAI,EACvBI,EAAKzB,EAAO,EAAIsB,EAAG,EAAIA,EAAG,EAAIA,EAAG,EACjCI,EAAKJ,EAAG,EAAIA,EAAG,EAAI,EACnBK,GAAMF,EAAKF,GAAM,GACvB,MAAO,KAAKA,CAAE,IAAIC,CAAE,MAAMD,EAAKI,CAAE,IAAIH,CAAE,KAAKC,EAAKE,CAAE,IAAID,CAAE,KAAKD,CAAE,IAAIC,CAAE,EAC1E,CAGO,SAASE,EAASjB,EAAgB,CACrC,IAAMkB,EAAQlB,EAAG,KAAK,OAAS,CAAC,EAChC,OAAIA,EAAG,QAAU,EAAU,CAAE,KAAMkB,EAAM,YAAc,UAAW,OAAQ,OAAQ,YAAa,EAAG,KAAMA,EAAM,OAAS,UAAW,OAAQlB,EAAG,EAAI,CAAE,EAC/IA,EAAG,QAAU,EAAU,CAAE,KAAMkB,EAAM,YAAc,UAAW,OAAQlB,EAAG,MAAO,YAAa,EAAG,KAAMkB,EAAM,OAAS,UAAW,OAAQlB,EAAG,EAAI,CAAE,EAC9I,CAAE,KAAMkB,EAAM,YAAc,UAAW,OAAQ,UAAW,YAAa,EAAG,KAAMA,EAAM,OAAS,UAAW,OAAQ,CAAE,CAC/H,CD8GQ,cAAAC,EAgCgB,QAAAC,MAhChB,oBA/MR,IAAMC,GAAW,GACXC,GAAW,IACXC,GAAa,EAINC,GAAUC,GAAwC,SAAiB,CAAE,KAAAC,EAAM,UAAAC,EAAW,OAAAC,EAAQ,WAAAC,EAAY,SAAAC,EAAU,QAAAC,EAAS,SAAAC,EAAU,OAAAC,EAAQ,OAAAC,EAAQ,KAAAC,EAAO,EAAK,EAAGC,EAAK,CACpL,IAAMC,EAASC,EAA8B,IAAI,EAC3C,CAACC,EAAMC,CAAO,EAAIC,EAAS,CAAE,EAAG,EAAG,EAAG,CAAE,CAAC,EACzC,CAACC,EAAMC,CAAO,EAAIF,EAAS,CAAE,EAAG,EAAG,EAAG,EAAG,EAAG,CAAE,CAAC,EAC/CG,EAAUN,EAAOI,CAAI,EAC3BE,EAAQ,QAAUF,EAClB,GAAM,CAACG,EAASC,CAAU,EAAIL,EAA8C,IAAI,EAC1E,CAACM,EAAMC,CAAO,EAAIP,EAAyG,IAAI,EAC/HQ,EAAUX,EAAqH,IAAI,EACnIY,EAASC,GAAQ,IAAMC,EAAU1B,EAAMC,CAAS,EAAG,CAACD,EAAMC,CAAS,CAAC,EAGpE0B,EAAWf,EAAO,EAAK,EAC7BgB,GAAgB,IAAM,CAClB,IAAMC,EAAKlB,EAAO,QAClB,GAAI,CAACkB,EAAI,OACT,IAAMC,EAAK,IAAI,eAAe,IAAMhB,EAAQ,CAAE,EAAGe,EAAG,YAAa,EAAGA,EAAG,YAAa,CAAC,CAAC,EACtF,OAAAC,EAAG,QAAQD,CAAE,EACbf,EAAQ,CAAE,EAAGe,EAAG,YAAa,EAAGA,EAAG,YAAa,CAAC,EAC1C,IAAMC,EAAG,WAAW,CAC/B,EAAG,CAAC,CAAC,EACL,IAAMC,EAASC,GAAY,IAAM,CAC7B,GAAM,CAAE,KAAAC,EAAM,KAAAC,EAAM,KAAAC,EAAM,KAAAC,CAAK,EAAIZ,EAAO,OACpCa,EAAInB,EAAQ,QAAQ,EAC1BD,EAAQ,CAAE,EAAGJ,EAAK,EAAI,GAAMoB,EAAOE,GAAQ,EAAKE,EAAG,EAAGxB,EAAK,EAAI,GAAMqB,EAAOE,GAAQ,EAAKC,EAAG,EAAAA,CAAE,CAAC,CACnG,EAAG,CAACb,EAAQX,CAAI,CAAC,EACjByB,GAAU,IAAM,CACRX,EAAS,SAAWd,EAAK,IAAM,IACnCc,EAAS,QAAU,GACnBI,EAAO,EACX,EAAG,CAAClB,EAAMkB,CAAM,CAAC,EACjB,IAAMQ,EAASP,GAAY,CAACQ,EAAgBC,EAAYC,IAAe,CACnEzB,EAAS0B,GAAM,CACX,IAAMN,EAAI,KAAK,IAAIzC,GAAU,KAAK,IAAID,GAAUgD,EAAE,EAAIH,CAAM,CAAC,EAC7D,MAAO,CAAE,EAAGC,GAAMA,EAAKE,EAAE,IAAMN,EAAIM,EAAE,GAAI,EAAGD,GAAMA,EAAKC,EAAE,IAAMN,EAAIM,EAAE,GAAI,EAAAN,CAAE,CAC/E,CAAC,CACL,EAAG,CAAC,CAAC,EACLO,GAAoBlC,EAAK,KAAO,CAAE,OAAAqB,EAAQ,OAASS,GAAWD,EAAOC,EAAQ3B,EAAK,EAAI,EAAGA,EAAK,EAAI,CAAC,CAAE,GAAI,CAACkB,EAAQQ,EAAQ1B,CAAI,CAAC,EAG/HyB,GAAU,IAAM,CACZ,IAAMT,EAAKlB,EAAO,QAClB,GAAI,CAACkB,EAAI,OACT,IAAMgB,EAAWC,GAAsB,CACnC,GAAI,EAAEA,EAAM,SAAWA,EAAM,SAAU,OACvCA,EAAM,eAAe,EACrB,IAAMC,EAAIlB,EAAG,sBAAsB,EACnCU,EAAOO,EAAM,OAAS,EAAI,IAAM,EAAI,IAAKA,EAAM,QAAUC,EAAE,KAAMD,EAAM,QAAUC,EAAE,GAAG,CAC1F,EACA,OAAAlB,EAAG,iBAAiB,QAASgB,EAAS,CAAE,QAAS,EAAM,CAAC,EACjD,IAAMhB,EAAG,oBAAoB,QAASgB,CAAO,CACxD,EAAG,CAACN,CAAM,CAAC,EAEX,IAAMS,EAAQ,CAACC,EAAyBC,EAAmBC,EAAU,KAAU,CACtEF,IACL/C,EAAO+C,EAAO,KAAMC,CAAQ,EACxBD,EAAO,UACP7C,EAAS6C,EAAO,OAAO,EACnBE,GAAS/B,EAAW,CAAE,GAAI6B,EAAO,QAAS,KAAM,EAAG,CAAC,GAEhE,EACMG,EAAaC,GAAe,CAC9B,GAAI/C,EAAU,OACd,IAAMgD,EAAKC,GAAWvD,EAAMqD,CAAE,EAC1BC,GAAIlC,EAAW,CAAE,GAAAiC,EAAI,KAAMC,EAAG,KAAK,KAAM,CAAC,CAClD,EACME,EAAa,IAAM,CAChBrC,IACL6B,EAAMS,GAASzD,EAAMmB,EAAQ,GAAIA,EAAQ,IAAI,CAAC,EAC9CC,EAAW,IAAI,EACfT,EAAO,SAAS,MAAM,CAAE,cAAe,EAAK,CAAC,EACjD,EAEM+C,EAAW,CAACC,EAAiBC,IAAoB,CACnD,IAAMb,EAAIpC,EAAO,QAAS,sBAAsB,EAChD,MAAO,CAAE,GAAIgD,EAAUZ,EAAE,KAAO/B,EAAK,GAAKA,EAAK,EAAG,GAAI4C,EAAUb,EAAE,IAAM/B,EAAK,GAAKA,EAAK,CAAE,CAC7F,EACM6C,EAAS,CAACF,EAAiBC,EAAiBE,IAA+D,CAC7G,IAAMC,EAAIL,EAASC,EAASC,CAAO,EACnC,QAAWI,KAAMxC,EAAO,MAAO,CAC3B,GAAIuC,EAAE,EAAIC,EAAG,EAAI,GAAKD,EAAE,EAAIC,EAAG,EAAIA,EAAG,EAAI,GAAKD,EAAE,EAAIC,EAAG,EAAI,GAAKD,EAAE,EAAIC,EAAG,EAAIA,EAAG,EAAI,EAAG,SACxF,GAAIC,GAAaH,EAASE,EAAG,EAAE,EAAG,OAAO,KACzC,GAAIA,EAAG,QAAU,EAAG,MAAO,CAAE,GAAIA,EAAG,GAAI,MAAO,OAAQ,EACvD,IAAME,GAAOH,EAAE,EAAIC,EAAG,GAAKA,EAAG,EAC9B,MAAO,CAAE,GAAIA,EAAG,GAAI,MAAOE,EAAM,IAAO,SAAWA,EAAM,IAAO,QAAU,OAAQ,CACtF,CACA,OAAO,IACX,EAEMC,GAAiBrB,GAAwC,CAC3D,GAAIA,EAAM,SAAW,EAAG,OACxB,IAAMsB,EAAStB,EAAM,OAGrB,GAFIsB,EAAO,QAAQ,cAAc,IAC7BjD,GAAW,CAACiD,EAAO,QAAQ,gBAAgB,GAAGZ,EAAW,EACzDY,EAAO,QAAQ,gBAAgB,GAAG,OACtC,IAAMC,EAAOD,EAAO,QAAQ,gBAAgB,EAC5C,GAAIC,EAAM,CACNrB,EAAMsB,GAAWtE,EAAMqE,EAAK,QAAQ,MAAO,CAAC,EAC5C,MACJ,CACA,IAAME,EAASH,EAAO,QAAQ,gBAAgB,EAG9C,GAFAzD,EAAO,SAAS,MAAM,CAAE,cAAe,EAAK,CAAC,EAEzC4D,EAAQ,CACR,IAAMlB,EAAKkB,EAAO,QAAQ,OAC1BnE,EAASiD,CAAE,EACX9B,EAAQ,QAAU,CAAE,KAAM,OAAQ,GAAA8B,EAAI,GAAIP,EAAM,QAAS,GAAIA,EAAM,QAAS,GAAI9B,EAAK,EAAG,GAAIA,EAAK,EAAG,MAAO,EAAM,CACrH,MACIZ,EAAS,IAAI,EACbmB,EAAQ,QAAU,CAAE,KAAM,MAAO,GAAIuB,EAAM,QAAS,GAAIA,EAAM,QAAS,GAAI9B,EAAK,EAAG,GAAIA,EAAK,EAAG,MAAO,EAAM,CAEpH,EACMwD,GAAiB1B,GAAwC,CAC3D,IAAMiB,EAAIxC,EAAQ,QAClB,GAAI,CAACwC,EAAG,OACR,IAAMU,EAAK3B,EAAM,QAAUiB,EAAE,GACvBW,EAAK5B,EAAM,QAAUiB,EAAE,GAC7B,GAAI,CAACA,EAAE,OAAS,KAAK,MAAMU,EAAIC,CAAE,EAAI7E,GAAY,OAGjD,GAFI,CAACkE,EAAE,OAAS,CAACpD,EAAO,SAAS,kBAAkBmC,EAAM,SAAS,GAAGnC,EAAO,SAAS,kBAAkBmC,EAAM,SAAS,EACtHiB,EAAE,MAAQ,GACNA,EAAE,OAAS,MAAO,CAClB9C,EAAS0B,IAAO,CAAE,GAAGA,EAAG,EAAGoB,EAAE,GAAKU,EAAI,EAAGV,EAAE,GAAKW,CAAG,EAAE,EACrD,MACJ,CACA,GAAIpE,GAAYyD,EAAE,KAAO/D,EAAK,GAAI,OAClC,IAAM8D,EAAUP,GAAWvD,EAAM+D,EAAE,EAAG,GAAG,KACzC,GAAI,CAACD,EAAS,OACd,IAAMf,EAAIpC,EAAO,QAAS,sBAAsB,EAChDW,EAAQ,CAAE,GAAIyC,EAAE,GAAK,GAAIjB,EAAM,QAAUC,EAAE,KAAM,GAAID,EAAM,QAAUC,EAAE,IAAK,OAAQc,EAAOf,EAAM,QAASA,EAAM,QAASgB,CAAO,CAAE,CAAC,CACvI,EACMa,GAAe7B,GAAwC,CACzD,IAAMiB,EAAIxC,EAAQ,QAClBA,EAAQ,QAAU,KACdZ,EAAO,SAAS,kBAAkBmC,EAAM,SAAS,GAAGnC,EAAO,QAAQ,sBAAsBmC,EAAM,SAAS,EACxGiB,GAAG,OAAS,QAAU1C,GAAM,QAAQ2B,EAAM4B,GAAS5E,EAAMqB,EAAK,GAAIA,EAAK,OAAO,GAAIA,EAAK,OAAO,KAAK,CAAC,EACxGC,EAAQ,IAAI,CAChB,EAEMuD,GAAW,CAACb,EAAgBc,IAA+B,CAC7D,IAAMxB,EAAKC,GAAWvD,EAAMgE,EAAG,EAAE,EACjC,GAAI,CAACV,EAAI,OAAO,KAChB,GAAIwB,IAAQ,WAAaA,IAAQ,YAAa,CAC1C,GAAI,CAACxB,EAAG,OAAQ,OAAO,KACvB,IAAMyB,GAAQzB,EAAG,OAAO,UAAY,CAAC,GAAG,OAAQ0B,GAAQxD,EAAO,KAAK,IAAIwD,EAAI,EAAE,GAAG,OAAShB,EAAG,IAAI,EAC3FiB,EAAIF,EAAK,UAAWC,GAAQA,EAAI,KAAOhB,EAAG,EAAE,EAClD,OAAOe,EAAKE,GAAKH,IAAQ,UAAY,GAAK,EAAE,GAAG,IAAM,IACzD,CAEA,GADiBA,IAAQ,cAAgBd,EAAG,MAAQ,GAAOc,IAAQ,aAAed,EAAG,MAAQ,EAChF,CACT,IAAMkB,EAAO5B,EAAG,KAAK,WAAa,GAAQ,CAAC,EAAKA,EAAG,KAAK,UAAY,CAAC,EAC/D6B,EAAOnB,EAAG,OAAS,EAAKc,IAAQ,aAAe,EAAI,GAAMd,EAAG,KAClE,OAAOkB,EAAK,KAAMF,GAAQxD,EAAO,KAAK,IAAIwD,EAAI,EAAE,GAAG,OAASG,CAAI,GAAG,IAAM,IAC7E,CACA,OAAOnB,EAAG,QACd,EACMoB,GAAatC,GAAyC,CACxD,GAAI3B,GAAY2B,EAAM,OAAuB,UAAY,QAAS,OAClE,IAAMuC,EAAMvC,EAAM,SAAWA,EAAM,QACnC,GAAIuC,IAAQvC,EAAM,MAAQ,KAAOA,EAAM,MAAQ,KAAM,CACjDA,EAAM,eAAe,EACjBA,EAAM,SAAUtC,IAAS,EACxBD,IAAS,EACd,MACJ,CACA,GAAI8E,IAAQvC,EAAM,MAAQ,KAAOA,EAAM,MAAQ,KAAM,CACjDA,EAAM,eAAe,EACrBtC,IAAS,EACT,MACJ,CACA,IAAMwD,EAAK7D,EAAaqB,EAAO,KAAK,IAAIrB,CAAU,EAAI,KACtD,GAAK6D,EACL,IAAIlB,EAAM,IAAI,WAAW,OAAO,EAAG,CAC/B,IAAMwC,EAAOT,GAASb,EAAIlB,EAAM,GAAG,EACnCA,EAAM,eAAe,EACjBwC,GAAMlF,EAASkF,CAAI,EACvB,MACJ,CACIhF,IACAwC,EAAM,MAAQ,OACdA,EAAM,eAAe,EACrBE,EAAMuC,GAASvF,EAAMgE,EAAG,EAAE,EAAG,OAAW,EAAI,GACrClB,EAAM,MAAQ,SACrBA,EAAM,eAAe,EACrBE,EAAMwC,GAAWxF,EAAMgE,EAAG,EAAE,EAAG,OAAW,EAAI,GACvClB,EAAM,MAAQ,MACrBA,EAAM,eAAe,EACrBM,EAAUY,EAAG,EAAE,GACRlB,EAAM,MAAQ,UAAYA,EAAM,MAAQ,aAC/CA,EAAM,eAAe,EACrBE,EAAMyC,GAAWzF,EAAMgE,EAAG,EAAE,CAAC,GACtBlB,EAAM,MAAQ,MACrBA,EAAM,eAAe,EACrBE,EAAMsB,GAAWtE,EAAMgE,EAAG,EAAE,CAAC,IAErC,EAEM0B,EAAWvF,EAAaqB,EAAO,KAAK,IAAIrB,CAAU,EAAI,OACtDwF,EAAYxE,EAAUK,EAAO,KAAK,IAAIL,EAAQ,EAAE,EAAI,OACpDyE,GAASvE,EAAOG,EAAO,KAAK,IAAIH,EAAK,EAAE,EAAI,OAC3CwE,EAASxE,GAAM,OAASG,EAAO,KAAK,IAAIH,EAAK,OAAO,EAAE,EAAI,OAC1DyE,EAAY,CAAChB,EAAaiB,EAAeC,EAAuBC,IAClExG,EAACyG,GAAA,CAAqB,MAAOH,EAAO,QAASE,EACxC,SAAAD,GADYlB,CAEjB,EAGJ,OACIpF,EAACyG,EAAA,CACG,IAAKxF,EACL,SAAU,EACV,UAAWyE,GACX,cAAejB,GACf,cAAeK,GACf,YAAaG,GACb,gBAAiBA,GACjB,cAAgB7B,GAAU,CACtB,IAAMyB,EAAUzB,EAAM,OAAuB,QAAQ,gBAAgB,EACjEyB,GAAQnB,EAAUmB,EAAO,QAAQ,MAAO,CAChD,EACA,GAAI,CAAE,SAAU,WAAY,MAAO,OAAQ,OAAQ,OAAQ,SAAU,SAAU,QAAS,UAAW,QAAS,OAAQ,YAAa,OAAQ,WAAY,OAAQ,OAAQhD,EAAQ,SAAS,OAAS,MAAQ,WAAa,SAAU,EAE9N,UAAA7B,EAACyG,EAAA,CAAI,GAAI,CAAE,SAAU,WAAY,KAAM,EAAG,IAAK,EAAG,UAAW,aAAanF,EAAK,CAAC,OAAOA,EAAK,CAAC,aAAaA,EAAK,CAAC,IAAK,gBAAiB,KAAM,EACxI,UAAAvB,EAAC,OAAI,MAAO,CAAE,SAAU,WAAY,KAAM,EAAG,IAAK,EAAG,MAAO,EAAG,OAAQ,EAAG,SAAU,SAAU,EACzF,SAAA+B,EAAO,MAAM,IAAK4E,GACf3G,EAAC,QAAsB,EAAG4G,EAASD,CAAI,EAAG,KAAK,OAAO,OAAQA,EAAK,MAAO,YAAaA,EAAK,GAAG,QAAU,EAAI,IAAM,KAAM,cAAc,SAA5HA,EAAK,GAAG,EAA4H,CAClJ,EACL,EACC5E,EAAO,MAAM,IAAKwC,GAAO,CACtB,IAAMsC,EAAOC,EAASvC,CAAE,EAClBkB,EAAOlB,EAAG,KAAK,UAAU,QAAU,EACnCwC,EAASxC,EAAG,KAAK,WAAa,IAASkB,EAAO,EAC9CuB,EAAQzC,EAAG,KAAO7D,EACxB,OACIT,EAACyG,EAAA,CAEG,eAAcnC,EAAG,GACjB,GAAI,CACA,SAAU,WACV,KAAMA,EAAG,EACT,IAAKA,EAAG,EACR,MAAOA,EAAG,EACV,OAAQA,EAAG,EACX,UAAW,aACX,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,aAAc,GAAGsC,EAAK,MAAM,KAC5B,QAASA,EAAK,KACd,OAAQA,EAAK,SAAW,OAAS,GAAGA,EAAK,WAAW,YAAYA,EAAK,MAAM,GAAK,EAChF,MAAOA,EAAK,KACZ,WAAYI,GACZ,SAAU1C,EAAG,SACb,WAAYA,EAAG,WACf,eAAgBA,EAAG,KAAK,OAAO,eAC/B,WAAY,SACZ,OAAQ1D,EAAW,UAAY,UAC/B,UAAWmG,EAAQ,oCAAsCzC,EAAG,QAAU,EAAI,6BAA+B,OACzG,QAAS3C,GAAM,KAAO2C,EAAG,GAAK,IAAO,EACrC,mBAAoB,CAAE,QAAS,CAAE,CACrC,EAEC,UAAA7C,GAAS,KAAO6C,EAAG,GAAK,KAAOA,EAAG,KAAK,OAAS,OAChDkB,EAAO,GAAKlB,EAAG,MAAQ,EACpBvE,EAAC0G,EAAA,CACG,UAAU,UACV,eAAcnC,EAAG,GACjB,MAAOwC,EAASnG,EAAQ,OAASA,EAAQ,KACzC,GAAI,CACA,SAAU,WACV,IAAK,MACL,CAAC2D,EAAG,KAAO,EAAI,OAAS,OAAO,EAAG,OAClC,UAAW,aAAaA,EAAG,KAAO,EAAI,EAAI,EAAE,YAC5C,SAAU,GACV,OAAQ,GACR,GAAIwC,EAAS,GAAM,EACnB,UAAW,aACX,aAAc,EACd,QAAS,OACT,OAAQ,eAAexC,EAAG,KAAK,GAC/B,MAAOA,EAAG,MACV,SAAU,GACV,WAAY,IACZ,WAAY,OACZ,UAAW,SACX,OAAQ,UACR,QAASwC,GAAUC,EAAQ,EAAI,EAC/B,eAAgB,MACpB,EAEC,SAAAD,EAAStB,EAAO,SACrB,EACA,OAzDClB,EAAG,EA0DZ,CAER,CAAC,EAEA6B,GAAUxE,GAAM,OACbA,EAAK,OAAO,QAAU,QAClB5B,EAAC0G,EAAA,CAAI,GAAI,CAAE,SAAU,WAAY,KAAMN,EAAO,EAAI,EAAG,IAAKA,EAAO,EAAI,EAAG,MAAOA,EAAO,EAAI,EAAG,OAAQA,EAAO,EAAI,EAAG,OAAQ,qBAAsB,aAAc,EAAG,cAAe,MAAO,EAAG,EAE3LpG,EAAC0G,EAAA,CAAI,GAAI,CAAE,SAAU,WAAY,KAAMN,EAAO,EAAG,IAAKxE,EAAK,OAAO,QAAU,SAAWwE,EAAO,EAAI,EAAIA,EAAO,EAAIA,EAAO,EAAI,EAAG,MAAOA,EAAO,EAAG,OAAQ,EAAG,aAAc,EAAG,QAAS,UAAW,cAAe,MAAO,EAAG,EAE7N,KACHF,GAAaxE,EACV1B,EAAC,SACG,eAAa,GACb,UAAS,GACT,MAAO0B,EAAQ,KACf,WAAY,GACZ,QAAU2B,GAAUA,EAAM,cAAc,OAAO,EAC/C,SAAWA,GAAU1B,EAAW,CAAE,GAAID,EAAQ,GAAI,KAAM2B,EAAM,OAAO,KAAM,CAAC,EAC5E,OAAQU,EACR,UAAYV,GAAU,CAElB,GADAA,EAAM,gBAAgB,EAClB,CAAAA,EAAM,YAAY,aACtB,GAAIA,EAAM,MAAQ,QACdA,EAAM,eAAe,EACrBU,EAAW,UACJV,EAAM,MAAQ,SACrBA,EAAM,eAAe,EACrB1B,EAAW,IAAI,EACfT,EAAO,SAAS,MAAM,CAAE,cAAe,EAAK,CAAC,UACtCmC,EAAM,MAAQ,MAAO,CAC5BA,EAAM,eAAe,EACrB,IAAMO,EAAKlC,EAAQ,GACbwF,EAAOxF,EAAQ,KACrBC,EAAW,IAAI,EACf,IAAMwF,EAAQnD,GAASzD,EAAMqD,EAAIsD,CAAI,EACrC3D,EAAMuC,GAASqB,GAAO,MAAQ5G,EAAMqD,CAAE,EAAG,OAAW,EAAI,CAC5D,EACJ,EACA,MAAO,CACH,SAAU,WACV,KAAMsC,EAAU,EAChB,IAAKA,EAAU,EACf,MAAO,KAAK,IAAIA,EAAU,EAAG,KAAK,KAAKkB,GAAY1F,EAAQ,MAAQ,IAAKwE,EAAU,SAAUA,EAAU,UAAU,CAAC,EAAI,EAAE,EACvH,OAAQA,EAAU,EAClB,UAAW,aACX,QAAS,SACT,OAAQ,oBACR,aAAc,EACd,QAAS,OACT,UAAW,SACX,WAAYe,GACZ,SAAUf,EAAU,SACpB,WAAYA,EAAU,WACtB,MAAO,UACP,WAAY,OACZ,OAAQ,CACZ,EACJ,EACA,MACR,EAECtE,GAAQuE,GACLnG,EAAC0G,EAAA,CAAI,GAAI,CAAE,SAAU,WAAY,KAAM9E,EAAK,GAAK,GAAI,IAAKA,EAAK,GAAK,GAAI,GAAI,IAAK,GAAI,GAAK,aAAc,EAAG,QAAS,OAAQ,OAAQ,eAAeuE,GAAO,KAAK,GAAI,SAAU,GAAI,QAAS,GAAK,cAAe,OAAQ,UAAW,6BAA8B,EAC1P,SAAAA,GAAO,KAAK,OAAS,OAC1B,EACA,KAEHF,GAAY,CAACvE,GAAW,CAACE,GAAQ,CAACf,EAC/BZ,EAACyG,EAAA,CACG,aAAW,GACX,GAAI,CACA,SAAU,WACV,KAAMnF,EAAK,GAAK0E,EAAS,EAAIA,EAAS,EAAI,GAAK1E,EAAK,EACpD,IAAKA,EAAK,EAAI0E,EAAS,EAAI1E,EAAK,EAChC,UAAW,qCACX,QAAS,OACT,IAAK,IACL,EAAG,IACH,QAAS,OACT,OAAQ,oBACR,aAAc,EACd,UAAW,6BACX,OAAQ,CACZ,EAEC,UAAA8E,EAAU,QAASzF,EAAQ,SAAUZ,EAACqH,GAAA,EAAgB,EAAI,IAAM9D,EAAMuC,GAASvF,EAAM0F,EAAS,EAAE,EAAG,OAAW,EAAI,CAAC,EACnHA,EAAS,MAAQ,EAAII,EAAU,UAAWzF,EAAQ,WAAYZ,EAACsH,GAAA,EAAkB,EAAI,IAAM/D,EAAMwC,GAAWxF,EAAM0F,EAAS,EAAE,EAAG,OAAW,EAAI,CAAC,EAAI,KACpJI,EAAU,OAAQzF,EAAQ,KAAMZ,EAACuH,GAAA,EAAW,EAAI,IAAM5D,EAAUsC,EAAS,EAAE,CAAC,EAC5EA,EAAS,MAAQ,EAAII,EAAU,SAAUzF,EAAQ,OAAQZ,EAACwH,GAAA,EAAU,EAAI,IAAMjE,EAAMyC,GAAWzF,EAAM0F,EAAS,EAAE,CAAC,CAAC,EAAI,MAC3H,EACA,KACHjF,EACGhB,EAAC0G,EAAA,CAAI,GAAI,CAAE,SAAU,WAAY,KAAM,GAAI,MAAO,GAAI,OAAQ,EAAG,SAAU,GAAI,WAAY,IAAK,MAAO,iBAAkB,cAAe,MAAO,EAC3I,SAAA1G,EAAC0G,EAAA,CAAI,UAAU,OAAO,GAAI,CAAE,QAAS,wBAAyB,EACzD,SAAA9F,EAAQ,QACb,EACJ,EACA,MACR,CAER,CAAC,EE/bD,OAAS,mBAAA6G,OAA6C,mBAGtD,IAAMC,GAAU,CACZ,GAAI,CAAE,IAAK,eAAM,QAAS,eAAM,SAAU,4BAAS,WAAY,sBAAQ,KAAM,4BAAS,OAAQ,qBAAO,QAAS,8CAAY,SAAU,oDAAa,QAAS,8CAAY,OAAQ,2BAAQ,OAAQ,eAAM,QAAS,eAAM,QAAS,4PAAmF,SAAU,qBAAO,EAChU,GAAI,CAAE,IAAK,MAAO,QAAS,OAAQ,SAAU,eAAgB,WAAY,iBAAkB,KAAM,YAAa,OAAQ,SAAU,QAAS,iBAAkB,SAAU,oBAAqB,QAAS,mBAAoB,OAAQ,SAAU,OAAQ,UAAW,QAAS,WAAY,QAAS,mIAAqH,SAAU,YAAa,EACta,GAAI,CAAE,IAAK,qBAAO,QAAS,qBAAO,SAAU,qBAAO,WAAY,qBAAO,KAAM,iCAAS,OAAQ,eAAM,QAAS,uCAAU,SAAU,iCAAS,QAAS,iCAAS,OAAQ,qBAAO,OAAQ,eAAM,QAAS,eAAM,QAAS,0SAAoF,SAAU,0BAAO,EACrT,GAAI,CAAE,IAAK,eAAM,QAAS,eAAM,SAAU,qBAAO,WAAY,2BAAQ,KAAM,2BAAQ,OAAQ,eAAM,QAAS,2BAAQ,SAAU,2BAAQ,QAAS,2BAAQ,OAAQ,eAAM,OAAQ,eAAM,QAAS,eAAM,QAAS,4NAAuE,SAAU,oBAAM,EAChS,GAAI,CAAE,IAAK,QAAS,QAAS,QAAS,SAAU,aAAc,WAAY,aAAc,KAAM,kBAAmB,OAAQ,aAAW,QAAS,aAAc,SAAU,cAAe,QAAS,aAAc,OAAQ,aAAc,OAAQ,mBAAc,QAAS,cAAe,QAAS,gKAA+I,SAAU,aAAc,EAC/b,GAAI,CAAE,IAAK,QAAS,QAAS,QAAS,SAAU,iBAAkB,WAAY,oBAAgB,KAAM,oBAAqB,OAAQ,YAAa,QAAS,uBAAkB,SAAU,iBAAkB,QAAS,iBAAkB,OAAQ,UAAW,OAAQ,SAAU,QAAS,cAAY,QAAS,wKAA4I,SAAU,kBAAmB,EAC5c,GAAI,CAAE,IAAK,QAAS,QAAS,SAAU,SAAU,cAAe,WAAY,gBAAiB,KAAM,iBAAkB,OAAQ,UAAW,QAAS,qBAAsB,SAAU,eAAgB,QAAS,iBAAkB,OAAQ,SAAU,OAAQ,cAAe,QAAS,SAAU,QAAS,mJAAqI,SAAU,YAAa,EAC7b,GAAI,CAAE,IAAK,wBAAU,QAAS,eAAa,SAAU,eAAa,WAAY,iBAAe,KAAM,oBAAW,OAAQ,SAAO,QAAS,qBAAc,SAAU,yBAAgB,QAAS,uBAAgB,OAAQ,oBAAW,OAAQ,cAAY,QAAS,eAAW,QAAS,qMAA0H,SAAU,mBAAY,CAC/Z,EAIO,SAASC,GAAeC,EAAiBC,EAAqD,CACjG,IAAMC,GAAQF,GAAU,MAAM,MAAM,EAAG,CAAC,EAAE,YAAY,EACtD,MAAO,CAAE,GAAGH,GAAgBG,CAAM,EAAG,GAAIF,GAAQI,CAAI,GAAKJ,GAAQ,GAAK,GAAGG,CAAU,CACxF,CCfA,OAAS,uBAAAE,OAA2B,mBAIpC,IAAMC,GAAOC,GAAiBA,EAAK,QAAQ,KAAM,OAAO,EAAE,QAAQ,KAAM,MAAM,EAAE,QAAQ,KAAM,MAAM,EAAE,QAAQ,KAAM,QAAQ,EAErH,SAASC,GAAiBC,EAAmBC,EAAqD,CAAC,EAAW,CACjH,IAAMC,EAAUD,EAAQ,SAAW,GAC7BE,EAASC,EAAUJ,EAAK,SAAWA,EAAK,WAAa,CAAkB,EACvE,CAAE,KAAAK,EAAM,KAAAC,EAAM,KAAAC,EAAM,KAAAC,CAAK,EAAIL,EAAO,OACpCM,EAAQ,KAAK,KAAKF,EAAOF,EAAOH,EAAU,CAAC,EAC3CQ,EAAS,KAAK,KAAKF,EAAOF,EAAOJ,EAAU,CAAC,EAC5CS,EAAKT,EAAUG,EACfO,EAAKV,EAAUI,EACfO,EAAkB,CAAC,EACzBA,EAAM,KAAK,gBAAgBJ,CAAK,aAAaC,CAAM,WAAWT,EAAQ,YAAc,SAAS,KAAK,EAClGY,EAAM,KAAK,2BAA2BF,CAAE,IAAIC,CAAE,KAAK,EACnD,QAAWE,KAAQX,EAAO,MAAOU,EAAM,KAAK,YAAYE,EAASD,CAAI,CAAC,yBAAyBA,EAAK,KAAK,mBAAmBA,EAAK,GAAG,QAAU,EAAI,IAAM,IAAI,4BAA4B,EACxL,QAAWE,KAAMb,EAAO,MAAO,CAC3B,IAAMc,EAAOC,EAASF,CAAE,EACxBH,EAAM,KACF,YAAYG,EAAG,CAAC,QAAQA,EAAG,CAAC,YAAYA,EAAG,CAAC,aAAaA,EAAG,CAAC,SAASC,EAAK,MAAM,WAAWA,EAAK,IAAI,IAAIA,EAAK,SAAW,OAAS,YAAYA,EAAK,MAAM,mBAAmBA,EAAK,WAAW,IAAM,EAAE,IACxM,EACA,IAAME,EAAOH,EAAG,KAAK,OAAO,eAI5B,GAHAH,EAAM,KACF,YAAYG,EAAG,EAAIA,EAAG,EAAI,CAAC,QAAQA,EAAG,EAAIA,EAAG,EAAI,CAAC,mEAAmEnB,GAAIuB,EAAmB,CAAC,gBAAgBJ,EAAG,QAAQ,kBAAkBA,EAAG,UAAU,WAAWC,EAAK,IAAI,IAAIE,EAAO,qBAAqBtB,GAAIsB,CAAI,CAAC,IAAM,EAAE,IAAItB,GAAImB,EAAG,KAAK,KAAK,CAAC,SACtS,EACIA,EAAG,KAAK,WAAa,KAAUA,EAAG,KAAK,UAAU,QAAU,GAAK,GAAKA,EAAG,MAAQ,EAAG,CACnF,IAAMK,EAAKL,EAAG,KAAO,EAAIA,EAAG,EAAIA,EAAG,EAAI,GAAKA,EAAG,EAAI,GAC7CM,EAAKN,EAAG,EAAIA,EAAG,EAAI,EACzBH,EAAM,KAAK,eAAeQ,CAAE,SAASC,CAAE,kCAAkCN,EAAG,KAAK,wBAAwB,EACzGH,EAAM,KAAK,YAAYQ,CAAE,QAAQC,CAAE,mEAAmEzB,GAAIuB,EAAmB,CAAC,0BAA0BJ,EAAG,KAAK,KAAKA,EAAG,KAAK,SAAU,MAAM,SAAS,CAC1M,CACJ,CACA,OAAAH,EAAM,KAAK,MAAM,EACV,kDAAkDJ,CAAK,aAAaC,CAAM,kBAAkBD,CAAK,IAAIC,CAAM,KAAKG,EAAM,KAAK,EAAE,CAAC,QACzI,CJHsC,OAiFlB,YAAAU,GAjFkB,OAAAC,EAiFlB,QAAAC,OAjFkB,oBADtC,IAAMC,GAAuG,CACzG,CAAE,MAAO,EAAG,IAAK,UAAW,KAAMF,EAACG,GAAA,EAAe,CAAG,EACrD,CAAE,MAAO,EAAG,IAAK,WAAY,KAAMH,EAACI,GAAA,EAAgB,CAAG,EACvD,CAAE,MAAO,EAAG,IAAK,UAAW,KAAMJ,EAACK,GAAA,EAAe,CAAG,CACzD,EAEaC,GAAUC,GAAwC,SAC3D,CAAE,MAAAC,EAAO,SAAAC,EAAU,OAAAC,EAAQ,QAASC,EAAW,SAAAC,EAAU,KAAMC,EAAU,YAAAC,EAAc,MAAO,aAAAC,EAAc,WAAAC,EAAY,KAAAC,EAAO,GAAM,OAAAC,EAAS,MAAO,EACrJC,EACF,CACE,IAAMC,EAAUC,GAAeX,EAAQC,CAAS,EAC1C,CAACW,EAASC,CAAU,EAAIC,GAAsBV,CAAW,EACzDW,EAAOZ,GAAYS,EACnBI,EAAWC,GAAsB,CACnCJ,EAAWI,CAAI,EACfZ,IAAeY,CAAI,EACfA,IAAS,OAAO,sBAAsB,IAAMC,EAAO,SAAS,OAAO,CAAC,CAC5E,EACM,CAACC,EAAUC,CAAW,EAAIN,GAAwB,IAAI,EACtDO,EAAUC,GAAe,EACzBJ,EAASK,GAA6B,IAAI,EAC1CC,EAAO1B,EAAM,SACb2B,EAAa3B,EAAM,WAAa,EAEhC4B,EAAS,CAACT,EAAgBU,IAAsB,CAClDN,EAAQ,OAAOG,EAAMG,CAAQ,EAC7B5B,EAAS,CAAE,GAAGD,EAAO,SAAUmB,CAAK,CAAC,CACzC,EACMW,EAAO,IAAM,CACf,IAAMC,EAAOR,EAAQ,KAAKG,CAAI,EAC1BK,GAAM9B,EAAS,CAAE,GAAGD,EAAO,SAAU+B,CAAK,CAAC,CACnD,EACMC,EAAO,IAAM,CACf,IAAMb,EAAOI,EAAQ,KAAKG,CAAI,EAC1BP,GAAMlB,EAAS,CAAE,GAAGD,EAAO,SAAUmB,CAAK,CAAC,CACnD,EACAc,GAAoBtB,EAAK,KAAO,CAAE,UAAW,IAAMuB,GAAiBlC,CAAK,EAAG,OAAQ,IAAMoB,EAAO,SAAS,OAAO,CAAE,GAAI,CAACpB,CAAK,CAAC,EAE9H,IAAMmC,EAAed,EAAWe,GAAWV,EAAML,CAAQ,GAAG,KAAO,OAC7DgB,EACF7C,EAAC8C,EAAA,CAAI,GAAI,CAAE,QAAS,OAAQ,EAAG,IAAM,aAAc,EAAG,QAAS,SAAU,EACnE,UAAC,MAAO,SAAS,EAAY,IAAKC,GAChC/C,EAACgD,GAAA,CAEG,eAAcvB,IAASsB,EACvB,QAAS,IAAMrB,EAAQqB,CAAI,EAC3B,GAAI,CACA,OAAQ,GACR,GAAI,KACJ,aAAc,IACd,SAAU,GACV,WAAYtB,IAASsB,EAAO,IAAM,IAClC,MAAOtB,IAASsB,EAAO,eAAiB,iBACxC,QAAStB,IAASsB,EAAO,OAAS,cAClC,UAAWtB,IAASsB,EAAO,6BAA+B,MAC9D,EAEC,SAAAA,IAAS,MAAQ3B,EAAQ,IAAMA,EAAQ,SAdnC2B,CAeT,CACH,EACL,EAGJ,OACI9C,GAAC6C,EAAA,CAAI,GAAI,CAAE,QAAS,OAAQ,cAAe,SAAU,OAAA5B,EAAQ,UAAW,EAAG,QAAS,MAAO,EACvF,UAAAlB,EAACiD,GAAA,CACG,QAAS7B,EACT,MAAOuB,EAAgBA,EAAa,OAAS,CAAC,EAAK,OACnD,QAAUO,GAAU,CAChB,GAAI,CAACrB,EAAU,OACf,IAAMsB,EAASC,GAAalB,EAAM,CAACL,CAAQ,EAAGqB,CAAK,EAC/CC,GAAQf,EAAOe,EAAO,IAAI,CAClC,EACA,QAASpB,EAAQ,QACjB,QAASA,EAAQ,QACjB,OAAQO,EACR,OAAQE,EACR,MAAOK,EACP,IAAK7B,EACL,SAAUJ,EAET,SAAAa,IAAS,MACNxB,GAAAF,GAAA,CACK,UAAAG,GAAW,IAAK6C,GACb/C,EAACqD,GAAA,CAA4B,MAAOjC,EAAQ2B,EAAK,GAAG,EAAG,OAAQZ,IAAcY,EAAK,MAAO,SAAUnC,EAAU,QAAS,IAAMH,EAAS,CAAE,GAAGD,EAAO,UAAWuC,EAAK,KAAM,CAAC,EACnK,SAAAA,EAAK,MADOA,EAAK,KAEtB,CACH,EACD/C,EAACsD,GAAA,EAAY,EACbtD,EAACqD,GAAA,CAAW,MAAOjC,EAAQ,QAAS,QAAS,IAAMQ,EAAO,SAAS,OAAO,EAAI,GAAG,EAC7E,SAAA5B,EAACuD,GAAA,EAAY,EACjB,EACAvD,EAACqD,GAAA,CAAW,MAAOjC,EAAQ,OAAQ,QAAS,IAAMQ,EAAO,SAAS,OAAO,GAAG,EACxE,SAAA5B,EAACwD,GAAA,EAAW,EAChB,EACAxD,EAACqD,GAAA,CAAW,MAAOjC,EAAQ,OAAQ,QAAS,IAAMQ,EAAO,SAAS,OAAO,EACrE,SAAA5B,EAACyD,GAAA,EAAc,EACnB,GACJ,EACA,KACR,EACAzD,EAAC8C,EAAA,CAAI,GAAI,CAAE,SAAU,WAAY,KAAM,EAAG,UAAW,CAAE,EAClD,SAAArB,IAAS,MACNzB,EAAC0D,GAAA,CAAQ,IAAK9B,EAAQ,KAAMM,EAAM,UAAWC,EAAW,OAAQC,EAAQ,WAAYP,EAAU,SAAUC,EAAa,QAASV,EAAS,SAAUR,EAAU,OAAQ0B,EAAM,OAAQE,EAAM,KAAMvB,EAAM,EAEnMhB,GAAAF,GAAA,CACI,UAAAC,EAAC2D,GAAA,CAAY,KAAMzB,EAAM,OAAQE,EAAQ,WAAYP,EAAU,SAAUC,EAAa,QAASV,EAAS,SAAUR,EAAU,OAAQ0B,EAAM,OAAQE,EAAM,EACvJvB,EACGjB,EAAC8C,EAAA,CAAI,GAAI,CAAE,SAAU,WAAY,KAAM,GAAI,MAAO,GAAI,OAAQ,EAAG,SAAU,GAAI,WAAY,IAAK,MAAO,iBAAkB,cAAe,MAAO,EAC3I,SAAA9C,EAAC8C,EAAA,CAAI,UAAU,OAAO,GAAI,CAAE,QAAS,uBAAwB,EACxD,SAAA1B,EAAQ,KACb,EACJ,EACA,MACR,EAER,GACJ,CAER,CAAC,EKrJD,OAAS,cAAAwC,OAAqD",
|
|
6
|
+
"names": ["forwardRef", "useImperativeHandle", "useRef", "useState", "Box", "ButtonBase", "BranchBothIcon", "BranchLeftIcon", "BranchRightIcon", "FitCenterIcon", "ZoomInIcon", "ZoomOutIcon", "FormatToolbar", "OutlineList", "ToolButton", "ToolDivider", "locateNode", "setNodeStyle", "useTreeHistory", "forwardRef", "useCallback", "useEffect", "useImperativeHandle", "useLayoutEffect", "useMemo", "useRef", "useState", "Box", "ChildBranchIcon", "PencilIcon", "SiblingBranchIcon", "TrashIcon", "DEFAULT_FONT_FAMILY", "ToolButton", "addChild", "addSibling", "containsNode", "locateNode", "measureText", "moveNode", "removeNode", "setTopic", "toggleFold", "measureText", "BRANCH_COLORS", "H_GAP_ROOT", "H_GAP", "V_GAP", "nodeFont", "node", "depth", "fontSize", "fontWeight", "nodeSize", "padX", "padY", "textW", "visibleKids", "layoutMap", "root", "direction", "heights", "subtree", "own", "kids", "sum", "acc", "kid", "value", "nodes", "edges", "rootSize", "rootLN", "place", "parent", "side", "colorOf", "total", "top", "gap", "i", "sh", "size", "cy", "x", "color", "ln", "all", "colorFor", "sideOf", "right", "left", "bounds", "n", "edgePath", "edge", "from", "to", "x1", "y1", "x2", "y2", "dx", "nodeLook", "style", "jsx", "jsxs", "ZOOM_MIN", "ZOOM_MAX", "DRAG_START", "MapView", "forwardRef", "root", "direction", "onEdit", "selectedId", "onSelect", "strings", "readOnly", "onUndo", "onRedo", "hint", "ref", "boxRef", "useRef", "size", "setSize", "useState", "view", "setView", "viewRef", "editing", "setEditing", "drag", "setDrag", "pointer", "layout", "useMemo", "layoutMap", "centered", "useLayoutEffect", "el", "ro", "center", "useCallback", "minX", "minY", "maxX", "maxY", "z", "useEffect", "zoomAt", "factor", "cx", "cy", "v", "useImperativeHandle", "onWheel", "event", "r", "apply", "result", "mergeKey", "editNew", "startEdit", "id", "at", "locateNode", "commitEdit", "setTopic", "toCanvas", "clientX", "clientY", "dropAt", "dragged", "p", "ln", "containsNode", "rel", "onPointerDown", "target", "fold", "toggleFold", "nodeEl", "onPointerMove", "dx", "dy", "onPointerUp", "moveNode", "neighbor", "key", "sibs", "kid", "i", "kids", "want", "onKeyDown", "mod", "next", "addChild", "addSibling", "removeNode", "selected", "editingLN", "dragLN", "dropLN", "barButton", "label", "icon", "onClick", "ToolButton", "Box", "edge", "edgePath", "look", "nodeLook", "folded", "isSel", "DEFAULT_FONT_FAMILY", "text", "named", "measureText", "ChildBranchIcon", "SiblingBranchIcon", "PencilIcon", "TrashIcon", "outlinerStrings", "STRINGS", "mindMapStrings", "locale", "overrides", "lang", "DEFAULT_FONT_FAMILY", "esc", "text", "exportMindMapSvg", "data", "options", "padding", "layout", "layoutMap", "minX", "minY", "maxX", "maxY", "width", "height", "ox", "oy", "parts", "edge", "edgePath", "ln", "look", "nodeLook", "deco", "DEFAULT_FONT_FAMILY", "cx", "cy", "Fragment", "jsx", "jsxs", "DIRECTIONS", "BranchBothIcon", "BranchRightIcon", "BranchLeftIcon", "MindMap", "forwardRef", "value", "onChange", "locale", "overrides", "readOnly", "viewProp", "defaultView", "onViewChange", "toolbarEnd", "hint", "height", "ref", "strings", "mindMapStrings", "ownView", "setOwnView", "useState", "view", "setView", "next", "mapRef", "selected", "setSelected", "history", "useTreeHistory", "useRef", "root", "direction", "commit", "mergeKey", "undo", "prev", "redo", "useImperativeHandle", "exportMindMapSvg", "selectedNode", "locateNode", "viewSwitch", "Box", "item", "ButtonBase", "FormatToolbar", "patch", "result", "setNodeStyle", "ToolButton", "ToolDivider", "ZoomOutIcon", "ZoomInIcon", "FitCenterIcon", "MapView", "OutlineList", "createTree"]
|
|
7
7
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var $e=Object.create;var oe=Object.defineProperty;var Ce=Object.getOwnPropertyDescriptor;var Be=Object.getOwnPropertyNames;var He=Object.getPrototypeOf,Pe=Object.prototype.hasOwnProperty;var Ve=(i,t)=>{for(var d in t)oe(i,d,{get:t[d],enumerable:!0})},fe=(i,t,d,M)=>{if(t&&typeof t=="object"||typeof t=="function")for(let f of Be(t))!Pe.call(i,f)&&f!==d&&oe(i,f,{get:()=>t[f],enumerable:!(M=Ce(t,f))||M.enumerable});return i};var A=(i,t,d)=>(d=i!=null?$e(He(i)):{},fe(t||!i||!i.__esModule?oe(d,"default",{value:i,enumerable:!0}):d,i)),Oe=i=>fe(oe({},"__esModule",{value:!0}),i);var _e={};Ve(_e,{BRANCH_COLORS:()=>ne,MapView:()=>ie,MindMap:()=>Ne,createTree:()=>ve.createTree,edgePath:()=>j,exportMindMapSvg:()=>de,layoutMap:()=>q,mindMapStrings:()=>re,nodeLook:()=>J,nodeSize:()=>ee});module.exports=Oe(_e);var X=require("react"),_=require("@mui/material"),we=A(require("@mui/icons-material/SwapHoriz")),Se=A(require("@mui/icons-material/East")),ze=A(require("@mui/icons-material/West")),Te=A(require("@mui/icons-material/CenterFocusStrongOutlined")),ke=A(require("@mui/icons-material/ZoomIn")),De=A(require("@mui/icons-material/ZoomOut")),L=require("@ehfuse/outliner");var b=require("react"),I=require("@mui/material"),he=A(require("@mui/icons-material/SubdirectoryArrowRight")),ge=A(require("@mui/icons-material/Add")),xe=A(require("@mui/icons-material/EditOutlined")),ye=A(require("@mui/icons-material/DeleteOutline")),u=require("@ehfuse/outliner");var me=require("@ehfuse/outliner"),ne=["#e8710a","#1a73e8","#188038","#d93025","#9334e6","#f9ab00","#12b5cb","#c2185b"],We=64,Ae=40,le=14;function Ye(i,t){let d=i.style?.fontSize?parseFloat(i.style.fontSize):t===0?22:t===1?16:14,M=i.style?.fontWeight??(t===0?"700":t===1?"500":"400");return{fontSize:d,fontWeight:M}}function ee(i,t){let{fontSize:d,fontWeight:M}=Ye(i,t),f=t===0?28:t===1?16:12,T=t===0?14:t===1?8:6,y=(0,me.measureText)(i.topic||" ",d,M);return{w:Math.max(t===0?100:48,Math.ceil(y)+f*2),h:Math.ceil(d*1.4)+T*2,fontSize:d,fontWeight:M}}var ce=i=>i.expanded===!1?[]:i.children??[];function q(i,t=2){let d=new Map,M=(a,w)=>{let m=ee(a,w).h,N=ce(a),x=N.reduce((D,k)=>D+M(k,w+1),0)+le*Math.max(0,N.length-1),$=Math.max(m,x);return d.set(a.id,$),$},f=[],T=[],y=ee(i,0),E={id:i.id,node:i,depth:0,x:-y.w/2,y:-y.h/2,w:y.w,h:y.h,side:0,color:"#3b3f5c",parentId:null,fontSize:y.fontSize,fontWeight:y.fontWeight};f.push(E);let R=(a,w,m,N,x)=>{w.forEach(v=>M(v,N));let $=w.reduce((v,H)=>v+(d.get(H.id)??0),0)+le*Math.max(0,w.length-1),D=a.y+a.h/2-$/2,k=N===1?We:Ae;w.forEach((v,H)=>{let P=d.get(v.id)??0,S=ee(v,N),G=D+P/2,c=m>0?a.x+a.w+k:a.x-k-S.w,V=x(v,H),Q={id:v.id,node:v,depth:N,x:c,y:G-S.h/2,w:S.w,h:S.h,side:m,color:V,parentId:a.id,fontSize:S.fontSize,fontWeight:S.fontWeight};f.push(Q),T.push({from:a,to:Q,color:V}),R(Q,ce(v),m,N+1,()=>V),D+=P+le})},B=ce(i),K=i.children??[],U=a=>ne[Math.max(0,K.indexOf(a))%ne.length],h=(a,w)=>t===0?-1:t===1?1:a.direction===0?-1:a.direction===1||w<Math.ceil(B.length/2)?1:-1,n=B.filter((a,w)=>h(a,w)===1),C=B.filter((a,w)=>h(a,w)===-1);R(E,n,1,1,U),R(E,C,-1,1,U);let p={minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0};for(let a of f)p.minX=Math.min(p.minX,a.x),p.minY=Math.min(p.minY,a.y),p.maxX=Math.max(p.maxX,a.x+a.w),p.maxY=Math.max(p.maxY,a.y+a.h);return{nodes:f,byId:new Map(f.map(a=>[a.id,a])),edges:T,bounds:p}}function j(i){let{from:t,to:d}=i,M=d.side>=0?1:-1,f=t.depth===0?t.x+t.w/2+M*t.w/2-M*12:M>0?t.x+t.w:t.x,T=t.y+t.h/2,y=M>0?d.x:d.x+d.w,E=d.y+d.h/2,R=(y-f)*.5;return`M ${f} ${T} C ${f+R} ${T}, ${y-R} ${E}, ${y} ${E}`}function J(i){let t=i.node.style??{};return i.depth===0?{fill:t.background??"#3b3f5c",stroke:"none",strokeWidth:0,text:t.color??"#ffffff",radius:i.h/2}:i.depth===1?{fill:t.background??"#ffffff",stroke:i.color,strokeWidth:2,text:t.color??"#1f2328",radius:i.h/2}:{fill:t.background??"#ffffff",stroke:"#d0d4da",strokeWidth:1,text:t.color??"#1f2328",radius:8}}var z=require("react/jsx-runtime"),Fe=.3,Xe=2.5,Ke=5,ie=(0,b.forwardRef)(function({root:t,direction:d,onEdit:M,selectedId:f,onSelect:T,strings:y,readOnly:E,onUndo:R,onRedo:B,hint:K=!0},U){let h=(0,b.useRef)(null),[n,C]=(0,b.useState)({w:0,h:0}),[p,a]=(0,b.useState)({x:0,y:0,z:1}),w=(0,b.useRef)(p);w.current=p;let[m,N]=(0,b.useState)(null),[x,$]=(0,b.useState)(null),D=(0,b.useRef)(null),k=(0,b.useMemo)(()=>q(t,d),[t,d]),v=(0,b.useRef)(!1);(0,b.useLayoutEffect)(()=>{let e=h.current;if(!e)return;let o=new ResizeObserver(()=>C({w:e.clientWidth,h:e.clientHeight}));return o.observe(e),C({w:e.clientWidth,h:e.clientHeight}),()=>o.disconnect()},[]);let H=(0,b.useCallback)(()=>{let{minX:e,minY:o,maxX:r,maxY:l}=k.bounds,s=w.current.z;a({x:n.w/2-(e+r)/2*s,y:n.h/2-(o+l)/2*s,z:s})},[k,n]);(0,b.useEffect)(()=>{v.current||n.w===0||(v.current=!0,H())},[n,H]);let P=(0,b.useCallback)((e,o,r)=>{a(l=>{let s=Math.min(Xe,Math.max(Fe,l.z*e));return{x:o-(o-l.x)*(s/l.z),y:r-(r-l.y)*(s/l.z),z:s}})},[]);(0,b.useImperativeHandle)(U,()=>({center:H,zoomBy:e=>P(e,n.w/2,n.h/2)}),[H,P,n]),(0,b.useEffect)(()=>{let e=h.current;if(!e)return;let o=r=>{if(!(r.ctrlKey||r.metaKey))return;r.preventDefault();let l=e.getBoundingClientRect();P(r.deltaY<0?1.1:1/1.1,r.clientX-l.left,r.clientY-l.top)};return e.addEventListener("wheel",o,{passive:!1}),()=>e.removeEventListener("wheel",o)},[P]);let S=(e,o,r=!1)=>{e&&(M(e.root,o),e.focusId&&(T(e.focusId),r&&N({id:e.focusId,text:""})))},G=e=>{if(E)return;let o=(0,u.locateNode)(t,e);o&&N({id:e,text:o.node.topic})},c=()=>{m&&(S((0,u.setTopic)(t,m.id,m.text)),N(null),h.current?.focus({preventScroll:!0}))},V=(e,o)=>{let r=h.current.getBoundingClientRect();return{x:(e-r.left-p.x)/p.z,y:(o-r.top-p.y)/p.z}},Q=(e,o,r)=>{let l=V(e,o);for(let s of k.nodes){if(l.x<s.x-4||l.x>s.x+s.w+4||l.y<s.y-4||l.y>s.y+s.h+4)continue;if((0,u.containsNode)(r,s.id))return null;if(s.depth===0)return{id:s.id,place:"child"};let F=(l.y-s.y)/s.h;return{id:s.id,place:F<.25?"before":F>.75?"after":"child"}}return null},Le=e=>{if(e.button!==0)return;let o=e.target;if(o.closest("[data-mm-ui]")||(m&&!o.closest("[data-mm-edit]")&&c(),o.closest("[data-mm-edit]")))return;let r=o.closest("[data-mm-fold]");if(r){S((0,u.toggleFold)(t,r.dataset.mmFold));return}let l=o.closest("[data-mm-node]");if(h.current?.focus({preventScroll:!0}),l){let s=l.dataset.mmNode;T(s),D.current={kind:"node",id:s,sx:e.clientX,sy:e.clientY,vx:p.x,vy:p.y,moved:!1}}else T(null),D.current={kind:"pan",sx:e.clientX,sy:e.clientY,vx:p.x,vy:p.y,moved:!1}},Ee=e=>{let o=D.current;if(!o)return;let r=e.clientX-o.sx,l=e.clientY-o.sy;if(!o.moved&&Math.hypot(r,l)<Ke)return;if(!o.moved&&!h.current?.hasPointerCapture(e.pointerId)&&h.current?.setPointerCapture(e.pointerId),o.moved=!0,o.kind==="pan"){a(Z=>({...Z,x:o.vx+r,y:o.vy+l}));return}if(E||o.id===t.id)return;let s=(0,u.locateNode)(t,o.id)?.node;if(!s)return;let F=h.current.getBoundingClientRect();$({id:o.id,px:e.clientX-F.left,py:e.clientY-F.top,target:Q(e.clientX,e.clientY,s)})},ue=e=>{let o=D.current;D.current=null,h.current?.hasPointerCapture(e.pointerId)&&h.current.releasePointerCapture(e.pointerId),o?.kind==="node"&&x?.target&&S((0,u.moveNode)(t,x.id,x.target.id,x.target.place)),$(null)},Ie=(e,o)=>{let r=(0,u.locateNode)(t,e.id);if(!r)return null;if(o==="ArrowUp"||o==="ArrowDown"){if(!r.parent)return null;let s=(r.parent.children??[]).filter(Z=>k.byId.get(Z.id)?.side===e.side),F=s.findIndex(Z=>Z.id===e.id);return s[F+(o==="ArrowUp"?-1:1)]?.id??null}if(o==="ArrowRight"&&e.side>=0||o==="ArrowLeft"&&e.side<=0){let s=r.node.expanded===!1?[]:r.node.children??[],F=e.side===0?o==="ArrowRight"?1:-1:e.side;return s.find(Z=>k.byId.get(Z.id)?.side===F)?.id??null}return e.parentId},Re=e=>{if(m||e.target.tagName==="INPUT")return;let o=e.ctrlKey||e.metaKey;if(o&&(e.key==="z"||e.key==="Z")){e.preventDefault(),e.shiftKey?B?.():R?.();return}if(o&&(e.key==="y"||e.key==="Y")){e.preventDefault(),B?.();return}let r=f?k.byId.get(f):null;if(r){if(e.key.startsWith("Arrow")){let l=Ie(r,e.key);e.preventDefault(),l&&T(l);return}E||(e.key==="Tab"?(e.preventDefault(),S((0,u.addChild)(t,r.id),void 0,!0)):e.key==="Enter"?(e.preventDefault(),S((0,u.addSibling)(t,r.id),void 0,!0)):e.key==="F2"?(e.preventDefault(),G(r.id)):e.key==="Delete"||e.key==="Backspace"?(e.preventDefault(),S((0,u.removeNode)(t,r.id))):e.key===" "&&(e.preventDefault(),S((0,u.toggleFold)(t,r.id))))}},O=f?k.byId.get(f):void 0,Y=m?k.byId.get(m.id):void 0,se=x?k.byId.get(x.id):void 0,W=x?.target?k.byId.get(x.target.id):void 0,te=(e,o,r,l)=>(0,z.jsx)(I.Tooltip,{title:o,disableInteractive:!0,children:(0,z.jsx)(I.IconButton,{size:"small","aria-label":o,onMouseDown:s=>s.preventDefault(),onClick:l,sx:{width:28,height:28,color:"text.secondary","&:hover":{color:"primary.main"}},children:r})},e);return(0,z.jsxs)(I.Box,{ref:h,tabIndex:0,onKeyDown:Re,onPointerDown:Le,onPointerMove:Ee,onPointerUp:ue,onPointerCancel:ue,onDoubleClick:e=>{let o=e.target.closest("[data-mm-node]");o&&G(o.dataset.mmNode)},sx:{position:"relative",width:"100%",height:"100%",overflow:"hidden",bgcolor:"#f7f8fa",outline:"none",touchAction:"none",userSelect:"none",cursor:D.current?.kind==="pan"?"grabbing":"default"},children:[(0,z.jsxs)(I.Box,{sx:{position:"absolute",left:0,top:0,transform:`translate(${p.x}px, ${p.y}px) scale(${p.z})`,transformOrigin:"0 0"},children:[(0,z.jsx)("svg",{style:{position:"absolute",left:0,top:0,width:1,height:1,overflow:"visible"},children:k.edges.map(e=>(0,z.jsx)("path",{d:j(e),fill:"none",stroke:e.color,strokeWidth:e.to.depth===1?2.5:1.75,strokeLinecap:"round"},e.to.id))}),k.nodes.map(e=>{let o=J(e),r=e.node.children?.length??0,l=e.node.expanded===!1&&r>0,s=e.id===f;return(0,z.jsxs)(I.Box,{"data-mm-node":e.id,sx:{position:"absolute",left:e.x,top:e.y,width:e.w,height:e.h,boxSizing:"border-box",display:"flex",alignItems:"center",justifyContent:"center",borderRadius:`${o.radius}px`,bgcolor:o.fill,border:o.stroke!=="none"?`${o.strokeWidth}px solid ${o.stroke}`:0,color:o.text,fontFamily:u.DEFAULT_FONT_FAMILY,fontSize:e.fontSize,fontWeight:e.fontWeight,textDecoration:e.node.style?.textDecoration,whiteSpace:"nowrap",cursor:E?"default":"pointer",boxShadow:s?"0 0 0 2px #fff, 0 0 0 4px #1a73e8":e.depth===0?"0 2px 6px rgba(0,0,0,0.18)":"none",opacity:x?.id===e.id?.35:1,"&:hover .mm-fold":{opacity:1}},children:[m?.id===e.id?null:e.node.topic||"\xA0",r>0&&e.depth>0?(0,z.jsx)(I.Box,{className:"mm-fold","data-mm-fold":e.id,title:l?y.unfold:y.fold,sx:{position:"absolute",top:"50%",[e.side>0?"left":"right"]:"100%",transform:`translate(${e.side>0?4:-4}px, -50%)`,minWidth:18,height:18,px:l?.5:0,boxSizing:"border-box",borderRadius:9,bgcolor:"#fff",border:`1.5px solid ${e.color}`,color:e.color,fontSize:11,fontWeight:600,lineHeight:"15px",textAlign:"center",cursor:"pointer",opacity:l||s?1:0,textDecoration:"none"},children:l?r:"\u2212"}):null]},e.id)}),W&&x?.target?x.target.place==="child"?(0,z.jsx)(I.Box,{sx:{position:"absolute",left:W.x-4,top:W.y-4,width:W.w+8,height:W.h+8,border:"2px dashed #1a73e8",borderRadius:2,pointerEvents:"none"}}):(0,z.jsx)(I.Box,{sx:{position:"absolute",left:W.x,top:x.target.place==="before"?W.y-6:W.y+W.h+4,width:W.w,height:3,borderRadius:2,bgcolor:"#1a73e8",pointerEvents:"none"}}):null,Y&&m?(0,z.jsx)("input",{"data-mm-edit":"",autoFocus:!0,value:m.text,spellCheck:!1,onFocus:e=>e.currentTarget.select(),onChange:e=>N({id:m.id,text:e.target.value}),onBlur:c,onKeyDown:e=>{if(e.stopPropagation(),!e.nativeEvent.isComposing){if(e.key==="Enter")e.preventDefault(),c();else if(e.key==="Escape")e.preventDefault(),N(null),h.current?.focus({preventScroll:!0});else if(e.key==="Tab"){e.preventDefault();let o=m.id,r=m.text;N(null);let l=(0,u.setTopic)(t,o,r);S((0,u.addChild)(l?.root??t,o),void 0,!0)}}},style:{position:"absolute",left:Y.x,top:Y.y,width:Math.max(Y.w,Math.ceil((0,u.measureText)(m.text||" ",Y.fontSize,Y.fontWeight))+40),height:Y.h,boxSizing:"border-box",padding:"0 12px",border:"2px solid #1a73e8",borderRadius:8,outline:"none",textAlign:"center",fontFamily:u.DEFAULT_FONT_FAMILY,fontSize:Y.fontSize,fontWeight:Y.fontWeight,color:"#1f2328",background:"#fff",zIndex:5}}):null]}),x&&se?(0,z.jsx)(I.Box,{sx:{position:"absolute",left:x.px+10,top:x.py+10,px:1.5,py:.5,borderRadius:2,bgcolor:"#fff",border:`1.5px solid ${se.color}`,fontSize:13,opacity:.9,pointerEvents:"none",boxShadow:"0 4px 12px rgba(0,0,0,0.15)"},children:se.node.topic||"\xA0"}):null,O&&!m&&!x&&!E?(0,z.jsxs)(I.Box,{"data-mm-ui":"",sx:{position:"absolute",left:p.x+(O.x+O.w/2)*p.z,top:p.y+O.y*p.z,transform:"translate(-50%, calc(-100% - 8px))",display:"flex",gap:.25,p:.25,bgcolor:"#fff",border:"1px solid #e0e0e0",borderRadius:1,boxShadow:"0 2px 6px rgba(0,0,0,0.12)",zIndex:6},children:[te("child",y.addChild,(0,z.jsx)(he.default,{sx:{fontSize:18}}),()=>S((0,u.addChild)(t,O.id),void 0,!0)),O.depth>0?te("sibling",y.addSibling,(0,z.jsx)(ge.default,{sx:{fontSize:18}}),()=>S((0,u.addSibling)(t,O.id),void 0,!0)):null,te("edit",y.edit,(0,z.jsx)(xe.default,{sx:{fontSize:17}}),()=>G(O.id)),O.depth>0?te("delete",y.remove,(0,z.jsx)(ye.default,{sx:{fontSize:18}}),()=>S((0,u.removeNode)(t,O.id))):null]}):null,K?(0,z.jsx)(I.Box,{sx:{position:"absolute",left:12,right:12,bottom:8,fontSize:12,lineHeight:1.5,color:"text.secondary",pointerEvents:"none"},children:(0,z.jsx)(I.Box,{component:"span",sx:{bgcolor:"rgba(247,248,250,0.85)"},children:y.mapHint})}):null]})});var Me=require("@ehfuse/outliner"),be={ko:{map:"\uC9C0\uB3C4",outline:"\uBAA9\uB85D",addChild:"\uC544\uB798 \uAC00\uC9C0",addSibling:"\uC606 \uAC00\uC9C0",edit:"\uAE00 \uACE0\uCE58\uAE30",remove:"\uC9C0\uC6B0\uAE30",dirSide:"\uC591\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30",dirRight:"\uC624\uB978\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30",dirLeft:"\uC67C\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30",center:"\uAC00\uC6B4\uB370\uB85C",zoomIn:"\uD655\uB300",zoomOut:"\uCD95\uC18C",mapHint:"\uB450 \uBC88 \uD074\uB9AD: \uAE00 \uACE0\uCE58\uAE30 \xB7 Tab: \uC544\uB798 \uAC00\uC9C0 \xB7 Enter: \uC606 \uAC00\uC9C0 \xB7 \uAC00\uC9C0 \uB04C\uAE30: \uC62E\uAE30\uAE30 \xB7 \uBE48 \uACF3 \uB04C\uAE30: \uC774\uB3D9 \xB7 Ctrl+\uD720: \uD655\uB300",newTopic:"\uC0C8 \uAC00\uC9C0"},en:{map:"Map",outline:"List",addChild:"Child branch",addSibling:"Sibling branch",edit:"Edit text",remove:"Delete",dirSide:"Grow both ways",dirRight:"Grow to the right",dirLeft:"Grow to the left",center:"Center",zoomIn:"Zoom in",zoomOut:"Zoom out",mapHint:"Double-click: edit \xB7 Tab: child \xB7 Enter: sibling \xB7 Drag a branch: move \xB7 Drag empty space: pan \xB7 Ctrl+wheel: zoom",newTopic:"New branch"},ja:{map:"\u30DE\u30C3\u30D7",outline:"\u30EA\u30B9\u30C8",addChild:"\u4E0B\u306E\u679D",addSibling:"\u6A2A\u306E\u679D",edit:"\u6587\u5B57\u3092\u7DE8\u96C6",remove:"\u524A\u9664",dirSide:"\u4E21\u5074\u306B\u5E83\u3052\u308B",dirRight:"\u53F3\u306B\u5E83\u3052\u308B",dirLeft:"\u5DE6\u306B\u5E83\u3052\u308B",center:"\u4E2D\u592E\u3078",zoomIn:"\u62E1\u5927",zoomOut:"\u7E2E\u5C0F",mapHint:"\u30C0\u30D6\u30EB\u30AF\u30EA\u30C3\u30AF: \u7DE8\u96C6 \xB7 Tab: \u4E0B\u306E\u679D \xB7 Enter: \u6A2A\u306E\u679D \xB7 \u679D\u3092\u30C9\u30E9\u30C3\u30B0: \u79FB\u52D5 \xB7 \u7A7A\u767D\u30C9\u30E9\u30C3\u30B0: \u30B9\u30AF\u30ED\u30FC\u30EB \xB7 Ctrl+\u30DB\u30A4\u30FC\u30EB: \u62E1\u5927",newTopic:"\u65B0\u3057\u3044\u679D"},zh:{map:"\u5BFC\u56FE",outline:"\u5217\u8868",addChild:"\u5B50\u5206\u652F",addSibling:"\u540C\u7EA7\u5206\u652F",edit:"\u7F16\u8F91\u6587\u5B57",remove:"\u5220\u9664",dirSide:"\u4E24\u4FA7\u5C55\u5F00",dirRight:"\u5411\u53F3\u5C55\u5F00",dirLeft:"\u5411\u5DE6\u5C55\u5F00",center:"\u5C45\u4E2D",zoomIn:"\u653E\u5927",zoomOut:"\u7F29\u5C0F",mapHint:"\u53CC\u51FB: \u7F16\u8F91 \xB7 Tab: \u5B50\u5206\u652F \xB7 Enter: \u540C\u7EA7\u5206\u652F \xB7 \u62D6\u52A8\u5206\u652F: \u79FB\u52A8 \xB7 \u62D6\u52A8\u7A7A\u767D: \u5E73\u79FB \xB7 Ctrl+\u6EDA\u8F6E: \u7F29\u653E",newTopic:"\u65B0\u5206\u652F"},de:{map:"Karte",outline:"Liste",addChild:"Unterzweig",addSibling:"Nebenzweig",edit:"Text bearbeiten",remove:"L\xF6schen",dirSide:"Beidseitig",dirRight:"Nach rechts",dirLeft:"Nach links",center:"Zentrieren",zoomIn:"Vergr\xF6\xDFern",zoomOut:"Verkleinern",mapHint:"Doppelklick: bearbeiten \xB7 Tab: Unterzweig \xB7 Enter: Nebenzweig \xB7 Zweig ziehen: verschieben \xB7 Leere Fl\xE4che ziehen: schwenken \xB7 Strg+Rad: Zoom",newTopic:"Neuer Zweig"},fr:{map:"Carte",outline:"Liste",addChild:"Branche enfant",addSibling:"Branche s\u0153ur",edit:"Modifier le texte",remove:"Supprimer",dirSide:"Des deux c\xF4t\xE9s",dirRight:"Vers la droite",dirLeft:"Vers la gauche",center:"Centrer",zoomIn:"Zoomer",zoomOut:"D\xE9zoomer",mapHint:"Double-clic : modifier \xB7 Tab : enfant \xB7 Entr\xE9e : s\u0153ur \xB7 Glisser une branche : d\xE9placer \xB7 Glisser le vide : d\xE9filer \xB7 Ctrl+molette : zoom",newTopic:"Nouvelle branche"},it:{map:"Mappa",outline:"Elenco",addChild:"Ramo figlio",addSibling:"Ramo fratello",edit:"Modifica testo",remove:"Elimina",dirSide:"Su entrambi i lati",dirRight:"Verso destra",dirLeft:"Verso sinistra",center:"Centra",zoomIn:"Ingrandisci",zoomOut:"Riduci",mapHint:"Doppio clic: modifica \xB7 Tab: figlio \xB7 Invio: fratello \xB7 Trascina un ramo: sposta \xB7 Trascina il vuoto: scorri \xB7 Ctrl+rotella: zoom",newTopic:"Nuovo ramo"},vi:{map:"B\u1EA3n \u0111\u1ED3",outline:"Danh s\xE1ch",addChild:"Nh\xE1nh con",addSibling:"Nh\xE1nh ngang",edit:"S\u1EEDa ch\u1EEF",remove:"X\xF3a",dirSide:"M\u1EDF hai b\xEAn",dirRight:"M\u1EDF sang ph\u1EA3i",dirLeft:"M\u1EDF sang tr\xE1i",center:"V\u1EC1 gi\u1EEFa",zoomIn:"Ph\xF3ng to",zoomOut:"Thu nh\u1ECF",mapHint:"Nh\u1EA5p \u0111\xFAp: s\u1EEDa \xB7 Tab: nh\xE1nh con \xB7 Enter: nh\xE1nh ngang \xB7 K\xE9o nh\xE1nh: di chuy\u1EC3n \xB7 K\xE9o ch\u1ED7 tr\u1ED1ng: cu\u1ED9n \xB7 Ctrl+cu\u1ED9n: ph\xF3ng to",newTopic:"Nh\xE1nh m\u1EDBi"}};function re(i,t){let d=(i??"en").slice(0,2).toLowerCase();return{...(0,Me.outlinerStrings)(i),...be[d]??be.en,...t}}var pe=require("@ehfuse/outliner");var ae=i=>i.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");function de(i,t={}){let d=t.padding??24,M=q(i.nodeData,i.direction??2),{minX:f,minY:T,maxX:y,maxY:E}=M.bounds,R=Math.ceil(y-f+d*2),B=Math.ceil(E-T+d*2),K=d-f,U=d-T,h=[];h.push(`<rect width="${R}" height="${B}" fill="${t.background??"#ffffff"}"/>`),h.push(`<g transform="translate(${K} ${U})">`);for(let n of M.edges)h.push(`<path d="${j(n)}" fill="none" stroke="${n.color}" stroke-width="${n.to.depth===1?2.5:1.75}" stroke-linecap="round"/>`);for(let n of M.nodes){let C=J(n);h.push(`<rect x="${n.x}" y="${n.y}" width="${n.w}" height="${n.h}" rx="${C.radius}" fill="${C.fill}"${C.stroke!=="none"?` stroke="${C.stroke}" stroke-width="${C.strokeWidth}"`:""}/>`);let p=n.node.style?.textDecoration;if(h.push(`<text x="${n.x+n.w/2}" y="${n.y+n.h/2}" text-anchor="middle" dominant-baseline="central" font-family="${ae(pe.DEFAULT_FONT_FAMILY)}" font-size="${n.fontSize}" font-weight="${n.fontWeight}" fill="${C.text}"${p?` text-decoration="${ae(p)}"`:""}>${ae(n.node.topic)}</text>`),n.node.expanded===!1&&(n.node.children?.length??0)>0&&n.depth>0){let a=n.side>0?n.x+n.w+10:n.x-10,w=n.y+n.h/2;h.push(`<circle cx="${a}" cy="${w}" r="9" fill="#ffffff" stroke="${n.color}" stroke-width="1.5"/>`),h.push(`<text x="${a}" y="${w}" text-anchor="middle" dominant-baseline="central" font-family="${ae(pe.DEFAULT_FONT_FAMILY)}" font-size="10" fill="${n.color}">${n.node.children.length}</text>`)}}return h.push("</g>"),`<svg xmlns="http://www.w3.org/2000/svg" width="${R}" height="${B}" viewBox="0 0 ${R} ${B}">${h.join("")}</svg>`}var g=require("react/jsx-runtime"),Ue=[{value:2,key:"dirSide",icon:(0,g.jsx)(we.default,{sx:{fontSize:19}})},{value:1,key:"dirRight",icon:(0,g.jsx)(Se.default,{sx:{fontSize:18}})},{value:0,key:"dirLeft",icon:(0,g.jsx)(ze.default,{sx:{fontSize:18}})}],Ne=(0,X.forwardRef)(function({value:t,onChange:d,locale:M,strings:f,readOnly:T,view:y,defaultView:E="map",onViewChange:R,toolbarEnd:B,hint:K=!0,height:U="100%"},h){let n=re(M,f),[C,p]=(0,X.useState)(E),a=y??C,w=c=>{p(c),R?.(c),c==="map"&&requestAnimationFrame(()=>$.current?.center())},[m,N]=(0,X.useState)(null),x=(0,L.useTreeHistory)(),$=(0,X.useRef)(null),D=t.nodeData,k=t.direction??2,v=(c,V)=>{x.record(D,V),d({...t,nodeData:c})},H=()=>{let c=x.undo(D);c&&d({...t,nodeData:c})},P=()=>{let c=x.redo(D);c&&d({...t,nodeData:c})};(0,X.useImperativeHandle)(h,()=>({exportSvg:()=>de(t),center:()=>$.current?.center()}),[t]);let S=m?(0,L.locateNode)(D,m)?.node:void 0,G=(0,g.jsx)(_.Box,{sx:{display:"flex",p:.25,borderRadius:1,bgcolor:"#f1f3f4"},children:["map","outline"].map(c=>(0,g.jsx)(_.ButtonBase,{"aria-pressed":a===c,onClick:()=>w(c),sx:{height:26,px:1.25,borderRadius:.75,fontSize:13,fontWeight:a===c?600:400,color:a===c?"primary.main":"text.secondary",bgcolor:a===c?"#fff":"transparent",boxShadow:a===c?"0 1px 2px rgba(0,0,0,0.15)":"none"},children:c==="map"?n.map:n.outline},c))});return(0,g.jsxs)(_.Box,{sx:{display:"flex",flexDirection:"column",height:U,minHeight:0,bgcolor:"#fff"},children:[(0,g.jsx)(L.FormatToolbar,{strings:n,style:S?S.style??{}:void 0,onStyle:c=>{if(!m)return;let V=(0,L.setNodeStyle)(D,[m],c);V&&v(V.root)},canUndo:x.canUndo,canRedo:x.canRedo,onUndo:H,onRedo:P,start:G,end:B,readOnly:T,children:a==="map"?(0,g.jsxs)(g.Fragment,{children:[Ue.map(c=>(0,g.jsx)(L.ToolButton,{label:n[c.key],active:k===c.value,disabled:T,onClick:()=>d({...t,direction:c.value}),children:c.icon},c.value)),(0,g.jsx)(L.ToolDivider,{}),(0,g.jsx)(L.ToolButton,{label:n.zoomOut,onClick:()=>$.current?.zoomBy(1/1.2),children:(0,g.jsx)(De.default,{sx:{fontSize:19}})}),(0,g.jsx)(L.ToolButton,{label:n.zoomIn,onClick:()=>$.current?.zoomBy(1.2),children:(0,g.jsx)(ke.default,{sx:{fontSize:19}})}),(0,g.jsx)(L.ToolButton,{label:n.center,onClick:()=>$.current?.center(),children:(0,g.jsx)(Te.default,{sx:{fontSize:18}})})]}):null}),(0,g.jsx)(_.Box,{sx:{position:"relative",flex:1,minHeight:0},children:a==="map"?(0,g.jsx)(ie,{ref:$,root:D,direction:k,onEdit:v,selectedId:m,onSelect:N,strings:n,readOnly:T,onUndo:H,onRedo:P,hint:K}):(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(L.OutlineList,{root:D,onEdit:v,selectedId:m,onSelect:N,strings:n,readOnly:T,onUndo:H,onRedo:P}),K?(0,g.jsx)(_.Box,{sx:{position:"absolute",left:12,right:12,bottom:8,fontSize:12,lineHeight:1.5,color:"text.secondary",pointerEvents:"none"},children:(0,g.jsx)(_.Box,{component:"span",sx:{bgcolor:"rgba(255,255,255,0.9)"},children:n.hint})}):null]})})]})});var ve=require("@ehfuse/outliner");
|
|
1
|
+
"use strict";var le=Object.defineProperty;var Te=Object.getOwnPropertyDescriptor;var ze=Object.getOwnPropertyNames;var ke=Object.prototype.hasOwnProperty;var Ne=(a,t)=>{for(var d in t)le(a,d,{get:t[d],enumerable:!0})},De=(a,t,d,M)=>{if(t&&typeof t=="object"||typeof t=="function")for(let f of ze(t))!ke.call(a,f)&&f!==d&&le(a,f,{get:()=>t[f],enumerable:!(M=Te(t,f))||M.enumerable});return a};var ve=a=>De(le({},"__esModule",{value:!0}),a);var He={};Ne(He,{BRANCH_COLORS:()=>ne,MapView:()=>ie,MindMap:()=>xe,createTree:()=>ye.createTree,edgePath:()=>J,exportMindMapSvg:()=>de,layoutMap:()=>j,mindMapStrings:()=>re,nodeLook:()=>Q,nodeSize:()=>te});module.exports=ve(He);var X=require("react"),G=require("@mui/material"),H=require("@ehfuse/toolbar-icons"),L=require("@ehfuse/outliner");var b=require("react"),V=require("@mui/material"),_=require("@ehfuse/toolbar-icons"),u=require("@ehfuse/outliner");var me=require("@ehfuse/outliner"),ne=["#e8710a","#1a73e8","#188038","#d93025","#9334e6","#f9ab00","#12b5cb","#c2185b"],Le=64,Ee=40,ce=14;function Ie(a,t){let d=a.style?.fontSize?parseFloat(a.style.fontSize):t===0?22:t===1?16:14,M=a.style?.fontWeight??(t===0?"700":t===1?"500":"400");return{fontSize:d,fontWeight:M}}function te(a,t){let{fontSize:d,fontWeight:M}=Ie(a,t),f=t===0?28:t===1?16:12,T=t===0?14:t===1?8:6,y=(0,me.measureText)(a.topic||" ",d,M);return{w:Math.max(t===0?100:48,Math.ceil(y)+f*2),h:Math.ceil(d*1.4)+T*2,fontSize:d,fontWeight:M}}var pe=a=>a.expanded===!1?[]:a.children??[];function j(a,t=2){let d=new Map,M=(r,w)=>{let m=te(r,w).h,D=pe(r),x=D.reduce((N,z)=>N+M(z,w+1),0)+ce*Math.max(0,D.length-1),R=Math.max(m,x);return d.set(r.id,R),R},f=[],T=[],y=te(a,0),E={id:a.id,node:a,depth:0,x:-y.w/2,y:-y.h/2,w:y.w,h:y.h,side:0,color:"#3b3f5c",parentId:null,fontSize:y.fontSize,fontWeight:y.fontWeight};f.push(E);let I=(r,w,m,D,x)=>{w.forEach(v=>M(v,D));let R=w.reduce((v,B)=>v+(d.get(B.id)??0),0)+ce*Math.max(0,w.length-1),N=r.y+r.h/2-R/2,z=D===1?Le:Ee;w.forEach((v,B)=>{let P=d.get(v.id)??0,S=te(v,D),Z=N+P/2,l=m>0?r.x+r.w+z:r.x-z-S.w,O=x(v,B),ee={id:v.id,node:v,depth:D,x:l,y:Z-S.h/2,w:S.w,h:S.h,side:m,color:O,parentId:r.id,fontSize:S.fontSize,fontWeight:S.fontWeight};f.push(ee),T.push({from:r,to:ee,color:O}),I(ee,pe(v),m,D+1,()=>O),N+=P+ce})},C=pe(a),K=a.children??[],U=r=>ne[Math.max(0,K.indexOf(r))%ne.length],h=(r,w)=>t===0?-1:t===1?1:r.direction===0?-1:r.direction===1||w<Math.ceil(C.length/2)?1:-1,n=C.filter((r,w)=>h(r,w)===1),$=C.filter((r,w)=>h(r,w)===-1);I(E,n,1,1,U),I(E,$,-1,1,U);let p={minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0};for(let r of f)p.minX=Math.min(p.minX,r.x),p.minY=Math.min(p.minY,r.y),p.maxX=Math.max(p.maxX,r.x+r.w),p.maxY=Math.max(p.maxY,r.y+r.h);return{nodes:f,byId:new Map(f.map(r=>[r.id,r])),edges:T,bounds:p}}function J(a){let{from:t,to:d}=a,M=d.side>=0?1:-1,f=t.depth===0?t.x+t.w/2+M*t.w/2-M*12:M>0?t.x+t.w:t.x,T=t.y+t.h/2,y=M>0?d.x:d.x+d.w,E=d.y+d.h/2,I=(y-f)*.5;return`M ${f} ${T} C ${f+I} ${T}, ${y-I} ${E}, ${y} ${E}`}function Q(a){let t=a.node.style??{};return a.depth===0?{fill:t.background??"#3b3f5c",stroke:"none",strokeWidth:0,text:t.color??"#ffffff",radius:a.h/2}:a.depth===1?{fill:t.background??"#ffffff",stroke:a.color,strokeWidth:2,text:t.color??"#1f2328",radius:a.h/2}:{fill:t.background??"#ffffff",stroke:"#d0d4da",strokeWidth:1,text:t.color??"#1f2328",radius:8}}var k=require("react/jsx-runtime"),Re=.3,$e=2.5,Ce=5,ie=(0,b.forwardRef)(function({root:t,direction:d,onEdit:M,selectedId:f,onSelect:T,strings:y,readOnly:E,onUndo:I,onRedo:C,hint:K=!0},U){let h=(0,b.useRef)(null),[n,$]=(0,b.useState)({w:0,h:0}),[p,r]=(0,b.useState)({x:0,y:0,z:1}),w=(0,b.useRef)(p);w.current=p;let[m,D]=(0,b.useState)(null),[x,R]=(0,b.useState)(null),N=(0,b.useRef)(null),z=(0,b.useMemo)(()=>j(t,d),[t,d]),v=(0,b.useRef)(!1);(0,b.useLayoutEffect)(()=>{let e=h.current;if(!e)return;let o=new ResizeObserver(()=>$({w:e.clientWidth,h:e.clientHeight}));return o.observe(e),$({w:e.clientWidth,h:e.clientHeight}),()=>o.disconnect()},[]);let B=(0,b.useCallback)(()=>{let{minX:e,minY:o,maxX:i,maxY:s}=z.bounds,c=w.current.z;r({x:n.w/2-(e+i)/2*c,y:n.h/2-(o+s)/2*c,z:c})},[z,n]);(0,b.useEffect)(()=>{v.current||n.w===0||(v.current=!0,B())},[n,B]);let P=(0,b.useCallback)((e,o,i)=>{r(s=>{let c=Math.min($e,Math.max(Re,s.z*e));return{x:o-(o-s.x)*(c/s.z),y:i-(i-s.y)*(c/s.z),z:c}})},[]);(0,b.useImperativeHandle)(U,()=>({center:B,zoomBy:e=>P(e,n.w/2,n.h/2)}),[B,P,n]),(0,b.useEffect)(()=>{let e=h.current;if(!e)return;let o=i=>{if(!(i.ctrlKey||i.metaKey))return;i.preventDefault();let s=e.getBoundingClientRect();P(i.deltaY<0?1.1:1/1.1,i.clientX-s.left,i.clientY-s.top)};return e.addEventListener("wheel",o,{passive:!1}),()=>e.removeEventListener("wheel",o)},[P]);let S=(e,o,i=!1)=>{e&&(M(e.root,o),e.focusId&&(T(e.focusId),i&&D({id:e.focusId,text:""})))},Z=e=>{if(E)return;let o=(0,u.locateNode)(t,e);o&&D({id:e,text:o.node.topic})},l=()=>{m&&(S((0,u.setTopic)(t,m.id,m.text)),D(null),h.current?.focus({preventScroll:!0}))},O=(e,o)=>{let i=h.current.getBoundingClientRect();return{x:(e-i.left-p.x)/p.z,y:(o-i.top-p.y)/p.z}},ee=(e,o,i)=>{let s=O(e,o);for(let c of z.nodes){if(s.x<c.x-4||s.x>c.x+c.w+4||s.y<c.y-4||s.y>c.y+c.h+4)continue;if((0,u.containsNode)(i,c.id))return null;if(c.depth===0)return{id:c.id,place:"child"};let F=(s.y-c.y)/c.h;return{id:c.id,place:F<.25?"before":F>.75?"after":"child"}}return null},be=e=>{if(e.button!==0)return;let o=e.target;if(o.closest("[data-mm-ui]")||(m&&!o.closest("[data-mm-edit]")&&l(),o.closest("[data-mm-edit]")))return;let i=o.closest("[data-mm-fold]");if(i){S((0,u.toggleFold)(t,i.dataset.mmFold));return}let s=o.closest("[data-mm-node]");if(h.current?.focus({preventScroll:!0}),s){let c=s.dataset.mmNode;T(c),N.current={kind:"node",id:c,sx:e.clientX,sy:e.clientY,vx:p.x,vy:p.y,moved:!1}}else T(null),N.current={kind:"pan",sx:e.clientX,sy:e.clientY,vx:p.x,vy:p.y,moved:!1}},Me=e=>{let o=N.current;if(!o)return;let i=e.clientX-o.sx,s=e.clientY-o.sy;if(!o.moved&&Math.hypot(i,s)<Ce)return;if(!o.moved&&!h.current?.hasPointerCapture(e.pointerId)&&h.current?.setPointerCapture(e.pointerId),o.moved=!0,o.kind==="pan"){r(q=>({...q,x:o.vx+i,y:o.vy+s}));return}if(E||o.id===t.id)return;let c=(0,u.locateNode)(t,o.id)?.node;if(!c)return;let F=h.current.getBoundingClientRect();R({id:o.id,px:e.clientX-F.left,py:e.clientY-F.top,target:ee(e.clientX,e.clientY,c)})},fe=e=>{let o=N.current;N.current=null,h.current?.hasPointerCapture(e.pointerId)&&h.current.releasePointerCapture(e.pointerId),o?.kind==="node"&&x?.target&&S((0,u.moveNode)(t,x.id,x.target.id,x.target.place)),R(null)},we=(e,o)=>{let i=(0,u.locateNode)(t,e.id);if(!i)return null;if(o==="ArrowUp"||o==="ArrowDown"){if(!i.parent)return null;let c=(i.parent.children??[]).filter(q=>z.byId.get(q.id)?.side===e.side),F=c.findIndex(q=>q.id===e.id);return c[F+(o==="ArrowUp"?-1:1)]?.id??null}if(o==="ArrowRight"&&e.side>=0||o==="ArrowLeft"&&e.side<=0){let c=i.node.expanded===!1?[]:i.node.children??[],F=e.side===0?o==="ArrowRight"?1:-1:e.side;return c.find(q=>z.byId.get(q.id)?.side===F)?.id??null}return e.parentId},Se=e=>{if(m||e.target.tagName==="INPUT")return;let o=e.ctrlKey||e.metaKey;if(o&&(e.key==="z"||e.key==="Z")){e.preventDefault(),e.shiftKey?C?.():I?.();return}if(o&&(e.key==="y"||e.key==="Y")){e.preventDefault(),C?.();return}let i=f?z.byId.get(f):null;if(i){if(e.key.startsWith("Arrow")){let s=we(i,e.key);e.preventDefault(),s&&T(s);return}E||(e.key==="Tab"?(e.preventDefault(),S((0,u.addChild)(t,i.id),void 0,!0)):e.key==="Enter"?(e.preventDefault(),S((0,u.addSibling)(t,i.id),void 0,!0)):e.key==="F2"?(e.preventDefault(),Z(i.id)):e.key==="Delete"||e.key==="Backspace"?(e.preventDefault(),S((0,u.removeNode)(t,i.id))):e.key===" "&&(e.preventDefault(),S((0,u.toggleFold)(t,i.id))))}},W=f?z.byId.get(f):void 0,Y=m?z.byId.get(m.id):void 0,se=x?z.byId.get(x.id):void 0,A=x?.target?z.byId.get(x.target.id):void 0,oe=(e,o,i,s)=>(0,k.jsx)(u.ToolButton,{label:o,onClick:s,children:i},e);return(0,k.jsxs)(V.Box,{ref:h,tabIndex:0,onKeyDown:Se,onPointerDown:be,onPointerMove:Me,onPointerUp:fe,onPointerCancel:fe,onDoubleClick:e=>{let o=e.target.closest("[data-mm-node]");o&&Z(o.dataset.mmNode)},sx:{position:"relative",width:"100%",height:"100%",overflow:"hidden",bgcolor:"#f7f8fa",outline:"none",touchAction:"none",userSelect:"none",cursor:N.current?.kind==="pan"?"grabbing":"default"},children:[(0,k.jsxs)(V.Box,{sx:{position:"absolute",left:0,top:0,transform:`translate(${p.x}px, ${p.y}px) scale(${p.z})`,transformOrigin:"0 0"},children:[(0,k.jsx)("svg",{style:{position:"absolute",left:0,top:0,width:1,height:1,overflow:"visible"},children:z.edges.map(e=>(0,k.jsx)("path",{d:J(e),fill:"none",stroke:e.color,strokeWidth:e.to.depth===1?2.5:1.75,strokeLinecap:"round"},e.to.id))}),z.nodes.map(e=>{let o=Q(e),i=e.node.children?.length??0,s=e.node.expanded===!1&&i>0,c=e.id===f;return(0,k.jsxs)(V.Box,{"data-mm-node":e.id,sx:{position:"absolute",left:e.x,top:e.y,width:e.w,height:e.h,boxSizing:"border-box",display:"flex",alignItems:"center",justifyContent:"center",borderRadius:`${o.radius}px`,bgcolor:o.fill,border:o.stroke!=="none"?`${o.strokeWidth}px solid ${o.stroke}`:0,color:o.text,fontFamily:u.DEFAULT_FONT_FAMILY,fontSize:e.fontSize,fontWeight:e.fontWeight,textDecoration:e.node.style?.textDecoration,whiteSpace:"nowrap",cursor:E?"default":"pointer",boxShadow:c?"0 0 0 2px #fff, 0 0 0 4px #1a73e8":e.depth===0?"0 2px 6px rgba(0,0,0,0.18)":"none",opacity:x?.id===e.id?.35:1,"&:hover .mm-fold":{opacity:1}},children:[m?.id===e.id?null:e.node.topic||"\xA0",i>0&&e.depth>0?(0,k.jsx)(V.Box,{className:"mm-fold","data-mm-fold":e.id,title:s?y.unfold:y.fold,sx:{position:"absolute",top:"50%",[e.side>0?"left":"right"]:"100%",transform:`translate(${e.side>0?4:-4}px, -50%)`,minWidth:18,height:18,px:s?.5:0,boxSizing:"border-box",borderRadius:9,bgcolor:"#fff",border:`1.5px solid ${e.color}`,color:e.color,fontSize:11,fontWeight:600,lineHeight:"15px",textAlign:"center",cursor:"pointer",opacity:s||c?1:0,textDecoration:"none"},children:s?i:"\u2212"}):null]},e.id)}),A&&x?.target?x.target.place==="child"?(0,k.jsx)(V.Box,{sx:{position:"absolute",left:A.x-4,top:A.y-4,width:A.w+8,height:A.h+8,border:"2px dashed #1a73e8",borderRadius:2,pointerEvents:"none"}}):(0,k.jsx)(V.Box,{sx:{position:"absolute",left:A.x,top:x.target.place==="before"?A.y-6:A.y+A.h+4,width:A.w,height:3,borderRadius:2,bgcolor:"#1a73e8",pointerEvents:"none"}}):null,Y&&m?(0,k.jsx)("input",{"data-mm-edit":"",autoFocus:!0,value:m.text,spellCheck:!1,onFocus:e=>e.currentTarget.select(),onChange:e=>D({id:m.id,text:e.target.value}),onBlur:l,onKeyDown:e=>{if(e.stopPropagation(),!e.nativeEvent.isComposing){if(e.key==="Enter")e.preventDefault(),l();else if(e.key==="Escape")e.preventDefault(),D(null),h.current?.focus({preventScroll:!0});else if(e.key==="Tab"){e.preventDefault();let o=m.id,i=m.text;D(null);let s=(0,u.setTopic)(t,o,i);S((0,u.addChild)(s?.root??t,o),void 0,!0)}}},style:{position:"absolute",left:Y.x,top:Y.y,width:Math.max(Y.w,Math.ceil((0,u.measureText)(m.text||" ",Y.fontSize,Y.fontWeight))+40),height:Y.h,boxSizing:"border-box",padding:"0 12px",border:"2px solid #1a73e8",borderRadius:8,outline:"none",textAlign:"center",fontFamily:u.DEFAULT_FONT_FAMILY,fontSize:Y.fontSize,fontWeight:Y.fontWeight,color:"#1f2328",background:"#fff",zIndex:5}}):null]}),x&&se?(0,k.jsx)(V.Box,{sx:{position:"absolute",left:x.px+10,top:x.py+10,px:1.5,py:.5,borderRadius:2,bgcolor:"#fff",border:`1.5px solid ${se.color}`,fontSize:13,opacity:.9,pointerEvents:"none",boxShadow:"0 4px 12px rgba(0,0,0,0.15)"},children:se.node.topic||"\xA0"}):null,W&&!m&&!x&&!E?(0,k.jsxs)(V.Box,{"data-mm-ui":"",sx:{position:"absolute",left:p.x+(W.x+W.w/2)*p.z,top:p.y+W.y*p.z,transform:"translate(-50%, calc(-100% - 8px))",display:"flex",gap:.25,p:.25,bgcolor:"#fff",border:"1px solid #e0e0e0",borderRadius:1,boxShadow:"0 2px 6px rgba(0,0,0,0.12)",zIndex:6},children:[oe("child",y.addChild,(0,k.jsx)(_.ChildBranchIcon,{}),()=>S((0,u.addChild)(t,W.id),void 0,!0)),W.depth>0?oe("sibling",y.addSibling,(0,k.jsx)(_.SiblingBranchIcon,{}),()=>S((0,u.addSibling)(t,W.id),void 0,!0)):null,oe("edit",y.edit,(0,k.jsx)(_.PencilIcon,{}),()=>Z(W.id)),W.depth>0?oe("delete",y.remove,(0,k.jsx)(_.TrashIcon,{}),()=>S((0,u.removeNode)(t,W.id))):null]}):null,K?(0,k.jsx)(V.Box,{sx:{position:"absolute",left:12,right:12,bottom:8,fontSize:12,lineHeight:1.5,color:"text.secondary",pointerEvents:"none"},children:(0,k.jsx)(V.Box,{component:"span",sx:{bgcolor:"rgba(247,248,250,0.85)"},children:y.mapHint})}):null]})});var ge=require("@ehfuse/outliner"),he={ko:{map:"\uC9C0\uB3C4",outline:"\uBAA9\uB85D",addChild:"\uC544\uB798 \uAC00\uC9C0",addSibling:"\uC606 \uAC00\uC9C0",edit:"\uAE00 \uACE0\uCE58\uAE30",remove:"\uC9C0\uC6B0\uAE30",dirSide:"\uC591\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30",dirRight:"\uC624\uB978\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30",dirLeft:"\uC67C\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30",center:"\uAC00\uC6B4\uB370\uB85C",zoomIn:"\uD655\uB300",zoomOut:"\uCD95\uC18C",mapHint:"\uB450 \uBC88 \uD074\uB9AD: \uAE00 \uACE0\uCE58\uAE30 \xB7 Tab: \uC544\uB798 \uAC00\uC9C0 \xB7 Enter: \uC606 \uAC00\uC9C0 \xB7 \uAC00\uC9C0 \uB04C\uAE30: \uC62E\uAE30\uAE30 \xB7 \uBE48 \uACF3 \uB04C\uAE30: \uC774\uB3D9 \xB7 Ctrl+\uD720: \uD655\uB300",newTopic:"\uC0C8 \uAC00\uC9C0"},en:{map:"Map",outline:"List",addChild:"Child branch",addSibling:"Sibling branch",edit:"Edit text",remove:"Delete",dirSide:"Grow both ways",dirRight:"Grow to the right",dirLeft:"Grow to the left",center:"Center",zoomIn:"Zoom in",zoomOut:"Zoom out",mapHint:"Double-click: edit \xB7 Tab: child \xB7 Enter: sibling \xB7 Drag a branch: move \xB7 Drag empty space: pan \xB7 Ctrl+wheel: zoom",newTopic:"New branch"},ja:{map:"\u30DE\u30C3\u30D7",outline:"\u30EA\u30B9\u30C8",addChild:"\u4E0B\u306E\u679D",addSibling:"\u6A2A\u306E\u679D",edit:"\u6587\u5B57\u3092\u7DE8\u96C6",remove:"\u524A\u9664",dirSide:"\u4E21\u5074\u306B\u5E83\u3052\u308B",dirRight:"\u53F3\u306B\u5E83\u3052\u308B",dirLeft:"\u5DE6\u306B\u5E83\u3052\u308B",center:"\u4E2D\u592E\u3078",zoomIn:"\u62E1\u5927",zoomOut:"\u7E2E\u5C0F",mapHint:"\u30C0\u30D6\u30EB\u30AF\u30EA\u30C3\u30AF: \u7DE8\u96C6 \xB7 Tab: \u4E0B\u306E\u679D \xB7 Enter: \u6A2A\u306E\u679D \xB7 \u679D\u3092\u30C9\u30E9\u30C3\u30B0: \u79FB\u52D5 \xB7 \u7A7A\u767D\u30C9\u30E9\u30C3\u30B0: \u30B9\u30AF\u30ED\u30FC\u30EB \xB7 Ctrl+\u30DB\u30A4\u30FC\u30EB: \u62E1\u5927",newTopic:"\u65B0\u3057\u3044\u679D"},zh:{map:"\u5BFC\u56FE",outline:"\u5217\u8868",addChild:"\u5B50\u5206\u652F",addSibling:"\u540C\u7EA7\u5206\u652F",edit:"\u7F16\u8F91\u6587\u5B57",remove:"\u5220\u9664",dirSide:"\u4E24\u4FA7\u5C55\u5F00",dirRight:"\u5411\u53F3\u5C55\u5F00",dirLeft:"\u5411\u5DE6\u5C55\u5F00",center:"\u5C45\u4E2D",zoomIn:"\u653E\u5927",zoomOut:"\u7F29\u5C0F",mapHint:"\u53CC\u51FB: \u7F16\u8F91 \xB7 Tab: \u5B50\u5206\u652F \xB7 Enter: \u540C\u7EA7\u5206\u652F \xB7 \u62D6\u52A8\u5206\u652F: \u79FB\u52A8 \xB7 \u62D6\u52A8\u7A7A\u767D: \u5E73\u79FB \xB7 Ctrl+\u6EDA\u8F6E: \u7F29\u653E",newTopic:"\u65B0\u5206\u652F"},de:{map:"Karte",outline:"Liste",addChild:"Unterzweig",addSibling:"Nebenzweig",edit:"Text bearbeiten",remove:"L\xF6schen",dirSide:"Beidseitig",dirRight:"Nach rechts",dirLeft:"Nach links",center:"Zentrieren",zoomIn:"Vergr\xF6\xDFern",zoomOut:"Verkleinern",mapHint:"Doppelklick: bearbeiten \xB7 Tab: Unterzweig \xB7 Enter: Nebenzweig \xB7 Zweig ziehen: verschieben \xB7 Leere Fl\xE4che ziehen: schwenken \xB7 Strg+Rad: Zoom",newTopic:"Neuer Zweig"},fr:{map:"Carte",outline:"Liste",addChild:"Branche enfant",addSibling:"Branche s\u0153ur",edit:"Modifier le texte",remove:"Supprimer",dirSide:"Des deux c\xF4t\xE9s",dirRight:"Vers la droite",dirLeft:"Vers la gauche",center:"Centrer",zoomIn:"Zoomer",zoomOut:"D\xE9zoomer",mapHint:"Double-clic : modifier \xB7 Tab : enfant \xB7 Entr\xE9e : s\u0153ur \xB7 Glisser une branche : d\xE9placer \xB7 Glisser le vide : d\xE9filer \xB7 Ctrl+molette : zoom",newTopic:"Nouvelle branche"},it:{map:"Mappa",outline:"Elenco",addChild:"Ramo figlio",addSibling:"Ramo fratello",edit:"Modifica testo",remove:"Elimina",dirSide:"Su entrambi i lati",dirRight:"Verso destra",dirLeft:"Verso sinistra",center:"Centra",zoomIn:"Ingrandisci",zoomOut:"Riduci",mapHint:"Doppio clic: modifica \xB7 Tab: figlio \xB7 Invio: fratello \xB7 Trascina un ramo: sposta \xB7 Trascina il vuoto: scorri \xB7 Ctrl+rotella: zoom",newTopic:"Nuovo ramo"},vi:{map:"B\u1EA3n \u0111\u1ED3",outline:"Danh s\xE1ch",addChild:"Nh\xE1nh con",addSibling:"Nh\xE1nh ngang",edit:"S\u1EEDa ch\u1EEF",remove:"X\xF3a",dirSide:"M\u1EDF hai b\xEAn",dirRight:"M\u1EDF sang ph\u1EA3i",dirLeft:"M\u1EDF sang tr\xE1i",center:"V\u1EC1 gi\u1EEFa",zoomIn:"Ph\xF3ng to",zoomOut:"Thu nh\u1ECF",mapHint:"Nh\u1EA5p \u0111\xFAp: s\u1EEDa \xB7 Tab: nh\xE1nh con \xB7 Enter: nh\xE1nh ngang \xB7 K\xE9o nh\xE1nh: di chuy\u1EC3n \xB7 K\xE9o ch\u1ED7 tr\u1ED1ng: cu\u1ED9n \xB7 Ctrl+cu\u1ED9n: ph\xF3ng to",newTopic:"Nh\xE1nh m\u1EDBi"}};function re(a,t){let d=(a??"en").slice(0,2).toLowerCase();return{...(0,ge.outlinerStrings)(a),...he[d]??he.en,...t}}var ue=require("@ehfuse/outliner");var ae=a=>a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");function de(a,t={}){let d=t.padding??24,M=j(a.nodeData,a.direction??2),{minX:f,minY:T,maxX:y,maxY:E}=M.bounds,I=Math.ceil(y-f+d*2),C=Math.ceil(E-T+d*2),K=d-f,U=d-T,h=[];h.push(`<rect width="${I}" height="${C}" fill="${t.background??"#ffffff"}"/>`),h.push(`<g transform="translate(${K} ${U})">`);for(let n of M.edges)h.push(`<path d="${J(n)}" fill="none" stroke="${n.color}" stroke-width="${n.to.depth===1?2.5:1.75}" stroke-linecap="round"/>`);for(let n of M.nodes){let $=Q(n);h.push(`<rect x="${n.x}" y="${n.y}" width="${n.w}" height="${n.h}" rx="${$.radius}" fill="${$.fill}"${$.stroke!=="none"?` stroke="${$.stroke}" stroke-width="${$.strokeWidth}"`:""}/>`);let p=n.node.style?.textDecoration;if(h.push(`<text x="${n.x+n.w/2}" y="${n.y+n.h/2}" text-anchor="middle" dominant-baseline="central" font-family="${ae(ue.DEFAULT_FONT_FAMILY)}" font-size="${n.fontSize}" font-weight="${n.fontWeight}" fill="${$.text}"${p?` text-decoration="${ae(p)}"`:""}>${ae(n.node.topic)}</text>`),n.node.expanded===!1&&(n.node.children?.length??0)>0&&n.depth>0){let r=n.side>0?n.x+n.w+10:n.x-10,w=n.y+n.h/2;h.push(`<circle cx="${r}" cy="${w}" r="9" fill="#ffffff" stroke="${n.color}" stroke-width="1.5"/>`),h.push(`<text x="${r}" y="${w}" text-anchor="middle" dominant-baseline="central" font-family="${ae(ue.DEFAULT_FONT_FAMILY)}" font-size="10" fill="${n.color}">${n.node.children.length}</text>`)}}return h.push("</g>"),`<svg xmlns="http://www.w3.org/2000/svg" width="${I}" height="${C}" viewBox="0 0 ${I} ${C}">${h.join("")}</svg>`}var g=require("react/jsx-runtime"),Be=[{value:2,key:"dirSide",icon:(0,g.jsx)(H.BranchBothIcon,{})},{value:1,key:"dirRight",icon:(0,g.jsx)(H.BranchRightIcon,{})},{value:0,key:"dirLeft",icon:(0,g.jsx)(H.BranchLeftIcon,{})}],xe=(0,X.forwardRef)(function({value:t,onChange:d,locale:M,strings:f,readOnly:T,view:y,defaultView:E="map",onViewChange:I,toolbarEnd:C,hint:K=!0,height:U="100%"},h){let n=re(M,f),[$,p]=(0,X.useState)(E),r=y??$,w=l=>{p(l),I?.(l),l==="map"&&requestAnimationFrame(()=>R.current?.center())},[m,D]=(0,X.useState)(null),x=(0,L.useTreeHistory)(),R=(0,X.useRef)(null),N=t.nodeData,z=t.direction??2,v=(l,O)=>{x.record(N,O),d({...t,nodeData:l})},B=()=>{let l=x.undo(N);l&&d({...t,nodeData:l})},P=()=>{let l=x.redo(N);l&&d({...t,nodeData:l})};(0,X.useImperativeHandle)(h,()=>({exportSvg:()=>de(t),center:()=>R.current?.center()}),[t]);let S=m?(0,L.locateNode)(N,m)?.node:void 0,Z=(0,g.jsx)(G.Box,{sx:{display:"flex",p:.25,borderRadius:1,bgcolor:"#f1f3f4"},children:["map","outline"].map(l=>(0,g.jsx)(G.ButtonBase,{"aria-pressed":r===l,onClick:()=>w(l),sx:{height:26,px:1.25,borderRadius:.75,fontSize:13,fontWeight:r===l?600:400,color:r===l?"primary.main":"text.secondary",bgcolor:r===l?"#fff":"transparent",boxShadow:r===l?"0 1px 2px rgba(0,0,0,0.15)":"none"},children:l==="map"?n.map:n.outline},l))});return(0,g.jsxs)(G.Box,{sx:{display:"flex",flexDirection:"column",height:U,minHeight:0,bgcolor:"#fff"},children:[(0,g.jsx)(L.FormatToolbar,{strings:n,style:S?S.style??{}:void 0,onStyle:l=>{if(!m)return;let O=(0,L.setNodeStyle)(N,[m],l);O&&v(O.root)},canUndo:x.canUndo,canRedo:x.canRedo,onUndo:B,onRedo:P,start:Z,end:C,readOnly:T,children:r==="map"?(0,g.jsxs)(g.Fragment,{children:[Be.map(l=>(0,g.jsx)(L.ToolButton,{label:n[l.key],active:z===l.value,disabled:T,onClick:()=>d({...t,direction:l.value}),children:l.icon},l.value)),(0,g.jsx)(L.ToolDivider,{}),(0,g.jsx)(L.ToolButton,{label:n.zoomOut,onClick:()=>R.current?.zoomBy(1/1.2),children:(0,g.jsx)(H.ZoomOutIcon,{})}),(0,g.jsx)(L.ToolButton,{label:n.zoomIn,onClick:()=>R.current?.zoomBy(1.2),children:(0,g.jsx)(H.ZoomInIcon,{})}),(0,g.jsx)(L.ToolButton,{label:n.center,onClick:()=>R.current?.center(),children:(0,g.jsx)(H.FitCenterIcon,{})})]}):null}),(0,g.jsx)(G.Box,{sx:{position:"relative",flex:1,minHeight:0},children:r==="map"?(0,g.jsx)(ie,{ref:R,root:N,direction:z,onEdit:v,selectedId:m,onSelect:D,strings:n,readOnly:T,onUndo:B,onRedo:P,hint:K}):(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(L.OutlineList,{root:N,onEdit:v,selectedId:m,onSelect:D,strings:n,readOnly:T,onUndo:B,onRedo:P}),K?(0,g.jsx)(G.Box,{sx:{position:"absolute",left:12,right:12,bottom:8,fontSize:12,lineHeight:1.5,color:"text.secondary",pointerEvents:"none"},children:(0,g.jsx)(G.Box,{component:"span",sx:{bgcolor:"rgba(255,255,255,0.9)"},children:n.hint})}):null]})})]})});var ye=require("@ehfuse/outliner");
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/MindMap.tsx", "../src/MapView.tsx", "../src/layout.ts", "../src/i18n.ts", "../src/exportSvg.ts"],
|
|
4
|
-
"sourcesContent": ["export { MindMap, type MindMapProps, type MindMapHandle } from \"./MindMap\";\nexport { MapView, type MapViewProps, type MapViewHandle } from \"./MapView\";\nexport { exportMindMapSvg } from \"./exportSvg\";\nexport { layoutMap, edgePath, nodeLook, nodeSize, BRANCH_COLORS, type MapDirection, type LayoutNode, type LayoutEdge, type MapLayout } from \"./layout\";\nexport { mindMapStrings, type MindMapStrings } from \"./i18n\";\nexport type { MindMapData, MindMapView } from \"./types\";\nexport { createTree, type TreeNode, type TreeNodeStyle } from \"@ehfuse/outliner\";\n", "/**\n * MindMap \u2014 one tree shown as a map or as a list (outline), with one formatting toolbar for both.\n * Controlled: pass `value` and `onChange`. Undo history lives inside (map and list share it).\n */\nimport { forwardRef, useImperativeHandle, useRef, useState, type ReactNode } from \"react\";\nimport { Box, ButtonBase } from \"@mui/material\";\nimport SwapHorizIcon from \"@mui/icons-material/SwapHoriz\";\nimport EastIcon from \"@mui/icons-material/East\";\nimport WestIcon from \"@mui/icons-material/West\";\nimport CenterFocusStrongOutlinedIcon from \"@mui/icons-material/CenterFocusStrongOutlined\";\nimport ZoomInIcon from \"@mui/icons-material/ZoomIn\";\nimport ZoomOutIcon from \"@mui/icons-material/ZoomOut\";\nimport { FormatToolbar, OutlineList, ToolButton, ToolDivider, locateNode, setNodeStyle, useTreeHistory, type TreeNode } from \"@ehfuse/outliner\";\nimport { MapView, type MapViewHandle } from \"./MapView\";\nimport { mindMapStrings, type MindMapStrings } from \"./i18n\";\nimport type { MapDirection } from \"./layout\";\nimport type { MindMapData, MindMapView } from \"./types\";\nimport { exportMindMapSvg } from \"./exportSvg\";\n\nexport interface MindMapProps {\n value: MindMapData;\n onChange: (value: MindMapData) => void;\n locale?: string;\n strings?: Partial<MindMapStrings>;\n readOnly?: boolean;\n /** Controlled view; or use `defaultView`. */\n view?: MindMapView;\n defaultView?: MindMapView;\n onViewChange?: (view: MindMapView) => void;\n /** Extra controls at the right end of the toolbar. */\n toolbarEnd?: ReactNode;\n /** Show the one-line help at the bottom (default true). */\n hint?: boolean;\n height?: number | string;\n}\n\nexport interface MindMapHandle {\n exportSvg: () => string;\n center: () => void;\n}\n\nconst DIRECTIONS: Array<{ value: MapDirection; key: \"dirSide\" | \"dirRight\" | \"dirLeft\"; icon: ReactNode }> = [\n { value: 2, key: \"dirSide\", icon: <SwapHorizIcon sx={{ fontSize: 19 }} /> },\n { value: 1, key: \"dirRight\", icon: <EastIcon sx={{ fontSize: 18 }} /> },\n { value: 0, key: \"dirLeft\", icon: <WestIcon sx={{ fontSize: 18 }} /> },\n];\n\nexport const MindMap = forwardRef<MindMapHandle, MindMapProps>(function MindMap(\n { value, onChange, locale, strings: overrides, readOnly, view: viewProp, defaultView = \"map\", onViewChange, toolbarEnd, hint = true, height = \"100%\" },\n ref\n) {\n const strings = mindMapStrings(locale, overrides);\n const [ownView, setOwnView] = useState<MindMapView>(defaultView);\n const view = viewProp ?? ownView;\n const setView = (next: MindMapView) => {\n setOwnView(next);\n onViewChange?.(next);\n if (next === \"map\") requestAnimationFrame(() => mapRef.current?.center());\n };\n const [selected, setSelected] = useState<string | null>(null);\n const history = useTreeHistory();\n const mapRef = useRef<MapViewHandle | null>(null);\n const root = value.nodeData;\n const direction = (value.direction ?? 2) as MapDirection;\n\n const commit = (next: TreeNode, mergeKey?: string) => {\n history.record(root, mergeKey);\n onChange({ ...value, nodeData: next });\n };\n const undo = () => {\n const prev = history.undo(root);\n if (prev) onChange({ ...value, nodeData: prev });\n };\n const redo = () => {\n const next = history.redo(root);\n if (next) onChange({ ...value, nodeData: next });\n };\n useImperativeHandle(ref, () => ({ exportSvg: () => exportMindMapSvg(value), center: () => mapRef.current?.center() }), [value]);\n\n const selectedNode = selected ? locateNode(root, selected)?.node : undefined;\n const viewSwitch = (\n <Box sx={{ display: \"flex\", p: 0.25, borderRadius: 1, bgcolor: \"#f1f3f4\" }}>\n {([\"map\", \"outline\"] as const).map((item) => (\n <ButtonBase\n key={item}\n aria-pressed={view === item}\n onClick={() => setView(item)}\n sx={{\n height: 26,\n px: 1.25,\n borderRadius: 0.75,\n fontSize: 13,\n fontWeight: view === item ? 600 : 400,\n color: view === item ? \"primary.main\" : \"text.secondary\",\n bgcolor: view === item ? \"#fff\" : \"transparent\",\n boxShadow: view === item ? \"0 1px 2px rgba(0,0,0,0.15)\" : \"none\",\n }}\n >\n {item === \"map\" ? strings.map : strings.outline}\n </ButtonBase>\n ))}\n </Box>\n );\n\n return (\n <Box sx={{ display: \"flex\", flexDirection: \"column\", height, minHeight: 0, bgcolor: \"#fff\" }}>\n <FormatToolbar\n strings={strings}\n style={selectedNode ? (selectedNode.style ?? {}) : undefined}\n onStyle={(patch) => {\n if (!selected) return;\n const result = setNodeStyle(root, [selected], patch);\n if (result) commit(result.root);\n }}\n canUndo={history.canUndo}\n canRedo={history.canRedo}\n onUndo={undo}\n onRedo={redo}\n start={viewSwitch}\n end={toolbarEnd}\n readOnly={readOnly}\n >\n {view === \"map\" ? (\n <>\n {DIRECTIONS.map((item) => (\n <ToolButton key={item.value} label={strings[item.key]} active={direction === item.value} disabled={readOnly} onClick={() => onChange({ ...value, direction: item.value })}>\n {item.icon}\n </ToolButton>\n ))}\n <ToolDivider />\n <ToolButton label={strings.zoomOut} onClick={() => mapRef.current?.zoomBy(1 / 1.2)}>\n <ZoomOutIcon sx={{ fontSize: 19 }} />\n </ToolButton>\n <ToolButton label={strings.zoomIn} onClick={() => mapRef.current?.zoomBy(1.2)}>\n <ZoomInIcon sx={{ fontSize: 19 }} />\n </ToolButton>\n <ToolButton label={strings.center} onClick={() => mapRef.current?.center()}>\n <CenterFocusStrongOutlinedIcon sx={{ fontSize: 18 }} />\n </ToolButton>\n </>\n ) : null}\n </FormatToolbar>\n <Box sx={{ position: \"relative\", flex: 1, minHeight: 0 }}>\n {view === \"map\" ? (\n <MapView ref={mapRef} root={root} direction={direction} onEdit={commit} selectedId={selected} onSelect={setSelected} strings={strings} readOnly={readOnly} onUndo={undo} onRedo={redo} hint={hint} />\n ) : (\n <>\n <OutlineList root={root} onEdit={commit} selectedId={selected} onSelect={setSelected} strings={strings} readOnly={readOnly} onUndo={undo} onRedo={redo} />\n {hint ? (\n <Box sx={{ position: \"absolute\", left: 12, right: 12, bottom: 8, fontSize: 12, lineHeight: 1.5, color: \"text.secondary\", pointerEvents: \"none\" }}>\n <Box component=\"span\" sx={{ bgcolor: \"rgba(255,255,255,0.9)\" }}>\n {strings.hint}\n </Box>\n </Box>\n ) : null}\n </>\n )}\n </Box>\n </Box>\n );\n});\n", "/**\n * Map view \u2014 draws the tree as a mind map and edits it in place.\n *\n * Mouse: click to select \u00B7 double-click to edit \u00B7 drag a branch onto another (middle = into it, top / bottom edge = before / after)\n * \u00B7 drag empty space to pan \u00B7 Ctrl/\u2318 + wheel to zoom (a plain wheel scrolls the page, not the map).\n * Keys (map focused): Tab child \u00B7 Enter sibling \u00B7 F2 edit \u00B7 Delete / Backspace remove \u00B7 Space fold \u00B7 arrows move the selection \u00B7\n * Ctrl/\u2318+Z undo \u00B7 Ctrl/\u2318+Shift+Z / Ctrl+Y redo.\n */\nimport { forwardRef, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, type KeyboardEvent, type PointerEvent } from \"react\";\nimport { Box, IconButton, Tooltip } from \"@mui/material\";\nimport SubdirectoryArrowRightIcon from \"@mui/icons-material/SubdirectoryArrowRight\";\nimport AddIcon from \"@mui/icons-material/Add\";\nimport EditOutlinedIcon from \"@mui/icons-material/EditOutlined\";\nimport DeleteOutlineIcon from \"@mui/icons-material/DeleteOutline\";\nimport {\n DEFAULT_FONT_FAMILY,\n addChild,\n addSibling,\n containsNode,\n locateNode,\n measureText,\n moveNode,\n removeNode,\n setTopic,\n toggleFold,\n type TreeEdit,\n type TreeNode,\n} from \"@ehfuse/outliner\";\nimport { edgePath, layoutMap, nodeLook, type LayoutNode, type MapDirection } from \"./layout\";\nimport type { MindMapStrings } from \"./i18n\";\n\nexport interface MapViewHandle {\n center: () => void;\n zoomBy: (factor: number) => void;\n}\n\nexport interface MapViewProps {\n root: TreeNode;\n direction: MapDirection;\n onEdit: (root: TreeNode, mergeKey?: string) => void;\n selectedId: string | null;\n onSelect: (id: string | null) => void;\n strings: MindMapStrings;\n readOnly?: boolean;\n onUndo?: () => void;\n onRedo?: () => void;\n /** Show the one-line help at the bottom (default true). */\n hint?: boolean;\n}\n\nconst ZOOM_MIN = 0.3;\nconst ZOOM_MAX = 2.5;\nconst DRAG_START = 5;\n\ntype DropPlace = \"before\" | \"after\" | \"child\";\n\nexport const MapView = forwardRef<MapViewHandle, MapViewProps>(function MapView({ root, direction, onEdit, selectedId, onSelect, strings, readOnly, onUndo, onRedo, hint = true }, ref) {\n const boxRef = useRef<HTMLDivElement | null>(null);\n const [size, setSize] = useState({ w: 0, h: 0 });\n const [view, setView] = useState({ x: 0, y: 0, z: 1 });\n const viewRef = useRef(view);\n viewRef.current = view;\n const [editing, setEditing] = useState<{ id: string; text: string } | null>(null);\n const [drag, setDrag] = useState<{ id: string; px: number; py: number; target: { id: string; place: DropPlace } | null } | null>(null);\n const pointer = useRef<{ kind: \"pan\" | \"node\"; id?: string; sx: number; sy: number; vx: number; vy: number; moved: boolean } | null>(null);\n const layout = useMemo(() => layoutMap(root, direction), [root, direction]);\n\n // Size \u2014 center the map the first time the box has a size.\n const centered = useRef(false);\n useLayoutEffect(() => {\n const el = boxRef.current;\n if (!el) return;\n const ro = new ResizeObserver(() => setSize({ w: el.clientWidth, h: el.clientHeight }));\n ro.observe(el);\n setSize({ w: el.clientWidth, h: el.clientHeight });\n return () => ro.disconnect();\n }, []);\n const center = useCallback(() => {\n const { minX, minY, maxX, maxY } = layout.bounds;\n const z = viewRef.current.z;\n setView({ x: size.w / 2 - ((minX + maxX) / 2) * z, y: size.h / 2 - ((minY + maxY) / 2) * z, z });\n }, [layout, size]);\n useEffect(() => {\n if (centered.current || size.w === 0) return;\n centered.current = true;\n center();\n }, [size, center]);\n const zoomAt = useCallback((factor: number, cx: number, cy: number) => {\n setView((v) => {\n const z = Math.min(ZOOM_MAX, Math.max(ZOOM_MIN, v.z * factor));\n return { x: cx - (cx - v.x) * (z / v.z), y: cy - (cy - v.y) * (z / v.z), z };\n });\n }, []);\n useImperativeHandle(ref, () => ({ center, zoomBy: (factor) => zoomAt(factor, size.w / 2, size.h / 2) }), [center, zoomAt, size]);\n\n // Ctrl/\u2318 + wheel zooms at the cursor; a plain wheel is left to the page (it must not pan the map).\n useEffect(() => {\n const el = boxRef.current;\n if (!el) return;\n const onWheel = (event: WheelEvent) => {\n if (!(event.ctrlKey || event.metaKey)) return;\n event.preventDefault();\n const r = el.getBoundingClientRect();\n zoomAt(event.deltaY < 0 ? 1.1 : 1 / 1.1, event.clientX - r.left, event.clientY - r.top);\n };\n el.addEventListener(\"wheel\", onWheel, { passive: false });\n return () => el.removeEventListener(\"wheel\", onWheel);\n }, [zoomAt]);\n\n const apply = (result: TreeEdit | null, mergeKey?: string, editNew = false) => {\n if (!result) return;\n onEdit(result.root, mergeKey);\n if (result.focusId) {\n onSelect(result.focusId);\n if (editNew) setEditing({ id: result.focusId, text: \"\" });\n }\n };\n const startEdit = (id: string) => {\n if (readOnly) return;\n const at = locateNode(root, id);\n if (at) setEditing({ id, text: at.node.topic });\n };\n const commitEdit = () => {\n if (!editing) return;\n apply(setTopic(root, editing.id, editing.text));\n setEditing(null);\n boxRef.current?.focus({ preventScroll: true });\n };\n\n const toCanvas = (clientX: number, clientY: number) => {\n const r = boxRef.current!.getBoundingClientRect();\n return { x: (clientX - r.left - view.x) / view.z, y: (clientY - r.top - view.y) / view.z };\n };\n const dropAt = (clientX: number, clientY: number, dragged: TreeNode): { id: string; place: DropPlace } | null => {\n const p = toCanvas(clientX, clientY);\n for (const ln of layout.nodes) {\n if (p.x < ln.x - 4 || p.x > ln.x + ln.w + 4 || p.y < ln.y - 4 || p.y > ln.y + ln.h + 4) continue;\n if (containsNode(dragged, ln.id)) return null;\n if (ln.depth === 0) return { id: ln.id, place: \"child\" };\n const rel = (p.y - ln.y) / ln.h;\n return { id: ln.id, place: rel < 0.25 ? \"before\" : rel > 0.75 ? \"after\" : \"child\" };\n }\n return null;\n };\n\n const onPointerDown = (event: PointerEvent<HTMLDivElement>) => {\n if (event.button !== 0) return;\n const target = event.target as HTMLElement;\n if (target.closest(\"[data-mm-ui]\")) return;\n if (editing && !target.closest(\"[data-mm-edit]\")) commitEdit();\n if (target.closest(\"[data-mm-edit]\")) return;\n const fold = target.closest(\"[data-mm-fold]\") as HTMLElement | null;\n if (fold) {\n apply(toggleFold(root, fold.dataset.mmFold!));\n return;\n }\n const nodeEl = target.closest(\"[data-mm-node]\") as HTMLElement | null;\n boxRef.current?.focus({ preventScroll: true });\n // Capture the pointer only once a drag starts \u2014 capturing on press retargets the double-click to the box, so editing never opened.\n if (nodeEl) {\n const id = nodeEl.dataset.mmNode!;\n onSelect(id);\n pointer.current = { kind: \"node\", id, sx: event.clientX, sy: event.clientY, vx: view.x, vy: view.y, moved: false };\n } else {\n onSelect(null);\n pointer.current = { kind: \"pan\", sx: event.clientX, sy: event.clientY, vx: view.x, vy: view.y, moved: false };\n }\n };\n const onPointerMove = (event: PointerEvent<HTMLDivElement>) => {\n const p = pointer.current;\n if (!p) return;\n const dx = event.clientX - p.sx;\n const dy = event.clientY - p.sy;\n if (!p.moved && Math.hypot(dx, dy) < DRAG_START) return;\n if (!p.moved && !boxRef.current?.hasPointerCapture(event.pointerId)) boxRef.current?.setPointerCapture(event.pointerId);\n p.moved = true;\n if (p.kind === \"pan\") {\n setView((v) => ({ ...v, x: p.vx + dx, y: p.vy + dy }));\n return;\n }\n if (readOnly || p.id === root.id) return;\n const dragged = locateNode(root, p.id!)?.node;\n if (!dragged) return;\n const r = boxRef.current!.getBoundingClientRect();\n setDrag({ id: p.id!, px: event.clientX - r.left, py: event.clientY - r.top, target: dropAt(event.clientX, event.clientY, dragged) });\n };\n const onPointerUp = (event: PointerEvent<HTMLDivElement>) => {\n const p = pointer.current;\n pointer.current = null;\n if (boxRef.current?.hasPointerCapture(event.pointerId)) boxRef.current.releasePointerCapture(event.pointerId);\n if (p?.kind === \"node\" && drag?.target) apply(moveNode(root, drag.id, drag.target.id, drag.target.place));\n setDrag(null);\n };\n\n const neighbor = (ln: LayoutNode, key: string): string | null => {\n const at = locateNode(root, ln.id);\n if (!at) return null;\n if (key === \"ArrowUp\" || key === \"ArrowDown\") {\n if (!at.parent) return null;\n const sibs = (at.parent.children ?? []).filter((kid) => layout.byId.get(kid.id)?.side === ln.side);\n const i = sibs.findIndex((kid) => kid.id === ln.id);\n return sibs[i + (key === \"ArrowUp\" ? -1 : 1)]?.id ?? null;\n }\n const outward = (key === \"ArrowRight\" && ln.side >= 0) || (key === \"ArrowLeft\" && ln.side <= 0);\n if (outward) {\n const kids = at.node.expanded === false ? [] : (at.node.children ?? []);\n const want = ln.side === 0 ? (key === \"ArrowRight\" ? 1 : -1) : ln.side;\n return kids.find((kid) => layout.byId.get(kid.id)?.side === want)?.id ?? null;\n }\n return ln.parentId;\n };\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (editing || (event.target as HTMLElement).tagName === \"INPUT\") return;\n const mod = event.ctrlKey || event.metaKey;\n if (mod && (event.key === \"z\" || event.key === \"Z\")) {\n event.preventDefault();\n if (event.shiftKey) onRedo?.();\n else onUndo?.();\n return;\n }\n if (mod && (event.key === \"y\" || event.key === \"Y\")) {\n event.preventDefault();\n onRedo?.();\n return;\n }\n const ln = selectedId ? layout.byId.get(selectedId) : null;\n if (!ln) return;\n if (event.key.startsWith(\"Arrow\")) {\n const next = neighbor(ln, event.key);\n event.preventDefault();\n if (next) onSelect(next);\n return;\n }\n if (readOnly) return;\n if (event.key === \"Tab\") {\n event.preventDefault();\n apply(addChild(root, ln.id), undefined, true);\n } else if (event.key === \"Enter\") {\n event.preventDefault();\n apply(addSibling(root, ln.id), undefined, true);\n } else if (event.key === \"F2\") {\n event.preventDefault();\n startEdit(ln.id);\n } else if (event.key === \"Delete\" || event.key === \"Backspace\") {\n event.preventDefault();\n apply(removeNode(root, ln.id));\n } else if (event.key === \" \") {\n event.preventDefault();\n apply(toggleFold(root, ln.id));\n }\n };\n\n const selected = selectedId ? layout.byId.get(selectedId) : undefined;\n const editingLN = editing ? layout.byId.get(editing.id) : undefined;\n const dragLN = drag ? layout.byId.get(drag.id) : undefined;\n const dropLN = drag?.target ? layout.byId.get(drag.target.id) : undefined;\n const barButton = (key: string, label: string, icon: React.ReactNode, onClick: () => void) => (\n <Tooltip key={key} title={label} disableInteractive>\n <IconButton size=\"small\" aria-label={label} onMouseDown={(event) => event.preventDefault()} onClick={onClick} sx={{ width: 28, height: 28, color: \"text.secondary\", \"&:hover\": { color: \"primary.main\" } }}>\n {icon}\n </IconButton>\n </Tooltip>\n );\n\n return (\n <Box\n ref={boxRef}\n tabIndex={0}\n onKeyDown={onKeyDown}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerUp}\n onDoubleClick={(event) => {\n const nodeEl = (event.target as HTMLElement).closest(\"[data-mm-node]\") as HTMLElement | null;\n if (nodeEl) startEdit(nodeEl.dataset.mmNode!);\n }}\n sx={{ position: \"relative\", width: \"100%\", height: \"100%\", overflow: \"hidden\", bgcolor: \"#f7f8fa\", outline: \"none\", touchAction: \"none\", userSelect: \"none\", cursor: pointer.current?.kind === \"pan\" ? \"grabbing\" : \"default\" }}\n >\n <Box sx={{ position: \"absolute\", left: 0, top: 0, transform: `translate(${view.x}px, ${view.y}px) scale(${view.z})`, transformOrigin: \"0 0\" }}>\n <svg style={{ position: \"absolute\", left: 0, top: 0, width: 1, height: 1, overflow: \"visible\" }}>\n {layout.edges.map((edge) => (\n <path key={edge.to.id} d={edgePath(edge)} fill=\"none\" stroke={edge.color} strokeWidth={edge.to.depth === 1 ? 2.5 : 1.75} strokeLinecap=\"round\" />\n ))}\n </svg>\n {layout.nodes.map((ln) => {\n const look = nodeLook(ln);\n const kids = ln.node.children?.length ?? 0;\n const folded = ln.node.expanded === false && kids > 0;\n const isSel = ln.id === selectedId;\n return (\n <Box\n key={ln.id}\n data-mm-node={ln.id}\n sx={{\n position: \"absolute\",\n left: ln.x,\n top: ln.y,\n width: ln.w,\n height: ln.h,\n boxSizing: \"border-box\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: `${look.radius}px`,\n bgcolor: look.fill,\n border: look.stroke !== \"none\" ? `${look.strokeWidth}px solid ${look.stroke}` : 0,\n color: look.text,\n fontFamily: DEFAULT_FONT_FAMILY,\n fontSize: ln.fontSize,\n fontWeight: ln.fontWeight,\n textDecoration: ln.node.style?.textDecoration,\n whiteSpace: \"nowrap\",\n cursor: readOnly ? \"default\" : \"pointer\",\n boxShadow: isSel ? \"0 0 0 2px #fff, 0 0 0 4px #1a73e8\" : ln.depth === 0 ? \"0 2px 6px rgba(0,0,0,0.18)\" : \"none\",\n opacity: drag?.id === ln.id ? 0.35 : 1,\n \"&:hover .mm-fold\": { opacity: 1 },\n }}\n >\n {editing?.id === ln.id ? null : ln.node.topic || \"\u00A0\"}\n {kids > 0 && ln.depth > 0 ? (\n <Box\n className=\"mm-fold\"\n data-mm-fold={ln.id}\n title={folded ? strings.unfold : strings.fold}\n sx={{\n position: \"absolute\",\n top: \"50%\",\n [ln.side > 0 ? \"left\" : \"right\"]: \"100%\",\n transform: `translate(${ln.side > 0 ? 4 : -4}px, -50%)`,\n minWidth: 18,\n height: 18,\n px: folded ? 0.5 : 0,\n boxSizing: \"border-box\",\n borderRadius: 9,\n bgcolor: \"#fff\",\n border: `1.5px solid ${ln.color}`,\n color: ln.color,\n fontSize: 11,\n fontWeight: 600,\n lineHeight: \"15px\",\n textAlign: \"center\",\n cursor: \"pointer\",\n opacity: folded || isSel ? 1 : 0,\n textDecoration: \"none\",\n }}\n >\n {folded ? kids : \"\u2212\"}\n </Box>\n ) : null}\n </Box>\n );\n })}\n {/* Drop target \u2014 into (outline) or before / after (line). */}\n {dropLN && drag?.target ? (\n drag.target.place === \"child\" ? (\n <Box sx={{ position: \"absolute\", left: dropLN.x - 4, top: dropLN.y - 4, width: dropLN.w + 8, height: dropLN.h + 8, border: \"2px dashed #1a73e8\", borderRadius: 2, pointerEvents: \"none\" }} />\n ) : (\n <Box sx={{ position: \"absolute\", left: dropLN.x, top: drag.target.place === \"before\" ? dropLN.y - 6 : dropLN.y + dropLN.h + 4, width: dropLN.w, height: 3, borderRadius: 2, bgcolor: \"#1a73e8\", pointerEvents: \"none\" }} />\n )\n ) : null}\n {editingLN && editing ? (\n <input\n data-mm-edit=\"\"\n autoFocus\n value={editing.text}\n spellCheck={false}\n onFocus={(event) => event.currentTarget.select()}\n onChange={(event) => setEditing({ id: editing.id, text: event.target.value })}\n onBlur={commitEdit}\n onKeyDown={(event) => {\n event.stopPropagation();\n if (event.nativeEvent.isComposing) return;\n if (event.key === \"Enter\") {\n event.preventDefault();\n commitEdit();\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n setEditing(null);\n boxRef.current?.focus({ preventScroll: true });\n } else if (event.key === \"Tab\") {\n event.preventDefault();\n const id = editing.id;\n const text = editing.text;\n setEditing(null);\n const named = setTopic(root, id, text);\n apply(addChild(named?.root ?? root, id), undefined, true);\n }\n }}\n style={{\n position: \"absolute\",\n left: editingLN.x,\n top: editingLN.y,\n width: Math.max(editingLN.w, Math.ceil(measureText(editing.text || \" \", editingLN.fontSize, editingLN.fontWeight)) + 40),\n height: editingLN.h,\n boxSizing: \"border-box\",\n padding: \"0 12px\",\n border: \"2px solid #1a73e8\",\n borderRadius: 8,\n outline: \"none\",\n textAlign: \"center\",\n fontFamily: DEFAULT_FONT_FAMILY,\n fontSize: editingLN.fontSize,\n fontWeight: editingLN.fontWeight,\n color: \"#1f2328\",\n background: \"#fff\",\n zIndex: 5,\n }}\n />\n ) : null}\n </Box>\n {/* Dragged branch follows the pointer. */}\n {drag && dragLN ? (\n <Box sx={{ position: \"absolute\", left: drag.px + 10, top: drag.py + 10, px: 1.5, py: 0.5, borderRadius: 2, bgcolor: \"#fff\", border: `1.5px solid ${dragLN.color}`, fontSize: 13, opacity: 0.9, pointerEvents: \"none\", boxShadow: \"0 4px 12px rgba(0,0,0,0.15)\" }}>\n {dragLN.node.topic || \"\u00A0\"}\n </Box>\n ) : null}\n {/* Buttons above the selected branch \u2014 growing the map without knowing the keys. */}\n {selected && !editing && !drag && !readOnly ? (\n <Box\n data-mm-ui=\"\"\n sx={{\n position: \"absolute\",\n left: view.x + (selected.x + selected.w / 2) * view.z,\n top: view.y + selected.y * view.z,\n transform: \"translate(-50%, calc(-100% - 8px))\",\n display: \"flex\",\n gap: 0.25,\n p: 0.25,\n bgcolor: \"#fff\",\n border: \"1px solid #e0e0e0\",\n borderRadius: 1,\n boxShadow: \"0 2px 6px rgba(0,0,0,0.12)\",\n zIndex: 6,\n }}\n >\n {barButton(\"child\", strings.addChild, <SubdirectoryArrowRightIcon sx={{ fontSize: 18 }} />, () => apply(addChild(root, selected.id), undefined, true))}\n {selected.depth > 0 ? barButton(\"sibling\", strings.addSibling, <AddIcon sx={{ fontSize: 18 }} />, () => apply(addSibling(root, selected.id), undefined, true)) : null}\n {barButton(\"edit\", strings.edit, <EditOutlinedIcon sx={{ fontSize: 17 }} />, () => startEdit(selected.id))}\n {selected.depth > 0 ? barButton(\"delete\", strings.remove, <DeleteOutlineIcon sx={{ fontSize: 18 }} />, () => apply(removeNode(root, selected.id))) : null}\n </Box>\n ) : null}\n {hint ? (\n <Box sx={{ position: \"absolute\", left: 12, right: 12, bottom: 8, fontSize: 12, lineHeight: 1.5, color: \"text.secondary\", pointerEvents: \"none\" }}>\n <Box component=\"span\" sx={{ bgcolor: \"rgba(247,248,250,0.85)\" }}>\n {strings.mapHint}\n </Box>\n </Box>\n ) : null}\n </Box>\n );\n});\n", "/**\n * Map layout \u2014 root in the middle, branches to the right / left / both sides.\n * Node sizes come from measured text (no DOM pass), so layout is a pure function of the data.\n */\nimport { measureText, type TreeNode } from \"@ehfuse/outliner\";\n\n/** 0 = left, 1 = right, 2 = both sides (same values as Mind Elixir). */\nexport type MapDirection = 0 | 1 | 2;\n\nexport interface LayoutNode {\n id: string;\n node: TreeNode;\n depth: number;\n x: number;\n y: number;\n w: number;\n h: number;\n /** 1 = grows to the right, -1 = to the left, 0 = root. */\n side: 1 | -1 | 0;\n color: string;\n parentId: string | null;\n fontSize: number;\n fontWeight: string;\n}\n\nexport interface LayoutEdge {\n from: LayoutNode;\n to: LayoutNode;\n color: string;\n}\n\nexport interface MapLayout {\n nodes: LayoutNode[];\n byId: Map<string, LayoutNode>;\n edges: LayoutEdge[];\n bounds: { minX: number; minY: number; maxX: number; maxY: number };\n}\n\nexport const BRANCH_COLORS = [\"#e8710a\", \"#1a73e8\", \"#188038\", \"#d93025\", \"#9334e6\", \"#f9ab00\", \"#12b5cb\", \"#c2185b\"];\nconst H_GAP_ROOT = 64;\nconst H_GAP = 40;\nconst V_GAP = 14;\n\n/** Default text size / weight by depth (a node's own style wins). */\nexport function nodeFont(node: TreeNode, depth: number) {\n const fontSize = node.style?.fontSize ? parseFloat(node.style.fontSize) : depth === 0 ? 22 : depth === 1 ? 16 : 14;\n const fontWeight = node.style?.fontWeight ?? (depth === 0 ? \"700\" : depth === 1 ? \"500\" : \"400\");\n return { fontSize, fontWeight };\n}\n\nexport function nodeSize(node: TreeNode, depth: number) {\n const { fontSize, fontWeight } = nodeFont(node, depth);\n const padX = depth === 0 ? 28 : depth === 1 ? 16 : 12;\n const padY = depth === 0 ? 14 : depth === 1 ? 8 : 6;\n const textW = measureText(node.topic || \" \", fontSize, fontWeight);\n return {\n w: Math.max(depth === 0 ? 100 : 48, Math.ceil(textW) + padX * 2),\n h: Math.ceil(fontSize * 1.4) + padY * 2,\n fontSize,\n fontWeight,\n };\n}\n\nconst visibleKids = (node: TreeNode) => (node.expanded === false ? [] : (node.children ?? []));\n\nexport function layoutMap(root: TreeNode, direction: MapDirection = 2): MapLayout {\n const heights = new Map<string, number>();\n const subtree = (node: TreeNode, depth: number): number => {\n const own = nodeSize(node, depth).h;\n const kids = visibleKids(node);\n const sum = kids.reduce((acc, kid) => acc + subtree(kid, depth + 1), 0) + V_GAP * Math.max(0, kids.length - 1);\n const value = Math.max(own, sum);\n heights.set(node.id, value);\n return value;\n };\n\n const nodes: LayoutNode[] = [];\n const edges: LayoutEdge[] = [];\n const rootSize = nodeSize(root, 0);\n const rootLN: LayoutNode = { id: root.id, node: root, depth: 0, x: -rootSize.w / 2, y: -rootSize.h / 2, w: rootSize.w, h: rootSize.h, side: 0, color: \"#3b3f5c\", parentId: null, fontSize: rootSize.fontSize, fontWeight: rootSize.fontWeight };\n nodes.push(rootLN);\n\n const place = (parent: LayoutNode, kids: TreeNode[], side: 1 | -1, depth: number, colorOf: (kid: TreeNode, i: number) => string) => {\n kids.forEach((kid) => subtree(kid, depth));\n const total = kids.reduce((acc, kid) => acc + (heights.get(kid.id) ?? 0), 0) + V_GAP * Math.max(0, kids.length - 1);\n let top = parent.y + parent.h / 2 - total / 2;\n const gap = depth === 1 ? H_GAP_ROOT : H_GAP;\n kids.forEach((kid, i) => {\n const sh = heights.get(kid.id) ?? 0;\n const size = nodeSize(kid, depth);\n const cy = top + sh / 2;\n const x = side > 0 ? parent.x + parent.w + gap : parent.x - gap - size.w;\n const color = colorOf(kid, i);\n const ln: LayoutNode = { id: kid.id, node: kid, depth, x, y: cy - size.h / 2, w: size.w, h: size.h, side, color, parentId: parent.id, fontSize: size.fontSize, fontWeight: size.fontWeight };\n nodes.push(ln);\n edges.push({ from: parent, to: ln, color });\n place(ln, visibleKids(kid), side, depth + 1, () => color);\n top += sh + V_GAP;\n });\n };\n\n const kids = visibleKids(root);\n const all = root.children ?? [];\n const colorFor = (kid: TreeNode) => BRANCH_COLORS[Math.max(0, all.indexOf(kid)) % BRANCH_COLORS.length];\n const sideOf = (kid: TreeNode, i: number): 1 | -1 => {\n if (direction === 0) return -1;\n if (direction === 1) return 1;\n if (kid.direction === 0) return -1;\n if (kid.direction === 1) return 1;\n // Both sides: first half right, second half left (keeps reading order top-down on each side).\n return i < Math.ceil(kids.length / 2) ? 1 : -1;\n };\n const right = kids.filter((kid, i) => sideOf(kid, i) === 1);\n const left = kids.filter((kid, i) => sideOf(kid, i) === -1);\n place(rootLN, right, 1, 1, colorFor);\n place(rootLN, left, -1, 1, colorFor);\n\n const bounds = { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity };\n for (const n of nodes) {\n bounds.minX = Math.min(bounds.minX, n.x);\n bounds.minY = Math.min(bounds.minY, n.y);\n bounds.maxX = Math.max(bounds.maxX, n.x + n.w);\n bounds.maxY = Math.max(bounds.maxY, n.y + n.h);\n }\n return { nodes, byId: new Map(nodes.map((n) => [n.id, n])), edges, bounds };\n}\n\n/** Curved connector from the parent's side to the child's near side. */\nexport function edgePath(edge: LayoutEdge): string {\n const { from, to } = edge;\n const side = to.side >= 0 ? 1 : -1;\n const x1 = from.depth === 0 ? from.x + from.w / 2 + (side * from.w) / 2 - side * 12 : side > 0 ? from.x + from.w : from.x;\n const y1 = from.y + from.h / 2;\n const x2 = side > 0 ? to.x : to.x + to.w;\n const y2 = to.y + to.h / 2;\n const dx = (x2 - x1) * 0.5;\n return `M ${x1} ${y1} C ${x1 + dx} ${y1}, ${x2 - dx} ${y2}, ${x2} ${y2}`;\n}\n\n/** Visual look of a node (fill \u00B7 border \u00B7 text color \u00B7 radius) \u2014 shared by the map and the SVG export. */\nexport function nodeLook(ln: LayoutNode) {\n const style = ln.node.style ?? {};\n if (ln.depth === 0) return { fill: style.background ?? \"#3b3f5c\", stroke: \"none\", strokeWidth: 0, text: style.color ?? \"#ffffff\", radius: ln.h / 2 };\n if (ln.depth === 1) return { fill: style.background ?? \"#ffffff\", stroke: ln.color, strokeWidth: 2, text: style.color ?? \"#1f2328\", radius: ln.h / 2 };\n return { fill: style.background ?? \"#ffffff\", stroke: \"#d0d4da\", strokeWidth: 1, text: style.color ?? \"#1f2328\", radius: 8 };\n}\n", "import { outlinerStrings, type OutlinerStrings } from \"@ehfuse/outliner\";\n\n/** Map-only strings (the formatting / outline strings come from @ehfuse/outliner). */\nconst STRINGS = {\n ko: { map: \"\uC9C0\uB3C4\", outline: \"\uBAA9\uB85D\", addChild: \"\uC544\uB798 \uAC00\uC9C0\", addSibling: \"\uC606 \uAC00\uC9C0\", edit: \"\uAE00 \uACE0\uCE58\uAE30\", remove: \"\uC9C0\uC6B0\uAE30\", dirSide: \"\uC591\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30\", dirRight: \"\uC624\uB978\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30\", dirLeft: \"\uC67C\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30\", center: \"\uAC00\uC6B4\uB370\uB85C\", zoomIn: \"\uD655\uB300\", zoomOut: \"\uCD95\uC18C\", mapHint: \"\uB450 \uBC88 \uD074\uB9AD: \uAE00 \uACE0\uCE58\uAE30 \u00B7 Tab: \uC544\uB798 \uAC00\uC9C0 \u00B7 Enter: \uC606 \uAC00\uC9C0 \u00B7 \uAC00\uC9C0 \uB04C\uAE30: \uC62E\uAE30\uAE30 \u00B7 \uBE48 \uACF3 \uB04C\uAE30: \uC774\uB3D9 \u00B7 Ctrl+\uD720: \uD655\uB300\", newTopic: \"\uC0C8 \uAC00\uC9C0\" },\n en: { map: \"Map\", outline: \"List\", addChild: \"Child branch\", addSibling: \"Sibling branch\", edit: \"Edit text\", remove: \"Delete\", dirSide: \"Grow both ways\", dirRight: \"Grow to the right\", dirLeft: \"Grow to the left\", center: \"Center\", zoomIn: \"Zoom in\", zoomOut: \"Zoom out\", mapHint: \"Double-click: edit \u00B7 Tab: child \u00B7 Enter: sibling \u00B7 Drag a branch: move \u00B7 Drag empty space: pan \u00B7 Ctrl+wheel: zoom\", newTopic: \"New branch\" },\n ja: { map: \"\u30DE\u30C3\u30D7\", outline: \"\u30EA\u30B9\u30C8\", addChild: \"\u4E0B\u306E\u679D\", addSibling: \"\u6A2A\u306E\u679D\", edit: \"\u6587\u5B57\u3092\u7DE8\u96C6\", remove: \"\u524A\u9664\", dirSide: \"\u4E21\u5074\u306B\u5E83\u3052\u308B\", dirRight: \"\u53F3\u306B\u5E83\u3052\u308B\", dirLeft: \"\u5DE6\u306B\u5E83\u3052\u308B\", center: \"\u4E2D\u592E\u3078\", zoomIn: \"\u62E1\u5927\", zoomOut: \"\u7E2E\u5C0F\", mapHint: \"\u30C0\u30D6\u30EB\u30AF\u30EA\u30C3\u30AF: \u7DE8\u96C6 \u00B7 Tab: \u4E0B\u306E\u679D \u00B7 Enter: \u6A2A\u306E\u679D \u00B7 \u679D\u3092\u30C9\u30E9\u30C3\u30B0: \u79FB\u52D5 \u00B7 \u7A7A\u767D\u30C9\u30E9\u30C3\u30B0: \u30B9\u30AF\u30ED\u30FC\u30EB \u00B7 Ctrl+\u30DB\u30A4\u30FC\u30EB: \u62E1\u5927\", newTopic: \"\u65B0\u3057\u3044\u679D\" },\n zh: { map: \"\u5BFC\u56FE\", outline: \"\u5217\u8868\", addChild: \"\u5B50\u5206\u652F\", addSibling: \"\u540C\u7EA7\u5206\u652F\", edit: \"\u7F16\u8F91\u6587\u5B57\", remove: \"\u5220\u9664\", dirSide: \"\u4E24\u4FA7\u5C55\u5F00\", dirRight: \"\u5411\u53F3\u5C55\u5F00\", dirLeft: \"\u5411\u5DE6\u5C55\u5F00\", center: \"\u5C45\u4E2D\", zoomIn: \"\u653E\u5927\", zoomOut: \"\u7F29\u5C0F\", mapHint: \"\u53CC\u51FB: \u7F16\u8F91 \u00B7 Tab: \u5B50\u5206\u652F \u00B7 Enter: \u540C\u7EA7\u5206\u652F \u00B7 \u62D6\u52A8\u5206\u652F: \u79FB\u52A8 \u00B7 \u62D6\u52A8\u7A7A\u767D: \u5E73\u79FB \u00B7 Ctrl+\u6EDA\u8F6E: \u7F29\u653E\", newTopic: \"\u65B0\u5206\u652F\" },\n de: { map: \"Karte\", outline: \"Liste\", addChild: \"Unterzweig\", addSibling: \"Nebenzweig\", edit: \"Text bearbeiten\", remove: \"L\u00F6schen\", dirSide: \"Beidseitig\", dirRight: \"Nach rechts\", dirLeft: \"Nach links\", center: \"Zentrieren\", zoomIn: \"Vergr\u00F6\u00DFern\", zoomOut: \"Verkleinern\", mapHint: \"Doppelklick: bearbeiten \u00B7 Tab: Unterzweig \u00B7 Enter: Nebenzweig \u00B7 Zweig ziehen: verschieben \u00B7 Leere Fl\u00E4che ziehen: schwenken \u00B7 Strg+Rad: Zoom\", newTopic: \"Neuer Zweig\" },\n fr: { map: \"Carte\", outline: \"Liste\", addChild: \"Branche enfant\", addSibling: \"Branche s\u0153ur\", edit: \"Modifier le texte\", remove: \"Supprimer\", dirSide: \"Des deux c\u00F4t\u00E9s\", dirRight: \"Vers la droite\", dirLeft: \"Vers la gauche\", center: \"Centrer\", zoomIn: \"Zoomer\", zoomOut: \"D\u00E9zoomer\", mapHint: \"Double-clic : modifier \u00B7 Tab : enfant \u00B7 Entr\u00E9e : s\u0153ur \u00B7 Glisser une branche : d\u00E9placer \u00B7 Glisser le vide : d\u00E9filer \u00B7 Ctrl+molette : zoom\", newTopic: \"Nouvelle branche\" },\n it: { map: \"Mappa\", outline: \"Elenco\", addChild: \"Ramo figlio\", addSibling: \"Ramo fratello\", edit: \"Modifica testo\", remove: \"Elimina\", dirSide: \"Su entrambi i lati\", dirRight: \"Verso destra\", dirLeft: \"Verso sinistra\", center: \"Centra\", zoomIn: \"Ingrandisci\", zoomOut: \"Riduci\", mapHint: \"Doppio clic: modifica \u00B7 Tab: figlio \u00B7 Invio: fratello \u00B7 Trascina un ramo: sposta \u00B7 Trascina il vuoto: scorri \u00B7 Ctrl+rotella: zoom\", newTopic: \"Nuovo ramo\" },\n vi: { map: \"B\u1EA3n \u0111\u1ED3\", outline: \"Danh s\u00E1ch\", addChild: \"Nh\u00E1nh con\", addSibling: \"Nh\u00E1nh ngang\", edit: \"S\u1EEDa ch\u1EEF\", remove: \"X\u00F3a\", dirSide: \"M\u1EDF hai b\u00EAn\", dirRight: \"M\u1EDF sang ph\u1EA3i\", dirLeft: \"M\u1EDF sang tr\u00E1i\", center: \"V\u1EC1 gi\u1EEFa\", zoomIn: \"Ph\u00F3ng to\", zoomOut: \"Thu nh\u1ECF\", mapHint: \"Nh\u1EA5p \u0111\u00FAp: s\u1EEDa \u00B7 Tab: nh\u00E1nh con \u00B7 Enter: nh\u00E1nh ngang \u00B7 K\u00E9o nh\u00E1nh: di chuy\u1EC3n \u00B7 K\u00E9o ch\u1ED7 tr\u1ED1ng: cu\u1ED9n \u00B7 Ctrl+cu\u1ED9n: ph\u00F3ng to\", newTopic: \"Nh\u00E1nh m\u1EDBi\" },\n} as const;\n\nexport type MindMapStrings = OutlinerStrings & { [K in keyof (typeof STRINGS)[\"en\"]]: string };\n\nexport function mindMapStrings(locale?: string, overrides?: Partial<MindMapStrings>): MindMapStrings {\n const lang = (locale ?? \"en\").slice(0, 2).toLowerCase() as keyof typeof STRINGS;\n return { ...outlinerStrings(locale), ...(STRINGS[lang] ?? STRINGS.en), ...overrides };\n}\n", "/**\n * Standalone SVG of the map (for saving a picture next to the data). Built from the layout, not the DOM,\n * so it works while the map is hidden and looks the same in an <img>.\n */\nimport { DEFAULT_FONT_FAMILY } from \"@ehfuse/outliner\";\nimport { edgePath, layoutMap, nodeLook, type MapDirection } from \"./layout\";\nimport type { MindMapData } from \"./types\";\n\nconst esc = (text: string) => text.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\").replace(/\"/g, \""\");\n\nexport function exportMindMapSvg(data: MindMapData, options: { padding?: number; background?: string } = {}): string {\n const padding = options.padding ?? 24;\n const layout = layoutMap(data.nodeData, (data.direction ?? 2) as MapDirection);\n const { minX, minY, maxX, maxY } = layout.bounds;\n const width = Math.ceil(maxX - minX + padding * 2);\n const height = Math.ceil(maxY - minY + padding * 2);\n const ox = padding - minX;\n const oy = padding - minY;\n const parts: string[] = [];\n parts.push(`<rect width=\"${width}\" height=\"${height}\" fill=\"${options.background ?? \"#ffffff\"}\"/>`);\n parts.push(`<g transform=\"translate(${ox} ${oy})\">`);\n for (const edge of layout.edges) parts.push(`<path d=\"${edgePath(edge)}\" fill=\"none\" stroke=\"${edge.color}\" stroke-width=\"${edge.to.depth === 1 ? 2.5 : 1.75}\" stroke-linecap=\"round\"/>`);\n for (const ln of layout.nodes) {\n const look = nodeLook(ln);\n parts.push(\n `<rect x=\"${ln.x}\" y=\"${ln.y}\" width=\"${ln.w}\" height=\"${ln.h}\" rx=\"${look.radius}\" fill=\"${look.fill}\"${look.stroke !== \"none\" ? ` stroke=\"${look.stroke}\" stroke-width=\"${look.strokeWidth}\"` : \"\"}/>`\n );\n const deco = ln.node.style?.textDecoration;\n parts.push(\n `<text x=\"${ln.x + ln.w / 2}\" y=\"${ln.y + ln.h / 2}\" text-anchor=\"middle\" dominant-baseline=\"central\" font-family=\"${esc(DEFAULT_FONT_FAMILY)}\" font-size=\"${ln.fontSize}\" font-weight=\"${ln.fontWeight}\" fill=\"${look.text}\"${deco ? ` text-decoration=\"${esc(deco)}\"` : \"\"}>${esc(ln.node.topic)}</text>`\n );\n if (ln.node.expanded === false && (ln.node.children?.length ?? 0) > 0 && ln.depth > 0) {\n const cx = ln.side > 0 ? ln.x + ln.w + 10 : ln.x - 10;\n const cy = ln.y + ln.h / 2;\n parts.push(`<circle cx=\"${cx}\" cy=\"${cy}\" r=\"9\" fill=\"#ffffff\" stroke=\"${ln.color}\" stroke-width=\"1.5\"/>`);\n parts.push(`<text x=\"${cx}\" y=\"${cy}\" text-anchor=\"middle\" dominant-baseline=\"central\" font-family=\"${esc(DEFAULT_FONT_FAMILY)}\" font-size=\"10\" fill=\"${ln.color}\">${ln.node.children!.length}</text>`);\n }\n }\n parts.push(\"</g>\");\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\">${parts.join(\"\")}</svg>`;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["index_exports", "__export", "BRANCH_COLORS", "MapView", "MindMap", "edgePath", "exportMindMapSvg", "layoutMap", "mindMapStrings", "nodeLook", "nodeSize", "__toCommonJS", "import_react", "import_material", "
|
|
4
|
+
"sourcesContent": ["export { MindMap, type MindMapProps, type MindMapHandle } from \"./MindMap\";\nexport { MapView, type MapViewProps, type MapViewHandle } from \"./MapView\";\nexport { exportMindMapSvg } from \"./exportSvg\";\nexport { layoutMap, edgePath, nodeLook, nodeSize, BRANCH_COLORS, type MapDirection, type LayoutNode, type LayoutEdge, type MapLayout } from \"./layout\";\nexport { mindMapStrings, type MindMapStrings } from \"./i18n\";\nexport type { MindMapData, MindMapView } from \"./types\";\nexport { createTree, type TreeNode, type TreeNodeStyle } from \"@ehfuse/outliner\";\n", "/**\n * MindMap \u2014 one tree shown as a map or as a list (outline), with one formatting toolbar for both.\n * Controlled: pass `value` and `onChange`. Undo history lives inside (map and list share it).\n */\nimport { forwardRef, useImperativeHandle, useRef, useState, type ReactNode } from \"react\";\nimport { Box, ButtonBase } from \"@mui/material\";\nimport { BranchBothIcon, BranchLeftIcon, BranchRightIcon, FitCenterIcon, ZoomInIcon, ZoomOutIcon } from \"@ehfuse/toolbar-icons\";\nimport { FormatToolbar, OutlineList, ToolButton, ToolDivider, locateNode, setNodeStyle, useTreeHistory, type TreeNode } from \"@ehfuse/outliner\";\nimport { MapView, type MapViewHandle } from \"./MapView\";\nimport { mindMapStrings, type MindMapStrings } from \"./i18n\";\nimport type { MapDirection } from \"./layout\";\nimport type { MindMapData, MindMapView } from \"./types\";\nimport { exportMindMapSvg } from \"./exportSvg\";\n\nexport interface MindMapProps {\n value: MindMapData;\n onChange: (value: MindMapData) => void;\n locale?: string;\n strings?: Partial<MindMapStrings>;\n readOnly?: boolean;\n /** Controlled view; or use `defaultView`. */\n view?: MindMapView;\n defaultView?: MindMapView;\n onViewChange?: (view: MindMapView) => void;\n /** Extra controls at the right end of the toolbar. */\n toolbarEnd?: ReactNode;\n /** Show the one-line help at the bottom (default true). */\n hint?: boolean;\n height?: number | string;\n}\n\nexport interface MindMapHandle {\n exportSvg: () => string;\n center: () => void;\n}\n\nconst DIRECTIONS: Array<{ value: MapDirection; key: \"dirSide\" | \"dirRight\" | \"dirLeft\"; icon: ReactNode }> = [\n { value: 2, key: \"dirSide\", icon: <BranchBothIcon /> },\n { value: 1, key: \"dirRight\", icon: <BranchRightIcon /> },\n { value: 0, key: \"dirLeft\", icon: <BranchLeftIcon /> },\n];\n\nexport const MindMap = forwardRef<MindMapHandle, MindMapProps>(function MindMap(\n { value, onChange, locale, strings: overrides, readOnly, view: viewProp, defaultView = \"map\", onViewChange, toolbarEnd, hint = true, height = \"100%\" },\n ref\n) {\n const strings = mindMapStrings(locale, overrides);\n const [ownView, setOwnView] = useState<MindMapView>(defaultView);\n const view = viewProp ?? ownView;\n const setView = (next: MindMapView) => {\n setOwnView(next);\n onViewChange?.(next);\n if (next === \"map\") requestAnimationFrame(() => mapRef.current?.center());\n };\n const [selected, setSelected] = useState<string | null>(null);\n const history = useTreeHistory();\n const mapRef = useRef<MapViewHandle | null>(null);\n const root = value.nodeData;\n const direction = (value.direction ?? 2) as MapDirection;\n\n const commit = (next: TreeNode, mergeKey?: string) => {\n history.record(root, mergeKey);\n onChange({ ...value, nodeData: next });\n };\n const undo = () => {\n const prev = history.undo(root);\n if (prev) onChange({ ...value, nodeData: prev });\n };\n const redo = () => {\n const next = history.redo(root);\n if (next) onChange({ ...value, nodeData: next });\n };\n useImperativeHandle(ref, () => ({ exportSvg: () => exportMindMapSvg(value), center: () => mapRef.current?.center() }), [value]);\n\n const selectedNode = selected ? locateNode(root, selected)?.node : undefined;\n const viewSwitch = (\n <Box sx={{ display: \"flex\", p: 0.25, borderRadius: 1, bgcolor: \"#f1f3f4\" }}>\n {([\"map\", \"outline\"] as const).map((item) => (\n <ButtonBase\n key={item}\n aria-pressed={view === item}\n onClick={() => setView(item)}\n sx={{\n height: 26,\n px: 1.25,\n borderRadius: 0.75,\n fontSize: 13,\n fontWeight: view === item ? 600 : 400,\n color: view === item ? \"primary.main\" : \"text.secondary\",\n bgcolor: view === item ? \"#fff\" : \"transparent\",\n boxShadow: view === item ? \"0 1px 2px rgba(0,0,0,0.15)\" : \"none\",\n }}\n >\n {item === \"map\" ? strings.map : strings.outline}\n </ButtonBase>\n ))}\n </Box>\n );\n\n return (\n <Box sx={{ display: \"flex\", flexDirection: \"column\", height, minHeight: 0, bgcolor: \"#fff\" }}>\n <FormatToolbar\n strings={strings}\n style={selectedNode ? (selectedNode.style ?? {}) : undefined}\n onStyle={(patch) => {\n if (!selected) return;\n const result = setNodeStyle(root, [selected], patch);\n if (result) commit(result.root);\n }}\n canUndo={history.canUndo}\n canRedo={history.canRedo}\n onUndo={undo}\n onRedo={redo}\n start={viewSwitch}\n end={toolbarEnd}\n readOnly={readOnly}\n >\n {view === \"map\" ? (\n <>\n {DIRECTIONS.map((item) => (\n <ToolButton key={item.value} label={strings[item.key]} active={direction === item.value} disabled={readOnly} onClick={() => onChange({ ...value, direction: item.value })}>\n {item.icon}\n </ToolButton>\n ))}\n <ToolDivider />\n <ToolButton label={strings.zoomOut} onClick={() => mapRef.current?.zoomBy(1 / 1.2)}>\n <ZoomOutIcon />\n </ToolButton>\n <ToolButton label={strings.zoomIn} onClick={() => mapRef.current?.zoomBy(1.2)}>\n <ZoomInIcon />\n </ToolButton>\n <ToolButton label={strings.center} onClick={() => mapRef.current?.center()}>\n <FitCenterIcon />\n </ToolButton>\n </>\n ) : null}\n </FormatToolbar>\n <Box sx={{ position: \"relative\", flex: 1, minHeight: 0 }}>\n {view === \"map\" ? (\n <MapView ref={mapRef} root={root} direction={direction} onEdit={commit} selectedId={selected} onSelect={setSelected} strings={strings} readOnly={readOnly} onUndo={undo} onRedo={redo} hint={hint} />\n ) : (\n <>\n <OutlineList root={root} onEdit={commit} selectedId={selected} onSelect={setSelected} strings={strings} readOnly={readOnly} onUndo={undo} onRedo={redo} />\n {hint ? (\n <Box sx={{ position: \"absolute\", left: 12, right: 12, bottom: 8, fontSize: 12, lineHeight: 1.5, color: \"text.secondary\", pointerEvents: \"none\" }}>\n <Box component=\"span\" sx={{ bgcolor: \"rgba(255,255,255,0.9)\" }}>\n {strings.hint}\n </Box>\n </Box>\n ) : null}\n </>\n )}\n </Box>\n </Box>\n );\n});\n", "/**\n * Map view \u2014 draws the tree as a mind map and edits it in place.\n *\n * Mouse: click to select \u00B7 double-click to edit \u00B7 drag a branch onto another (middle = into it, top / bottom edge = before / after)\n * \u00B7 drag empty space to pan \u00B7 Ctrl/\u2318 + wheel to zoom (a plain wheel scrolls the page, not the map).\n * Keys (map focused): Tab child \u00B7 Enter sibling \u00B7 F2 edit \u00B7 Delete / Backspace remove \u00B7 Space fold \u00B7 arrows move the selection \u00B7\n * Ctrl/\u2318+Z undo \u00B7 Ctrl/\u2318+Shift+Z / Ctrl+Y redo.\n */\nimport { forwardRef, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, type KeyboardEvent, type PointerEvent } from \"react\";\nimport { Box } from \"@mui/material\";\nimport { ChildBranchIcon, PencilIcon, SiblingBranchIcon, TrashIcon } from \"@ehfuse/toolbar-icons\";\nimport {\n DEFAULT_FONT_FAMILY,\n ToolButton,\n addChild,\n addSibling,\n containsNode,\n locateNode,\n measureText,\n moveNode,\n removeNode,\n setTopic,\n toggleFold,\n type TreeEdit,\n type TreeNode,\n} from \"@ehfuse/outliner\";\nimport { edgePath, layoutMap, nodeLook, type LayoutNode, type MapDirection } from \"./layout\";\nimport type { MindMapStrings } from \"./i18n\";\n\nexport interface MapViewHandle {\n center: () => void;\n zoomBy: (factor: number) => void;\n}\n\nexport interface MapViewProps {\n root: TreeNode;\n direction: MapDirection;\n onEdit: (root: TreeNode, mergeKey?: string) => void;\n selectedId: string | null;\n onSelect: (id: string | null) => void;\n strings: MindMapStrings;\n readOnly?: boolean;\n onUndo?: () => void;\n onRedo?: () => void;\n /** Show the one-line help at the bottom (default true). */\n hint?: boolean;\n}\n\nconst ZOOM_MIN = 0.3;\nconst ZOOM_MAX = 2.5;\nconst DRAG_START = 5;\n\ntype DropPlace = \"before\" | \"after\" | \"child\";\n\nexport const MapView = forwardRef<MapViewHandle, MapViewProps>(function MapView({ root, direction, onEdit, selectedId, onSelect, strings, readOnly, onUndo, onRedo, hint = true }, ref) {\n const boxRef = useRef<HTMLDivElement | null>(null);\n const [size, setSize] = useState({ w: 0, h: 0 });\n const [view, setView] = useState({ x: 0, y: 0, z: 1 });\n const viewRef = useRef(view);\n viewRef.current = view;\n const [editing, setEditing] = useState<{ id: string; text: string } | null>(null);\n const [drag, setDrag] = useState<{ id: string; px: number; py: number; target: { id: string; place: DropPlace } | null } | null>(null);\n const pointer = useRef<{ kind: \"pan\" | \"node\"; id?: string; sx: number; sy: number; vx: number; vy: number; moved: boolean } | null>(null);\n const layout = useMemo(() => layoutMap(root, direction), [root, direction]);\n\n // Size \u2014 center the map the first time the box has a size.\n const centered = useRef(false);\n useLayoutEffect(() => {\n const el = boxRef.current;\n if (!el) return;\n const ro = new ResizeObserver(() => setSize({ w: el.clientWidth, h: el.clientHeight }));\n ro.observe(el);\n setSize({ w: el.clientWidth, h: el.clientHeight });\n return () => ro.disconnect();\n }, []);\n const center = useCallback(() => {\n const { minX, minY, maxX, maxY } = layout.bounds;\n const z = viewRef.current.z;\n setView({ x: size.w / 2 - ((minX + maxX) / 2) * z, y: size.h / 2 - ((minY + maxY) / 2) * z, z });\n }, [layout, size]);\n useEffect(() => {\n if (centered.current || size.w === 0) return;\n centered.current = true;\n center();\n }, [size, center]);\n const zoomAt = useCallback((factor: number, cx: number, cy: number) => {\n setView((v) => {\n const z = Math.min(ZOOM_MAX, Math.max(ZOOM_MIN, v.z * factor));\n return { x: cx - (cx - v.x) * (z / v.z), y: cy - (cy - v.y) * (z / v.z), z };\n });\n }, []);\n useImperativeHandle(ref, () => ({ center, zoomBy: (factor) => zoomAt(factor, size.w / 2, size.h / 2) }), [center, zoomAt, size]);\n\n // Ctrl/\u2318 + wheel zooms at the cursor; a plain wheel is left to the page (it must not pan the map).\n useEffect(() => {\n const el = boxRef.current;\n if (!el) return;\n const onWheel = (event: WheelEvent) => {\n if (!(event.ctrlKey || event.metaKey)) return;\n event.preventDefault();\n const r = el.getBoundingClientRect();\n zoomAt(event.deltaY < 0 ? 1.1 : 1 / 1.1, event.clientX - r.left, event.clientY - r.top);\n };\n el.addEventListener(\"wheel\", onWheel, { passive: false });\n return () => el.removeEventListener(\"wheel\", onWheel);\n }, [zoomAt]);\n\n const apply = (result: TreeEdit | null, mergeKey?: string, editNew = false) => {\n if (!result) return;\n onEdit(result.root, mergeKey);\n if (result.focusId) {\n onSelect(result.focusId);\n if (editNew) setEditing({ id: result.focusId, text: \"\" });\n }\n };\n const startEdit = (id: string) => {\n if (readOnly) return;\n const at = locateNode(root, id);\n if (at) setEditing({ id, text: at.node.topic });\n };\n const commitEdit = () => {\n if (!editing) return;\n apply(setTopic(root, editing.id, editing.text));\n setEditing(null);\n boxRef.current?.focus({ preventScroll: true });\n };\n\n const toCanvas = (clientX: number, clientY: number) => {\n const r = boxRef.current!.getBoundingClientRect();\n return { x: (clientX - r.left - view.x) / view.z, y: (clientY - r.top - view.y) / view.z };\n };\n const dropAt = (clientX: number, clientY: number, dragged: TreeNode): { id: string; place: DropPlace } | null => {\n const p = toCanvas(clientX, clientY);\n for (const ln of layout.nodes) {\n if (p.x < ln.x - 4 || p.x > ln.x + ln.w + 4 || p.y < ln.y - 4 || p.y > ln.y + ln.h + 4) continue;\n if (containsNode(dragged, ln.id)) return null;\n if (ln.depth === 0) return { id: ln.id, place: \"child\" };\n const rel = (p.y - ln.y) / ln.h;\n return { id: ln.id, place: rel < 0.25 ? \"before\" : rel > 0.75 ? \"after\" : \"child\" };\n }\n return null;\n };\n\n const onPointerDown = (event: PointerEvent<HTMLDivElement>) => {\n if (event.button !== 0) return;\n const target = event.target as HTMLElement;\n if (target.closest(\"[data-mm-ui]\")) return;\n if (editing && !target.closest(\"[data-mm-edit]\")) commitEdit();\n if (target.closest(\"[data-mm-edit]\")) return;\n const fold = target.closest(\"[data-mm-fold]\") as HTMLElement | null;\n if (fold) {\n apply(toggleFold(root, fold.dataset.mmFold!));\n return;\n }\n const nodeEl = target.closest(\"[data-mm-node]\") as HTMLElement | null;\n boxRef.current?.focus({ preventScroll: true });\n // Capture the pointer only once a drag starts \u2014 capturing on press retargets the double-click to the box, so editing never opened.\n if (nodeEl) {\n const id = nodeEl.dataset.mmNode!;\n onSelect(id);\n pointer.current = { kind: \"node\", id, sx: event.clientX, sy: event.clientY, vx: view.x, vy: view.y, moved: false };\n } else {\n onSelect(null);\n pointer.current = { kind: \"pan\", sx: event.clientX, sy: event.clientY, vx: view.x, vy: view.y, moved: false };\n }\n };\n const onPointerMove = (event: PointerEvent<HTMLDivElement>) => {\n const p = pointer.current;\n if (!p) return;\n const dx = event.clientX - p.sx;\n const dy = event.clientY - p.sy;\n if (!p.moved && Math.hypot(dx, dy) < DRAG_START) return;\n if (!p.moved && !boxRef.current?.hasPointerCapture(event.pointerId)) boxRef.current?.setPointerCapture(event.pointerId);\n p.moved = true;\n if (p.kind === \"pan\") {\n setView((v) => ({ ...v, x: p.vx + dx, y: p.vy + dy }));\n return;\n }\n if (readOnly || p.id === root.id) return;\n const dragged = locateNode(root, p.id!)?.node;\n if (!dragged) return;\n const r = boxRef.current!.getBoundingClientRect();\n setDrag({ id: p.id!, px: event.clientX - r.left, py: event.clientY - r.top, target: dropAt(event.clientX, event.clientY, dragged) });\n };\n const onPointerUp = (event: PointerEvent<HTMLDivElement>) => {\n const p = pointer.current;\n pointer.current = null;\n if (boxRef.current?.hasPointerCapture(event.pointerId)) boxRef.current.releasePointerCapture(event.pointerId);\n if (p?.kind === \"node\" && drag?.target) apply(moveNode(root, drag.id, drag.target.id, drag.target.place));\n setDrag(null);\n };\n\n const neighbor = (ln: LayoutNode, key: string): string | null => {\n const at = locateNode(root, ln.id);\n if (!at) return null;\n if (key === \"ArrowUp\" || key === \"ArrowDown\") {\n if (!at.parent) return null;\n const sibs = (at.parent.children ?? []).filter((kid) => layout.byId.get(kid.id)?.side === ln.side);\n const i = sibs.findIndex((kid) => kid.id === ln.id);\n return sibs[i + (key === \"ArrowUp\" ? -1 : 1)]?.id ?? null;\n }\n const outward = (key === \"ArrowRight\" && ln.side >= 0) || (key === \"ArrowLeft\" && ln.side <= 0);\n if (outward) {\n const kids = at.node.expanded === false ? [] : (at.node.children ?? []);\n const want = ln.side === 0 ? (key === \"ArrowRight\" ? 1 : -1) : ln.side;\n return kids.find((kid) => layout.byId.get(kid.id)?.side === want)?.id ?? null;\n }\n return ln.parentId;\n };\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (editing || (event.target as HTMLElement).tagName === \"INPUT\") return;\n const mod = event.ctrlKey || event.metaKey;\n if (mod && (event.key === \"z\" || event.key === \"Z\")) {\n event.preventDefault();\n if (event.shiftKey) onRedo?.();\n else onUndo?.();\n return;\n }\n if (mod && (event.key === \"y\" || event.key === \"Y\")) {\n event.preventDefault();\n onRedo?.();\n return;\n }\n const ln = selectedId ? layout.byId.get(selectedId) : null;\n if (!ln) return;\n if (event.key.startsWith(\"Arrow\")) {\n const next = neighbor(ln, event.key);\n event.preventDefault();\n if (next) onSelect(next);\n return;\n }\n if (readOnly) return;\n if (event.key === \"Tab\") {\n event.preventDefault();\n apply(addChild(root, ln.id), undefined, true);\n } else if (event.key === \"Enter\") {\n event.preventDefault();\n apply(addSibling(root, ln.id), undefined, true);\n } else if (event.key === \"F2\") {\n event.preventDefault();\n startEdit(ln.id);\n } else if (event.key === \"Delete\" || event.key === \"Backspace\") {\n event.preventDefault();\n apply(removeNode(root, ln.id));\n } else if (event.key === \" \") {\n event.preventDefault();\n apply(toggleFold(root, ln.id));\n }\n };\n\n const selected = selectedId ? layout.byId.get(selectedId) : undefined;\n const editingLN = editing ? layout.byId.get(editing.id) : undefined;\n const dragLN = drag ? layout.byId.get(drag.id) : undefined;\n const dropLN = drag?.target ? layout.byId.get(drag.target.id) : undefined;\n const barButton = (key: string, label: string, icon: React.ReactNode, onClick: () => void) => (\n <ToolButton key={key} label={label} onClick={onClick}>\n {icon}\n </ToolButton>\n );\n\n return (\n <Box\n ref={boxRef}\n tabIndex={0}\n onKeyDown={onKeyDown}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerUp}\n onDoubleClick={(event) => {\n const nodeEl = (event.target as HTMLElement).closest(\"[data-mm-node]\") as HTMLElement | null;\n if (nodeEl) startEdit(nodeEl.dataset.mmNode!);\n }}\n sx={{ position: \"relative\", width: \"100%\", height: \"100%\", overflow: \"hidden\", bgcolor: \"#f7f8fa\", outline: \"none\", touchAction: \"none\", userSelect: \"none\", cursor: pointer.current?.kind === \"pan\" ? \"grabbing\" : \"default\" }}\n >\n <Box sx={{ position: \"absolute\", left: 0, top: 0, transform: `translate(${view.x}px, ${view.y}px) scale(${view.z})`, transformOrigin: \"0 0\" }}>\n <svg style={{ position: \"absolute\", left: 0, top: 0, width: 1, height: 1, overflow: \"visible\" }}>\n {layout.edges.map((edge) => (\n <path key={edge.to.id} d={edgePath(edge)} fill=\"none\" stroke={edge.color} strokeWidth={edge.to.depth === 1 ? 2.5 : 1.75} strokeLinecap=\"round\" />\n ))}\n </svg>\n {layout.nodes.map((ln) => {\n const look = nodeLook(ln);\n const kids = ln.node.children?.length ?? 0;\n const folded = ln.node.expanded === false && kids > 0;\n const isSel = ln.id === selectedId;\n return (\n <Box\n key={ln.id}\n data-mm-node={ln.id}\n sx={{\n position: \"absolute\",\n left: ln.x,\n top: ln.y,\n width: ln.w,\n height: ln.h,\n boxSizing: \"border-box\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: `${look.radius}px`,\n bgcolor: look.fill,\n border: look.stroke !== \"none\" ? `${look.strokeWidth}px solid ${look.stroke}` : 0,\n color: look.text,\n fontFamily: DEFAULT_FONT_FAMILY,\n fontSize: ln.fontSize,\n fontWeight: ln.fontWeight,\n textDecoration: ln.node.style?.textDecoration,\n whiteSpace: \"nowrap\",\n cursor: readOnly ? \"default\" : \"pointer\",\n boxShadow: isSel ? \"0 0 0 2px #fff, 0 0 0 4px #1a73e8\" : ln.depth === 0 ? \"0 2px 6px rgba(0,0,0,0.18)\" : \"none\",\n opacity: drag?.id === ln.id ? 0.35 : 1,\n \"&:hover .mm-fold\": { opacity: 1 },\n }}\n >\n {editing?.id === ln.id ? null : ln.node.topic || \"\u00A0\"}\n {kids > 0 && ln.depth > 0 ? (\n <Box\n className=\"mm-fold\"\n data-mm-fold={ln.id}\n title={folded ? strings.unfold : strings.fold}\n sx={{\n position: \"absolute\",\n top: \"50%\",\n [ln.side > 0 ? \"left\" : \"right\"]: \"100%\",\n transform: `translate(${ln.side > 0 ? 4 : -4}px, -50%)`,\n minWidth: 18,\n height: 18,\n px: folded ? 0.5 : 0,\n boxSizing: \"border-box\",\n borderRadius: 9,\n bgcolor: \"#fff\",\n border: `1.5px solid ${ln.color}`,\n color: ln.color,\n fontSize: 11,\n fontWeight: 600,\n lineHeight: \"15px\",\n textAlign: \"center\",\n cursor: \"pointer\",\n opacity: folded || isSel ? 1 : 0,\n textDecoration: \"none\",\n }}\n >\n {folded ? kids : \"\u2212\"}\n </Box>\n ) : null}\n </Box>\n );\n })}\n {/* Drop target \u2014 into (outline) or before / after (line). */}\n {dropLN && drag?.target ? (\n drag.target.place === \"child\" ? (\n <Box sx={{ position: \"absolute\", left: dropLN.x - 4, top: dropLN.y - 4, width: dropLN.w + 8, height: dropLN.h + 8, border: \"2px dashed #1a73e8\", borderRadius: 2, pointerEvents: \"none\" }} />\n ) : (\n <Box sx={{ position: \"absolute\", left: dropLN.x, top: drag.target.place === \"before\" ? dropLN.y - 6 : dropLN.y + dropLN.h + 4, width: dropLN.w, height: 3, borderRadius: 2, bgcolor: \"#1a73e8\", pointerEvents: \"none\" }} />\n )\n ) : null}\n {editingLN && editing ? (\n <input\n data-mm-edit=\"\"\n autoFocus\n value={editing.text}\n spellCheck={false}\n onFocus={(event) => event.currentTarget.select()}\n onChange={(event) => setEditing({ id: editing.id, text: event.target.value })}\n onBlur={commitEdit}\n onKeyDown={(event) => {\n event.stopPropagation();\n if (event.nativeEvent.isComposing) return;\n if (event.key === \"Enter\") {\n event.preventDefault();\n commitEdit();\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n setEditing(null);\n boxRef.current?.focus({ preventScroll: true });\n } else if (event.key === \"Tab\") {\n event.preventDefault();\n const id = editing.id;\n const text = editing.text;\n setEditing(null);\n const named = setTopic(root, id, text);\n apply(addChild(named?.root ?? root, id), undefined, true);\n }\n }}\n style={{\n position: \"absolute\",\n left: editingLN.x,\n top: editingLN.y,\n width: Math.max(editingLN.w, Math.ceil(measureText(editing.text || \" \", editingLN.fontSize, editingLN.fontWeight)) + 40),\n height: editingLN.h,\n boxSizing: \"border-box\",\n padding: \"0 12px\",\n border: \"2px solid #1a73e8\",\n borderRadius: 8,\n outline: \"none\",\n textAlign: \"center\",\n fontFamily: DEFAULT_FONT_FAMILY,\n fontSize: editingLN.fontSize,\n fontWeight: editingLN.fontWeight,\n color: \"#1f2328\",\n background: \"#fff\",\n zIndex: 5,\n }}\n />\n ) : null}\n </Box>\n {/* Dragged branch follows the pointer. */}\n {drag && dragLN ? (\n <Box sx={{ position: \"absolute\", left: drag.px + 10, top: drag.py + 10, px: 1.5, py: 0.5, borderRadius: 2, bgcolor: \"#fff\", border: `1.5px solid ${dragLN.color}`, fontSize: 13, opacity: 0.9, pointerEvents: \"none\", boxShadow: \"0 4px 12px rgba(0,0,0,0.15)\" }}>\n {dragLN.node.topic || \"\u00A0\"}\n </Box>\n ) : null}\n {/* Buttons above the selected branch \u2014 growing the map without knowing the keys. */}\n {selected && !editing && !drag && !readOnly ? (\n <Box\n data-mm-ui=\"\"\n sx={{\n position: \"absolute\",\n left: view.x + (selected.x + selected.w / 2) * view.z,\n top: view.y + selected.y * view.z,\n transform: \"translate(-50%, calc(-100% - 8px))\",\n display: \"flex\",\n gap: 0.25,\n p: 0.25,\n bgcolor: \"#fff\",\n border: \"1px solid #e0e0e0\",\n borderRadius: 1,\n boxShadow: \"0 2px 6px rgba(0,0,0,0.12)\",\n zIndex: 6,\n }}\n >\n {barButton(\"child\", strings.addChild, <ChildBranchIcon />, () => apply(addChild(root, selected.id), undefined, true))}\n {selected.depth > 0 ? barButton(\"sibling\", strings.addSibling, <SiblingBranchIcon />, () => apply(addSibling(root, selected.id), undefined, true)) : null}\n {barButton(\"edit\", strings.edit, <PencilIcon />, () => startEdit(selected.id))}\n {selected.depth > 0 ? barButton(\"delete\", strings.remove, <TrashIcon />, () => apply(removeNode(root, selected.id))) : null}\n </Box>\n ) : null}\n {hint ? (\n <Box sx={{ position: \"absolute\", left: 12, right: 12, bottom: 8, fontSize: 12, lineHeight: 1.5, color: \"text.secondary\", pointerEvents: \"none\" }}>\n <Box component=\"span\" sx={{ bgcolor: \"rgba(247,248,250,0.85)\" }}>\n {strings.mapHint}\n </Box>\n </Box>\n ) : null}\n </Box>\n );\n});\n", "/**\n * Map layout \u2014 root in the middle, branches to the right / left / both sides.\n * Node sizes come from measured text (no DOM pass), so layout is a pure function of the data.\n */\nimport { measureText, type TreeNode } from \"@ehfuse/outliner\";\n\n/** 0 = left, 1 = right, 2 = both sides (same values as Mind Elixir). */\nexport type MapDirection = 0 | 1 | 2;\n\nexport interface LayoutNode {\n id: string;\n node: TreeNode;\n depth: number;\n x: number;\n y: number;\n w: number;\n h: number;\n /** 1 = grows to the right, -1 = to the left, 0 = root. */\n side: 1 | -1 | 0;\n color: string;\n parentId: string | null;\n fontSize: number;\n fontWeight: string;\n}\n\nexport interface LayoutEdge {\n from: LayoutNode;\n to: LayoutNode;\n color: string;\n}\n\nexport interface MapLayout {\n nodes: LayoutNode[];\n byId: Map<string, LayoutNode>;\n edges: LayoutEdge[];\n bounds: { minX: number; minY: number; maxX: number; maxY: number };\n}\n\nexport const BRANCH_COLORS = [\"#e8710a\", \"#1a73e8\", \"#188038\", \"#d93025\", \"#9334e6\", \"#f9ab00\", \"#12b5cb\", \"#c2185b\"];\nconst H_GAP_ROOT = 64;\nconst H_GAP = 40;\nconst V_GAP = 14;\n\n/** Default text size / weight by depth (a node's own style wins). */\nexport function nodeFont(node: TreeNode, depth: number) {\n const fontSize = node.style?.fontSize ? parseFloat(node.style.fontSize) : depth === 0 ? 22 : depth === 1 ? 16 : 14;\n const fontWeight = node.style?.fontWeight ?? (depth === 0 ? \"700\" : depth === 1 ? \"500\" : \"400\");\n return { fontSize, fontWeight };\n}\n\nexport function nodeSize(node: TreeNode, depth: number) {\n const { fontSize, fontWeight } = nodeFont(node, depth);\n const padX = depth === 0 ? 28 : depth === 1 ? 16 : 12;\n const padY = depth === 0 ? 14 : depth === 1 ? 8 : 6;\n const textW = measureText(node.topic || \" \", fontSize, fontWeight);\n return {\n w: Math.max(depth === 0 ? 100 : 48, Math.ceil(textW) + padX * 2),\n h: Math.ceil(fontSize * 1.4) + padY * 2,\n fontSize,\n fontWeight,\n };\n}\n\nconst visibleKids = (node: TreeNode) => (node.expanded === false ? [] : (node.children ?? []));\n\nexport function layoutMap(root: TreeNode, direction: MapDirection = 2): MapLayout {\n const heights = new Map<string, number>();\n const subtree = (node: TreeNode, depth: number): number => {\n const own = nodeSize(node, depth).h;\n const kids = visibleKids(node);\n const sum = kids.reduce((acc, kid) => acc + subtree(kid, depth + 1), 0) + V_GAP * Math.max(0, kids.length - 1);\n const value = Math.max(own, sum);\n heights.set(node.id, value);\n return value;\n };\n\n const nodes: LayoutNode[] = [];\n const edges: LayoutEdge[] = [];\n const rootSize = nodeSize(root, 0);\n const rootLN: LayoutNode = { id: root.id, node: root, depth: 0, x: -rootSize.w / 2, y: -rootSize.h / 2, w: rootSize.w, h: rootSize.h, side: 0, color: \"#3b3f5c\", parentId: null, fontSize: rootSize.fontSize, fontWeight: rootSize.fontWeight };\n nodes.push(rootLN);\n\n const place = (parent: LayoutNode, kids: TreeNode[], side: 1 | -1, depth: number, colorOf: (kid: TreeNode, i: number) => string) => {\n kids.forEach((kid) => subtree(kid, depth));\n const total = kids.reduce((acc, kid) => acc + (heights.get(kid.id) ?? 0), 0) + V_GAP * Math.max(0, kids.length - 1);\n let top = parent.y + parent.h / 2 - total / 2;\n const gap = depth === 1 ? H_GAP_ROOT : H_GAP;\n kids.forEach((kid, i) => {\n const sh = heights.get(kid.id) ?? 0;\n const size = nodeSize(kid, depth);\n const cy = top + sh / 2;\n const x = side > 0 ? parent.x + parent.w + gap : parent.x - gap - size.w;\n const color = colorOf(kid, i);\n const ln: LayoutNode = { id: kid.id, node: kid, depth, x, y: cy - size.h / 2, w: size.w, h: size.h, side, color, parentId: parent.id, fontSize: size.fontSize, fontWeight: size.fontWeight };\n nodes.push(ln);\n edges.push({ from: parent, to: ln, color });\n place(ln, visibleKids(kid), side, depth + 1, () => color);\n top += sh + V_GAP;\n });\n };\n\n const kids = visibleKids(root);\n const all = root.children ?? [];\n const colorFor = (kid: TreeNode) => BRANCH_COLORS[Math.max(0, all.indexOf(kid)) % BRANCH_COLORS.length];\n const sideOf = (kid: TreeNode, i: number): 1 | -1 => {\n if (direction === 0) return -1;\n if (direction === 1) return 1;\n if (kid.direction === 0) return -1;\n if (kid.direction === 1) return 1;\n // Both sides: first half right, second half left (keeps reading order top-down on each side).\n return i < Math.ceil(kids.length / 2) ? 1 : -1;\n };\n const right = kids.filter((kid, i) => sideOf(kid, i) === 1);\n const left = kids.filter((kid, i) => sideOf(kid, i) === -1);\n place(rootLN, right, 1, 1, colorFor);\n place(rootLN, left, -1, 1, colorFor);\n\n const bounds = { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity };\n for (const n of nodes) {\n bounds.minX = Math.min(bounds.minX, n.x);\n bounds.minY = Math.min(bounds.minY, n.y);\n bounds.maxX = Math.max(bounds.maxX, n.x + n.w);\n bounds.maxY = Math.max(bounds.maxY, n.y + n.h);\n }\n return { nodes, byId: new Map(nodes.map((n) => [n.id, n])), edges, bounds };\n}\n\n/** Curved connector from the parent's side to the child's near side. */\nexport function edgePath(edge: LayoutEdge): string {\n const { from, to } = edge;\n const side = to.side >= 0 ? 1 : -1;\n const x1 = from.depth === 0 ? from.x + from.w / 2 + (side * from.w) / 2 - side * 12 : side > 0 ? from.x + from.w : from.x;\n const y1 = from.y + from.h / 2;\n const x2 = side > 0 ? to.x : to.x + to.w;\n const y2 = to.y + to.h / 2;\n const dx = (x2 - x1) * 0.5;\n return `M ${x1} ${y1} C ${x1 + dx} ${y1}, ${x2 - dx} ${y2}, ${x2} ${y2}`;\n}\n\n/** Visual look of a node (fill \u00B7 border \u00B7 text color \u00B7 radius) \u2014 shared by the map and the SVG export. */\nexport function nodeLook(ln: LayoutNode) {\n const style = ln.node.style ?? {};\n if (ln.depth === 0) return { fill: style.background ?? \"#3b3f5c\", stroke: \"none\", strokeWidth: 0, text: style.color ?? \"#ffffff\", radius: ln.h / 2 };\n if (ln.depth === 1) return { fill: style.background ?? \"#ffffff\", stroke: ln.color, strokeWidth: 2, text: style.color ?? \"#1f2328\", radius: ln.h / 2 };\n return { fill: style.background ?? \"#ffffff\", stroke: \"#d0d4da\", strokeWidth: 1, text: style.color ?? \"#1f2328\", radius: 8 };\n}\n", "import { outlinerStrings, type OutlinerStrings } from \"@ehfuse/outliner\";\n\n/** Map-only strings (the formatting / outline strings come from @ehfuse/outliner). */\nconst STRINGS = {\n ko: { map: \"\uC9C0\uB3C4\", outline: \"\uBAA9\uB85D\", addChild: \"\uC544\uB798 \uAC00\uC9C0\", addSibling: \"\uC606 \uAC00\uC9C0\", edit: \"\uAE00 \uACE0\uCE58\uAE30\", remove: \"\uC9C0\uC6B0\uAE30\", dirSide: \"\uC591\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30\", dirRight: \"\uC624\uB978\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30\", dirLeft: \"\uC67C\uCABD\uC73C\uB85C \uD3BC\uCE58\uAE30\", center: \"\uAC00\uC6B4\uB370\uB85C\", zoomIn: \"\uD655\uB300\", zoomOut: \"\uCD95\uC18C\", mapHint: \"\uB450 \uBC88 \uD074\uB9AD: \uAE00 \uACE0\uCE58\uAE30 \u00B7 Tab: \uC544\uB798 \uAC00\uC9C0 \u00B7 Enter: \uC606 \uAC00\uC9C0 \u00B7 \uAC00\uC9C0 \uB04C\uAE30: \uC62E\uAE30\uAE30 \u00B7 \uBE48 \uACF3 \uB04C\uAE30: \uC774\uB3D9 \u00B7 Ctrl+\uD720: \uD655\uB300\", newTopic: \"\uC0C8 \uAC00\uC9C0\" },\n en: { map: \"Map\", outline: \"List\", addChild: \"Child branch\", addSibling: \"Sibling branch\", edit: \"Edit text\", remove: \"Delete\", dirSide: \"Grow both ways\", dirRight: \"Grow to the right\", dirLeft: \"Grow to the left\", center: \"Center\", zoomIn: \"Zoom in\", zoomOut: \"Zoom out\", mapHint: \"Double-click: edit \u00B7 Tab: child \u00B7 Enter: sibling \u00B7 Drag a branch: move \u00B7 Drag empty space: pan \u00B7 Ctrl+wheel: zoom\", newTopic: \"New branch\" },\n ja: { map: \"\u30DE\u30C3\u30D7\", outline: \"\u30EA\u30B9\u30C8\", addChild: \"\u4E0B\u306E\u679D\", addSibling: \"\u6A2A\u306E\u679D\", edit: \"\u6587\u5B57\u3092\u7DE8\u96C6\", remove: \"\u524A\u9664\", dirSide: \"\u4E21\u5074\u306B\u5E83\u3052\u308B\", dirRight: \"\u53F3\u306B\u5E83\u3052\u308B\", dirLeft: \"\u5DE6\u306B\u5E83\u3052\u308B\", center: \"\u4E2D\u592E\u3078\", zoomIn: \"\u62E1\u5927\", zoomOut: \"\u7E2E\u5C0F\", mapHint: \"\u30C0\u30D6\u30EB\u30AF\u30EA\u30C3\u30AF: \u7DE8\u96C6 \u00B7 Tab: \u4E0B\u306E\u679D \u00B7 Enter: \u6A2A\u306E\u679D \u00B7 \u679D\u3092\u30C9\u30E9\u30C3\u30B0: \u79FB\u52D5 \u00B7 \u7A7A\u767D\u30C9\u30E9\u30C3\u30B0: \u30B9\u30AF\u30ED\u30FC\u30EB \u00B7 Ctrl+\u30DB\u30A4\u30FC\u30EB: \u62E1\u5927\", newTopic: \"\u65B0\u3057\u3044\u679D\" },\n zh: { map: \"\u5BFC\u56FE\", outline: \"\u5217\u8868\", addChild: \"\u5B50\u5206\u652F\", addSibling: \"\u540C\u7EA7\u5206\u652F\", edit: \"\u7F16\u8F91\u6587\u5B57\", remove: \"\u5220\u9664\", dirSide: \"\u4E24\u4FA7\u5C55\u5F00\", dirRight: \"\u5411\u53F3\u5C55\u5F00\", dirLeft: \"\u5411\u5DE6\u5C55\u5F00\", center: \"\u5C45\u4E2D\", zoomIn: \"\u653E\u5927\", zoomOut: \"\u7F29\u5C0F\", mapHint: \"\u53CC\u51FB: \u7F16\u8F91 \u00B7 Tab: \u5B50\u5206\u652F \u00B7 Enter: \u540C\u7EA7\u5206\u652F \u00B7 \u62D6\u52A8\u5206\u652F: \u79FB\u52A8 \u00B7 \u62D6\u52A8\u7A7A\u767D: \u5E73\u79FB \u00B7 Ctrl+\u6EDA\u8F6E: \u7F29\u653E\", newTopic: \"\u65B0\u5206\u652F\" },\n de: { map: \"Karte\", outline: \"Liste\", addChild: \"Unterzweig\", addSibling: \"Nebenzweig\", edit: \"Text bearbeiten\", remove: \"L\u00F6schen\", dirSide: \"Beidseitig\", dirRight: \"Nach rechts\", dirLeft: \"Nach links\", center: \"Zentrieren\", zoomIn: \"Vergr\u00F6\u00DFern\", zoomOut: \"Verkleinern\", mapHint: \"Doppelklick: bearbeiten \u00B7 Tab: Unterzweig \u00B7 Enter: Nebenzweig \u00B7 Zweig ziehen: verschieben \u00B7 Leere Fl\u00E4che ziehen: schwenken \u00B7 Strg+Rad: Zoom\", newTopic: \"Neuer Zweig\" },\n fr: { map: \"Carte\", outline: \"Liste\", addChild: \"Branche enfant\", addSibling: \"Branche s\u0153ur\", edit: \"Modifier le texte\", remove: \"Supprimer\", dirSide: \"Des deux c\u00F4t\u00E9s\", dirRight: \"Vers la droite\", dirLeft: \"Vers la gauche\", center: \"Centrer\", zoomIn: \"Zoomer\", zoomOut: \"D\u00E9zoomer\", mapHint: \"Double-clic : modifier \u00B7 Tab : enfant \u00B7 Entr\u00E9e : s\u0153ur \u00B7 Glisser une branche : d\u00E9placer \u00B7 Glisser le vide : d\u00E9filer \u00B7 Ctrl+molette : zoom\", newTopic: \"Nouvelle branche\" },\n it: { map: \"Mappa\", outline: \"Elenco\", addChild: \"Ramo figlio\", addSibling: \"Ramo fratello\", edit: \"Modifica testo\", remove: \"Elimina\", dirSide: \"Su entrambi i lati\", dirRight: \"Verso destra\", dirLeft: \"Verso sinistra\", center: \"Centra\", zoomIn: \"Ingrandisci\", zoomOut: \"Riduci\", mapHint: \"Doppio clic: modifica \u00B7 Tab: figlio \u00B7 Invio: fratello \u00B7 Trascina un ramo: sposta \u00B7 Trascina il vuoto: scorri \u00B7 Ctrl+rotella: zoom\", newTopic: \"Nuovo ramo\" },\n vi: { map: \"B\u1EA3n \u0111\u1ED3\", outline: \"Danh s\u00E1ch\", addChild: \"Nh\u00E1nh con\", addSibling: \"Nh\u00E1nh ngang\", edit: \"S\u1EEDa ch\u1EEF\", remove: \"X\u00F3a\", dirSide: \"M\u1EDF hai b\u00EAn\", dirRight: \"M\u1EDF sang ph\u1EA3i\", dirLeft: \"M\u1EDF sang tr\u00E1i\", center: \"V\u1EC1 gi\u1EEFa\", zoomIn: \"Ph\u00F3ng to\", zoomOut: \"Thu nh\u1ECF\", mapHint: \"Nh\u1EA5p \u0111\u00FAp: s\u1EEDa \u00B7 Tab: nh\u00E1nh con \u00B7 Enter: nh\u00E1nh ngang \u00B7 K\u00E9o nh\u00E1nh: di chuy\u1EC3n \u00B7 K\u00E9o ch\u1ED7 tr\u1ED1ng: cu\u1ED9n \u00B7 Ctrl+cu\u1ED9n: ph\u00F3ng to\", newTopic: \"Nh\u00E1nh m\u1EDBi\" },\n} as const;\n\nexport type MindMapStrings = OutlinerStrings & { [K in keyof (typeof STRINGS)[\"en\"]]: string };\n\nexport function mindMapStrings(locale?: string, overrides?: Partial<MindMapStrings>): MindMapStrings {\n const lang = (locale ?? \"en\").slice(0, 2).toLowerCase() as keyof typeof STRINGS;\n return { ...outlinerStrings(locale), ...(STRINGS[lang] ?? STRINGS.en), ...overrides };\n}\n", "/**\n * Standalone SVG of the map (for saving a picture next to the data). Built from the layout, not the DOM,\n * so it works while the map is hidden and looks the same in an <img>.\n */\nimport { DEFAULT_FONT_FAMILY } from \"@ehfuse/outliner\";\nimport { edgePath, layoutMap, nodeLook, type MapDirection } from \"./layout\";\nimport type { MindMapData } from \"./types\";\n\nconst esc = (text: string) => text.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\").replace(/\"/g, \""\");\n\nexport function exportMindMapSvg(data: MindMapData, options: { padding?: number; background?: string } = {}): string {\n const padding = options.padding ?? 24;\n const layout = layoutMap(data.nodeData, (data.direction ?? 2) as MapDirection);\n const { minX, minY, maxX, maxY } = layout.bounds;\n const width = Math.ceil(maxX - minX + padding * 2);\n const height = Math.ceil(maxY - minY + padding * 2);\n const ox = padding - minX;\n const oy = padding - minY;\n const parts: string[] = [];\n parts.push(`<rect width=\"${width}\" height=\"${height}\" fill=\"${options.background ?? \"#ffffff\"}\"/>`);\n parts.push(`<g transform=\"translate(${ox} ${oy})\">`);\n for (const edge of layout.edges) parts.push(`<path d=\"${edgePath(edge)}\" fill=\"none\" stroke=\"${edge.color}\" stroke-width=\"${edge.to.depth === 1 ? 2.5 : 1.75}\" stroke-linecap=\"round\"/>`);\n for (const ln of layout.nodes) {\n const look = nodeLook(ln);\n parts.push(\n `<rect x=\"${ln.x}\" y=\"${ln.y}\" width=\"${ln.w}\" height=\"${ln.h}\" rx=\"${look.radius}\" fill=\"${look.fill}\"${look.stroke !== \"none\" ? ` stroke=\"${look.stroke}\" stroke-width=\"${look.strokeWidth}\"` : \"\"}/>`\n );\n const deco = ln.node.style?.textDecoration;\n parts.push(\n `<text x=\"${ln.x + ln.w / 2}\" y=\"${ln.y + ln.h / 2}\" text-anchor=\"middle\" dominant-baseline=\"central\" font-family=\"${esc(DEFAULT_FONT_FAMILY)}\" font-size=\"${ln.fontSize}\" font-weight=\"${ln.fontWeight}\" fill=\"${look.text}\"${deco ? ` text-decoration=\"${esc(deco)}\"` : \"\"}>${esc(ln.node.topic)}</text>`\n );\n if (ln.node.expanded === false && (ln.node.children?.length ?? 0) > 0 && ln.depth > 0) {\n const cx = ln.side > 0 ? ln.x + ln.w + 10 : ln.x - 10;\n const cy = ln.y + ln.h / 2;\n parts.push(`<circle cx=\"${cx}\" cy=\"${cy}\" r=\"9\" fill=\"#ffffff\" stroke=\"${ln.color}\" stroke-width=\"1.5\"/>`);\n parts.push(`<text x=\"${cx}\" y=\"${cy}\" text-anchor=\"middle\" dominant-baseline=\"central\" font-family=\"${esc(DEFAULT_FONT_FAMILY)}\" font-size=\"10\" fill=\"${ln.color}\">${ln.node.children!.length}</text>`);\n }\n }\n parts.push(\"</g>\");\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\">${parts.join(\"\")}</svg>`;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["index_exports", "__export", "BRANCH_COLORS", "MapView", "MindMap", "edgePath", "exportMindMapSvg", "layoutMap", "mindMapStrings", "nodeLook", "nodeSize", "__toCommonJS", "import_react", "import_material", "import_toolbar_icons", "import_outliner", "import_react", "import_material", "import_toolbar_icons", "import_outliner", "import_outliner", "BRANCH_COLORS", "H_GAP_ROOT", "H_GAP", "V_GAP", "nodeFont", "node", "depth", "fontSize", "fontWeight", "nodeSize", "padX", "padY", "textW", "visibleKids", "layoutMap", "root", "direction", "heights", "subtree", "own", "kids", "sum", "acc", "kid", "value", "nodes", "edges", "rootSize", "rootLN", "place", "parent", "side", "colorOf", "total", "top", "gap", "i", "sh", "size", "cy", "x", "color", "ln", "all", "colorFor", "sideOf", "right", "left", "bounds", "n", "edgePath", "edge", "from", "to", "x1", "y1", "x2", "y2", "dx", "nodeLook", "style", "import_jsx_runtime", "ZOOM_MIN", "ZOOM_MAX", "DRAG_START", "MapView", "root", "direction", "onEdit", "selectedId", "onSelect", "strings", "readOnly", "onUndo", "onRedo", "hint", "ref", "boxRef", "size", "setSize", "view", "setView", "viewRef", "editing", "setEditing", "drag", "setDrag", "pointer", "layout", "layoutMap", "centered", "el", "ro", "center", "minX", "minY", "maxX", "maxY", "z", "zoomAt", "factor", "cx", "cy", "v", "onWheel", "event", "r", "apply", "result", "mergeKey", "editNew", "startEdit", "id", "at", "commitEdit", "toCanvas", "clientX", "clientY", "dropAt", "dragged", "p", "ln", "rel", "onPointerDown", "target", "fold", "nodeEl", "onPointerMove", "dx", "dy", "onPointerUp", "neighbor", "key", "sibs", "kid", "i", "kids", "want", "onKeyDown", "mod", "next", "selected", "editingLN", "dragLN", "dropLN", "barButton", "label", "icon", "onClick", "edge", "edgePath", "look", "nodeLook", "folded", "isSel", "text", "named", "import_outliner", "STRINGS", "mindMapStrings", "locale", "overrides", "lang", "import_outliner", "esc", "text", "exportMindMapSvg", "data", "options", "padding", "layout", "layoutMap", "minX", "minY", "maxX", "maxY", "width", "height", "ox", "oy", "parts", "edge", "edgePath", "ln", "look", "nodeLook", "deco", "cx", "cy", "import_jsx_runtime", "DIRECTIONS", "MindMap", "value", "onChange", "locale", "overrides", "readOnly", "viewProp", "defaultView", "onViewChange", "toolbarEnd", "hint", "height", "ref", "strings", "mindMapStrings", "ownView", "setOwnView", "view", "setView", "next", "mapRef", "selected", "setSelected", "history", "root", "direction", "commit", "mergeKey", "undo", "prev", "redo", "exportMindMapSvg", "selectedNode", "viewSwitch", "item", "patch", "result", "MapView", "import_outliner"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ehfuse/mindmap",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Mind map for React + MUI — map and outline views of one tree, formatting toolbar, drag to move, undo, SVG export",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"typescript": "^5.6.3"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"@ehfuse/outliner": "^0.
|
|
65
|
+
"@ehfuse/outliner": "^0.2.0",
|
|
66
|
+
"@ehfuse/toolbar-icons": "^0.1.0"
|
|
66
67
|
}
|
|
67
68
|
}
|