flow-mindmap 0.1.0-beta.1
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/LICENSE +201 -0
- package/README.md +288 -0
- package/dist/components/DataPanel.vue.d.ts +10 -0
- package/dist/components/Drawer.vue.d.ts +33 -0
- package/dist/components/Icon.vue.d.ts +7 -0
- package/dist/components/MarkdownPanel.vue.d.ts +12 -0
- package/dist/components/MindMap.vue.d.ts +60 -0
- package/dist/components/NodeContextMenu.vue.d.ts +46 -0
- package/dist/components/NotePanel.vue.d.ts +20 -0
- package/dist/components/Outline.vue.d.ts +45 -0
- package/dist/components/SettingsPanel.vue.d.ts +30 -0
- package/dist/composables/useHistory.d.ts +19 -0
- package/dist/composables/useKeyboard.d.ts +32 -0
- package/dist/composables/usePanZoom.d.ts +35 -0
- package/dist/core/layout.d.ts +98 -0
- package/dist/core/palettes.d.ts +43 -0
- package/dist/entry.d.ts +11 -0
- package/dist/flow-mindmap.js +1849 -0
- package/dist/flow-mindmap.umd.cjs +1 -0
- package/dist/style.css +1 -0
- package/dist/tree.d.ts +68 -0
- package/dist/types.d.ts +215 -0
- package/package.json +70 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(D,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(D=typeof globalThis<"u"?globalThis:D||self,e(D.FlowMind={},D.Vue))})(this,function(D,e){"use strict";const It=["width","height","stroke-width"],Wt={key:4,points:"6 9 12 15 18 9"},$t={key:5,points:"9 6 15 12 9 18"},z=e.defineComponent({__name:"Icon",props:{name:{},size:{},stroke:{}},setup(o){return(u,l)=>(e.openBlock(),e.createElementBlock("svg",{width:o.size??16,height:o.size??16,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":o.stroke??1.8,"stroke-linecap":"round","stroke-linejoin":"round","aria-hidden":"true"},[o.name==="add"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[l[0]||(l[0]=e.createElementVNode("circle",{cx:"12",cy:"12",r:"9"},null,-1)),l[1]||(l[1]=e.createElementVNode("line",{x1:"12",y1:"8",x2:"12",y2:"16"},null,-1)),l[2]||(l[2]=e.createElementVNode("line",{x1:"8",y1:"12",x2:"16",y2:"12"},null,-1))],64)):o.name==="minus"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[l[3]||(l[3]=e.createElementVNode("circle",{cx:"12",cy:"12",r:"9"},null,-1)),l[4]||(l[4]=e.createElementVNode("line",{x1:"8",y1:"12",x2:"16",y2:"12"},null,-1))],64)):o.name==="delete"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:2},[l[5]||(l[5]=e.createStaticVNode('<polyline points="4 7 20 7"></polyline><path d="M9 7 V5 a1 1 0 0 1 1 -1 h4 a1 1 0 0 1 1 1 V7"></path><path d="M6 7 l1 12 a1 1 0 0 0 1 1 h8 a1 1 0 0 0 1 -1 l1 -12"></path><line x1="10" y1="11" x2="10" y2="18"></line><line x1="14" y1="11" x2="14" y2="18"></line>',5))],64)):o.name==="edit"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:3},[l[6]||(l[6]=e.createElementVNode("path",{d:"M4 20 l4 -1 11 -11 -3 -3 -11 11 z"},null,-1)),l[7]||(l[7]=e.createElementVNode("line",{x1:"14",y1:"6",x2:"18",y2:"10"},null,-1))],64)):o.name==="collapse"?(e.openBlock(),e.createElementBlock("polyline",Wt)):o.name==="expand"?(e.openBlock(),e.createElementBlock("polyline",$t)):o.name==="zoom-in"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:6},[l[8]||(l[8]=e.createElementVNode("circle",{cx:"11",cy:"11",r:"7"},null,-1)),l[9]||(l[9]=e.createElementVNode("line",{x1:"11",y1:"8",x2:"11",y2:"14"},null,-1)),l[10]||(l[10]=e.createElementVNode("line",{x1:"8",y1:"11",x2:"14",y2:"11"},null,-1)),l[11]||(l[11]=e.createElementVNode("line",{x1:"16",y1:"16",x2:"21",y2:"21"},null,-1))],64)):o.name==="zoom-out"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:7},[l[12]||(l[12]=e.createElementVNode("circle",{cx:"11",cy:"11",r:"7"},null,-1)),l[13]||(l[13]=e.createElementVNode("line",{x1:"8",y1:"11",x2:"14",y2:"11"},null,-1)),l[14]||(l[14]=e.createElementVNode("line",{x1:"16",y1:"16",x2:"21",y2:"21"},null,-1))],64)):o.name==="reset"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:8},[l[15]||(l[15]=e.createElementVNode("circle",{cx:"12",cy:"12",r:"9"},null,-1)),l[16]||(l[16]=e.createElementVNode("circle",{cx:"12",cy:"12",r:"4"},null,-1)),l[17]||(l[17]=e.createElementVNode("circle",{cx:"12",cy:"12",r:"0.8",fill:"currentColor"},null,-1))],64)):o.name==="logo"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:9},[l[18]||(l[18]=e.createStaticVNode('<circle cx="12" cy="12" r="2.2"></circle><circle cx="4" cy="5" r="1.6"></circle><circle cx="20" cy="5" r="1.6"></circle><circle cx="4" cy="19" r="1.6"></circle><circle cx="20" cy="19" r="1.6"></circle><line x1="10.5" y1="10.8" x2="5.2" y2="6.4"></line><line x1="13.5" y1="10.8" x2="18.8" y2="6.4"></line><line x1="10.5" y1="13.2" x2="5.2" y2="17.6"></line><line x1="13.5" y1="13.2" x2="18.8" y2="17.6"></line>',9))],64)):o.name==="import"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:10},[l[19]||(l[19]=e.createElementVNode("path",{d:"M12 4 V15"},null,-1)),l[20]||(l[20]=e.createElementVNode("polyline",{points:"7 10 12 15 17 10"},null,-1)),l[21]||(l[21]=e.createElementVNode("path",{d:"M4 19 H20"},null,-1))],64)):o.name==="export"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:11},[l[22]||(l[22]=e.createElementVNode("path",{d:"M12 15 V4"},null,-1)),l[23]||(l[23]=e.createElementVNode("polyline",{points:"7 9 12 4 17 9"},null,-1)),l[24]||(l[24]=e.createElementVNode("path",{d:"M4 19 H20"},null,-1))],64)):o.name==="balance"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:12},[l[25]||(l[25]=e.createStaticVNode('<line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="18" x2="21" y2="18"></line><polyline points="9 4 5 6 9 8"></polyline><polyline points="15 4 19 6 15 8"></polyline><polyline points="9 10 5 12 9 14"></polyline><polyline points="15 10 19 12 15 14"></polyline><polyline points="9 16 5 18 9 20"></polyline><polyline points="15 16 19 18 15 20"></polyline>',9))],64)):o.name==="mindmap"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:13},[l[26]||(l[26]=e.createStaticVNode('<circle cx="12" cy="12" r="2.2" fill="currentColor" stroke="none"></circle><line x1="13" y1="11" x2="19" y2="6"></line><line x1="13" y1="13" x2="19" y2="18"></line><line x1="11" y1="11" x2="5" y2="6"></line><line x1="11" y1="13" x2="5" y2="18"></line>',5))],64)):o.name==="tree"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:14},[l[27]||(l[27]=e.createStaticVNode('<circle cx="6" cy="12" r="2" fill="currentColor" stroke="none"></circle><circle cx="18" cy="6" r="2" fill="currentColor" stroke="none"></circle><circle cx="18" cy="12" r="2" fill="currentColor" stroke="none"></circle><circle cx="18" cy="18" r="2" fill="currentColor" stroke="none"></circle><line x1="8" y1="12" x2="16" y2="6"></line><line x1="8" y1="12" x2="16" y2="12"></line><line x1="8" y1="12" x2="16" y2="18"></line>',7))],64)):o.name==="org"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:15},[l[28]||(l[28]=e.createStaticVNode('<circle cx="12" cy="5" r="2" fill="currentColor" stroke="none"></circle><circle cx="6" cy="19" r="2" fill="currentColor" stroke="none"></circle><circle cx="12" cy="19" r="2" fill="currentColor" stroke="none"></circle><circle cx="18" cy="19" r="2" fill="currentColor" stroke="none"></circle><line x1="12" y1="7" x2="12" y2="13"></line><line x1="6" y1="13" x2="18" y2="13"></line><line x1="6" y1="13" x2="6" y2="17"></line><line x1="12" y1="13" x2="12" y2="17"></line><line x1="18" y1="13" x2="18" y2="17"></line>',9))],64)):o.name==="image"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:16},[l[29]||(l[29]=e.createElementVNode("rect",{x:"3",y:"5",width:"18",height:"14",rx:"2"},null,-1)),l[30]||(l[30]=e.createElementVNode("circle",{cx:"9",cy:"11",r:"1.6"},null,-1)),l[31]||(l[31]=e.createElementVNode("polyline",{points:"3 17 9 12 13 15 16 13 21 17"},null,-1))],64)):o.name==="x"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:17},[l[32]||(l[32]=e.createElementVNode("line",{x1:"6",y1:"6",x2:"18",y2:"18"},null,-1)),l[33]||(l[33]=e.createElementVNode("line",{x1:"18",y1:"6",x2:"6",y2:"18"},null,-1))],64)):o.name==="link"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:18},[l[34]||(l[34]=e.createElementVNode("path",{d:"M10 13 a4 4 0 0 0 5.66 0 l3 -3 a4 4 0 1 0 -5.66 -5.66 l-1 1"},null,-1)),l[35]||(l[35]=e.createElementVNode("path",{d:"M14 11 a4 4 0 0 0 -5.66 0 l-3 3 a4 4 0 1 0 5.66 5.66 l1 -1"},null,-1))],64)):o.name==="note"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:19},[l[36]||(l[36]=e.createElementVNode("path",{d:"M6 4 h9 l3 3 v13 a1 1 0 0 1 -1 1 h-11 a1 1 0 0 1 -1 -1 v-15 a1 1 0 0 1 1 -1 z"},null,-1)),l[37]||(l[37]=e.createElementVNode("line",{x1:"8",y1:"10",x2:"16",y2:"10"},null,-1)),l[38]||(l[38]=e.createElementVNode("line",{x1:"8",y1:"13",x2:"16",y2:"13"},null,-1)),l[39]||(l[39]=e.createElementVNode("line",{x1:"8",y1:"16",x2:"13",y2:"16"},null,-1))],64)):e.createCommentVNode("",!0)],8,It))}}),Rt="data:image/svg+xml,%3csvg%20t='1780822312364'%20class='icon'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='7459'%20width='200'%20height='200'%3e%3cpath%20d='M329.16%20292.571h658.286V512H329.16zM329.16%200h658.286v219.429H329.16z'%20fill='%239AA1A2'%20p-id='7460'%3e%3c/path%3e%3cpath%20d='M44.927%20146.286a46.519%2046.519%200%200%201%2038.107-73.143h319.269v73.143H109.73V791.99l-48.713%205.705-24.43-651.41h8.339z'%20fill='%239AA1A2'%20p-id='7461'%3e%3c/path%3e%3cpath%20d='M363.83%20877.714H179.51c-78.775%200-142.921-66.12-142.921-147.31V112.787c0-21.943%2017.188-39.643%2038.473-39.643%2021.211%200%2033.5%2017.774%2033.5%2039.643v617.619c0%2037.522%2028.013%2076.58%2064.438%2076.58h190.903c21.211%200%2038.766%2013.97%2038.766%2035.84%200%2021.943-17.555%2034.89-38.766%2034.89z'%20fill='%239AA1A2'%20p-id='7462'%3e%3c/path%3e%3cpath%20d='M432.95%20438.857H179.51c-78.775%200-81.043-18.578-81.043-62.903l10.094-90.624c0%2020.48%2013.458%2080.677%2049.884%2080.677h210.139c21.211%200%20120.613%204.023%20120.613%2016.018%200%2011.922-35.036%2056.832-56.32%2056.832zM640.017%20749.714V640a54.857%2054.857%200%200%201%20109.714%200v109.714h109.715a54.857%2054.857%200%200%201%200%20109.715H749.73v109.714a54.857%2054.857%200%200%201-109.714%200V859.429H530.303a54.857%2054.857%200%200%201%200-109.715h109.714z'%20fill='%239AA1A2'%20p-id='7463'%3e%3c/path%3e%3c/svg%3e",Dt="data:image/svg+xml,%3csvg%20t='1780822464335'%20class='icon'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='8457'%20width='200'%20height='200'%3e%3cpath%20d='M512%20804.571h512V1024H512V804.571zM0%200h658.286v219.429H0V0z'%20fill='%239AA1A2'%20p-id='8458'%3e%3c/path%3e%3cpath%20d='M619.813%20950.857h-184.32c-78.775%200-142.922-66.121-142.922-147.31V185.93c0-21.943%2017.189-39.643%2038.474-39.643%2021.211%200%2033.353%2017.773%2033.353%2039.643v617.618c0%2037.523%2034.743%2073.728%2071.095%2073.728h184.32c21.211%200%2038.473%2012.069%2038.473%2033.939%200%2021.943-17.189%2039.643-38.473%2039.643z'%20fill='%239AA1A2'%20p-id='8459'%3e%3c/path%3e%3cpath%20d='M676.571%20457.143V347.429a54.857%2054.857%200%200%201%20109.715%200v109.714H896a54.857%2054.857%200%200%201%200%20109.714H786.286v109.714a54.857%2054.857%200%200%201-109.715%200V566.857H566.857a54.857%2054.857%200%200%201%200-109.714h109.714z'%20fill='%239AA1A2'%20p-id='8460'%3e%3c/path%3e%3c/svg%3e",Me=[18,15,13,12],Lt=[700,600,500,400],At=[52,40,32,28],je=[120,80,60,44],Ht=[.8,.8,.8,.8],Pt=Me.length-1;function Tt(o){return Math.round(Me[Be(o)]*Ht[Be(o)])}function Be(o){return Math.min(Pt,Math.max(0,o))}function Ft(o){return Me[Be(o)]}const Ce=60,le=14,F=24;let Ae=null;function Ot(){if(Ae)return Ae;const o=typeof document<"u"?document.createElement("canvas").getContext("2d"):null;return o?(Ae=o,o):{font:"",measureText:()=>({width:0})}}const Ge=new Map;function qt(o,u,l){const i=`${l}|${u}|${o}`,c=Ge.get(i);if(c!==void 0)return c;const d=Ot();d.font=`${l} ${u}px "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif`;const m=d.measureText(o).width;return Ge.set(i,m),m}const Xt=24,Kt=400,Ut=8,Je=16,Yt=4;function jt(o,u,l){return Math.min(l,Math.max(u,o))}function Gt(o,u){const l=Be(u),i=qt(o.text||"",Me[l],Lt[l]),c=Tt(u),d=Math.ceil(i+c*2),m=At[l];let p=0;if(o.link&&(p+=Je),o.note&&(p+=Je),p>0){const v=(o.link?1:0)+(o.note?1:0);p+=Yt*v}const g=d+p;if(!o.image)return{w:Math.max(je[l],g),h:m};const x=jt(o.image.width,Xt,Kt),s=Math.max(je[l],g,Math.ceil(x+c*2)),w=Math.ceil(o.image.height+Ut+m);return{w:s,h:w}}function Jt(o,u={}){const l=u.mode??"mindmap",i=u.preservePositions===!0,c=Qe(o,0,null,1,"right");return Qt(c),Zt(c,l,i),c.x=0,c.y=0,_t(c,i)}function Zt(o,u,l=!1){if(u==="mindmap"){const i=o.children;if(i.length!==0)if(i.length===1)i[0]._dir="right",i[0].side=1,i[0]._dirRight=1;else{const p=i.reduce((w,v)=>w+v._subtreeH,0);let g=1,x=Math.abs(i[0]._subtreeH-(p-i[0]._subtreeH)),s=0;for(let w=0;w<i.length-1;w++){s+=i[w]._subtreeH;const v=Math.abs(s-(p-s));v<x&&(x=v,g=w+1)}for(let w=0;w<g;w++)i[w]._dir="right",i[w].side=1,i[w]._dirRight=1;for(let w=g;w<i.length;w++)i[w]._dir="left",i[w].side=-1,i[w]._dirRight=-1}const c=o.children.filter(p=>p.side===1),d=o.children.filter(p=>p.side===-1),m=(p,g)=>{const x=g==="right"?1:-1;p._dir=g,p.side=x,p._dirRight=x;for(const s of p.children)m(s,g)};for(const p of c)m(p,"right");for(const p of d)m(p,"left");if(c.length>0){const p={...o,children:c};ve(p,"right",Ce,!0,l)}if(d.length>0){const p={...o,children:d};ve(p,"left",Ce,!0,l)}}else if(u==="tree"){const i=c=>{c.side=1,c._dir="right";for(const d of c.children)i(d)};for(const c of o.children)c._dir="right";ve(o,"right",Ce,!0,l),i(o)}else{for(const i of o.children)i._dir="down";Ze(o,Ce,l)}}function ve(o,u,l,i,c=!1){if(o.children.length===0)return;const d=o.children.reduce((x,s,w)=>x+s._subtreeH+(w>0?le:0),0),m=u==="right"?1:-1,p=i?m:1;let g=o.y-p*d/2;o.children.forEach(x=>{c||(x.x=o.x+m*(o.width/2+l+x.width/2),x.y=g+p*x._subtreeH/2),x._dir=u,g+=p*(x._subtreeH+le),ve(x,u,l,!1,c)})}function Ze(o,u,l=!1){if(o.children.length===0)return;const i=o.children.reduce((d,m,p)=>d+m._subtreeW+(p>0?le*2:0),0);let c=o.x-i/2;o.children.forEach(d=>{l||(d.x=c+d._subtreeW/2,d.y=o.y+o.height/2+u+d.height/2),d._dir="down",c+=d._subtreeW+le*2,Ze(d,u,l)})}function Qe(o,u,l,i,c){const d=Gt(o,u),m={id:o.id,text:o.text,depth:u,x:o._x??0,y:o._y??0,width:d.w,height:d.h,fontSize:Ft(u),isRoot:u===0,collapsed:o.collapsed,side:i,_dir:c,_dirRight:i,_subtreeH:d.h,_subtreeW:d.w,image:o.image?{...o.image}:void 0,link:o.link?{url:o.link.url}:void 0,note:o.note?{text:o.note.text}:void 0,children:[],parent:l};if(o.collapsed)return m;const p=o.children.length,g=Math.ceil(p/2);return m.children=o.children.map((x,s)=>{const w=u===0?s<g?1:-1:i;return Qe(x,u+1,m,w,c)}),m}function Qt(o){const u=[o];for(let l=0;l<u.length;l++){const i=u[l];for(const c of i.children)u.push(c)}for(let l=u.length-1;l>=0;l--){const i=u[l];if(i.collapsed||i.children.length===0){i._subtreeH=i.height,i._subtreeW=i.width;continue}let c=0,d=0;for(const m of i.children)c+=m._subtreeH,d+=m._subtreeW;i.children.length>1&&(c+=le*(i.children.length-1),d+=le*2*(i.children.length-1)),i._subtreeH=Math.max(i.height,c),i._subtreeW=Math.max(i.width,d)}}function _t(o,u=!1){const l=[o];let i=1/0,c=-1/0,d=1/0,m=-1/0;for(;l.length;){const x=l.pop(),s=x.width/2,w=x.height/2;x.x-s<i&&(i=x.x-s),x.x+s>c&&(c=x.x+s),x.y-w<d&&(d=x.y-w),x.y+w>m&&(m=x.y+w),l.push(...x.children)}if(u)return{root:o,width:c-i+F*2,height:m-d+F*2,vbX:i-F,vbY:d-F,vbW:c-i+F*2,vbH:m-d+F*2};const p=F-d,g=[o];for(;g.length;){const x=g.pop();x.y+=p,g.push(...x.children)}return d+=p,m+=p,{root:o,width:c-i+F*2,height:m+F,vbX:i-F,vbY:0,vbW:c-i+F*2,vbH:m+F}}const ue=[{id:"default",name:"默认",colors:["#f87171","#fb923c","#fbbf24","#a3e635","#34d399","#22d3ee","#818cf8","#c084fc"]},{id:"classic",name:"经典",colors:["#ef4444","#f59e0b","#10b981","#3b82f6","#6366f1","#8b5cf6","#ec4899","#14b8a6"]},{id:"vivid",name:"活力",colors:["#dc2626","#ea580c","#ca8a04","#16a34a","#0891b2","#2563eb","#7c3aed","#db2777"]},{id:"dev",name:"代码",colors:["#f472b6","#a78bfa","#60a5fa","#38bdf8","#22d3ee","#34d399","#facc15","#fb923c"]},{id:"mint",name:"薄荷",colors:["#5eead4","#67e8f9","#93c5fd","#c4b5fd","#fbcfe8","#fde68a","#a7f3d0","#bae6fd"]}];function en(o,u=[]){return[...ue,...u].find(i=>i.id===o)??ue[0]}function fe(){return"n_"+Math.random().toString(36).slice(2,10)+Date.now().toString(36).slice(-4)}function J(o){return JSON.parse(JSON.stringify(o))}function B(o,u){if(o.id===u)return o;for(const l of o.children){const i=B(l,u);if(i)return i}return null}function O(o,u,l=null){if(o.id===u)return l;for(const i of o.children){const c=O(i,u,o);if(c!==null)return c}return null}function He(o,u){const l=o.children.findIndex(i=>i.id===u);if(l>=0)return o.children.splice(l,1),!0;for(const i of o.children)if(He(i,u))return!0;return!1}function tn(o,u,l){const i=B(o,u);return!i||i.text===l?!1:(i.text=l,!0)}function nn(o,u,l,i){if(!O(o,u)||u===l||B(B(o,u),l))return!1;const c=O(o,u),d=c.children.findIndex(x=>x.id===u);if(d<0)return!1;const[m]=c.children.splice(d,1);if(i==="child"){const x=B(o,l);return x?(x.children.push(m),!0):(c.children.splice(d,0,m),!1)}const p=O(o,l);if(!p)return c.children.splice(d,0,m),!1;let g=p.children.findIndex(x=>x.id===l);return g<0?(c.children.splice(d,0,m),!1):(i==="after"&&(g+=1),p.children.splice(g,0,m),!0)}function _e(o){const u=/^新节点(?:\s+(\d+))?$/;let l=0,i=!1;for(const c of o.children){const d=c.text.match(u);if(d)if(d[1]){const m=parseInt(d[1],10);m>l&&(l=m)}else i=!0}return l===0&&!i?Se:l>0?`新节点 ${l+1}`:"新节点 2"}function et(o,u,l){const i=B(o,u);if(!i)return null;const c={id:fe(),text:l??_e(i),children:[]};return i.children.push(c),c}function tt(o,u,l){const i=O(o,u);if(!i)return null;const c=i.children.findIndex(m=>m.id===u);if(c<0)return null;const d={id:fe(),text:l??_e(i),children:[]};return i.children.splice(c+1,0,d),d}function on(o,u,l){const i=O(o,u);if(!i)return null;const c=i.children.findIndex(m=>m.id===u);if(c<0)return null;const d={id:fe(),text:l,children:[]};return i.children.splice(c,0,d),d}function ln(o,u){const l=O(o,u);if(!l)return null;const i=l.children.findIndex(m=>m.id===u);if(i<0)return null;const c=l.children[i],d=J(c);return nt(d),l.children.splice(i+1,0,d),d}function nt(o){o.id=fe();for(const u of o.children)nt(u)}const Se="新节点";function rn(o){const u=o.minScale??.2,l=o.maxScale??3,i=o.step??1.2,c=e.ref(1),d=e.ref(0),m=e.ref(0),p=e.ref(!1),g=e.reactive({x:0,y:0,ox:0,oy:0}),x=e.ref(!1),s=e.reactive({x:0,y:0}),w=e.reactive({x:0,y:0,width:0,height:0}),v=e.ref(0);let E=null;function I(M){E=M}function K(M){M.preventDefault();const R=o.getContainer();if(!R)return;const L=-M.deltaY*.001,H=Math.min(l,Math.max(u,c.value*(1+L))),q=R.getBoundingClientRect(),X=M.clientX-q.left,re=M.clientY-q.top,ke=(X-d.value)/c.value,Q=(re-m.value)/c.value;c.value=H,d.value=X-ke*H,m.value=re-Q*H}function j(){c.value=Math.min(l,c.value*i)}function Ve(){c.value=Math.max(u,c.value/i)}function G(M){var L;M.target.closest(".zm-node, .zm-toolbar, button, input, textarea")||(p.value=!0,g.x=M.clientX,g.y=M.clientY,g.ox=d.value,g.oy=m.value,window.addEventListener("mousemove",he),window.addEventListener("mouseup",ze),(L=M.preventDefault)==null||L.call(M))}function he(M){p.value&&(d.value=g.ox+(M.clientX-g.x),m.value=g.oy+(M.clientY-g.y))}function ze(){p.value=!1,window.removeEventListener("mousemove",he),window.removeEventListener("mouseup",ze)}function ye(M,R){x.value=!0,s.x=M,s.y=R,w.x=M,w.y=R,w.width=0,w.height=0,v.value++,window.addEventListener("mousemove",pe),window.addEventListener("mouseup",xe)}function ge(M,R){if(!x.value)return;const L=Math.min(s.x,M),H=Math.min(s.y,R),q=Math.max(s.x,M),X=Math.max(s.y,R);w.x=L,w.y=H,w.width=q-L,w.height=X-H,v.value++}function xe(){x.value=!1,window.removeEventListener("mousemove",pe),window.removeEventListener("mouseup",xe),E&&E()}function pe(M){if(!x.value)return;const R=o.getContainer();if(!R)return;const L=R.getBoundingClientRect(),H=(M.clientX-L.left-d.value)/c.value,q=(M.clientY-L.top-m.value)/c.value;ge(H,q)}function $(M,R,L,H=60){const q=o.getContainer();if(!q)return;const X=q.getBoundingClientRect(),re=(X.width-H*2)/M,ke=(X.height-H*2)/R,Q=Math.min(1,Math.max(.3,Math.min(re,ke)));c.value=Q,d.value=X.width/2,m.value=X.height/2-L*Q}return{scale:c,offsetX:d,offsetY:m,isPanning:p,onWheel:K,zoomIn:j,zoomOut:Ve,startPan:G,startMarquee:ye,updateMarquee:ge,isMarquee:x,marquee:w,marqueeVersion:v,setOnMarqueeEnd:I,resetView:$}}const an=typeof navigator<"u"&&/Mac|iPhone|iPad/.test(navigator.platform);function ot(o){return an?o.metaKey:o.ctrlKey}function cn(o){function u(){const i=o.getSelectedId();return i||(o.defaultTargetId?o.defaultTargetId():o.getRootId())}function l(i){const c=i.target;if(c&&(c.tagName==="INPUT"||c.tagName==="TEXTAREA"||c.isContentEditable)||o.isReadonly()||o.isEditing())return;const d=o.getSelectedId(),m=u();if(m){if(ot(i)&&!i.shiftKey){if(i.key==="d"||i.key==="D"){d&&d!==o.getRootId()&&(i.preventDefault(),o.onDuplicate(d));return}if(i.key==="z"||i.key==="Z"){i.preventDefault(),o.onUndo();return}if(i.key==="y"||i.key==="Y"){i.preventDefault(),o.onRedo();return}if(i.key==="Home"){i.preventDefault(),o.onSelectRoot();return}}if(ot(i)&&i.shiftKey&&(i.key==="Z"||i.key==="z")){i.preventDefault(),o.onRedo();return}i.key==="Tab"?(i.preventDefault(),o.onAddChild(m)):i.key==="Enter"?(i.preventDefault(),i.shiftKey?d&&d!==o.getRootId()&&o.onAddSiblingBefore(d):o.onAddSibling(m)):(i.key==="Delete"||i.key==="Backspace")&&d&&d!==o.getRootId()?(i.preventDefault(),o.onRemove(d)):i.key==="F2"&&d?(i.preventDefault(),o.onStartEdit(d)):i.key==="Escape"?(i.preventDefault(),o.onClearSelection()):i.key==="ArrowDown"?(i.preventDefault(),o.onNavigate(0,1)):i.key==="ArrowUp"?(i.preventDefault(),o.onNavigate(0,-1)):i.key==="ArrowRight"?(i.preventDefault(),o.onNavigate(1,0)):i.key==="ArrowLeft"&&(i.preventDefault(),o.onNavigate(-1,0))}}e.onMounted(()=>{window.addEventListener("keydown",l)}),e.onBeforeUnmount(()=>{window.removeEventListener("keydown",l)})}function sn(o=100){const u=e.ref([]);let l=-1;function i(){return l>0}function c(){return l<u.value.length-1}function d(x){const s=JSON.stringify(x);for(l<u.value.length-1&&(u.value=u.value.slice(0,l+1)),u.value.push(s),l=u.value.length-1;u.value.length>o;)u.value.shift(),l--}function m(){return i()?(l--,JSON.parse(u.value[l])):null}function p(){return c()?(l++,JSON.parse(u.value[l])):null}function g(){u.value=[],l=-1}return{canUndo:i,canRedo:c,record:d,undo:m,redo:p,reset:g}}const dn=["disabled"],un=["disabled"],fn=["disabled"],mn=["disabled"],hn=["disabled"],yn=["disabled"],gn=e.defineComponent({__name:"NodeContextMenu",props:{x:{},y:{},container:{},hasImage:{type:Boolean,default:!1},hasLink:{type:Boolean,default:!1},hasNote:{type:Boolean,default:!1},readonly:{type:Boolean,default:!1}},emits:["pickImage","setLink","removeLink","editNote","removeNote","removeImage","close"],setup(o,{emit:u}){const l=o,i=u,c=e.computed(()=>{let v=l.x+2,E=l.y+2;if(l.container){const I=l.container.getBoundingClientRect(),K=180,j=d.value?m.value?184:160:136;v+K>I.right&&(v=Math.max(I.left+4,l.x-K-2)),E+j>I.bottom&&(E=Math.max(I.top+4,l.y-j-2)),v<I.left+2&&(v=I.left+2),E<I.top+2&&(E=I.top+2)}return{left:v,top:E}}),d=e.computed(()=>l.hasImage),m=e.computed(()=>l.hasLink),p=e.computed(()=>l.hasNote);function g(v){const E=v.target;E&&E.closest(".zm-node-menu")||i("close")}function x(v){v.key==="Escape"&&i("close")}function s(){i("close")}window.addEventListener("mousedown",g,!0),window.addEventListener("keydown",x,!0),window.addEventListener("wheel",s,!0),window.addEventListener("scroll",s,!0),e.onBeforeUnmount(()=>{window.removeEventListener("mousedown",g,!0),window.removeEventListener("keydown",x,!0),window.removeEventListener("wheel",s,!0),window.removeEventListener("scroll",s,!0)});function w(v){l.readonly||(v(),i("close"))}return(v,E)=>(e.openBlock(),e.createElementBlock("div",{class:"zm-node-menu",style:e.normalizeStyle({left:c.value.left+"px",top:c.value.top+"px"}),onContextmenu:E[6]||(E[6]=e.withModifiers(()=>{},["prevent"]))},[e.createElementVNode("button",{class:"zm-node-menu-item",disabled:o.readonly,onClick:E[0]||(E[0]=e.withModifiers(I=>w(()=>i("pickImage")),["stop"]))},[e.createVNode(z,{name:"image",size:13}),e.createElementVNode("span",null,e.toDisplayString(d.value?"替换图片":"添加图片"),1)],8,dn),d.value?(e.openBlock(),e.createElementBlock("button",{key:0,class:"zm-node-menu-item",disabled:o.readonly,onClick:E[1]||(E[1]=e.withModifiers(I=>w(()=>i("removeImage")),["stop"]))},[e.createVNode(z,{name:"x",size:13}),E[7]||(E[7]=e.createElementVNode("span",null,"移除图片",-1))],8,un)):e.createCommentVNode("",!0),e.createElementVNode("button",{class:"zm-node-menu-item",disabled:o.readonly,onClick:E[2]||(E[2]=e.withModifiers(I=>w(()=>i("setLink")),["stop"]))},[e.createVNode(z,{name:"link",size:13}),e.createElementVNode("span",null,e.toDisplayString(m.value?"编辑链接":"添加链接"),1)],8,fn),m.value?(e.openBlock(),e.createElementBlock("button",{key:1,class:"zm-node-menu-item",disabled:o.readonly,onClick:E[3]||(E[3]=e.withModifiers(I=>w(()=>i("removeLink")),["stop"]))},[e.createVNode(z,{name:"x",size:13}),E[8]||(E[8]=e.createElementVNode("span",null,"移除链接",-1))],8,mn)):e.createCommentVNode("",!0),e.createElementVNode("button",{class:"zm-node-menu-item",disabled:o.readonly,onClick:E[4]||(E[4]=e.withModifiers(I=>w(()=>i("editNote")),["stop"]))},[e.createVNode(z,{name:"note",size:13}),e.createElementVNode("span",null,e.toDisplayString(p.value?"编辑笔记":"添加笔记"),1)],8,hn),p.value?(e.openBlock(),e.createElementBlock("button",{key:2,class:"zm-node-menu-item",disabled:o.readonly,onClick:E[5]||(E[5]=e.withModifiers(I=>w(()=>i("removeNote")),["stop"]))},[e.createVNode(z,{name:"x",size:13}),E[9]||(E[9]=e.createElementVNode("span",null,"移除笔记",-1))],8,yn)):e.createCommentVNode("",!0)],36))}}),xn=["viewBox","width","height"],pn={class:"zm-edges"},kn=["d","fill"],wn=["data-node-id","onClick","onDblclick","onContextmenu","onMouseenter","onMouseleave"],bn=["src","width","height","alt"],En={key:1,class:"zm-text"},Nn={class:"zm-text-label"},Mn=["href","title"],Bn=["title","onClick"],Cn=["title"],vn=["title","onClick"],Sn=["onClick"],Vn=["onMousedown"],zn=["onClick"],In={key:0,class:"zm-toolbar"},Wn=["src"],$n=["src"],Rn={class:"zm-tb-tip"},ie=24,me=400,Z=160,lt=e.defineComponent({__name:"MindMap",props:{data:{},readonly:{type:Boolean,default:!1},theme:{},previewMode:{type:Boolean,default:!1}},emits:["change","select","edit-note"],setup(o,{expose:u,emit:l}){const i=o,c=l,d=e.ref(null),m=e.ref(null),p=e.ref(""),g=e.ref(null),x=e.ref(new Set),s=e.ref(J(i.data)),w=e.computed(()=>k.showOrderBadge===!0),v=e.ref(new Map),E=v.value;function I(t,n){const a={};n.bg&&(a.bg=n.bg),n.textColor&&(a.textColor=n.textColor),n.borderColor&&(a.borderColor=n.borderColor),n.fontWeight&&(a.fontWeight=n.fontWeight),Object.keys(a).length===0?E.delete(t):E.set(t,a),v.value=new Map(E)}function K(t){return E.get(t)??{}}function j(t,n){const a=B(s.value,t);a&&(a.image={src:n.src,naturalW:n.naturalW,naturalH:n.naturalH,width:G(n.width,ie,me),height:G(n.height,ie,me)},P(),V(),c("change",s.value))}function Ve(t){const n=B(s.value,t);!n||!n.image||(delete n.image,P(),V(),c("change",s.value))}function G(t,n,a){return Math.min(a,Math.max(n,t))}function he(t,n){const a=new FileReader;a.onload=()=>{if(typeof a.result!="string")return;const f=a.result,h=new window.Image;h.onload=()=>{const r=h.naturalWidth||Z,y=h.naturalHeight||Z,C=G(r,ie,Z),W=G(Math.round(y*C/r),ie,me);n({src:f,naturalW:r,naturalH:y,width:C,height:W})},h.onerror=()=>{n({src:f,naturalW:Z,naturalH:Z,width:Z,height:Z})},h.src=f},a.readAsDataURL(t)}function ze(t){const n=document.createElement("input");n.type="file",n.accept="image/*",n.style.display="none",n.onchange=()=>{var f;const a=(f=n.files)==null?void 0:f[0];a&&(he(a,h=>j(t,h)),document.body.removeChild(n))},document.body.appendChild(n),n.click()}function ye(t,n){const a=n.trim(),f=B(s.value,t);f&&(a?f.link={url:a}:delete f.link,P(),V(),c("change",s.value))}function ge(t){ye(t,"")}function xe(t,n){const a=B(s.value,t);a&&(n?a.note={text:n}:delete a.note,P(),V(),c("change",s.value))}function pe(t){xe(t,"")}const $=e.ref(null);function M(t,n){i.readonly||(t.preventDefault(),t.stopPropagation(),g.value=n.id,c("select",B(s.value,n.id)),$.value={nodeId:n.id,x:t.clientX,y:t.clientY})}function R(){$.value=null}function L(){var n;const t=(n=$.value)==null?void 0:n.nodeId;t&&ze(t)}function H(){var f,h,r;const t=(f=$.value)==null?void 0:f.nodeId;if(!t)return;const n=((r=(h=B(s.value,t))==null?void 0:h.link)==null?void 0:r.url)??"",a=window.prompt("输入链接 URL(留空取消)",n);a!==null&&ye(t,a)}function q(){var n;const t=(n=$.value)==null?void 0:n.nodeId;t&&ge(t)}function X(){var n;const t=(n=$.value)==null?void 0:n.nodeId;t&&Q(t)}function re(){var n;const t=(n=$.value)==null?void 0:n.nodeId;t&&pe(t)}function ke(){var n;const t=(n=$.value)==null?void 0:n.nodeId;t&&Ve(t)}function Q(t){i.readonly||c("edit-note",t)}function Ln(t,n=60){const a=t.replace(/\s+/g," ").trim();return a.length<=n?a||"点击编辑笔记":a.slice(0,n)+"…"}function it(t){var h;if(i.readonly||m.value)return;const n=t.target;if(n&&(n.tagName==="INPUT"||n.tagName==="TEXTAREA"||n.isContentEditable))return;const a=g.value;if(!a)return;const f=(h=t.clipboardData)==null?void 0:h.items;if(f)for(let r=0;r<f.length;r++){const y=f[r];if(y.kind==="file"&&y.type.startsWith("image/")){const C=y.getAsFile();if(!C)continue;t.preventDefault();const W=B(s.value,a);if(W!=null&&W.image&&!window.confirm("该节点已有图片,要用剪贴板里的图片替换吗?"))return;he(C,A=>j(a,A));return}}}e.onMounted(()=>{window.addEventListener("paste",it)}),e.onBeforeUnmount(()=>{window.removeEventListener("paste",it)});const we=e.ref(null),An=e.computed(()=>{var t;return((t=we.value)==null?void 0:t.nodeId)??null});function Hn(t,n){if(!n.image)return;t.preventDefault(),t.stopPropagation();const a=n.image.naturalW||n.image.width,f=n.image.naturalH||n.image.height,h=f>0?f/a:1;we.value={nodeId:n.id,startX:t.clientX,startY:t.clientY,startW:n.image.width,startH:n.image.height,naturalW:a,naturalH:f,ratio:h,pendingW:n.image.width,pendingH:n.image.height},window.addEventListener("mousemove",rt),window.addEventListener("mouseup",at)}function rt(t){var W,A;const n=we.value;if(!n)return;const a=b.scale.value||1,f=t.clientX-n.startX,h=G(n.startW+f/a,ie,me),r=G(h*n.ratio,ie,me);n.pendingW=h,n.pendingH=r;const y=(W=d.value)==null?void 0:W.querySelector(`[data-node-id="${n.nodeId}"] .zm-node-img`);y&&(y.style.width=`${h}px`,y.style.height=`${r}px`);const C=(A=d.value)==null?void 0:A.querySelector(`[data-node-id="${n.nodeId}"]`);C&&(C.style.minWidth=`${Math.max(80,Math.ceil(h+28))}px`,C.style.height=`${Math.ceil(r+8+30)}px`)}function at(){const t=we.value;if(window.removeEventListener("mousemove",rt),window.removeEventListener("mouseup",at),we.value=null,!t)return;const n=B(s.value,t.nodeId);!n||!n.image||(j(t.nodeId,{src:n.image.src,naturalW:n.image.naturalW,naturalH:n.image.naturalH,width:t.pendingW,height:t.pendingH}),g.value=t.nodeId,c("select",n),Te=!0)}const Pe=e.ref(null);let Te=!1;function Pn(t){Pe.value=t}function Tn(t){Pe.value===t&&(Pe.value=null)}const ct=e.ref(0),Fe=e.ref(!1),_=sn(100);function P(){_.record({data:s.value})}function V(){x.value=new Set(x.value),ct.value++}const U=e.computed(()=>{var t,n,a,f,h,r,y,C,W,A;return{rootBg:((t=i.theme)==null?void 0:t.rootBg)??"#1f2937",rootText:((n=i.theme)==null?void 0:n.rootText)??"#ffffff",branchBg:((a=i.theme)==null?void 0:a.branchBg)??"#ffffff",branchText:((f=i.theme)==null?void 0:f.branchText)??"#1f2937",lineColor:((h=i.theme)==null?void 0:h.lineColor)??"#94a3b8",bgColor:((r=i.theme)==null?void 0:r.bgColor)??"#f8fafc",fontSize:((y=i.theme)==null?void 0:y.fontSize)??14,lineWidthStart:((C=i.theme)==null?void 0:C.lineWidthStart)??2.2,lineWidthEnd:((W=i.theme)==null?void 0:W.lineWidthEnd)??.8,rainbowBranch:((A=i.theme)==null?void 0:A.rainbowBranch)??!1}}),k=e.reactive({autoBalanceOnChange:!0,lineWidthStart:12,lineWidthEnd:3.6,rainbowBranch:!0,branchPaletteId:"default",customPalettes:[],lineStyle:"curve",layoutMode:"mindmap",taperedEdge:!0,showOrderBadge:!1});function st(t){return k.taperedEdge?Fn(t):ut(t)}function dt(t){return k.taperedEdge?k.lineWidthEnd:ut(t)}function Fn(t){return t<=0?k.lineWidthStart:t===1?Math.max(1.5,k.lineWidthStart*.67):t===2?Math.max(.8,k.lineWidthStart*.42):k.lineWidthEnd}function ut(t){if(t<=0)return k.lineWidthStart;if(t>=3)return k.lineWidthEnd;const n=t/3;return k.lineWidthStart+(k.lineWidthEnd-k.lineWidthStart)*n}function On(t,n,a,f){const h=1-t,r=h*h*h*n.x+3*h*h*t*a.x1+3*h*t*t*a.x2+t*t*t*f.x,y=h*h*h*n.y+3*h*h*t*a.y1+3*h*t*t*a.y2+t*t*t*f.y;return{x:r,y}}function qn(t,n,a,f,h=32,r="curve",y="right"){if(r==="curve"){let oe;if(y==="right"||y==="left"){const S=Math.abs(n.x-t.x)*.45,Y=y==="right"?1:-1;oe={x1:t.x+Y*S,y1:t.y,x2:n.x-Y*S,y2:n.y}}else{const S=Math.abs(n.y-t.y)*.45;oe={x1:t.x,y1:t.y+S,x2:n.x,y2:n.y-S}}const mo=N=>{const S=1-N,Y=-3*S*S*t.x+3*(S*S-2*S*N)*oe.x1+3*(2*S*N-N*N)*oe.x2+3*N*N*n.x,de=-3*S*S*t.y+3*(S*S-2*S*N)*oe.y1+3*(2*S*N-N*N)*oe.y2+3*N*N*n.y;return{dx:Y,dy:de}},Ne=[],Ye=[];for(let N=0;N<=h;N++){const S=N/h,Y=N===0?t:N===h?n:On(S,t,oe,n),de=mo(S);let De=Math.hypot(de.dx,de.dy);De<1e-6&&(De=1);const Vt=-de.dy/De,zt=de.dx/De,Le=(a+(f-a)*S)/2;Ne.push({x:Y.x+Vt*Le,y:Y.y+zt*Le}),Ye.push({x:Y.x-Vt*Le,y:Y.y-zt*Le})}let Re=`M ${Ne[0].x.toFixed(2)} ${Ne[0].y.toFixed(2)}`;for(let N=1;N<=h;N++)Re+=` L ${Ne[N].x.toFixed(2)} ${Ne[N].y.toFixed(2)}`;for(let N=h;N>=0;N--)Re+=` L ${Ye[N].x.toFixed(2)} ${Ye[N].y.toFixed(2)}`;return Re+=" Z",Re}const C=n.x-t.x,W=n.y-t.y;let A=Math.hypot(C,W);A<1e-6&&(A=1);const ne=-W/A,ce=C/A,se=a/2,Ee=f/2,Bt={x:t.x+ne*se,y:t.y+ce*se},Ct={x:t.x-ne*se,y:t.y-ce*se},vt={x:n.x-ne*Ee,y:n.y-ce*Ee},St={x:n.x+ne*Ee,y:n.y+ce*Ee};return`M ${Bt.x.toFixed(2)} ${Bt.y.toFixed(2)} L ${St.x.toFixed(2)} ${St.y.toFixed(2)} L ${vt.x.toFixed(2)} ${vt.y.toFixed(2)} L ${Ct.x.toFixed(2)} ${Ct.y.toFixed(2)} Z`}const Ie=e.computed(()=>T.value.root.children),Xn=ue[0].colors,ft=e.computed(()=>en(k.branchPaletteId,k.customPalettes)),ee=e.computed(()=>{const t=new Map;if(!k.rainbowBranch)return t;const n=ft.value.colors.length>0?ft.value.colors:Xn;for(let f=0;f<Ie.value.length;f++){const h=Ie.value[f];t.set(h.id,n[f%n.length])}const a=(f,h)=>{t.set(f.id,h);for(const r of f.children)a(r,h)};for(let f=0;f<Ie.value.length;f++){const h=Ie.value[f];a(h,n[f%n.length])}return t});function Kn(t,n){return k.rainbowBranch?ee.value.get(n.id)??U.value.lineColor:U.value.lineColor}function Un(t){const n=K(t.id);if(n.bg)return n.bg;if(t.isRoot)return U.value.rootBg;if(k.rainbowBranch){const a=ee.value.get(t.id);if(a)return Jn(a,.18)}return U.value.branchBg}function Yn(t){const n=K(t.id);if(n.textColor)return n.textColor;if(t.isRoot)return U.value.rootText;if(k.rainbowBranch){const a=ee.value.get(t.id);if(a)return mt(a,.55)}return U.value.branchText}function jn(t){const n=K(t.id);if(n.borderColor)return n.borderColor;if(t.isRoot)return U.value.rootBg;if(k.rainbowBranch){const a=ee.value.get(t.id);if(a)return mt(a,.3)}return U.value.lineColor}function Gn(t){return K(t.id).fontWeight??(t.isRoot?600:400)}function Jn(t,n){const a=t.replace("#",""),f=a.length===6?a:a.split("").map(C=>C+C).join(""),h=parseInt(f.slice(0,2),16),r=parseInt(f.slice(2,4),16),y=parseInt(f.slice(4,6),16);return`rgba(${h}, ${r}, ${y}, ${n})`}function mt(t,n){const a=t.replace("#",""),f=a.length===6?a:a.split("").map(C=>C+C).join(""),h=Math.round(parseInt(f.slice(0,2),16)*(1-n)),r=Math.round(parseInt(f.slice(2,4),16)*(1-n)),y=Math.round(parseInt(f.slice(4,6),16)*(1-n));return`rgb(${h}, ${r}, ${y})`}const b=rn({getContainer:()=>d.value});b.setOnMarqueeEnd(ao),cn({isEditing:()=>m.value!==null,isReadonly:()=>i.readonly,getSelectedId:()=>g.value,getRootId:()=>s.value.id,defaultTargetId:()=>s.value.id,onAddChild:ae,onAddSibling:$e,onAddSiblingBefore:gt,onRemove:pt,onStartEdit:be,onClearSelection:()=>{g.value=null,c("select",null)},onDuplicate:xt,onUndo:qe,onRedo:Xe,onNavigate:to,onSelectRoot:()=>{g.value=s.value.id;const t=B(s.value,s.value.id);t&&c("select",t)}});const T=e.computed(()=>{const t=J(s.value);return yt(t),Jt(t,{mode:k.layoutMode})}),ht=e.ref([]),Oe=e.computed(()=>(ct.value,ht.value));e.watch(T,t=>{const n=[],a=f=>{n.push(f);for(const h of f.children)a(h)};a(t.root),ht.value=n},{immediate:!0});const Zn=e.computed(()=>{const t=[];for(const n of Oe.value)for(const a of n.children)t.push({from:n,to:a,key:`${n.id}->${a.id}`});return t}),Qn=e.computed(()=>`${T.value.vbX} ${T.value.vbY} ${T.value.vbW} ${T.value.vbH}`);function yt(t){if(x.value.has(t.id)){t.children=[],t.collapsed=!0;return}t.collapsed=!1;for(const n of t.children)yt(n)}function be(t){const n=B(s.value,t);n&&(m.value=t,p.value=n.text,e.nextTick(()=>{const a=document.querySelector(".zm-input");a==null||a.focus(),a==null||a.select()}))}function We(t={}){if(!m.value)return;const n=B(s.value,m.value);n&&n.text!==(p.value.trim()||" ")&&(n.text=p.value.trim()||" ",P(),c("change",s.value));const a=m.value;m.value=null,t.addChild?e.nextTick(()=>ae(a)):t.addSibling==="after"?e.nextTick(()=>$e(a)):t.addSibling==="before"&&e.nextTick(()=>gt(a))}function _n(){m.value=null}function eo(t){const n=t.metaKey||t.ctrlKey;n&&(t.key==="z"||t.key==="Z")&&!t.shiftKey?(t.preventDefault(),qe()):(n&&t.shiftKey&&(t.key==="z"||t.key==="Z")||n&&(t.key==="y"||t.key==="Y")&&!t.shiftKey)&&(t.preventDefault(),Xe())}function ae(t){const n=et(s.value,t,Se);n&&(P(),V(),c("change",s.value),e.nextTick(()=>be(n.id)))}function $e(t){if(t===s.value.id){ae(t);return}const n=tt(s.value,t,Se);n&&(P(),V(),c("change",s.value),e.nextTick(()=>be(n.id)))}function gt(t){if(t===s.value.id){ae(t);return}const n=on(s.value,t,Se);n&&(P(),V(),c("change",s.value),e.nextTick(()=>be(n.id)))}function xt(t){if(t===s.value.id)return;const n=ln(s.value,t);n&&(P(),g.value=n.id,c("change",s.value),V())}function qe(){const t=_.undo();t&&(s.value=t.data,g.value=null,c("select",null),V(),c("change",s.value))}function Xe(){const t=_.redo();t&&(s.value=t.data,g.value=null,c("select",null),V(),c("change",s.value))}function to(t,n){const a=g.value??s.value.id,f=B(s.value,a);if(!f)return;let h=null;if(n===1){const r=O(s.value,f.id);if(r){const y=r.children.findIndex(C=>C.id===f.id);y>=0&&y<r.children.length-1&&(h=r.children[y+1].id)}}else if(n===-1){const r=O(s.value,f.id);if(r){const y=r.children.findIndex(C=>C.id===f.id);y>0&&(h=r.children[y-1].id)}}else if(t===1){const r=O(s.value,f.id);r&&(h=r.id)}else t===-1&&f.children.length>0&&(h=f.children[0].id);if(h){g.value=h;const r=B(s.value,h);r&&c("select",r)}}function pt(t){t!==s.value.id&&He(s.value,t)&&(P(),g.value===t&&(g.value=null),V(),c("change",s.value))}function kt(t){x.value.has(t)?x.value.delete(t):x.value.add(t),V()}function no(t,n){tn(s.value,t,n)&&(P(),V(),c("change",s.value))}function oo(t,n,a){return nn(s.value,t,n,a)?(P(),V(),c("change",s.value),!0):!1}function lo(t,n){t.stopPropagation(),g.value=n.id;const a=B(s.value,n.id);c("select",a)}function io(t){const n=t.target;if(!n||n.closest(".zm-node, .zm-toolbar, button, input, textarea"))return;if(t.button===2){b.startPan(t);return}if(t.button!==0)return;const a=d.value.getBoundingClientRect(),f=(t.clientX-a.left-b.offsetX.value)/b.scale.value,h=(t.clientY-a.top-b.offsetY.value)/b.scale.value;b.startMarquee(f,h)}function ro(t){if(Te){Te=!1;return}const n=t.target;if(!n||n.closest(".zm-node"))return;const a=b.marquee;a.width>=4||a.height>=4||g.value!==null&&(g.value=null,c("select",null))}function ao(){const t=b.marquee;if(t.width<4&&t.height<4)return;const n=t.x,a=t.y,f=t.x+t.width,h=t.y+t.height,r=[];for(const y of Oe.value){const C=y.width/2,W=y.height/2,A=y.x-C,ne=y.x+C,ce=y.y-W,se=y.y+W;A<=f&&ne>=n&&ce<=h&&se>=a&&r.push(y.id)}if(r.length>0){g.value=r[0];const y=B(s.value,r[0]);y&&c("select",y)}}function wt(t){return x.value.has(t)}function co(t){const n=B(s.value,t.id);return!!n&&n.children.length>0}function Ke(t){const n=B(s.value,t);return n?n.children.length:0}function bt(t){if(!B(s.value,t))return 0;const f=[s.value];for(;f.length;){const h=f.pop(),r=h.children.findIndex(y=>y.id===t);if(r>=0)return r;for(const y of h.children)f.push(y)}return 0}function Et(t,n,a,f){if(((f==null?void 0:f._dir)??t._dir)==="down")return n==="out"?{x:t.x,y:t.y+t.height/2}:{x:t.x,y:t.y-t.height/2};let r;return n==="in"?r=-t.side:a!==void 0?r=a:r=t.side,{x:t.x+r*(t.width/2),y:t.y}}function te(){const t=T.value;b.resetView(t.width,t.height,t.root.y)}function so(){Fe.value=!0,P(),V(),e.nextTick(()=>te())}function Ue(t){k.layoutMode!==t&&(k.layoutMode=t,V(),e.nextTick(()=>te()))}function Nt(){return JSON.stringify(s.value,null,2)}function Mt(t){try{const n=JSON.parse(t);return!n.id||!Array.isArray(n.children)?!1:(_.reset(),s.value=J(n),g.value=null,x.value=new Set,V(),e.nextTick(()=>te()),c("change",s.value),!0)}catch{return!1}}function uo(){const t=document.createElement("input");t.type="file",t.accept="application/json",t.onchange=()=>{var f;const n=(f=t.files)==null?void 0:f[0];if(!n)return;const a=new FileReader;a.onload=()=>{typeof a.result=="string"&&(Mt(a.result)||alert("导入失败:JSON 格式无效"))},a.readAsText(n)},t.click()}function fo(){const t=new Blob([Nt()],{type:"application/json"}),n=URL.createObjectURL(t),a=document.createElement("a");a.href=n,a.download=`${s.value.text||"mindmap"}.json`,a.click(),URL.revokeObjectURL(n)}return u({addChild:t=>ae(t),addSibling:t=>$e(t),removeNode:t=>pt(t),duplicateNode:t=>xt(t),setNodeText:(t,n)=>no(t,n),moveNode:(t,n,a)=>oo(t,n,a),lineWidthForDepth:st,endWidthForDepth:dt,getData:()=>s.value,setData:t=>{_.reset(),s.value=J(t),g.value=null,x.value=new Set,V(),e.nextTick(()=>te())},resetView:()=>te(),exportData:Nt,importData:Mt,setBalanced:t=>{Fe.value=t},isBalanced:()=>Fe.value,balance:()=>so(),applyNodeStyle:(t,n)=>I(t,n),getNodeStyle:t=>K(t),applyNodeLink:(t,n)=>ye(t,n),removeNodeLink:t=>ge(t),applyNodeNote:(t,n)=>xe(t,n),removeNodeNote:t=>pe(t),undo:()=>qe(),redo:()=>Xe(),canUndo:()=>_.canUndo(),canRedo:()=>_.canRedo(),applySettings:t=>{t.autoBalanceOnChange!==void 0&&(k.autoBalanceOnChange=t.autoBalanceOnChange),t.lineWidthStart!==void 0&&(k.lineWidthStart=Math.max(.5,Math.min(20,t.lineWidthStart))),t.lineWidthEnd!==void 0&&(k.lineWidthEnd=Math.max(.3,Math.min(10,t.lineWidthEnd))),t.rainbowBranch!==void 0&&(k.rainbowBranch=t.rainbowBranch),t.branchPaletteId!==void 0&&(k.branchPaletteId=t.branchPaletteId),t.customPalettes!==void 0&&(k.customPalettes=t.customPalettes),t.lineStyle!==void 0&&(k.lineStyle=t.lineStyle),t.taperedEdge!==void 0&&(k.taperedEdge=t.taperedEdge),t.showOrderBadge!==void 0&&(k.showOrderBadge=t.showOrderBadge)},getSettings:()=>({autoBalanceOnChange:k.autoBalanceOnChange,lineWidthStart:k.lineWidthStart,lineWidthEnd:k.lineWidthEnd,rainbowBranch:k.rainbowBranch,branchPaletteId:k.branchPaletteId,customPalettes:k.customPalettes,lineStyle:k.lineStyle,layoutMode:k.layoutMode,taperedEdge:k.taperedEdge,showOrderBadge:k.showOrderBadge}),setBranchPalette:t=>{if(!t)return;[...ue,...k.customPalettes].find(a=>a.id===t)&&(k.branchPaletteId=t)},getBranchPalette:()=>k.branchPaletteId,getBranchPalettes:()=>[...ue,...k.customPalettes]}),e.watch(()=>i.data,t=>{s.value=J(t),V()},{deep:!1}),e.onMounted(()=>{e.nextTick(()=>te())}),(t,n)=>{var a,f,h;return e.openBlock(),e.createElementBlock("div",{class:"zm-mindmap",style:e.normalizeStyle({background:U.value.bgColor,fontSize:U.value.fontSize+"px"})},[e.createElementVNode("div",{ref_key:"wrapperRef",ref:d,class:"zm-canvas",onMousedown:io,onContextmenu:n[13]||(n[13]=e.withModifiers(()=>{},["prevent"])),onWheel:n[14]||(n[14]=(...r)=>e.unref(b).onWheel&&e.unref(b).onWheel(...r)),onClick:ro},[e.createElementVNode("div",{class:"zm-svg-layer",style:e.normalizeStyle({left:T.value.vbX*e.unref(b).scale.value+e.unref(b).offsetX.value+"px",top:T.value.vbY*e.unref(b).scale.value+e.unref(b).offsetY.value+"px",width:T.value.vbW*e.unref(b).scale.value+"px",height:T.value.vbH*e.unref(b).scale.value+"px"})},[(e.openBlock(),e.createElementBlock("svg",{class:"zm-svg",viewBox:Qn.value,preserveAspectRatio:"xMinYMin meet",width:T.value.vbW*e.unref(b).scale.value,height:T.value.vbH*e.unref(b).scale.value},[e.createElementVNode("g",pn,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(Zn.value,r=>(e.openBlock(),e.createElementBlock("path",{key:r.key,d:qn(Et(r.from,"out",r.to.side,r.to),Et(r.to,"in"),st(r.from.depth),dt(r.to.depth),32,k.lineStyle,r.to._dir),fill:Kn(r.from,r.to),stroke:"none"},null,8,kn))),128))])],8,xn))],4),e.unref(b).isMarquee.value?(e.openBlock(),e.createElementBlock("div",{key:0,class:"zm-marquee",style:e.normalizeStyle({left:e.unref(b).marquee.x*e.unref(b).scale.value+e.unref(b).offsetX.value+"px",top:e.unref(b).marquee.y*e.unref(b).scale.value+e.unref(b).offsetY.value+"px",width:e.unref(b).marquee.width*e.unref(b).scale.value+"px",height:e.unref(b).marquee.height*e.unref(b).scale.value+"px"})},null,4)):e.createCommentVNode("",!0),e.createElementVNode("div",{class:"zm-world",style:e.normalizeStyle({transform:`translate(${e.unref(b).offsetX.value}px, ${e.unref(b).offsetY.value}px) scale(${e.unref(b).scale.value})`})},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(Oe.value,r=>(e.openBlock(),e.createElementBlock("div",{key:r.id,class:e.normalizeClass(["zm-node",{"is-root":r.isRoot,"is-selected":g.value===r.id,"is-editing":m.value===r.id,"has-image":!!r.image,"is-resizing":An.value===r.id}]),"data-node-id":r.id,style:e.normalizeStyle({left:r.x+"px",top:r.y+"px",minWidth:r.width+"px",height:r.height+"px",fontSize:r.fontSize+"px",background:Un(r),color:Yn(r),borderColor:jn(r),fontWeight:Gn(r),transform:"translate(-50%, -50%)"}),onClick:y=>lo(y,r),onDblclick:y=>{y.stopPropagation(),o.readonly||be(r.id)},onContextmenu:y=>M(y,r),onMouseenter:y=>Pn(r.id),onMouseleave:y=>Tn(r.id)},[r.image?(e.openBlock(),e.createElementBlock("img",{key:0,class:"zm-node-img",src:r.image.src,width:r.image.width,height:r.image.height,alt:r.text,draggable:"false"},null,8,bn)):e.createCommentVNode("",!0),m.value!==r.id?(e.openBlock(),e.createElementBlock("span",En,[e.createElementVNode("span",Nn,e.toDisplayString(r.text),1),r.link&&!m.value?(e.openBlock(),e.createElementBlock("a",{key:0,class:"zm-node-link",href:r.link.url,target:"_blank",rel:"noopener noreferrer",title:`打开链接:${r.link.url}`,onClick:n[0]||(n[0]=e.withModifiers(()=>{},["stop"])),onMousedown:n[1]||(n[1]=e.withModifiers(()=>{},["stop"]))},[e.createVNode(z,{name:"link",size:11,stroke:2})],40,Mn)):e.createCommentVNode("",!0),r.note&&!m.value?(e.openBlock(),e.createElementBlock("button",{key:1,class:"zm-node-note-btn",type:"button",title:Ln(r.note.text),onClick:e.withModifiers(y=>Q(r.id),["stop"]),onMousedown:n[2]||(n[2]=e.withModifiers(()=>{},["stop"]))},[e.createVNode(z,{name:"note",size:11,stroke:2})],40,Bn)):e.createCommentVNode("",!0)])):e.withDirectives((e.openBlock(),e.createElementBlock("input",{key:2,class:"zm-input","onUpdate:modelValue":n[3]||(n[3]=y=>p.value=y),autofocus:"",onBlur:n[4]||(n[4]=y=>We()),onKeydown:[n[5]||(n[5]=e.withKeys(e.withModifiers(y=>We({addSibling:"after"}),["exact"]),["enter"])),n[6]||(n[6]=e.withKeys(e.withModifiers(y=>We({addSibling:"before"}),["shift","prevent","exact"]),["enter"])),n[7]||(n[7]=e.withKeys(e.withModifiers(y=>We({addChild:!0}),["prevent"]),["tab"])),e.withKeys(_n,["esc"]),eo],onMousedown:n[8]||(n[8]=e.withModifiers(()=>{},["stop"])),onClick:n[9]||(n[9]=e.withModifiers(()=>{},["stop"]))},null,544)),[[e.vModelText,p.value]]),w.value?(e.openBlock(),e.createElementBlock("span",{key:3,class:"zm-order-badge",title:`数据顺序:第 ${bt(r.id)+1} 个`},e.toDisplayString(bt(r.id)+1),9,Cn)):e.createCommentVNode("",!0),wt(r.id)&&!r.isRoot&&Ke(r.id)>0?(e.openBlock(),e.createElementBlock("span",{key:4,class:e.normalizeClass(["zm-collapse-badge",{"is-on-left":r.side===-1}]),style:e.normalizeStyle({background:ee.value.get(r.id)??"#64748b"}),title:`展开 ${Ke(r.id)} 个子节点`,onMousedown:n[10]||(n[10]=e.withModifiers(()=>{},["stop"])),onClick:e.withModifiers(y=>kt(r.id),["stop"])},e.toDisplayString(Ke(r.id)),47,vn)):e.createCommentVNode("",!0),!o.readonly&&!r.isRoot&&co(r)&&!wt(r.id)?(e.openBlock(),e.createElementBlock("button",{key:5,class:e.normalizeClass(["zm-btn zm-collapse",{"is-on-left":r.side===-1}]),style:e.normalizeStyle({color:ee.value.get(r.id)??"#64748b",borderColor:ee.value.get(r.id)??"#64748b"}),title:"折叠",onMousedown:n[11]||(n[11]=e.withModifiers(()=>{},["stop"])),onClick:e.withModifiers(y=>kt(r.id),["stop"])},[e.createVNode(z,{name:"minus",size:10,stroke:2.4})],46,Sn)):e.createCommentVNode("",!0),r.image&&g.value===r.id&&m.value!==r.id?(e.openBlock(),e.createElementBlock("span",{key:6,class:"zm-img-resize-handle",title:"拖动调整图片大小",onMousedown:e.withModifiers(y=>Hn(y,r),["stop"])},null,40,Vn)):e.createCommentVNode("",!0),r.image&&g.value===r.id&&m.value!==r.id?(e.openBlock(),e.createElementBlock("button",{key:7,class:"zm-img-remove-btn",title:"移除图片",onMousedown:n[12]||(n[12]=e.withModifiers(()=>{},["stop"])),onClick:e.withModifiers(y=>Ve(r.id),["stop"])},[e.createVNode(z,{name:"x",size:9,stroke:2.2})],40,zn)):e.createCommentVNode("",!0)],46,wn))),128))],4),$.value?(e.openBlock(),e.createBlock(gn,{key:1,x:$.value.x,y:$.value.y,container:d.value,"has-image":!!((a=e.unref(B)(s.value,$.value.nodeId))!=null&&a.image),"has-link":!!((f=e.unref(B)(s.value,$.value.nodeId))!=null&&f.link),"has-note":!!((h=e.unref(B)(s.value,$.value.nodeId))!=null&&h.note),readonly:i.readonly,onPickImage:L,onRemoveImage:ke,onSetLink:H,onRemoveLink:q,onEditNote:X,onRemoveNote:re,onClose:R},null,8,["x","y","container","has-image","has-link","has-note","readonly"])):e.createCommentVNode("",!0)],544),i.previewMode?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("div",In,[e.createElementVNode("button",{class:"zm-tb-btn",title:"放大",onClick:n[15]||(n[15]=(...r)=>e.unref(b).zoomIn&&e.unref(b).zoomIn(...r))},[e.createVNode(z,{name:"zoom-in"})]),e.createElementVNode("button",{class:"zm-tb-btn",title:"缩小",onClick:n[16]||(n[16]=(...r)=>e.unref(b).zoomOut&&e.unref(b).zoomOut(...r))},[e.createVNode(z,{name:"zoom-out"})]),e.createElementVNode("button",{class:"zm-tb-btn",title:"重置视图",onClick:te},[e.createVNode(z,{name:"reset"})]),n[22]||(n[22]=e.createElementVNode("span",{class:"zm-tb-divider"},null,-1)),o.readonly?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("button",{key:0,class:"zm-tb-btn",title:"添加子节点 (Tab)",onClick:n[17]||(n[17]=r=>g.value&&ae(g.value))},[e.createElementVNode("img",{src:e.unref(Dt),width:"14",height:"14",alt:"添加子节点",draggable:"false"},null,8,Wn)])),o.readonly?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("button",{key:1,class:"zm-tb-btn",title:"添加同级 (Enter)",onClick:n[18]||(n[18]=r=>g.value&&$e(g.value))},[e.createElementVNode("img",{src:e.unref(Rt),width:"14",height:"14",alt:"添加同级",draggable:"false"},null,8,$n)])),n[23]||(n[23]=e.createElementVNode("span",{class:"zm-tb-divider"},null,-1)),e.createElementVNode("button",{class:e.normalizeClass(["zm-tb-btn",{active:k.layoutMode==="mindmap"}]),title:"思维导图布局 (中心辐射)",onClick:n[19]||(n[19]=r=>Ue("mindmap"))},[e.createVNode(z,{name:"mindmap"})],2),e.createElementVNode("button",{class:e.normalizeClass(["zm-tb-btn",{active:k.layoutMode==="tree"}]),title:"树形布局 (向右展开)",onClick:n[20]||(n[20]=r=>Ue("tree"))},[e.createVNode(z,{name:"tree"})],2),e.createElementVNode("button",{class:e.normalizeClass(["zm-tb-btn",{active:k.layoutMode==="org"}]),title:"组织结构布局 (向下展开)",onClick:n[21]||(n[21]=r=>Ue("org"))},[e.createVNode(z,{name:"org"})],2),n[24]||(n[24]=e.createElementVNode("span",{class:"zm-tb-divider"},null,-1)),o.readonly?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("button",{key:2,class:"zm-tb-btn",title:"导入 JSON",onClick:uo},[e.createVNode(z,{name:"import"})])),e.createElementVNode("button",{class:"zm-tb-btn",title:"导出 JSON",onClick:fo},[e.createVNode(z,{name:"export"})]),e.createElementVNode("span",Rn,e.toDisplayString(Math.round(e.unref(b).scale.value*100))+"%",1)]))],4)}}}),Dn={install(o){o.component("FlowMindMap",lt)}};D.MindMap=lt,D.addChild=et,D.addSibling=tt,D.clone=J,D.default=Dn,D.findNode=B,D.findParent=O,D.removeNode=He,D.uid=fe,Object.defineProperties(D,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
package/dist/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.zm-node-menu{position:fixed;z-index:40;min-width:168px;padding:4px;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 8px 24px #0f172a24;display:flex;flex-direction:column;gap:2px;font-size:13px;color:#1e293b;-webkit-user-select:none;user-select:none}.zm-node-menu-item{display:flex;align-items:center;gap:8px;padding:6px 10px;border:none;background:transparent;color:inherit;font:inherit;text-align:left;border-radius:4px;cursor:pointer;width:100%;transition:background .1s}.zm-node-menu-item:hover:not(:disabled){background:#f1f5f9}.zm-node-menu-item:active:not(:disabled){background:#e2e8f0}.zm-node-menu-item:disabled{color:#94a3b8;cursor:not-allowed}.zm-mindmap{position:relative;width:100%;height:100%;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,Microsoft YaHei,sans-serif;-webkit-user-select:none;user-select:none}.zm-canvas{position:absolute;top:0;right:0;bottom:0;left:0;cursor:grab}.zm-canvas:active{cursor:grabbing}.zm-world{position:absolute;left:0;top:0;transform-origin:0 0}.zm-svg-layer{position:absolute;pointer-events:none;overflow:visible}.zm-marquee{position:absolute;border:1px dashed #3b82f6;background:#3b82f614;pointer-events:none;z-index:5}.zm-svg{position:absolute;left:0;top:0;pointer-events:none;overflow:visible;shape-rendering:geometricPrecision}.zm-node{position:absolute;display:flex;align-items:center;justify-content:center;padding:0 .8em;box-sizing:border-box;border-radius:8px;border:1px solid;line-height:1.2;cursor:default;transition:box-shadow .15s;box-shadow:0 1px 2px #0000000f;white-space:nowrap;z-index:1}.zm-node:hover{box-shadow:0 4px 12px #0000001a;z-index:2}.zm-node.is-root{font-weight:600}.zm-node.is-selected{outline:2px solid #3b82f6;outline-offset:2px;z-index:3}.zm-text{display:inline-flex;align-items:center;gap:4px;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.zm-text-label{pointer-events:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex-shrink:1}.zm-input{border:none;outline:none;background:transparent;color:inherit;font:inherit;text-align:center;width:100%;min-width:40px}.zm-btn{position:absolute;width:18px;height:18px;border-radius:50%;border:none;background:#3b82f6;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;opacity:0;transition:opacity .15s,transform .15s;z-index:4}.zm-node:hover .zm-btn,.zm-node.is-selected .zm-btn{opacity:1}.zm-btn:hover{transform:scale(1.15)}.zm-collapse{right:-8px;top:50%;width:14px;height:14px;background:#fff;border:1.5px solid;transform:translateY(-50%);box-shadow:0 1px 3px #0f172a2e}.zm-collapse.is-on-left{right:auto;left:-8px}.zm-collapse:hover{transform:translateY(-50%) scale(1.15);background:#fff}.zm-collapse-badge{position:absolute;top:50%;transform:translateY(-50%);left:calc(100% + 8px);min-width:18px;height:18px;padding:0 5px;border-radius:5px;color:#fff;font-size:11px;font-weight:600;line-height:18px;text-align:center;box-shadow:0 1px 2px #00000026;cursor:pointer;-webkit-user-select:none;user-select:none;z-index:2;transition:filter .1s}.zm-collapse-badge.is-on-left{left:auto;right:calc(100% + 8px)}.zm-collapse-badge:hover{filter:brightness(.9)}.zm-node.has-image{flex-direction:column;padding:8px;gap:6px;white-space:normal}.zm-node-img{display:block;pointer-events:none;-webkit-user-select:none;user-select:none;-webkit-user-drag:none;object-fit:contain;border-radius:4px}.zm-node-link,.zm-node-note-btn{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;background:transparent;color:currentColor;border-radius:3px;cursor:pointer;flex-shrink:0;text-decoration:none;opacity:.75;transition:opacity .1s,background .1s;pointer-events:auto}.zm-node-link:hover,.zm-node-note-btn:hover{opacity:1;background:#0f172a14}.zm-node-link svg,.zm-node-note-btn svg{display:block}.zm-img-resize-handle{position:absolute;right:-5px;bottom:-5px;width:10px;height:10px;background:#fff;border:1.5px solid #3b82f6;border-radius:2px;cursor:nwse-resize;z-index:4;box-shadow:0 1px 3px #0f172a33}.zm-node.is-resizing{cursor:nwse-resize!important}.zm-img-remove-btn{position:absolute;right:-5px;bottom:14px;width:14px;height:14px;background:#fff;border:1px solid #cbd5e1;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;color:#64748b;padding:0;z-index:4;box-shadow:0 1px 2px #0f172a1f}.zm-img-remove-btn:hover{background:#fee2e2;color:#b91c1c;border-color:#fca5a5}.zm-order-badge{display:inline-block;margin-left:6px;padding:0 5px;font-size:10px;font-weight:600;line-height:16px;color:#475569;background:#e2e8f0;border-radius:3px;font-variant-numeric:tabular-nums;pointer-events:none;-webkit-user-select:none;user-select:none;vertical-align:middle}.zm-toolbar{position:absolute;bottom:16px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:4px;padding:6px 10px;background:#fff;border:1px solid #e2e8f0;border-radius:999px;box-shadow:0 4px 12px #0000000f;z-index:10}.zm-tb-btn{width:32px;height:32px;display:flex;align-items:center;justify-content:center;border:none;background:transparent;border-radius:6px;cursor:pointer;color:#475569}.zm-tb-btn:hover{background:#f1f5f9;color:#1e293b}.zm-tb-btn img{filter:invert(20%) sepia(15%) saturate(500%) hue-rotate(180deg);transition:filter .1s}.zm-tb-btn:hover img{filter:invert(15%) sepia(30%) saturate(800%) hue-rotate(180deg)}.zm-tb-btn.active{background:var(--zm-tb-active, #fff7ed);color:var(--zm-tb-active-fg, #c2410c)}.zm-tb-divider{width:1px;height:18px;background:#e2e8f0;margin:0 4px}.zm-tb-tip{font-size:12px;color:#64748b;min-width:38px;text-align:center}
|
package/dist/tree.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { MindMapNode } from './types';
|
|
2
|
+
export declare function uid(): string;
|
|
3
|
+
export declare function clone<T>(o: T): T;
|
|
4
|
+
export declare function findNode(root: MindMapNode, id: string): MindMapNode | null;
|
|
5
|
+
export declare function findParent(root: MindMapNode, id: string, parent?: MindMapNode | null): MindMapNode | null;
|
|
6
|
+
export declare function removeNode(root: MindMapNode, id: string): boolean;
|
|
7
|
+
/** Replace the text of a node by id. Returns true on success, false
|
|
8
|
+
* if the node was not found. No-op on an empty / same string. */
|
|
9
|
+
export declare function setNodeText(root: MindMapNode, id: string, text: string): boolean;
|
|
10
|
+
/** Position relative to a target node when moving a sibling. */
|
|
11
|
+
export type MovePosition = 'before' | 'after' | 'child';
|
|
12
|
+
/** Move a node to a new location in the tree.
|
|
13
|
+
* - 'before' / 'after': insert as a sibling of the target at that slot
|
|
14
|
+
* (target's parent's children array).
|
|
15
|
+
* - 'child': insert as the last child of the target.
|
|
16
|
+
* No-op (returns false) if src === root, or if the move would
|
|
17
|
+
* create a cycle (i.e. the target lives inside the src subtree, or
|
|
18
|
+
* src is already in the target's desired position). */
|
|
19
|
+
export declare function moveNode(root: MindMapNode, srcId: string, targetId: string, position: MovePosition): boolean;
|
|
20
|
+
export declare function addChild(root: MindMapNode, parentId: string, text?: string): MindMapNode | null;
|
|
21
|
+
export declare function addSibling(root: MindMapNode, nodeId: string, text?: string): MindMapNode | null;
|
|
22
|
+
/**
|
|
23
|
+
* Insert a new sibling node BEFORE the given node (Shift+Enter in xmind).
|
|
24
|
+
* Returns the new node, or null if the target is the root.
|
|
25
|
+
*/
|
|
26
|
+
export declare function addSiblingBefore(root: MindMapNode, nodeId: string, text?: string): MindMapNode | null;
|
|
27
|
+
/**
|
|
28
|
+
* Deep-clone a node (with all its descendants) and insert the copy as a
|
|
29
|
+
* sibling immediately after the original. New ids are generated so the
|
|
30
|
+
* result is a real duplicate. Returns the new node, or null if the
|
|
31
|
+
* target is the root.
|
|
32
|
+
*/
|
|
33
|
+
export declare function duplicateNode(root: MindMapNode, nodeId: string): MindMapNode | null;
|
|
34
|
+
export declare function countDescendants(n: MindMapNode): number;
|
|
35
|
+
export declare const DEFAULT_NEW_NODE_TEXT = "\u65B0\u8282\u70B9";
|
|
36
|
+
/**
|
|
37
|
+
* Parse a Markdown string into a MindMapNode tree. Each heading
|
|
38
|
+
* becomes a node; its level sets the depth.
|
|
39
|
+
* - `# Title` → root text (overrides `rootText`)
|
|
40
|
+
* - `## Sub` → child of the previous #/##/... heading
|
|
41
|
+
* - bullet / paragraph text between headings → first child
|
|
42
|
+
* of the preceding heading (so a `# Topic\n- detail` tree
|
|
43
|
+
* gives one root node with one child).
|
|
44
|
+
*
|
|
45
|
+
* Inline fields parsed from a heading's body (in order, attached
|
|
46
|
+
* to the heading that precedes them):
|
|
47
|
+
* - `` → image
|
|
48
|
+
* - `[label](url)` → link (label becomes the node's text)
|
|
49
|
+
* - ` ```note ... ``` ` → note (the fence body becomes note.text)
|
|
50
|
+
*
|
|
51
|
+
* Empty input, or input with no `#` heading, returns a single
|
|
52
|
+
* root with the fallback text.
|
|
53
|
+
*/
|
|
54
|
+
export declare function markdownToMindMap(md: string, rootText?: string): MindMapNode;
|
|
55
|
+
/**
|
|
56
|
+
* Round-trip-safe Markdown export of a MindMapNode tree. Each
|
|
57
|
+
* heading is emitted as `#…`, then any inline fields (link /
|
|
58
|
+
* image / note) in a fixed order so the same source produces
|
|
59
|
+
* byte-stable output across re-exports.
|
|
60
|
+
*
|
|
61
|
+
* The `note` field round-trips through a ` ```note ` fence so a
|
|
62
|
+
* user opening the export in any markdown editor sees a clearly
|
|
63
|
+
* labeled block. The link is emitted as a standard `[label](url)`
|
|
64
|
+
* with the node's text as the label — this keeps the export
|
|
65
|
+
* human-readable and lets `markdownToMindMap` re-attach the
|
|
66
|
+
* link to the right heading.
|
|
67
|
+
*/
|
|
68
|
+
export declare function mindMapToMarkdown(n: MindMapNode, depth?: number): string;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
export interface MindMapNode {
|
|
2
|
+
id: string;
|
|
3
|
+
text: string;
|
|
4
|
+
children: MindMapNode[];
|
|
5
|
+
collapsed?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Reserved for the layout algorithm — do not set or read from
|
|
8
|
+
* your own code. After a drag, MindMap writes the dragged
|
|
9
|
+
* node's offset into the data tree so a subsequent layout with
|
|
10
|
+
* `preservePositions: true` can keep the node where the user
|
|
11
|
+
* put it. Cleared on the next data-mutating action (add,
|
|
12
|
+
* remove, edit, import) so unrelated re-layouts don't keep
|
|
13
|
+
* stale overrides around.
|
|
14
|
+
*/
|
|
15
|
+
_x?: number;
|
|
16
|
+
_y?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Optional embedded image shown above the node text. The
|
|
19
|
+
* image is stored as either a remote URL (preferred) or a
|
|
20
|
+
* data: URL (fallback for local-file uploads); width/height
|
|
21
|
+
* reflect the rendered size, which the user can resize via
|
|
22
|
+
* a drag handle. naturalW/naturalH preserve the source
|
|
23
|
+
* aspect ratio so a resize keeps the original proportions.
|
|
24
|
+
*/
|
|
25
|
+
image?: MindMapImage;
|
|
26
|
+
/**
|
|
27
|
+
* Optional external link. When set, the node renders a
|
|
28
|
+
* small link icon next to its text; clicking the icon
|
|
29
|
+
* navigates to `url` in a new tab. No validation is
|
|
30
|
+
* performed at write time — the rendering layer is
|
|
31
|
+
* responsible for rejecting dangerous schemes (javascript:,
|
|
32
|
+
* data:, …) before following the link.
|
|
33
|
+
*/
|
|
34
|
+
link?: {
|
|
35
|
+
url: string;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Optional free-form note. When set, the node renders a
|
|
39
|
+
* small note icon next to its text; clicking the icon
|
|
40
|
+
* expands an inline textarea below the node for editing,
|
|
41
|
+
* hovering the icon shows a tooltip preview. An empty
|
|
42
|
+
* `text` field is treated as "no note" by the UI.
|
|
43
|
+
*/
|
|
44
|
+
note?: {
|
|
45
|
+
text: string;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export interface MindMapImage {
|
|
49
|
+
/** Remote URL or data URL. Always a string — never undefined. */
|
|
50
|
+
src: string;
|
|
51
|
+
/** Source image intrinsic size, in px. Used to lock aspect
|
|
52
|
+
* ratio during a user-driven resize. */
|
|
53
|
+
naturalW: number;
|
|
54
|
+
naturalH: number;
|
|
55
|
+
/** Current rendered size, in px. Drag handle writes to these
|
|
56
|
+
* fields. Clamped to a sane range by the layout (≥24, ≤400). */
|
|
57
|
+
width: number;
|
|
58
|
+
height: number;
|
|
59
|
+
}
|
|
60
|
+
export interface MindMapOptions {
|
|
61
|
+
data: MindMapNode;
|
|
62
|
+
readonly?: boolean;
|
|
63
|
+
theme?: MindMapTheme;
|
|
64
|
+
}
|
|
65
|
+
export interface MindMapTheme {
|
|
66
|
+
rootBg?: string;
|
|
67
|
+
rootText?: string;
|
|
68
|
+
branchBg?: string;
|
|
69
|
+
branchText?: string;
|
|
70
|
+
lineColor?: string;
|
|
71
|
+
bgColor?: string;
|
|
72
|
+
fontSize?: number;
|
|
73
|
+
/** Stroke width of SVG connecting paths at the *parent-end* of the
|
|
74
|
+
* edge, in px. Default 2.2. */
|
|
75
|
+
lineWidthStart?: number;
|
|
76
|
+
/** Stroke width at the *child-end* of the edge, in px. Default 0.8. */
|
|
77
|
+
lineWidthEnd?: number;
|
|
78
|
+
/**
|
|
79
|
+
* When true, each top-level branch gets its own color (root stays
|
|
80
|
+
* neutral, every child[0] of root takes a different hue, and that
|
|
81
|
+
* hue propagates down the subtree). Default false.
|
|
82
|
+
*/
|
|
83
|
+
rainbowBranch?: boolean;
|
|
84
|
+
}
|
|
85
|
+
export type LineStyle = 'curve' | 'straight';
|
|
86
|
+
export type LayoutMode = 'mindmap' | 'tree' | 'org';
|
|
87
|
+
/** Identifier for a branch palette — the id of a built-in (e.g.
|
|
88
|
+
* 'default', 'classic', 'vivid', 'dev', 'mint') or a user-defined
|
|
89
|
+
* custom palette. Strings rather than a string union so users
|
|
90
|
+
* can add their own ids without recompiling the type. */
|
|
91
|
+
export type BranchPaletteId = string;
|
|
92
|
+
/**
|
|
93
|
+
* A named 8-color palette cycled across top-level branches when
|
|
94
|
+
* `rainbowBranch` is on. Exposed in the public API so the library
|
|
95
|
+
* consumer can register their own scheme (e.g. a corporate brand
|
|
96
|
+
* palette) via `setBranchPalette` / `customPalettes`.
|
|
97
|
+
*/
|
|
98
|
+
export interface BranchPalette {
|
|
99
|
+
id: BranchPaletteId;
|
|
100
|
+
name: string;
|
|
101
|
+
/** Hex colors cycled across top-level branches, in display order.
|
|
102
|
+
* When a palette has fewer than the number of branches, colors
|
|
103
|
+
* wrap around with modulo. */
|
|
104
|
+
colors: string[];
|
|
105
|
+
}
|
|
106
|
+
export interface MindMapSettings {
|
|
107
|
+
/** When the user adds a new node or finishes a drag, automatically
|
|
108
|
+
* snap the layout back to balanced mode. Default false. */
|
|
109
|
+
autoBalanceOnChange: boolean;
|
|
110
|
+
/** Stroke width of SVG edges at the parent end. */
|
|
111
|
+
lineWidthStart: number;
|
|
112
|
+
/** Stroke width of SVG edges at the child end. */
|
|
113
|
+
lineWidthEnd: number;
|
|
114
|
+
/** Color-cycle the top-level branches. */
|
|
115
|
+
rainbowBranch: boolean;
|
|
116
|
+
/** Which named palette to use when rainbowBranch is on. Built-in
|
|
117
|
+
* ids: 'default' | 'classic' | 'vivid' | 'dev' | 'mint'. Any
|
|
118
|
+
* custom palette id in `customPalettes` is also valid. Default
|
|
119
|
+
* 'default'. */
|
|
120
|
+
branchPaletteId: BranchPaletteId;
|
|
121
|
+
/** User-defined palettes. The settings panel lets the user add,
|
|
122
|
+
* edit (via a textarea of hex codes), and delete entries. The
|
|
123
|
+
* canvas treats these as first-class palettes alongside the
|
|
124
|
+
* built-ins. Persisted by the host app. */
|
|
125
|
+
customPalettes: BranchPalette[];
|
|
126
|
+
/** Edge shape between parent and child. 'curve' = fish-gill bezier
|
|
127
|
+
* (xmind default), 'straight' = direct line segment. */
|
|
128
|
+
lineStyle: LineStyle;
|
|
129
|
+
/** Layout mode (1.html parity). 'mindmap' = center + left/right
|
|
130
|
+
* fans; 'tree' = single column expanding to the right; 'org' =
|
|
131
|
+
* downward hierarchy. Default 'mindmap'. */
|
|
132
|
+
layoutMode: LayoutMode;
|
|
133
|
+
/** When true (default), each edge tapers independently — its
|
|
134
|
+
* parent-end width comes from the parent node's tier and its
|
|
135
|
+
* child-end width comes from `lineWidthEnd`. Visually you get
|
|
136
|
+
* discrete ribbons where the parent side of a level-2 edge can
|
|
137
|
+
* be thicker than the child side of a level-1 edge.
|
|
138
|
+
* When false, the whole tree forms a single tapered band:
|
|
139
|
+
* every edge's parent end = the previous edge's child end, so
|
|
140
|
+
* widths interpolate continuously from root to leaves. */
|
|
141
|
+
taperedEdge: boolean;
|
|
142
|
+
/** When true, every node shows a small badge with its zero-based
|
|
143
|
+
* position in its parent's children array ("1.", "2.", "3.").
|
|
144
|
+
* Default false — useful when verifying the data-tree order
|
|
145
|
+
* against the visual layout. */
|
|
146
|
+
showOrderBadge: boolean;
|
|
147
|
+
}
|
|
148
|
+
export interface NodeStyle {
|
|
149
|
+
bg?: string;
|
|
150
|
+
textColor?: string;
|
|
151
|
+
borderColor?: string;
|
|
152
|
+
fontWeight?: 400 | 600;
|
|
153
|
+
}
|
|
154
|
+
export interface MindMapExpose {
|
|
155
|
+
addChild: (parentId: string) => void;
|
|
156
|
+
addSibling: (nodeId: string) => void;
|
|
157
|
+
removeNode: (nodeId: string) => void;
|
|
158
|
+
duplicateNode: (nodeId: string) => void;
|
|
159
|
+
/** Set a node's text (no-op if unchanged). Used by the outline
|
|
160
|
+
* panel's inline edit; the canvas has its own dblclick → input
|
|
161
|
+
* flow. */
|
|
162
|
+
setNodeText: (nodeId: string, text: string) => void;
|
|
163
|
+
/** Move a node to a new location. `position` is relative to
|
|
164
|
+
* `targetId`: 'before' / 'after' insert as siblings, 'child'
|
|
165
|
+
* makes it the last child of target. Used by the outline panel's
|
|
166
|
+
* drag-and-drop. Returns true on success, false (no-op) if the
|
|
167
|
+
* move would create a cycle or hit another invalid case. */
|
|
168
|
+
moveNode: (srcId: string, targetId: string, position: 'before' | 'after' | 'child') => boolean;
|
|
169
|
+
getData: () => MindMapNode;
|
|
170
|
+
setData: (data: MindMapNode) => void;
|
|
171
|
+
resetView: () => void;
|
|
172
|
+
exportData: () => string;
|
|
173
|
+
importData: (json: string) => boolean;
|
|
174
|
+
setBalanced: (value: boolean) => void;
|
|
175
|
+
isBalanced: () => boolean;
|
|
176
|
+
balance: () => void;
|
|
177
|
+
/** Apply or update the per-node style override (empty object clears it). */
|
|
178
|
+
applyNodeStyle: (nodeId: string, style: NodeStyle) => void;
|
|
179
|
+
/** Read the current per-node style override. */
|
|
180
|
+
getNodeStyle: (nodeId: string) => NodeStyle;
|
|
181
|
+
/** Set a node's external link. Pass an empty string to clear. */
|
|
182
|
+
applyNodeLink: (nodeId: string, url: string) => void;
|
|
183
|
+
/** Remove a node's link (no-op if absent). */
|
|
184
|
+
removeNodeLink: (nodeId: string) => void;
|
|
185
|
+
/** Set a node's note text. Pass an empty string to clear. */
|
|
186
|
+
applyNodeNote: (nodeId: string, text: string) => void;
|
|
187
|
+
/** Remove a node's note (no-op if absent). */
|
|
188
|
+
removeNodeNote: (nodeId: string) => void;
|
|
189
|
+
undo: () => void;
|
|
190
|
+
redo: () => void;
|
|
191
|
+
canUndo: () => boolean;
|
|
192
|
+
canRedo: () => boolean;
|
|
193
|
+
/** Apply a partial settings object — keys you omit are left as-is. */
|
|
194
|
+
applySettings: (s: Partial<MindMapSettings>) => void;
|
|
195
|
+
/** Read the current effective settings. */
|
|
196
|
+
getSettings: () => MindMapSettings;
|
|
197
|
+
/** Set the active branch palette by id. The id may be a built-in
|
|
198
|
+
* ('default' / 'classic' / 'vivid' / 'dev' / 'mint') or a custom
|
|
199
|
+
* palette id from `customPalettes`. No-op if the id is unknown. */
|
|
200
|
+
setBranchPalette: (id: BranchPaletteId) => void;
|
|
201
|
+
/** Read the active palette id. */
|
|
202
|
+
getBranchPalette: () => BranchPaletteId;
|
|
203
|
+
/** Read every palette the canvas knows about — built-ins first,
|
|
204
|
+
* then the user's custom palettes. Useful for the host app to
|
|
205
|
+
* render a picker. */
|
|
206
|
+
getBranchPalettes: () => BranchPalette[];
|
|
207
|
+
/** Stroke width used for the parent end of an edge that starts at
|
|
208
|
+
* a node of the given depth. Lets the canvas taper sharply
|
|
209
|
+
* (root → 1st → 2nd → 3rd+) instead of using a single global
|
|
210
|
+
* width. */
|
|
211
|
+
lineWidthForDepth: (depth: number) => number;
|
|
212
|
+
/** Stroke width used for the child end of an edge that ends at
|
|
213
|
+
* a node of the given depth. */
|
|
214
|
+
endWidthForDepth: (depth: number) => number;
|
|
215
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "flow-mindmap",
|
|
3
|
+
"version": "0.1.0-beta.1",
|
|
4
|
+
"description": "A modern, minimalist mind mapping tool — xmind-style, embeddable as a Vue component.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "xuze",
|
|
9
|
+
"email": "569552263@qq.com"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/xz333221/flow-mindmap.git"
|
|
14
|
+
},
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/xz333221/flow-mindmap/issues"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"mindmap",
|
|
20
|
+
"mind-map",
|
|
21
|
+
"xmind",
|
|
22
|
+
"vue",
|
|
23
|
+
"vue3",
|
|
24
|
+
"vite",
|
|
25
|
+
"svg",
|
|
26
|
+
"canvas",
|
|
27
|
+
"tree"
|
|
28
|
+
],
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"README.md",
|
|
32
|
+
"LICENSE"
|
|
33
|
+
],
|
|
34
|
+
"main": "./dist/flow-mindmap.umd.cjs",
|
|
35
|
+
"module": "./dist/flow-mindmap.js",
|
|
36
|
+
"types": "./dist/entry.d.ts",
|
|
37
|
+
"exports": {
|
|
38
|
+
".": {
|
|
39
|
+
"types": "./dist/entry.d.ts",
|
|
40
|
+
"import": "./dist/flow-mindmap.js",
|
|
41
|
+
"require": "./dist/flow-mindmap.umd.cjs"
|
|
42
|
+
},
|
|
43
|
+
"./style.css": "./dist/style.css"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"dev": "vite --port 7851 --strictPort",
|
|
47
|
+
"build:types": "vue-tsc -p tsconfig.build.json",
|
|
48
|
+
"build:lib": "vite build --mode lib",
|
|
49
|
+
"build": "pnpm build:types && pnpm build:lib",
|
|
50
|
+
"preview": "vite preview --port 7852",
|
|
51
|
+
"typecheck": "vue-tsc --noEmit",
|
|
52
|
+
"lint": "eslint . --ext .vue,.ts,.js --max-warnings 0",
|
|
53
|
+
"test": "vitest run",
|
|
54
|
+
"test:watch": "vitest"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"vue": "^3.4.0"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@types/node": "^25.9.1",
|
|
61
|
+
"@vitejs/plugin-vue": "^5.1.4",
|
|
62
|
+
"happy-dom": "^20.10.1",
|
|
63
|
+
"playwright": "^1.60.0",
|
|
64
|
+
"typescript": "^5.6.3",
|
|
65
|
+
"vite": "^5.4.10",
|
|
66
|
+
"vitest": "3.2.4",
|
|
67
|
+
"vue": "^3.5.12",
|
|
68
|
+
"vue-tsc": "^2.1.10"
|
|
69
|
+
}
|
|
70
|
+
}
|