sweet-diagram
Version:
A modern and intuitive diagram editor component for React applications with 3D visualization support
1,557 lines (1,553 loc) • 605 kB
JavaScript
import { jsxs as t, jsx as e, Fragment as pe } from "react/jsx-runtime";
import { useEffect as ge, createContext as $e, useState as D, useRef as Ie, useCallback as U, useContext as _e, forwardRef as et, createElement as Re, useMemo as lt } from "react";
const g = ({
id: r = "",
text: a = "",
width: n = 120,
height: o = 60,
x: c = 0,
y: d = 0,
textDirection: s = "horizontal",
// "horizontal" | "vertical"
verticalDirection: x = "lr",
// "lr" | "rl" - Vertical text direction (lr: left→right, rl: right→left)
className: C = "bg-[#0066ff] text-white border-blue-800 border-2 rounded-lg text-sm",
onClick: f = null
}) => {
let i, h;
try {
const P = We();
i = P.registerBox, h = P.unregisterBox;
} catch {
i = null, h = null;
}
ge(() => {
r && i && i(r, { id: r, x: c, y: d, width: n, height: o });
}, [r, c, d, n, o, i]), ge(() => () => {
r && h && h(r);
}, [r, h]);
const b = (P) => {
f && f(P, { id: r, x: c, y: d, width: n, height: o });
}, S = (P) => {
(P.key === "Enter" || P.key === " ") && b(P);
}, w = () => s === "vertical" ? {
writingMode: `vertical-${x}`,
// vertical-lr or vertical-rl
textOrientation: "mixed",
textAlign: "center"
} : {
textAlign: "center"
}, O = {
top: { x: c + n / 2, y: d },
right: { x: c + n, y: d + o / 2 },
bottom: { x: c + n / 2, y: d + o },
left: { x: c, y: d + o / 2 }
};
return /* @__PURE__ */ t(
"div",
{
className: `absolute z-10 ${C}`,
style: {
left: `${c}px`,
// Explicitly add px unit
top: `${d}px`,
// Explicitly add px unit
width: `${n}px`,
height: `${o}px`,
transform: "translate3d(0,0,0)"
// Utilize GPU acceleration
},
"data-box-id": r,
onClick: b,
onKeyDown: S,
tabIndex: "0",
role: "button",
"aria-label": `Box component: ${a} ${r ? `(ID: ${r})` : ""}`,
children: [
/* @__PURE__ */ e("div", { className: "flex items-center justify-center w-full h-full cursor-pointer select-none transition-all duration-200 hover:shadow-lg hover:scale-105 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50", children: /* @__PURE__ */ e("span", { className: "font-medium px-2 leading-tight", style: w(), children: a }) }),
Object.entries(O).map(([P, z]) => /* @__PURE__ */ e(
"div",
{
className: "absolute w-2 h-2 bg-[#0066ff] rounded-full opacity-0 hover:opacity-100 transition-all duration-200 cursor-crosshair hover:scale-150 hover:bg-[#0066ff] z-20",
style: {
left: `${z.x - c - 4}px`,
top: `${z.y - d - 4}px`
},
"data-connection-point": P,
"data-box-id": r,
"data-x": z.x,
"data-y": z.y,
title: `${r ? `${r} - ` : ""}${P} connection point`
},
P
))
]
}
);
}, tt = $e(), We = () => {
const r = _e(tt);
if (!r)
throw new Error("useDiagram must be used within a DiagramProvider");
return r;
}, He = ({ children: r, className: a = "", style: n = {} }) => {
const [o, c] = D(/* @__PURE__ */ new Map()), [d, s] = D([]), [x, C] = D(null), [f, i] = D(/* @__PURE__ */ new Set()), [h, b] = D(!1), [S, w] = D(!1), [v, O] = D(null), [P, z] = D([]), [A, I] = D(-1), [Q, W] = D(1), [q, te] = D({ x: 0, y: 0 }), [ie, l] = D(/* @__PURE__ */ new Map()), p = Ie(null), ee = U((B, T) => {
c((E) => {
const F = new Map(E), me = {
id: B,
x: T.x,
y: T.y,
width: T.width,
height: T.height,
element: T.element,
// DOM 요소 참조
...T
};
return F.set(B, me), F;
});
}, []), re = U((B) => {
const T = B.id || `dynamic-box-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, E = {
id: T,
x: B.x || Math.random() * 400 + 50,
y: B.y || Math.random() * 300 + 50,
width: B.width || 120,
height: B.height || 80,
text: B.text || `박스 ${T}`,
className: B.className || "bg-blue-500 text-white border-blue-600 border-2 rounded-lg",
...B
};
return l((F) => {
const me = new Map(F);
return me.set(T, E), me;
}), c((F) => {
const me = new Map(F);
return me.set(T, E), me;
}), T;
}, []), Y = U((B) => {
l((T) => {
const E = new Map(T);
return E.delete(B), E;
}), he(B);
}, []), oe = U((B, T) => {
c((E) => {
const F = new Map(E), me = F.get(B);
if (me && (me.x !== T.x || me.y !== T.y)) {
const we = { ...me, ...T };
return F.set(B, we), l((m) => {
const u = new Map(m);
return u.has(B) && u.set(B, we), u;
}), F;
}
return E;
});
}, []), he = U((B) => {
c((T) => {
const E = new Map(T);
return E.delete(B), E;
}), s((T) => T.filter((E) => {
var F, me;
return ((F = E.fromBox) == null ? void 0 : F.id) !== B && ((me = E.toBox) == null ? void 0 : me.id) !== B;
})), i((T) => {
const E = new Set(T);
return E.delete(B), E;
});
}, []), ae = U(
(B) => o.get(B),
[o]
), K = U(() => Array.from(o.values()), [o]), de = U((B, T = !1) => {
i((E) => {
const F = /* @__PURE__ */ new Set();
return T ? (F.add(...E), E.has(B) ? F.delete(B) : F.add(B)) : E.has(B) && E.size === 1 || F.add(B), F;
});
}, []), Z = U(() => {
i(/* @__PURE__ */ new Set());
}, []), H = U((B) => {
const T = {
id: `conn_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
...B
};
return s((E) => [...E, T]), T.id;
}, []), X = U((B) => {
s((T) => T.filter((E) => E.id !== B));
}, []), ce = U((B, T) => {
s((E) => E.map((F) => F.id === B ? { ...F, ...T } : F));
}, []), ue = U(
(B, T) => {
const E = o.get(B), F = o.get(T);
if (!E || !F) return null;
const me = {
x: E.x + E.width / 2,
y: E.y + E.height / 2
}, we = {
x: F.x + F.width / 2,
y: F.y + F.height / 2
}, m = we.x - me.x, u = we.y - me.y;
let N, k;
return Math.abs(m) > Math.abs(u) ? m > 0 ? (N = "right", k = "left") : (N = "left", k = "right") : u > 0 ? (N = "bottom", k = "top") : (N = "top", k = "bottom"), { fromPosition: N, toPosition: k };
},
[o]
), fe = U(() => {
const B = {
boxes: new Map(o),
connections: [...d],
dynamicBoxes: new Map(ie),
timestamp: Date.now()
};
z((T) => {
const E = T.slice(0, A + 1);
return E.push(B), E.slice(-50);
}), I((T) => Math.min(T + 1, 49));
}, [o, d, ie, A]), Pe = U(() => {
if (A > 0) {
const B = P[A - 1];
c(new Map(B.boxes)), s([...B.connections]), l(new Map(B.dynamicBoxes || /* @__PURE__ */ new Map())), I((T) => T - 1);
}
}, [P, A]), Te = U(() => {
if (A < P.length - 1) {
const B = P[A + 1];
c(new Map(B.boxes)), s([...B.connections]), l(new Map(B.dynamicBoxes || /* @__PURE__ */ new Map())), I((T) => T + 1);
}
}, [P, A]), Ve = U(() => {
c(/* @__PURE__ */ new Map()), s([]), l(/* @__PURE__ */ new Map()), i(/* @__PURE__ */ new Set()), C(null), fe();
}, [fe]), Le = U(() => {
W((B) => Math.min(B * 1.2, 3));
}, []), je = U(() => {
W((B) => Math.max(B / 1.2, 0.1));
}, []), qe = U(() => {
W(1), te({ x: 0, y: 0 });
}, []), Xe = U(() => ({
boxCount: o.size,
connectionCount: d.length,
selectedBoxCount: f.size,
canUndo: A > 0,
canRedo: A < P.length - 1,
scale: Q,
panOffset: q
}), [o.size, d.length, f.size, A, P.length, Q, q]), De = U(
(B) => Array.from(o.values()).filter(B),
[o]
), j = U(
(B) => d.filter(B),
[d]
), J = U(() => {
const B = Array.from(o.values());
if (B.length === 0) return;
const T = /* @__PURE__ */ new Map(), E = 50, F = 800, me = 600;
B.forEach((we) => {
T.set(we.id, { ...we });
});
for (let we = 0; we < E; we++) {
const m = /* @__PURE__ */ new Map();
B.forEach((u) => {
let N = 0, k = 0;
const M = T.get(u.id);
B.forEach((xe) => {
if (u.id !== xe.id) {
const se = T.get(xe.id), ve = M.x - se.x, ye = M.y - se.y, _ = Math.sqrt(ve * ve + ye * ye) || 1, $ = Math.min(1e3 / (_ * _), 10);
N += ve / _ * $, k += ye / _ * $;
}
}), d.forEach((xe) => {
var ve, ye, _, $;
let se = null;
if (((ve = xe.fromBox) == null ? void 0 : ve.id) === u.id ? se = T.get((ye = xe.toBox) == null ? void 0 : ye.id) : ((_ = xe.toBox) == null ? void 0 : _.id) === u.id && (se = T.get(($ = xe.fromBox) == null ? void 0 : $.id)), se) {
const Ce = se.x - M.x, Be = se.y - M.y, Ye = Math.sqrt(Ce * Ce + Be * Be) || 1, Qe = (Ye - 150) * 0.05;
N += Ce / Ye * Qe, k += Be / Ye * Qe;
}
});
const V = F / 2, L = me / 2, R = (V - M.x) * 1e-3, ne = (L - M.y) * 1e-3;
N += R, k += ne, m.set(u.id, { fx: N, fy: k });
}), B.forEach((u) => {
const N = m.get(u.id), k = T.get(u.id), M = 0.1;
let V = k.x + N.fx * M, L = k.y + N.fy * M;
V = Math.max(10, Math.min(F - k.width - 10, V)), L = Math.max(10, Math.min(me - k.height - 10, L)), T.set(u.id, {
...k,
x: V,
y: L
});
});
}
c(T), l((we) => {
const m = new Map(we);
return T.forEach((u, N) => {
m.has(N) && m.set(N, u);
}), m;
}), fe();
}, [o, d, fe]), ke = {
// 박스 관리
boxes: o,
registerBox: ee,
unregisterBox: he,
updateBoxPosition: oe,
getBox: ae,
getAllBoxes: K,
selectBox: de,
clearSelection: Z,
selectedBoxes: f,
findBoxes: De,
addDynamicBox: re,
removeDynamicBox: Y,
dynamicBoxes: ie,
// 연결 관리
connections: d,
addConnection: H,
removeConnection: X,
updateConnection: ce,
selectedConnection: x,
setSelectedConnection: C,
getOptimalConnectionPoints: ue,
findConnections: j,
// 상태 관리
isDragging: h,
setIsDragging: b,
isConnecting: S,
setIsConnecting: w,
connectionStartBox: v,
setConnectionStartBox: O,
// 히스토리 관리
undo: Pe,
redo: Te,
saveState: fe,
clearDiagram: Ve,
// 뷰 관리
scale: Q,
setScale: W,
panOffset: q,
setPanOffset: te,
zoomIn: Le,
zoomOut: je,
resetZoom: qe,
// 유틸리티
getDiagramStats: Xe,
optimizeLayout: J,
// 컨테이너 관련
containerRef: p
}, Ae = {
position: "relative",
width: "100%",
height: "100%",
...n
}, Me = `sweet-diagram-provider diagram-container ${a}`;
return /* @__PURE__ */ e(tt.Provider, { value: ke, children: /* @__PURE__ */ e("div", { ref: p, className: Me, style: Ae, children: r }) });
}, y = ({
// 기존 방식 (좌표 직접 지정)
startPoint: r = null,
endPoint: a = null,
// 새로운 방식 (박스 연결 - 자동 감지)
fromBox: n = null,
// { id: "box1", position: "right", offset: { x: 0, y: 0 } }
toBox: o = null,
// { id: "box2", position: "left", offset: { x: 0, y: 0 } }
// 자유 포인트 연결 방식
fromCustomPoint: c = null,
// { x: number, y: number } - 절대 좌표
toCustomPoint: d = null,
// { x: number, y: number } - 절대 좌표
fromBoxCustom: s = null,
// { id: string, customPoint: { x: 0~1, y: 0~1 } } - 박스 내 상대 위치
toBoxCustom: x = null,
// { id: string, customPoint: { x: 0~1, y: 0~1 } } - 박스 내 상대 위치
connectionType: C = "straight",
// 'straight', 'curved', 'orthogonal', 'stepped', 'custom'
strokeWidth: f = 2,
animated: i = !1,
animationType: h = "dash",
animationSpeed: b = 2,
className: S = "",
arrowSize: w = 8,
arrowDirection: v = "forward",
// 'forward', 'backward', 'both', 'none'
arrowColor: O = "current",
// 'current', 'red', 'blue', etc.
arrowShape: P = "triangle",
// 'triangle', 'diamond', 'circle', 'square'
bendPoints: z,
// 중간 꺾임점들 [{ x: 150, y: 100 }, { x: 150, y: 200 }] - 기본값 제거
cornerRadius: A = 0,
// 모서리 둥글기
orthogonalDirection: I = "auto",
// 'horizontal-first', 'vertical-first', 'auto'
stepOffset: Q = 50
// orthogonal 연결에서 중간 지점 오프셋
}) => {
let W = null;
try {
W = We().getBox;
} catch {
W = null;
}
const q = Array.isArray(z) ? z : void 0, te = v === "none" ? !1 : v === "forward" || v === "both", ie = v === "none" ? !1 : v === "backward" || v === "both", l = () => O === "current" ? "fill-current" : {
red: "fill-red-500",
blue: "fill-blue-500",
green: "fill-green-500",
yellow: "fill-yellow-500",
purple: "fill-purple-500",
pink: "fill-pink-500",
indigo: "fill-indigo-500",
gray: "fill-gray-500",
black: "fill-black",
white: "fill-white"
}[O] || `fill-${O}` || "fill-current", p = (m, u, N, k, M, V, L) => {
switch (P) {
case "triangle":
return `${m},${u} ${N},${k} ${M},${V}`;
case "diamond": {
const R = Math.atan2(k - u, N - m), ne = m - L * 0.6 * Math.cos(R), xe = u - L * 0.6 * Math.sin(R), se = m + L * 0.6 * Math.cos(R), ve = u + L * 0.6 * Math.sin(R), ye = m + L * 0.4 * Math.cos(R + Math.PI / 2), _ = u + L * 0.4 * Math.sin(R + Math.PI / 2), $ = m + L * 0.4 * Math.cos(R - Math.PI / 2), Ce = u + L * 0.4 * Math.sin(R - Math.PI / 2);
return `${ne},${xe} ${ye},${_} ${se},${ve} ${$},${Ce}`;
}
case "circle":
return null;
case "square": {
const ne = L * 0.8 / 2;
return `${m - ne},${u - ne} ${m + ne},${u - ne} ${m + ne},${u + ne} ${m - ne},${u + ne}`;
}
default:
return `${m},${u} ${N},${k} ${M},${V}`;
}
}, ee = (m, u, N, k) => P !== "circle" ? null : /* @__PURE__ */ e("circle", { cx: m - N, cy: u - k, r: Z * 0.6, className: l() }), re = (m, u, N = { x: 0, y: 0 }) => {
if (!m || typeof m.x != "number" || typeof m.y != "number")
return null;
const { x: k, y: M, width: V, height: L } = m;
let R = { x: 0, y: 0 };
switch (u) {
case "top":
R = { x: k + V / 2, y: M };
break;
case "right":
R = { x: k + V, y: M + L / 2 };
break;
case "bottom":
R = { x: k + V / 2, y: M + L };
break;
case "left":
R = { x: k, y: M + L / 2 };
break;
case "center":
R = { x: k + V / 2, y: M + L / 2 };
break;
default:
R = { x: k + V / 2, y: M + L / 2 };
}
return {
x: R.x + ((N == null ? void 0 : N.x) || 0),
y: R.y + ((N == null ? void 0 : N.y) || 0)
};
}, Y = (m) => {
if (!W) return null;
const u = W(m.id);
if (!u) return null;
const { x: N, y: k, width: M, height: V } = u, { customPoint: L } = m, R = Math.max(0, Math.min(1, L.x)), ne = Math.max(0, Math.min(1, L.y)), xe = N + M * R, se = k + V * ne;
return {
x: xe,
y: se
};
}, oe = () => {
let m = r, u = a;
if (c && d)
m = c, u = d;
else if (s && x && W) {
const N = Y(s), k = Y(x);
N && k && (m = N, u = k);
} else if ((n || s) && (o || x || c || d)) {
if (s && W)
m = Y(s);
else if (n && n.id && W) {
const N = W(n.id);
N && (m = re(N, n.position, n.offset));
} else c && (m = c);
if (x && W)
u = Y(x);
else if (o && o.id && W) {
const N = W(o.id);
N && (u = re(N, o.position, o.offset));
} else d && (u = d);
} else if (n && o && n.id && o.id && W) {
const N = W(n.id), k = W(o.id);
if (N && k) {
const M = re(N, n.position, n.offset), V = re(k, o.position, o.offset);
M && V && (m = M, u = V);
} else
q && q.length >= 2 && (m = q[0], u = q[q.length - 1]);
}
return { actualStartPoint: m, actualEndPoint: u };
}, { actualStartPoint: he, actualEndPoint: ae } = oe(), K = {
x: (he == null ? void 0 : he.x) ?? 100,
y: (he == null ? void 0 : he.y) ?? 100
}, de = {
x: (ae == null ? void 0 : ae.x) ?? 300,
y: (ae == null ? void 0 : ae.y) ?? 200
}, Z = typeof w == "number" && !isNaN(w) ? w : 8, H = typeof f == "number" && !isNaN(f) ? f : 2, ce = (() => {
if (C === "custom" && (!q || q.length === 0))
return console.warn(
"⚠️ connectionType='custom'이지만 bendPoints가 정의되지 않았습니다. 'straight' 타입으로 fallback합니다."
), "straight";
if (C !== "auto") return C;
if (n && o && n.position && o.position) {
const { position: m } = n;
return m === "right" && o.position === "left" || m === "left" && o.position === "right" || m === "top" && o.position === "bottom" || m === "bottom" && o.position === "top" ? "straight" : "orthogonal";
}
return "straight";
})(), ue = () => {
const { x: m, y: u } = K, { x: N, y: k } = de;
let M = `M ${m} ${u}`;
if (n && o && n.position && o.position) {
const { position: V } = n;
if (V === "right" || V === "left") {
const L = V === "right" ? m + Q : m - Q;
M += ` L ${L} ${u} L ${L} ${k} L ${N} ${k}`;
} else {
const L = V === "bottom" ? u + Q : u - Q;
M += ` L ${m} ${L} L ${N} ${L} L ${N} ${k}`;
}
} else if (I === "horizontal-first") {
const V = m + Q;
M += ` L ${V} ${u} L ${V} ${k} L ${N} ${k}`;
} else if (I === "vertical-first") {
const V = u + Q;
M += ` L ${m} ${V} L ${N} ${V} L ${N} ${k}`;
} else {
const V = Math.abs(N - m), L = Math.abs(k - u);
if (V > L) {
const R = m + (N - m) * 0.5;
M += ` L ${R} ${u} L ${R} ${k} L ${N} ${k}`;
} else {
const R = u + (k - u) * 0.5;
M += ` L ${m} ${R} L ${N} ${R} L ${N} ${k}`;
}
}
return M;
}, fe = () => {
const { x: m, y: u } = K, { x: N, y: k } = de, M = 3, V = (N - m) / M, L = (k - u) / M;
let R = `M ${m} ${u}`;
for (let ne = 1; ne <= M; ne++) {
const xe = m + V * ne, se = u + L * (ne - 1), ve = u + L * ne;
R += ` L ${xe} ${se} L ${xe} ${ve}`;
}
return R;
}, Pe = () => {
const { x: m, y: u } = K, { x: N, y: k } = de;
let M = `M ${m} ${u}`;
if (q && q.length > 0) {
q.forEach((L) => {
L && typeof L.x == "number" && typeof L.y == "number" && (M += ` L ${L.x} ${L.y}`);
});
const V = q[q.length - 1];
V && (V.x !== N || V.y !== k) && (M += ` L ${N} ${k}`);
} else
M += ` L ${N} ${k}`;
return M;
}, Te = () => {
const { x: m, y: u } = K, { x: N, y: k } = de, M = N - m, V = k - u;
if (n && o && n.position && o.position) {
const { position: ye } = n;
let _ = m, $ = u, Ce = N, Be = k;
return ye === "right" ? _ = m + Math.abs(M) * 0.5 : ye === "left" ? _ = m - Math.abs(M) * 0.5 : ye === "bottom" ? $ = u + Math.abs(V) * 0.5 : ye === "top" && ($ = u - Math.abs(V) * 0.5), o.position === "left" ? Ce = N - Math.abs(M) * 0.5 : o.position === "right" ? Ce = N + Math.abs(M) * 0.5 : o.position === "top" ? Be = k - Math.abs(V) * 0.5 : o.position === "bottom" && (Be = k + Math.abs(V) * 0.5), `M ${m} ${u} C ${_} ${$} ${Ce} ${Be} ${N} ${k}`;
}
const L = Math.sqrt(M * M + V * V), R = Math.min(L * 0.3, 100), ne = m + R, xe = u, se = N - R;
return `M ${m} ${u} C ${ne} ${xe} ${se} ${k} ${N} ${k}`;
}, Ve = () => {
const { x: m, y: u } = K, { x: N, y: k } = de;
return `M ${m} ${u} L ${N} ${k}`;
}, Le = () => {
switch (ce) {
case "curved":
return Te();
case "orthogonal":
return ue();
case "stepped":
return fe();
case "custom":
return Pe();
default:
return Ve();
}
}, je = () => {
const m = Le();
return A <= 0 || ce === "curved" || ce === "orthogonal", m;
}, qe = () => {
const { x: m, y: u } = K, { x: N, y: k } = de;
if (o && o.position && n) {
const { position: _ } = o;
let $;
switch (_) {
case "left":
$ = 0;
break;
case "right":
$ = Math.PI;
break;
case "top":
$ = Math.PI / 2;
break;
case "bottom":
$ = -Math.PI / 2;
break;
default:
$ = Math.atan2(k - u, N - m);
}
const Ce = {
x: N - Z * Math.cos($ - Math.PI / 6),
y: k - Z * Math.sin($ - Math.PI / 6)
}, Be = {
x: N - Z * Math.cos($ + Math.PI / 6),
y: k - Z * Math.sin($ + Math.PI / 6)
};
return { arrowHead1: Ce, arrowHead2: Be };
}
let M = m, V = u, L = N, R = k;
if (ce === "custom" && q && q.length > 0) {
const _ = q[q.length - 1];
_ && typeof _.x == "number" && typeof _.y == "number" && (M = _.x, V = _.y);
} else ce === "orthogonal" && (Math.abs(N - m) > Math.abs(k - u) ? V = k : M = N);
const ne = L - M, xe = R - V, se = Math.atan2(xe, ne), ve = {
x: N - Z * Math.cos(se - Math.PI / 6),
y: k - Z * Math.sin(se - Math.PI / 6)
}, ye = {
x: N - Z * Math.cos(se + Math.PI / 6),
y: k - Z * Math.sin(se + Math.PI / 6)
};
return { arrowHead1: ve, arrowHead2: ye };
}, Xe = () => {
const { x: m, y: u } = K, { x: N, y: k } = de;
if (n && n.position && o) {
const { position: _ } = n;
let $;
switch (_) {
case "right":
$ = 0;
break;
case "left":
$ = Math.PI;
break;
case "bottom":
$ = Math.PI / 2;
break;
case "top":
$ = -Math.PI / 2;
break;
default:
$ = Math.atan2(k - u, N - m);
}
const Ce = {
x: m + Z * Math.cos($ - Math.PI / 6),
y: u + Z * Math.sin($ - Math.PI / 6)
}, Be = {
x: m + Z * Math.cos($ + Math.PI / 6),
y: u + Z * Math.sin($ + Math.PI / 6)
};
return { startArrowHead1: Ce, startArrowHead2: Be };
}
let M = m, V = u, L = N, R = k;
if (ce === "custom" && q && q.length > 0) {
const _ = q[0];
_ && typeof _.x == "number" && typeof _.y == "number" && (L = _.x, R = _.y);
} else ce === "orthogonal" && (Math.abs(N - m) > Math.abs(k - u) ? R = u : L = m);
const ne = L - M, xe = R - V, se = Math.atan2(xe, ne), ve = {
x: m + Z * Math.cos(se - Math.PI / 6),
y: u + Z * Math.sin(se - Math.PI / 6)
}, ye = {
x: m + Z * Math.cos(se + Math.PI / 6),
y: u + Z * Math.sin(se + Math.PI / 6)
};
return { startArrowHead1: ve, startArrowHead2: ye };
}, { arrowHead1: De, arrowHead2: j } = te ? qe() : { arrowHead1: null, arrowHead2: null }, { startArrowHead1: J, startArrowHead2: ke } = ie ? Xe() : { startArrowHead1: null, startArrowHead2: null }, Ae = q ? q.filter(
(m) => m && typeof m.x == "number" && typeof m.y == "number" && !isNaN(m.x) && !isNaN(m.y)
) : [], Me = [K, de, ...Ae], B = Math.min(...Me.map((m) => m.x)) - Z, T = Math.min(...Me.map((m) => m.y)) - Z, E = Math.max(...Me.map((m) => m.x)) + Z, F = Math.max(...Me.map((m) => m.y)) + Z, me = () => {
if (!i) return "";
const m = b || 2;
switch (console.log(`Animation enabled: ${i}, Type: ${h}, Speed: ${m}`), h) {
case "electric":
return `
.electric-path {
stroke-dasharray: 8, 4, 2, 4;
animation: electricFlow ${m * 0.9}s linear infinite, electricGlow ${m * 2}s ease-in-out infinite alternate;
filter: drop-shadow(0 0 6px rgba(59, 130, 246, 0.7));
stroke-linecap: round;
}
@keyframes electricFlow {
0% {
stroke-dashoffset: 0;
opacity: 0.8;
}
25% {
opacity: 1;
}
50% {
opacity: 0.9;
}
75% {
opacity: 1;
}
100% {
stroke-dashoffset: -14;
opacity: 0.8;
}
}
@keyframes electricGlow {
0% {
filter: drop-shadow(0 0 6px rgba(59, 130, 246, 0.7));
}
100% {
filter: drop-shadow(0 0 12px rgba(59, 130, 246, 1)) drop-shadow(0 0 20px rgba(96, 165, 250, 0.6));
}
}
`;
case "water":
return `
.water-path {
stroke-dasharray: 12, 6, 4, 6;
animation: waterFlow ${m * 1.1}s ease-in-out infinite, waterWave ${m * 2}s ease-in-out infinite;
filter: drop-shadow(0 0 4px rgba(59, 130, 246, 0.6));
stroke-linecap: round;
}
@keyframes waterFlow {
0% {
stroke-dashoffset: 0;
opacity: 0.7;
}
25% {
opacity: 0.9;
}
50% {
opacity: 1;
}
75% {
opacity: 0.8;
}
100% {
stroke-dashoffset: -16;
opacity: 0.7;
}
}
@keyframes waterWave {
0% {
filter: drop-shadow(0 0 4px rgba(59, 130, 246, 0.6));
}
50% {
filter: drop-shadow(0 0 8px rgba(59, 130, 246, 0.8)) drop-shadow(0 0 14px rgba(14, 165, 233, 0.5));
}
100% {
filter: drop-shadow(0 0 4px rgba(59, 130, 246, 0.6));
}
}
`;
case "wind":
return `
.wind-path {
stroke-dasharray: 6, 10, 4, 8;
animation: windFlow ${m * 0.8}s ease-in-out infinite, windGust ${m * 2.2}s ease-in-out infinite;
filter: drop-shadow(0 0 3px rgba(156, 163, 175, 0.5));
stroke-linecap: round;
}
@keyframes windFlow {
0% {
stroke-dashoffset: 0;
opacity: 0.5;
}
20% {
opacity: 0.7;
}
40% {
opacity: 0.4;
}
60% {
opacity: 0.8;
}
80% {
opacity: 0.6;
}
100% {
stroke-dashoffset: -18;
opacity: 0.5;
}
}
@keyframes windGust {
0% {
filter: drop-shadow(0 0 3px rgba(156, 163, 175, 0.5));
}
50% {
filter: drop-shadow(0 0 6px rgba(156, 163, 175, 0.7)) drop-shadow(0 0 12px rgba(107, 114, 128, 0.4));
}
100% {
filter: drop-shadow(0 0 3px rgba(156, 163, 175, 0.5));
}
}
`;
case "gas":
return `
.gas-path {
stroke-dasharray: 6, 8, 4, 6;
animation: gasFlow ${m * 1.2}s ease-in-out infinite, gasDiffusion ${m * 2.5}s ease-in-out infinite;
filter: drop-shadow(0 0 4px rgba(251, 191, 36, 0.6));
stroke-linecap: round;
}
@keyframes gasFlow {
0% {
stroke-dashoffset: 0;
opacity: 0.6;
}
20% {
opacity: 0.8;
}
40% {
opacity: 0.5;
}
60% {
opacity: 0.9;
}
80% {
opacity: 0.7;
}
100% {
stroke-dashoffset: -14;
opacity: 0.6;
}
}
@keyframes gasDiffusion {
0% {
filter: drop-shadow(0 0 4px rgba(251, 191, 36, 0.6));
}
50% {
filter: drop-shadow(0 0 8px rgba(251, 191, 36, 0.8)) drop-shadow(0 0 15px rgba(245, 158, 11, 0.5));
}
100% {
filter: drop-shadow(0 0 4px rgba(251, 191, 36, 0.6));
}
}
`;
case "data":
return `
.data-path {
stroke-dasharray: 4, 3, 2, 3;
animation: dataTransfer ${m * 0.9}s linear infinite, dataGlow ${m * 2}s ease-in-out infinite;
filter: drop-shadow(0 0 5px rgba(34, 197, 94, 0.7));
stroke-linecap: round;
}
@keyframes dataTransfer {
0% {
stroke-dashoffset: 0;
opacity: 0.8;
}
25% {
opacity: 1;
}
50% {
opacity: 0.9;
}
75% {
opacity: 1;
}
100% {
stroke-dashoffset: -12;
opacity: 0.8;
}
}
@keyframes dataGlow {
0% {
filter: drop-shadow(0 0 5px rgba(34, 197, 94, 0.7));
}
50% {
filter: drop-shadow(0 0 10px rgba(34, 197, 94, 0.9)) drop-shadow(0 0 18px rgba(16, 185, 129, 0.6));
}
100% {
filter: drop-shadow(0 0 5px rgba(34, 197, 94, 0.7));
}
}
.data-packets {
animation: dataPacket ${m * 0.6}s linear infinite;
}
@keyframes dataPacket {
0% {
opacity: 0;
r: 1;
fill: #22c55e;
}
20% {
opacity: 0.7;
r: 1.5;
fill: #10b981;
}
40% {
opacity: 1;
r: 2;
fill: #059669;
}
60% {
opacity: 0.8;
r: 1.8;
fill: #047857;
}
80% {
opacity: 0.4;
r: 1.2;
fill: #065f46;
}
100% {
opacity: 0;
r: 1;
fill: #22c55e;
}
}
`;
default:
return `
.dash-path {
stroke-dasharray: 8, 4;
animation: dashFlow ${m}s linear infinite;
stroke-linecap: round;
opacity: 0.8;
}
@keyframes dashFlow {
0% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: -12;
}
}
`;
}
}, we = () => null;
return /* @__PURE__ */ t(
"svg",
{
className: `absolute pointer-events-none z-10 ${S}`,
style: {
left: B,
top: T,
width: E - B,
height: F - T
},
children: [
i && /* @__PURE__ */ e("defs", { children: /* @__PURE__ */ e("style", { children: me() }) }),
/* @__PURE__ */ e(
"path",
{
d: je(),
strokeWidth: H,
fill: "none",
className: `stroke-current ${i ? `${h}-path` : ""}`,
transform: `translate(${-B}, ${-T})`,
strokeLinecap: "round",
strokeLinejoin: "round"
}
),
we(),
te && De && j && /* @__PURE__ */ e(pe, { children: P === "circle" ? ee(de.x, de.y, B, T) : /* @__PURE__ */ e(
"polygon",
{
points: p(
de.x,
de.y,
De.x,
De.y,
j.x,
j.y,
Z
),
className: l(),
transform: `translate(${-B}, ${-T})`
}
) }),
ie && J && ke && /* @__PURE__ */ e(pe, { children: P === "circle" ? ee(K.x, K.y, B, T) : /* @__PURE__ */ e(
"polygon",
{
points: p(
K.x,
K.y,
J.x,
J.y,
ke.x,
ke.y,
Z
),
className: l(),
transform: `translate(${-B}, ${-T})`
}
) })
]
}
);
}, Oe = ({
direction: r = "right",
length: a = 100,
strokeWidth: n = 2,
startPoint: o = { x: 0, y: 0 },
endPoint: c = null,
className: d = "text-blue-600 hover:text-blue-700 transition-colors duration-200",
arrowSize: s = 8,
showStartArrow: x = !1,
showEndArrow: C = !0,
onClick: f = null
}) => {
const i = {
x: typeof (o == null ? void 0 : o.x) == "number" && !isNaN(o.x) ? o.x : 0,
y: typeof (o == null ? void 0 : o.y) == "number" && !isNaN(o.y) ? o.y : 0
}, h = typeof a == "number" && !isNaN(a) ? a : 100, b = typeof s == "number" && !isNaN(s) ? s : 8, S = typeof n == "number" && !isNaN(n) ? n : 2, v = (() => {
if (c && typeof c.x == "number" && typeof c.y == "number" && !isNaN(c.x) && !isNaN(c.y))
return c;
const W = {
right: { x: i.x + h, y: i.y },
left: { x: i.x - h, y: i.y },
up: { x: i.x, y: i.y - h },
down: { x: i.x, y: i.y + h },
"up-right": { x: i.x + h * 0.7, y: i.y - h * 0.7 },
"down-right": { x: i.x + h * 0.7, y: i.y + h * 0.7 },
"up-left": { x: i.x - h * 0.7, y: i.y - h * 0.7 },
"down-left": { x: i.x - h * 0.7, y: i.y + h * 0.7 }
};
return W[r] || W.right;
})(), O = () => {
const W = v.x - i.x, q = v.y - i.y, te = Math.atan2(q, W), ie = {
x: v.x - b * Math.cos(te - Math.PI / 6),
y: v.y - b * Math.sin(te - Math.PI / 6)
}, l = {
x: v.x - b * Math.cos(te + Math.PI / 6),
y: v.y - b * Math.sin(te + Math.PI / 6)
};
return { arrowHead1: ie, arrowHead2: l };
}, P = () => {
const W = i.x - v.x, q = i.y - v.y, te = Math.atan2(q, W), ie = {
x: i.x - b * Math.cos(te - Math.PI / 6),
y: i.y - b * Math.sin(te - Math.PI / 6)
}, l = {
x: i.x - b * Math.cos(te + Math.PI / 6),
y: i.y - b * Math.sin(te + Math.PI / 6)
};
return { arrowHead1: ie, arrowHead2: l };
}, z = C ? O() : null, A = x ? P() : null, I = (W) => {
f && f(W, { startPoint: i, endPoint: v, arrowSize: b });
}, Q = (W) => {
(W.key === "Enter" || W.key === " ") && I(W);
};
return /* @__PURE__ */ t(
"svg",
{
className: `absolute ${f ? "cursor-pointer" : "pointer-events-none"} ${d}`,
style: {
left: Math.min(i.x, v.x) - b,
top: Math.min(i.y, v.y) - b,
width: Math.abs(v.x - i.x) + b * 2,
height: Math.abs(v.y - i.y) + b * 2
},
onClick: f ? I : void 0,
onKeyDown: f ? Q : void 0,
tabIndex: f ? 0 : void 0,
role: f ? "button" : void 0,
"aria-label": f ? "화살표" : void 0,
children: [
/* @__PURE__ */ e(
"line",
{
x1: i.x - Math.min(i.x, v.x) + b,
y1: i.y - Math.min(i.y, v.y) + b,
x2: v.x - Math.min(i.x, v.x) + b,
y2: v.y - Math.min(i.y, v.y) + b,
strokeWidth: S,
className: "stroke-current",
strokeLinecap: "round"
}
),
C && z && /* @__PURE__ */ e(
"polygon",
{
points: `${v.x - Math.min(i.x, v.x) + b},${v.y - Math.min(i.y, v.y) + b} ${z.arrowHead1.x - Math.min(i.x, v.x) + b},${z.arrowHead1.y - Math.min(i.y, v.y) + b} ${z.arrowHead2.x - Math.min(i.x, v.x) + b},${z.arrowHead2.y - Math.min(i.y, v.y) + b}`,
className: "fill-current"
}
),
x && A && /* @__PURE__ */ e(
"polygon",
{
points: `${i.x - Math.min(i.x, v.x) + b},${i.y - Math.min(i.y, v.y) + b} ${A.arrowHead1.x - Math.min(i.x, v.x) + b},${A.arrowHead1.y - Math.min(i.y, v.y) + b} ${A.arrowHead2.x - Math.min(i.x, v.x) + b},${A.arrowHead2.y - Math.min(i.y, v.y) + b}`,
className: "fill-current"
}
)
]
}
);
}, be = ({
startPoint: r = { x: 0, y: 0 },
endPoint: a = { x: 100, y: 0 },
strokeWidth: n = 2,
lineType: o = "straight",
// 'straight', 'curved', 'stepped'
className: c = "text-gray-500 hover:text-gray-600 transition-colors duration-200",
dashArray: d = null
// '5,5' for dashed line
}) => {
const s = {
x: typeof (r == null ? void 0 : r.x) == "number" && !isNaN(r.x) ? r.x : 0,
y: typeof (r == null ? void 0 : r.y) == "number" && !isNaN(r.y) ? r.y : 0
}, x = {
x: typeof (a == null ? void 0 : a.x) == "number" && !isNaN(a.x) ? a.x : 100,
y: typeof (a == null ? void 0 : a.y) == "number" && !isNaN(a.y) ? a.y : 0
}, C = typeof n == "number" && !isNaN(n) ? n : 2, f = () => {
const { x: w, y: v } = s, { x: O, y: P } = x;
switch (o) {
case "curved": {
const z = (w + O) / 2, A = (v + P) / 2, I = z, Q = A - Math.abs(O - w) * 0.2;
return `M ${w} ${v} Q ${I} ${Q} ${O} ${P}`;
}
case "stepped": {
const z = w + (O - w) * 0.5;
return `M ${w} ${v} L ${z} ${v} L ${z} ${P} L ${O} ${P}`;
}
default:
return `M ${w} ${v} L ${O} ${P}`;
}
}, i = Math.min(s.x, x.x), h = Math.min(s.y, x.y), b = Math.max(s.x, x.x), S = Math.max(s.y, x.y);
return /* @__PURE__ */ t(
"svg",
{
className: `absolute pointer-events-none ${c}`,
style: {
left: i - C,
top: h - C,
width: b - i + C * 2,
height: S - h + C * 2
},
children: [
/* @__PURE__ */ e(
"path",
{
d: f(),
strokeWidth: C,
fill: "none",
strokeDasharray: d,
transform: `translate(${-i + C}, ${-h + C})`,
className: "stroke-current",
strokeLinecap: "round",
strokeLinejoin: "round"
}
),
/* @__PURE__ */ e(
"circle",
{
cx: s.x - i + C,
cy: s.y - h + C,
r: "3",
className: "opacity-50 hover:opacity-100 transition-opacity fill-current"
}
),
/* @__PURE__ */ e(
"circle",
{
cx: x.x - i + C,
cy: x.y - h + C,
r: "3",
className: "opacity-50 hover:opacity-100 transition-opacity fill-current"
}
)
]
}
);
}, Ee = ({
direction: r = "up",
// 'up', 'down', 'left', 'right'
size: a = 40,
x: n = 0,
y: o = 0,
className: c = "text-emerald-600 hover:text-emerald-700 transition-colors duration-200",
onClick: d = null
}) => {
const s = (h) => {
d && d(h, { x: n, y: o, size: a, direction: r });
}, x = (h) => {
(h.key === "Enter" || h.key === " ") && s(h);
}, C = () => {
const h = a / 2;
switch (r) {
case "up":
return `${h},0 0,${a} ${a},${a}`;
case "down":
return `0,0 ${a},0 ${h},${a}`;
case "left":
return `${a},0 ${a},${a} 0,${h}`;
case "right":
return `0,0 0,${a} ${a},${h}`;
default:
return `${h},0 0,${a} ${a},${a}`;
}
}, i = (() => {
const h = a / 2;
switch (r) {
case "up":
return {
top: { x: n + h, y: o },
bottom: { x: n + h, y: o + a },
left: { x: n, y: o + a },
right: { x: n + a, y: o + a }
};
case "down":
return {
top: { x: n + h, y: o },
bottom: { x: n + h, y: o + a },
left: { x: n, y: o },
right: { x: n + a, y: o }
};
case "left":
return {
top: { x: n + a, y: o },
bottom: { x: n + a, y: o + a },
left: { x: n, y: o + h },
right: { x: n + a, y: o + h }
};
case "right":
return {
top: { x: n, y: o },
bottom: { x: n, y: o + a },
left: { x: n, y: o + h },
right: { x: n + a, y: o + h }
};
default:
return {
top: { x: n + h, y: o },
bottom: { x: n + h, y: o + a },
left: { x: n, y: o + a },
right: { x: n + a, y: o + a }
};
}
})();
return /* @__PURE__ */ t(
"div",
{
className: `absolute ${c}`,
style: {
left: `${n}px`,
top: `${o}px`
},
children: [
/* @__PURE__ */ e(
"svg",
{
width: a,
height: a,
className: `cursor-pointer transition-all duration-200 hover:scale-110 focus:outline-none focus:ring-2 focus:ring-emerald-500 focus:ring-opacity-50 ${c}`,
onClick: s,
onKeyDown: x,
tabIndex: "0",
role: "button",
"aria-label": `Triangle pointing ${r}`,
children: /* @__PURE__ */ e(
"polygon",
{
points: C(),
className: "fill-current stroke-current stroke-2 transition-colors duration-200 hover:opacity-80"
}
)
}
),
Object.entries(i).map(([h, b]) => /* @__PURE__ */ e(
"div",
{
className: "absolute w-2 h-2 bg-emerald-600 rounded-full opacity-0 hover:opacity-100 transition-all duration-200 cursor-crosshair hover:scale-150 hover:bg-emerald-500",
style: {
left: `${b.x - n - 4}px`,
top: `${b.y - o - 4}px`
},
"data-connection-point": h,
"data-x": b.x,
"data-y": b.y
},
h
))
]
}
);
};
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const it = (r) => r.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), dt = (r) => r.replace(
/^([A-Z])|[\s-_]+(\w)/g,
(a, n, o) => o ? o.toUpperCase() : n.toLowerCase()
), Ue = (r) => {
const a = dt(r);
return a.charAt(0).toUpperCase() + a.slice(1);
}, rt = (...r) => r.filter((a, n, o) => !!a && a.trim() !== "" && o.indexOf(a) === n).join(" ").trim(), ct = (r) => {
for (const a in r)
if (a.startsWith("aria-") || a === "role" || a === "title")
return !0;
};
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
var mt = {
xmlns: "http://www.w3.org/2000/svg",
width: 24,
height: 24,
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
strokeWidth: 2,
strokeLinecap: "round",
strokeLinejoin: "round"
};
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const ht = et(
({
color: r = "currentColor",
size: a = 24,
strokeWidth: n = 2,
absoluteStrokeWidth: o,
className: c = "",
children: d,
iconNode: s,
...x
}, C) => Re(
"svg",
{
ref: C,
...mt,
width: a,
height: a,
stroke: r,
strokeWidth: o ? Number(n) * 24 / Number(a) : n,
className: rt("lucide", c),
...!d && !ct(x) && { "aria-hidden": "true" },
...x
},
[
...s.map(([f, i]) => Re(f, i)),
...Array.isArray(d) ? d : [d]
]
)
);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Ne = (r, a) => {
const n = et(
({ className: o, ...c }, d) => Re(ht, {
ref: d,
iconNode: a,
className: rt(
`lucide-${it(Ue(r))}`,
`lucide-${r}`,
o
),
...c
})
);
return n.displayName = Ue(r), n;
};
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const xt = [
[
"path",
{
d: "M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2",
key: "169zse"
}
]
], pt = Ne("activity", xt);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const gt = [
["path", { d: "m12 19-7-7 7-7", key: "1l729n" }],
["path", { d: "M19 12H5", key: "x3x0zl" }]
], bt = Ne("arrow-left", gt);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const ut = [
["path", { d: "M5 12h14", key: "1ays0h" }],
["path", { d: "m12 5 7 7-7 7", key: "xquz4c" }]
], yt = Ne("arrow-right", ut);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Nt = [
["path", { d: "M21.801 10A10 10 0 1 1 17 3.335", key: "yps3ct" }],
["path", { d: "m9 11 3 3L22 4", key: "1pflzl" }]
], ft = Ne("circle-check-big", Nt);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const wt = [
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
["path", { d: "m15 9-6 6", key: "1uzhvr" }],
["path", { d: "m9 9 6 6", key: "z0biqf" }]
], vt = Ne("circle-x", wt);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const kt = [["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]], Ct = Ne("circle", kt);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Pt = [
["path", { d: "m12 14 4-4", key: "9kzdfg" }],
["path", { d: "M3.34 19a10 10 0 1 1 17.32 0", key: "19p75a" }]
], At = Ne("gauge", Pt);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Bt = [["path", { d: "M5 12h14", key: "1ays0h" }]], St = Ne("minus", Bt);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Tt = [
["path", { d: "M5 12h14", key: "1ays0h" }],
["path", { d: "M12 5v14", key: "s699le" }]
], zt = Ne("plus", Tt);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Dt = [
["path", { d: "M12 2v10", key: "mnfbl" }],
["path", { d: "M18.4 6.6a9 9 0 1 1-12.77.04", key: "obofu9" }]
], Wt = Ne("power", Dt);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Mt = [
["path", { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8", key: "1p45f6" }],
["path", { d: "M21 3v5h-5", key: "1q7to0" }]
], Ot = Ne("rotate-cw", Mt);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Ht = [
[
"path",
{
d: "M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z",
key: "1qme2f"
}
],
["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
], Ge = Ne("settings", Ht);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Vt = [
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }]
], Lt = Ne("square", Vt);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const jt = [
["path", { d: "M12 9a4 4 0 0 0-2 7.5", key: "1jvsq6" }],
["path", { d: "M12 3v2", key: "1w22ol" }],
["path", { d: "m6.6 18.4-1.4 1.4", key: "w2yidj" }],
["path", { d: "M20 4v10.54a4 4 0 1 1-4 0V4a2 2 0 0 1 4 0Z", key: "iof6y5" }],
["path", { d: "M4 13H2", key: "118le4" }],
["path", { d: "M6.34 7.34 4.93 5.93", key: "1brd51" }]
], Xt = Ne("thermometer-sun", jt);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Et = [
[
"path",
{
d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",
key: "wmoenq"
}
],
["path", { d: "M12 9v4", key: "juzpu7" }],
["path", { d: "M12 17h.01", key: "p32p05" }]
], It = Ne("triangle-alert", Et);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const qt = [
[
"path",
{
d: "M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z",
key: "cbrjhi"
}
]
], Yt = Ne("wrench", qt);
/**
* @license lucide-react v0.511.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Rt = [
[
"path",
{
d: "M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",
key: "1xq2db"
}
]
], Gt = Ne("zap", Rt), G = ({
type: r = "gate",
// 'gate', 'ball', 'check', 'butterfly', 'needle'
size: a = 50,
x: n = 0,
y: o = 0,
isOpen: c = !0,
className: d = "text-amber-500 hover:text-amber-600 transition-colors duration-200",
onClick: s = null,
showIcon: x = !1,
// 아이콘 표시 여부
customIcon: C = null,
/