kakidash 0.0.1 → 0.0.3
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.d.ts +14 -3
- package/dist/kakidash.cjs +48 -0
- package/dist/kakidash.es.js +211 -156
- package/dist/kakidash.umd.js +3 -3
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,11 @@ export declare class Kakidash extends TypedEventEmitter<KakidashEventMap> {
|
|
|
9
9
|
private layoutSwitcher;
|
|
10
10
|
private layoutMode;
|
|
11
11
|
private selectedNodeId;
|
|
12
|
+
/**
|
|
13
|
+
* Flag to track if we just created a node via UI interaction and are waiting for edit completion
|
|
14
|
+
* to emit the final model:change event.
|
|
15
|
+
*/
|
|
16
|
+
private pendingNodeCreation;
|
|
12
17
|
private panX;
|
|
13
18
|
private panY;
|
|
14
19
|
private targetPanX;
|
|
@@ -21,17 +26,23 @@ export declare class Kakidash extends TypedEventEmitter<KakidashEventMap> {
|
|
|
21
26
|
* Adds a new child node to the specified parent.
|
|
22
27
|
* This is a pure data operation and does not trigger UI actions like auto-focus or scroll.
|
|
23
28
|
*/
|
|
24
|
-
addNode(parentId: string, topic?: string, layoutSide?: 'left' | 'right'
|
|
29
|
+
addNode(parentId: string, topic?: string, layoutSide?: 'left' | 'right', options?: {
|
|
30
|
+
emitChange?: boolean;
|
|
31
|
+
}): Node_2 | null;
|
|
25
32
|
/**
|
|
26
33
|
* Adds a sibling node relative to the reference node.
|
|
27
34
|
* This is a pure data operation.
|
|
28
35
|
*/
|
|
29
|
-
addSibling(referenceId: string, position?: 'before' | 'after', topic?: string
|
|
36
|
+
addSibling(referenceId: string, position?: 'before' | 'after', topic?: string, options?: {
|
|
37
|
+
emitChange?: boolean;
|
|
38
|
+
}): Node_2 | null;
|
|
30
39
|
/**
|
|
31
40
|
* Inserts a parent node above the specified node.
|
|
32
41
|
* This is a pure data operation.
|
|
33
42
|
*/
|
|
34
|
-
insertParent(targetId: string, topic?: string
|
|
43
|
+
insertParent(targetId: string, topic?: string, options?: {
|
|
44
|
+
emitChange?: boolean;
|
|
45
|
+
}): Node_2 | null;
|
|
35
46
|
/**
|
|
36
47
|
* Removes a node.
|
|
37
48
|
* This is a pure data operation.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";var Q=Object.defineProperty;var ee=(v,t,e)=>t in v?Q(v,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):v[t]=e;var c=(v,t,e)=>ee(v,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class te{constructor(t){c(this,"root");c(this,"theme","default");this.root=t}findNode(t){return this.findNodeRecursive(this.root,t)}findNodeRecursive(t,e){if(t.id===e)return t;for(const i of t.children){const s=this.findNodeRecursive(i,e);if(s)return s}return null}moveNode(t,e){const i=this.findNode(t),s=this.findNode(e);if(!i||!s||i.isRoot||i.parentId===e||this.isDescendant(i,e))return!1;if(i.parentId){const n=this.findNode(i.parentId);n&&n.removeChild(t)}return s.addChild(i),!0}addSibling(t,e,i){const s=this.findNode(t);if(!s||!s.parentId)return!1;const n=this.findNode(s.parentId);if(!n)return!1;const r=n.children.findIndex(a=>a.id===t);if(r===-1)return!1;const o=i==="before"?r:r+1;return n.insertChild(e,o),!0}insertParent(t,e){const i=this.findNode(t);if(!i||!i.parentId)return!1;const s=this.findNode(i.parentId);if(!s)return!1;const n=s.children.findIndex(r=>r.id===t);return n===-1?!1:(s.removeChild(t),s.insertChild(e,n),e.addChild(i),!0)}isDescendant(t,e){if(t.id===e)return!0;for(const i of t.children)if(this.isDescendant(i,e))return!0;return!1}}class C{constructor(t,e,i=null,s=!1,n,r){c(this,"id");c(this,"topic");c(this,"children");c(this,"style");c(this,"parentId");c(this,"isRoot");c(this,"image");c(this,"layoutSide");this.id=t,this.topic=e,this.children=[],this.style={fontSize:s?"24px":"16px"},this.parentId=i,this.isRoot=s,this.image=n,this.layoutSide=r}addChild(t){t.parentId=this.id,this.children.push(t)}insertChild(t,e){t.parentId=this.id,e>=0&&e<=this.children.length?this.children.splice(e,0,t):this.children.push(t)}removeChild(t){this.children=this.children.filter(e=>e.id!==t)}updateTopic(t){this.topic=t}}class ie{constructor(t=10){c(this,"past",[]);c(this,"future",[]);c(this,"maxHistorySize");this.maxHistorySize=t}push(t){this.past.push(t),this.past.length>this.maxHistorySize&&this.past.shift(),this.future=[]}undo(t){if(this.past.length===0)return null;const e=this.past.pop();return e?(this.future.push(t),e):null}get canUndo(){return this.past.length>0}redo(t){if(this.future.length===0)return null;const e=this.future.pop();return e?(this.past.push(t),this.past.length>this.maxHistorySize&&this.past.shift(),e):null}get canRedo(){return this.future.length>0}clear(){this.past=[],this.future=[]}}class se{constructor(t){c(this,"mindMap");c(this,"historyManager");c(this,"clipboard",null);this.mindMap=t,this.historyManager=new ie(10)}saveState(){this.historyManager.push(this.exportData())}undo(){const t=this.historyManager.undo(this.exportData());return t?(this.importData(t),!0):!1}get canUndo(){return this.historyManager.canUndo}addNode(t,e="New topic",i){const s=this.mindMap.findNode(t);if(!s)return null;this.saveState();const n=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),r=new C(n,e,null,!1,void 0,i);return s.addChild(r),r}addImageNode(t,e){const i=this.mindMap.findNode(t);if(!i)return null;this.saveState();const s=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),n=new C(s,"",t,!1,e);return i.addChild(n),n}removeNode(t,e=!0){const i=this.mindMap.findNode(t);if(!i||i.isRoot||!i.parentId)return!1;const s=this.mindMap.findNode(i.parentId);return s?(e&&this.saveState(),s.removeChild(t),!0):!1}updateNodeTopic(t,e){const i=this.mindMap.findNode(t);return i?(this.saveState(),i.updateTopic(e),!0):!1}updateNodeStyle(t,e){const i=this.mindMap.findNode(t);return i?(this.saveState(),i.style={...i.style,...e},!0):!1}setTheme(t){this.mindMap.theme!==t&&(this.saveState(),this.mindMap.theme=t)}moveNode(t,e,i){const s=this.mindMap.findNode(t);if(s&&s.parentId===e)return i&&s.layoutSide!==i?(this.saveState(),s.layoutSide=i,!0):!1;if(!s)return!1;if(this.saveState(),this.mindMap.moveNode(t,e)){if(i){const n=this.mindMap.findNode(t);n&&(n.layoutSide=i)}return!0}return!1}addSibling(t,e,i="New topic"){const s=this.mindMap.findNode(t);if(!s||!s.parentId)return null;this.saveState();const n=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),r=new C(n,i);return this.mindMap.addSibling(t,r,e)?r:null}reorderNode(t,e,i){const s=this.mindMap.findNode(t),n=this.mindMap.findNode(e);if(!s||!n||!n.parentId||s.id===n.id||s.isRoot)return!1;const r=this.mindMap.findNode(n.parentId);if(!r)return!1;if(this.saveState(),s.parentId!==r.id){let d=r;for(;d.parentId;){if(d.id===s.id)return!1;if(!d.parentId)break;const h=this.mindMap.findNode(d.parentId);if(!h)break;d=h}}if(s.parentId&&s.parentId!==r.id){const d=this.mindMap.findNode(s.parentId);d&&d.removeChild(s.id),s.parentId=r.id}else s.parentId===r.id&&r.removeChild(s.id);const o=r.children.findIndex(d=>d.id===e);if(o===-1)return r.addChild(s),!0;const a=i==="before"?o:o+1;return r.insertChild(s,a),r.isRoot&&n.layoutSide&&(s.layoutSide=n.layoutSide),!0}insertNodeAsParent(t,e){const i=this.mindMap.findNode(t),s=this.mindMap.findNode(e);if(!i||!s||!s.parentId||i.id===s.id)return!1;const n=this.mindMap.findNode(s.parentId);if(!n)return!1;let r=n;for(;r;){if(r.id===i.id)return!1;if(!r.parentId)break;r=this.mindMap.findNode(r.parentId)}if(this.saveState(),i.parentId){const a=this.mindMap.findNode(i.parentId);a&&a.removeChild(i.id)}const o=n.children.findIndex(a=>a.id===e);return o===-1?!1:(n.isRoot&&s.layoutSide&&(i.layoutSide=s.layoutSide),n.removeChild(e),n.insertChild(i,o),i.parentId=n.id,i.addChild(s),!0)}insertParent(t,e="New topic"){const i=this.mindMap.findNode(t);if(!i||!i.parentId)return null;this.saveState();const s=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),n=new C(s,e);return this.mindMap.insertParent(t,n)?n:null}copyNode(t){const e=this.mindMap.findNode(t);e&&(this.clipboard=this.deepCloneNode(e),navigator.clipboard&&navigator.clipboard.writeText(e.topic).catch(i=>{console.error("Failed to write to clipboard",i)}))}cutNode(t){const e=this.mindMap.findNode(t);e&&!e.isRoot&&e.parentId&&(this.copyNode(t),this.removeNode(t))}pasteNode(t){if(!this.clipboard)return null;const e=this.mindMap.findNode(t);if(!e)return null;this.saveState();const i=this.deepCloneNode(this.clipboard);return this.regenerateIds(i),e.addChild(i),i}deepCloneNode(t){const e=new C(t.id,t.topic,null,!1,t.image,t.layoutSide);return e.style={...t.style},e.children=t.children.map(i=>this.deepCloneNode(i)),e.children.forEach(i=>i.parentId=e.id),e}regenerateIds(t){t.id=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),t.children.forEach(e=>{e.parentId=t.id,this.regenerateIds(e)})}exportData(){const t=e=>({id:e.id,topic:e.topic,root:e.isRoot||void 0,children:e.children.length>0?e.children.map(t):void 0,style:Object.keys(e.style).length>0?e.style:void 0,image:e.image,layoutSide:e.layoutSide});return{nodeData:t(this.mindMap.root),theme:this.mindMap.theme}}importData(t){const e=(i,s=null)=>{const n=!!i.root,r=new C(i.id,i.topic,s,n,i.image,i.layoutSide);return i.style&&(r.style={...i.style}),i.children&&i.children.length>0&&i.children.forEach(o=>{const a=e(o,r.id);r.addChild(a)}),r};this.mindMap.root=e(t.nodeData),t.theme&&(this.mindMap.theme=t.theme)}}const E=class E{constructor(t,e={}){c(this,"container");c(this,"svg");c(this,"nodeContainer");c(this,"options");this.container=t,this.container.style.position="relative",this.container.style.width="100%",this.container.style.height="100%",this.container.style.overflow="hidden",this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.position="absolute",this.svg.style.top="0",this.svg.style.left="0",this.svg.style.width="100%",this.svg.style.height="100%",this.svg.style.zIndex="0",this.svg.style.pointerEvents="none",this.svg.style.overflow="visible",this.svg.style.transformOrigin="0 0",this.container.appendChild(this.svg),this.nodeContainer=document.createElement("div"),this.nodeContainer.style.position="absolute",this.nodeContainer.style.top="0",this.nodeContainer.style.left="0",this.nodeContainer.style.width="100%",this.nodeContainer.style.height="100%",this.nodeContainer.style.zIndex="1",this.nodeContainer.style.transformOrigin="0 0",this.container.appendChild(this.nodeContainer),this.options=e}render(t,e=null,i="Right"){this.svg.innerHTML="",this.nodeContainer.innerHTML="",this.renderNode(t.root,0,this.container.clientHeight/2,e,i,!0,void 0,t)}updateTransform(t,e,i=1){const s=`translate(${t}px, ${e}px) scale(${i})`;this.svg.style.transform=s,this.nodeContainer.style.transform=s}getThemeColor(t,e){if(e.theme==="colorful"){if(t.isRoot)return"#333";let i=t;for(;i.parentId&&i.parentId!==e.root.id;){const r=e.findNode(i.parentId);if(!r)break;i=r}const n=e.root.children.findIndex(r=>r.id===i.id);if(n!==-1)return E.RAINBOW_PALETTE[n%E.RAINBOW_PALETTE.length]}return"#ccc"}renderNode(t,e,i,s,n,r,o="right",a){const d=document.createElement("div");if(d.dataset.id=t.id,t.image){const m=document.createElement("img");m.src=t.image,m.style.maxWidth="150px",m.style.maxHeight="150px",m.style.display="block",d.appendChild(m);const u=document.createElement("div");u.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="11" y1="8" x2="11" y2="14"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>',u.style.position="absolute",u.style.bottom="5px",u.style.right="5px",u.style.backgroundColor="rgba(255, 255, 255, 0.9)",u.style.borderRadius="50%",u.style.width="24px",u.style.height="24px",u.style.display="flex",u.style.justifyContent="center",u.style.alignItems="center",u.style.cursor="pointer",u.title="Zoom Image",u.style.boxShadow="0 1px 3px rgba(0,0,0,0.2)",d.appendChild(u),u.addEventListener("click",x=>{x.stopPropagation(),this.showImageModal(t.image)}),d.style.padding="5px"}else d.textContent=t.topic,d.style.whiteSpace="pre";d.className="mindmap-node",t.isRoot||(d.draggable=!0),d.style.position="absolute",d.style.padding="8px 12px",t.image&&(d.style.padding="5px"),d.style.backgroundColor="white";const h=(a==null?void 0:a.theme)||"default",f=a?this.getThemeColor(t,a):"#ccc";h==="simple"&&!t.isRoot?d.style.border="none":h==="colorful"?d.style.border=`2px solid ${f}`:d.style.border="1px solid #ccc",d.style.borderRadius="4px",t.isRoot&&(d.style.fontSize="1.2em",d.style.fontWeight="bold",d.style.border="2px solid #333"),t.style.color&&(d.style.color=t.style.color),t.style.fontSize&&(d.style.fontSize=t.style.fontSize),t.style.fontWeight&&(d.style.fontWeight=t.style.fontWeight),t.style.fontStyle&&(d.style.fontStyle=t.style.fontStyle),t.style.background&&(d.style.backgroundColor=t.style.background);const{width:p}=this.measureNode(t);let l=e;if(o==="left"&&!r?l=e-p:r&&(l=e-p/2),d.style.left=`${l}px`,d.style.top=`${i}px`,d.style.transform="translate(0, -50%)",d.style.zIndex="10",d.style.cursor="default",d.style.userSelect="none",t.id===s&&(d.style.outline="2px solid #007bff",d.style.boxShadow="0 0 5px rgba(0, 123, 255, 0.5)"),this.nodeContainer.appendChild(d),t.children.length===0)return;let y=[],g=[];r&&n==="Both"?t.children.forEach((m,u)=>{(m.layoutSide||(u%2===0?"right":"left"))==="right"?y.push(m):g.push(m)}):n==="Left"?g=t.children:n==="Right"?y=t.children:o==="left"?g=t.children:y=t.children,y.length>0&&this.renderChildrenStack(t,y,e,i,s,n,"right",p,a),g.length>0&&this.renderChildrenStack(t,g,e,i,s,n,"left",p,a)}renderChildrenStack(t,e,i,s,n,r,o,a,d){const h=e.reduce((y,g)=>y+this.getNodeHeight(g),0);let f=s-h/2;const p=80;let l=0;t.isRoot?l=o==="right"?i+a/2:i-a/2:o==="right"?l=i+a:(l=i,l=i-a),e.forEach(y=>{const g=this.getNodeHeight(y),m=f+g/2;let u=0;o==="right"?u=l+p:u=l-p,this.renderNode(y,u,m,n,r,!1,o,d);const x=d?this.getThemeColor(y,d):"#ccc";this.drawConnection(l,s,u,m,x),f+=g})}getChildrenHeight(t){return t.children.reduce((e,i)=>e+this.getNodeHeight(i),0)}getNodeHeight(t){const{height:e}=this.measureNode(t),i=20;if(t.children.length===0)return e+i;const s=this.getChildrenHeight(t);return Math.max(e+i,s)}measureNode(t){if(t.image)return{width:160,height:160};const e=document.createElement("div");e.textContent=t.topic,e.className="mindmap-node",e.style.visibility="hidden",e.style.position="absolute",e.style.whiteSpace="pre",e.style.padding="8px 12px",e.style.border="1px solid #ccc",t.isRoot&&(e.style.fontSize="1.2em",e.style.fontWeight="bold",e.style.border="2px solid #333"),t.style.color&&(e.style.color=t.style.color),t.style.fontSize&&(e.style.fontSize=t.style.fontSize),t.style.fontWeight&&(e.style.fontWeight=t.style.fontWeight),t.style.fontStyle&&(e.style.fontStyle=t.style.fontStyle),t.style.background&&(e.style.backgroundColor=t.style.background),this.nodeContainer.appendChild(e);const i=e.offsetWidth,s=e.offsetHeight;return this.nodeContainer.removeChild(e),{width:i||100,height:s||40}}drawConnection(t,e,i,s,n="#ccc"){const r=document.createElementNS("http://www.w3.org/2000/svg","path"),o=t+(i-t)/2,a=t+(i-t)/2,d=`M ${t} ${e} C ${o} ${e}, ${a} ${s}, ${i} ${s}`;r.setAttribute("d",d),r.setAttribute("stroke",n),r.setAttribute("fill","none"),r.setAttribute("stroke-width","2"),this.svg.appendChild(r)}showImageModal(t){this.options.onImageZoom&&this.options.onImageZoom(!0);const e=document.createElement("div");e.style.position="fixed",e.style.top="0",e.style.left="0",e.style.width="100vw",e.style.height="100vh",e.style.backgroundColor="rgba(0,0,0,0.8)",e.style.zIndex="1000",e.style.display="flex",e.style.justifyContent="center",e.style.alignItems="center",e.style.cursor="zoom-out";const i=document.createElement("img");i.src=t,i.style.maxWidth="90%",i.style.maxHeight="90%",i.style.boxShadow="0 0 20px rgba(0,0,0,0.5)",e.appendChild(i),document.body.appendChild(e);let s;const n=()=>{document.body.contains(e)&&document.body.removeChild(e),s&&document.removeEventListener("keydown",s,!0),this.options.onImageZoom&&this.options.onImageZoom(!1),this.container.focus()};s=r=>{r.stopPropagation(),r.preventDefault(),n()},document.addEventListener("keydown",s,!0),e.addEventListener("click",()=>{n()})}};c(E,"RAINBOW_PALETTE",["#E74C3C","#3498DB","#2ECC71","#F1C40F","#9B59B6","#E67E22","#1ABC9C"]);let T=E;const S=class S{constructor(t){c(this,"container");c(this,"editorEl");c(this,"currentNodeId",null);c(this,"onUpdate");this.container=t,this.editorEl=this.createEditor(),this.container.appendChild(this.editorEl),this.editorEl.addEventListener("mousedown",e=>e.stopPropagation()),this.editorEl.addEventListener("click",e=>e.stopPropagation()),this.editorEl.addEventListener("dblclick",e=>e.stopPropagation())}createEditor(){const t=document.createElement("div");t.className="style-editor",t.style.position="absolute",t.style.top="20px",t.style.right="20px",t.style.display="none",t.style.backgroundColor="white",t.style.border="1px solid #eee",t.style.borderRadius="8px",t.style.padding="8px",t.style.boxShadow="0 4px 12px rgba(0,0,0,0.1)",t.style.zIndex="2000",t.style.pointerEvents="auto",t.style.fontFamily="Arial, sans-serif",t.style.display="flex",t.style.flexDirection="column",t.style.gap="8px",t.style.margin="0",t.style.boxSizing="border-box",t.style.minWidth="220px";const e=document.createElement("div");e.style.display="flex",e.style.gap="8px",e.style.alignItems="center";const i=document.createElement("select");i.style.padding="4px 8px",i.style.borderRadius="4px",i.style.border="1px solid #ccc",i.style.fontSize="14px",i.style.flex="1",S.FONT_SIZES.forEach(h=>{const f=document.createElement("option");f.value=h.value,f.textContent=h.label,i.appendChild(f)}),i.onchange=h=>{this.currentNodeId&&this.onUpdate&&this.onUpdate(this.currentNodeId,{fontSize:h.target.value})},e.appendChild(i);const n=(h,f,p)=>{const l=document.createElement("button");return l.textContent=h,l.style.width="32px",l.style.height="32px",l.style.padding="0",l.style.display="flex",l.style.justifyContent="center",l.style.alignItems="center",l.style.border="1px solid #ddd",l.style.backgroundColor="#f5f5f5",l.style.borderRadius="4px",l.style.cursor="pointer",l.style.fontSize="14px",f&&(l.style[f]=f==="fontWeight"?"bold":"italic"),l.onclick=p,l},r=n("B","fontWeight",()=>{if(this.currentNodeId&&this.onUpdate){const h=r.classList.contains("active"),f=h?"normal":"bold";this.onUpdate(this.currentNodeId,{fontWeight:f}),this.updateButtonState(r,!h)}}),o=n("I","fontStyle",()=>{if(this.currentNodeId&&this.onUpdate){const h=o.classList.contains("active"),f=h?"normal":"italic";this.onUpdate(this.currentNodeId,{fontStyle:f}),this.updateButtonState(o,!h)}});e.appendChild(r),e.appendChild(o),t.appendChild(e);const a=document.createElement("div");a.style.display="flex",a.style.gap="4px",a.style.alignItems="center",a.style.justifyContent="space-between";const d=document.createElement("input");return d.type="color",d.style.width="24px",d.style.height="24px",d.style.border="1px solid #ccc",d.style.padding="0",d.style.backgroundColor="transparent",d.style.cursor="pointer",d.style.appearance="none",d.onchange=h=>{this.currentNodeId&&this.onUpdate&&(this.onUpdate(this.currentNodeId,{color:h.target.value}),this.updateActivePaletteItem(h.target.value))},S.PALETTE.forEach((h,f)=>{const p=document.createElement("div");p.className="color-swatch",p.dataset.color=h,p.textContent=(f+1).toString(),p.style.width="24px",p.style.height="24px",p.style.backgroundColor=h,p.style.borderRadius="4px",p.style.cursor="pointer",p.style.border="1px solid transparent",p.style.color=h==="#F1C40F"?"black":"white",p.style.fontSize="12px",p.style.fontWeight="bold",p.style.display="flex",p.style.justifyContent="center",p.style.alignItems="center",p.onclick=()=>{this.currentNodeId&&this.onUpdate&&(this.onUpdate(this.currentNodeId,{color:h}),d.value=h,this.updateActivePaletteItem(h))},a.appendChild(p)}),a.appendChild(d),t.appendChild(a),t}updateActivePaletteItem(t){this.editorEl.querySelectorAll(".color-swatch").forEach(i=>{var n;const s=i;((n=s.dataset.color)==null?void 0:n.toLowerCase())===t.toLowerCase()?(s.style.border="2px solid #ccc",s.style.transform="scale(1.1)"):(s.style.border="1px solid transparent",s.style.transform="scale(1)")})}updateButtonState(t,e){e?(t.classList.add("active"),t.style.backgroundColor="#e0e0e0",t.style.borderColor="#999"):(t.classList.remove("active"),t.style.backgroundColor="#f5f5f5",t.style.borderColor="#ddd")}show(t,e){this.currentNodeId=t,this.editorEl.style.display="flex";const i=this.editorEl.querySelector("select");i.value=e.fontSize||"";const s=this.editorEl.querySelector('input[type="color"]'),n=e.color||"#000000";s.value=n,this.updateActivePaletteItem(n);const r=this.editorEl.querySelectorAll("button")[0];this.updateButtonState(r,e.fontWeight==="bold");const o=this.editorEl.querySelectorAll("button")[1];this.updateButtonState(o,e.fontStyle==="italic")}hide(){this.editorEl.style.display="none",this.currentNodeId=null}};c(S,"FONT_SIZES",[{label:"12px",value:"12px"},{label:"14px",value:"14px"},{label:"16px",value:"16px"},{label:"18px",value:"18px"},{label:"24px",value:"24px"},{label:"32px",value:"32px"},{label:"48px",value:"48px"}]),c(S,"PALETTE",["#000000","#E74C3C","#E67E22","#F1C40F","#2ECC71","#3498DB","#9B59B6"]);let w=S;class ne{constructor(t,e){c(this,"container");c(this,"element");c(this,"options");c(this,"currentMode","Right");c(this,"currentTheme","default");c(this,"layoutButtons",new Map);c(this,"themeButtons",new Map);this.container=t,this.options=e,this.element=document.createElement("div"),this.render()}render(){this.element.style.position="absolute",this.element.style.top="20px",this.element.style.left="20px",this.element.style.display="flex",this.element.style.flexDirection="column",this.element.style.backgroundColor="white",this.element.style.borderRadius="8px",this.element.style.boxShadow="0 2px 10px rgba(0,0,0,0.1)",this.element.style.padding="5px",this.element.style.zIndex="2000",this.element.style.gap="5px",this.element.style.pointerEvents="auto",this.element.addEventListener("click",t=>t.stopPropagation()),this.element.addEventListener("mousedown",t=>t.stopPropagation()),this.createLayoutButton("Right",this.getRightIcon()),this.createLayoutButton("Left",this.getLeftIcon()),this.createLayoutButton("Both",this.getBothIcon()),this.addSeparator(),this.createThemeButton("default",this.getThemeDefaultIcon()),this.createThemeButton("simple",this.getThemeSimpleIcon()),this.createThemeButton("colorful",this.getThemeColorfulIcon()),this.addSeparator(),this.createIconActionButton("Reset Zoom",this.getZoomResetIcon(),()=>{this.options.onZoomReset&&this.options.onZoomReset()}),this.container.appendChild(this.element),this.updateActiveButtons()}addSeparator(){const t=document.createElement("div");t.style.height="1px",t.style.backgroundColor="#ccc",t.style.margin="5px 2px",this.element.appendChild(t)}createLayoutButton(t,e){const i=document.createElement("button");i.innerHTML=e,this.styleButton(i),i.title=`Layout: ${t}`,i.addEventListener("click",()=>{this.setMode(t)}),this.element.appendChild(i),this.layoutButtons.set(t,i)}createThemeButton(t,e){const i=document.createElement("button");i.innerHTML=e,this.styleButton(i),i.title=`Theme: ${t}`,i.addEventListener("click",()=>{this.setTheme(t)}),this.element.appendChild(i),this.themeButtons.set(t,i)}createIconActionButton(t,e,i){const s=document.createElement("button");s.innerHTML=e,this.styleButton(s),s.title=t,s.addEventListener("click",i),this.element.appendChild(s)}styleButton(t){t.style.width="32px",t.style.height="32px",t.style.border="none",t.style.background="transparent",t.style.cursor="pointer",t.style.borderRadius="4px",t.style.display="flex",t.style.alignItems="center",t.style.justifyContent="center",t.style.color="#555"}updateActiveButtons(){this.layoutButtons.forEach((t,e)=>{e===this.currentMode?(t.style.backgroundColor="#e6f7ff",t.style.color="#007bff"):(t.style.backgroundColor="transparent",t.style.color="#555")}),this.themeButtons.forEach((t,e)=>{e===this.currentTheme?(t.style.backgroundColor="#e6f7ff",t.style.color="#007bff"):(t.style.backgroundColor="transparent",t.style.color="#555")})}setMode(t){this.currentMode!==t&&(this.currentMode=t,this.updateActiveButtons(),this.options.onLayoutChange(t))}setTheme(t){this.currentTheme!==t&&(this.currentTheme=t,this.updateActiveButtons(),this.options.onThemeChange(t))}getRightIcon(){return`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<circle cx="5" cy="12" r="3"></circle>
|
|
3
|
+
<path d="M8 12h8"></path>
|
|
4
|
+
<path d="M8 12 L16 5"></path>
|
|
5
|
+
<path d="M8 12 L16 19"></path>
|
|
6
|
+
<circle cx="19" cy="5" r="2"></circle>
|
|
7
|
+
<circle cx="19" cy="12" r="2"></circle>
|
|
8
|
+
<circle cx="19" cy="19" r="2"></circle>
|
|
9
|
+
</svg>`}getLeftIcon(){return`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
10
|
+
<circle cx="19" cy="12" r="3"></circle>
|
|
11
|
+
<path d="M16 12h-8"></path>
|
|
12
|
+
<path d="M16 12 L8 5"></path>
|
|
13
|
+
<path d="M16 12 L8 19"></path>
|
|
14
|
+
<circle cx="5" cy="5" r="2"></circle>
|
|
15
|
+
<circle cx="5" cy="12" r="2"></circle>
|
|
16
|
+
<circle cx="5" cy="19" r="2"></circle>
|
|
17
|
+
</svg>`}getBothIcon(){return'<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M12 9V5"></path><circle cx="12" cy="2" r="2"></circle><path d="M12 15v4"></path><circle cx="12" cy="22" r="2"></circle><path d="M9 12H5"></path><circle cx="2" cy="12" r="2"></circle><path d="M15 12h4"></path><circle cx="22" cy="12" r="2"></circle></svg>'}getThemeDefaultIcon(){return`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
18
|
+
<rect x="3" y="3" width="18" height="18" rx="4" ry="4" top="3" />
|
|
19
|
+
<line x1="8" y1="12" x2="16" y2="12" />
|
|
20
|
+
</svg>`}getThemeSimpleIcon(){return`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
21
|
+
<line x1="4" y1="6" x2="20" y2="6" />
|
|
22
|
+
<line x1="4" y1="12" x2="20" y2="12" />
|
|
23
|
+
<line x1="4" y1="18" x2="20" y2="18" />
|
|
24
|
+
</svg>`}getThemeColorfulIcon(){return`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
25
|
+
<path d="M12 2C6.477 2 2 6.477 2 12c0 4.418 2.865 8.167 6.839 9.49.5.166.86-.2.86-.677v-.36c0-.46.38-.853.84-.853h1.76c1.93 0 3.5-1.57 3.5-3.5 0-.54.42-1 .99-1h.26c2.6 0 4.75-1.95 4.94-4.5C22.25 6.7 17.65 2 12 2z" />
|
|
26
|
+
<circle cx="7.5" cy="8.5" r="1.5" fill="currentColor" stroke="none" />
|
|
27
|
+
<circle cx="12.5" cy="6.5" r="1.5" fill="currentColor" stroke="none" />
|
|
28
|
+
<circle cx="16.5" cy="9.5" r="1.5" fill="currentColor" stroke="none" />
|
|
29
|
+
</svg>`}getZoomResetIcon(){return`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
30
|
+
<circle cx="11" cy="11" r="8"></circle>
|
|
31
|
+
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
|
32
|
+
<line x1="5" y1="5" x2="17" y2="17"></line>
|
|
33
|
+
<line x1="17" y1="5" x2="5" y2="17"></line>
|
|
34
|
+
</svg>`}}class oe{constructor(t,e){c(this,"container");c(this,"options");c(this,"selectedNodeId",null);c(this,"draggedNodeId",null);c(this,"isPanning",!1);c(this,"lastMouseX",0);c(this,"lastMouseY",0);c(this,"isReadOnly",!1);c(this,"cleanupFns",[]);this.container=t,this.container.tabIndex=0,this.container.style.outline="none",this.container.style.cursor="default",this.options=e,this.attachEvents()}setReadOnly(t){this.isReadOnly=t,t&&this.draggedNodeId&&(this.draggedNodeId=null)}destroy(){this.cleanupFns.forEach(t=>t()),this.cleanupFns=[]}updateSelection(t){this.selectedNodeId=t}attachEvents(){let t=null;const e=(r,o,a,d)=>{r.addEventListener(o,a,d),this.cleanupFns.push(()=>{typeof r.removeEventListener=="function"&&r.removeEventListener(o,a,d)})};e(this.container,"focus",()=>{}),e(this.container,"blur",()=>{}),e(this.container,"scroll",()=>{(this.container.scrollTop!==0||this.container.scrollLeft!==0)&&(this.container.scrollTop=0,this.container.scrollLeft=0)}),e(this.container,"click",r=>{const a=r.target.closest(".mindmap-node");a&&a.dataset.id?this.options.onNodeClick(a.dataset.id):this.options.onNodeClick(""),this.container.focus()}),e(this.container,"mousedown",r=>{const o=r,a=o.target;!a.closest(".mindmap-node")&&a.tagName!=="INPUT"&&(this.isPanning=!0,this.lastMouseX=o.clientX,this.lastMouseY=o.clientY,this.container.style.cursor="all-scroll")}),e(window,"mousemove",r=>{const o=r;if(this.isPanning){const a=o.clientX-this.lastMouseX,d=o.clientY-this.lastMouseY;this.lastMouseX=o.clientX,this.lastMouseY=o.clientY,this.options.onPan&&this.options.onPan(a,d)}});const i=()=>{this.isPanning&&(this.isPanning=!1,this.container.style.cursor="default")};e(window,"mouseup",i),e(window,"mouseleave",i),e(this.container,"wheel",r=>{const o=r;if(o.preventDefault(),o.ctrlKey||o.metaKey){this.options.onZoom&&this.options.onZoom(o.deltaY,o.clientX,o.clientY);return}let a=1;o.deltaMode===1?a=33:o.deltaMode===2&&(a=window.innerHeight);const d=-o.deltaX*a,h=-o.deltaY*a;this.options.onPan&&this.options.onPan(d,h)},{passive:!1}),e(document,"keydown",r=>{var h,f,p,l,y,g,m,u,x,I,L,B,D,P,A,O,z,U,X,Y,H,K,F,W,Z,$;const o=r,a=["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","h","j","k","l"],d=["Tab","Enter","Delete","Backspace"];if(!this.selectedNodeId){if(a.includes(o.key)){o.preventDefault();let N=null,b=1/0;this.container.querySelectorAll(".mindmap-node").forEach(q=>{const R=q;if(!R.dataset.id)return;const k=R.getBoundingClientRect(),V=k.left+k.width/2,_=k.top+k.height/2,M=this.container.getBoundingClientRect(),G=M.left+M.width/2,J=M.top+M.height/2,j=Math.pow(V-G,2)+Math.pow(_-J,2);j<b&&(b=j,N=R.dataset.id)}),N&&this.options.onNodeClick(N)}return}if(!(this.isReadOnly&&!["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","h","j","k","l","c"].includes(o.key))){switch((d.includes(o.key)||a.includes(o.key))&&o.preventDefault(),o.key){case"Tab":if(this.isReadOnly)return;o.shiftKey?(f=(h=this.options).onInsertParent)==null||f.call(h,this.selectedNodeId):this.options.onAddChild(this.selectedNodeId);break;case"Enter":if(this.isReadOnly)return;this.options.onAddSibling(this.selectedNodeId,o.shiftKey?"before":"after");break;case"Delete":case"Backspace":if(this.isReadOnly)return;this.options.onDeleteNode(this.selectedNodeId);break;case"ArrowUp":case"k":(this.isReadOnly||!o.ctrlKey&&!o.metaKey&&!o.altKey)&&((l=(p=this.options).onNavigate)==null||l.call(p,this.selectedNodeId,"Up"));break;case"ArrowDown":case"j":(this.isReadOnly||!o.ctrlKey&&!o.metaKey&&!o.altKey)&&((g=(y=this.options).onNavigate)==null||g.call(y,this.selectedNodeId,"Down"));break;case"ArrowLeft":case"h":(this.isReadOnly||!o.ctrlKey&&!o.metaKey&&!o.altKey)&&((u=(m=this.options).onNavigate)==null||u.call(m,this.selectedNodeId,"Left"));break;case"ArrowRight":case"l":(this.isReadOnly||!o.ctrlKey&&!o.metaKey&&!o.altKey)&&((I=(x=this.options).onNavigate)==null||I.call(x,this.selectedNodeId,"Right"));break;case"F2":{if(this.isReadOnly)return;o.preventDefault();const N=this.container.querySelector(`.mindmap-node[data-id="${this.selectedNodeId}"]`);if(N){if(N.querySelector("img"))return;this.startEditing(N,this.selectedNodeId)}break}case"c":(o.metaKey||o.ctrlKey)&&(o.preventDefault(),(B=(L=this.options).onCopyNode)==null||B.call(L,this.selectedNodeId));break;case"v":if(this.isReadOnly)return;(o.metaKey||o.ctrlKey)&&(t&&clearTimeout(t),t=setTimeout(()=>{var N,b;this.selectedNodeId&&((b=(N=this.options).onPasteNode)==null||b.call(N,this.selectedNodeId))},50));break;case"x":if(this.isReadOnly)return;(o.metaKey||o.ctrlKey)&&(o.preventDefault(),(P=(D=this.options).onCutNode)==null||P.call(D,this.selectedNodeId));break;case"z":if(this.isReadOnly)return;(o.metaKey||o.ctrlKey)&&(o.preventDefault(),o.shiftKey||(O=(A=this.options).onUndo)==null||O.call(A));break;case"b":if(this.isReadOnly)return;(o.metaKey||o.ctrlKey)&&(o.preventDefault(),(U=(z=this.options).onStyleAction)==null||U.call(z,this.selectedNodeId,{type:"bold"}));break;case"i":{if(this.isReadOnly)return;if(o.metaKey||o.ctrlKey)o.preventDefault(),(Y=(X=this.options).onStyleAction)==null||Y.call(X,this.selectedNodeId,{type:"italic"});else{o.preventDefault();const N=this.container.querySelector(`.mindmap-node[data-id="${this.selectedNodeId}"]`);if(N){if(N.querySelector("img"))return;this.startEditing(N,this.selectedNodeId)}}break}case" ":if(this.isReadOnly)return;o.preventDefault();{const N=this.container.querySelector(`.mindmap-node[data-id="${this.selectedNodeId}"]`);if(N){const b=N.querySelector('[title="Zoom Image"]');b&&b.click()}}break;case"+":case"=":if(this.isReadOnly)return;(o.key==="+"||o.key==="="&&o.shiftKey)&&((K=(H=this.options).onStyleAction)==null||K.call(H,this.selectedNodeId,{type:"increaseSize"}));break;case"-":if(this.isReadOnly)return;(W=(F=this.options).onStyleAction)==null||W.call(F,this.selectedNodeId,{type:"decreaseSize"});break}if(/^[1-7]$/.test(o.key)){if(this.isReadOnly)return;if(!o.ctrlKey&&!o.metaKey&&!o.altKey){const N=parseInt(o.key)-1;($=(Z=this.options).onStyleAction)==null||$.call(Z,this.selectedNodeId,{type:"color",index:N})}}}}),e(document,"paste",r=>{var h,f,p,l,y;const o=r;if(t&&(clearTimeout(t),t=null),this.isReadOnly||!this.selectedNodeId)return;const a=(h=o.clipboardData)==null?void 0:h.items;if(!a||a.length===0){(p=(f=this.options).onPasteNode)==null||p.call(f,this.selectedNodeId);return}let d=!1;for(const g of a)if(g.type.startsWith("image/")){const m=g.getAsFile();if(m){const u=new FileReader;u.onload=x=>{var I;(I=x.target)!=null&&I.result&&this.options.onPasteImage&&this.selectedNodeId&&this.options.onPasteImage(this.selectedNodeId,x.target.result)},u.readAsDataURL(m)}o.preventDefault(),d=!0;break}d||(y=(l=this.options).onPasteNode)==null||y.call(l,this.selectedNodeId)});const s=document.createElement("style");s.textContent=`
|
|
35
|
+
.mindmap-node.drag-over-top {
|
|
36
|
+
border-top: 4px solid #007bff !important;
|
|
37
|
+
}
|
|
38
|
+
.mindmap-node.drag-over-bottom {
|
|
39
|
+
border-bottom: 4px solid #007bff !important;
|
|
40
|
+
}
|
|
41
|
+
.mindmap-node.drag-over-left {
|
|
42
|
+
border-left: 4px solid #007bff !important;
|
|
43
|
+
}
|
|
44
|
+
.mindmap-node.drag-over-right {
|
|
45
|
+
border-right: 4px solid #007bff !important;
|
|
46
|
+
}
|
|
47
|
+
`,document.head.appendChild(s),this.container.addEventListener("dragstart",r=>{var d;if(this.isReadOnly){r.preventDefault();return}const a=r.target.closest(".mindmap-node");a&&a.dataset.id&&(this.draggedNodeId=a.dataset.id,(d=r.dataTransfer)==null||d.setData("text/plain",a.dataset.id),r.dataTransfer&&(r.dataTransfer.effectAllowed="move"))}),this.cleanupFns.push(()=>{});const n=(r,o)=>{const a=o.getBoundingClientRect(),d=r.clientX-a.left,h=r.clientY-a.top,f=a.width,p=a.height;return h<p*.25?"top":h>p*.75?"bottom":d<f*.25?"left":(d>f*.75,"right")};e(this.container,"dragstart",r=>{var h;const o=r;if(this.isReadOnly){o.preventDefault();return}const d=o.target.closest(".mindmap-node");d&&d.dataset.id&&(this.draggedNodeId=d.dataset.id,(h=o.dataTransfer)==null||h.setData("text/plain",d.dataset.id),o.dataTransfer&&(o.dataTransfer.effectAllowed="move"))}),e(this.container,"dragover",r=>{const o=r;if(this.isReadOnly)return;o.preventDefault();const d=o.target.closest(".mindmap-node");if(d&&d.dataset.id&&this.draggedNodeId&&d.dataset.id!==this.draggedNodeId){const h=n(o,d);d.classList.remove("drag-over-top","drag-over-bottom","drag-over-left","drag-over-right"),d.classList.add(`drag-over-${h}`),o.dataTransfer&&(o.dataTransfer.dropEffect="move")}}),e(this.container,"dragleave",r=>{const a=r.target.closest(".mindmap-node");a&&a.classList.remove("drag-over-top","drag-over-bottom","drag-over-left","drag-over-right")}),e(this.container,"drop",r=>{const o=r;o.preventDefault();const d=o.target.closest(".mindmap-node");if(this.container.querySelectorAll(".mindmap-node").forEach(h=>{h.classList.remove("drag-over-top","drag-over-bottom","drag-over-left","drag-over-right")}),!this.isReadOnly){if(d&&d.dataset.id&&this.draggedNodeId){const h=d.dataset.id;if(this.draggedNodeId!==h){const f=n(o,d);this.options.onDropNode(this.draggedNodeId,h,f)}}this.draggedNodeId=null}}),e(this.container,"dragend",()=>{this.draggedNodeId=null,this.container.querySelectorAll(".mindmap-node").forEach(r=>{r.classList.remove("drag-over-top","drag-over-bottom","drag-over-left","drag-over-right")})}),e(this.container,"dblclick",r=>{if(this.isReadOnly)return;const a=r.target.closest(".mindmap-node");a&&a.dataset.id&&this.startEditing(a,a.dataset.id)})}editNode(t){const e=this.container.querySelector(`.mindmap-node[data-id="${t}"]`);e&&this.startEditing(e,t)}startEditing(t,e){const i=t.textContent||"",s=document.createElement("textarea");s.value=i,s.style.position="absolute",s.style.top=t.style.top,s.style.left=t.style.left,s.style.transform=t.style.transform,s.style.overflow="hidden",s.style.resize="none",s.style.minHeight="1em";const n=window.getComputedStyle(t);s.style.font=n.font,s.style.padding=n.padding,s.style.boxSizing="border-box",s.style.backgroundColor=n.backgroundColor,s.style.border="none",s.style.outline="none",s.style.boxShadow="none",s.style.borderTop=n.borderTop,s.style.borderRight=n.borderRight,s.style.borderBottom=n.borderBottom,s.style.borderLeft=n.borderLeft,s.style.borderRadius=n.borderRadius,s.style.zIndex="100";const r=t.style.outline,o=t.style.boxShadow;t.style.outline="none",t.style.boxShadow="none";const a=()=>{const l=document.createElement("span");l.style.font=n.font,l.style.padding=n.padding,l.style.whiteSpace="pre-wrap",l.style.visibility="hidden",l.style.position="absolute",l.textContent=s.value||"",(s.value.endsWith(`
|
|
48
|
+
`)||s.value==="")&&(l.textContent+=""),document.body.appendChild(l);const y=l.offsetWidth+20,g=l.offsetHeight+10;s.style.width=Math.max(y,t.offsetWidth)+"px",s.style.height=Math.max(g,t.offsetHeight)+"px",document.body.removeChild(l)};a(),s.addEventListener("input",a);let d=!1;const h=()=>{s.parentNode&&s.parentNode.contains(s)&&s.parentNode.removeChild(s),t.style.outline=r,t.style.boxShadow=o},f=()=>{if(d)return;d=!0;const l=s.value;l!==i&&this.options.onUpdateNode&&this.options.onUpdateNode(e,l),h(),this.options.onEditEnd&&this.options.onEditEnd(e)};s.addEventListener("blur",()=>{d||f()});const p=()=>{d||(d=!0,d=!0,h(),this.options.onEditEnd&&this.options.onEditEnd(e))};s.addEventListener("keydown",l=>{if(l.stopPropagation(),!l.isComposing)if(l.key==="Enter"){if(l.shiftKey)return;l.preventDefault(),f()}else l.key==="Escape"&&(l.preventDefault(),p())}),t.parentElement?t.parentElement.appendChild(s):this.container.appendChild(s),s.focus({preventScroll:!0}),s.select()}}class re{constructor(){c(this,"listeners",{})}on(t,e){var i;this.listeners[t]||(this.listeners[t]=[]),(i=this.listeners[t])==null||i.push(e)}addListener(t,e){this.on(t,e)}off(t,e){const i=this.listeners[t];i&&(this.listeners[t]=i.filter(s=>s!==e))}removeListener(t,e){this.off(t,e)}emit(t,e){var i;(i=this.listeners[t])==null||i.forEach(s=>s(e))}}class de extends re{constructor(e){super();c(this,"mindMap");c(this,"service");c(this,"renderer");c(this,"interactionHandler");c(this,"styleEditor");c(this,"layoutSwitcher");c(this,"layoutMode","Right");c(this,"selectedNodeId",null);c(this,"pendingNodeCreation",!1);c(this,"panX",0);c(this,"panY",0);c(this,"targetPanX",0);c(this,"targetPanY",0);c(this,"scale",1);c(this,"isBatching",!1);c(this,"animationFrameId",null);const i=new C("root","Root Topic",null,!0);this.mindMap=new te(i),this.service=new se(this.mindMap),this.renderer=new T(e,{onImageZoom:n=>this.setReadOnly(n)});const s=document.createElement("div");s.style.position="absolute",s.style.top="0",s.style.left="0",s.style.width="100%",s.style.height="100%",s.style.pointerEvents="none",s.style.zIndex="2000",e.style.overscrollBehavior="none",e.style.touchAction="none",e.appendChild(s),this.styleEditor=new w(s),this.styleEditor.onUpdate=(n,r)=>{this.interactionHandler.isReadOnly||this.service.updateNodeStyle(n,r)&&(this.render(),this.emit("model:change",void 0))},this.panX=e.clientWidth/2,this.targetPanX=this.panX,this.targetPanY=this.panY,this.layoutSwitcher=new ne(s,{onLayoutChange:n=>this.setLayoutMode(n),onThemeChange:n=>this.setTheme(n),onZoomReset:()=>this.resetZoom()}),this.startAnimationLoop(),this.interactionHandler=new oe(e,{onNodeClick:n=>this.selectNode(n||null),onAddChild:n=>this.addChildNode(n),onInsertParent:n=>this.insertParentNode(n),onAddSibling:(n,r)=>this.addSiblingNode(n,r),onDeleteNode:n=>this.removeNode(n),onDropNode:(n,r,o)=>this.moveNode(n,r,o),onUpdateNode:(n,r)=>this.updateNodeTopic(n,r),onNavigate:(n,r)=>this.navigateNode(n,r),onPan:(n,r)=>this.panBoard(n,r),onCopyNode:n=>this.copyNode(n),onPasteNode:n=>this.pasteNode(n),onCutNode:n=>this.cutNode(n),onPasteImage:(n,r)=>this.pasteImage(n,r),onZoom:(n,r,o)=>this.zoomBoard(n,r,o),onUndo:()=>{this.service.undo()&&(this.render(),this.emit("model:change",void 0))},onStyleAction:(n,r)=>{if(this.interactionHandler.isReadOnly)return;const o=this.mindMap.findNode(n);if(!o)return;const a=o.style||{};let d=null;if(r.type==="bold")d={fontWeight:a.fontWeight==="bold"?"normal":"bold"};else if(r.type==="italic")d={fontStyle:a.fontStyle==="italic"?"normal":"italic"};else if(r.type==="color")r.index>=0&&r.index<w.PALETTE.length&&(d={color:w.PALETTE[r.index]});else if(r.type==="increaseSize"||r.type==="decreaseSize"){const h=w.FONT_SIZES,f=a.fontSize||"";let p=h.findIndex(y=>y.value===f);p===-1&&(p=0);let l=p;r.type==="increaseSize"?l=Math.min(h.length-1,p+1):l=Math.max(0,p-1),l!==p&&(d={fontSize:h[l].value})}d&&this.service.updateNodeStyle(n,d)&&(this.render(),this.emit("model:change",void 0),this.selectedNodeId===n&&this.styleEditor.show(n,{...a,...d}))},onEditEnd:n=>{this.pendingNodeCreation&&(this.pendingNodeCreation=!1,this.emit("model:change",void 0))}}),this.render()}addNode(e,i,s,n={emitChange:!0}){const r=this.service.addNode(e,i,s);return r&&(this.render(),this.emit("node:add",{id:r.id,topic:r.topic}),n.emitChange&&this.emit("model:change",void 0)),r}addSibling(e,i="after",s="New topic",n={emitChange:!0}){const r=this.mindMap.findNode(e);if(!r||!r.parentId)return null;const o=this.mindMap.findNode(r.parentId);o&&o.isRoot&&this.layoutMode==="Both"&&this.ensureExplicitLayoutSides(o);const a=this.service.addSibling(e,i,s);if(a){if(o&&o.isRoot&&this.layoutMode==="Both"){const d=r.layoutSide||(o.children.indexOf(r)%2===0?"right":"left");a.layoutSide=d}this.render(),this.emit("node:add",{id:a.id,topic:a.topic}),n.emitChange&&this.emit("model:change",void 0)}return a}insertParent(e,i="New topic",s={emitChange:!0}){const n=this.service.insertParent(e,i);return n&&(this.render(),this.emit("node:add",{id:n.id,topic:n.topic}),s.emitChange&&this.emit("model:change",void 0)),n}deleteNode(e){this.service.removeNode(e)&&(this.render(),this.emit("node:remove",e),this.emit("model:change",void 0))}updateNode(e,i){let s=!1;this.interactionHandler.isReadOnly||(i.topic!==void 0&&this.service.updateNodeTopic(e,i.topic)&&(s=!0),i.style!==void 0&&this.service.updateNodeStyle(e,i.style)&&(s=!0),s&&(this.render(),i.topic!==void 0&&this.emit("node:update",{id:e,topic:i.topic}),this.emit("model:change",void 0),this.pendingNodeCreation&&(this.pendingNodeCreation=!1)))}updateNodeStyle(e,i){this.service.updateNodeStyle(e,i)}setTheme(e){this.service.setTheme(e),this.layoutSwitcher.setTheme(e),this.render(),this.emit("model:change",void 0)}getMindMap(){return this.mindMap}getNode(e){return this.mindMap.findNode(e)||void 0}getRoot(){return this.mindMap.root}findNodes(e){const i=[],s=n=>{e(n)&&i.push(n),n.children.forEach(s)};return s(this.mindMap.root),i}setReadOnly(e){this.interactionHandler.setReadOnly(e),e&&this.styleEditor.hide()}destroy(){this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.interactionHandler.destroy(),this.renderer.container}batch(e){this.isBatching=!0;try{e()}finally{this.isBatching=!1,this.render()}}addChildNode(e){const i=this.mindMap.findNode(e);i&&i.isRoot&&this.layoutMode==="Both"&&this.ensureExplicitLayoutSides(i);let s;if(this.layoutMode==="Both"&&i&&i.isRoot){let r=0,o=0;i.children.forEach((a,d)=>{(a.layoutSide||(d%2===0?"right":"left"))==="left"?r++:o++}),s=r<o?"left":"right"}this.pendingNodeCreation=!0;const n=this.addNode(e,"New topic",s,{emitChange:!1});n&&(this.selectNode(n.id),this.ensureNodeVisible(n.id),this.interactionHandler.editNode(n.id))}addSiblingNode(e,i="after"){this.pendingNodeCreation=!0;const s=this.addSibling(e,i,"New topic",{emitChange:!1});s&&(this.selectNode(s.id),this.ensureNodeVisible(s.id),this.interactionHandler.editNode(s.id))}insertParentNode(e){this.pendingNodeCreation=!0;const i=this.insertParent(e,"New topic",{emitChange:!1});i&&(this.selectNode(i.id),this.ensureNodeVisible(i.id),this.interactionHandler.editNode(i.id))}removeNode(e){const i=this.mindMap.findNode(e),s=(i==null?void 0:i.parentId)||null,n=this.selectedNodeId===e;this.deleteNode(e),n&&s&&this.selectNode(s)}ensureExplicitLayoutSides(e){!e.isRoot||this.layoutMode!=="Both"||e.children.forEach((i,s)=>{i.layoutSide||(i.layoutSide=s%2===0?"right":"left")})}moveNode(e,i,s){const n=this.mindMap.findNode(i);if(n){if(s==="top"){if(n.isRoot)return;this.service.reorderNode(e,i,"before")}else if(s==="bottom"){if(n.isRoot)return;this.service.reorderNode(e,i,"after")}else if(n.isRoot){const r=s==="left"?"left":"right";this.service.moveNode(e,i,r)}else{const r=this.getNodeDirection(n);let o="addChild";r==="right"?s==="right"?o="addChild":o="insertParent":s==="left"?o="addChild":o="insertParent",o==="addChild"?this.service.moveNode(e,i):this.service.insertNodeAsParent(e,i)}this.render(),this.emit("node:move",{nodeId:e,newParentId:i,position:s}),this.emit("model:change",void 0)}}updateNodeTopic(e,i){this.updateNode(e,{topic:i}),setTimeout(()=>this.ensureNodeVisible(e),0)}selectNode(e){if(this.selectedNodeId!==e){if(this.selectedNodeId=e,this.interactionHandler.updateSelection(e),e){const i=this.mindMap.findNode(e);i&&(!i.image&&!this.interactionHandler.isReadOnly?this.styleEditor.show(e,i.style):this.styleEditor.hide())}else this.styleEditor.hide();this.render(),this.emit("node:select",e)}}panBoard(e,i){this.targetPanX+=e,this.targetPanY+=i}zoomBoard(e,i,s){const a=this.renderer.container.getBoundingClientRect(),d=i-a.left,h=s-a.top,f=Math.min(Math.max(this.scale*(1-e*.001),.1),5),p=d-(d-this.panX)*(f/this.scale),l=h-(h-this.panY)*(f/this.scale);this.panX=p,this.panY=l,this.targetPanX=p,this.targetPanY=l,this.scale=f,this.renderer.updateTransform(this.panX,this.panY,this.scale)}resetZoom(){this.scale=1,this.panX=this.renderer.container.clientWidth/2,this.panY=0,this.targetPanX=this.panX,this.targetPanY=this.panY,this.render()}copyNode(e){this.service.copyNode(e)}pasteNode(e){const i=this.service.pasteNode(e);i&&(this.render(),this.selectNode(i.id),this.emit("node:add",{id:i.id,topic:i.topic}),this.emit("model:change",void 0),setTimeout(()=>this.ensureNodeVisible(i.id,!0),0))}pasteImage(e,i){const s=this.service.addImageNode(e,i);s&&(this.render(),this.selectNode(s.id),this.emit("node:add",{id:s.id,topic:""}),this.emit("model:change",void 0),setTimeout(()=>this.ensureNodeVisible(s.id,!0),0))}cutNode(e){const i=this.mindMap.findNode(e);if(i){const s=i.parentId;this.service.cutNode(e),this.selectNode(s),this.render(),this.emit("node:remove",e),this.emit("model:change",void 0)}}render(){this.isBatching||(this.renderer.render(this.mindMap,this.selectedNodeId,this.layoutMode),this.renderer.updateTransform(this.panX,this.panY,this.scale))}updateLayout(e){e==="Standard"?this.setLayoutMode("Both"):this.setLayoutMode(e)}setLayoutMode(e){this.layoutMode=e,this.layoutSwitcher.setMode(e);const i=this.renderer.container.clientWidth;e==="Right"?this.panX=i*.2:e==="Left"?this.panX=i*.8:this.panX=i*.5,this.panY=0,this.targetPanX=this.panX,this.targetPanY=this.panY,this.render()}getLayoutMode(){return this.layoutMode}navigateNode(e,i){const s=this.mindMap.findNode(e);if(s){switch(i){case"Left":if(s.isRoot){let n;this.layoutMode==="Left"?n=s.children[0]:this.layoutMode==="Both"&&(n=s.children.find((r,o)=>(r.layoutSide||(o%2!==0?"left":"right"))==="left")),n&&this.selectNode(n.id)}else s.parentId&&(this.getNodeDirection(s)==="right"?this.selectNode(s.parentId):s.children.length>0&&this.selectNode(s.children[0].id));break;case"Right":if(s.isRoot){let n;this.layoutMode==="Right"?n=s.children[0]:this.layoutMode==="Both"&&(n=s.children.find((r,o)=>(r.layoutSide||(o%2===0?"right":"left"))==="right")),n&&this.selectNode(n.id)}else s.parentId&&(this.getNodeDirection(s)==="right"?s.children.length>0&&this.selectNode(s.children[0].id):this.selectNode(s.parentId));break;case"Up":if(s.parentId){const n=this.mindMap.findNode(s.parentId);if(n){const r=this.getNodeDirection(s),o=n.children.filter(d=>this.getNodeDirection(d)===r),a=o.findIndex(d=>d.id===e);a>0&&this.selectNode(o[a-1].id)}}break;case"Down":if(s.parentId){const n=this.mindMap.findNode(s.parentId);if(n){const r=this.getNodeDirection(s),o=n.children.filter(d=>this.getNodeDirection(d)===r),a=o.findIndex(d=>d.id===e);a!==-1&&a<o.length-1&&this.selectNode(o[a+1].id)}}break}this.selectedNodeId&&this.selectedNodeId!==e&&setTimeout(()=>this.ensureNodeVisible(this.selectedNodeId,!0),0)}}getData(){return this.service.exportData()}loadData(e){try{this.service.importData(e),this.selectNode(null),this.render(),this.emit("model:load",e),e.theme&&this.layoutSwitcher.setTheme(e.theme),this.emit("model:change",void 0)}catch(i){console.error("Failed to load data",i)}}getRootId(){return this.mindMap.root.id}getNodeDirection(e){if(e.isRoot||this.layoutMode==="Right")return"right";if(this.layoutMode==="Left")return"left";let i=e;for(;i.parentId;){const s=this.mindMap.findNode(i.parentId);if(!s)break;if(s.isRoot)return i.layoutSide?i.layoutSide:s.children.findIndex(r=>r.id===i.id)%2===0?"right":"left";i=s}return"right"}startAnimationLoop(){let e=performance.now();const i=()=>{const s=performance.now(),n=(s-e)/1e3;e=s;const r=1-Math.exp(-8*n),o=this.targetPanX-this.panX,a=this.targetPanY-this.panY;Math.abs(o)>.1||Math.abs(a)>.1?(this.panX+=o*r,this.panY+=a*r,this.renderer.updateTransform(this.panX,this.panY,this.scale)):(this.panX!==this.targetPanX||this.panY!==this.targetPanY)&&(this.panX=this.targetPanX,this.panY=this.targetPanY,this.renderer.updateTransform(this.panX,this.panY,this.scale)),Number.isNaN(this.panX)&&(this.panX=0),Number.isNaN(this.panY)&&(this.panY=0),this.animationFrameId=requestAnimationFrame(i)};i()}ensureNodeVisible(e,i=!1){const s=this.renderer.container.querySelector(`.mindmap-node[data-id="${e}"]`);if(!s)return;const n=s.getBoundingClientRect(),r=this.renderer.container.getBoundingClientRect(),o=50;let a=0,d=0;const h=n.left<r.left+o,f=n.right>r.right-o,p=n.top<r.top+o,l=n.bottom>r.bottom-o;if(i&&(h||f||p||l)){const y=n.left+n.width/2,g=n.top+n.height/2,m=r.left+r.width/2,u=r.top+r.height/2;a=m-y,d=u-g}else h?a=r.left+o-n.left:f&&(a=r.right-o-n.right),p?d=r.top+o-n.top:l&&(d=r.bottom-o-n.bottom);(a!==0||d!==0)&&this.panBoard(a,d)}}exports.Kakidash=de;
|
package/dist/kakidash.es.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var c = (
|
|
4
|
-
class
|
|
1
|
+
var Q = Object.defineProperty;
|
|
2
|
+
var ee = (v, t, e) => t in v ? Q(v, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : v[t] = e;
|
|
3
|
+
var c = (v, t, e) => ee(v, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
class te {
|
|
5
5
|
constructor(t) {
|
|
6
6
|
c(this, "root");
|
|
7
7
|
c(this, "theme", "default");
|
|
@@ -54,7 +54,7 @@ class j {
|
|
|
54
54
|
return !1;
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
class
|
|
57
|
+
class C {
|
|
58
58
|
constructor(t, e, i = null, s = !1, n, r) {
|
|
59
59
|
c(this, "id");
|
|
60
60
|
c(this, "topic");
|
|
@@ -79,7 +79,7 @@ class b {
|
|
|
79
79
|
this.topic = t;
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
class
|
|
82
|
+
class ie {
|
|
83
83
|
constructor(t = 10) {
|
|
84
84
|
c(this, "past", []);
|
|
85
85
|
c(this, "future", []);
|
|
@@ -112,12 +112,12 @@ class Z {
|
|
|
112
112
|
this.past = [], this.future = [];
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
-
class
|
|
115
|
+
class se {
|
|
116
116
|
constructor(t) {
|
|
117
117
|
c(this, "mindMap");
|
|
118
118
|
c(this, "historyManager");
|
|
119
119
|
c(this, "clipboard", null);
|
|
120
|
-
this.mindMap = t, this.historyManager = new
|
|
120
|
+
this.mindMap = t, this.historyManager = new ie(10);
|
|
121
121
|
}
|
|
122
122
|
saveState() {
|
|
123
123
|
this.historyManager.push(this.exportData());
|
|
@@ -129,18 +129,18 @@ class V {
|
|
|
129
129
|
get canUndo() {
|
|
130
130
|
return this.historyManager.canUndo;
|
|
131
131
|
}
|
|
132
|
-
addNode(t, e = "New
|
|
132
|
+
addNode(t, e = "New topic", i) {
|
|
133
133
|
const s = this.mindMap.findNode(t);
|
|
134
134
|
if (!s) return null;
|
|
135
135
|
this.saveState();
|
|
136
|
-
const n = typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : Date.now().toString(36) + Math.random().toString(36).substr(2), r = new
|
|
136
|
+
const n = typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : Date.now().toString(36) + Math.random().toString(36).substr(2), r = new C(n, e, null, !1, void 0, i);
|
|
137
137
|
return s.addChild(r), r;
|
|
138
138
|
}
|
|
139
139
|
addImageNode(t, e) {
|
|
140
140
|
const i = this.mindMap.findNode(t);
|
|
141
141
|
if (!i) return null;
|
|
142
142
|
this.saveState();
|
|
143
|
-
const s = typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : Date.now().toString(36) + Math.random().toString(36).substr(2), n = new
|
|
143
|
+
const s = typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : Date.now().toString(36) + Math.random().toString(36).substr(2), n = new C(s, "", t, !1, e);
|
|
144
144
|
return i.addChild(n), n;
|
|
145
145
|
}
|
|
146
146
|
removeNode(t, e = !0) {
|
|
@@ -174,11 +174,11 @@ class V {
|
|
|
174
174
|
}
|
|
175
175
|
return !1;
|
|
176
176
|
}
|
|
177
|
-
addSibling(t, e, i = "New
|
|
177
|
+
addSibling(t, e, i = "New topic") {
|
|
178
178
|
const s = this.mindMap.findNode(t);
|
|
179
179
|
if (!s || !s.parentId) return null;
|
|
180
180
|
this.saveState();
|
|
181
|
-
const n = typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : Date.now().toString(36) + Math.random().toString(36).substr(2), r = new
|
|
181
|
+
const n = typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : Date.now().toString(36) + Math.random().toString(36).substr(2), r = new C(n, i);
|
|
182
182
|
return this.mindMap.addSibling(t, r, e) ? r : null;
|
|
183
183
|
}
|
|
184
184
|
reorderNode(t, e, i) {
|
|
@@ -224,11 +224,11 @@ class V {
|
|
|
224
224
|
const o = n.children.findIndex((a) => a.id === e);
|
|
225
225
|
return o === -1 ? !1 : (n.isRoot && s.layoutSide && (i.layoutSide = s.layoutSide), n.removeChild(e), n.insertChild(i, o), i.parentId = n.id, i.addChild(s), !0);
|
|
226
226
|
}
|
|
227
|
-
insertParent(t, e = "New
|
|
227
|
+
insertParent(t, e = "New topic") {
|
|
228
228
|
const i = this.mindMap.findNode(t);
|
|
229
229
|
if (!i || !i.parentId) return null;
|
|
230
230
|
this.saveState();
|
|
231
|
-
const s = typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : Date.now().toString(36) + Math.random().toString(36).substr(2), n = new
|
|
231
|
+
const s = typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : Date.now().toString(36) + Math.random().toString(36).substr(2), n = new C(s, e);
|
|
232
232
|
return this.mindMap.insertParent(t, n) ? n : null;
|
|
233
233
|
}
|
|
234
234
|
copyNode(t) {
|
|
@@ -250,7 +250,7 @@ class V {
|
|
|
250
250
|
return this.regenerateIds(i), e.addChild(i), i;
|
|
251
251
|
}
|
|
252
252
|
deepCloneNode(t) {
|
|
253
|
-
const e = new
|
|
253
|
+
const e = new C(t.id, t.topic, null, !1, t.image, t.layoutSide);
|
|
254
254
|
return e.style = { ...t.style }, e.children = t.children.map((i) => this.deepCloneNode(i)), e.children.forEach((i) => i.parentId = e.id), e;
|
|
255
255
|
}
|
|
256
256
|
regenerateIds(t) {
|
|
@@ -275,7 +275,7 @@ class V {
|
|
|
275
275
|
}
|
|
276
276
|
importData(t) {
|
|
277
277
|
const e = (i, s = null) => {
|
|
278
|
-
const n = !!i.root, r = new
|
|
278
|
+
const n = !!i.root, r = new C(i.id, i.topic, s, n, i.image, i.layoutSide);
|
|
279
279
|
return i.style && (r.style = { ...i.style }), i.children && i.children.length > 0 && i.children.forEach((o) => {
|
|
280
280
|
const a = e(o, r.id);
|
|
281
281
|
r.addChild(a);
|
|
@@ -284,12 +284,13 @@ class V {
|
|
|
284
284
|
this.mindMap.root = e(t.nodeData), t.theme && (this.mindMap.theme = t.theme);
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
|
-
const
|
|
288
|
-
constructor(t) {
|
|
287
|
+
const E = class E {
|
|
288
|
+
constructor(t, e = {}) {
|
|
289
289
|
c(this, "container");
|
|
290
290
|
c(this, "svg");
|
|
291
291
|
c(this, "nodeContainer");
|
|
292
|
-
|
|
292
|
+
c(this, "options");
|
|
293
|
+
this.container = t, this.container.style.position = "relative", this.container.style.width = "100%", this.container.style.height = "100%", this.container.style.overflow = "hidden", this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), this.svg.style.position = "absolute", this.svg.style.top = "0", this.svg.style.left = "0", this.svg.style.width = "100%", this.svg.style.height = "100%", this.svg.style.zIndex = "0", this.svg.style.pointerEvents = "none", this.svg.style.overflow = "visible", this.svg.style.transformOrigin = "0 0", this.container.appendChild(this.svg), this.nodeContainer = document.createElement("div"), this.nodeContainer.style.position = "absolute", this.nodeContainer.style.top = "0", this.nodeContainer.style.left = "0", this.nodeContainer.style.width = "100%", this.nodeContainer.style.height = "100%", this.nodeContainer.style.zIndex = "1", this.nodeContainer.style.transformOrigin = "0 0", this.container.appendChild(this.nodeContainer), this.options = e;
|
|
293
294
|
}
|
|
294
295
|
render(t, e = null, i = "Right") {
|
|
295
296
|
this.svg.innerHTML = "", this.nodeContainer.innerHTML = "", this.renderNode(
|
|
@@ -319,7 +320,7 @@ const I = class I {
|
|
|
319
320
|
}
|
|
320
321
|
const n = e.root.children.findIndex((r) => r.id === i.id);
|
|
321
322
|
if (n !== -1)
|
|
322
|
-
return
|
|
323
|
+
return E.RAINBOW_PALETTE[n % E.RAINBOW_PALETTE.length];
|
|
323
324
|
}
|
|
324
325
|
return "#ccc";
|
|
325
326
|
}
|
|
@@ -401,16 +402,24 @@ const I = class I {
|
|
|
401
402
|
r.setAttribute("d", d), r.setAttribute("stroke", n), r.setAttribute("fill", "none"), r.setAttribute("stroke-width", "2"), this.svg.appendChild(r);
|
|
402
403
|
}
|
|
403
404
|
showImageModal(t) {
|
|
405
|
+
this.options.onImageZoom && this.options.onImageZoom(!0);
|
|
404
406
|
const e = document.createElement("div");
|
|
405
407
|
e.style.position = "fixed", e.style.top = "0", e.style.left = "0", e.style.width = "100vw", e.style.height = "100vh", e.style.backgroundColor = "rgba(0,0,0,0.8)", e.style.zIndex = "1000", e.style.display = "flex", e.style.justifyContent = "center", e.style.alignItems = "center", e.style.cursor = "zoom-out";
|
|
406
408
|
const i = document.createElement("img");
|
|
407
|
-
i.src = t, i.style.maxWidth = "90%", i.style.maxHeight = "90%", i.style.boxShadow = "0 0 20px rgba(0,0,0,0.5)", e.appendChild(i), document.body.appendChild(e)
|
|
408
|
-
|
|
409
|
+
i.src = t, i.style.maxWidth = "90%", i.style.maxHeight = "90%", i.style.boxShadow = "0 0 20px rgba(0,0,0,0.5)", e.appendChild(i), document.body.appendChild(e);
|
|
410
|
+
let s;
|
|
411
|
+
const n = () => {
|
|
412
|
+
document.body.contains(e) && document.body.removeChild(e), s && document.removeEventListener("keydown", s, !0), this.options.onImageZoom && this.options.onImageZoom(!1), this.container.focus();
|
|
413
|
+
};
|
|
414
|
+
s = (r) => {
|
|
415
|
+
r.stopPropagation(), r.preventDefault(), n();
|
|
416
|
+
}, document.addEventListener("keydown", s, !0), e.addEventListener("click", () => {
|
|
417
|
+
n();
|
|
409
418
|
});
|
|
410
419
|
}
|
|
411
420
|
};
|
|
412
421
|
// Palette for Colorful mode
|
|
413
|
-
c(
|
|
422
|
+
c(E, "RAINBOW_PALETTE", [
|
|
414
423
|
"#E74C3C",
|
|
415
424
|
// Red
|
|
416
425
|
"#3498DB",
|
|
@@ -426,8 +435,8 @@ c(I, "RAINBOW_PALETTE", [
|
|
|
426
435
|
"#1ABC9C"
|
|
427
436
|
// Teal
|
|
428
437
|
]);
|
|
429
|
-
let
|
|
430
|
-
const
|
|
438
|
+
let T = E;
|
|
439
|
+
const S = class S {
|
|
431
440
|
constructor(t) {
|
|
432
441
|
c(this, "container");
|
|
433
442
|
c(this, "editorEl");
|
|
@@ -441,7 +450,7 @@ const C = class C {
|
|
|
441
450
|
const e = document.createElement("div");
|
|
442
451
|
e.style.display = "flex", e.style.gap = "8px", e.style.alignItems = "center";
|
|
443
452
|
const i = document.createElement("select");
|
|
444
|
-
i.style.padding = "4px 8px", i.style.borderRadius = "4px", i.style.border = "1px solid #ccc", i.style.fontSize = "14px", i.style.flex = "1",
|
|
453
|
+
i.style.padding = "4px 8px", i.style.borderRadius = "4px", i.style.border = "1px solid #ccc", i.style.fontSize = "14px", i.style.flex = "1", S.FONT_SIZES.forEach((h) => {
|
|
445
454
|
const f = document.createElement("option");
|
|
446
455
|
f.value = h.value, f.textContent = h.label, i.appendChild(f);
|
|
447
456
|
}), i.onchange = (h) => {
|
|
@@ -467,7 +476,7 @@ const C = class C {
|
|
|
467
476
|
const d = document.createElement("input");
|
|
468
477
|
return d.type = "color", d.style.width = "24px", d.style.height = "24px", d.style.border = "1px solid #ccc", d.style.padding = "0", d.style.backgroundColor = "transparent", d.style.cursor = "pointer", d.style.appearance = "none", d.onchange = (h) => {
|
|
469
478
|
this.currentNodeId && this.onUpdate && (this.onUpdate(this.currentNodeId, { color: h.target.value }), this.updateActivePaletteItem(h.target.value));
|
|
470
|
-
},
|
|
479
|
+
}, S.PALETTE.forEach((h, f) => {
|
|
471
480
|
const p = document.createElement("div");
|
|
472
481
|
p.className = "color-swatch", p.dataset.color = h, p.textContent = (f + 1).toString(), p.style.width = "24px", p.style.height = "24px", p.style.backgroundColor = h, p.style.borderRadius = "4px", p.style.cursor = "pointer", p.style.border = "1px solid transparent", p.style.color = h === "#F1C40F" ? "black" : "white", p.style.fontSize = "12px", p.style.fontWeight = "bold", p.style.display = "flex", p.style.justifyContent = "center", p.style.alignItems = "center", p.onclick = () => {
|
|
473
482
|
this.currentNodeId && this.onUpdate && (this.onUpdate(this.currentNodeId, { color: h }), d.value = h, this.updateActivePaletteItem(h));
|
|
@@ -499,7 +508,7 @@ const C = class C {
|
|
|
499
508
|
this.editorEl.style.display = "none", this.currentNodeId = null;
|
|
500
509
|
}
|
|
501
510
|
};
|
|
502
|
-
c(
|
|
511
|
+
c(S, "FONT_SIZES", [
|
|
503
512
|
{ label: "12px", value: "12px" },
|
|
504
513
|
{ label: "14px", value: "14px" },
|
|
505
514
|
{ label: "16px", value: "16px" },
|
|
@@ -511,7 +520,7 @@ c(C, "FONT_SIZES", [
|
|
|
511
520
|
// Black, Red, Orange, Yellow, Green, Blue, Purple
|
|
512
521
|
// Palette colors based on screenshot approximation + standard colors
|
|
513
522
|
// Black, Red, Orange, Yellow, Green, Blue, Purple
|
|
514
|
-
c(
|
|
523
|
+
c(S, "PALETTE", [
|
|
515
524
|
"#000000",
|
|
516
525
|
"#E74C3C",
|
|
517
526
|
"#E67E22",
|
|
@@ -520,8 +529,8 @@ c(C, "PALETTE", [
|
|
|
520
529
|
"#3498DB",
|
|
521
530
|
"#9B59B6"
|
|
522
531
|
]);
|
|
523
|
-
let w =
|
|
524
|
-
class
|
|
532
|
+
let w = S;
|
|
533
|
+
class ne {
|
|
525
534
|
constructor(t, e) {
|
|
526
535
|
c(this, "container");
|
|
527
536
|
c(this, "element");
|
|
@@ -628,7 +637,7 @@ class q {
|
|
|
628
637
|
</svg>`;
|
|
629
638
|
}
|
|
630
639
|
}
|
|
631
|
-
class
|
|
640
|
+
class oe {
|
|
632
641
|
constructor(t, e) {
|
|
633
642
|
c(this, "container");
|
|
634
643
|
c(this, "options");
|
|
@@ -693,9 +702,22 @@ class _ {
|
|
|
693
702
|
},
|
|
694
703
|
{ passive: !1 }
|
|
695
704
|
), e(document, "keydown", (r) => {
|
|
696
|
-
var h, f, p, l, y, g, m, u, x,
|
|
697
|
-
const o = r;
|
|
698
|
-
if (!this.selectedNodeId
|
|
705
|
+
var h, f, p, l, y, g, m, u, x, I, L, B, D, P, A, O, z, U, X, Y, H, K, F, W, Z, $;
|
|
706
|
+
const o = r, a = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "h", "j", "k", "l"], d = ["Tab", "Enter", "Delete", "Backspace"];
|
|
707
|
+
if (!this.selectedNodeId) {
|
|
708
|
+
if (a.includes(o.key)) {
|
|
709
|
+
o.preventDefault();
|
|
710
|
+
let N = null, b = 1 / 0;
|
|
711
|
+
this.container.querySelectorAll(".mindmap-node").forEach((q) => {
|
|
712
|
+
const R = q;
|
|
713
|
+
if (!R.dataset.id) return;
|
|
714
|
+
const k = R.getBoundingClientRect(), V = k.left + k.width / 2, _ = k.top + k.height / 2, M = this.container.getBoundingClientRect(), G = M.left + M.width / 2, J = M.top + M.height / 2, j = Math.pow(V - G, 2) + Math.pow(_ - J, 2);
|
|
715
|
+
j < b && (b = j, N = R.dataset.id);
|
|
716
|
+
}), N && this.options.onNodeClick(N);
|
|
717
|
+
}
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
if (!(this.isReadOnly && ![
|
|
699
721
|
"ArrowUp",
|
|
700
722
|
"ArrowDown",
|
|
701
723
|
"ArrowLeft",
|
|
@@ -707,98 +729,118 @@ class _ {
|
|
|
707
729
|
// Vim navigation
|
|
708
730
|
"c"
|
|
709
731
|
// Copy
|
|
710
|
-
].includes(o.key))
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
case "F2": {
|
|
744
|
-
if (this.isReadOnly) return;
|
|
745
|
-
o.preventDefault();
|
|
746
|
-
const v = this.container.querySelector(
|
|
747
|
-
`.mindmap-node[data-id="${this.selectedNodeId}"]`
|
|
748
|
-
);
|
|
749
|
-
v && this.startEditing(v, this.selectedNodeId);
|
|
750
|
-
break;
|
|
751
|
-
}
|
|
752
|
-
case "c":
|
|
753
|
-
(o.metaKey || o.ctrlKey) && (o.preventDefault(), (k = (M = this.options).onCopyNode) == null || k.call(M, this.selectedNodeId));
|
|
754
|
-
break;
|
|
755
|
-
case "v":
|
|
756
|
-
if (this.isReadOnly) return;
|
|
757
|
-
(o.metaKey || o.ctrlKey) && (t && clearTimeout(t), t = setTimeout(() => {
|
|
758
|
-
var v, F;
|
|
759
|
-
this.selectedNodeId && ((F = (v = this.options).onPasteNode) == null || F.call(v, this.selectedNodeId));
|
|
760
|
-
}, 50));
|
|
761
|
-
break;
|
|
762
|
-
case "x":
|
|
763
|
-
if (this.isReadOnly) return;
|
|
764
|
-
(o.metaKey || o.ctrlKey) && (o.preventDefault(), (T = (R = this.options).onCutNode) == null || T.call(R, this.selectedNodeId));
|
|
765
|
-
break;
|
|
766
|
-
case "z":
|
|
767
|
-
if (this.isReadOnly) return;
|
|
768
|
-
(o.metaKey || o.ctrlKey) && (o.preventDefault(), o.shiftKey || (B = (L = this.options).onUndo) == null || B.call(L));
|
|
769
|
-
break;
|
|
770
|
-
case "b":
|
|
771
|
-
if (this.isReadOnly) return;
|
|
772
|
-
(o.metaKey || o.ctrlKey) && (o.preventDefault(), (P = (D = this.options).onStyleAction) == null || P.call(D, this.selectedNodeId, { type: "bold" }));
|
|
773
|
-
break;
|
|
774
|
-
case "i": {
|
|
775
|
-
if (this.isReadOnly) return;
|
|
776
|
-
if (o.metaKey || o.ctrlKey)
|
|
777
|
-
o.preventDefault(), (O = (A = this.options).onStyleAction) == null || O.call(A, this.selectedNodeId, { type: "italic" });
|
|
778
|
-
else {
|
|
732
|
+
].includes(o.key))) {
|
|
733
|
+
switch ((d.includes(o.key) || a.includes(o.key)) && o.preventDefault(), o.key) {
|
|
734
|
+
case "Tab":
|
|
735
|
+
if (this.isReadOnly) return;
|
|
736
|
+
o.shiftKey ? (f = (h = this.options).onInsertParent) == null || f.call(h, this.selectedNodeId) : this.options.onAddChild(this.selectedNodeId);
|
|
737
|
+
break;
|
|
738
|
+
case "Enter":
|
|
739
|
+
if (this.isReadOnly) return;
|
|
740
|
+
this.options.onAddSibling(this.selectedNodeId, o.shiftKey ? "before" : "after");
|
|
741
|
+
break;
|
|
742
|
+
case "Delete":
|
|
743
|
+
case "Backspace":
|
|
744
|
+
if (this.isReadOnly) return;
|
|
745
|
+
this.options.onDeleteNode(this.selectedNodeId);
|
|
746
|
+
break;
|
|
747
|
+
case "ArrowUp":
|
|
748
|
+
case "k":
|
|
749
|
+
(this.isReadOnly || !o.ctrlKey && !o.metaKey && !o.altKey) && ((l = (p = this.options).onNavigate) == null || l.call(p, this.selectedNodeId, "Up"));
|
|
750
|
+
break;
|
|
751
|
+
case "ArrowDown":
|
|
752
|
+
case "j":
|
|
753
|
+
(this.isReadOnly || !o.ctrlKey && !o.metaKey && !o.altKey) && ((g = (y = this.options).onNavigate) == null || g.call(y, this.selectedNodeId, "Down"));
|
|
754
|
+
break;
|
|
755
|
+
case "ArrowLeft":
|
|
756
|
+
case "h":
|
|
757
|
+
(this.isReadOnly || !o.ctrlKey && !o.metaKey && !o.altKey) && ((u = (m = this.options).onNavigate) == null || u.call(m, this.selectedNodeId, "Left"));
|
|
758
|
+
break;
|
|
759
|
+
case "ArrowRight":
|
|
760
|
+
case "l":
|
|
761
|
+
(this.isReadOnly || !o.ctrlKey && !o.metaKey && !o.altKey) && ((I = (x = this.options).onNavigate) == null || I.call(x, this.selectedNodeId, "Right"));
|
|
762
|
+
break;
|
|
763
|
+
case "F2": {
|
|
764
|
+
if (this.isReadOnly) return;
|
|
779
765
|
o.preventDefault();
|
|
780
|
-
const
|
|
766
|
+
const N = this.container.querySelector(
|
|
781
767
|
`.mindmap-node[data-id="${this.selectedNodeId}"]`
|
|
782
768
|
);
|
|
783
|
-
|
|
769
|
+
if (N) {
|
|
770
|
+
if (N.querySelector("img"))
|
|
771
|
+
return;
|
|
772
|
+
this.startEditing(N, this.selectedNodeId);
|
|
773
|
+
}
|
|
774
|
+
break;
|
|
784
775
|
}
|
|
785
|
-
|
|
776
|
+
case "c":
|
|
777
|
+
(o.metaKey || o.ctrlKey) && (o.preventDefault(), (B = (L = this.options).onCopyNode) == null || B.call(L, this.selectedNodeId));
|
|
778
|
+
break;
|
|
779
|
+
case "v":
|
|
780
|
+
if (this.isReadOnly) return;
|
|
781
|
+
(o.metaKey || o.ctrlKey) && (t && clearTimeout(t), t = setTimeout(() => {
|
|
782
|
+
var N, b;
|
|
783
|
+
this.selectedNodeId && ((b = (N = this.options).onPasteNode) == null || b.call(N, this.selectedNodeId));
|
|
784
|
+
}, 50));
|
|
785
|
+
break;
|
|
786
|
+
case "x":
|
|
787
|
+
if (this.isReadOnly) return;
|
|
788
|
+
(o.metaKey || o.ctrlKey) && (o.preventDefault(), (P = (D = this.options).onCutNode) == null || P.call(D, this.selectedNodeId));
|
|
789
|
+
break;
|
|
790
|
+
case "z":
|
|
791
|
+
if (this.isReadOnly) return;
|
|
792
|
+
(o.metaKey || o.ctrlKey) && (o.preventDefault(), o.shiftKey || (O = (A = this.options).onUndo) == null || O.call(A));
|
|
793
|
+
break;
|
|
794
|
+
case "b":
|
|
795
|
+
if (this.isReadOnly) return;
|
|
796
|
+
(o.metaKey || o.ctrlKey) && (o.preventDefault(), (U = (z = this.options).onStyleAction) == null || U.call(z, this.selectedNodeId, { type: "bold" }));
|
|
797
|
+
break;
|
|
798
|
+
case "i": {
|
|
799
|
+
if (this.isReadOnly) return;
|
|
800
|
+
if (o.metaKey || o.ctrlKey)
|
|
801
|
+
o.preventDefault(), (Y = (X = this.options).onStyleAction) == null || Y.call(X, this.selectedNodeId, { type: "italic" });
|
|
802
|
+
else {
|
|
803
|
+
o.preventDefault();
|
|
804
|
+
const N = this.container.querySelector(
|
|
805
|
+
`.mindmap-node[data-id="${this.selectedNodeId}"]`
|
|
806
|
+
);
|
|
807
|
+
if (N) {
|
|
808
|
+
if (N.querySelector("img"))
|
|
809
|
+
return;
|
|
810
|
+
this.startEditing(N, this.selectedNodeId);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
break;
|
|
814
|
+
}
|
|
815
|
+
case " ":
|
|
816
|
+
if (this.isReadOnly) return;
|
|
817
|
+
o.preventDefault();
|
|
818
|
+
{
|
|
819
|
+
const N = this.container.querySelector(
|
|
820
|
+
`.mindmap-node[data-id="${this.selectedNodeId}"]`
|
|
821
|
+
);
|
|
822
|
+
if (N) {
|
|
823
|
+
const b = N.querySelector('[title="Zoom Image"]');
|
|
824
|
+
b && b.click();
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
break;
|
|
828
|
+
case "+":
|
|
829
|
+
case "=":
|
|
830
|
+
if (this.isReadOnly) return;
|
|
831
|
+
(o.key === "+" || o.key === "=" && o.shiftKey) && ((K = (H = this.options).onStyleAction) == null || K.call(H, this.selectedNodeId, { type: "increaseSize" }));
|
|
832
|
+
break;
|
|
833
|
+
case "-":
|
|
834
|
+
if (this.isReadOnly) return;
|
|
835
|
+
(W = (F = this.options).onStyleAction) == null || W.call(F, this.selectedNodeId, { type: "decreaseSize" });
|
|
836
|
+
break;
|
|
786
837
|
}
|
|
787
|
-
|
|
788
|
-
case "=":
|
|
789
|
-
if (this.isReadOnly) return;
|
|
790
|
-
(o.key === "+" || o.key === "=" && o.shiftKey) && ((U = (z = this.options).onStyleAction) == null || U.call(z, this.selectedNodeId, { type: "increaseSize" }));
|
|
791
|
-
break;
|
|
792
|
-
case "-":
|
|
838
|
+
if (/^[1-7]$/.test(o.key)) {
|
|
793
839
|
if (this.isReadOnly) return;
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
if (this.isReadOnly) return;
|
|
799
|
-
if (!o.ctrlKey && !o.metaKey && !o.altKey) {
|
|
800
|
-
const v = parseInt(o.key) - 1;
|
|
801
|
-
(K = (H = this.options).onStyleAction) == null || K.call(H, this.selectedNodeId, { type: "color", index: v });
|
|
840
|
+
if (!o.ctrlKey && !o.metaKey && !o.altKey) {
|
|
841
|
+
const N = parseInt(o.key) - 1;
|
|
842
|
+
($ = (Z = this.options).onStyleAction) == null || $.call(Z, this.selectedNodeId, { type: "color", index: N });
|
|
843
|
+
}
|
|
802
844
|
}
|
|
803
845
|
}
|
|
804
846
|
}), e(document, "paste", (r) => {
|
|
@@ -817,8 +859,8 @@ class _ {
|
|
|
817
859
|
if (m) {
|
|
818
860
|
const u = new FileReader();
|
|
819
861
|
u.onload = (x) => {
|
|
820
|
-
var
|
|
821
|
-
(
|
|
862
|
+
var I;
|
|
863
|
+
(I = x.target) != null && I.result && this.options.onPasteImage && this.selectedNodeId && this.options.onPasteImage(this.selectedNodeId, x.target.result);
|
|
822
864
|
}, u.readAsDataURL(m);
|
|
823
865
|
}
|
|
824
866
|
o.preventDefault(), d = !0;
|
|
@@ -949,13 +991,13 @@ class _ {
|
|
|
949
991
|
if (d) return;
|
|
950
992
|
d = !0;
|
|
951
993
|
const l = s.value;
|
|
952
|
-
l !== i && this.options.onUpdateNode && this.options.onUpdateNode(e, l), h();
|
|
994
|
+
l !== i && this.options.onUpdateNode && this.options.onUpdateNode(e, l), h(), this.options.onEditEnd && this.options.onEditEnd(e);
|
|
953
995
|
};
|
|
954
996
|
s.addEventListener("blur", () => {
|
|
955
997
|
d || f();
|
|
956
998
|
});
|
|
957
999
|
const p = () => {
|
|
958
|
-
d || (d = !0, h());
|
|
1000
|
+
d || (d = !0, d = !0, h(), this.options.onEditEnd && this.options.onEditEnd(e));
|
|
959
1001
|
};
|
|
960
1002
|
s.addEventListener("keydown", (l) => {
|
|
961
1003
|
if (l.stopPropagation(), !l.isComposing)
|
|
@@ -967,7 +1009,7 @@ class _ {
|
|
|
967
1009
|
}), t.parentElement ? t.parentElement.appendChild(s) : this.container.appendChild(s), s.focus({ preventScroll: !0 }), s.select();
|
|
968
1010
|
}
|
|
969
1011
|
}
|
|
970
|
-
class
|
|
1012
|
+
class re {
|
|
971
1013
|
constructor() {
|
|
972
1014
|
c(this, "listeners", {});
|
|
973
1015
|
}
|
|
@@ -990,7 +1032,7 @@ class G {
|
|
|
990
1032
|
(i = this.listeners[t]) == null || i.forEach((s) => s(e));
|
|
991
1033
|
}
|
|
992
1034
|
}
|
|
993
|
-
class
|
|
1035
|
+
class le extends re {
|
|
994
1036
|
constructor(e) {
|
|
995
1037
|
super();
|
|
996
1038
|
c(this, "mindMap");
|
|
@@ -1001,6 +1043,11 @@ class Q extends G {
|
|
|
1001
1043
|
c(this, "layoutSwitcher");
|
|
1002
1044
|
c(this, "layoutMode", "Right");
|
|
1003
1045
|
c(this, "selectedNodeId", null);
|
|
1046
|
+
/**
|
|
1047
|
+
* Flag to track if we just created a node via UI interaction and are waiting for edit completion
|
|
1048
|
+
* to emit the final model:change event.
|
|
1049
|
+
*/
|
|
1050
|
+
c(this, "pendingNodeCreation", !1);
|
|
1004
1051
|
c(this, "panX", 0);
|
|
1005
1052
|
c(this, "panY", 0);
|
|
1006
1053
|
c(this, "targetPanX", 0);
|
|
@@ -1008,17 +1055,19 @@ class Q extends G {
|
|
|
1008
1055
|
c(this, "scale", 1);
|
|
1009
1056
|
c(this, "isBatching", !1);
|
|
1010
1057
|
c(this, "animationFrameId", null);
|
|
1011
|
-
const i = new
|
|
1012
|
-
this.mindMap = new
|
|
1058
|
+
const i = new C("root", "Root Topic", null, !0);
|
|
1059
|
+
this.mindMap = new te(i), this.service = new se(this.mindMap), this.renderer = new T(e, {
|
|
1060
|
+
onImageZoom: (n) => this.setReadOnly(n)
|
|
1061
|
+
});
|
|
1013
1062
|
const s = document.createElement("div");
|
|
1014
1063
|
s.style.position = "absolute", s.style.top = "0", s.style.left = "0", s.style.width = "100%", s.style.height = "100%", s.style.pointerEvents = "none", s.style.zIndex = "2000", e.style.overscrollBehavior = "none", e.style.touchAction = "none", e.appendChild(s), this.styleEditor = new w(s), this.styleEditor.onUpdate = (n, r) => {
|
|
1015
1064
|
this.interactionHandler.isReadOnly || this.service.updateNodeStyle(n, r) && (this.render(), this.emit("model:change", void 0));
|
|
1016
|
-
}, this.panX = e.clientWidth / 2, this.targetPanX = this.panX, this.targetPanY = this.panY, this.layoutSwitcher = new
|
|
1065
|
+
}, this.panX = e.clientWidth / 2, this.targetPanX = this.panX, this.targetPanY = this.panY, this.layoutSwitcher = new ne(s, {
|
|
1017
1066
|
// Pass uiLayer
|
|
1018
1067
|
onLayoutChange: (n) => this.setLayoutMode(n),
|
|
1019
1068
|
onThemeChange: (n) => this.setTheme(n),
|
|
1020
1069
|
onZoomReset: () => this.resetZoom()
|
|
1021
|
-
}), this.startAnimationLoop(), this.interactionHandler = new
|
|
1070
|
+
}), this.startAnimationLoop(), this.interactionHandler = new oe(e, {
|
|
1022
1071
|
onNodeClick: (n) => this.selectNode(n || null),
|
|
1023
1072
|
onAddChild: (n) => this.addChildNode(n),
|
|
1024
1073
|
onInsertParent: (n) => this.insertParentNode(n),
|
|
@@ -1056,6 +1105,9 @@ class Q extends G {
|
|
|
1056
1105
|
r.type === "increaseSize" ? l = Math.min(h.length - 1, p + 1) : l = Math.max(0, p - 1), l !== p && (d = { fontSize: h[l].value });
|
|
1057
1106
|
}
|
|
1058
1107
|
d && this.service.updateNodeStyle(n, d) && (this.render(), this.emit("model:change", void 0), this.selectedNodeId === n && this.styleEditor.show(n, { ...a, ...d }));
|
|
1108
|
+
},
|
|
1109
|
+
onEditEnd: (n) => {
|
|
1110
|
+
this.pendingNodeCreation && (this.pendingNodeCreation = !1, this.emit("model:change", void 0));
|
|
1059
1111
|
}
|
|
1060
1112
|
}), this.render();
|
|
1061
1113
|
}
|
|
@@ -1066,36 +1118,36 @@ class Q extends G {
|
|
|
1066
1118
|
* Adds a new child node to the specified parent.
|
|
1067
1119
|
* This is a pure data operation and does not trigger UI actions like auto-focus or scroll.
|
|
1068
1120
|
*/
|
|
1069
|
-
addNode(e, i, s) {
|
|
1070
|
-
const
|
|
1071
|
-
return
|
|
1121
|
+
addNode(e, i, s, n = { emitChange: !0 }) {
|
|
1122
|
+
const r = this.service.addNode(e, i, s);
|
|
1123
|
+
return r && (this.render(), this.emit("node:add", { id: r.id, topic: r.topic }), n.emitChange && this.emit("model:change", void 0)), r;
|
|
1072
1124
|
}
|
|
1073
1125
|
/**
|
|
1074
1126
|
* Adds a sibling node relative to the reference node.
|
|
1075
1127
|
* This is a pure data operation.
|
|
1076
1128
|
*/
|
|
1077
|
-
addSibling(e, i = "after", s = "New
|
|
1078
|
-
const
|
|
1079
|
-
if (!
|
|
1080
|
-
const
|
|
1081
|
-
|
|
1082
|
-
const
|
|
1083
|
-
if (
|
|
1084
|
-
if (
|
|
1085
|
-
const
|
|
1086
|
-
|
|
1129
|
+
addSibling(e, i = "after", s = "New topic", n = { emitChange: !0 }) {
|
|
1130
|
+
const r = this.mindMap.findNode(e);
|
|
1131
|
+
if (!r || !r.parentId) return null;
|
|
1132
|
+
const o = this.mindMap.findNode(r.parentId);
|
|
1133
|
+
o && o.isRoot && this.layoutMode === "Both" && this.ensureExplicitLayoutSides(o);
|
|
1134
|
+
const a = this.service.addSibling(e, i, s);
|
|
1135
|
+
if (a) {
|
|
1136
|
+
if (o && o.isRoot && this.layoutMode === "Both") {
|
|
1137
|
+
const d = r.layoutSide || (o.children.indexOf(r) % 2 === 0 ? "right" : "left");
|
|
1138
|
+
a.layoutSide = d;
|
|
1087
1139
|
}
|
|
1088
|
-
this.render(), this.emit("node:add", { id:
|
|
1140
|
+
this.render(), this.emit("node:add", { id: a.id, topic: a.topic }), n.emitChange && this.emit("model:change", void 0);
|
|
1089
1141
|
}
|
|
1090
|
-
return
|
|
1142
|
+
return a;
|
|
1091
1143
|
}
|
|
1092
1144
|
/**
|
|
1093
1145
|
* Inserts a parent node above the specified node.
|
|
1094
1146
|
* This is a pure data operation.
|
|
1095
1147
|
*/
|
|
1096
|
-
insertParent(e, i = "New
|
|
1097
|
-
const
|
|
1098
|
-
return
|
|
1148
|
+
insertParent(e, i = "New topic", s = { emitChange: !0 }) {
|
|
1149
|
+
const n = this.service.insertParent(e, i);
|
|
1150
|
+
return n && (this.render(), this.emit("node:add", { id: n.id, topic: n.topic }), s.emitChange && this.emit("model:change", void 0)), n;
|
|
1099
1151
|
}
|
|
1100
1152
|
/**
|
|
1101
1153
|
* Removes a node.
|
|
@@ -1115,7 +1167,7 @@ class Q extends G {
|
|
|
1115
1167
|
*/
|
|
1116
1168
|
updateNode(e, i) {
|
|
1117
1169
|
let s = !1;
|
|
1118
|
-
this.interactionHandler.isReadOnly || (i.topic !== void 0 && this.service.updateNodeTopic(e, i.topic) && (s = !0), i.style !== void 0 && this.service.updateNodeStyle(e, i.style) && (s = !0), s && (this.render(), i.topic !== void 0 && this.emit("node:update", { id: e, topic: i.topic }), this.emit("model:change", void 0)));
|
|
1170
|
+
this.interactionHandler.isReadOnly || (i.topic !== void 0 && this.service.updateNodeTopic(e, i.topic) && (s = !0), i.style !== void 0 && this.service.updateNodeStyle(e, i.style) && (s = !0), s && (this.render(), i.topic !== void 0 && this.emit("node:update", { id: e, topic: i.topic }), this.emit("model:change", void 0), this.pendingNodeCreation && (this.pendingNodeCreation = !1)));
|
|
1119
1171
|
}
|
|
1120
1172
|
/* ==========================================================================================
|
|
1121
1173
|
Node Accessors
|
|
@@ -1145,7 +1197,7 @@ class Q extends G {
|
|
|
1145
1197
|
Lifecycle & Modes
|
|
1146
1198
|
========================================================================================== */
|
|
1147
1199
|
setReadOnly(e) {
|
|
1148
|
-
this.interactionHandler.setReadOnly(e), e &&
|
|
1200
|
+
this.interactionHandler.setReadOnly(e), e && this.styleEditor.hide();
|
|
1149
1201
|
}
|
|
1150
1202
|
destroy() {
|
|
1151
1203
|
this.animationFrameId !== null && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = null), this.interactionHandler.destroy(), this.renderer.container;
|
|
@@ -1171,15 +1223,18 @@ class Q extends G {
|
|
|
1171
1223
|
(a.layoutSide || (d % 2 === 0 ? "right" : "left")) === "left" ? r++ : o++;
|
|
1172
1224
|
}), s = r < o ? "left" : "right";
|
|
1173
1225
|
}
|
|
1174
|
-
|
|
1226
|
+
this.pendingNodeCreation = !0;
|
|
1227
|
+
const n = this.addNode(e, "New topic", s, { emitChange: !1 });
|
|
1175
1228
|
n && (this.selectNode(n.id), this.ensureNodeVisible(n.id), this.interactionHandler.editNode(n.id));
|
|
1176
1229
|
}
|
|
1177
1230
|
addSiblingNode(e, i = "after") {
|
|
1178
|
-
|
|
1231
|
+
this.pendingNodeCreation = !0;
|
|
1232
|
+
const s = this.addSibling(e, i, "New topic", { emitChange: !1 });
|
|
1179
1233
|
s && (this.selectNode(s.id), this.ensureNodeVisible(s.id), this.interactionHandler.editNode(s.id));
|
|
1180
1234
|
}
|
|
1181
1235
|
insertParentNode(e) {
|
|
1182
|
-
|
|
1236
|
+
this.pendingNodeCreation = !0;
|
|
1237
|
+
const i = this.insertParent(e, "New topic", { emitChange: !1 });
|
|
1183
1238
|
i && (this.selectNode(i.id), this.ensureNodeVisible(i.id), this.interactionHandler.editNode(i.id));
|
|
1184
1239
|
}
|
|
1185
1240
|
/**
|
|
@@ -1378,5 +1433,5 @@ class Q extends G {
|
|
|
1378
1433
|
}
|
|
1379
1434
|
}
|
|
1380
1435
|
export {
|
|
1381
|
-
|
|
1436
|
+
le as Kakidash
|
|
1382
1437
|
};
|
package/dist/kakidash.umd.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(v,N){typeof exports=="object"&&typeof module<"u"?N(exports):typeof define=="function"&&define.amd?define(["exports"],N):(v=typeof globalThis<"u"?globalThis:v||self,N(v.kakidash={}))})(this,function(v){"use strict";var J=Object.defineProperty;var Q=(v,N,x)=>N in v?J(v,N,{enumerable:!0,configurable:!0,writable:!0,value:x}):v[N]=x;var c=(v,N,x)=>Q(v,typeof N!="symbol"?N+"":N,x);class N{constructor(t){c(this,"root");c(this,"theme","default");this.root=t}findNode(t){return this.findNodeRecursive(this.root,t)}findNodeRecursive(t,e){if(t.id===e)return t;for(const i of t.children){const s=this.findNodeRecursive(i,e);if(s)return s}return null}moveNode(t,e){const i=this.findNode(t),s=this.findNode(e);if(!i||!s||i.isRoot||i.parentId===e||this.isDescendant(i,e))return!1;if(i.parentId){const n=this.findNode(i.parentId);n&&n.removeChild(t)}return s.addChild(i),!0}addSibling(t,e,i){const s=this.findNode(t);if(!s||!s.parentId)return!1;const n=this.findNode(s.parentId);if(!n)return!1;const r=n.children.findIndex(a=>a.id===t);if(r===-1)return!1;const o=i==="before"?r:r+1;return n.insertChild(e,o),!0}insertParent(t,e){const i=this.findNode(t);if(!i||!i.parentId)return!1;const s=this.findNode(i.parentId);if(!s)return!1;const n=s.children.findIndex(r=>r.id===t);return n===-1?!1:(s.removeChild(t),s.insertChild(e,n),e.addChild(i),!0)}isDescendant(t,e){if(t.id===e)return!0;for(const i of t.children)if(this.isDescendant(i,e))return!0;return!1}}class x{constructor(t,e,i=null,s=!1,n,r){c(this,"id");c(this,"topic");c(this,"children");c(this,"style");c(this,"parentId");c(this,"isRoot");c(this,"image");c(this,"layoutSide");this.id=t,this.topic=e,this.children=[],this.style={fontSize:s?"24px":"16px"},this.parentId=i,this.isRoot=s,this.image=n,this.layoutSide=r}addChild(t){t.parentId=this.id,this.children.push(t)}insertChild(t,e){t.parentId=this.id,e>=0&&e<=this.children.length?this.children.splice(e,0,t):this.children.push(t)}removeChild(t){this.children=this.children.filter(e=>e.id!==t)}updateTopic(t){this.topic=t}}class j{constructor(t=10){c(this,"past",[]);c(this,"future",[]);c(this,"maxHistorySize");this.maxHistorySize=t}push(t){this.past.push(t),this.past.length>this.maxHistorySize&&this.past.shift(),this.future=[]}undo(t){if(this.past.length===0)return null;const e=this.past.pop();return e?(this.future.push(t),e):null}get canUndo(){return this.past.length>0}redo(t){if(this.future.length===0)return null;const e=this.future.pop();return e?(this.past.push(t),this.past.length>this.maxHistorySize&&this.past.shift(),e):null}get canRedo(){return this.future.length>0}clear(){this.past=[],this.future=[]}}class Z{constructor(t){c(this,"mindMap");c(this,"historyManager");c(this,"clipboard",null);this.mindMap=t,this.historyManager=new j(10)}saveState(){this.historyManager.push(this.exportData())}undo(){const t=this.historyManager.undo(this.exportData());return t?(this.importData(t),!0):!1}get canUndo(){return this.historyManager.canUndo}addNode(t,e="New Node",i){const s=this.mindMap.findNode(t);if(!s)return null;this.saveState();const n=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),r=new x(n,e,null,!1,void 0,i);return s.addChild(r),r}addImageNode(t,e){const i=this.mindMap.findNode(t);if(!i)return null;this.saveState();const s=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),n=new x(s,"",t,!1,e);return i.addChild(n),n}removeNode(t,e=!0){const i=this.mindMap.findNode(t);if(!i||i.isRoot||!i.parentId)return!1;const s=this.mindMap.findNode(i.parentId);return s?(e&&this.saveState(),s.removeChild(t),!0):!1}updateNodeTopic(t,e){const i=this.mindMap.findNode(t);return i?(this.saveState(),i.updateTopic(e),!0):!1}updateNodeStyle(t,e){const i=this.mindMap.findNode(t);return i?(this.saveState(),i.style={...i.style,...e},!0):!1}setTheme(t){this.mindMap.theme!==t&&(this.saveState(),this.mindMap.theme=t)}moveNode(t,e,i){const s=this.mindMap.findNode(t);if(s&&s.parentId===e)return i&&s.layoutSide!==i?(this.saveState(),s.layoutSide=i,!0):!1;if(!s)return!1;if(this.saveState(),this.mindMap.moveNode(t,e)){if(i){const n=this.mindMap.findNode(t);n&&(n.layoutSide=i)}return!0}return!1}addSibling(t,e,i="New Node"){const s=this.mindMap.findNode(t);if(!s||!s.parentId)return null;this.saveState();const n=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),r=new x(n,i);return this.mindMap.addSibling(t,r,e)?r:null}reorderNode(t,e,i){const s=this.mindMap.findNode(t),n=this.mindMap.findNode(e);if(!s||!n||!n.parentId||s.id===n.id||s.isRoot)return!1;const r=this.mindMap.findNode(n.parentId);if(!r)return!1;if(this.saveState(),s.parentId!==r.id){let d=r;for(;d.parentId;){if(d.id===s.id)return!1;if(!d.parentId)break;const h=this.mindMap.findNode(d.parentId);if(!h)break;d=h}}if(s.parentId&&s.parentId!==r.id){const d=this.mindMap.findNode(s.parentId);d&&d.removeChild(s.id),s.parentId=r.id}else s.parentId===r.id&&r.removeChild(s.id);const o=r.children.findIndex(d=>d.id===e);if(o===-1)return r.addChild(s),!0;const a=i==="before"?o:o+1;return r.insertChild(s,a),r.isRoot&&n.layoutSide&&(s.layoutSide=n.layoutSide),!0}insertNodeAsParent(t,e){const i=this.mindMap.findNode(t),s=this.mindMap.findNode(e);if(!i||!s||!s.parentId||i.id===s.id)return!1;const n=this.mindMap.findNode(s.parentId);if(!n)return!1;let r=n;for(;r;){if(r.id===i.id)return!1;if(!r.parentId)break;r=this.mindMap.findNode(r.parentId)}if(this.saveState(),i.parentId){const a=this.mindMap.findNode(i.parentId);a&&a.removeChild(i.id)}const o=n.children.findIndex(a=>a.id===e);return o===-1?!1:(n.isRoot&&s.layoutSide&&(i.layoutSide=s.layoutSide),n.removeChild(e),n.insertChild(i,o),i.parentId=n.id,i.addChild(s),!0)}insertParent(t,e="New Parent"){const i=this.mindMap.findNode(t);if(!i||!i.parentId)return null;this.saveState();const s=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),n=new x(s,e);return this.mindMap.insertParent(t,n)?n:null}copyNode(t){const e=this.mindMap.findNode(t);e&&(this.clipboard=this.deepCloneNode(e),navigator.clipboard&&navigator.clipboard.writeText(e.topic).catch(i=>{console.error("Failed to write to clipboard",i)}))}cutNode(t){const e=this.mindMap.findNode(t);e&&!e.isRoot&&e.parentId&&(this.copyNode(t),this.removeNode(t))}pasteNode(t){if(!this.clipboard)return null;const e=this.mindMap.findNode(t);if(!e)return null;this.saveState();const i=this.deepCloneNode(this.clipboard);return this.regenerateIds(i),e.addChild(i),i}deepCloneNode(t){const e=new x(t.id,t.topic,null,!1,t.image,t.layoutSide);return e.style={...t.style},e.children=t.children.map(i=>this.deepCloneNode(i)),e.children.forEach(i=>i.parentId=e.id),e}regenerateIds(t){t.id=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),t.children.forEach(e=>{e.parentId=t.id,this.regenerateIds(e)})}exportData(){const t=e=>({id:e.id,topic:e.topic,root:e.isRoot||void 0,children:e.children.length>0?e.children.map(t):void 0,style:Object.keys(e.style).length>0?e.style:void 0,image:e.image,layoutSide:e.layoutSide});return{nodeData:t(this.mindMap.root),theme:this.mindMap.theme}}importData(t){const e=(i,s=null)=>{const n=!!i.root,r=new x(i.id,i.topic,s,n,i.image,i.layoutSide);return i.style&&(r.style={...i.style}),i.children&&i.children.length>0&&i.children.forEach(o=>{const a=e(o,r.id);r.addChild(a)}),r};this.mindMap.root=e(t.nodeData),t.theme&&(this.mindMap.theme=t.theme)}}const E=class E{constructor(t){c(this,"container");c(this,"svg");c(this,"nodeContainer");this.container=t,this.container.style.position="relative",this.container.style.width="100%",this.container.style.height="100%",this.container.style.overflow="hidden",this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.position="absolute",this.svg.style.top="0",this.svg.style.left="0",this.svg.style.width="100%",this.svg.style.height="100%",this.svg.style.zIndex="0",this.svg.style.pointerEvents="none",this.svg.style.overflow="visible",this.svg.style.transformOrigin="0 0",this.container.appendChild(this.svg),this.nodeContainer=document.createElement("div"),this.nodeContainer.style.position="absolute",this.nodeContainer.style.top="0",this.nodeContainer.style.left="0",this.nodeContainer.style.width="100%",this.nodeContainer.style.height="100%",this.nodeContainer.style.zIndex="1",this.nodeContainer.style.transformOrigin="0 0",this.container.appendChild(this.nodeContainer)}render(t,e=null,i="Right"){this.svg.innerHTML="",this.nodeContainer.innerHTML="",this.renderNode(t.root,0,this.container.clientHeight/2,e,i,!0,void 0,t)}updateTransform(t,e,i=1){const s=`translate(${t}px, ${e}px) scale(${i})`;this.svg.style.transform=s,this.nodeContainer.style.transform=s}getThemeColor(t,e){if(e.theme==="colorful"){if(t.isRoot)return"#333";let i=t;for(;i.parentId&&i.parentId!==e.root.id;){const r=e.findNode(i.parentId);if(!r)break;i=r}const n=e.root.children.findIndex(r=>r.id===i.id);if(n!==-1)return E.RAINBOW_PALETTE[n%E.RAINBOW_PALETTE.length]}return"#ccc"}renderNode(t,e,i,s,n,r,o="right",a){const d=document.createElement("div");if(d.dataset.id=t.id,t.image){const m=document.createElement("img");m.src=t.image,m.style.maxWidth="150px",m.style.maxHeight="150px",m.style.display="block",d.appendChild(m);const u=document.createElement("div");u.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="11" y1="8" x2="11" y2="14"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>',u.style.position="absolute",u.style.bottom="5px",u.style.right="5px",u.style.backgroundColor="rgba(255, 255, 255, 0.9)",u.style.borderRadius="50%",u.style.width="24px",u.style.height="24px",u.style.display="flex",u.style.justifyContent="center",u.style.alignItems="center",u.style.cursor="pointer",u.title="Zoom Image",u.style.boxShadow="0 1px 3px rgba(0,0,0,0.2)",d.appendChild(u),u.addEventListener("click",w=>{w.stopPropagation(),this.showImageModal(t.image)}),d.style.padding="5px"}else d.textContent=t.topic,d.style.whiteSpace="pre";d.className="mindmap-node",t.isRoot||(d.draggable=!0),d.style.position="absolute",d.style.padding="8px 12px",t.image&&(d.style.padding="5px"),d.style.backgroundColor="white";const h=(a==null?void 0:a.theme)||"default",f=a?this.getThemeColor(t,a):"#ccc";h==="simple"&&!t.isRoot?d.style.border="none":h==="colorful"?d.style.border=`2px solid ${f}`:d.style.border="1px solid #ccc",d.style.borderRadius="4px",t.isRoot&&(d.style.fontSize="1.2em",d.style.fontWeight="bold",d.style.border="2px solid #333"),t.style.color&&(d.style.color=t.style.color),t.style.fontSize&&(d.style.fontSize=t.style.fontSize),t.style.fontWeight&&(d.style.fontWeight=t.style.fontWeight),t.style.fontStyle&&(d.style.fontStyle=t.style.fontStyle),t.style.background&&(d.style.backgroundColor=t.style.background);const{width:p}=this.measureNode(t);let l=e;if(o==="left"&&!r?l=e-p:r&&(l=e-p/2),d.style.left=`${l}px`,d.style.top=`${i}px`,d.style.transform="translate(0, -50%)",d.style.zIndex="10",d.style.cursor="default",d.style.userSelect="none",t.id===s&&(d.style.outline="2px solid #007bff",d.style.boxShadow="0 0 5px rgba(0, 123, 255, 0.5)"),this.nodeContainer.appendChild(d),t.children.length===0)return;let y=[],g=[];r&&n==="Both"?t.children.forEach((m,u)=>{(m.layoutSide||(u%2===0?"right":"left"))==="right"?y.push(m):g.push(m)}):n==="Left"?g=t.children:n==="Right"?y=t.children:o==="left"?g=t.children:y=t.children,y.length>0&&this.renderChildrenStack(t,y,e,i,s,n,"right",p,a),g.length>0&&this.renderChildrenStack(t,g,e,i,s,n,"left",p,a)}renderChildrenStack(t,e,i,s,n,r,o,a,d){const h=e.reduce((y,g)=>y+this.getNodeHeight(g),0);let f=s-h/2;const p=80;let l=0;t.isRoot?l=o==="right"?i+a/2:i-a/2:o==="right"?l=i+a:(l=i,l=i-a),e.forEach(y=>{const g=this.getNodeHeight(y),m=f+g/2;let u=0;o==="right"?u=l+p:u=l-p,this.renderNode(y,u,m,n,r,!1,o,d);const w=d?this.getThemeColor(y,d):"#ccc";this.drawConnection(l,s,u,m,w),f+=g})}getChildrenHeight(t){return t.children.reduce((e,i)=>e+this.getNodeHeight(i),0)}getNodeHeight(t){const{height:e}=this.measureNode(t),i=20;if(t.children.length===0)return e+i;const s=this.getChildrenHeight(t);return Math.max(e+i,s)}measureNode(t){if(t.image)return{width:160,height:160};const e=document.createElement("div");e.textContent=t.topic,e.className="mindmap-node",e.style.visibility="hidden",e.style.position="absolute",e.style.whiteSpace="pre",e.style.padding="8px 12px",e.style.border="1px solid #ccc",t.isRoot&&(e.style.fontSize="1.2em",e.style.fontWeight="bold",e.style.border="2px solid #333"),t.style.color&&(e.style.color=t.style.color),t.style.fontSize&&(e.style.fontSize=t.style.fontSize),t.style.fontWeight&&(e.style.fontWeight=t.style.fontWeight),t.style.fontStyle&&(e.style.fontStyle=t.style.fontStyle),t.style.background&&(e.style.backgroundColor=t.style.background),this.nodeContainer.appendChild(e);const i=e.offsetWidth,s=e.offsetHeight;return this.nodeContainer.removeChild(e),{width:i||100,height:s||40}}drawConnection(t,e,i,s,n="#ccc"){const r=document.createElementNS("http://www.w3.org/2000/svg","path"),o=t+(i-t)/2,a=t+(i-t)/2,d=`M ${t} ${e} C ${o} ${e}, ${a} ${s}, ${i} ${s}`;r.setAttribute("d",d),r.setAttribute("stroke",n),r.setAttribute("fill","none"),r.setAttribute("stroke-width","2"),this.svg.appendChild(r)}showImageModal(t){const e=document.createElement("div");e.style.position="fixed",e.style.top="0",e.style.left="0",e.style.width="100vw",e.style.height="100vh",e.style.backgroundColor="rgba(0,0,0,0.8)",e.style.zIndex="1000",e.style.display="flex",e.style.justifyContent="center",e.style.alignItems="center",e.style.cursor="zoom-out";const i=document.createElement("img");i.src=t,i.style.maxWidth="90%",i.style.maxHeight="90%",i.style.boxShadow="0 0 20px rgba(0,0,0,0.5)",e.appendChild(i),document.body.appendChild(e),e.addEventListener("click",()=>{document.body.removeChild(e)})}};c(E,"RAINBOW_PALETTE",["#E74C3C","#3498DB","#2ECC71","#F1C40F","#9B59B6","#E67E22","#1ABC9C"]);let M=E;const I=class I{constructor(t){c(this,"container");c(this,"editorEl");c(this,"currentNodeId",null);c(this,"onUpdate");this.container=t,this.editorEl=this.createEditor(),this.container.appendChild(this.editorEl),this.editorEl.addEventListener("mousedown",e=>e.stopPropagation()),this.editorEl.addEventListener("click",e=>e.stopPropagation()),this.editorEl.addEventListener("dblclick",e=>e.stopPropagation())}createEditor(){const t=document.createElement("div");t.className="style-editor",t.style.position="absolute",t.style.top="20px",t.style.right="20px",t.style.display="none",t.style.backgroundColor="white",t.style.border="1px solid #eee",t.style.borderRadius="8px",t.style.padding="8px",t.style.boxShadow="0 4px 12px rgba(0,0,0,0.1)",t.style.zIndex="2000",t.style.pointerEvents="auto",t.style.fontFamily="Arial, sans-serif",t.style.display="flex",t.style.flexDirection="column",t.style.gap="8px",t.style.margin="0",t.style.boxSizing="border-box",t.style.minWidth="220px";const e=document.createElement("div");e.style.display="flex",e.style.gap="8px",e.style.alignItems="center";const i=document.createElement("select");i.style.padding="4px 8px",i.style.borderRadius="4px",i.style.border="1px solid #ccc",i.style.fontSize="14px",i.style.flex="1",I.FONT_SIZES.forEach(h=>{const f=document.createElement("option");f.value=h.value,f.textContent=h.label,i.appendChild(f)}),i.onchange=h=>{this.currentNodeId&&this.onUpdate&&this.onUpdate(this.currentNodeId,{fontSize:h.target.value})},e.appendChild(i);const n=(h,f,p)=>{const l=document.createElement("button");return l.textContent=h,l.style.width="32px",l.style.height="32px",l.style.padding="0",l.style.display="flex",l.style.justifyContent="center",l.style.alignItems="center",l.style.border="1px solid #ddd",l.style.backgroundColor="#f5f5f5",l.style.borderRadius="4px",l.style.cursor="pointer",l.style.fontSize="14px",f&&(l.style[f]=f==="fontWeight"?"bold":"italic"),l.onclick=p,l},r=n("B","fontWeight",()=>{if(this.currentNodeId&&this.onUpdate){const h=r.classList.contains("active"),f=h?"normal":"bold";this.onUpdate(this.currentNodeId,{fontWeight:f}),this.updateButtonState(r,!h)}}),o=n("I","fontStyle",()=>{if(this.currentNodeId&&this.onUpdate){const h=o.classList.contains("active"),f=h?"normal":"italic";this.onUpdate(this.currentNodeId,{fontStyle:f}),this.updateButtonState(o,!h)}});e.appendChild(r),e.appendChild(o),t.appendChild(e);const a=document.createElement("div");a.style.display="flex",a.style.gap="4px",a.style.alignItems="center",a.style.justifyContent="space-between";const d=document.createElement("input");return d.type="color",d.style.width="24px",d.style.height="24px",d.style.border="1px solid #ccc",d.style.padding="0",d.style.backgroundColor="transparent",d.style.cursor="pointer",d.style.appearance="none",d.onchange=h=>{this.currentNodeId&&this.onUpdate&&(this.onUpdate(this.currentNodeId,{color:h.target.value}),this.updateActivePaletteItem(h.target.value))},I.PALETTE.forEach((h,f)=>{const p=document.createElement("div");p.className="color-swatch",p.dataset.color=h,p.textContent=(f+1).toString(),p.style.width="24px",p.style.height="24px",p.style.backgroundColor=h,p.style.borderRadius="4px",p.style.cursor="pointer",p.style.border="1px solid transparent",p.style.color=h==="#F1C40F"?"black":"white",p.style.fontSize="12px",p.style.fontWeight="bold",p.style.display="flex",p.style.justifyContent="center",p.style.alignItems="center",p.onclick=()=>{this.currentNodeId&&this.onUpdate&&(this.onUpdate(this.currentNodeId,{color:h}),d.value=h,this.updateActivePaletteItem(h))},a.appendChild(p)}),a.appendChild(d),t.appendChild(a),t}updateActivePaletteItem(t){this.editorEl.querySelectorAll(".color-swatch").forEach(i=>{var n;const s=i;((n=s.dataset.color)==null?void 0:n.toLowerCase())===t.toLowerCase()?(s.style.border="2px solid #ccc",s.style.transform="scale(1.1)"):(s.style.border="1px solid transparent",s.style.transform="scale(1)")})}updateButtonState(t,e){e?(t.classList.add("active"),t.style.backgroundColor="#e0e0e0",t.style.borderColor="#999"):(t.classList.remove("active"),t.style.backgroundColor="#f5f5f5",t.style.borderColor="#ddd")}show(t,e){this.currentNodeId=t,this.editorEl.style.display="flex";const i=this.editorEl.querySelector("select");i.value=e.fontSize||"";const s=this.editorEl.querySelector('input[type="color"]'),n=e.color||"#000000";s.value=n,this.updateActivePaletteItem(n);const r=this.editorEl.querySelectorAll("button")[0];this.updateButtonState(r,e.fontWeight==="bold");const o=this.editorEl.querySelectorAll("button")[1];this.updateButtonState(o,e.fontStyle==="italic")}hide(){this.editorEl.style.display="none",this.currentNodeId=null}};c(I,"FONT_SIZES",[{label:"12px",value:"12px"},{label:"14px",value:"14px"},{label:"16px",value:"16px"},{label:"18px",value:"18px"},{label:"24px",value:"24px"},{label:"32px",value:"32px"},{label:"48px",value:"48px"}]),c(I,"PALETTE",["#000000","#E74C3C","#E67E22","#F1C40F","#2ECC71","#3498DB","#9B59B6"]);let S=I;class V{constructor(t,e){c(this,"container");c(this,"element");c(this,"options");c(this,"currentMode","Right");c(this,"currentTheme","default");c(this,"layoutButtons",new Map);c(this,"themeButtons",new Map);this.container=t,this.options=e,this.element=document.createElement("div"),this.render()}render(){this.element.style.position="absolute",this.element.style.top="20px",this.element.style.left="20px",this.element.style.display="flex",this.element.style.flexDirection="column",this.element.style.backgroundColor="white",this.element.style.borderRadius="8px",this.element.style.boxShadow="0 2px 10px rgba(0,0,0,0.1)",this.element.style.padding="5px",this.element.style.zIndex="2000",this.element.style.gap="5px",this.element.style.pointerEvents="auto",this.element.addEventListener("click",t=>t.stopPropagation()),this.element.addEventListener("mousedown",t=>t.stopPropagation()),this.createLayoutButton("Right",this.getRightIcon()),this.createLayoutButton("Left",this.getLeftIcon()),this.createLayoutButton("Both",this.getBothIcon()),this.addSeparator(),this.createThemeButton("default",this.getThemeDefaultIcon()),this.createThemeButton("simple",this.getThemeSimpleIcon()),this.createThemeButton("colorful",this.getThemeColorfulIcon()),this.addSeparator(),this.createIconActionButton("Reset Zoom",this.getZoomResetIcon(),()=>{this.options.onZoomReset&&this.options.onZoomReset()}),this.container.appendChild(this.element),this.updateActiveButtons()}addSeparator(){const t=document.createElement("div");t.style.height="1px",t.style.backgroundColor="#ccc",t.style.margin="5px 2px",this.element.appendChild(t)}createLayoutButton(t,e){const i=document.createElement("button");i.innerHTML=e,this.styleButton(i),i.title=`Layout: ${t}`,i.addEventListener("click",()=>{this.setMode(t)}),this.element.appendChild(i),this.layoutButtons.set(t,i)}createThemeButton(t,e){const i=document.createElement("button");i.innerHTML=e,this.styleButton(i),i.title=`Theme: ${t}`,i.addEventListener("click",()=>{this.setTheme(t)}),this.element.appendChild(i),this.themeButtons.set(t,i)}createIconActionButton(t,e,i){const s=document.createElement("button");s.innerHTML=e,this.styleButton(s),s.title=t,s.addEventListener("click",i),this.element.appendChild(s)}styleButton(t){t.style.width="32px",t.style.height="32px",t.style.border="none",t.style.background="transparent",t.style.cursor="pointer",t.style.borderRadius="4px",t.style.display="flex",t.style.alignItems="center",t.style.justifyContent="center",t.style.color="#555"}updateActiveButtons(){this.layoutButtons.forEach((t,e)=>{e===this.currentMode?(t.style.backgroundColor="#e6f7ff",t.style.color="#007bff"):(t.style.backgroundColor="transparent",t.style.color="#555")}),this.themeButtons.forEach((t,e)=>{e===this.currentTheme?(t.style.backgroundColor="#e6f7ff",t.style.color="#007bff"):(t.style.backgroundColor="transparent",t.style.color="#555")})}setMode(t){this.currentMode!==t&&(this.currentMode=t,this.updateActiveButtons(),this.options.onLayoutChange(t))}setTheme(t){this.currentTheme!==t&&(this.currentTheme=t,this.updateActiveButtons(),this.options.onThemeChange(t))}getRightIcon(){return`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
1
|
+
(function(x,v){typeof exports=="object"&&typeof module<"u"?v(exports):typeof define=="function"&&define.amd?define(["exports"],v):(x=typeof globalThis<"u"?globalThis:x||self,v(x.kakidash={}))})(this,function(x){"use strict";var de=Object.defineProperty;var ae=(x,v,b)=>v in x?de(x,v,{enumerable:!0,configurable:!0,writable:!0,value:b}):x[v]=b;var c=(x,v,b)=>ae(x,typeof v!="symbol"?v+"":v,b);class v{constructor(t){c(this,"root");c(this,"theme","default");this.root=t}findNode(t){return this.findNodeRecursive(this.root,t)}findNodeRecursive(t,e){if(t.id===e)return t;for(const i of t.children){const s=this.findNodeRecursive(i,e);if(s)return s}return null}moveNode(t,e){const i=this.findNode(t),s=this.findNode(e);if(!i||!s||i.isRoot||i.parentId===e||this.isDescendant(i,e))return!1;if(i.parentId){const n=this.findNode(i.parentId);n&&n.removeChild(t)}return s.addChild(i),!0}addSibling(t,e,i){const s=this.findNode(t);if(!s||!s.parentId)return!1;const n=this.findNode(s.parentId);if(!n)return!1;const r=n.children.findIndex(a=>a.id===t);if(r===-1)return!1;const o=i==="before"?r:r+1;return n.insertChild(e,o),!0}insertParent(t,e){const i=this.findNode(t);if(!i||!i.parentId)return!1;const s=this.findNode(i.parentId);if(!s)return!1;const n=s.children.findIndex(r=>r.id===t);return n===-1?!1:(s.removeChild(t),s.insertChild(e,n),e.addChild(i),!0)}isDescendant(t,e){if(t.id===e)return!0;for(const i of t.children)if(this.isDescendant(i,e))return!0;return!1}}class b{constructor(t,e,i=null,s=!1,n,r){c(this,"id");c(this,"topic");c(this,"children");c(this,"style");c(this,"parentId");c(this,"isRoot");c(this,"image");c(this,"layoutSide");this.id=t,this.topic=e,this.children=[],this.style={fontSize:s?"24px":"16px"},this.parentId=i,this.isRoot=s,this.image=n,this.layoutSide=r}addChild(t){t.parentId=this.id,this.children.push(t)}insertChild(t,e){t.parentId=this.id,e>=0&&e<=this.children.length?this.children.splice(e,0,t):this.children.push(t)}removeChild(t){this.children=this.children.filter(e=>e.id!==t)}updateTopic(t){this.topic=t}}class _{constructor(t=10){c(this,"past",[]);c(this,"future",[]);c(this,"maxHistorySize");this.maxHistorySize=t}push(t){this.past.push(t),this.past.length>this.maxHistorySize&&this.past.shift(),this.future=[]}undo(t){if(this.past.length===0)return null;const e=this.past.pop();return e?(this.future.push(t),e):null}get canUndo(){return this.past.length>0}redo(t){if(this.future.length===0)return null;const e=this.future.pop();return e?(this.past.push(t),this.past.length>this.maxHistorySize&&this.past.shift(),e):null}get canRedo(){return this.future.length>0}clear(){this.past=[],this.future=[]}}class G{constructor(t){c(this,"mindMap");c(this,"historyManager");c(this,"clipboard",null);this.mindMap=t,this.historyManager=new _(10)}saveState(){this.historyManager.push(this.exportData())}undo(){const t=this.historyManager.undo(this.exportData());return t?(this.importData(t),!0):!1}get canUndo(){return this.historyManager.canUndo}addNode(t,e="New topic",i){const s=this.mindMap.findNode(t);if(!s)return null;this.saveState();const n=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),r=new b(n,e,null,!1,void 0,i);return s.addChild(r),r}addImageNode(t,e){const i=this.mindMap.findNode(t);if(!i)return null;this.saveState();const s=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),n=new b(s,"",t,!1,e);return i.addChild(n),n}removeNode(t,e=!0){const i=this.mindMap.findNode(t);if(!i||i.isRoot||!i.parentId)return!1;const s=this.mindMap.findNode(i.parentId);return s?(e&&this.saveState(),s.removeChild(t),!0):!1}updateNodeTopic(t,e){const i=this.mindMap.findNode(t);return i?(this.saveState(),i.updateTopic(e),!0):!1}updateNodeStyle(t,e){const i=this.mindMap.findNode(t);return i?(this.saveState(),i.style={...i.style,...e},!0):!1}setTheme(t){this.mindMap.theme!==t&&(this.saveState(),this.mindMap.theme=t)}moveNode(t,e,i){const s=this.mindMap.findNode(t);if(s&&s.parentId===e)return i&&s.layoutSide!==i?(this.saveState(),s.layoutSide=i,!0):!1;if(!s)return!1;if(this.saveState(),this.mindMap.moveNode(t,e)){if(i){const n=this.mindMap.findNode(t);n&&(n.layoutSide=i)}return!0}return!1}addSibling(t,e,i="New topic"){const s=this.mindMap.findNode(t);if(!s||!s.parentId)return null;this.saveState();const n=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),r=new b(n,i);return this.mindMap.addSibling(t,r,e)?r:null}reorderNode(t,e,i){const s=this.mindMap.findNode(t),n=this.mindMap.findNode(e);if(!s||!n||!n.parentId||s.id===n.id||s.isRoot)return!1;const r=this.mindMap.findNode(n.parentId);if(!r)return!1;if(this.saveState(),s.parentId!==r.id){let d=r;for(;d.parentId;){if(d.id===s.id)return!1;if(!d.parentId)break;const h=this.mindMap.findNode(d.parentId);if(!h)break;d=h}}if(s.parentId&&s.parentId!==r.id){const d=this.mindMap.findNode(s.parentId);d&&d.removeChild(s.id),s.parentId=r.id}else s.parentId===r.id&&r.removeChild(s.id);const o=r.children.findIndex(d=>d.id===e);if(o===-1)return r.addChild(s),!0;const a=i==="before"?o:o+1;return r.insertChild(s,a),r.isRoot&&n.layoutSide&&(s.layoutSide=n.layoutSide),!0}insertNodeAsParent(t,e){const i=this.mindMap.findNode(t),s=this.mindMap.findNode(e);if(!i||!s||!s.parentId||i.id===s.id)return!1;const n=this.mindMap.findNode(s.parentId);if(!n)return!1;let r=n;for(;r;){if(r.id===i.id)return!1;if(!r.parentId)break;r=this.mindMap.findNode(r.parentId)}if(this.saveState(),i.parentId){const a=this.mindMap.findNode(i.parentId);a&&a.removeChild(i.id)}const o=n.children.findIndex(a=>a.id===e);return o===-1?!1:(n.isRoot&&s.layoutSide&&(i.layoutSide=s.layoutSide),n.removeChild(e),n.insertChild(i,o),i.parentId=n.id,i.addChild(s),!0)}insertParent(t,e="New topic"){const i=this.mindMap.findNode(t);if(!i||!i.parentId)return null;this.saveState();const s=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),n=new b(s,e);return this.mindMap.insertParent(t,n)?n:null}copyNode(t){const e=this.mindMap.findNode(t);e&&(this.clipboard=this.deepCloneNode(e),navigator.clipboard&&navigator.clipboard.writeText(e.topic).catch(i=>{console.error("Failed to write to clipboard",i)}))}cutNode(t){const e=this.mindMap.findNode(t);e&&!e.isRoot&&e.parentId&&(this.copyNode(t),this.removeNode(t))}pasteNode(t){if(!this.clipboard)return null;const e=this.mindMap.findNode(t);if(!e)return null;this.saveState();const i=this.deepCloneNode(this.clipboard);return this.regenerateIds(i),e.addChild(i),i}deepCloneNode(t){const e=new b(t.id,t.topic,null,!1,t.image,t.layoutSide);return e.style={...t.style},e.children=t.children.map(i=>this.deepCloneNode(i)),e.children.forEach(i=>i.parentId=e.id),e}regenerateIds(t){t.id=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),t.children.forEach(e=>{e.parentId=t.id,this.regenerateIds(e)})}exportData(){const t=e=>({id:e.id,topic:e.topic,root:e.isRoot||void 0,children:e.children.length>0?e.children.map(t):void 0,style:Object.keys(e.style).length>0?e.style:void 0,image:e.image,layoutSide:e.layoutSide});return{nodeData:t(this.mindMap.root),theme:this.mindMap.theme}}importData(t){const e=(i,s=null)=>{const n=!!i.root,r=new b(i.id,i.topic,s,n,i.image,i.layoutSide);return i.style&&(r.style={...i.style}),i.children&&i.children.length>0&&i.children.forEach(o=>{const a=e(o,r.id);r.addChild(a)}),r};this.mindMap.root=e(t.nodeData),t.theme&&(this.mindMap.theme=t.theme)}}const k=class k{constructor(t,e={}){c(this,"container");c(this,"svg");c(this,"nodeContainer");c(this,"options");this.container=t,this.container.style.position="relative",this.container.style.width="100%",this.container.style.height="100%",this.container.style.overflow="hidden",this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.position="absolute",this.svg.style.top="0",this.svg.style.left="0",this.svg.style.width="100%",this.svg.style.height="100%",this.svg.style.zIndex="0",this.svg.style.pointerEvents="none",this.svg.style.overflow="visible",this.svg.style.transformOrigin="0 0",this.container.appendChild(this.svg),this.nodeContainer=document.createElement("div"),this.nodeContainer.style.position="absolute",this.nodeContainer.style.top="0",this.nodeContainer.style.left="0",this.nodeContainer.style.width="100%",this.nodeContainer.style.height="100%",this.nodeContainer.style.zIndex="1",this.nodeContainer.style.transformOrigin="0 0",this.container.appendChild(this.nodeContainer),this.options=e}render(t,e=null,i="Right"){this.svg.innerHTML="",this.nodeContainer.innerHTML="",this.renderNode(t.root,0,this.container.clientHeight/2,e,i,!0,void 0,t)}updateTransform(t,e,i=1){const s=`translate(${t}px, ${e}px) scale(${i})`;this.svg.style.transform=s,this.nodeContainer.style.transform=s}getThemeColor(t,e){if(e.theme==="colorful"){if(t.isRoot)return"#333";let i=t;for(;i.parentId&&i.parentId!==e.root.id;){const r=e.findNode(i.parentId);if(!r)break;i=r}const n=e.root.children.findIndex(r=>r.id===i.id);if(n!==-1)return k.RAINBOW_PALETTE[n%k.RAINBOW_PALETTE.length]}return"#ccc"}renderNode(t,e,i,s,n,r,o="right",a){const d=document.createElement("div");if(d.dataset.id=t.id,t.image){const m=document.createElement("img");m.src=t.image,m.style.maxWidth="150px",m.style.maxHeight="150px",m.style.display="block",d.appendChild(m);const u=document.createElement("div");u.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="11" y1="8" x2="11" y2="14"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>',u.style.position="absolute",u.style.bottom="5px",u.style.right="5px",u.style.backgroundColor="rgba(255, 255, 255, 0.9)",u.style.borderRadius="50%",u.style.width="24px",u.style.height="24px",u.style.display="flex",u.style.justifyContent="center",u.style.alignItems="center",u.style.cursor="pointer",u.title="Zoom Image",u.style.boxShadow="0 1px 3px rgba(0,0,0,0.2)",d.appendChild(u),u.addEventListener("click",C=>{C.stopPropagation(),this.showImageModal(t.image)}),d.style.padding="5px"}else d.textContent=t.topic,d.style.whiteSpace="pre";d.className="mindmap-node",t.isRoot||(d.draggable=!0),d.style.position="absolute",d.style.padding="8px 12px",t.image&&(d.style.padding="5px"),d.style.backgroundColor="white";const h=(a==null?void 0:a.theme)||"default",f=a?this.getThemeColor(t,a):"#ccc";h==="simple"&&!t.isRoot?d.style.border="none":h==="colorful"?d.style.border=`2px solid ${f}`:d.style.border="1px solid #ccc",d.style.borderRadius="4px",t.isRoot&&(d.style.fontSize="1.2em",d.style.fontWeight="bold",d.style.border="2px solid #333"),t.style.color&&(d.style.color=t.style.color),t.style.fontSize&&(d.style.fontSize=t.style.fontSize),t.style.fontWeight&&(d.style.fontWeight=t.style.fontWeight),t.style.fontStyle&&(d.style.fontStyle=t.style.fontStyle),t.style.background&&(d.style.backgroundColor=t.style.background);const{width:p}=this.measureNode(t);let l=e;if(o==="left"&&!r?l=e-p:r&&(l=e-p/2),d.style.left=`${l}px`,d.style.top=`${i}px`,d.style.transform="translate(0, -50%)",d.style.zIndex="10",d.style.cursor="default",d.style.userSelect="none",t.id===s&&(d.style.outline="2px solid #007bff",d.style.boxShadow="0 0 5px rgba(0, 123, 255, 0.5)"),this.nodeContainer.appendChild(d),t.children.length===0)return;let y=[],g=[];r&&n==="Both"?t.children.forEach((m,u)=>{(m.layoutSide||(u%2===0?"right":"left"))==="right"?y.push(m):g.push(m)}):n==="Left"?g=t.children:n==="Right"?y=t.children:o==="left"?g=t.children:y=t.children,y.length>0&&this.renderChildrenStack(t,y,e,i,s,n,"right",p,a),g.length>0&&this.renderChildrenStack(t,g,e,i,s,n,"left",p,a)}renderChildrenStack(t,e,i,s,n,r,o,a,d){const h=e.reduce((y,g)=>y+this.getNodeHeight(g),0);let f=s-h/2;const p=80;let l=0;t.isRoot?l=o==="right"?i+a/2:i-a/2:o==="right"?l=i+a:(l=i,l=i-a),e.forEach(y=>{const g=this.getNodeHeight(y),m=f+g/2;let u=0;o==="right"?u=l+p:u=l-p,this.renderNode(y,u,m,n,r,!1,o,d);const C=d?this.getThemeColor(y,d):"#ccc";this.drawConnection(l,s,u,m,C),f+=g})}getChildrenHeight(t){return t.children.reduce((e,i)=>e+this.getNodeHeight(i),0)}getNodeHeight(t){const{height:e}=this.measureNode(t),i=20;if(t.children.length===0)return e+i;const s=this.getChildrenHeight(t);return Math.max(e+i,s)}measureNode(t){if(t.image)return{width:160,height:160};const e=document.createElement("div");e.textContent=t.topic,e.className="mindmap-node",e.style.visibility="hidden",e.style.position="absolute",e.style.whiteSpace="pre",e.style.padding="8px 12px",e.style.border="1px solid #ccc",t.isRoot&&(e.style.fontSize="1.2em",e.style.fontWeight="bold",e.style.border="2px solid #333"),t.style.color&&(e.style.color=t.style.color),t.style.fontSize&&(e.style.fontSize=t.style.fontSize),t.style.fontWeight&&(e.style.fontWeight=t.style.fontWeight),t.style.fontStyle&&(e.style.fontStyle=t.style.fontStyle),t.style.background&&(e.style.backgroundColor=t.style.background),this.nodeContainer.appendChild(e);const i=e.offsetWidth,s=e.offsetHeight;return this.nodeContainer.removeChild(e),{width:i||100,height:s||40}}drawConnection(t,e,i,s,n="#ccc"){const r=document.createElementNS("http://www.w3.org/2000/svg","path"),o=t+(i-t)/2,a=t+(i-t)/2,d=`M ${t} ${e} C ${o} ${e}, ${a} ${s}, ${i} ${s}`;r.setAttribute("d",d),r.setAttribute("stroke",n),r.setAttribute("fill","none"),r.setAttribute("stroke-width","2"),this.svg.appendChild(r)}showImageModal(t){this.options.onImageZoom&&this.options.onImageZoom(!0);const e=document.createElement("div");e.style.position="fixed",e.style.top="0",e.style.left="0",e.style.width="100vw",e.style.height="100vh",e.style.backgroundColor="rgba(0,0,0,0.8)",e.style.zIndex="1000",e.style.display="flex",e.style.justifyContent="center",e.style.alignItems="center",e.style.cursor="zoom-out";const i=document.createElement("img");i.src=t,i.style.maxWidth="90%",i.style.maxHeight="90%",i.style.boxShadow="0 0 20px rgba(0,0,0,0.5)",e.appendChild(i),document.body.appendChild(e);let s;const n=()=>{document.body.contains(e)&&document.body.removeChild(e),s&&document.removeEventListener("keydown",s,!0),this.options.onImageZoom&&this.options.onImageZoom(!1),this.container.focus()};s=r=>{r.stopPropagation(),r.preventDefault(),n()},document.addEventListener("keydown",s,!0),e.addEventListener("click",()=>{n()})}};c(k,"RAINBOW_PALETTE",["#E74C3C","#3498DB","#2ECC71","#F1C40F","#9B59B6","#E67E22","#1ABC9C"]);let L=k;const E=class E{constructor(t){c(this,"container");c(this,"editorEl");c(this,"currentNodeId",null);c(this,"onUpdate");this.container=t,this.editorEl=this.createEditor(),this.container.appendChild(this.editorEl),this.editorEl.addEventListener("mousedown",e=>e.stopPropagation()),this.editorEl.addEventListener("click",e=>e.stopPropagation()),this.editorEl.addEventListener("dblclick",e=>e.stopPropagation())}createEditor(){const t=document.createElement("div");t.className="style-editor",t.style.position="absolute",t.style.top="20px",t.style.right="20px",t.style.display="none",t.style.backgroundColor="white",t.style.border="1px solid #eee",t.style.borderRadius="8px",t.style.padding="8px",t.style.boxShadow="0 4px 12px rgba(0,0,0,0.1)",t.style.zIndex="2000",t.style.pointerEvents="auto",t.style.fontFamily="Arial, sans-serif",t.style.display="flex",t.style.flexDirection="column",t.style.gap="8px",t.style.margin="0",t.style.boxSizing="border-box",t.style.minWidth="220px";const e=document.createElement("div");e.style.display="flex",e.style.gap="8px",e.style.alignItems="center";const i=document.createElement("select");i.style.padding="4px 8px",i.style.borderRadius="4px",i.style.border="1px solid #ccc",i.style.fontSize="14px",i.style.flex="1",E.FONT_SIZES.forEach(h=>{const f=document.createElement("option");f.value=h.value,f.textContent=h.label,i.appendChild(f)}),i.onchange=h=>{this.currentNodeId&&this.onUpdate&&this.onUpdate(this.currentNodeId,{fontSize:h.target.value})},e.appendChild(i);const n=(h,f,p)=>{const l=document.createElement("button");return l.textContent=h,l.style.width="32px",l.style.height="32px",l.style.padding="0",l.style.display="flex",l.style.justifyContent="center",l.style.alignItems="center",l.style.border="1px solid #ddd",l.style.backgroundColor="#f5f5f5",l.style.borderRadius="4px",l.style.cursor="pointer",l.style.fontSize="14px",f&&(l.style[f]=f==="fontWeight"?"bold":"italic"),l.onclick=p,l},r=n("B","fontWeight",()=>{if(this.currentNodeId&&this.onUpdate){const h=r.classList.contains("active"),f=h?"normal":"bold";this.onUpdate(this.currentNodeId,{fontWeight:f}),this.updateButtonState(r,!h)}}),o=n("I","fontStyle",()=>{if(this.currentNodeId&&this.onUpdate){const h=o.classList.contains("active"),f=h?"normal":"italic";this.onUpdate(this.currentNodeId,{fontStyle:f}),this.updateButtonState(o,!h)}});e.appendChild(r),e.appendChild(o),t.appendChild(e);const a=document.createElement("div");a.style.display="flex",a.style.gap="4px",a.style.alignItems="center",a.style.justifyContent="space-between";const d=document.createElement("input");return d.type="color",d.style.width="24px",d.style.height="24px",d.style.border="1px solid #ccc",d.style.padding="0",d.style.backgroundColor="transparent",d.style.cursor="pointer",d.style.appearance="none",d.onchange=h=>{this.currentNodeId&&this.onUpdate&&(this.onUpdate(this.currentNodeId,{color:h.target.value}),this.updateActivePaletteItem(h.target.value))},E.PALETTE.forEach((h,f)=>{const p=document.createElement("div");p.className="color-swatch",p.dataset.color=h,p.textContent=(f+1).toString(),p.style.width="24px",p.style.height="24px",p.style.backgroundColor=h,p.style.borderRadius="4px",p.style.cursor="pointer",p.style.border="1px solid transparent",p.style.color=h==="#F1C40F"?"black":"white",p.style.fontSize="12px",p.style.fontWeight="bold",p.style.display="flex",p.style.justifyContent="center",p.style.alignItems="center",p.onclick=()=>{this.currentNodeId&&this.onUpdate&&(this.onUpdate(this.currentNodeId,{color:h}),d.value=h,this.updateActivePaletteItem(h))},a.appendChild(p)}),a.appendChild(d),t.appendChild(a),t}updateActivePaletteItem(t){this.editorEl.querySelectorAll(".color-swatch").forEach(i=>{var n;const s=i;((n=s.dataset.color)==null?void 0:n.toLowerCase())===t.toLowerCase()?(s.style.border="2px solid #ccc",s.style.transform="scale(1.1)"):(s.style.border="1px solid transparent",s.style.transform="scale(1)")})}updateButtonState(t,e){e?(t.classList.add("active"),t.style.backgroundColor="#e0e0e0",t.style.borderColor="#999"):(t.classList.remove("active"),t.style.backgroundColor="#f5f5f5",t.style.borderColor="#ddd")}show(t,e){this.currentNodeId=t,this.editorEl.style.display="flex";const i=this.editorEl.querySelector("select");i.value=e.fontSize||"";const s=this.editorEl.querySelector('input[type="color"]'),n=e.color||"#000000";s.value=n,this.updateActivePaletteItem(n);const r=this.editorEl.querySelectorAll("button")[0];this.updateButtonState(r,e.fontWeight==="bold");const o=this.editorEl.querySelectorAll("button")[1];this.updateButtonState(o,e.fontStyle==="italic")}hide(){this.editorEl.style.display="none",this.currentNodeId=null}};c(E,"FONT_SIZES",[{label:"12px",value:"12px"},{label:"14px",value:"14px"},{label:"16px",value:"16px"},{label:"18px",value:"18px"},{label:"24px",value:"24px"},{label:"32px",value:"32px"},{label:"48px",value:"48px"}]),c(E,"PALETTE",["#000000","#E74C3C","#E67E22","#F1C40F","#2ECC71","#3498DB","#9B59B6"]);let I=E;class J{constructor(t,e){c(this,"container");c(this,"element");c(this,"options");c(this,"currentMode","Right");c(this,"currentTheme","default");c(this,"layoutButtons",new Map);c(this,"themeButtons",new Map);this.container=t,this.options=e,this.element=document.createElement("div"),this.render()}render(){this.element.style.position="absolute",this.element.style.top="20px",this.element.style.left="20px",this.element.style.display="flex",this.element.style.flexDirection="column",this.element.style.backgroundColor="white",this.element.style.borderRadius="8px",this.element.style.boxShadow="0 2px 10px rgba(0,0,0,0.1)",this.element.style.padding="5px",this.element.style.zIndex="2000",this.element.style.gap="5px",this.element.style.pointerEvents="auto",this.element.addEventListener("click",t=>t.stopPropagation()),this.element.addEventListener("mousedown",t=>t.stopPropagation()),this.createLayoutButton("Right",this.getRightIcon()),this.createLayoutButton("Left",this.getLeftIcon()),this.createLayoutButton("Both",this.getBothIcon()),this.addSeparator(),this.createThemeButton("default",this.getThemeDefaultIcon()),this.createThemeButton("simple",this.getThemeSimpleIcon()),this.createThemeButton("colorful",this.getThemeColorfulIcon()),this.addSeparator(),this.createIconActionButton("Reset Zoom",this.getZoomResetIcon(),()=>{this.options.onZoomReset&&this.options.onZoomReset()}),this.container.appendChild(this.element),this.updateActiveButtons()}addSeparator(){const t=document.createElement("div");t.style.height="1px",t.style.backgroundColor="#ccc",t.style.margin="5px 2px",this.element.appendChild(t)}createLayoutButton(t,e){const i=document.createElement("button");i.innerHTML=e,this.styleButton(i),i.title=`Layout: ${t}`,i.addEventListener("click",()=>{this.setMode(t)}),this.element.appendChild(i),this.layoutButtons.set(t,i)}createThemeButton(t,e){const i=document.createElement("button");i.innerHTML=e,this.styleButton(i),i.title=`Theme: ${t}`,i.addEventListener("click",()=>{this.setTheme(t)}),this.element.appendChild(i),this.themeButtons.set(t,i)}createIconActionButton(t,e,i){const s=document.createElement("button");s.innerHTML=e,this.styleButton(s),s.title=t,s.addEventListener("click",i),this.element.appendChild(s)}styleButton(t){t.style.width="32px",t.style.height="32px",t.style.border="none",t.style.background="transparent",t.style.cursor="pointer",t.style.borderRadius="4px",t.style.display="flex",t.style.alignItems="center",t.style.justifyContent="center",t.style.color="#555"}updateActiveButtons(){this.layoutButtons.forEach((t,e)=>{e===this.currentMode?(t.style.backgroundColor="#e6f7ff",t.style.color="#007bff"):(t.style.backgroundColor="transparent",t.style.color="#555")}),this.themeButtons.forEach((t,e)=>{e===this.currentTheme?(t.style.backgroundColor="#e6f7ff",t.style.color="#007bff"):(t.style.backgroundColor="transparent",t.style.color="#555")})}setMode(t){this.currentMode!==t&&(this.currentMode=t,this.updateActiveButtons(),this.options.onLayoutChange(t))}setTheme(t){this.currentTheme!==t&&(this.currentTheme=t,this.updateActiveButtons(),this.options.onThemeChange(t))}getRightIcon(){return`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
2
|
<circle cx="5" cy="12" r="3"></circle>
|
|
3
3
|
<path d="M8 12h8"></path>
|
|
4
4
|
<path d="M8 12 L16 5"></path>
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
|
32
32
|
<line x1="5" y1="5" x2="17" y2="17"></line>
|
|
33
33
|
<line x1="17" y1="5" x2="5" y2="17"></line>
|
|
34
|
-
</svg>`}}class
|
|
34
|
+
</svg>`}}class Q{constructor(t,e){c(this,"container");c(this,"options");c(this,"selectedNodeId",null);c(this,"draggedNodeId",null);c(this,"isPanning",!1);c(this,"lastMouseX",0);c(this,"lastMouseY",0);c(this,"isReadOnly",!1);c(this,"cleanupFns",[]);this.container=t,this.container.tabIndex=0,this.container.style.outline="none",this.container.style.cursor="default",this.options=e,this.attachEvents()}setReadOnly(t){this.isReadOnly=t,t&&this.draggedNodeId&&(this.draggedNodeId=null)}destroy(){this.cleanupFns.forEach(t=>t()),this.cleanupFns=[]}updateSelection(t){this.selectedNodeId=t}attachEvents(){let t=null;const e=(r,o,a,d)=>{r.addEventListener(o,a,d),this.cleanupFns.push(()=>{typeof r.removeEventListener=="function"&&r.removeEventListener(o,a,d)})};e(this.container,"focus",()=>{}),e(this.container,"blur",()=>{}),e(this.container,"scroll",()=>{(this.container.scrollTop!==0||this.container.scrollLeft!==0)&&(this.container.scrollTop=0,this.container.scrollLeft=0)}),e(this.container,"click",r=>{const a=r.target.closest(".mindmap-node");a&&a.dataset.id?this.options.onNodeClick(a.dataset.id):this.options.onNodeClick(""),this.container.focus()}),e(this.container,"mousedown",r=>{const o=r,a=o.target;!a.closest(".mindmap-node")&&a.tagName!=="INPUT"&&(this.isPanning=!0,this.lastMouseX=o.clientX,this.lastMouseY=o.clientY,this.container.style.cursor="all-scroll")}),e(window,"mousemove",r=>{const o=r;if(this.isPanning){const a=o.clientX-this.lastMouseX,d=o.clientY-this.lastMouseY;this.lastMouseX=o.clientX,this.lastMouseY=o.clientY,this.options.onPan&&this.options.onPan(a,d)}});const i=()=>{this.isPanning&&(this.isPanning=!1,this.container.style.cursor="default")};e(window,"mouseup",i),e(window,"mouseleave",i),e(this.container,"wheel",r=>{const o=r;if(o.preventDefault(),o.ctrlKey||o.metaKey){this.options.onZoom&&this.options.onZoom(o.deltaY,o.clientX,o.clientY);return}let a=1;o.deltaMode===1?a=33:o.deltaMode===2&&(a=window.innerHeight);const d=-o.deltaX*a,h=-o.deltaY*a;this.options.onPan&&this.options.onPan(d,h)},{passive:!1}),e(document,"keydown",r=>{var h,f,p,l,y,g,m,u,C,M,D,P,A,O,z,U,X,Y,H,K,F,W,Z,$,j,q;const o=r,a=["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","h","j","k","l"],d=["Tab","Enter","Delete","Backspace"];if(!this.selectedNodeId){if(a.includes(o.key)){o.preventDefault();let N=null,w=1/0;this.container.querySelectorAll(".mindmap-node").forEach(ie=>{const B=ie;if(!B.dataset.id)return;const R=B.getBoundingClientRect(),se=R.left+R.width/2,ne=R.top+R.height/2,T=this.container.getBoundingClientRect(),oe=T.left+T.width/2,re=T.top+T.height/2,V=Math.pow(se-oe,2)+Math.pow(ne-re,2);V<w&&(w=V,N=B.dataset.id)}),N&&this.options.onNodeClick(N)}return}if(!(this.isReadOnly&&!["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","h","j","k","l","c"].includes(o.key))){switch((d.includes(o.key)||a.includes(o.key))&&o.preventDefault(),o.key){case"Tab":if(this.isReadOnly)return;o.shiftKey?(f=(h=this.options).onInsertParent)==null||f.call(h,this.selectedNodeId):this.options.onAddChild(this.selectedNodeId);break;case"Enter":if(this.isReadOnly)return;this.options.onAddSibling(this.selectedNodeId,o.shiftKey?"before":"after");break;case"Delete":case"Backspace":if(this.isReadOnly)return;this.options.onDeleteNode(this.selectedNodeId);break;case"ArrowUp":case"k":(this.isReadOnly||!o.ctrlKey&&!o.metaKey&&!o.altKey)&&((l=(p=this.options).onNavigate)==null||l.call(p,this.selectedNodeId,"Up"));break;case"ArrowDown":case"j":(this.isReadOnly||!o.ctrlKey&&!o.metaKey&&!o.altKey)&&((g=(y=this.options).onNavigate)==null||g.call(y,this.selectedNodeId,"Down"));break;case"ArrowLeft":case"h":(this.isReadOnly||!o.ctrlKey&&!o.metaKey&&!o.altKey)&&((u=(m=this.options).onNavigate)==null||u.call(m,this.selectedNodeId,"Left"));break;case"ArrowRight":case"l":(this.isReadOnly||!o.ctrlKey&&!o.metaKey&&!o.altKey)&&((M=(C=this.options).onNavigate)==null||M.call(C,this.selectedNodeId,"Right"));break;case"F2":{if(this.isReadOnly)return;o.preventDefault();const N=this.container.querySelector(`.mindmap-node[data-id="${this.selectedNodeId}"]`);if(N){if(N.querySelector("img"))return;this.startEditing(N,this.selectedNodeId)}break}case"c":(o.metaKey||o.ctrlKey)&&(o.preventDefault(),(P=(D=this.options).onCopyNode)==null||P.call(D,this.selectedNodeId));break;case"v":if(this.isReadOnly)return;(o.metaKey||o.ctrlKey)&&(t&&clearTimeout(t),t=setTimeout(()=>{var N,w;this.selectedNodeId&&((w=(N=this.options).onPasteNode)==null||w.call(N,this.selectedNodeId))},50));break;case"x":if(this.isReadOnly)return;(o.metaKey||o.ctrlKey)&&(o.preventDefault(),(O=(A=this.options).onCutNode)==null||O.call(A,this.selectedNodeId));break;case"z":if(this.isReadOnly)return;(o.metaKey||o.ctrlKey)&&(o.preventDefault(),o.shiftKey||(U=(z=this.options).onUndo)==null||U.call(z));break;case"b":if(this.isReadOnly)return;(o.metaKey||o.ctrlKey)&&(o.preventDefault(),(Y=(X=this.options).onStyleAction)==null||Y.call(X,this.selectedNodeId,{type:"bold"}));break;case"i":{if(this.isReadOnly)return;if(o.metaKey||o.ctrlKey)o.preventDefault(),(K=(H=this.options).onStyleAction)==null||K.call(H,this.selectedNodeId,{type:"italic"});else{o.preventDefault();const N=this.container.querySelector(`.mindmap-node[data-id="${this.selectedNodeId}"]`);if(N){if(N.querySelector("img"))return;this.startEditing(N,this.selectedNodeId)}}break}case" ":if(this.isReadOnly)return;o.preventDefault();{const N=this.container.querySelector(`.mindmap-node[data-id="${this.selectedNodeId}"]`);if(N){const w=N.querySelector('[title="Zoom Image"]');w&&w.click()}}break;case"+":case"=":if(this.isReadOnly)return;(o.key==="+"||o.key==="="&&o.shiftKey)&&((W=(F=this.options).onStyleAction)==null||W.call(F,this.selectedNodeId,{type:"increaseSize"}));break;case"-":if(this.isReadOnly)return;($=(Z=this.options).onStyleAction)==null||$.call(Z,this.selectedNodeId,{type:"decreaseSize"});break}if(/^[1-7]$/.test(o.key)){if(this.isReadOnly)return;if(!o.ctrlKey&&!o.metaKey&&!o.altKey){const N=parseInt(o.key)-1;(q=(j=this.options).onStyleAction)==null||q.call(j,this.selectedNodeId,{type:"color",index:N})}}}}),e(document,"paste",r=>{var h,f,p,l,y;const o=r;if(t&&(clearTimeout(t),t=null),this.isReadOnly||!this.selectedNodeId)return;const a=(h=o.clipboardData)==null?void 0:h.items;if(!a||a.length===0){(p=(f=this.options).onPasteNode)==null||p.call(f,this.selectedNodeId);return}let d=!1;for(const g of a)if(g.type.startsWith("image/")){const m=g.getAsFile();if(m){const u=new FileReader;u.onload=C=>{var M;(M=C.target)!=null&&M.result&&this.options.onPasteImage&&this.selectedNodeId&&this.options.onPasteImage(this.selectedNodeId,C.target.result)},u.readAsDataURL(m)}o.preventDefault(),d=!0;break}d||(y=(l=this.options).onPasteNode)==null||y.call(l,this.selectedNodeId)});const s=document.createElement("style");s.textContent=`
|
|
35
35
|
.mindmap-node.drag-over-top {
|
|
36
36
|
border-top: 4px solid #007bff !important;
|
|
37
37
|
}
|
|
@@ -45,4 +45,4 @@
|
|
|
45
45
|
border-right: 4px solid #007bff !important;
|
|
46
46
|
}
|
|
47
47
|
`,document.head.appendChild(s),this.container.addEventListener("dragstart",r=>{var d;if(this.isReadOnly){r.preventDefault();return}const a=r.target.closest(".mindmap-node");a&&a.dataset.id&&(this.draggedNodeId=a.dataset.id,(d=r.dataTransfer)==null||d.setData("text/plain",a.dataset.id),r.dataTransfer&&(r.dataTransfer.effectAllowed="move"))}),this.cleanupFns.push(()=>{});const n=(r,o)=>{const a=o.getBoundingClientRect(),d=r.clientX-a.left,h=r.clientY-a.top,f=a.width,p=a.height;return h<p*.25?"top":h>p*.75?"bottom":d<f*.25?"left":(d>f*.75,"right")};e(this.container,"dragstart",r=>{var h;const o=r;if(this.isReadOnly){o.preventDefault();return}const d=o.target.closest(".mindmap-node");d&&d.dataset.id&&(this.draggedNodeId=d.dataset.id,(h=o.dataTransfer)==null||h.setData("text/plain",d.dataset.id),o.dataTransfer&&(o.dataTransfer.effectAllowed="move"))}),e(this.container,"dragover",r=>{const o=r;if(this.isReadOnly)return;o.preventDefault();const d=o.target.closest(".mindmap-node");if(d&&d.dataset.id&&this.draggedNodeId&&d.dataset.id!==this.draggedNodeId){const h=n(o,d);d.classList.remove("drag-over-top","drag-over-bottom","drag-over-left","drag-over-right"),d.classList.add(`drag-over-${h}`),o.dataTransfer&&(o.dataTransfer.dropEffect="move")}}),e(this.container,"dragleave",r=>{const a=r.target.closest(".mindmap-node");a&&a.classList.remove("drag-over-top","drag-over-bottom","drag-over-left","drag-over-right")}),e(this.container,"drop",r=>{const o=r;o.preventDefault();const d=o.target.closest(".mindmap-node");if(this.container.querySelectorAll(".mindmap-node").forEach(h=>{h.classList.remove("drag-over-top","drag-over-bottom","drag-over-left","drag-over-right")}),!this.isReadOnly){if(d&&d.dataset.id&&this.draggedNodeId){const h=d.dataset.id;if(this.draggedNodeId!==h){const f=n(o,d);this.options.onDropNode(this.draggedNodeId,h,f)}}this.draggedNodeId=null}}),e(this.container,"dragend",()=>{this.draggedNodeId=null,this.container.querySelectorAll(".mindmap-node").forEach(r=>{r.classList.remove("drag-over-top","drag-over-bottom","drag-over-left","drag-over-right")})}),e(this.container,"dblclick",r=>{if(this.isReadOnly)return;const a=r.target.closest(".mindmap-node");a&&a.dataset.id&&this.startEditing(a,a.dataset.id)})}editNode(t){const e=this.container.querySelector(`.mindmap-node[data-id="${t}"]`);e&&this.startEditing(e,t)}startEditing(t,e){const i=t.textContent||"",s=document.createElement("textarea");s.value=i,s.style.position="absolute",s.style.top=t.style.top,s.style.left=t.style.left,s.style.transform=t.style.transform,s.style.overflow="hidden",s.style.resize="none",s.style.minHeight="1em";const n=window.getComputedStyle(t);s.style.font=n.font,s.style.padding=n.padding,s.style.boxSizing="border-box",s.style.backgroundColor=n.backgroundColor,s.style.border="none",s.style.outline="none",s.style.boxShadow="none",s.style.borderTop=n.borderTop,s.style.borderRight=n.borderRight,s.style.borderBottom=n.borderBottom,s.style.borderLeft=n.borderLeft,s.style.borderRadius=n.borderRadius,s.style.zIndex="100";const r=t.style.outline,o=t.style.boxShadow;t.style.outline="none",t.style.boxShadow="none";const a=()=>{const l=document.createElement("span");l.style.font=n.font,l.style.padding=n.padding,l.style.whiteSpace="pre-wrap",l.style.visibility="hidden",l.style.position="absolute",l.textContent=s.value||"",(s.value.endsWith(`
|
|
48
|
-
`)||s.value==="")&&(l.textContent+=""),document.body.appendChild(l);const y=l.offsetWidth+20,g=l.offsetHeight+10;s.style.width=Math.max(y,t.offsetWidth)+"px",s.style.height=Math.max(g,t.offsetHeight)+"px",document.body.removeChild(l)};a(),s.addEventListener("input",a);let d=!1;const h=()=>{s.parentNode&&s.parentNode.contains(s)&&s.parentNode.removeChild(s),t.style.outline=r,t.style.boxShadow=o},f=()=>{if(d)return;d=!0;const l=s.value;l!==i&&this.options.onUpdateNode&&this.options.onUpdateNode(e,l),h()};s.addEventListener("blur",()=>{d||f()});const p=()=>{d||(d=!0,h())};s.addEventListener("keydown",l=>{if(l.stopPropagation(),!l.isComposing)if(l.key==="Enter"){if(l.shiftKey)return;l.preventDefault(),f()}else l.key==="Escape"&&(l.preventDefault(),p())}),t.parentElement?t.parentElement.appendChild(s):this.container.appendChild(s),s.focus({preventScroll:!0}),s.select()}}class _{constructor(){c(this,"listeners",{})}on(t,e){var i;this.listeners[t]||(this.listeners[t]=[]),(i=this.listeners[t])==null||i.push(e)}addListener(t,e){this.on(t,e)}off(t,e){const i=this.listeners[t];i&&(this.listeners[t]=i.filter(s=>s!==e))}removeListener(t,e){this.off(t,e)}emit(t,e){var i;(i=this.listeners[t])==null||i.forEach(s=>s(e))}}class G extends _{constructor(e){super();c(this,"mindMap");c(this,"service");c(this,"renderer");c(this,"interactionHandler");c(this,"styleEditor");c(this,"layoutSwitcher");c(this,"layoutMode","Right");c(this,"selectedNodeId",null);c(this,"panX",0);c(this,"panY",0);c(this,"targetPanX",0);c(this,"targetPanY",0);c(this,"scale",1);c(this,"isBatching",!1);c(this,"animationFrameId",null);const i=new x("root","Root Topic",null,!0);this.mindMap=new N(i),this.service=new Z(this.mindMap),this.renderer=new M(e);const s=document.createElement("div");s.style.position="absolute",s.style.top="0",s.style.left="0",s.style.width="100%",s.style.height="100%",s.style.pointerEvents="none",s.style.zIndex="2000",e.style.overscrollBehavior="none",e.style.touchAction="none",e.appendChild(s),this.styleEditor=new S(s),this.styleEditor.onUpdate=(n,r)=>{this.interactionHandler.isReadOnly||this.service.updateNodeStyle(n,r)&&(this.render(),this.emit("model:change",void 0))},this.panX=e.clientWidth/2,this.targetPanX=this.panX,this.targetPanY=this.panY,this.layoutSwitcher=new V(s,{onLayoutChange:n=>this.setLayoutMode(n),onThemeChange:n=>this.setTheme(n),onZoomReset:()=>this.resetZoom()}),this.startAnimationLoop(),this.interactionHandler=new q(e,{onNodeClick:n=>this.selectNode(n||null),onAddChild:n=>this.addChildNode(n),onInsertParent:n=>this.insertParentNode(n),onAddSibling:(n,r)=>this.addSiblingNode(n,r),onDeleteNode:n=>this.removeNode(n),onDropNode:(n,r,o)=>this.moveNode(n,r,o),onUpdateNode:(n,r)=>this.updateNodeTopic(n,r),onNavigate:(n,r)=>this.navigateNode(n,r),onPan:(n,r)=>this.panBoard(n,r),onCopyNode:n=>this.copyNode(n),onPasteNode:n=>this.pasteNode(n),onCutNode:n=>this.cutNode(n),onPasteImage:(n,r)=>this.pasteImage(n,r),onZoom:(n,r,o)=>this.zoomBoard(n,r,o),onUndo:()=>{this.service.undo()&&(this.render(),this.emit("model:change",void 0))},onStyleAction:(n,r)=>{if(this.interactionHandler.isReadOnly)return;const o=this.mindMap.findNode(n);if(!o)return;const a=o.style||{};let d=null;if(r.type==="bold")d={fontWeight:a.fontWeight==="bold"?"normal":"bold"};else if(r.type==="italic")d={fontStyle:a.fontStyle==="italic"?"normal":"italic"};else if(r.type==="color")r.index>=0&&r.index<S.PALETTE.length&&(d={color:S.PALETTE[r.index]});else if(r.type==="increaseSize"||r.type==="decreaseSize"){const h=S.FONT_SIZES,f=a.fontSize||"";let p=h.findIndex(y=>y.value===f);p===-1&&(p=0);let l=p;r.type==="increaseSize"?l=Math.min(h.length-1,p+1):l=Math.max(0,p-1),l!==p&&(d={fontSize:h[l].value})}d&&this.service.updateNodeStyle(n,d)&&(this.render(),this.emit("model:change",void 0),this.selectedNodeId===n&&this.styleEditor.show(n,{...a,...d}))}}),this.render()}addNode(e,i,s){const n=this.service.addNode(e,i,s);return n&&(this.render(),this.emit("node:add",{id:n.id,topic:n.topic}),this.emit("model:change",void 0)),n}addSibling(e,i="after",s="New Sibling"){const n=this.mindMap.findNode(e);if(!n||!n.parentId)return null;const r=this.mindMap.findNode(n.parentId);r&&r.isRoot&&this.layoutMode==="Both"&&this.ensureExplicitLayoutSides(r);const o=this.service.addSibling(e,i,s);if(o){if(r&&r.isRoot&&this.layoutMode==="Both"){const a=n.layoutSide||(r.children.indexOf(n)%2===0?"right":"left");o.layoutSide=a}this.render(),this.emit("node:add",{id:o.id,topic:o.topic}),this.emit("model:change",void 0)}return o}insertParent(e,i="New Parent"){const s=this.service.insertParent(e,i);return s&&(this.render(),this.emit("node:add",{id:s.id,topic:s.topic}),this.emit("model:change",void 0)),s}deleteNode(e){this.service.removeNode(e)&&(this.render(),this.emit("node:remove",e),this.emit("model:change",void 0))}updateNode(e,i){let s=!1;this.interactionHandler.isReadOnly||(i.topic!==void 0&&this.service.updateNodeTopic(e,i.topic)&&(s=!0),i.style!==void 0&&this.service.updateNodeStyle(e,i.style)&&(s=!0),s&&(this.render(),i.topic!==void 0&&this.emit("node:update",{id:e,topic:i.topic}),this.emit("model:change",void 0)))}updateNodeStyle(e,i){this.service.updateNodeStyle(e,i)}setTheme(e){this.service.setTheme(e),this.layoutSwitcher.setTheme(e),this.render(),this.emit("model:change",void 0)}getMindMap(){return this.mindMap}getNode(e){return this.mindMap.findNode(e)||void 0}getRoot(){return this.mindMap.root}findNodes(e){const i=[],s=n=>{e(n)&&i.push(n),n.children.forEach(s)};return s(this.mindMap.root),i}setReadOnly(e){this.interactionHandler.setReadOnly(e),e&&(this.styleEditor.hide(),this.selectNode(null))}destroy(){this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.interactionHandler.destroy(),this.renderer.container}batch(e){this.isBatching=!0;try{e()}finally{this.isBatching=!1,this.render()}}addChildNode(e){const i=this.mindMap.findNode(e);i&&i.isRoot&&this.layoutMode==="Both"&&this.ensureExplicitLayoutSides(i);let s;if(this.layoutMode==="Both"&&i&&i.isRoot){let r=0,o=0;i.children.forEach((a,d)=>{(a.layoutSide||(d%2===0?"right":"left"))==="left"?r++:o++}),s=r<o?"left":"right"}const n=this.addNode(e,"New Child",s);n&&(this.selectNode(n.id),this.ensureNodeVisible(n.id),this.interactionHandler.editNode(n.id))}addSiblingNode(e,i="after"){const s=this.addSibling(e,i,"New Sibling");s&&(this.selectNode(s.id),this.ensureNodeVisible(s.id),this.interactionHandler.editNode(s.id))}insertParentNode(e){const i=this.insertParent(e,"New Parent");i&&(this.selectNode(i.id),this.ensureNodeVisible(i.id),this.interactionHandler.editNode(i.id))}removeNode(e){const i=this.mindMap.findNode(e),s=(i==null?void 0:i.parentId)||null,n=this.selectedNodeId===e;this.deleteNode(e),n&&s&&this.selectNode(s)}ensureExplicitLayoutSides(e){!e.isRoot||this.layoutMode!=="Both"||e.children.forEach((i,s)=>{i.layoutSide||(i.layoutSide=s%2===0?"right":"left")})}moveNode(e,i,s){const n=this.mindMap.findNode(i);if(n){if(s==="top"){if(n.isRoot)return;this.service.reorderNode(e,i,"before")}else if(s==="bottom"){if(n.isRoot)return;this.service.reorderNode(e,i,"after")}else if(n.isRoot){const r=s==="left"?"left":"right";this.service.moveNode(e,i,r)}else{const r=this.getNodeDirection(n);let o="addChild";r==="right"?s==="right"?o="addChild":o="insertParent":s==="left"?o="addChild":o="insertParent",o==="addChild"?this.service.moveNode(e,i):this.service.insertNodeAsParent(e,i)}this.render(),this.emit("node:move",{nodeId:e,newParentId:i,position:s}),this.emit("model:change",void 0)}}updateNodeTopic(e,i){this.updateNode(e,{topic:i}),setTimeout(()=>this.ensureNodeVisible(e),0)}selectNode(e){if(this.selectedNodeId!==e){if(this.selectedNodeId=e,this.interactionHandler.updateSelection(e),e){const i=this.mindMap.findNode(e);i&&(!i.image&&!this.interactionHandler.isReadOnly?this.styleEditor.show(e,i.style):this.styleEditor.hide())}else this.styleEditor.hide();this.render(),this.emit("node:select",e)}}panBoard(e,i){this.targetPanX+=e,this.targetPanY+=i}zoomBoard(e,i,s){const a=this.renderer.container.getBoundingClientRect(),d=i-a.left,h=s-a.top,f=Math.min(Math.max(this.scale*(1-e*.001),.1),5),p=d-(d-this.panX)*(f/this.scale),l=h-(h-this.panY)*(f/this.scale);this.panX=p,this.panY=l,this.targetPanX=p,this.targetPanY=l,this.scale=f,this.renderer.updateTransform(this.panX,this.panY,this.scale)}resetZoom(){this.scale=1,this.panX=this.renderer.container.clientWidth/2,this.panY=0,this.targetPanX=this.panX,this.targetPanY=this.panY,this.render()}copyNode(e){this.service.copyNode(e)}pasteNode(e){const i=this.service.pasteNode(e);i&&(this.render(),this.selectNode(i.id),this.emit("node:add",{id:i.id,topic:i.topic}),this.emit("model:change",void 0),setTimeout(()=>this.ensureNodeVisible(i.id,!0),0))}pasteImage(e,i){const s=this.service.addImageNode(e,i);s&&(this.render(),this.selectNode(s.id),this.emit("node:add",{id:s.id,topic:""}),this.emit("model:change",void 0),setTimeout(()=>this.ensureNodeVisible(s.id,!0),0))}cutNode(e){const i=this.mindMap.findNode(e);if(i){const s=i.parentId;this.service.cutNode(e),this.selectNode(s),this.render(),this.emit("node:remove",e),this.emit("model:change",void 0)}}render(){this.isBatching||(this.renderer.render(this.mindMap,this.selectedNodeId,this.layoutMode),this.renderer.updateTransform(this.panX,this.panY,this.scale))}updateLayout(e){e==="Standard"?this.setLayoutMode("Both"):this.setLayoutMode(e)}setLayoutMode(e){this.layoutMode=e,this.layoutSwitcher.setMode(e);const i=this.renderer.container.clientWidth;e==="Right"?this.panX=i*.2:e==="Left"?this.panX=i*.8:this.panX=i*.5,this.panY=0,this.targetPanX=this.panX,this.targetPanY=this.panY,this.render()}getLayoutMode(){return this.layoutMode}navigateNode(e,i){const s=this.mindMap.findNode(e);if(s){switch(i){case"Left":if(s.isRoot){let n;this.layoutMode==="Left"?n=s.children[0]:this.layoutMode==="Both"&&(n=s.children.find((r,o)=>(r.layoutSide||(o%2!==0?"left":"right"))==="left")),n&&this.selectNode(n.id)}else s.parentId&&(this.getNodeDirection(s)==="right"?this.selectNode(s.parentId):s.children.length>0&&this.selectNode(s.children[0].id));break;case"Right":if(s.isRoot){let n;this.layoutMode==="Right"?n=s.children[0]:this.layoutMode==="Both"&&(n=s.children.find((r,o)=>(r.layoutSide||(o%2===0?"right":"left"))==="right")),n&&this.selectNode(n.id)}else s.parentId&&(this.getNodeDirection(s)==="right"?s.children.length>0&&this.selectNode(s.children[0].id):this.selectNode(s.parentId));break;case"Up":if(s.parentId){const n=this.mindMap.findNode(s.parentId);if(n){const r=this.getNodeDirection(s),o=n.children.filter(d=>this.getNodeDirection(d)===r),a=o.findIndex(d=>d.id===e);a>0&&this.selectNode(o[a-1].id)}}break;case"Down":if(s.parentId){const n=this.mindMap.findNode(s.parentId);if(n){const r=this.getNodeDirection(s),o=n.children.filter(d=>this.getNodeDirection(d)===r),a=o.findIndex(d=>d.id===e);a!==-1&&a<o.length-1&&this.selectNode(o[a+1].id)}}break}this.selectedNodeId&&this.selectedNodeId!==e&&setTimeout(()=>this.ensureNodeVisible(this.selectedNodeId,!0),0)}}getData(){return this.service.exportData()}loadData(e){try{this.service.importData(e),this.selectNode(null),this.render(),this.emit("model:load",e),e.theme&&this.layoutSwitcher.setTheme(e.theme),this.emit("model:change",void 0)}catch(i){console.error("Failed to load data",i)}}getRootId(){return this.mindMap.root.id}getNodeDirection(e){if(e.isRoot||this.layoutMode==="Right")return"right";if(this.layoutMode==="Left")return"left";let i=e;for(;i.parentId;){const s=this.mindMap.findNode(i.parentId);if(!s)break;if(s.isRoot)return i.layoutSide?i.layoutSide:s.children.findIndex(r=>r.id===i.id)%2===0?"right":"left";i=s}return"right"}startAnimationLoop(){let e=performance.now();const i=()=>{const s=performance.now(),n=(s-e)/1e3;e=s;const r=1-Math.exp(-8*n),o=this.targetPanX-this.panX,a=this.targetPanY-this.panY;Math.abs(o)>.1||Math.abs(a)>.1?(this.panX+=o*r,this.panY+=a*r,this.renderer.updateTransform(this.panX,this.panY,this.scale)):(this.panX!==this.targetPanX||this.panY!==this.targetPanY)&&(this.panX=this.targetPanX,this.panY=this.targetPanY,this.renderer.updateTransform(this.panX,this.panY,this.scale)),Number.isNaN(this.panX)&&(this.panX=0),Number.isNaN(this.panY)&&(this.panY=0),this.animationFrameId=requestAnimationFrame(i)};i()}ensureNodeVisible(e,i=!1){const s=this.renderer.container.querySelector(`.mindmap-node[data-id="${e}"]`);if(!s)return;const n=s.getBoundingClientRect(),r=this.renderer.container.getBoundingClientRect(),o=50;let a=0,d=0;const h=n.left<r.left+o,f=n.right>r.right-o,p=n.top<r.top+o,l=n.bottom>r.bottom-o;if(i&&(h||f||p||l)){const y=n.left+n.width/2,g=n.top+n.height/2,m=r.left+r.width/2,u=r.top+r.height/2;a=m-y,d=u-g}else h?a=r.left+o-n.left:f&&(a=r.right-o-n.right),p?d=r.top+o-n.top:l&&(d=r.bottom-o-n.bottom);(a!==0||d!==0)&&this.panBoard(a,d)}}v.Kakidash=G,Object.defineProperty(v,Symbol.toStringTag,{value:"Module"})});
|
|
48
|
+
`)||s.value==="")&&(l.textContent+=""),document.body.appendChild(l);const y=l.offsetWidth+20,g=l.offsetHeight+10;s.style.width=Math.max(y,t.offsetWidth)+"px",s.style.height=Math.max(g,t.offsetHeight)+"px",document.body.removeChild(l)};a(),s.addEventListener("input",a);let d=!1;const h=()=>{s.parentNode&&s.parentNode.contains(s)&&s.parentNode.removeChild(s),t.style.outline=r,t.style.boxShadow=o},f=()=>{if(d)return;d=!0;const l=s.value;l!==i&&this.options.onUpdateNode&&this.options.onUpdateNode(e,l),h(),this.options.onEditEnd&&this.options.onEditEnd(e)};s.addEventListener("blur",()=>{d||f()});const p=()=>{d||(d=!0,d=!0,h(),this.options.onEditEnd&&this.options.onEditEnd(e))};s.addEventListener("keydown",l=>{if(l.stopPropagation(),!l.isComposing)if(l.key==="Enter"){if(l.shiftKey)return;l.preventDefault(),f()}else l.key==="Escape"&&(l.preventDefault(),p())}),t.parentElement?t.parentElement.appendChild(s):this.container.appendChild(s),s.focus({preventScroll:!0}),s.select()}}class ee{constructor(){c(this,"listeners",{})}on(t,e){var i;this.listeners[t]||(this.listeners[t]=[]),(i=this.listeners[t])==null||i.push(e)}addListener(t,e){this.on(t,e)}off(t,e){const i=this.listeners[t];i&&(this.listeners[t]=i.filter(s=>s!==e))}removeListener(t,e){this.off(t,e)}emit(t,e){var i;(i=this.listeners[t])==null||i.forEach(s=>s(e))}}class te extends ee{constructor(e){super();c(this,"mindMap");c(this,"service");c(this,"renderer");c(this,"interactionHandler");c(this,"styleEditor");c(this,"layoutSwitcher");c(this,"layoutMode","Right");c(this,"selectedNodeId",null);c(this,"pendingNodeCreation",!1);c(this,"panX",0);c(this,"panY",0);c(this,"targetPanX",0);c(this,"targetPanY",0);c(this,"scale",1);c(this,"isBatching",!1);c(this,"animationFrameId",null);const i=new b("root","Root Topic",null,!0);this.mindMap=new v(i),this.service=new G(this.mindMap),this.renderer=new L(e,{onImageZoom:n=>this.setReadOnly(n)});const s=document.createElement("div");s.style.position="absolute",s.style.top="0",s.style.left="0",s.style.width="100%",s.style.height="100%",s.style.pointerEvents="none",s.style.zIndex="2000",e.style.overscrollBehavior="none",e.style.touchAction="none",e.appendChild(s),this.styleEditor=new I(s),this.styleEditor.onUpdate=(n,r)=>{this.interactionHandler.isReadOnly||this.service.updateNodeStyle(n,r)&&(this.render(),this.emit("model:change",void 0))},this.panX=e.clientWidth/2,this.targetPanX=this.panX,this.targetPanY=this.panY,this.layoutSwitcher=new J(s,{onLayoutChange:n=>this.setLayoutMode(n),onThemeChange:n=>this.setTheme(n),onZoomReset:()=>this.resetZoom()}),this.startAnimationLoop(),this.interactionHandler=new Q(e,{onNodeClick:n=>this.selectNode(n||null),onAddChild:n=>this.addChildNode(n),onInsertParent:n=>this.insertParentNode(n),onAddSibling:(n,r)=>this.addSiblingNode(n,r),onDeleteNode:n=>this.removeNode(n),onDropNode:(n,r,o)=>this.moveNode(n,r,o),onUpdateNode:(n,r)=>this.updateNodeTopic(n,r),onNavigate:(n,r)=>this.navigateNode(n,r),onPan:(n,r)=>this.panBoard(n,r),onCopyNode:n=>this.copyNode(n),onPasteNode:n=>this.pasteNode(n),onCutNode:n=>this.cutNode(n),onPasteImage:(n,r)=>this.pasteImage(n,r),onZoom:(n,r,o)=>this.zoomBoard(n,r,o),onUndo:()=>{this.service.undo()&&(this.render(),this.emit("model:change",void 0))},onStyleAction:(n,r)=>{if(this.interactionHandler.isReadOnly)return;const o=this.mindMap.findNode(n);if(!o)return;const a=o.style||{};let d=null;if(r.type==="bold")d={fontWeight:a.fontWeight==="bold"?"normal":"bold"};else if(r.type==="italic")d={fontStyle:a.fontStyle==="italic"?"normal":"italic"};else if(r.type==="color")r.index>=0&&r.index<I.PALETTE.length&&(d={color:I.PALETTE[r.index]});else if(r.type==="increaseSize"||r.type==="decreaseSize"){const h=I.FONT_SIZES,f=a.fontSize||"";let p=h.findIndex(y=>y.value===f);p===-1&&(p=0);let l=p;r.type==="increaseSize"?l=Math.min(h.length-1,p+1):l=Math.max(0,p-1),l!==p&&(d={fontSize:h[l].value})}d&&this.service.updateNodeStyle(n,d)&&(this.render(),this.emit("model:change",void 0),this.selectedNodeId===n&&this.styleEditor.show(n,{...a,...d}))},onEditEnd:n=>{this.pendingNodeCreation&&(this.pendingNodeCreation=!1,this.emit("model:change",void 0))}}),this.render()}addNode(e,i,s,n={emitChange:!0}){const r=this.service.addNode(e,i,s);return r&&(this.render(),this.emit("node:add",{id:r.id,topic:r.topic}),n.emitChange&&this.emit("model:change",void 0)),r}addSibling(e,i="after",s="New topic",n={emitChange:!0}){const r=this.mindMap.findNode(e);if(!r||!r.parentId)return null;const o=this.mindMap.findNode(r.parentId);o&&o.isRoot&&this.layoutMode==="Both"&&this.ensureExplicitLayoutSides(o);const a=this.service.addSibling(e,i,s);if(a){if(o&&o.isRoot&&this.layoutMode==="Both"){const d=r.layoutSide||(o.children.indexOf(r)%2===0?"right":"left");a.layoutSide=d}this.render(),this.emit("node:add",{id:a.id,topic:a.topic}),n.emitChange&&this.emit("model:change",void 0)}return a}insertParent(e,i="New topic",s={emitChange:!0}){const n=this.service.insertParent(e,i);return n&&(this.render(),this.emit("node:add",{id:n.id,topic:n.topic}),s.emitChange&&this.emit("model:change",void 0)),n}deleteNode(e){this.service.removeNode(e)&&(this.render(),this.emit("node:remove",e),this.emit("model:change",void 0))}updateNode(e,i){let s=!1;this.interactionHandler.isReadOnly||(i.topic!==void 0&&this.service.updateNodeTopic(e,i.topic)&&(s=!0),i.style!==void 0&&this.service.updateNodeStyle(e,i.style)&&(s=!0),s&&(this.render(),i.topic!==void 0&&this.emit("node:update",{id:e,topic:i.topic}),this.emit("model:change",void 0),this.pendingNodeCreation&&(this.pendingNodeCreation=!1)))}updateNodeStyle(e,i){this.service.updateNodeStyle(e,i)}setTheme(e){this.service.setTheme(e),this.layoutSwitcher.setTheme(e),this.render(),this.emit("model:change",void 0)}getMindMap(){return this.mindMap}getNode(e){return this.mindMap.findNode(e)||void 0}getRoot(){return this.mindMap.root}findNodes(e){const i=[],s=n=>{e(n)&&i.push(n),n.children.forEach(s)};return s(this.mindMap.root),i}setReadOnly(e){this.interactionHandler.setReadOnly(e),e&&this.styleEditor.hide()}destroy(){this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.interactionHandler.destroy(),this.renderer.container}batch(e){this.isBatching=!0;try{e()}finally{this.isBatching=!1,this.render()}}addChildNode(e){const i=this.mindMap.findNode(e);i&&i.isRoot&&this.layoutMode==="Both"&&this.ensureExplicitLayoutSides(i);let s;if(this.layoutMode==="Both"&&i&&i.isRoot){let r=0,o=0;i.children.forEach((a,d)=>{(a.layoutSide||(d%2===0?"right":"left"))==="left"?r++:o++}),s=r<o?"left":"right"}this.pendingNodeCreation=!0;const n=this.addNode(e,"New topic",s,{emitChange:!1});n&&(this.selectNode(n.id),this.ensureNodeVisible(n.id),this.interactionHandler.editNode(n.id))}addSiblingNode(e,i="after"){this.pendingNodeCreation=!0;const s=this.addSibling(e,i,"New topic",{emitChange:!1});s&&(this.selectNode(s.id),this.ensureNodeVisible(s.id),this.interactionHandler.editNode(s.id))}insertParentNode(e){this.pendingNodeCreation=!0;const i=this.insertParent(e,"New topic",{emitChange:!1});i&&(this.selectNode(i.id),this.ensureNodeVisible(i.id),this.interactionHandler.editNode(i.id))}removeNode(e){const i=this.mindMap.findNode(e),s=(i==null?void 0:i.parentId)||null,n=this.selectedNodeId===e;this.deleteNode(e),n&&s&&this.selectNode(s)}ensureExplicitLayoutSides(e){!e.isRoot||this.layoutMode!=="Both"||e.children.forEach((i,s)=>{i.layoutSide||(i.layoutSide=s%2===0?"right":"left")})}moveNode(e,i,s){const n=this.mindMap.findNode(i);if(n){if(s==="top"){if(n.isRoot)return;this.service.reorderNode(e,i,"before")}else if(s==="bottom"){if(n.isRoot)return;this.service.reorderNode(e,i,"after")}else if(n.isRoot){const r=s==="left"?"left":"right";this.service.moveNode(e,i,r)}else{const r=this.getNodeDirection(n);let o="addChild";r==="right"?s==="right"?o="addChild":o="insertParent":s==="left"?o="addChild":o="insertParent",o==="addChild"?this.service.moveNode(e,i):this.service.insertNodeAsParent(e,i)}this.render(),this.emit("node:move",{nodeId:e,newParentId:i,position:s}),this.emit("model:change",void 0)}}updateNodeTopic(e,i){this.updateNode(e,{topic:i}),setTimeout(()=>this.ensureNodeVisible(e),0)}selectNode(e){if(this.selectedNodeId!==e){if(this.selectedNodeId=e,this.interactionHandler.updateSelection(e),e){const i=this.mindMap.findNode(e);i&&(!i.image&&!this.interactionHandler.isReadOnly?this.styleEditor.show(e,i.style):this.styleEditor.hide())}else this.styleEditor.hide();this.render(),this.emit("node:select",e)}}panBoard(e,i){this.targetPanX+=e,this.targetPanY+=i}zoomBoard(e,i,s){const a=this.renderer.container.getBoundingClientRect(),d=i-a.left,h=s-a.top,f=Math.min(Math.max(this.scale*(1-e*.001),.1),5),p=d-(d-this.panX)*(f/this.scale),l=h-(h-this.panY)*(f/this.scale);this.panX=p,this.panY=l,this.targetPanX=p,this.targetPanY=l,this.scale=f,this.renderer.updateTransform(this.panX,this.panY,this.scale)}resetZoom(){this.scale=1,this.panX=this.renderer.container.clientWidth/2,this.panY=0,this.targetPanX=this.panX,this.targetPanY=this.panY,this.render()}copyNode(e){this.service.copyNode(e)}pasteNode(e){const i=this.service.pasteNode(e);i&&(this.render(),this.selectNode(i.id),this.emit("node:add",{id:i.id,topic:i.topic}),this.emit("model:change",void 0),setTimeout(()=>this.ensureNodeVisible(i.id,!0),0))}pasteImage(e,i){const s=this.service.addImageNode(e,i);s&&(this.render(),this.selectNode(s.id),this.emit("node:add",{id:s.id,topic:""}),this.emit("model:change",void 0),setTimeout(()=>this.ensureNodeVisible(s.id,!0),0))}cutNode(e){const i=this.mindMap.findNode(e);if(i){const s=i.parentId;this.service.cutNode(e),this.selectNode(s),this.render(),this.emit("node:remove",e),this.emit("model:change",void 0)}}render(){this.isBatching||(this.renderer.render(this.mindMap,this.selectedNodeId,this.layoutMode),this.renderer.updateTransform(this.panX,this.panY,this.scale))}updateLayout(e){e==="Standard"?this.setLayoutMode("Both"):this.setLayoutMode(e)}setLayoutMode(e){this.layoutMode=e,this.layoutSwitcher.setMode(e);const i=this.renderer.container.clientWidth;e==="Right"?this.panX=i*.2:e==="Left"?this.panX=i*.8:this.panX=i*.5,this.panY=0,this.targetPanX=this.panX,this.targetPanY=this.panY,this.render()}getLayoutMode(){return this.layoutMode}navigateNode(e,i){const s=this.mindMap.findNode(e);if(s){switch(i){case"Left":if(s.isRoot){let n;this.layoutMode==="Left"?n=s.children[0]:this.layoutMode==="Both"&&(n=s.children.find((r,o)=>(r.layoutSide||(o%2!==0?"left":"right"))==="left")),n&&this.selectNode(n.id)}else s.parentId&&(this.getNodeDirection(s)==="right"?this.selectNode(s.parentId):s.children.length>0&&this.selectNode(s.children[0].id));break;case"Right":if(s.isRoot){let n;this.layoutMode==="Right"?n=s.children[0]:this.layoutMode==="Both"&&(n=s.children.find((r,o)=>(r.layoutSide||(o%2===0?"right":"left"))==="right")),n&&this.selectNode(n.id)}else s.parentId&&(this.getNodeDirection(s)==="right"?s.children.length>0&&this.selectNode(s.children[0].id):this.selectNode(s.parentId));break;case"Up":if(s.parentId){const n=this.mindMap.findNode(s.parentId);if(n){const r=this.getNodeDirection(s),o=n.children.filter(d=>this.getNodeDirection(d)===r),a=o.findIndex(d=>d.id===e);a>0&&this.selectNode(o[a-1].id)}}break;case"Down":if(s.parentId){const n=this.mindMap.findNode(s.parentId);if(n){const r=this.getNodeDirection(s),o=n.children.filter(d=>this.getNodeDirection(d)===r),a=o.findIndex(d=>d.id===e);a!==-1&&a<o.length-1&&this.selectNode(o[a+1].id)}}break}this.selectedNodeId&&this.selectedNodeId!==e&&setTimeout(()=>this.ensureNodeVisible(this.selectedNodeId,!0),0)}}getData(){return this.service.exportData()}loadData(e){try{this.service.importData(e),this.selectNode(null),this.render(),this.emit("model:load",e),e.theme&&this.layoutSwitcher.setTheme(e.theme),this.emit("model:change",void 0)}catch(i){console.error("Failed to load data",i)}}getRootId(){return this.mindMap.root.id}getNodeDirection(e){if(e.isRoot||this.layoutMode==="Right")return"right";if(this.layoutMode==="Left")return"left";let i=e;for(;i.parentId;){const s=this.mindMap.findNode(i.parentId);if(!s)break;if(s.isRoot)return i.layoutSide?i.layoutSide:s.children.findIndex(r=>r.id===i.id)%2===0?"right":"left";i=s}return"right"}startAnimationLoop(){let e=performance.now();const i=()=>{const s=performance.now(),n=(s-e)/1e3;e=s;const r=1-Math.exp(-8*n),o=this.targetPanX-this.panX,a=this.targetPanY-this.panY;Math.abs(o)>.1||Math.abs(a)>.1?(this.panX+=o*r,this.panY+=a*r,this.renderer.updateTransform(this.panX,this.panY,this.scale)):(this.panX!==this.targetPanX||this.panY!==this.targetPanY)&&(this.panX=this.targetPanX,this.panY=this.targetPanY,this.renderer.updateTransform(this.panX,this.panY,this.scale)),Number.isNaN(this.panX)&&(this.panX=0),Number.isNaN(this.panY)&&(this.panY=0),this.animationFrameId=requestAnimationFrame(i)};i()}ensureNodeVisible(e,i=!1){const s=this.renderer.container.querySelector(`.mindmap-node[data-id="${e}"]`);if(!s)return;const n=s.getBoundingClientRect(),r=this.renderer.container.getBoundingClientRect(),o=50;let a=0,d=0;const h=n.left<r.left+o,f=n.right>r.right-o,p=n.top<r.top+o,l=n.bottom>r.bottom-o;if(i&&(h||f||p||l)){const y=n.left+n.width/2,g=n.top+n.height/2,m=r.left+r.width/2,u=r.top+r.height/2;a=m-y,d=u-g}else h?a=r.left+o-n.left:f&&(a=r.right-o-n.right),p?d=r.top+o-n.top:l&&(d=r.bottom-o-n.bottom);(a!==0||d!==0)&&this.panBoard(a,d)}}x.Kakidash=te,Object.defineProperty(x,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kakidash",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "A lightweight, dependency-free Mindmap library for the browser.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
"url": "https://github.com/hiroooo000/kakidash/issues"
|
|
12
12
|
},
|
|
13
13
|
"type": "module",
|
|
14
|
-
"main": "./dist/kakidash.
|
|
14
|
+
"main": "./dist/kakidash.cjs",
|
|
15
15
|
"module": "./dist/kakidash.es.js",
|
|
16
16
|
"types": "./dist/index.d.ts",
|
|
17
17
|
"exports": {
|
|
18
18
|
".": {
|
|
19
19
|
"import": "./dist/kakidash.es.js",
|
|
20
|
-
"require": "./dist/kakidash.
|
|
20
|
+
"require": "./dist/kakidash.cjs"
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"scripts": {
|
|
27
27
|
"dev": "vite --host",
|
|
28
28
|
"build": "tsc && vite build",
|
|
29
|
-
"test": "vitest",
|
|
29
|
+
"test": "vitest run",
|
|
30
30
|
"lint": "eslint src tests",
|
|
31
31
|
"format": "prettier --write \"src/**/*.{ts,json}\""
|
|
32
32
|
},
|
|
@@ -60,4 +60,4 @@
|
|
|
60
60
|
"vite-plugin-dts": "^4.5.4",
|
|
61
61
|
"vitest": "^1.4.0"
|
|
62
62
|
}
|
|
63
|
-
}
|
|
63
|
+
}
|