UNPKG

sankey-hand-layout

Version:

A user-driven layout Sankey diagram library with drag, rotate, and resize interactions

2 lines (1 loc) 38.9 kB
(function(k,O){typeof exports=="object"&&typeof module<"u"?O(exports):typeof define=="function"&&define.amd?define(["exports"],O):(k=typeof globalThis<"u"?globalThis:k||self,O(k.SankeyHandLayout={}))})(this,(function(k){"use strict";const O={linear:n=>n,easeIn:n=>n*n,easeOut:n=>n*(2-n),easeInOut:n=>n<.5?2*n*n:-1+(4-2*n)*n,easeOutCubic:n=>1-Math.pow(1-n,3),easeInOutCubic:n=>n<.5?4*n*n*n:1-Math.pow(-2*n+2,3)/2},tt={linkThickness:1,linkCurvature:.5,nodeLength:20,valueScale:1,pathStyle:"constantWidth",minNodeThickness:4,minNodeLength:10,minControlPointDistance:20,transitionDuration:300,transitionEasing:O.easeOut};function R(n,t){const e=new Set;for(const i of n){if(e.has(i.id))throw new Error(`Duplicate node ID: ${i.id}`);e.add(i.id)}for(const i of t){if(!e.has(i.source))throw new Error(`Link "${i.id}" references unknown source node: ${i.source}`);if(!e.has(i.target))throw new Error(`Link "${i.id}" references unknown target node: ${i.target}`)}return{nodes:[...n],links:[...t]}}function et(n,t){return n.nodes.find(e=>e.id===t)}function nt(n,t){return n.links.find(e=>e.id===t)}function St(n,t){const e=n.links.filter(s=>s.target===t),i=n.links.filter(s=>s.source===t);return{incoming:e,outgoing:i}}function it(n,t){return n.nodes.map(e=>{const{incoming:i,outgoing:s}=St(n,e.id),o=i.reduce((d,l)=>d+l.value,0),r=s.reduce((d,l)=>d+l.value,0),c=Math.max(o,r)*t.valueScale;return{...e,thickness:c,incomingValue:o,outgoingValue:r}})}function st(n){return n.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}function N(n,t){const e={nodes:{}};for(const i of n)e.nodes[i.id]={x:i.x,y:i.y,orientation:i.orientation,length:i.length,shape:i.shape};if(t){const i={};let s=!1;for(const o of t)(o.sourceOrder!==void 0||o.targetOrder!==void 0)&&(i[o.id]={sourceOrder:o.sourceOrder,targetOrder:o.targetOrder},s=!0);s&&(e.linkOrders=i)}return e}function T(n,t){return n.map(e=>{const i=t.nodes[e.id];return i?{...e,x:i.x,y:i.y,orientation:i.orientation,length:i.length??e.length,shape:i.shape??e.shape}:e})}function P(n,t){return t.linkOrders?n.map(e=>{const i=t.linkOrders[e.id];return i?{...e,sourceOrder:i.sourceOrder??e.sourceOrder,targetOrder:i.targetOrder??e.targetOrder}:e}):n}function Mt(n){return JSON.stringify(n,null,2)}function At(n){const t=JSON.parse(n);if(!t.nodes||typeof t.nodes!="object")throw new Error("Invalid layout: missing nodes object");return t}function q(n,t,e){const i=Math.min(t,e);switch(n){case"arrow":return i*.4;case"chevron":return i*.35;case"diamond":return Math.min(t,e)*.5;case"circle":return Math.min(t,e)*.15;default:return 0}}function z(n,t,e,i,s,o){if(n==="rect")return null;const r=q(n,i,s),a=i/2,c=s/2;switch(n){case"arrow":{const d=r;return o===0?`M ${t-a+r} ${e-c} L ${t+a-d} ${e-c} L ${t+a} ${e} L ${t+a-d} ${e+c} L ${t-a+r} ${e+c} Z`:o===180?`M ${t+a-r} ${e-c} L ${t-a+d} ${e-c} L ${t-a} ${e} L ${t-a+d} ${e+c} L ${t+a-r} ${e+c} Z`:o===90?`M ${t-a} ${e-c+r} L ${t+a} ${e-c+r} L ${t+a} ${e+c-d} L ${t} ${e+c} L ${t-a} ${e+c-d} Z`:`M ${t-a} ${e+c-r} L ${t+a} ${e+c-r} L ${t+a} ${e-c+d} L ${t} ${e-c} L ${t-a} ${e-c+d} Z`}case"chevron":{const d=r,l=Math.min(i,s)*.2;return o===0?`M ${t-a+r+l} ${e} L ${t-a+r} ${e-c} L ${t+a-d} ${e-c} L ${t+a} ${e} L ${t+a-d} ${e+c} L ${t-a+r} ${e+c} Z`:o===180?`M ${t+a-r-l} ${e} L ${t+a-r} ${e-c} L ${t-a+d} ${e-c} L ${t-a} ${e} L ${t-a+d} ${e+c} L ${t+a-r} ${e+c} Z`:o===90?`M ${t} ${e-c+r+l} L ${t-a} ${e-c+r} L ${t-a} ${e+c-d} L ${t} ${e+c} L ${t+a} ${e+c-d} L ${t+a} ${e-c+r} Z`:`M ${t} ${e+c-r-l} L ${t-a} ${e+c-r} L ${t-a} ${e-c+d} L ${t} ${e-c} L ${t+a} ${e-c+d} L ${t+a} ${e+c-r} Z`}case"diamond":{const d=a*.7,l=c*.7;return`M ${t} ${e-l} L ${t+d} ${e} L ${t} ${e+l} L ${t-d} ${e} Z`}case"circle":return null;default:return null}}function Nt(n,t,e,i,s,o){const r="http://www.w3.org/2000/svg";if(n==="rect")return null;if(n==="circle"){const d=q(n,i,s),l=document.createElementNS(r,"ellipse");return l.setAttribute("cx",String(t)),l.setAttribute("cy",String(e)),l.setAttribute("rx",String(i/2-d)),l.setAttribute("ry",String(s/2-d)),l}const a=z(n,t,e,i,s,o);if(!a)return null;const c=document.createElementNS(r,"path");return c.setAttribute("d",a),c}function Et(n){const t=document.createElementNS("http://www.w3.org/2000/svg","svg");t.setAttribute("class","sankey-hand-layout"),t.style.width="100%",t.style.height="100%";const e=document.createElementNS("http://www.w3.org/2000/svg","g");e.setAttribute("class","links"),t.appendChild(e);const i=document.createElementNS("http://www.w3.org/2000/svg","g");return i.setAttribute("class","nodes"),t.appendChild(i),n.appendChild(t),t}function rt(n,t,e,i=!1){const s=n.querySelector(".nodes");if(!s)return;const o=new Set;for(const a of t){const c=a.shape??"rect";let d=s.querySelector(`[data-node-id="${a.id}"]`);const l=d!==null,f=a.length??e.nodeLength,p=Math.max(a.thickness,e.minNodeThickness),m=a.orientation===0||a.orientation===180,x=m?f:p,h=m?p:f;if(!d){d=document.createElementNS("http://www.w3.org/2000/svg","g"),d.setAttribute("data-node-id",a.id);const u=document.createElementNS("http://www.w3.org/2000/svg","rect");u.classList.add("node-base"),d.appendChild(u),s.appendChild(d)}o.add(a.id),d.setAttribute("class",`node node--${st(a.id)} node-shape--${c}`),d.setAttribute("data-orientation",String(a.orientation)),d.setAttribute("data-shape",c);const $=!l||!i;if($){const u=d.querySelector(".node-base");u&&(u.setAttribute("x",String(a.x-x/2)),u.setAttribute("y",String(a.y-h/2)),u.setAttribute("width",String(x)),u.setAttribute("height",String(h)))}const g=d.querySelector(".node-shape-overlay");if(c!=="rect")if(g){if($)if(c==="circle"){const u=q(c,x,h);g.setAttribute("cx",String(a.x)),g.setAttribute("cy",String(a.y)),g.setAttribute("rx",String(x/2-u)),g.setAttribute("ry",String(h/2-u))}else{const u=z(c,a.x,a.y,x,h,a.orientation);u&&g.setAttribute("d",u)}}else{const u=Nt(c,a.x,a.y,x,h,a.orientation);if(u){u.classList.add("node-shape-overlay");const b=d.querySelector("text");b?d.insertBefore(u,b):d.appendChild(u)}}else g&&g.remove();let y=d.querySelector("text");a.label?(y||(y=document.createElementNS("http://www.w3.org/2000/svg","text"),y.setAttribute("text-anchor","middle"),y.setAttribute("dominant-baseline","middle"),d.appendChild(y)),y.setAttribute("x",String(a.x)),y.setAttribute("y",String(a.y)),y.textContent=a.label):y&&y.remove()}s.querySelectorAll("[data-node-id]").forEach(a=>{const c=a.getAttribute("data-node-id");c&&!o.has(c)&&a.remove()})}function ot(n,t,e,i=!1){const s=n.querySelector(".links");if(!s)return;const o=new Set;for(const a of t){let c=s.querySelector(`[data-link-id="${a.id}"]`);const d=c!==null;c||(c=document.createElementNS("http://www.w3.org/2000/svg","path"),c.setAttribute("data-link-id",a.id),s.appendChild(c)),o.add(a.id),c.setAttribute("class",`link link--${st(a.id)}`),c.setAttribute("data-source",a.source),c.setAttribute("data-target",a.target),(!d||!i)&&c.setAttribute("d",a.path)}s.querySelectorAll("[data-link-id]").forEach(a=>{const c=a.getAttribute("data-link-id");c&&!o.has(c)&&a.remove()})}function Ht(n){const t=n.querySelector(".nodes"),e=n.querySelector(".links");t&&(t.innerHTML=""),e&&(e.innerHTML="")}function at(n,t,e,i,s){const o=n.length??s.nodeLength,r=Math.max(n.thickness,s.minNodeThickness),a=n.orientation===0||n.orientation===180,c=a?o:r,d=a?r:o;let l;n.orientation===0?l=t==="in"?"left":"right":n.orientation===90?l=t==="in"?"top":"bottom":n.orientation===180?l=t==="in"?"right":"left":l=t==="in"?"bottom":"top";const f=n.x-c/2,p=n.x+c/2,m=n.y-d/2,x=n.y+d/2;let h,$,g,y;switch(l){case"left":h=f,$=m+d*e,g=-1,y=0;break;case"right":h=p,$=m+d*e,g=1,y=0;break;case"top":h=f+c*e,$=m,g=0,y=-1;break;case"bottom":h=f+c*e,$=x,g=0,y=1;break}return{x:h,y:$,dx:g,dy:y,thickness:i}}function Ot(n,t,e,i){const s=n.thickness/2,o=t.thickness/2,r=n.dy,a=-n.dx,c=t.dy,d=-t.dx,l=n.x+r*s,f=n.y+a*s,p=n.x-r*s,m=n.y-a*s,x=t.x+c*o,h=t.y+d*o,$=t.x-c*o,g=t.y-d*o,y=Math.sqrt((t.x-n.x)**2+(t.y-n.y)**2),u=Math.max(y*e,i),b=l+n.dx*u,v=f+n.dy*u,A=p+n.dx*u,L=m+n.dy*u,ge=x+t.dx*u,pe=h+t.dy*u,me=$+t.dx*u,xe=g+t.dy*u;return[`M ${l} ${f}`,`C ${b} ${v}, ${ge} ${pe}, ${x} ${h}`,`L ${$} ${g}`,`C ${me} ${xe}, ${A} ${L}, ${p} ${m}`,"Z"].join(" ")}function It(n,t,e,i,s){const o=1-s,r=o*o,a=r*o,c=s*s,d=c*s;return{x:a*n.x+3*r*s*t.x+3*o*c*e.x+d*i.x,y:a*n.y+3*r*s*t.y+3*o*c*e.y+d*i.y}}function Pt(n,t,e,i,s){const o=1-s,r=o*o,a=s*s;return{x:3*r*(t.x-n.x)+6*o*s*(e.x-t.x)+3*a*(i.x-e.x),y:3*r*(t.y-n.y)+6*o*s*(e.y-t.y)+3*a*(i.y-e.y)}}function qt(n){const t=Math.sqrt(n.x*n.x+n.y*n.y);return t===0?{x:0,y:0}:{x:n.x/t,y:n.y/t}}function Dt(n){return{x:-n.y,y:n.x}}function ct(n,t,e,i,s=64){const r=(n.thickness+t.thickness)/2/2,a=Math.sqrt((t.x-n.x)**2+(t.y-n.y)**2),c=Math.max(a*e,i),d={x:n.x,y:n.y},l={x:n.x+n.dx*c,y:n.y+n.dy*c},f={x:t.x+t.dx*c,y:t.y+t.dy*c},p={x:t.x,y:t.y},m=[],x=[];for(let u=0;u<=s;u++){const b=u/s,v=It(d,l,f,p,b),A=qt(Pt(d,l,f,p,b)),L=Dt(A);m.push({x:v.x+L.x*r,y:v.y+L.y*r}),x.push({x:v.x-L.x*r,y:v.y-L.y*r})}const h=[];h.push(`M ${m[0].x.toFixed(2)} ${m[0].y.toFixed(2)}`);for(let u=1;u<m.length;u++){const b=m[u-1],v=m[u];if(u===1)h.push(`L ${v.x.toFixed(2)} ${v.y.toFixed(2)}`);else{const A=b.x,L=b.y;h.push(`Q ${A.toFixed(2)} ${L.toFixed(2)} ${((b.x+v.x)/2).toFixed(2)} ${((b.y+v.y)/2).toFixed(2)}`)}}const $=m[m.length-1];h.push(`L ${$.x.toFixed(2)} ${$.y.toFixed(2)}`);const g=x[x.length-1];h.push(`L ${g.x.toFixed(2)} ${g.y.toFixed(2)}`);for(let u=x.length-2;u>=0;u--){const b=x[u+1],v=x[u];if(u===x.length-2)h.push(`L ${v.x.toFixed(2)} ${v.y.toFixed(2)}`);else{const A=b.x,L=b.y;h.push(`Q ${A.toFixed(2)} ${L.toFixed(2)} ${((b.x+v.x)/2).toFixed(2)} ${((b.y+v.y)/2).toFixed(2)}`)}}const y=x[0];return h.push(`L ${y.x.toFixed(2)} ${y.y.toFixed(2)}`),h.push("Z"),h.join(" ")}function Ct(n,t,e,i,s="constantWidth"){switch(s){case"bezier":return Ot(n,t,e,i);case"constantWidth":return ct(n,t,e,i);default:return ct(n,t,e,i)}}function dt(n,t,e,i,s){const o=new Map,r=e==="out"?n.filter(d=>d.source===t):n.filter(d=>d.target===t);if(i===0)return o;const a=[...r].sort((d,l)=>{const f=e==="out"?d.sourceOrder??1/0:d.targetOrder??1/0,p=e==="out"?l.sourceOrder??1/0:l.targetOrder??1/0;return f===1/0&&p===1/0?0:f-p});let c=0;for(const d of a){const l=d.value/i,f=c+l/2,p=d.value*s.valueScale;o.set(d.id,{offset:f,thickness:p}),c+=l}return o}function lt(n,t,e){const i=new Map(n.map(r=>[r.id,r])),s=new Map,o=new Map;for(const r of n)s.set(r.id,dt(t,r.id,"out",r.outgoingValue,e)),o.set(r.id,dt(t,r.id,"in",r.incomingValue,e));return t.map(r=>{const a=i.get(r.source),c=i.get(r.target);if(!a||!c)throw new Error(`Link "${r.id}" references missing node`);const d=s.get(r.source)?.get(r.id),l=o.get(r.target)?.get(r.id),f=d?.offset??.5,p=l?.offset??.5,m=r.value*e.valueScale,x=at(a,"out",f,m,e),h=at(c,"in",p,m,e),$=Ct(x,h,e.linkCurvature,e.minControlPointDistance,e.pathStyle);return{...r,sourceName:a.label??a.id,targetName:c.label??c.id,path:$}})}class Gt{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=[]),this.listeners[t].push(e),()=>this.off(t,e)}off(t,e){const i=this.listeners[t];if(!i)return;const s=i.indexOf(e);s>-1&&i.splice(s,1)}emit(t,e){const i=this.listeners[t];if(i)for(const s of i)s(e)}clear(){this.listeners={}}}class Ft{constructor(t,e,i={}){this.dragging=null,this.dragOffset={x:0,y:0},this.hasMoved=!1,this.nodeHandlers=new Map,this.svg=t,this.nodes=e,this.callbacks=i,this.boundMouseMove=this.onMouseMove.bind(this),this.boundMouseUp=this.onMouseUp.bind(this),this.attachListeners()}updateNodes(t){this.nodes=t,this.reattachNodeListeners()}attachListeners(){this.reattachNodeListeners()}reattachNodeListeners(){this.nodeHandlers.clear(),this.svg.querySelectorAll(".node").forEach(e=>{const i=e.getAttribute("data-node-id");if(!i)return;const s=o=>this.onNodeMouseDown(o,i);this.nodeHandlers.set(i,s),e.addEventListener("mousedown",s)})}onNodeMouseDown(t,e){const i=this.nodes.find(o=>o.id===e);if(!i)return;this.dragging=i,this.hasMoved=!1;const s=this.getSVGPoint(t);this.dragOffset={x:s.x-i.x,y:s.y-i.y},document.addEventListener("mousemove",this.boundMouseMove),document.addEventListener("mouseup",this.boundMouseUp)}onMouseMove(t){if(!this.dragging)return;this.hasMoved||(this.hasMoved=!0,t.preventDefault(),this.svg.querySelector(`[data-node-id="${this.dragging.id}"]`)?.classList.add("dragging"),this.callbacks.onDragStart?.(this.dragging)),t.preventDefault();const e=this.getSVGPoint(t),i=e.x-this.dragOffset.x,s=e.y-this.dragOffset.y;this.dragging.x=i,this.dragging.y=s,this.callbacks.onDrag?.(this.dragging,i,s)}onMouseUp(t){if(this.dragging){if(this.hasMoved){this.svg.querySelector(`[data-node-id="${this.dragging.id}"]`)?.classList.remove("dragging");const i=N(this.nodes);this.callbacks.onDragEnd?.(this.dragging,i)}document.removeEventListener("mousemove",this.boundMouseMove),document.removeEventListener("mouseup",this.boundMouseUp),this.dragging=null,this.hasMoved=!1}}getSVGPoint(t){const e=this.svg.getBoundingClientRect(),i=this.svg.viewBox.baseVal;return!i||i.width===0?{x:t.clientX-e.left,y:t.clientY-e.top}:{x:(t.clientX-e.left)/e.width*i.width+i.x,y:(t.clientY-e.top)/e.height*i.height+i.y}}destroy(){document.removeEventListener("mousemove",this.boundMouseMove),document.removeEventListener("mouseup",this.boundMouseUp),this.nodeHandlers.clear()}}class Rt{constructor(t,e,i={}){this.boundHandlers=new Map,this.svg=t,this.nodes=e,this.callbacks=i,this.attachListeners()}updateNodes(t){this.nodes=t,this.reattachListeners()}attachListeners(){this.reattachListeners()}reattachListeners(){this.boundHandlers.clear(),this.svg.querySelectorAll(".node").forEach(e=>{const i=e.getAttribute("data-node-id");if(!i)return;const s=o=>{o.preventDefault(),this.rotateNode(i)};this.boundHandlers.set(i,s),e.addEventListener("dblclick",s)})}rotateNode(t){const e=this.nodes.find(c=>c.id===t);if(!e)return;const i=[0,90,180,270],o=(i.indexOf(e.orientation)+1)%4,r=i[o];e.orientation=r;const a=N(this.nodes);this.callbacks.onRotate?.(e,r,a)}destroy(){this.boundHandlers.clear()}}const ut={HANDLE_DEPTH:8,MAX_HANDLE_SPAN:20};class Tt{constructor(t,e,i,s){this.activeNode=null,this.activeHandleSide=null,this.startLength=0,this.startPos={x:0,y:0},this.handleElements=new Map,this.svg=t,this.nodes=e,this.options=i,this.sankeyOptions=s,this.onMouseMove=this.onMouseMove.bind(this),this.onMouseUp=this.onMouseUp.bind(this),this.createHandles()}createHandles(){this.handleElements.forEach(({start:e,end:i})=>{e.remove(),i.remove()}),this.handleElements.clear();const t=this.svg.querySelector(".nodes");if(t)for(const e of this.nodes){const i=t.querySelector(`[data-node-id="${e.id}"]`);if(!i)continue;const s=this.createHandle(e,"start"),o=this.createHandle(e,"end");i.appendChild(s),i.appendChild(o),this.handleElements.set(e.id,{start:s,end:o})}}createHandle(t,e){const i=document.createElementNS("http://www.w3.org/2000/svg","rect");return i.setAttribute("class",`resize-handle resize-handle--${e}`),this.positionHandle(i,t,e),i.addEventListener("mousedown",s=>this.onMouseDown(s,t,e)),i}positionHandle(t,e,i){const s=e.length??this.sankeyOptions.nodeLength,o=Math.max(e.thickness,this.sankeyOptions.minNodeThickness),r=ut.HANDLE_DEPTH,a=Math.min(o,ut.MAX_HANDLE_SPAN),c=e.orientation===0||e.orientation===180;let d,l,f,p;if(c)d=i==="end"?e.x+s/2-r/2:e.x-s/2-r/2,l=e.y-a/2,f=r,p=a;else{const m=i==="end"?e.y+s/2-r/2:e.y-s/2-r/2;d=e.x-a/2,l=m,f=a,p=r}t.setAttribute("x",String(d)),t.setAttribute("y",String(l)),t.setAttribute("width",String(f)),t.setAttribute("height",String(p))}onMouseDown(t,e,i){t.preventDefault(),t.stopPropagation(),this.activeNode=e,this.activeHandleSide=i,this.startLength=e.length??this.sankeyOptions.nodeLength,this.startPos=this.getSVGPoint(t),this.svg.querySelector(`[data-node-id="${e.id}"]`)?.classList.add("resizing"),document.addEventListener("mousemove",this.onMouseMove),document.addEventListener("mouseup",this.onMouseUp)}onMouseMove(t){if(!this.activeNode||!this.activeHandleSide)return;const e=this.getSVGPoint(t),i=this.activeNode.orientation===0||this.activeNode.orientation===180;let s;if(i){const r=e.x-this.startPos.x;s=this.activeHandleSide==="end"?r:-r}else{const r=e.y-this.startPos.y;s=this.activeHandleSide==="end"?r:-r}const o=Math.max(this.sankeyOptions.minNodeLength,this.startLength+s*2);this.options.onResize(this.activeNode,o)}onMouseUp(){if(!this.activeNode)return;this.svg.querySelector(`[data-node-id="${this.activeNode.id}"]`)?.classList.remove("resizing");const e=N(this.nodes.map(i=>i.id===this.activeNode.id?{...i,length:i.length}:i));this.options.onResizeEnd(this.activeNode,e),this.activeNode=null,this.activeHandleSide=null,document.removeEventListener("mousemove",this.onMouseMove),document.removeEventListener("mouseup",this.onMouseUp)}getSVGPoint(t){const e=this.svg.createSVGPoint();e.x=t.clientX,e.y=t.clientY;const i=this.svg.getScreenCTM();if(i){const s=e.matrixTransform(i.inverse());return{x:s.x,y:s.y}}return{x:t.clientX,y:t.clientY}}updateNodes(t){this.nodes=t,this.createHandles()}destroy(){document.removeEventListener("mousemove",this.onMouseMove),document.removeEventListener("mouseup",this.onMouseUp),this.handleElements.forEach(({start:t,end:e})=>{t.remove(),e.remove()}),this.handleElements.clear()}}class zt{constructor(t,e,i,s,o){this.handles=[],this.handlesGroup=null,this.dragging=null,this.dragStartY=0,this.siblingHandles=[],this.svg=t,this.nodes=e,this.links=i,this.callbacks=s,this.options=o,this.boundMouseMove=this.onMouseMove.bind(this),this.boundMouseUp=this.onMouseUp.bind(this),this.createHandles(),this.attachGlobalListeners()}updateNodes(t,e){this.nodes=t,this.links=e,this.destroyHandles(),this.createHandles()}createHandles(){this.handlesGroup=document.createElementNS("http://www.w3.org/2000/svg","g"),this.handlesGroup.classList.add("link-order-handles"),this.svg.appendChild(this.handlesGroup);for(const t of this.nodes){const e=this.links.filter(s=>s.source===t.id);this.createNodeHandles(t,e,"source");const i=this.links.filter(s=>s.target===t.id);this.createNodeHandles(t,i,"target")}}createNodeHandles(t,e,i){if(e.length<2)return;const s=i==="source"?t.outgoingValue:t.incomingValue;if(s===0)return;const o=[...e].sort((a,c)=>{const d=i==="source"?"sourceOrder":"targetOrder",l=a[d]??1/0,f=c[d]??1/0;return l===1/0&&f===1/0?0:l-f});let r=0;for(const a of o){const c=a.value/s,d=r+c/2;r+=c;const l=this.getHandlePosition(t,i,d),f=this.createHandle(l.x,l.y,a.id,t.id,i);this.handles.push(f)}}getHandlePosition(t,e,i){const s=t.length??this.options.nodeLength,o=Math.max(t.thickness,this.options.minNodeThickness),r=t.orientation===0||t.orientation===180,a=r?s:o,c=r?o:s;let d;t.orientation===0?d=e==="target"?"left":"right":t.orientation===90?d=e==="target"?"top":"bottom":t.orientation===180?d=e==="target"?"right":"left":d=e==="target"?"bottom":"top";const l=t.x-a/2,f=t.x+a/2,p=t.y-c/2,m=t.y+c/2,x=8;let h,$;switch(d){case"left":h=l-x,$=p+c*i;break;case"right":h=f+x,$=p+c*i;break;case"top":h=l+a*i,$=p-x;break;case"bottom":h=l+a*i,$=m+x;break}return{x:h,y:$}}createHandle(t,e,i,s,o){const r=document.createElementNS("http://www.w3.org/2000/svg","circle");r.setAttribute("cx",String(t)),r.setAttribute("cy",String(e)),r.setAttribute("r","5"),r.classList.add("link-order-handle"),r.style.fill="#666",r.style.stroke="#333",r.style.strokeWidth="1",r.style.cursor="grab",r.style.opacity="0",r.style.transition="opacity 0.15s";const a={linkId:i,nodeId:s,side:o,element:r};return r.addEventListener("mouseenter",()=>{this.showSiblingHandles(s,o)}),r.addEventListener("mouseleave",()=>{this.dragging||this.hideSiblingHandles(s,o)}),r.addEventListener("mousedown",c=>{c.stopPropagation(),c.preventDefault(),this.startDrag(a,c)}),this.handlesGroup.appendChild(r),a}showSiblingHandles(t,e){for(const i of this.handles)i.nodeId===t&&i.side===e&&(i.element.style.opacity="1")}hideSiblingHandles(t,e){for(const i of this.handles)i.nodeId===t&&i.side===e&&(i.element.style.opacity="0")}startDrag(t,e){this.dragging=t,this.dragStartY=e.clientY,t.element.style.cursor="grabbing",t.element.style.fill="#2196F3",this.handlesGroup?.classList.add("active"),this.siblingHandles=this.handles.filter(i=>i.nodeId===t.nodeId&&i.side===t.side&&i.linkId!==t.linkId)}onMouseMove(t){if(!this.dragging)return;const e=this.nodes.find(c=>c.id===this.dragging.nodeId);if(!e)return;const{inSide:i,outSide:s}=Vt(e.orientation),o=this.dragging.side==="source"?s:i,r=o==="left"||o==="right",a=this.svg.getBoundingClientRect();if(r){const c=t.clientY-a.top;this.dragging.element.setAttribute("cy",String(c))}else{const c=t.clientX-a.left;this.dragging.element.setAttribute("cx",String(c))}this.checkForSwap(t,r)}checkForSwap(t,e){if(!this.dragging)return;const i=this.svg.getBoundingClientRect(),s=e?t.clientY-i.top:t.clientX-i.left;for(const o of this.siblingHandles){const r=parseFloat(e?o.element.getAttribute("cy")||"0":o.element.getAttribute("cx")||"0");if(Math.abs(s-r)<15){this.swapLinkOrders(this.dragging.linkId,o.linkId);return}}}swapLinkOrders(t,e){const i=this.links.find(c=>c.id===t),s=this.links.find(c=>c.id===e);if(!i||!s)return;const o=this.dragging.side,r=o==="source"?"sourceOrder":"targetOrder";this.ensureOrdersInitialized(this.dragging.nodeId,o);const a=i[r];i[r]=s[r],s[r]=a,this.callbacks.onOrderChange(this.links)}ensureOrdersInitialized(t,e){const i=e==="source"?"sourceOrder":"targetOrder",s=e==="source"?this.links.filter(r=>r.source===t):this.links.filter(r=>r.target===t);s.some(r=>r[i]===void 0)&&s.forEach((r,a)=>{r[i]===void 0&&(r[i]=a)})}onMouseUp(t){if(!this.dragging)return;const e=this.dragging.nodeId,i=this.dragging.side;this.dragging.element.style.cursor="grab",this.dragging.element.style.fill="#666",this.dragging=null,this.siblingHandles=[],this.handlesGroup?.classList.remove("active"),setTimeout(()=>{this.hideSiblingHandles(e,i)},200)}attachGlobalListeners(){document.addEventListener("mousemove",this.boundMouseMove),document.addEventListener("mouseup",this.boundMouseUp)}destroyHandles(){this.handlesGroup&&(this.handlesGroup.remove(),this.handlesGroup=null),this.handles=[]}destroy(){document.removeEventListener("mousemove",this.boundMouseMove),document.removeEventListener("mouseup",this.boundMouseUp),this.destroyHandles()}}function Vt(n){switch(n){case 0:return{inSide:"left",outSide:"right"};case 90:return{inSide:"top",outSide:"bottom"};case 180:return{inSide:"right",outSide:"left"};case 270:return{inSide:"bottom",outSide:"top"}}}class Ut{constructor(t,e,i,s,o){this.linkOrderHandler=null,this.svg=t,this.dragHandler=new Ft(t,e,{onDrag:s.onDrag,onDragEnd:s.onDragEnd}),this.rotateHandler=new Rt(t,e,{onRotate:s.onRotate}),this.resizeHandler=new Tt(t,e,{onResize:s.onResize,onResizeEnd:s.onResizeEnd},o),s.onLinkOrderChange&&(this.linkOrderHandler=new zt(t,e,i,{onOrderChange:s.onLinkOrderChange},o))}updateNodes(t,e){this.dragHandler.updateNodes(t),this.rotateHandler.updateNodes(t),this.resizeHandler.updateNodes(t),this.linkOrderHandler&&e&&this.linkOrderHandler.updateNodes(t,e)}destroy(){this.dragHandler.destroy(),this.rotateHandler.destroy(),this.resizeHandler.destroy(),this.linkOrderHandler?.destroy()}}function Y(n,t,e){n.prototype=t.prototype=e,e.constructor=n}function ht(n,t){var e=Object.create(n.prototype);for(var i in t)e[i]=t[i];return e}function D(){}var C=.7,V=1/C,I="\\s*([+-]?\\d+)\\s*",G="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",M="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",_t=/^#([0-9a-f]{3,8})$/,jt=new RegExp(`^rgb\\(${I},${I},${I}\\)$`),Xt=new RegExp(`^rgb\\(${M},${M},${M}\\)$`),Yt=new RegExp(`^rgba\\(${I},${I},${I},${G}\\)$`),Bt=new RegExp(`^rgba\\(${M},${M},${M},${G}\\)$`),Zt=new RegExp(`^hsl\\(${G},${M},${M}\\)$`),Wt=new RegExp(`^hsla\\(${G},${M},${M},${G}\\)$`),ft={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};Y(D,F,{copy(n){return Object.assign(new this.constructor,this,n)},displayable(){return this.rgb().displayable()},hex:gt,formatHex:gt,formatHex8:Qt,formatHsl:Jt,formatRgb:pt,toString:pt});function gt(){return this.rgb().formatHex()}function Qt(){return this.rgb().formatHex8()}function Jt(){return vt(this).formatHsl()}function pt(){return this.rgb().formatRgb()}function F(n){var t,e;return n=(n+"").trim().toLowerCase(),(t=_t.exec(n))?(e=t[1].length,t=parseInt(t[1],16),e===6?mt(t):e===3?new w(t>>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):e===8?U(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):e===4?U(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=jt.exec(n))?new w(t[1],t[2],t[3],1):(t=Xt.exec(n))?new w(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=Yt.exec(n))?U(t[1],t[2],t[3],t[4]):(t=Bt.exec(n))?U(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=Zt.exec(n))?bt(t[1],t[2]/100,t[3]/100,1):(t=Wt.exec(n))?bt(t[1],t[2]/100,t[3]/100,t[4]):ft.hasOwnProperty(n)?mt(ft[n]):n==="transparent"?new w(NaN,NaN,NaN,0):null}function mt(n){return new w(n>>16&255,n>>8&255,n&255,1)}function U(n,t,e,i){return i<=0&&(n=t=e=NaN),new w(n,t,e,i)}function Kt(n){return n instanceof D||(n=F(n)),n?(n=n.rgb(),new w(n.r,n.g,n.b,n.opacity)):new w}function B(n,t,e,i){return arguments.length===1?Kt(n):new w(n,t,e,i??1)}function w(n,t,e,i){this.r=+n,this.g=+t,this.b=+e,this.opacity=+i}Y(w,B,ht(D,{brighter(n){return n=n==null?V:Math.pow(V,n),new w(this.r*n,this.g*n,this.b*n,this.opacity)},darker(n){return n=n==null?C:Math.pow(C,n),new w(this.r*n,this.g*n,this.b*n,this.opacity)},rgb(){return this},clamp(){return new w(E(this.r),E(this.g),E(this.b),_(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:xt,formatHex:xt,formatHex8:te,formatRgb:yt,toString:yt}));function xt(){return`#${H(this.r)}${H(this.g)}${H(this.b)}`}function te(){return`#${H(this.r)}${H(this.g)}${H(this.b)}${H((isNaN(this.opacity)?1:this.opacity)*255)}`}function yt(){const n=_(this.opacity);return`${n===1?"rgb(":"rgba("}${E(this.r)}, ${E(this.g)}, ${E(this.b)}${n===1?")":`, ${n})`}`}function _(n){return isNaN(n)?1:Math.max(0,Math.min(1,n))}function E(n){return Math.max(0,Math.min(255,Math.round(n)||0))}function H(n){return n=E(n),(n<16?"0":"")+n.toString(16)}function bt(n,t,e,i){return i<=0?n=t=e=NaN:e<=0||e>=1?n=t=NaN:t<=0&&(n=NaN),new S(n,t,e,i)}function vt(n){if(n instanceof S)return new S(n.h,n.s,n.l,n.opacity);if(n instanceof D||(n=F(n)),!n)return new S;if(n instanceof S)return n;n=n.rgb();var t=n.r/255,e=n.g/255,i=n.b/255,s=Math.min(t,e,i),o=Math.max(t,e,i),r=NaN,a=o-s,c=(o+s)/2;return a?(t===o?r=(e-i)/a+(e<i)*6:e===o?r=(i-t)/a+2:r=(t-e)/a+4,a/=c<.5?o+s:2-o-s,r*=60):a=c>0&&c<1?0:r,new S(r,a,c,n.opacity)}function ee(n,t,e,i){return arguments.length===1?vt(n):new S(n,t,e,i??1)}function S(n,t,e,i){this.h=+n,this.s=+t,this.l=+e,this.opacity=+i}Y(S,ee,ht(D,{brighter(n){return n=n==null?V:Math.pow(V,n),new S(this.h,this.s,this.l*n,this.opacity)},darker(n){return n=n==null?C:Math.pow(C,n),new S(this.h,this.s,this.l*n,this.opacity)},rgb(){var n=this.h%360+(this.h<0)*360,t=isNaN(n)||isNaN(this.s)?0:this.s,e=this.l,i=e+(e<.5?e:1-e)*t,s=2*e-i;return new w(Z(n>=240?n-240:n+120,s,i),Z(n,s,i),Z(n<120?n+240:n-120,s,i),this.opacity)},clamp(){return new S($t(this.h),j(this.s),j(this.l),_(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const n=_(this.opacity);return`${n===1?"hsl(":"hsla("}${$t(this.h)}, ${j(this.s)*100}%, ${j(this.l)*100}%${n===1?")":`, ${n})`}`}}));function $t(n){return n=(n||0)%360,n<0?n+360:n}function j(n){return Math.max(0,Math.min(1,n||0))}function Z(n,t,e){return(n<60?t+(e-t)*n/60:n<180?e:n<240?t+(e-t)*(240-n)/60:t)*255}const W=n=>()=>n;function ne(n,t){return function(e){return n+e*t}}function ie(n,t,e){return n=Math.pow(n,e),t=Math.pow(t,e)-n,e=1/e,function(i){return Math.pow(n+i*t,e)}}function se(n){return(n=+n)==1?kt:function(t,e){return e-t?ie(t,e,n):W(isNaN(t)?e:t)}}function kt(n,t){var e=t-n;return e?ne(n,e):W(isNaN(n)?t:n)}const wt=(function n(t){var e=se(t);function i(s,o){var r=e((s=B(s)).r,(o=B(o)).r),a=e(s.g,o.g),c=e(s.b,o.b),d=kt(s.opacity,o.opacity);return function(l){return s.r=r(l),s.g=a(l),s.b=c(l),s.opacity=d(l),s+""}}return i.gamma=n,i})(1);function re(n,t){t||(t=[]);var e=n?Math.min(t.length,n.length):0,i=t.slice(),s;return function(o){for(s=0;s<e;++s)i[s]=n[s]*(1-o)+t[s]*o;return i}}function oe(n){return ArrayBuffer.isView(n)&&!(n instanceof DataView)}function ae(n,t){var e=t?t.length:0,i=n?Math.min(e,n.length):0,s=new Array(i),o=new Array(e),r;for(r=0;r<i;++r)s[r]=K(n[r],t[r]);for(;r<e;++r)o[r]=t[r];return function(a){for(r=0;r<i;++r)o[r]=s[r](a);return o}}function ce(n,t){var e=new Date;return n=+n,t=+t,function(i){return e.setTime(n*(1-i)+t*i),e}}function X(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function de(n,t){var e={},i={},s;(n===null||typeof n!="object")&&(n={}),(t===null||typeof t!="object")&&(t={});for(s in t)s in n?e[s]=K(n[s],t[s]):i[s]=t[s];return function(o){for(s in e)i[s]=e[s](o);return i}}var Q=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,J=new RegExp(Q.source,"g");function le(n){return function(){return n}}function ue(n){return function(t){return n(t)+""}}function he(n,t){var e=Q.lastIndex=J.lastIndex=0,i,s,o,r=-1,a=[],c=[];for(n=n+"",t=t+"";(i=Q.exec(n))&&(s=J.exec(t));)(o=s.index)>e&&(o=t.slice(e,o),a[r]?a[r]+=o:a[++r]=o),(i=i[0])===(s=s[0])?a[r]?a[r]+=s:a[++r]=s:(a[++r]=null,c.push({i:r,x:X(i,s)})),e=J.lastIndex;return e<t.length&&(o=t.slice(e),a[r]?a[r]+=o:a[++r]=o),a.length<2?c[0]?ue(c[0].x):le(t):(t=c.length,function(d){for(var l=0,f;l<t;++l)a[(f=c[l]).i]=f.x(d);return a.join("")})}function K(n,t){var e=typeof t,i;return t==null||e==="boolean"?W(t):(e==="number"?X:e==="string"?(i=F(t))?(t=i,wt):he:t instanceof F?wt:t instanceof Date?ce:oe(t)?re:Array.isArray(t)?ae:typeof t.valueOf!="function"&&typeof t.toString!="function"||isNaN(t)?de:X)(n,t)}class Lt{constructor(t,e,i={}){this.animationId=null,this.svg=t,this.options=e,this.callbacks=i}updateOptions(t){this.options=t}cancel(){this.animationId!==null&&(cancelAnimationFrame(this.animationId),this.animationId=null,this.svg.classList.remove("animating"))}isAnimating(){return this.animationId!==null}captureState(){const t=new Map,e=new Map;return this.svg.querySelectorAll(".node").forEach(o=>{const r=o.getAttribute("data-node-id"),a=o.querySelector(".node-base");if(r&&a){const c=o.getAttribute("data-orientation"),l=parseFloat(c==="0"||c==="180"?a.getAttribute("height")||"0":a.getAttribute("width")||"0");t.set(r,{thickness:l})}}),this.svg.querySelectorAll(".link").forEach(o=>{const r=o.getAttribute("data-link-id"),a=o.getAttribute("d");r&&a&&e.set(r,{path:a})}),{nodes:t,links:e}}animateTo(t,e,i){return new Promise(s=>{this.cancel();const o=this.options.transitionDuration,r=this.options.transitionEasing;if(o<=0){this.applyFinalState(t,e),s();return}const a=i??this.captureState(),c=this.buildNodeInterpolators(a,t),d=this.buildLinkInterpolators(a,e);this.svg.classList.add("animating"),this.applyNodeFrame(c,0,t),this.applyLinkFrame(d,0),this.callbacks.onStart?.();const l=()=>{const f=performance.now(),p=()=>{const m=performance.now()-f,x=Math.min(m/o,1),h=r(x);this.applyNodeFrame(c,h,t),this.applyLinkFrame(d,h),x<1?this.animationId=requestAnimationFrame(p):(this.animationId=null,this.svg.classList.remove("animating"),this.callbacks.onEnd?.(),s())};this.animationId=requestAnimationFrame(p)};requestAnimationFrame(()=>{requestAnimationFrame(l)})})}buildNodeInterpolators(t,e){const i=new Map;for(const s of e){const o=t.nodes.get(s.id)?.thickness??this.options.minNodeThickness,r=Math.max(s.thickness,this.options.minNodeThickness);i.set(s.id,X(o,r))}return i}buildLinkInterpolators(t,e){const i=new Map;for(const s of e){const o=t.links.get(s.id)?.path,r=s.path;o&&this.arePathsCompatible(o,r)?i.set(s.id,K(o,r)):i.set(s.id,()=>r)}return i}arePathsCompatible(t,e){const i=s=>(s.match(/[MLCQAZHVS]/gi)||[]).length;return i(t)===i(e)}applyNodeFrame(t,e,i){const s=this.svg.querySelector(".nodes");if(s)for(const o of i){const r=t.get(o.id);if(!r)continue;const a=r(e),c=s.querySelector(`[data-node-id="${o.id}"]`);if(!c)continue;const d=c.querySelector(".node-base");if(!d)continue;const l=o.length??this.options.nodeLength,f=o.orientation===0||o.orientation===180,p=f?l:a,m=f?a:l;d.setAttribute("x",String(o.x-p/2)),d.setAttribute("y",String(o.y-m/2)),d.setAttribute("width",String(p)),d.setAttribute("height",String(m));const x=c.querySelector(".node-shape-overlay");if(x){const h=o.shape??"rect";if(h==="circle"){const $=q(h,p,m);x.setAttribute("cx",String(o.x)),x.setAttribute("cy",String(o.y)),x.setAttribute("rx",String(p/2-$)),x.setAttribute("ry",String(m/2-$))}else{const $=z(h,o.x,o.y,p,m,o.orientation);$&&x.setAttribute("d",$)}}}}applyLinkFrame(t,e){const i=this.svg.querySelector(".links");i&&t.forEach((s,o)=>{const r=i.querySelector(`[data-link-id="${o}"]`);r&&r.setAttribute("d",s(e))})}applyFinalState(t,e){const i=this.svg.querySelector(".nodes"),s=this.svg.querySelector(".links");if(i)for(const o of t){const r=i.querySelector(`[data-node-id="${o.id}"]`);if(!r)continue;const a=r.querySelector(".node-base");if(!a)continue;const c=Math.max(o.thickness,this.options.minNodeThickness),d=o.length??this.options.nodeLength,l=o.orientation===0||o.orientation===180,f=l?d:c,p=l?c:d;a.setAttribute("x",String(o.x-f/2)),a.setAttribute("y",String(o.y-p/2)),a.setAttribute("width",String(f)),a.setAttribute("height",String(p));const m=r.querySelector(".node-shape-overlay");if(m){const x=o.shape??"rect";if(x==="circle"){const h=q(x,f,p);m.setAttribute("cx",String(o.x)),m.setAttribute("cy",String(o.y)),m.setAttribute("rx",String(f/2-h)),m.setAttribute("ry",String(p/2-h))}else{const h=z(x,o.x,o.y,f,p,o.orientation);h&&m.setAttribute("d",h)}}}if(s)for(const o of e){const r=s.querySelector(`[data-link-id="${o.id}"]`);r&&r.setAttribute("d",o.path)}}destroy(){this.cancel()}}function fe(n,t){let e=[...t.nodes],i=[...t.links],s={...tt,...t.options};t.layout&&(e=T(e,t.layout),i=P(i,t.layout));let o=R(e,i);const r=Et(n),a=new Gt;let c=[],d=[],l=null;const f=new Lt(r,s,{onStart:()=>a.emit("transitionStart",null),onEnd:()=>a.emit("transitionEnd",null)});function p(){c=it(o,s),d=lt(c,o.links,s),rt(r,c,s),ot(r,d),$()}async function m(){const g=f.captureState();c=it(o,s),d=lt(c,o.links,s),rt(r,c,s,!0),ot(r,d,s,!0),$(),await f.animateTo(c,d,g),x()}function x(){l?l.updateNodes(c,o.links):l=new Ut(r,c,o.links,{onDrag:(g,y,u)=>{const b=o.nodes.find(v=>v.id===g.id);b&&(b.x=y,b.y=u),p(),l?.updateNodes(c,o.links)},onDragEnd:(g,y)=>{a.emit("layoutChange",y)},onRotate:(g,y,u)=>{const b=o.nodes.find(v=>v.id===g.id);b&&(b.orientation=y),h(),a.emit("layoutChange",u)},onResize:(g,y)=>{const u=o.nodes.find(b=>b.id===g.id);u&&(u.length=y),p(),l?.updateNodes(c,o.links)},onResizeEnd:(g,y)=>{a.emit("layoutChange",y)},onLinkOrderChange:g=>{p(),l?.updateNodes(c,o.links),a.emit("layoutChange",N(o.nodes,o.links))}},s)}function h(){p(),x()}function $(){r.querySelectorAll(".node").forEach(u=>{const b=u.getAttribute("data-node-id");b&&(u.addEventListener("click",()=>{const v=et(o,b);v&&a.emit("nodeClick",v)}),u.addEventListener("mouseenter",()=>{const v=et(o,b);v&&a.emit("nodeHover",v)}),u.addEventListener("mouseleave",()=>{a.emit("nodeHover",null)}))}),r.querySelectorAll(".link").forEach(u=>{const b=u.getAttribute("data-link-id");b&&(u.addEventListener("click",()=>{const v=nt(o,b);v&&a.emit("linkClick",v)}),u.addEventListener("mouseenter",()=>{const v=nt(o,b);v&&a.emit("linkHover",v)}),u.addEventListener("mouseleave",()=>{a.emit("linkHover",null)}))})}return h(),{on(g,y){return a.on(g,y)},getLayout(){return N(o.nodes,o.links)},setLayout(g){o=R(T(o.nodes,g),P(o.links,g)),h(),a.emit("layoutChange",g)},setOption(g,y){s[g]=y,f.updateOptions(s),h()},getOptions(){return{...s}},setData(g,y){const u=N(o.nodes,o.links),b=T(g,u).map((A,L)=>({...A,shape:g[L].shape})),v=P(y,u);o=R(b,v),m()},setLinks(g){const y=N(o.nodes,o.links),u=P(g,y);o=R(o.nodes,u),m()},isAnimating(){return f.isAnimating()},cancelAnimation(){f.cancel()},setTheme(g){g==="dark"?r.classList.add("theme-dark"):r.classList.remove("theme-dark")},destroy(){f.destroy(),l?.destroy(),a.clear(),Ht(r),r.remove()}}}k.Animator=Lt,k.DEFAULT_OPTIONS=tt,k.applyLayout=T,k.applyLinkOrders=P,k.createSankey=fe,k.easings=O,k.extractLayout=N,k.parseLayout=At,k.serializeLayout=Mt,Object.defineProperty(k,Symbol.toStringTag,{value:"Module"})}));